diff --git a/.artifactignore b/.artifactignore new file mode 100644 index 000000000000..5af70cce6426 --- /dev/null +++ b/.artifactignore @@ -0,0 +1,12 @@ +**/* +!target/*.bin +!target/*.log +!target/*.img.gz +!target/docker-sonic-vs.gz +!target/docker-ptf.gz +!target/debs/**/*.deb +!target/debs/**/*.deb.log +!target/debs/**/*.deb-install.log +!target/python-wheels/*.whl +!target/python-wheels/*.whl.log +!target/python-wheels/*.whl-install.log diff --git a/.azure-pipelines/build-template.yml b/.azure-pipelines/build-template.yml new file mode 100644 index 000000000000..c1cc04836a94 --- /dev/null +++ b/.azure-pipelines/build-template.yml @@ -0,0 +1,116 @@ +parameters: +- name: platform + type: string + values: + - broadcom + - centec-arm64 + - marvell-armhf + - mellanox + - vs + +- name: platform_arch + type: string + values: + - amd64 + - armhf + - arm64 + default: amd64 + +- name: platform_short + type: string + values: + - brcm + - centec-arm64 + - marvell-armhf + - mlnx + - vs + +- name: cache_mode + type: string + values: + - wcache + - rcache + - cache + +- name: pool + type: string + values: + - sonicbld + - sonicbld_8c + default: sonicbld + +- name: dbg_image + type: boolean + default: false + +- name: swi_image + type: boolean + default: false + +- name: raw_image + type: boolean + default: false + +- name: sync_rpc_image + type: boolean + default: false + +- name: timeout + type: number + default: 600 + +jobs: +- job: + pool: ${{ parameters.pool }} + displayName: ${{ parameters.platform }} + timeoutInMinutes: ${{ parameters.timeout }} + steps: + - template: cleanup.yml + - checkout: self + clean: true + submodules: recursive + displayName: 'Checkout code' + - script: | + git submodule foreach --recursive 'git clean -xfdf || true' + git submodule foreach --recursive 'git reset --hard || true' + git submodule foreach --recursive 'git remote update || true' + git submodule update --init --recursive + displayName: 'Reset submodules' + - script: | + set -e + sudo modprobe overlay + sudo apt-get install -y acl + export DOCKER_DATA_ROOT_FOR_MULTIARCH=/data/march/docker + CACHE_OPTIONS="SONIC_DPKG_CACHE_METHOD=${{ parameters.cache_mode }} SONIC_DPKG_CACHE_SOURCE=/nfs/dpkg_cache/${{ parameters.platform }}" + ENABLE_DOCKER_BASE_PULL=y make configure PLATFORM=${{ parameters.platform }} PLATFORM_ARCH=${{ parameters.platform_arch }} + trap "sudo rm -rf fsroot" EXIT + + if [ ${{ parameters.platform }} == vs ]; then + if [ ${{ parameters.dbg_image }} == true ]; then + make USERNAME=admin $CACHE_OPTIONS SONIC_BUILD_JOBS=$(nproc) INSTALL_DEBUG_TOOLS=y target/sonic-vs.img.gz && \ + mv target/sonic-vs.img.gz target/sonic-vs-dbg.img.gz + fi + + make USERNAME=admin $CACHE_OPTIONS SONIC_BUILD_JOBS=$(nproc) target/docker-sonic-vs.gz target/sonic-vs.img.gz target/docker-ptf.gz + else + if [ ${{ parameters.dbg_image }} == true ]; then + make USERNAME=admin $CACHE_OPTIONS SONIC_BUILD_JOBS=$(nproc) INSTALL_DEBUG_TOOLS=y target/sonic-${{ parameters.platform }}.bin && \ + mv target/sonic-${{ parameters.platform }}.bin target/sonic-${{ parameters.platform }}-dbg.bin + fi + if [ ${{ parameters.swi_image }} == true ]; then + make USERNAME=admin $CACHE_OPTIONS SONIC_BUILD_JOBS=$(nproc) ENABLE_IMAGE_SIGNATURE=y target/sonic-aboot-${{ parameters.platform }}.swi + fi + if [ ${{ parameters.raw_image }} == true ]; then + make USERNAME=admin $CACHE_OPTIONS SONIC_BUILD_JOBS=$(nproc) target/sonic-${{ parameters.platform }}.raw + fi + if [ ${{ parameters.sync_rpc_image }} == true ]; then + make USERNAME=admin $CACHE_OPTIONS SONIC_BUILD_JOBS=$(nproc) ENABLE_SYNCD_RPC=y target/docker-syncd-${{ parameters.platform_short }}-rpc.gz + fi + + make USERNAME=admin $CACHE_OPTIONS SONIC_BUILD_JOBS=$(nproc) target/sonic-${{ parameters.platform }}.bin + fi + displayName: 'Build sonic image' + - template: cleanup.yml + - publish: $(System.DefaultWorkingDirectory)/ + artifact: sonic-buildimage.${{ parameters.platform }} + displayName: "Archive sonic image" diff --git a/.azure-pipelines/cleanup.yml b/.azure-pipelines/cleanup.yml new file mode 100644 index 000000000000..ffbcf298b6c9 --- /dev/null +++ b/.azure-pipelines/cleanup.yml @@ -0,0 +1,17 @@ +steps: +- script: | + if sudo [ -f /var/run/march/docker.pid ] ; then + pid=`sudo cat /var/run/march/docker.pid` ; sudo kill $pid + fi + sudo rm -f /var/run/march/docker.pid + sudo rm -rf /data/march/docker + + # clean native docker build + if sudo [ -f dockerfs/var/run/docker.pid ] ; then + pid=`sudo cat dockerfs/var/run/docker.pid` ; sudo kill $pid + fi + sudo rm -rf dockerfs + sudo rm -rf fsroot + username=$(id -un) + sudo chown -R ${username}.${username} . + displayName: "Clean Workspace" diff --git a/.azure-pipelines/official-build.yml b/.azure-pipelines/official-build.yml new file mode 100644 index 000000000000..b353ab678c29 --- /dev/null +++ b/.azure-pipelines/official-build.yml @@ -0,0 +1,54 @@ +# Starter pipeline +# Start with a minimal pipeline that you can customize to build and deploy your code. +# Add steps that build, run tests, deploy, and more: +# https://aka.ms/yaml + +schedules: +- cron: "0 8 * * *" + displayName: Daily midnight build + branches: + include: + - master + always: true + +trigger: none +pr: none + +stages: +- stage: Build + + jobs: + - template: build-template.yml + parameters: + platform: broadcom + platform_short: brcm + cache_mode: wcache + dbg_image: true + swi_image: true + raw_image: true + sync_rpc_image: true + + - template: build-template.yml + parameters: + platform: vs + platform_short: vs + dbg_image: true + cache_mode: wcache + + - template: build-template.yml + parameters: + timeout: 3600 + platform: marvell-armhf + platform_arch: armhf + platform_short: marvell-armhf + cache_mode: wcache + pool: sonicbld_8c + + - template: build-template.yml + parameters: + timeout: 3600 + platform: centec-arm64 + platform_arch: arm64 + platform_short: centec-arm64 + cache_mode: wcache + pool: sonicbld_8c diff --git a/.azure-pipelines/run-test-template.yml b/.azure-pipelines/run-test-template.yml new file mode 100644 index 000000000000..afe5eadec338 --- /dev/null +++ b/.azure-pipelines/run-test-template.yml @@ -0,0 +1,82 @@ +parameters: +- name: dut + type: string +- name: tbname + type: string +- name: tbtype + type: string +- name: ptf_name + type: string + +steps: +- checkout: self + clean: true + displayName: 'checkout sonic-mgmt repo' + +- task: DownloadPipelineArtifact@2 + inputs: + artifact: sonic-buildimage.vs + displayName: "Download sonic-buildimage.vs artifact" + +- script: | + set -x + sudo mkdir -p /data/sonic-vm/images + sudo cp -v ../target/sonic-vs.img.gz /data/sonic-vm/images/sonic-vs.img.gz + sudo gzip -fd /data/sonic-vm/images/sonic-vs.img.gz + username=$(id -un) + sudo chown -R $username.$username /data/sonic-vm + + pushd /data/sonic-mgmt + git remote update + git reset --hard origin/master + sed -i s/use_own_value/${username}/ ansible/veos_vtb + echo aaa > ansible/password.txt + docker exec sonic-mgmt bash -c "pushd /data/sonic-mgmt/ansible;./testbed-cli.sh -d /data/sonic-vm -m $(inventory) -t $(testbed_file) -k ceos refresh-dut ${{ parameters.tbname }} password.txt" && sleep 180 + displayName: "Setup testbed" + +- script: | + rm -rf $(Build.ArtifactStagingDirectory)/* + docker exec sonic-mgmt bash -c "/data/sonic-mgmt/tests/kvmtest.sh -en -T ${{ parameters.tbtype }} ${{ parameters.tbname }} ${{ parameters.dut }}" + displayName: "Run tests" + +- script: | + # save dut state if test fails + virsh_version=$(virsh --version) + if [ $virsh_version == "6.0.0" ]; then + mkdir -p $(Build.ArtifactStagingDirectory)/kvmdump + virsh -c qemu:///system list + virsh -c qemu:///system save ${{ parameters.dut }} $(Build.ArtifactStagingDirectory)/kvmdump/${{ parameters.dut }}.memdmp + virsh -c qemu:///system dumpxml ${{ parameters.dut }} > $(Build.ArtifactStagingDirectory)/kvmdump/${{ parameters.dut }}.xml + img=$(virsh -c qemu:///system domblklist ${{ parameters.dut }} | grep vda | awk '{print $2}') + cp $img $(Build.ArtifactStagingDirectory)/kvmdump/${{ parameters.dut }}.img + virsh -c qemu:///system undefine ${{ parameters.dut }} + fi + + docker commit ${{ parameters.ptf_name }} docker-ptf:$(Build.BuildNumber) + docker save docker-ptf:$(Build.BuildNumber) | gzip -c > $(Build.ArtifactStagingDirectory)/kvmdump/docker-ptf-dump.gz + docker rmi docker-ptf:$(Build.BuildNumber) + displayName: "Collect kvmdump" + condition: failed() + +- script: | + cp -r /data/sonic-mgmt/tests/logs $(Build.ArtifactStagingDirectory)/ + username=$(id -un) + sudo chown -R $username.$username $(Build.ArtifactStagingDirectory) + displayName: "Collect test logs" + condition: succeededOrFailed() + +- publish: $(Build.ArtifactStagingDirectory)/kvmdump + artifact: sonic-buildimage.kvmtest.${{ parameters.tbtype}}.memdump@$(System.JobAttempt) + displayName: "Archive sonic kvm memdump" + condition: failed() + +- publish: $(Build.ArtifactStagingDirectory)/logs + artifact: sonic-buildimage.kvmtest.${{ parameters.tbtype }}.log@$(System.JobAttempt) + displayName: "Archive sonic kvm logs" + condition: succeededOrFailed() + +- task: PublishTestResults@2 + inputs: + testResultsFiles: '$(Build.ArtifactStagingDirectory)/logs/**/*.xml' + testRunTitle: kvmtest.${{ parameters.tbtype }} + condition: succeededOrFailed() diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 000000000000..8790ea4efd61 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,35 @@ +# This is a comment. +# Each line is a file pattern followed by one or more owners. + +# rules are explained here +# https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners + +# These owners will be the default owners for everything in +# the repo. Unless a later match takes precedence, +# @lguohan will be requested for review when someone opens +# a pull request. +* @lguohan + +/device/ @jleveque + +# build +/rules/ @qiluo-msft @xumia @lguohan +/Makefile @qiluo-msft @xumia @lguohan +/Makefile.cache @qiluo-msft @xumia @lguohan +/Makefile.work @qiluo-msft @xumia @lguohan +/slave.mk @qiluo-msft @xumia @lguohan +/scripts @qiluo-msft @xumia @lguohan + +# installer +/installer/ @qiluo-msft + +# permission +/files/image_config/sudoers/ @qiluo-msft + +# dockers +/dockers/docker-base*/ @qiluo-msft +/dockers/docker-config-engine*/ @qiluo-msft +/dockers/docker-snmp/ @qiluo-msft + +# src +/src/initramfs-tools/ @qiluo-msft diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index 05f39760b195..000000000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,60 +0,0 @@ - - -**Description** - - - -**Steps to reproduce the issue:** -1. -2. -3. - -**Describe the results you received:** - - -**Describe the results you expected:** - - -**Additional information you deem important (e.g. issue happens only occasionally):** - - **Output of `show version`:** - - ``` - (paste your output here) - ``` - - **Attach debug file `sudo generate_dump`:** - - ``` - (paste your output here) - ``` diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 2ac7d9e47730..000000000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,26 +0,0 @@ - - -**- What I did** - -**- How I did it** - -**- How to verify it** - -**- Description for the changelog** - - - -**- A picture of a cute animal (not mandatory but encouraged)** diff --git a/.github/issue_template.md b/.github/issue_template.md new file mode 100644 index 000000000000..d460bdc31d66 --- /dev/null +++ b/.github/issue_template.md @@ -0,0 +1,58 @@ + + +#### Description + + + +#### Steps to reproduce the issue: +1. +2. +3. + +#### Describe the results you received: + + +#### Describe the results you expected: + + +#### Output of `show version`: + +``` +(paste your output here) +``` + +#### Additional information you deem important (e.g. issue happens only occasionally): + + diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 000000000000..d2c06ae13abe --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,41 @@ + + +#### Why I did it + +#### How I did it + +#### How to verify it + +#### Which release branch to backport (provide reason below if selected) + + + +- [ ] 201811 +- [ ] 201911 +- [ ] 202006 +- [ ] 202012 + +#### Description for the changelog + + + +#### A picture of a cute animal (not mandatory but encouraged) + diff --git a/.gitignore b/.gitignore index d9ca023fedc3..7e2f73f718e9 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ .arch .platform .screen +rules/config.user # Build artifacts fsroot/ @@ -20,111 +21,18 @@ target/ *dbg.j2 *.img -# 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/* -!src/isc-dhcp/Makefile -!src/isc-dhcp/patch -src/socat/* -!src/socat/Makefile -!src/socat/*.patch -src/tacacs/* -src/tacacs/nsm/* -src/tacacs/pam/* -!src/tacacs/nsm/Makefile -!src/tacacs/nsm/*.patch -!src/tacacs/pam/Makefile -!src/tacacs/pam/*.patch -src/hiredis/* -!src/hiredis/Makefile -src/igb/* -!src/igb/Makefile -src/initramfs-tools/* -!src/initramfs-tools/Makefile -src/iproute2/* -!src/iproute2/Makefile -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 -src/libyang/* -!src/libyang/Makefile -src/lldpd/* -!src/lldpd/Makefile -!src/lldpd/patch/ -src/lm-sensors/* -!src/lm-sensors/Makefile -src/monit/* -!src/monit/Makefile -!src/monit/patch/ -src/mpdecimal/* -!src/mpdecimal/Makefile -src/python-click/* -!src/python-click/Makefile -src/python3/* -!src/python3/Makefile -src/radvd/* -!src/radvd/Makefile -!src/radvd/patch/ -src/redis/* -!src/redis/Makefile -src/smartmontools/* -!src/smartmontools/Makefile -src/snmpd/* -!src/snmpd/Makefile -src/sonic-device-data/src/device/ -src/sonic-device-data/src/debian/ -src/supervisor/* -!src/supervisor/Makefile -!src/supervisor/patch/ -src/swig/* -!src/swig/Makefile -src/systemd-sonic-generator/systemd-sonic-generator -src/systemd-sonic-generator/debian/* -!src/systemd-sonic-generator/debian/changelog -!src/systemd-sonic-generator/debian/compat -!src/systemd-sonic-generator/debian/control -!src/systemd-sonic-generator/debian/rules -src/telemetry/debian/* -!src/telemetry/debian/changelog -!src/telemetry/debian/compat -!src/telemetry/debian/control -!src/telemetry/debian/rules -!src/telemetry/debian/telemetry.init.d -src/thrift/* -!src/thrift/patch/ -!src/thrift/Makefile - # Autogenerated Dockerfiles sonic-slave*/Dockerfile +sonic-slave*/Dockerfile.user dockers/*/Dockerfile platform/*/docker-*/Dockerfile # Installer-related files and directories installer/x86_64/platforms/ -# Config engine -src/sonic-config-engine/**/*.pyc -src/sonic-config-engine/build -src/sonic-config-engine/sonic_config_engine.egg-info -src/sonic-daemon-base/**/*.pyc -src/sonic-daemon-base/build -src/sonic-daemon-base/sonic_daemon_base.egg-info - # Misc. files +asic_config_checksum +files/Aboot/boot0 files/initramfs-tools/arista-convertfs files/initramfs-tools/union-mount @@ -141,3 +49,23 @@ src/**/debian/stamp-autotools-files # .o files src/**/*.o + +# platform +platform/**/*.egg-info +platform/**/*-none-any.whl +platform/**/.pybuild +platform/**/debian/* +platform/**/build +platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/ipmihelper.py +platform/broadcom/sonic-platform-modules-dell/s6100/modules/dell_ich.c +platform/broadcom/sonic-platform-modules-dell/s6100/modules/dell_s6100_lpc.c +platform/broadcom/sonic-platform-modules-dell/z9100/modules/dell_ich.c +platform/broadcom/sonic-platform-modules-dell/z9100/modules/dell_mailbox.c +platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/ipmihelper.py + +# buildinfo +files/build/buildinfo +files/build/tmp +dockers/**/buildinfo +platform/**/buildinfo +sonic-slave*/**/buildinfo diff --git a/.gitmodules b/.gitmodules index 4fd4bd52be6c..9f2ae12ebb46 100644 --- a/.gitmodules +++ b/.gitmodules @@ -47,7 +47,7 @@ [submodule "src/sonic-frr/frr"] path = src/sonic-frr/frr url = https://github.com/Azure/sonic-frr.git - branch = frr/7.2 + branch = frr/7.5 [submodule "platform/p4/p4-hlir/p4-hlir-v1.1"] path = platform/p4/p4-hlir/p4-hlir-v1.1 url = https://github.com/p4lang/p4-hlir.git @@ -82,3 +82,9 @@ path = src/sonic-restapi url = https://github.com/Azure/sonic-restapi.git branch = master +[submodule "src/sonic-mgmt-common"] + path = src/sonic-mgmt-common + url = https://github.com/Azure/sonic-mgmt-common.git +[submodule "src/wpasupplicant/sonic-wpa-supplicant"] + path = src/wpasupplicant/sonic-wpa-supplicant + url = https://github.com/Azure/sonic-wpa-supplicant.git diff --git a/Makefile b/Makefile index 13a3f247fc31..2231e6d98231 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,17 @@ # SONiC make file -NOJESSIE ?= 0 +NOJESSIE ?= 1 +NOSTRETCH ?= 0 %:: @echo "+++ --- Making $@ --- +++" ifeq ($(NOJESSIE), 0) - EXTRA_JESSIE_TARGETS=$(notdir $@) make -f Makefile.work jessie + EXTRA_DOCKER_TARGETS=$(notdir $@) make -f Makefile.work jessie endif - BLDENV=stretch make -f Makefile.work $@ +ifeq ($(NOSTRETCH), 0) + EXTRA_DOCKER_TARGETS=$(notdir $@) BLDENV=stretch make -f Makefile.work stretch +endif + BLDENV=buster make -f Makefile.work $@ jessie: @echo "+++ Making $@ +++" @@ -15,9 +19,26 @@ ifeq ($(NOJESSIE), 0) make -f Makefile.work jessie endif -clean reset init configure showtag sonic-slave-build sonic-slave-bash : +stretch: + @echo "+++ Making $@ +++" +ifeq ($(NOSTRETCH), 0) + make -f Makefile.work stretch +endif + +init: + @echo "+++ Making $@ +++" + make -f Makefile.work $@ + +clean configure reset showtag sonic-slave-build sonic-slave-bash : @echo "+++ Making $@ +++" ifeq ($(NOJESSIE), 0) make -f Makefile.work $@ endif +ifeq ($(NOSTRETCH), 0) BLDENV=stretch make -f Makefile.work $@ +endif + BLDENV=buster make -f Makefile.work $@ + +# Freeze the versions, see more detail options: scripts/versions_manager.py freeze -h +freeze: + @scripts/versions_manager.py freeze $(FREEZE_VERSION_OPTIONS) diff --git a/Makefile.cache b/Makefile.cache index b1e5903a60b7..4037222ffc93 100644 --- a/Makefile.cache +++ b/Makefile.cache @@ -8,12 +8,12 @@ # # Email : kalimuthu.velappan@broadcom.com # greg.paussa@broadcom.com -# +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -68,12 +68,13 @@ # Run the 'touch cache.skip.common' command in the base directory to exclude the common files from caching SONIC_COMMON_FILES_LIST := $(if $(wildcard cache.skip.common),, .platform slave.mk rules/functions Makefile.cache) SONIC_COMMON_FLAGS_LIST := $(CONFIGURED_PLATFORM) \ - $(SONIC_DPKG_CACHE_SOURCE) $(SONIC_DEBUGGING_ON) \ - $(SONIC_PROFILING_ON) $(SONIC_SANITIZER_ON) + $(SONIC_DEBUGGING_ON) \ + $(SONIC_PROFILING_ON) $(SONIC_ENABLE_SYNCD_RPC) SONIC_COMMON_DPKG_LIST := debian/control debian/changelog debian/rules \ debian/compat debian/install debian/copyright -SONIC_COMMON_BASE_FILES_LIST := sonic-slave-jessie/Dockerfile.j2 sonic-slave-jessie/Dockerfile.user \ - sonic-slave-stretch/Dockerfile.j2 sonic-slave-stretch/Dockerfile.user +SONIC_COMMON_BASE_FILES_LIST := sonic-slave-jessie/Dockerfile.j2 sonic-slave-jessie/Dockerfile.user.j2 \ + sonic-slave-stretch/Dockerfile.j2 sonic-slave-stretch/Dockerfile.user.j2 \ + sonic-slave-buster/Dockerfile.j2 sonic-slave-buster/Dockerfile.user.j2 @@ -88,11 +89,13 @@ endif -include $(PLATFORM_PATH)/rules.dep endif +ifndef SONIC_BUILD_QUIETER $(info "SONIC_DPKG_CACHE_METHOD" : "$(SONIC_DPKG_CACHE_METHOD)") ifneq ($(SONIC_DPKG_CACHE_METHOD),none) $(info "DPKG_CACHE_PATH" : "$(SONIC_DPKG_CACHE_SOURCE)") endif $(info ) +endif ############################################################################### @@ -105,7 +108,7 @@ MOD_CACHE_LOCK_TIMEOUT := 3600 SONIC_DPKG_LOCAL_CACHE_DIR=${TARGET_PATH}/cache $(shell test -d $(SONIC_DPKG_LOCAL_CACHE_DIR) || \ mkdir -p $(SONIC_DPKG_LOCAL_CACHE_DIR) && chmod 777 $(SONIC_DPKG_LOCAL_CACHE_DIR) ) -$(shell test -w $(SONIC_DPKG_CACHE_DIR) || sudo chmod 777 $(SONIC_DPKG_CACHE_DIR) ) +$(shell test -w $(SONIC_DPKG_CACHE_DIR) || sudo chmod 777 $(SONIC_DPKG_CACHE_DIR) ) DOCKER_LOCKFILE_SUFFIX := access DOCKER_LOCKFILE_TIMEOUT := 1200 @@ -172,8 +175,14 @@ define GET_MOD_DEP_SHA $(if $($(dfile)_MAIN_DEB),$($(dfile)_MAIN_DEB),$(dfile))) ) $(if $(MDEBUG), $(info $(1)_MOD_DEP_PKGS: $($(1)_MOD_DEP_PKGS))) - $(eval $(1)_DEP_MOD_SHA := $(shell git hash-object \ - $(foreach dfile,$($(1)_MOD_DEP_PKGS), $($(dfile)_DEP_FLAGS_FILE) $($(dfile)_MOD_HASH_FILE) $($(dfile)_SMOD_HASH_FILE) ) \ + + # Warn if there is any missing dependency files + $(eval $(1)_DEP_MOD_SHA_FILES := $(foreach dfile,$($(1)_MOD_DEP_PKGS), \ + $($(dfile)_DEP_FLAGS_FILE) $($(dfile)_MOD_HASH_FILE) $($(dfile)_SMOD_HASH_FILE)) ) + $(eval $(1)_DEP_FILES_MISSING := $(filter-out $(wildcard $($(1)_DEP_MOD_SHA_FILES)),$($(1)_DEP_MOD_SHA_FILES)) ) + $(if $($(1)_DEP_FILES_MISSING), $(warning "[ DPKG ] Dependecy file(s) are not found for $(1) : $($(1)_DEP_FILES_MISSING))) + + $(eval $(1)_DEP_MOD_SHA := $(shell git hash-object $($(1)_DEP_MOD_SHA_FILES) \ | sha1sum | awk '{print substr($$1,0,23);}')) endef @@ -240,11 +249,10 @@ define LOAD_FROM_CACHE # Update the cache_loaded variable $(if $(and $(CACHE_FILE_SELECT),$(filter $(RCACHE_OPTIONS),$(SONIC_DPKG_CACHE_METHOD))), $(if $(LOAD_DRV_DEB), $($(1)_CACHE_USER) tar -C $($(1)_BASE_PATH) -mxzvf $(CACHE_FILE_SELECT) 1>> $($(1)_DST_PATH)/$(1).log ,echo ); - echo "File $(CACHE_FILE_SELECT) is loaded from cache" >> $($(1)_DST_PATH)/$(1).log + echo "File $(CACHE_FILE_SELECT) is loaded from cache into $($(1)_BASE_PATH)" >> $($(1)_DST_PATH)/$(1).log $(eval $(1)_CACHE_LOADED := Yes) - $(shell touch $(CACHE_FILE_SELECT)) + $(if $(call CHECK_WCACHE_ENABLED,$(1)), $(shell touch $(CACHE_FILE_SELECT))) echo "[ CACHE::LOADED ] $($(1)_CACHE_DIR)/$($(1)_MOD_CACHE_FILE)" >> $($(1)_DST_PATH)/$(1).log - , echo "File $($(1)_CACHE_DIR)/$($(1)_MOD_CACHE_FILE) is not present in cache or cache mode set as $(SONIC_DPKG_CACHE_METHOD) !" >> $($(1)_DST_PATH)/$(1).log echo "[ CACHE::SKIPPED ] $($(1)_CACHE_DIR)/$($(1)_MOD_CACHE_FILE)" >> $($(1)_DST_PATH)/$(1).log echo "[ CACHE::SKIPPED ] DEP_FILES - Modified Files: [$($(1)_FILES_MODIFIED)] " >> $($(1)_DST_PATH)/$(1).log @@ -315,11 +323,11 @@ define SHOW_WHY $(if $($(1)_PREREQ_PHONY), PHONY PREREQUISITES: $($(1)_PREREQ_PHONY)))" >> $($(1)_DST_PATH)/$(1).log @echo "[ FLAGS FILE ] : [$($(1)_FILE_FLAGS)] " >> $($(1)_DST_PATH)/$(1).log - @echo "[ FLAGS DEPENDS ] : [$($(1)_DEP_FLAGS)] " >> $($(1)_DST_PATH)/$(1).log + @echo "[ FLAGS DEPENDS ] : [$($(1)_DEP_FLAGS_ALL)] " >> $($(1)_DST_PATH)/$(1).log @echo "[ FLAGS DIFF ] : [$($(1)_FLAGS_DIFF)] " >> $($(1)_DST_PATH)/$(1).log - @echo "[ DEP DEPENDS ] : [$($(1)_DEP_FILES_MODIFIED)] " >> $($(1)_DST_PATH)/$(1).log - @echo "[ SMDEP DEPENDS ] : [$($(1)_SMDEP_FILES_MODIFIED)] " >> $($(1)_DST_PATH)/$(1).log - @echo "[ TARGET DEPENDS ] : [$?] " >> $($(1)_DST_PATH)/$(1).log + @$(file >>$($(1)_DST_PATH)/$(1).log, "[ DEP DEPENDS ] : [$($(1)_DEP_FILES_MODIFIED)] ") + @$(file >>$($(1)_DST_PATH)/$(1).log, "[ SMDEP DEPENDS ] : [$($(1)_SMDEP_FILES_MODIFIED)] ") + @$(file >>$($(1)_DST_PATH)/$(1).log, "[ TARGET DEPENDS ] : [$?] ") endef @@ -455,19 +463,21 @@ $(foreach pkg, $(SONIC_MAKE_DEBS) $(SONIC_DPKG_DEBS) $(SONIC_ONLINE_DEBS) $(SONI # $(1) => target name # $(2) => target destination folder path # $(3) => target file extension +# $(4) => additional flags # # It updates the _DEP_FLAGS variable if there is any change in the module flags. define FLAGS_DEP_RULES ALL_DEP_FILES_LIST += $(foreach pkg,$(2), $(if $(filter none,$($(1)_CACHE_MODE)),$(addsuffix .$(3),$(addprefix $(pkg)/, $(1))))) $(addsuffix .$(3),$(addprefix $(2)/, $(1))) :: $(2)/%.$(3) : - @$$(eval $$*_FILE_FLAGS := $$(shell test -f $$@ && cat $$@)) - @echo '$$($$*_DEP_FLAGS)' | cmp -s - $$@ || echo '$$($$*_DEP_FLAGS)' > $$@ - $$(eval $$*_FLAGS_DIFF := $$(filter-out $$($$*_FILE_FLAGS),$$($$*_DEP_FLAGS)) $$(filter-out $$($$*_DEP_FLAGS),$$($$*_FILE_FLAGS))) + @$$(eval $$*_FILE_FLAGS := $$(shell test -f $$@ && cat $$@)) + @$$(eval $$*_DEP_FLAGS_ALL := $$(shell echo '$$($$*_DEP_FLAGS) $(4)' | sed -E 's/[ ]+/ /g' | sed -E 's/[ ]+$$$$//g')) + @echo '$$($$*_DEP_FLAGS_ALL)' | cmp -s - $$@ || echo '$$($$*_DEP_FLAGS_ALL)' > $$@ + $$(eval $$*_FLAGS_DIFF := $$(filter-out $$($$*_FILE_FLAGS),$$($$*_DEP_FLAGS_ALL)) $$(filter-out $$($$*_DEP_FLAGS_ALL),$$($$*_FILE_FLAGS))) @$$(if $$(MDEBUG), $$(info FLAGS: $$@, DEP:$$?)) endef -$(eval $(call FLAGS_DEP_RULES, $(SONIC_MAKE_DEBS) $(SONIC_DPKG_DEBS) $(SONIC_ONLINE_DEBS) $(SONIC_COPY_DEBS), $(DEBS_PATH),flags) ) -$(eval $(call FLAGS_DEP_RULES, $(SONIC_MAKE_FILES), $(FILES_PATH),flags)) +$(eval $(call FLAGS_DEP_RULES, $(SONIC_MAKE_DEBS) $(SONIC_DPKG_DEBS) $(SONIC_ONLINE_DEBS) $(SONIC_COPY_DEBS), $(DEBS_PATH),flags,$(BLDENV)) ) +$(eval $(call FLAGS_DEP_RULES, $(SONIC_MAKE_FILES), $(FILES_PATH),flags,$(BLDENV))) $(eval $(call FLAGS_DEP_RULES, $(SONIC_PYTHON_STDEB_DEBS), $(PYTHON_DEBS_PATH),flags)) $(eval $(call FLAGS_DEP_RULES, $(SONIC_PYTHON_WHEELS), $(PYTHON_WHEELS_PATH),flags)) $(eval $(call FLAGS_DEP_RULES, $(SONIC_DOCKER_IMAGES) $(SONIC_DOCKER_DBG_IMAGES), $(TARGET_PATH),flags)) @@ -548,8 +558,10 @@ ALL_DEP_FILES_LIST += $(foreach pkg,$(2), $($(filter none,$($(1)_CACHE_MODE)), \ $(addsuffix .$(3),$(addprefix $(2)/, $(1))) : $(2)/%.$(3) : \ $(2)/%.flags $$$$($$$$*_DEP_FILES) $$$$(if $$$$($$$$*_SMDEP_FILES), $(2)/%.smdep) @$$(eval $$*_DEP_FILES_MODIFIED := $$? ) - @$$(file >$$@,$$($$*_DEP_FILES)) - @cat $$@ |xargs git hash-object >$$@.sha + @$$(file >$$@.tmp,$$($$*_DEP_FILES)) + @cat $$@.tmp |xargs git hash-object >$$@.sha.tmp + @if ! cmp -s $$@.sha.tmp $$@.sha; then cp $$@.tmp $$@; cp $$@.sha.tmp $$@.sha; fi + @rm -f $$@.tmp $$@.sha.tmp @$$(if $$(MDEBUG), $$(info DEP: $$@, MOD:$$?)) endef $(eval $(call SHA_DEP_RULES, $(SONIC_MAKE_DEBS) $(SONIC_DPKG_DEBS) $(SONIC_ONLINE_DEBS) $(SONIC_COPY_DEBS), $(DEBS_PATH),dep)) @@ -571,7 +583,7 @@ SONIC_CACHE_CLEAN_DEBS = $(addsuffix -clean,$(addprefix $(DEBS_PATH)/, \ $(SONIC_DPKG_DEBS) \ $(SONIC_DERIVED_DEBS) \ $(SONIC_EXTRA_DEBS))) -$(SONIC_CACHE_CLEAN_DEBS) :: $(DEBS_PATH)/%-clean : .platform $$(addsuffix -clean,$$(addprefix $(DEBS_PATH)/,$$($$*_MAIN_DEB))) +$(SONIC_CACHE_CLEAN_DEBS) :: $(DEBS_PATH)/%-clean : .platform $$(addsuffix -clean,$$(addprefix $(DEBS_PATH)/,$$($$*_MAIN_DEB))) @rm -f $($*_DEP_FLAGS_FILE) $($*_MOD_HASH_FILE) $($*_SMOD_HASH_FILE) \ $($*_MOD_DEP_FILE) $($*_SMOD_DEP_FILE) @@ -581,7 +593,7 @@ SONIC_CACHE_CLEAN_FILES = $(addsuffix -clean,$(addprefix $(FILES_PATH)/, \ $(SONIC_ONLINE_FILES) \ $(SONIC_COPY_FILES) \ $(SONIC_MAKE_FILES))) -$(SONIC_CACHE_CLEAN_FILES) :: $(FILES_PATH)/%-clean : .platform +$(SONIC_CACHE_CLEAN_FILES) :: $(FILES_PATH)/%-clean : .platform @rm -f $($*_DEP_FLAGS_FILE) $($*_MOD_HASH_FILE) $($*_SMOD_HASH_FILE) \ $($*_MOD_DEP_FILE) $($*_SMOD_DEP_FILE) @@ -592,7 +604,7 @@ SONIC_CACHE_CLEAN_TARGETS = $(addsuffix -clean,$(addprefix $(TARGET_PATH)/, \ $(SONIC_DOCKER_DBG_IMAGES) \ $(SONIC_SIMPLE_DOCKER_IMAGES) \ $(SONIC_INSTALLERS))) -$(SONIC_CACHE_CLEAN_TARGETS) :: $(TARGET_PATH)/%-clean : .platform +$(SONIC_CACHE_CLEAN_TARGETS) :: $(TARGET_PATH)/%-clean : .platform @rm -f $($*_DEP_FLAGS_FILE) $($*_MOD_HASH_FILE) $($*_SMOD_HASH_FILE) \ $($*_MOD_DEP_FILE) $($*_SMOD_DEP_FILE) @@ -600,7 +612,7 @@ $(SONIC_CACHE_CLEAN_TARGETS) :: $(TARGET_PATH)/%-clean : .platform # Clean all the DEP and SHA files for all the PYTHON DEBS target SONIC_CACHE_CLEAN_STDEB_DEBS = $(addsuffix -clean,$(addprefix $(PYTHON_DEBS_PATH)/, \ $(SONIC_PYTHON_STDEB_DEBS))) -$(SONIC_CACHE_CLEAN_STDEB_DEBS) :: $(PYTHON_DEBS_PATH)/%-clean : .platform +$(SONIC_CACHE_CLEAN_STDEB_DEBS) :: $(PYTHON_DEBS_PATH)/%-clean : .platform @rm -f $($*_DEP_FLAGS_FILE) $($*_MOD_HASH_FILE) $($*_SMOD_HASH_FILE) \ $($*_MOD_DEP_FILE) $($*_SMOD_DEP_FILE) @@ -608,7 +620,7 @@ $(SONIC_CACHE_CLEAN_STDEB_DEBS) :: $(PYTHON_DEBS_PATH)/%-clean : .platform # Clean all the DEP and SHA files for all the PYTHON WHEELS target SONIC_CACHE_CLEAN_WHEELS = $(addsuffix -clean,$(addprefix $(PYTHON_WHEELS_PATH)/, \ $(SONIC_PYTHON_WHEELS))) -$(SONIC_CACHE_CLEAN_WHEELS) :: $(PYTHON_WHEELS_PATH)/%-clean : .platform +$(SONIC_CACHE_CLEAN_WHEELS) :: $(PYTHON_WHEELS_PATH)/%-clean : .platform @rm -f $($*_DEP_FLAGS_FILE) $($*_MOD_HASH_FILE) $($*_SMOD_HASH_FILE) \ $($*_MOD_DEP_FILE) $($*_SMOD_DEP_FILE) @@ -616,7 +628,7 @@ $(SONIC_CACHE_CLEAN_WHEELS) :: $(PYTHON_WHEELS_PATH)/%-clean : .platform cclean:: $(SONIC_CACHE_CLEAN_DEBS) $(SONIC_CACHE_CLEAN_FILES) $(SONIC_CACHE_CLEAN_TARGETS) \ $(SONIC_CACHE_CLEAN_STDEB_DEBS) $(SONIC_CACHE_CLEAN_WHEELS) -.PHONY: clean +.PHONY: clean clean:: cclean # Clear all the local cache contents @@ -653,7 +665,7 @@ show-%: )\ )\ ) - $(info ) + $(info ) diff --git a/Makefile.work b/Makefile.work index 4e58ab83a40d..654ccb660eb1 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. +# * INCLUDE_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. @@ -31,8 +32,12 @@ # * Default: yes # * Values: yes, no # * KERNEL_PROCURE_METHOD: Specifying method of obtaining kernel Debian package: download or build +# * TELEMETRY_WRITABLE: Enable write/config operations via the gNMI interface. +# * Default: unset +# * Values: y # * SONIC_DPKG_CACHE_METHOD: Specifying method of obtaining the Debian packages from cache: none or cache # * SONIC_DPKG_CACHE_SOURCE: Debian package cache location when cache enabled for debian packages +# * BUILD_LOG_TIMESTAMP: Set timestamp in the build log (simple/none) # ############################################################################### @@ -40,6 +45,9 @@ SHELL = /bin/bash USER := $(shell id -un) PWD := $(shell pwd) +USER_LC := $(shell echo $(USER) | tr A-Z a-z) + +comma := , ifeq ($(USER), root) $(error Add your user account to docker group and use your user account to make. root or sudo are not supported!) @@ -48,7 +56,7 @@ endif # Check for j2cli availability J2_VER := $(shell j2 --version 2>&1 | grep j2cli | awk '{printf $$2}') ifeq ($(J2_VER),) -$(error Install j2cli) +$(error Please install j2cli (sudo pip install j2cli)) endif # Check for minimum Docker version on build host @@ -74,15 +82,40 @@ ifeq ($(PLATFORM_ARCH),) override PLATFORM_ARCH = $(CONFIGURED_ARCH) endif -ifeq ($(BLDENV), stretch) +ifeq ($(BLDENV), buster) +SLAVE_DIR = sonic-slave-buster +else ifeq ($(BLDENV), stretch) SLAVE_DIR = sonic-slave-stretch else SLAVE_DIR = sonic-slave-jessie endif -SLAVE_BASE_TAG = $(shell CONFIGURED_ARCH=$(CONFIGURED_ARCH) j2 $(SLAVE_DIR)/Dockerfile.j2 > $(SLAVE_DIR)/Dockerfile && sha1sum $(SLAVE_DIR)/Dockerfile | awk '{print substr($$1,0,11);}') -SLAVE_TAG = $(shell cat $(SLAVE_DIR)/Dockerfile.user $(SLAVE_DIR)/Dockerfile | sha1sum | awk '{print substr($$1,0,11);}') + +include rules/config + +ifeq ($(ENABLE_DOCKER_BASE_PULL),) + override ENABLE_DOCKER_BASE_PULL = n +endif + +ifeq ($(CONFIGURED_ARCH),amd64) SLAVE_BASE_IMAGE = $(SLAVE_DIR) -SLAVE_IMAGE = $(SLAVE_BASE_IMAGE)-$(USER) +else +SLAVE_BASE_IMAGE = $(SLAVE_DIR)-$(CONFIGURED_ARCH) +endif +SLAVE_IMAGE = $(SLAVE_BASE_IMAGE)-$(USER_LC) + +# Generate the version control build info +$(shell SONIC_VERSION_CONTROL_COMPONENTS=$(SONIC_VERSION_CONTROL_COMPONENTS) \ + TRUSTED_GPG_URLS=$(TRUSTED_GPG_URLS) PACKAGE_URL_PREFIX=$(PACKAGE_URL_PREFIX) \ + scripts/generate_buildinfo_config.sh) + +# Generate the slave Dockerfile, and prepare build info for it +$(shell CONFIGURED_ARCH=$(CONFIGURED_ARCH) j2 $(SLAVE_DIR)/Dockerfile.j2 > $(SLAVE_DIR)/Dockerfile) +$(shell CONFIGURED_ARCH=$(CONFIGURED_ARCH) j2 $(SLAVE_DIR)/Dockerfile.user.j2 > $(SLAVE_DIR)/Dockerfile.user) +$(shell BUILD_SLAVE=y scripts/prepare_docker_buildinfo.sh $(SLAVE_BASE_IMAGE) $(SLAVE_DIR)/Dockerfile $(CONFIGURED_ARCH) "" $(BLDENV)) + +# Add the versions in the tag, if the version change, need to rebuild the slave +SLAVE_BASE_TAG = $(shell cat $(SLAVE_DIR)/Dockerfile $(SLAVE_DIR)/buildinfo/versions/versions-* src/sonic-build-hooks/hooks/* | sha1sum | awk '{print substr($$1,0,11);}') +SLAVE_TAG = $(shell cat $(SLAVE_DIR)/Dockerfile.user $(SLAVE_DIR)/Dockerfile $(SLAVE_DIR)/buildinfo/versions/versions-* | sha1sum | awk '{print substr($$1,0,11);}') OVERLAY_MODULE_CHECK := \ lsmod | grep -q "^overlay " &>/dev/null || \ @@ -100,14 +133,21 @@ ifeq ($(DOCKER_BUILDER_WORKDIR),) override DOCKER_BUILDER_WORKDIR := "/sonic" endif -DOCKER_RUN := docker run --rm=true --privileged \ +DOCKER_RUN := docker run --rm=true --privileged --init \ -v $(DOCKER_BUILDER_MOUNT) \ -w $(DOCKER_BUILDER_WORKDIR) \ -e "http_proxy=$(http_proxy)" \ -e "https_proxy=$(https_proxy)" \ - -i$(if $(TERM),t,) + -i$(shell { if [ -t 0 ]; then echo t; fi }) \ + $(SONIC_BUILDER_EXTRA_CMDLINE) -include rules/config +ifneq ($(DOCKER_BUILDER_USER_MOUNT),) + DOCKER_RUN += $(foreach mount,$(subst $(comma), ,$(DOCKER_BUILDER_USER_MOUNT)), $(addprefix -v , $(mount))) +endif + +ifdef SONIC_BUILD_QUIETER + DOCKER_RUN += -e "SONIC_BUILD_QUIETER=$(SONIC_BUILD_QUIETER)" +endif ifneq ($(SONIC_DPKG_CACHE_SOURCE),) DOCKER_RUN += -v "$(SONIC_DPKG_CACHE_SOURCE):/dpkg_cache:rw" @@ -116,16 +156,20 @@ endif ifeq ($(SONIC_CONFIG_USE_NATIVE_DOCKERD_FOR_BUILD), y) DOCKER_RUN += -v /var/run/docker.sock:/var/run/docker.sock endif + ifneq (,$(filter $(CONFIGURED_ARCH), armhf arm64)) +ifeq ($(DOCKER_DATA_ROOT_FOR_MULTIARCH),) + DOCKER_DATA_ROOT_FOR_MULTIARCH := /var/lib/march/docker +endif # Multiarch docker cannot start dockerd service due to iptables cannot run over different arch kernel SONIC_SERVICE_DOCKERD_FOR_MULTIARCH=y SONIC_NATIVE_DOCKERD_FOR_MUTLIARCH := dockerd --experimental=true --storage-driver=vfs \ - --data-root=/var/lib/march/docker/ --exec-root=/var/run/march/docker/ \ - -H unix:///var/run/march/docker.sock -p /var/run/march/docker.pid + --data-root=$(DOCKER_DATA_ROOT_FOR_MULTIARCH) --exec-root=/var/run/march/docker/ \ + -H unix:///var/run/march/docker.sock -p /var/run/march/docker.pid DOCKER_RUN += -v /var/run/march/docker.sock:/var/run/docker.sock DOCKER_RUN += -v /var/run/march/docker.pid:/var/run/docker.pid DOCKER_RUN += -v /var/run/march/docker:/var/run/docker - DOCKER_RUN += -v /var/lib/march/docker:/var/lib/docker + DOCKER_RUN += -v $(DOCKER_DATA_ROOT_FOR_MULTIARCH):/var/lib/docker SONIC_USERFACL_DOCKERD_FOR_MUTLIARCH := setfacl -m user:$(USER):rw /var/run/march/docker.sock #Override Native config to prevent docker service @@ -155,6 +199,9 @@ DOCKER_BASE_BUILD = docker build --no-cache \ --build-arg https_proxy=$(https_proxy) \ $(SLAVE_DIR) +DOCKER_BASE_PULL = docker pull \ + $(REGISTRY_SERVER):$(REGISTRY_PORT)/$(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) + DOCKER_BUILD = docker build --no-cache \ --build-arg user=$(USER) \ --build-arg uid=$(shell id -u) \ @@ -167,14 +214,18 @@ DOCKER_BUILD = docker build --no-cache \ SONIC_BUILD_INSTRUCTION := make \ -f slave.mk \ - BLDENV=$(BLDENV) \ PLATFORM=$(PLATFORM) \ PLATFORM_ARCH=$(PLATFORM_ARCH) \ BUILD_NUMBER=$(BUILD_NUMBER) \ BUILD_TIMESTAMP=$(BUILD_TIMESTAMP) \ + SONIC_IMAGE_VERSION=$(SONIC_IMAGE_VERSION) \ ENABLE_DHCP_GRAPH_SERVICE=$(ENABLE_DHCP_GRAPH_SERVICE) \ ENABLE_ZTP=$(ENABLE_ZTP) \ SHUTDOWN_BGP_ON_START=$(SHUTDOWN_BGP_ON_START) \ + INCLUDE_KUBERNETES=$(INCLUDE_KUBERNETES) \ + KUBERNETES_VERSION=$(KUBERNETES_VERSION) \ + KUBERNETES_CNI_VERSION=$(KUBERNETES_CNI_VERSION) \ + K8s_GCR_IO_PAUSE_VERSION=$(K8s_GCR_IO_PAUSE_VERSION) \ SONIC_ENABLE_PFCWD_ON_START=$(ENABLE_PFCWD_ON_START) \ SONIC_ENABLE_SYNCD_RPC=$(ENABLE_SYNCD_RPC) \ SONIC_INSTALL_DEBUG_TOOLS=$(INSTALL_DEBUG_TOOLS) \ @@ -189,9 +240,14 @@ SONIC_BUILD_INSTRUCTION := make \ SONIC_DPKG_CACHE_SOURCE=$(SONIC_DPKG_CACHE_SOURCE) \ 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_INCLUDE_SYSTEM_TELEMETRY=$(INCLUDE_SYSTEM_TELEMETRY) \ + SONIC_INCLUDE_RESTAPI=$(INCLUDE_RESTAPI) \ + TELEMETRY_WRITABLE=$(TELEMETRY_WRITABLE) \ + EXTRA_DOCKER_TARGETS=$(EXTRA_DOCKER_TARGETS) \ + BUILD_LOG_TIMESTAMP=$(BUILD_LOG_TIMESTAMP) \ + SONIC_ENABLE_IMAGE_SIGNATURE=$(ENABLE_IMAGE_SIGNATURE) \ + ENABLE_HOST_SERVICE_ON_START=$(ENABLE_HOST_SERVICE_ON_START) \ + SLAVE_DIR=$(SLAVE_DIR) \ $(SONIC_OVERRIDE_BUILD_VARS) .PHONY: sonic-slave-build sonic-slave-bash init reset @@ -207,37 +263,58 @@ ifneq ($(BLDENV), ) endif endif @$(OVERLAY_MODULE_CHECK) - + + @pushd src/sonic-build-hooks; TRUSTED_GPG_URLS=$(TRUSTED_GPG_URLS) make all; popd + @cp src/sonic-build-hooks/buildinfo/sonic-build-hooks* $(SLAVE_DIR)/buildinfo @docker inspect --type image $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) &> /dev/null || \ + { [ $(ENABLE_DOCKER_BASE_PULL) == y ] && { echo Image $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) not found. Pulling...; } && \ + $(DOCKER_BASE_PULL) && \ + { docker tag $(REGISTRY_SERVER):$(REGISTRY_PORT)/$(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) && \ + scripts/collect_docker_version_files.sh $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) target ; } } || \ { echo Image $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) not found. Building... ; \ - $(DOCKER_BASE_BUILD) ; } + $(DOCKER_BASE_BUILD) ; \ + scripts/collect_docker_version_files.sh $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) target ; } @docker inspect --type image $(SLAVE_IMAGE):$(SLAVE_TAG) &> /dev/null || \ { echo Image $(SLAVE_IMAGE):$(SLAVE_TAG) not found. Building... ; \ $(DOCKER_BUILD) ; } ifeq "$(KEEP_SLAVE_ON)" "yes" ifdef SOURCE_FOLDER - @$(DOCKER_RUN) -v $(SOURCE_FOLDER):/var/$(USER)/src $(SLAVE_IMAGE):$(SLAVE_TAG) bash -c "$(SONIC_BUILD_INSTRUCTION) $@; /bin/bash" + @$(DOCKER_RUN) -v $(SOURCE_FOLDER):/var/$(USER)/src $(SLAVE_IMAGE):$(SLAVE_TAG) bash -c "$(SONIC_BUILD_INSTRUCTION) $@; scripts/collect_build_version_files.sh \$$?; /bin/bash" else - @$(DOCKER_RUN) $(SLAVE_IMAGE):$(SLAVE_TAG) bash -c "$(SONIC_BUILD_INSTRUCTION) $@; /bin/bash" + @$(DOCKER_RUN) $(SLAVE_IMAGE):$(SLAVE_TAG) bash -c "$(SONIC_BUILD_INSTRUCTION) $@; scripts/collect_build_version_files.sh \$$?; /bin/bash" endif else - @$(DOCKER_RUN) $(SLAVE_IMAGE):$(SLAVE_TAG) $(SONIC_BUILD_INSTRUCTION) $@ + @$(DOCKER_RUN) $(SLAVE_IMAGE):$(SLAVE_TAG) bash -c "$(SONIC_BUILD_INSTRUCTION) $@; scripts/collect_build_version_files.sh \$$?" endif -sonic-slave-build : - $(DOCKER_BASE_BUILD) - $(DOCKER_BUILD) +sonic-build-hooks: + @pushd src/sonic-build-hooks; TRUSTED_GPG_URLS=$(TRUSTED_GPG_URLS) make all; popd + @cp src/sonic-build-hooks/buildinfo/sonic-build-hooks* $(SLAVE_DIR)/buildinfo -sonic-slave-bash : +sonic-slave-base-build : sonic-build-hooks @$(OVERLAY_MODULE_CHECK) + @echo Checking sonic-slave-base image: $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) @docker inspect --type image $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) &> /dev/null || \ + { [ $(ENABLE_DOCKER_BASE_PULL) == y ] && { echo Image $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) not found. Pulling...; } && \ + $(DOCKER_BASE_PULL) && \ + { docker tag $(REGISTRY_SERVER):$(REGISTRY_PORT)/$(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) && \ + scripts/collect_docker_version_files.sh $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) target ; } } || \ { echo Image $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) not found. Building... ; \ - $(DOCKER_BASE_BUILD) ; } + $(DOCKER_BASE_BUILD) ; \ + scripts/collect_docker_version_files.sh $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) target ; } + +sonic-slave-build : sonic-slave-base-build + @echo Checking sonic-slave image: $(SLAVE_IMAGE):$(SLAVE_TAG) @docker inspect --type image $(SLAVE_IMAGE):$(SLAVE_TAG) &> /dev/null || \ { echo Image $(SLAVE_IMAGE):$(SLAVE_TAG) not found. Building... ; \ $(DOCKER_BUILD) ; } + +sonic-slave-bash : sonic-slave-build @$(DOCKER_RUN) -t $(SLAVE_IMAGE):$(SLAVE_TAG) bash +sonic-slave-run : sonic-slave-build + @$(DOCKER_RUN) $(SLAVE_IMAGE):$(SLAVE_TAG) bash -c "$(SONIC_RUN_CMDS)" + showtag: @echo $(SLAVE_IMAGE):$(SLAVE_TAG) @echo $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) @@ -260,8 +337,9 @@ reset : fi git clean -xfdf; git reset --hard; - git submodule foreach --recursive git clean -xfdf; - git submodule foreach --recursive git reset --hard; + git submodule foreach --recursive 'git clean -xfdf || true'; + git submodule foreach --recursive 'git reset --hard || true'; + git submodule foreach --recursive 'git remote update || true'; git submodule update --init --recursive; echo "Reset complete!"; else diff --git a/README.buildsystem.md b/README.buildsystem.md index f2d804d7e90f..44fa7e5ffffe 100644 --- a/README.buildsystem.md +++ b/README.buildsystem.md @@ -243,7 +243,7 @@ _Recommend: Rename image built using INSTALL_DEBUG_TOOLS=y to mark it explicit. * To debug a core file in non-SONiC environment that supports docker * `docker load -i docker--dbg.gz` * copy your unzipped core file into ~/debug - * `docker run -it -entrypoint=/bin/bash -v ~/debug:/debug ` + * `docker run -it --entrypoint=/bin/bash -v ~/debug:/debug ` * `gdb /usr/bin/ -c /debug/` ### Debug SONiC image diff --git a/README.md b/README.md index f9cef7fba212..b21bfeaf7826 100644 --- a/README.md +++ b/README.md @@ -1,40 +1,68 @@ -*master*: -Innovium: [![Innovium](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-all/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-all) -Barefoot: [![Barefoot](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-all/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-all) -Broadcom: [![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-all/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-all) -Mellanox: [![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-all/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-all) -Nephos: [![Nephos](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-all/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-all) -P4: [![P4](https://sonic-jenkins.westus2.cloudapp.azure.com/job/p4/job/buildimage-p4-all/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/p4/job/buildimage-p4-all) -VS: [![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-all/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-all) - -*201911*: -Innovium: [![Innovium](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-201911/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-201911/) -Broadcom: [![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201911/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201911/) -Mellanox: [![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201911/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201911/) -VS: [![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201911/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201911) - -*201811*: -Innovium: [![Innovium](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-201811/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-201811/) -Broadcom: [![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201811/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201811/) -Mellanox: [![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201811/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201811/) -VS: [![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201811/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201811) - -*201807*: -Broadcom: [![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201807/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201807/) -Barefoot: [![Barefoot](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201807/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201807/) -Mellanox: [![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201807/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201807/) - -*201803*: -Broadcom: [![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201803/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201803/) -Nephos: [![Nephos](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201803/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201803/) -Marvell: [![Marvell](https://sonic-jenkins.westus2.cloudapp.azure.com/job/marvell/job/buildimage-mrvl-201803/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/marvell/job/buildimage-mrvl-201803/) -Mellanox: [![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201803/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201803/) +*static anaylsis*: + +[![Total alerts](https://img.shields.io/lgtm/alerts/g/Azure/sonic-buildimage.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/Azure/sonic-buildimage/alerts/) +[![Language grade: Python](https://img.shields.io/lgtm/grade/python/g/Azure/sonic-buildimage.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/Azure/sonic-buildimage/context:python) + + +*master builds*: + +[![Barefoot](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-all/badge/icon?subject=Barefoot)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-all) +[![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-all/badge/icon?subject=Broadcom)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-all) +[![Centec](https://sonic-jenkins.westus2.cloudapp.azure.com/job/centec/job/buildimage-centec-all/badge/icon?subject=Centec)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/centec/job/buildimage-centec-all) +[![Centec(arm64)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/centec/job/buildimage-centec-arm64-all/badge/icon?subject=Centec(arm64))](https://sonic-jenkins.westus2.cloudapp.azure.com/job/centec/job/buildimage-centec-arm64-all) +[![Innovium](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-all/badge/icon?subject=Innovium)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-all) +[![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-all/badge/icon?subject=Mellanox)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-all) +[![Marvell(armhf)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/marvell/job/buildimage-mrvl-armhf-all/badge/icon?subject=Marvell(armhf))](https://sonic-jenkins.westus2.cloudapp.azure.com/job/marvell/job/buildimage-mrvl-armhf-all) +[![Nephos](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-all/badge/icon?subject=Nephos)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-all) +[![P4](https://sonic-jenkins.westus2.cloudapp.azure.com/job/p4/job/buildimage-p4-all/badge/icon?subject=P4)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/p4/job/buildimage-p4-all) +[![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-image/badge/icon?subject=VS)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-image) + +*202012 builds*: + +[![Barefoot](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-202012/badge/icon?subject=Barefoot)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-202012/) +[![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-202012/badge/icon?subject=Broadcom)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-202012) +[![Centec](https://sonic-jenkins.westus2.cloudapp.azure.com/job/centec/job/buildimage-centec-202012/badge/icon?subject=Centec)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/centec/job/buildimage-centec-202012) +[![Centec(arm64)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/centec/job/buildimage-centec-arm64-202012/badge/icon?subject=Centec(arm64))](https://sonic-jenkins.westus2.cloudapp.azure.com/job/centec/job/buildimage-centec-arm64-202012) +[![Innovium](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-202012/badge/icon?subject=Innovium)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-202012/) +[![Marvell(armhf)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/marvell/job/buildimage-mrvl-armhf-202012/badge/icon?subject=Marvell(armhf))](https://sonic-jenkins.westus2.cloudapp.azure.com/job/marvell/job/buildimage-mrvl-armhf-202012) +[![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-202012/badge/icon?subject=Mellanox)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-202012) +[![Nephos](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-202012/badge/icon?subject=Nephos)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-202012) +[![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-image-202012/badge/icon?subject=VS)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-image-202012) + +*201911 builds*: + +[![Barefoot](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201911/badge/icon?subject=Barefoot)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201911/) +[![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201911/badge/icon?subject=Broadcom)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201911/) +[![Innovium](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-201911/badge/icon?subject=Innovium)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-201911/) +[![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201911/badge/icon?subject=Mellanox)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201911/) +[![Nephos](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201911/badge/icon?subject=Nephos)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201911) +[![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201911/badge/icon?subject=VS)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201911) + +*201811 builds*: + +[![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201811/badge/icon?subject=Broadcom)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201811/) +[![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201811/badge/icon?subject=Mellanox)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201811/) +[![Innovium](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-201811/badge/icon?subject=Innovium)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-201811/) +[![Nephos](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201811/badge/icon?subject=Nephos)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201811) +[![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201811/badge/icon?subject=VS)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201811) + +*201807 builds*: + +[![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201807/badge/icon?subject=Broadcom)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201807/) +[![Barefoot](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201807/badge/icon?subject=Barefoot)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201807/) + +*201803 builds*: + +[![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201803/badge/icon?subject=Broadcom)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201803/) +[![Nephos](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201803/badge/icon?subject=Nephos)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201803/) +[![Marvell](https://sonic-jenkins.westus2.cloudapp.azure.com/job/marvell/job/buildimage-mrvl-201803/badge/icon?subject=Marvell)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/marvell/job/buildimage-mrvl-201803/) +[![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201803/badge/icon?subject=Mellanox)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201803/) # sonic-buildimage ## Build SONiC Switch Images -# Description +# Description Following is the instruction on how to build an [(ONIE)](https://github.com/opencomputeproject/onie) compatible network operating system (NOS) installer image for network switches, and also how to build docker images running inside the NOS. Note that SONiC image are build per ASIC platform. Switches using the same ASIC platform share a common image. For a list of supported switches and ASIC, please refer to this [list](https://github.com/Azure/SONiC/wiki/Supported-Devices-and-Platforms) @@ -55,8 +83,8 @@ Configure your system to allow running the 'docker' command without 'sudo': `sudo gpasswd -a ${USER} docker` Log out and log back in so that your group membership is re-evaluated -## SAI Version -Please refer to [SONiC roadmap](https://github.com/Azure/SONiC/wiki/Sonic-Roadmap-Planning) on the SAI version for each SONiC release. +## SAI Version +Please refer to [SONiC roadmap](https://github.com/Azure/SONiC/wiki/Sonic-Roadmap-Planning) on the SAI version for each SONiC release. ## Clone or fetch the code repository with all git submodules To clone the code repository recursively, assuming git version 1.9 or newer: @@ -131,15 +159,16 @@ To build Arm64 bit for plaform The SONiC installer contains all docker images needed. SONiC uses one image for all devices of a same ASIC vendor. The supported ASIC vendors are: - PLATFORM=broadcom -- PLATFORM=marvell +- PLATFORM=marvell - PLATFORM=mellanox - PLATFORM=cavium - PLATFORM=centec - PLATFORM=nephos +- PLATFORM=innovium - PLATFORM=p4 - PLATFORM=vs -For Broadcom ASIC, we build ONIE and EOS image. EOS image is used for Arista devices, ONIE image is used for all other Broadcom ASIC based devices. +For Broadcom ASIC, we build ONIE and EOS image. EOS image is used for Arista devices, ONIE image is used for all other Broadcom ASIC based devices. make configure PLATFORM=broadcom # build debian stretch required targets @@ -186,6 +215,7 @@ This may take a while, but it is a one-time action, so please be patient. - docker-syncd-cavm.gz: docker image for the daemon to sync database and Cavium switch ASIC (gzip tar archive) - docker-syncd-mlnx.gz: docker image for the daemon to sync database and Mellanox switch ASIC (gzip tar archive) - docker-syncd-nephos.gz: docker image for the daemon to sync database and Nephos switch ASIC (gzip tar archive) + - docker-syncd-invm.gz: docker image for the daemon to sync database and Innovium switch ASIC (gzip tar archive) - docker-sonic-p4.gz: docker image for all-in-one for p4 software switch (gzip tar archive) - docker-sonic-vs.gz: docker image for all-in-one for software virtual switch (gzip tar archive) - docker-sonic-mgmt.gz: docker image for [managing, configuring and monitoring SONiC](https://github.com/Azure/sonic-mgmt) (gzip tar archive) diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 000000000000..5d36ff5be8ec --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,136 @@ +# Starter pipeline +# Start with a minimal pipeline that you can customize to build and deploy your code. +# Add steps that build, run tests, deploy, and more: +# https://aka.ms/yaml + +trigger: + branches: + include: + - master + - 202012 + paths: + exclude: + - .github + +pr: + branches: + include: + - master + paths: + exclude: + - .github + +name: $(TeamProject)_$(Build.DefinitionName)_$(SourceBranchName)_$(Date:yyyyMMdd)$(Rev:.r) + +resources: + repositories: + - repository: sonic-mgmt + type: github + name: Azure/sonic-mgmt + endpoint: build + +stages: +- stage: Build + pool: sonicbld + + jobs: + - template: .azure-pipelines/build-template.yml + parameters: + platform: broadcom + platform_short: brcm + cache_mode: rcache + sync_rpc_image: true + + - template: .azure-pipelines/build-template.yml + parameters: + platform: mellanox + platform_short: mlnx + cache_mode: rcache + sync_rpc_image: true + + - template: .azure-pipelines/build-template.yml + parameters: + platform: vs + platform_short: vs + cache_mode: rcache + +- stage: Test + variables: + - name: inventory + value: veos_vtb + - name: testbed_file + value: vtestbed.csv + + jobs: + - job: + pool: sonictest + displayName: "vstest" + timeoutInMinutes: 60 + steps: + - checkout: self + clean: true + submodules: recursive + displayName: 'Checkout code' + + - task: DownloadPipelineArtifact@2 + inputs: + source: specific + project: build + pipeline: 9 + artifacts: sonic-swss-common.amd64.ubuntu20_04 + runVersion: 'latestFromBranch' + runBranch: 'refs/heads/master' + displayName: "Download sonic swss common deb packages" + + - task: DownloadPipelineArtifact@2 + inputs: + artifact: sonic-buildimage.vs + displayName: "Download sonic-buildimage.vs artifact" + + - script: | + set -x + sudo dpkg -i --force-confask,confnew ../sonic-swss-common.amd64.ubuntu20_04/libswsscommon_1.0.0_amd64.deb + sudo dpkg -i ../sonic-swss-common.amd64.ubuntu20_04/python3-swsscommon_1.0.0_amd64.deb + sudo docker load -i ../target/docker-sonic-vs.gz + docker tag docker-sonic-vs:latest docker-sonic-vs:$(Build.BuildNumber) + username=$(id -un) + + trap "docker ps; docker images; ip netns list; \ + docker rmi docker-sonic-vs:$(Build.BuildNumber); \ + ip netns list | grep -E [-]srv[0-9]+ | awk '{print $1}' | xargs -I {} sudo ip netns delete {}; \ + sudo chown -R ${username}.${username} .; \ + sudo chown -R ${username}.${username} $(System.DefaultWorkingDirectory)" EXIT + pushd platform/vs/tests + sudo py.test -v --junitxml=tr.xml --imgname=docker-sonic-vs:$(Build.BuildNumber) + displayName: "Run vs tests" + + - task: PublishTestResults@2 + inputs: + testResultsFiles: '**/tr.xml' + testRunTitle: vstest + + - job: + pool: sonictest + displayName: "kvmtest-t0" + timeoutInMinutes: 240 + + steps: + - template: .azure-pipelines/run-test-template.yml + parameters: + dut: vlab-01 + tbname: vms-kvm-t0 + ptf_name: ptf_vms6-1 + tbtype: t0 + + - job: + pool: sonictest-t1-lag + displayName: "kvmtest-t1-lag" + timeoutInMinutes: 240 + + steps: + - template: .azure-pipelines/run-test-template.yml + parameters: + dut: vlab-03 + tbname: vms-kvm-t1-lag + ptf_name: ptf_vms6-2 + tbtype: t1-lag diff --git a/build_debian.sh b/build_debian.sh index 37db2bdeb44e..abe5612e293e 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -31,13 +31,8 @@ set -x -e CONFIGURED_ARCH=$([ -f .arch ] && cat .arch || echo amd64) ## docker engine version (with platform) -if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then - # Version name differs between ARCH, copying same version as in sonic-slave docker - DOCKER_VERSION=18.06.3~ce~3-0~debian -else - DOCKER_VERSION=5:18.09.8~3-0~debian-stretch -fi -LINUX_KERNEL_VERSION=4.9.0-11-2 +DOCKER_VERSION=5:18.09.8~3-0~debian-$IMAGE_DISTRO +LINUX_KERNEL_VERSION=4.19.0-12-2 ## Working directory to prepare the file system FILESYSTEM_ROOT=./fsroot @@ -45,6 +40,8 @@ PLATFORM_DIR=platform ## Hostname for the linux image HOSTNAME=sonic DEFAULT_USERINFO="Default admin user,,," +BUILD_TOOL_PATH=src/sonic-build-hooks/buildinfo +TRUSTED_GPG_DIR=$BUILD_TOOL_PATH/trusted.gpg.d ## Read ONIE image related config file . ./onie-image.conf @@ -75,16 +72,12 @@ pushd $FILESYSTEM_ROOT sudo mount --bind . . popd -## Build a basic Debian system by debootstrap -echo '[INFO] Debootstrap...' -if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then - # qemu arm bin executable for cross-building - sudo mkdir -p $FILESYSTEM_ROOT/usr/bin - sudo cp /usr/bin/qemu*static $FILESYSTEM_ROOT/usr/bin || true - sudo http_proxy=$http_proxy debootstrap --variant=minbase --arch $CONFIGURED_ARCH stretch $FILESYSTEM_ROOT http://deb.debian.org/debian -else - sudo http_proxy=$http_proxy debootstrap --variant=minbase --arch $CONFIGURED_ARCH stretch $FILESYSTEM_ROOT http://debian-archive.trafficmanager.net/debian -fi +## Build the host debian base system +echo '[INFO] Build host debian base system...' +TARGET_PATH=$TARGET_PATH scripts/build_debian_base_system.sh $CONFIGURED_ARCH $IMAGE_DISTRO $FILESYSTEM_ROOT + +# Prepare buildinfo +sudo scripts/prepare_debian_image_buildinfo.sh $CONFIGURED_ARCH $IMAGE_DISTRO $FILESYSTEM_ROOT $http_proxy ## Config hostname and hosts, otherwise 'sudo ...' will complain 'sudo: unable to resolve host ...' sudo LANG=C chroot $FILESYSTEM_ROOT /bin/bash -c "echo '$HOSTNAME' > /etc/hostname" @@ -98,17 +91,19 @@ sudo LANG=C chroot $FILESYSTEM_ROOT /bin/bash -c 'echo "sysfs /sys sysfs default ## Setup proxy [ -n "$http_proxy" ] && sudo /bin/bash -c "echo 'Acquire::http::Proxy \"$http_proxy\";' > $FILESYSTEM_ROOT/etc/apt/apt.conf.d/01proxy" +trap_push 'sudo LANG=C chroot $FILESYSTEM_ROOT umount /proc || true' +sudo LANG=C chroot $FILESYSTEM_ROOT mount proc /proc -t proc ## Note: mounting is necessary to makedev and install linux image echo '[INFO] Mount all' ## Output all the mounted device for troubleshooting -mount -trap_push 'sudo umount $FILESYSTEM_ROOT/proc || true' -sudo LANG=C chroot $FILESYSTEM_ROOT mount proc /proc -t proc +sudo LANG=C chroot $FILESYSTEM_ROOT mount + +## Install the trusted gpg public keys +[ -d $TRUSTED_GPG_DIR ] && [ ! -z "$(ls $TRUSTED_GPG_DIR)" ] && sudo cp $TRUSTED_GPG_DIR/* ${FILESYSTEM_ROOT}/etc/apt/trusted.gpg.d/ ## Pointing apt to public apt mirrors and getting latest packages, needed for latest security updates sudo cp files/apt/sources.list.$CONFIGURED_ARCH $FILESYSTEM_ROOT/etc/apt/sources.list sudo cp files/apt/apt.conf.d/{81norecommends,apt-{clean,gzip-indexes,no-languages},no-check-valid-until} $FILESYSTEM_ROOT/etc/apt/apt.conf.d/ -sudo LANG=C chroot $FILESYSTEM_ROOT bash -c 'apt-mark auto `apt-mark showmanual`' ## Note: set lang to prevent locale warnings in your chroot sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y update @@ -129,7 +124,7 @@ fi ## 2. mount supports squashfs ## However, 'dpkg -i' plus 'apt-get install -f' will ignore the recommended dependency. So ## we install busybox explicitly -sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install busybox +sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install busybox linux-base echo '[INFO] Install SONiC linux kernel image' ## Note: duplicate apt-get command to ensure every line return zero sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/initramfs-tools-core_*.deb || \ @@ -165,6 +160,10 @@ sudo chmod +x $FILESYSTEM_ROOT/etc/initramfs-tools/scripts/init-premount/arista- sudo cp files/initramfs-tools/resize-rootfs $FILESYSTEM_ROOT/etc/initramfs-tools/scripts/init-premount/resize-rootfs sudo chmod +x $FILESYSTEM_ROOT/etc/initramfs-tools/scripts/init-premount/resize-rootfs +# Hook into initramfs: run fsck to repair a non-clean filesystem prior to be mounted +sudo cp files/initramfs-tools/fsck-rootfs $FILESYSTEM_ROOT/etc/initramfs-tools/scripts/init-premount/fsck-rootfs +sudo chmod +x $FILESYSTEM_ROOT/etc/initramfs-tools/scripts/init-premount/fsck-rootfs + ## Hook into initramfs: after partition mount and loop file mount ## 1. Prepare layered file system ## 2. Bind-mount docker working directory (docker overlay storage cannot work over overlay rootfs) @@ -183,10 +182,9 @@ if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then sudo chmod +x $FILESYSTEM_ROOT/etc/initramfs-tools/hooks/uboot-utils cat files/initramfs-tools/modules.arm | sudo tee -a $FILESYSTEM_ROOT/etc/initramfs-tools/modules > /dev/null fi - -if [[ $CONFIGURED_ARCH == amd64 ]]; then - ## Install latest intel ixgbe driver - sudo cp $files_path/ixgbe.ko $FILESYSTEM_ROOT/lib/modules/${LINUX_KERNEL_VERSION}-amd64/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe.ko +# Update initramfs for load platform specific modules +if [ -f platform/$CONFIGURED_PLATFORM/modules ]; then + cat platform/$CONFIGURED_PLATFORM/modules | sudo tee -a $FILESYSTEM_ROOT/etc/initramfs-tools/modules > /dev/null fi ## Install docker @@ -194,19 +192,50 @@ echo '[INFO] Install docker' ## Install apparmor utils since they're missing and apparmor is enabled in the kernel ## Otherwise Docker will fail to start sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install apparmor +sudo cp files/image_config/ntp/ntp-apparmor $FILESYSTEM_ROOT/etc/apparmor.d/local/usr.sbin.ntpd sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install apt-transport-https \ ca-certificates \ curl \ gnupg2 \ software-properties-common +if [[ $CONFIGURED_ARCH == armhf ]]; then + # update ssl ca certificates for secure pem + sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT c_rehash +fi sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT curl -o /tmp/docker.gpg -fsSL https://download.docker.com/linux/debian/gpg sudo LANG=C chroot $FILESYSTEM_ROOT apt-key add /tmp/docker.gpg sudo LANG=C chroot $FILESYSTEM_ROOT rm /tmp/docker.gpg sudo LANG=C chroot $FILESYSTEM_ROOT add-apt-repository \ - "deb [arch=$CONFIGURED_ARCH] https://download.docker.com/linux/debian stretch stable" + "deb [arch=$CONFIGURED_ARCH] https://download.docker.com/linux/debian $IMAGE_DISTRO stable" 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 dpkg --compare-versions ${DOCKER_VERSION} ge "18.09"; then + sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install docker-ce=${DOCKER_VERSION} docker-ce-cli=${DOCKER_VERSION} +else + sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install docker-ce=${DOCKER_VERSION} +fi + +# Uninstall 'python3-gi' installed as part of 'software-properties-common' to remove debian version of 'PyGObject' +# pip version of 'PyGObject' will be installed during installation of 'sonic-host-services' +sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y remove software-properties-common gnupg2 python3-gi + +if [ "$INCLUDE_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 kubernetes-cni=${KUBERNETES_CNI_VERSION}-00 + sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install kubelet=${KUBERNETES_VERSION}-00 + sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install kubectl=${KUBERNETES_VERSION}-00 + 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/ @@ -215,9 +244,12 @@ sudo cp files/docker/docker.service.conf $_ ## Fix systemd race between docker and containerd sudo sed -i '/After=/s/$/ containerd.service/' $FILESYSTEM_ROOT/lib/systemd/system/docker.service +## Create redis group +sudo LANG=C chroot $FILESYSTEM_ROOT groupadd -f redis + ## Create default user -## Note: user should be in the group with the same name, and also in sudo/docker group -sudo LANG=C chroot $FILESYSTEM_ROOT useradd -G sudo,docker $USERNAME -c "$DEFAULT_USERINFO" -m -s /bin/bash +## Note: user should be in the group with the same name, and also in sudo/docker/redis groups +sudo LANG=C chroot $FILESYSTEM_ROOT useradd -G sudo,docker,redis $USERNAME -c "$DEFAULT_USERINFO" -m -s /bin/bash ## Create password for the default user echo "$USERNAME:$PASSWORD" | sudo LANG=C chroot $FILESYSTEM_ROOT chpasswd @@ -242,11 +274,9 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in vim \ tcpdump \ dbus \ - ntp \ ntpstat \ openssh-server \ python \ - python-setuptools \ python-apt \ traceroute \ iputils-ping \ @@ -280,14 +310,20 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in ipmitool \ ndisc6 \ makedumpfile \ - conntrack - + conntrack \ + python-pip \ + python3 \ + python3-distutils \ + python3-pip \ + cron \ + haveged \ + jq if [[ $CONFIGURED_ARCH == amd64 ]]; then ## Pre-install the fundamental packages for amd64 (x86) sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install \ flashrom \ - mcelog + rasdaemon fi ## Set /etc/shadow permissions to -rw-------. @@ -301,15 +337,18 @@ sudo LANG=c chroot $FILESYSTEM_ROOT chmod 644 /etc/group sudo LANG=C chroot $FILESYSTEM_ROOT /bin/bash -c "mkdir -p /etc/initramfs-tools/conf.d" sudo LANG=C chroot $FILESYSTEM_ROOT /bin/bash -c "echo 'MODULES=most' >> /etc/initramfs-tools/conf.d/driver-policy" +# Copy vmcore-sysctl.conf to add more vmcore dump flags to kernel +sudo cp files/image_config/kdump/vmcore-sysctl.conf $FILESYSTEM_ROOT/etc/sysctl.d/ + #Adds a locale to a debian system in non-interactive mode sudo sed -i '/^#.* en_US.* /s/^#//' $FILESYSTEM_ROOT/etc/locale.gen && \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT locale-gen "en_US.UTF-8" sudo LANG=en_US.UTF-8 DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT update-locale "LANG=en_US.UTF-8" sudo LANG=C chroot $FILESYSTEM_ROOT bash -c "find /usr/share/i18n/locales/ ! -name 'en_US' -type f -exec rm -f {} +" -# Install certain fundamental packages from stretch-backports in order to get +# Install certain fundamental packages from $IMAGE_DISTRO-backports in order to get # more up-to-date (but potentially less stable) versions -sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y -t stretch-backports install \ +sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y -t $IMAGE_DISTRO-backports install \ picocom if [[ $CONFIGURED_ARCH == amd64 ]]; then @@ -322,10 +361,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/ @@ -355,75 +390,55 @@ EOF sudo sed -i 's/^ListenAddress ::/#ListenAddress ::/' $FILESYSTEM_ROOT/etc/ssh/sshd_config sudo sed -i 's/^#ListenAddress 0.0.0.0/ListenAddress 0.0.0.0/' $FILESYSTEM_ROOT/etc/ssh/sshd_config -## Config sysctl +## Config rsyslog +sudo augtool -r $FILESYSTEM_ROOT --autosave " +rm /files/lib/systemd/system/rsyslog.service/Service/ExecStart/arguments +set /files/lib/systemd/system/rsyslog.service/Service/ExecStart/arguments/1 -n +" + sudo mkdir -p $FILESYSTEM_ROOT/var/core -sudo augtool --autosave " -set /files/etc/sysctl.conf/kernel.core_pattern '|/usr/bin/coredump-compress %e %t %p' +# Config sysctl +sudo augtool --autosave " +set /files/etc/sysctl.conf/kernel.core_pattern '|/usr/local/bin/coredump-compress %e %t %p %P' set /files/etc/sysctl.conf/kernel.softlockup_panic 1 set /files/etc/sysctl.conf/kernel.panic 10 +set /files/etc/sysctl.conf/kernel.hung_task_timeout_secs 300 set /files/etc/sysctl.conf/vm.panic_on_oom 2 set /files/etc/sysctl.conf/fs.suid_dumpable 2 +" -r $FILESYSTEM_ROOT -set /files/etc/sysctl.conf/net.ipv4.conf.default.forwarding 1 -set /files/etc/sysctl.conf/net.ipv4.conf.all.forwarding 1 -set /files/etc/sysctl.conf/net.ipv4.conf.eth0.forwarding 0 - -set /files/etc/sysctl.conf/net.ipv4.conf.default.arp_accept 0 -set /files/etc/sysctl.conf/net.ipv4.conf.default.arp_announce 0 -set /files/etc/sysctl.conf/net.ipv4.conf.default.arp_filter 0 -set /files/etc/sysctl.conf/net.ipv4.conf.default.arp_notify 0 -set /files/etc/sysctl.conf/net.ipv4.conf.default.arp_ignore 0 -set /files/etc/sysctl.conf/net.ipv4.conf.all.arp_accept 0 -set /files/etc/sysctl.conf/net.ipv4.conf.all.arp_announce 1 -set /files/etc/sysctl.conf/net.ipv4.conf.all.arp_filter 0 -set /files/etc/sysctl.conf/net.ipv4.conf.all.arp_notify 1 -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 -set /files/etc/sysctl.conf/net.ipv6.conf.eth0.forwarding 0 - -set /files/etc/sysctl.conf/net.ipv6.conf.default.accept_dad 0 -set /files/etc/sysctl.conf/net.ipv6.conf.all.accept_dad 0 -set /files/etc/sysctl.conf/net.ipv6.conf.eth0.accept_dad 0 - -set /files/etc/sysctl.conf/net.ipv6.conf.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.ipv4.tcp_l3mdev_accept 1 -set /files/etc/sysctl.conf/net.ipv4.udp_l3mdev_accept 1 - -set /files/etc/sysctl.conf/net.core.rmem_max 2097152 -set /files/etc/sysctl.conf/net.core.wmem_max 2097152 - -set /files/etc/sysctl.conf/net.core.somaxconn 512 +sysctl_net_cmd_string="" +while read line; do + [[ "$line" =~ ^#.*$ ]] && continue + sysctl_net_conf_key=`echo $line | awk -F '=' '{print $1}'` + sysctl_net_conf_value=`echo $line | awk -F '=' '{print $2}'` + sysctl_net_cmd_string=$sysctl_net_cmd_string"set /files/etc/sysctl.conf/$sysctl_net_conf_key $sysctl_net_conf_value"$'\n' +done < files/image_config/sysctl/sysctl-net.conf -" -r $FILESYSTEM_ROOT +sudo augtool --autosave "$sysctl_net_cmd_string" -r $FILESYSTEM_ROOT -if [[ $CONFIGURED_ARCH == amd64 ]]; then - # Configure mcelog to log machine checks to syslog - sudo sed -i 's/^#syslog = yes/syslog = yes/' $FILESYSTEM_ROOT/etc/mcelog/mcelog.conf -fi +# Upgrade pip via PyPI and uninstall the Debian version +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install --upgrade 'pip<21' +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install --upgrade pip +sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get purge -y python-pip python3-pip + +# For building Python packages +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install 'setuptools==40.8.0' +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install 'wheel==0.35.1' +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install 'setuptools==49.6.00' +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install 'wheel==0.35.1' + +# docker Python API package is needed by Ansible docker module as well as some SONiC applications +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install 'docker==4.3.1' + +# Install scapy +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install 'scapy==2.4.4' -## docker-py is needed by Ansible docker module -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT easy_install pip -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install 'docker-py==1.6.0' ## Note: keep pip installed for maintainance purpose -## Get gcc and python dev pkgs -sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install gcc libpython2.7-dev -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install 'netifaces==0.10.7' +# Install GCC, needed for building/installing some Python packages +sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install gcc ## Create /var/run/redis folder for docker-database to mount sudo mkdir -p $FILESYSTEM_ROOT/var/run/redis @@ -446,10 +461,15 @@ if [ -f files/image_config/ntp/ntp ]; then sudo cp ./files/image_config/ntp/ntp $FILESYSTEM_ROOT/etc/init.d/ fi +if [ -f files/image_config/ntp/ntp-systemd-wrapper ]; then + sudo mkdir -p $FILESYSTEM_ROOT/usr/lib/ntp/ + sudo cp ./files/image_config/ntp/ntp-systemd-wrapper $FILESYSTEM_ROOT/usr/lib/ntp/ +fi + ## Version file sudo mkdir -p $FILESYSTEM_ROOT/etc/sonic sudo tee $FILESYSTEM_ROOT/etc/sonic/sonic_version.yml > /dev/null <> .imagehash zip -g $OUTPUT_ABOOT_IMAGE .imagehash zip -g $ABOOT_BOOT_IMAGE .imagehash @@ -143,6 +147,12 @@ elif [ "$IMAGE_TYPE" = "aboot" ]; then zip -g $OUTPUT_ABOOT_IMAGE $ABOOT_BOOT_IMAGE rm $ABOOT_BOOT_IMAGE + if [ "$SONIC_ENABLE_IMAGE_SIGNATURE" = "y" ]; then + TARGET_CA_CERT="$TARGET_PATH/ca.cert" + rm -f "$TARGET_CA_CERT" + [ -f "$CA_CERT" ] && cp "$CA_CERT" "$TARGET_CA_CERT" + ./scripts/sign_image.sh -i "$OUTPUT_ABOOT_IMAGE" -k "$SIGNING_KEY" -c "$SIGNING_CERT" -a "$TARGET_CA_CERT" + fi else echo "Error: Non supported image type $IMAGE_TYPE" exit 1 diff --git a/check_install.py b/check_install.py index d95d831daa70..ed0d8018afe7 100755 --- a/check_install.py +++ b/check_install.py @@ -1,10 +1,11 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 -import pexpect import argparse +import pexpect import sys import time + def main(): parser = argparse.ArgumentParser(description='test_login cmdline parser') @@ -21,16 +22,16 @@ def main(): login_prompt = 'sonic login:' passwd_prompt = 'Password:' - cmd_prompt = "%s@sonic:~\$ $" % args.u + cmd_prompt = "{}@sonic:~\$ $".format(args.u) grub_selection = "The highlighted entry will be executed" i = 0 while True: try: - p = pexpect.spawn("telnet 127.0.0.1 %s" % args.p, timeout=600, logfile=sys.stdout) + p = pexpect.spawn("telnet 127.0.0.1 {}".format(args.p), timeout=600, logfile=sys.stdout, encoding='utf-8') break except Exception as e: - print str(e) + print(str(e)) i += 1 if i == 10: raise @@ -57,6 +58,8 @@ def main(): # check version time.sleep(5) + p.sendline('uptime') + p.expect([cmd_prompt]) p.sendline('show version') p.expect([cmd_prompt]) p.sendline('show ip bgp sum') @@ -64,5 +67,6 @@ def main(): p.sendline('sync') p.expect([cmd_prompt]) + if __name__ == '__main__': main() diff --git a/device/accton/x86_64-accton_as4630_54pe-r0/Accton-AS4630-54PE/hx5-as4630-48x1G+4x25G+2x100G.bcm b/device/accton/x86_64-accton_as4630_54pe-r0/Accton-AS4630-54PE/hx5-as4630-48x1G+4x25G+2x100G.bcm index a7f89ba4c62d..331f6d002647 100755 --- a/device/accton/x86_64-accton_as4630_54pe-r0/Accton-AS4630-54PE/hx5-as4630-48x1G+4x25G+2x100G.bcm +++ b/device/accton/x86_64-accton_as4630_54pe-r0/Accton-AS4630-54PE/hx5-as4630-48x1G+4x25G+2x100G.bcm @@ -19,7 +19,10 @@ l2_mem_entries=32768 #l3_mem_entries=49152 #fpem_mem_entries=16384 l2xmsg_mode=1 +l3_alpm_enable=2 +ipv6_lpm_128b_enable=1 port_flex_enable=1 +ifp_inports_support_enable=1 #3x PM4x10Q (3 * 16 = 48 physical ports) #Doesn't support oversubscribe in Q mode diff --git a/device/accton/x86_64-accton_as4630_54pe-r0/Accton-AS4630-54PE/port_config.ini b/device/accton/x86_64-accton_as4630_54pe-r0/Accton-AS4630-54PE/port_config.ini index aabb372bf649..f8965dfe41d0 100755 --- a/device/accton/x86_64-accton_as4630_54pe-r0/Accton-AS4630-54PE/port_config.ini +++ b/device/accton/x86_64-accton_as4630_54pe-r0/Accton-AS4630-54PE/port_config.ini @@ -1,55 +1,55 @@ -# name lanes alias index speed -Ethernet0 26 thousandE1 1 1000 -Ethernet1 25 thousandE2 2 1000 -Ethernet2 28 thousandE3 3 1000 -Ethernet3 27 thousandE4 4 1000 -Ethernet4 30 thousandE5 5 1000 -Ethernet5 29 thousandE6 6 1000 -Ethernet6 32 thousandE7 7 1000 -Ethernet7 31 thousandE8 8 1000 -Ethernet8 38 thousandE9 9 1000 -Ethernet9 37 thousandE10 10 1000 -Ethernet10 40 thousandE11 11 1000 -Ethernet11 39 thousandE12 12 1000 -Ethernet12 34 thousandE13 13 1000 -Ethernet13 33 thousandE14 14 1000 -Ethernet14 36 thousandE15 15 1000 -Ethernet15 35 thousandE16 16 1000 -Ethernet16 46 thousandE17 17 1000 -Ethernet17 45 thousandE18 18 1000 -Ethernet18 48 thousandE19 19 1000 -Ethernet19 47 thousandE20 20 1000 -Ethernet20 42 thousandE21 21 1000 -Ethernet21 41 thousandE22 22 1000 -Ethernet22 44 thousandE23 23 1000 -Ethernet23 43 thousandE24 24 1000 -Ethernet24 2 thousandE25 25 1000 -Ethernet25 1 thousandE26 26 1000 -Ethernet26 4 thousandE27 27 1000 -Ethernet27 3 thousandE28 28 1000 -Ethernet28 6 thousandE29 29 1000 -Ethernet29 5 thousandE30 30 1000 -Ethernet30 8 thousandE31 31 1000 -Ethernet31 7 thousandE32 32 1000 -Ethernet32 10 thousandE33 33 1000 -Ethernet33 9 thousandE34 34 1000 -Ethernet34 12 thousandE35 35 1000 -Ethernet35 11 thousandE36 36 1000 -Ethernet36 14 thousandE37 37 1000 -Ethernet37 13 thousandE38 38 1000 -Ethernet38 16 thousandE39 39 1000 -Ethernet39 15 thousandE40 40 1000 -Ethernet40 18 thousandE41 41 1000 -Ethernet41 17 thousandE42 42 1000 -Ethernet42 20 thousandE43 43 1000 -Ethernet43 19 thousandE44 44 1000 -Ethernet44 22 thousandE45 45 1000 -Ethernet45 21 thousandE46 46 1000 -Ethernet46 24 thousandE47 47 1000 -Ethernet47 23 thousandE48 48 1000 -Ethernet48 67 twentyfiveGigE49 49 25000 -Ethernet49 66 twentyfiveGigE50 50 25000 -Ethernet50 65 twentyfiveGigE51 51 25000 -Ethernet51 68 twentyfiveGigE52 52 25000 -Ethernet52 73,74,75,76 hundredGigE53 53 100000 -Ethernet56 69,70,71,72 hundredGigE54 54 100000 +# name lanes alias index speed autoneg +Ethernet0 26 thousandE1 1 1000 1 +Ethernet1 25 thousandE2 2 1000 1 +Ethernet2 28 thousandE3 3 1000 1 +Ethernet3 27 thousandE4 4 1000 1 +Ethernet4 30 thousandE5 5 1000 1 +Ethernet5 29 thousandE6 6 1000 1 +Ethernet6 32 thousandE7 7 1000 1 +Ethernet7 31 thousandE8 8 1000 1 +Ethernet8 38 thousandE9 9 1000 1 +Ethernet9 37 thousandE10 10 1000 1 +Ethernet10 40 thousandE11 11 1000 1 +Ethernet11 39 thousandE12 12 1000 1 +Ethernet12 34 thousandE13 13 1000 1 +Ethernet13 33 thousandE14 14 1000 1 +Ethernet14 36 thousandE15 15 1000 1 +Ethernet15 35 thousandE16 16 1000 1 +Ethernet16 46 thousandE17 17 1000 1 +Ethernet17 45 thousandE18 18 1000 1 +Ethernet18 48 thousandE19 19 1000 1 +Ethernet19 47 thousandE20 20 1000 1 +Ethernet20 42 thousandE21 21 1000 1 +Ethernet21 41 thousandE22 22 1000 1 +Ethernet22 44 thousandE23 23 1000 1 +Ethernet23 43 thousandE24 24 1000 1 +Ethernet24 2 thousandE25 25 1000 1 +Ethernet25 1 thousandE26 26 1000 1 +Ethernet26 4 thousandE27 27 1000 1 +Ethernet27 3 thousandE28 28 1000 1 +Ethernet28 6 thousandE29 29 1000 1 +Ethernet29 5 thousandE30 30 1000 1 +Ethernet30 8 thousandE31 31 1000 1 +Ethernet31 7 thousandE32 32 1000 1 +Ethernet32 10 thousandE33 33 1000 1 +Ethernet33 9 thousandE34 34 1000 1 +Ethernet34 12 thousandE35 35 1000 1 +Ethernet35 11 thousandE36 36 1000 1 +Ethernet36 14 thousandE37 37 1000 1 +Ethernet37 13 thousandE38 38 1000 1 +Ethernet38 16 thousandE39 39 1000 1 +Ethernet39 15 thousandE40 40 1000 1 +Ethernet40 18 thousandE41 41 1000 1 +Ethernet41 17 thousandE42 42 1000 1 +Ethernet42 20 thousandE43 43 1000 1 +Ethernet43 19 thousandE44 44 1000 1 +Ethernet44 22 thousandE45 45 1000 1 +Ethernet45 21 thousandE46 46 1000 1 +Ethernet46 24 thousandE47 47 1000 1 +Ethernet47 23 thousandE48 48 1000 1 +Ethernet48 67 twentyfiveGigE49 49 25000 0 +Ethernet49 66 twentyfiveGigE50 50 25000 0 +Ethernet50 65 twentyfiveGigE51 51 25000 0 +Ethernet51 68 twentyfiveGigE52 52 25000 0 +Ethernet52 73,74,75,76 hundredGigE53 53 100000 0 +Ethernet56 69,70,71,72 hundredGigE54 54 100000 0 diff --git a/device/accton/x86_64-accton_as4630_54pe-r0/custom_led.bin b/device/accton/x86_64-accton_as4630_54pe-r0/custom_led.bin new file mode 100644 index 000000000000..0f6e37a82492 Binary files /dev/null and b/device/accton/x86_64-accton_as4630_54pe-r0/custom_led.bin differ diff --git a/device/accton/x86_64-accton_as4630_54pe-r0/led_proc_init.soc b/device/accton/x86_64-accton_as4630_54pe-r0/led_proc_init.soc index 4fa004f5d130..5bef973ed2ae 100755 --- a/device/accton/x86_64-accton_as4630_54pe-r0/led_proc_init.soc +++ b/device/accton/x86_64-accton_as4630_54pe-r0/led_proc_init.soc @@ -1,2 +1,3 @@ +m0 load 0 0x3800 /usr/share/sonic/platform/custom_led.bin led start led auto on diff --git a/device/accton/x86_64-accton_as4630_54pe-r0/media_settings.json b/device/accton/x86_64-accton_as4630_54pe-r0/media_settings.json new file mode 100644 index 000000000000..656f12355205 --- /dev/null +++ b/device/accton/x86_64-accton_as4630_54pe-r0/media_settings.json @@ -0,0 +1,52 @@ +{ + "PORT_MEDIA_SETTINGS": { + "49": { + "Default": { + "preemphasis": { + "lane0":"0x124106" + } + } + }, + "50": { + "Default": { + "preemphasis": { + "lane0":"0x124106" + } + } + }, + "51": { + "Default": { + "preemphasis": { + "lane0":"0x124106" + } + } + }, + "52": { + "Default": { + "preemphasis": { + "lane0":"0x124106" + } + } + }, + "53": { + "Default": { + "preemphasis": { + "lane0":"0x124106", + "lane1":"0x124106", + "lane2":"0x124106", + "lane3":"0x124106" + } + } + }, + "54": { + "Default": { + "preemphasis": { + "lane0":"0x124106", + "lane1":"0x124106", + "lane2":"0x124106", + "lane3":"0x124106" + } + } + } + } +} diff --git a/device/accton/x86_64-accton_as4630_54pe-r0/plugins/eeprom.py b/device/accton/x86_64-accton_as4630_54pe-r0/plugins/eeprom.py index 0d7def70fdc0..3d0ff81ca574 100755 --- a/device/accton/x86_64-accton_as4630_54pe-r0/plugins/eeprom.py +++ b/device/accton/x86_64-accton_as4630_54pe-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -11,11 +8,13 @@ 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") +except ImportError as 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/1-0057/eeprom" super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/accton/x86_64-accton_as4630_54pe-r0/plugins/psuutil.py b/device/accton/x86_64-accton_as4630_54pe-r0/plugins/psuutil.py index a646981334e6..92e08e23afd6 100755 --- a/device/accton/x86_64-accton_as4630_54pe-r0/plugins/psuutil.py +++ b/device/accton/x86_64-accton_as4630_54pe-r0/plugins/psuutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Accton # @@ -13,7 +11,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" diff --git a/device/accton/x86_64-accton_as4630_54pe-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as4630_54pe-r0/plugins/sfputil.py index 33a2630f1d71..fd660ccdc245 100755 --- a/device/accton/x86_64-accton_as4630_54pe-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as4630_54pe-r0/plugins/sfputil.py @@ -15,6 +15,7 @@ SFP_STATUS_INSERTED = '1' SFP_STATUS_REMOVED = '0' + class SfpUtil(SfpUtilBase): """Platform-specific SfpUtil class""" @@ -31,13 +32,13 @@ class SfpUtil(SfpUtilBase): _port_to_eeprom_mapping = {} _port_to_i2c_mapping = { - 49: [18], - 50: [19], - 51: [20], - 52: [21], - 53: [22], - 54: [23], - } + 49: [18], + 50: [19], + 51: [20], + 52: [21], + 53: [22], + 54: [23], + } @property def port_start(self): @@ -49,7 +50,7 @@ def port_end(self): @property def qsfp_ports(self): - return range(self.PORT_START, self.PORTS_IN_BLOCK + 1) + return list(range(self.PORT_START, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -70,15 +71,15 @@ def get_presence(self, port_num): present_path = self.BASE_CPLD_PATH + "module_present_" + str(port_num) self.__port_to_is_present = present_path - content="0" + content = "0" try: val_file = open(self.__port_to_is_present) content = val_file.readline().rstrip() val_file.close() except IOError as e: - print "Error: unable to access file: %s" % str(e) + print("Error: unable to access file: %s" % str(e)) return False - + if content == "1": return True @@ -108,7 +109,7 @@ def get_low_power_mode(self, port_num): return False except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False finally: if eeprom is not None: @@ -123,7 +124,7 @@ def set_low_power_mode(self, port_num, lpmode): try: eeprom = None if not self.get_presence(port_num): - return False # Port is not present, unable to set the eeprom + return False # Port is not present, unable to set the eeprom # Fill in write buffer # 0x3:Low Power Mode, 0x1:High Power Mode @@ -138,7 +139,7 @@ def set_low_power_mode(self, port_num, lpmode): eeprom.write(buffer[0]) return True except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False finally: if eeprom is not None: @@ -153,21 +154,22 @@ def _get_presence_bitmap(self): bits = [] for x in range(self.port_start, self.port_end+1): - bits.append(str(int(self.get_presence(x)))) + bits.append(str(int(self.get_presence(x)))) rev = "".join(bits[::-1]) - return int(rev,2) + return int(rev, 2) + + data = {'present': 0} - data = {'present':0} def get_transceiver_change_event(self, timeout=0): port_dict = {} if timeout == 0: - cd_ms = sys.maxint + cd_ms = sys.maxsize else: cd_ms = timeout - #poll per second + # poll per second while cd_ms > 0: reg_value = self._get_presence_bitmap changed_ports = self.data['present'] ^ reg_value @@ -177,7 +179,7 @@ def get_transceiver_change_event(self, timeout=0): cd_ms = cd_ms - 1000 if changed_ports != 0: - for port in range (self.port_start, self.port_end+1): + for port in range(self.port_start, self.port_end+1): # Mask off the bit corresponding to our port mask = (1 << (port - self.port_start)) if changed_ports & mask: @@ -192,4 +194,3 @@ def get_transceiver_change_event(self, timeout=0): else: return True, {} return False, {} - diff --git a/device/accton/x86_64-accton_as4630_54pe-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as4630_54pe-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as4630_54pe-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as4630_54pe-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as5712_54x-r0/Accton-AS5712-54X/sai.profile b/device/accton/x86_64-accton_as5712_54x-r0/Accton-AS5712-54X/sai.profile index aec436d22608..9020d35fda23 100755 --- a/device/accton/x86_64-accton_as5712_54x-r0/Accton-AS5712-54X/sai.profile +++ b/device/accton/x86_64-accton_as5712_54x-r0/Accton-AS5712-54X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-as5712-72x10G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as5712_54x-r0/Accton-AS5712-54X/td2-as5712-72x10G.config.bcm b/device/accton/x86_64-accton_as5712_54x-r0/Accton-AS5712-54X/td2-as5712-72x10G.config.bcm index 4844616d0382..1d6286ba3bd7 100644 --- a/device/accton/x86_64-accton_as5712_54x-r0/Accton-AS5712-54X/td2-as5712-72x10G.config.bcm +++ b/device/accton/x86_64-accton_as5712_54x-r0/Accton-AS5712-54X/td2-as5712-72x10G.config.bcm @@ -3,7 +3,7 @@ bcm_stat_flags=0 parity_enable=0 parity_correction=0 -bcm_num_cos=8 +bcm_num_cos=10 l2_mem_entries=32768 l3_mem_entries=16384 l3_alpm_enable=2 diff --git a/device/accton/x86_64-accton_as5712_54x-r0/plugins/eeprom.py b/device/accton/x86_64-accton_as5712_54x-r0/plugins/eeprom.py index 7681caafeef4..951384d5e37d 100644 --- a/device/accton/x86_64-accton_as5712_54x-r0/plugins/eeprom.py +++ b/device/accton/x86_64-accton_as5712_54x-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -11,14 +8,16 @@ 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") +except ImportError as 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/1-0057/eeprom" - #Two i2c buses might get flipped order, check them both. + # Two i2c buses might get flipped order, check them both. if not os.path.exists(self.eeprom_path): self.eeprom_path = "/sys/bus/i2c/devices/0-0057/eeprom" super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/accton/x86_64-accton_as5712_54x-r0/plugins/psuutil.py b/device/accton/x86_64-accton_as5712_54x-r0/plugins/psuutil.py index 841070637b3e..a07aebc96312 100755 --- a/device/accton/x86_64-accton_as5712_54x-r0/plugins/psuutil.py +++ b/device/accton/x86_64-accton_as5712_54x-r0/plugins/psuutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Accton # @@ -13,7 +11,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" diff --git a/device/accton/x86_64-accton_as5712_54x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as5712_54x-r0/plugins/sfputil.py index b1727f0a79b6..5002d842a15f 100755 --- a/device/accton/x86_64-accton_as5712_54x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as5712_54x-r0/plugins/sfputil.py @@ -12,7 +12,7 @@ raise ImportError("%s - required module not found" % str(e)) -#from xcvrd +# from xcvrd SFP_STATUS_INSERTED = '1' SFP_STATUS_REMOVED = '0' @@ -32,7 +32,7 @@ class SfpUtil(SfpUtilBase): BASE_CPLD3_PATH = "/sys/bus/i2c/devices/{0}-0062/" I2C_BUS_ORDER = -1 - #The sidebands of QSFP is different. + # The sidebands of QSFP is different. qsfp_sb_map = [0, 2, 4, 1, 3, 5] _port_to_is_present = {} @@ -40,61 +40,61 @@ class SfpUtil(SfpUtilBase): _port_to_eeprom_mapping = {} _port_to_i2c_mapping = { - 1: [1, 2], - 2: [2, 3], - 3: [3, 4], - 4: [4, 5], - 5: [5, 6], - 6: [6, 7], - 7: [7, 8], - 8: [8, 9], - 9: [9, 10], - 10: [10, 11], - 11: [11, 12], - 12: [12, 13], - 13: [13, 14], - 14: [14, 15], - 15: [15, 16], - 16: [16, 17], - 17: [17, 18], - 18: [18, 19], - 19: [19, 20], - 20: [20, 21], - 21: [21, 22], - 22: [22, 23], - 23: [23, 24], - 24: [24, 25], - 25: [25, 26], - 26: [26, 27], - 27: [27, 28], - 28: [28, 29], - 29: [29, 30], - 30: [30, 31], - 31: [31, 32], - 32: [32, 33], - 33: [33, 34], - 34: [34, 35], - 35: [35, 36], - 36: [36, 37], - 37: [37, 38], - 38: [38, 39], - 39: [39, 40], - 40: [40, 41], - 41: [41, 42], - 42: [42, 43], - 43: [43, 44], - 44: [44, 45], - 45: [45, 46], - 46: [46, 47], - 47: [47, 48], - 48: [48, 49], - 49: [49, 50],#QSFP49 - 50: [51, 52], - 51: [53, 54], - 52: [50, 51], - 53: [52, 53], - 54: [54, 55],#QSFP54 - } + 1: [1, 2], + 2: [2, 3], + 3: [3, 4], + 4: [4, 5], + 5: [5, 6], + 6: [6, 7], + 7: [7, 8], + 8: [8, 9], + 9: [9, 10], + 10: [10, 11], + 11: [11, 12], + 12: [12, 13], + 13: [13, 14], + 14: [14, 15], + 15: [15, 16], + 16: [16, 17], + 17: [17, 18], + 18: [18, 19], + 19: [19, 20], + 20: [20, 21], + 21: [21, 22], + 22: [22, 23], + 23: [23, 24], + 24: [24, 25], + 25: [25, 26], + 26: [26, 27], + 27: [27, 28], + 28: [28, 29], + 29: [29, 30], + 30: [30, 31], + 31: [31, 32], + 32: [32, 33], + 33: [33, 34], + 34: [34, 35], + 35: [35, 36], + 36: [36, 37], + 37: [37, 38], + 38: [38, 39], + 39: [39, 40], + 40: [40, 41], + 41: [41, 42], + 42: [42, 43], + 43: [43, 44], + 44: [44, 45], + 45: [45, 46], + 46: [46, 47], + 47: [47, 48], + 48: [48, 49], + 49: [49, 50], # QSFP49 + 50: [51, 52], + 51: [53, 54], + 52: [50, 51], + 53: [52, 53], + 54: [54, 55], # QSFP54 + } @property def port_start(self): @@ -111,16 +111,16 @@ def qsfp_port_start(self): @property def qsfp_port_end(self): return self.QSFP_PORT_END - + @property def qsfp_ports(self): - return range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1) + return list(range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): return self._port_to_eeprom_mapping - #Two i2c buses might get flipped order, check them both. + # Two i2c buses might get flipped order, check them both. def update_i2c_order(self): if self.I2C_BUS_ORDER < 0: eeprom_path = "/sys/bus/i2c/devices/1-0057/eeprom" @@ -129,7 +129,7 @@ def update_i2c_order(self): eeprom_path = "/sys/bus/i2c/devices/0-0057/eeprom" if os.path.exists(eeprom_path): self.I2C_BUS_ORDER = 1 - return self.I2C_BUS_ORDER + return self.I2C_BUS_ORDER def get_presence(self, port_num): # Check for invalid port_num @@ -144,15 +144,15 @@ def get_presence(self, port_num): present_path = present_path + "module_present_" + str(port_num) self.__port_to_is_present = present_path - content="0" + content = "0" try: val_file = open(self.__port_to_is_present) content = val_file.readline().rstrip() val_file.close() except IOError as e: - print "Error: unable to access file: %s" % str(e) + print("Error: unable to access file: %s" % str(e)) return False - + if content == "1": return True @@ -167,22 +167,22 @@ def qsfp_sb_remap(self, port_num): def get_low_power_mode_cpld(self, port_num): if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: return False - + order = self.update_i2c_order() lp_mode_path = self.BASE_CPLD3_PATH.format(order) - lp_mode_path = lp_mode_path + "module_lp_mode_" + lp_mode_path = lp_mode_path + "module_lp_mode_" q = self.qsfp_sb_remap(port_num) lp_mode_path = lp_mode_path + str(q) - - content="0" + + content = "0" try: val_file = open(lp_mode_path) content = val_file.readline().rstrip() val_file.close() except IOError as e: - print "Error: unable to access file: %s" % str(e) + print("Error: unable to access file: %s" % str(e)) return False - + if content == "1": return True @@ -191,7 +191,7 @@ def get_low_power_mode_cpld(self, port_num): def get_low_power_mode(self, port_num): if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: return False - + if not self.get_presence(port_num): return self.get_low_power_mode_cpld(port_num) @@ -202,15 +202,15 @@ def get_low_power_mode(self, port_num): eeprom.seek(93) lpmode = ord(eeprom.read(1)) - if not (lpmode & 0x1): # 'Power override' bit is 0 + if not (lpmode & 0x1): # 'Power override' bit is 0 return self.get_low_power_mode_cpld(port_num) else: if ((lpmode & 0x2) == 0x2): - return True # Low Power Mode if "Power set" bit is 1 + return True # Low Power Mode if "Power set" bit is 1 else: - return False # High Power Mode if "Power set" bit is 0 + return False # High Power Mode if "Power set" bit is 0 except IOError as err: - print "Error: unable to open file: %s" % str(err) + print("Error: unable to open file: %s" % str(err)) return False finally: if eeprom is not None: @@ -225,10 +225,10 @@ def set_low_power_mode(self, port_num, lpmode): eeprom = None if not self.get_presence(port_num): - return False # Port is not present, unable to set the eeprom + return False # Port is not present, unable to set the eeprom # Fill in write buffer - regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode + regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode buffer = create_string_buffer(1) buffer[0] = chr(regval) @@ -238,7 +238,7 @@ def set_low_power_mode(self, port_num, lpmode): eeprom.write(buffer[0]) return True except IOError as err: - print "Error: unable to open file: %s" % str(err) + print("Error: unable to open file: %s" % str(err)) return False finally: if eeprom is not None: @@ -248,19 +248,19 @@ def set_low_power_mode(self, port_num, lpmode): def reset(self, port_num): if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: return False - + order = self.update_i2c_order() lp_mode_path = self.BASE_CPLD3_PATH.format(order) - mod_rst_path = lp_mode_path + "module_reset_" + mod_rst_path = lp_mode_path + "module_reset_" q = self.qsfp_sb_remap(port_num) mod_rst_path = mod_rst_path + str(q) try: reg_file = open(mod_rst_path, 'r+', buffering=0) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False - #toggle reset + # toggle reset reg_file.seek(0) reg_file.write('0') time.sleep(1) @@ -271,31 +271,31 @@ def reset(self, port_num): @property def _get_presence_bitmap(self): - nodes = [] + nodes = [] order = self.update_i2c_order() - + present_path = self.BASE_CPLD2_PATH.format(order) nodes.append(present_path + "module_present_all") present_path = self.BASE_CPLD3_PATH.format(order) nodes.append(present_path + "module_present_all") - bitmap = "" - for node in nodes: + bitmap = "" + for node in nodes: try: reg_file = open(node) - + except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False bitmap += reg_file.readline().rstrip() + " " reg_file.close() rev = bitmap.split(" ") rev = "".join(rev[::-1]) - return int(rev,16) - + return int(rev, 16) + + data = {'valid': 0, 'last': 0, 'present': 0} - data = {'valid':0, 'last':0, 'present':0} def get_transceiver_change_event(self, timeout=2000): now = time.time() port_dict = {} @@ -303,8 +303,7 @@ def get_transceiver_change_event(self, timeout=2000): if timeout < 1000: timeout = 1000 - timeout = (timeout) / float(1000) # Convert to secs - + timeout = (timeout) / float(1000) # Convert to secs if now < (self.data['last'] + timeout) and self.data['valid']: return True, {} @@ -312,7 +311,7 @@ def get_transceiver_change_event(self, timeout=2000): reg_value = self._get_presence_bitmap changed_ports = self.data['present'] ^ reg_value if changed_ports: - for port in range (self.port_start, self.port_end+1): + for port in range(self.port_start, self.port_end+1): # Mask off the bit corresponding to our port fp_port = self._port_to_i2c_mapping[port][0] mask = (1 << (fp_port - 1)) @@ -323,7 +322,7 @@ def get_transceiver_change_event(self, timeout=2000): else: port_dict[port] = SFP_STATUS_INSERTED - # Update cache + # Update cache self.data['present'] = reg_value self.data['last'] = now self.data['valid'] = 1 @@ -333,17 +332,12 @@ def get_transceiver_change_event(self, timeout=2000): return True, {} return False, {} - def __init__(self): eeprom_path = self.BASE_OOM_PATH + "eeprom" for x in range(self.port_start, self.port_end+1): self.port_to_eeprom_mapping[x] = eeprom_path.format( self._port_to_i2c_mapping[x][1] - ) + ) SfpUtilBase.__init__(self) - - - - diff --git a/device/accton/x86_64-accton_as5712_54x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as5712_54x-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as5712_54x-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as5712_54x-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/sai.profile b/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/sai.profile index dc4f243953bf..3c78aab15dcb 100644 --- a/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/sai.profile +++ b/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-as5812t-72x10G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/td2-as5812t-72x10G.config.bcm b/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/td2-as5812t-72x10G.config.bcm index b55558521094..23ccc495bbd6 100644 --- a/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/td2-as5812t-72x10G.config.bcm +++ b/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/td2-as5812t-72x10G.config.bcm @@ -1,4 +1,4 @@ -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_flags=0 bcm_stat_interval=2000000 bcm_tunnel_term_compatible_mode=1 diff --git a/device/accton/x86_64-accton_as5812_54t-r0/plugins/eeprom.py b/device/accton/x86_64-accton_as5812_54t-r0/plugins/eeprom.py index 7681caafeef4..951384d5e37d 100644 --- a/device/accton/x86_64-accton_as5812_54t-r0/plugins/eeprom.py +++ b/device/accton/x86_64-accton_as5812_54t-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -11,14 +8,16 @@ 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") +except ImportError as 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/1-0057/eeprom" - #Two i2c buses might get flipped order, check them both. + # Two i2c buses might get flipped order, check them both. if not os.path.exists(self.eeprom_path): self.eeprom_path = "/sys/bus/i2c/devices/0-0057/eeprom" super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/accton/x86_64-accton_as5812_54t-r0/plugins/psuutil.py b/device/accton/x86_64-accton_as5812_54t-r0/plugins/psuutil.py index cfcd62e5828e..b7a0a2fd66e3 100755 --- a/device/accton/x86_64-accton_as5812_54t-r0/plugins/psuutil.py +++ b/device/accton/x86_64-accton_as5812_54t-r0/plugins/psuutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Accton # @@ -13,7 +11,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" diff --git a/device/accton/x86_64-accton_as5812_54t-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as5812_54t-r0/plugins/sfputil.py index 5647c84a35db..38beeaf6ca5e 100755 --- a/device/accton/x86_64-accton_as5812_54t-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as5812_54t-r0/plugins/sfputil.py @@ -5,13 +5,12 @@ try: import time import os - import pickle from ctypes import create_string_buffer from sonic_sfp.sfputilbase import SfpUtilBase except ImportError as e: raise ImportError("%s - required module not found" % str(e)) -#from xcvrd +# from xcvrd SFP_STATUS_INSERTED = '1' SFP_STATUS_REMOVED = '0' @@ -30,9 +29,9 @@ class SfpUtil(SfpUtilBase): BASE_CPLD_PATH = "/sys/bus/i2c/devices/{0}-0060/" I2C_BUS_ORDER = -1 - #The sidebands of QSFP is different. - #present is in-order. - #But lp_mode and reset are not. + # The sidebands of QSFP is different. + # present is in-order. + # But lp_mode and reset are not. qsfp_sb_map = [0, 2, 4, 1, 3, 5] _port_to_is_present = {} @@ -40,13 +39,13 @@ class SfpUtil(SfpUtilBase): _port_to_eeprom_mapping = {} _port_to_i2c_mapping = { - 49: [1,4],#QSFP_start - 50: [2,6], - 51: [3,3], - 52: [4,5], - 53: [5,7], - 54: [6,2], - } + 49: [1, 4], # QSFP_start + 50: [2, 6], + 51: [3, 3], + 52: [4, 5], + 53: [5, 7], + 54: [6, 2], + } @property def port_start(self): @@ -63,10 +62,10 @@ def qsfp_port_start(self): @property def qsfp_port_end(self): return self.QSFP_PORT_END - + @property def qsfp_ports(self): - return range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1) + return list(range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -78,22 +77,19 @@ def __init__(self): for x in range(self.port_start, self.port_end+1): self.port_to_eeprom_mapping[x] = eeprom_path.format( self._port_to_i2c_mapping[x][1] - ) + ) SfpUtilBase.__init__(self) - #Two i2c buses might get flipped order, check them both. + # Two i2c buses might get flipped order, check them both. def update_i2c_order(self): - if os.path.exists("/tmp/accton_util.p"): - self.I2C_BUS_ORDER = pickle.load(open("/tmp/accton_util.p", "rb")) - else: - if self.I2C_BUS_ORDER < 0: - eeprom_path = "/sys/bus/i2c/devices/1-0057/eeprom" - if os.path.exists(eeprom_path): - self.I2C_BUS_ORDER = 0 - eeprom_path = "/sys/bus/i2c/devices/0-0057/eeprom" - if os.path.exists(eeprom_path): - self.I2C_BUS_ORDER = 1 - return self.I2C_BUS_ORDER + if self.I2C_BUS_ORDER < 0: + eeprom_path = "/sys/bus/i2c/devices/1-0057/eeprom" + if os.path.exists(eeprom_path): + self.I2C_BUS_ORDER = 0 + eeprom_path = "/sys/bus/i2c/devices/0-0057/eeprom" + if os.path.exists(eeprom_path): + self.I2C_BUS_ORDER = 1 + return self.I2C_BUS_ORDER def get_presence(self, port_num): # Check for invalid port_num @@ -102,18 +98,18 @@ def get_presence(self, port_num): order = self.update_i2c_order() present_path = self.BASE_CPLD_PATH.format(order) - present_path = present_path + "module_present_" + str(port_num) + present_path = present_path + "module_present_" + str(port_num) self.__port_to_is_present = present_path - content="0" + content = "0" try: val_file = open(self.__port_to_is_present) content = val_file.readline().rstrip() val_file.close() except IOError as e: - print "Error: unable to access file: %s" % str(e) + print("Error: unable to access file: %s" % str(e)) return False - + if content == "1": return True @@ -122,21 +118,21 @@ def get_presence(self, port_num): def get_low_power_mode_cpld(self, port_num): if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: return False - + order = self.update_i2c_order() lp_mode_path = self.BASE_CPLD_PATH.format(order) - lp_mode_path = lp_mode_path + "module_lp_mode_" + lp_mode_path = lp_mode_path + "module_lp_mode_" lp_mode_path = lp_mode_path + str(port_num) - - content="0" + + content = "0" try: val_file = open(lp_mode_path) content = val_file.readline().rstrip() val_file.close() except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False - + if content == "1": return True @@ -145,7 +141,7 @@ def get_low_power_mode_cpld(self, port_num): def get_low_power_mode(self, port_num): if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: return False - + if not self.get_presence(port_num): return self.get_low_power_mode_cpld(port_num) @@ -155,15 +151,15 @@ def get_low_power_mode(self, port_num): eeprom.seek(93) lpmode = ord(eeprom.read(1)) - if not (lpmode & 0x1): # 'Power override' bit is 0 + if not (lpmode & 0x1): # 'Power override' bit is 0 return self.get_low_power_mode_cpld(port_num) else: if ((lpmode & 0x2) == 0x2): - return True # Low Power Mode if "Power set" bit is 1 + return True # Low Power Mode if "Power set" bit is 1 else: - return False # High Power Mode if "Power set" bit is 0 + return False # High Power Mode if "Power set" bit is 0 except IOError as err: - print "Error: unable to open file: %s" % str(err) + print("Error: unable to open file: %s" % str(err)) return False finally: if eeprom is not None: @@ -178,10 +174,10 @@ def set_low_power_mode(self, port_num, lpmode): eeprom = None if not self.get_presence(port_num): - return False # Port is not present, unable to set the eeprom + return False # Port is not present, unable to set the eeprom # Fill in write buffer - regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode + regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode buffer = create_string_buffer(1) buffer[0] = chr(regval) @@ -191,7 +187,7 @@ def set_low_power_mode(self, port_num, lpmode): eeprom.write(buffer[0]) return True except IOError as err: - print "Error: unable to open file: %s" % str(err) + print("Error: unable to open file: %s" % str(err)) return False finally: if eeprom is not None: @@ -201,20 +197,20 @@ def set_low_power_mode(self, port_num, lpmode): def reset(self, port_num): if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: return False - + order = self.update_i2c_order() lp_mode_path = self.BASE_CPLD_PATH.format(order) - mod_rst_path = lp_mode_path + "module_reset_" + mod_rst_path = lp_mode_path + "module_reset_" mod_rst_path = mod_rst_path + str(port_num) print(mod_rst_path) - + try: reg_file = open(mod_rst_path, 'r+', buffering=0) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False - #toggle reset + # toggle reset reg_file.seek(0) reg_file.write('1') time.sleep(1) @@ -225,39 +221,39 @@ def reset(self, port_num): @property def _get_presence_bitmap(self): - nodes = [] + nodes = [] order = self.update_i2c_order() - + present_path = self.BASE_CPLD_PATH.format(order) nodes.append(present_path + "module_present_all") - bitmap = "" - for node in nodes: + bitmap = "" + for node in nodes: try: reg_file = open(node) - + except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False bitmap += reg_file.readline().rstrip() + " " reg_file.close() rev = bitmap.split(" ") rev = "".join(rev[::-1]) - return int(rev,16) - + return int(rev, 16) + + data = {'present': 0} - data = {'present':0} def get_transceiver_change_event(self, timeout=2000): port_dict = {} port = 0 if timeout == 0: - cd_ms = sys.maxint + cd_ms = sys.maxsize else: cd_ms = timeout - #poll per second + # poll per second while cd_ms > 0: reg_value = self._get_presence_bitmap changed_ports = self.data['present'] ^ reg_value @@ -267,7 +263,7 @@ def get_transceiver_change_event(self, timeout=2000): cd_ms = cd_ms - 1000 if changed_ports: - for port in range (self.port_start, self.port_end+1): + for port in range(self.port_start, self.port_end+1): # Mask off the bit corresponding to our port fp_port = self._port_to_i2c_mapping[port][0] mask = (1 << (fp_port - 1)) @@ -278,11 +274,10 @@ def get_transceiver_change_event(self, timeout=2000): else: port_dict[port] = SFP_STATUS_INSERTED - # Update cache + # Update cache self.data['present'] = reg_value return True, port_dict else: return True, {} return False, {} - diff --git a/device/accton/x86_64-accton_as5812_54t-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as5812_54t-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as5812_54t-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as5812_54t-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/sai.profile b/device/accton/x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/sai.profile index 063814c1fcb3..0ec3aa1896cf 100755 --- a/device/accton/x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/sai.profile +++ b/device/accton/x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-as5812-72x10G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/td2-as5812-72x10G.config.bcm b/device/accton/x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/td2-as5812-72x10G.config.bcm index 4844616d0382..1d6286ba3bd7 100644 --- a/device/accton/x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/td2-as5812-72x10G.config.bcm +++ b/device/accton/x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/td2-as5812-72x10G.config.bcm @@ -3,7 +3,7 @@ bcm_stat_flags=0 parity_enable=0 parity_correction=0 -bcm_num_cos=8 +bcm_num_cos=10 l2_mem_entries=32768 l3_mem_entries=16384 l3_alpm_enable=2 diff --git a/device/accton/x86_64-accton_as5812_54x-r0/plugins/eeprom.py b/device/accton/x86_64-accton_as5812_54x-r0/plugins/eeprom.py index 7681caafeef4..951384d5e37d 100644 --- a/device/accton/x86_64-accton_as5812_54x-r0/plugins/eeprom.py +++ b/device/accton/x86_64-accton_as5812_54x-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -11,14 +8,16 @@ 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") +except ImportError as 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/1-0057/eeprom" - #Two i2c buses might get flipped order, check them both. + # Two i2c buses might get flipped order, check them both. if not os.path.exists(self.eeprom_path): self.eeprom_path = "/sys/bus/i2c/devices/0-0057/eeprom" super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/accton/x86_64-accton_as5812_54x-r0/plugins/psuutil.py b/device/accton/x86_64-accton_as5812_54x-r0/plugins/psuutil.py index 841070637b3e..a07aebc96312 100755 --- a/device/accton/x86_64-accton_as5812_54x-r0/plugins/psuutil.py +++ b/device/accton/x86_64-accton_as5812_54x-r0/plugins/psuutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Accton # @@ -13,7 +11,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" diff --git a/device/accton/x86_64-accton_as5812_54x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as5812_54x-r0/plugins/sfputil.py index 62b9db604363..be301aea493b 100755 --- a/device/accton/x86_64-accton_as5812_54x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as5812_54x-r0/plugins/sfputil.py @@ -5,13 +5,12 @@ try: import time import os - import pickle from ctypes import create_string_buffer from sonic_sfp.sfputilbase import SfpUtilBase except ImportError as e: raise ImportError("%s - required module not found" % str(e)) -#from xcvrd +# from xcvrd SFP_STATUS_INSERTED = '1' SFP_STATUS_REMOVED = '0' @@ -31,9 +30,9 @@ class SfpUtil(SfpUtilBase): BASE_CPLD3_PATH = "/sys/bus/i2c/devices/{0}-0062/" I2C_BUS_ORDER = -1 - #The sidebands of QSFP is different. - #present is in-order. - #But lp_mode and reset are not. + # The sidebands of QSFP is different. + # present is in-order. + # But lp_mode and reset are not. qsfp_sb_map = [0, 2, 4, 1, 3, 5] _port_to_is_present = {} @@ -41,61 +40,61 @@ class SfpUtil(SfpUtilBase): _port_to_eeprom_mapping = {} _port_to_i2c_mapping = { - 1: [1, 2], - 2: [2, 3], - 3: [3, 4], - 4: [4, 5], - 5: [5, 6], - 6: [6, 7], - 7: [7, 8], - 8: [8, 9], - 9: [9, 10], - 10: [10,11], - 11: [11,12], - 12: [12,13], - 13: [13,14], - 14: [14,15], - 15: [15,16], - 16: [16,17], - 17: [17,18], - 18: [18,19], - 19: [19,20], - 20: [20,21], - 21: [21,22], - 22: [22,23], - 23: [23,24], - 24: [24,25], - 25: [25,26], - 26: [26,27], - 27: [27,28], - 28: [28,29], - 29: [29,30], - 30: [30,31], - 31: [31,32], - 32: [32,33], - 33: [33,34], - 34: [34,35], - 35: [35,36], - 36: [36,37], - 37: [37,38], - 38: [38,39], - 39: [39,40], - 40: [40,41], - 41: [41,42], - 42: [42,43], - 43: [43,44], - 44: [44,45], - 45: [45,46], - 46: [46,47], - 47: [47,48], - 48: [48,49], - 49: [49,50],#QSFP_start - 50: [51,52], - 51: [53,54], - 52: [50,51], - 53: [52,53], - 54: [54,55], - } + 1: [1, 2], + 2: [2, 3], + 3: [3, 4], + 4: [4, 5], + 5: [5, 6], + 6: [6, 7], + 7: [7, 8], + 8: [8, 9], + 9: [9, 10], + 10: [10, 11], + 11: [11, 12], + 12: [12, 13], + 13: [13, 14], + 14: [14, 15], + 15: [15, 16], + 16: [16, 17], + 17: [17, 18], + 18: [18, 19], + 19: [19, 20], + 20: [20, 21], + 21: [21, 22], + 22: [22, 23], + 23: [23, 24], + 24: [24, 25], + 25: [25, 26], + 26: [26, 27], + 27: [27, 28], + 28: [28, 29], + 29: [29, 30], + 30: [30, 31], + 31: [31, 32], + 32: [32, 33], + 33: [33, 34], + 34: [34, 35], + 35: [35, 36], + 36: [36, 37], + 37: [37, 38], + 38: [38, 39], + 39: [39, 40], + 40: [40, 41], + 41: [41, 42], + 42: [42, 43], + 43: [43, 44], + 44: [44, 45], + 45: [45, 46], + 46: [46, 47], + 47: [47, 48], + 48: [48, 49], + 49: [49, 50], # QSFP_start + 50: [51, 52], + 51: [53, 54], + 52: [50, 51], + 53: [52, 53], + 54: [54, 55], + } @property def port_start(self): @@ -112,10 +111,10 @@ def qsfp_port_start(self): @property def qsfp_port_end(self): return self.QSFP_PORT_END - + @property def qsfp_ports(self): - return range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1) + return list(range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -127,22 +126,19 @@ def __init__(self): for x in range(self.port_start, self.port_end+1): self.port_to_eeprom_mapping[x] = eeprom_path.format( self._port_to_i2c_mapping[x][1] - ) + ) SfpUtilBase.__init__(self) - #Two i2c buses might get flipped order, check them both. + # Two i2c buses might get flipped order, check them both. def update_i2c_order(self): - if os.path.exists("/tmp/accton_util.p"): - self.I2C_BUS_ORDER = pickle.load(open("/tmp/accton_util.p", "rb")) - else: - if self.I2C_BUS_ORDER < 0: - eeprom_path = "/sys/bus/i2c/devices/1-0057/eeprom" - if os.path.exists(eeprom_path): - self.I2C_BUS_ORDER = 0 - eeprom_path = "/sys/bus/i2c/devices/0-0057/eeprom" - if os.path.exists(eeprom_path): - self.I2C_BUS_ORDER = 1 - return self.I2C_BUS_ORDER + if self.I2C_BUS_ORDER < 0: + eeprom_path = "/sys/bus/i2c/devices/1-0057/eeprom" + if os.path.exists(eeprom_path): + self.I2C_BUS_ORDER = 0 + eeprom_path = "/sys/bus/i2c/devices/0-0057/eeprom" + if os.path.exists(eeprom_path): + self.I2C_BUS_ORDER = 1 + return self.I2C_BUS_ORDER def get_presence(self, port_num): # Check for invalid port_num @@ -151,22 +147,22 @@ def get_presence(self, port_num): order = self.update_i2c_order() if port_num <= 24: - present_path = self.BASE_CPLD2_PATH.format(order) + present_path = self.BASE_CPLD2_PATH.format(order) else: present_path = self.BASE_CPLD3_PATH.format(order) - - present_path = present_path + "module_present_" + str(port_num) + + present_path = present_path + "module_present_" + str(port_num) self.__port_to_is_present = present_path - content="0" + content = "0" try: val_file = open(self.__port_to_is_present) content = val_file.readline().rstrip() val_file.close() except IOError as e: - print "Error: unable to access file: %s" % str(e) + print("Error: unable to access file: %s" % str(e)) return False - + if content == "1": return True @@ -181,22 +177,22 @@ def qsfp_sb_remap(self, port_num): def get_low_power_mode_cpld(self, port_num): if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: return False - + order = self.update_i2c_order() lp_mode_path = self.BASE_CPLD3_PATH.format(order) - lp_mode_path = lp_mode_path + "module_lp_mode_" + lp_mode_path = lp_mode_path + "module_lp_mode_" q = self.qsfp_sb_remap(port_num) lp_mode_path = lp_mode_path + str(q) - + content = "0" try: val_file = open(lp_mode_path) content = val_file.readline().rstrip() val_file.close() except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False - + if content == "1": return True @@ -205,7 +201,7 @@ def get_low_power_mode_cpld(self, port_num): def get_low_power_mode(self, port_num): if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: return False - + if not self.get_presence(port_num): return self.get_low_power_mode_cpld(port_num) @@ -216,15 +212,15 @@ def get_low_power_mode(self, port_num): eeprom.seek(93) lpmode = ord(eeprom.read(1)) - if not (lpmode & 0x1): # 'Power override' bit is 0 + if not (lpmode & 0x1): # 'Power override' bit is 0 return self.get_low_power_mode_cpld(port_num) else: if ((lpmode & 0x2) == 0x2): - return True # Low Power Mode if "Power set" bit is 1 + return True # Low Power Mode if "Power set" bit is 1 else: - return False # High Power Mode if "Power set" bit is 0 + return False # High Power Mode if "Power set" bit is 0 except IOError as err: - print "Error: unable to open file: %s" % str(err) + print("Error: unable to open file: %s" % str(err)) return False finally: if eeprom is not None: @@ -239,10 +235,10 @@ def set_low_power_mode(self, port_num, lpmode): eeprom = None if not self.get_presence(port_num): - return False # Port is not present, unable to set the eeprom + return False # Port is not present, unable to set the eeprom # Fill in write buffer - regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode + regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode buffer = create_string_buffer(1) buffer[0] = chr(regval) @@ -252,7 +248,7 @@ def set_low_power_mode(self, port_num, lpmode): eeprom.write(buffer[0]) return True except IOError as err: - print "Error: unable to open file: %s" % str(err) + print("Error: unable to open file: %s" % str(err)) return False finally: if eeprom is not None: @@ -262,20 +258,20 @@ def set_low_power_mode(self, port_num, lpmode): def reset(self, port_num): if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: return False - + order = self.update_i2c_order() lp_mode_path = self.BASE_CPLD3_PATH.format(order) - mod_rst_path = lp_mode_path + "module_reset_" + mod_rst_path = lp_mode_path + "module_reset_" q = self.qsfp_sb_remap(port_num) mod_rst_path = mod_rst_path + str(q) - + try: reg_file = open(mod_rst_path, 'r+', buffering=0) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False - #toggle reset + # toggle reset reg_file.seek(0) reg_file.write('0') time.sleep(1) @@ -286,31 +282,31 @@ def reset(self, port_num): @property def _get_presence_bitmap(self): - nodes = [] + nodes = [] order = self.update_i2c_order() - + present_path = self.BASE_CPLD2_PATH.format(order) nodes.append(present_path + "module_present_all") present_path = self.BASE_CPLD3_PATH.format(order) nodes.append(present_path + "module_present_all") - bitmap = "" - for node in nodes: + bitmap = "" + for node in nodes: try: reg_file = open(node) - + except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False bitmap += reg_file.readline().rstrip() + " " reg_file.close() rev = bitmap.split(" ") rev = "".join(rev[::-1]) - return int(rev,16) - + return int(rev, 16) + + data = {'valid': 0, 'last': 0, 'present': 0} - data = {'valid':0, 'last':0, 'present':0} def get_transceiver_change_event(self, timeout=2000): now = time.time() port_dict = {} @@ -318,8 +314,7 @@ def get_transceiver_change_event(self, timeout=2000): if timeout < 1000: timeout = 1000 - timeout = (timeout) / float(1000) # Convert to secs - + timeout = (timeout) / float(1000) # Convert to secs if now < (self.data['last'] + timeout) and self.data['valid']: return True, {} @@ -327,7 +322,7 @@ def get_transceiver_change_event(self, timeout=2000): reg_value = self._get_presence_bitmap changed_ports = self.data['present'] ^ reg_value if changed_ports: - for port in range (self.port_start, self.port_end+1): + for port in range(self.port_start, self.port_end+1): # Mask off the bit corresponding to our port fp_port = self._port_to_i2c_mapping[port][0] mask = (1 << (fp_port - 1)) @@ -338,7 +333,7 @@ def get_transceiver_change_event(self, timeout=2000): else: port_dict[port] = SFP_STATUS_INSERTED - # Update cache + # Update cache self.data['present'] = reg_value self.data['last'] = now self.data['valid'] = 1 @@ -347,4 +342,3 @@ def get_transceiver_change_event(self, timeout=2000): else: return True, {} return False, {} - diff --git a/device/accton/x86_64-accton_as5812_54x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as5812_54x-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as5812_54x-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as5812_54x-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/mv2-as5835t-48x10G+6x100G.config.bcm b/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/mv2-as5835t-48x10G+6x100G.config.bcm new file mode 100755 index 000000000000..63738e788d54 --- /dev/null +++ b/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/mv2-as5835t-48x10G+6x100G.config.bcm @@ -0,0 +1,534 @@ +#polarity/lanemap is using TH2 style. +core_clock_frequency=1525 +dpp_clock_ratio=2:3 + +ptp_ts_pll_fref=50000000 +ptp_bs_fref_0=50000000 +ptp_bs_fref_1=50000000 + +oversubscribe_mode=1 + +pbmp_xport_xe=0x1FFFFFFFFFFFFFFFE + +parity_enable=0 +mem_cache_enable=0 + +l2_mem_entries=32768 +l3_mem_entries=16384 +fpem_mem_entries=16384 +l2xmsg_mode=1 + +# Platform specfic +bcm_num_cos=10 +bcm_stat_interval=2000000 +cdma_timeout_usec=3000000 +ifp_inports_support_enable=1 +ipv6_lpm_128b_enable=0x1 +l3_alpm_enable=2 +l3_max_ecmp_mode=1 +max_vp_lags=0 +miim_intr_enable=0 +module_64ports=1 +port_flex_enable=1 +schan_intr_enable=0 +stable_size=0x5500000 ;Specify the stable cache size in bytes used for Warm boot operations +tdma_timeout_usec=3000000 +skip_L2_USER_ENTRY=0 +bcm_tunnel_term_compatible_mode=1 +l3_alpm_ipv6_128b_bkt_rsvd=1 + +#FC0 +dport_map_port_1=2 +dport_map_port_2=1 +dport_map_port_3=4 +dport_map_port_4=3 +portmap_1=1:10 +portmap_2=2:10 +portmap_3=3:10 +portmap_4=4:10 +#port_phy_addr_1=0x00 +#port_phy_addr_2=0x01 +#port_phy_addr_3=0x02 +#port_phy_addr_4=0x03 +phy_chain_rx_lane_map_physical{1.0}=0x0123 +phy_chain_rx_lane_map_physical{2.0}=0x0123 +phy_chain_rx_lane_map_physical{3.0}=0x0123 +phy_chain_rx_lane_map_physical{4.0}=0x0123 +phy_chain_tx_lane_map_physical{1.0}=0x0123 +phy_chain_tx_lane_map_physical{2.0}=0x0123 +phy_chain_tx_lane_map_physical{3.0}=0x0123 +phy_chain_tx_lane_map_physical{4.0}=0x0123 +phy_chain_rx_polarity_flip_physical{1.0}=0x1 +phy_chain_rx_polarity_flip_physical{2.0}=0x1 +phy_chain_rx_polarity_flip_physical{3.0}=0x1 +phy_chain_rx_polarity_flip_physical{4.0}=0x1 +phy_chain_tx_polarity_flip_physical{1.0}=0x0 +phy_chain_tx_polarity_flip_physical{2.0}=0x0 +phy_chain_tx_polarity_flip_physical{3.0}=0x0 +phy_chain_tx_polarity_flip_physical{4.0}=0x0 + +#FC1 +dport_map_port_5=6 +dport_map_port_6=5 +dport_map_port_7=8 +dport_map_port_8=7 +portmap_5=5:10 +portmap_6=6:10 +portmap_7=7:10 +portmap_8=8:10 +#port_phy_addr_5=0x04 +#port_phy_addr_6=0x05 +#port_phy_addr_7=0x06 +#port_phy_addr_8=0x07 +phy_chain_rx_lane_map_physical{5.0}=0x0123 +phy_chain_rx_lane_map_physical{6.0}=0x0123 +phy_chain_rx_lane_map_physical{7.0}=0x0123 +phy_chain_rx_lane_map_physical{8.0}=0x0123 +phy_chain_tx_lane_map_physical{5.0}=0x0123 +phy_chain_tx_lane_map_physical{6.0}=0x0123 +phy_chain_tx_lane_map_physical{7.0}=0x0123 +phy_chain_tx_lane_map_physical{8.0}=0x0123 +phy_chain_rx_polarity_flip_physical{5.0}=0x0 +phy_chain_rx_polarity_flip_physical{6.0}=0x0 +phy_chain_rx_polarity_flip_physical{7.0}=0x0 +phy_chain_rx_polarity_flip_physical{8.0}=0x0 +phy_chain_tx_polarity_flip_physical{5.0}=0x0 +phy_chain_tx_polarity_flip_physical{6.0}=0x0 +phy_chain_tx_polarity_flip_physical{7.0}=0x0 +phy_chain_tx_polarity_flip_physical{8.0}=0x0 + +#FC2 +dport_map_port_9=10 +dport_map_port_10=9 +dport_map_port_11=12 +dport_map_port_12=11 +portmap_9=9:10 +portmap_10=10:10 +portmap_11=11:10 +portmap_12=12:10 +#port_phy_addr_9=0x20 +#port_phy_addr_10=0x21 +#port_phy_addr_11=0x22 +#port_phy_addr_12=0x23 +phy_chain_rx_lane_map_physical{9.0}=0x0123 +phy_chain_rx_lane_map_physical{10.0}=0x0123 +phy_chain_rx_lane_map_physical{11.0}=0x0123 +phy_chain_rx_lane_map_physical{12.0}=0x0123 +phy_chain_tx_lane_map_physical{9.0}=0x0123 +phy_chain_tx_lane_map_physical{10.0}=0x0123 +phy_chain_tx_lane_map_physical{11.0}=0x0123 +phy_chain_tx_lane_map_physical{12.0}=0x0123 +phy_chain_rx_polarity_flip_physical{9.0}=0x0 +phy_chain_rx_polarity_flip_physical{10.0}=0x0 +phy_chain_rx_polarity_flip_physical{11.0}=0x0 +phy_chain_rx_polarity_flip_physical{12.0}=0x0 +phy_chain_tx_polarity_flip_physical{9.0}=0x0 +phy_chain_tx_polarity_flip_physical{10.0}=0x0 +phy_chain_tx_polarity_flip_physical{11.0}=0x0 +phy_chain_tx_polarity_flip_physical{12.0}=0x0 + +#FC3 +dport_map_port_13=14 +dport_map_port_14=13 +dport_map_port_15=16 +dport_map_port_16=15 +portmap_13=13:10 +portmap_14=14:10 +portmap_15=15:10 +portmap_16=16:10 +#port_phy_addr_13=0x24 +#port_phy_addr_14=0x25 +#port_phy_addr_15=0x26 +#port_phy_addr_16=0x27 +phy_chain_rx_lane_map_physical{13.0}=0x0123 +phy_chain_rx_lane_map_physical{14.0}=0x0123 +phy_chain_rx_lane_map_physical{15.0}=0x0123 +phy_chain_rx_lane_map_physical{16.0}=0x0123 +phy_chain_tx_lane_map_physical{13.0}=0x0123 +phy_chain_tx_lane_map_physical{14.0}=0x0123 +phy_chain_tx_lane_map_physical{15.0}=0x0123 +phy_chain_tx_lane_map_physical{16.0}=0x0123 +phy_chain_rx_polarity_flip_physical{13.0}=0x0 +phy_chain_rx_polarity_flip_physical{14.0}=0x0 +phy_chain_rx_polarity_flip_physical{15.0}=0x0 +phy_chain_rx_polarity_flip_physical{16.0}=0x0 +phy_chain_tx_polarity_flip_physical{13.0}=0x0 +phy_chain_tx_polarity_flip_physical{14.0}=0x0 +phy_chain_tx_polarity_flip_physical{15.0}=0x0 +phy_chain_tx_polarity_flip_physical{16.0}=0x0 + +#FC4 +dport_map_port_17=18 +dport_map_port_18=17 +dport_map_port_19=20 +dport_map_port_20=19 +portmap_17=17:10 +portmap_18=18:10 +portmap_19=19:10 +portmap_20=20:10 +#port_phy_addr_17=0x40 +#port_phy_addr_18=0x41 +#port_phy_addr_19=0x42 +#port_phy_addr_20=0x43 +phy_chain_rx_lane_map_physical{17.0}=0x0123 +phy_chain_rx_lane_map_physical{18.0}=0x0123 +phy_chain_rx_lane_map_physical{19.0}=0x0123 +phy_chain_rx_lane_map_physical{20.0}=0x0123 +phy_chain_tx_lane_map_physical{17.0}=0x0123 +phy_chain_tx_lane_map_physical{18.0}=0x0123 +phy_chain_tx_lane_map_physical{19.0}=0x0123 +phy_chain_tx_lane_map_physical{20.0}=0x0123 +phy_chain_rx_polarity_flip_physical{17.0}=0x1 +phy_chain_rx_polarity_flip_physical{18.0}=0x1 +phy_chain_rx_polarity_flip_physical{19.0}=0x1 +phy_chain_rx_polarity_flip_physical{20.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 + +#FC5 +dport_map_port_21=22 +dport_map_port_22=21 +dport_map_port_23=24 +dport_map_port_24=23 +portmap_21=21:10 +portmap_22=22:10 +portmap_23=23:10 +portmap_24=24:10 +#port_phy_addr_21=0x44 +#port_phy_addr_22=0x45 +#port_phy_addr_23=0x46 +#port_phy_addr_24=0x47 +phy_chain_rx_lane_map_physical{21.0}=0x0123 +phy_chain_rx_lane_map_physical{22.0}=0x0123 +phy_chain_rx_lane_map_physical{23.0}=0x0123 +phy_chain_rx_lane_map_physical{24.0}=0x0123 +phy_chain_tx_lane_map_physical{21.0}=0x0123 +phy_chain_tx_lane_map_physical{22.0}=0x0123 +phy_chain_tx_lane_map_physical{23.0}=0x0123 +phy_chain_tx_lane_map_physical{24.0}=0x0123 +phy_chain_rx_polarity_flip_physical{21.0}=0x0 +phy_chain_rx_polarity_flip_physical{22.0}=0x0 +phy_chain_rx_polarity_flip_physical{23.0}=0x0 +phy_chain_rx_polarity_flip_physical{24.0}=0x0 +phy_chain_tx_polarity_flip_physical{21.0}=0x0 +phy_chain_tx_polarity_flip_physical{22.0}=0x0 +phy_chain_tx_polarity_flip_physical{23.0}=0x0 +phy_chain_tx_polarity_flip_physical{24.0}=0x0 + +#FC6 + +#FC7 +dport_map_port_25=50 +portmap_25=29:100:4 +phy_chain_rx_lane_map_physical{29.0}=0x1302 +phy_chain_rx_lane_map_physical{30.0}=0x1302 +phy_chain_rx_lane_map_physical{31.0}=0x1302 +phy_chain_rx_lane_map_physical{32.0}=0x1302 +phy_chain_tx_lane_map_physical{29.0}=0x2031 +phy_chain_tx_lane_map_physical{30.0}=0x2031 +phy_chain_tx_lane_map_physical{31.0}=0x2031 +phy_chain_tx_lane_map_physical{32.0}=0x2031 +phy_chain_rx_polarity_flip_physical{29.0}=0x0 +phy_chain_rx_polarity_flip_physical{30.0}=0x0 +phy_chain_rx_polarity_flip_physical{31.0}=0x0 +phy_chain_rx_polarity_flip_physical{32.0}=0x1 +phy_chain_tx_polarity_flip_physical{29.0}=0x1 +phy_chain_tx_polarity_flip_physical{30.0}=0x1 +phy_chain_tx_polarity_flip_physical{31.0}=0x1 +phy_chain_tx_polarity_flip_physical{32.0}=0x1 + +#FC8 +dport_map_port_26=51 +portmap_26=33:100:4 +phy_chain_rx_lane_map_physical{33.0}=0x0123 +phy_chain_rx_lane_map_physical{34.0}=0x0123 +phy_chain_rx_lane_map_physical{35.0}=0x0123 +phy_chain_rx_lane_map_physical{36.0}=0x0123 +phy_chain_tx_lane_map_physical{33.0}=0x0123 +phy_chain_tx_lane_map_physical{34.0}=0x0123 +phy_chain_tx_lane_map_physical{35.0}=0x0123 +phy_chain_tx_lane_map_physical{36.0}=0x0123 +phy_chain_rx_polarity_flip_physical{33.0}=0x0 +phy_chain_rx_polarity_flip_physical{34.0}=0x1 +phy_chain_rx_polarity_flip_physical{35.0}=0x0 +phy_chain_rx_polarity_flip_physical{36.0}=0x1 +phy_chain_tx_polarity_flip_physical{33.0}=0x0 +phy_chain_tx_polarity_flip_physical{34.0}=0x0 +phy_chain_tx_polarity_flip_physical{35.0}=0x0 +phy_chain_tx_polarity_flip_physical{36.0}=0x0 + +#FC9 +dport_map_port_27=49 +dport_map_port_28=52 +dport_map_port_29=53 +dport_map_port_30=54 +portmap_27=37:100:4 +phy_chain_rx_lane_map_physical{37.0}=0x1023 +phy_chain_rx_lane_map_physical{38.0}=0x1023 +phy_chain_rx_lane_map_physical{39.0}=0x1023 +phy_chain_rx_lane_map_physical{40.0}=0x1023 +phy_chain_tx_lane_map_physical{37.0}=0x3210 +phy_chain_tx_lane_map_physical{38.0}=0x3210 +phy_chain_tx_lane_map_physical{39.0}=0x3210 +phy_chain_tx_lane_map_physical{40.0}=0x3210 +phy_chain_rx_polarity_flip_physical{37.0}=0x0 +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_tx_polarity_flip_physical{37.0}=0x0 +phy_chain_tx_polarity_flip_physical{38.0}=0x1 +phy_chain_tx_polarity_flip_physical{39.0}=0x0 +phy_chain_tx_polarity_flip_physical{40.0}=0x0 + +#FC10 +dport_map_port_33=57 +portmap_33=41:100:4 +phy_chain_rx_lane_map_physical{41.0}=0x3210 +phy_chain_rx_lane_map_physical{42.0}=0x3210 +phy_chain_rx_lane_map_physical{43.0}=0x3210 +phy_chain_rx_lane_map_physical{44.0}=0x3210 +phy_chain_tx_lane_map_physical{41.0}=0x3210 +phy_chain_tx_lane_map_physical{42.0}=0x3210 +phy_chain_tx_lane_map_physical{43.0}=0x3210 +phy_chain_tx_lane_map_physical{44.0}=0x3210 +phy_chain_rx_polarity_flip_physical{41.0}=0x0 +phy_chain_rx_polarity_flip_physical{42.0}=0x1 +phy_chain_rx_polarity_flip_physical{43.0}=0x0 +phy_chain_rx_polarity_flip_physical{44.0}=0x1 +phy_chain_tx_polarity_flip_physical{41.0}=0x1 +phy_chain_tx_polarity_flip_physical{42.0}=0x0 +phy_chain_tx_polarity_flip_physical{43.0}=0x0 +phy_chain_tx_polarity_flip_physical{44.0}=0x0 + +#FC11 +dport_map_port_34=56 +portmap_34=45:100:4 +phy_chain_rx_lane_map_physical{45.0}=0x3210 +phy_chain_rx_lane_map_physical{46.0}=0x3210 +phy_chain_rx_lane_map_physical{47.0}=0x3210 +phy_chain_rx_lane_map_physical{48.0}=0x3210 +phy_chain_tx_lane_map_physical{45.0}=0x3210 +phy_chain_tx_lane_map_physical{46.0}=0x3210 +phy_chain_tx_lane_map_physical{47.0}=0x3210 +phy_chain_tx_lane_map_physical{48.0}=0x3210 +phy_chain_rx_polarity_flip_physical{45.0}=0x0 +phy_chain_rx_polarity_flip_physical{46.0}=0x0 +phy_chain_rx_polarity_flip_physical{47.0}=0x0 +phy_chain_rx_polarity_flip_physical{48.0}=0x0 +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}=0x0 + +#FC12 +dport_map_port_35=55 +dport_map_port_36=58 +dport_map_port_37=59 +dport_map_port_38=60 +portmap_35=49:100:4 +phy_chain_rx_lane_map_physical{49.0}=0x3210 +phy_chain_rx_lane_map_physical{50.0}=0x3210 +phy_chain_rx_lane_map_physical{51.0}=0x3210 +phy_chain_rx_lane_map_physical{52.0}=0x3210 +phy_chain_tx_lane_map_physical{49.0}=0x3210 +phy_chain_tx_lane_map_physical{50.0}=0x3210 +phy_chain_tx_lane_map_physical{51.0}=0x3210 +phy_chain_tx_lane_map_physical{52.0}=0x3210 +phy_chain_rx_polarity_flip_physical{49.0}=0x0 +phy_chain_rx_polarity_flip_physical{50.0}=0x0 +phy_chain_rx_polarity_flip_physical{51.0}=0x0 +phy_chain_rx_polarity_flip_physical{52.0}=0x0 +phy_chain_tx_polarity_flip_physical{49.0}=0x1 +phy_chain_tx_polarity_flip_physical{50.0}=0x0 +phy_chain_tx_polarity_flip_physical{51.0}=0x0 +phy_chain_tx_polarity_flip_physical{52.0}=0x1 + +#FC13 +dport_map_port_39=26 +dport_map_port_40=25 +dport_map_port_41=28 +dport_map_port_42=27 +portmap_39=53:10 +portmap_40=54:10 +portmap_41=55:10 +portmap_42=56:10 +#port_phy_addr_39=0x60 +#port_phy_addr_40=0x61 +#port_phy_addr_41=0x62 +#port_phy_addr_42=0x63 +phy_chain_rx_lane_map_physical{53.0}=0x3120 +phy_chain_rx_lane_map_physical{54.0}=0x3120 +phy_chain_rx_lane_map_physical{55.0}=0x3120 +phy_chain_rx_lane_map_physical{56.0}=0x3120 +phy_chain_tx_lane_map_physical{53.0}=0x3102 +phy_chain_tx_lane_map_physical{54.0}=0x3102 +phy_chain_tx_lane_map_physical{55.0}=0x3102 +phy_chain_tx_lane_map_physical{56.0}=0x3102 +phy_chain_rx_polarity_flip_physical{53.0}=0x0 +phy_chain_rx_polarity_flip_physical{54.0}=0x1 +phy_chain_rx_polarity_flip_physical{55.0}=0x1 +phy_chain_rx_polarity_flip_physical{56.0}=0x0 +phy_chain_tx_polarity_flip_physical{53.0}=0x0 +phy_chain_tx_polarity_flip_physical{54.0}=0x1 +phy_chain_tx_polarity_flip_physical{55.0}=0x1 +phy_chain_tx_polarity_flip_physical{56.0}=0x0 + +#FC14 +dport_map_port_43=30 +dport_map_port_44=29 +dport_map_port_45=32 +dport_map_port_46=31 +portmap_43=57:10 +portmap_44=58:10 +portmap_45=59:10 +portmap_46=60:10 +#port_phy_addr_43=0x64 +#port_phy_addr_44=0x65 +#port_phy_addr_45=0x66 +#port_phy_addr_46=0x67 +phy_chain_rx_lane_map_physical{57.0}=0x3210 +phy_chain_rx_lane_map_physical{58.0}=0x3210 +phy_chain_rx_lane_map_physical{59.0}=0x3210 +phy_chain_rx_lane_map_physical{60.0}=0x3210 +phy_chain_tx_lane_map_physical{57.0}=0x3210 +phy_chain_tx_lane_map_physical{58.0}=0x3210 +phy_chain_tx_lane_map_physical{59.0}=0x3210 +phy_chain_tx_lane_map_physical{60.0}=0x3210 +phy_chain_rx_polarity_flip_physical{57.0}=0x1 +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}=0x0 +phy_chain_tx_polarity_flip_physical{57.0}=0x0 +phy_chain_tx_polarity_flip_physical{58.0}=0x0 +phy_chain_tx_polarity_flip_physical{59.0}=0x0 +phy_chain_tx_polarity_flip_physical{60.0}=0x0 + +#FC15 +dport_map_port_47=34 +dport_map_port_48=33 +dport_map_port_49=36 +dport_map_port_50=35 +portmap_47=61:10 +portmap_48=62:10 +portmap_49=63:10 +portmap_50=64:10 +#port_phy_addr_47=0x100 +#port_phy_addr_48=0x101 +#port_phy_addr_49=0x102 +#port_phy_addr_50=0x103 +phy_chain_rx_lane_map_physical{61.0}=0x3210 +phy_chain_rx_lane_map_physical{62.0}=0x3210 +phy_chain_rx_lane_map_physical{63.0}=0x3210 +phy_chain_rx_lane_map_physical{64.0}=0x3210 +phy_chain_tx_lane_map_physical{61.0}=0x3210 +phy_chain_tx_lane_map_physical{62.0}=0x3210 +phy_chain_tx_lane_map_physical{63.0}=0x3210 +phy_chain_tx_lane_map_physical{64.0}=0x3210 +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}=0x1 +phy_chain_rx_polarity_flip_physical{64.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}=0x0 +phy_chain_tx_polarity_flip_physical{64.0}=0x0 + +#FC16 +dport_map_port_51=38 +dport_map_port_52=37 +dport_map_port_53=40 +dport_map_port_54=39 +portmap_51=65:10 +portmap_52=66:10 +portmap_53=67:10 +portmap_54=68:10 +#port_phy_addr_51=0x104 +#port_phy_addr_52=0x105 +#port_phy_addr_53=0x106 +#port_phy_addr_54=0x107 +phy_chain_rx_lane_map_physical{65.0}=0x3210 +phy_chain_rx_lane_map_physical{66.0}=0x3210 +phy_chain_rx_lane_map_physical{67.0}=0x3210 +phy_chain_rx_lane_map_physical{68.0}=0x3210 +phy_chain_tx_lane_map_physical{65.0}=0x3210 +phy_chain_tx_lane_map_physical{66.0}=0x3210 +phy_chain_tx_lane_map_physical{67.0}=0x3210 +phy_chain_tx_lane_map_physical{68.0}=0x3210 +phy_chain_rx_polarity_flip_physical{65.0}=0x0 +phy_chain_rx_polarity_flip_physical{66.0}=0x0 +phy_chain_rx_polarity_flip_physical{67.0}=0x0 +phy_chain_rx_polarity_flip_physical{68.0}=0x0 +phy_chain_tx_polarity_flip_physical{65.0}=0x0 +phy_chain_tx_polarity_flip_physical{66.0}=0x0 +phy_chain_tx_polarity_flip_physical{67.0}=0x0 +phy_chain_tx_polarity_flip_physical{68.0}=0x0 + +#FC17 +dport_map_port_55=42 +dport_map_port_56=41 +dport_map_port_57=44 +dport_map_port_58=43 +portmap_55=69:10 +portmap_56=70:10 +portmap_57=71:10 +portmap_58=72:10 +#port_phy_addr_55=0x120 +#port_phy_addr_56=0x121 +#port_phy_addr_57=0x122 +#port_phy_addr_58=0x123 +phy_chain_rx_lane_map_physical{69.0}=0x3210 +phy_chain_rx_lane_map_physical{70.0}=0x3210 +phy_chain_rx_lane_map_physical{71.0}=0x3210 +phy_chain_rx_lane_map_physical{72.0}=0x3210 +phy_chain_tx_lane_map_physical{69.0}=0x3210 +phy_chain_tx_lane_map_physical{70.0}=0x3210 +phy_chain_tx_lane_map_physical{71.0}=0x3210 +phy_chain_tx_lane_map_physical{72.0}=0x3210 +phy_chain_rx_polarity_flip_physical{69.0}=0x0 +phy_chain_rx_polarity_flip_physical{70.0}=0x0 +phy_chain_rx_polarity_flip_physical{71.0}=0x0 +phy_chain_rx_polarity_flip_physical{72.0}=0x0 +phy_chain_tx_polarity_flip_physical{69.0}=0x0 +phy_chain_tx_polarity_flip_physical{70.0}=0x0 +phy_chain_tx_polarity_flip_physical{71.0}=0x0 +phy_chain_tx_polarity_flip_physical{72.0}=0x0 + +#FC18 +dport_map_port_59=46 +dport_map_port_60=45 +dport_map_port_61=48 +dport_map_port_62=47 +portmap_59=73:10 +portmap_60=74:10 +portmap_61=75:10 +portmap_62=76:10 +#port_phy_addr_59=0x124 +#port_phy_addr_60=0x125 +#port_phy_addr_61=0x126 +#port_phy_addr_62=0x127 +phy_chain_rx_lane_map_physical{73.0}=0x3210 +phy_chain_rx_lane_map_physical{74.0}=0x3210 +phy_chain_rx_lane_map_physical{75.0}=0x3210 +phy_chain_rx_lane_map_physical{76.0}=0x3210 +phy_chain_tx_lane_map_physical{73.0}=0x2031 +phy_chain_tx_lane_map_physical{74.0}=0x2031 +phy_chain_tx_lane_map_physical{75.0}=0x2031 +phy_chain_tx_lane_map_physical{76.0}=0x2031 +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}=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}=0x0 + +#FC19 + +dport_map_port_64=64 +portmap_64=81:10:m +phy_chain_rx_polarity_flip_physical{81.0}=0x1 +phy_chain_tx_polarity_flip_physical{81.0}=0x1 + diff --git a/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/port_config.ini b/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/port_config.ini old mode 100644 new mode 100755 index 2e128a4fde65..119fe814fee1 --- a/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/port_config.ini +++ b/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/port_config.ini @@ -47,9 +47,9 @@ Ethernet44 74 tenGigE45 45 10000 Ethernet45 73 tenGigE46 46 10000 Ethernet46 76 tenGigE47 47 10000 Ethernet47 75 tenGigE48 48 10000 -Ethernet48 29,30,31,32 hundredGigE49 49 100000 -Ethernet52 33,34,35,36 hundredGigE50 53 100000 -Ethernet56 37,38,39,40 hundredGigE51 57 100000 -Ethernet60 41,42,43,44 hundredGigE52 61 100000 +Ethernet48 37,38,39,40 hundredGigE49 49 100000 +Ethernet52 29,30,31,32 hundredGigE50 53 100000 +Ethernet56 33,34,35,36 hundredGigE51 57 100000 +Ethernet60 49,50,51,52 hundredGigE52 61 100000 Ethernet64 45,46,47,48 hundredGigE53 65 100000 -Ethernet68 49,50,51,52 hundredGigE54 69 100000 +Ethernet68 41,42,43,44 hundredGigE54 69 100000 diff --git a/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/sai.profile b/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/sai.profile old mode 100644 new mode 100755 index 952c87a00eeb..124811980e70 --- a/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/sai.profile +++ b/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/sai.profile @@ -1 +1,3 @@ -SAI_INIT_CONFIG_FILE=/etc/bcm/td3-as5835t-48x10G+6x100G.config.bcm +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/mv2-as5835t-48x10G+6x100G.config.bcm +SAI_BOARD_CONFIG_PATH=/etc/accton +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/td3-as5835t-48x10G+6x100G.config.bcm b/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/td3-as5835t-48x10G+6x100G.config.bcm deleted file mode 100644 index 4b73e8c29db3..000000000000 --- a/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/td3-as5835t-48x10G+6x100G.config.bcm +++ /dev/null @@ -1,515 +0,0 @@ -#polarity/lanemap is using TH2 style. -core_clock_frequency=1525 -dpp_clock_ratio=2:3 - -ptp_ts_pll_fref=50000000 -ptp_bs_fref_0=50000000 -ptp_bs_fref_1=50000000 - -oversubscribe_mode=1 - -pbmp_xport_xe=0x1FFFFFFFFFFFFFFFE - -parity_enable=0 -mem_cache_enable=0 - -l2_mem_entries=32768 -#l3_mem_entries=49152 -#fpem_mem_entries=16384 -l2xmsg_mode=1 - -#FC0 -dport_map_port_1=2 -dport_map_port_2=1 -dport_map_port_3=4 -dport_map_port_4=3 -portmap_1=1:10 -portmap_2=2:10 -portmap_3=3:10 -portmap_4=4:10 -#port_phy_addr_1=0x00 -#port_phy_addr_2=0x01 -#port_phy_addr_3=0x02 -#port_phy_addr_4=0x03 -phy_chain_rx_lane_map_physical{1.0}=0x0123 -phy_chain_rx_lane_map_physical{2.0}=0x0123 -phy_chain_rx_lane_map_physical{3.0}=0x0123 -phy_chain_rx_lane_map_physical{4.0}=0x0123 -phy_chain_tx_lane_map_physical{1.0}=0x0123 -phy_chain_tx_lane_map_physical{2.0}=0x0123 -phy_chain_tx_lane_map_physical{3.0}=0x0123 -phy_chain_tx_lane_map_physical{4.0}=0x0123 -phy_chain_rx_polarity_flip_physical{1.0}=0x1 -phy_chain_rx_polarity_flip_physical{2.0}=0x1 -phy_chain_rx_polarity_flip_physical{3.0}=0x1 -phy_chain_rx_polarity_flip_physical{4.0}=0x1 -phy_chain_tx_polarity_flip_physical{1.0}=0x0 -phy_chain_tx_polarity_flip_physical{2.0}=0x0 -phy_chain_tx_polarity_flip_physical{3.0}=0x0 -phy_chain_tx_polarity_flip_physical{4.0}=0x0 - -#FC1 -dport_map_port_5=6 -dport_map_port_6=5 -dport_map_port_7=8 -dport_map_port_8=7 -portmap_5=5:10 -portmap_6=6:10 -portmap_7=7:10 -portmap_8=8:10 -#port_phy_addr_5=0x04 -#port_phy_addr_6=0x05 -#port_phy_addr_7=0x06 -#port_phy_addr_8=0x07 -phy_chain_rx_lane_map_physical{5.0}=0x0123 -phy_chain_rx_lane_map_physical{6.0}=0x0123 -phy_chain_rx_lane_map_physical{7.0}=0x0123 -phy_chain_rx_lane_map_physical{8.0}=0x0123 -phy_chain_tx_lane_map_physical{5.0}=0x0123 -phy_chain_tx_lane_map_physical{6.0}=0x0123 -phy_chain_tx_lane_map_physical{7.0}=0x0123 -phy_chain_tx_lane_map_physical{8.0}=0x0123 -phy_chain_rx_polarity_flip_physical{5.0}=0x0 -phy_chain_rx_polarity_flip_physical{6.0}=0x0 -phy_chain_rx_polarity_flip_physical{7.0}=0x0 -phy_chain_rx_polarity_flip_physical{8.0}=0x0 -phy_chain_tx_polarity_flip_physical{5.0}=0x0 -phy_chain_tx_polarity_flip_physical{6.0}=0x0 -phy_chain_tx_polarity_flip_physical{7.0}=0x0 -phy_chain_tx_polarity_flip_physical{8.0}=0x0 - -#FC2 -dport_map_port_9=10 -dport_map_port_10=9 -dport_map_port_11=12 -dport_map_port_12=11 -portmap_9=9:10 -portmap_10=10:10 -portmap_11=11:10 -portmap_12=12:10 -#port_phy_addr_9=0x20 -#port_phy_addr_10=0x21 -#port_phy_addr_11=0x22 -#port_phy_addr_12=0x23 -phy_chain_rx_lane_map_physical{9.0}=0x0123 -phy_chain_rx_lane_map_physical{10.0}=0x0123 -phy_chain_rx_lane_map_physical{11.0}=0x0123 -phy_chain_rx_lane_map_physical{12.0}=0x0123 -phy_chain_tx_lane_map_physical{9.0}=0x0123 -phy_chain_tx_lane_map_physical{10.0}=0x0123 -phy_chain_tx_lane_map_physical{11.0}=0x0123 -phy_chain_tx_lane_map_physical{12.0}=0x0123 -phy_chain_rx_polarity_flip_physical{9.0}=0x0 -phy_chain_rx_polarity_flip_physical{10.0}=0x0 -phy_chain_rx_polarity_flip_physical{11.0}=0x0 -phy_chain_rx_polarity_flip_physical{12.0}=0x0 -phy_chain_tx_polarity_flip_physical{9.0}=0x0 -phy_chain_tx_polarity_flip_physical{10.0}=0x0 -phy_chain_tx_polarity_flip_physical{11.0}=0x0 -phy_chain_tx_polarity_flip_physical{12.0}=0x0 - -#FC3 -dport_map_port_13=14 -dport_map_port_14=13 -dport_map_port_15=16 -dport_map_port_16=15 -portmap_13=13:10 -portmap_14=14:10 -portmap_15=15:10 -portmap_16=16:10 -#port_phy_addr_13=0x24 -#port_phy_addr_14=0x25 -#port_phy_addr_15=0x26 -#port_phy_addr_16=0x27 -phy_chain_rx_lane_map_physical{13.0}=0x0123 -phy_chain_rx_lane_map_physical{14.0}=0x0123 -phy_chain_rx_lane_map_physical{15.0}=0x0123 -phy_chain_rx_lane_map_physical{16.0}=0x0123 -phy_chain_tx_lane_map_physical{13.0}=0x0123 -phy_chain_tx_lane_map_physical{14.0}=0x0123 -phy_chain_tx_lane_map_physical{15.0}=0x0123 -phy_chain_tx_lane_map_physical{16.0}=0x0123 -phy_chain_rx_polarity_flip_physical{13.0}=0x0 -phy_chain_rx_polarity_flip_physical{14.0}=0x0 -phy_chain_rx_polarity_flip_physical{15.0}=0x0 -phy_chain_rx_polarity_flip_physical{16.0}=0x0 -phy_chain_tx_polarity_flip_physical{13.0}=0x0 -phy_chain_tx_polarity_flip_physical{14.0}=0x0 -phy_chain_tx_polarity_flip_physical{15.0}=0x0 -phy_chain_tx_polarity_flip_physical{16.0}=0x0 - -#FC4 -dport_map_port_17=18 -dport_map_port_18=17 -dport_map_port_19=20 -dport_map_port_20=19 -portmap_17=17:10 -portmap_18=18:10 -portmap_19=19:10 -portmap_20=20:10 -#port_phy_addr_17=0x40 -#port_phy_addr_18=0x41 -#port_phy_addr_19=0x42 -#port_phy_addr_20=0x43 -phy_chain_rx_lane_map_physical{17.0}=0x0123 -phy_chain_rx_lane_map_physical{18.0}=0x0123 -phy_chain_rx_lane_map_physical{19.0}=0x0123 -phy_chain_rx_lane_map_physical{20.0}=0x0123 -phy_chain_tx_lane_map_physical{17.0}=0x0123 -phy_chain_tx_lane_map_physical{18.0}=0x0123 -phy_chain_tx_lane_map_physical{19.0}=0x0123 -phy_chain_tx_lane_map_physical{20.0}=0x0123 -phy_chain_rx_polarity_flip_physical{17.0}=0x1 -phy_chain_rx_polarity_flip_physical{18.0}=0x1 -phy_chain_rx_polarity_flip_physical{19.0}=0x1 -phy_chain_rx_polarity_flip_physical{20.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 - -#FC5 -dport_map_port_21=22 -dport_map_port_22=21 -dport_map_port_23=24 -dport_map_port_24=23 -portmap_21=21:10 -portmap_22=22:10 -portmap_23=23:10 -portmap_24=24:10 -#port_phy_addr_21=0x44 -#port_phy_addr_22=0x45 -#port_phy_addr_23=0x46 -#port_phy_addr_24=0x47 -phy_chain_rx_lane_map_physical{21.0}=0x0123 -phy_chain_rx_lane_map_physical{22.0}=0x0123 -phy_chain_rx_lane_map_physical{23.0}=0x0123 -phy_chain_rx_lane_map_physical{24.0}=0x0123 -phy_chain_tx_lane_map_physical{21.0}=0x0123 -phy_chain_tx_lane_map_physical{22.0}=0x0123 -phy_chain_tx_lane_map_physical{23.0}=0x0123 -phy_chain_tx_lane_map_physical{24.0}=0x0123 -phy_chain_rx_polarity_flip_physical{21.0}=0x0 -phy_chain_rx_polarity_flip_physical{22.0}=0x0 -phy_chain_rx_polarity_flip_physical{23.0}=0x0 -phy_chain_rx_polarity_flip_physical{24.0}=0x0 -phy_chain_tx_polarity_flip_physical{21.0}=0x0 -phy_chain_tx_polarity_flip_physical{22.0}=0x0 -phy_chain_tx_polarity_flip_physical{23.0}=0x0 -phy_chain_tx_polarity_flip_physical{24.0}=0x0 - -#FC6 - -#FC7 -dport_map_port_25=50 -portmap_25=29:100:4 -phy_chain_rx_lane_map_physical{29.0}=0x1302 -phy_chain_rx_lane_map_physical{30.0}=0x1302 -phy_chain_rx_lane_map_physical{31.0}=0x1302 -phy_chain_rx_lane_map_physical{32.0}=0x1302 -phy_chain_tx_lane_map_physical{29.0}=0x2031 -phy_chain_tx_lane_map_physical{30.0}=0x2031 -phy_chain_tx_lane_map_physical{31.0}=0x2031 -phy_chain_tx_lane_map_physical{32.0}=0x2031 -phy_chain_rx_polarity_flip_physical{29.0}=0x0 -phy_chain_rx_polarity_flip_physical{30.0}=0x0 -phy_chain_rx_polarity_flip_physical{31.0}=0x0 -phy_chain_rx_polarity_flip_physical{32.0}=0x1 -phy_chain_tx_polarity_flip_physical{29.0}=0x1 -phy_chain_tx_polarity_flip_physical{30.0}=0x1 -phy_chain_tx_polarity_flip_physical{31.0}=0x1 -phy_chain_tx_polarity_flip_physical{32.0}=0x1 - -#FC8 -dport_map_port_26=51 -portmap_26=33:100:4 -phy_chain_rx_lane_map_physical{33.0}=0x0123 -phy_chain_rx_lane_map_physical{34.0}=0x0123 -phy_chain_rx_lane_map_physical{35.0}=0x0123 -phy_chain_rx_lane_map_physical{36.0}=0x0123 -phy_chain_tx_lane_map_physical{33.0}=0x0123 -phy_chain_tx_lane_map_physical{34.0}=0x0123 -phy_chain_tx_lane_map_physical{35.0}=0x0123 -phy_chain_tx_lane_map_physical{36.0}=0x0123 -phy_chain_rx_polarity_flip_physical{33.0}=0x0 -phy_chain_rx_polarity_flip_physical{34.0}=0x1 -phy_chain_rx_polarity_flip_physical{35.0}=0x0 -phy_chain_rx_polarity_flip_physical{36.0}=0x1 -phy_chain_tx_polarity_flip_physical{33.0}=0x0 -phy_chain_tx_polarity_flip_physical{34.0}=0x0 -phy_chain_tx_polarity_flip_physical{35.0}=0x0 -phy_chain_tx_polarity_flip_physical{36.0}=0x0 - -#FC9 -dport_map_port_27=49 -dport_map_port_28=52 -dport_map_port_29=53 -dport_map_port_30=54 -portmap_27=37:100:4 -phy_chain_rx_lane_map_physical{37.0}=0x1023 -phy_chain_rx_lane_map_physical{38.0}=0x1023 -phy_chain_rx_lane_map_physical{39.0}=0x1023 -phy_chain_rx_lane_map_physical{40.0}=0x1023 -phy_chain_tx_lane_map_physical{37.0}=0x3210 -phy_chain_tx_lane_map_physical{38.0}=0x3210 -phy_chain_tx_lane_map_physical{39.0}=0x3210 -phy_chain_tx_lane_map_physical{40.0}=0x3210 -phy_chain_rx_polarity_flip_physical{37.0}=0x0 -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_tx_polarity_flip_physical{37.0}=0x0 -phy_chain_tx_polarity_flip_physical{38.0}=0x1 -phy_chain_tx_polarity_flip_physical{39.0}=0x0 -phy_chain_tx_polarity_flip_physical{40.0}=0x0 - -#FC10 -dport_map_port_33=57 -portmap_33=41:100:4 -phy_chain_rx_lane_map_physical{41.0}=0x3210 -phy_chain_rx_lane_map_physical{42.0}=0x3210 -phy_chain_rx_lane_map_physical{43.0}=0x3210 -phy_chain_rx_lane_map_physical{44.0}=0x3210 -phy_chain_tx_lane_map_physical{41.0}=0x3210 -phy_chain_tx_lane_map_physical{42.0}=0x3210 -phy_chain_tx_lane_map_physical{43.0}=0x3210 -phy_chain_tx_lane_map_physical{44.0}=0x3210 -phy_chain_rx_polarity_flip_physical{41.0}=0x0 -phy_chain_rx_polarity_flip_physical{42.0}=0x1 -phy_chain_rx_polarity_flip_physical{43.0}=0x0 -phy_chain_rx_polarity_flip_physical{44.0}=0x1 -phy_chain_tx_polarity_flip_physical{41.0}=0x1 -phy_chain_tx_polarity_flip_physical{42.0}=0x0 -phy_chain_tx_polarity_flip_physical{43.0}=0x0 -phy_chain_tx_polarity_flip_physical{44.0}=0x0 - -#FC11 -dport_map_port_34=56 -portmap_34=45:100:4 -phy_chain_rx_lane_map_physical{45.0}=0x3210 -phy_chain_rx_lane_map_physical{46.0}=0x3210 -phy_chain_rx_lane_map_physical{47.0}=0x3210 -phy_chain_rx_lane_map_physical{48.0}=0x3210 -phy_chain_tx_lane_map_physical{45.0}=0x3210 -phy_chain_tx_lane_map_physical{46.0}=0x3210 -phy_chain_tx_lane_map_physical{47.0}=0x3210 -phy_chain_tx_lane_map_physical{48.0}=0x3210 -phy_chain_rx_polarity_flip_physical{45.0}=0x0 -phy_chain_rx_polarity_flip_physical{46.0}=0x0 -phy_chain_rx_polarity_flip_physical{47.0}=0x0 -phy_chain_rx_polarity_flip_physical{48.0}=0x0 -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}=0x0 - -#FC12 -dport_map_port_35=55 -dport_map_port_36=58 -dport_map_port_37=59 -dport_map_port_38=60 -portmap_35=49:100:4 -phy_chain_rx_lane_map_physical{49.0}=0x3210 -phy_chain_rx_lane_map_physical{50.0}=0x3210 -phy_chain_rx_lane_map_physical{51.0}=0x3210 -phy_chain_rx_lane_map_physical{52.0}=0x3210 -phy_chain_tx_lane_map_physical{49.0}=0x3210 -phy_chain_tx_lane_map_physical{50.0}=0x3210 -phy_chain_tx_lane_map_physical{51.0}=0x3210 -phy_chain_tx_lane_map_physical{52.0}=0x3210 -phy_chain_rx_polarity_flip_physical{49.0}=0x0 -phy_chain_rx_polarity_flip_physical{50.0}=0x0 -phy_chain_rx_polarity_flip_physical{51.0}=0x0 -phy_chain_rx_polarity_flip_physical{52.0}=0x0 -phy_chain_tx_polarity_flip_physical{49.0}=0x1 -phy_chain_tx_polarity_flip_physical{50.0}=0x0 -phy_chain_tx_polarity_flip_physical{51.0}=0x0 -phy_chain_tx_polarity_flip_physical{52.0}=0x1 - -#FC13 -dport_map_port_39=26 -dport_map_port_40=25 -dport_map_port_41=28 -dport_map_port_42=27 -portmap_39=53:10 -portmap_40=54:10 -portmap_41=55:10 -portmap_42=56:10 -#port_phy_addr_39=0x60 -#port_phy_addr_40=0x61 -#port_phy_addr_41=0x62 -#port_phy_addr_42=0x63 -phy_chain_rx_lane_map_physical{53.0}=0x3120 -phy_chain_rx_lane_map_physical{54.0}=0x3120 -phy_chain_rx_lane_map_physical{55.0}=0x3120 -phy_chain_rx_lane_map_physical{56.0}=0x3120 -phy_chain_tx_lane_map_physical{53.0}=0x3102 -phy_chain_tx_lane_map_physical{54.0}=0x3102 -phy_chain_tx_lane_map_physical{55.0}=0x3102 -phy_chain_tx_lane_map_physical{56.0}=0x3102 -phy_chain_rx_polarity_flip_physical{53.0}=0x0 -phy_chain_rx_polarity_flip_physical{54.0}=0x1 -phy_chain_rx_polarity_flip_physical{55.0}=0x1 -phy_chain_rx_polarity_flip_physical{56.0}=0x0 -phy_chain_tx_polarity_flip_physical{53.0}=0x0 -phy_chain_tx_polarity_flip_physical{54.0}=0x1 -phy_chain_tx_polarity_flip_physical{55.0}=0x1 -phy_chain_tx_polarity_flip_physical{56.0}=0x0 - -#FC14 -dport_map_port_43=30 -dport_map_port_44=29 -dport_map_port_45=32 -dport_map_port_46=31 -portmap_43=57:10 -portmap_44=58:10 -portmap_45=59:10 -portmap_46=60:10 -#port_phy_addr_43=0x64 -#port_phy_addr_44=0x65 -#port_phy_addr_45=0x66 -#port_phy_addr_46=0x67 -phy_chain_rx_lane_map_physical{57.0}=0x3210 -phy_chain_rx_lane_map_physical{58.0}=0x3210 -phy_chain_rx_lane_map_physical{59.0}=0x3210 -phy_chain_rx_lane_map_physical{60.0}=0x3210 -phy_chain_tx_lane_map_physical{57.0}=0x3210 -phy_chain_tx_lane_map_physical{58.0}=0x3210 -phy_chain_tx_lane_map_physical{59.0}=0x3210 -phy_chain_tx_lane_map_physical{60.0}=0x3210 -phy_chain_rx_polarity_flip_physical{57.0}=0x1 -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}=0x0 -phy_chain_tx_polarity_flip_physical{57.0}=0x0 -phy_chain_tx_polarity_flip_physical{58.0}=0x0 -phy_chain_tx_polarity_flip_physical{59.0}=0x0 -phy_chain_tx_polarity_flip_physical{60.0}=0x0 - -#FC15 -dport_map_port_47=34 -dport_map_port_48=33 -dport_map_port_49=36 -dport_map_port_50=35 -portmap_47=61:10 -portmap_48=62:10 -portmap_49=63:10 -portmap_50=64:10 -#port_phy_addr_47=0x100 -#port_phy_addr_48=0x101 -#port_phy_addr_49=0x102 -#port_phy_addr_50=0x103 -phy_chain_rx_lane_map_physical{61.0}=0x3210 -phy_chain_rx_lane_map_physical{62.0}=0x3210 -phy_chain_rx_lane_map_physical{63.0}=0x3210 -phy_chain_rx_lane_map_physical{64.0}=0x3210 -phy_chain_tx_lane_map_physical{61.0}=0x3210 -phy_chain_tx_lane_map_physical{62.0}=0x3210 -phy_chain_tx_lane_map_physical{63.0}=0x3210 -phy_chain_tx_lane_map_physical{64.0}=0x3210 -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}=0x1 -phy_chain_rx_polarity_flip_physical{64.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}=0x0 -phy_chain_tx_polarity_flip_physical{64.0}=0x0 - -#FC16 -dport_map_port_51=38 -dport_map_port_52=37 -dport_map_port_53=40 -dport_map_port_54=39 -portmap_51=65:10 -portmap_52=66:10 -portmap_53=67:10 -portmap_54=68:10 -#port_phy_addr_51=0x104 -#port_phy_addr_52=0x105 -#port_phy_addr_53=0x106 -#port_phy_addr_54=0x107 -phy_chain_rx_lane_map_physical{65.0}=0x3210 -phy_chain_rx_lane_map_physical{66.0}=0x3210 -phy_chain_rx_lane_map_physical{67.0}=0x3210 -phy_chain_rx_lane_map_physical{68.0}=0x3210 -phy_chain_tx_lane_map_physical{65.0}=0x3210 -phy_chain_tx_lane_map_physical{66.0}=0x3210 -phy_chain_tx_lane_map_physical{67.0}=0x3210 -phy_chain_tx_lane_map_physical{68.0}=0x3210 -phy_chain_rx_polarity_flip_physical{65.0}=0x0 -phy_chain_rx_polarity_flip_physical{66.0}=0x0 -phy_chain_rx_polarity_flip_physical{67.0}=0x0 -phy_chain_rx_polarity_flip_physical{68.0}=0x0 -phy_chain_tx_polarity_flip_physical{65.0}=0x0 -phy_chain_tx_polarity_flip_physical{66.0}=0x0 -phy_chain_tx_polarity_flip_physical{67.0}=0x0 -phy_chain_tx_polarity_flip_physical{68.0}=0x0 - -#FC17 -dport_map_port_55=42 -dport_map_port_56=41 -dport_map_port_57=44 -dport_map_port_58=43 -portmap_55=69:10 -portmap_56=70:10 -portmap_57=71:10 -portmap_58=72:10 -#port_phy_addr_55=0x120 -#port_phy_addr_56=0x121 -#port_phy_addr_57=0x122 -#port_phy_addr_58=0x123 -phy_chain_rx_lane_map_physical{69.0}=0x3210 -phy_chain_rx_lane_map_physical{70.0}=0x3210 -phy_chain_rx_lane_map_physical{71.0}=0x3210 -phy_chain_rx_lane_map_physical{72.0}=0x3210 -phy_chain_tx_lane_map_physical{69.0}=0x3210 -phy_chain_tx_lane_map_physical{70.0}=0x3210 -phy_chain_tx_lane_map_physical{71.0}=0x3210 -phy_chain_tx_lane_map_physical{72.0}=0x3210 -phy_chain_rx_polarity_flip_physical{69.0}=0x0 -phy_chain_rx_polarity_flip_physical{70.0}=0x0 -phy_chain_rx_polarity_flip_physical{71.0}=0x0 -phy_chain_rx_polarity_flip_physical{72.0}=0x0 -phy_chain_tx_polarity_flip_physical{69.0}=0x0 -phy_chain_tx_polarity_flip_physical{70.0}=0x0 -phy_chain_tx_polarity_flip_physical{71.0}=0x0 -phy_chain_tx_polarity_flip_physical{72.0}=0x0 - -#FC18 -dport_map_port_59=46 -dport_map_port_60=45 -dport_map_port_61=48 -dport_map_port_62=47 -portmap_59=73:10 -portmap_60=74:10 -portmap_61=75:10 -portmap_62=76:10 -#port_phy_addr_59=0x124 -#port_phy_addr_60=0x125 -#port_phy_addr_61=0x126 -#port_phy_addr_62=0x127 -phy_chain_rx_lane_map_physical{73.0}=0x3210 -phy_chain_rx_lane_map_physical{74.0}=0x3210 -phy_chain_rx_lane_map_physical{75.0}=0x3210 -phy_chain_rx_lane_map_physical{76.0}=0x3210 -phy_chain_tx_lane_map_physical{73.0}=0x2031 -phy_chain_tx_lane_map_physical{74.0}=0x2031 -phy_chain_tx_lane_map_physical{75.0}=0x2031 -phy_chain_tx_lane_map_physical{76.0}=0x2031 -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}=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}=0x0 - -#FC19 - -dport_map_port_64=64 -portmap_64=81:10:m -phy_chain_rx_polarity_flip_physical{81.0}=0x1 -phy_chain_tx_polarity_flip_physical{81.0}=0x1 - diff --git a/device/accton/x86_64-accton_as5835_54t-r0/plugins/eeprom.py b/device/accton/x86_64-accton_as5835_54t-r0/plugins/eeprom.py index 7681caafeef4..951384d5e37d 100644 --- a/device/accton/x86_64-accton_as5835_54t-r0/plugins/eeprom.py +++ b/device/accton/x86_64-accton_as5835_54t-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -11,14 +8,16 @@ 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") +except ImportError as 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/1-0057/eeprom" - #Two i2c buses might get flipped order, check them both. + # Two i2c buses might get flipped order, check them both. if not os.path.exists(self.eeprom_path): self.eeprom_path = "/sys/bus/i2c/devices/0-0057/eeprom" super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/accton/x86_64-accton_as5835_54t-r0/plugins/psuutil.py b/device/accton/x86_64-accton_as5835_54t-r0/plugins/psuutil.py index c95bc27897dc..b22e01f5e9fc 100644 --- a/device/accton/x86_64-accton_as5835_54t-r0/plugins/psuutil.py +++ b/device/accton/x86_64-accton_as5835_54t-r0/plugins/psuutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Accton # @@ -13,7 +11,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" diff --git a/device/accton/x86_64-accton_as5835_54t-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as5835_54t-r0/plugins/sfputil.py index 34e8f724ae42..7c7e7f941a1f 100644 --- a/device/accton/x86_64-accton_as5835_54t-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as5835_54t-r0/plugins/sfputil.py @@ -14,6 +14,7 @@ SFP_STATUS_INSERTED = '1' SFP_STATUS_REMOVED = '0' + class SfpUtil(SfpUtilBase): """Platform-specific SfpUtil class""" @@ -23,31 +24,31 @@ class SfpUtil(SfpUtilBase): _port_to_eeprom_mapping = {} _port_to_i2c_mapping = { - 49: 28, #QSFP49 - 50: 28, - 51: 28, - 52: 28, - 53: 29, #QSFP50 - 54: 29, - 55: 29, - 56: 29, - 57: 26, #QSFP51 - 58: 26, - 59: 26, - 60: 26, - 61: 30, #QSFP52 - 62: 30, - 63: 30, - 64: 30, - 65: 31, #QSFP53 - 66: 31, - 67: 31, - 68: 31, - 69: 27, #QSFP54 - 70: 27, - 71: 27, - 72: 27, - } + 49: 28, # QSFP49 + 50: 28, + 51: 28, + 52: 28, + 53: 29, # QSFP50 + 54: 29, + 55: 29, + 56: 29, + 57: 26, # QSFP51 + 58: 26, + 59: 26, + 60: 26, + 61: 30, # QSFP52 + 62: 30, + 63: 30, + 64: 30, + 65: 31, # QSFP53 + 66: 31, + 67: 31, + 68: 31, + 69: 27, # QSFP54 + 70: 27, + 71: 27, + 72: 27, + } @property def port_start(self): @@ -64,10 +65,10 @@ def qsfp_port_start(self): @property def qsfp_port_end(self): return self.PORT_END - + @property def qsfp_ports(self): - return range(self.PORT_START, self.PORTS_IN_BLOCK + 1) + return list(range(self.PORT_START, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -81,9 +82,9 @@ def __init__(self): SfpUtilBase.__init__(self) - # For port 49~54 are QSFP, here presumed they're all split to 4 lanes. - def get_cage_num(self, port_num): + + def get_cage_num(self, port_num): cage_num = port_num if (port_num >= self.PORT_START): cage_num = (port_num - self.PORT_START)/4 @@ -95,51 +96,51 @@ 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 - + cage_num = self.get_cage_num(port_num) path = "/sys/bus/i2c/devices/3-0062/module_present_{0}" port_ps = path.format(cage_num) - content="0" + content = "0" try: val_file = open(port_ps) content = val_file.readline().rstrip() val_file.close() except IOError as e: - print "Error: unable to access file: %s" % str(e) + print("Error: unable to access file: %s" % str(e)) return False - + if content == "1": return True return False - def get_low_power_mode_cpld(self, port_num): + def get_low_power_mode_cpld(self, port_num): if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: return False cage_num = self.get_cage_num(port_num) path = "/sys/bus/i2c/devices/3-0062/module_lpmode_{0}" lp_mode_path = path.format(cage_num) - + try: val_file = open(lp_mode_path) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = val_file.readline().rstrip() val_file.close() - + if content == "1": return True return False - def get_low_power_mode(self, port_num): + def get_low_power_mode(self, port_num): if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: return False - + if not self.get_presence(port_num): return False @@ -150,15 +151,15 @@ def get_low_power_mode(self, port_num): eeprom.seek(93) lpmode = ord(eeprom.read(1)) - if not (lpmode & 0x1): # 'Power override' bit is 0 + if not (lpmode & 0x1): # 'Power override' bit is 0 return self.get_low_power_mode_cpld(port_num) else: if ((lpmode & 0x2) == 0x2): - return True # Low Power Mode if "Power set" bit is 1 + return True # Low Power Mode if "Power set" bit is 1 else: - return False # High Power Mode if "Power set" bit is 0 + return False # High Power Mode if "Power set" bit is 0 except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False finally: if eeprom is not None: @@ -167,16 +168,16 @@ def get_low_power_mode(self, port_num): def set_low_power_mode(self, port_num, lpmode): if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: - return False + return False try: eeprom = None if not self.get_presence(port_num): - return False # Port is not present, unable to set the eeprom + return False # Port is not present, unable to set the eeprom # Fill in write buffer - regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode + regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode buffer = create_string_buffer(1) buffer[0] = chr(regval) @@ -186,7 +187,7 @@ def set_low_power_mode(self, port_num, lpmode): eeprom.write(buffer[0]) return True except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False finally: if eeprom is not None: @@ -196,24 +197,24 @@ def set_low_power_mode(self, port_num, lpmode): def reset(self, port_num): if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: return False - + cage_num = self.get_cage_num(port_num) path = "/sys/bus/i2c/devices/3-0062/module_reset_{0}" port_ps = path.format(cage_num) try: reg_file = open(port_ps, mode="w", buffering=0) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False - #toggle reset + # toggle reset reg_file.seek(0) reg_file.write('0') time.sleep(1) reg_file.seek(0) reg_file.write('1') reg_file.close() - + return True @property @@ -223,31 +224,32 @@ def _get_presence_bitmap(self): try: reg_file = open("/sys/bus/i2c/devices/3-0062/module_present_all") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False bitmap += reg_file.readline().rstrip() + " " reg_file.close() rev = bitmap.split(" ") - rev.pop() # Remove the last useless character + rev.pop() # Remove the last useless character # Save port 49-54 into buffer tmp = rev.pop() # Insert port 1-48 - for i in range (0, 6): + for i in range(0, 6): rev.append(hex(0)[2:]) rev[i] = rev[i].zfill(2) # Expand port 49-54 - for i in range (0, 6): - val = (int(tmp,16) >> i) & 0x1 + for i in range(0, 6): + val = (int(tmp, 16) >> i) & 0x1 rev.append(hex(val)[2:]) rev = "".join(rev[::-1]) - return int(rev,16) + return int(rev, 16) + + data = {'valid': 0, 'present': 0} - data = {'valid':0, 'present':0} def get_transceiver_change_event(self, timeout=0): start_time = time.time() @@ -258,17 +260,17 @@ def get_transceiver_change_event(self, timeout=0): if timeout == 0: blocking = True elif timeout > 0: - timeout = timeout / float(1000) # Convert to secs + timeout = timeout / float(1000) # Convert to secs else: - print "get_transceiver_change_event:Invalid timeout value", timeout + print("get_transceiver_change_event:Invalid timeout value", timeout) return False, {} end_time = start_time + timeout if start_time > end_time: - print 'get_transceiver_change_event:' \ - 'time wrap / invalid timeout value', timeout + print('get_transceiver_change_event:' + 'time wrap / invalid timeout value', timeout) - return False, {} # Time wrap or possibly incorrect timeout + return False, {} # Time wrap or possibly incorrect timeout while timeout >= 0: # Check for OIR events and return updated port_dict @@ -276,7 +278,7 @@ def get_transceiver_change_event(self, timeout=0): reg_value = self._get_presence_bitmap changed_ports = self.data['present'] ^ reg_value if changed_ports: - for port in range (self.port_start, self.port_end+1): + for port in range(self.port_start, self.port_end+1): # Mask off the bit corresponding to our port mask = (1 << (port - 1)) if changed_ports & mask: @@ -286,7 +288,7 @@ def get_transceiver_change_event(self, timeout=0): else: port_dict[port] = SFP_STATUS_INSERTED - # Update cache + # Update cache self.data['present'] = reg_value self.data['valid'] = 1 return True, port_dict @@ -296,10 +298,10 @@ def get_transceiver_change_event(self, timeout=0): else: timeout = end_time - time.time() if timeout >= 1: - time.sleep(1) # We poll at 1 second granularity + time.sleep(1) # We poll at 1 second granularity else: if timeout > 0: time.sleep(timeout) return True, {} - print "get_transceiver_change_event: Should not reach here." + print("get_transceiver_change_event: Should not reach here.") return False, {} diff --git a/device/accton/x86_64-accton_as5835_54t-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as5835_54t-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as5835_54t-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as5835_54t-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as5835_54x-r0/Accton-AS5835-54X/sai.profile b/device/accton/x86_64-accton_as5835_54x-r0/Accton-AS5835-54X/sai.profile index 8b795f81c4f2..744c6571f7c7 100644 --- a/device/accton/x86_64-accton_as5835_54x-r0/Accton-AS5835-54X/sai.profile +++ b/device/accton/x86_64-accton_as5835_54x-r0/Accton-AS5835-54X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/etc/bcm/mv2-as5835-48x10G+6x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as5835_54x-r0/plugins/eeprom.py b/device/accton/x86_64-accton_as5835_54x-r0/plugins/eeprom.py index 7681caafeef4..951384d5e37d 100644 --- a/device/accton/x86_64-accton_as5835_54x-r0/plugins/eeprom.py +++ b/device/accton/x86_64-accton_as5835_54x-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -11,14 +8,16 @@ 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") +except ImportError as 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/1-0057/eeprom" - #Two i2c buses might get flipped order, check them both. + # Two i2c buses might get flipped order, check them both. if not os.path.exists(self.eeprom_path): self.eeprom_path = "/sys/bus/i2c/devices/0-0057/eeprom" super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/accton/x86_64-accton_as5835_54x-r0/plugins/psuutil.py b/device/accton/x86_64-accton_as5835_54x-r0/plugins/psuutil.py index c95bc27897dc..b22e01f5e9fc 100644 --- a/device/accton/x86_64-accton_as5835_54x-r0/plugins/psuutil.py +++ b/device/accton/x86_64-accton_as5835_54x-r0/plugins/psuutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Accton # @@ -13,7 +11,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" diff --git a/device/accton/x86_64-accton_as5835_54x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as5835_54x-r0/plugins/sfputil.py index 7782f708fccd..b18b15f3e68c 100644 --- a/device/accton/x86_64-accton_as5835_54x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as5835_54x-r0/plugins/sfputil.py @@ -14,6 +14,7 @@ SFP_STATUS_INSERTED = '1' SFP_STATUS_REMOVED = '0' + class SfpUtil(SfpUtilBase): """Platform-specific SfpUtil class""" @@ -30,84 +31,84 @@ class SfpUtil(SfpUtilBase): _port_to_eeprom_mapping = {} _cpld_mapping = { - 0: "3-0060", - 1: "3-0061", - 2: "3-0062", - } + 0: "3-0060", + 1: "3-0061", + 2: "3-0062", + } _port_to_i2c_mapping = { - 1: 42, - 2: 43, - 3: 44, - 4: 45, - 5: 46, - 6: 47, - 7: 48, - 8: 49, - 9: 50, - 10: 51, - 11: 52, - 12: 53, - 13: 54, - 14: 55, - 15: 56, - 16: 57, - 17: 58, - 18: 59, - 19: 60, - 20: 61, - 21: 62, - 22: 63, - 23: 64, - 24: 65, - 25: 66, - 26: 67, - 27: 68, - 28: 69, - 29: 70, - 30: 71, - 31: 72, - 32: 73, - 33: 74, - 34: 75, - 35: 76, - 36: 77, - 37: 78, - 38: 79, - 39: 80, - 40: 81, - 41: 82, - 42: 83, - 43: 84, - 44: 85, - 45: 86, - 46: 87, - 47: 88, - 48: 89, - 49: 28, #QSFP49 - 50: 28, - 51: 28, - 52: 28, - 53: 29, #QSFP50 - 54: 29, - 55: 29, - 56: 29, - 57: 26, #QSFP51 - 58: 26, - 59: 26, - 60: 26, - 61: 30, #QSFP52 - 62: 30, - 63: 30, - 64: 30, - 65: 31, #QSFP53 - 66: 31, - 67: 31, - 68: 31, - 69: 27, #QSFP54 - 70: 27, - 71: 27, - 72: 27, - } + 1: 42, + 2: 43, + 3: 44, + 4: 45, + 5: 46, + 6: 47, + 7: 48, + 8: 49, + 9: 50, + 10: 51, + 11: 52, + 12: 53, + 13: 54, + 14: 55, + 15: 56, + 16: 57, + 17: 58, + 18: 59, + 19: 60, + 20: 61, + 21: 62, + 22: 63, + 23: 64, + 24: 65, + 25: 66, + 26: 67, + 27: 68, + 28: 69, + 29: 70, + 30: 71, + 31: 72, + 32: 73, + 33: 74, + 34: 75, + 35: 76, + 36: 77, + 37: 78, + 38: 79, + 39: 80, + 40: 81, + 41: 82, + 42: 83, + 43: 84, + 44: 85, + 45: 86, + 46: 87, + 47: 88, + 48: 89, + 49: 28, # QSFP49 + 50: 28, + 51: 28, + 52: 28, + 53: 29, # QSFP50 + 54: 29, + 55: 29, + 56: 29, + 57: 26, # QSFP51 + 58: 26, + 59: 26, + 60: 26, + 61: 30, # QSFP52 + 62: 30, + 63: 30, + 64: 30, + 65: 31, # QSFP53 + 66: 31, + 67: 31, + 68: 31, + 69: 27, # QSFP54 + 70: 27, + 71: 27, + 72: 27, + } @property def port_start(self): @@ -124,10 +125,10 @@ def qsfp_port_start(self): @property def qsfp_port_end(self): return self.QSFP_PORT_END - + @property def qsfp_ports(self): - return range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1) + return list(range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -141,9 +142,9 @@ def __init__(self): SfpUtilBase.__init__(self) - # For port 49~54 are QSFP, here presumed they're all split to 4 lanes. - def get_cage_num(self, port_num): + + def get_cage_num(self, port_num): cage_num = port_num if (port_num >= self.QSFP_PORT_START): cage_num = (port_num - self.QSFP_PORT_START)/4 @@ -152,14 +153,14 @@ def get_cage_num(self, port_num): return cage_num # For cage 1~38 are at cpld2, others are at cpld3. - def get_cpld_num(self, port_num): + def get_cpld_num(self, port_num): return 1 if (port_num < 39) else 2 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 - + cage_num = self.get_cage_num(port_num) cpld_i = self.get_cpld_num(port_num) @@ -173,15 +174,15 @@ def get_presence(self, port_num): content = val_file.readline().rstrip() val_file.close() except IOError as e: - print "Error: unable to access file: %s" % str(e) + print("Error: unable to access file: %s" % str(e)) return False - + if content == "1": return True return False - def get_low_power_mode_cpld(self, port_num): + def get_low_power_mode_cpld(self, port_num): if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: return False @@ -191,25 +192,25 @@ def get_low_power_mode_cpld(self, port_num): cpld_ps = self._cpld_mapping[cpld_i] path = "/sys/bus/i2c/devices/{0}/module_lpmode_{1}" lp_mode_path = path.format(cpld_ps, cage_num) - + try: val_file = open(lp_mode_path) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = val_file.readline().rstrip() val_file.close() - + if content == "1": return True return False - def get_low_power_mode(self, port_num): + def get_low_power_mode(self, port_num): if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: return False - + if not self.get_presence(port_num): return False @@ -220,15 +221,15 @@ def get_low_power_mode(self, port_num): eeprom.seek(93) lpmode = ord(eeprom.read(1)) - if not (lpmode & 0x1): # 'Power override' bit is 0 + if not (lpmode & 0x1): # 'Power override' bit is 0 return self.get_low_power_mode_cpld(port_num) else: if ((lpmode & 0x2) == 0x2): - return True # Low Power Mode if "Power set" bit is 1 + return True # Low Power Mode if "Power set" bit is 1 else: - return False # High Power Mode if "Power set" bit is 0 + return False # High Power Mode if "Power set" bit is 0 except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False finally: if eeprom is not None: @@ -237,16 +238,16 @@ def get_low_power_mode(self, port_num): def set_low_power_mode(self, port_num, lpmode): if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: - return False + return False try: eeprom = None if not self.get_presence(port_num): - return False # Port is not present, unable to set the eeprom + return False # Port is not present, unable to set the eeprom # Fill in write buffer - regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode + regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode buffer = create_string_buffer(1) buffer[0] = chr(regval) @@ -256,7 +257,7 @@ def set_low_power_mode(self, port_num, lpmode): eeprom.write(buffer[0]) return True except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False finally: if eeprom is not None: @@ -266,7 +267,7 @@ def set_low_power_mode(self, port_num, lpmode): def reset(self, port_num): if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: return False - + cage_num = self.get_cage_num(port_num) cpld_i = self.get_cpld_num(port_num) cpld_ps = self._cpld_mapping[cpld_i] @@ -275,17 +276,17 @@ def reset(self, port_num): try: reg_file = open(port_ps, mode='w', buffering=0) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False - #toggle reset + # toggle reset reg_file.seek(0) reg_file.write('0') time.sleep(1) reg_file.seek(0) reg_file.write('1') reg_file.close() - + return True @property @@ -295,36 +296,37 @@ def _get_presence_bitmap(self): nodes.append("/sys/bus/i2c/devices/3-0062/module_present_all") bitmap = "" - for node in nodes: + for node in nodes: try: reg_file = open(node) - + except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False bitmap += reg_file.readline().rstrip() + " " reg_file.close() rev = bitmap.split(" ") - rev.pop() # Remove the last useless character - + rev.pop() # Remove the last useless character + # Convert bitmap into continuously port order - rev[4] = hex((int(rev[4],16) | ((int(rev[5],16) & 0x3) << 6)))[2:] # Port 33-40 - rev[5] = hex((int(rev[5],16) >> 2) | ((int(rev[6],16) & 0x3) << 6))[2:] # Port 41-48 + rev[4] = hex((int(rev[4], 16) | ((int(rev[5], 16) & 0x3) << 6)))[2:] # Port 33-40 + rev[5] = hex((int(rev[5], 16) >> 2) | ((int(rev[6], 16) & 0x3) << 6))[2:] # Port 41-48 # Expand port 49-54 tmp = rev.pop() - for i in range (2, 8): - val = (int(tmp,16) >> i) & 0x1 + for i in range(2, 8): + val = (int(tmp, 16) >> i) & 0x1 rev.append(hex(val)[2:]) - - for i in range (0,6): + + for i in range(0, 6): rev[i] = rev[i].zfill(2) rev = "".join(rev[::-1]) - return int(rev,16) + return int(rev, 16) + + data = {'valid': 0, 'present': 0} - data = {'valid':0, 'present':0} def get_transceiver_change_event(self, timeout=0): start_time = time.time() @@ -335,17 +337,17 @@ def get_transceiver_change_event(self, timeout=0): if timeout == 0: blocking = True elif timeout > 0: - timeout = timeout / float(1000) # Convert to secs + timeout = timeout / float(1000) # Convert to secs else: - print "get_transceiver_change_event:Invalid timeout value", timeout + print("get_transceiver_change_event:Invalid timeout value", timeout) return False, {} end_time = start_time + timeout if start_time > end_time: - print 'get_transceiver_change_event:' \ - 'time wrap / invalid timeout value', timeout + print('get_transceiver_change_event:' + 'time wrap / invalid timeout value', timeout) - return False, {} # Time wrap or possibly incorrect timeout + return False, {} # Time wrap or possibly incorrect timeout while timeout >= 0: # Check for OIR events and return updated port_dict @@ -353,7 +355,7 @@ def get_transceiver_change_event(self, timeout=0): reg_value = self._get_presence_bitmap changed_ports = self.data['present'] ^ reg_value if changed_ports: - for port in range (self.port_start, self.port_end+1): + for port in range(self.port_start, self.port_end+1): # Mask off the bit corresponding to our port mask = (1 << (port - 1)) if changed_ports & mask: @@ -363,7 +365,7 @@ def get_transceiver_change_event(self, timeout=0): else: port_dict[port] = SFP_STATUS_INSERTED - # Update cache + # Update cache self.data['present'] = reg_value self.data['valid'] = 1 return True, port_dict @@ -373,12 +375,10 @@ def get_transceiver_change_event(self, timeout=0): else: timeout = end_time - time.time() if timeout >= 1: - time.sleep(1) # We poll at 1 second granularity + time.sleep(1) # We poll at 1 second granularity else: if timeout > 0: time.sleep(timeout) return True, {} - print "get_transceiver_change_event: Should not reach here." + print("get_transceiver_change_event: Should not reach here.") return False, {} - - diff --git a/device/accton/x86_64-accton_as5835_54x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as5835_54x-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as5835_54x-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as5835_54x-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as6712_32x-r0/Accton-AS6712-32X/port_config.ini b/device/accton/x86_64-accton_as6712_32x-r0/Accton-AS6712-32X/port_config.ini index 36067bddc1d0..5ad503c619df 100755 --- a/device/accton/x86_64-accton_as6712_32x-r0/Accton-AS6712-32X/port_config.ini +++ b/device/accton/x86_64-accton_as6712_32x-r0/Accton-AS6712-32X/port_config.ini @@ -1,33 +1,33 @@ # name lanes alias index speed -Ethernet0 49,50,51,52 fortyGigE1 1 40000 -Ethernet4 53,54,55,56 fortyGigE2 2 40000 -Ethernet8 57,58,59,60 fortyGigE3 3 40000 -Ethernet12 61,62,63,64 fortyGigE4 4 40000 -Ethernet16 65,66,67,68 fortyGigE5 5 40000 -Ethernet20 69,70,71,72 fortyGigE6 6 40000 -Ethernet24 73,74,75,76 fortyGigE7 7 40000 -Ethernet28 77,78,79,80 fortyGigE8 8 40000 +Ethernet0 1,2,3,4 fortyGigE1 1 40000 +Ethernet4 5,6,7,8 fortyGigE2 2 40000 +Ethernet8 9,10,11,12 fortyGigE3 3 40000 +Ethernet12 13,14,15,16 fortyGigE4 4 40000 +Ethernet16 17,18,19,20 fortyGigE5 5 40000 +Ethernet20 21,22,23,24 fortyGigE6 6 40000 +Ethernet24 25,26,27,28 fortyGigE7 7 40000 +Ethernet28 29,30,31,32 fortyGigE8 8 40000 Ethernet32 33,34,35,36 fortyGigE9 9 40000 Ethernet36 37,38,39,40 fortyGigE10 10 40000 Ethernet40 41,42,43,44 fortyGigE11 11 40000 Ethernet44 45,46,47,48 fortyGigE12 12 40000 -Ethernet48 81,82,83,84 fortyGigE13 13 40000 -Ethernet52 85,86,87,88 fortyGigE14 14 40000 -Ethernet56 89,90,91,92 fortyGigE15 15 40000 -Ethernet60 93,94,95,96 fortyGigE16 16 40000 -Ethernet64 97,98,99,100 fortyGigE17 17 40000 -Ethernet68 101,102,103,104 fortyGigE18 18 40000 -Ethernet72 105,106,107,108 fortyGigE19 19 40000 -Ethernet76 109,110,111,112 fortyGigE20 20 40000 -Ethernet80 17,18,19,20 fortyGigE21 21 40000 -Ethernet84 21,22,23,24 fortyGigE22 22 40000 -Ethernet88 25,26,27,28 fortyGigE23 23 40000 -Ethernet92 29,30,31,32 fortyGigE24 24 40000 -Ethernet96 113,114,115,116 fortyGigE25 25 40000 -Ethernet100 117,118,119,120 fortyGigE26 26 40000 -Ethernet104 121,122,123,124 fortyGigE27 27 40000 -Ethernet108 125,126,127,128 fortyGigE28 28 40000 -Ethernet112 1,2,3,4 fortyGigE29 29 40000 -Ethernet116 5,6,7,8 fortyGigE30 30 40000 -Ethernet120 9,10,11,12 fortyGigE31 31 40000 -Ethernet124 13,14,15,16 fortyGigE32 32 40000 +Ethernet48 49,50,51,52 fortyGigE13 13 40000 +Ethernet52 53,54,55,56 fortyGigE14 14 40000 +Ethernet56 57,58,59,60 fortyGigE15 15 40000 +Ethernet60 61,62,63,64 fortyGigE16 16 40000 +Ethernet64 65,66,67,68 fortyGigE17 17 40000 +Ethernet68 69,70,71,72 fortyGigE18 18 40000 +Ethernet72 73,74,75,76 fortyGigE19 19 40000 +Ethernet76 77,78,79,80 fortyGigE20 20 40000 +Ethernet80 81,82,83,84 fortyGigE21 21 40000 +Ethernet84 85,86,87,88 fortyGigE22 22 40000 +Ethernet88 89,90,91,92 fortyGigE23 23 40000 +Ethernet92 93,94,95,96 fortyGigE24 24 40000 +Ethernet96 97,98,99,100 fortyGigE25 25 40000 +Ethernet100 101,102,103,104 fortyGigE26 26 40000 +Ethernet104 105,106,107,108 fortyGigE27 27 40000 +Ethernet108 109,110,111,112 fortyGigE28 28 40000 +Ethernet112 113,114,115,116 fortyGigE29 29 40000 +Ethernet116 117,118,119,120 fortyGigE30 30 40000 +Ethernet120 121,122,123,124 fortyGigE31 31 40000 +Ethernet124 125,126,127,128 fortyGigE32 32 40000 diff --git a/device/accton/x86_64-accton_as6712_32x-r0/Accton-AS6712-32X/sai.profile b/device/accton/x86_64-accton_as6712_32x-r0/Accton-AS6712-32X/sai.profile index 22432e548b4a..6f2a70f146ca 100644 --- a/device/accton/x86_64-accton_as6712_32x-r0/Accton-AS6712-32X/sai.profile +++ b/device/accton/x86_64-accton_as6712_32x-r0/Accton-AS6712-32X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-as6712-32x40G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as6712_32x-r0/plugins/eeprom.py b/device/accton/x86_64-accton_as6712_32x-r0/plugins/eeprom.py index 7681caafeef4..bf7f2e1f3aec 100644 --- a/device/accton/x86_64-accton_as6712_32x-r0/plugins/eeprom.py +++ b/device/accton/x86_64-accton_as6712_32x-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -10,15 +7,16 @@ 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") +except ImportError as 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/1-0057/eeprom" - #Two i2c buses might get flipped order, check them both. + # Two i2c buses might get flipped order, check them both. if not os.path.exists(self.eeprom_path): self.eeprom_path = "/sys/bus/i2c/devices/0-0057/eeprom" super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/accton/x86_64-accton_as6712_32x-r0/plugins/psuutil.py b/device/accton/x86_64-accton_as6712_32x-r0/plugins/psuutil.py index 191654429e6b..110c836004c8 100644 --- a/device/accton/x86_64-accton_as6712_32x-r0/plugins/psuutil.py +++ b/device/accton/x86_64-accton_as6712_32x-r0/plugins/psuutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Accton # @@ -13,7 +11,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" diff --git a/device/accton/x86_64-accton_as6712_32x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as6712_32x-r0/plugins/sfputil.py index 6889280608fb..28c9010abf56 100644 --- a/device/accton/x86_64-accton_as6712_32x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as6712_32x-r0/plugins/sfputil.py @@ -12,7 +12,7 @@ except ImportError as e: raise ImportError("%s - required module not found" % str(e)) -#from xcvrd +# from xcvrd SFP_STATUS_INSERTED = '1' SFP_STATUS_REMOVED = '0' @@ -36,39 +36,39 @@ class SfpUtil(SfpUtilBase): _port_to_eeprom_mapping = {} _port_to_i2c_mapping = { - 1: [1, 2], - 2: [2, 3], - 3: [3, 4], - 4: [4, 5], - 5: [5, 6], - 6: [6, 7], - 7: [7, 8], - 8: [8, 9], - 9: [9, 10], - 10: [10, 11], - 11: [11, 12], - 12: [12, 13], - 13: [13, 14], - 14: [14, 15], - 15: [15, 16], - 16: [16, 17], - 17: [17, 18], - 18: [18, 19], - 19: [19, 20], - 20: [20, 21], - 21: [21, 22], - 22: [22, 23], - 23: [23, 24], - 24: [24, 25], - 25: [25, 26], - 26: [26, 27], - 27: [27, 28], - 28: [28, 29], - 29: [29, 30], - 30: [30, 31], - 31: [31, 32], - 32: [32, 33], - } + 1: [1, 2], + 2: [2, 3], + 3: [3, 4], + 4: [4, 5], + 5: [5, 6], + 6: [6, 7], + 7: [7, 8], + 8: [8, 9], + 9: [9, 10], + 10: [10, 11], + 11: [11, 12], + 12: [12, 13], + 13: [13, 14], + 14: [14, 15], + 15: [15, 16], + 16: [16, 17], + 17: [17, 18], + 18: [18, 19], + 19: [19, 20], + 20: [20, 21], + 21: [21, 22], + 22: [22, 23], + 23: [23, 24], + 24: [24, 25], + 25: [25, 26], + 26: [26, 27], + 27: [27, 28], + 28: [28, 29], + 29: [29, 30], + 30: [30, 31], + 31: [31, 32], + 32: [32, 33], + } @property def port_start(self): @@ -85,10 +85,10 @@ def qsfp_port_start(self): @property def qsfp_port_end(self): return self.QSFP_PORT_END - + @property def qsfp_ports(self): - return range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1) + return list(range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -100,7 +100,7 @@ def __init__(self): for x in range(self.port_start, self.port_end+1): self.port_to_eeprom_mapping[x] = eeprom_path.format( self._port_to_i2c_mapping[x][1] - ) + ) SfpUtilBase.__init__(self) def get_cpld_dev_path(self, port_num): @@ -108,65 +108,64 @@ def get_cpld_dev_path(self, port_num): cpld_num = 0 else: cpld_num = 1 - - #cpld can be at either bus 0 or bus 1. + + # cpld can be at either bus 0 or bus 1. cpld_path = self.I2C_DEV_PATH + str(0) + self.CPLD_ADDRESS[cpld_num] - if not os.path.exists(cpld_path): + if not os.path.exists(cpld_path): cpld_path = self.I2C_DEV_PATH + str(1) + self.CPLD_ADDRESS[cpld_num] return cpld_path - + 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 - cpld_path = self.get_cpld_dev_path(port_num) - present_path = cpld_path + "/module_present_" + present_path = cpld_path + "/module_present_" present_path += str(self._port_to_i2c_mapping[port_num][0]) self.__port_to_is_present = present_path - content="0" + content = "0" try: val_file = open(self.__port_to_is_present) content = val_file.readline().rstrip() val_file.close() except IOError as e: - print "Error: unable to access file: %s" % str(e) + print("Error: unable to access file: %s" % str(e)) return False - + if content == "1": return True return False - def get_low_power_mode_cpld(self, port_num): + def get_low_power_mode_cpld(self, port_num): if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: return False - + cpld_path = self.get_cpld_dev_path(port_num) - _path = cpld_path + "/module_lp_mode_" + _path = cpld_path + "/module_lp_mode_" _path += str(self._port_to_i2c_mapping[port_num][0]) - content="0" + content = "0" try: reg_file = open(_path) content = reg_file.readline().rstrip() reg_file.close() except IOError as e: - print "Error: unable to access file: %s" % str(e) + print("Error: unable to access file: %s" % str(e)) return False - + if content == "1": return True return False - def get_low_power_mode(self, port_num): + def get_low_power_mode(self, port_num): if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: return False - + if not self.get_presence(port_num): return False @@ -177,15 +176,15 @@ def get_low_power_mode(self, port_num): eeprom.seek(93) lpmode = ord(eeprom.read(1)) - if not (lpmode & 0x1): # 'Power override' bit is 0 + if not (lpmode & 0x1): # 'Power override' bit is 0 return self.get_low_power_mode_cpld(port_num) else: if ((lpmode & 0x2) == 0x2): - return True # Low Power Mode if "Power set" bit is 1 + return True # Low Power Mode if "Power set" bit is 1 else: - return False # High Power Mode if "Power set" bit is 0 + return False # High Power Mode if "Power set" bit is 0 except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False finally: if eeprom is not None: @@ -194,16 +193,16 @@ def get_low_power_mode(self, port_num): def set_low_power_mode(self, port_num, lpmode): if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: - return False + return False try: eeprom = None if not self.get_presence(port_num): - return False # Port is not present, unable to set the eeprom + return False # Port is not present, unable to set the eeprom # Fill in write buffer - regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode + regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode buffer = create_string_buffer(1) buffer[0] = chr(regval) @@ -213,7 +212,7 @@ def set_low_power_mode(self, port_num, lpmode): eeprom.write(buffer[0]) return True except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False finally: if eeprom is not None: @@ -223,15 +222,15 @@ def set_low_power_mode(self, port_num, lpmode): def reset(self, port_num): if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: return False - + cpld_path = self.get_cpld_dev_path(port_num) - _path = cpld_path + "/module_reset_" + _path = cpld_path + "/module_reset_" _path += str(self._port_to_i2c_mapping[port_num][0]) try: reg_file = open(_path, 'w') except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_file.seek(0) @@ -240,7 +239,7 @@ def reset(self, port_num): reg_file.seek(0) reg_file.write('0') reg_file.close() - + return True @property @@ -258,17 +257,17 @@ def get_transceiver_status(self): reg_file = open(node) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False bitmap += reg_file.readline().rstrip() + " " reg_file.close() rev = bitmap.split(" ") rev = "".join(rev[::-1]) - return int(rev,16) + return int(rev, 16) + data = {'valid': 0, 'last': 0, 'present': 0} - data = {'valid':0, 'last':0, 'present':0} def get_transceiver_change_event(self, timeout=2000): now = time.time() port_dict = {} @@ -276,8 +275,7 @@ def get_transceiver_change_event(self, timeout=2000): if timeout < 1000: timeout = 1000 - timeout = (timeout) / float(1000) # Convert to secs - + timeout = (timeout) / float(1000) # Convert to secs if now < (self.data['last'] + timeout) and self.data['valid']: return True, {} @@ -285,7 +283,7 @@ def get_transceiver_change_event(self, timeout=2000): reg_value = self.get_transceiver_status changed_ports = self.data['present'] ^ reg_value if changed_ports: - for port in range (self.port_start, self.port_end+1): + for port in range(self.port_start, self.port_end+1): # Mask off the bit corresponding to our port fp_port = self._port_to_i2c_mapping[port][0] mask = (1 << (fp_port - 1)) @@ -305,5 +303,3 @@ def get_transceiver_change_event(self, timeout=2000): else: return True, {} return False, {} - - diff --git a/device/accton/x86_64-accton_as6712_32x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as6712_32x-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as6712_32x-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as6712_32x-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as7116_54x-r0/plugins/eeprom.py b/device/accton/x86_64-accton_as7116_54x-r0/plugins/eeprom.py index 1e7d1046d93d..4241483d68eb 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/plugins/eeprom.py +++ b/device/accton/x86_64-accton_as7116_54x-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -11,11 +8,13 @@ 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") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + class board(eeprom_tlvinfo.TlvInfoDecoder): _TLV_INFO_MAX_LEN = 256 + def __init__(self, name, path, cpld_root, ro): self.eeprom_path = "/sys/bus/i2c/devices/0-0056/eeprom" super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/accton/x86_64-accton_as7116_54x-r0/plugins/psuutil.py b/device/accton/x86_64-accton_as7116_54x-r0/plugins/psuutil.py index 08fd2648f314..40e7257a6f02 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/plugins/psuutil.py +++ b/device/accton/x86_64-accton_as7116_54x-r0/plugins/psuutil.py @@ -20,12 +20,12 @@ class PsuUtil(PsuBase): def __init__(self): PsuBase.__init__(self) - - + # Get sysfs attribute + def get_attr_value(self, attr_path): - - retval = 'ERR' + + retval = 'ERR' if (not os.path.isfile(attr_path)): return retval @@ -55,16 +55,16 @@ def get_psu_status(self, index): faulty """ status = 0 - attr_file = 'psu_power_good' - attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file - + 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 + status = 1 return status @@ -77,16 +77,15 @@ def get_psu_presence(self, index): """ status = 0 psu_absent = 0 - attr_file ='psu_present' - attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file - + 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 + status = 1 return status - diff --git a/device/accton/x86_64-accton_as7116_54x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7116_54x-r0/plugins/sfputil.py index 3562043ad9fc..9f678757f2a8 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7116_54x-r0/plugins/sfputil.py @@ -1,14 +1,13 @@ -#!/usr/bin/env python - try: import time - from sonic_sfp.sfputilbase import SfpUtilBase -except ImportError, e: - raise ImportError (str(e) + "- required module not found") + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") SFP_STATUS_INSERTED = '1' SFP_STATUS_REMOVED = '0' + class SfpUtil(SfpUtilBase): """Platform specific SfpUtill class""" @@ -19,63 +18,63 @@ class SfpUtil(SfpUtilBase): _port_to_eeprom_mapping = {} _port_to_i2c_mapping = { - 0 : 37, - 1 : 38, - 2 : 39, - 3 : 40, - 4 : 41, - 5 : 42, - 6 : 43, - 7 : 44, - 8 : 45, - 9 : 46, - 10 : 47, - 11 : 48, - 12 : 49, - 13 : 50, - 14 : 51, - 15 : 52, - 16 : 53, - 17 : 54, - 18 : 55, - 19 : 56, - 20 : 57, - 21 : 58, - 22 : 59, - 23 : 60, - 24 : 61, - 25 : 62, - 26 : 63, - 27 : 64, - 28 : 65, - 29 : 66, - 30 : 67, - 31 : 68, - 32 : 69, - 33 : 70, - 34 : 71, - 35 : 72, - 36 : 73, - 37 : 74, - 38 : 75, - 39 : 76, - 40 : 77, - 41 : 78, - 42 : 79, - 43 : 80, - 44 : 81, - 45 : 82, - 46 : 83, - 47 : 84, - 48 : 21, - 49 : 22, - 50 : 23, - 51 : 24, - 52 : 25, - 53 : 26, + 0: 37, + 1: 38, + 2: 39, + 3: 40, + 4: 41, + 5: 42, + 6: 43, + 7: 44, + 8: 45, + 9: 46, + 10: 47, + 11: 48, + 12: 49, + 13: 50, + 14: 51, + 15: 52, + 16: 53, + 17: 54, + 18: 55, + 19: 56, + 20: 57, + 21: 58, + 22: 59, + 23: 60, + 24: 61, + 25: 62, + 26: 63, + 27: 64, + 28: 65, + 29: 66, + 30: 67, + 31: 68, + 32: 69, + 33: 70, + 34: 71, + 35: 72, + 36: 73, + 37: 74, + 38: 75, + 39: 76, + 40: 77, + 41: 78, + 42: 79, + 43: 80, + 44: 81, + 45: 82, + 46: 83, + 47: 84, + 48: 21, + 49: 22, + 50: 23, + 51: 24, + 52: 25, + 53: 26, } - _qsfp_ports = range(_qsfp_port_start, _ports_in_block + 1) + _qsfp_ports = list(range(_qsfp_port_start, _ports_in_block + 1)) _present_status = dict() @@ -83,27 +82,27 @@ 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._port_to_eeprom_mapping[x] = port_eeprom_path self._present_status[x] = SFP_STATUS_REMOVED - + SfpUtilBase.__init__(self) - + def reset(self, port_num): # Check for invalid port_num if port_num < self._qsfp_port_start or port_num > self._port_end: - print "Error: port %d is not qsfp port" % port_num + print("Error: port %d is not qsfp port" % port_num) 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) + print("Error: unable to open file: %s" % str(e)) return False - #toggle reset + # toggle reset reg_file.seek(0) reg_file.write('1') time.sleep(1) @@ -132,14 +131,14 @@ def get_presence(self, port_num): reg_value = reg_file.readline().rstrip() reg_file.close() except IOError as e: - print "Error: unable to access file: %s" % str(e) + print("Error: unable to access file: %s" % str(e)) return False - + if reg_value == '1': return True return False - + def get_transceiver_change_event(self, timeout=0): raise NotImplementedError @@ -155,19 +154,18 @@ def port_end(self): def qsfp_ports(self): return self._qsfp_ports - @property + @property def port_to_eeprom_mapping(self): - return self._port_to_eeprom_mapping + return self._port_to_eeprom_mapping def get_transceiver_change_event(self, timeout=0): ret_present = dict() for phy_port in range(self._port_start, self._port_end + 1): last_present_status = SFP_STATUS_INSERTED if self.get_presence(phy_port) else SFP_STATUS_REMOVED if self._present_status[phy_port] != last_present_status: - ret_present[phy_port] = last_present_status - self._present_status[phy_port] = last_present_status - + ret_present[phy_port] = last_present_status + self._present_status[phy_port] = last_present_status + time.sleep(2) - - return True, ret_present + return True, ret_present diff --git a/device/accton/x86_64-accton_as7116_54x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7116_54x-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as7116_54x-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/chassis.py b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/chassis.py index 6d5ed915812e..86ae121c6c82 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/chassis.py +++ b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/chassis.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # # Module contains an implementation of SONiC Platform Base API and @@ -14,7 +12,7 @@ import json import syslog from sonic_platform_base.chassis_base import ChassisBase - from sonic_daemon_base.daemon_base import Logger + from sonic_py_common.logger import Logger from sonic_platform.fan import Fan from sonic_platform.psu import Psu from sonic_platform.component import Component @@ -32,7 +30,7 @@ SFP_PORT_START = 0 QSFP_PORT_START = 48 SFP_PORT_END = 47 -QSFP_PORT_END=53 +QSFP_PORT_END = 53 HOST_REBOOT_CAUSE_PATH = "/host/reboot-cause/" PMON_REBOOT_CAUSE_PATH = "/usr/share/sonic/platform/api_files/reboot-cause/" REBOOT_CAUSE_FILE = "reboot-cause.txt" @@ -93,7 +91,7 @@ def get_base_mac(self): """ return self._eeprom.get_mac() - def get_serial_number(self): + def get_serial(self): """ Retrieves the hardware serial number for the chassis Returns: diff --git a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/component.py b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/component.py index c8f109aa4db9..15d8e9e15e9d 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/component.py +++ b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/component.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Component contains an implementation of SONiC Platform Base API and # provides the components firmware management function @@ -18,6 +16,7 @@ BIOS_VERSION_PATH = "/sys/class/dmi/id/bios_version" + class Component(DeviceBase): """Platform-specific Component class""" @@ -31,7 +30,7 @@ def __run_command(self, command): # Run bash command and print output to stdout try: process = subprocess.Popen( - shlex.split(command), stdout=subprocess.PIPE) + shlex.split(command), universal_newlines=True, stdout=subprocess.PIPE) while True: output = process.stdout.readline() if output == '' and process.poll() is not None: diff --git a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/eeprom.py b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/eeprom.py index 714ac8153e0e..9cdd09106331 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/eeprom.py +++ b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Platform and model specific eeprom subclass, inherits from the base class, # and provides the followings: @@ -11,10 +9,14 @@ import glob import os import sys - import imp import re from array import array - from cStringIO import StringIO + + if sys.version_info.major == 3: + from io import StringIO + else: + from cStringIO import StringIO + from sonic_platform_base.sonic_eeprom import eeprom_dts from sonic_platform_base.sonic_eeprom import eeprom_tlvinfo except ImportError as e: diff --git a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/fan.py b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/fan.py index 54878e3e1baa..421e7727ceeb 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/fan.py +++ b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/fan.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # # Module contains an implementation of SONiC Platform Base API and @@ -21,6 +19,7 @@ "FANTRAY-3", "FANTRAY-4", "FANTRAY-5"] FAN_NAME_LIST = ["front", "rear"] + class Fan(FanBase): """Platform-specific Fan class""" @@ -67,7 +66,7 @@ def get_direction(self): """ direction = self.FAN_DIRECTION_EXHAUST fan_direction_file = (FAN_PATH + - self.fan_direction.format(self.fan_tray_index+1)) + self.fan_direction.format(self.fan_tray_index+1)) raw = self.__read_txt_file(fan_direction_file).strip('\r\n') direction = self.FAN_DIRECTION_INTAKE if str( raw).upper() == "1" else self.FAN_DIRECTION_EXHAUST @@ -84,7 +83,7 @@ def get_speed(self): speed = 0 if self.get_presence(): fan_speed_file = (FAN_PATH + - self.fan_speed_rpm.format(self.fan_tray_index+1,FAN_NAME_LIST[self.fan_index])) + self.fan_speed_rpm.format(self.fan_tray_index+1, FAN_NAME_LIST[self.fan_index])) speed = self.__read_txt_file(fan_speed_file).strip('\r\n') return int(speed) @@ -98,9 +97,9 @@ def get_target_speed(self): """ target = 0 if self.get_presence(): - fan_speed_file=(FAN_PATH + - self.fan_speed_rpm.format(self.fan_tray_index+1, FAN_NAME_LIST[self.fan_index])) - target=self.__read_txt_file(fan_speed_file).strip('\r\n') + fan_speed_file = (FAN_PATH + + self.fan_speed_rpm.format(self.fan_tray_index+1, FAN_NAME_LIST[self.fan_index])) + target = self.__read_txt_file(fan_speed_file).strip('\r\n') return target diff --git a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/platform.py b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/platform.py index 44e03cdadbb3..6e1a90132acc 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/platform.py +++ b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/platform.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Module contains an implementation of SONiC Platform Base API and # provides the platform information @@ -12,6 +10,7 @@ except ImportError as e: raise ImportError(str(e) + "- required module not found") + class Platform(PlatformBase): """Platform-specific Platform class""" diff --git a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/psu.py b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/psu.py index b1c8029dced9..f53b7506bb3e 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/psu.py +++ b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/psu.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # psuutil.py # Platform-specific PSU status interface for SONiC @@ -17,6 +15,7 @@ FAN_MAX_RPM = 9600 PSU_NAME_LIST = ["PSU-0", "PSU-1"] + class Psu(PsuBase): """Platform-specific Psu class""" @@ -27,7 +26,6 @@ def __init__(self): self.index = psu_index PsuBase.__init__(self) - def get_fan(self): """ Retrieves object representing the fan module contained in this PSU @@ -73,8 +71,8 @@ def get_presence(self): Returns: bool: True if PSU is present, False if not """ - attr_file ='psu_present' - attr_path = self.SYSFS_PSU_DIR[self.index-1] +'/' + attr_file + attr_file = 'psu_present' + attr_path = self.SYSFS_PSU_DIR[self.index-1] + '/' + attr_file status = 0 try: with open(attr_path, 'r') as psu_prs: @@ -91,11 +89,11 @@ def get_status(self): A boolean value, True if device is operating properly, False if not """ attr_file = 'psu_power_good' - attr_path = self.SYSFS_PSU_DIR[self.index-1] +'/' + attr_file + attr_path = self.SYSFS_PSU_DIR[self.index-1] + '/' + attr_file status = 0 try: - with open(attr_path, 'r') as power_status: - status = int(power_status.read()) + with open(attr_path, 'r') as power_status: + status = int(power_status.read()) except IOError: return False 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..2006561ffef0 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 @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Sfp contains an implementation of SONiC Platform Base API and # provides the sfp device status which are available in the platform @@ -8,7 +6,6 @@ import os import time import subprocess - import sonic_device_util import syslog from ctypes import create_string_buffer from sonic_platform_base.sfp_base import SfpBase @@ -18,7 +15,6 @@ from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper - from sonic_daemon_base.daemon_base import Logger except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -107,6 +103,7 @@ 'Fibre Channel link length/Transmitter Technology', 'Fibre Channel transmission media', 'Fibre Channel Speed') + class Sfp(SfpBase): """Platform-specific Sfp class""" @@ -170,7 +167,7 @@ class Sfp(SfpBase): 52: 25, 53: 26, } - _sfp_port = range(48, PORT_END + 1) + _sfp_port = list(range(48, PORT_END + 1)) RESET_PATH = "/sys/bus/i2c/devices/{}-0050/sfp_port_reset" PRS_PATH = "/sys/bus/i2c/devices/{}-0050/sfp_is_present" @@ -182,7 +179,7 @@ class Sfp(SfpBase): HWSKU = "Accton-AS7116-54X-R0" def __init__(self, sfp_index, sfp_type): - # Init index + # Init index self.index = sfp_index self.port_num = self.index + 1 self.sfp_type = sfp_type @@ -195,7 +192,7 @@ def __init__(self, sfp_index, sfp_type): self.port_to_eeprom_mapping[p_num] = eeprom_path.format( self.port_to_i2c_mapping[p_num]) - self.info_dict_keys = ['type', 'hardwarerev', 'serialnum', 'manufacturename', 'modelname', 'Connector', 'encoding', 'ext_identifier', + self.info_dict_keys = ['type', 'hardware_rev', 'serial', 'manufacturer', 'model', 'connector', 'encoding', 'ext_identifier', 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance', 'vendor_date', 'vendor_oui'] self.dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', 'temperature', 'voltage', @@ -308,11 +305,11 @@ def get_sfp_transceiver_info(self): keys |Value Format |Information ---------------------------|---------------|---------------------------- type |1*255VCHAR |type of SFP - hardwarerev |1*255VCHAR |hardware version of SFP - serialnum |1*255VCHAR |serial number of the SFP - manufacturename |1*255VCHAR |SFP vendor name - modelname |1*255VCHAR |SFP model name - Connector |1*255VCHAR |connector information + hardware_rev |1*255VCHAR |hardware version of SFP + serial |1*255VCHAR |serial number of the SFP + manufacturer |1*255VCHAR |SFP vendor name + model |1*255VCHAR |SFP model name + connector |1*255VCHAR |connector information encoding |1*255VCHAR |encoding information ext_identifier |1*255VCHAR |extend identifier ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance @@ -371,17 +368,17 @@ def get_sfp_transceiver_info(self): if sfp_interface_bulk_data: transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] - transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data[ + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data[ 'data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A' - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A' transceiver_info_dict['vendor_date'] = sfp_vendor_date_data[ 'data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A' @@ -562,11 +559,11 @@ def get_qsfp_transceiver_info(self): keys |Value Format |Information ---------------------------|---------------|---------------------------- type |1*255VCHAR |type of SFP - hardwarerev |1*255VCHAR |hardware version of SFP - serialnum |1*255VCHAR |serial number of the SFP - manufacturename |1*255VCHAR |SFP vendor name - modelname |1*255VCHAR |SFP model name - Connector |1*255VCHAR |connector information + hardware_rev |1*255VCHAR |hardware version of SFP + serial |1*255VCHAR |serial number of the SFP + manufacturer |1*255VCHAR |SFP vendor name + model |1*255VCHAR |SFP model name + connector |1*255VCHAR |connector information encoding |1*255VCHAR |encoding information ext_identifier |1*255VCHAR |extend identifier ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance @@ -625,17 +622,17 @@ def get_qsfp_transceiver_info(self): if sfp_interface_bulk_data: transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] - transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data[ + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data[ 'data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A' - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A' transceiver_info_dict['vendor_date'] = sfp_vendor_date_data[ 'data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A' @@ -701,7 +698,7 @@ def get_qsfp_transceiver_bulk_status(self): qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes( (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( + qspf_dom_capability_data = sfpi_obj.parse_dom_capability( qsfp_dom_capability_raw, 0) else: return None @@ -1111,7 +1108,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): @@ -1121,7 +1118,7 @@ def get_model(self): string: Model/part number of device """ transceiver_dom_info_dict = self.get_transceiver_info() - return transceiver_dom_info_dict.get("modelname", "N/A") + return transceiver_dom_info_dict.get("model", "N/A") def get_serial(self): """ @@ -1130,4 +1127,4 @@ def get_serial(self): string: Serial number of device """ transceiver_dom_info_dict = self.get_transceiver_info() - return transceiver_dom_info_dict.get("serialnum", "N/A") + return transceiver_dom_info_dict.get("serial", "N/A") diff --git a/device/accton/x86_64-accton_as7212_54x-r0/plugins/eeprom.py b/device/accton/x86_64-accton_as7212_54x-r0/plugins/eeprom.py index 7681caafeef4..951384d5e37d 100755 --- a/device/accton/x86_64-accton_as7212_54x-r0/plugins/eeprom.py +++ b/device/accton/x86_64-accton_as7212_54x-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -11,14 +8,16 @@ 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") +except ImportError as 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/1-0057/eeprom" - #Two i2c buses might get flipped order, check them both. + # Two i2c buses might get flipped order, check them both. if not os.path.exists(self.eeprom_path): self.eeprom_path = "/sys/bus/i2c/devices/0-0057/eeprom" super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/accton/x86_64-accton_as7212_54x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7212_54x-r0/plugins/sfputil.py index 92ba72507285..47e1f9350aff 100755 --- a/device/accton/x86_64-accton_as7212_54x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7212_54x-r0/plugins/sfputil.py @@ -1,10 +1,8 @@ -#!/usr/bin/env python - try: import time from sonic_sfp.sfputilbase import SfpUtilBase -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class sfputil(SfpUtilBase): @@ -16,41 +14,41 @@ class sfputil(SfpUtilBase): port_to_eeprom_mapping = {} port_to_i2c_mapping = { - 9 : 18, - 10 : 19, - 11 : 20, - 12 : 21, - 1 : 22, - 2 : 23, - 3 : 24, - 4 : 25, - 6 : 26, - 5 : 27, - 8 : 28, - 7 : 29, - 13 : 30, - 14 : 31, - 15 : 32, - 16 : 33, - 17 : 34, - 18 : 35, - 19 : 36, - 20 : 37, - 25 : 38, - 26 : 39, - 27 : 40, - 28 : 41, - 29 : 42, - 30 : 43, - 31 : 44, - 32 : 45, - 21 : 46, - 22 : 47, - 23 : 48, - 24 : 49, + 9: 18, + 10: 19, + 11: 20, + 12: 21, + 1: 22, + 2: 23, + 3: 24, + 4: 25, + 6: 26, + 5: 27, + 8: 28, + 7: 29, + 13: 30, + 14: 31, + 15: 32, + 16: 33, + 17: 34, + 18: 35, + 19: 36, + 20: 37, + 25: 38, + 26: 39, + 27: 40, + 28: 41, + 29: 42, + 30: 43, + 31: 44, + 32: 45, + 21: 46, + 22: 47, + 23: 48, + 24: 49, } - _qsfp_ports = range(0, ports_in_block + 1) + _qsfp_ports = list(range(0, ports_in_block + 1)) def __init__(self): # Override port_to_eeprom_mapping for class initialization @@ -67,14 +65,14 @@ def reset(self, port_num): path = "/sys/bus/i2c/devices/{0}-0050/sfp_port_reset" port_ps = path.format(self.port_to_i2c_mapping[port_num+1]) - + try: reg_file = open(port_ps, 'w') except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False - #toggle reset + # toggle reset reg_file.seek(0) reg_file.write('1') time.sleep(1) @@ -88,7 +86,7 @@ def set_low_power_mode(self, port_nuM, lpmode): def get_low_power_mode(self, port_num): raise NotImplementedErro - + def get_presence(self, port_num): # Check for invalid port_num if port_num < self._port_start or port_num > self._port_end: @@ -103,9 +101,9 @@ def get_presence(self, port_num): reg_value = reg_file.readline().rstrip() reg_file.close() except IOError as e: - print "Error: unable to access file: %s" % str(e) + print("Error: unable to access file: %s" % str(e)) return False - + if reg_value == '1': return True @@ -118,14 +116,14 @@ def port_start(self): @property def port_end(self): return self._port_end - + @property def qsfp_ports(self): - return range(0, self.ports_in_block + 1) + return list(range(0, self.ports_in_block + 1)) - @property + @property def port_to_eeprom_mapping(self): - return self._port_to_eeprom_mapping + return self._port_to_eeprom_mapping def get_transceiver_change_event(self): """ diff --git a/device/accton/x86_64-accton_as7212_54x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7212_54x-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as7212_54x-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as7212_54x-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as7312_54x-r0/Accton-AS7312-54X/sai.profile b/device/accton/x86_64-accton_as7312_54x-r0/Accton-AS7312-54X/sai.profile index 31aefe2c2905..54cdc34801dd 100644 --- a/device/accton/x86_64-accton_as7312_54x-r0/Accton-AS7312-54X/sai.profile +++ b/device/accton/x86_64-accton_as7312_54x-r0/Accton-AS7312-54X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-as7312-48x25G+6x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as7312_54x-r0/Accton-AS7312-54X/th-as7312-48x25G+6x100G.config.bcm b/device/accton/x86_64-accton_as7312_54x-r0/Accton-AS7312-54X/th-as7312-48x25G+6x100G.config.bcm index eef4d987e8ed..0ac6051b1ad4 100644 --- a/device/accton/x86_64-accton_as7312_54x-r0/Accton-AS7312-54X/th-as7312-48x25G+6x100G.config.bcm +++ b/device/accton/x86_64-accton_as7312_54x-r0/Accton-AS7312-54X/th-as7312-48x25G+6x100G.config.bcm @@ -107,7 +107,7 @@ dport_map_port_122=54 #dport_map_port_66=55 #dport_map_port_100=56 -/* Port Map */ +#/* Port Map */ ## FC10 ## portmap_42=41:25 portmap_43=42:25 diff --git a/device/accton/x86_64-accton_as7312_54x-r0/plugins/eeprom.py b/device/accton/x86_64-accton_as7312_54x-r0/plugins/eeprom.py index 7681caafeef4..951384d5e37d 100644 --- a/device/accton/x86_64-accton_as7312_54x-r0/plugins/eeprom.py +++ b/device/accton/x86_64-accton_as7312_54x-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -11,14 +8,16 @@ 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") +except ImportError as 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/1-0057/eeprom" - #Two i2c buses might get flipped order, check them both. + # Two i2c buses might get flipped order, check them both. if not os.path.exists(self.eeprom_path): self.eeprom_path = "/sys/bus/i2c/devices/0-0057/eeprom" super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/accton/x86_64-accton_as7312_54x-r0/plugins/psuutil.py b/device/accton/x86_64-accton_as7312_54x-r0/plugins/psuutil.py index d73e65bf7981..a47dfcab7e94 100644 --- a/device/accton/x86_64-accton_as7312_54x-r0/plugins/psuutil.py +++ b/device/accton/x86_64-accton_as7312_54x-r0/plugins/psuutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Accton # @@ -13,7 +11,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" diff --git a/device/accton/x86_64-accton_as7312_54x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7312_54x-r0/plugins/sfputil.py index 52b57e210ebb..7255b2d784e1 100644 --- a/device/accton/x86_64-accton_as7312_54x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7312_54x-r0/plugins/sfputil.py @@ -28,66 +28,66 @@ class SfpUtil(SfpUtilBase): _port_to_eeprom_mapping = {} _cpld_mapping = { - 0: "4-0060", - 1: "5-0062", - 2: "6-0064", - } + 0: "4-0060", + 1: "5-0062", + 2: "6-0064", + } _port_to_i2c_mapping = { - 1: 18, - 2: 19, - 3: 20, - 4: 21, - 5: 22, - 6: 23, - 7: 24, - 8: 25, - 9: 26, - 10: 27, - 11: 28, - 12: 29, - 13: 30, - 14: 31, - 15: 32, - 16: 33, - 17: 34, - 18: 35, - 19: 36, - 20: 37, - 21: 38, - 22: 39, - 23: 40, - 24: 41, - 25: 42, - 26: 43, - 27: 44, - 28: 45, - 29: 46, - 30: 47, - 31: 48, - 32: 49, - 33: 50, - 34: 51, - 35: 52, - 36: 53, - 37: 54, - 38: 55, - 39: 56, - 40: 57, - 41: 58, - 42: 59, - 43: 60, - 44: 61, - 45: 62, - 46: 63, - 47: 64, - 48: 65, - 49: 66, #QSFP49 - 50: 67, - 51: 68, - 52: 69, - 53: 70, - 54: 71, #QSFP54 - } + 1: 18, + 2: 19, + 3: 20, + 4: 21, + 5: 22, + 6: 23, + 7: 24, + 8: 25, + 9: 26, + 10: 27, + 11: 28, + 12: 29, + 13: 30, + 14: 31, + 15: 32, + 16: 33, + 17: 34, + 18: 35, + 19: 36, + 20: 37, + 21: 38, + 22: 39, + 23: 40, + 24: 41, + 25: 42, + 26: 43, + 27: 44, + 28: 45, + 29: 46, + 30: 47, + 31: 48, + 32: 49, + 33: 50, + 34: 51, + 35: 52, + 36: 53, + 37: 54, + 38: 55, + 39: 56, + 40: 57, + 41: 58, + 42: 59, + 43: 60, + 44: 61, + 45: 62, + 46: 63, + 47: 64, + 48: 65, + 49: 66, # QSFP49 + 50: 67, + 51: 68, + 52: 69, + 53: 70, + 54: 71, # QSFP54 + } @property def port_start(self): @@ -104,10 +104,10 @@ def qsfp_port_start(self): @property def qsfp_port_end(self): return self.QSFP_PORT_END - + @property def qsfp_ports(self): - return range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1) + return list(range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -121,12 +121,12 @@ def __init__(self): SfpUtilBase.__init__(self) - def get_cpld_num(self, port_num): + def get_cpld_num(self, port_num): cpld_i = 1 if (port_num > 24 and port_num < self.qsfp_port_start): cpld_i = 2 - if (port_num > 52): + if (port_num > 52): cpld_i = 2 return cpld_i @@ -135,7 +135,7 @@ 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 - + cpld_i = self.get_cpld_num(port_num) cpld_ps = self._cpld_mapping[cpld_i] @@ -148,9 +148,9 @@ def get_presence(self, port_num): content = val_file.readline().rstrip() val_file.close() except IOError as e: - print "Error: unable to access file: %s" % str(e) + print("Error: unable to access file: %s" % str(e)) return False - + if content == "1": return True @@ -172,20 +172,21 @@ def get_low_power_mode(self, port_num): lpmode = ord(eeprom.read(1)) if ((lpmode & 0x3) == 0x3): - return True # Low Power Mode if "Power override" bit is 1 and "Power set" bit is 1 + return True # Low Power Mode if "Power override" bit is 1 and "Power set" bit is 1 else: - return False # High Power Mode if one of the following conditions is matched: - # 1. "Power override" bit is 0 - # 2. "Power override" bit is 1 and "Power set" bit is 0 + # High Power Mode if one of the following conditions is matched: + # 1. "Power override" bit is 0 + # 2. "Power override" bit is 1 and "Power set" bit is 0 + return False except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False finally: if eeprom is not None: eeprom.close() time.sleep(0.01) - def set_low_power_mode(self, port_num, lpmode): + 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.qsfp_port_end: return False @@ -194,10 +195,10 @@ def set_low_power_mode(self, port_num, lpmode): eeprom = None if not self.get_presence(port_num): - return False # Port is not present, unable to set the eeprom + return False # Port is not present, unable to set the eeprom # Fill in write buffer - regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode + regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode buffer = create_string_buffer(1) buffer[0] = chr(regval) @@ -207,7 +208,7 @@ def set_low_power_mode(self, port_num, lpmode): eeprom.write(buffer[0]) return True except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False finally: if eeprom is not None: @@ -217,7 +218,7 @@ def set_low_power_mode(self, port_num, lpmode): def reset(self, port_num): if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: return False - + cpld_i = self.get_cpld_num(port_num) cpld_ps = self._cpld_mapping[cpld_i] path = "/sys/bus/i2c/devices/{0}/module_reset_{1}" @@ -225,14 +226,14 @@ def reset(self, port_num): try: reg_file = open(port_ps, 'w') except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = '0' reg_file.write(reg_value) reg_file.close() - + return True def get_transceiver_change_event(self): diff --git a/device/accton/x86_64-accton_as7312_54x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7312_54x-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as7312_54x-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as7312_54x-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as7312_54x-r0/sonic_platform/__init__.py b/device/accton/x86_64-accton_as7312_54x-r0/sonic_platform/__init__.py new file mode 100644 index 000000000000..43435472a423 --- /dev/null +++ b/device/accton/x86_64-accton_as7312_54x-r0/sonic_platform/__init__.py @@ -0,0 +1,2 @@ +__all__ = ['chassis', 'eeprom', 'platform', 'psu', 'sfp', 'thermal', 'fan'] +from . import platform diff --git a/device/accton/x86_64-accton_as7312_54x-r0/sonic_platform/chassis.py b/device/accton/x86_64-accton_as7312_54x-r0/sonic_platform/chassis.py new file mode 100644 index 000000000000..ceece0f9db83 --- /dev/null +++ b/device/accton/x86_64-accton_as7312_54x-r0/sonic_platform/chassis.py @@ -0,0 +1,193 @@ +############################################################################# +# Edgecore +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Chassis information which are available in the platform +# +############################################################################# + +import os + +try: + from sonic_platform_base.chassis_base import ChassisBase + from .helper import APIHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +NUM_FAN_TRAY = 6 +NUM_FAN = 2 +NUM_PSU = 2 +NUM_THERMAL = 4 +PORT_END = 54 +NUM_COMPONENT = 4 +HOST_REBOOT_CAUSE_PATH = "/host/reboot-cause/" +PMON_REBOOT_CAUSE_PATH = "/usr/share/sonic/platform/api_files/reboot-cause/" +REBOOT_CAUSE_FILE = "reboot-cause.txt" +PREV_REBOOT_CAUSE_FILE = "previous-reboot-cause.txt" +HOST_CHK_CMD = "docker > /dev/null 2>&1" + + +class Chassis(ChassisBase): + """Platform-specific Chassis class""" + + def __init__(self): + ChassisBase.__init__(self) + self._api_helper = APIHelper() + self._api_helper = APIHelper() + self.is_host = self._api_helper.is_host() + + self.config_data = {} + + self.__initialize_fan() + self.__initialize_psu() + self.__initialize_thermals() + self.__initialize_components() + self.__initialize_sfp() + self.__initialize_eeprom() + + def __initialize_sfp(self): + from sonic_platform.sfp import Sfp + for index in range(0, PORT_END): + sfp = Sfp(index) + self._sfp_list.append(sfp) + self.sfp_module_initialized = True + + def __initialize_fan(self): + from sonic_platform.fan import Fan + for fant_index in range(0, NUM_FAN_TRAY): + for fan_index in range(0, NUM_FAN): + fan = Fan(fant_index, fan_index) + self._fan_list.append(fan) + + def __initialize_psu(self): + from sonic_platform.psu import Psu + for index in range(0, NUM_PSU): + psu = Psu(index) + self._psu_list.append(psu) + + def __initialize_thermals(self): + from sonic_platform.thermal import Thermal + for index in range(0, NUM_THERMAL): + thermal = Thermal(index) + self._thermal_list.append(thermal) + + def __initialize_eeprom(self): + from sonic_platform.eeprom import Tlv + self._eeprom = Tlv() + + def __initialize_components(self): + from sonic_platform.component import Component + for index in range(0, NUM_COMPONENT): + component = Component(index) + self._component_list.append(component) + + def __initialize_watchdog(self): + from sonic_platform.watchdog import Watchdog + self._watchdog = Watchdog() + + + def __is_host(self): + return os.system(HOST_CHK_CMD) == 0 + + def __read_txt_file(self, file_path): + try: + with open(file_path, 'r') as fd: + data = fd.read() + return data.strip() + except IOError: + pass + return None + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + + return self._api_helper.hwsku + + def get_presence(self): + """ + Retrieves the presence of the Chassis + Returns: + bool: True if Chassis is present, False if not + """ + return True + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return True + + def get_base_mac(self): + """ + Retrieves the base MAC address for the chassis + Returns: + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' + """ + return self._eeprom.get_mac() + + def get_serial_number(self): + """ + Retrieves the hardware serial number for the chassis + Returns: + A string containing the hardware serial number for this chassis. + """ + return self._eeprom.get_serial() + + def get_system_eeprom_info(self): + """ + Retrieves the full content of system EEPROM information for the chassis + Returns: + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their corresponding + values. + """ + return self._eeprom.get_eeprom() + + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + + Returns: + A tuple (string, string) where the first element is a string + containing the cause of the previous reboot. This string must be + one of the predefined strings in this class. If the first string + is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used + to pass a description of the reboot cause. + """ + + reboot_cause_path = (HOST_REBOOT_CAUSE_PATH + REBOOT_CAUSE_FILE) + sw_reboot_cause = self._api_helper.read_txt_file( + reboot_cause_path) or "Unknown" + + + return ('REBOOT_CAUSE_NON_HARDWARE', sw_reboot_cause) + + 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, 1 for Ethernet0, 2 for Ethernet4 and so on. + Returns: + An object dervied from SfpBase representing the specified sfp + """ + sfp = None + if not self.sfp_module_initialized: + self.__initialize_sfp() + + try: + # The index will start from 1 + sfp = self._sfp_list[index-1] + except IndexError: + sys.stderr.write("SFP index {} out of range (1-{})\n".format( + index, len(self._sfp_list))) + return sfp diff --git a/device/accton/x86_64-accton_as7312_54x-r0/sonic_platform/component.py b/device/accton/x86_64-accton_as7312_54x-r0/sonic_platform/component.py new file mode 100644 index 000000000000..5300e1e73233 --- /dev/null +++ b/device/accton/x86_64-accton_as7312_54x-r0/sonic_platform/component.py @@ -0,0 +1,125 @@ +############################################################################# +# Celestica +# +# Component contains an implementation of SONiC Platform Base API and +# provides the components firmware management function +# +############################################################################# + +import shlex +import subprocess + +try: + from sonic_platform_base.component_base import ComponentBase + from .helper import APIHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +CPLD_ADDR_MAPPING = { + "CPLD1": "4-0060", + "CPLD2": "5-0062", + "CPLD3": "6-0064", +} +SYSFS_PATH = "/sys/bus/i2c/devices/" +BIOS_VERSION_PATH = "/sys/class/dmi/id/bios_version" +COMPONENT_LIST= [ + ("CPLD1", "CPLD 1"), + ("CPLD2", "CPLD 2"), + ("CPLD3", "CPLD 3"), + ("BIOS", "Basic Input/Output System") + +] +COMPONENT_DES_LIST = ["CPLD","Basic Input/Output System"] + + +class Component(ComponentBase): + """Platform-specific Component class""" + + DEVICE_TYPE = "component" + + def __init__(self, component_index=0): + self._api_helper=APIHelper() + ComponentBase.__init__(self) + self.index = component_index + self.name = self.get_name() + + def __run_command(self, command): + # Run bash command and print output to stdout + try: + process = subprocess.Popen( + shlex.split(command), stdout=subprocess.PIPE) + while True: + output = process.stdout.readline() + if output == '' and process.poll() is not None: + break + rc = process.poll() + if rc != 0: + return False + except Exception: + return False + return True + + def __get_bios_version(self): + # Retrieves the BIOS firmware version + try: + with open(BIOS_VERSION_PATH, 'r') as fd: + bios_version = fd.read() + return bios_version.strip() + except Exception as e: + return None + + def __get_cpld_version(self): + # Retrieves the CPLD firmware version + cpld_version = dict() + for cpld_name in CPLD_ADDR_MAPPING: + try: + cpld_path = "{}{}{}".format(SYSFS_PATH, CPLD_ADDR_MAPPING[cpld_name], '/version') + cpld_version_raw= self._api_helper.read_txt_file(cpld_path) + cpld_version[cpld_name] = "{}".format(int(cpld_version_raw,16)) + except Exception as e: + print('Get exception when read cpld') + cpld_version[cpld_name] = 'None' + + return cpld_version + + def get_name(self): + """ + Retrieves the name of the component + Returns: + A string containing the name of the component + """ + return COMPONENT_LIST[self.index][0] + + def get_description(self): + """ + Retrieves the description of the component + Returns: + A string containing the description of the component + """ + return COMPONENT_LIST[self.index][1] + #return "testhwsku" + + def get_firmware_version(self): + """ + Retrieves the firmware version of module + Returns: + string: The firmware versions of the module + """ + fw_version = None + if self.name == "BIOS": + fw_version = self.__get_bios_version() + elif "CPLD" in self.name: + cpld_version = self.__get_cpld_version() + fw_version = cpld_version.get(self.name) + + return fw_version + + def install_firmware(self, image_path): + """ + Install firmware to module + Args: + image_path: A string, path to firmware image + Returns: + A boolean, True if install successfully, False if not + """ + raise NotImplementedError diff --git a/device/accton/x86_64-accton_as7312_54x-r0/sonic_platform/eeprom.py b/device/accton/x86_64-accton_as7312_54x-r0/sonic_platform/eeprom.py new file mode 100644 index 000000000000..1b2f3f276c3e --- /dev/null +++ b/device/accton/x86_64-accton_as7312_54x-r0/sonic_platform/eeprom.py @@ -0,0 +1,102 @@ +try: + import os + import sys + import re + if sys.version_info[0] >= 3: + from io import StringIO + else: + from cStringIO import StringIO + + from sonic_platform_base.sonic_eeprom import eeprom_tlvinfo +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +CACHE_ROOT = '/var/cache/sonic/decode-syseeprom' +CACHE_FILE = 'syseeprom_cache' + + +class Tlv(eeprom_tlvinfo.TlvInfoDecoder): + + EEPROM_DECODE_HEADLINES = 6 + + def __init__(self): + self._eeprom_path = "/sys/bus/i2c/devices/0-0057/eeprom" + super(Tlv, self).__init__(self._eeprom_path, 0, '', True) + self._eeprom = self._load_eeprom() + + def __parse_output(self, decode_output): + decode_output.replace('\0', '') + lines = decode_output.split('\n') + lines = lines[self.EEPROM_DECODE_HEADLINES:] + _eeprom_info_dict = dict() + + for line in lines: + try: + match = re.search( + '(0x[0-9a-fA-F]{2})([\s]+[\S]+[\s]+)([\S]+)', line) + if match is not None: + idx = match.group(1) + value = match.group(3).rstrip('\0') + + _eeprom_info_dict[idx] = value + except Exception: + pass + + return _eeprom_info_dict + + def _load_eeprom(self): + original_stdout = sys.stdout + sys.stdout = StringIO() + try: + self.read_eeprom_db() + except Exception: + decode_output = sys.stdout.getvalue() + sys.stdout = original_stdout + return self.__parse_output(decode_output) + + status = self.check_status() + if 'ok' not in status: + return False + + if not os.path.exists(CACHE_ROOT): + try: + os.makedirs(CACHE_ROOT) + except Exception: + pass + + # + # only the eeprom classes that inherit from eeprom_base + # support caching. Others will work normally + # + try: + self.set_cache_name(os.path.join(CACHE_ROOT, CACHE_FILE)) + except Exception: + pass + + e = self.read_eeprom() + if e is None: + return 0 + + try: + self.update_cache(e) + except Exception: + pass + + self.decode_eeprom(e) + decode_output = sys.stdout.getvalue() + sys.stdout = original_stdout + + (is_valid, valid_crc) = self.is_checksum_valid(e) + if not is_valid: + return False + + return self.__parse_output(decode_output) + + def get_eeprom(self): + return self._eeprom + + def get_serial(self): + return self._eeprom.get('0x23', "Undefined.") + + def get_mac(self): + return self._eeprom.get('0x24', "Undefined.") diff --git a/device/accton/x86_64-accton_as7312_54x-r0/sonic_platform/fan.py b/device/accton/x86_64-accton_as7312_54x-r0/sonic_platform/fan.py new file mode 100644 index 000000000000..fc072941a3d3 --- /dev/null +++ b/device/accton/x86_64-accton_as7312_54x-r0/sonic_platform/fan.py @@ -0,0 +1,177 @@ +############################################################################# +# Edgecore +# +# Module contains an implementation of SONiC Platform Base API and +# provides the fan status which are available in the platform +# +############################################################################# + + +try: + from sonic_platform_base.fan_base import FanBase + from .helper import APIHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +PSU_FAN_MAX_RPM = 26688 + +CPLD_I2C_PATH = "/sys/bus/i2c/devices/2-0066/fan" +PSU_HWMON_I2C_PATH ="/sys/bus/i2c/devices/{}-00{}/" +PSU_I2C_MAPPING = { + 0: { + "num": 11, + "addr": "5b" + }, + 1: { + "num": 10, + "addr": "58" + }, +} + + +class Fan(FanBase): + """Platform-specific Fan class""" + + def __init__(self, fan_tray_index, fan_index=0, is_psu_fan=False, psu_index=0): + self._api_helper=APIHelper() + self.fan_index = fan_index + self.fan_tray_index = fan_tray_index + self.is_psu_fan = is_psu_fan + if self.is_psu_fan: + self.psu_index = psu_index + self.psu_i2c_num = PSU_I2C_MAPPING[self.psu_index]['num'] + self.psu_i2c_addr = PSU_I2C_MAPPING[self.psu_index]['addr'] + self.psu_hwmon_path = PSU_HWMON_I2C_PATH.format( + self.psu_i2c_num, self.psu_i2c_addr) + + FanBase.__init__(self) + + + def get_direction(self): + """ + Retrieves the direction of fan + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + """ + + + if not self.is_psu_fan: + dir_str = "{}{}{}".format(CPLD_I2C_PATH, self.fan_tray_index, '_direction') + val=self._api_helper.read_txt_file(dir_str) + if val is not None: + if val==0:#F2B + direction=self.FAN_DIRECTION_EXHAUST + else: + direction=self.FAN_DIRECTION_INTAKE + else: + direction=self.FAN_DIRECTION_EXHAUST + + else: #For PSU + dir_str = "{}{}".format(self.psu_hwmon_path,'psu_hwmon_path') + val=self._api_helper.read_txt_file(dir_str) + if val is not None: + if val=='F2B': + direction=self.FAN_DIRECTION_EXHAUST + else: + direction=self.FAN_DIRECTION_INTAKE + else: + direction=self.FAN_DIRECTION_EXHAUST + + return direction + + def get_speed(self): + """ + Retrieves the speed of fan as a percentage of full speed + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + + """ + speed = 0 + if self.is_psu_fan: + psu_fan_path= "{}{}".format(self.psu_hwmon_path, 'psu_fan1_speed_rpm') + fan_speed_rpm = self._api_helper.read_txt_file(psu_fan_path) + if fan_speed_rpm is not None: + speed = (int(fan_speed_rpm,10))*100/26688 + if speed > 100: + speed=100 + else: + return 0 + + elif self.get_presence(): + speed_path = "{}{}".format(CPLD_I2C_PATH, '_duty_cycle_percentage') + speed=self._api_helper.read_txt_file(speed_path) + if speed is None: + return 0 + + return int(speed) + + def get_target_speed(self): + """ + Retrieves the target (expected) speed of the fan + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + + Note: + speed_pc = pwm_target/255*100 + + 0 : when PWM mode is use + pwm : when pwm mode is not use + """ + return False #Not supported + + def get_speed_tolerance(self): + """ + Retrieves the speed tolerance of the fan + Returns: + An integer, the percentage of variance from target speed which is + considered tolerable + """ + return False #Not supported + + def set_speed(self, speed): + """ + Sets the fan speed + Args: + speed: An integer, the percentage of full fan speed to set fan to, + in the range 0 (off) to 100 (full speed) + Returns: + A boolean, True if speed is set successfully, False if not + + """ + + if not self.is_psu_fan and self.get_presence(): + speed_path = "{}{}".format(CPLD_I2C_PATH, '_duty_cycle_percentage') + return self._api_helper.write_txt_file(speed_path, int(speed)) + + return False + + def set_status_led(self, color): + """ + Sets the state of the fan module status LED + Args: + color: A string representing the color with which to set the + fan module status LED + Returns: + bool: True if status LED state is set successfully, False if not + """ + return False #Not supported + + def get_presence(self): + """ + Retrieves the presence of the FAN + Returns: + bool: True if FAN is present, False if not + """ + present_path = "{}{}{}".format(CPLD_I2C_PATH, self.fan_tray_index+1, '_present') + val=self._api_helper.read_txt_file(present_path) + + if not self.is_psu_fan: + if val is not None: + return int(val, 10)==1 + else: + return False + else: + return True diff --git a/device/accton/x86_64-accton_as7312_54x-r0/sonic_platform/helper.py b/device/accton/x86_64-accton_as7312_54x-r0/sonic_platform/helper.py new file mode 100644 index 000000000000..4cd60ac90611 --- /dev/null +++ b/device/accton/x86_64-accton_as7312_54x-r0/sonic_platform/helper.py @@ -0,0 +1,117 @@ +import os +import struct +import subprocess +from mmap import * +from sonic_py_common import device_info + +HOST_CHK_CMD = "docker > /dev/null 2>&1" +EMPTY_STRING = "" + + +class APIHelper(): + + def __init__(self): + (self.platform, self.hwsku) = device_info.get_platform_and_hwsku() + + def is_host(self): + return os.system(HOST_CHK_CMD) == 0 + + def pci_get_value(self, resource, offset): + status = True + result = "" + try: + fd = os.open(resource, os.O_RDWR) + mm = mmap(fd, 0) + mm.seek(int(offset)) + read_data_stream = mm.read(4) + result = struct.unpack('I', read_data_stream) + except Exception: + status = False + return status, result + + def run_command(self, cmd): + status = True + result = "" + try: + p = subprocess.Popen( + cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err == '': + result = raw_data.strip() + except Exception: + status = False + return status, result + + def run_interactive_command(self, cmd): + try: + os.system(cmd) + except Exception: + return False + return True + + def read_txt_file(self, file_path): + try: + with open(file_path, 'r') as fd: + data = fd.read() + return data.strip() + except IOError: + pass + return None + + def write_txt_file(self, file_path, value): + try: + with open(file_path, 'w') as fd: + fd.write(str(value)) + except IOError: + return False + return True + + def ipmi_raw(self, netfn, cmd): + status = True + result = "" + try: + cmd = "ipmitool raw {} {}".format(str(netfn), str(cmd)) + p = subprocess.Popen( + cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err == '': + result = raw_data.strip() + else: + status = False + except Exception: + status = False + return status, result + + def ipmi_fru_id(self, id, key=None): + status = True + result = "" + try: + cmd = "ipmitool fru print {}".format(str( + id)) if not key else "ipmitool fru print {0} | grep '{1}' ".format(str(id), str(key)) + + p = subprocess.Popen( + cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err == '': + result = raw_data.strip() + else: + status = False + except Exception: + status = False + return status, result + + def ipmi_set_ss_thres(self, id, threshold_key, value): + status = True + result = "" + try: + cmd = "ipmitool sensor thresh '{}' {} {}".format(str(id), str(threshold_key), str(value)) + p = subprocess.Popen( + cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err == '': + result = raw_data.strip() + else: + status = False + except Exception: + status = False + return status, result diff --git a/device/accton/x86_64-accton_as7312_54x-r0/sonic_platform/platform.py b/device/accton/x86_64-accton_as7312_54x-r0/sonic_platform/platform.py new file mode 100644 index 000000000000..2f2c2a447fcf --- /dev/null +++ b/device/accton/x86_64-accton_as7312_54x-r0/sonic_platform/platform.py @@ -0,0 +1,21 @@ +############################################################################# +# Edgecore +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PlatformBase): + """Platform-specific Platform class""" + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() diff --git a/device/accton/x86_64-accton_as7312_54x-r0/sonic_platform/psu.py b/device/accton/x86_64-accton_as7312_54x-r0/sonic_platform/psu.py new file mode 100644 index 000000000000..cb715515d50e --- /dev/null +++ b/device/accton/x86_64-accton_as7312_54x-r0/sonic_platform/psu.py @@ -0,0 +1,220 @@ +############################################################################# +# Edgecore +# +# Module contains an implementation of SONiC Platform Base API and +# provides the PSUs status which are available in the platform +# +############################################################################# + +#import sonic_platform + +try: + from sonic_platform_base.psu_base import PsuBase + from .helper import APIHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +I2C_PATH ="/sys/bus/i2c/devices/{0}-00{1}/" + +PSU_NAME_LIST = ["PSU-1", "PSU-2"] +PSU_NUM_FAN = [1, 1] +PSU_HWMON_I2C_MAPPING = { + 0: { + "num": 11, + "addr": "5b" + }, + 1: { + "num": 10, + "addr": "58" + }, +} + +PSU_CPLD_I2C_MAPPING = { + 0: { + "num": 11, + "addr": "53" + }, + 1: { + "num": 10, + "addr": "50" + }, +} + +class Psu(PsuBase): + """Platform-specific Psu class""" + + def __init__(self, psu_index=0): + PsuBase.__init__(self) + self.index = psu_index + self._api_helper = APIHelper() + + self.i2c_num = PSU_HWMON_I2C_MAPPING[self.index]["num"] + self.i2c_addr = PSU_HWMON_I2C_MAPPING[self.index]["addr"] + self.hwmon_path = I2C_PATH.format(self.i2c_num, self.i2c_addr) + + self.i2c_num = PSU_CPLD_I2C_MAPPING[self.index]["num"] + self.i2c_addr = PSU_CPLD_I2C_MAPPING[self.index]["addr"] + self.cpld_path = I2C_PATH.format(self.i2c_num, self.i2c_addr) + self.__initialize_fan() + + def __initialize_fan(self): + from sonic_platform.fan import Fan + for fan_index in range(0, PSU_NUM_FAN[self.index]): + fan = Fan(fan_index, 0, is_psu_fan=True, psu_index=self.index) + self._fan_list.append(fan) + + def get_voltage(self): + """ + Retrieves current PSU voltage output + Returns: + A float number, the output voltage in volts, + e.g. 12.1 + """ + vout_path = "{}{}".format(self.hwmon_path, 'psu_v_out') + vout_val=self._api_helper.read_txt_file(vout_path) + return float(vout_val)/ 1000 + + def get_current(self): + """ + Retrieves present electric current supplied by PSU + Returns: + A float number, the electric current in amperes, e.g 15.4 + """ + iout_path = "{}{}".format(self.hwmon_path, 'psu_i_out') + val=self._api_helper.read_txt_file(iout_path) + if val is not None: + return float(val)/1000 + else: + return 0 + + def get_power(self): + """ + Retrieves current energy supplied by PSU + Returns: + A float number, the power in watts, e.g. 302.6 + """ + pout_path = "{}{}".format(self.hwmon_path, 'psu_p_out') + val=self._api_helper.read_txt_file(pout_path) + if val is not None: + return float(val)/1000 + else: + return 0 + + def get_powergood_status(self): + """ + Retrieves the powergood status of PSU + Returns: + A boolean, True if PSU has stablized its output voltages and passed all + its internal self-tests, False if not. + """ + return self.get_status() + + def set_status_led(self, color): + """ + Sets the state of the PSU status LED + Args: + color: A string representing the color with which to set the PSU status LED + Note: Only support green and off + Returns: + bool: True if status LED state is set successfully, False if not + """ + + return False #Controlled by HW + + def get_status_led(self): + """ + Gets the state of the PSU status LED + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + + if self.get_status(): + return True + else: + return False + + def get_temperature(self): + """ + Retrieves current temperature reading from PSU + Returns: + A float number of current temperature in Celsius up to nearest thousandth + of one degree Celsius, e.g. 30.125 + """ + temp_path = "{}{}".format(self.hwmon_path, 'psu_temp1_input') + val=self._api_helper.read_txt_file(temp_path) + if val is not None: + return float(val)/1000 + else: + return 0 + + def get_temperature_high_threshold(self): + """ + Retrieves the high threshold temperature of PSU + Returns: + A float number, the high threshold temperature of PSU in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + return False #Not supported + + def get_voltage_high_threshold(self): + """ + Retrieves the high threshold PSU voltage output + Returns: + A float number, the high threshold output voltage in volts, + e.g. 12.1 + """ + vout_path = "{}{}".format(self.hwmon_path, 'psu_mfr_vout_max') + vout_val=self._api_helper.read_txt_file(vout_path) + if vout_val is not None: + return float(vout_val)/ 1000 + else: + return 0 + + def get_voltage_low_threshold(self): + """ + Retrieves the low threshold PSU voltage output + Returns: + A float number, the low threshold output voltage in volts, + e.g. 12.1 + """ + vout_path = "{}{}".format(self.hwmon_path, 'psu_mfr_vout_min') + vout_val=self._api_helper.read_txt_file(vout_path) + if vout_val is not None: + return float(vout_val)/ 1000 + else: + return 0 + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + return PSU_NAME_LIST[self.index] + + def get_presence(self): + """ + Retrieves the presence of the PSU + Returns: + bool: True if PSU is present, False if not + """ + presence_path="{}{}".format(self.cpld_path, 'psu_present') + val=self._api_helper.read_txt_file(presence_path) + if val is not None: + return int(val, 10) == 1 + else: + return 0 + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + power_path="{}{}".format(self.cpld_path, 'psu_power_good') + val=self._api_helper.read_txt_file(power_path) + if val is not None: + return int(val, 10) == 1 + else: + return 0 diff --git a/device/accton/x86_64-accton_as7312_54x-r0/sonic_platform/sfp.py b/device/accton/x86_64-accton_as7312_54x-r0/sonic_platform/sfp.py new file mode 100644 index 000000000000..b5e38017bc90 --- /dev/null +++ b/device/accton/x86_64-accton_as7312_54x-r0/sonic_platform/sfp.py @@ -0,0 +1,1228 @@ +############################################################################# +# Edgecore +# +# Sfp contains an implementation of SONiC Platform Base API and +# provides the sfp device status which are available in the platform +# +############################################################################# + +import os +import time +import sys + +from ctypes import create_string_buffer + +try: + from sonic_platform_base.sfp_base import SfpBase + from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom + from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom + from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId + #from sonic_platform_base.sonic_sfp.sff8472 import sffbase + from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper + from .helper import APIHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +CPLD_I2C_PATH = "/sys/bus/i2c/devices/" + +QSFP_INFO_OFFSET = 128 +QSFP_DOM_OFFSET = 0 + +SFP_INFO_OFFSET = 0 +SFP_DOM_OFFSET = 256 + +XCVR_INTFACE_BULK_OFFSET = 0 +XCVR_INTFACE_BULK_WIDTH_QSFP = 20 +XCVR_INTFACE_BULK_WIDTH_SFP = 21 +XCVR_HW_REV_WIDTH_QSFP = 2 +XCVR_HW_REV_WIDTH_SFP = 4 +XCVR_CABLE_LENGTH_WIDTH_QSFP = 5 +XCVR_VENDOR_NAME_OFFSET = 20 +XCVR_VENDOR_NAME_WIDTH = 16 +XCVR_VENDOR_OUI_OFFSET = 37 +XCVR_VENDOR_OUI_WIDTH = 3 +XCVR_VENDOR_PN_OFFSET = 40 +XCVR_VENDOR_PN_WIDTH = 16 +XCVR_HW_REV_OFFSET = 56 +XCVR_HW_REV_WIDTH_OSFP = 2 +XCVR_HW_REV_WIDTH_SFP = 4 +XCVR_VENDOR_SN_OFFSET = 68 +XCVR_VENDOR_SN_WIDTH = 16 +XCVR_VENDOR_DATE_OFFSET = 84 +XCVR_VENDOR_DATE_WIDTH = 8 +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 1 + +# Offset for values in QSFP eeprom +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_CONTROL_OFFSET = 86 +QSFP_CONTROL_WIDTH = 8 +QSFP_CHANNL_RX_LOS_STATUS_OFFSET = 3 +QSFP_CHANNL_RX_LOS_STATUS_WIDTH = 1 +QSFP_CHANNL_TX_FAULT_STATUS_OFFSET = 4 +QSFP_CHANNL_TX_FAULT_STATUS_WIDTH = 1 +QSFP_POWEROVERRIDE_OFFSET = 93 +QSFP_POWEROVERRIDE_WIDTH = 1 +QSFP_MODULE_THRESHOLD_OFFSET = 128 +QSFP_MODULE_THRESHOLD_WIDTH = 24 +QSFP_CHANNEL_THRESHOLD_OFFSET = 176 +QSFP_CHANNEL_THRESHOLD_WIDTH = 16 + +qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', + 'Length OM2(m)', 'Length OM1(m)', + 'Length Cable Assembly(m)') + +qsfp_compliance_code_tup = ('10/40G Ethernet Compliance Code', 'SONET Compliance codes', + 'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes', + 'Fibre Channel link length/Transmitter Technology', + 'Fibre Channel transmission media', 'Fibre Channel Speed') + + +# Offset for values in SFP eeprom +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VOLT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_CHANNL_MON_OFFSET = 100 +SFP_CHANNL_MON_WIDTH = 6 +SFP_MODULE_THRESHOLD_OFFSET = 0 +SFP_MODULE_THRESHOLD_WIDTH = 40 +SFP_CHANNL_THRESHOLD_OFFSET = 112 +SFP_CHANNL_THRESHOLD_WIDTH = 2 +SFP_STATUS_CONTROL_OFFSET = 110 +SFP_STATUS_CONTROL_WIDTH = 1 +SFP_TX_DISABLE_HARD_BIT = 7 +SFP_TX_DISABLE_SOFT_BIT = 6 + +sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)', + 'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)', + 'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)') + +sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode', + 'ESCONComplianceCodes', 'SONETComplianceCodes', + 'EthernetComplianceCodes', 'FibreChannelLinkLength', + 'FibreChannelTechnology', 'SFP+CableTechnology', + 'FibreChannelTransmissionMedia', 'FibreChannelSpeed') + + +class Sfp(SfpBase): + """Platform-specific Sfp class""" + + # Port number + PORT_START = 1 + PORT_END = 54 + QSFP_PORT_START = 49 + + # Path to sysfs + PLATFORM_ROOT_PATH = "/usr/share/sonic/device" + PMON_HWSKU_PATH = "/usr/share/sonic/hwsku" + HOST_CHK_CMD = "docker > /dev/null 2>&1" + + PLATFORM = "x86_64-accton_as7312_54x-r0" + HWSKU = "Accton-AS7312-54X" + + _cpld_mapping = { + 0: "4-0060", + 1: "5-0062", + 2: "6-0064", + } + _port_to_i2c_mapping = { + 1: 18, + 2: 19, + 3: 20, + 4: 21, + 5: 22, + 6: 23, + 7: 24, + 8: 25, + 9: 26, + 10: 27, + 11: 28, + 12: 29, + 13: 30, + 14: 31, + 15: 32, + 16: 33, + 17: 34, + 18: 35, + 19: 36, + 20: 37, + 21: 38, + 22: 39, + 23: 40, + 24: 41, + 25: 42, + 26: 43, + 27: 44, + 28: 45, + 29: 46, + 30: 47, + 31: 48, + 32: 49, + 33: 50, + 34: 51, + 35: 52, + 36: 53, + 37: 54, + 38: 55, + 39: 56, + 40: 57, + 41: 58, + 42: 59, + 43: 60, + 44: 61, + 45: 62, + 46: 63, + 47: 64, + 48: 65, + 49: 66, # QSFP49 + 50: 67, + 51: 68, + 52: 69, + 53: 70, + 54: 71, # QSFP54 + } + + + def __init__(self, sfp_index=0): + self._api_helper=APIHelper() + # Init index + self.index = sfp_index + self.port_num = self.index + 1 + + # Init eeprom path + eeprom_path = '/sys/bus/i2c/devices/{0}-0050/eeprom' + self.port_to_eeprom_mapping = {} + for x in range(self.PORT_START, self.PORT_END + 1): + self.port_to_eeprom_mapping[x] = eeprom_path.format(self._port_to_i2c_mapping[x]) + + self.info_dict_keys = ['type', 'hardware_rev', 'serial', 'manufacturer', 'model', 'connector', 'encoding', 'ext_identifier', + 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance', 'vendor_date', 'vendor_oui'] + + self.dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', 'temperature', 'voltage', + 'rx1power', 'rx2power', 'rx3power', 'rx4power', 'tx1bias', 'tx2bias', 'tx3bias', 'tx4bias', 'tx1power', 'tx2power', 'tx3power', 'tx4power'] + + self.threshold_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning', 'vcchighalarm', 'vcchighwarning', 'vcclowalarm', 'vcclowwarning', 'rxpowerhighalarm', 'rxpowerhighwarning', + 'rxpowerlowalarm', 'rxpowerlowwarning', 'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', 'txpowerlowwarning', 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning'] + + SfpBase.__init__(self) + + def __get_cpld_num(self, port_num): + cpld_i = 1 + if (port_num > 24 and port_num < self.QSFP_PORT_START): + cpld_i = 2 + + if (port_num > 52): + cpld_i = 2 + + return cpld_i + + + def _convert_string_to_num(self, value_str): + if "-inf" in value_str: + return 'N/A' + elif "Unknown" in value_str: + return 'N/A' + elif 'dBm' in value_str: + t_str = value_str.rstrip('dBm') + return float(t_str) + elif 'mA' in value_str: + t_str = value_str.rstrip('mA') + return float(t_str) + elif 'C' in value_str: + t_str = value_str.rstrip('C') + return float(t_str) + elif 'Volts' in value_str: + t_str = value_str.rstrip('Volts') + return float(t_str) + else: + return 'N/A' + + def __write_txt_file(self, file_path, value): + try: + with open(file_path, 'w', buffering=0) as fd: + fd.write(str(value)) + except Exception: + return False + return True + + def __is_host(self): + return os.system(self.HOST_CHK_CMD) == 0 + + def __get_path_to_port_config_file(self): + platform_path = "/".join([self.PLATFORM_ROOT_PATH, self.PLATFORM]) + hwsku_path = "/".join([platform_path, self.HWSKU] + ) if self.__is_host() else self.PMON_HWSKU_PATH + return "/".join([hwsku_path, "port_config.ini"]) + + def __read_eeprom_specific_bytes(self, offset, num_bytes): + sysfsfile_eeprom = None + eeprom_raw = [] + + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[self.port_num] + try: + sysfsfile_eeprom = open( + sysfs_sfp_i2c_client_eeprom_path, mode="rb", buffering=0) + sysfsfile_eeprom.seek(offset) + raw = sysfsfile_eeprom.read(num_bytes) + if sys.version_info[0] >= 3: + for n in range(0, num_bytes): + eeprom_raw[n] = hex(raw[n])[2:].zfill(2) + else: + for n in range(0, num_bytes): + eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + except Exception: + pass + finally: + if sysfsfile_eeprom: + sysfsfile_eeprom.close() + + return eeprom_raw + + def get_transceiver_info(self): + """ + Retrieves transceiver info of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + type |1*255VCHAR |type of SFP + hardware_rev |1*255VCHAR |hardware version of SFP + serial |1*255VCHAR |serial number of the SFP + manufacturer |1*255VCHAR |SFP vendor name + model |1*255VCHAR |SFP model name + connector |1*255VCHAR |connector information + encoding |1*255VCHAR |encoding information + ext_identifier |1*255VCHAR |extend identifier + ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance + cable_length |INT |cable length in m + nominal_bit_rate |INT |nominal bit rate by 100Mbs + specification_compliance |1*255VCHAR |specification compliance + vendor_date |1*255VCHAR |vendor date + vendor_oui |1*255VCHAR |vendor OUI + ======================================================================== + """ + # check present status + if self.port_num < 49: + sfpi_obj = sff8472InterfaceId() #SFP + else: + sfpi_obj = sff8436InterfaceId() #QSFP + if not self.get_presence() or not sfpi_obj: + return {} + + if self.port_num < 49: + offset = SFP_INFO_OFFSET + sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_INTFACE_BULK_OFFSET), XCVR_INTFACE_BULK_WIDTH_SFP) + else: + offset = QSFP_INFO_OFFSET + sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_INTFACE_BULK_OFFSET), XCVR_INTFACE_BULK_WIDTH_QSFP) + + sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk( + sfp_interface_bulk_raw, 0) + + sfp_vendor_name_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) + sfp_vendor_name_data = sfpi_obj.parse_vendor_name( + sfp_vendor_name_raw, 0) + + sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn( + sfp_vendor_pn_raw, 0) + + if self.port_num < 49: + sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_HW_REV_OFFSET), XCVR_HW_REV_WIDTH_SFP) + else: + sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_HW_REV_OFFSET), XCVR_HW_REV_WIDTH_QSFP) + + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev( + sfp_vendor_rev_raw, 0) + + sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn( + sfp_vendor_sn_raw, 0) + + sfp_vendor_oui_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH) + if sfp_vendor_oui_raw is not None: + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui( + sfp_vendor_oui_raw, 0) + + sfp_vendor_date_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH) + sfp_vendor_date_data = sfpi_obj.parse_vendor_date( + sfp_vendor_date_raw, 0) + + transceiver_info_dict = dict.fromkeys(self.info_dict_keys, 'N/A') + compliance_code_dict = dict() + + if sfp_interface_bulk_data: + transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] + transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] + transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] + transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] + + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data[ + 'data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A' + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' + transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A' + transceiver_info_dict['vendor_date'] = sfp_vendor_date_data[ + 'data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A' + transceiver_info_dict['cable_type'] = "Unknown" + transceiver_info_dict['cable_length'] = "Unknown" + + if self.port_num < 49: + for key in sfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str( + sfp_interface_bulk_data['data'][key]['value']) + + for key in sfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + + transceiver_info_dict['specification_compliance'] = str( + compliance_code_dict) + transceiver_info_dict['nominal_bit_rate'] = str( + sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) + else: + for key in qsfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str( + sfp_interface_bulk_data['data'][key]['value']) + + for key in qsfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + + transceiver_info_dict['specification_compliance'] = str( + compliance_code_dict) + transceiver_info_dict['nominal_bit_rate'] = str( + sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value']) + + + return transceiver_info_dict + + def get_transceiver_bulk_status(self): + """ + Retrieves transceiver bulk status of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + rx_los |BOOLEAN |RX loss-of-signal status, True if has RX los, False if not. + tx_fault |BOOLEAN |TX fault status, True if has TX fault, False if not. + reset_status |BOOLEAN |reset status, True if SFP in reset, False if not. + lp_mode |BOOLEAN |low power mode status, True in lp mode, False if not. + tx_disable |BOOLEAN |TX disable status, True TX disabled, False if not. + tx_disabled_channel |HEX |disabled TX channels in hex, bits 0 to 3 represent channel 0 + | |to channel 3. + temperature |INT |module temperature in Celsius + voltage |INT |supply voltage in mV + txbias |INT |TX Bias Current in mA, n is the channel number, + | |for example, tx2bias stands for tx bias of channel 2. + rxpower |INT |received optical power in mW, n is the channel number, + | |for example, rx2power stands for rx power of channel 2. + txpower |INT |TX output power in mW, n is the channel number, + | |for example, tx2power stands for tx power of channel 2. + ======================================================================== + """ + # check present status + if self.port_num < 49: #SFP case + sfpd_obj = sff8472Dom() + if not self.get_presence() or not sfpd_obj: + return {} + + eeprom_ifraw = self.__read_eeprom_specific_bytes(0, SFP_DOM_OFFSET) + sfpi_obj = sff8472InterfaceId(eeprom_ifraw) + cal_type = sfpi_obj.get_calibration_type() + sfpd_obj._calibration_type = cal_type + + offset = SFP_DOM_OFFSET + transceiver_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A') + dom_temperature_raw = self.__read_eeprom_specific_bytes( + (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) + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + + dom_voltage_raw = self.__read_eeprom_specific_bytes( + (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) + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_voltage_data = sfpd_obj.parse_channel_monitor_params( + dom_channel_monitor_raw, 0) + transceiver_dom_info_dict['tx1power'] = dom_voltage_data['data']['TXPower']['value'] + transceiver_dom_info_dict['rx1power'] = dom_voltage_data['data']['RXPower']['value'] + transceiver_dom_info_dict['tx1bias'] = dom_voltage_data['data']['TXBias']['value'] + + else: #QSFP case + sfpd_obj = sff8436Dom() + sfpi_obj = sff8436InterfaceId() + + if not self.get_presence() or not sfpi_obj or not sfpd_obj: + return {} + + transceiver_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A') + offset = QSFP_DOM_OFFSET + offset_xcvr = QSFP_INFO_OFFSET + + # 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( + (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_dom_capability( + qsfp_dom_capability_raw, 0) + else: + return None + + dom_temperature_raw = self.__read_eeprom_specific_bytes( + (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) + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + + dom_voltage_raw = self.__read_eeprom_specific_bytes( + (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) + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + + qsfp_dom_rev_raw = self.__read_eeprom_specific_bytes( + (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) + qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['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 = {} + dom_channel_monitor_raw = None + 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( + (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: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (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) + 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'] + + if dom_channel_monitor_raw: + 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'] + #End of else + + + for key in transceiver_dom_info_dict: + transceiver_dom_info_dict[key] = self._convert_string_to_num( + transceiver_dom_info_dict[key]) + + transceiver_dom_info_dict['rx_los'] = self.get_rx_los() + transceiver_dom_info_dict['tx_fault'] = self.get_tx_fault() + transceiver_dom_info_dict['reset_status'] = self.get_reset_status() + transceiver_dom_info_dict['lp_mode'] = self.get_lpmode() + + return transceiver_dom_info_dict + + def get_transceiver_threshold_info(self): + """ + Retrieves transceiver threshold info of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius. + templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius. + temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius. + templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius. + vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV. + vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV. + vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV. + vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV. + rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm. + rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm. + rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm. + rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm. + txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm. + txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm. + txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm. + txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm. + txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA. + txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA. + txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA. + txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA. + ======================================================================== + """ + # check present status + if self.port_num < 49: + sfpd_obj = sff8472Dom() + + if not self.get_presence() and not sfpd_obj: + return {} + + eeprom_ifraw = self.__read_eeprom_specific_bytes(0, SFP_DOM_OFFSET) + sfpi_obj = sff8472InterfaceId(eeprom_ifraw) + cal_type = sfpi_obj.get_calibration_type() + sfpd_obj._calibration_type = cal_type + + offset = SFP_DOM_OFFSET + transceiver_dom_threshold_info_dict = dict.fromkeys( + self.threshold_dict_keys, 'N/A') + dom_module_threshold_raw = self.__read_eeprom_specific_bytes( + (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) + + 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'] + + for key in transceiver_dom_threshold_info_dict: + transceiver_dom_threshold_info_dict[key] = self._convert_string_to_num( + transceiver_dom_threshold_info_dict[key]) + + return transceiver_dom_threshold_info_dict + + + else: + sfpd_obj = sff8436Dom() + + if not self.get_presence() or not sfpd_obj: + return {} + + transceiver_dom_threshold_dict = dict.fromkeys( + self.threshold_dict_keys, 'N/A') + dom_thres_raw = self.__read_eeprom_specific_bytes( + QSFP_MODULE_THRESHOLD_OFFSET, QSFP_MODULE_THRESHOLD_WIDTH) if self.get_presence() and sfpd_obj else None + + if dom_thres_raw: + module_threshold_values = sfpd_obj.parse_module_threshold_values( + dom_thres_raw, 0) + module_threshold_data = module_threshold_values.get('data') + if module_threshold_data: + transceiver_dom_threshold_dict['temphighalarm'] = module_threshold_data['TempHighAlarm']['value'] + transceiver_dom_threshold_dict['templowalarm'] = module_threshold_data['TempLowAlarm']['value'] + transceiver_dom_threshold_dict['temphighwarning'] = module_threshold_data['TempHighWarning']['value'] + transceiver_dom_threshold_dict['templowwarning'] = module_threshold_data['TempLowWarning']['value'] + transceiver_dom_threshold_dict['vcchighalarm'] = module_threshold_data['VccHighAlarm']['value'] + transceiver_dom_threshold_dict['vcclowalarm'] = module_threshold_data['VccLowAlarm']['value'] + transceiver_dom_threshold_dict['vcchighwarning'] = module_threshold_data['VccHighWarning']['value'] + transceiver_dom_threshold_dict['vcclowwarning'] = module_threshold_data['VccLowWarning']['value'] + + dom_thres_raw = self.__read_eeprom_specific_bytes( + QSFP_CHANNEL_THRESHOLD_OFFSET, QSFP_CHANNEL_THRESHOLD_WIDTH) if self.get_presence() and sfpd_obj else None + channel_threshold_values = sfpd_obj.parse_channel_threshold_values( + dom_thres_raw, 0) + channel_threshold_data = channel_threshold_values.get('data') + if channel_threshold_data: + transceiver_dom_threshold_dict['rxpowerhighalarm'] = channel_threshold_data['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerlowalarm'] = channel_threshold_data['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerhighwarning'] = channel_threshold_data['RxPowerHighWarning']['value'] + transceiver_dom_threshold_dict['rxpowerlowwarning'] = channel_threshold_data['RxPowerLowWarning']['value'] + transceiver_dom_threshold_dict['txpowerhighalarm'] = "0.0dBm" + transceiver_dom_threshold_dict['txpowerlowalarm'] = "0.0dBm" + transceiver_dom_threshold_dict['txpowerhighwarning'] = "0.0dBm" + transceiver_dom_threshold_dict['txpowerlowwarning'] = "0.0dBm" + transceiver_dom_threshold_dict['txbiashighalarm'] = channel_threshold_data['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_dict['txbiaslowalarm'] = channel_threshold_data['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_dict['txbiashighwarning'] = channel_threshold_data['TxBiasHighWarning']['value'] + transceiver_dom_threshold_dict['txbiaslowwarning'] = channel_threshold_data['TxBiasLowWarning']['value'] + + for key in transceiver_dom_threshold_dict: + transceiver_dom_threshold_dict[key] = self._convert_string_to_num( + transceiver_dom_threshold_dict[key]) + + return transceiver_dom_threshold_dict + + def get_reset_status(self): + """ + Retrieves the reset status of SFP + Returns: + A Boolean, True if reset enabled, False if disabled + """ + if self.port_num <49: + return False # SPF port doesn't support this feature + + cpld_i = self.__get_cpld_num(self.port_num) + cpld_path = self._cpld_mapping[cpld_i] + reset_path = "{}{}{}{}".format(CPLD_I2C_PATH, cpld_path, '/module_reset_', self.port_num) + val=self._api_helper.read_txt_file(reset_path) + if val is None: + return 0 + + return int(val, 10)==1 + + def get_rx_los(self): + """ + Retrieves the RX LOS (lost-of-signal) status of SFP + Returns: + A Boolean, True if SFP has RX LOS, False if not. + Note : RX LOS status is latched until a call to get_rx_los or a reset. + """ + rx_los = False + if self.port_num < 49: + cpld_i = self.__get_cpld_num(self.port_num) + cpld_path = self._cpld_mapping[cpld_i] + rx_path = "{}{}{}{}".format(CPLD_I2C_PATH, cpld_path, '/module_rx_los_', self.port_num) + rx_los=self._api_helper.read_txt_file(rx_path) + if rx_los is None: + return False + #status_control_raw = self.__read_eeprom_specific_bytes( + # SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + #if status_control_raw: + # data = int(status_control_raw[0], 16) + # rx_los = (sffbase().test_bit(data, 1) != 0) + + else: + rx_los_list = [] + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + QSFP_CHANNL_RX_LOS_STATUS_OFFSET, QSFP_CHANNL_RX_LOS_STATUS_WIDTH) if self.get_presence() else None + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 16) + rx_los_list.append(rx_los_data & 0x01 != 0) + rx_los_list.append(rx_los_data & 0x02 != 0) + rx_los_list.append(rx_los_data & 0x04 != 0) + rx_los_list.append(rx_los_data & 0x08 != 0) + rx_los = rx_los_list[0] and rx_los_list[1] and rx_los_list[2] and rx_los_list[3] + + return rx_los + + def get_tx_fault(self): + """ + Retrieves the TX fault status of SFP + Returns: + A Boolean, True if SFP has TX fault, False if not + Note : TX fault status is lached until a call to get_tx_fault or a reset. + """ + tx_fault = False + if self.port_num < 49: + cpld_i = self.__get_cpld_num(self.port_num) + cpld_path = self._cpld_mapping[cpld_i] + tx_path = "{}{}{}{}".format(CPLD_I2C_PATH, cpld_path, '/module_tx_fault_', self.port_num) + tx_fault=self._api_helper.read_txt_file(tx_path) + if tx_fault is None: + return False + #status_control_raw = self.__read_eeprom_specific_bytes( + # SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + #if status_control_raw: + # data = int(status_control_raw[0], 16) + # tx_fault = (sffbase().test_bit(data, 2) != 0) + else: + tx_fault_list = [] + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + QSFP_CHANNL_TX_FAULT_STATUS_OFFSET, QSFP_CHANNL_TX_FAULT_STATUS_WIDTH) if self.get_presence() else None + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 16) + tx_fault_list.append(tx_fault_data & 0x01 != 0) + tx_fault_list.append(tx_fault_data & 0x02 != 0) + tx_fault_list.append(tx_fault_data & 0x04 != 0) + tx_fault_list.append(tx_fault_data & 0x08 != 0) + tx_fault = tx_fault_list[0] and tx_fault_list[1] and tx_fault_list[2] and tx_fault_list[3] + + return tx_fault + + def get_tx_disable(self): + """ + Retrieves the tx_disable status of this SFP + Returns: + A Boolean, True if tx_disable is enabled, False if disabled + """ + if self.port_num < 49: + tx_disable = False + + cpld_i = self.__get_cpld_num(self.port_num) + cpld_path = self._cpld_mapping[cpld_i] + tx_path = "{}{}{}{}".format(CPLD_I2C_PATH, cpld_path, '/module_tx_disable_', self.port_num) + tx_disable=self._api_helper.read_txt_file(tx_path) + + #status_control_raw = self.__read_eeprom_specific_bytes( + # SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + #if status_control_raw: + # data = int(status_control_raw[0], 16) + # tx_disable_hard = (sffbase().test_bit( + # data, SFP_TX_DISABLE_HARD_BIT) != 0) + # tx_disable_soft = (sffbase().test_bit( + # data, SFP_TX_DISABLE_SOFT_BIT) != 0) + # tx_disable = tx_disable_hard | tx_disable_soft + if tx_disable is not None: + return tx_disable + else: + return False + + else: + tx_disable_list = [] + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return False + + dom_control_raw = self.__read_eeprom_specific_bytes( + QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH) if self.get_presence() else None + if dom_control_raw is not None: + dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0) + tx_disable_list.append( + 'On' == dom_control_data['data']['TX1Disable']['value']) + tx_disable_list.append( + 'On' == dom_control_data['data']['TX2Disable']['value']) + tx_disable_list.append( + 'On' == dom_control_data['data']['TX3Disable']['value']) + tx_disable_list.append( + 'On' == dom_control_data['data']['TX4Disable']['value']) + + return tx_disable_list + + def get_tx_disable_channel(self): + """ + Retrieves the TX disabled channels in this SFP + Returns: + A hex of 4 bits (bit 0 to bit 3 as channel 0 to channel 3) to represent + TX channels which have been disabled in this SFP. + As an example, a returned value of 0x5 indicates that channel 0 + and channel 2 have been disabled. + """ + if self.port_num < 49: + # SFP doesn't support this feature + return False + else: + tx_disable_list = self.get_tx_disable() + if tx_disable_list is None: + return 0 + tx_disabled = 0 + for i in range(len(tx_disable_list)): + if tx_disable_list[i]: + tx_disabled |= 1 << i + return tx_disabled + + def get_lpmode(self): + """ + Retrieves the lpmode (low power mode) status of this SFP + Returns: + A Boolean, True if lpmode is enabled, False if disabled + """ + if self.port_num < 49: + # SFP doesn't support this feature + return False + else: + power_set=self.get_power_set() + power_override = self.get_power_override() + return power_set and power_override + + + def get_power_set(self): + + if self.port_num < 49: + # SFP doesn't support this feature + return False + else: + power_set = False + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return False + + dom_control_raw = self.__read_eeprom_specific_bytes( + QSFP_POWEROVERRIDE_OFFSET, QSFP_CONTROL_WIDTH) if self.get_presence() else None + if dom_control_raw is not None: + dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0) + power_set = ( + 'On' == dom_control_data['data']['PowerSet']['value']) + + return power_set + + def get_power_override(self): + """ + Retrieves the power-override status of this SFP + Returns: + A Boolean, True if power-override is enabled, False if disabled + """ + if self.port_num < 49: + return False # SFP doesn't support this feature + else: + power_override = False + + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return False + + dom_control_raw = self.__read_eeprom_specific_bytes( + QSFP_POWEROVERRIDE_OFFSET, QSFP_CONTROL_WIDTH) if self.get_presence() else None + if dom_control_raw is not None: + dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0) + power_override = ( + 'On' == dom_control_data['data']['PowerOverride']['value']) + + return power_override + + def get_temperature(self): + """ + Retrieves the temperature of this SFP + Returns: + An integer number of current temperature in Celsius + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + return transceiver_dom_info_dict.get("temperature", "N/A") + + def get_voltage(self): + """ + Retrieves the supply voltage of this SFP + Returns: + An integer number of supply voltage in mV + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + return transceiver_dom_info_dict.get("voltage", "N/A") + + def get_tx_bias(self): + """ + Retrieves the TX bias current of this SFP + Returns: + A list of four integer numbers, representing TX bias in mA + for channel 0 to channel 4. + Ex. ['110.09', '111.12', '108.21', '112.09'] + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + + tx1_bs = transceiver_dom_info_dict.get("tx1bias", "N/A") + if self.port_num < 49: + return [tx1_bs, "N/A", "N/A", "N/A"] if transceiver_dom_info_dict else [] + + tx2_bs = transceiver_dom_info_dict.get("tx2bias", "N/A") + tx3_bs = transceiver_dom_info_dict.get("tx3bias", "N/A") + tx4_bs = transceiver_dom_info_dict.get("tx4bias", "N/A") + return [tx1_bs, tx2_bs, tx3_bs, tx4_bs] if transceiver_dom_info_dict else [] + + def get_rx_power(self): + """ + Retrieves the received optical power for this SFP + Returns: + A list of four integer numbers, representing received optical + power in mW for channel 0 to channel 4. + Ex. ['1.77', '1.71', '1.68', '1.70'] + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + + rx1_pw = transceiver_dom_info_dict.get("rx1power", "N/A") + if self.port_num < 49: + return [rx1_pw, "N/A", "N/A", "N/A"] if transceiver_dom_info_dict else [] + rx2_pw = transceiver_dom_info_dict.get("rx2power", "N/A") + rx3_pw = transceiver_dom_info_dict.get("rx3power", "N/A") + rx4_pw = transceiver_dom_info_dict.get("rx4power", "N/A") + return [rx1_pw, rx2_pw, rx3_pw, rx4_pw] if transceiver_dom_info_dict else [] + + def get_tx_power(self): + """ + Retrieves the TX power of this SFP + Returns: + A list of four integer numbers, representing TX power in mW + for channel 0 to channel 4. + Ex. ['1.86', '1.86', '1.86', '1.86'] + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + tx1_pw = transceiver_dom_info_dict.get("tx1power", "N/A") + if self.port_num < 49: + return [tx1_pw, "N/A", "N/A", "N/A"] if transceiver_dom_info_dict else [] + tx2_pw = transceiver_dom_info_dict.get("tx2power", "N/A") + tx3_pw = transceiver_dom_info_dict.get("tx3power", "N/A") + tx4_pw = transceiver_dom_info_dict.get("tx4power", "N/A") + return [tx1_pw, tx2_pw, tx3_pw, tx4_pw] + + def reset(self): + """ + Reset SFP and return all user module settings to their default srate. + Returns: + A boolean, True if successful, False if not + """ + if self.port_num <49: + return False # SFP doesn't support this feature + + cpld_i = self.__get_cpld_num(self.port_num) + cpld_path = self._cpld_mapping[cpld_i] + reset_path = "{}{}{}{}".format(CPLD_I2C_PATH, cpld_path, '/module_reset_', self.port_num) + ret = self.__write_txt_file(reset_path, 1) + if ret is not True: + return ret + + time.sleep(0.01) + ret = self.__write_txt_file(reset_path, 0) + time.sleep(0.2) + + return ret + + + def tx_disable(self, tx_disable): + """ + Disable SFP TX for all channels + Args: + tx_disable : A Boolean, True to enable tx_disable mode, False to disable + tx_disable mode. + Returns: + A boolean, True if tx_disable is set successfully, False if not + """ + if self.port_num < 49: + cpld_i = self.__get_cpld_num(self.port_num) + cpld_path = self._cpld_mapping[cpld_i] + tx_path = "{}{}{}{}".format(CPLD_I2C_PATH, cpld_path, '/module_tx_disable_', self.port_num) + ret = self.__write_txt_file(tx_path, 1 if tx_disable else 0) + time.sleep(0.01) + return ret + + else: + if not self.get_presence(): + return False + sysfsfile_eeprom = None + try: + tx_disable_ctl = 0xf if tx_disable else 0x0 + buffer = create_string_buffer(1) + if sys.version_info[0] >= 3: + buffer[0] = tx_disable_ctl + else: + buffer[0] = chr(tx_disable_ctl) + # Write to eeprom + sysfsfile_eeprom = open( + self.port_to_eeprom_mapping[self.port_num], "r+b") + sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except IOError as e: + print ('Error: unable to open file: ',str(e)) + return False + finally: + if sysfsfile_eeprom is not None: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + + def tx_disable_channel(self, channel, disable): + """ + Sets the tx_disable for specified SFP channels + Args: + channel : A hex of 4 bits (bit 0 to bit 3) which represent channel 0 to 3, + e.g. 0x5 for channel 0 and channel 2. + disable : A boolean, True to disable TX channels specified in channel, + False to enable + Returns: + A boolean, True if successful, False if not + """ + + if self.port_num < 49: + return False # SFP doesn't support this feature + else: + if not self.get_presence(): + return False + + sysfsfile_eeprom = None + try: + channel_state = self.get_tx_disable_channel() + + for i in range(4): + channel_mask = (1 << i) + if not (channel & channel_mask): + continue + + if disable: + channel_state |= channel_mask + else: + channel_state &= ~channel_mask + + buffer = create_string_buffer(1) + if sys.version_info[0] >= 3: + buffer[0] = channel_state + else: + buffer[0] = chr(channel_state) + # Write to eeprom + sysfsfile_eeprom = open( + self.port_to_eeprom_mapping[self.port_num], "r+b") + sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except IOError as e: + print ('Error: unable to open file: ', str(e)) + return False + finally: + if sysfsfile_eeprom is not None: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + + def set_lpmode(self, lpmode): + """ + Sets the lpmode (low power mode) of SFP + Args: + lpmode: A Boolean, True to enable lpmode, False to disable it + Note : lpmode can be overridden by set_power_override + Returns: + A boolean, True if lpmode is set successfully, False if not + """ + if self.port_num < 49: + return False # SFP doesn't support this feature + else: + if lpmode is True: + self.set_power_override(True, True) + else: + self.set_power_override(False, False) + + return True + + def set_power_override(self, power_override, power_set): + """ + Sets SFP power level using power_override and power_set + Args: + power_override : + A Boolean, True to override set_lpmode and use power_set + to control SFP power, False to disable SFP power control + through power_override/power_set and use set_lpmode + to control SFP power. + power_set : + Only valid when power_override is True. + A Boolean, True to set SFP to low power mode, False to set + SFP to high power mode. + Returns: + A boolean, True if power-override and power_set are set successfully, + False if not + """ + if self.port_num < 49: + return False # SFP doesn't support this feature + else: + if not self.get_presence(): + return False + try: + power_override_bit = (1 << 0) if power_override else 0 + power_set_bit = (1 << 1) if power_set else (1 << 3) + + buffer = create_string_buffer(1) + if sys.version_info[0] >= 3: + buffer[0] = (power_override_bit | power_set_bit) + else: + buffer[0] = chr(power_override_bit | power_set_bit) + # Write to eeprom + with open(self.port_to_eeprom_mapping[self.port_num], "r+b") as fd: + fd.seek(QSFP_POWEROVERRIDE_OFFSET) + fd.write(buffer[0]) + time.sleep(0.01) + except Exception: + print ('Error: unable to open file: ', str(e)) + return False + return True + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + sfputil_helper = SfpUtilHelper() + sfputil_helper.read_porttab_mappings( + self.__get_path_to_port_config_file()) + name = sfputil_helper.logical[self.index] or "Unknown" + return name + + def get_presence(self): + """ + Retrieves the presence of the device + Returns: + bool: True if device is present, False if not + """ + cpld_i = self.__get_cpld_num(self.port_num) + cpld_path = self._cpld_mapping[cpld_i] + present_path = "{}{}{}{}".format(CPLD_I2C_PATH, cpld_path, '/module_present_', self.port_num) + val=self._api_helper.read_txt_file(present_path) + if val is not None: + return int(val, 10)==1 + else: + return False + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + transceiver_dom_info_dict = self.get_transceiver_info() + return transceiver_dom_info_dict.get("model", "N/A") + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + transceiver_dom_info_dict = self.get_transceiver_info() + return transceiver_dom_info_dict.get("serial", "N/A") + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self.get_presence() and self.get_transceiver_bulk_status() diff --git a/device/accton/x86_64-accton_as7312_54x-r0/sonic_platform/thermal.py b/device/accton/x86_64-accton_as7312_54x-r0/sonic_platform/thermal.py new file mode 100644 index 000000000000..aeab2caa23db --- /dev/null +++ b/device/accton/x86_64-accton_as7312_54x-r0/sonic_platform/thermal.py @@ -0,0 +1,146 @@ +############################################################################# +# Edgecore +# +# Thermal contains an implementation of SONiC Platform Base API and +# provides the thermal device status which are available in the platform +# +############################################################################# + +import os +import os.path +import glob + +try: + from sonic_platform_base.thermal_base import ThermalBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Thermal(ThermalBase): + """Platform-specific Thermal class""" + + THERMAL_NAME_LIST = [] + SYSFS_PATH = "/sys/bus/i2c/devices" + + def __init__(self, thermal_index=0): + self.index = thermal_index + # Add thermal name + self.THERMAL_NAME_LIST.append("Temp sensor 1") + self.THERMAL_NAME_LIST.append("Temp sensor 2") + self.THERMAL_NAME_LIST.append("Temp sensor 3") + self.THERMAL_NAME_LIST.append("Temp sensor 4") + + # Set hwmon path + i2c_path = { + 0: "3-0048/hwmon/hwmon*/", + 1: "3-0049/hwmon/hwmon*/", + 2: "3-004a/hwmon/hwmon*/", + 3: "3-004b/hwmon/hwmon*/", + }.get(self.index, None) + + self.hwmon_path = "{}/{}".format(self.SYSFS_PATH, i2c_path) + self.ss_key = self.THERMAL_NAME_LIST[self.index] + self.ss_index = 1 + + def __read_txt_file(self, file_path): + for filename in glob.glob(file_path): + try: + with open(filename, 'r') as fd: + data =fd.readline().rstrip() + return data + except IOError as e: + pass + + return None + + def __get_temp(self, temp_file): + temp_file_path = os.path.join(self.hwmon_path, temp_file) + raw_temp = self.__read_txt_file(temp_file_path) + if raw_temp is not None: + return float(raw_temp)/1000 + else: + return 0 + + + def __set_threshold(self, file_name, temperature): + temp_file_path = os.path.join(self.hwmon_path, file_name) + for filename in glob.glob(temp_file_path): + try: + with open(filename, 'w') as fd: + fd.write(str(temperature)) + return True + except IOError as e: + print("IOError") + + + def get_temperature(self): + """ + Retrieves current temperature reading from thermal + Returns: + A float number of current temperature in Celsius up to nearest thousandth + of one degree Celsius, e.g. 30.125 + """ + temp_file = "temp{}_input".format(self.ss_index) + return self.__get_temp(temp_file) + + def get_high_threshold(self): + """ + Retrieves the high threshold temperature of thermal + Returns: + A float number, the high threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + temp_file = "temp{}_max".format(self.ss_index) + return self.__get_temp(temp_file) + + def set_high_threshold(self, temperature): + """ + Sets the high threshold temperature of thermal + Args : + temperature: A float number up to nearest thousandth of one degree Celsius, + e.g. 30.125 + Returns: + A boolean, True if threshold is set successfully, False if not + """ + temp_file = "temp{}_max".format(self.ss_index) + temperature = temperature *1000 + self.__set_threshold(temp_file, temperature) + + return True + + def get_name(self): + """ + Retrieves the name of the thermal device + Returns: + string: The name of the thermal device + """ + return self.THERMAL_NAME_LIST[self.index] + + def get_presence(self): + """ + Retrieves the presence of the Thermal + Returns: + bool: True if Thermal is present, False if not + """ + temp_file = "temp{}_input".format(self.ss_index) + temp_file_path = os.path.join(self.hwmon_path, temp_file) + raw_txt = self.__read_txt_file(temp_file_path) + if raw_txt is not None: + return True + else: + return False + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + + file_str = "temp{}_input".format(self.ss_index) + file_path = os.path.join(self.hwmon_path, file_str) + raw_txt = self.__read_txt_file(file_path) + if raw_txt is None: + return False + else: + return int(raw_txt) != 0 diff --git a/device/accton/x86_64-accton_as7312_54xs-r0/Accton-AS7312-54XS/sai.profile b/device/accton/x86_64-accton_as7312_54xs-r0/Accton-AS7312-54XS/sai.profile index 31aefe2c2905..54cdc34801dd 100644 --- a/device/accton/x86_64-accton_as7312_54xs-r0/Accton-AS7312-54XS/sai.profile +++ b/device/accton/x86_64-accton_as7312_54xs-r0/Accton-AS7312-54XS/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-as7312-48x25G+6x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as7312_54xs-r0/Accton-AS7312-54XS/th-as7312-48x25G+6x100G.config.bcm b/device/accton/x86_64-accton_as7312_54xs-r0/Accton-AS7312-54XS/th-as7312-48x25G+6x100G.config.bcm index eef4d987e8ed..0ac6051b1ad4 100644 --- a/device/accton/x86_64-accton_as7312_54xs-r0/Accton-AS7312-54XS/th-as7312-48x25G+6x100G.config.bcm +++ b/device/accton/x86_64-accton_as7312_54xs-r0/Accton-AS7312-54XS/th-as7312-48x25G+6x100G.config.bcm @@ -107,7 +107,7 @@ dport_map_port_122=54 #dport_map_port_66=55 #dport_map_port_100=56 -/* Port Map */ +#/* Port Map */ ## FC10 ## portmap_42=41:25 portmap_43=42:25 diff --git a/device/accton/x86_64-accton_as7312_54xs-r0/plugins/eeprom.py b/device/accton/x86_64-accton_as7312_54xs-r0/plugins/eeprom.py index 7681caafeef4..951384d5e37d 100644 --- a/device/accton/x86_64-accton_as7312_54xs-r0/plugins/eeprom.py +++ b/device/accton/x86_64-accton_as7312_54xs-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -11,14 +8,16 @@ 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") +except ImportError as 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/1-0057/eeprom" - #Two i2c buses might get flipped order, check them both. + # Two i2c buses might get flipped order, check them both. if not os.path.exists(self.eeprom_path): self.eeprom_path = "/sys/bus/i2c/devices/0-0057/eeprom" super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/accton/x86_64-accton_as7312_54xs-r0/plugins/psuutil.py b/device/accton/x86_64-accton_as7312_54xs-r0/plugins/psuutil.py index d73e65bf7981..a47dfcab7e94 100644 --- a/device/accton/x86_64-accton_as7312_54xs-r0/plugins/psuutil.py +++ b/device/accton/x86_64-accton_as7312_54xs-r0/plugins/psuutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Accton # @@ -13,7 +11,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" diff --git a/device/accton/x86_64-accton_as7312_54xs-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7312_54xs-r0/plugins/sfputil.py index 90349ff53908..7d700fdaf90e 100644 --- a/device/accton/x86_64-accton_as7312_54xs-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7312_54xs-r0/plugins/sfputil.py @@ -28,66 +28,66 @@ class SfpUtil(SfpUtilBase): _port_to_eeprom_mapping = {} _cpld_mapping = { - 0: "4-0060", - 1: "5-0062", - 2: "6-0064", - } + 0: "4-0060", + 1: "5-0062", + 2: "6-0064", + } _port_to_i2c_mapping = { - 1: 18, - 2: 19, - 3: 20, - 4: 21, - 5: 22, - 6: 23, - 7: 24, - 8: 25, - 9: 26, - 10: 27, - 11: 28, - 12: 29, - 13: 30, - 14: 31, - 15: 32, - 16: 33, - 17: 34, - 18: 35, - 19: 36, - 20: 37, - 21: 38, - 22: 39, - 23: 40, - 24: 41, - 25: 42, - 26: 43, - 27: 44, - 28: 45, - 29: 46, - 30: 47, - 31: 48, - 32: 49, - 33: 50, - 34: 51, - 35: 52, - 36: 53, - 37: 54, - 38: 55, - 39: 56, - 40: 57, - 41: 58, - 42: 59, - 43: 60, - 44: 61, - 45: 62, - 46: 63, - 47: 64, - 48: 65, - 49: 66, #QSFP49 - 50: 67, - 51: 68, - 52: 69, - 53: 70, - 54: 71, #QSFP54 - } + 1: 18, + 2: 19, + 3: 20, + 4: 21, + 5: 22, + 6: 23, + 7: 24, + 8: 25, + 9: 26, + 10: 27, + 11: 28, + 12: 29, + 13: 30, + 14: 31, + 15: 32, + 16: 33, + 17: 34, + 18: 35, + 19: 36, + 20: 37, + 21: 38, + 22: 39, + 23: 40, + 24: 41, + 25: 42, + 26: 43, + 27: 44, + 28: 45, + 29: 46, + 30: 47, + 31: 48, + 32: 49, + 33: 50, + 34: 51, + 35: 52, + 36: 53, + 37: 54, + 38: 55, + 39: 56, + 40: 57, + 41: 58, + 42: 59, + 43: 60, + 44: 61, + 45: 62, + 46: 63, + 47: 64, + 48: 65, + 49: 66, # QSFP49 + 50: 67, + 51: 68, + 52: 69, + 53: 70, + 54: 71, # QSFP54 + } @property def port_start(self): @@ -104,10 +104,10 @@ def qsfp_port_start(self): @property def qsfp_port_end(self): return self.QSFP_PORT_END - + @property def qsfp_ports(self): - return range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1) + return list(range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -121,12 +121,12 @@ def __init__(self): SfpUtilBase.__init__(self) - def get_cpld_num(self, port_num): + def get_cpld_num(self, port_num): cpld_i = 1 if (port_num > 24 and port_num < self.qsfp_port_start): cpld_i = 2 - if (port_num > 52): + if (port_num > 52): cpld_i = 2 return cpld_i @@ -135,7 +135,7 @@ 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 - + cpld_i = self.get_cpld_num(port_num) cpld_ps = self._cpld_mapping[cpld_i] @@ -148,7 +148,7 @@ def get_presence(self, port_num): content = val_file.readline().rstrip() val_file.close() except IOError as e: - print "Error: unable to access file: %s" % str(e) + print("Error: unable to access file: %s" % str(e)) return False # content is a string, either "0" or "1" @@ -173,20 +173,21 @@ def get_low_power_mode(self, port_num): lpmode = ord(eeprom.read(1)) if ((lpmode & 0x3) == 0x3): - return True # Low Power Mode if "Power override" bit is 1 and "Power set" bit is 1 + return True # Low Power Mode if "Power override" bit is 1 and "Power set" bit is 1 else: - return False # High Power Mode if one of the following conditions is matched: - # 1. "Power override" bit is 0 - # 2. "Power override" bit is 1 and "Power set" bit is 0 + # High Power Mode if one of the following conditions is matched: + # 1. "Power override" bit is 0 + # 2. "Power override" bit is 1 and "Power set" bit is 0 + return False except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False finally: if eeprom is not None: eeprom.close() time.sleep(0.01) - def set_low_power_mode(self, port_num, lpmode): + 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.qsfp_port_end: return False @@ -195,10 +196,10 @@ def set_low_power_mode(self, port_num, lpmode): eeprom = None if not self.get_presence(port_num): - return False # Port is not present, unable to set the eeprom + return False # Port is not present, unable to set the eeprom # Fill in write buffer - regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode + regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode buffer = create_string_buffer(1) buffer[0] = chr(regval) @@ -208,7 +209,7 @@ def set_low_power_mode(self, port_num, lpmode): eeprom.write(buffer[0]) return True except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False finally: if eeprom is not None: @@ -218,7 +219,7 @@ def set_low_power_mode(self, port_num, lpmode): def reset(self, port_num): if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: return False - + cpld_i = self.get_cpld_num(port_num) cpld_ps = self._cpld_mapping[cpld_i] path = "/sys/bus/i2c/devices/{0}/module_reset_{1}" @@ -226,14 +227,14 @@ def reset(self, port_num): try: reg_file = open(port_ps, 'w') except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = '0' reg_file.write(reg_value) reg_file.close() - + return True def get_transceiver_change_event(self): diff --git a/device/accton/x86_64-accton_as7312_54xs-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7312_54xs-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as7312_54xs-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as7312_54xs-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as7315_27xb-r0/Accton-AS7315-27XB/qax-as7315-20x10G+4x25G+3x100G.config.bcm b/device/accton/x86_64-accton_as7315_27xb-r0/Accton-AS7315-27XB/qax-as7315-20x10G+4x25G+3x100G.config.bcm index eef4d987e8ed..0ac6051b1ad4 100644 --- a/device/accton/x86_64-accton_as7315_27xb-r0/Accton-AS7315-27XB/qax-as7315-20x10G+4x25G+3x100G.config.bcm +++ b/device/accton/x86_64-accton_as7315_27xb-r0/Accton-AS7315-27XB/qax-as7315-20x10G+4x25G+3x100G.config.bcm @@ -107,7 +107,7 @@ dport_map_port_122=54 #dport_map_port_66=55 #dport_map_port_100=56 -/* Port Map */ +#/* Port Map */ ## FC10 ## portmap_42=41:25 portmap_43=42:25 diff --git a/device/accton/x86_64-accton_as7315_27xb-r0/Accton-AS7315-27XB/sai.profile b/device/accton/x86_64-accton_as7315_27xb-r0/Accton-AS7315-27XB/sai.profile index 191b27dac2f8..551599b5eba9 100644 --- a/device/accton/x86_64-accton_as7315_27xb-r0/Accton-AS7315-27XB/sai.profile +++ b/device/accton/x86_64-accton_as7315_27xb-r0/Accton-AS7315-27XB/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/qax-as7315-20x10G+4x25G+3x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as7315_27xb-r0/plugins/eeprom.py b/device/accton/x86_64-accton_as7315_27xb-r0/plugins/eeprom.py index 171593068ae5..6f7ad9ef091d 100644 --- a/device/accton/x86_64-accton_as7315_27xb-r0/plugins/eeprom.py +++ b/device/accton/x86_64-accton_as7315_27xb-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -11,11 +8,13 @@ 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") +except ImportError as 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/4-0057/eeprom" super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/accton/x86_64-accton_as7315_27xb-r0/plugins/psuutil.py b/device/accton/x86_64-accton_as7315_27xb-r0/plugins/psuutil.py index 7ec16640e5a8..dbc0a1170251 100644 --- a/device/accton/x86_64-accton_as7315_27xb-r0/plugins/psuutil.py +++ b/device/accton/x86_64-accton_as7315_27xb-r0/plugins/psuutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Accton # @@ -13,7 +11,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" diff --git a/device/accton/x86_64-accton_as7315_27xb-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7315_27xb-r0/plugins/sfputil.py index dc37f5ea360c..1a1b61d1e659 100644 --- a/device/accton/x86_64-accton_as7315_27xb-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7315_27xb-r0/plugins/sfputil.py @@ -12,10 +12,11 @@ except ImportError as e: raise ImportError("%s - required module not found" % str(e)) -#from xcvrd +# from xcvrd SFP_STATUS_REMOVED = '0' SFP_STATUS_INSERTED = '1' + class SfpUtil(SfpUtilBase): """Platform-specific SfpUtil class""" @@ -31,37 +32,37 @@ class SfpUtil(SfpUtilBase): _port_to_lp_mode = {} _port_to_eeprom_mapping = {} - _cpld_mapping = [ "8-0063", "7-0064"] + _cpld_mapping = ["8-0063", "7-0064"] _port_to_i2c_mapping = { - 1: 26, - 2: 27, - 3: 28, - 4: 29, - 5: 30, - 6: 31, - 7: 32, - 8: 33, - 9: 34, - 10: 35, - 11: 36, - 12: 37, - 13: 38, - 14: 39, - 15: 40, - 16: 41, - 17: 42, - 18: 43, - 19: 44, - 20: 45, - 21: 46, - 22: 47, - 23: 48, - 24: 49, - 25: 21, #QSFP - 26: 22, - 27: 23, - } + 1: 26, + 2: 27, + 3: 28, + 4: 29, + 5: 30, + 6: 31, + 7: 32, + 8: 33, + 9: 34, + 10: 35, + 11: 36, + 12: 37, + 13: 38, + 14: 39, + 15: 40, + 16: 41, + 17: 42, + 18: 43, + 19: 44, + 20: 45, + 21: 46, + 22: 47, + 23: 48, + 24: 49, + 25: 21, # QSFP + 26: 22, + 27: 23, + } @property def port_start(self): @@ -78,10 +79,10 @@ def qsfp_port_start(self): @property def qsfp_port_end(self): return self.QSFP_PORT_END - + @property def qsfp_ports(self): - return range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1) + return list(range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -96,7 +97,7 @@ def __init__(self): self.get_transceiver_change_event() SfpUtilBase.__init__(self) - def get_cpld_num(self, port_num): + def get_cpld_num(self, port_num): cpld_i = 0 if (port_num >= self.qsfp_port_start): cpld_i = 1 @@ -107,11 +108,11 @@ 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 - + cpld_i = self.get_cpld_num(port_num) cpld_ps = self._cpld_mapping[cpld_i] path = "/sys/bus/i2c/devices/{0}/present_{1}" - index = ((port_num-1)%24) +1 + index = ((port_num-1) % 24) + 1 port_ps = path.format(cpld_ps, index) content = "0" @@ -120,9 +121,9 @@ def get_presence(self, port_num): content = val_file.readline().rstrip() val_file.close() except IOError as e: - print "Error: unable to access file: %s" % str(e) + print("Error: unable to access file: %s" % str(e)) return False - + if content == "1": return True @@ -144,20 +145,21 @@ def get_low_power_mode(self, port_num): lpmode = ord(eeprom.read(1)) if ((lpmode & 0x3) == 0x3): - return True # Low Power Mode if "Power override" bit is 1 and "Power set" bit is 1 + return True # Low Power Mode if "Power override" bit is 1 and "Power set" bit is 1 else: - return False # High Power Mode if one of the following conditions is matched: - # 1. "Power override" bit is 0 - # 2. "Power override" bit is 1 and "Power set" bit is 0 + # High Power Mode if one of the following conditions is matched: + # 1. "Power override" bit is 0 + # 2. "Power override" bit is 1 and "Power set" bit is 0 + return False except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False finally: if eeprom is not None: eeprom.close() time.sleep(0.01) - def set_low_power_mode(self, port_num, lpmode): + 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.qsfp_port_end: return False @@ -166,10 +168,10 @@ def set_low_power_mode(self, port_num, lpmode): eeprom = None if not self.get_presence(port_num): - return False # Port is not present, unable to set the eeprom + return False # Port is not present, unable to set the eeprom # Fill in write buffer - regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode + regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode buffer = create_string_buffer(1) buffer[0] = chr(regval) @@ -179,7 +181,7 @@ def set_low_power_mode(self, port_num, lpmode): eeprom.write(buffer[0]) return True except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False finally: if eeprom is not None: @@ -187,14 +189,14 @@ def set_low_power_mode(self, port_num, lpmode): time.sleep(0.01) def reset(self, port_num): - raise NotImplementedError + raise NotImplementedError @property def _get_present_bitmap(self): nodes = [] - port_num = [24,3] + port_num = [24, 3] - path = "/sys/bus/i2c/devices/{0}/" + path = "/sys/bus/i2c/devices/{0}/" cpld_path = path.format(self._cpld_mapping[0]) nodes.append((cpld_path + "module_present_all", port_num[0])) cpld_path = path.format(self._cpld_mapping[1]) @@ -206,16 +208,17 @@ def _get_present_bitmap(self): reg_file = open(node[0]) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False cpld_bm = reg_file.readline().rstrip().zfill(node[1]/4) bitmap.append(cpld_bm) reg_file.close() rev = "".join(bitmap[::-1]) - return int(rev,16) + return int(rev, 16) + + data = {'valid': 0, 'last': 0, 'present': 0} - data = {'valid':0, 'last':0, 'present':0} def get_transceiver_change_event(self, timeout=2000): now = time.time() port_dict = {} @@ -223,7 +226,7 @@ def get_transceiver_change_event(self, timeout=2000): if timeout < 1000: timeout = 1000 - timeout = (timeout) / float(1000) # Convert to secs + timeout = (timeout) / float(1000) # Convert to secs if now < (self.data['last'] + timeout) and self.data['valid']: return True, {} @@ -231,7 +234,7 @@ def get_transceiver_change_event(self, timeout=2000): reg_value = self._get_present_bitmap changed_ports = self.data['present'] ^ reg_value if changed_ports: - for port in range (self.port_start, self.port_end+1): + for port in range(self.port_start, self.port_end+1): # Mask off the bit corresponding to our port mask = (1 << (port - 1)) if changed_ports & mask: @@ -249,5 +252,3 @@ def get_transceiver_change_event(self, timeout=2000): else: return True, {} return False, {} - - diff --git a/device/accton/x86_64-accton_as7315_27xb-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7315_27xb-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as7315_27xb-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as7315_27xb-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/sai.profile b/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/sai.profile index 47e3107477a2..eb932199dfab 100755 --- a/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/sai.profile +++ b/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-as7326-48x25G+8x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/td3-as7326-48x25G+8x100G.config.bcm b/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/td3-as7326-48x25G+8x100G.config.bcm index 1a4b7da32df3..5da8cd015da1 100755 --- a/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/td3-as7326-48x25G+8x100G.config.bcm +++ b/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/td3-as7326-48x25G+8x100G.config.bcm @@ -1,3 +1,4 @@ +sai_load_hw_config=/etc/bcm/flex/bcm56870_a0_issu/b870.6.4.1/ #polarity/lanemap is using TH2 style. core_clock_frequency=1525 dpp_clock_ratio=2:3 @@ -14,7 +15,7 @@ fpem_mem_entries=16384 l2xmsg_mode=1 # Platform specfic -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 cdma_timeout_usec=3000000 ifp_inports_support_enable=1 diff --git a/device/accton/x86_64-accton_as7326_56x-r0/led_proc_init.soc b/device/accton/x86_64-accton_as7326_56x-r0/led_proc_init.soc index 01b49772c0ba..cb549f2773f9 100755 --- a/device/accton/x86_64-accton_as7326_56x-r0/led_proc_init.soc +++ b/device/accton/x86_64-accton_as7326_56x-r0/led_proc_init.soc @@ -1,6 +1,6 @@ #led auto off #led stop -m0 load 0 0x0 /usr/share/sonic/platform/linkscan_led_fw.bin +#m0 load 0 0x0 /usr/share/sonic/platform/linkscan_led_fw.bin m0 load 0 0x3800 /usr/share/sonic/platform/custom_led.bin led auto on led start diff --git a/device/accton/x86_64-accton_as7326_56x-r0/plugins/eeprom.py b/device/accton/x86_64-accton_as7326_56x-r0/plugins/eeprom.py index 1e7d1046d93d..4241483d68eb 100644 --- a/device/accton/x86_64-accton_as7326_56x-r0/plugins/eeprom.py +++ b/device/accton/x86_64-accton_as7326_56x-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -11,11 +8,13 @@ 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") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + class board(eeprom_tlvinfo.TlvInfoDecoder): _TLV_INFO_MAX_LEN = 256 + def __init__(self, name, path, cpld_root, ro): self.eeprom_path = "/sys/bus/i2c/devices/0-0056/eeprom" super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/accton/x86_64-accton_as7326_56x-r0/plugins/psuutil.py b/device/accton/x86_64-accton_as7326_56x-r0/plugins/psuutil.py index a3c30bc478e7..c215bb896772 100644 --- a/device/accton/x86_64-accton_as7326_56x-r0/plugins/psuutil.py +++ b/device/accton/x86_64-accton_as7326_56x-r0/plugins/psuutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Accton # @@ -13,7 +11,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" diff --git a/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py index 553e48fdd2a9..965e876691c8 100644 --- a/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py @@ -11,10 +11,11 @@ except ImportError as e: raise ImportError("%s - required module not found" % str(e)) -#from xcvrd +# from xcvrd SFP_STATUS_REMOVED = '0' SFP_STATUS_INSERTED = '1' + class SfpUtil(SfpUtilBase): """Platform-specific SfpUtil class""" @@ -31,69 +32,69 @@ class SfpUtil(SfpUtilBase): _port_to_eeprom_mapping = {} _cpld_mapping = { - 1: "12-0062", - 2: "18-0060", - 3: "19-0064", - } + 1: "12-0062", + 2: "18-0060", + 3: "19-0064", + } _port_to_i2c_mapping = { - 1: 42, - 2: 41, - 3: 44, - 4: 43, - 5: 47, - 6: 45, - 7: 46, - 8: 50, - 9: 48, - 10: 49, - 11: 51, - 12: 52, - 13: 53, - 14: 56, - 15: 55, - 16: 54, - 17: 58, - 18: 57, - 19: 59, - 20: 60, - 21: 61, - 22: 63, - 23: 62, - 24: 64, - 25: 66, - 26: 68, - 27: 65, - 28: 67, - 29: 69, - 30: 71, - 31: 72, - 32: 70, - 33: 74, - 34: 73, - 35: 76, - 36: 75, - 37: 77, - 38: 79, - 39: 78, - 40: 80, - 41: 81, - 42: 82, - 43: 84, - 44: 85, - 45: 83, - 46: 87, - 47: 88, - 48: 86, - 49: 25,#QSFP49 - 50: 26, - 51: 27, - 52: 28, - 53: 29, - 54: 30, - 55: 31, - 56: 32,#QSFP56 - } + 1: 42, + 2: 41, + 3: 44, + 4: 43, + 5: 47, + 6: 45, + 7: 46, + 8: 50, + 9: 48, + 10: 49, + 11: 52, + 12: 51, + 13: 53, + 14: 56, + 15: 55, + 16: 54, + 17: 58, + 18: 57, + 19: 60, + 20: 59, + 21: 61, + 22: 63, + 23: 62, + 24: 64, + 25: 66, + 26: 68, + 27: 65, + 28: 67, + 29: 69, + 30: 71, + 31: 72, + 32: 70, + 33: 74, + 34: 73, + 35: 76, + 36: 75, + 37: 77, + 38: 79, + 39: 78, + 40: 80, + 41: 81, + 42: 82, + 43: 84, + 44: 85, + 45: 83, + 46: 87, + 47: 88, + 48: 86, + 49: 25, # QSFP49 + 50: 26, + 51: 27, + 52: 28, + 53: 29, + 54: 30, + 55: 31, + 56: 32, # QSFP56 + } @property def port_start(self): @@ -113,7 +114,7 @@ def qsfp_port_end(self): @property def qsfp_ports(self): - return range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1) + return list(range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -145,13 +146,13 @@ def get_presence(self, port_num): path = "/sys/bus/i2c/devices/{0}/module_present_{1}" port_ps = path.format(cpld_ps, port_num) - content="0" + content = "0" try: val_file = open(port_ps) content = val_file.readline().rstrip() val_file.close() except IOError as e: - print "Error: unable to access file: %s" % str(e) + print("Error: unable to access file: %s" % str(e)) return False if content == "1": @@ -175,14 +176,15 @@ def get_low_power_mode(self, port_num): lpmode = ord(eeprom.read(1)) if ((lpmode & 0x3) == 0x3): - return True # Low Power Mode if "Power override" bit is 1 and "Power set" bit is 1 + return True # Low Power Mode if "Power override" bit is 1 and "Power set" bit is 1 else: - return False # High Power Mode if one of the following conditions is matched: - # 1. "Power override" bit is 0 - # 2. "Power override" bit is 1 and "Power set" bit is 0 + # High Power Mode if one of the following conditions is matched: + # 1. "Power override" bit is 0 + # 2. "Power override" bit is 1 and "Power set" bit is 0 + return False except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False finally: if eeprom is not None: @@ -198,10 +200,10 @@ def set_low_power_mode(self, port_num, lpmode): eeprom = None if not self.get_presence(port_num): - return False # Port is not present, unable to set the eeprom + return False # Port is not present, unable to set the eeprom # Fill in write buffer - regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode + regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode buffer = create_string_buffer(1) buffer[0] = chr(regval) @@ -211,7 +213,7 @@ def set_low_power_mode(self, port_num, lpmode): eeprom.write(buffer[0]) return True except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False finally: if eeprom is not None: @@ -226,28 +228,29 @@ def reset(self, port_num): cpld_ps = self._cpld_mapping[cpld_i] path = "/sys/bus/i2c/devices/{0}/module_reset_{1}" port_ps = path.format(cpld_ps, port_num) - + self.__port_to_mod_rst = port_ps try: reg_file = open(self.__port_to_mod_rst, 'r+', buffering=0) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False - #toggle reset + # 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 + @property def _get_present_bitmap(self): nodes = [] rev = [] - port_num = [30,26] + port_num = [30, 26] path = "/sys/bus/i2c/devices/{0}/module_present_all" cpld_i = self.get_cpld_num(self.port_start) @@ -262,7 +265,7 @@ def _get_present_bitmap(self): try: reg_file = open(node[0]) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False bitmap = reg_file.readline().rstrip() bitmap = bin(int(bitmap, 16))[2:].zfill(node[1]) @@ -273,7 +276,8 @@ def _get_present_bitmap(self): bitmaps = hex(int(bitmaps, 2)) return int(bitmaps, 0) - data = {'valid':0, 'last':0, 'present':0} + data = {'valid': 0, 'last': 0, 'present': 0} + def get_transceiver_change_event(self, timeout=2000): now = time.time() port_dict = {} @@ -281,7 +285,7 @@ def get_transceiver_change_event(self, timeout=2000): if timeout < 1000: timeout = 1000 - timeout = (timeout) / float(1000) # Convert to secs + timeout = (timeout) / float(1000) # Convert to secs if now < (self.data['last'] + timeout) and self.data['valid']: return True, {} @@ -289,7 +293,7 @@ def get_transceiver_change_event(self, timeout=2000): reg_value = self._get_present_bitmap changed_ports = self.data['present'] ^ reg_value if changed_ports: - for port in range (self.port_start, self.port_end+1): + for port in range(self.port_start, self.port_end+1): # Mask off the bit corresponding to our port mask = (1 << (port - 1)) if changed_ports & mask: diff --git a/device/accton/x86_64-accton_as7326_56x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7326_56x-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as7326_56x-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as7326_56x-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as7512_32x-r0/plugins/eeprom.py b/device/accton/x86_64-accton_as7512_32x-r0/plugins/eeprom.py index 6e2c0c8bb96f..f2f0703f0a11 100644 --- a/device/accton/x86_64-accton_as7512_32x-r0/plugins/eeprom.py +++ b/device/accton/x86_64-accton_as7512_32x-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Cavium # @@ -10,7 +8,6 @@ ############################################################################# try: - import exceptions import binascii import time import optparse @@ -20,8 +17,9 @@ 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") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + class board(eeprom_tlvinfo.TlvInfoDecoder): diff --git a/device/accton/x86_64-accton_as7512_32x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7512_32x-r0/plugins/sfputil.py index a4f405fa6afd..a999ecc24092 100644 --- a/device/accton/x86_64-accton_as7512_32x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7512_32x-r0/plugins/sfputil.py @@ -5,8 +5,8 @@ import string from ctypes import create_string_buffer from sonic_sfp.sfputilbase import SfpUtilBase -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class SfpUtil(SfpUtilBase): @@ -16,11 +16,10 @@ class SfpUtil(SfpUtilBase): _port_end = 31 ports_in_block = 32 - _port_to_eeprom_mapping = {} - _qsfp_ports = range(0, ports_in_block + 1) - + _qsfp_ports = list(range(0, ports_in_block + 1)) + def __init__(self): # Override port_to_eeprom_mapping for class initialization eeprom_path = '/sys/bus/i2c/devices/{0}-0050/sfp_eeprom' @@ -45,9 +44,9 @@ def get_presence(self, port_num): reg_value = reg_file.readline().rstrip() reg_file.close() except IOError as e: - print "Error: unable to access file: %s" % str(e) + print("Error: unable to access file: %s" % str(e)) return False - + if reg_value == '1': return True @@ -63,7 +62,7 @@ def port_end(self): @property def qsfp_ports(self): - return range(0, self.ports_in_block + 1) + return list(range(0, self.ports_in_block + 1)) @property def port_to_eeprom_mapping(self): @@ -93,20 +92,21 @@ def get_low_power_mode(self, port_num): lpmode = ord(eeprom.read(1)) if ((lpmode & 0x3) == 0x3): - return True # Low Power Mode if "Power override" bit is 1 and "Power set" bit is 1 + return True # Low Power Mode if "Power override" bit is 1 and "Power set" bit is 1 else: - return False # High Power Mode if one of the following conditions is matched: - # 1. "Power override" bit is 0 - # 2. "Power override" bit is 1 and "Power set" bit is 0 + # High Power Mode if one of the following conditions is matched: + # 1. "Power override" bit is 0 + # 2. "Power override" bit is 1 and "Power set" bit is 0 + return False except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False finally: if eeprom is not None: eeprom.close() time.sleep(0.01) - def set_low_power_mode(self, port_num, lpmode): + def set_low_power_mode(self, port_num, lpmode): # Check for invalid port_num if port_num < self._port_start or port_num > self._port_end: return False @@ -115,10 +115,10 @@ def set_low_power_mode(self, port_num, lpmode): eeprom = None if not self.get_presence(port_num): - return False # Port is not present, unable to set the eeprom + return False # Port is not present, unable to set the eeprom # Fill in write buffer - regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode + regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode buffer = create_string_buffer(1) buffer[0] = chr(regval) @@ -128,9 +128,9 @@ def set_low_power_mode(self, port_num, lpmode): eeprom.write(buffer[0]) return True except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False finally: if eeprom is not None: eeprom.close() - time.sleep(0.01) \ No newline at end of file + time.sleep(0.01) diff --git a/device/accton/x86_64-accton_as7512_32x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7512_32x-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as7512_32x-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as7512_32x-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as7712_32x-r0/Accton-AS7712-32X/sai.profile b/device/accton/x86_64-accton_as7712_32x-r0/Accton-AS7712-32X/sai.profile index 28953a08f205..6e4d11fb7292 100644 --- a/device/accton/x86_64-accton_as7712_32x-r0/Accton-AS7712-32X/sai.profile +++ b/device/accton/x86_64-accton_as7712_32x-r0/Accton-AS7712-32X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-as7712-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as7712_32x-r0/Accton-AS7712-32X/th-as7712-32x100G.config.bcm b/device/accton/x86_64-accton_as7712_32x-r0/Accton-AS7712-32X/th-as7712-32x100G.config.bcm index 09d97c5e4c63..6ecca8e02a08 100644 --- a/device/accton/x86_64-accton_as7712_32x-r0/Accton-AS7712-32X/th-as7712-32x100G.config.bcm +++ b/device/accton/x86_64-accton_as7712_32x-r0/Accton-AS7712-32X/th-as7712-32x100G.config.bcm @@ -14,7 +14,7 @@ pbmp_xport_xe=0x444444451111111144444444422222222 # arl_clean_timeout_usec=15000000 asf_mem_profile=2 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_flags=1 bcm_stat_jumbo=9236 cdma_timeout_usec=15000000 diff --git a/device/accton/x86_64-accton_as7712_32x-r0/plugins/eeprom.py b/device/accton/x86_64-accton_as7712_32x-r0/plugins/eeprom.py index 7681caafeef4..951384d5e37d 100644 --- a/device/accton/x86_64-accton_as7712_32x-r0/plugins/eeprom.py +++ b/device/accton/x86_64-accton_as7712_32x-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -11,14 +8,16 @@ 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") +except ImportError as 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/1-0057/eeprom" - #Two i2c buses might get flipped order, check them both. + # Two i2c buses might get flipped order, check them both. if not os.path.exists(self.eeprom_path): self.eeprom_path = "/sys/bus/i2c/devices/0-0057/eeprom" super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/accton/x86_64-accton_as7712_32x-r0/plugins/psuutil.py b/device/accton/x86_64-accton_as7712_32x-r0/plugins/psuutil.py index d7600a2af4b1..a9133f8adccb 100644 --- a/device/accton/x86_64-accton_as7712_32x-r0/plugins/psuutil.py +++ b/device/accton/x86_64-accton_as7712_32x-r0/plugins/psuutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Accton # @@ -13,7 +11,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" diff --git a/device/accton/x86_64-accton_as7712_32x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7712_32x-r0/plugins/sfputil.py index 8cfde932e7e3..079a533e4e7d 100644 --- a/device/accton/x86_64-accton_as7712_32x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7712_32x-r0/plugins/sfputil.py @@ -1,14 +1,12 @@ -#!/usr/bin/env python - try: import time import string from ctypes import create_string_buffer - from sonic_sfp.sfputilbase import SfpUtilBase -except ImportError, e: - raise ImportError (str(e) + "- required module not found") + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") -#from xcvrd +# from xcvrd SFP_STATUS_INSERTED = '1' SFP_STATUS_REMOVED = '0' @@ -22,41 +20,41 @@ class SfpUtil(SfpUtilBase): _port_to_eeprom_mapping = {} port_to_i2c_mapping = { - 9 : 18, - 10 : 19, - 11 : 20, - 12 : 21, - 1 : 22, - 2 : 23, - 3 : 24, - 4 : 25, - 6 : 26, - 5 : 27, - 8 : 28, - 7 : 29, - 13 : 30, - 14 : 31, - 15 : 32, - 16 : 33, - 17 : 34, - 18 : 35, - 19 : 36, - 20 : 37, - 25 : 38, - 26 : 39, - 27 : 40, - 28 : 41, - 29 : 42, - 30 : 43, - 31 : 44, - 32 : 45, - 21 : 46, - 22 : 47, - 23 : 48, - 24 : 49, + 9: 18, + 10: 19, + 11: 20, + 12: 21, + 1: 22, + 2: 23, + 3: 24, + 4: 25, + 6: 26, + 5: 27, + 8: 28, + 7: 29, + 13: 30, + 14: 31, + 15: 32, + 16: 33, + 17: 34, + 18: 35, + 19: 36, + 20: 37, + 25: 38, + 26: 39, + 27: 40, + 28: 41, + 29: 42, + 30: 43, + 31: 44, + 32: 45, + 21: 46, + 22: 47, + 23: 48, + 24: 49, } - _qsfp_ports = range(0, ports_in_block + 1) + _qsfp_ports = list(range(0, ports_in_block + 1)) def __init__(self): eeprom_path = '/sys/bus/i2c/devices/{0}-0050/eeprom' @@ -72,14 +70,14 @@ def reset(self, port_num): path = "/sys/bus/i2c/devices/4-0060/module_reset_{0}" port_ps = path.format(port_num) - + try: reg_file = open(port_ps, 'w', buffering=0) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False - #toggle reset + # toggle reset reg_file.seek(0) reg_file.write('1') time.sleep(1) @@ -87,7 +85,7 @@ def reset(self, port_num): reg_file.write('0') reg_file.close() return True - + def get_presence(self, port_num): # Check for invalid port_num if port_num < self._port_start or port_num > self._port_end: @@ -102,9 +100,9 @@ def get_presence(self, port_num): reg_value = reg_file.readline().rstrip() reg_file.close() except IOError as e: - print "Error: unable to access file: %s" % str(e) + print("Error: unable to access file: %s" % str(e)) return False - + if reg_value == '1': return True @@ -117,14 +115,14 @@ def port_start(self): @property def port_end(self): return self._port_end - + @property def qsfp_ports(self): - return range(self.port_start, self.ports_in_block + 1) + return list(range(self.port_start, self.ports_in_block + 1)) - @property + @property def port_to_eeprom_mapping(self): - return self._port_to_eeprom_mapping + return self._port_to_eeprom_mapping def get_low_power_mode(self, port_num): # Check for invalid port_num @@ -142,20 +140,21 @@ def get_low_power_mode(self, port_num): lpmode = ord(eeprom.read(1)) if ((lpmode & 0x3) == 0x3): - return True # Low Power Mode if "Power override" bit is 1 and "Power set" bit is 1 + return True # Low Power Mode if "Power override" bit is 1 and "Power set" bit is 1 else: - return False # High Power Mode if one of the following conditions is matched: - # 1. "Power override" bit is 0 - # 2. "Power override" bit is 1 and "Power set" bit is 0 + # High Power Mode if one of the following conditions is matched: + # 1. "Power override" bit is 0 + # 2. "Power override" bit is 1 and "Power set" bit is 0 + return False except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False finally: if eeprom is not None: eeprom.close() time.sleep(0.01) - def set_low_power_mode(self, port_num, lpmode): + def set_low_power_mode(self, port_num, lpmode): # Check for invalid port_num if port_num < self._port_start or port_num > self._port_end: return False @@ -164,10 +163,10 @@ def set_low_power_mode(self, port_num, lpmode): eeprom = None if not self.get_presence(port_num): - return False # Port is not present, unable to set the eeprom + return False # Port is not present, unable to set the eeprom # Fill in write buffer - regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode + regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode buffer = create_string_buffer(1) buffer[0] = chr(regval) @@ -177,7 +176,7 @@ def set_low_power_mode(self, port_num, lpmode): eeprom.write(buffer[0]) return True except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False finally: if eeprom is not None: @@ -197,16 +196,17 @@ def _get_all_presence(self): reg_file = open(node) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False bitmap += reg_file.readline().rstrip() + " " reg_file.close() rev = bitmap.split(" ") rev = "".join(rev[::-1]) - return int(rev,16) + return int(rev, 16) + + data = {'valid': 0, 'last': 0, 'present': 0} - data = {'valid':0, 'last':0, 'present':0} def get_transceiver_change_event(self, timeout=2000): now = time.time() port_dict = {} @@ -214,7 +214,7 @@ def get_transceiver_change_event(self, timeout=2000): if timeout < 1000: timeout = 1000 - timeout = (timeout) / float(1000) # Convert to secs + timeout = (timeout) / float(1000) # Convert to secs if now < (self.data['last'] + timeout) and self.data['valid']: return True, {} @@ -222,7 +222,7 @@ def get_transceiver_change_event(self, timeout=2000): reg_value = self._get_all_presence changed_ports = self.data['present'] ^ reg_value if changed_ports: - for port in range (self.port_start, self.port_end+1): + for port in range(self.port_start, self.port_end+1): # Mask off the bit corresponding to our port mask = (1 << (port - 1)) if changed_ports & mask: @@ -239,4 +239,3 @@ def get_transceiver_change_event(self, timeout=2000): else: return True, {} return False, {} - diff --git a/device/accton/x86_64-accton_as7712_32x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7712_32x-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as7712_32x-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as7712_32x-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as7716_32x-r0/Accton-AS7716-32X/sai.profile b/device/accton/x86_64-accton_as7716_32x-r0/Accton-AS7716-32X/sai.profile index 65944732653c..794c15a5c95a 100644 --- a/device/accton/x86_64-accton_as7716_32x-r0/Accton-AS7716-32X/sai.profile +++ b/device/accton/x86_64-accton_as7716_32x-r0/Accton-AS7716-32X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-as7716-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as7716_32x-r0/Accton-AS7716-32X/th-as7716-32x100G.config.bcm b/device/accton/x86_64-accton_as7716_32x-r0/Accton-AS7716-32X/th-as7716-32x100G.config.bcm index 1231bf302be7..1aa9f5d2c16b 100644 --- a/device/accton/x86_64-accton_as7716_32x-r0/Accton-AS7716-32X/th-as7716-32x100G.config.bcm +++ b/device/accton/x86_64-accton_as7716_32x-r0/Accton-AS7716-32X/th-as7716-32x100G.config.bcm @@ -14,7 +14,7 @@ pbmp_xport_xe=0x444444451111111144444444422222222 # arl_clean_timeout_usec=15000000 asf_mem_profile=2 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_flags=1 bcm_stat_jumbo=9236 cdma_timeout_usec=15000000 diff --git a/device/accton/x86_64-accton_as7716_32x-r0/plugins/eeprom.py b/device/accton/x86_64-accton_as7716_32x-r0/plugins/eeprom.py index c0122e65844a..9e4e9970e9f5 100755 --- a/device/accton/x86_64-accton_as7716_32x-r0/plugins/eeprom.py +++ b/device/accton/x86_64-accton_as7716_32x-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -11,14 +8,16 @@ 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") +except ImportError as 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/1-0056/eeprom" - #Two i2c buses might get flipped order, check them both. + # Two i2c buses might get flipped order, check them both. if not os.path.exists(self.eeprom_path): self.eeprom_path = "/sys/bus/i2c/devices/0-0056/eeprom" super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/accton/x86_64-accton_as7716_32x-r0/plugins/psuutil.py b/device/accton/x86_64-accton_as7716_32x-r0/plugins/psuutil.py index d8fddc23550b..5c18e6f51b8e 100755 --- a/device/accton/x86_64-accton_as7716_32x-r0/plugins/psuutil.py +++ b/device/accton/x86_64-accton_as7716_32x-r0/plugins/psuutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Accton # @@ -13,7 +11,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" diff --git a/device/accton/x86_64-accton_as7716_32x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7716_32x-r0/plugins/sfputil.py index b8e4e8d1317d..7af5098d52f0 100755 --- a/device/accton/x86_64-accton_as7716_32x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7716_32x-r0/plugins/sfputil.py @@ -10,7 +10,7 @@ from sonic_sfp.sfputilbase import SfpUtilBase except ImportError as e: raise ImportError("%s - required module not found" % str(e)) -#from xcvrd +# from xcvrd SFP_STATUS_REMOVED = '0' SFP_STATUS_INSERTED = '1' @@ -21,48 +21,48 @@ class SfpUtil(SfpUtilBase): PORT_START = 1 PORT_END = 32 PORTS_IN_BLOCK = 32 - + BASE_OOM_PATH = "/sys/bus/i2c/devices/{0}-0050/" BASE_CPLD_PATH = "/sys/bus/i2c/devices/11-0060/" - + _port_to_is_present = {} _port_to_lp_mode = {} _port_to_eeprom_mapping = {} _port_to_i2c_mapping = { - 1: 29, - 2: 30, - 3: 31, - 4: 32, - 5: 34, - 6: 33, - 7: 36, - 8: 35, - 9: 25, - 10: 26, - 11: 27, - 12: 28, - 13: 37, - 14: 38, - 15: 39, - 16: 40, - 17: 41, - 18: 42, - 19: 43, - 20: 44, - 21: 53, - 22: 54, - 23: 55, - 24: 56, - 25: 45, - 26: 46, - 27: 47, - 28: 48, - 29: 49, - 30: 50, - 31: 51, - 32: 52, - } + 1: 29, + 2: 30, + 3: 31, + 4: 32, + 5: 34, + 6: 33, + 7: 36, + 8: 35, + 9: 25, + 10: 26, + 11: 27, + 12: 28, + 13: 37, + 14: 38, + 15: 39, + 16: 40, + 17: 41, + 18: 42, + 19: 43, + 20: 44, + 21: 53, + 22: 54, + 23: 55, + 24: 56, + 25: 45, + 26: 46, + 27: 47, + 28: 48, + 29: 49, + 30: 50, + 31: 51, + 32: 52, + } @property def port_start(self): @@ -71,10 +71,10 @@ def port_start(self): @property def port_end(self): return self.PORT_END - + @property def qsfp_ports(self): - return range(self.PORT_START, self.PORTS_IN_BLOCK + 1) + return list(range(self.PORT_START, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -83,17 +83,17 @@ def port_to_eeprom_mapping(self): def __init__(self): eeprom_path = self.BASE_OOM_PATH + "eeprom" - for x in range(self.port_start, self.port_end+1): + for x in range(self.port_start, self.port_end+1): self.port_to_eeprom_mapping[x] = eeprom_path.format( self._port_to_i2c_mapping[x] - ) + ) SfpUtilBase.__init__(self) def get_presence(self, port_num): # Check for invalid port_num if port_num < self.port_start or port_num > self.port_end: return False - + present_path = self.BASE_CPLD_PATH + "module_present_" + str(port_num) self.__port_to_is_present = present_path @@ -103,9 +103,9 @@ def get_presence(self, port_num): content = val_file.readline().rstrip() val_file.close() except IOError as e: - print "Error: unable to access file: %s" % str(e) + print("Error: unable to access file: %s" % str(e)) return False - + if content == "1": return True @@ -127,20 +127,21 @@ def get_low_power_mode(self, port_num): lpmode = ord(eeprom.read(1)) if ((lpmode & 0x3) == 0x3): - return True # Low Power Mode if "Power override" bit is 1 and "Power set" bit is 1 + return True # Low Power Mode if "Power override" bit is 1 and "Power set" bit is 1 else: - return False # High Power Mode if one of the following conditions is matched: - # 1. "Power override" bit is 0 - # 2. "Power override" bit is 1 and "Power set" bit is 0 + # High Power Mode if one of the following conditions is matched: + # 1. "Power override" bit is 0 + # 2. "Power override" bit is 1 and "Power set" bit is 0 + return False except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False finally: if eeprom is not None: eeprom.close() time.sleep(0.01) - def set_low_power_mode(self, port_num, lpmode): + def set_low_power_mode(self, port_num, lpmode): # Check for invalid port_num if port_num < self.port_start or port_num > self.port_end: return False @@ -149,10 +150,10 @@ def set_low_power_mode(self, port_num, lpmode): eeprom = None if not self.get_presence(port_num): - return False # Port is not present, unable to set the eeprom + return False # Port is not present, unable to set the eeprom # Fill in write buffer - regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode + regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode buffer = create_string_buffer(1) buffer[0] = chr(regval) @@ -162,7 +163,7 @@ def set_low_power_mode(self, port_num, lpmode): eeprom.write(buffer[0]) return True except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False finally: if eeprom is not None: @@ -172,20 +173,20 @@ def set_low_power_mode(self, port_num, lpmode): def reset(self, port_num): if port_num < self.port_start or port_num > self.port_end: return False - + mod_rst_path = self.BASE_CPLD_PATH + "module_reset_" + str(port_num) self.__port_to_mod_rst = mod_rst_path try: reg_file = open(self.__port_to_mod_rst, 'r+') except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = '1' reg_file.write(reg_value) reg_file.close() - + return True @property @@ -199,16 +200,17 @@ def _get_present_bitmap(self): reg_file = open(node) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False bitmap += reg_file.readline().rstrip() + " " reg_file.close() rev = bitmap.split(" ") rev = "".join(rev[::-1]) - return int(rev,16) + return int(rev, 16) + + data = {'valid': 0, 'last': 0, 'present': 0} - data = {'valid':0, 'last':0, 'present':0} def get_transceiver_change_event(self, timeout=2000): now = time.time() port_dict = {} @@ -216,7 +218,7 @@ def get_transceiver_change_event(self, timeout=2000): if timeout < 1000: timeout = 1000 - timeout = (timeout) / float(1000) # Convert to secs + timeout = (timeout) / float(1000) # Convert to secs if now < (self.data['last'] + timeout) and self.data['valid']: return True, {} @@ -224,7 +226,7 @@ def get_transceiver_change_event(self, timeout=2000): reg_value = self._get_present_bitmap changed_ports = self.data['present'] ^ reg_value if changed_ports: - for port in range (self.port_start, self.port_end+1): + for port in range(self.port_start, self.port_end+1): # Mask off the bit corresponding to our port mask = (1 << (port - 1)) if changed_ports & mask: @@ -241,4 +243,3 @@ def get_transceiver_change_event(self, timeout=2000): else: return True, {} return False, {} - diff --git a/device/accton/x86_64-accton_as7716_32x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7716_32x-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as7716_32x-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as7716_32x-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as7716_32xb-r0/Accton-AS7716-32XB/sai.profile b/device/accton/x86_64-accton_as7716_32xb-r0/Accton-AS7716-32XB/sai.profile index 65944732653c..794c15a5c95a 100755 --- a/device/accton/x86_64-accton_as7716_32xb-r0/Accton-AS7716-32XB/sai.profile +++ b/device/accton/x86_64-accton_as7716_32xb-r0/Accton-AS7716-32XB/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-as7716-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as7716_32xb-r0/Accton-AS7716-32XB/th-as7716-32x100G.config.bcm b/device/accton/x86_64-accton_as7716_32xb-r0/Accton-AS7716-32XB/th-as7716-32x100G.config.bcm index 1231bf302be7..1aa9f5d2c16b 100644 --- a/device/accton/x86_64-accton_as7716_32xb-r0/Accton-AS7716-32XB/th-as7716-32x100G.config.bcm +++ b/device/accton/x86_64-accton_as7716_32xb-r0/Accton-AS7716-32XB/th-as7716-32x100G.config.bcm @@ -14,7 +14,7 @@ pbmp_xport_xe=0x444444451111111144444444422222222 # arl_clean_timeout_usec=15000000 asf_mem_profile=2 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_flags=1 bcm_stat_jumbo=9236 cdma_timeout_usec=15000000 diff --git a/device/accton/x86_64-accton_as7716_32xb-r0/plugins/eeprom.py b/device/accton/x86_64-accton_as7716_32xb-r0/plugins/eeprom.py index 6fa5719afbad..0982e699367a 100755 --- a/device/accton/x86_64-accton_as7716_32xb-r0/plugins/eeprom.py +++ b/device/accton/x86_64-accton_as7716_32xb-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -11,14 +8,16 @@ 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") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + class board(eeprom_tlvinfo.TlvInfoDecoder): _TLV_INFO_MAX_LEN = 256 + def __init__(self, name, path, cpld_root, ro): self.eeprom_path = "/sys/bus/i2c/devices/0-0056/eeprom" - #Two i2c buses might get flipped order, check them both. + # Two i2c buses might get flipped order, check them both. if not os.path.exists(self.eeprom_path): self.eeprom_path = "/sys/bus/i2c/devices/0-0056/eeprom" super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/accton/x86_64-accton_as7716_32xb-r0/plugins/psuutil.py b/device/accton/x86_64-accton_as7716_32xb-r0/plugins/psuutil.py index 5a4b0fe83d87..d4815ac85cec 100755 --- a/device/accton/x86_64-accton_as7716_32xb-r0/plugins/psuutil.py +++ b/device/accton/x86_64-accton_as7716_32xb-r0/plugins/psuutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Accton # @@ -13,7 +11,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" diff --git a/device/accton/x86_64-accton_as7716_32xb-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7716_32xb-r0/plugins/sfputil.py index 8bc5869e6b94..af8b9dd2fa02 100755 --- a/device/accton/x86_64-accton_as7716_32xb-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7716_32xb-r0/plugins/sfputil.py @@ -6,8 +6,8 @@ try: import time import os - import sys, getopt - import commands + import sys + import subprocess from sonic_sfp.sfputilbase import SfpUtilBase except ImportError as e: raise ImportError("%s - required module not found" % str(e)) @@ -19,49 +19,49 @@ class SfpUtil(SfpUtilBase): PORT_START = 0 PORT_END = 31 PORTS_IN_BLOCK = 32 - + BASE_OOM_PATH = "/sys/bus/i2c/devices/{0}-0050/" BASE_CPLD_PATH = "/sys/bus/i2c/devices/0-0060/" BASE_I2C_PATH = "/sys/bus/i2c/devices/" - + _port_to_is_present = {} _port_to_lp_mode = {} _port_to_eeprom_mapping = {} _port_to_i2c_mapping = { - 0: [1, 29], - 1: [2, 30], - 2: [3, 31], - 3: [4, 32], - 4: [5, 34], - 5: [6, 33], - 6: [7, 36], - 7: [8, 35], - 8: [9, 25], - 9: [10, 26], - 10: [11, 27], - 11: [12, 28], - 12: [14, 37], - 13: [15, 38], - 14: [16, 39], - 15: [17, 40], - 16: [18, 41], - 17: [19, 42], - 18: [20, 43], - 19: [21, 44], - 20: [22, 53], - 21: [23, 54], - 22: [24, 55], - 23: [25, 56], - 24: [26, 45], - 25: [27, 46], - 26: [28, 47], - 27: [29, 48], - 28: [30, 49], - 29: [31, 50], - 30: [32, 51], - 31: [33, 52], - } + 0: [1, 29], + 1: [2, 30], + 2: [3, 31], + 3: [4, 32], + 4: [5, 34], + 5: [6, 33], + 6: [7, 36], + 7: [8, 35], + 8: [9, 25], + 9: [10, 26], + 10: [11, 27], + 11: [12, 28], + 12: [14, 37], + 13: [15, 38], + 14: [16, 39], + 15: [17, 40], + 16: [18, 41], + 17: [19, 42], + 18: [20, 43], + 19: [21, 44], + 20: [22, 53], + 21: [23, 54], + 22: [24, 55], + 23: [25, 56], + 24: [26, 45], + 25: [27, 46], + 26: [28, 47], + 27: [29, 48], + 28: [30, 49], + 29: [31, 50], + 30: [32, 51], + 31: [33, 52], + } @property def port_start(self): @@ -70,20 +70,20 @@ def port_start(self): @property def port_end(self): return self.PORT_END - + @property def qsfp_ports(self): - return range(self.PORT_START, self.PORTS_IN_BLOCK + 1) + return list(range(self.PORT_START, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): return self._port_to_eeprom_mapping - + def get_presence(self, port_num): - # Check for invalid port_num + # Check for invalid port_num if port_num < self.port_start or port_num > self.port_end: return False - + present_path = self.BASE_CPLD_PATH + "module_present_" + str(port_num+1) self.__port_to_is_present = present_path @@ -93,47 +93,45 @@ def get_presence(self, port_num): content = val_file.readline().rstrip() val_file.close() except IOError as e: - print "Error: unable to access file: %s" % str(e) + print("Error: unable to access file: %s" % str(e)) return False - + if content == "1": return True return False def __init__(self): - eeprom_path = self.BASE_I2C_PATH + eeprom_path = self.BASE_I2C_PATH - for x in range(0, self.port_end+1): + for x in range(0, self.port_end+1): self.port_to_eeprom_mapping[x] = eeprom_path.format( self._port_to_i2c_mapping[x][1] - ) - if(x < 9): - if(self.get_presence(x)==1): - self.port_to_eeprom_mapping[x] = self.BASE_I2C_PATH + "0-000" +str(x+1) + "/eeprom" - + ) + if(x < 9): + if(self.get_presence(x) == 1): + self.port_to_eeprom_mapping[x] = self.BASE_I2C_PATH + "0-000" + str(x+1) + "/eeprom" + else: - if(self.get_presence(x)==1): - self.port_to_eeprom_mapping[x] = self.BASE_I2C_PATH + "0-00" +str(x+1)+ "/eeprom" - + if(self.get_presence(x) == 1): + self.port_to_eeprom_mapping[x] = self.BASE_I2C_PATH + "0-00" + str(x+1) + "/eeprom" + SfpUtilBase.__init__(self) - + def get_low_power_mode(self, port_num): + raise NotImplementedError - def get_low_power_mode(self, port_num): - raise NotImplementedError - def set_low_power_mode(self, port_num, lpmode): raise NotImplementedError def reset(self, port_num): if port_num < self.port_start or port_num > self.port_end: return False - - mod_rst_cmd = "ipmitool raw 0x34 0x11 " + str(port_num+1) + " 0x11 0x1" - (status, output) = commands.getstatusoutput (mod_rst_cmd) + + mod_rst_cmd = "ipmitool raw 0x34 0x11 " + str(port_num+1) + " 0x11 0x1" + subprocess.check_output(mod_rst_cmd, universal_newlines=True) return True - + def get_transceiver_change_event(self): """ TODO: This function need to be implemented diff --git a/device/accton/x86_64-accton_as7716_32xb-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7716_32xb-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as7716_32xb-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as7716_32xb-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/sai.profile b/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/sai.profile index 46f5cb3bf850..276f982e3e3d 100644 --- a/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/sai.profile +++ b/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/sai.profile @@ -1 +1,2 @@ -SAI_INIT_CONFIG_FILE=/etc/bcm/td3-as7726-32x100G.config.bcm +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-as7726-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/td3-as7726-32x100G.config.bcm b/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/td3-as7726-32x100G.config.bcm index 16cbb8d341e8..f88656bfd5cf 100755 --- a/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/td3-as7726-32x100G.config.bcm +++ b/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/td3-as7726-32x100G.config.bcm @@ -1,3 +1,4 @@ +sai_load_hw_config=/etc/bcm/flex/bcm56870_a0_issu/b870.6.4.1/ #polarity/lanemap is using TH2 style. core_clock_frequency=1525 dpp_clock_ratio=2:3 @@ -11,26 +12,28 @@ mem_cache_enable=0 l2_mem_entries=32768 l3_mem_entries=16384 -fpem_mem_entries=131072 +fpem_mem_entries=16384 l2xmsg_mode=1 # Platform specfic -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 cdma_timeout_usec=3000000 +ifp_inports_support_enable=1 ipv6_lpm_128b_enable=0x1 l3_max_ecmp_mode=1 -#l3_alpm_enable=2 +l3_alpm_enable=2 lpm_scaling_enable=0 max_vp_lags=0 miim_intr_enable=0 module_64ports=1 +port_flex_enable=1 schan_intr_enable=0 stable_size=0x5500000 tdma_timeout_usec=3000000 skip_L2_USER_ENTRY=0 bcm_tunnel_term_compatible_mode=1 - +l3_alpm_ipv6_128b_bkt_rsvd=1 phy_an_c73=1 dport_map_port_1=1 @@ -100,10 +103,10 @@ portmap_115=113:100 portmap_119=117:100 portmap_123=121:100 portmap_127=125:100 -portmap_66=129:10:m -portmap_130=128:10:m -portmap_65=130:10 -portmap_131=131:10 +#portmap_66=129:10:m +#portmap_130=128:10:m +#portmap_65=130:10 +#portmap_131=131:10 phy_chain_rx_lane_map_physical{1.0}=0x1320 phy_chain_rx_lane_map_physical{5.0}=0x0123 diff --git a/device/accton/x86_64-accton_as7726_32x-r0/custom_led.bin b/device/accton/x86_64-accton_as7726_32x-r0/custom_led.bin new file mode 100755 index 000000000000..73dcf0e085dc Binary files /dev/null and b/device/accton/x86_64-accton_as7726_32x-r0/custom_led.bin differ diff --git a/device/accton/x86_64-accton_as7726_32x-r0/led_proc_init.soc b/device/accton/x86_64-accton_as7726_32x-r0/led_proc_init.soc new file mode 100644 index 000000000000..1b1e6403d902 --- /dev/null +++ b/device/accton/x86_64-accton_as7726_32x-r0/led_proc_init.soc @@ -0,0 +1,4 @@ + +m0 load 0 0x3800 /usr/share/sonic/platform/custom_led.bin +led auto on +led start diff --git a/device/accton/x86_64-accton_as7726_32x-r0/plugins/eeprom.py b/device/accton/x86_64-accton_as7726_32x-r0/plugins/eeprom.py index 68ed5f9466b0..5ff41c3bac24 100755 --- a/device/accton/x86_64-accton_as7726_32x-r0/plugins/eeprom.py +++ b/device/accton/x86_64-accton_as7726_32x-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -11,14 +8,16 @@ 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") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + class board(eeprom_tlvinfo.TlvInfoDecoder): _TLV_INFO_MAX_LEN = 256 + def __init__(self, name, path, cpld_root, ro): self.eeprom_path = "/sys/bus/i2c/devices/0-0056/eeprom" - #Two i2c buses might get flipped order, check them both. + # Two i2c buses might get flipped order, check them both. if not os.path.exists(self.eeprom_path): self.eeprom_path = "/sys/bus/i2c/devices/1-0056/eeprom" super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/accton/x86_64-accton_as7726_32x-r0/plugins/psuutil.py b/device/accton/x86_64-accton_as7726_32x-r0/plugins/psuutil.py index 44fb45662d50..92b453784721 100755 --- a/device/accton/x86_64-accton_as7726_32x-r0/plugins/psuutil.py +++ b/device/accton/x86_64-accton_as7726_32x-r0/plugins/psuutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Accton # @@ -13,7 +11,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" diff --git a/device/accton/x86_64-accton_as7726_32x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7726_32x-r0/plugins/sfputil.py index f8ef438af954..350c2245fe3b 100755 --- a/device/accton/x86_64-accton_as7726_32x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7726_32x-r0/plugins/sfputil.py @@ -11,61 +11,61 @@ except ImportError as e: raise ImportError("%s - required module not found" % str(e)) -#from xcvrd +# from xcvrd SFP_STATUS_INSERTED = '1' SFP_STATUS_REMOVED = '0' class SfpUtil(SfpUtilBase): """Platform-specific SfpUtil class""" - + PORT_START = 1 - PORT_END = 32 #34 cages actually, but last 2 are not at port_config.ini. + PORT_END = 32 # 34 cages actually, but last 2 are not at port_config.ini. PORTS_IN_BLOCK = 32 - + BASE_OOM_PATH = "/sys/bus/i2c/devices/{0}-0050/" BASE_CPLD_PATH = "/sys/bus/i2c/devices/11-0060/" - + _port_to_is_present = {} _port_to_lp_mode = {} _port_to_eeprom_mapping = {} _port_to_i2c_mapping = { - 1: 21, - 2: 22, - 3: 23, - 4: 24, - 5: 26, - 6: 25, - 7: 28, - 8: 27, - 9: 17, - 10: 18, - 11: 19, - 12: 20, - 13: 29, - 14: 30, - 15: 31, - 16: 32, - 17: 33, - 18: 34, - 19: 35, - 20: 36, - 21: 45, - 22: 46, - 23: 47, - 24: 48, - 25: 37, - 26: 38, - 27: 39, - 28: 40, - 29: 41, - 30: 42, - 31: 43, - 32: 44, - 33: 15, - 34: 16, - } + 1: 21, + 2: 22, + 3: 23, + 4: 24, + 5: 26, + 6: 25, + 7: 28, + 8: 27, + 9: 17, + 10: 18, + 11: 19, + 12: 20, + 13: 29, + 14: 30, + 15: 31, + 16: 32, + 17: 33, + 18: 34, + 19: 35, + 20: 36, + 21: 45, + 22: 46, + 23: 47, + 24: 48, + 25: 37, + 26: 38, + 27: 39, + 28: 40, + 29: 41, + 30: 42, + 31: 43, + 32: 44, + 33: 15, + 34: 16, + } @property def port_start(self): @@ -74,10 +74,10 @@ def port_start(self): @property def port_end(self): return self.PORT_END - + @property def qsfp_ports(self): - return range(self.PORT_START, self.PORTS_IN_BLOCK + 1) + return list(range(self.PORT_START, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -85,11 +85,11 @@ def port_to_eeprom_mapping(self): def __init__(self): eeprom_path = self.BASE_OOM_PATH + "eeprom" - + for x in range(self.port_start, self.port_end+1): self.port_to_eeprom_mapping[x] = eeprom_path.format( self._port_to_i2c_mapping[x] - ) + ) SfpUtilBase.__init__(self) def get_presence(self, port_num): @@ -100,15 +100,15 @@ def get_presence(self, port_num): present_path = self.BASE_CPLD_PATH + "module_present_" + str(port_num) self.__port_to_is_present = present_path - content="0" + content = "0" try: val_file = open(self.__port_to_is_present) content = val_file.readline().rstrip() val_file.close() except IOError as e: - print "Error: unable to access file: %s" % str(e) + print("Error: unable to access file: %s" % str(e)) return False - + if content == "1": return True @@ -130,20 +130,21 @@ def get_low_power_mode(self, port_num): lpmode = ord(eeprom.read(1)) if ((lpmode & 0x3) == 0x3): - return True # Low Power Mode if "Power override" bit is 1 and "Power set" bit is 1 + return True # Low Power Mode if "Power override" bit is 1 and "Power set" bit is 1 else: - return False # High Power Mode if one of the following conditions is matched: - # 1. "Power override" bit is 0 - # 2. "Power override" bit is 1 and "Power set" bit is 0 + # High Power Mode if one of the following conditions is matched: + # 1. "Power override" bit is 0 + # 2. "Power override" bit is 1 and "Power set" bit is 0 + return False except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False finally: if eeprom is not None: eeprom.close() time.sleep(0.01) - def set_low_power_mode(self, port_num, lpmode): + def set_low_power_mode(self, port_num, lpmode): # Check for invalid port_num if port_num < self.port_start or port_num > self.port_end: return False @@ -152,10 +153,10 @@ def set_low_power_mode(self, port_num, lpmode): eeprom = None if not self.get_presence(port_num): - return False # Port is not present, unable to set the eeprom + return False # Port is not present, unable to set the eeprom # Fill in write buffer - regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode + regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode buffer = create_string_buffer(1) buffer[0] = chr(regval) @@ -165,7 +166,7 @@ def set_low_power_mode(self, port_num, lpmode): eeprom.write(buffer[0]) return True except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False finally: if eeprom is not None: @@ -175,24 +176,24 @@ def set_low_power_mode(self, port_num, lpmode): def reset(self, port_num): if port_num < self.port_start or port_num > self.port_end: return False - + mod_rst_path = self.BASE_CPLD_PATH + "module_reset_" + str(port_num) - + self.__port_to_mod_rst = mod_rst_path try: reg_file = open(self.__port_to_mod_rst, 'r+', buffering=0) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False - #toggle reset + # 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 @property @@ -208,16 +209,17 @@ def get_transceiver_status(self): reg_file = open(node) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False bitmap += reg_file.readline().rstrip() + " " reg_file.close() rev = bitmap.split(" ") rev = "".join(rev[::-1]) - return int(rev,16) + return int(rev, 16) + + data = {'valid': 0, 'last': 0, 'present': 0} - data = {'valid':0, 'last':0, 'present':0} def get_transceiver_change_event(self, timeout=2000): now = time.time() port_dict = {} @@ -225,8 +227,7 @@ def get_transceiver_change_event(self, timeout=2000): if timeout < 1000: timeout = 1000 - timeout = (timeout) / float(1000) # Convert to secs - + timeout = (timeout) / float(1000) # Convert to secs if now < (self.data['last'] + timeout) and self.data['valid']: return True, {} @@ -234,7 +235,7 @@ def get_transceiver_change_event(self, timeout=2000): reg_value = self.get_transceiver_status changed_ports = self.data['present'] ^ reg_value if changed_ports: - for port in range (self.port_start, self.port_end+1): + for port in range(self.port_start, self.port_end+1): # Mask off the bit corresponding to our port fp_port = port mask = (1 << (fp_port - 1)) @@ -253,4 +254,3 @@ def get_transceiver_change_event(self, timeout=2000): else: return True, {} return False, {} - diff --git a/device/accton/x86_64-accton_as7726_32x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7726_32x-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as7726_32x-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as7726_32x-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/sai.profile b/device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/sai.profile index e2f945e9a073..7c7d74d3ce9e 100644 --- a/device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/sai.profile +++ b/device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/sai.profile @@ -1 +1,2 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-as7816-64x100G.config.bcm +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-as7816-64x25G-48x100G_row1.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/th2-as7816-64x100G.config.bcm b/device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/th2-as7816-64x100G.config.bcm deleted file mode 100644 index 2a440fbfe07c..000000000000 --- a/device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/th2-as7816-64x100G.config.bcm +++ /dev/null @@ -1,1182 +0,0 @@ -# accton_as7816_64x 64x100G SDK config -os=unix -schan_intr_enable=0 -l2_mem_entries=40960 -l2xmsg_mode=1 -l3_mem_entries=40960 -parity_correction=0 -parity_enable=0 -mmu_lossless=1 - -pbmp_xport_xe=0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -pbmp_oversubscribe=0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - -# platform specific setting -arl_clean_timeout_usec=15000000 -asf_mem_profile=2 -bcm_num_cos=8 -bcm_stat_flags=1 -bcm_stat_jumbo=9236 -cdma_timeout_usec=15000000 -dma_desc_timeout_usec=15000000 -ipv6_lpm_128b_enable=1 -l3_alpm_enable=2 -lpm_scaling_enable=0 -max_vp_lags=0 -miim_intr_enable=0 -module_64ports=1 -oversubscribe_mode=1 - -#add loopback port -# port 33 is the first loopback port -portmap_33=260:10 -# port 66 is the first management port -portmap_66=257:10 -# port 67 is the second loopback port -portmap_67=261:10 -# port 100 is the second management port -portmap_100=259:10 -# port 101 is the third loopback port -portmap_101=262:10 -# port 135 is the fourth loopback port -portmap_135=263:10 - -#Port0 -#FC18 -#dport_map_port_34=1 -dport_map_port_34=73 -dport_map_port_35=74 -dport_map_port_36=75 -dport_map_port_37=76 -portmap_34=73:100 -phy_chain_rx_lane_map_physical{73.0}=0x3210 -phy_chain_rx_lane_map_physical{74.0}=0x3210 -phy_chain_rx_lane_map_physical{75.0}=0x3210 -phy_chain_rx_lane_map_physical{76.0}=0x3210 -phy_chain_tx_lane_map_physical{73.0}=0x3021 -phy_chain_tx_lane_map_physical{74.0}=0x3021 -phy_chain_tx_lane_map_physical{75.0}=0x3021 -phy_chain_tx_lane_map_physical{76.0}=0x3021 -phy_chain_rx_polarity_flip_physical{73.0}=0x0 -phy_chain_rx_polarity_flip_physical{74.0}=0x0 -phy_chain_rx_polarity_flip_physical{75.0}=0x0 -phy_chain_rx_polarity_flip_physical{76.0}=0x1 -phy_chain_tx_polarity_flip_physical{73.0}=0x0 -phy_chain_tx_polarity_flip_physical{74.0}=0x0 -phy_chain_tx_polarity_flip_physical{75.0}=0x1 -phy_chain_tx_polarity_flip_physical{76.0}=0x0 - -#Port2 -#FC20 -#dport_map_port_39=5 -dport_map_port_39=81 -dport_map_port_40=82 -dport_map_port_41=83 -dport_map_port_42=84 -portmap_39=81:100 -phy_chain_rx_lane_map_physical{81.0}=0x1230 -phy_chain_rx_lane_map_physical{82.0}=0x1230 -phy_chain_rx_lane_map_physical{83.0}=0x1230 -phy_chain_rx_lane_map_physical{84.0}=0x1230 -phy_chain_tx_lane_map_physical{81.0}=0x1032 -phy_chain_tx_lane_map_physical{82.0}=0x1032 -phy_chain_tx_lane_map_physical{83.0}=0x1032 -phy_chain_tx_lane_map_physical{84.0}=0x1032 -phy_chain_rx_polarity_flip_physical{81.0}=0x1 -phy_chain_rx_polarity_flip_physical{82.0}=0x0 -phy_chain_rx_polarity_flip_physical{83.0}=0x1 -phy_chain_rx_polarity_flip_physical{84.0}=0x0 -phy_chain_tx_polarity_flip_physical{81.0}=0x1 -phy_chain_tx_polarity_flip_physical{82.0}=0x1 -phy_chain_tx_polarity_flip_physical{83.0}=0x1 -phy_chain_tx_polarity_flip_physical{84.0}=0x0 - -#Port4 -#FC26 -#dport_map_port_44=9 -dport_map_port_44=105 -dport_map_port_45=106 -dport_map_port_46=107 -dport_map_port_47=108 -portmap_44=105:100 -phy_chain_rx_lane_map_physical{105.0}=0x3210 -phy_chain_rx_lane_map_physical{106.0}=0x3210 -phy_chain_rx_lane_map_physical{107.0}=0x3210 -phy_chain_rx_lane_map_physical{108.0}=0x3210 -phy_chain_tx_lane_map_physical{105.0}=0x0231 -phy_chain_tx_lane_map_physical{106.0}=0x0231 -phy_chain_tx_lane_map_physical{107.0}=0x0231 -phy_chain_tx_lane_map_physical{108.0}=0x0231 -phy_chain_rx_polarity_flip_physical{105.0}=0x0 -phy_chain_rx_polarity_flip_physical{106.0}=0x0 -phy_chain_rx_polarity_flip_physical{107.0}=0x0 -phy_chain_rx_polarity_flip_physical{108.0}=0x1 -phy_chain_tx_polarity_flip_physical{105.0}=0x0 -phy_chain_tx_polarity_flip_physical{106.0}=0x1 -phy_chain_tx_polarity_flip_physical{107.0}=0x0 -phy_chain_tx_polarity_flip_physical{108.0}=0x1 - -#Port6 -#FC 28 -#dport_map_port_49=13 -dport_map_port_49=113 -dport_map_port_50=114 -dport_map_port_51=115 -dport_map_port_52=116 -portmap_49=113:100 -phy_chain_rx_lane_map_physical{113.0}=0x3021 -phy_chain_rx_lane_map_physical{114.0}=0x3021 -phy_chain_rx_lane_map_physical{115.0}=0x3021 -phy_chain_rx_lane_map_physical{116.0}=0x3021 -phy_chain_tx_lane_map_physical{113.0}=0x0312 -phy_chain_tx_lane_map_physical{114.0}=0x0312 -phy_chain_tx_lane_map_physical{115.0}=0x0312 -phy_chain_tx_lane_map_physical{116.0}=0x0312 -phy_chain_rx_polarity_flip_physical{113.0}=0x0 -phy_chain_rx_polarity_flip_physical{114.0}=0x1 -phy_chain_rx_polarity_flip_physical{115.0}=0x1 -phy_chain_rx_polarity_flip_physical{116.0}=0x0 -phy_chain_tx_polarity_flip_physical{113.0}=0x1 -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}=0x1 - -#Port8 -#FC10 -#dport_map_port_1=17 -dport_map_port_1=41 -dport_map_port_2=42 -dport_map_port_3=43 -dport_map_port_4=44 -portmap_1=41:100 -phy_chain_rx_lane_map_physical{41.0}=0x0132 -phy_chain_rx_lane_map_physical{42.0}=0x0132 -phy_chain_rx_lane_map_physical{43.0}=0x0132 -phy_chain_rx_lane_map_physical{44.0}=0x0132 -phy_chain_tx_lane_map_physical{41.0}=0x1302 -phy_chain_tx_lane_map_physical{42.0}=0x1302 -phy_chain_tx_lane_map_physical{43.0}=0x1302 -phy_chain_tx_lane_map_physical{44.0}=0x1302 -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}=0x0 -phy_chain_rx_polarity_flip_physical{44.0}=0x0 -phy_chain_tx_polarity_flip_physical{41.0}=0x1 -phy_chain_tx_polarity_flip_physical{42.0}=0x0 -phy_chain_tx_polarity_flip_physical{43.0}=0x0 -phy_chain_tx_polarity_flip_physical{44.0}=0x0 - -#Port10 -#FC12 -#dport_map_port_6=21 -dport_map_port_6=49 -dport_map_port_7=50 -dport_map_port_8=51 -dport_map_port_9=52 -portmap_6=49:100 -phy_chain_rx_lane_map_physical{49.0}=0x3210 -phy_chain_rx_lane_map_physical{50.0}=0x3210 -phy_chain_rx_lane_map_physical{51.0}=0x3210 -phy_chain_rx_lane_map_physical{52.0}=0x3210 -phy_chain_tx_lane_map_physical{49.0}=0x3102 -phy_chain_tx_lane_map_physical{50.0}=0x3102 -phy_chain_tx_lane_map_physical{51.0}=0x3102 -phy_chain_tx_lane_map_physical{52.0}=0x3102 -phy_chain_rx_polarity_flip_physical{49.0}=0x1 -phy_chain_rx_polarity_flip_physical{50.0}=0x0 -phy_chain_rx_polarity_flip_physical{51.0}=0x1 -phy_chain_rx_polarity_flip_physical{52.0}=0x0 -phy_chain_tx_polarity_flip_physical{49.0}=0x1 -phy_chain_tx_polarity_flip_physical{50.0}=0x1 -phy_chain_tx_polarity_flip_physical{51.0}=0x0 -phy_chain_tx_polarity_flip_physical{52.0}=0x1 - -#Port12 -#FC34 -#dport_map_port_68=25 -dport_map_port_68=137 -dport_map_port_69=138 -dport_map_port_70=139 -dport_map_port_71=140 -portmap_68=137:100 -phy_chain_rx_lane_map_physical{137.0}=0x3210 -phy_chain_rx_lane_map_physical{138.0}=0x3210 -phy_chain_rx_lane_map_physical{139.0}=0x3210 -phy_chain_rx_lane_map_physical{140.0}=0x3210 -phy_chain_tx_lane_map_physical{137.0}=0x0213 -phy_chain_tx_lane_map_physical{138.0}=0x0213 -phy_chain_tx_lane_map_physical{139.0}=0x0213 -phy_chain_tx_lane_map_physical{140.0}=0x0213 -phy_chain_rx_polarity_flip_physical{137.0}=0x0 -phy_chain_rx_polarity_flip_physical{138.0}=0x0 -phy_chain_rx_polarity_flip_physical{139.0}=0x1 -phy_chain_rx_polarity_flip_physical{140.0}=0x0 -phy_chain_tx_polarity_flip_physical{137.0}=0x1 -phy_chain_tx_polarity_flip_physical{138.0}=0x0 -phy_chain_tx_polarity_flip_physical{139.0}=0x0 -phy_chain_tx_polarity_flip_physical{140.0}=0x0 - -#Port14 -#FC36 -#dport_map_port_73=29 -dport_map_port_73=145 -dport_map_port_74=146 -dport_map_port_75=147 -dport_map_port_76=148 -portmap_73=145:100 -phy_chain_rx_lane_map_physical{145.0}=0x0213 -phy_chain_rx_lane_map_physical{146.0}=0x0213 -phy_chain_rx_lane_map_physical{147.0}=0x0213 -phy_chain_rx_lane_map_physical{148.0}=0x0213 -phy_chain_tx_lane_map_physical{145.0}=0x2301 -phy_chain_tx_lane_map_physical{146.0}=0x2301 -phy_chain_tx_lane_map_physical{147.0}=0x2301 -phy_chain_tx_lane_map_physical{148.0}=0x2301 -phy_chain_rx_polarity_flip_physical{145.0}=0x1 -phy_chain_rx_polarity_flip_physical{146.0}=0x1 -phy_chain_rx_polarity_flip_physical{147.0}=0x0 -phy_chain_rx_polarity_flip_physical{148.0}=0x0 -phy_chain_tx_polarity_flip_physical{145.0}=0x0 -phy_chain_tx_polarity_flip_physical{146.0}=0x0 -phy_chain_tx_polarity_flip_physical{147.0}=0x0 -phy_chain_tx_polarity_flip_physical{148.0}=0x1 - -#Port16 -#FC43 -#dport_map_port_78=33 -dport_map_port_78=173 -dport_map_port_79=174 -dport_map_port_80=175 -dport_map_port_81=176 -portmap_78=173:100 -phy_chain_rx_lane_map_physical{173.0}=0x1032 -phy_chain_rx_lane_map_physical{174.0}=0x1032 -phy_chain_rx_lane_map_physical{175.0}=0x1032 -phy_chain_rx_lane_map_physical{176.0}=0x1032 -phy_chain_tx_lane_map_physical{173.0}=0x1203 -phy_chain_tx_lane_map_physical{174.0}=0x1203 -phy_chain_tx_lane_map_physical{175.0}=0x1203 -phy_chain_tx_lane_map_physical{176.0}=0x1203 -phy_chain_rx_polarity_flip_physical{173.0}=0x0 -phy_chain_rx_polarity_flip_physical{174.0}=0x0 -phy_chain_rx_polarity_flip_physical{175.0}=0x0 -phy_chain_rx_polarity_flip_physical{176.0}=0x0 -phy_chain_tx_polarity_flip_physical{173.0}=0x1 -phy_chain_tx_polarity_flip_physical{174.0}=0x1 -phy_chain_tx_polarity_flip_physical{175.0}=0x0 -phy_chain_tx_polarity_flip_physical{176.0}=0x1 - -#Port18 -#FC45 -#dport_map_port_83=37 -dport_map_port_83=181 -dport_map_port_84=182 -dport_map_port_85=183 -dport_map_port_86=184 -portmap_83=181:100 -phy_chain_rx_lane_map_physical{181.0}=0x0312 -phy_chain_rx_lane_map_physical{182.0}=0x0312 -phy_chain_rx_lane_map_physical{183.0}=0x0312 -phy_chain_rx_lane_map_physical{184.0}=0x0312 -phy_chain_tx_lane_map_physical{181.0}=0x3120 -phy_chain_tx_lane_map_physical{182.0}=0x3120 -phy_chain_tx_lane_map_physical{183.0}=0x3120 -phy_chain_tx_lane_map_physical{184.0}=0x3120 -phy_chain_rx_polarity_flip_physical{181.0}=0x0 -phy_chain_rx_polarity_flip_physical{182.0}=0x1 -phy_chain_rx_polarity_flip_physical{183.0}=0x1 -phy_chain_rx_polarity_flip_physical{184.0}=0x0 -phy_chain_tx_polarity_flip_physical{181.0}=0x0 -phy_chain_tx_polarity_flip_physical{182.0}=0x0 -phy_chain_tx_polarity_flip_physical{183.0}=0x1 -phy_chain_tx_polarity_flip_physical{184.0}=0x0 - -#Port20 -#FC3 -#dport_map_port_11=41 -dport_map_port_11=13 -dport_map_port_12=14 -dport_map_port_13=15 -dport_map_port_14=16 -portmap_11=13:100 -phy_chain_rx_lane_map_physical{13.0}=0x3120 -phy_chain_rx_lane_map_physical{14.0}=0x3120 -phy_chain_rx_lane_map_physical{15.0}=0x3120 -phy_chain_rx_lane_map_physical{16.0}=0x3120 -phy_chain_tx_lane_map_physical{13.0}=0x3210 -phy_chain_tx_lane_map_physical{14.0}=0x3210 -phy_chain_tx_lane_map_physical{15.0}=0x3210 -phy_chain_tx_lane_map_physical{16.0}=0x3210 -phy_chain_rx_polarity_flip_physical{13.0}=0x1 -phy_chain_rx_polarity_flip_physical{14.0}=0x0 -phy_chain_rx_polarity_flip_physical{15.0}=0x1 -phy_chain_rx_polarity_flip_physical{16.0}=0x1 -phy_chain_tx_polarity_flip_physical{13.0}=0x0 -phy_chain_tx_polarity_flip_physical{14.0}=0x0 -phy_chain_tx_polarity_flip_physical{15.0}=0x0 -phy_chain_tx_polarity_flip_physical{16.0}=0x1 - -#Port22 -#FC7 -#dport_map_port_16=45 -dport_map_port_16=29 -dport_map_port_17=30 -dport_map_port_18=31 -dport_map_port_19=32 -portmap_16=29:100 -phy_chain_rx_lane_map_physical{29.0}=0x3021 -phy_chain_rx_lane_map_physical{30.0}=0x3021 -phy_chain_rx_lane_map_physical{31.0}=0x3021 -phy_chain_rx_lane_map_physical{32.0}=0x3021 -phy_chain_tx_lane_map_physical{29.0}=0x2130 -phy_chain_tx_lane_map_physical{30.0}=0x2130 -phy_chain_tx_lane_map_physical{31.0}=0x2130 -phy_chain_tx_lane_map_physical{32.0}=0x2130 -phy_chain_rx_polarity_flip_physical{29.0}=0x1 -phy_chain_rx_polarity_flip_physical{30.0}=0x0 -phy_chain_rx_polarity_flip_physical{31.0}=0x0 -phy_chain_rx_polarity_flip_physical{32.0}=0x1 -phy_chain_tx_polarity_flip_physical{29.0}=0x1 -phy_chain_tx_polarity_flip_physical{30.0}=0x0 -phy_chain_tx_polarity_flip_physical{31.0}=0x0 -phy_chain_tx_polarity_flip_physical{32.0}=0x0 - -#Port24 -#FC51 -#dport_map_port_102=49 -dport_map_port_102=205 -dport_map_port_103=206 -dport_map_port_104=207 -dport_map_port_105=208 -portmap_102=205:100 -phy_chain_rx_lane_map_physical{205.0}=0x0132 -phy_chain_rx_lane_map_physical{206.0}=0x0132 -phy_chain_rx_lane_map_physical{207.0}=0x0132 -phy_chain_rx_lane_map_physical{208.0}=0x0132 -phy_chain_tx_lane_map_physical{205.0}=0x1230 -phy_chain_tx_lane_map_physical{206.0}=0x1230 -phy_chain_tx_lane_map_physical{207.0}=0x1230 -phy_chain_tx_lane_map_physical{208.0}=0x1230 -phy_chain_rx_polarity_flip_physical{205.0}=0x1 -phy_chain_rx_polarity_flip_physical{206.0}=0x1 -phy_chain_rx_polarity_flip_physical{207.0}=0x1 -phy_chain_rx_polarity_flip_physical{208.0}=0x0 -phy_chain_tx_polarity_flip_physical{205.0}=0x0 -phy_chain_tx_polarity_flip_physical{206.0}=0x1 -phy_chain_tx_polarity_flip_physical{207.0}=0x0 -phy_chain_tx_polarity_flip_physical{208.0}=0x1 - -#Port26 -#FC53 -#dport_map_port_107=53 -dport_map_port_107=213 -dport_map_port_108=214 -dport_map_port_109=215 -dport_map_port_110=216 -portmap_107=213:100 -phy_chain_rx_lane_map_physical{213.0}=0x3210 -phy_chain_rx_lane_map_physical{214.0}=0x3210 -phy_chain_rx_lane_map_physical{215.0}=0x3210 -phy_chain_rx_lane_map_physical{216.0}=0x3210 -phy_chain_tx_lane_map_physical{213.0}=0x1230 -phy_chain_tx_lane_map_physical{214.0}=0x1230 -phy_chain_tx_lane_map_physical{215.0}=0x1230 -phy_chain_tx_lane_map_physical{216.0}=0x1230 -phy_chain_rx_polarity_flip_physical{213.0}=0x0 -phy_chain_rx_polarity_flip_physical{214.0}=0x1 -phy_chain_rx_polarity_flip_physical{215.0}=0x0 -phy_chain_rx_polarity_flip_physical{216.0}=0x1 -phy_chain_tx_polarity_flip_physical{213.0}=0x0 -phy_chain_tx_polarity_flip_physical{214.0}=0x0 -phy_chain_tx_polarity_flip_physical{215.0}=0x0 -phy_chain_tx_polarity_flip_physical{216.0}=0x1 - -#Port28 -#FC57 -#dport_map_port_112=57 -dport_map_port_112=229 -dport_map_port_113=230 -dport_map_port_114=231 -dport_map_port_115=232 -portmap_112=229:100 -phy_chain_rx_lane_map_physical{229.0}=0x2301 -phy_chain_rx_lane_map_physical{230.0}=0x2301 -phy_chain_rx_lane_map_physical{231.0}=0x2301 -phy_chain_rx_lane_map_physical{232.0}=0x2301 -phy_chain_tx_lane_map_physical{229.0}=0x3210 -phy_chain_tx_lane_map_physical{230.0}=0x3210 -phy_chain_tx_lane_map_physical{231.0}=0x3210 -phy_chain_tx_lane_map_physical{232.0}=0x3210 -phy_chain_rx_polarity_flip_physical{229.0}=0x1 -phy_chain_rx_polarity_flip_physical{230.0}=0x1 -phy_chain_rx_polarity_flip_physical{231.0}=0x0 -phy_chain_rx_polarity_flip_physical{232.0}=0x1 -phy_chain_tx_polarity_flip_physical{229.0}=0x0 -phy_chain_tx_polarity_flip_physical{230.0}=0x1 -phy_chain_tx_polarity_flip_physical{231.0}=0x0 -phy_chain_tx_polarity_flip_physical{232.0}=0x0 - -#Port30 -#FC61 -#dport_map_port_117=61 -dport_map_port_117=245 -dport_map_port_118=246 -dport_map_port_119=247 -dport_map_port_120=248 -portmap_117=245:100 -phy_chain_rx_lane_map_physical{245.0}=0x0213 -phy_chain_rx_lane_map_physical{246.0}=0x0213 -phy_chain_rx_lane_map_physical{247.0}=0x0213 -phy_chain_rx_lane_map_physical{248.0}=0x0213 -phy_chain_tx_lane_map_physical{245.0}=0x3210 -phy_chain_tx_lane_map_physical{246.0}=0x3210 -phy_chain_tx_lane_map_physical{247.0}=0x3210 -phy_chain_tx_lane_map_physical{248.0}=0x3210 -phy_chain_rx_polarity_flip_physical{245.0}=0x0 -phy_chain_rx_polarity_flip_physical{246.0}=0x0 -phy_chain_rx_polarity_flip_physical{247.0}=0x1 -phy_chain_rx_polarity_flip_physical{248.0}=0x1 -phy_chain_tx_polarity_flip_physical{245.0}=0x1 -phy_chain_tx_polarity_flip_physical{246.0}=0x0 -phy_chain_tx_polarity_flip_physical{247.0}=0x1 -phy_chain_tx_polarity_flip_physical{248.0}=0x0 - -#Port1 -#FC16 -#dport_map_port_38=65 -dport_map_port_38=65 -portmap_38=65:100 -phy_chain_rx_lane_map_physical{65.0}=0x3210 -phy_chain_tx_lane_map_physical{65.0}=0x3210 -phy_chain_rx_polarity_flip_physical{65.0}=0x0 -phy_chain_rx_polarity_flip_physical{66.0}=0x0 -phy_chain_rx_polarity_flip_physical{67.0}=0x0 -phy_chain_rx_polarity_flip_physical{68.0}=0x0 -phy_chain_tx_polarity_flip_physical{65.0}=0x1 -phy_chain_tx_polarity_flip_physical{66.0}=0x0 -phy_chain_tx_polarity_flip_physical{67.0}=0x0 -phy_chain_tx_polarity_flip_physical{68.0}=0x0 - -#Port3 -#FC22 -#dport_map_port_43=66 -dport_map_port_43=89 -portmap_43=89:100 -phy_chain_rx_lane_map_physical{89.0}=0x0132 -phy_chain_tx_lane_map_physical{89.0}=0x1203 -phy_chain_rx_polarity_flip_physical{89.0}=0x1 -phy_chain_rx_polarity_flip_physical{90.0}=0x0 -phy_chain_rx_polarity_flip_physical{91.0}=0x0 -phy_chain_rx_polarity_flip_physical{92.0}=0x1 -phy_chain_tx_polarity_flip_physical{89.0}=0x1 -phy_chain_tx_polarity_flip_physical{90.0}=0x0 -phy_chain_tx_polarity_flip_physical{91.0}=0x1 -phy_chain_tx_polarity_flip_physical{92.0}=0x1 - -#Port5 -#FC24 -#dport_map_port_48=67 -dport_map_port_48=97 -portmap_48=97:100 -phy_chain_rx_lane_map_physical{97.0}=0x0213 -phy_chain_tx_lane_map_physical{97.0}=0x3210 -phy_chain_rx_polarity_flip_physical{97.0}=0x1 -phy_chain_rx_polarity_flip_physical{98.0}=0x0 -phy_chain_rx_polarity_flip_physical{99.0}=0x0 -phy_chain_rx_polarity_flip_physical{100.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}=0x0 -phy_chain_tx_polarity_flip_physical{100.0}=0x0 - -#Port7 -#FC30 -#dport_map_port_53=68 -dport_map_port_53=121 -portmap_53=121:100 -phy_chain_rx_lane_map_physical{121.0}=0x3021 -phy_chain_tx_lane_map_physical{121.0}=0x2130 -phy_chain_rx_polarity_flip_physical{121.0}=0x0 -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_tx_polarity_flip_physical{121.0}=0x1 -phy_chain_tx_polarity_flip_physical{122.0}=0x1 -phy_chain_tx_polarity_flip_physical{123.0}=0x1 -phy_chain_tx_polarity_flip_physical{124.0}=0x0 - -#Port9 -#FC8 -#dport_map_port_5=69 -dport_map_port_5=33 -portmap_5=33:100 -phy_chain_rx_lane_map_physical{33.0}=0x2310 -phy_chain_tx_lane_map_physical{33.0}=0x0213 -phy_chain_rx_polarity_flip_physical{33.0}=0x0 -phy_chain_rx_polarity_flip_physical{34.0}=0x1 -phy_chain_rx_polarity_flip_physical{35.0}=0x0 -phy_chain_rx_polarity_flip_physical{36.0}=0x0 -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}=0x0 -phy_chain_tx_polarity_flip_physical{36.0}=0x0 - -#Port11 -#FC14 -#dport_map_port_10=70 -dport_map_port_10=57 -portmap_10=57:100 -phy_chain_rx_lane_map_physical{57.0}=0x3210 -phy_chain_tx_lane_map_physical{57.0}=0x1302 -phy_chain_rx_polarity_flip_physical{57.0}=0x1 -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}=0x0 -phy_chain_tx_polarity_flip_physical{57.0}=0x0 -phy_chain_tx_polarity_flip_physical{58.0}=0x0 -phy_chain_tx_polarity_flip_physical{59.0}=0x0 -phy_chain_tx_polarity_flip_physical{60.0}=0x1 - -#Port13 -#FC32 -#dport_map_port_72=71 -dport_map_port_72=129 -portmap_72=129:100 -phy_chain_rx_lane_map_physical{129.0}=0x3021 -phy_chain_tx_lane_map_physical{129.0}=0x1203 -phy_chain_rx_polarity_flip_physical{129.0}=0x1 -phy_chain_rx_polarity_flip_physical{130.0}=0x0 -phy_chain_rx_polarity_flip_physical{131.0}=0x0 -phy_chain_rx_polarity_flip_physical{132.0}=0x0 -phy_chain_tx_polarity_flip_physical{129.0}=0x1 -phy_chain_tx_polarity_flip_physical{130.0}=0x1 -phy_chain_tx_polarity_flip_physical{131.0}=0x1 -phy_chain_tx_polarity_flip_physical{132.0}=0x1 - -#Port15 -#FC38 -#dport_map_port_77=72 -dport_map_port_77=153 -portmap_77=153:100 -phy_chain_rx_lane_map_physical{153.0}=0x0213 -phy_chain_tx_lane_map_physical{153.0}=0x1302 -phy_chain_rx_polarity_flip_physical{153.0}=0x1 -phy_chain_rx_polarity_flip_physical{154.0}=0x0 -phy_chain_rx_polarity_flip_physical{155.0}=0x1 -phy_chain_rx_polarity_flip_physical{156.0}=0x1 -phy_chain_tx_polarity_flip_physical{153.0}=0x0 -phy_chain_tx_polarity_flip_physical{154.0}=0x1 -phy_chain_tx_polarity_flip_physical{155.0}=0x0 -phy_chain_tx_polarity_flip_physical{156.0}=0x0 - -#Port17 -#FC41 -#dport_map_port_82=73 -dport_map_port_82=165 -portmap_82=165:100 -phy_chain_rx_lane_map_physical{165.0}=0x1230 -phy_chain_tx_lane_map_physical{165.0}=0x2130 -phy_chain_rx_polarity_flip_physical{165.0}=0x1 -phy_chain_rx_polarity_flip_physical{166.0}=0x0 -phy_chain_rx_polarity_flip_physical{167.0}=0x1 -phy_chain_rx_polarity_flip_physical{168.0}=0x1 -phy_chain_tx_polarity_flip_physical{165.0}=0x1 -phy_chain_tx_polarity_flip_physical{166.0}=0x0 -phy_chain_tx_polarity_flip_physical{167.0}=0x1 -phy_chain_tx_polarity_flip_physical{168.0}=0x0 - -#Port19 -#FC47 -#dport_map_port_87=74 -dport_map_port_87=189 -portmap_87=189:100 -phy_chain_rx_lane_map_physical{189.0}=0x0132 -phy_chain_tx_lane_map_physical{189.0}=0x3210 -phy_chain_rx_polarity_flip_physical{189.0}=0x0 -phy_chain_rx_polarity_flip_physical{190.0}=0x1 -phy_chain_rx_polarity_flip_physical{191.0}=0x1 -phy_chain_rx_polarity_flip_physical{192.0}=0x1 -phy_chain_tx_polarity_flip_physical{189.0}=0x1 -phy_chain_tx_polarity_flip_physical{190.0}=0x0 -phy_chain_tx_polarity_flip_physical{191.0}=0x0 -phy_chain_tx_polarity_flip_physical{192.0}=0x0 - -#Port21 -#FC1 -#dport_map_port_15=75 -dport_map_port_15=5 -portmap_15=5:100 -phy_chain_rx_lane_map_physical{5.0}=0x0213 -phy_chain_tx_lane_map_physical{5.0}=0x0321 -phy_chain_rx_polarity_flip_physical{5.0}=0x0 -phy_chain_rx_polarity_flip_physical{6.0}=0x0 -phy_chain_rx_polarity_flip_physical{7.0}=0x1 -phy_chain_rx_polarity_flip_physical{8.0}=0x0 -phy_chain_tx_polarity_flip_physical{5.0}=0x1 -phy_chain_tx_polarity_flip_physical{6.0}=0x1 -phy_chain_tx_polarity_flip_physical{7.0}=0x0 -phy_chain_tx_polarity_flip_physical{8.0}=0x1 - -#Port23 -#FC5 -#dport_map_port_20=76 -dport_map_port_20=21 -portmap_20=21:100 -phy_chain_rx_lane_map_physical{21.0}=0x0321 -phy_chain_tx_lane_map_physical{21.0}=0x0123 -phy_chain_rx_polarity_flip_physical{21.0}=0x1 -phy_chain_rx_polarity_flip_physical{22.0}=0x0 -phy_chain_rx_polarity_flip_physical{23.0}=0x1 -phy_chain_rx_polarity_flip_physical{24.0}=0x0 -phy_chain_tx_polarity_flip_physical{21.0}=0x0 -phy_chain_tx_polarity_flip_physical{22.0}=0x1 -phy_chain_tx_polarity_flip_physical{23.0}=0x1 -phy_chain_tx_polarity_flip_physical{24.0}=0x1 - -#Port25 -#FC49 -#dport_map_port_106=77 -dport_map_port_106=197 -portmap_106=197:100 -phy_chain_rx_lane_map_physical{197.0}=0x1230 -phy_chain_tx_lane_map_physical{197.0}=0x3021 -phy_chain_rx_polarity_flip_physical{197.0}=0x0 -phy_chain_rx_polarity_flip_physical{198.0}=0x0 -phy_chain_rx_polarity_flip_physical{199.0}=0x0 -phy_chain_rx_polarity_flip_physical{200.0}=0x0 -phy_chain_tx_polarity_flip_physical{197.0}=0x1 -phy_chain_tx_polarity_flip_physical{198.0}=0x0 -phy_chain_tx_polarity_flip_physical{199.0}=0x1 -phy_chain_tx_polarity_flip_physical{200.0}=0x0 - -#Port27 -#FC55 -#dport_map_port_111=78 -dport_map_port_111=221 -portmap_111=221:100 -phy_chain_rx_lane_map_physical{221.0}=0x3210 -phy_chain_tx_lane_map_physical{221.0}=0x3210 -phy_chain_rx_polarity_flip_physical{221.0}=0x1 -phy_chain_rx_polarity_flip_physical{222.0}=0x1 -phy_chain_rx_polarity_flip_physical{223.0}=0x0 -phy_chain_rx_polarity_flip_physical{224.0}=0x0 -phy_chain_tx_polarity_flip_physical{221.0}=0x0 -phy_chain_tx_polarity_flip_physical{222.0}=0x0 -phy_chain_tx_polarity_flip_physical{223.0}=0x0 -phy_chain_tx_polarity_flip_physical{224.0}=0x0 - -#Port29 -#FC59 -#dport_map_port_116=79 -dport_map_port_116=237 -portmap_116=237:100 -phy_chain_rx_lane_map_physical{237.0}=0x0123 -phy_chain_tx_lane_map_physical{237.0}=0x3210 -phy_chain_rx_polarity_flip_physical{237.0}=0x1 -phy_chain_rx_polarity_flip_physical{238.0}=0x0 -phy_chain_rx_polarity_flip_physical{239.0}=0x1 -phy_chain_rx_polarity_flip_physical{240.0}=0x1 -phy_chain_tx_polarity_flip_physical{237.0}=0x1 -phy_chain_tx_polarity_flip_physical{238.0}=0x1 -phy_chain_tx_polarity_flip_physical{239.0}=0x0 -phy_chain_tx_polarity_flip_physical{240.0}=0x0 - -#Port31 -#FC63 -#dport_map_port_121=80 -dport_map_port_121=253 -portmap_121=253:100 -phy_chain_rx_lane_map_physical{253.0}=0x0213 -phy_chain_tx_lane_map_physical{253.0}=0x0312 -phy_chain_rx_polarity_flip_physical{253.0}=0x0 -phy_chain_rx_polarity_flip_physical{254.0}=0x0 -phy_chain_rx_polarity_flip_physical{255.0}=0x0 -phy_chain_rx_polarity_flip_physical{256.0}=0x1 -phy_chain_tx_polarity_flip_physical{253.0}=0x0 -phy_chain_tx_polarity_flip_physical{254.0}=0x1 -phy_chain_tx_polarity_flip_physical{255.0}=0x0 -phy_chain_tx_polarity_flip_physical{256.0}=0x0 - -#Port32 -#FC17 -#dport_map_port_54=81 -dport_map_port_54=69 -portmap_54=69:100 -phy_chain_rx_lane_map_physical{69.0}=0x1032 -phy_chain_tx_lane_map_physical{69.0}=0x3102 -phy_chain_rx_polarity_flip_physical{69.0}=0x1 -phy_chain_rx_polarity_flip_physical{70.0}=0x0 -phy_chain_rx_polarity_flip_physical{71.0}=0x0 -phy_chain_rx_polarity_flip_physical{72.0}=0x1 -phy_chain_tx_polarity_flip_physical{69.0}=0x0 -phy_chain_tx_polarity_flip_physical{70.0}=0x0 -phy_chain_tx_polarity_flip_physical{71.0}=0x1 -phy_chain_tx_polarity_flip_physical{72.0}=0x1 -#Port33 -#FC19 -#dport_map_port_55=82 -dport_map_port_55=77 -portmap_55=77:100 -phy_chain_rx_lane_map_physical{77.0}=0x1230 -phy_chain_tx_lane_map_physical{77.0}=0x3021 -phy_chain_rx_polarity_flip_physical{77.0}=0x1 -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}=0x0 -phy_chain_tx_polarity_flip_physical{77.0}=0x0 -phy_chain_tx_polarity_flip_physical{78.0}=0x0 -phy_chain_tx_polarity_flip_physical{79.0}=0x1 -phy_chain_tx_polarity_flip_physical{80.0}=0x0 -#Port34 -#FC23 -#dport_map_port_56=83 -dport_map_port_56=93 -portmap_56=93:100 -phy_chain_rx_lane_map_physical{93.0}=0x1032 -phy_chain_tx_lane_map_physical{93.0}=0x0231 -phy_chain_rx_polarity_flip_physical{93.0}=0x1 -phy_chain_rx_polarity_flip_physical{94.0}=0x1 -phy_chain_rx_polarity_flip_physical{95.0}=0x1 -phy_chain_rx_polarity_flip_physical{96.0}=0x1 -phy_chain_tx_polarity_flip_physical{93.0}=0x0 -phy_chain_tx_polarity_flip_physical{94.0}=0x1 -phy_chain_tx_polarity_flip_physical{95.0}=0x1 -phy_chain_tx_polarity_flip_physical{96.0}=0x1 -#Port35 -#FC21 -#dport_map_port_57=84 -dport_map_port_57=85 -portmap_57=85:100 -phy_chain_rx_lane_map_physical{85.0}=0x0312 -phy_chain_tx_lane_map_physical{85.0}=0x1230 -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}=0x0 -phy_chain_rx_polarity_flip_physical{88.0}=0x1 -phy_chain_tx_polarity_flip_physical{85.0}=0x1 -phy_chain_tx_polarity_flip_physical{86.0}=0x0 -phy_chain_tx_polarity_flip_physical{87.0}=0x1 -phy_chain_tx_polarity_flip_physical{88.0}=0x0 -#Port36 -#FC25 -#dport_map_port_58=85 -dport_map_port_58=101 -portmap_58=101:100 -phy_chain_rx_lane_map_physical{101.0}=0x1302 -phy_chain_tx_lane_map_physical{101.0}=0x0213 -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}=0x0 -phy_chain_tx_polarity_flip_physical{101.0}=0x0 -phy_chain_tx_polarity_flip_physical{102.0}=0x1 -phy_chain_tx_polarity_flip_physical{103.0}=0x0 -phy_chain_tx_polarity_flip_physical{104.0}=0x1 -#Port37 -#FC27 -#dport_map_port_59=86 -dport_map_port_59=109 -portmap_59=109:100 -phy_chain_rx_lane_map_physical{109.0}=0x0213 -phy_chain_tx_lane_map_physical{109.0}=0x1032 -phy_chain_rx_polarity_flip_physical{109.0}=0x1 -phy_chain_rx_polarity_flip_physical{110.0}=0x1 -phy_chain_rx_polarity_flip_physical{111.0}=0x0 -phy_chain_rx_polarity_flip_physical{112.0}=0x0 -phy_chain_tx_polarity_flip_physical{109.0}=0x0 -phy_chain_tx_polarity_flip_physical{110.0}=0x1 -phy_chain_tx_polarity_flip_physical{111.0}=0x1 -phy_chain_tx_polarity_flip_physical{112.0}=0x1 -#Port38 -#FC31 -#dport_map_port_60=87 -dport_map_port_60=125 -portmap_60=125:100 -phy_chain_rx_lane_map_physical{125.0}=0x2130 -phy_chain_tx_lane_map_physical{125.0}=0x1203 -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_tx_polarity_flip_physical{125.0}=0x0 -phy_chain_tx_polarity_flip_physical{126.0}=0x1 -phy_chain_tx_polarity_flip_physical{127.0}=0x1 -phy_chain_tx_polarity_flip_physical{128.0}=0x1 -#Port39 -#FC29 -#dport_map_port_61=88 -dport_map_port_61=117 -portmap_61=117:100 -phy_chain_rx_lane_map_physical{117.0}=0x3102 -phy_chain_tx_lane_map_physical{117.0}=0x2310 -phy_chain_rx_polarity_flip_physical{117.0}=0x1 -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}=0x0 -phy_chain_tx_polarity_flip_physical{117.0}=0x1 -phy_chain_tx_polarity_flip_physical{118.0}=0x0 -phy_chain_tx_polarity_flip_physical{119.0}=0x1 -phy_chain_tx_polarity_flip_physical{120.0}=0x0 -#Port40 -#FC9 -#dport_map_port_21=89 -dport_map_port_21=37 -portmap_21=37:100 -phy_chain_rx_lane_map_physical{37.0}=0x3210 -phy_chain_tx_lane_map_physical{37.0}=0x1302 -phy_chain_rx_polarity_flip_physical{37.0}=0x1 -phy_chain_rx_polarity_flip_physical{38.0}=0x0 -phy_chain_rx_polarity_flip_physical{39.0}=0x0 -phy_chain_rx_polarity_flip_physical{40.0}=0x0 -phy_chain_tx_polarity_flip_physical{37.0}=0x1 -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 -#Port41 -#FC11 -#dport_map_port_22=90 -dport_map_port_22=45 -portmap_22=45:100 -phy_chain_rx_lane_map_physical{45.0}=0x3210 -phy_chain_tx_lane_map_physical{45.0}=0x0123 -phy_chain_rx_polarity_flip_physical{45.0}=0x0 -phy_chain_rx_polarity_flip_physical{46.0}=0x0 -phy_chain_rx_polarity_flip_physical{47.0}=0x0 -phy_chain_rx_polarity_flip_physical{48.0}=0x0 -phy_chain_tx_polarity_flip_physical{45.0}=0x0 -phy_chain_tx_polarity_flip_physical{46.0}=0x1 -phy_chain_tx_polarity_flip_physical{47.0}=0x0 -phy_chain_tx_polarity_flip_physical{48.0}=0x1 -#Port42 -#FC15 -#dport_map_port_23=91 -dport_map_port_23=61 -portmap_23=61:100 -phy_chain_rx_lane_map_physical{61.0}=0x3210 -phy_chain_tx_lane_map_physical{61.0}=0x1230 -phy_chain_rx_polarity_flip_physical{61.0}=0x0 -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_tx_polarity_flip_physical{61.0}=0x0 -phy_chain_tx_polarity_flip_physical{62.0}=0x1 -phy_chain_tx_polarity_flip_physical{63.0}=0x1 -phy_chain_tx_polarity_flip_physical{64.0}=0x0 -#Port43 -#FC13 -#dport_map_port_24=92 -dport_map_port_24=53 -portmap_24=53:100 -phy_chain_rx_lane_map_physical{53.0}=0x3210 -phy_chain_tx_lane_map_physical{53.0}=0x3210 -phy_chain_rx_polarity_flip_physical{53.0}=0x0 -phy_chain_rx_polarity_flip_physical{54.0}=0x0 -phy_chain_rx_polarity_flip_physical{55.0}=0x1 -phy_chain_rx_polarity_flip_physical{56.0}=0x0 -phy_chain_tx_polarity_flip_physical{53.0}=0x1 -phy_chain_tx_polarity_flip_physical{54.0}=0x1 -phy_chain_tx_polarity_flip_physical{55.0}=0x1 -phy_chain_tx_polarity_flip_physical{56.0}=0x0 -#Port44 -#FC33 -#dport_map_port_88=93 -dport_map_port_88=133 -portmap_88=133:100 -phy_chain_rx_lane_map_physical{133.0}=0x0312 -phy_chain_tx_lane_map_physical{133.0}=0x2310 -phy_chain_rx_polarity_flip_physical{133.0}=0x0 -phy_chain_rx_polarity_flip_physical{134.0}=0x0 -phy_chain_rx_polarity_flip_physical{135.0}=0x1 -phy_chain_rx_polarity_flip_physical{136.0}=0x0 -phy_chain_tx_polarity_flip_physical{133.0}=0x0 -phy_chain_tx_polarity_flip_physical{134.0}=0x1 -phy_chain_tx_polarity_flip_physical{135.0}=0x0 -phy_chain_tx_polarity_flip_physical{136.0}=0x1 -#Port45 -#FC35 -#dport_map_port_89=94 -dport_map_port_89=141 -portmap_89=141:100 -phy_chain_rx_lane_map_physical{141.0}=0x3012 -phy_chain_tx_lane_map_physical{141.0}=0x0123 -phy_chain_rx_polarity_flip_physical{141.0}=0x1 -phy_chain_rx_polarity_flip_physical{142.0}=0x0 -phy_chain_rx_polarity_flip_physical{143.0}=0x1 -phy_chain_rx_polarity_flip_physical{144.0}=0x0 -phy_chain_tx_polarity_flip_physical{141.0}=0x1 -phy_chain_tx_polarity_flip_physical{142.0}=0x1 -phy_chain_tx_polarity_flip_physical{143.0}=0x0 -phy_chain_tx_polarity_flip_physical{144.0}=0x0 -#Port46 -#FC39 -#dport_map_port_90=95 -dport_map_port_90=157 -portmap_90=157:100 -phy_chain_rx_lane_map_physical{157.0}=0x2103 -phy_chain_tx_lane_map_physical{157.0}=0x0231 -phy_chain_rx_polarity_flip_physical{157.0}=0x0 -phy_chain_rx_polarity_flip_physical{158.0}=0x0 -phy_chain_rx_polarity_flip_physical{159.0}=0x1 -phy_chain_rx_polarity_flip_physical{160.0}=0x0 -phy_chain_tx_polarity_flip_physical{157.0}=0x0 -phy_chain_tx_polarity_flip_physical{158.0}=0x1 -phy_chain_tx_polarity_flip_physical{159.0}=0x0 -phy_chain_tx_polarity_flip_physical{160.0}=0x0 -#Port47 -#FC37 -#dport_map_port_91=96 -dport_map_port_91=149 -portmap_91=149:100 -phy_chain_rx_lane_map_physical{149.0}=0x3120 -phy_chain_tx_lane_map_physical{149.0}=0x1023 -phy_chain_rx_polarity_flip_physical{149.0}=0x0 -phy_chain_rx_polarity_flip_physical{150.0}=0x1 -phy_chain_rx_polarity_flip_physical{151.0}=0x0 -phy_chain_rx_polarity_flip_physical{152.0}=0x0 -phy_chain_tx_polarity_flip_physical{149.0}=0x1 -phy_chain_tx_polarity_flip_physical{150.0}=0x0 -phy_chain_tx_polarity_flip_physical{151.0}=0x0 -phy_chain_tx_polarity_flip_physical{152.0}=0x1 -#Port48 -#FC40 -#dport_map_port_92=97 -dport_map_port_92=161 -portmap_92=161:100 -phy_chain_rx_lane_map_physical{161.0}=0x3012 -phy_chain_tx_lane_map_physical{161.0}=0x1023 -phy_chain_rx_polarity_flip_physical{161.0}=0x1 -phy_chain_rx_polarity_flip_physical{162.0}=0x1 -phy_chain_rx_polarity_flip_physical{163.0}=0x0 -phy_chain_rx_polarity_flip_physical{164.0}=0x0 -phy_chain_tx_polarity_flip_physical{161.0}=0x0 -phy_chain_tx_polarity_flip_physical{162.0}=0x1 -phy_chain_tx_polarity_flip_physical{163.0}=0x0 -phy_chain_tx_polarity_flip_physical{164.0}=0x0 -#Port49 -#FC42 -#dport_map_port_93=98 -dport_map_port_93=169 -portmap_93=169:100 -phy_chain_rx_lane_map_physical{169.0}=0x3210 -phy_chain_tx_lane_map_physical{169.0}=0x2031 -phy_chain_rx_polarity_flip_physical{169.0}=0x0 -phy_chain_rx_polarity_flip_physical{170.0}=0x1 -phy_chain_rx_polarity_flip_physical{171.0}=0x0 -phy_chain_rx_polarity_flip_physical{172.0}=0x0 -phy_chain_tx_polarity_flip_physical{169.0}=0x1 -phy_chain_tx_polarity_flip_physical{170.0}=0x0 -phy_chain_tx_polarity_flip_physical{171.0}=0x0 -phy_chain_tx_polarity_flip_physical{172.0}=0x0 -#Port50 -#FC46 -#dport_map_port_94=99 -dport_map_port_94=185 -portmap_94=185:100 -phy_chain_rx_lane_map_physical{185.0}=0x2310 -phy_chain_tx_lane_map_physical{185.0}=0x3021 -phy_chain_rx_polarity_flip_physical{185.0}=0x1 -phy_chain_rx_polarity_flip_physical{186.0}=0x0 -phy_chain_rx_polarity_flip_physical{187.0}=0x1 -phy_chain_rx_polarity_flip_physical{188.0}=0x0 -phy_chain_tx_polarity_flip_physical{185.0}=0x0 -phy_chain_tx_polarity_flip_physical{186.0}=0x1 -phy_chain_tx_polarity_flip_physical{187.0}=0x0 -phy_chain_tx_polarity_flip_physical{188.0}=0x0 -#Port51 -#FC44 -#dport_map_port_95=100 -dport_map_port_95=177 -portmap_95=177:100 -phy_chain_rx_lane_map_physical{177.0}=0x1032 -phy_chain_tx_lane_map_physical{177.0}=0x2301 -phy_chain_rx_polarity_flip_physical{177.0}=0x1 -phy_chain_rx_polarity_flip_physical{178.0}=0x1 -phy_chain_rx_polarity_flip_physical{179.0}=0x0 -phy_chain_rx_polarity_flip_physical{180.0}=0x1 -phy_chain_tx_polarity_flip_physical{177.0}=0x1 -phy_chain_tx_polarity_flip_physical{178.0}=0x1 -phy_chain_tx_polarity_flip_physical{179.0}=0x1 -phy_chain_tx_polarity_flip_physical{180.0}=0x0 - -#Port52 -#FC0 -#dport_map_port_27=103 -dport_map_port_27=1 -portmap_27=1:100 -phy_chain_rx_lane_map_physical{1.0}=0x2130 -phy_chain_tx_lane_map_physical{1.0}=0x1203 -phy_chain_rx_polarity_flip_physical{1.0}=0x1 -phy_chain_rx_polarity_flip_physical{2.0}=0x0 -phy_chain_rx_polarity_flip_physical{3.0}=0x1 -phy_chain_rx_polarity_flip_physical{4.0}=0x1 -phy_chain_tx_polarity_flip_physical{1.0}=0x0 -phy_chain_tx_polarity_flip_physical{2.0}=0x0 -phy_chain_tx_polarity_flip_physical{3.0}=0x0 -phy_chain_tx_polarity_flip_physical{4.0}=0x1 -#Port53 -#FC2 -#dport_map_port_28=104 -dport_map_port_28=9 -portmap_28=9:100 -phy_chain_rx_lane_map_physical{9.0}=0x1203 -phy_chain_tx_lane_map_physical{9.0}=0x1230 -phy_chain_rx_polarity_flip_physical{9.0}=0x0 -phy_chain_rx_polarity_flip_physical{10.0}=0x1 -phy_chain_rx_polarity_flip_physical{11.0}=0x0 -phy_chain_rx_polarity_flip_physical{12.0}=0x0 -phy_chain_tx_polarity_flip_physical{9.0}=0x1 -phy_chain_tx_polarity_flip_physical{10.0}=0x0 -phy_chain_tx_polarity_flip_physical{11.0}=0x1 -phy_chain_tx_polarity_flip_physical{12.0}=0x0 -#Port54 -#FC6 -#dport_map_port_25=101 -dport_map_port_25=25 -portmap_25=25:100 -phy_chain_rx_lane_map_physical{25.0}=0x3102 -phy_chain_tx_lane_map_physical{25.0}=0x0132 -phy_chain_rx_polarity_flip_physical{25.0}=0x0 -phy_chain_rx_polarity_flip_physical{26.0}=0x0 -phy_chain_rx_polarity_flip_physical{27.0}=0x1 -phy_chain_rx_polarity_flip_physical{28.0}=0x0 -phy_chain_tx_polarity_flip_physical{25.0}=0x0 -phy_chain_tx_polarity_flip_physical{26.0}=0x1 -phy_chain_tx_polarity_flip_physical{27.0}=0x0 -phy_chain_tx_polarity_flip_physical{28.0}=0x1 - -#Port55 -#FC4 -#dport_map_port_26=102 -dport_map_port_26=17 -portmap_26=17:100 -phy_chain_rx_lane_map_physical{17.0}=0x3120 -phy_chain_tx_lane_map_physical{17.0}=0x3021 -phy_chain_rx_polarity_flip_physical{17.0}=0x0 -phy_chain_rx_polarity_flip_physical{18.0}=0x1 -phy_chain_rx_polarity_flip_physical{19.0}=0x0 -phy_chain_rx_polarity_flip_physical{20.0}=0x0 -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}=0x1 -phy_chain_tx_polarity_flip_physical{20.0}=0x0 - -#Port56 -#FC48 -#dport_map_port_122=105 -dport_map_port_122=193 -portmap_122=193:100 -phy_chain_rx_lane_map_physical{193.0}=0x2103 -phy_chain_tx_lane_map_physical{193.0}=0x1230 -phy_chain_rx_polarity_flip_physical{193.0}=0x0 -phy_chain_rx_polarity_flip_physical{194.0}=0x1 -phy_chain_rx_polarity_flip_physical{195.0}=0x0 -phy_chain_rx_polarity_flip_physical{196.0}=0x1 -phy_chain_tx_polarity_flip_physical{193.0}=0x0 -phy_chain_tx_polarity_flip_physical{194.0}=0x0 -phy_chain_tx_polarity_flip_physical{195.0}=0x1 -phy_chain_tx_polarity_flip_physical{196.0}=0x0 -#Port57 -#FC50 -#dport_map_port_123=106 -dport_map_port_123=201 -portmap_123=201:100 -phy_chain_rx_lane_map_physical{201.0}=0x0321 -phy_chain_tx_lane_map_physical{201.0}=0x3021 -phy_chain_rx_polarity_flip_physical{201.0}=0x0 -phy_chain_rx_polarity_flip_physical{202.0}=0x0 -phy_chain_rx_polarity_flip_physical{203.0}=0x1 -phy_chain_rx_polarity_flip_physical{204.0}=0x0 -phy_chain_tx_polarity_flip_physical{201.0}=0x1 -phy_chain_tx_polarity_flip_physical{202.0}=0x1 -phy_chain_tx_polarity_flip_physical{203.0}=0x0 -phy_chain_tx_polarity_flip_physical{204.0}=0x1 -#Port58 -#FC54 -#dport_map_port_124=107 -dport_map_port_124=217 -portmap_124=217:100 -phy_chain_rx_lane_map_physical{217.0}=0x1203 -phy_chain_tx_lane_map_physical{217.0}=0x2031 -phy_chain_rx_polarity_flip_physical{217.0}=0x1 -phy_chain_rx_polarity_flip_physical{218.0}=0x0 -phy_chain_rx_polarity_flip_physical{219.0}=0x1 -phy_chain_rx_polarity_flip_physical{220.0}=0x1 -phy_chain_tx_polarity_flip_physical{217.0}=0x1 -phy_chain_tx_polarity_flip_physical{218.0}=0x0 -phy_chain_tx_polarity_flip_physical{219.0}=0x1 -phy_chain_tx_polarity_flip_physical{220.0}=0x0 -#Port59 -#FC52 -#dport_map_port_125=108 -dport_map_port_125=209 -portmap_125=209:100 -phy_chain_rx_lane_map_physical{209.0}=0x0321 -phy_chain_tx_lane_map_physical{209.0}=0x3102 -phy_chain_rx_polarity_flip_physical{209.0}=0x0 -phy_chain_rx_polarity_flip_physical{210.0}=0x0 -phy_chain_rx_polarity_flip_physical{211.0}=0x1 -phy_chain_rx_polarity_flip_physical{212.0}=0x0 -phy_chain_tx_polarity_flip_physical{209.0}=0x0 -phy_chain_tx_polarity_flip_physical{210.0}=0x0 -phy_chain_tx_polarity_flip_physical{211.0}=0x1 -phy_chain_tx_polarity_flip_physical{212.0}=0x0 -#Port60 -#FC56 -#dport_map_port_126=109 -dport_map_port_126=225 -portmap_126=225:100 -phy_chain_rx_lane_map_physical{225.0}=0x2103 -phy_chain_tx_lane_map_physical{225.0}=0x2031 -phy_chain_rx_polarity_flip_physical{225.0}=0x0 -phy_chain_rx_polarity_flip_physical{226.0}=0x0 -phy_chain_rx_polarity_flip_physical{227.0}=0x1 -phy_chain_rx_polarity_flip_physical{228.0}=0x1 -phy_chain_tx_polarity_flip_physical{225.0}=0x1 -phy_chain_tx_polarity_flip_physical{226.0}=0x0 -phy_chain_tx_polarity_flip_physical{227.0}=0x1 -phy_chain_tx_polarity_flip_physical{228.0}=0x1 -#Port61 -#FC58 -#dport_map_port_127=110 -dport_map_port_127=233 -portmap_127=233:100 -phy_chain_rx_lane_map_physical{233.0}=0x2130 -phy_chain_tx_lane_map_physical{233.0}=0x0312 -phy_chain_rx_polarity_flip_physical{233.0}=0x0 -phy_chain_rx_polarity_flip_physical{234.0}=0x1 -phy_chain_rx_polarity_flip_physical{235.0}=0x1 -phy_chain_rx_polarity_flip_physical{236.0}=0x0 -phy_chain_tx_polarity_flip_physical{233.0}=0x0 -phy_chain_tx_polarity_flip_physical{234.0}=0x0 -phy_chain_tx_polarity_flip_physical{235.0}=0x1 -phy_chain_tx_polarity_flip_physical{236.0}=0x0 -#Port62 -#FC62 -#dport_map_port_128=111 -dport_map_port_128=249 -portmap_128=249:100 -phy_chain_rx_lane_map_physical{249.0}=0x1302 -phy_chain_tx_lane_map_physical{249.0}=0x1302 -phy_chain_rx_polarity_flip_physical{249.0}=0x0 -phy_chain_rx_polarity_flip_physical{250.0}=0x1 -phy_chain_rx_polarity_flip_physical{251.0}=0x0 -phy_chain_rx_polarity_flip_physical{252.0}=0x1 -phy_chain_tx_polarity_flip_physical{249.0}=0x1 -phy_chain_tx_polarity_flip_physical{250.0}=0x1 -phy_chain_tx_polarity_flip_physical{251.0}=0x1 -phy_chain_tx_polarity_flip_physical{252.0}=0x1 -#Port63 -#FC60 -#dport_map_port_129=112 -dport_map_port_129=241 -portmap_129=241:100 -phy_chain_rx_lane_map_physical{241.0}=0x3012 -phy_chain_tx_lane_map_physical{241.0}=0x2301 -phy_chain_rx_polarity_flip_physical{241.0}=0x1 -phy_chain_rx_polarity_flip_physical{242.0}=0x1 -phy_chain_rx_polarity_flip_physical{243.0}=0x0 -phy_chain_rx_polarity_flip_physical{244.0}=0x1 -phy_chain_tx_polarity_flip_physical{241.0}=0x1 -phy_chain_tx_polarity_flip_physical{242.0}=0x0 -phy_chain_tx_polarity_flip_physical{243.0}=0x1 -phy_chain_tx_polarity_flip_physical{244.0}=0x0 diff --git a/device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/th2-as7816-64x25G-48x100G_row1.config.bcm b/device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/th2-as7816-64x25G-48x100G_row1.config.bcm new file mode 100644 index 000000000000..bceebfddaf18 --- /dev/null +++ b/device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/th2-as7816-64x25G-48x100G_row1.config.bcm @@ -0,0 +1,1183 @@ +# accton_as7816_64x 64x100G SDK config +os=unix +schan_intr_enable=0 +l2_mem_entries=40960 +l2xmsg_mode=1 +l3_mem_entries=40960 +parity_correction=0 +parity_enable=0 +mmu_lossless=1 + +pbmp_xport_xe=0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +pbmp_oversubscribe=0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + +# platform specific setting +arl_clean_timeout_usec=15000000 +asf_mem_profile=2 +bcm_num_cos=10 +bcm_stat_flags=1 +bcm_stat_jumbo=9236 +cdma_timeout_usec=15000000 +dma_desc_timeout_usec=15000000 +ipv6_lpm_128b_enable=1 +l3_alpm_enable=2 +lpm_scaling_enable=0 +max_vp_lags=0 +miim_intr_enable=0 +module_64ports=1 +oversubscribe_mode=1 +port_flex_enable=1 + +#add loopback port +# port 33 is the first loopback port +#portmap_33=260:10 +# port 66 is the first management port +#portmap_66=257:10 +# port 67 is the second loopback port +#portmap_67=261:10 +# port 100 is the second management port +#portmap_100=259:10 +# port 101 is the third loopback port +#portmap_101=262:10 +# port 135 is the fourth loopback port +#portmap_135=263:10 + +#Port0 +#FC18 +#dport_map_port_34=1 +dport_map_port_34=73 +dport_map_port_35=74 +dport_map_port_36=75 +dport_map_port_37=76 +portmap_34=73:100 +phy_chain_rx_lane_map_physical{73.0}=0x3210 +phy_chain_rx_lane_map_physical{74.0}=0x3210 +phy_chain_rx_lane_map_physical{75.0}=0x3210 +phy_chain_rx_lane_map_physical{76.0}=0x3210 +phy_chain_tx_lane_map_physical{73.0}=0x3021 +phy_chain_tx_lane_map_physical{74.0}=0x3021 +phy_chain_tx_lane_map_physical{75.0}=0x3021 +phy_chain_tx_lane_map_physical{76.0}=0x3021 +phy_chain_rx_polarity_flip_physical{73.0}=0x0 +phy_chain_rx_polarity_flip_physical{74.0}=0x0 +phy_chain_rx_polarity_flip_physical{75.0}=0x0 +phy_chain_rx_polarity_flip_physical{76.0}=0x1 +phy_chain_tx_polarity_flip_physical{73.0}=0x0 +phy_chain_tx_polarity_flip_physical{74.0}=0x0 +phy_chain_tx_polarity_flip_physical{75.0}=0x1 +phy_chain_tx_polarity_flip_physical{76.0}=0x0 + +#Port2 +#FC20 +#dport_map_port_39=5 +dport_map_port_39=81 +dport_map_port_40=82 +dport_map_port_41=83 +dport_map_port_42=84 +portmap_39=81:100 +phy_chain_rx_lane_map_physical{81.0}=0x1230 +phy_chain_rx_lane_map_physical{82.0}=0x1230 +phy_chain_rx_lane_map_physical{83.0}=0x1230 +phy_chain_rx_lane_map_physical{84.0}=0x1230 +phy_chain_tx_lane_map_physical{81.0}=0x1032 +phy_chain_tx_lane_map_physical{82.0}=0x1032 +phy_chain_tx_lane_map_physical{83.0}=0x1032 +phy_chain_tx_lane_map_physical{84.0}=0x1032 +phy_chain_rx_polarity_flip_physical{81.0}=0x1 +phy_chain_rx_polarity_flip_physical{82.0}=0x0 +phy_chain_rx_polarity_flip_physical{83.0}=0x1 +phy_chain_rx_polarity_flip_physical{84.0}=0x0 +phy_chain_tx_polarity_flip_physical{81.0}=0x1 +phy_chain_tx_polarity_flip_physical{82.0}=0x1 +phy_chain_tx_polarity_flip_physical{83.0}=0x1 +phy_chain_tx_polarity_flip_physical{84.0}=0x0 + +#Port4 +#FC26 +#dport_map_port_44=9 +dport_map_port_44=105 +dport_map_port_45=106 +dport_map_port_46=107 +dport_map_port_47=108 +portmap_44=105:100 +phy_chain_rx_lane_map_physical{105.0}=0x3210 +phy_chain_rx_lane_map_physical{106.0}=0x3210 +phy_chain_rx_lane_map_physical{107.0}=0x3210 +phy_chain_rx_lane_map_physical{108.0}=0x3210 +phy_chain_tx_lane_map_physical{105.0}=0x0231 +phy_chain_tx_lane_map_physical{106.0}=0x0231 +phy_chain_tx_lane_map_physical{107.0}=0x0231 +phy_chain_tx_lane_map_physical{108.0}=0x0231 +phy_chain_rx_polarity_flip_physical{105.0}=0x0 +phy_chain_rx_polarity_flip_physical{106.0}=0x0 +phy_chain_rx_polarity_flip_physical{107.0}=0x0 +phy_chain_rx_polarity_flip_physical{108.0}=0x1 +phy_chain_tx_polarity_flip_physical{105.0}=0x0 +phy_chain_tx_polarity_flip_physical{106.0}=0x1 +phy_chain_tx_polarity_flip_physical{107.0}=0x0 +phy_chain_tx_polarity_flip_physical{108.0}=0x1 + +#Port6 +#FC 28 +#dport_map_port_49=13 +dport_map_port_49=113 +dport_map_port_50=114 +dport_map_port_51=115 +dport_map_port_52=116 +portmap_49=113:100 +phy_chain_rx_lane_map_physical{113.0}=0x3021 +phy_chain_rx_lane_map_physical{114.0}=0x3021 +phy_chain_rx_lane_map_physical{115.0}=0x3021 +phy_chain_rx_lane_map_physical{116.0}=0x3021 +phy_chain_tx_lane_map_physical{113.0}=0x0312 +phy_chain_tx_lane_map_physical{114.0}=0x0312 +phy_chain_tx_lane_map_physical{115.0}=0x0312 +phy_chain_tx_lane_map_physical{116.0}=0x0312 +phy_chain_rx_polarity_flip_physical{113.0}=0x0 +phy_chain_rx_polarity_flip_physical{114.0}=0x1 +phy_chain_rx_polarity_flip_physical{115.0}=0x1 +phy_chain_rx_polarity_flip_physical{116.0}=0x0 +phy_chain_tx_polarity_flip_physical{113.0}=0x1 +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}=0x1 + +#Port8 +#FC10 +#dport_map_port_1=17 +dport_map_port_1=41 +dport_map_port_2=42 +dport_map_port_3=43 +dport_map_port_4=44 +portmap_1=41:100 +phy_chain_rx_lane_map_physical{41.0}=0x0132 +phy_chain_rx_lane_map_physical{42.0}=0x0132 +phy_chain_rx_lane_map_physical{43.0}=0x0132 +phy_chain_rx_lane_map_physical{44.0}=0x0132 +phy_chain_tx_lane_map_physical{41.0}=0x1302 +phy_chain_tx_lane_map_physical{42.0}=0x1302 +phy_chain_tx_lane_map_physical{43.0}=0x1302 +phy_chain_tx_lane_map_physical{44.0}=0x1302 +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}=0x0 +phy_chain_rx_polarity_flip_physical{44.0}=0x0 +phy_chain_tx_polarity_flip_physical{41.0}=0x1 +phy_chain_tx_polarity_flip_physical{42.0}=0x0 +phy_chain_tx_polarity_flip_physical{43.0}=0x0 +phy_chain_tx_polarity_flip_physical{44.0}=0x0 + +#Port10 +#FC12 +#dport_map_port_6=21 +dport_map_port_6=49 +dport_map_port_7=50 +dport_map_port_8=51 +dport_map_port_9=52 +portmap_6=49:100 +phy_chain_rx_lane_map_physical{49.0}=0x3210 +phy_chain_rx_lane_map_physical{50.0}=0x3210 +phy_chain_rx_lane_map_physical{51.0}=0x3210 +phy_chain_rx_lane_map_physical{52.0}=0x3210 +phy_chain_tx_lane_map_physical{49.0}=0x3102 +phy_chain_tx_lane_map_physical{50.0}=0x3102 +phy_chain_tx_lane_map_physical{51.0}=0x3102 +phy_chain_tx_lane_map_physical{52.0}=0x3102 +phy_chain_rx_polarity_flip_physical{49.0}=0x1 +phy_chain_rx_polarity_flip_physical{50.0}=0x0 +phy_chain_rx_polarity_flip_physical{51.0}=0x1 +phy_chain_rx_polarity_flip_physical{52.0}=0x0 +phy_chain_tx_polarity_flip_physical{49.0}=0x1 +phy_chain_tx_polarity_flip_physical{50.0}=0x1 +phy_chain_tx_polarity_flip_physical{51.0}=0x0 +phy_chain_tx_polarity_flip_physical{52.0}=0x1 + +#Port12 +#FC34 +#dport_map_port_68=25 +dport_map_port_68=137 +dport_map_port_69=138 +dport_map_port_70=139 +dport_map_port_71=140 +portmap_68=137:100 +phy_chain_rx_lane_map_physical{137.0}=0x3210 +phy_chain_rx_lane_map_physical{138.0}=0x3210 +phy_chain_rx_lane_map_physical{139.0}=0x3210 +phy_chain_rx_lane_map_physical{140.0}=0x3210 +phy_chain_tx_lane_map_physical{137.0}=0x0213 +phy_chain_tx_lane_map_physical{138.0}=0x0213 +phy_chain_tx_lane_map_physical{139.0}=0x0213 +phy_chain_tx_lane_map_physical{140.0}=0x0213 +phy_chain_rx_polarity_flip_physical{137.0}=0x0 +phy_chain_rx_polarity_flip_physical{138.0}=0x0 +phy_chain_rx_polarity_flip_physical{139.0}=0x1 +phy_chain_rx_polarity_flip_physical{140.0}=0x0 +phy_chain_tx_polarity_flip_physical{137.0}=0x1 +phy_chain_tx_polarity_flip_physical{138.0}=0x0 +phy_chain_tx_polarity_flip_physical{139.0}=0x0 +phy_chain_tx_polarity_flip_physical{140.0}=0x0 + +#Port14 +#FC36 +#dport_map_port_73=29 +dport_map_port_73=145 +dport_map_port_74=146 +dport_map_port_75=147 +dport_map_port_76=148 +portmap_73=145:100 +phy_chain_rx_lane_map_physical{145.0}=0x0213 +phy_chain_rx_lane_map_physical{146.0}=0x0213 +phy_chain_rx_lane_map_physical{147.0}=0x0213 +phy_chain_rx_lane_map_physical{148.0}=0x0213 +phy_chain_tx_lane_map_physical{145.0}=0x2301 +phy_chain_tx_lane_map_physical{146.0}=0x2301 +phy_chain_tx_lane_map_physical{147.0}=0x2301 +phy_chain_tx_lane_map_physical{148.0}=0x2301 +phy_chain_rx_polarity_flip_physical{145.0}=0x1 +phy_chain_rx_polarity_flip_physical{146.0}=0x1 +phy_chain_rx_polarity_flip_physical{147.0}=0x0 +phy_chain_rx_polarity_flip_physical{148.0}=0x0 +phy_chain_tx_polarity_flip_physical{145.0}=0x0 +phy_chain_tx_polarity_flip_physical{146.0}=0x0 +phy_chain_tx_polarity_flip_physical{147.0}=0x0 +phy_chain_tx_polarity_flip_physical{148.0}=0x1 + +#Port16 +#FC43 +#dport_map_port_78=33 +dport_map_port_78=173 +dport_map_port_79=174 +dport_map_port_80=175 +dport_map_port_81=176 +portmap_78=173:100 +phy_chain_rx_lane_map_physical{173.0}=0x1032 +phy_chain_rx_lane_map_physical{174.0}=0x1032 +phy_chain_rx_lane_map_physical{175.0}=0x1032 +phy_chain_rx_lane_map_physical{176.0}=0x1032 +phy_chain_tx_lane_map_physical{173.0}=0x1203 +phy_chain_tx_lane_map_physical{174.0}=0x1203 +phy_chain_tx_lane_map_physical{175.0}=0x1203 +phy_chain_tx_lane_map_physical{176.0}=0x1203 +phy_chain_rx_polarity_flip_physical{173.0}=0x0 +phy_chain_rx_polarity_flip_physical{174.0}=0x0 +phy_chain_rx_polarity_flip_physical{175.0}=0x0 +phy_chain_rx_polarity_flip_physical{176.0}=0x0 +phy_chain_tx_polarity_flip_physical{173.0}=0x1 +phy_chain_tx_polarity_flip_physical{174.0}=0x1 +phy_chain_tx_polarity_flip_physical{175.0}=0x0 +phy_chain_tx_polarity_flip_physical{176.0}=0x1 + +#Port18 +#FC45 +#dport_map_port_83=37 +dport_map_port_83=181 +dport_map_port_84=182 +dport_map_port_85=183 +dport_map_port_86=184 +portmap_83=181:100 +phy_chain_rx_lane_map_physical{181.0}=0x0312 +phy_chain_rx_lane_map_physical{182.0}=0x0312 +phy_chain_rx_lane_map_physical{183.0}=0x0312 +phy_chain_rx_lane_map_physical{184.0}=0x0312 +phy_chain_tx_lane_map_physical{181.0}=0x3120 +phy_chain_tx_lane_map_physical{182.0}=0x3120 +phy_chain_tx_lane_map_physical{183.0}=0x3120 +phy_chain_tx_lane_map_physical{184.0}=0x3120 +phy_chain_rx_polarity_flip_physical{181.0}=0x0 +phy_chain_rx_polarity_flip_physical{182.0}=0x1 +phy_chain_rx_polarity_flip_physical{183.0}=0x1 +phy_chain_rx_polarity_flip_physical{184.0}=0x0 +phy_chain_tx_polarity_flip_physical{181.0}=0x0 +phy_chain_tx_polarity_flip_physical{182.0}=0x0 +phy_chain_tx_polarity_flip_physical{183.0}=0x1 +phy_chain_tx_polarity_flip_physical{184.0}=0x0 + +#Port20 +#FC3 +#dport_map_port_11=41 +dport_map_port_11=13 +dport_map_port_12=14 +dport_map_port_13=15 +dport_map_port_14=16 +portmap_11=13:100 +phy_chain_rx_lane_map_physical{13.0}=0x3120 +phy_chain_rx_lane_map_physical{14.0}=0x3120 +phy_chain_rx_lane_map_physical{15.0}=0x3120 +phy_chain_rx_lane_map_physical{16.0}=0x3120 +phy_chain_tx_lane_map_physical{13.0}=0x3210 +phy_chain_tx_lane_map_physical{14.0}=0x3210 +phy_chain_tx_lane_map_physical{15.0}=0x3210 +phy_chain_tx_lane_map_physical{16.0}=0x3210 +phy_chain_rx_polarity_flip_physical{13.0}=0x1 +phy_chain_rx_polarity_flip_physical{14.0}=0x0 +phy_chain_rx_polarity_flip_physical{15.0}=0x1 +phy_chain_rx_polarity_flip_physical{16.0}=0x1 +phy_chain_tx_polarity_flip_physical{13.0}=0x0 +phy_chain_tx_polarity_flip_physical{14.0}=0x0 +phy_chain_tx_polarity_flip_physical{15.0}=0x0 +phy_chain_tx_polarity_flip_physical{16.0}=0x1 + +#Port22 +#FC7 +#dport_map_port_16=45 +dport_map_port_16=29 +dport_map_port_17=30 +dport_map_port_18=31 +dport_map_port_19=32 +portmap_16=29:100 +phy_chain_rx_lane_map_physical{29.0}=0x3021 +phy_chain_rx_lane_map_physical{30.0}=0x3021 +phy_chain_rx_lane_map_physical{31.0}=0x3021 +phy_chain_rx_lane_map_physical{32.0}=0x3021 +phy_chain_tx_lane_map_physical{29.0}=0x2130 +phy_chain_tx_lane_map_physical{30.0}=0x2130 +phy_chain_tx_lane_map_physical{31.0}=0x2130 +phy_chain_tx_lane_map_physical{32.0}=0x2130 +phy_chain_rx_polarity_flip_physical{29.0}=0x1 +phy_chain_rx_polarity_flip_physical{30.0}=0x0 +phy_chain_rx_polarity_flip_physical{31.0}=0x0 +phy_chain_rx_polarity_flip_physical{32.0}=0x1 +phy_chain_tx_polarity_flip_physical{29.0}=0x1 +phy_chain_tx_polarity_flip_physical{30.0}=0x0 +phy_chain_tx_polarity_flip_physical{31.0}=0x0 +phy_chain_tx_polarity_flip_physical{32.0}=0x0 + +#Port24 +#FC51 +#dport_map_port_102=49 +dport_map_port_102=205 +dport_map_port_103=206 +dport_map_port_104=207 +dport_map_port_105=208 +portmap_102=205:100 +phy_chain_rx_lane_map_physical{205.0}=0x0132 +phy_chain_rx_lane_map_physical{206.0}=0x0132 +phy_chain_rx_lane_map_physical{207.0}=0x0132 +phy_chain_rx_lane_map_physical{208.0}=0x0132 +phy_chain_tx_lane_map_physical{205.0}=0x1230 +phy_chain_tx_lane_map_physical{206.0}=0x1230 +phy_chain_tx_lane_map_physical{207.0}=0x1230 +phy_chain_tx_lane_map_physical{208.0}=0x1230 +phy_chain_rx_polarity_flip_physical{205.0}=0x1 +phy_chain_rx_polarity_flip_physical{206.0}=0x1 +phy_chain_rx_polarity_flip_physical{207.0}=0x1 +phy_chain_rx_polarity_flip_physical{208.0}=0x0 +phy_chain_tx_polarity_flip_physical{205.0}=0x0 +phy_chain_tx_polarity_flip_physical{206.0}=0x1 +phy_chain_tx_polarity_flip_physical{207.0}=0x0 +phy_chain_tx_polarity_flip_physical{208.0}=0x1 + +#Port26 +#FC53 +#dport_map_port_107=53 +dport_map_port_107=213 +dport_map_port_108=214 +dport_map_port_109=215 +dport_map_port_110=216 +portmap_107=213:100 +phy_chain_rx_lane_map_physical{213.0}=0x3210 +phy_chain_rx_lane_map_physical{214.0}=0x3210 +phy_chain_rx_lane_map_physical{215.0}=0x3210 +phy_chain_rx_lane_map_physical{216.0}=0x3210 +phy_chain_tx_lane_map_physical{213.0}=0x1230 +phy_chain_tx_lane_map_physical{214.0}=0x1230 +phy_chain_tx_lane_map_physical{215.0}=0x1230 +phy_chain_tx_lane_map_physical{216.0}=0x1230 +phy_chain_rx_polarity_flip_physical{213.0}=0x0 +phy_chain_rx_polarity_flip_physical{214.0}=0x1 +phy_chain_rx_polarity_flip_physical{215.0}=0x0 +phy_chain_rx_polarity_flip_physical{216.0}=0x1 +phy_chain_tx_polarity_flip_physical{213.0}=0x0 +phy_chain_tx_polarity_flip_physical{214.0}=0x0 +phy_chain_tx_polarity_flip_physical{215.0}=0x0 +phy_chain_tx_polarity_flip_physical{216.0}=0x1 + +#Port28 +#FC57 +#dport_map_port_112=57 +dport_map_port_112=229 +dport_map_port_113=230 +dport_map_port_114=231 +dport_map_port_115=232 +portmap_112=229:100 +phy_chain_rx_lane_map_physical{229.0}=0x2301 +phy_chain_rx_lane_map_physical{230.0}=0x2301 +phy_chain_rx_lane_map_physical{231.0}=0x2301 +phy_chain_rx_lane_map_physical{232.0}=0x2301 +phy_chain_tx_lane_map_physical{229.0}=0x3210 +phy_chain_tx_lane_map_physical{230.0}=0x3210 +phy_chain_tx_lane_map_physical{231.0}=0x3210 +phy_chain_tx_lane_map_physical{232.0}=0x3210 +phy_chain_rx_polarity_flip_physical{229.0}=0x1 +phy_chain_rx_polarity_flip_physical{230.0}=0x1 +phy_chain_rx_polarity_flip_physical{231.0}=0x0 +phy_chain_rx_polarity_flip_physical{232.0}=0x1 +phy_chain_tx_polarity_flip_physical{229.0}=0x0 +phy_chain_tx_polarity_flip_physical{230.0}=0x1 +phy_chain_tx_polarity_flip_physical{231.0}=0x0 +phy_chain_tx_polarity_flip_physical{232.0}=0x0 + +#Port30 +#FC61 +#dport_map_port_117=61 +dport_map_port_117=245 +dport_map_port_118=246 +dport_map_port_119=247 +dport_map_port_120=248 +portmap_117=245:100 +phy_chain_rx_lane_map_physical{245.0}=0x0213 +phy_chain_rx_lane_map_physical{246.0}=0x0213 +phy_chain_rx_lane_map_physical{247.0}=0x0213 +phy_chain_rx_lane_map_physical{248.0}=0x0213 +phy_chain_tx_lane_map_physical{245.0}=0x3210 +phy_chain_tx_lane_map_physical{246.0}=0x3210 +phy_chain_tx_lane_map_physical{247.0}=0x3210 +phy_chain_tx_lane_map_physical{248.0}=0x3210 +phy_chain_rx_polarity_flip_physical{245.0}=0x0 +phy_chain_rx_polarity_flip_physical{246.0}=0x0 +phy_chain_rx_polarity_flip_physical{247.0}=0x1 +phy_chain_rx_polarity_flip_physical{248.0}=0x1 +phy_chain_tx_polarity_flip_physical{245.0}=0x1 +phy_chain_tx_polarity_flip_physical{246.0}=0x0 +phy_chain_tx_polarity_flip_physical{247.0}=0x1 +phy_chain_tx_polarity_flip_physical{248.0}=0x0 + +#Port1 +#FC16 +#dport_map_port_38=65 +dport_map_port_38=65 +portmap_38=65:100 +phy_chain_rx_lane_map_physical{65.0}=0x3210 +phy_chain_tx_lane_map_physical{65.0}=0x3210 +phy_chain_rx_polarity_flip_physical{65.0}=0x0 +phy_chain_rx_polarity_flip_physical{66.0}=0x0 +phy_chain_rx_polarity_flip_physical{67.0}=0x0 +phy_chain_rx_polarity_flip_physical{68.0}=0x0 +phy_chain_tx_polarity_flip_physical{65.0}=0x1 +phy_chain_tx_polarity_flip_physical{66.0}=0x0 +phy_chain_tx_polarity_flip_physical{67.0}=0x0 +phy_chain_tx_polarity_flip_physical{68.0}=0x0 + +#Port3 +#FC22 +#dport_map_port_43=66 +dport_map_port_43=89 +portmap_43=89:100 +phy_chain_rx_lane_map_physical{89.0}=0x0132 +phy_chain_tx_lane_map_physical{89.0}=0x1203 +phy_chain_rx_polarity_flip_physical{89.0}=0x1 +phy_chain_rx_polarity_flip_physical{90.0}=0x0 +phy_chain_rx_polarity_flip_physical{91.0}=0x0 +phy_chain_rx_polarity_flip_physical{92.0}=0x1 +phy_chain_tx_polarity_flip_physical{89.0}=0x1 +phy_chain_tx_polarity_flip_physical{90.0}=0x0 +phy_chain_tx_polarity_flip_physical{91.0}=0x1 +phy_chain_tx_polarity_flip_physical{92.0}=0x1 + +#Port5 +#FC24 +#dport_map_port_48=67 +dport_map_port_48=97 +portmap_48=97:100 +phy_chain_rx_lane_map_physical{97.0}=0x0213 +phy_chain_tx_lane_map_physical{97.0}=0x3210 +phy_chain_rx_polarity_flip_physical{97.0}=0x1 +phy_chain_rx_polarity_flip_physical{98.0}=0x0 +phy_chain_rx_polarity_flip_physical{99.0}=0x0 +phy_chain_rx_polarity_flip_physical{100.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}=0x0 +phy_chain_tx_polarity_flip_physical{100.0}=0x0 + +#Port7 +#FC30 +#dport_map_port_53=68 +dport_map_port_53=121 +portmap_53=121:100 +phy_chain_rx_lane_map_physical{121.0}=0x3021 +phy_chain_tx_lane_map_physical{121.0}=0x2130 +phy_chain_rx_polarity_flip_physical{121.0}=0x0 +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_tx_polarity_flip_physical{121.0}=0x1 +phy_chain_tx_polarity_flip_physical{122.0}=0x1 +phy_chain_tx_polarity_flip_physical{123.0}=0x1 +phy_chain_tx_polarity_flip_physical{124.0}=0x0 + +#Port9 +#FC8 +#dport_map_port_5=69 +dport_map_port_5=33 +portmap_5=33:100 +phy_chain_rx_lane_map_physical{33.0}=0x2310 +phy_chain_tx_lane_map_physical{33.0}=0x0213 +phy_chain_rx_polarity_flip_physical{33.0}=0x0 +phy_chain_rx_polarity_flip_physical{34.0}=0x1 +phy_chain_rx_polarity_flip_physical{35.0}=0x0 +phy_chain_rx_polarity_flip_physical{36.0}=0x0 +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}=0x0 +phy_chain_tx_polarity_flip_physical{36.0}=0x0 + +#Port11 +#FC14 +#dport_map_port_10=70 +dport_map_port_10=57 +portmap_10=57:100 +phy_chain_rx_lane_map_physical{57.0}=0x3210 +phy_chain_tx_lane_map_physical{57.0}=0x1302 +phy_chain_rx_polarity_flip_physical{57.0}=0x1 +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}=0x0 +phy_chain_tx_polarity_flip_physical{57.0}=0x0 +phy_chain_tx_polarity_flip_physical{58.0}=0x0 +phy_chain_tx_polarity_flip_physical{59.0}=0x0 +phy_chain_tx_polarity_flip_physical{60.0}=0x1 + +#Port13 +#FC32 +#dport_map_port_72=71 +dport_map_port_72=129 +portmap_72=129:100 +phy_chain_rx_lane_map_physical{129.0}=0x3021 +phy_chain_tx_lane_map_physical{129.0}=0x1203 +phy_chain_rx_polarity_flip_physical{129.0}=0x1 +phy_chain_rx_polarity_flip_physical{130.0}=0x0 +phy_chain_rx_polarity_flip_physical{131.0}=0x0 +phy_chain_rx_polarity_flip_physical{132.0}=0x0 +phy_chain_tx_polarity_flip_physical{129.0}=0x1 +phy_chain_tx_polarity_flip_physical{130.0}=0x1 +phy_chain_tx_polarity_flip_physical{131.0}=0x1 +phy_chain_tx_polarity_flip_physical{132.0}=0x1 + +#Port15 +#FC38 +#dport_map_port_77=72 +dport_map_port_77=153 +portmap_77=153:100 +phy_chain_rx_lane_map_physical{153.0}=0x0213 +phy_chain_tx_lane_map_physical{153.0}=0x1302 +phy_chain_rx_polarity_flip_physical{153.0}=0x1 +phy_chain_rx_polarity_flip_physical{154.0}=0x0 +phy_chain_rx_polarity_flip_physical{155.0}=0x1 +phy_chain_rx_polarity_flip_physical{156.0}=0x1 +phy_chain_tx_polarity_flip_physical{153.0}=0x0 +phy_chain_tx_polarity_flip_physical{154.0}=0x1 +phy_chain_tx_polarity_flip_physical{155.0}=0x0 +phy_chain_tx_polarity_flip_physical{156.0}=0x0 + +#Port17 +#FC41 +#dport_map_port_82=73 +dport_map_port_82=165 +portmap_82=165:100 +phy_chain_rx_lane_map_physical{165.0}=0x1230 +phy_chain_tx_lane_map_physical{165.0}=0x2130 +phy_chain_rx_polarity_flip_physical{165.0}=0x1 +phy_chain_rx_polarity_flip_physical{166.0}=0x0 +phy_chain_rx_polarity_flip_physical{167.0}=0x1 +phy_chain_rx_polarity_flip_physical{168.0}=0x1 +phy_chain_tx_polarity_flip_physical{165.0}=0x1 +phy_chain_tx_polarity_flip_physical{166.0}=0x0 +phy_chain_tx_polarity_flip_physical{167.0}=0x1 +phy_chain_tx_polarity_flip_physical{168.0}=0x0 + +#Port19 +#FC47 +#dport_map_port_87=74 +dport_map_port_87=189 +portmap_87=189:100 +phy_chain_rx_lane_map_physical{189.0}=0x0132 +phy_chain_tx_lane_map_physical{189.0}=0x3210 +phy_chain_rx_polarity_flip_physical{189.0}=0x0 +phy_chain_rx_polarity_flip_physical{190.0}=0x1 +phy_chain_rx_polarity_flip_physical{191.0}=0x1 +phy_chain_rx_polarity_flip_physical{192.0}=0x1 +phy_chain_tx_polarity_flip_physical{189.0}=0x1 +phy_chain_tx_polarity_flip_physical{190.0}=0x0 +phy_chain_tx_polarity_flip_physical{191.0}=0x0 +phy_chain_tx_polarity_flip_physical{192.0}=0x0 + +#Port21 +#FC1 +#dport_map_port_15=75 +dport_map_port_15=5 +portmap_15=5:100 +phy_chain_rx_lane_map_physical{5.0}=0x0213 +phy_chain_tx_lane_map_physical{5.0}=0x0321 +phy_chain_rx_polarity_flip_physical{5.0}=0x0 +phy_chain_rx_polarity_flip_physical{6.0}=0x0 +phy_chain_rx_polarity_flip_physical{7.0}=0x1 +phy_chain_rx_polarity_flip_physical{8.0}=0x0 +phy_chain_tx_polarity_flip_physical{5.0}=0x1 +phy_chain_tx_polarity_flip_physical{6.0}=0x1 +phy_chain_tx_polarity_flip_physical{7.0}=0x0 +phy_chain_tx_polarity_flip_physical{8.0}=0x1 + +#Port23 +#FC5 +#dport_map_port_20=76 +dport_map_port_20=21 +portmap_20=21:100 +phy_chain_rx_lane_map_physical{21.0}=0x0321 +phy_chain_tx_lane_map_physical{21.0}=0x0123 +phy_chain_rx_polarity_flip_physical{21.0}=0x1 +phy_chain_rx_polarity_flip_physical{22.0}=0x0 +phy_chain_rx_polarity_flip_physical{23.0}=0x1 +phy_chain_rx_polarity_flip_physical{24.0}=0x0 +phy_chain_tx_polarity_flip_physical{21.0}=0x0 +phy_chain_tx_polarity_flip_physical{22.0}=0x1 +phy_chain_tx_polarity_flip_physical{23.0}=0x1 +phy_chain_tx_polarity_flip_physical{24.0}=0x1 + +#Port25 +#FC49 +#dport_map_port_106=77 +dport_map_port_106=197 +portmap_106=197:100 +phy_chain_rx_lane_map_physical{197.0}=0x1230 +phy_chain_tx_lane_map_physical{197.0}=0x3021 +phy_chain_rx_polarity_flip_physical{197.0}=0x0 +phy_chain_rx_polarity_flip_physical{198.0}=0x0 +phy_chain_rx_polarity_flip_physical{199.0}=0x0 +phy_chain_rx_polarity_flip_physical{200.0}=0x0 +phy_chain_tx_polarity_flip_physical{197.0}=0x1 +phy_chain_tx_polarity_flip_physical{198.0}=0x0 +phy_chain_tx_polarity_flip_physical{199.0}=0x1 +phy_chain_tx_polarity_flip_physical{200.0}=0x0 + +#Port27 +#FC55 +#dport_map_port_111=78 +dport_map_port_111=221 +portmap_111=221:100 +phy_chain_rx_lane_map_physical{221.0}=0x3210 +phy_chain_tx_lane_map_physical{221.0}=0x3210 +phy_chain_rx_polarity_flip_physical{221.0}=0x1 +phy_chain_rx_polarity_flip_physical{222.0}=0x1 +phy_chain_rx_polarity_flip_physical{223.0}=0x0 +phy_chain_rx_polarity_flip_physical{224.0}=0x0 +phy_chain_tx_polarity_flip_physical{221.0}=0x0 +phy_chain_tx_polarity_flip_physical{222.0}=0x0 +phy_chain_tx_polarity_flip_physical{223.0}=0x0 +phy_chain_tx_polarity_flip_physical{224.0}=0x0 + +#Port29 +#FC59 +#dport_map_port_116=79 +dport_map_port_116=237 +portmap_116=237:100 +phy_chain_rx_lane_map_physical{237.0}=0x0123 +phy_chain_tx_lane_map_physical{237.0}=0x3210 +phy_chain_rx_polarity_flip_physical{237.0}=0x1 +phy_chain_rx_polarity_flip_physical{238.0}=0x0 +phy_chain_rx_polarity_flip_physical{239.0}=0x1 +phy_chain_rx_polarity_flip_physical{240.0}=0x1 +phy_chain_tx_polarity_flip_physical{237.0}=0x1 +phy_chain_tx_polarity_flip_physical{238.0}=0x1 +phy_chain_tx_polarity_flip_physical{239.0}=0x0 +phy_chain_tx_polarity_flip_physical{240.0}=0x0 + +#Port31 +#FC63 +#dport_map_port_121=80 +dport_map_port_121=253 +portmap_121=253:100 +phy_chain_rx_lane_map_physical{253.0}=0x0213 +phy_chain_tx_lane_map_physical{253.0}=0x0312 +phy_chain_rx_polarity_flip_physical{253.0}=0x0 +phy_chain_rx_polarity_flip_physical{254.0}=0x0 +phy_chain_rx_polarity_flip_physical{255.0}=0x0 +phy_chain_rx_polarity_flip_physical{256.0}=0x1 +phy_chain_tx_polarity_flip_physical{253.0}=0x0 +phy_chain_tx_polarity_flip_physical{254.0}=0x1 +phy_chain_tx_polarity_flip_physical{255.0}=0x0 +phy_chain_tx_polarity_flip_physical{256.0}=0x0 + +#Port32 +#FC17 +#dport_map_port_54=81 +dport_map_port_54=69 +portmap_54=69:100 +phy_chain_rx_lane_map_physical{69.0}=0x1032 +phy_chain_tx_lane_map_physical{69.0}=0x3102 +phy_chain_rx_polarity_flip_physical{69.0}=0x1 +phy_chain_rx_polarity_flip_physical{70.0}=0x0 +phy_chain_rx_polarity_flip_physical{71.0}=0x0 +phy_chain_rx_polarity_flip_physical{72.0}=0x1 +phy_chain_tx_polarity_flip_physical{69.0}=0x0 +phy_chain_tx_polarity_flip_physical{70.0}=0x0 +phy_chain_tx_polarity_flip_physical{71.0}=0x1 +phy_chain_tx_polarity_flip_physical{72.0}=0x1 +#Port33 +#FC19 +#dport_map_port_55=82 +dport_map_port_55=77 +portmap_55=77:100 +phy_chain_rx_lane_map_physical{77.0}=0x1230 +phy_chain_tx_lane_map_physical{77.0}=0x3021 +phy_chain_rx_polarity_flip_physical{77.0}=0x1 +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}=0x0 +phy_chain_tx_polarity_flip_physical{77.0}=0x0 +phy_chain_tx_polarity_flip_physical{78.0}=0x0 +phy_chain_tx_polarity_flip_physical{79.0}=0x1 +phy_chain_tx_polarity_flip_physical{80.0}=0x0 +#Port34 +#FC23 +#dport_map_port_56=83 +dport_map_port_56=93 +portmap_56=93:100 +phy_chain_rx_lane_map_physical{93.0}=0x1032 +phy_chain_tx_lane_map_physical{93.0}=0x0231 +phy_chain_rx_polarity_flip_physical{93.0}=0x1 +phy_chain_rx_polarity_flip_physical{94.0}=0x1 +phy_chain_rx_polarity_flip_physical{95.0}=0x1 +phy_chain_rx_polarity_flip_physical{96.0}=0x1 +phy_chain_tx_polarity_flip_physical{93.0}=0x0 +phy_chain_tx_polarity_flip_physical{94.0}=0x1 +phy_chain_tx_polarity_flip_physical{95.0}=0x1 +phy_chain_tx_polarity_flip_physical{96.0}=0x1 +#Port35 +#FC21 +#dport_map_port_57=84 +dport_map_port_57=85 +portmap_57=85:100 +phy_chain_rx_lane_map_physical{85.0}=0x0312 +phy_chain_tx_lane_map_physical{85.0}=0x1230 +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}=0x0 +phy_chain_rx_polarity_flip_physical{88.0}=0x1 +phy_chain_tx_polarity_flip_physical{85.0}=0x1 +phy_chain_tx_polarity_flip_physical{86.0}=0x0 +phy_chain_tx_polarity_flip_physical{87.0}=0x1 +phy_chain_tx_polarity_flip_physical{88.0}=0x0 +#Port36 +#FC25 +#dport_map_port_58=85 +dport_map_port_58=101 +portmap_58=101:100 +phy_chain_rx_lane_map_physical{101.0}=0x1302 +phy_chain_tx_lane_map_physical{101.0}=0x0213 +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}=0x0 +phy_chain_tx_polarity_flip_physical{101.0}=0x0 +phy_chain_tx_polarity_flip_physical{102.0}=0x1 +phy_chain_tx_polarity_flip_physical{103.0}=0x0 +phy_chain_tx_polarity_flip_physical{104.0}=0x1 +#Port37 +#FC27 +#dport_map_port_59=86 +dport_map_port_59=109 +portmap_59=109:100 +phy_chain_rx_lane_map_physical{109.0}=0x0213 +phy_chain_tx_lane_map_physical{109.0}=0x1032 +phy_chain_rx_polarity_flip_physical{109.0}=0x1 +phy_chain_rx_polarity_flip_physical{110.0}=0x1 +phy_chain_rx_polarity_flip_physical{111.0}=0x0 +phy_chain_rx_polarity_flip_physical{112.0}=0x0 +phy_chain_tx_polarity_flip_physical{109.0}=0x0 +phy_chain_tx_polarity_flip_physical{110.0}=0x1 +phy_chain_tx_polarity_flip_physical{111.0}=0x1 +phy_chain_tx_polarity_flip_physical{112.0}=0x1 +#Port38 +#FC31 +#dport_map_port_60=87 +dport_map_port_60=125 +portmap_60=125:100 +phy_chain_rx_lane_map_physical{125.0}=0x2130 +phy_chain_tx_lane_map_physical{125.0}=0x1203 +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_tx_polarity_flip_physical{125.0}=0x0 +phy_chain_tx_polarity_flip_physical{126.0}=0x1 +phy_chain_tx_polarity_flip_physical{127.0}=0x1 +phy_chain_tx_polarity_flip_physical{128.0}=0x1 +#Port39 +#FC29 +#dport_map_port_61=88 +dport_map_port_61=117 +portmap_61=117:100 +phy_chain_rx_lane_map_physical{117.0}=0x3102 +phy_chain_tx_lane_map_physical{117.0}=0x2310 +phy_chain_rx_polarity_flip_physical{117.0}=0x1 +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}=0x0 +phy_chain_tx_polarity_flip_physical{117.0}=0x1 +phy_chain_tx_polarity_flip_physical{118.0}=0x0 +phy_chain_tx_polarity_flip_physical{119.0}=0x1 +phy_chain_tx_polarity_flip_physical{120.0}=0x0 +#Port40 +#FC9 +#dport_map_port_21=89 +dport_map_port_21=37 +portmap_21=37:100 +phy_chain_rx_lane_map_physical{37.0}=0x3210 +phy_chain_tx_lane_map_physical{37.0}=0x1302 +phy_chain_rx_polarity_flip_physical{37.0}=0x1 +phy_chain_rx_polarity_flip_physical{38.0}=0x0 +phy_chain_rx_polarity_flip_physical{39.0}=0x0 +phy_chain_rx_polarity_flip_physical{40.0}=0x0 +phy_chain_tx_polarity_flip_physical{37.0}=0x1 +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 +#Port41 +#FC11 +#dport_map_port_22=90 +dport_map_port_22=45 +portmap_22=45:100 +phy_chain_rx_lane_map_physical{45.0}=0x3210 +phy_chain_tx_lane_map_physical{45.0}=0x0123 +phy_chain_rx_polarity_flip_physical{45.0}=0x0 +phy_chain_rx_polarity_flip_physical{46.0}=0x0 +phy_chain_rx_polarity_flip_physical{47.0}=0x0 +phy_chain_rx_polarity_flip_physical{48.0}=0x0 +phy_chain_tx_polarity_flip_physical{45.0}=0x0 +phy_chain_tx_polarity_flip_physical{46.0}=0x1 +phy_chain_tx_polarity_flip_physical{47.0}=0x0 +phy_chain_tx_polarity_flip_physical{48.0}=0x1 +#Port42 +#FC15 +#dport_map_port_23=91 +dport_map_port_23=61 +portmap_23=61:100 +phy_chain_rx_lane_map_physical{61.0}=0x3210 +phy_chain_tx_lane_map_physical{61.0}=0x1230 +phy_chain_rx_polarity_flip_physical{61.0}=0x0 +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_tx_polarity_flip_physical{61.0}=0x0 +phy_chain_tx_polarity_flip_physical{62.0}=0x1 +phy_chain_tx_polarity_flip_physical{63.0}=0x1 +phy_chain_tx_polarity_flip_physical{64.0}=0x0 +#Port43 +#FC13 +#dport_map_port_24=92 +dport_map_port_24=53 +portmap_24=53:100 +phy_chain_rx_lane_map_physical{53.0}=0x3210 +phy_chain_tx_lane_map_physical{53.0}=0x3210 +phy_chain_rx_polarity_flip_physical{53.0}=0x0 +phy_chain_rx_polarity_flip_physical{54.0}=0x0 +phy_chain_rx_polarity_flip_physical{55.0}=0x1 +phy_chain_rx_polarity_flip_physical{56.0}=0x0 +phy_chain_tx_polarity_flip_physical{53.0}=0x1 +phy_chain_tx_polarity_flip_physical{54.0}=0x1 +phy_chain_tx_polarity_flip_physical{55.0}=0x1 +phy_chain_tx_polarity_flip_physical{56.0}=0x0 +#Port44 +#FC33 +#dport_map_port_88=93 +dport_map_port_88=133 +portmap_88=133:100 +phy_chain_rx_lane_map_physical{133.0}=0x0312 +phy_chain_tx_lane_map_physical{133.0}=0x2310 +phy_chain_rx_polarity_flip_physical{133.0}=0x0 +phy_chain_rx_polarity_flip_physical{134.0}=0x0 +phy_chain_rx_polarity_flip_physical{135.0}=0x1 +phy_chain_rx_polarity_flip_physical{136.0}=0x0 +phy_chain_tx_polarity_flip_physical{133.0}=0x0 +phy_chain_tx_polarity_flip_physical{134.0}=0x1 +phy_chain_tx_polarity_flip_physical{135.0}=0x0 +phy_chain_tx_polarity_flip_physical{136.0}=0x1 +#Port45 +#FC35 +#dport_map_port_89=94 +dport_map_port_89=141 +portmap_89=141:100 +phy_chain_rx_lane_map_physical{141.0}=0x3012 +phy_chain_tx_lane_map_physical{141.0}=0x0123 +phy_chain_rx_polarity_flip_physical{141.0}=0x1 +phy_chain_rx_polarity_flip_physical{142.0}=0x0 +phy_chain_rx_polarity_flip_physical{143.0}=0x1 +phy_chain_rx_polarity_flip_physical{144.0}=0x0 +phy_chain_tx_polarity_flip_physical{141.0}=0x1 +phy_chain_tx_polarity_flip_physical{142.0}=0x1 +phy_chain_tx_polarity_flip_physical{143.0}=0x0 +phy_chain_tx_polarity_flip_physical{144.0}=0x0 +#Port46 +#FC39 +#dport_map_port_90=95 +dport_map_port_90=157 +portmap_90=157:100 +phy_chain_rx_lane_map_physical{157.0}=0x2103 +phy_chain_tx_lane_map_physical{157.0}=0x0231 +phy_chain_rx_polarity_flip_physical{157.0}=0x0 +phy_chain_rx_polarity_flip_physical{158.0}=0x0 +phy_chain_rx_polarity_flip_physical{159.0}=0x1 +phy_chain_rx_polarity_flip_physical{160.0}=0x0 +phy_chain_tx_polarity_flip_physical{157.0}=0x0 +phy_chain_tx_polarity_flip_physical{158.0}=0x1 +phy_chain_tx_polarity_flip_physical{159.0}=0x0 +phy_chain_tx_polarity_flip_physical{160.0}=0x0 +#Port47 +#FC37 +#dport_map_port_91=96 +dport_map_port_91=149 +portmap_91=149:100 +phy_chain_rx_lane_map_physical{149.0}=0x3120 +phy_chain_tx_lane_map_physical{149.0}=0x1023 +phy_chain_rx_polarity_flip_physical{149.0}=0x0 +phy_chain_rx_polarity_flip_physical{150.0}=0x1 +phy_chain_rx_polarity_flip_physical{151.0}=0x0 +phy_chain_rx_polarity_flip_physical{152.0}=0x0 +phy_chain_tx_polarity_flip_physical{149.0}=0x1 +phy_chain_tx_polarity_flip_physical{150.0}=0x0 +phy_chain_tx_polarity_flip_physical{151.0}=0x0 +phy_chain_tx_polarity_flip_physical{152.0}=0x1 +#Port48 +#FC40 +#dport_map_port_92=97 +dport_map_port_92=161 +portmap_92=161:100 +phy_chain_rx_lane_map_physical{161.0}=0x3012 +phy_chain_tx_lane_map_physical{161.0}=0x1023 +phy_chain_rx_polarity_flip_physical{161.0}=0x1 +phy_chain_rx_polarity_flip_physical{162.0}=0x1 +phy_chain_rx_polarity_flip_physical{163.0}=0x0 +phy_chain_rx_polarity_flip_physical{164.0}=0x0 +phy_chain_tx_polarity_flip_physical{161.0}=0x0 +phy_chain_tx_polarity_flip_physical{162.0}=0x1 +phy_chain_tx_polarity_flip_physical{163.0}=0x0 +phy_chain_tx_polarity_flip_physical{164.0}=0x0 +#Port49 +#FC42 +#dport_map_port_93=98 +dport_map_port_93=169 +portmap_93=169:100 +phy_chain_rx_lane_map_physical{169.0}=0x3210 +phy_chain_tx_lane_map_physical{169.0}=0x2031 +phy_chain_rx_polarity_flip_physical{169.0}=0x0 +phy_chain_rx_polarity_flip_physical{170.0}=0x1 +phy_chain_rx_polarity_flip_physical{171.0}=0x0 +phy_chain_rx_polarity_flip_physical{172.0}=0x0 +phy_chain_tx_polarity_flip_physical{169.0}=0x1 +phy_chain_tx_polarity_flip_physical{170.0}=0x0 +phy_chain_tx_polarity_flip_physical{171.0}=0x0 +phy_chain_tx_polarity_flip_physical{172.0}=0x0 +#Port50 +#FC46 +#dport_map_port_94=99 +dport_map_port_94=185 +portmap_94=185:100 +phy_chain_rx_lane_map_physical{185.0}=0x2310 +phy_chain_tx_lane_map_physical{185.0}=0x3021 +phy_chain_rx_polarity_flip_physical{185.0}=0x1 +phy_chain_rx_polarity_flip_physical{186.0}=0x0 +phy_chain_rx_polarity_flip_physical{187.0}=0x1 +phy_chain_rx_polarity_flip_physical{188.0}=0x0 +phy_chain_tx_polarity_flip_physical{185.0}=0x0 +phy_chain_tx_polarity_flip_physical{186.0}=0x1 +phy_chain_tx_polarity_flip_physical{187.0}=0x0 +phy_chain_tx_polarity_flip_physical{188.0}=0x0 +#Port51 +#FC44 +#dport_map_port_95=100 +dport_map_port_95=177 +portmap_95=177:100 +phy_chain_rx_lane_map_physical{177.0}=0x1032 +phy_chain_tx_lane_map_physical{177.0}=0x2301 +phy_chain_rx_polarity_flip_physical{177.0}=0x1 +phy_chain_rx_polarity_flip_physical{178.0}=0x1 +phy_chain_rx_polarity_flip_physical{179.0}=0x0 +phy_chain_rx_polarity_flip_physical{180.0}=0x1 +phy_chain_tx_polarity_flip_physical{177.0}=0x1 +phy_chain_tx_polarity_flip_physical{178.0}=0x1 +phy_chain_tx_polarity_flip_physical{179.0}=0x1 +phy_chain_tx_polarity_flip_physical{180.0}=0x0 + +#Port52 +#FC0 +#dport_map_port_27=103 +dport_map_port_27=1 +portmap_27=1:100 +phy_chain_rx_lane_map_physical{1.0}=0x2130 +phy_chain_tx_lane_map_physical{1.0}=0x1203 +phy_chain_rx_polarity_flip_physical{1.0}=0x1 +phy_chain_rx_polarity_flip_physical{2.0}=0x0 +phy_chain_rx_polarity_flip_physical{3.0}=0x1 +phy_chain_rx_polarity_flip_physical{4.0}=0x1 +phy_chain_tx_polarity_flip_physical{1.0}=0x0 +phy_chain_tx_polarity_flip_physical{2.0}=0x0 +phy_chain_tx_polarity_flip_physical{3.0}=0x0 +phy_chain_tx_polarity_flip_physical{4.0}=0x1 +#Port53 +#FC2 +#dport_map_port_28=104 +dport_map_port_28=9 +portmap_28=9:100 +phy_chain_rx_lane_map_physical{9.0}=0x1203 +phy_chain_tx_lane_map_physical{9.0}=0x1230 +phy_chain_rx_polarity_flip_physical{9.0}=0x0 +phy_chain_rx_polarity_flip_physical{10.0}=0x1 +phy_chain_rx_polarity_flip_physical{11.0}=0x0 +phy_chain_rx_polarity_flip_physical{12.0}=0x0 +phy_chain_tx_polarity_flip_physical{9.0}=0x1 +phy_chain_tx_polarity_flip_physical{10.0}=0x0 +phy_chain_tx_polarity_flip_physical{11.0}=0x1 +phy_chain_tx_polarity_flip_physical{12.0}=0x0 +#Port54 +#FC6 +#dport_map_port_25=101 +dport_map_port_25=25 +portmap_25=25:100 +phy_chain_rx_lane_map_physical{25.0}=0x3102 +phy_chain_tx_lane_map_physical{25.0}=0x0132 +phy_chain_rx_polarity_flip_physical{25.0}=0x0 +phy_chain_rx_polarity_flip_physical{26.0}=0x0 +phy_chain_rx_polarity_flip_physical{27.0}=0x1 +phy_chain_rx_polarity_flip_physical{28.0}=0x0 +phy_chain_tx_polarity_flip_physical{25.0}=0x0 +phy_chain_tx_polarity_flip_physical{26.0}=0x1 +phy_chain_tx_polarity_flip_physical{27.0}=0x0 +phy_chain_tx_polarity_flip_physical{28.0}=0x1 + +#Port55 +#FC4 +#dport_map_port_26=102 +dport_map_port_26=17 +portmap_26=17:100 +phy_chain_rx_lane_map_physical{17.0}=0x3120 +phy_chain_tx_lane_map_physical{17.0}=0x3021 +phy_chain_rx_polarity_flip_physical{17.0}=0x0 +phy_chain_rx_polarity_flip_physical{18.0}=0x1 +phy_chain_rx_polarity_flip_physical{19.0}=0x0 +phy_chain_rx_polarity_flip_physical{20.0}=0x0 +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}=0x1 +phy_chain_tx_polarity_flip_physical{20.0}=0x0 + +#Port56 +#FC48 +#dport_map_port_122=105 +dport_map_port_122=193 +portmap_122=193:100 +phy_chain_rx_lane_map_physical{193.0}=0x2103 +phy_chain_tx_lane_map_physical{193.0}=0x1230 +phy_chain_rx_polarity_flip_physical{193.0}=0x0 +phy_chain_rx_polarity_flip_physical{194.0}=0x1 +phy_chain_rx_polarity_flip_physical{195.0}=0x0 +phy_chain_rx_polarity_flip_physical{196.0}=0x1 +phy_chain_tx_polarity_flip_physical{193.0}=0x0 +phy_chain_tx_polarity_flip_physical{194.0}=0x0 +phy_chain_tx_polarity_flip_physical{195.0}=0x1 +phy_chain_tx_polarity_flip_physical{196.0}=0x0 +#Port57 +#FC50 +#dport_map_port_123=106 +dport_map_port_123=201 +portmap_123=201:100 +phy_chain_rx_lane_map_physical{201.0}=0x0321 +phy_chain_tx_lane_map_physical{201.0}=0x3021 +phy_chain_rx_polarity_flip_physical{201.0}=0x0 +phy_chain_rx_polarity_flip_physical{202.0}=0x0 +phy_chain_rx_polarity_flip_physical{203.0}=0x1 +phy_chain_rx_polarity_flip_physical{204.0}=0x0 +phy_chain_tx_polarity_flip_physical{201.0}=0x1 +phy_chain_tx_polarity_flip_physical{202.0}=0x1 +phy_chain_tx_polarity_flip_physical{203.0}=0x0 +phy_chain_tx_polarity_flip_physical{204.0}=0x1 +#Port58 +#FC54 +#dport_map_port_124=107 +dport_map_port_124=217 +portmap_124=217:100 +phy_chain_rx_lane_map_physical{217.0}=0x1203 +phy_chain_tx_lane_map_physical{217.0}=0x2031 +phy_chain_rx_polarity_flip_physical{217.0}=0x1 +phy_chain_rx_polarity_flip_physical{218.0}=0x0 +phy_chain_rx_polarity_flip_physical{219.0}=0x1 +phy_chain_rx_polarity_flip_physical{220.0}=0x1 +phy_chain_tx_polarity_flip_physical{217.0}=0x1 +phy_chain_tx_polarity_flip_physical{218.0}=0x0 +phy_chain_tx_polarity_flip_physical{219.0}=0x1 +phy_chain_tx_polarity_flip_physical{220.0}=0x0 +#Port59 +#FC52 +#dport_map_port_125=108 +dport_map_port_125=209 +portmap_125=209:100 +phy_chain_rx_lane_map_physical{209.0}=0x0321 +phy_chain_tx_lane_map_physical{209.0}=0x3102 +phy_chain_rx_polarity_flip_physical{209.0}=0x0 +phy_chain_rx_polarity_flip_physical{210.0}=0x0 +phy_chain_rx_polarity_flip_physical{211.0}=0x1 +phy_chain_rx_polarity_flip_physical{212.0}=0x0 +phy_chain_tx_polarity_flip_physical{209.0}=0x0 +phy_chain_tx_polarity_flip_physical{210.0}=0x0 +phy_chain_tx_polarity_flip_physical{211.0}=0x1 +phy_chain_tx_polarity_flip_physical{212.0}=0x0 +#Port60 +#FC56 +#dport_map_port_126=109 +dport_map_port_126=225 +portmap_126=225:100 +phy_chain_rx_lane_map_physical{225.0}=0x2103 +phy_chain_tx_lane_map_physical{225.0}=0x2031 +phy_chain_rx_polarity_flip_physical{225.0}=0x0 +phy_chain_rx_polarity_flip_physical{226.0}=0x0 +phy_chain_rx_polarity_flip_physical{227.0}=0x1 +phy_chain_rx_polarity_flip_physical{228.0}=0x1 +phy_chain_tx_polarity_flip_physical{225.0}=0x1 +phy_chain_tx_polarity_flip_physical{226.0}=0x0 +phy_chain_tx_polarity_flip_physical{227.0}=0x1 +phy_chain_tx_polarity_flip_physical{228.0}=0x1 +#Port61 +#FC58 +#dport_map_port_127=110 +dport_map_port_127=233 +portmap_127=233:100 +phy_chain_rx_lane_map_physical{233.0}=0x2130 +phy_chain_tx_lane_map_physical{233.0}=0x0312 +phy_chain_rx_polarity_flip_physical{233.0}=0x0 +phy_chain_rx_polarity_flip_physical{234.0}=0x1 +phy_chain_rx_polarity_flip_physical{235.0}=0x1 +phy_chain_rx_polarity_flip_physical{236.0}=0x0 +phy_chain_tx_polarity_flip_physical{233.0}=0x0 +phy_chain_tx_polarity_flip_physical{234.0}=0x0 +phy_chain_tx_polarity_flip_physical{235.0}=0x1 +phy_chain_tx_polarity_flip_physical{236.0}=0x0 +#Port62 +#FC62 +#dport_map_port_128=111 +dport_map_port_128=249 +portmap_128=249:100 +phy_chain_rx_lane_map_physical{249.0}=0x1302 +phy_chain_tx_lane_map_physical{249.0}=0x1302 +phy_chain_rx_polarity_flip_physical{249.0}=0x0 +phy_chain_rx_polarity_flip_physical{250.0}=0x1 +phy_chain_rx_polarity_flip_physical{251.0}=0x0 +phy_chain_rx_polarity_flip_physical{252.0}=0x1 +phy_chain_tx_polarity_flip_physical{249.0}=0x1 +phy_chain_tx_polarity_flip_physical{250.0}=0x1 +phy_chain_tx_polarity_flip_physical{251.0}=0x1 +phy_chain_tx_polarity_flip_physical{252.0}=0x1 +#Port63 +#FC60 +#dport_map_port_129=112 +dport_map_port_129=241 +portmap_129=241:100 +phy_chain_rx_lane_map_physical{241.0}=0x3012 +phy_chain_tx_lane_map_physical{241.0}=0x2301 +phy_chain_rx_polarity_flip_physical{241.0}=0x1 +phy_chain_rx_polarity_flip_physical{242.0}=0x1 +phy_chain_rx_polarity_flip_physical{243.0}=0x0 +phy_chain_rx_polarity_flip_physical{244.0}=0x1 +phy_chain_tx_polarity_flip_physical{241.0}=0x1 +phy_chain_tx_polarity_flip_physical{242.0}=0x0 +phy_chain_tx_polarity_flip_physical{243.0}=0x1 +phy_chain_tx_polarity_flip_physical{244.0}=0x0 diff --git a/device/accton/x86_64-accton_as7816_64x-r0/plugins/eeprom.py b/device/accton/x86_64-accton_as7816_64x-r0/plugins/eeprom.py index 1e7d1046d93d..4241483d68eb 100644 --- a/device/accton/x86_64-accton_as7816_64x-r0/plugins/eeprom.py +++ b/device/accton/x86_64-accton_as7816_64x-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -11,11 +8,13 @@ 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") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + class board(eeprom_tlvinfo.TlvInfoDecoder): _TLV_INFO_MAX_LEN = 256 + def __init__(self, name, path, cpld_root, ro): self.eeprom_path = "/sys/bus/i2c/devices/0-0056/eeprom" super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/accton/x86_64-accton_as7816_64x-r0/plugins/psuutil.py b/device/accton/x86_64-accton_as7816_64x-r0/plugins/psuutil.py index 707c7c897c82..b05cf3e477ac 100755 --- a/device/accton/x86_64-accton_as7816_64x-r0/plugins/psuutil.py +++ b/device/accton/x86_64-accton_as7816_64x-r0/plugins/psuutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Accton # @@ -13,7 +11,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" diff --git a/device/accton/x86_64-accton_as7816_64x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7816_64x-r0/plugins/sfputil.py index afb6f0c74147..0520799d385a 100644 --- a/device/accton/x86_64-accton_as7816_64x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7816_64x-r0/plugins/sfputil.py @@ -1,17 +1,16 @@ -#!/usr/bin/env python - try: import time import string from ctypes import create_string_buffer - from sonic_sfp.sfputilbase import SfpUtilBase -except ImportError, e: - raise ImportError (str(e) + "- required module not found") + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") -#from xcvrd +# from xcvrd SFP_STATUS_INSERTED = '1' SFP_STATUS_REMOVED = '0' + class SfpUtil(SfpUtilBase): """Platform specific SfpUtill class""" @@ -21,72 +20,72 @@ class SfpUtil(SfpUtilBase): _port_to_eeprom_mapping = {} port_to_i2c_mapping = { - 61 : 25, - 62 : 26, - 63 : 27, - 64 : 28, - 55 : 29, - 56 : 30, - 53 : 31, - 54 : 32, - 9 : 33, - 10 : 34, - 11 : 35, - 12 : 36, - 1 : 37, - 2 : 38, - 3 : 39, - 4 : 40, - 6 : 41, - 5 : 42, - 8 : 43, - 7 : 44, - 13 : 45, - 14 : 46, - 15 : 47, - 16 : 48, - 17 : 49, - 18 : 50, - 19 : 51, - 20 : 52, - 25 : 53, - 26 : 54, - 27 : 55, - 28 : 56, - 29 : 57, - 30 : 58, - 31 : 59, - 32 : 60, - 21 : 61, - 22 : 62, - 23 : 63, - 24 : 64, - 41 : 65, - 42 : 66, - 43 : 67, - 44 : 68, - 33 : 69, - 34 : 70, - 35 : 71, - 36 : 72, - 45 : 73, - 46 : 74, - 47 : 75, - 48 : 76, - 37 : 77, - 38 : 78, - 39 : 79, - 40 : 80, - 57 : 81, - 58 : 82, - 59 : 83, - 60 : 84, - 49 : 85, - 50 : 86, - 51 : 87, - 52 : 88,} - - _qsfp_ports = range(0, ports_in_block + 1) + 61: 25, + 62: 26, + 63: 27, + 64: 28, + 55: 29, + 56: 30, + 53: 31, + 54: 32, + 9: 33, + 10: 34, + 11: 35, + 12: 36, + 1: 37, + 2: 38, + 3: 39, + 4: 40, + 6: 41, + 5: 42, + 8: 43, + 7: 44, + 13: 45, + 14: 46, + 15: 47, + 16: 48, + 17: 49, + 18: 50, + 19: 51, + 20: 52, + 25: 53, + 26: 54, + 27: 55, + 28: 56, + 29: 57, + 30: 58, + 31: 59, + 32: 60, + 21: 61, + 22: 62, + 23: 63, + 24: 64, + 41: 65, + 42: 66, + 43: 67, + 44: 68, + 33: 69, + 34: 70, + 35: 71, + 36: 72, + 45: 73, + 46: 74, + 47: 75, + 48: 76, + 37: 77, + 38: 78, + 39: 79, + 40: 80, + 57: 81, + 58: 82, + 59: 83, + 60: 84, + 49: 85, + 50: 86, + 51: 87, + 52: 88, } + + _qsfp_ports = list(range(0, ports_in_block + 1)) def __init__(self): eeprom_path = '/sys/bus/i2c/devices/{0}-0050/eeprom' @@ -99,21 +98,21 @@ 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/19-0060/module_reset_{0}" + path = "/sys/bus/i2c/devices/19-0060/module_reset_{0}" port_ps = path.format(port_num) - + try: reg_file = open(port_ps, 'w') except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False - #HW will clear reset after set. + # HW will clear reset after set. reg_file.seek(0) reg_file.write('1') reg_file.close() return True - + def get_presence(self, port_num): # Check for invalid port_num if port_num < self.port_start or port_num > self.port_end: @@ -121,16 +120,16 @@ def get_presence(self, port_num): path = "/sys/bus/i2c/devices/19-0060/module_present_{0}" port_ps = path.format(port_num) - + reg_value = '0' try: reg_file = open(port_ps) reg_value = reg_file.readline().rstrip() reg_file.close() except IOError as e: - print "Error: unable to access file: %s" % str(e) + print("Error: unable to access file: %s" % str(e)) return False - + if reg_value == '1': return True @@ -143,14 +142,14 @@ def port_start(self): @property def port_end(self): return self._port_end - + @property def qsfp_ports(self): - return range(0, self.ports_in_block + 1) + return list(range(0, self.ports_in_block + 1)) - @property + @property def port_to_eeprom_mapping(self): - return self._port_to_eeprom_mapping + return self._port_to_eeprom_mapping def get_low_power_mode(self, port_num): # Check for invalid port_num @@ -168,20 +167,21 @@ def get_low_power_mode(self, port_num): lpmode = ord(eeprom.read(1)) if ((lpmode & 0x3) == 0x3): - return True # Low Power Mode if "Power override" bit is 1 and "Power set" bit is 1 + return True # Low Power Mode if "Power override" bit is 1 and "Power set" bit is 1 else: - return False # High Power Mode if one of the following conditions is matched: - # 1. "Power override" bit is 0 - # 2. "Power override" bit is 1 and "Power set" bit is 0 + # High Power Mode if one of the following conditions is matched: + # 1. "Power override" bit is 0 + # 2. "Power override" bit is 1 and "Power set" bit is 0 + return False except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False finally: if eeprom is not None: eeprom.close() time.sleep(0.01) - def set_low_power_mode(self, port_num, lpmode): + def set_low_power_mode(self, port_num, lpmode): # Check for invalid port_num if port_num < self._port_start or port_num > self._port_end: return False @@ -190,10 +190,10 @@ def set_low_power_mode(self, port_num, lpmode): eeprom = None if not self.get_presence(port_num): - return False # Port is not present, unable to set the eeprom + return False # Port is not present, unable to set the eeprom # Fill in write buffer - regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode + regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode buffer = create_string_buffer(1) buffer[0] = chr(regval) @@ -203,7 +203,7 @@ def set_low_power_mode(self, port_num, lpmode): eeprom.write(buffer[0]) return True except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False finally: if eeprom is not None: @@ -223,17 +223,17 @@ def _get_present_bitmap(self): reg_file = open(node) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False bitmap += reg_file.readline().rstrip() + " " reg_file.close() rev = bitmap.split(" ") rev = "".join(rev[::-1]) - return int(rev,16) + return int(rev, 16) + data = {'valid': 0, 'last': 0, 'present': 0} - data = {'valid':0, 'last':0, 'present':0} def get_transceiver_change_event(self, timeout=2000): now = time.time() port_dict = {} @@ -241,7 +241,7 @@ def get_transceiver_change_event(self, timeout=2000): if timeout < 1000: timeout = 1000 - timeout = (timeout) / float(1000) # Convert to secs + timeout = (timeout) / float(1000) # Convert to secs if now < (self.data['last'] + timeout) and self.data['valid']: return True, {} @@ -250,7 +250,7 @@ def get_transceiver_change_event(self, timeout=2000): reg_value = ~reg_value changed_ports = self.data['present'] ^ reg_value if changed_ports: - for port in range (self.port_start, self.port_end+1): + for port in range(self.port_start, self.port_end+1): # Mask off the bit corresponding to our port mask = (1 << (port - 1)) if changed_ports & mask: @@ -267,4 +267,3 @@ def get_transceiver_change_event(self, timeout=2000): else: return True, {} return False, {} - diff --git a/device/accton/x86_64-accton_as7816_64x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7816_64x-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as7816_64x-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as7816_64x-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/port_config.ini b/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/port_config.ini index a13514fcd909..ab5ba53d280e 100644 --- a/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/port_config.ini +++ b/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/port_config.ini @@ -1,33 +1,33 @@ # name lanes alias index speed -Ethernet0 73,74,75,76,77,78,79,80 fourHundredGigE1 0 400000 -Ethernet4 65,66,67,68,69,70,71,72 fourHundredGigE2 1 400000 -Ethernet8 81,82,83,84,85,86,87,88 fourHundredGigE3 2 400000 -Ethernet12 89,90,91,92,93,94,95,96 fourHundredGigE4 3 400000 -Ethernet16 97,98,99,100,101,102,103,104 fourHundredGigE5 4 400000 -Ethernet20 105,106,107,108,109,110,111,112 fourHundredGigE6 5 400000 -Ethernet24 113,114,115,116,117,118,119,120 fourHundredGigE7 6 400000 -Ethernet28 121,122,123,124,125,126,127,128 fourHundredGigE8 7 400000 -Ethernet32 41,42,43,44,45,46,47,48 fourHundredGigE9 8 400000 -Ethernet36 33,34,35,36,37,38,39,40 fourHundredGigE10 9 400000 -Ethernet40 49,50,51,52,53,54,55,56 fourHundredGigE11 10 400000 -Ethernet44 57,58,59,60,61,62,63,64 fourHundredGigE12 11 400000 -Ethernet48 129,130,131,132,133,134,135,136 fourHundredGigE13 12 400000 -Ethernet52 137,138,139,140,141,142,143,144 fourHundredGigE14 13 400000 -Ethernet56 145,146,147,148,149,150,151,152 fourHundredGigE15 14 400000 -Ethernet60 153,154,155,156,157,158,159,160 fourHundredGigE16 15 400000 -Ethernet64 169,170,171,172,173,174,175,176 fourHundredGigE17 16 400000 -Ethernet68 161,162,163,164,165,166,167,168 fourHundredGigE18 17 400000 -Ethernet72 177,178,179,180,181,182,183,184 fourHundredGigE19 18 400000 -Ethernet76 185,186,187,188,189,190,191,192 fourHundredGigE20 19 400000 -Ethernet80 1,2,3,4,5,6,7,8 fourHundredGigE21 20 400000 -Ethernet84 9,10,11,12,13,14,15,16 fourHundredGigE22 21 400000 -Ethernet88 17,18,19,20,21,22,23,24 fourHundredGigE23 22 400000 -Ethernet92 25,26,27,28,29,30,31,32 fourHundredGigE24 23 400000 -Ethernet96 201,202,203,204,205,206,207,208 fourHundredGigE25 24 400000 -Ethernet100 193,194,195,196,197,198,199,200 fourHundredGigE26 25 400000 -Ethernet104 217,218,219,220,221,222,223,224 fourHundredGigE27 26 400000 -Ethernet108 209,210,211,212,213,214,215,216 fourHundredGigE28 27 400000 -Ethernet112 233,234,235,236,237,238,239,240 fourHundredGigE29 28 400000 -Ethernet116 225,226,227,228,229,230,231,232 fourHundredGigE30 29 400000 -Ethernet120 249,250,251,252,253,254,255,256 fourHundredGigE31 30 400000 -Ethernet124 241,242,243,244,245,246,247,248 fourHundredGigE32 31 400000 +Ethernet0 73,74,75,76,77,78,79,80 fourHundredGigE1 0 400000 +Ethernet8 65,66,67,68,69,70,71,72 fourHundredGigE2 1 400000 +Ethernet16 81,82,83,84,85,86,87,88 fourHundredGigE3 2 400000 +Ethernet24 89,90,91,92,93,94,95,96 fourHundredGigE4 3 400000 +Ethernet32 97,98,99,100,101,102,103,104 fourHundredGigE5 4 400000 +Ethernet40 105,106,107,108,109,110,111,112 fourHundredGigE6 5 400000 +Ethernet48 113,114,115,116,117,118,119,120 fourHundredGigE7 6 400000 +Ethernet56 121,122,123,124,125,126,127,128 fourHundredGigE8 7 400000 +Ethernet64 41,42,43,44,45,46,47,48 fourHundredGigE9 8 400000 +Ethernet72 33,34,35,36,37,38,39,40 fourHundredGigE10 9 400000 +Ethernet80 49,50,51,52,53,54,55,56 fourHundredGigE11 10 400000 +Ethernet88 57,58,59,60,61,62,63,64 fourHundredGigE12 11 400000 +Ethernet96 129,130,131,132,133,134,135,136 fourHundredGigE13 12 400000 +Ethernet104 137,138,139,140,141,142,143,144 fourHundredGigE14 13 400000 +Ethernet112 145,146,147,148,149,150,151,152 fourHundredGigE15 14 400000 +Ethernet120 153,154,155,156,157,158,159,160 fourHundredGigE16 15 400000 +Ethernet128 169,170,171,172,173,174,175,176 fourHundredGigE17 16 400000 +Ethernet136 161,162,163,164,165,166,167,168 fourHundredGigE18 17 400000 +Ethernet144 177,178,179,180,181,182,183,184 fourHundredGigE19 18 400000 +Ethernet152 185,186,187,188,189,190,191,192 fourHundredGigE20 19 400000 +Ethernet160 1,2,3,4,5,6,7,8 fourHundredGigE21 20 400000 +Ethernet168 9,10,11,12,13,14,15,16 fourHundredGigE22 21 400000 +Ethernet176 17,18,19,20,21,22,23,24 fourHundredGigE23 22 400000 +Ethernet184 25,26,27,28,29,30,31,32 fourHundredGigE24 23 400000 +Ethernet192 201,202,203,204,205,206,207,208 fourHundredGigE25 24 400000 +Ethernet200 193,194,195,196,197,198,199,200 fourHundredGigE26 25 400000 +Ethernet208 217,218,219,220,221,222,223,224 fourHundredGigE27 26 400000 +Ethernet216 209,210,211,212,213,214,215,216 fourHundredGigE28 27 400000 +Ethernet224 233,234,235,236,237,238,239,240 fourHundredGigE29 28 400000 +Ethernet232 225,226,227,228,229,230,231,232 fourHundredGigE30 29 400000 +Ethernet240 249,250,251,252,253,254,255,256 fourHundredGigE31 30 400000 +Ethernet248 241,242,243,244,245,246,247,248 fourHundredGigE32 31 400000 diff --git a/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/sai.profile b/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/sai.profile index be39b1f961f2..60f0d4b11d63 100644 --- a/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/sai.profile +++ b/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/sai.profile @@ -1 +1,2 @@ -SAI_INIT_CONFIG_FILE=/etc/bcm/th3-as9716-32x400G.config.bcm +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-as9716-32x400G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/th3-as9716-32x400G.config.bcm b/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/th3-as9716-32x400G.config.bcm new file mode 100644 index 000000000000..5850f4ce4d72 --- /dev/null +++ b/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/th3-as9716-32x400G.config.bcm @@ -0,0 +1,1287 @@ +pbmp_xport_xe.0=0x3ffffffffffffffffffffffffffffffffffffffe + +# Reference specfic +parity_correction=1 +parity_enable=1 +phy_null=1 +#pll_bypass=1 +core_clock_frequency=1325 +dpr_clock_frequency=1000 +device_clock_frequency=1325 +port_flex_enable=1 +l2xmsg_mode.0=1 +l2_mem_entries.0=8192 +l3_alpm_enable.0=2 +l3_mem_entries.0=16384 +mmu_port_num_mc_queue.0=1 +module_64ports.0=1 +multicast_l2_range.0=511 +oversubscribe_mode=1 + +# Platform specfic +arl_clean_timeout_usec=15000000 +asf_mem_profile.0=2 +bcm_num_cos.0=8 +bcm_stat_flags=1 +bcm_stat_jumbo.0=9236 +cdma_timeout_usec.0=15000000 +dma_desc_timeout_usec.0=15000000 +dpr_clock_frequency.0=1000 +max_vp_lags.0=0 +miim_intr_enable.0=0 +sram_scan_enable.0=0 +tdma_timeout_usec.0=15000000 +tslam_timeout_usec.0=15000000 + +#BC0# +dport_map_port_1=81 +dport_map_port_2=82 +dport_map_port_3=83 +dport_map_port_4=84 +portmap_1=1:400 +phy_chain_rx_lane_map_physical{1.0}=0x45301726 +phy_chain_rx_lane_map_physical{2.0}=0x45301726 +phy_chain_rx_lane_map_physical{3.0}=0x45301726 +phy_chain_rx_lane_map_physical{4.0}=0x45301726 +phy_chain_rx_lane_map_physical{5.0}=0x45301726 +phy_chain_rx_lane_map_physical{6.0}=0x45301726 +phy_chain_rx_lane_map_physical{7.0}=0x45301726 +phy_chain_rx_lane_map_physical{8.0}=0x45301726 +phy_chain_tx_lane_map_physical{1.0}=0x23761450 +phy_chain_tx_lane_map_physical{2.0}=0x23761450 +phy_chain_tx_lane_map_physical{3.0}=0x23761450 +phy_chain_tx_lane_map_physical{4.0}=0x23761450 +phy_chain_tx_lane_map_physical{5.0}=0x23761450 +phy_chain_tx_lane_map_physical{6.0}=0x23761450 +phy_chain_tx_lane_map_physical{7.0}=0x23761450 +phy_chain_tx_lane_map_physical{8.0}=0x23761450 +serdes_core_rx_polarity_flip_physical{1}=0xA9 +serdes_core_rx_polarity_flip_physical{2}=0xA9 +serdes_core_rx_polarity_flip_physical{3}=0xA9 +serdes_core_rx_polarity_flip_physical{4}=0xA9 +serdes_core_rx_polarity_flip_physical{5}=0xA9 +serdes_core_rx_polarity_flip_physical{6}=0xA9 +serdes_core_rx_polarity_flip_physical{7}=0xA9 +serdes_core_rx_polarity_flip_physical{8}=0xA9 +serdes_core_tx_polarity_flip_physical{1}=0x7E +serdes_core_tx_polarity_flip_physical{2}=0x7E +serdes_core_tx_polarity_flip_physical{3}=0x7E +serdes_core_tx_polarity_flip_physical{4}=0x7E +serdes_core_tx_polarity_flip_physical{5}=0x7E +serdes_core_tx_polarity_flip_physical{6}=0x7E +serdes_core_tx_polarity_flip_physical{7}=0x7E +serdes_core_tx_polarity_flip_physical{8}=0x7E + +#BC1# +dport_map_port_5=85 +dport_map_port_6=86 +dport_map_port_7=87 +dport_map_port_8=88 +portmap_5=9:400 +phy_chain_rx_lane_map_physical{9.0}=0x12650374 +phy_chain_rx_lane_map_physical{10.0}=0x12650374 +phy_chain_rx_lane_map_physical{11.0}=0x12650374 +phy_chain_rx_lane_map_physical{12.0}=0x12650374 +phy_chain_rx_lane_map_physical{13.0}=0x12650374 +phy_chain_rx_lane_map_physical{14.0}=0x12650374 +phy_chain_rx_lane_map_physical{15.0}=0x12650374 +phy_chain_rx_lane_map_physical{16.0}=0x12650374 +phy_chain_tx_lane_map_physical{9.0}=0x70146253 +phy_chain_tx_lane_map_physical{10.0}=0x70146253 +phy_chain_tx_lane_map_physical{11.0}=0x70146253 +phy_chain_tx_lane_map_physical{12.0}=0x70146253 +phy_chain_tx_lane_map_physical{13.0}=0x70146253 +phy_chain_tx_lane_map_physical{14.0}=0x70146253 +phy_chain_tx_lane_map_physical{15.0}=0x70146253 +phy_chain_tx_lane_map_physical{16.0}=0x70146253 +serdes_core_rx_polarity_flip_physical{9}=0x5A +serdes_core_rx_polarity_flip_physical{10}=0x5A +serdes_core_rx_polarity_flip_physical{11}=0x5A +serdes_core_rx_polarity_flip_physical{12}=0x5A +serdes_core_rx_polarity_flip_physical{13}=0x5A +serdes_core_rx_polarity_flip_physical{14}=0x5A +serdes_core_rx_polarity_flip_physical{15}=0x5A +serdes_core_rx_polarity_flip_physical{16}=0x5A +serdes_core_tx_polarity_flip_physical{9}=0x76 +serdes_core_tx_polarity_flip_physical{10}=0x76 +serdes_core_tx_polarity_flip_physical{11}=0x76 +serdes_core_tx_polarity_flip_physical{12}=0x76 +serdes_core_tx_polarity_flip_physical{13}=0x76 +serdes_core_tx_polarity_flip_physical{14}=0x76 +serdes_core_tx_polarity_flip_physical{15}=0x76 +serdes_core_tx_polarity_flip_physical{16}=0x76 + +#BC2# +dport_map_port_9=89 +dport_map_port_10=90 +dport_map_port_11=91 +dport_map_port_12=92 +portmap_9=17:400 +phy_chain_rx_lane_map_physical{17.0}=0x40572136 +phy_chain_rx_lane_map_physical{18.0}=0x40572136 +phy_chain_rx_lane_map_physical{19.0}=0x40572136 +phy_chain_rx_lane_map_physical{20.0}=0x40572136 +phy_chain_rx_lane_map_physical{21.0}=0x40572136 +phy_chain_rx_lane_map_physical{22.0}=0x40572136 +phy_chain_rx_lane_map_physical{23.0}=0x40572136 +phy_chain_rx_lane_map_physical{24.0}=0x40572136 +phy_chain_tx_lane_map_physical{17.0}=0x75324160 +phy_chain_tx_lane_map_physical{18.0}=0x75324160 +phy_chain_tx_lane_map_physical{19.0}=0x75324160 +phy_chain_tx_lane_map_physical{20.0}=0x75324160 +phy_chain_tx_lane_map_physical{21.0}=0x75324160 +phy_chain_tx_lane_map_physical{22.0}=0x75324160 +phy_chain_tx_lane_map_physical{23.0}=0x75324160 +phy_chain_tx_lane_map_physical{24.0}=0x75324160 +serdes_core_rx_polarity_flip_physical{17}=0x78 +serdes_core_rx_polarity_flip_physical{18}=0x78 +serdes_core_rx_polarity_flip_physical{19}=0x78 +serdes_core_rx_polarity_flip_physical{20}=0x78 +serdes_core_rx_polarity_flip_physical{21}=0x78 +serdes_core_rx_polarity_flip_physical{22}=0x78 +serdes_core_rx_polarity_flip_physical{23}=0x78 +serdes_core_rx_polarity_flip_physical{24}=0x78 +serdes_core_tx_polarity_flip_physical{17}=0x3B +serdes_core_tx_polarity_flip_physical{18}=0x3B +serdes_core_tx_polarity_flip_physical{19}=0x3B +serdes_core_tx_polarity_flip_physical{20}=0x3B +serdes_core_tx_polarity_flip_physical{21}=0x3B +serdes_core_tx_polarity_flip_physical{22}=0x3B +serdes_core_tx_polarity_flip_physical{23}=0x3B +serdes_core_tx_polarity_flip_physical{24}=0x3B + +#BC3# +dport_map_port_13=93 +dport_map_port_14=94 +dport_map_port_15=95 +dport_map_port_16=96 +portmap_13=25:400 +phy_chain_rx_lane_map_physical{25.0}=0x20576143 +phy_chain_rx_lane_map_physical{26.0}=0x20576143 +phy_chain_rx_lane_map_physical{27.0}=0x20576143 +phy_chain_rx_lane_map_physical{28.0}=0x20576143 +phy_chain_rx_lane_map_physical{29.0}=0x20576143 +phy_chain_rx_lane_map_physical{30.0}=0x20576143 +phy_chain_rx_lane_map_physical{31.0}=0x20576143 +phy_chain_rx_lane_map_physical{32.0}=0x20576143 +phy_chain_tx_lane_map_physical{25.0}=0x43716520 +phy_chain_tx_lane_map_physical{26.0}=0x43716520 +phy_chain_tx_lane_map_physical{27.0}=0x43716520 +phy_chain_tx_lane_map_physical{28.0}=0x43716520 +phy_chain_tx_lane_map_physical{29.0}=0x43716520 +phy_chain_tx_lane_map_physical{30.0}=0x43716520 +phy_chain_tx_lane_map_physical{31.0}=0x43716520 +phy_chain_tx_lane_map_physical{32.0}=0x43716520 +serdes_core_rx_polarity_flip_physical{25}=0xF8 +serdes_core_rx_polarity_flip_physical{26}=0xF8 +serdes_core_rx_polarity_flip_physical{27}=0xF8 +serdes_core_rx_polarity_flip_physical{28}=0xF8 +serdes_core_rx_polarity_flip_physical{29}=0xF8 +serdes_core_rx_polarity_flip_physical{30}=0xF8 +serdes_core_rx_polarity_flip_physical{31}=0xF8 +serdes_core_rx_polarity_flip_physical{32}=0xF8 +serdes_core_tx_polarity_flip_physical{25}=0x6E +serdes_core_tx_polarity_flip_physical{26}=0x6E +serdes_core_tx_polarity_flip_physical{27}=0x6E +serdes_core_tx_polarity_flip_physical{28}=0x6E +serdes_core_tx_polarity_flip_physical{29}=0x6E +serdes_core_tx_polarity_flip_physical{30}=0x6E +serdes_core_tx_polarity_flip_physical{31}=0x6E +serdes_core_tx_polarity_flip_physical{32}=0x6E + +#BC4# +dport_map_port_24=37 +dport_map_port_25=38 +dport_map_port_26=39 +dport_map_port_27=40 +portmap_24=33:400 +phy_chain_rx_lane_map_physical{33.0}=0x47205361 +phy_chain_rx_lane_map_physical{34.0}=0x47205361 +phy_chain_rx_lane_map_physical{35.0}=0x47205361 +phy_chain_rx_lane_map_physical{36.0}=0x47205361 +phy_chain_rx_lane_map_physical{37.0}=0x47205361 +phy_chain_rx_lane_map_physical{38.0}=0x47205361 +phy_chain_rx_lane_map_physical{39.0}=0x47205361 +phy_chain_rx_lane_map_physical{40.0}=0x47205361 +phy_chain_tx_lane_map_physical{33.0}=0x01452736 +phy_chain_tx_lane_map_physical{34.0}=0x01452736 +phy_chain_tx_lane_map_physical{35.0}=0x01452736 +phy_chain_tx_lane_map_physical{36.0}=0x01452736 +phy_chain_tx_lane_map_physical{37.0}=0x01452736 +phy_chain_tx_lane_map_physical{38.0}=0x01452736 +phy_chain_tx_lane_map_physical{39.0}=0x01452736 +phy_chain_tx_lane_map_physical{40.0}=0x01452736 +serdes_core_rx_polarity_flip_physical{33}=0x87 +serdes_core_rx_polarity_flip_physical{34}=0x87 +serdes_core_rx_polarity_flip_physical{35}=0x87 +serdes_core_rx_polarity_flip_physical{36}=0x87 +serdes_core_rx_polarity_flip_physical{37}=0x87 +serdes_core_rx_polarity_flip_physical{38}=0x87 +serdes_core_rx_polarity_flip_physical{39}=0x87 +serdes_core_rx_polarity_flip_physical{40}=0x87 +serdes_core_tx_polarity_flip_physical{33}=0x27 +serdes_core_tx_polarity_flip_physical{34}=0x27 +serdes_core_tx_polarity_flip_physical{35}=0x27 +serdes_core_tx_polarity_flip_physical{36}=0x27 +serdes_core_tx_polarity_flip_physical{37}=0x27 +serdes_core_tx_polarity_flip_physical{38}=0x27 +serdes_core_tx_polarity_flip_physical{39}=0x27 +serdes_core_tx_polarity_flip_physical{40}=0x27 + +#BC5# +dport_map_port_20=33 +dport_map_port_21=34 +dport_map_port_22=35 +dport_map_port_23=36 +portmap_20=41:400 +phy_chain_rx_lane_map_physical{41.0}=0x45013726 +phy_chain_rx_lane_map_physical{42.0}=0x45013726 +phy_chain_rx_lane_map_physical{43.0}=0x45013726 +phy_chain_rx_lane_map_physical{44.0}=0x45013726 +phy_chain_rx_lane_map_physical{45.0}=0x45013726 +phy_chain_rx_lane_map_physical{46.0}=0x45013726 +phy_chain_rx_lane_map_physical{47.0}=0x45013726 +phy_chain_rx_lane_map_physical{48.0}=0x45013726 +phy_chain_tx_lane_map_physical{41.0}=0x10273564 +phy_chain_tx_lane_map_physical{42.0}=0x10273564 +phy_chain_tx_lane_map_physical{43.0}=0x10273564 +phy_chain_tx_lane_map_physical{44.0}=0x10273564 +phy_chain_tx_lane_map_physical{45.0}=0x10273564 +phy_chain_tx_lane_map_physical{46.0}=0x10273564 +phy_chain_tx_lane_map_physical{47.0}=0x10273564 +phy_chain_tx_lane_map_physical{48.0}=0x10273564 +serdes_core_rx_polarity_flip_physical{41}=0x99 +serdes_core_rx_polarity_flip_physical{42}=0x99 +serdes_core_rx_polarity_flip_physical{43}=0x99 +serdes_core_rx_polarity_flip_physical{44}=0x99 +serdes_core_rx_polarity_flip_physical{45}=0x99 +serdes_core_rx_polarity_flip_physical{46}=0x99 +serdes_core_rx_polarity_flip_physical{47}=0x99 +serdes_core_rx_polarity_flip_physical{48}=0x99 +serdes_core_tx_polarity_flip_physical{41}=0xA8 +serdes_core_tx_polarity_flip_physical{42}=0xA8 +serdes_core_tx_polarity_flip_physical{43}=0xA8 +serdes_core_tx_polarity_flip_physical{44}=0xA8 +serdes_core_tx_polarity_flip_physical{45}=0xA8 +serdes_core_tx_polarity_flip_physical{46}=0xA8 +serdes_core_tx_polarity_flip_physical{47}=0xA8 +serdes_core_tx_polarity_flip_physical{48}=0xA8 + +#BC6# +dport_map_port_28=41 +dport_map_port_29=42 +dport_map_port_30=43 +dport_map_port_31=44 +portmap_28=49:400 +phy_chain_rx_lane_map_physical{49.0}=0x04571326 +phy_chain_rx_lane_map_physical{50.0}=0x04571326 +phy_chain_rx_lane_map_physical{51.0}=0x04571326 +phy_chain_rx_lane_map_physical{52.0}=0x04571326 +phy_chain_rx_lane_map_physical{53.0}=0x04571326 +phy_chain_rx_lane_map_physical{54.0}=0x04571326 +phy_chain_rx_lane_map_physical{55.0}=0x04571326 +phy_chain_rx_lane_map_physical{56.0}=0x04571326 +phy_chain_tx_lane_map_physical{49.0}=0x51230764 +phy_chain_tx_lane_map_physical{50.0}=0x51230764 +phy_chain_tx_lane_map_physical{51.0}=0x51230764 +phy_chain_tx_lane_map_physical{52.0}=0x51230764 +phy_chain_tx_lane_map_physical{53.0}=0x51230764 +phy_chain_tx_lane_map_physical{54.0}=0x51230764 +phy_chain_tx_lane_map_physical{55.0}=0x51230764 +phy_chain_tx_lane_map_physical{56.0}=0x51230764 +serdes_core_rx_polarity_flip_physical{49}=0xB2 +serdes_core_rx_polarity_flip_physical{50}=0xB2 +serdes_core_rx_polarity_flip_physical{51}=0xB2 +serdes_core_rx_polarity_flip_physical{52}=0xB2 +serdes_core_rx_polarity_flip_physical{53}=0xB2 +serdes_core_rx_polarity_flip_physical{54}=0xB2 +serdes_core_rx_polarity_flip_physical{55}=0xB2 +serdes_core_rx_polarity_flip_physical{56}=0xB2 +serdes_core_tx_polarity_flip_physical{49}=0x88 +serdes_core_tx_polarity_flip_physical{50}=0x88 +serdes_core_tx_polarity_flip_physical{51}=0x88 +serdes_core_tx_polarity_flip_physical{52}=0x88 +serdes_core_tx_polarity_flip_physical{53}=0x88 +serdes_core_tx_polarity_flip_physical{54}=0x88 +serdes_core_tx_polarity_flip_physical{55}=0x88 +serdes_core_tx_polarity_flip_physical{56}=0x88 + +#BC7# +dport_map_port_32=45 +dport_map_port_33=46 +dport_map_port_34=47 +dport_map_port_35=48 +portmap_32=57:400 +phy_chain_rx_lane_map_physical{57.0}=0x01675243 +phy_chain_rx_lane_map_physical{58.0}=0x01675243 +phy_chain_rx_lane_map_physical{59.0}=0x01675243 +phy_chain_rx_lane_map_physical{60.0}=0x01675243 +phy_chain_rx_lane_map_physical{61.0}=0x01675243 +phy_chain_rx_lane_map_physical{62.0}=0x01675243 +phy_chain_rx_lane_map_physical{63.0}=0x01675243 +phy_chain_rx_lane_map_physical{64.0}=0x01675243 +phy_chain_tx_lane_map_physical{57.0}=0x37106425 +phy_chain_tx_lane_map_physical{58.0}=0x37106425 +phy_chain_tx_lane_map_physical{59.0}=0x37106425 +phy_chain_tx_lane_map_physical{60.0}=0x37106425 +phy_chain_tx_lane_map_physical{61.0}=0x37106425 +phy_chain_tx_lane_map_physical{62.0}=0x37106425 +phy_chain_tx_lane_map_physical{63.0}=0x37106425 +phy_chain_tx_lane_map_physical{64.0}=0x37106425 +serdes_core_rx_polarity_flip_physical{57}=0x9C +serdes_core_rx_polarity_flip_physical{58}=0x9C +serdes_core_rx_polarity_flip_physical{59}=0x9C +serdes_core_rx_polarity_flip_physical{60}=0x9C +serdes_core_rx_polarity_flip_physical{61}=0x9C +serdes_core_rx_polarity_flip_physical{62}=0x9C +serdes_core_rx_polarity_flip_physical{63}=0x9C +serdes_core_rx_polarity_flip_physical{64}=0x9C +serdes_core_tx_polarity_flip_physical{57}=0x4F +serdes_core_tx_polarity_flip_physical{58}=0x4F +serdes_core_tx_polarity_flip_physical{59}=0x4F +serdes_core_tx_polarity_flip_physical{60}=0x4F +serdes_core_tx_polarity_flip_physical{61}=0x4F +serdes_core_tx_polarity_flip_physical{62}=0x4F +serdes_core_tx_polarity_flip_physical{63}=0x4F +serdes_core_tx_polarity_flip_physical{64}=0x4F + +#BC8# +dport_map_port_44=5 +dport_map_port_45=6 +dport_map_port_46=7 +dport_map_port_47=8 +portmap_44=65:400 +phy_chain_rx_lane_map_physical{65.0}=0x56024713 +phy_chain_rx_lane_map_physical{66.0}=0x56024713 +phy_chain_rx_lane_map_physical{67.0}=0x56024713 +phy_chain_rx_lane_map_physical{68.0}=0x56024713 +phy_chain_rx_lane_map_physical{69.0}=0x56024713 +phy_chain_rx_lane_map_physical{70.0}=0x56024713 +phy_chain_rx_lane_map_physical{71.0}=0x56024713 +phy_chain_rx_lane_map_physical{72.0}=0x56024713 +phy_chain_tx_lane_map_physical{65.0}=0x12673504 +phy_chain_tx_lane_map_physical{66.0}=0x12673504 +phy_chain_tx_lane_map_physical{67.0}=0x12673504 +phy_chain_tx_lane_map_physical{68.0}=0x12673504 +phy_chain_tx_lane_map_physical{69.0}=0x12673504 +phy_chain_tx_lane_map_physical{70.0}=0x12673504 +phy_chain_tx_lane_map_physical{71.0}=0x12673504 +phy_chain_tx_lane_map_physical{72.0}=0x12673504 +serdes_core_rx_polarity_flip_physical{65}=0x4B +serdes_core_rx_polarity_flip_physical{66}=0x4B +serdes_core_rx_polarity_flip_physical{67}=0x4B +serdes_core_rx_polarity_flip_physical{68}=0x4B +serdes_core_rx_polarity_flip_physical{69}=0x4B +serdes_core_rx_polarity_flip_physical{70}=0x4B +serdes_core_rx_polarity_flip_physical{71}=0x4B +serdes_core_rx_polarity_flip_physical{72}=0x4B +serdes_core_tx_polarity_flip_physical{65}=0xB7 +serdes_core_tx_polarity_flip_physical{66}=0xB7 +serdes_core_tx_polarity_flip_physical{67}=0xB7 +serdes_core_tx_polarity_flip_physical{68}=0xB7 +serdes_core_tx_polarity_flip_physical{69}=0xB7 +serdes_core_tx_polarity_flip_physical{70}=0xB7 +serdes_core_tx_polarity_flip_physical{71}=0xB7 +serdes_core_tx_polarity_flip_physical{72}=0xB7 + +#BC9# +dport_map_port_40=1 +dport_map_port_41=2 +dport_map_port_42=3 +dport_map_port_43=4 +portmap_40=73:400 +phy_chain_rx_lane_map_physical{73.0}=0x45231607 +phy_chain_rx_lane_map_physical{74.0}=0x45231607 +phy_chain_rx_lane_map_physical{75.0}=0x45231607 +phy_chain_rx_lane_map_physical{76.0}=0x45231607 +phy_chain_rx_lane_map_physical{77.0}=0x45231607 +phy_chain_rx_lane_map_physical{78.0}=0x45231607 +phy_chain_rx_lane_map_physical{79.0}=0x45231607 +phy_chain_rx_lane_map_physical{80.0}=0x45231607 +phy_chain_tx_lane_map_physical{73.0}=0x04273165 +phy_chain_tx_lane_map_physical{74.0}=0x04273165 +phy_chain_tx_lane_map_physical{75.0}=0x04273165 +phy_chain_tx_lane_map_physical{76.0}=0x04273165 +phy_chain_tx_lane_map_physical{77.0}=0x04273165 +phy_chain_tx_lane_map_physical{78.0}=0x04273165 +phy_chain_tx_lane_map_physical{79.0}=0x04273165 +phy_chain_tx_lane_map_physical{80.0}=0x04273165 +serdes_core_rx_polarity_flip_physical{73}=0x9C +serdes_core_rx_polarity_flip_physical{74}=0x9C +serdes_core_rx_polarity_flip_physical{75}=0x9C +serdes_core_rx_polarity_flip_physical{76}=0x9C +serdes_core_rx_polarity_flip_physical{77}=0x9C +serdes_core_rx_polarity_flip_physical{78}=0x9C +serdes_core_rx_polarity_flip_physical{79}=0x9C +serdes_core_rx_polarity_flip_physical{80}=0x9C +serdes_core_tx_polarity_flip_physical{73}=0xAC +serdes_core_tx_polarity_flip_physical{74}=0xAC +serdes_core_tx_polarity_flip_physical{75}=0xAC +serdes_core_tx_polarity_flip_physical{76}=0xAC +serdes_core_tx_polarity_flip_physical{77}=0xAC +serdes_core_tx_polarity_flip_physical{78}=0xAC +serdes_core_tx_polarity_flip_physical{79}=0xAC +serdes_core_tx_polarity_flip_physical{80}=0xAC + +#BC10# +dport_map_port_48=9 +dport_map_port_49=10 +dport_map_port_50=11 +dport_map_port_51=12 +portmap_48=81:400 +phy_chain_rx_lane_map_physical{81.0}=0x20563147 +phy_chain_rx_lane_map_physical{82.0}=0x20563147 +phy_chain_rx_lane_map_physical{83.0}=0x20563147 +phy_chain_rx_lane_map_physical{84.0}=0x20563147 +phy_chain_rx_lane_map_physical{85.0}=0x20563147 +phy_chain_rx_lane_map_physical{86.0}=0x20563147 +phy_chain_rx_lane_map_physical{87.0}=0x20563147 +phy_chain_rx_lane_map_physical{88.0}=0x20563147 +phy_chain_tx_lane_map_physical{81.0}=0x53216704 +phy_chain_tx_lane_map_physical{82.0}=0x53216704 +phy_chain_tx_lane_map_physical{83.0}=0x53216704 +phy_chain_tx_lane_map_physical{84.0}=0x53216704 +phy_chain_tx_lane_map_physical{85.0}=0x53216704 +phy_chain_tx_lane_map_physical{86.0}=0x53216704 +phy_chain_tx_lane_map_physical{87.0}=0x53216704 +phy_chain_tx_lane_map_physical{88.0}=0x53216704 +serdes_core_rx_polarity_flip_physical{81}=0xE1 +serdes_core_rx_polarity_flip_physical{82}=0xE1 +serdes_core_rx_polarity_flip_physical{83}=0xE1 +serdes_core_rx_polarity_flip_physical{84}=0xE1 +serdes_core_rx_polarity_flip_physical{85}=0xE1 +serdes_core_rx_polarity_flip_physical{86}=0xE1 +serdes_core_rx_polarity_flip_physical{87}=0xE1 +serdes_core_rx_polarity_flip_physical{88}=0xE1 +serdes_core_tx_polarity_flip_physical{81}=0xA2 +serdes_core_tx_polarity_flip_physical{82}=0xA2 +serdes_core_tx_polarity_flip_physical{83}=0xA2 +serdes_core_tx_polarity_flip_physical{84}=0xA2 +serdes_core_tx_polarity_flip_physical{85}=0xA2 +serdes_core_tx_polarity_flip_physical{86}=0xA2 +serdes_core_tx_polarity_flip_physical{87}=0xA2 +serdes_core_tx_polarity_flip_physical{88}=0xA2 + +#BC11# +dport_map_port_52=13 +dport_map_port_53=14 +dport_map_port_54=15 +dport_map_port_55=16 +portmap_52=89:400 +phy_chain_rx_lane_map_physical{89.0}=0x02514376 +phy_chain_rx_lane_map_physical{90.0}=0x02514376 +phy_chain_rx_lane_map_physical{91.0}=0x02514376 +phy_chain_rx_lane_map_physical{92.0}=0x02514376 +phy_chain_rx_lane_map_physical{93.0}=0x02514376 +phy_chain_rx_lane_map_physical{94.0}=0x02514376 +phy_chain_rx_lane_map_physical{95.0}=0x02514376 +phy_chain_rx_lane_map_physical{96.0}=0x02514376 +phy_chain_tx_lane_map_physical{89.0}=0x64012735 +phy_chain_tx_lane_map_physical{90.0}=0x64012735 +phy_chain_tx_lane_map_physical{91.0}=0x64012735 +phy_chain_tx_lane_map_physical{92.0}=0x64012735 +phy_chain_tx_lane_map_physical{93.0}=0x64012735 +phy_chain_tx_lane_map_physical{94.0}=0x64012735 +phy_chain_tx_lane_map_physical{95.0}=0x64012735 +phy_chain_tx_lane_map_physical{96.0}=0x64012735 +serdes_core_rx_polarity_flip_physical{89}=0xE2 +serdes_core_rx_polarity_flip_physical{90}=0xE2 +serdes_core_rx_polarity_flip_physical{91}=0xE2 +serdes_core_rx_polarity_flip_physical{92}=0xE2 +serdes_core_rx_polarity_flip_physical{93}=0xE2 +serdes_core_rx_polarity_flip_physical{94}=0xE2 +serdes_core_rx_polarity_flip_physical{95}=0xE2 +serdes_core_rx_polarity_flip_physical{96}=0xE2 +serdes_core_tx_polarity_flip_physical{89}=0xCF +serdes_core_tx_polarity_flip_physical{90}=0xCF +serdes_core_tx_polarity_flip_physical{91}=0xCF +serdes_core_tx_polarity_flip_physical{92}=0xCF +serdes_core_tx_polarity_flip_physical{93}=0xCF +serdes_core_tx_polarity_flip_physical{94}=0xCF +serdes_core_tx_polarity_flip_physical{95}=0xCF +serdes_core_tx_polarity_flip_physical{96}=0xCF + +#BC12# +dport_map_port_60=17 +dport_map_port_61=18 +dport_map_port_62=19 +dport_map_port_63=20 +portmap_60=97:400 +phy_chain_rx_lane_map_physical{97.0}=0x51276034 +phy_chain_rx_lane_map_physical{98.0}=0x51276034 +phy_chain_rx_lane_map_physical{99.0}=0x51276034 +phy_chain_rx_lane_map_physical{100.0}=0x51276034 +phy_chain_rx_lane_map_physical{101.0}=0x51276034 +phy_chain_rx_lane_map_physical{102.0}=0x51276034 +phy_chain_rx_lane_map_physical{103.0}=0x51276034 +phy_chain_rx_lane_map_physical{104.0}=0x51276034 +phy_chain_tx_lane_map_physical{97.0}=0x05476321 +phy_chain_tx_lane_map_physical{98.0}=0x05476321 +phy_chain_tx_lane_map_physical{99.0}=0x05476321 +phy_chain_tx_lane_map_physical{100.0}=0x05476321 +phy_chain_tx_lane_map_physical{101.0}=0x05476321 +phy_chain_tx_lane_map_physical{102.0}=0x05476321 +phy_chain_tx_lane_map_physical{103.0}=0x05476321 +phy_chain_tx_lane_map_physical{104.0}=0x05476321 +serdes_core_rx_polarity_flip_physical{97}=0x8E +serdes_core_rx_polarity_flip_physical{98}=0x8E +serdes_core_rx_polarity_flip_physical{99}=0x8E +serdes_core_rx_polarity_flip_physical{100}=0x8E +serdes_core_rx_polarity_flip_physical{101}=0x8E +serdes_core_rx_polarity_flip_physical{102}=0x8E +serdes_core_rx_polarity_flip_physical{103}=0x8E +serdes_core_rx_polarity_flip_physical{104}=0x8E +serdes_core_tx_polarity_flip_physical{97}=0xC8 +serdes_core_tx_polarity_flip_physical{98}=0xC8 +serdes_core_tx_polarity_flip_physical{99}=0xC8 +serdes_core_tx_polarity_flip_physical{100}=0xC8 +serdes_core_tx_polarity_flip_physical{101}=0xC8 +serdes_core_tx_polarity_flip_physical{102}=0xC8 +serdes_core_tx_polarity_flip_physical{103}=0xC8 +serdes_core_tx_polarity_flip_physical{104}=0xC8 + +#BC13# +dport_map_port_64=21 +dport_map_port_65=22 +dport_map_port_66=23 +dport_map_port_67=24 +portmap_64=105:400 +phy_chain_rx_lane_map_physical{105.0}=0x74126503 +phy_chain_rx_lane_map_physical{106.0}=0x74126503 +phy_chain_rx_lane_map_physical{107.0}=0x74126503 +phy_chain_rx_lane_map_physical{108.0}=0x74126503 +phy_chain_rx_lane_map_physical{109.0}=0x74126503 +phy_chain_rx_lane_map_physical{110.0}=0x74126503 +phy_chain_rx_lane_map_physical{111.0}=0x74126503 +phy_chain_rx_lane_map_physical{112.0}=0x74126503 +phy_chain_tx_lane_map_physical{105.0}=0x75236140 +phy_chain_tx_lane_map_physical{106.0}=0x75236140 +phy_chain_tx_lane_map_physical{107.0}=0x75236140 +phy_chain_tx_lane_map_physical{108.0}=0x75236140 +phy_chain_tx_lane_map_physical{109.0}=0x75236140 +phy_chain_tx_lane_map_physical{110.0}=0x75236140 +phy_chain_tx_lane_map_physical{111.0}=0x75236140 +phy_chain_tx_lane_map_physical{112.0}=0x75236140 +serdes_core_rx_polarity_flip_physical{105}=0x96 +serdes_core_rx_polarity_flip_physical{106}=0x96 +serdes_core_rx_polarity_flip_physical{107}=0x96 +serdes_core_rx_polarity_flip_physical{108}=0x96 +serdes_core_rx_polarity_flip_physical{109}=0x96 +serdes_core_rx_polarity_flip_physical{110}=0x96 +serdes_core_rx_polarity_flip_physical{111}=0x96 +serdes_core_rx_polarity_flip_physical{112}=0x96 +serdes_core_tx_polarity_flip_physical{105}=0xE1 +serdes_core_tx_polarity_flip_physical{106}=0xE1 +serdes_core_tx_polarity_flip_physical{107}=0xE1 +serdes_core_tx_polarity_flip_physical{108}=0xE1 +serdes_core_tx_polarity_flip_physical{109}=0xE1 +serdes_core_tx_polarity_flip_physical{110}=0xE1 +serdes_core_tx_polarity_flip_physical{111}=0xE1 +serdes_core_tx_polarity_flip_physical{112}=0xE1 + +#BC14# +dport_map_port_68=25 +dport_map_port_69=26 +dport_map_port_70=27 +dport_map_port_71=28 +portmap_68=113:400 +phy_chain_rx_lane_map_physical{113.0}=0x32461057 +phy_chain_rx_lane_map_physical{114.0}=0x32461057 +phy_chain_rx_lane_map_physical{115.0}=0x32461057 +phy_chain_rx_lane_map_physical{116.0}=0x32461057 +phy_chain_rx_lane_map_physical{117.0}=0x32461057 +phy_chain_rx_lane_map_physical{118.0}=0x32461057 +phy_chain_rx_lane_map_physical{119.0}=0x32461057 +phy_chain_rx_lane_map_physical{120.0}=0x32461057 +phy_chain_tx_lane_map_physical{113.0}=0x54107362 +phy_chain_tx_lane_map_physical{114.0}=0x54107362 +phy_chain_tx_lane_map_physical{115.0}=0x54107362 +phy_chain_tx_lane_map_physical{116.0}=0x54107362 +phy_chain_tx_lane_map_physical{117.0}=0x54107362 +phy_chain_tx_lane_map_physical{118.0}=0x54107362 +phy_chain_tx_lane_map_physical{119.0}=0x54107362 +phy_chain_tx_lane_map_physical{120.0}=0x54107362 +serdes_core_rx_polarity_flip_physical{113}=0x47 +serdes_core_rx_polarity_flip_physical{114}=0x47 +serdes_core_rx_polarity_flip_physical{115}=0x47 +serdes_core_rx_polarity_flip_physical{116}=0x47 +serdes_core_rx_polarity_flip_physical{117}=0x47 +serdes_core_rx_polarity_flip_physical{118}=0x47 +serdes_core_rx_polarity_flip_physical{119}=0x47 +serdes_core_rx_polarity_flip_physical{120}=0x47 +serdes_core_tx_polarity_flip_physical{113}=0xBD +serdes_core_tx_polarity_flip_physical{114}=0xBD +serdes_core_tx_polarity_flip_physical{115}=0xBD +serdes_core_tx_polarity_flip_physical{116}=0xBD +serdes_core_tx_polarity_flip_physical{117}=0xBD +serdes_core_tx_polarity_flip_physical{118}=0xBD +serdes_core_tx_polarity_flip_physical{119}=0xBD +serdes_core_tx_polarity_flip_physical{120}=0xBD + +#BC15# +dport_map_port_72=29 +dport_map_port_73=30 +dport_map_port_74=31 +dport_map_port_75=32 +portmap_72=121:400 +phy_chain_rx_lane_map_physical{121.0}=0x75342610 +phy_chain_rx_lane_map_physical{122.0}=0x75342610 +phy_chain_rx_lane_map_physical{123.0}=0x75342610 +phy_chain_rx_lane_map_physical{124.0}=0x75342610 +phy_chain_rx_lane_map_physical{125.0}=0x75342610 +phy_chain_rx_lane_map_physical{126.0}=0x75342610 +phy_chain_rx_lane_map_physical{127.0}=0x75342610 +phy_chain_rx_lane_map_physical{128.0}=0x75342610 +phy_chain_tx_lane_map_physical{121.0}=0x24617350 +phy_chain_tx_lane_map_physical{122.0}=0x24617350 +phy_chain_tx_lane_map_physical{123.0}=0x24617350 +phy_chain_tx_lane_map_physical{124.0}=0x24617350 +phy_chain_tx_lane_map_physical{125.0}=0x24617350 +phy_chain_tx_lane_map_physical{126.0}=0x24617350 +phy_chain_tx_lane_map_physical{127.0}=0x24617350 +phy_chain_tx_lane_map_physical{128.0}=0x24617350 +serdes_core_rx_polarity_flip_physical{121}=0x36 +serdes_core_rx_polarity_flip_physical{122}=0x36 +serdes_core_rx_polarity_flip_physical{123}=0x36 +serdes_core_rx_polarity_flip_physical{124}=0x36 +serdes_core_rx_polarity_flip_physical{125}=0x36 +serdes_core_rx_polarity_flip_physical{126}=0x36 +serdes_core_rx_polarity_flip_physical{127}=0x36 +serdes_core_rx_polarity_flip_physical{128}=0x36 +serdes_core_tx_polarity_flip_physical{121}=0x7F +serdes_core_tx_polarity_flip_physical{122}=0x7F +serdes_core_tx_polarity_flip_physical{123}=0x7F +serdes_core_tx_polarity_flip_physical{124}=0x7F +serdes_core_tx_polarity_flip_physical{125}=0x7F +serdes_core_tx_polarity_flip_physical{126}=0x7F +serdes_core_tx_polarity_flip_physical{127}=0x7F +serdes_core_tx_polarity_flip_physical{128}=0x7F + +#BC16# +dport_map_port_80=49 +dport_map_port_81=50 +dport_map_port_82=51 +dport_map_port_83=52 +portmap_80=129:400 +phy_chain_rx_lane_map_physical{129.0}=0x45302716 +phy_chain_rx_lane_map_physical{130.0}=0x45302716 +phy_chain_rx_lane_map_physical{131.0}=0x45302716 +phy_chain_rx_lane_map_physical{132.0}=0x45302716 +phy_chain_rx_lane_map_physical{133.0}=0x45302716 +phy_chain_rx_lane_map_physical{134.0}=0x45302716 +phy_chain_rx_lane_map_physical{135.0}=0x45302716 +phy_chain_rx_lane_map_physical{136.0}=0x45302716 +phy_chain_tx_lane_map_physical{129.0}=0x24763150 +phy_chain_tx_lane_map_physical{130.0}=0x24763150 +phy_chain_tx_lane_map_physical{131.0}=0x24763150 +phy_chain_tx_lane_map_physical{132.0}=0x24763150 +phy_chain_tx_lane_map_physical{133.0}=0x24763150 +phy_chain_tx_lane_map_physical{134.0}=0x24763150 +phy_chain_tx_lane_map_physical{135.0}=0x24763150 +phy_chain_tx_lane_map_physical{136.0}=0x24763150 +serdes_core_rx_polarity_flip_physical{129}=0xA3 +serdes_core_rx_polarity_flip_physical{130}=0xA3 +serdes_core_rx_polarity_flip_physical{131}=0xA3 +serdes_core_rx_polarity_flip_physical{132}=0xA3 +serdes_core_rx_polarity_flip_physical{133}=0xA3 +serdes_core_rx_polarity_flip_physical{134}=0xA3 +serdes_core_rx_polarity_flip_physical{135}=0xA3 +serdes_core_rx_polarity_flip_physical{136}=0xA3 +serdes_core_tx_polarity_flip_physical{129}=0x5C +serdes_core_tx_polarity_flip_physical{130}=0x5C +serdes_core_tx_polarity_flip_physical{131}=0x5C +serdes_core_tx_polarity_flip_physical{132}=0x5C +serdes_core_tx_polarity_flip_physical{133}=0x5C +serdes_core_tx_polarity_flip_physical{134}=0x5C +serdes_core_tx_polarity_flip_physical{135}=0x5C +serdes_core_tx_polarity_flip_physical{136}=0x5C + +#BC17# +dport_map_port_84=53 +dport_map_port_85=54 +dport_map_port_86=55 +dport_map_port_87=56 +portmap_84=137:400 +phy_chain_rx_lane_map_physical{137.0}=0x12460357 +phy_chain_rx_lane_map_physical{138.0}=0x12460357 +phy_chain_rx_lane_map_physical{139.0}=0x12460357 +phy_chain_rx_lane_map_physical{140.0}=0x12460357 +phy_chain_rx_lane_map_physical{141.0}=0x12460357 +phy_chain_rx_lane_map_physical{142.0}=0x12460357 +phy_chain_rx_lane_map_physical{143.0}=0x12460357 +phy_chain_rx_lane_map_physical{144.0}=0x12460357 +phy_chain_tx_lane_map_physical{137.0}=0x70135462 +phy_chain_tx_lane_map_physical{138.0}=0x70135462 +phy_chain_tx_lane_map_physical{139.0}=0x70135462 +phy_chain_tx_lane_map_physical{140.0}=0x70135462 +phy_chain_tx_lane_map_physical{141.0}=0x70135462 +phy_chain_tx_lane_map_physical{142.0}=0x70135462 +phy_chain_tx_lane_map_physical{143.0}=0x70135462 +phy_chain_tx_lane_map_physical{144.0}=0x70135462 +serdes_core_rx_polarity_flip_physical{137}=0x4B +serdes_core_rx_polarity_flip_physical{138}=0x4B +serdes_core_rx_polarity_flip_physical{139}=0x4B +serdes_core_rx_polarity_flip_physical{140}=0x4B +serdes_core_rx_polarity_flip_physical{141}=0x4B +serdes_core_rx_polarity_flip_physical{142}=0x4B +serdes_core_rx_polarity_flip_physical{143}=0x4B +serdes_core_rx_polarity_flip_physical{144}=0x4B +serdes_core_tx_polarity_flip_physical{137}=0xF8 +serdes_core_tx_polarity_flip_physical{138}=0xF8 +serdes_core_tx_polarity_flip_physical{139}=0xF8 +serdes_core_tx_polarity_flip_physical{140}=0xF8 +serdes_core_tx_polarity_flip_physical{141}=0xF8 +serdes_core_tx_polarity_flip_physical{142}=0xF8 +serdes_core_tx_polarity_flip_physical{143}=0xF8 +serdes_core_tx_polarity_flip_physical{144}=0xF8 + +#BC18# +dport_map_port_88=57 +dport_map_port_89=58 +dport_map_port_90=59 +dport_map_port_91=60 +portmap_88=145:400 +phy_chain_rx_lane_map_physical{145.0}=0x20563147 +phy_chain_rx_lane_map_physical{146.0}=0x20563147 +phy_chain_rx_lane_map_physical{147.0}=0x20563147 +phy_chain_rx_lane_map_physical{148.0}=0x20563147 +phy_chain_rx_lane_map_physical{149.0}=0x20563147 +phy_chain_rx_lane_map_physical{150.0}=0x20563147 +phy_chain_rx_lane_map_physical{151.0}=0x20563147 +phy_chain_rx_lane_map_physical{152.0}=0x20563147 +phy_chain_tx_lane_map_physical{145.0}=0x54126073 +phy_chain_tx_lane_map_physical{146.0}=0x54126073 +phy_chain_tx_lane_map_physical{147.0}=0x54126073 +phy_chain_tx_lane_map_physical{148.0}=0x54126073 +phy_chain_tx_lane_map_physical{149.0}=0x54126073 +phy_chain_tx_lane_map_physical{150.0}=0x54126073 +phy_chain_tx_lane_map_physical{151.0}=0x54126073 +phy_chain_tx_lane_map_physical{152.0}=0x54126073 +serdes_core_rx_polarity_flip_physical{145}=0xE1 +serdes_core_rx_polarity_flip_physical{146}=0xE1 +serdes_core_rx_polarity_flip_physical{147}=0xE1 +serdes_core_rx_polarity_flip_physical{148}=0xE1 +serdes_core_rx_polarity_flip_physical{149}=0xE1 +serdes_core_rx_polarity_flip_physical{150}=0xE1 +serdes_core_rx_polarity_flip_physical{151}=0xE1 +serdes_core_rx_polarity_flip_physical{152}=0xE1 +serdes_core_tx_polarity_flip_physical{145}=0xD5 +serdes_core_tx_polarity_flip_physical{146}=0xD5 +serdes_core_tx_polarity_flip_physical{147}=0xD5 +serdes_core_tx_polarity_flip_physical{148}=0xD5 +serdes_core_tx_polarity_flip_physical{149}=0xD5 +serdes_core_tx_polarity_flip_physical{150}=0xD5 +serdes_core_tx_polarity_flip_physical{151}=0xD5 +serdes_core_tx_polarity_flip_physical{152}=0xD5 + +#BC19# +dport_map_port_92=61 +dport_map_port_93=62 +dport_map_port_94=63 +dport_map_port_95=64 +portmap_92=153:400 +phy_chain_rx_lane_map_physical{153.0}=0x10652473 +phy_chain_rx_lane_map_physical{154.0}=0x10652473 +phy_chain_rx_lane_map_physical{155.0}=0x10652473 +phy_chain_rx_lane_map_physical{156.0}=0x10652473 +phy_chain_rx_lane_map_physical{157.0}=0x10652473 +phy_chain_rx_lane_map_physical{158.0}=0x10652473 +phy_chain_rx_lane_map_physical{159.0}=0x10652473 +phy_chain_rx_lane_map_physical{160.0}=0x10652473 +phy_chain_tx_lane_map_physical{153.0}=0x15036427 +phy_chain_tx_lane_map_physical{154.0}=0x15036427 +phy_chain_tx_lane_map_physical{155.0}=0x15036427 +phy_chain_tx_lane_map_physical{156.0}=0x15036427 +phy_chain_tx_lane_map_physical{157.0}=0x15036427 +phy_chain_tx_lane_map_physical{158.0}=0x15036427 +phy_chain_tx_lane_map_physical{159.0}=0x15036427 +phy_chain_tx_lane_map_physical{160.0}=0x15036427 +serdes_core_rx_polarity_flip_physical{153}=0xB1 +serdes_core_rx_polarity_flip_physical{154}=0xB1 +serdes_core_rx_polarity_flip_physical{155}=0xB1 +serdes_core_rx_polarity_flip_physical{156}=0xB1 +serdes_core_rx_polarity_flip_physical{157}=0xB1 +serdes_core_rx_polarity_flip_physical{158}=0xB1 +serdes_core_rx_polarity_flip_physical{159}=0xB1 +serdes_core_rx_polarity_flip_physical{160}=0xB1 +serdes_core_tx_polarity_flip_physical{153}=0x5E +serdes_core_tx_polarity_flip_physical{154}=0x5E +serdes_core_tx_polarity_flip_physical{155}=0x5E +serdes_core_tx_polarity_flip_physical{156}=0x5E +serdes_core_tx_polarity_flip_physical{157}=0x5E +serdes_core_tx_polarity_flip_physical{158}=0x5E +serdes_core_tx_polarity_flip_physical{159}=0x5E +serdes_core_tx_polarity_flip_physical{160}=0x5E + +#BC20# +dport_map_port_104=69 +dport_map_port_105=70 +dport_map_port_106=71 +dport_map_port_107=72 +portmap_104=161:400 +phy_chain_rx_lane_map_physical{161.0}=0x70125643 +phy_chain_rx_lane_map_physical{162.0}=0x70125643 +phy_chain_rx_lane_map_physical{163.0}=0x70125643 +phy_chain_rx_lane_map_physical{164.0}=0x70125643 +phy_chain_rx_lane_map_physical{165.0}=0x70125643 +phy_chain_rx_lane_map_physical{166.0}=0x70125643 +phy_chain_rx_lane_map_physical{167.0}=0x70125643 +phy_chain_rx_lane_map_physical{168.0}=0x70125643 +phy_chain_tx_lane_map_physical{161.0}=0x21073456 +phy_chain_tx_lane_map_physical{162.0}=0x21073456 +phy_chain_tx_lane_map_physical{163.0}=0x21073456 +phy_chain_tx_lane_map_physical{164.0}=0x21073456 +phy_chain_tx_lane_map_physical{165.0}=0x21073456 +phy_chain_tx_lane_map_physical{166.0}=0x21073456 +phy_chain_tx_lane_map_physical{167.0}=0x21073456 +phy_chain_tx_lane_map_physical{168.0}=0x21073456 +serdes_core_rx_polarity_flip_physical{161}=0x27 +serdes_core_rx_polarity_flip_physical{162}=0x27 +serdes_core_rx_polarity_flip_physical{163}=0x27 +serdes_core_rx_polarity_flip_physical{164}=0x27 +serdes_core_rx_polarity_flip_physical{165}=0x27 +serdes_core_rx_polarity_flip_physical{166}=0x27 +serdes_core_rx_polarity_flip_physical{167}=0x27 +serdes_core_rx_polarity_flip_physical{168}=0x27 +serdes_core_tx_polarity_flip_physical{161}=0x5 +serdes_core_tx_polarity_flip_physical{162}=0x5 +serdes_core_tx_polarity_flip_physical{163}=0x5 +serdes_core_tx_polarity_flip_physical{164}=0x5 +serdes_core_tx_polarity_flip_physical{165}=0x5 +serdes_core_tx_polarity_flip_physical{166}=0x5 +serdes_core_tx_polarity_flip_physical{167}=0x5 +serdes_core_tx_polarity_flip_physical{168}=0x5 + +#BC21# +dport_map_port_100=65 +dport_map_port_101=66 +dport_map_port_102=67 +dport_map_port_103=68 +portmap_100=169:400 +phy_chain_rx_lane_map_physical{169.0}=0x27416350 +phy_chain_rx_lane_map_physical{170.0}=0x27416350 +phy_chain_rx_lane_map_physical{171.0}=0x27416350 +phy_chain_rx_lane_map_physical{172.0}=0x27416350 +phy_chain_rx_lane_map_physical{173.0}=0x27416350 +phy_chain_rx_lane_map_physical{174.0}=0x27416350 +phy_chain_rx_lane_map_physical{175.0}=0x27416350 +phy_chain_rx_lane_map_physical{176.0}=0x27416350 +phy_chain_tx_lane_map_physical{169.0}=0x36570412 +phy_chain_tx_lane_map_physical{170.0}=0x36570412 +phy_chain_tx_lane_map_physical{171.0}=0x36570412 +phy_chain_tx_lane_map_physical{172.0}=0x36570412 +phy_chain_tx_lane_map_physical{173.0}=0x36570412 +phy_chain_tx_lane_map_physical{174.0}=0x36570412 +phy_chain_tx_lane_map_physical{175.0}=0x36570412 +phy_chain_tx_lane_map_physical{176.0}=0x36570412 +serdes_core_rx_polarity_flip_physical{169}=0x3C +serdes_core_rx_polarity_flip_physical{170}=0x3C +serdes_core_rx_polarity_flip_physical{171}=0x3C +serdes_core_rx_polarity_flip_physical{172}=0x3C +serdes_core_rx_polarity_flip_physical{173}=0x3C +serdes_core_rx_polarity_flip_physical{174}=0x3C +serdes_core_rx_polarity_flip_physical{175}=0x3C +serdes_core_rx_polarity_flip_physical{176}=0x3C +serdes_core_tx_polarity_flip_physical{169}=0x7D +serdes_core_tx_polarity_flip_physical{170}=0x7D +serdes_core_tx_polarity_flip_physical{171}=0x7D +serdes_core_tx_polarity_flip_physical{172}=0x7D +serdes_core_tx_polarity_flip_physical{173}=0x7D +serdes_core_tx_polarity_flip_physical{174}=0x7D +serdes_core_tx_polarity_flip_physical{175}=0x7D +serdes_core_tx_polarity_flip_physical{176}=0x7D + +#BC22# +dport_map_port_108=73 +dport_map_port_109=74 +dport_map_port_110=75 +dport_map_port_111=76 +portmap_108=177:400 +phy_chain_rx_lane_map_physical{177.0}=0x04153726 +phy_chain_rx_lane_map_physical{178.0}=0x04153726 +phy_chain_rx_lane_map_physical{179.0}=0x04153726 +phy_chain_rx_lane_map_physical{180.0}=0x04153726 +phy_chain_rx_lane_map_physical{181.0}=0x04153726 +phy_chain_rx_lane_map_physical{182.0}=0x04153726 +phy_chain_rx_lane_map_physical{183.0}=0x04153726 +phy_chain_rx_lane_map_physical{184.0}=0x04153726 +phy_chain_tx_lane_map_physical{177.0}=0x47305162 +phy_chain_tx_lane_map_physical{178.0}=0x47305162 +phy_chain_tx_lane_map_physical{179.0}=0x47305162 +phy_chain_tx_lane_map_physical{180.0}=0x47305162 +phy_chain_tx_lane_map_physical{181.0}=0x47305162 +phy_chain_tx_lane_map_physical{182.0}=0x47305162 +phy_chain_tx_lane_map_physical{183.0}=0x47305162 +phy_chain_tx_lane_map_physical{184.0}=0x47305162 +serdes_core_rx_polarity_flip_physical{177}=0x96 +serdes_core_rx_polarity_flip_physical{178}=0x96 +serdes_core_rx_polarity_flip_physical{179}=0x96 +serdes_core_rx_polarity_flip_physical{180}=0x96 +serdes_core_rx_polarity_flip_physical{181}=0x96 +serdes_core_rx_polarity_flip_physical{182}=0x96 +serdes_core_rx_polarity_flip_physical{183}=0x96 +serdes_core_rx_polarity_flip_physical{184}=0x96 +serdes_core_tx_polarity_flip_physical{177}=0xE9 +serdes_core_tx_polarity_flip_physical{178}=0xE9 +serdes_core_tx_polarity_flip_physical{179}=0xE9 +serdes_core_tx_polarity_flip_physical{180}=0xE9 +serdes_core_tx_polarity_flip_physical{181}=0xE9 +serdes_core_tx_polarity_flip_physical{182}=0xE9 +serdes_core_tx_polarity_flip_physical{183}=0xE9 +serdes_core_tx_polarity_flip_physical{184}=0xE9 + +#BC23# +dport_map_port_112=77 +dport_map_port_113=78 +dport_map_port_114=79 +dport_map_port_115=80 +portmap_112=185:400 +phy_chain_rx_lane_map_physical{185.0}=0x02561347 +phy_chain_rx_lane_map_physical{186.0}=0x02561347 +phy_chain_rx_lane_map_physical{187.0}=0x02561347 +phy_chain_rx_lane_map_physical{188.0}=0x02561347 +phy_chain_rx_lane_map_physical{189.0}=0x02561347 +phy_chain_rx_lane_map_physical{190.0}=0x02561347 +phy_chain_rx_lane_map_physical{191.0}=0x02561347 +phy_chain_rx_lane_map_physical{192.0}=0x02561347 +phy_chain_tx_lane_map_physical{185.0}=0x50327614 +phy_chain_tx_lane_map_physical{186.0}=0x50327614 +phy_chain_tx_lane_map_physical{187.0}=0x50327614 +phy_chain_tx_lane_map_physical{188.0}=0x50327614 +phy_chain_tx_lane_map_physical{189.0}=0x50327614 +phy_chain_tx_lane_map_physical{190.0}=0x50327614 +phy_chain_tx_lane_map_physical{191.0}=0x50327614 +phy_chain_tx_lane_map_physical{192.0}=0x50327614 +serdes_core_rx_polarity_flip_physical{185}=0xE1 +serdes_core_rx_polarity_flip_physical{186}=0xE1 +serdes_core_rx_polarity_flip_physical{187}=0xE1 +serdes_core_rx_polarity_flip_physical{188}=0xE1 +serdes_core_rx_polarity_flip_physical{189}=0xE1 +serdes_core_rx_polarity_flip_physical{190}=0xE1 +serdes_core_rx_polarity_flip_physical{191}=0xE1 +serdes_core_rx_polarity_flip_physical{192}=0xE1 +serdes_core_tx_polarity_flip_physical{185}=0x0 +serdes_core_tx_polarity_flip_physical{186}=0x0 +serdes_core_tx_polarity_flip_physical{187}=0x0 +serdes_core_tx_polarity_flip_physical{188}=0x0 +serdes_core_tx_polarity_flip_physical{189}=0x0 +serdes_core_tx_polarity_flip_physical{190}=0x0 +serdes_core_tx_polarity_flip_physical{191}=0x0 +serdes_core_tx_polarity_flip_physical{192}=0x0 + +#BC24# +dport_map_port_124=101 +dport_map_port_125=102 +dport_map_port_126=103 +dport_map_port_127=104 +portmap_124=193:400 +phy_chain_rx_lane_map_physical{193.0}=0x74126503 +phy_chain_rx_lane_map_physical{194.0}=0x74126503 +phy_chain_rx_lane_map_physical{195.0}=0x74126503 +phy_chain_rx_lane_map_physical{196.0}=0x74126503 +phy_chain_rx_lane_map_physical{197.0}=0x74126503 +phy_chain_rx_lane_map_physical{198.0}=0x74126503 +phy_chain_rx_lane_map_physical{199.0}=0x74126503 +phy_chain_rx_lane_map_physical{200.0}=0x74126503 +phy_chain_tx_lane_map_physical{193.0}=0x43571620 +phy_chain_tx_lane_map_physical{194.0}=0x43571620 +phy_chain_tx_lane_map_physical{195.0}=0x43571620 +phy_chain_tx_lane_map_physical{196.0}=0x43571620 +phy_chain_tx_lane_map_physical{197.0}=0x43571620 +phy_chain_tx_lane_map_physical{198.0}=0x43571620 +phy_chain_tx_lane_map_physical{199.0}=0x43571620 +phy_chain_tx_lane_map_physical{200.0}=0x43571620 +serdes_core_rx_polarity_flip_physical{193}=0x69 +serdes_core_rx_polarity_flip_physical{194}=0x69 +serdes_core_rx_polarity_flip_physical{195}=0x69 +serdes_core_rx_polarity_flip_physical{196}=0x69 +serdes_core_rx_polarity_flip_physical{197}=0x69 +serdes_core_rx_polarity_flip_physical{198}=0x69 +serdes_core_rx_polarity_flip_physical{199}=0x69 +serdes_core_rx_polarity_flip_physical{200}=0x69 +serdes_core_tx_polarity_flip_physical{193}=0xC4 +serdes_core_tx_polarity_flip_physical{194}=0xC4 +serdes_core_tx_polarity_flip_physical{195}=0xC4 +serdes_core_tx_polarity_flip_physical{196}=0xC4 +serdes_core_tx_polarity_flip_physical{197}=0xC4 +serdes_core_tx_polarity_flip_physical{198}=0xC4 +serdes_core_tx_polarity_flip_physical{199}=0xC4 +serdes_core_tx_polarity_flip_physical{200}=0xC4 + +#BC25# +dport_map_port_120=97 +dport_map_port_121=98 +dport_map_port_122=99 +dport_map_port_123=100 +portmap_120=201:400 +phy_chain_rx_lane_map_physical{201.0}=0x45031726 +phy_chain_rx_lane_map_physical{202.0}=0x45031726 +phy_chain_rx_lane_map_physical{203.0}=0x45031726 +phy_chain_rx_lane_map_physical{204.0}=0x45031726 +phy_chain_rx_lane_map_physical{205.0}=0x45031726 +phy_chain_rx_lane_map_physical{206.0}=0x45031726 +phy_chain_rx_lane_map_physical{207.0}=0x45031726 +phy_chain_rx_lane_map_physical{208.0}=0x45031726 +phy_chain_tx_lane_map_physical{201.0}=0x23761450 +phy_chain_tx_lane_map_physical{202.0}=0x23761450 +phy_chain_tx_lane_map_physical{203.0}=0x23761450 +phy_chain_tx_lane_map_physical{204.0}=0x23761450 +phy_chain_tx_lane_map_physical{205.0}=0x23761450 +phy_chain_tx_lane_map_physical{206.0}=0x23761450 +phy_chain_tx_lane_map_physical{207.0}=0x23761450 +phy_chain_tx_lane_map_physical{208.0}=0x23761450 +serdes_core_rx_polarity_flip_physical{201}=0x99 +serdes_core_rx_polarity_flip_physical{202}=0x99 +serdes_core_rx_polarity_flip_physical{203}=0x99 +serdes_core_rx_polarity_flip_physical{204}=0x99 +serdes_core_rx_polarity_flip_physical{205}=0x99 +serdes_core_rx_polarity_flip_physical{206}=0x99 +serdes_core_rx_polarity_flip_physical{207}=0x99 +serdes_core_rx_polarity_flip_physical{208}=0x99 +serdes_core_tx_polarity_flip_physical{201}=0x7F +serdes_core_tx_polarity_flip_physical{202}=0x7F +serdes_core_tx_polarity_flip_physical{203}=0x7F +serdes_core_tx_polarity_flip_physical{204}=0x7F +serdes_core_tx_polarity_flip_physical{205}=0x7F +serdes_core_tx_polarity_flip_physical{206}=0x7F +serdes_core_tx_polarity_flip_physical{207}=0x7F +serdes_core_tx_polarity_flip_physical{208}=0x7F + +#BC26# +dport_map_port_132=109 +dport_map_port_133=110 +dport_map_port_134=111 +dport_map_port_135=112 +portmap_132=209:400 +phy_chain_rx_lane_map_physical{209.0}=0x46150723 +phy_chain_rx_lane_map_physical{210.0}=0x46150723 +phy_chain_rx_lane_map_physical{211.0}=0x46150723 +phy_chain_rx_lane_map_physical{212.0}=0x46150723 +phy_chain_rx_lane_map_physical{213.0}=0x46150723 +phy_chain_rx_lane_map_physical{214.0}=0x46150723 +phy_chain_rx_lane_map_physical{215.0}=0x46150723 +phy_chain_rx_lane_map_physical{216.0}=0x46150723 +phy_chain_tx_lane_map_physical{209.0}=0x12603754 +phy_chain_tx_lane_map_physical{210.0}=0x12603754 +phy_chain_tx_lane_map_physical{211.0}=0x12603754 +phy_chain_tx_lane_map_physical{212.0}=0x12603754 +phy_chain_tx_lane_map_physical{213.0}=0x12603754 +phy_chain_tx_lane_map_physical{214.0}=0x12603754 +phy_chain_tx_lane_map_physical{215.0}=0x12603754 +phy_chain_tx_lane_map_physical{216.0}=0x12603754 +serdes_core_rx_polarity_flip_physical{209}=0xE1 +serdes_core_rx_polarity_flip_physical{210}=0xE1 +serdes_core_rx_polarity_flip_physical{211}=0xE1 +serdes_core_rx_polarity_flip_physical{212}=0xE1 +serdes_core_rx_polarity_flip_physical{213}=0xE1 +serdes_core_rx_polarity_flip_physical{214}=0xE1 +serdes_core_rx_polarity_flip_physical{215}=0xE1 +serdes_core_rx_polarity_flip_physical{216}=0xE1 +serdes_core_tx_polarity_flip_physical{209}=0x29 +serdes_core_tx_polarity_flip_physical{210}=0x29 +serdes_core_tx_polarity_flip_physical{211}=0x29 +serdes_core_tx_polarity_flip_physical{212}=0x29 +serdes_core_tx_polarity_flip_physical{213}=0x29 +serdes_core_tx_polarity_flip_physical{214}=0x29 +serdes_core_tx_polarity_flip_physical{215}=0x29 +serdes_core_tx_polarity_flip_physical{216}=0x29 + +#BC27# +dport_map_port_128=105 +dport_map_port_129=106 +dport_map_port_130=107 +dport_map_port_131=108 +portmap_128=217:400 +phy_chain_rx_lane_map_physical{217.0}=0x46127503 +phy_chain_rx_lane_map_physical{218.0}=0x46127503 +phy_chain_rx_lane_map_physical{219.0}=0x46127503 +phy_chain_rx_lane_map_physical{220.0}=0x46127503 +phy_chain_rx_lane_map_physical{221.0}=0x46127503 +phy_chain_rx_lane_map_physical{222.0}=0x46127503 +phy_chain_rx_lane_map_physical{223.0}=0x46127503 +phy_chain_rx_lane_map_physical{224.0}=0x46127503 +phy_chain_tx_lane_map_physical{217.0}=0x54273016 +phy_chain_tx_lane_map_physical{218.0}=0x54273016 +phy_chain_tx_lane_map_physical{219.0}=0x54273016 +phy_chain_tx_lane_map_physical{220.0}=0x54273016 +phy_chain_tx_lane_map_physical{221.0}=0x54273016 +phy_chain_tx_lane_map_physical{222.0}=0x54273016 +phy_chain_tx_lane_map_physical{223.0}=0x54273016 +phy_chain_tx_lane_map_physical{224.0}=0x54273016 +serdes_core_rx_polarity_flip_physical{217}=0xE1 +serdes_core_rx_polarity_flip_physical{218}=0xE1 +serdes_core_rx_polarity_flip_physical{219}=0xE1 +serdes_core_rx_polarity_flip_physical{220}=0xE1 +serdes_core_rx_polarity_flip_physical{221}=0xE1 +serdes_core_rx_polarity_flip_physical{222}=0xE1 +serdes_core_rx_polarity_flip_physical{223}=0xE1 +serdes_core_rx_polarity_flip_physical{224}=0xE1 +serdes_core_tx_polarity_flip_physical{217}=0x5B +serdes_core_tx_polarity_flip_physical{218}=0x5B +serdes_core_tx_polarity_flip_physical{219}=0x5B +serdes_core_tx_polarity_flip_physical{220}=0x5B +serdes_core_tx_polarity_flip_physical{221}=0x5B +serdes_core_tx_polarity_flip_physical{222}=0x5B +serdes_core_tx_polarity_flip_physical{223}=0x5B +serdes_core_tx_polarity_flip_physical{224}=0x5B + +#BC28# +dport_map_port_144=117 +dport_map_port_145=118 +dport_map_port_146=119 +dport_map_port_147=120 +portmap_144=225:400 +phy_chain_rx_lane_map_physical{225.0}=0x52761340 +phy_chain_rx_lane_map_physical{226.0}=0x52761340 +phy_chain_rx_lane_map_physical{227.0}=0x52761340 +phy_chain_rx_lane_map_physical{228.0}=0x52761340 +phy_chain_rx_lane_map_physical{229.0}=0x52761340 +phy_chain_rx_lane_map_physical{230.0}=0x52761340 +phy_chain_rx_lane_map_physical{231.0}=0x52761340 +phy_chain_rx_lane_map_physical{232.0}=0x52761340 +phy_chain_tx_lane_map_physical{225.0}=0x53462107 +phy_chain_tx_lane_map_physical{226.0}=0x53462107 +phy_chain_tx_lane_map_physical{227.0}=0x53462107 +phy_chain_tx_lane_map_physical{228.0}=0x53462107 +phy_chain_tx_lane_map_physical{229.0}=0x53462107 +phy_chain_tx_lane_map_physical{230.0}=0x53462107 +phy_chain_tx_lane_map_physical{231.0}=0x53462107 +phy_chain_tx_lane_map_physical{232.0}=0x53462107 +serdes_core_rx_polarity_flip_physical{225}=0x3C +serdes_core_rx_polarity_flip_physical{226}=0x3C +serdes_core_rx_polarity_flip_physical{227}=0x3C +serdes_core_rx_polarity_flip_physical{228}=0x3C +serdes_core_rx_polarity_flip_physical{229}=0x3C +serdes_core_rx_polarity_flip_physical{230}=0x3C +serdes_core_rx_polarity_flip_physical{231}=0x3C +serdes_core_rx_polarity_flip_physical{232}=0x3C +serdes_core_tx_polarity_flip_physical{225}=0x71 +serdes_core_tx_polarity_flip_physical{226}=0x71 +serdes_core_tx_polarity_flip_physical{227}=0x71 +serdes_core_tx_polarity_flip_physical{228}=0x71 +serdes_core_tx_polarity_flip_physical{229}=0x71 +serdes_core_tx_polarity_flip_physical{230}=0x71 +serdes_core_tx_polarity_flip_physical{231}=0x71 +serdes_core_tx_polarity_flip_physical{232}=0x71 + +#BC29# +dport_map_port_140=113 +dport_map_port_141=114 +dport_map_port_142=115 +dport_map_port_143=116 +portmap_140=233:400 +phy_chain_rx_lane_map_physical{233.0}=0x45021736 +phy_chain_rx_lane_map_physical{234.0}=0x45021736 +phy_chain_rx_lane_map_physical{235.0}=0x45021736 +phy_chain_rx_lane_map_physical{236.0}=0x45021736 +phy_chain_rx_lane_map_physical{237.0}=0x45021736 +phy_chain_rx_lane_map_physical{238.0}=0x45021736 +phy_chain_rx_lane_map_physical{239.0}=0x45021736 +phy_chain_rx_lane_map_physical{240.0}=0x45021736 +phy_chain_tx_lane_map_physical{233.0}=0x20465371 +phy_chain_tx_lane_map_physical{234.0}=0x20465371 +phy_chain_tx_lane_map_physical{235.0}=0x20465371 +phy_chain_tx_lane_map_physical{236.0}=0x20465371 +phy_chain_tx_lane_map_physical{237.0}=0x20465371 +phy_chain_tx_lane_map_physical{238.0}=0x20465371 +phy_chain_tx_lane_map_physical{239.0}=0x20465371 +phy_chain_tx_lane_map_physical{240.0}=0x20465371 +serdes_core_rx_polarity_flip_physical{233}=0x8B +serdes_core_rx_polarity_flip_physical{234}=0x8B +serdes_core_rx_polarity_flip_physical{235}=0x8B +serdes_core_rx_polarity_flip_physical{236}=0x8B +serdes_core_rx_polarity_flip_physical{237}=0x8B +serdes_core_rx_polarity_flip_physical{238}=0x8B +serdes_core_rx_polarity_flip_physical{239}=0x8B +serdes_core_rx_polarity_flip_physical{240}=0x8B +serdes_core_tx_polarity_flip_physical{233}=0x35 +serdes_core_tx_polarity_flip_physical{234}=0x35 +serdes_core_tx_polarity_flip_physical{235}=0x35 +serdes_core_tx_polarity_flip_physical{236}=0x35 +serdes_core_tx_polarity_flip_physical{237}=0x35 +serdes_core_tx_polarity_flip_physical{238}=0x35 +serdes_core_tx_polarity_flip_physical{239}=0x35 +serdes_core_tx_polarity_flip_physical{240}=0x35 + +#BC30# +dport_map_port_152=125 +dport_map_port_153=126 +dport_map_port_154=127 +dport_map_port_155=128 +portmap_152=241:400 +phy_chain_rx_lane_map_physical{241.0}=0x65721403 +phy_chain_rx_lane_map_physical{242.0}=0x65721403 +phy_chain_rx_lane_map_physical{243.0}=0x65721403 +phy_chain_rx_lane_map_physical{244.0}=0x65721403 +phy_chain_rx_lane_map_physical{245.0}=0x65721403 +phy_chain_rx_lane_map_physical{246.0}=0x65721403 +phy_chain_rx_lane_map_physical{247.0}=0x65721403 +phy_chain_rx_lane_map_physical{248.0}=0x65721403 +phy_chain_tx_lane_map_physical{241.0}=0x32647150 +phy_chain_tx_lane_map_physical{242.0}=0x32647150 +phy_chain_tx_lane_map_physical{243.0}=0x32647150 +phy_chain_tx_lane_map_physical{244.0}=0x32647150 +phy_chain_tx_lane_map_physical{245.0}=0x32647150 +phy_chain_tx_lane_map_physical{246.0}=0x32647150 +phy_chain_tx_lane_map_physical{247.0}=0x32647150 +phy_chain_tx_lane_map_physical{248.0}=0x32647150 +serdes_core_rx_polarity_flip_physical{241}=0x8D +serdes_core_rx_polarity_flip_physical{242}=0x8D +serdes_core_rx_polarity_flip_physical{243}=0x8D +serdes_core_rx_polarity_flip_physical{244}=0x8D +serdes_core_rx_polarity_flip_physical{245}=0x8D +serdes_core_rx_polarity_flip_physical{246}=0x8D +serdes_core_rx_polarity_flip_physical{247}=0x8D +serdes_core_rx_polarity_flip_physical{248}=0x8D +serdes_core_tx_polarity_flip_physical{241}=0x35 +serdes_core_tx_polarity_flip_physical{242}=0x35 +serdes_core_tx_polarity_flip_physical{243}=0x35 +serdes_core_tx_polarity_flip_physical{244}=0x35 +serdes_core_tx_polarity_flip_physical{245}=0x35 +serdes_core_tx_polarity_flip_physical{246}=0x35 +serdes_core_tx_polarity_flip_physical{247}=0x35 +serdes_core_tx_polarity_flip_physical{248}=0x35 + +#BC31# +dport_map_port_148=121 +dport_map_port_149=122 +dport_map_port_150=123 +dport_map_port_151=124 +portmap_148=249:400 +phy_chain_rx_lane_map_physical{249.0}=0x13560247 +phy_chain_rx_lane_map_physical{250.0}=0x13560247 +phy_chain_rx_lane_map_physical{251.0}=0x13560247 +phy_chain_rx_lane_map_physical{252.0}=0x13560247 +phy_chain_rx_lane_map_physical{253.0}=0x13560247 +phy_chain_rx_lane_map_physical{254.0}=0x13560247 +phy_chain_rx_lane_map_physical{255.0}=0x13560247 +phy_chain_rx_lane_map_physical{256.0}=0x13560247 +phy_chain_tx_lane_map_physical{249.0}=0x10456273 +phy_chain_tx_lane_map_physical{250.0}=0x10456273 +phy_chain_tx_lane_map_physical{251.0}=0x10456273 +phy_chain_tx_lane_map_physical{252.0}=0x10456273 +phy_chain_tx_lane_map_physical{253.0}=0x10456273 +phy_chain_tx_lane_map_physical{254.0}=0x10456273 +phy_chain_tx_lane_map_physical{255.0}=0x10456273 +phy_chain_tx_lane_map_physical{256.0}=0x10456273 +serdes_core_rx_polarity_flip_physical{249}=0x2D +serdes_core_rx_polarity_flip_physical{250}=0x2D +serdes_core_rx_polarity_flip_physical{251}=0x2D +serdes_core_rx_polarity_flip_physical{252}=0x2D +serdes_core_rx_polarity_flip_physical{253}=0x2D +serdes_core_rx_polarity_flip_physical{254}=0x2D +serdes_core_rx_polarity_flip_physical{255}=0x2D +serdes_core_rx_polarity_flip_physical{256}=0x2D +serdes_core_tx_polarity_flip_physical{249}=0xD6 +serdes_core_tx_polarity_flip_physical{250}=0xD6 +serdes_core_tx_polarity_flip_physical{251}=0xD6 +serdes_core_tx_polarity_flip_physical{252}=0xD6 +serdes_core_tx_polarity_flip_physical{253}=0xD6 +serdes_core_tx_polarity_flip_physical{254}=0xD6 +serdes_core_tx_polarity_flip_physical{255}=0xD6 +serdes_core_tx_polarity_flip_physical{256}=0xD6 + +#dport_map_port_38=129 +#portmap_38=257:10 +#dport_map_port_118=130 +#portmap_118=258:10 diff --git a/device/accton/x86_64-accton_as9716_32d-r0/custom_led.bin b/device/accton/x86_64-accton_as9716_32d-r0/custom_led.bin new file mode 100644 index 000000000000..07cfab044f60 Binary files /dev/null and b/device/accton/x86_64-accton_as9716_32d-r0/custom_led.bin differ diff --git a/device/accton/x86_64-accton_as9716_32d-r0/led_proc_init.soc b/device/accton/x86_64-accton_as9716_32d-r0/led_proc_init.soc new file mode 100644 index 000000000000..57ee7fedaf2b --- /dev/null +++ b/device/accton/x86_64-accton_as9716_32d-r0/led_proc_init.soc @@ -0,0 +1,3 @@ +m0 load 0 0x3800 /usr/share/sonic/platform/custom_led.bin +led auto on +led start diff --git a/device/accton/x86_64-accton_as9716_32d-r0/plugins/eeprom.py b/device/accton/x86_64-accton_as9716_32d-r0/plugins/eeprom.py index 1e7d1046d93d..9031f2c60ece 100644 --- a/device/accton/x86_64-accton_as9716_32d-r0/plugins/eeprom.py +++ b/device/accton/x86_64-accton_as9716_32d-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -11,11 +8,26 @@ 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") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +def eeprom_check(): + filepath = "/sys/bus/i2c/devices/0-0057/eeprom" + if os.path.isfile(filepath): + return 1 # now board, 0x57 + else: + return 0 # now board, 0x56 + class board(eeprom_tlvinfo.TlvInfoDecoder): _TLV_INFO_MAX_LEN = 256 + def __init__(self, name, path, cpld_root, ro): - self.eeprom_path = "/sys/bus/i2c/devices/0-0056/eeprom" + ret = eeprom_check() + if ret == 1: + self.eeprom_path = "/sys/bus/i2c/devices/0-0057/eeprom" + else: + self.eeprom_path = "/sys/bus/i2c/devices/0-0056/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/accton/x86_64-accton_as9716_32d-r0/plugins/psuutil.py b/device/accton/x86_64-accton_as9716_32d-r0/plugins/psuutil.py index 25eceb7428c7..ef49f262dca9 100644 --- a/device/accton/x86_64-accton_as9716_32d-r0/plugins/psuutil.py +++ b/device/accton/x86_64-accton_as9716_32d-r0/plugins/psuutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Accton # @@ -13,7 +11,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" diff --git a/device/accton/x86_64-accton_as9716_32d-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as9716_32d-r0/plugins/sfputil.py old mode 100644 new mode 100755 index bc3297471c5c..7b3ca53d4ed4 --- a/device/accton/x86_64-accton_as9716_32d-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as9716_32d-r0/plugins/sfputil.py @@ -5,6 +5,9 @@ try: import time + import os + import sys + from ctypes import create_string_buffer from sonic_sfp.sfputilbase import SfpUtilBase except ImportError as e: raise ImportError("%s - required module not found" % str(e)) @@ -12,55 +15,55 @@ class SfpUtil(SfpUtilBase): """Platform-specific SfpUtil class""" - + PORT_START = 0 PORT_END = 33 PORTS_IN_BLOCK = 34 - + BASE_OOM_PATH = "/sys/bus/i2c/devices/{0}-0050/" BASE_CPLD1_PATH = "/sys/bus/i2c/devices/20-0061/" BASE_CPLD2_PATH = "/sys/bus/i2c/devices/21-0062/" - + _port_to_is_present = {} _port_to_lp_mode = {} _port_to_eeprom_mapping = {} _port_to_i2c_mapping = { - 0: [1, 25], - 1: [2, 26], - 2: [3, 27], - 3: [4, 28], - 4: [5, 29], - 5: [6, 30], - 6: [7, 31], - 7: [8, 32], - 8: [9, 33], - 9: [10, 34], - 10: [11, 35], - 11: [12, 36], - 12: [13, 37], - 13: [14, 38], - 14: [15, 39], - 15: [16, 40], - 16: [17, 41], - 17: [18, 42], - 18: [19, 43], - 19: [20, 44], - 20: [21, 45], - 21: [22, 46], - 22: [23, 47], - 23: [24, 48], - 24: [25, 49], - 25: [26, 50], - 26: [27, 51], - 27: [28, 52], - 28: [29, 53], - 29: [30, 54], - 30: [31, 55], - 31: [32, 56], - 32: [33, 57], - 33: [34, 58], - } + 0: [1, 25], + 1: [2, 26], + 2: [3, 27], + 3: [4, 28], + 4: [5, 29], + 5: [6, 30], + 6: [7, 31], + 7: [8, 32], + 8: [9, 33], + 9: [10, 34], + 10: [11, 35], + 11: [12, 36], + 12: [13, 37], + 13: [14, 38], + 14: [15, 39], + 15: [16, 40], + 16: [17, 41], + 17: [18, 42], + 18: [19, 43], + 19: [20, 44], + 20: [21, 45], + 21: [22, 46], + 22: [23, 47], + 23: [24, 48], + 24: [25, 49], + 25: [26, 50], + 26: [27, 51], + 27: [28, 52], + 28: [29, 53], + 29: [30, 54], + 30: [31, 55], + 31: [32, 56], + 32: [33, 57], + 33: [34, 58], + } @property def port_start(self): @@ -69,10 +72,10 @@ def port_start(self): @property def port_end(self): return self.PORT_END - + @property def qsfp_ports(self): - return range(self.PORT_START, self.PORTS_IN_BLOCK + 1) + return list(range(self.PORT_START, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -80,11 +83,11 @@ def port_to_eeprom_mapping(self): def __init__(self): eeprom_path = self.BASE_OOM_PATH + "eeprom" - + for x in range(0, self.port_end+1): self.port_to_eeprom_mapping[x] = eeprom_path.format( self._port_to_i2c_mapping[x][1] - ) + ) SfpUtilBase.__init__(self) @@ -92,19 +95,19 @@ 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 - if port_num < 16 : + if port_num < 16: present_path = self.BASE_CPLD1_PATH + "module_present_" + str(port_num+1) else: present_path = self.BASE_CPLD2_PATH + "module_present_" + str(port_num+1) self.__port_to_is_present = present_path - content="0" + content = "0" try: val_file = open(self.__port_to_is_present) content = val_file.readline().rstrip() val_file.close() except IOError as e: - print "Error: unable to access file: %s" % str(e) + print("Error: unable to access file: %s" % str(e)) return False if content == "1": @@ -112,39 +115,176 @@ def get_presence(self, port_num): return False - def get_low_power_mode(self, port_num): - raise NotImplementedError - + def get_low_power_mode(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + try: + eeprom = None + + if not self.get_presence(port_num): + return False + + eeprom = open(self.port_to_eeprom_mapping[port_num], "rb") + eeprom.seek(93) + lpmode = ord(eeprom.read(1)) + + if ((lpmode & 0x3) == 0x3): + return True # Low Power Mode if "Power override" bit is 1 and "Power set" bit is 1 + else: + # High Power Mode if one of the following conditions is matched: + # 1. "Power override" bit is 0 + # 2. "Power override" bit is 1 and "Power set" bit is 0 + return False + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) + def set_low_power_mode(self, port_num, lpmode): - raise NotImplementedError + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + try: + eeprom = None + + if not self.get_presence(port_num): + return False # Port is not present, unable to set the eeprom + + # Fill in write buffer + # 0x3:Low Power Mode. "Power override" bit is 1 and "Power set" bit is 1 + # 0x9:High Power Mode. "Power override" bit is 1 ,"Power set" bit is 0 and "High Power Class Enable" bit is 1 + regval = 0x3 if lpmode else 0x9 + + buffer = create_string_buffer(1) + buffer[0] = chr(regval) + + # Write to eeprom + eeprom = open(self.port_to_eeprom_mapping[port_num], "r+b") + eeprom.seek(93) + eeprom.write(buffer[0]) + return True + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) def reset(self, port_num): if port_num < self.port_start or port_num > self.port_end: return False - - if port_num < 16 : + + if port_num < 16: mod_rst_path = self.BASE_CPLD1_PATH + "module_reset_" + str(port_num+1) else: mod_rst_path = self.BASE_CPLD2_PATH + "module_reset_" + str(port_num+1) - + self.__port_to_mod_rst = mod_rst_path try: reg_file = open(self.__port_to_mod_rst, 'r+') except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = '1' reg_file.write(reg_value) reg_file.close() - + return True - - 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 \ No newline at end of file + + def get_cpld_interrupt(self): + port_dict = {} + for i in range(0, 4): + if i == 0 or i == 1: + cpld_i2c_path = self.BASE_CPLD1_PATH + "cpld_intr_" + str(i+1) + else: + cpld_i2c_path = self.BASE_CPLD2_PATH + "cpld_intr_" + str(i+1) + + start_i = (i*8) + end_i = (i*8+8) + try: + val_file = open(cpld_i2c_path) + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + + for k in range(start_i, end_i): + port_dict[k] = 0 + return port_dict + + status = val_file.readline().rstrip() + val_file.close() + status = status.strip() + status = int(status, 16) + + interrupt_status = ~(status & 0xff) + if interrupt_status: + port_shift = 0 + for k in range(start_i, end_i): + if interrupt_status & (0x1 << port_shift): + port_dict[k] = 1 + else: + port_dict[k] = 0 + port_shift = port_shift+1 + + return port_dict + + def get_transceiver_change_event(self, timeout=0): + start_time = time.time() + port_dict = {} + ori_present = {} + forever = False + + if timeout == 0: + forever = True + elif timeout > 0: + timeout = timeout / float(1000) # Convert to secs + else: + print("get_transceiver_change_event:Invalid timeout value", timeout) + return False, {} + + end_time = start_time + timeout + if start_time > end_time: + print('get_transceiver_change_event:' + 'time wrap / invalid timeout value', timeout) + + return False, {} # Time wrap or possibly incorrect timeout + + # for i in range(self.port_start, self.port_end+1): + # ori_present[i]=self.get_presence(i) + + while timeout >= 0: + change_status = 0 + + port_dict = self.get_cpld_interrupt() + present = 0 + for key, value in port_dict.items(): + if value == 1: + present = self.get_presence(key) + change_status = 1 + if present: + port_dict[key] = '1' + else: + port_dict[key] = '0' + + if change_status: + return True, port_dict + if forever: + time.sleep(1) + else: + timeout = end_time - time.time() + if timeout >= 1: + time.sleep(1) # We poll at 1 second granularity + else: + if timeout > 0: + time.sleep(timeout) + return True, {} + print("get_evt_change_event: Should not reach here.") + return False, {} diff --git a/device/accton/x86_64-accton_as9716_32d-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as9716_32d-r0/pmon_daemon_control.json index 44bad6494229..584a14b9d942 100644 --- a/device/accton/x86_64-accton_as9716_32d-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as9716_32d-r0/pmon_daemon_control.json @@ -1,4 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/accton/x86_64-accton_minipack-r0/Accton-MINIPACK/config_16Q_FEC544_EVTA_100G.bcm b/device/accton/x86_64-accton_minipack-r0/Accton-MINIPACK/config_16Q_FEC544_EVTA_100G.bcm index 9f4066cc736d..a9dfbd4797e1 100755 --- a/device/accton/x86_64-accton_minipack-r0/Accton-MINIPACK/config_16Q_FEC544_EVTA_100G.bcm +++ b/device/accton/x86_64-accton_minipack-r0/Accton-MINIPACK/config_16Q_FEC544_EVTA_100G.bcm @@ -15,6 +15,10 @@ dpr_clock_frequency=1000 device_clock_frequency=1325 port_flex_enable=1 +l3_alpm_enable=2 +l3_mem_entries=983040 +ipv6_lpm_128b_enable=1 + #firmware load method, use fast load load_firmware=0x2 diff --git a/device/accton/x86_64-accton_minipack-r0/Accton-MINIPACK/config_16Q_FEC544_EVTB_100G.bcm b/device/accton/x86_64-accton_minipack-r0/Accton-MINIPACK/config_16Q_FEC544_EVTB_100G.bcm index a72f22bbfd98..676dcdd89bd1 100755 --- a/device/accton/x86_64-accton_minipack-r0/Accton-MINIPACK/config_16Q_FEC544_EVTB_100G.bcm +++ b/device/accton/x86_64-accton_minipack-r0/Accton-MINIPACK/config_16Q_FEC544_EVTB_100G.bcm @@ -15,6 +15,10 @@ dpr_clock_frequency=1000 device_clock_frequency=1325 port_flex_enable=1 +l3_alpm_enable=2 +l3_mem_entries=983040 +ipv6_lpm_128b_enable=1 + #firmware load method, use fast load load_firmware=0x2 @@ -1463,25 +1467,3 @@ serdes_core_tx_polarity_flip_physical{254}=0x7E serdes_core_tx_polarity_flip_physical{255}=0x7E serdes_core_tx_polarity_flip_physical{256}=0x7E -dport_map_port_38=299 -portmap_38=257:10 - -dport_map_port_118=300 -portmap_118=258:10 - -portmap_19=259:10 - -portmap_39=260:10 - -portmap_59=261:10 - -portmap_79=262:10 - -portmap_99=263:10 - -portmap_119=264:10 - -portmap_139=265:10 - -portmap_159=266:10 - diff --git a/device/accton/x86_64-accton_minipack-r0/plugins/eeprom.py b/device/accton/x86_64-accton_minipack-r0/plugins/eeprom.py index c1ac366fc3fa..3912194484db 100644 --- a/device/accton/x86_64-accton_minipack-r0/plugins/eeprom.py +++ b/device/accton/x86_64-accton_minipack-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -11,11 +8,13 @@ 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") +except ImportError as 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/1-0057/eeprom" super(board, self).__init__(self.eeprom_path, 0x200, '', True) diff --git a/device/accton/x86_64-accton_minipack-r0/plugins/led_control.py b/device/accton/x86_64-accton_minipack-r0/plugins/led_control.py index 26e2a7f7c8a2..a11a31062367 100755 --- a/device/accton/x86_64-accton_minipack-r0/plugins/led_control.py +++ b/device/accton/x86_64-accton_minipack-r0/plugins/led_control.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python -# # led_control.py # # Platform-specific LED control functionality for SONiC @@ -17,19 +15,18 @@ from socket import * from select import * from minipack.pimutil import PimUtil -except ImportError, e: +except ImportError as e: raise ImportError(str(e) + " - required module not found") class LedControl(LedControlBase): """Platform specific LED control class""" SONIC_PORT_NAME_PREFIX = "Ethernet" - - + def __init__(self): - pim=PimUtil() + pim = PimUtil() pim.init_pim_fpga() - + def _port_name_to_index(self, port_name): # Strip "Ethernet" off port name if not port_name.startswith(self.SONIC_PORT_NAME_PREFIX): @@ -37,23 +34,22 @@ def _port_name_to_index(self, port_name): port_idx = int(port_name[len(self.SONIC_PORT_NAME_PREFIX):]) return port_idx - + def _port_state_to_mode(self, port_idx, state): if state == "up": - return 1, 4 #port linkup, led is green + return 1, 4 # port linkup, led is green else: - return 0, 0 #port linkdown, led is off + return 0, 0 # port linkdown, led is off def port_link_state_change(self, portname, state): - pim=PimUtil() + pim = PimUtil() port_idx = self._port_name_to_index(portname) new_control, led_mode = self._port_state_to_mode(port_idx, state) - color, control=pim.get_port_led(port_idx) - - if color==led_mode: - if control==new_control: + color, control = pim.get_port_led(port_idx) + + if color == led_mode: + if control == new_control: return - - pim.set_port_led(port_idx, led_mode, new_control)#port linkup, led is green - #port linkdown, led is off + pim.set_port_led(port_idx, led_mode, new_control) # port linkup, led is green + # port linkdown, led is off diff --git a/device/accton/x86_64-accton_minipack-r0/plugins/psuutil.py b/device/accton/x86_64-accton_minipack-r0/plugins/psuutil.py index 99e1bbae9377..2a8bd232db44 100644 --- a/device/accton/x86_64-accton_minipack-r0/plugins/psuutil.py +++ b/device/accton/x86_64-accton_minipack-r0/plugins/psuutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Accton # @@ -13,7 +11,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" diff --git a/device/accton/x86_64-accton_minipack-r0/plugins/sfputil.py b/device/accton/x86_64-accton_minipack-r0/plugins/sfputil.py index 6f62d8ed4c07..85dc5f81f5ac 100755 --- a/device/accton/x86_64-accton_minipack-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_minipack-r0/plugins/sfputil.py @@ -7,20 +7,20 @@ import time from sonic_sfp.sfputilbase import SfpUtilBase import os - import sys, getopt - from minipack.pimutil import PimUtil + import sys + from minipack.pimutil import PimUtil except ImportError as e: raise ImportError("%s - required module not found" % str(e)) class SfpUtil(SfpUtilBase): """Platform-specific SfpUtil class""" - + PORT_START = 0 PORT_END = 128 - + LOCAL_OOM_PATH = "/usr/local/bin/minipack_qsfp/port%d_eeprom" - + _port_to_is_present = {} _port_to_lp_mode = {} @@ -33,10 +33,10 @@ def port_start(self): @property def port_end(self): return self.PORT_END - + @property def qsfp_ports(self): - return range(self.PORT_START, self.PORT_END + 1) + return list(range(self.PORT_START, self.PORT_END + 1)) @property def port_to_eeprom_mapping(self): @@ -47,100 +47,99 @@ def sfp_map(self, index): base = ((port-1)/8*8) + 10 index = (port - 1) % 8 index = 7 - index - if (index%2): - index = index -1 + if (index % 2): + index = index - 1 else: - index = index +1 + index = index + 1 bus = base + index return bus - def __init__(self): - for x in range(0, self.port_end): - self.port_to_eeprom_mapping[x] = self.LOCAL_OOM_PATH %x + for x in range(0, self.port_end): + self.port_to_eeprom_mapping[x] = self.LOCAL_OOM_PATH % x SfpUtilBase.__init__(self) - pim=PimUtil() + pim = PimUtil() pim.init_pim_fpga() - + def __del__(self): - self.value=0 + self.value = 0 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 - pim=PimUtil() - status=pim.get_qsfp_presence(port_num) + pim = PimUtil() + status = pim.get_qsfp_presence(port_num) return status - - def get_low_power_mode(self, port_num): + + def get_low_power_mode(self, port_num): if port_num < self.port_start or port_num > self.port_end: return False - pim=PimUtil() + pim = PimUtil() return pim.get_low_power_mode(port_num) - + def set_low_power_mode(self, port_num, lpmode): if port_num < self.port_start or port_num > self.port_end: return False - pim=PimUtil() - pim.set_low_power_mode(port_num, lpmode) - return True + pim = PimUtil() + pim.set_low_power_mode(port_num, lpmode) + return True def reset(self, port_num): if port_num < self.port_start or port_num > self.port_end: return False - pim=PimUtil() + pim = PimUtil() pim.reset(port_num) - return True - + return True + def get_transceiver_change_event(self, timeout=0): - pim=PimUtil() + pim = PimUtil() start_time = time.time() port_dict = {} forever = False - + if timeout == 0: forever = True elif timeout > 0: - timeout = timeout / float(1000) # Convert to secs + timeout = timeout / float(1000) # Convert to secs else: - print "get_transceiver_change_event:Invalid timeout value", timeout + print("get_transceiver_change_event:Invalid timeout value", timeout) return False, {} end_time = start_time + timeout if start_time > end_time: - print 'get_transceiver_change_event:' \ - 'time wrap / invalid timeout value', timeout + print('get_transceiver_change_event:' + 'time wrap / invalid timeout value', timeout) + + return False, {} # Time wrap or possibly incorrect timeout - return False, {} # Time wrap or possibly incorrect timeout - - while timeout >= 0: - change_status=0 + while timeout >= 0: + change_status = 0 port_dict = pim.get_qsfp_interrupt() - present=0 - for key, value in port_dict.iteritems(): - if value==1: - present=self.get_presence(key) - change_status=1 + present = 0 + for key, value in port_dict.items(): + if value == 1: + present = self.get_presence(key) + change_status = 1 if present: - port_dict[key]='1' + port_dict[key] = '1' else: - port_dict[key]='0' - - if change_status: + port_dict[key] = '0' + + if change_status: return True, port_dict if forever: time.sleep(1) else: timeout = end_time - time.time() if timeout >= 1: - time.sleep(1) # We poll at 1 second granularity + time.sleep(1) # We poll at 1 second granularity else: if timeout > 0: time.sleep(timeout) return True, {} - print "get_evt_change_event: Should not reach here." + print("get_evt_change_event: Should not reach here.") return False, {} diff --git a/device/accton/x86_64-accton_minipack-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_minipack-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..584a14b9d942 --- /dev/null +++ b/device/accton/x86_64-accton_minipack-r0/pmon_daemon_control.json @@ -0,0 +1,5 @@ +{ + "skip_ledd": true, + "skip_thermalctld": true +} + diff --git a/device/alphanetworks/x86_64-alphanetworks_snh60a0_320fv2-r0/Alphanetworks-SNH60A0-320FV2/sai.profile b/device/alphanetworks/x86_64-alphanetworks_snh60a0_320fv2-r0/Alphanetworks-SNH60A0-320FV2/sai.profile index b6e792ad0a18..66d99a8450c3 100644 --- a/device/alphanetworks/x86_64-alphanetworks_snh60a0_320fv2-r0/Alphanetworks-SNH60A0-320FV2/sai.profile +++ b/device/alphanetworks/x86_64-alphanetworks_snh60a0_320fv2-r0/Alphanetworks-SNH60A0-320FV2/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-snh60a0-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/alphanetworks/x86_64-alphanetworks_snh60a0_320fv2-r0/plugins/eeprom.py b/device/alphanetworks/x86_64-alphanetworks_snh60a0_320fv2-r0/plugins/eeprom.py index c0122e65844a..9e4e9970e9f5 100644 --- a/device/alphanetworks/x86_64-alphanetworks_snh60a0_320fv2-r0/plugins/eeprom.py +++ b/device/alphanetworks/x86_64-alphanetworks_snh60a0_320fv2-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -11,14 +8,16 @@ 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") +except ImportError as 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/1-0056/eeprom" - #Two i2c buses might get flipped order, check them both. + # Two i2c buses might get flipped order, check them both. if not os.path.exists(self.eeprom_path): self.eeprom_path = "/sys/bus/i2c/devices/0-0056/eeprom" super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/alphanetworks/x86_64-alphanetworks_snh60a0_320fv2-r0/plugins/led_control.py b/device/alphanetworks/x86_64-alphanetworks_snh60a0_320fv2-r0/plugins/led_control.py index bab96d69dc47..4da72e7f7a04 100644 --- a/device/alphanetworks/x86_64-alphanetworks_snh60a0_320fv2-r0/plugins/led_control.py +++ b/device/alphanetworks/x86_64-alphanetworks_snh60a0_320fv2-r0/plugins/led_control.py @@ -1,22 +1,19 @@ -#!/usr/bin/env python -# -# led_control.py -# # Platform-specific LED control functionality for SONiC # # try: # from sonic_led.led_control_base import LedControlBase # import swsssdk -# except ImportError, e: +# except ImportError as e: # raise ImportError (str(e) + " - required module not found") import time + class LedControlBase(object): -# __metaclass__ = abc.ABCMeta + # __metaclass__ = abc.ABCMeta -# @abc.abstractmethod + # @abc.abstractmethod def port_link_state_change(self, port, state): """ Called when port link state changes. Update port link state LED here. @@ -26,6 +23,7 @@ def port_link_state_change(self, port, state): """ return + ### Zion specified ### read_fan_fault = 0 is_fan_all_OK = 0 @@ -35,126 +33,128 @@ def port_link_state_change(self, port, state): is_reset_button_push = 0 ########################## + def sysled_task(): while True: system_led_check() time.sleep(5) - + ### Zion specified ### + + def system_led_check(): - global read_fan_fault, read_power_status, is_fan_all_OK, is_power_all_OK, is_thermal_high, is_reset_button_push - is_fan_all_OK = 1 - is_power_all_OK = 0 - is_thermal_high = 0 - is_reset_button_push = 0 - with open("/sys/bus/i2c/devices/1-005e/fan1_fault", "r") as f1: - read_fan_fault = f1.read() - with open("/sys/bus/i2c/devices/9-005f/fan1_led", "w") as f11: - if str(read_fan_fault) == str("1\n"): - is_fan_all_OK = 0 - f11.write("4") - else: - f11.write("1") - with open("/sys/bus/i2c/devices/1-005e/fan2_fault", "r") as f1: - read_fan_fault = f1.read() - with open("/sys/bus/i2c/devices/9-005f/fan2_led", "w") as f11: - if str(read_fan_fault) == str("1\n"): - is_fan_all_OK = 0 - f11.write("4") - else: - f11.write("1") - with open("/sys/bus/i2c/devices/1-005e/fan3_fault", "r") as f1: - read_fan_fault = f1.read() - with open("/sys/bus/i2c/devices/9-005f/fan3_led", "w") as f11: - if str(read_fan_fault) == str("1\n"): - is_fan_all_OK = 0 - f11.write("4") - else: - f11.write("1") - with open("/sys/bus/i2c/devices/1-005e/fan4_fault", "r") as f1: - read_fan_fault = f1.read() - with open("/sys/bus/i2c/devices/9-005f/fan4_led", "w") as f11: - if str(read_fan_fault) == str("1\n"): - is_fan_all_OK = 0 - f11.write("4") - else: - f11.write("1") - with open("/sys/bus/i2c/devices/1-005e/fan5_fault", "r") as f1: - read_fan_fault = f1.read() - with open("/sys/bus/i2c/devices/9-005f/fan5_led", "w") as f11: - if str(read_fan_fault) == str("1\n"): - is_fan_all_OK = 0 - f11.write("4") - else: - f11.write("1") - with open("/sys/bus/i2c/devices/1-005e/fan6_fault", "r") as f1: - read_fan_fault = f1.read() - with open("/sys/bus/i2c/devices/9-005f/fan6_led", "w") as f11: - if str(read_fan_fault) == str("1\n"): - is_fan_all_OK = 0 - f11.write("4") - else: - f11.write("1") - - - with open("/sys/bus/i2c/devices/1-005e/psu1_power_good", "r") as f1: - read_power_status = f1.read() - with open("/sys/bus/i2c/devices/9-005f/sys_pwr", "w") as f11: - if str(read_power_status) == str("1\n"): - f11.write("1") - else: - f11.write("4") - with open("/sys/bus/i2c/devices/1-005e/psu1_present", "r") as f1: - read_power_status = f1.read() - with open("/sys/bus/i2c/devices/9-005f/sys_pwr", "w") as f11: - if str(read_power_status) == str("1\n"): - is_power_all_OK = is_power_all_OK + 1 - f11.write("1") - else: - f11.write("4") - with open("/sys/bus/i2c/devices/1-005e/psu2_power_good", "r") as f1: - read_power_status = f1.read() - with open("/sys/bus/i2c/devices/9-005f/sys_pwr", "w") as f11: - if str(read_power_status) == str("1\n"): - f11.write("1") - else: - f11.write("4") - with open("/sys/bus/i2c/devices/1-005e/psu2_present", "r") as f1: - read_power_status = f1.read() - with open("/sys/bus/i2c/devices/9-005f/sys_pwr", "w") as f11: - if str(read_power_status) == str("1\n"): - is_power_all_OK = is_power_all_OK + 1 - f11.write("1") - else: - f11.write("4") - - - with open("/sys/bus/i2c/devices/9-005f/swi_ctrl", "r") as f5: - is_reset_button_push = f5.read() - if str(is_reset_button_push) == "1\n": - is_reset_button_push = 1 - else: - is_reset_button_push = 0 - - with open("/sys/bus/i2c/devices/4-004d/hwmon/hwmon3/temp1_input", "r") as f3: - is_thermal_high = f3.read() - if int(is_thermal_high) >= 70000: - is_thermal_high = 1 - else: - is_thermal_high = 0 - - with open("/sys/bus/i2c/devices/9-005f/sys_status", "w") as f2: - if is_reset_button_push == 1: - f2.write("3") - elif is_fan_all_OK == 0 or is_power_all_OK == 0 or is_thermal_high == 1: - f2.write("4") - else: - f2.write("1") - - return + global read_fan_fault, read_power_status, is_fan_all_OK, is_power_all_OK, is_thermal_high, is_reset_button_push + + is_fan_all_OK = 1 + is_power_all_OK = 0 + is_thermal_high = 0 + is_reset_button_push = 0 + with open("/sys/bus/i2c/devices/1-005e/fan1_fault", "r") as f1: + read_fan_fault = f1.read() + with open("/sys/bus/i2c/devices/9-005f/fan1_led", "w") as f11: + if str(read_fan_fault) == str("1\n"): + is_fan_all_OK = 0 + f11.write("4") + else: + f11.write("1") + with open("/sys/bus/i2c/devices/1-005e/fan2_fault", "r") as f1: + read_fan_fault = f1.read() + with open("/sys/bus/i2c/devices/9-005f/fan2_led", "w") as f11: + if str(read_fan_fault) == str("1\n"): + is_fan_all_OK = 0 + f11.write("4") + else: + f11.write("1") + with open("/sys/bus/i2c/devices/1-005e/fan3_fault", "r") as f1: + read_fan_fault = f1.read() + with open("/sys/bus/i2c/devices/9-005f/fan3_led", "w") as f11: + if str(read_fan_fault) == str("1\n"): + is_fan_all_OK = 0 + f11.write("4") + else: + f11.write("1") + with open("/sys/bus/i2c/devices/1-005e/fan4_fault", "r") as f1: + read_fan_fault = f1.read() + with open("/sys/bus/i2c/devices/9-005f/fan4_led", "w") as f11: + if str(read_fan_fault) == str("1\n"): + is_fan_all_OK = 0 + f11.write("4") + else: + f11.write("1") + with open("/sys/bus/i2c/devices/1-005e/fan5_fault", "r") as f1: + read_fan_fault = f1.read() + with open("/sys/bus/i2c/devices/9-005f/fan5_led", "w") as f11: + if str(read_fan_fault) == str("1\n"): + is_fan_all_OK = 0 + f11.write("4") + else: + f11.write("1") + with open("/sys/bus/i2c/devices/1-005e/fan6_fault", "r") as f1: + read_fan_fault = f1.read() + with open("/sys/bus/i2c/devices/9-005f/fan6_led", "w") as f11: + if str(read_fan_fault) == str("1\n"): + is_fan_all_OK = 0 + f11.write("4") + else: + f11.write("1") + + with open("/sys/bus/i2c/devices/1-005e/psu1_power_good", "r") as f1: + read_power_status = f1.read() + with open("/sys/bus/i2c/devices/9-005f/sys_pwr", "w") as f11: + if str(read_power_status) == str("1\n"): + f11.write("1") + else: + f11.write("4") + with open("/sys/bus/i2c/devices/1-005e/psu1_present", "r") as f1: + read_power_status = f1.read() + with open("/sys/bus/i2c/devices/9-005f/sys_pwr", "w") as f11: + if str(read_power_status) == str("1\n"): + is_power_all_OK = is_power_all_OK + 1 + f11.write("1") + else: + f11.write("4") + with open("/sys/bus/i2c/devices/1-005e/psu2_power_good", "r") as f1: + read_power_status = f1.read() + with open("/sys/bus/i2c/devices/9-005f/sys_pwr", "w") as f11: + if str(read_power_status) == str("1\n"): + f11.write("1") + else: + f11.write("4") + with open("/sys/bus/i2c/devices/1-005e/psu2_present", "r") as f1: + read_power_status = f1.read() + with open("/sys/bus/i2c/devices/9-005f/sys_pwr", "w") as f11: + if str(read_power_status) == str("1\n"): + is_power_all_OK = is_power_all_OK + 1 + f11.write("1") + else: + f11.write("4") + + with open("/sys/bus/i2c/devices/9-005f/swi_ctrl", "r") as f5: + is_reset_button_push = f5.read() + if str(is_reset_button_push) == "1\n": + is_reset_button_push = 1 + else: + is_reset_button_push = 0 + + with open("/sys/bus/i2c/devices/4-004d/hwmon/hwmon3/temp1_input", "r") as f3: + is_thermal_high = f3.read() + if int(is_thermal_high) >= 70000: + is_thermal_high = 1 + else: + is_thermal_high = 0 + + with open("/sys/bus/i2c/devices/9-005f/sys_status", "w") as f2: + if is_reset_button_push == 1: + f2.write("3") + elif is_fan_all_OK == 0 or is_power_all_OK == 0 or is_thermal_high == 1: + f2.write("4") + else: + f2.write("1") + + return ########## - - + + class LedControl(LedControlBase): """Platform specific LED control class""" PORT_TABLE_PREFIX = "PORT_TABLE:" @@ -184,17 +184,18 @@ def _port_name_to_qsfp_index(self, port_name): swss = swsssdk.SonicV2Connector() swss.connect(swss.APPL_DB) - lanes = swss.get(swss.APPL_DB, self.PORT_TABLE_PREFIX + port_name, 'lanes') + lanes = swss.get( + swss.APPL_DB, self.PORT_TABLE_PREFIX + port_name, 'lanes') # SONiC port nums are 0-based and increment by 4 # Arista QSFP indices are 1-based and increment by 1 - return (((sonic_port_num/4) + 1), sonic_port_num%4, len(lanes.split(','))) - + return (((sonic_port_num/4) + 1), sonic_port_num % 4, len(lanes.split(','))) # Concrete implementation of port_link_state_change() method + def port_link_state_change_bk(self, port, state): qsfp_index, lane_index, lanes = self._port_name_to_qsfp_index(port) - + # Ignore invalid QSFP indices if qsfp_index <= 0 or lanes <= 0 or lanes > 4: return @@ -203,9 +204,11 @@ def port_link_state_change_bk(self, port, state): # whereas indices 25-32 are not breakout-capable, and only have one if qsfp_index <= self.QSFP_BREAKOUT_END_IDX: # assuming 40G, then we need to control four lanes - led_sysfs_paths = [ self.LED_SYSFS_PATH_BREAKOUT_CAPABLE.format(qsfp_index, i) for i in range(lane_index + 1, lane_index + 1 + lanes) ] + led_sysfs_paths = [self.LED_SYSFS_PATH_BREAKOUT_CAPABLE.format( + qsfp_index, i) for i in range(lane_index + 1, lane_index + 1 + lanes)] else: - led_sysfs_paths = [ self.LED_SYSFS_PATH_NO_BREAKOUT.format(qsfp_index) ] + led_sysfs_paths = [ + self.LED_SYSFS_PATH_NO_BREAKOUT.format(qsfp_index)] for led_sysfs_path in led_sysfs_paths: led_file = open(led_sysfs_path, "w") @@ -240,7 +243,7 @@ def __init__(self): f.write("1") with open("/sys/bus/i2c/devices/9-005f/fan6_led", "w") as f: f.write("1") - sysled_task() + sysled_task() # Initialize: Turn all front panel QSFP LEDs off # # for qsfp_index in range(self.QSFP_BREAKOUT_START_IDX, self.QSFP_BREAKOUT_END_IDX + 1): diff --git a/device/alphanetworks/x86_64-alphanetworks_snh60a0_320fv2-r0/plugins/psuutil.py b/device/alphanetworks/x86_64-alphanetworks_snh60a0_320fv2-r0/plugins/psuutil.py index 7a3b87f24d2d..d189349b5d0e 100644 --- a/device/alphanetworks/x86_64-alphanetworks_snh60a0_320fv2-r0/plugins/psuutil.py +++ b/device/alphanetworks/x86_64-alphanetworks_snh60a0_320fv2-r0/plugins/psuutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Alphanetworks # @@ -13,7 +11,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" diff --git a/device/alphanetworks/x86_64-alphanetworks_snh60a0_320fv2-r0/plugins/sfputil.py b/device/alphanetworks/x86_64-alphanetworks_snh60a0_320fv2-r0/plugins/sfputil.py index 9e502578f153..09679eed8c3b 100644 --- a/device/alphanetworks/x86_64-alphanetworks_snh60a0_320fv2-r0/plugins/sfputil.py +++ b/device/alphanetworks/x86_64-alphanetworks_snh60a0_320fv2-r0/plugins/sfputil.py @@ -1,10 +1,8 @@ -#!/usr/bin/env python - try: import time - from sonic_sfp.sfputilbase import SfpUtilBase -except ImportError, e: - raise ImportError (str(e) + "- required module not found") + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class SfpUtil(SfpUtilBase): @@ -16,17 +14,18 @@ class SfpUtil(SfpUtilBase): port_to_eeprom = {} port_to_i2cbus_mapping = { - 1 : 14, - 2 : 15, - 3 : 16, - 4 : 17, + 1: 14, + 2: 15, + 3: 16, + 4: 17, } eeprom_path = "/sys/bus/i2c/devices/{0}-005f/sfp{1}_eeprom" port_reset_path = "/sys/bus/i2c/devices/{0}-005f/sfp{1}_port_reset" present_path = "/sys/bus/i2c/devices/{0}-005f/sfp{1}_is_present" - _qsfp_ports = range(first_port, port_num + 1) + _qsfp_ports = list(range(first_port, port_num + 1)) + @property def port_start(self): return self.first_port @@ -37,11 +36,11 @@ def port_end(self): @property def qsfp_ports(self): - return range(self.first_port, self.port_num + 1) + return list(range(self.first_port, self.port_num + 1)) - @property + @property def port_to_eeprom_mapping(self): - return self.port_to_eeprom + return self.port_to_eeprom def get_transceiver_change_event(self): """ @@ -68,11 +67,11 @@ def reset(self, port_num): i2c_index = (port_num / 8) + 1 path = self.port_reset_path port_path = path.format(self.port_to_i2cbus_mapping[i2c_index], (index + 1)) - + try: reg_file = open(port_path, 'w') except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False # reset @@ -90,7 +89,7 @@ def set_low_power_mode(self, port_nuM, lpmode): 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.first_port or port_num > self.last_port: @@ -101,11 +100,10 @@ def get_presence(self, port_num): path = self.present_path port_path = path.format(self.port_to_i2cbus_mapping[i2c_index], (index + 1)) - try: reg_file = open(port_path) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = reg_file.readline().rstrip() @@ -113,4 +111,3 @@ def get_presence(self, port_num): return True return False - diff --git a/device/alphanetworks/x86_64-alphanetworks_snh60b0_640f-r0/Alphanetworks-SNH60B0-640F/sai.profile b/device/alphanetworks/x86_64-alphanetworks_snh60b0_640f-r0/Alphanetworks-SNH60B0-640F/sai.profile index 04555733c028..0abb91695d5d 100644 --- a/device/alphanetworks/x86_64-alphanetworks_snh60b0_640f-r0/Alphanetworks-SNH60B0-640F/sai.profile +++ b/device/alphanetworks/x86_64-alphanetworks_snh60b0_640f-r0/Alphanetworks-SNH60B0-640F/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-snh60b0-64x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/alphanetworks/x86_64-alphanetworks_snh60b0_640f-r0/plugins/eeprom.py b/device/alphanetworks/x86_64-alphanetworks_snh60b0_640f-r0/plugins/eeprom.py index c0122e65844a..9e4e9970e9f5 100644 --- a/device/alphanetworks/x86_64-alphanetworks_snh60b0_640f-r0/plugins/eeprom.py +++ b/device/alphanetworks/x86_64-alphanetworks_snh60b0_640f-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -11,14 +8,16 @@ 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") +except ImportError as 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/1-0056/eeprom" - #Two i2c buses might get flipped order, check them both. + # Two i2c buses might get flipped order, check them both. if not os.path.exists(self.eeprom_path): self.eeprom_path = "/sys/bus/i2c/devices/0-0056/eeprom" super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/alphanetworks/x86_64-alphanetworks_snh60b0_640f-r0/plugins/led_control.py b/device/alphanetworks/x86_64-alphanetworks_snh60b0_640f-r0/plugins/led_control.py index 457b1d750b28..53cc43c6cce3 100644 --- a/device/alphanetworks/x86_64-alphanetworks_snh60b0_640f-r0/plugins/led_control.py +++ b/device/alphanetworks/x86_64-alphanetworks_snh60b0_640f-r0/plugins/led_control.py @@ -1,22 +1,21 @@ -#!/usr/bin/env python -# # led_control.py -# +# # Platform-specific LED control functionality for SONiC # # try: # from sonic_led.led_control_base import LedControlBase # import swsssdk -# except ImportError, e: +# except ImportError as e: # raise ImportError (str(e) + " - required module not found") import time + class LedControlBase(object): -# __metaclass__ = abc.ABCMeta + # __metaclass__ = abc.ABCMeta -# @abc.abstractmethod + # @abc.abstractmethod def port_link_state_change(self, port, state): """ Called when port link state changes. Update port link state LED here. @@ -26,6 +25,7 @@ def port_link_state_change(self, port, state): """ return + ### Goreme specified ### read_fan_fault = 0 is_fan_all_OK = 0 @@ -35,91 +35,93 @@ def port_link_state_change(self, port, state): is_reset_button_push = 0 ########################## + def sysled_task(): while True: system_led_check() time.sleep(5) - -########## Goreme System LED checking + +# Goreme System LED checking + + def system_led_check(): - global read_fan_fault, read_power_status, is_fan_all_OK, is_power_all_OK, is_thermal_high, is_reset_button_push - is_fan_all_OK = 1 - is_power_all_OK = 0 - is_thermal_high = 0 - is_reset_button_push = 0 - with open("/sys/bus/i2c/devices/0-005e/fan1_fault", "r") as f1: - read_fan_fault = f1.read() - if str(read_fan_fault) == str("1\n"): - is_fan_all_OK = 0 - with open("/sys/bus/i2c/devices/0-005e/fan2_fault", "r") as f1: - read_fan_fault = f1.read() - if str(read_fan_fault) == str("1\n"): - is_fan_all_OK = 0 - with open("/sys/bus/i2c/devices/0-005e/fan3_fault", "r") as f1: - read_fan_fault = f1.read() - if str(read_fan_fault) == str("1\n"): - is_fan_all_OK = 0 - with open("/sys/bus/i2c/devices/0-005e/fan4_fault", "r") as f1: - read_fan_fault = f1.read() - if str(read_fan_fault) == str("1\n"): - is_fan_all_OK = 0 - - with open("/sys/bus/i2c/devices/8-005f/fan1_led", "w") as f11: - if int(is_fan_all_OK) == 1: - f11.write("1") - else: - f11.write("4") - - - with open("/sys/bus/i2c/devices/0-005e/psu1_power_good", "r") as f1: - read_power_status = f1.read() - if str(read_power_status) != str("1\n"): - is_power_all_OK = -10 - with open("/sys/bus/i2c/devices/0-005e/psu1_present", "r") as f1: - read_power_status = f1.read() - if str(read_power_status) == str("1\n"): - is_power_all_OK = is_power_all_OK + 1 - with open("/sys/bus/i2c/devices/0-005e/psu2_power_good", "r") as f1: - read_power_status = f1.read() - if str(read_power_status) != str("1\n"): - is_power_all_OK = -10 - with open("/sys/bus/i2c/devices/0-005e/psu2_present", "r") as f1: - read_power_status = f1.read() - if str(read_power_status) == str("1\n"): - is_power_all_OK = is_power_all_OK + 1 - - with open("/sys/bus/i2c/devices/8-005f/sys_pwr", "w") as f11: - if int(is_power_all_OK) > 0: - f11.write("1") - else: - f11.write("4") - - - with open("/sys/bus/i2c/devices/8-005f/swi_ctrl", "r") as f5: - is_reset_button_push = f5.read() - if str(is_reset_button_push) == "1\n": - is_reset_button_push = 1 - else: - is_reset_button_push = 0 - - with open("/sys/bus/i2c/devices/3-004d/hwmon/hwmon2/temp1_input", "r") as f3: - is_thermal_high = f3.read() - if int(is_thermal_high) >= 70000: - is_thermal_high = 1 - else: - is_thermal_high = 0 - - with open("/sys/bus/i2c/devices/8-005f/sys_status", "w") as f2: - if is_reset_button_push == 1: - f2.write("3") - elif is_fan_all_OK == 0 or is_power_all_OK == 0 or is_thermal_high == 1: - f2.write("4") - else: - f2.write("1") - - return + global read_fan_fault, read_power_status, is_fan_all_OK, is_power_all_OK, is_thermal_high, is_reset_button_push + is_fan_all_OK = 1 + is_power_all_OK = 0 + is_thermal_high = 0 + is_reset_button_push = 0 + with open("/sys/bus/i2c/devices/0-005e/fan1_fault", "r") as f1: + read_fan_fault = f1.read() + if str(read_fan_fault) == str("1\n"): + is_fan_all_OK = 0 + with open("/sys/bus/i2c/devices/0-005e/fan2_fault", "r") as f1: + read_fan_fault = f1.read() + if str(read_fan_fault) == str("1\n"): + is_fan_all_OK = 0 + with open("/sys/bus/i2c/devices/0-005e/fan3_fault", "r") as f1: + read_fan_fault = f1.read() + if str(read_fan_fault) == str("1\n"): + is_fan_all_OK = 0 + with open("/sys/bus/i2c/devices/0-005e/fan4_fault", "r") as f1: + read_fan_fault = f1.read() + if str(read_fan_fault) == str("1\n"): + is_fan_all_OK = 0 + + with open("/sys/bus/i2c/devices/8-005f/fan1_led", "w") as f11: + if int(is_fan_all_OK) == 1: + f11.write("1") + else: + f11.write("4") + + with open("/sys/bus/i2c/devices/0-005e/psu1_power_good", "r") as f1: + read_power_status = f1.read() + if str(read_power_status) != str("1\n"): + is_power_all_OK = -10 + with open("/sys/bus/i2c/devices/0-005e/psu1_present", "r") as f1: + read_power_status = f1.read() + if str(read_power_status) == str("1\n"): + is_power_all_OK = is_power_all_OK + 1 + with open("/sys/bus/i2c/devices/0-005e/psu2_power_good", "r") as f1: + read_power_status = f1.read() + if str(read_power_status) != str("1\n"): + is_power_all_OK = -10 + with open("/sys/bus/i2c/devices/0-005e/psu2_present", "r") as f1: + read_power_status = f1.read() + if str(read_power_status) == str("1\n"): + is_power_all_OK = is_power_all_OK + 1 + + with open("/sys/bus/i2c/devices/8-005f/sys_pwr", "w") as f11: + if int(is_power_all_OK) > 0: + f11.write("1") + else: + f11.write("4") + + with open("/sys/bus/i2c/devices/8-005f/swi_ctrl", "r") as f5: + is_reset_button_push = f5.read() + if str(is_reset_button_push) == "1\n": + is_reset_button_push = 1 + else: + is_reset_button_push = 0 + + with open("/sys/bus/i2c/devices/3-004d/hwmon/hwmon2/temp1_input", "r") as f3: + is_thermal_high = f3.read() + if int(is_thermal_high) >= 70000: + is_thermal_high = 1 + else: + is_thermal_high = 0 + + with open("/sys/bus/i2c/devices/8-005f/sys_status", "w") as f2: + if is_reset_button_push == 1: + f2.write("3") + elif is_fan_all_OK == 0 or is_power_all_OK == 0 or is_thermal_high == 1: + f2.write("4") + else: + f2.write("1") + + return ########## - + + class LedControl(LedControlBase): """Platform specific LED control class""" PORT_TABLE_PREFIX = "PORT_TABLE:" @@ -149,18 +151,18 @@ def _port_name_to_qsfp_index(self, port_name): swss = swsssdk.SonicV2Connector() swss.connect(swss.APPL_DB) - lanes = swss.get(swss.APPL_DB, self.PORT_TABLE_PREFIX + port_name, 'lanes') + lanes = swss.get( + swss.APPL_DB, self.PORT_TABLE_PREFIX + port_name, 'lanes') # SONiC port nums are 0-based and increment by 4 # Arista QSFP indices are 1-based and increment by 1 - return (((sonic_port_num/4) + 1), sonic_port_num%4, len(lanes.split(','))) - - + return (((sonic_port_num/4) + 1), sonic_port_num % 4, len(lanes.split(','))) # Concrete implementation of port_link_state_change() method + def port_link_state_change_bk(self, port, state): qsfp_index, lane_index, lanes = self._port_name_to_qsfp_index(port) - + # Ignore invalid QSFP indices if qsfp_index <= 0 or lanes <= 0 or lanes > 4: return @@ -169,9 +171,11 @@ def port_link_state_change_bk(self, port, state): # whereas indices 25-32 are not breakout-capable, and only have one if qsfp_index <= self.QSFP_BREAKOUT_END_IDX: # assuming 40G, then we need to control four lanes - led_sysfs_paths = [ self.LED_SYSFS_PATH_BREAKOUT_CAPABLE.format(qsfp_index, i) for i in range(lane_index + 1, lane_index + 1 + lanes) ] + led_sysfs_paths = [self.LED_SYSFS_PATH_BREAKOUT_CAPABLE.format( + qsfp_index, i) for i in range(lane_index + 1, lane_index + 1 + lanes)] else: - led_sysfs_paths = [ self.LED_SYSFS_PATH_NO_BREAKOUT.format(qsfp_index) ] + led_sysfs_paths = [ + self.LED_SYSFS_PATH_NO_BREAKOUT.format(qsfp_index)] for led_sysfs_path in led_sysfs_paths: led_file = open(led_sysfs_path, "w") @@ -202,7 +206,7 @@ def __init__(self): f.write("1") with open("/sys/bus/i2c/devices/8-005f/fan4_led", "w") as f: f.write("1") - sysled_task() + sysled_task() # Initialize: Turn all front panel QSFP LEDs off # # for qsfp_index in range(self.QSFP_BREAKOUT_START_IDX, self.QSFP_BREAKOUT_END_IDX + 1): diff --git a/device/alphanetworks/x86_64-alphanetworks_snh60b0_640f-r0/plugins/psuutil.py b/device/alphanetworks/x86_64-alphanetworks_snh60b0_640f-r0/plugins/psuutil.py index 7a3b87f24d2d..d189349b5d0e 100644 --- a/device/alphanetworks/x86_64-alphanetworks_snh60b0_640f-r0/plugins/psuutil.py +++ b/device/alphanetworks/x86_64-alphanetworks_snh60b0_640f-r0/plugins/psuutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Alphanetworks # @@ -13,7 +11,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" diff --git a/device/alphanetworks/x86_64-alphanetworks_snh60b0_640f-r0/plugins/sfputil.py b/device/alphanetworks/x86_64-alphanetworks_snh60b0_640f-r0/plugins/sfputil.py index cc3cd4e8611d..e2c2aae496cc 100644 --- a/device/alphanetworks/x86_64-alphanetworks_snh60b0_640f-r0/plugins/sfputil.py +++ b/device/alphanetworks/x86_64-alphanetworks_snh60b0_640f-r0/plugins/sfputil.py @@ -1,10 +1,8 @@ -#!/usr/bin/env python - try: import time - from sonic_sfp.sfputilbase import SfpUtilBase -except ImportError, e: - raise ImportError (str(e) + "- required module not found") + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class SfpUtil(SfpUtilBase): @@ -16,11 +14,11 @@ class SfpUtil(SfpUtilBase): port_to_eeprom = {} port_to_i2cbus_mapping = { - 1 : 13, - 2 : 14, - 3 : 15, - 4 : 16, - 5 : 23, + 1: 13, + 2: 14, + 3: 15, + 4: 16, + 5: 23, } eeprom_path_1 = "/sys/bus/i2c/devices/{0}-0020/sfp{1}_eeprom" @@ -30,7 +28,7 @@ class SfpUtil(SfpUtilBase): present_path_1 = "/sys/bus/i2c/devices/{0}-0020/sfp{1}_is_present" present_path = "/sys/bus/i2c/devices/{0}-005f/sfp{1}_is_present" - _qsfp_ports = range(first_port, port_num) + _qsfp_ports = list(range(first_port, port_num)) @property def port_start(self): @@ -42,11 +40,11 @@ def port_end(self): @property def qsfp_ports(self): - return range(self.first_port, self.port_num + 1) + return list(range(self.first_port, self.port_num + 1)) - @property + @property def port_to_eeprom_mapping(self): - return self.port_to_eeprom + return self.port_to_eeprom def get_transceiver_change_event(self): """ @@ -79,12 +77,12 @@ def reset(self, port_num): else: path = self.port_reset_path port_path = path.format(self.port_to_i2cbus_mapping[cpld_index], index) - + try: reg_file = open(port_path, 'w') except IOError as e: if cpld_index < 5: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False # reset @@ -102,7 +100,7 @@ def set_low_power_mode(self, port_nuM, lpmode): 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.first_port or port_num > self.last_port: @@ -116,12 +114,11 @@ def get_presence(self, port_num): path = self.present_path port_path = path.format(self.port_to_i2cbus_mapping[cpld_index], index) - try: reg_file = open(port_path) except IOError as e: if cpld_index < 5: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = reg_file.readline().rstrip() @@ -129,4 +126,3 @@ def get_presence(self, port_num): return True return False - diff --git a/device/arista/x86_64-arista_7050_qx32/Arista-7050-Q16S64/td2-a7050-qx32-16x40G+32x10G+8x40G.config.bcm b/device/arista/x86_64-arista_7050_qx32/Arista-7050-Q16S64/td2-a7050-qx32-16x40G+32x10G+8x40G.config.bcm index 4ce6b2d4a9d6..d3ee2d5e3b0a 100644 --- a/device/arista/x86_64-arista_7050_qx32/Arista-7050-Q16S64/td2-a7050-qx32-16x40G+32x10G+8x40G.config.bcm +++ b/device/arista/x86_64-arista_7050_qx32/Arista-7050-Q16S64/td2-a7050-qx32-16x40G+32x10G+8x40G.config.bcm @@ -37,7 +37,7 @@ stat_if_parity_enable=0 l2xmsg_hostbuf_size=8192 l2xmsg_mode=1 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 lls_num_l2uc=12 max_vp_lags=0 diff --git a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/pg_profile_lookup.ini b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/pg_profile_lookup.ini index 0588079e6840..d8190e4893de 100644 --- a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/pg_profile_lookup.ini +++ b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/pg_profile_lookup.ini @@ -1,11 +1,11 @@ # PG lossless profiles. # speed cable size xon xoff threshold xon_offset - 40000 5m 56368 18432 55120 -3 2496 - 50000 5m 56368 18432 55120 -3 2496 - 100000 5m 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 - 40000 300m 56368 18432 55120 -3 2496 - 50000 300m 56368 18432 55120 -3 2496 - 100000 300m 56368 18432 55120 -3 2496 + 40000 5m 46384 18432 45136 -3 2496 + 50000 5m 46592 18432 45344 -3 2496 + 100000 5m 48464 18432 47216 -3 2496 + 40000 40m 48464 18432 47216 -3 2496 + 50000 40m 49296 18432 48048 -3 2496 + 100000 40m 53872 18432 52624 -3 2496 + 40000 300m 64064 18432 62816 -3 2496 + 50000 300m 68848 18432 67600 -3 2496 + 100000 300m 92976 18432 91728 -3 2496 diff --git a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/td2-a7050-qx32-32x40G.config.bcm b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/td2-a7050-qx32-32x40G.config.bcm index 76b1af3aba16..7537b36411f7 100644 --- a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/td2-a7050-qx32-32x40G.config.bcm +++ b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/td2-a7050-qx32-32x40G.config.bcm @@ -37,7 +37,7 @@ stat_if_parity_enable=0 l2xmsg_hostbuf_size=8192 l2xmsg_mode=1 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 lls_num_l2uc=12 max_vp_lags=0 diff --git a/device/arista/x86_64-arista_7050_qx32/platform.json b/device/arista/x86_64-arista_7050_qx32/platform.json new file mode 100644 index 000000000000..9cf2acddfaf3 --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32/platform.json @@ -0,0 +1,189 @@ +{ + "chassis": { + "name": "DCS-7050QX-32", + "components": [], + "fans": [ + { + "name": "fan1" + }, + { + "name": "fan2" + }, + { + "name": "fan3" + }, + { + "name": "fan4" + } + ], + "fan_drawers": [ + { + "name": "fan1", + "fans": [ + { + "name": "fan1" + } + ] + }, + { + "name": "fan2", + "fans": [ + { + "name": "fan2" + } + ] + }, + { + "name": "fan3", + "fans": [ + { + "name": "fan3" + } + ] + }, + { + "name": "fan4", + "fans": [ + { + "name": "fan4" + } + ] + } + ], + "psus": [ + { + "name": "psu1", + "fans": [] + }, + { + "name": "psu2", + "fans": [] + } + ], + "thermals": [ + { + "name": "Cpu temp sensor" + }, + { + "name": "Board sensor" + }, + { + "name": "Front-panel temp sensor" + }, + { + "name": "Rear temp sensor" + }, + { + "name": "Power supply 1 inlet temp sensor" + }, + { + "name": "Power supply 1 internal sensor" + }, + { + "name": "Power supply 2 inlet temp sensor" + }, + { + "name": "Power supply 2 internal sensor" + } + ], + "sfps": [ + { + "name": "qsfp1" + }, + { + "name": "qsfp2" + }, + { + "name": "qsfp3" + }, + { + "name": "qsfp4" + }, + { + "name": "qsfp5" + }, + { + "name": "qsfp6" + }, + { + "name": "qsfp7" + }, + { + "name": "qsfp8" + }, + { + "name": "qsfp9" + }, + { + "name": "qsfp10" + }, + { + "name": "qsfp11" + }, + { + "name": "qsfp12" + }, + { + "name": "qsfp13" + }, + { + "name": "qsfp14" + }, + { + "name": "qsfp15" + }, + { + "name": "qsfp16" + }, + { + "name": "qsfp17" + }, + { + "name": "qsfp18" + }, + { + "name": "qsfp19" + }, + { + "name": "qsfp20" + }, + { + "name": "qsfp21" + }, + { + "name": "qsfp22" + }, + { + "name": "qsfp23" + }, + { + "name": "qsfp24" + }, + { + "name": "qsfp25" + }, + { + "name": "qsfp26" + }, + { + "name": "qsfp27" + }, + { + "name": "qsfp28" + }, + { + "name": "qsfp29" + }, + { + "name": "qsfp30" + }, + { + "name": "qsfp31" + }, + { + "name": "qsfp32" + } + ] + }, + "interfaces": {} +} \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050_qx32/pmon_daemon_control.json b/device/arista/x86_64-arista_7050_qx32/pmon_daemon_control.json new file mode 120000 index 000000000000..51d5ab7b0059 --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050_qx32/system_health_monitoring_config.json b/device/arista/x86_64-arista_7050_qx32/system_health_monitoring_config.json new file mode 120000 index 000000000000..1185f771fa8e --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-arista_common/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050_qx32/thermal_policy.json b/device/arista/x86_64-arista_7050_qx32/thermal_policy.json new file mode 120000 index 000000000000..0991dc7f3638 --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-arista_common/thermal_policy.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/pg_profile_lookup.ini b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/pg_profile_lookup.ini index 0588079e6840..d8190e4893de 100644 --- a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/pg_profile_lookup.ini +++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/pg_profile_lookup.ini @@ -1,11 +1,11 @@ # PG lossless profiles. # speed cable size xon xoff threshold xon_offset - 40000 5m 56368 18432 55120 -3 2496 - 50000 5m 56368 18432 55120 -3 2496 - 100000 5m 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 - 40000 300m 56368 18432 55120 -3 2496 - 50000 300m 56368 18432 55120 -3 2496 - 100000 300m 56368 18432 55120 -3 2496 + 40000 5m 46384 18432 45136 -3 2496 + 50000 5m 46592 18432 45344 -3 2496 + 100000 5m 48464 18432 47216 -3 2496 + 40000 40m 48464 18432 47216 -3 2496 + 50000 40m 49296 18432 48048 -3 2496 + 100000 40m 53872 18432 52624 -3 2496 + 40000 300m 64064 18432 62816 -3 2496 + 50000 300m 68848 18432 67600 -3 2496 + 100000 300m 92976 18432 91728 -3 2496 diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/sai.profile b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/sai.profile index 6479c4c14d3f..cbaa8cdfd51a 100644 --- a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/sai.profile +++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-a7050-qx32s-32x40G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/td2-a7050-qx32s-32x40G.config.bcm b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/td2-a7050-qx32s-32x40G.config.bcm index 3b1a4514409c..31521e4c43ae 100644 --- a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/td2-a7050-qx32s-32x40G.config.bcm +++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/td2-a7050-qx32s-32x40G.config.bcm @@ -31,7 +31,7 @@ stat_if_parity_enable=0 l2xmsg_hostbuf_size=8192 l2xmsg_mode=1 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 lls_num_l2uc=12 max_vp_lags=0 diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/sai.profile b/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/sai.profile index 9a50433cabdc..0be2fc5e0f45 100644 --- a/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/sai.profile +++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-a7050-q31s4-31x40G-4x10G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7050_qx32s/platform.json b/device/arista/x86_64-arista_7050_qx32s/platform.json new file mode 100644 index 000000000000..7d725b59fe13 --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/platform.json @@ -0,0 +1,197 @@ +{ + "chassis": { + "name": "DCS-7050QX-32S", + "components": [], + "fans": [], + "fan_drawers": [ + { + "name": "slot1", + "fans": [ + { + "name": "fan1" + } + ] + }, + { + "name": "slot2", + "fans": [ + { + "name": "fan2" + } + ] + }, + { + "name": "slot3", + "fans": [ + { + "name": "fan3" + } + ] + }, + { + "name": "slot4", + "fans": [ + { + "name": "fan4" + } + ] + } + ], + "psus": [ + { + "name": "psu1", + "fans": [] + }, + { + "name": "psu2", + "fans": [] + } + ], + "thermals": [ + { + "name": "Cpu temp sensor" + }, + { + "name": "Cpu board temp sensor" + }, + { + "name": "Back-panel temp sensor" + }, + { + "name": "Board Sensor" + }, + { + "name": "Front-panel temp sensor" + }, + { + "name": "Power supply 1 hotspot sensor" + }, + { + "name": "Power supply 1 inlet temp sensor" + }, + { + "name": "Power supply 1 exhaust temp sensor" + }, + { + "name": "Power supply 2 hotspot sensor" + }, + { + "name": "Power supply 2 inlet temp sensor" + }, + { + "name": "Power supply 2 exhaust temp sensor" + } + ], + "sfps": [ + { + "name": "sfp1" + }, + { + "name": "sfp2" + }, + { + "name": "sfp3" + }, + { + "name": "sfp4" + }, + { + "name": "qsfp5" + }, + { + "name": "qsfp6" + }, + { + "name": "qsfp7" + }, + { + "name": "qsfp8" + }, + { + "name": "qsfp9" + }, + { + "name": "qsfp10" + }, + { + "name": "qsfp11" + }, + { + "name": "qsfp12" + }, + { + "name": "qsfp13" + }, + { + "name": "qsfp14" + }, + { + "name": "qsfp15" + }, + { + "name": "qsfp16" + }, + { + "name": "qsfp17" + }, + { + "name": "qsfp18" + }, + { + "name": "qsfp19" + }, + { + "name": "qsfp20" + }, + { + "name": "qsfp21" + }, + { + "name": "qsfp22" + }, + { + "name": "qsfp23" + }, + { + "name": "qsfp24" + }, + { + "name": "qsfp25" + }, + { + "name": "qsfp26" + }, + { + "name": "qsfp27" + }, + { + "name": "qsfp28" + }, + { + "name": "qsfp29" + }, + { + "name": "qsfp30" + }, + { + "name": "qsfp31" + }, + { + "name": "qsfp32" + }, + { + "name": "qsfp33" + }, + { + "name": "qsfp34" + }, + { + "name": "qsfp35" + }, + { + "name": "qsfp36" + } + ] + }, + "interfaces": {} +} \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050_qx32s/plugins/eeprom.py b/device/arista/x86_64-arista_7050_qx32s/plugins/eeprom.py new file mode 120000 index 000000000000..35cfaff3de4e --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/plugins/eeprom.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/eeprom.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050_qx32s/plugins/led_control.py b/device/arista/x86_64-arista_7050_qx32s/plugins/led_control.py new file mode 120000 index 000000000000..8d733780117e --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/plugins/led_control.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/led_control.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050_qx32s/plugins/pcie.yaml b/device/arista/x86_64-arista_7050_qx32s/plugins/pcie.yaml new file mode 100644 index 000000000000..d40522ff4998 --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/plugins/pcie.yaml @@ -0,0 +1,135 @@ +- bus: '00' + dev: '00' + fn: '0' + id: '1536' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Root + Complex' +- bus: '00' + dev: '01' + fn: '0' + id: '9831' + name: 'VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] Kabini + [Radeon HD 8400E]' +- bus: '00' + dev: '02' + fn: '0' + id: '1538' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Function + 0' +- bus: '00' + dev: '02' + fn: '1' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '2' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '3' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '4' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '5' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '11' + fn: '0' + id: '7801' + name: 'SATA controller: Advanced Micro Devices, Inc. [AMD] FCH SATA Controller [AHCI + mode] (rev 40)' +- bus: '00' + dev: '12' + fn: '0' + id: '7807' + name: 'USB controller: Advanced Micro Devices, Inc. [AMD] FCH USB OHCI Controller + (rev 39)' +- bus: '00' + dev: '12' + fn: '2' + id: '7808' + name: 'USB controller: Advanced Micro Devices, Inc. [AMD] FCH USB EHCI Controller + (rev 39)' +- bus: '00' + dev: '14' + fn: '0' + id: 780b + name: 'SMBus: Advanced Micro Devices, Inc. [AMD] FCH SMBus Controller (rev 3a)' +- bus: '00' + dev: '14' + fn: '3' + id: 780e + name: 'ISA bridge: Advanced Micro Devices, Inc. [AMD] FCH LPC Bridge (rev 11)' +- bus: '00' + dev: '14' + fn: '7' + id: '7813' + name: 'SD Host controller: Advanced Micro Devices, Inc. [AMD] FCH SD Flash Controller + (rev 01)' +- bus: '00' + dev: '18' + fn: '0' + id: '1530' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Function + 0' +- bus: '00' + dev: '18' + fn: '1' + id: '1531' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Function + 1' +- bus: '00' + dev: '18' + fn: '2' + id: '1532' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Function + 2' +- bus: '00' + dev: '18' + fn: '3' + id: '1533' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Function + 3' +- bus: '00' + dev: '18' + fn: '4' + id: '1534' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Function + 4' +- bus: '00' + dev: '18' + fn: '5' + id: '1535' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Function + 5' +- bus: '01' + dev: '00' + fn: '0' + id: b850 + name: 'Ethernet controller: Broadcom Limited Broadcom BCM56850 Switch ASIC (rev + 03)' +- bus: '02' + dev: '00' + fn: '0' + id: '0001' + name: 'System peripheral: Arastra Inc. Device 0001 (rev 01)' +- bus: '04' + dev: '00' + fn: '0' + id: '1682' + name: 'Ethernet controller: Broadcom Limited NetXtreme BCM57762 Gigabit Ethernet + PCIe (rev 20)' diff --git a/device/arista/x86_64-arista_7050_qx32s/plugins/psuutil.py b/device/arista/x86_64-arista_7050_qx32s/plugins/psuutil.py new file mode 120000 index 000000000000..2b0024ade969 --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/plugins/psuutil.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/psuutil.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050_qx32s/plugins/sfputil.py b/device/arista/x86_64-arista_7050_qx32s/plugins/sfputil.py new file mode 120000 index 000000000000..c333e23763d7 --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/plugins/sfputil.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/sfputil.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050_qx32s/pmon_daemon_control.json b/device/arista/x86_64-arista_7050_qx32s/pmon_daemon_control.json new file mode 120000 index 000000000000..51d5ab7b0059 --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050_qx32s/system_health_monitoring_config.json b/device/arista/x86_64-arista_7050_qx32s/system_health_monitoring_config.json new file mode 120000 index 000000000000..1185f771fa8e --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-arista_common/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050_qx32s/thermal_policy.json b/device/arista/x86_64-arista_7050_qx32s/thermal_policy.json new file mode 120000 index 000000000000..0991dc7f3638 --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-arista_common/thermal_policy.json \ No newline at end of file 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 index d3d339076a59..4b96b8cf87c9 100644 --- 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 @@ -1,35 +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 +# name lanes alias index speed +Ethernet0 1,2,3,4 Ethernet1/1 1 100000 +Ethernet4 5,6,7,8 Ethernet2/1 2 100000 +Ethernet8 9,10,11,12 Ethernet3/1 3 100000 +Ethernet12 13,14,15,16 Ethernet4/1 4 100000 +Ethernet16 21,22,23,24 Ethernet5/1 5 100000 +Ethernet20 17,18,19,20 Ethernet6/1 6 100000 +Ethernet24 25,26,27,28 Ethernet7/1 7 100000 +Ethernet28 29,30,31,32 Ethernet8/1 8 100000 +Ethernet32 37,38,39,40 Ethernet9/1 9 100000 +Ethernet36 33,34,35,36 Ethernet10/1 10 100000 +Ethernet40 41,42,43,44 Ethernet11/1 11 100000 +Ethernet44 45,46,47,48 Ethernet12/1 12 100000 +Ethernet48 53,54,55,56 Ethernet13/1 13 100000 +Ethernet52 49,50,51,52 Ethernet14/1 14 100000 +Ethernet56 57,58,59,60 Ethernet15/1 15 100000 +Ethernet60 61,62,63,64 Ethernet16/1 16 100000 +Ethernet64 69,70,71,72 Ethernet17/1 17 100000 +Ethernet68 65,66,67,68 Ethernet18/1 18 100000 +Ethernet72 73,74,75,76 Ethernet19/1 19 100000 +Ethernet76 77,78,79,80 Ethernet20/1 20 100000 +Ethernet80 85,86,87,88 Ethernet21/1 21 100000 +Ethernet84 81,82,83,84 Ethernet22/1 22 100000 +Ethernet88 89,90,91,92 Ethernet23/1 23 100000 +Ethernet92 93,94,95,96 Ethernet24/1 24 100000 +Ethernet96 101,102,103,104 Ethernet25/1 25 100000 +Ethernet100 97,98,99,100 Ethernet26/1 26 100000 +Ethernet104 105,106,107,108 Ethernet27/1 27 100000 +Ethernet108 109,110,111,112 Ethernet28/1 28 100000 +Ethernet112 117,118,119,120 Ethernet29/1 29 100000 +Ethernet116 113,114,115,116 Ethernet30/1 30 100000 +Ethernet120 121,122,123,124 Ethernet31/1 31 100000 +Ethernet124 125,126,127,128 Ethernet32/1 32 100000 +Ethernet128 129 Ethernet33 33 10000 +Ethernet132 128 Ethernet34 34 10000 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 index d359ffc15cba..7d96f190de73 100644 --- 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 @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-a7050cx3-32s-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 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 index 217d15b4e579..c3b350204875 100644 --- 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 @@ -1,6 +1,16 @@ +sai_load_hw_config=/etc/bcm/flex/bcm56870_a0_issu/b870.6.4.1/ +host_as_route_disable=1 +use_all_splithorizon_groups=1 +riot_enable=1 +sai_tunnel_support=1 +riot_overlay_l3_intf_mem_size=4096 +riot_overlay_l3_egress_mem_size=32768 +l3_ecmp_levels=3 +riot_overlay_ecmp_resilient_hash_size=16384 +flow_init_mode=1 arl_clean_timeout_usec=15000000 asf_mem_profile=2 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_flags=1 bcm_stat_jumbo=9236 bcm_tunnel_term_compatible_mode=1 @@ -35,7 +45,6 @@ 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 diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/port_config.ini b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/port_config.ini new file mode 100644 index 000000000000..25670f87d9cc --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/port_config.ini @@ -0,0 +1,57 @@ +# name lanes alias index speed +Ethernet0 1,2 Ethernet1/1 1 50000 +Ethernet2 3,4 Ethernet1/3 1 50000 +Ethernet4 5,6 Ethernet2/1 2 50000 +Ethernet6 7,8 Ethernet2/3 2 50000 +Ethernet8 9,10 Ethernet3/1 3 50000 +Ethernet10 11,12 Ethernet3/3 3 50000 +Ethernet12 13,14 Ethernet4/1 4 50000 +Ethernet14 15,16 Ethernet4/3 4 50000 +Ethernet16 21,22 Ethernet5/1 5 50000 +Ethernet18 23,24 Ethernet5/3 5 50000 +Ethernet20 17,18 Ethernet6/1 6 50000 +Ethernet22 19,20 Ethernet6/3 6 50000 +Ethernet24 25,26,27,28 Ethernet7/1 7 100000 +Ethernet28 29,30,31,32 Ethernet8/1 8 100000 +Ethernet32 37,38,39,40 Ethernet9/1 9 100000 +Ethernet36 33,34,35,36 Ethernet10/1 10 100000 +Ethernet40 41,42 Ethernet11/1 11 50000 +Ethernet42 43,44 Ethernet11/3 11 50000 +Ethernet44 45,46 Ethernet12/1 12 50000 +Ethernet46 47,48 Ethernet12/3 12 50000 +Ethernet48 53,54 Ethernet13/1 13 50000 +Ethernet50 55,56 Ethernet13/3 13 50000 +Ethernet52 49,50 Ethernet14/1 14 50000 +Ethernet54 51,52 Ethernet14/3 14 50000 +Ethernet56 57,58 Ethernet15/1 15 50000 +Ethernet58 59,60 Ethernet15/3 15 50000 +Ethernet60 61,62 Ethernet16/1 16 50000 +Ethernet62 63,64 Ethernet16/3 16 50000 +Ethernet64 69,70 Ethernet17/1 17 50000 +Ethernet66 71,72 Ethernet17/3 17 50000 +Ethernet68 65,66 Ethernet18/1 18 50000 +Ethernet70 67,68 Ethernet18/3 18 50000 +Ethernet72 73,74 Ethernet19/1 19 50000 +Ethernet74 75,76 Ethernet19/3 19 50000 +Ethernet76 77,78 Ethernet20/1 20 50000 +Ethernet78 79,80 Ethernet20/3 20 50000 +Ethernet80 85,86 Ethernet21/1 21 50000 +Ethernet82 87,88 Ethernet21/3 21 50000 +Ethernet84 81,82 Ethernet22/1 22 50000 +Ethernet86 83,84 Ethernet22/3 22 50000 +Ethernet88 89,90,91,92 Ethernet23/1 23 100000 +Ethernet92 93,94,95,96 Ethernet24/1 24 100000 +Ethernet96 101,102,103,104 Ethernet25/1 25 100000 +Ethernet100 97,98,99,100 Ethernet26/1 26 100000 +Ethernet104 105,106 Ethernet27/1 27 50000 +Ethernet106 107,108 Ethernet27/3 27 50000 +Ethernet108 109,110 Ethernet28/1 28 50000 +Ethernet110 111,112 Ethernet28/3 28 50000 +Ethernet112 117,118 Ethernet29/1 29 50000 +Ethernet114 119,120 Ethernet29/3 29 50000 +Ethernet116 113,114 Ethernet30/1 30 50000 +Ethernet118 115,116 Ethernet30/3 30 50000 +Ethernet120 121,122 Ethernet31/1 31 50000 +Ethernet122 123,124 Ethernet31/3 31 50000 +Ethernet124 125,126 Ethernet32/1 32 50000 +Ethernet126 127,128 Ethernet32/3 32 50000 diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/sai.profile b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/sai.profile new file mode 100644 index 000000000000..1865041f8d9f --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-a7050cx3-32s-48x50G+8x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/td3-a7050cx3-32s-48x50G+8x100G.config.bcm b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/td3-a7050cx3-32s-48x50G+8x100G.config.bcm new file mode 100644 index 000000000000..1b5b7e338708 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/td3-a7050cx3-32s-48x50G+8x100G.config.bcm @@ -0,0 +1,555 @@ +sai_load_hw_config=/etc/bcm/flex/bcm56870_a0_issu/b870.6.4.1/ +host_as_route_disable=1 +use_all_splithorizon_groups=1 +riot_enable=1 +sai_tunnel_support=1 +riot_overlay_l3_intf_mem_size=4096 +riot_overlay_l3_egress_mem_size=32768 +l3_ecmp_levels=3 +riot_overlay_ecmp_resilient_hash_size=16384 +flow_init_mode=1 +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=0x7ffffffffffffffffffffffffffffffffe +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 +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{5.0}=0x3120 +phy_chain_rx_lane_map_physical{9.0}=0x3120 +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{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{93.0}=0x0213 +phy_chain_rx_lane_map_physical{97.0}=0x2130 +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_polarity_flip_physical{1.0}=0x0 +phy_chain_rx_polarity_flip_physical{2.0}=0x0 +phy_chain_rx_polarity_flip_physical{3.0}=0x0 +phy_chain_rx_polarity_flip_physical{4.0}=0x1 +phy_chain_rx_polarity_flip_physical{5.0}=0x0 +phy_chain_rx_polarity_flip_physical{6.0}=0x1 +phy_chain_rx_polarity_flip_physical{7.0}=0x0 +phy_chain_rx_polarity_flip_physical{8.0}=0x0 +phy_chain_rx_polarity_flip_physical{9.0}=0x0 +phy_chain_rx_polarity_flip_physical{10.0}=0x0 +phy_chain_rx_polarity_flip_physical{11.0}=0x1 +phy_chain_rx_polarity_flip_physical{12.0}=0x1 +phy_chain_rx_polarity_flip_physical{13.0}=0x1 +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{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{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{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{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{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{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{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{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_rx_polarity_flip_physical{100.0}=0x1 +phy_chain_rx_polarity_flip_physical{101.0}=0x1 +phy_chain_rx_polarity_flip_physical{102.0}=0x0 +phy_chain_rx_polarity_flip_physical{103.0}=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{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{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{131.0}=0x0 +phy_chain_tx_lane_map_physical{1.0}=0x3021 +phy_chain_tx_lane_map_physical{5.0}=0x1203 +phy_chain_tx_lane_map_physical{9.0}=0x0213 +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{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{93.0}=0x2130 +phy_chain_tx_lane_map_physical{97.0}=0x1302 +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_polarity_flip_physical{1.0}=0x1 +phy_chain_tx_polarity_flip_physical{2.0}=0x1 +phy_chain_tx_polarity_flip_physical{3.0}=0x0 +phy_chain_tx_polarity_flip_physical{4.0}=0x0 +phy_chain_tx_polarity_flip_physical{5.0}=0x1 +phy_chain_tx_polarity_flip_physical{6.0}=0x1 +phy_chain_tx_polarity_flip_physical{7.0}=0x0 +phy_chain_tx_polarity_flip_physical{8.0}=0x1 +phy_chain_tx_polarity_flip_physical{9.0}=0x1 +phy_chain_tx_polarity_flip_physical{10.0}=0x1 +phy_chain_tx_polarity_flip_physical{11.0}=0x0 +phy_chain_tx_polarity_flip_physical{12.0}=0x0 +phy_chain_tx_polarity_flip_physical{13.0}=0x1 +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{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{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{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{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{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{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{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{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 +phy_chain_tx_polarity_flip_physical{100.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{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{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{131.0}=0x0 +portmap_1=1:50:2 +portmap_3=3:50:2 +portmap_5=5:50:2 +portmap_7=7:50:2 +portmap_9=9:50:2 +portmap_11=11:50:2 +portmap_13=13:50:2 +portmap_15=15:50:2 +portmap_17=17:50:2 +portmap_19=19:50:2 +portmap_21=21:50:2 +portmap_23=23:50:2 +portmap_25=25:100 +portmap_29=29:100 +portmap_33=33:100 +portmap_37=37:100 +portmap_41=41:50:2 +portmap_43=43:50:2 +portmap_45=45:50:2 +portmap_47=47:50:2 +portmap_49=49:50:2 +portmap_51=51:50:2 +portmap_53=53:50:2 +portmap_55=55:50:2 +portmap_57=57:50:2 +portmap_59=59:50:2 +portmap_61=61:50:2 +portmap_63=63:50:2 +# skip 2 +portmap_67=65:50:2 +portmap_69=67:50:2 +portmap_71=69:50:2 +portmap_73=71:50:2 +portmap_75=73:50:2 +portmap_77=75:50:2 +portmap_79=77:50:2 +portmap_81=79:50:2 +portmap_83=81:50:2 +portmap_85=83:50:2 +portmap_87=85:50:2 +portmap_89=87:50:2 +portmap_91=89:100 +portmap_95=93:100 +portmap_99=97:100 +portmap_103=101:100 +portmap_107=105:50:2 +portmap_109=107:50:2 +portmap_111=109:50:2 +portmap_113=111:50:2 +portmap_115=113:50:2 +portmap_117=115:50:2 +portmap_119=117:50:2 +portmap_121=119:50:2 +portmap_123=121:50:2 +portmap_125=123:50:2 +portmap_127=125:50:2 +portmap_129=127:50:2 +serdes_core_rx_polarity_flip_physical{1}=0x8 +serdes_core_rx_polarity_flip_physical{5}=0x2 +serdes_core_rx_polarity_flip_physical{9}=0xc +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{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{93}=0xc +serdes_core_rx_polarity_flip_physical{97}=0xb +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{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_tx_polarity_flip_physical{1}=0x3 +serdes_core_tx_polarity_flip_physical{5}=0xb +serdes_core_tx_polarity_flip_physical{9}=0x3 +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{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{93}=0xc +serdes_core_tx_polarity_flip_physical{97}=0xf +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{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_preemphasis_1=0x45808 +serdes_preemphasis_3=0x45808 +serdes_preemphasis_5=0x45808 +serdes_preemphasis_7=0x45808 +serdes_preemphasis_9=0x45808 +serdes_preemphasis_11=0x45808 +serdes_preemphasis_13=0x45808 +serdes_preemphasis_15=0x45808 +serdes_preemphasis_17=0x45808 +serdes_preemphasis_19=0x45808 +serdes_preemphasis_21=0x45808 +serdes_preemphasis_23=0x45808 +serdes_preemphasis_25=0xd3e05 +serdes_preemphasis_29=0xd3e05 +serdes_preemphasis_33=0xb3403 +serdes_preemphasis_37=0x93603 +serdes_preemphasis_41=0x580c +serdes_preemphasis_43=0x580c +serdes_preemphasis_45=0x580c +serdes_preemphasis_47=0x580c +serdes_preemphasis_49=0x580c +serdes_preemphasis_51=0x580c +serdes_preemphasis_53=0x580c +serdes_preemphasis_55=0x580c +serdes_preemphasis_57=0x580c +serdes_preemphasis_59=0x580c +serdes_preemphasis_61=0x580c +serdes_preemphasis_63=0x580c +serdes_preemphasis_67=0x580c +serdes_preemphasis_69=0x580c +serdes_preemphasis_71=0x580c +serdes_preemphasis_73=0x580c +serdes_preemphasis_75=0x580c +serdes_preemphasis_77=0x580c +serdes_preemphasis_79=0x580c +serdes_preemphasis_81=0x580c +serdes_preemphasis_83=0x580c +serdes_preemphasis_85=0x580c +serdes_preemphasis_87=0x580c +serdes_preemphasis_89=0x580c +serdes_preemphasis_91=0x93603 +serdes_preemphasis_95=0xd3e05 +serdes_preemphasis_99=0xb3403 +serdes_preemphasis_103=0xd3e05 +serdes_preemphasis_107=0x85804 +serdes_preemphasis_109=0x85804 +serdes_preemphasis_111=0x85804 +serdes_preemphasis_113=0x85804 +serdes_preemphasis_115=0x85804 +serdes_preemphasis_117=0x85804 +serdes_preemphasis_119=0x85804 +serdes_preemphasis_121=0x85804 +serdes_preemphasis_123=0x85804 +serdes_preemphasis_125=0x85804 +serdes_preemphasis_127=0x85804 +serdes_preemphasis_129=0x85804 diff --git a/device/arista/x86_64-arista_7050cx3_32s/platform.json b/device/arista/x86_64-arista_7050cx3_32s/platform.json new file mode 100644 index 000000000000..632747ad2333 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/platform.json @@ -0,0 +1,191 @@ +{ + "chassis": { + "name": "DCS-7050CX3-32S", + "components": [], + "fans": [], + "fan_drawers": [ + { + "name": "slot1", + "fans": [ + { + "name": "fan1" + } + ] + }, + { + "name": "slot2", + "fans": [ + { + "name": "fan2" + } + ] + }, + { + "name": "slot3", + "fans": [ + { + "name": "fan3" + } + ] + }, + { + "name": "slot4", + "fans": [ + { + "name": "fan4" + } + ] + } + ], + "psus": [ + { + "name": "psu1", + "fans": [] + }, + { + "name": "psu2", + "fans": [] + } + ], + "thermals": [ + { + "name": "Cpu temp sensor" + }, + { + "name": "Cpu board temp sensor" + }, + { + "name": "Back-panel temp sensor" + }, + { + "name": "Board temp sensor" + }, + { + "name": "Front-panel temp sensor" + }, + { + "name": "Power supply 1 hotspot sensor" + }, + { + "name": "Power supply 1 inlet temp sensor" + }, + { + "name": "Power supply 1 exhaust temp sensor" + }, + { + "name": "Power supply 2 hotspot sensor" + }, + { + "name": "Power supply 2 inlet temp sensor" + }, + { + "name": "Power supply 2 exhaust temp sensor" + } + ], + "sfps": [ + { + "name": "qsfp1" + }, + { + "name": "qsfp2" + }, + { + "name": "qsfp3" + }, + { + "name": "qsfp4" + }, + { + "name": "qsfp5" + }, + { + "name": "qsfp6" + }, + { + "name": "qsfp7" + }, + { + "name": "qsfp8" + }, + { + "name": "qsfp9" + }, + { + "name": "qsfp10" + }, + { + "name": "qsfp11" + }, + { + "name": "qsfp12" + }, + { + "name": "qsfp13" + }, + { + "name": "qsfp14" + }, + { + "name": "qsfp15" + }, + { + "name": "qsfp16" + }, + { + "name": "qsfp17" + }, + { + "name": "qsfp18" + }, + { + "name": "qsfp19" + }, + { + "name": "qsfp20" + }, + { + "name": "qsfp21" + }, + { + "name": "qsfp22" + }, + { + "name": "qsfp23" + }, + { + "name": "qsfp24" + }, + { + "name": "qsfp25" + }, + { + "name": "qsfp26" + }, + { + "name": "qsfp27" + }, + { + "name": "qsfp28" + }, + { + "name": "qsfp29" + }, + { + "name": "qsfp30" + }, + { + "name": "qsfp31" + }, + { + "name": "qsfp32" + }, + { + "name": "sfp33" + }, + { + "name": "sfp34" + } + ] + }, + "interfaces": {} +} \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050cx3_32s/plugins/eeprom.py b/device/arista/x86_64-arista_7050cx3_32s/plugins/eeprom.py new file mode 120000 index 000000000000..35cfaff3de4e --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/plugins/eeprom.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/eeprom.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050cx3_32s/plugins/led_control.py b/device/arista/x86_64-arista_7050cx3_32s/plugins/led_control.py new file mode 120000 index 000000000000..8d733780117e --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/plugins/led_control.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/led_control.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050cx3_32s/plugins/pcie.yaml b/device/arista/x86_64-arista_7050cx3_32s/plugins/pcie.yaml new file mode 100644 index 000000000000..f56c87185f3c --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/plugins/pcie.yaml @@ -0,0 +1,133 @@ +- bus: '00' + dev: '00' + fn: '0' + id: '1566' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Root Complex' +- bus: '00' + dev: '00' + fn: '2' + id: '1567' + name: 'IOMMU: Advanced Micro Devices, Inc. [AMD] Mullins IOMMU' +- bus: '00' + dev: '02' + fn: '0' + id: 156b + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Host Bridge' +- bus: '00' + dev: '02' + fn: '1' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '2' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '3' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '4' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '5' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: 08 + fn: '0' + id: '1537' + name: 'Encryption controller: Advanced Micro Devices, Inc. [AMD] Kabini/Mullins + PSP-Platform Security Processor' +- bus: '00' + dev: '11' + fn: '0' + id: '7801' + name: 'SATA controller: Advanced Micro Devices, Inc. [AMD] FCH SATA Controller [AHCI + mode] (rev 40)' +- bus: '00' + dev: '12' + fn: '0' + id: '7808' + name: 'USB controller: Advanced Micro Devices, Inc. [AMD] FCH USB EHCI Controller + (rev 39)' +- bus: '00' + dev: '14' + fn: '0' + id: 780b + name: 'SMBus: Advanced Micro Devices, Inc. [AMD] FCH SMBus Controller (rev 42)' +- bus: '00' + dev: '14' + fn: '3' + id: 780e + name: 'ISA bridge: Advanced Micro Devices, Inc. [AMD] FCH LPC Bridge (rev 11)' +- bus: '00' + dev: '14' + fn: '7' + id: '7813' + name: 'SD Host controller: Advanced Micro Devices, Inc. [AMD] FCH SD Flash Controller + (rev 01)' +- bus: '00' + dev: '18' + fn: '0' + id: '1580' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 0' +- bus: '00' + dev: '18' + fn: '1' + id: '1581' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 1' +- bus: '00' + dev: '18' + fn: '2' + id: '1582' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 2' +- bus: '00' + dev: '18' + fn: '3' + id: '1583' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 3' +- bus: '00' + dev: '18' + fn: '4' + id: '1584' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 4' +- bus: '00' + dev: '18' + fn: '5' + id: '1585' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 5' +- bus: '01' + dev: '00' + fn: '0' + id: b870 + name: 'Ethernet controller: Broadcom Limited Device b870 (rev 01)' +- bus: '02' + dev: '00' + fn: '0' + id: '0001' + name: 'System peripheral: Arastra Inc. Device 0001 (rev 01)' +- bus: '04' + dev: '00' + fn: '0' + id: '1682' + name: 'Ethernet controller: Broadcom Limited NetXtreme BCM57762 Gigabit Ethernet + PCIe (rev 20)' diff --git a/device/arista/x86_64-arista_7050cx3_32s/plugins/psuutil.py b/device/arista/x86_64-arista_7050cx3_32s/plugins/psuutil.py new file mode 120000 index 000000000000..2b0024ade969 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/plugins/psuutil.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/psuutil.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050cx3_32s/plugins/sfputil.py b/device/arista/x86_64-arista_7050cx3_32s/plugins/sfputil.py new file mode 120000 index 000000000000..c333e23763d7 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/plugins/sfputil.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/sfputil.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050cx3_32s/pmon_daemon_control.json b/device/arista/x86_64-arista_7050cx3_32s/pmon_daemon_control.json new file mode 120000 index 000000000000..51d5ab7b0059 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050cx3_32s/system_health_monitoring_config.json b/device/arista/x86_64-arista_7050cx3_32s/system_health_monitoring_config.json new file mode 120000 index 000000000000..1185f771fa8e --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-arista_common/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050cx3_32s/thermal_policy.json b/device/arista/x86_64-arista_7050cx3_32s/thermal_policy.json new file mode 120000 index 000000000000..0991dc7f3638 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-arista_common/thermal_policy.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/pg_profile_lookup.ini b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/pg_profile_lookup.ini index aedda37a8878..673df369a9bb 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/pg_profile_lookup.ini +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/pg_profile_lookup.ini @@ -1,17 +1,17 @@ # PG lossless profiles. # speed cable size xon xoff threshold xon_offset - 10000 5m 1248 2288 35776 -3 2288 - 25000 5m 1248 2288 53248 -3 2288 - 40000 5m 1248 2288 66560 -3 2288 - 50000 5m 1248 2288 90272 -3 2288 - 100000 5m 1248 2288 165568 -3 2288 - 10000 40m 1248 2288 37024 -3 2288 - 25000 40m 1248 2288 53248 -3 2288 - 40000 40m 1248 2288 71552 -3 2288 - 50000 40m 1248 2288 96096 -3 2288 - 100000 40m 1248 2288 177632 -3 2288 - 10000 300m 1248 2288 46176 -3 2288 - 25000 300m 1248 2288 79040 -3 2288 - 40000 300m 1248 2288 108160 -3 2288 - 50000 300m 1248 2288 141856 -3 2288 - 100000 300m 1248 2288 268736 -3 2288 + 10000 5m 1248 2288 35776 0 2288 + 25000 5m 1248 2288 53248 0 2288 + 40000 5m 1248 2288 66560 0 2288 + 50000 5m 1248 2288 90272 0 2288 + 100000 5m 1248 2288 165568 0 2288 + 10000 40m 1248 2288 37024 0 2288 + 25000 40m 1248 2288 53248 0 2288 + 40000 40m 1248 2288 71552 0 2288 + 50000 40m 1248 2288 96096 0 2288 + 100000 40m 1248 2288 177632 0 2288 + 10000 300m 1248 2288 46176 0 2288 + 25000 300m 1248 2288 79040 0 2288 + 40000 300m 1248 2288 108160 0 2288 + 50000 300m 1248 2288 141856 0 2288 + 100000 300m 1248 2288 268736 0 2288 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/qos.json.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/qos.json.j2 index 3e548325ea30..34002048afdb 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/qos.json.j2 +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/qos.json.j2 @@ -1 +1,21 @@ +{%- macro generate_wred_profiles() %} + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "wred_green_enable" : "true", + "wred_yellow_enable" : "true", + "wred_red_enable" : "true", + "ecn" : "ecn_all", + "green_max_threshold" : "2097152", + "green_min_threshold" : "250000", + "yellow_max_threshold" : "2097152", + "yellow_min_threshold" : "1048576", + "red_max_threshold" : "2097152", + "red_min_threshold" : "1048576", + "green_drop_probability" : "5", + "yellow_drop_probability": "5", + "red_drop_probability" : "5" + } + }, +{%- endmacro %} + {%- include 'qos_config.j2' %} diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/sai.profile b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/sai.profile index 4f8c558b0885..66f88f894c30 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/sai.profile +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-a7060-cx32s-32x100G-t1.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/th-a7060-cx32s-32x100G-t1.config.bcm b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/th-a7060-cx32s-32x100G-t1.config.bcm index 039fd955836c..95a947003fbc 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/th-a7060-cx32s-32x100G-t1.config.bcm +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/th-a7060-cx32s-32x100G-t1.config.bcm @@ -3,7 +3,7 @@ phy_an_allow_pll_change=1 arl_clean_timeout_usec=15000000 asf_mem_profile=2 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_flags=1 bcm_stat_jumbo=9236 cdma_timeout_usec=15000000 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/buffers_defaults_t0.j2 index 5add8968e621..1430479d08e0 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/buffers_defaults_t0.j2 +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/buffers_defaults_t0.j2 @@ -10,14 +10,14 @@ {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{%- endif %} {%- endfor %} - {%- for port_idx in range(24,32) %} + {%- for port_idx in range(26,32) %} {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{%- endif %} {%- endfor %} {%- for port_idx in range(6,10) %} {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} {%- endfor %} - {%- for port_idx in range(22,24) %} + {%- for port_idx in range(22,26) %} {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} {%- endfor %} {%- endmacro %} diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/pg_profile_lookup.ini b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/pg_profile_lookup.ini index dc05d0a100a3..0b5d680edda7 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/pg_profile_lookup.ini +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/pg_profile_lookup.ini @@ -1,17 +1,17 @@ # PG lossless profiles. # speed cable size xon xoff threshold xon_offset - 10000 5m 1248 2288 35776 -3 2288 - 25000 5m 1248 2288 53248 -3 2288 - 40000 5m 1248 2288 66560 -3 2288 - 50000 5m 1248 2288 79872 -3 2288 - 100000 5m 1248 2288 165568 -3 2288 - 10000 40m 1248 2288 37024 -3 2288 - 25000 40m 1248 2288 56160 -3 2288 - 40000 40m 1248 2288 71552 -3 2288 - 50000 40m 1248 2288 85696 -3 2288 - 100000 40m 1248 2288 177632 -3 2288 - 10000 300m 1248 2288 46176 -3 2288 - 25000 300m 1248 2288 79040 -3 2288 - 40000 300m 1248 2288 108160 -3 2288 - 50000 300m 1248 2288 141856 -3 2288 - 100000 300m 1248 2288 268736 -3 2288 + 10000 5m 1248 2288 35776 0 2288 + 25000 5m 1248 2288 53248 0 2288 + 40000 5m 1248 2288 66560 0 2288 + 50000 5m 1248 2288 79872 0 2288 + 100000 5m 1248 2288 165568 0 2288 + 10000 40m 1248 2288 37024 0 2288 + 25000 40m 1248 2288 56160 0 2288 + 40000 40m 1248 2288 71552 0 2288 + 50000 40m 1248 2288 85696 0 2288 + 100000 40m 1248 2288 177632 0 2288 + 10000 300m 1248 2288 46176 0 2288 + 25000 300m 1248 2288 79040 0 2288 + 40000 300m 1248 2288 108160 0 2288 + 50000 300m 1248 2288 141856 0 2288 + 100000 300m 1248 2288 268736 0 2288 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/qos.json.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/qos.json.j2 index 3e548325ea30..34002048afdb 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/qos.json.j2 +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/qos.json.j2 @@ -1 +1,21 @@ +{%- macro generate_wred_profiles() %} + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "wred_green_enable" : "true", + "wred_yellow_enable" : "true", + "wred_red_enable" : "true", + "ecn" : "ecn_all", + "green_max_threshold" : "2097152", + "green_min_threshold" : "250000", + "yellow_max_threshold" : "2097152", + "yellow_min_threshold" : "1048576", + "red_max_threshold" : "2097152", + "red_min_threshold" : "1048576", + "green_drop_probability" : "5", + "yellow_drop_probability": "5", + "red_drop_probability" : "5" + } + }, +{%- endmacro %} + {%- include 'qos_config.j2' %} diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/sai.profile b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/sai.profile index 87b4ffdadd6d..692f79decc1f 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/sai.profile +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-a7060-cx32s-8x100G+48x50G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/th-a7060-cx32s-8x100G+48x50G.config.bcm b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/th-a7060-cx32s-8x100G+48x50G.config.bcm index 326a51ada84f..5c70d324dbb3 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/th-a7060-cx32s-8x100G+48x50G.config.bcm +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/th-a7060-cx32s-8x100G+48x50G.config.bcm @@ -3,7 +3,7 @@ phy_an_allow_pll_change=1 arl_clean_timeout_usec=15000000 asf_mem_profile=2 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_flags=1 bcm_stat_jumbo=9236 cdma_timeout_usec=15000000 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/buffers_defaults_t0.j2 index c0fa1ff0864e..4858c7a67e65 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/buffers_defaults_t0.j2 +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/buffers_defaults_t0.j2 @@ -2,22 +2,7 @@ {%- macro generate_port_lists(PORT_ALL) %} {# Generate list of ports #} - {%- for port_idx in range(0,6) %} - {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} - {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{%- endif %} - {%- endfor %} - {%- for port_idx in range(10,22) %} - {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} - {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{%- endif %} - {%- endfor %} - {%- for port_idx in range(24,32) %} - {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} - {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{%- endif %} - {%- endfor %} - {%- for port_idx in range(6,10) %} - {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} - {%- endfor %} - {%- for port_idx in range(22,24) %} + {%- for port_idx in range(0,32) %} {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} {%- endfor %} {%- endmacro %} diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/sai.profile b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/sai.profile index 42e0c57347a2..08abf1198948 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/sai.profile +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-a7060-cx32s-8x100G+24x40G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/th-a7060-cx32s-8x100G+24x40G.config.bcm b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/th-a7060-cx32s-8x100G+24x40G.config.bcm index 7149b5e7ef54..05908a259c48 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/th-a7060-cx32s-8x100G+24x40G.config.bcm +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/th-a7060-cx32s-8x100G+24x40G.config.bcm @@ -3,7 +3,7 @@ phy_an_allow_pll_change=1 arl_clean_timeout_usec=15000000 asf_mem_profile=2 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_flags=1 bcm_stat_jumbo=9236 cdma_timeout_usec=15000000 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/pg_profile_lookup.ini b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/pg_profile_lookup.ini index aedda37a8878..673df369a9bb 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/pg_profile_lookup.ini +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/pg_profile_lookup.ini @@ -1,17 +1,17 @@ # PG lossless profiles. # speed cable size xon xoff threshold xon_offset - 10000 5m 1248 2288 35776 -3 2288 - 25000 5m 1248 2288 53248 -3 2288 - 40000 5m 1248 2288 66560 -3 2288 - 50000 5m 1248 2288 90272 -3 2288 - 100000 5m 1248 2288 165568 -3 2288 - 10000 40m 1248 2288 37024 -3 2288 - 25000 40m 1248 2288 53248 -3 2288 - 40000 40m 1248 2288 71552 -3 2288 - 50000 40m 1248 2288 96096 -3 2288 - 100000 40m 1248 2288 177632 -3 2288 - 10000 300m 1248 2288 46176 -3 2288 - 25000 300m 1248 2288 79040 -3 2288 - 40000 300m 1248 2288 108160 -3 2288 - 50000 300m 1248 2288 141856 -3 2288 - 100000 300m 1248 2288 268736 -3 2288 + 10000 5m 1248 2288 35776 0 2288 + 25000 5m 1248 2288 53248 0 2288 + 40000 5m 1248 2288 66560 0 2288 + 50000 5m 1248 2288 90272 0 2288 + 100000 5m 1248 2288 165568 0 2288 + 10000 40m 1248 2288 37024 0 2288 + 25000 40m 1248 2288 53248 0 2288 + 40000 40m 1248 2288 71552 0 2288 + 50000 40m 1248 2288 96096 0 2288 + 100000 40m 1248 2288 177632 0 2288 + 10000 300m 1248 2288 46176 0 2288 + 25000 300m 1248 2288 79040 0 2288 + 40000 300m 1248 2288 108160 0 2288 + 50000 300m 1248 2288 141856 0 2288 + 100000 300m 1248 2288 268736 0 2288 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/qos.json.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/qos.json.j2 index 3e548325ea30..34002048afdb 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/qos.json.j2 +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/qos.json.j2 @@ -1 +1,21 @@ +{%- macro generate_wred_profiles() %} + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "wred_green_enable" : "true", + "wred_yellow_enable" : "true", + "wred_red_enable" : "true", + "ecn" : "ecn_all", + "green_max_threshold" : "2097152", + "green_min_threshold" : "250000", + "yellow_max_threshold" : "2097152", + "yellow_min_threshold" : "1048576", + "red_max_threshold" : "2097152", + "red_min_threshold" : "1048576", + "green_drop_probability" : "5", + "yellow_drop_probability": "5", + "red_drop_probability" : "5" + } + }, +{%- endmacro %} + {%- include 'qos_config.j2' %} diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/sai.profile.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/sai.profile.j2 index 638fd28b0765..5a50185247a0 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/sai.profile.j2 +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/sai.profile.j2 @@ -1,7 +1,7 @@ {# Get sai.profile based on switch_role #} {%- if DEVICE_METADATA is defined -%} {%- set switch_role = DEVICE_METADATA['localhost']['type'] -%} -{%- if switch_role.lower() == 'torrouter' %} +{%- if 'torrouter' in switch_role.lower() %} {% set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-a7060-cx32s-32x40G-t0.config.bcm' -%} {%- else %} {%- set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-a7060-cx32s-32x40G-t1.config.bcm' -%} @@ -11,3 +11,4 @@ {%- endif %} {# Write the contents of sai_ profile_filename to sai.profile file #} {{ sai_profile_contents }} +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/th-a7060-cx32s-32x40G-t0.config.bcm b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/th-a7060-cx32s-32x40G-t0.config.bcm index 0cb4ae4a474a..c011ad93f4d7 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/th-a7060-cx32s-32x40G-t0.config.bcm +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/th-a7060-cx32s-32x40G-t0.config.bcm @@ -3,7 +3,7 @@ phy_an_allow_pll_change=1 arl_clean_timeout_usec=15000000 asf_mem_profile=2 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_flags=1 bcm_stat_jumbo=9236 cdma_timeout_usec=15000000 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/th-a7060-cx32s-32x40G-t1.config.bcm b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/th-a7060-cx32s-32x40G-t1.config.bcm index c3218645ac2d..65a7d57b5513 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/th-a7060-cx32s-32x40G-t1.config.bcm +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/th-a7060-cx32s-32x40G-t1.config.bcm @@ -3,7 +3,7 @@ phy_an_allow_pll_change=1 arl_clean_timeout_usec=15000000 asf_mem_profile=2 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_flags=1 bcm_stat_jumbo=9236 cdma_timeout_usec=15000000 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-T96C8/sai.profile b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-T96C8/sai.profile index d54a263e72b6..f9a1e2bdc4d6 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-T96C8/sai.profile +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-T96C8/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-a7060-cx32s-8x100G+96x25G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-T96C8/th-a7060-cx32s-8x100G+96x25G.config.bcm b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-T96C8/th-a7060-cx32s-8x100G+96x25G.config.bcm index d3b9a758ba1f..467d428830c9 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-T96C8/th-a7060-cx32s-8x100G+96x25G.config.bcm +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-T96C8/th-a7060-cx32s-8x100G+96x25G.config.bcm @@ -3,7 +3,7 @@ phy_an_allow_pll_change=1 arl_clean_timeout_usec=15000000 asf_mem_profile=2 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_flags=1 bcm_stat_jumbo=9236 cdma_timeout_usec=15000000 diff --git a/device/arista/x86_64-arista_7060_cx32s/platform.json b/device/arista/x86_64-arista_7060_cx32s/platform.json new file mode 100644 index 000000000000..fe62f3db0c53 --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/platform.json @@ -0,0 +1,197 @@ +{ + "chassis": { + "name": "DCS-7060CX-32S", + "components": [], + "fans": [], + "fan_drawers": [ + { + "name": "slot1", + "fans": [ + { + "name": "fan1" + } + ] + }, + { + "name": "slot2", + "fans": [ + { + "name": "fan2" + } + ] + }, + { + "name": "slot3", + "fans": [ + { + "name": "fan3" + } + ] + }, + { + "name": "slot4", + "fans": [ + { + "name": "fan4" + } + ] + } + ], + "psus": [ + { + "name": "psu1", + "fans": [] + }, + { + "name": "psu2", + "fans": [] + } + ], + "thermals": [ + { + "name": "Cpu temp sensor" + }, + { + "name": "Cpu board temp sensor" + }, + { + "name": "Back-panel temp sensor" + }, + { + "name": "Board sensor" + }, + { + "name": "Switch chip left sensor" + }, + { + "name": "Switch chip right sensor" + }, + { + "name": "Front-panel temp sensor" + }, + { + "name": "Power supply 1 hotspot sensor" + }, + { + "name": "Power supply 1 inlet temp sensor" + }, + { + "name": "Power supply 1 exhaust temp sensor" + }, + { + "name": "Power supply 2 hotspot sensor" + }, + { + "name": "Power supply 2 inlet temp sensor" + }, + { + "name": "Power supply 2 exhaust temp sensor" + } + ], + "sfps": [ + { + "name": "qsfp1" + }, + { + "name": "qsfp2" + }, + { + "name": "qsfp3" + }, + { + "name": "qsfp4" + }, + { + "name": "qsfp5" + }, + { + "name": "qsfp6" + }, + { + "name": "qsfp7" + }, + { + "name": "qsfp8" + }, + { + "name": "qsfp9" + }, + { + "name": "qsfp10" + }, + { + "name": "qsfp11" + }, + { + "name": "qsfp12" + }, + { + "name": "qsfp13" + }, + { + "name": "qsfp14" + }, + { + "name": "qsfp15" + }, + { + "name": "qsfp16" + }, + { + "name": "qsfp17" + }, + { + "name": "qsfp18" + }, + { + "name": "qsfp19" + }, + { + "name": "qsfp20" + }, + { + "name": "qsfp21" + }, + { + "name": "qsfp22" + }, + { + "name": "qsfp23" + }, + { + "name": "qsfp24" + }, + { + "name": "qsfp25" + }, + { + "name": "qsfp26" + }, + { + "name": "qsfp27" + }, + { + "name": "qsfp28" + }, + { + "name": "qsfp29" + }, + { + "name": "qsfp30" + }, + { + "name": "qsfp31" + }, + { + "name": "qsfp32" + }, + { + "name": "sfp33" + }, + { + "name": "sfp34" + } + ] + }, + "interfaces": {} +} \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060_cx32s/plugins/eeprom.py b/device/arista/x86_64-arista_7060_cx32s/plugins/eeprom.py new file mode 120000 index 000000000000..35cfaff3de4e --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/plugins/eeprom.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/eeprom.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060_cx32s/plugins/led_control.py b/device/arista/x86_64-arista_7060_cx32s/plugins/led_control.py new file mode 120000 index 000000000000..8d733780117e --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/plugins/led_control.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/led_control.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060_cx32s/plugins/pcie.yaml b/device/arista/x86_64-arista_7060_cx32s/plugins/pcie.yaml new file mode 100644 index 000000000000..a988a7d1c5fc --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/plugins/pcie.yaml @@ -0,0 +1,140 @@ +- bus: '00' + dev: '00' + fn: '0' + id: '1566' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Root Complex' +- bus: '00' + dev: '00' + fn: '2' + id: '1567' + name: 'IOMMU: Advanced Micro Devices, Inc. [AMD] Mullins IOMMU' +- bus: '00' + dev: '02' + fn: '0' + id: 156b + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Host Bridge' +- bus: '00' + dev: '02' + fn: '1' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '2' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '3' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '4' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '5' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: 08 + fn: '0' + id: '1537' + name: 'Encryption controller: Advanced Micro Devices, Inc. [AMD] Kabini/Mullins + PSP-Platform Security Processor' +- bus: '00' + dev: '11' + fn: '0' + id: '7801' + name: 'SATA controller: Advanced Micro Devices, Inc. [AMD] FCH SATA Controller [AHCI + mode] (rev 40)' +- bus: '00' + dev: '12' + fn: '0' + id: '7808' + name: 'USB controller: Advanced Micro Devices, Inc. [AMD] FCH USB EHCI Controller + (rev 39)' +- bus: '00' + dev: '14' + fn: '0' + id: 780b + name: 'SMBus: Advanced Micro Devices, Inc. [AMD] FCH SMBus Controller (rev 42)' +- bus: '00' + dev: '14' + fn: '3' + id: 780e + name: 'ISA bridge: Advanced Micro Devices, Inc. [AMD] FCH LPC Bridge (rev 11)' +- bus: '00' + dev: '14' + fn: '7' + id: '7813' + name: 'SD Host controller: Advanced Micro Devices, Inc. [AMD] FCH SD Flash Controller + (rev 01)' +- bus: '00' + dev: '18' + fn: '0' + id: '1580' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 0' +- bus: '00' + dev: '18' + fn: '1' + id: '1581' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 1' +- bus: '00' + dev: '18' + fn: '2' + id: '1582' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 2' +- bus: '00' + dev: '18' + fn: '3' + id: '1583' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 3' +- bus: '00' + dev: '18' + fn: '4' + id: '1584' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 4' +- bus: '00' + dev: '18' + fn: '5' + id: '1585' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 5' +- bus: '01' + dev: '00' + fn: '0' + id: b960 + name: 'Ethernet controller: Broadcom Limited Broadcom BCM56960 Switch ASIC (rev + 12)' +- bus: '01' + dev: '00' + fn: '1' + id: b960 + name: 'Ethernet controller: Broadcom Limited Broadcom BCM56960 Switch ASIC (rev + 12)' +- bus: '02' + dev: '00' + fn: '0' + id: '0001' + name: 'System peripheral: Arastra Inc. Device 0001 (rev 01)' +- bus: '04' + dev: '00' + fn: '0' + id: '1682' + name: 'Ethernet controller: Broadcom Limited NetXtreme BCM57762 Gigabit Ethernet + PCIe (rev 20)' diff --git a/device/arista/x86_64-arista_7060_cx32s/plugins/psuutil.py b/device/arista/x86_64-arista_7060_cx32s/plugins/psuutil.py new file mode 120000 index 000000000000..2b0024ade969 --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/plugins/psuutil.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/psuutil.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060_cx32s/plugins/sfputil.py b/device/arista/x86_64-arista_7060_cx32s/plugins/sfputil.py new file mode 120000 index 000000000000..c333e23763d7 --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/plugins/sfputil.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/sfputil.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060_cx32s/pmon_daemon_control.json b/device/arista/x86_64-arista_7060_cx32s/pmon_daemon_control.json new file mode 120000 index 000000000000..51d5ab7b0059 --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060_cx32s/system_health_monitoring_config.json b/device/arista/x86_64-arista_7060_cx32s/system_health_monitoring_config.json new file mode 120000 index 000000000000..1185f771fa8e --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-arista_common/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060_cx32s/thermal_policy.json b/device/arista/x86_64-arista_7060_cx32s/thermal_policy.json new file mode 120000 index 000000000000..0991dc7f3638 --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-arista_common/thermal_policy.json \ No newline at end of file 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.json b/device/arista/x86_64-arista_7060cx2_32s/platform.json new file mode 100644 index 000000000000..fae3f8764735 --- /dev/null +++ b/device/arista/x86_64-arista_7060cx2_32s/platform.json @@ -0,0 +1,197 @@ +{ + "chassis": { + "name": "DCS-7060CX2-32S", + "components": [], + "fans": [], + "fan_drawers": [ + { + "name": "slot1", + "fans": [ + { + "name": "fan1" + } + ] + }, + { + "name": "slot2", + "fans": [ + { + "name": "fan2" + } + ] + }, + { + "name": "slot3", + "fans": [ + { + "name": "fan3" + } + ] + }, + { + "name": "slot4", + "fans": [ + { + "name": "fan4" + } + ] + } + ], + "psus": [ + { + "name": "psu1", + "fans": [] + }, + { + "name": "psu2", + "fans": [] + } + ], + "thermals": [ + { + "name": "Cpu temp sensor" + }, + { + "name": "Cpu board temp sensor" + }, + { + "name": "Back-panel temp sensor" + }, + { + "name": "Board sensor" + }, + { + "name": "Switch chip left sensor" + }, + { + "name": "Switch chip right sensor" + }, + { + "name": "Front-panel temp sensor" + }, + { + "name": "Power supply 1 hotspot sensor" + }, + { + "name": "Power supply 1 inlet temp sensor" + }, + { + "name": "Power supply 1 exhaust temp sensor" + }, + { + "name": "Power supply 2 hotspot sensor" + }, + { + "name": "Power supply 2 inlet temp sensor" + }, + { + "name": "Power supply 2 exhaust temp sensor" + } + ], + "sfps": [ + { + "name": "qsfp1" + }, + { + "name": "qsfp2" + }, + { + "name": "qsfp3" + }, + { + "name": "qsfp4" + }, + { + "name": "qsfp5" + }, + { + "name": "qsfp6" + }, + { + "name": "qsfp7" + }, + { + "name": "qsfp8" + }, + { + "name": "qsfp9" + }, + { + "name": "qsfp10" + }, + { + "name": "qsfp11" + }, + { + "name": "qsfp12" + }, + { + "name": "qsfp13" + }, + { + "name": "qsfp14" + }, + { + "name": "qsfp15" + }, + { + "name": "qsfp16" + }, + { + "name": "qsfp17" + }, + { + "name": "qsfp18" + }, + { + "name": "qsfp19" + }, + { + "name": "qsfp20" + }, + { + "name": "qsfp21" + }, + { + "name": "qsfp22" + }, + { + "name": "qsfp23" + }, + { + "name": "qsfp24" + }, + { + "name": "qsfp25" + }, + { + "name": "qsfp26" + }, + { + "name": "qsfp27" + }, + { + "name": "qsfp28" + }, + { + "name": "qsfp29" + }, + { + "name": "qsfp30" + }, + { + "name": "qsfp31" + }, + { + "name": "qsfp32" + }, + { + "name": "sfp33" + }, + { + "name": "sfp34" + } + ] + }, + "interfaces": {} +} 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_7050_qx32s/plugins b/device/arista/x86_64-arista_7060cx2_32s/plugins similarity index 100% rename from device/arista/x86_64-arista_7050_qx32s/plugins rename to device/arista/x86_64-arista_7060cx2_32s/plugins diff --git a/device/arista/x86_64-arista_7060cx2_32s/pmon_daemon_control.json b/device/arista/x86_64-arista_7060cx2_32s/pmon_daemon_control.json new file mode 120000 index 000000000000..51d5ab7b0059 --- /dev/null +++ b/device/arista/x86_64-arista_7060cx2_32s/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control.json \ 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_7060cx2_32s/system_health_monitoring_config.json b/device/arista/x86_64-arista_7060cx2_32s/system_health_monitoring_config.json new file mode 120000 index 000000000000..1185f771fa8e --- /dev/null +++ b/device/arista/x86_64-arista_7060cx2_32s/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-arista_common/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060cx2_32s/thermal_policy.json b/device/arista/x86_64-arista_7060cx2_32s/thermal_policy.json new file mode 120000 index 000000000000..0991dc7f3638 --- /dev/null +++ b/device/arista/x86_64-arista_7060cx2_32s/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-arista_common/thermal_policy.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060dx4_32 b/device/arista/x86_64-arista_7060dx4_32 deleted file mode 120000 index ac560a1139bf..000000000000 --- a/device/arista/x86_64-arista_7060dx4_32 +++ /dev/null @@ -1 +0,0 @@ -x86_64-arista_7060px4_32/ \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060dx4_32/Arista-7060DX4-C32 b/device/arista/x86_64-arista_7060dx4_32/Arista-7060DX4-C32 new file mode 120000 index 000000000000..19cc64c75f13 --- /dev/null +++ b/device/arista/x86_64-arista_7060dx4_32/Arista-7060DX4-C32 @@ -0,0 +1 @@ +../x86_64-arista_7060px4_32/Arista-7060DX4-C32 \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060dx4_32/Arista-7060PX4-C64 b/device/arista/x86_64-arista_7060dx4_32/Arista-7060PX4-C64 new file mode 120000 index 000000000000..f0d5c7697f08 --- /dev/null +++ b/device/arista/x86_64-arista_7060dx4_32/Arista-7060PX4-C64 @@ -0,0 +1 @@ +../x86_64-arista_7060px4_32/Arista-7060PX4-C64 \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060dx4_32/Arista-7060PX4-O32 b/device/arista/x86_64-arista_7060dx4_32/Arista-7060PX4-O32 new file mode 120000 index 000000000000..1e0685f3fb42 --- /dev/null +++ b/device/arista/x86_64-arista_7060dx4_32/Arista-7060PX4-O32 @@ -0,0 +1 @@ +../x86_64-arista_7060px4_32/Arista-7060PX4-O32 \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060dx4_32/default_sku b/device/arista/x86_64-arista_7060dx4_32/default_sku new file mode 120000 index 000000000000..ebca56647346 --- /dev/null +++ b/device/arista/x86_64-arista_7060dx4_32/default_sku @@ -0,0 +1 @@ +../x86_64-arista_7060px4_32/default_sku \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060dx4_32/fancontrol b/device/arista/x86_64-arista_7060dx4_32/fancontrol new file mode 120000 index 000000000000..099befbdee42 --- /dev/null +++ b/device/arista/x86_64-arista_7060dx4_32/fancontrol @@ -0,0 +1 @@ +../x86_64-arista_7060px4_32/fancontrol \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060dx4_32/platform.json b/device/arista/x86_64-arista_7060dx4_32/platform.json new file mode 100644 index 000000000000..d37370b0d948 --- /dev/null +++ b/device/arista/x86_64-arista_7060dx4_32/platform.json @@ -0,0 +1,223 @@ +{ + "chassis": { + "name": "DCS-7060DX4-32", + "components": [], + "fans": [], + "fan_drawers": [ + { + "name": "slot1", + "fans": [ + { + "name": "fan1" + } + ] + }, + { + "name": "slot2", + "fans": [ + { + "name": "fan2" + } + ] + }, + { + "name": "slot3", + "fans": [ + { + "name": "fan3" + } + ] + }, + { + "name": "slot4", + "fans": [ + { + "name": "fan4" + } + ] + }, + { + "name": "slot5", + "fans": [ + { + "name": "fan5" + } + ] + } + ], + "psus": [ + { + "name": "psu1", + "fans": [] + }, + { + "name": "psu2", + "fans": [] + } + ], + "thermals": [ + { + "name": "Board sensor" + }, + { + "name": "Switch board middle sensor" + }, + { + "name": "Switch board left sensor" + }, + { + "name": "Front-panel temp sensor" + }, + { + "name": "Switch chip diode 1 sensor" + }, + { + "name": "Switch chip diode 2 sensor" + }, + { + "name": "PCH temp sensor" + }, + { + "name": "Physical id 0" + }, + { + "name": "CPU core0 temp sensor" + }, + { + "name": "CPU core1 temp sensor" + }, + { + "name": "CPU board temp sensor" + }, + { + "name": "Back-panel temp sensor" + }, + { + "name": "Front-panel temp sensor" + }, + { + "name": "Power supply 1 hotspot sensor" + }, + { + "name": "Power supply 1 inlet temp sensor" + }, + { + "name": "Power supply 1 exhaust temp sensor" + }, + { + "name": "Power supply 2 hotspot sensor" + }, + { + "name": "Power supply 2 inlet temp sensor" + }, + { + "name": "Power supply 2 exhaust temp sensor" + } + ], + "sfps": [ + { + "name": "osfp1" + }, + { + "name": "osfp2" + }, + { + "name": "osfp3" + }, + { + "name": "osfp4" + }, + { + "name": "osfp5" + }, + { + "name": "osfp6" + }, + { + "name": "osfp7" + }, + { + "name": "osfp8" + }, + { + "name": "osfp9" + }, + { + "name": "osfp10" + }, + { + "name": "osfp11" + }, + { + "name": "osfp12" + }, + { + "name": "osfp13" + }, + { + "name": "osfp14" + }, + { + "name": "osfp15" + }, + { + "name": "osfp16" + }, + { + "name": "osfp17" + }, + { + "name": "osfp18" + }, + { + "name": "osfp19" + }, + { + "name": "osfp20" + }, + { + "name": "osfp21" + }, + { + "name": "osfp22" + }, + { + "name": "osfp23" + }, + { + "name": "osfp24" + }, + { + "name": "osfp25" + }, + { + "name": "osfp26" + }, + { + "name": "osfp27" + }, + { + "name": "osfp28" + }, + { + "name": "osfp29" + }, + { + "name": "osfp30" + }, + { + "name": "osfp31" + }, + { + "name": "osfp32" + }, + { + "name": "sfp33" + }, + { + "name": "sfp34" + } + ] + }, + "interfaces": {} +} diff --git a/device/arista/x86_64-arista_7060dx4_32/platform_reboot b/device/arista/x86_64-arista_7060dx4_32/platform_reboot new file mode 120000 index 000000000000..d82455f8577b --- /dev/null +++ b/device/arista/x86_64-arista_7060dx4_32/platform_reboot @@ -0,0 +1 @@ +../x86_64-arista_7060px4_32/platform_reboot \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060dx4_32/plugins b/device/arista/x86_64-arista_7060dx4_32/plugins new file mode 120000 index 000000000000..b2db88a63359 --- /dev/null +++ b/device/arista/x86_64-arista_7060dx4_32/plugins @@ -0,0 +1 @@ +../x86_64-arista_7060px4_32/plugins \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060dx4_32/pmon_daemon_control.json b/device/arista/x86_64-arista_7060dx4_32/pmon_daemon_control.json new file mode 120000 index 000000000000..247cff87a9ea --- /dev/null +++ b/device/arista/x86_64-arista_7060dx4_32/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_7060px4_32/pmon_daemon_control.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060dx4_32/sensors.conf b/device/arista/x86_64-arista_7060dx4_32/sensors.conf new file mode 120000 index 000000000000..efe0b2605896 --- /dev/null +++ b/device/arista/x86_64-arista_7060dx4_32/sensors.conf @@ -0,0 +1 @@ +../x86_64-arista_7060px4_32/sensors.conf \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060dx4_32/system_health_monitoring_config.json b/device/arista/x86_64-arista_7060dx4_32/system_health_monitoring_config.json new file mode 120000 index 000000000000..1185f771fa8e --- /dev/null +++ b/device/arista/x86_64-arista_7060dx4_32/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-arista_common/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060dx4_32/thermal_policy.json b/device/arista/x86_64-arista_7060dx4_32/thermal_policy.json new file mode 120000 index 000000000000..a14947df5b5c --- /dev/null +++ b/device/arista/x86_64-arista_7060dx4_32/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-arista_7060px4_32/thermal_policy.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060px4_32/Arista-7060DX4-C32/port_config.ini b/device/arista/x86_64-arista_7060px4_32/Arista-7060DX4-C32/port_config.ini new file mode 100644 index 000000000000..45ef9b7754b9 --- /dev/null +++ b/device/arista/x86_64-arista_7060px4_32/Arista-7060DX4-C32/port_config.ini @@ -0,0 +1,35 @@ +# name lanes alias index speed +Ethernet0 1,2,3,4,5,6,7,8 Ethernet1/1 1 400000 +Ethernet8 9,10,11,12,13,14,15,16 Ethernet2/1 2 400000 +Ethernet16 17,18,19,20,21,22,23,24 Ethernet3/1 3 400000 +Ethernet24 25,26,27,28,29,30,31,32 Ethernet4/1 4 400000 +Ethernet32 33,34,35,36,37,38,39,40 Ethernet5/1 5 400000 +Ethernet40 41,42,43,44,45,46,47,48 Ethernet6/1 6 400000 +Ethernet48 49,50,51,52,53,54,55,56 Ethernet7/1 7 400000 +Ethernet56 57,58,59,60,61,62,63,64 Ethernet8/1 8 400000 +Ethernet64 65,66,67,68,69,70,71,72 Ethernet9/1 9 400000 +Ethernet72 73,74,75,76,77,78,79,80 Ethernet10/1 10 400000 +Ethernet80 81,82,83,84,85,86,87,88 Ethernet11/1 11 400000 +Ethernet88 89,90,91,92,93,94,95,96 Ethernet12/1 12 400000 +Ethernet96 97,98,99,100,101,102,103,104 Ethernet13/1 13 400000 +Ethernet104 105,106,107,108,109,110,111,112 Ethernet14/1 14 400000 +Ethernet112 113,114,115,116,117,118,119,120 Ethernet15/1 15 400000 +Ethernet120 121,122,123,124,125,126,127,128 Ethernet16/1 16 400000 +Ethernet128 129,130,131,132,133,134,135,136 Ethernet17/1 17 400000 +Ethernet136 137,138,139,140,141,142,143,144 Ethernet18/1 18 400000 +Ethernet144 145,146,147,148,149,150,151,152 Ethernet19/1 19 400000 +Ethernet152 153,154,155,156,157,158,159,160 Ethernet20/1 20 400000 +Ethernet160 161,162,163,164,165,166,167,168 Ethernet21/1 21 400000 +Ethernet168 169,170,171,172,173,174,175,176 Ethernet22/1 22 400000 +Ethernet176 177,178,179,180,181,182,183,184 Ethernet23/1 23 400000 +Ethernet184 185,186,187,188,189,190,191,192 Ethernet24/1 24 400000 +Ethernet192 193,194,195,196,197,198,199,200 Ethernet25/1 25 400000 +Ethernet200 201,202,203,204,205,206,207,208 Ethernet26/1 26 400000 +Ethernet208 209,210,211,212,213,214,215,216 Ethernet27/1 27 400000 +Ethernet216 217,218,219,220,221,222,223,224 Ethernet28/1 28 400000 +Ethernet224 225,226,227,228,229,230,231,232 Ethernet29/1 29 400000 +Ethernet232 233,234,235,236,237,238,239,240 Ethernet30/1 30 400000 +Ethernet240 241,242,243,244,245,246,247,248 Ethernet31/1 31 400000 +Ethernet248 249,250,251,252,253,254,255,256 Ethernet32/1 32 400000 +Ethernet256 258 Ethernet33 33 10000 +Ethernet260 257 Ethernet34 34 10000 diff --git a/device/arista/x86_64-arista_7060px4_32/Arista-7060DX4-C32/sai.profile b/device/arista/x86_64-arista_7060px4_32/Arista-7060DX4-C32/sai.profile new file mode 100644 index 000000000000..296b1c8b0ecb --- /dev/null +++ b/device/arista/x86_64-arista_7060px4_32/Arista-7060DX4-C32/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-a7060dx4-c32-32x400G.config.bcm diff --git a/device/arista/x86_64-arista_7060px4_32/Arista-7060DX4-C32/th3-a7060dx4-c32-32x400G.config.bcm b/device/arista/x86_64-arista_7060px4_32/Arista-7060DX4-C32/th3-a7060dx4-c32-32x400G.config.bcm new file mode 100644 index 000000000000..7bd96fed83b8 --- /dev/null +++ b/device/arista/x86_64-arista_7060px4_32/Arista-7060DX4-C32/th3-a7060dx4-c32-32x400G.config.bcm @@ -0,0 +1,848 @@ +arl_clean_timeout_usec=15000000 +asf_mem_profile.0=2 +bcm_num_cos.0=8 +bcm_stat_flags=1 +bcm_stat_jumbo.0=9236 +cdma_timeout_usec.0=15000000 +disable_pcie_firmware_check.0=1 +dma_desc_timeout_usec.0=15000000 +dpr_clock_frequency.0=1000 +l2xmsg_mode.0=1 +l2_mem_entries.0=8192 +l3_alpm_enable.0=2 +l3_mem_entries.0=16384 +max_vp_lags.0=0 +miim_intr_enable.0=0 +module_64ports.0=1 +multicast_l2_range.0=511 +oversubscribe_mode=1 +parity_correction=1 +parity_enable=1 +pbmp_xport_xe.0=0x3ffffffffffffffffffffffffffffffffffffffe +phy_an_c37_38.0=2 +phy_an_c37_118.0=2 +phy_an_c73_1.0=1 +phy_an_c73_2.0=1 +phy_an_c73_3.0=1 +phy_an_c73_4.0=1 +phy_an_c73_20.0=1 +phy_an_c73_21.0=1 +phy_an_c73_22.0=1 +phy_an_c73_23.0=1 +phy_an_c73_38.0=0 +phy_an_c73_40.0=1 +phy_an_c73_41.0=1 +phy_an_c73_42.0=1 +phy_an_c73_43.0=1 +phy_an_c73_60.0=1 +phy_an_c73_61.0=1 +phy_an_c73_62.0=1 +phy_an_c73_63.0=1 +phy_an_c73_80.0=1 +phy_an_c73_81.0=1 +phy_an_c73_82.0=1 +phy_an_c73_83.0=1 +phy_an_c73_100.0=1 +phy_an_c73_101.0=1 +phy_an_c73_102.0=1 +phy_an_c73_103.0=1 +phy_an_c73_118.0=0 +phy_an_c73_120.0=1 +phy_an_c73_121.0=1 +phy_an_c73_122.0=1 +phy_an_c73_123.0=1 +phy_an_c73_140.0=1 +phy_an_c73_141.0=1 +phy_an_c73_142.0=1 +phy_an_c73_143.0=1 +phy_chain_rx_lane_map_physical{1.0}=0x42537160 +phy_chain_rx_lane_map_physical{9.0}=0x60715342 +phy_chain_rx_lane_map_physical{17.0}=0x06173425 +phy_chain_rx_lane_map_physical{25.0}=0x02471356 +phy_chain_rx_lane_map_physical{33.0}=0x27160534 +phy_chain_rx_lane_map_physical{41.0}=0x02461357 +phy_chain_rx_lane_map_physical{49.0}=0x26150437 +phy_chain_rx_lane_map_physical{57.0}=0x02461357 +phy_chain_rx_lane_map_physical{65.0}=0x27140536 +phy_chain_rx_lane_map_physical{73.0}=0x02471356 +phy_chain_rx_lane_map_physical{81.0}=0x27140536 +phy_chain_rx_lane_map_physical{89.0}=0x02471356 +phy_chain_rx_lane_map_physical{97.0}=0x02461357 +phy_chain_rx_lane_map_physical{105.0}=0x57124603 +phy_chain_rx_lane_map_physical{113.0}=0x17243506 +phy_chain_rx_lane_map_physical{121.0}=0x46315720 +phy_chain_rx_lane_map_physical{129.0}=0x60534271 +phy_chain_rx_lane_map_physical{137.0}=0x02461357 +phy_chain_rx_lane_map_physical{145.0}=0x27140536 +phy_chain_rx_lane_map_physical{153.0}=0x50271463 +phy_chain_rx_lane_map_physical{161.0}=0x31652074 +phy_chain_rx_lane_map_physical{169.0}=0x02461357 +phy_chain_rx_lane_map_physical{177.0}=0x26140537 +phy_chain_rx_lane_map_physical{185.0}=0x02461357 +phy_chain_rx_lane_map_physical{193.0}=0x26140537 +phy_chain_rx_lane_map_physical{201.0}=0x02461357 +phy_chain_rx_lane_map_physical{209.0}=0x27140536 +phy_chain_rx_lane_map_physical{217.0}=0x02641357 +phy_chain_rx_lane_map_physical{225.0}=0x60734251 +phy_chain_rx_lane_map_physical{233.0}=0x31462057 +phy_chain_rx_lane_map_physical{241.0}=0x60715342 +phy_chain_rx_lane_map_physical{249.0}=0x35216047 +phy_chain_rx_lane_map_physical{257.0}=0x3210 +phy_chain_rx_polarity_flip_physical{1.0}=0x1 +phy_chain_rx_polarity_flip_physical{2.0}=0x0 +phy_chain_rx_polarity_flip_physical{3.0}=0x0 +phy_chain_rx_polarity_flip_physical{4.0}=0x1 +phy_chain_rx_polarity_flip_physical{5.0}=0x0 +phy_chain_rx_polarity_flip_physical{6.0}=0x1 +phy_chain_rx_polarity_flip_physical{7.0}=0x1 +phy_chain_rx_polarity_flip_physical{8.0}=0x0 +phy_chain_rx_polarity_flip_physical{9.0}=0x1 +phy_chain_rx_polarity_flip_physical{10.0}=0x0 +phy_chain_rx_polarity_flip_physical{11.0}=0x0 +phy_chain_rx_polarity_flip_physical{12.0}=0x1 +phy_chain_rx_polarity_flip_physical{13.0}=0x0 +phy_chain_rx_polarity_flip_physical{14.0}=0x1 +phy_chain_rx_polarity_flip_physical{15.0}=0x1 +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{21.0}=0x0 +phy_chain_rx_polarity_flip_physical{22.0}=0x1 +phy_chain_rx_polarity_flip_physical{23.0}=0x1 +phy_chain_rx_polarity_flip_physical{24.0}=0x1 +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}=0x0 +phy_chain_rx_polarity_flip_physical{28.0}=0x0 +phy_chain_rx_polarity_flip_physical{29.0}=0x0 +phy_chain_rx_polarity_flip_physical{30.0}=0x1 +phy_chain_rx_polarity_flip_physical{31.0}=0x1 +phy_chain_rx_polarity_flip_physical{32.0}=0x0 +phy_chain_rx_polarity_flip_physical{33.0}=0x1 +phy_chain_rx_polarity_flip_physical{34.0}=0x1 +phy_chain_rx_polarity_flip_physical{35.0}=0x0 +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{41.0}=0x0 +phy_chain_rx_polarity_flip_physical{42.0}=0x1 +phy_chain_rx_polarity_flip_physical{43.0}=0x1 +phy_chain_rx_polarity_flip_physical{44.0}=0x0 +phy_chain_rx_polarity_flip_physical{45.0}=0x0 +phy_chain_rx_polarity_flip_physical{46.0}=0x1 +phy_chain_rx_polarity_flip_physical{47.0}=0x1 +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{51.0}=0x1 +phy_chain_rx_polarity_flip_physical{52.0}=0x0 +phy_chain_rx_polarity_flip_physical{53.0}=0x0 +phy_chain_rx_polarity_flip_physical{54.0}=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}=0x1 +phy_chain_rx_polarity_flip_physical{59.0}=0x1 +phy_chain_rx_polarity_flip_physical{60.0}=0x0 +phy_chain_rx_polarity_flip_physical{61.0}=0x0 +phy_chain_rx_polarity_flip_physical{62.0}=0x1 +phy_chain_rx_polarity_flip_physical{63.0}=0x1 +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}=0x0 +phy_chain_rx_polarity_flip_physical{69.0}=0x1 +phy_chain_rx_polarity_flip_physical{70.0}=0x1 +phy_chain_rx_polarity_flip_physical{71.0}=0x0 +phy_chain_rx_polarity_flip_physical{72.0}=0x0 +phy_chain_rx_polarity_flip_physical{73.0}=0x1 +phy_chain_rx_polarity_flip_physical{74.0}=0x1 +phy_chain_rx_polarity_flip_physical{75.0}=0x0 +phy_chain_rx_polarity_flip_physical{76.0}=0x0 +phy_chain_rx_polarity_flip_physical{77.0}=0x0 +phy_chain_rx_polarity_flip_physical{78.0}=0x1 +phy_chain_rx_polarity_flip_physical{79.0}=0x1 +phy_chain_rx_polarity_flip_physical{80.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}=0x0 +phy_chain_rx_polarity_flip_physical{85.0}=0x1 +phy_chain_rx_polarity_flip_physical{86.0}=0x1 +phy_chain_rx_polarity_flip_physical{87.0}=0x0 +phy_chain_rx_polarity_flip_physical{88.0}=0x0 +phy_chain_rx_polarity_flip_physical{89.0}=0x1 +phy_chain_rx_polarity_flip_physical{90.0}=0x1 +phy_chain_rx_polarity_flip_physical{91.0}=0x0 +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}=0x1 +phy_chain_rx_polarity_flip_physical{95.0}=0x1 +phy_chain_rx_polarity_flip_physical{96.0}=0x0 +phy_chain_rx_polarity_flip_physical{97.0}=0x0 +phy_chain_rx_polarity_flip_physical{98.0}=0x1 +phy_chain_rx_polarity_flip_physical{99.0}=0x1 +phy_chain_rx_polarity_flip_physical{100.0}=0x1 +phy_chain_rx_polarity_flip_physical{101.0}=0x1 +phy_chain_rx_polarity_flip_physical{102.0}=0x0 +phy_chain_rx_polarity_flip_physical{103.0}=0x0 +phy_chain_rx_polarity_flip_physical{104.0}=0x0 +phy_chain_rx_polarity_flip_physical{105.0}=0x1 +phy_chain_rx_polarity_flip_physical{106.0}=0x1 +phy_chain_rx_polarity_flip_physical{107.0}=0x0 +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}=0x1 +phy_chain_rx_polarity_flip_physical{111.0}=0x1 +phy_chain_rx_polarity_flip_physical{112.0}=0x0 +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}=0x1 +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{121.0}=0x1 +phy_chain_rx_polarity_flip_physical{122.0}=0x0 +phy_chain_rx_polarity_flip_physical{123.0}=0x0 +phy_chain_rx_polarity_flip_physical{124.0}=0x1 +phy_chain_rx_polarity_flip_physical{125.0}=0x0 +phy_chain_rx_polarity_flip_physical{126.0}=0x1 +phy_chain_rx_polarity_flip_physical{127.0}=0x1 +phy_chain_rx_polarity_flip_physical{128.0}=0x0 +phy_chain_rx_polarity_flip_physical{129.0}=0x0 +phy_chain_rx_polarity_flip_physical{130.0}=0x0 +phy_chain_rx_polarity_flip_physical{131.0}=0x1 +phy_chain_rx_polarity_flip_physical{132.0}=0x0 +phy_chain_rx_polarity_flip_physical{133.0}=0x0 +phy_chain_rx_polarity_flip_physical{134.0}=0x1 +phy_chain_rx_polarity_flip_physical{135.0}=0x0 +phy_chain_rx_polarity_flip_physical{136.0}=0x0 +phy_chain_rx_polarity_flip_physical{137.0}=0x0 +phy_chain_rx_polarity_flip_physical{138.0}=0x1 +phy_chain_rx_polarity_flip_physical{139.0}=0x1 +phy_chain_rx_polarity_flip_physical{140.0}=0x0 +phy_chain_rx_polarity_flip_physical{141.0}=0x0 +phy_chain_rx_polarity_flip_physical{142.0}=0x1 +phy_chain_rx_polarity_flip_physical{143.0}=0x1 +phy_chain_rx_polarity_flip_physical{144.0}=0x0 +phy_chain_rx_polarity_flip_physical{145.0}=0x1 +phy_chain_rx_polarity_flip_physical{146.0}=0x1 +phy_chain_rx_polarity_flip_physical{147.0}=0x0 +phy_chain_rx_polarity_flip_physical{148.0}=0x0 +phy_chain_rx_polarity_flip_physical{149.0}=0x1 +phy_chain_rx_polarity_flip_physical{150.0}=0x1 +phy_chain_rx_polarity_flip_physical{151.0}=0x0 +phy_chain_rx_polarity_flip_physical{152.0}=0x0 +phy_chain_rx_polarity_flip_physical{153.0}=0x0 +phy_chain_rx_polarity_flip_physical{154.0}=0x1 +phy_chain_rx_polarity_flip_physical{155.0}=0x0 +phy_chain_rx_polarity_flip_physical{156.0}=0x1 +phy_chain_rx_polarity_flip_physical{157.0}=0x1 +phy_chain_rx_polarity_flip_physical{158.0}=0x0 +phy_chain_rx_polarity_flip_physical{159.0}=0x1 +phy_chain_rx_polarity_flip_physical{160.0}=0x0 +phy_chain_rx_polarity_flip_physical{161.0}=0x1 +phy_chain_rx_polarity_flip_physical{162.0}=0x1 +phy_chain_rx_polarity_flip_physical{163.0}=0x1 +phy_chain_rx_polarity_flip_physical{164.0}=0x1 +phy_chain_rx_polarity_flip_physical{165.0}=0x0 +phy_chain_rx_polarity_flip_physical{166.0}=0x0 +phy_chain_rx_polarity_flip_physical{167.0}=0x0 +phy_chain_rx_polarity_flip_physical{168.0}=0x0 +phy_chain_rx_polarity_flip_physical{169.0}=0x0 +phy_chain_rx_polarity_flip_physical{170.0}=0x1 +phy_chain_rx_polarity_flip_physical{171.0}=0x1 +phy_chain_rx_polarity_flip_physical{172.0}=0x0 +phy_chain_rx_polarity_flip_physical{173.0}=0x0 +phy_chain_rx_polarity_flip_physical{174.0}=0x1 +phy_chain_rx_polarity_flip_physical{175.0}=0x1 +phy_chain_rx_polarity_flip_physical{176.0}=0x0 +phy_chain_rx_polarity_flip_physical{177.0}=0x0 +phy_chain_rx_polarity_flip_physical{178.0}=0x0 +phy_chain_rx_polarity_flip_physical{179.0}=0x0 +phy_chain_rx_polarity_flip_physical{180.0}=0x0 +phy_chain_rx_polarity_flip_physical{181.0}=0x1 +phy_chain_rx_polarity_flip_physical{182.0}=0x1 +phy_chain_rx_polarity_flip_physical{183.0}=0x0 +phy_chain_rx_polarity_flip_physical{184.0}=0x0 +phy_chain_rx_polarity_flip_physical{185.0}=0x0 +phy_chain_rx_polarity_flip_physical{186.0}=0x1 +phy_chain_rx_polarity_flip_physical{187.0}=0x1 +phy_chain_rx_polarity_flip_physical{188.0}=0x0 +phy_chain_rx_polarity_flip_physical{189.0}=0x0 +phy_chain_rx_polarity_flip_physical{190.0}=0x1 +phy_chain_rx_polarity_flip_physical{191.0}=0x1 +phy_chain_rx_polarity_flip_physical{192.0}=0x0 +phy_chain_rx_polarity_flip_physical{193.0}=0x0 +phy_chain_rx_polarity_flip_physical{194.0}=0x0 +phy_chain_rx_polarity_flip_physical{195.0}=0x0 +phy_chain_rx_polarity_flip_physical{196.0}=0x0 +phy_chain_rx_polarity_flip_physical{197.0}=0x1 +phy_chain_rx_polarity_flip_physical{198.0}=0x1 +phy_chain_rx_polarity_flip_physical{199.0}=0x0 +phy_chain_rx_polarity_flip_physical{200.0}=0x0 +phy_chain_rx_polarity_flip_physical{201.0}=0x0 +phy_chain_rx_polarity_flip_physical{202.0}=0x1 +phy_chain_rx_polarity_flip_physical{203.0}=0x1 +phy_chain_rx_polarity_flip_physical{204.0}=0x0 +phy_chain_rx_polarity_flip_physical{205.0}=0x0 +phy_chain_rx_polarity_flip_physical{206.0}=0x1 +phy_chain_rx_polarity_flip_physical{207.0}=0x1 +phy_chain_rx_polarity_flip_physical{208.0}=0x0 +phy_chain_rx_polarity_flip_physical{209.0}=0x1 +phy_chain_rx_polarity_flip_physical{210.0}=0x1 +phy_chain_rx_polarity_flip_physical{211.0}=0x0 +phy_chain_rx_polarity_flip_physical{212.0}=0x0 +phy_chain_rx_polarity_flip_physical{213.0}=0x1 +phy_chain_rx_polarity_flip_physical{214.0}=0x1 +phy_chain_rx_polarity_flip_physical{215.0}=0x0 +phy_chain_rx_polarity_flip_physical{216.0}=0x0 +phy_chain_rx_polarity_flip_physical{217.0}=0x0 +phy_chain_rx_polarity_flip_physical{218.0}=0x1 +phy_chain_rx_polarity_flip_physical{219.0}=0x1 +phy_chain_rx_polarity_flip_physical{220.0}=0x0 +phy_chain_rx_polarity_flip_physical{221.0}=0x0 +phy_chain_rx_polarity_flip_physical{222.0}=0x1 +phy_chain_rx_polarity_flip_physical{223.0}=0x1 +phy_chain_rx_polarity_flip_physical{224.0}=0x0 +phy_chain_rx_polarity_flip_physical{225.0}=0x0 +phy_chain_rx_polarity_flip_physical{226.0}=0x0 +phy_chain_rx_polarity_flip_physical{227.0}=0x1 +phy_chain_rx_polarity_flip_physical{228.0}=0x0 +phy_chain_rx_polarity_flip_physical{229.0}=0x0 +phy_chain_rx_polarity_flip_physical{230.0}=0x1 +phy_chain_rx_polarity_flip_physical{231.0}=0x0 +phy_chain_rx_polarity_flip_physical{232.0}=0x0 +phy_chain_rx_polarity_flip_physical{233.0}=0x0 +phy_chain_rx_polarity_flip_physical{234.0}=0x1 +phy_chain_rx_polarity_flip_physical{235.0}=0x1 +phy_chain_rx_polarity_flip_physical{236.0}=0x0 +phy_chain_rx_polarity_flip_physical{237.0}=0x1 +phy_chain_rx_polarity_flip_physical{238.0}=0x0 +phy_chain_rx_polarity_flip_physical{239.0}=0x0 +phy_chain_rx_polarity_flip_physical{240.0}=0x1 +phy_chain_rx_polarity_flip_physical{241.0}=0x1 +phy_chain_rx_polarity_flip_physical{242.0}=0x0 +phy_chain_rx_polarity_flip_physical{243.0}=0x0 +phy_chain_rx_polarity_flip_physical{244.0}=0x0 +phy_chain_rx_polarity_flip_physical{245.0}=0x0 +phy_chain_rx_polarity_flip_physical{246.0}=0x1 +phy_chain_rx_polarity_flip_physical{247.0}=0x1 +phy_chain_rx_polarity_flip_physical{248.0}=0x1 +phy_chain_rx_polarity_flip_physical{249.0}=0x1 +phy_chain_rx_polarity_flip_physical{250.0}=0x1 +phy_chain_rx_polarity_flip_physical{251.0}=0x0 +phy_chain_rx_polarity_flip_physical{252.0}=0x0 +phy_chain_rx_polarity_flip_physical{253.0}=0x0 +phy_chain_rx_polarity_flip_physical{254.0}=0x0 +phy_chain_rx_polarity_flip_physical{255.0}=0x1 +phy_chain_rx_polarity_flip_physical{256.0}=0x1 +phy_chain_rx_polarity_flip_physical{257.0}=0x0 +phy_chain_rx_polarity_flip_physical{258.0}=0x0 +phy_chain_tx_lane_map_physical{1.0}=0x30451627 +phy_chain_tx_lane_map_physical{9.0}=0x74532610 +phy_chain_tx_lane_map_physical{17.0}=0x51407362 +phy_chain_tx_lane_map_physical{25.0}=0x27160435 +phy_chain_tx_lane_map_physical{33.0}=0x65347021 +phy_chain_tx_lane_map_physical{41.0}=0x16072435 +phy_chain_tx_lane_map_physical{49.0}=0x75126430 +phy_chain_tx_lane_map_physical{57.0}=0x26071435 +phy_chain_tx_lane_map_physical{65.0}=0x75026431 +phy_chain_tx_lane_map_physical{73.0}=0x26071435 +phy_chain_tx_lane_map_physical{81.0}=0x75026431 +phy_chain_tx_lane_map_physical{89.0}=0x26071435 +phy_chain_tx_lane_map_physical{97.0}=0x03746521 +phy_chain_tx_lane_map_physical{105.0}=0x06142735 +phy_chain_tx_lane_map_physical{113.0}=0x56237014 +phy_chain_tx_lane_map_physical{121.0}=0x01426375 +phy_chain_tx_lane_map_physical{129.0}=0x12673450 +phy_chain_tx_lane_map_physical{137.0}=0x45062731 +phy_chain_tx_lane_map_physical{145.0}=0x56237014 +phy_chain_tx_lane_map_physical{153.0}=0x56012437 +phy_chain_tx_lane_map_physical{161.0}=0x76215430 +phy_chain_tx_lane_map_physical{169.0}=0x57362410 +phy_chain_tx_lane_map_physical{177.0}=0x76215430 +phy_chain_tx_lane_map_physical{185.0}=0x57362410 +phy_chain_tx_lane_map_physical{193.0}=0x76215430 +phy_chain_tx_lane_map_physical{201.0}=0x57362410 +phy_chain_tx_lane_map_physical{209.0}=0x76215430 +phy_chain_tx_lane_map_physical{217.0}=0x57261430 +phy_chain_tx_lane_map_physical{225.0}=0x65217430 +phy_chain_tx_lane_map_physical{233.0}=0x45063721 +phy_chain_tx_lane_map_physical{241.0}=0x75216430 +phy_chain_tx_lane_map_physical{249.0}=0x64275130 +phy_chain_tx_lane_map_physical{257.0}=0x3210 +phy_chain_tx_polarity_flip_physical{1.0}=0x1 +phy_chain_tx_polarity_flip_physical{2.0}=0x1 +phy_chain_tx_polarity_flip_physical{3.0}=0x0 +phy_chain_tx_polarity_flip_physical{4.0}=0x1 +phy_chain_tx_polarity_flip_physical{5.0}=0x1 +phy_chain_tx_polarity_flip_physical{6.0}=0x1 +phy_chain_tx_polarity_flip_physical{7.0}=0x1 +phy_chain_tx_polarity_flip_physical{8.0}=0x0 +phy_chain_tx_polarity_flip_physical{9.0}=0x1 +phy_chain_tx_polarity_flip_physical{10.0}=0x0 +phy_chain_tx_polarity_flip_physical{11.0}=0x1 +phy_chain_tx_polarity_flip_physical{12.0}=0x1 +phy_chain_tx_polarity_flip_physical{13.0}=0x0 +phy_chain_tx_polarity_flip_physical{14.0}=0x0 +phy_chain_tx_polarity_flip_physical{15.0}=0x1 +phy_chain_tx_polarity_flip_physical{16.0}=0x0 +phy_chain_tx_polarity_flip_physical{17.0}=0x1 +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}=0x1 +phy_chain_tx_polarity_flip_physical{21.0}=0x0 +phy_chain_tx_polarity_flip_physical{22.0}=0x1 +phy_chain_tx_polarity_flip_physical{23.0}=0x1 +phy_chain_tx_polarity_flip_physical{24.0}=0x0 +phy_chain_tx_polarity_flip_physical{25.0}=0x1 +phy_chain_tx_polarity_flip_physical{26.0}=0x0 +phy_chain_tx_polarity_flip_physical{27.0}=0x0 +phy_chain_tx_polarity_flip_physical{28.0}=0x1 +phy_chain_tx_polarity_flip_physical{29.0}=0x0 +phy_chain_tx_polarity_flip_physical{30.0}=0x1 +phy_chain_tx_polarity_flip_physical{31.0}=0x1 +phy_chain_tx_polarity_flip_physical{32.0}=0x0 +phy_chain_tx_polarity_flip_physical{33.0}=0x0 +phy_chain_tx_polarity_flip_physical{34.0}=0x0 +phy_chain_tx_polarity_flip_physical{35.0}=0x0 +phy_chain_tx_polarity_flip_physical{36.0}=0x1 +phy_chain_tx_polarity_flip_physical{37.0}=0x1 +phy_chain_tx_polarity_flip_physical{38.0}=0x1 +phy_chain_tx_polarity_flip_physical{39.0}=0x1 +phy_chain_tx_polarity_flip_physical{40.0}=0x0 +phy_chain_tx_polarity_flip_physical{41.0}=0x0 +phy_chain_tx_polarity_flip_physical{42.0}=0x0 +phy_chain_tx_polarity_flip_physical{43.0}=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{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}=0x0 +phy_chain_tx_polarity_flip_physical{60.0}=0x1 +phy_chain_tx_polarity_flip_physical{61.0}=0x0 +phy_chain_tx_polarity_flip_physical{62.0}=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}=0x0 +phy_chain_tx_polarity_flip_physical{68.0}=0x0 +phy_chain_tx_polarity_flip_physical{69.0}=0x0 +phy_chain_tx_polarity_flip_physical{70.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}=0x0 +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{81.0}=0x1 +phy_chain_tx_polarity_flip_physical{82.0}=0x1 +phy_chain_tx_polarity_flip_physical{83.0}=0x0 +phy_chain_tx_polarity_flip_physical{84.0}=0x0 +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{91.0}=0x0 +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}=0x0 +phy_chain_tx_polarity_flip_physical{98.0}=0x0 +phy_chain_tx_polarity_flip_physical{99.0}=0x0 +phy_chain_tx_polarity_flip_physical{100.0}=0x0 +phy_chain_tx_polarity_flip_physical{101.0}=0x1 +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}=0x1 +phy_chain_tx_polarity_flip_physical{109.0}=0x1 +phy_chain_tx_polarity_flip_physical{110.0}=0x0 +phy_chain_tx_polarity_flip_physical{111.0}=0x1 +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}=0x1 +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}=0x0 +phy_chain_tx_polarity_flip_physical{119.0}=0x0 +phy_chain_tx_polarity_flip_physical{120.0}=0x0 +phy_chain_tx_polarity_flip_physical{121.0}=0x0 +phy_chain_tx_polarity_flip_physical{122.0}=0x0 +phy_chain_tx_polarity_flip_physical{123.0}=0x1 +phy_chain_tx_polarity_flip_physical{124.0}=0x1 +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{130.0}=0x1 +phy_chain_tx_polarity_flip_physical{131.0}=0x0 +phy_chain_tx_polarity_flip_physical{132.0}=0x0 +phy_chain_tx_polarity_flip_physical{133.0}=0x1 +phy_chain_tx_polarity_flip_physical{134.0}=0x0 +phy_chain_tx_polarity_flip_physical{135.0}=0x0 +phy_chain_tx_polarity_flip_physical{136.0}=0x0 +phy_chain_tx_polarity_flip_physical{137.0}=0x0 +phy_chain_tx_polarity_flip_physical{138.0}=0x0 +phy_chain_tx_polarity_flip_physical{139.0}=0x1 +phy_chain_tx_polarity_flip_physical{140.0}=0x1 +phy_chain_tx_polarity_flip_physical{141.0}=0x1 +phy_chain_tx_polarity_flip_physical{142.0}=0x1 +phy_chain_tx_polarity_flip_physical{143.0}=0x0 +phy_chain_tx_polarity_flip_physical{144.0}=0x0 +phy_chain_tx_polarity_flip_physical{145.0}=0x0 +phy_chain_tx_polarity_flip_physical{146.0}=0x1 +phy_chain_tx_polarity_flip_physical{147.0}=0x0 +phy_chain_tx_polarity_flip_physical{148.0}=0x0 +phy_chain_tx_polarity_flip_physical{149.0}=0x1 +phy_chain_tx_polarity_flip_physical{150.0}=0x0 +phy_chain_tx_polarity_flip_physical{151.0}=0x0 +phy_chain_tx_polarity_flip_physical{152.0}=0x0 +phy_chain_tx_polarity_flip_physical{153.0}=0x0 +phy_chain_tx_polarity_flip_physical{154.0}=0x0 +phy_chain_tx_polarity_flip_physical{155.0}=0x0 +phy_chain_tx_polarity_flip_physical{156.0}=0x1 +phy_chain_tx_polarity_flip_physical{157.0}=0x0 +phy_chain_tx_polarity_flip_physical{158.0}=0x1 +phy_chain_tx_polarity_flip_physical{159.0}=0x1 +phy_chain_tx_polarity_flip_physical{160.0}=0x0 +phy_chain_tx_polarity_flip_physical{161.0}=0x0 +phy_chain_tx_polarity_flip_physical{162.0}=0x1 +phy_chain_tx_polarity_flip_physical{163.0}=0x1 +phy_chain_tx_polarity_flip_physical{164.0}=0x0 +phy_chain_tx_polarity_flip_physical{165.0}=0x0 +phy_chain_tx_polarity_flip_physical{166.0}=0x0 +phy_chain_tx_polarity_flip_physical{167.0}=0x0 +phy_chain_tx_polarity_flip_physical{168.0}=0x0 +phy_chain_tx_polarity_flip_physical{169.0}=0x1 +phy_chain_tx_polarity_flip_physical{170.0}=0x0 +phy_chain_tx_polarity_flip_physical{171.0}=0x0 +phy_chain_tx_polarity_flip_physical{172.0}=0x1 +phy_chain_tx_polarity_flip_physical{173.0}=0x0 +phy_chain_tx_polarity_flip_physical{174.0}=0x1 +phy_chain_tx_polarity_flip_physical{175.0}=0x1 +phy_chain_tx_polarity_flip_physical{176.0}=0x0 +phy_chain_tx_polarity_flip_physical{177.0}=0x0 +phy_chain_tx_polarity_flip_physical{178.0}=0x1 +phy_chain_tx_polarity_flip_physical{179.0}=0x1 +phy_chain_tx_polarity_flip_physical{180.0}=0x0 +phy_chain_tx_polarity_flip_physical{181.0}=0x0 +phy_chain_tx_polarity_flip_physical{182.0}=0x0 +phy_chain_tx_polarity_flip_physical{183.0}=0x0 +phy_chain_tx_polarity_flip_physical{184.0}=0x0 +phy_chain_tx_polarity_flip_physical{185.0}=0x1 +phy_chain_tx_polarity_flip_physical{186.0}=0x0 +phy_chain_tx_polarity_flip_physical{187.0}=0x0 +phy_chain_tx_polarity_flip_physical{188.0}=0x1 +phy_chain_tx_polarity_flip_physical{189.0}=0x0 +phy_chain_tx_polarity_flip_physical{190.0}=0x1 +phy_chain_tx_polarity_flip_physical{191.0}=0x1 +phy_chain_tx_polarity_flip_physical{192.0}=0x0 +phy_chain_tx_polarity_flip_physical{193.0}=0x0 +phy_chain_tx_polarity_flip_physical{194.0}=0x1 +phy_chain_tx_polarity_flip_physical{195.0}=0x1 +phy_chain_tx_polarity_flip_physical{196.0}=0x0 +phy_chain_tx_polarity_flip_physical{197.0}=0x0 +phy_chain_tx_polarity_flip_physical{198.0}=0x0 +phy_chain_tx_polarity_flip_physical{199.0}=0x0 +phy_chain_tx_polarity_flip_physical{200.0}=0x0 +phy_chain_tx_polarity_flip_physical{201.0}=0x1 +phy_chain_tx_polarity_flip_physical{202.0}=0x0 +phy_chain_tx_polarity_flip_physical{203.0}=0x0 +phy_chain_tx_polarity_flip_physical{204.0}=0x1 +phy_chain_tx_polarity_flip_physical{205.0}=0x0 +phy_chain_tx_polarity_flip_physical{206.0}=0x1 +phy_chain_tx_polarity_flip_physical{207.0}=0x1 +phy_chain_tx_polarity_flip_physical{208.0}=0x0 +phy_chain_tx_polarity_flip_physical{209.0}=0x0 +phy_chain_tx_polarity_flip_physical{210.0}=0x1 +phy_chain_tx_polarity_flip_physical{211.0}=0x1 +phy_chain_tx_polarity_flip_physical{212.0}=0x0 +phy_chain_tx_polarity_flip_physical{213.0}=0x0 +phy_chain_tx_polarity_flip_physical{214.0}=0x0 +phy_chain_tx_polarity_flip_physical{215.0}=0x0 +phy_chain_tx_polarity_flip_physical{216.0}=0x0 +phy_chain_tx_polarity_flip_physical{217.0}=0x0 +phy_chain_tx_polarity_flip_physical{218.0}=0x1 +phy_chain_tx_polarity_flip_physical{219.0}=0x0 +phy_chain_tx_polarity_flip_physical{220.0}=0x1 +phy_chain_tx_polarity_flip_physical{221.0}=0x0 +phy_chain_tx_polarity_flip_physical{222.0}=0x1 +phy_chain_tx_polarity_flip_physical{223.0}=0x1 +phy_chain_tx_polarity_flip_physical{224.0}=0x0 +phy_chain_tx_polarity_flip_physical{225.0}=0x0 +phy_chain_tx_polarity_flip_physical{226.0}=0x1 +phy_chain_tx_polarity_flip_physical{227.0}=0x1 +phy_chain_tx_polarity_flip_physical{228.0}=0x0 +phy_chain_tx_polarity_flip_physical{229.0}=0x0 +phy_chain_tx_polarity_flip_physical{230.0}=0x1 +phy_chain_tx_polarity_flip_physical{231.0}=0x1 +phy_chain_tx_polarity_flip_physical{232.0}=0x0 +phy_chain_tx_polarity_flip_physical{233.0}=0x0 +phy_chain_tx_polarity_flip_physical{234.0}=0x1 +phy_chain_tx_polarity_flip_physical{235.0}=0x1 +phy_chain_tx_polarity_flip_physical{236.0}=0x0 +phy_chain_tx_polarity_flip_physical{237.0}=0x1 +phy_chain_tx_polarity_flip_physical{238.0}=0x1 +phy_chain_tx_polarity_flip_physical{239.0}=0x0 +phy_chain_tx_polarity_flip_physical{240.0}=0x0 +phy_chain_tx_polarity_flip_physical{241.0}=0x0 +phy_chain_tx_polarity_flip_physical{242.0}=0x1 +phy_chain_tx_polarity_flip_physical{243.0}=0x1 +phy_chain_tx_polarity_flip_physical{244.0}=0x0 +phy_chain_tx_polarity_flip_physical{245.0}=0x0 +phy_chain_tx_polarity_flip_physical{246.0}=0x0 +phy_chain_tx_polarity_flip_physical{247.0}=0x1 +phy_chain_tx_polarity_flip_physical{248.0}=0x1 +phy_chain_tx_polarity_flip_physical{249.0}=0x1 +phy_chain_tx_polarity_flip_physical{250.0}=0x1 +phy_chain_tx_polarity_flip_physical{251.0}=0x0 +phy_chain_tx_polarity_flip_physical{252.0}=0x0 +phy_chain_tx_polarity_flip_physical{253.0}=0x0 +phy_chain_tx_polarity_flip_physical{254.0}=0x0 +phy_chain_tx_polarity_flip_physical{255.0}=0x1 +phy_chain_tx_polarity_flip_physical{256.0}=0x1 +phy_chain_tx_polarity_flip_physical{257.0}=0x0 +phy_chain_tx_polarity_flip_physical{258.0}=0x0 +portmap_1.0=1:400 +portmap_2.0=9:400 +portmap_3.0=17:400 +portmap_4.0=25:400 +portmap_20.0=33:400 +portmap_21.0=41:400 +portmap_22.0=49:400 +portmap_23.0=57:400 +portmap_38.0=257:10 +portmap_40.0=65:400 +portmap_41.0=73:400 +portmap_42.0=81:400 +portmap_43.0=89:400 +portmap_60.0=97:400 +portmap_61.0=105:400 +portmap_62.0=113:400 +portmap_63.0=121:400 +portmap_80.0=129:400 +portmap_81.0=137:400 +portmap_82.0=145:400 +portmap_83.0=153:400 +portmap_100.0=161:400 +portmap_101.0=169:400 +portmap_102.0=177:400 +portmap_103.0=185:400 +portmap_118.0=258:10 +portmap_120.0=193:400 +portmap_121.0=201:400 +portmap_122.0=209:400 +portmap_123.0=217:400 +portmap_140.0=225:400 +portmap_141.0=233:400 +portmap_142.0=241:400 +portmap_143.0=249:400 +port_init_autoneg_1.0=0 +port_init_autoneg_2.0=0 +port_init_autoneg_3.0=0 +port_init_autoneg_4.0=0 +port_init_autoneg_20.0=0 +port_init_autoneg_21.0=0 +port_init_autoneg_22.0=0 +port_init_autoneg_23.0=0 +port_init_autoneg_38.0=0 +port_init_autoneg_40.0=0 +port_init_autoneg_41.0=0 +port_init_autoneg_42.0=0 +port_init_autoneg_43.0=0 +port_init_autoneg_60.0=0 +port_init_autoneg_61.0=0 +port_init_autoneg_62.0=0 +port_init_autoneg_63.0=0 +port_init_autoneg_80.0=0 +port_init_autoneg_81.0=0 +port_init_autoneg_82.0=0 +port_init_autoneg_83.0=0 +port_init_autoneg_100.0=0 +port_init_autoneg_101.0=0 +port_init_autoneg_102.0=0 +port_init_autoneg_103.0=0 +port_init_autoneg_118.0=0 +port_init_autoneg_120.0=0 +port_init_autoneg_121.0=0 +port_init_autoneg_122.0=0 +port_init_autoneg_123.0=0 +port_init_autoneg_140.0=0 +port_init_autoneg_141.0=0 +port_init_autoneg_142.0=0 +port_init_autoneg_143.0=0 +port_phy_addr_1.0=0xff +port_phy_addr_2.0=0xff +port_phy_addr_3.0=0xff +port_phy_addr_4.0=0xff +port_phy_addr_20.0=0xff +port_phy_addr_21.0=0xff +port_phy_addr_22.0=0xff +port_phy_addr_23.0=0xff +port_phy_addr_38.0=0xff +port_phy_addr_40.0=0xff +port_phy_addr_41.0=0xff +port_phy_addr_42.0=0xff +port_phy_addr_43.0=0xff +port_phy_addr_60.0=0xff +port_phy_addr_61.0=0xff +port_phy_addr_62.0=0xff +port_phy_addr_63.0=0xff +port_phy_addr_80.0=0xff +port_phy_addr_81.0=0xff +port_phy_addr_82.0=0xff +port_phy_addr_83.0=0xff +port_phy_addr_100.0=0xff +port_phy_addr_101.0=0xff +port_phy_addr_102.0=0xff +port_phy_addr_103.0=0xff +port_phy_addr_118.0=0xff +port_phy_addr_120.0=0xff +port_phy_addr_121.0=0xff +port_phy_addr_122.0=0xff +port_phy_addr_123.0=0xff +port_phy_addr_140.0=0xff +port_phy_addr_141.0=0xff +port_phy_addr_142.0=0xff +port_phy_addr_143.0=0xff +robust_hash_disable_egress_vlan.0=1 +robust_hash_disable_mpls.0=1 +robust_hash_disable_vlan.0=1 +tdma_timeout_usec.0=15000000 +tslam_timeout_usec.0=15000000 + +# Tuning +serdes_core_rx_polarity_flip_physical{1}=0x96 +serdes_core_rx_polarity_flip_physical{9}=0x69 +serdes_core_rx_polarity_flip_physical{17}=0x93 +serdes_core_rx_polarity_flip_physical{25}=0xd3 +serdes_core_rx_polarity_flip_physical{33}=0xcc +serdes_core_rx_polarity_flip_physical{41}=0xc3 +serdes_core_rx_polarity_flip_physical{49}=0x99 +serdes_core_rx_polarity_flip_physical{57}=0xc3 +serdes_core_rx_polarity_flip_physical{65}=0xcc +serdes_core_rx_polarity_flip_physical{73}=0xd2 +serdes_core_rx_polarity_flip_physical{81}=0xcc +serdes_core_rx_polarity_flip_physical{89}=0xd2 +serdes_core_rx_polarity_flip_physical{97}=0xc3 +serdes_core_rx_polarity_flip_physical{105}=0xd2 +serdes_core_rx_polarity_flip_physical{113}=0x66 +serdes_core_rx_polarity_flip_physical{121}=0xf0 +serdes_core_rx_polarity_flip_physical{129}=0x99 +serdes_core_rx_polarity_flip_physical{137}=0xc3 +serdes_core_rx_polarity_flip_physical{145}=0xcc +serdes_core_rx_polarity_flip_physical{153}=0x99 +serdes_core_rx_polarity_flip_physical{161}=0xd2 +serdes_core_rx_polarity_flip_physical{169}=0xc3 +serdes_core_rx_polarity_flip_physical{177}=0x8d +serdes_core_rx_polarity_flip_physical{185}=0xc3 +serdes_core_rx_polarity_flip_physical{193}=0x8d +serdes_core_rx_polarity_flip_physical{201}=0xc3 +serdes_core_rx_polarity_flip_physical{209}=0xcc +serdes_core_rx_polarity_flip_physical{217}=0xc3 +serdes_core_rx_polarity_flip_physical{225}=0x66 +serdes_core_rx_polarity_flip_physical{233}=0xf +serdes_core_rx_polarity_flip_physical{241}=0x69 +serdes_core_rx_polarity_flip_physical{249}=0x9a +serdes_core_rx_polarity_flip_physical{257}=0x0 +serdes_core_tx_polarity_flip_physical{1}=0xac +serdes_core_tx_polarity_flip_physical{9}=0xa9 +serdes_core_tx_polarity_flip_physical{17}=0x99 +serdes_core_tx_polarity_flip_physical{25}=0xc9 +serdes_core_tx_polarity_flip_physical{33}=0x4e +serdes_core_tx_polarity_flip_physical{41}=0x39 +serdes_core_tx_polarity_flip_physical{49}=0xd1 +serdes_core_tx_polarity_flip_physical{57}=0xb1 +serdes_core_tx_polarity_flip_physical{65}=0xf0 +serdes_core_tx_polarity_flip_physical{73}=0xb1 +serdes_core_tx_polarity_flip_physical{81}=0xf0 +serdes_core_tx_polarity_flip_physical{89}=0xb1 +serdes_core_tx_polarity_flip_physical{97}=0x6e +serdes_core_tx_polarity_flip_physical{105}=0xd8 +serdes_core_tx_polarity_flip_physical{113}=0xac +serdes_core_tx_polarity_flip_physical{121}=0x6c +serdes_core_tx_polarity_flip_physical{129}=0xac +serdes_core_tx_polarity_flip_physical{137}=0x6c +serdes_core_tx_polarity_flip_physical{145}=0xac +serdes_core_tx_polarity_flip_physical{153}=0xe9 +serdes_core_tx_polarity_flip_physical{161}=0xa9 +serdes_core_tx_polarity_flip_physical{169}=0xc9 +serdes_core_tx_polarity_flip_physical{177}=0xa9 +serdes_core_tx_polarity_flip_physical{185}=0xc9 +serdes_core_tx_polarity_flip_physical{193}=0xa9 +serdes_core_tx_polarity_flip_physical{201}=0xc9 +serdes_core_tx_polarity_flip_physical{209}=0xa9 +serdes_core_tx_polarity_flip_physical{217}=0xe1 +serdes_core_tx_polarity_flip_physical{225}=0x69 +serdes_core_tx_polarity_flip_physical{233}=0x66 +serdes_core_tx_polarity_flip_physical{241}=0xe1 +serdes_core_tx_polarity_flip_physical{249}=0xc6 +serdes_core_tx_polarity_flip_physical{257}=0x0 +serdes_tx_taps_cd0=pam4:-28:124:-12:4:0:0 +serdes_tx_taps_cd1=pam4:-28:124:-12:4:0:0 +serdes_tx_taps_cd2=pam4:-28:124:-12:4:0:0 +serdes_tx_taps_cd3=pam4:-28:120:-4:4:0:0 +serdes_tx_taps_cd4=pam4:-28:120:-4:4:0:0 +serdes_tx_taps_cd5=pam4:-28:120:-4:4:0:0 +serdes_tx_taps_cd6=pam4:-28:120:-4:4:0:0 +serdes_tx_taps_cd7=pam4:-28:120:-4:4:0:0 +serdes_tx_taps_cd8=pam4:-28:120:-4:4:0:0 +serdes_tx_taps_cd9=pam4:-28:120:-4:4:0:0 +serdes_tx_taps_cd10=pam4:-28:124:0:4:0:0 +serdes_tx_taps_cd11=pam4:-28:124:0:4:0:0 +serdes_tx_taps_cd12=pam4:-28:124:0:4:0:0 +serdes_tx_taps_cd13=pam4:-28:124:0:4:0:0 +serdes_tx_taps_cd14=pam4:-28:124:0:4:0:0 +serdes_tx_taps_cd15=pam4:-28:124:0:4:0:0 +serdes_tx_taps_cd16=pam4:-28:124:0:4:0:0 +serdes_tx_taps_cd17=pam4:-28:124:0:4:0:0 +serdes_tx_taps_cd18=pam4:-28:124:0:4:0:0 +serdes_tx_taps_cd19=pam4:-28:124:0:4:0:0 +serdes_tx_taps_cd20=pam4:-28:124:0:4:0:0 +serdes_tx_taps_cd21=pam4:-28:124:0:4:0:0 +serdes_tx_taps_cd22=pam4:-28:120:-4:4:0:0 +serdes_tx_taps_cd23=pam4:-28:120:-4:4:0:0 +serdes_tx_taps_cd24=pam4:-28:120:-4:4:0:0 +serdes_tx_taps_cd25=pam4:-28:120:-4:4:0:0 +serdes_tx_taps_cd26=pam4:-28:120:-4:4:0:0 +serdes_tx_taps_cd27=pam4:-28:120:-4:4:0:0 +serdes_tx_taps_cd28=pam4:-28:120:-4:4:0:0 +serdes_tx_taps_cd29=pam4:-28:124:-12:4:0:0 +serdes_tx_taps_cd30=pam4:-28:124:-12:4:0:0 +serdes_tx_taps_cd31=pam4:-28:124:-12:4:0:0 +serdes_tx_taps_cd32=pam4:1:34:9:0:0:0 +serdes_tx_taps_cd33=pam4:1:34:9:0:0:0 diff --git a/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-C64/sai.profile b/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-C64/sai.profile index 8f820cb0f066..9d051624c589 100644 --- a/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-C64/sai.profile +++ b/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-C64/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-a7060px4-32-64x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-C64/th3-a7060px4-32-64x100G.config.bcm b/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-C64/th3-a7060px4-32-64x100G.config.bcm index 5002d29045ab..52e3424aaf55 100644 --- a/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-C64/th3-a7060px4-32-64x100G.config.bcm +++ b/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-C64/th3-a7060px4-32-64x100G.config.bcm @@ -1,14 +1,12 @@ -PHY_AN_ALLOW_PLL_CHANGE=1 arl_clean_timeout_usec=15000000 asf_mem_profile.0=2 bcm_num_cos.0=8 bcm_stat_flags=1 bcm_stat_jumbo.0=9236 cdma_timeout_usec.0=15000000 +disable_pcie_firmware_check.0=1 dma_desc_timeout_usec.0=15000000 dpr_clock_frequency.0=1000 -higig2_hdr_mode.0=1 -ipv6_lpm_128b_enable.0=0 l2xmsg_mode.0=1 l2_mem_entries.0=8192 l3_alpm_enable.0=2 @@ -17,10 +15,10 @@ max_vp_lags.0=0 miim_intr_enable.0=0 module_64ports.0=1 multicast_l2_range.0=511 -num_ipv6_lpm_128b_entries.0=0 -os=unix oversubscribe_mode=1 -pbmp_xport_xe.0=0xf0000f4000f0000f0000f0000f4000f0001e +parity_correction=1 +parity_enable=1 +pbmp_xport_xe.0=0x3ffffffffffffffffffffffffffffffffffffffe phy_an_c37_38.0=2 phy_an_c37_118.0=2 phy_an_c37_1.0=1 @@ -872,7 +870,6 @@ port_phy_addr_147.0=0xff robust_hash_disable_egress_vlan.0=1 robust_hash_disable_mpls.0=1 robust_hash_disable_vlan.0=1 -sram_scan_enable.0=0 tdma_timeout_usec.0=15000000 tslam_timeout_usec.0=15000000 diff --git a/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-O32/sai.profile b/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-O32/sai.profile index 2163c4be9057..c9a6b4d330ce 100644 --- a/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-O32/sai.profile +++ b/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-O32/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-a7060px4-o32-32x400G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-O32/th3-a7060px4-o32-32x400G.config.bcm b/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-O32/th3-a7060px4-o32-32x400G.config.bcm index d3a66dee635f..0cf9ae8f3a65 100644 --- a/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-O32/th3-a7060px4-o32-32x400G.config.bcm +++ b/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-O32/th3-a7060px4-o32-32x400G.config.bcm @@ -1,14 +1,12 @@ -PHY_AN_ALLOW_PLL_CHANGE=1 arl_clean_timeout_usec=15000000 asf_mem_profile.0=2 bcm_num_cos.0=8 bcm_stat_flags=1 bcm_stat_jumbo.0=9236 cdma_timeout_usec.0=15000000 +disable_pcie_firmware_check.0=1 dma_desc_timeout_usec.0=15000000 dpr_clock_frequency.0=1000 -higig2_hdr_mode.0=1 -ipv6_lpm_128b_enable.0=0 l2xmsg_mode.0=1 l2_mem_entries.0=8192 l3_alpm_enable.0=2 @@ -17,10 +15,10 @@ max_vp_lags.0=0 miim_intr_enable.0=0 module_64ports.0=1 multicast_l2_range.0=511 -num_ipv6_lpm_128b_entries.0=0 -os=unix oversubscribe_mode=1 -pbmp_xport_xe.0=0xf0000f4000f0000f0000f0000f4000f0001e +parity_correction=1 +parity_enable=1 +pbmp_xport_xe.0=0x3ffffffffffffffffffffffffffffffffffffffe phy_an_c37_38.0=2 phy_an_c37_118.0=2 phy_an_c73_1.0=1 @@ -744,7 +742,6 @@ port_phy_addr_143.0=0xff robust_hash_disable_egress_vlan.0=1 robust_hash_disable_mpls.0=1 robust_hash_disable_vlan.0=1 -sram_scan_enable.0=0 tdma_timeout_usec.0=15000000 tslam_timeout_usec.0=15000000 diff --git a/device/arista/x86_64-arista_7060px4_32/platform.json b/device/arista/x86_64-arista_7060px4_32/platform.json new file mode 100644 index 000000000000..b486b9152c06 --- /dev/null +++ b/device/arista/x86_64-arista_7060px4_32/platform.json @@ -0,0 +1,223 @@ +{ + "chassis": { + "name": "DCS-7060PX4-32", + "components": [], + "fans": [], + "fan_drawers": [ + { + "name": "slot1", + "fans": [ + { + "name": "fan1" + } + ] + }, + { + "name": "slot2", + "fans": [ + { + "name": "fan2" + } + ] + }, + { + "name": "slot3", + "fans": [ + { + "name": "fan3" + } + ] + }, + { + "name": "slot4", + "fans": [ + { + "name": "fan4" + } + ] + }, + { + "name": "slot5", + "fans": [ + { + "name": "fan5" + } + ] + } + ], + "psus": [ + { + "name": "psu1", + "fans": [] + }, + { + "name": "psu2", + "fans": [] + } + ], + "thermals": [ + { + "name": "Board sensor" + }, + { + "name": "Switch board middle sensor" + }, + { + "name": "Switch board left sensor" + }, + { + "name": "Front-panel temp sensor" + }, + { + "name": "Switch chip diode 1 sensor" + }, + { + "name": "Switch chip diode 2 sensor" + }, + { + "name": "PCH temp sensor" + }, + { + "name": "Physical id 0" + }, + { + "name": "CPU core0 temp sensor" + }, + { + "name": "CPU core1 temp sensor" + }, + { + "name": "CPU board temp sensor" + }, + { + "name": "Back-panel temp sensor" + }, + { + "name": "Front-panel temp sensor" + }, + { + "name": "Power supply 1 hotspot sensor" + }, + { + "name": "Power supply 1 inlet temp sensor" + }, + { + "name": "Power supply 1 exhaust temp sensor" + }, + { + "name": "Power supply 2 hotspot sensor" + }, + { + "name": "Power supply 2 inlet temp sensor" + }, + { + "name": "Power supply 2 exhaust temp sensor" + } + ], + "sfps": [ + { + "name": "osfp1" + }, + { + "name": "osfp2" + }, + { + "name": "osfp3" + }, + { + "name": "osfp4" + }, + { + "name": "osfp5" + }, + { + "name": "osfp6" + }, + { + "name": "osfp7" + }, + { + "name": "osfp8" + }, + { + "name": "osfp9" + }, + { + "name": "osfp10" + }, + { + "name": "osfp11" + }, + { + "name": "osfp12" + }, + { + "name": "osfp13" + }, + { + "name": "osfp14" + }, + { + "name": "osfp15" + }, + { + "name": "osfp16" + }, + { + "name": "osfp17" + }, + { + "name": "osfp18" + }, + { + "name": "osfp19" + }, + { + "name": "osfp20" + }, + { + "name": "osfp21" + }, + { + "name": "osfp22" + }, + { + "name": "osfp23" + }, + { + "name": "osfp24" + }, + { + "name": "osfp25" + }, + { + "name": "osfp26" + }, + { + "name": "osfp27" + }, + { + "name": "osfp28" + }, + { + "name": "osfp29" + }, + { + "name": "osfp30" + }, + { + "name": "osfp31" + }, + { + "name": "osfp32" + }, + { + "name": "sfp33" + }, + { + "name": "sfp34" + } + ] + }, + "interfaces": {} +} \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060px4_32/pmon_daemon_control.json b/device/arista/x86_64-arista_7060px4_32/pmon_daemon_control.json new file mode 120000 index 000000000000..51d5ab7b0059 --- /dev/null +++ b/device/arista/x86_64-arista_7060px4_32/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060px4_32/system_health_monitoring_config.json b/device/arista/x86_64-arista_7060px4_32/system_health_monitoring_config.json new file mode 120000 index 000000000000..1185f771fa8e --- /dev/null +++ b/device/arista/x86_64-arista_7060px4_32/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-arista_common/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060px4_32/thermal_policy.json b/device/arista/x86_64-arista_7060px4_32/thermal_policy.json new file mode 120000 index 000000000000..0991dc7f3638 --- /dev/null +++ b/device/arista/x86_64-arista_7060px4_32/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-arista_common/thermal_policy.json \ 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_7050cx3_32s/plugins b/device/arista/x86_64-arista_7170_32c/plugins similarity index 100% rename from device/arista/x86_64-arista_7050cx3_32s/plugins rename to device/arista/x86_64-arista_7170_32c/plugins diff --git a/device/arista/x86_64-arista_7170_32c/pmon_daemon_control.json b/device/arista/x86_64-arista_7170_32c/pmon_daemon_control.json new file mode 120000 index 000000000000..51d5ab7b0059 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32c/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control.json \ 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_32c/system_health_monitoring_config.json b/device/arista/x86_64-arista_7170_32c/system_health_monitoring_config.json new file mode 120000 index 000000000000..1185f771fa8e --- /dev/null +++ b/device/arista/x86_64-arista_7170_32c/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-arista_common/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_32c/thermal_policy.json b/device/arista/x86_64-arista_7170_32c/thermal_policy.json new file mode 120000 index 000000000000..0991dc7f3638 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32c/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-arista_common/thermal_policy.json \ 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/pmon_daemon_control.json b/device/arista/x86_64-arista_7170_32cd/pmon_daemon_control.json new file mode 120000 index 000000000000..51d5ab7b0059 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32cd/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control.json \ 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/device/arista/x86_64-arista_7170_32cd/system_health_monitoring_config.json b/device/arista/x86_64-arista_7170_32cd/system_health_monitoring_config.json new file mode 120000 index 000000000000..1185f771fa8e --- /dev/null +++ b/device/arista/x86_64-arista_7170_32cd/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-arista_common/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_32cd/thermal_policy.json b/device/arista/x86_64-arista_7170_32cd/thermal_policy.json new file mode 120000 index 000000000000..0991dc7f3638 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32cd/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-arista_common/thermal_policy.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_64c/platform.json b/device/arista/x86_64-arista_7170_64c/platform.json new file mode 100644 index 000000000000..d9207b1ba9cc --- /dev/null +++ b/device/arista/x86_64-arista_7170_64c/platform.json @@ -0,0 +1,299 @@ +{ + "chassis": { + "name": "DCS-7170-64C", + "components": [], + "fans": [], + "fan_drawers": [ + { + "name": "slot1", + "fans": [ + { + "name": "fan1" + } + ] + }, + { + "name": "slot2", + "fans": [ + { + "name": "fan2" + } + ] + }, + { + "name": "slot3", + "fans": [ + { + "name": "fan3" + } + ] + }, + { + "name": "slot4", + "fans": [ + { + "name": "fan4" + } + ] + } + ], + "psus": [ + { + "name": "psu1", + "fans": [] + }, + { + "name": "psu2", + "fans": [] + } + ], + "thermals": [ + { + "name": "Board sensor" + }, + { + "name": "Switch Chip sensor" + }, + { + "name": "PCH temp sensor" + }, + { + "name": "Physical id 0" + }, + { + "name": "CPU core0 temp sensor" + }, + { + "name": "CPU core1 temp sensor" + }, + { + "name": "CPU board temp sensor" + }, + { + "name": "Back-panel temp sensor" + }, + { + "name": "Front-panel temp sensor" + }, + { + "name": "Power supply 1 hotspot sensor" + }, + { + "name": "Power supply 1 inlet temp sensor" + }, + { + "name": "Power supply 1 exhaust temp sensor" + }, + { + "name": "Power supply 2 hotspot sensor" + }, + { + "name": "Power supply 2 inlet temp sensor" + }, + { + "name": "Power supply 2 exhaust temp sensor" + } + ], + "sfps": [ + { + "name": "qsfp1" + }, + { + "name": "qsfp2" + }, + { + "name": "qsfp3" + }, + { + "name": "qsfp4" + }, + { + "name": "qsfp5" + }, + { + "name": "qsfp6" + }, + { + "name": "qsfp7" + }, + { + "name": "qsfp8" + }, + { + "name": "qsfp9" + }, + { + "name": "qsfp10" + }, + { + "name": "qsfp11" + }, + { + "name": "qsfp12" + }, + { + "name": "qsfp13" + }, + { + "name": "qsfp14" + }, + { + "name": "qsfp15" + }, + { + "name": "qsfp16" + }, + { + "name": "qsfp17" + }, + { + "name": "qsfp18" + }, + { + "name": "qsfp19" + }, + { + "name": "qsfp20" + }, + { + "name": "qsfp21" + }, + { + "name": "qsfp22" + }, + { + "name": "qsfp23" + }, + { + "name": "qsfp24" + }, + { + "name": "qsfp25" + }, + { + "name": "qsfp26" + }, + { + "name": "qsfp27" + }, + { + "name": "qsfp28" + }, + { + "name": "qsfp29" + }, + { + "name": "qsfp30" + }, + { + "name": "qsfp31" + }, + { + "name": "qsfp32" + }, + { + "name": "qsfp33" + }, + { + "name": "qsfp34" + }, + { + "name": "qsfp35" + }, + { + "name": "qsfp36" + }, + { + "name": "qsfp37" + }, + { + "name": "qsfp38" + }, + { + "name": "qsfp39" + }, + { + "name": "qsfp40" + }, + { + "name": "qsfp41" + }, + { + "name": "qsfp42" + }, + { + "name": "qsfp43" + }, + { + "name": "qsfp44" + }, + { + "name": "qsfp45" + }, + { + "name": "qsfp46" + }, + { + "name": "qsfp47" + }, + { + "name": "qsfp48" + }, + { + "name": "qsfp49" + }, + { + "name": "qsfp50" + }, + { + "name": "qsfp51" + }, + { + "name": "qsfp52" + }, + { + "name": "qsfp53" + }, + { + "name": "qsfp54" + }, + { + "name": "qsfp55" + }, + { + "name": "qsfp56" + }, + { + "name": "qsfp57" + }, + { + "name": "qsfp58" + }, + { + "name": "qsfp59" + }, + { + "name": "qsfp60" + }, + { + "name": "qsfp61" + }, + { + "name": "qsfp62" + }, + { + "name": "qsfp63" + }, + { + "name": "qsfp64" + }, + { + "name": "sfp65" + }, + { + "name": "sfp66" + } + ] + }, + "interfaces": {} +} \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_64c/pmon_daemon_control.json b/device/arista/x86_64-arista_7170_64c/pmon_daemon_control.json new file mode 120000 index 000000000000..51d5ab7b0059 --- /dev/null +++ b/device/arista/x86_64-arista_7170_64c/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_64c/sensors.conf b/device/arista/x86_64-arista_7170_64c/sensors.conf index 732cb92a96ef..5b1e592cbe21 100644 --- a/device/arista/x86_64-arista_7170_64c/sensors.conf +++ b/device/arista/x86_64-arista_7170_64c/sensors.conf @@ -20,7 +20,7 @@ chip "max6658-i2c-8-4c" set temp2_min -55 ignore temp2 -chip "dps1900-i2c-6-58" +chip "pmbus-i2c-6-58" label temp1 "PSU1 primary hotspot temp" label temp2 "PSU1 inlet temp" label temp3 "PSU1 exhaust temp" @@ -31,7 +31,7 @@ chip "dps1900-i2c-6-58" ignore fan2 ignore fan3 -chip "dps1900-i2c-7-58" +chip "pmbus-i2c-7-58" label temp1 "PSU2 primary hotspot temp" label temp2 "PSU2 inlet temp" label temp3 "PSU2 exhaust temp" diff --git a/device/arista/x86_64-arista_7170_64c/system_health_monitoring_config.json b/device/arista/x86_64-arista_7170_64c/system_health_monitoring_config.json new file mode 120000 index 000000000000..1185f771fa8e --- /dev/null +++ b/device/arista/x86_64-arista_7170_64c/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-arista_common/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_64c/thermal_policy.json b/device/arista/x86_64-arista_7170_64c/thermal_policy.json new file mode 120000 index 000000000000..0991dc7f3638 --- /dev/null +++ b/device/arista/x86_64-arista_7170_64c/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-arista_common/thermal_policy.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-C64/sai.profile b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-C64/sai.profile index 74aea949c3b7..2607bef50850 100644 --- a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-C64/sai.profile +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-C64/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-a7260cx3-64-64x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-C64/th2-a7260cx3-64-64x100G.config.bcm b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-C64/th2-a7260cx3-64-64x100G.config.bcm index 44fb6f7536b4..13fdd280e857 100644 --- a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-C64/th2-a7260cx3-64-64x100G.config.bcm +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-C64/th2-a7260cx3-64-64x100G.config.bcm @@ -1,7 +1,7 @@ PHY_AN_ALLOW_PLL_CHANGE=1 arl_clean_timeout_usec=15000000 asf_mem_profile=2 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_flags=1 bcm_stat_jumbo=9236 cdma_timeout_usec=15000000 diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/sai.profile b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/sai.profile index 235f2423df82..166f5c5b6e1a 100644 --- a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/sai.profile +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-a7260cx3-64-112x50G+8x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/th2-a7260cx3-64-112x50G+8x100G.config.bcm b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/th2-a7260cx3-64-112x50G+8x100G.config.bcm index 3c2a343bf04d..6e4c266b1db4 100644 --- a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/th2-a7260cx3-64-112x50G+8x100G.config.bcm +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/th2-a7260cx3-64-112x50G+8x100G.config.bcm @@ -1,7 +1,7 @@ PHY_AN_ALLOW_PLL_CHANGE=1 arl_clean_timeout_usec=15000000 asf_mem_profile=2 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_flags=1 bcm_stat_jumbo=9236 cdma_timeout_usec=15000000 diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/sai.profile b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/sai.profile index db64a26b47da..a89cba46c3d1 100644 --- a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/sai.profile +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-a7260cx3-64-64x40G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/th2-a7260cx3-64-64x40G.config.bcm b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/th2-a7260cx3-64-64x40G.config.bcm index f5ac5e37ef7e..e26a8131efdb 100644 --- a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/th2-a7260cx3-64-64x40G.config.bcm +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/th2-a7260cx3-64-64x40G.config.bcm @@ -1,7 +1,7 @@ PHY_AN_ALLOW_PLL_CHANGE=1 arl_clean_timeout_usec=15000000 asf_mem_profile=2 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_flags=1 bcm_stat_jumbo=9236 cdma_timeout_usec=15000000 diff --git a/device/arista/x86_64-arista_7260cx3_64/platform.json b/device/arista/x86_64-arista_7260cx3_64/platform.json new file mode 100644 index 000000000000..d489bd9506c9 --- /dev/null +++ b/device/arista/x86_64-arista_7260cx3_64/platform.json @@ -0,0 +1,296 @@ +{ + "chassis": { + "name": "DCS-7260CX3-64", + "components": [], + "fans": [], + "fan_drawers": [ + { + "name": "slot1", + "fans": [ + { + "name": "fan1" + } + ] + }, + { + "name": "slot2", + "fans": [ + { + "name": "fan2" + } + ] + }, + { + "name": "slot3", + "fans": [ + { + "name": "fan3" + } + ] + }, + { + "name": "slot4", + "fans": [ + { + "name": "fan4" + } + ] + } + ], + "psus": [ + { + "name": "psu1", + "fans": [] + }, + { + "name": "psu2", + "fans": [] + } + ], + "thermals": [ + { + "name": "Board sensor" + }, + { + "name": "PCH temp sensor" + }, + { + "name": "Physical id 0" + }, + { + "name": "CPU core0 temp sensor" + }, + { + "name": "CPU core1 temp sensor" + }, + { + "name": "CPU board temp sensor" + }, + { + "name": "Back-panel temp sensor" + }, + { + "name": "Front-panel temp sensor" + }, + { + "name": "Power supply 1 hotspot sensor" + }, + { + "name": "Power supply 1 inlet temp sensor" + }, + { + "name": "Power supply 1 exhaust temp sensor" + }, + { + "name": "Power supply 2 hotspot sensor" + }, + { + "name": "Power supply 2 inlet temp sensor" + }, + { + "name": "Power supply 2 exhaust temp sensor" + } + ], + "sfps": [ + { + "name": "qsfp1" + }, + { + "name": "qsfp2" + }, + { + "name": "qsfp3" + }, + { + "name": "qsfp4" + }, + { + "name": "qsfp5" + }, + { + "name": "qsfp6" + }, + { + "name": "qsfp7" + }, + { + "name": "qsfp8" + }, + { + "name": "qsfp9" + }, + { + "name": "qsfp10" + }, + { + "name": "qsfp11" + }, + { + "name": "qsfp12" + }, + { + "name": "qsfp13" + }, + { + "name": "qsfp14" + }, + { + "name": "qsfp15" + }, + { + "name": "qsfp16" + }, + { + "name": "qsfp17" + }, + { + "name": "qsfp18" + }, + { + "name": "qsfp19" + }, + { + "name": "qsfp20" + }, + { + "name": "qsfp21" + }, + { + "name": "qsfp22" + }, + { + "name": "qsfp23" + }, + { + "name": "qsfp24" + }, + { + "name": "qsfp25" + }, + { + "name": "qsfp26" + }, + { + "name": "qsfp27" + }, + { + "name": "qsfp28" + }, + { + "name": "qsfp29" + }, + { + "name": "qsfp30" + }, + { + "name": "qsfp31" + }, + { + "name": "qsfp32" + }, + { + "name": "qsfp33" + }, + { + "name": "qsfp34" + }, + { + "name": "qsfp35" + }, + { + "name": "qsfp36" + }, + { + "name": "qsfp37" + }, + { + "name": "qsfp38" + }, + { + "name": "qsfp39" + }, + { + "name": "qsfp40" + }, + { + "name": "qsfp41" + }, + { + "name": "qsfp42" + }, + { + "name": "qsfp43" + }, + { + "name": "qsfp44" + }, + { + "name": "qsfp45" + }, + { + "name": "qsfp46" + }, + { + "name": "qsfp47" + }, + { + "name": "qsfp48" + }, + { + "name": "qsfp49" + }, + { + "name": "qsfp50" + }, + { + "name": "qsfp51" + }, + { + "name": "qsfp52" + }, + { + "name": "qsfp53" + }, + { + "name": "qsfp54" + }, + { + "name": "qsfp55" + }, + { + "name": "qsfp56" + }, + { + "name": "qsfp57" + }, + { + "name": "qsfp58" + }, + { + "name": "qsfp59" + }, + { + "name": "qsfp60" + }, + { + "name": "qsfp61" + }, + { + "name": "qsfp62" + }, + { + "name": "qsfp63" + }, + { + "name": "qsfp64" + }, + { + "name": "sfp65" + }, + { + "name": "sfp66" + } + ] + }, + "interfaces": {} +} \ No newline at end of file diff --git a/device/arista/x86_64-arista_7260cx3_64/plugins/eeprom.py b/device/arista/x86_64-arista_7260cx3_64/plugins/eeprom.py new file mode 120000 index 000000000000..35cfaff3de4e --- /dev/null +++ b/device/arista/x86_64-arista_7260cx3_64/plugins/eeprom.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/eeprom.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7260cx3_64/plugins/led_control.py b/device/arista/x86_64-arista_7260cx3_64/plugins/led_control.py new file mode 120000 index 000000000000..8d733780117e --- /dev/null +++ b/device/arista/x86_64-arista_7260cx3_64/plugins/led_control.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/led_control.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7260cx3_64/plugins/pcie.yaml b/device/arista/x86_64-arista_7260cx3_64/plugins/pcie.yaml new file mode 100644 index 000000000000..a2540013703e --- /dev/null +++ b/device/arista/x86_64-arista_7260cx3_64/plugins/pcie.yaml @@ -0,0 +1,426 @@ +- bus: '00' + dev: '00' + fn: '0' + id: 6f00 + name: 'Host bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D DMI2 + (rev 03)' +- bus: '00' + dev: '01' + fn: '0' + id: 6f02 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 1 (rev 03)' +- bus: '00' + dev: '01' + fn: '1' + id: 6f03 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 1 (rev 03)' +- bus: '00' + dev: '02' + fn: '0' + id: 6f04 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 2 (rev 03)' +- bus: '00' + dev: '02' + fn: '2' + id: 6f06 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 2 (rev 03)' +- bus: '00' + dev: '03' + fn: '0' + id: 6f08 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 3 (rev 03)' +- bus: '00' + dev: '05' + fn: '0' + id: 6f28 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Map/VTd_Misc/System Management (rev 03)' +- bus: '00' + dev: '05' + fn: '1' + id: 6f29 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Hot Plug (rev 03)' +- bus: '00' + dev: '05' + fn: '2' + id: 6f2a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO RAS/Control Status/Global Errors (rev 03)' +- bus: '00' + dev: '05' + fn: '4' + id: 6f2c + name: 'PIC: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D I/O APIC (rev + 03)' +- bus: '00' + dev: '14' + fn: '0' + id: 8c31 + name: 'USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB + xHCI (rev 05)' +- bus: '00' + dev: 1c + fn: '0' + id: 8c10 + name: 'PCI bridge: Intel Corporation 8 Series/C220 Series Chipset Family PCI Express + Root Port #1 (rev d5)' +- bus: '00' + dev: 1c + fn: '4' + id: 8c18 + name: 'PCI bridge: Intel Corporation 8 Series/C220 Series Chipset Family PCI Express + Root Port #5 (rev d5)' +- bus: '00' + dev: 1f + fn: '0' + id: 8c54 + name: 'ISA bridge: Intel Corporation C224 Series Chipset Family Server Standard + SKU LPC Controller (rev 05)' +- bus: '00' + dev: 1f + fn: '2' + id: 8c02 + name: 'SATA controller: Intel Corporation 8 Series/C220 Series Chipset Family 6-port + SATA Controller 1 [AHCI mode] (rev 05)' +- bus: '00' + dev: 1f + fn: '3' + id: 8c22 + name: 'SMBus: Intel Corporation 8 Series/C220 Series Chipset Family SMBus Controller + (rev 05)' +- bus: '00' + dev: 1f + fn: '6' + id: 8c24 + name: 'Signal processing controller: Intel Corporation 8 Series Chipset Family Thermal + Management Controller (rev 05)' +- bus: '01' + dev: '00' + fn: '0' + id: '1682' + name: 'Ethernet controller: Broadcom Limited NetXtreme BCM57762 Gigabit Ethernet + PCIe (rev 20)' +- bus: '02' + dev: '00' + fn: '0' + id: '1682' + name: 'Ethernet controller: Broadcom Limited NetXtreme BCM57762 Gigabit Ethernet + PCIe (rev 20)' +- bus: '03' + dev: '00' + fn: '0' + id: 6f50 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 0' +- bus: '03' + dev: '00' + fn: '1' + id: 6f51 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 1' +- bus: '03' + dev: '00' + fn: '2' + id: 6f52 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 2' +- bus: '03' + dev: '00' + fn: '3' + id: 6f53 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 3' +- bus: '04' + dev: '00' + fn: '0' + id: 15a7 + name: 'Ethernet controller: Intel Corporation Device 15a7' +- bus: '04' + dev: '00' + fn: '1' + id: 15a7 + name: 'Ethernet controller: Intel Corporation Device 15a7' +- bus: '06' + dev: '00' + fn: '0' + id: '0001' + name: 'System peripheral: Arastra Inc. Device 0001 (rev 01)' +- bus: '07' + dev: '00' + fn: '0' + id: b971 + name: 'Ethernet controller: Broadcom Limited Device b971 (rev 11)' +- bus: '07' + dev: '00' + fn: '1' + id: b971 + name: 'Ethernet controller: Broadcom Limited Device b971 (rev 11)' +- bus: ff + dev: 0b + fn: '0' + id: 6f81 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '1' + id: 6f36 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '2' + id: 6f37 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '3' + id: '0001' + name: 'System peripheral: Arastra Inc. Device 0001 (rev 03)' +- bus: ff + dev: 0c + fn: '0' + id: 6fe0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0c + fn: '1' + id: 6fe1 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '0' + id: 6ff8 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '4' + id: 6ffc + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '5' + id: 6ffd + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '6' + id: 6ffe + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: '10' + fn: '0' + id: 6f1d + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R2PCIe Agent (rev 03)' +- bus: ff + dev: '10' + fn: '1' + id: 6f34 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R2PCIe Agent (rev 03)' +- bus: ff + dev: '10' + fn: '5' + id: 6f1e + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '10' + fn: '6' + id: 6f7d + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '10' + fn: '7' + id: 6f1f + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '12' + fn: '0' + id: 6fa0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Home Agent 0 (rev 03)' +- bus: ff + dev: '12' + fn: '1' + id: 6f30 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Home Agent 0 (rev 03)' +- bus: ff + dev: '13' + fn: '0' + id: 6fa8 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Target Address/Thermal/RAS (rev 03)' +- bus: ff + dev: '13' + fn: '1' + id: 6f71 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Target Address/Thermal/RAS (rev 03)' +- bus: ff + dev: '13' + fn: '2' + id: 6faa + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '3' + id: 6fab + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '4' + id: 6fac + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '5' + id: 6fad + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '6' + id: 6fae + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Broadcast (rev 03)' +- bus: ff + dev: '13' + fn: '7' + id: 6faf + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Global Broadcast (rev 03)' +- bus: ff + dev: '14' + fn: '0' + id: 6fb0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 0 Thermal Control (rev 03)' +- bus: ff + dev: '14' + fn: '1' + id: 6fb1 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 1 Thermal Control (rev 03)' +- bus: ff + dev: '14' + fn: '2' + id: 6fb2 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 0 Error (rev 03)' +- bus: ff + dev: '14' + fn: '3' + id: 6fb3 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 1 Error (rev 03)' +- bus: ff + dev: '14' + fn: '4' + id: 6fbc + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '5' + id: 6fbd + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '6' + id: 6fbe + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '7' + id: 6fbf + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '15' + fn: '0' + id: 6fb4 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 2 Thermal Control (rev 03)' +- bus: ff + dev: '15' + fn: '1' + id: 6fb5 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 3 Thermal Control (rev 03)' +- bus: ff + dev: '15' + fn: '2' + id: 6fb6 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 2 Error (rev 03)' +- bus: ff + dev: '15' + fn: '3' + id: 6fb7 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 3 Error (rev 03)' +- bus: ff + dev: 1e + fn: '0' + id: 6f98 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '1' + id: 6f99 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '2' + id: 6f9a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '3' + id: 6fc0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '4' + id: 6f9c + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1f + fn: '0' + id: 6f88 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1f + fn: '2' + id: 6f8a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' diff --git a/device/arista/x86_64-arista_7260cx3_64/plugins/psuutil.py b/device/arista/x86_64-arista_7260cx3_64/plugins/psuutil.py new file mode 120000 index 000000000000..2b0024ade969 --- /dev/null +++ b/device/arista/x86_64-arista_7260cx3_64/plugins/psuutil.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/psuutil.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7260cx3_64/plugins/sfputil.py b/device/arista/x86_64-arista_7260cx3_64/plugins/sfputil.py new file mode 120000 index 000000000000..c333e23763d7 --- /dev/null +++ b/device/arista/x86_64-arista_7260cx3_64/plugins/sfputil.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/sfputil.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7260cx3_64/pmon_daemon_control.json b/device/arista/x86_64-arista_7260cx3_64/pmon_daemon_control.json new file mode 120000 index 000000000000..51d5ab7b0059 --- /dev/null +++ b/device/arista/x86_64-arista_7260cx3_64/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7260cx3_64/system_health_monitoring_config.json b/device/arista/x86_64-arista_7260cx3_64/system_health_monitoring_config.json new file mode 120000 index 000000000000..1185f771fa8e --- /dev/null +++ b/device/arista/x86_64-arista_7260cx3_64/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-arista_common/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7260cx3_64/thermal_policy.json b/device/arista/x86_64-arista_7260cx3_64/thermal_policy.json new file mode 120000 index 000000000000..0991dc7f3638 --- /dev/null +++ b/device/arista/x86_64-arista_7260cx3_64/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-arista_common/thermal_policy.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7280cr3_32d4 b/device/arista/x86_64-arista_7280cr3_32d4 deleted file mode 120000 index d6e2ddbb64bd..000000000000 --- a/device/arista/x86_64-arista_7280cr3_32d4 +++ /dev/null @@ -1 +0,0 @@ -x86_64-arista_7280cr3_32p4 \ No newline at end of file diff --git a/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/jr2-a7280cr3-32d4-40x100G.config.bcm b/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/jr2-a7280cr3-32d4-40x100G.config.bcm new file mode 100644 index 000000000000..4467d5d033ce --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/jr2-a7280cr3-32d4-40x100G.config.bcm @@ -0,0 +1,769 @@ +soc_family.BCM8869X=BCM8869X + +custom_feature_ucode_path=u_code_db2pem.txt +system_headers_mode=1 +suppress_unknown_prop_warnings=1 +l4_protocols_load_balancing_enable=1 +fabric_logical_port_base=512 +trunk_group_max_members=128 +num_olp_tm_ports.BCM8869X=1 + +ucode_port_0.BCM8869X=CPU.0:core_0.0 +ucode_port_200.BCM8869X=CPU.8:core_1.200 +ucode_port_201.BCM8869X=CPU.16:core_0.201 +ucode_port_202.BCM8869X=CPU.24:core_1.202 +ucode_port_203.BCM8869X=CPU.32:core_0.203 + +port_init_speed_xe.BCM8869X=10000 +port_init_speed_xl.BCM8869X=40000 +port_init_speed_le.BCM8869X=50000 +port_init_speed_ce.BCM8869X=100000 +port_init_speed_cc.BCM8869X=200000 +port_init_speed_cd.BCM8869X=400000 +port_init_speed_il.BCM8869X=10312 + +port_init_cl72=0 + +serdes_tx_taps_1=pam4:-16:64:0:3:0:0 +serdes_tx_taps_2=pam4:-16:64:0:3:0:0 +serdes_tx_taps_3=pam4:-16:64:0:3:0:0 +serdes_tx_taps_4=pam4:-16:64:0:3:0:0 +serdes_tx_taps_5=pam4:-16:64:0:3:0:0 +serdes_tx_taps_6=pam4:-16:64:0:3:0:0 +serdes_tx_taps_7=pam4:-16:64:0:3:0:0 +serdes_tx_taps_8=pam4:-16:64:0:3:0:0 +serdes_tx_taps_9=pam4:-8:60:0:0:0:0 +serdes_tx_taps_10=pam4:-8:60:0:0:0:0 +serdes_tx_taps_11=pam4:-8:60:0:0:0:0 +serdes_tx_taps_12=pam4:-8:60:0:0:0:0 +serdes_tx_taps_13=pam4:-8:60:0:0:0:0 +serdes_tx_taps_14=pam4:-8:60:0:0:0:0 +serdes_tx_taps_15=pam4:-8:60:0:0:0:0 +serdes_tx_taps_16=pam4:-8:60:0:0:0:0 +serdes_tx_taps_17=pam4:-8:60:0:0:0:0 +serdes_tx_taps_18=pam4:-8:60:0:0:0:0 +serdes_tx_taps_19=pam4:-8:60:0:0:0:0 +serdes_tx_taps_20=pam4:-8:60:0:0:0:0 +serdes_tx_taps_21=pam4:-8:60:0:0:0:0 +serdes_tx_taps_22=pam4:-8:60:0:0:0:0 +serdes_tx_taps_23=pam4:-8:60:0:0:0:0 +serdes_tx_taps_24=pam4:-8:60:0:0:0:0 +serdes_tx_taps_25=pam4:-8:60:0:0:0:0 +serdes_tx_taps_26=pam4:-8:60:0:0:0:0 +serdes_tx_taps_27=pam4:-8:60:0:0:0:0 +serdes_tx_taps_28=pam4:-8:60:0:0:0:0 +serdes_tx_taps_29=pam4:-16:60:0:3:0:0 +serdes_tx_taps_30=pam4:-16:60:0:3:0:0 +serdes_tx_taps_31=pam4:-16:60:0:3:0:0 +serdes_tx_taps_32=pam4:-16:60:0:3:0:0 +serdes_tx_taps_33=nrz:0:71:-16:-5:0:0 +serdes_tx_taps_34=nrz:0:71:-16:-5:0:0 +serdes_tx_taps_35=nrz:0:78:-22:-4:0:0 +serdes_tx_taps_36=nrz:0:78:-22:-4:0:0 +serdes_tx_taps_37=nrz:0:72:-18:-5:0:0 +serdes_tx_taps_38=nrz:0:72:-18:-5:0:0 +serdes_tx_taps_39=nrz:0:68:-17:-6:0:0 +serdes_tx_taps_40=nrz:0:68:-17:-6:0:0 + +ucode_port_100.BCM8869X=RCY_MIRROR.0:core_0.100 +ucode_port_101.BCM8869X=RCY_MIRROR.1:core_0.101 +ucode_port_102.BCM8869X=RCY_MIRROR.2:core_0.102 +ucode_port_103.BCM8869X=RCY_MIRROR.3:core_0.103 +ucode_port_104.BCM8869X=RCY_MIRROR.4:core_0.104 +ucode_port_105.BCM8869X=RCY_MIRROR.5:core_0.105 +ucode_port_106.BCM8869X=RCY_MIRROR.6:core_0.106 +ucode_port_107.BCM8869X=RCY_MIRROR.7:core_0.107 +ucode_port_108.BCM8869X=RCY_MIRROR.8:core_0.108 +ucode_port_109.BCM8869X=RCY_MIRROR.9:core_0.109 +ucode_port_110.BCM8869X=RCY_MIRROR.10:core_0.110 +ucode_port_111.BCM8869X=RCY_MIRROR.11:core_0.111 +ucode_port_112.BCM8869X=RCY_MIRROR.12:core_0.112 +ucode_port_113.BCM8869X=RCY_MIRROR.13:core_0.113 +ucode_port_114.BCM8869X=RCY_MIRROR.14:core_0.114 +ucode_port_115.BCM8869X=RCY_MIRROR.15:core_0.115 +ucode_port_116.BCM8869X=RCY_MIRROR.16:core_0.116 +ucode_port_117.BCM8869X=RCY_MIRROR.17:core_0.117 +ucode_port_118.BCM8869X=RCY_MIRROR.18:core_0.118 +ucode_port_119.BCM8869X=RCY_MIRROR.19:core_0.119 +ucode_port_120.BCM8869X=RCY_MIRROR.0:core_1.120 +ucode_port_121.BCM8869X=RCY_MIRROR.1:core_1.121 +ucode_port_122.BCM8869X=RCY_MIRROR.2:core_1.122 +ucode_port_123.BCM8869X=RCY_MIRROR.3:core_1.123 +ucode_port_124.BCM8869X=RCY_MIRROR.4:core_1.124 +ucode_port_125.BCM8869X=RCY_MIRROR.5:core_1.125 +ucode_port_126.BCM8869X=RCY_MIRROR.6:core_1.126 +ucode_port_127.BCM8869X=RCY_MIRROR.7:core_1.127 +ucode_port_128.BCM8869X=RCY_MIRROR.8:core_1.128 +ucode_port_129.BCM8869X=RCY_MIRROR.9:core_1.129 +ucode_port_130.BCM8869X=RCY_MIRROR.10:core_1.130 +ucode_port_131.BCM8869X=RCY_MIRROR.11:core_1.131 +ucode_port_132.BCM8869X=RCY_MIRROR.12:core_1.132 +ucode_port_133.BCM8869X=RCY_MIRROR.13:core_1.133 +ucode_port_134.BCM8869X=RCY_MIRROR.14:core_1.134 +ucode_port_135.BCM8869X=RCY_MIRROR.15:core_1.135 +ucode_port_136.BCM8869X=RCY_MIRROR.16:core_1.136 +ucode_port_137.BCM8869X=RCY_MIRROR.17:core_1.137 +ucode_port_138.BCM8869X=RCY_MIRROR.18:core_1.138 +ucode_port_139.BCM8869X=RCY_MIRROR.19:core_1.139 + +port_priorities.BCM8869X=8 + +ucode_port_240.BCM8869X=OLP:core_0.240 + +sw_state_max_size.BCM8869X=750000000 + +stable_location.BCM8869X=4 +stable_location.BCM8869X_ADAPTER=3 + +stable_filename.BCM8869X_ADAPTER=warmboot_data_0 +stable_filename=/dev/shm/warmboot_data_0 +stable_filename.1=/dev/shm/warmboot_data_1 +stable_filename.2=/dev/shm/warmboot_data_2 + +stable_size.BCM8869X=800000000 + +tm_port_header_type_in_0.BCM8869X=INJECTED_2 +tm_port_header_type_out_0.BCM8869X=CPU + +tm_port_header_type_in_200.BCM8869X=INJECTED_2_PP +tm_port_header_type_out_200.BCM8869X=ETH +tm_port_header_type_in_201.BCM8869X=INJECTED_2_PP +tm_port_header_type_out_201.BCM8869X=ETH +tm_port_header_type_in_202.BCM8869X=INJECTED_2_PP +tm_port_header_type_out_202.BCM8869X=ETH +tm_port_header_type_in_203.BCM8869X=INJECTED_2_PP +tm_port_header_type_out_203.BCM8869X=ETH + +sat_enable.BCM8869X=1 +tm_port_header_type_out_218.BCM8869X=CPU +tm_port_header_type_in_218.BCM8869X=INJECTED_2 + +tm_port_header_type_in_232.BCM8869X=INJECTED_2 +tm_port_header_type_out_232.BCM8869X=CPU +tm_port_header_type_in_233.BCM8869X=INJECTED_2 +tm_port_header_type_out_233.BCM8869X=CPU + +tm_port_header_type_in_240.BCM8869X=INJECTED_2 +tm_port_header_type_out_240.BCM8869X=RAW + +dtm_flow_mapping_mode_region_64.BCM8869X=3 +dtm_flow_mapping_mode_region_65.BCM8869X=3 +dtm_flow_mapping_mode_region_66.BCM8869X=3 +dtm_flow_mapping_mode_region_67.BCM8869X=3 +dtm_flow_mapping_mode_region_68.BCM8869X=3 +dtm_flow_mapping_mode_region_69.BCM8869X=3 +dtm_flow_mapping_mode_region_70.BCM8869X=3 +dtm_flow_mapping_mode_region_71.BCM8869X=3 +dtm_flow_mapping_mode_region_72.BCM8869X=3 +dtm_flow_mapping_mode_region_73.BCM8869X=3 +dtm_flow_mapping_mode_region_74.BCM8869X=3 +dtm_flow_mapping_mode_region_75.BCM8869X=3 +dtm_flow_mapping_mode_region_76.BCM8869X=3 +dtm_flow_mapping_mode_region_77.BCM8869X=3 +dtm_flow_mapping_mode_region_78.BCM8869X=3 +dtm_flow_mapping_mode_region_79.BCM8869X=7 +dtm_flow_mapping_mode_region_80.BCM8869X=3 +dtm_flow_mapping_mode_region_81.BCM8869X=1 +dtm_flow_mapping_mode_region_82.BCM8869X=3 +dtm_flow_mapping_mode_region_83.BCM8869X=3 +dtm_flow_mapping_mode_region_84.BCM8869X=3 +dtm_flow_mapping_mode_region_85.BCM8869X=3 +dtm_flow_mapping_mode_region_86.BCM8869X=3 +dtm_flow_mapping_mode_region_87.BCM8869X=3 +dtm_flow_mapping_mode_region_88.BCM8869X=3 +dtm_flow_mapping_mode_region_89.BCM8869X=3 +dtm_flow_mapping_mode_region_90.BCM8869X=3 +dtm_flow_mapping_mode_region_91.BCM8869X=3 +dtm_flow_mapping_mode_region_92.BCM8869X=3 +dtm_flow_mapping_mode_region_93.BCM8869X=3 +dtm_flow_mapping_mode_region_94.BCM8869X=3 + +dtm_flow_nof_remote_cores_region_1.BCM8869X=2 +dtm_flow_nof_remote_cores_region_2.BCM8869X=2 +dtm_flow_nof_remote_cores_region_3.BCM8869X=2 +dtm_flow_nof_remote_cores_region_4.BCM8869X=2 +dtm_flow_nof_remote_cores_region_5.BCM8869X=2 +dtm_flow_nof_remote_cores_region_6.BCM8869X=2 +dtm_flow_nof_remote_cores_region_7.BCM8869X=2 +dtm_flow_nof_remote_cores_region_8.BCM8869X=2 +dtm_flow_nof_remote_cores_region_9.BCM8869X=2 +dtm_flow_nof_remote_cores_region_10.BCM8869X=2 +dtm_flow_nof_remote_cores_region_11.BCM8869X=2 +dtm_flow_nof_remote_cores_region_12.BCM8869X=2 +dtm_flow_nof_remote_cores_region_13.BCM8869X=2 +dtm_flow_nof_remote_cores_region_14.BCM8869X=2 +dtm_flow_nof_remote_cores_region_15.BCM8869X=2 +dtm_flow_nof_remote_cores_region_16.BCM8869X=2 +dtm_flow_nof_remote_cores_region_17.BCM8869X=2 +dtm_flow_nof_remote_cores_region_18.BCM8869X=2 +dtm_flow_nof_remote_cores_region_19.BCM8869X=2 +dtm_flow_nof_remote_cores_region_20.BCM8869X=2 +dtm_flow_nof_remote_cores_region_21.BCM8869X=2 +dtm_flow_nof_remote_cores_region_22.BCM8869X=2 +dtm_flow_nof_remote_cores_region_23.BCM8869X=2 +dtm_flow_nof_remote_cores_region_24.BCM8869X=2 +dtm_flow_nof_remote_cores_region_25.BCM8869X=2 +dtm_flow_nof_remote_cores_region_26.BCM8869X=2 +dtm_flow_nof_remote_cores_region_27.BCM8869X=2 +dtm_flow_nof_remote_cores_region_28.BCM8869X=2 +dtm_flow_nof_remote_cores_region_29.BCM8869X=2 +dtm_flow_nof_remote_cores_region_30.BCM8869X=2 +dtm_flow_nof_remote_cores_region_31.BCM8869X=2 +dtm_flow_nof_remote_cores_region_32.BCM8869X=2 +dtm_flow_nof_remote_cores_region_33.BCM8869X=2 +dtm_flow_nof_remote_cores_region_34.BCM8869X=2 +dtm_flow_nof_remote_cores_region_35.BCM8869X=2 +dtm_flow_nof_remote_cores_region_36.BCM8869X=2 +dtm_flow_nof_remote_cores_region_37.BCM8869X=2 +dtm_flow_nof_remote_cores_region_38.BCM8869X=2 +dtm_flow_nof_remote_cores_region_39.BCM8869X=2 +dtm_flow_nof_remote_cores_region_40.BCM8869X=2 +dtm_flow_nof_remote_cores_region_41.BCM8869X=2 +dtm_flow_nof_remote_cores_region_42.BCM8869X=2 +dtm_flow_nof_remote_cores_region_43.BCM8869X=2 +dtm_flow_nof_remote_cores_region_44.BCM8869X=2 +dtm_flow_nof_remote_cores_region_45.BCM8869X=2 +dtm_flow_nof_remote_cores_region_46.BCM8869X=2 +dtm_flow_nof_remote_cores_region_47.BCM8869X=2 +dtm_flow_nof_remote_cores_region_48.BCM8869X=2 +dtm_flow_nof_remote_cores_region_49.BCM8869X=2 +dtm_flow_nof_remote_cores_region_50.BCM8869X=2 +dtm_flow_nof_remote_cores_region_51.BCM8869X=2 +dtm_flow_nof_remote_cores_region_52.BCM8869X=2 +dtm_flow_nof_remote_cores_region_53.BCM8869X=2 +dtm_flow_nof_remote_cores_region_54.BCM8869X=2 +dtm_flow_nof_remote_cores_region_55.BCM8869X=2 +dtm_flow_nof_remote_cores_region_56.BCM8869X=2 +dtm_flow_nof_remote_cores_region_57.BCM8869X=2 +dtm_flow_nof_remote_cores_region_58.BCM8869X=2 +dtm_flow_nof_remote_cores_region_59.BCM8869X=2 +dtm_flow_nof_remote_cores_region_60.BCM8869X=2 + +mdb_profile.BCM8869X=l3-xl + +outlif_logical_to_physical_phase_map_1=S1 +outlif_logical_to_physical_phase_map_2=L1 +outlif_logical_to_physical_phase_map_3=XL +outlif_logical_to_physical_phase_map_4=L2 +outlif_logical_to_physical_phase_map_5=M1 +outlif_logical_to_physical_phase_map_6=M2 +outlif_logical_to_physical_phase_map_7=M3 +outlif_logical_to_physical_phase_map_8=S2 + +outlif_physical_phase_data_granularity_S1=60 +outlif_physical_phase_data_granularity_S2=60 +outlif_physical_phase_data_granularity_M1=60 +outlif_physical_phase_data_granularity_M2=60 +outlif_physical_phase_data_granularity_M3=60 +outlif_physical_phase_data_granularity_L1=60 +outlif_physical_phase_data_granularity_L2=60 +outlif_physical_phase_data_granularity_XL=60 + +port_init_speed_fabric.BCM8869X=53125 + +fabric_connect_mode.BCM8869X=SINGLE_FAP +protocol_traps_mode.BCM8869X=IN_LIF + +schan_intr_enable.BCM8869X=0 +tdma_intr_enable.BCM8869X=0 +tslam_intr_enable.BCM8869X=0 +miim_intr_enable.BCM8869X=0 +schan_timeout_usec.BCM8869X=300000 +tdma_timeout_usec.BCM8869X=1000000 +tslam_timeout_usec.BCM8869X=1000000 + +appl_enable_intr_init.BCM8869X=1 +polled_irq_mode.BCM8869X=1 +polled_irq_delay.BCM8869X=1000 + +bcm_stat_interval.BCM8869X=1000 + +mem_cache_enable_ecc.BCM8869X=1 +mem_cache_enable_parity.BCM8869X=1 + +serdes_nif_clk_freq_in.BCM8869X_A0=2 +serdes_nif_clk_freq_out.BCM8869X_A0=1 +serdes_fabric_clk_freq_in.BCM8869X_A0=2 +serdes_fabric_clk_freq_out.BCM8869X_A0=1 + +serdes_nif_clk_freq_in.BCM8869X=1 +serdes_nif_clk_freq_out.BCM8869X=bypass +serdes_fabric_clk_freq_in.BCM8869X=1 +serdes_fabric_clk_freq_out.BCM8869X=bypass + +dram_phy_tune_mode_on_init.BCM8869X=RUN_TUNE + +dport_map_direct.BCM8869X=1 + +pmf_sexem3_stage.BCM8869X=IPMF3 + +lane_to_serdes_map_fabric_lane0.0=rx0:tx0 +lane_to_serdes_map_fabric_lane1.0=rx1:tx1 +lane_to_serdes_map_fabric_lane2.0=rx2:tx2 +lane_to_serdes_map_fabric_lane3.0=rx3:tx3 +lane_to_serdes_map_fabric_lane4.0=rx4:tx4 +lane_to_serdes_map_fabric_lane5.0=rx5:tx5 +lane_to_serdes_map_fabric_lane6.0=rx6:tx6 +lane_to_serdes_map_fabric_lane7.0=rx7:tx7 +lane_to_serdes_map_fabric_lane8.0=rx8:tx8 +lane_to_serdes_map_fabric_lane9.0=rx9:tx9 +lane_to_serdes_map_fabric_lane10.0=rx10:tx10 +lane_to_serdes_map_fabric_lane11.0=rx11:tx11 +lane_to_serdes_map_fabric_lane12.0=rx12:tx12 +lane_to_serdes_map_fabric_lane13.0=rx13:tx13 +lane_to_serdes_map_fabric_lane14.0=rx14:tx14 +lane_to_serdes_map_fabric_lane15.0=rx15:tx15 +lane_to_serdes_map_fabric_lane16.0=rx16:tx16 +lane_to_serdes_map_fabric_lane17.0=rx17:tx17 +lane_to_serdes_map_fabric_lane18.0=rx18:tx18 +lane_to_serdes_map_fabric_lane19.0=rx19:tx19 +lane_to_serdes_map_fabric_lane20.0=rx20:tx20 +lane_to_serdes_map_fabric_lane21.0=rx21:tx21 +lane_to_serdes_map_fabric_lane22.0=rx22:tx22 +lane_to_serdes_map_fabric_lane23.0=rx23:tx23 +lane_to_serdes_map_fabric_lane24.0=rx24:tx24 +lane_to_serdes_map_fabric_lane25.0=rx25:tx25 +lane_to_serdes_map_fabric_lane26.0=rx26:tx26 +lane_to_serdes_map_fabric_lane27.0=rx27:tx27 +lane_to_serdes_map_fabric_lane28.0=rx28:tx28 +lane_to_serdes_map_fabric_lane29.0=rx29:tx29 +lane_to_serdes_map_fabric_lane30.0=rx30:tx30 +lane_to_serdes_map_fabric_lane31.0=rx31:tx31 +lane_to_serdes_map_fabric_lane32.0=rx32:tx32 +lane_to_serdes_map_fabric_lane33.0=rx33:tx33 +lane_to_serdes_map_fabric_lane34.0=rx34:tx34 +lane_to_serdes_map_fabric_lane35.0=rx35:tx35 +lane_to_serdes_map_fabric_lane36.0=rx36:tx36 +lane_to_serdes_map_fabric_lane37.0=rx37:tx37 +lane_to_serdes_map_fabric_lane38.0=rx38:tx38 +lane_to_serdes_map_fabric_lane39.0=rx39:tx39 +lane_to_serdes_map_fabric_lane40.0=rx40:tx40 +lane_to_serdes_map_fabric_lane41.0=rx41:tx41 +lane_to_serdes_map_fabric_lane42.0=rx42:tx42 +lane_to_serdes_map_fabric_lane43.0=rx43:tx43 +lane_to_serdes_map_fabric_lane44.0=rx44:tx44 +lane_to_serdes_map_fabric_lane45.0=rx45:tx45 +lane_to_serdes_map_fabric_lane46.0=rx46:tx46 +lane_to_serdes_map_fabric_lane47.0=rx47:tx47 +lane_to_serdes_map_fabric_lane48.0=rx48:tx48 +lane_to_serdes_map_fabric_lane49.0=rx49:tx49 +lane_to_serdes_map_fabric_lane50.0=rx50:tx50 +lane_to_serdes_map_fabric_lane51.0=rx51:tx51 +lane_to_serdes_map_fabric_lane52.0=rx52:tx52 +lane_to_serdes_map_fabric_lane53.0=rx53:tx53 +lane_to_serdes_map_fabric_lane54.0=rx54:tx54 +lane_to_serdes_map_fabric_lane55.0=rx55:tx55 +lane_to_serdes_map_fabric_lane56.0=rx56:tx56 +lane_to_serdes_map_fabric_lane57.0=rx57:tx57 +lane_to_serdes_map_fabric_lane58.0=rx58:tx58 +lane_to_serdes_map_fabric_lane59.0=rx59:tx59 +lane_to_serdes_map_fabric_lane60.0=rx60:tx60 +lane_to_serdes_map_fabric_lane61.0=rx61:tx61 +lane_to_serdes_map_fabric_lane62.0=rx62:tx62 +lane_to_serdes_map_fabric_lane63.0=rx63:tx63 +lane_to_serdes_map_fabric_lane64.0=rx64:tx64 +lane_to_serdes_map_fabric_lane65.0=rx65:tx65 +lane_to_serdes_map_fabric_lane66.0=rx66:tx66 +lane_to_serdes_map_fabric_lane67.0=rx67:tx67 +lane_to_serdes_map_fabric_lane68.0=rx68:tx68 +lane_to_serdes_map_fabric_lane69.0=rx69:tx69 +lane_to_serdes_map_fabric_lane70.0=rx70:tx70 +lane_to_serdes_map_fabric_lane71.0=rx71:tx71 +lane_to_serdes_map_fabric_lane72.0=rx72:tx72 +lane_to_serdes_map_fabric_lane73.0=rx73:tx73 +lane_to_serdes_map_fabric_lane74.0=rx74:tx74 +lane_to_serdes_map_fabric_lane75.0=rx75:tx75 +lane_to_serdes_map_fabric_lane76.0=rx76:tx76 +lane_to_serdes_map_fabric_lane77.0=rx77:tx77 +lane_to_serdes_map_fabric_lane78.0=rx78:tx78 +lane_to_serdes_map_fabric_lane79.0=rx79:tx79 +lane_to_serdes_map_fabric_lane80.0=rx80:tx80 +lane_to_serdes_map_fabric_lane81.0=rx81:tx81 +lane_to_serdes_map_fabric_lane82.0=rx82:tx82 +lane_to_serdes_map_fabric_lane83.0=rx83:tx83 +lane_to_serdes_map_fabric_lane84.0=rx84:tx84 +lane_to_serdes_map_fabric_lane85.0=rx85:tx85 +lane_to_serdes_map_fabric_lane86.0=rx86:tx86 +lane_to_serdes_map_fabric_lane87.0=rx87:tx87 +lane_to_serdes_map_fabric_lane88.0=rx88:tx88 +lane_to_serdes_map_fabric_lane89.0=rx89:tx89 +lane_to_serdes_map_fabric_lane90.0=rx90:tx90 +lane_to_serdes_map_fabric_lane91.0=rx91:tx91 +lane_to_serdes_map_fabric_lane92.0=rx92:tx92 +lane_to_serdes_map_fabric_lane93.0=rx93:tx93 +lane_to_serdes_map_fabric_lane94.0=rx94:tx94 +lane_to_serdes_map_fabric_lane95.0=rx95:tx95 +lane_to_serdes_map_fabric_lane96.0=rx96:tx96 +lane_to_serdes_map_fabric_lane97.0=rx97:tx97 +lane_to_serdes_map_fabric_lane98.0=rx98:tx98 +lane_to_serdes_map_fabric_lane99.0=rx99:tx99 +lane_to_serdes_map_fabric_lane100.0=rx100:tx100 +lane_to_serdes_map_fabric_lane101.0=rx101:tx101 +lane_to_serdes_map_fabric_lane102.0=rx102:tx102 +lane_to_serdes_map_fabric_lane103.0=rx103:tx103 +lane_to_serdes_map_fabric_lane104.0=rx104:tx104 +lane_to_serdes_map_fabric_lane105.0=rx105:tx105 +lane_to_serdes_map_fabric_lane106.0=rx106:tx106 +lane_to_serdes_map_fabric_lane107.0=rx107:tx107 +lane_to_serdes_map_fabric_lane108.0=rx108:tx108 +lane_to_serdes_map_fabric_lane109.0=rx109:tx109 +lane_to_serdes_map_fabric_lane110.0=rx110:tx110 +lane_to_serdes_map_fabric_lane111.0=rx111:tx111 + +lane_to_serdes_map_nif_lane0.0=rx5:tx7 +lane_to_serdes_map_nif_lane1.0=rx7:tx6 +lane_to_serdes_map_nif_lane2.0=rx4:tx5 +lane_to_serdes_map_nif_lane3.0=rx6:tx4 +lane_to_serdes_map_nif_lane4.0=rx0:tx0 +lane_to_serdes_map_nif_lane5.0=rx1:tx1 +lane_to_serdes_map_nif_lane6.0=rx2:tx3 +lane_to_serdes_map_nif_lane7.0=rx3:tx2 +lane_to_serdes_map_nif_lane8.0=rx13:tx15 +lane_to_serdes_map_nif_lane9.0=rx12:tx14 +lane_to_serdes_map_nif_lane10.0=rx15:tx13 +lane_to_serdes_map_nif_lane11.0=rx14:tx12 +lane_to_serdes_map_nif_lane12.0=rx10:tx10 +lane_to_serdes_map_nif_lane13.0=rx8:tx9 +lane_to_serdes_map_nif_lane14.0=rx9:tx11 +lane_to_serdes_map_nif_lane15.0=rx11:tx8 +lane_to_serdes_map_nif_lane16.0=rx23:tx23 +lane_to_serdes_map_nif_lane17.0=rx21:tx22 +lane_to_serdes_map_nif_lane18.0=rx22:tx21 +lane_to_serdes_map_nif_lane19.0=rx20:tx20 +lane_to_serdes_map_nif_lane20.0=rx16:tx18 +lane_to_serdes_map_nif_lane21.0=rx17:tx17 +lane_to_serdes_map_nif_lane22.0=rx18:tx16 +lane_to_serdes_map_nif_lane23.0=rx19:tx19 +lane_to_serdes_map_nif_lane24.0=rx31:tx31 +lane_to_serdes_map_nif_lane25.0=rx30:tx30 +lane_to_serdes_map_nif_lane26.0=rx29:tx29 +lane_to_serdes_map_nif_lane27.0=rx28:tx28 +lane_to_serdes_map_nif_lane28.0=rx24:tx26 +lane_to_serdes_map_nif_lane29.0=rx26:tx25 +lane_to_serdes_map_nif_lane30.0=rx25:tx24 +lane_to_serdes_map_nif_lane31.0=rx27:tx27 +lane_to_serdes_map_nif_lane32.0=rx38:tx34 +lane_to_serdes_map_nif_lane33.0=rx34:tx39 +lane_to_serdes_map_nif_lane34.0=rx39:tx33 +lane_to_serdes_map_nif_lane35.0=rx32:tx38 +lane_to_serdes_map_nif_lane36.0=rx36:tx35 +lane_to_serdes_map_nif_lane37.0=rx33:tx37 +lane_to_serdes_map_nif_lane38.0=rx37:tx32 +lane_to_serdes_map_nif_lane39.0=rx35:tx36 +lane_to_serdes_map_nif_lane40.0=rx46:tx41 +lane_to_serdes_map_nif_lane41.0=rx41:tx46 +lane_to_serdes_map_nif_lane42.0=rx45:tx42 +lane_to_serdes_map_nif_lane43.0=rx40:tx47 +lane_to_serdes_map_nif_lane44.0=rx47:tx40 +lane_to_serdes_map_nif_lane45.0=rx43:tx44 +lane_to_serdes_map_nif_lane46.0=rx44:tx43 +lane_to_serdes_map_nif_lane47.0=rx42:tx45 +lane_to_serdes_map_nif_lane48.0=rx55:tx55 +lane_to_serdes_map_nif_lane49.0=rx54:tx54 +lane_to_serdes_map_nif_lane50.0=rx53:tx53 +lane_to_serdes_map_nif_lane51.0=rx52:tx52 +lane_to_serdes_map_nif_lane52.0=rx48:tx48 +lane_to_serdes_map_nif_lane53.0=rx49:tx49 +lane_to_serdes_map_nif_lane54.0=rx50:tx50 +lane_to_serdes_map_nif_lane55.0=rx51:tx51 +lane_to_serdes_map_nif_lane56.0=rx60:tx60 +lane_to_serdes_map_nif_lane57.0=rx61:tx61 +lane_to_serdes_map_nif_lane58.0=rx62:tx63 +lane_to_serdes_map_nif_lane59.0=rx63:tx62 +lane_to_serdes_map_nif_lane60.0=rx58:tx59 +lane_to_serdes_map_nif_lane61.0=rx59:tx56 +lane_to_serdes_map_nif_lane62.0=rx57:tx58 +lane_to_serdes_map_nif_lane63.0=rx56:tx57 +lane_to_serdes_map_nif_lane64.0=rx68:tx69 +lane_to_serdes_map_nif_lane65.0=rx69:tx68 +lane_to_serdes_map_nif_lane66.0=rx70:tx71 +lane_to_serdes_map_nif_lane67.0=rx71:tx70 +lane_to_serdes_map_nif_lane68.0=rx67:tx64 +lane_to_serdes_map_nif_lane69.0=rx66:tx67 +lane_to_serdes_map_nif_lane70.0=rx65:tx65 +lane_to_serdes_map_nif_lane71.0=rx64:tx66 +lane_to_serdes_map_nif_lane72.0=rx78:tx76 +lane_to_serdes_map_nif_lane73.0=rx76:tx77 +lane_to_serdes_map_nif_lane74.0=rx79:tx78 +lane_to_serdes_map_nif_lane75.0=rx77:tx79 +lane_to_serdes_map_nif_lane76.0=rx75:tx72 +lane_to_serdes_map_nif_lane77.0=rx74:tx75 +lane_to_serdes_map_nif_lane78.0=rx73:tx73 +lane_to_serdes_map_nif_lane79.0=rx72:tx74 +lane_to_serdes_map_nif_lane80.0=rx83:tx84 +lane_to_serdes_map_nif_lane81.0=rx87:tx80 +lane_to_serdes_map_nif_lane82.0=rx82:tx85 +lane_to_serdes_map_nif_lane83.0=rx84:tx83 +lane_to_serdes_map_nif_lane84.0=rx80:tx86 +lane_to_serdes_map_nif_lane85.0=rx85:tx81 +lane_to_serdes_map_nif_lane86.0=rx81:tx87 +lane_to_serdes_map_nif_lane87.0=rx86:tx82 +lane_to_serdes_map_nif_lane88.0=rx90:tx93 +lane_to_serdes_map_nif_lane89.0=rx88:tx91 +lane_to_serdes_map_nif_lane90.0=rx91:tx92 +lane_to_serdes_map_nif_lane91.0=rx95:tx88 +lane_to_serdes_map_nif_lane92.0=rx94:tx95 +lane_to_serdes_map_nif_lane93.0=rx93:tx90 +lane_to_serdes_map_nif_lane94.0=rx89:tx94 +lane_to_serdes_map_nif_lane95.0=rx92:tx89 + +phy_rx_polarity_flip_phy0=0 +phy_rx_polarity_flip_phy1=1 +phy_rx_polarity_flip_phy2=0 +phy_rx_polarity_flip_phy3=0 +phy_rx_polarity_flip_phy4=0 +phy_rx_polarity_flip_phy5=0 +phy_rx_polarity_flip_phy6=0 +phy_rx_polarity_flip_phy7=0 +phy_rx_polarity_flip_phy8=1 +phy_rx_polarity_flip_phy9=1 +phy_rx_polarity_flip_phy10=1 +phy_rx_polarity_flip_phy11=1 +phy_rx_polarity_flip_phy12=0 +phy_rx_polarity_flip_phy13=1 +phy_rx_polarity_flip_phy14=1 +phy_rx_polarity_flip_phy15=1 +phy_rx_polarity_flip_phy16=0 +phy_rx_polarity_flip_phy17=1 +phy_rx_polarity_flip_phy18=1 +phy_rx_polarity_flip_phy19=0 +phy_rx_polarity_flip_phy20=0 +phy_rx_polarity_flip_phy21=0 +phy_rx_polarity_flip_phy22=0 +phy_rx_polarity_flip_phy23=0 +phy_rx_polarity_flip_phy24=1 +phy_rx_polarity_flip_phy25=1 +phy_rx_polarity_flip_phy26=1 +phy_rx_polarity_flip_phy27=0 +phy_rx_polarity_flip_phy28=0 +phy_rx_polarity_flip_phy29=1 +phy_rx_polarity_flip_phy30=1 +phy_rx_polarity_flip_phy31=0 +phy_rx_polarity_flip_phy32=1 +phy_rx_polarity_flip_phy33=0 +phy_rx_polarity_flip_phy34=0 +phy_rx_polarity_flip_phy35=0 +phy_rx_polarity_flip_phy36=0 +phy_rx_polarity_flip_phy37=1 +phy_rx_polarity_flip_phy38=0 +phy_rx_polarity_flip_phy39=1 + +phy_rx_polarity_flip_phy40=1 +phy_rx_polarity_flip_phy41=1 +phy_rx_polarity_flip_phy42=0 +phy_rx_polarity_flip_phy43=0 +phy_rx_polarity_flip_phy44=1 +phy_rx_polarity_flip_phy45=0 +phy_rx_polarity_flip_phy46=1 +phy_rx_polarity_flip_phy47=0 + +phy_rx_polarity_flip_phy48=1 +phy_rx_polarity_flip_phy49=1 +phy_rx_polarity_flip_phy50=1 +phy_rx_polarity_flip_phy51=1 +phy_rx_polarity_flip_phy52=0 +phy_rx_polarity_flip_phy53=0 +phy_rx_polarity_flip_phy54=0 +phy_rx_polarity_flip_phy55=0 +phy_rx_polarity_flip_phy56=0 +phy_rx_polarity_flip_phy57=0 +phy_rx_polarity_flip_phy58=0 +phy_rx_polarity_flip_phy59=0 +phy_rx_polarity_flip_phy60=1 +phy_rx_polarity_flip_phy61=1 +phy_rx_polarity_flip_phy62=1 +phy_rx_polarity_flip_phy63=1 +phy_rx_polarity_flip_phy64=1 +phy_rx_polarity_flip_phy65=1 +phy_rx_polarity_flip_phy66=1 +phy_rx_polarity_flip_phy67=1 +phy_rx_polarity_flip_phy68=1 +phy_rx_polarity_flip_phy69=1 +phy_rx_polarity_flip_phy70=1 +phy_rx_polarity_flip_phy71=1 +phy_rx_polarity_flip_phy72=1 +phy_rx_polarity_flip_phy73=0 +phy_rx_polarity_flip_phy74=0 +phy_rx_polarity_flip_phy75=1 +phy_rx_polarity_flip_phy76=1 +phy_rx_polarity_flip_phy77=1 +phy_rx_polarity_flip_phy78=1 +phy_rx_polarity_flip_phy79=1 + +phy_rx_polarity_flip_phy80=1 +phy_rx_polarity_flip_phy81=1 +phy_rx_polarity_flip_phy82=1 +phy_rx_polarity_flip_phy83=0 +phy_rx_polarity_flip_phy84=1 +phy_rx_polarity_flip_phy85=0 +phy_rx_polarity_flip_phy86=1 +phy_rx_polarity_flip_phy87=0 + +phy_rx_polarity_flip_phy88=1 +phy_rx_polarity_flip_phy89=0 +phy_rx_polarity_flip_phy90=0 +phy_rx_polarity_flip_phy91=1 +phy_rx_polarity_flip_phy92=1 +phy_rx_polarity_flip_phy93=0 +phy_rx_polarity_flip_phy94=0 +phy_rx_polarity_flip_phy95=1 + +phy_tx_polarity_flip_phy0=1 +phy_tx_polarity_flip_phy1=1 +phy_tx_polarity_flip_phy2=1 +phy_tx_polarity_flip_phy3=1 +phy_tx_polarity_flip_phy4=1 +phy_tx_polarity_flip_phy5=1 +phy_tx_polarity_flip_phy6=0 +phy_tx_polarity_flip_phy7=0 +phy_tx_polarity_flip_phy8=1 +phy_tx_polarity_flip_phy9=1 +phy_tx_polarity_flip_phy10=1 +phy_tx_polarity_flip_phy11=1 +phy_tx_polarity_flip_phy12=1 +phy_tx_polarity_flip_phy13=1 +phy_tx_polarity_flip_phy14=0 +phy_tx_polarity_flip_phy15=0 +phy_tx_polarity_flip_phy16=0 +phy_tx_polarity_flip_phy17=0 +phy_tx_polarity_flip_phy18=0 +phy_tx_polarity_flip_phy19=0 +phy_tx_polarity_flip_phy20=0 +phy_tx_polarity_flip_phy21=0 +phy_tx_polarity_flip_phy22=0 +phy_tx_polarity_flip_phy23=0 +phy_tx_polarity_flip_phy24=0 +phy_tx_polarity_flip_phy25=0 +phy_tx_polarity_flip_phy26=0 +phy_tx_polarity_flip_phy27=0 +phy_tx_polarity_flip_phy28=0 +phy_tx_polarity_flip_phy29=0 +phy_tx_polarity_flip_phy30=0 +phy_tx_polarity_flip_phy31=0 +phy_tx_polarity_flip_phy32=1 +phy_tx_polarity_flip_phy33=0 +phy_tx_polarity_flip_phy34=0 +phy_tx_polarity_flip_phy35=1 +phy_tx_polarity_flip_phy36=1 +phy_tx_polarity_flip_phy37=0 +phy_tx_polarity_flip_phy38=1 +phy_tx_polarity_flip_phy39=0 + +phy_tx_polarity_flip_phy40=0 +phy_tx_polarity_flip_phy41=1 +phy_tx_polarity_flip_phy42=1 +phy_tx_polarity_flip_phy43=0 +phy_tx_polarity_flip_phy44=1 +phy_tx_polarity_flip_phy45=0 +phy_tx_polarity_flip_phy46=1 +phy_tx_polarity_flip_phy47=0 + +phy_tx_polarity_flip_phy48=0 +phy_tx_polarity_flip_phy49=0 +phy_tx_polarity_flip_phy50=0 +phy_tx_polarity_flip_phy51=0 +phy_tx_polarity_flip_phy52=0 +phy_tx_polarity_flip_phy53=0 +phy_tx_polarity_flip_phy54=0 +phy_tx_polarity_flip_phy55=0 +phy_tx_polarity_flip_phy56=1 +phy_tx_polarity_flip_phy57=1 +phy_tx_polarity_flip_phy58=0 +phy_tx_polarity_flip_phy59=0 +phy_tx_polarity_flip_phy60=1 +phy_tx_polarity_flip_phy61=1 +phy_tx_polarity_flip_phy62=0 +phy_tx_polarity_flip_phy63=0 +phy_tx_polarity_flip_phy64=0 +phy_tx_polarity_flip_phy65=0 +phy_tx_polarity_flip_phy66=0 +phy_tx_polarity_flip_phy67=0 +phy_tx_polarity_flip_phy68=0 +phy_tx_polarity_flip_phy69=0 +phy_tx_polarity_flip_phy70=1 +phy_tx_polarity_flip_phy71=1 +phy_tx_polarity_flip_phy72=1 +phy_tx_polarity_flip_phy73=1 +phy_tx_polarity_flip_phy74=1 +phy_tx_polarity_flip_phy75=1 +phy_tx_polarity_flip_phy76=0 +phy_tx_polarity_flip_phy77=0 +phy_tx_polarity_flip_phy78=1 +phy_tx_polarity_flip_phy79=1 + +phy_tx_polarity_flip_phy80=1 +phy_tx_polarity_flip_phy81=1 +phy_tx_polarity_flip_phy82=0 +phy_tx_polarity_flip_phy83=0 +phy_tx_polarity_flip_phy84=1 +phy_tx_polarity_flip_phy85=1 +phy_tx_polarity_flip_phy86=1 +phy_tx_polarity_flip_phy87=1 + +phy_tx_polarity_flip_phy88=0 +phy_tx_polarity_flip_phy89=0 +phy_tx_polarity_flip_phy90=1 +phy_tx_polarity_flip_phy91=1 +phy_tx_polarity_flip_phy92=1 +phy_tx_polarity_flip_phy93=1 +phy_tx_polarity_flip_phy94=1 +phy_tx_polarity_flip_phy95=1 + +ucode_port_1=CGE2_0:core_0.1 +ucode_port_2=CGE2_1:core_0.2 +ucode_port_3=CGE2_2:core_0.3 +ucode_port_4=CGE2_3:core_0.4 +ucode_port_5=CGE2_4:core_0.5 +ucode_port_6=CGE2_5:core_0.6 +ucode_port_7=CGE2_6:core_0.7 +ucode_port_8=CGE2_7:core_0.8 +ucode_port_9=CGE2_8:core_0.9 +ucode_port_10=CGE2_9:core_0.10 +ucode_port_11=CGE2_10:core_0.11 +ucode_port_12=CGE2_11:core_0.12 +ucode_port_13=CGE2_12:core_0.13 +ucode_port_14=CGE2_13:core_0.14 +ucode_port_15=CGE2_14:core_0.15 +ucode_port_16=CGE2_15:core_0.16 +ucode_port_17=CGE2_36:core_1.17 +ucode_port_18=CGE2_37:core_1.18 +ucode_port_19=CGE2_38:core_1.19 +ucode_port_20=CGE2_39:core_1.20 +ucode_port_21=CGE2_32:core_1.21 +ucode_port_22=CGE2_33:core_1.22 +ucode_port_23=CGE2_34:core_1.23 +ucode_port_24=CGE2_35:core_1.24 +ucode_port_25=CGE2_28:core_1.25 +ucode_port_26=CGE2_29:core_1.26 +ucode_port_27=CGE2_30:core_1.27 +ucode_port_28=CGE2_31:core_1.28 +ucode_port_29=CGE2_24:core_1.29 +ucode_port_30=CGE2_25:core_1.30 +ucode_port_31=CGE2_26:core_1.31 +ucode_port_32=CGE2_27:core_1.32 + +port_fec_33=2 +port_fec_34=2 +port_fec_35=2 +port_fec_36=2 +port_fec_37=2 +port_fec_38=2 +port_fec_39=2 +port_fec_40=2 + +ucode_port_33=CGE8:core_0.33 +ucode_port_34=CGE9:core_0.34 +ucode_port_35=CGE10:core_0.35 +ucode_port_36=CGE11:core_0.36 +ucode_port_37=CGE22:core_1.37 +ucode_port_38=CGE23:core_1.38 +ucode_port_39=CGE20:core_1.39 +ucode_port_40=CGE21:core_1.40 + +rif_id_max=0x4000 + +dma_desc_aggregator_chain_length_max.BCM8869X=1000 +dma_desc_aggregator_buff_size_kb.BCM8869X=100 +dma_desc_aggregator_timeout_usec.BCM8869X=1000 +dma_desc_aggregator_enable_specific_MDB_LPM.BCM8869X=1 +dma_desc_aggregator_enable_specific_MDB_FEC.BCM8869X=1 diff --git a/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/port_config.ini b/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/port_config.ini new file mode 100644 index 000000000000..2ba638aee50d --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/port_config.ini @@ -0,0 +1,41 @@ +# name lanes alias index speed +Ethernet0 0,1 Ethernet1/1 1 100000 +Ethernet4 2,3 Ethernet2/1 2 100000 +Ethernet8 4,5 Ethernet3/1 3 100000 +Ethernet12 6,7 Ethernet4/1 4 100000 +Ethernet16 8,9 Ethernet5/1 5 100000 +Ethernet20 10,11 Ethernet6/1 6 100000 +Ethernet24 12,13 Ethernet7/1 7 100000 +Ethernet28 14,15 Ethernet8/1 8 100000 +Ethernet32 16,17 Ethernet9/1 9 100000 +Ethernet36 18,19 Ethernet10/1 10 100000 +Ethernet40 20,21 Ethernet11/1 11 100000 +Ethernet44 22,23 Ethernet12/1 12 100000 +Ethernet48 24,25 Ethernet13/1 13 100000 +Ethernet52 26,27 Ethernet14/1 14 100000 +Ethernet56 28,29 Ethernet15/1 15 100000 +Ethernet60 30,31 Ethernet16/1 16 100000 +Ethernet64 72,73 Ethernet17/1 17 100000 +Ethernet68 74,75 Ethernet18/1 18 100000 +Ethernet72 76,77 Ethernet19/1 19 100000 +Ethernet76 78,79 Ethernet20/1 20 100000 +Ethernet80 64,65 Ethernet21/1 21 100000 +Ethernet84 66,67 Ethernet22/1 22 100000 +Ethernet88 68,69 Ethernet23/1 23 100000 +Ethernet92 70,71 Ethernet24/1 24 100000 +Ethernet96 56,57 Ethernet25/1 25 100000 +Ethernet100 58,59 Ethernet26/1 26 100000 +Ethernet104 60,61 Ethernet27/1 27 100000 +Ethernet108 62,63 Ethernet28/1 28 100000 +Ethernet112 48,49 Ethernet29/1 29 100000 +Ethernet116 50,51 Ethernet30/1 30 100000 +Ethernet120 52,53 Ethernet31/1 31 100000 +Ethernet124 54,55 Ethernet32/1 32 100000 +Ethernet128 32,33,34,35 Ethernet33/1 33 100000 +Ethernet132 36,37,38,39 Ethernet33/5 33 100000 +Ethernet136 40,41,42,43 Ethernet34/1 34 100000 +Ethernet140 44,45,46,47 Ethernet34/5 34 100000 +Ethernet144 88,89,90,91 Ethernet35/1 35 100000 +Ethernet148 92,93,94,95 Ethernet35/5 35 100000 +Ethernet152 80,81,82,83 Ethernet36/1 36 100000 +Ethernet156 84,85,86,87 Ethernet36/5 36 100000 diff --git a/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/sai.profile b/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/sai.profile new file mode 100644 index 000000000000..17ef703d798d --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/jr2-a7280cr3-32d4-40x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7280cr3_32d4/default_sku b/device/arista/x86_64-arista_7280cr3_32d4/default_sku new file mode 100644 index 000000000000..a65e1f845ad3 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32d4/default_sku @@ -0,0 +1 @@ +Arista-7280CR3-C32P4 t1 diff --git a/device/arista/x86_64-arista_7280cr3_32d4/fancontrol b/device/arista/x86_64-arista_7280cr3_32d4/fancontrol new file mode 120000 index 000000000000..6a53b7541071 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32d4/fancontrol @@ -0,0 +1 @@ +../x86_64-arista_7280cr3_32p4/fancontrol \ No newline at end of file diff --git a/device/arista/x86_64-arista_7280cr3_32d4/platform.json b/device/arista/x86_64-arista_7280cr3_32d4/platform.json new file mode 100644 index 000000000000..39b91ddd0f63 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32d4/platform.json @@ -0,0 +1,207 @@ +{ + "chassis": { + "name": "DCS-7280CR3K-32D4", + "components": [], + "fans": [], + "fan_drawers": [ + { + "name": "slot1", + "fans": [ + { + "name": "fan1" + }, + { + "name": "fan2" + } + ] + }, + { + "name": "slot2", + "fans": [ + { + "name": "fan3" + }, + { + "name": "fan4" + } + ] + }, + { + "name": "slot3", + "fans": [ + { + "name": "fan5" + }, + { + "name": "fan6" + } + ] + } + ], + "psus": [ + { + "name": "psu1", + "fans": [] + }, + { + "name": "psu2", + "fans": [] + } + ], + "thermals": [ + { + "name": "Cpu temp sensor" + }, + { + "name": "CPU board temp sensor" + }, + { + "name": "Back-panel temp sensor" + }, + { + "name": "Board Sensor" + }, + { + "name": "Front Air" + }, + { + "name": "Rear Air" + }, + { + "name": "Fap 0 Core 0" + }, + { + "name": "Fap 0 Core 1" + }, + { + "name": "Power supply 1 inlet temp sensor" + }, + { + "name": "Power supply 1 secondary hotspot sensor" + }, + { + "name": "Power supply 1 primary hotspot sensor" + }, + { + "name": "Power supply 2 inlet temp sensor" + }, + { + "name": "Power supply 2 secondary hotspot sensor" + }, + { + "name": "Power supply 2 primary hotspot sensor" + } + ], + "sfps": [ + { + "name": "qsfp1" + }, + { + "name": "qsfp2" + }, + { + "name": "qsfp3" + }, + { + "name": "qsfp4" + }, + { + "name": "qsfp5" + }, + { + "name": "qsfp6" + }, + { + "name": "qsfp7" + }, + { + "name": "qsfp8" + }, + { + "name": "qsfp9" + }, + { + "name": "qsfp10" + }, + { + "name": "qsfp11" + }, + { + "name": "qsfp12" + }, + { + "name": "qsfp13" + }, + { + "name": "qsfp14" + }, + { + "name": "qsfp15" + }, + { + "name": "qsfp16" + }, + { + "name": "qsfp17" + }, + { + "name": "qsfp18" + }, + { + "name": "qsfp19" + }, + { + "name": "qsfp20" + }, + { + "name": "qsfp21" + }, + { + "name": "qsfp22" + }, + { + "name": "qsfp23" + }, + { + "name": "qsfp24" + }, + { + "name": "qsfp25" + }, + { + "name": "qsfp26" + }, + { + "name": "qsfp27" + }, + { + "name": "qsfp28" + }, + { + "name": "qsfp29" + }, + { + "name": "qsfp30" + }, + { + "name": "qsfp31" + }, + { + "name": "qsfp32" + }, + { + "name": "osfp33" + }, + { + "name": "osfp34" + }, + { + "name": "osfp35" + }, + { + "name": "osfp36" + } + ] + }, + "interfaces": {} +} \ No newline at end of file diff --git a/device/arista/x86_64-arista_7280cr3_32d4/platform_reboot b/device/arista/x86_64-arista_7280cr3_32d4/platform_reboot new file mode 120000 index 000000000000..7f94a49e38b0 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32d4/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_7060_cx32s/plugins b/device/arista/x86_64-arista_7280cr3_32d4/plugins similarity index 100% rename from device/arista/x86_64-arista_7060_cx32s/plugins rename to device/arista/x86_64-arista_7280cr3_32d4/plugins diff --git a/device/arista/x86_64-arista_7280cr3_32d4/pmon_daemon_control.json b/device/arista/x86_64-arista_7280cr3_32d4/pmon_daemon_control.json new file mode 120000 index 000000000000..51d5ab7b0059 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32d4/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7280cr3_32d4/sensors.conf b/device/arista/x86_64-arista_7280cr3_32d4/sensors.conf new file mode 120000 index 000000000000..0b3f7a039764 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32d4/sensors.conf @@ -0,0 +1 @@ +../x86_64-arista_7280cr3_32p4/sensors.conf \ No newline at end of file diff --git a/device/arista/x86_64-arista_7280cr3_32d4/system_health_monitoring_config.json b/device/arista/x86_64-arista_7280cr3_32d4/system_health_monitoring_config.json new file mode 120000 index 000000000000..1185f771fa8e --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32d4/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-arista_common/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7280cr3_32d4/thermal_policy.json b/device/arista/x86_64-arista_7280cr3_32d4/thermal_policy.json new file mode 120000 index 000000000000..0991dc7f3638 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32d4/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-arista_common/thermal_policy.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/sai.profile b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/sai.profile index 7e699b10430e..f0554cdb874f 100644 --- a/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/sai.profile +++ b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/jr2-a7280cr3-32p4-28x100G-8x10G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/sai.profile b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/sai.profile index 130a3f8c4cbd..ac1394486c61 100644 --- a/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/sai.profile +++ b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/jr2-a7280cr3-32p4-40x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7280cr3_32p4/fancontrol b/device/arista/x86_64-arista_7280cr3_32p4/fancontrol index 1c0415b7e464..55a48e095084 100644 --- a/device/arista/x86_64-arista_7280cr3_32p4/fancontrol +++ b/device/arista/x86_64-arista_7280cr3_32p4/fancontrol @@ -1,7 +1,7 @@ INTERVAL=5 -DEVPATH=hwmon2=devices/pci0000:00/0000:00:09.0 hwmon4=devices/pci0000:00/0000:00:09.0/i2c-56/56-004c -DEVNAME=hwmon2=scd_fan_p3 hwmon4=max6658 -FCTEMPS=hwmon2/pwm6=hwmon4/temp1_input hwmon2/pwm5=hwmon4/temp1_input hwmon2/pwm4=hwmon4/temp1_input hwmon2/pwm4=hwmon4/temp1_input hwmon2/pwm2=hwmon4/temp1_input hwmon2/pwm1=hwmon4/temp1_input +DEVPATH=hwmon2=devices/pci0000:00/0000:00:09.0 hwmon3=devices/pci0000:00/0000:00:09.0/i2c-56/56-004c +DEVNAME=hwmon2=scd_fan_p3 hwmon3=max6658 +FCTEMPS=hwmon2/pwm6=hwmon3/temp1_input hwmon2/pwm5=hwmon3/temp1_input hwmon2/pwm4=hwmon3/temp1_input hwmon2/pwm3=hwmon3/temp1_input hwmon2/pwm2=hwmon3/temp1_input hwmon2/pwm1=hwmon3/temp1_input FCFANS=hwmon2/pwm6=hwmon2/fan6_input hwmon2/pwm5=hwmon2/fan5_input hwmon2/pwm4=hwmon2/fan4_input hwmon2/pwm3=hwmon2/fan3_input hwmon2/pwm2=hwmon2/fan2_input hwmon2/pwm1=hwmon2/fan1_input MINTEMP=hwmon2/pwm6=50 hwmon2/pwm5=50 hwmon2/pwm4=50 hwmon2/pwm3=50 hwmon2/pwm2=50 hwmon2/pwm1=50 MINPWM=hwmon2/pwm6=128 hwmon2/pwm5=128 hwmon2/pwm4=128 hwmon2/pwm3=128 hwmon2/pwm2=128 hwmon2/pwm1=128 diff --git a/device/arista/x86_64-arista_7280cr3_32p4/platform.json b/device/arista/x86_64-arista_7280cr3_32p4/platform.json new file mode 100644 index 000000000000..ebde92784715 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32p4/platform.json @@ -0,0 +1,207 @@ +{ + "chassis": { + "name": "DCS-7280CR3K-32P4", + "components": [], + "fans": [], + "fan_drawers": [ + { + "name": "slot1", + "fans": [ + { + "name": "fan1" + }, + { + "name": "fan2" + } + ] + }, + { + "name": "slot2", + "fans": [ + { + "name": "fan3" + }, + { + "name": "fan4" + } + ] + }, + { + "name": "slot3", + "fans": [ + { + "name": "fan5" + }, + { + "name": "fan6" + } + ] + } + ], + "psus": [ + { + "name": "psu1", + "fans": [] + }, + { + "name": "psu2", + "fans": [] + } + ], + "thermals": [ + { + "name": "Cpu temp sensor" + }, + { + "name": "CPU board temp sensor" + }, + { + "name": "Back-panel temp sensor" + }, + { + "name": "Board Sensor" + }, + { + "name": "Front Air" + }, + { + "name": "Rear Air" + }, + { + "name": "Fap 0 Core 0" + }, + { + "name": "Fap 0 Core 1" + }, + { + "name": "Power supply 1 inlet temp sensor" + }, + { + "name": "Power supply 1 secondary hotspot sensor" + }, + { + "name": "Power supply 1 primary hotspot sensor" + }, + { + "name": "Power supply 2 inlet temp sensor" + }, + { + "name": "Power supply 2 secondary hotspot sensor" + }, + { + "name": "Power supply 2 primary hotspot sensor" + } + ], + "sfps": [ + { + "name": "qsfp1" + }, + { + "name": "qsfp2" + }, + { + "name": "qsfp3" + }, + { + "name": "qsfp4" + }, + { + "name": "qsfp5" + }, + { + "name": "qsfp6" + }, + { + "name": "qsfp7" + }, + { + "name": "qsfp8" + }, + { + "name": "qsfp9" + }, + { + "name": "qsfp10" + }, + { + "name": "qsfp11" + }, + { + "name": "qsfp12" + }, + { + "name": "qsfp13" + }, + { + "name": "qsfp14" + }, + { + "name": "qsfp15" + }, + { + "name": "qsfp16" + }, + { + "name": "qsfp17" + }, + { + "name": "qsfp18" + }, + { + "name": "qsfp19" + }, + { + "name": "qsfp20" + }, + { + "name": "qsfp21" + }, + { + "name": "qsfp22" + }, + { + "name": "qsfp23" + }, + { + "name": "qsfp24" + }, + { + "name": "qsfp25" + }, + { + "name": "qsfp26" + }, + { + "name": "qsfp27" + }, + { + "name": "qsfp28" + }, + { + "name": "qsfp29" + }, + { + "name": "qsfp30" + }, + { + "name": "qsfp31" + }, + { + "name": "qsfp32" + }, + { + "name": "osfp33" + }, + { + "name": "osfp34" + }, + { + "name": "osfp35" + }, + { + "name": "osfp36" + } + ] + }, + "interfaces": {} +} diff --git a/device/arista/x86_64-arista_7280cr3_32p4/pmon_daemon_control.json b/device/arista/x86_64-arista_7280cr3_32p4/pmon_daemon_control.json new file mode 120000 index 000000000000..51d5ab7b0059 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32p4/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7280cr3_32p4/system_health_monitoring_config.json b/device/arista/x86_64-arista_7280cr3_32p4/system_health_monitoring_config.json new file mode 120000 index 000000000000..1185f771fa8e --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32p4/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-arista_common/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7280cr3_32p4/thermal_policy.json b/device/arista/x86_64-arista_7280cr3_32p4/thermal_policy.json new file mode 120000 index 000000000000..0991dc7f3638 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32p4/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-arista_common/thermal_policy.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7280cr3k_32d4 b/device/arista/x86_64-arista_7280cr3k_32d4 new file mode 120000 index 000000000000..50478132d933 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3k_32d4 @@ -0,0 +1 @@ +x86_64-arista_7280cr3_32d4 \ No newline at end of file diff --git a/device/arista/x86_64-arista_7800_sup/chassisdb.conf b/device/arista/x86_64-arista_7800_sup/chassisdb.conf new file mode 100644 index 000000000000..3918a00c4ee9 --- /dev/null +++ b/device/arista/x86_64-arista_7800_sup/chassisdb.conf @@ -0,0 +1,2 @@ +start_chassis_db=1 +chassis_db_address=127.100.1.1 diff --git a/device/arista/x86_64-arista_7800_sup/platform_reboot b/device/arista/x86_64-arista_7800_sup/platform_reboot new file mode 120000 index 000000000000..7f94a49e38b0 --- /dev/null +++ b/device/arista/x86_64-arista_7800_sup/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_7800_sup/plugins b/device/arista/x86_64-arista_7800_sup/plugins new file mode 120000 index 000000000000..789a45fcace9 --- /dev/null +++ b/device/arista/x86_64-arista_7800_sup/plugins @@ -0,0 +1 @@ +../x86_64-arista_common/plugins \ No newline at end of file diff --git a/device/arista/x86_64-arista_7800_sup/pmon_daemon_control.json b/device/arista/x86_64-arista_7800_sup/pmon_daemon_control.json new file mode 100644 index 000000000000..fbec8f525160 --- /dev/null +++ b/device/arista/x86_64-arista_7800_sup/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_ledd": true, + "skip_xcvrd": true +} diff --git a/device/arista/x86_64-arista_7800_sup/system_health_monitoring_config.json b/device/arista/x86_64-arista_7800_sup/system_health_monitoring_config.json new file mode 120000 index 000000000000..1185f771fa8e --- /dev/null +++ b/device/arista/x86_64-arista_7800_sup/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-arista_common/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7800r3_48cq2_lc/chassisdb.conf b/device/arista/x86_64-arista_7800r3_48cq2_lc/chassisdb.conf new file mode 100644 index 000000000000..75dc7d65703b --- /dev/null +++ b/device/arista/x86_64-arista_7800r3_48cq2_lc/chassisdb.conf @@ -0,0 +1 @@ +chassis_db_address=127.100.1.1 diff --git a/device/arista/x86_64-arista_7260cx3_64/plugins b/device/arista/x86_64-arista_7800r3_48cq2_lc/plugins similarity index 100% rename from device/arista/x86_64-arista_7260cx3_64/plugins rename to device/arista/x86_64-arista_7800r3_48cq2_lc/plugins diff --git a/src/sonic-daemon-base/sonic_daemon_base/__init__.py b/device/arista/x86_64-arista_7800r3_48cq2_lc/sensors.conf similarity index 100% rename from src/sonic-daemon-base/sonic_daemon_base/__init__.py rename to device/arista/x86_64-arista_7800r3_48cq2_lc/sensors.conf diff --git a/device/arista/x86_64-arista_7800r3_48cq2_lc/system_health_monitoring_config.json b/device/arista/x86_64-arista_7800r3_48cq2_lc/system_health_monitoring_config.json new file mode 120000 index 000000000000..1185f771fa8e --- /dev/null +++ b/device/arista/x86_64-arista_7800r3_48cq2_lc/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-arista_common/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7800r3_48cqm2_lc/plugins b/device/arista/x86_64-arista_7800r3_48cqm2_lc/plugins new file mode 120000 index 000000000000..5fbbf98a6284 --- /dev/null +++ b/device/arista/x86_64-arista_7800r3_48cqm2_lc/plugins @@ -0,0 +1 @@ +../x86_64-arista_common/plugins/ \ No newline at end of file diff --git a/device/arista/x86_64-arista_7800r3_48cqm2_lc/sensors.conf b/device/arista/x86_64-arista_7800r3_48cqm2_lc/sensors.conf new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/device/arista/x86_64-arista_7800r3_48cqm2_lc/system_health_monitoring_config.json b/device/arista/x86_64-arista_7800r3_48cqm2_lc/system_health_monitoring_config.json new file mode 120000 index 000000000000..1185f771fa8e --- /dev/null +++ b/device/arista/x86_64-arista_7800r3_48cqm2_lc/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-arista_common/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_common/platform_reboot b/device/arista/x86_64-arista_common/platform_reboot index b8b1a5d7bfe5..1c3f954c03cc 100755 --- a/device/arista/x86_64-arista_common/platform_reboot +++ b/device/arista/x86_64-arista_common/platform_reboot @@ -1,11 +1,13 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import arista.platforms from arista.utils.sonic_reboot import reboot + def main(): - # reboot the system - reboot() + # reboot the system + reboot() + if __name__ == "__main__": - main() + main() diff --git a/device/arista/x86_64-arista_common/plugins/eeprom.py b/device/arista/x86_64-arista_common/plugins/eeprom.py index 5c0286979056..3cc5a6b13c59 100644 --- a/device/arista/x86_64-arista_common/plugins/eeprom.py +++ b/device/arista/x86_64-arista_common/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - # # Arista eeprom processing for SONiC # Uses the arista driver library to obtain the TlvInfoDecoder diff --git a/device/arista/x86_64-arista_common/plugins/led_control.py b/device/arista/x86_64-arista_common/plugins/led_control.py index febb04ad1616..8ea9f70a8604 100644 --- a/device/arista/x86_64-arista_common/plugins/led_control.py +++ b/device/arista/x86_64-arista_common/plugins/led_control.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - # # Arista LED controls for SONiC # diff --git a/device/arista/x86_64-arista_common/plugins/psuutil.py b/device/arista/x86_64-arista_common/plugins/psuutil.py index 46ec6b32e2e4..14755365257b 100644 --- a/device/arista/x86_64-arista_common/plugins/psuutil.py +++ b/device/arista/x86_64-arista_common/plugins/psuutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - # # Arista PSU interface for SONiC # diff --git a/device/arista/x86_64-arista_common/plugins/sfputil.py b/device/arista/x86_64-arista_common/plugins/sfputil.py index 5e02eef69aef..4c99ad533f27 100644 --- a/device/arista/x86_64-arista_common/plugins/sfputil.py +++ b/device/arista/x86_64-arista_common/plugins/sfputil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - # # Arista SFP transceiver interface for SONiC # diff --git a/device/arista/x86_64-arista_common/pmon_daemon_control.json b/device/arista/x86_64-arista_common/pmon_daemon_control.json new file mode 100644 index 000000000000..6453cd2c5d0d --- /dev/null +++ b/device/arista/x86_64-arista_common/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_fancontrol": true +} + diff --git a/device/arista/x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json b/device/arista/x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json new file mode 100644 index 000000000000..75db6d97558a --- /dev/null +++ b/device/arista/x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json @@ -0,0 +1,4 @@ +{ + "skip_thermalctld": true +} + diff --git a/device/arista/x86_64-arista_common/system_health_monitoring_config.json b/device/arista/x86_64-arista_common/system_health_monitoring_config.json new file mode 100644 index 000000000000..1733fcffdba3 --- /dev/null +++ b/device/arista/x86_64-arista_common/system_health_monitoring_config.json @@ -0,0 +1,16 @@ +{ + "services_to_ignore": [], + "devices_to_ignore": [ + "asic", + "psu.temperature", + "PSU2 Fan", + "PSU1 Fan" + ], + "user_defined_checkers": [], + "polling_interval": 60, + "led_color": { + "fault": "orange", + "normal": "green", + "booting": "orange_blink" + } +} diff --git a/device/arista/x86_64-arista_common/thermal_policy.json b/device/arista/x86_64-arista_common/thermal_policy.json new file mode 100644 index 000000000000..bc1bd0acfad0 --- /dev/null +++ b/device/arista/x86_64-arista_common/thermal_policy.json @@ -0,0 +1,60 @@ +{ + "thermal_control_algorithm": { + "run_at_boot_up": "true", + "fan_speed_when_suspend": "100" + }, + "info_types": [ + { + "type": "control_info" + }, + { + "type": "fan_info" + }, + { + "type": "thermal_info" + } + ], + "policies": [ + { + "name": "any thermal critical", + "conditions": [ + { + "type": "thermal.any.critical" + } + ], + "actions": [ + { + "type": "fan.all.set_speed", + "speed": "100" + } + ] + }, + { + "name": "any thermal overheat", + "conditions": [ + { + "type": "thermal.any.overheat" + } + ], + "actions": [ + { + "type": "fan.all.set_speed", + "speed": "100" + } + ] + }, + { + "name": "normal operations", + "conditions": [ + { + "type": "normal" + } + ], + "actions": [ + { + "type": "thermal_control.control" + } + ] + } + ] +} diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/default_sku b/device/barefoot/x86_64-accton_as9516_32d-r0/default_sku similarity index 100% rename from device/barefoot/x86_64-accton_as9516bf_32d-r0/default_sku rename to device/barefoot/x86_64-accton_as9516_32d-r0/default_sku diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/installer.conf b/device/barefoot/x86_64-accton_as9516_32d-r0/installer.conf similarity index 100% rename from device/barefoot/x86_64-accton_as9516bf_32d-r0/installer.conf rename to device/barefoot/x86_64-accton_as9516_32d-r0/installer.conf diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers.json.j2 b/device/barefoot/x86_64-accton_as9516_32d-r0/newport/buffers.json.j2 similarity index 100% rename from device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers.json.j2 rename to device/barefoot/x86_64-accton_as9516_32d-r0/newport/buffers.json.j2 diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers_defaults_t0.j2 b/device/barefoot/x86_64-accton_as9516_32d-r0/newport/buffers_defaults_t0.j2 similarity index 100% rename from device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers_defaults_t0.j2 rename to device/barefoot/x86_64-accton_as9516_32d-r0/newport/buffers_defaults_t0.j2 diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers_defaults_t1.j2 b/device/barefoot/x86_64-accton_as9516_32d-r0/newport/buffers_defaults_t1.j2 similarity index 100% rename from device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers_defaults_t1.j2 rename to device/barefoot/x86_64-accton_as9516_32d-r0/newport/buffers_defaults_t1.j2 diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/pg_profile_lookup.ini b/device/barefoot/x86_64-accton_as9516_32d-r0/newport/pg_profile_lookup.ini similarity index 100% rename from device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/pg_profile_lookup.ini rename to device/barefoot/x86_64-accton_as9516_32d-r0/newport/pg_profile_lookup.ini diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/port_config.ini b/device/barefoot/x86_64-accton_as9516_32d-r0/newport/port_config.ini similarity index 100% rename from device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/port_config.ini rename to device/barefoot/x86_64-accton_as9516_32d-r0/newport/port_config.ini diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/qos.json.j2 b/device/barefoot/x86_64-accton_as9516_32d-r0/newport/qos.json.j2 similarity index 100% rename from device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/qos.json.j2 rename to device/barefoot/x86_64-accton_as9516_32d-r0/newport/qos.json.j2 diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/sai.profile b/device/barefoot/x86_64-accton_as9516_32d-r0/newport/sai.profile similarity index 100% rename from device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/sai.profile rename to device/barefoot/x86_64-accton_as9516_32d-r0/newport/sai.profile diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/switch-tna-sai.conf b/device/barefoot/x86_64-accton_as9516_32d-r0/newport/switch-tna-sai.conf similarity index 100% rename from device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/switch-tna-sai.conf rename to device/barefoot/x86_64-accton_as9516_32d-r0/newport/switch-tna-sai.conf diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/plugins b/device/barefoot/x86_64-accton_as9516_32d-r0/plugins similarity index 100% rename from device/barefoot/x86_64-accton_as9516bf_32d-r0/plugins rename to device/barefoot/x86_64-accton_as9516_32d-r0/plugins diff --git a/device/barefoot/x86_64-accton_as9516_32d-r0/pmon_daemon_control.json b/device/barefoot/x86_64-accton_as9516_32d-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..c4573af5e93d --- /dev/null +++ b/device/barefoot/x86_64-accton_as9516_32d-r0/pmon_daemon_control.json @@ -0,0 +1,9 @@ +{ + "skip_pcied": false, + "skip_fancontrol": true, + "skip_thermalctld": true, + "skip_ledd": true, + "skip_xcvrd": false, + "skip_psud": false, + "skip_syseepromd": false +} diff --git a/device/barefoot/x86_64-accton_as9516_32d-r0/syncd.conf b/device/barefoot/x86_64-accton_as9516_32d-r0/syncd.conf new file mode 100644 index 000000000000..11956f83a5af --- /dev/null +++ b/device/barefoot/x86_64-accton_as9516_32d-r0/syncd.conf @@ -0,0 +1,29 @@ +#!/bin/bash + + +y_profile_set() { + P4_PROFILE=$(sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["p4_profile"]') + if [[ -n "$P4_PROFILE" || ( ! -L /opt/bfn/install && -e /opt/bfn/install ) ]]; then + return + fi + + if [[ $(readlink /opt/bfn/install) =~ "install_y" ]]; then + echo "/opt/bfn/install is a link to Y profile" + return + fi + + Y_PROFILE=$(ls -d /opt/bfn/install_y*_profile 2> /dev/null | head -1) + if [[ -z $Y_PROFILE ]]; then + echo "No P4 profile found for Newport" + return + fi + + echo "Link /opt/bfn/install to $Y_PROFILE" + ln -srfn $Y_PROFILE /opt/bfn/install +} + +( + unset PYTHONPATH + unset PYTHONHOME + y_profile_set +) diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0 b/device/barefoot/x86_64-accton_as9516bf_32d-r0 new file mode 120000 index 000000000000..93f47d51b742 --- /dev/null +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0 @@ -0,0 +1 @@ +x86_64-accton_as9516_32d-r0 \ No newline at end of file diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/pmon_daemon_control.json b/device/barefoot/x86_64-accton_as9516bf_32d-r0/pmon_daemon_control.json deleted file mode 100644 index 3a76f2fdd0e4..000000000000 --- a/device/barefoot/x86_64-accton_as9516bf_32d-r0/pmon_daemon_control.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "skip_ledd": true, - "skip_xcvrd": false, - "skip_psud": false, - "skip_syseepromd": false -} diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/hwsku.json b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/hwsku.json new file mode 100644 index 000000000000..a253fa3bd480 --- /dev/null +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/hwsku.json @@ -0,0 +1,164 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet4": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet8": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet12": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet16": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet20": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet24": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet28": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet32": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet36": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet40": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet44": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet48": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet52": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet56": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet60": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet64": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet68": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet72": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet76": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet80": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet84": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet88": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet92": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet96": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet100": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet104": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet108": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet112": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet116": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet120": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet124": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + } + } +} diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/platform.json b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/platform.json new file mode 100644 index 000000000000..0b68edf1610c --- /dev/null +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/platform.json @@ -0,0 +1,196 @@ +{ + "interfaces": { + "Ethernet0": { + "index": "1,1,1,1", + "lanes": "0,1,2,3", + "alias_at_lanes": "Ethernet0,Ethernet1,Ethernet2,Ethernet3", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet4": { + "index": "2,2,2,2", + "lanes": "4,5,6,7", + "alias_at_lanes": "Ethernet4,Ethernet5,Ethernet6,Ethernet7", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet8": { + "index": "3,3,3,3", + "lanes": "8,9,10,11", + "alias_at_lanes": "Ethernet8,Ethernet9,Ethernet10,Ethernet11", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet12": { + "index": "4,4,4,4", + "lanes": "12,13,14,15", + "alias_at_lanes": "Ethernet12,Ethernet13,Ethernet14,Ethernet15", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet16": { + "index": "5,5,5,5", + "lanes": "16,17,18,19", + "alias_at_lanes": "Ethernet16,Ethernet17,Ethernet18,Ethernet19", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet20": { + "index": "6,6,6,6", + "lanes": "20,21,22,23", + "alias_at_lanes": "Ethernet20,Ethernet21,Ethernet22,Ethernet23", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet24": { + "index": "7,7,7,7", + "lanes": "24,25,26,27", + "alias_at_lanes": "Ethernet24,Ethernet25,Ethernet26,Ethernet27", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet28": { + "index": "8,8,8,8", + "lanes": "28,29,30,31", + "alias_at_lanes": "Ethernet28,Ethernet29,Ethernet30,Ethernet31", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet32": { + "index": "9,9,9,9", + "lanes": "32,33,34,35", + "alias_at_lanes": "Ethernet32,Ethernet33,Ethernet34,Ethernet35", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet36": { + "index": "10,10,10,10", + "lanes": "36,37,38,39", + "alias_at_lanes": "Ethernet36,Ethernet37,Ethernet38,Ethernet39", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet40": { + "index": "11,11,11,11", + "lanes": "40,41,42,43", + "alias_at_lanes": "Ethernet40,Ethernet41,Ethernet42,Ethernet43", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet44": { + "index": "12,12,12,12", + "lanes": "44,45,46,47", + "alias_at_lanes": "Ethernet44,Ethernet45,Ethernet46,Ethernet47", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet48": { + "index": "13,13,13,13", + "lanes": "48,49,50,51", + "alias_at_lanes": "Ethernet48,Ethernet49,Ethernet50,Ethernet51", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet52": { + "index": "14,14,14,14", + "lanes": "52,53,54,55", + "alias_at_lanes": "Ethernet52,Ethernet53,Ethernet54,Ethernet55", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet56": { + "index": "15,15,15,15", + "lanes": "56,57,58,59", + "alias_at_lanes": "Ethernet56,Ethernet57,Ethernet58,Ethernet59", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet60": { + "index": "16,16,16,16", + "lanes": "60,61,62,63", + "alias_at_lanes": "Ethernet60,Ethernet61,Ethernet62,Ethernet63", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet64": { + "index": "17,17,17,17", + "lanes": "64,65,66,67", + "alias_at_lanes": "Ethernet64,Ethernet65,Ethernet66,Ethernet67", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet68": { + "index": "18,18,18,18", + "lanes": "68,69,70,71", + "alias_at_lanes": "Ethernet68,Ethernet69,Ethernet70,Ethernet71", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet72": { + "index": "19,19,19,19", + "lanes": "72,73,74,75", + "alias_at_lanes": "Ethernet72,Ethernet73,Ethernet74,Ethernet75", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet76": { + "index": "20,20,20,20", + "lanes": "76,77,78,79", + "alias_at_lanes": "Ethernet76,Ethernet77,Ethernet78,Ethernet79", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet80": { + "index": "21,21,21,21", + "lanes": "80,81,82,83", + "alias_at_lanes": "Ethernet80,Ethernet81,Ethernet82,Ethernet83", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet84": { + "index": "22,22,22,22", + "lanes": "84,85,86,87", + "alias_at_lanes": "Ethernet84,Ethernet85,Ethernet86,Ethernet87", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet88": { + "index": "23,23,23,23", + "lanes": "88,89,90,91", + "alias_at_lanes": "Ethernet88,Ethernet89,Ethernet90,Ethernet91", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet92": { + "index": "24,24,24,24", + "lanes": "92,93,94,95", + "alias_at_lanes": "Ethernet92,Ethernet93,Ethernet94,Ethernet95", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet96": { + "index": "25,25,25,25", + "lanes": "96,97,98,99", + "alias_at_lanes": "Ethernet96,Ethernet97,Ethernet98,Ethernet99", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet100": { + "index": "26,26,26,26", + "lanes": "100,101,102,103", + "alias_at_lanes": "Ethernet100,Ethernet101,Ethernet102,Ethernet103", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet104": { + "index": "27,27,27,27", + "lanes": "104,105,106,107", + "alias_at_lanes": "Ethernet104,Ethernet105,Ethernet106,Ethernet107", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet108": { + "index": "28,28,28,28", + "lanes": "108,109,110,111", + "alias_at_lanes": "Ethernet108,Ethernet109,Ethernet110,Ethernet111", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet112": { + "index": "29,29,29,29", + "lanes": "112,113,114,115", + "alias_at_lanes": "Ethernet112,Ethernet113,Ethernet114,Ethernet115", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet116": { + "index": "30,30,30,30", + "lanes": "116,117,118,119", + "alias_at_lanes": "Ethernet116,Ethernet117,Ethernet118,Ethernet119", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet120": { + "index": "31,31,31,31", + "lanes": "120,121,122,123", + "alias_at_lanes": "Ethernet120,Ethernet121,Ethernet122,Ethernet123", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet124": { + "index": "32,32,32,32", + "lanes": "124,125,126,127", + "alias_at_lanes": "Ethernet124,Ethernet125,Ethernet126,Ethernet127", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + } + } +} diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/eeprom.py b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/eeprom.py index 9c14441475d4..b94fab471b95 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/eeprom.py +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/eeprom.py @@ -1,6 +1,3 @@ -#!/usr/bin/python - - try: import importlib import time @@ -23,52 +20,63 @@ from thrift.protocol import TMultiplexedProtocol from argparse import ArgumentParser - from cStringIO import StringIO + + if sys.version_info.major == 3: + from io import StringIO + else: + from cStringIO import StringIO + from sonic_eeprom import eeprom_base from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +if sys.version_info.major == 3: + STRING_TYPE = str +else: + STRING_TYPE = basestring eeprom_default_dict = { - "prod_name" : ("Product Name", "0x21", 12), - "odm_pcba_part_num" : ("Part Number", "0x22", 13), - "prod_ser_num" : ("Serial Number", "0x23", 12), - "ext_mac_addr" : ("Extended MAC Address Base", "0x24", 12), - "sys_mfg_date" : ("System Manufacturing Date", "0x25", 4), - "prod_ver" : ("Product Version", "0x26", 1), - "ext_mac_addr_size" : ("Extende MAC Address Size", "0x2A", 2), - "sys_mfger" : ("Manufacturer", "0x2B", 8) + "prod_name": ("Product Name", "0x21", 12), + "odm_pcba_part_num": ("Part Number", "0x22", 13), + "prod_ser_num": ("Serial Number", "0x23", 12), + "ext_mac_addr": ("Extended MAC Address Base", "0x24", 12), + "sys_mfg_date": ("System Manufacturing Date", "0x25", 4), + "prod_ver": ("Product Version", "0x26", 1), + "ext_mac_addr_size": ("Extende MAC Address Size", "0x2A", 2), + "sys_mfger": ("Manufacturer", "0x2B", 8) } -eeprom_dict = { "version" : ("Version", None, 0), - "pcb_mfger" : ("PCB Manufacturer", "0x01", 8), - "prod_ser_num" : ("Serial Number", "0x23", 12), - "bfn_pcba_part_num" : ("Switch PCBA Part Number", "0x02", 12), - "odm_pcba_part_num" : ("Part Number", "0x22", 13), - "bfn_pcbb_part_num" : ("Switch PCBB Part Number", "0x04", 12), - "sys_asm_part_num" : ("System Assembly Part Number", "0x05", 12), - "prod_state" : ("Product Production State", "0x06", 1), - "location" : ("EEPROM Location of Fabric", "0x07", 8), - "ext_mac_addr_size" : ("Extende MAC Address Size", "0x08", 2), - "sys_mfg_date" : ("System Manufacturing Date", "0x25", 4), - "prod_name" : ("Product Name", "0x21", 12), - "prod_ver" : ("Product Version", "0x26", 1), - "prod_part_num" : ("Product Part Number", "0x09", 8), - "sys_mfger" : ("Manufacturer", "0x2B", 8), - "assembled_at" : ("Assembled at", "0x08", 8), - "prod_ast_tag" : ("Product Asset Tag", "0x09", 12), - "loc_mac_addr" : ("Local MAC address", "0x0A", 12), - "odm_pcba_ser_num" : ("ODM PBCA Serial Number", "0x0B", 12), - "ext_mac_addr" : ("Extended MAC Address Base", "0x0C", 12), - "prod_sub_ver" : ("Product Sub Version", "0x0D", 1) - } - -product_dict = { "Montara" : "Wedge100BF-32X-O-AC-F-BF", - "Lower MAV" : "Wedge100BF-65X-O-AC-F-BF", - "Upper MAV" : "Wedge100BF-65X-O-AC-F-BF" +eeprom_dict = {"version": ("Version", None, 0), + "pcb_mfger": ("PCB Manufacturer", "0x01", 8), + "prod_ser_num": ("Serial Number", "0x23", 12), + "bfn_pcba_part_num": ("Switch PCBA Part Number", "0x02", 12), + "odm_pcba_part_num": ("Part Number", "0x22", 13), + "bfn_pcbb_part_num": ("Switch PCBB Part Number", "0x04", 12), + "sys_asm_part_num": ("System Assembly Part Number", "0x05", 12), + "prod_state": ("Product Production State", "0x06", 1), + "location": ("EEPROM Location of Fabric", "0x07", 8), + "ext_mac_addr_size": ("Extende MAC Address Size", "0x08", 2), + "sys_mfg_date": ("System Manufacturing Date", "0x25", 4), + "prod_name": ("Product Name", "0x21", 12), + "prod_ver": ("Product Version", "0x26", 1), + "prod_part_num": ("Product Part Number", "0x09", 8), + "sys_mfger": ("Manufacturer", "0x2B", 8), + "assembled_at": ("Assembled at", "0x08", 8), + "prod_ast_tag": ("Product Asset Tag", "0x09", 12), + "loc_mac_addr": ("Local MAC address", "0x0A", 12), + "odm_pcba_ser_num": ("ODM PBCA Serial Number", "0x0B", 12), + "ext_mac_addr": ("Extended MAC Address Base", "0x0C", 12), + "prod_sub_ver": ("Product Sub Version", "0x0D", 1) } +product_dict = {"Montara": "Wedge100BF-32X-O-AC-F-BF", + "Lower MAV": "Wedge100BF-65X-O-AC-F-BF", + "Upper MAV": "Wedge100BF-65X-O-AC-F-BF" + } + thrift_server = 'localhost' transport = None pltfm_mgr = None @@ -76,13 +84,14 @@ EEPROM_SYMLINK = "/var/run/platform/eeprom/syseeprom" EEPROM_STATUS = "/var/run/platform/eeprom/status" + class board(eeprom_tlvinfo.TlvInfoDecoder): - RETRIES = 3 + RETRIES = 35 def __init__(self, name, path, cpld_root, ro): with open(os.path.dirname(__file__) + "/logging.conf", 'r') as f: - config_dict = yaml.load(f) + config_dict = yaml.load(f, yaml.SafeLoader) logging.config.dictConfig(config_dict) if not os.path.exists(os.path.dirname(EEPROM_SYMLINK)): @@ -101,8 +110,10 @@ def __init__(self, name, path, cpld_root, ro): super(board, self).__init__(self.eeprom_path, 0, EEPROM_STATUS, True) for attempt in range(self.RETRIES): - if self.eeprom_init() or (attempt + 1 >= self.RETRIES): + if self.eeprom_init(): break + if attempt + 1 == self.RETRIES: + raise RuntimeError("eeprom.py: Initialization failed") time.sleep(1) def thrift_setup(self): @@ -112,8 +123,10 @@ def thrift_setup(self): transport = TTransport.TBufferedTransport(transport) bprotocol = TBinaryProtocol.TBinaryProtocol(transport) - pltfm_mgr_client_module = importlib.import_module(".".join(["pltfm_mgr_rpc", "pltfm_mgr_rpc"])) - pltfm_mgr_protocol = TMultiplexedProtocol.TMultiplexedProtocol(bprotocol, "pltfm_mgr_rpc") + pltfm_mgr_client_module = importlib.import_module( + ".".join(["pltfm_mgr_rpc", "pltfm_mgr_rpc"])) + pltfm_mgr_protocol = TMultiplexedProtocol.TMultiplexedProtocol( + bprotocol, "pltfm_mgr_rpc") pltfm_mgr = pltfm_mgr_client_module.Client(pltfm_mgr_protocol) transport.open() @@ -137,7 +150,7 @@ def eeprom_init(self): f.close() eeprom_params = "" - for attr, val in eeprom.__dict__.iteritems(): + for attr, val in eeprom.__dict__.items(): if val is None: continue @@ -145,13 +158,14 @@ def eeprom_init(self): if elem is None: continue - if isinstance(val, basestring): + if isinstance(val, STRING_TYPE): value = val.replace('\0', '') else: value = str(val) if attr == "sys_mfg_date": - value = datetime.datetime.strptime(value, '%m-%d-%y').strftime('%m/%d/%Y 00:00:00') + value = datetime.datetime.strptime( + value, '%m-%d-%y').strftime('%m/%d/%Y 00:00:00') product = product_dict.get(value) if product is not None: @@ -162,9 +176,9 @@ def eeprom_init(self): orig_stdout = sys.stdout sys.stdout = StringIO() - new_e = eeprom_tlvinfo.TlvInfoDecoder.set_eeprom(self, "", [eeprom_params]) + new_e = eeprom_tlvinfo.TlvInfoDecoder.set_eeprom( + self, "", [eeprom_params]) sys.stdout = orig_stdout eeprom_base.EepromDecoder.write_eeprom(self, new_e) return True - 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'] diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/pltfm_mgr_rpc/pltfm_mgr_rpc.py b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/pltfm_mgr_rpc/pltfm_mgr_rpc.py index b256b6285fc3..8f5b89e4312a 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/pltfm_mgr_rpc/pltfm_mgr_rpc.py +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/pltfm_mgr_rpc/pltfm_mgr_rpc.py @@ -177,7 +177,8 @@ def recv_pltfm_mgr_sys_tmp_get(self): return result.success if result.ouch is not None: raise result.ouch - raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_sys_tmp_get failed: unknown result") + raise TApplicationException(TApplicationException.MISSING_RESULT, + "pltfm_mgr_sys_tmp_get failed: unknown result") def pltfm_mgr_sys_eeprom_get(self): self.send_pltfm_mgr_sys_eeprom_get() @@ -205,7 +206,8 @@ def recv_pltfm_mgr_sys_eeprom_get(self): return result.success if result.ouch is not None: raise result.ouch - raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_sys_eeprom_get failed: unknown result") + raise TApplicationException(TApplicationException.MISSING_RESULT, + "pltfm_mgr_sys_eeprom_get failed: unknown result") def pltfm_mgr_pwr_supply_present_get(self, ps_num): """ @@ -238,7 +240,8 @@ def recv_pltfm_mgr_pwr_supply_present_get(self): return result.success if result.ouch is not None: raise result.ouch - raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_pwr_supply_present_get failed: unknown result") + raise TApplicationException(TApplicationException.MISSING_RESULT, + "pltfm_mgr_pwr_supply_present_get failed: unknown result") def pltfm_mgr_pwr_supply_info_get(self, ps_num): """ @@ -271,7 +274,8 @@ def recv_pltfm_mgr_pwr_supply_info_get(self): return result.success if result.ouch is not None: raise result.ouch - raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_pwr_supply_info_get failed: unknown result") + raise TApplicationException(TApplicationException.MISSING_RESULT, + "pltfm_mgr_pwr_supply_info_get failed: unknown result") def pltfm_mgr_pwr_rail_info_get(self, ps_num): """ @@ -304,7 +308,8 @@ def recv_pltfm_mgr_pwr_rail_info_get(self): return result.success if result.ouch is not None: raise result.ouch - raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_pwr_rail_info_get failed: unknown result") + raise TApplicationException(TApplicationException.MISSING_RESULT, + "pltfm_mgr_pwr_rail_info_get failed: unknown result") def pltfm_mgr_fan_speed_set(self, fan_num, percent): """ @@ -339,7 +344,8 @@ def recv_pltfm_mgr_fan_speed_set(self): return result.success if result.ouch is not None: raise result.ouch - raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_fan_speed_set failed: unknown result") + raise TApplicationException(TApplicationException.MISSING_RESULT, + "pltfm_mgr_fan_speed_set failed: unknown result") def pltfm_mgr_fan_info_get(self, fan_num): """ @@ -372,7 +378,8 @@ def recv_pltfm_mgr_fan_info_get(self): return result.success if result.ouch is not None: raise result.ouch - raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_fan_info_get failed: unknown result") + raise TApplicationException(TApplicationException.MISSING_RESULT, + "pltfm_mgr_fan_info_get failed: unknown result") def pltfm_mgr_qsfp_presence_get(self, port_num): """ @@ -405,7 +412,8 @@ def recv_pltfm_mgr_qsfp_presence_get(self): return result.success if result.ouch is not None: raise result.ouch - raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_qsfp_presence_get failed: unknown result") + raise TApplicationException(TApplicationException.MISSING_RESULT, + "pltfm_mgr_qsfp_presence_get failed: unknown result") def pltfm_mgr_qsfp_info_get(self, port_num): """ @@ -438,7 +446,8 @@ def recv_pltfm_mgr_qsfp_info_get(self): return result.success if result.ouch is not None: raise result.ouch - raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_qsfp_info_get failed: unknown result") + raise TApplicationException(TApplicationException.MISSING_RESULT, + "pltfm_mgr_qsfp_info_get failed: unknown result") def pltfm_mgr_qsfp_get_max_port(self): self.send_pltfm_mgr_qsfp_get_max_port() @@ -466,7 +475,8 @@ def recv_pltfm_mgr_qsfp_get_max_port(self): return result.success if result.ouch is not None: raise result.ouch - raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_qsfp_get_max_port failed: unknown result") + raise TApplicationException(TApplicationException.MISSING_RESULT, + "pltfm_mgr_qsfp_get_max_port failed: unknown result") def pltfm_mgr_qsfp_reset(self, port_num, reset): """ @@ -534,7 +544,8 @@ def recv_pltfm_mgr_qsfp_lpmode_get(self): return result.success if result.ouch is not None: raise result.ouch - raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_qsfp_lpmode_get failed: unknown result") + raise TApplicationException(TApplicationException.MISSING_RESULT, + "pltfm_mgr_qsfp_lpmode_get failed: unknown result") def pltfm_mgr_qsfp_lpmode_set(self, port_num, lpmode): """ @@ -569,7 +580,8 @@ def recv_pltfm_mgr_qsfp_lpmode_set(self): return result.success if result.ouch is not None: raise result.ouch - raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_qsfp_lpmode_set failed: unknown result") + raise TApplicationException(TApplicationException.MISSING_RESULT, + "pltfm_mgr_qsfp_lpmode_set failed: unknown result") def pltfm_mgr_sensor_info_get(self, options): """ @@ -602,7 +614,8 @@ def recv_pltfm_mgr_sensor_info_get(self): return result.success if result.ouch is not None: raise result.ouch - raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_sensor_info_get failed: unknown result") + raise TApplicationException(TApplicationException.MISSING_RESULT, + "pltfm_mgr_sensor_info_get failed: unknown result") class Processor(Iface, TProcessor): @@ -1020,7 +1033,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -1079,7 +1092,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -1121,7 +1134,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -1194,7 +1207,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -1236,7 +1249,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -1309,7 +1322,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -1369,7 +1382,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -1441,7 +1454,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -1501,7 +1514,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -1574,7 +1587,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -1634,7 +1647,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -1707,7 +1720,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -1779,7 +1792,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -1851,7 +1864,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -1911,7 +1924,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -1984,7 +1997,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -2044,7 +2057,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -2116,7 +2129,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -2176,7 +2189,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -2213,7 +2226,8 @@ def read(self, iprot): break if fid == 0: if ftype == TType.STRING: - self.success = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.success = iprot.readString().decode( + 'utf-8') if sys.version_info[0] == 2 else iprot.readString() else: iprot.skip(ftype) elif fid == 1: @@ -2248,7 +2262,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -2290,7 +2304,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -2362,7 +2376,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -2434,7 +2448,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -2506,7 +2520,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -2566,7 +2580,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -2638,7 +2652,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -2710,7 +2724,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -2782,7 +2796,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -2817,7 +2831,8 @@ def read(self, iprot): break if fid == 1: if ftype == TType.STRING: - self.options = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.options = iprot.readString().decode( + 'utf-8') if sys.version_info[0] == 2 else iprot.readString() else: iprot.skip(ftype) else: @@ -2842,7 +2857,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -2879,7 +2894,8 @@ def read(self, iprot): break if fid == 0: if ftype == TType.STRING: - self.success = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.success = iprot.readString().decode( + 'utf-8') if sys.version_info[0] == 2 else iprot.readString() else: iprot.skip(ftype) elif fid == 1: @@ -2914,7 +2930,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/pltfm_mgr_rpc/ttypes.py b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/pltfm_mgr_rpc/ttypes.py index ce03e14f8691..1f88c3c1f94f 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/pltfm_mgr_rpc/ttypes.py +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/pltfm_mgr_rpc/ttypes.py @@ -171,7 +171,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -274,37 +274,44 @@ def read(self, iprot): iprot.skip(ftype) elif fid == 2: if ftype == TType.STRING: - self.prod_name = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.prod_name = iprot.readString().decode( + 'utf-8') if sys.version_info[0] == 2 else iprot.readString() else: iprot.skip(ftype) elif fid == 3: if ftype == TType.STRING: - self.prod_part_num = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.prod_part_num = iprot.readString().decode( + 'utf-8') if sys.version_info[0] == 2 else iprot.readString() else: iprot.skip(ftype) elif fid == 4: if ftype == TType.STRING: - self.sys_asm_part_num = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.sys_asm_part_num = iprot.readString().decode( + 'utf-8') if sys.version_info[0] == 2 else iprot.readString() else: iprot.skip(ftype) elif fid == 5: if ftype == TType.STRING: - self.bfn_pcba_part_num = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.bfn_pcba_part_num = iprot.readString().decode( + 'utf-8') if sys.version_info[0] == 2 else iprot.readString() else: iprot.skip(ftype) elif fid == 6: if ftype == TType.STRING: - self.bfn_pcbb_part_num = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.bfn_pcbb_part_num = iprot.readString().decode( + 'utf-8') if sys.version_info[0] == 2 else iprot.readString() else: iprot.skip(ftype) elif fid == 7: if ftype == TType.STRING: - self.odm_pcba_part_num = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.odm_pcba_part_num = iprot.readString().decode( + 'utf-8') if sys.version_info[0] == 2 else iprot.readString() else: iprot.skip(ftype) elif fid == 8: if ftype == TType.STRING: - self.odm_pcba_ser_num = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.odm_pcba_ser_num = iprot.readString().decode( + 'utf-8') if sys.version_info[0] == 2 else iprot.readString() else: iprot.skip(ftype) elif fid == 9: @@ -324,42 +331,50 @@ def read(self, iprot): iprot.skip(ftype) elif fid == 12: if ftype == TType.STRING: - self.prod_ser_num = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.prod_ser_num = iprot.readString().decode( + 'utf-8') if sys.version_info[0] == 2 else iprot.readString() else: iprot.skip(ftype) elif fid == 13: if ftype == TType.STRING: - self.prod_ast_tag = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.prod_ast_tag = iprot.readString().decode( + 'utf-8') if sys.version_info[0] == 2 else iprot.readString() else: iprot.skip(ftype) elif fid == 14: if ftype == TType.STRING: - self.sys_mfger = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.sys_mfger = iprot.readString().decode( + 'utf-8') if sys.version_info[0] == 2 else iprot.readString() else: iprot.skip(ftype) elif fid == 15: if ftype == TType.STRING: - self.sys_mfg_date = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.sys_mfg_date = iprot.readString().decode( + 'utf-8') if sys.version_info[0] == 2 else iprot.readString() else: iprot.skip(ftype) elif fid == 16: if ftype == TType.STRING: - self.pcb_mfger = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.pcb_mfger = iprot.readString().decode( + 'utf-8') if sys.version_info[0] == 2 else iprot.readString() else: iprot.skip(ftype) elif fid == 17: if ftype == TType.STRING: - self.assembled_at = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.assembled_at = iprot.readString().decode( + 'utf-8') if sys.version_info[0] == 2 else iprot.readString() else: iprot.skip(ftype) elif fid == 18: if ftype == TType.STRING: - self.loc_mac_addr = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.loc_mac_addr = iprot.readString().decode( + 'utf-8') if sys.version_info[0] == 2 else iprot.readString() else: iprot.skip(ftype) elif fid == 19: if ftype == TType.STRING: - self.ext_mac_addr = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.ext_mac_addr = iprot.readString().decode( + 'utf-8') if sys.version_info[0] == 2 else iprot.readString() else: iprot.skip(ftype) elif fid == 20: @@ -369,7 +384,8 @@ def read(self, iprot): iprot.skip(ftype) elif fid == 21: if ftype == TType.STRING: - self.location = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.location = iprot.readString().decode( + 'utf-8') if sys.version_info[0] == 2 else iprot.readString() else: iprot.skip(ftype) elif fid == 22: @@ -401,23 +417,28 @@ def write(self, oprot): oprot.writeFieldEnd() if self.sys_asm_part_num is not None: oprot.writeFieldBegin('sys_asm_part_num', TType.STRING, 4) - oprot.writeString(self.sys_asm_part_num.encode('utf-8') if sys.version_info[0] == 2 else self.sys_asm_part_num) + oprot.writeString(self.sys_asm_part_num.encode('utf-8') + if sys.version_info[0] == 2 else self.sys_asm_part_num) oprot.writeFieldEnd() if self.bfn_pcba_part_num is not None: oprot.writeFieldBegin('bfn_pcba_part_num', TType.STRING, 5) - oprot.writeString(self.bfn_pcba_part_num.encode('utf-8') if sys.version_info[0] == 2 else self.bfn_pcba_part_num) + oprot.writeString(self.bfn_pcba_part_num.encode('utf-8') + if sys.version_info[0] == 2 else self.bfn_pcba_part_num) oprot.writeFieldEnd() if self.bfn_pcbb_part_num is not None: oprot.writeFieldBegin('bfn_pcbb_part_num', TType.STRING, 6) - oprot.writeString(self.bfn_pcbb_part_num.encode('utf-8') if sys.version_info[0] == 2 else self.bfn_pcbb_part_num) + oprot.writeString(self.bfn_pcbb_part_num.encode('utf-8') + if sys.version_info[0] == 2 else self.bfn_pcbb_part_num) oprot.writeFieldEnd() if self.odm_pcba_part_num is not None: oprot.writeFieldBegin('odm_pcba_part_num', TType.STRING, 7) - oprot.writeString(self.odm_pcba_part_num.encode('utf-8') if sys.version_info[0] == 2 else self.odm_pcba_part_num) + oprot.writeString(self.odm_pcba_part_num.encode('utf-8') + if sys.version_info[0] == 2 else self.odm_pcba_part_num) oprot.writeFieldEnd() if self.odm_pcba_ser_num is not None: oprot.writeFieldBegin('odm_pcba_ser_num', TType.STRING, 8) - oprot.writeString(self.odm_pcba_ser_num.encode('utf-8') if sys.version_info[0] == 2 else self.odm_pcba_ser_num) + oprot.writeString(self.odm_pcba_ser_num.encode('utf-8') + if sys.version_info[0] == 2 else self.odm_pcba_ser_num) oprot.writeFieldEnd() if self.prod_state is not None: oprot.writeFieldBegin('prod_state', TType.I16, 9) @@ -483,7 +504,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -651,7 +672,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -891,7 +912,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -987,7 +1008,7 @@ def validate(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): @@ -1050,7 +1071,7 @@ def __str__(self): def __repr__(self): L = ['%s=%r' % (key, value) - for key, value in self.__dict__.items()] + for key, value in list(self.__dict__.items())] return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) def __eq__(self, other): diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/psuutil.py b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/psuutil.py index 2c0e2fdb224e..0ef5162d282c 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/psuutil.py +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/psuutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - try: import os import sys @@ -16,12 +14,13 @@ from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") thrift_server = 'localhost' transport = None pltfm_mgr = None + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" @@ -35,8 +34,10 @@ def thrift_setup(self): transport = TTransport.TBufferedTransport(transport) bprotocol = TBinaryProtocol.TBinaryProtocol(transport) - pltfm_mgr_client_module = importlib.import_module(".".join(["pltfm_mgr_rpc", "pltfm_mgr_rpc"])) - pltfm_mgr_protocol = TMultiplexedProtocol.TMultiplexedProtocol(bprotocol, "pltfm_mgr_rpc") + pltfm_mgr_client_module = importlib.import_module( + ".".join(["pltfm_mgr_rpc", "pltfm_mgr_rpc"])) + pltfm_mgr_protocol = TMultiplexedProtocol.TMultiplexedProtocol( + bprotocol, "pltfm_mgr_rpc") pltfm_mgr = pltfm_mgr_client_module.Client(pltfm_mgr_protocol) transport.open() @@ -65,9 +66,9 @@ def get_psu_status(self, index): global pltfm_mgr try: - self.thrift_setup() - psu_info = pltfm_mgr.pltfm_mgr_pwr_supply_info_get(index) - self.thrift_teardown() + self.thrift_setup() + psu_info = pltfm_mgr.pltfm_mgr_pwr_supply_info_get(index) + self.thrift_teardown() except: return False @@ -86,11 +87,10 @@ def get_psu_presence(self, index): global pltfm_mgr try: - self.thrift_setup() - status = pltfm_mgr.pltfm_mgr_pwr_supply_present_get(index) - self.thrift_teardown() + self.thrift_setup() + status = pltfm_mgr.pltfm_mgr_pwr_supply_present_get(index) + self.thrift_teardown() except: return False return status - diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/sfputil.py b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/sfputil.py index 1daee453573e..41d75501f491 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/sfputil.py +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/sfputil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - try: import os import sys @@ -17,7 +15,7 @@ from sonic_sfp.sfputilbase import SfpUtilBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") thrift_server = 'localhost' transport = None @@ -25,6 +23,7 @@ SFP_EEPROM_CACHE = "/var/run/platform/sfp/cache" + class SfpUtil(SfpUtilBase): """Platform-specific SfpUtil class""" @@ -35,6 +34,8 @@ class SfpUtil(SfpUtilBase): QSFP_PORT_END = 0 EEPROM_OFFSET = 0 QSFP_CHECK_INTERVAL = 4 + THRIFT_RETRIES = 5 + THRIFT_TIMEOUT = 5 @property def port_start(self): @@ -49,12 +50,12 @@ def port_end(self): @property def qsfp_ports(self): self.update_port_info() - return range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1) + return list(range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): - print "dependency on sysfs has been removed" - raise Exception() + print("dependency on sysfs has been removed") + raise Exception() def __init__(self): self.ready = False @@ -78,7 +79,7 @@ def update_port_info(self): if self.QSFP_PORT_END == 0: self.thrift_setup() - self.QSFP_PORT_END = pltfm_mgr.pltfm_mgr_qsfp_get_max_port(); + self.QSFP_PORT_END = pltfm_mgr.pltfm_mgr_qsfp_get_max_port() self.PORT_END = self.QSFP_PORT_END self.PORTS_IN_BLOCK = self.QSFP_PORT_END self.thrift_teardown() @@ -94,7 +95,20 @@ def thrift_setup(self): pltfm_mgr_protocol = TMultiplexedProtocol.TMultiplexedProtocol(bprotocol, "pltfm_mgr_rpc") pltfm_mgr = pltfm_mgr_client_module.Client(pltfm_mgr_protocol) - transport.open() + for i in range(self.THRIFT_RETRIES): + try: + transport.open() + if i: + # The main thrift server is starded without platform api + # Platform api is added later during syncd initialization + # So we need to wait a little bit before do any platform api call + # Just in case when can't connect from the first try (warm-reboot case) + time.sleep(self.THRIFT_TIMEOUT) + break + except TTransport.TTransportException as e: + if e.type != TTransport.TTransportException.NOT_OPEN or i >= self.THRIFT_RETRIES - 1: + raise e + time.sleep(self.THRIFT_TIMEOUT) def thrift_teardown(self): global transport @@ -112,8 +126,8 @@ def get_presence(self, port_num): presence = pltfm_mgr.pltfm_mgr_qsfp_presence_get(port_num) self.thrift_teardown() except Exception as e: - print e.__doc__ - print e.message + print(e.__doc__) + print(e.message) return presence @@ -146,7 +160,7 @@ def reset(self, port_num): status = pltfm_mgr.pltfm_mgr_qsfp_reset(port_num, True) status = pltfm_mgr.pltfm_mgr_qsfp_reset(port_num, False) self.thrift_teardown() - return status + return (status == 0) def check_transceiver_change(self): if not self.ready: @@ -183,9 +197,9 @@ def get_transceiver_change_event(self, timeout=0): if timeout == 0: forever = True elif timeout > 0: - timeout = timeout / float(1000) # Convert to secs + timeout = timeout / float(1000) # Convert to secs else: - print "get_transceiver_change_event:Invalid timeout value", timeout + print("get_transceiver_change_event:Invalid timeout value", timeout) return False, {} while forever or timeout > 0: @@ -234,4 +248,3 @@ def _get_port_eeprom_path(self, port_num, devid): self.thrift_teardown() return eeprom_path - diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/pmon_daemon_control.json b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/pmon_daemon_control.json index 3a76f2fdd0e4..70bce43bbf67 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/pmon_daemon_control.json +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/pmon_daemon_control.json @@ -1,6 +1,9 @@ { + "skip_pcied": false, + "skip_fancontrol": true, + "skip_thermalctld": true, "skip_ledd": true, "skip_xcvrd": false, "skip_psud": false, - "skip_syseepromd": false + "skip_syseepromd": false } diff --git a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/hwsku.json b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/hwsku.json new file mode 100644 index 000000000000..857b00852c0b --- /dev/null +++ b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/hwsku.json @@ -0,0 +1,329 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet4": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet8": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet12": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet16": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet20": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet24": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet28": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet32": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet36": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet40": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet44": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet48": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet52": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet56": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet60": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet64": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet68": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet72": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet76": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet80": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet84": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet88": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet92": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet96": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet100": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet104": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet108": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet112": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet116": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet120": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet124": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet128": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet132": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet136": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet140": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet144": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet148": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet152": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet156": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet160": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet164": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet168": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet172": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet176": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet180": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet184": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet188": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet192": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet196": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet200": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet204": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet208": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet212": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet216": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet220": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet224": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet228": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet232": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet236": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet240": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet244": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet248": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet252": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "rs" + }, + "Ethernet256": { + "default_brkout_mode": "1x100G[40G]", + "autoneg": "0", + "fec": "none" + } + } +} diff --git a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/platform.json b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/platform.json new file mode 100644 index 000000000000..866706a28357 --- /dev/null +++ b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/platform.json @@ -0,0 +1,394 @@ +{ + "interfaces": { + "Ethernet0": { + "index": "1,1,1,1", + "lanes": "0,1,2,3", + "alias_at_lanes": "Ethernet0,Ethernet1,Ethernet2,Ethernet3", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet4": { + "index": "2,2,2,2", + "lanes": "4,5,6,7", + "alias_at_lanes": "Ethernet4,Ethernet5,Ethernet6,Ethernet7", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet8": { + "index": "3,3,3,3", + "lanes": "8,9,10,11", + "alias_at_lanes": "Ethernet8,Ethernet9,Ethernet10,Ethernet11", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet12": { + "index": "4,4,4,4", + "lanes": "12,13,14,15", + "alias_at_lanes": "Ethernet12,Ethernet13,Ethernet14,Ethernet15", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet16": { + "index": "5,5,5,5", + "lanes": "16,17,18,19", + "alias_at_lanes": "Ethernet16,Ethernet17,Ethernet18,Ethernet19", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet20": { + "index": "6,6,6,6", + "lanes": "20,21,22,23", + "alias_at_lanes": "Ethernet20,Ethernet21,Ethernet22,Ethernet23", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet24": { + "index": "7,7,7,7", + "lanes": "24,25,26,27", + "alias_at_lanes": "Ethernet24,Ethernet25,Ethernet26,Ethernet27", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet28": { + "index": "8,8,8,8", + "lanes": "28,29,30,31", + "alias_at_lanes": "Ethernet28,Ethernet29,Ethernet30,Ethernet31", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet32": { + "index": "9,9,9,9", + "lanes": "32,33,34,35", + "alias_at_lanes": "Ethernet32,Ethernet33,Ethernet34,Ethernet35", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet36": { + "index": "10,10,10,10", + "lanes": "36,37,38,39", + "alias_at_lanes": "Ethernet36,Ethernet37,Ethernet38,Ethernet39", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet40": { + "index": "11,11,11,11", + "lanes": "40,41,42,43", + "alias_at_lanes": "Ethernet40,Ethernet41,Ethernet42,Ethernet43", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet44": { + "index": "12,12,12,12", + "lanes": "44,45,46,47", + "alias_at_lanes": "Ethernet44,Ethernet45,Ethernet46,Ethernet47", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet48": { + "index": "13,13,13,13", + "lanes": "48,49,50,51", + "alias_at_lanes": "Ethernet48,Ethernet49,Ethernet50,Ethernet51", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet52": { + "index": "14,14,14,14", + "lanes": "52,53,54,55", + "alias_at_lanes": "Ethernet52,Ethernet53,Ethernet54,Ethernet55", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet56": { + "index": "15,15,15,15", + "lanes": "56,57,58,59", + "alias_at_lanes": "Ethernet56,Ethernet57,Ethernet58,Ethernet59", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet60": { + "index": "16,16,16,16", + "lanes": "60,61,62,63", + "alias_at_lanes": "Ethernet60,Ethernet61,Ethernet62,Ethernet63", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet64": { + "index": "17,17,17,17", + "lanes": "64,65,66,67", + "alias_at_lanes": "Ethernet64,Ethernet65,Ethernet66,Ethernet67", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet68": { + "index": "18,18,18,18", + "lanes": "68,69,70,71", + "alias_at_lanes": "Ethernet68,Ethernet69,Ethernet70,Ethernet71", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet72": { + "index": "19,19,19,19", + "lanes": "72,73,74,75", + "alias_at_lanes": "Ethernet72,Ethernet73,Ethernet74,Ethernet75", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet76": { + "index": "20,20,20,20", + "lanes": "76,77,78,79", + "alias_at_lanes": "Ethernet76,Ethernet77,Ethernet78,Ethernet79", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet80": { + "index": "21,21,21,21", + "lanes": "80,81,82,83", + "alias_at_lanes": "Ethernet80,Ethernet81,Ethernet82,Ethernet83", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet84": { + "index": "22,22,22,22", + "lanes": "84,85,86,87", + "alias_at_lanes": "Ethernet84,Ethernet85,Ethernet86,Ethernet87", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet88": { + "index": "23,23,23,23", + "lanes": "88,89,90,91", + "alias_at_lanes": "Ethernet88,Ethernet89,Ethernet90,Ethernet91", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet92": { + "index": "24,24,24,24", + "lanes": "92,93,94,95", + "alias_at_lanes": "Ethernet92,Ethernet93,Ethernet94,Ethernet95", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet96": { + "index": "25,25,25,25", + "lanes": "96,97,98,99", + "alias_at_lanes": "Ethernet96,Ethernet97,Ethernet98,Ethernet99", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet100": { + "index": "26,26,26,26", + "lanes": "100,101,102,103", + "alias_at_lanes": "Ethernet100,Ethernet101,Ethernet102,Ethernet103", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet104": { + "index": "27,27,27,27", + "lanes": "104,105,106,107", + "alias_at_lanes": "Ethernet104,Ethernet105,Ethernet106,Ethernet107", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet108": { + "index": "28,28,28,28", + "lanes": "108,109,110,111", + "alias_at_lanes": "Ethernet108,Ethernet109,Ethernet110,Ethernet111", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet112": { + "index": "29,29,29,29", + "lanes": "112,113,114,115", + "alias_at_lanes": "Ethernet112,Ethernet113,Ethernet114,Ethernet115", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet116": { + "index": "30,30,30,30", + "lanes": "116,117,118,119", + "alias_at_lanes": "Ethernet116,Ethernet117,Ethernet118,Ethernet119", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet120": { + "index": "31,31,31,31", + "lanes": "120,121,122,123", + "alias_at_lanes": "Ethernet120,Ethernet121,Ethernet122,Ethernet123", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet124": { + "index": "32,32,32,32", + "lanes": "124,125,126,127", + "alias_at_lanes": "Ethernet124,Ethernet125,Ethernet126,Ethernet127", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet128": { + "index": "33,33,33,33", + "lanes": "128,129,130,131", + "alias_at_lanes": "Ethernet128,Ethernet129,Ethernet130,Ethernet131", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet132": { + "index": "34,34,34,34", + "lanes": "132,133,134,135", + "alias_at_lanes": "Ethernet132,Ethernet133,Ethernet134,Ethernet135", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet136": { + "index": "35,35,35,35", + "lanes": "136,137,138,139", + "alias_at_lanes": "Ethernet136,Ethernet137,Ethernet138,Ethernet139", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet140": { + "index": "36,36,36,36", + "lanes": "140,141,142,143", + "alias_at_lanes": "Ethernet140,Ethernet141,Ethernet142,Ethernet143", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet144": { + "index": "37,37,37,37", + "lanes": "144,145,146,147", + "alias_at_lanes": "Ethernet144,Ethernet145,Ethernet146,Ethernet147", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet148": { + "index": "38,38,38,38", + "lanes": "148,149,150,151", + "alias_at_lanes": "Ethernet148,Ethernet149,Ethernet150,Ethernet151", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet152": { + "index": "39,39,39,39", + "lanes": "152,153,154,155", + "alias_at_lanes": "Ethernet152,Ethernet153,Ethernet154,Ethernet155", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet156": { + "index": "40,40,40,40", + "lanes": "156,157,158,159", + "alias_at_lanes": "Ethernet156,Ethernet157,Ethernet158,Ethernet159", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet160": { + "index": "41,41,41,41", + "lanes": "160,161,162,163", + "alias_at_lanes": "Ethernet160,Ethernet161,Ethernet162,Ethernet163", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet164": { + "index": "42,42,42,42", + "lanes": "164,165,166,167", + "alias_at_lanes": "Ethernet164,Ethernet165,Ethernet166,Ethernet167", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet168": { + "index": "43,43,43,43", + "lanes": "168,169,170,171", + "alias_at_lanes": "Ethernet168,Ethernet169,Ethernet170,Ethernet171", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet172": { + "index": "44,44,44,44", + "lanes": "172,173,174,175", + "alias_at_lanes": "Ethernet172,Ethernet173,Ethernet174,Ethernet175", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet176": { + "index": "45,45,45,45", + "lanes": "176,177,178,179", + "alias_at_lanes": "Ethernet176,Ethernet177,Ethernet178,Ethernet179", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet180": { + "index": "46,46,46,46", + "lanes": "180,181,182,183", + "alias_at_lanes": "Ethernet180,Ethernet181,Ethernet182,Ethernet183", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet184": { + "index": "47,47,47,47", + "lanes": "184,185,186,187", + "alias_at_lanes": "Ethernet184,Ethernet185,Ethernet186,Ethernet187", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet188": { + "index": "48,48,48,48", + "lanes": "188,189,190,191", + "alias_at_lanes": "Ethernet188,Ethernet189,Ethernet190,Ethernet191", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet192": { + "index": "49,49,49,49", + "lanes": "192,193,194,195", + "alias_at_lanes": "Ethernet192,Ethernet193,Ethernet194,Ethernet195", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet196": { + "index": "50,50,50,50", + "lanes": "196,197,198,199", + "alias_at_lanes": "Ethernet196,Ethernet197,Ethernet198,Ethernet199", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet200": { + "index": "51,51,51,51", + "lanes": "200,201,202,203", + "alias_at_lanes": "Ethernet200,Ethernet201,Ethernet202,Ethernet203", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet204": { + "index": "52,52,52,52", + "lanes": "204,205,206,207", + "alias_at_lanes": "Ethernet204,Ethernet205,Ethernet206,Ethernet207", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet208": { + "index": "53,53,53,53", + "lanes": "208,209,210,211", + "alias_at_lanes": "Ethernet208,Ethernet209,Ethernet210,Ethernet211", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet212": { + "index": "54,54,54,54", + "lanes": "212,213,214,215", + "alias_at_lanes": "Ethernet212,Ethernet213,Ethernet214,Ethernet215", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet216": { + "index": "55,55,55,55", + "lanes": "216,217,218,219", + "alias_at_lanes": "Ethernet216,Ethernet217,Ethernet218,Ethernet219", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet220": { + "index": "56,56,56,56", + "lanes": "220,221,222,223", + "alias_at_lanes": "Ethernet220,Ethernet221,Ethernet222,Ethernet223", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet224": { + "index": "57,57,57,57", + "lanes": "224,225,226,227", + "alias_at_lanes": "Ethernet224,Ethernet225,Ethernet226,Ethernet227", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet228": { + "index": "58,58,58,58", + "lanes": "228,229,230,231", + "alias_at_lanes": "Ethernet228,Ethernet229,Ethernet230,Ethernet231", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet232": { + "index": "59,59,59,59", + "lanes": "232,233,234,235", + "alias_at_lanes": "Ethernet232,Ethernet233,Ethernet234,Ethernet235", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet236": { + "index": "60,60,60,60", + "lanes": "236,237,238,239", + "alias_at_lanes": "Ethernet236,Ethernet237,Ethernet238,Ethernet239", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet240": { + "index": "61,61,61,61", + "lanes": "240,241,242,243", + "alias_at_lanes": "Ethernet240,Ethernet241,Ethernet242,Ethernet243", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet244": { + "index": "62,62,62,62", + "lanes": "244,245,246,247", + "alias_at_lanes": "Ethernet244,Ethernet245,Ethernet246,Ethernet247", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet248": { + "index": "63,63,63,63", + "lanes": "248,249,250,251", + "alias_at_lanes": "Ethernet248,Ethernet249,Ethernet250,Ethernet251", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet252": { + "index": "64,64,64,64", + "lanes": "252,253,254,255", + "alias_at_lanes": "Ethernet252,Ethernet253,Ethernet254,Ethernet255", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet256": { + "index": "65,65,65,65", + "lanes": "256,257,258,259", + "alias_at_lanes": "Ethernet256,Ethernet257,Ethernet258,Ethernet259", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + } + } +} diff --git a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/pmon_daemon_control.json b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/pmon_daemon_control.json index 3a76f2fdd0e4..f94fa8370273 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/pmon_daemon_control.json +++ b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/pmon_daemon_control.json @@ -1,6 +1,9 @@ { + "skip_pcied": true, + "skip_fancontrol": true, + "skip_thermalctld": true, "skip_ledd": true, "skip_xcvrd": false, "skip_psud": false, - "skip_syseepromd": false + "skip_syseepromd": false } diff --git a/device/broadcom/x86_64-bcm_xlr-r0/BCM956960K/sai.profile b/device/broadcom/x86_64-bcm_xlr-r0/BCM956960K/sai.profile index 80aa570ddfb3..9e6a31e3d1e9 100644 --- a/device/broadcom/x86_64-bcm_xlr-r0/BCM956960K/sai.profile +++ b/device/broadcom/x86_64-bcm_xlr-r0/BCM956960K/sai.profile @@ -1 +1,2 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/config_th_32x100.bcm +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th_32x100.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/broadcom/x86_64-bcm_xlr-r0/BCM956960K/config_th_32x100.bcm b/device/broadcom/x86_64-bcm_xlr-r0/BCM956960K/th_32x100.config.bcm similarity index 100% rename from device/broadcom/x86_64-bcm_xlr-r0/BCM956960K/config_th_32x100.bcm rename to device/broadcom/x86_64-bcm_xlr-r0/BCM956960K/th_32x100.config.bcm diff --git a/device/broadcom/x86_64-bcm_xlr-r0/plugins/eeprom.py b/device/broadcom/x86_64-bcm_xlr-r0/plugins/eeprom.py index ce122d6fface..0a4e11155711 100644 --- a/device/broadcom/x86_64-bcm_xlr-r0/plugins/eeprom.py +++ b/device/broadcom/x86_64-bcm_xlr-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Broadcom XLR/GTS 'eeprom' support # @@ -8,20 +6,24 @@ # - the eeprom format definition # - specific encoder/decoder if there is special need # -# Note: the file /etc/sys_eeprom.bin is generated by the script -# brcm-xlr-gts-create-eeprom-file.py +# Note: the file /usr/share/sonic/platform/sys_eeprom.bin is generated +# by the script brcm-xlr-gts-create-eeprom-file.py ############################################################################# +import os + try: from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): def __init__(self, name, path, cpld_root, ro): - self.eeprom_path = "/etc/sys_eeprom.bin" + self.eeprom_path = "/usr/share/sonic/platform/sys_eeprom.bin" + if os.path.isfile(self.eeprom_path) is False: + self.eeprom_path = "/usr/share/sonic/device/x86_64-bcm_xlr-r0/sys_eeprom.bin" super(board, self).__init__(self.eeprom_path, 0, '', False, True) def serial_number_str(self, e): diff --git a/device/broadcom/x86_64-bcm_xlr-r0/plugins/psuutil.py b/device/broadcom/x86_64-bcm_xlr-r0/plugins/psuutil.py index 5cfdda1578b9..fefc3c3494e5 100644 --- a/device/broadcom/x86_64-bcm_xlr-r0/plugins/psuutil.py +++ b/device/broadcom/x86_64-bcm_xlr-r0/plugins/psuutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - import os.path try: diff --git a/device/broadcom/x86_64-bcm_xlr-r0/plugins/sfputil.py b/device/broadcom/x86_64-bcm_xlr-r0/plugins/sfputil.py index 3dc25793ba4a..f526706f5dd4 100644 --- a/device/broadcom/x86_64-bcm_xlr-r0/plugins/sfputil.py +++ b/device/broadcom/x86_64-bcm_xlr-r0/plugins/sfputil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - try: import time import os diff --git a/device/celestica/x86_64-cel_e1031-r0/Celestica-E1031-T48S4/sai.profile b/device/celestica/x86_64-cel_e1031-r0/Celestica-E1031-T48S4/sai.profile index f467f997fe62..a98bdc993e73 100644 --- a/device/celestica/x86_64-cel_e1031-r0/Celestica-E1031-T48S4/sai.profile +++ b/device/celestica/x86_64-cel_e1031-r0/Celestica-E1031-T48S4/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/helix4-e1031-48x1G+4x10G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/celestica/x86_64-cel_e1031-r0/plugins/eeprom.py b/device/celestica/x86_64-cel_e1031-r0/plugins/eeprom.py index 6577631c8908..4728d562cc7a 100644 --- a/device/celestica/x86_64-cel_e1031-r0/plugins/eeprom.py +++ b/device/celestica/x86_64-cel_e1031-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Celestica Haliburton # @@ -11,8 +9,8 @@ try: from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): @@ -20,4 +18,3 @@ class board(eeprom_tlvinfo.TlvInfoDecoder): def __init__(self, name, path, cpld_root, ro): self.eeprom_path = "/sys/class/i2c-adapter/i2c-2/2-0050/eeprom" super(board, self).__init__(self.eeprom_path, 0, '', True) - diff --git a/device/celestica/x86_64-cel_e1031-r0/plugins/pcie.yaml b/device/celestica/x86_64-cel_e1031-r0/plugins/pcie.yaml new file mode 100644 index 000000000000..485ac3512fe5 --- /dev/null +++ b/device/celestica/x86_64-cel_e1031-r0/plugins/pcie.yaml @@ -0,0 +1,76 @@ +- bus: '00' + dev: '00' + fn: '0' + id: 1f0f + name: 'Host bridge: Intel Corporation Atom processor C2000 SoC Transaction Router' +- bus: '00' + dev: '01' + fn: '0' + id: 1f10 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 1' +- bus: '00' + dev: '02' + fn: '0' + id: 1f11 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 2' +- bus: '00' + dev: '03' + fn: '0' + id: 1f12 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 3' +- bus: '00' + dev: '04' + fn: '0' + id: 1f13 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 4' +- bus: '00' + dev: 0e + fn: '0' + id: 1f14 + name: 'Host bridge: Intel Corporation Atom processor C2000 RAS' +- bus: '00' + dev: 0f + fn: '0' + id: 1f16 + name: 'IOMMU: Intel Corporation Atom processor C2000 RCEC' +- bus: '00' + dev: '13' + fn: '0' + id: 1f15 + name: 'System peripheral: Intel Corporation Atom processor C2000 SMBus 2.0' +- bus: '00' + dev: '14' + fn: '0' + id: 1f41 + name: 'Ethernet controller: Intel Corporation Ethernet Connection I354' +- bus: '00' + dev: '16' + fn: '0' + id: 1f2c + name: 'USB controller: Intel Corporation Atom processor C2000 USB Enhanced Host Controller' +- bus: '00' + dev: '17' + fn: '0' + id: 1f22 + name: 'SATA controller: Intel Corporation Atom processor C2000 AHCI SATA2 Controller' +- bus: '00' + dev: 1f + fn: '0' + id: 1f38 + name: 'ISA bridge: Intel Corporation Atom processor C2000 PCU' +- bus: '00' + dev: 1f + fn: '3' + id: 1f3c + name: 'SMBus: Intel Corporation Atom processor C2000 PCU SMBus' +- bus: '01' + dev: '00' + fn: '0' + id: b340 + name: 'Ethernet controller: Broadcom Limited Device b340' +- bus: '01' + dev: '00' + fn: '1' + id: b340 + name: 'Ethernet controller: Broadcom Limited Device b340' + diff --git a/device/celestica/x86_64-cel_e1031-r0/plugins/psuutil.py b/device/celestica/x86_64-cel_e1031-r0/plugins/psuutil.py index 71b8d4ad3c59..8e019efbebcd 100644 --- a/device/celestica/x86_64-cel_e1031-r0/plugins/psuutil.py +++ b/device/celestica/x86_64-cel_e1031-r0/plugins/psuutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - import os.path try: diff --git a/device/celestica/x86_64-cel_e1031-r0/plugins/sfputil.py b/device/celestica/x86_64-cel_e1031-r0/plugins/sfputil.py index 9cbec7127261..d65f2cf3f54f 100644 --- a/device/celestica/x86_64-cel_e1031-r0/plugins/sfputil.py +++ b/device/celestica/x86_64-cel_e1031-r0/plugins/sfputil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - try: import time import os @@ -15,15 +13,15 @@ class SfpUtil(SfpUtilBase): PORT_START = 1 PORT_END = 52 port_to_i2c_mapping = { - 1: None, - 2: None, - 3: None, - 4: None, - 5: None, - 6: None, - 7: None, - 8: None, - 9: None, + 1: None, + 2: None, + 3: None, + 4: None, + 5: None, + 6: None, + 7: None, + 8: None, + 9: None, 10: None, 11: None, 12: None, @@ -69,7 +67,7 @@ class SfpUtil(SfpUtilBase): 52: 16 } _port_to_eeprom_mapping = {} - _sfp_port = range(49, PORT_END + 1) + _sfp_port = list(range(49, PORT_END + 1)) @property def port_start(self): @@ -95,7 +93,6 @@ def __init__(self): self.port_to_eeprom_mapping[x] = port_eeprom_path SfpUtilBase.__init__(self) - def get_presence(self, port_num): sfp_modabs_path = '/sys/devices/platform/e1031.smc/SFP/sfp_modabs' @@ -129,7 +126,7 @@ def get_transceiver_change_event(self, timeout=0): try: # We get notified when there is an SCI interrupt from GPIO SUS7 fd = open("/sys/devices/platform/hlx-ich.0/sci_int_gpio_sus7", "r") - fd.read() + fd.read() epoll.register(fd.fileno(), select.EPOLLIN & select.EPOLLET) events = epoll.poll(timeout=timeout_sec if timeout != 0 else -1) @@ -139,18 +136,18 @@ def get_transceiver_change_event(self, timeout=0): with open(modabs_interrupt_path, 'r') as port_changes: changes = int(port_changes.read(), 16) for port_num in self._sfp_port: - change = (changes >> ( port_num - 49)) & 1 + change = (changes >> (port_num - 49)) & 1 if change == 1: port_dict[str(port_num)] = str(int(self.get_presence(port_num))) found_flag = 1 - + if not found_flag: return False, {} return True, port_dict - + finally: fd.close() epoll.close() - return False, {} \ No newline at end of file + return False, {} 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 719170d831b7..40c4bb4ef73b 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 @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Celestica # @@ -87,7 +85,7 @@ def get_base_mac(self): """ return self._eeprom.get_mac() - def get_serial_number(self): + def get_serial(self): """ Retrieves the hardware serial number for the chassis Returns: 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 fe34bc45c670..7fdfc8756a4d 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 @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Celestica # @@ -43,7 +41,7 @@ def __run_command(self, command): # Run bash command and print output to stdout try: process = subprocess.Popen( - shlex.split(command), stdout=subprocess.PIPE) + shlex.split(command), universal_newlines=True, stdout=subprocess.PIPE) while True: output = process.stdout.readline() if output == '' and process.poll() is not None: @@ -68,7 +66,7 @@ def get_register_value(self, register): # Retrieves the cpld register value cmd = "echo {1} > {0}; cat {0}".format(GETREG_PATH, register) p = subprocess.Popen( - cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) raw_data, err = p.communicate() if err is not '': return None diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/eeprom.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/eeprom.py index 20f3db111f66..0058fccfa0ca 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/eeprom.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Celestica Haliburton # @@ -13,13 +11,17 @@ import glob import os import sys - import imp import re from array import array - from cStringIO import StringIO + + if sys.version_info.major == 3: + from io import StringIO + else: + from cStringIO import StringIO + from sonic_platform_base.sonic_eeprom import eeprom_dts from sonic_platform_base.sonic_eeprom import eeprom_tlvinfo -except ImportError, e: +except ImportError as e: raise ImportError(str(e) + "- required module not found") CACHE_ROOT = '/var/cache/sonic/decode-syseeprom' diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/fan.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/fan.py index 2c5bc5c0c45c..18cf513800aa 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/fan.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/fan.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Celestica # diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/platform.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/platform.py index a632de87e742..7d98ec9f7cdf 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/platform.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/platform.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Celestica # diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/psu.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/psu.py index 9777bb6fea64..27d70f123c59 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/psu.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/psu.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Celestica # @@ -84,7 +82,7 @@ def get_voltage(self): if vout_label_path: dir_name = os.path.dirname(vout_label_path) basename = os.path.basename(vout_label_path) - in_num = filter(str.isdigit, basename) + in_num = ''.join(list(filter(str.isdigit, basename))) vout_path = os.path.join( dir_name, voltage_name.format(in_num)) vout_val = self.__read_txt_file(vout_path) @@ -107,7 +105,7 @@ def get_current(self): if curr_label_path: dir_name = os.path.dirname(curr_label_path) basename = os.path.basename(curr_label_path) - cur_num = filter(str.isdigit, basename) + cur_num = ''.join(list(filter(str.isdigit, basename))) cur_path = os.path.join( dir_name, current_name.format(cur_num)) cur_val = self.__read_txt_file(cur_path) @@ -130,7 +128,7 @@ def get_power(self): if pw_label_path: dir_name = os.path.dirname(pw_label_path) basename = os.path.basename(pw_label_path) - pw_num = filter(str.isdigit, basename) + pw_num = ''.join(list(filter(str.isdigit, basename))) pw_path = os.path.join( dir_name, current_name.format(pw_num)) pw_val = self.__read_txt_file(pw_path) 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 6ef8838ba8af..608111d7e2fd 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 @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Celestica # @@ -11,7 +9,6 @@ import os import time import subprocess -import sonic_device_util from ctypes import create_string_buffer try: @@ -82,7 +79,7 @@ class Sfp(SfpBase): 51: 17, 52: 16 } - _sfp_port = range(49, PORT_END + 1) + _sfp_port = list(range(49, PORT_END + 1)) PRS_PATH = "/sys/devices/platform/e1031.smc/SFP/sfp_modabs" PLATFORM_ROOT_PATH = '/usr/share/sonic/device' PMON_HWSKU_PATH = '/usr/share/sonic/hwsku' @@ -105,7 +102,7 @@ def __init__(self, sfp_index): self.port_to_eeprom_mapping[x] = eeprom_path.format( self.port_to_i2c_mapping[x]) - self.info_dict_keys = ['type', 'hardwarerev', 'serialnum', 'manufacturename', 'modelname', 'Connector', 'encoding', 'ext_identifier', + self.info_dict_keys = ['type', 'hardware_rev', 'serial', 'manufacturer', 'model', 'connector', 'encoding', 'ext_identifier', 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance', 'vendor_date', 'vendor_oui'] self.dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', 'temperature', 'voltage', @@ -185,11 +182,11 @@ def get_transceiver_info(self): keys |Value Format |Information ---------------------------|---------------|---------------------------- type |1*255VCHAR |type of SFP - hardwarerev |1*255VCHAR |hardware version of SFP - serialnum |1*255VCHAR |serial number of the SFP - manufacturename |1*255VCHAR |SFP vendor name - modelname |1*255VCHAR |SFP model name - Connector |1*255VCHAR |connector information + hardware_rev |1*255VCHAR |hardware version of SFP + serial |1*255VCHAR |serial number of the SFP + manufacturer |1*255VCHAR |SFP vendor name + model |1*255VCHAR |SFP model name + connector |1*255VCHAR |connector information encoding |1*255VCHAR |encoding information ext_identifier |1*255VCHAR |extend identifier ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance @@ -248,17 +245,17 @@ def get_transceiver_info(self): if sfp_interface_bulk_data: transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] - transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data[ + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data[ 'data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A' - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A' transceiver_info_dict['vendor_date'] = sfp_vendor_date_data[ 'data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A' @@ -705,7 +702,7 @@ def get_model(self): string: Model/part number of device """ transceiver_dom_info_dict = self.get_transceiver_info() - return transceiver_dom_info_dict.get("modelname", "N/A") + return transceiver_dom_info_dict.get("model", "N/A") def get_serial(self): """ @@ -714,4 +711,4 @@ def get_serial(self): string: Serial number of device """ transceiver_dom_info_dict = self.get_transceiver_info() - return transceiver_dom_info_dict.get("serialnum", "N/A") + return transceiver_dom_info_dict.get("serial", "N/A") diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/thermal.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/thermal.py index 6c37f3b7ce88..157f49a7c3e2 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/thermal.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/thermal.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Celestica # diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/watchdog.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/watchdog.py index b539bc06f618..882285251784 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/watchdog.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/watchdog.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Celestica # diff --git a/device/celestica/x86_64-cel_midstone-r0/plugins/eeprom.py b/device/celestica/x86_64-cel_midstone-r0/plugins/eeprom.py index 86e7f1b2af15..c8b593a15003 100755 --- a/device/celestica/x86_64-cel_midstone-r0/plugins/eeprom.py +++ b/device/celestica/x86_64-cel_midstone-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Celestica Midstone-200i # @@ -11,8 +9,8 @@ try: from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): diff --git a/device/celestica/x86_64-cel_midstone-r0/plugins/psuutil.py b/device/celestica/x86_64-cel_midstone-r0/plugins/psuutil.py index 4e6c5eec5d85..0c93576e1fba 100644 --- a/device/celestica/x86_64-cel_midstone-r0/plugins/psuutil.py +++ b/device/celestica/x86_64-cel_midstone-r0/plugins/psuutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Celestica # @@ -14,7 +12,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" @@ -44,7 +43,6 @@ def get_psu_status(self, index): status = 1 return status == 1 - def get_psu_presence(self, index): """ Retrieves the presence status of power supply unit (PSU) defined @@ -58,4 +56,3 @@ def get_psu_presence(self, index): status = 1 return status == 1 - diff --git a/device/celestica/x86_64-cel_midstone-r0/plugins/sfputil.py b/device/celestica/x86_64-cel_midstone-r0/plugins/sfputil.py index 4d2a444c198b..8b3b06ff00ef 100755 --- a/device/celestica/x86_64-cel_midstone-r0/plugins/sfputil.py +++ b/device/celestica/x86_64-cel_midstone-r0/plugins/sfputil.py @@ -32,7 +32,7 @@ def port_end(self): @property def qsfp_ports(self): - return range(self.QSFP_PORT_START, self.QSFP_PORT_END+1) + return list(range(self.QSFP_PORT_START, self.QSFP_PORT_END+1)) @property def port_to_eeprom_mapping(self): @@ -59,7 +59,7 @@ def get_presence(self, port_num): try: reg_file = open("/sys/devices/platform/ms200i_cpld/qsfp_modprs") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -90,7 +90,7 @@ def get_low_power_mode(self, port_num): try: reg_file = open("/sys/devices/platform/ms200i_cpld/qsfp_lpmode") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) content = reg_file.readline().rstrip() @@ -120,7 +120,7 @@ def set_low_power_mode(self, port_num, lpmode): try: reg_file = open("/sys/devices/platform/ms200i_cpld/qsfp_lpmode", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -162,7 +162,7 @@ def reset(self, port_num): try: reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -194,7 +194,7 @@ def reset(self, port_num): try: reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "w") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = reg_value | mask diff --git a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/pg_profile_lookup.ini b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/pg_profile_lookup.ini index aedda37a8878..673df369a9bb 100644 --- a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/pg_profile_lookup.ini +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/pg_profile_lookup.ini @@ -1,17 +1,17 @@ # PG lossless profiles. # speed cable size xon xoff threshold xon_offset - 10000 5m 1248 2288 35776 -3 2288 - 25000 5m 1248 2288 53248 -3 2288 - 40000 5m 1248 2288 66560 -3 2288 - 50000 5m 1248 2288 90272 -3 2288 - 100000 5m 1248 2288 165568 -3 2288 - 10000 40m 1248 2288 37024 -3 2288 - 25000 40m 1248 2288 53248 -3 2288 - 40000 40m 1248 2288 71552 -3 2288 - 50000 40m 1248 2288 96096 -3 2288 - 100000 40m 1248 2288 177632 -3 2288 - 10000 300m 1248 2288 46176 -3 2288 - 25000 300m 1248 2288 79040 -3 2288 - 40000 300m 1248 2288 108160 -3 2288 - 50000 300m 1248 2288 141856 -3 2288 - 100000 300m 1248 2288 268736 -3 2288 + 10000 5m 1248 2288 35776 0 2288 + 25000 5m 1248 2288 53248 0 2288 + 40000 5m 1248 2288 66560 0 2288 + 50000 5m 1248 2288 90272 0 2288 + 100000 5m 1248 2288 165568 0 2288 + 10000 40m 1248 2288 37024 0 2288 + 25000 40m 1248 2288 53248 0 2288 + 40000 40m 1248 2288 71552 0 2288 + 50000 40m 1248 2288 96096 0 2288 + 100000 40m 1248 2288 177632 0 2288 + 10000 300m 1248 2288 46176 0 2288 + 25000 300m 1248 2288 79040 0 2288 + 40000 300m 1248 2288 108160 0 2288 + 50000 300m 1248 2288 141856 0 2288 + 100000 300m 1248 2288 268736 0 2288 diff --git a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/qos.json.j2 b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/qos.json.j2 index 3e548325ea30..34002048afdb 100644 --- a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/qos.json.j2 +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/qos.json.j2 @@ -1 +1,21 @@ +{%- macro generate_wred_profiles() %} + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "wred_green_enable" : "true", + "wred_yellow_enable" : "true", + "wred_red_enable" : "true", + "ecn" : "ecn_all", + "green_max_threshold" : "2097152", + "green_min_threshold" : "250000", + "yellow_max_threshold" : "2097152", + "yellow_min_threshold" : "1048576", + "red_max_threshold" : "2097152", + "red_min_threshold" : "1048576", + "green_drop_probability" : "5", + "yellow_drop_probability": "5", + "red_drop_probability" : "5" + } + }, +{%- endmacro %} + {%- include 'qos_config.j2' %} diff --git a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/sai.profile.j2 b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/sai.profile.j2 index abc2daefd04e..5feba4956931 100644 --- a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/sai.profile.j2 +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/sai.profile.j2 @@ -1,7 +1,7 @@ {# Get sai.profile based on switch_role #} {%- if DEVICE_METADATA is defined and DEVICE_METADATA['localhost'] is defined and DEVICE_METADATA['localhost']['type'] is defined -%} {%- set switch_role = DEVICE_METADATA['localhost']['type'] -%} -{%- if switch_role.lower() == 'torrouter' %} +{%- if 'torrouter' in switch_role.lower() %} {% set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-seastone-dx010-32x100G-t0.config.bcm' -%} {%- else %} {% set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-seastone-dx010-32x100G-t1.config.bcm' -%} @@ -11,3 +11,4 @@ {%- endif %} {# Write the contents of sai_ profile_filename to sai.profile file #} {{ sai_profile_contents }} +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/pg_profile_lookup.ini b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/pg_profile_lookup.ini index aedda37a8878..673df369a9bb 100644 --- a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/pg_profile_lookup.ini +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/pg_profile_lookup.ini @@ -1,17 +1,17 @@ # PG lossless profiles. # speed cable size xon xoff threshold xon_offset - 10000 5m 1248 2288 35776 -3 2288 - 25000 5m 1248 2288 53248 -3 2288 - 40000 5m 1248 2288 66560 -3 2288 - 50000 5m 1248 2288 90272 -3 2288 - 100000 5m 1248 2288 165568 -3 2288 - 10000 40m 1248 2288 37024 -3 2288 - 25000 40m 1248 2288 53248 -3 2288 - 40000 40m 1248 2288 71552 -3 2288 - 50000 40m 1248 2288 96096 -3 2288 - 100000 40m 1248 2288 177632 -3 2288 - 10000 300m 1248 2288 46176 -3 2288 - 25000 300m 1248 2288 79040 -3 2288 - 40000 300m 1248 2288 108160 -3 2288 - 50000 300m 1248 2288 141856 -3 2288 - 100000 300m 1248 2288 268736 -3 2288 + 10000 5m 1248 2288 35776 0 2288 + 25000 5m 1248 2288 53248 0 2288 + 40000 5m 1248 2288 66560 0 2288 + 50000 5m 1248 2288 90272 0 2288 + 100000 5m 1248 2288 165568 0 2288 + 10000 40m 1248 2288 37024 0 2288 + 25000 40m 1248 2288 53248 0 2288 + 40000 40m 1248 2288 71552 0 2288 + 50000 40m 1248 2288 96096 0 2288 + 100000 40m 1248 2288 177632 0 2288 + 10000 300m 1248 2288 46176 0 2288 + 25000 300m 1248 2288 79040 0 2288 + 40000 300m 1248 2288 108160 0 2288 + 50000 300m 1248 2288 141856 0 2288 + 100000 300m 1248 2288 268736 0 2288 diff --git a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/qos.json.j2 b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/qos.json.j2 index 3e548325ea30..34002048afdb 100644 --- a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/qos.json.j2 +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/qos.json.j2 @@ -1 +1,21 @@ +{%- macro generate_wred_profiles() %} + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "wred_green_enable" : "true", + "wred_yellow_enable" : "true", + "wred_red_enable" : "true", + "ecn" : "ecn_all", + "green_max_threshold" : "2097152", + "green_min_threshold" : "250000", + "yellow_max_threshold" : "2097152", + "yellow_min_threshold" : "1048576", + "red_max_threshold" : "2097152", + "red_min_threshold" : "1048576", + "green_drop_probability" : "5", + "yellow_drop_probability": "5", + "red_drop_probability" : "5" + } + }, +{%- endmacro %} + {%- include 'qos_config.j2' %} diff --git a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/sai.profile b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/sai.profile index 46d96b2fd905..50220639519c 100644 --- a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/sai.profile +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-seastone-dx010-48x50G+8x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-10-50/hwsku.json b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-10-50/hwsku.json new file mode 100644 index 000000000000..b578376a3313 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-10-50/hwsku.json @@ -0,0 +1,100 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet4": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet8": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet12": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet16": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet20": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet24": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet28": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet32": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet36": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet40": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet44": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet48": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet52": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet56": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet60": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet64": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet68": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet72": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet76": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet80": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet84": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet88": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet92": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet96": { + "default_brkout_mode": "2x50G" + }, + "Ethernet100": { + "default_brkout_mode": "2x50G" + }, + "Ethernet104": { + "default_brkout_mode": "2x50G" + }, + "Ethernet108": { + "default_brkout_mode": "2x50G" + }, + "Ethernet112": { + "default_brkout_mode": "2x50G" + }, + "Ethernet116": { + "default_brkout_mode": "2x50G" + }, + "Ethernet120": { + "default_brkout_mode": "2x50G" + }, + "Ethernet124": { + "default_brkout_mode": "2x50G" + } + } +} \ No newline at end of file diff --git a/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-25-50/hwsku.json b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-25-50/hwsku.json new file mode 100644 index 000000000000..b578376a3313 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-25-50/hwsku.json @@ -0,0 +1,100 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet4": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet8": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet12": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet16": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet20": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet24": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet28": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet32": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet36": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet40": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet44": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet48": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet52": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet56": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet60": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet64": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet68": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet72": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet76": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet80": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet84": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet88": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet92": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet96": { + "default_brkout_mode": "2x50G" + }, + "Ethernet100": { + "default_brkout_mode": "2x50G" + }, + "Ethernet104": { + "default_brkout_mode": "2x50G" + }, + "Ethernet108": { + "default_brkout_mode": "2x50G" + }, + "Ethernet112": { + "default_brkout_mode": "2x50G" + }, + "Ethernet116": { + "default_brkout_mode": "2x50G" + }, + "Ethernet120": { + "default_brkout_mode": "2x50G" + }, + "Ethernet124": { + "default_brkout_mode": "2x50G" + } + } +} \ No newline at end of file diff --git a/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50-40/hwsku.json b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50-40/hwsku.json new file mode 100644 index 000000000000..3b1b8a97909a --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50-40/hwsku.json @@ -0,0 +1,100 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "2x50G" + }, + "Ethernet4": { + "default_brkout_mode": "2x50G" + }, + "Ethernet8": { + "default_brkout_mode": "2x50G" + }, + "Ethernet12": { + "default_brkout_mode": "2x50G" + }, + "Ethernet16": { + "default_brkout_mode": "2x50G" + }, + "Ethernet20": { + "default_brkout_mode": "2x50G" + }, + "Ethernet24": { + "default_brkout_mode": "2x50G" + }, + "Ethernet28": { + "default_brkout_mode": "2x50G" + }, + "Ethernet32": { + "default_brkout_mode": "2x50G" + }, + "Ethernet36": { + "default_brkout_mode": "2x50G" + }, + "Ethernet40": { + "default_brkout_mode": "2x50G" + }, + "Ethernet44": { + "default_brkout_mode": "2x50G" + }, + "Ethernet48": { + "default_brkout_mode": "2x50G" + }, + "Ethernet52": { + "default_brkout_mode": "2x50G" + }, + "Ethernet56": { + "default_brkout_mode": "2x50G" + }, + "Ethernet60": { + "default_brkout_mode": "2x50G" + }, + "Ethernet64": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet68": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet72": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet76": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet80": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet84": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet88": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet92": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet96": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet100": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet104": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet108": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet112": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet116": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet120": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet124": { + "default_brkout_mode": "1x100G[40G]" + } + } +} \ No newline at end of file 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 diff --git a/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50/hwsku.json b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50/hwsku.json new file mode 100644 index 000000000000..0b219eee39f7 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50/hwsku.json @@ -0,0 +1,100 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "2x50G" + }, + "Ethernet4": { + "default_brkout_mode": "2x50G" + }, + "Ethernet8": { + "default_brkout_mode": "2x50G" + }, + "Ethernet12": { + "default_brkout_mode": "2x50G" + }, + "Ethernet16": { + "default_brkout_mode": "2x50G" + }, + "Ethernet20": { + "default_brkout_mode": "2x50G" + }, + "Ethernet24": { + "default_brkout_mode": "2x50G" + }, + "Ethernet28": { + "default_brkout_mode": "2x50G" + }, + "Ethernet32": { + "default_brkout_mode": "2x50G" + }, + "Ethernet36": { + "default_brkout_mode": "2x50G" + }, + "Ethernet40": { + "default_brkout_mode": "2x50G" + }, + "Ethernet44": { + "default_brkout_mode": "2x50G" + }, + "Ethernet48": { + "default_brkout_mode": "2x50G" + }, + "Ethernet52": { + "default_brkout_mode": "2x50G" + }, + "Ethernet56": { + "default_brkout_mode": "2x50G" + }, + "Ethernet60": { + "default_brkout_mode": "2x50G" + }, + "Ethernet64": { + "default_brkout_mode": "2x50G" + }, + "Ethernet68": { + "default_brkout_mode": "2x50G" + }, + "Ethernet72": { + "default_brkout_mode": "2x50G" + }, + "Ethernet76": { + "default_brkout_mode": "2x50G" + }, + "Ethernet80": { + "default_brkout_mode": "2x50G" + }, + "Ethernet84": { + "default_brkout_mode": "2x50G" + }, + "Ethernet88": { + "default_brkout_mode": "2x50G" + }, + "Ethernet92": { + "default_brkout_mode": "2x50G" + }, + "Ethernet96": { + "default_brkout_mode": "2x50G" + }, + "Ethernet100": { + "default_brkout_mode": "2x50G" + }, + "Ethernet104": { + "default_brkout_mode": "2x50G" + }, + "Ethernet108": { + "default_brkout_mode": "2x50G" + }, + "Ethernet112": { + "default_brkout_mode": "2x50G" + }, + "Ethernet116": { + "default_brkout_mode": "2x50G" + }, + "Ethernet120": { + "default_brkout_mode": "2x50G" + }, + "Ethernet124": { + "default_brkout_mode": "2x50G" + } + } +} \ No newline at end of file diff --git a/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010/hwsku.json b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010/hwsku.json new file mode 100644 index 000000000000..984ba3e4f15e --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010/hwsku.json @@ -0,0 +1,100 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet4": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet8": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet12": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet16": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet20": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet24": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet28": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet32": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet36": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet40": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet44": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet48": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet52": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet56": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet60": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet64": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet68": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet72": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet76": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet80": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet84": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet88": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet92": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet96": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet100": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet104": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet108": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet112": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet116": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet120": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet124": { + "default_brkout_mode": "1x100G[40G]" + } + } +} \ No newline at end of file diff --git a/device/celestica/x86_64-cel_seastone-r0/fancontrol-B2F b/device/celestica/x86_64-cel_seastone-r0/fancontrol-B2F index c2132d7f2806..f3277db14df2 100644 --- a/device/celestica/x86_64-cel_seastone-r0/fancontrol-B2F +++ b/device/celestica/x86_64-cel_seastone-r0/fancontrol-B2F @@ -8,4 +8,5 @@ MINSTART=13-002e/pwm1=89 13-002e/pwm2=89 13-002e/pwm3=89 13-002e/pwm4=89 13-002e MINSTOP=13-002e/pwm1=89 13-002e/pwm2=89 13-002e/pwm3=89 13-002e/pwm4=89 13-002e/pwm5=89 13-004d/pwm1=89 13-004d/pwm2=89 13-004d/pwm3=89 13-004d/pwm4=89 13-004d/pwm5=89 MINPWM=13-002e/pwm1=89 13-002e/pwm2=89 13-002e/pwm3=89 13-002e/pwm4=89 13-002e/pwm5=89 13-004d/pwm1=89 13-004d/pwm2=89 13-004d/pwm3=89 13-004d/pwm4=89 13-004d/pwm5=89 MAXPWM=13-002e/pwm1=255 13-002e/pwm2=255 13-002e/pwm3=255 13-002e/pwm4=255 13-002e/pwm5=255 13-004d/pwm1=255 13-004d/pwm2=255 13-004d/pwm3=255 13-004d/pwm4=255 13-004d/pwm5=255 -THYST=13-002e/pwm1=3 13-002e/pwm2=3 13-002e/pwm3=3 13-002e/pwm4=3 13-002e/pwm5=3 13-004d/pwm1=3 13-004d/pwm2=3 13-004d/pwm3=3 13-004d/pwm4=3 13-004d/pwm5=3 \ No newline at end of file +THYST=13-002e/pwm1=3 13-002e/pwm2=3 13-002e/pwm3=3 13-002e/pwm4=3 13-002e/pwm5=3 13-004d/pwm1=3 13-004d/pwm2=3 13-004d/pwm3=3 13-004d/pwm4=3 13-004d/pwm5=3 + diff --git a/device/celestica/x86_64-cel_seastone-r0/platform.json b/device/celestica/x86_64-cel_seastone-r0/platform.json new file mode 100644 index 000000000000..66ed83ef2060 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/platform.json @@ -0,0 +1,196 @@ +{ + "interfaces": { + "Ethernet0": { + "index": "1,1,1,1", + "lanes": "65,66,67,68", + "alias_at_lanes": "Eth1/1, Eth1/2, Eth1/3, Eth1/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet4": { + "index": "2,2,2,2", + "lanes": "69,70,71,72", + "alias_at_lanes": "Eth2/1, Eth2/2, Eth2/3, Eth2/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet8": { + "index": "3,3,3,3", + "lanes": "73,74,75,76", + "alias_at_lanes": "Eth3/1, Eth3/2, Eth3/3, Eth3/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet12": { + "index": "4,4,4,4", + "lanes": "77,78,79,80", + "alias_at_lanes": "Eth4/1, Eth4/2, Eth4/3, Eth4/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet16": { + "index": "5,5,5,5", + "lanes": "33,34,35,36", + "alias_at_lanes": "Eth5/1, Eth5/2, Eth5/3, Eth5/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet20": { + "index": "6,6,6,6", + "lanes": "37,38,39,40", + "alias_at_lanes": "Eth6/1, Eth6/2, Eth6/3, Eth6/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet24": { + "index": "7,7,7,7", + "lanes": "41,42,43,44", + "alias_at_lanes": "Eth7/1, Eth7/2, Eth7/3, Eth7/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet28": { + "index": "8,8,8,8", + "lanes": "45,46,47,48", + "alias_at_lanes": "Eth8/1, Eth8/2, Eth8/3, Eth8/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet32": { + "index": "9,9,9,9", + "lanes": "49,50,51,52", + "alias_at_lanes": "Eth9/1, Eth9/2, Eth9/3, Eth9/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet36": { + "index": "10,10,10,10", + "lanes": "53,54,55,56", + "alias_at_lanes": "Eth10/1, Eth10/2, Eth10/3, Eth10/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet40": { + "index": "11,11,11,11", + "lanes": "57,58,59,60", + "alias_at_lanes": "Eth11/1, Eth11/2, Eth11/3, Eth11/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet44": { + "index": "12,12,12,12", + "lanes": "61,62,63,64", + "alias_at_lanes": "Eth12/1, Eth12/2, Eth12/3, Eth12/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet48": { + "index": "13,13,13,13", + "lanes": "81,82,83,84", + "alias_at_lanes": "Eth13/1, Eth13/2, Eth13/3, Eth13/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet52": { + "index": "14,14,14,14", + "lanes": "85,86,87,88", + "alias_at_lanes": "Eth14/1, Eth14/2, Eth14/3, Eth14/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet56": { + "index": "15,15,15,15", + "lanes": "89,90,91,92", + "alias_at_lanes": "Eth15/1, Eth15/2, Eth15/3, Eth15/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet60": { + "index": "16,16,16,16", + "lanes": "93,94,95,96", + "alias_at_lanes": "Eth16/1, Eth16/2, Eth16/3, Eth16/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet64": { + "index": "17,17,17,17", + "lanes": "97,98,99,100", + "alias_at_lanes": "Eth17/1, Eth17/2, Eth17/3, Eth17/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet68": { + "index": "18,18,18,18", + "lanes": "101,102,103,104", + "alias_at_lanes": "Eth18/1, Eth18/2, Eth18/3, Eth18/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet72": { + "index": "19,19,19,19", + "lanes": "105,106,107,108", + "alias_at_lanes": "Eth19/1, Eth19/2, Eth19/3, Eth19/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet76": { + "index": "20,20,20,20", + "lanes": "109,110,111,112", + "alias_at_lanes": "Eth20/1, Eth20/2, Eth20/3, Eth20/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet80": { + "index": "21,21,21,21", + "lanes": "1,2,3,4", + "alias_at_lanes": "Eth21/1, Eth21/2, Eth21/3, Eth21/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet84": { + "index": "22,22,22,22", + "lanes": "5,6,7,8", + "alias_at_lanes": "Eth22/1, Eth22/2, Eth22/3, Eth22/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet88": { + "index": "23,23,23,23", + "lanes": "9,10,11,12", + "alias_at_lanes": "Eth23/1, Eth23/2, Eth23/3, Eth23/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet92": { + "index": "24,24,24,24", + "lanes": "13,14,15,16", + "alias_at_lanes": "Eth24/1, Eth24/2, Eth24/3, Eth24/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet96": { + "index": "25,25,25,25", + "lanes": "17,18,19,20", + "alias_at_lanes": "Eth25/1, Eth25/2, Eth25/3, Eth25/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet100": { + "index": "26,26,26,26", + "lanes": "21,22,23,24", + "alias_at_lanes": "Eth26/1, Eth26/2, Eth26/3, Eth26/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet104": { + "index": "27,27,27,27", + "lanes": "25,26,27,28", + "alias_at_lanes": "Eth27/1, Eth27/2, Eth27/3, Eth27/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet108": { + "index": "28,28,28,28", + "lanes": "29,30,31,32", + "alias_at_lanes": "Eth28/1, Eth28/2, Eth28/3, Eth28/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet112": { + "index": "29,29,29,29", + "lanes": "113,114,115,116", + "alias_at_lanes": "Eth29/1, Eth29/2, Eth29/3, Eth29/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet116": { + "index": "30,30,30,30", + "lanes": "117,118,119,120", + "alias_at_lanes": "Eth30/1, Eth30/2, Eth30/3, Eth30/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet120": { + "index": "31,31,31,31", + "lanes": "121,122,123,124", + "alias_at_lanes": "Eth31/1, Eth31/2, Eth31/3, Eth31/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet124": { + "index": "32,32,32,32", + "lanes": "125,126,127,128", + "alias_at_lanes": "Eth32/1, Eth32/2, Eth32/3, Eth32/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + } + } +} \ No newline at end of file diff --git a/device/celestica/x86_64-cel_seastone-r0/plugins/eeprom.py b/device/celestica/x86_64-cel_seastone-r0/plugins/eeprom.py index 29f01a07fc73..bba16943966a 100644 --- a/device/celestica/x86_64-cel_seastone-r0/plugins/eeprom.py +++ b/device/celestica/x86_64-cel_seastone-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Celestica DX010 # @@ -11,8 +9,8 @@ try: from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): @@ -20,4 +18,3 @@ class board(eeprom_tlvinfo.TlvInfoDecoder): def __init__(self, name, path, cpld_root, ro): self.eeprom_path = "/sys/class/i2c-adapter/i2c-12/12-0050/eeprom" super(board, self).__init__(self.eeprom_path, 0, '', True) - diff --git a/device/celestica/x86_64-cel_seastone-r0/plugins/pcie.yaml b/device/celestica/x86_64-cel_seastone-r0/plugins/pcie.yaml new file mode 100644 index 000000000000..18e52be96474 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/plugins/pcie.yaml @@ -0,0 +1,75 @@ +- bus: '00' + dev: '00' + fn: '0' + id: 1f0c + name: 'Host bridge: Intel Corporation Atom processor C2000 SoC Transaction Router' +- bus: '00' + dev: '01' + fn: '0' + id: 1f10 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 1' +- bus: '00' + dev: '02' + fn: '0' + id: 1f11 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 2' +- bus: '00' + dev: '03' + fn: '0' + id: 1f12 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 3' +- bus: '00' + dev: 0e + fn: '0' + id: 1f14 + name: 'Host bridge: Intel Corporation Atom processor C2000 RAS' +- bus: '00' + dev: 0f + fn: '0' + id: 1f16 + name: 'IOMMU: Intel Corporation Atom processor C2000 RCEC' +- bus: '00' + dev: '13' + fn: '0' + id: 1f15 + name: 'System peripheral: Intel Corporation Atom processor C2000 SMBus 2.0' +- bus: '00' + dev: '14' + fn: '0' + id: 1f41 + name: 'Ethernet controller: Intel Corporation Ethernet Connection I354' +- bus: '00' + dev: '16' + fn: '0' + id: 1f2c + name: 'USB controller: Intel Corporation Atom processor C2000 USB Enhanced Host Controller' +- bus: '00' + dev: '17' + fn: '0' + id: 1f22 + name: 'SATA controller: Intel Corporation Atom processor C2000 AHCI SATA2 Controller' +- bus: '00' + dev: '18' + fn: '0' + id: 1f32 + name: 'SATA controller: Intel Corporation Atom processor C2000 AHCI SATA3 Controller' +- bus: '00' + dev: 1f + fn: '0' + id: 1f38 + name: 'ISA bridge: Intel Corporation Atom processor C2000 PCU' +- bus: '00' + dev: 1f + fn: '3' + id: 1f3c + name: 'SMBus: Intel Corporation Atom processor C2000 PCU SMBus' +- bus: '01' + dev: '00' + fn: '0' + id: b960 + name: 'Ethernet controller: Broadcom Limited Broadcom BCM56960 Switch ASIC' +- bus: '01' + dev: '00' + fn: '1' + id: b960 + name: 'Ethernet controller: Broadcom Limited Broadcom BCM56960 Switch ASIC' diff --git a/device/celestica/x86_64-cel_seastone-r0/plugins/sfputil.py b/device/celestica/x86_64-cel_seastone-r0/plugins/sfputil.py index c361659b0f17..ca960dd8136d 100644 --- a/device/celestica/x86_64-cel_seastone-r0/plugins/sfputil.py +++ b/device/celestica/x86_64-cel_seastone-r0/plugins/sfputil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python -# # Platform-specific SFP transceiver interface for SONiC # @@ -29,7 +27,7 @@ def port_end(self): @property def qsfp_ports(self): - return range(self.PORT_START, self.PORTS_IN_BLOCK + 1) + return list(range(self.PORT_START, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -54,7 +52,7 @@ def get_presence(self, port_num): try: reg_file = open("/sys/devices/platform/dx010_cpld/qsfp_modprs", "r") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -85,7 +83,7 @@ def get_low_power_mode(self, port_num): try: reg_file = open("/sys/devices/platform/dx010_cpld/qsfp_lpmode", "r") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -116,7 +114,7 @@ def set_low_power_mode(self, port_num, lpmode): try: reg_file = open("/sys/devices/platform/dx010_cpld/qsfp_lpmode", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -156,7 +154,7 @@ def reset(self, port_num): try: reg_file = open("/sys/devices/platform/dx010_cpld/qsfp_reset", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -190,7 +188,7 @@ def reset(self, port_num): try: reg_file = open("/sys/devices/platform/dx010_cpld/qsfp_reset", "w") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = reg_value | mask diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/__init__.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/__init__.py index d82f3749319c..db1748e44d2c 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/__init__.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/__init__.py @@ -1,2 +1,2 @@ -__all__ = ["platform", "chassis"] -from sonic_platform import * +from . import chassis +from . import platform 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 7db46e55bd8c..1b5c5773e27b 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 @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Celestica # @@ -8,20 +6,13 @@ # ############################################################################# -import sys -import re -import os -import subprocess -import json - try: + import sys from sonic_platform_base.chassis_base import ChassisBase - from sonic_platform.fan import Fan - from sonic_platform.psu import Psu - from sonic_platform.component import Component - from sonic_platform.thermal import Thermal - from sonic_platform.sfp import Sfp - from sonic_platform.eeprom import Tlv + from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper + from sonic_py_common import device_info + from .event import SfpEvent + from .helper import APIHelper except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -33,9 +24,9 @@ NUM_COMPONENT = 5 RESET_REGISTER = "0x103" HOST_REBOOT_CAUSE_PATH = "/host/reboot-cause/" -PMON_REBOOT_CAUSE_PATH = "/usr/share/sonic/platform/api_files/reboot-cause/" REBOOT_CAUSE_FILE = "reboot-cause.txt" PREV_REBOOT_CAUSE_FILE = "previous-reboot-cause.txt" +GETREG_PATH = "/sys/devices/platform/dx010_cpld/getreg" HOST_CHK_CMD = "docker > /dev/null 2>&1" @@ -44,39 +35,64 @@ class Chassis(ChassisBase): def __init__(self): ChassisBase.__init__(self) - self.config_data = {} + self._api_helper = APIHelper() + self.sfp_module_initialized = False + self.__initialize_eeprom() + self.is_host = self._api_helper.is_host() + + if not self.is_host: + self.__initialize_fan() + self.__initialize_psu() + self.__initialize_thermals() + else: + self.__initialize_components() + + def __initialize_sfp(self): + sfputil_helper = SfpUtilHelper() + port_config_file_path = device_info.get_path_to_port_config_file() + sfputil_helper.read_porttab_mappings(port_config_file_path, 0) + + from sonic_platform.sfp import Sfp + for index in range(0, NUM_SFP): + name_idx = 0 if index+1 == NUM_SFP else index+1 + sfp = Sfp(index, sfputil_helper.logical[name_idx]) + self._sfp_list.append(sfp) + self.sfp_module_initialized = True + + def __initialize_psu(self): + from sonic_platform.psu import Psu + for index in range(0, NUM_PSU): + psu = Psu(index) + self._psu_list.append(psu) + + def __initialize_fan(self): + from sonic_platform.fan import Fan for fant_index in range(0, NUM_FAN_TRAY): for fan_index in range(0, NUM_FAN): fan = Fan(fant_index, fan_index) self._fan_list.append(fan) - for index in range(0, NUM_PSU): - psu = Psu(index) - self._psu_list.append(psu) + + def __initialize_thermals(self): + from sonic_platform.thermal import Thermal + airflow = self.__get_air_flow() for index in range(0, NUM_THERMAL): - thermal = Thermal(index) + thermal = Thermal(index, airflow) self._thermal_list.append(thermal) - # 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) + def __initialize_eeprom(self): + from sonic_platform.eeprom import Tlv self._eeprom = Tlv() - def __is_host(self): - return os.system(HOST_CHK_CMD) == 0 + def __initialize_components(self): + from sonic_platform.component import Component + for index in range(0, NUM_COMPONENT): + component = Component(index) + self._component_list.append(component) - def __read_txt_file(self, file_path): - try: - with open(file_path, 'r') as fd: - data = fd.read() - return data.strip() - except IOError: - pass - return None + def __get_air_flow(self): + air_flow_path = '/usr/share/sonic/device/{}/fan_airflow'.format(self._api_helper.platform) if self.is_host else '/usr/share/sonic/platform/fan_airflow' + air_flow = self._api_helper.read_one_line_file(air_flow_path) + return air_flow or 'B2F' def get_base_mac(self): """ @@ -87,14 +103,6 @@ def get_base_mac(self): """ return self._eeprom.get_mac() - def get_serial_number(self): - """ - Retrieves the hardware serial number for the chassis - Returns: - A string containing the hardware serial number for this chassis. - """ - return self._eeprom.get_serial() - def get_system_eeprom_info(self): """ Retrieves the full content of system EEPROM information for the chassis @@ -108,44 +116,130 @@ def get_system_eeprom_info(self): def get_reboot_cause(self): """ Retrieves the cause of the previous reboot - Returns: A tuple (string, string) where the first element is a string containing the cause of the previous reboot. This string must be one of the predefined strings in this class. If the first string is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used to pass a description of the reboot cause. + + REBOOT_CAUSE_POWER_LOSS = "Power Loss" + REBOOT_CAUSE_THERMAL_OVERLOAD_CPU = "Thermal Overload: CPU" + REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC = "Thermal Overload: ASIC" + REBOOT_CAUSE_THERMAL_OVERLOAD_OTHER = "Thermal Overload: Other" + REBOOT_CAUSE_INSUFFICIENT_FAN_SPEED = "Insufficient Fan Speed" + REBOOT_CAUSE_WATCHDOG = "Watchdog" + REBOOT_CAUSE_HARDWARE_OTHER = "Hardware - Other" + REBOOT_CAUSE_NON_HARDWARE = "Non-Hardware" + """ - description = 'None' - reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER + reboot_cause_path = (HOST_REBOOT_CAUSE_PATH + REBOOT_CAUSE_FILE) + sw_reboot_cause = self._api_helper.read_txt_file( + reboot_cause_path) or "Unknown" + hw_reboot_cause = self._api_helper.get_cpld_reg_value( + GETREG_PATH, RESET_REGISTER) - reboot_cause_path = (HOST_REBOOT_CAUSE_PATH + REBOOT_CAUSE_FILE) if self.__is_host( - ) else PMON_REBOOT_CAUSE_PATH + REBOOT_CAUSE_FILE - prev_reboot_cause_path = (HOST_REBOOT_CAUSE_PATH + PREV_REBOOT_CAUSE_FILE) if self.__is_host( - ) else PMON_REBOOT_CAUSE_PATH + PREV_REBOOT_CAUSE_FILE + prev_reboot_cause = { + '0x11': (self.REBOOT_CAUSE_POWER_LOSS, 'Power on reset'), + '0x22': (self.REBOOT_CAUSE_HARDWARE_OTHER, 'CPLD_WD_RESET'), + '0x33': (self.REBOOT_CAUSE_HARDWARE_OTHER, 'Power cycle reset triggered by CPU'), + '0x44': (self.REBOOT_CAUSE_HARDWARE_OTHER, 'Power cycle reset triggered by reset button'), + '0x55': (self.REBOOT_CAUSE_THERMAL_OVERLOAD_CPU, ''), + '0x66': (self.REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC, ''), + '0x77': (self.REBOOT_CAUSE_WATCHDOG, '') + }.get(hw_reboot_cause, (self.REBOOT_CAUSE_HARDWARE_OTHER, 'Unknown reason')) - hw_reboot_cause = self._component_list[0].get_register_value(RESET_REGISTER) + if sw_reboot_cause != 'Unknown' and hw_reboot_cause == '0x11': + prev_reboot_cause = ( + self.REBOOT_CAUSE_NON_HARDWARE, sw_reboot_cause) - sw_reboot_cause = self.__read_txt_file( - reboot_cause_path) or "Unknown" - prev_sw_reboot_cause = self.__read_txt_file( - prev_reboot_cause_path) or "Unknown" - - if sw_reboot_cause == "Unknown" and (prev_sw_reboot_cause == "Unknown" or prev_sw_reboot_cause == self.REBOOT_CAUSE_POWER_LOSS) and hw_reboot_cause == "0x11": - reboot_cause = self.REBOOT_CAUSE_POWER_LOSS - elif sw_reboot_cause != "Unknown" and hw_reboot_cause == "0x11": - reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE - description = sw_reboot_cause - elif prev_reboot_cause_path != "Unknown" and hw_reboot_cause == "0x11": - reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE - description = prev_sw_reboot_cause - elif hw_reboot_cause == "0x22": - reboot_cause = self.REBOOT_CAUSE_WATCHDOG, - else: - reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER - description = 'Unknown reason' + return prev_reboot_cause + + + def get_change_event(self, timeout=0): + """ + Returns a nested dictionary containing all devices which have + experienced a change at chassis level + Args: + timeout: Timeout in milliseconds (optional). If timeout == 0, + this method will block until a change is detected. + Returns: + (bool, dict): + - True if call successful, False if not; + - A nested dictionary where key is a device type, + value is a dictionary with key:value pairs in the format of + {'device_id':'device_event'}, + where device_id is the device ID for this device and + device_event, + status='1' represents device inserted, + status='0' represents device removed. + Ex. {'fan':{'0':'0', '2':'1'}, 'sfp':{'11':'0'}} + indicates that fan 0 has been removed, fan 2 + has been inserted and sfp 11 has been removed. + """ + # SFP event + if not self.sfp_module_initialized: + self.__initialize_sfp() + + sfp_event = SfpEvent(self._sfp_list).get_sfp_event(timeout) + if sfp_event: + return True, {'sfp': sfp_event} - return (reboot_cause, description) + return False, {'sfp': {}} + + ############################################################## + ######################## SFP methods ######################### + ############################################################## + + def get_num_sfps(self): + """ + Retrieves the number of sfps available on this chassis + Returns: + An integer, the number of sfps available on this chassis + """ + if not self.sfp_module_initialized: + self.__initialize_sfp() + + return len(self._sfp_list) + + def get_all_sfps(self): + """ + Retrieves all sfps available on this chassis + Returns: + A list of objects derived from SfpBase representing all sfps + available on this chassis + """ + if not self.sfp_module_initialized: + self.__initialize_sfp() + + return self._sfp_list + + 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, 1 for Ethernet0, 2 for Ethernet4 and so on. + Returns: + An object dervied from SfpBase representing the specified sfp + """ + sfp = None + if not self.sfp_module_initialized: + self.__initialize_sfp() + + try: + # The index will start from 1 + sfp = self._sfp_list[index-1] + except IndexError: + sys.stderr.write("SFP index {} out of range (1-{})\n".format( + index, len(self._sfp_list))) + return sfp + + ############################################################## + ####################### Other methods ######################## + ############################################################## def get_watchdog(self): """ @@ -159,3 +253,51 @@ def get_watchdog(self): self._watchdog = Watchdog() return self._watchdog + + ############################################################## + ###################### Device methods ######################## + ############################################################## + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + return self._api_helper.hwsku + + def get_presence(self): + """ + Retrieves the presence of the Chassis + Returns: + bool: True if Chassis is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + return self._eeprom.get_pn() + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + return self._eeprom.get_serial() + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return True + + def get_thermal_manager(self): + from .thermal_manager import ThermalManager + return ThermalManager 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 d94a93474452..2833bf4d1cc5 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 @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Celestica # @@ -8,14 +6,13 @@ # ############################################################################# -import json import os.path import shutil -import shlex import subprocess try: from sonic_platform_base.component_base import ComponentBase + from .helper import APIHelper except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -29,7 +26,8 @@ GETREG_PATH = "/sys/devices/platform/dx010_cpld/getreg" BIOS_VERSION_PATH = "/sys/class/dmi/id/bios_version" COMPONENT_NAME_LIST = ["CPLD1", "CPLD2", "CPLD3", "CPLD4", "BIOS"] -COMPONENT_DES_LIST = ["CPLD1", "CPLD2", "CPLD3", "CPLD4", "Basic Input/Output System"] +COMPONENT_DES_LIST = ["Used for managing the CPU", + "Used for managing QSFP+ ports (1-10)", "Used for managing QSFP+ ports (11-20)", "Used for managing QSFP+ ports (22-32)", "Basic Input/Output System"] class Component(ComponentBase): @@ -40,24 +38,9 @@ class Component(ComponentBase): def __init__(self, component_index): ComponentBase.__init__(self) self.index = component_index + self._api_helper = APIHelper() self.name = self.get_name() - def __run_command(self, command): - # Run bash command and print output to stdout - try: - process = subprocess.Popen( - shlex.split(command), stdout=subprocess.PIPE) - while True: - output = process.stdout.readline() - if output == '' and process.poll() is not None: - break - rc = process.poll() - if rc != 0: - return False - except: - return False - return True - def __get_bios_version(self): # Retrieves the BIOS firmware version try: @@ -71,7 +54,7 @@ def get_register_value(self, register): # Retrieves the cpld register value cmd = "echo {1} > {0}; cat {0}".format(GETREG_PATH, register) p = subprocess.Popen( - cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) raw_data, err = p.communicate() if err is not '': return None diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/eeprom.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/eeprom.py index dffda1a3c050..b2b4a8122590 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/eeprom.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Celestica Seastone-DX010 # @@ -13,13 +11,17 @@ import glob import os import sys - import imp import re from array import array - from cStringIO import StringIO + + if sys.version_info.major == 3: + from io import StringIO + else: + from cStringIO import StringIO + from sonic_platform_base.sonic_eeprom import eeprom_dts from sonic_platform_base.sonic_eeprom import eeprom_tlvinfo -except ImportError, e: +except ImportError as e: raise ImportError(str(e) + "- required module not found") CACHE_ROOT = '/var/cache/sonic/decode-syseeprom' diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/event.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/event.py new file mode 100644 index 000000000000..351b2a5ac087 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/event.py @@ -0,0 +1,52 @@ +try: + import select + from .helper import APIHelper + from sonic_py_common.logger import Logger +except ImportError as e: + raise ImportError(repr(e) + " - required module not found") + + +class SfpEvent: + ''' Listen to insert/remove sfp events ''' + + QSFP_MODPRS_IRQ = '/sys/devices/platform/dx010_cpld/qsfp_modprs_irq' + GPIO_SUS6 = "/sys/devices/platform/slx-ich.0/sci_int_gpio_sus6" + + def __init__(self, sfp_list): + self._api_helper = APIHelper() + self._sfp_list = sfp_list + self._logger = Logger() + + def get_sfp_event(self, timeout): + epoll = select.epoll() + port_dict = {} + timeout_sec = timeout/1000 + + try: + # We get notified when there is an SCI interrupt from GPIO SUS6 + fd = open(self.GPIO_SUS6, "r") + fd.read() + + epoll.register(fd.fileno(), select.EPOLLIN & select.EPOLLET) + events = epoll.poll(timeout=timeout_sec if timeout != 0 else -1) + if events: + # Read the QSFP ABS interrupt & status registers + port_changes = self._api_helper.read_one_line_file( + self.QSFP_MODPRS_IRQ) + changes = int(port_changes, 16) + for sfp in self._sfp_list: + change = (changes >> sfp.port_num-1) & 1 + if change == 1: + port_dict[str(sfp.port_num)] = str( + int(sfp.get_presence())) + + return port_dict + except Exception as e: + self._logger.log_error("Failed to detect SfpEvent - " + repr(e)) + return False + + finally: + fd.close() + epoll.close() + + return False diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/fan.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/fan.py index c0724e9bb688..bf2b27019b63 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/fan.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/fan.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Celestica # @@ -14,6 +12,7 @@ try: from sonic_platform_base.fan_base import FanBase + from .helper import APIHelper except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -38,13 +37,16 @@ "addr": "5b" }, } +NULL_VAL = "N/A" class Fan(FanBase): """Platform-specific Fan class""" def __init__(self, fan_tray_index, fan_index=0, is_psu_fan=False, psu_index=0): + FanBase.__init__(self) self.fan_index = fan_index + self._api_helper = APIHelper() self.fan_tray_index = fan_tray_index self.is_psu_fan = is_psu_fan if self.is_psu_fan: @@ -75,16 +77,6 @@ def __init__(self, fan_tray_index, fan_index=0, is_psu_fan=False, psu_index=0): {'prs': 14, 'dir': 19, 'color': {'red': 37, 'green': 38}}, # 4 {'prs': 12, 'dir': 17, 'color': {'red': 33, 'green': 34}}, # 5 ] - FanBase.__init__(self) - - def __read_txt_file(self, file_path): - try: - with open(file_path, 'r') as fd: - data = fd.read() - return data.strip() - except IOError: - pass - return "" def __write_txt_file(self, file_path, value): try: @@ -105,7 +97,7 @@ def __search_file_by_name(self, directory, file_name): def __get_gpio_base(self): for r in os.listdir(GPIO_DIR): label_path = os.path.join(GPIO_DIR, r, "label") - if "gpiochip" in r and GPIO_LABEL in self.__read_txt_file(label_path): + if "gpiochip" in r and GPIO_LABEL in self._api_helper.read_txt_file(label_path): return int(r[8:], 10) return 216 # Reserve @@ -113,7 +105,7 @@ def __get_gpio_value(self, pinnum): gpio_base = self.dx010_fan_gpio[0]['base'] gpio_dir = GPIO_DIR + '/gpio' + str(gpio_base+pinnum) gpio_file = gpio_dir + "/value" - retval = self.__read_txt_file(gpio_file) + retval = self._api_helper.read_txt_file(gpio_file) return retval.rstrip('\r\n') def __set_gpio_value(self, pinnum, value=0): @@ -154,7 +146,8 @@ def get_speed(self): fan_speed_sysfs_name = "fan{}_input".format(self.fan_index+1) fan_speed_sysfs_path = self.__search_file_by_name( self.psu_hwmon_path, fan_speed_sysfs_name) - fan_speed_rpm = self.__read_txt_file(fan_speed_sysfs_path) or 0 + fan_speed_rpm = self._api_helper.read_txt_file( + fan_speed_sysfs_path) or 0 fan_speed_raw = float(fan_speed_rpm)/PSU_FAN_MAX_RPM * 100 speed = math.ceil(float(fan_speed_rpm) * 100 / PSU_FAN_MAX_RPM) elif self.get_presence(): @@ -164,7 +157,7 @@ def get_speed(self): sysfs_path = "%s%s/%s" % ( EMC2305_PATH, device, EMC2305_FAN_INPUT) sysfs_path = sysfs_path.format(fan_index[self.fan_tray_index]) - raw = self.__read_txt_file(sysfs_path).strip('\r\n') + raw = self._api_helper.read_txt_file(sysfs_path).strip('\r\n') pwm = int(raw, 10) if raw else 0 speed = math.ceil(float(pwm * 100 / EMC2305_MAX_PWM)) @@ -183,19 +176,7 @@ def get_target_speed(self): 0 : when PWM mode is use pwm : when pwm mode is not use """ - target = 0 - if not self.is_psu_fan: - chip = self.emc2305_chip_mapping[self.fan_index] - device = chip['device'] - fan_index = chip['index_map'] - sysfs_path = "%s%s/%s" % ( - EMC2305_PATH, device, EMC2305_FAN_TARGET) - sysfs_path = sysfs_path.format(fan_index[self.fan_tray_index]) - raw = self.__read_txt_file(sysfs_path).strip('\r\n') - pwm = int(raw, 10) if raw else 0 - target = math.ceil(float(pwm) * 100 / EMC2305_MAX_PWM) - - return target + return 'N/A' def get_speed_tolerance(self): """ @@ -284,11 +265,59 @@ def get_name(self): def get_presence(self): """ - Retrieves the presence of the PSU + Retrieves the presence of the FAN Returns: - bool: True if PSU is present, False if not + bool: True if FAN is present, False if not """ present_str = self.__get_gpio_value( self.dx010_fan_gpio[self.fan_tray_index+1]['prs']) return int(present_str, 10) == 0 if not self.is_psu_fan else True + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + if self.is_psu_fan: + return NULL_VAL + + model = NULL_VAL + return model + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + if self.is_psu_fan: + return NULL_VAL + + serial = NULL_VAL + return serial + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + status = 1 + if self.is_psu_fan: + fan_fault_sysfs_name = "fan1_fault" + fan_fault_sysfs_path = self.__search_file_by_name( + self.psu_hwmon_path, fan_fault_sysfs_name) + status = self._api_helper.read_one_line_file(fan_fault_sysfs_path) + + elif self.get_presence(): + chip = self.emc2305_chip_mapping[self.fan_index] + device = chip['device'] + fan_index = chip['index_map'] + sysfs_path = "%s%s/%s" % ( + EMC2305_PATH, device, 'fan{}_fault') + sysfs_path = sysfs_path.format(fan_index[self.fan_tray_index]) + status = self._api_helper.read_one_line_file(sysfs_path) + + return False if int(status) != 0 else True diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/helper.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/helper.py new file mode 100644 index 000000000000..140c62c08666 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/helper.py @@ -0,0 +1,133 @@ +import os +import struct +import subprocess +from mmap import * + +from sonic_py_common import device_info + +HOST_CHK_CMD = "docker > /dev/null 2>&1" +EMPTY_STRING = "" + + +class APIHelper(): + + def __init__(self): + (self.platform, self.hwsku) = device_info.get_platform_and_hwsku() + + def is_host(self): + return os.system(HOST_CHK_CMD) == 0 + + def pci_get_value(self, resource, offset): + status = True + result = "" + try: + fd = os.open(resource, os.O_RDWR) + mm = mmap(fd, 0) + mm.seek(int(offset)) + read_data_stream = mm.read(4) + result = struct.unpack('I', read_data_stream) + except: + status = False + return status, result + + def run_command(self, cmd): + status = True + result = "" + try: + p = subprocess.Popen( + cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err == '': + result = raw_data.strip() + except: + status = False + return status, result + + def run_interactive_command(self, cmd): + try: + os.system(cmd) + except: + return False + return True + + def read_txt_file(self, file_path): + try: + with open(file_path, 'r') as fd: + data = fd.read() + return data.strip() + except IOError: + pass + return None + + def read_one_line_file(self, file_path): + try: + with open(file_path, 'r') as fd: + data = fd.readline() + return data.strip() + except IOError: + pass + return None + + def write_txt_file(self, file_path, value): + try: + with open(file_path, 'w') as fd: + fd.write(str(value)) + except Exception: + return False + return True + + def get_cpld_reg_value(self, getreg_path, register): + cmd = "echo {1} > {0}; cat {0}".format(getreg_path, register) + status, result = self.run_command(cmd) + return result if status else None + + def ipmi_raw(self, netfn, cmd): + status = True + result = "" + try: + cmd = "ipmitool raw {} {}".format(str(netfn), str(cmd)) + p = subprocess.Popen( + cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err == '': + result = raw_data.strip() + else: + status = False + except: + status = False + return status, result + + def ipmi_fru_id(self, id, key=None): + status = True + result = "" + try: + cmd = "ipmitool fru print {}".format(str( + id)) if not key else "ipmitool fru print {0} | grep '{1}' ".format(str(id), str(key)) + + p = subprocess.Popen( + cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err == '': + result = raw_data.strip() + else: + status = False + except: + status = False + return status, result + + def ipmi_set_ss_thres(self, id, threshold_key, value): + status = True + result = "" + try: + cmd = "ipmitool sensor thresh '{}' {} {}".format( + str(id), str(threshold_key), str(value)) + p = subprocess.Popen( + cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err == '': + result = raw_data.strip() + else: + status = False + except: + status = False + return status, result diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/platform.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/platform.py index a632de87e742..7d98ec9f7cdf 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/platform.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/platform.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Celestica # diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/psu.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/psu.py index 8558b0b0cadd..f9a342953aeb 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/psu.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/psu.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Celestica # @@ -14,6 +12,7 @@ try: from sonic_platform_base.psu_base import PsuBase from sonic_platform.fan import Fan + from .helper import APIHelper except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -41,6 +40,7 @@ class Psu(PsuBase): def __init__(self, psu_index): PsuBase.__init__(self) self.index = psu_index + self._api_helper = APIHelper() self.green_led_path = GREEN_LED_PATH.format(self.index+1) self.dx010_psu_gpio = [ {'base': self.__get_gpio_base()}, @@ -54,27 +54,18 @@ def __init__(self, psu_index): fan = Fan(fan_index, 0, is_psu_fan=True, psu_index=self.index) self._fan_list.append(fan) - def __read_txt_file(self, file_path): - try: - with open(file_path, 'r') as fd: - data = fd.read() - return data.strip() - except IOError: - pass - return "" - def __search_file_by_contain(self, directory, search_str, file_start): for dirpath, dirnames, files in os.walk(directory): for name in files: file_path = os.path.join(dirpath, name) - if name.startswith(file_start) and search_str in self.__read_txt_file(file_path): + if name.startswith(file_start) and search_str in self._api_helper.read_txt_file(file_path): return file_path return None def __get_gpio_base(self): for r in os.listdir(GPIO_DIR): label_path = os.path.join(GPIO_DIR, r, "label") - if "gpiochip" in r and GPIO_LABEL in self.__read_txt_file(label_path): + if "gpiochip" in r and GPIO_LABEL in self._api_helper.read_txt_file(label_path): return int(r[8:], 10) return 216 # Reserve @@ -82,7 +73,7 @@ def __get_gpio_value(self, pinnum): gpio_base = self.dx010_psu_gpio[0]['base'] gpio_dir = GPIO_DIR + '/gpio' + str(gpio_base+pinnum) gpio_file = gpio_dir + "/value" - retval = self.__read_txt_file(gpio_file) + retval = self._api_helper.read_txt_file(gpio_file) return retval.rstrip('\r\n') def get_voltage(self): @@ -101,10 +92,10 @@ def get_voltage(self): if vout_label_path: dir_name = os.path.dirname(vout_label_path) basename = os.path.basename(vout_label_path) - in_num = filter(str.isdigit, basename) + in_num = ''.join(list(filter(str.isdigit, basename))) vout_path = os.path.join( dir_name, voltage_name.format(in_num)) - vout_val = self.__read_txt_file(vout_path) + vout_val = self._api_helper.read_txt_file(vout_path) psu_voltage = float(vout_val) / 1000 return psu_voltage @@ -124,10 +115,10 @@ def get_current(self): if curr_label_path: dir_name = os.path.dirname(curr_label_path) basename = os.path.basename(curr_label_path) - cur_num = filter(str.isdigit, basename) + cur_num = ''.join(list(filter(str.isdigit, basename))) cur_path = os.path.join( dir_name, current_name.format(cur_num)) - cur_val = self.__read_txt_file(cur_path) + cur_val = self._api_helper.read_txt_file(cur_path) psu_current = float(cur_val) / 1000 return psu_current @@ -147,10 +138,10 @@ def get_power(self): if pw_label_path: dir_name = os.path.dirname(pw_label_path) basename = os.path.basename(pw_label_path) - pw_num = filter(str.isdigit, basename) + pw_num = ''.join(list(filter(str.isdigit, basename))) pw_path = os.path.join( dir_name, current_name.format(pw_num)) - pw_val = self.__read_txt_file(pw_path) + pw_val = self._api_helper.read_txt_file(pw_path) psu_power = float(pw_val) / 1000000 return psu_power @@ -196,7 +187,7 @@ def get_status_led(self): Returns: A string, one of the predefined STATUS_LED_COLOR_* strings above """ - status = self.__read_txt_file(self.green_led_path) + status = self._api_helper.read_txt_file(self.green_led_path) status_str = { '255': self.STATUS_LED_COLOR_GREEN, '0': self.STATUS_LED_COLOR_OFF 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 04fb36b72b8f..13ae4b8a47ad 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 @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Celestica # @@ -8,27 +6,45 @@ # ############################################################################# -import os import time import subprocess -import sonic_device_util from ctypes import create_string_buffer try: from sonic_platform_base.sfp_base import SfpBase - from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom + from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId - from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper + from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom + from sonic_platform_base.sonic_sfp.inf8628 import inf8628InterfaceId + from .helper import APIHelper except ImportError as e: raise ImportError(str(e) + "- required module not found") INFO_OFFSET = 128 DOM_OFFSET = 0 +# definitions of the offset and width for values in XCVR info eeprom XCVR_INTFACE_BULK_OFFSET = 0 XCVR_INTFACE_BULK_WIDTH_QSFP = 20 -XCVR_HW_REV_WIDTH_QSFP = 2 +XCVR_INTFACE_BULK_WIDTH_SFP = 21 +XCVR_TYPE_OFFSET = 0 +XCVR_TYPE_WIDTH = 1 +XCVR_EXT_TYPE_OFFSET = 1 +XCVR_EXT_TYPE_WIDTH = 1 +XCVR_CONNECTOR_OFFSET = 2 +XCVR_CONNECTOR_WIDTH = 1 +XCVR_COMPLIANCE_CODE_OFFSET = 3 +XCVR_COMPLIANCE_CODE_WIDTH = 8 +XCVR_ENCODING_OFFSET = 11 +XCVR_ENCODING_WIDTH = 1 +XCVR_NBR_OFFSET = 12 +XCVR_NBR_WIDTH = 1 +XCVR_EXT_RATE_SEL_OFFSET = 13 +XCVR_EXT_RATE_SEL_WIDTH = 1 +XCVR_CABLE_LENGTH_OFFSET = 14 XCVR_CABLE_LENGTH_WIDTH_QSFP = 5 +XCVR_CABLE_LENGTH_WIDTH_SFP = 6 XCVR_VENDOR_NAME_OFFSET = 20 XCVR_VENDOR_NAME_WIDTH = 16 XCVR_VENDOR_OUI_OFFSET = 37 @@ -37,13 +53,29 @@ XCVR_VENDOR_PN_WIDTH = 16 XCVR_HW_REV_OFFSET = 56 XCVR_HW_REV_WIDTH_OSFP = 2 +XCVR_HW_REV_WIDTH_QSFP = 2 XCVR_HW_REV_WIDTH_SFP = 4 XCVR_VENDOR_SN_OFFSET = 68 XCVR_VENDOR_SN_WIDTH = 16 XCVR_VENDOR_DATE_OFFSET = 84 XCVR_VENDOR_DATE_WIDTH = 8 XCVR_DOM_CAPABILITY_OFFSET = 92 -XCVR_DOM_CAPABILITY_WIDTH = 1 +XCVR_DOM_CAPABILITY_WIDTH = 2 + +XCVR_INTERFACE_DATA_START = 0 +XCVR_INTERFACE_DATA_SIZE = 92 + +QSFP_DOM_BULK_DATA_START = 22 +QSFP_DOM_BULK_DATA_SIZE = 36 +SFP_DOM_BULK_DATA_START = 96 +SFP_DOM_BULK_DATA_SIZE = 10 + +# definitions of the offset for values in OSFP info eeprom +OSFP_TYPE_OFFSET = 0 +OSFP_VENDOR_NAME_OFFSET = 129 +OSFP_VENDOR_PN_OFFSET = 148 +OSFP_HW_REV_OFFSET = 164 +OSFP_VENDOR_SN_OFFSET = 166 # Offset for values in QSFP eeprom QSFP_DOM_REV_OFFSET = 1 @@ -52,64 +84,109 @@ QSFP_TEMPE_WIDTH = 2 QSFP_VOLT_OFFSET = 26 QSFP_VOLT_WIDTH = 2 +QSFP_VERSION_COMPLIANCE_OFFSET = 1 +QSFP_VERSION_COMPLIANCE_WIDTH = 2 QSFP_CHANNL_MON_OFFSET = 34 QSFP_CHANNL_MON_WIDTH = 16 QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 -QSFP_CONTROL_OFFSET = 86 -QSFP_CONTROL_WIDTH = 8 +QSFP_CHANNL_DISABLE_STATUS_OFFSET = 86 +QSFP_CHANNL_DISABLE_STATUS_WIDTH = 1 QSFP_CHANNL_RX_LOS_STATUS_OFFSET = 3 QSFP_CHANNL_RX_LOS_STATUS_WIDTH = 1 QSFP_CHANNL_TX_FAULT_STATUS_OFFSET = 4 QSFP_CHANNL_TX_FAULT_STATUS_WIDTH = 1 +QSFP_CONTROL_OFFSET = 86 +QSFP_CONTROL_WIDTH = 8 +QSFP_MODULE_MONITOR_OFFSET = 0 +QSFP_MODULE_MONITOR_WIDTH = 9 QSFP_POWEROVERRIDE_OFFSET = 93 QSFP_POWEROVERRIDE_WIDTH = 1 +QSFP_POWEROVERRIDE_BIT = 0 +QSFP_POWERSET_BIT = 1 +QSFP_OPTION_VALUE_OFFSET = 192 +QSFP_OPTION_VALUE_WIDTH = 4 +QSFP_MODULE_UPPER_PAGE3_START = 384 QSFP_MODULE_THRESHOLD_OFFSET = 128 QSFP_MODULE_THRESHOLD_WIDTH = 24 -QSFP_CHANNEL_THRESHOLD_OFFSET = 176 -QSFP_CHANNEL_THRESHOLD_WIDTH = 16 +QSFP_CHANNL_THRESHOLD_OFFSET = 176 +QSFP_CHANNL_THRESHOLD_WIDTH = 24 + +SFP_MODULE_ADDRA2_OFFSET = 256 +SFP_MODULE_THRESHOLD_OFFSET = 0 +SFP_MODULE_THRESHOLD_WIDTH = 56 +SFP_CHANNL_THRESHOLD_OFFSET = 112 +SFP_CHANNL_THRESHOLD_WIDTH = 2 + +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VOLT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_CHANNL_MON_OFFSET = 100 +SFP_CHANNL_MON_WIDTH = 6 +SFP_CHANNL_STATUS_OFFSET = 110 +SFP_CHANNL_STATUS_WIDTH = 1 + qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', 'Length OM2(m)', 'Length OM1(m)', 'Length Cable Assembly(m)') +sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)', + 'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)', + 'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)') + +sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode', + 'ESCONComplianceCodes', 'SONETComplianceCodes', + 'EthernetComplianceCodes', 'FibreChannelLinkLength', + 'FibreChannelTechnology', 'SFP+CableTechnology', + 'FibreChannelTransmissionMedia', 'FibreChannelSpeed') + qsfp_compliance_code_tup = ('10/40G Ethernet Compliance Code', 'SONET Compliance codes', 'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes', 'Fibre Channel link length/Transmitter Technology', 'Fibre Channel transmission media', 'Fibre Channel Speed') +SFP_TYPE = "SFP" +QSFP_TYPE = "QSFP" +OSFP_TYPE = "OSFP" + +PORT_START = 1 +PORT_END = 56 +QSFP_PORT_START = 1 +QSFP_PORT_END = 32 + +SFP_I2C_START = 26 class Sfp(SfpBase): """Platform-specific Sfp class""" - # Port number - PORT_START = 1 - PORT_END = 32 - # Path to QSFP sysfs RESET_PATH = "/sys/devices/platform/dx010_cpld/qsfp_reset" LP_PATH = "/sys/devices/platform/dx010_cpld/qsfp_lpmode" PRS_PATH = "/sys/devices/platform/dx010_cpld/qsfp_modprs" - PLATFORM_ROOT_PATH = "/usr/share/sonic/device" - PMON_HWSKU_PATH = "/usr/share/sonic/hwsku" - HOST_CHK_CMD = "docker > /dev/null 2>&1" - PLATFORM = "x86_64-cel_seastone-r0" - HWSKU = "Seastone-DX010" - - def __init__(self, sfp_index): + def __init__(self, sfp_index, sfp_name): + SfpBase.__init__(self) # Init index self.index = sfp_index - self.port_num = self.index + self.port_num = self.index + 1 + self.dom_supported = False + self.sfp_type, self.port_name = self.__get_sfp_info() + self._api_helper = APIHelper() + self.name = sfp_name # Init eeprom path eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom' self.port_to_eeprom_mapping = {} - for x in range(self.PORT_START, self.PORT_END + 1): - p_num = x - 1 if self.PORT_START == 1 else x - self.port_to_eeprom_mapping[x] = eeprom_path.format(p_num + 26) + self.port_to_i2c_mapping = {} - self.info_dict_keys = ['type', 'hardwarerev', 'serialnum', 'manufacturename', 'modelname', 'Connector', 'encoding', 'ext_identifier', + for x in range(PORT_START, PORT_END + 1): + self.port_to_i2c_mapping[x] = (SFP_I2C_START + x) - 1 + port_eeprom_path = eeprom_path.format(self.port_to_i2c_mapping[x]) + self.port_to_eeprom_mapping[x] = port_eeprom_path + + self.info_dict_keys = ['type', 'hardware_rev', 'serial', 'manufacturer', 'model', 'connector', 'encoding', 'ext_identifier', 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance', 'vendor_date', 'vendor_oui'] self.dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', 'temperature', 'voltage', @@ -118,9 +195,21 @@ def __init__(self, sfp_index): self.threshold_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning', 'vcchighalarm', 'vcchighwarning', 'vcclowalarm', 'vcclowwarning', 'rxpowerhighalarm', 'rxpowerhighwarning', 'rxpowerlowalarm', 'rxpowerlowwarning', 'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', 'txpowerlowwarning', 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning'] - SfpBase.__init__(self) + self._dom_capability_detect() - def _convert_string_to_num(self, value_str): + def __get_sfp_info(self): + port_name = "Unknown" + sfp_type = "Unknown" + + if self.port_num >= QSFP_PORT_START and self.port_num <= QSFP_TYPE: + sfp_type = QSFP_TYPE + port_name = "QSFP" + str(self.port_num - QSFP_PORT_START + 1) + elif self.port_num >= SFP_PORT_START and self.port_num <= SFP_PORT_END: + sfp_type = SFP_TYPE + port_name = "SFP" + str(self.port_num - SFP_PORT_START + 1) + return sfp_type, port_name + + def __convert_string_to_num(self, value_str): if "-inf" in value_str: return 'N/A' elif "Unknown" in value_str: @@ -140,24 +229,6 @@ def _convert_string_to_num(self, value_str): else: return 'N/A' - def __read_txt_file(self, file_path): - try: - with open(file_path, 'r') as fd: - data = fd.read() - return data.strip() - except IOError: - pass - return "" - - def __is_host(self): - return os.system(self.HOST_CHK_CMD) == 0 - - def __get_path_to_port_config_file(self): - platform_path = "/".join([self.PLATFORM_ROOT_PATH, self.PLATFORM]) - hwsku_path = "/".join([platform_path, self.HWSKU] - ) if self.__is_host() else self.PMON_HWSKU_PATH - return "/".join([hwsku_path, "port_config.ini"]) - def __read_eeprom_specific_bytes(self, offset, num_bytes): sysfsfile_eeprom = None eeprom_raw = [] @@ -180,6 +251,106 @@ def __read_eeprom_specific_bytes(self, offset, num_bytes): return eeprom_raw + def _dom_capability_detect(self): + if not self.get_presence(): + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.calibration = 0 + return + + if self.sfp_type == "QSFP": + self.calibration = 1 + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + self.dom_supported = False + offset = 128 + + # 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( + (offset + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) + if qsfp_dom_capability_raw is not None: + qsfp_version_compliance_raw = self.__read_eeprom_specific_bytes( + QSFP_VERSION_COMPLIANCE_OFFSET, QSFP_VERSION_COMPLIANCE_WIDTH) + qsfp_version_compliance = int( + qsfp_version_compliance_raw[0], 16) + dom_capability = sfpi_obj.parse_dom_capability( + qsfp_dom_capability_raw, 0) + if qsfp_version_compliance >= 0x08: + self.dom_temp_supported = dom_capability['data']['Temp_support']['value'] == 'On' + self.dom_volt_supported = dom_capability['data']['Voltage_support']['value'] == 'On' + self.dom_rx_power_supported = dom_capability['data']['Rx_power_support']['value'] == 'On' + self.dom_tx_power_supported = dom_capability['data']['Tx_power_support']['value'] == 'On' + else: + self.dom_temp_supported = True + self.dom_volt_supported = True + self.dom_rx_power_supported = dom_capability['data']['Rx_power_support']['value'] == 'On' + self.dom_tx_power_supported = True + + self.dom_supported = True + self.calibration = 1 + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + qsfp_option_value_raw = self.__read_eeprom_specific_bytes( + QSFP_OPTION_VALUE_OFFSET, QSFP_OPTION_VALUE_WIDTH) + if qsfp_option_value_raw is not None: + optional_capability = sfpd_obj.parse_option_params( + qsfp_option_value_raw, 0) + self.dom_tx_disable_supported = optional_capability[ + 'data']['TxDisable']['value'] == 'On' + dom_status_indicator = sfpd_obj.parse_dom_status_indicator( + qsfp_version_compliance_raw, 1) + self.qsfp_page3_available = dom_status_indicator['data']['FlatMem']['value'] == 'Off' + else: + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.calibration = 0 + self.qsfp_page3_available = False + + elif self.sfp_type == "SFP": + sfpi_obj = sff8472InterfaceId() + if sfpi_obj is None: + return None + sfp_dom_capability_raw = self.__read_eeprom_specific_bytes( + XCVR_DOM_CAPABILITY_OFFSET, XCVR_DOM_CAPABILITY_WIDTH) + if sfp_dom_capability_raw is not None: + sfp_dom_capability = int(sfp_dom_capability_raw[0], 16) + self.dom_supported = (sfp_dom_capability & 0x40 != 0) + if self.dom_supported: + self.dom_temp_supported = True + self.dom_volt_supported = True + self.dom_rx_power_supported = True + self.dom_tx_power_supported = True + if sfp_dom_capability & 0x20 != 0: + self.calibration = 1 + elif sfp_dom_capability & 0x10 != 0: + self.calibration = 2 + else: + self.calibration = 0 + else: + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.calibration = 0 + self.dom_tx_disable_supported = ( + int(sfp_dom_capability_raw[1], 16) & 0x40 != 0) + else: + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + def get_transceiver_info(self): """ Retrieves transceiver info of this SFP @@ -189,11 +360,11 @@ def get_transceiver_info(self): keys |Value Format |Information ---------------------------|---------------|---------------------------- type |1*255VCHAR |type of SFP - hardwarerev |1*255VCHAR |hardware version of SFP - serialnum |1*255VCHAR |serial number of the SFP - manufacturename |1*255VCHAR |SFP vendor name - modelname |1*255VCHAR |SFP model name - Connector |1*255VCHAR |connector information + hardware_rev |1*255VCHAR |hardware version of SFP + serial |1*255VCHAR |serial number of the SFP + manufacturer |1*255VCHAR |SFP vendor name + model |1*255VCHAR |SFP model name + connector |1*255VCHAR |connector information encoding |1*255VCHAR |encoding information ext_identifier |1*255VCHAR |extend identifier ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance @@ -203,85 +374,182 @@ def get_transceiver_info(self): vendor_date |1*255VCHAR |vendor date vendor_oui |1*255VCHAR |vendor OUI ======================================================================== - """ - # check present status - sfpi_obj = sff8436InterfaceId() - if not self.get_presence() or not sfpi_obj: - return {} - - offset = INFO_OFFSET - - sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes( - (offset + XCVR_INTFACE_BULK_OFFSET), XCVR_INTFACE_BULK_WIDTH_QSFP) - sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk( - sfp_interface_bulk_raw, 0) - - sfp_vendor_name_raw = self.__read_eeprom_specific_bytes( - (offset + XCVR_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) - sfp_vendor_name_data = sfpi_obj.parse_vendor_name( - sfp_vendor_name_raw, 0) - - sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes( - (offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) - sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn( - sfp_vendor_pn_raw, 0) - - sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes( - (offset + XCVR_HW_REV_OFFSET), XCVR_HW_REV_WIDTH_QSFP) - sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev( - sfp_vendor_rev_raw, 0) - - sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes( - (offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) - sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn( - sfp_vendor_sn_raw, 0) - - sfp_vendor_oui_raw = self.__read_eeprom_specific_bytes( - (offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH) - if sfp_vendor_oui_raw is not None: - sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui( - sfp_vendor_oui_raw, 0) - - sfp_vendor_date_raw = self.__read_eeprom_specific_bytes( - (offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH) - sfp_vendor_date_data = sfpi_obj.parse_vendor_date( - sfp_vendor_date_raw, 0) - + """ + compliance_code_dict = {} transceiver_info_dict = dict.fromkeys(self.info_dict_keys, 'N/A') - compliance_code_dict = dict() + if not self.get_presence(): + return transceiver_info_dict + + # ToDo: OSFP tranceiver info parsing not fully supported. + # in inf8628.py lack of some memory map definition + # will be implemented when the inf8628 memory map ready + if self.sfp_type == OSFP_TYPE: + offset = 0 + vendor_rev_width = XCVR_HW_REV_WIDTH_OSFP + + sfpi_obj = inf8628InterfaceId() + if sfpi_obj is None: + return None + + sfp_type_raw = self.__read_eeprom_specific_bytes( + (offset + OSFP_TYPE_OFFSET), XCVR_TYPE_WIDTH) + if sfp_type_raw is not None: + sfp_type_data = sfpi_obj.parse_sfp_type(sfp_type_raw, 0) + else: + return None + + sfp_vendor_name_raw = self.__read_eeprom_specific_bytes( + (offset + OSFP_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) + if sfp_vendor_name_raw is not None: + sfp_vendor_name_data = sfpi_obj.parse_vendor_name( + sfp_vendor_name_raw, 0) + else: + return None + + sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes( + (offset + OSFP_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + if sfp_vendor_pn_raw is not None: + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn( + sfp_vendor_pn_raw, 0) + else: + return None + + sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes( + (offset + OSFP_HW_REV_OFFSET), vendor_rev_width) + if sfp_vendor_rev_raw is not None: + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev( + sfp_vendor_rev_raw, 0) + else: + return None + + sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes( + (offset + OSFP_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + if sfp_vendor_sn_raw is not None: + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn( + sfp_vendor_sn_raw, 0) + else: + return None + + transceiver_info_dict['type'] = sfp_type_data['data']['type']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['vendor_oui'] = 'N/A' + transceiver_info_dict['vendor_date'] = 'N/A' + transceiver_info_dict['connector'] = 'N/A' + transceiver_info_dict['encoding'] = 'N/A' + transceiver_info_dict['ext_identifier'] = 'N/A' + transceiver_info_dict['ext_rateselect_compliance'] = 'N/A' + transceiver_info_dict['cable_type'] = 'N/A' + transceiver_info_dict['cable_length'] = 'N/A' + transceiver_info_dict['specification_compliance'] = '{}' + transceiver_info_dict['nominal_bit_rate'] = 'N/A' + + else: + if self.sfp_type == QSFP_TYPE: + offset = 128 + vendor_rev_width = XCVR_HW_REV_WIDTH_QSFP + # cable_length_width = XCVR_CABLE_LENGTH_WIDTH_QSFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_QSFP + + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + + else: + offset = 0 + vendor_rev_width = XCVR_HW_REV_WIDTH_SFP + # cable_length_width = XCVR_CABLE_LENGTH_WIDTH_SFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_SFP + + sfpi_obj = sff8472InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes( + offset + XCVR_INTERFACE_DATA_START, XCVR_INTERFACE_DATA_SIZE) + if sfp_interface_bulk_raw is None: + return None + + start = XCVR_INTFACE_BULK_OFFSET - XCVR_INTERFACE_DATA_START + end = start + interface_info_bulk_width + sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_NAME_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_NAME_WIDTH + sfp_vendor_name_data = sfpi_obj.parse_vendor_name( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_PN_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_PN_WIDTH + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_HW_REV_OFFSET - XCVR_INTERFACE_DATA_START + end = start + vendor_rev_width + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_SN_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_SN_WIDTH + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_OUI_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_OUI_WIDTH + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui( + sfp_interface_bulk_raw[start: end], 0) - if sfp_interface_bulk_data: + start = XCVR_VENDOR_DATE_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_DATE_WIDTH + sfp_vendor_date_data = sfpi_obj.parse_vendor_date( + sfp_interface_bulk_raw[start: end], 0) transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] - transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] + transceiver_info_dict['vendor_date'] = sfp_vendor_date_data[ + 'data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] - transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] - - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data[ - 'data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A' - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' - transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A' - transceiver_info_dict['vendor_date'] = sfp_vendor_date_data[ - 'data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A' - transceiver_info_dict['cable_type'] = "Unknown" - transceiver_info_dict['cable_length'] = "Unknown" - - for key in qsfp_cable_length_tup: - if key in sfp_interface_bulk_data['data']: - transceiver_info_dict['cable_type'] = key - transceiver_info_dict['cable_length'] = str( - sfp_interface_bulk_data['data'][key]['value']) - - for key in qsfp_compliance_code_tup: - if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: - compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] - transceiver_info_dict['specification_compliance'] = str( - compliance_code_dict) - transceiver_info_dict['nominal_bit_rate'] = str( - sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value']) + + if self.sfp_type == QSFP_TYPE: + for key in qsfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str( + sfp_interface_bulk_data['data'][key]['value']) + + for key in qsfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + transceiver_info_dict['specification_compliance'] = str( + compliance_code_dict) + + transceiver_info_dict['nominal_bit_rate'] = str( + sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value']) + else: + for key in sfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str( + sfp_interface_bulk_data['data'][key]['value']) + + for key in sfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + transceiver_info_dict['specification_compliance'] = str( + compliance_code_dict) + + transceiver_info_dict['nominal_bit_rate'] = str( + sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) return transceiver_info_dict @@ -310,84 +578,117 @@ def get_transceiver_bulk_status(self): | |for example, tx2power stands for tx power of channel 2. ======================================================================== """ - # check present status - sfpd_obj = sff8436Dom() - sfpi_obj = sff8436InterfaceId() + transceiver_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A') + + if self.sfp_type == OSFP_TYPE: + pass - if not self.get_presence() or not sfpi_obj or not sfpd_obj: - return {} + elif self.sfp_type == QSFP_TYPE: + if not self.dom_supported: + return transceiver_dom_info_dict + + offset = 0 + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return transceiver_dom_info_dict + + dom_data_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_DOM_BULK_DATA_START), QSFP_DOM_BULK_DATA_SIZE) + if dom_data_raw is None: + return transceiver_dom_info_dict + + if self.dom_temp_supported: + start = QSFP_TEMPE_OFFSET - QSFP_DOM_BULK_DATA_START + end = start + QSFP_TEMPE_WIDTH + dom_temperature_data = sfpd_obj.parse_temperature( + dom_data_raw[start: end], 0) + temp = self.__convert_string_to_num( + dom_temperature_data['data']['Temperature']['value']) + if temp is not None: + transceiver_dom_info_dict['temperature'] = temp + + if self.dom_volt_supported: + start = QSFP_VOLT_OFFSET - QSFP_DOM_BULK_DATA_START + end = start + QSFP_VOLT_WIDTH + dom_voltage_data = sfpd_obj.parse_voltage( + dom_data_raw[start: end], 0) + volt = self.__convert_string_to_num( + dom_voltage_data['data']['Vcc']['value']) + if volt is not None: + transceiver_dom_info_dict['voltage'] = volt + + start = QSFP_CHANNL_MON_OFFSET - QSFP_DOM_BULK_DATA_START + end = start + QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power( + dom_data_raw[start: end], 0) + + if self.dom_tx_power_supported: + transceiver_dom_info_dict['tx1power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['TX1Power']['value']) + transceiver_dom_info_dict['tx2power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['TX2Power']['value']) + transceiver_dom_info_dict['tx3power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['TX3Power']['value']) + transceiver_dom_info_dict['tx4power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['TX4Power']['value']) + + if self.dom_rx_power_supported: + transceiver_dom_info_dict['rx1power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['RX1Power']['value']) + transceiver_dom_info_dict['rx2power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['RX2Power']['value']) + transceiver_dom_info_dict['rx3power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['RX3Power']['value']) + transceiver_dom_info_dict['rx4power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['RX4Power']['value']) + + transceiver_dom_info_dict['tx1bias'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['TX1Bias']['value']) + transceiver_dom_info_dict['tx2bias'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['TX2Bias']['value']) + transceiver_dom_info_dict['tx3bias'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['TX3Bias']['value']) + transceiver_dom_info_dict['tx4bias'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['TX4Bias']['value']) - transceiver_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A') - offset = DOM_OFFSET - offset_xcvr = INFO_OFFSET - - # 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( - (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 None + if not self.dom_supported: + return transceiver_dom_info_dict - dom_temperature_raw = self.__read_eeprom_specific_bytes( - (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) - transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] - - dom_voltage_raw = self.__read_eeprom_specific_bytes( - (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) - transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] - - qsfp_dom_rev_raw = self.__read_eeprom_specific_bytes( - (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) - qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['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 = {} - dom_channel_monitor_raw = None - 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( - (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) + offset = 256 + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return transceiver_dom_info_dict + sfpd_obj._calibration_type = self.calibration - else: - dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( - (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) - 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'] - - if dom_channel_monitor_raw: - 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'] - - for key in transceiver_dom_info_dict: - transceiver_dom_info_dict[key] = self._convert_string_to_num( - transceiver_dom_info_dict[key]) + dom_data_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_DOM_BULK_DATA_START), SFP_DOM_BULK_DATA_SIZE) + + start = SFP_TEMPE_OFFSET - SFP_DOM_BULK_DATA_START + end = start + SFP_TEMPE_WIDTH + dom_temperature_data = sfpd_obj.parse_temperature( + dom_data_raw[start: end], 0) + + start = SFP_VOLT_OFFSET - SFP_DOM_BULK_DATA_START + end = start + SFP_VOLT_WIDTH + dom_voltage_data = sfpd_obj.parse_voltage( + dom_data_raw[start: end], 0) + + start = SFP_CHANNL_MON_OFFSET - SFP_DOM_BULK_DATA_START + end = start + SFP_CHANNL_MON_WIDTH + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( + dom_data_raw[start: end], 0) + + transceiver_dom_info_dict['temperature'] = self.__convert_string_to_num( + dom_temperature_data['data']['Temperature']['value']) + transceiver_dom_info_dict['voltage'] = self.__convert_string_to_num( + dom_voltage_data['data']['Vcc']['value']) + transceiver_dom_info_dict['rx1power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['RXPower']['value']) + transceiver_dom_info_dict['tx1bias'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['TXBias']['value']) + transceiver_dom_info_dict['tx1power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['TXPower']['value']) transceiver_dom_info_dict['rx_los'] = self.get_rx_los() transceiver_dom_info_dict['tx_fault'] = self.get_tx_fault() @@ -426,55 +727,106 @@ def get_transceiver_threshold_info(self): txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA. ======================================================================== """ - # check present status - sfpd_obj = sff8436Dom() + transceiver_dom_threshold_info_dict = dict.fromkeys( + self.threshold_dict_keys, 'N/A') - if not self.get_presence() or not sfpd_obj: - return {} + if self.sfp_type == OSFP_TYPE: + pass - transceiver_dom_threshold_dict = dict.fromkeys( - self.threshold_dict_keys, 'N/A') - dom_thres_raw = self.__read_eeprom_specific_bytes( - QSFP_MODULE_THRESHOLD_OFFSET, QSFP_MODULE_THRESHOLD_WIDTH) if self.get_presence() and sfpd_obj else None - - if dom_thres_raw: - module_threshold_values = sfpd_obj.parse_module_threshold_values( - dom_thres_raw, 0) - module_threshold_data = module_threshold_values.get('data') - if module_threshold_data: - transceiver_dom_threshold_dict['temphighalarm'] = module_threshold_data['TempHighAlarm']['value'] - transceiver_dom_threshold_dict['templowalarm'] = module_threshold_data['TempLowAlarm']['value'] - transceiver_dom_threshold_dict['temphighwarning'] = module_threshold_data['TempHighWarning']['value'] - transceiver_dom_threshold_dict['templowwarning'] = module_threshold_data['TempLowWarning']['value'] - transceiver_dom_threshold_dict['vcchighalarm'] = module_threshold_data['VccHighAlarm']['value'] - transceiver_dom_threshold_dict['vcclowalarm'] = module_threshold_data['VccLowAlarm']['value'] - transceiver_dom_threshold_dict['vcchighwarning'] = module_threshold_data['VccHighWarning']['value'] - transceiver_dom_threshold_dict['vcclowwarning'] = module_threshold_data['VccLowWarning']['value'] - - dom_thres_raw = self.__read_eeprom_specific_bytes( - QSFP_CHANNEL_THRESHOLD_OFFSET, QSFP_CHANNEL_THRESHOLD_WIDTH) if self.get_presence() and sfpd_obj else None - channel_threshold_values = sfpd_obj.parse_channel_threshold_values( - dom_thres_raw, 0) - channel_threshold_data = channel_threshold_values.get('data') - if channel_threshold_data: - transceiver_dom_threshold_dict['rxpowerhighalarm'] = channel_threshold_data['RxPowerHighAlarm']['value'] - transceiver_dom_threshold_dict['rxpowerlowalarm'] = channel_threshold_data['RxPowerLowAlarm']['value'] - transceiver_dom_threshold_dict['rxpowerhighwarning'] = channel_threshold_data['RxPowerHighWarning']['value'] - transceiver_dom_threshold_dict['rxpowerlowwarning'] = channel_threshold_data['RxPowerLowWarning']['value'] - transceiver_dom_threshold_dict['txpowerhighalarm'] = "0.0dBm" - transceiver_dom_threshold_dict['txpowerlowalarm'] = "0.0dBm" - transceiver_dom_threshold_dict['txpowerhighwarning'] = "0.0dBm" - transceiver_dom_threshold_dict['txpowerlowwarning'] = "0.0dBm" - transceiver_dom_threshold_dict['txbiashighalarm'] = channel_threshold_data['TxBiasHighAlarm']['value'] - transceiver_dom_threshold_dict['txbiaslowalarm'] = channel_threshold_data['TxBiasLowAlarm']['value'] - transceiver_dom_threshold_dict['txbiashighwarning'] = channel_threshold_data['TxBiasHighWarning']['value'] - transceiver_dom_threshold_dict['txbiaslowwarning'] = channel_threshold_data['TxBiasLowWarning']['value'] - - for key in transceiver_dom_threshold_dict: - transceiver_dom_threshold_dict[key] = self._convert_string_to_num( - transceiver_dom_threshold_dict[key]) - - return transceiver_dom_threshold_dict + elif self.sfp_type == QSFP_TYPE: + if not self.dom_supported or not self.qsfp_page3_available: + return transceiver_dom_threshold_info_dict + + # Dom Threshold data starts from offset 384 + # Revert offset back to 0 once data is retrieved + offset = QSFP_MODULE_UPPER_PAGE3_START + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_MODULE_THRESHOLD_OFFSET), QSFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_data = sfpd_obj.parse_module_threshold_values( + dom_module_threshold_raw, 0) + + dom_channel_threshold_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNL_THRESHOLD_OFFSET), + QSFP_CHANNL_THRESHOLD_WIDTH) + if dom_channel_threshold_raw is None: + return transceiver_dom_threshold_info_dict + dom_channel_threshold_data = sfpd_obj.parse_channel_threshold_values( + dom_channel_threshold_raw, 0) + + # 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'] + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_channel_threshold_data['data']['TxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_channel_threshold_data['data']['TxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_channel_threshold_data['data']['TxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_channel_threshold_data['data']['TxPowerLowWarning']['value'] + + else: + offset = SFP_MODULE_ADDRA2_OFFSET + + if not self.dom_supported: + return transceiver_dom_threshold_info_dict + + sfpd_obj = sff8472Dom(None, self.calibration) + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_raw = self.__read_eeprom_specific_bytes((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 + + # 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'] + + for key in transceiver_dom_threshold_info_dict: + transceiver_dom_threshold_info_dict[key] = self.__convert_string_to_num( + transceiver_dom_threshold_info_dict[key]) + + return transceiver_dom_threshold_info_dict def get_reset_status(self): """ @@ -482,7 +834,7 @@ def get_reset_status(self): Returns: A Boolean, True if reset enabled, False if disabled """ - reset_status_raw = self.__read_txt_file(self.RESET_PATH).rstrip() + reset_status_raw = self._api_helper.read_txt_file(self.RESET_PATH).rstrip() if not reset_status_raw: return False @@ -498,16 +850,28 @@ def get_rx_los(self): Note : RX LOS status is latched until a call to get_rx_los or a reset. """ rx_los = False - rx_los_list = [] - dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( - QSFP_CHANNL_RX_LOS_STATUS_OFFSET, QSFP_CHANNL_RX_LOS_STATUS_WIDTH) if self.get_presence() else None - if dom_channel_monitor_raw is not None: - rx_los_data = int(dom_channel_monitor_raw[0], 16) - rx_los_list.append(rx_los_data & 0x01 != 0) - rx_los_list.append(rx_los_data & 0x02 != 0) - rx_los_list.append(rx_los_data & 0x04 != 0) - rx_los_list.append(rx_los_data & 0x08 != 0) - rx_los = rx_los_list[0] and rx_los_list[1] and rx_los_list[2] and rx_los_list[3] + if self.sfp_type == OSFP_TYPE: + return False + + elif self.sfp_type == QSFP_TYPE: + offset = 0 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_RX_LOS_STATUS_OFFSET), QSFP_CHANNL_RX_LOS_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 16) + rx1_los = (rx_los_data & 0x01 != 0) + rx2_los = (rx_los_data & 0x02 != 0) + rx3_los = (rx_los_data & 0x04 != 0) + rx4_los = (rx_los_data & 0x08 != 0) + rx_los = (rx1_los and rx2_los and rx3_los and rx4_los) + else: + offset = 256 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 16) + rx_los = (rx_los_data & 0x02 != 0) + return rx_los def get_tx_fault(self): @@ -517,19 +881,32 @@ def get_tx_fault(self): A Boolean, True if SFP has TX fault, False if not Note : TX fault status is lached until a call to get_tx_fault or a reset. """ - tx_fault = False - tx_fault_list = [] - dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( - QSFP_CHANNL_TX_FAULT_STATUS_OFFSET, QSFP_CHANNL_TX_FAULT_STATUS_WIDTH) if self.get_presence() else None - if dom_channel_monitor_raw is not None: - tx_fault_data = int(dom_channel_monitor_raw[0], 16) - tx_fault_list.append(tx_fault_data & 0x01 != 0) - tx_fault_list.append(tx_fault_data & 0x02 != 0) - tx_fault_list.append(tx_fault_data & 0x04 != 0) - tx_fault_list.append(tx_fault_data & 0x08 != 0) - tx_fault = tx_fault_list[0] and tx_fault_list[1] and tx_fault_list[2] and tx_fault_list[3] + tx4_fault = False + + if self.sfp_type == OSFP_TYPE or not self.dom_supported: + return False + + elif self.sfp_type == QSFP_TYPE: + offset = 0 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_TX_FAULT_STATUS_OFFSET), QSFP_CHANNL_TX_FAULT_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 16) + tx1_fault = (tx_fault_data & 0x01 != 0) + tx2_fault = (tx_fault_data & 0x02 != 0) + tx3_fault = (tx_fault_data & 0x04 != 0) + tx4_fault = (tx_fault_data & 0x08 != 0) + tx4_fault = ( + tx1_fault and tx2_fault and tx3_fault and tx4_fault) + else: + offset = 256 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 16) + tx4_fault = (tx_fault_data & 0x04 != 0) - return tx_fault + return tx4_fault def get_tx_disable(self): """ @@ -537,26 +914,33 @@ def get_tx_disable(self): Returns: A Boolean, True if tx_disable is enabled, False if disabled """ - tx_disable_list = [] - sfpd_obj = sff8436Dom() - if sfpd_obj is None: + tx_disable = False + + if self.sfp_type == OSFP_TYPE and not self.dom_supported: return False - dom_control_raw = self.__read_eeprom_specific_bytes( - QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH) if self.get_presence() else None - if dom_control_raw is not None: - dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0) - tx_disable_list.append( - 'On' == dom_control_data['data']['TX1Disable']['value']) - tx_disable_list.append( - 'On' == dom_control_data['data']['TX2Disable']['value']) - tx_disable_list.append( - 'On' == dom_control_data['data']['TX3Disable']['value']) - tx_disable_list.append( - 'On' == dom_control_data['data']['TX4Disable']['value']) - - return tx_disable_list + elif self.sfp_type == QSFP_TYPE: + offset = 0 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_DISABLE_STATUS_OFFSET), QSFP_CHANNL_DISABLE_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_disable_data = int(dom_channel_monitor_raw[0], 16) + tx1_disable = (tx_disable_data & 0x01 != 0) + tx2_disable = (tx_disable_data & 0x02 != 0) + tx3_disable = (tx_disable_data & 0x04 != 0) + tx4_disable = (tx_disable_data & 0x08 != 0) + tx_disable = ( + tx1_disable and tx2_disable and tx3_disable and tx4_disable) + else: + offset = 256 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_disable_data = int(dom_channel_monitor_raw[0], 16) + tx_disable = (tx_disable_data & 0xC0 != 0) + + return tx_disable def get_tx_disable_channel(self): """ @@ -567,9 +951,29 @@ def get_tx_disable_channel(self): As an example, a returned value of 0x5 indicates that channel 0 and channel 2 have been disabled. """ - tx_disable_list = self.get_tx_disable() - if tx_disable_list is None: - return 0 + tx_disable_list = [False, False, False, False] + + if self.sfp_type == OSFP_TYPE: + pass + + elif self.sfp_type == QSFP_TYPE: + offset = 0 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_DISABLE_STATUS_OFFSET), QSFP_CHANNL_DISABLE_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_disable_data = int(dom_channel_monitor_raw[0], 16) + tx_disable_list[0] = (tx_disable_data & 0x01 != 0) + tx_disable_list[1] = (tx_disable_data & 0x02 != 0) + tx_disable_list[2] = (tx_disable_data & 0x04 != 0) + tx_disable_list[3] = (tx_disable_data & 0x08 != 0) + else: + offset = 256 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_disable_data = int(dom_channel_monitor_raw[0], 16) + tx_disable_list[0] = (tx_disable_data & 0xC0 != 0) + tx_disabled = 0 for i in range(len(tx_disable_list)): if tx_disable_list[i]: @@ -593,7 +997,7 @@ def get_lpmode(self): reg_value = int(content, 16) # Determind if port_num start from 1 or 0 - bit_index = self.port_num - 1 if self.PORT_START == 1 else self.port_num + bit_index = self.index # Mask off the bit corresponding to our port mask = (1 << bit_index) @@ -610,30 +1014,31 @@ def get_power_override(self): Returns: A Boolean, True if power-override is enabled, False if disabled """ - power_override = False - - offset = 0 - sfpd_obj = sff8436Dom() - if sfpd_obj is None: + if self.sfp_type == QSFP_TYPE: + offset = 0 + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return False + + dom_control_raw = self.__read_eeprom_specific_bytes( + QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH) if self.get_presence() else None + if dom_control_raw is not None: + dom_control_data = sfpd_obj.parse_control_bytes( + dom_control_raw, 0) + power_override = ( + 'On' == dom_control_data['data']['PowerOverride']['value']) + return power_override + else: return False - dom_control_raw = self.__read_eeprom_specific_bytes( - QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH) if self.get_presence() else None - if dom_control_raw is not None: - dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0) - power_override = ( - 'On' == dom_control_data['data']['PowerOverride']['value']) - - return power_override - def get_temperature(self): """ Retrieves the temperature of this SFP Returns: An integer number of current temperature in Celsius """ - transceiver_dom_info_dict = self.get_transceiver_bulk_status() - return transceiver_dom_info_dict.get("temperature", "N/A") + transceiver_bulk_status = self.get_transceiver_bulk_status() + return transceiver_bulk_status.get("temperature", "N/A") def get_voltage(self): """ @@ -641,8 +1046,8 @@ def get_voltage(self): Returns: An integer number of supply voltage in mV """ - transceiver_dom_info_dict = self.get_transceiver_bulk_status() - return transceiver_dom_info_dict.get("voltage", "N/A") + transceiver_bulk_status = self.get_transceiver_bulk_status() + return transceiver_bulk_status.get("voltage", "N/A") def get_tx_bias(self): """ @@ -652,12 +1057,13 @@ def get_tx_bias(self): for channel 0 to channel 4. Ex. ['110.09', '111.12', '108.21', '112.09'] """ - transceiver_dom_info_dict = self.get_transceiver_bulk_status() - tx1_bs = transceiver_dom_info_dict.get("tx1bias", "N/A") - tx2_bs = transceiver_dom_info_dict.get("tx2bias", "N/A") - tx3_bs = transceiver_dom_info_dict.get("tx3bias", "N/A") - tx4_bs = transceiver_dom_info_dict.get("tx4bias", "N/A") - return [tx1_bs, tx2_bs, tx3_bs, tx4_bs] if transceiver_dom_info_dict else [] + transceiver_bulk_status = self.get_transceiver_bulk_status() + tx1_bs = transceiver_bulk_status.get("tx1bias", "N/A") + tx2_bs = transceiver_bulk_status.get("tx2bias", "N/A") + tx3_bs = transceiver_bulk_status.get("tx3bias", "N/A") + tx4_bs = transceiver_bulk_status.get("tx4bias", "N/A") + tx_bias_list = [tx1_bs, tx2_bs, tx3_bs, tx4_bs] + return tx_bias_list def get_rx_power(self): """ @@ -667,12 +1073,14 @@ def get_rx_power(self): power in mW for channel 0 to channel 4. Ex. ['1.77', '1.71', '1.68', '1.70'] """ - transceiver_dom_info_dict = self.get_transceiver_bulk_status() - rx1_pw = transceiver_dom_info_dict.get("rx1power", "N/A") - rx2_pw = transceiver_dom_info_dict.get("rx2power", "N/A") - rx3_pw = transceiver_dom_info_dict.get("rx3power", "N/A") - rx4_pw = transceiver_dom_info_dict.get("rx4power", "N/A") - return [rx1_pw, rx2_pw, rx3_pw, rx4_pw] if transceiver_dom_info_dict else [] + rx_power_list = [] + transceiver_bulk_status = self.get_transceiver_bulk_status() + rx1_p = transceiver_bulk_status.get("rx1power", "N/A") + rx2_p = transceiver_bulk_status.get("rx2power", "N/A") + rx3_p = transceiver_bulk_status.get("rx3power", "N/A") + rx4_p = transceiver_bulk_status.get("rx4power", "N/A") + rx_power_list = [rx1_p, rx2_p, rx3_p, rx4_p] + return rx_power_list def get_tx_power(self): """ @@ -682,12 +1090,14 @@ def get_tx_power(self): for channel 0 to channel 4. Ex. ['1.86', '1.86', '1.86', '1.86'] """ - transceiver_dom_info_dict = self.get_transceiver_bulk_status() - tx1_pw = transceiver_dom_info_dict.get("tx1power", "N/A") - tx2_pw = transceiver_dom_info_dict.get("tx2power", "N/A") - tx3_pw = transceiver_dom_info_dict.get("tx3power", "N/A") - tx4_pw = transceiver_dom_info_dict.get("tx4power", "N/A") - return [tx1_pw, tx2_pw, tx3_pw, tx4_pw] + tx_power_list = [] + transceiver_bulk_status = self.get_transceiver_bulk_status() + tx1_p = transceiver_bulk_status.get("tx1power", "N/A") + tx2_p = transceiver_bulk_status.get("tx2power", "N/A") + tx3_p = transceiver_bulk_status.get("tx3power", "N/A") + tx4_p = transceiver_bulk_status.get("tx4power", "N/A") + tx_power_list = [tx1_p, tx2_p, tx3_p, tx4_p] + return tx_power_list def reset(self): """ @@ -710,7 +1120,7 @@ def reset(self): reg_value = int(content, 16) # Determind if port_num start from 1 or 0 - bit_index = self.port_num - 1 if self.PORT_START == 1 else self.port_num + bit_index = self.index # Mask off the bit corresponding to our port mask = (1 << bit_index) @@ -749,24 +1159,26 @@ def tx_disable(self, tx_disable): Returns: A boolean, True if tx_disable is set successfully, False if not """ - sysfsfile_eeprom = None - try: - tx_disable_ctl = 0xf if tx_disable else 0x0 - buffer = create_string_buffer(1) - buffer[0] = chr(tx_disable_ctl) - # Write to eeprom - sysfsfile_eeprom = open( - self.port_to_eeprom_mapping[self.port_num], "r+b") - sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET) - sysfsfile_eeprom.write(buffer[0]) - except IOError as e: - print "Error: unable to open file: %s" % str(e) - return False - finally: - if sysfsfile_eeprom is not None: - sysfsfile_eeprom.close() - time.sleep(0.01) - return True + if self.sfp_type == QSFP_TYPE: + sysfsfile_eeprom = None + try: + tx_disable_ctl = 0xf if tx_disable else 0x0 + buffer = create_string_buffer(1) + buffer[0] = chr(tx_disable_ctl) + # Write to eeprom + sysfsfile_eeprom = open( + self.port_to_eeprom_mapping[self.port_num], "r+b") + sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except IOError as e: + #print("Error: unable to open file: %s" % str(e)) + return False + finally: + if sysfsfile_eeprom is not None: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + return False def tx_disable_channel(self, channel, disable): """ @@ -779,28 +1191,30 @@ def tx_disable_channel(self, channel, disable): Returns: A boolean, True if successful, False if not """ - sysfsfile_eeprom = None - try: - channel_state = self.get_tx_disable_channel() - tx_enable_mask = [0xe, 0xd, 0xb, 0x7] - tx_disable_mask = [0x1, 0x3, 0x7, 0xf] - tx_disable_ctl = channel_state | tx_disable_mask[ - channel] if disable else channel_state & tx_enable_mask[channel] - buffer = create_string_buffer(1) - buffer[0] = chr(tx_disable_ctl) - # Write to eeprom - sysfsfile_eeprom = open( - self.port_to_eeprom_mapping[self.port_num], "r+b") - sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET) - sysfsfile_eeprom.write(buffer[0]) - except IOError as e: - print "Error: unable to open file: %s" % str(e) - return False - finally: - if sysfsfile_eeprom is not None: - sysfsfile_eeprom.close() - time.sleep(0.01) - return True + if self.sfp_type == QSFP_TYPE: + sysfsfile_eeprom = None + try: + channel_state = self.get_tx_disable_channel() + tx_enable_mask = [0xe, 0xd, 0xb, 0x7] + tx_disable_mask = [0x1, 0x3, 0x7, 0xf] + tx_disable_ctl = channel_state | tx_disable_mask[ + channel] if disable else channel_state & tx_enable_mask[channel] + buffer = create_string_buffer(1) + buffer[0] = chr(tx_disable_ctl) + # Write to eeprom + sysfsfile_eeprom = open( + self.port_to_eeprom_mapping[self.port_num], "r+b") + sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except IOError as e: + #print("Error: unable to open file: %s" % str(e)) + return False + finally: + if sysfsfile_eeprom is not None: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + return False def set_lpmode(self, lpmode): """ @@ -823,7 +1237,7 @@ def set_lpmode(self, lpmode): reg_value = int(content, 16) # Determind if port_num start from 1 or 0 - bit_index = self.port_num - 1 if self.PORT_START == 1 else self.port_num + bit_index = self.index # Mask off the bit corresponding to our port mask = (1 << bit_index) @@ -856,30 +1270,36 @@ def set_power_override(self, power_override, power_set): A boolean, True if power-override and power_set are set successfully, False if not """ - try: - power_override_bit = 0 - if power_override: - power_override_bit |= 1 << 0 - - power_set_bit = 0 - if power_set: - power_set_bit |= 1 << 1 + if self.sfp_type == QSFP_TYPE: + try: + power_override_bit = 0 + if power_override: + power_override_bit |= 1 << 0 + + power_set_bit = 0 + if power_set: + power_set_bit |= 1 << 1 + + buffer = create_string_buffer(1) + buffer[0] = chr(power_override_bit | power_set_bit) + # Write to eeprom + sysfsfile_eeprom = open( + self.port_to_eeprom_mapping[self.port_num], "r+b") + sysfsfile_eeprom.seek(QSFP_POWEROVERRIDE_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except IOError as e: + #print("Error: unable to open file: %s" % str(e)) + return False + finally: + if sysfsfile_eeprom is not None: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + return False - buffer = create_string_buffer(1) - buffer[0] = chr(power_override_bit | power_set_bit) - # Write to eeprom - sysfsfile_eeprom = open( - self.port_to_eeprom_mapping[self.port_num], "r+b") - sysfsfile_eeprom.seek(QSFP_POWEROVERRIDE_OFFSET) - sysfsfile_eeprom.write(buffer[0]) - except IOError as e: - print "Error: unable to open file: %s" % str(e) - return False - finally: - if sysfsfile_eeprom is not None: - sysfsfile_eeprom.close() - time.sleep(0.01) - return True + ############################################################## + ###################### Device methods ######################## + ############################################################## def get_name(self): """ @@ -887,11 +1307,7 @@ def get_name(self): Returns: string: The name of the device """ - sfputil_helper = SfpUtilHelper() - sfputil_helper.read_porttab_mappings( - self.__get_path_to_port_config_file()) - name = sfputil_helper.logical[self.index] or "Unknown" - return name + return self.name def get_presence(self): """ @@ -899,7 +1315,7 @@ def get_presence(self): Returns: bool: True if PSU is present, False if not """ - presence_status_raw = self.__read_txt_file(self.PRS_PATH).rstrip() + presence_status_raw = self._api_helper.read_txt_file(self.PRS_PATH).rstrip() if not presence_status_raw: return False @@ -907,7 +1323,7 @@ def get_presence(self): reg_value = int(content, 16) # Determind if port_num start from 1 or 0 - bit_index = self.port_num - 1 if self.PORT_START == 1 else self.port_num + bit_index = self.index # Mask off the bit corresponding to our port mask = (1 << bit_index) @@ -925,7 +1341,7 @@ def get_model(self): string: Model/part number of device """ transceiver_dom_info_dict = self.get_transceiver_info() - return transceiver_dom_info_dict.get("modelname", "N/A") + return transceiver_dom_info_dict.get("model", "N/A") def get_serial(self): """ @@ -934,7 +1350,7 @@ def get_serial(self): string: Serial number of device """ transceiver_dom_info_dict = self.get_transceiver_info() - return transceiver_dom_info_dict.get("serialnum", "N/A") + return transceiver_dom_info_dict.get("serial", "N/A") def get_status(self): """ @@ -942,4 +1358,4 @@ def get_status(self): Returns: A boolean value, True if device is operating properly, False if not """ - return self.get_presence() and self.get_transceiver_bulk_status() + return self.get_presence() and not self.get_reset_status() diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/thermal.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/thermal.py index 1e0a2c4b5645..2b38ef94d6c4 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/thermal.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/thermal.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Celestica # @@ -14,56 +12,79 @@ try: from sonic_platform_base.thermal_base import ThermalBase + from .helper import APIHelper except ImportError as e: raise ImportError(str(e) + "- required module not found") +THERMAL_INFO = { + 0: { + "F2B_max": 50, + "B2F_max": 55, + "postion": "asic", + "name": "Front-panel temp sensor 1", + "i2c_path": "i2c-5/5-0048/hwmon/hwmon1", # u4 system-inlet + }, + 1: { + "F2B_max": 50, + "B2F_max": 55, + "postion": "asic", + "name": "Front-panel temp sensor 2", + "i2c_path": "i2c-6/6-0049/hwmon/hwmon2", # u2 system-inlet + }, + 2: { + "F2B_max": 70, + "F2B_max_crit": 75, + "B2F_max": 60, + "B2F_max_crit": 65, + "postion": "asic", + "name": "ASIC temp sensor", + "i2c_path": "i2c-7/7-004a/hwmon/hwmon3", # u44 bmc56960-on-board + }, + 3: { + "F2B_max": 70, + "F2B_max_crit": 75, + "B2F_max": 70, + "B2F_max_crit": 75, + "postion": "cpu", + "name": "Rear-panel temp sensor 1", + "i2c_path": "i2c-14/14-0048/hwmon/hwmon4", # u9200 cpu-on-board + }, + 4: { + "F2B_max": 70, + "B2F_max": 55, + "postion": "cpu", + "name": "Rear-panel temp sensor 2", + "i2c_path": "i2c-15/15-004e/hwmon/hwmon5" # u9201 system-outlet + } +} +NULL_VAL = "N/A" +I2C_ADAPTER_PATH = "/sys/class/i2c-adapter" + class Thermal(ThermalBase): """Platform-specific Thermal class""" - THERMAL_NAME_LIST = [] - I2C_ADAPTER_PATH = "/sys/class/i2c-adapter" SS_CONFIG_PATH = "/usr/share/sonic/device/x86_64-cel_seastone-r0/sensors.conf" - def __init__(self, thermal_index): + def __init__(self, thermal_index, airflow): self.index = thermal_index - - # Add thermal name - self.THERMAL_NAME_LIST.append("Front-panel temp sensor 1") - self.THERMAL_NAME_LIST.append("Front-panel temp sensor 2") - self.THERMAL_NAME_LIST.append("ASIC temp sensor") - self.THERMAL_NAME_LIST.append("Rear-panel temp sensor 1") - self.THERMAL_NAME_LIST.append("Rear-panel temp sensor 2") - - # Set hwmon path - i2c_path = { - 0: "i2c-5/5-0048/hwmon/hwmon1", # u4 system-inlet - 1: "i2c-6/6-0049/hwmon/hwmon2", # u2 system-inlet - 2: "i2c-7/7-004a/hwmon/hwmon3", # u44 bmc56960-on-board - 3: "i2c-14/14-0048/hwmon/hwmon4", # u9200 cpu-on-board - 4: "i2c-15/15-004e/hwmon/hwmon5" # u9201 system-outlet - }.get(self.index, None) - - self.hwmon_path = "{}/{}".format(self.I2C_ADAPTER_PATH, i2c_path) - self.ss_key = self.THERMAL_NAME_LIST[self.index] + self._api_helper = APIHelper() + self._airflow = airflow + self._thermal_info = THERMAL_INFO[self.index] + self._hwmon_path = "{}/{}".format(I2C_ADAPTER_PATH, + self._thermal_info["i2c_path"]) + self.name = self.get_name() + self.postion = self._thermal_info["postion"] self.ss_index = 1 - def __read_txt_file(self, file_path): - try: - with open(file_path, 'r') as fd: - data = fd.read() - return data.strip() - except IOError: - pass - def __get_temp(self, temp_file): - temp_file_path = os.path.join(self.hwmon_path, temp_file) - raw_temp = self.__read_txt_file(temp_file_path) + temp_file_path = os.path.join(self._hwmon_path, temp_file) + raw_temp = self._api_helper.read_txt_file(temp_file_path) temp = float(raw_temp)/1000 - return "{:.3f}".format(temp) + return float("{:.3f}".format(temp)) def __set_threshold(self, file_name, temperature): - temp_file_path = os.path.join(self.hwmon_path, file_name) + temp_file_path = os.path.join(self._hwmon_path, file_name) try: with open(temp_file_path, 'w') as fd: fd.write(str(temperature)) @@ -88,8 +109,17 @@ def get_high_threshold(self): A float number, the high threshold temperature of thermal in Celsius up to nearest thousandth of one degree Celsius, e.g. 30.125 """ - temp_file = "temp{}_max".format(self.ss_index) - return self.__get_temp(temp_file) + max_crit_key = '{}_max'.format(self._airflow) + return self._thermal_info.get(max_crit_key, None) + + def get_low_threshold(self): + """ + Retrieves the low threshold temperature of thermal + Returns: + A float number, the low threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + return 0.0 def set_high_threshold(self, temperature): """ @@ -110,7 +140,7 @@ def set_high_threshold(self, temperature): f.seek(0) ss_found = False for idx, val in enumerate(content): - if self.ss_key in val: + if self.name in val: ss_found = True elif ss_found and temp_file in val: content[idx] = " set {} {}\n".format( @@ -123,13 +153,43 @@ def set_high_threshold(self, temperature): return is_set & file_set + def set_low_threshold(self, temperature): + """ + Sets the low threshold temperature of thermal + Args : + temperature: A float number up to nearest thousandth of one degree Celsius, + e.g. 30.125 + Returns: + A boolean, True if threshold is set successfully, False if not + """ + return False + + def get_high_critical_threshold(self): + """ + Retrieves the high critical threshold temperature of thermal + Returns: + A float number, the high critical threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + max_crit_key = '{}_max_crit'.format(self._airflow) + return self._thermal_info.get(max_crit_key, None) + + def get_low_critical_threshold(self): + """ + Retrieves the low critical threshold temperature of thermal + Returns: + A float number, the low critical threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + return 0.0 + def get_name(self): """ Retrieves the name of the thermal device Returns: string: The name of the thermal device """ - return self.THERMAL_NAME_LIST[self.index] + return self._thermal_info["name"] def get_presence(self): """ @@ -138,9 +198,25 @@ def get_presence(self): bool: True if PSU is present, False if not """ temp_file = "temp{}_input".format(self.ss_index) - temp_file_path = os.path.join(self.hwmon_path, temp_file) + temp_file_path = os.path.join(self._hwmon_path, temp_file) return os.path.isfile(temp_file_path) + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + return NULL_VAL + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + return NULL_VAL + def get_status(self): """ Retrieves the operational status of the device @@ -151,7 +227,7 @@ def get_status(self): return False fault_file = "temp{}_fault".format(self.ss_index) - fault_file_path = os.path.join(self.hwmon_path, fault_file) + fault_file_path = os.path.join(self._hwmon_path, fault_file) if not os.path.isfile(fault_file_path): return True diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/thermal_actions.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/thermal_actions.py new file mode 100644 index 000000000000..545db861f683 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/thermal_actions.py @@ -0,0 +1,78 @@ + +from sonic_platform_base.sonic_thermal_control.thermal_action_base import ThermalPolicyActionBase +from sonic_platform_base.sonic_thermal_control.thermal_json_object import thermal_json_object +from .thermal_infos import ChassisInfo +from .helper import APIHelper + + +@thermal_json_object('thermal_control.control') +class ControlThermalAlgoAction(ThermalPolicyActionBase): + """ + Action to control the thermal control algorithm + """ + # JSON field definition + JSON_FIELD_STATUS = 'status' + + def __init__(self): + self.status = True + + def load_from_json(self, json_obj): + """ + Construct ControlThermalAlgoAction via JSON. JSON example: + { + "type": "thermal_control.control" + "status": "true" + } + :param json_obj: A JSON object representing a ControlThermalAlgoAction action. + :return: + """ + if ControlThermalAlgoAction.JSON_FIELD_STATUS in json_obj: + status_str = json_obj[ControlThermalAlgoAction.JSON_FIELD_STATUS].lower() + if status_str == 'true': + self.status = True + elif status_str == 'false': + self.status = False + else: + raise ValueError('Invalid {} field value, please specify true of false'. + format(ControlThermalAlgoAction.JSON_FIELD_STATUS)) + else: + raise ValueError('ControlThermalAlgoAction ' + 'missing mandatory field {} in JSON policy file'. + format(ControlThermalAlgoAction.JSON_FIELD_STATUS)) + + def execute(self, thermal_info_dict): + """ + Disable thermal control algorithm + :param thermal_info_dict: A dictionary stores all thermal information. + :return: + """ + if ChassisInfo.INFO_NAME in thermal_info_dict: + chassis_info_obj = thermal_info_dict[ChassisInfo.INFO_NAME] + chassis = chassis_info_obj.get_chassis() + thermal_manager = chassis.get_thermal_manager() + if self.status: + thermal_manager.start_thermal_control_algorithm() + else: + thermal_manager.stop_thermal_control_algorithm() + + +@thermal_json_object('switch.power_cycling') +class SwitchPolicyAction(ThermalPolicyActionBase): + """ + Base class for thermal action. Once all thermal conditions in a thermal policy are matched, + all predefined thermal action will be executed. + """ + + def execute(self, thermal_info_dict): + """ + Take action when thermal condition matches. For example, power cycle the switch. + :param thermal_info_dict: A dictionary stores all thermal information. + :return: + """ + thermal_overload_position_path = '/tmp/thermal_overload_position' + thermal_overload_position = APIHelper().read_one_line_file( + thermal_overload_position_path) + + cmd = 'bash /usr/share/sonic/platform/thermal_overload_control.sh {}'.format( + thermal_overload_position) + APIHelper().run_command(cmd) diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/thermal_conditions.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/thermal_conditions.py new file mode 100644 index 000000000000..1eee8ea91ab5 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/thermal_conditions.py @@ -0,0 +1,77 @@ +from sonic_platform_base.sonic_thermal_control.thermal_condition_base import ThermalPolicyConditionBase +from sonic_platform_base.sonic_thermal_control.thermal_json_object import thermal_json_object + + +class FanCondition(ThermalPolicyConditionBase): + def get_fan_info(self, thermal_info_dict): + from .thermal_infos import FanInfo + if FanInfo.INFO_NAME in thermal_info_dict and isinstance(thermal_info_dict[FanInfo.INFO_NAME], FanInfo): + return thermal_info_dict[FanInfo.INFO_NAME] + else: + return None + + +@thermal_json_object('fan.any.absence') +class AnyFanAbsenceCondition(FanCondition): + def is_match(self, thermal_info_dict): + fan_info_obj = self.get_fan_info(thermal_info_dict) + return len(fan_info_obj.get_absence_fans()) > 0 if fan_info_obj else False + + +@thermal_json_object('fan.any.fault') +class AnyFanFaultCondition(FanCondition): + def is_match(self, thermal_info_dict): + fan_info_obj = self.get_fan_info(thermal_info_dict) + return len(fan_info_obj.get_fault_fans()) > 0 if fan_info_obj else False + + +@thermal_json_object('fan.all.presence') +class AllFanPresenceCondition(FanCondition): + def is_match(self, thermal_info_dict): + fan_info_obj = self.get_fan_info(thermal_info_dict) + return len(fan_info_obj.get_absence_fans()) == 0 if fan_info_obj else False + + +@thermal_json_object('fan.all.good') +class AllFanGoodCondition(FanCondition): + def is_match(self, thermal_info_dict): + fan_info_obj = self.get_fan_info(thermal_info_dict) + return len(fan_info_obj.get_fault_fans()) == 0 if fan_info_obj else False + + +class ThermalCondition(ThermalPolicyConditionBase): + def get_thermal_info(self, thermal_info_dict): + from .thermal_infos import ThermalInfo + if ThermalInfo.INFO_NAME in thermal_info_dict and isinstance(thermal_info_dict[ThermalInfo.INFO_NAME], ThermalInfo): + return thermal_info_dict[ThermalInfo.INFO_NAME] + else: + return None + + +@thermal_json_object('thermal.over.high_threshold') +class ThermalOverHighCriticalCondition(ThermalCondition): + def is_match(self, thermal_info_dict): + thermal_info_obj = self.get_thermal_info(thermal_info_dict) + if thermal_info_obj: + return thermal_info_obj.is_over_high_threshold() + else: + return False + + +@thermal_json_object('thermal.over.high_critical_threshold') +class ThermalOverHighCriticalCondition(ThermalCondition): + def is_match(self, thermal_info_dict): + thermal_info_obj = self.get_thermal_info(thermal_info_dict) + if thermal_info_obj: + return thermal_info_obj.is_over_high_critical_threshold() + else: + return False + +@thermal_json_object('thermal.all.good') +class ThermalGoodCondition(ThermalCondition): + def is_match(self, thermal_info_dict): + thermal_info_obj = self.get_thermal_info(thermal_info_dict) + if thermal_info_obj: + return not thermal_info_obj.is_over_threshold() + else: + return False diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/thermal_infos.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/thermal_infos.py new file mode 100644 index 000000000000..a680b31b634f --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/thermal_infos.py @@ -0,0 +1,165 @@ +from sonic_platform_base.sonic_thermal_control.thermal_info_base import ThermalPolicyInfoBase +from sonic_platform_base.sonic_thermal_control.thermal_json_object import thermal_json_object +from .helper import APIHelper +import time + + +@thermal_json_object('fan_info') +class FanInfo(ThermalPolicyInfoBase): + """ + Fan information needed by thermal policy + """ + + # Fan information name + INFO_NAME = 'fan_info' + + def __init__(self): + self._absence_fans = set() + self._presence_fans = set() + self._fault_fans = set() + self._status_changed = False + + def collect(self, chassis): + """ + Collect absence and presence fans. + :param chassis: The chassis object + :return: + """ + self._status_changed = False + for fan in chassis.get_all_fans(): + presence = fan.get_presence() + status = fan.get_status() + if presence and fan not in self._presence_fans: + self._presence_fans.add(fan) + self._status_changed = True + if fan in self._absence_fans: + self._absence_fans.remove(fan) + elif not presence and fan not in self._absence_fans: + self._absence_fans.add(fan) + self._status_changed = True + if fan in self._presence_fans: + self._presence_fans.remove(fan) + + if not status and fan not in self._fault_fans: + self._fault_fans.add(fan) + self._status_changed = True + + elif status and fan in self._fault_fans: + self._fault_fans.remove(fan) + self._status_changed = True + + def get_absence_fans(self): + """ + Retrieves absence fans + :return: A set of absence fans + """ + return self._absence_fans + + def get_presence_fans(self): + """ + Retrieves presence fans + :return: A set of presence fans + """ + return self._presence_fans + + def get_fault_fans(self): + """ + Retrieves fault fans + :return: A set of fault fans + """ + return self._fault_fans + + def is_status_changed(self): + """ + Retrieves if the status of fan information changed + :return: True if status changed else False + """ + return self._status_changed + + +@thermal_json_object('thermal_info') +class ThermalInfo(ThermalPolicyInfoBase): + """ + Thermal information needed by thermal policy + """ + + # Fan information name + INFO_NAME = 'thermal_info' + + def collect(self, chassis): + """ + Collect thermal sensor temperature change status + :param chassis: The chassis object + :return: + """ + self._over_high_threshold = False + self._over_high_critical_threshold = False + self._thermal_overload_position = 'cpu' + + # Calculate average temp within the device + temp = 0 + num_of_thermals = chassis.get_num_thermals() + for index in range(num_of_thermals): + thermal = chassis.get_thermal(index) + temp = thermal.get_temperature() + high_threshold = thermal.get_high_threshold() + high_critical_threshold = thermal.get_high_critical_threshold() + + if high_threshold and temp > high_threshold: + self._over_high_threshold = True + + if high_critical_threshold and temp > high_critical_threshold: + self._thermal_overload_position = thermal.postion + self._over_high_critical_threshold = True + + def is_over_threshold(self): + """ + Retrieves if the temperature is over any threshold + :return: True if the temperature is over any threshold else False + """ + return self._over_high_threshold or self._over_high_critical_threshold + + def is_over_high_critical_threshold(self): + """ + Retrieves if the temperature is over high critical threshold + :return: True if the temperature is over high critical threshold else False + """ + thermal_overload_position_path = '/tmp/thermal_overload_position' + if self._over_high_critical_threshold: + APIHelper().write_txt_file(thermal_overload_position_path, + self._thermal_overload_position) + time.sleep(1) + return self._over_high_critical_threshold + + def is_over_high_threshold(self): + """ + Retrieves if the temperature is over high threshold + :return: True if the temperature is over high threshold else False + """ + return self._over_high_threshold + + +@thermal_json_object('chassis_info') +class ChassisInfo(ThermalPolicyInfoBase): + """ + Chassis information needed by thermal policy + """ + INFO_NAME = 'chassis_info' + + def __init__(self): + self._chassis = None + + def collect(self, chassis): + """ + Collect platform chassis. + :param chassis: The chassis object + :return: + """ + self._chassis = chassis + + def get_chassis(self): + """ + Retrieves platform chassis object + :return: A platform chassis object. + """ + return self._chassis diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/thermal_manager.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/thermal_manager.py new file mode 100644 index 000000000000..9f057cf1f37f --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/thermal_manager.py @@ -0,0 +1,46 @@ +from sonic_platform_base.sonic_thermal_control.thermal_manager_base import ThermalManagerBase +from .helper import APIHelper +from .thermal_actions import * +from .thermal_conditions import * +from .thermal_infos import * + +class ThermalManager(ThermalManagerBase): + FSC_ALGORITHM_CMD = 'service fancontrol {}' + + @classmethod + def start_thermal_control_algorithm(cls): + """ + Start vendor specific thermal control algorithm. The default behavior of this function is a no-op. + :return: + """ + return cls._enable_fancontrol_service(True) + + @classmethod + def stop_thermal_control_algorithm(cls): + """ + Stop thermal control algorithm + Returns: + bool: True if set success, False if fail. + """ + return cls._enable_fancontrol_service(False) + + @classmethod + def deinitialize(cls): + """ + Destroy thermal manager, including any vendor specific cleanup. The default behavior of this function + is a no-op. + :return: + """ + return cls._enable_fancontrol_service(True) + + @classmethod + def _enable_fancontrol_service(cls, enable): + """ + Control thermal by fcs algorithm + Args: + enable: Bool, indicate enable the algorithm or not + Returns: + bool: True if set success, False if fail. + """ + cmd = 'start' if enable else 'stop' + return APIHelper().run_command(cls.FSC_ALGORITHM_CMD.format(cmd)) diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/watchdog.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/watchdog.py index b539bc06f618..31bb911d2401 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/watchdog.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/watchdog.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Celestica # @@ -7,115 +5,79 @@ # ############################################################################# import ctypes -import fcntl import os import subprocess import time -import array try: from sonic_platform_base.watchdog_base import WatchdogBase + from .helper import APIHelper except ImportError as e: raise ImportError(str(e) + "- required module not found") -""" ioctl constants """ -IO_WRITE = 0x40000000 -IO_READ = 0x80000000 -IO_READ_WRITE = 0xC0000000 -IO_SIZE_INT = 0x00040000 -IO_SIZE_40 = 0x00280000 -IO_TYPE_WATCHDOG = ord('W') << 8 - -WDR_INT = IO_READ | IO_SIZE_INT | IO_TYPE_WATCHDOG -WDR_40 = IO_READ | IO_SIZE_40 | IO_TYPE_WATCHDOG -WDWR_INT = IO_READ_WRITE | IO_SIZE_INT | IO_TYPE_WATCHDOG - -""" Watchdog ioctl commands """ -WDIOC_GETSUPPORT = 0 | WDR_40 -WDIOC_GETSTATUS = 1 | WDR_INT -WDIOC_GETBOOTSTATUS = 2 | WDR_INT -WDIOC_GETTEMP = 3 | WDR_INT -WDIOC_SETOPTIONS = 4 | WDR_INT -WDIOC_KEEPALIVE = 5 | WDR_INT -WDIOC_SETTIMEOUT = 6 | WDWR_INT -WDIOC_GETTIMEOUT = 7 | WDR_INT -WDIOC_SETPRETIMEOUT = 8 | WDWR_INT -WDIOC_GETPRETIMEOUT = 9 | WDR_INT -WDIOC_GETTIMELEFT = 10 | WDR_INT - -""" Watchdog status constants """ -WDIOS_DISABLECARD = 0x0001 -WDIOS_ENABLECARD = 0x0002 - +PLATFORM_CPLD_PATH = '/sys/devices/platform/dx010_cpld' +GETREG_FILE = 'getreg' +SETREG_FILE = 'setreg' +WDT_ENABLE_REG = '0x141' +WDT_TIMER_L_BIT_REG = '0x142' +WDT_TIMER_M_BIT_REG = '0x143' +WDT_TIMER_H_BIT_REG = '0x144' +WDT_KEEP_ALVIVE_REG = '0x145' +ENABLE_CMD = '0x1' +DISABLE_CMD = '0x0' WDT_COMMON_ERROR = -1 -WD_MAIN_IDENTITY = "iTCO_wdt" -WDT_SYSFS_PATH = "/sys/class/watchdog/" class Watchdog(WatchdogBase): def __init__(self): + # Init helper + self._api_helper = APIHelper() + + # Init cpld reg path + self.setreg_path = os.path.join(PLATFORM_CPLD_PATH, SETREG_FILE) + self.getreg_path = os.path.join(PLATFORM_CPLD_PATH, GETREG_FILE) - self.watchdog, self.wdt_main_dev_name = self._get_wdt() - self.status_path = "/sys/class/watchdog/%s/status" % self.wdt_main_dev_name - self.state_path = "/sys/class/watchdog/%s/state" % self.wdt_main_dev_name - self.timeout_path = "/sys/class/watchdog/%s/timeout" % self.wdt_main_dev_name # Set default value self._disable() self.armed = False - self.timeout = self._gettimeout(self.timeout_path) - - def _is_wd_main(self, dev): - """ - Checks watchdog identity - """ - identity = self._read_file( - "{}/{}/identity".format(WDT_SYSFS_PATH, dev)) - return identity == WD_MAIN_IDENTITY - - def _get_wdt(self): - """ - Retrieves watchdog device - """ - wdt_main_dev_list = [dev for dev in os.listdir( - "/dev/") if dev.startswith("watchdog") and self._is_wd_main(dev)] - if not wdt_main_dev_list: - return None - wdt_main_dev_name = wdt_main_dev_list[0] - watchdog_device_path = "/dev/{}".format(wdt_main_dev_name) - watchdog = os.open(watchdog_device_path, os.O_RDWR) - return watchdog, wdt_main_dev_name - - def _read_file(self, file_path): - """ - Read text file - """ - try: - with open(file_path, "r") as fd: - txt = fd.read() - except IOError: - return WDT_COMMON_ERROR - return txt.strip() + self.timeout = self._gettimeout() def _enable(self): """ Turn on the watchdog timer """ - req = array.array('h', [WDIOS_ENABLECARD]) - fcntl.ioctl(self.watchdog, WDIOC_SETOPTIONS, req, False) + # echo 0x141 0x1 > /sys/devices/platform/dx010_cpld/setreg + enable_val = '{} {}'.format(WDT_ENABLE_REG, ENABLE_CMD) + return self._api_helper.write_txt_file(self.setreg_path, enable_val) def _disable(self): """ Turn off the watchdog timer """ - req = array.array('h', [WDIOS_DISABLECARD]) - fcntl.ioctl(self.watchdog, WDIOC_SETOPTIONS, req, False) + # echo 0x141 0x0 > /sys/devices/platform/dx010_cpld/setreg + disable_val = '{} {}'.format(WDT_ENABLE_REG, DISABLE_CMD) + return self._api_helper.write_txt_file(self.setreg_path, disable_val) def _keepalive(self): """ Keep alive watchdog timer """ - fcntl.ioctl(self.watchdog, WDIOC_KEEPALIVE) + # echo 0x145 0x1 > /sys/devices/platform/dx010_cpld/setreg + enable_val = '{} {}'.format(WDT_KEEP_ALVIVE_REG, ENABLE_CMD) + return self._api_helper.write_txt_file(self.setreg_path, enable_val) + + def _get_level_hex(self, sub_hex): + sub_hex_str = sub_hex.replace("x", "0") + return hex(int(sub_hex_str, 16)) + + def _seconds_to_lmh_hex(self, seconds): + ms = seconds*1000 # calculate timeout in ms format + hex_str = hex(ms) + l = self._get_level_hex(hex_str[-2:]) + m = self._get_level_hex(hex_str[-4:-2]) + h = self._get_level_hex(hex_str[-6:-4]) + return (l, m, h) def _settimeout(self, seconds): """ @@ -123,29 +85,35 @@ def _settimeout(self, seconds): @param seconds - timeout in seconds @return is the actual set timeout """ - req = array.array('I', [seconds]) - fcntl.ioctl(self.watchdog, WDIOC_SETTIMEOUT, req, True) - return int(req[0]) + # max = 0xffffff = 16777.215 seconds + + (l, m, h) = self._seconds_to_lmh_hex(seconds) + set_h_val = '{} {}'.format(WDT_TIMER_H_BIT_REG, h) + set_m_val = '{} {}'.format(WDT_TIMER_M_BIT_REG, m) + set_l_val = '{} {}'.format(WDT_TIMER_L_BIT_REG, l) - def _gettimeout(self, timeout_path): + self._api_helper.write_txt_file(self.setreg_path, set_h_val) + self._api_helper.write_txt_file(self.setreg_path, set_m_val) + self._api_helper.write_txt_file(self.setreg_path, set_l_val) + + return seconds + + def _gettimeout(self): """ Get watchdog timeout @return watchdog timeout """ - req = array.array('I', [0]) - fcntl.ioctl(self.watchdog, WDIOC_GETTIMEOUT, req, True) - return int(req[0]) - - def _gettimeleft(self): - """ - Get time left before watchdog timer expires - @return time left in seconds - """ - req = array.array('I', [0]) - fcntl.ioctl(self.watchdog, WDIOC_GETTIMELEFT, req, True) + h_bit = self._api_helper.get_cpld_reg_value( + self.getreg_path, WDT_TIMER_H_BIT_REG) + m_bit = self._api_helper.get_cpld_reg_value( + self.getreg_path, WDT_TIMER_M_BIT_REG) + l_bit = self._api_helper.get_cpld_reg_value( + self.getreg_path, WDT_TIMER_L_BIT_REG) - return int(req[0]) + hex_time = '0x{}{}{}'.format(h_bit[2:], m_bit[2:], l_bit[2:]) + ms = int(hex_time, 16) + return int(float(ms)/1000) ################################################################# @@ -169,12 +137,15 @@ def arm(self, seconds): try: if self.timeout != seconds: self.timeout = self._settimeout(seconds) + if self.armed: self._keepalive() else: self._enable() self.armed = True + ret = self.timeout + self.arm_timestamp = time.time() except IOError as e: pass @@ -215,19 +186,4 @@ def get_remaining_time(self): watchdog timer. If the watchdog is not armed, returns -1. """ - timeleft = WDT_COMMON_ERROR - - if self.armed: - try: - timeleft = self._gettimeleft() - except IOError: - pass - - return timeleft - - def __del__(self): - """ - Close watchdog - """ - - os.close(self.watchdog) + return int(self.timeout - (time.time() - self.arm_timestamp)) if self.armed else WDT_COMMON_ERROR diff --git a/device/celestica/x86_64-cel_seastone-r0/system_health_monitoring_config.json b/device/celestica/x86_64-cel_seastone-r0/system_health_monitoring_config.json new file mode 100644 index 000000000000..4dc38d035ab4 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/system_health_monitoring_config.json @@ -0,0 +1,16 @@ +{ + "services_to_ignore": [], + "devices_to_ignore": [ + "asic", + "psu.temperature", + "PSU2 Fan", + "PSU1 Fan" + ], + "user_defined_checkers": [], + "polling_interval": 60, + "led_color": { + "fault": "orange", + "normal": "green", + "booting": "orange_blink" + } +} \ No newline at end of file diff --git a/device/celestica/x86_64-cel_seastone-r0/thermal_overload_control.sh b/device/celestica/x86_64-cel_seastone-r0/thermal_overload_control.sh new file mode 100755 index 000000000000..57fd851f9cfb --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/thermal_overload_control.sh @@ -0,0 +1,75 @@ +#!/bin/bash +# +# Copyright 2020-present Celestica. All Rights Reserved. +# +# This program file is free software; 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. +# +# + +PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin +SETREG_FILE=/sys/devices/platform/dx010_cpld/setreg +TOVERREG=0x140 +CPUOVER=0xa1 +ASICOVER=0xa2 + +prog="$0" +command="$1" + +if [[ $EUID -ne 0 ]]; then + echo "This script must be run as root" + exit 1 +fi + +usage() { + echo "Usage: thermal_overload_control.sh [option] " + echo + echo "Options:" + echo " -h, --help : to print this message." + echo + echo "Commands:" + echo + echo " cpu: To enabling CPU thermal overload handler" + echo + echo " asic : To enabling ASIC thermal overload handler" + echo +} + +cpu_overload() { + logger "Enable CPU thermal overload control" + set_reg=`echo ${TOVERREG} ${CPUOVER} > ${SETREG_FILE}` +} + +asic_overload() { + logger "Enable ASIC thermal overload control" + set_reg=`echo ${TOVERREG} ${ASICOVER} > ${SETREG_FILE}` +} + +if [ $# -lt 1 ]; then + usage + exit -1 +fi + +case "$command" in +-h | --help) + usage + ;; +cpu) + cpu_overload + ;; +asic) + asic_overload + ;; +*) + usage + exit -1 + ;; +esac + +exit $? diff --git a/device/celestica/x86_64-cel_seastone-r0/thermal_policy.json b/device/celestica/x86_64-cel_seastone-r0/thermal_policy.json new file mode 100644 index 000000000000..f937b6bd4456 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/thermal_policy.json @@ -0,0 +1,93 @@ +{ + "thermal_control_algorithm": { + "run_at_boot_up": "true" + }, + "info_types": [ + { + "type": "chassis_info" + }, + { + "type": "fan_info" + }, + { + "type": "thermal_info" + } + ], + "policies": [ + { + "name": "any fan absence", + "conditions": [ + { + "type": "fan.any.absence" + } + ], + "actions": [ + { + "type": "thermal_control.control", + "status": "false" + } + ] + }, + { + "name": "any fan broken", + "conditions": [ + { + "type": "fan.any.fault" + } + ], + "actions": [ + { + "type": "thermal_control.control", + "status": "false" + } + ] + }, + { + "name": "any thermal over threshold", + "conditions": [ + { + "type": "thermal.over.high_threshold" + } + ], + "actions": [ + { + "type": "thermal_control.control", + "status": "false" + } + ] + }, + { + "name": "temp over high critical threshold", + "conditions": [ + { + "type": "thermal.over.high_critical_threshold" + } + ], + "actions": [ + { + "type": "switch.power_cycling" + } + ] + }, + { + "name": "all fan presence / thermal no warning", + "conditions": [ + { + "type": "fan.all.presence" + }, + { + "type": "fan.all.good" + }, + { + "type": "thermal.all.good" + } + ], + "actions": [ + { + "type": "thermal_control.control", + "status": "true" + } + ] + } + ] +} \ No newline at end of file diff --git a/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/sai.profile b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/sai.profile index ea150bf237c3..b57101d114f0 100644 --- a/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/sai.profile +++ b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-seastone_2-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/td3-seastone_2-32x100G.config.bcm b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/td3-seastone_2-32x100G.config.bcm index 2c23d0da2f22..62bcdbc58840 100644 --- a/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/td3-seastone_2-32x100G.config.bcm +++ b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/td3-seastone_2-32x100G.config.bcm @@ -1,3 +1,4 @@ +sai_load_hw_config=/etc/bcm/flex/bcm56870_a0_issu/b870.6.4.1/ help_cli_enable=1 ifp_inports_support_enable=1 ipv6_lpm_128b_enable=0x1 diff --git a/device/celestica/x86_64-cel_seastone_2-r0/plugins/eeprom.py b/device/celestica/x86_64-cel_seastone_2-r0/plugins/eeprom.py index 2ae540870c41..93290ebf82bf 100644 --- a/device/celestica/x86_64-cel_seastone_2-r0/plugins/eeprom.py +++ b/device/celestica/x86_64-cel_seastone_2-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Celestica Seastone2 # @@ -11,8 +9,8 @@ try: from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): @@ -20,4 +18,3 @@ class board(eeprom_tlvinfo.TlvInfoDecoder): def __init__(self, name, path, cpld_root, ro): self.eeprom_path = "/sys/class/i2c-adapter/i2c-0/0-0056/eeprom" super(board, self).__init__(self.eeprom_path, 0, '', True) - diff --git a/device/celestica/x86_64-cel_seastone_2-r0/plugins/psuutil.py b/device/celestica/x86_64-cel_seastone_2-r0/plugins/psuutil.py index f315e875542c..cc5461ccb5d4 100644 --- a/device/celestica/x86_64-cel_seastone_2-r0/plugins/psuutil.py +++ b/device/celestica/x86_64-cel_seastone_2-r0/plugins/psuutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - import os.path import subprocess import sys @@ -8,7 +6,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" @@ -18,21 +17,21 @@ def __init__(self): PsuBase.__init__(self) def run_command(self, command): - proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) + proc = subprocess.Popen(command, shell=True, universal_newlines=True, stdout=subprocess.PIPE) (out, err) = proc.communicate() if proc.returncode != 0: sys.exit(proc.returncode) - + return out - + def find_value(self, grep_string): result = re.search(".+\| (0x\d{2})\d{2}\|.+", grep_string) if result: return result.group(1) else: return result - + def get_num_psus(self): """ Retrieves the number of PSUs available on the device @@ -51,9 +50,9 @@ def get_psu_status(self, index): return False grep_key = "PSUL_Status" if index == 1 else "PSUR_Status" - grep_string = self.run_command(self.ipmi_sensor + ' | grep '+ grep_key) + grep_string = self.run_command(self.ipmi_sensor + ' | grep ' + grep_key) status_byte = self.find_value(grep_string) - + if status_byte is None: return False @@ -75,13 +74,13 @@ def get_psu_presence(self, index): return False grep_key = "PSUL_Status" if index == 1 else "PSUR_Status" - grep_string = self.run_command(self.ipmi_sensor + ' | grep '+ grep_key) + grep_string = self.run_command(self.ipmi_sensor + ' | grep ' + grep_key) status_byte = self.find_value(grep_string) - + if status_byte is None: return False - - presence = ( int(status_byte, 16) >> 0 ) & 1 + + presence = (int(status_byte, 16) >> 0) & 1 if presence: return True else: diff --git a/device/celestica/x86_64-cel_seastone_2-r0/plugins/sfputil.py b/device/celestica/x86_64-cel_seastone_2-r0/plugins/sfputil.py index db3ca9976e32..6f05527621fe 100755 --- a/device/celestica/x86_64-cel_seastone_2-r0/plugins/sfputil.py +++ b/device/celestica/x86_64-cel_seastone_2-r0/plugins/sfputil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python -# # Platform-specific SFP transceiver interface for SONiC # @@ -35,7 +33,7 @@ def port_end(self): @property def qsfp_ports(self): - return range(self.QSFP_PORT_START, self.QSFP_PORT_END + 1) + return list(range(self.QSFP_PORT_START, self.QSFP_PORT_END + 1)) @property def port_to_eeprom_mapping(self): @@ -73,7 +71,7 @@ def __init__(self): def get_presence(self, port_num): # Check for invalid port_num - if port_num not in range(self.port_start, self.port_end + 1): + if port_num not in list(range(self.port_start, self.port_end + 1)): return False # Get path for access port presence status @@ -87,7 +85,7 @@ def get_presence(self, port_num): content = reg_file.readline().rstrip() reg_value = int(content) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False # Module present is active low @@ -106,7 +104,7 @@ def get_low_power_mode(self, port_num): reg_file = open( "/".join([self.PORT_INFO_PATH, port_name, "qsfp_lpmode"]), "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False # Read status @@ -128,7 +126,7 @@ def set_low_power_mode(self, port_num, lpmode): reg_file = open( "/".join([self.PORT_INFO_PATH, port_name, "qsfp_lpmode"]), "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = hex(lpmode) @@ -149,7 +147,7 @@ def reset(self, port_num): reg_file = open( "/".join([self.PORT_INFO_PATH, port_name, "qsfp_reset"]), "w") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False # Convert our register value back to a hex string and write back @@ -165,7 +163,7 @@ def reset(self, port_num): reg_file = open( "/".join([self.PORT_INFO_PATH, port_name, "qsfp_reset"]), "w") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_file.seek(0) @@ -179,4 +177,3 @@ def get_transceiver_change_event(self, timeout=0): TBD: When the feature request. """ raise NotImplementedError - diff --git a/device/celestica/x86_64-cel_seastone_2-r0/pmon_daemon_control.json b/device/celestica/x86_64-cel_seastone_2-r0/pmon_daemon_control.json index 294259681a11..5e59513ef696 100644 --- a/device/celestica/x86_64-cel_seastone_2-r0/pmon_daemon_control.json +++ b/device/celestica/x86_64-cel_seastone_2-r0/pmon_daemon_control.json @@ -2,5 +2,6 @@ "skip_ledd": true, "skip_xcvrd": false, "skip_psud": false, - "skip_syseepromd": false + "skip_syseepromd": false, + "skip_fancontrol": true } \ No newline at end of file diff --git a/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/chassis.json b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/chassis.json new file mode 100644 index 000000000000..dfa1a1bddff8 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/chassis.json @@ -0,0 +1,45 @@ +{ + "eeprom": "/sys/class/i2c-adapter/i2c-0/0-0056/eeprom", + "get_reboot_cause": { + "output_source": "ipmitool", + "command": "ipmitool raw 0x3a 0x0c 0x0 0x2 0x06", + "output_translator": { + "00": "Hardware - Other", + "11": "Hardware - Other", + "22": "Non-Hardware", + "33": "Hardware - Other", + "44": "Non-Hardware", + "55": "Non-Hardware", + "77": "Watchdog", + "88": "Thermal Overload: CPU", + "99": "Thermal Overload: ASIC" + } + }, + "get_reboot_description": { + "output_source": "ipmitool", + "command": "ipmitool raw 0x3a 0x0c 0x0 0x2 0x06", + "output_translator": { + "00": "The last reset is power cycle reset (set register 0xA164)", + "11": "The last reset is Power on reset", + "22": "The last reset is soft-set CPU warm reset", + "33": "The last reset is soft-set CPU cold reset", + "44": "The last reset is CPU warm reset", + "55": "The last reset is CPU cold reset", + "77": "The last reset is watchdog reset", + "88": "The last reset is CPU thermal overload", + "99": "The last reset is ASIC thermal overload" + } + }, + "get_watchdog": { + "output_source": "class", + "host_path": "/usr/share/sonic/device/x86_64-cel_seastone_2-r0/sonic_platform_config/watchdog.py", + "pmon_path": "/usr/share/sonic/platform/sonic_platform_config/watchdog.py", + "class": "Watchdog" + }, + "get_change_event": { + "output_source": "class", + "host_path": "/usr/share/sonic/device/x86_64-cel_seastone_2-r0/sonic_platform_config/event.py", + "pmon_path": "/usr/share/sonic/platform/sonic_platform_config/event.py", + "class": "SfpEvent" + } +} diff --git a/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/component.json b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/component.json new file mode 100644 index 000000000000..96f646206f97 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/component.json @@ -0,0 +1,62 @@ +{ + "component_num": 5, + "get_name": { + "output_source": "value_list", + "value_list": [ + "BIOS", + "CPLD_BASEBOARD", + "CPLD_SWITCHBOARD", + "FPGA", + "BMC" + ] + }, + "get_description": { + "output_source": "value_list", + "value_list": [ + "Used to perform hardware initialization during the booting process", + "Used to control the system power & reset, Control FAN, UART Mux etc", + "Used for managing QSFP ports", + "Used for managing I2C, SPI, PCIe etc", + "Used for monitoring and managing whole system" + ] + }, + "get_firmware_version": { + "output_source": "function", + "function": [ + "_get_bios_ver", + "_get_base_cpld_ver", + "_get_sw_cpld_ver", + "_get_fpga_ver", + "_get_bmc_ver" + ] + }, + "_get_bmc_ver": { + "output_source": "ipmitool", + "command": "ipmitool mc info | grep 'Firmware Revision'", + "output_translator": "'{}'.split(':')[-1].strip()" + }, + "_get_bios_ver": { + "output_source": "txt_file", + "path": "/sys/class/dmi/id/bios_version" + }, + "_get_base_cpld_ver": { + "output_source": "hex_version_file", + "num_of_points": 1, + "num_of_bits": 8, + "path": "/sys/devices/platform/baseboard/version" + }, + "_get_sw_cpld_ver": { + "output_source": "hex_version_getreg", + "num_of_points": 1, + "num_of_bits": 8, + "reg_addr": "0x00", + "path": "/sys/devices/platform/switchboard/CPLD1/getreg" + }, + "_get_fpga_ver": { + "output_source": "hex_version_getreg", + "num_of_points": 1, + "num_of_bits": 32, + "reg_addr": "0x00", + "path": "/sys/devices/platform/switchboard/FPGA/getreg" + } +} \ No newline at end of file diff --git a/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/event.py b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/event.py new file mode 100644 index 000000000000..ed3b78cf7fd6 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/event.py @@ -0,0 +1,112 @@ +############################################################################# +# Celestica Seastone2 +# +# SfpEvent contains an implementation of SONiC Platform Base API +# +############################################################################# +try: + import time + import os + from sonic_platform.common import Common +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +PLATFORM_PATH = "/sys/devices/platform/" +SWITCH_BRD_PLATFORM = "switchboard" +POLL_INTERVAL = 1 + + +class SfpEvent: + ''' Listen to insert/remove sfp events ''' + + PORT_INFO_DIR = 'SFF' + PATH_INT_SYSFS = "{0}/{port_name}/{type_prefix}_isr_flags" + PATH_INTMASK_SYSFS = "{0}/{port_name}/{type_prefix}_isr_mask" + PATH_PRS_SYSFS = "{0}/{port_name}/{prs_file_name}" + PRESENT_EN = 0x01 + + def __init__(self, sfp_list): + self.num_sfp = len(sfp_list) + self._api_common = Common() + self._initialize_interrupts() + + def _initialize_interrupts(self): + sfp_info_obj = {} + port_info_path = os.path.join( + PLATFORM_PATH, SWITCH_BRD_PLATFORM, self.PORT_INFO_DIR) + + for index in range(self.num_sfp): + port_num = index + 1 + port_name = "QSFP{}".format(port_num) + port_type = "qsfp" + sysfs_prs_file = "{}_modprs".format(port_type) + + sfp_info_obj[index] = {} + sfp_info_obj[index]['intmask_sysfs'] = self.PATH_INTMASK_SYSFS.format( + port_info_path, + port_name=port_name, + type_prefix=port_type) + + sfp_info_obj[index]['int_sysfs'] = self.PATH_INT_SYSFS.format( + port_info_path, + port_name=port_name, + type_prefix=port_type) + + sfp_info_obj[index]['prs_sysfs'] = self.PATH_PRS_SYSFS.format( + port_info_path, + port_name=port_name, + prs_file_name=sysfs_prs_file) + + self._api_common.write_txt_file( + sfp_info_obj[index]["intmask_sysfs"], hex(self.PRESENT_EN)) + + self.sfp_info_obj = sfp_info_obj + + def _is_port_device_present(self, port_idx): + prs_path = self.sfp_info_obj[port_idx]["prs_sysfs"] + is_present = 1 - int(self._api_common.read_txt_file(prs_path)) + return is_present + + def _update_port_event_object(self, interrup_devices, port_dict): + for port_idx in interrup_devices: + device_id = str(port_idx + 1) + port_dict[device_id] = str(self._is_port_device_present(port_idx)) + return port_dict + + def _clear_event_flag(self, path): + self._api_common.write_txt_file(path, hex(0xff)) + time.sleep(0.1) + self._api_common.write_txt_file(path, hex(0x0)) + + def _check_all_port_interrupt_event(self): + interrupt_devices = {} + for i in range(self.num_sfp): + int_sysfs = self.sfp_info_obj[i]["int_sysfs"] + interrupt_flags = self._api_common.read_txt_file(int_sysfs) + if interrupt_flags != '0x00': + interrupt_devices[i] = 1 + self._clear_event_flag(int_sysfs) + return interrupt_devices + + def get_event(self, timeout): + sleep_time = min( + timeout, POLL_INTERVAL) if timeout != 0 else POLL_INTERVAL + start_milli_time = int(round(time.time() * 1000)) + int_sfp = {} + + while True: + chk_sfp = self._check_all_port_interrupt_event() + int_sfp = self._update_port_event_object( + chk_sfp, int_sfp) if chk_sfp else int_sfp + current_milli_time = int(round(time.time() * 1000)) + if (int_sfp) or \ + (timeout != 0 and current_milli_time - start_milli_time > timeout): + break + + time.sleep(sleep_time) + + change_dict = dict() + change_dict['sfp'] = int_sfp + + return True, change_dict diff --git a/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/fan.json b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/fan.json new file mode 100644 index 000000000000..724f6edf53c1 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/fan.json @@ -0,0 +1,200 @@ +{ + "fan_num_per_drawer": 2, + "drawer_num": 4, + "get_name": { + "output_source": "value_list", + "value_list": [ + "Fan1-F", + "Fan1-R", + "Fan2-F", + "Fan2-R", + "Fan3-F", + "Fan3-R", + "Fan4-F", + "Fan4-R" + ] + }, + "get_presence": { + "output_source": "ipmitool", + "command": "ipmitool raw 0x3a 0x03 0x03 {}", + "argument": [ + "0x00", + "0x00", + "0x01", + "0x01", + "0x02", + "0x02", + "0x03", + "0x03" + ], + "output_translator": "True if '00' in '{}' else False" + }, + "get_model": { + "output_source": "ipmitool", + "command": "ipmitool fru list {} | grep 'Board Part Number'", + "argument": [ + "5", + "5", + "6", + "6", + "7", + "7", + "8", + "8" + ], + "output_translator": "'{}'.split()[-1]" + }, + "get_serial": { + "output_source": "ipmitool", + "command": "ipmitool fru list {} | grep 'Board Serial'", + "argument": [ + "5", + "5", + "6", + "6", + "7", + "7", + "8", + "8" + ], + "output_translator": "'{}'.split()[-1]" + }, + "get_direction": { + "output_source": "ipmitool", + "command": "ipmitool fru list {} | grep 'F2B\\|B2F'", + "argument": [ + "5", + "5", + "6", + "6", + "7", + "7", + "8", + "8" + ], + "output_translator": "'intake' if 'B2F' in '{}' else 'exhaust'" + }, + "get_speed": { + "output_source": "ipmitool", + "command": "ipmitool raw 0x04 0x2d {}", + "argument": [ + "0x81", + "0x80", + "0x83", + "0x82", + "0x85", + "0x84", + "0x87", + "0x86" + ], + "output_translator": "int('{}'.split()[0],16)*150", + "max_front": 23000, + "max_rear": 20500 + }, + "get_target_speed": { + "output_source": "value", + "value": "N/A" + }, + "get_speed_tolerance": { + "output_source": "value", + "value": 10 + }, + "set_speed": { + "set_method": "ipmitool", + "input_translator": "hex(int({} * 255 / 100.0))", + "command": "ipmitool raw 0x3a 0x0c 0x00 0x03 {}", + "argument": [ + "0x40 {}", + "0x40 {}", + "0x44 {}", + "0x44 {}", + "0x4c {}", + "0x4c {}", + "0x50 {}", + "0x50 {}" + ] + }, + "set_status_led": { + "set_method": "ipmitool", + "avaliable_input": [ + "off", + "amber", + "green" + ], + "input_translator": { + "off": "0x0", + "amber": "0x1", + "green": "0x2" + }, + "command": "ipmitool raw 0x3a 0x0a {}", + "argument": [ + "0x4 {}", + "0x4 {}", + "0x5 {}", + "0x5 {}", + "0x6 {}", + "0x6 {}", + "0x7 {}", + "0x7 {}" + ] + }, + "get_status_led": { + "output_source": "ipmitool", + "command": "ipmitool raw 0x3a 0x0b {}", + "argument": [ + "0x4", + "0x4", + "0x5", + "0x5", + "0x6", + "0x6", + "0x7", + "0x7" + ], + "output_translator": { + "00": "off", + "01": "amber", + "02": "green" + } + }, + "psu_fan": [ + { + "num_of_fan": 1, + "get_name": { + "output_source": "value_list", + "value_list": [ + "PSU-R-Fan" + ] + }, + "get_speed": { + "output_source": "ipmitool", + "command": "ipmitool raw 0x04 0x2d {}", + "argument": [ + "0x8b" + ], + "output_translator": "int('{}'.split()[0],16)*100", + "max_front": 22600, + "max_rear": 22600 + } + }, + { + "num_of_fan": 1, + "get_name": { + "output_source": "value_list", + "value_list": [ + "PSU-L-Fan" + ] + }, + "get_speed": { + "output_source": "ipmitool", + "command": "ipmitool raw 0x04 0x2d {}", + "argument": [ + "0x8a" + ], + "output_translator": "int('{}'.split()[0],16)*100", + "max_front": 22600, + "max_rear": 22600 + } + } + ] +} \ No newline at end of file diff --git a/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/psu.json b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/psu.json new file mode 100644 index 000000000000..c3e953c082a7 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/psu.json @@ -0,0 +1,135 @@ +{ + "psu_num": 2, + "fan_per_psu_num": 1, + "get_name": { + "output_source": "value_list", + "value_list": [ + "PSU-R", + "PSU-L" + ] + }, + "get_power": { + "output_source": "ipmitool", + "command": "ipmitool sdr | grep {}", + "argument": [ + "PSUR_POut", + "PSUL_POut" + ], + "output_translator": "float('{}'.split()[2])" + }, + "get_current": { + "output_source": "ipmitool", + "command": "ipmitool sdr | grep {}", + "argument": [ + "PSUR_COut", + "PSUL_COut" + ], + "output_translator": "float('{}'.split()[2])" + }, + "get_voltage": { + "output_source": "ipmitool", + "command": "ipmitool sdr | grep {}", + "argument": [ + "PSUR_VOut", + "PSUL_VOut" + ], + "output_translator": "float('{}'.split()[2])" + }, + "get_voltage_high_threshold": { + "output_source": "ipmitool", + "command": "ipmitool sensor list | grep {}", + "argument": [ + "PSUR_Temp2", + "PSUL_Temp2" + ], + "output_translator": "float(0 if '{0}'.split()[-3]=='na' else '{0}'.split()[-3])" + }, + "get_voltage_low_threshold": { + "output_source": "ipmitool", + "command": "ipmitool sensor list | grep {}", + "argument": [ + "PSUR_Temp2", + "PSUL_Temp2" + ], + "output_translator": "float(0 if '{0}'.split()[-9]=='na' else '{0}'.split()[-9])" + }, + "get_presence": { + "output_source": "ipmitool", + "command": "ipmitool raw 0x3a 0x0c 0x00 0x2 0x60", + "output_translator": [ + "True if (int('{}', 16) >> 4 & 1) == 0 else False", + "True if (int('{}', 16) >> 5 & 1) == 0 else False" + ] + }, + "get_model": { + "output_source": "ipmitool", + "command": "ipmitool fru list {} | grep 'Product Part Number'", + "argument": [ + "4", + "3" + ], + "output_translator": "'{}'.split()[-1]" + }, + "get_serial": { + "output_source": "ipmitool", + "command": "ipmitool fru list {} | grep 'Product Serial'", + "argument": [ + "4", + "3" + ], + "output_translator": "'{}'.split()[-1]" + }, + "get_powergood_status": { + "output_source": "ipmitool", + "command": "ipmitool raw 0x3a 0x0c 0x0 0x2 0x60", + "output_translator": [ + "True if (int('{}', 16) >> 2 & 1) == 1 else False", + "True if (int('{}', 16) >> 3 & 1) == 1 else False" + ] + }, + "set_status_led": { + "set_method": "ipmitool", + "avaliable_input": [ + "amber" + ], + "input_translator": { + "amber": "0x1" + }, + "command": "ipmitool raw 0x3a 0x0a {}", + "argument": [ + "0x3 {}", + "0x2 {}" + ] + }, + "get_status_led": { + "output_source": "ipmitool", + "command": "ipmitool raw 0x3a 0x0b {}", + "argument": [ + "0x3", + "0x2" + ], + "output_translator": { + "00": "green", + "01": "amber" + }, + "default_output": "off" + }, + "get_temperature": { + "output_source": "ipmitool", + "command": "ipmitool sdr | grep {}", + "argument": [ + "PSUR_Temp2", + "PSUL_Temp2" + ], + "output_translator": "float('{}'.split()[2])" + }, + "get_temperature_high_threshold": { + "output_source": "ipmitool", + "command": "ipmitool sensor list | grep {}", + "argument": [ + "PSUR_Temp2", + "PSUL_Temp2" + ], + "output_translator": "float(0 if '{0}'.split()[-3]=='na' else '{0}'.split()[-3])" + } +} \ No newline at end of file diff --git a/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/sfp.json b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/sfp.json new file mode 100644 index 000000000000..d77e75e50e2f --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/sfp.json @@ -0,0 +1,106 @@ +{ + "port_num": 32, + "eeprom_path": "/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom", + "port_i2c_mapping": [ + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33 + ], + "get_presence": { + "output_source": "sysfs_value", + "sysfs_path": "/sys/devices/platform/switchboard/SFF/{}/qsfp_modprs", + "argument": "$ref:_port_name", + "output_translator": "False if '{}' == '1' else True" + }, + "get_lpmode": { + "output_source": "sysfs_value", + "sysfs_path": "/sys/devices/platform/switchboard/SFF/{}/qsfp_lpmode", + "argument": "$ref:_port_name", + "output_translator": "True if '{}' == '1' else False" + }, + "get_reset_status": { + "output_source": "sysfs_value", + "sysfs_path": "/sys/devices/platform/switchboard/SFF/{}/qsfp_reset", + "argument": "$ref:_port_name", + "output_translator": "False if '{}' == '1' else True" + }, + "reset": { + "set_method": "sysfs_value", + "write_offset": 0, + "sysfs_path": "/sys/devices/platform/switchboard/SFF/{}/qsfp_reset", + "argument": "$ref:_port_name" + }, + "set_lpmode": { + "set_method": "sysfs_value", + "input_translator": { + "True": "0x1", + "False": "0x0" + }, + "write_offset": 0, + "sysfs_path": "/sys/devices/platform/switchboard/SFF/{}/qsfp_lpmode", + "argument": "$ref:_port_name" + }, + "_port_name": [ + "QSFP1", + "QSFP2", + "QSFP3", + "QSFP4", + "QSFP5", + "QSFP6", + "QSFP7", + "QSFP8", + "QSFP9", + "QSFP10", + "QSFP11", + "QSFP12", + "QSFP13", + "QSFP14", + "QSFP15", + "QSFP16", + "QSFP17", + "QSFP18", + "QSFP19", + "QSFP20", + "QSFP21", + "QSFP22", + "QSFP23", + "QSFP24", + "QSFP25", + "QSFP26", + "QSFP27", + "QSFP28", + "QSFP29", + "QSFP30", + "QSFP31", + "QSFP32" + ] +} \ No newline at end of file diff --git a/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/thermal.json b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/thermal.json new file mode 100644 index 000000000000..e3dcb7fb9271 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/thermal.json @@ -0,0 +1,105 @@ +{ + "thermal_num": 9, + "get_name": { + "output_source": "value_list", + "value_list": [ + "Base_Temp_U5", + "Base_Temp_U7", + "CPU_Temp", + "Switch_Temp_U1", + "Switch_Temp_U18", + "Switch_Temp_U28", + "Switch_Temp_U29", + "Switch_U21_Temp", + "Switch_U33_Temp" + ] + }, + "get_temperature": { + "output_source": "ipmitool", + "command": "ipmitool raw 0x04 0x2D {}", + "argument": [ + "0x1", + "0x2", + "0x7", + "0x3", + "0x4", + "0x5", + "0x6", + "0x56", + "0x4C" + ], + "output_translator": "int('{}'.split()[0],16)" + }, + "get_high_threshold": { + "output_source": "ipmitool", + "command": "ipmitool raw 0x04 0x27 {}", + "argument": [ + "0x1", + "0x2", + "0x7", + "0x3", + "0x4", + "0x5", + "0x6", + "0x56", + "0x4c" + ], + "output_translator": "int('{}'.split()[4], 16)" + }, + "get_low_threshold": { + "output_source": "value", + "value": "N/A" + }, + "set_high_threshold": { + "set_method": "ipmitool", + "command": "ipmitool sensor thresh {}", + "input_translator": "{}", + "argument": [ + "Base_Temp_U5 unc {}", + "Base_Temp_U7 unc {}", + "CPU_Temp unc {}", + "Switch_Temp_U1 unc {}", + "Switch_Temp_U18 unc {}", + "Switch_Temp_U28 unc {}", + "Switch_Temp_U29 unc {}", + "Switch_U21_Temp unc {}", + "Switch_U33_Temp unc {}" + ] + }, + "set_low_threshold": { + "output_source": "ipmitool", + "command": "ipmitool sensor thresh {}", + "input_translator": "{}", + "argument": [ + "Base_Temp_U5 lnc {}", + "Base_Temp_U7 lnc {}", + "CPU_Temp lnc {}", + "Switch_Temp_U1 lnc {}", + "Switch_Temp_U18 lnc {}", + "Switch_Temp_U28 lnc {}", + "Switch_Temp_U29 lnc {}", + "Switch_U21_Temp lnc {}", + "Switch_U33_Temp lnc {}" + ] + }, + "get_high_critical_threshold": { + "output_source": "ipmitool", + "command": "ipmitool raw 0x04 0x27 {}", + "argument": [ + "0x1", + "0x2", + "0x7", + "0x3", + "0x4", + "0x5", + "0x6", + "0x56", + "0x4c" + ], + "output_translator": "int('{}'.split()[5], 16)" + }, + "get_low_critical_threshold": { + "output_source": "value", + "value": "N/A" + } +} \ No newline at end of file diff --git a/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/watchdog.py b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/watchdog.py new file mode 100644 index 000000000000..cc87c3d6b32a --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/watchdog.py @@ -0,0 +1,189 @@ +############################################################################# +# Celestica Seastone2 +# +# Watchdog contains an implementation of SONiC Platform Base API +# +############################################################################# +import os +import time + +try: + from sonic_platform_base.watchdog_base import WatchdogBase + from sonic_platform.common import Common +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +PLATFORM_CPLD_PATH = '/sys/devices/platform/baseboard/' +GETREG_FILE = 'getreg' +SETREG_FILE = 'setreg' +WDT_ENABLE_REG = '0xA181' +WDT_TIMER_L_BIT_REG = '0xA182' +WDT_TIMER_M_BIT_REG = '0xA183' +WDT_TIMER_H_BIT_REG = '0xA184' +WDT_KEEP_ALVIVE_REG = '0xA185' +ENABLE_CMD = '0x1' +DISABLE_CMD = '0x0' +WDT_COMMON_ERROR = -1 + + +class Watchdog(WatchdogBase): + + def __init__(self): + self._api_common = Common() + + # Init cpld reg path + self.setreg_path = os.path.join(PLATFORM_CPLD_PATH, SETREG_FILE) + self.getreg_path = os.path.join(PLATFORM_CPLD_PATH, GETREG_FILE) + + # Set default value + self._disable() + self.armed = False + self.timeout = self._gettimeout() + + def _enable(self): + """ + Turn on the watchdog timer + """ + # echo 0xA181 0x1 > /sys/devices/platform/baseboard/setreg + enable_val = '{} {}'.format(WDT_ENABLE_REG, ENABLE_CMD) + return self._api_common.write_txt_file(self.setreg_path, enable_val) + + def _disable(self): + """ + Turn off the watchdog timer + """ + # echo 0xA181 0x0 > /sys/devices/platform/baseboard/setreg + disable_val = '{} {}'.format(WDT_ENABLE_REG, DISABLE_CMD) + return self._api_common.write_txt_file(self.setreg_path, disable_val) + + def _keepalive(self): + """ + Keep alive watchdog timer + """ + # echo 0xA185 0x1 > /sys/devices/platform/baseboard/setreg + enable_val = '{} {}'.format(WDT_KEEP_ALVIVE_REG, ENABLE_CMD) + return self._api_common.write_txt_file(self.setreg_path, enable_val) + + def _get_level_hex(self, sub_hex): + sub_hex_str = sub_hex.replace("x", "0") + return hex(int(sub_hex_str, 16)) + + def _seconds_to_lmh_hex(self, seconds): + ms = seconds*1000 # calculate timeout in ms format + hex_str = hex(ms) + l = self._get_level_hex(hex_str[-2:]) + m = self._get_level_hex(hex_str[-4:-2]) + h = self._get_level_hex(hex_str[-6:-4]) + return (l, m, h) + + def _settimeout(self, seconds): + """ + Set watchdog timer timeout + @param seconds - timeout in seconds + @return is the actual set timeout + """ + # max = 0xffffff = 16777.215 seconds + + (l, m, h) = self._seconds_to_lmh_hex(seconds) + set_h_val = '{} {}'.format(WDT_TIMER_H_BIT_REG, h) + set_m_val = '{} {}'.format(WDT_TIMER_M_BIT_REG, m) + set_l_val = '{} {}'.format(WDT_TIMER_L_BIT_REG, l) + + self._api_common.write_txt_file( + self.setreg_path, set_h_val) # set high bit + self._api_common.write_txt_file( + self.setreg_path, set_m_val) # set med bit + self._api_common.write_txt_file( + self.setreg_path, set_l_val) # set low bit + + return seconds + + def _gettimeout(self): + """ + Get watchdog timeout + @return watchdog timeout + """ + + h_bit = self._api_common.get_reg( + self.getreg_path, WDT_TIMER_H_BIT_REG) + m_bit = self._api_common.get_reg( + self.getreg_path, WDT_TIMER_M_BIT_REG) + l_bit = self._api_common.get_reg( + self.getreg_path, WDT_TIMER_L_BIT_REG) + + hex_time = '0x{}{}{}'.format(h_bit[2:], m_bit[2:], l_bit[2:]) + ms = int(hex_time, 16) + return int(float(ms)/1000) + + ################################################################# + + def arm(self, seconds): + """ + Arm the hardware watchdog with a timeout of seconds. + If the watchdog is currently armed, calling this function will + simply reset the timer to the provided value. If the underlying + hardware does not support the value provided in , this + method should arm the watchdog with the *next greater* available + value. + Returns: + An integer specifying the *actual* number of seconds the watchdog + was armed with. On failure returns -1. + """ + + ret = WDT_COMMON_ERROR + if seconds < 0: + return ret + + try: + if self.timeout != seconds: + self.timeout = self._settimeout(seconds) + + if self.armed: + self._keepalive() + else: + self._enable() + self.armed = True + + ret = self.timeout + self.arm_timestamp = time.time() + except IOError as e: + pass + + return ret + + def disarm(self): + """ + Disarm the hardware watchdog + Returns: + A boolean, True if watchdog is disarmed successfully, False if not + """ + disarmed = False + if self.is_armed(): + try: + self._disable() + self.armed = False + disarmed = True + except IOError: + pass + + return disarmed + + def is_armed(self): + """ + Retrieves the armed state of the hardware watchdog. + Returns: + A boolean, True if watchdog is armed, False if not + """ + + return self.armed + + def get_remaining_time(self): + """ + If the watchdog is armed, retrieve the number of seconds remaining on + the watchdog timer + Returns: + An integer specifying the number of seconds remaining on thei + watchdog timer. If the watchdog is not armed, returns -1. + """ + + return int(self.timeout - (time.time() - self.arm_timestamp)) if self.armed else WDT_COMMON_ERROR diff --git a/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/sai.profile b/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/sai.profile index bc7681f0272f..483e85c0c1fa 100644 --- a/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/sai.profile +++ b/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-128x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/celestica/x86_64-cel_silverstone-r0/Silverstone/sai.profile b/device/celestica/x86_64-cel_silverstone-r0/Silverstone/sai.profile index 1915eb9b35a1..550bfe181df4 100644 --- a/device/celestica/x86_64-cel_silverstone-r0/Silverstone/sai.profile +++ b/device/celestica/x86_64-cel_silverstone-r0/Silverstone/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-32x400G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/celestica/x86_64-cel_silverstone-r0/led_proc_init.soc b/device/celestica/x86_64-cel_silverstone-r0/led_proc_init.soc index 827458afefbe..3a8ac119076e 100644 --- a/device/celestica/x86_64-cel_silverstone-r0/led_proc_init.soc +++ b/device/celestica/x86_64-cel_silverstone-r0/led_proc_init.soc @@ -1,2 +1,7 @@ #The Port LED of Silverstone SONIC can't work well, after the issue is fixed by SAI, The led will start. #led auto on; led start +linkscan off +m0 load 0 0x3800 /usr/share/sonic/platform/custom.bin +sleep 10 +led auto on; led start +linkscan on diff --git a/device/celestica/x86_64-cel_silverstone-r0/plugins/eeprom.py b/device/celestica/x86_64-cel_silverstone-r0/plugins/eeprom.py index 34c50a6ce31f..012196b0dd4c 100644 --- a/device/celestica/x86_64-cel_silverstone-r0/plugins/eeprom.py +++ b/device/celestica/x86_64-cel_silverstone-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Celestica Silverstone # @@ -11,8 +9,8 @@ try: from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): @@ -20,4 +18,3 @@ class board(eeprom_tlvinfo.TlvInfoDecoder): def __init__(self, name, path, cpld_root, ro): self.eeprom_path = "/sys/class/i2c-adapter/i2c-0/0-0056/eeprom" super(board, self).__init__(self.eeprom_path, 0, '', True) - diff --git a/device/celestica/x86_64-cel_silverstone-r0/plugins/psuutil.py b/device/celestica/x86_64-cel_silverstone-r0/plugins/psuutil.py index d5e197e82d2b..ca75ad98334c 100644 --- a/device/celestica/x86_64-cel_silverstone-r0/plugins/psuutil.py +++ b/device/celestica/x86_64-cel_silverstone-r0/plugins/psuutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - import os.path import subprocess import sys @@ -8,7 +6,7 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") class PsuUtil(PsuBase): @@ -21,21 +19,21 @@ def __init__(self): PsuBase.__init__(self) def run_command(self, command): - proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) + proc = subprocess.Popen(command, shell=True, universal_newlines=True, stdout=subprocess.PIPE) (out, err) = proc.communicate() if proc.returncode != 0: sys.exit(proc.returncode) - + return out - + def find_value(self, in_string): result = re.search("^.+ ([0-9a-f]{2}) .+$", in_string) if result: return result.group(1) else: return result - + def get_num_psus(self): """ Retrieves the number of PSUs available on the device @@ -56,7 +54,7 @@ def get_psu_status(self, index): psu_id = self.psu1_id if index == 1 else self.psu2_id res_string = self.run_command(self.ipmi_raw + ' ' + psu_id) status_byte = self.find_value(res_string) - + if status_byte is None: return False @@ -80,12 +78,12 @@ def get_psu_presence(self, index): psu_id = self.psu1_id if index == 1 else self.psu2_id res_string = self.run_command(self.ipmi_raw + ' ' + psu_id) status_byte = self.find_value(res_string) - + if status_byte is None: return False - - presence = ( int(status_byte, 16) >> 0 ) & 1 + + presence = (int(status_byte, 16) >> 0) & 1 if presence: return True else: - return False \ No newline at end of file + return False diff --git a/device/celestica/x86_64-cel_silverstone-r0/plugins/sfputil.py b/device/celestica/x86_64-cel_silverstone-r0/plugins/sfputil.py index 33b761b9397a..c089b42c3638 100755 --- a/device/celestica/x86_64-cel_silverstone-r0/plugins/sfputil.py +++ b/device/celestica/x86_64-cel_silverstone-r0/plugins/sfputil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python -# # Platform-specific SFP transceiver interface for SONiC # This plugin supports QSFP-DD, QSFP and SFP. @@ -41,7 +39,7 @@ def qsfp_ports(self): @property def osfp_ports(self): - return range(self.OSFP_PORT_START, self.OSFP_PORT_END + 1) + return list(range(self.OSFP_PORT_START, self.OSFP_PORT_END + 1)) @property def port_to_eeprom_mapping(self): @@ -78,7 +76,7 @@ def __init__(self): def get_presence(self, port_num): # Check for invalid port_num - if port_num not in range(self.port_start, self.port_end + 1): + if port_num not in list(range(self.port_start, self.port_end + 1)): return False # Get path for access port presence status @@ -92,7 +90,7 @@ def get_presence(self, port_num): content = reg_file.readline().rstrip() reg_value = int(content) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False # Module present is active low @@ -111,7 +109,7 @@ def get_low_power_mode(self, port_num): reg_file = open("/".join([self.PORT_INFO_PATH, port_name, "qsfp_lpmode"])) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False # Read status @@ -133,7 +131,7 @@ def set_low_power_mode(self, port_num, lpmode): reg_file = open("/".join([self.PORT_INFO_PATH, port_name, "qsfp_lpmode"]), "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = hex(lpmode) @@ -154,7 +152,7 @@ def reset(self, port_num): reg_file = open("/".join([self.PORT_INFO_PATH, port_name, "qsfp_reset"]), "w") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False # Convert our register value back to a hex string and write back @@ -170,7 +168,7 @@ def reset(self, port_num): reg_file = open( "/".join([self.PORT_INFO_PATH, port_name, "qsfp_reset"]), "w") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_file.seek(0) diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/chassis.py index b4e2760d0ce9..b6f77cbd3dc9 100644 --- a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/chassis.py +++ b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/chassis.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Celestica # @@ -22,7 +20,7 @@ from sonic_platform.sfp import Sfp from sonic_platform.psu import Psu from sonic_platform.thermal import Thermal - from helper import APIHelper + from .helper import APIHelper except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -65,7 +63,6 @@ def __init__(self): thermal = Thermal(index) self._thermal_list.append(thermal) - def get_base_mac(self): """ Retrieves the base MAC address for the chassis @@ -75,7 +72,7 @@ def get_base_mac(self): """ return self._eeprom.get_mac() - def get_serial_number(self): + def get_serial(self): """ Retrieves the hardware serial number for the chassis Returns: diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/component.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/component.py index 737908b5b50e..bbbb9f1d458d 100644 --- a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/component.py +++ b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/component.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Celestica # @@ -13,7 +11,7 @@ try: from sonic_platform_base.component_base import ComponentBase - from helper import APIHelper + from .helper import APIHelper except ImportError as e: raise ImportError(str(e) + "- required module not found") diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/eeprom.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/eeprom.py index dd0c9332b54e..cf3f1a98de20 100644 --- a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/eeprom.py +++ b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Celestica Silverstone # @@ -13,13 +11,17 @@ import glob import os import sys - import imp import re from array import array - from cStringIO import StringIO + + if sys.version_info.major == 3: + from io import StringIO + else: + from cStringIO import StringIO + from sonic_platform_base.sonic_eeprom import eeprom_dts from sonic_platform_base.sonic_eeprom import eeprom_tlvinfo -except ImportError, e: +except ImportError as e: raise ImportError(str(e) + "- required module not found") CACHE_ROOT = '/var/cache/sonic/decode-syseeprom' @@ -27,12 +29,14 @@ TLV_EEPROM_I2C_BUS = 0 TLV_EEPROM_I2C_ADDR = 56 + class Tlv(eeprom_tlvinfo.TlvInfoDecoder): EEPROM_DECODE_HEADLINES = 6 def __init__(self): - self._eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-00{1}/eeprom".format(TLV_EEPROM_I2C_BUS, TLV_EEPROM_I2C_ADDR) + self._eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-00{1}/eeprom".format( + TLV_EEPROM_I2C_BUS, TLV_EEPROM_I2C_ADDR) super(Tlv, self).__init__(self._eeprom_path, 0, '', True) self._eeprom = self._load_eeprom() diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/fan.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/fan.py index d1b36effc1ac..1055aee68fc7 100644 --- a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/fan.py +++ b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/fan.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Celestica # @@ -14,7 +12,7 @@ try: from sonic_platform_base.fan_base import FanBase - from helper import APIHelper + from .helper import APIHelper except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -150,7 +148,7 @@ def set_speed(self, speed): # register = 22 32 42 52 62 72 82 if self.is_psu_fan: - ## TODO + # TODO return False speed_hex = hex(int(float(speed)/100 * 255)) diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/helper.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/helper.py index 82f0eea6b448..144d9e154348 100644 --- a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/helper.py +++ b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/helper.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - import os import struct import subprocess @@ -35,7 +33,7 @@ def run_command(self, cmd): result = "" try: p = subprocess.Popen( - cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) raw_data, err = p.communicate() if err == '': result = raw_data.strip() @@ -65,7 +63,7 @@ def ipmi_raw(self, netfn, cmd): try: cmd = "ipmitool raw {} {}".format(str(netfn), str(cmd)) p = subprocess.Popen( - cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) raw_data, err = p.communicate() if err == '': result = raw_data.strip() @@ -83,7 +81,7 @@ def ipmi_fru_id(self, id, key=None): id)) if not key else "ipmitool fru print {0} | grep '{1}' ".format(str(id), str(key)) p = subprocess.Popen( - cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) raw_data, err = p.communicate() if err == '': result = raw_data.strip() @@ -99,7 +97,7 @@ def ipmi_set_ss_thres(self, id, threshold_key, value): try: cmd = "ipmitool sensor thresh '{}' {} {}".format(str(id), str(threshold_key), str(value)) p = subprocess.Popen( - cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) raw_data, err = p.communicate() if err == '': result = raw_data.strip() diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/platform.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/platform.py index a632de87e742..7d98ec9f7cdf 100644 --- a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/platform.py +++ b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/platform.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Celestica # diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/psu.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/psu.py index c5d2270d2657..9ad0f1dc9392 100644 --- a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/psu.py +++ b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/psu.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Celestica # @@ -15,7 +13,7 @@ try: from sonic_platform_base.psu_base import PsuBase - from helper import APIHelper + from .helper import APIHelper from sonic_platform.fan import Fan except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -238,6 +236,6 @@ def get_status(self): if status: failure_detected = (int(status_byte, 16) >> 1) & 1 input_lost = (int(status_byte, 16) >> 3) & 1 - psu_status = False if (input_lost or failure_detected) else True + psu_status = False if (input_lost or failure_detected) else True return psu_status diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/sfp.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/sfp.py index d0d0f59cd10d..e909416e9081 100644 --- a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/sfp.py +++ b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/sfp.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Celestica # @@ -11,7 +9,6 @@ import os import time import subprocess -import sonic_device_util from ctypes import create_string_buffer try: @@ -228,7 +225,7 @@ def __init__(self, sfp_index): port_eeprom_path = eeprom_path.format(self.port_to_i2c_mapping[x]) self.port_to_eeprom_mapping[x] = port_eeprom_path - self.info_dict_keys = ['type', 'hardwarerev', 'serialnum', 'manufacturename', 'modelname', 'Connector', 'encoding', 'ext_identifier', + self.info_dict_keys = ['type', 'hardware_rev', 'serial', 'manufacturer', 'model', 'connector', 'encoding', 'ext_identifier', 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance', 'vendor_date', 'vendor_oui'] self.dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', 'temperature', 'voltage', @@ -331,7 +328,7 @@ def _dom_capability_detect(self): QSFP_VERSION_COMPLIANCE_OFFSET, QSFP_VERSION_COMPLIANCE_WIDTH) qsfp_version_compliance = int( qsfp_version_compliance_raw[0], 16) - dom_capability = sfpi_obj.parse_qsfp_dom_capability( + dom_capability = sfpi_obj.parse_dom_capability( qsfp_dom_capability_raw, 0) if qsfp_version_compliance >= 0x08: self.dom_temp_supported = dom_capability['data']['Temp_support']['value'] == 'On' @@ -412,11 +409,11 @@ def get_transceiver_info(self): keys |Value Format |Information ---------------------------|---------------|---------------------------- type |1*255VCHAR |type of SFP - hardwarerev |1*255VCHAR |hardware version of SFP - serialnum |1*255VCHAR |serial number of the SFP - manufacturename |1*255VCHAR |SFP vendor name - modelname |1*255VCHAR |SFP model name - Connector |1*255VCHAR |connector information + hardware_rev |1*255VCHAR |hardware version of SFP + serial |1*255VCHAR |serial number of the SFP + manufacturer |1*255VCHAR |SFP vendor name + model |1*255VCHAR |SFP model name + connector |1*255VCHAR |connector information encoding |1*255VCHAR |encoding information ext_identifier |1*255VCHAR |extend identifier ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance @@ -483,13 +480,13 @@ def get_transceiver_info(self): return None transceiver_info_dict['type'] = sfp_type_data['data']['type']['value'] - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] transceiver_info_dict['vendor_oui'] = 'N/A' transceiver_info_dict['vendor_date'] = 'N/A' - transceiver_info_dict['Connector'] = 'N/A' + transceiver_info_dict['connector'] = 'N/A' transceiver_info_dict['encoding'] = 'N/A' transceiver_info_dict['ext_identifier'] = 'N/A' transceiver_info_dict['ext_rateselect_compliance'] = 'N/A' @@ -562,14 +559,14 @@ def get_transceiver_info(self): sfp_vendor_date_data = sfpi_obj.parse_vendor_date( sfp_interface_bulk_raw[start: end], 0) transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] transceiver_info_dict['vendor_date'] = sfp_vendor_date_data[ 'data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] - transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] @@ -1447,7 +1444,7 @@ def get_model(self): string: Model/part number of device """ transceiver_dom_info_dict = self.get_transceiver_info() - return transceiver_dom_info_dict.get("modelname", "N/A") + return transceiver_dom_info_dict.get("model", "N/A") def get_serial(self): """ @@ -1456,7 +1453,7 @@ def get_serial(self): string: Serial number of device """ transceiver_dom_info_dict = self.get_transceiver_info() - return transceiver_dom_info_dict.get("serialnum", "N/A") + return transceiver_dom_info_dict.get("serial", "N/A") def get_status(self): """ diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/thermal.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/thermal.py index e3138e6bb897..9ecf12218d50 100644 --- a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/thermal.py +++ b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/thermal.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Celestica # @@ -14,7 +12,7 @@ try: from sonic_platform_base.thermal_base import ThermalBase - from helper import APIHelper + from .helper import APIHelper except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -47,20 +45,21 @@ def __init__(self, thermal_index): self.sensor_id = self.THERMAL_LIST[self.index][0] self.sensor_des = self.THERMAL_LIST[self.index][1] self.sensor_reading_addr = self.THERMAL_LIST[self.index][2] + def __set_threshold(self, key, value): - print(key, value) + print('{} {}'.format(key, value)) def get_temperature(self): """ Retrieves current temperature reading from thermal Returns: A float number of current temperature in Celsius up to nearest thousandth - of one degree Celsius, e.g. 30.125 + of one degree Celsius, e.g. 30.125 """ temperature = 0.0 status, raw_ss_read = self._api_helper.ipmi_raw( IPMI_SENSOR_NETFN, IPMI_SS_READ_CMD.format(self.sensor_reading_addr)) - if status and len(raw_ss_read.split()) > 0: + if status and len(raw_ss_read.split()) > 0: ss_read = raw_ss_read.split()[0] temperature = float(int(ss_read, 16)) return temperature @@ -75,7 +74,7 @@ def get_high_threshold(self): high_threshold = 0.0 status, raw_up_thres_read = self._api_helper.ipmi_raw( IPMI_SENSOR_NETFN, IPMI_SS_THRESHOLD_CMD.format(self.sensor_reading_addr)) - if status and len(raw_up_thres_read.split()) > 6: + if status and len(raw_up_thres_read.split()) > 6: ss_read = raw_up_thres_read.split()[4] high_threshold = float(int(ss_read, 16)) return high_threshold @@ -92,8 +91,8 @@ def get_low_threshold(self): def set_high_threshold(self, temperature): """ Sets the high threshold temperature of thermal - Args : - temperature: A float number up to nearest thousandth of one degree Celsius, + Args : + temperature: A float number up to nearest thousandth of one degree Celsius, e.g. 30.125 Returns: A boolean, True if threshold is set successfully, False if not @@ -104,7 +103,7 @@ def set_high_threshold(self, temperature): def set_low_threshold(self, temperature): """ Sets the low threshold temperature of thermal - Args : + Args : temperature: A float number up to nearest thousandth of one degree Celsius, e.g. 30.125 Returns: @@ -150,4 +149,4 @@ def get_status(self): Returns: A boolean value, True if device is operating properly, False if not """ - return self.get_presence() \ No newline at end of file + return self.get_presence() diff --git a/device/centec/arm64-centec_e530_24x2c-r0/E530-24x2c/buffers.json.j2 b/device/centec/arm64-centec_e530_24x2c-r0/E530-24x2c/buffers.json.j2 new file mode 100644 index 000000000000..08e21e428b6c --- /dev/null +++ b/device/centec/arm64-centec_e530_24x2c-r0/E530-24x2c/buffers.json.j2 @@ -0,0 +1,70 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '40m' %} +{% set default_ports_num = 54 -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) -%} + {%- set cable_len = [] -%} + {%- for local_port in DEVICE_NEIGHBOR -%} + {%- if local_port == port_name -%} + {%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor_role = neighbor.type -%} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role -%} + {%- set roles1 = roles1 | lower -%} + {%- set roles2 = roles2 | lower -%} + {%- if roles1 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%} + {%- elif roles2 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endfor -%} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif -%} +{% endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(1,default_ports_num+1) %} + {% if PORT.append("Ethernet%d" % (port_idx)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "CABLE_LENGTH": { + "AZURE": { + {% for port in PORT %} + {% set cable = cable_length(port) -%} + "{{ port }}": "{{ cable }}"{%- if not loop.last -%},{% endif %} + + {% endfor %} + } + } +} + diff --git a/device/centec/arm64-centec_e530_24x2c-r0/E530-24x2c/pg_profile_lookup.ini b/device/centec/arm64-centec_e530_24x2c-r0/E530-24x2c/pg_profile_lookup.ini new file mode 100644 index 000000000000..a65244e69b5b --- /dev/null +++ b/device/centec/arm64-centec_e530_24x2c-r0/E530-24x2c/pg_profile_lookup.ini @@ -0,0 +1,21 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 1000 5m 34816 18432 16384 0 + 10000 5m 34816 18432 16384 0 + 25000 5m 34816 18432 16384 0 + 40000 5m 34816 18432 16384 0 + 50000 5m 34816 18432 16384 0 + 100000 5m 36864 18432 18432 0 + 1000 40m 36864 18432 18432 0 + 10000 40m 36864 18432 18432 0 + 25000 40m 39936 18432 21504 0 + 40000 40m 41984 18432 23552 0 + 50000 40m 41984 18432 23552 0 + 100000 40m 54272 18432 35840 0 + 1000 300m 49152 18432 30720 0 + 10000 300m 49152 18432 30720 0 + 25000 300m 71680 18432 53248 0 + 40000 300m 94208 18432 75776 0 + 50000 300m 94208 18432 75776 0 + 100000 300m 184320 18432 165888 0 + diff --git a/device/centec/arm64-centec_e530_24x2c-r0/E530-24x2c/port_config.ini b/device/centec/arm64-centec_e530_24x2c-r0/E530-24x2c/port_config.ini new file mode 100644 index 000000000000..27d43a0abd0d --- /dev/null +++ b/device/centec/arm64-centec_e530_24x2c-r0/E530-24x2c/port_config.ini @@ -0,0 +1,27 @@ +# name lanes alias speed +Ethernet1 0 eth-0-1 10000 +Ethernet2 1 eth-0-2 10000 +Ethernet3 2 eth-0-3 10000 +Ethernet4 3 eth-0-4 10000 +Ethernet5 8 eth-0-5 10000 +Ethernet6 9 eth-0-6 10000 +Ethernet7 10 eth-0-7 10000 +Ethernet8 11 eth-0-8 10000 +Ethernet9 20 eth-0-9 10000 +Ethernet10 21 eth-0-10 10000 +Ethernet11 22 eth-0-11 10000 +Ethernet12 23 eth-0-12 10000 +Ethernet13 12 eth-0-13 10000 +Ethernet14 13 eth-0-14 10000 +Ethernet15 14 eth-0-15 10000 +Ethernet16 15 eth-0-16 10000 +Ethernet17 24 eth-0-17 10000 +Ethernet18 25 eth-0-18 10000 +Ethernet19 26 eth-0-19 10000 +Ethernet20 27 eth-0-20 10000 +Ethernet21 28 eth-0-21 10000 +Ethernet22 29 eth-0-22 10000 +Ethernet23 30 eth-0-23 10000 +Ethernet24 31 eth-0-24 10000 +Ethernet25 61,60,63,62 eth-0-25 100000 +Ethernet26 45,44,47,46 eth-0-26 100000 diff --git a/device/centec/arm64-centec_e530_24x2c-r0/E530-24x2c/qos.json.j2 b/device/centec/arm64-centec_e530_24x2c-r0/E530-24x2c/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/centec/arm64-centec_e530_24x2c-r0/E530-24x2c/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/centec/arm64-centec_e530_24x2c-r0/E530-24x2c/sai.profile b/device/centec/arm64-centec_e530_24x2c-r0/E530-24x2c/sai.profile new file mode 100644 index 000000000000..09efce07c613 --- /dev/null +++ b/device/centec/arm64-centec_e530_24x2c-r0/E530-24x2c/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/etc/centec/E530-24x2c-chip-profile.txt +SAI_HW_PORT_PROFILE_ID_CONFIG_FILE=/etc/centec/E530-24x2c-datapath-cfg.txt diff --git a/device/centec/arm64-centec_e530_24x2c-r0/default_sku b/device/centec/arm64-centec_e530_24x2c-r0/default_sku new file mode 100644 index 000000000000..c714e6c18dbb --- /dev/null +++ b/device/centec/arm64-centec_e530_24x2c-r0/default_sku @@ -0,0 +1 @@ +E530-24x2c l2 diff --git a/device/centec/arm64-centec_e530_24x2c-r0/fancontrol b/device/centec/arm64-centec_e530_24x2c-r0/fancontrol new file mode 100644 index 000000000000..e3775297128e --- /dev/null +++ b/device/centec/arm64-centec_e530_24x2c-r0/fancontrol @@ -0,0 +1 @@ +# Configuration file generated by pwmconfig, changes will be lost diff --git a/device/centec/arm64-centec_e530_24x2c-r0/installer.conf b/device/centec/arm64-centec_e530_24x2c-r0/installer.conf new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/device/centec/arm64-centec_e530_24x2c-r0/plugins/eeprom.py b/device/centec/arm64-centec_e530_24x2c-r0/plugins/eeprom.py new file mode 100644 index 000000000000..afea818be079 --- /dev/null +++ b/device/centec/arm64-centec_e530_24x2c-r0/plugins/eeprom.py @@ -0,0 +1,20 @@ +############################################################################# +# Centec E550-24X8Y2C +# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# + +try: + from sonic_eeprom import eeprom_tlvinfo +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/dev/mtd3" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/centec/arm64-centec_e530_24x2c-r0/plugins/led_control.py b/device/centec/arm64-centec_e530_24x2c-r0/plugins/led_control.py new file mode 100644 index 000000000000..627cf03ddad4 --- /dev/null +++ b/device/centec/arm64-centec_e530_24x2c-r0/plugins/led_control.py @@ -0,0 +1,96 @@ +# +# led_control.py +# +# Platform-specific LED control functionality for SONiC +# + +try: + from sonic_led.led_control_base import LedControlBase + import syslog + from socket import * + from select import * +except ImportError as e: + raise ImportError(str(e) + " - required module not found") + + +def DBG_PRINT(str): + syslog.openlog("centec-led") + syslog.syslog(syslog.LOG_INFO, str) + syslog.closelog() + + +class LedControl(LedControlBase): + """Platform specific LED control class""" + + # Helper method to map SONiC port name to index + def _port_name_to_index(self, port_name): + # Strip "Ethernet" off port name + if not port_name.startswith(self.SONIC_PORT_NAME_PREFIX): + return -1 + + port_idx = int(port_name[len(self.SONIC_PORT_NAME_PREFIX):]) + return port_idx + + def _port_state_to_mode(self, port_idx, state): + if state == "up": + return self.LED_MODE_UP[0] if (port_idx < 25) else self.LED_MODE_UP[1] + else: + return self.LED_MODE_DOWN[0] if (port_idx < 25) else self.LED_MODE_DOWN[1] + + def _port_led_mode_update(self, port_idx, ledMode): + with open(self.f_led.format("port{}".format(port_idx)), 'w') as led_file: + led_file.write(str(ledMode)) + + def _initSystemLed(self): + try: + with open(self.f_led.format("system"), 'w') as led_file: + led_file.write("1") + DBG_PRINT("init system led to normal") + with open(self.f_led.format("idn"), 'w') as led_file: + led_file.write("1") + DBG_PRINT("init idn led to off") + except IOError as e: + DBG_PRINT(str(e)) + + def _initPanelLed(self): + with open(self.f_led.format("port1"), 'r') as led_file: + shouldInit = (int(led_file.read()) == 0) + + if shouldInit == True: + for idx in range(1, 27): + defmode = self._port_state_to_mode(idx, "down") + with open(self.f_led.format("port{}".format(idx)), 'w') as led_file: + led_file.write(str(defmode)) + DBG_PRINT("init port{} led to mode={}".format(idx, defmode)) + + def _initDefaultConfig(self): + DBG_PRINT("start init led") + + self._initSystemLed() + self._initPanelLed() + + DBG_PRINT("init led done") + + # Concrete implementation of port_link_state_change() method + + def port_link_state_change(self, portname, state): + port_idx = self._port_name_to_index(portname) + ledMode = self._port_state_to_mode(port_idx, state) + with open(self.f_led.format("port{}".format(port_idx)), 'r') as led_file: + saveMode = int(led_file.read()) + + if ledMode == saveMode: + return + + self._port_led_mode_update(port_idx, ledMode) + DBG_PRINT("update {} led mode from {} to {}".format(portname, saveMode, ledMode)) + + # Constructor + + def __init__(self): + self.SONIC_PORT_NAME_PREFIX = "Ethernet" + self.LED_MODE_UP = [11, 11] + self.LED_MODE_DOWN = [7, 7] + + self.f_led = "/sys/class/leds/{}/brightness" + self._initDefaultConfig() diff --git a/device/centec/arm64-centec_e530_24x2c-r0/plugins/psuutil.py b/device/centec/arm64-centec_e530_24x2c-r0/plugins/psuutil.py new file mode 100644 index 000000000000..3a83f406d990 --- /dev/null +++ b/device/centec/arm64-centec_e530_24x2c-r0/plugins/psuutil.py @@ -0,0 +1,71 @@ +############################################################################# +# Centec +# +# Module contains an implementation of SONiC PSU Base API and +# provides the PSUs status which are available in the platform +# +############################################################################# + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + PsuBase.__init__(self) + + self.psu_path = "/sys/class/psu/psu{}/" + self.psu_presence = "psu_presence" + self.psu_oper_status = "psu_status" + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + + :return: An integer, the number of PSUs available on the device + """ + return 2 + + def get_psu_status(self, index): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by 1-based index + + :param index: An integer, 1-based index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is faulty + """ + if index is None: + return False + + status = 0 + try: + with open(self.psu_path.format(index) + self.psu_oper_status, 'r') as power_status: + status = int(power_status.read()) + except IOError: + return False + + return status == 1 + + def get_psu_presence(self, index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by 1-based index + + :param index: An integer, 1-based index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + if index is None: + return False + + status = 0 + try: + with open(self.psu_path.format(index) + self.psu_presence, 'r') as presence_status: + status = int(presence_status.read()) + except IOError: + return False + + return status == 1 diff --git a/device/centec/arm64-centec_e530_24x2c-r0/plugins/sfputil.py b/device/centec/arm64-centec_e530_24x2c-r0/plugins/sfputil.py new file mode 100644 index 000000000000..c5c0dc8e16e0 --- /dev/null +++ b/device/centec/arm64-centec_e530_24x2c-r0/plugins/sfputil.py @@ -0,0 +1,163 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# + +try: + import time + from socket import * + from select import * + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + + +def DBG_PRINT(str): + print(str + "\n") + + +SFP_STATUS_INSERTED = '1' +SFP_STATUS_REMOVED = '0' + + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + @property + def port_start(self): + return self.PORT_START + + @property + def port_end(self): + return self.PORT_END + + @property + def sfp_base(self): + return self.SFP_BASE + + @property + def qsfp_ports(self): + return list(range(25, self.PORTS_IN_BLOCK + 1)) + + @property + def port_to_eeprom_mapping(self): + return self.eeprom_mapping + + def is_logical_port(self, port_name): + return True + + def get_eeprom_data(self, port): + ret = None + port_num = self.get_logical_to_physical(port)[0] + if port_num < self.port_start or port_num > self.port_end: + return ret + if port_num < self.sfp_base: + return ret + try: + with open(self.eeprom_mapping[port_num], 'r') as eeprom_file: + ret = eeprom_file.read() + except IOError as e: + DBG_PRINT(str(e)) + + return ret + + # todo + # def _get_port_eeprom_path(self, port_num, devid): + # pass + + def __init__(self): + self.SONIC_PORT_NAME_PREFIX = "Ethernet" + self.PORT_START = 1 + self.PORT_END = 26 + self.SFP_BASE = 1 + self.PORTS_IN_BLOCK = 26 + self.logical = [] + self.physical_to_logical = {} + self.logical_to_physical = {} + + self.eeprom_mapping = {} + self.f_sfp_present = "/sys/class/sfp/sfp{}/sfp_presence" + self.f_sfp_enable = "/sys/class/sfp/sfp{}/sfp_enable" + for x in range(self.port_start, self.sfp_base): + self.eeprom_mapping[x] = None + for x in range(self.sfp_base, self.port_end + 1): + self.eeprom_mapping[x] = "/sys/class/sfp/sfp{}/sfp_eeprom".format( + x - self.sfp_base + 1) + self.presence = {} + for x in range(self.sfp_base, self.port_end + 1): + self.presence[x] = False + + SfpUtilBase.__init__(self) + + for x in range(self.sfp_base, self.port_end + 1): + self.logical.append('Ethernet' + str(x)) + + 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 + if port_num < self.sfp_base: + return False + try: + with open(self.f_sfp_present.format(port_num - self.sfp_base + 1), 'r') as sfp_file: + return 1 == int(sfp_file.read()) + except IOError as e: + DBG_PRINT(str(e)) + + return False + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + return False + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + return False + + def reset(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + return False + + def read_porttab_mappings(self, porttabfile): + for x in range(self.sfp_base, self.port_end + 1): + self.logical_to_physical['Ethernet' + str(x)] = [x] + self.physical_to_logical[x] = ['Ethernet' + str(x)] + + data = {'valid': 0, 'last': 0} + + def get_transceiver_change_event(self, timeout=2000): + now = time.time() + port_dict = {} + + if timeout < 1000: + timeout = 1000 + timeout = (timeout) / float(1000) # Convert to secs + + if now < (self.data['last'] + timeout) and self.data['valid']: + return True, {} + + for x in range(self.sfp_base, self.port_end + 1): + presence = self.get_presence(x) + if presence != self.presence[x]: + self.presence[x] = presence + if presence: + port_dict[x] = SFP_STATUS_INSERTED + else: + port_dict[x] = SFP_STATUS_REMOVED + + if bool(port_dict): + self.data['last'] = now + self.data['valid'] = 1 + return True, port_dict + else: + time.sleep(0.5) + return True, {} diff --git a/device/centec/arm64-centec_e530_48t4x_p-r0/E530-48t4x-p/buffers.json.j2 b/device/centec/arm64-centec_e530_48t4x_p-r0/E530-48t4x-p/buffers.json.j2 new file mode 100644 index 000000000000..08e21e428b6c --- /dev/null +++ b/device/centec/arm64-centec_e530_48t4x_p-r0/E530-48t4x-p/buffers.json.j2 @@ -0,0 +1,70 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '40m' %} +{% set default_ports_num = 54 -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) -%} + {%- set cable_len = [] -%} + {%- for local_port in DEVICE_NEIGHBOR -%} + {%- if local_port == port_name -%} + {%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor_role = neighbor.type -%} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role -%} + {%- set roles1 = roles1 | lower -%} + {%- set roles2 = roles2 | lower -%} + {%- if roles1 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%} + {%- elif roles2 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endfor -%} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif -%} +{% endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(1,default_ports_num+1) %} + {% if PORT.append("Ethernet%d" % (port_idx)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "CABLE_LENGTH": { + "AZURE": { + {% for port in PORT %} + {% set cable = cable_length(port) -%} + "{{ port }}": "{{ cable }}"{%- if not loop.last -%},{% endif %} + + {% endfor %} + } + } +} + diff --git a/device/centec/arm64-centec_e530_48t4x_p-r0/E530-48t4x-p/pg_profile_lookup.ini b/device/centec/arm64-centec_e530_48t4x_p-r0/E530-48t4x-p/pg_profile_lookup.ini new file mode 100644 index 000000000000..a65244e69b5b --- /dev/null +++ b/device/centec/arm64-centec_e530_48t4x_p-r0/E530-48t4x-p/pg_profile_lookup.ini @@ -0,0 +1,21 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 1000 5m 34816 18432 16384 0 + 10000 5m 34816 18432 16384 0 + 25000 5m 34816 18432 16384 0 + 40000 5m 34816 18432 16384 0 + 50000 5m 34816 18432 16384 0 + 100000 5m 36864 18432 18432 0 + 1000 40m 36864 18432 18432 0 + 10000 40m 36864 18432 18432 0 + 25000 40m 39936 18432 21504 0 + 40000 40m 41984 18432 23552 0 + 50000 40m 41984 18432 23552 0 + 100000 40m 54272 18432 35840 0 + 1000 300m 49152 18432 30720 0 + 10000 300m 49152 18432 30720 0 + 25000 300m 71680 18432 53248 0 + 40000 300m 94208 18432 75776 0 + 50000 300m 94208 18432 75776 0 + 100000 300m 184320 18432 165888 0 + diff --git a/device/centec/arm64-centec_e530_48t4x_p-r0/E530-48t4x-p/port_config.ini b/device/centec/arm64-centec_e530_48t4x_p-r0/E530-48t4x-p/port_config.ini new file mode 100644 index 000000000000..c904ece72ea0 --- /dev/null +++ b/device/centec/arm64-centec_e530_48t4x_p-r0/E530-48t4x-p/port_config.ini @@ -0,0 +1,53 @@ +# name lanes alias speed +Ethernet1 1 eth-0-1 1000 +Ethernet2 0 eth-0-2 1000 +Ethernet3 3 eth-0-3 1000 +Ethernet4 2 eth-0-4 1000 +Ethernet5 5 eth-0-5 1000 +Ethernet6 4 eth-0-6 1000 +Ethernet7 7 eth-0-7 1000 +Ethernet8 6 eth-0-8 1000 +Ethernet9 17 eth-0-9 1000 +Ethernet10 16 eth-0-10 1000 +Ethernet11 19 eth-0-11 1000 +Ethernet12 18 eth-0-12 1000 +Ethernet13 21 eth-0-13 1000 +Ethernet14 20 eth-0-14 1000 +Ethernet15 23 eth-0-15 1000 +Ethernet16 22 eth-0-16 1000 +Ethernet17 9 eth-0-17 1000 +Ethernet18 8 eth-0-18 1000 +Ethernet19 11 eth-0-19 1000 +Ethernet20 10 eth-0-20 1000 +Ethernet21 33 eth-0-21 1000 +Ethernet22 32 eth-0-22 1000 +Ethernet23 35 eth-0-23 1000 +Ethernet24 34 eth-0-24 1000 +Ethernet25 37 eth-0-25 1000 +Ethernet26 36 eth-0-26 1000 +Ethernet27 39 eth-0-27 1000 +Ethernet28 38 eth-0-28 1000 +Ethernet29 41 eth-0-29 1000 +Ethernet30 40 eth-0-30 1000 +Ethernet31 43 eth-0-31 1000 +Ethernet32 42 eth-0-32 1000 +Ethernet33 25 eth-0-33 1000 +Ethernet34 24 eth-0-34 1000 +Ethernet35 27 eth-0-35 1000 +Ethernet36 26 eth-0-36 1000 +Ethernet37 49 eth-0-37 1000 +Ethernet38 48 eth-0-38 1000 +Ethernet39 51 eth-0-39 1000 +Ethernet40 50 eth-0-40 1000 +Ethernet41 53 eth-0-41 1000 +Ethernet42 52 eth-0-42 1000 +Ethernet43 55 eth-0-43 1000 +Ethernet44 54 eth-0-44 1000 +Ethernet45 57 eth-0-45 1000 +Ethernet46 56 eth-0-46 1000 +Ethernet47 59 eth-0-47 1000 +Ethernet48 58 eth-0-48 1000 +Ethernet49 13 eth-0-49 10000 +Ethernet50 12 eth-0-50 10000 +Ethernet51 15 eth-0-51 10000 +Ethernet52 14 eth-0-52 10000 diff --git a/device/centec/arm64-centec_e530_48t4x_p-r0/E530-48t4x-p/qos.json.j2 b/device/centec/arm64-centec_e530_48t4x_p-r0/E530-48t4x-p/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/centec/arm64-centec_e530_48t4x_p-r0/E530-48t4x-p/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/centec/arm64-centec_e530_48t4x_p-r0/E530-48t4x-p/sai.profile b/device/centec/arm64-centec_e530_48t4x_p-r0/E530-48t4x-p/sai.profile new file mode 100644 index 000000000000..e026761f7b8a --- /dev/null +++ b/device/centec/arm64-centec_e530_48t4x_p-r0/E530-48t4x-p/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/etc/centec/E530-48t4x-p-chip-profile.txt +SAI_HW_PORT_PROFILE_ID_CONFIG_FILE=/etc/centec/E530-48t4x-p-datapath.txt diff --git a/device/centec/arm64-centec_e530_48t4x_p-r0/default_sku b/device/centec/arm64-centec_e530_48t4x_p-r0/default_sku new file mode 100644 index 000000000000..03b04aaf1b0d --- /dev/null +++ b/device/centec/arm64-centec_e530_48t4x_p-r0/default_sku @@ -0,0 +1 @@ +E530-48t4x-p l2 diff --git a/device/centec/arm64-centec_e530_48t4x_p-r0/fancontrol b/device/centec/arm64-centec_e530_48t4x_p-r0/fancontrol new file mode 100644 index 000000000000..e3775297128e --- /dev/null +++ b/device/centec/arm64-centec_e530_48t4x_p-r0/fancontrol @@ -0,0 +1 @@ +# Configuration file generated by pwmconfig, changes will be lost diff --git a/device/centec/arm64-centec_e530_48t4x_p-r0/installer.conf b/device/centec/arm64-centec_e530_48t4x_p-r0/installer.conf new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/device/centec/arm64-centec_e530_48t4x_p-r0/plugins/eeprom.py b/device/centec/arm64-centec_e530_48t4x_p-r0/plugins/eeprom.py new file mode 100644 index 000000000000..afea818be079 --- /dev/null +++ b/device/centec/arm64-centec_e530_48t4x_p-r0/plugins/eeprom.py @@ -0,0 +1,20 @@ +############################################################################# +# Centec E550-24X8Y2C +# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# + +try: + from sonic_eeprom import eeprom_tlvinfo +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/dev/mtd3" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/centec/arm64-centec_e530_48t4x_p-r0/plugins/led_control.py b/device/centec/arm64-centec_e530_48t4x_p-r0/plugins/led_control.py new file mode 100644 index 000000000000..eb567de89c22 --- /dev/null +++ b/device/centec/arm64-centec_e530_48t4x_p-r0/plugins/led_control.py @@ -0,0 +1,95 @@ +# led_control.py +# +# Platform-specific LED control functionality for SONiC +# + +try: + from sonic_led.led_control_base import LedControlBase + import syslog + from socket import * + from select import * +except ImportError as e: + raise ImportError(str(e) + " - required module not found") + + +def DBG_PRINT(str): + syslog.openlog("centec-led") + syslog.syslog(syslog.LOG_INFO, str) + syslog.closelog() + + +class LedControl(LedControlBase): + """Platform specific LED control class""" + + # Helper method to map SONiC port name to index + def _port_name_to_index(self, port_name): + # Strip "Ethernet" off port name + if not port_name.startswith(self.SONIC_PORT_NAME_PREFIX): + return -1 + + port_idx = int(port_name[len(self.SONIC_PORT_NAME_PREFIX):]) + return port_idx + + def _port_state_to_mode(self, port_idx, state): + if state == "up": + return self.LED_MODE_UP[0] if (port_idx < 49) else self.LED_MODE_UP[1] + else: + return self.LED_MODE_DOWN[0] if (port_idx < 49) else self.LED_MODE_DOWN[1] + + def _port_led_mode_update(self, port_idx, ledMode): + with open(self.f_led.format("port{}".format(port_idx)), 'w') as led_file: + led_file.write(str(ledMode)) + + def _initSystemLed(self): + try: + with open(self.f_led.format("system"), 'w') as led_file: + led_file.write("1") + DBG_PRINT("init system led to normal") + with open(self.f_led.format("idn"), 'w') as led_file: + led_file.write("1") + DBG_PRINT("init idn led to off") + except IOError as e: + DBG_PRINT(str(e)) + + def _initPanelLed(self): + with open(self.f_led.format("port1"), 'r') as led_file: + shouldInit = (int(led_file.read()) == 0) + + if shouldInit == True: + for idx in range(1, 53): + defmode = self._port_state_to_mode(idx, "down") + with open(self.f_led.format("port{}".format(idx)), 'w') as led_file: + led_file.write(str(defmode)) + DBG_PRINT("init port{} led to mode={}".format(idx, defmode)) + + def _initDefaultConfig(self): + DBG_PRINT("start init led") + + self._initSystemLed() + self._initPanelLed() + + DBG_PRINT("init led done") + + # Concrete implementation of port_link_state_change() method + + def port_link_state_change(self, portname, state): + port_idx = self._port_name_to_index(portname) + ledMode = self._port_state_to_mode(port_idx, state) + with open(self.f_led.format("port{}".format(port_idx)), 'r') as led_file: + saveMode = int(led_file.read()) + + if ledMode == saveMode: + return + + self._port_led_mode_update(port_idx, ledMode) + DBG_PRINT("update {} led mode from {} to {}".format(portname, saveMode, ledMode)) + + # Constructor + + def __init__(self): + self.SONIC_PORT_NAME_PREFIX = "Ethernet" + self.LED_MODE_UP = [2, 11] + self.LED_MODE_DOWN = [1, 7] + + self.f_led = "/sys/class/leds/{}/brightness" + self._initDefaultConfig() diff --git a/device/centec/arm64-centec_e530_48t4x_p-r0/plugins/psuutil.py b/device/centec/arm64-centec_e530_48t4x_p-r0/plugins/psuutil.py new file mode 100644 index 000000000000..3a83f406d990 --- /dev/null +++ b/device/centec/arm64-centec_e530_48t4x_p-r0/plugins/psuutil.py @@ -0,0 +1,71 @@ +############################################################################# +# Centec +# +# Module contains an implementation of SONiC PSU Base API and +# provides the PSUs status which are available in the platform +# +############################################################################# + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + PsuBase.__init__(self) + + self.psu_path = "/sys/class/psu/psu{}/" + self.psu_presence = "psu_presence" + self.psu_oper_status = "psu_status" + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + + :return: An integer, the number of PSUs available on the device + """ + return 2 + + def get_psu_status(self, index): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by 1-based index + + :param index: An integer, 1-based index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is faulty + """ + if index is None: + return False + + status = 0 + try: + with open(self.psu_path.format(index) + self.psu_oper_status, 'r') as power_status: + status = int(power_status.read()) + except IOError: + return False + + return status == 1 + + def get_psu_presence(self, index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by 1-based index + + :param index: An integer, 1-based index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + if index is None: + return False + + status = 0 + try: + with open(self.psu_path.format(index) + self.psu_presence, 'r') as presence_status: + status = int(presence_status.read()) + except IOError: + return False + + return status == 1 diff --git a/device/centec/arm64-centec_e530_48t4x_p-r0/plugins/sfputil.py b/device/centec/arm64-centec_e530_48t4x_p-r0/plugins/sfputil.py new file mode 100644 index 000000000000..f7094828eafb --- /dev/null +++ b/device/centec/arm64-centec_e530_48t4x_p-r0/plugins/sfputil.py @@ -0,0 +1,137 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# + +try: + import time + from socket import * + from select import * + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + + +def DBG_PRINT(str): + print(str + "\n") + + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + @property + def port_start(self): + return self.PORT_START + + @property + def port_end(self): + return self.PORT_END + + @property + def sfp_base(self): + return self.SFP_BASE + + @property + def qsfp_ports(self): + return () + + @property + def port_to_eeprom_mapping(self): + return self.eeprom_mapping + + def is_logical_port(self, port_name): + return True + + def get_logical_to_physical(self, port_name): + if not port_name.startswith(self.SONIC_PORT_NAME_PREFIX): + return None + + port_idx = int(port_name[len(self.SONIC_PORT_NAME_PREFIX):]) + + return [port_idx] + + def get_eeprom_data(self, port): + ret = None + port_num = self.get_logical_to_physical(port)[0] + if port_num < self.port_start or port_num > self.port_end: + return ret + if port_num < self.sfp_base: + return ret + try: + with open(self.eeprom_mapping[port_num], 'r') as eeprom_file: + ret = eeprom_file.read() + except IOError as e: + DBG_PRINT(str(e)) + + return ret + + # todo + # def _get_port_eeprom_path(self, port_num, devid): + # pass + + def __init__(self): + self.SONIC_PORT_NAME_PREFIX = "Ethernet" + self.PORT_START = 1 + self.PORT_END = 52 + self.SFP_BASE = 49 + self.PORTS_IN_BLOCK = 52 + + self.eeprom_mapping = {} + self.f_sfp_present = "/sys/class/sfp/sfp{}/sfp_presence" + self.f_sfp_enable = "/sys/class/sfp/sfp{}/sfp_enable" + for x in range(self.port_start, self.sfp_base): + self.eeprom_mapping[x] = None + for x in range(self.sfp_base, self.port_end + 1): + self.eeprom_mapping[x] = "/sys/class/sfp/sfp{}/sfp_eeprom".format( + x - self.sfp_base + 1) + self.presence = {} + for x in range(self.sfp_base, self.port_end + 1): + self.presence[x] = False + + SfpUtilBase.__init__(self) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + if port_num < self.sfp_base: + return False + try: + with open(self.f_sfp_present.format(port_num - self.sfp_base + 1), 'r') as sfp_file: + return 1 == int(sfp_file.read()) + except IOError as e: + DBG_PRINT(str(e)) + + return False + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + return False + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + return False + + def reset(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + return False + + def get_transceiver_change_event(self, timeout=0): + port_dict = {} + while True: + for x in range(self.sfp_base, self.port_end + 1): + presence = self.get_presence(x) + if presence != self.presence[x]: + self.presence[x] = presence + port_dict[x] = presence + return True, port_dict + time.sleep(0.5) diff --git a/device/centec/x86_64-centec_e582_48x2q4z-r0/E582-48x2q4z/port_config.ini b/device/centec/x86_64-centec_e582_48x2q4z-r0/E582-48x2q4z/port_config.ini index 78a1df9f051d..5b35cd7f5111 100644 --- a/device/centec/x86_64-centec_e582_48x2q4z-r0/E582-48x2q4z/port_config.ini +++ b/device/centec/x86_64-centec_e582_48x2q4z-r0/E582-48x2q4z/port_config.ini @@ -1,24 +1,24 @@ # name lanes alias speed -Ethernet1 75 eth-0-1 1000 -Ethernet2 73 eth-0-2 1000 -Ethernet3 72 eth-0-3 1000 -Ethernet4 70 eth-0-4 1000 -Ethernet5 69 eth-0-5 1000 -Ethernet6 67 eth-0-6 1000 -Ethernet7 66 eth-0-7 1000 -Ethernet8 64 eth-0-8 1000 -Ethernet9 63 eth-0-9 1000 -Ethernet10 61 eth-0-10 1000 -Ethernet11 60 eth-0-11 1000 -Ethernet12 58 eth-0-12 1000 -Ethernet13 57 eth-0-13 10000 -Ethernet14 56 eth-0-14 10000 -Ethernet15 55 eth-0-15 10000 -Ethernet16 53 eth-0-16 10000 -Ethernet17 52 eth-0-17 10000 -Ethernet18 50 eth-0-18 10000 -Ethernet19 49 eth-0-19 10000 -Ethernet20 48 eth-0-20 10000 +Ethernet1 91 eth-0-1 10000 +Ethernet2 89 eth-0-2 10000 +Ethernet3 88 eth-0-3 10000 +Ethernet4 86 eth-0-4 10000 +Ethernet5 85 eth-0-5 10000 +Ethernet6 83 eth-0-6 10000 +Ethernet7 82 eth-0-7 10000 +Ethernet8 80 eth-0-8 10000 +Ethernet9 79 eth-0-9 10000 +Ethernet10 77 eth-0-10 10000 +Ethernet11 76 eth-0-11 10000 +Ethernet12 74 eth-0-12 10000 +Ethernet13 73 eth-0-13 10000 +Ethernet14 72 eth-0-14 10000 +Ethernet15 71 eth-0-15 10000 +Ethernet16 69 eth-0-16 10000 +Ethernet17 68 eth-0-17 10000 +Ethernet18 66 eth-0-18 10000 +Ethernet19 65 eth-0-19 10000 +Ethernet20 64 eth-0-20 10000 Ethernet21 0 eth-0-21 10000 Ethernet22 1 eth-0-22 10000 Ethernet23 3 eth-0-23 10000 @@ -46,10 +46,10 @@ Ethernet44 30 eth-0-44 10000 Ethernet45 31 eth-0-45 10000 Ethernet46 33 eth-0-46 10000 Ethernet47 34 eth-0-47 10000 -Ethernet48 36 eth-0-48 10000 -Ethernet49 42,41,43,40 eth-0-49 40000 -Ethernet50 45,46,44,47 eth-0-50 40000 -Ethernet51 94,93,95,92 eth-0-51 100000 -Ethernet52 89,90,88,91 eth-0-52 100000 -Ethernet53 85,86,84,87 eth-0-53 100000 -Ethernet54 81,82,80,83 eth-0-54 100000 +Ethernet48 48 eth-0-48 10000 +Ethernet49 38,37,39,36 eth-0-49 100000 +Ethernet50 53,54,52,55 eth-0-50 100000 +Ethernet51 118,117,119,116 eth-0-51 100000 +Ethernet52 101,102,100,103 eth-0-52 100000 +Ethernet53 113,114,112,115 eth-0-53 40000 +Ethernet54 97,98,96,99 eth-0-54 40000 diff --git a/device/centec/x86_64-centec_e582_48x2q4z-r0/default_sku b/device/centec/x86_64-centec_e582_48x2q4z-r0/default_sku index 89c83dc3d0e3..332f7a2b4764 100644 --- a/device/centec/x86_64-centec_e582_48x2q4z-r0/default_sku +++ b/device/centec/x86_64-centec_e582_48x2q4z-r0/default_sku @@ -1 +1 @@ -E582-48x2q4z t1 +E582-48x2q4z l2 diff --git a/device/centec/x86_64-centec_e582_48x2q4z-r0/plugins/eeprom.py b/device/centec/x86_64-centec_e582_48x2q4z-r0/plugins/eeprom.py index 3fd55c63d8b7..63854d994cf1 100644 --- a/device/centec/x86_64-centec_e582_48x2q4z-r0/plugins/eeprom.py +++ b/device/centec/x86_64-centec_e582_48x2q4z-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Centec E582-48X6Q # @@ -10,7 +8,6 @@ ############################################################################# try: - import exceptions import binascii import time import optparse @@ -20,8 +17,8 @@ import subprocess from sonic_eeprom import eeprom_base from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): diff --git a/device/centec/x86_64-centec_e582_48x2q4z-r0/plugins/led_control.py b/device/centec/x86_64-centec_e582_48x2q4z-r0/plugins/led_control.py index 4459096cb011..48a4d8d04eae 100644 --- a/device/centec/x86_64-centec_e582_48x2q4z-r0/plugins/led_control.py +++ b/device/centec/x86_64-centec_e582_48x2q4z-r0/plugins/led_control.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python -# # led_control.py # # Platform-specific LED control functionality for SONiC @@ -16,7 +14,7 @@ import syslog from socket import * from select import * -except ImportError, e: +except ImportError as e: raise ImportError(str(e) + " - required module not found") @@ -25,6 +23,7 @@ def DBG_PRINT(str): syslog.syslog(syslog.LOG_INFO, str) syslog.closelog() + class LedControl(LedControlBase): """Platform specific LED control class""" SONIC_PORT_NAME_PREFIX = "Ethernet" @@ -53,7 +52,8 @@ def _initPanelLed(self): data = struct.pack('=HHHBB30B', 0, 3, 32, 30, 0, *[x[0] for x in self.led_mapping[21:51]]) self.udpClient.sendto(data, ('localhost', 8101)) - data = struct.pack('=HHHBB28B', 0, 3, 30, 28, 1, *[x[0] for x in (self.led_mapping[1:21]+self.led_mapping[51:59])]) + data = struct.pack('=HHHBB28B', 0, 3, 30, 28, 1, *[x[0] + for x in (self.led_mapping[1:21]+self.led_mapping[51:59])]) self.udpClient.sendto(data, ('localhost', 8101)) data = struct.pack('=HHHB', 0, 5, 1, 1) @@ -96,8 +96,8 @@ def _initDefaultConfig(self): DBG_PRINT("init led done") - # Helper method to map SONiC port name to index + def _port_name_to_index(self, port_name): # Strip "Ethernet" off port name if not port_name.startswith(self.SONIC_PORT_NAME_PREFIX): @@ -136,13 +136,20 @@ def port_link_state_change(self, portname, state): def __init__(self): # [macid, ctlid, defaultmode] self.led_mapping = [(0, 0, 0)] # resv - self.led_mapping.extend([(27, 1, 7), (25, 1, 7), (24, 1, 7), (22, 1, 7), (21, 1, 7), (19, 1, 7), (18, 1, 7), (16, 1, 7)]) # panel port 1~8 - self.led_mapping.extend([(15, 1, 7), (13, 1, 7), (12, 1, 7), (10, 1, 7), (9, 1, 7), (8, 1, 7), (7, 1, 7), (5, 1, 7)]) # panel port 9~16 - self.led_mapping.extend([(4, 1, 7), (2, 1, 7), (1, 1, 7), (0, 1, 7), (0, 0, 7), (1, 0, 7), (3, 0, 7), (2, 0, 7)]) # panel port 17~24 - self.led_mapping.extend([(4, 0, 7), (5, 0, 7), (6, 0, 7), (7, 0, 7), (8, 0, 7), (9, 0, 7), (10, 0, 7), (12, 0, 7)]) # panel port 25~32 - self.led_mapping.extend([(13, 0, 7), (15, 0, 7), (16, 0, 7), (18, 0, 7), (19, 0, 7), (21, 0, 7), (22, 0, 7), (24, 0, 7)]) # panel port 33~40 - self.led_mapping.extend([(25, 0, 7), (27, 0, 7), (28, 0, 7), (30, 0, 7), (31, 0, 7), (33, 0, 7), (34, 0, 7), (48, 0, 7)]) # panel port 41~48 - self.led_mapping.extend([(36, 0, 2), (52, 0, 2), (52, 1, 2), (36, 1, 2), (48, 1, 2), (32, 1, 2)]) # panel port 49~54 + self.led_mapping.extend([(27, 1, 7), (25, 1, 7), (24, 1, 7), (22, 1, 7), (21, 1, 7), + (19, 1, 7), (18, 1, 7), (16, 1, 7)]) # panel port 1~8 + self.led_mapping.extend([(15, 1, 7), (13, 1, 7), (12, 1, 7), (10, 1, 7), (9, 1, 7), + (8, 1, 7), (7, 1, 7), (5, 1, 7)]) # panel port 9~16 + self.led_mapping.extend([(4, 1, 7), (2, 1, 7), (1, 1, 7), (0, 1, 7), (0, 0, 7), + (1, 0, 7), (3, 0, 7), (2, 0, 7)]) # panel port 17~24 + self.led_mapping.extend([(4, 0, 7), (5, 0, 7), (6, 0, 7), (7, 0, 7), (8, 0, 7), + (9, 0, 7), (10, 0, 7), (12, 0, 7)]) # panel port 25~32 + self.led_mapping.extend([(13, 0, 7), (15, 0, 7), (16, 0, 7), (18, 0, 7), (19, 0, 7), + (21, 0, 7), (22, 0, 7), (24, 0, 7)]) # panel port 33~40 + self.led_mapping.extend([(25, 0, 7), (27, 0, 7), (28, 0, 7), (30, 0, 7), (31, 0, 7), + (33, 0, 7), (34, 0, 7), (48, 0, 7)]) # panel port 41~48 + self.led_mapping.extend([(36, 0, 2), (52, 0, 2), (52, 1, 2), (36, 1, 2), (48, 1, 2), + (32, 1, 2)]) # panel port 49~54 self.led_mapping.extend([(11, 1, 2), (11, 1, 2), (11, 1, 2), (11, 1, 2), (11, 1, 2), (11, 1, 2)]) self.f_led = "/sys/class/leds/{}/brightness" @@ -150,4 +157,3 @@ def __init__(self): self.udpClient = socket(AF_INET, SOCK_DGRAM) self._initDefaultConfig() - diff --git a/device/centec/x86_64-centec_e582_48x2q4z-r0/plugins/psuutil.py b/device/centec/x86_64-centec_e582_48x2q4z-r0/plugins/psuutil.py index 6505318ed948..f38f0cdd0a2e 100644 --- a/device/centec/x86_64-centec_e582_48x2q4z-r0/plugins/psuutil.py +++ b/device/centec/x86_64-centec_e582_48x2q4z-r0/plugins/psuutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Centec # @@ -13,7 +11,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" diff --git a/device/centec/x86_64-centec_e582_48x2q4z-r0/plugins/sfputil.py b/device/centec/x86_64-centec_e582_48x2q4z-r0/plugins/sfputil.py index 4d4b3f3e5558..4e94646db772 100644 --- a/device/centec/x86_64-centec_e582_48x2q4z-r0/plugins/sfputil.py +++ b/device/centec/x86_64-centec_e582_48x2q4z-r0/plugins/sfputil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - # sfputil.py # # Platform-specific SFP transceiver interface for SONiC @@ -18,9 +16,8 @@ raise ImportError("%s - required module not found" % str(e)) - def DBG_PRINT(str): - print str + "\n" + print(str + "\n") class SfpUtil(SfpUtilBase): @@ -40,7 +37,7 @@ def port_end(self): @property def qsfp_ports(self): - return range(49, self.PORTS_IN_BLOCK + 1) + return list(range(49, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -62,17 +59,17 @@ def get_eeprom_data(self, port): offset = (128 if port in self.qsfp_ports else 0) r_sel = [self.udpClient] req = struct.pack('=HHHBBHIBBBBI', - 0, 9, 16, # lchip/msgtype/msglen - ctlid, # uint8 ctl_id - devid, # uint8 slave_dev_id - 0x50, # uint16 dev_addr - (1< /dev/null 2>&1") + if p.readline() != None: + status = 1 + p.close() + except IOError: + return False + return status == 1 diff --git a/device/centec/x86_64-ew_es6220_x48q2h4-r0/plugins/sfputil.py b/device/centec/x86_64-ew_es6220_x48q2h4-r0/plugins/sfputil.py new file mode 100644 index 000000000000..103b3cd5630b --- /dev/null +++ b/device/centec/x86_64-ew_es6220_x48q2h4-r0/plugins/sfputil.py @@ -0,0 +1,188 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# + +try: + import time + import os + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + PORT_START = 0 + PORT_END = 53 + PORTS_IN_BLOCK = 32 + + EEPROM_OFFSET = 20 + + _port_to_eeprom_mapping = {} + + @property + def port_start(self): + return self.PORT_START + + @property + def port_end(self): + return self.PORT_END + + @property + def qsfp_ports(self): + return list(range(0, self.PORTS_IN_BLOCK + 1)) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + def __init__(self): + eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" + + for x in range(0, self.port_end + 1): + self._port_to_eeprom_mapping[x] = eeprom_path.format( + x + self.EEPROM_OFFSET) + + SfpUtilBase.__init__(self) + + def get_presence(self, port_name): + # modify by zhw to get sfp presence + # Check for invalid port_num + port_num = int(port_name[8:]) + + if port_num < (self.port_start+1) or port_num > (self.port_end+1): + return False + + # cpld info from "CPLD Register for es5800A2.2(V1.1)" + cpld_map = {0: '0x82', 1: '0x83', 2: '0x84', + 3: '0x85', 4: '0x86', 5: '0x87', 6: '0x8E'} + cpld_key = (port_num - 1)/8 + cpld_mask = (1 << (port_num - 1) % 8) + + # use i2cget cmd to get cpld data + output = os.popen('i2cdetect -l | grep CP') + bus_num = output.read()[4] + cmd = "i2cget -y "+bus_num+" 0x5 "+cpld_map[cpld_key] + tmp = os.popen(cmd).read().replace("\n", "") + cpld_value = int(tmp, 16) + + if cpld_value & cpld_mask == 0: + return True + else: + return False + + def get_low_power_mode(self, port_num): + ''' + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + try: + reg_file = open("/sys/devices/platform/dell-s6000-cpld.0/qsfp_lpmode") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + + content = reg_file.readline().rstrip() + + # content is a string containing the hex representation of the register + reg_value = int(content, 16) + + # Mask off the bit corresponding to our port + mask = (1 << port_num) + + # LPMode is active high + if reg_value & mask == 0: + return False + ''' + return False + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + try: + reg_file = open( + "/sys/devices/platform/dell-s6000-cpld.0/qsfp_lpmode", "r+") + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + content = reg_file.readline().rstrip() + + # content is a string containing the hex representation of the register + reg_value = int(content, 16) + + # Mask off the bit corresponding to our port + mask = (1 << port_num) + + # LPMode is active high; set or clear the bit accordingly + if lpmode is True: + reg_value = reg_value | mask + else: + reg_value = reg_value & ~mask + + # Convert our register value back to a hex string and write back + content = hex(reg_value) + + reg_file.seek(0) + reg_file.write(content) + reg_file.close() + + return True + + def reset(self, port_num): + QSFP_RESET_REGISTER_DEVICE_FILE = "/sys/devices/platform/dell-s6000-cpld.0/qsfp_reset" + + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + try: + reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "r+") + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + content = reg_file.readline().rstrip() + + # File content is a string containing the hex representation of the register + reg_value = int(content, 16) + + # Mask off the bit corresponding to our port + mask = (1 << port_num) + + # ResetL is active low + reg_value = reg_value & ~mask + + # Convert our register value back to a hex string and write back + reg_file.seek(0) + reg_file.write(hex(reg_value)) + reg_file.close() + + # Sleep 1 second to allow it to settle + time.sleep(1) + + # Flip the bit back high and write back to the register to take port out of reset + try: + reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "w") + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + reg_value = reg_value | mask + reg_file.seek(0) + reg_file.write(hex(reg_value)) + reg_file.close() + + return True + + 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 diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/port_config.nps b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/port_config.nps index 9c6a5af8e5f0..e7f4fc78221c 100644 --- a/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/port_config.nps +++ b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/port_config.nps @@ -620,59 +620,5 @@ 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 port set property unit=0 portlist=129 an=enable -port set property unit=0 portlist=0 admin=enable -port set property unit=0 portlist=1 admin=enable -port set property unit=0 portlist=2 admin=enable -port set property unit=0 portlist=3 admin=enable -port set property unit=0 portlist=4 admin=enable -port set property unit=0 portlist=5 admin=enable -port set property unit=0 portlist=6 admin=enable -port set property unit=0 portlist=7 admin=enable -port set property unit=0 portlist=8 admin=enable -port set property unit=0 portlist=9 admin=enable -port set property unit=0 portlist=10 admin=enable -port set property unit=0 portlist=11 admin=enable -port set property unit=0 portlist=12 admin=enable -port set property unit=0 portlist=13 admin=enable -port set property unit=0 portlist=14 admin=enable -port set property unit=0 portlist=15 admin=enable -port set property unit=0 portlist=16 admin=enable -port set property unit=0 portlist=17 admin=enable -port set property unit=0 portlist=18 admin=enable -port set property unit=0 portlist=19 admin=enable -port set property unit=0 portlist=20 admin=enable -port set property unit=0 portlist=21 admin=enable -port set property unit=0 portlist=22 admin=enable -port set property unit=0 portlist=23 admin=enable -port set property unit=0 portlist=24 admin=enable -port set property unit=0 portlist=25 admin=enable -port set property unit=0 portlist=26 admin=enable -port set property unit=0 portlist=27 admin=enable -port set property unit=0 portlist=28 admin=enable -port set property unit=0 portlist=29 admin=enable -port set property unit=0 portlist=30 admin=enable -port set property unit=0 portlist=31 admin=enable -port set property unit=0 portlist=32 admin=enable -port set property unit=0 portlist=33 admin=enable -port set property unit=0 portlist=34 admin=enable -port set property unit=0 portlist=35 admin=enable -port set property unit=0 portlist=36 admin=enable -port set property unit=0 portlist=37 admin=enable -port set property unit=0 portlist=38 admin=enable -port set property unit=0 portlist=39 admin=enable -port set property unit=0 portlist=40 admin=enable -port set property unit=0 portlist=41 admin=enable -port set property unit=0 portlist=42 admin=enable -port set property unit=0 portlist=43 admin=enable -port set property unit=0 portlist=44 admin=enable -port set property unit=0 portlist=45 admin=enable -port set property unit=0 portlist=46 admin=enable -port set property unit=0 portlist=47 admin=enable -port set property unit=0 portlist=48 admin=enable -port set property unit=0 portlist=49 admin=enable -port set property unit=0 portlist=50 admin=enable -port set property unit=0 portlist=51 admin=enable -port set property unit=0 portlist=52 admin=enable -port set property unit=0 portlist=53 admin=enable -port set property unit=0 portlist=129 admin=disable -port set property unit=0 portlist=130 admin=disable +port set property unit=0 portlist=0-53 admin=disable +port set property unit=0 portlist=129-130 admin=disable 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 index 5019b9c40a9a..ae5a8385d96c 100755 --- a/device/cig/x86_64-cig_cs5435_54p-r0/plugins/eeprom.py +++ b/device/cig/x86_64-cig_cs5435_54p-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -11,11 +8,13 @@ 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") +except ImportError as 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 index 70d50e6c3458..442026775a5e 100755 --- a/device/cig/x86_64-cig_cs5435_54p-r0/plugins/psuutil.py +++ b/device/cig/x86_64-cig_cs5435_54p-r0/plugins/psuutil.py @@ -22,8 +22,8 @@ class PsuUtil(PsuBase): def __init__(self): PsuBase.__init__(self) - # Get sysfs attribute + def get_attr_value(self, attr_path): retval = 'ERR' @@ -57,7 +57,7 @@ def get_psu_status(self, index): """ status = 0 attr_file = 'psu_power_good' - attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file + attr_path = self.SYSFS_PSU_DIR[index-1] + '/' + attr_file attr_value = self.get_attr_value(attr_path) @@ -65,7 +65,7 @@ def get_psu_status(self, index): attr_value = int(attr_value, 16) # Check for PSU status if (attr_value == 1): - status = 1 + status = 1 return status @@ -78,8 +78,8 @@ def get_psu_presence(self, index): """ status = 0 psu_absent = 0 - attr_file ='psu_present' - attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file + attr_file = 'psu_present' + attr_path = self.SYSFS_PSU_DIR[index-1] + '/' + attr_file attr_value = self.get_attr_value(attr_path) @@ -87,7 +87,6 @@ def get_psu_presence(self, index): attr_value = int(attr_value, 16) # Check for PSU presence if (attr_value == 1): - status = 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 index 2863b80c9950..2d6827300457 100755 --- a/device/cig/x86_64-cig_cs5435_54p-r0/plugins/sfputil.py +++ b/device/cig/x86_64-cig_cs5435_54p-r0/plugins/sfputil.py @@ -1,10 +1,8 @@ -#!/usr/bin/env python - try: import time from sonic_sfp.sfputilbase import SfpUtilBase -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class SfpUtil(SfpUtilBase): @@ -19,63 +17,63 @@ class SfpUtil(SfpUtilBase): _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, + 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, + 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) + _qsfp_ports = list(range(_qsfp_port_start, _ports_in_block + 1)) def get_presence(self, port_num): # Check for invalid port_num @@ -85,11 +83,10 @@ def get_presence(self, port_num): 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) + print("Error: unable to open file: %s" % str(e)) return False try: @@ -100,7 +97,7 @@ def get_presence(self, port_num): 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) + print("Error:try again to read file failed: %s %s" % (str(e), port_ps)) reg_file.close() return False @@ -118,7 +115,6 @@ 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): @@ -139,10 +135,10 @@ def reset(self, port_num): try: reg_file = open(port_ps, 'w') except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False - #toggle reset + # toggle reset reg_file.seek(0) reg_file.write('1') time.sleep(1) @@ -158,15 +154,15 @@ def set_low_power_mode(self, port_num, lpmode): pre_value = self.get_presence(port_num) if pre_value == False: - return 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') + reg_file = open(port_ps, 'w') except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_file.seek(0) @@ -179,7 +175,6 @@ def set_low_power_mode(self, port_num, lpmode): return True - def get_low_power_mode(self, port_num): # Check for invalid port_num @@ -196,13 +191,13 @@ def get_low_power_mode(self, port_num): try: reg_file = open(port_ps) except IOError as e: - print "Error: unable to open file:%s %s" % (str(e), port_ps) + 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) + print("Error: unable to open file:%s %s" % (str(e), port_ps)) reg_file.close() return False @@ -232,7 +227,6 @@ def get_transceiver_change_event(self): time.sleep(0.5) - @property def port_start(self): return self._port_start @@ -247,4 +241,4 @@ def qsfp_ports(self): @property def port_to_eeprom_mapping(self): - return self._port_to_eeprom_mapping + return self._port_to_eeprom_mapping diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/port_config.nps b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/port_config.nps index aca222f5962d..120b7f398871 100644 --- a/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/port_config.nps +++ b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/port_config.nps @@ -620,59 +620,5 @@ 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 port set property unit=0 portlist=129 an=enable -port set property unit=0 portlist=0 admin=enable -port set property unit=0 portlist=1 admin=enable -port set property unit=0 portlist=2 admin=enable -port set property unit=0 portlist=3 admin=enable -port set property unit=0 portlist=4 admin=enable -port set property unit=0 portlist=5 admin=enable -port set property unit=0 portlist=6 admin=enable -port set property unit=0 portlist=7 admin=enable -port set property unit=0 portlist=8 admin=enable -port set property unit=0 portlist=9 admin=enable -port set property unit=0 portlist=10 admin=enable -port set property unit=0 portlist=11 admin=enable -port set property unit=0 portlist=12 admin=enable -port set property unit=0 portlist=13 admin=enable -port set property unit=0 portlist=14 admin=enable -port set property unit=0 portlist=15 admin=enable -port set property unit=0 portlist=16 admin=enable -port set property unit=0 portlist=17 admin=enable -port set property unit=0 portlist=18 admin=enable -port set property unit=0 portlist=19 admin=enable -port set property unit=0 portlist=20 admin=enable -port set property unit=0 portlist=21 admin=enable -port set property unit=0 portlist=22 admin=enable -port set property unit=0 portlist=23 admin=enable -port set property unit=0 portlist=24 admin=enable -port set property unit=0 portlist=25 admin=enable -port set property unit=0 portlist=26 admin=enable -port set property unit=0 portlist=27 admin=enable -port set property unit=0 portlist=28 admin=enable -port set property unit=0 portlist=29 admin=enable -port set property unit=0 portlist=30 admin=enable -port set property unit=0 portlist=31 admin=enable -port set property unit=0 portlist=32 admin=enable -port set property unit=0 portlist=33 admin=enable -port set property unit=0 portlist=34 admin=enable -port set property unit=0 portlist=35 admin=enable -port set property unit=0 portlist=36 admin=enable -port set property unit=0 portlist=37 admin=enable -port set property unit=0 portlist=38 admin=enable -port set property unit=0 portlist=39 admin=enable -port set property unit=0 portlist=40 admin=enable -port set property unit=0 portlist=41 admin=enable -port set property unit=0 portlist=42 admin=enable -port set property unit=0 portlist=43 admin=enable -port set property unit=0 portlist=44 admin=enable -port set property unit=0 portlist=45 admin=enable -port set property unit=0 portlist=46 admin=enable -port set property unit=0 portlist=47 admin=enable -port set property unit=0 portlist=48 admin=enable -port set property unit=0 portlist=49 admin=enable -port set property unit=0 portlist=50 admin=enable -port set property unit=0 portlist=51 admin=enable -port set property unit=0 portlist=52 admin=enable -port set property unit=0 portlist=53 admin=enable -port set property unit=0 portlist=129 admin=disable -port set property unit=0 portlist=130 admin=disable +port set property unit=0 portlist=0-53 admin=disable +port set property unit=0 portlist=129-130 admin=disable 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 index 5019b9c40a9a..c068c04dac6d 100755 --- a/device/cig/x86_64-cig_cs6436_54p-r0/plugins/eeprom.py +++ b/device/cig/x86_64-cig_cs6436_54p-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -10,12 +7,13 @@ 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") +except ImportError as 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 index 70d50e6c3458..442026775a5e 100755 --- a/device/cig/x86_64-cig_cs6436_54p-r0/plugins/psuutil.py +++ b/device/cig/x86_64-cig_cs6436_54p-r0/plugins/psuutil.py @@ -22,8 +22,8 @@ class PsuUtil(PsuBase): def __init__(self): PsuBase.__init__(self) - # Get sysfs attribute + def get_attr_value(self, attr_path): retval = 'ERR' @@ -57,7 +57,7 @@ def get_psu_status(self, index): """ status = 0 attr_file = 'psu_power_good' - attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file + attr_path = self.SYSFS_PSU_DIR[index-1] + '/' + attr_file attr_value = self.get_attr_value(attr_path) @@ -65,7 +65,7 @@ def get_psu_status(self, index): attr_value = int(attr_value, 16) # Check for PSU status if (attr_value == 1): - status = 1 + status = 1 return status @@ -78,8 +78,8 @@ def get_psu_presence(self, index): """ status = 0 psu_absent = 0 - attr_file ='psu_present' - attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file + attr_file = 'psu_present' + attr_path = self.SYSFS_PSU_DIR[index-1] + '/' + attr_file attr_value = self.get_attr_value(attr_path) @@ -87,7 +87,6 @@ def get_psu_presence(self, index): attr_value = int(attr_value, 16) # Check for PSU presence if (attr_value == 1): - status = 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 index 2863b80c9950..2d6827300457 100755 --- a/device/cig/x86_64-cig_cs6436_54p-r0/plugins/sfputil.py +++ b/device/cig/x86_64-cig_cs6436_54p-r0/plugins/sfputil.py @@ -1,10 +1,8 @@ -#!/usr/bin/env python - try: import time from sonic_sfp.sfputilbase import SfpUtilBase -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class SfpUtil(SfpUtilBase): @@ -19,63 +17,63 @@ class SfpUtil(SfpUtilBase): _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, + 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, + 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) + _qsfp_ports = list(range(_qsfp_port_start, _ports_in_block + 1)) def get_presence(self, port_num): # Check for invalid port_num @@ -85,11 +83,10 @@ def get_presence(self, port_num): 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) + print("Error: unable to open file: %s" % str(e)) return False try: @@ -100,7 +97,7 @@ def get_presence(self, port_num): 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) + print("Error:try again to read file failed: %s %s" % (str(e), port_ps)) reg_file.close() return False @@ -118,7 +115,6 @@ 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): @@ -139,10 +135,10 @@ def reset(self, port_num): try: reg_file = open(port_ps, 'w') except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False - #toggle reset + # toggle reset reg_file.seek(0) reg_file.write('1') time.sleep(1) @@ -158,15 +154,15 @@ def set_low_power_mode(self, port_num, lpmode): pre_value = self.get_presence(port_num) if pre_value == False: - return 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') + reg_file = open(port_ps, 'w') except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_file.seek(0) @@ -179,7 +175,6 @@ def set_low_power_mode(self, port_num, lpmode): return True - def get_low_power_mode(self, port_num): # Check for invalid port_num @@ -196,13 +191,13 @@ def get_low_power_mode(self, port_num): try: reg_file = open(port_ps) except IOError as e: - print "Error: unable to open file:%s %s" % (str(e), port_ps) + 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) + print("Error: unable to open file:%s %s" % (str(e), port_ps)) reg_file.close() return False @@ -232,7 +227,6 @@ def get_transceiver_change_event(self): time.sleep(0.5) - @property def port_start(self): return self._port_start @@ -247,4 +241,4 @@ def qsfp_ports(self): @property def port_to_eeprom_mapping(self): - return self._port_to_eeprom_mapping + return self._port_to_eeprom_mapping diff --git a/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps b/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps index ec5f0273b9b5..c0067a3b56af 100644 --- a/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps +++ b/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps @@ -642,61 +642,5 @@ 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 port set property unit=0 portlist=129 an=enable -port set property unit=0 portlist=0 admin=enable -port set property unit=0 portlist=1 admin=enable -port set property unit=0 portlist=2 admin=enable -port set property unit=0 portlist=3 admin=enable -port set property unit=0 portlist=4 admin=enable -port set property unit=0 portlist=5 admin=enable -port set property unit=0 portlist=6 admin=enable -port set property unit=0 portlist=7 admin=enable -port set property unit=0 portlist=8 admin=enable -port set property unit=0 portlist=9 admin=enable -port set property unit=0 portlist=10 admin=enable -port set property unit=0 portlist=11 admin=enable -port set property unit=0 portlist=12 admin=enable -port set property unit=0 portlist=13 admin=enable -port set property unit=0 portlist=14 admin=enable -port set property unit=0 portlist=15 admin=enable -port set property unit=0 portlist=16 admin=enable -port set property unit=0 portlist=17 admin=enable -port set property unit=0 portlist=18 admin=enable -port set property unit=0 portlist=19 admin=enable -port set property unit=0 portlist=20 admin=enable -port set property unit=0 portlist=21 admin=enable -port set property unit=0 portlist=22 admin=enable -port set property unit=0 portlist=23 admin=enable -port set property unit=0 portlist=24 admin=enable -port set property unit=0 portlist=25 admin=enable -port set property unit=0 portlist=26 admin=enable -port set property unit=0 portlist=27 admin=enable -port set property unit=0 portlist=28 admin=enable -port set property unit=0 portlist=29 admin=enable -port set property unit=0 portlist=30 admin=enable -port set property unit=0 portlist=31 admin=enable -port set property unit=0 portlist=32 admin=enable -port set property unit=0 portlist=33 admin=enable -port set property unit=0 portlist=34 admin=enable -port set property unit=0 portlist=35 admin=enable -port set property unit=0 portlist=36 admin=enable -port set property unit=0 portlist=37 admin=enable -port set property unit=0 portlist=38 admin=enable -port set property unit=0 portlist=39 admin=enable -port set property unit=0 portlist=40 admin=enable -port set property unit=0 portlist=41 admin=enable -port set property unit=0 portlist=42 admin=enable -port set property unit=0 portlist=43 admin=enable -port set property unit=0 portlist=44 admin=enable -port set property unit=0 portlist=45 admin=enable -port set property unit=0 portlist=46 admin=enable -port set property unit=0 portlist=47 admin=enable -port set property unit=0 portlist=48 admin=enable -port set property unit=0 portlist=49 admin=enable -port set property unit=0 portlist=50 admin=enable -port set property unit=0 portlist=51 admin=enable -port set property unit=0 portlist=52 admin=enable -port set property unit=0 portlist=53 admin=enable -port set property unit=0 portlist=54 admin=enable -port set property unit=0 portlist=55 admin=enable -port set property unit=0 portlist=129 admin=disable -port set property unit=0 portlist=130 admin=disable +port set property unit=0 portlist=0-55 admin=disable +port set property unit=0 portlist=129-130 admin=disable diff --git a/device/cig/x86_64-cig_cs6436_56p-r0/plugins/eeprom.py b/device/cig/x86_64-cig_cs6436_56p-r0/plugins/eeprom.py index 5019b9c40a9a..ae5a8385d96c 100755 --- a/device/cig/x86_64-cig_cs6436_56p-r0/plugins/eeprom.py +++ b/device/cig/x86_64-cig_cs6436_56p-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -11,11 +8,13 @@ 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") +except ImportError as 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_56p-r0/plugins/psuutil.py b/device/cig/x86_64-cig_cs6436_56p-r0/plugins/psuutil.py index 70d50e6c3458..442026775a5e 100755 --- a/device/cig/x86_64-cig_cs6436_56p-r0/plugins/psuutil.py +++ b/device/cig/x86_64-cig_cs6436_56p-r0/plugins/psuutil.py @@ -22,8 +22,8 @@ class PsuUtil(PsuBase): def __init__(self): PsuBase.__init__(self) - # Get sysfs attribute + def get_attr_value(self, attr_path): retval = 'ERR' @@ -57,7 +57,7 @@ def get_psu_status(self, index): """ status = 0 attr_file = 'psu_power_good' - attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file + attr_path = self.SYSFS_PSU_DIR[index-1] + '/' + attr_file attr_value = self.get_attr_value(attr_path) @@ -65,7 +65,7 @@ def get_psu_status(self, index): attr_value = int(attr_value, 16) # Check for PSU status if (attr_value == 1): - status = 1 + status = 1 return status @@ -78,8 +78,8 @@ def get_psu_presence(self, index): """ status = 0 psu_absent = 0 - attr_file ='psu_present' - attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file + attr_file = 'psu_present' + attr_path = self.SYSFS_PSU_DIR[index-1] + '/' + attr_file attr_value = self.get_attr_value(attr_path) @@ -87,7 +87,6 @@ def get_psu_presence(self, index): attr_value = int(attr_value, 16) # Check for PSU presence if (attr_value == 1): - status = 1 + status = 1 return status - diff --git a/device/cig/x86_64-cig_cs6436_56p-r0/plugins/sfputil.py b/device/cig/x86_64-cig_cs6436_56p-r0/plugins/sfputil.py index 1e15c0e886f7..9c31083f5c23 100755 --- a/device/cig/x86_64-cig_cs6436_56p-r0/plugins/sfputil.py +++ b/device/cig/x86_64-cig_cs6436_56p-r0/plugins/sfputil.py @@ -1,10 +1,8 @@ -#!/usr/bin/env python - try: import time from sonic_sfp.sfputilbase import SfpUtilBase -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class SfpUtil(SfpUtilBase): @@ -17,68 +15,68 @@ class SfpUtil(SfpUtilBase): _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, + 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 : 58, - 52 : 59, - 53 : 60, - 54 : 61, - 55 : 62, - 56 : 63, + 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: 58, + 52: 59, + 53: 60, + 54: 61, + 55: 62, + 56: 63, } - _qsfp_ports = range(_qsfp_port_start, _ports_in_block + 1) - + _qsfp_ports = list(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: @@ -87,29 +85,28 @@ def get_presence(self, port_num): 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) + 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) + 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 @@ -120,13 +117,12 @@ 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) @@ -137,14 +133,14 @@ def reset(self, port_num): 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) + print("Error: unable to open file: %s" % str(e)) return False - #toggle reset + # toggle reset reg_file.seek(0) reg_file.write('1') time.sleep(1) @@ -152,23 +148,23 @@ 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) + pre_value = self.get_presence(port_num) if pre_value == False: - return 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') + reg_file = open(port_ps, 'w') except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_file.seek(0) @@ -181,40 +177,39 @@ def set_low_power_mode(self, port_num, lpmode): 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) + + 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) + 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() + 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: @@ -234,7 +229,6 @@ def get_transceiver_change_event(self): time.sleep(0.5) - @property def port_start(self): return self._port_start @@ -247,6 +241,6 @@ def port_end(self): def qsfp_ports(self): return self._qsfp_ports - @property + @property def port_to_eeprom_mapping(self): - return self._port_to_eeprom_mapping + return self._port_to_eeprom_mapping diff --git a/device/common/pddf/plugins/eeprom.py b/device/common/pddf/plugins/eeprom.py new file mode 100755 index 000000000000..cf7215e0c9ac --- /dev/null +++ b/device/common/pddf/plugins/eeprom.py @@ -0,0 +1,25 @@ +try: + import os + import sys + import json + sys.path.append('/usr/share/sonic/platform/plugins') + import pddfparse + #from sonic_eeprom import eeprom_base + from sonic_eeprom import eeprom_tlvinfo +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class board(eeprom_tlvinfo.TlvInfoDecoder): + _TLV_INFO_MAX_LEN = 256 + + def __init__(self, name, path, cpld_root, ro): + global pddf_obj + global plugin_data + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)) + '/../pddf/pd-plugin.json')) as pd: + plugin_data = json.load(pd) + + pddf_obj = pddfparse.PddfParse() + # system EEPROM always has device name EEPROM1 + self.eeprom_path = pddf_obj.get_path("EEPROM1", "eeprom") + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/common/pddf/plugins/fanutil.py b/device/common/pddf/plugins/fanutil.py new file mode 100755 index 000000000000..f34c260035e8 --- /dev/null +++ b/device/common/pddf/plugins/fanutil.py @@ -0,0 +1,199 @@ +# Sample pddf_fanutil file +# All the supported FAN SysFS aattributes are +#- fan_present +#- fan_direction +#- fan_input +#- fan_pwm +#- fan_fault +# where idx is in the range [1-12] +# + + +import os.path +import sys +sys.path.append('/usr/share/sonic/platform/plugins') +import pddfparse +import json + +try: + from sonic_fan.fan_base import FanBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class FanUtil(FanBase): + """PDDF generic FAN util class""" + + def __init__(self): + FanBase.__init__(self) + global pddf_obj + global plugin_data + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)) + '/../pddf/pd-plugin.json')) as pd: + plugin_data = json.load(pd) + + pddf_obj = pddfparse.PddfParse() + self.platform = pddf_obj.get_platform() + + self.num_fans = (self.platform['num_fantrays'] * self.platform['num_fans_pertray']) + + def get_num_fans(self): + return self.num_fans + + def get_presence(self, idx): + # 1 based fan index + if idx < 1 or idx > self.num_fans: + print("Invalid fan index %d\n" % idx) + return False + + attr_name = "fan" + str(idx) + "_present" + output = pddf_obj.get_attr_name_output("FAN-CTRL", attr_name) + if not output: + return False + + mode = output['mode'] + presence = output['status'].rstrip() + + vmap = plugin_data['FAN']['present'][mode]['valmap'] + + if presence in vmap: + status = vmap[presence] + else: + status = False + + return status + + def get_status(self, idx): + # 1 based fan index + if idx < 1 or idx > self.num_fans: + print("Invalid fan index %d\n" % idx) + return False + + speed = self.get_speed(idx) + status = True if (speed != 0) else False + return status + + def get_direction(self, idx): + # 1 based fan index + if idx < 1 or idx > self.num_fans: + print("Invalid fan index %d\n" % idx) + return None + + attr = "fan" + str(idx) + "_direction" + output = pddf_obj.get_attr_name_output("FAN-CTRL", attr) + if not output: + return None + + mode = output['mode'] + val = output['status'] + + val = val.rstrip() + vmap = plugin_data['FAN']['direction'][mode]['valmap'] + + if val in vmap: + direction = vmap[val] + else: + direction = val + + return direction + + def get_directions(self): + num_fan = self.get_num_fan() + + for i in range(1, num_fan+1): + attr = "fan" + str(i) + "_direction" + output = pddf_obj.get_attr_name_output("FAN-CTRL", attr) + if not output: + return None + + mode = output['mode'] + val = output['status'] + + val = val.rstrip() + vmap = plugin_data['FAN']['direction'][mode]['valmap'] + + direction = vmap[str(val)] + + print("FAN-%d direction is %s" % (i, direction)) + + return 0 + + def get_speed(self, idx): + # 1 based fan index + if idx < 1 or idx > self.num_fans: + print("Invalid fan index %d\n" % idx) + return 0 + + attr = "fan" + str(idx) + "_input" + output = pddf_obj.get_attr_name_output("FAN-CTRL", attr) + if not output: + return 0 + + #mode = output['mode'] + val = output['status'].rstrip() + + if val.isalpha(): + return 0 + else: + rpm_speed = int(float(val)) + + return rpm_speed + + def get_speeds(self): + num_fan = self.get_num_fan() + ret = "FAN_INDEX\t\tRPM\n" + + for i in range(1, num_fan+1): + attr1 = "fan" + str(i) + "_input" + output = pddf_obj.get_attr_name_output("FAN-CTRL", attr1) + if not output: + return "" + + #mode = output['mode'] + val = output['status'].rstrip() + + if val.isalpha(): + frpm = 0 + else: + frpm = int(val) + + ret += "FAN-%d\t\t\t%d\n" % (i, frpm) + + return ret + + def set_speed(self, val): + if val < 0 or val > 100: + print("Error: Invalid speed %d. Please provide a valid speed percentage" % val) + return False + + num_fan = self.num_fans + if 'duty_cycle_to_pwm' not in plugin_data['FAN']: + print("Setting fan speed is not allowed !") + return False + else: + duty_cycle_to_pwm = eval(plugin_data['FAN']['duty_cycle_to_pwm']) + pwm = duty_cycle_to_pwm(val) + print("New Speed: %d%% - PWM value to be set is %d\n" % (val, pwm)) + + for i in range(1, num_fan+1): + attr = "fan" + str(i) + "_pwm" + node = pddf_obj.get_path("FAN-CTRL", attr) + if node is None: + return False + try: + with open(node, 'w') as f: + f.write(str(pwm)) + except IOError: + return False + + return True + + def dump_sysfs(self): + return pddf_obj.cli_dump_dsysfs('fan') + + def get_change_event(self): + """ + TODO: This function need to be implemented + when decide to support monitoring FAN(fand) + on this platform. + """ + raise NotImplementedError diff --git a/device/common/pddf/plugins/ledutil.py b/device/common/pddf/plugins/ledutil.py new file mode 100755 index 000000000000..5f9e2e99dbfa --- /dev/null +++ b/device/common/pddf/plugins/ledutil.py @@ -0,0 +1,59 @@ +import sys +sys.path.append('/usr/share/sonic/platform/plugins') +import pddfparse + + +class LedUtil: + color_map = { + "STATUS_LED_COLOR_GREEN": "on", + "STATUS_LED_COLOR_RED": "faulty", + "STATUS_LED_COLOR_OFF": "off" + } + + def __init__(self): + global pddf_obj + pddf_obj = pddfparse.PddfParse() + self.path = "pddf/devices/led" + self.cur_state_path = "pddf/devices/led/cur_state" + + def set_status_led(self, led_device_name, color, color_state="SOLID"): + if (not led_device_name in list(pddf_obj.data.keys())): + status = "ERROR: " + led_device_name + " is not configured" + return (status) + + if (not color in list(self.color_map.keys())): + status = "ERROR: Invalid color" + return (status) + + index = pddf_obj.data[led_device_name]['dev_attr']['index'] + pddf_obj.create_attr('device_name', led_device_name, self.path) + pddf_obj.create_attr('index', index, self.path) + pddf_obj.create_attr( + 'color', self.color_map[color], self.cur_state_path) + pddf_obj.create_attr('color_state', color_state, self.cur_state_path) + pddf_obj.create_attr('dev_ops', 'set_status', self.path) + return ("Executed") + + def get_status_led(self, led_device_name): + if (not led_device_name in list(pddf_obj.data.keys())): + status = "ERROR: " + led_device_name + " is not configured" + return (status) + + index = pddf_obj.data[led_device_name]['dev_attr']['index'] + pddf_obj.create_attr('device_name', led_device_name, self.path) + pddf_obj.create_attr('index', index, self.path) + pddf_obj.create_attr('dev_ops', 'get_status', self.path) + color_f = "/sys/kernel/" + self.cur_state_path + "/color" + color_state_f = "/sys/kernel/" + self.cur_state_path + "/color_state" + + try: + with open(color_f, 'r') as f: + color = f.read().strip("\r\n") + with open(color_state_f, 'r') as f: + color_state = f.read().strip("\r\n") + except IOError: + status = "ERROR :" + color_f + " open failed" + return (status) + status = "%s-%s:\t%s %s\n" % (led_device_name, + index, color, color_state) + return (status) diff --git a/device/common/pddf/plugins/psuutil.py b/device/common/pddf/plugins/psuutil.py new file mode 100755 index 000000000000..dccb1ac1a155 --- /dev/null +++ b/device/common/pddf/plugins/psuutil.py @@ -0,0 +1,270 @@ +# +# Sample pddf_psuutil file +# +# All the supported PSU SysFS aattributes are +#- psu_present +#- psu_model_name +#- psu_power_good +#- psu_mfr_id +#- psu_serial_num +#- psu_fan_dir +#- psu_v_out +#- psu_i_out +#- psu_p_out +#- psu_fan1_speed_rpm +# + +import os.path +import sys +sys.path.append('/usr/share/sonic/platform/plugins') +import pddfparse +import json + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PsuUtil(PsuBase): + """PDDF generic PSU util class""" + + def __init__(self): + PsuBase.__init__(self) + global pddf_obj + global plugin_data + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)) + '/../pddf/pd-plugin.json')) as pd: + plugin_data = json.load(pd) + + pddf_obj = pddfparse.PddfParse() + self.platform = pddf_obj.get_platform() + + def get_num_psus(self): + return int(self.platform['num_psus']) + + def get_psu_status(self, index): + if index is None: + return False + + device = "PSU" + "%d" % index + output = pddf_obj.get_attr_name_output(device, "psu_power_good") + if not output: + return False + + mode = output['mode'] + val = output['status'] + + val = val.rstrip() + vmap = plugin_data['PSU']['psu_power_good'][mode]['valmap'] + + if val in vmap: + return vmap[val] + else: + return False + + def get_psu_presence(self, index): + if index is None: + return False + + status = 0 + device = "PSU" + "%d" % index + output = pddf_obj.get_attr_name_output(device, "psu_present") + if not output: + return False + + mode = output['mode'] + status = output['status'] + + vmap = plugin_data['PSU']['psu_present'][mode]['valmap'] + + if status.rstrip('\n') in vmap: + return vmap[status.rstrip('\n')] + else: + return False + + def get_powergood_status(self, idx): + if idx is None: + return False + + if idx < 1 or idx > self.platform['num_psus']: + print("Invalid index %d\n" % idx) + return False + + device = "PSU"+"%d" % (idx) + output = pddf_obj.get_attr_name_output(device, "psu_power_good") + if not output: + return False + + mode = output['mode'] + status = output['status'] + + vmap = plugin_data['PSU']['psu_power_good'][mode]['valmap'] + + if status.rstrip('\n') in vmap: + return vmap[status.rstrip('\n')] + else: + return False + + def get_model(self, idx): + if idx is None: + return None + + if idx < 1 or idx > self.platform['num_psus']: + print("Invalid index %d\n" % idx) + return None + + device = "PSU"+"%d" % (idx) + output = pddf_obj.get_attr_name_output(device, "psu_model_name") + if not output: + return None + + model = output['status'] + + # strip_non_ascii + stripped = (c for c in model if 0 < ord(c) < 127) + model = ''.join(stripped) + + return model.rstrip('\n') + + def get_mfr_id(self, idx): + if idx is None: + return None + + if idx < 1 or idx > self.platform['num_psus']: + print("Invalid index %d\n" % idx) + return None + + device = "PSU"+"%d" % (idx) + output = pddf_obj.get_attr_name_output(device, "psu_mfr_id") + if not output: + return None + + mfr = output['status'] + + return mfr.rstrip('\n') + + def get_serial(self, idx): + if idx is None: + return None + + if idx < 1 or idx > self.platform['num_psus']: + print("Invalid index %d\n" % idx) + return None + + device = "PSU"+"%d" % (idx) + output = pddf_obj.get_attr_name_output(device, "psu_serial_num") + if not output: + return None + + serial = output['status'] + + return serial.rstrip('\n') + + def get_direction(self, idx): + if idx is None: + return None + + if idx < 1 or idx > self.platform['num_psus']: + print("Invalid index %d\n" % idx) + return None + + device = "PSU"+"%d" % (idx) + output = pddf_obj.get_attr_name_output(device, "psu_fan_dir") + if not output: + return None + + mode = output['mode'] + direction = output['status'].rstrip('\n') + + vmap = plugin_data['PSU']['psu_fan_dir'][mode]['valmap'] + if direction in vmap: + airflow_dir_real = vmap[direction] + else: + airflow_dir_real = direction + + return airflow_dir_real + + def get_output_voltage(self, idx): + if idx is None: + return 0.0 + + if idx < 1 or idx > self.platform['num_psus']: + print("Invalid index %d\n" % idx) + return 0.0 + + device = "PSU"+"%d" % (idx) + output = pddf_obj.get_attr_name_output(device, "psu_v_out") + if not output: + return 0.0 + + v_out = output['status'] + + # value returned by the psu driver is in mV + return float(v_out)/1000 + + def get_output_current(self, idx): + if idx is None: + return 0.0 + + if idx < 1 or idx > self.platform['num_psus']: + print("Invalid index %d\n" % idx) + return 0.0 + + device = "PSU"+"%d" % (idx) + output = pddf_obj.get_attr_name_output(device, "psu_i_out") + if not output: + return 0.0 + + i_out = output['status'] + + # current in mA + return float(i_out)/1000 + + def get_output_power(self, idx): + if idx is None: + return 0.0 + + if idx < 1 or idx > self.platform['num_psus']: + print("Invalid index %d\n" % idx) + return 0.0 + + device = "PSU"+"%d" % (idx) + output = pddf_obj.get_attr_name_output(device, "psu_p_out") + if not output: + return 0.0 + + p_out = output['status'] + + # power is returned in micro watts + return float(p_out)/1000000 + + def get_fan_rpm(self, idx, fan_idx): + if idx is None or fan_idx is None: + return 0 + + if idx < 1 or idx > self.platform['num_psus']: + print("Invalid index %d\n" % idx) + return 0 + + device = "PSU"+"%d" % (idx) + num_fans = pddf_obj.get_num_psu_fans(device) + + if fan_idx < 1 or fan_idx > num_fans: + print("Invalid PSU-fan index %d\n" % fan_idx) + return 0 + + output = pddf_obj.get_attr_name_output(device, "psu_fan"+str(fan_idx)+"_speed_rpm") + if not output: + return 0 + + #mode = output['mode'] + output['status'] = output['status'].rstrip() + if output['status'].isalpha(): + return 0 + else: + speed = int(output['status']) + + return speed + + def dump_sysfs(self): + return pddf_obj.cli_dump_dsysfs('psu') diff --git a/device/common/pddf/plugins/sfputil.py b/device/common/pddf/plugins/sfputil.py new file mode 100755 index 000000000000..1ca925610822 --- /dev/null +++ b/device/common/pddf/plugins/sfputil.py @@ -0,0 +1,236 @@ +import os.path +import sys +sys.path.append('/usr/share/sonic/platform/plugins') +import pddfparse +import json + +try: + import time + from ctypes import create_string_buffer + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class SfpUtil(SfpUtilBase): + """Platform generic PDDF SfpUtil class""" + + _port_to_eeprom_mapping = {} + _port_start = 0 + _port_end = 0 + _port_to_type_mapping = {} + _qsfp_ports = [] + _sfp_ports = [] + + def __init__(self): + SfpUtilBase.__init__(self) + global pddf_obj + global plugin_data + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)) + '/../pddf/pd-plugin.json')) as pd: + plugin_data = json.load(pd) + + pddf_obj = pddfparse.PddfParse() + self.platform = pddf_obj.get_platform() + self._port_start = 0 + self._port_end = self.get_num_ports() + + for port_num in range(self._port_start, self._port_end): + device = "PORT" + "%d" % (port_num+1) + port_eeprom_path = pddf_obj.get_path(device, "eeprom") + self._port_to_eeprom_mapping[port_num] = port_eeprom_path + port_type = pddf_obj.get_device_type(device) + self._port_to_type_mapping[port_num] = port_type + self.populate_port_type(port_num) + + def get_num_ports(self): + return int(self.platform['num_ports']) + + def is_valid_port(self, port_num): + if port_num < self._port_start or port_num > self._port_end: + return False + else: + return True + + def get_presence(self, port_num): + if port_num < self._port_start or port_num > self._port_end: + return False + + device = "PORT" + "%d" % (port_num+1) + output = pddf_obj.get_attr_name_output(device, 'xcvr_present') + if not output: + return False + + #mode = output['mode'] + modpres = output['status'].rstrip() + if 'XCVR' in plugin_data: + if 'xcvr_present' in plugin_data['XCVR']: + ptype = self._port_to_type_mapping[port_num] + vtype = 'valmap-'+ptype + if vtype in plugin_data['XCVR']['xcvr_present']: + vmap = plugin_data['XCVR']['xcvr_present'][vtype] + if modpres in vmap: + return vmap[modpres] + else: + return False + # if plugin_data doesn't specify anything regarding Transceivers + if modpres == '1': + return True + + return False + + def populate_port_type(self, port): + if self._port_to_type_mapping[port] == 'QSFP' or self._port_to_type_mapping[port] == 'QSFP28': + self._qsfp_ports.append(port) + elif self._port_to_type_mapping[port] == 'SFP' or self._port_to_type_mapping[port] == 'SFP28': + self._sfp_ports.append(port) + + @property + def port_start(self): + return self._port_start + + @property + def port_end(self): + return (self._port_end - 1) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + @property + def qsfp_ports(self): + return self._qsfp_ports + + def reset(self, port_num): + if port_num < self._port_start or port_num > self._port_end: + return False + + device = "PORT" + "%d" % (port_num+1) + port_ps = pddf_obj.get_path(device, "xcvr_reset") + if port_ps is None: + return False + + try: + reg_file = open(port_ps, 'w') + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + try: + reg_file.seek(0) + reg_file.write('1') + time.sleep(1) + reg_file.seek(0) + reg_file.write('0') + reg_file.close() + return True + except IOError as e: + return False + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + if not self.get_presence(port_num): + return False + + device = "PORT" + "%d" % (port_num+1) + output = pddf_obj.get_attr_name_output(device, 'xcvr_lpmode') + if not output: + if port_num not in self.qsfp_ports: + return False # Read from eeprom only for QSFP ports + try: + eeprom = None + eeprom = open(self.port_to_eeprom_mapping[port_num], "rb") + # check for valid connector type + eeprom.seek(2) + ctype = eeprom.read(1) + if ctype in ['21', '23']: + return False + + eeprom.seek(93) + lpmode = ord(eeprom.read(1)) + + if ((lpmode & 0x3) == 0x3): + return True # Low Power Mode if "Power override" bit is 1 and "Power set" bit is 1 + else: + # High Power Mode if one of the following conditions is matched: + # 1. "Power override" bit is 0 + # 2. "Power override" bit is 1 and "Power set" bit is 0 + return False + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) + else: + #mode = output['mode'] + status = int(output['status'].rstrip()) + + if status == 1: + return True + else: + return False + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + if not self.get_presence(port_num): + return False # Port is not present, unable to set the eeprom + + device = "PORT" + "%d" % (port_num+1) + port_ps = pddf_obj.get_path(device, "xcvr_lpmode") + if port_ps is None: + if port_num not in self.qsfp_ports: + return False # Write to eeprom only for QSFP ports + try: + eeprom = None + eeprom = open(self.port_to_eeprom_mapping[port_num], "r+b") + # check for valid connector type + eeprom.seek(2) + ctype = eeprom.read(1) + if ctype in ['21', '23']: + return False + + # Fill in write buffer + regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode + buffer = create_string_buffer(1) + buffer[0] = chr(regval) + + # Write to eeprom + eeprom.seek(93) + eeprom.write(buffer[0]) + return True + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) + else: + try: + f = open(port_ps, 'w') + if lpmode: + f.write('1') + else: + f.write('0') + f.close() + return True + except IOError as e: + 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 + + def dump_sysfs(self): + return pddf_obj.cli_dump_dsysfs('xcvr') diff --git a/device/common/pddf/plugins/sysstatutil.py b/device/common/pddf/plugins/sysstatutil.py new file mode 100755 index 000000000000..af4dd5915361 --- /dev/null +++ b/device/common/pddf/plugins/sysstatutil.py @@ -0,0 +1,82 @@ +import os.path +import sys +sys.path.append('/usr/share/sonic/platform/plugins') +import pddfparse +import json + + +class SYSStatusUtil(): + """Platform-specific SYSStatus class""" + + def __init__(self): + global pddf_obj + global plugin_data + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)) + '/../pddf/pd-plugin.json')) as pd: + plugin_data = json.load(pd) + + pddf_obj = pddfparse.PddfParse() + + def get_board_info(self): + device = "SYSSTATUS" + node = pddf_obj.get_path(device, "board_info") + if node is None: + return False + try: + with open(node, 'r') as f: + status = f.read() + print("board_info : %s" % status) + except IOError: + return False + + def get_cpld_versio(self): + device = "SYSSTATUS" + node = pddf_obj.get_path(device, "cpld1_version") + if node is None: + return False + try: + with open(node, 'r') as f: + status = f.read() + print("cpld1_version : %s" % status) + except IOError: + return False + + def get_power_module_status(self): + device = "SYSSTATUS" + node = pddf_obj.get_path(device, "power_module_status") + if node is None: + return False + try: + with open(node, 'r') as f: + status = f.read() + print("power_module_status : %s" % status) + except IOError: + return False + + def get_system_reset_status(self): + device = "SYSSTATUS" + for i in range(1, 8): + node = pddf_obj.get_path(device, "system_reset"+str(i)) + if node is None: + return False + try: + with open(node, 'r') as f: + status = f.read() + print("system_reset%s : %s" % (i, status)) + except IOError: + print("system_reset%s not supported" % i) + + def get_misc_status(self): + device = "SYSSTATUS" + for i in range(1, 3): + node = pddf_obj.get_path(device, "misc"+str(i)) + if node is None: + return False + try: + with open(node, 'r') as f: + status = f.read() + print("misc%s : %s" % (i, status)) + except IOError: + print("system_reset%s not supported" % i) + + def dump_sysfs(self): + return pddf_obj.cli_dump_dsysfs('sys-status') diff --git a/device/common/pddf/plugins/thermalutil.py b/device/common/pddf/plugins/thermalutil.py new file mode 100755 index 000000000000..6aef47b7e924 --- /dev/null +++ b/device/common/pddf/plugins/thermalutil.py @@ -0,0 +1,75 @@ +import os.path +import sys +import json +sys.path.append('/usr/share/sonic/platform/plugins') +import pddfparse + + +class ThermalUtil: + def __init__(self): + global pddf_obj + global plugin_data + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)) + '/../pddf/pd-plugin.json')) as pd: + plugin_data = json.load(pd) + + pddf_obj = pddfparse.PddfParse() + self.platform = pddf_obj.get_platform() + self.num_thermals = self.platform['num_temps'] + self.info = [] + + def get_num_thermals(self): + return (self.num_thermals) + + def get_thermal_info(self): + list = [] + pddf_obj.get_device_list(list, "TEMP_SENSOR") + list.sort() + for dev in list: + data = {} + device_name = dev['dev_info']['device_name'] + topo_info = dev['i2c']['topo_info'] + label = "%s-i2c-%d-%x" % (topo_info['dev_type'], + int(topo_info['parent_bus'], 0), int(topo_info['dev_addr'], 0)) + attr_list = dev['i2c']['attr_list'] + data['device_name'] = device_name + data['label'] = label + for attr in attr_list: + attr_name = attr['attr_name'] + node = pddf_obj.get_path(device_name, attr_name) + if node is None: + return False + try: + with open(node, 'r') as f: + attr_value = int(f.read()) + except IOError: + return False + data[attr_name] = attr_value/float(1000) + self.info.append(data) + + def show_thermal_temp_values(self, idx): + if idx < 1 or idx > self.num_thermals: + print("Invalid temperature sensor idx %d" % idx) + return None + self.get_thermal_info() + thermal_name = "TEMP"+"%d" % idx + label = "" + value = "" + for temp in self.info: + if thermal_name == temp['device_name']: + label = temp['label'] + value = "temp1\t %+.1f C (high = %+.1f C, hyst = %+.1f C)" % ( + temp['temp1_input'], temp['temp1_max'], temp['temp1_max_hyst']) + else: + continue + + return (label, value) + + def show_temp_values(self): + self.get_thermal_info() + for temp in self.info: + print(temp['label']) + print("temp1\t %+.1f C (high = %+.1f C, hyst = %+.1f C)" % + (temp['temp1_input'], temp['temp1_max'], temp['temp1_max_hyst'])) + + def dump_sysfs(self): + return pddf_obj.cli_dump_dsysfs('temp-sensors') diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/buffers.json.j2 b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/buffers.json.j2 new file mode 100755 index 000000000000..e6e9e844469b --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/buffers.json.j2 @@ -0,0 +1,3 @@ +{%- set default_topo = 't0' %} +{%- include 'buffers_config.j2' %} + diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/buffers_defaults_t0.j2 b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/buffers_defaults_t0.j2 new file mode 100755 index 000000000000..8243498dd31c --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/buffers_defaults_t0.j2 @@ -0,0 +1,63 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,8) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} + {% for port_idx in range(8,14) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 1)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 3)) %}{% endif %} + {% endfor %} + {% for port_idx in range(14,18) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} + {% for port_idx in range(18,24) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 1)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 3)) %}{% endif %} + {% endfor %} + {% for port_idx in range(24,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/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/buffers_defaults_t1.j2 b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/buffers_defaults_t1.j2 new file mode 100755 index 000000000000..8243498dd31c --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/buffers_defaults_t1.j2 @@ -0,0 +1,63 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,8) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} + {% for port_idx in range(8,14) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 1)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 3)) %}{% endif %} + {% endfor %} + {% for port_idx in range(14,18) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} + {% for port_idx in range(18,24) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 1)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 3)) %}{% endif %} + {% endfor %} + {% for port_idx in range(24,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/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/pg_profile_lookup.ini b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/pg_profile_lookup.ini new file mode 100755 index 000000000000..9f2eacb6fc42 --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/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/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/port_config.ini b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/port_config.ini new file mode 100755 index 000000000000..d999be87623e --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/port_config.ini @@ -0,0 +1,69 @@ +# name lanes alias index speed +Ethernet0 29,30,31,32 fortyGigE0/0 0 40000 +Ethernet4 25,26,27,28 fortyGigE0/4 1 40000 +Ethernet8 37,38,39,40 fortyGigE0/8 2 40000 +Ethernet12 33,34,35,36 fortyGigE0/12 3 40000 +Ethernet16 41,42,43,44 fortyGigE0/16 4 40000 +Ethernet20 45,46,47,48 fortyGigE0/20 5 40000 +Ethernet24 5,6,7,8 fortyGigE0/24 6 40000 +Ethernet28 1,2,3,4 fortyGigE0/28 7 40000 +Ethernet32 9 tenGigE0/32 8 10000 +Ethernet33 10 tenGigE0/33 8 10000 +Ethernet34 11 tenGigE0/34 8 10000 +Ethernet35 12 tenGigE0/35 8 10000 +Ethernet36 13 tenGigE0/36 9 10000 +Ethernet37 14 tenGigE0/37 9 10000 +Ethernet38 15 tenGigE0/38 9 10000 +Ethernet39 16 tenGigE0/39 9 10000 +Ethernet40 21 tenGigE0/40 10 10000 +Ethernet41 22 tenGigE0/41 10 10000 +Ethernet42 23 tenGigE0/42 10 10000 +Ethernet43 24 tenGigE0/43 10 10000 +Ethernet44 17 tenGigE0/44 11 10000 +Ethernet45 18 tenGigE0/45 11 10000 +Ethernet46 19 tenGigE0/46 11 10000 +Ethernet47 20 tenGigE0/47 11 10000 +Ethernet48 49 tenGigE0/48 12 10000 +Ethernet49 50 tenGigE0/49 12 10000 +Ethernet50 51 tenGigE0/50 12 10000 +Ethernet51 52 tenGigE0/51 12 10000 +Ethernet52 53 tenGigE0/52 13 10000 +Ethernet53 54 tenGigE0/53 13 10000 +Ethernet54 55 tenGigE0/54 13 10000 +Ethernet55 56 tenGigE0/55 13 10000 +Ethernet56 61,62,63,64 fortyGigE0/56 14 40000 +Ethernet60 57,58,59,60 fortyGigE0/60 15 40000 +Ethernet64 65,66,67,68 fortyGigE0/64 16 40000 +Ethernet68 69,70,71,72 fortyGigE0/68 17 40000 +Ethernet72 77 tenGigE0/72 18 10000 +Ethernet73 78 tenGigE0/73 18 10000 +Ethernet74 79 tenGigE0/74 18 10000 +Ethernet75 80 tenGigE0/75 18 10000 +Ethernet76 73 tenGigE0/76 19 10000 +Ethernet77 74 tenGigE0/77 19 10000 +Ethernet78 75 tenGigE0/78 19 10000 +Ethernet79 76 tenGigE0/79 19 10000 +Ethernet80 105 tenGigE0/80 20 10000 +Ethernet81 106 tenGigE0/81 20 10000 +Ethernet82 107 tenGigE0/82 20 10000 +Ethernet83 108 tenGigE0/83 20 10000 +Ethernet84 109 tenGigE0/84 21 10000 +Ethernet85 110 tenGigE0/85 21 10000 +Ethernet86 111 tenGigE0/86 21 10000 +Ethernet87 112 tenGigE0/87 21 10000 +Ethernet88 117 tenGigE0/88 22 10000 +Ethernet89 118 tenGigE0/89 22 10000 +Ethernet90 119 tenGigE0/90 22 10000 +Ethernet91 120 tenGigE0/91 22 10000 +Ethernet92 113 tenGigE0/92 23 10000 +Ethernet93 114 tenGigE0/93 23 10000 +Ethernet94 115 tenGigE0/94 23 10000 +Ethernet95 116 tenGigE0/95 23 10000 +Ethernet96 121,122,123,124 fortyGigE0/96 24 40000 +Ethernet100 125,126,127,128 fortyGigE0/100 25 40000 +Ethernet104 85,86,87,88 fortyGigE0/104 26 40000 +Ethernet108 81,82,83,84 fortyGigE0/108 27 40000 +Ethernet112 89,90,91,92 fortyGigE0/112 28 40000 +Ethernet116 93,94,95,96 fortyGigE0/116 29 40000 +Ethernet120 97,98,99,100 fortyGigE0/120 30 40000 +Ethernet124 101,102,103,104 fortyGigE0/124 31 40000 diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/qos.json.j2 b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/qos.json.j2 new file mode 100755 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/sai.profile b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/sai.profile new file mode 100755 index 000000000000..22e114e6af26 --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-20x40G-48x10G.config.bcm +SAI_NUM_ECMP_MEMBERS=32 diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/td2-s6000-20x40G-48x10G.config.bcm b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/td2-s6000-20x40G-48x10G.config.bcm new file mode 100755 index 000000000000..d63f589d4fc9 --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q20S48/td2-s6000-20x40G-48x10G.config.bcm @@ -0,0 +1,755 @@ +# 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=10 +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=0x000000000000001fffffffffffffffff +pbmp_xport_xe=0x000000000000001fffffffffffffffff + +# Ports configuration +# xe0 (40G) +portmap_1=29:40 +xgxs_rx_lane_map_1=0x213 +xgxs_tx_lane_map_1=0x213 +phy_xaui_rx_polarity_flip_1=0xc +phy_xaui_tx_polarity_flip_1=0x9 +serdes_driver_current_lane0_1=0x6 +serdes_driver_current_lane1_1=0x7 +serdes_driver_current_lane2_1=0x6 +serdes_driver_current_lane3_1=0x6 +serdes_pre_driver_current_lane0_1=0x6 +serdes_pre_driver_current_lane1_1=0x7 +serdes_pre_driver_current_lane2_1=0x6 +serdes_pre_driver_current_lane3_1=0x6 +serdes_preemphasis_lane0_1=0xc2f0 +serdes_preemphasis_lane1_1=0xd2b0 +serdes_preemphasis_lane2_1=0xc6e0 +serdes_preemphasis_lane3_1=0xc2f0 + +# xe1 (40G) +portmap_2=25:40 +xgxs_rx_lane_map_2=0x213 +xgxs_tx_lane_map_2=0x2031 +phy_xaui_rx_polarity_flip_2=0xe +phy_xaui_tx_polarity_flip_2=0x2 +serdes_driver_current_lane0_2=0x5 +serdes_driver_current_lane1_2=0x5 +serdes_driver_current_lane2_2=0x5 +serdes_driver_current_lane3_2=0x5 +serdes_pre_driver_current_lane0_2=0x5 +serdes_pre_driver_current_lane1_2=0x5 +serdes_pre_driver_current_lane2_2=0x5 +serdes_pre_driver_current_lane3_2=0x5 +serdes_preemphasis_lane0_2=0xcad0 +serdes_preemphasis_lane1_2=0xc6e0 +serdes_preemphasis_lane2_2=0xc6e0 +serdes_preemphasis_lane3_2=0xd2b0 + +# xe2 (40G) +portmap_3=37:40 +xgxs_rx_lane_map_3=0x213 +xgxs_tx_lane_map_3=0x1203 +phy_xaui_rx_polarity_flip_3=0x3 +phy_xaui_tx_polarity_flip_3=0xe +serdes_driver_current_lane0_3=0x4 +serdes_driver_current_lane1_3=0x4 +serdes_driver_current_lane2_3=0x4 +serdes_driver_current_lane3_3=0x4 +serdes_pre_driver_current_lane0_3=0x4 +serdes_pre_driver_current_lane1_3=0x4 +serdes_pre_driver_current_lane2_3=0x4 +serdes_pre_driver_current_lane3_3=0x4 +serdes_preemphasis_lane0_3=0xcad0 +serdes_preemphasis_lane1_3=0xcad0 +serdes_preemphasis_lane2_3=0xc2f0 +serdes_preemphasis_lane3_3=0xc2f0 + +# xe3 (40G) +portmap_4=33:40 +xgxs_rx_lane_map_4=0x213 +xgxs_tx_lane_map_4=0x132 +phy_xaui_rx_polarity_flip_4=0xe +phy_xaui_tx_polarity_flip_4=0x2 +serdes_driver_current_lane0_4=0x4 +serdes_driver_current_lane1_4=0x4 +serdes_driver_current_lane2_4=0x4 +serdes_driver_current_lane3_4=0x4 +serdes_pre_driver_current_lane0_4=0x4 +serdes_pre_driver_current_lane1_4=0x4 +serdes_pre_driver_current_lane2_4=0x4 +serdes_pre_driver_current_lane3_4=0x4 +serdes_preemphasis_lane0_4=0xc6e0 +serdes_preemphasis_lane1_4=0xc6e0 +serdes_preemphasis_lane2_4=0xc6e0 +serdes_preemphasis_lane3_4=0xc6e0 + +# xe4 (40G) +portmap_5=41:40 +xgxs_rx_lane_map_5=0x213 +xgxs_tx_lane_map_5=0x3021 +phy_xaui_rx_polarity_flip_5=0x3 +phy_xaui_tx_polarity_flip_5=0xb +serdes_driver_current_lane0_5=0x4 +serdes_driver_current_lane1_5=0x4 +serdes_driver_current_lane2_5=0x4 +serdes_driver_current_lane3_5=0x4 +serdes_pre_driver_current_lane0_5=0x4 +serdes_pre_driver_current_lane1_5=0x4 +serdes_pre_driver_current_lane2_5=0x4 +serdes_pre_driver_current_lane3_5=0x4 +serdes_preemphasis_lane0_5=0xc6e0 +serdes_preemphasis_lane1_5=0xc2f0 +serdes_preemphasis_lane2_5=0xc2f0 +serdes_preemphasis_lane3_5=0xcad0 + +# xe5 (40G) +portmap_6=45:40 +xgxs_rx_lane_map_6=0x213 +xgxs_tx_lane_map_6=0x213 +phy_xaui_rx_polarity_flip_6=0xe +phy_xaui_tx_polarity_flip_6=0x8 +serdes_driver_current_lane0_6=0x4 +serdes_driver_current_lane1_6=0x4 +serdes_driver_current_lane2_6=0x4 +serdes_driver_current_lane3_6=0x4 +serdes_pre_driver_current_lane0_6=0x4 +serdes_pre_driver_current_lane1_6=0x4 +serdes_pre_driver_current_lane2_6=0x4 +serdes_pre_driver_current_lane3_6=0x4 +serdes_preemphasis_lane0_6=0xc2f0 +serdes_preemphasis_lane1_6=0xc2f0 +serdes_preemphasis_lane2_6=0xc2f0 +serdes_preemphasis_lane3_6=0xc2f0 + +# xe6 (40G) +portmap_7=5:40 +xgxs_rx_lane_map_7=0x213 +xgxs_tx_lane_map_7=0x1203 +phy_xaui_rx_polarity_flip_7=0xc +phy_xaui_tx_polarity_flip_7=0x1 +serdes_driver_current_lane0_7=0x4 +serdes_driver_current_lane1_7=0x4 +serdes_driver_current_lane2_7=0x4 +serdes_driver_current_lane3_7=0x4 +serdes_pre_driver_current_lane0_7=0x4 +serdes_pre_driver_current_lane1_7=0x4 +serdes_pre_driver_current_lane2_7=0x4 +serdes_pre_driver_current_lane3_7=0x4 +serdes_preemphasis_lane0_7=0xc6e0 +serdes_preemphasis_lane1_7=0xc6e0 +serdes_preemphasis_lane2_7=0xc6e0 +serdes_preemphasis_lane3_7=0xc6e0 + +# xe7 (40G) +portmap_8=1:40 +xgxs_rx_lane_map_8=0x213 +xgxs_tx_lane_map_8=0x2031 +phy_xaui_rx_polarity_flip_8=0xe +phy_xaui_tx_polarity_flip_8=0xd +serdes_driver_current_lane0_8=0x5 +serdes_driver_current_lane1_8=0x5 +serdes_driver_current_lane2_8=0x5 +serdes_driver_current_lane3_8=0x5 +serdes_pre_driver_current_lane0_8=0x5 +serdes_pre_driver_current_lane1_8=0x5 +serdes_pre_driver_current_lane2_8=0x5 +serdes_pre_driver_current_lane3_8=0x5 +serdes_preemphasis_lane0_8=0xc6e0 +serdes_preemphasis_lane1_8=0xcad0 +serdes_preemphasis_lane2_8=0xc6e0 +serdes_preemphasis_lane3_8=0xcad0 + +# xe8 (4x10G) +portmap_9=9:10 +portmap_10=10:10 +portmap_11=11:10 +portmap_12=12:10 +xgxs_rx_lane_map_9=0x3120 +xgxs_tx_lane_map_9=0x3021 +phy_xaui_rx_polarity_flip_9=0x0 +phy_xaui_tx_polarity_flip_9=0x4 +phy_xaui_rx_polarity_flip_10=0x0 +phy_xaui_tx_polarity_flip_10=0x0 +phy_xaui_rx_polarity_flip_11=0x0 +phy_xaui_tx_polarity_flip_11=0x1 +phy_xaui_rx_polarity_flip_12=0x0 +phy_xaui_tx_polarity_flip_12=0x0 +serdes_driver_current_lane0_9=0x3 +serdes_driver_current_lane1_9=0x3 +serdes_driver_current_lane2_9=0x3 +serdes_driver_current_lane3_9=0x3 +serdes_pre_driver_current_lane0_9=0x3 +serdes_pre_driver_current_lane1_9=0x3 +serdes_pre_driver_current_lane2_9=0x3 +serdes_pre_driver_current_lane3_9=0x3 +serdes_preemphasis_lane0_9=0xc2f0 +serdes_preemphasis_lane1_9=0xc6e0 +serdes_preemphasis_lane2_9=0xbf00 +serdes_preemphasis_lane3_9=0xc2f0 + +# xe9 (4x10G) +portmap_13=13:10 +portmap_14=14:10 +portmap_15=15:10 +portmap_16=16:10 +xgxs_rx_lane_map_13=0x213 +xgxs_tx_lane_map_13=0x132 +phy_xaui_rx_polarity_flip_13=0xe +phy_xaui_tx_polarity_flip_13=0x0 +phy_xaui_rx_polarity_flip_14=0x1 +phy_xaui_tx_polarity_flip_14=0x0 +phy_xaui_rx_polarity_flip_15=0x1 +phy_xaui_tx_polarity_flip_15=0x0 +phy_xaui_rx_polarity_flip_16=0x1 +phy_xaui_tx_polarity_flip_16=0x0 +serdes_driver_current_lane0_13=0x2 +serdes_driver_current_lane1_13=0x3 +serdes_driver_current_lane2_13=0x2 +serdes_driver_current_lane3_13=0x2 +serdes_pre_driver_current_lane0_13=0x2 +serdes_pre_driver_current_lane1_13=0x3 +serdes_pre_driver_current_lane2_13=0x2 +serdes_pre_driver_current_lane3_13=0x2 +serdes_preemphasis_lane0_13=0xb270 +serdes_preemphasis_lane1_13=0xbb10 +serdes_preemphasis_lane2_13=0xb720 +serdes_preemphasis_lane3_13=0xb720 + +# xe10 (4x10G) +portmap_17=21:10 +portmap_18=22:10 +portmap_19=23:10 +portmap_20=24:10 +xgxs_rx_lane_map_17=0x123 +xgxs_tx_lane_map_17=0x1203 +phy_xaui_rx_polarity_flip_17=0xc +phy_xaui_tx_polarity_flip_17=0xe +phy_xaui_rx_polarity_flip_18=0x0 +phy_xaui_tx_polarity_flip_18=0x1 +phy_xaui_rx_polarity_flip_19=0x1 +phy_xaui_tx_polarity_flip_19=0x1 +phy_xaui_rx_polarity_flip_20=0x1 +phy_xaui_tx_polarity_flip_20=0x1 +serdes_driver_current_lane0_17=0x2 +serdes_driver_current_lane1_17=0x2 +serdes_driver_current_lane2_17=0x2 +serdes_driver_current_lane3_17=0x2 +serdes_pre_driver_current_lane0_17=0x2 +serdes_pre_driver_current_lane1_17=0x2 +serdes_pre_driver_current_lane2_17=0x2 +serdes_pre_driver_current_lane3_17=0x2 +serdes_preemphasis_lane0_17=0xb330 +serdes_preemphasis_lane1_17=0xb330 +serdes_preemphasis_lane2_17=0xb330 +serdes_preemphasis_lane3_17=0xb330 + +# xe11 (4x10G) +portmap_21=17:10 +portmap_22=18:10 +portmap_23=19:10 +portmap_24=20:10 +xgxs_rx_lane_map_21=0x213 +xgxs_tx_lane_map_21=0x132 +phy_xaui_rx_polarity_flip_21=0xe +phy_xaui_tx_polarity_flip_21=0x0 +phy_xaui_rx_polarity_flip_22=0x1 +phy_xaui_tx_polarity_flip_22=0x0 +phy_xaui_rx_polarity_flip_23=0x1 +phy_xaui_tx_polarity_flip_23=0x0 +phy_xaui_rx_polarity_flip_24=0x1 +phy_xaui_tx_polarity_flip_24=0x0 +serdes_driver_current_lane0_21=0x2 +serdes_driver_current_lane1_21=0x2 +serdes_driver_current_lane2_21=0x2 +serdes_driver_current_lane3_21=0x2 +serdes_pre_driver_current_lane0_21=0x2 +serdes_pre_driver_current_lane1_21=0x2 +serdes_pre_driver_current_lane2_21=0x2 +serdes_pre_driver_current_lane3_21=0x2 +serdes_preemphasis_lane0_21=0xb330 +serdes_preemphasis_lane1_21=0xbb10 +serdes_preemphasis_lane2_21=0xbb10 +serdes_preemphasis_lane3_21=0xbb10 + +# xe12 (4x10G) +portmap_25=49:10 +portmap_26=50:10 +portmap_27=51:10 +portmap_28=52:10 +xgxs_rx_lane_map_25=0x1302 +xgxs_tx_lane_map_25=0x2031 +phy_xaui_rx_polarity_flip_25=0xb +phy_xaui_tx_polarity_flip_25=0x3 +phy_xaui_rx_polarity_flip_26=0x1 +phy_xaui_tx_polarity_flip_26=0x1 +phy_xaui_rx_polarity_flip_27=0x0 +phy_xaui_tx_polarity_flip_27=0x0 +phy_xaui_rx_polarity_flip_28=0x1 +phy_xaui_tx_polarity_flip_28=0x0 +serdes_driver_current_lane0_25=0x2 +serdes_driver_current_lane1_25=0x2 +serdes_driver_current_lane2_25=0x2 +serdes_driver_current_lane3_25=0x2 +serdes_pre_driver_current_lane0_25=0x2 +serdes_pre_driver_current_lane1_25=0x2 +serdes_pre_driver_current_lane2_25=0x2 +serdes_pre_driver_current_lane3_25=0x2 +serdes_preemphasis_lane0_25=0xa760 +serdes_preemphasis_lane1_25=0xa760 +serdes_preemphasis_lane2_25=0xa760 +serdes_preemphasis_lane3_25=0xa760 + +# xe13 (4x10G) +portmap_29=53:10 +portmap_30=54:10 +portmap_31=55:10 +portmap_32=56:10 +xgxs_rx_lane_map_29=0x213 +xgxs_tx_lane_map_29=0x231 +phy_xaui_rx_polarity_flip_29=0x1 +phy_xaui_tx_polarity_flip_29=0x0 +phy_xaui_rx_polarity_flip_30=0x0 +phy_xaui_tx_polarity_flip_30=0x0 +phy_xaui_rx_polarity_flip_31=0x0 +phy_xaui_tx_polarity_flip_31=0x0 +phy_xaui_rx_polarity_flip_32=0x0 +phy_xaui_tx_polarity_flip_32=0x0 +serdes_driver_current_lane0_29=0x2 +serdes_driver_current_lane1_29=0x2 +serdes_driver_current_lane2_29=0x2 +serdes_driver_current_lane3_29=0x2 +serdes_pre_driver_current_lane0_29=0x2 +serdes_pre_driver_current_lane1_29=0x2 +serdes_pre_driver_current_lane2_29=0x2 +serdes_pre_driver_current_lane3_29=0x2 +serdes_preemphasis_lane0_29=0xaf40 +serdes_preemphasis_lane1_29=0xaf40 +serdes_preemphasis_lane2_29=0xaf40 +serdes_preemphasis_lane3_29=0xaf40 + +# xe14 (40G) +portmap_33=61:40 +xgxs_rx_lane_map_33=0x132 +xgxs_tx_lane_map_33=0x213 +phy_xaui_rx_polarity_flip_33=0x0 +phy_xaui_tx_polarity_flip_33=0x0 +serdes_driver_current_lane0_33=0x2 +serdes_driver_current_lane1_33=0x2 +serdes_driver_current_lane2_33=0x2 +serdes_driver_current_lane3_33=0x2 +serdes_pre_driver_current_lane0_33=0x2 +serdes_pre_driver_current_lane1_33=0x2 +serdes_pre_driver_current_lane2_33=0x2 +serdes_pre_driver_current_lane3_33=0x2 +serdes_preemphasis_lane0_33=0xa760 +serdes_preemphasis_lane1_33=0xa760 +serdes_preemphasis_lane2_33=0xa760 +serdes_preemphasis_lane3_33=0xa760 + +# xe15 (40G) +portmap_34=57:40 +xgxs_rx_lane_map_34=0x213 +xgxs_tx_lane_map_34=0x2031 +phy_xaui_rx_polarity_flip_34=0x1 +phy_xaui_tx_polarity_flip_34=0x0 +serdes_driver_current_lane0_34=0x1 +serdes_driver_current_lane1_34=0x1 +serdes_driver_current_lane2_34=0x1 +serdes_driver_current_lane3_34=0x1 +serdes_pre_driver_current_lane0_34=0x1 +serdes_pre_driver_current_lane1_34=0x1 +serdes_pre_driver_current_lane2_34=0x1 +serdes_pre_driver_current_lane3_34=0x1 +serdes_preemphasis_lane0_34=0xa760 +serdes_preemphasis_lane1_34=0xa760 +serdes_preemphasis_lane2_34=0xa760 +serdes_preemphasis_lane3_34=0xa760 + +# xe16 (40G) +portmap_35=65:40 +xgxs_rx_lane_map_35=0x132 +xgxs_tx_lane_map_35=0x2031 +phy_xaui_rx_polarity_flip_35=0x3 +phy_xaui_tx_polarity_flip_35=0x9 +serdes_driver_current_lane0_35=0x1 +serdes_driver_current_lane1_35=0x1 +serdes_driver_current_lane2_35=0x1 +serdes_driver_current_lane3_35=0x1 +serdes_pre_driver_current_lane0_35=0x1 +serdes_pre_driver_current_lane1_35=0x1 +serdes_pre_driver_current_lane2_35=0x1 +serdes_pre_driver_current_lane3_35=0x1 +serdes_preemphasis_lane0_35=0xa370 +serdes_preemphasis_lane1_35=0xa370 +serdes_preemphasis_lane2_35=0xa370 +serdes_preemphasis_lane3_35=0xa370 + +# xe17 (40G) +portmap_36=69:40 +xgxs_rx_lane_map_36=0x213 +xgxs_tx_lane_map_36=0x2130 +phy_xaui_rx_polarity_flip_36=0x1 +phy_xaui_tx_polarity_flip_36=0xf +serdes_driver_current_lane0_36=0x1 +serdes_driver_current_lane1_36=0x1 +serdes_driver_current_lane2_36=0x1 +serdes_driver_current_lane3_36=0x1 +serdes_pre_driver_current_lane0_36=0x1 +serdes_pre_driver_current_lane1_36=0x1 +serdes_pre_driver_current_lane2_36=0x1 +serdes_pre_driver_current_lane3_36=0x1 +serdes_preemphasis_lane0_36=0xa760 +serdes_preemphasis_lane1_36=0xa760 +serdes_preemphasis_lane2_36=0xa760 +serdes_preemphasis_lane3_36=0xa760 + +# xe18 (4x10G) +portmap_37=77:10 +portmap_38=78:10 +portmap_39=79:10 +portmap_40=80:10 +xgxs_rx_lane_map_37=0x123 +xgxs_tx_lane_map_37=0x1203 +phy_xaui_rx_polarity_flip_37=0x3 +phy_xaui_tx_polarity_flip_37=0xe +phy_xaui_rx_polarity_flip_38=0x1 +phy_xaui_tx_polarity_flip_38=0x1 +phy_xaui_rx_polarity_flip_39=0x0 +phy_xaui_tx_polarity_flip_39=0x1 +phy_xaui_rx_polarity_flip_40=0x0 +phy_xaui_tx_polarity_flip_40=0x1 +serdes_driver_current_lane0_37=0x2 +serdes_driver_current_lane1_37=0x2 +serdes_driver_current_lane2_37=0x2 +serdes_driver_current_lane3_37=0x2 +serdes_pre_driver_current_lane0_37=0x2 +serdes_pre_driver_current_lane1_37=0x2 +serdes_pre_driver_current_lane2_37=0x2 +serdes_pre_driver_current_lane3_37=0x2 +serdes_preemphasis_lane0_37=0xaf40 +serdes_preemphasis_lane1_37=0xaf40 +serdes_preemphasis_lane2_37=0xaf40 +serdes_preemphasis_lane3_37=0xaf40 + +# xe19 (4x10G) +portmap_41=73:10 +portmap_42=74:10 +portmap_43=75:10 +portmap_44=76:10 +xgxs_rx_lane_map_41=0x213 +xgxs_tx_lane_map_41=0x2031 +phy_xaui_rx_polarity_flip_41=0x1 +phy_xaui_tx_polarity_flip_41=0x0 +phy_xaui_rx_polarity_flip_42=0x0 +phy_xaui_tx_polarity_flip_42=0x0 +phy_xaui_rx_polarity_flip_43=0x0 +phy_xaui_tx_polarity_flip_43=0x0 +phy_xaui_rx_polarity_flip_44=0x0 +phy_xaui_tx_polarity_flip_44=0x0 +serdes_driver_current_lane0_41=0x2 +serdes_driver_current_lane1_41=0x2 +serdes_driver_current_lane2_41=0x2 +serdes_driver_current_lane3_41=0x2 +serdes_pre_driver_current_lane0_41=0x2 +serdes_pre_driver_current_lane1_41=0x2 +serdes_pre_driver_current_lane2_41=0x2 +serdes_pre_driver_current_lane3_41=0x2 +serdes_preemphasis_lane0_41=0xa760 +serdes_preemphasis_lane1_41=0xa760 +serdes_preemphasis_lane2_41=0xa760 +serdes_preemphasis_lane3_41=0xa760 + +# xe20 (4x10G) +portmap_45=105:10 +portmap_46=106:10 +portmap_47=107:10 +portmap_48=108:10 +xgxs_rx_lane_map_45=0x1320 +xgxs_tx_lane_map_45=0x3021 +phy_xaui_rx_polarity_flip_45=0xd +phy_xaui_tx_polarity_flip_45=0xb +phy_xaui_rx_polarity_flip_46=0x0 +phy_xaui_tx_polarity_flip_46=0x1 +phy_xaui_rx_polarity_flip_47=0x1 +phy_xaui_tx_polarity_flip_47=0x0 +phy_xaui_rx_polarity_flip_48=0x1 +phy_xaui_tx_polarity_flip_48=0x1 +serdes_driver_current_lane0_45=0x1 +serdes_driver_current_lane1_45=0x1 +serdes_driver_current_lane2_45=0x1 +serdes_driver_current_lane3_45=0x1 +serdes_pre_driver_current_lane0_45=0x1 +serdes_pre_driver_current_lane1_45=0x1 +serdes_pre_driver_current_lane2_45=0x1 +serdes_pre_driver_current_lane3_45=0x1 +serdes_preemphasis_lane0_45=0xb330 +serdes_preemphasis_lane1_45=0xb330 +serdes_preemphasis_lane2_45=0xb330 +serdes_preemphasis_lane3_45=0xb330 + +# xe21 (4x10G) +portmap_49=109:10 +portmap_50=110:10 +portmap_51=111:10 +portmap_52=112:10 +xgxs_rx_lane_map_49=0x132 +xgxs_tx_lane_map_49=0x132 +phy_xaui_rx_polarity_flip_49=0x8 +phy_xaui_tx_polarity_flip_49=0x0 +phy_xaui_rx_polarity_flip_50=0x0 +phy_xaui_tx_polarity_flip_50=0x0 +phy_xaui_rx_polarity_flip_51=0x0 +phy_xaui_tx_polarity_flip_51=0x0 +phy_xaui_rx_polarity_flip_52=0x1 +phy_xaui_tx_polarity_flip_52=0x0 +serdes_driver_current_lane0_49=0x1 +serdes_driver_current_lane1_49=0x1 +serdes_driver_current_lane2_49=0x1 +serdes_driver_current_lane3_49=0x2 +serdes_pre_driver_current_lane0_49=0x1 +serdes_pre_driver_current_lane1_49=0x1 +serdes_pre_driver_current_lane2_49=0x1 +serdes_pre_driver_current_lane3_49=0x2 +serdes_preemphasis_lane0_49=0xb330 +serdes_preemphasis_lane1_49=0xb330 +serdes_preemphasis_lane2_49=0xb330 +serdes_preemphasis_lane3_49=0xbff0 + +# xe22 (4x10G) +portmap_53=117:10 +portmap_54=118:10 +portmap_55=119:10 +portmap_56=120:10 +xgxs_rx_lane_map_53=0x231 +xgxs_tx_lane_map_53=0x1203 +phy_xaui_rx_polarity_flip_53=0x3 +phy_xaui_tx_polarity_flip_53=0xe +phy_xaui_rx_polarity_flip_54=0x1 +phy_xaui_tx_polarity_flip_54=0x1 +phy_xaui_rx_polarity_flip_55=0x0 +phy_xaui_tx_polarity_flip_55=0x1 +phy_xaui_rx_polarity_flip_56=0x0 +phy_xaui_tx_polarity_flip_56=0x1 +serdes_driver_current_lane0_53=0x3 +serdes_driver_current_lane1_53=0x5 +serdes_driver_current_lane2_53=0x3 +serdes_driver_current_lane3_53=0x3 +serdes_pre_driver_current_lane0_53=0x3 +serdes_pre_driver_current_lane1_53=0x5 +serdes_pre_driver_current_lane2_53=0x3 +serdes_pre_driver_current_lane3_53=0x3 +serdes_preemphasis_lane0_53=0xc6e0 +serdes_preemphasis_lane1_53=0xc6e0 +serdes_preemphasis_lane2_53=0xc6e0 +serdes_preemphasis_lane3_53=0xc6e0 + +# xe23 (4x10G) +portmap_57=113:10 +portmap_58=114:10 +portmap_59=115:10 +portmap_60=116:10 +xgxs_rx_lane_map_57=0x132 +xgxs_tx_lane_map_57=0x132 +phy_xaui_rx_polarity_flip_57=0x8 +phy_xaui_tx_polarity_flip_57=0x0 +phy_xaui_rx_polarity_flip_58=0x0 +phy_xaui_tx_polarity_flip_58=0x0 +phy_xaui_rx_polarity_flip_59=0x0 +phy_xaui_tx_polarity_flip_59=0x0 +phy_xaui_rx_polarity_flip_60=0x1 +phy_xaui_tx_polarity_flip_60=0x0 +serdes_driver_current_lane0_57=0x1 +serdes_driver_current_lane1_57=0x1 +serdes_driver_current_lane2_57=0x1 +serdes_driver_current_lane3_57=0x1 +serdes_pre_driver_current_lane0_57=0x1 +serdes_pre_driver_current_lane1_57=0x1 +serdes_pre_driver_current_lane2_57=0x1 +serdes_pre_driver_current_lane3_57=0x1 +serdes_preemphasis_lane0_57=0xbb10 +serdes_preemphasis_lane1_57=0xbb10 +serdes_preemphasis_lane2_57=0xbb10 +serdes_preemphasis_lane3_57=0xc2f0 + +# xe24 (40G) +portmap_61=121:40 +xgxs_rx_lane_map_61=0x1320 +xgxs_tx_lane_map_61=0x3021 +phy_xaui_rx_polarity_flip_61=0xd +phy_xaui_tx_polarity_flip_61=0xb +serdes_driver_current_lane0_61=0x4 +serdes_driver_current_lane1_61=0x4 +serdes_driver_current_lane2_61=0x4 +serdes_driver_current_lane3_61=0x4 +serdes_pre_driver_current_lane0_61=0x4 +serdes_pre_driver_current_lane1_61=0x4 +serdes_pre_driver_current_lane2_61=0x4 +serdes_pre_driver_current_lane3_61=0x4 +serdes_preemphasis_lane0_61=0xc6e0 +serdes_preemphasis_lane1_61=0xc6e0 +serdes_preemphasis_lane2_61=0xc6e0 +serdes_preemphasis_lane3_61=0xc6e0 + +# xe25 (40G) +portmap_62=125:40 +xgxs_rx_lane_map_62=0x132 +xgxs_tx_lane_map_62=0x132 +phy_xaui_rx_polarity_flip_62=0x8 +phy_xaui_tx_polarity_flip_62=0x0 +serdes_driver_current_lane0_62=0x4 +serdes_driver_current_lane1_62=0x4 +serdes_driver_current_lane2_62=0x4 +serdes_driver_current_lane3_62=0x4 +serdes_pre_driver_current_lane0_62=0x4 +serdes_pre_driver_current_lane1_62=0x4 +serdes_pre_driver_current_lane2_62=0x4 +serdes_pre_driver_current_lane3_62=0x4 +serdes_preemphasis_lane0_62=0xc6e0 +serdes_preemphasis_lane1_62=0xc6e0 +serdes_preemphasis_lane2_62=0xc6e0 +serdes_preemphasis_lane3_62=0xcec0 + +# xe26 (40G) +portmap_63=85:40 +xgxs_rx_lane_map_63=0x213 +xgxs_tx_lane_map_63=0x1203 +phy_xaui_rx_polarity_flip_63=0xc +phy_xaui_tx_polarity_flip_63=0xe +serdes_driver_current_lane0_63=0x4 +serdes_driver_current_lane1_63=0x5 +serdes_driver_current_lane2_63=0x4 +serdes_driver_current_lane3_63=0x5 +serdes_pre_driver_current_lane0_63=0x4 +serdes_pre_driver_current_lane1_63=0x5 +serdes_pre_driver_current_lane2_63=0x4 +serdes_pre_driver_current_lane3_63=0x5 +serdes_preemphasis_lane0_63=0xc2f0 +serdes_preemphasis_lane1_63=0xc6e0 +serdes_preemphasis_lane2_63=0xc6e0 +serdes_preemphasis_lane3_63=0xc6e0 + +# xe27 (40G) +portmap_64=81:40 +xgxs_rx_lane_map_64=0x1320 +xgxs_tx_lane_map_64=0x2031 +phy_xaui_rx_polarity_flip_64=0x1 +phy_xaui_tx_polarity_flip_64=0x2 +serdes_driver_current_lane0_64=0x2 +serdes_driver_current_lane1_64=0x2 +serdes_driver_current_lane2_64=0x2 +serdes_driver_current_lane3_64=0x2 +serdes_pre_driver_current_lane0_64=0x2 +serdes_pre_driver_current_lane1_64=0x2 +serdes_pre_driver_current_lane2_64=0x2 +serdes_pre_driver_current_lane3_64=0x2 +serdes_preemphasis_lane0_64=0xbb10 +serdes_preemphasis_lane1_64=0xbb10 +serdes_preemphasis_lane2_64=0xbf00 +serdes_preemphasis_lane3_64=0xbb10 + +# xe28 (40G) +portmap_65=89:40 +xgxs_rx_lane_map_65=0x1320 +xgxs_tx_lane_map_65=0x3021 +phy_xaui_rx_polarity_flip_65=0x2 +phy_xaui_tx_polarity_flip_65=0xb +serdes_driver_current_lane0_65=0x4 +serdes_driver_current_lane1_65=0x4 +serdes_driver_current_lane2_65=0x4 +serdes_driver_current_lane3_65=0x4 +serdes_pre_driver_current_lane0_65=0x4 +serdes_pre_driver_current_lane1_65=0x4 +serdes_pre_driver_current_lane2_65=0x4 +serdes_pre_driver_current_lane3_65=0x4 +serdes_preemphasis_lane0_65=0xcad0 +serdes_preemphasis_lane1_65=0xc6e0 +serdes_preemphasis_lane2_65=0xc6e0 +serdes_preemphasis_lane3_65=0xc6e0 + +# xe29 (40G) +portmap_66=93:40 +xgxs_rx_lane_map_66=0x1320 +xgxs_tx_lane_map_66=0x2031 +phy_xaui_rx_polarity_flip_66=0x1 +phy_xaui_tx_polarity_flip_66=0x2 +serdes_driver_current_lane0_66=0x4 +serdes_driver_current_lane1_66=0x4 +serdes_driver_current_lane2_66=0x4 +serdes_driver_current_lane3_66=0x4 +serdes_pre_driver_current_lane0_66=0x4 +serdes_pre_driver_current_lane1_66=0x4 +serdes_pre_driver_current_lane2_66=0x4 +serdes_pre_driver_current_lane3_66=0x4 +serdes_preemphasis_lane0_66=0xc2f0 +serdes_preemphasis_lane1_66=0xc2f0 +serdes_preemphasis_lane2_66=0xc2f0 +serdes_preemphasis_lane3_66=0xc2f0 + +# xe30 (40G) +portmap_67=97:40 +xgxs_rx_lane_map_67=0x213 +xgxs_tx_lane_map_67=0x2031 +phy_xaui_rx_polarity_flip_67=0xc +phy_xaui_tx_polarity_flip_67=0x3 +serdes_driver_current_lane0_67=0x5 +serdes_driver_current_lane1_67=0x5 +serdes_driver_current_lane2_67=0x5 +serdes_driver_current_lane3_67=0x5 +serdes_pre_driver_current_lane0_67=0x5 +serdes_pre_driver_current_lane1_67=0x5 +serdes_pre_driver_current_lane2_67=0x5 +serdes_pre_driver_current_lane3_67=0x5 +serdes_preemphasis_lane0_67=0xcad0 +serdes_preemphasis_lane1_67=0xcad0 +serdes_preemphasis_lane2_67=0xcad0 +serdes_preemphasis_lane3_67=0xcad0 + +# xe31 (40G) +portmap_68=101:40 +xgxs_rx_lane_map_68=0x1320 +xgxs_tx_lane_map_68=0x1203 +phy_xaui_rx_polarity_flip_68=0x1 +phy_xaui_tx_polarity_flip_68=0x6 +serdes_driver_current_lane0_68=0x6 +serdes_driver_current_lane1_68=0x6 +serdes_driver_current_lane2_68=0x6 +serdes_driver_current_lane3_68=0x7 +serdes_pre_driver_current_lane0_68=0x6 +serdes_pre_driver_current_lane1_68=0x6 +serdes_pre_driver_current_lane2_68=0x6 +serdes_pre_driver_current_lane3_68=0x7 +serdes_preemphasis_lane0_68=0xcec0 +serdes_preemphasis_lane1_68=0xcec0 +serdes_preemphasis_lane2_68=0xcad0 +serdes_preemphasis_lane3_68=0xc6e0 + diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/buffers.json.j2 b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/buffers.json.j2 new file mode 100755 index 000000000000..b67cf577ab75 --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/buffers.json.j2 @@ -0,0 +1,3 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} + diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/buffers_defaults_t0.j2 b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/buffers_defaults_t0.j2 new file mode 100755 index 000000000000..9d37f8a579db --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/buffers_defaults_t0.j2 @@ -0,0 +1,55 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,16) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} + {% for port_idx in range(16,25) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 1)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 3)) %}{% endif %} + + {% endfor %} + {% for port_idx in range(25,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/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/buffers_defaults_t1.j2 b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/buffers_defaults_t1.j2 new file mode 100755 index 000000000000..9d37f8a579db --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/buffers_defaults_t1.j2 @@ -0,0 +1,55 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,16) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} + {% for port_idx in range(16,25) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 1)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 3)) %}{% endif %} + + {% endfor %} + {% for port_idx in range(25,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/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/pg_profile_lookup.ini b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/pg_profile_lookup.ini new file mode 100755 index 000000000000..9f2eacb6fc42 --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/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/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/port_config.ini b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/port_config.ini new file mode 100755 index 000000000000..b238104455f7 --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/port_config.ini @@ -0,0 +1,57 @@ +# name lanes alias index speed +Ethernet0 29,30,31,32 fortyGigE0/0 0 40000 +Ethernet4 25,26,27,28 fortyGigE0/4 1 40000 +Ethernet8 37,38,39,40 fortyGigE0/8 2 40000 +Ethernet12 33,34,35,36 fortyGigE0/12 3 40000 +Ethernet16 41,42,43,44 fortyGigE0/16 4 40000 +Ethernet20 45,46,47,48 fortyGigE0/20 5 40000 +Ethernet24 5,6,7,8 fortyGigE0/24 6 40000 +Ethernet28 1,2,3,4 fortyGigE0/28 7 40000 +Ethernet32 9,10,11,12 fortyGigE0/32 8 40000 +Ethernet36 13,14,15,16 fortyGigE0/36 9 40000 +Ethernet40 21,22,23,24 fortyGigE0/40 10 40000 +Ethernet44 17,18,19,20 fortyGigE0/44 11 40000 +Ethernet48 49,50,51,52 fortyGigE0/48 12 40000 +Ethernet52 53,54,55,56 fortyGigE0/52 13 40000 +Ethernet56 61,62,63,64 fortyGigE0/56 14 40000 +Ethernet60 57,58,59,60 fortyGigE0/60 15 40000 +Ethernet64 65 tenGigE0/64 16 10000 +Ethernet65 66 tenGigE0/65 16 10000 +Ethernet66 67 tenGigE0/66 16 10000 +Ethernet67 68 tenGigE0/67 16 10000 +Ethernet68 69 tenGigE0/68 17 10000 +Ethernet69 70 tenGigE0/69 17 10000 +Ethernet70 71 tenGigE0/70 17 10000 +Ethernet71 72 tenGigE0/71 17 10000 +Ethernet72 77 tenGigE0/72 18 10000 +Ethernet73 78 tenGigE0/73 18 10000 +Ethernet74 79 tenGigE0/74 18 10000 +Ethernet75 80 tenGigE0/75 18 10000 +Ethernet76 73 tenGigE0/76 19 10000 +Ethernet77 74 tenGigE0/77 19 10000 +Ethernet78 75 tenGigE0/78 19 10000 +Ethernet79 76 tenGigE0/79 19 10000 +Ethernet80 105 tenGigE0/80 20 10000 +Ethernet81 106 tenGigE0/81 20 10000 +Ethernet82 107 tenGigE0/82 20 10000 +Ethernet83 108 tenGigE0/83 20 10000 +Ethernet84 109 tenGigE0/84 21 10000 +Ethernet85 110 tenGigE0/85 21 10000 +Ethernet86 111 tenGigE0/86 21 10000 +Ethernet87 112 tenGigE0/87 21 10000 +Ethernet88 117 tenGigE0/88 22 10000 +Ethernet89 118 tenGigE0/89 22 10000 +Ethernet90 119 tenGigE0/90 22 10000 +Ethernet91 120 tenGigE0/91 22 10000 +Ethernet92 113 tenGigE0/92 23 10000 +Ethernet93 114 tenGigE0/93 23 10000 +Ethernet94 115 tenGigE0/94 23 10000 +Ethernet95 116 tenGigE0/95 23 10000 +Ethernet96 121,122,123,124 fortyGigE0/96 24 40000 +Ethernet100 125,126,127,128 fortyGigE0/100 25 40000 +Ethernet104 85,86,87,88 fortyGigE0/104 26 40000 +Ethernet108 81,82,83,84 fortyGigE0/108 27 40000 +Ethernet112 89,90,91,92 fortyGigE0/112 28 40000 +Ethernet116 93,94,95,96 fortyGigE0/116 29 40000 +Ethernet120 97,98,99,100 fortyGigE0/120 30 40000 +Ethernet124 101,102,103,104 fortyGigE0/124 31 40000 diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/qos.json.j2 b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/qos.json.j2 new file mode 100755 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/sai.profile b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/sai.profile new file mode 100755 index 000000000000..3335af4b9bf5 --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-24x40G-32x10G.config.bcm +SAI_NUM_ECMP_MEMBERS=32 diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/td2-s6000-24x40G-32x10G.config.bcm b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/td2-s6000-24x40G-32x10G.config.bcm new file mode 100755 index 000000000000..5734e9ee5b1d --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q24S32/td2-s6000-24x40G-32x10G.config.bcm @@ -0,0 +1,719 @@ +# 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=10 +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=0x000001fffffffffffffffffffff +pbmp_xport_xe=0x000001fffffffffffffffffffff + +# Ports configuration +# xe0 (40G) +portmap_1=29:40 +xgxs_rx_lane_map_1=0x213 +xgxs_tx_lane_map_1=0x213 +phy_xaui_rx_polarity_flip_1=0xc +phy_xaui_tx_polarity_flip_1=0x9 +serdes_driver_current_lane0_1=0x6 +serdes_driver_current_lane1_1=0x7 +serdes_driver_current_lane2_1=0x6 +serdes_driver_current_lane3_1=0x6 +serdes_pre_driver_current_lane0_1=0x6 +serdes_pre_driver_current_lane1_1=0x7 +serdes_pre_driver_current_lane2_1=0x6 +serdes_pre_driver_current_lane3_1=0x6 +serdes_preemphasis_lane0_1=0xc2f0 +serdes_preemphasis_lane1_1=0xd2b0 +serdes_preemphasis_lane2_1=0xc6e0 +serdes_preemphasis_lane3_1=0xc2f0 + +# xe1 (40G) +portmap_2=25:40 +xgxs_rx_lane_map_2=0x213 +xgxs_tx_lane_map_2=0x2031 +phy_xaui_rx_polarity_flip_2=0xe +phy_xaui_tx_polarity_flip_2=0x2 +serdes_driver_current_lane0_2=0x5 +serdes_driver_current_lane1_2=0x5 +serdes_driver_current_lane2_2=0x5 +serdes_driver_current_lane3_2=0x5 +serdes_pre_driver_current_lane0_2=0x5 +serdes_pre_driver_current_lane1_2=0x5 +serdes_pre_driver_current_lane2_2=0x5 +serdes_pre_driver_current_lane3_2=0x5 +serdes_preemphasis_lane0_2=0xcad0 +serdes_preemphasis_lane1_2=0xc6e0 +serdes_preemphasis_lane2_2=0xc6e0 +serdes_preemphasis_lane3_2=0xd2b0 + +# xe2 (40G) +portmap_3=37:40 +xgxs_rx_lane_map_3=0x213 +xgxs_tx_lane_map_3=0x1203 +phy_xaui_rx_polarity_flip_3=0x3 +phy_xaui_tx_polarity_flip_3=0xe +serdes_driver_current_lane0_3=0x4 +serdes_driver_current_lane1_3=0x4 +serdes_driver_current_lane2_3=0x4 +serdes_driver_current_lane3_3=0x4 +serdes_pre_driver_current_lane0_3=0x4 +serdes_pre_driver_current_lane1_3=0x4 +serdes_pre_driver_current_lane2_3=0x4 +serdes_pre_driver_current_lane3_3=0x4 +serdes_preemphasis_lane0_3=0xcad0 +serdes_preemphasis_lane1_3=0xcad0 +serdes_preemphasis_lane2_3=0xc2f0 +serdes_preemphasis_lane3_3=0xc2f0 + +# xe3 (40G) +portmap_4=33:40 +xgxs_rx_lane_map_4=0x213 +xgxs_tx_lane_map_4=0x132 +phy_xaui_rx_polarity_flip_4=0xe +phy_xaui_tx_polarity_flip_4=0x2 +serdes_driver_current_lane0_4=0x4 +serdes_driver_current_lane1_4=0x4 +serdes_driver_current_lane2_4=0x4 +serdes_driver_current_lane3_4=0x4 +serdes_pre_driver_current_lane0_4=0x4 +serdes_pre_driver_current_lane1_4=0x4 +serdes_pre_driver_current_lane2_4=0x4 +serdes_pre_driver_current_lane3_4=0x4 +serdes_preemphasis_lane0_4=0xc6e0 +serdes_preemphasis_lane1_4=0xc6e0 +serdes_preemphasis_lane2_4=0xc6e0 +serdes_preemphasis_lane3_4=0xc6e0 + +# xe4 (40G) +portmap_5=41:40 +xgxs_rx_lane_map_5=0x213 +xgxs_tx_lane_map_5=0x3021 +phy_xaui_rx_polarity_flip_5=0x3 +phy_xaui_tx_polarity_flip_5=0xb +serdes_driver_current_lane0_5=0x4 +serdes_driver_current_lane1_5=0x4 +serdes_driver_current_lane2_5=0x4 +serdes_driver_current_lane3_5=0x4 +serdes_pre_driver_current_lane0_5=0x4 +serdes_pre_driver_current_lane1_5=0x4 +serdes_pre_driver_current_lane2_5=0x4 +serdes_pre_driver_current_lane3_5=0x4 +serdes_preemphasis_lane0_5=0xc6e0 +serdes_preemphasis_lane1_5=0xc2f0 +serdes_preemphasis_lane2_5=0xc2f0 +serdes_preemphasis_lane3_5=0xcad0 + +# xe5 (40G) +portmap_6=45:40 +xgxs_rx_lane_map_6=0x213 +xgxs_tx_lane_map_6=0x213 +phy_xaui_rx_polarity_flip_6=0xe +phy_xaui_tx_polarity_flip_6=0x8 +serdes_driver_current_lane0_6=0x4 +serdes_driver_current_lane1_6=0x4 +serdes_driver_current_lane2_6=0x4 +serdes_driver_current_lane3_6=0x4 +serdes_pre_driver_current_lane0_6=0x4 +serdes_pre_driver_current_lane1_6=0x4 +serdes_pre_driver_current_lane2_6=0x4 +serdes_pre_driver_current_lane3_6=0x4 +serdes_preemphasis_lane0_6=0xc2f0 +serdes_preemphasis_lane1_6=0xc2f0 +serdes_preemphasis_lane2_6=0xc2f0 +serdes_preemphasis_lane3_6=0xc2f0 + +# xe6 (40G) +portmap_7=5:40 +xgxs_rx_lane_map_7=0x213 +xgxs_tx_lane_map_7=0x1203 +phy_xaui_rx_polarity_flip_7=0xc +phy_xaui_tx_polarity_flip_7=0x1 +serdes_driver_current_lane0_7=0x4 +serdes_driver_current_lane1_7=0x4 +serdes_driver_current_lane2_7=0x4 +serdes_driver_current_lane3_7=0x4 +serdes_pre_driver_current_lane0_7=0x4 +serdes_pre_driver_current_lane1_7=0x4 +serdes_pre_driver_current_lane2_7=0x4 +serdes_pre_driver_current_lane3_7=0x4 +serdes_preemphasis_lane0_7=0xc6e0 +serdes_preemphasis_lane1_7=0xc6e0 +serdes_preemphasis_lane2_7=0xc6e0 +serdes_preemphasis_lane3_7=0xc6e0 + +# xe7 (40G) +portmap_8=1:40 +xgxs_rx_lane_map_8=0x213 +xgxs_tx_lane_map_8=0x2031 +phy_xaui_rx_polarity_flip_8=0xe +phy_xaui_tx_polarity_flip_8=0xd +serdes_driver_current_lane0_8=0x5 +serdes_driver_current_lane1_8=0x5 +serdes_driver_current_lane2_8=0x5 +serdes_driver_current_lane3_8=0x5 +serdes_pre_driver_current_lane0_8=0x5 +serdes_pre_driver_current_lane1_8=0x5 +serdes_pre_driver_current_lane2_8=0x5 +serdes_pre_driver_current_lane3_8=0x5 +serdes_preemphasis_lane0_8=0xc6e0 +serdes_preemphasis_lane1_8=0xcad0 +serdes_preemphasis_lane2_8=0xc6e0 +serdes_preemphasis_lane3_8=0xcad0 + +# xe9 (40G) +portmap_9=9:40 +xgxs_rx_lane_map_9=0x3120 +xgxs_tx_lane_map_9=0x3021 +phy_xaui_rx_polarity_flip_9=0x0 +phy_xaui_tx_polarity_flip_9=0x4 +serdes_driver_current_lane0_9=0x3 +serdes_driver_current_lane1_9=0x3 +serdes_driver_current_lane2_9=0x3 +serdes_driver_current_lane3_9=0x3 +serdes_pre_driver_current_lane0_9=0x3 +serdes_pre_driver_current_lane1_9=0x3 +serdes_pre_driver_current_lane2_9=0x3 +serdes_pre_driver_current_lane3_9=0x3 +serdes_preemphasis_lane0_9=0xc2f0 +serdes_preemphasis_lane1_9=0xc6e0 +serdes_preemphasis_lane2_9=0xbf00 +serdes_preemphasis_lane3_9=0xc2f0 + +# xe9 (40G) +portmap_10=13:40 +xgxs_rx_lane_map_10=0x213 +xgxs_tx_lane_map_10=0x132 +phy_xaui_rx_polarity_flip_10=0xe +phy_xaui_tx_polarity_flip_10=0x0 +serdes_driver_current_lane0_10=0x2 +serdes_driver_current_lane1_10=0x3 +serdes_driver_current_lane2_10=0x2 +serdes_driver_current_lane3_10=0x2 +serdes_pre_driver_current_lane0_10=0x2 +serdes_pre_driver_current_lane1_10=0x3 +serdes_pre_driver_current_lane2_10=0x2 +serdes_pre_driver_current_lane3_10=0x2 +serdes_preemphasis_lane0_10=0xb270 +serdes_preemphasis_lane1_10=0xbb10 +serdes_preemphasis_lane2_10=0xb720 +serdes_preemphasis_lane3_10=0xb720 + +# xe10 (40G) +portmap_11=21:40 +xgxs_rx_lane_map_11=0x123 +xgxs_tx_lane_map_11=0x1203 +phy_xaui_rx_polarity_flip_11=0xc +phy_xaui_tx_polarity_flip_11=0xe +serdes_driver_current_lane0_11=0x2 +serdes_driver_current_lane1_11=0x2 +serdes_driver_current_lane2_11=0x2 +serdes_driver_current_lane3_11=0x2 +serdes_pre_driver_current_lane0_11=0x2 +serdes_pre_driver_current_lane1_11=0x2 +serdes_pre_driver_current_lane2_11=0x2 +serdes_pre_driver_current_lane3_11=0x2 +serdes_preemphasis_lane0_11=0xb330 +serdes_preemphasis_lane1_11=0xb330 +serdes_preemphasis_lane2_11=0xb330 +serdes_preemphasis_lane3_11=0xb330 + +# xe11 (40G) +portmap_12=17:40 +xgxs_rx_lane_map_12=0x213 +xgxs_tx_lane_map_12=0x132 +phy_xaui_rx_polarity_flip_12=0xe +phy_xaui_tx_polarity_flip_12=0x0 +serdes_driver_current_lane0_12=0x2 +serdes_driver_current_lane1_12=0x2 +serdes_driver_current_lane2_12=0x2 +serdes_driver_current_lane3_12=0x2 +serdes_pre_driver_current_lane0_12=0x2 +serdes_pre_driver_current_lane1_12=0x2 +serdes_pre_driver_current_lane2_12=0x2 +serdes_pre_driver_current_lane3_12=0x2 +serdes_preemphasis_lane0_12=0xb330 +serdes_preemphasis_lane1_12=0xbb10 +serdes_preemphasis_lane2_12=0xbb10 +serdes_preemphasis_lane3_12=0xbb10 + +# xe12 (40G) +portmap_13=49:40 +xgxs_rx_lane_map_13=0x1302 +xgxs_tx_lane_map_13=0x2031 +phy_xaui_rx_polarity_flip_13=0xb +phy_xaui_tx_polarity_flip_13=0x3 +serdes_driver_current_lane0_13=0x2 +serdes_driver_current_lane1_13=0x2 +serdes_driver_current_lane2_13=0x2 +serdes_driver_current_lane3_13=0x2 +serdes_pre_driver_current_lane0_13=0x2 +serdes_pre_driver_current_lane1_13=0x2 +serdes_pre_driver_current_lane2_13=0x2 +serdes_pre_driver_current_lane3_13=0x2 +serdes_preemphasis_lane0_13=0xa760 +serdes_preemphasis_lane1_13=0xa760 +serdes_preemphasis_lane2_13=0xa760 +serdes_preemphasis_lane3_13=0xa760 + +# xe13 (40G) +portmap_14=53:40 +xgxs_rx_lane_map_14=0x213 +xgxs_tx_lane_map_14=0x231 +phy_xaui_rx_polarity_flip_14=0x1 +phy_xaui_tx_polarity_flip_14=0x0 +serdes_driver_current_lane0_14=0x2 +serdes_driver_current_lane1_14=0x2 +serdes_driver_current_lane2_14=0x2 +serdes_driver_current_lane3_14=0x2 +serdes_pre_driver_current_lane0_14=0x2 +serdes_pre_driver_current_lane1_14=0x2 +serdes_pre_driver_current_lane2_14=0x2 +serdes_pre_driver_current_lane3_14=0x2 +serdes_preemphasis_lane0_14=0xaf40 +serdes_preemphasis_lane1_14=0xaf40 +serdes_preemphasis_lane2_14=0xaf40 +serdes_preemphasis_lane3_14=0xaf40 + +# xe14 (40G) +portmap_15=61:40 +xgxs_rx_lane_map_15=0x132 +xgxs_tx_lane_map_15=0x213 +phy_xaui_rx_polarity_flip_15=0x0 +phy_xaui_tx_polarity_flip_15=0x0 +serdes_driver_current_lane0_15=0x2 +serdes_driver_current_lane1_15=0x2 +serdes_driver_current_lane2_15=0x2 +serdes_driver_current_lane3_15=0x2 +serdes_pre_driver_current_lane0_15=0x2 +serdes_pre_driver_current_lane1_15=0x2 +serdes_pre_driver_current_lane2_15=0x2 +serdes_pre_driver_current_lane3_15=0x2 +serdes_preemphasis_lane0_15=0xa760 +serdes_preemphasis_lane1_15=0xa760 +serdes_preemphasis_lane2_15=0xa760 +serdes_preemphasis_lane3_15=0xa760 + +# xe15 (40G) +portmap_16=57:40 +xgxs_rx_lane_map_16=0x213 +xgxs_tx_lane_map_16=0x2031 +phy_xaui_rx_polarity_flip_16=0x1 +phy_xaui_tx_polarity_flip_16=0x0 +serdes_driver_current_lane0_16=0x1 +serdes_driver_current_lane1_16=0x1 +serdes_driver_current_lane2_16=0x1 +serdes_driver_current_lane3_16=0x1 +serdes_pre_driver_current_lane0_16=0x1 +serdes_pre_driver_current_lane1_16=0x1 +serdes_pre_driver_current_lane2_16=0x1 +serdes_pre_driver_current_lane3_16=0x1 +serdes_preemphasis_lane0_16=0xa760 +serdes_preemphasis_lane1_16=0xa760 +serdes_preemphasis_lane2_16=0xa760 +serdes_preemphasis_lane3_16=0xa760 + +# xe16 (4x10G) +portmap_17=65:10 +portmap_18=66:10 +portmap_19=67:10 +portmap_20=68:10 +xgxs_rx_lane_map_17=0x132 +xgxs_tx_lane_map_17=0x2031 +phy_xaui_rx_polarity_flip_17=0x3 +phy_xaui_tx_polarity_flip_17=0x9 +phy_xaui_rx_polarity_flip_18=0x1 +phy_xaui_tx_polarity_flip_18=0x0 +phy_xaui_rx_polarity_flip_19=0x0 +phy_xaui_tx_polarity_flip_19=0x0 +phy_xaui_rx_polarity_flip_20=0x0 +phy_xaui_tx_polarity_flip_20=0x1 +serdes_driver_current_lane0_17=0x1 +serdes_driver_current_lane1_17=0x1 +serdes_driver_current_lane2_17=0x1 +serdes_driver_current_lane3_17=0x1 +serdes_pre_driver_current_lane0_17=0x1 +serdes_pre_driver_current_lane1_17=0x1 +serdes_pre_driver_current_lane2_17=0x1 +serdes_pre_driver_current_lane3_17=0x1 +serdes_preemphasis_lane0_17=0xa370 +serdes_preemphasis_lane1_17=0xa370 +serdes_preemphasis_lane2_17=0xa370 +serdes_preemphasis_lane3_17=0xa370 + +# xe17 (4x10G) +portmap_21=69:10 +portmap_22=70:10 +portmap_23=71:10 +portmap_24=72:10 +xgxs_rx_lane_map_21=0x213 +xgxs_tx_lane_map_21=0x2130 +phy_xaui_rx_polarity_flip_21=0x1 +phy_xaui_tx_polarity_flip_21=0xf +phy_xaui_rx_polarity_flip_22=0x0 +phy_xaui_tx_polarity_flip_22=0x1 +phy_xaui_rx_polarity_flip_23=0x0 +phy_xaui_tx_polarity_flip_23=0x1 +phy_xaui_rx_polarity_flip_24=0x0 +phy_xaui_tx_polarity_flip_24=0x1 +serdes_driver_current_lane0_21=0x1 +serdes_driver_current_lane1_21=0x1 +serdes_driver_current_lane2_21=0x1 +serdes_driver_current_lane3_21=0x1 +serdes_pre_driver_current_lane0_21=0x1 +serdes_pre_driver_current_lane1_21=0x1 +serdes_pre_driver_current_lane2_21=0x1 +serdes_pre_driver_current_lane3_21=0x1 +serdes_preemphasis_lane0_21=0xa760 +serdes_preemphasis_lane1_21=0xa760 +serdes_preemphasis_lane2_21=0xa760 +serdes_preemphasis_lane3_21=0xa760 + +# xe18 (4x10G) +portmap_25=77:10 +portmap_26=78:10 +portmap_27=79:10 +portmap_28=80:10 +xgxs_rx_lane_map_25=0x123 +xgxs_tx_lane_map_25=0x1203 +phy_xaui_rx_polarity_flip_25=0x3 +phy_xaui_tx_polarity_flip_25=0xe +phy_xaui_rx_polarity_flip_26=0x1 +phy_xaui_tx_polarity_flip_26=0x1 +phy_xaui_rx_polarity_flip_27=0x0 +phy_xaui_tx_polarity_flip_27=0x1 +phy_xaui_rx_polarity_flip_28=0x0 +phy_xaui_tx_polarity_flip_28=0x1 +serdes_driver_current_lane0_25=0x2 +serdes_driver_current_lane1_25=0x2 +serdes_driver_current_lane2_25=0x2 +serdes_driver_current_lane3_25=0x2 +serdes_pre_driver_current_lane0_25=0x2 +serdes_pre_driver_current_lane1_25=0x2 +serdes_pre_driver_current_lane2_25=0x2 +serdes_pre_driver_current_lane3_25=0x2 +serdes_preemphasis_lane0_25=0xaf40 +serdes_preemphasis_lane1_25=0xaf40 +serdes_preemphasis_lane2_25=0xaf40 +serdes_preemphasis_lane3_25=0xaf40 + +# xe19 (4x10G) +portmap_29=73:10 +portmap_30=74:10 +portmap_31=75:10 +portmap_32=76:10 +xgxs_rx_lane_map_29=0x213 +xgxs_tx_lane_map_29=0x2031 +phy_xaui_rx_polarity_flip_29=0x1 +phy_xaui_tx_polarity_flip_29=0x0 +phy_xaui_rx_polarity_flip_30=0x0 +phy_xaui_tx_polarity_flip_30=0x0 +phy_xaui_rx_polarity_flip_31=0x0 +phy_xaui_tx_polarity_flip_31=0x0 +phy_xaui_rx_polarity_flip_32=0x0 +phy_xaui_tx_polarity_flip_32=0x0 +serdes_driver_current_lane0_29=0x2 +serdes_driver_current_lane1_29=0x2 +serdes_driver_current_lane2_29=0x2 +serdes_driver_current_lane3_29=0x2 +serdes_pre_driver_current_lane0_29=0x2 +serdes_pre_driver_current_lane1_29=0x2 +serdes_pre_driver_current_lane2_29=0x2 +serdes_pre_driver_current_lane3_29=0x2 +serdes_preemphasis_lane0_29=0xa760 +serdes_preemphasis_lane1_29=0xa760 +serdes_preemphasis_lane2_29=0xa760 +serdes_preemphasis_lane3_29=0xa760 + +# xe20 (4x10G) +portmap_33=105:10 +portmap_34=106:10 +portmap_35=107:10 +portmap_36=108:10 +xgxs_rx_lane_map_33=0x1320 +xgxs_tx_lane_map_33=0x3021 +phy_xaui_rx_polarity_flip_33=0xd +phy_xaui_tx_polarity_flip_33=0xb +phy_xaui_rx_polarity_flip_34=0x0 +phy_xaui_tx_polarity_flip_34=0x1 +phy_xaui_rx_polarity_flip_35=0x1 +phy_xaui_tx_polarity_flip_35=0x0 +phy_xaui_rx_polarity_flip_36=0x1 +phy_xaui_tx_polarity_flip_36=0x1 +serdes_driver_current_lane0_33=0x1 +serdes_driver_current_lane1_33=0x1 +serdes_driver_current_lane2_33=0x1 +serdes_driver_current_lane3_33=0x1 +serdes_pre_driver_current_lane0_33=0x1 +serdes_pre_driver_current_lane1_33=0x1 +serdes_pre_driver_current_lane2_33=0x1 +serdes_pre_driver_current_lane3_33=0x1 +serdes_preemphasis_lane0_33=0xb330 +serdes_preemphasis_lane1_33=0xb330 +serdes_preemphasis_lane2_33=0xb330 +serdes_preemphasis_lane3_33=0xb330 + +# xe21 (4x10G) +portmap_37=109:10 +portmap_38=110:10 +portmap_39=111:10 +portmap_40=112:10 +xgxs_rx_lane_map_37=0x132 +xgxs_tx_lane_map_37=0x132 +phy_xaui_rx_polarity_flip_37=0x8 +phy_xaui_tx_polarity_flip_37=0x0 +phy_xaui_rx_polarity_flip_38=0x0 +phy_xaui_tx_polarity_flip_38=0x0 +phy_xaui_rx_polarity_flip_39=0x0 +phy_xaui_tx_polarity_flip_39=0x0 +phy_xaui_rx_polarity_flip_40=0x1 +phy_xaui_tx_polarity_flip_40=0x0 +serdes_driver_current_lane0_37=0x1 +serdes_driver_current_lane1_37=0x1 +serdes_driver_current_lane2_37=0x1 +serdes_driver_current_lane3_37=0x2 +serdes_pre_driver_current_lane0_37=0x1 +serdes_pre_driver_current_lane1_37=0x1 +serdes_pre_driver_current_lane2_37=0x1 +serdes_pre_driver_current_lane3_37=0x2 +serdes_preemphasis_lane0_37=0xb330 +serdes_preemphasis_lane1_37=0xb330 +serdes_preemphasis_lane2_37=0xb330 +serdes_preemphasis_lane3_37=0xbff0 + +# xe22 (4x10G) +portmap_41=117:10 +portmap_42=118:10 +portmap_43=119:10 +portmap_44=120:10 +xgxs_rx_lane_map_41=0x231 +xgxs_tx_lane_map_41=0x1203 +phy_xaui_rx_polarity_flip_41=0x3 +phy_xaui_tx_polarity_flip_41=0xe +phy_xaui_rx_polarity_flip_42=0x1 +phy_xaui_tx_polarity_flip_42=0x1 +phy_xaui_rx_polarity_flip_43=0x0 +phy_xaui_tx_polarity_flip_43=0x1 +phy_xaui_rx_polarity_flip_44=0x0 +phy_xaui_tx_polarity_flip_44=0x1 +serdes_driver_current_lane0_41=0x3 +serdes_driver_current_lane1_41=0x5 +serdes_driver_current_lane2_41=0x3 +serdes_driver_current_lane3_41=0x3 +serdes_pre_driver_current_lane0_41=0x3 +serdes_pre_driver_current_lane1_41=0x5 +serdes_pre_driver_current_lane2_41=0x3 +serdes_pre_driver_current_lane3_41=0x3 +serdes_preemphasis_lane0_41=0xc6e0 +serdes_preemphasis_lane1_41=0xc6e0 +serdes_preemphasis_lane2_41=0xc6e0 +serdes_preemphasis_lane3_41=0xc6e0 + +# xe23 (40x10G) +portmap_45=113:10 +portmap_46=114:10 +portmap_47=115:10 +portmap_48=116:10 +xgxs_rx_lane_map_45=0x132 +xgxs_tx_lane_map_45=0x132 +phy_xaui_rx_polarity_flip_45=0x8 +phy_xaui_tx_polarity_flip_45=0x0 +phy_xaui_rx_polarity_flip_46=0x0 +phy_xaui_tx_polarity_flip_46=0x0 +phy_xaui_rx_polarity_flip_47=0x0 +phy_xaui_tx_polarity_flip_47=0x0 +phy_xaui_rx_polarity_flip_48=0x1 +phy_xaui_tx_polarity_flip_48=0x0 +serdes_driver_current_lane0_45=0x1 +serdes_driver_current_lane1_45=0x1 +serdes_driver_current_lane2_45=0x1 +serdes_driver_current_lane3_45=0x1 +serdes_pre_driver_current_lane0_45=0x1 +serdes_pre_driver_current_lane1_45=0x1 +serdes_pre_driver_current_lane2_45=0x1 +serdes_pre_driver_current_lane3_45=0x1 +serdes_preemphasis_lane0_45=0xbb10 +serdes_preemphasis_lane1_45=0xbb10 +serdes_preemphasis_lane2_45=0xbb10 +serdes_preemphasis_lane3_45=0xc2f0 + +# xe24 (40G) +portmap_49=121:40 +xgxs_rx_lane_map_49=0x1320 +xgxs_tx_lane_map_49=0x3021 +phy_xaui_rx_polarity_flip_49=0xd +phy_xaui_tx_polarity_flip_49=0xb +serdes_driver_current_lane0_49=0x4 +serdes_driver_current_lane1_49=0x4 +serdes_driver_current_lane2_49=0x4 +serdes_driver_current_lane3_49=0x4 +serdes_pre_driver_current_lane0_49=0x4 +serdes_pre_driver_current_lane1_49=0x4 +serdes_pre_driver_current_lane2_49=0x4 +serdes_pre_driver_current_lane3_49=0x4 +serdes_preemphasis_lane0_49=0xc6e0 +serdes_preemphasis_lane1_49=0xc6e0 +serdes_preemphasis_lane2_49=0xc6e0 +serdes_preemphasis_lane3_49=0xc6e0 + +# xe25 (40G) +portmap_50=125:40 +xgxs_rx_lane_map_50=0x132 +xgxs_tx_lane_map_50=0x132 +phy_xaui_rx_polarity_flip_50=0x8 +phy_xaui_tx_polarity_flip_50=0x0 +serdes_driver_current_lane0_50=0x4 +serdes_driver_current_lane1_50=0x4 +serdes_driver_current_lane2_50=0x4 +serdes_driver_current_lane3_50=0x4 +serdes_pre_driver_current_lane0_50=0x4 +serdes_pre_driver_current_lane1_50=0x4 +serdes_pre_driver_current_lane2_50=0x4 +serdes_pre_driver_current_lane3_50=0x4 +serdes_preemphasis_lane0_50=0xc6e0 +serdes_preemphasis_lane1_50=0xc6e0 +serdes_preemphasis_lane2_50=0xc6e0 +serdes_preemphasis_lane3_50=0xcec0 + +# xe26 (40G) +portmap_51=85:40 +xgxs_rx_lane_map_51=0x213 +xgxs_tx_lane_map_51=0x1203 +phy_xaui_rx_polarity_flip_51=0xc +phy_xaui_tx_polarity_flip_51=0xe +serdes_driver_current_lane0_51=0x4 +serdes_driver_current_lane1_51=0x5 +serdes_driver_current_lane2_51=0x4 +serdes_driver_current_lane3_51=0x5 +serdes_pre_driver_current_lane0_51=0x4 +serdes_pre_driver_current_lane1_51=0x5 +serdes_pre_driver_current_lane2_51=0x4 +serdes_pre_driver_current_lane3_51=0x5 +serdes_preemphasis_lane0_51=0xc2f0 +serdes_preemphasis_lane1_51=0xc6e0 +serdes_preemphasis_lane2_51=0xc6e0 +serdes_preemphasis_lane3_51=0xc6e0 + +# xe27 (40G) +portmap_52=81:40 +xgxs_rx_lane_map_52=0x1320 +xgxs_tx_lane_map_52=0x2031 +phy_xaui_rx_polarity_flip_52=0x1 +phy_xaui_tx_polarity_flip_52=0x2 +serdes_driver_current_lane0_52=0x2 +serdes_driver_current_lane1_52=0x2 +serdes_driver_current_lane2_52=0x2 +serdes_driver_current_lane3_52=0x2 +serdes_pre_driver_current_lane0_52=0x2 +serdes_pre_driver_current_lane1_52=0x2 +serdes_pre_driver_current_lane2_52=0x2 +serdes_pre_driver_current_lane3_52=0x2 +serdes_preemphasis_lane0_52=0xbb10 +serdes_preemphasis_lane1_52=0xbb10 +serdes_preemphasis_lane2_52=0xbf00 +serdes_preemphasis_lane3_52=0xbb10 + +# xe28 (40G) +portmap_53=89:40 +xgxs_rx_lane_map_53=0x1320 +xgxs_tx_lane_map_53=0x3021 +phy_xaui_rx_polarity_flip_53=0x2 +phy_xaui_tx_polarity_flip_53=0xb +serdes_driver_current_lane0_53=0x4 +serdes_driver_current_lane1_53=0x4 +serdes_driver_current_lane2_53=0x4 +serdes_driver_current_lane3_53=0x4 +serdes_pre_driver_current_lane0_53=0x4 +serdes_pre_driver_current_lane1_53=0x4 +serdes_pre_driver_current_lane2_53=0x4 +serdes_pre_driver_current_lane3_53=0x4 +serdes_preemphasis_lane0_53=0xcad0 +serdes_preemphasis_lane1_53=0xc6e0 +serdes_preemphasis_lane2_53=0xc6e0 +serdes_preemphasis_lane3_53=0xc6e0 + +# xe29 (40G) +portmap_54=93:40 +xgxs_rx_lane_map_54=0x1320 +xgxs_tx_lane_map_54=0x2031 +phy_xaui_rx_polarity_flip_54=0x1 +phy_xaui_tx_polarity_flip_54=0x2 +serdes_driver_current_lane0_54=0x4 +serdes_driver_current_lane1_54=0x4 +serdes_driver_current_lane2_54=0x4 +serdes_driver_current_lane3_54=0x4 +serdes_pre_driver_current_lane0_54=0x4 +serdes_pre_driver_current_lane1_54=0x4 +serdes_pre_driver_current_lane2_54=0x4 +serdes_pre_driver_current_lane3_54=0x4 +serdes_preemphasis_lane0_54=0xc2f0 +serdes_preemphasis_lane1_54=0xc2f0 +serdes_preemphasis_lane2_54=0xc2f0 +serdes_preemphasis_lane3_54=0xc2f0 + +# xe30 (40G) +portmap_55=97:40 +xgxs_rx_lane_map_55=0x213 +xgxs_tx_lane_map_55=0x2031 +phy_xaui_rx_polarity_flip_55=0xc +phy_xaui_tx_polarity_flip_55=0x3 +serdes_driver_current_lane0_55=0x5 +serdes_driver_current_lane1_55=0x5 +serdes_driver_current_lane2_55=0x5 +serdes_driver_current_lane3_55=0x5 +serdes_pre_driver_current_lane0_55=0x5 +serdes_pre_driver_current_lane1_55=0x5 +serdes_pre_driver_current_lane2_55=0x5 +serdes_pre_driver_current_lane3_55=0x5 +serdes_preemphasis_lane0_55=0xcad0 +serdes_preemphasis_lane1_55=0xcad0 +serdes_preemphasis_lane2_55=0xcad0 +serdes_preemphasis_lane3_55=0xcad0 + +# xe31 (40G) +portmap_56=101:40 +xgxs_rx_lane_map_56=0x1320 +xgxs_tx_lane_map_56=0x1203 +phy_xaui_rx_polarity_flip_56=0x1 +phy_xaui_tx_polarity_flip_56=0x6 +serdes_driver_current_lane0_56=0x6 +serdes_driver_current_lane1_56=0x6 +serdes_driver_current_lane2_56=0x6 +serdes_driver_current_lane3_56=0x7 +serdes_pre_driver_current_lane0_56=0x6 +serdes_pre_driver_current_lane1_56=0x6 +serdes_pre_driver_current_lane2_56=0x6 +serdes_pre_driver_current_lane3_56=0x7 +serdes_preemphasis_lane0_56=0xcec0 +serdes_preemphasis_lane1_56=0xcec0 +serdes_preemphasis_lane2_56=0xcad0 +serdes_preemphasis_lane3_56=0xc6e0 + diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/buffers.json.j2 b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/buffers.json.j2 new file mode 100755 index 000000000000..e6e9e844469b --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/buffers.json.j2 @@ -0,0 +1,3 @@ +{%- set default_topo = 't0' %} +{%- include 'buffers_config.j2' %} + diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/buffers_defaults_t0.j2 b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/buffers_defaults_t0.j2 new file mode 100755 index 000000000000..b5a7336e0511 --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/buffers_defaults_t0.j2 @@ -0,0 +1,78 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,1) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 1)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 3)) %}{% endif %} + {% endfor %} + {% for port_idx in range(1,2) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} + {% for port_idx in range(2,3) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 1)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 3)) %}{% endif %} + {% endfor %} + {% for port_idx in range(3,4) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} + {% for port_idx in range(4,5) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 1)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 3)) %}{% endif %} + {% endfor %} + {% for port_idx in range(5,6) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} + {% for port_idx in range(6,7) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 1)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 3)) %}{% endif %} + {% endfor %} + {% for port_idx in range(7,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/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/buffers_defaults_t1.j2 b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/buffers_defaults_t1.j2 new file mode 100755 index 000000000000..b5a7336e0511 --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/buffers_defaults_t1.j2 @@ -0,0 +1,78 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,1) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 1)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 3)) %}{% endif %} + {% endfor %} + {% for port_idx in range(1,2) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} + {% for port_idx in range(2,3) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 1)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 3)) %}{% endif %} + {% endfor %} + {% for port_idx in range(3,4) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} + {% for port_idx in range(4,5) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 1)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 3)) %}{% endif %} + {% endfor %} + {% for port_idx in range(5,6) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} + {% for port_idx in range(6,7) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 1)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{% endif %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 3)) %}{% endif %} + {% endfor %} + {% for port_idx in range(7,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/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/pg_profile_lookup.ini b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/pg_profile_lookup.ini new file mode 100755 index 000000000000..9f2eacb6fc42 --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/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/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/port_config.ini b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/port_config.ini new file mode 100755 index 000000000000..5cf518be64a1 --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/port_config.ini @@ -0,0 +1,45 @@ +# name lanes alias index speed +Ethernet0 29 tenGigE0/0 0 10000 +Ethernet1 30 tenGigE0/1 0 10000 +Ethernet2 31 tenGigE0/2 0 10000 +Ethernet3 32 tenGigE0/3 0 10000 +Ethernet4 25,26,27,28 fortyGigE0/4 1 40000 +Ethernet8 37 tenGigE0/8 2 10000 +Ethernet9 38 tenGigE0/9 2 10000 +Ethernet10 39 tenGigE0/10 2 10000 +Ethernet11 40 tenGigE0/11 2 10000 +Ethernet12 33,34,35,36 fortyGigE0/12 3 40000 +Ethernet16 41 tenGigE0/16 4 10000 +Ethernet17 42 tenGigE0/17 4 10000 +Ethernet18 43 tenGigE0/18 4 10000 +Ethernet19 44 tenGigE0/19 4 10000 +Ethernet20 45,46,47,48 fortyGigE0/20 5 40000 +Ethernet24 5 tenGigE0/24 6 10000 +Ethernet25 6 tenGigE0/25 6 10000 +Ethernet26 7 tenGigE0/26 6 10000 +Ethernet27 8 tenGigE0/27 6 10000 +Ethernet28 1,2,3,4 fortyGigE0/28 7 40000 +Ethernet32 9,10,11,12 fortyGigE0/32 8 40000 +Ethernet36 13,14,15,16 fortyGigE0/36 9 40000 +Ethernet40 21,22,23,24 fortyGigE0/40 10 40000 +Ethernet44 17,18,19,20 fortyGigE0/44 11 40000 +Ethernet48 49,50,51,52 fortyGigE0/48 12 40000 +Ethernet52 53,54,55,56 fortyGigE0/52 13 40000 +Ethernet56 61,62,63,64 fortyGigE0/56 14 40000 +Ethernet60 57,58,59,60 fortyGigE0/60 15 40000 +Ethernet64 65,66,67,68 fortyGigE0/64 16 40000 +Ethernet68 69,70,71,72 fortyGigE0/68 17 40000 +Ethernet72 77,78,79,80 fortyGigE0/72 18 40000 +Ethernet76 73,74,75,76 fortyGigE0/76 19 40000 +Ethernet80 105,106,107,108 fortyGigE0/80 20 40000 +Ethernet84 109,110,111,112 fortyGigE0/84 21 40000 +Ethernet88 117,118,119,120 fortyGigE0/88 22 40000 +Ethernet92 113,114,115,116 fortyGigE0/92 23 40000 +Ethernet96 121,122,123,124 fortyGigE0/96 24 40000 +Ethernet100 125,126,127,128 fortyGigE0/100 25 40000 +Ethernet104 85,86,87,88 fortyGigE0/104 26 40000 +Ethernet108 81,82,83,84 fortyGigE0/108 27 40000 +Ethernet112 89,90,91,92 fortyGigE0/112 28 40000 +Ethernet116 93,94,95,96 fortyGigE0/116 29 40000 +Ethernet120 97,98,99,100 fortyGigE0/120 30 40000 +Ethernet124 101,102,103,104 fortyGigE0/124 31 40000 diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/qos.json.j2 b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/qos.json.j2 new file mode 100755 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/sai.profile b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/sai.profile new file mode 100755 index 000000000000..394d163e30c3 --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-28x40G-16x10G.config.bcm +SAI_NUM_ECMP_MEMBERS=32 diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/td2-s6000-28x40G-16x10G.config.bcm b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/td2-s6000-28x40G-16x10G.config.bcm new file mode 100755 index 000000000000..e0ebfd96f00b --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000-Q28S16/td2-s6000-28x40G-16x10G.config.bcm @@ -0,0 +1,683 @@ +# 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=10 +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=0x0000000000000000000001fffffffffff +pbmp_xport_xe=0x0000000000000000000001fffffffffff + + +# Ports configuration +# xe0 (4x10G) +portmap_1=29:10 +portmap_2=30:10 +portmap_3=31:10 +portmap_4=32:10 +xgxs_rx_lane_map_1=0x213 +xgxs_tx_lane_map_1=0x213 +phy_xaui_rx_polarity_flip_1=0xc +phy_xaui_tx_polarity_flip_1=0x9 +phy_xaui_rx_polarity_flip_2=0x0 +phy_xaui_tx_polarity_flip_2=0x0 +phy_xaui_rx_polarity_flip_3=0x1 +phy_xaui_tx_polarity_flip_3=0x0 +phy_xaui_rx_polarity_flip_4=0x1 +phy_xaui_tx_polarity_flip_4=0x1 +serdes_driver_current_lane0_1=0x6 +serdes_driver_current_lane1_1=0x7 +serdes_driver_current_lane2_1=0x6 +serdes_driver_current_lane3_1=0x6 +serdes_pre_driver_current_lane0_1=0x6 +serdes_pre_driver_current_lane1_1=0x7 +serdes_pre_driver_current_lane2_1=0x6 +serdes_pre_driver_current_lane3_1=0x6 +serdes_preemphasis_lane0_1=0xc2f0 +serdes_preemphasis_lane1_1=0xd2b0 +serdes_preemphasis_lane2_1=0xc6e0 +serdes_preemphasis_lane3_1=0xc2f0 + +# xe1 (40G) +portmap_5=25:40 +xgxs_rx_lane_map_5=0x213 +xgxs_tx_lane_map_5=0x2031 +phy_xaui_rx_polarity_flip_5=0xe +phy_xaui_tx_polarity_flip_5=0x2 +serdes_driver_current_lane0_5=0x5 +serdes_driver_current_lane1_5=0x5 +serdes_driver_current_lane2_5=0x5 +serdes_driver_current_lane3_5=0x5 +serdes_pre_driver_current_lane0_5=0x5 +serdes_pre_driver_current_lane1_5=0x5 +serdes_pre_driver_current_lane2_5=0x5 +serdes_pre_driver_current_lane3_5=0x5 +serdes_preemphasis_lane0_5=0xcad0 +serdes_preemphasis_lane1_5=0xc6e0 +serdes_preemphasis_lane2_5=0xc6e0 +serdes_preemphasis_lane3_5=0xd2b0 + +# xe2 (4x10G) +portmap_6=37:10 +portmap_7=38:10 +portmap_8=39:10 +portmap_9=40:10 +xgxs_rx_lane_map_6=0x213 +xgxs_tx_lane_map_6=0x1203 +phy_xaui_rx_polarity_flip_6=0x3 +phy_xaui_tx_polarity_flip_6=0xe +phy_xaui_rx_polarity_flip_7=0x1 +phy_xaui_tx_polarity_flip_7=0x1 +phy_xaui_rx_polarity_flip_8=0x0 +phy_xaui_tx_polarity_flip_8=0x1 +phy_xaui_rx_polarity_flip_9=0x0 +phy_xaui_tx_polarity_flip_9=0x1 +serdes_driver_current_lane0_6=0x4 +serdes_driver_current_lane1_6=0x4 +serdes_driver_current_lane2_6=0x4 +serdes_driver_current_lane3_6=0x4 +serdes_pre_driver_current_lane0_6=0x4 +serdes_pre_driver_current_lane1_6=0x4 +serdes_pre_driver_current_lane2_6=0x4 +serdes_pre_driver_current_lane3_6=0x4 +serdes_preemphasis_lane0_6=0xcad0 +serdes_preemphasis_lane1_6=0xcad0 +serdes_preemphasis_lane2_6=0xc2f0 +serdes_preemphasis_lane3_6=0xc2f0 + +# xe3 (40G) +portmap_10=33:40 +xgxs_rx_lane_map_10=0x213 +xgxs_tx_lane_map_10=0x132 +phy_xaui_rx_polarity_flip_10=0xe +phy_xaui_tx_polarity_flip_10=0x2 +serdes_driver_current_lane0_10=0x4 +serdes_driver_current_lane1_10=0x4 +serdes_driver_current_lane2_10=0x4 +serdes_driver_current_lane3_10=0x4 +serdes_pre_driver_current_lane0_10=0x4 +serdes_pre_driver_current_lane1_10=0x4 +serdes_pre_driver_current_lane2_10=0x4 +serdes_pre_driver_current_lane3_10=0x4 +serdes_preemphasis_lane0_10=0xc6e0 +serdes_preemphasis_lane1_10=0xc6e0 +serdes_preemphasis_lane2_10=0xc6e0 +serdes_preemphasis_lane3_10=0xc6e0 + +# xe4 (4x10G) +portmap_11=41:10 +portmap_12=42:10 +portmap_13=43:10 +portmap_14=44:10 +xgxs_rx_lane_map_11=0x213 +xgxs_tx_lane_map_11=0x3021 +phy_xaui_rx_polarity_flip_11=0x3 +phy_xaui_tx_polarity_flip_11=0xb +phy_xaui_rx_polarity_flip_12=0x1 +phy_xaui_tx_polarity_flip_12=0x1 +phy_xaui_rx_polarity_flip_13=0x0 +phy_xaui_tx_polarity_flip_13=0x0 +phy_xaui_rx_polarity_flip_14=0x0 +phy_xaui_tx_polarity_flip_14=0x1 +serdes_driver_current_lane0_11=0x4 +serdes_driver_current_lane1_11=0x4 +serdes_driver_current_lane2_11=0x4 +serdes_driver_current_lane3_11=0x4 +serdes_pre_driver_current_lane0_11=0x4 +serdes_pre_driver_current_lane1_11=0x4 +serdes_pre_driver_current_lane2_11=0x4 +serdes_pre_driver_current_lane3_11=0x4 +serdes_preemphasis_lane0_11=0xc6e0 +serdes_preemphasis_lane1_11=0xc2f0 +serdes_preemphasis_lane2_11=0xc2f0 +serdes_preemphasis_lane3_11=0xcad0 + +# xe5 (40G) +portmap_15=45:40 +xgxs_rx_lane_map_15=0x213 +xgxs_tx_lane_map_15=0x213 +phy_xaui_rx_polarity_flip_15=0xe +phy_xaui_tx_polarity_flip_15=0x8 +serdes_driver_current_lane0_15=0x4 +serdes_driver_current_lane1_15=0x4 +serdes_driver_current_lane2_15=0x4 +serdes_driver_current_lane3_15=0x4 +serdes_pre_driver_current_lane0_15=0x4 +serdes_pre_driver_current_lane1_15=0x4 +serdes_pre_driver_current_lane2_15=0x4 +serdes_pre_driver_current_lane3_15=0x4 +serdes_preemphasis_lane0_15=0xc2f0 +serdes_preemphasis_lane1_15=0xc2f0 +serdes_preemphasis_lane2_15=0xc2f0 +serdes_preemphasis_lane3_15=0xc2f0 + +# xe6 (4x10G) +portmap_16=5:10 +portmap_17=6:10 +portmap_18=7:10 +portmap_19=8:10 +xgxs_rx_lane_map_16=0x213 +xgxs_tx_lane_map_16=0x1203 +phy_xaui_rx_polarity_flip_16=0xc +phy_xaui_tx_polarity_flip_16=0x1 +phy_xaui_rx_polarity_flip_17=0x0 +phy_xaui_tx_polarity_flip_17=0x0 +phy_xaui_rx_polarity_flip_18=0x1 +phy_xaui_tx_polarity_flip_18=0x0 +phy_xaui_rx_polarity_flip_19=0x1 +phy_xaui_tx_polarity_flip_19=0x0 +serdes_driver_current_lane0_16=0x4 +serdes_driver_current_lane1_16=0x4 +serdes_driver_current_lane2_16=0x4 +serdes_driver_current_lane3_16=0x4 +serdes_pre_driver_current_lane0_16=0x4 +serdes_pre_driver_current_lane1_16=0x4 +serdes_pre_driver_current_lane2_16=0x4 +serdes_pre_driver_current_lane3_16=0x4 +serdes_preemphasis_lane0_16=0xc6e0 +serdes_preemphasis_lane1_16=0xc6e0 +serdes_preemphasis_lane2_16=0xc6e0 +serdes_preemphasis_lane3_16=0xc6e0 + +# xe7 (40G) +portmap_20=1:40 +xgxs_rx_lane_map_20=0x213 +xgxs_tx_lane_map_20=0x2031 +phy_xaui_rx_polarity_flip_20=0xe +phy_xaui_tx_polarity_flip_20=0xd +serdes_driver_current_lane0_20=0x5 +serdes_driver_current_lane1_20=0x5 +serdes_driver_current_lane2_20=0x5 +serdes_driver_current_lane3_20=0x5 +serdes_pre_driver_current_lane0_20=0x5 +serdes_pre_driver_current_lane1_20=0x5 +serdes_pre_driver_current_lane2_20=0x5 +serdes_pre_driver_current_lane3_20=0x5 +serdes_preemphasis_lane0_20=0xc6e0 +serdes_preemphasis_lane1_20=0xcad0 +serdes_preemphasis_lane2_20=0xc6e0 +serdes_preemphasis_lane3_20=0xcad0 + +# xe8 (40G) +portmap_21=9:40 +xgxs_rx_lane_map_21=0x3120 +xgxs_tx_lane_map_21=0x3021 +phy_xaui_rx_polarity_flip_21=0x0 +phy_xaui_tx_polarity_flip_21=0x4 +serdes_driver_current_lane0_21=0x3 +serdes_driver_current_lane1_21=0x3 +serdes_driver_current_lane2_21=0x3 +serdes_driver_current_lane3_21=0x3 +serdes_pre_driver_current_lane0_21=0x3 +serdes_pre_driver_current_lane1_21=0x3 +serdes_pre_driver_current_lane2_21=0x3 +serdes_pre_driver_current_lane3_21=0x3 +serdes_preemphasis_lane0_21=0xc2f0 +serdes_preemphasis_lane1_21=0xc6e0 +serdes_preemphasis_lane2_21=0xbf00 +serdes_preemphasis_lane3_21=0xc2f0 + +# xe9 (40G) +portmap_22=13:40 +xgxs_rx_lane_map_22=0x213 +xgxs_tx_lane_map_22=0x132 +phy_xaui_rx_polarity_flip_22=0xe +phy_xaui_tx_polarity_flip_22=0x0 +serdes_driver_current_lane0_22=0x2 +serdes_driver_current_lane1_22=0x3 +serdes_driver_current_lane2_22=0x2 +serdes_driver_current_lane3_22=0x2 +serdes_pre_driver_current_lane0_22=0x2 +serdes_pre_driver_current_lane1_22=0x3 +serdes_pre_driver_current_lane2_22=0x2 +serdes_pre_driver_current_lane3_22=0x2 +serdes_preemphasis_lane0_22=0xb270 +serdes_preemphasis_lane1_22=0xbb10 +serdes_preemphasis_lane2_22=0xb720 +serdes_preemphasis_lane3_22=0xb720 + +# xe10 (40G) +portmap_23=21:40 +xgxs_rx_lane_map_23=0x123 +xgxs_tx_lane_map_23=0x1203 +phy_xaui_rx_polarity_flip_23=0xc +phy_xaui_tx_polarity_flip_23=0xe +serdes_driver_current_lane0_23=0x2 +serdes_driver_current_lane1_23=0x2 +serdes_driver_current_lane2_23=0x2 +serdes_driver_current_lane3_23=0x2 +serdes_pre_driver_current_lane0_23=0x2 +serdes_pre_driver_current_lane1_23=0x2 +serdes_pre_driver_current_lane2_23=0x2 +serdes_pre_driver_current_lane3_23=0x2 +serdes_preemphasis_lane0_23=0xb330 +serdes_preemphasis_lane1_23=0xb330 +serdes_preemphasis_lane2_23=0xb330 +serdes_preemphasis_lane3_23=0xb330 + +# xe11 (40G) +portmap_24=17:40 +xgxs_rx_lane_map_24=0x213 +xgxs_tx_lane_map_24=0x132 +phy_xaui_rx_polarity_flip_24=0xe +phy_xaui_tx_polarity_flip_24=0x0 +serdes_driver_current_lane0_24=0x2 +serdes_driver_current_lane1_24=0x2 +serdes_driver_current_lane2_24=0x2 +serdes_driver_current_lane3_24=0x2 +serdes_pre_driver_current_lane0_24=0x2 +serdes_pre_driver_current_lane1_24=0x2 +serdes_pre_driver_current_lane2_24=0x2 +serdes_pre_driver_current_lane3_24=0x2 +serdes_preemphasis_lane0_24=0xb330 +serdes_preemphasis_lane1_24=0xbb10 +serdes_preemphasis_lane2_24=0xbb10 +serdes_preemphasis_lane3_24=0xbb10 + +# xe12 (40G) +portmap_25=49:40 +xgxs_rx_lane_map_25=0x1302 +xgxs_tx_lane_map_25=0x2031 +phy_xaui_rx_polarity_flip_25=0xb +phy_xaui_tx_polarity_flip_25=0x3 +serdes_driver_current_lane0_25=0x2 +serdes_driver_current_lane1_25=0x2 +serdes_driver_current_lane2_25=0x2 +serdes_driver_current_lane3_25=0x2 +serdes_pre_driver_current_lane0_25=0x2 +serdes_pre_driver_current_lane1_25=0x2 +serdes_pre_driver_current_lane2_25=0x2 +serdes_pre_driver_current_lane3_25=0x2 +serdes_preemphasis_lane0_25=0xa760 +serdes_preemphasis_lane1_25=0xa760 +serdes_preemphasis_lane2_25=0xa760 +serdes_preemphasis_lane3_25=0xa760 + +# xe13 (40G) +portmap_26=53:40 +xgxs_rx_lane_map_26=0x213 +xgxs_tx_lane_map_26=0x231 +phy_xaui_rx_polarity_flip_26=0x1 +phy_xaui_tx_polarity_flip_26=0x0 +serdes_driver_current_lane0_26=0x2 +serdes_driver_current_lane1_26=0x2 +serdes_driver_current_lane2_26=0x2 +serdes_driver_current_lane3_26=0x2 +serdes_pre_driver_current_lane0_26=0x2 +serdes_pre_driver_current_lane1_26=0x2 +serdes_pre_driver_current_lane2_26=0x2 +serdes_pre_driver_current_lane3_26=0x2 +serdes_preemphasis_lane0_26=0xaf40 +serdes_preemphasis_lane1_26=0xaf40 +serdes_preemphasis_lane2_26=0xaf40 +serdes_preemphasis_lane3_26=0xaf40 + +# xe14 (40G) +portmap_27=61:40 +xgxs_rx_lane_map_27=0x132 +xgxs_tx_lane_map_27=0x213 +phy_xaui_rx_polarity_flip_27=0x0 +phy_xaui_tx_polarity_flip_27=0x0 +serdes_driver_current_lane0_27=0x2 +serdes_driver_current_lane1_27=0x2 +serdes_driver_current_lane2_27=0x2 +serdes_driver_current_lane3_27=0x2 +serdes_pre_driver_current_lane0_27=0x2 +serdes_pre_driver_current_lane1_27=0x2 +serdes_pre_driver_current_lane2_27=0x2 +serdes_pre_driver_current_lane3_27=0x2 +serdes_preemphasis_lane0_27=0xa760 +serdes_preemphasis_lane1_27=0xa760 +serdes_preemphasis_lane2_27=0xa760 +serdes_preemphasis_lane3_27=0xa760 + +# xe15 (40G) +portmap_28=57:40 +xgxs_rx_lane_map_28=0x213 +xgxs_tx_lane_map_28=0x2031 +phy_xaui_rx_polarity_flip_28=0x1 +phy_xaui_tx_polarity_flip_28=0x0 +serdes_driver_current_lane0_28=0x1 +serdes_driver_current_lane1_28=0x1 +serdes_driver_current_lane2_28=0x1 +serdes_driver_current_lane3_28=0x1 +serdes_pre_driver_current_lane0_28=0x1 +serdes_pre_driver_current_lane1_28=0x1 +serdes_pre_driver_current_lane2_28=0x1 +serdes_pre_driver_current_lane3_28=0x1 +serdes_preemphasis_lane0_28=0xa760 +serdes_preemphasis_lane1_28=0xa760 +serdes_preemphasis_lane2_28=0xa760 +serdes_preemphasis_lane3_28=0xa760 + +# xe16 (40G) +portmap_29=65:40 +xgxs_rx_lane_map_29=0x132 +xgxs_tx_lane_map_29=0x2031 +phy_xaui_rx_polarity_flip_29=0x3 +phy_xaui_tx_polarity_flip_29=0x9 +serdes_driver_current_lane0_29=0x1 +serdes_driver_current_lane1_29=0x1 +serdes_driver_current_lane2_29=0x1 +serdes_driver_current_lane3_29=0x1 +serdes_pre_driver_current_lane0_29=0x1 +serdes_pre_driver_current_lane1_29=0x1 +serdes_pre_driver_current_lane2_29=0x1 +serdes_pre_driver_current_lane3_29=0x1 +serdes_preemphasis_lane0_29=0xa370 +serdes_preemphasis_lane1_29=0xa370 +serdes_preemphasis_lane2_29=0xa370 +serdes_preemphasis_lane3_29=0xa370 + +# xe17 (40G) +portmap_30=69:40 +xgxs_rx_lane_map_30=0x213 +xgxs_tx_lane_map_30=0x2130 +phy_xaui_rx_polarity_flip_30=0x1 +phy_xaui_tx_polarity_flip_30=0xf +serdes_driver_current_lane0_30=0x1 +serdes_driver_current_lane1_30=0x1 +serdes_driver_current_lane2_30=0x1 +serdes_driver_current_lane3_30=0x1 +serdes_pre_driver_current_lane0_30=0x1 +serdes_pre_driver_current_lane1_30=0x1 +serdes_pre_driver_current_lane2_30=0x1 +serdes_pre_driver_current_lane3_30=0x1 +serdes_preemphasis_lane0_30=0xa760 +serdes_preemphasis_lane1_30=0xa760 +serdes_preemphasis_lane2_30=0xa760 +serdes_preemphasis_lane3_30=0xa760 + +# xe18 (40G) +portmap_31=77:40 +xgxs_rx_lane_map_31=0x123 +xgxs_tx_lane_map_31=0x1203 +phy_xaui_rx_polarity_flip_31=0x3 +phy_xaui_tx_polarity_flip_31=0xe +serdes_driver_current_lane0_31=0x2 +serdes_driver_current_lane1_31=0x2 +serdes_driver_current_lane2_31=0x2 +serdes_driver_current_lane3_31=0x2 +serdes_pre_driver_current_lane0_31=0x2 +serdes_pre_driver_current_lane1_31=0x2 +serdes_pre_driver_current_lane2_31=0x2 +serdes_pre_driver_current_lane3_31=0x2 +serdes_preemphasis_lane0_31=0xaf40 +serdes_preemphasis_lane1_31=0xaf40 +serdes_preemphasis_lane2_31=0xaf40 +serdes_preemphasis_lane3_31=0xaf40 + +# xe19 (40G) +portmap_32=73:40 +xgxs_rx_lane_map_32=0x213 +xgxs_tx_lane_map_32=0x2031 +phy_xaui_rx_polarity_flip_32=0x1 +phy_xaui_tx_polarity_flip_32=0x0 +serdes_driver_current_lane0_32=0x2 +serdes_driver_current_lane1_32=0x2 +serdes_driver_current_lane2_32=0x2 +serdes_driver_current_lane3_32=0x2 +serdes_pre_driver_current_lane0_32=0x2 +serdes_pre_driver_current_lane1_32=0x2 +serdes_pre_driver_current_lane2_32=0x2 +serdes_pre_driver_current_lane3_32=0x2 +serdes_preemphasis_lane0_32=0xa760 +serdes_preemphasis_lane1_32=0xa760 +serdes_preemphasis_lane2_32=0xa760 +serdes_preemphasis_lane3_32=0xa760 + +# xe20 (40G) +portmap_33=105:40 +xgxs_rx_lane_map_33=0x1320 +xgxs_tx_lane_map_33=0x3021 +phy_xaui_rx_polarity_flip_33=0xd +phy_xaui_tx_polarity_flip_33=0xb +serdes_driver_current_lane0_33=0x1 +serdes_driver_current_lane1_33=0x1 +serdes_driver_current_lane2_33=0x1 +serdes_driver_current_lane3_33=0x1 +serdes_pre_driver_current_lane0_33=0x1 +serdes_pre_driver_current_lane1_33=0x1 +serdes_pre_driver_current_lane2_33=0x1 +serdes_pre_driver_current_lane3_33=0x1 +serdes_preemphasis_lane0_33=0xb330 +serdes_preemphasis_lane1_33=0xb330 +serdes_preemphasis_lane2_33=0xb330 +serdes_preemphasis_lane3_33=0xb330 + +# xe21 (40G) +portmap_34=109:40 +xgxs_rx_lane_map_34=0x132 +xgxs_tx_lane_map_34=0x132 +phy_xaui_rx_polarity_flip_34=0x8 +phy_xaui_tx_polarity_flip_34=0x0 +serdes_driver_current_lane0_34=0x1 +serdes_driver_current_lane1_34=0x1 +serdes_driver_current_lane2_34=0x1 +serdes_driver_current_lane3_34=0x2 +serdes_pre_driver_current_lane0_34=0x1 +serdes_pre_driver_current_lane1_34=0x1 +serdes_pre_driver_current_lane2_34=0x1 +serdes_pre_driver_current_lane3_34=0x2 +serdes_preemphasis_lane0_34=0xb330 +serdes_preemphasis_lane1_34=0xb330 +serdes_preemphasis_lane2_34=0xb330 +serdes_preemphasis_lane3_34=0xbff0 + +# xe22 (40G) +portmap_35=117:40 +xgxs_rx_lane_map_35=0x231 +xgxs_tx_lane_map_35=0x1203 +phy_xaui_rx_polarity_flip_35=0x3 +phy_xaui_tx_polarity_flip_35=0xe +serdes_driver_current_lane0_35=0x3 +serdes_driver_current_lane1_35=0x5 +serdes_driver_current_lane2_35=0x3 +serdes_driver_current_lane3_35=0x3 +serdes_pre_driver_current_lane0_35=0x3 +serdes_pre_driver_current_lane1_35=0x5 +serdes_pre_driver_current_lane2_35=0x3 +serdes_pre_driver_current_lane3_35=0x3 +serdes_preemphasis_lane0_35=0xc6e0 +serdes_preemphasis_lane1_35=0xc6e0 +serdes_preemphasis_lane2_35=0xc6e0 +serdes_preemphasis_lane3_35=0xc6e0 + +# xe23 (40G) +portmap_36=113:40 +xgxs_rx_lane_map_36=0x132 +xgxs_tx_lane_map_36=0x132 +phy_xaui_rx_polarity_flip_36=0x8 +phy_xaui_tx_polarity_flip_36=0x0 +serdes_driver_current_lane0_36=0x1 +serdes_driver_current_lane1_36=0x1 +serdes_driver_current_lane2_36=0x1 +serdes_driver_current_lane3_36=0x1 +serdes_pre_driver_current_lane0_36=0x1 +serdes_pre_driver_current_lane1_36=0x1 +serdes_pre_driver_current_lane2_36=0x1 +serdes_pre_driver_current_lane3_36=0x1 +serdes_preemphasis_lane0_36=0xbb10 +serdes_preemphasis_lane1_36=0xbb10 +serdes_preemphasis_lane2_36=0xbb10 +serdes_preemphasis_lane3_36=0xc2f0 + +# xe24 (40G) +portmap_37=121:40 +xgxs_rx_lane_map_37=0x1320 +xgxs_tx_lane_map_37=0x3021 +phy_xaui_rx_polarity_flip_37=0xd +phy_xaui_tx_polarity_flip_37=0xb +serdes_driver_current_lane0_37=0x4 +serdes_driver_current_lane1_37=0x4 +serdes_driver_current_lane2_37=0x4 +serdes_driver_current_lane3_37=0x4 +serdes_pre_driver_current_lane0_37=0x4 +serdes_pre_driver_current_lane1_37=0x4 +serdes_pre_driver_current_lane2_37=0x4 +serdes_pre_driver_current_lane3_37=0x4 +serdes_preemphasis_lane0_37=0xc6e0 +serdes_preemphasis_lane1_37=0xc6e0 +serdes_preemphasis_lane2_37=0xc6e0 +serdes_preemphasis_lane3_37=0xc6e0 + +# xe25 (40G) +portmap_38=125:40 +xgxs_rx_lane_map_38=0x132 +xgxs_tx_lane_map_38=0x132 +phy_xaui_rx_polarity_flip_38=0x8 +phy_xaui_tx_polarity_flip_38=0x0 +serdes_driver_current_lane0_38=0x4 +serdes_driver_current_lane1_38=0x4 +serdes_driver_current_lane2_38=0x4 +serdes_driver_current_lane3_38=0x4 +serdes_pre_driver_current_lane0_38=0x4 +serdes_pre_driver_current_lane1_38=0x4 +serdes_pre_driver_current_lane2_38=0x4 +serdes_pre_driver_current_lane3_38=0x4 +serdes_preemphasis_lane0_38=0xc6e0 +serdes_preemphasis_lane1_38=0xc6e0 +serdes_preemphasis_lane2_38=0xc6e0 +serdes_preemphasis_lane3_38=0xcec0 + +# xe26 (40G) +portmap_39=85:40 +xgxs_rx_lane_map_39=0x213 +xgxs_tx_lane_map_39=0x1203 +phy_xaui_rx_polarity_flip_39=0xc +phy_xaui_tx_polarity_flip_39=0xe +serdes_driver_current_lane0_39=0x4 +serdes_driver_current_lane1_39=0x5 +serdes_driver_current_lane2_39=0x4 +serdes_driver_current_lane3_39=0x5 +serdes_pre_driver_current_lane0_39=0x4 +serdes_pre_driver_current_lane1_39=0x5 +serdes_pre_driver_current_lane2_39=0x4 +serdes_pre_driver_current_lane3_39=0x5 +serdes_preemphasis_lane0_39=0xc2f0 +serdes_preemphasis_lane1_39=0xc6e0 +serdes_preemphasis_lane2_39=0xc6e0 +serdes_preemphasis_lane3_39=0xc6e0 + +# xe27 (40G) +portmap_40=81:40 +xgxs_rx_lane_map_40=0x1320 +xgxs_tx_lane_map_40=0x2031 +phy_xaui_rx_polarity_flip_40=0x1 +phy_xaui_tx_polarity_flip_40=0x2 +serdes_driver_current_lane0_40=0x2 +serdes_driver_current_lane1_40=0x2 +serdes_driver_current_lane2_40=0x2 +serdes_driver_current_lane3_40=0x2 +serdes_pre_driver_current_lane0_40=0x2 +serdes_pre_driver_current_lane1_40=0x2 +serdes_pre_driver_current_lane2_40=0x2 +serdes_pre_driver_current_lane3_40=0x2 +serdes_preemphasis_lane0_40=0xbb10 +serdes_preemphasis_lane1_40=0xbb10 +serdes_preemphasis_lane2_40=0xbf00 +serdes_preemphasis_lane3_40=0xbb10 + +# xe28 (40G) +portmap_41=89:40 +xgxs_rx_lane_map_41=0x1320 +xgxs_tx_lane_map_41=0x3021 +phy_xaui_rx_polarity_flip_41=0x2 +phy_xaui_tx_polarity_flip_41=0xb +serdes_driver_current_lane0_41=0x4 +serdes_driver_current_lane1_41=0x4 +serdes_driver_current_lane2_41=0x4 +serdes_driver_current_lane3_41=0x4 +serdes_pre_driver_current_lane0_41=0x4 +serdes_pre_driver_current_lane1_41=0x4 +serdes_pre_driver_current_lane2_41=0x4 +serdes_pre_driver_current_lane3_41=0x4 +serdes_preemphasis_lane0_41=0xcad0 +serdes_preemphasis_lane1_41=0xc6e0 +serdes_preemphasis_lane2_41=0xc6e0 +serdes_preemphasis_lane3_41=0xc6e0 + +# xe29 (40G) +portmap_42=93:40 +xgxs_rx_lane_map_42=0x1320 +xgxs_tx_lane_map_42=0x2031 +phy_xaui_rx_polarity_flip_42=0x1 +phy_xaui_tx_polarity_flip_42=0x2 +serdes_driver_current_lane0_42=0x4 +serdes_driver_current_lane1_42=0x4 +serdes_driver_current_lane2_42=0x4 +serdes_driver_current_lane3_42=0x4 +serdes_pre_driver_current_lane0_42=0x4 +serdes_pre_driver_current_lane1_42=0x4 +serdes_pre_driver_current_lane2_42=0x4 +serdes_pre_driver_current_lane3_42=0x4 +serdes_preemphasis_lane0_42=0xc2f0 +serdes_preemphasis_lane1_42=0xc2f0 +serdes_preemphasis_lane2_42=0xc2f0 +serdes_preemphasis_lane3_42=0xc2f0 + +# xe30 (40G) +portmap_43=97:40 +xgxs_rx_lane_map_43=0x213 +xgxs_tx_lane_map_43=0x2031 +phy_xaui_rx_polarity_flip_43=0xc +phy_xaui_tx_polarity_flip_43=0x3 +serdes_driver_current_lane0_43=0x5 +serdes_driver_current_lane1_43=0x5 +serdes_driver_current_lane2_43=0x5 +serdes_driver_current_lane3_43=0x5 +serdes_pre_driver_current_lane0_43=0x5 +serdes_pre_driver_current_lane1_43=0x5 +serdes_pre_driver_current_lane2_43=0x5 +serdes_pre_driver_current_lane3_43=0x5 +serdes_preemphasis_lane0_43=0xcad0 +serdes_preemphasis_lane1_43=0xcad0 +serdes_preemphasis_lane2_43=0xcad0 +serdes_preemphasis_lane3_43=0xcad0 + +# xe31 (40G) +portmap_44=101:40 +xgxs_rx_lane_map_44=0x1320 +xgxs_tx_lane_map_44=0x1203 +phy_xaui_rx_polarity_flip_44=0x1 +phy_xaui_tx_polarity_flip_44=0x6 +serdes_driver_current_lane0_44=0x6 +serdes_driver_current_lane1_44=0x6 +serdes_driver_current_lane2_44=0x6 +serdes_driver_current_lane3_44=0x7 +serdes_pre_driver_current_lane0_44=0x6 +serdes_pre_driver_current_lane1_44=0x6 +serdes_pre_driver_current_lane2_44=0x6 +serdes_pre_driver_current_lane3_44=0x7 +serdes_preemphasis_lane0_44=0xcec0 +serdes_preemphasis_lane1_44=0xcec0 +serdes_preemphasis_lane2_44=0xcad0 +serdes_preemphasis_lane3_44=0xc6e0 diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/td2-s6000-32x40G.config.bcm b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/td2-s6000-32x40G.config.bcm index 4c94db7107c7..0e25b4d4232d 100644 --- a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/td2-s6000-32x40G.config.bcm +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/td2-s6000-32x40G.config.bcm @@ -20,7 +20,7 @@ parity_enable=1 stat_if_parity_enable=0 # -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 l2xmsg_hostbuf_size=8192 l2xmsg_mode=1 diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/platform.json b/device/dell/x86_64-dell_s6000_s1220-r0/platform.json new file mode 100644 index 000000000000..62a53fe328fc --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/platform.json @@ -0,0 +1,228 @@ +{ + "chassis": { + "name": "S6000", + "components": [ + { + "name": "BIOS" + }, + { + "name": "System-CPLD" + }, + { + "name": "Master-CPLD" + }, + { + "name": "Slave-CPLD" + } + ], + "fans": [ + { + "name": "FanTray1-Fan1" + }, + { + "name": "FanTray1-Fan2" + }, + { + "name": "FanTray2-Fan1" + }, + { + "name": "FanTray2-Fan2" + }, + { + "name": "FanTray3-Fan1" + }, + { + "name": "FanTray3-Fan2" + } + ], + "fan_drawers":[ + { + "name": "FanTray1", + "fans": [ + { + "name": "FanTray1-Fan1" + }, + { + "name": "FanTray1-Fan2" + } + ] + }, + { + "name": "FanTray2", + "fans": [ + { + "name": "FanTray2-Fan1" + }, + { + "name": "FanTray2-Fan2" + } + ] + }, + { + "name": "FanTray3", + "fans": [ + { + "name": "FanTray3-Fan1" + }, + { + "name": "FanTray3-Fan2" + } + ] + } + ], + "psus": [ + { + "name": "PSU1", + "fans": [ + { + "name": "PSU1 Fan" + } + ], + "thermals": [ + { + "name": "PSU1-Sensor 1" + }, + { + "name": "PSU1-Sensor 2" + } + ] + }, + { + "name": "PSU2", + "fans": [ + { + "name": "PSU2 Fan" + } + ], + "thermals": [ + { + "name": "PSU2-Sensor 1" + }, + { + "name": "PSU2-Sensor 2" + } + ] + } + ], + "thermals": [ + { + "name": "ASIC On-board" + }, + { + "name": "NIC" + }, + { + "name": "System Front" + }, + { + "name": "DIMM" + }, + { + "name": "CPU Core 0" + }, + { + "name": "CPU Core 1" + } + ], + "modules": [], + "sfps": [ + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + } + ] + }, + "interfaces": {} +} diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/platform_reboot b/device/dell/x86_64-dell_s6000_s1220-r0/platform_reboot index dc6e3d517a84..28f2ec626605 100755 --- a/device/dell/x86_64-dell_s6000_s1220-r0/platform_reboot +++ b/device/dell/x86_64-dell_s6000_s1220-r0/platform_reboot @@ -1,39 +1,41 @@ -#!/usr/bin/python +#!/usr/bin/python3 + import sys import os import struct +PORT_RES = '/dev/port' NVRAM_RES = '/dev/nvram' -COLD_RESET = 0xE # Cold Reset -WARM_RESET = 0x6 # Warm Reset +COLD_RESET = 0xE # Cold Reset +WARM_RESET = 0x6 # Warm Reset +RESET_REG = 0xCF9 def io_reg_write(resource, offset, val): fd = os.open(resource, os.O_RDWR) if(fd < 0): - print 'file open failed %s" % resource' + print('file open failed %s" % resource') return if(os.lseek(fd, offset, os.SEEK_SET) != offset): - print 'lseek failed on %s' % resource + print('lseek failed on %s' % resource) return ret = os.write(fd, struct.pack('B', val)) if(ret != 1): - print 'write failed %d' % ret + print('write failed %d' % ret) return os.close(fd) - def power_reset(val): with open('/sys/devices/platform/dell-s6000-cpld.0/power_reset', 'w') as p: p.write(str(int(val)) + '\n') p.flush() -def gpio_direction(pin,direction): +def gpio_direction(pin, direction): kernpath = '/sys/class/gpio/gpio'+str(pin)+'/direction' with open(('kernpath'), 'w') as p: p.write(str(direction) + '\n') p.flush() -def gpio_set(pin,value): +def gpio_set(pin, value): kernpath = '/sys/class/gpio/gpio'+str(pin)+'/value' with open(('kernpath'), 'w') as p: p.write(str(int(value)) + '\n') @@ -44,13 +46,18 @@ def gpio_export(value): p.write(str(int(value)) + '\n') p.flush() - if __name__ == "__main__": + + retry_count = 0 io_reg_write(NVRAM_RES, 0x49, COLD_RESET) - if not os.path.isdir("/sys/class/gpio/gpio10"): - gpio_export(10) - gpio_direction("10","out") - #Toggle GPIO10 pin (to reset MUX) - gpio_set("10",1) - gpio_set("10",0) - power_reset(1) + + while retry_count < 3: + if not os.path.isdir("/sys/class/gpio/gpio10"): + gpio_export(10) + gpio_direction("10", "out") + # Toggle GPIO10 pin (to reset MUX) + gpio_set("10", 1) + gpio_set("10", 0) + power_reset(1) + retry_count += 1 + io_reg_write(PORT_RES, RESET_REG, COLD_RESET) diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/plugins/eeprom.py b/device/dell/x86_64-dell_s6000_s1220-r0/plugins/eeprom.py index b326d24f6d44..dc16fde7d770 100644 --- a/device/dell/x86_64-dell_s6000_s1220-r0/plugins/eeprom.py +++ b/device/dell/x86_64-dell_s6000_s1220-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Dell S6000 # @@ -10,13 +8,21 @@ ############################################################################# try: - from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") + from sonic_eeprom.eeprom_tlvinfo import TlvInfoDecoder + from sonic_platform.eeprom import EepromS6000 +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class board(object): + def __new__(cls, name, path, cpld_root, ro): + eeprom_path = "/sys/class/i2c-adapter/i2c-10/10-0053/eeprom" -class board(eeprom_tlvinfo.TlvInfoDecoder): + with open("/sys/class/dmi/id/product_name", "r") as fd: + board_type = fd.read() - def __init__(self, name, path, cpld_root, ro): - self.eeprom_path = "/sys/class/i2c-adapter/i2c-10/10-0053/eeprom" - super(board, self).__init__(self.eeprom_path, 0, '', True) + if 'S6000-ON' in board_type: + return TlvInfoDecoder(eeprom_path, 0, '', True) + else: + return EepromS6000(is_plugin=True) diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/plugins/pcie.yaml b/device/dell/x86_64-dell_s6000_s1220-r0/plugins/pcie.yaml new file mode 100644 index 000000000000..9c4bea46730a --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/plugins/pcie.yaml @@ -0,0 +1,65 @@ +- bus: '00' + dev: '01' + fn: '0' + id: 0c46 + name: 'PCI bridge: Intel Corporation Atom Processor S1200 PCI Express Root Port 1' +- bus: '00' + dev: '02' + fn: '0' + id: 0c47 + name: 'PCI bridge: Intel Corporation Atom Processor S1200 PCI Express Root Port 2' +- bus: '00' + dev: '03' + fn: '0' + id: 0c48 + name: 'PCI bridge: Intel Corporation Atom Processor S1200 PCI Express Root Port 3' +- bus: '00' + dev: '04' + fn: '0' + id: 0c49 + name: 'PCI bridge: Intel Corporation Atom Processor S1200 PCI Express Root Port 4' +- bus: '00' + dev: 0e + fn: '0' + id: 0c54 + name: 'IOMMU: Intel Corporation Atom Processor S1200 Internal' +- bus: '00' + dev: '13' + fn: '0' + id: 0c59 + name: 'System peripheral: Intel Corporation Atom Processor S1200 SMBus 2.0 Controller 0' +- bus: '00' + dev: '13' + fn: '1' + id: 0c5a + name: 'System peripheral: Intel Corporation Atom Processor S1200 SMBus 2.0 Controller 1' +- bus: '01' + dev: '00' + fn: '0' + id: b850 + name: 'Ethernet controller: Broadcom Limited Broadcom BCM56850 Switch ASIC' +- bus: '02' + dev: '00' + fn: '0' + id: '9170' + name: 'SATA controller: Marvell Technology Group Ltd. Device 9170' +- bus: '03' + dev: '00' + fn: '0' + id: 400a + name: 'PCI bridge: Pericom Semiconductor PI7C9X442SL PCI Express Bridge Port' +- bus: '04' + dev: '01' + fn: '0' + id: 400a + name: 'PCI bridge: Pericom Semiconductor PI7C9X442SL PCI Express Bridge Port' +- bus: '04' + dev: '02' + fn: '0' + id: 400a + name: 'PCI bridge: Pericom Semiconductor PI7C9X442SL PCI Express Bridge Port' +- bus: 08 + dev: '00' + fn: '0' + id: 10d3 + name: 'Ethernet controller: Intel Corporation 82574L Gigabit Network Connection' diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/plugins/psuutil.py b/device/dell/x86_64-dell_s6000_s1220-r0/plugins/psuutil.py index 537605f3975b..16318bca8162 100644 --- a/device/dell/x86_64-dell_s6000_s1220-r0/plugins/psuutil.py +++ b/device/dell/x86_64-dell_s6000_s1220-r0/plugins/psuutil.py @@ -21,7 +21,7 @@ def __init__(self): def get_cpld_register(self, reg_name): cpld_dir = "/sys/devices/platform/dell-s6000-cpld.0" retval = 'ERR' - reg_file = cpld_dir +'/' + reg_name + reg_file = cpld_dir + '/' + reg_name if (not os.path.isfile(reg_file)): return retval diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/plugins/sfputil.py b/device/dell/x86_64-dell_s6000_s1220-r0/plugins/sfputil.py index b27bf4bc22ea..f03415cbc7ea 100644 --- a/device/dell/x86_64-dell_s6000_s1220-r0/plugins/sfputil.py +++ b/device/dell/x86_64-dell_s6000_s1220-r0/plugins/sfputil.py @@ -33,7 +33,7 @@ def port_end(self): @property def qsfp_ports(self): - return range(0, self.PORTS_IN_BLOCK + 1) + return list(range(0, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -46,7 +46,7 @@ def get_transceiver_status(self): reg_file = open("/sys/devices/platform/dell-s6000-cpld.0/qsfp_modprs") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -55,7 +55,6 @@ def get_transceiver_status(self): return int(content, 16) - def __init__(self): eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" @@ -76,7 +75,7 @@ def get_presence(self, port_num): try: reg_file = open("/sys/devices/platform/dell-s6000-cpld.0/qsfp_modprs") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -101,7 +100,7 @@ def get_low_power_mode(self, port_num): try: reg_file = open("/sys/devices/platform/dell-s6000-cpld.0/qsfp_lpmode") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) content = reg_file.readline().rstrip() @@ -125,7 +124,7 @@ def set_low_power_mode(self, port_num, lpmode): try: reg_file = open("/sys/devices/platform/dell-s6000-cpld.0/qsfp_lpmode", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -161,7 +160,7 @@ def reset(self, port_num): try: reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -187,7 +186,7 @@ def reset(self, port_num): try: reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "w") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = reg_value | mask @@ -207,17 +206,17 @@ def get_transceiver_change_event(self, timeout=0): if timeout == 0: forever = True elif timeout > 0: - timeout = timeout / float(1000) # Convert to secs + timeout = timeout / float(1000) # Convert to secs else: - print "get_transceiver_change_event:Invalid timeout value", timeout + print("get_transceiver_change_event:Invalid timeout value", timeout) return False, {} end_time = start_time + timeout if start_time > end_time: - print 'get_transceiver_change_event:' \ - 'time wrap / invalid timeout value', timeout + print('get_transceiver_change_event:' + 'time wrap / invalid timeout value', timeout) - return False, {} # Time wrap or possibly incorrect timeout + return False, {} # Time wrap or possibly incorrect timeout while timeout >= 0: # Check for OIR events and return updated port_dict @@ -247,10 +246,10 @@ def get_transceiver_change_event(self, timeout=0): else: timeout = end_time - time.time() if timeout >= 1: - time.sleep(1) # We poll at 1 second granularity + time.sleep(1) # We poll at 1 second granularity else: if timeout > 0: time.sleep(timeout) return True, {} - print "get_transceiver_change_event: Should not reach here." + print("get_transceiver_change_event: Should not reach here.") return False, {} diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/sensors.conf b/device/dell/x86_64-dell_s6000_s1220-r0/sensors.conf index c87af11afacc..f74a2b3d40ac 100644 --- a/device/dell/x86_64-dell_s6000_s1220-r0/sensors.conf +++ b/device/dell/x86_64-dell_s6000_s1220-r0/sensors.conf @@ -7,8 +7,8 @@ # tmp75-i2c-11-4e is an ambient temperature sensor. chip "tmp75-*" - set temp1_max 50 - set temp1_max_hyst 25 + set temp1_max 80 + set temp1_max_hyst 70 # emc1403-i2c-10-4d has following temperature sensors: # temp1: CPU0 external Temp Sensor @@ -32,5 +32,5 @@ chip "jc42-*" set temp1_crit 85 chip "dni_dps460-*" - set temp1_max 50 - set temp2_max 50 + set temp1_max 80 + set temp2_max 80 diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/pg_profile_lookup.ini b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/pg_profile_lookup.ini index dc05d0a100a3..0b5d680edda7 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/pg_profile_lookup.ini +++ b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/pg_profile_lookup.ini @@ -1,17 +1,17 @@ # PG lossless profiles. # speed cable size xon xoff threshold xon_offset - 10000 5m 1248 2288 35776 -3 2288 - 25000 5m 1248 2288 53248 -3 2288 - 40000 5m 1248 2288 66560 -3 2288 - 50000 5m 1248 2288 79872 -3 2288 - 100000 5m 1248 2288 165568 -3 2288 - 10000 40m 1248 2288 37024 -3 2288 - 25000 40m 1248 2288 56160 -3 2288 - 40000 40m 1248 2288 71552 -3 2288 - 50000 40m 1248 2288 85696 -3 2288 - 100000 40m 1248 2288 177632 -3 2288 - 10000 300m 1248 2288 46176 -3 2288 - 25000 300m 1248 2288 79040 -3 2288 - 40000 300m 1248 2288 108160 -3 2288 - 50000 300m 1248 2288 141856 -3 2288 - 100000 300m 1248 2288 268736 -3 2288 + 10000 5m 1248 2288 35776 0 2288 + 25000 5m 1248 2288 53248 0 2288 + 40000 5m 1248 2288 66560 0 2288 + 50000 5m 1248 2288 79872 0 2288 + 100000 5m 1248 2288 165568 0 2288 + 10000 40m 1248 2288 37024 0 2288 + 25000 40m 1248 2288 56160 0 2288 + 40000 40m 1248 2288 71552 0 2288 + 50000 40m 1248 2288 85696 0 2288 + 100000 40m 1248 2288 177632 0 2288 + 10000 300m 1248 2288 46176 0 2288 + 25000 300m 1248 2288 79040 0 2288 + 40000 300m 1248 2288 108160 0 2288 + 50000 300m 1248 2288 141856 0 2288 + 100000 300m 1248 2288 268736 0 2288 diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json.j2 b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json.j2 index 3e548325ea30..34002048afdb 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json.j2 +++ b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json.j2 @@ -1 +1,21 @@ +{%- macro generate_wred_profiles() %} + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "wred_green_enable" : "true", + "wred_yellow_enable" : "true", + "wred_red_enable" : "true", + "ecn" : "ecn_all", + "green_max_threshold" : "2097152", + "green_min_threshold" : "250000", + "yellow_max_threshold" : "2097152", + "yellow_min_threshold" : "1048576", + "red_max_threshold" : "2097152", + "red_min_threshold" : "1048576", + "green_drop_probability" : "5", + "yellow_drop_probability": "5", + "red_drop_probability" : "5" + } + }, +{%- endmacro %} + {%- include 'qos_config.j2' %} diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/sai.profile.j2 b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/sai.profile.j2 index df3cbb558294..44992f92f45f 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/sai.profile.j2 +++ b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/sai.profile.j2 @@ -1,7 +1,7 @@ {# Get sai.profile based on switch_role #} {%- if DEVICE_METADATA is defined -%} {%- set switch_role = DEVICE_METADATA['localhost']['type'] -%} -{%- if switch_role.lower() == 'torrouter' %} +{%- if 'torrouter' in switch_role.lower() %} {% set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-s6100-64x40G-t0.config.bcm' -%} {%- else %} {%- set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-s6100-64x40G-t1.config.bcm' -%} @@ -11,3 +11,4 @@ {%- endif %} {# Write the contents of sai_ profile_filename to sai.profile file #} {{ sai_profile_contents }} +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/th-s6100-64x40G-t0.config.bcm b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/th-s6100-64x40G-t0.config.bcm index adbef9387eda..7fa577052635 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/th-s6100-64x40G-t0.config.bcm +++ b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/th-s6100-64x40G-t0.config.bcm @@ -2,7 +2,7 @@ l3_alpm_enable=2 pfc_deadlock_seq_control=1 bcm_stat_interval=2000000 -bcm_num_cos=8 +bcm_num_cos=10 switch_bypass_mode=0 mmu_lossless=0 lpm_scaling_enable=0 diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/th-s6100-64x40G-t1.config.bcm b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/th-s6100-64x40G-t1.config.bcm index f9dc619849d0..f55fb9d3ab51 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/th-s6100-64x40G-t1.config.bcm +++ b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/th-s6100-64x40G-t1.config.bcm @@ -2,7 +2,7 @@ l3_alpm_enable=2 pfc_deadlock_seq_control=1 bcm_stat_interval=2000000 -bcm_num_cos=8 +bcm_num_cos=10 switch_bypass_mode=0 mmu_lossless=0 lpm_scaling_enable=0 diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/installer.conf b/device/dell/x86_64-dell_s6100_c2538-r0/installer.conf index 0a9a3a639eb2..0932d0637760 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/installer.conf +++ b/device/dell/x86_64-dell_s6100_c2538-r0/installer.conf @@ -1,3 +1,3 @@ CONSOLE_PORT=0x2f8 CONSOLE_DEV=1 -ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="module_blacklist=gpio_ich" +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="module_blacklist=gpio_ich nos-config-part=/dev/sda12" diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/platform.json b/device/dell/x86_64-dell_s6100_c2538-r0/platform.json new file mode 100644 index 000000000000..24e32b16bb15 --- /dev/null +++ b/device/dell/x86_64-dell_s6100_c2538-r0/platform.json @@ -0,0 +1,343 @@ +{ + "chassis": { + "name": "S6100-ON", + "components": [ + { + "name": "BIOS" + }, + { + "name": "CPLD" + }, + { + "name": "FPGA" + } + ], + "fans": [ + { + "name": "FanTray1-Fan1" + }, + { + "name": "FanTray2-Fan1" + }, + { + "name": "FanTray3-Fan1" + }, + { + "name": "FanTray4-Fan1" + } + ], + "fan_drawers":[ + { + "name": "FanTray1", + "fans": [ + { + "name": "FanTray1-Fan1" + } + ] + }, + { + "name": "FanTray2", + "fans": [ + { + "name": "FanTray2-Fan1" + } + ] + }, + { + "name": "FanTray3", + "fans": [ + { + "name": "FanTray3-Fan1" + } + ] + }, + { + "name": "FanTray4", + "fans": [ + { + "name": "FanTray4-Fan1" + } + ] + } + ], + "psus": [ + { + "name": "PSU1", + "fans": [ + { + "name": "PSU1 Fan" + } + ] + }, + { + "name": "PSU2", + "fans": [ + { + "name": "PSU2 Fan" + } + ] + } + ], + "thermals": [ + { + "name": "CPU On-board" + }, + { + "name": "ASIC On-board Front" + }, + { + "name": "System Front" + }, + { + "name": "ASIC On-board Rear" + }, + { + "name": "Front GE board" + }, + { + "name": "Front SFP+ board" + }, + { + "name": "CPU Core 0" + }, + { + "name": "CPU Core 1" + }, + { + "name": "CPU Core 2" + }, + { + "name": "CPU Core 3" + } + ], + "modules": [ + { + "name": "IOM1: 16x40G QSFP+ Module", + "components": [ + { + "name": "IOM1-CPLD" + } + ] + }, + { + "name": "IOM2: 16x40G QSFP+ Module", + "components": [ + { + "name": "IOM2-CPLD" + } + ] + }, + { + "name": "IOM3: 16x40G QSFP+ Module", + "components": [ + { + "name": "IOM3-CPLD" + } + ] + }, + { + "name": "IOM4: 16x40G QSFP+ Module", + "components": [ + { + "name": "IOM4-CPLD" + } + ] + } + ], + "sfps": [ + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + }, + { + "name": "QSFP+ or later" + } + ] + }, + "interfaces": {} +} diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/plugins/eeprom.py b/device/dell/x86_64-dell_s6100_c2538-r0/plugins/eeprom.py index 7265b90efb1f..12a318def38c 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/plugins/eeprom.py +++ b/device/dell/x86_64-dell_s6100_c2538-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Dell S6100 # @@ -11,8 +9,8 @@ try: from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): @@ -30,4 +28,4 @@ def serial_number_str(self, e): # 'results' is a list containing 3 elements, type (int), length (int), # and value (string) of the requested TLV - return results[2] + return results[2].decode('ascii') diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/plugins/pcie.yaml b/device/dell/x86_64-dell_s6100_c2538-r0/plugins/pcie.yaml new file mode 100644 index 000000000000..650610c7b557 --- /dev/null +++ b/device/dell/x86_64-dell_s6100_c2538-r0/plugins/pcie.yaml @@ -0,0 +1,55 @@ +- bus: '00' + dev: '01' + fn: '0' + id: 1f10 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 1' +- bus: '00' + dev: '02' + fn: '0' + id: 1f11 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 2' +- bus: '00' + dev: '03' + fn: '0' + id: 1f12 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 3' +- bus: '00' + dev: '04' + fn: '0' + id: 1f13 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 4' +- bus: '00' + dev: 0f + fn: '0' + id: 1f16 + name: 'IOMMU: Intel Corporation Atom processor C2000 RCEC' +- bus: '00' + dev: '13' + fn: '0' + id: 1f15 + name: 'System peripheral: Intel Corporation Atom processor C2000 SMBus 2.0' +- bus: '00' + dev: '14' + fn: '0' + id: 1f41 + name: 'Ethernet controller: Intel Corporation Ethernet Connection I354' +- bus: '00' + dev: '14' + fn: '1' + id: 1f41 + name: 'Ethernet controller: Intel Corporation Ethernet Connection I354' +- bus: '00' + dev: '14' + fn: '2' + id: 1f41 + name: 'Ethernet controller: Intel Corporation Ethernet Connection I354' +- bus: '01' + dev: '00' + fn: '0' + id: b960 + name: 'Ethernet controller: Broadcom Limited Broadcom BCM56960 Switch ASIC' +- bus: '01' + dev: '00' + fn: '1' + id: b960 + name: 'Ethernet controller: Broadcom Limited Broadcom BCM56960 Switch ASIC' diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/plugins/psuutil.py b/device/dell/x86_64-dell_s6100_c2538-r0/plugins/psuutil.py index 2f3673801526..a29d45f939bf 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/plugins/psuutil.py +++ b/device/dell/x86_64-dell_s6100_c2538-r0/plugins/psuutil.py @@ -14,6 +14,7 @@ HWMON_DIR = "/sys/devices/platform/SMF.512/hwmon/" HWMON_NODE = os.listdir(HWMON_DIR)[0] + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" @@ -26,7 +27,7 @@ def get_pmc_register(self, reg_name): retval = 'ERR' mb_reg_file = mailbox_dir+'/' + reg_name if (not os.path.isfile(mb_reg_file)): - logging.error(mb_reg_file, "not found !") + logging.error(mb_reg_file + " not found !") return retval try: @@ -60,7 +61,7 @@ def get_psu_status(self, index): psu_status = int(psu_status, 16) # Check for PSU statuse if (~psu_status & 0b1000) or (psu_status & 0b0100): - status = 1 + status = 1 return status @@ -77,6 +78,6 @@ def get_psu_presence(self, index): psu_presence = int(psu_presence, 16) # Check for PSU presence if (~psu_presence & 0b1): - status = 1 + status = 1 return status diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/plugins/sfputil.py b/device/dell/x86_64-dell_s6100_c2538-r0/plugins/sfputil.py index ff4426ba10c2..a6a7cce72f56 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/plugins/sfputil.py +++ b/device/dell/x86_64-dell_s6100_c2538-r0/plugins/sfputil.py @@ -31,70 +31,70 @@ class SfpUtil(SfpUtilBase): _port_to_eeprom_mapping = {} _port_to_i2c_mapping = { - 0: [6, 18, 34, 50, 66], - 1: [6, 19, 35, 51, 67], - 2: [6, 20, 36, 52, 68], - 3: [6, 21, 37, 53, 69], - 4: [6, 22, 38, 54, 70], - 5: [6, 23, 39, 55, 71], - 6: [6, 24, 40, 56, 72], - 7: [6, 25, 41, 57, 73], - 8: [6, 26, 42, 58, 74], - 9: [6, 27, 43, 59, 75], - 10: [6, 28, 44, 60, 76], - 11: [6, 29, 45, 61, 77], - 12: [6, 30, 46, 62, 78], - 13: [6, 31, 47, 63, 79], - 14: [6, 32, 48, 64, 80], - 15: [6, 33, 49, 65, 81], - 16: [8, 18, 34, 50, 66], - 17: [8, 19, 35, 51, 67], - 18: [8, 20, 36, 52, 68], - 19: [8, 21, 37, 53, 69], - 20: [8, 22, 38, 54, 70], - 21: [8, 23, 39, 55, 71], - 22: [8, 24, 40, 56, 72], - 23: [8, 25, 41, 57, 73], - 24: [8, 26, 42, 58, 74], - 25: [8, 27, 43, 59, 75], - 26: [8, 28, 44, 60, 76], - 27: [8, 29, 45, 61, 77], - 28: [8, 30, 46, 62, 78], - 29: [8, 31, 47, 63, 79], - 30: [8, 32, 48, 64, 80], - 31: [8, 33, 49, 65, 81], - 32: [7, 18, 34, 50, 66], - 33: [7, 19, 35, 51, 67], - 34: [7, 20, 36, 52, 68], - 35: [7, 21, 37, 53, 69], - 36: [7, 22, 38, 54, 70], - 37: [7, 23, 39, 55, 71], - 38: [7, 24, 40, 56, 72], - 39: [7, 25, 41, 57, 73], - 40: [7, 26, 42, 58, 74], - 41: [7, 27, 43, 59, 75], - 42: [7, 28, 44, 60, 76], - 43: [7, 29, 45, 61, 77], - 44: [7, 30, 46, 62, 78], - 45: [7, 31, 47, 63, 79], - 46: [7, 32, 48, 64, 80], - 47: [7, 33, 49, 65, 81], - 48: [9, 18, 34, 50, 66], - 49: [9, 19, 35, 51, 67], - 50: [9, 20, 36, 52, 68], - 51: [9, 21, 37, 53, 69], - 52: [9, 22, 38, 54, 70], - 53: [9, 23, 39, 55, 71], - 54: [9, 24, 40, 56, 72], - 55: [9, 25, 41, 57, 73], - 56: [9, 26, 42, 58, 74], - 57: [9, 27, 43, 59, 75], - 58: [9, 28, 44, 60, 76], - 59: [9, 29, 45, 61, 77], - 60: [9, 30, 46, 62, 78], - 61: [9, 31, 47, 63, 79], - 62: [9, 32, 48, 64, 80], - 63: [9, 33, 49, 65, 81] + 0: [6, 18, 34, 50, 66], + 1: [6, 19, 35, 51, 67], + 2: [6, 20, 36, 52, 68], + 3: [6, 21, 37, 53, 69], + 4: [6, 22, 38, 54, 70], + 5: [6, 23, 39, 55, 71], + 6: [6, 24, 40, 56, 72], + 7: [6, 25, 41, 57, 73], + 8: [6, 26, 42, 58, 74], + 9: [6, 27, 43, 59, 75], + 10: [6, 28, 44, 60, 76], + 11: [6, 29, 45, 61, 77], + 12: [6, 30, 46, 62, 78], + 13: [6, 31, 47, 63, 79], + 14: [6, 32, 48, 64, 80], + 15: [6, 33, 49, 65, 81], + 16: [8, 18, 34, 50, 66], + 17: [8, 19, 35, 51, 67], + 18: [8, 20, 36, 52, 68], + 19: [8, 21, 37, 53, 69], + 20: [8, 22, 38, 54, 70], + 21: [8, 23, 39, 55, 71], + 22: [8, 24, 40, 56, 72], + 23: [8, 25, 41, 57, 73], + 24: [8, 26, 42, 58, 74], + 25: [8, 27, 43, 59, 75], + 26: [8, 28, 44, 60, 76], + 27: [8, 29, 45, 61, 77], + 28: [8, 30, 46, 62, 78], + 29: [8, 31, 47, 63, 79], + 30: [8, 32, 48, 64, 80], + 31: [8, 33, 49, 65, 81], + 32: [7, 18, 34, 50, 66], + 33: [7, 19, 35, 51, 67], + 34: [7, 20, 36, 52, 68], + 35: [7, 21, 37, 53, 69], + 36: [7, 22, 38, 54, 70], + 37: [7, 23, 39, 55, 71], + 38: [7, 24, 40, 56, 72], + 39: [7, 25, 41, 57, 73], + 40: [7, 26, 42, 58, 74], + 41: [7, 27, 43, 59, 75], + 42: [7, 28, 44, 60, 76], + 43: [7, 29, 45, 61, 77], + 44: [7, 30, 46, 62, 78], + 45: [7, 31, 47, 63, 79], + 46: [7, 32, 48, 64, 80], + 47: [7, 33, 49, 65, 81], + 48: [9, 18, 34, 50, 66], + 49: [9, 19, 35, 51, 67], + 50: [9, 20, 36, 52, 68], + 51: [9, 21, 37, 53, 69], + 52: [9, 22, 38, 54, 70], + 53: [9, 23, 39, 55, 71], + 54: [9, 24, 40, 56, 72], + 55: [9, 25, 41, 57, 73], + 56: [9, 26, 42, 58, 74], + 57: [9, 27, 43, 59, 75], + 58: [9, 28, 44, 60, 76], + 59: [9, 29, 45, 61, 77], + 60: [9, 30, 46, 62, 78], + 61: [9, 31, 47, 63, 79], + 62: [9, 32, 48, 64, 80], + 63: [9, 33, 49, 65, 81] } IOM_1_PORT_START = 0 @@ -125,7 +125,7 @@ def port_end(self): @property def qsfp_ports(self): - return range(0, self.PORTS_IN_BLOCK + 1) + return list(range(0, self.PORTS_IN_BLOCK + 1)) @property def iom1_port_start(self): @@ -172,69 +172,69 @@ def __init__(self): global port_to_eeprom_path for port_num in range(0, self.port_end + 1): - if port_num >= self.iom1_port_start and port_num <=\ - self.iom1_port_end: - assigned = 0 - # i2c-6 - for x in range(1, 5): - port_to_eeprom_path = eeprom_path.format( - self.port_to_i2c_mapping[port_num][0], - self.port_to_i2c_mapping[port_num][x]) - if (os.path.isfile(port_to_eeprom_path)): - self.port_to_eeprom_mapping[port_num] =\ - port_to_eeprom_path - assigned = 1 - elif (not assigned): - self.port_to_eeprom_mapping[port_num] =\ - "No IOM" - - elif(port_num >= self.iom2_port_start and - port_num <= self.iom2_port_end): - assigned = 0 - # i2c-8 - for x in range(1, 5): - port_to_eeprom_path = eeprom_path.format( - self.port_to_i2c_mapping[port_num][0], - self.port_to_i2c_mapping[port_num][x]) - if (os.path.isfile(port_to_eeprom_path)): - self.port_to_eeprom_mapping[port_num] =\ - port_to_eeprom_path - assigned = 1 - elif (not assigned): - self.port_to_eeprom_mapping[port_num] =\ - "No IOM" - - elif(port_num >= self.iom3_port_start and port_num <= - self.iom3_port_end): - assigned = 0 - # i2c-7 - for x in range(1, 5): - port_to_eeprom_path = eeprom_path.format( - self.port_to_i2c_mapping[port_num][0], - self.port_to_i2c_mapping[port_num][x]) - if (os.path.isfile(port_to_eeprom_path)): - self.port_to_eeprom_mapping[port_num] =\ - port_to_eeprom_path - assigned = 1 - elif (not assigned): - self.port_to_eeprom_mapping[port_num] =\ - "No IOM" - - elif(port_num >= self.iom4_port_start and port_num <= - self.iom4_port_end): - assigned = 0 - # i2c-9 - for x in range(1, 5): - port_to_eeprom_path = eeprom_path.format( - self.port_to_i2c_mapping[port_num][0], - self.port_to_i2c_mapping[port_num][x]) - if (os.path.isfile(port_to_eeprom_path)): - self.port_to_eeprom_mapping[port_num] =\ - port_to_eeprom_path - assigned = 1 - elif (not assigned): - self.port_to_eeprom_mapping[port_num] =\ - "No IOM" + if port_num >= self.iom1_port_start and port_num <=\ + self.iom1_port_end: + assigned = 0 + # i2c-6 + for x in range(1, 5): + port_to_eeprom_path = eeprom_path.format( + self.port_to_i2c_mapping[port_num][0], + self.port_to_i2c_mapping[port_num][x]) + if (os.path.isfile(port_to_eeprom_path)): + self.port_to_eeprom_mapping[port_num] =\ + port_to_eeprom_path + assigned = 1 + elif (not assigned): + self.port_to_eeprom_mapping[port_num] =\ + "No IOM" + + elif(port_num >= self.iom2_port_start and + port_num <= self.iom2_port_end): + assigned = 0 + # i2c-8 + for x in range(1, 5): + port_to_eeprom_path = eeprom_path.format( + self.port_to_i2c_mapping[port_num][0], + self.port_to_i2c_mapping[port_num][x]) + if (os.path.isfile(port_to_eeprom_path)): + self.port_to_eeprom_mapping[port_num] =\ + port_to_eeprom_path + assigned = 1 + elif (not assigned): + self.port_to_eeprom_mapping[port_num] =\ + "No IOM" + + elif(port_num >= self.iom3_port_start and port_num <= + self.iom3_port_end): + assigned = 0 + # i2c-7 + for x in range(1, 5): + port_to_eeprom_path = eeprom_path.format( + self.port_to_i2c_mapping[port_num][0], + self.port_to_i2c_mapping[port_num][x]) + if (os.path.isfile(port_to_eeprom_path)): + self.port_to_eeprom_mapping[port_num] =\ + port_to_eeprom_path + assigned = 1 + elif (not assigned): + self.port_to_eeprom_mapping[port_num] =\ + "No IOM" + + elif(port_num >= self.iom4_port_start and port_num <= + self.iom4_port_end): + assigned = 0 + # i2c-9 + for x in range(1, 5): + port_to_eeprom_path = eeprom_path.format( + self.port_to_i2c_mapping[port_num][0], + self.port_to_i2c_mapping[port_num][x]) + if (os.path.isfile(port_to_eeprom_path)): + self.port_to_eeprom_mapping[port_num] =\ + port_to_eeprom_path + assigned = 1 + elif (not assigned): + self.port_to_eeprom_mapping[port_num] =\ + "No IOM" SfpUtilBase.__init__(self) @@ -267,11 +267,11 @@ def get_presence(self, port_num): i2c_line = 17 try: - qsfp_path = self.BASE_VAL_PATH.format(i2c_line)+"qsfp_modprs" - reg_file = open(qsfp_path, "r") + qsfp_path = self.BASE_VAL_PATH.format(i2c_line)+"qsfp_modprs" + reg_file = open(qsfp_path, "r") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -316,11 +316,11 @@ def get_low_power_mode(self, port_num): i2c_line = 17 try: - qsfp_path = self.BASE_VAL_PATH.format(i2c_line)+"qsfp_lpmode" - reg_file = open(qsfp_path, "r") + qsfp_path = self.BASE_VAL_PATH.format(i2c_line)+"qsfp_lpmode" + reg_file = open(qsfp_path, "r") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -365,11 +365,11 @@ def set_low_power_mode(self, port_num, lpmode): i2c_line = 17 try: - qsfp_path = self.BASE_VAL_PATH.format(i2c_line)+"qsfp_lpmode" - reg_file = open(qsfp_path, "r+") + qsfp_path = self.BASE_VAL_PATH.format(i2c_line)+"qsfp_lpmode" + reg_file = open(qsfp_path, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -426,11 +426,11 @@ def reset(self, port_num): i2c_line = 17 try: - qsfp_path = self.BASE_VAL_PATH.format(i2c_line)+"qsfp_lpmode" - reg_file = open(qsfp_path, "r+") + qsfp_path = self.BASE_VAL_PATH.format(i2c_line)+"qsfp_lpmode" + reg_file = open(qsfp_path, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -465,11 +465,11 @@ def reset(self, port_num): # Flip the bit back high and write back to the register to take port # out of reset try: - qsfp_path = self.BASE_VAL_PATH.format(i2c_line)+"qsfp_lpmode" - reg_file = open(qsfp_path, "w") + qsfp_path = self.BASE_VAL_PATH.format(i2c_line)+"qsfp_lpmode" + reg_file = open(qsfp_path, "w") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = reg_value | mask @@ -480,158 +480,157 @@ def reset(self, port_num): return True def get_register(self, reg_file): - retval = 'ERR' + retval = 'ERR' - if (not os.path.isfile(reg_file)): - print reg_file, 'not found !' - return retval + if (not os.path.isfile(reg_file)): + print(reg_file + ' not found !') + return retval - try: - with open(reg_file, 'r') as fd: - retval = fd.read() - except Exception as error: - logging.error("Unable to open ", reg_file, "file !") + try: + with open(reg_file, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", reg_file, "file !") - retval = retval.rstrip('\r\n') - retval = retval.lstrip(" ") - return retval + retval = retval.rstrip('\r\n') + retval = retval.lstrip(" ") + return retval def check_interrupts(self, port_dict): - retval = 0 - is_port_dict_updated = False - - # Read the QSFP ABS interrupt & status registers - cpld2_abs_int = self.get_register( - "/sys/class/i2c-adapter/i2c-14/14-003e/qsfp_abs_int") - cpld2_abs_sta = self.get_register( - "/sys/class/i2c-adapter/i2c-14/14-003e/qsfp_abs_sta") - cpld3_abs_int = self.get_register( - "/sys/class/i2c-adapter/i2c-15/15-003e/qsfp_abs_int") - cpld3_abs_sta = self.get_register( - "/sys/class/i2c-adapter/i2c-15/15-003e/qsfp_abs_sta") - cpld4_abs_int = self.get_register( - "/sys/class/i2c-adapter/i2c-16/16-003e/qsfp_abs_int") - cpld4_abs_sta = self.get_register( - "/sys/class/i2c-adapter/i2c-16/16-003e/qsfp_abs_sta") - cpld5_abs_int = self.get_register( - "/sys/class/i2c-adapter/i2c-17/17-003e/qsfp_abs_int") - cpld5_abs_sta = self.get_register( - "/sys/class/i2c-adapter/i2c-17/17-003e/qsfp_abs_sta") - - if (cpld2_abs_int == 'ERR' or cpld2_abs_sta == 'ERR' or - cpld3_abs_int == 'ERR' or cpld3_abs_sta == 'ERR' or - cpld4_abs_int == 'ERR' or cpld4_abs_sta == 'ERR' or - cpld5_abs_int == 'ERR' or cpld5_abs_sta == 'ERR'): - return -1 - - # If IOM is not present, interrupt will return 'read error' - # Handle the scenario gracefully - if (cpld2_abs_int == 'read error'): - cpld2_abs_int = "0x0" - cpld2_abs_sta = "0x0" - if (cpld3_abs_int == 'read error'): - cpld3_abs_int = "0x0" - cpld3_abs_sta = "0x0" - if (cpld4_abs_int == 'read error'): - cpld4_abs_int = "0x0" - cpld4_abs_sta = "0x0" - if (cpld5_abs_int == 'read error'): - cpld5_abs_int = "0x0" - cpld5_abs_sta = "0x0" - - cpld2_abs_int = int(cpld2_abs_int, 16) - cpld2_abs_sta = int(cpld2_abs_sta, 16) - cpld3_abs_int = int(cpld3_abs_int, 16) - cpld3_abs_sta = int(cpld3_abs_sta, 16) - cpld4_abs_int = int(cpld4_abs_int, 16) - cpld4_abs_sta = int(cpld4_abs_sta, 16) - cpld5_abs_int = int(cpld5_abs_int, 16) - cpld5_abs_sta = int(cpld5_abs_sta, 16) - - # Make it contiguous - interrupt_reg = (cpld2_abs_int & 0xffff) | \ - ((cpld4_abs_int & 0xffff) << 16) | \ - ((cpld3_abs_int & 0xffff) << 32) | \ - ((cpld5_abs_int & 0xffff) << 48) - status_reg = (cpld2_abs_sta & 0xffff) | \ - ((cpld4_abs_sta & 0xffff) << 16) | \ - ((cpld3_abs_sta & 0xffff) << 32) | \ - ((cpld5_abs_sta & 0xffff) << 48) - - port = self.port_start - while port <= self.port_end: - if interrupt_reg & (1 << port): - # update only if atleast one port has generated - # interrupt - is_port_dict_updated = True - if status_reg & (1 << port): - # status reg 1 => optics is removed - port_dict[port] = '0' - else: - # status reg 0 => optics is inserted - port_dict[port] = '1' - port += 1 - return retval, is_port_dict_updated + retval = 0 + is_port_dict_updated = False + + # Read the QSFP ABS interrupt & status registers + cpld2_abs_int = self.get_register( + "/sys/class/i2c-adapter/i2c-14/14-003e/qsfp_abs_int") + cpld2_abs_sta = self.get_register( + "/sys/class/i2c-adapter/i2c-14/14-003e/qsfp_abs_sta") + cpld3_abs_int = self.get_register( + "/sys/class/i2c-adapter/i2c-15/15-003e/qsfp_abs_int") + cpld3_abs_sta = self.get_register( + "/sys/class/i2c-adapter/i2c-15/15-003e/qsfp_abs_sta") + cpld4_abs_int = self.get_register( + "/sys/class/i2c-adapter/i2c-16/16-003e/qsfp_abs_int") + cpld4_abs_sta = self.get_register( + "/sys/class/i2c-adapter/i2c-16/16-003e/qsfp_abs_sta") + cpld5_abs_int = self.get_register( + "/sys/class/i2c-adapter/i2c-17/17-003e/qsfp_abs_int") + cpld5_abs_sta = self.get_register( + "/sys/class/i2c-adapter/i2c-17/17-003e/qsfp_abs_sta") + + if (cpld2_abs_int == 'ERR' or cpld2_abs_sta == 'ERR' or + cpld3_abs_int == 'ERR' or cpld3_abs_sta == 'ERR' or + cpld4_abs_int == 'ERR' or cpld4_abs_sta == 'ERR' or + cpld5_abs_int == 'ERR' or cpld5_abs_sta == 'ERR'): + return -1 + + # If IOM is not present, interrupt will return 'read error' + # Handle the scenario gracefully + if (cpld2_abs_int == 'read error'): + cpld2_abs_int = "0x0" + cpld2_abs_sta = "0x0" + if (cpld3_abs_int == 'read error'): + cpld3_abs_int = "0x0" + cpld3_abs_sta = "0x0" + if (cpld4_abs_int == 'read error'): + cpld4_abs_int = "0x0" + cpld4_abs_sta = "0x0" + if (cpld5_abs_int == 'read error'): + cpld5_abs_int = "0x0" + cpld5_abs_sta = "0x0" + + cpld2_abs_int = int(cpld2_abs_int, 16) + cpld2_abs_sta = int(cpld2_abs_sta, 16) + cpld3_abs_int = int(cpld3_abs_int, 16) + cpld3_abs_sta = int(cpld3_abs_sta, 16) + cpld4_abs_int = int(cpld4_abs_int, 16) + cpld4_abs_sta = int(cpld4_abs_sta, 16) + cpld5_abs_int = int(cpld5_abs_int, 16) + cpld5_abs_sta = int(cpld5_abs_sta, 16) + + # Make it contiguous + interrupt_reg = (cpld2_abs_int & 0xffff) | \ + ((cpld4_abs_int & 0xffff) << 16) | \ + ((cpld3_abs_int & 0xffff) << 32) | \ + ((cpld5_abs_int & 0xffff) << 48) + status_reg = (cpld2_abs_sta & 0xffff) | \ + ((cpld4_abs_sta & 0xffff) << 16) | \ + ((cpld3_abs_sta & 0xffff) << 32) | \ + ((cpld5_abs_sta & 0xffff) << 48) + + port = self.port_start + while port <= self.port_end: + if interrupt_reg & (1 << port): + # update only if atleast one port has generated + # interrupt + is_port_dict_updated = True + if status_reg & (1 << port): + # status reg 1 => optics is removed + port_dict[port] = '0' + else: + # status reg 0 => optics is inserted + port_dict[port] = '1' + port += 1 + return retval, is_port_dict_updated def get_transceiver_change_event(self, timeout=0): - port_dict = {} - try: - # We get notified when there is an SCI interrupt from GPIO SUS6 - # Open the sysfs file and register the epoll object - self.oir_fd = open(self.OIR_FD_PATH, "r") - if self.oir_fd != -1: - # Do a dummy read before epoll register - self.oir_fd.read() - self.epoll = select.epoll() - self.epoll.register(self.oir_fd.fileno(), - select.EPOLLIN & select.EPOLLET) - else: - print("get_transceiver_change_event : unable to create fd") - return False, {} + port_dict = {} + try: + # We get notified when there is an SCI interrupt from GPIO SUS6 + # Open the sysfs file and register the epoll object + self.oir_fd = open(self.OIR_FD_PATH, "r") + if self.oir_fd != -1: + # Do a dummy read before epoll register + self.oir_fd.read() + self.epoll = select.epoll() + self.epoll.register(self.oir_fd.fileno(), + select.EPOLLIN & select.EPOLLET) + else: + print("get_transceiver_change_event : unable to create fd") + return False, {} - # Check for missed interrupts by invoking self.check_interrupts - # which will update the port_dict. - while True: - interrupt_count_start = self.get_register(self.OIR_FD_PATH) + # Check for missed interrupts by invoking self.check_interrupts + # which will update the port_dict. + while True: + interrupt_count_start = self.get_register(self.OIR_FD_PATH) - retval, is_port_dict_updated = \ - self.check_interrupts(port_dict) - if ((retval == 0) and (is_port_dict_updated is True)): - return True, port_dict + retval, is_port_dict_updated = \ + self.check_interrupts(port_dict) + if ((retval == 0) and (is_port_dict_updated is True)): + return True, port_dict - interrupt_count_end = self.get_register(self.OIR_FD_PATH) + interrupt_count_end = self.get_register(self.OIR_FD_PATH) - if (interrupt_count_start == 'ERR' or - interrupt_count_end == 'ERR'): - print("get_transceiver_change_event : \ + if (interrupt_count_start == 'ERR' or + interrupt_count_end == 'ERR'): + print("get_transceiver_change_event : \ unable to retrive interrupt count") - break - - # check_interrupts() itself may take upto 100s of msecs. - # We detect a missed interrupt based on the count - if interrupt_count_start == interrupt_count_end: - break - - # Block until an xcvr is inserted or removed with timeout = -1 - events = self.epoll.poll( - timeout=timeout if timeout != 0 else -1) - if events: - # check interrupts and return the port_dict - retval, is_port_dict_updated = \ - self.check_interrupts(port_dict) - if (retval != 0): - return False, {} - - return True, port_dict - except: - return False, {} - finally: - if self.oir_fd != -1: - self.epoll.unregister(self.oir_fd.fileno()) - self.epoll.close() - self.oir_fd.close() - self.oir_fd = -1 - self.epoll = -1 + break + + # check_interrupts() itself may take upto 100s of msecs. + # We detect a missed interrupt based on the count + if interrupt_count_start == interrupt_count_end: + break + + # Block until an xcvr is inserted or removed with timeout = -1 + events = self.epoll.poll( + timeout=timeout if timeout != 0 else -1) + if events: + # check interrupts and return the port_dict + retval, is_port_dict_updated = \ + self.check_interrupts(port_dict) + if (retval != 0): + return False, {} + return True, port_dict + except: return False, {} - + finally: + if self.oir_fd != -1: + self.epoll.unregister(self.oir_fd.fileno()) + self.epoll.close() + self.oir_fd.close() + self.oir_fd = -1 + self.epoll = -1 + + return False, {} diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/sai.profile b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/sai.profile index a690c3ff8b94..1076ddfe28f4 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/sai.profile +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-z9100-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/th-z9100-32x100G.config.bcm b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/th-z9100-32x100G.config.bcm index 39a3695b4cdc..48fa30d78111 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/th-z9100-32x100G.config.bcm +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/th-z9100-32x100G.config.bcm @@ -3,7 +3,7 @@ l3_alpm_enable=2 pfc_deadlock_seq_control=1 bcm_stat_interval=2000000 -bcm_num_cos=8 +bcm_num_cos=10 switch_bypass_mode=0 mmu_lossless=0 lpm_scaling_enable=0 diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/sai.profile b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/sai.profile index 182624c19bd4..b277ae5f0bde 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/sai.profile +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-z9100-8x100G-48x50G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/th-z9100-8x100G-48x50G.config.bcm b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/th-z9100-8x100G-48x50G.config.bcm index 3dd7cc89456d..3130c801a38f 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/th-z9100-8x100G-48x50G.config.bcm +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/th-z9100-8x100G-48x50G.config.bcm @@ -3,7 +3,7 @@ l3_alpm_enable=2 pfc_deadlock_seq_control=1 bcm_stat_interval=2000000 -bcm_num_cos=8 +bcm_num_cos=10 switch_bypass_mode=0 mmu_lossless=0 lpm_scaling_enable=0 diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/plugins/eeprom.py b/device/dell/x86_64-dell_z9100_c2538-r0/plugins/eeprom.py index 8d1d13f4b7cc..eca797ee7637 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/plugins/eeprom.py +++ b/device/dell/x86_64-dell_z9100_c2538-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Dell Z9100 # @@ -11,8 +9,8 @@ try: from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/plugins/psuutil.py b/device/dell/x86_64-dell_z9100_c2538-r0/plugins/psuutil.py index f96fac6f46cf..d6eed4a5a7c1 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/plugins/psuutil.py +++ b/device/dell/x86_64-dell_z9100_c2538-r0/plugins/psuutil.py @@ -14,6 +14,7 @@ HWMON_DIR = "/sys/devices/platform/SMF.512/hwmon/" HWMON_NODE = os.listdir(HWMON_DIR)[0] + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" @@ -26,7 +27,7 @@ def get_pmc_register(self, reg_name): retval = 'ERR' mb_reg_file = mailbox_dir+'/' + reg_name if (not os.path.isfile(mb_reg_file)): - logging.error(mb_reg_file, "not found !") + logging.error(mb_reg_file + " not found !") return retval try: @@ -60,7 +61,7 @@ def get_psu_status(self, index): psu_status = int(psu_status, 16) # Check for PSU statuse if (~psu_status & 0b1000) or (psu_status & 0b0100): - status = 1 + status = 1 return status @@ -77,6 +78,6 @@ def get_psu_presence(self, index): psu_presence = int(psu_presence, 16) # Check for PSU presence if (~psu_presence & 0b1): - status = 1 + status = 1 return status diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/plugins/sfputil.py b/device/dell/x86_64-dell_z9100_c2538-r0/plugins/sfputil.py index 98c01216902d..16b5192522e3 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/plugins/sfputil.py +++ b/device/dell/x86_64-dell_z9100_c2538-r0/plugins/sfputil.py @@ -33,40 +33,40 @@ class SfpUtil(SfpUtilBase): epoll = -1 _port_to_eeprom_mapping = {} _port_to_i2c_mapping = { - 0: [0, 00], # Dummy Entry - 1: [9, 18], - 2: [9, 19], - 3: [9, 20], - 4: [9, 21], - 5: [9, 22], - 6: [9, 23], - 7: [9, 24], - 8: [9, 25], - 9: [8, 26], - 10: [8, 27], - 11: [8, 28], - 12: [8, 29], - 13: [8, 31], # reordered - 14: [8, 30], - 15: [8, 33], # reordered - 16: [8, 32], - 17: [7, 34], - 18: [7, 35], - 19: [7, 36], - 20: [7, 37], - 21: [7, 38], - 22: [7, 39], - 23: [7, 40], - 24: [7, 41], - 25: [6, 42], - 26: [6, 43], - 27: [6, 44], - 28: [6, 45], - 29: [6, 46], - 30: [6, 47], - 31: [6, 48], - 32: [6, 49] - } + 0: [0, 00], # Dummy Entry + 1: [9, 18], + 2: [9, 19], + 3: [9, 20], + 4: [9, 21], + 5: [9, 22], + 6: [9, 23], + 7: [9, 24], + 8: [9, 25], + 9: [8, 26], + 10: [8, 27], + 11: [8, 28], + 12: [8, 29], + 13: [8, 31], # reordered + 14: [8, 30], + 15: [8, 33], # reordered + 16: [8, 32], + 17: [7, 34], + 18: [7, 35], + 19: [7, 36], + 20: [7, 37], + 21: [7, 38], + 22: [7, 39], + 23: [7, 40], + 24: [7, 41], + 25: [6, 42], + 26: [6, 43], + 27: [6, 44], + 28: [6, 45], + 29: [6, 46], + 30: [6, 47], + 31: [6, 48], + 32: [6, 49] + } @property def port_start(self): @@ -78,7 +78,7 @@ def port_end(self): @property def qsfp_ports(self): - return range(self.PORT_START, self.PORTS_IN_BLOCK + 1) + return list(range(self.PORT_START, self.PORTS_IN_BLOCK + 1)) @property def iom1_port_start(self): @@ -124,9 +124,9 @@ def __init__(self): def __del__(self): if self.oir_fd != -1: - self.epoll.unregister(self.oir_fd.fileno()) - self.epoll.close() - self.oir_fd.close() + self.epoll.unregister(self.oir_fd.fileno()) + self.epoll.close() + self.oir_fd.close() def normalize_port(self, port_num): # Check for invalid port_num @@ -153,7 +153,6 @@ def normalize_port(self, port_num): return i2c_line, port_num - def get_presence(self, port_num): i2c_line, port_num = self.normalize_port(port_num) @@ -165,7 +164,7 @@ def get_presence(self, port_num): reg_file = open(qsfp_path, "r") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -193,11 +192,11 @@ def get_low_power_mode(self, port_num): return False try: - qsfp_path = self.BASE_VAL_PATH.format(i2c_line)+"qsfp_lpmode" - reg_file = open(qsfp_path, "r") + qsfp_path = self.BASE_VAL_PATH.format(i2c_line)+"qsfp_lpmode" + reg_file = open(qsfp_path, "r") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -225,12 +224,11 @@ def set_low_power_mode(self, port_num, lpmode): return False try: - qsfp_path = self.BASE_VAL_PATH.format(i2c_line)+"qsfp_lpmode" - reg_file = open(qsfp_path, "r+") - + qsfp_path = self.BASE_VAL_PATH.format(i2c_line)+"qsfp_lpmode" + reg_file = open(qsfp_path, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -266,11 +264,11 @@ def reset(self, port_num): return False try: - qsfp_path = self.BASE_VAL_PATH.format(i2c_line)+"qsfp_lpmode" - reg_file = open(qsfp_path, "r+") + qsfp_path = self.BASE_VAL_PATH.format(i2c_line)+"qsfp_lpmode" + reg_file = open(qsfp_path, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -295,11 +293,11 @@ def reset(self, port_num): # Flip the bit back high and write back to the register to take # port out of reset try: - qsfp_path = self.BASE_VAL_PATH.format(i2c_line)+"qsfp_lpmode" - reg_file = open(qsfp_path, "w+") + qsfp_path = self.BASE_VAL_PATH.format(i2c_line)+"qsfp_lpmode" + reg_file = open(qsfp_path, "w+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = reg_value | mask @@ -310,133 +308,132 @@ def reset(self, port_num): return True def get_register(self, reg_file): - retval = 'ERR' + retval = 'ERR' - if (not os.path.isfile(reg_file)): - print reg_file, 'not found !' - return retval + if (not os.path.isfile(reg_file)): + print(reg_file + ' not found !') + return retval - try: - with open(reg_file, 'r') as fd: - retval = fd.read() - except Exception as error: - logging.error("Unable to open ", reg_file, "file !") + try: + with open(reg_file, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", reg_file, "file !") - retval = retval.rstrip('\r\n') - retval = retval.lstrip(" ") - return retval + retval = retval.rstrip('\r\n') + retval = retval.lstrip(" ") + return retval def check_interrupts(self, port_dict): - retval = 0 - is_port_dict_updated = False - # Read the QSFP ABS interrupt & status registers - cpld2_abs_int = self.get_register( - "/sys/class/i2c-adapter/i2c-14/14-003e/qsfp_abs_int") - cpld2_abs_sta = self.get_register( - "/sys/class/i2c-adapter/i2c-14/14-003e/qsfp_abs_sta") - cpld3_abs_int = self.get_register( - "/sys/class/i2c-adapter/i2c-15/15-003e/qsfp_abs_int") - cpld3_abs_sta = self.get_register( - "/sys/class/i2c-adapter/i2c-15/15-003e/qsfp_abs_sta") - cpld4_abs_int = self.get_register( - "/sys/class/i2c-adapter/i2c-16/16-003e/qsfp_abs_int") - cpld4_abs_sta = self.get_register( - "/sys/class/i2c-adapter/i2c-16/16-003e/qsfp_abs_sta") - - if (cpld2_abs_int == 'ERR' or cpld2_abs_sta == 'ERR' or - cpld3_abs_int == 'ERR' or cpld3_abs_sta == 'ERR' or - cpld4_abs_int == 'ERR' or cpld4_abs_sta == 'ERR'): - return -1 - - cpld2_abs_int = int(cpld2_abs_int, 16) - cpld2_abs_sta = int(cpld2_abs_sta, 16) - cpld3_abs_int = int(cpld3_abs_int, 16) - cpld3_abs_sta = int(cpld3_abs_sta, 16) - cpld4_abs_int = int(cpld4_abs_int, 16) - cpld4_abs_sta = int(cpld4_abs_sta, 16) - - # Make it contiguous (discard reserved bits) - interrupt_reg = (cpld2_abs_int & 0xfff) |\ - ((cpld3_abs_int & 0x3ff) << 12) |\ - ((cpld4_abs_int & 0x3ff) << 22) - status_reg = (cpld2_abs_sta & 0xfff) |\ - ((cpld3_abs_sta & 0x3ff) << 12) |\ - ((cpld4_abs_sta & 0x3ff) << 22) - - port = self.port_start - while port <= self.port_end: - if interrupt_reg & (1 << (port-1)): - # update only if atleast one port has generated - # interrupt - is_port_dict_updated = True - if status_reg & (1 << (port-1)): - # status reg 1 => optics is removed - port_dict[port] = '0' - else: - # status reg 0 => optics is inserted - port_dict[port] = '1' - port += 1 - return retval, is_port_dict_updated + retval = 0 + is_port_dict_updated = False + # Read the QSFP ABS interrupt & status registers + cpld2_abs_int = self.get_register( + "/sys/class/i2c-adapter/i2c-14/14-003e/qsfp_abs_int") + cpld2_abs_sta = self.get_register( + "/sys/class/i2c-adapter/i2c-14/14-003e/qsfp_abs_sta") + cpld3_abs_int = self.get_register( + "/sys/class/i2c-adapter/i2c-15/15-003e/qsfp_abs_int") + cpld3_abs_sta = self.get_register( + "/sys/class/i2c-adapter/i2c-15/15-003e/qsfp_abs_sta") + cpld4_abs_int = self.get_register( + "/sys/class/i2c-adapter/i2c-16/16-003e/qsfp_abs_int") + cpld4_abs_sta = self.get_register( + "/sys/class/i2c-adapter/i2c-16/16-003e/qsfp_abs_sta") + + if (cpld2_abs_int == 'ERR' or cpld2_abs_sta == 'ERR' or + cpld3_abs_int == 'ERR' or cpld3_abs_sta == 'ERR' or + cpld4_abs_int == 'ERR' or cpld4_abs_sta == 'ERR'): + return -1 + + cpld2_abs_int = int(cpld2_abs_int, 16) + cpld2_abs_sta = int(cpld2_abs_sta, 16) + cpld3_abs_int = int(cpld3_abs_int, 16) + cpld3_abs_sta = int(cpld3_abs_sta, 16) + cpld4_abs_int = int(cpld4_abs_int, 16) + cpld4_abs_sta = int(cpld4_abs_sta, 16) + + # Make it contiguous (discard reserved bits) + interrupt_reg = (cpld2_abs_int & 0xfff) |\ + ((cpld3_abs_int & 0x3ff) << 12) |\ + ((cpld4_abs_int & 0x3ff) << 22) + status_reg = (cpld2_abs_sta & 0xfff) |\ + ((cpld3_abs_sta & 0x3ff) << 12) |\ + ((cpld4_abs_sta & 0x3ff) << 22) + + port = self.port_start + while port <= self.port_end: + if interrupt_reg & (1 << (port-1)): + # update only if atleast one port has generated + # interrupt + is_port_dict_updated = True + if status_reg & (1 << (port-1)): + # status reg 1 => optics is removed + port_dict[port] = '0' + else: + # status reg 0 => optics is inserted + port_dict[port] = '1' + port += 1 + return retval, is_port_dict_updated def get_transceiver_change_event(self, timeout=0): - port_dict = {} - try: - # We get notified when there is an SCI interrupt from GPIO SUS6 - # Open the sysfs file and register the epoll object - self.oir_fd = open(self.OIR_FD_PATH, "r") - if self.oir_fd != -1: - # Do a dummy read before epoll register - self.oir_fd.read() - self.epoll = select.epoll() - self.epoll.register(self.oir_fd.fileno(), - select.EPOLLIN & select.EPOLLET) - else: - print("get_transceiver_change_event : unable to create fd") - return False, {} + port_dict = {} + try: + # We get notified when there is an SCI interrupt from GPIO SUS6 + # Open the sysfs file and register the epoll object + self.oir_fd = open(self.OIR_FD_PATH, "r") + if self.oir_fd != -1: + # Do a dummy read before epoll register + self.oir_fd.read() + self.epoll = select.epoll() + self.epoll.register(self.oir_fd.fileno(), + select.EPOLLIN & select.EPOLLET) + else: + print("get_transceiver_change_event : unable to create fd") + return False, {} - # Check for missed interrupts by invoking self.check_interrupts - # which will update the port_dict. - while True: - interrupt_count_start = self.get_register(self.OIR_FD_PATH) + # Check for missed interrupts by invoking self.check_interrupts + # which will update the port_dict. + while True: + interrupt_count_start = self.get_register(self.OIR_FD_PATH) - retval, is_port_dict_updated = \ - self.check_interrupts(port_dict) - if ((retval == 0) and (is_port_dict_updated is True)): - return True, port_dict + retval, is_port_dict_updated = \ + self.check_interrupts(port_dict) + if ((retval == 0) and (is_port_dict_updated is True)): + return True, port_dict - interrupt_count_end = self.get_register(self.OIR_FD_PATH) + interrupt_count_end = self.get_register(self.OIR_FD_PATH) - if (interrupt_count_start == 'ERR' or - interrupt_count_end == 'ERR'): - print("get_transceiver_change_event : \ + if (interrupt_count_start == 'ERR' or + interrupt_count_end == 'ERR'): + print("get_transceiver_change_event : \ unable to retrive interrupt count") - break - - # check_interrupts() itself may take upto 100s of msecs. - # We detect a missed interrupt based on the count - if interrupt_count_start == interrupt_count_end: - break - - # Block until an xcvr is inserted or removed with timeout = -1 - events = self.epoll.poll( - timeout=timeout if timeout != 0 else -1) - if events: - # check interrupts and return the port_dict - retval, is_port_dict_updated = \ - self.check_interrupts(port_dict) - if (retval != 0): - return False, {} - - return True, port_dict - except: - return False, {} - finally: - if self.oir_fd != -1: - self.epoll.unregister(self.oir_fd.fileno()) - self.epoll.close() - self.oir_fd.close() - self.oir_fd = -1 - self.epoll = -1 + break + + # check_interrupts() itself may take upto 100s of msecs. + # We detect a missed interrupt based on the count + if interrupt_count_start == interrupt_count_end: + break + + # Block until an xcvr is inserted or removed with timeout = -1 + events = self.epoll.poll( + timeout=timeout if timeout != 0 else -1) + if events: + # check interrupts and return the port_dict + retval, is_port_dict_updated = \ + self.check_interrupts(port_dict) + if (retval != 0): + return False, {} + return True, port_dict + except: return False, {} + finally: + if self.oir_fd != -1: + self.epoll.unregister(self.oir_fd.fileno()) + self.epoll.close() + self.oir_fd.close() + self.oir_fd = -1 + self.epoll = -1 + return False, {} diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/pmon_daemon_control.json b/device/dell/x86_64-dell_z9100_c2538-r0/pmon_daemon_control.json index 94592fa8cebc..44871c057e82 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/pmon_daemon_control.json +++ b/device/dell/x86_64-dell_z9100_c2538-r0/pmon_daemon_control.json @@ -1,3 +1,4 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/buffers_defaults_t0.j2 index 98ec91a9b694..3369e2cc5e4d 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/buffers_defaults_t0.j2 +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/buffers_defaults_t0.j2 @@ -1,16 +1,15 @@ - -{%- set default_cable = '40m' %} +{%- set default_cable = '5m' %} {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "28550336", + "size": "26284032", "type": "ingress", "mode": "dynamic", - "xoff": "4194112" + "xoff": "6291456" }, - "egress_pool": { - "size": "28550336", + "egress_lossless_pool": { + "size": "32575488", "type": "egress", "mode": "static" } @@ -22,13 +21,13 @@ "dynamic_th":"3" }, "egress_lossless_profile": { - "pool":"[BUFFER_POOL|egress_pool]", + "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", "mode": "static", - "static_th":"32744448" + "static_th":"32575488" }, "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_pool]", + "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", "mode": "dynamic", "dynamic_th":"3" diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/buffers_defaults_t1.j2 index 98ec91a9b694..a1fa90d39779 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/buffers_defaults_t1.j2 +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/buffers_defaults_t1.j2 @@ -1,16 +1,15 @@ - {%- set default_cable = '40m' %} {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "28550336", + "size": "26284032", "type": "ingress", "mode": "dynamic", - "xoff": "4194112" + "xoff": "6291456" }, - "egress_pool": { - "size": "28550336", + "egress_lossless_pool": { + "size": "32575488", "type": "egress", "mode": "static" } @@ -22,13 +21,13 @@ "dynamic_th":"3" }, "egress_lossless_profile": { - "pool":"[BUFFER_POOL|egress_pool]", + "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", "mode": "static", - "static_th":"32744448" + "static_th":"32575488" }, "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_pool]", + "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", "mode": "dynamic", "dynamic_th":"3" 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.profile b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/sai.profile index e5362a7aef00..3491c7700c24 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/sai.profile +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-s5232f-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 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..bf15510bf49b 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 @@ -1,3 +1,4 @@ +sai_load_hw_config=/etc/bcm/flex/bcm56870_a0_issu/b870.6.4.1/ os=unix core_clock_frequency=1525 @@ -541,4 +542,6 @@ dport_map_port_129=126 dport_map_port_66=127 dport_map_port_130=128 -mmu_init_config="TD3-DEFAULT-LOSSLESS-P3P4" +mmu_init_config="TD3-DELL-lossless" +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-C8D48/buffers.json.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers.json.j2 new file mode 100644 index 000000000000..0b1cb2c541b6 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..3369e2cc5e4d --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t0.j2 @@ -0,0 +1,36 @@ +{%- set default_cable = '5m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "26284032", + "type": "ingress", + "mode": "dynamic", + "xoff": "6291456" + }, + "egress_lossless_pool": { + "size": "32575488", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "mode": "static", + "static_th":"32575488" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..3a8e9a92261a --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t1.j2 @@ -0,0 +1,37 @@ +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "26284032", + "type": "ingress", + "mode": "dynamic", + "xoff": "6291456" + }, + "egress_lossless_pool": { + "size": "32575488", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "mode": "static", + "static_th":"32575488" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} + diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/custom_led.bin b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/custom_led.bin new file mode 100755 index 000000000000..49e559cd9813 Binary files /dev/null and b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/custom_led.bin differ diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/linkscan_led_fw.bin b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/linkscan_led_fw.bin new file mode 100755 index 000000000000..c2fa94a2d8cb Binary files /dev/null and b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/linkscan_led_fw.bin differ diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/pg_profile_lookup.ini b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/pg_profile_lookup.ini new file mode 100644 index 000000000000..aedda37a8878 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 1248 2288 35776 -3 2288 + 25000 5m 1248 2288 53248 -3 2288 + 40000 5m 1248 2288 66560 -3 2288 + 50000 5m 1248 2288 90272 -3 2288 + 100000 5m 1248 2288 165568 -3 2288 + 10000 40m 1248 2288 37024 -3 2288 + 25000 40m 1248 2288 53248 -3 2288 + 40000 40m 1248 2288 71552 -3 2288 + 50000 40m 1248 2288 96096 -3 2288 + 100000 40m 1248 2288 177632 -3 2288 + 10000 300m 1248 2288 46176 -3 2288 + 25000 300m 1248 2288 79040 -3 2288 + 40000 300m 1248 2288 108160 -3 2288 + 50000 300m 1248 2288 141856 -3 2288 + 100000 300m 1248 2288 268736 -3 2288 diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/port_config.ini b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/port_config.ini new file mode 100644 index 000000000000..3fc2ef699913 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/port_config.ini @@ -0,0 +1,59 @@ +# name lanes alias index speed +Ethernet0 1,2 fiftyGigE1/1/1 1 50000 +Ethernet2 3,4 fiftyGigE1/1/2 1 50000 +Ethernet4 5,6 fiftyGigE1/2/1 2 50000 +Ethernet6 7,8 fiftyGigE1/2/2 2 50000 +Ethernet8 9,10 fiftyGigE1/3/1 3 50000 +Ethernet10 11,12 fiftyGigE1/3/2 3 50000 +Ethernet12 13,14 fiftyGigE1/4/1 4 50000 +Ethernet14 15,16 fiftyGigE1/4/2 4 50000 +Ethernet16 17,18 fiftyGigE1/5/1 5 50000 +Ethernet18 19,20 fiftyGigE1/5/2 5 50000 +Ethernet20 21,22 fiftyGigE1/6/1 6 50000 +Ethernet22 23,24 fiftyGigE1/6/2 6 50000 +Ethernet24 25,26,27,28 hundredGigE1/7 7 100000 +Ethernet28 29,30,31,32 hundredGigE1/8 8 100000 +Ethernet32 33,34,35,36 hundredGigE1/9 9 100000 +Ethernet36 37,38,39,40 hundredGigE1/10 10 100000 +Ethernet40 41,42 fiftyGigE1/11/1 11 50000 +Ethernet42 43,44 fiftyGigE1/11/2 11 50000 +Ethernet44 45,46 fiftyGigE1/12/1 12 50000 +Ethernet46 47,48 fiftyGigE1/12/2 12 50000 +Ethernet48 49,50 fiftyGigE1/13/1 13 50000 +Ethernet50 51,52 fiftyGigE1/13/2 13 50000 +Ethernet52 53,54 fiftyGigE1/14/1 14 50000 +Ethernet54 55,56 fiftyGigE1/14/2 14 50000 +Ethernet56 57,58 fiftyGigE1/15/1 15 50000 +Ethernet58 59,60 fiftyGigE1/15/2 15 50000 +Ethernet60 61,62 fiftyGigE1/16/1 16 50000 +Ethernet62 63,64 fiftyGigE1/16/2 16 50000 +Ethernet64 65,66 fiftyGigE1/17/1 17 50000 +Ethernet66 67,68 fiftyGigE1/17/2 17 50000 +Ethernet68 69,70 fiftyGigE1/18/1 18 50000 +Ethernet70 71,72 fiftyGigE1/18/2 18 50000 +Ethernet72 73,74 fiftyGigE1/19/1 19 50000 +Ethernet74 75,76 fiftyGigE1/19/2 19 50000 +Ethernet76 77,78 fiftyGigE1/20/1 20 50000 +Ethernet78 79,80 fiftyGigE1/20/2 20 50000 +Ethernet80 81,82 fiftyGigE1/21/1 21 50000 +Ethernet82 83,84 fiftyGigE1/21/2 21 50000 +Ethernet84 85,86 fiftyGigE1/22/1 22 50000 +Ethernet86 87,88 fiftyGigE1/22/2 22 50000 +Ethernet88 89,90,91,92 hundredGigE1/23 23 100000 +Ethernet92 93,94,95,96 hundredGigE1/24 24 100000 +Ethernet96 97,98,99,100 hundredGigE1/25 25 100000 +Ethernet100 101,102,103,104 hundredGigE1/26 26 100000 +Ethernet104 105,106 fiftyGigE1/27/1 27 50000 +Ethernet106 107,108 fiftyGigE1/27/2 27 50000 +Ethernet108 109,110 fiftyGigE1/28/1 28 50000 +Ethernet110 111,112 fiftyGigE1/28/2 28 50000 +Ethernet112 113,114 fiftyGigE1/29/1 29 50000 +Ethernet114 115,116 fiftyGigE1/29/2 29 50000 +Ethernet116 117,118 fiftyGigE1/30/1 30 50000 +Ethernet118 119,120 fiftyGigE1/30/2 30 50000 +Ethernet120 121,122 fiftyGigE1/31/1 31 50000 +Ethernet122 123,124 fiftyGigE1/31/2 31 50000 +Ethernet124 125,126 fiftyGigE1/32/1 32 50000 +Ethernet126 127,128 fiftyGigE1/32/2 32 50000 +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-C8D48/qos.json.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/sai.profile b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/sai.profile new file mode 100644 index 000000000000..b9703d137bb9 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-s5232f-8x100G+48x50G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/sai_preinit_cmd.soc b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/sai_preinit_cmd.soc new file mode 100644 index 000000000000..4d62900f898f --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/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-C8D48/td3-s5232f-8x100G+48x50G.config.bcm b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/td3-s5232f-8x100G+48x50G.config.bcm new file mode 100644 index 000000000000..68fb77a4219f --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/td3-s5232f-8x100G+48x50G.config.bcm @@ -0,0 +1,573 @@ +sai_load_hw_config=/etc/bcm/flex/bcm56870_a0_issu/b870.6.4.1/ +os=unix + +core_clock_frequency=1525 +dpp_clock_ratio=2:3 + +parity_enable=1 +parity_correction=1 +tdma_intr_enable=1 +schan_intr_enable=0 +tdma_intr_enable=1 +miim_intr_enable=1 +stat_if_parity_enable=1 + +port_flex_enable=1 +port_flex_enable_66=0 +port_flex_enable_130=0 +phy_an_c73=3 +phy_an_c73_66=0 +phy_an_c73_130=0 + +module_64ports=0 +table_dma_enable=1 +tdma_timeout_usec=5000000 +mmu_lossless=0 +pdma_descriptor_prefetch_enable=1 +pktdma_poll_mode_channel_bitmap=1 + +l2xmsg_mode=1 +l2xmsg_hostbuf_size=8192 +ipv6_lpm_128b_enable=1 +max_vp_lags=0 + +l3_alpm_enable=2 +l2_mem_entries=32768 +l3_mem_entries=16384 +l3_max_ecmp_mode=1 + +bcm_tunnel_term_compatible_mode=1 +ifp_inports_support_enable=1 + +stable_size=0x5500000 + +oversubscribe_mode=1 +pbmp_oversubscribe=0x6fffffffffffffffdfffffffffffffffe +pbmp_xport_xe=0x6fffffffffffffffdfffffffffffffffe + + +portmap_1.0=1:50:2 +portmap_3.0=3:50:2 +portmap_5.0=5:50:2 +portmap_7.0=7:50:2 +portmap_9.0=9:50:2 +portmap_11.0=11:50:2 +portmap_13.0=13:50:2 +portmap_15.0=15:50:2 +portmap_17.0=17:50:2 +portmap_19.0=19:50:2 +portmap_21.0=21:50:2 +portmap_23.0=23:50:2 +portmap_25.0=25:100 +portmap_29.0=29:100 +portmap_33.0=33:100 +portmap_37.0=37:100 +portmap_41.0=41:50:2 +portmap_43.0=43:50:2 +portmap_45.0=45:50:2 +portmap_47.0=47:50:2 +portmap_49.0=49:50:2 +portmap_51.0=51:50:2 +portmap_53.0=53:50:2 +portmap_55.0=55:50:2 +portmap_57.0=57:50:2 +portmap_59.0=59:50:2 +portmap_61.0=61:50:2 +portmap_63.0=63:50:2 +portmap_67.0=65:50:2 +portmap_69.0=67:50:2 +portmap_71.0=69:50:2 +portmap_73.0=71:50:2 +portmap_75.0=73:50:2 +portmap_77.0=75:50:2 +portmap_79.0=77:50:2 +portmap_81.0=79:50:2 +portmap_83.0=81:50:2 +portmap_85.0=83:50:2 +portmap_87.0=85:50:2 +portmap_89.0=87:50:2 +portmap_91.0=89:100 +portmap_95.0=93:100 +portmap_99.0=97:100 +portmap_103.0=101:100 +portmap_107.0=105:50:2 +portmap_109.0=107:50:2 +portmap_111.0=109:50:2 +portmap_113.0=111:50:2 +portmap_115.0=113:50:2 +portmap_117.0=115:50:2 +portmap_119.0=117:50:2 +portmap_121.0=119:50:2 +portmap_123.0=121:50:2 +portmap_125.0=123:50:2 +portmap_127.0=125:50:2 +portmap_129.0=127:50:2 +portmap_130.0=128:10:m +portmap_66.0=129:10:m + + +phy_chain_tx_lane_map_physical{1.0}=0x0132 +phy_chain_rx_lane_map_physical{1.0}=0x3210 +phy_chain_tx_lane_map_physical{5.0}=0x2301 +phy_chain_rx_lane_map_physical{5.0}=0x2031 +phy_chain_tx_lane_map_physical{9.0}=0x0132 +phy_chain_rx_lane_map_physical{9.0}=0x3210 +phy_chain_tx_lane_map_physical{13.0}=0x3201 +phy_chain_rx_lane_map_physical{13.0}=0x2031 +phy_chain_tx_lane_map_physical{17.0}=0x0123 +phy_chain_rx_lane_map_physical{17.0}=0x3210 +phy_chain_tx_lane_map_physical{21.0}=0x2301 +phy_chain_rx_lane_map_physical{21.0}=0x2031 +phy_chain_tx_lane_map_physical{25.0}=0x0123 +phy_chain_rx_lane_map_physical{25.0}=0x3210 +phy_chain_tx_lane_map_physical{29.0}=0x3201 +phy_chain_rx_lane_map_physical{29.0}=0x2031 +phy_chain_tx_lane_map_physical{33.0}=0x0213 +phy_chain_rx_lane_map_physical{33.0}=0x1302 +phy_chain_tx_lane_map_physical{37.0}=0x1302 +phy_chain_rx_lane_map_physical{37.0}=0x2031 +phy_chain_tx_lane_map_physical{41.0}=0x0231 +phy_chain_rx_lane_map_physical{41.0}=0x3120 +phy_chain_tx_lane_map_physical{45.0}=0x1302 +phy_chain_rx_lane_map_physical{45.0}=0x2031 +phy_chain_tx_lane_map_physical{49.0}=0x2103 +phy_chain_rx_lane_map_physical{49.0}=0x3120 +phy_chain_tx_lane_map_physical{53.0}=0x2301 +phy_chain_rx_lane_map_physical{53.0}=0x2031 +phy_chain_tx_lane_map_physical{57.0}=0x0123 +phy_chain_rx_lane_map_physical{57.0}=0x2301 +phy_chain_tx_lane_map_physical{61.0}=0x3210 +phy_chain_rx_lane_map_physical{61.0}=0x1032 +phy_chain_tx_lane_map_physical{65.0}=0x3210 +phy_chain_rx_lane_map_physical{65.0}=0x1023 +phy_chain_tx_lane_map_physical{69.0}=0x0123 +phy_chain_rx_lane_map_physical{69.0}=0x1302 +phy_chain_tx_lane_map_physical{73.0}=0x2301 +phy_chain_rx_lane_map_physical{73.0}=0x1032 +phy_chain_tx_lane_map_physical{77.0}=0x2013 +phy_chain_rx_lane_map_physical{77.0}=0x3120 +phy_chain_tx_lane_map_physical{81.0}=0x1302 +phy_chain_rx_lane_map_physical{81.0}=0x2031 +phy_chain_tx_lane_map_physical{85.0}=0x0123 +phy_chain_rx_lane_map_physical{85.0}=0x2130 +phy_chain_tx_lane_map_physical{89.0}=0x2301 +phy_chain_rx_lane_map_physical{89.0}=0x2031 +phy_chain_tx_lane_map_physical{93.0}=0x0312 +phy_chain_rx_lane_map_physical{93.0}=0x2310 +phy_chain_tx_lane_map_physical{97.0}=0x2301 +phy_chain_rx_lane_map_physical{97.0}=0x1032 +phy_chain_tx_lane_map_physical{101.0}=0x0123 +phy_chain_rx_lane_map_physical{101.0}=0x3210 +phy_chain_tx_lane_map_physical{105.0}=0x2301 +phy_chain_rx_lane_map_physical{105.0}=0x1032 +phy_chain_tx_lane_map_physical{109.0}=0x0123 +phy_chain_rx_lane_map_physical{109.0}=0x3210 +phy_chain_tx_lane_map_physical{113.0}=0x2301 +phy_chain_rx_lane_map_physical{113.0}=0x2031 +phy_chain_tx_lane_map_physical{117.0}=0x0123 +phy_chain_rx_lane_map_physical{117.0}=0x3210 +phy_chain_tx_lane_map_physical{121.0}=0x2301 +phy_chain_rx_lane_map_physical{121.0}=0x1032 +phy_chain_tx_lane_map_physical{125.0}=0x0123 +phy_chain_rx_lane_map_physical{125.0}=0x3210 +phy_chain_tx_lane_map_physical{129.0}=0x3210 +phy_chain_rx_lane_map_physical{129.0}=0x0231 +phy_chain_tx_lane_map_physical{128.0}=0x3210 +phy_chain_rx_lane_map_physical{128.0}=0x0231 +phy_chain_tx_polarity_flip_physical{1.0}=0x0 +phy_chain_rx_polarity_flip_physical{1.0}=0x0 +phy_chain_tx_polarity_flip_physical{2.0}=0x0 +phy_chain_rx_polarity_flip_physical{2.0}=0x1 +phy_chain_tx_polarity_flip_physical{3.0}=0x0 +phy_chain_rx_polarity_flip_physical{3.0}=0x0 +phy_chain_tx_polarity_flip_physical{4.0}=0x1 +phy_chain_rx_polarity_flip_physical{4.0}=0x1 +phy_chain_tx_polarity_flip_physical{5.0}=0x0 +phy_chain_rx_polarity_flip_physical{5.0}=0x0 +phy_chain_tx_polarity_flip_physical{6.0}=0x1 +phy_chain_rx_polarity_flip_physical{6.0}=0x1 +phy_chain_tx_polarity_flip_physical{7.0}=0x0 +phy_chain_rx_polarity_flip_physical{7.0}=0x1 +phy_chain_tx_polarity_flip_physical{8.0}=0x1 +phy_chain_rx_polarity_flip_physical{8.0}=0x1 +phy_chain_tx_polarity_flip_physical{9.0}=0x0 +phy_chain_rx_polarity_flip_physical{9.0}=0x0 +phy_chain_tx_polarity_flip_physical{10.0}=0x0 +phy_chain_rx_polarity_flip_physical{10.0}=0x1 +phy_chain_tx_polarity_flip_physical{11.0}=0x0 +phy_chain_rx_polarity_flip_physical{11.0}=0x0 +phy_chain_tx_polarity_flip_physical{12.0}=0x1 +phy_chain_rx_polarity_flip_physical{12.0}=0x1 +phy_chain_tx_polarity_flip_physical{13.0}=0x0 +phy_chain_rx_polarity_flip_physical{13.0}=0x0 +phy_chain_tx_polarity_flip_physical{14.0}=0x1 +phy_chain_rx_polarity_flip_physical{14.0}=0x1 +phy_chain_tx_polarity_flip_physical{15.0}=0x0 +phy_chain_rx_polarity_flip_physical{15.0}=0x1 +phy_chain_tx_polarity_flip_physical{16.0}=0x0 +phy_chain_rx_polarity_flip_physical{16.0}=0x1 +phy_chain_tx_polarity_flip_physical{17.0}=0x0 +phy_chain_rx_polarity_flip_physical{17.0}=0x0 +phy_chain_tx_polarity_flip_physical{18.0}=0x1 +phy_chain_rx_polarity_flip_physical{18.0}=0x1 +phy_chain_tx_polarity_flip_physical{19.0}=0x0 +phy_chain_rx_polarity_flip_physical{19.0}=0x0 +phy_chain_tx_polarity_flip_physical{20.0}=0x1 +phy_chain_rx_polarity_flip_physical{20.0}=0x1 +phy_chain_tx_polarity_flip_physical{21.0}=0x0 +phy_chain_rx_polarity_flip_physical{21.0}=0x0 +phy_chain_tx_polarity_flip_physical{22.0}=0x1 +phy_chain_rx_polarity_flip_physical{22.0}=0x1 +phy_chain_tx_polarity_flip_physical{23.0}=0x0 +phy_chain_rx_polarity_flip_physical{23.0}=0x1 +phy_chain_tx_polarity_flip_physical{24.0}=0x1 +phy_chain_rx_polarity_flip_physical{24.0}=0x1 +phy_chain_tx_polarity_flip_physical{25.0}=0x0 +phy_chain_rx_polarity_flip_physical{25.0}=0x1 +phy_chain_tx_polarity_flip_physical{26.0}=0x1 +phy_chain_rx_polarity_flip_physical{26.0}=0x0 +phy_chain_tx_polarity_flip_physical{27.0}=0x0 +phy_chain_rx_polarity_flip_physical{27.0}=0x1 +phy_chain_tx_polarity_flip_physical{28.0}=0x1 +phy_chain_rx_polarity_flip_physical{28.0}=0x0 +phy_chain_tx_polarity_flip_physical{29.0}=0x1 +phy_chain_rx_polarity_flip_physical{29.0}=0x1 +phy_chain_tx_polarity_flip_physical{30.0}=0x1 +phy_chain_rx_polarity_flip_physical{30.0}=0x0 +phy_chain_tx_polarity_flip_physical{31.0}=0x0 +phy_chain_rx_polarity_flip_physical{31.0}=0x0 +phy_chain_tx_polarity_flip_physical{32.0}=0x0 +phy_chain_rx_polarity_flip_physical{32.0}=0x0 +phy_chain_tx_polarity_flip_physical{33.0}=0x1 +phy_chain_rx_polarity_flip_physical{33.0}=0x1 +phy_chain_tx_polarity_flip_physical{34.0}=0x0 +phy_chain_rx_polarity_flip_physical{34.0}=0x0 +phy_chain_tx_polarity_flip_physical{35.0}=0x0 +phy_chain_rx_polarity_flip_physical{35.0}=0x0 +phy_chain_tx_polarity_flip_physical{36.0}=0x1 +phy_chain_rx_polarity_flip_physical{36.0}=0x0 +phy_chain_tx_polarity_flip_physical{37.0}=0x1 +phy_chain_rx_polarity_flip_physical{37.0}=0x1 +phy_chain_tx_polarity_flip_physical{38.0}=0x1 +phy_chain_rx_polarity_flip_physical{38.0}=0x0 +phy_chain_tx_polarity_flip_physical{39.0}=0x1 +phy_chain_rx_polarity_flip_physical{39.0}=0x0 +phy_chain_tx_polarity_flip_physical{40.0}=0x0 +phy_chain_rx_polarity_flip_physical{40.0}=0x1 +phy_chain_tx_polarity_flip_physical{41.0}=0x1 +phy_chain_rx_polarity_flip_physical{41.0}=0x1 +phy_chain_tx_polarity_flip_physical{42.0}=0x0 +phy_chain_rx_polarity_flip_physical{42.0}=0x1 +phy_chain_tx_polarity_flip_physical{43.0}=0x1 +phy_chain_rx_polarity_flip_physical{43.0}=0x0 +phy_chain_tx_polarity_flip_physical{44.0}=0x1 +phy_chain_rx_polarity_flip_physical{44.0}=0x1 +phy_chain_tx_polarity_flip_physical{45.0}=0x1 +phy_chain_rx_polarity_flip_physical{45.0}=0x0 +phy_chain_tx_polarity_flip_physical{46.0}=0x1 +phy_chain_rx_polarity_flip_physical{46.0}=0x0 +phy_chain_tx_polarity_flip_physical{47.0}=0x1 +phy_chain_rx_polarity_flip_physical{47.0}=0x1 +phy_chain_tx_polarity_flip_physical{48.0}=0x0 +phy_chain_rx_polarity_flip_physical{48.0}=0x1 +phy_chain_tx_polarity_flip_physical{49.0}=0x1 +phy_chain_rx_polarity_flip_physical{49.0}=0x0 +phy_chain_tx_polarity_flip_physical{50.0}=0x1 +phy_chain_rx_polarity_flip_physical{50.0}=0x0 +phy_chain_tx_polarity_flip_physical{51.0}=0x0 +phy_chain_rx_polarity_flip_physical{51.0}=0x1 +phy_chain_tx_polarity_flip_physical{52.0}=0x1 +phy_chain_rx_polarity_flip_physical{52.0}=0x1 +phy_chain_tx_polarity_flip_physical{53.0}=0x0 +phy_chain_rx_polarity_flip_physical{53.0}=0x0 +phy_chain_tx_polarity_flip_physical{54.0}=0x1 +phy_chain_rx_polarity_flip_physical{54.0}=0x1 +phy_chain_tx_polarity_flip_physical{55.0}=0x0 +phy_chain_rx_polarity_flip_physical{55.0}=0x1 +phy_chain_tx_polarity_flip_physical{56.0}=0x1 +phy_chain_rx_polarity_flip_physical{56.0}=0x1 +phy_chain_tx_polarity_flip_physical{57.0}=0x1 +phy_chain_rx_polarity_flip_physical{57.0}=0x0 +phy_chain_tx_polarity_flip_physical{58.0}=0x1 +phy_chain_rx_polarity_flip_physical{58.0}=0x1 +phy_chain_tx_polarity_flip_physical{59.0}=0x0 +phy_chain_rx_polarity_flip_physical{59.0}=0x0 +phy_chain_tx_polarity_flip_physical{60.0}=0x1 +phy_chain_rx_polarity_flip_physical{60.0}=0x1 +phy_chain_tx_polarity_flip_physical{61.0}=0x0 +phy_chain_rx_polarity_flip_physical{61.0}=0x1 +phy_chain_tx_polarity_flip_physical{62.0}=0x1 +phy_chain_rx_polarity_flip_physical{62.0}=0x0 +phy_chain_tx_polarity_flip_physical{63.0}=0x0 +phy_chain_rx_polarity_flip_physical{63.0}=0x1 +phy_chain_tx_polarity_flip_physical{64.0}=0x0 +phy_chain_rx_polarity_flip_physical{64.0}=0x0 +phy_chain_tx_polarity_flip_physical{65.0}=0x1 +phy_chain_rx_polarity_flip_physical{65.0}=0x0 +phy_chain_tx_polarity_flip_physical{66.0}=0x0 +phy_chain_rx_polarity_flip_physical{66.0}=0x0 +phy_chain_tx_polarity_flip_physical{67.0}=0x1 +phy_chain_rx_polarity_flip_physical{67.0}=0x1 +phy_chain_tx_polarity_flip_physical{68.0}=0x0 +phy_chain_rx_polarity_flip_physical{68.0}=0x0 +phy_chain_tx_polarity_flip_physical{69.0}=0x1 +phy_chain_rx_polarity_flip_physical{69.0}=0x1 +phy_chain_tx_polarity_flip_physical{70.0}=0x0 +phy_chain_rx_polarity_flip_physical{70.0}=0x0 +phy_chain_tx_polarity_flip_physical{71.0}=0x1 +phy_chain_rx_polarity_flip_physical{71.0}=0x0 +phy_chain_tx_polarity_flip_physical{72.0}=0x0 +phy_chain_rx_polarity_flip_physical{72.0}=0x0 +phy_chain_tx_polarity_flip_physical{73.0}=0x0 +phy_chain_rx_polarity_flip_physical{73.0}=0x1 +phy_chain_tx_polarity_flip_physical{74.0}=0x1 +phy_chain_rx_polarity_flip_physical{74.0}=0x0 +phy_chain_tx_polarity_flip_physical{75.0}=0x0 +phy_chain_rx_polarity_flip_physical{75.0}=0x1 +phy_chain_tx_polarity_flip_physical{76.0}=0x1 +phy_chain_rx_polarity_flip_physical{76.0}=0x0 +phy_chain_tx_polarity_flip_physical{77.0}=0x0 +phy_chain_rx_polarity_flip_physical{77.0}=0x0 +phy_chain_tx_polarity_flip_physical{78.0}=0x0 +phy_chain_rx_polarity_flip_physical{78.0}=0x0 +phy_chain_tx_polarity_flip_physical{79.0}=0x1 +phy_chain_rx_polarity_flip_physical{79.0}=0x1 +phy_chain_tx_polarity_flip_physical{80.0}=0x1 +phy_chain_rx_polarity_flip_physical{80.0}=0x1 +phy_chain_tx_polarity_flip_physical{81.0}=0x0 +phy_chain_rx_polarity_flip_physical{81.0}=0x0 +phy_chain_tx_polarity_flip_physical{82.0}=0x0 +phy_chain_rx_polarity_flip_physical{82.0}=0x0 +phy_chain_tx_polarity_flip_physical{83.0}=0x1 +phy_chain_rx_polarity_flip_physical{83.0}=0x1 +phy_chain_tx_polarity_flip_physical{84.0}=0x1 +phy_chain_rx_polarity_flip_physical{84.0}=0x0 +phy_chain_tx_polarity_flip_physical{85.0}=0x1 +phy_chain_rx_polarity_flip_physical{85.0}=0x1 +phy_chain_tx_polarity_flip_physical{86.0}=0x0 +phy_chain_rx_polarity_flip_physical{86.0}=0x1 +phy_chain_tx_polarity_flip_physical{87.0}=0x1 +phy_chain_rx_polarity_flip_physical{87.0}=0x0 +phy_chain_tx_polarity_flip_physical{88.0}=0x0 +phy_chain_rx_polarity_flip_physical{88.0}=0x0 +phy_chain_tx_polarity_flip_physical{89.0}=0x1 +phy_chain_rx_polarity_flip_physical{89.0}=0x0 +phy_chain_tx_polarity_flip_physical{90.0}=0x0 +phy_chain_rx_polarity_flip_physical{90.0}=0x0 +phy_chain_tx_polarity_flip_physical{91.0}=0x1 +phy_chain_rx_polarity_flip_physical{91.0}=0x1 +phy_chain_tx_polarity_flip_physical{92.0}=0x0 +phy_chain_rx_polarity_flip_physical{92.0}=0x1 +phy_chain_tx_polarity_flip_physical{93.0}=0x1 +phy_chain_rx_polarity_flip_physical{93.0}=0x1 +phy_chain_tx_polarity_flip_physical{94.0}=0x1 +phy_chain_rx_polarity_flip_physical{94.0}=0x1 +phy_chain_tx_polarity_flip_physical{95.0}=0x0 +phy_chain_rx_polarity_flip_physical{95.0}=0x0 +phy_chain_tx_polarity_flip_physical{96.0}=0x0 +phy_chain_rx_polarity_flip_physical{96.0}=0x1 +phy_chain_tx_polarity_flip_physical{97.0}=0x1 +phy_chain_rx_polarity_flip_physical{97.0}=0x1 +phy_chain_tx_polarity_flip_physical{98.0}=0x0 +phy_chain_rx_polarity_flip_physical{98.0}=0x0 +phy_chain_tx_polarity_flip_physical{99.0}=0x1 +phy_chain_rx_polarity_flip_physical{99.0}=0x1 +phy_chain_tx_polarity_flip_physical{100.0}=0x0 +phy_chain_rx_polarity_flip_physical{100.0}=0x0 +phy_chain_tx_polarity_flip_physical{101.0}=0x1 +phy_chain_rx_polarity_flip_physical{101.0}=0x0 +phy_chain_tx_polarity_flip_physical{102.0}=0x0 +phy_chain_rx_polarity_flip_physical{102.0}=0x1 +phy_chain_tx_polarity_flip_physical{103.0}=0x1 +phy_chain_rx_polarity_flip_physical{103.0}=0x0 +phy_chain_tx_polarity_flip_physical{104.0}=0x0 +phy_chain_rx_polarity_flip_physical{104.0}=0x0 +phy_chain_tx_polarity_flip_physical{105.0}=0x1 +phy_chain_rx_polarity_flip_physical{105.0}=0x0 +phy_chain_tx_polarity_flip_physical{106.0}=0x0 +phy_chain_rx_polarity_flip_physical{106.0}=0x1 +phy_chain_tx_polarity_flip_physical{107.0}=0x1 +phy_chain_rx_polarity_flip_physical{107.0}=0x0 +phy_chain_tx_polarity_flip_physical{108.0}=0x0 +phy_chain_rx_polarity_flip_physical{108.0}=0x1 +phy_chain_tx_polarity_flip_physical{109.0}=0x1 +phy_chain_rx_polarity_flip_physical{109.0}=0x1 +phy_chain_tx_polarity_flip_physical{110.0}=0x0 +phy_chain_rx_polarity_flip_physical{110.0}=0x0 +phy_chain_tx_polarity_flip_physical{111.0}=0x1 +phy_chain_rx_polarity_flip_physical{111.0}=0x1 +phy_chain_tx_polarity_flip_physical{112.0}=0x0 +phy_chain_rx_polarity_flip_physical{112.0}=0x0 +phy_chain_tx_polarity_flip_physical{113.0}=0x1 +phy_chain_rx_polarity_flip_physical{113.0}=0x1 +phy_chain_tx_polarity_flip_physical{114.0}=0x0 +phy_chain_rx_polarity_flip_physical{114.0}=0x0 +phy_chain_tx_polarity_flip_physical{115.0}=0x1 +phy_chain_rx_polarity_flip_physical{115.0}=0x0 +phy_chain_tx_polarity_flip_physical{116.0}=0x0 +phy_chain_rx_polarity_flip_physical{116.0}=0x0 +phy_chain_tx_polarity_flip_physical{117.0}=0x1 +phy_chain_rx_polarity_flip_physical{117.0}=0x1 +phy_chain_tx_polarity_flip_physical{118.0}=0x0 +phy_chain_rx_polarity_flip_physical{118.0}=0x0 +phy_chain_tx_polarity_flip_physical{119.0}=0x1 +phy_chain_rx_polarity_flip_physical{119.0}=0x1 +phy_chain_tx_polarity_flip_physical{120.0}=0x0 +phy_chain_rx_polarity_flip_physical{120.0}=0x0 +phy_chain_tx_polarity_flip_physical{121.0}=0x1 +phy_chain_rx_polarity_flip_physical{121.0}=0x0 +phy_chain_tx_polarity_flip_physical{122.0}=0x0 +phy_chain_rx_polarity_flip_physical{122.0}=0x1 +phy_chain_tx_polarity_flip_physical{123.0}=0x1 +phy_chain_rx_polarity_flip_physical{123.0}=0x0 +phy_chain_tx_polarity_flip_physical{124.0}=0x0 +phy_chain_rx_polarity_flip_physical{124.0}=0x1 +phy_chain_tx_polarity_flip_physical{125.0}=0x1 +phy_chain_rx_polarity_flip_physical{125.0}=0x1 +phy_chain_tx_polarity_flip_physical{126.0}=0x0 +phy_chain_rx_polarity_flip_physical{126.0}=0x0 +phy_chain_tx_polarity_flip_physical{127.0}=0x1 +phy_chain_rx_polarity_flip_physical{127.0}=0x1 +phy_chain_tx_polarity_flip_physical{128.0}=0x0 +phy_chain_rx_polarity_flip_physical{128.0}=0x0 +phy_chain_tx_polarity_flip_physical{129.0}=0x1 +phy_chain_rx_polarity_flip_physical{129.0}=0x0 +phy_chain_tx_polarity_flip_physical{130.0}=0x0 +phy_chain_rx_polarity_flip_physical{130.0}=0x0 +phy_chain_tx_polarity_flip_physical{131.0}=0x1 +phy_chain_rx_polarity_flip_physical{131.0}=0x1 +phy_chain_tx_polarity_flip_physical{132.0}=0x0 +phy_chain_rx_polarity_flip_physical{132.0}=0x1 +dport_map_enable=1 +dport_map_port_1=1 +dport_map_port_2=2 +dport_map_port_3=3 +dport_map_port_4=4 +dport_map_port_5=5 +dport_map_port_6=6 +dport_map_port_7=7 +dport_map_port_8=8 +dport_map_port_9=9 +dport_map_port_10=10 +dport_map_port_11=11 +dport_map_port_12=12 +dport_map_port_13=13 +dport_map_port_14=14 +dport_map_port_15=15 +dport_map_port_16=16 +dport_map_port_17=17 +dport_map_port_18=18 +dport_map_port_19=19 +dport_map_port_20=20 +dport_map_port_21=21 +dport_map_port_22=22 +dport_map_port_23=23 +dport_map_port_24=24 +dport_map_port_25=25 +dport_map_port_26=26 +dport_map_port_27=27 +dport_map_port_28=28 +dport_map_port_29=29 +dport_map_port_30=30 +dport_map_port_31=31 +dport_map_port_32=32 +dport_map_port_33=33 +dport_map_port_34=34 +dport_map_port_35=35 +dport_map_port_36=36 +dport_map_port_37=37 +dport_map_port_38=38 +dport_map_port_39=39 +dport_map_port_40=40 +dport_map_port_41=41 +dport_map_port_42=42 +dport_map_port_43=43 +dport_map_port_44=44 +dport_map_port_45=45 +dport_map_port_46=46 +dport_map_port_47=47 +dport_map_port_48=48 +dport_map_port_49=49 +dport_map_port_50=50 +dport_map_port_51=51 +dport_map_port_52=52 +dport_map_port_53=53 +dport_map_port_54=54 +dport_map_port_55=55 +dport_map_port_56=56 +dport_map_port_57=57 +dport_map_port_58=58 +dport_map_port_59=59 +dport_map_port_60=60 +dport_map_port_61=61 +dport_map_port_62=62 +dport_map_port_63=63 +dport_map_port_64=64 +dport_map_port_67=65 +dport_map_port_68=66 +dport_map_port_69=67 +dport_map_port_70=68 +dport_map_port_71=69 +dport_map_port_72=70 +dport_map_port_73=71 +dport_map_port_74=72 +dport_map_port_75=73 +dport_map_port_76=74 +dport_map_port_77=75 +dport_map_port_78=76 +dport_map_port_79=77 +dport_map_port_80=78 +dport_map_port_81=79 +dport_map_port_82=80 +dport_map_port_83=81 +dport_map_port_84=82 +dport_map_port_85=83 +dport_map_port_86=84 +dport_map_port_87=85 +dport_map_port_88=86 +dport_map_port_89=87 +dport_map_port_90=88 +dport_map_port_91=89 +dport_map_port_92=90 +dport_map_port_93=91 +dport_map_port_94=92 +dport_map_port_95=93 +dport_map_port_96=94 +dport_map_port_97=95 +dport_map_port_98=96 +dport_map_port_99=97 +dport_map_port_100=98 +dport_map_port_101=99 +dport_map_port_102=100 +dport_map_port_103=101 +dport_map_port_104=102 +dport_map_port_105=103 +dport_map_port_106=104 +dport_map_port_107=105 +dport_map_port_108=106 +dport_map_port_109=107 +dport_map_port_110=108 +dport_map_port_111=109 +dport_map_port_112=110 +dport_map_port_113=111 +dport_map_port_114=112 +dport_map_port_115=113 +dport_map_port_116=114 +dport_map_port_117=115 +dport_map_port_118=116 +dport_map_port_119=117 +dport_map_port_120=118 +dport_map_port_121=119 +dport_map_port_122=120 +dport_map_port_123=121 +dport_map_port_124=122 +dport_map_port_125=123 +dport_map_port_126=124 +dport_map_port_127=125 +dport_map_port_129=126 +dport_map_port_66=127 +dport_map_port_130=128 + +mmu_init_config="TD3-DELL-lossless" +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/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/buffers_defaults_t0.j2 index c31728e46543..3369e2cc5e4d 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/buffers_defaults_t0.j2 +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/buffers_defaults_t0.j2 @@ -1,46 +1,36 @@ - -{%- set default_cable = '40m' %} +{%- set default_cable = '5m' %} {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "32744448", + "size": "26284032", "type": "ingress", - "mode": "static" + "mode": "dynamic", + "xoff": "6291456" }, - "egress_lossy_pool": { - "size": "32744448", + "egress_lossless_pool": { + "size": "32575488", "type": "egress", - "mode": "dynamic" + "mode": "static" } }, "BUFFER_PROFILE": { "ingress_lossy_profile": { "pool":"[BUFFER_POOL|ingress_lossless_pool]", "size":"0", - "static_th":"32744448" + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "mode": "static", + "static_th":"32575488" }, "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_lossy_pool]", + "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", + "mode": "dynamic", "dynamic_th":"3" } }, {%- endmacro %} - -{%- macro generate_pg_profils(port_names_active) %} - "BUFFER_PG": { - "{{ port_names_active }}|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - } - }, -{%- endmacro %} - -{% macro generate_queue_buffers(port_names_active) %} - "BUFFER_QUEUE": { - "{{ port_names_active }}|0-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - } - } -{% endmacro %} - diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/buffers_defaults_t1.j2 index c31728e46543..a1fa90d39779 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/buffers_defaults_t1.j2 +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/buffers_defaults_t1.j2 @@ -1,46 +1,36 @@ - {%- set default_cable = '40m' %} {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "32744448", + "size": "26284032", "type": "ingress", - "mode": "static" + "mode": "dynamic", + "xoff": "6291456" }, - "egress_lossy_pool": { - "size": "32744448", + "egress_lossless_pool": { + "size": "32575488", "type": "egress", - "mode": "dynamic" + "mode": "static" } }, "BUFFER_PROFILE": { "ingress_lossy_profile": { "pool":"[BUFFER_POOL|ingress_lossless_pool]", "size":"0", - "static_th":"32744448" + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "mode": "static", + "static_th":"32575488" }, "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_lossy_pool]", + "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", + "mode": "dynamic", "dynamic_th":"3" } }, {%- endmacro %} - -{%- macro generate_pg_profils(port_names_active) %} - "BUFFER_PG": { - "{{ port_names_active }}|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - } - }, -{%- endmacro %} - -{% macro generate_queue_buffers(port_names_active) %} - "BUFFER_QUEUE": { - "{{ port_names_active }}|0-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - } - } -{% endmacro %} - diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/sai.profile b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/sai.profile index e5362a7aef00..3491c7700c24 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/sai.profile +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-s5232f-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 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..c44e4805c62a 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 @@ -1,3 +1,4 @@ +sai_load_hw_config=/etc/bcm/flex/bcm56870_a0_issu/b870.6.4.1/ os=unix core_clock_frequency=1525 @@ -541,4 +542,5 @@ dport_map_port_129=126 dport_map_port_66=127 dport_map_port_130=128 -mmu_init_config="TD3-DEFAULT" +mmu_init_config="TD3-DELL-lossless" +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/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/buffers_defaults_t0.j2 index c31728e46543..3369e2cc5e4d 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/buffers_defaults_t0.j2 +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/buffers_defaults_t0.j2 @@ -1,46 +1,36 @@ - -{%- set default_cable = '40m' %} +{%- set default_cable = '5m' %} {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "32744448", + "size": "26284032", "type": "ingress", - "mode": "static" + "mode": "dynamic", + "xoff": "6291456" }, - "egress_lossy_pool": { - "size": "32744448", + "egress_lossless_pool": { + "size": "32575488", "type": "egress", - "mode": "dynamic" + "mode": "static" } }, "BUFFER_PROFILE": { "ingress_lossy_profile": { "pool":"[BUFFER_POOL|ingress_lossless_pool]", "size":"0", - "static_th":"32744448" + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "mode": "static", + "static_th":"32575488" }, "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_lossy_pool]", + "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", + "mode": "dynamic", "dynamic_th":"3" } }, {%- endmacro %} - -{%- macro generate_pg_profils(port_names_active) %} - "BUFFER_PG": { - "{{ port_names_active }}|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - } - }, -{%- endmacro %} - -{% macro generate_queue_buffers(port_names_active) %} - "BUFFER_QUEUE": { - "{{ port_names_active }}|0-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - } - } -{% endmacro %} - diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/buffers_defaults_t1.j2 index c31728e46543..a1fa90d39779 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/buffers_defaults_t1.j2 +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/buffers_defaults_t1.j2 @@ -1,46 +1,36 @@ - {%- set default_cable = '40m' %} {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "32744448", + "size": "26284032", "type": "ingress", - "mode": "static" + "mode": "dynamic", + "xoff": "6291456" }, - "egress_lossy_pool": { - "size": "32744448", + "egress_lossless_pool": { + "size": "32575488", "type": "egress", - "mode": "dynamic" + "mode": "static" } }, "BUFFER_PROFILE": { "ingress_lossy_profile": { "pool":"[BUFFER_POOL|ingress_lossless_pool]", "size":"0", - "static_th":"32744448" + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "mode": "static", + "static_th":"32575488" }, "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_lossy_pool]", + "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", + "mode": "dynamic", "dynamic_th":"3" } }, {%- endmacro %} - -{%- macro generate_pg_profils(port_names_active) %} - "BUFFER_PG": { - "{{ port_names_active }}|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - } - }, -{%- endmacro %} - -{% macro generate_queue_buffers(port_names_active) %} - "BUFFER_QUEUE": { - "{{ port_names_active }}|0-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - } - } -{% endmacro %} - diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/sai.profile b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/sai.profile index 947af7ebacc3..166a0fa8c8bc 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/sai.profile +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-s5232f-96x10G+8x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 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..6f62b7209198 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 @@ -1,3 +1,4 @@ +sai_load_hw_config=/etc/bcm/flex/bcm56870_a0_issu/b870.6.4.1/ os=unix core_clock_frequency=1525 @@ -614,4 +615,5 @@ dport_map_port_129=126 dport_map_port_66=127 dport_map_port_130=128 -mmu_init_config="TD3-DEFAULT" +mmu_init_config="TD3-DELL-lossless" +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/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/buffers_defaults_t0.j2 index c31728e46543..3369e2cc5e4d 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/buffers_defaults_t0.j2 +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/buffers_defaults_t0.j2 @@ -1,46 +1,36 @@ - -{%- set default_cable = '40m' %} +{%- set default_cable = '5m' %} {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "32744448", + "size": "26284032", "type": "ingress", - "mode": "static" + "mode": "dynamic", + "xoff": "6291456" }, - "egress_lossy_pool": { - "size": "32744448", + "egress_lossless_pool": { + "size": "32575488", "type": "egress", - "mode": "dynamic" + "mode": "static" } }, "BUFFER_PROFILE": { "ingress_lossy_profile": { "pool":"[BUFFER_POOL|ingress_lossless_pool]", "size":"0", - "static_th":"32744448" + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "mode": "static", + "static_th":"32575488" }, "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_lossy_pool]", + "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", + "mode": "dynamic", "dynamic_th":"3" } }, {%- endmacro %} - -{%- macro generate_pg_profils(port_names_active) %} - "BUFFER_PG": { - "{{ port_names_active }}|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - } - }, -{%- endmacro %} - -{% macro generate_queue_buffers(port_names_active) %} - "BUFFER_QUEUE": { - "{{ port_names_active }}|0-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - } - } -{% endmacro %} - diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/buffers_defaults_t1.j2 index c31728e46543..a1fa90d39779 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/buffers_defaults_t1.j2 +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/buffers_defaults_t1.j2 @@ -1,46 +1,36 @@ - {%- set default_cable = '40m' %} {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "32744448", + "size": "26284032", "type": "ingress", - "mode": "static" + "mode": "dynamic", + "xoff": "6291456" }, - "egress_lossy_pool": { - "size": "32744448", + "egress_lossless_pool": { + "size": "32575488", "type": "egress", - "mode": "dynamic" + "mode": "static" } }, "BUFFER_PROFILE": { "ingress_lossy_profile": { "pool":"[BUFFER_POOL|ingress_lossless_pool]", "size":"0", - "static_th":"32744448" + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "mode": "static", + "static_th":"32575488" }, "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_lossy_pool]", + "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", + "mode": "dynamic", "dynamic_th":"3" } }, {%- endmacro %} - -{%- macro generate_pg_profils(port_names_active) %} - "BUFFER_PG": { - "{{ port_names_active }}|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - } - }, -{%- endmacro %} - -{% macro generate_queue_buffers(port_names_active) %} - "BUFFER_QUEUE": { - "{{ port_names_active }}|0-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - } - } -{% endmacro %} - diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/sai.profile b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/sai.profile index ae09492f0e76..0c5cf8ca671a 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/sai.profile +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-s5232f-96x25G+8x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 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..a4fccde19686 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 @@ -1,3 +1,4 @@ +sai_load_hw_config=/etc/bcm/flex/bcm56870_a0_issu/b870.6.4.1/ os=unix core_clock_frequency=1525 @@ -614,4 +615,5 @@ dport_map_port_129=126 dport_map_port_66=127 dport_map_port_130=128 -mmu_init_config="TD3-DEFAULT" +mmu_init_config="TD3-DELL-lossless" +sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc 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/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/eeprom.py b/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/eeprom.py index 0b96b00d4ec7..2374ceb790c5 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/eeprom.py +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # DellEMC S5232f # @@ -13,8 +11,8 @@ try: import os.path from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): 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..27042e3122b4 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 @@ -6,17 +6,22 @@ import os.path import logging -import commands import sys +if sys.version_info[0] < 3: + import commands +else: + import subprocess as commands + 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 +47,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) + logging.error('Failed to execute ipmitool') 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 ') - sys.exit(0) + output = ipmi_sdr_list - output = output.split('|')[1] - - logging.basicConfig(level=logging.DEBUG) return output def get_num_psus(self): @@ -86,8 +87,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 +115,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 be2d31a16afc..b56fcc5aafd0 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 @@ -45,12 +45,13 @@ XCVR_DOM_CAPABILITY_OFFSET = 92 XCVR_DOM_CAPABILITY_WIDTH = 1 + 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" @@ -68,7 +69,7 @@ def port_end(self): @property def qsfp_ports(self): - return range(self.PORT_START, self.PORTS_IN_BLOCK + 1) + return list(range(self.PORT_START, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -76,8 +77,8 @@ def port_to_eeprom_mapping(self): def pci_mem_read(self, mm, offset): mm.seek(offset) - read_data_stream=mm.read(4) - reg_val=struct.unpack('I',read_data_stream) + read_data_stream = mm.read(4) + reg_val = struct.unpack('I', read_data_stream) mem_val = str(reg_val)[1:-2] # print "reg_val read:%x"%reg_val return mem_val @@ -85,7 +86,7 @@ def pci_mem_read(self, mm, offset): def pci_mem_write(self, mm, offset, data): mm.seek(offset) # print "data to write:%x"%data - mm.write(struct.pack('I',data)) + mm.write(struct.pack('I', data)) def pci_set_value(self, resource, val, offset): fd = open(resource, O_RDWR) @@ -102,7 +103,7 @@ def pci_get_value(self, resource, offset): mm.close() close(fd) return val - + def init_global_port_presence(self): for port_num in range(self.port_start, (self.port_end + 1)): presence = self.get_presence(port_num) @@ -110,17 +111,17 @@ def init_global_port_presence(self): self._global_port_pres_dict[port_num] = '1' else: self._global_port_pres_dict[port_num] = '0' - + def __init__(self): eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" for x in range(self.port_start, self.port_end + 1): - port_num = x + 1 + port_num = x + 1 self.port_to_eeprom_mapping[x] = eeprom_path.format( - port_num) + port_num) port_num = 0 self.init_global_port_presence() - + SfpUtilBase.__init__(self) def get_presence(self, port_num): @@ -129,18 +130,22 @@ def get_presence(self, port_num): return False # Port offset starts with 0x4004 - port_offset = 16388 + ((port_num-1) * 16) + port_offset = 16388 + ((port_num-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) - status = self.pci_get_value(self.BASE_RES_PATH, port_offset) - reg_value = int(status) - # Absence of status throws error - if (reg_value == "" ): + if (reg_value == ""): return False # 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 @@ -153,14 +158,14 @@ def get_low_power_mode(self, port_num): if port_num < self.port_start or port_num > self.port_end: return False - # Port offset starts with 0x4000 - port_offset = 16384 + ((port_num-1) * 16) + # Port offset starts with 0x4000 + port_offset = 16384 + ((port_num-1) * 16) - status = self.pci_get_value(self.BASE_RES_PATH, port_offset) - reg_value = int(status) + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) # Absence of status throws error - if (reg_value == "" ): + if (reg_value == ""): return False # Mask off 4th bit for presence @@ -178,67 +183,70 @@ def set_low_power_mode(self, port_num, lpmode): if port_num < self.port_start or port_num > self.port_end: return False - # Port offset starts with 0x4000 - port_offset = 16384 + ((port_num-1) * 16) + # Port offset starts with 0x4000 + port_offset = 16384 + ((port_num-1) * 16) - status = self.pci_get_value(self.BASE_RES_PATH, port_offset) - reg_value = int(status) + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) # Absence of status throws error - if (reg_value == "" ): + if (reg_value == ""): return False - # Mask off 4th bit for presence + # Mask off 6th bit for lpmode mask = (1 << 6) - - # LPMode is active high; set or clear the bit accordingly + + # LPMode is active high; set or clear the bit accordingly if lpmode is True: reg_value = reg_value | mask else: reg_value = reg_value & ~mask # Convert our register value back to a hex string and write back - status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) return True def reset(self, port_num): - # Check for invalid port_num + # Check for invalid port_num if port_num < self.port_start or port_num > self.port_end: return False - # Port offset starts with 0x4000 - port_offset = 16384 + ((port_num-1) * 16) + # Port offset starts with 0x4000 + port_offset = 16384 + ((port_num-1) * 16) - status = self.pci_get_value(self.BASE_RES_PATH, port_offset) - reg_value = int(status) + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) # Absence of status throws error - if (reg_value == "" ): + if (reg_value == ""): return False # Mask off 4th bit for presence - mask = (1 << 6) + mask = (1 << 4) # ResetL is active low reg_value = reg_value & ~mask - # Convert our register value back to a hex string and write back - status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + # Convert our register value back to a hex string and write back + status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) # Sleep 1 second to allow it to settle time.sleep(1) reg_value = reg_value | mask - # Convert our register value back to a hex string and write back - status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + # Convert our register value back to a hex string and write back + status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) return True 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) @@ -251,9 +259,17 @@ def get_transceiver_change_event(self, timeout=0): 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) - time.sleep(0.5) + return True, port_dict def get_transceiver_dom_info_dict(self, port_num): transceiver_dom_info_dict = {} @@ -263,13 +279,14 @@ def get_transceiver_dom_info_dict(self, port_num): '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) + file_path = self._get_port_eeprom_path( + port_num, self.IDENTITY_EEPROM_ADDR) if not self._sfp_eeprom_present(file_path, 0): return None @@ -291,27 +308,34 @@ def get_transceiver_dom_info_dict(self, port_num): # 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) + 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) + qspf_dom_capability_data = sfpi_obj.parse_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) + 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) + 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) + 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) + 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) + qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev( + qsfp_dom_rev_raw, 0) else: return transceiver_dom_info_dict @@ -324,9 +348,11 @@ def get_transceiver_dom_info_dict(self, port_num): 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) + 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) + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( + dom_channel_monitor_raw, 0) else: return transceiver_dom_info_dict @@ -335,9 +361,11 @@ def get_transceiver_dom_info_dict(self, port_num): 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) + 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) + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power( + dom_channel_monitor_raw, 0) else: return None @@ -364,47 +392,50 @@ def get_transceiver_dom_info_dict(self, port_num): transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['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 + 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) + 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) + 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) + 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) + dom_temperature_data = sfpd_obj.parse_temperature( + dom_temperature_raw, 0) else: - return transceiver_dom_info_dict + return transceiver_dom_info_dict - dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_VOLT_OFFSET), - SFP_VOLT_WIDTH) + 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_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) + 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) + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( + dom_channel_monitor_raw, 0) else: - return transceiver_dom_info_dict + return transceiver_dom_info_dict try: - sysfsfile_eeprom.close() + sysfsfile_eeprom.close() except IOError: - print("Error: closing sysfs file %s" % file_path) - return None + 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'] @@ -421,8 +452,8 @@ def get_transceiver_dom_info_dict(self, port_num): transceiver_dom_info_dict['tx3power'] = 'N/A' transceiver_dom_info_dict['tx4power'] = 'N/A' - return transceiver_dom_info_dict - + 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', @@ -435,11 +466,13 @@ def get_transceiver_dom_threshold_info_dict(self, port_num): 'txpowerlowalarm', 'txpowerlowwarning', 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning' - ] - transceiver_dom_threshold_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') + ] + 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) + file_path = self._get_port_eeprom_path( + port_num, self.IDENTITY_EEPROM_ADDR) if not self._sfp_eeprom_present(file_path, 0): return None @@ -457,20 +490,22 @@ def get_transceiver_dom_threshold_info_dict(self, port_num): # 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) + 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) + 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) + 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) + dom_channel_threshold_data = sfpd_obj.parse_channel_threshold_values( + dom_channel_threshold_raw, 0) else: return transceiver_dom_threshold_info_dict @@ -500,25 +535,27 @@ def get_transceiver_dom_threshold_info_dict(self, port_num): else: offset = 256 - file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR) + 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) + 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) + + 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) - + + 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) + dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold( + dom_module_threshold_raw, 0) else: return transceiver_dom_threshold_info_dict @@ -528,14 +565,15 @@ def get_transceiver_dom_threshold_info_dict(self, port_num): print("Error: closing sysfs file %s" % file_path) return None - #Threshold Data + # 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['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'] @@ -549,5 +587,5 @@ def get_transceiver_dom_threshold_info_dict(self, port_num): 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 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..e15132a189b1 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,3 @@ { - "skip_ledd": true + "skip_ledd": true } diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/sai.profile b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/sai.profile index 52afc687173c..72f420de5d40 100644 --- a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/sai.profile +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-s5248f-10g.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/td3-s5248f-10g.config.bcm b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/td3-s5248f-10g.config.bcm index 2369f4590795..021f94dc32f7 100644 --- a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/td3-s5248f-10g.config.bcm +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/td3-s5248f-10g.config.bcm @@ -1,3 +1,4 @@ +sai_load_hw_config=/etc/bcm/flex/bcm56870_a0_issu/b870.6.4.1/ os=unix dpp_clock_ratio=2:3 oversubscribe_mode=1 diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/sai.profile b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/sai.profile index 4753ec3886c4..eb9a3cb196fe 100644 --- a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/sai.profile +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-s5248f-25g.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/td3-s5248f-25g.config.bcm b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/td3-s5248f-25g.config.bcm index 4095c2d0a4f4..2630512df0ca 100644 --- a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/td3-s5248f-25g.config.bcm +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/td3-s5248f-25g.config.bcm @@ -1,3 +1,4 @@ +sai_load_hw_config=/etc/bcm/flex/bcm56870_a0_issu/b870.6.4.1/ os=unix dpp_clock_ratio=2:3 diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/eeprom.py b/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/eeprom.py index b6305a6ed634..dc7eeb330215 100644 --- a/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/eeprom.py +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # DellEMC S5248f # @@ -13,8 +11,8 @@ try: import os.path from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/psuutil.py b/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/psuutil.py index 8004697d7c0a..9cd186611486 100644 --- a/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/psuutil.py +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/psuutil.py @@ -6,9 +6,13 @@ import os.path import logging -import commands import sys +if sys.version_info[0] < 3: + import commands +else: + import subprocess as commands + S5248F_MAX_PSUS = 2 IPMI_PSU_DATA = "docker exec -it pmon ipmitool sdr list" @@ -102,6 +106,5 @@ def get_psu_presence(self, index): if (psu_status != 'ERR'): # Check for PSU presence if (psu_status == 0x00): - status = 1 + status = 1 return status - diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/sfputil.py b/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/sfputil.py index 4bc0745df2de..dba21ed11bdb 100644 --- a/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/sfputil.py +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/sfputil.py @@ -21,7 +21,7 @@ except ImportError as e: raise ImportError("%s - required module not found" % str(e)) -#definitions of the offset and width for values in DOM info eeprom +# definitions of the offset and width for values in DOM info eeprom QSFP_DOM_REV_OFFSET = 1 QSFP_DOM_REV_WIDTH = 1 QSFP_TEMPE_OFFSET = 22 @@ -48,6 +48,7 @@ XCVR_DOM_CAPABILITY_OFFSET = 92 XCVR_DOM_CAPABILITY_WIDTH = 1 + class SfpUtil(SfpUtilBase): """Platform-specific SfpUtil class""" @@ -58,68 +59,67 @@ class SfpUtil(SfpUtilBase): BASE_RES_PATH = "/sys/bus/pci/devices/0000:04:00.0/resource0" _port_to_i2c_mapping = { - 1: 2, - 2: 3, - 3: 4, - 4: 5, - 5: 6, - 6: 7, - 7: 8, - 8: 9, - 9: 10, - 10: 11, - 11: 12, - 12: 13, - 13: 14, - 14: 15, - 15: 16, - 16: 17, - 17: 18, - 18: 19, - 19: 20, - 20: 21, - 21: 22, - 22: 23, - 23: 24, - 24: 25, - 25: 26, - 26: 27, - 27: 28, - 28: 29, - 29: 30, - 30: 31, - 31: 32, - 32: 33, - 33: 34, - 34: 35, - 35: 36, - 36: 37, - 37: 38, - 38: 39, - 39: 40, - 40: 41, - 41: 42, - 42: 43, - 43: 44, - 44: 45, - 45: 46, - 46: 47, - 47: 48, - 48: 49, - # DD + QSFP28 - 49: 50, - 50: 50, - 51: 51, - 52: 51, - 53: 52, - 54: 53, - 55: 54, - 56: 55, - } + 1: 2, + 2: 3, + 3: 4, + 4: 5, + 5: 6, + 6: 7, + 7: 8, + 8: 9, + 9: 10, + 10: 11, + 11: 12, + 12: 13, + 13: 14, + 14: 15, + 15: 16, + 16: 17, + 17: 18, + 18: 19, + 19: 20, + 20: 21, + 21: 22, + 22: 23, + 23: 24, + 24: 25, + 25: 26, + 26: 27, + 27: 28, + 28: 29, + 29: 30, + 30: 31, + 31: 32, + 32: 33, + 33: 34, + 34: 35, + 35: 36, + 36: 37, + 37: 38, + 38: 39, + 39: 40, + 40: 41, + 41: 42, + 42: 43, + 43: 44, + 44: 45, + 45: 46, + 46: 47, + 47: 48, + 48: 49, + # DD + QSFP28 + 49: 50, + 50: 50, + 51: 51, + 52: 51, + 53: 52, + 54: 53, + 55: 54, + 56: 55, + } _port_to_eeprom_mapping = {} - _global_port_pres_dict = {} @property @@ -132,7 +132,7 @@ def port_end(self): @property def qsfp_ports(self): - return range(49, self.PORTS_IN_BLOCK + 1) + return list(range(49, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -140,8 +140,8 @@ def port_to_eeprom_mapping(self): def pci_mem_read(self, mm, offset): mm.seek(offset) - read_data_stream=mm.read(4) - reg_val=struct.unpack('I',read_data_stream) + read_data_stream = mm.read(4) + reg_val = struct.unpack('I', read_data_stream) mem_val = str(reg_val)[1:-2] # print "reg_val read:%x"%reg_val return mem_val @@ -149,7 +149,7 @@ def pci_mem_read(self, mm, offset): def pci_mem_write(self, mm, offset, data): mm.seek(offset) # print "data to write:%x"%data - mm.write(struct.pack('I',data)) + mm.write(struct.pack('I', data)) def pci_set_value(self, resource, val, offset): fd = open(resource, O_RDWR) @@ -166,7 +166,7 @@ def pci_get_value(self, resource, offset): mm.close() close(fd) return val - + def init_global_port_presence(self): for port_num in range(self.port_start, (self.port_end + 1)): presence = self.get_presence(port_num) @@ -174,13 +174,13 @@ def init_global_port_presence(self): self._global_port_pres_dict[port_num] = '1' else: self._global_port_pres_dict[port_num] = '0' - + def __init__(self): eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" for x in range(self.port_start, self.port_end + 1): self.port_to_eeprom_mapping[x] = eeprom_path.format( - self._port_to_i2c_mapping[x]) + self._port_to_i2c_mapping[x]) self.init_global_port_presence() SfpUtilBase.__init__(self) @@ -190,13 +190,13 @@ def get_presence(self, port_num): return False # Port offset starts with 0x4004 - port_offset = 16388 + ((port_num-1) * 16) + port_offset = 16388 + ((port_num-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) - status = self.pci_get_value(self.BASE_RES_PATH, port_offset) - reg_value = int(status) - # Absence of status throws error - if (reg_value == "" ): + if (reg_value == ""): return False # Mask off bit for presence @@ -204,7 +204,6 @@ def get_presence(self, port_num): if (port_num > 48): mask = (1 << 4) - # ModPrsL is active low if reg_value & mask == 0: return True @@ -217,14 +216,14 @@ def get_low_power_mode(self, port_num): if port_num < self.port_start or port_num > self.port_end: return False - # Port offset starts with 0x4000 - port_offset = 16384 + ((port_num-1) * 16) + # Port offset starts with 0x4000 + port_offset = 16384 + ((port_num-1) * 16) - status = self.pci_get_value(self.BASE_RES_PATH, port_offset) - reg_value = int(status) + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) # Absence of status throws error - if (reg_value == "" ): + if (reg_value == ""): return False # Mask off 4th bit for presence @@ -242,62 +241,62 @@ def set_low_power_mode(self, port_num, lpmode): if port_num < self.port_start or port_num > self.port_end: return False - # Port offset starts with 0x4000 - port_offset = 16384 + ((port_num-1) * 16) + # Port offset starts with 0x4000 + port_offset = 16384 + ((port_num-1) * 16) - status = self.pci_get_value(self.BASE_RES_PATH, port_offset) - reg_value = int(status) + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) # Absence of status throws error - if (reg_value == "" ): + if (reg_value == ""): return False - # Mask off 4th bit for presence + # Mask off 6th bit for lpmode mask = (1 << 6) - - # LPMode is active high; set or clear the bit accordingly + + # LPMode is active high; set or clear the bit accordingly if lpmode is True: reg_value = reg_value | mask else: reg_value = reg_value & ~mask # Convert our register value back to a hex string and write back - status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) return True def reset(self, port_num): - # Check for invalid port_num + # Check for invalid port_num if port_num < self.port_start or port_num > self.port_end: return False - # Port offset starts with 0x4000 - port_offset = 16384 + ((port_num-1) * 16) + # Port offset starts with 0x4000 + port_offset = 16384 + ((port_num-1) * 16) - status = self.pci_get_value(self.BASE_RES_PATH, port_offset) - reg_value = int(status) + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) # Absence of status throws error - if (reg_value == "" ): + if (reg_value == ""): return False # Mask off 4th bit for presence - mask = (1 << 6) + mask = (1 << 4) # ResetL is active low reg_value = reg_value & ~mask - # Convert our register value back to a hex string and write back - status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + # Convert our register value back to a hex string and write back + status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) # Sleep 1 second to allow it to settle time.sleep(1) reg_value = reg_value | mask - # Convert our register value back to a hex string and write back - status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + # Convert our register value back to a hex string and write back + status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) return True @@ -318,7 +317,7 @@ def get_transceiver_change_event(self, timeout=0): return True, port_dict time.sleep(0.5) - + def get_transceiver_dom_info_dict(self, port_num): transceiver_dom_info_dict = {} @@ -327,13 +326,14 @@ def get_transceiver_dom_info_dict(self, port_num): '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) + file_path = self._get_port_eeprom_path( + port_num, self.IDENTITY_EEPROM_ADDR) if not self._sfp_eeprom_present(file_path, 0): return None @@ -355,27 +355,34 @@ def get_transceiver_dom_info_dict(self, port_num): # 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) + 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) + qspf_dom_capability_data = sfpi_obj.parse_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) + 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) + 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) + 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) + 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) + qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev( + qsfp_dom_rev_raw, 0) else: return transceiver_dom_info_dict @@ -388,9 +395,11 @@ def get_transceiver_dom_info_dict(self, port_num): 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) + 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) + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( + dom_channel_monitor_raw, 0) else: return transceiver_dom_info_dict @@ -399,9 +408,11 @@ def get_transceiver_dom_info_dict(self, port_num): 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) + 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) + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power( + dom_channel_monitor_raw, 0) else: return None @@ -428,48 +439,51 @@ def get_transceiver_dom_info_dict(self, port_num): transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['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 + 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) + 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) + 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) - + SFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: - dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + 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) + 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_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) + 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) + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( + dom_channel_monitor_raw, 0) else: - return transceiver_dom_info_dict + return transceiver_dom_info_dict try: - sysfsfile_eeprom.close() + sysfsfile_eeprom.close() except IOError: - print("Error: closing sysfs file %s" % file_path) - return None + 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'] @@ -486,8 +500,8 @@ def get_transceiver_dom_info_dict(self, port_num): transceiver_dom_info_dict['tx3power'] = 'N/A' transceiver_dom_info_dict['tx4power'] = 'N/A' - return transceiver_dom_info_dict - + 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', @@ -500,11 +514,13 @@ def get_transceiver_dom_threshold_info_dict(self, port_num): 'txpowerlowalarm', 'txpowerlowwarning', 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning' - ] - transceiver_dom_threshold_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') + ] + 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) + file_path = self._get_port_eeprom_path( + port_num, self.IDENTITY_EEPROM_ADDR) if not self._sfp_eeprom_present(file_path, 0): return None @@ -522,20 +538,22 @@ def get_transceiver_dom_threshold_info_dict(self, port_num): # 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) + 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) + 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) + 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) + dom_channel_threshold_data = sfpd_obj.parse_channel_threshold_values( + dom_channel_threshold_raw, 0) else: return transceiver_dom_threshold_info_dict @@ -565,25 +583,27 @@ def get_transceiver_dom_threshold_info_dict(self, port_num): else: offset = 256 - file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR) + 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) + 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) + + 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) - + + 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) + dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold( + dom_module_threshold_raw, 0) else: return transceiver_dom_threshold_info_dict @@ -593,7 +613,7 @@ def get_transceiver_dom_threshold_info_dict(self, port_num): print("Error: closing sysfs file %s" % file_path) return None - #Threshold Data + # 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'] @@ -614,5 +634,5 @@ def get_transceiver_dom_threshold_info_dict(self, port_num): 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 diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/buffers.json.j2 b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/buffers.json.j2 new file mode 100644 index 000000000000..0b1cb2c541b6 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..c31728e46543 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/buffers_defaults_t0.j2 @@ -0,0 +1,46 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "32744448", + "type": "ingress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "32744448", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"32744448" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names_active) %} + "BUFFER_PG": { + "{{ port_names_active }}|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, +{%- endmacro %} + +{% macro generate_queue_buffers(port_names_active) %} + "BUFFER_QUEUE": { + "{{ port_names_active }}|0-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +{% endmacro %} + diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..c31728e46543 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/buffers_defaults_t1.j2 @@ -0,0 +1,46 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "32744448", + "type": "ingress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "32744448", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"32744448" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names_active) %} + "BUFFER_PG": { + "{{ port_names_active }}|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, +{%- endmacro %} + +{% macro generate_queue_buffers(port_names_active) %} + "BUFFER_QUEUE": { + "{{ port_names_active }}|0-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +{% endmacro %} + diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/custom_led.bin b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/custom_led.bin new file mode 100755 index 000000000000..302a41d9789a Binary files /dev/null and b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/custom_led.bin differ diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/linkscan_led_fw.bin b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/linkscan_led_fw.bin new file mode 100755 index 000000000000..c2fa94a2d8cb Binary files /dev/null and b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/linkscan_led_fw.bin differ diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/port_config.ini b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/port_config.ini new file mode 100644 index 000000000000..f16b3e656a18 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/port_config.ini @@ -0,0 +1,105 @@ +# name lanes alias index speed +Ethernet0 5 tenGigE1/1/1 1 10000 +Ethernet1 6 tenGigE1/1/2 2 10000 +Ethernet2 7 tenGigE1/1/3 3 10000 +Ethernet3 8 tenGigE1/1/4 4 10000 +Ethernet4 13 tenGigE1/2/1 5 10000 +Ethernet5 14 tenGigE1/2/2 6 10000 +Ethernet6 15 tenGigE1/2/3 7 10000 +Ethernet7 16 tenGigE1/2/4 8 10000 +Ethernet8 17 tenGigE1/3/1 9 10000 +Ethernet9 18 tenGigE1/3/2 10 10000 +Ethernet10 19 tenGigE1/3/3 11 10000 +Ethernet11 20 tenGigE1/3/4 12 10000 +Ethernet12 37 tenGigE1/4/1 13 10000 +Ethernet13 38 tenGigE1/4/2 14 10000 +Ethernet14 39 tenGigE1/4/3 15 10000 +Ethernet15 40 tenGigE1/4/4 16 10000 +Ethernet16 45 tenGigE1/5/1 17 10000 +Ethernet17 46 tenGigE1/5/2 18 10000 +Ethernet18 47 tenGigE1/5/3 19 10000 +Ethernet19 48 tenGigE1/5/4 20 10000 +Ethernet20 53 tenGigE1/6/1 21 10000 +Ethernet21 54 tenGigE1/6/2 22 10000 +Ethernet22 55 tenGigE1/6/3 23 10000 +Ethernet23 56 tenGigE1/6/4 24 10000 +Ethernet24 65 tenGigE1/7/1 25 10000 +Ethernet25 66 tenGigE1/7/2 26 10000 +Ethernet26 67 tenGigE1/7/3 27 10000 +Ethernet27 68 tenGigE1/7/4 28 10000 +Ethernet28 73 tenGigE1/8/1 29 10000 +Ethernet29 74 tenGigE1/8/2 30 10000 +Ethernet30 75 tenGigE1/8/3 31 10000 +Ethernet31 76 tenGigE1/8/4 32 10000 +Ethernet32 89 tenGigE1/9/1 33 10000 +Ethernet33 90 tenGigE1/9/2 34 10000 +Ethernet34 91 tenGigE1/9/3 35 10000 +Ethernet35 92 tenGigE1/9/4 36 10000 +Ethernet36 101 tenGigE1/10/1 37 10000 +Ethernet37 102 tenGigE1/10/2 38 10000 +Ethernet38 103 tenGigE1/10/3 39 10000 +Ethernet39 104 tenGigE1/10/4 40 10000 +Ethernet40 109 tenGigE1/11/1 41 10000 +Ethernet41 110 tenGigE1/11/2 42 10000 +Ethernet42 111 tenGigE1/11/3 43 10000 +Ethernet43 112 tenGigE1/11/4 44 10000 +Ethernet44 117 tenGigE1/12/1 45 10000 +Ethernet45 118 tenGigE1/12/2 46 10000 +Ethernet46 119 tenGigE1/12/3 47 10000 +Ethernet47 120 tenGigE1/12/4 48 10000 +Ethernet48 1 tenGigE1/13/1 49 10000 +Ethernet49 2 tenGigE1/13/2 50 10000 +Ethernet50 3 tenGigE1/13/3 51 10000 +Ethernet51 4 tenGigE1/13/4 52 10000 +Ethernet52 9 tenGigE1/14/1 53 10000 +Ethernet53 10 tenGigE1/14/2 54 10000 +Ethernet54 11 tenGigE1/14/3 55 10000 +Ethernet55 12 tenGigE1/14/4 56 10000 +Ethernet56 25 tenGigE1/15/1 57 10000 +Ethernet57 26 tenGigE1/15/2 58 10000 +Ethernet58 27 tenGigE1/15/3 59 10000 +Ethernet59 28 tenGigE1/15/4 60 10000 +Ethernet60 33 tenGigE1/16/1 61 10000 +Ethernet61 34 tenGigE1/16/2 62 10000 +Ethernet62 35 tenGigE1/16/3 63 10000 +Ethernet63 36 tenGigE1/16/4 64 10000 +Ethernet64 41 tenGigE1/17/1 65 10000 +Ethernet65 42 tenGigE1/17/2 66 10000 +Ethernet66 43 tenGigE1/17/3 67 10000 +Ethernet67 44 tenGigE1/17/4 68 10000 +Ethernet68 49 tenGigE1/18/1 69 10000 +Ethernet69 50 tenGigE1/18/2 70 10000 +Ethernet70 51 tenGigE1/18/3 71 10000 +Ethernet71 52 tenGigE1/18/4 72 10000 +Ethernet72 69 tenGigE1/19/1 73 10000 +Ethernet73 70 tenGigE1/19/2 74 10000 +Ethernet74 71 tenGigE1/19/3 75 10000 +Ethernet75 72 tenGigE1/19/4 76 10000 +Ethernet76 77 tenGigE1/20/1 77 10000 +Ethernet77 78 tenGigE1/20/2 78 10000 +Ethernet78 79 tenGigE1/20/3 79 10000 +Ethernet79 80 tenGigE1/20/4 80 10000 +Ethernet80 81 tenGigE1/21/1 81 10000 +Ethernet81 82 tenGigE1/21/2 82 10000 +Ethernet82 83 tenGigE1/21/3 83 10000 +Ethernet83 84 tenGigE1/21/4 84 10000 +Ethernet84 97 tenGigE1/22/1 85 10000 +Ethernet85 98 tenGigE1/22/2 86 10000 +Ethernet86 99 tenGigE1/22/3 87 10000 +Ethernet87 100 tenGigE1/22/4 88 10000 +Ethernet88 105 tenGigE1/23/1 89 10000 +Ethernet89 106 tenGigE1/23/2 90 10000 +Ethernet90 107 tenGigE1/23/3 91 10000 +Ethernet91 108 tenGigE1/23/4 92 10000 +Ethernet92 113 tenGigE1/24/1 93 10000 +Ethernet93 114 tenGigE1/24/2 94 10000 +Ethernet94 115 tenGigE1/24/3 95 10000 +Ethernet95 116 tenGigE1/24/4 96 10000 +Ethernet96 29,30,31,32 hundredGigE1/49 97 100000 +Ethernet97 21,22,23,24 hundredGigE1/50 98 100000 +Ethernet98 125,126,127,128 hundredGigE1/51 99 100000 +Ethernet99 85,86,87,88 hundredGigE1/52 100 100000 +Ethernet100 57,58,59,60 hundredGigE1/53 101 100000 +Ethernet101 61,62,63,64 hundredGigE1/54 102 100000 +Ethernet102 121,122,123,124 hundredGigE1/55 103 100000 +Ethernet103 93,94,95,96 hundredGigE1/56 104 100000 diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/qos.json.j2 b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/qos.json.j2 new file mode 100644 index 000000000000..d2b3d2b0131c --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/qos.json.j2 @@ -0,0 +1,226 @@ +{%- set PORT_ALL = [] %} +{%- for port in PORT %} + {%- if PORT_ALL.append(port) %}{% endif %} +{%- endfor %} +{%- if PORT_ALL | sort_by_port_index %}{% endif %} + +{%- set port_names_list_all = [] %} +{%- for port in PORT_ALL %} + {%- if port_names_list_all.append(port) %}{% endif %} +{%- endfor %} +{%- set port_names_all = port_names_list_all | join(',') -%} + + +{%- set PORT_ACTIVE = [] %} +{%- if DEVICE_NEIGHBOR is not defined %} + {%- set PORT_ACTIVE = PORT_ALL %} +{%- else %} + {%- for port in DEVICE_NEIGHBOR.keys() %} + {%- if PORT_ACTIVE.append(port) %}{%- endif %} + {%- endfor %} +{%- endif %} +{%- if PORT_ACTIVE | sort_by_port_index %}{% endif %} + +{%- set port_names_list_active = [] %} +{%- for port in PORT_ACTIVE %} + {%- if port_names_list_active.append(port) %}{%- endif %} +{%- endfor %} +{%- set port_names_active = port_names_list_active | join(',') -%} + + +{%- set pfc_to_pg_map_supported_asics = ['mellanox', 'barefoot', 'marvell'] -%} + + +{ +{% if generate_tc_to_pg_map is defined %} + {{- generate_tc_to_pg_map() }} +{% else %} + "TC_TO_PRIORITY_GROUP_MAP": { + "DEFAULT": { + "0": "0", + "1": "0", + "2": "0", + "3": "0", + "4": "0", + "5": "0", + "6": "0", + "7": "7" + } + }, +{% endif %} + "MAP_PFC_PRIORITY_TO_QUEUE": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "DEFAULT": { + "0" : "0", + "1" : "0", + "2" : "0", + "3" : "0", + "4" : "0", + "5" : "0", + "6" : "0", + "7" : "0", + "8" : "0", + "9" : "0", + "10": "0", + "11": "0", + "12": "0", + "13": "0", + "14": "0", + "15": "0", + "16": "0", + "17": "0", + "18": "0", + "19": "0", + "20": "0", + "21": "0", + "22": "0", + "23": "0", + "24": "0", + "25": "0", + "26": "0", + "27": "0", + "28": "0", + "29": "0", + "30": "0", + "31": "0", + "32": "0", + "33": "0", + "34": "0", + "35": "0", + "36": "0", + "37": "0", + "38": "0", + "39": "0", + "40": "0", + "41": "0", + "42": "0", + "43": "0", + "44": "0", + "45": "0", + "46": "0", + "47": "0", + "48": "0", + "49": "0", + "50": "0", + "51": "0", + "52": "0", + "53": "0", + "54": "0", + "55": "0", + "56": "0", + "57": "0", + "58": "0", + "59": "0", + "60": "0", + "61": "0", + "62": "0", + "63": "0" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type" : "DWRR", + "weight": "1" + }, + "scheduler.1": { + "type" : "DWRR", + "weight": "2" + }, + "scheduler.2": { + "type" : "DWRR", + "weight": "3" + }, + "scheduler.3": { + "type" : "DWRR", + "weight": "4" + }, + "scheduler.4": { + "type" : "DWRR", + "weight": "5" + }, + "scheduler.5": { + "type" : "DWRR", + "weight": "10" + }, + "scheduler.6": { + "type" : "DWRR", + "weight": "25" + }, + "scheduler.7": { + "type" : "DWRR", + "weight": "50" + } + }, + "PORT_QOS_MAP": { + "{{ port_names_active }}": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|DEFAULT]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|DEFAULT]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|DEFAULT]" + } + }, + "QUEUE": { +{% for port in PORT_ACTIVE %} + "{{ port }}|0": { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|1": { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|2": { + "scheduler": "[SCHEDULER|scheduler.2]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|3": { + "scheduler": "[SCHEDULER|scheduler.3]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|4": { + "scheduler": "[SCHEDULER|scheduler.4]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|5": { + "scheduler": "[SCHEDULER|scheduler.5]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|6": { + "scheduler": "[SCHEDULER|scheduler.6]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|7": { + "scheduler": "[SCHEDULER|scheduler.7]" + }{% if not loop.last %},{% endif %} +{% endfor %} + } +} diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/sai.profile b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/sai.profile new file mode 100644 index 000000000000..f12601115339 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-s5296f-10g.config.bcm diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/sai_preinit_cmd.soc b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/sai_preinit_cmd.soc new file mode 100644 index 000000000000..4d62900f898f --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-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_s5296f_c3538-r0/DellEMC-S5296f-P-10G/td3-s5296f-10g.config.bcm b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/td3-s5296f-10g.config.bcm new file mode 100644 index 000000000000..ddc14d9363d3 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-10G/td3-s5296f-10g.config.bcm @@ -0,0 +1,596 @@ +sai_load_hw_config=/etc/bcm/flex/bcm56870_a0_issu/b870.6.4.1/ +os=unix +portmap_5.0=5:10 +portmap_6.0=6:10 +portmap_7.0=7:10 +portmap_8.0=8:10 +portmap_13.0=13:10 +portmap_14.0=14:10 +portmap_15.0=15:10 +portmap_16.0=16:10 +portmap_17.0=17:10 +portmap_18.0=18:10 +portmap_19.0=19:10 +portmap_20.0=20:10 +portmap_37.0=37:10 +portmap_38.0=38:10 +portmap_39.0=39:10 +portmap_40.0=40:10 +portmap_45.0=45:10 +portmap_46.0=46:10 +portmap_47.0=47:10 +portmap_48.0=48:10 +portmap_53.0=53:10 +portmap_54.0=54:10 +portmap_55.0=55:10 +portmap_56.0=56:10 +portmap_67.0=65:10 +portmap_68.0=66:10 +portmap_69.0=67:10 +portmap_70.0=68:10 +portmap_75.0=73:10 +portmap_76.0=74:10 +portmap_77.0=75:10 +portmap_78.0=76:10 +portmap_91.0=89:10 +portmap_92.0=90:10 +portmap_93.0=91:10 +portmap_94.0=92:10 +portmap_103.0=101:10 +portmap_104.0=102:10 +portmap_105.0=103:10 +portmap_106.0=104:10 +portmap_111.0=109:10 +portmap_112.0=110:10 +portmap_113.0=111:10 +portmap_114.0=112:10 +portmap_119.0=117:10 +portmap_120.0=118:10 +portmap_121.0=119:10 +portmap_122.0=120:10 +portmap_1.0=1:10 +portmap_2.0=2:10 +portmap_3.0=3:10 +portmap_4.0=4:10 +portmap_9.0=9:10 +portmap_10.0=10:10 +portmap_11.0=11:10 +portmap_12.0=12:10 +portmap_25.0=25:10 +portmap_26.0=26:10 +portmap_27.0=27:10 +portmap_28.0=28:10 +portmap_33.0=33:10 +portmap_34.0=34:10 +portmap_35.0=35:10 +portmap_36.0=36:10 +portmap_41.0=41:10 +portmap_42.0=42:10 +portmap_43.0=43:10 +portmap_44.0=44:10 +portmap_49.0=49:10 +portmap_50.0=50:10 +portmap_51.0=51:10 +portmap_52.0=52:10 +portmap_71.0=69:10 +portmap_72.0=70:10 +portmap_73.0=71:10 +portmap_74.0=72:10 +portmap_79.0=77:10 +portmap_80.0=78:10 +portmap_81.0=79:10 +portmap_82.0=80:10 +portmap_83.0=81:10 +portmap_84.0=82:10 +portmap_85.0=83:10 +portmap_86.0=84:10 +portmap_99.0=97:10 +portmap_100.0=98:10 +portmap_101.0=99:10 +portmap_102.0=100:10 +portmap_107.0=105:10 +portmap_108.0=106:10 +portmap_109.0=107:10 +portmap_110.0=108:10 +portmap_115.0=113:10 +portmap_116.0=114:10 +portmap_117.0=115:10 +portmap_118.0=116:10 +portmap_29.0=29:100 +portmap_21.0=21:100 +portmap_127.0=125:100 +portmap_87.0=85:100 +portmap_57.0=57:100 +portmap_61.0=61:100 +portmap_123.0=121:100 +portmap_95.0=93:100 +phy_chain_tx_lane_map_physical{5.0}=0x0123 +phy_chain_rx_lane_map_physical{5.0}=0x0123 +phy_chain_tx_lane_map_physical{13.0}=0x0123 +phy_chain_rx_lane_map_physical{13.0}=0x0123 +phy_chain_tx_lane_map_physical{17.0}=0x0123 +phy_chain_rx_lane_map_physical{17.0}=0x0123 +phy_chain_tx_lane_map_physical{37.0}=0x0123 +phy_chain_rx_lane_map_physical{37.0}=0x0123 +phy_chain_tx_lane_map_physical{45.0}=0x0123 +phy_chain_rx_lane_map_physical{45.0}=0x0123 +phy_chain_tx_lane_map_physical{53.0}=0x0123 +phy_chain_rx_lane_map_physical{53.0}=0x0123 +phy_chain_tx_lane_map_physical{65.0}=0x3210 +phy_chain_rx_lane_map_physical{65.0}=0x3210 +phy_chain_tx_lane_map_physical{73.0}=0x3210 +phy_chain_rx_lane_map_physical{73.0}=0x3210 +phy_chain_tx_lane_map_physical{89.0}=0x3210 +phy_chain_rx_lane_map_physical{89.0}=0x3210 +phy_chain_tx_lane_map_physical{101.0}=0x3210 +phy_chain_rx_lane_map_physical{101.0}=0x3210 +phy_chain_tx_lane_map_physical{109.0}=0x3210 +phy_chain_rx_lane_map_physical{109.0}=0x3210 +phy_chain_tx_lane_map_physical{117.0}=0x3210 +phy_chain_rx_lane_map_physical{117.0}=0x3210 +phy_chain_tx_lane_map_physical{1.0}=0x1032 +phy_chain_rx_lane_map_physical{1.0}=0x1032 +phy_chain_tx_lane_map_physical{9.0}=0x1032 +phy_chain_rx_lane_map_physical{9.0}=0x1032 +phy_chain_tx_lane_map_physical{25.0}=0x1032 +phy_chain_rx_lane_map_physical{25.0}=0x1032 +phy_chain_tx_lane_map_physical{33.0}=0x1032 +phy_chain_rx_lane_map_physical{33.0}=0x1032 +phy_chain_tx_lane_map_physical{41.0}=0x1032 +phy_chain_rx_lane_map_physical{41.0}=0x1032 +phy_chain_tx_lane_map_physical{49.0}=0x2031 +phy_chain_rx_lane_map_physical{49.0}=0x2031 +phy_chain_tx_lane_map_physical{69.0}=0x2301 +phy_chain_rx_lane_map_physical{69.0}=0x2301 +phy_chain_tx_lane_map_physical{77.0}=0x1302 +phy_chain_rx_lane_map_physical{77.0}=0x1302 +phy_chain_tx_lane_map_physical{81.0}=0x2301 +phy_chain_rx_lane_map_physical{81.0}=0x2301 +phy_chain_tx_lane_map_physical{97.0}=0x2301 +phy_chain_rx_lane_map_physical{97.0}=0x2301 +phy_chain_tx_lane_map_physical{105.0}=0x2301 +phy_chain_rx_lane_map_physical{105.0}=0x2301 +phy_chain_tx_lane_map_physical{113.0}=0x2301 +phy_chain_rx_lane_map_physical{113.0}=0x2301 +phy_chain_tx_lane_map_physical{29.0}=0x0123 +phy_chain_rx_lane_map_physical{29.0}=0x3201 +phy_chain_tx_lane_map_physical{21.0}=0x3021 +phy_chain_rx_lane_map_physical{21.0}=0x0312 +phy_chain_tx_lane_map_physical{125.0}=0x3210 +phy_chain_rx_lane_map_physical{125.0}=0x0132 +phy_chain_tx_lane_map_physical{85.0}=0x0312 +phy_chain_rx_lane_map_physical{85.0}=0x3021 +phy_chain_tx_lane_map_physical{57.0}=0x3021 +phy_chain_rx_lane_map_physical{57.0}=0x0312 +phy_chain_tx_lane_map_physical{61.0}=0x3210 +phy_chain_rx_lane_map_physical{61.0}=0x1230 +phy_chain_tx_lane_map_physical{121.0}=0x0123 +phy_chain_rx_lane_map_physical{121.0}=0x2310 +phy_chain_tx_lane_map_physical{93.0}=0x0123 +phy_chain_rx_lane_map_physical{93.0}=0x2301 +phy_chain_tx_polarity_flip_physical{5.0}=0x1 +phy_chain_rx_polarity_flip_physical{5.0}=0x1 +phy_chain_tx_polarity_flip_physical{6.0}=0x1 +phy_chain_rx_polarity_flip_physical{6.0}=0x1 +phy_chain_tx_polarity_flip_physical{7.0}=0x1 +phy_chain_rx_polarity_flip_physical{7.0}=0x1 +phy_chain_tx_polarity_flip_physical{8.0}=0x1 +phy_chain_rx_polarity_flip_physical{8.0}=0x1 +phy_chain_tx_polarity_flip_physical{13.0}=0x1 +phy_chain_rx_polarity_flip_physical{13.0}=0x1 +phy_chain_tx_polarity_flip_physical{14.0}=0x1 +phy_chain_rx_polarity_flip_physical{14.0}=0x1 +phy_chain_tx_polarity_flip_physical{15.0}=0x1 +phy_chain_rx_polarity_flip_physical{15.0}=0x1 +phy_chain_tx_polarity_flip_physical{16.0}=0x1 +phy_chain_rx_polarity_flip_physical{16.0}=0x1 +phy_chain_tx_polarity_flip_physical{17.0}=0x0 +phy_chain_rx_polarity_flip_physical{17.0}=0x1 +phy_chain_tx_polarity_flip_physical{18.0}=0x0 +phy_chain_rx_polarity_flip_physical{18.0}=0x1 +phy_chain_tx_polarity_flip_physical{19.0}=0x0 +phy_chain_rx_polarity_flip_physical{19.0}=0x1 +phy_chain_tx_polarity_flip_physical{20.0}=0x0 +phy_chain_rx_polarity_flip_physical{20.0}=0x1 +phy_chain_tx_polarity_flip_physical{37.0}=0x1 +phy_chain_rx_polarity_flip_physical{37.0}=0x1 +phy_chain_tx_polarity_flip_physical{38.0}=0x1 +phy_chain_rx_polarity_flip_physical{38.0}=0x1 +phy_chain_tx_polarity_flip_physical{39.0}=0x1 +phy_chain_rx_polarity_flip_physical{39.0}=0x1 +phy_chain_tx_polarity_flip_physical{40.0}=0x1 +phy_chain_rx_polarity_flip_physical{40.0}=0x1 +phy_chain_tx_polarity_flip_physical{45.0}=0x1 +phy_chain_rx_polarity_flip_physical{45.0}=0x1 +phy_chain_tx_polarity_flip_physical{46.0}=0x1 +phy_chain_rx_polarity_flip_physical{46.0}=0x1 +phy_chain_tx_polarity_flip_physical{47.0}=0x1 +phy_chain_rx_polarity_flip_physical{47.0}=0x1 +phy_chain_tx_polarity_flip_physical{48.0}=0x1 +phy_chain_rx_polarity_flip_physical{48.0}=0x1 +phy_chain_tx_polarity_flip_physical{53.0}=0x1 +phy_chain_rx_polarity_flip_physical{53.0}=0x1 +phy_chain_tx_polarity_flip_physical{54.0}=0x1 +phy_chain_rx_polarity_flip_physical{54.0}=0x1 +phy_chain_tx_polarity_flip_physical{55.0}=0x1 +phy_chain_rx_polarity_flip_physical{55.0}=0x1 +phy_chain_tx_polarity_flip_physical{56.0}=0x1 +phy_chain_rx_polarity_flip_physical{56.0}=0x1 +phy_chain_tx_polarity_flip_physical{65.0}=0x1 +phy_chain_rx_polarity_flip_physical{65.0}=0x1 +phy_chain_tx_polarity_flip_physical{66.0}=0x1 +phy_chain_rx_polarity_flip_physical{66.0}=0x1 +phy_chain_tx_polarity_flip_physical{67.0}=0x1 +phy_chain_rx_polarity_flip_physical{67.0}=0x1 +phy_chain_tx_polarity_flip_physical{68.0}=0x1 +phy_chain_rx_polarity_flip_physical{68.0}=0x1 +phy_chain_tx_polarity_flip_physical{73.0}=0x1 +phy_chain_rx_polarity_flip_physical{73.0}=0x1 +phy_chain_tx_polarity_flip_physical{74.0}=0x1 +phy_chain_rx_polarity_flip_physical{74.0}=0x1 +phy_chain_tx_polarity_flip_physical{75.0}=0x1 +phy_chain_rx_polarity_flip_physical{75.0}=0x1 +phy_chain_tx_polarity_flip_physical{76.0}=0x1 +phy_chain_rx_polarity_flip_physical{76.0}=0x1 +phy_chain_tx_polarity_flip_physical{89.0}=0x0 +phy_chain_rx_polarity_flip_physical{89.0}=0x1 +phy_chain_tx_polarity_flip_physical{90.0}=0x0 +phy_chain_rx_polarity_flip_physical{90.0}=0x1 +phy_chain_tx_polarity_flip_physical{91.0}=0x0 +phy_chain_rx_polarity_flip_physical{91.0}=0x1 +phy_chain_tx_polarity_flip_physical{92.0}=0x0 +phy_chain_rx_polarity_flip_physical{92.0}=0x1 +phy_chain_tx_polarity_flip_physical{101.0}=0x1 +phy_chain_rx_polarity_flip_physical{101.0}=0x0 +phy_chain_tx_polarity_flip_physical{102.0}=0x1 +phy_chain_rx_polarity_flip_physical{102.0}=0x0 +phy_chain_tx_polarity_flip_physical{103.0}=0x1 +phy_chain_rx_polarity_flip_physical{103.0}=0x0 +phy_chain_tx_polarity_flip_physical{104.0}=0x1 +phy_chain_rx_polarity_flip_physical{104.0}=0x0 +phy_chain_tx_polarity_flip_physical{109.0}=0x1 +phy_chain_rx_polarity_flip_physical{109.0}=0x1 +phy_chain_tx_polarity_flip_physical{110.0}=0x1 +phy_chain_rx_polarity_flip_physical{110.0}=0x1 +phy_chain_tx_polarity_flip_physical{111.0}=0x1 +phy_chain_rx_polarity_flip_physical{111.0}=0x1 +phy_chain_tx_polarity_flip_physical{112.0}=0x1 +phy_chain_rx_polarity_flip_physical{112.0}=0x1 +phy_chain_tx_polarity_flip_physical{117.0}=0x1 +phy_chain_rx_polarity_flip_physical{117.0}=0x1 +phy_chain_tx_polarity_flip_physical{118.0}=0x1 +phy_chain_rx_polarity_flip_physical{118.0}=0x1 +phy_chain_tx_polarity_flip_physical{119.0}=0x1 +phy_chain_rx_polarity_flip_physical{119.0}=0x1 +phy_chain_tx_polarity_flip_physical{120.0}=0x1 +phy_chain_rx_polarity_flip_physical{120.0}=0x1 +phy_chain_tx_polarity_flip_physical{1.0}=0x0 +phy_chain_rx_polarity_flip_physical{1.0}=0x0 +phy_chain_tx_polarity_flip_physical{2.0}=0x1 +phy_chain_rx_polarity_flip_physical{2.0}=0x1 +phy_chain_tx_polarity_flip_physical{3.0}=0x0 +phy_chain_rx_polarity_flip_physical{3.0}=0x0 +phy_chain_tx_polarity_flip_physical{4.0}=0x1 +phy_chain_rx_polarity_flip_physical{4.0}=0x1 +phy_chain_tx_polarity_flip_physical{9.0}=0x0 +phy_chain_rx_polarity_flip_physical{9.0}=0x0 +phy_chain_tx_polarity_flip_physical{10.0}=0x1 +phy_chain_rx_polarity_flip_physical{10.0}=0x1 +phy_chain_tx_polarity_flip_physical{11.0}=0x0 +phy_chain_rx_polarity_flip_physical{11.0}=0x0 +phy_chain_tx_polarity_flip_physical{12.0}=0x1 +phy_chain_rx_polarity_flip_physical{12.0}=0x1 +phy_chain_tx_polarity_flip_physical{25.0}=0x0 +phy_chain_rx_polarity_flip_physical{25.0}=0x1 +phy_chain_tx_polarity_flip_physical{26.0}=0x1 +phy_chain_rx_polarity_flip_physical{26.0}=0x1 +phy_chain_tx_polarity_flip_physical{27.0}=0x0 +phy_chain_rx_polarity_flip_physical{27.0}=0x1 +phy_chain_tx_polarity_flip_physical{28.0}=0x1 +phy_chain_rx_polarity_flip_physical{28.0}=0x0 +phy_chain_tx_polarity_flip_physical{33.0}=0x1 +phy_chain_rx_polarity_flip_physical{33.0}=0x1 +phy_chain_tx_polarity_flip_physical{34.0}=0x0 +phy_chain_rx_polarity_flip_physical{34.0}=0x0 +phy_chain_tx_polarity_flip_physical{35.0}=0x1 +phy_chain_rx_polarity_flip_physical{35.0}=0x1 +phy_chain_tx_polarity_flip_physical{36.0}=0x0 +phy_chain_rx_polarity_flip_physical{36.0}=0x0 +phy_chain_tx_polarity_flip_physical{41.0}=0x1 +phy_chain_rx_polarity_flip_physical{41.0}=0x1 +phy_chain_tx_polarity_flip_physical{42.0}=0x0 +phy_chain_rx_polarity_flip_physical{42.0}=0x0 +phy_chain_tx_polarity_flip_physical{43.0}=0x1 +phy_chain_rx_polarity_flip_physical{43.0}=0x1 +phy_chain_tx_polarity_flip_physical{44.0}=0x0 +phy_chain_rx_polarity_flip_physical{44.0}=0x0 +phy_chain_tx_polarity_flip_physical{49.0}=0x1 +phy_chain_rx_polarity_flip_physical{49.0}=0x1 +phy_chain_tx_polarity_flip_physical{50.0}=0x1 +phy_chain_rx_polarity_flip_physical{50.0}=0x1 +phy_chain_tx_polarity_flip_physical{51.0}=0x0 +phy_chain_rx_polarity_flip_physical{51.0}=0x0 +phy_chain_tx_polarity_flip_physical{52.0}=0x0 +phy_chain_rx_polarity_flip_physical{52.0}=0x0 +phy_chain_tx_polarity_flip_physical{69.0}=0x1 +phy_chain_rx_polarity_flip_physical{69.0}=0x1 +phy_chain_tx_polarity_flip_physical{70.0}=0x0 +phy_chain_rx_polarity_flip_physical{70.0}=0x0 +phy_chain_tx_polarity_flip_physical{71.0}=0x1 +phy_chain_rx_polarity_flip_physical{71.0}=0x1 +phy_chain_tx_polarity_flip_physical{72.0}=0x0 +phy_chain_rx_polarity_flip_physical{72.0}=0x0 +phy_chain_tx_polarity_flip_physical{77.0}=0x1 +phy_chain_rx_polarity_flip_physical{77.0}=0x1 +phy_chain_tx_polarity_flip_physical{78.0}=0x1 +phy_chain_rx_polarity_flip_physical{78.0}=0x1 +phy_chain_tx_polarity_flip_physical{79.0}=0x0 +phy_chain_rx_polarity_flip_physical{79.0}=0x0 +phy_chain_tx_polarity_flip_physical{80.0}=0x0 +phy_chain_rx_polarity_flip_physical{80.0}=0x0 +phy_chain_tx_polarity_flip_physical{81.0}=0x0 +phy_chain_rx_polarity_flip_physical{81.0}=0x0 +phy_chain_tx_polarity_flip_physical{82.0}=0x1 +phy_chain_rx_polarity_flip_physical{82.0}=0x1 +phy_chain_tx_polarity_flip_physical{83.0}=0x0 +phy_chain_rx_polarity_flip_physical{83.0}=0x0 +phy_chain_tx_polarity_flip_physical{84.0}=0x1 +phy_chain_rx_polarity_flip_physical{84.0}=0x1 +phy_chain_tx_polarity_flip_physical{97.0}=0x0 +phy_chain_rx_polarity_flip_physical{97.0}=0x0 +phy_chain_tx_polarity_flip_physical{98.0}=0x1 +phy_chain_rx_polarity_flip_physical{98.0}=0x1 +phy_chain_tx_polarity_flip_physical{99.0}=0x0 +phy_chain_rx_polarity_flip_physical{99.0}=0x0 +phy_chain_tx_polarity_flip_physical{100.0}=0x1 +phy_chain_rx_polarity_flip_physical{100.0}=0x1 +phy_chain_tx_polarity_flip_physical{105.0}=0x0 +phy_chain_rx_polarity_flip_physical{105.0}=0x1 +phy_chain_tx_polarity_flip_physical{106.0}=0x1 +phy_chain_rx_polarity_flip_physical{106.0}=0x0 +phy_chain_tx_polarity_flip_physical{107.0}=0x0 +phy_chain_rx_polarity_flip_physical{107.0}=0x1 +phy_chain_tx_polarity_flip_physical{108.0}=0x1 +phy_chain_rx_polarity_flip_physical{108.0}=0x0 +phy_chain_tx_polarity_flip_physical{113.0}=0x0 +phy_chain_rx_polarity_flip_physical{113.0}=0x1 +phy_chain_tx_polarity_flip_physical{114.0}=0x1 +phy_chain_rx_polarity_flip_physical{114.0}=0x0 +phy_chain_tx_polarity_flip_physical{115.0}=0x0 +phy_chain_rx_polarity_flip_physical{115.0}=0x1 +phy_chain_tx_polarity_flip_physical{116.0}=0x1 +phy_chain_rx_polarity_flip_physical{116.0}=0x0 +phy_chain_tx_polarity_flip_physical{29.0}=0x1 +phy_chain_rx_polarity_flip_physical{29.0}=0x0 +phy_chain_tx_polarity_flip_physical{30.0}=0x1 +phy_chain_rx_polarity_flip_physical{30.0}=0x1 +phy_chain_tx_polarity_flip_physical{31.0}=0x0 +phy_chain_rx_polarity_flip_physical{31.0}=0x0 +phy_chain_tx_polarity_flip_physical{32.0}=0x0 +phy_chain_rx_polarity_flip_physical{32.0}=0x0 +phy_chain_tx_polarity_flip_physical{21.0}=0x0 +phy_chain_rx_polarity_flip_physical{21.0}=0x1 +phy_chain_tx_polarity_flip_physical{22.0}=0x0 +phy_chain_rx_polarity_flip_physical{22.0}=0x1 +phy_chain_tx_polarity_flip_physical{23.0}=0x1 +phy_chain_rx_polarity_flip_physical{23.0}=0x1 +phy_chain_tx_polarity_flip_physical{24.0}=0x0 +phy_chain_rx_polarity_flip_physical{24.0}=0x1 +phy_chain_tx_polarity_flip_physical{125.0}=0x1 +phy_chain_rx_polarity_flip_physical{125.0}=0x0 +phy_chain_tx_polarity_flip_physical{126.0}=0x0 +phy_chain_rx_polarity_flip_physical{126.0}=0x0 +phy_chain_tx_polarity_flip_physical{127.0}=0x0 +phy_chain_rx_polarity_flip_physical{127.0}=0x0 +phy_chain_tx_polarity_flip_physical{128.0}=0x0 +phy_chain_rx_polarity_flip_physical{128.0}=0x1 +phy_chain_tx_polarity_flip_physical{85.0}=0x0 +phy_chain_rx_polarity_flip_physical{85.0}=0x0 +phy_chain_tx_polarity_flip_physical{86.0}=0x0 +phy_chain_rx_polarity_flip_physical{86.0}=0x0 +phy_chain_tx_polarity_flip_physical{87.0}=0x1 +phy_chain_rx_polarity_flip_physical{87.0}=0x1 +phy_chain_tx_polarity_flip_physical{88.0}=0x0 +phy_chain_rx_polarity_flip_physical{88.0}=0x0 +phy_chain_tx_polarity_flip_physical{57.0}=0x0 +phy_chain_rx_polarity_flip_physical{57.0}=0x0 +phy_chain_tx_polarity_flip_physical{58.0}=0x0 +phy_chain_rx_polarity_flip_physical{58.0}=0x1 +phy_chain_tx_polarity_flip_physical{59.0}=0x1 +phy_chain_rx_polarity_flip_physical{59.0}=0x0 +phy_chain_tx_polarity_flip_physical{60.0}=0x0 +phy_chain_rx_polarity_flip_physical{60.0}=0x0 +phy_chain_tx_polarity_flip_physical{61.0}=0x0 +phy_chain_rx_polarity_flip_physical{61.0}=0x1 +phy_chain_tx_polarity_flip_physical{62.0}=0x1 +phy_chain_rx_polarity_flip_physical{62.0}=0x0 +phy_chain_tx_polarity_flip_physical{63.0}=0x1 +phy_chain_rx_polarity_flip_physical{63.0}=0x1 +phy_chain_tx_polarity_flip_physical{64.0}=0x1 +phy_chain_rx_polarity_flip_physical{64.0}=0x1 +phy_chain_tx_polarity_flip_physical{121.0}=0x1 +phy_chain_rx_polarity_flip_physical{121.0}=0x0 +phy_chain_tx_polarity_flip_physical{122.0}=0x1 +phy_chain_rx_polarity_flip_physical{122.0}=0x1 +phy_chain_tx_polarity_flip_physical{123.0}=0x1 +phy_chain_rx_polarity_flip_physical{123.0}=0x1 +phy_chain_tx_polarity_flip_physical{124.0}=0x1 +phy_chain_rx_polarity_flip_physical{124.0}=0x1 +phy_chain_tx_polarity_flip_physical{93.0}=0x0 +phy_chain_rx_polarity_flip_physical{93.0}=0x1 +phy_chain_tx_polarity_flip_physical{94.0}=0x0 +phy_chain_rx_polarity_flip_physical{94.0}=0x0 +phy_chain_tx_polarity_flip_physical{95.0}=0x1 +phy_chain_rx_polarity_flip_physical{95.0}=0x0 +phy_chain_tx_polarity_flip_physical{96.0}=0x0 +phy_chain_rx_polarity_flip_physical{96.0}=0x1 +dport_map_enable=1 +dport_map_port_5=1 +dport_map_port_6=2 +dport_map_port_7=3 +dport_map_port_8=4 +dport_map_port_13=5 +dport_map_port_14=6 +dport_map_port_15=7 +dport_map_port_16=8 +dport_map_port_17=9 +dport_map_port_18=10 +dport_map_port_19=11 +dport_map_port_20=12 +dport_map_port_37=13 +dport_map_port_38=14 +dport_map_port_39=15 +dport_map_port_40=16 +dport_map_port_45=17 +dport_map_port_46=18 +dport_map_port_47=19 +dport_map_port_48=20 +dport_map_port_53=21 +dport_map_port_54=22 +dport_map_port_55=23 +dport_map_port_56=24 +dport_map_port_67=25 +dport_map_port_68=26 +dport_map_port_69=27 +dport_map_port_70=28 +dport_map_port_75=29 +dport_map_port_76=30 +dport_map_port_77=31 +dport_map_port_78=32 +dport_map_port_91=33 +dport_map_port_92=34 +dport_map_port_93=35 +dport_map_port_94=36 +dport_map_port_103=37 +dport_map_port_104=38 +dport_map_port_105=39 +dport_map_port_106=40 +dport_map_port_111=41 +dport_map_port_112=42 +dport_map_port_113=43 +dport_map_port_114=44 +dport_map_port_119=45 +dport_map_port_120=46 +dport_map_port_121=47 +dport_map_port_122=48 +dport_map_port_1=49 +dport_map_port_2=50 +dport_map_port_3=51 +dport_map_port_4=52 +dport_map_port_9=53 +dport_map_port_10=54 +dport_map_port_11=55 +dport_map_port_12=56 +dport_map_port_25=57 +dport_map_port_26=58 +dport_map_port_27=59 +dport_map_port_28=60 +dport_map_port_33=61 +dport_map_port_34=62 +dport_map_port_35=63 +dport_map_port_36=64 +dport_map_port_41=65 +dport_map_port_42=66 +dport_map_port_43=67 +dport_map_port_44=68 +dport_map_port_49=69 +dport_map_port_50=70 +dport_map_port_51=71 +dport_map_port_52=72 +dport_map_port_71=73 +dport_map_port_72=74 +dport_map_port_73=75 +dport_map_port_74=76 +dport_map_port_79=77 +dport_map_port_80=78 +dport_map_port_81=79 +dport_map_port_82=80 +dport_map_port_83=81 +dport_map_port_84=82 +dport_map_port_85=83 +dport_map_port_86=84 +dport_map_port_99=85 +dport_map_port_100=86 +dport_map_port_101=87 +dport_map_port_102=88 +dport_map_port_107=89 +dport_map_port_108=90 +dport_map_port_109=91 +dport_map_port_110=92 +dport_map_port_115=93 +dport_map_port_116=94 +dport_map_port_117=95 +dport_map_port_118=96 +dport_map_port_29=97 +dport_map_port_30=98 +dport_map_port_31=99 +dport_map_port_32=100 +dport_map_port_21=101 +dport_map_port_22=102 +dport_map_port_23=103 +dport_map_port_24=104 +dport_map_port_127=105 +dport_map_port_128=106 +dport_map_port_129=107 +dport_map_port_130=108 +dport_map_port_87=109 +dport_map_port_88=110 +dport_map_port_89=111 +dport_map_port_90=112 +dport_map_port_57=113 +dport_map_port_58=114 +dport_map_port_59=115 +dport_map_port_60=116 +dport_map_port_61=117 +dport_map_port_62=118 +dport_map_port_63=119 +dport_map_port_64=120 +dport_map_port_123=121 +dport_map_port_124=122 +dport_map_port_125=123 +dport_map_port_126=124 +dport_map_port_95=125 +dport_map_port_96=126 +dport_map_port_97=127 +dport_map_port_98=128 + +dpp_clock_ratio=2:3 +oversubscribe_mode=1 +core_clock_frequency=1525 +l2xmsg_mode=1 +pbmp_oversubscribe=0x7fffffffffffffff9fffffffffffffffe +pbmp_xport_xe=0x7fffffffffffffff9fffffffffffffffe +ifp_inports_support_enable=1 +port_flex_enable=1 +phy_an_c73=3 +l2xmsg_hostbuf_size=8192 +module_64ports=0 +tdma_intr_enable=1 +ipv6_lpm_128b_enable=1 +stat_if_parity_enable=1 +bcm_tunnel_term_compatible_mode=1 +table_dma_enable=1 +schan_intr_enable=0 +parity_enable=1 +parity_correction=1 +miim_intr_enable=1 +tdma_timeout_usec=5000000 +max_vp_lags=0 +mmu_lossless=0 +pdma_descriptor_prefetch_enable=1 +pktdma_poll_mode_channel_bitmap=1 +l3_max_ecmp_mode.0=1 +ptp_ts_pll_fref=50000000 +ptp_bs_fref_0=50000000 +ptp_bs_fref_1=50000000 + +l3_alpm_enable=2 +l3_alpm_ipv6_128b_bkt_rsvd=1 +l2_mem_entries=40960 +l3_mem_entries=40960 +l3_max_ecmp_mode=1 + +stable_size=0x5500000 + +mmu_init_config="TD3-DELL-lossless" +sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/buffers.json.j2 b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/buffers.json.j2 new file mode 100644 index 000000000000..0b1cb2c541b6 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..c31728e46543 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/buffers_defaults_t0.j2 @@ -0,0 +1,46 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "32744448", + "type": "ingress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "32744448", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"32744448" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names_active) %} + "BUFFER_PG": { + "{{ port_names_active }}|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, +{%- endmacro %} + +{% macro generate_queue_buffers(port_names_active) %} + "BUFFER_QUEUE": { + "{{ port_names_active }}|0-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +{% endmacro %} + diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..c31728e46543 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/buffers_defaults_t1.j2 @@ -0,0 +1,46 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "32744448", + "type": "ingress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "32744448", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"32744448" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names_active) %} + "BUFFER_PG": { + "{{ port_names_active }}|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, +{%- endmacro %} + +{% macro generate_queue_buffers(port_names_active) %} + "BUFFER_QUEUE": { + "{{ port_names_active }}|0-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +{% endmacro %} + diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/custom_led.bin b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/custom_led.bin new file mode 100755 index 000000000000..302a41d9789a Binary files /dev/null and b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/custom_led.bin differ diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/linkscan_led_fw.bin b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/linkscan_led_fw.bin new file mode 100755 index 000000000000..c2fa94a2d8cb Binary files /dev/null and b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/linkscan_led_fw.bin differ diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/port_config.ini b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/port_config.ini new file mode 100644 index 000000000000..5b2f7ccd20fb --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/port_config.ini @@ -0,0 +1,105 @@ +# name lanes alias index speed +Ethernet0 5 twentyfiveGigE1/1/1 1 25000 +Ethernet1 6 twentyfiveGigE1/1/2 2 25000 +Ethernet2 7 twentyfiveGigE1/1/3 3 25000 +Ethernet3 8 twentyfiveGigE1/1/4 4 25000 +Ethernet4 13 twentyfiveGigE1/2/1 5 25000 +Ethernet5 14 twentyfiveGigE1/2/2 6 25000 +Ethernet6 15 twentyfiveGigE1/2/3 7 25000 +Ethernet7 16 twentyfiveGigE1/2/4 8 25000 +Ethernet8 17 twentyfiveGigE1/3/1 9 25000 +Ethernet9 18 twentyfiveGigE1/3/2 10 25000 +Ethernet10 19 twentyfiveGigE1/3/3 11 25000 +Ethernet11 20 twentyfiveGigE1/3/4 12 25000 +Ethernet12 37 twentyfiveGigE1/4/1 13 25000 +Ethernet13 38 twentyfiveGigE1/4/2 14 25000 +Ethernet14 39 twentyfiveGigE1/4/3 15 25000 +Ethernet15 40 twentyfiveGigE1/4/4 16 25000 +Ethernet16 45 twentyfiveGigE1/5/1 17 25000 +Ethernet17 46 twentyfiveGigE1/5/2 18 25000 +Ethernet18 47 twentyfiveGigE1/5/3 19 25000 +Ethernet19 48 twentyfiveGigE1/5/4 20 25000 +Ethernet20 53 twentyfiveGigE1/6/1 21 25000 +Ethernet21 54 twentyfiveGigE1/6/2 22 25000 +Ethernet22 55 twentyfiveGigE1/6/3 23 25000 +Ethernet23 56 twentyfiveGigE1/6/4 24 25000 +Ethernet24 65 twentyfiveGigE1/7/1 25 25000 +Ethernet25 66 twentyfiveGigE1/7/2 26 25000 +Ethernet26 67 twentyfiveGigE1/7/3 27 25000 +Ethernet27 68 twentyfiveGigE1/7/4 28 25000 +Ethernet28 73 twentyfiveGigE1/8/1 29 25000 +Ethernet29 74 twentyfiveGigE1/8/2 30 25000 +Ethernet30 75 twentyfiveGigE1/8/3 31 25000 +Ethernet31 76 twentyfiveGigE1/8/4 32 25000 +Ethernet32 89 twentyfiveGigE1/9/1 33 25000 +Ethernet33 90 twentyfiveGigE1/9/2 34 25000 +Ethernet34 91 twentyfiveGigE1/9/3 35 25000 +Ethernet35 92 twentyfiveGigE1/9/4 36 25000 +Ethernet36 101 twentyfiveGigE1/10/1 37 25000 +Ethernet37 102 twentyfiveGigE1/10/2 38 25000 +Ethernet38 103 twentyfiveGigE1/10/3 39 25000 +Ethernet39 104 twentyfiveGigE1/10/4 40 25000 +Ethernet40 109 twentyfiveGigE1/11/1 41 25000 +Ethernet41 110 twentyfiveGigE1/11/2 42 25000 +Ethernet42 111 twentyfiveGigE1/11/3 43 25000 +Ethernet43 112 twentyfiveGigE1/11/4 44 25000 +Ethernet44 117 twentyfiveGigE1/12/1 45 25000 +Ethernet45 118 twentyfiveGigE1/12/2 46 25000 +Ethernet46 119 twentyfiveGigE1/12/3 47 25000 +Ethernet47 120 twentyfiveGigE1/12/4 48 25000 +Ethernet48 1 twentyfiveGigE1/13/1 49 25000 +Ethernet49 2 twentyfiveGigE1/13/2 50 25000 +Ethernet50 3 twentyfiveGigE1/13/3 51 25000 +Ethernet51 4 twentyfiveGigE1/13/4 52 25000 +Ethernet52 9 twentyfiveGigE1/14/1 53 25000 +Ethernet53 10 twentyfiveGigE1/14/2 54 25000 +Ethernet54 11 twentyfiveGigE1/14/3 55 25000 +Ethernet55 12 twentyfiveGigE1/14/4 56 25000 +Ethernet56 25 twentyfiveGigE1/15/1 57 25000 +Ethernet57 26 twentyfiveGigE1/15/2 58 25000 +Ethernet58 27 twentyfiveGigE1/15/3 59 25000 +Ethernet59 28 twentyfiveGigE1/15/4 60 25000 +Ethernet60 33 twentyfiveGigE1/16/1 61 25000 +Ethernet61 34 twentyfiveGigE1/16/2 62 25000 +Ethernet62 35 twentyfiveGigE1/16/3 63 25000 +Ethernet63 36 twentyfiveGigE1/16/4 64 25000 +Ethernet64 41 twentyfiveGigE1/17/1 65 25000 +Ethernet65 42 twentyfiveGigE1/17/2 66 25000 +Ethernet66 43 twentyfiveGigE1/17/3 67 25000 +Ethernet67 44 twentyfiveGigE1/17/4 68 25000 +Ethernet68 49 twentyfiveGigE1/18/1 69 25000 +Ethernet69 50 twentyfiveGigE1/18/2 70 25000 +Ethernet70 51 twentyfiveGigE1/18/3 71 25000 +Ethernet71 52 twentyfiveGigE1/18/4 72 25000 +Ethernet72 69 twentyfiveGigE1/19/1 73 25000 +Ethernet73 70 twentyfiveGigE1/19/2 74 25000 +Ethernet74 71 twentyfiveGigE1/19/3 75 25000 +Ethernet75 72 twentyfiveGigE1/19/4 76 25000 +Ethernet76 77 twentyfiveGigE1/20/1 77 25000 +Ethernet77 78 twentyfiveGigE1/20/2 78 25000 +Ethernet78 79 twentyfiveGigE1/20/3 79 25000 +Ethernet79 80 twentyfiveGigE1/20/4 80 25000 +Ethernet80 81 twentyfiveGigE1/21/1 81 25000 +Ethernet81 82 twentyfiveGigE1/21/2 82 25000 +Ethernet82 83 twentyfiveGigE1/21/3 83 25000 +Ethernet83 84 twentyfiveGigE1/21/4 84 25000 +Ethernet84 97 twentyfiveGigE1/22/1 85 25000 +Ethernet85 98 twentyfiveGigE1/22/2 86 25000 +Ethernet86 99 twentyfiveGigE1/22/3 87 25000 +Ethernet87 100 twentyfiveGigE1/22/4 88 25000 +Ethernet88 105 twentyfiveGigE1/23/1 89 25000 +Ethernet89 106 twentyfiveGigE1/23/2 90 25000 +Ethernet90 107 twentyfiveGigE1/23/3 91 25000 +Ethernet91 108 twentyfiveGigE1/23/4 92 25000 +Ethernet92 113 twentyfiveGigE1/24/1 93 25000 +Ethernet93 114 twentyfiveGigE1/24/2 94 25000 +Ethernet94 115 twentyfiveGigE1/24/3 95 25000 +Ethernet95 116 twentyfiveGigE1/24/4 96 25000 +Ethernet96 29,30,31,32 hundredGigE1/49 97 100000 +Ethernet97 21,22,23,24 hundredGigE1/50 98 100000 +Ethernet98 125,126,127,128 hundredGigE1/51 99 100000 +Ethernet99 85,86,87,88 hundredGigE1/52 100 100000 +Ethernet100 57,58,59,60 hundredGigE1/53 101 100000 +Ethernet101 61,62,63,64 hundredGigE1/54 102 100000 +Ethernet102 121,122,123,124 hundredGigE1/55 103 100000 +Ethernet103 93,94,95,96 hundredGigE1/56 104 100000 diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/qos.json.j2 b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/qos.json.j2 new file mode 100644 index 000000000000..d2b3d2b0131c --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/qos.json.j2 @@ -0,0 +1,226 @@ +{%- set PORT_ALL = [] %} +{%- for port in PORT %} + {%- if PORT_ALL.append(port) %}{% endif %} +{%- endfor %} +{%- if PORT_ALL | sort_by_port_index %}{% endif %} + +{%- set port_names_list_all = [] %} +{%- for port in PORT_ALL %} + {%- if port_names_list_all.append(port) %}{% endif %} +{%- endfor %} +{%- set port_names_all = port_names_list_all | join(',') -%} + + +{%- set PORT_ACTIVE = [] %} +{%- if DEVICE_NEIGHBOR is not defined %} + {%- set PORT_ACTIVE = PORT_ALL %} +{%- else %} + {%- for port in DEVICE_NEIGHBOR.keys() %} + {%- if PORT_ACTIVE.append(port) %}{%- endif %} + {%- endfor %} +{%- endif %} +{%- if PORT_ACTIVE | sort_by_port_index %}{% endif %} + +{%- set port_names_list_active = [] %} +{%- for port in PORT_ACTIVE %} + {%- if port_names_list_active.append(port) %}{%- endif %} +{%- endfor %} +{%- set port_names_active = port_names_list_active | join(',') -%} + + +{%- set pfc_to_pg_map_supported_asics = ['mellanox', 'barefoot', 'marvell'] -%} + + +{ +{% if generate_tc_to_pg_map is defined %} + {{- generate_tc_to_pg_map() }} +{% else %} + "TC_TO_PRIORITY_GROUP_MAP": { + "DEFAULT": { + "0": "0", + "1": "0", + "2": "0", + "3": "0", + "4": "0", + "5": "0", + "6": "0", + "7": "7" + } + }, +{% endif %} + "MAP_PFC_PRIORITY_TO_QUEUE": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "DEFAULT": { + "0" : "0", + "1" : "0", + "2" : "0", + "3" : "0", + "4" : "0", + "5" : "0", + "6" : "0", + "7" : "0", + "8" : "0", + "9" : "0", + "10": "0", + "11": "0", + "12": "0", + "13": "0", + "14": "0", + "15": "0", + "16": "0", + "17": "0", + "18": "0", + "19": "0", + "20": "0", + "21": "0", + "22": "0", + "23": "0", + "24": "0", + "25": "0", + "26": "0", + "27": "0", + "28": "0", + "29": "0", + "30": "0", + "31": "0", + "32": "0", + "33": "0", + "34": "0", + "35": "0", + "36": "0", + "37": "0", + "38": "0", + "39": "0", + "40": "0", + "41": "0", + "42": "0", + "43": "0", + "44": "0", + "45": "0", + "46": "0", + "47": "0", + "48": "0", + "49": "0", + "50": "0", + "51": "0", + "52": "0", + "53": "0", + "54": "0", + "55": "0", + "56": "0", + "57": "0", + "58": "0", + "59": "0", + "60": "0", + "61": "0", + "62": "0", + "63": "0" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type" : "DWRR", + "weight": "1" + }, + "scheduler.1": { + "type" : "DWRR", + "weight": "2" + }, + "scheduler.2": { + "type" : "DWRR", + "weight": "3" + }, + "scheduler.3": { + "type" : "DWRR", + "weight": "4" + }, + "scheduler.4": { + "type" : "DWRR", + "weight": "5" + }, + "scheduler.5": { + "type" : "DWRR", + "weight": "10" + }, + "scheduler.6": { + "type" : "DWRR", + "weight": "25" + }, + "scheduler.7": { + "type" : "DWRR", + "weight": "50" + } + }, + "PORT_QOS_MAP": { + "{{ port_names_active }}": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|DEFAULT]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|DEFAULT]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|DEFAULT]" + } + }, + "QUEUE": { +{% for port in PORT_ACTIVE %} + "{{ port }}|0": { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|1": { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|2": { + "scheduler": "[SCHEDULER|scheduler.2]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|3": { + "scheduler": "[SCHEDULER|scheduler.3]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|4": { + "scheduler": "[SCHEDULER|scheduler.4]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|5": { + "scheduler": "[SCHEDULER|scheduler.5]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|6": { + "scheduler": "[SCHEDULER|scheduler.6]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|7": { + "scheduler": "[SCHEDULER|scheduler.7]" + }{% if not loop.last %},{% endif %} +{% endfor %} + } +} diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/sai.profile b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/sai.profile new file mode 100644 index 000000000000..793e75fc4e45 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-s5296f-25g.config.bcm diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/sai_preinit_cmd.soc b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/sai_preinit_cmd.soc new file mode 100644 index 000000000000..4d62900f898f --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-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_s5296f_c3538-r0/DellEMC-S5296f-P-25G/td3-s5296f-25g.config.bcm b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/td3-s5296f-25g.config.bcm new file mode 100644 index 000000000000..dd0901f5d01f --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/DellEMC-S5296f-P-25G/td3-s5296f-25g.config.bcm @@ -0,0 +1,596 @@ +sai_load_hw_config=/etc/bcm/flex/bcm56870_a0_issu/b870.6.4.1/ +os=unix +portmap_5.0=5:25 +portmap_6.0=6:25 +portmap_7.0=7:25 +portmap_8.0=8:25 +portmap_13.0=13:25 +portmap_14.0=14:25 +portmap_15.0=15:25 +portmap_16.0=16:25 +portmap_17.0=17:25 +portmap_18.0=18:25 +portmap_19.0=19:25 +portmap_20.0=20:25 +portmap_37.0=37:25 +portmap_38.0=38:25 +portmap_39.0=39:25 +portmap_40.0=40:25 +portmap_45.0=45:25 +portmap_46.0=46:25 +portmap_47.0=47:25 +portmap_48.0=48:25 +portmap_53.0=53:25 +portmap_54.0=54:25 +portmap_55.0=55:25 +portmap_56.0=56:25 +portmap_67.0=65:25 +portmap_68.0=66:25 +portmap_69.0=67:25 +portmap_70.0=68:25 +portmap_75.0=73:25 +portmap_76.0=74:25 +portmap_77.0=75:25 +portmap_78.0=76:25 +portmap_91.0=89:25 +portmap_92.0=90:25 +portmap_93.0=91:25 +portmap_94.0=92:25 +portmap_103.0=101:25 +portmap_104.0=102:25 +portmap_105.0=103:25 +portmap_106.0=104:25 +portmap_111.0=109:25 +portmap_112.0=110:25 +portmap_113.0=111:25 +portmap_114.0=112:25 +portmap_119.0=117:25 +portmap_120.0=118:25 +portmap_121.0=119:25 +portmap_122.0=120:25 +portmap_1.0=1:25 +portmap_2.0=2:25 +portmap_3.0=3:25 +portmap_4.0=4:25 +portmap_9.0=9:25 +portmap_10.0=10:25 +portmap_11.0=11:25 +portmap_12.0=12:25 +portmap_25.0=25:25 +portmap_26.0=26:25 +portmap_27.0=27:25 +portmap_28.0=28:25 +portmap_33.0=33:25 +portmap_34.0=34:25 +portmap_35.0=35:25 +portmap_36.0=36:25 +portmap_41.0=41:25 +portmap_42.0=42:25 +portmap_43.0=43:25 +portmap_44.0=44:25 +portmap_49.0=49:25 +portmap_50.0=50:25 +portmap_51.0=51:25 +portmap_52.0=52:25 +portmap_71.0=69:25 +portmap_72.0=70:25 +portmap_73.0=71:25 +portmap_74.0=72:25 +portmap_79.0=77:25 +portmap_80.0=78:25 +portmap_81.0=79:25 +portmap_82.0=80:25 +portmap_83.0=81:25 +portmap_84.0=82:25 +portmap_85.0=83:25 +portmap_86.0=84:25 +portmap_99.0=97:25 +portmap_100.0=98:25 +portmap_101.0=99:25 +portmap_102.0=100:25 +portmap_107.0=105:25 +portmap_108.0=106:25 +portmap_109.0=107:25 +portmap_110.0=108:25 +portmap_115.0=113:25 +portmap_116.0=114:25 +portmap_117.0=115:25 +portmap_118.0=116:25 +portmap_29.0=29:100 +portmap_21.0=21:100 +portmap_127.0=125:100 +portmap_87.0=85:100 +portmap_57.0=57:100 +portmap_61.0=61:100 +portmap_123.0=121:100 +portmap_95.0=93:100 +phy_chain_tx_lane_map_physical{5.0}=0x0123 +phy_chain_rx_lane_map_physical{5.0}=0x0123 +phy_chain_tx_lane_map_physical{13.0}=0x0123 +phy_chain_rx_lane_map_physical{13.0}=0x0123 +phy_chain_tx_lane_map_physical{17.0}=0x0123 +phy_chain_rx_lane_map_physical{17.0}=0x0123 +phy_chain_tx_lane_map_physical{37.0}=0x0123 +phy_chain_rx_lane_map_physical{37.0}=0x0123 +phy_chain_tx_lane_map_physical{45.0}=0x0123 +phy_chain_rx_lane_map_physical{45.0}=0x0123 +phy_chain_tx_lane_map_physical{53.0}=0x0123 +phy_chain_rx_lane_map_physical{53.0}=0x0123 +phy_chain_tx_lane_map_physical{65.0}=0x3210 +phy_chain_rx_lane_map_physical{65.0}=0x3210 +phy_chain_tx_lane_map_physical{73.0}=0x3210 +phy_chain_rx_lane_map_physical{73.0}=0x3210 +phy_chain_tx_lane_map_physical{89.0}=0x3210 +phy_chain_rx_lane_map_physical{89.0}=0x3210 +phy_chain_tx_lane_map_physical{101.0}=0x3210 +phy_chain_rx_lane_map_physical{101.0}=0x3210 +phy_chain_tx_lane_map_physical{109.0}=0x3210 +phy_chain_rx_lane_map_physical{109.0}=0x3210 +phy_chain_tx_lane_map_physical{117.0}=0x3210 +phy_chain_rx_lane_map_physical{117.0}=0x3210 +phy_chain_tx_lane_map_physical{1.0}=0x1032 +phy_chain_rx_lane_map_physical{1.0}=0x1032 +phy_chain_tx_lane_map_physical{9.0}=0x1032 +phy_chain_rx_lane_map_physical{9.0}=0x1032 +phy_chain_tx_lane_map_physical{25.0}=0x1032 +phy_chain_rx_lane_map_physical{25.0}=0x1032 +phy_chain_tx_lane_map_physical{33.0}=0x1032 +phy_chain_rx_lane_map_physical{33.0}=0x1032 +phy_chain_tx_lane_map_physical{41.0}=0x1032 +phy_chain_rx_lane_map_physical{41.0}=0x1032 +phy_chain_tx_lane_map_physical{49.0}=0x2031 +phy_chain_rx_lane_map_physical{49.0}=0x2031 +phy_chain_tx_lane_map_physical{69.0}=0x2301 +phy_chain_rx_lane_map_physical{69.0}=0x2301 +phy_chain_tx_lane_map_physical{77.0}=0x1302 +phy_chain_rx_lane_map_physical{77.0}=0x1302 +phy_chain_tx_lane_map_physical{81.0}=0x2301 +phy_chain_rx_lane_map_physical{81.0}=0x2301 +phy_chain_tx_lane_map_physical{97.0}=0x2301 +phy_chain_rx_lane_map_physical{97.0}=0x2301 +phy_chain_tx_lane_map_physical{105.0}=0x2301 +phy_chain_rx_lane_map_physical{105.0}=0x2301 +phy_chain_tx_lane_map_physical{113.0}=0x2301 +phy_chain_rx_lane_map_physical{113.0}=0x2301 +phy_chain_tx_lane_map_physical{29.0}=0x0123 +phy_chain_rx_lane_map_physical{29.0}=0x3201 +phy_chain_tx_lane_map_physical{21.0}=0x3021 +phy_chain_rx_lane_map_physical{21.0}=0x0312 +phy_chain_tx_lane_map_physical{125.0}=0x3210 +phy_chain_rx_lane_map_physical{125.0}=0x0132 +phy_chain_tx_lane_map_physical{85.0}=0x0312 +phy_chain_rx_lane_map_physical{85.0}=0x3021 +phy_chain_tx_lane_map_physical{57.0}=0x3021 +phy_chain_rx_lane_map_physical{57.0}=0x0312 +phy_chain_tx_lane_map_physical{61.0}=0x3210 +phy_chain_rx_lane_map_physical{61.0}=0x1230 +phy_chain_tx_lane_map_physical{121.0}=0x0123 +phy_chain_rx_lane_map_physical{121.0}=0x2310 +phy_chain_tx_lane_map_physical{93.0}=0x0123 +phy_chain_rx_lane_map_physical{93.0}=0x2301 +phy_chain_tx_polarity_flip_physical{5.0}=0x1 +phy_chain_rx_polarity_flip_physical{5.0}=0x1 +phy_chain_tx_polarity_flip_physical{6.0}=0x1 +phy_chain_rx_polarity_flip_physical{6.0}=0x1 +phy_chain_tx_polarity_flip_physical{7.0}=0x1 +phy_chain_rx_polarity_flip_physical{7.0}=0x1 +phy_chain_tx_polarity_flip_physical{8.0}=0x1 +phy_chain_rx_polarity_flip_physical{8.0}=0x1 +phy_chain_tx_polarity_flip_physical{13.0}=0x1 +phy_chain_rx_polarity_flip_physical{13.0}=0x1 +phy_chain_tx_polarity_flip_physical{14.0}=0x1 +phy_chain_rx_polarity_flip_physical{14.0}=0x1 +phy_chain_tx_polarity_flip_physical{15.0}=0x1 +phy_chain_rx_polarity_flip_physical{15.0}=0x1 +phy_chain_tx_polarity_flip_physical{16.0}=0x1 +phy_chain_rx_polarity_flip_physical{16.0}=0x1 +phy_chain_tx_polarity_flip_physical{17.0}=0x0 +phy_chain_rx_polarity_flip_physical{17.0}=0x1 +phy_chain_tx_polarity_flip_physical{18.0}=0x0 +phy_chain_rx_polarity_flip_physical{18.0}=0x1 +phy_chain_tx_polarity_flip_physical{19.0}=0x0 +phy_chain_rx_polarity_flip_physical{19.0}=0x1 +phy_chain_tx_polarity_flip_physical{20.0}=0x0 +phy_chain_rx_polarity_flip_physical{20.0}=0x1 +phy_chain_tx_polarity_flip_physical{37.0}=0x1 +phy_chain_rx_polarity_flip_physical{37.0}=0x1 +phy_chain_tx_polarity_flip_physical{38.0}=0x1 +phy_chain_rx_polarity_flip_physical{38.0}=0x1 +phy_chain_tx_polarity_flip_physical{39.0}=0x1 +phy_chain_rx_polarity_flip_physical{39.0}=0x1 +phy_chain_tx_polarity_flip_physical{40.0}=0x1 +phy_chain_rx_polarity_flip_physical{40.0}=0x1 +phy_chain_tx_polarity_flip_physical{45.0}=0x1 +phy_chain_rx_polarity_flip_physical{45.0}=0x1 +phy_chain_tx_polarity_flip_physical{46.0}=0x1 +phy_chain_rx_polarity_flip_physical{46.0}=0x1 +phy_chain_tx_polarity_flip_physical{47.0}=0x1 +phy_chain_rx_polarity_flip_physical{47.0}=0x1 +phy_chain_tx_polarity_flip_physical{48.0}=0x1 +phy_chain_rx_polarity_flip_physical{48.0}=0x1 +phy_chain_tx_polarity_flip_physical{53.0}=0x1 +phy_chain_rx_polarity_flip_physical{53.0}=0x1 +phy_chain_tx_polarity_flip_physical{54.0}=0x1 +phy_chain_rx_polarity_flip_physical{54.0}=0x1 +phy_chain_tx_polarity_flip_physical{55.0}=0x1 +phy_chain_rx_polarity_flip_physical{55.0}=0x1 +phy_chain_tx_polarity_flip_physical{56.0}=0x1 +phy_chain_rx_polarity_flip_physical{56.0}=0x1 +phy_chain_tx_polarity_flip_physical{65.0}=0x1 +phy_chain_rx_polarity_flip_physical{65.0}=0x1 +phy_chain_tx_polarity_flip_physical{66.0}=0x1 +phy_chain_rx_polarity_flip_physical{66.0}=0x1 +phy_chain_tx_polarity_flip_physical{67.0}=0x1 +phy_chain_rx_polarity_flip_physical{67.0}=0x1 +phy_chain_tx_polarity_flip_physical{68.0}=0x1 +phy_chain_rx_polarity_flip_physical{68.0}=0x1 +phy_chain_tx_polarity_flip_physical{73.0}=0x1 +phy_chain_rx_polarity_flip_physical{73.0}=0x1 +phy_chain_tx_polarity_flip_physical{74.0}=0x1 +phy_chain_rx_polarity_flip_physical{74.0}=0x1 +phy_chain_tx_polarity_flip_physical{75.0}=0x1 +phy_chain_rx_polarity_flip_physical{75.0}=0x1 +phy_chain_tx_polarity_flip_physical{76.0}=0x1 +phy_chain_rx_polarity_flip_physical{76.0}=0x1 +phy_chain_tx_polarity_flip_physical{89.0}=0x0 +phy_chain_rx_polarity_flip_physical{89.0}=0x1 +phy_chain_tx_polarity_flip_physical{90.0}=0x0 +phy_chain_rx_polarity_flip_physical{90.0}=0x1 +phy_chain_tx_polarity_flip_physical{91.0}=0x0 +phy_chain_rx_polarity_flip_physical{91.0}=0x1 +phy_chain_tx_polarity_flip_physical{92.0}=0x0 +phy_chain_rx_polarity_flip_physical{92.0}=0x1 +phy_chain_tx_polarity_flip_physical{101.0}=0x1 +phy_chain_rx_polarity_flip_physical{101.0}=0x0 +phy_chain_tx_polarity_flip_physical{102.0}=0x1 +phy_chain_rx_polarity_flip_physical{102.0}=0x0 +phy_chain_tx_polarity_flip_physical{103.0}=0x1 +phy_chain_rx_polarity_flip_physical{103.0}=0x0 +phy_chain_tx_polarity_flip_physical{104.0}=0x1 +phy_chain_rx_polarity_flip_physical{104.0}=0x0 +phy_chain_tx_polarity_flip_physical{109.0}=0x1 +phy_chain_rx_polarity_flip_physical{109.0}=0x1 +phy_chain_tx_polarity_flip_physical{110.0}=0x1 +phy_chain_rx_polarity_flip_physical{110.0}=0x1 +phy_chain_tx_polarity_flip_physical{111.0}=0x1 +phy_chain_rx_polarity_flip_physical{111.0}=0x1 +phy_chain_tx_polarity_flip_physical{112.0}=0x1 +phy_chain_rx_polarity_flip_physical{112.0}=0x1 +phy_chain_tx_polarity_flip_physical{117.0}=0x1 +phy_chain_rx_polarity_flip_physical{117.0}=0x1 +phy_chain_tx_polarity_flip_physical{118.0}=0x1 +phy_chain_rx_polarity_flip_physical{118.0}=0x1 +phy_chain_tx_polarity_flip_physical{119.0}=0x1 +phy_chain_rx_polarity_flip_physical{119.0}=0x1 +phy_chain_tx_polarity_flip_physical{120.0}=0x1 +phy_chain_rx_polarity_flip_physical{120.0}=0x1 +phy_chain_tx_polarity_flip_physical{1.0}=0x0 +phy_chain_rx_polarity_flip_physical{1.0}=0x0 +phy_chain_tx_polarity_flip_physical{2.0}=0x1 +phy_chain_rx_polarity_flip_physical{2.0}=0x1 +phy_chain_tx_polarity_flip_physical{3.0}=0x0 +phy_chain_rx_polarity_flip_physical{3.0}=0x0 +phy_chain_tx_polarity_flip_physical{4.0}=0x1 +phy_chain_rx_polarity_flip_physical{4.0}=0x1 +phy_chain_tx_polarity_flip_physical{9.0}=0x0 +phy_chain_rx_polarity_flip_physical{9.0}=0x0 +phy_chain_tx_polarity_flip_physical{10.0}=0x1 +phy_chain_rx_polarity_flip_physical{10.0}=0x1 +phy_chain_tx_polarity_flip_physical{11.0}=0x0 +phy_chain_rx_polarity_flip_physical{11.0}=0x0 +phy_chain_tx_polarity_flip_physical{12.0}=0x1 +phy_chain_rx_polarity_flip_physical{12.0}=0x1 +phy_chain_tx_polarity_flip_physical{25.0}=0x0 +phy_chain_rx_polarity_flip_physical{25.0}=0x1 +phy_chain_tx_polarity_flip_physical{26.0}=0x1 +phy_chain_rx_polarity_flip_physical{26.0}=0x1 +phy_chain_tx_polarity_flip_physical{27.0}=0x0 +phy_chain_rx_polarity_flip_physical{27.0}=0x1 +phy_chain_tx_polarity_flip_physical{28.0}=0x1 +phy_chain_rx_polarity_flip_physical{28.0}=0x0 +phy_chain_tx_polarity_flip_physical{33.0}=0x1 +phy_chain_rx_polarity_flip_physical{33.0}=0x1 +phy_chain_tx_polarity_flip_physical{34.0}=0x0 +phy_chain_rx_polarity_flip_physical{34.0}=0x0 +phy_chain_tx_polarity_flip_physical{35.0}=0x1 +phy_chain_rx_polarity_flip_physical{35.0}=0x1 +phy_chain_tx_polarity_flip_physical{36.0}=0x0 +phy_chain_rx_polarity_flip_physical{36.0}=0x0 +phy_chain_tx_polarity_flip_physical{41.0}=0x1 +phy_chain_rx_polarity_flip_physical{41.0}=0x1 +phy_chain_tx_polarity_flip_physical{42.0}=0x0 +phy_chain_rx_polarity_flip_physical{42.0}=0x0 +phy_chain_tx_polarity_flip_physical{43.0}=0x1 +phy_chain_rx_polarity_flip_physical{43.0}=0x1 +phy_chain_tx_polarity_flip_physical{44.0}=0x0 +phy_chain_rx_polarity_flip_physical{44.0}=0x0 +phy_chain_tx_polarity_flip_physical{49.0}=0x1 +phy_chain_rx_polarity_flip_physical{49.0}=0x1 +phy_chain_tx_polarity_flip_physical{50.0}=0x1 +phy_chain_rx_polarity_flip_physical{50.0}=0x1 +phy_chain_tx_polarity_flip_physical{51.0}=0x0 +phy_chain_rx_polarity_flip_physical{51.0}=0x0 +phy_chain_tx_polarity_flip_physical{52.0}=0x0 +phy_chain_rx_polarity_flip_physical{52.0}=0x0 +phy_chain_tx_polarity_flip_physical{69.0}=0x1 +phy_chain_rx_polarity_flip_physical{69.0}=0x1 +phy_chain_tx_polarity_flip_physical{70.0}=0x0 +phy_chain_rx_polarity_flip_physical{70.0}=0x0 +phy_chain_tx_polarity_flip_physical{71.0}=0x1 +phy_chain_rx_polarity_flip_physical{71.0}=0x1 +phy_chain_tx_polarity_flip_physical{72.0}=0x0 +phy_chain_rx_polarity_flip_physical{72.0}=0x0 +phy_chain_tx_polarity_flip_physical{77.0}=0x1 +phy_chain_rx_polarity_flip_physical{77.0}=0x1 +phy_chain_tx_polarity_flip_physical{78.0}=0x1 +phy_chain_rx_polarity_flip_physical{78.0}=0x1 +phy_chain_tx_polarity_flip_physical{79.0}=0x0 +phy_chain_rx_polarity_flip_physical{79.0}=0x0 +phy_chain_tx_polarity_flip_physical{80.0}=0x0 +phy_chain_rx_polarity_flip_physical{80.0}=0x0 +phy_chain_tx_polarity_flip_physical{81.0}=0x0 +phy_chain_rx_polarity_flip_physical{81.0}=0x0 +phy_chain_tx_polarity_flip_physical{82.0}=0x1 +phy_chain_rx_polarity_flip_physical{82.0}=0x1 +phy_chain_tx_polarity_flip_physical{83.0}=0x0 +phy_chain_rx_polarity_flip_physical{83.0}=0x0 +phy_chain_tx_polarity_flip_physical{84.0}=0x1 +phy_chain_rx_polarity_flip_physical{84.0}=0x1 +phy_chain_tx_polarity_flip_physical{97.0}=0x0 +phy_chain_rx_polarity_flip_physical{97.0}=0x0 +phy_chain_tx_polarity_flip_physical{98.0}=0x1 +phy_chain_rx_polarity_flip_physical{98.0}=0x1 +phy_chain_tx_polarity_flip_physical{99.0}=0x0 +phy_chain_rx_polarity_flip_physical{99.0}=0x0 +phy_chain_tx_polarity_flip_physical{100.0}=0x1 +phy_chain_rx_polarity_flip_physical{100.0}=0x1 +phy_chain_tx_polarity_flip_physical{105.0}=0x0 +phy_chain_rx_polarity_flip_physical{105.0}=0x1 +phy_chain_tx_polarity_flip_physical{106.0}=0x1 +phy_chain_rx_polarity_flip_physical{106.0}=0x0 +phy_chain_tx_polarity_flip_physical{107.0}=0x0 +phy_chain_rx_polarity_flip_physical{107.0}=0x1 +phy_chain_tx_polarity_flip_physical{108.0}=0x1 +phy_chain_rx_polarity_flip_physical{108.0}=0x0 +phy_chain_tx_polarity_flip_physical{113.0}=0x0 +phy_chain_rx_polarity_flip_physical{113.0}=0x1 +phy_chain_tx_polarity_flip_physical{114.0}=0x1 +phy_chain_rx_polarity_flip_physical{114.0}=0x0 +phy_chain_tx_polarity_flip_physical{115.0}=0x0 +phy_chain_rx_polarity_flip_physical{115.0}=0x1 +phy_chain_tx_polarity_flip_physical{116.0}=0x1 +phy_chain_rx_polarity_flip_physical{116.0}=0x0 +phy_chain_tx_polarity_flip_physical{29.0}=0x1 +phy_chain_rx_polarity_flip_physical{29.0}=0x0 +phy_chain_tx_polarity_flip_physical{30.0}=0x1 +phy_chain_rx_polarity_flip_physical{30.0}=0x1 +phy_chain_tx_polarity_flip_physical{31.0}=0x0 +phy_chain_rx_polarity_flip_physical{31.0}=0x0 +phy_chain_tx_polarity_flip_physical{32.0}=0x0 +phy_chain_rx_polarity_flip_physical{32.0}=0x0 +phy_chain_tx_polarity_flip_physical{21.0}=0x0 +phy_chain_rx_polarity_flip_physical{21.0}=0x1 +phy_chain_tx_polarity_flip_physical{22.0}=0x0 +phy_chain_rx_polarity_flip_physical{22.0}=0x1 +phy_chain_tx_polarity_flip_physical{23.0}=0x1 +phy_chain_rx_polarity_flip_physical{23.0}=0x1 +phy_chain_tx_polarity_flip_physical{24.0}=0x0 +phy_chain_rx_polarity_flip_physical{24.0}=0x1 +phy_chain_tx_polarity_flip_physical{125.0}=0x1 +phy_chain_rx_polarity_flip_physical{125.0}=0x0 +phy_chain_tx_polarity_flip_physical{126.0}=0x0 +phy_chain_rx_polarity_flip_physical{126.0}=0x0 +phy_chain_tx_polarity_flip_physical{127.0}=0x0 +phy_chain_rx_polarity_flip_physical{127.0}=0x0 +phy_chain_tx_polarity_flip_physical{128.0}=0x0 +phy_chain_rx_polarity_flip_physical{128.0}=0x1 +phy_chain_tx_polarity_flip_physical{85.0}=0x0 +phy_chain_rx_polarity_flip_physical{85.0}=0x0 +phy_chain_tx_polarity_flip_physical{86.0}=0x0 +phy_chain_rx_polarity_flip_physical{86.0}=0x0 +phy_chain_tx_polarity_flip_physical{87.0}=0x1 +phy_chain_rx_polarity_flip_physical{87.0}=0x1 +phy_chain_tx_polarity_flip_physical{88.0}=0x0 +phy_chain_rx_polarity_flip_physical{88.0}=0x0 +phy_chain_tx_polarity_flip_physical{57.0}=0x0 +phy_chain_rx_polarity_flip_physical{57.0}=0x0 +phy_chain_tx_polarity_flip_physical{58.0}=0x0 +phy_chain_rx_polarity_flip_physical{58.0}=0x1 +phy_chain_tx_polarity_flip_physical{59.0}=0x1 +phy_chain_rx_polarity_flip_physical{59.0}=0x0 +phy_chain_tx_polarity_flip_physical{60.0}=0x0 +phy_chain_rx_polarity_flip_physical{60.0}=0x0 +phy_chain_tx_polarity_flip_physical{61.0}=0x0 +phy_chain_rx_polarity_flip_physical{61.0}=0x1 +phy_chain_tx_polarity_flip_physical{62.0}=0x1 +phy_chain_rx_polarity_flip_physical{62.0}=0x0 +phy_chain_tx_polarity_flip_physical{63.0}=0x1 +phy_chain_rx_polarity_flip_physical{63.0}=0x1 +phy_chain_tx_polarity_flip_physical{64.0}=0x1 +phy_chain_rx_polarity_flip_physical{64.0}=0x1 +phy_chain_tx_polarity_flip_physical{121.0}=0x1 +phy_chain_rx_polarity_flip_physical{121.0}=0x0 +phy_chain_tx_polarity_flip_physical{122.0}=0x1 +phy_chain_rx_polarity_flip_physical{122.0}=0x1 +phy_chain_tx_polarity_flip_physical{123.0}=0x1 +phy_chain_rx_polarity_flip_physical{123.0}=0x1 +phy_chain_tx_polarity_flip_physical{124.0}=0x1 +phy_chain_rx_polarity_flip_physical{124.0}=0x1 +phy_chain_tx_polarity_flip_physical{93.0}=0x0 +phy_chain_rx_polarity_flip_physical{93.0}=0x1 +phy_chain_tx_polarity_flip_physical{94.0}=0x0 +phy_chain_rx_polarity_flip_physical{94.0}=0x0 +phy_chain_tx_polarity_flip_physical{95.0}=0x1 +phy_chain_rx_polarity_flip_physical{95.0}=0x0 +phy_chain_tx_polarity_flip_physical{96.0}=0x0 +phy_chain_rx_polarity_flip_physical{96.0}=0x1 +dport_map_enable=1 +dport_map_port_5=1 +dport_map_port_6=2 +dport_map_port_7=3 +dport_map_port_8=4 +dport_map_port_13=5 +dport_map_port_14=6 +dport_map_port_15=7 +dport_map_port_16=8 +dport_map_port_17=9 +dport_map_port_18=10 +dport_map_port_19=11 +dport_map_port_20=12 +dport_map_port_37=13 +dport_map_port_38=14 +dport_map_port_39=15 +dport_map_port_40=16 +dport_map_port_45=17 +dport_map_port_46=18 +dport_map_port_47=19 +dport_map_port_48=20 +dport_map_port_53=21 +dport_map_port_54=22 +dport_map_port_55=23 +dport_map_port_56=24 +dport_map_port_67=25 +dport_map_port_68=26 +dport_map_port_69=27 +dport_map_port_70=28 +dport_map_port_75=29 +dport_map_port_76=30 +dport_map_port_77=31 +dport_map_port_78=32 +dport_map_port_91=33 +dport_map_port_92=34 +dport_map_port_93=35 +dport_map_port_94=36 +dport_map_port_103=37 +dport_map_port_104=38 +dport_map_port_105=39 +dport_map_port_106=40 +dport_map_port_111=41 +dport_map_port_112=42 +dport_map_port_113=43 +dport_map_port_114=44 +dport_map_port_119=45 +dport_map_port_120=46 +dport_map_port_121=47 +dport_map_port_122=48 +dport_map_port_1=49 +dport_map_port_2=50 +dport_map_port_3=51 +dport_map_port_4=52 +dport_map_port_9=53 +dport_map_port_10=54 +dport_map_port_11=55 +dport_map_port_12=56 +dport_map_port_25=57 +dport_map_port_26=58 +dport_map_port_27=59 +dport_map_port_28=60 +dport_map_port_33=61 +dport_map_port_34=62 +dport_map_port_35=63 +dport_map_port_36=64 +dport_map_port_41=65 +dport_map_port_42=66 +dport_map_port_43=67 +dport_map_port_44=68 +dport_map_port_49=69 +dport_map_port_50=70 +dport_map_port_51=71 +dport_map_port_52=72 +dport_map_port_71=73 +dport_map_port_72=74 +dport_map_port_73=75 +dport_map_port_74=76 +dport_map_port_79=77 +dport_map_port_80=78 +dport_map_port_81=79 +dport_map_port_82=80 +dport_map_port_83=81 +dport_map_port_84=82 +dport_map_port_85=83 +dport_map_port_86=84 +dport_map_port_99=85 +dport_map_port_100=86 +dport_map_port_101=87 +dport_map_port_102=88 +dport_map_port_107=89 +dport_map_port_108=90 +dport_map_port_109=91 +dport_map_port_110=92 +dport_map_port_115=93 +dport_map_port_116=94 +dport_map_port_117=95 +dport_map_port_118=96 +dport_map_port_29=97 +dport_map_port_30=98 +dport_map_port_31=99 +dport_map_port_32=100 +dport_map_port_21=101 +dport_map_port_22=102 +dport_map_port_23=103 +dport_map_port_24=104 +dport_map_port_127=105 +dport_map_port_128=106 +dport_map_port_129=107 +dport_map_port_130=108 +dport_map_port_87=109 +dport_map_port_88=110 +dport_map_port_89=111 +dport_map_port_90=112 +dport_map_port_57=113 +dport_map_port_58=114 +dport_map_port_59=115 +dport_map_port_60=116 +dport_map_port_61=117 +dport_map_port_62=118 +dport_map_port_63=119 +dport_map_port_64=120 +dport_map_port_123=121 +dport_map_port_124=122 +dport_map_port_125=123 +dport_map_port_126=124 +dport_map_port_95=125 +dport_map_port_96=126 +dport_map_port_97=127 +dport_map_port_98=128 + +dpp_clock_ratio=2:3 +oversubscribe_mode=1 +core_clock_frequency=1525 +l2xmsg_mode=1 +pbmp_oversubscribe=0x7fffffffffffffff9fffffffffffffffe +pbmp_xport_xe=0x7fffffffffffffff9fffffffffffffffe +ifp_inports_support_enable=1 +port_flex_enable=1 +phy_an_c73=3 +l2xmsg_hostbuf_size=8192 +module_64ports=0 +tdma_intr_enable=1 +ipv6_lpm_128b_enable=1 +stat_if_parity_enable=1 +bcm_tunnel_term_compatible_mode=1 +table_dma_enable=1 +schan_intr_enable=0 +parity_enable=1 +parity_correction=1 +miim_intr_enable=1 +tdma_timeout_usec=5000000 +max_vp_lags=0 +mmu_lossless=0 +pdma_descriptor_prefetch_enable=1 +pktdma_poll_mode_channel_bitmap=1 +l3_max_ecmp_mode.0=1 +ptp_ts_pll_fref=50000000 +ptp_bs_fref_0=50000000 +ptp_bs_fref_1=50000000 + +l3_alpm_enable=2 +l3_alpm_ipv6_128b_bkt_rsvd=1 +l2_mem_entries=40960 +l3_mem_entries=40960 +l3_max_ecmp_mode=1 + +stable_size=0x5500000 + +mmu_init_config="TD3-DELL-lossless" +sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/default_sku b/device/dell/x86_64-dellemc_s5296f_c3538-r0/default_sku new file mode 100644 index 000000000000..622d32812f43 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/default_sku @@ -0,0 +1 @@ +DellEMC-S5296f-P-25G t1 \ No newline at end of file diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/installer.conf b/device/dell/x86_64-dellemc_s5296f_c3538-r0/installer.conf new file mode 100644 index 000000000000..924e0fb81963 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/installer.conf @@ -0,0 +1,2 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/led_proc_init.soc b/device/dell/x86_64-dellemc_s5296f_c3538-r0/led_proc_init.soc new file mode 100644 index 000000000000..69072c369a64 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/led_proc_init.soc @@ -0,0 +1,6 @@ +# LED microprocessor initialization for Dell S5232 +# +# +#Led0 +led auto on +led start diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/media_settings.json b/device/dell/x86_64-dellemc_s5296f_c3538-r0/media_settings.json new file mode 100644 index 000000000000..8bdc0e7aa984 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/media_settings.json @@ -0,0 +1,442 @@ +{ + "GLOBAL_MEDIA_SETTINGS": { + "1-32": { + "QSFP28-40GBASE-CR4-1M":{ + "preemphasis": { + "lane0":"0x16440A", + "lane1":"0x16440A", + "lane2":"0x16440A", + "lane3":"0x16440A" + } + }, + "QSFP28-40GBASE-CR4-2M":{ + "preemphasis": { + "lane0":"0x18420A", + "lane1":"0x18420A", + "lane2":"0x18420A", + "lane3":"0x18420A" + } + }, + "QSFP28-40GBASE-CR4-3M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP28-40GBASE-CR4-4M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP28-40GBASE-CR4-5M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP28-40GBASE-CR4-7M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP28-40GBASE-CR4-10M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP+-40GBASE-CR4-1M":{ + "preemphasis": { + "lane0":"0x16440A", + "lane1":"0x16440A", + "lane2":"0x16440A", + "lane3":"0x16440A" + } + }, + "QSFP+-40GBASE-CR4-2M":{ + "preemphasis": { + "lane0":"0x18420A", + "lane1":"0x18420A", + "lane2":"0x18420A", + "lane3":"0x18420A" + } + }, + "QSFP+-40GBASE-CR4-3M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP+-40GBASE-CR4-4M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP+-40GBASE-CR4-5M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP+-40GBASE-CR4-7M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP+-40GBASE-CR4-10M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + } + } + }, + + "PORT_MEDIA_SETTINGS": { + "1": { + "Default": { + "preemphasis": { + "lane0":"0x164509", + "lane1":"0x164509", + "lane2":"0x164509", + "lane3":"0x164509" + } + } + }, + "2": { + "Default": { + "preemphasis": { + "lane0":"0x164509", + "lane1":"0x164509", + "lane2":"0x164509", + "lane3":"0x164509" + } + } + }, + "3": { + "Default": { + "preemphasis": { + "lane0":"0x144808", + "lane1":"0x144808", + "lane2":"0x144808", + "lane3":"0x144808" + } + } + }, + "4": { + "Default": { + "preemphasis": { + "lane0":"0x144808", + "lane1":"0x144808", + "lane2":"0x144808", + "lane3":"0x144808" + } + } + }, + "5": { + "Default": { + "preemphasis": { + "lane0":"0x144808", + "lane1":"0x144808", + "lane2":"0x144808", + "lane3":"0x144808" + } + } + }, + "6": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "7": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "8": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "9": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "10": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "11": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "12": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "13": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "14": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "15": { + "Default": { + "preemphasis": { + "lane0":"0x0E4E08", + "lane1":"0x0E4E08", + "lane2":"0x0E4E08", + "lane3":"0x0E4E08" + } + } + }, + "16": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "17": { + "Default": { + "preemphasis": { + "lane0":"0x0E4E08", + "lane1":"0x0E4E08", + "lane2":"0x0E4E08", + "lane3":"0x0E4E08" + } + } + }, + "18": { + "Default": { + "preemphasis": { + "lane0":"0x0E4E08", + "lane1":"0x0E4E08", + "lane2":"0x0E4E08", + "lane3":"0x0E4E08" + } + } + }, + "19": { + "Default": { + "preemphasis": { + "lane0":"0x0E4E08", + "lane1":"0x0E4E08", + "lane2":"0x0E4E08", + "lane3":"0x0E4E08" + } + } + }, + "20": { + "Default": { + "preemphasis": { + "lane0":"0x0E4E08", + "lane1":"0x0E4E08", + "lane2":"0x0E4E08", + "lane3":"0x0E4E08" + } + } + }, + "21": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "22": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "23": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "24": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "25": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "26": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "27": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "28": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "29": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "30": { + "Default": { + "preemphasis": { + "lane0":"0x144808", + "lane1":"0x144808", + "lane2":"0x144808", + "lane3":"0x144808" + } + } + }, + "31": { + "Default": { + "preemphasis": { + "lane0":"0x144808", + "lane1":"0x144808", + "lane2":"0x144808", + "lane3":"0x144808" + } + } + }, + "32": { + "Default": { + "preemphasis": { + "lane0":"0x144808", + "lane1":"0x144808", + "lane2":"0x144808", + "lane3":"0x144808" + } + } + } + } +} + diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/plugins/eeprom.py b/device/dell/x86_64-dellemc_s5296f_c3538-r0/plugins/eeprom.py new file mode 100644 index 000000000000..e4ee56138a77 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/plugins/eeprom.py @@ -0,0 +1,30 @@ +############################################################################# +# DellEMC S5296f +# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# + +import os.path + +try: + from sonic_eeprom import eeprom_tlvinfo +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = None + for b in (0, 1): + f = '/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom'.format(b) + if os.path.exists(f): + self.eeprom_path = f + break + if self.eeprom_path is None: + return + + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/plugins/psuutil.py b/device/dell/x86_64-dellemc_s5296f_c3538-r0/plugins/psuutil.py new file mode 100644 index 000000000000..8a7b53a626bf --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/plugins/psuutil.py @@ -0,0 +1,102 @@ +# +# psuutil.py +# Platform-specific PSU status interface for SONiC +# + + +import logging +import sys + +if sys.version_info[0] < 3: + import commands +else: + import subprocess as commands + + +S5296F_MAX_PSUS = 2 +IPMI_PSU_DATA = "docker exec -it pmon ipmitool sdr list" +IPMI_PSU_DATA_DOCKER = "ipmitool sdr list" +PSU_PRESENCE = "PSU{0}_stat" +# Use this for older firmware +# PSU_PRESENCE="PSU{0}_prsnt" +ipmi_sdr_list = "" + + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + PsuBase.__init__(self) + + def isDockerEnv(self): + num_docker = open('/proc/self/cgroup', 'r').read().count(":/docker") + if num_docker > 0: + return True + else: + return False + + # Fetch a BMC register + def get_pmc_register(self, reg_name): + + global ipmi_sdr_list + ipmi_cmd = IPMI_PSU_DATA + dockerenv = self.isDockerEnv() + if dockerenv == True: + ipmi_cmd = IPMI_PSU_DATA_DOCKER + + status, ipmi_sdr_list = commands.getstatusoutput(ipmi_cmd) + + 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 ') + sys.exit(0) + + output = output.split('|')[1] + + logging.basicConfig(level=logging.DEBUG) + return output + + 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 + """ + S5296F_MAX_PSUS = 2 + return S5296F_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 + """ + # Until psu_status is implemented this is hardcoded temporarily + + 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 + """ + cmd_status, psu_status = commands.getstatusoutput( + 'ipmitool raw 0x04 0x2d ' + hex(0x30 + index) + " | awk '{print substr($0,9,1)}'") + return 1 if psu_status == '1' else 0 diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/plugins/sfputil.py b/device/dell/x86_64-dellemc_s5296f_c3538-r0/plugins/sfputil.py new file mode 100644 index 000000000000..c270ef47f1e0 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/plugins/sfputil.py @@ -0,0 +1,556 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# +# For S5296F-ON, hardware version X01 + +try: + import struct + import time + from sonic_sfp.sfputilbase import SfpUtilBase + from os import * + from mmap import * + import io + 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)) + + +# definitions of the offset and width for values in DOM info eeprom +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""" + + PORT_START = 1 + PORT_END = 104 + PORTS_IN_BLOCK = 104 + + BASE_RES_PATH = "/sys/bus/pci/devices/0000:04:00.0/resource0" + + _port_to_eeprom_mapping = {} + + _global_port_pres_dict = {} + + @property + def port_start(self): + return self.PORT_START + + @property + def port_end(self): + return self.PORT_END + + @property + def qsfp_ports(self): + return list(range(97, self.PORTS_IN_BLOCK + 1)) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + def pci_mem_read(self, mm, offset): + mm.seek(offset) + read_data_stream = mm.read(4) + reg_val = struct.unpack('I', read_data_stream) + mem_val = str(reg_val)[1:-2] + # print "reg_val read:%x"%reg_val + return mem_val + + def pci_mem_write(self, mm, offset, data): + mm.seek(offset) + # print "data to write:%x"%data + mm.write(struct.pack('I', data)) + + def pci_set_value(self, resource, val, offset): + fd = open(resource, O_RDWR) + mm = mmap(fd, 0) + val = self.pci_mem_write(mm, offset, val) + mm.close() + close(fd) + return val + + def pci_get_value(self, resource, offset): + fd = open(resource, O_RDWR) + mm = mmap(fd, 0) + val = self.pci_mem_read(mm, offset) + mm.close() + close(fd) + return val + + def init_global_port_presence(self): + for port_num in range(self.port_start, (self.port_end + 1)): + presence = self.get_presence(port_num) + if(presence): + self._global_port_pres_dict[port_num] = '1' + else: + self._global_port_pres_dict[port_num] = '0' + + def __init__(self): + eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" + + for x in range(self.port_start, self.port_end + 1): + self.port_to_eeprom_mapping[x] = eeprom_path.format(x + 1) + self.init_global_port_presence() + SfpUtilBase.__init__(self) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + # Port offset starts with 0x4004 + port_offset = 16388 + ((port_num-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == ""): + return False + + # Mask off bit for presence + mask = (1 << 1) + if (port_num > 96): + mask = (1 << 4) + + # ModPrsL is active low + if reg_value & mask == 0: + return True + + return False + + def get_low_power_mode(self, port_num): + + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + # Port offset starts with 0x4000 + port_offset = 16384 + ((port_num-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == ""): + return False + + # Mask off 4th bit for presence + mask = (1 << 6) + + # LPMode is active high + if reg_value & mask == 0: + return False + + return True + + def set_low_power_mode(self, port_num, lpmode): + + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + # Port offset starts with 0x4000 + port_offset = 16384 + ((port_num-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == ""): + return False + + # Mask off 4th bit for presence + mask = (1 << 6) + + # LPMode is active high; set or clear the bit accordingly + if lpmode is True: + reg_value = reg_value | mask + else: + reg_value = reg_value & ~mask + + # Convert our register value back to a hex string and write back + self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + + return True + + def reset(self, port_num): + + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + # Port offset starts with 0x4000 + port_offset = 16384 + ((port_num-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == ""): + return False + + # Mask off 4th bit for presence + mask = (1 << 6) + + # ResetL is active low + reg_value = reg_value & ~mask + + # Convert our register value back to a hex string and write back + self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + + # Sleep 1 second to allow it to settle + time.sleep(1) + + reg_value = reg_value | mask + + # Convert our register value back to a hex string and write back + self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + + return True + + 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) + 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): + 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_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' + 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'] + + 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 None + 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 diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/pmon_daemon_control.json b/device/dell/x86_64-dellemc_s5296f_c3538-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..72ef3c2210a2 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/pmon_daemon_control.json @@ -0,0 +1,8 @@ +{ + "skip_sensors": true, + "skip_fancontrol": true, + "skip_ledd": true, + "skip_psud": true, + "skip_syseepromd": true, + "skip_thermalctld": true +} diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/buffers_defaults_t1.j2 index f120b337de04..d538ab1f650f 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/buffers_defaults_t1.j2 +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/buffers_defaults_t1.j2 @@ -11,18 +11,13 @@ {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "34859968", + "size": "35621248", "type": "ingress", "mode": "dynamic", "xoff": "7847424" }, - "egress_lossy_pool": { - "size": "29631680", - "type": "egress", - "mode": "dynamic" - }, "egress_lossless_pool": { - "size": "43481152", + "size": "43468672", "type": "egress", "mode": "static" } @@ -35,12 +30,13 @@ }, "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", - "size":"1518", - "static_th":"10870288" + "size":"0", + "static_th":"43468672" }, "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_lossy_pool]", - "size":"1518", + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "mode":"dynamic", "dynamic_th":"3" } }, diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/sai.profile b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/sai.profile index 0a4fed041752..c6e99b771db6 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/sai.profile +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-z9264f-64x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/th2-z9264f-64x100G.config.bcm b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/th2-z9264f-64x100G.config.bcm index fdd3b3fc076d..2cc2d055f48d 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/th2-z9264f-64x100G.config.bcm +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/th2-z9264f-64x100G.config.bcm @@ -8,7 +8,7 @@ fpem_mem_entries=65536 l2xmsg_mode=1 l3_alpm_enable=2 -bcm_num_cos=8 +bcm_num_cos=10 switch_bypass_mode=0 mmu_lossless=0 lpm_scaling_enable=0 @@ -1003,3 +1003,4 @@ dport_map_port_66=65 dport_map_port_100=66 module_64ports=1 +mmu_init_config="MSFT-TH2-Tier1" diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/buffers_defaults_t0.j2 index 2b40c3d6ad25..cbbae78d7596 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/buffers_defaults_t0.j2 +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/buffers_defaults_t0.j2 @@ -18,18 +18,13 @@ {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "33096128", + "size": "34369920", "type": "ingress", "mode": "dynamic", "xoff": "9098752" }, - "egress_lossy_pool": { - "size": "28132416", - "type": "egress", - "mode": "dynamic" - }, "egress_lossless_pool": { - "size": "43108416", + "size": "43468672", "type": "egress", "mode": "static" } @@ -42,12 +37,13 @@ }, "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", - "size":"1518", - "static_th":"10777104" + "size":"0", + "static_th":"43468672" }, "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_lossy_pool]", + "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"1518", + "mode":"dynamic", "dynamic_th":"3" } }, diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/sai.profile b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/sai.profile index 7bf21827cd19..a6a351387d56 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/sai.profile +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-z9264f-8x100G-112x50G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/th2-z9264f-8x100G-112x50G.config.bcm b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/th2-z9264f-8x100G-112x50G.config.bcm index f4b3addfb516..0c1fabf7c6fe 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/th2-z9264f-8x100G-112x50G.config.bcm +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/th2-z9264f-8x100G-112x50G.config.bcm @@ -8,7 +8,7 @@ fpem_mem_entries=65536 l2xmsg_mode=1 l3_alpm_enable=2 -bcm_num_cos=8 +bcm_num_cos=10 switch_bypass_mode=0 mmu_lossless=0 lpm_scaling_enable=0 @@ -1115,5 +1115,5 @@ dport_map_port_66=121 dport_map_port_100=122 module_64ports=1 -mmu_init_config="MSFT-TH-Tier0" +mmu_init_config="MSFT-TH2-Tier0" diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/buffers_defaults_t0.j2 index c3e8cbda67dd..96c99e5800e9 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/buffers_defaults_t0.j2 +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/buffers_defaults_t0.j2 @@ -11,18 +11,13 @@ {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "38738752", + "size": "35621248", "type": "ingress", "mode": "dynamic", - "xoff": "3855488" - }, - "egress_lossy_pool": { - "size": "37057280", - "type": "egress", - "mode": "dynamic" + "xoff": "7847424" }, "egress_lossless_pool": { - "size": "43507776", + "size": "43468672", "type": "egress", "mode": "static" } @@ -35,12 +30,13 @@ }, "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", - "size":"1518", - "static_th":"10876944" + "size":"0", + "static_th":"43468672" }, "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_lossy_pool]", + "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"1518", + "mode":"dynamic", "dynamic_th":"3" } }, diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/buffers_defaults_t1.j2 index a5322c73272d..5710131e5287 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/buffers_defaults_t1.j2 +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/buffers_defaults_t1.j2 @@ -11,18 +11,13 @@ {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "37968320", + "size": "35621248", "type": "ingress", "mode": "dynamic", - "xoff": "4625920" - }, - "egress_lossy_pool": { - "size": "36402496", - "type": "egress", - "mode": "dynamic" + "xoff": "7847424" }, "egress_lossless_pool": { - "size": "43507776", + "size": "43468672", "type": "egress", "mode": "static" } @@ -35,11 +30,11 @@ }, "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", - "size":"1518", - "static_th":"10876944" + "size":"0", + "static_th":"43468672" }, "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_lossy_pool]", + "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"1518", "dynamic_th":"3" } diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/sai.profile.j2 b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/sai.profile.j2 index 66859a473733..7c6d12b4b173 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/sai.profile.j2 +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/sai.profile.j2 @@ -1,7 +1,7 @@ {# Get sai.profile based on switch_role #} {%- if DEVICE_METADATA is defined -%} {%- set switch_role = DEVICE_METADATA['localhost']['type'] -%} -{%- if switch_role.lower() == 'torrouter' %} +{%- if 'torrouter' in switch_role.lower() %} {% set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-z9264f-64x40G-t0.config.bcm' -%} {%- else %} {%- set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-z9264f-64x40G-t1.config.bcm' -%} @@ -11,3 +11,4 @@ {%- endif %} {# Write the contents of sai_ profile_filename to sai.profile file #} {{ sai_profile_contents }} +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t0.config.bcm b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t0.config.bcm index 79ec519f7853..24990bbdb1e7 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t0.config.bcm +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t0.config.bcm @@ -8,7 +8,7 @@ fpem_mem_entries=65536 l2xmsg_mode=1 l3_alpm_enable=2 -bcm_num_cos=8 +bcm_num_cos=10 switch_bypass_mode=0 mmu_lossless=0 lpm_scaling_enable=0 @@ -1003,5 +1003,4 @@ dport_map_port_66=65 dport_map_port_100=66 module_64ports=1 - -mmu_init_config="MSFT-TH-Tier0" +mmu_init_config="MSFT-TH2-Tier0" diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t1.config.bcm b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t1.config.bcm index 8551d7b5b14d..b3920ebc6b8a 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t1.config.bcm +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t1.config.bcm @@ -8,7 +8,7 @@ fpem_mem_entries=65536 l2xmsg_mode=1 l3_alpm_enable=2 -bcm_num_cos=8 +bcm_num_cos=10 switch_bypass_mode=0 mmu_lossless=0 lpm_scaling_enable=0 @@ -1004,4 +1004,4 @@ dport_map_port_100=66 module_64ports=1 -mmu_init_config="MSFT-TH-Tier1" +mmu_init_config="MSFT-TH2-Tier1" diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/eeprom.py b/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/eeprom.py index ce1691a72945..a38a0395d5b3 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/eeprom.py +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # DellEMC Z9264f # @@ -12,15 +10,15 @@ try: import os.path from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): def __init__(self, name, path, cpld_root, ro): self.eeprom_path = None - for b in (0,1): + for b in (0, 1): f = '/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom'.format(b) if os.path.exists(f): self.eeprom_path = f diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/psuutil.py b/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/psuutil.py index c72a2d6675b3..3a58afda8df4 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/psuutil.py +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/psuutil.py @@ -6,9 +6,13 @@ import os.path import logging -import commands import sys +if sys.version_info[0] < 3: + import commands +else: + import subprocess as commands + Z9264F_MAX_PSUS = 2 IPMI_PSU_DATA = "docker exec -it pmon ipmitool sdr list" @@ -102,6 +106,5 @@ def get_psu_presence(self, index): if (psu_status != 'ERR'): # Check for PSU presence if (psu_status): - status = 1 + status = 1 return status - diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/sfputil.py b/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/sfputil.py index 6aa18d85e2e7..48f722a5d964 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/sfputil.py +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/sfputil.py @@ -21,7 +21,7 @@ except ImportError as e: raise ImportError("%s - required module not found" % str(e)) -#definitions of the offset and width for values in DOM info eeprom +# definitions of the offset and width for values in DOM info eeprom QSFP_DOM_REV_OFFSET = 1 QSFP_DOM_REV_WIDTH = 1 QSFP_TEMPE_OFFSET = 22 @@ -50,6 +50,7 @@ XCVR_DOM_CAPABILITY_OFFSET = 92 XCVR_DOM_CAPABILITY_WIDTH = 1 + class SfpUtil(SfpUtilBase): """Platform-specific SfpUtil class""" @@ -77,7 +78,7 @@ def port_end(self): @property def qsfp_ports(self): - return range(self.PORT_START, self.PORTS_IN_BLOCK + 1) + return list(range(self.PORT_START, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -150,7 +151,7 @@ def get_presence(self, port_num): # Mask off 1st bit for presence 65,66 if (port_num > 64): - mask = (1 << 0) + mask = (1 << 0) # ModPrsL is active low if reg_value & mask == 0: return True @@ -248,96 +249,96 @@ def reset(self, port_num): return True def get_register(self, reg_file): - retval = 'ERR' - if (not path.isfile(reg_file)): - print reg_file, 'not found !' - return retval + retval = 'ERR' + if (not path.isfile(reg_file)): + print(reg_file + ' not found !') + return retval - try: - with fdopen(open(reg_file, O_RDONLY)) as fd: - retval = fd.read() - except Exception as error: - logging.error("Unable to open ", reg_file, "file !") + try: + with fdopen(open(reg_file, O_RDONLY)) as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", reg_file, "file !") - retval = retval.rstrip('\r\n') - retval = retval.lstrip(" ") - return retval + retval = retval.rstrip('\r\n') + retval = retval.lstrip(" ") + return retval def check_interrupts(self, port_dict): - retval = 0 - is_port_dict_updated = False - 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'): - is_port_dict_updated = True - 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'): - is_port_dict_updated = True - self._global_port_pres_dict[port_num] = '0' - port_dict[port_num] = '0' - return retval, is_port_dict_updated + retval = 0 + is_port_dict_updated = False + 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'): + is_port_dict_updated = True + 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'): + is_port_dict_updated = True + self._global_port_pres_dict[port_num] = '0' + port_dict[port_num] = '0' + return retval, is_port_dict_updated def get_transceiver_change_event(self, timeout=0): - port_dict = {} - try: - # We get notified when there is a MSI interrupt (vector 4/5)CVR - # Open the sysfs file and register the epoll object - self.oir_fd = fdopen(open(self.OIR_FD_PATH, O_RDONLY)) - if self.oir_fd != -1: - # Do a dummy read before epoll register - self.oir_fd.read() - self.epoll = select.epoll() - self.epoll.register( - self.oir_fd.fileno(), select.EPOLLIN & select.EPOLLET) - else: - print("get_transceiver_change_event : unable to create fd") - return False, {} + port_dict = {} + try: + # We get notified when there is a MSI interrupt (vector 4/5)CVR + # Open the sysfs file and register the epoll object + self.oir_fd = fdopen(open(self.OIR_FD_PATH, O_RDONLY)) + if self.oir_fd != -1: + # Do a dummy read before epoll register + self.oir_fd.read() + self.epoll = select.epoll() + self.epoll.register( + self.oir_fd.fileno(), select.EPOLLIN & select.EPOLLET) + else: + print("get_transceiver_change_event : unable to create fd") + return False, {} - # Check for missed interrupts by invoking self.check_interrupts - # which will update the port_dict. - while True: - interrupt_count_start = self.get_register(self.OIR_FD_PATH) - retval, is_port_dict_updated = \ - self.check_interrupts(port_dict) - if ((retval == 0) and (is_port_dict_updated is True)): - return True, port_dict - interrupt_count_end = self.get_register(self.OIR_FD_PATH) - if (interrupt_count_start == 'ERR' or - interrupt_count_end == 'ERR'): - print("get_transceiver_change_event : \ + # Check for missed interrupts by invoking self.check_interrupts + # which will update the port_dict. + while True: + interrupt_count_start = self.get_register(self.OIR_FD_PATH) + retval, is_port_dict_updated = \ + self.check_interrupts(port_dict) + if ((retval == 0) and (is_port_dict_updated is True)): + return True, port_dict + interrupt_count_end = self.get_register(self.OIR_FD_PATH) + if (interrupt_count_start == 'ERR' or + interrupt_count_end == 'ERR'): + print("get_transceiver_change_event : \ unable to retrive interrupt count") - break - - # check_interrupts() itself may take upto 100s of msecs. - # We detect a missed interrupt based on the count - if interrupt_count_start == interrupt_count_end: - break - - # Block until an xcvr is inserted or removed with timeout = -1 - events = self.epoll.poll( - timeout=timeout if timeout != 0 else -1) - if events: - # check interrupts and return the port_dict - retval, is_port_dict_updated = \ - self.check_interrupts(port_dict) - if (retval != 0): - return False, {} - - return True, port_dict - except: - return False, {} - finally: - if self.oir_fd != -1: - self.epoll.unregister(self.oir_fd.fileno()) - self.epoll.close() - self.oir_fd.close() - self.oir_fd = -1 - self.epoll = -1 + break + + # check_interrupts() itself may take upto 100s of msecs. + # We detect a missed interrupt based on the count + if interrupt_count_start == interrupt_count_end: + break + + # Block until an xcvr is inserted or removed with timeout = -1 + events = self.epoll.poll( + timeout=timeout if timeout != 0 else -1) + if events: + # check interrupts and return the port_dict + retval, is_port_dict_updated = \ + self.check_interrupts(port_dict) + if (retval != 0): + return False, {} + return True, port_dict + except: return False, {} - + finally: + if self.oir_fd != -1: + self.epoll.unregister(self.oir_fd.fileno()) + self.epoll.close() + self.oir_fd.close() + self.oir_fd = -1 + self.epoll = -1 + + return False, {} + def get_transceiver_dom_info_dict(self, port_num): transceiver_dom_info_dict = {} @@ -346,7 +347,7 @@ def get_transceiver_dom_info_dict(self, port_num): '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: @@ -374,25 +375,29 @@ def get_transceiver_dom_info_dict(self, port_num): # 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) + 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) + qspf_dom_capability_data = sfpi_obj.parse_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) + 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) + 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) + 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: @@ -407,7 +412,8 @@ def get_transceiver_dom_info_dict(self, port_num): 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) + 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: @@ -418,9 +424,11 @@ def get_transceiver_dom_info_dict(self, port_num): 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) + 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) + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power( + dom_channel_monitor_raw, 0) else: return None @@ -453,16 +461,16 @@ def get_transceiver_dom_info_dict(self, port_num): return None try: - sysfsfile_eeprom = io.open(file_path,"rb",0) + 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) + sfpd_obj = sff8472Dom(None, 1) if sfpd_obj is None: return None dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_TEMPE_OFFSET), - SFP_TEMPE_WIDTH) + SFP_TEMPE_WIDTH) if dom_temperature_raw is not None: dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) @@ -470,7 +478,7 @@ def get_transceiver_dom_info_dict(self, port_num): return transceiver_dom_info_dict dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_VOLT_OFFSET), - SFP_VOLT_WIDTH) + SFP_VOLT_WIDTH) if dom_voltage_raw is not None: dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) @@ -519,7 +527,7 @@ def get_transceiver_dom_threshold_info_dict(self, port_num): '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: @@ -541,18 +549,18 @@ def get_transceiver_dom_threshold_info_dict(self, port_num): # 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) + 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) + 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: @@ -589,18 +597,18 @@ def get_transceiver_dom_threshold_info_dict(self, port_num): return None try: - sysfsfile_eeprom = io.open(file_path,"rb",0) + 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) + + 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) - + + 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: @@ -612,7 +620,7 @@ def get_transceiver_dom_threshold_info_dict(self, port_num): print("Error: closing sysfs file %s" % file_path) return None - #Threshold Data + # 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'] @@ -633,5 +641,5 @@ def get_transceiver_dom_threshold_info_dict(self, port_num): 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 diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/pmon_daemon_control.json b/device/dell/x86_64-dellemc_z9264f_c3538-r0/pmon_daemon_control.json index 94592fa8cebc..44871c057e82 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/pmon_daemon_control.json +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/pmon_daemon_control.json @@ -1,3 +1,4 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/buffers.json.j2 b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/buffers.json.j2 new file mode 100644 index 000000000000..0b1cb2c541b6 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..77747f6403c8 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/buffers_defaults_t0.j2 @@ -0,0 +1,20 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + }, + "BUFFER_PROFILE": { + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names_active) %} + "BUFFER_PG": { + }, +{%- endmacro %} + +{% macro generate_queue_buffers(port_names_active) %} + "BUFFER_QUEUE": { + } +{% endmacro %} + diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..77747f6403c8 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/buffers_defaults_t1.j2 @@ -0,0 +1,20 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + }, + "BUFFER_PROFILE": { + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names_active) %} + "BUFFER_PG": { + }, +{%- endmacro %} + +{% macro generate_queue_buffers(port_names_active) %} + "BUFFER_QUEUE": { + } +{% endmacro %} + diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/custom_led.bin b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/custom_led.bin new file mode 100755 index 000000000000..3ee9545e28ae Binary files /dev/null and b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/custom_led.bin differ diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/linkscan_led_fw.bin b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/linkscan_led_fw.bin new file mode 100755 index 000000000000..c2fa94a2d8cb Binary files /dev/null and b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/linkscan_led_fw.bin differ diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/port_config.ini b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/port_config.ini new file mode 100644 index 000000000000..d7d83ae21e76 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/port_config.ini @@ -0,0 +1,35 @@ +# name lanes alias index speed +Ethernet0 33,34,35,36 hundredGigE1/1 1 100000 +Ethernet8 41,42,43,44 hundredGigE1/2 2 100000 +Ethernet16 49,50,51,52 hundredGigE1/3 3 100000 +Ethernet24 57,58,59,60 hundredGigE1/4 4 100000 +Ethernet32 65,66,67,68 hundredGigE1/5 5 100000 +Ethernet40 73,74,75,76 hundredGigE1/6 6 100000 +Ethernet48 81,82,83,84 hundredGigE1/7 7 100000 +Ethernet56 89,90,91,92 hundredGigE1/8 8 100000 +Ethernet64 1,2,3,4 hundredGigE1/9 9 100000 +Ethernet72 9,10,11,12 hundredGigE1/10 10 100000 +Ethernet80 17,18,19,20 hundredGigE1/11 11 100000 +Ethernet88 25,26,27,28 hundredGigE1/12 12 100000 +Ethernet96 97,98,99,100 hundredGigE1/13 13 100000 +Ethernet104 105,106,107,108 hundredGigE1/14 14 100000 +Ethernet112 113,114,115,116 hundredGigE1/15 15 100000 +Ethernet120 121,122,123,124 hundredGigE1/16 16 100000 +Ethernet128 129,130,131,132 hundredGigE1/17 17 100000 +Ethernet136 137,138,139,140 hundredGigE1/18 18 100000 +Ethernet144 145,146,147,148 hundredGigE1/19 19 100000 +Ethernet152 153,154,155,156 hundredGigE1/20 20 100000 +Ethernet160 225,226,227,228 hundredGigE1/21 21 100000 +Ethernet168 233,234,235,236 hundredGigE1/22 22 100000 +Ethernet176 241,242,243,244 hundredGigE1/23 23 100000 +Ethernet184 249,250,251,252 hundredGigE1/24 24 100000 +Ethernet192 161,162,163,164 hundredGigE1/25 25 100000 +Ethernet200 169,170,171,172 hundredGigE1/26 26 100000 +Ethernet208 177,178,179,180 hundredGigE1/27 27 100000 +Ethernet216 185,186,187,188 hundredGigE1/28 28 100000 +Ethernet224 193,194,195,196 hundredGigE1/29 29 100000 +Ethernet232 201,202,203,204 hundredGigE1/30 30 100000 +Ethernet240 209,210,211,212 hundredGigE1/31 31 100000 +Ethernet248 217,218,219,220 hundredGigE1/32 32 100000 +Ethernet256 257 tenGigE1/33 33 10000 +Ethernet257 258 tenGigE1/34 34 10000 diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/qos.json.j2 b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/qos.json.j2 new file mode 100644 index 000000000000..f6b7ac977f7b --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/qos.json.j2 @@ -0,0 +1,225 @@ +{%- set PORT_ALL = [] %} +{%- for port in PORT %} + {%- if PORT_ALL.append(port) %}{% endif %} +{%- endfor %} +{%- if PORT_ALL | sort_by_port_index %}{% endif %} + +{%- set port_names_list_all = [] %} +{%- for port in PORT_ALL %} + {%- if port_names_list_all.append(port) %}{% endif %} +{%- endfor %} +{%- set port_names_all = port_names_list_all | join(',') -%} + + +{%- set PORT_ACTIVE = [] %} +{%- if DEVICE_NEIGHBOR is not defined %} + {%- set PORT_ACTIVE = PORT_ALL %} +{%- else %} + {%- for port in DEVICE_NEIGHBOR.keys() %} + {%- if PORT_ACTIVE.append(port) %}{%- endif %} + {%- endfor %} +{%- endif %} +{%- if PORT_ACTIVE | sort_by_port_index %}{% endif %} + +{%- set port_names_list_active = [] %} +{%- for port in PORT_ACTIVE %} + {%- if port_names_list_active.append(port) %}{%- endif %} +{%- endfor %} +{%- set port_names_active = port_names_list_active | join(',') -%} + + +{%- set pfc_to_pg_map_supported_asics = ['mellanox', 'barefoot', 'marvell'] -%} + + +{ +{% if generate_tc_to_pg_map is defined %} + {{- generate_tc_to_pg_map() }} +{% else %} + "TC_TO_PRIORITY_GROUP_MAP": { + "DEFAULT": { + "0": "0", + "1": "0", + "2": "0", + "3": "0", + "4": "0", + "5": "0", + "6": "0", + "7": "7" + } + }, +{% endif %} + "MAP_PFC_PRIORITY_TO_QUEUE": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "DEFAULT": { + "0" : "0", + "1" : "0", + "2" : "0", + "3" : "0", + "4" : "0", + "5" : "0", + "6" : "0", + "7" : "0", + "8" : "0", + "9" : "0", + "10": "0", + "11": "0", + "12": "0", + "13": "0", + "14": "0", + "15": "0", + "16": "0", + "17": "0", + "18": "0", + "19": "0", + "20": "0", + "21": "0", + "22": "0", + "23": "0", + "24": "0", + "25": "0", + "26": "0", + "27": "0", + "28": "0", + "29": "0", + "30": "0", + "31": "0", + "32": "0", + "33": "0", + "34": "0", + "35": "0", + "36": "0", + "37": "0", + "38": "0", + "39": "0", + "40": "0", + "41": "0", + "42": "0", + "43": "0", + "44": "0", + "45": "0", + "46": "0", + "47": "0", + "48": "0", + "49": "0", + "50": "0", + "51": "0", + "52": "0", + "53": "0", + "54": "0", + "55": "0", + "56": "0", + "57": "0", + "58": "0", + "59": "0", + "60": "0", + "61": "0", + "62": "0", + "63": "0" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type" : "DWRR", + "weight": "1" + }, + "scheduler.1": { + "type" : "DWRR", + "weight": "2" + }, + "scheduler.2": { + "type" : "DWRR", + "weight": "3" + }, + "scheduler.3": { + "type" : "DWRR", + "weight": "4" + }, + "scheduler.4": { + "type" : "DWRR", + "weight": "5" + }, + "scheduler.5": { + "type" : "DWRR", + "weight": "10" + }, + "scheduler.6": { + "type" : "DWRR", + "weight": "25" + }, + "scheduler.7": { + "type" : "STRICT" + } + }, + "PORT_QOS_MAP": { + "{{ port_names_active }}": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|DEFAULT]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|DEFAULT]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|DEFAULT]" + } + }, + "QUEUE": { +{% for port in PORT_ACTIVE %} + "{{ port }}|0": { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|1": { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|2": { + "scheduler": "[SCHEDULER|scheduler.2]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|3": { + "scheduler": "[SCHEDULER|scheduler.3]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|4": { + "scheduler": "[SCHEDULER|scheduler.4]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|5": { + "scheduler": "[SCHEDULER|scheduler.5]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|6": { + "scheduler": "[SCHEDULER|scheduler.6]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|7": { + "scheduler": "[SCHEDULER|scheduler.7]" + }{% if not loop.last %},{% endif %} +{% endfor %} + } +} diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/qos.json.j2.pfc.reference b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/qos.json.j2.pfc.reference new file mode 100644 index 000000000000..1756f106cc71 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/qos.json.j2.pfc.reference @@ -0,0 +1,227 @@ +{%- set PORT_ALL = [] %} +{%- for port in PORT %} + {%- if PORT_ALL.append(port) %}{% endif %} +{%- endfor %} +{%- if PORT_ALL | sort_by_port_index %}{% endif %} + +{%- set port_names_list_all = [] %} +{%- for port in PORT_ALL %} + {%- if port_names_list_all.append(port) %}{% endif %} +{%- endfor %} +{%- set port_names_all = port_names_list_all | join(',') -%} + + +{%- set PORT_ACTIVE = [] %} +{%- if DEVICE_NEIGHBOR is not defined %} + {%- set PORT_ACTIVE = PORT_ALL %} +{%- else %} + {%- for port in DEVICE_NEIGHBOR.keys() %} + {%- if PORT_ACTIVE.append(port) %}{%- endif %} + {%- endfor %} +{%- endif %} +{%- if PORT_ACTIVE | sort_by_port_index %}{% endif %} + +{%- set port_names_list_active = [] %} +{%- for port in PORT_ACTIVE %} + {%- if port_names_list_active.append(port) %}{%- endif %} +{%- endfor %} +{%- set port_names_active = port_names_list_active | join(',') -%} + + +{%- set pfc_to_pg_map_supported_asics = ['mellanox', 'barefoot', 'marvell'] -%} + + +{ +{% if generate_tc_to_pg_map is defined %} + {{- generate_tc_to_pg_map() }} +{% else %} + "TC_TO_PRIORITY_GROUP_MAP": { + "DEFAULT": { + "0": "0", + "1": "0", + "2": "0", + "3": "3", + "4": "4", + "5": "0", + "6": "0", + "7": "7" + } + }, +{% endif %} + "MAP_PFC_PRIORITY_TO_QUEUE": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "DEFAULT": { + "0" : "0", + "1" : "0", + "2" : "0", + "3" : "0", + "4" : "0", + "5" : "0", + "6" : "0", + "7" : "0", + "8" : "0", + "9" : "0", + "10": "0", + "11": "0", + "12": "0", + "13": "0", + "14": "0", + "15": "0", + "16": "0", + "17": "0", + "18": "0", + "19": "0", + "20": "0", + "21": "0", + "22": "0", + "23": "0", + "24": "0", + "25": "0", + "26": "0", + "27": "0", + "28": "0", + "29": "0", + "30": "0", + "31": "0", + "32": "0", + "33": "0", + "34": "0", + "35": "0", + "36": "0", + "37": "0", + "38": "0", + "39": "0", + "40": "0", + "41": "0", + "42": "0", + "43": "0", + "44": "0", + "45": "0", + "46": "0", + "47": "0", + "48": "0", + "49": "0", + "50": "0", + "51": "0", + "52": "0", + "53": "0", + "54": "0", + "55": "0", + "56": "0", + "57": "0", + "58": "0", + "59": "0", + "60": "0", + "61": "0", + "62": "0", + "63": "0" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type" : "DWRR", + "weight": "1" + }, + "scheduler.1": { + "type" : "DWRR", + "weight": "2" + }, + "scheduler.2": { + "type" : "DWRR", + "weight": "3" + }, + "scheduler.3": { + "type" : "DWRR", + "weight": "4" + }, + "scheduler.4": { + "type" : "DWRR", + "weight": "5" + }, + "scheduler.5": { + "type" : "DWRR", + "weight": "10" + }, + "scheduler.6": { + "type" : "DWRR", + "weight": "25" + }, + "scheduler.7": { + "type" : "STRICT" + } + }, + "PORT_QOS_MAP": { + "{{ port_names_active }}": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|DEFAULT]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|DEFAULT]", + "pfc_enable" : "3,4", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|DEFAULT]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|DEFAULT]" + } + }, + "QUEUE": { +{% for port in PORT_ACTIVE %} + "{{ port }}|0": { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|1": { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|2": { + "scheduler": "[SCHEDULER|scheduler.2]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|3": { + "scheduler": "[SCHEDULER|scheduler.3]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|4": { + "scheduler": "[SCHEDULER|scheduler.4]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|5": { + "scheduler": "[SCHEDULER|scheduler.5]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|6": { + "scheduler": "[SCHEDULER|scheduler.6]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|7": { + "scheduler": "[SCHEDULER|scheduler.7]" + }{% if not loop.last %},{% endif %} +{% endfor %} + } +} diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/sai.profile b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/sai.profile new file mode 100644 index 000000000000..bdc55873e429 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-z9332f-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/sai_postinit_cmd.soc b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/sai_postinit_cmd.soc new file mode 100644 index 000000000000..52793ea0147f --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/sai_postinit_cmd.soc @@ -0,0 +1,995 @@ +delay 200 +link off +counter off +local port ce0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x46 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1EC +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x48 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1EC +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce1 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x3C +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x46 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce2 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x3C +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x48 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce3 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x36 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce4 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x3C +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x3C +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce5 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x36 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x3C +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce6 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x3C +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x3C +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x3C +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x38 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce7 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x36 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x42 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x3C +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x3C +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce8 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x48 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce9 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x46 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce10 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x46 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce11 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x3A +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x3C +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce12 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x3C +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x3A +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x36 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x3A +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce13 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x32 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x34 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x32 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce14 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x32 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x34 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x30 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x32 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce15 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x30 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x32 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x2C +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x2C +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce16 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x36 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x32 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x30 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x30 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce17 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x30 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x36 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x32 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x32 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce18 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x36 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x38 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x32 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x32 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce19 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x3A +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x3A +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x34 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x36 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce20 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x48 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + + +delay 10 +local port ce21 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x42 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce22 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x48 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1EC +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x42 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce23 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x48 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce24 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x42 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x3C +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x42 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x3A +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce25 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x42 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x38 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x3C +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce26 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce27 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x3E +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x3C +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce28 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x3C +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce29 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce30 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x48 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1EC +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x46 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F6 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +delay 10 +local port ce31 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x40 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x4E +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1EC +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x44 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1FC +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x46 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 +link on +counter on diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/sai_preinit_cmd.soc b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/sai_preinit_cmd.soc new file mode 100644 index 000000000000..920cd33016b4 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/sai_preinit_cmd.soc @@ -0,0 +1,3 @@ +#Not supported in current SAI version +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_z9332f_d1508-r0/DellEMC-Z9332f-C32/th3-z9332f-32x100G.config.bcm b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/th3-z9332f-32x100G.config.bcm new file mode 100644 index 000000000000..67a24de577d4 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/th3-z9332f-32x100G.config.bcm @@ -0,0 +1,519 @@ +core_clock_frequency=1325 +dpr_clock_frequency=1000 +device_clock_frequency=1325 +port_flex_enable=1 + +#firmware load method, use fast load +load_firmware=0x2 + +ccm_dma_enable=0 +ccmdma_intr_enable=0 +mem_cache_enable=1 +phy_enable=0 +phy_null=1 + +dport_map_enable=1 + +module_64ports.0=0 +tdma_intr_enable.0=1 +ipv6_lpm_128b_enable.0=1 +stat_if_parity_enable.0=1 +oversubscribe_mode=0 +bcm_tunnel_term_compatible_mode.0=1 +table_dma_enable.0=1 +schan_intr_enable.0=0 +parity_enable.0=1 +tdma_timeout_usec=1000000 +lls_num_l2uc.0=10 +miim_intr_enable.0=0 +table_dma_enable=1 +max_vp_lags.0=0 +tdma_intr_enable=1 +tdma_timeout_usec.0=5000000 +parity_correction.0=1 +mmu_lossless.0=0 +bcm_num_cos=10 +default_cpu_tx_queue=7 +pktdma_poll_mode_channel_bitmap=1 +l3_max_ecmp_mode.0=1 +l3_alpm_enable=2 +l3_alpm_ipv6_128b_bkt_rsvd=1 +l2_mem_entries=40960 +l3_mem_entries=40960 + +l2xlrn_thread_interval=50000 +l2xlrn_intr_en=0 + +pbmp_xport_xe=0x1ffffffFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE + +phy_an_c73=3 + +portmap_1.0=1:100:4 +portmap_5.0=9:100:4 +portmap_10.0=17:100:4 +portmap_14.0=25:100:4 + +portmap_20.0=33:100:4 +portmap_24.0=41:100:4 +portmap_29.0=49:100:4 +portmap_33.0=57:100:4 + +portmap_40.0=65:100:4 +portmap_44.0=73:100:4 +portmap_49.0=81:100:4 +portmap_53.0=89:100:4 + +portmap_60.0=97:100:4 +portmap_64.0=105:100:4 +portmap_69.0=113:100:4 +portmap_73.0=121:100:4 + +portmap_80.0=129:100:4 +portmap_84.0=137:100:4 +portmap_89.0=145:100:4 +portmap_93.0=153:100:4 + +portmap_100.0=161:100:4 +portmap_104.0=169:100:4 +portmap_109.0=177:100:4 +portmap_113.0=185:100:4 + +portmap_120.0=193:100:4 +portmap_124.0=201:100:4 +portmap_129.0=209:100:4 +portmap_133.0=217:100:4 + +portmap_140.0=225:100:4 +portmap_144.0=233:100:4 +portmap_149.0=241:100:4 +portmap_153.0=249:100:4 + +portmap_38.0=257:10:1 +portmap_118.0=258:10:1 + +dport_map_port_20=1 +dport_map_port_21=2 +dport_map_port_22=3 +dport_map_port_23=4 +dport_map_port_24=5 +dport_map_port_25=6 +dport_map_port_26=7 +dport_map_port_27=8 +dport_map_port_28=9 +dport_map_port_29=10 +dport_map_port_30=11 +dport_map_port_31=12 +dport_map_port_32=13 +dport_map_port_33=14 +dport_map_port_34=15 +dport_map_port_35=16 +dport_map_port_36=17 +dport_map_port_37=18 +dport_map_port_40=19 +dport_map_port_41=20 +dport_map_port_42=21 +dport_map_port_43=22 +dport_map_port_44=23 +dport_map_port_45=24 +dport_map_port_46=25 +dport_map_port_47=26 +dport_map_port_48=27 +dport_map_port_49=28 +dport_map_port_50=29 +dport_map_port_51=30 +dport_map_port_52=31 +dport_map_port_53=32 +dport_map_port_54=33 +dport_map_port_55=34 +dport_map_port_56=35 +dport_map_port_57=36 +dport_map_port_1=37 +dport_map_port_2=38 +dport_map_port_3=39 +dport_map_port_4=40 +dport_map_port_5=41 +dport_map_port_6=42 +dport_map_port_7=43 +dport_map_port_8=44 +dport_map_port_9=45 +dport_map_port_10=46 +dport_map_port_11=47 +dport_map_port_12=48 +dport_map_port_13=49 +dport_map_port_14=50 +dport_map_port_15=51 +dport_map_port_16=52 +dport_map_port_17=53 +dport_map_port_18=54 +dport_map_port_60=55 +dport_map_port_61=56 +dport_map_port_62=57 +dport_map_port_63=58 +dport_map_port_64=59 +dport_map_port_65=60 +dport_map_port_66=61 +dport_map_port_67=62 +dport_map_port_68=63 +dport_map_port_69=64 +dport_map_port_70=65 +dport_map_port_71=66 +dport_map_port_72=67 +dport_map_port_73=68 +dport_map_port_74=69 +dport_map_port_75=70 +dport_map_port_76=71 +dport_map_port_77=72 +dport_map_port_80=73 +dport_map_port_81=74 +dport_map_port_82=75 +dport_map_port_83=76 +dport_map_port_84=77 +dport_map_port_85=78 +dport_map_port_86=79 +dport_map_port_87=80 +dport_map_port_88=81 +dport_map_port_89=82 +dport_map_port_90=83 +dport_map_port_91=84 +dport_map_port_92=85 +dport_map_port_93=86 +dport_map_port_94=87 +dport_map_port_95=88 +dport_map_port_96=89 +dport_map_port_97=90 +dport_map_port_140=91 +dport_map_port_141=92 +dport_map_port_142=93 +dport_map_port_143=94 +dport_map_port_144=95 +dport_map_port_145=96 +dport_map_port_146=97 +dport_map_port_147=98 +dport_map_port_148=99 +dport_map_port_149=100 +dport_map_port_150=101 +dport_map_port_151=102 +dport_map_port_152=103 +dport_map_port_153=104 +dport_map_port_154=105 +dport_map_port_155=106 +dport_map_port_156=107 +dport_map_port_157=108 +dport_map_port_100=109 +dport_map_port_101=110 +dport_map_port_102=111 +dport_map_port_103=112 +dport_map_port_104=113 +dport_map_port_105=114 +dport_map_port_106=115 +dport_map_port_107=116 +dport_map_port_108=117 +dport_map_port_109=118 +dport_map_port_110=119 +dport_map_port_111=120 +dport_map_port_112=121 +dport_map_port_113=122 +dport_map_port_114=123 +dport_map_port_115=124 +dport_map_port_116=125 +dport_map_port_117=126 +dport_map_port_120=127 +dport_map_port_121=128 +dport_map_port_122=129 +dport_map_port_123=130 +dport_map_port_124=131 +dport_map_port_125=132 +dport_map_port_126=133 +dport_map_port_127=134 +dport_map_port_128=135 +dport_map_port_129=136 +dport_map_port_130=137 +dport_map_port_131=138 +dport_map_port_132=139 +dport_map_port_133=140 +dport_map_port_134=141 +dport_map_port_135=142 +dport_map_port_136=143 +dport_map_port_137=144 +dport_map_port_38=145 +dport_map_port_118=146 + +phy_chain_rx_lane_map_physical{33.0}=0x65732041 +phy_chain_tx_lane_map_physical{33.0}=0x47206531 +phy_chain_rx_lane_map_physical{41.0}=0x07561243 +phy_chain_tx_lane_map_physical{41.0}=0x36207514 +phy_chain_rx_lane_map_physical{49.0}=0x54632071 +phy_chain_tx_lane_map_physical{49.0}=0x06241735 +phy_chain_rx_lane_map_physical{57.0}=0x07561243 +phy_chain_tx_lane_map_physical{57.0}=0x35207614 +phy_chain_rx_lane_map_physical{65.0}=0x45623170 +phy_chain_tx_lane_map_physical{65.0}=0x51260734 +phy_chain_rx_lane_map_physical{73.0}=0x07561243 +phy_chain_tx_lane_map_physical{73.0}=0x37245610 +phy_chain_rx_lane_map_physical{81.0}=0x45632071 +phy_chain_tx_lane_map_physical{81.0}=0x51260734 +phy_chain_rx_lane_map_physical{89.0}=0x07561243 +phy_chain_tx_lane_map_physical{89.0}=0x26437510 +phy_chain_rx_lane_map_physical{1.0}=0x30176524 +phy_chain_tx_lane_map_physical{1.0}=0x20615374 +phy_chain_rx_lane_map_physical{9.0}=0x37562041 +phy_chain_tx_lane_map_physical{9.0}=0x05176432 +phy_chain_rx_lane_map_physical{17.0}=0x43607251 +phy_chain_tx_lane_map_physical{17.0}=0x70261435 +phy_chain_rx_lane_map_physical{25.0}=0x60347125 +phy_chain_tx_lane_map_physical{25.0}=0x46357120 +phy_chain_rx_lane_map_physical{97.0}=0x47601352 +phy_chain_tx_lane_map_physical{97.0}=0x04265137 +phy_chain_rx_lane_map_physical{105.0}=0x73206415 +phy_chain_tx_lane_map_physical{105.0}=0x26374150 +phy_chain_rx_lane_map_physical{113.0}=0x47632051 +phy_chain_tx_lane_map_physical{113.0}=0x03254617 +phy_chain_rx_lane_map_physical{121.0}=0x63027415 +phy_chain_tx_lane_map_physical{121.0}=0x63721045 +phy_chain_rx_lane_map_physical{129.0}=0x30154627 +phy_chain_tx_lane_map_physical{129.0}=0x04735261 +phy_chain_rx_lane_map_physical{137.0}=0x24753061 +phy_chain_tx_lane_map_physical{137.0}=0x37614520 +phy_chain_rx_lane_map_physical{145.0}=0x47601352 +phy_chain_tx_lane_map_physical{145.0}=0x63274510 +phy_chain_rx_lane_map_physical{153.0}=0x07361524 +phy_chain_tx_lane_map_physical{153.0}=0x36527104 +phy_chain_rx_lane_map_physical{225.0}=0x56410273 +phy_chain_tx_lane_map_physical{225.0}=0x10274635 +phy_chain_rx_lane_map_physical{233.0}=0x15740263 +phy_chain_tx_lane_map_physical{233.0}=0x24351607 +phy_chain_rx_lane_map_physical{241.0}=0x74015263 +phy_chain_tx_lane_map_physical{241.0}=0x04152637 +phy_chain_rx_lane_map_physical{249.0}=0x62037514 +phy_chain_tx_lane_map_physical{249.0}=0x72453160 +phy_chain_rx_lane_map_physical{161.0}=0x46510273 +phy_chain_tx_lane_map_physical{161.0}=0x01653724 +phy_chain_rx_lane_map_physical{169.0}=0x25743160 +phy_chain_tx_lane_map_physical{169.0}=0x07216435 +phy_chain_rx_lane_map_physical{177.0}=0x46510273 +phy_chain_tx_lane_map_physical{177.0}=0x01652734 +phy_chain_rx_lane_map_physical{185.0}=0x25743160 +phy_chain_tx_lane_map_physical{185.0}=0x37016425 +phy_chain_rx_lane_map_physical{193.0}=0x46510372 +phy_chain_tx_lane_map_physical{193.0}=0x06153724 +phy_chain_rx_lane_map_physical{201.0}=0x25743160 +phy_chain_tx_lane_map_physical{201.0}=0x36017524 +phy_chain_rx_lane_map_physical{209.0}=0x47601352 +phy_chain_tx_lane_map_physical{209.0}=0x04152736 +phy_chain_rx_lane_map_physical{217.0}=0x26453170 +phy_chain_tx_lane_map_physical{217.0}=0x36027415 + +serdes_core_rx_polarity_flip_physical{33}=0x29 +serdes_core_tx_polarity_flip_physical{33}=0xfe +serdes_core_rx_polarity_flip_physical{41}=0xb1 +serdes_core_tx_polarity_flip_physical{41}=0xe8 +serdes_core_rx_polarity_flip_physical{49}=0xca +serdes_core_tx_polarity_flip_physical{49}=0xb6 +serdes_core_rx_polarity_flip_physical{57}=0x9b +serdes_core_tx_polarity_flip_physical{57}=0xdc +serdes_core_rx_polarity_flip_physical{65}=0x17 +serdes_core_tx_polarity_flip_physical{65}=0x86 +serdes_core_rx_polarity_flip_physical{73}=0x9b +serdes_core_tx_polarity_flip_physical{73}=0x55 +serdes_core_rx_polarity_flip_physical{81}=0xa +serdes_core_tx_polarity_flip_physical{81}=0x6 +serdes_core_rx_polarity_flip_physical{89}=0x9b +serdes_core_tx_polarity_flip_physical{89}=0x48 +serdes_core_rx_polarity_flip_physical{1}=0xec +serdes_core_tx_polarity_flip_physical{1}=0x56 +serdes_core_rx_polarity_flip_physical{9}=0x13 +serdes_core_tx_polarity_flip_physical{9}=0xa6 +serdes_core_rx_polarity_flip_physical{17}=0x5a +serdes_core_tx_polarity_flip_physical{17}=0xc6 +serdes_core_rx_polarity_flip_physical{25}=0xf +serdes_core_tx_polarity_flip_physical{25}=0x4e +serdes_core_rx_polarity_flip_physical{97}=0x17 +serdes_core_tx_polarity_flip_physical{97}=0x2e +serdes_core_rx_polarity_flip_physical{105}=0xce +serdes_core_tx_polarity_flip_physical{105}=0x7c +serdes_core_rx_polarity_flip_physical{113}=0xa +serdes_core_tx_polarity_flip_physical{113}=0x35 + +serdes_core_rx_polarity_flip_physical{121}=0xb9 +serdes_core_tx_polarity_flip_physical{121}=0xef +serdes_core_rx_polarity_flip_physical{129}=0xe8 +serdes_core_tx_polarity_flip_physical{129}=0xac +serdes_core_rx_polarity_flip_physical{137}=0xcb +serdes_core_tx_polarity_flip_physical{137}=0x9c +serdes_core_rx_polarity_flip_physical{145}=0x17 +serdes_core_tx_polarity_flip_physical{145}=0x32 +serdes_core_rx_polarity_flip_physical{153}=0xb9 +serdes_core_tx_polarity_flip_physical{153}=0xaf +serdes_core_rx_polarity_flip_physical{225}=0xaa +serdes_core_tx_polarity_flip_physical{225}=0x7 +serdes_core_rx_polarity_flip_physical{233}=0x31 +serdes_core_tx_polarity_flip_physical{233}=0x47 +serdes_core_rx_polarity_flip_physical{241}=0xe8 +serdes_core_tx_polarity_flip_physical{241}=0x9e +serdes_core_rx_polarity_flip_physical{249}=0xec +serdes_core_tx_polarity_flip_physical{249}=0x1f +serdes_core_rx_polarity_flip_physical{161}=0x6a +serdes_core_tx_polarity_flip_physical{161}=0xd4 +serdes_core_rx_polarity_flip_physical{169}=0x9e +serdes_core_tx_polarity_flip_physical{169}=0x7b +serdes_core_rx_polarity_flip_physical{177}=0x6a +serdes_core_tx_polarity_flip_physical{177}=0xcc +serdes_core_rx_polarity_flip_physical{185}=0x9e +serdes_core_tx_polarity_flip_physical{185}=0x58 +serdes_core_rx_polarity_flip_physical{193}=0x6f +serdes_core_tx_polarity_flip_physical{193}=0x24 +serdes_core_rx_polarity_flip_physical{201}=0x9e +serdes_core_tx_polarity_flip_physical{201}=0xdf +serdes_core_rx_polarity_flip_physical{209}=0x17 +serdes_core_tx_polarity_flip_physical{209}=0xe9 +serdes_core_rx_polarity_flip_physical{217}=0xec +serdes_core_tx_polarity_flip_physical{217}=0x68 + +serdes_lane_config_media_type_49=copper +serdes_lane_config_media_type_50=copper +serdes_lane_config_media_type_51=copper +serdes_lane_config_media_type_52=copper +serdes_lane_config_media_type_54=copper +serdes_lane_config_media_type_55=copper +serdes_lane_config_media_type_56=copper +serdes_lane_config_media_type_57=copper +serdes_lane_config_media_type_53=copper +serdes_lane_config_media_type_60=copper +serdes_lane_config_media_type_61=copper +serdes_lane_config_media_type_62=copper +serdes_lane_config_media_type_63=copper +serdes_lane_config_media_type_65=copper +serdes_lane_config_media_type_66=copper +serdes_lane_config_media_type_67=copper +serdes_lane_config_media_type_68=copper +serdes_lane_config_media_type_64=copper +serdes_lane_config_media_type_80=copper +serdes_lane_config_media_type_81=copper +serdes_lane_config_media_type_82=copper +serdes_lane_config_media_type_83=copper +serdes_lane_config_media_type_85=copper +serdes_lane_config_media_type_86=copper +serdes_lane_config_media_type_87=copper +serdes_lane_config_media_type_88=copper +serdes_lane_config_media_type_84=copper +serdes_lane_config_media_type_100=copper +serdes_lane_config_media_type_101=copper +serdes_lane_config_media_type_102=copper +serdes_lane_config_media_type_103=copper +serdes_lane_config_media_type_105=copper +serdes_lane_config_media_type_106=copper +serdes_lane_config_media_type_107=copper +serdes_lane_config_media_type_108=copper +serdes_lane_config_media_type_104=copper +serdes_lane_config_media_type_120=copper +serdes_lane_config_media_type_121=copper +serdes_lane_config_media_type_122=copper +serdes_lane_config_media_type_123=copper +serdes_lane_config_media_type_125=copper +serdes_lane_config_media_type_126=copper +serdes_lane_config_media_type_127=copper +serdes_lane_config_media_type_128=copper +serdes_lane_config_media_type_124=copper +serdes_lane_config_media_type_140=copper +serdes_lane_config_media_type_141=copper +serdes_lane_config_media_type_142=copper +serdes_lane_config_media_type_143=copper +serdes_lane_config_media_type_145=copper +serdes_lane_config_media_type_146=copper +serdes_lane_config_media_type_147=copper +serdes_lane_config_media_type_148=copper +serdes_lane_config_media_type_144=copper +serdes_lane_config_media_type_40=copper +serdes_lane_config_media_type_41=copper +serdes_lane_config_media_type_42=copper +serdes_lane_config_media_type_43=copper +serdes_lane_config_media_type_45=copper +serdes_lane_config_media_type_46=copper +serdes_lane_config_media_type_47=copper +serdes_lane_config_media_type_48=copper +serdes_lane_config_media_type_44=copper +serdes_lane_config_media_type_69=copper +serdes_lane_config_media_type_70=copper +serdes_lane_config_media_type_71=copper +serdes_lane_config_media_type_72=copper +serdes_lane_config_media_type_74=copper +serdes_lane_config_media_type_75=copper +serdes_lane_config_media_type_76=copper +serdes_lane_config_media_type_77=copper +serdes_lane_config_media_type_73=copper +serdes_lane_config_media_type_1=copper +serdes_lane_config_media_type_2=copper +serdes_lane_config_media_type_3=copper +serdes_lane_config_media_type_4=copper +serdes_lane_config_media_type_6=copper +serdes_lane_config_media_type_7=copper +serdes_lane_config_media_type_8=copper +serdes_lane_config_media_type_9=copper +serdes_lane_config_media_type_5=copper +serdes_lane_config_media_type_29=copper +serdes_lane_config_media_type_30=copper +serdes_lane_config_media_type_31=copper +serdes_lane_config_media_type_32=copper +serdes_lane_config_media_type_34=copper +serdes_lane_config_media_type_35=copper +serdes_lane_config_media_type_36=copper +serdes_lane_config_media_type_37=copper +serdes_lane_config_media_type_33=copper +serdes_lane_config_media_type_89=copper +serdes_lane_config_media_type_90=copper +serdes_lane_config_media_type_91=copper +serdes_lane_config_media_type_92=copper +serdes_lane_config_media_type_94=copper +serdes_lane_config_media_type_95=copper +serdes_lane_config_media_type_96=copper +serdes_lane_config_media_type_97=copper +serdes_lane_config_media_type_93=copper +serdes_lane_config_media_type_109=copper +serdes_lane_config_media_type_110=copper +serdes_lane_config_media_type_111=copper +serdes_lane_config_media_type_112=copper +serdes_lane_config_media_type_114=copper +serdes_lane_config_media_type_115=copper +serdes_lane_config_media_type_116=copper +serdes_lane_config_media_type_117=copper +serdes_lane_config_media_type_113=copper +serdes_lane_config_media_type_129=copper +serdes_lane_config_media_type_130=copper +serdes_lane_config_media_type_131=copper +serdes_lane_config_media_type_132=copper +serdes_lane_config_media_type_134=copper +serdes_lane_config_media_type_135=copper +serdes_lane_config_media_type_136=copper +serdes_lane_config_media_type_137=copper +serdes_lane_config_media_type_133=copper +serdes_lane_config_media_type_149=copper +serdes_lane_config_media_type_150=copper +serdes_lane_config_media_type_151=copper +serdes_lane_config_media_type_152=copper +serdes_lane_config_media_type_154=copper +serdes_lane_config_media_type_155=copper +serdes_lane_config_media_type_156=copper +serdes_lane_config_media_type_157=copper +serdes_lane_config_media_type_153=copper +serdes_lane_config_media_type_10=copper +serdes_lane_config_media_type_11=copper +serdes_lane_config_media_type_12=copper +serdes_lane_config_media_type_13=copper +serdes_lane_config_media_type_15=copper +serdes_lane_config_media_type_16=copper +serdes_lane_config_media_type_17=copper +serdes_lane_config_media_type_18=copper +serdes_lane_config_media_type_14=copper +serdes_lane_config_media_type_20=copper +serdes_lane_config_media_type_21=copper +serdes_lane_config_media_type_22=copper +serdes_lane_config_media_type_23=copper +serdes_lane_config_media_type_25=copper +serdes_lane_config_media_type_26=copper +serdes_lane_config_media_type_27=copper +serdes_lane_config_media_type_28=copper +serdes_lane_config_media_type_24=copper + +#sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc +sai_postinit_cmd_file=/usr/share/sonic/hwsku/sai_postinit_cmd.soc + diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/buffers.json.j2 b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/buffers.json.j2 new file mode 100644 index 000000000000..0b1cb2c541b6 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..77747f6403c8 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/buffers_defaults_t0.j2 @@ -0,0 +1,20 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + }, + "BUFFER_PROFILE": { + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names_active) %} + "BUFFER_PG": { + }, +{%- endmacro %} + +{% macro generate_queue_buffers(port_names_active) %} + "BUFFER_QUEUE": { + } +{% endmacro %} + diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..77747f6403c8 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/buffers_defaults_t1.j2 @@ -0,0 +1,20 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + }, + "BUFFER_PROFILE": { + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names_active) %} + "BUFFER_PG": { + }, +{%- endmacro %} + +{% macro generate_queue_buffers(port_names_active) %} + "BUFFER_QUEUE": { + } +{% endmacro %} + diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/custom_led.bin b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/custom_led.bin new file mode 100755 index 000000000000..3ee9545e28ae Binary files /dev/null and b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/custom_led.bin differ diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/linkscan_led_fw.bin b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/linkscan_led_fw.bin new file mode 100755 index 000000000000..c2fa94a2d8cb Binary files /dev/null and b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/linkscan_led_fw.bin differ diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/pg_profile_lookup.ini b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/pg_profile_lookup.ini new file mode 100644 index 000000000000..a5f3286beef8 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/pg_profile_lookup.ini @@ -0,0 +1,23 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 1270 0 190500 -2 2540 + 25000 5m 1270 0 190500 -2 2540 + 40000 5m 1270 0 190500 -2 2540 + 50000 5m 1270 0 190500 -2 2540 + 100000 5m 1270 0 190500 -2 2540 + 200000 5m 1270 0 190500 -2 2540 + 400000 5m 1270 0 190500 -2 2540 + 10000 40m 1270 0 190500 -2 2540 + 25000 40m 1270 0 190500 -2 2540 + 40000 40m 1270 0 190500 -2 2540 + 50000 40m 1270 0 190500 -2 2540 + 100000 40m 1270 0 190500 -2 2540 + 200000 40m 1270 0 190500 -2 2540 + 400000 40m 1270 0 190500 -2 2540 + 10000 300m 1270 0 190500 -2 2540 + 25000 300m 1270 0 190500 -2 2540 + 40000 300m 1270 0 190500 -2 2540 + 50000 300m 1270 0 190500 -2 2540 + 100000 300m 1270 0 190500 -2 2540 + 200000 300m 1270 0 190500 -2 2540 + 400000 300m 1270 0 190500 -2 2540 diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/port_config.ini b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/port_config.ini new file mode 100644 index 000000000000..542992d761a6 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/port_config.ini @@ -0,0 +1,83 @@ +# name lanes alias index speed +Ethernet0 33,34 hundredGigE1/1/1 1 100000 +Ethernet2 35,36 hundredGigE1/1/2 1 100000 +Ethernet4 37,38 hundredGigE1/1/3 1 100000 +Ethernet6 39,40 hundredGigE1/1/4 1 100000 +Ethernet8 41,42 hundredGigE1/2/1 2 100000 +Ethernet10 43,44 hundredGigE1/2/2 2 100000 +Ethernet12 45,46 hundredGigE1/2/3 2 100000 +Ethernet14 47,48 hundredGigE1/2/4 2 100000 +Ethernet16 49,50 hundredGigE1/3/1 3 100000 +Ethernet18 51,52 hundredGigE1/3/2 3 100000 +Ethernet20 53,54 hundredGigE1/3/3 3 100000 +Ethernet22 55,56 hundredGigE1/3/4 3 100000 +Ethernet24 57,58 hundredGigE1/4/1 4 100000 +Ethernet26 59,60 hundredGigE1/4/2 4 100000 +Ethernet28 61,62 hundredGigE1/4/3 4 100000 +Ethernet30 63,64 hundredGigE1/4/4 4 100000 +Ethernet32 65,66,67,68,69,70,71,72 fourhundredGigE1/5 5 400000 +Ethernet40 73,74,75,76,77,78,79,80 fourhundredGigE1/6 6 400000 +Ethernet48 81,82,83,84,85,86,87,88 fourhundredGigE1/7 7 400000 +Ethernet56 89,90,91,92,93,94,95,96 fourhundredGigE1/8 8 400000 +Ethernet64 1,2 hundredGigE1/9/1 9 100000 +Ethernet66 3,4 hundredGigE1/9/2 9 100000 +Ethernet68 5,6 hundredGigE1/9/3 9 100000 +Ethernet70 7,8 hundredGigE1/9/4 9 100000 +Ethernet72 9,10 hundredGigE1/10/1 10 100000 +Ethernet74 11,12 hundredGigE1/10/2 10 100000 +Ethernet76 13,14 hundredGigE1/10/3 10 100000 +Ethernet78 15,16 hundredGigE1/10/4 10 100000 +Ethernet80 17,18 hundredGigE1/11/1 11 100000 +Ethernet82 19,20 hundredGigE1/11/2 11 100000 +Ethernet84 21,22 hundredGigE1/11/3 11 100000 +Ethernet86 23,24 hundredGigE1/11/4 11 100000 +Ethernet88 25,26 hundredGigE1/12/1 12 100000 +Ethernet90 27,28 hundredGigE1/12/2 12 100000 +Ethernet92 29,30 hundredGigE1/12/3 12 100000 +Ethernet94 31,32 hundredGigE1/12/4 12 100000 +Ethernet96 97,98,99,100,101,102,103,104 fourhundredGigE1/13 13 400000 +Ethernet104 105,106,107,108,109,110,111,112 fourhundredGigE1/14 14 400000 +Ethernet112 113,114,115,116,117,118,119,120 fourhundredGigE1/15 15 400000 +Ethernet120 121,122,123,124,125,126,127,128 fourhundredGigE1/16 16 400000 +Ethernet128 129,130,131,132,133,134,135,136 fourhundredGigE1/17 17 400000 +Ethernet136 137,138,139,140,141,142,143,144 fourhundredGigE1/18 18 400000 +Ethernet144 145,146,147,148,149,150,151,152 fourhundredGigE1/19 19 400000 +Ethernet152 153,154,155,156,157,158,159,160 fourhundredGigE1/20 20 400000 +Ethernet160 225,226 hundredGigE1/21/1 21 100000 +Ethernet162 227,228 hundredGigE1/21/2 21 100000 +Ethernet164 229,230 hundredGigE1/21/3 21 100000 +Ethernet166 231,232 hundredGigE1/21/4 21 100000 +Ethernet168 233,234 hundredGigE1/22/1 22 100000 +Ethernet170 235,236 hundredGigE1/22/2 22 100000 +Ethernet172 237,238 hundredGigE1/22/3 22 100000 +Ethernet174 239,240 hundredGigE1/22/4 22 100000 +Ethernet176 241,242 hundredGigE1/23/1 23 100000 +Ethernet178 243,244 hundredGigE1/23/2 23 100000 +Ethernet180 245,246 hundredGigE1/23/3 23 100000 +Ethernet182 247,248 hundredGigE1/23/4 23 100000 +Ethernet184 249,250 hundredGigE1/24/1 24 100000 +Ethernet186 251,252 hundredGigE1/24/2 24 100000 +Ethernet188 253,254 hundredGigE1/24/3 24 100000 +Ethernet190 255,256 hundredGigE1/24/4 24 100000 +Ethernet192 161,162,163,164,165,166,167,168 fourhundredGigE1/25 25 400000 +Ethernet200 169,170,171,172,173,174,175,176 fourhundredGigE1/26 26 400000 +Ethernet208 177,178,179,180,181,182,183,184 fourhundredGigE1/27 27 400000 +Ethernet216 185,186,187,188,189,190,191,192 fourhundredGigE1/28 28 400000 +Ethernet224 193,194 hundredGigE1/29/1 29 100000 +Ethernet226 195,196 hundredGigE1/29/2 29 100000 +Ethernet228 197,198 hundredGigE1/29/3 29 100000 +Ethernet230 199,200 hundredGigE1/29/4 29 100000 +Ethernet232 201,202 hundredGigE1/30/1 30 100000 +Ethernet234 203,204 hundredGigE1/30/2 30 100000 +Ethernet236 205,206 hundredGigE1/30/3 30 100000 +Ethernet238 207,208 hundredGigE1/30/4 30 100000 +Ethernet240 209,210 hundredGigE1/31/1 31 100000 +Ethernet242 211,212 hundredGigE1/31/2 31 100000 +Ethernet244 213,214 hundredGigE1/31/3 31 100000 +Ethernet246 215,216 hundredGigE1/31/4 31 100000 +Ethernet248 217,218 hundredGigE1/32/1 32 100000 +Ethernet250 219,220 hundredGigE1/32/2 32 100000 +Ethernet252 221,222 hundredGigE1/32/3 32 100000 +Ethernet254 223,224 hundredGigE1/32/4 32 100000 +Ethernet256 257 tenGigE1/33 33 10000 +Ethernet257 258 tenGigE1/34 34 10000 diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/qos.json.j2 b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/qos.json.j2 new file mode 100644 index 000000000000..a48e1b56621c --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/qos.json.j2 @@ -0,0 +1,226 @@ +{%- set PORT_ALL = [] %} +{%- for port in PORT %} + {%- if PORT_ALL.append(port) %}{% endif %} +{%- endfor %} +{%- if PORT_ALL | sort_by_port_index %}{% endif %} + +{%- set port_names_list_all = [] %} +{%- for port in PORT_ALL %} + {%- if port_names_list_all.append(port) %}{% endif %} +{%- endfor %} +{%- set port_names_all = port_names_list_all | join(',') -%} + + +{%- set PORT_ACTIVE = [] %} +{%- if DEVICE_NEIGHBOR is not defined %} + {%- set PORT_ACTIVE = PORT_ALL %} +{%- else %} + {%- for port in DEVICE_NEIGHBOR.keys() %} + {%- if PORT_ACTIVE.append(port) %}{%- endif %} + {%- endfor %} +{%- endif %} +{%- if PORT_ACTIVE | sort_by_port_index %}{% endif %} + +{%- set port_names_list_active = [] %} +{%- for port in PORT_ACTIVE %} + {%- if port_names_list_active.append(port) %}{%- endif %} +{%- endfor %} +{%- set port_names_active = port_names_list_active | join(',') -%} + + +{%- set pfc_to_pg_map_supported_asics = ['mellanox', 'barefoot', 'marvell'] -%} + + +{ +{% if generate_tc_to_pg_map is defined %} + {{- generate_tc_to_pg_map() }} +{% else %} + "TC_TO_PRIORITY_GROUP_MAP": { + "DEFAULT": { + "0": "0", + "1": "0", + "2": "0", + "3": "3", + "4": "4", + "5": "0", + "6": "0", + "7": "7" + } + }, +{% endif %} + "MAP_PFC_PRIORITY_TO_QUEUE": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "DEFAULT": { + "0" : "0", + "1" : "0", + "2" : "0", + "3" : "0", + "4" : "0", + "5" : "0", + "6" : "0", + "7" : "0", + "8" : "0", + "9" : "0", + "10": "0", + "11": "0", + "12": "0", + "13": "0", + "14": "0", + "15": "0", + "16": "0", + "17": "0", + "18": "0", + "19": "0", + "20": "0", + "21": "0", + "22": "0", + "23": "0", + "24": "0", + "25": "0", + "26": "0", + "27": "0", + "28": "0", + "29": "0", + "30": "0", + "31": "0", + "32": "0", + "33": "0", + "34": "0", + "35": "0", + "36": "0", + "37": "0", + "38": "0", + "39": "0", + "40": "0", + "41": "0", + "42": "0", + "43": "0", + "44": "0", + "45": "0", + "46": "0", + "47": "0", + "48": "0", + "49": "0", + "50": "0", + "51": "0", + "52": "0", + "53": "0", + "54": "0", + "55": "0", + "56": "0", + "57": "0", + "58": "0", + "59": "0", + "60": "0", + "61": "0", + "62": "0", + "63": "0" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type" : "DWRR", + "weight": "1" + }, + "scheduler.1": { + "type" : "DWRR", + "weight": "2" + }, + "scheduler.2": { + "type" : "DWRR", + "weight": "3" + }, + "scheduler.3": { + "type" : "DWRR", + "weight": "4" + }, + "scheduler.4": { + "type" : "DWRR", + "weight": "5" + }, + "scheduler.5": { + "type" : "DWRR", + "weight": "10" + }, + "scheduler.6": { + "type" : "DWRR", + "weight": "25" + }, + "scheduler.7": { + "type" : "STRICT" + } + }, + "PORT_QOS_MAP": { + "{{ port_names_active }}": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|DEFAULT]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|DEFAULT]", + "pfc_enable" : "3,4", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|DEFAULT]" + } + }, + "QUEUE": { +{% for port in PORT_ACTIVE %} + "{{ port }}|0": { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|1": { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|2": { + "scheduler": "[SCHEDULER|scheduler.2]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|3": { + "scheduler": "[SCHEDULER|scheduler.3]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|4": { + "scheduler": "[SCHEDULER|scheduler.4]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|5": { + "scheduler": "[SCHEDULER|scheduler.5]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|6": { + "scheduler": "[SCHEDULER|scheduler.6]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|7": { + "scheduler": "[SCHEDULER|scheduler.7]" + }{% if not loop.last %},{% endif %} +{% endfor %} + } +} diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/sai.profile b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/sai.profile new file mode 100644 index 000000000000..26867a291b00 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-z9332f-32x400G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/sai_postinit_cmd.soc b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/sai_postinit_cmd.soc new file mode 100644 index 000000000000..9550e9c822c8 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/sai_postinit_cmd.soc @@ -0,0 +1,2530 @@ +delay 200 +link off +counter off + +#*** +#*** Port CD0 Preemphasis setting *** +#*** + +local port cd0 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD1 Preemphasis setting *** +#*** + +local port cd1 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD2 Preemphasis setting *** +#*** + +local port cd2 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD3 Preemphasis setting *** +#*** + +local port cd3 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD4 Preemphasis setting *** +#*** + +local port cd4 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD5 Preemphasis setting *** +#*** + +local port cd5 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD6 Preemphasis setting *** +#*** + +local port cd6 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD7 Preemphasis setting *** +#*** + +local port cd7 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD8 Preemphasis setting *** +#*** + +local port cd8 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD9 Preemphasis setting *** +#*** + +local port cd9 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD10 Preemphasis setting *** +#*** + +local port cd10 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x78 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1EC +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD11 Preemphasis setting *** +#*** + +local port cd11 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD12 Preemphasis setting *** +#*** + +local port cd12 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD13 Preemphasis setting *** +#*** + +local port cd13 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD14 Preemphasis setting *** +#*** + +local port cd14 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD15 Preemphasis setting *** +#*** + +local port cd15 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD16 Preemphasis setting *** +#*** + +local port cd16 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD17 Preemphasis setting *** +#*** + +local port cd17 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD18 Preemphasis setting *** +#*** + +local port cd18 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD19 Preemphasis setting *** +#*** + +local port cd19 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD20 Preemphasis setting *** +#*** + +local port cd20 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD21 Preemphasis setting *** +#*** + +local port cd21 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD22 Preemphasis setting *** +#*** + +local port cd22 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD23 Preemphasis setting *** +#*** + +local port cd23 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD24 Preemphasis setting *** +#*** + +local port cd24 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD25 Preemphasis setting *** +#*** + +local port cd25 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD26 Preemphasis setting *** +#*** + +local port cd26 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD27 Preemphasis setting *** +#*** + +local port cd27 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD28 Preemphasis setting *** +#*** + +local port cd28 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD29 Preemphasis setting *** +#*** + +local port cd29 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD30 Preemphasis setting *** +#*** + +local port cd30 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD31 Preemphasis setting *** +#*** + +local port cd31 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +link on +counter on diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/sai_preinit_cmd.soc b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/sai_preinit_cmd.soc new file mode 100644 index 000000000000..e48c05b9f664 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/sai_preinit_cmd.soc @@ -0,0 +1,3 @@ +#Not supported Until SAI 3.6 +#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_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/th3-z9332f-32x400G.config.bcm b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/th3-z9332f-32x400G.config.bcm new file mode 100644 index 000000000000..fc6613601f52 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/th3-z9332f-32x400G.config.bcm @@ -0,0 +1,519 @@ +core_clock_frequency=1325 +dpr_clock_frequency=1000 +device_clock_frequency=1325 +port_flex_enable=1 + +#firmware load method, use fast load +load_firmware=0x2 + +ccm_dma_enable=0 +ccmdma_intr_enable=0 +mem_cache_enable=1 +phy_enable=0 +phy_null=1 + +dport_map_enable=1 + +module_64ports.0=0 +tdma_intr_enable.0=1 +ipv6_lpm_128b_enable.0=1 +stat_if_parity_enable.0=1 +oversubscribe_mode=0 +bcm_tunnel_term_compatible_mode.0=1 +table_dma_enable.0=1 +schan_intr_enable.0=0 +parity_enable.0=1 +tdma_timeout_usec=1000000 +lls_num_l2uc.0=10 +miim_intr_enable.0=0 +table_dma_enable=1 +max_vp_lags.0=0 +tdma_intr_enable=1 +tdma_timeout_usec.0=5000000 +parity_correction.0=1 +mmu_lossless.0=0 +bcm_num_cos=10 +default_cpu_tx_queue=7 +pktdma_poll_mode_channel_bitmap=1 +l3_max_ecmp_mode.0=1 +l3_alpm_enable=2 +l3_alpm_ipv6_128b_bkt_rsvd=1 +l2_mem_entries=40960 +l3_mem_entries=40960 + +l2xlrn_thread_interval=50000 +l2xlrn_intr_en=0 + +pbmp_xport_xe=0xffffffFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE + +phy_an_c73=3 + +portmap_1.0=1:400 +portmap_5.0=9:400 +portmap_10.0=17:400 +portmap_14.0=25:400 + +portmap_20.0=33:400 +portmap_24.0=41:400 +portmap_29.0=49:400 +portmap_33.0=57:400 + +portmap_40.0=65:400 +portmap_44.0=73:400 +portmap_49.0=81:400 +portmap_53.0=89:400 + +portmap_60.0=97:400 +portmap_64.0=105:400 +portmap_69.0=113:400 +portmap_73.0=121:400 + +portmap_80.0=129:400 +portmap_84.0=137:400 +portmap_89.0=145:400 +portmap_93.0=153:400 + +portmap_100.0=161:400 +portmap_104.0=169:400 +portmap_109.0=177:400 +portmap_113.0=185:400 + +portmap_120.0=193:400 +portmap_124.0=201:400 +portmap_129.0=209:400 +portmap_133.0=217:400 + +portmap_140.0=225:400 +portmap_144.0=233:400 +portmap_149.0=241:400 +portmap_153.0=249:400 + +portmap_38.0=257:10:1 +portmap_118.0=258:10:1 + +dport_map_port_20=1 +dport_map_port_21=2 +dport_map_port_22=3 +dport_map_port_23=4 +dport_map_port_24=5 +dport_map_port_25=6 +dport_map_port_26=7 +dport_map_port_27=8 +dport_map_port_28=9 +dport_map_port_29=10 +dport_map_port_30=11 +dport_map_port_31=12 +dport_map_port_32=13 +dport_map_port_33=14 +dport_map_port_34=15 +dport_map_port_35=16 +dport_map_port_36=17 +dport_map_port_37=18 +dport_map_port_40=19 +dport_map_port_41=20 +dport_map_port_42=21 +dport_map_port_43=22 +dport_map_port_44=23 +dport_map_port_45=24 +dport_map_port_46=25 +dport_map_port_47=26 +dport_map_port_48=27 +dport_map_port_49=28 +dport_map_port_50=29 +dport_map_port_51=30 +dport_map_port_52=31 +dport_map_port_53=32 +dport_map_port_54=33 +dport_map_port_55=34 +dport_map_port_56=35 +dport_map_port_57=36 +dport_map_port_1=37 +dport_map_port_2=38 +dport_map_port_3=39 +dport_map_port_4=40 +dport_map_port_5=41 +dport_map_port_6=42 +dport_map_port_7=43 +dport_map_port_8=44 +dport_map_port_9=45 +dport_map_port_10=46 +dport_map_port_11=47 +dport_map_port_12=48 +dport_map_port_13=49 +dport_map_port_14=50 +dport_map_port_15=51 +dport_map_port_16=52 +dport_map_port_17=53 +dport_map_port_18=54 +dport_map_port_60=55 +dport_map_port_61=56 +dport_map_port_62=57 +dport_map_port_63=58 +dport_map_port_64=59 +dport_map_port_65=60 +dport_map_port_66=61 +dport_map_port_67=62 +dport_map_port_68=63 +dport_map_port_69=64 +dport_map_port_70=65 +dport_map_port_71=66 +dport_map_port_72=67 +dport_map_port_73=68 +dport_map_port_74=69 +dport_map_port_75=70 +dport_map_port_76=71 +dport_map_port_77=72 +dport_map_port_80=73 +dport_map_port_81=74 +dport_map_port_82=75 +dport_map_port_83=76 +dport_map_port_84=77 +dport_map_port_85=78 +dport_map_port_86=79 +dport_map_port_87=80 +dport_map_port_88=81 +dport_map_port_89=82 +dport_map_port_90=83 +dport_map_port_91=84 +dport_map_port_92=85 +dport_map_port_93=86 +dport_map_port_94=87 +dport_map_port_95=88 +dport_map_port_96=89 +dport_map_port_97=90 +dport_map_port_140=91 +dport_map_port_141=92 +dport_map_port_142=93 +dport_map_port_143=94 +dport_map_port_144=95 +dport_map_port_145=96 +dport_map_port_146=97 +dport_map_port_147=98 +dport_map_port_148=99 +dport_map_port_149=100 +dport_map_port_150=101 +dport_map_port_151=102 +dport_map_port_152=103 +dport_map_port_153=104 +dport_map_port_154=105 +dport_map_port_155=106 +dport_map_port_156=107 +dport_map_port_157=108 +dport_map_port_100=109 +dport_map_port_101=110 +dport_map_port_102=111 +dport_map_port_103=112 +dport_map_port_104=113 +dport_map_port_105=114 +dport_map_port_106=115 +dport_map_port_107=116 +dport_map_port_108=117 +dport_map_port_109=118 +dport_map_port_110=119 +dport_map_port_111=120 +dport_map_port_112=121 +dport_map_port_113=122 +dport_map_port_114=123 +dport_map_port_115=124 +dport_map_port_116=125 +dport_map_port_117=126 +dport_map_port_120=127 +dport_map_port_121=128 +dport_map_port_122=129 +dport_map_port_123=130 +dport_map_port_124=131 +dport_map_port_125=132 +dport_map_port_126=133 +dport_map_port_127=134 +dport_map_port_128=135 +dport_map_port_129=136 +dport_map_port_130=137 +dport_map_port_131=138 +dport_map_port_132=139 +dport_map_port_133=140 +dport_map_port_134=141 +dport_map_port_135=142 +dport_map_port_136=143 +dport_map_port_137=144 +dport_map_port_38=145 +dport_map_port_118=146 + +phy_chain_rx_lane_map_physical{33.0}=0x65732041 +phy_chain_tx_lane_map_physical{33.0}=0x47206531 +phy_chain_rx_lane_map_physical{41.0}=0x07561243 +phy_chain_tx_lane_map_physical{41.0}=0x36207514 +phy_chain_rx_lane_map_physical{49.0}=0x54632071 +phy_chain_tx_lane_map_physical{49.0}=0x06241735 +phy_chain_rx_lane_map_physical{57.0}=0x07561243 +phy_chain_tx_lane_map_physical{57.0}=0x35207614 +phy_chain_rx_lane_map_physical{65.0}=0x45623170 +phy_chain_tx_lane_map_physical{65.0}=0x51260734 +phy_chain_rx_lane_map_physical{73.0}=0x07561243 +phy_chain_tx_lane_map_physical{73.0}=0x37245610 +phy_chain_rx_lane_map_physical{81.0}=0x45632071 +phy_chain_tx_lane_map_physical{81.0}=0x51260734 +phy_chain_rx_lane_map_physical{89.0}=0x07561243 +phy_chain_tx_lane_map_physical{89.0}=0x26437510 +phy_chain_rx_lane_map_physical{1.0}=0x30176524 +phy_chain_tx_lane_map_physical{1.0}=0x20615374 +phy_chain_rx_lane_map_physical{9.0}=0x37562041 +phy_chain_tx_lane_map_physical{9.0}=0x05176432 +phy_chain_rx_lane_map_physical{17.0}=0x43607251 +phy_chain_tx_lane_map_physical{17.0}=0x70261435 +phy_chain_rx_lane_map_physical{25.0}=0x60347125 +phy_chain_tx_lane_map_physical{25.0}=0x46357120 +phy_chain_rx_lane_map_physical{97.0}=0x47601352 +phy_chain_tx_lane_map_physical{97.0}=0x04265137 +phy_chain_rx_lane_map_physical{105.0}=0x73206415 +phy_chain_tx_lane_map_physical{105.0}=0x26374150 +phy_chain_rx_lane_map_physical{113.0}=0x47632051 +phy_chain_tx_lane_map_physical{113.0}=0x03254617 +phy_chain_rx_lane_map_physical{121.0}=0x63027415 +phy_chain_tx_lane_map_physical{121.0}=0x63721045 +phy_chain_rx_lane_map_physical{129.0}=0x30154627 +phy_chain_tx_lane_map_physical{129.0}=0x04735261 +phy_chain_rx_lane_map_physical{137.0}=0x24753061 +phy_chain_tx_lane_map_physical{137.0}=0x37614520 +phy_chain_rx_lane_map_physical{145.0}=0x47601352 +phy_chain_tx_lane_map_physical{145.0}=0x63274510 +phy_chain_rx_lane_map_physical{153.0}=0x07361524 +phy_chain_tx_lane_map_physical{153.0}=0x36527104 +phy_chain_rx_lane_map_physical{225.0}=0x56410273 +phy_chain_tx_lane_map_physical{225.0}=0x10274635 +phy_chain_rx_lane_map_physical{233.0}=0x15740263 +phy_chain_tx_lane_map_physical{233.0}=0x24351607 +phy_chain_rx_lane_map_physical{241.0}=0x74015263 +phy_chain_tx_lane_map_physical{241.0}=0x04152637 +phy_chain_rx_lane_map_physical{249.0}=0x62037514 +phy_chain_tx_lane_map_physical{249.0}=0x72453160 +phy_chain_rx_lane_map_physical{161.0}=0x46510273 +phy_chain_tx_lane_map_physical{161.0}=0x01653724 +phy_chain_rx_lane_map_physical{169.0}=0x25743160 +phy_chain_tx_lane_map_physical{169.0}=0x07216435 +phy_chain_rx_lane_map_physical{177.0}=0x46510273 +phy_chain_tx_lane_map_physical{177.0}=0x01652734 +phy_chain_rx_lane_map_physical{185.0}=0x25743160 +phy_chain_tx_lane_map_physical{185.0}=0x37016425 +phy_chain_rx_lane_map_physical{193.0}=0x46510372 +phy_chain_tx_lane_map_physical{193.0}=0x06153724 +phy_chain_rx_lane_map_physical{201.0}=0x25743160 +phy_chain_tx_lane_map_physical{201.0}=0x36017524 +phy_chain_rx_lane_map_physical{209.0}=0x47601352 +phy_chain_tx_lane_map_physical{209.0}=0x04152736 +phy_chain_rx_lane_map_physical{217.0}=0x26453170 +phy_chain_tx_lane_map_physical{217.0}=0x36027415 + +serdes_core_rx_polarity_flip_physical{33}=0x29 +serdes_core_tx_polarity_flip_physical{33}=0xfe +serdes_core_rx_polarity_flip_physical{41}=0xb1 +serdes_core_tx_polarity_flip_physical{41}=0xe8 +serdes_core_rx_polarity_flip_physical{49}=0xca +serdes_core_tx_polarity_flip_physical{49}=0xb6 +serdes_core_rx_polarity_flip_physical{57}=0x9b +serdes_core_tx_polarity_flip_physical{57}=0xdc +serdes_core_rx_polarity_flip_physical{65}=0x17 +serdes_core_tx_polarity_flip_physical{65}=0x86 +serdes_core_rx_polarity_flip_physical{73}=0x9b +serdes_core_tx_polarity_flip_physical{73}=0x55 +serdes_core_rx_polarity_flip_physical{81}=0xa +serdes_core_tx_polarity_flip_physical{81}=0x6 +serdes_core_rx_polarity_flip_physical{89}=0x9b +serdes_core_tx_polarity_flip_physical{89}=0x48 +serdes_core_rx_polarity_flip_physical{1}=0xec +serdes_core_tx_polarity_flip_physical{1}=0x56 +serdes_core_rx_polarity_flip_physical{9}=0x13 +serdes_core_tx_polarity_flip_physical{9}=0xa6 +serdes_core_rx_polarity_flip_physical{17}=0x5a +serdes_core_tx_polarity_flip_physical{17}=0xc6 +serdes_core_rx_polarity_flip_physical{25}=0xf +serdes_core_tx_polarity_flip_physical{25}=0x4e +serdes_core_rx_polarity_flip_physical{97}=0x17 +serdes_core_tx_polarity_flip_physical{97}=0x2e +serdes_core_rx_polarity_flip_physical{105}=0xce +serdes_core_tx_polarity_flip_physical{105}=0x7c +serdes_core_rx_polarity_flip_physical{113}=0xa +serdes_core_tx_polarity_flip_physical{113}=0x35 + +serdes_core_rx_polarity_flip_physical{121}=0xb9 +serdes_core_tx_polarity_flip_physical{121}=0xef +serdes_core_rx_polarity_flip_physical{129}=0xe8 +serdes_core_tx_polarity_flip_physical{129}=0xac +serdes_core_rx_polarity_flip_physical{137}=0xcb +serdes_core_tx_polarity_flip_physical{137}=0x9c +serdes_core_rx_polarity_flip_physical{145}=0x17 +serdes_core_tx_polarity_flip_physical{145}=0x32 +serdes_core_rx_polarity_flip_physical{153}=0xb9 +serdes_core_tx_polarity_flip_physical{153}=0xaf +serdes_core_rx_polarity_flip_physical{225}=0xaa +serdes_core_tx_polarity_flip_physical{225}=0x7 +serdes_core_rx_polarity_flip_physical{233}=0x31 +serdes_core_tx_polarity_flip_physical{233}=0x47 +serdes_core_rx_polarity_flip_physical{241}=0xe8 +serdes_core_tx_polarity_flip_physical{241}=0x9e +serdes_core_rx_polarity_flip_physical{249}=0xec +serdes_core_tx_polarity_flip_physical{249}=0x1f +serdes_core_rx_polarity_flip_physical{161}=0x6a +serdes_core_tx_polarity_flip_physical{161}=0xd4 +serdes_core_rx_polarity_flip_physical{169}=0x9e +serdes_core_tx_polarity_flip_physical{169}=0x7b +serdes_core_rx_polarity_flip_physical{177}=0x6a +serdes_core_tx_polarity_flip_physical{177}=0xcc +serdes_core_rx_polarity_flip_physical{185}=0x9e +serdes_core_tx_polarity_flip_physical{185}=0x58 +serdes_core_rx_polarity_flip_physical{193}=0x6f +serdes_core_tx_polarity_flip_physical{193}=0x24 +serdes_core_rx_polarity_flip_physical{201}=0x9e +serdes_core_tx_polarity_flip_physical{201}=0xdf +serdes_core_rx_polarity_flip_physical{209}=0x17 +serdes_core_tx_polarity_flip_physical{209}=0xe9 +serdes_core_rx_polarity_flip_physical{217}=0xec +serdes_core_tx_polarity_flip_physical{217}=0x68 + +serdes_lane_config_media_type_49=copper +serdes_lane_config_media_type_50=copper +serdes_lane_config_media_type_51=copper +serdes_lane_config_media_type_52=copper +serdes_lane_config_media_type_54=copper +serdes_lane_config_media_type_55=copper +serdes_lane_config_media_type_56=copper +serdes_lane_config_media_type_57=copper +serdes_lane_config_media_type_53=copper +serdes_lane_config_media_type_60=copper +serdes_lane_config_media_type_61=copper +serdes_lane_config_media_type_62=copper +serdes_lane_config_media_type_63=copper +serdes_lane_config_media_type_65=copper +serdes_lane_config_media_type_66=copper +serdes_lane_config_media_type_67=copper +serdes_lane_config_media_type_68=copper +serdes_lane_config_media_type_64=copper +serdes_lane_config_media_type_80=copper +serdes_lane_config_media_type_81=copper +serdes_lane_config_media_type_82=copper +serdes_lane_config_media_type_83=copper +serdes_lane_config_media_type_85=copper +serdes_lane_config_media_type_86=copper +serdes_lane_config_media_type_87=copper +serdes_lane_config_media_type_88=copper +serdes_lane_config_media_type_84=copper +serdes_lane_config_media_type_100=copper +serdes_lane_config_media_type_101=copper +serdes_lane_config_media_type_102=copper +serdes_lane_config_media_type_103=copper +serdes_lane_config_media_type_105=copper +serdes_lane_config_media_type_106=copper +serdes_lane_config_media_type_107=copper +serdes_lane_config_media_type_108=copper +serdes_lane_config_media_type_104=copper +serdes_lane_config_media_type_120=copper +serdes_lane_config_media_type_121=copper +serdes_lane_config_media_type_122=copper +serdes_lane_config_media_type_123=copper +serdes_lane_config_media_type_125=copper +serdes_lane_config_media_type_126=copper +serdes_lane_config_media_type_127=copper +serdes_lane_config_media_type_128=copper +serdes_lane_config_media_type_124=copper +serdes_lane_config_media_type_140=copper +serdes_lane_config_media_type_141=copper +serdes_lane_config_media_type_142=copper +serdes_lane_config_media_type_143=copper +serdes_lane_config_media_type_145=copper +serdes_lane_config_media_type_146=copper +serdes_lane_config_media_type_147=copper +serdes_lane_config_media_type_148=copper +serdes_lane_config_media_type_144=copper +serdes_lane_config_media_type_40=copper +serdes_lane_config_media_type_41=copper +serdes_lane_config_media_type_42=copper +serdes_lane_config_media_type_43=copper +serdes_lane_config_media_type_45=copper +serdes_lane_config_media_type_46=copper +serdes_lane_config_media_type_47=copper +serdes_lane_config_media_type_48=copper +serdes_lane_config_media_type_44=copper +serdes_lane_config_media_type_69=copper +serdes_lane_config_media_type_70=copper +serdes_lane_config_media_type_71=copper +serdes_lane_config_media_type_72=copper +serdes_lane_config_media_type_74=copper +serdes_lane_config_media_type_75=copper +serdes_lane_config_media_type_76=copper +serdes_lane_config_media_type_77=copper +serdes_lane_config_media_type_73=copper +serdes_lane_config_media_type_1=copper +serdes_lane_config_media_type_2=copper +serdes_lane_config_media_type_3=copper +serdes_lane_config_media_type_4=copper +serdes_lane_config_media_type_6=copper +serdes_lane_config_media_type_7=copper +serdes_lane_config_media_type_8=copper +serdes_lane_config_media_type_9=copper +serdes_lane_config_media_type_5=copper +serdes_lane_config_media_type_29=copper +serdes_lane_config_media_type_30=copper +serdes_lane_config_media_type_31=copper +serdes_lane_config_media_type_32=copper +serdes_lane_config_media_type_34=copper +serdes_lane_config_media_type_35=copper +serdes_lane_config_media_type_36=copper +serdes_lane_config_media_type_37=copper +serdes_lane_config_media_type_33=copper +serdes_lane_config_media_type_89=copper +serdes_lane_config_media_type_90=copper +serdes_lane_config_media_type_91=copper +serdes_lane_config_media_type_92=copper +serdes_lane_config_media_type_94=copper +serdes_lane_config_media_type_95=copper +serdes_lane_config_media_type_96=copper +serdes_lane_config_media_type_97=copper +serdes_lane_config_media_type_93=copper +serdes_lane_config_media_type_109=copper +serdes_lane_config_media_type_110=copper +serdes_lane_config_media_type_111=copper +serdes_lane_config_media_type_112=copper +serdes_lane_config_media_type_114=copper +serdes_lane_config_media_type_115=copper +serdes_lane_config_media_type_116=copper +serdes_lane_config_media_type_117=copper +serdes_lane_config_media_type_113=copper +serdes_lane_config_media_type_129=copper +serdes_lane_config_media_type_130=copper +serdes_lane_config_media_type_131=copper +serdes_lane_config_media_type_132=copper +serdes_lane_config_media_type_134=copper +serdes_lane_config_media_type_135=copper +serdes_lane_config_media_type_136=copper +serdes_lane_config_media_type_137=copper +serdes_lane_config_media_type_133=copper +serdes_lane_config_media_type_149=copper +serdes_lane_config_media_type_150=copper +serdes_lane_config_media_type_151=copper +serdes_lane_config_media_type_152=copper +serdes_lane_config_media_type_154=copper +serdes_lane_config_media_type_155=copper +serdes_lane_config_media_type_156=copper +serdes_lane_config_media_type_157=copper +serdes_lane_config_media_type_153=copper +serdes_lane_config_media_type_10=copper +serdes_lane_config_media_type_11=copper +serdes_lane_config_media_type_12=copper +serdes_lane_config_media_type_13=copper +serdes_lane_config_media_type_15=copper +serdes_lane_config_media_type_16=copper +serdes_lane_config_media_type_17=copper +serdes_lane_config_media_type_18=copper +serdes_lane_config_media_type_14=copper +serdes_lane_config_media_type_20=copper +serdes_lane_config_media_type_21=copper +serdes_lane_config_media_type_22=copper +serdes_lane_config_media_type_23=copper +serdes_lane_config_media_type_25=copper +serdes_lane_config_media_type_26=copper +serdes_lane_config_media_type_27=copper +serdes_lane_config_media_type_28=copper +serdes_lane_config_media_type_24=copper + +#sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc +sai_postinit_cmd_file=/usr/share/sonic/hwsku/sai_postinit_cmd.soc + diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai.profile b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai.profile index 19cd5cb02839..26867a291b00 100644 --- a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai.profile +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-z9332f-32x400G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/th3-z9332f-32x400G.config.bcm b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/th3-z9332f-32x400G.config.bcm index 3d204640d5aa..fc6613601f52 100644 --- a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/th3-z9332f-32x400G.config.bcm +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/th3-z9332f-32x400G.config.bcm @@ -8,7 +8,7 @@ load_firmware=0x2 ccm_dma_enable=0 ccmdma_intr_enable=0 -mem_cache_enable=0 +mem_cache_enable=1 phy_enable=0 phy_null=1 @@ -32,7 +32,7 @@ tdma_intr_enable=1 tdma_timeout_usec.0=5000000 parity_correction.0=1 mmu_lossless.0=0 -bcm_num_cos=8 +bcm_num_cos=10 default_cpu_tx_queue=7 pktdma_poll_mode_channel_bitmap=1 l3_max_ecmp_mode.0=1 diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/eeprom.py b/device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/eeprom.py index e224cd452496..a346f1957be4 100644 --- a/device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/eeprom.py +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # DellEMC Z9332f # @@ -11,8 +9,8 @@ try: from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/psuutil.py b/device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/psuutil.py index b2c373de358f..435f9b2929ec 100644 --- a/device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/psuutil.py +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/psuutil.py @@ -6,9 +6,13 @@ import os.path import logging -import commands import sys +if sys.version_info[0] < 3: + import commands +else: + import subprocess as commands + Z9332F_MAX_PSUS = 2 IPMI_PSU1_DATA = "docker exec -it pmon ipmitool raw 0x04 0x2d 0x2f | awk '{print substr($0,9,1)}'" @@ -50,15 +54,15 @@ def get_pmc_register(self, reg_name): ipmi_cmd_2 = IPMI_PSU1_DATA dockerenv = self.isDockerEnv() if dockerenv == True: - 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) + 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 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 ipmitool') @@ -102,25 +106,24 @@ def get_psu_presence(self, index): ipmi_dev_node = "/dev/pmi0" dockerenv = self.isDockerEnv() if dockerenv == True: - 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) + 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: - ret_status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU2_DATA) + if index == 1: + 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: - # print ipmi_sdr_list - # logging.error('Failed to execute ipmitool') - # sys.exit(0) + # if ret_status: + # print ipmi_sdr_list + # logging.error('Failed to execute ipmitool') + # sys.exit(0) psu_status = ipmi_sdr_list if psu_status == '1': - status = 1 + status = 1 return status - diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/sfputil.py b/device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/sfputil.py index 1ea6af1f8d26..d037fd9273dd 100644 --- a/device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/sfputil.py +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/sfputil.py @@ -16,59 +16,56 @@ except ImportError as e: raise ImportError("%s - required module not found" % str(e)) -#from xcvrd +# from xcvrd SFP_STATUS_REMOVED = '0' SFP_STATUS_INSERTED = '1' - - - class SfpUtil(SfpUtilBase): """Platform-specific SfpUtil class""" PORT_START = 1 - PORT_END = 34 - PORTS_IN_BLOCK = 34 + PORT_END = 34 + PORTS_IN_BLOCK = 34 BASE_RES_PATH = "/sys/bus/pci/devices/0000:09:00.0/resource0" _port_to_i2c_mapping = { - 1: 10, - 2: 11, - 3: 12, - 4: 13, - 5: 14, - 6: 15, - 7: 16, - 8: 17, - 9: 18, - 10: 19, - 11: 20, - 12: 21, - 13: 22, - 14: 23, - 15: 24, - 16: 25, - 17: 26, - 18: 27, - 19: 28, - 20: 29, - 21: 30, - 22: 31, - 23: 32, - 24: 33, - 25: 34, - 26: 35, - 27: 36, - 28: 37, - 29: 38, - 30: 39, - 31: 40, - 32: 41, - 33: 1, - 34: 2, - } + 1: 10, + 2: 11, + 3: 12, + 4: 13, + 5: 14, + 6: 15, + 7: 16, + 8: 17, + 9: 18, + 10: 19, + 11: 20, + 12: 21, + 13: 22, + 14: 23, + 15: 24, + 16: 25, + 17: 26, + 18: 27, + 19: 28, + 20: 29, + 21: 30, + 22: 31, + 23: 32, + 24: 33, + 25: 34, + 26: 35, + 27: 36, + 28: 37, + 29: 38, + 30: 39, + 31: 40, + 32: 41, + 33: 1, + 34: 2, + } _port_to_eeprom_mapping = {} @@ -84,7 +81,7 @@ def port_end(self): @property def qsfp_ports(self): - return range(self.PORT_START, self.PORTS_IN_BLOCK + 1) + return list(range(self.PORT_START, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -128,27 +125,26 @@ def init_global_port_presence(self): self._global_port_pres_dict[port_num] = '0' def mod_pres(self): - port_pres_mask =0 + port_pres_mask = 0 for port_num in range(self.port_start, (self.port_end + 1)): presence = self.get_presence(port_num) if(presence): self._global_port_pres_dict[port_num] = '1' - port_val = (1 << (port_num -1)) + port_val = (1 << (port_num - 1)) port_pres_mask = (port_pres_mask | port_val) else: self._global_port_pres_dict[port_num] = '0' - port_val = ~(1 << (port_num -1)) + port_val = ~(1 << (port_num - 1)) port_pres_mask = (port_pres_mask & port_val) return port_pres_mask - def __init__(self): eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" for x in range(self.port_start, self.port_end + 1): self.port_to_eeprom_mapping[x] = eeprom_path.format( - self._port_to_i2c_mapping[x]) + self._port_to_i2c_mapping[x]) self.init_global_port_presence() SfpUtilBase.__init__(self) @@ -172,7 +168,7 @@ def get_presence(self, port_num): # Mask off 1st bit for presence 33,34 if (port_num > 32): - mask = (1 << 0) + mask = (1 << 0) # ModPrsL is active low if reg_value & mask == 0: @@ -271,21 +267,21 @@ def reset(self, port_num): return True def get_register(self, reg_file): - retval = 'ERR' - if (not path.isfile(reg_file)): - print reg_file, 'not found !' - return retval - - try: - with fdopen(open(reg_file, O_RDONLY)) as fd: - retval = fd.read() - except Exception as error: - logging.error("Unable to open ", reg_file, "file !") - - retval = retval.rstrip('\r\n') - retval = retval.lstrip(" ") + retval = 'ERR' + if (not path.isfile(reg_file)): + print(reg_file + ' not found !') return retval + try: + with fdopen(open(reg_file, O_RDONLY)) as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", reg_file, "file !") + + retval = retval.rstrip('\r\n') + retval = retval.lstrip(" ") + return retval + def get_transceiver_change_event(self): port_dict = {} while True: @@ -303,5 +299,3 @@ def get_transceiver_change_event(self): return True, port_dict time.sleep(0.5) - - diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/pmon_daemon_control.json b/device/dell/x86_64-dellemc_z9332f_d1508-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/system_health_monitoring_config.json b/device/dell/x86_64-dellemc_z9332f_d1508-r0/system_health_monitoring_config.json new file mode 100644 index 000000000000..d52b24cf905d --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/system_health_monitoring_config.json @@ -0,0 +1,11 @@ +{ + "services_to_ignore": [], + "devices_to_ignore": ["asic","fan.speed"], + "user_defined_checkers": [], + "polling_interval": 60, + "led_color": { + "fault": "yellow", + "normal": "green", + "booting": "flash_green" + } +} diff --git a/device/delta/x86_64-delta_ag5648-r0/Delta-ag5648/sai.profile b/device/delta/x86_64-delta_ag5648-r0/Delta-ag5648/sai.profile index 094e2d2cda01..98876a9c2a39 100644 --- a/device/delta/x86_64-delta_ag5648-r0/Delta-ag5648/sai.profile +++ b/device/delta/x86_64-delta_ag5648-r0/Delta-ag5648/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-ag5648-48x25G+6x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/delta/x86_64-delta_ag5648-r0/plugins/eeprom.py b/device/delta/x86_64-delta_ag5648-r0/plugins/eeprom.py index 786e1fdc85e3..bd9bbb755f39 100644 --- a/device/delta/x86_64-delta_ag5648-r0/plugins/eeprom.py +++ b/device/delta/x86_64-delta_ag5648-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Mellanox # @@ -10,7 +8,6 @@ ############################################################################# try: - import exceptions import binascii import time import optparse @@ -20,13 +17,14 @@ 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") +except ImportError as 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/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-2/2-0053/eeprom" - super(board, self).__init__(self.eeprom_path, 0, '', True) + self.eeprom_path = "/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-2/2-0053/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/delta/x86_64-delta_ag5648-r0/plugins/psuutil.py b/device/delta/x86_64-delta_ag5648-r0/plugins/psuutil.py index 0d17ff05681a..8aa080166f8a 100644 --- a/device/delta/x86_64-delta_ag5648-r0/plugins/psuutil.py +++ b/device/delta/x86_64-delta_ag5648-r0/plugins/psuutil.py @@ -3,7 +3,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" @@ -15,7 +16,6 @@ def __init__(self): self.psu_oper_status = "in1_input" self.psu_presence = "i2cget -y 6 0x{} 0x00" - def get_num_psus(self): """ Retrieves the number of PSUs available on the device @@ -31,7 +31,7 @@ def get_psu_status(self, index): status = 0 try: with open(self.psu_path.format(index + Base_bus_number) + self.psu_oper_status, 'r') as power_status: - if int(power_status.read()) == 0 : + if int(power_status.read()) == 0: return False else: status = 1 @@ -45,12 +45,10 @@ def get_psu_presence(self, index): Base_bus_number = 49 status = 0 try: - p = os.popen(self.psu_presence.format(index + Base_bus_number)+ "> /dev/null 2>&1") + p = os.popen(self.psu_presence.format(index + Base_bus_number) + "> /dev/null 2>&1") if p.readline() != None: status = 1 p.close() except IOError: return False return status == 1 - - diff --git a/device/delta/x86_64-delta_ag5648-r0/plugins/sfputil.py b/device/delta/x86_64-delta_ag5648-r0/plugins/sfputil.py index 864977414251..5fc426340818 100644 --- a/device/delta/x86_64-delta_ag5648-r0/plugins/sfputil.py +++ b/device/delta/x86_64-delta_ag5648-r0/plugins/sfputil.py @@ -25,6 +25,7 @@ class SfpUtil(SfpUtilBase): @property def port_start(self): return self.PORT_START + @property def port_start_qsfp(self): return self.PORT_START_QSFP @@ -35,7 +36,7 @@ def port_end(self): @property def qsfp_ports(self): - return range(0, self.PORTS_IN_BLOCK + 1) + return list(range(0, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -45,7 +46,7 @@ def __init__(self): eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" for x in range(0, self.port_end + 1): - if x > self.port_start_qsfp -1 and x < self.port_end + 1: + if x > self.port_start_qsfp - 1 and x < self.port_end + 1: self.get_response(x) self._port_to_eeprom_mapping[x] = eeprom_path.format(x + self.EEPROM_OFFSET) SfpUtilBase.__init__(self) @@ -58,12 +59,12 @@ def get_response(self, port_num): try: reg_file = open("/sys/devices/platform/delta-ag5648-cpld.0/sfp_response", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False - # set the bit corresponding to our port - mask = (port_num + 1) % 8 - 1 - mask = 1 << mask + # set the bit corresponding to our port + mask = (port_num + 1) % 8 - 1 + mask = 1 << mask # Convert our register value back to a hex string and write back content = hex(mask) @@ -81,7 +82,7 @@ def get_presence(self, port_num): try: reg_file = open("/sys/devices/platform/delta-ag5648-cpld.0/sfp_present") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -106,7 +107,7 @@ def get_low_power_mode(self, port_num): try: reg_file = open("/sys/devices/platform/delta-ag5648-cpld.0/sfp_lpmode") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) content = reg_file.readline().rstrip() @@ -130,7 +131,7 @@ def set_low_power_mode(self, port_num, lpmode): try: reg_file = open("/sys/devices/platform/delta-ag5648-cpld.0/sfp_lpmode", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -166,7 +167,7 @@ def reset(self, port_num): try: reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -192,7 +193,7 @@ def reset(self, port_num): try: reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "w") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = reg_value | mask diff --git a/device/delta/x86_64-delta_ag9032v1-r0/Delta-ag9032v1/sai.profile b/device/delta/x86_64-delta_ag9032v1-r0/Delta-ag9032v1/sai.profile index c77b2bf79a34..a1ec3ca258df 100644 --- a/device/delta/x86_64-delta_ag9032v1-r0/Delta-ag9032v1/sai.profile +++ b/device/delta/x86_64-delta_ag9032v1-r0/Delta-ag9032v1/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-ag9032v1-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/delta/x86_64-delta_ag9032v1-r0/plugins/eeprom.py b/device/delta/x86_64-delta_ag9032v1-r0/plugins/eeprom.py index 786e1fdc85e3..bd9bbb755f39 100644 --- a/device/delta/x86_64-delta_ag9032v1-r0/plugins/eeprom.py +++ b/device/delta/x86_64-delta_ag9032v1-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Mellanox # @@ -10,7 +8,6 @@ ############################################################################# try: - import exceptions import binascii import time import optparse @@ -20,13 +17,14 @@ 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") +except ImportError as 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/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-2/2-0053/eeprom" - super(board, self).__init__(self.eeprom_path, 0, '', True) + self.eeprom_path = "/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-2/2-0053/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/delta/x86_64-delta_ag9032v1-r0/plugins/psuutil.py b/device/delta/x86_64-delta_ag9032v1-r0/plugins/psuutil.py index 4b370d9a7443..391efbd2401f 100644 --- a/device/delta/x86_64-delta_ag9032v1-r0/plugins/psuutil.py +++ b/device/delta/x86_64-delta_ag9032v1-r0/plugins/psuutil.py @@ -3,7 +3,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" @@ -15,7 +16,6 @@ def __init__(self): self.psu_oper_status = "in1_input" self.psu_presence = "i2cget -y {} 0x50 0x00" - def get_num_psus(self): """ Retrieves the number of PSUs available on the device @@ -29,10 +29,10 @@ def get_psu_status(self, index): return False Base_bus_number = 39 status = 0 - #index from 1, psu attribute bus from 40 + # index from 1, psu attribute bus from 40 try: with open(self.psu_path.format(index + Base_bus_number) + self.psu_oper_status, 'r') as power_status: - if int(power_status.read()) == 0 : + if int(power_status.read()) == 0: return False else: status = 1 @@ -46,12 +46,10 @@ def get_psu_presence(self, index): Base_bus_number = 39 status = 0 try: - p = os.popen(self.psu_presence.format(index + Base_bus_number)+ "> /dev/null 2>&1") + p = os.popen(self.psu_presence.format(index + Base_bus_number) + "> /dev/null 2>&1") if p.readline() != None: status = 1 p.close() except IOError: return False return status == 1 - - diff --git a/device/delta/x86_64-delta_ag9032v1-r0/plugins/sfputil.py b/device/delta/x86_64-delta_ag9032v1-r0/plugins/sfputil.py index 748e2b6643f4..c620540d2911 100644 --- a/device/delta/x86_64-delta_ag9032v1-r0/plugins/sfputil.py +++ b/device/delta/x86_64-delta_ag9032v1-r0/plugins/sfputil.py @@ -31,7 +31,7 @@ def port_end(self): @property def qsfp_ports(self): - return range(0, self.PORTS_IN_BLOCK + 1) + return list(range(0, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -53,7 +53,7 @@ def get_presence(self, port_num): try: reg_file = open("/sys/devices/platform/delta-ag9032v1-swpld.0/sfp_present") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -78,7 +78,7 @@ def get_low_power_mode(self, port_num): try: reg_file = open("/sys/devices/platform/delta-ag9032v1-swpld.0/sfp_lpmode") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) content = reg_file.readline().rstrip() @@ -102,7 +102,7 @@ def set_low_power_mode(self, port_num, lpmode): try: reg_file = open("/sys/devices/platform/delta-ag9032v1-swpld.0/sfp_lpmode", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -138,7 +138,7 @@ def reset(self, port_num): try: reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -164,7 +164,7 @@ def reset(self, port_num): try: reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "w") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = reg_value | mask diff --git a/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/custom_led.bin b/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/custom_led.bin new file mode 100755 index 000000000000..fca72410f8d7 Binary files /dev/null and b/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/custom_led.bin differ diff --git a/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/sai.profile b/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/sai.profile index f0eccb028258..0d3c85f8f38a 100644 --- a/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/sai.profile +++ b/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-ag9032v2a-32x100G+1x10G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/td3-ag9032v2a-32x100G+1x10G.config.bcm b/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/td3-ag9032v2a-32x100G+1x10G.config.bcm index 4c6ceb075bf4..07600e0b8a65 100755 --- a/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/td3-ag9032v2a-32x100G+1x10G.config.bcm +++ b/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/td3-ag9032v2a-32x100G+1x10G.config.bcm @@ -1,3 +1,4 @@ +sai_load_hw_config=/etc/bcm/flex/bcm56870_a0_issu/b870.6.4.1/ pbmp_oversubscribe=0x00003fc000000ff0000003fc000001fe pbmp_xport_xe=0xffffffffffffffffffffffffffffffffffff core_clock_frequency=1525 @@ -9,7 +10,7 @@ l2_mem_entries=32768 l3_mem_entries=16384 fpem_mem_entries=131072 l2xmsg_mode=1 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 cdma_timeout_usec=3000000 ipv6_lpm_128b_enable=0x1 diff --git a/device/delta/x86_64-delta_ag9032v2a-r0/led_proc_init.soc b/device/delta/x86_64-delta_ag9032v2a-r0/led_proc_init.soc new file mode 100644 index 000000000000..57ee7fedaf2b --- /dev/null +++ b/device/delta/x86_64-delta_ag9032v2a-r0/led_proc_init.soc @@ -0,0 +1,3 @@ +m0 load 0 0x3800 /usr/share/sonic/platform/custom_led.bin +led auto on +led start diff --git a/device/delta/x86_64-delta_ag9032v2a-r0/plugins/eeprom.py b/device/delta/x86_64-delta_ag9032v2a-r0/plugins/eeprom.py index fc741c11e9ea..9d55c090d57b 100644 --- a/device/delta/x86_64-delta_ag9032v2a-r0/plugins/eeprom.py +++ b/device/delta/x86_64-delta_ag9032v2a-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Mellanox # @@ -10,7 +8,6 @@ ############################################################################# try: - import exceptions import binascii import time import optparse @@ -20,13 +17,14 @@ 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") +except ImportError as 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/devices/pci0000:00/0000:00:1f.3/i2c-0/i2c-1/1-0053/eeprom" - super(board, self).__init__(self.eeprom_path, 0, '', True) + self.eeprom_path = "/sys/devices/pci0000:00/0000:00:1f.3/i2c-0/i2c-1/1-0053/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/delta/x86_64-delta_ag9032v2a-r0/plugins/psuutil.py b/device/delta/x86_64-delta_ag9032v2a-r0/plugins/psuutil.py index 93936664c1c5..06655c07a416 100644 --- a/device/delta/x86_64-delta_ag9032v2a-r0/plugins/psuutil.py +++ b/device/delta/x86_64-delta_ag9032v2a-r0/plugins/psuutil.py @@ -9,7 +9,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" @@ -52,7 +53,6 @@ def get_psu_status(self, index): return False return status == 1 - def get_psu_presence(self, index): """ Retrieves the presence status of power supply unit (PSU) defined @@ -72,14 +72,13 @@ def get_psu_presence(self, index): if index == 1: mask = (1 << 7) if reg_value & mask == 0x80: - return False + return False else: mask = (1 << 3) if reg_value & mask == 0x08: - return False + return False status = 1 p.close() except IOError: return False return status == 1 - diff --git a/device/delta/x86_64-delta_ag9032v2a-r0/plugins/sfputil.py b/device/delta/x86_64-delta_ag9032v2a-r0/plugins/sfputil.py index 9abaa8cf01c1..ace5d9f3736b 100644 --- a/device/delta/x86_64-delta_ag9032v2a-r0/plugins/sfputil.py +++ b/device/delta/x86_64-delta_ag9032v2a-r0/plugins/sfputil.py @@ -31,7 +31,7 @@ def port_end(self): @property def qsfp_ports(self): - return range(0, self.PORT_END - self.PORT_START + 1) + return list(range(0, self.PORT_END - self.PORT_START + 1)) @property def port_to_eeprom_mapping(self): @@ -53,7 +53,7 @@ def get_presence(self, port_num): try: reg_file = open("/sys/devices/platform/delta-ag9032v2a-swpld1.0/sfp_is_present") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -78,7 +78,7 @@ def get_low_power_mode(self, port_num): try: reg_file = open("/sys/devices/platform/delta-ag9032v2a-swpld1.0/qsfp_lpmode") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) content = reg_file.readline().rstrip() @@ -102,7 +102,7 @@ def set_low_power_mode(self, port_num, lpmode): try: reg_file = open("/sys/devices/platform/delta-ag9032v2a-swpld1.0/qsfp_lpmode", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -138,7 +138,7 @@ def reset(self, port_num): try: reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -164,7 +164,7 @@ def reset(self, port_num): try: reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "w") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = reg_value | mask diff --git a/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/sai.profile b/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/sai.profile index 21f013773e61..2fc46808b555 100644 --- a/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/sai.profile +++ b/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-ag9064-64x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/th2-ag9064-64x100G.config.bcm b/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/th2-ag9064-64x100G.config.bcm index eae7278a3ab2..4aba9cc855a2 100644 --- a/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/th2-ag9064-64x100G.config.bcm +++ b/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/th2-ag9064-64x100G.config.bcm @@ -781,7 +781,7 @@ portmap_8=29:100 portmap_9=33:100 lpm_scaling_enable=0 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_jumbo=9236 ipv6_lpm_128b_enable=1 max_vp_lags=0 diff --git a/device/delta/x86_64-delta_ag9064-r0/plugins/eeprom.py b/device/delta/x86_64-delta_ag9064-r0/plugins/eeprom.py index e4048ed302de..9a3ea5737684 100644 --- a/device/delta/x86_64-delta_ag9064-r0/plugins/eeprom.py +++ b/device/delta/x86_64-delta_ag9064-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Mellanox # @@ -10,7 +8,6 @@ ############################################################################# try: - import exceptions import binascii import time import optparse @@ -20,13 +17,14 @@ 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") +except ImportError as 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/devices/pci0000:00/0000:00:1f.3/i2c-0/0-0056/eeprom" - super(board, self).__init__(self.eeprom_path, 0, '', True) + self.eeprom_path = "/sys/devices/pci0000:00/0000:00:1f.3/i2c-0/0-0056/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/delta/x86_64-delta_ag9064-r0/plugins/psuutil.py b/device/delta/x86_64-delta_ag9064-r0/plugins/psuutil.py index 2a2bd1eea6a2..43f7bb6acb3c 100644 --- a/device/delta/x86_64-delta_ag9064-r0/plugins/psuutil.py +++ b/device/delta/x86_64-delta_ag9064-r0/plugins/psuutil.py @@ -9,7 +9,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" @@ -44,15 +45,13 @@ def get_psu_status(self, index): content = p.readline().rstrip() reg_value = int(content) if reg_value != 0: - return False + return False status = 1 p.close() except IOError: return False return status == 1 - - def get_psu_presence(self, index): """ Retrieves the presence status of power supply unit (PSU) defined @@ -75,4 +74,3 @@ def get_psu_presence(self, index): except IOError: return False return status == 1 - diff --git a/device/delta/x86_64-delta_ag9064-r0/plugins/sfputil.py b/device/delta/x86_64-delta_ag9064-r0/plugins/sfputil.py index 8b1b1aea1d82..f86fac5f2af2 100644 --- a/device/delta/x86_64-delta_ag9064-r0/plugins/sfputil.py +++ b/device/delta/x86_64-delta_ag9064-r0/plugins/sfputil.py @@ -31,7 +31,7 @@ def port_end(self): @property def qsfp_ports(self): - return range(0, self.PORTS_IN_BLOCK + 1) + return list(range(0, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -53,7 +53,7 @@ def get_presence(self, port_num): try: reg_file = open("/sys/devices/platform/delta-ag9064-cpld.0/qsfp_present") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -78,7 +78,7 @@ def get_low_power_mode(self, port_num): try: reg_file = open("/sys/devices/platform/delta-ag9064-cpld.0/qsfp_lpmode") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) content = reg_file.readline().rstrip() @@ -102,7 +102,7 @@ def set_low_power_mode(self, port_num, lpmode): try: reg_file = open("/sys/devices/platform/delta-ag9064-cpld.0/qsfp_lpmode", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -138,7 +138,7 @@ def reset(self, port_num): try: reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -164,7 +164,7 @@ def reset(self, port_num): try: reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "w") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = reg_value | mask diff --git a/device/delta/x86_64-delta_agc032-r0/Delta-agc032/port_config.ini b/device/delta/x86_64-delta_agc032-r0/Delta-agc032/port_config.ini new file mode 100644 index 000000000000..e081ee55aea7 --- /dev/null +++ b/device/delta/x86_64-delta_agc032-r0/Delta-agc032/port_config.ini @@ -0,0 +1,35 @@ +# name lanes alias speed index +Ethernet0 17,18,19,20,21,22,23,24 fourhundredGigE1/1 400000 0 +Ethernet4 25,26,27,28,29,30,31,32 fourhundredGigE1/2 400000 1 +Ethernet8 1,2,3,4,5,6,7,8, fourhundredGigE1/3 400000 2 +Ethernet12 9,10,11,12,13,14,15,16 fourhundredGigE1/4 400000 3 +Ethernet16 49,50,51,52,53,54,55,56 fourhundredGigE1/5 400000 4 +Ethernet20 57,58,59,60,61,62,63,64 fourhundredGigE1/6 400000 5 +Ethernet24 33,34,35,36,37,38,39,40 fourhundredGigE1/7 400000 6 +Ethernet28 41,42,43,44,45,46,47,48 fourhundredGigE1/8 400000 7 +Ethernet32 81,82,83,84,85,86,87,88 fourhundredGigE1/9 400000 8 +Ethernet36 89,90,91,92,93,94,95,96 fourhundredGigE1/10 400000 9 +Ethernet40 65,66,67,68,69,70,71,72 fourhundredGigE1/11 400000 10 +Ethernet44 73,74,75,76,77,78,79,80 fourhundredGigE1/12 400000 11 +Ethernet48 113,114,115,116,117,118,119,120 fourhundredGigE1/13 400000 12 +Ethernet52 121,122,123,124,125,126,127,128 fourhundredGigE1/14 400000 13 +Ethernet56 97,98,99,100,101,102,103,104 fourhundredGigE1/15 400000 14 +Ethernet60 105,106,107,108,109,110,111,112 fourhundredGigE1/16 400000 15 +Ethernet64 129,130,131,132,133,134,135,136 fourhundredGigE1/17 400000 16 +Ethernet68 137,138,139,140,141,142,143,144 fourhundredGigE1/18 400000 17 +Ethernet72 145,146,147,148,149,150,151,152 fourhundredGigE1/19 400000 18 +Ethernet76 153,154,155,156,157,158,159,160 fourhundredGigE1/20 400000 19 +Ethernet80 161,162,163,164,165,166,167,168 fourhundredGigE1/21 400000 20 +Ethernet84 169,170,171,172,173,174,175,176 fourhundredGigE1/22 400000 21 +Ethernet88 177,178,179,180,181,182,183,184 fourhundredGigE1/23 400000 22 +Ethernet92 185,186,187,188,189,190,191,192 fourhundredGigE1/24 400000 23 +Ethernet96 193,194,195,196,197,198,199,200 fourhundredGigE1/25 400000 24 +Ethernet100 201,202,203,204,205,206,207,208 fourhundredGigE1/26 400000 25 +Ethernet104 209,210,211,212,213,214,215,216 fourhundredGigE1/27 400000 26 +Ethernet108 217,218,219,220,221,222,223,224 fourhundredGigE1/28 400000 27 +Ethernet112 225,226,227,228,229,230,231,232 fourhundredGigE1/29 400000 28 +Ethernet116 233,234,235,236,237,238,239,240 fourhundredGigE1/30 400000 29 +Ethernet120 241,242,243,244,245,246,247,248 fourhundredGigE1/31 400000 30 +Ethernet124 249,250,251,252,253,254,255,256 fourhundredGigE1/32 400000 31 +Ethernet128 257 tenGigE1/33 10000 32 +Ethernet132 258 tenGigE1/34 10000 33 diff --git a/device/delta/x86_64-delta_agc032-r0/Delta-agc032/sai.profile b/device/delta/x86_64-delta_agc032-r0/Delta-agc032/sai.profile new file mode 100644 index 000000000000..2da82c5bffa5 --- /dev/null +++ b/device/delta/x86_64-delta_agc032-r0/Delta-agc032/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-agc032-32x400G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/delta/x86_64-delta_agc032-r0/Delta-agc032/th3-agc032-32x400G.config.bcm b/device/delta/x86_64-delta_agc032-r0/Delta-agc032/th3-agc032-32x400G.config.bcm new file mode 100644 index 000000000000..d3dfd269ff1b --- /dev/null +++ b/device/delta/x86_64-delta_agc032-r0/Delta-agc032/th3-agc032-32x400G.config.bcm @@ -0,0 +1,280 @@ +######################################### +## cfg for AGC032 +######################################### +pbmp_xport_xe=0x8000f8000fc000f8000f8000f8000fc000f8001e +ccm_dma_enable=0 +ccmdma_intr_enable=0 +ctr_evict_enable=0 +mem_cache_enable=0 +parity_correction=0 +parity_enable=0 +phy_enable=0 +phy_null=1 +pll_bypass=1 +init_all_modules=0 +################################################################################ +# Pipe 0 +portmap_1=1:400 +portmap_2=9:400 +portmap_3=17:400 +portmap_4=25:400 + +#loopback port +portmap_19=259:10 +################################################################################ +# Pipe 1 +portmap_20=33:400 +portmap_21=41:400 +portmap_22=49:400 +portmap_23=57:400 + +#management port +portmap_38=257:10 + +#loopback port +portmap_39=260:10 +################################################################################ +# Pipe 2 +portmap_40=65:400 +portmap_41=73:400 +portmap_42=81:400 +portmap_43=89:400 + +#loopback port +portmap_59=261:10 +################################################################################ +# Pipe 3 +portmap_60=97:400 +portmap_61=105:400 +portmap_62=113:400 +portmap_63=121:400 + +#loopback port +portmap_79=262:10 +################################################################################ +# Pipe 4 +portmap_80=129:400 +portmap_81=137:400 +portmap_82=145:400 +portmap_83=153:400 + +#loopback port +portmap_99=263:10 +################################################################################ +# Pipe 5 +portmap_100=161:400 +portmap_101=169:400 +portmap_102=177:400 +portmap_103=185:400 + +#management port +portmap_118=258:10 + +#loopback port +portmap_119=264:10 +################################################################################ +# Pipe 6 +portmap_120=193:400 +portmap_121=201:400 +portmap_122=209:400 +portmap_123=217:400 + +#loopback port +portmap_139=265:10 +################################################################################ +# Pipe 7 +portmap_140=225:400 +portmap_141=233:400 +portmap_142=241:400 +portmap_143=249:400 + +#loopback port +portmap_159=266:10 +################################################################################ +dport_map_enable=1 + +dport_map_port_1=3 +dport_map_port_2=4 +dport_map_port_3=1 +dport_map_port_4=2 +dport_map_port_20=7 +dport_map_port_21=8 +dport_map_port_22=5 +dport_map_port_23=6 +dport_map_port_40=11 +dport_map_port_41=12 +dport_map_port_42=9 +dport_map_port_43=10 +dport_map_port_60=15 +dport_map_port_61=16 +dport_map_port_62=13 +dport_map_port_63=14 +dport_map_port_80=17 +dport_map_port_81=18 +dport_map_port_82=19 +dport_map_port_83=20 +dport_map_port_100=21 +dport_map_port_101=22 +dport_map_port_102=23 +dport_map_port_103=24 +dport_map_port_120=25 +dport_map_port_121=26 +dport_map_port_122=27 +dport_map_port_123=28 +dport_map_port_140=29 +dport_map_port_141=30 +dport_map_port_142=31 +dport_map_port_143=32 + +dport_map_port_38=33 +dport_map_port_118=34 +################################################################################ +# tx_lane map +phy_chain_tx_lane_map_physical{1.0}=0x14762350 +phy_chain_tx_lane_map_physical{9.0}=0x36104527 +phy_chain_tx_lane_map_physical{17.0}=0x17053624 +phy_chain_tx_lane_map_physical{25.0}=0x57314602 +phy_chain_tx_lane_map_physical{33.0}=0x46302517 +phy_chain_tx_lane_map_physical{41.0}=0x76203514 +phy_chain_tx_lane_map_physical{49.0}=0x26143507 +phy_chain_tx_lane_map_physical{57.0}=0x74236510 +phy_chain_tx_lane_map_physical{65.0}=0x75021436 +phy_chain_tx_lane_map_physical{73.0}=0x67210435 +phy_chain_tx_lane_map_physical{81.0}=0x26143507 +phy_chain_tx_lane_map_physical{89.0}=0x75436120 +phy_chain_tx_lane_map_physical{97.0}=0x54621730 +phy_chain_tx_lane_map_physical{105.0}=0x64310725 +phy_chain_tx_lane_map_physical{113.0}=0x07352416 +phy_chain_tx_lane_map_physical{121.0}=0x13762054 +phy_chain_tx_lane_map_physical{129.0}=0x13427506 +phy_chain_tx_lane_map_physical{137.0}=0x54307612 +phy_chain_tx_lane_map_physical{145.0}=0x76103524 +phy_chain_tx_lane_map_physical{153.0}=0x67103425 +phy_chain_tx_lane_map_physical{161.0}=0x15402637 +phy_chain_tx_lane_map_physical{169.0}=0x76135420 +phy_chain_tx_lane_map_physical{177.0}=0x67052431 +phy_chain_tx_lane_map_physical{185.0}=0x57103624 +phy_chain_tx_lane_map_physical{193.0}=0x15402637 +phy_chain_tx_lane_map_physical{201.0}=0x54137620 +phy_chain_tx_lane_map_physical{209.0}=0x56012734 +phy_chain_tx_lane_map_physical{217.0}=0x57301426 +phy_chain_tx_lane_map_physical{225.0}=0x07352641 +phy_chain_tx_lane_map_physical{233.0}=0x57236401 +phy_chain_tx_lane_map_physical{241.0}=0x16543720 +phy_chain_tx_lane_map_physical{249.0}=0x50273416 + +# rx_lane_map +phy_chain_rx_lane_map_physical{1.0}=0x42305761 +phy_chain_rx_lane_map_physical{9.0}=0x13605472 +phy_chain_rx_lane_map_physical{17.0}=0x41730652 +phy_chain_rx_lane_map_physical{25.0}=0x71206534 +phy_chain_rx_lane_map_physical{33.0}=0x62170453 +phy_chain_rx_lane_map_physical{41.0}=0x27641305 +phy_chain_rx_lane_map_physical{49.0}=0x53604271 +phy_chain_rx_lane_map_physical{57.0}=0x31607425 +phy_chain_rx_lane_map_physical{65.0}=0x47612350 +phy_chain_rx_lane_map_physical{73.0}=0x23471605 +phy_chain_rx_lane_map_physical{81.0}=0x43710265 +phy_chain_rx_lane_map_physical{89.0}=0x31706425 +phy_chain_rx_lane_map_physical{97.0}=0x60317425 +phy_chain_rx_lane_map_physical{105.0}=0x40635172 +phy_chain_rx_lane_map_physical{113.0}=0x20573146 +phy_chain_rx_lane_map_physical{121.0}=0x51204637 +phy_chain_rx_lane_map_physical{129.0}=0x34102567 +phy_chain_rx_lane_map_physical{137.0}=0x70143526 +phy_chain_rx_lane_map_physical{145.0}=0x20316574 +phy_chain_rx_lane_map_physical{153.0}=0x13572046 +phy_chain_rx_lane_map_physical{161.0}=0x61253074 +phy_chain_rx_lane_map_physical{169.0}=0x61043527 +phy_chain_rx_lane_map_physical{177.0}=0x43617250 +phy_chain_rx_lane_map_physical{185.0}=0x31067425 +phy_chain_rx_lane_map_physical{193.0}=0x35162074 +phy_chain_rx_lane_map_physical{201.0}=0x30146527 +phy_chain_rx_lane_map_physical{209.0}=0x73506241 +phy_chain_rx_lane_map_physical{217.0}=0x73241605 +phy_chain_rx_lane_map_physical{225.0}=0x26573140 +phy_chain_rx_lane_map_physical{233.0}=0x46213750 +phy_chain_rx_lane_map_physical{241.0}=0x13650274 +phy_chain_rx_lane_map_physical{249.0}=0x42305167 + +# tx polarity +serdes_core_tx_polarity_flip_physical{1}=0x5d +serdes_core_tx_polarity_flip_physical{9}=0x9c +serdes_core_tx_polarity_flip_physical{17}=0x72 +serdes_core_tx_polarity_flip_physical{25}=0xad +serdes_core_tx_polarity_flip_physical{33}=0x38 +serdes_core_tx_polarity_flip_physical{41}=0x86 +serdes_core_tx_polarity_flip_physical{49}=0xaf +serdes_core_tx_polarity_flip_physical{57}=0xc6 +serdes_core_tx_polarity_flip_physical{65}=0x70 +serdes_core_tx_polarity_flip_physical{73}=0xc7 +serdes_core_tx_polarity_flip_physical{81}=0xae +serdes_core_tx_polarity_flip_physical{89}=0xe0 +serdes_core_tx_polarity_flip_physical{97}=0xf1 +serdes_core_tx_polarity_flip_physical{105}=0x0c +serdes_core_tx_polarity_flip_physical{113}=0xc8 +serdes_core_tx_polarity_flip_physical{121}=0x3f +serdes_core_tx_polarity_flip_physical{129}=0x8b +serdes_core_tx_polarity_flip_physical{137}=0x77 +serdes_core_tx_polarity_flip_physical{145}=0x39 +serdes_core_tx_polarity_flip_physical{153}=0xa5 +serdes_core_tx_polarity_flip_physical{161}=0xd8 +serdes_core_tx_polarity_flip_physical{169}=0x8b +serdes_core_tx_polarity_flip_physical{177}=0x29 +serdes_core_tx_polarity_flip_physical{185}=0x30 +serdes_core_tx_polarity_flip_physical{193}=0xf8 +serdes_core_tx_polarity_flip_physical{201}=0x8a +serdes_core_tx_polarity_flip_physical{209}=0xb8 +serdes_core_tx_polarity_flip_physical{217}=0x08 +serdes_core_tx_polarity_flip_physical{225}=0xb3 +serdes_core_tx_polarity_flip_physical{233}=0x62 +serdes_core_tx_polarity_flip_physical{241}=0x70 +serdes_core_tx_polarity_flip_physical{249}=0xd2 + +# rx poplarity +serdes_core_rx_polarity_flip_physical{1}=0x18 +serdes_core_rx_polarity_flip_physical{9}=0xa0 +serdes_core_rx_polarity_flip_physical{17}=0x9c +serdes_core_rx_polarity_flip_physical{25}=0x47 +serdes_core_rx_polarity_flip_physical{33}=0xf5 +serdes_core_rx_polarity_flip_physical{41}=0x38 +serdes_core_rx_polarity_flip_physical{49}=0x87 +serdes_core_rx_polarity_flip_physical{57}=0x1a +serdes_core_rx_polarity_flip_physical{65}=0xf0 +serdes_core_rx_polarity_flip_physical{73}=0x68 +serdes_core_rx_polarity_flip_physical{81}=0x96 +serdes_core_rx_polarity_flip_physical{89}=0x32 +serdes_core_rx_polarity_flip_physical{97}=0x5a +serdes_core_rx_polarity_flip_physical{105}=0xb4 +serdes_core_rx_polarity_flip_physical{113}=0xe1 +serdes_core_rx_polarity_flip_physical{121}=0x4a +serdes_core_rx_polarity_flip_physical{129}=0xf3 +serdes_core_rx_polarity_flip_physical{137}=0xc3 +serdes_core_rx_polarity_flip_physical{145}=0x12 +serdes_core_rx_polarity_flip_physical{153}=0xb4 +serdes_core_rx_polarity_flip_physical{161}=0xf0 +serdes_core_rx_polarity_flip_physical{169}=0xa7 +serdes_core_rx_polarity_flip_physical{177}=0xe1 +serdes_core_rx_polarity_flip_physical{185}=0x90 +serdes_core_rx_polarity_flip_physical{193}=0x0a +serdes_core_rx_polarity_flip_physical{201}=0x4e +serdes_core_rx_polarity_flip_physical{209}=0x5a +serdes_core_rx_polarity_flip_physical{217}=0x98 +serdes_core_rx_polarity_flip_physical{225}=0x2f +serdes_core_rx_polarity_flip_physical{233}=0x5b +serdes_core_rx_polarity_flip_physical{241}=0xf4 +serdes_core_rx_polarity_flip_physical{249}=0x1d +################################################################################ +#firmware load, use fast load +load_firmware=0x2 + +core_clock_frequency=1325 +dpr_clock_frequency=1000 +device_clock_frequency=1325 +port_flex_enable=1 + + +################################################################################ +serdes_tx_taps_cd=pam4:-36:118:0:8:6:0 + + diff --git a/device/delta/x86_64-delta_agc032-r0/custom_led.bin b/device/delta/x86_64-delta_agc032-r0/custom_led.bin new file mode 100644 index 000000000000..e91edee19815 Binary files /dev/null and b/device/delta/x86_64-delta_agc032-r0/custom_led.bin differ diff --git a/device/delta/x86_64-delta_agc032-r0/default_sku b/device/delta/x86_64-delta_agc032-r0/default_sku new file mode 100644 index 000000000000..afc35fa094b0 --- /dev/null +++ b/device/delta/x86_64-delta_agc032-r0/default_sku @@ -0,0 +1 @@ +Delta-agc032 t1 \ No newline at end of file diff --git a/device/delta/x86_64-delta_agc032-r0/fancontrol b/device/delta/x86_64-delta_agc032-r0/fancontrol new file mode 100644 index 000000000000..83805adc6804 --- /dev/null +++ b/device/delta/x86_64-delta_agc032-r0/fancontrol @@ -0,0 +1,10 @@ +INTERVAL=10 +DEVPATH=hwmon1=/sys/bus/i2c/devices +DEVNAME=hwmon1=emc2305 +FCTEMPS= hwmon1/i2c-4/4-004f/hwmon/hwmon*/temp1_input hwmon1/i2c-5/5-004a/hwmon/hwmon*/temp1_input hwmon1/i2c-5/5-004d/hwmon/hwmon*/temp1_input hwmon1/i2c-5/5-004b/hwmon/hwmon*/temp1_input hwmon1/i2c-5/5-0049/hwmon/hwmon*/temp1_input hwmon1/i2c-5/5-004e/hwmon/hwmon*/temp1_input + +FCFANS=hwmon1/4-004c/fan1_input hwmon1/4-004c/fan2_input hwmon1/4-004c/fan3_input hwmon1/4-004c/fan4_input hwmon1/4-004c/fan5_input hwmon1/4-002d/fan1_input hwmon1/4-002d/fan2_input hwmon1/4-002d/fan3_input hwmon1/4-002d/fan4_input hwmon1/4-002d/fan5_input hwmon1/4-002e/fan1_input hwmon1/4-002e/fan2_input +MINTEMP=20 +MAXTEMP=60 +MINSTART=75 +MINSTOP=22 diff --git a/device/delta/x86_64-delta_agc032-r0/fancontrol.service b/device/delta/x86_64-delta_agc032-r0/fancontrol.service new file mode 100755 index 000000000000..2052d1c34bb7 --- /dev/null +++ b/device/delta/x86_64-delta_agc032-r0/fancontrol.service @@ -0,0 +1,295 @@ +#!/bin/bash +# +# Simple script implementing a temperature dependent fan speed control +# Supported Linux kernel versions: 2.6.5 and later +# +# Version 0.70 +# +# Usage: fancontrol [CONFIGFILE] +# +# Dependencies: +# bash, egrep, sed, cut, sleep, readlink, lm_sensors :) +# +# Please send any questions, comments or success stories to +# marius.reiner@hdev.de +# Thanks! +# +# For configuration instructions and warnings please see fancontrol.txt, which +# can be found in the doc/ directory or at the website mentioned above. +# +# +# Copyright 2003 Marius Reiner +# Copyright (C) 2007-2009 Jean Delvare +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301 USA. +# +# + +PIDFILE="/var/run/fancontrol.pid" + +#DEBUG=1 +MAX=255 + +function LoadConfig +{ + local fcvcount fcv + + echo "Loading configuration from $1 ..." + if [ ! -r "$1" ] + then + echo "Error: Can't read configuration file" >&2 + exit 1 + fi + + # grep configuration from file + INTERVAL=`egrep '^INTERVAL=.*$' $1 | sed -e 's/INTERVAL=//g'` + DEVPATH=`egrep '^DEVPATH=.*$' $1 | sed -e 's/DEVPATH= *//g'` + DEVNAME=`egrep '^DEVNAME=.*$' $1 | sed -e 's/DEVNAME= *//g'` + FCTEMPS=`egrep '^FCTEMPS=.*$' $1 | sed -e 's/FCTEMPS=//g'` + MINTEMP=`egrep '^MINTEMP=.*$' $1 | sed -e 's/MINTEMP=//g'` + MAXTEMP=`egrep '^MAXTEMP=.*$' $1 | sed -e 's/MAXTEMP=//g'` + MINSTART=`egrep '^MINSTART=.*$' $1 | sed -e 's/MINSTART=//g'` + MINSTOP=`egrep '^MINSTOP=.*$' $1 | sed -e 's/MINSTOP=//g'` + HWMON=$( echo "$DEVPATH" | sed 's/=.*$//g') + FCDEVPATH=$( echo "$DEVPATH" | sed 's/^.*=//g') + FCMINTEMP=$MINTEMP + FCMAXTEMP=$MAXTEMP + FCMINSTART=$MINSTART + FCMINSTOP=$MINSTOP + AFCTEMP_1_LOWER=(00 39 36 41 46 55) + AFCTEMP_1_UPPER=(39 39 44 49 54 150) + AFCTEMP_2_LOWER=(00 61 65 69 73 82) + AFCTEMP_2_UPPER=(63 67 71 75 79 150) + AFCTEMP_3_LOWER=(00 51 55 59 63 71) + AFCTEMP_3_UPPER=(53 57 61 65 69 150) + AFCTEMP_4_LOWER=(00 46 50 54 58 65) + AFCTEMP_4_UPPER=(45 52 56 60 64 150) + AFCTEMP_5_LOWER=(00 46 50 54 58 65) + AFCTEMP_5_UPPER=(45 52 56 60 64 150) + + + FCFANS=`egrep '^FCFANS=.*$' $1 | sed -e 's/FCFANS=//g'` + + # Check whether all mandatory settings are set + if [[ -z ${INTERVAL} || -z ${FCTEMPS} || -z ${MINTEMP} || -z ${MAXTEMP} || -z ${MINSTART} || -z ${MINSTOP} ]] + then + echo "Some mandatory settings missing, please check your config file!" >&2 + exit 1 + fi + if [ "$INTERVAL" -le 0 ] + then + echo "Error in configuration file:" >&2 + echo "INTERVAL must be at least 1" >&2 + exit 1 + fi + + # write settings to arrays for easier use and print them + echo + echo "Common settings:" + + temp_string=$FCTEMPS + + let fcvcount=0 + for fcv in $FCTEMPS + do + fcvcount=$((fcvcount+1)) + AFCTEMP[$fcvcount]=$( echo "$temp_string" | cut -d" " -f $fcvcount ) + AFCTEMP[$fcvcount]=$( echo "${AFCTEMP[$fcvcount]}" | sed 's/hwmon1/\/sys\/bus\/i2c\/devices/g' ) + AFCTEMP_PATH[$fcvcount]=$( echo "${AFCTEMP[$fcvcount]}" | sed 's/hwmon1/\/sys\/bus\/i2c\/devices/g' ) + AFCTEMP[$fcvcount]=$( cat ${AFCTEMP[$fcvcount]} ) + AFCTEMP[$fcvcount]=$(( AFCTEMP[$fcvcount]/1000 )) + done + + fan_string=$FCFANS + fcvcount=0 + zero=0 + for fcv in $FCFANS + do + fcvcount=$((fcvcount+1)) + AFCFAN[$fcvcount]=$( echo "$fan_string" | cut -d" " -f $fcvcount ) + AFCFAN_PATH[$fcvcount]=$( echo "${AFCFAN[$fcvcount]}" | sed 's/hwmon1/\/sys\/bus\/i2c\/devices/g' ) + AFCFAN_TARGET[$fcvcount]=$( echo "${AFCFAN_PATH[$fcvcount]}" | sed 's/hwmon1/\/sys\/bus\/i2c\/devices/g' ) + AFCFAN_TARGET[$fcvcount]=$( echo "${AFCFAN_TARGET[$fcvcount]}" | sed 's/$/_percentage/g') + AFCFAN[$fcvcount]=$( cat ${AFCFAN_PATH[$fcvcount]} ) + if [ "${AFCFAN[$fcvcount]}" == 960 ] + then + AFCFAN[$fcvcount]=$zero + fi + done +} + +# Check that all referenced sysfs files exist +function CheckFiles +{ + local outdated=0 fcvcount tsen fan + if [ $outdated -eq 1 ] + then + echo >&2 + echo "At least one referenced file is missing. Either some required kernel" >&2 + echo "modules haven't been loaded, or your configuration file is outdated." >&2 + echo "In the latter case, you should run pwmconfig again." >&2 + fi + return $outdated +} + +#LoadConfig $1 +if [ -f "$1" ] +then + LoadConfig $1 +else + LoadConfig /etc/fancontrol +fi + +# Detect path to sensors +if [ ! -d $DIR ] +then + echo $0: 'No sensors found! (did you load the necessary modules?)' >&2 + exit 1 +fi +cd $DIR + +# Check for configuration change +if [ "$DIR" != "/" ] && [ -z "$DEVPATH" -o -z "$DEVNAME" ] +then + echo "Configuration is too old, please run pwmconfig again" >&2 + exit 1 +fi +if [ "$DIR" = "/" -a -n "$DEVPATH" ] +then + echo "Unneeded DEVPATH with absolute device paths" >&2 + exit 1 +fi +CheckFiles || exit 1 + +if [ -f "$PIDFILE" ] +then + echo "File $PIDFILE exists, is fancontrol already running?" >&2 + exit 1 +fi +echo $$ > "$PIDFILE" + +# main function +function UpdateThermalSensors +{ + fcvcount=0 + for fcv in $FCTEMPS + do + fcvcount=$((fcvcount+1)) + AFCTEMP[$fcvcount]=$( cat ${AFCTEMP_PATH[$fcvcount]} ) + AFCTEMP[$fcvcount]=$(( AFCTEMP[$fcvcount]/1000 )) + done +} + +function UpdateThermalLevel +{ + AFCTEMP_NUM=$((6-${AFCTEMP_LEVEL[$i]})) + AFCTEMP_UPPER_BUF=AFCTEMP_"$i"_UPPER["$AFCTEMP_NUM"] + AFCTEMP_LOWER_BUF=AFCTEMP_"$i"_LOWER["$AFCTEMP_NUM"] + + AFCTEMP_UPPER=${!AFCTEMP_UPPER_BUF} + AFCTEMP_LOWER=${!AFCTEMP_LOWER_BUF} + + + if (( ("${AFCTEMP[$i]}" <= "$AFCTEMP_UPPER") && ("${AFCTEMP[$i]}" >= "$AFCTEMP_LOWER") )) ; then + FLAG=2 + elif (( "${AFCTEMP[$i]}" > "$AFCTEMP_UPPER" )); then + AFCTEMP_LEVEL[$i]=$((${AFCTEMP_LEVEL[$i]} - 1)) + FLAG=1 + elif (( "${AFCTEMP[$i]}" < "$AFCTEMP_LOWER" )); then + AFCTEMP_LEVEL[$i]=$((${AFCTEMP_LEVEL[$i]} + 1)) + FLAG=1 + else + AFCTEMP_LEVEL[$i]=1 + FLAG=2 + fi +} + +function UpdateFanSpeeds +{ + #echo "num tmp lev F L H" + #Update level + for i in 1 2 3 4 5 + do + #echo "----------------------" + FLAG=0 + #FLAG=0 : initial flag + #FLAG=1 : update level + #FLAG=2 : final level + while [ $FLAG -ne 2 ] + do + UpdateThermalLevel + #echo " $i ${AFCTEMP[$i]} ${AFCTEMP_LEVEL[$i]} $FLAG $AFCTEMP_LOWER $AFCTEMP_UPPER " + done + done + + min=${AFCTEMP_LEVEL[0]} + for j in "${AFCTEMP_LEVEL[@]}"; do + (( j < min )) && min=$j + done + + if (($min == 1 || $min == 2)); then + FAN_PERCENTAGE=100 + elif (($min == 3)); then + FAN_PERCENTAGE=80 + elif (($min == 4)); then + FAN_PERCENTAGE=60 + elif (($min == 5)); then + FAN_PERCENTAGE=50 + elif (($min == 6)); then + FAN_PERCENTAGE=40 + else + FAN_PERCENTAGE=100 + fi + echo "The lowest level of thermal sensors: $min " + echo "Trying to set fan speed to $FAN_PERCENTAGE %" + #Set speed to fan1~fan10 + let fcvcount=0 + for fcv in $FCFANS + do + fcvcount=$(( fcvcount + 1 )) + echo $FAN_PERCENTAGE > ${AFCFAN_TARGET[$fcvcount]} + AFCFAN[$fcvcount]=$( cat ${AFCFAN_PATH[$fcvcount]} ) + + if [ "${AFCFAN[$fcvcount]}" == 960 ] + then + AFCFAN[$fcvcount]=$zero + fi + echo "FAN fan$fcvcount = ${AFCFAN[$fcvcount]} (rpm)" + done + + FAN_ON_PSU_PERCENTAGE=$FAN_PERCENTAGE + #Set speed to PSU_FAN1 + echo "$FAN_ON_PSU_PERCENTAGE" > '/sys/bus/i2c/devices/1-0058/fan1_set_percentage' + echo "PSU fan1 =$( cat '/sys/bus/i2c/devices/1-0058/fan1_input' ) (rpm)" + #Set speed to PSU_FAN2 + echo "$FAN_ON_PSU_PERCENTAGE" > '/sys/bus/i2c/devices/2-0058/fan1_set_percentage' + echo "PSU fan2 =$( cat '/sys/bus/i2c/devices/2-0058/fan1_input' ) (rpm)" + + rm -f "$PIDFILE" +} + +# main loop calling the main function at specified intervals +AFCTEMP_LEVEL=(9 4 4 4 4 4) #inttial level +while true +do + UpdateThermalSensors + UpdateFanSpeeds + echo "Sleep $INTERVAL seconds ..." + echo + # Sleep while still handling signals + sleep $INTERVAL & + wait $! +done diff --git a/device/delta/x86_64-delta_agc032-r0/installer.conf b/device/delta/x86_64-delta_agc032-r0/installer.conf new file mode 100644 index 000000000000..925a32fc0c3a --- /dev/null +++ b/device/delta/x86_64-delta_agc032-r0/installer.conf @@ -0,0 +1,3 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 +CONSOLE_SPEED=115200 diff --git a/device/delta/x86_64-delta_agc032-r0/led_proc_init.soc b/device/delta/x86_64-delta_agc032-r0/led_proc_init.soc new file mode 100644 index 000000000000..5dcf85ea7956 --- /dev/null +++ b/device/delta/x86_64-delta_agc032-r0/led_proc_init.soc @@ -0,0 +1,5 @@ +led auto off +led stop +m0 load 0 0x3800 /usr/share/sonic/platform/custom_led.bin +led auto on +led start diff --git a/device/delta/x86_64-delta_agc032-r0/platform_env.conf b/device/delta/x86_64-delta_agc032-r0/platform_env.conf new file mode 100644 index 000000000000..283e1c0ce710 --- /dev/null +++ b/device/delta/x86_64-delta_agc032-r0/platform_env.conf @@ -0,0 +1 @@ +usemsi=1 diff --git a/device/delta/x86_64-delta_agc032-r0/plugins/eeprom.py b/device/delta/x86_64-delta_agc032-r0/plugins/eeprom.py new file mode 100644 index 000000000000..c252fd69f678 --- /dev/null +++ b/device/delta/x86_64-delta_agc032-r0/plugins/eeprom.py @@ -0,0 +1,12 @@ +try: + from sonic_eeprom import eeprom_tlvinfo +except ImportError as 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/devices/pci0000:00/0000:00:1f.3/i2c-0/0-0053/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/delta/x86_64-delta_agc032-r0/plugins/psuutil.py b/device/delta/x86_64-delta_agc032-r0/plugins/psuutil.py new file mode 100644 index 000000000000..0cb47cad1bf9 --- /dev/null +++ b/device/delta/x86_64-delta_agc032-r0/plugins/psuutil.py @@ -0,0 +1,60 @@ +import os.path + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + PsuBase.__init__(self) + + self.psu_path = "/sys/bus/i2c/devices/{}-0058/" + self.psu_oper_status = "in1_input" + self.psu_oper_status2 = "in2_input" + self.psu_presence = "i2cget -y {} 0x50 0x00" + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + + :return: An integer, the number of PSUs available on the device + """ + return 2 + + def get_psu_status(self, index): + if index is None: + return False + Base_bus_number = 0 + status = 0 + # index from 1, psu attribute bus from 40 + try: + with open(self.psu_path.format(index + Base_bus_number) + self.psu_oper_status, 'r') as power_status: + if int(power_status.read()) == 0: + return False + else: + with open(self.psu_path.format(index + Base_bus_number) + self.psu_oper_status2, 'r') as power_status2: + if int(power_status2.read()) == 0: + return False + else: + status = 1 + except IOError: + return False + return status == 1 + + def get_psu_presence(self, index): + if index is None: + return False + Base_bus_number = 0 + status = 0 + try: + p = os.popen(self.psu_presence.format(index + Base_bus_number) + "> /dev/null 2>&1") + if p.readline() != None: + status = 1 + p.close() + except IOError: + return False + return status == 1 diff --git a/device/delta/x86_64-delta_agc032-r0/plugins/sfputil.py b/device/delta/x86_64-delta_agc032-r0/plugins/sfputil.py new file mode 100644 index 000000000000..e9b02c6c77c6 --- /dev/null +++ b/device/delta/x86_64-delta_agc032-r0/plugins/sfputil.py @@ -0,0 +1,242 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# + +try: + import time + from sonic_sfp.sfputilbase import SfpUtilBase + from sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_sfp.sff8436 import sff8436Dom +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + PORT_START = 0 + PORT_END = 33 + PORTS_IN_BLOCK = 32 + + EEPROM_OFFSET = 1 + + CPLD_SWITCH = 0 + + _port_to_eeprom_mapping = {} + + @property + def port_start(self): + return self.PORT_START + + @property + def port_end(self): + return self.PORT_END + + @property + def qsfp_ports(self): + return list(range(0, self.PORTS_IN_BLOCK)) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + def __init__(self): + eeprom_path = "/sys/bus/i2c/devices/{0}-0050/eeprom" + + for x in range(0, self.port_end + 1): + self._port_to_eeprom_mapping[x] = eeprom_path.format(x + self.EEPROM_OFFSET) + + SfpUtilBase.__init__(self) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + # Retrieve file path of presence + port = (str(port_num + 1)).zfill(2) + + # SWPLD2 for port 1~16, SWPLD3 for port 17~34 + if port_num < 16: + present_path = "SWPLD2/qsfp_p{}_modprs".format(port) + elif port_num < self.PORTS_IN_BLOCK: + present_path = "SWPLD3/qsfp_p{}_modprs".format(port) + else: + present_path = "SWPLD3/sfp_p{}_modprs".format(str(port_num - self.PORTS_IN_BLOCK)) + + try: + with open("/sys/devices/platform/delta-agc032-swpld.0/" + present_path, 'r') as present: + if int(present.readline()) == 0: + return True + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + return False + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num >= self.PORTS_IN_BLOCK: + return False + + # Retrieve file path of presence + port = (str(port_num + 1)).zfill(2) + + # SWPLD2 for port 1~16, SWPLD3 for port 17~32 + if port_num < 16: + lpmode_path = "SWPLD2/qsfp_p{}_lpmode".format(port) + else: + lpmode_path = "SWPLD3/qsfp_p{}_lpmode".format(port) + + try: + with open("/sys/devices/platform/delta-agc032-swpld.0/" + lpmode_path, 'r') as lpmode: + if int(lpmode.readline()) == 1: + return True + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + return False + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self.port_start or port_num >= self.PORTS_IN_BLOCK: + return False + + # Retrieve file path of presence + port = (str(port_num + 1)).zfill(2) + + # SWPLD2 for port 1~16, SWPLD3 for port 17~32 + if port_num < 16: + lpmode_path = "SWPLD2/qsfp_p{}_lpmode".format(port) + else: + lpmode_path = "SWPLD3/qsfp_p{}_lpmode".format(port) + + try: + file = open("/sys/devices/platform/delta-agc032-swpld.0/" + lpmode_path, 'r+') + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + file.seek(0) + if lpmode is True: + # "1" for lpmode on + file.write('1') + else: + # "0" for lpmode off + file.write('0') + file.close() + + return True + + def reset(self, port_num): + + # Check for invalid port_num + if port_num < self.port_start or port_num >= self.PORTS_IN_BLOCK: + return False + + # Retrieve file path of presence + port = (str(port_num + 1)).zfill(2) + + # SWPLD2 for port 1~16, SWPLD3 for port 17~32 + if port_num < 16: + reset_path = "SWPLD2/qsfp_p{}_rst".format(port) + else: + reset_path = "SWPLD3/qsfp_p{}_rst".format(port) + + try: + file = open("/sys/devices/platform/delta-agc032-swpld.0/" + reset_path, 'r+') + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + file.seek(0) + file.write('0') + file.close() + + # Sleep 1 second to allow it to settle + time.sleep(1) + + # Flip the bit back high and write back to the register to take port out of reset + try: + file = open("/sys/devices/platform/delta-agc032-swpld.0/" + reset_path, 'r+') + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + file.seek(0) + file.write('1') + file.close() + + return True + + def get_eeprom_dict(self, port_num): + sfp_data = {} + + try: + file = open("/sys/devices/platform/delta-agc032-cpupld.0/cpu_i2c_mux_sel", 'r+') + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + # Switch CPLD to FRONT-PORT EEPROM MUX + file.seek(0) + file.write('3') + file.close() + + eeprom_ifraw = self.get_eeprom_raw(port_num) + eeprom_domraw = self.get_eeprom_dom_raw(port_num) + + try: + file = open("/sys/devices/platform/delta-agc032-cpupld.0/cpu_i2c_mux_sel", 'r+') + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + # Switch CPLD to FRONT-PORT EEPROM MUX + file.seek(0) + file.write('1') + file.close() + + if eeprom_ifraw is None: + return None + + if port_num in self.osfp_ports: + sfpi_obj = inf8628InterfaceId(eeprom_ifraw) + if sfpi_obj is not None: + sfp_data['interface'] = sfpi_obj.get_data_pretty() + return sfp_data + elif port_num in self.qsfp_ports: + sfpi_obj = sff8436InterfaceId(eeprom_ifraw) + if sfpi_obj is not None: + sfp_data['interface'] = sfpi_obj.get_data_pretty() + # For Qsfp's the dom data is part of eeprom_if_raw + # The first 128 bytes + + sfpd_obj = sff8436Dom(eeprom_ifraw) + if sfpd_obj is not None: + sfp_data['dom'] = sfpd_obj.get_data_pretty() + + return sfp_data + else: + sfpi_obj = sff8472InterfaceId(eeprom_ifraw) + if sfpi_obj is not None: + sfp_data['interface'] = sfpi_obj.get_data_pretty() + cal_type = sfpi_obj.get_calibration_type() + + if eeprom_domraw is not None: + sfpd_obj = sff8472Dom(eeprom_domraw, cal_type) + if sfpd_obj is not None: + sfp_data['dom'] = sfpd_obj.get_data_pretty() + + return sfp_data + + 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 diff --git a/device/delta/x86_64-delta_agc032-r0/pmon_daemon_control.json b/device/delta/x86_64-delta_agc032-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..d5784cc779f7 --- /dev/null +++ b/device/delta/x86_64-delta_agc032-r0/pmon_daemon_control.json @@ -0,0 +1,6 @@ +{ + "skip_thermalctld": true, + "skip_syseepromd": true, + "skip_fancontrol": true, + "skip_xcvrd": true +} diff --git a/device/delta/x86_64-delta_agc032-r0/sensors.conf b/device/delta/x86_64-delta_agc032-r0/sensors.conf new file mode 100644 index 000000000000..7df258da28c1 --- /dev/null +++ b/device/delta/x86_64-delta_agc032-r0/sensors.conf @@ -0,0 +1,47 @@ +# libsensors configuration file for DCS-7060CX-32S +# ------------------------------------------------ +# + +bus "i2c-4" "i2c-0-mux (chan_id 3)" +bus "i2c-5" "i2c-0-mux (chan_id 4)" + +chip "tmp75-i2c-4-4f" + label temp1 "Wind thermal sensor" + set temp1_max 65 + set temp1_max_hyst 60 +chip "tmp75-i2c-5-4d" + label temp1 "CPU below side thermal sensor" + set temp1_max 60 + set temp1_max_hyst 55 +chip "tmp75-i2c-5-49" + label temp1 "Surroundings thermal sensor1" + set temp1_max 65 + set temp1_max_hyst 60 +chip "tmp75-i2c-5-4a" + label temp1 "Surroundings thermal sensor2" + set temp1_max 65 + set temp1_max_hyst 60 +chip "tmp75-i2c-5-4b" + label temp1 "Surroundings thermal sensor3" + set temp1_max 65 + set temp1_max_hyst 60 +chip "tmp75-i2c-5-4d" + label temp1 "Surroundings thermal sensor4" + set temp1_max 65 + set temp1_max_hyst 60 + +chip "emc2305-i2c-4-4c" + label fan1 "FANTRAY 1 FRONT" + label fan2 "FANTRAY 2 REAR" + label fan3 "FANTRAY 3 FRONT" + label fan4 "FANTRAY 4 REAR" + label fan5 "FANTRAY 5 FRONT" +chip "emc2305-i2c-4-2d" + label fan1 "FANTRAY 1 REAR" + label fan2 "FANTRAY 2 FRONT" + label fan3 "FANTRAY 3 REAR" + label fan4 "FANTRAY 4 FRONT" + label fan5 "FANTRAY 5 REAR" +chip "emc2302-i2c-4-2e" + label fan1 "FANTRAY 1 FRONT" + label fan2 "FANTRAY 2 REAR" diff --git a/device/delta/x86_64-delta_et-6248brb-r0/Delta-et-6248brb/sai.profile b/device/delta/x86_64-delta_et-6248brb-r0/Delta-et-6248brb/sai.profile index 726e1b6dc667..20e067d8eda7 100644 --- a/device/delta/x86_64-delta_et-6248brb-r0/Delta-et-6248brb/sai.profile +++ b/device/delta/x86_64-delta_et-6248brb-r0/Delta-et-6248brb/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/etc/bcm/helix4-et-6248brb-48x1G+2x10G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/delta/x86_64-delta_et-6248brb-r0/plugins/eeprom.py b/device/delta/x86_64-delta_et-6248brb-r0/plugins/eeprom.py index 11c9285f47db..3b4b15ee543b 100644 --- a/device/delta/x86_64-delta_et-6248brb-r0/plugins/eeprom.py +++ b/device/delta/x86_64-delta_et-6248brb-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Mellanox # @@ -10,7 +8,6 @@ ############################################################################# try: - import exceptions import binascii import time import optparse @@ -20,13 +17,14 @@ 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") +except ImportError as 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/devices/pci0000:00/0000:00:13.0/i2c-1/1-0054/eeprom" - super(board, self).__init__(self.eeprom_path, 0, '', True) + self.eeprom_path = "/sys/devices/pci0000:00/0000:00:13.0/i2c-1/1-0054/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/delta/x86_64-delta_et-6248brb-r0/plugins/psuutil.py b/device/delta/x86_64-delta_et-6248brb-r0/plugins/psuutil.py index 99e8f1d17dd8..c6ec180bfc06 100644 --- a/device/delta/x86_64-delta_et-6248brb-r0/plugins/psuutil.py +++ b/device/delta/x86_64-delta_et-6248brb-r0/plugins/psuutil.py @@ -3,7 +3,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" @@ -15,7 +16,6 @@ def __init__(self): self.psu_oper_status = "in1_input" self.psu_presence = "/sys/devices/platform/delta-et6248brb-gpio.0/PSU/psu{}_pres" - def get_num_psus(self): """ Retrieves the number of PSUs available on the device @@ -31,7 +31,7 @@ def get_psu_status(self, index): try: reg_file = open(self.psu_path.format(index)) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False if int(reg_file.readline()) == 1: @@ -46,7 +46,7 @@ def get_psu_presence(self, index): try: reg_file = open(self.psu_presence.format(index)) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False if int(reg_file.readline()) == 0: diff --git a/device/delta/x86_64-delta_et-6248brb-r0/plugins/sfputil.py b/device/delta/x86_64-delta_et-6248brb-r0/plugins/sfputil.py index 84a3bfc3dac0..c8d30d3beeeb 100644 --- a/device/delta/x86_64-delta_et-6248brb-r0/plugins/sfputil.py +++ b/device/delta/x86_64-delta_et-6248brb-r0/plugins/sfputil.py @@ -31,7 +31,7 @@ def port_end(self): @property def qsfp_ports(self): - return range(0) + return list(range(0)) @property def port_to_eeprom_mapping(self): @@ -52,13 +52,13 @@ 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 - + presence_path = "/sys/devices/platform/delta-et6248brb-gpio.0/SFP/sfp_mod_p{}" try: reg_file = open(presence_path.format(port_num - 47)) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False if int(reg_file.readline()) == 0: diff --git a/device/delta/x86_64-delta_et-c032if-r0/plugins/eeprom.py b/device/delta/x86_64-delta_et-c032if-r0/plugins/eeprom.py index 1a624414637c..23376fcd7236 100644 --- a/device/delta/x86_64-delta_et-c032if-r0/plugins/eeprom.py +++ b/device/delta/x86_64-delta_et-c032if-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Mellanox # @@ -10,7 +8,6 @@ ############################################################################# try: - import exceptions import binascii import time import optparse @@ -20,13 +17,14 @@ 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") +except ImportError as 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/devices/pci0000:00/0000:00:1f.3/i2c-0/i2c-10/10-0053/eeprom" - super(board, self).__init__(self.eeprom_path, 0, '', True) + self.eeprom_path = "/sys/devices/pci0000:00/0000:00:1f.3/i2c-0/i2c-10/10-0053/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/delta/x86_64-delta_et-c032if-r0/plugins/psuutil.py b/device/delta/x86_64-delta_et-c032if-r0/plugins/psuutil.py index 80383aaffddf..4eb3bb87db80 100644 --- a/device/delta/x86_64-delta_et-c032if-r0/plugins/psuutil.py +++ b/device/delta/x86_64-delta_et-c032if-r0/plugins/psuutil.py @@ -9,7 +9,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" @@ -44,15 +45,13 @@ def get_psu_status(self, index): reg_value = int(content, 16) mask = (1 << (8 - index)) if reg_value & mask == 0: - return False + return False status = 1 p.close() except IOError: return False return status == 1 - - def get_psu_presence(self, index): """ Retrieves the presence status of power supply unit (PSU) defined @@ -75,4 +74,3 @@ def get_psu_presence(self, index): except IOError: return False return status == 1 - diff --git a/device/delta/x86_64-delta_et-c032if-r0/plugins/sfputil.py b/device/delta/x86_64-delta_et-c032if-r0/plugins/sfputil.py index 4802c3a8f0ce..25b1ba3abdeb 100644 --- a/device/delta/x86_64-delta_et-c032if-r0/plugins/sfputil.py +++ b/device/delta/x86_64-delta_et-c032if-r0/plugins/sfputil.py @@ -16,7 +16,7 @@ class SfpUtil(SfpUtilBase): PORT_START = 0 PORT_START_SFP = 32 - PORT_END = 33 + PORT_END = 33 PORTS_IN_BLOCK = 34 EEPROM_OFFSET = 1 @@ -38,7 +38,7 @@ def port_end(self): @property def qsfp_ports(self): - return range(0, self.PORTS_IN_BLOCK + 1) + return list(range(0, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -51,7 +51,7 @@ def get_transceiver_status(self): reg_file = open("/sys/devices/platform/delta-et-c032if-cpld.0/sfp_is_present") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -60,7 +60,6 @@ def get_transceiver_status(self): return int(content, 16) - def __init__(self): eeprom_path = "/sys/kernel/sfp/eeprom_sfp_{0}" @@ -78,7 +77,7 @@ def get_presence(self, port_num): try: reg_file = open("/sys/devices/platform/delta-et-c032if-cpld.0/sfp_is_present") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -103,7 +102,7 @@ def get_low_power_mode(self, port_num): try: reg_file = open("/sys/devices/platform/delta-et-c032if-cpld.0/sfp_lp_mode") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) content = reg_file.readline().rstrip() @@ -127,7 +126,7 @@ def set_low_power_mode(self, port_num, lpmode): try: reg_file = open("/sys/devices/platform/delta-et-c032if-cpld.0/sfp_lp_mode", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -163,7 +162,7 @@ def reset(self, port_num): try: reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -189,7 +188,7 @@ def reset(self, port_num): try: reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "w") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = reg_value | mask @@ -207,17 +206,17 @@ def get_transceiver_change_event(self, timeout=0): if timeout == 0: forever = True elif timeout > 0: - timeout = timeout / float(1000) # Convert to secs + timeout = timeout / float(1000) # Convert to secs else: - print "get_transceiver_change_event:Invalid timeout value", timeout + print("get_transceiver_change_event:Invalid timeout value", timeout) return False, {} end_time = start_time + timeout if start_time > end_time: - print 'get_transceiver_change_event:' \ - 'time wrap / invalid timeout value', timeout + print('get_transceiver_change_event:' + 'time wrap / invalid timeout value', timeout) - return False, {} # Time wrap or possibly incorrect timeout + return False, {} # Time wrap or possibly incorrect timeout while timeout >= 0: # Check for OIR events and return updated port_dict reg_value = self.get_transceiver_status @@ -246,10 +245,10 @@ def get_transceiver_change_event(self, timeout=0): else: timeout = end_time - time.time() if timeout >= 1: - time.sleep(1) # We poll at 1 second granularity + time.sleep(1) # We poll at 1 second granularity else: if timeout > 0: time.sleep(timeout) return True, {} - print "get_transceiver_change_event: Should not reach here." + print("get_transceiver_change_event: Should not reach here.") return False, {} diff --git a/device/embedway/x86_64-ew_es6220_x48q2h4-r0/default_sku b/device/embedway/x86_64-ew_es6220_x48q2h4-r0/default_sku deleted file mode 100644 index 0f663505d7a4..000000000000 --- a/device/embedway/x86_64-ew_es6220_x48q2h4-r0/default_sku +++ /dev/null @@ -1 +0,0 @@ -OSW1800-48x6q t1 diff --git a/device/embedway/x86_64-ew_es6220_x48q2h4-r0/installer.conf b/device/embedway/x86_64-ew_es6220_x48q2h4-r0/installer.conf deleted file mode 100644 index 5e62742c11bf..000000000000 --- a/device/embedway/x86_64-ew_es6220_x48q2h4-r0/installer.conf +++ /dev/null @@ -1 +0,0 @@ -CONSOLE_SPEED=115200 diff --git a/device/facebook/x86_64-facebook_wedge100-r0/Facebook-W100-C32/sai.profile b/device/facebook/x86_64-facebook_wedge100-r0/Facebook-W100-C32/sai.profile index b5586b7ba24c..426284150a0d 100644 --- a/device/facebook/x86_64-facebook_wedge100-r0/Facebook-W100-C32/sai.profile +++ b/device/facebook/x86_64-facebook_wedge100-r0/Facebook-W100-C32/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-wedge100-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/ingrasys/x86_64-ingrasys_s8810_32q-r0/INGRASYS-S8810-32Q/sai.profile b/device/ingrasys/x86_64-ingrasys_s8810_32q-r0/INGRASYS-S8810-32Q/sai.profile index 42315ee4ea6a..3205cd2d6ad9 100644 --- a/device/ingrasys/x86_64-ingrasys_s8810_32q-r0/INGRASYS-S8810-32Q/sai.profile +++ b/device/ingrasys/x86_64-ingrasys_s8810_32q-r0/INGRASYS-S8810-32Q/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s8810-32x40G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/ingrasys/x86_64-ingrasys_s8810_32q-r0/plugins/eeprom.py b/device/ingrasys/x86_64-ingrasys_s8810_32q-r0/plugins/eeprom.py index 4f919ccd7273..8f9ee7d9989b 100644 --- a/device/ingrasys/x86_64-ingrasys_s8810_32q-r0/plugins/eeprom.py +++ b/device/ingrasys/x86_64-ingrasys_s8810_32q-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Ingrasys S8810-32Q # @@ -11,8 +9,8 @@ try: from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): diff --git a/device/ingrasys/x86_64-ingrasys_s8810_32q-r0/plugins/psuutil.py b/device/ingrasys/x86_64-ingrasys_s8810_32q-r0/plugins/psuutil.py index 7e69360b0402..fcf9136d25db 100644 --- a/device/ingrasys/x86_64-ingrasys_s8810_32q-r0/plugins/psuutil.py +++ b/device/ingrasys/x86_64-ingrasys_s8810_32q-r0/plugins/psuutil.py @@ -20,12 +20,12 @@ class PsuUtil(PsuBase): def __init__(self): PsuBase.__init__(self) - - + # Get sysfs attribute + def get_attr_value(self, attr_path): - - retval = 'ERR' + + retval = 'ERR' if (not os.path.isfile(attr_path)): return retval @@ -55,16 +55,16 @@ def get_psu_status(self, index): faulty """ status = 0 - attr_file = 'psu_pg' - attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file - + attr_file = 'psu_pg' + 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 + status = 1 return status @@ -77,16 +77,15 @@ def get_psu_presence(self, index): """ status = 0 psu_absent = 0 - attr_file ='psu_abs' - attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file - + attr_file = 'psu_abs' + 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 == 0): - status = 1 + status = 1 return status - diff --git a/device/ingrasys/x86_64-ingrasys_s8810_32q-r0/plugins/sfputil.py b/device/ingrasys/x86_64-ingrasys_s8810_32q-r0/plugins/sfputil.py index 8d195f644e18..c1afbdf0738d 100644 --- a/device/ingrasys/x86_64-ingrasys_s8810_32q-r0/plugins/sfputil.py +++ b/device/ingrasys/x86_64-ingrasys_s8810_32q-r0/plugins/sfputil.py @@ -26,7 +26,7 @@ class SfpUtil(SfpUtilBase): LP_GPIO_BASE = 160 RST_GPIO_BASE = 128 GPIO_OFFSET = 0 - + BASE_DIR_PATH = "/sys/class/gpio/gpio{0}/direction" BASE_VAL_PATH = "/sys/class/gpio/gpio{0}/value" @@ -42,7 +42,7 @@ def port_end(self): @property def qsfp_ports(self): - return range(0, self.PORTS_IN_BLOCK + 1) + return list(range(0, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -55,11 +55,11 @@ def set_gpio_offset(self): for d in os.listdir(sys_gpio_dir): if "gpiochip" in d: try: - gpiochip_no = int(d[8:],10) + gpiochip_no = int(d[8:], 10) except ValueError as e: - print "Error: %s" % str(e) + print("Error: %s" % str(e)) if gpiochip_no > 255: - self.GPIO_OFFSET=256 + self.GPIO_OFFSET = 256 return True return True @@ -89,10 +89,10 @@ def get_presence(self, port_num): try: abs_device_file = self.BASE_VAL_PATH.format( - port_num + self.ABS_GPIO_BASE) + port_num + self.ABS_GPIO_BASE) val_file = open(abs_device_file) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = val_file.readline().rstrip() @@ -110,14 +110,14 @@ def get_low_power_mode(self, port_num): try: lpmode_val_device_file = self.BASE_VAL_PATH.format( - port_num + self.LP_GPIO_BASE) + port_num + self.LP_GPIO_BASE) val_file = open(lpmode_val_device_file) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False - + content = val_file.readline().rstrip() - + # content is a string, either "0" or "1" if content == "1": return True @@ -131,12 +131,12 @@ def set_low_power_mode(self, port_num, lpmode): try: lpmode_val_device_file = self.BASE_VAL_PATH.format( - port_num + self.LP_GPIO_BASE) + port_num + self.LP_GPIO_BASE) val_file = open(lpmode_val_device_file, "w") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False - + val_file.write("1" if lpmode is True else "0") val_file.close() @@ -146,29 +146,29 @@ def reset(self, port_num): # Check for invalid port_num if port_num < self.port_start or port_num > self.port_end: return False - + try: reset_val_device_file = self.BASE_VAL_PATH.format( - port_num + self.RST_GPIO_BASE) + port_num + self.RST_GPIO_BASE) val_file = open(reset_val_device_file, "w") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False - + val_file.write("1") val_file.close() - + # Sleep 1 second to allow it to settle time.sleep(1) - + try: reset_val_device_file = self.BASE_VAL_PATH.format( - port_num + self.RST_GPIO_BASE) + port_num + self.RST_GPIO_BASE) val_file = open(reset_val_device_file, "w") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False - + val_file.write("0") val_file.close() diff --git a/device/ingrasys/x86_64-ingrasys_s8900_54xc-r0/INGRASYS-S8900-54XC/sai.profile b/device/ingrasys/x86_64-ingrasys_s8900_54xc-r0/INGRASYS-S8900-54XC/sai.profile index 29db3ecd1624..607f20f329a6 100644 --- a/device/ingrasys/x86_64-ingrasys_s8900_54xc-r0/INGRASYS-S8900-54XC/sai.profile +++ b/device/ingrasys/x86_64-ingrasys_s8900_54xc-r0/INGRASYS-S8900-54XC/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-s8900-48x25G+6x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/ingrasys/x86_64-ingrasys_s8900_54xc-r0/plugins/eeprom.py b/device/ingrasys/x86_64-ingrasys_s8900_54xc-r0/plugins/eeprom.py index 414ff38221bf..fcfaf8a27947 100644 --- a/device/ingrasys/x86_64-ingrasys_s8900_54xc-r0/plugins/eeprom.py +++ b/device/ingrasys/x86_64-ingrasys_s8900_54xc-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Dell Z9100 # @@ -11,8 +9,8 @@ try: from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): diff --git a/device/ingrasys/x86_64-ingrasys_s8900_54xc-r0/plugins/psuutil.py b/device/ingrasys/x86_64-ingrasys_s8900_54xc-r0/plugins/psuutil.py index 4f226c69fff3..ef45a0c91727 100644 --- a/device/ingrasys/x86_64-ingrasys_s8900_54xc-r0/plugins/psuutil.py +++ b/device/ingrasys/x86_64-ingrasys_s8900_54xc-r0/plugins/psuutil.py @@ -19,12 +19,12 @@ class PsuUtil(PsuBase): def __init__(self): PsuBase.__init__(self) - - + # Get sysfs attribute + def get_attr_value(self, attr_path): - - retval = 'ERR' + + retval = 'ERR' if (not os.path.isfile(attr_path)): return retval @@ -54,17 +54,17 @@ def get_psu_status(self, index): faulty """ status = 0 - mask = [ 0x08, 0x10 ] - attr_file = 'cpld_pw_good' - attr_path = self.PSU_CPLD_DIR +'/'+ attr_file - + mask = [0x08, 0x10] + attr_file = 'cpld_pw_good' + attr_path = self.PSU_CPLD_DIR + '/' + 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 & mask[index-1]): - status = 1 + status = 1 return status @@ -76,17 +76,16 @@ def get_psu_presence(self, index): :return: Boolean, True if PSU is plugged, False if not """ status = 0 - mask = [ 0x01, 0x02 ] - attr_file ='cpld_pw_abs' - attr_path = self.PSU_CPLD_DIR +'/'+ attr_file - + mask = [0x01, 0x02] + attr_file = 'cpld_pw_abs' + attr_path = self.PSU_CPLD_DIR + '/' + 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 & mask[index-1]): - status = 1 + status = 1 return status - diff --git a/device/ingrasys/x86_64-ingrasys_s8900_54xc-r0/plugins/sfputil.py b/device/ingrasys/x86_64-ingrasys_s8900_54xc-r0/plugins/sfputil.py index 586e6e189743..c7a4dfa471b6 100644 --- a/device/ingrasys/x86_64-ingrasys_s8900_54xc-r0/plugins/sfputil.py +++ b/device/ingrasys/x86_64-ingrasys_s8900_54xc-r0/plugins/sfputil.py @@ -20,7 +20,7 @@ class SfpUtil(SfpUtilBase): QSFP_PORT_START = 48 PORTS_IN_BLOCK = 54 GPIO_OFFSET = 0 - + BASE_DIR_PATH = "/sys/class/gpio/gpio{0}/direction" BASE_VAL_PATH = "/sys/class/gpio/gpio{0}/value" @@ -100,7 +100,7 @@ def port_end(self): @property def qsfp_ports(self): - return range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1) + return list(range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -113,11 +113,11 @@ def set_gpio_offset(self): for d in os.listdir(sys_gpio_dir): if "gpiochip" in d: try: - gpiochip_no = int(d[8:],10) + gpiochip_no = int(d[8:], 10) except ValueError as e: - print "Error: %s" % str(e) + print("Error: %s" % str(e)) if gpiochip_no > 255: - self.GPIO_OFFSET=256 + self.GPIO_OFFSET = 256 return True return True @@ -179,7 +179,7 @@ def init_abs_to_gpio_mapping(self): 53: 245+self.GPIO_OFFSET } return True - + def init_lpmode_to_gpio_mapping(self): self.lpmode_to_gpio_mapping = { 48: 224+self.GPIO_OFFSET, @@ -190,7 +190,7 @@ def init_lpmode_to_gpio_mapping(self): 53: 229+self.GPIO_OFFSET } return True - + def init_reset_to_gpio_mapping(self): self.reset_to_gpio_mapping = { 48: 208+self.GPIO_OFFSET, @@ -225,10 +225,10 @@ def get_presence(self, port_num): try: abs_device_file = self.BASE_VAL_PATH.format( - self.abs_to_gpio_mapping[port_num]) + self.abs_to_gpio_mapping[port_num]) val_file = open(abs_device_file) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = val_file.readline().rstrip() @@ -246,14 +246,14 @@ def get_low_power_mode(self, port_num): try: lpmode_val_device_file = self.BASE_VAL_PATH.format( - self.lpmode_to_gpio_mapping[port_num]) + self.lpmode_to_gpio_mapping[port_num]) val_file = open(lpmode_val_device_file) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False - + content = val_file.readline().rstrip() - + # content is a string, either "0" or "1" if content == "1": return True @@ -267,12 +267,12 @@ def set_low_power_mode(self, port_num, lpmode): try: lpmode_val_device_file = self.BASE_VAL_PATH.format( - self.lpmode_to_gpio_mapping[port_num]) + self.lpmode_to_gpio_mapping[port_num]) val_file = open(lpmode_val_device_file, "w") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False - + val_file.write("1" if lpmode is True else "0") val_file.close() @@ -281,32 +281,32 @@ def set_low_power_mode(self, port_num, lpmode): def reset(self, port_num): # Check for invalid port_num if port_num < self.qsfp_port_start or port_num > self.port_end: - print "Error: unable to reset non-QSFP module: port %s" % str(port_num) + print("Error: unable to reset non-QSFP module: port %s" % str(port_num)) return False - + try: - print "port %s" % str(port_num) + print("port %s" % str(port_num)) reset_val_device_file = self.BASE_VAL_PATH.format( - self.reset_to_gpio_mapping[port_num]) + self.reset_to_gpio_mapping[port_num]) val_file = open(reset_val_device_file, "w") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False - + val_file.write("1") val_file.close() - + # Sleep 1 second to allow it to settle time.sleep(1) - + try: reset_val_device_file = self.BASE_VAL_PATH.format( - self.reset_to_gpio_mapping[port_num]) + self.reset_to_gpio_mapping[port_num]) val_file = open(reset_val_device_file, "w") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False - + val_file.write("0") val_file.close() diff --git a/device/ingrasys/x86_64-ingrasys_s8900_64xc-r0/INGRASYS-S8900-64XC/sai.profile b/device/ingrasys/x86_64-ingrasys_s8900_64xc-r0/INGRASYS-S8900-64XC/sai.profile index 77a0e3efa431..1100f7199a3e 100644 --- a/device/ingrasys/x86_64-ingrasys_s8900_64xc-r0/INGRASYS-S8900-64XC/sai.profile +++ b/device/ingrasys/x86_64-ingrasys_s8900_64xc-r0/INGRASYS-S8900-64XC/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-s8900-48x25G+16x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/ingrasys/x86_64-ingrasys_s8900_64xc-r0/plugins/eeprom.py b/device/ingrasys/x86_64-ingrasys_s8900_64xc-r0/plugins/eeprom.py index 1b8de3f16bca..1737549081a6 100644 --- a/device/ingrasys/x86_64-ingrasys_s8900_64xc-r0/plugins/eeprom.py +++ b/device/ingrasys/x86_64-ingrasys_s8900_64xc-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Ingrasys S8900-64XC # @@ -11,8 +9,8 @@ try: from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): diff --git a/device/ingrasys/x86_64-ingrasys_s8900_64xc-r0/plugins/psuutil.py b/device/ingrasys/x86_64-ingrasys_s8900_64xc-r0/plugins/psuutil.py index 3af5423daebd..e97e3193fd64 100644 --- a/device/ingrasys/x86_64-ingrasys_s8900_64xc-r0/plugins/psuutil.py +++ b/device/ingrasys/x86_64-ingrasys_s8900_64xc-r0/plugins/psuutil.py @@ -19,12 +19,12 @@ class PsuUtil(PsuBase): def __init__(self): PsuBase.__init__(self) - - + # Get sysfs attribute + def get_attr_value(self, attr_path): - - retval = 'ERR' + + retval = 'ERR' if (not os.path.isfile(attr_path)): return retval @@ -54,17 +54,17 @@ def get_psu_status(self, index): faulty """ status = 0 - mask = [ 0x04, 0x08 ] - attr_file = 'cpld_pw_good' - attr_path = self.PSU_CPLD_DIR +'/'+ attr_file - + mask = [0x04, 0x08] + attr_file = 'cpld_pw_good' + attr_path = self.PSU_CPLD_DIR + '/' + 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 & mask[index-1]): - status = 1 + status = 1 return status @@ -76,17 +76,16 @@ def get_psu_presence(self, index): :return: Boolean, True if PSU is plugged, False if not """ status = 0 - mask = [ 0x01, 0x02 ] - attr_file ='cpld_pw_abs' - attr_path = self.PSU_CPLD_DIR +'/'+ attr_file - + mask = [0x01, 0x02] + attr_file = 'cpld_pw_abs' + attr_path = self.PSU_CPLD_DIR + '/' + 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 & mask[index-1]): - status = 1 + status = 1 return status - diff --git a/device/ingrasys/x86_64-ingrasys_s8900_64xc-r0/plugins/sfputil.py b/device/ingrasys/x86_64-ingrasys_s8900_64xc-r0/plugins/sfputil.py index 26355bf441e6..cc2c01d3bd33 100644 --- a/device/ingrasys/x86_64-ingrasys_s8900_64xc-r0/plugins/sfputil.py +++ b/device/ingrasys/x86_64-ingrasys_s8900_64xc-r0/plugins/sfputil.py @@ -16,6 +16,7 @@ cpld_addr = '0x33' mux_reg = '0x4A' + class SfpUtil(SfpUtilBase): """Platform-specific SfpUtil class""" @@ -26,70 +27,70 @@ class SfpUtil(SfpUtilBase): _port_to_eeprom_mapping = {} port_to_i2c_mapping = { - 0: [2,1], - 1: [2,2], - 2: [2,3], - 3: [2,4], - 4: [2,5], - 5: [2,6], - 6: [2,7], - 7: [2,8], - 8: [2,9], - 9: [2,10], - 10: [2,11], - 11: [2,12], - 12: [2,13], - 13: [2,14], - 14: [2,15], - 15: [2,16], - 16: [2,17], - 17: [2,18], - 18: [2,19], - 19: [2,20], - 20: [2,21], - 21: [2,22], - 22: [2,23], - 23: [2,24], - 24: [3,25], - 25: [3,26], - 26: [3,27], - 27: [3,28], - 28: [3,29], - 29: [3,30], - 30: [3,31], - 31: [3,32], - 32: [3,33], - 33: [3,34], - 34: [3,35], - 35: [3,36], - 36: [3,37], - 37: [3,38], - 38: [3,39], - 39: [3,40], - 40: [3,41], - 41: [3,42], - 42: [3,43], - 43: [3,44], - 44: [3,45], - 45: [3,46], - 46: [3,47], - 47: [3,48], - 48: [4,49], - 49: [4,50], - 50: [4,51], - 51: [4,52], - 52: [4,53], - 53: [4,54], - 54: [4,55], - 55: [4,56], - 56: [4,57], - 57: [4,58], - 58: [4,59], - 59: [4,60], - 60: [4,61], - 61: [4,62], - 62: [4,63], - 63: [4,64] + 0: [2, 1], + 1: [2, 2], + 2: [2, 3], + 3: [2, 4], + 4: [2, 5], + 5: [2, 6], + 6: [2, 7], + 7: [2, 8], + 8: [2, 9], + 9: [2, 10], + 10: [2, 11], + 11: [2, 12], + 12: [2, 13], + 13: [2, 14], + 14: [2, 15], + 15: [2, 16], + 16: [2, 17], + 17: [2, 18], + 18: [2, 19], + 19: [2, 20], + 20: [2, 21], + 21: [2, 22], + 22: [2, 23], + 23: [2, 24], + 24: [3, 25], + 25: [3, 26], + 26: [3, 27], + 27: [3, 28], + 28: [3, 29], + 29: [3, 30], + 30: [3, 31], + 31: [3, 32], + 32: [3, 33], + 33: [3, 34], + 34: [3, 35], + 35: [3, 36], + 36: [3, 37], + 37: [3, 38], + 38: [3, 39], + 39: [3, 40], + 40: [3, 41], + 41: [3, 42], + 42: [3, 43], + 43: [3, 44], + 44: [3, 45], + 45: [3, 46], + 46: [3, 47], + 47: [3, 48], + 48: [4, 49], + 49: [4, 50], + 50: [4, 51], + 51: [4, 52], + 52: [4, 53], + 53: [4, 54], + 54: [4, 55], + 55: [4, 56], + 56: [4, 57], + 57: [4, 58], + 58: [4, 59], + 59: [4, 60], + 60: [4, 61], + 61: [4, 62], + 62: [4, 63], + 63: [4, 64] } @property @@ -102,7 +103,7 @@ def port_end(self): @property def qsfp_ports(self): - return range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1) + return list(range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -133,7 +134,7 @@ def get_presence(self, port_num): try: reg_file = open("/sys/devices/platform/ingrasys-s8900-64xc-cpld.0/qsfp_modprs") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -158,7 +159,7 @@ def get_low_power_mode(self, port_num): try: reg_file = open("/sys/devices/platform/ingrasys-s8900-64xc-cpld.0/qsfp_lpmode") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -167,7 +168,7 @@ def get_low_power_mode(self, port_num): reg_value = int(content, 16) # Mask off the bit corresponding to our port - mask = (1 << (port_num - self.qsfp_port_start) ) + mask = (1 << (port_num - self.qsfp_port_start)) # LPMode is active high if reg_value & mask == 0: @@ -183,7 +184,7 @@ def set_low_power_mode(self, port_num, lpmode): try: reg_file = open("/sys/devices/platform/ingrasys-s8900-64xc-cpld.0/qsfp_lpmode", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -192,7 +193,7 @@ def set_low_power_mode(self, port_num, lpmode): reg_value = int(content, 16) # Mask off the bit corresponding to our port - mask = (1 << (port_num - self.qsfp_port_start) ) + mask = (1 << (port_num - self.qsfp_port_start)) # LPMode is active high; set or clear the bit accordingly if lpmode is True: @@ -219,7 +220,7 @@ def reset(self, port_num): try: reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -245,7 +246,7 @@ def reset(self, port_num): try: reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "w") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = reg_value | mask diff --git a/device/ingrasys/x86_64-ingrasys_s9100-r0/INGRASYS-S9100-C32/sai.profile b/device/ingrasys/x86_64-ingrasys_s9100-r0/INGRASYS-S9100-C32/sai.profile index 14a36af5f554..11c0ae1ab636 100644 --- a/device/ingrasys/x86_64-ingrasys_s9100-r0/INGRASYS-S9100-C32/sai.profile +++ b/device/ingrasys/x86_64-ingrasys_s9100-r0/INGRASYS-S9100-C32/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-s9100-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/ingrasys/x86_64-ingrasys_s9100-r0/plugins/eeprom.py b/device/ingrasys/x86_64-ingrasys_s9100-r0/plugins/eeprom.py index 83bf65a389bd..1c23602fcb5a 100644 --- a/device/ingrasys/x86_64-ingrasys_s9100-r0/plugins/eeprom.py +++ b/device/ingrasys/x86_64-ingrasys_s9100-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Ingrasys S9100 # @@ -11,8 +9,8 @@ try: from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): diff --git a/device/ingrasys/x86_64-ingrasys_s9100-r0/plugins/psuutil.py b/device/ingrasys/x86_64-ingrasys_s9100-r0/plugins/psuutil.py index 4f226c69fff3..ef45a0c91727 100644 --- a/device/ingrasys/x86_64-ingrasys_s9100-r0/plugins/psuutil.py +++ b/device/ingrasys/x86_64-ingrasys_s9100-r0/plugins/psuutil.py @@ -19,12 +19,12 @@ class PsuUtil(PsuBase): def __init__(self): PsuBase.__init__(self) - - + # Get sysfs attribute + def get_attr_value(self, attr_path): - - retval = 'ERR' + + retval = 'ERR' if (not os.path.isfile(attr_path)): return retval @@ -54,17 +54,17 @@ def get_psu_status(self, index): faulty """ status = 0 - mask = [ 0x08, 0x10 ] - attr_file = 'cpld_pw_good' - attr_path = self.PSU_CPLD_DIR +'/'+ attr_file - + mask = [0x08, 0x10] + attr_file = 'cpld_pw_good' + attr_path = self.PSU_CPLD_DIR + '/' + 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 & mask[index-1]): - status = 1 + status = 1 return status @@ -76,17 +76,16 @@ def get_psu_presence(self, index): :return: Boolean, True if PSU is plugged, False if not """ status = 0 - mask = [ 0x01, 0x02 ] - attr_file ='cpld_pw_abs' - attr_path = self.PSU_CPLD_DIR +'/'+ attr_file - + mask = [0x01, 0x02] + attr_file = 'cpld_pw_abs' + attr_path = self.PSU_CPLD_DIR + '/' + 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 & mask[index-1]): - status = 1 + status = 1 return status - diff --git a/device/ingrasys/x86_64-ingrasys_s9100-r0/plugins/sfputil.py b/device/ingrasys/x86_64-ingrasys_s9100-r0/plugins/sfputil.py index 849bd13d94d3..f2da8544202c 100644 --- a/device/ingrasys/x86_64-ingrasys_s9100-r0/plugins/sfputil.py +++ b/device/ingrasys/x86_64-ingrasys_s9100-r0/plugins/sfputil.py @@ -73,7 +73,7 @@ def port_end(self): @property def qsfp_ports(self): - return range(0, self.PORTS_IN_BLOCK + 1) + return list(range(0, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -86,11 +86,11 @@ def set_gpio_offset(self): for d in os.listdir(sys_gpio_dir): if "gpiochip" in d: try: - gpiochip_no = int(d[8:],10) + gpiochip_no = int(d[8:], 10) except ValueError as e: - print "Error: %s" % str(e) + print("Error: %s" % str(e)) if gpiochip_no > 255: - self.GPIO_OFFSET=256 + self.GPIO_OFFSET = 256 return True return True @@ -228,10 +228,10 @@ def get_presence(self, port_num): try: abs_device_file = self.BASE_VAL_PATH.format( - self.abs_to_gpio_mapping[port_num]) + self.abs_to_gpio_mapping[port_num]) val_file = open(abs_device_file) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = val_file.readline().rstrip() @@ -250,10 +250,10 @@ def get_low_power_mode(self, port_num): try: lpmode_val_device_file = self.BASE_VAL_PATH.format( - self.lpmode_to_gpio_mapping[port_num]) + self.lpmode_to_gpio_mapping[port_num]) val_file = open(lpmode_val_device_file) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = val_file.readline().rstrip() @@ -272,10 +272,10 @@ def set_low_power_mode(self, port_num, lpmode): try: lpmode_val_device_file = self.BASE_VAL_PATH.format( - self.lpmode_to_gpio_mapping[port_num]) + self.lpmode_to_gpio_mapping[port_num]) val_file = open(lpmode_val_device_file, "w") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False val_file.write("1" if lpmode is True else "0") @@ -290,10 +290,10 @@ def reset(self, port_num): try: reset_val_device_file = self.BASE_VAL_PATH.format( - self.reset_to_gpio_mapping[port_num]) + self.reset_to_gpio_mapping[port_num]) val_file = open(reset_val_device_file, "w") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False val_file.write("1") @@ -304,10 +304,10 @@ def reset(self, port_num): try: reset_val_device_file = self.BASE_VAL_PATH.format( - self.reset_to_gpio_mapping[port_num]) + self.reset_to_gpio_mapping[port_num]) val_file = open(reset_val_device_file, "w") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False val_file.write("0") diff --git a/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/INGRASYS-S9130-32X/port_config.nps b/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/INGRASYS-S9130-32X/port_config.nps index 49068859b25c..6d49c6720882 100644 --- a/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/INGRASYS-S9130-32X/port_config.nps +++ b/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/INGRASYS-S9130-32X/port_config.nps @@ -349,4 +349,5 @@ port set property unit=0 portlist=129-130 medium-type=kr port set property unit=0 portlist=0-31 fec=disable port set adver unit=0 portlist=129-130 speed-10g-kr port set property unit=0 portlist=129-130 an=enable -port set property unit=0 portlist=0-31,129-130 admin=enable +port set property unit=0 portlist=129-130 admin=enable +port set property unit=0 portlist=0-31 admin=disable diff --git a/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/plugins/eeprom.py b/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/plugins/eeprom.py index 71ce941f1abb..7496ebe21ada 100644 --- a/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/plugins/eeprom.py +++ b/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Ingrasys S9130-32X # @@ -11,8 +9,8 @@ try: from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): diff --git a/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/plugins/psuutil.py b/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/plugins/psuutil.py index 4a029c15b1a6..37e2173aa9d2 100644 --- a/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/plugins/psuutil.py +++ b/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/plugins/psuutil.py @@ -20,12 +20,12 @@ class PsuUtil(PsuBase): def __init__(self): PsuBase.__init__(self) - - + # Get sysfs attribute + def get_attr_value(self, attr_path): - - retval = 'ERR' + + retval = 'ERR' if (not os.path.isfile(attr_path)): return retval @@ -55,16 +55,16 @@ def get_psu_status(self, index): faulty """ status = 0 - attr_file = 'psu_pg' - attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file - + attr_file = 'psu_pg' + 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 + status = 1 return status @@ -77,16 +77,15 @@ def get_psu_presence(self, index): """ status = 0 psu_absent = 0 - attr_file ='psu_abs' - attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file - + attr_file = 'psu_abs' + 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 == 0): - status = 1 + status = 1 return status - diff --git a/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/plugins/sfputil.py b/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/plugins/sfputil.py index 4827ad3bfa80..260c759c7993 100644 --- a/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/plugins/sfputil.py +++ b/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/plugins/sfputil.py @@ -41,7 +41,7 @@ def port_end(self): @property def qsfp_ports(self): - return range(0, self.PORTS_IN_BLOCK + 1) + return list(range(0, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -49,16 +49,16 @@ def port_to_eeprom_mapping(self): def set_gpio_offset(self): sys_gpio_dir = "/sys/class/gpio" - self.GPIO_OFFSET = 0 - gpiochip_no = 0 + self.GPIO_OFFSET = 0 + gpiochip_no = 0 for d in os.listdir(sys_gpio_dir): if "gpiochip" in d: try: - gpiochip_no = int(d[8:],10) + gpiochip_no = int(d[8:], 10) except ValueError as e: - print "Error: %s" % str(e) + print("Error: %s" % str(e)) if gpiochip_no > 255: - self.GPIO_OFFSET=256 + self.GPIO_OFFSET = 256 return True return True @@ -92,14 +92,14 @@ def get_presence(self, port_num): # open corrsponding gpio file try: if port_num <= 15: - gpio_base = self.ABS_GPIO_BASE_0_15 - else : - gpio_base = self.ABS_GPIO_BASE_16_31 + gpio_base = self.ABS_GPIO_BASE_0_15 + else: + gpio_base = self.ABS_GPIO_BASE_16_31 gpio_index = gpio_base + (port_num % 16) gpio_file_path = self.GPIO_VAL_PATH.format(gpio_index) gpio_file = open(gpio_file_path) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False # content is a string containing the gpio value @@ -121,13 +121,13 @@ def get_low_power_mode(self, port_num): try: if port_num <= 15: gpio_base = self.LP_MODE_GPIO_BASE_0_15 - else : + else: gpio_base = self.LP_MODE_GPIO_BASE_16_31 gpio_index = gpio_base + (port_num % 16) gpio_file_path = self.GPIO_VAL_PATH.format(gpio_index) gpio_file = open(gpio_file_path) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False # content is a string containing the gpio value @@ -148,13 +148,13 @@ def set_low_power_mode(self, port_num, lpmode): try: if port_num <= 15: gpio_base = self.LP_MODE_GPIO_BASE_0_15 - else : + else: gpio_base = self.LP_MODE_GPIO_BASE_16_31 gpio_index = gpio_base + (port_num % 16) gpio_file_path = self.GPIO_VAL_PATH.format(gpio_index) gpio_file = open(gpio_file_path, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False # the gpio pin is ACTIVE_HIGH @@ -179,13 +179,13 @@ def reset(self, port_num): try: if port_num <= 15: gpio_base = self.RST_GPIO_BASE_0_15 - else : + else: gpio_base = self.RST_GPIO_BASE_16_31 gpio_index = gpio_base + (port_num % 16) gpio_file_path = self.GPIO_VAL_PATH.format(gpio_index) gpio_file = open(gpio_file_path, "w") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False # set the gpio to take port into reset @@ -203,13 +203,13 @@ def reset(self, port_num): try: gpio_file = open(gpio_file_path, "w") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False # set gpio back low to take port out of reset # the gpio pin is ACTIVE_LOW but reversed gpio_val = "0" - # write value to gpio + # write value to gpio gpio_file.seek(0) gpio_file.write(gpio_val) gpio_file.close() diff --git a/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/plugins/eeprom.py b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/plugins/eeprom.py index d1270eeffbf6..f3fb959c2d01 100644 --- a/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/plugins/eeprom.py +++ b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Ingrasys S9180-32X # @@ -11,8 +9,8 @@ try: from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): diff --git a/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/plugins/psuutil.py b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/plugins/psuutil.py index 25cdfb031882..3ac4fa48afd0 100644 --- a/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/plugins/psuutil.py +++ b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/plugins/psuutil.py @@ -20,16 +20,16 @@ class PsuUtil(PsuBase): def set_gpio_offset(self): sys_gpio_dir = "/sys/class/gpio" - self.GPIO_OFFSET = 0 - gpiochip_no = 0 + self.GPIO_OFFSET = 0 + gpiochip_no = 0 for d in os.listdir(sys_gpio_dir): if "gpiochip" in d: try: - gpiochip_no = int(d[8:],10) + gpiochip_no = int(d[8:], 10) except ValueError as e: - print "Error: %s" % str(e) + print("Error: %s" % str(e)) if gpiochip_no > 255: - self.GPIO_OFFSET=256 + self.GPIO_OFFSET = 256 return True return True @@ -37,8 +37,8 @@ def __init__(self): self.set_gpio_offset() PsuBase.__init__(self) - # Get sysfs attribute + def get_attr_value(self, attr_path): retval = 'ERR' @@ -71,7 +71,7 @@ def get_psu_status(self, index): faulty """ status = 0 - gpio_path = [ 'gpio'+str(99+self.GPIO_OFFSET)+'/value', 'gpio'+str(96+self.GPIO_OFFSET)+'/value' ] + gpio_path = ['gpio'+str(99+self.GPIO_OFFSET)+'/value', 'gpio'+str(96+self.GPIO_OFFSET)+'/value'] attr_path = self.SYS_GPIO_DIR + gpio_path[index-1] attr_value = self.get_attr_value(attr_path) @@ -80,7 +80,7 @@ def get_psu_status(self, index): attr_value = int(attr_value, 10) # Check for PSU status if (attr_value == 1): - status = 1 + status = 1 return status @@ -92,7 +92,7 @@ def get_psu_presence(self, index): :return: Boolean, True if PSU is plugged, False if not """ status = 0 - gpio_path = [ 'gpio'+str(100+self.GPIO_OFFSET)+'/value', 'gpio'+str(97+self.GPIO_OFFSET)+'/value' ] + gpio_path = ['gpio'+str(100+self.GPIO_OFFSET)+'/value', 'gpio'+str(97+self.GPIO_OFFSET)+'/value'] attr_path = self.SYS_GPIO_DIR + gpio_path[index-1] attr_value = self.get_attr_value(attr_path) @@ -101,7 +101,6 @@ def get_psu_presence(self, index): attr_value = int(attr_value, 10) # Check for PSU status if (attr_value == 1): - status = 1 + status = 1 return status - diff --git a/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/plugins/sfputil.py b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/plugins/sfputil.py index 00c5e10e0b0d..c061fcabd23a 100644 --- a/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/plugins/sfputil.py +++ b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/plugins/sfputil.py @@ -76,11 +76,12 @@ def port_end(self): @property def qsfp_ports(self): - return range(0, self.PORTS_IN_BLOCK + 1) + return list(range(0, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): return self._port_to_eeprom_mapping + @property def sfp_port_start(self): return self.SFP_PORT_START @@ -92,11 +93,11 @@ def set_gpio_offset(self): for d in os.listdir(sys_gpio_dir): if "gpiochip" in d: try: - gpiochip_no = int(d[8:],10) + gpiochip_no = int(d[8:], 10) except ValueError as e: - print "Error: %s" % str(e) + print("Error: %s" % str(e)) if gpiochip_no > 255: - self.GPIO_OFFSET=256 + self.GPIO_OFFSET = 256 return True return True @@ -172,12 +173,12 @@ def init_lpmode_to_gpio_mapping(self): 28: 157+self.GPIO_OFFSET, 29: 156+self.GPIO_OFFSET, 30: 159+self.GPIO_OFFSET, - 31: 158+self.GPIO_OFFSET + 31: 158+self.GPIO_OFFSET } return True def init_reset_to_gpio_mapping(self): - self.reset_to_gpio_mapping = { + self.reset_to_gpio_mapping = { 0: 129+self.GPIO_OFFSET, 1: 128+self.GPIO_OFFSET, 2: 131+self.GPIO_OFFSET, @@ -209,7 +210,7 @@ def init_reset_to_gpio_mapping(self): 28: 125+self.GPIO_OFFSET, 29: 124+self.GPIO_OFFSET, 30: 127+self.GPIO_OFFSET, - 31: 126+self.GPIO_OFFSET + 31: 126+self.GPIO_OFFSET } return True @@ -236,10 +237,10 @@ def get_presence(self, port_num): try: abs_device_file = self.BASE_VAL_PATH.format( - self.abs_to_gpio_mapping[port_num]) + self.abs_to_gpio_mapping[port_num]) val_file = open(abs_device_file) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = val_file.readline().rstrip() @@ -253,15 +254,15 @@ def get_presence(self, port_num): def get_low_power_mode(self, port_num): # Check for invalid port_num - if port_num < self.port_start or port_num > self.sfp_port_start: # TBD + if port_num < self.port_start or port_num > self.sfp_port_start: # TBD return False try: lpmode_val_device_file = self.BASE_VAL_PATH.format( - self.lpmode_to_gpio_mapping[port_num]) + self.lpmode_to_gpio_mapping[port_num]) val_file = open(lpmode_val_device_file) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = val_file.readline().rstrip() @@ -275,15 +276,15 @@ def get_low_power_mode(self, port_num): def set_low_power_mode(self, port_num, lpmode): # Check for invalid port_num - if port_num < self.port_start or port_num > self.sfp_port_start: # TBD + if port_num < self.port_start or port_num > self.sfp_port_start: # TBD return False try: lpmode_val_device_file = self.BASE_VAL_PATH.format( - self.lpmode_to_gpio_mapping[port_num]) + self.lpmode_to_gpio_mapping[port_num]) val_file = open(lpmode_val_device_file, "w") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False val_file.write("1" if lpmode is True else "0") @@ -293,15 +294,15 @@ def set_low_power_mode(self, port_num, lpmode): def reset(self, port_num): # Check for invalid port_num - if port_num < self.port_start or port_num > self.sfp_port_start: # TBD + if port_num < self.port_start or port_num > self.sfp_port_start: # TBD return False try: reset_val_device_file = self.BASE_VAL_PATH.format( - self.reset_to_gpio_mapping[port_num]) + self.reset_to_gpio_mapping[port_num]) val_file = open(reset_val_device_file, "w") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False val_file.write("1") @@ -312,10 +313,10 @@ def reset(self, port_num): try: reset_val_device_file = self.BASE_VAL_PATH.format( - self.reset_to_gpio_mapping[port_num]) + self.reset_to_gpio_mapping[port_num]) val_file = open(reset_val_device_file, "w") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False val_file.write("0") diff --git a/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/INGRASYS-S9200-64X/sai.profile b/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/INGRASYS-S9200-64X/sai.profile index 5404ca338ffd..d16307aa360d 100644 --- a/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/INGRASYS-S9200-64X/sai.profile +++ b/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/INGRASYS-S9200-64X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-s9200-64x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/plugins/eeprom.py b/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/plugins/eeprom.py index 64ddb99554b0..034c592c411e 100644 --- a/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/plugins/eeprom.py +++ b/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Ingrasys S9200-64X # @@ -11,8 +9,8 @@ try: from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): diff --git a/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/plugins/psuutil.py b/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/plugins/psuutil.py index cc996057e09e..b2cdb9dca023 100644 --- a/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/plugins/psuutil.py +++ b/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/plugins/psuutil.py @@ -20,12 +20,12 @@ class PsuUtil(PsuBase): def __init__(self): PsuBase.__init__(self) - - + # Get sysfs attribute + def get_attr_value(self, attr_path): - - retval = 'ERR' + + retval = 'ERR' if (not os.path.isfile(attr_path)): return retval @@ -55,16 +55,16 @@ def get_psu_status(self, index): faulty """ status = 0 - attr_file = 'psu_pg' - attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file - + attr_file = 'psu_pg' + 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 + status = 1 return status @@ -77,16 +77,15 @@ def get_psu_presence(self, index): """ status = 0 psu_absent = 0 - attr_file ='psu_abs' - attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file - + attr_file = 'psu_abs' + 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 == 0): - status = 1 + status = 1 return status - diff --git a/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/plugins/sfputil.py b/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/plugins/sfputil.py index 584b0e9716b8..1066c78ba826 100644 --- a/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/plugins/sfputil.py +++ b/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/plugins/sfputil.py @@ -14,7 +14,7 @@ class SfpUtil(SfpUtilBase): """Platform-specific SfpUtil class""" PORT_START = 0 - PORT_END = 63 + PORT_END = 63 PORTS_IN_BLOCK = 64 EEPROM_OFFSET = 29 @@ -22,70 +22,70 @@ class SfpUtil(SfpUtilBase): _port_to_eeprom_mapping = {} _logic_to_phy_port_mapping = { - 0: 0, - 1: 1, - 2: 4, - 3: 5, - 4: 8, - 5: 9, - 6: 12, - 7: 13, - 8: 16, - 9: 17, - 10: 20, - 11: 21, - 12: 24, - 13: 25, - 14: 28, - 15: 29, - 16: 32, - 17: 33, - 18: 36, - 19: 37, - 20: 40, - 21: 41, - 22: 44, - 23: 45, - 24: 48, - 25: 49, - 26: 52, - 27: 53, - 28: 56, - 29: 57, - 30: 60, - 31: 61, - 32: 2, - 33: 3, - 34: 6, - 35: 7, - 36: 10, - 37: 11, - 38: 14, - 39: 15, - 40: 18, - 41: 19, - 42: 22, - 43: 23, - 44: 26, - 45: 27, - 46: 30, - 47: 31, - 48: 34, - 49: 35, - 50: 38, - 51: 39, - 52: 42, - 53: 43, - 54: 46, - 55: 47, - 56: 50, - 57: 51, - 58: 54, - 59: 55, - 60: 58, - 61: 59, - 62: 62, - 63: 63 + 0: 0, + 1: 1, + 2: 4, + 3: 5, + 4: 8, + 5: 9, + 6: 12, + 7: 13, + 8: 16, + 9: 17, + 10: 20, + 11: 21, + 12: 24, + 13: 25, + 14: 28, + 15: 29, + 16: 32, + 17: 33, + 18: 36, + 19: 37, + 20: 40, + 21: 41, + 22: 44, + 23: 45, + 24: 48, + 25: 49, + 26: 52, + 27: 53, + 28: 56, + 29: 57, + 30: 60, + 31: 61, + 32: 2, + 33: 3, + 34: 6, + 35: 7, + 36: 10, + 37: 11, + 38: 14, + 39: 15, + 40: 18, + 41: 19, + 42: 22, + 43: 23, + 44: 26, + 45: 27, + 46: 30, + 47: 31, + 48: 34, + 49: 35, + 50: 38, + 51: 39, + 52: 42, + 53: 43, + 54: 46, + 55: 47, + 56: 50, + 57: 51, + 58: 54, + 59: 55, + 60: 58, + 61: 59, + 62: 62, + 63: 63 } @property @@ -98,7 +98,7 @@ def port_end(self): @property def qsfp_ports(self): - return range(0, self.PORTS_IN_BLOCK + 1) + return list(range(0, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -124,7 +124,7 @@ def get_presence(self, port_num): try: reg_file = open("/sys/devices/platform/ingrasys-s9200-cpld.0/qsfp_modprs") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -152,7 +152,7 @@ def get_low_power_mode(self, port_num): try: reg_file = open("/sys/devices/platform/ingrasys-s9200-cpld.0/qsfp_lpmode") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) content = reg_file.readline().rstrip() @@ -175,15 +175,14 @@ def set_low_power_mode(self, port_num, lpmode): # logic port to physical port mapping port_num = self._logic_to_phy_port_mapping[port_num] - + try: reg_file = open("/sys/devices/platform/ingrasys-s9200-cpld.0/qsfp_lpmode", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() - # content is a string containing the hex representation of the register reg_value = int(content, 16) @@ -219,7 +218,7 @@ def reset(self, port_num): try: reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -247,7 +246,7 @@ def reset(self, port_num): try: reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "w") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = reg_value | mask diff --git a/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/port_config.nps b/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/port_config.nps index 0e14b9ced3fe..4f89209537f8 100644 --- a/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/port_config.nps +++ b/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/port_config.nps @@ -678,4 +678,5 @@ port set property portlist=0-63 fec=disable port set adver portlist=129-130 speed-10g-kr port set property portlist=129-130 an=enable -port set property portlist=0-63,129-130 admin=enable +port set property portlist=129-130 admin=enable +port set property portlist=0-63 admin=disable diff --git a/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/plugins/eeprom.py b/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/plugins/eeprom.py index 770b0cf43baf..159e12d98f64 100644 --- a/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/plugins/eeprom.py +++ b/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Ingrasys S9230-64X # @@ -11,8 +9,8 @@ try: from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): diff --git a/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/plugins/psuutil.py b/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/plugins/psuutil.py index cc996057e09e..b2cdb9dca023 100644 --- a/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/plugins/psuutil.py +++ b/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/plugins/psuutil.py @@ -20,12 +20,12 @@ class PsuUtil(PsuBase): def __init__(self): PsuBase.__init__(self) - - + # Get sysfs attribute + def get_attr_value(self, attr_path): - - retval = 'ERR' + + retval = 'ERR' if (not os.path.isfile(attr_path)): return retval @@ -55,16 +55,16 @@ def get_psu_status(self, index): faulty """ status = 0 - attr_file = 'psu_pg' - attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file - + attr_file = 'psu_pg' + 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 + status = 1 return status @@ -77,16 +77,15 @@ def get_psu_presence(self, index): """ status = 0 psu_absent = 0 - attr_file ='psu_abs' - attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file - + attr_file = 'psu_abs' + 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 == 0): - status = 1 + status = 1 return status - diff --git a/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/plugins/sfputil.py b/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/plugins/sfputil.py index 2f7a5395bb47..f3e1d49cd86b 100644 --- a/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/plugins/sfputil.py +++ b/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/plugins/sfputil.py @@ -16,7 +16,7 @@ class SfpUtil(SfpUtilBase): PORT_START = 0 PORT_END = 63 PORTS_IN_BLOCK = 64 - #TODO: modify according to port map + # TODO: modify according to port map EEPROM_OFFSET = 33 CPLD1_PORTS = 12 CPLDx_PORTS = 13 @@ -32,70 +32,70 @@ class SfpUtil(SfpUtilBase): _port_to_eeprom_mapping = {} _logic_to_phy_port_mapping = { - 0: 0, - 1: 1, - 2: 4, - 3: 5, - 4: 8, - 5: 9, - 6: 12, - 7: 13, - 8: 16, - 9: 17, - 10: 20, - 11: 21, - 12: 24, - 13: 25, - 14: 28, - 15: 29, - 16: 32, - 17: 33, - 18: 36, - 19: 37, - 20: 40, - 21: 41, - 22: 44, - 23: 45, - 24: 48, - 25: 49, - 26: 52, - 27: 53, - 28: 56, - 29: 57, - 30: 60, - 31: 61, - 32: 2, - 33: 3, - 34: 6, - 35: 7, - 36: 10, - 37: 11, - 38: 14, - 39: 15, - 40: 18, - 41: 19, - 42: 22, - 43: 23, - 44: 26, - 45: 27, - 46: 30, - 47: 31, - 48: 34, - 49: 35, - 50: 38, - 51: 39, - 52: 42, - 53: 43, - 54: 46, - 55: 47, - 56: 50, - 57: 51, - 58: 54, - 59: 55, - 60: 58, - 61: 59, - 62: 62, - 63: 63 + 0: 0, + 1: 1, + 2: 4, + 3: 5, + 4: 8, + 5: 9, + 6: 12, + 7: 13, + 8: 16, + 9: 17, + 10: 20, + 11: 21, + 12: 24, + 13: 25, + 14: 28, + 15: 29, + 16: 32, + 17: 33, + 18: 36, + 19: 37, + 20: 40, + 21: 41, + 22: 44, + 23: 45, + 24: 48, + 25: 49, + 26: 52, + 27: 53, + 28: 56, + 29: 57, + 30: 60, + 31: 61, + 32: 2, + 33: 3, + 34: 6, + 35: 7, + 36: 10, + 37: 11, + 38: 14, + 39: 15, + 40: 18, + 41: 19, + 42: 22, + 43: 23, + 44: 26, + 45: 27, + 46: 30, + 47: 31, + 48: 34, + 49: 35, + 50: 38, + 51: 39, + 52: 42, + 53: 43, + 54: 46, + 55: 47, + 56: 50, + 57: 51, + 58: 54, + 59: 55, + 60: 58, + 61: 59, + 62: 62, + 63: 63 } @property @@ -108,13 +108,12 @@ def port_end(self): @property def qsfp_ports(self): - return range(0, self.PORTS_IN_BLOCK + 1) + return list(range(0, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): return self._port_to_eeprom_mapping - def __init__(self): # Override port_to_eeprom_mapping for class initialization eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" @@ -132,7 +131,7 @@ def qsfp_to_cpld_index(self, port_num): else: cpld_id = 1 + (port_num - self.CPLD1_PORTS) / self.CPLDx_PORTS cpld_port_index = ((port_num - self.CPLD1_PORTS) % self.CPLDx_PORTS) + 1 - return cpld_id, cpld_port_index + return cpld_id, cpld_port_index def get_presence(self, port_num): # Check for invalid port_num @@ -144,25 +143,25 @@ def get_presence(self, port_num): cpld_id, cpld_port_index = self.qsfp_to_cpld_index(port_num) i2c_id = self.CPLD_OFFSET + cpld_id - reg_path = self.CPLD_REG_PATH.format(i2c_id, self.CPLDx_I2C_ADDR, \ - self.CPLD_PORT_STATUS_KEY, cpld_port_index) + reg_path = self.CPLD_REG_PATH.format(i2c_id, self.CPLDx_I2C_ADDR, + self.CPLD_PORT_STATUS_KEY, cpld_port_index) try: reg_file = open(reg_path) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False # content is a string containing the status register value content = reg_file.readline().rstrip() reg_file.close() - + reg_value = int(content, 16) # mask for presence bit (bit 1) mask = (1 << self.CPLD_PRES_BIT) # 0 - presence, 1 - absence - if reg_value & mask == 0: + if reg_value & mask == 0: return True return False @@ -177,13 +176,13 @@ def get_low_power_mode(self, port_num): cpld_id, cpld_port_index = self.qsfp_to_cpld_index(port_num) i2c_id = self.CPLD_OFFSET + cpld_id - reg_path = self.CPLD_REG_PATH.format(i2c_id, self.CPLDx_I2C_ADDR, \ - self.CPLD_PORT_CONFIG_KEY, cpld_port_index) + reg_path = self.CPLD_REG_PATH.format(i2c_id, self.CPLDx_I2C_ADDR, + self.CPLD_PORT_CONFIG_KEY, cpld_port_index) try: reg_file = open(reg_path) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False # content is a string containing the status register value @@ -195,7 +194,7 @@ def get_low_power_mode(self, port_num): mask = (1 << self.CPLD_LPMOD_BIT) # 0 - disable, 1 - low power mode - if reg_value & mask == 0: + if reg_value & mask == 0: return False return True @@ -210,13 +209,13 @@ def set_low_power_mode(self, port_num, lpmode): cpld_id, cpld_port_index = self.qsfp_to_cpld_index(port_num) i2c_id = self.CPLD_OFFSET + cpld_id - reg_path = self.CPLD_REG_PATH.format(i2c_id, self.CPLDx_I2C_ADDR, \ - self.CPLD_PORT_CONFIG_KEY, cpld_port_index) + reg_path = self.CPLD_REG_PATH.format(i2c_id, self.CPLDx_I2C_ADDR, + self.CPLD_PORT_CONFIG_KEY, cpld_port_index) try: reg_file = open(reg_path, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False # content is a string containing the status register value @@ -250,14 +249,14 @@ def reset(self, port_num): cpld_id, cpld_port_index = self.qsfp_to_cpld_index(port_num) i2c_id = self.CPLD_OFFSET + cpld_id - reg_path = self.CPLD_REG_PATH.format(i2c_id, self.CPLDx_I2C_ADDR, \ - self.CPLD_PORT_CONFIG_KEY, cpld_port_index) + reg_path = self.CPLD_REG_PATH.format(i2c_id, self.CPLDx_I2C_ADDR, + self.CPLD_PORT_CONFIG_KEY, cpld_port_index) # reset the port try: reg_file = open(reg_path, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False # content is a string containing the status register value @@ -280,7 +279,7 @@ def reset(self, port_num): try: reg_file = open(reg_path, "w") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = reg_value | mask diff --git a/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/plugins/eeprom.py b/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/plugins/eeprom.py index ecf171539843..3fc614fc2632 100644 --- a/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/plugins/eeprom.py +++ b/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Ingrasys S9280-64X # @@ -11,8 +9,8 @@ try: from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): diff --git a/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/plugins/psuutil.py b/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/plugins/psuutil.py index c4b78c943e81..8c7d5cfa4174 100644 --- a/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/plugins/psuutil.py +++ b/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/plugins/psuutil.py @@ -21,12 +21,12 @@ class PsuUtil(PsuBase): def __init__(self): PsuBase.__init__(self) - - + # Get sysfs attribute + def get_attr_value(self, attr_path): - - retval = 'ERR' + + retval = 'ERR' if (not os.path.isfile(attr_path)): return retval @@ -56,16 +56,16 @@ def get_psu_status(self, index): faulty """ status = 0 - attr_file = 'psu_pg' - attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file - + attr_file = 'psu_pg' + 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 + status = 1 return status @@ -78,16 +78,15 @@ def get_psu_presence(self, index): """ status = 0 psu_absent = 0 - attr_file ='psu_abs' - attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file - + attr_file = 'psu_abs' + 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 == 0): - status = 1 + status = 1 return status - diff --git a/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/plugins/sfputil.py b/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/plugins/sfputil.py index 57edb81cd109..689710cf3f4d 100644 --- a/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/plugins/sfputil.py +++ b/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/plugins/sfputil.py @@ -19,7 +19,7 @@ class SfpUtil(SfpUtilBase): EEPROM_OFFSET = 41 CPLD1_PORTS = 12 CPLDx_PORTS = 13 - #TODO: check init sequence for CPLD i2c bus + # TODO: check init sequence for CPLD i2c bus CPLD_OFFSET = 1 CPLD_PRES_BIT = 1 CPLD_RESET_BIT = 0 @@ -32,72 +32,72 @@ class SfpUtil(SfpUtilBase): _port_to_eeprom_mapping = {} - #TODO: check the fp port to phy port mapping + # TODO: check the fp port to phy port mapping _fp2phy_port_mapping = { - 0: 0, - 1: 1, - 2: 4, - 3: 5, - 4: 8, - 5: 9, - 6: 12, - 7: 13, - 8: 16, - 9: 17, - 10: 20, - 11: 21, - 12: 24, - 13: 25, - 14: 28, - 15: 29, - 16: 32, - 17: 33, - 18: 36, - 19: 37, - 20: 40, - 21: 41, - 22: 44, - 23: 45, - 24: 48, - 25: 49, - 26: 52, - 27: 53, - 28: 56, - 29: 57, - 30: 60, - 31: 61, - 32: 2, - 33: 3, - 34: 6, - 35: 7, - 36: 10, - 37: 11, - 38: 14, - 39: 15, - 40: 18, - 41: 19, - 42: 22, - 43: 23, - 44: 26, - 45: 27, - 46: 30, - 47: 31, - 48: 34, - 49: 35, - 50: 38, - 51: 39, - 52: 42, - 53: 43, - 54: 46, - 55: 47, - 56: 50, - 57: 51, - 58: 54, - 59: 55, - 60: 58, - 61: 59, - 62: 62, - 63: 63 + 0: 0, + 1: 1, + 2: 4, + 3: 5, + 4: 8, + 5: 9, + 6: 12, + 7: 13, + 8: 16, + 9: 17, + 10: 20, + 11: 21, + 12: 24, + 13: 25, + 14: 28, + 15: 29, + 16: 32, + 17: 33, + 18: 36, + 19: 37, + 20: 40, + 21: 41, + 22: 44, + 23: 45, + 24: 48, + 25: 49, + 26: 52, + 27: 53, + 28: 56, + 29: 57, + 30: 60, + 31: 61, + 32: 2, + 33: 3, + 34: 6, + 35: 7, + 36: 10, + 37: 11, + 38: 14, + 39: 15, + 40: 18, + 41: 19, + 42: 22, + 43: 23, + 44: 26, + 45: 27, + 46: 30, + 47: 31, + 48: 34, + 49: 35, + 50: 38, + 51: 39, + 52: 42, + 53: 43, + 54: 46, + 55: 47, + 56: 50, + 57: 51, + 58: 54, + 59: 55, + 60: 58, + 61: 59, + 62: 62, + 63: 63 } @property @@ -110,13 +110,12 @@ def port_end(self): @property def qsfp_ports(self): - return range(0, self.PORTS_IN_BLOCK + 1) + return list(range(0, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): return self._port_to_eeprom_mapping - def __init__(self): # Override port_to_eeprom_mapping for class initialization eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-00{1}/eeprom" @@ -134,7 +133,7 @@ def qsfp_to_cpld_index(self, port_num): else: cpld_id = 1 + (port_num - self.CPLD1_PORTS) / self.CPLDx_PORTS cpld_port_index = ((port_num - self.CPLD1_PORTS) % self.CPLDx_PORTS) + 1 - return cpld_id, cpld_port_index + return cpld_id, cpld_port_index def fp2phy_port_num(self, fp_port_num): @@ -151,25 +150,25 @@ def get_presence(self, port_num): cpld_id, cpld_port_index = self.qsfp_to_cpld_index(port_num) i2c_id = self.CPLD_OFFSET + cpld_id - reg_path = self.CPLD_REG_PATH.format(i2c_id, self.CPLDx_I2C_ADDR, \ - self.CPLD_PORT_STATUS_KEY, cpld_port_index) + reg_path = self.CPLD_REG_PATH.format(i2c_id, self.CPLDx_I2C_ADDR, + self.CPLD_PORT_STATUS_KEY, cpld_port_index) try: reg_file = open(reg_path) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False # content is a string containing the status register value content = reg_file.readline().rstrip() reg_file.close() - + reg_value = int(content, 16) # mask for presence bit (bit 1) mask = (1 << self.CPLD_PRES_BIT) # 0 - presence, 1 - absence - if reg_value & mask == 0: + if reg_value & mask == 0: return True return False @@ -184,13 +183,13 @@ def get_low_power_mode(self, port_num): cpld_id, cpld_port_index = self.qsfp_to_cpld_index(port_num) i2c_id = self.CPLD_OFFSET + cpld_id - reg_path = self.CPLD_REG_PATH.format(i2c_id, self.CPLDx_I2C_ADDR, \ - self.CPLD_PORT_CONFIG_KEY, cpld_port_index) + reg_path = self.CPLD_REG_PATH.format(i2c_id, self.CPLDx_I2C_ADDR, + self.CPLD_PORT_CONFIG_KEY, cpld_port_index) try: reg_file = open(reg_path) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False # content is a string containing the status register value @@ -202,7 +201,7 @@ def get_low_power_mode(self, port_num): mask = (1 << self.CPLD_LPMOD_BIT) # 0 - disable, 1 - low power mode - if reg_value & mask == 0: + if reg_value & mask == 0: return False return True @@ -217,13 +216,13 @@ def set_low_power_mode(self, port_num, lpmode): cpld_id, cpld_port_index = self.qsfp_to_cpld_index(port_num) i2c_id = self.CPLD_OFFSET + cpld_id - reg_path = self.CPLD_REG_PATH.format(i2c_id, self.CPLDx_I2C_ADDR, \ - self.CPLD_PORT_CONFIG_KEY, cpld_port_index) + reg_path = self.CPLD_REG_PATH.format(i2c_id, self.CPLDx_I2C_ADDR, + self.CPLD_PORT_CONFIG_KEY, cpld_port_index) try: reg_file = open(reg_path, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False # content is a string containing the status register value @@ -257,14 +256,14 @@ def reset(self, port_num): cpld_id, cpld_port_index = self.qsfp_to_cpld_index(port_num) i2c_id = self.CPLD_OFFSET + cpld_id - reg_path = self.CPLD_REG_PATH.format(i2c_id, self.CPLDx_I2C_ADDR, \ - self.CPLD_PORT_CONFIG_KEY, cpld_port_index) + reg_path = self.CPLD_REG_PATH.format(i2c_id, self.CPLDx_I2C_ADDR, + self.CPLD_PORT_CONFIG_KEY, cpld_port_index) # reset the port try: reg_file = open(reg_path, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False # content is a string containing the status register value @@ -287,7 +286,7 @@ def reset(self, port_num): try: reg_file = open(reg_path, "w") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = reg_value | mask @@ -305,4 +304,3 @@ def get_transceiver_change_event(self): on this platform. """ raise NotImplementedError - diff --git a/device/inventec/x86_64-inventec_d6254qs-r0/plugins/eeprom.py b/device/inventec/x86_64-inventec_d6254qs-r0/plugins/eeprom.py index de5c24ba0e6d..31f847614fb0 100644 --- a/device/inventec/x86_64-inventec_d6254qs-r0/plugins/eeprom.py +++ b/device/inventec/x86_64-inventec_d6254qs-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Inventec d7032q28b # @@ -11,8 +9,8 @@ try: from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): diff --git a/device/inventec/x86_64-inventec_d6254qs-r0/plugins/psuutil.py b/device/inventec/x86_64-inventec_d6254qs-r0/plugins/psuutil.py index 4bd3f7a27052..162e240bae35 100644 --- a/device/inventec/x86_64-inventec_d6254qs-r0/plugins/psuutil.py +++ b/device/inventec/x86_64-inventec_d6254qs-r0/plugins/psuutil.py @@ -22,8 +22,8 @@ def __init__(self): # Get sysfs attribute def get_attr_value(self, attr_path): - - retval = 'ERR' + + retval = 'ERR' if (not os.path.isfile(attr_path)): return retval @@ -35,7 +35,7 @@ def get_attr_value(self, attr_path): retval = retval.rstrip(' \t\n\r') return retval - + def get_num_psus(self): """ Retrieves the number of PSUs available on the device @@ -53,14 +53,14 @@ def get_psu_status(self, index): faulty """ status = 0 - attr_file = 'psoc_psu'+ str(index) + '_iout' - attr_path = self.PSU_DIR +'/' + attr_file - + attr_file = 'psoc_psu' + str(index) + '_iout' + attr_path = self.PSU_DIR + '/' + attr_file + attr_value = self.get_attr_value(attr_path) if (attr_value != 'ERR'): # Check for PSU status if (attr_value != 0): - status = 1 + status = 1 return status def get_psu_presence(self, index): @@ -73,12 +73,12 @@ def get_psu_presence(self, index): status = 0 psu_absent = 0 ind = index-1 - attr_file ='psu'+ str(ind) - attr_path = self.PSU_DIR +'/' + attr_file - normal_attr_value = '0 : normal' + attr_file = 'psu' + str(ind) + attr_path = self.PSU_DIR + '/' + attr_file + normal_attr_value = '0 : normal' attr_value = self.get_attr_value(attr_path) if (attr_value != 'ERR'): # Check for PSU presence if (attr_value == normal_attr_value): - status = 1 + status = 1 return status diff --git a/device/inventec/x86_64-inventec_d6254qs-r0/plugins/sfputil.py b/device/inventec/x86_64-inventec_d6254qs-r0/plugins/sfputil.py index 6cd470795fb6..62a67f72e1a4 100644 --- a/device/inventec/x86_64-inventec_d6254qs-r0/plugins/sfputil.py +++ b/device/inventec/x86_64-inventec_d6254qs-r0/plugins/sfputil.py @@ -95,7 +95,7 @@ def qsfp_port_end(self): @property def qsfp_ports(self): - return range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1) + return list(range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -117,7 +117,7 @@ def get_presence(self, port_num): try: reg_file = open("/sys/class/swps/port"+str(port_num)+"/present") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = int(reg_file.readline().rstrip()) @@ -137,7 +137,7 @@ def get_low_power_mode(self, port_num): try: reg_file = open("/sys/class/swps/port"+str(port_num)+"/lpmod") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) reg_value = int(reg_file.readline().rstrip()) @@ -151,13 +151,13 @@ def set_low_power_mode(self, port_num, lpmode): if port_num < self.port_start or port_num > self.port_end: return False if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: - print "\nError:SFP's don't support this property" + print("\nError:SFP's don't support this property") return False try: reg_file = open("/sys/class/swps/port"+str(port_num)+"/lpmod", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = int(reg_file.readline().rstrip()) @@ -179,13 +179,13 @@ def reset(self, port_num): if port_num < self.port_start or port_num > self.port_end: return False if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: - print "\nError:SFP's don't support this property" + print("\nError:SFP's don't support this property") return False try: reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = 0 @@ -199,7 +199,7 @@ def reset(self, port_num): try: reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = 1 diff --git a/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/buffers.json.j2 b/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/buffers.json.j2 new file mode 100644 index 000000000000..0b1cb2c541b6 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} diff --git a/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/buffers_defaults_t1.j2 b/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..f77839cddf87 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/buffers_defaults_t1.j2 @@ -0,0 +1,46 @@ + +{%- set default_cable = '40m' %} + +{%- set PORT_ALL = [] %} + +{%- for port in PORT %} + {%- if PORT_ALL.append(port) %}{%- endif %} +{%- endfor %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "27678784", + "type": "ingress", + "mode": "dynamic", + "xoff": "4194112" + }, + "egress_lossy_pool": { + "size": "26045524", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "32786432", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "static_th":"3995680" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} \ No newline at end of file diff --git a/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/pg_profile_lookup.ini b/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/pg_profile_lookup.ini new file mode 100644 index 000000000000..7222f8014925 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 1248 2288 35776 -4 2288 + 25000 5m 1248 2288 53248 -4 2288 + 40000 5m 1248 2288 66560 -4 2288 + 50000 5m 1248 2288 79872 -4 2288 + 100000 5m 1248 2288 165568 -4 2288 + 10000 40m 1248 2288 37024 -4 2288 + 25000 40m 1248 2288 56160 -4 2288 + 40000 40m 1248 2288 71552 -4 2288 + 50000 40m 1248 2288 85696 -4 2288 + 100000 40m 1248 2288 177632 -4 2288 + 10000 300m 1248 2288 46176 -4 2288 + 25000 300m 1248 2288 79040 -4 2288 + 40000 300m 1248 2288 108160 -4 2288 + 50000 300m 1248 2288 131456 -4 2288 + 100000 300m 1248 2288 268736 -4 2288 diff --git a/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/port_config.ini b/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/port_config.ini new file mode 100755 index 000000000000..d0ce46c7a8fe --- /dev/null +++ b/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/port_config.ini @@ -0,0 +1,33 @@ +# name lanes index speed autoneg +Ethernet0 21,22,23,24 0 100000 0 +Ethernet4 17,18,19,20 1 100000 0 +Ethernet8 25,26,27,28 2 100000 0 +Ethernet12 29,30,31,32 3 100000 0 +Ethernet16 37,38,39,40 4 100000 0 +Ethernet20 33,34,35,36 5 100000 0 +Ethernet24 41,42,43,44 6 100000 0 +Ethernet28 45,46,47,48 7 100000 0 +Ethernet32 5,6,7,8 8 100000 0 +Ethernet36 1,2,3,4 9 100000 0 +Ethernet40 9,10,11,12 10 100000 0 +Ethernet44 13,14,15,16 11 100000 0 +Ethernet48 53,54,55,56 12 100000 0 +Ethernet52 49,50,51,52 13 100000 0 +Ethernet56 57,58,59,60 14 100000 0 +Ethernet60 61,62,63,64 15 100000 0 +Ethernet64 69,70,71,72 16 100000 0 +Ethernet68 65,66,67,68 17 100000 0 +Ethernet72 73,74,75,76 18 100000 0 +Ethernet76 77,78,79,80 19 100000 0 +Ethernet80 117,118,119,120 20 100000 0 +Ethernet84 113,114,115,116 21 100000 0 +Ethernet88 121,122,123,124 22 100000 0 +Ethernet92 125,126,127,128 23 100000 0 +Ethernet96 85,86,87,88 24 100000 0 +Ethernet100 81,82,83,84 25 100000 0 +Ethernet104 89,90,91,92 26 100000 0 +Ethernet108 93,94,95,96 27 100000 0 +Ethernet112 101,102,103,104 28 100000 0 +Ethernet116 97,98,99,100 29 100000 0 +Ethernet120 105,106,107,108 30 100000 0 +Ethernet124 109,110,111,112 31 100000 0 diff --git a/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/qos.json.j2 b/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/qos.json.j2 new file mode 100644 index 000000000000..3b909e0adbbc --- /dev/null +++ b/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/qos.json.j2 @@ -0,0 +1,161 @@ +{%- set PORT_ALL = [] %} + +{%- for port in PORT %} + {%- if PORT_ALL.append(port) %}{%- endif %} +{%- endfor %} + +{ + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "MAP_PFC_PRIORITY_TO_QUEUE": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"3", + "4":"4", + "5":"0", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "SCHEDULER": { + "scheduler.0" : { + "type":"DWRR", + "weight": "25" + }, + "scheduler.1" : { + "type":"DWRR", + "weight": "30" + }, + "scheduler.2" : { + "type":"DWRR", + "weight": "20" + } + }, + "PORT_QOS_MAP": { + "{{ PORT_ALL|join(',') }}": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable": "3,4" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "wred_red_enable":"true", + "ecn":"ecn_all", + "red_max_threshold":"312000", + "red_min_threshold":"104000", + "yellow_max_threshold":"312000", + "yellow_min_threshold":"104000", + "green_max_threshold": "312000", + "green_min_threshold": "104000" + } + }, + "QUEUE": { + "{{ PORT_ALL|join(',') }}|3-4" : { + "scheduler" : "[SCHEDULER|scheduler.0]", + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "{{ PORT_ALL|join(',') }}|0" : { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, + "{{ PORT_ALL|join(',') }}|1" : { + "scheduler" : "[SCHEDULER|scheduler.2]" + } + } +} diff --git a/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/sai.profile b/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/sai.profile new file mode 100755 index 000000000000..51c00abc35f7 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-d6332-32x100G-SR4.config.bcm +SAI_NUM_ECMP_MEMBERS=32 diff --git a/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/td3-d6332-32x100G-SR4.config.bcm b/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/td3-d6332-32x100G-SR4.config.bcm new file mode 100644 index 000000000000..8fe7622f4b8f --- /dev/null +++ b/device/inventec/x86_64-inventec_d6332-r0/INVENTEC-D6332/td3-d6332-32x100G-SR4.config.bcm @@ -0,0 +1,669 @@ +sai_load_hw_config=/etc/bcm/flex/bcm56870_a0_issu/b870.6.4.1/ +### fix for sonic +ptp_ts_pll_fref=50000000 +ptp_bs_fref_0=50000000 +ptp_bs_fref_1=50000000 +ifp_inports_support_enable=1 +### end fix + +core_clock_frequency=1525 +dpp_clock_ratio=2:3 + +oversubscribe_mode=1 +pbmp_xport_xe=0xc888888888888888e2222222222222222 + +l2_mem_entries=32768 +l3_mem_entries=16384 +fpem_mem_entries=16384 +l2xmsg_mode=1 + +pdma_descriptor_prefetch_enable=1 + +port_flex_enable=1 +stable_size=0x5500000 + + +### Loopback port +#portmap_65=130:10 +#portmap_131=131:10 + +portmap_1=1:100 +portmap_5=5:100 +portmap_9=9:100 +portmap_13=13:100 +portmap_17=17:100 +portmap_21=21:100 +portmap_25=25:100 +portmap_29=29:100 + +### Pipeline0, halfpipe 1 (8x100G) +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_57=57:100 +portmap_61=61:100 + +### Pipeline 1 +### First management port +#portmap_66=129:10:m +### Second management port +#portmap_130=128:10:m + +### Pipeline 1, halfpipe 0 (8x100G) +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 + +### Pipeline 1, halfpipe 1 (8x100G) +portmap_99=97:100 +portmap_103=101:100 +portmap_107=105:100 +portmap_111=109:100 +portmap_115=113:100 +portmap_119=117:100 +portmap_123=121:100 +portmap_127=125:100 + + +#dport part +dport_map_port_21=1 +dport_map_port_17=2 +dport_map_port_25=3 +dport_map_port_29=4 +dport_map_port_37=5 +dport_map_port_33=6 +dport_map_port_41=7 +dport_map_port_45=8 +dport_map_port_5=9 +dport_map_port_1=10 +dport_map_port_9=11 +dport_map_port_13=12 +dport_map_port_53=13 +dport_map_port_49=14 +dport_map_port_57=15 +dport_map_port_61=16 +dport_map_port_71=17 +dport_map_port_67=18 +dport_map_port_75=19 +dport_map_port_79=20 +dport_map_port_119=21 +dport_map_port_115=22 +dport_map_port_123=23 +dport_map_port_127=24 +dport_map_port_87=25 +dport_map_port_83=26 +dport_map_port_91=27 +dport_map_port_95=28 +dport_map_port_103=29 +dport_map_port_99=30 +dport_map_port_107=31 +dport_map_port_111=32 + + + + +#Polarity flips +#FC0 +phy_chain_rx_polarity_flip_physical{1.0}=0x0 +phy_chain_rx_polarity_flip_physical{2.0}=0x0 +phy_chain_rx_polarity_flip_physical{3.0}=0x1 +phy_chain_rx_polarity_flip_physical{4.0}=0x1 +phy_chain_tx_polarity_flip_physical{1.0}=0x0 +phy_chain_tx_polarity_flip_physical{2.0}=0x0 +phy_chain_tx_polarity_flip_physical{3.0}=0x1 +phy_chain_tx_polarity_flip_physical{4.0}=0x1 + +#FC1 +phy_chain_rx_polarity_flip_physical{5.0}=0x1 +phy_chain_rx_polarity_flip_physical{6.0}=0x1 +phy_chain_rx_polarity_flip_physical{7.0}=0x0 +phy_chain_rx_polarity_flip_physical{8.0}=0x0 +phy_chain_tx_polarity_flip_physical{5.0}=0x0 +phy_chain_tx_polarity_flip_physical{6.0}=0x0 +phy_chain_tx_polarity_flip_physical{7.0}=0x1 +phy_chain_tx_polarity_flip_physical{8.0}=0x1 + +#FC2 +phy_chain_rx_polarity_flip_physical{9.0}=0x0 +phy_chain_rx_polarity_flip_physical{10.0}=0x0 +phy_chain_rx_polarity_flip_physical{11.0}=0x1 +phy_chain_rx_polarity_flip_physical{12.0}=0x1 +phy_chain_tx_polarity_flip_physical{9.0}=0x0 +phy_chain_tx_polarity_flip_physical{10.0}=0x1 +phy_chain_tx_polarity_flip_physical{11.0}=0x1 +phy_chain_tx_polarity_flip_physical{12.0}=0x1 + +#FC3 +phy_chain_rx_polarity_flip_physical{13.0}=0x1 +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_tx_polarity_flip_physical{13.0}=0x0 +phy_chain_tx_polarity_flip_physical{14.0}=0x0 +phy_chain_tx_polarity_flip_physical{15.0}=0x1 +phy_chain_tx_polarity_flip_physical{16.0}=0x1 + +#FC4 +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}=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}=0x1 +phy_chain_tx_polarity_flip_physical{20.0}=0x1 + +#FC5 +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_tx_polarity_flip_physical{21.0}=0x0 +phy_chain_tx_polarity_flip_physical{22.0}=0x0 +phy_chain_tx_polarity_flip_physical{23.0}=0x1 +phy_chain_tx_polarity_flip_physical{24.0}=0x1 + +#FC6 +phy_chain_rx_polarity_flip_physical{25.0}=0x1 +phy_chain_rx_polarity_flip_physical{26.0}=0x1 +phy_chain_rx_polarity_flip_physical{27.0}=0x0 +phy_chain_rx_polarity_flip_physical{28.0}=0x0 +phy_chain_tx_polarity_flip_physical{25.0}=0x0 +phy_chain_tx_polarity_flip_physical{26.0}=0x1 +phy_chain_tx_polarity_flip_physical{27.0}=0x1 +phy_chain_tx_polarity_flip_physical{28.0}=0x1 + +#FC7 +phy_chain_rx_polarity_flip_physical{29.0}=0x0 +phy_chain_rx_polarity_flip_physical{30.0}=0x0 +phy_chain_rx_polarity_flip_physical{31.0}=0x1 +phy_chain_rx_polarity_flip_physical{32.0}=0x1 +phy_chain_tx_polarity_flip_physical{29.0}=0x0 +phy_chain_tx_polarity_flip_physical{30.0}=0x0 +phy_chain_tx_polarity_flip_physical{31.0}=0x1 +phy_chain_tx_polarity_flip_physical{32.0}=0x1 + +#FC8 +phy_chain_rx_polarity_flip_physical{33.0}=0x1 +phy_chain_rx_polarity_flip_physical{34.0}=0x1 +phy_chain_rx_polarity_flip_physical{35.0}=0x0 +phy_chain_rx_polarity_flip_physical{36.0}=0x0 +phy_chain_tx_polarity_flip_physical{33.0}=0x0 +phy_chain_tx_polarity_flip_physical{34.0}=0x0 +phy_chain_tx_polarity_flip_physical{35.0}=0x1 +phy_chain_tx_polarity_flip_physical{36.0}=0x1 + +#FC9 +phy_chain_rx_polarity_flip_physical{37.0}=0x0 +phy_chain_rx_polarity_flip_physical{38.0}=0x0 +phy_chain_rx_polarity_flip_physical{39.0}=0x1 +phy_chain_rx_polarity_flip_physical{40.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 + +#FC10 +phy_chain_rx_polarity_flip_physical{41.0}=0x1 +phy_chain_rx_polarity_flip_physical{42.0}=0x1 +phy_chain_rx_polarity_flip_physical{43.0}=0x0 +phy_chain_rx_polarity_flip_physical{44.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 + +#FC11 +phy_chain_rx_polarity_flip_physical{45.0}=0x0 +phy_chain_rx_polarity_flip_physical{46.0}=0x0 +phy_chain_rx_polarity_flip_physical{47.0}=0x1 +phy_chain_rx_polarity_flip_physical{48.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 + +#FC12 +phy_chain_rx_polarity_flip_physical{49.0}=0x1 +phy_chain_rx_polarity_flip_physical{50.0}=0x0 +phy_chain_rx_polarity_flip_physical{51.0}=0x1 +phy_chain_rx_polarity_flip_physical{52.0}=0x0 +phy_chain_tx_polarity_flip_physical{49.0}=0x0 +phy_chain_tx_polarity_flip_physical{50.0}=0x0 +phy_chain_tx_polarity_flip_physical{51.0}=0x1 +phy_chain_tx_polarity_flip_physical{52.0}=0x1 + +#FC13 +phy_chain_rx_polarity_flip_physical{53.0}=0x0 +phy_chain_rx_polarity_flip_physical{54.0}=0x0 +phy_chain_rx_polarity_flip_physical{55.0}=0x1 +phy_chain_rx_polarity_flip_physical{56.0}=0x1 +phy_chain_tx_polarity_flip_physical{53.0}=0x1 +phy_chain_tx_polarity_flip_physical{54.0}=0x1 +phy_chain_tx_polarity_flip_physical{55.0}=0x0 +phy_chain_tx_polarity_flip_physical{56.0}=0x0 + +#FC14 +phy_chain_rx_polarity_flip_physical{57.0}=0x1 +phy_chain_rx_polarity_flip_physical{58.0}=0x1 +phy_chain_rx_polarity_flip_physical{59.0}=0x0 +phy_chain_rx_polarity_flip_physical{60.0}=0x0 +phy_chain_tx_polarity_flip_physical{57.0}=0x1 +phy_chain_tx_polarity_flip_physical{58.0}=0x0 +phy_chain_tx_polarity_flip_physical{59.0}=0x0 +phy_chain_tx_polarity_flip_physical{60.0}=0x0 + +#FC15 +phy_chain_rx_polarity_flip_physical{61.0}=0x0 +phy_chain_rx_polarity_flip_physical{62.0}=0x0 +phy_chain_rx_polarity_flip_physical{63.0}=0x1 +phy_chain_rx_polarity_flip_physical{64.0}=0x1 +phy_chain_tx_polarity_flip_physical{61.0}=0x1 +phy_chain_tx_polarity_flip_physical{62.0}=0x1 +phy_chain_tx_polarity_flip_physical{63.0}=0x0 +phy_chain_tx_polarity_flip_physical{64.0}=0x0 + +#FC16 +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}=0x0 +phy_chain_tx_polarity_flip_physical{65.0}=0x0 +phy_chain_tx_polarity_flip_physical{66.0}=0x0 +phy_chain_tx_polarity_flip_physical{67.0}=0x1 +phy_chain_tx_polarity_flip_physical{68.0}=0x1 + +#FC17 +phy_chain_rx_polarity_flip_physical{69.0}=0x0 +phy_chain_rx_polarity_flip_physical{70.0}=0x0 +phy_chain_rx_polarity_flip_physical{71.0}=0x1 +phy_chain_rx_polarity_flip_physical{72.0}=0x1 +phy_chain_tx_polarity_flip_physical{69.0}=0x1 +phy_chain_tx_polarity_flip_physical{70.0}=0x0 +phy_chain_tx_polarity_flip_physical{71.0}=0x0 +phy_chain_tx_polarity_flip_physical{72.0}=0x1 + +#FC18 +phy_chain_rx_polarity_flip_physical{73.0}=0x1 +phy_chain_rx_polarity_flip_physical{74.0}=0x1 +phy_chain_rx_polarity_flip_physical{75.0}=0x0 +phy_chain_rx_polarity_flip_physical{76.0}=0x0 +phy_chain_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 + +#FC19 +phy_chain_rx_polarity_flip_physical{77.0}=0x0 +phy_chain_rx_polarity_flip_physical{78.0}=0x1 +phy_chain_rx_polarity_flip_physical{79.0}=0x0 +phy_chain_rx_polarity_flip_physical{80.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 + +#FC20 +phy_chain_rx_polarity_flip_physical{81.0}=0x0 +phy_chain_rx_polarity_flip_physical{82.0}=0x0 +phy_chain_rx_polarity_flip_physical{83.0}=0x1 +phy_chain_rx_polarity_flip_physical{84.0}=0x1 +phy_chain_tx_polarity_flip_physical{81.0}=0x0 +phy_chain_tx_polarity_flip_physical{82.0}=0x0 +phy_chain_tx_polarity_flip_physical{83.0}=0x1 +phy_chain_tx_polarity_flip_physical{84.0}=0x1 + +#FC21 +phy_chain_rx_polarity_flip_physical{85.0}=0x1 +phy_chain_rx_polarity_flip_physical{86.0}=0x1 +phy_chain_rx_polarity_flip_physical{87.0}=0x0 +phy_chain_rx_polarity_flip_physical{88.0}=0x0 +phy_chain_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 + +#FC22 +phy_chain_rx_polarity_flip_physical{89.0}=0x0 +phy_chain_rx_polarity_flip_physical{90.0}=0x0 +phy_chain_rx_polarity_flip_physical{91.0}=0x1 +phy_chain_rx_polarity_flip_physical{92.0}=0x1 +phy_chain_tx_polarity_flip_physical{89.0}=0x0 +phy_chain_tx_polarity_flip_physical{90.0}=0x1 +phy_chain_tx_polarity_flip_physical{91.0}=0x1 +phy_chain_tx_polarity_flip_physical{92.0}=0x1 + +#FC23 +phy_chain_rx_polarity_flip_physical{93.0}=0x1 +phy_chain_rx_polarity_flip_physical{94.0}=0x1 +phy_chain_rx_polarity_flip_physical{95.0}=0x0 +phy_chain_rx_polarity_flip_physical{96.0}=0x0 +phy_chain_tx_polarity_flip_physical{93.0}=0x0 +phy_chain_tx_polarity_flip_physical{94.0}=0x0 +phy_chain_tx_polarity_flip_physical{95.0}=0x1 +phy_chain_tx_polarity_flip_physical{96.0}=0x1 + +#FC24 +phy_chain_rx_polarity_flip_physical{97.0}=0x0 +phy_chain_rx_polarity_flip_physical{98.0}=0x0 +phy_chain_rx_polarity_flip_physical{99.0}=0x1 +phy_chain_rx_polarity_flip_physical{100.0}=0x1 +phy_chain_tx_polarity_flip_physical{97.0}=0x0 +phy_chain_tx_polarity_flip_physical{98.0}=0x0 +phy_chain_tx_polarity_flip_physical{99.0}=0x1 +phy_chain_tx_polarity_flip_physical{100.0}=0x1 + +#FC25 +phy_chain_rx_polarity_flip_physical{101.0}=0x1 +phy_chain_rx_polarity_flip_physical{102.0}=0x1 +phy_chain_rx_polarity_flip_physical{103.0}=0x0 +phy_chain_rx_polarity_flip_physical{104.0}=0x0 +phy_chain_tx_polarity_flip_physical{101.0}=0x0 +phy_chain_tx_polarity_flip_physical{102.0}=0x0 +phy_chain_tx_polarity_flip_physical{103.0}=0x1 +phy_chain_tx_polarity_flip_physical{104.0}=0x1 + +#FC26 +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}=0x0 +phy_chain_rx_polarity_flip_physical{108.0}=0x0 +phy_chain_tx_polarity_flip_physical{105.0}=0x0 +phy_chain_tx_polarity_flip_physical{106.0}=0x1 +phy_chain_tx_polarity_flip_physical{107.0}=0x1 +phy_chain_tx_polarity_flip_physical{108.0}=0x1 + +#FC27 +phy_chain_rx_polarity_flip_physical{109.0}=0x0 +phy_chain_rx_polarity_flip_physical{110.0}=0x0 +phy_chain_rx_polarity_flip_physical{111.0}=0x1 +phy_chain_rx_polarity_flip_physical{112.0}=0x1 +phy_chain_tx_polarity_flip_physical{109.0}=0x0 +phy_chain_tx_polarity_flip_physical{110.0}=0x0 +phy_chain_tx_polarity_flip_physical{111.0}=0x1 +phy_chain_tx_polarity_flip_physical{112.0}=0x1 + +#FC28 +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}=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}=0x1 +phy_chain_tx_polarity_flip_physical{116.0}=0x1 + +#FC29 +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_tx_polarity_flip_physical{117.0}=0x0 +phy_chain_tx_polarity_flip_physical{118.0}=0x0 +phy_chain_tx_polarity_flip_physical{119.0}=0x1 +phy_chain_tx_polarity_flip_physical{120.0}=0x1 + +#FC30 +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}=0x0 +phy_chain_rx_polarity_flip_physical{124.0}=0x0 +phy_chain_tx_polarity_flip_physical{121.0}=0x0 +phy_chain_tx_polarity_flip_physical{122.0}=0x1 +phy_chain_tx_polarity_flip_physical{123.0}=0x1 +phy_chain_tx_polarity_flip_physical{124.0}=0x1 + +#FC31 +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_tx_polarity_flip_physical{125.0}=0x0 +phy_chain_tx_polarity_flip_physical{126.0}=0x0 +phy_chain_tx_polarity_flip_physical{127.0}=0x1 +phy_chain_tx_polarity_flip_physical{128.0}=0x1 + +#lanes swap +#FC0~FC7 +phy_chain_rx_lane_map_physical{1.0}=0x1302 +phy_chain_tx_lane_map_physical{1.0}=0x2031 +phy_chain_rx_lane_map_physical{5.0}=0x3120 +phy_chain_tx_lane_map_physical{5.0}=0x2031 +phy_chain_rx_lane_map_physical{9.0}=0x1302 +phy_chain_tx_lane_map_physical{9.0}=0x2031 +phy_chain_rx_lane_map_physical{13.0}=0x3120 +phy_chain_tx_lane_map_physical{13.0}=0x0213 +phy_chain_rx_lane_map_physical{17.0}=0x1302 +phy_chain_tx_lane_map_physical{17.0}=0x2031 +phy_chain_rx_lane_map_physical{21.0}=0x3120 +phy_chain_tx_lane_map_physical{21.0}=0x0213 +phy_chain_rx_lane_map_physical{25.0}=0x1302 +phy_chain_tx_lane_map_physical{25.0}=0x2031 +phy_chain_rx_lane_map_physical{29.0}=0x3120 +phy_chain_tx_lane_map_physical{29.0}=0x0213 + +#FC8~FC15 +phy_chain_rx_lane_map_physical{33.0}=0x1302 +phy_chain_tx_lane_map_physical{33.0}=0x2031 +phy_chain_rx_lane_map_physical{37.0}=0x3120 +phy_chain_tx_lane_map_physical{37.0}=0x0213 +phy_chain_rx_lane_map_physical{41.0}=0x1302 +phy_chain_tx_lane_map_physical{41.0}=0x2031 +phy_chain_rx_lane_map_physical{45.0}=0x3120 +phy_chain_tx_lane_map_physical{45.0}=0x0213 +phy_chain_rx_lane_map_physical{49.0}=0x2301 +phy_chain_tx_lane_map_physical{49.0}=0x2031 +phy_chain_rx_lane_map_physical{53.0}=0x3120 +phy_chain_tx_lane_map_physical{53.0}=0x2031 +phy_chain_rx_lane_map_physical{57.0}=0x1302 +phy_chain_tx_lane_map_physical{57.0}=0x2031 +phy_chain_rx_lane_map_physical{61.0}=0x3120 +phy_chain_tx_lane_map_physical{61.0}=0x0213 + +#FC16~FC23 +phy_chain_rx_lane_map_physical{65.0}=0x2031 +phy_chain_tx_lane_map_physical{65.0}=0x1302 +phy_chain_rx_lane_map_physical{69.0}=0x0213 +phy_chain_tx_lane_map_physical{69.0}=0x3201 +phy_chain_rx_lane_map_physical{73.0}=0x2031 +phy_chain_tx_lane_map_physical{73.0}=0x1302 +phy_chain_rx_lane_map_physical{77.0}=0x0123 +phy_chain_tx_lane_map_physical{77.0}=0x3120 +phy_chain_rx_lane_map_physical{81.0}=0x2031 +phy_chain_tx_lane_map_physical{81.0}=0x1302 +phy_chain_rx_lane_map_physical{85.0}=0x0213 +phy_chain_tx_lane_map_physical{85.0}=0x1302 +phy_chain_rx_lane_map_physical{89.0}=0x2031 +phy_chain_tx_lane_map_physical{89.0}=0x1302 +phy_chain_rx_lane_map_physical{93.0}=0x0213 +phy_chain_tx_lane_map_physical{93.0}=0x3120 + +#FC24~FC31 +phy_chain_rx_lane_map_physical{97.0}=0x2031 +phy_chain_tx_lane_map_physical{97.0}=0x1302 +phy_chain_rx_lane_map_physical{101.0}=0x2031 +phy_chain_tx_lane_map_physical{101.0}=0x1302 +phy_chain_rx_lane_map_physical{105.0}=0x2031 +phy_chain_tx_lane_map_physical{105.0}=0x1302 +phy_chain_rx_lane_map_physical{109.0}=0x0213 +phy_chain_tx_lane_map_physical{109.0}=0x3120 +phy_chain_rx_lane_map_physical{113.0}=0x2031 +phy_chain_tx_lane_map_physical{113.0}=0x1302 +phy_chain_rx_lane_map_physical{117.0}=0x0213 +phy_chain_tx_lane_map_physical{117.0}=0x1302 +phy_chain_rx_lane_map_physical{121.0}=0x2031 +phy_chain_tx_lane_map_physical{121.0}=0x1302 +phy_chain_rx_lane_map_physical{125.0}=0x0213 +phy_chain_tx_lane_map_physical{125.0}=0x3120 + + +serdes_preemphasis_lane0_21=0x11490A +serdes_preemphasis_lane1_21=0x11490A +serdes_preemphasis_lane2_21=0x11490A +serdes_preemphasis_lane3_21=0x11490A +serdes_preemphasis_lane0_17=0x12480A +serdes_preemphasis_lane1_17=0x12480A +serdes_preemphasis_lane2_17=0x12480A +serdes_preemphasis_lane3_17=0x12480A +serdes_preemphasis_lane0_25=0x104A0A +serdes_preemphasis_lane1_25=0x104A0A +serdes_preemphasis_lane2_25=0x104A0A +serdes_preemphasis_lane3_25=0x104A0A +serdes_preemphasis_lane0_29=0x104A0A +serdes_preemphasis_lane1_29=0x104A0A +serdes_preemphasis_lane2_29=0x104A0A +serdes_preemphasis_lane3_29=0x104A0A +serdes_preemphasis_lane0_37=0x0F4B0A +serdes_preemphasis_lane1_37=0x0F4B0A +serdes_preemphasis_lane2_37=0x0F4B0A +serdes_preemphasis_lane3_37=0x0F4B0A +serdes_preemphasis_lane0_33=0x0F4B0A +serdes_preemphasis_lane1_33=0x104A0A +serdes_preemphasis_lane2_33=0x0F4B0A +serdes_preemphasis_lane3_33=0x104A0A +serdes_preemphasis_lane0_41=0x0E4C0A +serdes_preemphasis_lane1_41=0x0F4B0A +serdes_preemphasis_lane2_41=0x0E4C0A +serdes_preemphasis_lane3_41=0x0F4B0A +serdes_preemphasis_lane0_45=0x0E4C0A +serdes_preemphasis_lane1_45=0x0E4C0A +serdes_preemphasis_lane2_45=0x0E4C0A +serdes_preemphasis_lane3_45=0x0E4C0A +serdes_preemphasis_lane0_5=0x0F4B0A +serdes_preemphasis_lane1_5=0x0F4B0A +serdes_preemphasis_lane2_5=0x0F4B0A +serdes_preemphasis_lane3_5=0x0F4B0A +serdes_preemphasis_lane0_1=0x0F4B0A +serdes_preemphasis_lane1_1=0x0F4B0A +serdes_preemphasis_lane2_1=0x0F4B0A +serdes_preemphasis_lane3_1=0x0F4B0A +serdes_preemphasis_lane0_9=0x0E4C0A +serdes_preemphasis_lane1_9=0x0F4B0A +serdes_preemphasis_lane2_9=0x0E4C0A +serdes_preemphasis_lane3_9=0x0F4B0A +serdes_preemphasis_lane0_13=0x0E4C0A +serdes_preemphasis_lane1_13=0x0F4B0A +serdes_preemphasis_lane2_13=0x0E4C0A +serdes_preemphasis_lane3_13=0x0F4B0A +serdes_preemphasis_lane0_53=0x05550A +serdes_preemphasis_lane1_53=0x07530A +serdes_preemphasis_lane2_53=0x05550A +serdes_preemphasis_lane3_53=0x07530A +serdes_preemphasis_lane0_49=0x07530A +serdes_preemphasis_lane1_49=0x0A500A +serdes_preemphasis_lane2_49=0x07530A +serdes_preemphasis_lane3_49=0x0A500A +serdes_preemphasis_lane0_57=0x05550A +serdes_preemphasis_lane1_57=0x05550A +serdes_preemphasis_lane2_57=0x05550A +serdes_preemphasis_lane3_57=0x07530A +serdes_preemphasis_lane0_61=0x07530A +serdes_preemphasis_lane1_61=0x07530A +serdes_preemphasis_lane2_61=0x07530A +serdes_preemphasis_lane3_61=0x0A500A +serdes_preemphasis_lane0_71=0x05550A +serdes_preemphasis_lane1_71=0x05550A +serdes_preemphasis_lane2_71=0x05550A +serdes_preemphasis_lane3_71=0x05550A +serdes_preemphasis_lane0_67=0x07530A +serdes_preemphasis_lane1_67=0x07530A +serdes_preemphasis_lane2_67=0x05550A +serdes_preemphasis_lane3_67=0x07530A +serdes_preemphasis_lane0_75=0x05550A +serdes_preemphasis_lane1_75=0x07530A +serdes_preemphasis_lane2_75=0x05550A +serdes_preemphasis_lane3_75=0x05550A +serdes_preemphasis_lane0_79=0x07530A +serdes_preemphasis_lane1_79=0x0A500A +serdes_preemphasis_lane2_79=0x07530A +serdes_preemphasis_lane3_79=0x0A500A +serdes_preemphasis_lane0_119=0x0E4C0A +serdes_preemphasis_lane1_119=0x0F4B0A +serdes_preemphasis_lane2_119=0x0E4C0A +serdes_preemphasis_lane3_119=0x0F4B0A +serdes_preemphasis_lane0_115=0x0E4C0A +serdes_preemphasis_lane1_115=0x0E4C0A +serdes_preemphasis_lane2_115=0x0F4B0A +serdes_preemphasis_lane3_115=0x0E4C0A +serdes_preemphasis_lane0_123=0x0F4B0A +serdes_preemphasis_lane1_123=0x0F4B0A +serdes_preemphasis_lane2_123=0x0F4B0A +serdes_preemphasis_lane3_123=0x0F4B0A +serdes_preemphasis_lane0_127=0x0F4B0A +serdes_preemphasis_lane1_127=0x0F4B0A +serdes_preemphasis_lane2_127=0x0F4B0A +serdes_preemphasis_lane3_127=0x0F4B0A +serdes_preemphasis_lane0_87=0x0E4C0A +serdes_preemphasis_lane1_87=0x0E4C0A +serdes_preemphasis_lane2_87=0x0E4C0A +serdes_preemphasis_lane3_87=0x0E4C0A +serdes_preemphasis_lane0_83=0x0F4B0A +serdes_preemphasis_lane1_83=0x0F4B0A +serdes_preemphasis_lane2_83=0x0F4B0A +serdes_preemphasis_lane3_83=0x0F4B0A +serdes_preemphasis_lane0_91=0x0F4B0A +serdes_preemphasis_lane1_91=0x0F4B0A +serdes_preemphasis_lane2_91=0x0F4B0A +serdes_preemphasis_lane3_91=0x0F4B0A +serdes_preemphasis_lane0_95=0x0F4B0A +serdes_preemphasis_lane1_95=0x104A0A +serdes_preemphasis_lane2_95=0x0F4B0A +serdes_preemphasis_lane3_95=0x104A0A +serdes_preemphasis_lane0_103=0x104A0A +serdes_preemphasis_lane1_103=0x104A0A +serdes_preemphasis_lane2_103=0x104A0A +serdes_preemphasis_lane3_103=0x104A0A +serdes_preemphasis_lane0_99=0x104A0A +serdes_preemphasis_lane1_99=0x104A0A +serdes_preemphasis_lane2_99=0x104A0A +serdes_preemphasis_lane3_99=0x104A0A +serdes_preemphasis_lane0_107=0x104A0A +serdes_preemphasis_lane1_107=0x11490A +serdes_preemphasis_lane2_107=0x104A0A +serdes_preemphasis_lane3_107=0x11490A +serdes_preemphasis_lane0_111=0x11490A +serdes_preemphasis_lane1_111=0x12480A +serdes_preemphasis_lane2_111=0x11490A +serdes_preemphasis_lane3_111=0x12480A + + +serdes_if_type_21=28 +serdes_if_type_17=28 +serdes_if_type_25=28 +serdes_if_type_29=28 +serdes_if_type_37=28 +serdes_if_type_33=28 +serdes_if_type_41=28 +serdes_if_type_45=28 +serdes_if_type_5=28 +serdes_if_type_1=28 +serdes_if_type_9=28 +serdes_if_type_13=28 +serdes_if_type_53=28 +serdes_if_type_49=28 +serdes_if_type_57=28 +serdes_if_type_61=28 +serdes_if_type_71=28 +serdes_if_type_67=28 +serdes_if_type_75=28 +serdes_if_type_79=28 +serdes_if_type_119=28 +serdes_if_type_115=28 +serdes_if_type_123=28 +serdes_if_type_127=28 +serdes_if_type_87=28 +serdes_if_type_83=28 +serdes_if_type_91=28 +serdes_if_type_95=28 +serdes_if_type_103=28 +serdes_if_type_99=28 +serdes_if_type_107=28 +serdes_if_type_111=28 diff --git a/device/inventec/x86_64-inventec_d6332-r0/custom_init.soc.j2 b/device/inventec/x86_64-inventec_d6332-r0/custom_init.soc.j2 new file mode 100644 index 000000000000..2149cb5a596e --- /dev/null +++ b/device/inventec/x86_64-inventec_d6332-r0/custom_init.soc.j2 @@ -0,0 +1,3 @@ +phy xe AN_X4_LD_BASE_ABIL3r BASE_25G_CR1_EN=1 +phy ce AN_X4_LD_BASE_ABIL1r 0x01ff +setreg CLMAC_TX_MAC_SA 0x{{ DEVICE_METADATA.localhost.mac|replace(":","")}} diff --git a/device/inventec/x86_64-inventec_d6332-r0/custom_led.bin b/device/inventec/x86_64-inventec_d6332-r0/custom_led.bin new file mode 100644 index 000000000000..adaab507cb90 Binary files /dev/null and b/device/inventec/x86_64-inventec_d6332-r0/custom_led.bin differ diff --git a/device/inventec/x86_64-inventec_d6332-r0/default_sku b/device/inventec/x86_64-inventec_d6332-r0/default_sku new file mode 100644 index 000000000000..e07c80931dde --- /dev/null +++ b/device/inventec/x86_64-inventec_d6332-r0/default_sku @@ -0,0 +1 @@ +INVENTEC-D6332 t1 diff --git a/device/inventec/x86_64-inventec_d6332-r0/installer.conf b/device/inventec/x86_64-inventec_d6332-r0/installer.conf new file mode 100644 index 000000000000..1db64ba02c38 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6332-r0/installer.conf @@ -0,0 +1,4 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 +CONSOLE_SPEED=115200 +VAR_LOG_SIZE=1024 diff --git a/device/inventec/x86_64-inventec_d6332-r0/led_proc_init.soc b/device/inventec/x86_64-inventec_d6332-r0/led_proc_init.soc new file mode 100644 index 000000000000..5dcf85ea7956 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6332-r0/led_proc_init.soc @@ -0,0 +1,5 @@ +led auto off +led stop +m0 load 0 0x3800 /usr/share/sonic/platform/custom_led.bin +led auto on +led start diff --git a/device/inventec/x86_64-inventec_d6332-r0/plugins/eeprom.py b/device/inventec/x86_64-inventec_d6332-r0/plugins/eeprom.py new file mode 100644 index 000000000000..96e27323aa44 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6332-r0/plugins/eeprom.py @@ -0,0 +1,20 @@ +############################################################################# +# Inventec d6356j +# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# + +try: + from sonic_eeprom import eeprom_tlvinfo +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/bus/i2c/devices/0-0055/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/inventec/x86_64-inventec_d6332-r0/plugins/psuutil.py b/device/inventec/x86_64-inventec_d6332-r0/plugins/psuutil.py new file mode 100755 index 000000000000..3ae6d5ddb355 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6332-r0/plugins/psuutil.py @@ -0,0 +1,89 @@ +# +# psuutil.py +# Platform-specific PSU status interface for SONiC +# + + +import os.path + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + """CPLD address""" + PSU_DIR = "/sys/bus/i2c/devices/i2c-inv_cpld/" + + def __init__(self): + PsuBase.__init__(self) + + # Get sysfs attribute + def get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip(' \t\n\r') + 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' + str(index) + attr_path = self.PSU_DIR + '/' + attr_file + normal_attr_value = '1:normal' + unpower_attr_value = '0:unpowered' + attr_value = self.get_attr_value(attr_path) + if (attr_value != 'ERR'): + # Check for PSU presence + if (attr_value == normal_attr_value): + status = 1 + elif (attr_value == unpower_attr_value): + status = 0 + 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 + attr_file = 'psu' + str(index) + attr_path = self.PSU_DIR + '/' + attr_file + normal_attr_value = '1:normal' + unpower_attr_value = '0:unpowered' + attr_value = self.get_attr_value(attr_path) + if (attr_value != 'ERR'): + # Check for PSU presence + if (attr_value == normal_attr_value): + status = 1 + if (attr_value == unpower_attr_value): + status = 1 + return status diff --git a/device/inventec/x86_64-inventec_d6332-r0/plugins/sfputil.py b/device/inventec/x86_64-inventec_d6332-r0/plugins/sfputil.py new file mode 100755 index 000000000000..7c3b78c1bc22 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6332-r0/plugins/sfputil.py @@ -0,0 +1,354 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# + +try: + import time + import os + import re + import socket + from sonic_sfp.sfputilbase import SfpUtilBase + from collections import OrderedDict + from sonic_sfp.sff8472 import sff8472Dom +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VLOT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_CHANNL_MON_OFFSET = 100 +SFP_CHANNL_MON_WIDTH = 6 + +NETLINK_KOBJECT_UEVENT = 15 +monitor = None + + +class SWPSEventMonitor(object): + + def __init__(self): + self.recieved_events = OrderedDict() + self.socket = socket.socket(socket.AF_NETLINK, socket.SOCK_DGRAM, NETLINK_KOBJECT_UEVENT) + + def start(self): + self.socket.bind((os.getpid(), -1)) + + def stop(self): + self.socket.close() + + def __enter__(self): + self.start() + return self + + def __exit__(self, exc_type, exc_value, traceback): + self.stop() + + def __iter__(self): + global monitor + while True: + for item in monitor.next_events(): + yield item + + def next_events(self): + data = self.socket.recv(16384) + event = {} + for item in data.split(b'\x00'): + if not item: + # check if we have an event and if we already received it + if event and event['SEQNUM'] not in self.recieved_events: + self.recieved_events[event['SEQNUM']] = None + if (len(self.recieved_events) > 100): + self.recieved_events.popitem(last=False) + yield event + event = {} + else: + try: + k, v = item.split(b'=', 1) + event[k.decode('ascii')] = v.decode('ascii') + except ValueError: + pass + + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + PORT_START = 0 + PORT_END = 31 + PORTS_IN_BLOCK = 32 + + _port_to_eeprom_mapping = {} + port_to_i2cbus_mapping = { + 0: 12, + 1: 13, + 2: 14, + 3: 15, + 4: 16, + 5: 17, + 6: 18, + 7: 19, + 8: 20, + 9: 21, + 10: 22, + 11: 23, + 12: 24, + 13: 25, + 14: 26, + 15: 27, + 16: 28, + 17: 29, + 18: 30, + 19: 31, + 20: 32, + 21: 33, + 22: 34, + 23: 35, + 24: 36, + 25: 37, + 26: 38, + 27: 39, + 28: 40, + 29: 41, + 30: 42, + 31: 43 + } + + @property + def port_start(self): + return self.PORT_START + + @property + def port_end(self): + return self.PORT_END + + @property + def qsfp_ports(self): + return list(range(0, self.PORTS_IN_BLOCK + 1)) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + def __init__(self): + eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" + + for x in range(0, self.port_end + 1): + port_eeprom_path = eeprom_path.format(self.port_to_i2cbus_mapping[x]) + self.port_to_eeprom_mapping[x] = port_eeprom_path + self.phy_port_dict = {} + SfpUtilBase.__init__(self) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + try: + reg_file = open("/sys/class/swps/port"+str(port_num)+"/present") + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + reg_value = int(reg_file.readline().rstrip()) + + if reg_value == 0: + return True + + return False + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + try: + reg_file = open("/sys/class/swps/port"+str(port_num)+"/lpmod") + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + + reg_value = int(reg_file.readline().rstrip()) + + if reg_value == 0: + return False + + return True + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + try: + reg_file = open("/sys/class/swps/port"+str(port_num)+"/lpmod", "r+") + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + lpmode = int(reg_file.readline().rstrip()) + + # LPMode is active high; set or clear the bit accordingly + if lpmode is True: + reg_value = 1 + else: + reg_value = 0 + + reg_file.write(hex(reg_value)) + reg_file.close() + + return True + + def reset(self, port_num): + QSFP_RESET_REGISTER_DEVICE_FILE = "/sys/class/swps/port"+str(port_num)+"/reset" + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + try: + reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "r+") + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + reg_value = 0 + reg_file.write(hex(reg_value)) + reg_file.close() + + # Sleep 2 second to allow it to settle + time.sleep(2) + + # Flip the value back write back to the register to take port out of reset + try: + reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "r+") + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + reg_value = 1 + reg_file.write(hex(reg_value)) + reg_file.close() + + return True + + def _get_port_eeprom_path(self, port_num, devid): + sysfs_i2c_adapter_base_path = "/sys/class/i2c-adapter" + if devid == self.IDENTITY_EEPROM_ADDR: + return SfpUtilBase._get_port_eeprom_path(self, port_num, devid) + else: + i2c_adapter_id = self._get_port_i2c_adapter_id(port_num) + if i2c_adapter_id is None: + print("Error getting i2c bus num") + return None + + # Get i2c virtual bus path for the sfp + sysfs_sfp_i2c_adapter_path = "%s/i2c-%s" % (sysfs_i2c_adapter_base_path, + str(i2c_adapter_id)) + + # If i2c bus for port does not exist + if not os.path.exists(sysfs_sfp_i2c_adapter_path): + print("Could not find i2c bus %s. Driver not loaded?" % sysfs_sfp_i2c_adapter_path) + return None + + sysfs_sfp_i2c_client_path = "%s/%s-00%s" % (sysfs_sfp_i2c_adapter_path, + str(i2c_adapter_id), + hex(devid)[-2:]) + + # If sfp device is not present on bus, Add it + if not os.path.exists(sysfs_sfp_i2c_client_path): + ret = self._add_new_sfp_device( + sysfs_sfp_i2c_adapter_path, devid) + if ret != 0: + print("Error adding sfp device") + return None + + sysfs_sfp_i2c_client_eeprom_path = "%s/eeprom" % sysfs_sfp_i2c_client_path + + return sysfs_sfp_i2c_client_eeprom_path + + def get_transceiver_dom_info_dict(self, port_num): + if port_num in self.qsfp_ports: + return SfpUtilBase.get_transceiver_dom_info_dict(self, port_num) + else: + transceiver_dom_info_dict = {} + + offset = 0 + 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 = open(file_path, "rb") + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8472Dom(None, 1) + if sfpd_obj is None: + return None + + dom_temperature_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, (offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + print(dom_temperature_raw) + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + print(dom_temperature_data) + else: + return None + + dom_voltage_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, (offset + SFP_VLOT_OFFSET), SFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + print(dom_voltage_raw) + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + else: + return None + + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, (offset + SFP_CHANNL_MON_OFFSET), SFP_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 None + + 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_change_event(self, timeout=0): + global monitor + port_dict = {} + with SWPSEventMonitor() as monitor: + for event in monitor: + if event['SUBSYSTEM'] == 'swps': + #print('SWPS event. From %s, ACTION %s, IF_TYPE %s, IF_LANE %s' % (event['DEVPATH'], event['ACTION'], event['IF_TYPE'], event['IF_LANE'])) + portname = event['DEVPATH'].split("/")[-1] + rc = re.match(r"port(?P\d+)", portname) + if rc is not None: + if event['ACTION'] == "remove": + remove_num = int(rc.group("num")) + port_dict[remove_num] = "0" + #port_dict[rc.group("num")] = "0" + if event['ACTION'] == "add": + add_num = int(rc.group("num")) + port_dict[add_num] = "1" + #port_dict[rc.group("num")] = "1" + return True, port_dict + return False, {} diff --git a/device/inventec/x86_64-inventec_d6332-r0/pmon_daemon_control.json b/device/inventec/x86_64-inventec_d6332-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/inventec/x86_64-inventec_d6332-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} diff --git a/device/inventec/x86_64-inventec_d6332-r0/sensors.conf b/device/inventec/x86_64-inventec_d6332-r0/sensors.conf new file mode 100644 index 000000000000..ecd518a77af9 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6332-r0/sensors.conf @@ -0,0 +1,69 @@ +# libsensors configuration file +chip "ucd90160-*" + ignore temp1 + +chip "pch_haswell-*" + label temp1 "PCH Temperature" + +chip "tmp75-i2c-*-0048" + label temp1 "CPU Board Temperature" + +chip "tmp75-i2c-*-004a" + label temp1 "FrontSide Temperature" + +chip "tmp75-i2c-*-004e" + label temp1 "NearASIC Temperature" + +chip "tmp75-i2c-*-004d" + label temp1 "RearSide Temperature" + +chip "inv_cpld-i2c-*-77" + label fan1 "FanModule1 Front RPM" + label fan2 "FanModule1 Rear RPM" + label fan3 "FanModule2 Front RPM" + label fan4 "FanModule2 Rear RPM" + label fan5 "FanModule3 Front RPM" + label fan6 "FanModule3 Rear RPM" + label fan7 "FanModule4 Front RPM" + label fan8 "FanModule4 Rear RPM" + label fan9 "FanModule5 Front RPM" + label fan10 "FanModule5 Rear RPM" + label pwm1 "FanModule1 PWM (0-255)" + label pwm2 "FanModule2 PWM (0-255)" + label pwm3 "FanModule3 PWM (0-255)" + label pwm4 "FanModule4 PWM (0-255)" + label pwm5 "FanModule5 PWM (0-255)" + label temp1 "ASIC Temperature" + +chip "pmbus-i2c-*-005a" + ignore power3 + ignore curr3 + ignore fan2 + label fan1 "PSU1 Fan RPM" + label temp1 "PSU1 Temperature1" + label temp2 "PSU1 Temperature2" + label temp3 "PSU1 Temperature3" + label in1 "PSU1 Input Voltage" + label curr1 "PSU1 Input Current" + label power1 "PSU1 Input Power" + label in2 "PSU1 Output Voltage" + label curr2 "PSU1 Output Current" + label power2 "PSU1 Output Power" + label pwm1 "PSU1 PWM (0-100)" + +chip "pmbus-i2c-*-005b" + ignore power3 + ignore curr3 + ignore fan2 + label fan1 "PSU2 Fan RPM" + label temp1 "PSU2 Temperature1" + label temp2 "PSU2 Temperature2" + label temp3 "PSU2 Temperature3" + label in1 "PSU2 Input Voltage" + label curr1 "PSU2 Input Current" + label power1 "PSU2 Input Power" + label in2 "PSU2 Output Voltage" + label curr2 "PSU2 Output Current" + label power2 "PSU2 Output Power" + label pwm1 "PSU2 PWM (0-100)" + diff --git a/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/td3-d6356-48x25G-8x100G.config.bcm b/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/td3-d6356-48x25G-8x100G.config.bcm index 57fd5cd57164..089207abd136 100644 --- a/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/td3-d6356-48x25G-8x100G.config.bcm +++ b/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/td3-d6356-48x25G-8x100G.config.bcm @@ -1,3 +1,4 @@ +sai_load_hw_config=/etc/bcm/flex/bcm56870_a0_issu/b870.6.4.1/ ### fix for sonic ptp_ts_pll_fref=50000000 ptp_bs_fref_0=50000000 diff --git a/device/inventec/x86_64-inventec_d6356-r0/plugins/eeprom.py b/device/inventec/x86_64-inventec_d6356-r0/plugins/eeprom.py index 953570d79cd7..4c75d0918add 100644 --- a/device/inventec/x86_64-inventec_d6356-r0/plugins/eeprom.py +++ b/device/inventec/x86_64-inventec_d6356-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Inventec d6356 # @@ -11,8 +9,8 @@ try: from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): diff --git a/device/inventec/x86_64-inventec_d6356-r0/plugins/psuutil.py b/device/inventec/x86_64-inventec_d6356-r0/plugins/psuutil.py index 732650ffe638..ce8d0b321928 100755 --- a/device/inventec/x86_64-inventec_d6356-r0/plugins/psuutil.py +++ b/device/inventec/x86_64-inventec_d6356-r0/plugins/psuutil.py @@ -22,8 +22,8 @@ def __init__(self): # Get sysfs attribute def get_attr_value(self, attr_path): - - retval = 'ERR' + + retval = 'ERR' if (not os.path.isfile(attr_path)): return retval @@ -35,7 +35,7 @@ def get_attr_value(self, attr_path): retval = retval.rstrip(' \t\n\r') return retval - + def get_num_psus(self): """ Retrieves the number of PSUs available on the device @@ -53,17 +53,17 @@ def get_psu_status(self, index): faulty """ status = 0 - - if index == 1 : + + if index == 1: attr_path = "/sys/class/hwmon/hwmon7/in1_input" - else : + else: attr_path = "/sys/class/hwmon/hwmon8/in1_input" attr_value = self.get_attr_value(attr_path) if (attr_value != 'ERR'): # Check for PSU status if (attr_value != 0): - status = 1 + status = 1 return status def get_psu_presence(self, index): @@ -76,13 +76,12 @@ def get_psu_presence(self, index): status = 0 psu_absent = 0 ind = index - attr_file ='psu'+ str(ind) - attr_path = self.PSU_DIR +'/' + attr_file - normal_attr_value = '1:normal' + attr_file = 'psu' + str(ind) + attr_path = self.PSU_DIR + '/' + attr_file + normal_attr_value = '1:normal' attr_value = self.get_attr_value(attr_path) if (attr_value != 'ERR'): # Check for PSU presence if (attr_value == normal_attr_value): - status = 1 + status = 1 return status - diff --git a/device/inventec/x86_64-inventec_d6356-r0/plugins/sfputil.py b/device/inventec/x86_64-inventec_d6356-r0/plugins/sfputil.py index 116a3d9acbc9..d58d1e96b766 100755 --- a/device/inventec/x86_64-inventec_d6356-r0/plugins/sfputil.py +++ b/device/inventec/x86_64-inventec_d6356-r0/plugins/sfputil.py @@ -14,7 +14,9 @@ # try: import time - import socket, re,os + import socket + import re + import os from collections import OrderedDict from sonic_sfp.sfputilbase import SfpUtilBase from sonic_sfp.sff8472 import sff8472Dom @@ -31,6 +33,7 @@ NETLINK_KOBJECT_UEVENT = 15 monitor = None + class SWPSEventMonitor(object): def __init__(self): @@ -76,6 +79,7 @@ def next_events(self): except ValueError: pass + class SfpUtil(SfpUtilBase): """Platform-specific SfpUtil class""" @@ -87,62 +91,62 @@ class SfpUtil(SfpUtilBase): _port_to_eeprom_mapping = {} port_to_i2c_mapping = { - 0:22, - 1:23, - 2:24, - 3:25, - 4:26, - 5:27, - 6:28, - 7:29, - 8:30, - 9:31, - 10:32, - 11:33, - 12:34, - 13:35, - 14:36, - 15:37, - 16:38, - 17:39, - 18:40, - 19:41, - 20:42, - 21:43, - 22:44, - 23:45, - 24:46, - 25:47, - 26:48, - 27:49, - 28:50, - 29:51, - 30:52, - 31:53, - 32:54, - 33:55, - 34:56, - 35:57, - 36:58, - 37:59, - 38:60, - 39:61, - 40:62, - 41:63, - 42:64, - 43:65, - 44:66, - 45:67, - 46:68, - 47:69, - 48:14, - 49:15, - 50:16, - 51:17, - 52:18, - 53:19, - 54:20, - 55:21 + 0: 22, + 1: 23, + 2: 24, + 3: 25, + 4: 26, + 5: 27, + 6: 28, + 7: 29, + 8: 30, + 9: 31, + 10: 32, + 11: 33, + 12: 34, + 13: 35, + 14: 36, + 15: 37, + 16: 38, + 17: 39, + 18: 40, + 19: 41, + 20: 42, + 21: 43, + 22: 44, + 23: 45, + 24: 46, + 25: 47, + 26: 48, + 27: 49, + 28: 50, + 29: 51, + 30: 52, + 31: 53, + 32: 54, + 33: 55, + 34: 56, + 35: 57, + 36: 58, + 37: 59, + 38: 60, + 39: 61, + 40: 62, + 41: 63, + 42: 64, + 43: 65, + 44: 66, + 45: 67, + 46: 68, + 47: 69, + 48: 14, + 49: 15, + 50: 16, + 51: 17, + 52: 18, + 53: 19, + 54: 20, + 55: 21 } @property @@ -163,7 +167,7 @@ def qsfp_port_end(self): @property def qsfp_ports(self): - return range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1) + return list(range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -185,7 +189,7 @@ def get_presence(self, port_num): try: reg_file = open("/sys/class/swps/port"+str(port_num)+"/present") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = int(reg_file.readline().rstrip()) @@ -205,7 +209,7 @@ def get_low_power_mode(self, port_num): try: reg_file = open("/sys/class/swps/port"+str(port_num)+"/lpmod") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) reg_value = int(reg_file.readline().rstrip()) @@ -219,13 +223,13 @@ def set_low_power_mode(self, port_num, lpmode): if port_num < self.port_start or port_num > self.port_end: return False if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: - print "\nError:SFP's don't support this property" + print("\nError:SFP's don't support this property") return False try: reg_file = open("/sys/class/swps/port"+str(port_num)+"/lpmod", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = int(reg_file.readline().rstrip()) @@ -247,13 +251,13 @@ def reset(self, port_num): if port_num < self.port_start or port_num > self.port_end: return False if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: - print "\nError:SFP's don't support this property" + print("\nError:SFP's don't support this property") return False try: reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = 0 @@ -267,7 +271,7 @@ def reset(self, port_num): try: reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = 1 @@ -293,7 +297,7 @@ def get_transceiver_change_event(self): if event['SUBSYSTEM'] == 'swps': #print('SWPS event. From %s, ACTION %s, IF_TYPE %s, IF_LANE %s' % (event['DEVPATH'], event['ACTION'], event['IF_TYPE'], event['IF_LANE'])) portname = event['DEVPATH'].split("/")[-1] - rc = re.match(r"port(?P\d+)",portname) + rc = re.match(r"port(?P\d+)", portname) if rc is not None: if event['ACTION'] == "remove": remove_num = int(rc.group("num")) @@ -335,19 +339,22 @@ def get_transceiver_dom_info_dict(self, port_num): if sfpd_obj is None: return None - dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH) + 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 None - dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_VLOT_OFFSET), SFP_VOLT_WIDTH) + dom_voltage_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, (offset + SFP_VLOT_OFFSET), SFP_VOLT_WIDTH) if dom_voltage_raw is not None: dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) else: return None - dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, (offset + SFP_CHANNL_MON_OFFSET), SFP_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: @@ -375,5 +382,3 @@ def get_transceiver_dom_info_dict(self, port_num): transceiver_dom_info_dict['tx4power'] = 'N/A' return transceiver_dom_info_dict - - diff --git a/device/inventec/x86_64-inventec_d6556-r0/plugins/eeprom.py b/device/inventec/x86_64-inventec_d6556-r0/plugins/eeprom.py index de5c24ba0e6d..31f847614fb0 100644 --- a/device/inventec/x86_64-inventec_d6556-r0/plugins/eeprom.py +++ b/device/inventec/x86_64-inventec_d6556-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Inventec d7032q28b # @@ -11,8 +9,8 @@ try: from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): diff --git a/device/inventec/x86_64-inventec_d6556-r0/plugins/psuutil.py b/device/inventec/x86_64-inventec_d6556-r0/plugins/psuutil.py index 855162f63b98..ced851d6c82a 100644 --- a/device/inventec/x86_64-inventec_d6556-r0/plugins/psuutil.py +++ b/device/inventec/x86_64-inventec_d6556-r0/plugins/psuutil.py @@ -22,8 +22,8 @@ def __init__(self): # Get sysfs attribute def get_attr_value(self, attr_path): - - retval = 'ERR' + + retval = 'ERR' if (not os.path.isfile(attr_path)): return retval @@ -35,7 +35,7 @@ def get_attr_value(self, attr_path): retval = retval.rstrip(' \t\n\r') return retval - + def get_num_psus(self): """ Retrieves the number of PSUs available on the device @@ -53,14 +53,14 @@ def get_psu_status(self, index): faulty """ status = 0 - attr_file = 'psoc_psu'+ str(index) + '_iout' - attr_path = self.PSU_DIR +'/' + attr_file - + attr_file = 'psoc_psu' + str(index) + '_iout' + attr_path = self.PSU_DIR + '/' + attr_file + attr_value = self.get_attr_value(attr_path) if (attr_value != 'ERR'): # Check for PSU status if (attr_value != 0): - status = 1 + status = 1 return status def get_psu_presence(self, index): @@ -73,12 +73,12 @@ def get_psu_presence(self, index): status = 0 psu_absent = 0 ind = index-1 - attr_file ='psu'+ str(ind) - attr_path = self.PSU_DIR +'/' + attr_file - normal_attr_value = '0 : normal' + attr_file = 'psu' + str(ind) + attr_path = self.PSU_DIR + '/' + attr_file + normal_attr_value = '0 : normal' attr_value = self.get_attr_value(attr_path) if (attr_value != 'ERR'): # Check for PSU presence if (attr_value == normal_attr_value): - status = 1 + status = 1 return status diff --git a/device/inventec/x86_64-inventec_d6556-r0/plugins/sfputil.py b/device/inventec/x86_64-inventec_d6556-r0/plugins/sfputil.py index 155b956827f1..3cd6c43d7cde 100644 --- a/device/inventec/x86_64-inventec_d6556-r0/plugins/sfputil.py +++ b/device/inventec/x86_64-inventec_d6556-r0/plugins/sfputil.py @@ -97,7 +97,7 @@ def qsfp_port_end(self): @property def qsfp_ports(self): - return range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1) + return list(range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -119,7 +119,7 @@ def get_presence(self, port_num): try: reg_file = open("/sys/class/swps/port"+str(port_num)+"/present") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = int(reg_file.readline().rstrip()) @@ -139,7 +139,7 @@ def get_low_power_mode(self, port_num): try: reg_file = open("/sys/class/swps/port"+str(port_num)+"/lpmod") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) reg_value = int(reg_file.readline().rstrip()) @@ -153,13 +153,13 @@ def set_low_power_mode(self, port_num, lpmode): if port_num < self.port_start or port_num > self.port_end: return False if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: - print "\nError:SFP's don't support this property" + print("\nError:SFP's don't support this property") return False try: reg_file = open("/sys/class/swps/port"+str(port_num)+"/lpmod", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = int(reg_file.readline().rstrip()) @@ -181,13 +181,13 @@ def reset(self, port_num): if port_num < self.port_start or port_num > self.port_end: return False if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: - print "\nError:SFP's don't support this property" + print("\nError:SFP's don't support this property") return False try: reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = 0 @@ -201,7 +201,7 @@ def reset(self, port_num): try: reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = 1 diff --git a/device/inventec/x86_64-inventec_d7032q28b-r0/plugins/eeprom.py b/device/inventec/x86_64-inventec_d7032q28b-r0/plugins/eeprom.py index de5c24ba0e6d..31f847614fb0 100644 --- a/device/inventec/x86_64-inventec_d7032q28b-r0/plugins/eeprom.py +++ b/device/inventec/x86_64-inventec_d7032q28b-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Inventec d7032q28b # @@ -11,8 +9,8 @@ try: from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): diff --git a/device/inventec/x86_64-inventec_d7032q28b-r0/plugins/psuutil.py b/device/inventec/x86_64-inventec_d7032q28b-r0/plugins/psuutil.py index cc5ca004dadf..2e058a9e410e 100644 --- a/device/inventec/x86_64-inventec_d7032q28b-r0/plugins/psuutil.py +++ b/device/inventec/x86_64-inventec_d7032q28b-r0/plugins/psuutil.py @@ -22,8 +22,8 @@ def __init__(self): # Get sysfs attribute def get_attr_value(self, attr_path): - - retval = 'ERR' + + retval = 'ERR' if (not os.path.isfile(attr_path)): return retval @@ -35,7 +35,7 @@ def get_attr_value(self, attr_path): retval = retval.rstrip(' \t\n\r') return retval - + def get_num_psus(self): """ Retrieves the number of PSUs available on the device @@ -54,17 +54,17 @@ def get_psu_status(self, index): """ status = 0 if (index == 1): - ind = 2 + ind = 2 if (index == 2): - ind = 1 - attr_file = 'psu'+ str(ind) + '_iout' - attr_path = self.PSU_DIR +'/' + attr_file - + ind = 1 + attr_file = 'psu' + str(ind) + '_iout' + attr_path = self.PSU_DIR + '/' + attr_file + attr_value = self.get_attr_value(attr_path) if (attr_value != 'ERR'): # Check for PSU status if (attr_value != 0): - status = 1 + status = 1 return status def get_psu_presence(self, index): @@ -77,12 +77,12 @@ def get_psu_presence(self, index): status = 0 psu_absent = 0 ind = index-1 - attr_file ='psu'+ str(ind) - attr_path = self.PSU_DIR +'/' + attr_file - normal_attr_value = '0 : normal' + attr_file = 'psu' + str(ind) + attr_path = self.PSU_DIR + '/' + attr_file + normal_attr_value = '0 : normal' attr_value = self.get_attr_value(attr_path) if (attr_value != 'ERR'): # Check for PSU presence if (attr_value == normal_attr_value): - status = 1 + status = 1 return status diff --git a/device/inventec/x86_64-inventec_d7032q28b-r0/plugins/sfputil.py b/device/inventec/x86_64-inventec_d7032q28b-r0/plugins/sfputil.py index d109f49f2e7d..5321e0c072e8 100644 --- a/device/inventec/x86_64-inventec_d7032q28b-r0/plugins/sfputil.py +++ b/device/inventec/x86_64-inventec_d7032q28b-r0/plugins/sfputil.py @@ -73,7 +73,7 @@ def qsfp_port_end(self): @property def qsfp_ports(self): - return range(0, self.PORTS_IN_BLOCK + 1) + return list(range(0, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -95,7 +95,7 @@ def get_presence(self, port_num): try: reg_file = open("/sys/class/swps/port"+str(port_num)+"/present") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = int(reg_file.readline().rstrip()) @@ -113,7 +113,7 @@ def get_low_power_mode(self, port_num): try: reg_file = open("/sys/class/swps/port"+str(port_num)+"/lpmod") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) reg_value = int(reg_file.readline().rstrip()) @@ -130,7 +130,7 @@ def set_low_power_mode(self, port_num, lpmode): try: reg_file = open("/sys/class/swps/port"+str(port_num)+"/lpmod", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = int(reg_file.readline().rstrip()) @@ -155,7 +155,7 @@ def reset(self, port_num): try: reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = 0 @@ -169,7 +169,7 @@ def reset(self, port_num): try: reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = 1 diff --git a/device/inventec/x86_64-inventec_d7054q28b-r0/plugins/eeprom.py b/device/inventec/x86_64-inventec_d7054q28b-r0/plugins/eeprom.py index de5c24ba0e6d..31f847614fb0 100644 --- a/device/inventec/x86_64-inventec_d7054q28b-r0/plugins/eeprom.py +++ b/device/inventec/x86_64-inventec_d7054q28b-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Inventec d7032q28b # @@ -11,8 +9,8 @@ try: from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): diff --git a/device/inventec/x86_64-inventec_d7054q28b-r0/plugins/psuutil.py b/device/inventec/x86_64-inventec_d7054q28b-r0/plugins/psuutil.py index 4bd3f7a27052..162e240bae35 100644 --- a/device/inventec/x86_64-inventec_d7054q28b-r0/plugins/psuutil.py +++ b/device/inventec/x86_64-inventec_d7054q28b-r0/plugins/psuutil.py @@ -22,8 +22,8 @@ def __init__(self): # Get sysfs attribute def get_attr_value(self, attr_path): - - retval = 'ERR' + + retval = 'ERR' if (not os.path.isfile(attr_path)): return retval @@ -35,7 +35,7 @@ def get_attr_value(self, attr_path): retval = retval.rstrip(' \t\n\r') return retval - + def get_num_psus(self): """ Retrieves the number of PSUs available on the device @@ -53,14 +53,14 @@ def get_psu_status(self, index): faulty """ status = 0 - attr_file = 'psoc_psu'+ str(index) + '_iout' - attr_path = self.PSU_DIR +'/' + attr_file - + attr_file = 'psoc_psu' + str(index) + '_iout' + attr_path = self.PSU_DIR + '/' + attr_file + attr_value = self.get_attr_value(attr_path) if (attr_value != 'ERR'): # Check for PSU status if (attr_value != 0): - status = 1 + status = 1 return status def get_psu_presence(self, index): @@ -73,12 +73,12 @@ def get_psu_presence(self, index): status = 0 psu_absent = 0 ind = index-1 - attr_file ='psu'+ str(ind) - attr_path = self.PSU_DIR +'/' + attr_file - normal_attr_value = '0 : normal' + attr_file = 'psu' + str(ind) + attr_path = self.PSU_DIR + '/' + attr_file + normal_attr_value = '0 : normal' attr_value = self.get_attr_value(attr_path) if (attr_value != 'ERR'): # Check for PSU presence if (attr_value == normal_attr_value): - status = 1 + status = 1 return status diff --git a/device/inventec/x86_64-inventec_d7054q28b-r0/plugins/sfputil.py b/device/inventec/x86_64-inventec_d7054q28b-r0/plugins/sfputil.py index 5dffdd0335b0..93baaa88ac3e 100755 --- a/device/inventec/x86_64-inventec_d7054q28b-r0/plugins/sfputil.py +++ b/device/inventec/x86_64-inventec_d7054q28b-r0/plugins/sfputil.py @@ -95,7 +95,7 @@ def qsfp_port_end(self): @property def qsfp_ports(self): - return range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1) + return list(range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -117,7 +117,7 @@ def get_presence(self, port_num): try: reg_file = open("/sys/class/swps/port"+str(port_num)+"/present") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = int(reg_file.readline().rstrip()) @@ -137,7 +137,7 @@ def get_low_power_mode(self, port_num): try: reg_file = open("/sys/class/swps/port"+str(port_num)+"/lpmod") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) reg_value = int(reg_file.readline().rstrip()) @@ -151,13 +151,13 @@ def set_low_power_mode(self, port_num, lpmode): if port_num < self.port_start or port_num > self.port_end: return False if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: - print "\nError:SFP's don't support this property" + print("\nError:SFP's don't support this property") return False try: reg_file = open("/sys/class/swps/port"+str(port_num)+"/lpmod", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = int(reg_file.readline().rstrip()) @@ -179,13 +179,13 @@ def reset(self, port_num): if port_num < self.port_start or port_num > self.port_end: return False if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: - print "\nError:SFP's don't support this property" + print("\nError:SFP's don't support this property") return False try: reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = 0 @@ -199,7 +199,7 @@ def reset(self, port_num): try: reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = 1 diff --git a/device/inventec/x86_64-inventec_d7264q28b-r0/plugins/eeprom.py b/device/inventec/x86_64-inventec_d7264q28b-r0/plugins/eeprom.py index de5c24ba0e6d..31f847614fb0 100644 --- a/device/inventec/x86_64-inventec_d7264q28b-r0/plugins/eeprom.py +++ b/device/inventec/x86_64-inventec_d7264q28b-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Inventec d7032q28b # @@ -11,8 +9,8 @@ try: from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): diff --git a/device/inventec/x86_64-inventec_d7264q28b-r0/plugins/psuutil.py b/device/inventec/x86_64-inventec_d7264q28b-r0/plugins/psuutil.py index c2337a97f4ea..8e100d36405d 100755 --- a/device/inventec/x86_64-inventec_d7264q28b-r0/plugins/psuutil.py +++ b/device/inventec/x86_64-inventec_d7264q28b-r0/plugins/psuutil.py @@ -23,8 +23,8 @@ def __init__(self): # Get sysfs attribute def get_attr_value(self, attr_path): - - retval = 'ERR' + + retval = 'ERR' if (not os.path.isfile(attr_path)): return retval @@ -36,7 +36,7 @@ def get_attr_value(self, attr_path): retval = retval.rstrip(' \t\n\r') return retval - + def get_num_psus(self): """ Retrieves the number of PSUs available on the device @@ -54,18 +54,18 @@ def get_psu_status(self, index): faulty """ status = 0 - attr_file = 'psoc_psu'+ str(index) + '_iout' - attr_path = self.PSU_DIR1 +'/' + attr_file - + attr_file = 'psoc_psu' + str(index) + '_iout' + attr_path = self.PSU_DIR1 + '/' + attr_file + attr_value = self.get_attr_value(attr_path) if (attr_value == 'ERR'): - attr_path = self.PSU_DIR2 +'/' + attr_file + attr_path = self.PSU_DIR2 + '/' + attr_file attr_value = self.get_attr_value(attr_path) # Check for PSU status if (attr_value != 0): - status = 1 + status = 1 if (attr_value != 0): - status = 1 + status = 1 return status def get_psu_presence(self, index): @@ -78,16 +78,16 @@ def get_psu_presence(self, index): status = 0 psu_absent = 0 ind = index-1 - attr_file ='psu'+ str(ind) + attr_file = 'psu' + str(ind) normal_attr_value = '0 : normal' - attr_path = self.PSU_DIR1 +'/' + attr_file + attr_path = self.PSU_DIR1 + '/' + attr_file attr_value = self.get_attr_value(attr_path) if (attr_value == 'ERR'): - attr_path = self.PSU_DIR2 +'/' + attr_file + attr_path = self.PSU_DIR2 + '/' + attr_file attr_value = self.get_attr_value(attr_path) # Check for PSU presence if (attr_value == normal_attr_value): - status = 1 + status = 1 if (attr_value == normal_attr_value): - status = 1 + status = 1 return status diff --git a/device/inventec/x86_64-inventec_d7264q28b-r0/plugins/sfputil.py b/device/inventec/x86_64-inventec_d7264q28b-r0/plugins/sfputil.py index 6f23ad01bd2c..6591809194af 100755 --- a/device/inventec/x86_64-inventec_d7264q28b-r0/plugins/sfputil.py +++ b/device/inventec/x86_64-inventec_d7264q28b-r0/plugins/sfputil.py @@ -76,15 +76,15 @@ class SfpUtil(SfpUtilBase): 52: 65, 53: 64, 54: 63, - 55: 62, - 56: 69, - 57: 68, - 58: 67, - 59: 66, - 60: 73, - 61: 72, - 62: 71, - 63: 70 + 55: 62, + 56: 69, + 57: 68, + 58: 67, + 59: 66, + 60: 73, + 61: 72, + 62: 71, + 63: 70 } @property @@ -105,7 +105,7 @@ def qsfp_port_end(self): @property def qsfp_ports(self): - return range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1) + return list(range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -127,7 +127,7 @@ def get_presence(self, port_num): try: reg_file = open("/sys/class/swps/port"+str(port_num)+"/present") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = int(reg_file.readline().rstrip()) @@ -147,7 +147,7 @@ def get_low_power_mode(self, port_num): try: reg_file = open("/sys/class/swps/port"+str(port_num)+"/lpmod") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) reg_value = int(reg_file.readline().rstrip()) @@ -161,13 +161,13 @@ def set_low_power_mode(self, port_num, lpmode): if port_num < self.port_start or port_num > self.port_end: return False if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: - print "\nError:SFP's don't support this property" + print("\nError:SFP's don't support this property") return False try: reg_file = open("/sys/class/swps/port"+str(port_num)+"/lpmod", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = int(reg_file.readline().rstrip()) @@ -189,13 +189,13 @@ def reset(self, port_num): if port_num < self.port_start or port_num > self.port_end: return False if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: - print "\nError:SFP's don't support this property" + print("\nError:SFP's don't support this property") return False try: reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = 0 @@ -209,7 +209,7 @@ def reset(self, port_num): try: reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = 1 diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/buffers.json.j2 b/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/buffers.json.j2 new file mode 100644 index 000000000000..a9a01d707ebf --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/buffers.json.j2 @@ -0,0 +1 @@ +{%- include 'buffers_config.j2' %} diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/buffers_defaults_t1.j2 b/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..3442612f70b2 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/buffers_defaults_t1.j2 @@ -0,0 +1,46 @@ +{%- set default_cable = '5m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0,64) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "33329088", + "type": "ingress", + "mode": "dynamic", + "xoff": "7827456" + }, + "egress_lossy_pool": { + "size": "26663272", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "42349632", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"44302336" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"42349632" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1664", + "dynamic_th":"-1" + } + }, +{%- endmacro %} diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/port_config.ini b/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/port_config.ini new file mode 100644 index 000000000000..a7ebdd116fc8 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias index speed +Ethernet0 49,50,51,52 hundredGigE1/1 0 100000 +Ethernet4 53,54,55,56 hundredGigE1/2 1 100000 +Ethernet8 57,58,59,60 hundredGigE1/3 2 100000 +Ethernet12 61,62,63,64 hundredGigE1/4 3 100000 +Ethernet16 65,66,67,68 hundredGigE1/5 4 100000 +Ethernet20 69,70,71,72 hundredGigE1/6 5 100000 +Ethernet24 73,74,75,76 hundredGigE1/7 6 100000 +Ethernet28 77,78,79,80 hundredGigE1/8 7 100000 +Ethernet32 81,82,83,84 hundredGigE1/9 8 100000 +Ethernet36 85,86,87,88 hundredGigE1/10 9 100000 +Ethernet40 37,38,39,40 hundredGigE1/11 10 100000 +Ethernet44 33,34,35,36 hundredGigE1/12 11 100000 +Ethernet48 41,42,43,44 hundredGigE1/13 12 100000 +Ethernet52 45,46,47,48 hundredGigE1/14 13 100000 +Ethernet56 89,90,91,92 hundredGigE1/15 14 100000 +Ethernet60 93,94,95,96 hundredGigE1/16 15 100000 +Ethernet64 97,98,99,100 hundredGigE1/17 16 100000 +Ethernet68 101,102,103,104 hundredGigE1/18 17 100000 +Ethernet72 17,18,19,20 hundredGigE1/19 18 100000 +Ethernet76 21,22,23,24 hundredGigE1/20 19 100000 +Ethernet80 29,30,31,32 hundredGigE1/21 20 100000 +Ethernet84 25,26,27,28 hundredGigE1/22 21 100000 +Ethernet88 105,106,107,108 hundredGigE1/23 22 100000 +Ethernet92 109,110,111,112 hundredGigE1/24 23 100000 +Ethernet96 113,114,115,116 hundredGigE1/25 24 100000 +Ethernet100 117,118,119,120 hundredGigE1/26 25 100000 +Ethernet104 121,122,123,124 hundredGigE1/27 26 100000 +Ethernet108 125,126,127,128 hundredGigE1/28 27 100000 +Ethernet112 1,2,3,4 hundredGigE1/29 28 100000 +Ethernet116 5,6,7,8 hundredGigE1/30 29 100000 +Ethernet120 9,10,11,12 hundredGigE1/31 30 100000 +Ethernet124 13,14,15,16 hundredGigE1/32 31 100000 diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/qos.json.j2 b/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/sai.profile b/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/sai.profile new file mode 100644 index 000000000000..9852552d899e --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-qfx5200-32x100g.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/th-qfx5200-32x100g.config.bcm b/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/th-qfx5200-32x100g.config.bcm new file mode 100644 index 000000000000..a0ed5ca2fa5c --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/th-qfx5200-32x100g.config.bcm @@ -0,0 +1,586 @@ +phy_xaui_tx_polarity_flip_99=0x01 +portmap_120=115:25:50:i +portmap_112=107:25:50:i +portmap_104=99:25:50:i +portmap_8=8:25:i +xgxs_rx_lane_map_20=0x3120 +xgxs_rx_lane_map_12=0x2301 +l2mod_dma_intr_enable=1 +xgxs_tx_lane_map_40=0x0123 +xgxs_tx_lane_map_32=0x0213 +xgxs_tx_lane_map_24=0x2310 +xgxs_tx_lane_map_16=0x1023 +port_phy_addr_99=0xff +rate_ext_mdio_divisor=0x80 +portmap_121=116:25:i +portmap_113=108:25:i +portmap_105=100:25:i +portmap_9=9:100 +xgxs_rx_lane_map_21=0x3120 +xgxs_rx_lane_map_13=0x0213 +tslam_timeout_usec=10000000 +xgxs_tx_lane_map_41=0x0123 +xgxs_tx_lane_map_25=0x0213 +xgxs_tx_lane_map_17=0x0213 +portmap_130=125:100 +portmap_122=117:100 +portmap_114=109:100 +xgxs_rx_lane_map_30=0x2301 +portmap_106=101:100 +xgxs_rx_lane_map_22=0x3120 +xgxs_rx_lane_map_14=0x0213 +xgxs_tx_lane_map_50=0x0213 +xgxs_tx_lane_map_42=0x2310 +xgxs_tx_lane_map_34=0x0123 +phy_xaui_rx_polarity_flip_20=0x01 +xgxs_tx_lane_map_26=0x0213 +xgxs_tx_lane_map_18=0x0213 +portmap_10=10:25:i +xgxs_tx_lane_map_1=0x3120 +portmap_131=126:25:i +portmap_123=118:25:i +portmap_115=110:25:i +xgxs_rx_lane_map_31=0x2301 +portmap_107=102:25:i +xgxs_rx_lane_map_23=0x3120 +xgxs_rx_lane_map_15=0x0213 +xgxs_tx_lane_map_51=0x0213 +xgxs_tx_lane_map_43=0x2310 +xgxs_tx_lane_map_35=0x0123 +phy_xaui_rx_polarity_flip_21=0x03 +xgxs_tx_lane_map_27=0x0213 +phy_xaui_rx_polarity_flip_13=0x0c +xgxs_tx_lane_map_19=0x0213 +portmap_11=11:25:50:i +xgxs_tx_lane_map_2=0x3120 +xgxs_tx_lane_map_110=0x1203 +xgxs_tx_lane_map_102=0x1203 +parity_correction=1 +portmap_132=127:25:50:i +portmap_124=119:25:50:i +portmap_116=111:25:50:i +xgxs_rx_lane_map_40=0x2310 +xgxs_rx_lane_map_32=0x2301 +portmap_108=103:25:50:i +xgxs_rx_lane_map_24=0x3120 +xgxs_rx_lane_map_16=0x0213 +xgxs_tx_lane_map_60=0x0213 +xgxs_tx_lane_map_52=0x0213 +xgxs_tx_lane_map_44=0x2310 +xgxs_tx_lane_map_36=0x0123 +phy_xaui_rx_polarity_flip_22=0x01 +xgxs_tx_lane_map_28=0x0213 +portmap_20=20:25:i +portmap_12=12:25:i +xgxs_tx_lane_map_3=0x3120 +xgxs_tx_lane_map_111=0x1203 +xgxs_tx_lane_map_103=0x1203 +portmap_133=128:25:i +portmap_125=120:25:i +portmap_117=112:25:i +xgxs_rx_lane_map_41=0x2310 +portmap_109=104:25:i +xgxs_rx_lane_map_25=0x3210 +xgxs_rx_lane_map_17=0x3120 +xgxs_tx_lane_map_61=0x0213 +xgxs_tx_lane_map_53=0x0213 +xgxs_tx_lane_map_45=0x2310 +xgxs_tx_lane_map_37=0x0123 +xgxs_tx_lane_map_29=0x0213 +phy_xaui_rx_polarity_flip_15=0x03 +portmap_21=21:100 +portmap_13=13:100 +xgxs_rx_lane_map_110=0x2301 +xgxs_rx_lane_map_102=0x2301 +xgxs_tx_lane_map_4=0x3120 +xgxs_tx_lane_map_120=0x1203 +xgxs_tx_lane_map_112=0x1203 +xgxs_tx_lane_map_104=0x1203 +bcm_stat_interval=500000 +l2xmsg_hostbuf_size=16384 +portmap_126=121:100 +xgxs_rx_lane_map_50=0x0231 +portmap_118=113:100 +xgxs_rx_lane_map_42=0x3201 +xgxs_rx_lane_map_34=0x3102 +xgxs_rx_lane_map_26=0x3210 +xgxs_rx_lane_map_18=0x3120 +xgxs_tx_lane_map_70=0x3120 +xgxs_tx_lane_map_62=0x2310 +xgxs_tx_lane_map_54=0x2310 +phy_xaui_rx_polarity_flip_40=0x01 +xgxs_tx_lane_map_46=0x2013 +xgxs_tx_lane_map_38=0x0123 +portmap_30=30:25:i +phy_xaui_rx_polarity_flip_16=0x01 +portmap_22=22:25:i +portmap_14=14:25:i +xgxs_rx_lane_map_111=0x2301 +xgxs_rx_lane_map_103=0x2301 +xgxs_tx_lane_map_5=0x1023 +xgxs_tx_lane_map_121=0x1203 +xgxs_tx_lane_map_113=0x1203 +xgxs_tx_lane_map_105=0x1203 +port_phy_addr_10=0xff +mem_check_nocache_override=1 +bcm_stat_flags=1 +portmap_127=122:25:i +xgxs_rx_lane_map_51=0x0231 +portmap_119=114:25:i +xgxs_rx_lane_map_43=0x3201 +xgxs_rx_lane_map_35=0x3102 +xgxs_rx_lane_map_27=0x3210 +xgxs_rx_lane_map_19=0x3120 +xgxs_tx_lane_map_71=0x3120 +xgxs_tx_lane_map_63=0x2310 +phy_xaui_tx_polarity_flip_11=0x02 +xgxs_tx_lane_map_55=0x2310 +xgxs_tx_lane_map_47=0x2013 +xgxs_tx_lane_map_39=0x0123 +phy_xaui_rx_polarity_flip_25=0x0c +portmap_31=31:25:50:i +phy_xaui_rx_polarity_flip_17=0x08 +portmap_23=23:25:50:i +portmap_15=15:25:50:i +xgxs_rx_lane_map_120=0x3120 +xgxs_rx_lane_map_112=0x2301 +xgxs_rx_lane_map_104=0x2301 +xgxs_tx_lane_map_6=0x1023 +xgxs_tx_lane_map_130=0x3201 +xgxs_tx_lane_map_122=0x1023 +xgxs_tx_lane_map_114=0x0132 +xgxs_tx_lane_map_106=0x0132 +port_phy_addr_11=0xff +xgxs_rx_lane_map_60=0x0231 +portmap_128=123:25:50:i +xgxs_rx_lane_map_52=0x0231 +xgxs_rx_lane_map_44=0x3201 +xgxs_rx_lane_map_36=0x3102 +xgxs_rx_lane_map_28=0x3210 +xgxs_tx_lane_map_80=0x3102 +xgxs_tx_lane_map_72=0x2310 +xgxs_tx_lane_map_64=0x2310 +phy_xaui_tx_polarity_flip_12=0x01 +xgxs_tx_lane_map_56=0x2310 +phy_xaui_rx_polarity_flip_42=0x04 +xgxs_tx_lane_map_48=0x2013 +phy_xaui_rx_polarity_flip_34=0x08 +portmap_40=39:25:50:i +xgxs_rx_lane_map_1=0x3201 +portmap_32=32:25:i +portmap_24=24:25:i +portmap_16=16:25:i +xgxs_rx_lane_map_121=0x3120 +xgxs_rx_lane_map_113=0x2301 +xgxs_rx_lane_map_105=0x2301 +xgxs_tx_lane_map_7=0x1023 +xgxs_tx_lane_map_131=0x3201 +xgxs_tx_lane_map_123=0x1023 +xgxs_tx_lane_map_115=0x0132 +xgxs_tx_lane_map_107=0x0132 +port_phy_addr_20=0xff +port_phy_addr_12=0xff +xgxs_rx_lane_map_61=0x0231 +portmap_129=124:25:i +xgxs_rx_lane_map_53=0x0231 +xgxs_rx_lane_map_45=0x3201 +xgxs_rx_lane_map_37=0x3102 +xgxs_rx_lane_map_29=0x2301 +xgxs_tx_lane_map_81=0x3102 +xgxs_tx_lane_map_73=0x2310 +phy_xaui_tx_polarity_flip_21=0x04 +xgxs_tx_lane_map_65=0x2310 +xgxs_tx_lane_map_57=0x2310 +xgxs_tx_lane_map_49=0x2013 +portmap_41=40:25:i +phy_xaui_rx_polarity_flip_27=0x03 +xgxs_rx_lane_map_2=0x3201 +phy_xaui_rx_polarity_flip_19=0x02 +portmap_25=25:100 +portmap_17=17:100 +xgxs_rx_lane_map_130=0x3210 +xgxs_rx_lane_map_122=0x1023 +xgxs_rx_lane_map_114=0x2301 +xgxs_rx_lane_map_106=0x2301 +xgxs_tx_lane_map_8=0x1023 +xgxs_tx_lane_map_132=0x3201 +xgxs_tx_lane_map_124=0x1023 +xgxs_tx_lane_map_116=0x0132 +xgxs_tx_lane_map_108=0x0132 +phy_xaui_rx_polarity_flip_114=0x07 +xgxs_rx_lane_map_70=0x0213 +xgxs_rx_lane_map_62=0x2310 +xgxs_rx_lane_map_54=0x2301 +xgxs_rx_lane_map_46=0x3012 +xgxs_rx_lane_map_38=0x2310 +xgxs_tx_lane_map_90=0x0123 +xgxs_tx_lane_map_82=0x3102 +xgxs_tx_lane_map_74=0x2310 +xgxs_tx_lane_map_58=0x0213 +phy_xaui_rx_polarity_flip_44=0x01 +portmap_50=49:100 +phy_xaui_rx_polarity_flip_36=0x02 +portmap_42=41:100 +phy_xaui_rx_polarity_flip_28=0x01 +xgxs_rx_lane_map_3=0x3201 +portmap_34=33:100 +portmap_26=26:25:i +portmap_18=18:25:i +xgxs_rx_lane_map_131=0x3210 +xgxs_rx_lane_map_123=0x1023 +xgxs_rx_lane_map_115=0x2301 +xgxs_rx_lane_map_107=0x2301 +xgxs_tx_lane_map_9=0x3120 +xgxs_tx_lane_map_133=0x3201 +xgxs_tx_lane_map_125=0x1023 +bcm_linkscan_interval=4000000 +xgxs_tx_lane_map_117=0x0132 +xgxs_tx_lane_map_109=0x0132 +phy_xaui_rx_polarity_flip_115=0x01 +port_phy_addr_30=0xff +port_phy_addr_22=0xff +port_phy_addr_14=0xff +xgxs_rx_lane_map_71=0x0213 +xgxs_rx_lane_map_63=0x2310 +xgxs_rx_lane_map_55=0x2301 +xgxs_rx_lane_map_47=0x3012 +xgxs_rx_lane_map_39=0x2310 +xgxs_tx_lane_map_91=0x0123 +xgxs_tx_lane_map_83=0x3102 +phy_xaui_tx_polarity_flip_31=0x02 +xgxs_tx_lane_map_75=0x2310 +phy_xaui_tx_polarity_flip_23=0x01 +xgxs_tx_lane_map_59=0x0213 +portmap_51=50:25:i +phy_xaui_rx_polarity_flip_37=0x01 +portmap_43=42:25:i +xgxs_rx_lane_map_4=0x3201 +portmap_35=34:25:i +portmap_27=27:25:50:i +portmap_19=19:25:50:i +xgxs_rx_lane_map_132=0x3210 +xgxs_rx_lane_map_124=0x1023 +xgxs_rx_lane_map_116=0x2301 +cdma_timeout_usec=4000000 +xgxs_rx_lane_map_108=0x2301 +xgxs_tx_lane_map_126=0x3120 +xgxs_tx_lane_map_118=0x1203 +phy_xaui_rx_polarity_flip_116=0x01 +port_phy_addr_31=0xff +port_phy_addr_23=0xff +port_phy_addr_15=0xff +xgxs_rx_lane_map_80=0x3210 +xgxs_rx_lane_map_72=0x2310 +xgxs_rx_lane_map_64=0x2310 +xgxs_rx_lane_map_56=0x2301 +xgxs_rx_lane_map_48=0x3012 +xgxs_tx_lane_map_92=0x0213 +phy_xaui_tx_polarity_flip_40=0x01 +xgxs_tx_lane_map_84=0x0213 +phy_xaui_tx_polarity_flip_32=0x01 +xgxs_tx_lane_map_76=0x0213 +xgxs_tx_lane_map_68=0x3120 +portmap_60=59:25:50:i +phy_xaui_rx_polarity_flip_46=0x08 +portmap_52=51:25:50:i +phy_xaui_rx_polarity_flip_38=0x04 +portmap_44=43:25:50:i +xgxs_rx_lane_map_5=0x1023 +portmap_36=35:25:50:i +portmap_28=28:25:i +mdio_output_delay=12 +xgxs_rx_lane_map_133=0x3210 +xgxs_rx_lane_map_125=0x1023 +xgxs_rx_lane_map_117=0x2301 +xgxs_rx_lane_map_109=0x2301 +xgxs_tx_lane_map_127=0x3120 +xgxs_tx_lane_map_119=0x1203 +port_phy_addr_40=0xff +port_phy_addr_32=0xff +port_phy_addr_24=0xff +port_phy_addr_16=0xff +xgxs_rx_lane_map_81=0x3210 +xgxs_rx_lane_map_73=0x2310 +tdma_timeout_usec=10000000 +xgxs_rx_lane_map_65=0x2310 +xgxs_rx_lane_map_57=0x2301 +xgxs_rx_lane_map_49=0x3012 +xgxs_tx_lane_map_93=0x0213 +xgxs_tx_lane_map_85=0x0213 +xgxs_tx_lane_map_77=0x0213 +phy_xaui_tx_polarity_flip_25=0x0d +xgxs_tx_lane_map_69=0x3120 +portmap_61=60:25:i +portmap_53=52:25:i +portmap_45=44:25:i +xgxs_rx_lane_map_6=0x1023 +portmap_37=36:25:i +portmap_29=29:100 +xgxs_rx_lane_map_126=0x2301 +xgxs_rx_lane_map_118=0x3120 +xgxs_tx_lane_map_128=0x3120 +port_phy_addr_41=0xff +ipv6_lpm_128b_enable=1 +xgxs_rx_lane_map_90=0x3210 +xgxs_rx_lane_map_82=0x3210 +xgxs_rx_lane_map_74=0x2310 +xgxs_rx_lane_map_58=0x0231 +fpem_mem_entries=0 +xgxs_tx_lane_map_94=0x0213 +phy_xaui_tx_polarity_flip_42=0x04 +xgxs_tx_lane_map_86=0x0213 +phy_xaui_tx_polarity_flip_34=0x08 +xgxs_tx_lane_map_78=0x0213 +portmap_70=67:25:50:i +portmap_62=61:100 +phy_xaui_rx_polarity_flip_48=0x02 +pbmp_xport_xe=0xfffffffffffffffffffffffffffffffffe +portmap_54=53:100 +portmap_46=45:100 +xgxs_rx_lane_map_7=0x1023 +portmap_38=37:100 +xgxs_rx_lane_map_127=0x2301 +xgxs_rx_lane_map_119=0x3120 +xgxs_tx_lane_map_129=0x3120 +l2_mem_entries=8192 +os=unix +port_phy_addr_26=0xff +port_phy_addr_18=0xff +xgxs_rx_lane_map_91=0x3210 +xgxs_rx_lane_map_83=0x3210 +xgxs_rx_lane_map_75=0x2310 +xgxs_rx_lane_map_59=0x0231 +xgxs_tx_lane_map_95=0x0213 +port_phy_addr_111=0xff +xgxs_tx_lane_map_87=0x0213 +port_phy_addr_103=0xff +xgxs_tx_lane_map_79=0x0213 +phy_xaui_tx_polarity_flip_27=0x03 +portmap_71=68:25:i +portmap_63=62:25:i +phy_xaui_rx_polarity_flip_49=0x01 +portmap_55=54:25:i +portmap_47=46:25:i +xgxs_rx_lane_map_8=0x1023 +portmap_39=38:25:i +xgxs_rx_lane_map_128=0x2301 +port_phy_addr_51=0xff +port_phy_addr_43=0xff +port_phy_addr_35=0xff +port_phy_addr_27=0xff +port_phy_addr_19=0xff +xgxs_rx_lane_map_92=0x2310 +xgxs_rx_lane_map_84=0x3210 +xgxs_rx_lane_map_76=0x0231 +xgxs_rx_lane_map_68=0x0213 +port_phy_addr_120=0xff +xgxs_tx_lane_map_96=0x0123 +phy_xaui_tx_polarity_flip_44=0x01 +port_phy_addr_112=0xff +xgxs_tx_lane_map_88=0x0123 +phy_xaui_tx_polarity_flip_36=0x02 +port_phy_addr_104=0xff +portmap_80=77:100 +phy_xaui_tx_polarity_flip_28=0x01 +portmap_72=69:100 +portmap_64=63:25:50:i +portmap_56=55:25:50:i +portmap_48=47:25:50:i +xgxs_rx_lane_map_9=0x2301 +phy_xaui_rx_polarity_flip_5=4 +xgxs_rx_lane_map_129=0x2301 +port_phy_addr_60=0xff +port_phy_addr_52=0xff +port_phy_addr_44=0xff +port_phy_addr_36=0xff +port_phy_addr_28=0xff +xgxs_rx_lane_map_93=0x2310 +xgxs_rx_lane_map_85=0x3210 +table_dma_enable=1 +xgxs_rx_lane_map_77=0x0231 +xgxs_rx_lane_map_69=0x0213 +port_phy_addr_121=0xff +xgxs_tx_lane_map_97=0x0123 +port_phy_addr_113=0xff +xgxs_tx_lane_map_89=0x0123 +phy_xaui_tx_polarity_flip_37=0x01 +port_phy_addr_105=0xff +portmap_81=78:25:i +phy_xaui_tx_polarity_flip_29=0x08 +portmap_73=70:25:i +portmap_65=64:25:i +portmap_57=56:25:i +portmap_49=48:25:i +port_phy_addr_61=0xff +port_phy_addr_53=0xff +port_phy_addr_45=0xff +port_phy_addr_37=0xff +xgxs_rx_lane_map_94=0x2310 +port_phy_addr_2=0xff +xgxs_rx_lane_map_86=0x3210 +xgxs_rx_lane_map_78=0x0231 +phy_xaui_rx_polarity_flip_92=0x0c +xgxs_tx_lane_map_98=0x0123 +phy_xaui_tx_polarity_flip_46=0x01 +portmap_90=87:25:50:i +phy_xaui_tx_polarity_flip_38=0x05 +portmap_82=79:25:50:i +portmap_74=71:25:50:i +portmap_66=129:1 +portmap_58=57:100 +phy_xaui_rx_polarity_flip_7=1 +port_phy_addr_70=0xff +xgxs_rx_lane_map_95=0x2310 +port_phy_addr_3=0xff +xgxs_rx_lane_map_87=0x3210 +xgxs_rx_lane_map_79=0x0231 +port_phy_addr_131=0xff +port_phy_addr_123=0xff +xgxs_tx_lane_map_99=0x0123 +phy_an_c37=3 +port_phy_addr_115=0xff +portmap_91=88:25:i +port_phy_addr_107=0xff +portmap_83=80:25:i +portmap_75=72:25:i +portmap_59=58:25:i +serdes_firmware_mode=0x1 +schan_intr_enable=0x00 +port_phy_addr_71=0xff +port_phy_addr_63=0xff +port_phy_addr_55=0xff +port_phy_addr_47=0xff +port_phy_addr_39=0xff +l2delete_chunks=128 +xgxs_rx_lane_map_96=0x2130 +port_phy_addr_4=0xff +xgxs_rx_lane_map_88=0x3210 +tslam_intr_enable=0 +port_phy_addr_132=0xff +phy_xaui_rx_polarity_flip_94=0x03 +port_phy_addr_124=0xff +port_phy_addr_116=0xff +portmap_92=89:100 +port_phy_addr_108=0xff +portmap_84=81:100 +portmap_76=73:100 +portmap_68=65:100 +port_phy_addr_64=0xff +mem_cache_enable=1 +port_phy_addr_56=0xff +port_phy_addr_48=0xff +parity_enable=1 +xgxs_rx_lane_map_97=0x2130 +xgxs_rx_lane_map_89=0x3210 +port_phy_addr_133=0xff +phy_xaui_rx_polarity_flip_95=0x01 +port_phy_addr_125=0xff +port_phy_addr_117=0xff +portmap_93=90:25:i +port_phy_addr_109=0xff +portmap_85=82:25:i +portmap_77=74:25:i +portmap_69=66:25:i +port_phy_addr_81=0xff +port_phy_addr_73=0xff +port_phy_addr_65=0xff +port_phy_addr_57=0xff +port_phy_addr_49=0xff +xgxs_rx_lane_map_98=0x2130 +port_phy_addr_6=0xff +phy_xaui_tx_polarity_flip_90=0x03 +phy_xaui_rx_polarity_flip_96=0x0c +portmap_94=91:25:50:i +portmap_86=83:25:50:i +portmap_78=75:25:50:i +port_phy_addr_90=0xff +port_phy_addr_82=0xff +port_phy_addr_74=0xff +load_firmware=0x102 +l2xmsg_mode=1 +xgxs_rx_lane_map_99=0x2130 +port_phy_addr_7=0xff +phy_xaui_tx_polarity_flip_91=0x01 +phy_an_c73=0 +port_phy_addr_127=0xff +port_phy_addr_119=0xff +portmap_95=92:25:i +portmap_87=84:25:i +portmap_79=76:25:i +port_phy_addr_91=0xff +port_phy_addr_83=0xff +port_phy_addr_75=0xff +port_phy_addr_59=0xff +mmu_lossless=0x01 +port_phy_addr_8=0xff +phy_xaui_tx_polarity_flip_92=0x04 +phy_xaui_tx_polarity_flip_84=0x04 +phy_xaui_rx_polarity_flip_98=0x03 +port_phy_addr_128=0xff +portmap_96=93:100 +portmap_1=1:100 +portmap_88=85:100 +phy_xaui_tx_polarity_flip_9=0x08 +phy_xaui_rx_polarity_flip_99=0x01 +port_phy_addr_129=0xff +portmap_97=94:25:i +portmap_2=2:25:i +portmap_89=86:25:i +xgxs_tx_lane_map_10=0x3120 +phy_an_c37_100=1 +port_phy_addr_93=0xff +port_phy_addr_85=0xff +port_phy_addr_77=0xff +port_phy_addr_69=0xff +phy_xaui_tx_polarity_flip_94=0x01 +phy_xaui_tx_polarity_flip_86=0x01 +max_vp_lags=0 +l3_max_ecmp_mode=1 +l3_alpm_enable=2 +portmap_98=95:25:50:i +portmap_3=3:25:50:i +miim_intr_enable=0x0 +xgxs_tx_lane_map_11=0x3120 +port_phy_addr_94=0xff +port_phy_addr_86=0xff +port_phy_addr_78=0xff +module_64ports=0 +tdma_intr_enable=0 +portmap_100=131:1 +portmap_99=96:25:i +pbmp_oversubscribe=0xC4444451111111144444444422222222 +portmap_4=4:25:i +l3_mem_entries=8192 +xgxs_tx_lane_map_20=0x0213 +xgxs_tx_lane_map_12=0x3120 +port_phy_addr_95=0xff +port_phy_addr_87=0xff +port_phy_addr_79=0xff +ptp_ts_pll_fref=0 +phy_xaui_tx_polarity_flip_96=0x08 +phy_xaui_tx_polarity_flip_88=0x0c +portmap_5=5:100 +xgxs_tx_lane_map_21=0x2310 +xgxs_tx_lane_map_13=0x1023 +tslam_dma_enable=1 +dport_map_direct=0x01 +portmap_110=105:100 +portmap_102=97:100 +portmap_6=6:25:i +xgxs_rx_lane_map_10=0x2301 +xgxs_tx_lane_map_30=0x0213 +xgxs_tx_lane_map_22=0x2310 +xgxs_tx_lane_map_14=0x1023 +phy_an_c73_100=0 +port_phy_addr_97=0xff +port_phy_addr_89=0xff +phy_xaui_tx_polarity_flip_98=0x02 +portmap_111=106:25:i +portmap_103=98:25:i +portmap_7=7:25:50:i +xgxs_rx_lane_map_11=0x2301 +xgxs_tx_lane_map_31=0x0213 +xgxs_tx_lane_map_23=0x2310 +xgxs_tx_lane_map_15=0x1023 +port_phy_addr_98=0xff + diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/default_sku b/device/juniper/x86_64-juniper_qfx5200-r0/default_sku new file mode 100644 index 000000000000..cf933bb4c87a --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/default_sku @@ -0,0 +1 @@ +Juniper-QFX5200-32C-S t1 diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/installer.conf b/device/juniper/x86_64-juniper_qfx5200-r0/installer.conf new file mode 100644 index 000000000000..e86aed7e522b --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/installer.conf @@ -0,0 +1,4 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 +CONSOLE_SPEED=9600 +VAR_LOG_SIZE=1024 diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/led_proc_init.soc b/device/juniper/x86_64-juniper_qfx5200-r0/led_proc_init.soc new file mode 100644 index 000000000000..f2b749eeba03 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/led_proc_init.soc @@ -0,0 +1,49 @@ +# LED microprocessor initialization for Tomahawk + + + +setreg CMIC_LEDUP0_CLK_DIV 0x54 +setreg CMIC_LEDUP1_CLK_DIV 0x54 +setreg CMIC_LEDUP2_CLK_DIV 0x54 + +led 0 stop +led 0 prog 02 fd 42 80 02 ff 42 00 02 fe 42 00 02 fb 42 40 67 14 3a 40 06 fe 88 88 88 4a 00 27 4a 01 27 b7 80 4a 00 27 c7 d7 87 80 4a 00 27 4a 01 27 b7 80 4a 00 27 c7 d7 87 80 4a 00 27 4a 01 27 b7 80 4a 00 27 c7 d7 87 80 4a 00 27 4a 01 27 b7 80 4a 00 27 c7 d7 87 86 fe 06 fe d2 10 74 14 57 +setreg CMIC_LEDUP0_PORT_ORDER_REMAP_0_3 0x411493 +setreg CMIC_LEDUP0_PORT_ORDER_REMAP_4_7 0x515597 +setreg CMIC_LEDUP0_PORT_ORDER_REMAP_8_11 0x30d38f +setreg CMIC_LEDUP0_PORT_ORDER_REMAP_12_15 0x20928b +setreg CMIC_LEDUP0_PORT_ORDER_REMAP_16_19 0xf3dfbf +setreg CMIC_LEDUP0_PORT_ORDER_REMAP_20_23 0xe39ebb +setreg CMIC_LEDUP0_PORT_ORDER_REMAP_24_27 0xd35db7 +setreg CMIC_LEDUP0_PORT_ORDER_REMAP_28_31 0xc31cb3 +setreg CMIC_LEDUP0_PORT_ORDER_REMAP_32_35 0xb2dbaf +setreg CMIC_LEDUP0_PORT_ORDER_REMAP_36_39 0xa29aab +setreg CMIC_LEDUP0_PORT_ORDER_REMAP_40_43 0x9259a7 +setreg CMIC_LEDUP0_PORT_ORDER_REMAP_44_47 0x8218a3 +setreg CMIC_LEDUP0_PORT_ORDER_REMAP_48_51 0x71d79f +setreg CMIC_LEDUP0_PORT_ORDER_REMAP_52_55 0x61969b +setreg CMIC_LEDUP0_PORT_ORDER_REMAP_56_59 0x105187 +setreg CMIC_LEDUP0_PORT_ORDER_REMAP_60_63 0x1083 +led 0 auto on +led 0 start + +led 1 stop +led 1 prog 02 fd 42 80 02 ff 42 00 02 fe 42 00 02 fb 42 40 67 14 3a 40 06 fe 88 88 88 4a 00 27 4a 01 27 b7 80 4a 00 27 c7 d7 87 80 4a 00 27 4a 01 27 b7 80 4a 00 27 c7 d7 87 80 4a 00 27 4a 01 27 b7 80 4a 00 27 c7 d7 87 80 4a 00 27 4a 01 27 b7 80 4a 00 27 c7 d7 87 86 fe 06 fe d2 10 74 14 57 +setreg CMIC_LEDUP1_PORT_ORDER_REMAP_0_3 0xb2dbaf +setreg CMIC_LEDUP1_PORT_ORDER_REMAP_4_7 0xa29aab +setreg CMIC_LEDUP1_PORT_ORDER_REMAP_8_11 0xc31cb3 +setreg CMIC_LEDUP1_PORT_ORDER_REMAP_12_15 0xd35db7 +setreg CMIC_LEDUP1_PORT_ORDER_REMAP_16_19 0x1083 +setreg CMIC_LEDUP1_PORT_ORDER_REMAP_20_23 0x105187 +setreg CMIC_LEDUP1_PORT_ORDER_REMAP_24_27 0x20928b +setreg CMIC_LEDUP1_PORT_ORDER_REMAP_28_31 0x30d38f +setreg CMIC_LEDUP1_PORT_ORDER_REMAP_32_35 0x411493 +setreg CMIC_LEDUP1_PORT_ORDER_REMAP_36_39 0x515597 +setreg CMIC_LEDUP1_PORT_ORDER_REMAP_40_43 0x61969b +setreg CMIC_LEDUP1_PORT_ORDER_REMAP_44_47 0x71d79f +setreg CMIC_LEDUP1_PORT_ORDER_REMAP_48_51 0x8218a3 +setreg CMIC_LEDUP1_PORT_ORDER_REMAP_52_55 0x9259a7 +setreg CMIC_LEDUP1_PORT_ORDER_REMAP_56_59 0xe39ebb +setreg CMIC_LEDUP1_PORT_ORDER_REMAP_60_63 0xf3dfbf +led 1 auto on +led 1 start \ No newline at end of file diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/media_settings.json b/device/juniper/x86_64-juniper_qfx5200-r0/media_settings.json new file mode 100644 index 000000000000..c56f2457e411 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/media_settings.json @@ -0,0 +1,176 @@ +{ + "GLOBAL_MEDIA_SETTINGS": { + "0-31": { + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x0c6400", + "lane1":"0x0c6400", + "lane2":"0x0c6400", + "lane3":"0x0c6400" + }, + "idriver": { + "lane0":"0xa", + "lane1":"0xa", + "lane2":"0xa", + "lane3":"0xa" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU2": { + "preemphasis": { + "lane0":"0x0c6400", + "lane1":"0x0c6400", + "lane2":"0x0c6400", + "lane3":"0x0c6400" + }, + "idriver": { + "lane0":"0xa", + "lane1":"0xa", + "lane2":"0xa", + "lane3":"0xa" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x0c6400", + "lane1":"0x0c6400", + "lane2":"0x0c6400", + "lane3":"0x0c6400" + }, + "idriver": { + "lane0":"0xa", + "lane1":"0xa", + "lane2":"0xa", + "lane3":"0xa" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x0c6400", + "lane1":"0x0c6400", + "lane2":"0x0c6400", + "lane3":"0x0c6400" + }, + "idriver": { + "lane0":"0xa", + "lane1":"0xa", + "lane2":"0xa", + "lane3":"0xa" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x0c6400", + "lane1":"0x0c6400", + "lane2":"0x0c6400", + "lane3":"0x0c6400" + }, + "idriver": { + "lane0":"0xa", + "lane1":"0xa", + "lane2":"0xa", + "lane3":"0xa" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J3": { + "preemphasis": { + "lane0":"0x0c6400", + "lane1":"0x0c6400", + "lane2":"0x0c6400", + "lane3":"0x0c6400" + }, + "idriver": { + "lane0":"0xa", + "lane1":"0xa", + "lane2":"0xa", + "lane3":"0xa" + } + }, + "JUNIPER-INNO-TR-FC13L-NJC": { + "preemphasis": { + "lane0":"0x0c6400", + "lane1":"0x0c6400", + "lane2":"0x0c6400", + "lane3":"0x0c6400" + }, + "idriver": { + "lane0":"0xa", + "lane1":"0xa", + "lane2":"0xa", + "lane3":"0xa" + } + }, + "JUNIPER-INNO-TR-FC13R-NJC": { + "preemphasis": { + "lane0":"0x0c6400", + "lane1":"0x0c6400", + "lane2":"0x0c6400", + "lane3":"0x0c6400" + }, + "idriver": { + "lane0":"0xa", + "lane1":"0xa", + "lane2":"0xa", + "lane3":"0xa" + } + }, + "JUNIPER-SOURCE-SPQCELRCDFAJ2": { + "preemphasis": { + "lane0":"0x0c6400", + "lane1":"0x0c6400", + "lane2":"0x0c6400", + "lane3":"0x0c6400" + }, + "idriver": { + "lane0":"0xa", + "lane1":"0xa", + "lane2":"0xa", + "lane3":"0xa" + } + }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x0c6400", + "lane1":"0x0c6400", + "lane2":"0x0c6400", + "lane3":"0x0c6400" + }, + "idriver": { + "lane0":"0xa", + "lane1":"0xa", + "lane2":"0xa", + "lane3":"0xa" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x0c6400", + "lane1":"0x0c6400", + "lane2":"0x0c6400", + "lane3":"0x0c6400" + }, + "idriver": { + "lane0":"0xa", + "lane1":"0xa", + "lane2":"0xa", + "lane3":"0xa" + } + }, + "FINISAR CORP.-FTL4C1QE1C-J1": { + "preemphasis": { + "lane0":"0x115f00", + "lane1":"0x115f00", + "lane2":"0x115f00", + "lane3":"0x115f00" + }, + "idriver": { + "lane0":"0x0", + "lane1":"0x0", + "lane2":"0x0", + "lane3":"0x0" + } + } + } + }, + "PORT_MEDIA_SETTINGS": { + } +} diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/plugins/eeprom.py b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/eeprom.py new file mode 100644 index 000000000000..33898d83a0e9 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/eeprom.py @@ -0,0 +1,62 @@ +# +# Name: eeprom.py version: 1.0 +# +# Description: Platform-specific EEPROM interface for Juniper QFX5200 +# +# Copyright (c) 2020, Juniper Networks, Inc. +# All rights reserved. +# +# Notice and Disclaimer: This code is licensed to you under the GNU General +# Public License as published by the Free Software Foundation, version 3 or +# any later version. This code is not an official Juniper product. You can +# obtain a copy of the License at +# +# OSS License: +# +# This program is free software: you can 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 . +# +# Third-Party Code: This code may depend on other components under separate +# copyright notice and license terms. Your use of the source code for those +# components is subject to the terms and conditions of the respective license +# as noted in the Third-Party source code file. + +try: + import os + from sonic_eeprom import eeprom_tlvinfo + import syslog + from array import * +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +SYSLOG_IDENTIFIER = "eeprom.py" +EEPROM_PATH = "/sys/bus/i2c/devices/0-0051/eeprom" + + +def log_error(msg): + syslog.openlog(SYSLOG_IDENTIFIER) + syslog.syslog(syslog.LOG_ERR, msg) + syslog.closelog() + + +class board(eeprom_tlvinfo.TlvInfoDecoder): + _TLV_INFO_MAX_LEN = 256 + + def __init__(self, name, path, cpld_root, ro): + + if not os.path.exists(EEPROM_PATH): + log_error("Cannot find system eeprom") + raise RuntimeError("No syseeprom found") + + self.eeprom_path = EEPROM_PATH + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/plugins/led_control.py b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/led_control.py new file mode 100644 index 000000000000..223c6dc8a289 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/led_control.py @@ -0,0 +1,184 @@ +# +# Name: led_control.py version: 1.0 +# +# Description: Platform-specific LED control functionality for Juniper QFX5200 +# +# Copyright (c) 2020, Juniper Networks, Inc. +# All rights reserved. +# +# Notice and Disclaimer: This code is licensed to you under the GNU General +# Public License as published by the Free Software Foundation, version 3 or +# any later version. This code is not an official Juniper product. You can +# obtain a copy of the License at +# +# OSS License: +# +# This program is free software: you can 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 . +# +# Third-Party Code: This code may depend on other components under separate +# copyright notice and license terms. Your use of the source code for those +# components is subject to the terms and conditions of the respective license +# as noted in the Third-Party source code file. + +try: + from sonic_led.led_control_base import LedControlBase + import os + import syslog + import glob + from socket import * + from select import * +except ImportError as e: + raise ImportError(str(e) + " - required module not found") + + +def DBG_PRINT(str): + syslog.openlog("ledi_control") + syslog.syslog(syslog.LOG_INFO, str) + syslog.closelog() + + +class LedControl(LedControlBase): + """Platform specific LED control class""" + SONIC_PORT_NAME_PREFIX = "Ethernet" + LED_MODE_OFF = 0 + LED_MODE_GREEN = 1 + PORT_START = 0 + PORT_END = 127 + port_to_gpio_pin_mapping = {} + GPIO_SLAVE0_PORT_START = 0 + GPIO_SLAVE0_PORT_END = 63 + GPIO_SLAVE1_PORT_START = 64 + GPIO_SLAVE1_PORT_END = 127 + + GPIO_LANE0_PORT_LED_OFFSET = 64 + GPIO_LANE1_PORT_LED_OFFSET = 80 + GPIO_LANE2_PORT_LED_OFFSET = 96 + GPIO_LANE3_PORT_LED_OFFSET = 112 + + # Turn OFF all port leds during init + def gpio_create_file(self, gpio_pin): + gpio_export_path = "/sys/class/gpio/export" + gpio_pin_path = "/sys/class/gpio/gpio" + str(gpio_pin) + if not os.path.exists(gpio_pin_path): + try: + gpio_export_file = open(gpio_export_path, 'w') + gpio_export_file.write(str(gpio_pin)) + gpio_export_file.close() + except IOError as e: + print("Error: unable to open export file: %s" % str(e)) + return False + + return True + + def gpio_port_led_init(self, gpio_base, port): + port_led_pin = gpio_base + self.GPIO_LANE0_PORT_LED_OFFSET + 16*(port % 4) + ((port % 64)/4) + if self.gpio_create_file(port_led_pin): + self.port_to_gpio_pin_mapping[port] = port_led_pin + + def gpio_port_led_slave_init(self, gpio_base_path, gpio_port_start, gpio_port_end): + flist = glob.glob(gpio_base_path) + if len(flist) == 1: + try: + fp = open(flist[0] + "/base") + gpio_base = int(fp.readline().rstrip()) + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return + for port in range(gpio_port_start, gpio_port_end + 1): + self.gpio_port_led_init(gpio_base, port) + + def gpio_port_led_base_init(self): + self.gpio_port_led_slave_init("/sys/bus/platform/drivers/gpioslave-tmc/gpioslave-tmc.22/gpio/gpio*", + self.GPIO_SLAVE0_PORT_START, self.GPIO_SLAVE0_PORT_END) + self.gpio_port_led_slave_init("/sys/bus/platform/drivers/gpioslave-tmc/gpioslave-tmc.21/gpio/gpio*", + self.GPIO_SLAVE1_PORT_START, self.GPIO_SLAVE1_PORT_END) + + # Write driver for port led + def gpio_led_write(self, gpio_pin, value): + success = False + gpio_pin_path = "/sys/class/gpio/gpio" + str(gpio_pin) + + try: + gpio_file = open(gpio_pin_path + "/value", 'w') + gpio_file.write(str(value)) + success = True + except IOError as e: + print("error: unable to open file: %s" % str(e)) + + return success + + # Read driver for port led + def gpio_led_read(self, gpio_pin): + gpio_pin_path = "/sys/class/gpio/gpio" + str(gpio_pin) + value = 0 + + try: + reg_file = open(gpio_pin_path + "/value") + value = int(reg_file.readline().rstrip()) + except IOError as e: + print("error: unable to open file: %s" % str(e)) + + return value + + def _initDefaultConfig(self): + DBG_PRINT("start init led") + + for port in range(self.PORT_START, self.PORT_END): + self._port_led_mode_update(self.port_to_gpio_pin_mapping[port], self.LED_MODE_OFF) + + DBG_PRINT("init led done") + + # Helper method to map SONiC port name to index + def _port_name_to_index(self, port_name): + # Strip "Ethernet" off port name + if not port_name.startswith(self.SONIC_PORT_NAME_PREFIX): + return -1 + + port_idx = int(port_name[len(self.SONIC_PORT_NAME_PREFIX):]) + return port_idx + + # Convert state up/down to Green/OFF which is 1/0 + def _port_state_to_mode(self, state): + if state == "up": + return self.LED_MODE_GREEN + else: + return self.LED_MODE_OFF + + # Set the port led mode to Green/OFF + + def _port_led_mode_update(self, gpio_pin, ledMode): + if ledMode == self.LED_MODE_GREEN: + self.gpio_led_write(gpio_pin, 1) + else: + self.gpio_led_write(gpio_pin, 0) + + # Concrete implementation of port_link_state_change() method + + def port_link_state_change(self, portname, state): + port_idx = self._port_name_to_index(portname) + gpio_pin = self.port_to_gpio_pin_mapping[port_idx] + + ledMode = self._port_state_to_mode(state) + saveMode = self.gpio_led_read(gpio_pin) + + if ledMode == saveMode: + return + + self._port_led_mode_update(gpio_pin, ledMode) + DBG_PRINT("update {} led mode from {} to {}".format(portname, saveMode, ledMode)) + + # Constructor + def __init__(self): + self.gpio_port_led_base_init() + self._initDefaultConfig() diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/plugins/psuutil.py b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/psuutil.py new file mode 100644 index 000000000000..7ee1d3c38a3d --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/psuutil.py @@ -0,0 +1,102 @@ +# +# Name: psuutil.py version: 1.0 +# +# Description: Platform-specific PSU status interface for Juniper QFX5200 +# +# Copyright (c) 2020, Juniper Networks, Inc. +# All rights reserved. +# +# Notice and Disclaimer: This code is licensed to you under the GNU General +# Public License as published by the Free Software Foundation, version 3 or +# any later version. This code is not an official Juniper product. You can +# obtain a copy of the License at +# +# OSS License: +# +# This program is free software: you can 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 . +# +# Third-Party Code: This code may depend on other components under separate +# copyright notice and license terms. Your use of the source code for those +# components is subject to the terms and conditions of the respective license +# as noted in the Third-Party source code file. + + +import os.path + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + PSU_DIR = "/sys/devices/pci0000:00/0000:00:1c.0/0000:0f:00.0/psu-tmc.15" + + def __init__(self): + PsuBase.__init__(self) + + +# Get sysfs attribute + + + def get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip(' \t\n\r') + return int(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 (starts from 1) of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is\ + faulty + """ + attr_file = 'psu' + str(index-1) + '_' + 'present' + attr_path = self.PSU_DIR + '/' + attr_file + attr_value = self.get_attr_value(attr_path) + + return attr_value == 1 + + 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 + """ + attr_file = 'psu' + str(index-1) + '_' + 'present' + attr_path = self.PSU_DIR + '/' + attr_file + attr_value = self.get_attr_value(attr_path) + return attr_value == 1 diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/plugins/qfx5200_eeprom_data.py b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/qfx5200_eeprom_data.py new file mode 100644 index 000000000000..ea53f11e698d --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/qfx5200_eeprom_data.py @@ -0,0 +1,437 @@ +#!/usr/bin/env python3 +# +# Name: juniper_qfx5200_eepromconv.py version: 1.0 +# +# Description: This file contains the code to store the contents of Main Board EEPROM and CPU Board EEPROM in file +# +# Copyright (c) 2020, Juniper Networks, Inc. +# All rights reserved. +# +# Notice and Disclaimer: This code is licensed to you under the GNU General +# Public License as published by the Free Software Foundation, version 3 or +# any later version. This code is not an official Juniper product. You can +# obtain a copy of the License at +# +# OSS License: +# +# This program is free software: you can 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 . +# +# Third-Party Code: This code may depend on other components under separate +# copyright notice and license terms. Your use of the source code for those +# components is subject to the terms and conditions of the respective license +# as noted in the Third-Party source code file. + +import binascii +import os +import sys +from sonic_eeprom import eeprom_tlvinfo + +if sys.version_info[0] < 3: + import commands +else: + import subprocess as commands + + +def fantype_detect(): + + refpgaTMC_path = "/sys/devices/pci0000:00/0000:00:1c.0/0000:0f:00.0/refpga-tmc.15" + + AFO = "1" + AFI = "0" + + # default fan type is AFO + default_fantype = "0" + + for filename in os.listdir(refpgaTMC_path): + if filename.endswith('_type'): + fantype_path = os.path.join(refpgaTMC_path, filename) + cat_string = "cat " + fantype_string = cat_string + fantype_path + status, fan_type = commands.getstatusoutput(fantype_string) + if ((fan_type == AFO) or (fan_type == AFI)): + return fan_type + else: + pass + + return default_fantype + + +def main(): + AFO_value = "1" + + eeprom_qfx5200 = Eeprom() + + fan_type = fantype_detect() + + # creating the "/var/run/eeprom" file and storing values of CPU board EEPROM and MAIN Board EEPROM in this file. + eeprom_file = open("/var/run/eeprom", "a+") + eeprom_file.write("\n") + if fan_type == AFO_value: + eeprom_file.write("Fan Type=AFO\r\n") + else: + eeprom_file.write("Fan Type=AFI\r\n") + + eeprom_file.write("\n") + + # Write the contents of CPU Board EEPROM to file + eeprom_file.write("CPU board eeprom (0x51)\r\n") + eeprom_file.write("===============================\r\n") + eeprom_file.write("Product Name=%s\r\n" % eeprom_qfx5200.modelstr()) + eeprom_file.write("Part Number=%s\r\n" % eeprom_qfx5200.part_number_str()) + eeprom_file.write("Serial Number=%s\r\n" % eeprom_qfx5200.serial_number_str()) + eeprom_file.write("MAC Address=%s\r\n" % eeprom_qfx5200.base_mac_address()) + eeprom_file.write("Manufacture Date=%s\r\n" % eeprom_qfx5200.manuDate_str()) + eeprom_file.write("Platform Name=%s\r\n" % eeprom_qfx5200.platform_str()) + eeprom_file.write("Number of MAC Addresses=%s\r\n" % eeprom_qfx5200.MACsize_str()) + eeprom_file.write("Vendor Name=%s\r\n" % eeprom_qfx5200.vendor_name_str()) + eeprom_file.write("Manufacture Name=%s\r\n" % eeprom_qfx5200.manufacture_name_str()) + + eeprom_dict = eeprom_qfx5200.system_eeprom_info() + key = '0x29' + if key in list(eeprom_dict.keys()): + onie_version_str = eeprom_dict.get('0x29', None) + else: + onie_version_str = "N/A" + eeprom_file.write("ONIE Version=%s\r\n" % onie_version_str) + + vendor_value_formatted, vendor_value_hexvalue = eeprom_qfx5200.vendor_ext_str() + + eeprom_hex = '/etc/init.d/eeprom_qfx5200_hex' + + with open(eeprom_hex, 'wb+') as Hexfile: + Hexfile.write(vendor_value_hexvalue) + + # Assembly ID + ASMID_str = "0D83" + with open(eeprom_hex, 'rb+') as AsmID_Hexfile: + AsmID_Hexfile.seek(24, 0) + AsmID_Hexfile.write(ASMID_str) + AsmID_Hexfile.seek(0, 0) + vendorext_read = AsmID_Hexfile.read(58) + vendorext = "" + vendorext += "0x" + vendorext_read[0:2] + for i in range(2, 58, 2): + vendorext += " 0x" + vendorext_read[i:i+2] + eeprom_file.write("Vendor Extension=%s\r\n" % str(vendorext)) + + with open(eeprom_hex, 'rb') as eeprom_hexfile: + eeprom_hexfile.seek(0, 0) + IANA_position_read = eeprom_hexfile.read(8) + IANA_write = binascii.unhexlify(IANA_position_read) + eeprom_file.write("\t") + eeprom_file.write("IANA=0x%s\r\n" % IANA_write) + + eeprom_hexfile.seek(8, 0) + AssemblyPartRev_position_read = eeprom_hexfile.read(16) + AssemblyPartRev_write = binascii.unhexlify(AssemblyPartRev_position_read) + eeprom_file.write("\t") + eeprom_file.write("Assembly Part Number Revision=0x%s\r\n" % AssemblyPartRev_write) + + eeprom_hexfile.seek(24, 0) + AssemblyID_write = eeprom_hexfile.read(4) + eeprom_file.write("\t") + eeprom_file.write("Assembly ID=0x%s\r\n" % AssemblyID_write) + + eeprom_hexfile.seek(28, 0) + HWMajorRev_write = eeprom_hexfile.read(2) + eeprom_file.write("\t") + eeprom_file.write("HW Major Revision=0x%s\r\n" % HWMajorRev_write) + + eeprom_hexfile.seek(30, 0) + HWMinorRev_write = eeprom_hexfile.read(2) + eeprom_file.write("\t") + eeprom_file.write("HW Minor Revision=0x%s\r\n" % HWMinorRev_write) + + eeprom_hexfile.seek(32, 0) + Deviation_write = eeprom_hexfile.read(10) + eeprom_file.write("\t") + eeprom_file.write("Deviation=0x%s\r\n" % Deviation_write) + + eeprom_hexfile.seek(52, 0) + JEDC_write = eeprom_hexfile.read(4) + eeprom_file.write("\t") + eeprom_file.write("JEDC=0x%s\r\n" % JEDC_write) + + eeprom_hexfile.seek(56, 0) + EEPROM_version_write = eeprom_hexfile.read(2) + eeprom_file.write("\t") + eeprom_file.write("EEPROM version=0x%s\r\n" % EEPROM_version_write) + + crc_str = eeprom_dict.get('0xFE', None) + eeprom_file.write("CRC=%s\r\n" % crc_str) + + eeprom_file.write("\n") + eeprom_file.write("\n") + eeprom_file.write("Main board eeprom (0x57)\r\n") + eeprom_file.write("===============================\r\n") + + MainEepromCreate = 'sudo echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-0/new_device' + # Write the contents of Main Board EEPROM to file + try: + os.system(MainEepromCreate) + except OSError: + print('Error: Execution of "%s" failed', MainEepromCreate) + return False + + MainEepromFileCmd = 'cat /sys/bus/i2c/devices/i2c-0/0-0057/eeprom > /etc/init.d/MainEeprom_qfx5200_ascii' + try: + os.system(MainEepromFileCmd) + except OSError: + print('Error: Execution of "%s" failed', MainEepromFileCmd) + return False + + maineeprom_ascii = '/etc/init.d/MainEeprom_qfx5200_ascii' + + # Read file contents in Hex format + with open(maineeprom_ascii, 'rb') as Hexformat: + content = Hexformat.read() + + Hexformatoutput = binascii.hexlify(content) + eeprom_hex = '/etc/init.d/MainEeprom_qfx5200_hex' + # Write contents of CPU EEPROM to new file in hexa format + with open(eeprom_hex, 'wb+') as Hexfile: + Hexfile.write(Hexformatoutput) + + with open(eeprom_hex, 'rb') as eeprom_hexfile: + eeprom_hexfile.seek(8, 0) + AssemblyID_read = eeprom_hexfile.read(4) + eeprom_file.write("Assembly ID=0x%s\r\n" % AssemblyID_read) + + eeprom_hexfile.seek(12, 0) + MajorHWRev_read = eeprom_hexfile.read(2) + eeprom_file.write("Assembly Major Revision=0x%s\r\n" % str(MajorHWRev_read)) + + eeprom_hexfile.seek(14, 0) + MinorHWRev_read = eeprom_hexfile.read(2) + eeprom_file.write("Assembly Minor Revision=0x%s\r\n" % str(MinorHWRev_read)) + + eeprom_hexfile.seek(24, 0) + AssemblyPNRev_read = eeprom_hexfile.read(16) + AssemblyPNRev_write = binascii.unhexlify(AssemblyPNRev_read) + eeprom_file.write("Assembly Part Number Revision=0x%s\r\n" % str(AssemblyPNRev_write)) + + eeprom_hexfile.seek(40, 0) + AssemblyPN_read = eeprom_hexfile.read(24) + AssemblyPN_write = binascii.unhexlify(AssemblyPN_read) + eeprom_file.write("Assembly Part Number=%s\r\n" % str(AssemblyPN_write)) + + eeprom_hexfile.seek(64, 0) + AssemblySN_read = eeprom_hexfile.read(24) + AssemblySN_write = binascii.unhexlify(AssemblySN_read) + eeprom_file.write("Assembly Serial Number=%s\r\n" % str(AssemblySN_write)) + + eeprom_hexfile.seek(90, 0) + AssemblyMFGDate_read = eeprom_hexfile.read(8) + eeprom_file.write("Manufacture Date=%s\r\n" % str(AssemblyMFGDate_read)) + + eeprom_hexfile.seek(138, 0) + CLEICode_read = eeprom_hexfile.read(20) + CLEI_name = binascii.unhexlify(CLEICode_read) + eeprom_file.write("CLEI Code=%s\r\n" % str(CLEI_name)) + + eeprom_hexfile.seek(158, 0) + FRUModelNumber_read = eeprom_hexfile.read(46) + FRUModelNumber_write = binascii.unhexlify(FRUModelNumber_read) + eeprom_file.write("FRU Model Number=%s\r\n" % str(FRUModelNumber_write)) + + eeprom_hexfile.seek(204, 0) + FRUModelMajorNumber_read = eeprom_hexfile.read(2) + eeprom_file.write("FRU Model Major Number=0x%s\r\n" % str(FRUModelMajorNumber_read)) + + eeprom_hexfile.seek(206, 0) + FRUModelMinorNumber_read = eeprom_hexfile.read(4) + eeprom_file.write("FRU Model Minor Number=0x%s\r\n" % str(FRUModelMinorNumber_read)) + + eeprom_hexfile.seek(210, 0) + Deviation_read = eeprom_hexfile.read(10) + eeprom_file.write("Deviation=0x%s\r\n" % str(Deviation_read)) + + eeprom_hexfile.seek(232, 0) + SerialNumber_read = eeprom_hexfile.read(24) + SerialNumber_write = binascii.unhexlify(SerialNumber_read) + eeprom_file.write("Chassis Serial Number=%s\r\n" % str(SerialNumber_write)) + eeprom_file.close() + return True + + +class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): + def __init__(self): + self.__eeprom_path = "/sys/class/i2c-adapter/i2c-0/0-0051/eeprom" + super(Eeprom, self).__init__(self.__eeprom_path, 0, '', True) + self.__eeprom_tlv_dict = dict() + try: + self.__eeprom_data = self.read_eeprom() + except: + self.__eeprom_data = "N/A" + raise RuntimeError("Eeprom is not Programmed") + else: + eeprom = self.__eeprom_data + + if not self.is_valid_tlvinfo_header(eeprom): + return + + total_length = (ord(eeprom[9]) << 8) | ord(eeprom[10]) + tlv_index = self._TLV_INFO_HDR_LEN + tlv_end = self._TLV_INFO_HDR_LEN + total_length + + while (tlv_index + 2) < len(eeprom) and tlv_index < tlv_end: + if not self.is_valid_tlv(eeprom[tlv_index:]): + break + + tlv = eeprom[tlv_index:tlv_index + 2 + + ord(eeprom[tlv_index + 1])] + code = "0x%02X" % (ord(tlv[0])) + + if ord(tlv[0]) == self._TLV_CODE_VENDOR_EXT: + value = str((ord(tlv[2]) << 24) | (ord(tlv[3]) << 16) | + (ord(tlv[4]) << 8) | ord(tlv[5])) + value += str(tlv[6:6 + ord(tlv[1])]) + else: + name, value = self.decoder(None, tlv) + + self.__eeprom_tlv_dict[code] = value + if ord(eeprom[tlv_index]) == self._TLV_CODE_CRC_32: + break + + tlv_index += ord(eeprom[tlv_index+1]) + 2 + + def serial_number_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_SERIAL_NUMBER) + if not is_valid: + return "N/A" + return results[2] + + def base_mac_address(self): + (is_valid, t) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_MAC_BASE) + if not is_valid or t[1] != 6: + return super(eeprom_tlvinfo.TlvInfoDecoder, self).switchaddrstr(self.__eeprom_data) + + return ":".join([binascii.b2a_hex(T) for T in t[2]]) + + def modelstr(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_PRODUCT_NAME) + if not is_valid: + return "N/A" + + return results[2] + + def part_number_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_PART_NUMBER) + if not is_valid: + return "N/A" + + return results[2] + + def serial_tag_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_SERVICE_TAG) + if not is_valid: + return "N/A" + + return results[2] + + def revision_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_DEVICE_VERSION) + if not is_valid: + return "N/A" + + return results[2] + + def manuDate_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_MANUF_DATE) + if not is_valid: + return "N/A" + + return results[2] + + def platform_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_PLATFORM_NAME) + if not is_valid: + return "N/A" + + return results[2] + + def MACsize_str(self): + (is_valid, t) = self.get_tlv_field(self.__eeprom_data, self._TLV_CODE_MAC_SIZE) + + if not is_valid: + return "N/A" + + return str((ord(t[2][0]) << 8) | ord(t[2][1])) + + def vendor_name_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_VENDOR_NAME) + if not is_valid: + return "N/A" + + return results[2] + + def manufacture_name_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_MANUF_NAME) + if not is_valid: + return "N/A" + + return results[2] + + def onie_version_str(self): + value = "" + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_ONIE_VERSION) + if not is_valid: + return "N/A" + + for c in results[2:2 + ord(results[1])]: + value += "0x%02X " % (ord(c),) + + return value + + def vendor_ext_str(self): + + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_VENDOR_EXT) + + if not is_valid: + return "N/A" + + vendor_value_formatted = ''.join([" 0x" + "%02X " % ord(x) for x in results[2]]).strip() + vendor_value_hexvalue = ''.join(["%02X" % ord(x) for x in results[2]]).strip() + + return vendor_value_formatted, vendor_value_hexvalue + + def crc_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_CRC_32) + if not is_valid: + return "N/A" + + def system_eeprom_info(self): + """ + Returns a dictionary, where keys are the type code defined in + ONIE EEPROM format and values are their corresponding values + found in the system EEPROM. + """ + return self.__eeprom_tlv_dict + + +if __name__ == "__main__": + main() diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/plugins/qfx5200_sfp_init.py b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/qfx5200_sfp_init.py new file mode 100644 index 000000000000..723a4073687e --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/qfx5200_sfp_init.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python3 +# +# Name: juniper_sfp_init.py version: 1.0 +# +# Description: Platform-specific SFP Transceiver Initialization for Juniper QFX5200 +# +# Copyright (c) 2020, Juniper Networks, Inc. +# All rights reserved. +# +# Notice and Disclaimer: This code is licensed to you under the GNU General +# Public License as published by the Free Software Foundation, version 3 or +# any later version. This code is not an official Juniper product. You can +# obtain a copy of the License at +# +# OSS License: +# +# This program is free software: you can 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 . +# +# Third-Party Code: This code may depend on other components under separate +# copyright notice and license terms. Your use of the source code for those +# components is subject to the terms and conditions of the respective license +# as noted in the Third-Party source code file. + +import time +import os.path +import sfputil as jnpr_sfp +from sonic_py_common.logger import Logger +from pprint import pprint + +SYSLOG_IDENTIFIER = "sfputil" + +# Global logger class instance +logger = Logger(SYSLOG_IDENTIFIER) + +DEBUG = False + + +def i2c_eeprom_dev_update(port, create_eeprom): + eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" + i2c_path = "/sys/class/i2c-adapter/i2c-{0}" + i2c_port = port + jnpr_sfp.SFP_I2C_OFFSET + port_eeprom_path = eeprom_path.format(i2c_port) + port_i2c_path = i2c_path.format(i2c_port) + if create_eeprom: + if not os.path.exists(port_eeprom_path): + try: + i2c_file = open(port_i2c_path + "/new_device", "w") + i2c_file.write("optoe2 0x50") + except IOError as e: + print("Error: unable to write to i2c file: %s" % str(e)) + return + else: + if os.path.exists(port_eeprom_path): + try: + i2c_file = open(port_i2c_path + "/delete_device", "w") + i2c_file.write("0x50") + except IOError as e: + print("Error: unable to write to i2c file: %s" % str(e)) + return + + +def gpio_sfp_init(): + jnpr_sfp.gpio_sfp_base_init() + + time.sleep(2) + + # Reset all ports + for port in range(jnpr_sfp.GPIO_PORT_START, jnpr_sfp.GPIO_PORT_END + 1): + logger.log_debug("GPIO SFP port {}".format(port)) + + jnpr_sfp.gpio_sfp_reset_set(port, 0) + i2c_eeprom_dev_update(port, True) + + time.sleep(1) + + # Enable optics for all ports which have XCVRs present + for port in range(jnpr_sfp.GPIO_PORT_START, jnpr_sfp.GPIO_PORT_END + 1): + jnpr_sfp.gpio_sfp_lpmode_set(port, 1) + + +if __name__ == '__main__': + + if DEBUG == True: + print("Initializing Juniper SFP module") + + gpio_sfp_init() + if DEBUG == True: + print("Juniper GPIO presence pin mapping:") + pprint(jnpr_sfp.gpio_sfp_presence) + print("Juniper GPIO reset pin mapping:") + pprint(jnpr_sfp.gpio_sfp_reset) + print("Juniper GPIO lpmode pin mapping:") + pprint(jnpr_sfp.gpio_sfp_lpmode) diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/plugins/sfputil.py b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/sfputil.py new file mode 100644 index 000000000000..db85347be3f4 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/sfputil.py @@ -0,0 +1,1143 @@ +# Name: sfputil.py version: 1.0 +# +# Description: Platform-specific SFP transceiver interface for Juniper QFX5200 +# +# Copyright (c) 2020, Juniper Networks, Inc. +# All rights reserved. +# +# Notice and Disclaimer: This code is licensed to you under the GNU General +# Public License as published by the Free Software Foundation, version 3 or +# any later version. This code is not an official Juniper product. You can +# obtain a copy of the License at +# +# OSS License: +# +# This program is free software: you can 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 . +# +# Third-Party Code: This code may depend on other components under separate +# copyright notice and license terms. Your use of the source code for those +# components is subject to the terms and conditions of the respective license +# as noted in the Third-Party source code file. + +try: + import time + import os.path + import glob + import io + from sonic_sfp.sfputilbase import SfpUtilBase + from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom + from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom + from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_py_common.logger import Logger + from ctypes import create_string_buffer + +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + +SYSLOG_IDENTIFIER = "sfputil" + +# Global Logger class instance +logger = Logger(SYSLOG_IDENTIFIER) + +qfx5200_qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', + 'Length OM2(m)', 'Length OM1(m)', + 'Length Cable Assembly(m)') + +qfx5200_sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)', + 'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)', + 'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)') + +qfx5200_sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode', + 'ESCONComplianceCodes', 'SONETComplianceCodes', + 'EthernetComplianceCodes', 'FibreChannelLinkLength', + 'FibreChannelTechnology', 'SFP+CableTechnology', + 'FibreChannelTransmissionMedia', 'FibreChannelSpeed') + +qfx5200_qsfp_compliance_code_tup = ('10/40G Ethernet Compliance Code', 'SONET Compliance codes', + 'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes', + 'Fibre Channel link length/Transmitter Technology', + 'Fibre Channel transmission media', 'Fibre Channel Speed') + + +GPIO_SLAVE0_PORT_START = 0 +GPIO_SLAVE0_PORT_END = 15 +GPIO_SLAVE1_PORT_START = 16 +GPIO_SLAVE1_PORT_END = 31 + +GPIO_PORT_START = 0 +GPIO_PORT_END = 31 + +GPIO_PRESENCE_OFFSET = 16 +GPIO_LPMODE_OFFSET = 48 +GPIO_RESET_OFFSET = 0 + +gpio_sfp_presence = {} +gpio_sfp_lpmode = {} +gpio_sfp_reset = {} + +SFP_I2C_OFFSET = 14 + + +# definitions of the offset and width for values in XCVR info eeprom +XCVR_INTFACE_BULK_OFFSET = 0 +XCVR_INTFACE_BULK_WIDTH_QSFP = 20 +XCVR_INTFACE_BULK_WIDTH_SFP = 21 +XCVR_TYPE_WIDTH = 1 +XCVR_VENDOR_NAME_OFFSET = 20 +XCVR_VENDOR_NAME_WIDTH = 16 +XCVR_VENDOR_OUI_OFFSET = 37 +XCVR_VENDOR_OUI_WIDTH = 3 +XCVR_VENDOR_PN_OFFSET = 40 +XCVR_VENDOR_PN_WIDTH = 16 +XCVR_HW_REV_OFFSET = 56 +XCVR_HW_REV_WIDTH_OSFP = 2 +XCVR_HW_REV_WIDTH_QSFP = 2 +XCVR_HW_REV_WIDTH_SFP = 4 +XCVR_VENDOR_SN_OFFSET = 68 +XCVR_VENDOR_SN_WIDTH = 16 +XCVR_VENDOR_DATE_OFFSET = 84 +XCVR_VENDOR_DATE_WIDTH = 8 +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 1 + + +# definitions of the offset for values in OSFP info eeprom +OSFP_TYPE_OFFSET = 0 +OSFP_VENDOR_NAME_OFFSET = 129 +OSFP_VENDOR_PN_OFFSET = 148 +OSFP_HW_REV_OFFSET = 164 +OSFP_VENDOR_SN_OFFSET = 166 + +# definitions of the offset and width for values in DOM info eeprom +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 + + +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VOLT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_CHANNL_MON_OFFSET = 100 +SFP_CHANNL_MON_WIDTH = 6 + + +def gpio_create_file(gpio_pin): + gpio_export_path = "/sys/class/gpio/export" + gpio_pin_path = "/sys/class/gpio/gpio" + str(gpio_pin) + if not os.path.exists(gpio_pin_path): + try: + gpio_export_file = open(gpio_export_path, 'w') + gpio_export_file.write(str(gpio_pin)) + gpio_export_file.close() + except IOError as e: + print("Error: unable to open export file: %s" % str(e)) + return False + + return True + + +def gpio_sfp_port_init(gpio_base, port): + presence_pin = gpio_base + GPIO_PRESENCE_OFFSET + (port % 16) + if gpio_create_file(presence_pin): + gpio_sfp_presence[port] = presence_pin + reset_pin = gpio_base + GPIO_RESET_OFFSET + (port % 16) + if gpio_create_file(reset_pin): + gpio_sfp_reset[port] = reset_pin + lpmode_pin = gpio_base + GPIO_LPMODE_OFFSET + (port % 16) + if gpio_create_file(lpmode_pin): + gpio_sfp_lpmode[port] = lpmode_pin + + +def gpio_sfp_slave_init(gpio_base_path, gpio_port_start, gpio_port_end): + flist = glob.glob(gpio_base_path) + if len(flist) == 1: + try: + fp = open(flist[0]+"/base") + gpio_base = int(fp.readline().rstrip()) + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return + + for port in range(gpio_port_start, gpio_port_end + 1): + gpio_sfp_port_init(gpio_base, port) + + +def gpio_sfp_base_init(): + gpio_sfp_slave_init("/sys/bus/platform/drivers/gpioslave-tmc/gpioslave-tmc.21/gpio/gpio*", + GPIO_SLAVE0_PORT_START, GPIO_SLAVE0_PORT_END) + gpio_sfp_slave_init("/sys/bus/platform/drivers/gpioslave-tmc/gpioslave-tmc.22/gpio/gpio*", + GPIO_SLAVE1_PORT_START, GPIO_SLAVE1_PORT_END) + + +def gpio_sfp_read(gpio_pin): + gpio_pin_path = "/sys/class/gpio/gpio" + str(gpio_pin) + value = 0 + + try: + reg_file = open(gpio_pin_path + "/value") + value = int(reg_file.readline().rstrip()) + except IOError as e: + print("error: unable to open file: %s" % str(e)) + + return value + + +def gpio_sfp_write(gpio_pin, value): + success = False + gpio_pin_path = "/sys/class/gpio/gpio" + str(gpio_pin) + + try: + gpio_file = open(gpio_pin_path + "/value", 'w') + gpio_file.write(str(value)) + success = True + except IOError as e: + print("error: unable to open file: %s" % str(e)) + + return success + + +def gpio_sfp_presence_get(port): + if port not in list(gpio_sfp_presence.keys()): + print("Port:" + str(port) + " not in sfp dict") + return 0 + + gpio_pin = gpio_sfp_presence[port] + return gpio_sfp_read(gpio_pin) + + +def gpio_sfp_lpmode_get(port): + if port not in list(gpio_sfp_lpmode.keys()): + return 0 + + gpio_pin = gpio_sfp_lpmode[port] + return gpio_sfp_read(gpio_pin) + + +def gpio_sfp_lpmode_set(port, value): + if port not in list(gpio_sfp_lpmode.keys()): + return False + + gpio_pin = gpio_sfp_lpmode[port] + return gpio_sfp_write(gpio_pin, value) + + +def gpio_sfp_reset_set(port, value): + if port not in list(gpio_sfp_reset.keys()): + return False + + gpio_pin = gpio_sfp_reset[port] + return gpio_sfp_write(gpio_pin, value) + + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + PORT_START = 0 + PORT_END = 31 + PORTS_IN_BLOCK = 32 + QSFP_PORT_START = 0 + QSFP_PORT_END = 31 + + cmd = '/var/run/sfppresence' + + _port_to_eeprom_mapping = {} + port_to_i2cbus_mapping = { + 0: 14, + 1: 15, + 2: 16, + 3: 17, + 4: 18, + 5: 19, + 6: 20, + 7: 21, + 8: 22, + 9: 23, + 10: 24, + 11: 25, + 12: 26, + 13: 27, + 14: 28, + 15: 29, + 16: 30, + 17: 31, + 18: 32, + 19: 33, + 20: 34, + 21: 35, + 22: 36, + 23: 37, + 24: 38, + 25: 39, + 26: 40, + 27: 41, + 28: 42, + 29: 43, + 30: 44, + 31: 45 + } + + port_ctle_settings = { + 0: 119, # 0x77 + 1: 102, # 0x66 + 2: 102, # 0x66 + 3: 102, # 0x66 + 4: 102, # 0x66 + 5: 85, # 0x55 + 6: 102, # 0x66 + 7: 85, # 0x55 + 8: 85, # 0x55 + 9: 85, # 0x55 + 10: 119, # 0x77 + 11: 119, # 0x77 + 12: 102, # 0x66 + 13: 85, # 0x55 + 14: 68, # 0x44 + 15: 51, # 0x33 + 16: 68, # 0x44 + 17: 85, # 0x55 + 18: 102, # 0x66 + 19: 102, # 0x66 + 20: 119, # 0X77 + 21: 102, # 0x66 + 22: 85, # 0X55 + 23: 85, # 0X55 + 24: 85, # 0x55 + 25: 85, # 0x55 + 26: 102, # 0x66 + 27: 85, # 0x55 + 28: 102, # 0x66 + 29: 102, # 0x66 + 30: 119, # 0x77 + 31: 119 # 0x77 + } + + optics_list_100g = { + "AFBR-89CDDZ-JU1", + "AFBR-89CDDZ-JU2", + "FTLC9551REPM-J1", + "FCBN425QE1C30-J1", + "FCBN425QE1C10-J1", + "FTLC9551REPM-J3", + "LUX42604CO", + "LUX42604BO", + "EOLQ-161HG-10-LJ1", + "FTLC1151RDPL-J1", + "TR-FC13R-NJC", + "TR-FC13L-NJC", + "TR-FC13R-NJ3", + "SPQ-CE-LR-CDFB-J2", + "1K1QAC", + "SPQCELRCDFAJ2" + } + + optics_list_40g = { + "FTL4C1QE1C-J1" + } + + def clear_bit(self, data, pos): + return (data & (~(1 << pos))) + + def check_bit(self, data, pos): + return (data & (1 << pos)) + + def set_bit(self, data, pos): + return (data | (1 << pos)) + + def is_100g_optics(self, part_num): + ret = part_num in self.optics_list_100g + return ret + + def is_40g_optics(self, part_num): + ret = part_num in self.optics_list_40g + return ret + + def is_optics(self, part_num): + if self.is_100g_optics(part_num): + return True + elif self.is_40g_optics(part_num): + return True + else: + return False + + def process_TxCTLE(self, eeprom, port_num, part_num): + if self.is_100g_optics(part_num): + logger.log_debug(" QFX5200: TxCTLE port {} and SFP PN NUM {} ".format(port_num, part_num)) + # Accessing page 3 of optics + regval = 3 + buffer = create_string_buffer(1) + buffer[0] = chr(regval) + eeprom.seek(127) + eeprom.write(buffer[0]) + + regval = self.port_ctle_settings[port_num] + logger.log_debug("QFX5200: TxCTLE port {}, SFP PN NUM {}, regval {} ".format(port_num, part_num, regval)) + + eeprom.seek(234) + buffer[0] = chr(regval) + eeprom.write(buffer[0]) + eeprom.seek(235) + eeprom.write(buffer[0]) + # Moving back the optics page to 0 + regval = 0x0 + buffer[0] = chr(regval) + eeprom.seek(127) + eeprom.write(buffer[0]) + else: + pass + + def is_highpower_optics(self, data): + return (self.check_bit(data, 0) | self.check_bit(data, 1)) + + def is_cdr_present(self, data): + return (self.check_bit(data, 2) | self.check_bit(data, 3)) + + @property + def port_start(self): + return self.PORT_START + + @property + def port_end(self): + return self.PORT_END + + @property + def qsfp_port_start(self): + return self.QSFP_PORT_START + + @property + def qsfp_port_end(self): + return self.QSFP_PORT_END + + @property + def qsfp_ports(self): + return list(range(0, self.PORTS_IN_BLOCK + 1)) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + def __init__(self): + gpio_sfp_base_init() + eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" + for x in range(0, self.port_end + 1): + self.port_to_eeprom_mapping[x] = eeprom_path.format(self.port_to_i2cbus_mapping[x]) + + logger.log_debug("QFX5200: SfpUtil __init__") + if os.path.isfile(self.cmd): + logger.log_debug("QFX5200: SfpUtil removing sfppresence file") + os.remove(self.cmd) + + SfpUtilBase.__init__(self) + + def get_presence(self, port_num): + reg_value = gpio_sfp_presence_get(port_num) + if reg_value == 1: + return True + + return False + + def get_low_power_mode(self, port_num): + reg_value = gpio_sfp_lpmode_get(port_num) + if reg_value == 0: + return True + + return False + + def set_low_power_mode(self, port_num, lpmode): + + if lpmode == False: + lpmode = 1 + else: + lpmode = 0 + + status = gpio_sfp_lpmode_set(port_num, lpmode) + return status + + def reset(self, port_num): + reset_val = 0 + status = gpio_sfp_reset_set(port_num, reset_val) + return status + + # Writing to a file from a list + def write_to_file(self, file_name, from_list): + try: + fp1 = open(file_name, 'w') + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + for i in from_list: + fp1.write(i) + fp1.write('\n') + + fp1.close() + return True + + # Reading from a file to a list + + def read_from_file(self, file_name): + try: + fp = open(file_name, 'r') + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + to_list = fp.readlines() + to_list = [x.rstrip() for x in to_list] + fp.close() + return to_list + + def sfp_detect(self): + port = 0 + ret_dict = {} + defl_dict = {} + current_sfp_values = [0] * 32 + previous_sfp_values = [0] * 32 + + logger.log_debug("QFX5200: sfp_detect Start") + if not os.path.isfile(self.cmd): + logger.log_debug("QFX5200: sfppresence file not created") + else: + if (self.read_from_file(self.cmd) == False): + logger.log_debug("QFX5200: sfp_detect not able to open sfppresence file") + return False, defl_dict + else: + previous_sfp_values = self.read_from_file(self.cmd) + logger.log_debug("QFX5200: sfp_detect sfppresence file present, previous_sfp_values populated") + + # Read the current values from sysfs + for port in range(GPIO_PORT_START, GPIO_PORT_END + 1): + sfp_present = gpio_sfp_presence_get(port) + current_sfp_values[port] = str(sfp_present) + ret_dict.update({port: current_sfp_values[port]}) + + prev_value = str(previous_sfp_values[port]) + + current_value = current_sfp_values[port] + if (prev_value != current_value): + ret_dict.update({port: current_sfp_values[port]}) + value = str(current_sfp_values[port]) + if (value): + offset = 128 + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + return None + + file_path = self._get_port_eeprom_path(port, self.IDENTITY_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + print("Error, file not exist %s" % file_path) + return None + + try: + sysfsfile_eeprom = open(file_path, mode="rb", buffering=0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfp_vendor_pn_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, (offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + if sfp_vendor_pn_raw is not None: + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0) + else: + return None + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + sfp_pn_num = str(sfp_vendor_pn_data['data']['Vendor PN']['value']) + if self.is_optics(sfp_pn_num): + logger.log_debug( + "QFX5200: Port {} is connected with Optics with Part Number {}".format(port, sfp_pn_num)) + eeprom1 = open(self._port_to_eeprom_mapping[port], "r+b") + self.process_TxCTLE(eeprom1, port, sfp_pn_num) + eeprom1.close + # End of if(value) + # End of current_sfp_values != previous_sfp_vlalues + # End of for loop + + if(self.write_to_file(self.cmd, current_sfp_values) == True): + logger.log_debug("QFX5200: sfp_detect, current sfp values written successfully to sfppresence file") + logger.log_debug("QFX5200: sfp_detect ret_dict is {}".format(ret_dict)) + return True, ret_dict + else: + logger.log_debug("QFX5200: sfp_detect, current sfp values not written to sfppresence file") + logger.log_debug("QFX5200: sfp_detect ret_dict is {}".format(def1_dict)) + return False, defl_dict + + # Read out SFP type, vendor name, PN, REV, SN from eeprom. + def get_transceiver_info_dict(self, port_num): + transceiver_info_dict = {} + compliance_code_dict = {} + logger.log_debug("QFX5200: get_transceiver_info_dict Start") + # ToDo: OSFP tranceiver info parsing not fully supported. + # in inf8628.py lack of some memory map definition + # will be implemented when the inf8628 memory map ready + if port_num in self.osfp_ports: + offset = 0 + vendor_rev_width = XCVR_HW_REV_WIDTH_OSFP + + sfpi_obj = inf8628InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + + file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + print("Error, file not exist %s" % file_path) + return None + + try: + sysfsfile_eeprom = open(file_path, mode="rb", buffering=0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfp_type_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, (offset + OSFP_TYPE_OFFSET), XCVR_TYPE_WIDTH) + if sfp_type_raw is not None: + sfp_type_data = sfpi_obj.parse_sfp_type(sfp_type_raw, 0) + else: + return None + + sfp_vendor_name_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, (offset + OSFP_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) + if sfp_vendor_name_raw is not None: + sfp_vendor_name_data = sfpi_obj.parse_vendor_name(sfp_vendor_name_raw, 0) + else: + return None + + sfp_vendor_pn_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, (offset + OSFP_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + if sfp_vendor_pn_raw is not None: + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0) + else: + return None + + sfp_vendor_rev_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, (offset + OSFP_HW_REV_OFFSET), vendor_rev_width) + if sfp_vendor_rev_raw is not None: + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_vendor_rev_raw, 0) + else: + return None + + sfp_vendor_sn_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, (offset + OSFP_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + if sfp_vendor_sn_raw is not None: + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_vendor_sn_raw, 0) + else: + return None + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + transceiver_info_dict['type'] = sfp_type_data['data']['type']['value'] + transceiver_info_dict['type_abbrv_name'] = sfp_type_data['data']['type_abbrv_name']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + # Below part is added to avoid fail the xcvrd, shall be implemented later + transceiver_info_dict['vendor_oui'] = 'N/A' + transceiver_info_dict['vendor_date'] = 'N/A' + transceiver_info_dict['connector'] = 'N/A' + transceiver_info_dict['encoding'] = 'N/A' + transceiver_info_dict['ext_identifier'] = 'N/A' + transceiver_info_dict['ext_rateselect_compliance'] = 'N/A' + transceiver_info_dict['cable_type'] = 'N/A' + transceiver_info_dict['cable_length'] = 'N/A' + transceiver_info_dict['specification_compliance'] = 'N/A' + transceiver_info_dict['nominal_bit_rate'] = 'N/A' + + else: + if port_num in self.qsfp_ports: + offset = 128 + vendor_rev_width = XCVR_HW_REV_WIDTH_QSFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_QSFP + sfp_type = 'QSFP' + + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + + else: + offset = 0 + vendor_rev_width = XCVR_HW_REV_WIDTH_SFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_SFP + sfp_type = 'SFP' + + sfpi_obj = sff8472InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + + file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + print("Error, file not exist %s" % file_path) + return None + + try: + sysfsfile_eeprom = open(file_path, mode="rb", buffering=0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfp_interface_bulk_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, (offset + XCVR_INTFACE_BULK_OFFSET), interface_info_bulk_width) + if sfp_interface_bulk_raw is not None: + sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(sfp_interface_bulk_raw, 0) + else: + return None + + sfp_vendor_name_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, (offset + XCVR_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) + if sfp_vendor_name_raw is not None: + sfp_vendor_name_data = sfpi_obj.parse_vendor_name(sfp_vendor_name_raw, 0) + else: + return None + + sfp_vendor_pn_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, (offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + if sfp_vendor_pn_raw is not None: + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0) + else: + return None + + sfp_vendor_rev_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, (offset + XCVR_HW_REV_OFFSET), vendor_rev_width) + if sfp_vendor_rev_raw is not None: + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_vendor_rev_raw, 0) + else: + return None + + sfp_vendor_sn_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, (offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + if sfp_vendor_sn_raw is not None: + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_vendor_sn_raw, 0) + else: + return None + + sfp_vendor_oui_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, (offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH) + if sfp_vendor_oui_raw is not None: + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(sfp_vendor_oui_raw, 0) + else: + return None + + sfp_vendor_date_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, (offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH) + if sfp_vendor_date_raw is not None: + sfp_vendor_date_data = sfpi_obj.parse_vendor_date(sfp_vendor_date_raw, 0) + else: + return None + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] + transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] + transceiver_info_dict['vendor_date'] = sfp_vendor_date_data[ + 'data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] + transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] + transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] + if sfp_type == 'QSFP': + for key in qfx5200_qsfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str(sfp_interface_bulk_data['data'][key]['value']) + break + else: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = 'N/A' + + for key in qfx5200_qsfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) + + if 'Nominal Bit Rate(100Mbs)' in sfp_interface_bulk_data['data']: + transceiver_info_dict['nominal_bit_rate'] = str( + sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value']) + else: + transceiver_info_dict['nominal_bit_rate'] = 'N/A' + else: + for key in qfx5200_sfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str(sfp_interface_bulk_data['data'][key]['value']) + else: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = 'N/A' + + for key in qfx5200_sfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) + + if 'NominalSignallingRate(UnitsOf100Mbd)' in sfp_interface_bulk_data['data']: + transceiver_info_dict['nominal_bit_rate'] = str( + sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) + else: + transceiver_info_dict['nominal_bit_rate'] = 'N/A' + + logger.log_debug("QFX5200: get_transceiver_info_dict End") + return transceiver_info_dict + + def get_transceiver_dom_info_dict(self, port_num): + transceiver_dom_info_dict = {} + + logger.log_debug("QFX5200: get_transceiver_dom_info_dict Start") + if port_num in self.osfp_ports: + # Below part is added to avoid fail xcvrd, shall be implemented later + transceiver_dom_info_dict['temperature'] = 'N/A' + transceiver_dom_info_dict['voltage'] = 'N/A' + transceiver_dom_info_dict['rx1power'] = 'N/A' + 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'] = 'N/A' + 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'] = 'N/A' + transceiver_dom_info_dict['tx2power'] = 'N/A' + transceiver_dom_info_dict['tx3power'] = 'N/A' + transceiver_dom_info_dict['tx4power'] = 'N/A' + + elif 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 = 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 None + + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + return None + + # 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_dom_capability(qsfp_dom_capability_raw, 0) + else: + return None + + 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 None + + 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 None + + 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 None + + 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 None + + 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'] + + 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 = open(file_path, mode="rb", buffering=0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + 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 None + + 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 None + + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, (offset + SFP_CHANNL_MON_OFFSET), SFP_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 None + + 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' + + logger.log_debug("QFX5200: get_transceiver_dom_info_dict End") + 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') + + logger.log_debug("QFX5200: get_transceiver_dom_threshold_info_dict Start") + 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'] + + logger.log_debug("QFX5200: get_transceiver_dom_threshold_info_dict End") + return transceiver_dom_threshold_info_dict + + def get_transceiver_change_event(self, timeout=2000): + time.sleep(3) + return self.sfp_detect() diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/pmon_daemon_control.json b/device/juniper/x86_64-juniper_qfx5200-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..1863ee2e5190 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_thermalctld": true +} diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/sai.profile b/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/sai.profile index dca8c2f68c04..768a7fa47ad4 100644 --- a/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/sai.profile +++ b/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-qfx5210-64x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/th2-qfx5210-64x100G.config.bcm b/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/th2-qfx5210-64x100G.config.bcm index bc421a4e5152..4d6e2f988c65 100644 --- a/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/th2-qfx5210-64x100G.config.bcm +++ b/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/th2-qfx5210-64x100G.config.bcm @@ -14,7 +14,7 @@ pbmp_oversubscribe=0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff # platform specific setting arl_clean_timeout_usec=15000000 asf_mem_profile=2 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_flags=1 bcm_stat_jumbo=9236 cdma_timeout_usec=15000000 diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/led_proc_init.soc b/device/juniper/x86_64-juniper_qfx5210-r0/led_proc_init.soc old mode 100755 new mode 100644 diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/media_settings.json b/device/juniper/x86_64-juniper_qfx5210-r0/media_settings.json index 22788f3a6f23..4a57e4b79e3a 100644 --- a/device/juniper/x86_64-juniper_qfx5210-r0/media_settings.json +++ b/device/juniper/x86_64-juniper_qfx5210-r0/media_settings.json @@ -241,6 +241,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "AVAGO-AFBR-79EQDZ-JU1": { "preemphasis": { "lane0":"0xd3a02", @@ -341,6 +369,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1c4503", @@ -651,6 +707,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1c4503", @@ -961,6 +1045,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1c4503", @@ -1271,6 +1383,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1b4603", @@ -1567,6 +1707,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { "preemphasis": { "lane0":"0x1c4503", @@ -1891,6 +2059,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x174a03", @@ -2201,6 +2397,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x194803", @@ -2511,6 +2735,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1c4503", @@ -2821,6 +3073,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1c4503", @@ -3131,6 +3411,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1a4703", @@ -3441,6 +3749,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1b4603", @@ -3751,6 +4087,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x154c03", @@ -4061,6 +4425,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x154c03", @@ -4371,6 +4763,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x154c03", @@ -4681,6 +5101,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x154c03", @@ -4991,6 +5439,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x154901", @@ -5301,6 +5777,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x154900", @@ -5569,10 +6073,40 @@ }, "JUNIPER-INNO-TR-IQ13L-NJ5": { "preemphasis": { - "lane0":"0xa3002", - "lane1":"0xa3002", - "lane2":"0xa3002", - "lane3":"0xa3002" + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "18": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" }, "idriver": { "lane0":"0x8", @@ -5580,15 +6114,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "18": { - "Default": { + }, + "JUNIPER-LUXTERA-LUX42604BO": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" }, "idriver": { "lane0":"0x8", @@ -5597,7 +6129,7 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-LUXTERA-LUX42604CO": { "preemphasis": { "lane0":"0x154900", "lane1":"0x124900", @@ -5921,6 +6453,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x154903", @@ -6231,6 +6791,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x194803", @@ -6541,6 +7129,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x194803", @@ -6851,6 +7467,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1c4503", @@ -7161,6 +7805,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1e4303", @@ -7471,6 +8143,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x154906", @@ -7781,6 +8481,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x174902", @@ -8091,6 +8819,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1a4703", @@ -8370,15 +9126,43 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "27": { - "Default": { + } + }, + "27": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604BO": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" }, "idriver": { "lane0":"0x8", @@ -8387,7 +9171,7 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-LUXTERA-LUX42604CO": { "preemphasis": { "lane0":"0x1a4703", "lane1":"0x1a4703", @@ -8711,6 +9495,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1a4505", @@ -9021,6 +9833,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1b4603", @@ -9331,6 +10171,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1a4604", @@ -9641,6 +10509,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1b4504", @@ -9951,6 +10847,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1c4503", @@ -10261,6 +11185,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1c4503", @@ -10571,6 +11523,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1a4703", @@ -10881,6 +11861,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1c4503", @@ -11149,10 +12157,40 @@ }, "JUNIPER-INNO-TR-IQ13L-NJ5": { "preemphasis": { - "lane0":"0xe3804", - "lane1":"0xe3803", - "lane2":"0xe3804", - "lane3":"0xe3804" + "lane0":"0xe3804", + "lane1":"0xe3803", + "lane2":"0xe3804", + "lane3":"0xe3804" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "36": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" }, "idriver": { "lane0":"0x8", @@ -11160,15 +12198,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "36": { - "Default": { + }, + "JUNIPER-LUXTERA-LUX42604BO": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" }, "idriver": { "lane0":"0x8", @@ -11177,7 +12213,7 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-LUXTERA-LUX42604CO": { "preemphasis": { "lane0":"0x1b4603", "lane1":"0x1b4603", @@ -11501,6 +12537,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x194803", @@ -11811,6 +12875,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x164903", @@ -12121,6 +13213,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x164901", @@ -12431,6 +13551,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1c4503", @@ -12741,6 +13889,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1b4603", @@ -13051,6 +14227,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1a4703", @@ -13361,6 +14565,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1b4603", @@ -13671,6 +14903,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x184902", @@ -13950,15 +15210,43 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "45": { - "Default": { + } + }, + "45": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604BO": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" }, "idriver": { "lane0":"0x8", @@ -13967,7 +15255,7 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-LUXTERA-LUX42604CO": { "preemphasis": { "lane0":"0x154900", "lane1":"0x154900", @@ -14291,6 +15579,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x174900", @@ -14601,6 +15917,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x154903", @@ -14911,6 +16255,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x184902", @@ -15221,6 +16593,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x174901", @@ -15531,6 +16931,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x184901", @@ -15841,6 +17269,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x154903", @@ -16151,6 +17607,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x194803", @@ -16461,6 +17945,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x194803", @@ -16729,10 +18241,40 @@ }, "JUNIPER-INNO-TR-IQ13L-NJ5": { "preemphasis": { - "lane0":"0xa3403", - "lane1":"0xa3403", - "lane2":"0xa3403", - "lane3":"0xa3403" + "lane0":"0xa3403", + "lane1":"0xa3403", + "lane2":"0xa3403", + "lane3":"0xa3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "54": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" }, "idriver": { "lane0":"0x8", @@ -16740,15 +18282,13 @@ "lane2":"0x8", "lane3":"0x8" } - } - }, - "54": { - "Default": { + }, + "JUNIPER-LUXTERA-LUX42604BO": { "preemphasis": { - "lane0":"0x14410a", - "lane1":"0x14410a", - "lane2":"0x14410a", - "lane3":"0x14410a" + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" }, "idriver": { "lane0":"0x8", @@ -16757,7 +18297,7 @@ "lane3":"0x8" } }, - "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "JUNIPER-LUXTERA-LUX42604CO": { "preemphasis": { "lane0":"0x1c4503", "lane1":"0x1e4204", @@ -17081,6 +18621,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1a4703", @@ -17391,6 +18959,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x184903", @@ -17701,6 +19297,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x194803", @@ -18011,6 +19635,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604C0": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1a4703", @@ -18321,6 +19973,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1a4703", @@ -18631,6 +20311,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1a4703", @@ -18941,6 +20649,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1b4603", @@ -19251,6 +20987,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1c4404", @@ -19562,6 +21326,34 @@ "lane3":"0x8" } }, + "JUNIPER-LUXTERA-LUX42604BO": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-LUXTERA-LUX42604CO": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, "JUNIPER-1F3-1F3QAA": { "preemphasis": { "lane0":"0x1b4504", diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/plugins/eeprom.py b/device/juniper/x86_64-juniper_qfx5210-r0/plugins/eeprom.py index a5453dc4f0a3..4f087afc6eb0 100644 --- a/device/juniper/x86_64-juniper_qfx5210-r0/plugins/eeprom.py +++ b/device/juniper/x86_64-juniper_qfx5210-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -14,18 +11,19 @@ import syslog from struct import * from array import * - -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") SYSLOG_IDENTIFIER = "eeprom.py" EEPROM_PATH = "/sys/bus/i2c/devices/0-0056/eeprom" + def log_error(msg): syslog.openlog(SYSLOG_IDENTIFIER) syslog.syslog(syslog.LOG_ERR, msg) syslog.closelog() + class board(eeprom_tlvinfo.TlvInfoDecoder): _TLV_INFO_MAX_LEN = 256 @@ -37,4 +35,3 @@ def __init__(self, name, path, cpld_root, ro): self.eeprom_path = EEPROM_PATH super(board, self).__init__(self.eeprom_path, 0, '', True) - diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/plugins/psuutil.py b/device/juniper/x86_64-juniper_qfx5210-r0/plugins/psuutil.py old mode 100755 new mode 100644 index 707c7c897c82..b05cf3e477ac --- a/device/juniper/x86_64-juniper_qfx5210-r0/plugins/psuutil.py +++ b/device/juniper/x86_64-juniper_qfx5210-r0/plugins/psuutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Accton # @@ -13,7 +11,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/plugins/qfx5210_eeprom_data.py b/device/juniper/x86_64-juniper_qfx5210-r0/plugins/qfx5210_eeprom_data.py new file mode 100644 index 000000000000..b0aef43ba273 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5210-r0/plugins/qfx5210_eeprom_data.py @@ -0,0 +1,333 @@ +#!/usr/bin/env python3 +# +# Name: juniper_qfx5210_eepromconv.py version: 1.0 +# +# Description: This file contains the code to store the contents of Board EEPROM in file +# +# Copyright (c) 2020, Juniper Networks, Inc. +# All rights reserved. +# +# Notice and Disclaimer: This code is licensed to you under the GNU General +# Public License as published by the Free Software Foundation, version 3 or +# any later version. This code is not an official Juniper product. You can +# obtain a copy of the License at +# +# OSS License: +# +# This program is free software: you can 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 . +# +# Third-Party Code: This code may depend on other components under separate +# copyright notice and license terms. Your use of the source code for those +# components is subject to the terms and conditions of the respective license +# as noted in the Third-Party source code file. + +import os +import binascii +from sonic_eeprom import eeprom_tlvinfo + + +def main(): + eeprom_qfx5210 = Eeprom() + + FANTYPE_PATH = '/sys/bus/i2c/devices/17-0068/fan1_direction' + isPlatformAFO = False + try: + fan_type_file = open(FANTYPE_PATH) + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + fan_type = -1 + else: + fan_type = fan_type_file.read() + fan_type_file.close() + + if (int(fan_type) == -1 or int(fan_type) == 0): + if (int(fan_type) == -1): + print("unable to open sys file for fan handling, defaulting it to AFO") + + isPlatformAFO = True + else: + isPlatformAFO = False + + # creating the "/var/run/eeprom" file and storing values of CPU board EEPROM in this file. + eeprom_file = open("/var/run/eeprom", "a+") + eeprom_file.write("\n") + if isPlatformAFO == True: + eeprom_file.write("Fan Type=AFO\r\n") + else: + eeprom_file.write("Fan Type=AFI\r\n") + eeprom_file.write("\n") + + # Write the contents of CPU Board EEPROM to file + eeprom_file.write("CPU Board EEPROM (0x56)\r\n") + eeprom_file.write("===============================\r\n") + eeprom_file.write("Product Name=%s\r\n" % eeprom_qfx5210.modelstr()) + eeprom_file.write("Part Number=%s\r\n" % eeprom_qfx5210.part_number_str()) + eeprom_file.write("Serial Number=%s\r\n" % eeprom_qfx5210.serial_number_str()) + eeprom_file.write("MAC Address=%s\r\n" % eeprom_qfx5210.base_mac_address()) + eeprom_file.write("Manufacture Date=%s\r\n" % eeprom_qfx5210.manuDate_str()) + eeprom_file.write("Platform Name=%s\r\n" % eeprom_qfx5210.platform_str()) + eeprom_file.write("Number of MAC Addresses=%s\r\n" % eeprom_qfx5210.MACsize_str()) + eeprom_file.write("Vendor Name=%s\r\n" % eeprom_qfx5210.vendor_name_str()) + eeprom_file.write("Manufacture Name=%s\r\n" % eeprom_qfx5210.manufacture_name_str()) + + CPUeepromFileCmd = 'cat /sys/devices/pci0000:00/0000:00:1f.3/i2c-0/0-0056/eeprom > /etc/init.d/eeprom_qfx5210_ascii' + # Write the contents of CPU EEPROM to file + try: + os.system(CPUeepromFileCmd) + except OSError: + print('Error: Execution of "%s" failed', CPUeepromFileCmd) + return False + + eeprom_ascii = '/etc/init.d/eeprom_qfx5210_ascii' + # Read file contents in Hex format + with open(eeprom_ascii, 'rb') as Hexformat: + content = Hexformat.read() + Hexformatoutput = binascii.hexlify(content) + + eeprom_hex = '/etc/init.d/eeprom_qfx5210_hex' + with open(eeprom_hex, 'wb+') as Hexfile: + Hexfile.write(Hexformatoutput) + + # Write contents of CPU EEPROM to new file in hexa format + with open(eeprom_hex, 'rb') as eeprom_hexfile: + eeprom_hexfile.seek(350, 0) + vendorext_read = eeprom_hexfile.read(124) + vendorext = "" + vendorext += "0x" + vendorext_read[0:2] + for i in range(2, 124, 2): + vendorext += " 0x" + vendorext_read[i:i+2] + eeprom_file.write("Vendor Extension=%s\r\n" % str(vendorext)) + + eeprom_hexfile.seek(350, 0) + IANA_read = eeprom_hexfile.read(8) + IANAName = binascii.unhexlify(IANA_read) + eeprom_file.write("IANA=%s\r\n" % str(IANAName)) + + eeprom_hexfile.seek(358, 0) + ASMpartrev_read = eeprom_hexfile.read(4) + ASMpartrev = binascii.unhexlify(ASMpartrev_read) + eeprom_file.write("Assembly Part Number Rev=%s\r\n" % str(ASMpartrev)) + + eeprom_hexfile.seek(374, 0) + ASMpartnum_read = eeprom_hexfile.read(20) + ASMpartnum_read = binascii.unhexlify(ASMpartnum_read) + eeprom_file.write("Assembly Part Number=%s\r\n" % str(ASMpartnum_read)) + + eeprom_hexfile.seek(402, 0) + ASMID_read = eeprom_hexfile.read(4) + ASMID_read_upper = ASMID_read.upper() + eeprom_file.write("Assembly ID=0x%s\r\n" % str(ASMID_read_upper)) + + ASMHWMajRev_position = eeprom_hexfile.seek(410, 0) + ASMHWMajRev_read = eeprom_hexfile.read(2) + eeprom_file.write("Assembly Major Revision=0x%s\r\n" % str(ASMHWMajRev_read)) + + eeprom_hexfile.seek(416, 0) + ASMHWMinRev_read = eeprom_hexfile.read(2) + eeprom_file.write("Assembly Minor Revision=0x%s\r\n" % str(ASMHWMinRev_read)) + + eeprom_hexfile.seek(422, 0) + Deviation_read = eeprom_hexfile.read(28) + Deviation_read_upper = Deviation_read.upper() + eeprom_file.write("Deviation=0x%s\r\n" % str(Deviation_read_upper)) + + eeprom_hexfile.seek(450, 0) + CLEI_read = eeprom_hexfile.read(20) + CLEI_name = binascii.unhexlify(CLEI_read) + eeprom_file.write("CLEI code=%s\r\n" % str(CLEI_name)) + + eeprom_dict = eeprom_qfx5210.system_eeprom_info() + key = '0x29' + if key in list(eeprom_dict.keys()): + onie_version_str = eeprom_dict.get('0x29', None) + else: + onie_version_str = "N/A" + eeprom_file.write("ONIE Version=%s\r\n" % onie_version_str) + + crc_str = eeprom_dict.get('0xFE', None) + eeprom_file.write("CRC=%s\r\n" % crc_str) + eeprom_file.close() + return True + + +class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): + def __init__(self): + self.__eeprom_path = "/sys/class/i2c-adapter/i2c-0/0-0056/eeprom" + super(Eeprom, self).__init__(self.__eeprom_path, 0, '', True) + self.__eeprom_tlv_dict = dict() + try: + self.__eeprom_data = self.read_eeprom() + except: + self.__eeprom_data = "N/A" + raise RuntimeError("Eeprom is not Programmed") + else: + eeprom = self.__eeprom_data + + if not self.is_valid_tlvinfo_header(eeprom): + return + + total_length = (ord(eeprom[9]) << 8) | ord(eeprom[10]) + tlv_index = self._TLV_INFO_HDR_LEN + tlv_end = self._TLV_INFO_HDR_LEN + total_length + + while (tlv_index + 2) < len(eeprom) and tlv_index < tlv_end: + if not self.is_valid_tlv(eeprom[tlv_index:]): + break + + tlv = eeprom[tlv_index:tlv_index + 2 + + ord(eeprom[tlv_index + 1])] + code = "0x%02X" % (ord(tlv[0])) + + if ord(tlv[0]) == self._TLV_CODE_VENDOR_EXT: + value = str((ord(tlv[2]) << 24) | (ord(tlv[3]) << 16) | + (ord(tlv[4]) << 8) | ord(tlv[5])) + value += str(tlv[6:6 + ord(tlv[1])]) + else: + name, value = self.decoder(None, tlv) + + self.__eeprom_tlv_dict[code] = value + if ord(eeprom[tlv_index]) == self._TLV_CODE_CRC_32: + break + + tlv_index += ord(eeprom[tlv_index+1]) + 2 + + def serial_number_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_SERIAL_NUMBER) + if not is_valid: + return "N/A" + return results[2] + + def base_mac_address(self): + (is_valid, t) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_MAC_BASE) + if not is_valid or t[1] != 6: + return super(eeprom_tlvinfo.TlvInfoDecoder, self).switchaddrstr(self.__eeprom_data) + + return ":".join([binascii.b2a_hex(T) for T in t[2]]) + + def modelstr(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_PRODUCT_NAME) + if not is_valid: + return "N/A" + + return results[2] + + def part_number_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_PART_NUMBER) + if not is_valid: + return "N/A" + + return results[2] + + def serial_tag_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_SERVICE_TAG) + if not is_valid: + return "N/A" + + return results[2] + + def revision_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_DEVICE_VERSION) + if not is_valid: + return "N/A" + + return results[2] + + def manuDate_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_MANUF_DATE) + if not is_valid: + return "N/A" + + return results[2] + + def platform_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_PLATFORM_NAME) + if not is_valid: + return "N/A" + + return results[2] + + def MACsize_str(self): + (is_valid, t) = self.get_tlv_field(self.__eeprom_data, self._TLV_CODE_MAC_SIZE) + + if not is_valid: + return "N/A" + + return str((ord(t[2][0]) << 8) | ord(t[2][1])) + + def vendor_name_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_VENDOR_NAME) + if not is_valid: + return "N/A" + + return results[2] + + def manufacture_name_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_MANUF_NAME) + if not is_valid: + return "N/A" + + return results[2] + + def onie_version_str(self): + value = "" + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_ONIE_VERSION) + if not is_valid: + return "N/A" + + for c in results[2:2 + ord(results[1])]: + value += "0x%02X " % (ord(c),) + + return value + + def vendor_ext_str(self): + + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_VENDOR_EXT) + + if not is_valid: + return "N/A" + + vendor_value_formatted = ''.join([" 0x" + "%02X " % ord(x) for x in results[2]]).strip() + vendor_value_hexvalue = ''.join(["%02X" % ord(x) for x in results[2]]).strip() + + return vendor_value_formatted, vendor_value_hexvalue + + def crc_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_CRC_32) + if not is_valid: + return "N/A" + + def system_eeprom_info(self): + """ + Returns a dictionary, where keys are the type code defined in + ONIE EEPROM format and values are their corresponding values + found in the system EEPROM. + """ + return self.__eeprom_tlv_dict + + +if __name__ == "__main__": + main() diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/plugins/sfputil.py b/device/juniper/x86_64-juniper_qfx5210-r0/plugins/sfputil.py index 59b1dfdb5875..673bb05ed107 100644 --- a/device/juniper/x86_64-juniper_qfx5210-r0/plugins/sfputil.py +++ b/device/juniper/x86_64-juniper_qfx5210-r0/plugins/sfputil.py @@ -1,37 +1,36 @@ -#!/usr/bin/env python - try: import time from sonic_sfp.sfputilbase import * import sys import os + import io import string from ctypes import create_string_buffer - # sys.path.append('/usr/local/bin') - # import sfp_detect -except ImportError, e: - raise ImportError (str(e) + "- required module not found") + from sonic_py_common.logger import Logger +except ImportError as e: + raise ImportError(str(e) + "- required module not found") +SYSLOG_IDENTIFIER = "sfputil" +logger = Logger(SYSLOG_IDENTIFIER) qfx5210_qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', - 'Length OM2(m)', 'Length OM1(m)', - 'Length Cable Assembly(m)') - + 'Length OM2(m)', 'Length OM1(m)', + 'Length Cable Assembly(m)') + qfx5210_sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)', - 'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)', - 'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)') + 'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)', + 'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)') qfx5210_sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode', - 'ESCONComplianceCodes', 'SONETComplianceCodes', - 'EthernetComplianceCodes','FibreChannelLinkLength', - 'FibreChannelTechnology', 'SFP+CableTechnology', - 'FibreChannelTransmissionMedia','FibreChannelSpeed') + 'ESCONComplianceCodes', 'SONETComplianceCodes', + 'EthernetComplianceCodes', 'FibreChannelLinkLength', + 'FibreChannelTechnology', 'SFP+CableTechnology', + 'FibreChannelTransmissionMedia', 'FibreChannelSpeed') qfx5210_qsfp_compliance_code_tup = ('10/40G Ethernet Compliance Code', 'SONET Compliance codes', - 'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes', - 'Fibre Channel link length/Transmitter Technology', - 'Fibre Channel transmission media', 'Fibre Channel Speed') - + 'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes', + 'Fibre Channel link length/Transmitter Technology', + 'Fibre Channel transmission media', 'Fibre Channel Speed') class SfpUtil(SfpUtilBase): @@ -40,77 +39,76 @@ class SfpUtil(SfpUtilBase): _port_start = 0 _port_end = 63 ports_in_block = 64 - cmd = '/var/run/sfppresence' + cmd = '/var/run/sfppresence' _port_to_eeprom_mapping = {} port_to_i2c_mapping = { - 60 : 25, - 61 : 26, - 62 : 27, - 63 : 28, - 54 : 29, - 55 : 30, - 52 : 31, - 53 : 32, - 8 : 33, - 9 : 34, - 10 : 35, - 11 : 36, - 0 : 37, - 1 : 38, - 2 : 39, - 3 : 40, - 5 : 41, - 4 : 42, - 7 : 43, - 6 : 44, - 12 : 45, - 13 : 46, - 14 : 47, - 15 : 48, - 16 : 49, - 17 : 50, - 18 : 51, - 19 : 52, - 24 : 53, - 25 : 54, - 26 : 55, - 27 : 56, - 28 : 57, - 29 : 58, - 30 : 59, - 31 : 60, - 20 : 61, - 21 : 62, - 22 : 63, - 23 : 64, - 40 : 65, - 41 : 66, - 42 : 67, - 43 : 68, - 32 : 69, - 33 : 70, - 34 : 71, - 35 : 72, - 44 : 73, - 45 : 74, - 46 : 75, - 47 : 76, - 36 : 77, - 37 : 78, - 38 : 79, - 39 : 80, - 56 : 81, - 57 : 82, - 58 : 83, - 59 : 84, - 48 : 85, - 49 : 86, - 50 : 87, - 51 : 88,} - - # sys.path.append('/usr/local/bin') - _qsfp_ports = range(0, ports_in_block + 1) + 60: 25, + 61: 26, + 62: 27, + 63: 28, + 54: 29, + 55: 30, + 52: 31, + 53: 32, + 8: 33, + 9: 34, + 10: 35, + 11: 36, + 0: 37, + 1: 38, + 2: 39, + 3: 40, + 5: 41, + 4: 42, + 7: 43, + 6: 44, + 12: 45, + 13: 46, + 14: 47, + 15: 48, + 16: 49, + 17: 50, + 18: 51, + 19: 52, + 24: 53, + 25: 54, + 26: 55, + 27: 56, + 28: 57, + 29: 58, + 30: 59, + 31: 60, + 20: 61, + 21: 62, + 22: 63, + 23: 64, + 40: 65, + 41: 66, + 42: 67, + 43: 68, + 32: 69, + 33: 70, + 34: 71, + 35: 72, + 44: 73, + 45: 74, + 46: 75, + 47: 76, + 36: 77, + 37: 78, + 38: 79, + 39: 80, + 56: 81, + 57: 82, + 58: 83, + 59: 84, + 48: 85, + 49: 86, + 50: 87, + 51: 88, } + # sys.path.append('/usr/local/bin') + _qsfp_ports = list(range(0, ports_in_block + 1)) def __init__(self): eeprom_path = '/sys/bus/i2c/devices/{0}-0050/eeprom' @@ -123,21 +121,21 @@ 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/19-0060/module_reset_{0}" + path = "/sys/bus/i2c/devices/19-0060/module_reset_{0}" port_ps = path.format(port_num+1) - + try: reg_file = open(port_ps, 'w') except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False - #HW will clear reset after set. + # HW will clear reset after set. reg_file.seek(0) reg_file.write('1') reg_file.close() return True - + def get_presence(self, port_num): # Check for invalid port_num if port_num < self._port_start or port_num > self._port_end: @@ -149,7 +147,7 @@ def get_presence(self, 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" % str(e)) return False reg_value = reg_file.readline().rstrip() @@ -165,21 +163,21 @@ def port_start(self): @property def port_end(self): return self._port_end - + @property def qsfp_ports(self): - return range(0, self.ports_in_block + 1) + return list(range(0, self.ports_in_block + 1)) - @property + @property def port_to_eeprom_mapping(self): - return self._port_to_eeprom_mapping + return self._port_to_eeprom_mapping # Writing to a file from a list def write_to_file(self, file_name, from_list): try: fp1 = open(file_name, 'w') except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False for i in from_list: @@ -189,20 +187,20 @@ def write_to_file(self, file_name, from_list): fp1.close() return True - # Reading from a file to a list + def read_from_file(self, file_name): try: fp = open(file_name, 'r') except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False - to_list = fp.readlines() - to_list = [x.rstrip() for x in to_list] - fp.close() - return to_list - + to_list = fp.readlines() + to_list = [x.rstrip() for x in to_list] + fp.close() + return to_list + def sfp_detect(self): x = 0 ret_dict = {} @@ -220,20 +218,20 @@ def sfp_detect(self): else: previous_sfp_values = self.read_from_file(self.cmd) - # Read the current values from sysfs - for x in range(self._port_start , self._port_end + 1): + # Read the current values from sysfs + for x in range(self._port_start, self._port_end + 1): try: new_path = path.format(x + 1) reg_file = open(new_path, 'r') except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False, defl_dict - sfp_present = reg_file.readline().rstrip() + sfp_present = reg_file.readline().rstrip() reg_file.close() current_sfp_values[x] = sfp_present - if (current_sfp_values[x] != previous_sfp_values[x]): - ret_dict.update({x:current_sfp_values[x]}) + if (current_sfp_values[x] != previous_sfp_values[x]): + ret_dict.update({x: current_sfp_values[x]}) if(self.write_to_file(self.cmd, current_sfp_values) == True): return True, ret_dict @@ -260,20 +258,21 @@ def get_low_power_mode(self, port_num): lpmode = ord(eeprom.read(1)) if ((lpmode & 0x3) == 0x3): - return True # Low Power Mode if "Power override" bit is 1 and "Power set" bit is 1 + return True # Low Power Mode if "Power override" bit is 1 and "Power set" bit is 1 else: - return False # High Power Mode if one of the following conditions is matched: - # 1. "Power override" bit is 0 - # 2. "Power override" bit is 1 and "Power set" bit is 0 + # High Power Mode if one of the following conditions is matched: + # 1. "Power override" bit is 0 + # 2. "Power override" bit is 1 and "Power set" bit is 0 + return False except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False finally: if eeprom is not None: eeprom.close() time.sleep(0.01) - def set_low_power_mode(self, port_num, lpmode): + def set_low_power_mode(self, port_num, lpmode): # Check for invalid port_num if port_num < self._port_start or port_num > self._port_end: return False @@ -282,10 +281,10 @@ def set_low_power_mode(self, port_num, lpmode): eeprom = None if not self.get_presence(port_num): - return False # Port is not present, unable to set the eeprom + return False # Port is not present, unable to set the eeprom # Fill in write buffer - regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode + regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode buffer = create_string_buffer(1) buffer[0] = chr(regval) @@ -295,7 +294,7 @@ def set_low_power_mode(self, port_num, lpmode): eeprom.write(buffer[0]) return True except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False finally: if eeprom is not None: @@ -330,31 +329,36 @@ def get_transceiver_info_dict(self, port_num): print("Error: reading sysfs file %s" % file_path) return None - sfp_type_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + OSFP_TYPE_OFFSET), XCVR_TYPE_WIDTH) + sfp_type_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, (offset + OSFP_TYPE_OFFSET), XCVR_TYPE_WIDTH) if sfp_type_raw is not None: sfp_type_data = sfpi_obj.parse_sfp_type(sfp_type_raw, 0) else: return None - sfp_vendor_name_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + OSFP_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) + sfp_vendor_name_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, (offset + OSFP_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) if sfp_vendor_name_raw is not None: sfp_vendor_name_data = sfpi_obj.parse_vendor_name(sfp_vendor_name_raw, 0) else: return None - sfp_vendor_pn_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + OSFP_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + sfp_vendor_pn_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, (offset + OSFP_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) if sfp_vendor_pn_raw is not None: sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0) else: return None - sfp_vendor_rev_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + OSFP_HW_REV_OFFSET), vendor_rev_width) + sfp_vendor_rev_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, (offset + OSFP_HW_REV_OFFSET), vendor_rev_width) if sfp_vendor_rev_raw is not None: sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_vendor_rev_raw, 0) else: return None - sfp_vendor_sn_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + OSFP_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + sfp_vendor_sn_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, (offset + OSFP_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) if sfp_vendor_sn_raw is not None: sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_vendor_sn_raw, 0) else: @@ -368,14 +372,14 @@ def get_transceiver_info_dict(self, port_num): transceiver_info_dict['type'] = sfp_type_data['data']['type']['value'] transceiver_info_dict['type_abbrv_name'] = sfp_type_data['data']['type_abbrv_name']['value'] - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] # Below part is added to avoid fail the xcvrd, shall be implemented later transceiver_info_dict['vendor_oui'] = 'N/A' transceiver_info_dict['vendor_date'] = 'N/A' - transceiver_info_dict['Connector'] = 'N/A' + transceiver_info_dict['connector'] = 'N/A' transceiver_info_dict['encoding'] = 'N/A' transceiver_info_dict['ext_identifier'] = 'N/A' transceiver_info_dict['ext_rateselect_compliance'] = 'N/A' @@ -420,43 +424,50 @@ def get_transceiver_info_dict(self, port_num): print("Error: reading sysfs file %s" % file_path) return None - sfp_interface_bulk_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + XCVR_INTFACE_BULK_OFFSET), interface_info_bulk_width) + sfp_interface_bulk_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, (offset + XCVR_INTFACE_BULK_OFFSET), interface_info_bulk_width) if sfp_interface_bulk_raw is not None: sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(sfp_interface_bulk_raw, 0) else: return None - sfp_vendor_name_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + XCVR_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) + sfp_vendor_name_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, (offset + XCVR_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) if sfp_vendor_name_raw is not None: sfp_vendor_name_data = sfpi_obj.parse_vendor_name(sfp_vendor_name_raw, 0) else: return None - sfp_vendor_pn_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + sfp_vendor_pn_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, (offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) if sfp_vendor_pn_raw is not None: sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0) else: return None - sfp_vendor_rev_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + XCVR_HW_REV_OFFSET), vendor_rev_width) + sfp_vendor_rev_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, (offset + XCVR_HW_REV_OFFSET), vendor_rev_width) if sfp_vendor_rev_raw is not None: sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_vendor_rev_raw, 0) else: return None - sfp_vendor_sn_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + sfp_vendor_sn_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, (offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) if sfp_vendor_sn_raw is not None: sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_vendor_sn_raw, 0) else: return None - sfp_vendor_oui_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH) + sfp_vendor_oui_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, (offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH) if sfp_vendor_oui_raw is not None: sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(sfp_vendor_oui_raw, 0) else: return None - sfp_vendor_date_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH) + sfp_vendor_date_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, (offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH) if sfp_vendor_date_raw is not None: sfp_vendor_date_data = sfpi_obj.parse_vendor_date(sfp_vendor_date_raw, 0) else: @@ -470,13 +481,14 @@ def get_transceiver_info_dict(self, port_num): transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] - transceiver_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] - transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['vendor_date'] = sfp_vendor_date_data[ + 'data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] @@ -494,10 +506,11 @@ def get_transceiver_info_dict(self, port_num): if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) - - if sfp_interface_bulk_data['data'].has_key('Nominal Bit Rate(100Mbs)'): - transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value']) - else: + + if 'Nominal Bit Rate(100Mbs)' in sfp_interface_bulk_data['data']: + transceiver_info_dict['nominal_bit_rate'] = str( + sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value']) + else: transceiver_info_dict['nominal_bit_rate'] = 'N/A' else: for key in qfx5210_sfp_cable_length_tup: @@ -507,18 +520,19 @@ def get_transceiver_info_dict(self, port_num): else: transceiver_info_dict['cable_type'] = key transceiver_info_dict['cable_length'] = 'N/A' - + for key in qfx5210_sfp_compliance_code_tup: if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) - if sfp_interface_bulk_data['data'].has_key('NominalSignallingRate(UnitsOf100Mbd)'): - transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) - else: + if 'NominalSignallingRate(UnitsOf100Mbd)' in sfp_interface_bulk_data['data']: + transceiver_info_dict['nominal_bit_rate'] = str( + sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) + else: transceiver_info_dict['nominal_bit_rate'] = 'N/A' #transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) - + return transceiver_info_dict def get_transceiver_dom_info_dict(self, port_num): @@ -566,25 +580,29 @@ def get_transceiver_dom_info_dict(self, port_num): # 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) + 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) + qspf_dom_capability_data = sfpi_obj.parse_dom_capability(qsfp_dom_capability_raw, 0) else: return None - dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) + 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 None - dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) + 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 None - qsfp_dom_rev_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH) + 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: @@ -599,7 +617,8 @@ def get_transceiver_dom_info_dict(self, port_num): 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) + 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: @@ -610,9 +629,11 @@ def get_transceiver_dom_info_dict(self, port_num): 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) + 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) + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power( + dom_channel_monitor_raw, 0) else: return None @@ -654,19 +675,22 @@ def get_transceiver_dom_info_dict(self, port_num): if sfpd_obj is None: return None - dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH) + 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 None - dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_VOLT_OFFSET), SFP_VOLT_WIDTH) + 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 None - dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, (offset + SFP_CHANNL_MON_OFFSET), SFP_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: @@ -694,3 +718,134 @@ def get_transceiver_dom_info_dict(self, port_num): 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') + + logger.log_debug("QFX5210: get_transceiver_dom_threshold_info_dict Start") + 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'] + + logger.log_debug("QFX5210: get_transceiver_dom_threshold_info_dict End") + return transceiver_dom_threshold_info_dict diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/pmon_daemon_control.json b/device/juniper/x86_64-juniper_qfx5210-r0/pmon_daemon_control.json index 94592fa8cebc..a3ecea34bcc9 100644 --- a/device/juniper/x86_64-juniper_qfx5210-r0/pmon_daemon_control.json +++ b/device/juniper/x86_64-juniper_qfx5210-r0/pmon_daemon_control.json @@ -1,3 +1,4 @@ { + "skip_thermalctld": true, "skip_ledd": true } diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/buffers_defaults_t0.j2 b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..b23ec5259b21 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/buffers_defaults_t0.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11500000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "11500000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"330000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/buffers_defaults_t1.j2 b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..b23ec5259b21 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/buffers_defaults_t1.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11500000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "11500000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"330000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/port_config.ini b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/port_config.ini new file mode 100644 index 000000000000..074c0344c896 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/port_config.ini @@ -0,0 +1,19 @@ +# name lanes speed alias +Ethernet0 0 25000 twenty5GigE0 +Ethernet1 1 25000 twenty5GigE1 +Ethernet2 2 25000 twenty5GigE2 +Ethernet3 3 25000 twenty5GigE3 +Ethernet4 4 25000 twenty5GigE4 +Ethernet5 5 25000 twenty5GigE5 +Ethernet6 6 25000 twenty5GigE6 +Ethernet7 7 25000 twenty5GigE7 +Ethernet8 8 25000 twenty5GigE8 +Ethernet9 9 25000 twenty5GigE9 +Ethernet10 10 25000 twenty5GigE10 +Ethernet11 11 25000 twenty5GigE11 +Ethernet12 12 25000 twenty5GigE12 +Ethernet13 13 25000 twenty5GigE13 +Ethernet14 14 25000 twenty5GigE14 +Ethernet15 15 25000 twenty5GigE15 +Ethernet16 16 10000 tenGigE16 +Ethernet17 17 10000 tenGigE17 diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/profile.ini b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/profile.ini new file mode 100644 index 000000000000..aeaafc4e6e4d --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/profile.ini @@ -0,0 +1,2 @@ +switchMacAddress=00:01:02:03:04:05 +apPortListWithCableLen=000:1 001:1 002:1 003:1 004:1 005:1 006:1 007:1 008:1 009:1 010:1 011:1 012:1 013:1 014:1 015:1 diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/sai.profile b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/sai.profile new file mode 100644 index 000000000000..2c9623c91105 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16X25G/sai.profile @@ -0,0 +1,3 @@ +mode=1 +hwId=FALCON16X25G +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/profile.ini diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/buffers_defaults_t0.j2 b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..b23ec5259b21 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/buffers_defaults_t0.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11500000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "11500000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"330000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/buffers_defaults_t1.j2 b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..b23ec5259b21 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/buffers_defaults_t1.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11500000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "11500000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"330000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/port_config.ini b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/port_config.ini new file mode 100644 index 000000000000..6a9bfda3fb8b --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/port_config.ini @@ -0,0 +1,19 @@ +# name lanes speed alias +Ethernet0 0,1,2,3,4,5,6,7 400000 four00GigE0 +Ethernet8 8,9,10,11,12,13,14,15 400000 four00GigE1 +Ethernet16 16,17,18,19,20,21,22,23 400000 four00GigE2 +Ethernet24 24,25,26,27,28,29,30,31 400000 four00GigE2 +Ethernet32 32,33,34,35,36,37,38,39 400000 four00GigE3 +Ethernet40 40,41,42,43,44,45,46,47 400000 four00GigE4 +Ethernet48 48,49,50,51,52,53,54,55 400000 four00GigE5 +Ethernet56 56,57,58,59,60,61,62,63 400000 four00GigE6 +Ethernet64 64,65,66,67,68,69,70,71 400000 four00GigE7 +Ethernet72 72,73,74,75,76,77,78,79 400000 four00GigE8 +Ethernet80 80,81,82,83,84,85,86,87 400000 four00GigE9 +Ethernet88 88,89,90,91,92,93,94,95 400000 four00GigE10 +Ethernet96 96,97,98,99,100,101,102,103 400000 four00GigE11 +Ethernet104 104,105,106,107,108,109,110,111 400000 four00GigE12 +Ethernet112 112,113,114,115,116,117,118,119 400000 four00GigE13 +Ethernet120 120,121,122,123,124,125,126,127 400000 four00GigE14 +Ethernet128 128 10000 tenGigE128 +Ethernet129 129 10000 tenGigE129 diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/profile.ini b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/profile.ini new file mode 100644 index 000000000000..16847ec03ae2 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/profile.ini @@ -0,0 +1,2 @@ +switchMacAddress=00:01:02:03:04:05 +apPortListWithCableLen=000:1 008:1 016:1 024:1 032:1 040:1 048:1 056:1 064:1 072:1 080:1 088:1 096:1 104:1 112:1 120:1 diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/sai.profile b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/sai.profile new file mode 100644 index 000000000000..6a2438f50180 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON16x400G/sai.profile @@ -0,0 +1,3 @@ +mode=1 +hwId=FALCON16x400G +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/profile.ini diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/buffers_defaults_t0.j2 b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..f9fb5482560d --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/buffers_defaults_t0.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11500000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "11500000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"170000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/buffers_defaults_t1.j2 b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..f9fb5482560d --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/buffers_defaults_t1.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11500000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "11500000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"170000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/port_config.ini b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/port_config.ini new file mode 100644 index 000000000000..d0402fd44317 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/port_config.ini @@ -0,0 +1,35 @@ +# name lanes speed alias +Ethernet0 0 25000 twenty5GigE0 +Ethernet1 1 25000 twenty5GigE1 +Ethernet2 2 25000 twenty5GigE2 +Ethernet3 3 25000 twenty5GigE3 +Ethernet4 4 25000 twenty5GigE4 +Ethernet5 5 25000 twenty5GigE5 +Ethernet6 6 25000 twenty5GigE6 +Ethernet7 7 25000 twenty5GigE7 +Ethernet8 8 25000 twenty5GigE8 +Ethernet9 9 25000 twenty5GigE9 +Ethernet10 10 25000 twenty5GigE10 +Ethernet11 11 25000 twenty5GigE11 +Ethernet12 12 25000 twenty5GigE12 +Ethernet13 13 25000 twenty5GigE13 +Ethernet14 14 25000 twenty5GigE14 +Ethernet15 15 25000 twenty5GigE15 +Ethernet16 16 25000 twenty5GigE16 +Ethernet17 17 25000 twenty5GigE17 +Ethernet18 18 25000 twenty5GigE18 +Ethernet19 19 25000 twenty5GigE19 +Ethernet20 20 25000 twenty5GigE20 +Ethernet21 21 25000 twenty5GigE21 +Ethernet22 22 25000 twenty5GigE22 +Ethernet23 23 25000 twenty5GigE23 +Ethernet24 24 25000 twenty5GigE24 +Ethernet25 25 25000 twenty5GigE25 +Ethernet26 26 25000 twenty5GigE26 +Ethernet27 27 25000 twenty5GigE27 +Ethernet28 28 25000 twenty5GigE28 +Ethernet29 29 25000 twenty5GigE29 +Ethernet30 30 25000 twenty5GigE30 +Ethernet31 31 25000 twenty5GigE31 +Ethernet32 32 10000 tenGigE32 +Ethernet33 33 10000 tenGigE33 diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/profile.ini b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/profile.ini new file mode 100644 index 000000000000..0ffbefa05805 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/profile.ini @@ -0,0 +1,2 @@ +switchMacAddress=00:01:02:03:04:05 +apPortListWithCableLen=000:1 001:1 002:1 003:1 004:1 005:1 006:1 007:1 008:1 009:1 010:1 011:1 012:1 013:1 014:1 015:1 016:1 017:1 018:1 019:1 020:1 021:1 022:1 023:1 024:1 025:1 026:1 027:1 028:1 029:1 030:1 031:1 diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/sai.profile b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/sai.profile new file mode 100644 index 000000000000..fa9983612117 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/FALCON32X25G/sai.profile @@ -0,0 +1,3 @@ +mode=1 +hwId=FALCON32x25G64 +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/profile.ini diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers.json.j2 b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers.json.j2 new file mode 100644 index 000000000000..a9a01d707ebf --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers.json.j2 @@ -0,0 +1 @@ +{%- include 'buffers_config.j2' %} diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_config.j2 b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_config.j2 new file mode 100644 index 000000000000..5431fbe72c1f --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_config.j2 @@ -0,0 +1,165 @@ +{%- macro set_default_topology() %} +{%- if default_topo is defined %} +{{ default_topo }} +{%- else %} +def +{%- endif %} +{%- endmacro -%} + +{# Determine device topology and filename postfix #} +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- if 'torrouter' in switch_role.lower() %} +{%- set filename_postfix = 't0' %} +{%- elif 'leafrouter' in switch_role.lower() %} +{%- set filename_postfix = 't1' %} +{%- else %} +{%- set filename_postfix = set_default_topology() %} +{%- endif %} +{%- else %} +{%- set filename_postfix = set_default_topology() %} +{%- set switch_role = '' %} +{%- endif -%} + +{# Import default values from device HWSKU folder #} +{%- import 'buffers_defaults_%s.j2' % filename_postfix as defs %} + +{%- set default_cable = defs.default_cable -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{%- if defs.ports2cable is defined %} + {%- set ports2cable = defs.ports2cable %} +{%- else %} + {%- set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } + -%} +{%- endif %} + +{%- macro cable_length(port_name) %} + {%- set cable_len = [] %} + {%- for local_port in DEVICE_NEIGHBOR %} + {%- if local_port == port_name %} + {%- if DEVICE_NEIGHBOR_METADATA is defined and 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 %} + {%- if 'torrouter' in switch_role.lower() %} + {%- for local_port in VLAN_MEMBER %} + {%- if local_port[1] == port_name %} + {%- set roles3 = switch_role + '_' + 'server' %} + {%- set roles3 = roles3 | lower %} + {%- if roles3 in ports2cable %} + {%- if cable_len.append(ports2cable[roles3]) %}{% endif %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- endif %} +{%- endmacro %} + +{%- set PORT_ALL = [] %} + +{%- if PORT is not defined %} + {%- if defs.generate_port_lists(PORT_ALL) %} {% endif %} +{%- else %} + {%- for port in PORT %} + {%- if PORT_ALL.append(port) %}{%- endif %} + {%- endfor %} +{%- endif %} + +{%- set PORT_ACTIVE = [] %} +{%- if DEVICE_NEIGHBOR is not defined %} + {%- set PORT_ACTIVE = PORT_ALL %} +{%- else %} + {%- for port in DEVICE_NEIGHBOR.keys() %} + {%- if PORT_ACTIVE.append(port) %}{%- endif %} + {%- endfor %} +{%- endif %} + +{%- set port_names_list_active = [] %} +{%- for port in PORT_ACTIVE %} + {%- if port_names_list_active.append(port) %}{%- endif %} +{%- endfor %} +{%- set port_names_active = port_names_list_active | join(',') %} + +{ + "CABLE_LENGTH": { + "AZURE": { + {% for port in PORT_ALL %} + {%- set cable = cable_length(port) %} + "{{ port }}": "{{ cable }}"{%- if not loop.last %},{% endif %} + + {% endfor %} + } + }, + +{% if defs.generate_buffer_pool_and_profiles is defined %} +{{ defs.generate_buffer_pool_and_profiles() }} +{% endif %} + +{%- if defs.generate_profile_lists is defined %} +{{ defs.generate_profile_lists(port_names_active) }}, +{% endif %} + +{%- if defs.generate_pg_profils is defined %} +{{ defs.generate_pg_profils(port_names_active) }} +{% else %} + "BUFFER_PG": { +{% for port in PORT_ACTIVE %} + "{{ port }}|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, +{% endif %} + +{% if defs.generate_queue_buffers is defined %} +{{ defs.generate_queue_buffers(port_names_active) }} +{% else %} + "BUFFER_QUEUE": { +{% for port in PORT_ACTIVE %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{% endif %} +} diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_defaults_t0.j2 b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..b23ec5259b21 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_defaults_t0.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11500000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "11500000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"330000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_defaults_t1.j2 b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..b23ec5259b21 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_defaults_t1.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11500000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "11500000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"330000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/port_config.ini b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/port_config.ini new file mode 100644 index 000000000000..6a9bfda3fb8b --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/port_config.ini @@ -0,0 +1,19 @@ +# name lanes speed alias +Ethernet0 0,1,2,3,4,5,6,7 400000 four00GigE0 +Ethernet8 8,9,10,11,12,13,14,15 400000 four00GigE1 +Ethernet16 16,17,18,19,20,21,22,23 400000 four00GigE2 +Ethernet24 24,25,26,27,28,29,30,31 400000 four00GigE2 +Ethernet32 32,33,34,35,36,37,38,39 400000 four00GigE3 +Ethernet40 40,41,42,43,44,45,46,47 400000 four00GigE4 +Ethernet48 48,49,50,51,52,53,54,55 400000 four00GigE5 +Ethernet56 56,57,58,59,60,61,62,63 400000 four00GigE6 +Ethernet64 64,65,66,67,68,69,70,71 400000 four00GigE7 +Ethernet72 72,73,74,75,76,77,78,79 400000 four00GigE8 +Ethernet80 80,81,82,83,84,85,86,87 400000 four00GigE9 +Ethernet88 88,89,90,91,92,93,94,95 400000 four00GigE10 +Ethernet96 96,97,98,99,100,101,102,103 400000 four00GigE11 +Ethernet104 104,105,106,107,108,109,110,111 400000 four00GigE12 +Ethernet112 112,113,114,115,116,117,118,119 400000 four00GigE13 +Ethernet120 120,121,122,123,124,125,126,127 400000 four00GigE14 +Ethernet128 128 10000 tenGigE128 +Ethernet129 129 10000 tenGigE129 diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/profile.ini b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/profile.ini new file mode 100644 index 000000000000..16847ec03ae2 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/profile.ini @@ -0,0 +1,2 @@ +switchMacAddress=00:01:02:03:04:05 +apPortListWithCableLen=000:1 008:1 016:1 024:1 032:1 040:1 048:1 056:1 064:1 072:1 080:1 088:1 096:1 104:1 112:1 120:1 diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/qos.json.j2 b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/sai.profile b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/sai.profile new file mode 100644 index 000000000000..6a2438f50180 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/sai.profile @@ -0,0 +1,3 @@ +mode=1 +hwId=FALCON16x400G +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/profile.ini diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/default_sku b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/default_sku new file mode 100644 index 000000000000..7908e555c02c --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/default_sku @@ -0,0 +1 @@ +db98cx8580_16cd t1 diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/plugins/eeprom.py b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/plugins/eeprom.py new file mode 100644 index 000000000000..71f05c5b70f5 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/plugins/eeprom.py @@ -0,0 +1,11 @@ +try: + from sonic_eeprom import eeprom_tlvinfo +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/etc/sonic/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/plugins/sfputil.py b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/plugins/sfputil.py new file mode 100644 index 000000000000..4463e687e695 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/plugins/sfputil.py @@ -0,0 +1,251 @@ +try: + import os + import time + import sys + import re + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +if sys.version_info[0] < 3: + import commands +else: + import subprocess as commands + +smbus_present = 1 + +try: + import smbus +except ImportError as e: + smbus_present = 0 + + +class SfpUtil(SfpUtilBase): + """Platform specific sfputil class""" + _port_start = 1 + _port_end = 132 + ports_in_block = 132 + + _port_to_eeprom_mapping = {} + + _qsfp_ports = list(range(_port_start, ports_in_block + 1)) + + def __init__(self): + os.system("modprobe i2c-dev") + if not os.path.exists("/sys/bus/i2c/devices/0-0050"): + os.system("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-0/new_device") + + eeprom_path = '/sys/bus/i2c/devices/0-0050/eeprom' + # for x in range(self.port _start, self.port_end +1): + x = self.port_start + while(x < self.port_end+1): + self.port_to_eeprom_mapping[x] = eeprom_path + x = x + 1 + 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 + + port_ps = "/sys/bus/i2c/devices/0-0050/sfp_port_reset" + + try: + reg_file = open(port_ps, 'w') + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + # toggle reset + reg_file.seek(0) + reg_file.write('1') + time.sleep(1) + reg_file.seek(0) + reg_file.write('0') + reg_file.close() + return True + + def set_low_power_mode(self, port_nuM, lpmode): + raise NotImplementedError + + def get_low_power_mode(self, port_num): + raise NotImplementedError + + def i2c_get(self, device_addr, offset): + status = 0 + if smbus_present == 0: + x = "i2cget -y 0 " + hex(device_addr) + " " + hex(offset) + cmdstatus, status = commands.getstatusoutput(x) + if cmdstatus != 0: + return cmdstatus + status = int(status, 16) + else: + bus = smbus.SMBus(0) + status = bus.read_byte_data(device_addr, offset) + return status + + def i2c_set(self, device_addr, offset, value): + if smbus_present == 0: + cmd = "i2cset -y 0 " + hex(device_addr) + " " + hex(offset) + " " + hex(value) + os.system(cmd) + else: + bus = smbus.SMBus(0) + bus.write_byte_data(device_addr, offset, value) + + 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 + else: + self.i2c_set(0x70, 0, 0) + self.i2c_set(0x71, 0, 0) + self.i2c_set(0x74, 0, 0) + reg = (port_num)/8 + offset = reg % 8 + if offset >= 4: + offset = offset-4 + elif offset < 4: + offset = offset+4 + bin_offset = 1 << offset + + if port_num >= 0 and port_num <= 63: + device_reg = 0x70 + elif port_num >= 64 and port_num <= 127: + device_reg = 0x71 + elif port_num >= 128 and port_num <= 131: + device_reg = 0x74 + + #print "i2c %d %x %x" % (port_num, device_reg, bin_offset) + self.i2c_set(device_reg, 0, bin_offset) + path = "/sys/bus/i2c/devices/0-0050/eeprom" + try: + reg_file = open(path) + reg_file.seek(0o1) + reg_file.read(0o2) + except IOError as e: + return False + + return True + + def read_porttab_mappings(self, porttabfile): + #print("I am in porttab_mappings") + logical = [] + logical_to_bcm = {} + logical_to_physical = {} + physical_to_logical = {} + last_fp_port_index = 0 + last_portname = "" + first = 1 + port_pos_in_file = 0 + parse_fmt_port_config_ini = False + + try: + f = open(porttabfile) + except: + raise + + parse_fmt_port_config_ini = (os.path.basename(porttabfile) == "port_config.ini") + # Read the porttab file and generate dicts + # with mapping for future reference. + # + # TODO: Refactor this to use the portconfig.py module that now + # exists as part of the sonic-config-engine package. + title = [] + for line in f: + line.strip() + if re.search("^#", line) is not None: + # The current format is: # name lanes alias index speed + # Where the ordering of the columns can vary + title = line.split()[1:] + continue + #print title + + # Parsing logic for 'port_config.ini' file + if (parse_fmt_port_config_ini): + # bcm_port is not explicitly listed in port_config.ini format + # Currently we assume ports are listed in numerical order according to bcm_port + # so we use the port's position in the file (zero-based) as bcm_port + portname = line.split()[0] + + bcm_port = str(port_pos_in_file) + + if "index" in title: + fp_port_index = int(line.split()[title.index("index")]) + # Leave the old code for backward compatibility + # if len(line.split()) >= 4: + # fp_port_index = (line.split()[3]) + # print(fp_port_index) + else: + fp_port_index = portname.split("Ethernet").pop() + fp_port_index = int(fp_port_index.split("s").pop(0))+1 + else: # Parsing logic for older 'portmap.ini' file + (portname, bcm_port) = line.split("=")[1].split(",")[:2] + + fp_port_index = portname.split("Ethernet").pop() + fp_port_index = int(fp_port_index.split("s").pop(0))+1 + + if ((len(self.sfp_ports) > 0) and (fp_port_index not in self.sfp_ports)): + continue + + if first == 1: + # Initialize last_[physical|logical]_port + # to the first valid port + last_fp_port_index = fp_port_index + last_portname = portname + first = 0 + + logical.append(portname) + + logical_to_bcm[portname] = "xe" + bcm_port + logical_to_physical[portname] = [fp_port_index] + if physical_to_logical.get(fp_port_index) is None: + physical_to_logical[fp_port_index] = [portname] + else: + physical_to_logical[fp_port_index].append( + portname) + + if (fp_port_index - last_fp_port_index) > 1: + # last port was a gang port + for p in range(last_fp_port_index+1, fp_port_index): + logical_to_physical[last_portname].append(p) + if physical_to_logical.get(p) is None: + physical_to_logical[p] = [last_portname] + else: + physical_to_logical[p].append(last_portname) + + last_fp_port_index = fp_port_index + last_portname = portname + + port_pos_in_file += 1 + + self.logical = logical + self.logical_to_bcm = logical_to_bcm + self.logical_to_physical = logical_to_physical + self.physical_to_logical = physical_to_logical + + # print(self.logical_to_physical) + '''print("logical: " + self.logical) + print("logical to bcm: " + self.logical_to_bcm) + print("logical to physical: " + self.logical_to_physical) + print("physical to logical: " + self.physical_to_logical)''' + #print("exiting port_tab_mappings") + + @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 + + @property + def get_transceiver_change_event(self): + raise NotImplementedError diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/pmon_daemon_control.json b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/buffers_defaults_t0.j2 b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..19be04b5ca4d --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/buffers_defaults_t0.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "23000000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "23000000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"340000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/buffers_defaults_t1.j2 b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..19be04b5ca4d --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/buffers_defaults_t1.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "23000000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "23000000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"340000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/port_config.ini b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/port_config.ini new file mode 100644 index 000000000000..6d8b5d0a13df --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/port_config.ini @@ -0,0 +1,34 @@ +# name lanes speed alias +Ethernet0 0 25000 twenty5GigE0 +Ethernet1 1 25000 twenty5GigE1 +Ethernet2 2 25000 twenty5GigE2 +Ethernet3 3 25000 twenty5GigE3 +Ethernet4 4 25000 twenty5GigE4 +Ethernet5 5 25000 twenty5GigE5 +Ethernet6 6 25000 twenty5GigE6 +Ethernet7 7 25000 twenty5GigE7 +Ethernet8 8 25000 twenty5GigE8 +Ethernet9 9 25000 twenty5GigE9 +Ethernet10 10 25000 twenty5GigE10 +Ethernet11 11 25000 twenty5GigE11 +Ethernet12 12 25000 twenty5GigE12 +Ethernet13 13 25000 twenty5GigE13 +Ethernet14 14 25000 twenty5GigE14 +Ethernet15 15 25000 twenty5GigE15 +Ethernet16 16 25000 twenty5GigE16 +Ethernet17 17 25000 twenty5GigE17 +Ethernet18 18 25000 twenty5GigE18 +Ethernet19 19 25000 twenty5GigE19 +Ethernet20 20 25000 twenty5GigE20 +Ethernet21 21 25000 twenty5GigE21 +Ethernet22 22 25000 twenty5GigE22 +Ethernet23 23 25000 twenty5GigE23 +Ethernet24 24 25000 twenty5GigE24 +Ethernet25 25 25000 twenty5GigE25 +Ethernet26 26 25000 twenty5GigE26 +Ethernet27 27 25000 twenty5GigE27 +Ethernet28 28 25000 twenty5GigE28 +Ethernet29 29 25000 twenty5GigE29 +Ethernet30 30 25000 twenty5GigE30 +Ethernet31 31 25000 twenty5GigE31 +Ethernet32 32 10000 tenGigE32 diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/profile.ini b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/profile.ini new file mode 100644 index 000000000000..487e80dcbd70 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/profile.ini @@ -0,0 +1,2 @@ +switchMacAddress=00:01:02:03:04:05 +apPortListWithCableLen=000:1 001:1 002:1 003:1 004:1 005:1 006:1 007:1 008:1 009:1 010:1 011:1 012:1 013:1 014:1 015:1 016:1 017:1 018:1 019:1 020:1 021:1 022:1 023:1 024:1 025:1 026:1 027:1 028:1 029:1 030:1 031:1 032:1 diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/sai.profile b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/sai.profile new file mode 100644 index 000000000000..dd6f707a81ab --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32X25G/sai.profile @@ -0,0 +1,3 @@ +mode=1 +hwId=FALCON32X25G +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/profile.ini diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/buffers_defaults_t0.j2 b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..19be04b5ca4d --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/buffers_defaults_t0.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "23000000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "23000000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"340000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/buffers_defaults_t1.j2 b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..19be04b5ca4d --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/buffers_defaults_t1.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "23000000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "23000000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"340000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/port_config.ini b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/port_config.ini new file mode 100644 index 000000000000..62dd91ba8869 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/port_config.ini @@ -0,0 +1,34 @@ +# name lanes speed alias +Ethernet0 0,1,2,3,4,5,6,7 400000 four00GigE0 +Ethernet8 8,9,10,11,12,13,14,15 400000 four00GigE8 +Ethernet16 16,17,18,19,20,21,22,23 400000 four00GigE16 +Ethernet24 24,25,26,27,28,29,30,31 400000 four00GigE24 +Ethernet32 32,33,34,35,36,37,38,39 400000 four00GigE32 +Ethernet40 40,41,42,43,44,45,46,47 400000 four00GigE40 +Ethernet48 48,49,50,51,52,53,54,55 400000 four00GigE48 +Ethernet56 56,57,58,59,60,61,62,63 400000 four00GigE56 +Ethernet64 64,65,66,67,68,69,70,71 400000 four00GigE64 +Ethernet72 72,73,74,75,76,77,78,79 400000 four00GigE72 +Ethernet80 80,81,82,83,84,85,86,87 400000 four00GigE80 +Ethernet88 88,89,90,91,92,93,94,95 400000 four00GigE88 +Ethernet96 96,97,98,99,100,101,102,103 400000 four00GigE96 +Ethernet104 104,105,106,107,108,109,110,111 400000 four00GigE104 +Ethernet112 112,113,114,115,116,117,118,119 400000 four00GigE112 +Ethernet120 120,121,122,123,124,125,126,127 400000 four00GigE120 +Ethernet128 128,129,130,131,132,133,134,135 400000 four00GigE128 +Ethernet136 136,137,138,139,140,141,142,143 400000 four00GigE136 +Ethernet144 144,145,146,147,148,149,150,151 400000 four00GigE144 +Ethernet152 152,153,154,155,156,157,158,159 400000 four00GigE152 +Ethernet160 160,161,162,163,164,165,166,167 400000 four00GigE160 +Ethernet168 168,169,170,171,172,173,174,175 400000 four00GigE168 +Ethernet176 176,177,178,179,180,181,182,183 400000 four00GigE176 +Ethernet184 184,185,186,187,188,189,190,191 400000 four00GigE184 +Ethernet192 192,193,194,195,196,197,198,199 400000 four00GigE192 +Ethernet200 200,201,202,203,204,205,206,207 400000 four00GigE200 +Ethernet208 208,209,210,211,212,213,214,215 400000 four00GigE208 +Ethernet216 216,217,218,219,220,221,222,223 400000 four00GigE216 +Ethernet224 224,225,226,227,228,229,230,231 400000 four00GigE224 +Ethernet232 232,233,234,235,236,237,238,239 400000 four00GigE232 +Ethernet240 240,241,242,243,244,245,246,247 400000 four00GigE240 +Ethernet248 248,249,250,251,252,253,254,255 400000 four00GigE248 +Ethernet256 256 10000 tenGigE256 diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/profile.ini b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/profile.ini new file mode 100644 index 000000000000..2813bbd363f8 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/profile.ini @@ -0,0 +1,2 @@ +switchMacAddress=00:01:02:03:04:05 +apPortListWithCableLen=000:1 008:1 016:1 024:1 032:1 040:1 048:1 056:1 064:1 072:1 080:1 088:1 096:1 104:1 112:1 120:1 128:1 136:1 144:1 152:1 160:1 168:1 176:1 184:1 192:1 200:1 208:1 216:1 224:1 232:1 240:1 248:1 256:1 diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/sai.profile b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/sai.profile new file mode 100644 index 000000000000..6dc6f35fed4e --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/FALCON32x400G/sai.profile @@ -0,0 +1,3 @@ +mode=1 +hwId=FALCON32x400G +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/profile.ini diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers.json.j2 b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers.json.j2 new file mode 100644 index 000000000000..a9a01d707ebf --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers.json.j2 @@ -0,0 +1 @@ +{%- include 'buffers_config.j2' %} diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_config.j2 b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_config.j2 new file mode 100644 index 000000000000..5431fbe72c1f --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_config.j2 @@ -0,0 +1,165 @@ +{%- macro set_default_topology() %} +{%- if default_topo is defined %} +{{ default_topo }} +{%- else %} +def +{%- endif %} +{%- endmacro -%} + +{# Determine device topology and filename postfix #} +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- if 'torrouter' in switch_role.lower() %} +{%- set filename_postfix = 't0' %} +{%- elif 'leafrouter' in switch_role.lower() %} +{%- set filename_postfix = 't1' %} +{%- else %} +{%- set filename_postfix = set_default_topology() %} +{%- endif %} +{%- else %} +{%- set filename_postfix = set_default_topology() %} +{%- set switch_role = '' %} +{%- endif -%} + +{# Import default values from device HWSKU folder #} +{%- import 'buffers_defaults_%s.j2' % filename_postfix as defs %} + +{%- set default_cable = defs.default_cable -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{%- if defs.ports2cable is defined %} + {%- set ports2cable = defs.ports2cable %} +{%- else %} + {%- set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } + -%} +{%- endif %} + +{%- macro cable_length(port_name) %} + {%- set cable_len = [] %} + {%- for local_port in DEVICE_NEIGHBOR %} + {%- if local_port == port_name %} + {%- if DEVICE_NEIGHBOR_METADATA is defined and 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 %} + {%- if 'torrouter' in switch_role.lower() %} + {%- for local_port in VLAN_MEMBER %} + {%- if local_port[1] == port_name %} + {%- set roles3 = switch_role + '_' + 'server' %} + {%- set roles3 = roles3 | lower %} + {%- if roles3 in ports2cable %} + {%- if cable_len.append(ports2cable[roles3]) %}{% endif %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- endif %} +{%- endmacro %} + +{%- set PORT_ALL = [] %} + +{%- if PORT is not defined %} + {%- if defs.generate_port_lists(PORT_ALL) %} {% endif %} +{%- else %} + {%- for port in PORT %} + {%- if PORT_ALL.append(port) %}{%- endif %} + {%- endfor %} +{%- endif %} + +{%- set PORT_ACTIVE = [] %} +{%- if DEVICE_NEIGHBOR is not defined %} + {%- set PORT_ACTIVE = PORT_ALL %} +{%- else %} + {%- for port in DEVICE_NEIGHBOR.keys() %} + {%- if PORT_ACTIVE.append(port) %}{%- endif %} + {%- endfor %} +{%- endif %} + +{%- set port_names_list_active = [] %} +{%- for port in PORT_ACTIVE %} + {%- if port_names_list_active.append(port) %}{%- endif %} +{%- endfor %} +{%- set port_names_active = port_names_list_active | join(',') %} + +{ + "CABLE_LENGTH": { + "AZURE": { + {% for port in PORT_ALL %} + {%- set cable = cable_length(port) %} + "{{ port }}": "{{ cable }}"{%- if not loop.last %},{% endif %} + + {% endfor %} + } + }, + +{% if defs.generate_buffer_pool_and_profiles is defined %} +{{ defs.generate_buffer_pool_and_profiles() }} +{% endif %} + +{%- if defs.generate_profile_lists is defined %} +{{ defs.generate_profile_lists(port_names_active) }}, +{% endif %} + +{%- if defs.generate_pg_profils is defined %} +{{ defs.generate_pg_profils(port_names_active) }} +{% else %} + "BUFFER_PG": { +{% for port in PORT_ACTIVE %} + "{{ port }}|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, +{% endif %} + +{% if defs.generate_queue_buffers is defined %} +{{ defs.generate_queue_buffers(port_names_active) }} +{% else %} + "BUFFER_QUEUE": { +{% for port in PORT_ACTIVE %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{% endif %} +} diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_defaults_t0.j2 b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..19be04b5ca4d --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_defaults_t0.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "23000000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "23000000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"340000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_defaults_t1.j2 b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..19be04b5ca4d --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_defaults_t1.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "23000000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "23000000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"340000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/port_config.ini b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/port_config.ini new file mode 100644 index 000000000000..62dd91ba8869 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/port_config.ini @@ -0,0 +1,34 @@ +# name lanes speed alias +Ethernet0 0,1,2,3,4,5,6,7 400000 four00GigE0 +Ethernet8 8,9,10,11,12,13,14,15 400000 four00GigE8 +Ethernet16 16,17,18,19,20,21,22,23 400000 four00GigE16 +Ethernet24 24,25,26,27,28,29,30,31 400000 four00GigE24 +Ethernet32 32,33,34,35,36,37,38,39 400000 four00GigE32 +Ethernet40 40,41,42,43,44,45,46,47 400000 four00GigE40 +Ethernet48 48,49,50,51,52,53,54,55 400000 four00GigE48 +Ethernet56 56,57,58,59,60,61,62,63 400000 four00GigE56 +Ethernet64 64,65,66,67,68,69,70,71 400000 four00GigE64 +Ethernet72 72,73,74,75,76,77,78,79 400000 four00GigE72 +Ethernet80 80,81,82,83,84,85,86,87 400000 four00GigE80 +Ethernet88 88,89,90,91,92,93,94,95 400000 four00GigE88 +Ethernet96 96,97,98,99,100,101,102,103 400000 four00GigE96 +Ethernet104 104,105,106,107,108,109,110,111 400000 four00GigE104 +Ethernet112 112,113,114,115,116,117,118,119 400000 four00GigE112 +Ethernet120 120,121,122,123,124,125,126,127 400000 four00GigE120 +Ethernet128 128,129,130,131,132,133,134,135 400000 four00GigE128 +Ethernet136 136,137,138,139,140,141,142,143 400000 four00GigE136 +Ethernet144 144,145,146,147,148,149,150,151 400000 four00GigE144 +Ethernet152 152,153,154,155,156,157,158,159 400000 four00GigE152 +Ethernet160 160,161,162,163,164,165,166,167 400000 four00GigE160 +Ethernet168 168,169,170,171,172,173,174,175 400000 four00GigE168 +Ethernet176 176,177,178,179,180,181,182,183 400000 four00GigE176 +Ethernet184 184,185,186,187,188,189,190,191 400000 four00GigE184 +Ethernet192 192,193,194,195,196,197,198,199 400000 four00GigE192 +Ethernet200 200,201,202,203,204,205,206,207 400000 four00GigE200 +Ethernet208 208,209,210,211,212,213,214,215 400000 four00GigE208 +Ethernet216 216,217,218,219,220,221,222,223 400000 four00GigE216 +Ethernet224 224,225,226,227,228,229,230,231 400000 four00GigE224 +Ethernet232 232,233,234,235,236,237,238,239 400000 four00GigE232 +Ethernet240 240,241,242,243,244,245,246,247 400000 four00GigE240 +Ethernet248 248,249,250,251,252,253,254,255 400000 four00GigE248 +Ethernet256 256 10000 tenGigE256 diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/profile.ini b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/profile.ini new file mode 100644 index 000000000000..2813bbd363f8 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/profile.ini @@ -0,0 +1,2 @@ +switchMacAddress=00:01:02:03:04:05 +apPortListWithCableLen=000:1 008:1 016:1 024:1 032:1 040:1 048:1 056:1 064:1 072:1 080:1 088:1 096:1 104:1 112:1 120:1 128:1 136:1 144:1 152:1 160:1 168:1 176:1 184:1 192:1 200:1 208:1 216:1 224:1 232:1 240:1 248:1 256:1 diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/qos.json.j2 b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/sai.profile b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/sai.profile new file mode 100644 index 000000000000..6dc6f35fed4e --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/sai.profile @@ -0,0 +1,3 @@ +mode=1 +hwId=FALCON32x400G +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/profile.ini diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/default_sku b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/default_sku new file mode 100644 index 000000000000..563676854022 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/default_sku @@ -0,0 +1 @@ +db98cx8580_32cd t1 diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/plugins/eeprom.py b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/plugins/eeprom.py new file mode 100644 index 000000000000..71f05c5b70f5 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/plugins/eeprom.py @@ -0,0 +1,11 @@ +try: + from sonic_eeprom import eeprom_tlvinfo +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/etc/sonic/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/plugins/sfputil.py b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/plugins/sfputil.py new file mode 100644 index 000000000000..b3d1ea371454 --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/plugins/sfputil.py @@ -0,0 +1,257 @@ +try: + import os + import time + import sys + import re + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +if sys.version_info[0] < 3: + import commands +else: + import subprocess as commands + +smbus_present = 1 + +try: + import smbus +except ImportError as e: + smbus_present = 0 + + +class SfpUtil(SfpUtilBase): + """Platform specific sfputil class""" + _port_start = 1 + _port_end = 257 + ports_in_block = 257 + + _port_to_eeprom_mapping = {} + + _qsfp_ports = list(range(_port_start, ports_in_block + 1)) + + def __init__(self): + os.system("modprobe i2c-dev") + if not os.path.exists("/sys/bus/i2c/devices/0-0050"): + os.system("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-0/new_device") + + eeprom_path = '/sys/bus/i2c/devices/0-0050/eeprom' + # for x in range(self.port _start, self.port_end +1): + x = self.port_start + while(x < self.port_end+1): + self.port_to_eeprom_mapping[x] = eeprom_path + x = x + 1 + 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 + + port_ps = "/sys/bus/i2c/devices/0-0050/sfp_port_reset" + + try: + reg_file = open(port_ps, 'w') + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + # toggle reset + reg_file.seek(0) + reg_file.write('1') + time.sleep(1) + reg_file.seek(0) + reg_file.write('0') + reg_file.close() + return True + + def set_low_power_mode(self, port_nuM, lpmode): + raise NotImplementedError + + def get_low_power_mode(self, port_num): + raise NotImplementedError + + def i2c_get(self, device_addr, offset): + status = 0 + if smbus_present == 0: + x = "i2cget -y 0 " + hex(device_addr) + " " + hex(offset) + cmdstatus, status = commands.getstatusoutput(x) + if cmdstatus != 0: + return cmdstatus + status = int(status, 16) + else: + bus = smbus.SMBus(0) + status = bus.read_byte_data(device_addr, offset) + return status + + def i2c_set(self, device_addr, offset, value): + if smbus_present == 0: + cmd = "i2cset -y 0 " + hex(device_addr) + " " + hex(offset) + " " + hex(value) + os.system(cmd) + else: + bus = smbus.SMBus(0) + bus.write_byte_data(device_addr, offset, value) + + 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 + else: + self.i2c_set(0x70, 0, 0) + self.i2c_set(0x71, 0, 0) + self.i2c_set(0x72, 0, 0) + self.i2c_set(0x73, 0, 0) + self.i2c_set(0x74, 0, 0) + reg = (port_num)/8 + offset = reg % 8 + if offset >= 4: + offset = offset-4 + elif offset < 4: + offset = offset+4 + bin_offset = 1 << offset + + if port_num >= 0 and port_num <= 63: + device_reg = 0x70 + elif port_num >= 64 and port_num <= 127: + device_reg = 0x71 + elif port_num >= 128 and port_num <= 191: + device_reg = 0x72 + elif port_num >= 192 and port_num <= 255: + device_reg = 0x73 + elif port_num >= 256 and port_num <= 257: + device_reg = 0x74 + + #print "i2c %d %x %x" % (port_num, device_reg, bin_offset) + self.i2c_set(device_reg, 0, bin_offset) + path = "/sys/bus/i2c/devices/0-0050/eeprom" + try: + reg_file = open(path) + reg_file.seek(0o1) + reg_file.read(0o2) + except IOError as e: + return False + + return True + + def read_porttab_mappings(self, porttabfile): + #print("I am in porttab_mappings") + logical = [] + logical_to_bcm = {} + logical_to_physical = {} + physical_to_logical = {} + last_fp_port_index = 0 + last_portname = "" + first = 1 + port_pos_in_file = 0 + parse_fmt_port_config_ini = False + + try: + f = open(porttabfile) + except: + raise + + parse_fmt_port_config_ini = (os.path.basename(porttabfile) == "port_config.ini") + # Read the porttab file and generate dicts + # with mapping for future reference. + # + # TODO: Refactor this to use the portconfig.py module that now + # exists as part of the sonic-config-engine package. + title = [] + for line in f: + line.strip() + if re.search("^#", line) is not None: + # The current format is: # name lanes alias index speed + # Where the ordering of the columns can vary + title = line.split()[1:] + continue + #print title + + # Parsing logic for 'port_config.ini' file + if (parse_fmt_port_config_ini): + # bcm_port is not explicitly listed in port_config.ini format + # Currently we assume ports are listed in numerical order according to bcm_port + # so we use the port's position in the file (zero-based) as bcm_port + portname = line.split()[0] + + bcm_port = str(port_pos_in_file) + + if "index" in title: + fp_port_index = int(line.split()[title.index("index")]) + # Leave the old code for backward compatibility + # if len(line.split()) >= 4: + # fp_port_index = (line.split()[3]) + # print(fp_port_index) + else: + fp_port_index = portname.split("Ethernet").pop() + fp_port_index = int(fp_port_index.split("s").pop(0))+1 + else: # Parsing logic for older 'portmap.ini' file + (portname, bcm_port) = line.split("=")[1].split(",")[:2] + + fp_port_index = portname.split("Ethernet").pop() + fp_port_index = int(fp_port_index.split("s").pop(0))+1 + + if ((len(self.sfp_ports) > 0) and (fp_port_index not in self.sfp_ports)): + continue + + if first == 1: + # Initialize last_[physical|logical]_port + # to the first valid port + last_fp_port_index = fp_port_index + last_portname = portname + first = 0 + + logical.append(portname) + + logical_to_bcm[portname] = "xe" + bcm_port + logical_to_physical[portname] = [fp_port_index] + if physical_to_logical.get(fp_port_index) is None: + physical_to_logical[fp_port_index] = [portname] + else: + physical_to_logical[fp_port_index].append( + portname) + + if (fp_port_index - last_fp_port_index) > 1: + # last port was a gang port + for p in range(last_fp_port_index+1, fp_port_index): + logical_to_physical[last_portname].append(p) + if physical_to_logical.get(p) is None: + physical_to_logical[p] = [last_portname] + else: + physical_to_logical[p].append(last_portname) + + last_fp_port_index = fp_port_index + last_portname = portname + + port_pos_in_file += 1 + + self.logical = logical + self.logical_to_bcm = logical_to_bcm + self.logical_to_physical = logical_to_physical + self.physical_to_logical = physical_to_logical + + # print(self.logical_to_physical) + '''print("logical: " + self.logical) + print("logical to bcm: " + self.logical_to_bcm) + print("logical to physical: " + self.logical_to_physical) + print("physical to logical: " + self.physical_to_logical)''' + #print("exiting port_tab_mappings") + + @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 + + @property + def get_transceiver_change_event(self): + raise NotImplementedError diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/pmon_daemon_control.json b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} diff --git a/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/eeprom.py b/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/eeprom.py index ea525f5d74b1..71f05c5b70f5 100644 --- a/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/eeprom.py +++ b/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/eeprom.py @@ -1,9 +1,7 @@ -#!/usr/bin/env python - try: from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): diff --git a/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/psuutil.py b/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/psuutil.py index 16965414e64b..ab6aeff2b20b 100755 --- a/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/psuutil.py +++ b/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/psuutil.py @@ -1,29 +1,28 @@ -#!/usr/bin/env python - import sys import os.path if sys.version_info[0] < 3: - import commands as cmd + import commands else: - import subprocess as cmd + import subprocess as commands smbus_present = 1 try: - import smbus + import smbus except ImportError as e: - smbus_present = 0 + smbus_present = 0 try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" def __init__(self): - PsuBase.__init__(self) - MAX_PSUS = 2 + PsuBase.__init__(self) + MAX_PSUS = 2 def get_num_psus(self): MAX_PSUS = 2 @@ -31,46 +30,47 @@ def get_num_psus(self): def get_psu_status(self, index): if index is None: - return False - if smbus_present == 0: - cmdstatus, psustatus = cmd.getstatusoutput('i2cget -y 0 0x41 0xa') #need to verify the cpld register logic - psustatus = int(psustatus, 16) - else : - bus = smbus.SMBus(0) - DEVICE_ADDRESS = 0x41 - DEVICE_REG = 0xa - psustatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + return False + if smbus_present == 0: + cmdstatus, psustatus = commands.getstatusoutput( + 'i2cget -y 0 0x41 0xa') # need to verify the cpld register logic + psustatus = int(psustatus, 16) + else: + bus = smbus.SMBus(0) + DEVICE_ADDRESS = 0x41 + DEVICE_REG = 0xa + psustatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) if index == 1: - psustatus = psustatus&4 - if psustatus == 4 : - return True + psustatus = psustatus & 4 + if psustatus == 4: + return True if index == 2: - psustatus = psustatus&8 - if psustatus == 8 : - return True - + psustatus = psustatus & 8 + if psustatus == 8: + return True + return False def get_psu_presence(self, index): if index is None: return False - if smbus_present == 0: - cmdstatus, psustatus = cmd.getstatusoutput('i2cget -y 0 0x41 0xa') #need to verify the cpld register logic - psustatus = int(psustatus, 16) - else : - bus = smbus.SMBus(0) - DEVICE_ADDRESS = 0x41 - DEVICE_REG = 0xa - psustatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + if smbus_present == 0: + cmdstatus, psustatus = commands.getstatusoutput( + 'i2cget -y 0 0x41 0xa') # need to verify the cpld register logic + psustatus = int(psustatus, 16) + else: + bus = smbus.SMBus(0) + DEVICE_ADDRESS = 0x41 + DEVICE_REG = 0xa + psustatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) if index == 1: - psustatus = psustatus&1 - if psustatus == 1 : - return True + psustatus = psustatus & 1 + if psustatus == 1: + return True if index == 2: - psustatus = psustatus&2 - if psustatus == 2 : + psustatus = psustatus & 2 + if psustatus == 2: return True return False - diff --git a/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/sfputil.py b/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/sfputil.py index 92a1604f311a..39d5db4ce7f4 100755 --- a/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/sfputil.py +++ b/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/sfputil.py @@ -1,20 +1,26 @@ -#!/usr/bin/env python - try: import os import time import re + import sys + import glob from sonic_sfp.sfputilbase import SfpUtilBase -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +if sys.version_info[0] < 3: + import commands +else: + import subprocess as commands smbus_present = 1 try: import smbus -except ImportError, e: +except ImportError as e: smbus_present = 0 + class SfpUtil(SfpUtilBase): """Platform specific sfputil class""" @@ -24,40 +30,46 @@ class SfpUtil(SfpUtilBase): _port_to_eeprom_mapping = {} port_to_i2c_mapping = { - 49 : 0, - 50 : 0, - 51 : 0, - 52 : 0 + 49: 2, + 50: 3, + 51: 4, + 52: 5 } - _qsfp_ports = range(_port_start, ports_in_block + 1) + _qsfp_ports = list(range(_port_start, ports_in_block + 1)) + _changed_ports = [0, 0, 0, 0] def __init__(self): - # Override port_to_eeprom_mapping for class initialization - if not os.path.exists("/sys/class/gpio/gpio50/") : - os.system("echo 50 > /sys/class/gpio/gpiochip32/subsystem/export") - if not os.path.exists("/sys/class/gpio/gpio52/") : - os.system("echo 52 > /sys/class/gpio/gpiochip32/subsystem/export") - os.system("echo out > /sys/class/gpio/gpio50/direction") - os.system("echo out > /sys/class/gpio/gpio52/direction ") - - if not os.path.exists("/sys/bus/i2c/devices/0-0050") : - os.system("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-0/new_device") - - eeprom_path = '/sys/bus/i2c/devices/0-0050/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 + # Enable optical SFP Tx - if smbus_present == 0 : + if smbus_present == 0: os.system("i2cset -y -m 0x0f 0 0x41 0x5 0x00") - else : + else: bus = smbus.SMBus(0) DEVICE_ADDRESS = 0x41 - DEVICEREG = 0x5 - OPTIC_E = bus.read_byte_data(DEVICE_ADDRESS, DEVICEREG) + DEVICEREG = 0x5 + OPTIC_E = bus.read_byte_data(DEVICE_ADDRESS, DEVICEREG) OPTIC_E = OPTIC_E & 0xf0 - bus.write_byte_data(DEVICE_ADDRESS, DEVICEREG, OPTIC_E) + bus.write_byte_data(DEVICE_ADDRESS, DEVICEREG, OPTIC_E) + + # Mux Ordering + mux_dev = sorted(glob.glob("/sys/class/i2c-adapter/i2c-0/i2c-[0-9]")) + + # Enable optoe2 Driver + eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" + bus_path = "/sys/class/i2c-adapter/i2c-{0}/" + y = 0 + for x in range(self.port_start, self.port_end + 1): + mux_dev_num = mux_dev[y] + self.port_to_i2c_mapping[x] = mux_dev_num[-1] + y = y + 1 + port_eeprom_path = eeprom_path.format(self.port_to_i2c_mapping[x]) + #print port_eeprom_path + if not os.path.exists(port_eeprom_path): + bus_dev_path = bus_path.format(self.port_to_i2c_mapping[x]) + os.system("echo optoe2 0x50 > " + bus_dev_path + "/new_device") + self.port_to_eeprom_mapping[x] = port_eeprom_path + self._port_to_eeprom_mapping[x] = port_eeprom_path SfpUtilBase.__init__(self) def reset(self, port_num): @@ -65,16 +77,16 @@ def reset(self, 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+1]) - + path = "/sys/class/i2c-adapter/i2c-{0}/{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) + print("Error: unable to open file: %s" % str(e)) return False - #toggle reset + # toggle reset reg_file.seek(0) reg_file.write('1') time.sleep(1) @@ -88,53 +100,36 @@ def set_low_power_mode(self, port_nuM, lpmode): 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 - prt = port_num % 49 - prt = "{0:02b}".format(prt) - p = prt[0] - q = prt[1] - cmd1 = "echo " + q + " > /sys/class/gpio/gpio50/value" - cmd2 = "echo " + p + " > /sys/class/gpio/gpio52/value" - os.system(cmd1) - os.system(cmd2) - - '''if port_num == 49 : - os.system("echo 0 > /sys/class/gpio/gpio50/value") - os.system("echo 0 > /sys/class/gpio/gpio52/value") - if port_num == 50 : - os.system("echo 0 > /sys/class/gpio/gpio50/value") - os.system("echo 0 > /sys/class/gpio/gpio52/value") - if port_num == 51 : - os.system("echo 0 > /sys/class/gpio/gpio50/value") - os.system("echo 0 > /sys/class/gpio/gpio52/value") - if port_num == 52: - os.system("echo 0 > /sys/class/gpio/gpio50/value") - os.system("echo 0 > /sys/class/gpio/gpio52/value")''' - path = "/sys/bus/i2c/devices/0-0050/eeprom" - #port_ps = path.format(self.port_to_i2c_mapping[port_num+1]) - - try: - reg_file = open(path) - reg_file.seek(01) - reg_file.read(02) - except IOError as e: - #print "Error: unable to open file: %s" % str(e) - - return False - - #reg_value = reg_file.readline().rstrip() - #if reg_value == '1': - # return True + prt = port_num % 49 + sel = "{0:02b}".format(prt) + p = sel[0] + q = sel[1] + + pos = [1, 2, 4, 8] + bit_pos = pos[prt] + if smbus_present == 0: + cmdstatus, sfpstatus = commands.getstatusoutput( + 'i2cget -y 0 0x41 0x3') # need to verify the cpld register logic + sfpstatus = int(sfpstatus, 16) + else: + bus = smbus.SMBus(0) + DEVICE_ADDRESS = 0x41 + DEVICE_REG = 0x3 + sfpstatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + sfpstatus = sfpstatus & (bit_pos) + if sfpstatus == 0: + #print("Port " + str(port_num) + "present") + return True - return True + return False def read_porttab_mappings(self, porttabfile): logical = [] - logical_to_bcm = {} logical_to_physical = {} physical_to_logical = {} last_fp_port_index = 0 @@ -166,14 +161,8 @@ def read_porttab_mappings(self, porttabfile): # Parsing logic for 'port_config.ini' file if (parse_fmt_port_config_ini): - # bcm_port is not explicitly listed in port_config.ini format - # Currently we assume ports are listed in numerical order according to bcm_port - # so we use the port's position in the file (zero-based) as bcm_port portname = line.split()[0] - bcm_port = str(port_pos_in_file) - #print("portname " + portname) - if "index" in title: fp_port_index = int(line.split()[title.index("index")]) # Leave the old code for backward compatibility @@ -182,10 +171,8 @@ def read_porttab_mappings(self, porttabfile): else: fp_port_index = portname.split("Ethernet").pop() fp_port_index = int(fp_port_index.split("s").pop(0))+1 - #print(fp_port_index) + # print(fp_port_index) else: # Parsing logic for older 'portmap.ini' file - (portname, bcm_port) = line.split("=")[1].split(",")[:2] - fp_port_index = portname.split("Ethernet").pop() fp_port_index = int(fp_port_index.split("s").pop(0))+1 @@ -201,7 +188,6 @@ def read_porttab_mappings(self, porttabfile): logical.append(portname) - logical_to_bcm[portname] = "xe" + bcm_port logical_to_physical[portname] = [fp_port_index] if physical_to_logical.get(fp_port_index) is None: physical_to_logical[fp_port_index] = [portname] @@ -224,18 +210,9 @@ def read_porttab_mappings(self, porttabfile): port_pos_in_file += 1 self.logical = logical - self.logical_to_bcm = logical_to_bcm self.logical_to_physical = logical_to_physical self.physical_to_logical = physical_to_logical - - - #print(self.logical_to_physical) - '''print("logical: " + self.logical) - print("logical to bcm: " + self.logical_to_bcm) - print("logical to physical: " + self.logical_to_physical) - print("physical to logical: " + self.physical_to_logical)''' - - + # print(self.logical_to_physical) @property def port_start(self): @@ -244,15 +221,47 @@ def port_start(self): @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 - @property - def get_transceiver_change_event(self): - raise NotImplementedError + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + def get_transceiver_change_event(self, timeout): + port_dict = {} + port = 0 + + if timeout == 0: + cd_ms = sys.maxsize + else: + cd_ms = timeout + changed_port = 0 + # poll per second + while cd_ms > 0: + for port_num in range(49, 53): + prt = port_num % 49 + sfpstatus = self.get_presence(port_num) + if sfpstatus: + port_dict[str(port_num)] = '1' + if self._changed_ports[prt] == 0: + changed_port = 1 + self._changed_ports[prt] = 1 + else: + port_dict[str(port_num)] = '0' + if self._changed_ports[prt] == 1: + changed_port = 1 + self._changed_ports[prt] = 0 + + if changed_port != 0: + break + time.sleep(1) + cd_ms = cd_ms - 1000 + + if changed_port: + return True, port_dict + else: + return True, {} + return False, {} diff --git a/device/marvell/armhf-marvell_et6448m_52x-r0/pmon_daemon_control.json b/device/marvell/armhf-marvell_et6448m_52x-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..a3ecea34bcc9 --- /dev/null +++ b/device/marvell/armhf-marvell_et6448m_52x-r0/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_thermalctld": true, + "skip_ledd": true +} diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/buffers_defaults_t0.j2 b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..b23ec5259b21 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/buffers_defaults_t0.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11500000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "11500000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"330000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/buffers_defaults_t1.j2 b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..b23ec5259b21 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/buffers_defaults_t1.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11500000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "11500000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"330000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/port_config.ini b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/port_config.ini new file mode 100644 index 000000000000..074c0344c896 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/port_config.ini @@ -0,0 +1,19 @@ +# name lanes speed alias +Ethernet0 0 25000 twenty5GigE0 +Ethernet1 1 25000 twenty5GigE1 +Ethernet2 2 25000 twenty5GigE2 +Ethernet3 3 25000 twenty5GigE3 +Ethernet4 4 25000 twenty5GigE4 +Ethernet5 5 25000 twenty5GigE5 +Ethernet6 6 25000 twenty5GigE6 +Ethernet7 7 25000 twenty5GigE7 +Ethernet8 8 25000 twenty5GigE8 +Ethernet9 9 25000 twenty5GigE9 +Ethernet10 10 25000 twenty5GigE10 +Ethernet11 11 25000 twenty5GigE11 +Ethernet12 12 25000 twenty5GigE12 +Ethernet13 13 25000 twenty5GigE13 +Ethernet14 14 25000 twenty5GigE14 +Ethernet15 15 25000 twenty5GigE15 +Ethernet16 16 10000 tenGigE16 +Ethernet17 17 10000 tenGigE17 diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/profile.ini b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/profile.ini new file mode 100644 index 000000000000..aeaafc4e6e4d --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/profile.ini @@ -0,0 +1,2 @@ +switchMacAddress=00:01:02:03:04:05 +apPortListWithCableLen=000:1 001:1 002:1 003:1 004:1 005:1 006:1 007:1 008:1 009:1 010:1 011:1 012:1 013:1 014:1 015:1 diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/sai.profile b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/sai.profile new file mode 100644 index 000000000000..2c9623c91105 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16X25G/sai.profile @@ -0,0 +1,3 @@ +mode=1 +hwId=FALCON16X25G +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/profile.ini diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/buffers_defaults_t0.j2 b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..b23ec5259b21 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/buffers_defaults_t0.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11500000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "11500000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"330000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/buffers_defaults_t1.j2 b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..b23ec5259b21 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/buffers_defaults_t1.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11500000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "11500000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"330000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/port_config.ini b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/port_config.ini new file mode 100644 index 000000000000..6a9bfda3fb8b --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/port_config.ini @@ -0,0 +1,19 @@ +# name lanes speed alias +Ethernet0 0,1,2,3,4,5,6,7 400000 four00GigE0 +Ethernet8 8,9,10,11,12,13,14,15 400000 four00GigE1 +Ethernet16 16,17,18,19,20,21,22,23 400000 four00GigE2 +Ethernet24 24,25,26,27,28,29,30,31 400000 four00GigE2 +Ethernet32 32,33,34,35,36,37,38,39 400000 four00GigE3 +Ethernet40 40,41,42,43,44,45,46,47 400000 four00GigE4 +Ethernet48 48,49,50,51,52,53,54,55 400000 four00GigE5 +Ethernet56 56,57,58,59,60,61,62,63 400000 four00GigE6 +Ethernet64 64,65,66,67,68,69,70,71 400000 four00GigE7 +Ethernet72 72,73,74,75,76,77,78,79 400000 four00GigE8 +Ethernet80 80,81,82,83,84,85,86,87 400000 four00GigE9 +Ethernet88 88,89,90,91,92,93,94,95 400000 four00GigE10 +Ethernet96 96,97,98,99,100,101,102,103 400000 four00GigE11 +Ethernet104 104,105,106,107,108,109,110,111 400000 four00GigE12 +Ethernet112 112,113,114,115,116,117,118,119 400000 four00GigE13 +Ethernet120 120,121,122,123,124,125,126,127 400000 four00GigE14 +Ethernet128 128 10000 tenGigE128 +Ethernet129 129 10000 tenGigE129 diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/profile.ini b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/profile.ini new file mode 100644 index 000000000000..16847ec03ae2 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/profile.ini @@ -0,0 +1,2 @@ +switchMacAddress=00:01:02:03:04:05 +apPortListWithCableLen=000:1 008:1 016:1 024:1 032:1 040:1 048:1 056:1 064:1 072:1 080:1 088:1 096:1 104:1 112:1 120:1 diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/sai.profile b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/sai.profile new file mode 100644 index 000000000000..6a2438f50180 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON16x400G/sai.profile @@ -0,0 +1,3 @@ +mode=1 +hwId=FALCON16x400G +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/profile.ini diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/buffers_defaults_t0.j2 b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..f9fb5482560d --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/buffers_defaults_t0.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11500000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "11500000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"170000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/buffers_defaults_t1.j2 b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..f9fb5482560d --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/buffers_defaults_t1.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11500000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "11500000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"170000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/port_config.ini b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/port_config.ini new file mode 100644 index 000000000000..d0402fd44317 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/port_config.ini @@ -0,0 +1,35 @@ +# name lanes speed alias +Ethernet0 0 25000 twenty5GigE0 +Ethernet1 1 25000 twenty5GigE1 +Ethernet2 2 25000 twenty5GigE2 +Ethernet3 3 25000 twenty5GigE3 +Ethernet4 4 25000 twenty5GigE4 +Ethernet5 5 25000 twenty5GigE5 +Ethernet6 6 25000 twenty5GigE6 +Ethernet7 7 25000 twenty5GigE7 +Ethernet8 8 25000 twenty5GigE8 +Ethernet9 9 25000 twenty5GigE9 +Ethernet10 10 25000 twenty5GigE10 +Ethernet11 11 25000 twenty5GigE11 +Ethernet12 12 25000 twenty5GigE12 +Ethernet13 13 25000 twenty5GigE13 +Ethernet14 14 25000 twenty5GigE14 +Ethernet15 15 25000 twenty5GigE15 +Ethernet16 16 25000 twenty5GigE16 +Ethernet17 17 25000 twenty5GigE17 +Ethernet18 18 25000 twenty5GigE18 +Ethernet19 19 25000 twenty5GigE19 +Ethernet20 20 25000 twenty5GigE20 +Ethernet21 21 25000 twenty5GigE21 +Ethernet22 22 25000 twenty5GigE22 +Ethernet23 23 25000 twenty5GigE23 +Ethernet24 24 25000 twenty5GigE24 +Ethernet25 25 25000 twenty5GigE25 +Ethernet26 26 25000 twenty5GigE26 +Ethernet27 27 25000 twenty5GigE27 +Ethernet28 28 25000 twenty5GigE28 +Ethernet29 29 25000 twenty5GigE29 +Ethernet30 30 25000 twenty5GigE30 +Ethernet31 31 25000 twenty5GigE31 +Ethernet32 32 10000 tenGigE32 +Ethernet33 33 10000 tenGigE33 diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/profile.ini b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/profile.ini new file mode 100644 index 000000000000..0ffbefa05805 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/profile.ini @@ -0,0 +1,2 @@ +switchMacAddress=00:01:02:03:04:05 +apPortListWithCableLen=000:1 001:1 002:1 003:1 004:1 005:1 006:1 007:1 008:1 009:1 010:1 011:1 012:1 013:1 014:1 015:1 016:1 017:1 018:1 019:1 020:1 021:1 022:1 023:1 024:1 025:1 026:1 027:1 028:1 029:1 030:1 031:1 diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/sai.profile b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/sai.profile new file mode 100644 index 000000000000..fa9983612117 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/FALCON32X25G/sai.profile @@ -0,0 +1,3 @@ +mode=1 +hwId=FALCON32x25G64 +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/profile.ini diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers.json.j2 b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers.json.j2 new file mode 100644 index 000000000000..a9a01d707ebf --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers.json.j2 @@ -0,0 +1 @@ +{%- include 'buffers_config.j2' %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_config.j2 b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_config.j2 new file mode 100644 index 000000000000..5431fbe72c1f --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_config.j2 @@ -0,0 +1,165 @@ +{%- macro set_default_topology() %} +{%- if default_topo is defined %} +{{ default_topo }} +{%- else %} +def +{%- endif %} +{%- endmacro -%} + +{# Determine device topology and filename postfix #} +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- if 'torrouter' in switch_role.lower() %} +{%- set filename_postfix = 't0' %} +{%- elif 'leafrouter' in switch_role.lower() %} +{%- set filename_postfix = 't1' %} +{%- else %} +{%- set filename_postfix = set_default_topology() %} +{%- endif %} +{%- else %} +{%- set filename_postfix = set_default_topology() %} +{%- set switch_role = '' %} +{%- endif -%} + +{# Import default values from device HWSKU folder #} +{%- import 'buffers_defaults_%s.j2' % filename_postfix as defs %} + +{%- set default_cable = defs.default_cable -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{%- if defs.ports2cable is defined %} + {%- set ports2cable = defs.ports2cable %} +{%- else %} + {%- set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } + -%} +{%- endif %} + +{%- macro cable_length(port_name) %} + {%- set cable_len = [] %} + {%- for local_port in DEVICE_NEIGHBOR %} + {%- if local_port == port_name %} + {%- if DEVICE_NEIGHBOR_METADATA is defined and 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 %} + {%- if 'torrouter' in switch_role.lower() %} + {%- for local_port in VLAN_MEMBER %} + {%- if local_port[1] == port_name %} + {%- set roles3 = switch_role + '_' + 'server' %} + {%- set roles3 = roles3 | lower %} + {%- if roles3 in ports2cable %} + {%- if cable_len.append(ports2cable[roles3]) %}{% endif %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- endif %} +{%- endmacro %} + +{%- set PORT_ALL = [] %} + +{%- if PORT is not defined %} + {%- if defs.generate_port_lists(PORT_ALL) %} {% endif %} +{%- else %} + {%- for port in PORT %} + {%- if PORT_ALL.append(port) %}{%- endif %} + {%- endfor %} +{%- endif %} + +{%- set PORT_ACTIVE = [] %} +{%- if DEVICE_NEIGHBOR is not defined %} + {%- set PORT_ACTIVE = PORT_ALL %} +{%- else %} + {%- for port in DEVICE_NEIGHBOR.keys() %} + {%- if PORT_ACTIVE.append(port) %}{%- endif %} + {%- endfor %} +{%- endif %} + +{%- set port_names_list_active = [] %} +{%- for port in PORT_ACTIVE %} + {%- if port_names_list_active.append(port) %}{%- endif %} +{%- endfor %} +{%- set port_names_active = port_names_list_active | join(',') %} + +{ + "CABLE_LENGTH": { + "AZURE": { + {% for port in PORT_ALL %} + {%- set cable = cable_length(port) %} + "{{ port }}": "{{ cable }}"{%- if not loop.last %},{% endif %} + + {% endfor %} + } + }, + +{% if defs.generate_buffer_pool_and_profiles is defined %} +{{ defs.generate_buffer_pool_and_profiles() }} +{% endif %} + +{%- if defs.generate_profile_lists is defined %} +{{ defs.generate_profile_lists(port_names_active) }}, +{% endif %} + +{%- if defs.generate_pg_profils is defined %} +{{ defs.generate_pg_profils(port_names_active) }} +{% else %} + "BUFFER_PG": { +{% for port in PORT_ACTIVE %} + "{{ port }}|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, +{% endif %} + +{% if defs.generate_queue_buffers is defined %} +{{ defs.generate_queue_buffers(port_names_active) }} +{% else %} + "BUFFER_QUEUE": { +{% for port in PORT_ACTIVE %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{% endif %} +} diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_defaults_t0.j2 b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..b23ec5259b21 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_defaults_t0.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11500000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "11500000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"330000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_defaults_t1.j2 b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..b23ec5259b21 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/buffers_defaults_t1.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11500000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "11500000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"330000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/port_config.ini b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/port_config.ini new file mode 100644 index 000000000000..6a9bfda3fb8b --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/port_config.ini @@ -0,0 +1,19 @@ +# name lanes speed alias +Ethernet0 0,1,2,3,4,5,6,7 400000 four00GigE0 +Ethernet8 8,9,10,11,12,13,14,15 400000 four00GigE1 +Ethernet16 16,17,18,19,20,21,22,23 400000 four00GigE2 +Ethernet24 24,25,26,27,28,29,30,31 400000 four00GigE2 +Ethernet32 32,33,34,35,36,37,38,39 400000 four00GigE3 +Ethernet40 40,41,42,43,44,45,46,47 400000 four00GigE4 +Ethernet48 48,49,50,51,52,53,54,55 400000 four00GigE5 +Ethernet56 56,57,58,59,60,61,62,63 400000 four00GigE6 +Ethernet64 64,65,66,67,68,69,70,71 400000 four00GigE7 +Ethernet72 72,73,74,75,76,77,78,79 400000 four00GigE8 +Ethernet80 80,81,82,83,84,85,86,87 400000 four00GigE9 +Ethernet88 88,89,90,91,92,93,94,95 400000 four00GigE10 +Ethernet96 96,97,98,99,100,101,102,103 400000 four00GigE11 +Ethernet104 104,105,106,107,108,109,110,111 400000 four00GigE12 +Ethernet112 112,113,114,115,116,117,118,119 400000 four00GigE13 +Ethernet120 120,121,122,123,124,125,126,127 400000 four00GigE14 +Ethernet128 128 10000 tenGigE128 +Ethernet129 129 10000 tenGigE129 diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/profile.ini b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/profile.ini new file mode 100644 index 000000000000..16847ec03ae2 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/profile.ini @@ -0,0 +1,2 @@ +switchMacAddress=00:01:02:03:04:05 +apPortListWithCableLen=000:1 008:1 016:1 024:1 032:1 040:1 048:1 056:1 064:1 072:1 080:1 088:1 096:1 104:1 112:1 120:1 diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/qos.json.j2 b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/sai.profile b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/sai.profile new file mode 100644 index 000000000000..6a2438f50180 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/db98cx8580_16cd/sai.profile @@ -0,0 +1,3 @@ +mode=1 +hwId=FALCON16x400G +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/profile.ini diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/default_sku b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/default_sku new file mode 100644 index 000000000000..7908e555c02c --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/default_sku @@ -0,0 +1 @@ +db98cx8580_16cd t1 diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/plugins/eeprom.py b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/plugins/eeprom.py new file mode 100644 index 000000000000..71f05c5b70f5 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/plugins/eeprom.py @@ -0,0 +1,11 @@ +try: + from sonic_eeprom import eeprom_tlvinfo +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/etc/sonic/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/plugins/sfputil.py b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/plugins/sfputil.py new file mode 100644 index 000000000000..4463e687e695 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/plugins/sfputil.py @@ -0,0 +1,251 @@ +try: + import os + import time + import sys + import re + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +if sys.version_info[0] < 3: + import commands +else: + import subprocess as commands + +smbus_present = 1 + +try: + import smbus +except ImportError as e: + smbus_present = 0 + + +class SfpUtil(SfpUtilBase): + """Platform specific sfputil class""" + _port_start = 1 + _port_end = 132 + ports_in_block = 132 + + _port_to_eeprom_mapping = {} + + _qsfp_ports = list(range(_port_start, ports_in_block + 1)) + + def __init__(self): + os.system("modprobe i2c-dev") + if not os.path.exists("/sys/bus/i2c/devices/0-0050"): + os.system("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-0/new_device") + + eeprom_path = '/sys/bus/i2c/devices/0-0050/eeprom' + # for x in range(self.port _start, self.port_end +1): + x = self.port_start + while(x < self.port_end+1): + self.port_to_eeprom_mapping[x] = eeprom_path + x = x + 1 + 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 + + port_ps = "/sys/bus/i2c/devices/0-0050/sfp_port_reset" + + try: + reg_file = open(port_ps, 'w') + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + # toggle reset + reg_file.seek(0) + reg_file.write('1') + time.sleep(1) + reg_file.seek(0) + reg_file.write('0') + reg_file.close() + return True + + def set_low_power_mode(self, port_nuM, lpmode): + raise NotImplementedError + + def get_low_power_mode(self, port_num): + raise NotImplementedError + + def i2c_get(self, device_addr, offset): + status = 0 + if smbus_present == 0: + x = "i2cget -y 0 " + hex(device_addr) + " " + hex(offset) + cmdstatus, status = commands.getstatusoutput(x) + if cmdstatus != 0: + return cmdstatus + status = int(status, 16) + else: + bus = smbus.SMBus(0) + status = bus.read_byte_data(device_addr, offset) + return status + + def i2c_set(self, device_addr, offset, value): + if smbus_present == 0: + cmd = "i2cset -y 0 " + hex(device_addr) + " " + hex(offset) + " " + hex(value) + os.system(cmd) + else: + bus = smbus.SMBus(0) + bus.write_byte_data(device_addr, offset, value) + + 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 + else: + self.i2c_set(0x70, 0, 0) + self.i2c_set(0x71, 0, 0) + self.i2c_set(0x74, 0, 0) + reg = (port_num)/8 + offset = reg % 8 + if offset >= 4: + offset = offset-4 + elif offset < 4: + offset = offset+4 + bin_offset = 1 << offset + + if port_num >= 0 and port_num <= 63: + device_reg = 0x70 + elif port_num >= 64 and port_num <= 127: + device_reg = 0x71 + elif port_num >= 128 and port_num <= 131: + device_reg = 0x74 + + #print "i2c %d %x %x" % (port_num, device_reg, bin_offset) + self.i2c_set(device_reg, 0, bin_offset) + path = "/sys/bus/i2c/devices/0-0050/eeprom" + try: + reg_file = open(path) + reg_file.seek(0o1) + reg_file.read(0o2) + except IOError as e: + return False + + return True + + def read_porttab_mappings(self, porttabfile): + #print("I am in porttab_mappings") + logical = [] + logical_to_bcm = {} + logical_to_physical = {} + physical_to_logical = {} + last_fp_port_index = 0 + last_portname = "" + first = 1 + port_pos_in_file = 0 + parse_fmt_port_config_ini = False + + try: + f = open(porttabfile) + except: + raise + + parse_fmt_port_config_ini = (os.path.basename(porttabfile) == "port_config.ini") + # Read the porttab file and generate dicts + # with mapping for future reference. + # + # TODO: Refactor this to use the portconfig.py module that now + # exists as part of the sonic-config-engine package. + title = [] + for line in f: + line.strip() + if re.search("^#", line) is not None: + # The current format is: # name lanes alias index speed + # Where the ordering of the columns can vary + title = line.split()[1:] + continue + #print title + + # Parsing logic for 'port_config.ini' file + if (parse_fmt_port_config_ini): + # bcm_port is not explicitly listed in port_config.ini format + # Currently we assume ports are listed in numerical order according to bcm_port + # so we use the port's position in the file (zero-based) as bcm_port + portname = line.split()[0] + + bcm_port = str(port_pos_in_file) + + if "index" in title: + fp_port_index = int(line.split()[title.index("index")]) + # Leave the old code for backward compatibility + # if len(line.split()) >= 4: + # fp_port_index = (line.split()[3]) + # print(fp_port_index) + else: + fp_port_index = portname.split("Ethernet").pop() + fp_port_index = int(fp_port_index.split("s").pop(0))+1 + else: # Parsing logic for older 'portmap.ini' file + (portname, bcm_port) = line.split("=")[1].split(",")[:2] + + fp_port_index = portname.split("Ethernet").pop() + fp_port_index = int(fp_port_index.split("s").pop(0))+1 + + if ((len(self.sfp_ports) > 0) and (fp_port_index not in self.sfp_ports)): + continue + + if first == 1: + # Initialize last_[physical|logical]_port + # to the first valid port + last_fp_port_index = fp_port_index + last_portname = portname + first = 0 + + logical.append(portname) + + logical_to_bcm[portname] = "xe" + bcm_port + logical_to_physical[portname] = [fp_port_index] + if physical_to_logical.get(fp_port_index) is None: + physical_to_logical[fp_port_index] = [portname] + else: + physical_to_logical[fp_port_index].append( + portname) + + if (fp_port_index - last_fp_port_index) > 1: + # last port was a gang port + for p in range(last_fp_port_index+1, fp_port_index): + logical_to_physical[last_portname].append(p) + if physical_to_logical.get(p) is None: + physical_to_logical[p] = [last_portname] + else: + physical_to_logical[p].append(last_portname) + + last_fp_port_index = fp_port_index + last_portname = portname + + port_pos_in_file += 1 + + self.logical = logical + self.logical_to_bcm = logical_to_bcm + self.logical_to_physical = logical_to_physical + self.physical_to_logical = physical_to_logical + + # print(self.logical_to_physical) + '''print("logical: " + self.logical) + print("logical to bcm: " + self.logical_to_bcm) + print("logical to physical: " + self.logical_to_physical) + print("physical to logical: " + self.physical_to_logical)''' + #print("exiting port_tab_mappings") + + @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 + + @property + def get_transceiver_change_event(self): + raise NotImplementedError diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/pmon_daemon_control.json b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/buffers_defaults_t0.j2 b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..19be04b5ca4d --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/buffers_defaults_t0.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "23000000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "23000000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"340000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/buffers_defaults_t1.j2 b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..19be04b5ca4d --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/buffers_defaults_t1.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "23000000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "23000000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"340000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/port_config.ini b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/port_config.ini new file mode 100644 index 000000000000..6d8b5d0a13df --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/port_config.ini @@ -0,0 +1,34 @@ +# name lanes speed alias +Ethernet0 0 25000 twenty5GigE0 +Ethernet1 1 25000 twenty5GigE1 +Ethernet2 2 25000 twenty5GigE2 +Ethernet3 3 25000 twenty5GigE3 +Ethernet4 4 25000 twenty5GigE4 +Ethernet5 5 25000 twenty5GigE5 +Ethernet6 6 25000 twenty5GigE6 +Ethernet7 7 25000 twenty5GigE7 +Ethernet8 8 25000 twenty5GigE8 +Ethernet9 9 25000 twenty5GigE9 +Ethernet10 10 25000 twenty5GigE10 +Ethernet11 11 25000 twenty5GigE11 +Ethernet12 12 25000 twenty5GigE12 +Ethernet13 13 25000 twenty5GigE13 +Ethernet14 14 25000 twenty5GigE14 +Ethernet15 15 25000 twenty5GigE15 +Ethernet16 16 25000 twenty5GigE16 +Ethernet17 17 25000 twenty5GigE17 +Ethernet18 18 25000 twenty5GigE18 +Ethernet19 19 25000 twenty5GigE19 +Ethernet20 20 25000 twenty5GigE20 +Ethernet21 21 25000 twenty5GigE21 +Ethernet22 22 25000 twenty5GigE22 +Ethernet23 23 25000 twenty5GigE23 +Ethernet24 24 25000 twenty5GigE24 +Ethernet25 25 25000 twenty5GigE25 +Ethernet26 26 25000 twenty5GigE26 +Ethernet27 27 25000 twenty5GigE27 +Ethernet28 28 25000 twenty5GigE28 +Ethernet29 29 25000 twenty5GigE29 +Ethernet30 30 25000 twenty5GigE30 +Ethernet31 31 25000 twenty5GigE31 +Ethernet32 32 10000 tenGigE32 diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/profile.ini b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/profile.ini new file mode 100644 index 000000000000..487e80dcbd70 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/profile.ini @@ -0,0 +1,2 @@ +switchMacAddress=00:01:02:03:04:05 +apPortListWithCableLen=000:1 001:1 002:1 003:1 004:1 005:1 006:1 007:1 008:1 009:1 010:1 011:1 012:1 013:1 014:1 015:1 016:1 017:1 018:1 019:1 020:1 021:1 022:1 023:1 024:1 025:1 026:1 027:1 028:1 029:1 030:1 031:1 032:1 diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/sai.profile b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/sai.profile new file mode 100644 index 000000000000..dd6f707a81ab --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32X25G/sai.profile @@ -0,0 +1,3 @@ +mode=1 +hwId=FALCON32X25G +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/profile.ini diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/buffers_defaults_t0.j2 b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..19be04b5ca4d --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/buffers_defaults_t0.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "23000000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "23000000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"340000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/buffers_defaults_t1.j2 b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..19be04b5ca4d --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/buffers_defaults_t1.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "23000000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "23000000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"340000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/port_config.ini b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/port_config.ini new file mode 100644 index 000000000000..62dd91ba8869 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/port_config.ini @@ -0,0 +1,34 @@ +# name lanes speed alias +Ethernet0 0,1,2,3,4,5,6,7 400000 four00GigE0 +Ethernet8 8,9,10,11,12,13,14,15 400000 four00GigE8 +Ethernet16 16,17,18,19,20,21,22,23 400000 four00GigE16 +Ethernet24 24,25,26,27,28,29,30,31 400000 four00GigE24 +Ethernet32 32,33,34,35,36,37,38,39 400000 four00GigE32 +Ethernet40 40,41,42,43,44,45,46,47 400000 four00GigE40 +Ethernet48 48,49,50,51,52,53,54,55 400000 four00GigE48 +Ethernet56 56,57,58,59,60,61,62,63 400000 four00GigE56 +Ethernet64 64,65,66,67,68,69,70,71 400000 four00GigE64 +Ethernet72 72,73,74,75,76,77,78,79 400000 four00GigE72 +Ethernet80 80,81,82,83,84,85,86,87 400000 four00GigE80 +Ethernet88 88,89,90,91,92,93,94,95 400000 four00GigE88 +Ethernet96 96,97,98,99,100,101,102,103 400000 four00GigE96 +Ethernet104 104,105,106,107,108,109,110,111 400000 four00GigE104 +Ethernet112 112,113,114,115,116,117,118,119 400000 four00GigE112 +Ethernet120 120,121,122,123,124,125,126,127 400000 four00GigE120 +Ethernet128 128,129,130,131,132,133,134,135 400000 four00GigE128 +Ethernet136 136,137,138,139,140,141,142,143 400000 four00GigE136 +Ethernet144 144,145,146,147,148,149,150,151 400000 four00GigE144 +Ethernet152 152,153,154,155,156,157,158,159 400000 four00GigE152 +Ethernet160 160,161,162,163,164,165,166,167 400000 four00GigE160 +Ethernet168 168,169,170,171,172,173,174,175 400000 four00GigE168 +Ethernet176 176,177,178,179,180,181,182,183 400000 four00GigE176 +Ethernet184 184,185,186,187,188,189,190,191 400000 four00GigE184 +Ethernet192 192,193,194,195,196,197,198,199 400000 four00GigE192 +Ethernet200 200,201,202,203,204,205,206,207 400000 four00GigE200 +Ethernet208 208,209,210,211,212,213,214,215 400000 four00GigE208 +Ethernet216 216,217,218,219,220,221,222,223 400000 four00GigE216 +Ethernet224 224,225,226,227,228,229,230,231 400000 four00GigE224 +Ethernet232 232,233,234,235,236,237,238,239 400000 four00GigE232 +Ethernet240 240,241,242,243,244,245,246,247 400000 four00GigE240 +Ethernet248 248,249,250,251,252,253,254,255 400000 four00GigE248 +Ethernet256 256 10000 tenGigE256 diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/profile.ini b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/profile.ini new file mode 100644 index 000000000000..2813bbd363f8 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/profile.ini @@ -0,0 +1,2 @@ +switchMacAddress=00:01:02:03:04:05 +apPortListWithCableLen=000:1 008:1 016:1 024:1 032:1 040:1 048:1 056:1 064:1 072:1 080:1 088:1 096:1 104:1 112:1 120:1 128:1 136:1 144:1 152:1 160:1 168:1 176:1 184:1 192:1 200:1 208:1 216:1 224:1 232:1 240:1 248:1 256:1 diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/sai.profile b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/sai.profile new file mode 100644 index 000000000000..6dc6f35fed4e --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/FALCON32x400G/sai.profile @@ -0,0 +1,3 @@ +mode=1 +hwId=FALCON32x400G +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/profile.ini diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers.json.j2 b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers.json.j2 new file mode 100644 index 000000000000..a9a01d707ebf --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers.json.j2 @@ -0,0 +1 @@ +{%- include 'buffers_config.j2' %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_config.j2 b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_config.j2 new file mode 100644 index 000000000000..5431fbe72c1f --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_config.j2 @@ -0,0 +1,165 @@ +{%- macro set_default_topology() %} +{%- if default_topo is defined %} +{{ default_topo }} +{%- else %} +def +{%- endif %} +{%- endmacro -%} + +{# Determine device topology and filename postfix #} +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- if 'torrouter' in switch_role.lower() %} +{%- set filename_postfix = 't0' %} +{%- elif 'leafrouter' in switch_role.lower() %} +{%- set filename_postfix = 't1' %} +{%- else %} +{%- set filename_postfix = set_default_topology() %} +{%- endif %} +{%- else %} +{%- set filename_postfix = set_default_topology() %} +{%- set switch_role = '' %} +{%- endif -%} + +{# Import default values from device HWSKU folder #} +{%- import 'buffers_defaults_%s.j2' % filename_postfix as defs %} + +{%- set default_cable = defs.default_cable -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{%- if defs.ports2cable is defined %} + {%- set ports2cable = defs.ports2cable %} +{%- else %} + {%- set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } + -%} +{%- endif %} + +{%- macro cable_length(port_name) %} + {%- set cable_len = [] %} + {%- for local_port in DEVICE_NEIGHBOR %} + {%- if local_port == port_name %} + {%- if DEVICE_NEIGHBOR_METADATA is defined and 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 %} + {%- if 'torrouter' in switch_role.lower() %} + {%- for local_port in VLAN_MEMBER %} + {%- if local_port[1] == port_name %} + {%- set roles3 = switch_role + '_' + 'server' %} + {%- set roles3 = roles3 | lower %} + {%- if roles3 in ports2cable %} + {%- if cable_len.append(ports2cable[roles3]) %}{% endif %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- endif %} +{%- endmacro %} + +{%- set PORT_ALL = [] %} + +{%- if PORT is not defined %} + {%- if defs.generate_port_lists(PORT_ALL) %} {% endif %} +{%- else %} + {%- for port in PORT %} + {%- if PORT_ALL.append(port) %}{%- endif %} + {%- endfor %} +{%- endif %} + +{%- set PORT_ACTIVE = [] %} +{%- if DEVICE_NEIGHBOR is not defined %} + {%- set PORT_ACTIVE = PORT_ALL %} +{%- else %} + {%- for port in DEVICE_NEIGHBOR.keys() %} + {%- if PORT_ACTIVE.append(port) %}{%- endif %} + {%- endfor %} +{%- endif %} + +{%- set port_names_list_active = [] %} +{%- for port in PORT_ACTIVE %} + {%- if port_names_list_active.append(port) %}{%- endif %} +{%- endfor %} +{%- set port_names_active = port_names_list_active | join(',') %} + +{ + "CABLE_LENGTH": { + "AZURE": { + {% for port in PORT_ALL %} + {%- set cable = cable_length(port) %} + "{{ port }}": "{{ cable }}"{%- if not loop.last %},{% endif %} + + {% endfor %} + } + }, + +{% if defs.generate_buffer_pool_and_profiles is defined %} +{{ defs.generate_buffer_pool_and_profiles() }} +{% endif %} + +{%- if defs.generate_profile_lists is defined %} +{{ defs.generate_profile_lists(port_names_active) }}, +{% endif %} + +{%- if defs.generate_pg_profils is defined %} +{{ defs.generate_pg_profils(port_names_active) }} +{% else %} + "BUFFER_PG": { +{% for port in PORT_ACTIVE %} + "{{ port }}|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, +{% endif %} + +{% if defs.generate_queue_buffers is defined %} +{{ defs.generate_queue_buffers(port_names_active) }} +{% else %} + "BUFFER_QUEUE": { +{% for port in PORT_ACTIVE %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{% endif %} +} diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_defaults_t0.j2 b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..19be04b5ca4d --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_defaults_t0.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "23000000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "23000000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"340000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_defaults_t1.j2 b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..19be04b5ca4d --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/buffers_defaults_t1.j2 @@ -0,0 +1,36 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "23000000", + "type": "ingress", + "mode": "dynamic" + }, + "egress_pool": { + "size": "23000000", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "mode": "static", + "size":"340000", + "static_th":"0" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/port_config.ini b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/port_config.ini new file mode 100644 index 000000000000..62dd91ba8869 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/port_config.ini @@ -0,0 +1,34 @@ +# name lanes speed alias +Ethernet0 0,1,2,3,4,5,6,7 400000 four00GigE0 +Ethernet8 8,9,10,11,12,13,14,15 400000 four00GigE8 +Ethernet16 16,17,18,19,20,21,22,23 400000 four00GigE16 +Ethernet24 24,25,26,27,28,29,30,31 400000 four00GigE24 +Ethernet32 32,33,34,35,36,37,38,39 400000 four00GigE32 +Ethernet40 40,41,42,43,44,45,46,47 400000 four00GigE40 +Ethernet48 48,49,50,51,52,53,54,55 400000 four00GigE48 +Ethernet56 56,57,58,59,60,61,62,63 400000 four00GigE56 +Ethernet64 64,65,66,67,68,69,70,71 400000 four00GigE64 +Ethernet72 72,73,74,75,76,77,78,79 400000 four00GigE72 +Ethernet80 80,81,82,83,84,85,86,87 400000 four00GigE80 +Ethernet88 88,89,90,91,92,93,94,95 400000 four00GigE88 +Ethernet96 96,97,98,99,100,101,102,103 400000 four00GigE96 +Ethernet104 104,105,106,107,108,109,110,111 400000 four00GigE104 +Ethernet112 112,113,114,115,116,117,118,119 400000 four00GigE112 +Ethernet120 120,121,122,123,124,125,126,127 400000 four00GigE120 +Ethernet128 128,129,130,131,132,133,134,135 400000 four00GigE128 +Ethernet136 136,137,138,139,140,141,142,143 400000 four00GigE136 +Ethernet144 144,145,146,147,148,149,150,151 400000 four00GigE144 +Ethernet152 152,153,154,155,156,157,158,159 400000 four00GigE152 +Ethernet160 160,161,162,163,164,165,166,167 400000 four00GigE160 +Ethernet168 168,169,170,171,172,173,174,175 400000 four00GigE168 +Ethernet176 176,177,178,179,180,181,182,183 400000 four00GigE176 +Ethernet184 184,185,186,187,188,189,190,191 400000 four00GigE184 +Ethernet192 192,193,194,195,196,197,198,199 400000 four00GigE192 +Ethernet200 200,201,202,203,204,205,206,207 400000 four00GigE200 +Ethernet208 208,209,210,211,212,213,214,215 400000 four00GigE208 +Ethernet216 216,217,218,219,220,221,222,223 400000 four00GigE216 +Ethernet224 224,225,226,227,228,229,230,231 400000 four00GigE224 +Ethernet232 232,233,234,235,236,237,238,239 400000 four00GigE232 +Ethernet240 240,241,242,243,244,245,246,247 400000 four00GigE240 +Ethernet248 248,249,250,251,252,253,254,255 400000 four00GigE248 +Ethernet256 256 10000 tenGigE256 diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/profile.ini b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/profile.ini new file mode 100644 index 000000000000..2813bbd363f8 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/profile.ini @@ -0,0 +1,2 @@ +switchMacAddress=00:01:02:03:04:05 +apPortListWithCableLen=000:1 008:1 016:1 024:1 032:1 040:1 048:1 056:1 064:1 072:1 080:1 088:1 096:1 104:1 112:1 120:1 128:1 136:1 144:1 152:1 160:1 168:1 176:1 184:1 192:1 200:1 208:1 216:1 224:1 232:1 240:1 248:1 256:1 diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/qos.json.j2 b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/sai.profile b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/sai.profile new file mode 100644 index 000000000000..6dc6f35fed4e --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/db98cx8580_32cd/sai.profile @@ -0,0 +1,3 @@ +mode=1 +hwId=FALCON32x400G +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/profile.ini diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/default_sku b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/default_sku new file mode 100644 index 000000000000..563676854022 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/default_sku @@ -0,0 +1 @@ +db98cx8580_32cd t1 diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/plugins/eeprom.py b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/plugins/eeprom.py new file mode 100644 index 000000000000..71f05c5b70f5 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/plugins/eeprom.py @@ -0,0 +1,11 @@ +try: + from sonic_eeprom import eeprom_tlvinfo +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/etc/sonic/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/plugins/sfputil.py b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/plugins/sfputil.py new file mode 100644 index 000000000000..b3d1ea371454 --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/plugins/sfputil.py @@ -0,0 +1,257 @@ +try: + import os + import time + import sys + import re + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +if sys.version_info[0] < 3: + import commands +else: + import subprocess as commands + +smbus_present = 1 + +try: + import smbus +except ImportError as e: + smbus_present = 0 + + +class SfpUtil(SfpUtilBase): + """Platform specific sfputil class""" + _port_start = 1 + _port_end = 257 + ports_in_block = 257 + + _port_to_eeprom_mapping = {} + + _qsfp_ports = list(range(_port_start, ports_in_block + 1)) + + def __init__(self): + os.system("modprobe i2c-dev") + if not os.path.exists("/sys/bus/i2c/devices/0-0050"): + os.system("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-0/new_device") + + eeprom_path = '/sys/bus/i2c/devices/0-0050/eeprom' + # for x in range(self.port _start, self.port_end +1): + x = self.port_start + while(x < self.port_end+1): + self.port_to_eeprom_mapping[x] = eeprom_path + x = x + 1 + 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 + + port_ps = "/sys/bus/i2c/devices/0-0050/sfp_port_reset" + + try: + reg_file = open(port_ps, 'w') + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + # toggle reset + reg_file.seek(0) + reg_file.write('1') + time.sleep(1) + reg_file.seek(0) + reg_file.write('0') + reg_file.close() + return True + + def set_low_power_mode(self, port_nuM, lpmode): + raise NotImplementedError + + def get_low_power_mode(self, port_num): + raise NotImplementedError + + def i2c_get(self, device_addr, offset): + status = 0 + if smbus_present == 0: + x = "i2cget -y 0 " + hex(device_addr) + " " + hex(offset) + cmdstatus, status = commands.getstatusoutput(x) + if cmdstatus != 0: + return cmdstatus + status = int(status, 16) + else: + bus = smbus.SMBus(0) + status = bus.read_byte_data(device_addr, offset) + return status + + def i2c_set(self, device_addr, offset, value): + if smbus_present == 0: + cmd = "i2cset -y 0 " + hex(device_addr) + " " + hex(offset) + " " + hex(value) + os.system(cmd) + else: + bus = smbus.SMBus(0) + bus.write_byte_data(device_addr, offset, value) + + 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 + else: + self.i2c_set(0x70, 0, 0) + self.i2c_set(0x71, 0, 0) + self.i2c_set(0x72, 0, 0) + self.i2c_set(0x73, 0, 0) + self.i2c_set(0x74, 0, 0) + reg = (port_num)/8 + offset = reg % 8 + if offset >= 4: + offset = offset-4 + elif offset < 4: + offset = offset+4 + bin_offset = 1 << offset + + if port_num >= 0 and port_num <= 63: + device_reg = 0x70 + elif port_num >= 64 and port_num <= 127: + device_reg = 0x71 + elif port_num >= 128 and port_num <= 191: + device_reg = 0x72 + elif port_num >= 192 and port_num <= 255: + device_reg = 0x73 + elif port_num >= 256 and port_num <= 257: + device_reg = 0x74 + + #print "i2c %d %x %x" % (port_num, device_reg, bin_offset) + self.i2c_set(device_reg, 0, bin_offset) + path = "/sys/bus/i2c/devices/0-0050/eeprom" + try: + reg_file = open(path) + reg_file.seek(0o1) + reg_file.read(0o2) + except IOError as e: + return False + + return True + + def read_porttab_mappings(self, porttabfile): + #print("I am in porttab_mappings") + logical = [] + logical_to_bcm = {} + logical_to_physical = {} + physical_to_logical = {} + last_fp_port_index = 0 + last_portname = "" + first = 1 + port_pos_in_file = 0 + parse_fmt_port_config_ini = False + + try: + f = open(porttabfile) + except: + raise + + parse_fmt_port_config_ini = (os.path.basename(porttabfile) == "port_config.ini") + # Read the porttab file and generate dicts + # with mapping for future reference. + # + # TODO: Refactor this to use the portconfig.py module that now + # exists as part of the sonic-config-engine package. + title = [] + for line in f: + line.strip() + if re.search("^#", line) is not None: + # The current format is: # name lanes alias index speed + # Where the ordering of the columns can vary + title = line.split()[1:] + continue + #print title + + # Parsing logic for 'port_config.ini' file + if (parse_fmt_port_config_ini): + # bcm_port is not explicitly listed in port_config.ini format + # Currently we assume ports are listed in numerical order according to bcm_port + # so we use the port's position in the file (zero-based) as bcm_port + portname = line.split()[0] + + bcm_port = str(port_pos_in_file) + + if "index" in title: + fp_port_index = int(line.split()[title.index("index")]) + # Leave the old code for backward compatibility + # if len(line.split()) >= 4: + # fp_port_index = (line.split()[3]) + # print(fp_port_index) + else: + fp_port_index = portname.split("Ethernet").pop() + fp_port_index = int(fp_port_index.split("s").pop(0))+1 + else: # Parsing logic for older 'portmap.ini' file + (portname, bcm_port) = line.split("=")[1].split(",")[:2] + + fp_port_index = portname.split("Ethernet").pop() + fp_port_index = int(fp_port_index.split("s").pop(0))+1 + + if ((len(self.sfp_ports) > 0) and (fp_port_index not in self.sfp_ports)): + continue + + if first == 1: + # Initialize last_[physical|logical]_port + # to the first valid port + last_fp_port_index = fp_port_index + last_portname = portname + first = 0 + + logical.append(portname) + + logical_to_bcm[portname] = "xe" + bcm_port + logical_to_physical[portname] = [fp_port_index] + if physical_to_logical.get(fp_port_index) is None: + physical_to_logical[fp_port_index] = [portname] + else: + physical_to_logical[fp_port_index].append( + portname) + + if (fp_port_index - last_fp_port_index) > 1: + # last port was a gang port + for p in range(last_fp_port_index+1, fp_port_index): + logical_to_physical[last_portname].append(p) + if physical_to_logical.get(p) is None: + physical_to_logical[p] = [last_portname] + else: + physical_to_logical[p].append(last_portname) + + last_fp_port_index = fp_port_index + last_portname = portname + + port_pos_in_file += 1 + + self.logical = logical + self.logical_to_bcm = logical_to_bcm + self.logical_to_physical = logical_to_physical + self.physical_to_logical = physical_to_logical + + # print(self.logical_to_physical) + '''print("logical: " + self.logical) + print("logical to bcm: " + self.logical_to_bcm) + print("logical to physical: " + self.logical_to_physical) + print("physical to logical: " + self.physical_to_logical)''' + #print("exiting port_tab_mappings") + + @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 + + @property + def get_transceiver_change_event(self): + raise NotImplementedError diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/pmon_daemon_control.json b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} diff --git a/device/marvell/x86_64-marvell_slm5401_54x-r0/plugins/eeprom.py b/device/marvell/x86_64-marvell_slm5401_54x-r0/plugins/eeprom.py index 7681caafeef4..951384d5e37d 100755 --- a/device/marvell/x86_64-marvell_slm5401_54x-r0/plugins/eeprom.py +++ b/device/marvell/x86_64-marvell_slm5401_54x-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -11,14 +8,16 @@ 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") +except ImportError as 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/1-0057/eeprom" - #Two i2c buses might get flipped order, check them both. + # Two i2c buses might get flipped order, check them both. if not os.path.exists(self.eeprom_path): self.eeprom_path = "/sys/bus/i2c/devices/0-0057/eeprom" super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/marvell/x86_64-marvell_slm5401_54x-r0/plugins/sfputil.py b/device/marvell/x86_64-marvell_slm5401_54x-r0/plugins/sfputil.py index fa706867a585..b1d356e393ee 100755 --- a/device/marvell/x86_64-marvell_slm5401_54x-r0/plugins/sfputil.py +++ b/device/marvell/x86_64-marvell_slm5401_54x-r0/plugins/sfputil.py @@ -1,10 +1,8 @@ -#!/usr/bin/env python - try: import time from sonic_sfp.sfputilbase import SfpUtilBase -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class sfputil(SfpUtilBase): @@ -16,41 +14,41 @@ class sfputil(SfpUtilBase): port_to_eeprom_mapping = {} port_to_i2c_mapping = { - 9 : 18, - 10 : 19, - 11 : 20, - 12 : 21, - 1 : 22, - 2 : 23, - 3 : 24, - 4 : 25, - 6 : 26, - 5 : 27, - 8 : 28, - 7 : 29, - 13 : 30, - 14 : 31, - 15 : 32, - 16 : 33, - 17 : 34, - 18 : 35, - 19 : 36, - 20 : 37, - 25 : 38, - 26 : 39, - 27 : 40, - 28 : 41, - 29 : 42, - 30 : 43, - 31 : 44, - 32 : 45, - 21 : 46, - 22 : 47, - 23 : 48, - 24 : 49, + 9: 18, + 10: 19, + 11: 20, + 12: 21, + 1: 22, + 2: 23, + 3: 24, + 4: 25, + 6: 26, + 5: 27, + 8: 28, + 7: 29, + 13: 30, + 14: 31, + 15: 32, + 16: 33, + 17: 34, + 18: 35, + 19: 36, + 20: 37, + 25: 38, + 26: 39, + 27: 40, + 28: 41, + 29: 42, + 30: 43, + 31: 44, + 32: 45, + 21: 46, + 22: 47, + 23: 48, + 24: 49, } - _qsfp_ports = range(0, ports_in_block + 1) + _qsfp_ports = list(range(0, ports_in_block + 1)) def __init__(self): # Override port_to_eeprom_mapping for class initialization @@ -67,14 +65,14 @@ def reset(self, port_num): path = "/sys/bus/i2c/devices/{0}-0050/sfp_port_reset" port_ps = path.format(self.port_to_i2c_mapping[port_num+1]) - + try: reg_file = open(port_ps, 'w') except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False - #toggle reset + # toggle reset reg_file.seek(0) reg_file.write('1') time.sleep(1) @@ -88,7 +86,7 @@ def set_low_power_mode(self, port_nuM, lpmode): def get_low_power_mode(self, port_num): raise NotImplementedErro - + def get_presence(self, port_num): # Check for invalid port_num if port_num < self._port_start or port_num > self._port_end: @@ -97,11 +95,10 @@ def get_presence(self, port_num): path = "/sys/bus/i2c/devices/{0}-0050/sfp_is_present" port_ps = path.format(self.port_to_i2c_mapping[port_num+1]) - 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" % str(e)) return False reg_value = reg_file.readline().rstrip() @@ -117,14 +114,14 @@ def port_start(self): @property def port_end(self): return self._port_end - + @property def qsfp_ports(self): - return range(0, self.ports_in_block + 1) + return list(range(0, self.ports_in_block + 1)) - @property + @property def port_to_eeprom_mapping(self): - return self._port_to_eeprom_mapping + return self._port_to_eeprom_mapping def get_transceiver_change_event(self): """ diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/pcie.yaml b/device/mellanox/x86_64-mlnx_lssn2700-r0/pcie.yaml new file mode 120000 index 000000000000..f739a7e8ec35 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/pcie.yaml @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/pcie.yaml \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_lssn2700-r0/system_health_monitoring_config.json new file mode 120000 index 000000000000..98df66c27ca5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2010-r0/ACS-MSN2010/buffers_dynamic.json.j2 b/device/mellanox/x86_64-mlnx_msn2010-r0/ACS-MSN2010/buffers_dynamic.json.j2 new file mode 120000 index 000000000000..8c4117c66214 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2010-r0/ACS-MSN2010/buffers_dynamic.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_dynamic.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2010-r0/ACS-MSN2010/hwsku.json b/device/mellanox/x86_64-mlnx_msn2010-r0/ACS-MSN2010/hwsku.json new file mode 100644 index 000000000000..7597b2c9a924 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2010-r0/ACS-MSN2010/hwsku.json @@ -0,0 +1,70 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet4": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet8": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet12": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet16": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet20": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet24": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet28": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet32": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet36": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet40": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet44": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet48": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet52": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet56": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet60": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet64": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet68": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet72": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet76": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet80": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet84": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn2010-r0/ACS-MSN2010/port_config.ini b/device/mellanox/x86_64-mlnx_msn2010-r0/ACS-MSN2010/port_config.ini index 2bd7aef02e1f..f9fa81669a13 100644 --- a/device/mellanox/x86_64-mlnx_msn2010-r0/ACS-MSN2010/port_config.ini +++ b/device/mellanox/x86_64-mlnx_msn2010-r0/ACS-MSN2010/port_config.ini @@ -1,23 +1,23 @@ # name lanes index -Ethernet0 0 0 -Ethernet4 4 1 -Ethernet8 8 2 -Ethernet12 12 3 -Ethernet16 16 4 -Ethernet20 20 5 -Ethernet24 24 6 -Ethernet28 28 7 -Ethernet32 32 8 -Ethernet36 36 9 -Ethernet40 40 10 -Ethernet44 44 11 -Ethernet48 48 12 -Ethernet52 52 13 -Ethernet56 56 14 -Ethernet60 60 15 -Ethernet64 64 16 -Ethernet68 68 17 -Ethernet72 72,73,74,75 18 -Ethernet76 76,77,78,79 19 -Ethernet80 80,81,82,83 20 -Ethernet84 84,85,86,87 21 +Ethernet0 0 1 +Ethernet4 4 2 +Ethernet8 8 3 +Ethernet12 12 4 +Ethernet16 16 5 +Ethernet20 20 6 +Ethernet24 24 7 +Ethernet28 28 8 +Ethernet32 32 9 +Ethernet36 36 10 +Ethernet40 40 11 +Ethernet44 44 12 +Ethernet48 48 13 +Ethernet52 52 14 +Ethernet56 56 15 +Ethernet60 60 16 +Ethernet64 64 17 +Ethernet68 68 18 +Ethernet72 72,73,74,75 19 +Ethernet76 76,77,78,79 20 +Ethernet80 80,81,82,83 21 +Ethernet84 84,85,86,87 22 diff --git a/device/mellanox/x86_64-mlnx_msn2010-r0/pcie.yaml b/device/mellanox/x86_64-mlnx_msn2010-r0/pcie.yaml new file mode 100644 index 000000000000..ca73122aaa81 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2010-r0/pcie.yaml @@ -0,0 +1,83 @@ +- bus: '00' + dev: '00' + fn: '0' + id: 1f0b + name: 'Host bridge: Intel Corporation Atom processor C2000 SoC Transaction Router + (rev 02)' +- bus: '00' + dev: '01' + fn: '0' + id: 1f10 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 1 (rev + 02)' +- bus: '00' + dev: '02' + fn: '0' + id: 1f11 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 2 (rev + 02)' +- bus: '00' + dev: '03' + fn: '0' + id: 1f12 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 3 (rev + 02)' +- bus: '00' + dev: 0b + fn: '0' + id: 1f18 + name: 'Co-processor: Intel Corporation Atom processor C2000 QAT (rev 02)' +- bus: '00' + dev: 0e + fn: '0' + id: 1f14 + name: 'Host bridge: Intel Corporation Atom processor C2000 RAS (rev 02)' +- bus: '00' + dev: 0f + fn: '0' + id: 1f16 + name: 'IOMMU: Intel Corporation Atom processor C2000 RCEC (rev 02)' +- bus: '00' + dev: '13' + fn: '0' + id: 1f15 + name: 'System peripheral: Intel Corporation Atom processor C2000 SMBus 2.0 (rev + 02)' +- bus: '00' + dev: '14' + fn: '0' + id: 1f41 + name: 'Ethernet controller: Intel Corporation Ethernet Connection I354 (rev 03)' +- bus: '00' + dev: '16' + fn: '0' + id: 1f2c + name: 'USB controller: Intel Corporation Atom processor C2000 USB Enhanced Host + Controller (rev 02)' +- bus: '00' + dev: '17' + fn: '0' + id: 1f22 + name: 'SATA controller: Intel Corporation Atom processor C2000 AHCI SATA2 Controller + (rev 02)' +- bus: '00' + dev: '18' + fn: '0' + id: 1f32 + name: 'SATA controller: Intel Corporation Atom processor C2000 AHCI SATA3 Controller + (rev 02)' +- bus: '00' + dev: 1f + fn: '0' + id: 1f38 + name: 'ISA bridge: Intel Corporation Atom processor C2000 PCU (rev 02)' +- bus: '00' + dev: 1f + fn: '3' + id: 1f3c + name: 'SMBus: Intel Corporation Atom processor C2000 PCU SMBus (rev 02)' +- bus: '01' + dev: '00' + fn: '0' + id: cb84 + name: 'Ethernet controller: Mellanox Technologies MT52100' diff --git a/device/mellanox/x86_64-mlnx_msn2010-r0/platform.json b/device/mellanox/x86_64-mlnx_msn2010-r0/platform.json new file mode 100644 index 000000000000..d80e66f9e011 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2010-r0/platform.json @@ -0,0 +1,136 @@ +{ + "interfaces": { + "Ethernet0": { + "index": "1", + "lanes": "0", + "alias_at_lanes": "etp1", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet4": { + "index": "2", + "lanes": "4", + "alias_at_lanes": "etp2", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet8": { + "index": "3", + "lanes": "8", + "alias_at_lanes": "etp3", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet12": { + "index": "4", + "lanes": "12", + "alias_at_lanes": "etp4", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet16": { + "index": "5", + "lanes": "16", + "alias_at_lanes": "etp5", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet20": { + "index": "6", + "lanes": "20", + "alias_at_lanes": "etp6", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet24": { + "index": "7", + "lanes": "24", + "alias_at_lanes": "etp7", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet28": { + "index": "8", + "lanes": "28", + "alias_at_lanes": "etp8", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet32": { + "index": "9", + "lanes": "32", + "alias_at_lanes": "etp9", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet36": { + "index": "10", + "lanes": "36", + "alias_at_lanes": "etp10", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet40": { + "index": "11", + "lanes": "40", + "alias_at_lanes": "etp11", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet44": { + "index": "12", + "lanes": "44", + "alias_at_lanes": "etp12", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet48": { + "index": "13", + "lanes": "48", + "alias_at_lanes": "etp13", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet52": { + "index": "14", + "lanes": "52", + "alias_at_lanes": "etp14", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet56": { + "index": "15", + "lanes": "56", + "alias_at_lanes": "etp15", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet60": { + "index": "16", + "lanes": "60", + "alias_at_lanes": "etp16", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet64": { + "index": "17", + "lanes": "64", + "alias_at_lanes": "etp17", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet68": { + "index": "18", + "lanes": "68", + "alias_at_lanes": "etp18", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet72": { + "index": "19,19,19,19", + "lanes": "72,73,74,75", + "alias_at_lanes": "etp19a, etp19b, etp19c, etp19d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G],4x25G[10G]" + }, + "Ethernet76": { + "index": "20,20,20,20", + "lanes": "76,77,78,79", + "alias_at_lanes": "etp20a, etp20b, etp20c, etp20d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G],4x25G[10G]" + }, + "Ethernet80": { + "index": "21,21,21,21", + "lanes": "80,81,82,83", + "alias_at_lanes": "etp21a, etp21b, etp21c, etp21d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G],4x25G[10G]" + }, + "Ethernet84": { + "index": "22,22,22,22", + "lanes": "84,85,86,87", + "alias_at_lanes": "etp22a, etp22b, etp22c, etp22d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G],4x25G[10G]" + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn2010-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn2010-r0/platform_components.json index 775c6e22cf5c..a5cd5b152c46 100644 --- a/device/mellanox/x86_64-mlnx_msn2010-r0/platform_components.json +++ b/device/mellanox/x86_64-mlnx_msn2010-r0/platform_components.json @@ -1,9 +1,12 @@ { "chassis": { - "x86_64-mlnx_msn2010-r0": { + "MSN2010": { "component": { + "ONIE": { }, + "SSD": { }, "BIOS": { }, - "CPLD": { } + "CPLD1": { }, + "CPLD2": { } } } } diff --git a/device/mellanox/x86_64-mlnx_msn2010-r0/plugins/psuutil.py b/device/mellanox/x86_64-mlnx_msn2010-r0/plugins/psuutil.py index a51a9b07292c..0d864849dc48 100644 --- a/device/mellanox/x86_64-mlnx_msn2010-r0/plugins/psuutil.py +++ b/device/mellanox/x86_64-mlnx_msn2010-r0/plugins/psuutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Mellanox # @@ -13,7 +11,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" diff --git a/device/mellanox/x86_64-mlnx_msn2010-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn2010-r0/sensors.conf index 3b68f775df2d..7f5b023afec6 100644 --- a/device/mellanox/x86_64-mlnx_msn2010-r0/sensors.conf +++ b/device/mellanox/x86_64-mlnx_msn2010-r0/sensors.conf @@ -1,92 +1,49 @@ +################################################################################ +# Copyright (c) 2020 Mellanox Technologies +# +# Platform specific sensors config for SN2010 +################################################################################ + +# Temperature sensors bus "i2c-2" "i2c-1-mux (chan_id 1)" -chip "mlxsw-i2c-2-48" - label temp1 "ASIC Temp" + chip "mlxsw-i2c-*-48" + label temp1 "Ambient ASIC Temp" bus "i2c-7" "i2c-1-mux (chan_id 6)" -chip "lm75-*" - label temp1 "Ambient Port Temp" + chip "lm75-i2c-*-4a" + label temp1 "Ambient Port Side Temp (air exhaust)" + chip "lm75-i2c-*-4b" + label temp1 "Ambient Fan Side Temp (air intake)" +# Power supplies bus "i2c-5" "i2c-1-mux (chan_id 4)" -chip "tps53679-*" - label vin "TPS vin" - label vout1 "TPS vout1" - label vout2 "TPS vout2" - label temp1 "TPS Temp1" - label temp2 "TPS Temp2" - label pout1 "TPS pouti1" - label pout2 "TPS pout2" - label iout1 "TPS iout1" - label iout2 "TPS iout2" - -chip "mlxsw-*" - ignore temp2 - ignore temp3 - ignore temp4 - ignore temp5 - ignore temp6 - ignore temp7 - ignore temp8 - ignore temp9 - ignore temp10 - ignore temp11 - ignore temp12 - ignore temp13 - ignore temp14 - ignore temp15 - ignore temp16 - ignore temp17 - ignore temp18 - ignore temp19 - ignore temp20 - ignore temp21 - ignore temp22 - ignore temp23 - ignore temp24 - ignore temp25 - ignore temp26 - ignore temp27 - ignore temp28 - ignore temp29 - ignore temp30 - ignore temp31 - ignore temp32 - ignore temp33 - ignore temp34 - ignore temp35 - ignore temp36 - ignore temp37 - ignore temp38 - ignore temp39 - ignore temp40 - ignore temp41 - ignore temp42 - ignore temp43 - ignore temp44 - ignore temp45 - ignore temp46 - ignore temp47 - ignore temp48 - ignore temp49 - ignore temp50 - ignore temp51 - ignore temp52 - ignore temp53 - ignore temp54 - ignore temp55 - ignore temp56 - ignore temp57 - ignore temp58 - ignore temp59 - ignore temp60 - ignore temp61 - ignore temp62 - ignore temp63 - ignore temp64 + chip "tps53679-i2c-*-70" + label in1 "PMIC-1 PSU 12V Rail (in1)" + label in2 "PMIC-1 PSU 12V Rail (in2)" + label in3 "PMIC-1 0.9V VCORE (out)" + label in4 "PMIC-1 1.2V Rail (out)" + label temp1 "PMIC-1 Temp 1" + label temp2 "PMIC-1 Temp 2" + label power1 "PMIC-1 0.9V VCORE Pwr (out)" + label power2 "PMIC-1 1.2V Rail Pwr (out)" + label curr1 "PMIC-1 0.9V VCORE Curr (out)" + label curr2 "PMIC-1 1.2V Rail Curr (out)" + chip "tps53679-i2c-*-71" + label in1 "PMIC-2 PSU 12V Rail (in1)" + label in2 "PMIC-2 PSU 12V Rail (in2)" + label in3 "PMIC-2 2.2V Rail (out)" + ignore in4 + label temp1 "PMIC-2 Temp 1" + label temp2 "PMIC-2 Temp 2" + label power1 "PMIC-2 2.2V Rail Pwr (out)" + ignore power2 + label curr1 "PMIC-2 2.2V Rail Curr (out)" + ignore curr2 -chip "*-virtual-*" - ignore temp1 - ignore temp2 - -chip "dps460-*" - ignore fan2 - ignore fan3 +# Chassis fans +bus "i2c-2" "i2c-1-mux (chan_id 1)" + chip "mlxsw-i2c-*-48" + label fan1 "Chassis Fan 1" + label fan2 "Chassis Fan 2" + label fan3 "Chassis Fan 3" + label fan4 "Chassis Fan 4" diff --git a/device/mellanox/x86_64-mlnx_msn2010-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_msn2010-r0/system_health_monitoring_config.json new file mode 100644 index 000000000000..a4c9e9b44e02 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2010-r0/system_health_monitoring_config.json @@ -0,0 +1,11 @@ +{ + "services_to_ignore": [], + "devices_to_ignore": ["psu.voltage", "psu.temperature"], + "user_defined_checkers": [], + "polling_interval": 60, + "led_color": { + "fault": "orange", + "normal": "green", + "booting": "orange_blink" + } +} diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/buffers_dynamic.json.j2 b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/buffers_dynamic.json.j2 new file mode 120000 index 000000000000..8c4117c66214 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/buffers_dynamic.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_dynamic.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/hwsku.json b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/hwsku.json new file mode 100644 index 000000000000..d77e2974f645 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/hwsku.json @@ -0,0 +1,52 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet4": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet8": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet12": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet16": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet20": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet24": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet28": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet32": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet36": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet40": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet44": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet48": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet52": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet56": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet60": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/port_config.ini b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/port_config.ini index c792a4114b9c..c7ea79bbdbee 100644 --- a/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/port_config.ini +++ b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/port_config.ini @@ -1,17 +1,17 @@ -# name lanes -Ethernet0 0,1,2,3 -Ethernet4 4,5,6,7 -Ethernet8 8,9,10,11 -Ethernet12 12,13,14,15 -Ethernet16 16,17,18,19 -Ethernet20 20,21,22,23 -Ethernet24 24,25,26,27 -Ethernet28 28,29,30,31 -Ethernet32 32,33,34,35 -Ethernet36 36,37,38,39 -Ethernet40 40,41,42,43 -Ethernet44 44,45,46,47 -Ethernet48 48,49,50,51 -Ethernet52 52,53,54,55 -Ethernet56 56,57,58,59 -Ethernet60 60,61,62,63 +# name lanes index +Ethernet0 0,1,2,3 1 +Ethernet4 4,5,6,7 2 +Ethernet8 8,9,10,11 3 +Ethernet12 12,13,14,15 4 +Ethernet16 16,17,18,19 5 +Ethernet20 20,21,22,23 6 +Ethernet24 24,25,26,27 7 +Ethernet28 28,29,30,31 8 +Ethernet32 32,33,34,35 9 +Ethernet36 36,37,38,39 10 +Ethernet40 40,41,42,43 11 +Ethernet44 44,45,46,47 12 +Ethernet48 48,49,50,51 13 +Ethernet52 52,53,54,55 14 +Ethernet56 56,57,58,59 15 +Ethernet60 60,61,62,63 16 diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/sai_2100.xml b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/sai_2100.xml index c9b844cd4bf8..92150596df64 100644 --- a/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/sai_2100.xml +++ b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/sai_2100.xml @@ -5,6 +5,9 @@ 00:02:03:04:05:00 + + 1 + 16 diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/pcie.yaml b/device/mellanox/x86_64-mlnx_msn2100-r0/pcie.yaml new file mode 100644 index 000000000000..63f09eecde7c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2100-r0/pcie.yaml @@ -0,0 +1,83 @@ +- bus: '00' + dev: '00' + fn: '0' + id: 1f0b + name: 'Host bridge: Intel Corporation Atom processor C2000 SoC Transaction Router + (rev 03)' +- bus: '00' + dev: '01' + fn: '0' + id: 1f10 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 1 (rev + 03)' +- bus: '00' + dev: '02' + fn: '0' + id: 1f11 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 2 (rev + 03)' +- bus: '00' + dev: '03' + fn: '0' + id: 1f12 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 3 (rev + 03)' +- bus: '00' + dev: 0b + fn: '0' + id: 1f18 + name: 'Co-processor: Intel Corporation Atom processor C2000 QAT (rev 03)' +- bus: '00' + dev: 0e + fn: '0' + id: 1f14 + name: 'Host bridge: Intel Corporation Atom processor C2000 RAS (rev 03)' +- bus: '00' + dev: 0f + fn: '0' + id: 1f16 + name: 'IOMMU: Intel Corporation Atom processor C2000 RCEC (rev 03)' +- bus: '00' + dev: '13' + fn: '0' + id: 1f15 + name: 'System peripheral: Intel Corporation Atom processor C2000 SMBus 2.0 (rev + 03)' +- bus: '00' + dev: '14' + fn: '0' + id: 1f41 + name: 'Ethernet controller: Intel Corporation Ethernet Connection I354 (rev 03)' +- bus: '00' + dev: '16' + fn: '0' + id: 1f2c + name: 'USB controller: Intel Corporation Atom processor C2000 USB Enhanced Host + Controller (rev 03)' +- bus: '00' + dev: '17' + fn: '0' + id: 1f22 + name: 'SATA controller: Intel Corporation Atom processor C2000 AHCI SATA2 Controller + (rev 03)' +- bus: '00' + dev: '18' + fn: '0' + id: 1f32 + name: 'SATA controller: Intel Corporation Atom processor C2000 AHCI SATA3 Controller + (rev 03)' +- bus: '00' + dev: 1f + fn: '0' + id: 1f38 + name: 'ISA bridge: Intel Corporation Atom processor C2000 PCU (rev 03)' +- bus: '00' + dev: 1f + fn: '3' + id: 1f3c + name: 'SMBus: Intel Corporation Atom processor C2000 PCU SMBus (rev 03)' +- bus: '01' + dev: '00' + fn: '0' + id: cb84 + name: 'Ethernet controller: Mellanox Technologies MT52100' diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/platform.json b/device/mellanox/x86_64-mlnx_msn2100-r0/platform.json new file mode 100644 index 000000000000..aa08998861fb --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2100-r0/platform.json @@ -0,0 +1,100 @@ +{ + "interfaces": { + "Ethernet0": { + "index": "1,1,1,1", + "lanes": "0,1,2,3", + "alias_at_lanes": "etp1a, etp1b, etp1c, etp1d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G],4x25G[10G]" + }, + "Ethernet4": { + "index": "2,2,2,2", + "lanes": "4,5,6,7", + "alias_at_lanes": "etp2a, etp2b, etp2c, etp2d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G],4x25G[10G]" + }, + "Ethernet8": { + "index": "3,3,3,3", + "lanes": "8,9,10,11", + "alias_at_lanes": "etp3a, etp3b, etp3c, etp3d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G],4x25G[10G]" + }, + "Ethernet12": { + "index": "4,4,4,4", + "lanes": "12,13,14,15", + "alias_at_lanes": "etp4a, etp4b, etp4c, etp4d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G],4x25G[10G]" + }, + "Ethernet16": { + "index": "5,5,5,5", + "lanes": "16,17,18,19", + "alias_at_lanes": "etp5a, etp5b, etp5c, etp5d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G],4x25G[10G]" + }, + "Ethernet20": { + "index": "6,6,6,6", + "lanes": "20,21,22,23", + "alias_at_lanes": "etp6a, etp6b, etp6c, etp6d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G],4x25G[10G]" + }, + "Ethernet24": { + "index": "7,7,7,7", + "lanes": "24,25,26,27", + "alias_at_lanes": "etp7a, etp7b, etp7c, etp7d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G],4x25G[10G]" + }, + "Ethernet28": { + "index": "8,8,8,8", + "lanes": "28,29,30,31", + "alias_at_lanes": "etp8a, etp8b, etp8c, etp8d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G],4x25G[10G]" + }, + "Ethernet32": { + "index": "9,9,9,9", + "lanes": "32,33,34,35", + "alias_at_lanes": "etp9a, etp9b, etp9c, etp9d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G],4x25G[10G]" + }, + "Ethernet36": { + "index": "10,10,10,10", + "lanes": "36,37,38,39", + "alias_at_lanes": "etp10a, etp10b, etp10c, etp10d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G],4x25G[10G]" + }, + "Ethernet40": { + "index": "11,11,11,11", + "lanes": "40,41,42,43", + "alias_at_lanes": "etp11a, etp11b, etp11c, etp11d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G],4x25G[10G]" + }, + "Ethernet44": { + "index": "12,12,12,12", + "lanes": "44,45,46,47", + "alias_at_lanes": "etp12a, etp12b, etp12c, etp12d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G],4x25G[10G]" + }, + "Ethernet48": { + "index": "13,13,13,13", + "lanes": "48,49,50,51", + "alias_at_lanes": "etp13a, etp13b, etp13c, etp13d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G],4x25G[10G]" + }, + "Ethernet52": { + "index": "14,14,14,14", + "lanes": "52,53,54,55", + "alias_at_lanes": "etp14a, etp14b, etp14c, etp14d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G],4x25G[10G]" + }, + "Ethernet56": { + "index": "15,15,15,15", + "lanes": "56,57,58,59", + "alias_at_lanes": "etp15a, etp15b, etp15c, etp15d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G],4x25G[10G]" + }, + "Ethernet60": { + "index": "16,16,16,16", + "lanes": "60,61,62,63", + "alias_at_lanes": "etp16a, etp16b, etp16c, etp16d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G],4x25G[10G]" + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn2100-r0/platform_components.json index 6a6a74301cbc..b8936fa3ad43 100644 --- a/device/mellanox/x86_64-mlnx_msn2100-r0/platform_components.json +++ b/device/mellanox/x86_64-mlnx_msn2100-r0/platform_components.json @@ -1,9 +1,12 @@ { "chassis": { - "x86_64-mlnx_msn2100-r0": { + "MSN2100": { "component": { + "ONIE": { }, + "SSD": { }, "BIOS": { }, - "CPLD": { } + "CPLD1": { }, + "CPLD2": { } } } } diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/plugins/psuutil.py b/device/mellanox/x86_64-mlnx_msn2100-r0/plugins/psuutil.py index b14b1d9dac4d..2b4f87397bc4 100644 --- a/device/mellanox/x86_64-mlnx_msn2100-r0/plugins/psuutil.py +++ b/device/mellanox/x86_64-mlnx_msn2100-r0/plugins/psuutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Mellanox # @@ -13,7 +11,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn2100-r0/sensors.conf deleted file mode 120000 index ea04d66d008c..000000000000 --- a/device/mellanox/x86_64-mlnx_msn2100-r0/sensors.conf +++ /dev/null @@ -1 +0,0 @@ -../x86_64-mlnx_msn2700-r0/sensors.conf \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn2100-r0/sensors.conf new file mode 100644 index 000000000000..e37dd25f03db --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2100-r0/sensors.conf @@ -0,0 +1,51 @@ +################################################################################ +# Copyright (c) 2020 Mellanox Technologies +# +# Platform specific sensors config for SN2100 +################################################################################ + +# 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 "lm75-i2c-*-4a" + label temp1 "Ambient Port Side Temp (air exhaust)" + chip "lm75-i2c-*-4b" + label temp1 "Ambient Fan Side Temp (air intake)" + +# Power controllers +bus "i2c-5" "i2c-1-mux (chan_id 4)" + chip "pmbus-i2c-*-41" + label in1 "PMB-1 12V Rail (in)" + label in2 "PMB-1 0.9V Rail (out)" + label in3 "PMB-1 1.8V Rail (out)" + label temp1 "PMB-1 Temp 1" + label temp2 "PMB-1 Temp 2" + ignore power1 + label power2 "PMB-1 0.9V Rail Pwr (out)" + label power3 "PMB-1 1.8V Rail Pwr (out)" + ignore curr1 + label curr2 "PMB-1 0.9V Rail Curr (out)" + label curr3 "PMB-1 1.8V Rail Curr (out)" + chip "pmbus-i2c-*-27" + label in1 "PMB-2 12V Rail (in)" + label in2 "PMB-2 3.3V Rail (out)" + label in3 "PMB-2 1.2V Rail (out)" + label temp1 "PMB-2 Temp 1" + label temp2 "PMB-2 Temp 2" + ignore power1 + label power2 "PMB-2 3.3V Rail Pwr (out)" + label power3 "PMB-2 1.2V Rail Pwr (out)" + ignore curr1 + label curr2 "PMB-2 3.3V Rail Curr (out)" + label curr3 "PMB-2 1.2V Rail Curr (out)" + +# Chassis fans +bus "i2c-2" "i2c-1-mux (chan_id 1)" + chip "mlxsw-i2c-*-48" + label fan1 "Chassis Fan 1" + label fan2 "Chassis Fan 2" + label fan3 "Chassis Fan 3" + label fan4 "Chassis Fan 4" diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_msn2100-r0/system_health_monitoring_config.json new file mode 120000 index 000000000000..265e22a00257 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2100-r0/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2010-r0/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/buffers_dynamic.json.j2 b/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/buffers_dynamic.json.j2 new file mode 120000 index 000000000000..8c4117c66214 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/buffers_dynamic.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_dynamic.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/hwsku.json b/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/hwsku.json new file mode 100644 index 000000000000..abb5b2393ba5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/hwsku.json @@ -0,0 +1,172 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet4": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet8": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet12": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet16": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet20": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet24": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet28": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet32": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet36": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet40": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet44": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet48": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet52": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet56": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet60": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet64": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet68": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet72": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet76": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet80": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet84": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet88": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet92": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet96": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet100": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet104": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet108": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet112": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet116": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet120": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet124": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet128": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet132": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet136": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet140": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet144": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet148": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet152": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet156": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet160": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet164": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet168": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet172": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet176": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet180": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet184": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet188": { + "default_brkout_mode": "1x25G[10G]" + }, + "Ethernet192": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet196": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet200": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet204": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet208": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet212": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet216": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet220": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/port_config.ini b/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/port_config.ini index c7db66b02274..782949e5706a 100644 --- a/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/port_config.ini +++ b/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/port_config.ini @@ -1,57 +1,57 @@ -# name lanes -Ethernet0 0 -Ethernet4 4 -Ethernet8 8 -Ethernet12 12 -Ethernet16 16 -Ethernet20 20 -Ethernet24 24 -Ethernet28 28 -Ethernet32 32 -Ethernet36 36 -Ethernet40 40 -Ethernet44 44 -Ethernet48 48 -Ethernet52 52 -Ethernet56 56 -Ethernet60 60 -Ethernet64 64 -Ethernet68 68 -Ethernet72 72 -Ethernet76 76 -Ethernet80 80 -Ethernet84 84 -Ethernet88 88 -Ethernet92 92 -Ethernet96 96 -Ethernet100 100 -Ethernet104 104 -Ethernet108 108 -Ethernet112 112 -Ethernet116 116 -Ethernet120 120 -Ethernet124 124 -Ethernet128 128 -Ethernet132 132 -Ethernet136 136 -Ethernet140 140 -Ethernet144 144 -Ethernet148 148 -Ethernet152 152 -Ethernet156 156 -Ethernet160 160 -Ethernet164 164 -Ethernet168 168 -Ethernet172 172 -Ethernet176 176 -Ethernet180 180 -Ethernet184 184 -Ethernet188 188 -Ethernet192 192,193,194,195 -Ethernet196 196,197,198,199 -Ethernet200 200,201,202,203 -Ethernet204 204,205,206,207 -Ethernet208 208,209,210,211 -Ethernet212 212,213,214,215 -Ethernet216 216,217,218,219 -Ethernet220 220,221,222,223 +# name lanes index +Ethernet0 0 1 +Ethernet4 4 2 +Ethernet8 8 3 +Ethernet12 12 4 +Ethernet16 16 5 +Ethernet20 20 6 +Ethernet24 24 7 +Ethernet28 28 8 +Ethernet32 32 9 +Ethernet36 36 10 +Ethernet40 40 11 +Ethernet44 44 12 +Ethernet48 48 13 +Ethernet52 52 14 +Ethernet56 56 15 +Ethernet60 60 16 +Ethernet64 64 17 +Ethernet68 68 18 +Ethernet72 72 19 +Ethernet76 76 20 +Ethernet80 80 21 +Ethernet84 84 22 +Ethernet88 88 23 +Ethernet92 92 24 +Ethernet96 96 25 +Ethernet100 100 26 +Ethernet104 104 27 +Ethernet108 108 28 +Ethernet112 112 29 +Ethernet116 116 30 +Ethernet120 120 31 +Ethernet124 124 32 +Ethernet128 128 33 +Ethernet132 132 34 +Ethernet136 136 35 +Ethernet140 140 36 +Ethernet144 144 37 +Ethernet148 148 38 +Ethernet152 152 39 +Ethernet156 156 40 +Ethernet160 160 41 +Ethernet164 164 42 +Ethernet168 168 43 +Ethernet172 172 44 +Ethernet176 176 45 +Ethernet180 180 46 +Ethernet184 184 47 +Ethernet188 188 48 +Ethernet192 192,193,194,195 49 +Ethernet196 196,197,198,199 50 +Ethernet200 200,201,202,203 51 +Ethernet204 204,205,206,207 52 +Ethernet208 208,209,210,211 53 +Ethernet212 212,213,214,215 54 +Ethernet216 216,217,218,219 55 +Ethernet220 220,221,222,223 56 diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/pcie.yaml b/device/mellanox/x86_64-mlnx_msn2410-r0/pcie.yaml new file mode 120000 index 000000000000..f739a7e8ec35 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2410-r0/pcie.yaml @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/pcie.yaml \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/platform.json b/device/mellanox/x86_64-mlnx_msn2410-r0/platform.json new file mode 100644 index 000000000000..0009dee63ba5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2410-r0/platform.json @@ -0,0 +1,340 @@ +{ + "interfaces": { + "Ethernet0": { + "index": "1", + "lanes": "0", + "alias_at_lanes": "etp1", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet4": { + "index": "2", + "lanes": "4", + "alias_at_lanes": "etp2", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet8": { + "index": "3", + "lanes": "8", + "alias_at_lanes": "etp3", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet12": { + "index": "4", + "lanes": "12", + "alias_at_lanes": "etp4", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet16": { + "index": "5", + "lanes": "16", + "alias_at_lanes": "etp5", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet20": { + "index": "6", + "lanes": "20", + "alias_at_lanes": "etp6", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet24": { + "index": "7", + "lanes": "24", + "alias_at_lanes": "etp7", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet28": { + "index": "8", + "lanes": "28", + "alias_at_lanes": "etp8", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet32": { + "index": "9", + "lanes": "32", + "alias_at_lanes": "etp9", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet36": { + "index": "10", + "lanes": "36", + "alias_at_lanes": "etp10", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet40": { + "index": "11", + "lanes": "40", + "alias_at_lanes": "etp11", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet44": { + "index": "12", + "lanes": "44", + "alias_at_lanes": "etp12", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet48": { + "index": "13", + "lanes": "48", + "alias_at_lanes": "etp13", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet52": { + "index": "14", + "lanes": "52", + "alias_at_lanes": "etp14", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet56": { + "index": "15", + "lanes": "56", + "alias_at_lanes": "etp15", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet60": { + "index": "16", + "lanes": "60", + "alias_at_lanes": "etp16", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet64": { + "index": "17", + "lanes": "64", + "alias_at_lanes": "etp17", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet68": { + "index": "18", + "lanes": "68", + "alias_at_lanes": "etp18", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet72": { + "index": "19", + "lanes": "72", + "alias_at_lanes": "etp19", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet76": { + "index": "20", + "lanes": "76", + "alias_at_lanes": "etp20", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet80": { + "index": "21", + "lanes": "80", + "alias_at_lanes": "etp21", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet84": { + "index": "22", + "lanes": "84", + "alias_at_lanes": "etp22", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet88": { + "index": "23", + "lanes": "88", + "alias_at_lanes": "etp23", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet92": { + "index": "24", + "lanes": "92", + "alias_at_lanes": "etp24", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet96": { + "index": "25", + "lanes": "96", + "alias_at_lanes": "etp25", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet100": { + "index": "26", + "lanes": "100", + "alias_at_lanes": "etp26", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet104": { + "index": "27", + "lanes": "104", + "alias_at_lanes": "etp27", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet108": { + "index": "28", + "lanes": "108", + "alias_at_lanes": "etp28", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet112": { + "index": "29", + "lanes": "112", + "alias_at_lanes": "etp29", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet116": { + "index": "30", + "lanes": "116", + "alias_at_lanes": "etp30", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet120": { + "index": "31", + "lanes": "120", + "alias_at_lanes": "etp31", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet124": { + "index": "32", + "lanes": "124", + "alias_at_lanes": "etp32", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet128": { + "index": "33", + "lanes": "128", + "alias_at_lanes": "etp33", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet132": { + "index": "34", + "lanes": "132", + "alias_at_lanes": "etp34", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet136": { + "index": "35", + "lanes": "136", + "alias_at_lanes": "etp35", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet140": { + "index": "36", + "lanes": "140", + "alias_at_lanes": "etp36", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet144": { + "index": "37", + "lanes": "144", + "alias_at_lanes": "etp37", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet148": { + "index": "38", + "lanes": "148", + "alias_at_lanes": "etp38", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet152": { + "index": "39", + "lanes": "152", + "alias_at_lanes": "etp39", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet156": { + "index": "40", + "lanes": "156", + "alias_at_lanes": "etp40", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet160": { + "index": "41", + "lanes": "160", + "alias_at_lanes": "etp41", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet164": { + "index": "42", + "lanes": "164", + "alias_at_lanes": "etp42", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet168": { + "index": "43", + "lanes": "168", + "alias_at_lanes": "etp43", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet172": { + "index": "44", + "lanes": "172", + "alias_at_lanes": "etp44", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet176": { + "index": "45", + "lanes": "176", + "alias_at_lanes": "etp45", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet180": { + "index": "46", + "lanes": "180", + "alias_at_lanes": "etp46", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet184": { + "index": "47", + "lanes": "184", + "alias_at_lanes": "etp47", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet188": { + "index": "48", + "lanes": "188", + "alias_at_lanes": "etp48", + "breakout_modes": "1x25G[10G]" + }, + "Ethernet192": { + "index": "49,49,49,49", + "lanes": "192,193,194,195", + "alias_at_lanes": "etp49a, etp49b, etp49c, etp49d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet196": { + "index": "50,50,50,50", + "lanes": "196,197,198,199", + "alias_at_lanes": "etp50a, etp50b, etp50c, etp50d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet200": { + "index": "51,51,51,51", + "lanes": "200,201,202,203", + "alias_at_lanes": "etp51a, etp51b, etp51c, etp51d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet204": { + "index": "52,52,52,52", + "lanes": "204,205,206,207", + "alias_at_lanes": "etp52a, etp52b, etp52c, etp52d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet208": { + "index": "53,53,53,53", + "lanes": "208,209,210,211", + "alias_at_lanes": "etp53a, etp53b, etp53c, etp53d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet212": { + "index": "54,54,54,54", + "lanes": "212,213,214,215", + "alias_at_lanes": "etp54a, etp54b, etp54c, etp54d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet216": { + "index": "55,55,55,55", + "lanes": "216,217,218,219", + "alias_at_lanes": "etp55a, etp55b, etp55c, etp55d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet220": { + "index": "56,56,56,56", + "lanes": "220,221,222,223", + "alias_at_lanes": "etp56a, etp56b, etp56c, etp56d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn2410-r0/platform_components.json index 77da35ce5818..52c09f4ea998 100644 --- a/device/mellanox/x86_64-mlnx_msn2410-r0/platform_components.json +++ b/device/mellanox/x86_64-mlnx_msn2410-r0/platform_components.json @@ -1,9 +1,13 @@ { "chassis": { - "x86_64-mlnx_msn2410-r0": { + "MSN2410": { "component": { + "ONIE": { }, + "SSD": { }, "BIOS": { }, - "CPLD": { } + "CPLD1": { }, + "CPLD2": { }, + "CPLD3": { } } } } diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn2410-r0/sensors.conf deleted file mode 120000 index ea04d66d008c..000000000000 --- a/device/mellanox/x86_64-mlnx_msn2410-r0/sensors.conf +++ /dev/null @@ -1 +0,0 @@ -../x86_64-mlnx_msn2700-r0/sensors.conf \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn2410-r0/sensors.conf new file mode 100644 index 000000000000..ede1fbe3c768 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2410-r0/sensors.conf @@ -0,0 +1,81 @@ +################################################################################ +# Copyright (c) 2020 Mellanox Technologies +# +# Platform specific sensors config for SN2410 +################################################################################ + +# 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 7)" + chip "lm75-i2c-7-4a" + label temp1 "Ambient Port Temp" + +bus "i2c-17" "i2c-1-mux (chan_id 17)" + chip "lm75-i2c-17-49" + label temp1 "Ambient Fan Temp" + +chip "acpitz-virtual-0" + label temp1 "ACPI CPU Temp" + label temp2 "ACPI Board Temp" + +# Power controllers +bus "i2c-5" "i2c-1-mux (chan_id 5)" + chip "pmbus-i2c-*-41" + label in1 "PMB-1 PSU 12V Rail (in)" + label in2 "PMB-1 0.9V VCORE Rail (out)" + label temp1 "PMB-1 Temp 1" + label temp2 "PMB-1 Temp 2" + ignore power1 + label power2 "PMB-1 0.9V VCORE Rail Pwr (out)" + ignore curr1 + label curr2 "PMB-1 0.9V VCORE Rail Curr (out)" + chip "pmbus-i2c-*-27" + label in1 "PMB-2 PSU 12V Rail (in)" + label in2 "PMB-2 3.3V Rail (out)" + label in3 "PMB-2 1.2V Rail (out)" + label temp1 "PMB-2 Temp 1" + label temp2 "PMB-2 Temp 2" + ignore power1 + label power2 "PMB-2 3.3V Rail Pwr (out)" + label power3 "PMB-2 1.2V Rail Pwr (out)" + ignore curr1 + label curr2 "PMB-2 3.3V Rail Curr (out)" + label curr3 "PMB-2 1.2V Rail Curr (out)" + +# Power supplies +bus "i2c-10" "i2c-1-mux (chan_id 10)" + chip "dps460-i2c-*-58" + label in1 "PSU-2(R) 220V Rail (in)" + label in2 "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 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)" + chip "dps460-i2c-*-59" + label in1 "PSU-1(L) 220V Rail (in)" + label in2 "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 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)" + +# Chassis fans +bus "i2c-2" "i2c-1-mux (chan_id 1)" + chip "mlxsw-i2c-*-48" + label fan1 "Chassis Drawer-1 Fan-1" + label fan2 "Chassis Drawer-1 Fan-2" + label fan3 "Chassis Drawer-2 Fan-1" + label fan4 "Chassis Drawer-2 Fan-2" + label fan5 "Chassis Drawer-3 Fan-1" + label fan6 "Chassis Drawer-3 Fan-2" + label fan7 "Chassis Drawer-4 Fan-1" + label fan8 "Chassis Drawer-4 Fan-2" diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_msn2410-r0/system_health_monitoring_config.json new file mode 120000 index 000000000000..98df66c27ca5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2410-r0/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/system_health_monitoring_config.json \ No newline at end of file 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 5529ee3d8598..d0bce94ba51d 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 = '5029836' %} -{% set ingress_lossy_pool_size = '5029836' %} -{% set egress_lossless_pool_size = '14024599' %} -{% set egress_lossy_pool_size = '5029836' %} +{% set ingress_lossless_pool_size = '4580864' %} +{% set ingress_lossy_pool_size = '4580864' %} +{% set egress_lossless_pool_size = '13945824' %} +{% set egress_lossy_pool_size = '4580864' %} {%- macro generate_port_lists(PORT_ALL) %} {# Generate list of ports #} @@ -14,12 +14,16 @@ {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { + {%- if dynamic_mode is not defined %} "size": "{{ ingress_lossless_pool_size }}", + {%- endif %} "type": "ingress", "mode": "dynamic" }, "ingress_lossy_pool": { + {%- if dynamic_mode is not defined %} "size": "{{ ingress_lossy_pool_size }}", + {%- endif %} "type": "ingress", "mode": "dynamic" }, @@ -29,7 +33,9 @@ "mode": "dynamic" }, "egress_lossy_pool": { + {%- if dynamic_mode is not defined %} "size": "{{ egress_lossy_pool_size }}", + {%- endif %} "type": "egress", "mode": "dynamic" } @@ -38,7 +44,7 @@ "ingress_lossless_profile": { "pool":"[BUFFER_POOL|ingress_lossless_pool]", "size":"0", - "dynamic_th":"0" + "dynamic_th":"7" }, "ingress_lossy_profile": { "pool":"[BUFFER_POOL|ingress_lossy_pool]", @@ -52,8 +58,8 @@ }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", - "size":"4096", - "dynamic_th":"3" + "size":"9216", + "dynamic_th":"7" }, "q_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", 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 f418e2ffa1db..5514c47a4090 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 = '2097100' %} -{% set ingress_lossy_pool_size = '2097100' %} -{% set egress_lossless_pool_size = '14024599' %} -{% set egress_lossy_pool_size = '2097100' %} +{% set ingress_lossless_pool_size = '3302912' %} +{% set ingress_lossy_pool_size = '3302912' %} +{% set egress_lossless_pool_size = '13945824' %} +{% set egress_lossy_pool_size = '3302912' %} {%- macro generate_port_lists(PORT_ALL) %} {# Generate list of ports #} @@ -14,12 +14,16 @@ {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { + {%- if dynamic_mode is not defined %} "size": "{{ ingress_lossless_pool_size }}", + {%- endif %} "type": "ingress", "mode": "dynamic" }, "ingress_lossy_pool": { + {%- if dynamic_mode is not defined %} "size": "{{ ingress_lossy_pool_size }}", + {%- endif %} "type": "ingress", "mode": "dynamic" }, @@ -29,7 +33,9 @@ "mode": "dynamic" }, "egress_lossy_pool": { + {%- if dynamic_mode is not defined %} "size": "{{ egress_lossy_pool_size }}", + {%- endif %} "type": "egress", "mode": "dynamic" } @@ -38,7 +44,7 @@ "ingress_lossless_profile": { "pool":"[BUFFER_POOL|ingress_lossless_pool]", "size":"0", - "dynamic_th":"0" + "dynamic_th":"7" }, "ingress_lossy_profile": { "pool":"[BUFFER_POOL|ingress_lossy_pool]", @@ -52,8 +58,8 @@ }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", - "size":"4096", - "dynamic_th":"3" + "size":"9216", + "dynamic_th":"7" }, "q_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_dynamic.json.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_dynamic.json.j2 new file mode 100644 index 000000000000..5954cc77c114 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_dynamic.json.j2 @@ -0,0 +1,3 @@ +{%- set default_topo = 't0' %} +{%- set dynamic_mode = 'true' %} +{%- include 'buffers_config.j2' %} diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/hwsku.json b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/hwsku.json new file mode 100644 index 000000000000..3edbff817895 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/hwsku.json @@ -0,0 +1,100 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet4": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet8": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet12": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet16": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet20": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet24": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet28": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet32": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet36": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet40": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet44": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet48": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet52": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet56": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet60": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet64": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet68": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet72": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet76": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet80": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet84": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet88": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet92": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet96": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet100": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet104": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet108": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet112": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet116": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet120": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet124": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/pg_profile_lookup.ini index b66b129fe43f..7abb2a058d1b 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/pg_profile_lookup.ini +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/pg_profile_lookup.ini @@ -1,17 +1,17 @@ -# PG lossless profiles. -# speed cable size xon xoff threshold - 10000 5m 34816 18432 16384 0 - 25000 5m 34816 18432 16384 0 - 40000 5m 34816 18432 16384 0 - 50000 5m 34816 18432 16384 0 - 100000 5m 36864 18432 18432 0 - 10000 40m 36864 18432 18432 0 - 25000 40m 39936 18432 21504 0 - 40000 40m 41984 18432 23552 0 - 50000 40m 41984 18432 23552 0 - 100000 40m 54272 18432 35840 0 - 10000 300m 49152 18432 30720 0 - 25000 300m 71680 18432 53248 0 - 40000 300m 94208 18432 75776 0 - 50000 300m 94208 18432 75776 0 - 100000 300m 184320 18432 165888 0 +# PG lossless profiles. +# speed cable size xon xoff threshold + 10000 5m 49152 19456 29696 0 + 25000 5m 49152 19456 29696 0 + 40000 5m 49152 19456 29696 0 + 50000 5m 49152 19456 29696 0 + 100000 5m 50176 19456 30720 0 + 10000 40m 49152 19456 29696 0 + 25000 40m 51200 19456 31744 0 + 40000 40m 52224 19456 32768 0 + 50000 40m 53248 19456 33792 0 + 100000 40m 58368 19456 38912 0 + 10000 300m 56320 19456 36864 0 + 25000 300m 67584 19456 48128 0 + 40000 300m 78848 19456 59392 0 + 50000 300m 86016 19456 66560 0 + 100000 300m 123904 19456 104448 0 diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/port_config.ini b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/port_config.ini index 1e1906ff0ef5..c1e59909c0fb 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/port_config.ini +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/port_config.ini @@ -1,33 +1,33 @@ -# name lanes 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 +# name lanes alias index +Ethernet0 0,1,2,3 etp1 1 +Ethernet4 4,5,6,7 etp2 2 +Ethernet8 8,9,10,11 etp3 3 +Ethernet12 12,13,14,15 etp4 4 +Ethernet16 16,17,18,19 etp5 5 +Ethernet20 20,21,22,23 etp6 6 +Ethernet24 24,25,26,27 etp7 7 +Ethernet28 28,29,30,31 etp8 8 +Ethernet32 32,33,34,35 etp9 9 +Ethernet36 36,37,38,39 etp10 10 +Ethernet40 40,41,42,43 etp11 11 +Ethernet44 44,45,46,47 etp12 12 +Ethernet48 48,49,50,51 etp13 13 +Ethernet52 52,53,54,55 etp14 14 +Ethernet56 56,57,58,59 etp15 15 +Ethernet60 60,61,62,63 etp16 16 +Ethernet64 64,65,66,67 etp17 17 +Ethernet68 68,69,70,71 etp18 18 +Ethernet72 72,73,74,75 etp19 19 +Ethernet76 76,77,78,79 etp20 20 +Ethernet80 80,81,82,83 etp21 21 +Ethernet84 84,85,86,87 etp22 22 +Ethernet88 88,89,90,91 etp23 23 +Ethernet92 92,93,94,95 etp24 24 +Ethernet96 96,97,98,99 etp25 25 +Ethernet100 100,101,102,103 etp26 26 +Ethernet104 104,105,106,107 etp27 27 +Ethernet108 108,109,110,111 etp28 28 +Ethernet112 112,113,114,115 etp29 29 +Ethernet116 116,117,118,119 etp30 30 +Ethernet120 120,121,122,123 etp31 31 +Ethernet124 124,125,126,127 etp32 32 diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700 b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700 deleted file mode 120000 index 9f12504c7c5a..000000000000 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700 +++ /dev/null @@ -1 +0,0 @@ -ACS-MSN2700 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/buffers_defaults_t0.j2 index a722094938f8..a1d24c418b3e 120000 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/buffers_defaults_t0.j2 +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/buffers_defaults_t0.j2 @@ -1 +1 @@ -../ACS-MSN2700/buffers_defaults_t0.j2 \ No newline at end of file +../Mellanox-SN2700-D48C8/buffers_defaults_t0.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/buffers_defaults_t1.j2 index b02d5e0194ac..bef0c9d9531c 120000 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/buffers_defaults_t1.j2 +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/buffers_defaults_t1.j2 @@ -1 +1 @@ -../ACS-MSN2700/buffers_defaults_t1.j2 \ No newline at end of file +../Mellanox-SN2700-D48C8/buffers_defaults_t1.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/buffers_dynamic.json.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/buffers_dynamic.json.j2 new file mode 120000 index 000000000000..8c4117c66214 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/buffers_dynamic.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_dynamic.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/hwsku.json b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/hwsku.json new file mode 100644 index 000000000000..8d3ad0dc0310 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/hwsku.json @@ -0,0 +1,112 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet4": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet8": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet12": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet16": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet20": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet24": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet28": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet32": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet36": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet40": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet44": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet48": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet52": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet56": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet60": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet64": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet68": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet72": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet76": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet80": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet84": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet88": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet92": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet96": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet100": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet104": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet108": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet112": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet114": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet116": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet118": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet120": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet122": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet124": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet126": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/pg_profile_lookup.ini index 229a556f88a8..40ad66c7356a 120000 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/pg_profile_lookup.ini +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/pg_profile_lookup.ini @@ -1 +1 @@ -../ACS-MSN2700/pg_profile_lookup.ini \ No newline at end of file +../Mellanox-SN2700-D48C8/pg_profile_lookup.ini \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/port_config.ini b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/port_config.ini index 8bc48269d163..653a61ecc23c 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 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 +Ethernet0 0,1,2,3 etp1 1 100000 +Ethernet4 4,5,6,7 etp2 2 100000 +Ethernet8 8,9,10,11 etp3 3 100000 +Ethernet12 12,13,14,15 etp4 4 100000 +Ethernet16 16,17,18,19 etp5 5 100000 +Ethernet20 20,21,22,23 etp6 6 100000 +Ethernet24 24,25,26,27 etp7 7 100000 +Ethernet28 28,29,30,31 etp8 8 100000 +Ethernet32 32,33,34,35 etp9 9 100000 +Ethernet36 36,37,38,39 etp10 10 100000 +Ethernet40 40,41,42,43 etp11 11 100000 +Ethernet44 44,45,46,47 etp12 12 100000 +Ethernet48 48,49,50,51 etp13 13 100000 +Ethernet52 52,53,54,55 etp14 14 100000 +Ethernet56 56,57,58,59 etp15 15 100000 +Ethernet60 60,61,62,63 etp16 16 100000 +Ethernet64 64,65,66,67 etp17 17 100000 +Ethernet68 68,69,70,71 etp18 18 100000 +Ethernet72 72,73,74,75 etp19 19 100000 +Ethernet76 76,77,78,79 etp20 20 100000 +Ethernet80 80,81,82,83 etp21 21 100000 +Ethernet84 84,85,86,87 etp22 22 100000 +Ethernet88 88,89,90,91 etp23 23 100000 +Ethernet92 92,93,94,95 etp24 24 100000 +Ethernet96 96,97,98,99 etp25 25 100000 +Ethernet100 100,101,102,103 etp26 26 100000 +Ethernet104 104,105,106,107 etp27 27 100000 +Ethernet108 108,109,110,111 etp28 28 100000 +Ethernet112 112,113 etp29a 29 50000 +Ethernet114 114,115 etp29b 29 50000 +Ethernet116 116,117 etp30a 30 50000 +Ethernet118 118,119 etp30b 30 50000 +Ethernet120 120,121 etp31a 31 50000 +Ethernet122 122,123 etp31b 31 50000 +Ethernet124 124,125 etp32a 32 50000 +Ethernet126 126,127 etp32b 32 50000 diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers_defaults_t0.j2 deleted file mode 120000 index a722094938f8..000000000000 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers_defaults_t0.j2 +++ /dev/null @@ -1 +0,0 @@ -../ACS-MSN2700/buffers_defaults_t0.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..6fc5efcf9b88 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers_defaults_t0.j2 @@ -0,0 +1,106 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '7719936' %} +{% set ingress_lossless_pool_xoff = '1032192' %} +{% set egress_lossless_pool_size = '13945824' %} +{% set egress_lossy_pool_size = '7719936' %} + +{%- 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": { + {%- if dynamic_mode is not defined %} + "size": "{{ ingress_lossless_pool_size }}", + "xoff": "{{ ingress_lossless_pool_xoff }}", + {%- endif %} + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + {%- if dynamic_mode is not defined %} + "size": "{{ egress_lossy_pool_size }}", + {%- endif %} + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "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", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"9216", + "dynamic_th":"7" + }, + "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]" + }{% 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_msn2700-r0/Mellanox-SN2700-D48C8/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers_defaults_t1.j2 deleted file mode 120000 index b02d5e0194ac..000000000000 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers_defaults_t1.j2 +++ /dev/null @@ -1 +0,0 @@ -../ACS-MSN2700/buffers_defaults_t1.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..95d35539253e --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers_defaults_t1.j2 @@ -0,0 +1,106 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '9686016' %} +{% set ingress_lossless_pool_xoff = '1179648' %} +{% set egress_lossless_pool_size = '13945824' %} +{% set egress_lossy_pool_size = '9686016' %} + +{%- 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": { + {%- if dynamic_mode is not defined %} + "size": "{{ ingress_lossless_pool_size }}", + "xoff": "{{ ingress_lossless_pool_xoff }}", + {%- endif %} + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + {%- if dynamic_mode is not defined %} + "size": "{{ egress_lossy_pool_size }}", + {%- endif %} + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "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", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"9216", + "dynamic_th":"7" + }, + "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]" + }{% 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_msn2700-r0/Mellanox-SN2700-D48C8/buffers_dynamic.json.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers_dynamic.json.j2 new file mode 120000 index 000000000000..8c4117c66214 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers_dynamic.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_dynamic.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/hwsku.json b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/hwsku.json new file mode 100644 index 000000000000..0e846d9b3874 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/hwsku.json @@ -0,0 +1,172 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet2": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet4": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet6": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet8": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet10": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet12": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet14": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet16": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet18": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet20": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet22": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet24": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet28": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet32": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet36": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet40": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet42": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet44": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet46": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet48": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet50": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet52": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet54": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet56": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet58": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet60": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet62": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet64": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet66": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet68": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet70": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet72": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet74": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet76": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet78": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet80": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet82": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet84": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet86": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet88": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet92": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet96": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet100": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet104": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet106": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet108": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet110": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet112": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet114": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet116": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet118": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet120": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet122": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet124": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet126": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/pg_profile_lookup.ini deleted file mode 120000 index 229a556f88a8..000000000000 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/pg_profile_lookup.ini +++ /dev/null @@ -1 +0,0 @@ -../ACS-MSN2700/pg_profile_lookup.ini \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/pg_profile_lookup.ini new file mode 100644 index 000000000000..cdd674e4e715 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 10000 5m 19456 19456 22528 0 + 25000 5m 19456 19456 22528 0 + 40000 5m 19456 19456 22528 0 + 50000 5m 19456 19456 22528 0 + 100000 5m 19456 19456 23552 0 + 10000 40m 19456 19456 22528 0 + 25000 40m 19456 19456 24576 0 + 40000 40m 19456 19456 25600 0 + 50000 40m 19456 19456 25600 0 + 100000 40m 19456 19456 29696 0 + 10000 300m 19456 19456 27648 0 + 25000 300m 19456 19456 36864 0 + 40000 300m 19456 19456 45056 0 + 50000 300m 19456 19456 50176 0 + 100000 300m 19456 19456 78848 0 diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/port_config.ini b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/port_config.ini index f9f465f1a3ea..830f558fb383 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 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 +Ethernet0 0,1 etp1a 1 50000 +Ethernet2 2,3 etp1b 1 50000 +Ethernet4 4,5 etp2a 2 50000 +Ethernet6 6,7 etp2b 2 50000 +Ethernet8 8,9 etp3a 3 50000 +Ethernet10 10,11 etp3b 3 50000 +Ethernet12 12,13 etp4a 4 50000 +Ethernet14 14,15 etp4b 4 50000 +Ethernet16 16,17 etp5a 5 50000 +Ethernet18 18,19 etp5b 5 50000 +Ethernet20 20,21 etp6a 6 50000 +Ethernet22 22,23 etp6b 6 50000 +Ethernet24 24,25,26,27 etp7 7 100000 +Ethernet28 28,29,30,31 etp8 8 100000 +Ethernet32 32,33,34,35 etp9 9 100000 +Ethernet36 36,37,38,39 etp10 10 100000 +Ethernet40 40,41 etp11a 11 50000 +Ethernet42 42,43 etp11b 11 50000 +Ethernet44 44,45 etp12a 12 50000 +Ethernet46 46,47 etp12b 12 50000 +Ethernet48 48,49 etp13a 13 50000 +Ethernet50 50,51 etp13b 13 50000 +Ethernet52 52,53 etp14a 14 50000 +Ethernet54 54,55 etp14b 14 50000 +Ethernet56 56,57 etp15a 15 50000 +Ethernet58 58,59 etp15b 15 50000 +Ethernet60 60,61 etp16a 16 50000 +Ethernet62 62,63 etp16b 16 50000 +Ethernet64 64,65 etp17a 17 50000 +Ethernet66 66,67 etp17b 17 50000 +Ethernet68 68,69 etp18a 18 50000 +Ethernet70 70,71 etp18b 18 50000 +Ethernet72 72,73 etp19a 19 50000 +Ethernet74 74,75 etp19b 19 50000 +Ethernet76 76,77 etp20a 20 50000 +Ethernet78 78,79 etp20b 20 50000 +Ethernet80 80,81 etp21a 21 50000 +Ethernet82 82,83 etp21b 21 50000 +Ethernet84 84,85 etp22a 22 50000 +Ethernet86 86,87 etp22b 22 50000 +Ethernet88 88,89,90,91 etp23 23 100000 +Ethernet92 92,93,94,95 etp24 24 100000 +Ethernet96 96,97,98,99 etp25 25 100000 +Ethernet100 100,101,102,103 etp26 26 100000 +Ethernet104 104,105 etp27a 27 50000 +Ethernet106 106,107 etp27b 27 50000 +Ethernet108 108,109 etp28a 28 50000 +Ethernet110 110,111 etp28b 28 50000 +Ethernet112 112,113 etp29a 29 50000 +Ethernet114 114,115 etp29b 29 50000 +Ethernet116 116,117 etp30a 30 50000 +Ethernet118 118,119 etp30b 30 50000 +Ethernet120 120,121 etp31a 31 50000 +Ethernet122 122,123 etp31b 31 50000 +Ethernet124 124,125 etp32a 32 50000 +Ethernet126 126,127 etp32b 32 50000 diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700/buffers.json.j2 new file mode 120000 index 000000000000..30c4e1d5bfdd --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700/buffers.json.j2 @@ -0,0 +1 @@ +../ACS-MSN2700/buffers.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..d2bf72b15f7c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700/buffers_defaults_t0.j2 @@ -0,0 +1,106 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '10177536' %} +{% set ingress_lossless_pool_xoff = '688128' %} +{% set egress_lossless_pool_size = '13945824' %} +{% set egress_lossy_pool_size = '10177536' %} + +{%- 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": { + {%- if dynamic_mode is not defined %} + "size": "{{ ingress_lossless_pool_size }}", + "xoff": "{{ ingress_lossless_pool_xoff }}", + {%- endif %} + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + {%- if dynamic_mode is not defined %} + "size": "{{ egress_lossy_pool_size }}", + {%- endif %} + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "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", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"9216", + "dynamic_th":"7" + }, + "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]" + }{% 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_msn2700-r0/Mellanox-SN2700/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..c4422556d87a --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700/buffers_defaults_t1.j2 @@ -0,0 +1,106 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '9292800' %} +{% set ingress_lossless_pool_xoff = '1572864' %} +{% set egress_lossless_pool_size = '13945824' %} +{% set egress_lossy_pool_size = '9292800' %} + +{%- 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": { + {%- if dynamic_mode is not defined %} + "size": "{{ ingress_lossless_pool_size }}", + "xoff": "{{ ingress_lossless_pool_xoff }}", + {%- endif %} + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + {%- if dynamic_mode is not defined %} + "size": "{{ egress_lossy_pool_size }}", + {%- endif %} + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "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", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"9216", + "dynamic_th":"7" + }, + "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]" + }{% 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_msn2700-r0/Mellanox-SN2700/buffers_dynamic.json.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700/buffers_dynamic.json.j2 new file mode 120000 index 000000000000..8c4117c66214 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700/buffers_dynamic.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_dynamic.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700/hwsku.json b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700/hwsku.json new file mode 100644 index 000000000000..3edbff817895 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700/hwsku.json @@ -0,0 +1,100 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet4": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet8": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet12": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet16": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet20": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet24": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet28": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet32": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet36": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet40": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet44": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet48": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet52": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet56": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet60": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet64": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet68": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet72": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet76": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet80": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet84": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet88": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet92": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet96": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet100": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet104": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet108": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet112": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet116": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet120": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet124": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700/pg_profile_lookup.ini new file mode 120000 index 000000000000..40ad66c7356a --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700/pg_profile_lookup.ini @@ -0,0 +1 @@ +../Mellanox-SN2700-D48C8/pg_profile_lookup.ini \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700/port_config.ini b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700/port_config.ini new file mode 120000 index 000000000000..75904c159253 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700/port_config.ini @@ -0,0 +1 @@ +../ACS-MSN2700/port_config.ini \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700/qos.json.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700/qos.json.j2 new file mode 120000 index 000000000000..8bd2d26567b8 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700/qos.json.j2 @@ -0,0 +1 @@ +../ACS-MSN2700/qos.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700/sai.profile b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700/sai.profile new file mode 120000 index 000000000000..5d2c55d8bb44 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700/sai.profile @@ -0,0 +1 @@ +../ACS-MSN2700/sai.profile \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700/sai_2700.xml b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700/sai_2700.xml new file mode 120000 index 000000000000..7f7b65fc6a21 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700/sai_2700.xml @@ -0,0 +1 @@ +../ACS-MSN2700/sai_2700.xml \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/pcie.yaml b/device/mellanox/x86_64-mlnx_msn2700-r0/pcie.yaml new file mode 100644 index 000000000000..8796390b73c6 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/pcie.yaml @@ -0,0 +1,111 @@ +- bus: '00' + dev: '00' + fn: '0' + id: '0154' + name: 'Host bridge: Intel Corporation 3rd Gen Core processor DRAM Controller (rev + 09)' +- bus: '00' + dev: '01' + fn: '0' + id: '0151' + name: 'PCI bridge: Intel Corporation Xeon E3-1200 v2/3rd Gen Core processor PCI + Express Root Port (rev 09)' +- bus: '00' + dev: '01' + fn: '1' + id: '0155' + name: 'PCI bridge: Intel Corporation Xeon E3-1200 v2/3rd Gen Core processor PCI + Express Root Port (rev 09)' +- bus: '00' + dev: '01' + fn: '2' + id: 0159 + name: 'PCI bridge: Intel Corporation Xeon E3-1200 v2/3rd Gen Core processor PCI + Express Root Port (rev 09)' +- bus: '00' + dev: '04' + fn: '0' + id: '0153' + name: 'Signal processing controller: Intel Corporation 3rd Gen Core Processor Thermal + Subsystem (rev 09)' +- bus: '00' + dev: '16' + fn: '0' + id: 1e3a + name: 'Communication controller: Intel Corporation 7 Series/C216 Chipset Family + MEI Controller #1 (rev 04)' +- bus: '00' + dev: '19' + fn: '0' + id: '1502' + name: 'Ethernet controller: Intel Corporation 82579LM Gigabit Network Connection + (rev 04)' +- bus: '00' + dev: 1a + fn: '0' + id: 1e2d + name: 'USB controller: Intel Corporation 7 Series/C216 Chipset Family USB Enhanced + Host Controller #2 (rev 04)' +- bus: '00' + dev: 1c + fn: '0' + id: 1e10 + name: 'PCI bridge: Intel Corporation 7 Series/C216 Chipset Family PCI Express Root + Port 1 (rev c4)' +- bus: '00' + dev: 1c + fn: '4' + id: 1e18 + name: 'PCI bridge: Intel Corporation 7 Series/C210 Series Chipset Family PCI Express + Root Port 5 (rev c4)' +- bus: '00' + dev: 1c + fn: '6' + id: 1e1c + name: 'PCI bridge: Intel Corporation 7 Series/C210 Series Chipset Family PCI Express + Root Port 7 (rev c4)' +- bus: '00' + dev: 1c + fn: '7' + id: 1e1e + name: 'PCI bridge: Intel Corporation 7 Series/C210 Series Chipset Family PCI Express + Root Port 8 (rev c4)' +- bus: '00' + dev: 1d + fn: '0' + id: 1e26 + name: 'USB controller: Intel Corporation 7 Series/C216 Chipset Family USB Enhanced + Host Controller #1 (rev 04)' +- bus: '00' + dev: 1f + fn: '0' + id: 1e55 + name: 'ISA bridge: Intel Corporation QM77 Express Chipset LPC Controller (rev 04)' +- bus: '00' + dev: 1f + fn: '2' + id: 1e03 + name: 'SATA controller: Intel Corporation 7 Series Chipset Family 6-port SATA Controller + [AHCI mode] (rev 04)' +- bus: '00' + dev: 1f + fn: '3' + id: 1e22 + name: 'SMBus: Intel Corporation 7 Series/C216 Chipset Family SMBus Controller (rev + 04)' +- bus: '00' + dev: 1f + fn: '6' + id: 1e24 + name: 'Signal processing controller: Intel Corporation 7 Series/C210 Series Chipset + Family Thermal Management Controller (rev 04)' +- bus: '03' + dev: '00' + fn: '0' + id: cb84 + name: 'Ethernet controller: Mellanox Technologies MT52100' +- bus: '06' + dev: '00' + fn: '0' + id: 150c + name: 'Ethernet controller: Intel Corporation 82583V Gigabit Network Connection' diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/platform.json b/device/mellanox/x86_64-mlnx_msn2700-r0/platform.json new file mode 100644 index 000000000000..65d28529ec14 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/platform.json @@ -0,0 +1,572 @@ +{ + "chassis": { + "name": "MSN2700", + "components": [ + { + "name": "ONIE" + }, + { + "name": "SSD" + }, + { + "name": "BIOS" + }, + { + "name": "CPLD1" + }, + { + "name": "CPLD2" + }, + { + "name": "CPLD3" + } + ], + "fans": [], + "fan_drawers": [ + { + "name": "drawer1", + "fans": [ + { + "name": "fan1" + }, + { + "name": "fan2" + } + ] + }, + { + "name": "drawer2", + "fans": [ + { + "name": "fan3" + }, + { + "name": "fan4" + } + ] + }, + { + "name": "drawer3", + "fans": [ + { + "name": "fan5" + }, + { + "name": "fan6" + } + ] + }, + { + "name": "drawer4", + "fans": [ + { + "name": "fan7" + }, + { + "name": "fan8" + } + ] + } + ], + "psus": [ + { + "name": "PSU 1", + "fans": [ + { + "name": "psu_1_fan_1" + } + ], + "thermals": [ + { + "name": "PSU-1 Temp" + } + ] + }, + { + "name": "PSU 2", + "fans": [ + { + "name": "PSU-2 Temp" + } + ], + "thermals": [ + { + "name": "xSFP module 1 Temp" + } + ] + } + ], + "thermals": [ + { + "name": "ASIC" + }, + { + "name": "Ambient Fan Side Temp" + }, + { + "name": "Ambient Port Side Temp" + }, + { + "name": "CPU Core 0 Temp" + }, + { + "name": "CPU Core 1 Temp" + }, + { + "name": "CPU Pack Temp" + } + ], + "sfps": [ + { + "name": "sfp1", + "thermals": [ + { + "name": "xSFP module 1 Temp" + } + ] + }, + { + "name": "sfp2", + "thermals": [ + { + "name": "xSFP module 2 Temp" + } + ] + }, + { + "name": "sfp3", + "thermals": [ + { + "name": "xSFP module 3 Temp" + } + ] + }, + { + "name": "sfp4", + "thermals": [ + { + "name": "xSFP module 4 Temp" + } + ] + }, + { + "name": "sfp5", + "thermals": [ + { + "name": "xSFP module 5 Temp" + } + ] + }, + { + "name": "sfp6", + "thermals": [ + { + "name": "xSFP module 6 Temp" + } + ] + }, + { + "name": "sfp7", + "thermals": [ + { + "name": "xSFP module 7 Temp" + } + ] + }, + { + "name": "sfp8", + "thermals": [ + { + "name": "xSFP module 8 Temp" + } + ] + }, + { + "name": "sfp9", + "thermals": [ + { + "name": "xSFP module 9 Temp" + } + ] + }, + { + "name": "sfp10", + "thermals": [ + { + "name": "xSFP module 10 Temp" + } + ] + }, + { + "name": "sfp11", + "thermals": [ + { + "name": "xSFP module 11 Temp" + } + ] + }, + { + "name": "sfp12", + "thermals": [ + { + "name": "xSFP module 12 Temp" + } + ] + }, + { + "name": "sfp13", + "thermals": [ + { + "name": "xSFP module 13 Temp" + } + ] + }, + { + "name": "sfp14", + "thermals": [ + { + "name": "xSFP module 14 Temp" + } + ] + }, + { + "name": "sfp15", + "thermals": [ + { + "name": "xSFP module 15 Temp" + } + ] + }, + { + "name": "sfp16", + "thermals": [ + { + "name": "xSFP module 16 Temp" + } + ] + }, + { + "name": "sfp17", + "thermals": [ + { + "name": "xSFP module 17 Temp" + } + ] + }, + { + "name": "sfp18", + "thermals": [ + { + "name": "xSFP module 18 Temp" + } + ] + }, + { + "name": "sfp19", + "thermals": [ + { + "name": "xSFP module 19 Temp" + } + ] + }, + { + "name": "sfp20", + "thermals": [ + { + "name": "xSFP module 20 Temp" + } + ] + }, + { + "name": "sfp21", + "thermals": [ + { + "name": "xSFP module 21 Temp" + } + ] + }, + { + "name": "sfp22", + "thermals": [ + { + "name": "xSFP module 22 Temp" + } + ] + }, + { + "name": "sfp23", + "thermals": [ + { + "name": "xSFP module 23 Temp" + } + ] + }, + { + "name": "sfp24", + "thermals": [ + { + "name": "xSFP module 24 Temp" + } + ] + }, + { + "name": "sfp25", + "thermals": [ + { + "name": "xSFP module 25 Temp" + } + ] + }, + { + "name": "sfp26", + "thermals": [ + { + "name": "xSFP module 26 Temp" + } + ] + }, + { + "name": "sfp27", + "thermals": [ + { + "name": "xSFP module 27 Temp" + } + ] + }, + { + "name": "sfp28", + "thermals": [ + { + "name": "xSFP module 28 Temp" + } + ] + }, + { + "name": "sfp29", + "thermals": [ + { + "name": "xSFP module 29 Temp" + } + ] + }, + { + "name": "sfp30", + "thermals": [ + { + "name": "xSFP module 30 Temp" + } + ] + }, + { + "name": "sfp31", + "thermals": [ + { + "name": "xSFP module 31 Temp" + } + ] + }, + { + "name": "sfp32", + "thermals": [ + { + "name": "xSFP module 32 Temp" + } + ] + } + ] + }, + "interfaces": { + "Ethernet0": { + "index": "1,1,1,1", + "lanes": "0,1,2,3", + "alias_at_lanes": "etp1a, etp1b, etp1c, etp1d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet4": { + "index": "2,2,2,2", + "lanes": "4,5,6,7", + "alias_at_lanes": "etp2a, etp2b, etp2c, etp2d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet8": { + "index": "3,3,3,3", + "lanes": "8,9,10,11", + "alias_at_lanes": "etp3a, etp3b, etp3c, etp3d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet12": { + "index": "4,4,4,4", + "lanes": "12,13,14,15", + "alias_at_lanes": "etp4a, etp4b, etp4c, etp4d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet16": { + "index": "5,5,5,5", + "lanes": "16,17,18,19", + "alias_at_lanes": "etp5a, etp5b, etp5c, etp5d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet20": { + "index": "6,6,6,6", + "lanes": "20,21,22,23", + "alias_at_lanes": "etp6a, etp6b, etp6c, etp6d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet24": { + "index": "7,7,7,7", + "lanes": "24,25,26,27", + "alias_at_lanes": "etp7a, etp7b, etp7c, etp7d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet28": { + "index": "8,8,8,8", + "lanes": "28,29,30,31", + "alias_at_lanes": "etp8a, etp8b, etp8c, etp8d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet32": { + "index": "9,9,9,9", + "lanes": "32,33,34,35", + "alias_at_lanes": "etp9a, etp9b, etp9c, etp9d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet36": { + "index": "10,10,10,10", + "lanes": "36,37,38,39", + "alias_at_lanes": "etp10a, etp10b, etp10c, etp10d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet40": { + "index": "11,11,11,11", + "lanes": "40,41,42,43", + "alias_at_lanes": "etp11a, etp11b, etp11c, etp11d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet44": { + "index": "12,12,12,12", + "lanes": "44,45,46,47", + "alias_at_lanes": "etp12a, etp12b, etp12c, etp12d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet48": { + "index": "13,13,13,13", + "lanes": "48,49,50,51", + "alias_at_lanes": "etp13a, etp13b, etp13c, etp13d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet52": { + "index": "14,14,14,14", + "lanes": "52,53,54,55", + "alias_at_lanes": "etp14a, etp14b, etp14c, etp14d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet56": { + "index": "15,15,15,15", + "lanes": "56,57,58,59", + "alias_at_lanes": "etp15a, etp15b, etp15c, etp15d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet60": { + "index": "16,16,16,16", + "lanes": "60,61,62,63", + "alias_at_lanes": "etp16a, etp16b, etp16c, etp16d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet64": { + "index": "17,17,17,17", + "lanes": "64,65,66,67", + "alias_at_lanes": "etp17a, etp17b, etp17c, etp17d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet68": { + "index": "18,18,18,18", + "lanes": "68,69,70,71", + "alias_at_lanes": "etp18a, etp18b, etp18c, etp18d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet72": { + "index": "19,19,19,19", + "lanes": "72,73,74,75", + "alias_at_lanes": "etp19a, etp19b, etp19c, etp19d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet76": { + "index": "20,20,20,20", + "lanes": "76,77,78,79", + "alias_at_lanes": "etp20a, etp20b, etp20c, etp20d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet80": { + "index": "21,21,21,21", + "lanes": "80,81,82,83", + "alias_at_lanes": "etp21a, etp21b, etp21c, etp21d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet84": { + "index": "22,22,22,22", + "lanes": "84,85,86,87", + "alias_at_lanes": "etp22a, etp22b, etp22c, etp22d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet88": { + "index": "23,23,23,23", + "lanes": "88,89,90,91", + "alias_at_lanes": "etp23a, etp23b, etp23c, etp23d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet92": { + "index": "24,24,24,24", + "lanes": "92,93,94,95", + "alias_at_lanes": "etp24a, etp24b, etp24c, etp24d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet96": { + "index": "25,25,25,25", + "lanes": "96,97,98,99", + "alias_at_lanes": "etp25a, etp25b, etp25c, etp25d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet100": { + "index": "26,26,26,26", + "lanes": "100,101,102,103", + "alias_at_lanes": "etp26a, etp26b, etp26c, etp26d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet104": { + "index": "27,27,27,27", + "lanes": "104,105,106,107", + "alias_at_lanes": "etp27a, etp27b, etp27c, etp27d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet108": { + "index": "28,28,28,28", + "lanes": "108,109,110,111", + "alias_at_lanes": "etp28a, etp28b, etp28c, etp28d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet112": { + "index": "29,29,29,29", + "lanes": "112,113,114,115", + "alias_at_lanes": "etp29a, etp29b, etp29c, etp29d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet116": { + "index": "30,30,30,30", + "lanes": "116,117,118,119", + "alias_at_lanes": "etp30a, etp30b, etp30c, etp30d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet120": { + "index": "31,31,31,31", + "lanes": "120,121,122,123", + "alias_at_lanes": "etp31a, etp31b, etp31c, etp31d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet124": { + "index": "32,32,32,32", + "lanes": "124,125,126,127", + "alias_at_lanes": "etp32a, etp32b, etp32c, etp32d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn2700-r0/platform_components.json index 2a6069414786..33a73547cc37 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/platform_components.json +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/platform_components.json @@ -1,9 +1,13 @@ { "chassis": { - "x86_64-mlnx_msn2700-r0": { + "MSN2700": { "component": { + "ONIE": { }, + "SSD": { }, "BIOS": { }, - "CPLD": { } + "CPLD1": { }, + "CPLD2": { }, + "CPLD3": { } } } } 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..0f20ffff3b53 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/eeprom.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Mellanox # @@ -10,7 +8,6 @@ ############################################################################# try: - import exceptions import binascii import time import optparse @@ -18,22 +15,38 @@ import os import sys import syslog - from cStringIO import StringIO + + if sys.version_info.major == 3: + from io import StringIO + else: + from cStringIO import StringIO + from sonic_eeprom import eeprom_base from sonic_eeprom import eeprom_tlvinfo + from sonic_py_common.device_info import get_machine_info import subprocess -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") SYSLOG_IDENTIFIER = "eeprom.py" EEPROM_SYMLINK = "/var/run/hw-management/eeprom/vpd_info" CACHE_FILE = "/var/cache/sonic/decode-syseeprom/syseeprom_cache" + def log_error(msg): syslog.openlog(SYSLOG_IDENTIFIER) 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 @@ -44,13 +57,13 @@ def __init__(self, name, path, cpld_root, ro): if not os.path.islink(EEPROM_SYMLINK): time.sleep(1) else: - break - + 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): diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/fanutil.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/fanutil.py index 429bf44750a2..ee6446e7c053 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/fanutil.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/fanutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Mellanox # @@ -16,20 +14,23 @@ from glob import glob from sonic_fan.fan_base import FanBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + def log_err(msg): syslog.openlog("fanutil") syslog.syslog(syslog.LOG_ERR, msg) syslog.closelog() + class FanUtil(FanBase): """Platform-specific FanUtil class""" PWM_MAX = 255 MAX_FAN_PER_DRAWER = 2 GET_HWSKU_CMD = "sonic-cfggen -d -v DEVICE_METADATA.localhost.hwsku" - sku_without_fan_direction = ['ACS-MSN2010', 'ACS-MSN2100', 'ACS-MSN2410', 'ACS-MSN2700', 'Mellanox-SN2700', 'Mellanox-SN2700-D48C8', 'LS-SN2700', 'ACS-MSN2740'] + sku_without_fan_direction = ['ACS-MSN2010', 'ACS-MSN2100', 'ACS-MSN2410', + 'ACS-MSN2700', 'Mellanox-SN2700', 'Mellanox-SN2700-D48C8', 'LS-SN2700', 'ACS-MSN2740'] sku_with_unpluggable_fan = ['ACS-MSN2010', 'ACS-MSN2100'] def __init__(self): @@ -50,12 +51,12 @@ def __init__(self): self.fan_direction = None else: self.fan_direction = "system/fan_dir" - + self.fan_led_green = "led/led_fan*_green" self.num_of_fan, self.num_of_drawer = self._extract_num_of_fans_and_fan_drawers() def _get_sku_name(self): - p = subprocess.Popen(self.GET_HWSKU_CMD, shell=True, stdout=subprocess.PIPE) + p = subprocess.Popen(self.GET_HWSKU_CMD, shell=True, universal_newlines=True, stdout=subprocess.PIPE) out, err = p.communicate() return out.rstrip('\n') @@ -74,7 +75,7 @@ def _extract_num_of_fans_and_fan_drawers(self): def _convert_fan_index_to_drawer_index(self, index): return (index + self.MAX_FAN_PER_DRAWER - 1) / self.MAX_FAN_PER_DRAWER - def _read_file(self, file_pattern, index = 0): + def _read_file(self, file_pattern, index=0): """ Reads the file of the fan @@ -124,7 +125,8 @@ def get_presence(self, index): :return: Boolean, True if FAN is plugged, False if not """ if index > self.num_of_fan: - raise RuntimeError("index ({}) shouldn't be greater than number of fans ({})".format(index, self.num_of_fan)) + raise RuntimeError( + "index ({}) shouldn't be greater than number of fans ({})".format(index, self.num_of_fan)) if self.unpluggable_fan: return True @@ -156,7 +158,8 @@ def get_direction(self, index): return self.FAN_DIRECTION_NOT_APPLICABLE if index > self.num_of_fan: - raise RuntimeError("index ({}) shouldn't be greater than number of fans ({})".format(index, self.num_of_fan)) + raise RuntimeError( + "index ({}) shouldn't be greater than number of fans ({})".format(index, self.num_of_fan)) drawer_index = self._convert_fan_index_to_drawer_index(index) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/psuutil.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/psuutil.py index cd01a1905a06..6da5770c294f 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/psuutil.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/psuutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Mellanox # @@ -14,7 +12,8 @@ import subprocess from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + def log_err(msg): syslog.openlog("psuutil") @@ -30,7 +29,8 @@ class PsuUtil(PsuBase): GET_HWSKU_CMD = "sonic-cfggen -d -v DEVICE_METADATA.localhost.hwsku" # for spectrum1 switches with plugable PSUs, the output voltage file is psuX_volt # for spectrum2 switches the output voltage file is psuX_volt_out2 - sku_spectrum1_with_plugable_psu = ['ACS-MSN2410', 'ACS-MSN2700', 'Mellanox-SN2700', 'Mellanox-SN2700-D48C8', 'LS-SN2700', 'ACS-MSN2740'] + sku_spectrum1_with_plugable_psu = ['ACS-MSN2410', 'ACS-MSN2700', + 'Mellanox-SN2700', 'Mellanox-SN2700-D48C8', 'LS-SN2700', 'ACS-MSN2740'] def __init__(self): PsuBase.__init__(self) @@ -49,7 +49,7 @@ def __init__(self): self.fan_speed = "thermal/psu{}_fan1_speed_get" def _get_sku_name(self): - p = subprocess.Popen(self.GET_HWSKU_CMD, shell=True, stdout=subprocess.PIPE) + p = subprocess.Popen(self.GET_HWSKU_CMD, shell=True, universal_newlines=True, stdout=subprocess.PIPE) out, err = p.communicate() return out.rstrip('\n') diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmget.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmget.py index 170766e9bce4..ca16c3573d06 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmget.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmget.py @@ -1,43 +1,54 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 -import sys, errno -import os -from python_sdk_api.sxd_api import * +""" +This utility get the power mode of a given module. +""" + +import sys +import errno from python_sdk_api.sx_api import * + +def mgmt_phy_mod_pwr_attr_get(handle, module_id, power_attr_type): + sx_mgmt_phy_mod_pwr_attr_p = new_sx_mgmt_phy_mod_pwr_attr_t_p() + sx_mgmt_phy_mod_pwr_attr = sx_mgmt_phy_mod_pwr_attr_t() + sx_mgmt_phy_mod_pwr_attr.power_attr_type = power_attr_type + sx_mgmt_phy_mod_pwr_attr_t_p_assign(sx_mgmt_phy_mod_pwr_attr_p, sx_mgmt_phy_mod_pwr_attr) + try: + rc = sx_mgmt_phy_mod_pwr_attr_get(handle, module_id, sx_mgmt_phy_mod_pwr_attr_p) + assert SX_STATUS_SUCCESS == rc, "sx_mgmt_phy_mod_pwr_attr_get failed" + sx_mgmt_phy_mod_pwr_attr = sx_mgmt_phy_mod_pwr_attr_t_p_value(sx_mgmt_phy_mod_pwr_attr_p) + pwr_mode_attr = sx_mgmt_phy_mod_pwr_attr.pwr_mode_attr + return pwr_mode_attr.admin_pwr_mode_e, pwr_mode_attr.oper_pwr_mode_e + finally: + delete_sx_mgmt_phy_mod_pwr_attr_t_p(sx_mgmt_phy_mod_pwr_attr_p) + + # Check if SFP port number is provided if len(sys.argv) < 2: - print "SFP module number is missed." - print "Usage: sfplpmget.py " + print("SFP module number is missed.") + print("Usage: sfplpmget.py ") sys.exit(errno.EINVAL) # Init SDK API rc, handle = sx_api_open(None) if (rc != SX_STATUS_SUCCESS): - print "Failed to open api handle.\nPlease check that SDK is running." - sys.exit(errno.EACCES) - -pid = os.getpid() -rc = sxd_access_reg_init(pid, None, 0) -if (rc != 0): - print "Failed to initializing register access.\nPlease check that SDK is running." + print("Failed to open api handle.\nPlease check that SDK is running.") sys.exit(errno.EACCES) # Get SFP module number -sfp_module = int(sys.argv[1]) - -# Get MCION -mcion = ku_mcion_reg() -mcion.module = sfp_module -meta = sxd_reg_meta_t() -meta.dev_id = 1 -meta.swid = 0 -meta.access_cmd = SXD_ACCESS_CMD_GET - -rc = sxd_access_reg_mcion(mcion, meta, 1, None, None) -assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_mcion failed, rc = %d" % rc - -# Get low power mode status -lpm_mask = 1 << 8 -lpm_status = (lpm_mask & mcion.module_status_bits) != 0 -print "LPM ON" if lpm_status else "LPM OFF" +sfp_module = int(sys.argv[1]) - 1 + +admin_pwr_mode, oper_pwr_mode = mgmt_phy_mod_pwr_attr_get(handle, sfp_module, SX_MGMT_PHY_MOD_PWR_ATTR_PWR_MODE_E) + +lpm_status = None +if oper_pwr_mode == SX_MGMT_PHY_MOD_PWR_MODE_HIGH_E: + lpm_status = False +elif oper_pwr_mode == SX_MGMT_PHY_MOD_PWR_MODE_LOW_E: + lpm_status = True +else: + print("LPM UNKNOWN") + +print("LPM ON" if lpm_status else "LPM OFF") + +sx_api_close(handle) 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 f9b35b8e74e7..61423880ac71 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py @@ -1,23 +1,18 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 -import sys, errno -import os -from python_sdk_api.sxd_api import * +""" +This utility set the power mode of a given module. +""" + +import sys +import errno from python_sdk_api.sx_api import * -REGISTER_NUM = 1 -SXD_LOG_VERBOSITY_LEVEL = 0 + DEVICE_ID = 1 SWITCH_ID = 0 SX_PORT_ATTR_ARR_SIZE = 64 -PMAOS_ASE = 1 -PMAOS_EE = 1 -PMAOS_E = 2 -PMAOS_RST = 0 -PMAOS_ENABLE = 1 -PMAOS_DISABLE = 2 - PORT_TYPE_CPU = 4 PORT_TYPE_NVE = 8 PORT_TYPE_OFFSET = 28 @@ -25,18 +20,21 @@ 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() module_state_p = new_sx_port_module_state_t_p() rc = sx_api_port_state_get(handle, log_port, oper_state_p, admin_state_p, module_state_p) - assert rc == SXD_STATUS_SUCCESS, "sx_api_port_state_get failed, rc = %d" % rc + assert rc == SX_STATUS_SUCCESS, "sx_api_port_state_get failed, rc = %d" % rc admin_state = sx_port_admin_state_t_p_value(admin_state_p) if admin_state == SX_PORT_ADMIN_STATUS_UP: @@ -44,126 +42,128 @@ def is_port_admin_status_up(log_port): else: return False + def set_port_admin_status_by_log_port(handle, log_port, admin_status): rc = sx_api_port_state_set(handle, log_port, admin_status) assert rc == SX_STATUS_SUCCESS, "sx_api_port_state_set failed, rc = %d" % rc # Get all the ports related to the sfp, if port admin status is up, put it to list + + def get_log_ports(handle, sfp_module): port_attributes_list = new_sx_port_attributes_t_arr(SX_PORT_ATTR_ARR_SIZE) port_cnt_p = new_uint32_t_p() uint32_t_p_assign(port_cnt_p, SX_PORT_ATTR_ARR_SIZE) - rc = sx_api_port_device_get(handle, DEVICE_ID , SWITCH_ID, port_attributes_list, port_cnt_p) + rc = sx_api_port_device_get(handle, DEVICE_ID, SWITCH_ID, port_attributes_list, port_cnt_p) assert rc == SX_STATUS_SUCCESS, "sx_api_port_device_get failed, rc = %d" % rc port_cnt = uint32_t_p_value(port_cnt_p) log_port_list = [] for i in range(0, port_cnt): port_attributes = sx_port_attributes_t_arr_getitem(port_attributes_list, i) - if is_nve(int(port_attributes.log_port)) == False \ - and is_cpu(int(port_attributes.log_port)) == False \ + if not is_nve(int(port_attributes.log_port)) \ + and not is_cpu(int(port_attributes.log_port)) \ 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) return log_port_list -def init_sx_meta_data(): - meta = sxd_reg_meta_t() - meta.dev_id = DEVICE_ID - meta.swid = SWITCH_ID - return meta - -def set_sfp_admin_status(sfp_module, admin_status): - # Get PMAOS - pmaos = ku_pmaos_reg() - pmaos.module = sfp_module - meta = init_sx_meta_data() - meta.access_cmd = SXD_ACCESS_CMD_GET - rc = sxd_access_reg_pmaos(pmaos, meta, REGISTER_NUM, None, None) - assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmaos failed, rc = %d" % rc - - # Set admin status to PMAOS - pmaos.ase = PMAOS_ASE - pmaos.ee = PMAOS_EE - pmaos.e = PMAOS_E - pmaos.rst = PMAOS_RST - if admin_status == SX_PORT_ADMIN_STATUS_DOWN: - pmaos.admin_status = PMAOS_DISABLE - else: - pmaos.admin_status = PMAOS_ENABLE - - meta.access_cmd = SXD_ACCESS_CMD_SET - rc = sxd_access_reg_pmaos(pmaos, meta, REGISTER_NUM, None, None) - assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmaos failed, rc = %d" % rc - -def set_sfp_lpmode(sfp_module, lpm_enable): - # Get PMMP - pmmp = ku_pmmp_reg() - pmmp.module = sfp_module - meta = init_sx_meta_data() - meta.access_cmd = SXD_ACCESS_CMD_GET - rc = sxd_access_reg_pmmp(pmmp, meta, REGISTER_NUM, None, None) - assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmmp failed, rc = %d" % rc - - # Set low power mode status - lpm_mask = 1 << 8 - if lpm_enable: - pmmp.eeprom_override = pmmp.eeprom_override | lpm_mask + +def mgmt_phy_mod_pwr_attr_set(handle, module_id, power_attr_type, admin_pwr_mode): + sx_mgmt_phy_mod_pwr_attr = sx_mgmt_phy_mod_pwr_attr_t() + sx_mgmt_phy_mod_pwr_mode_attr = sx_mgmt_phy_mod_pwr_mode_attr_t() + sx_mgmt_phy_mod_pwr_attr.power_attr_type = power_attr_type + sx_mgmt_phy_mod_pwr_mode_attr.admin_pwr_mode_e = admin_pwr_mode + sx_mgmt_phy_mod_pwr_attr.pwr_mode_attr = sx_mgmt_phy_mod_pwr_mode_attr + sx_mgmt_phy_mod_pwr_attr_p = new_sx_mgmt_phy_mod_pwr_attr_t_p() + sx_mgmt_phy_mod_pwr_attr_t_p_assign(sx_mgmt_phy_mod_pwr_attr_p, sx_mgmt_phy_mod_pwr_attr) + try: + rc = sx_mgmt_phy_mod_pwr_attr_set(handle, SX_ACCESS_CMD_SET, module_id, sx_mgmt_phy_mod_pwr_attr_p) + assert SX_STATUS_SUCCESS == rc, "sx_mgmt_phy_mod_pwr_attr_set failed" + finally: + delete_sx_mgmt_phy_mod_pwr_attr_t_p(sx_mgmt_phy_mod_pwr_attr_p) + + +def mgmt_phy_mod_pwr_attr_get(handle, module_id, power_attr_type): + sx_mgmt_phy_mod_pwr_attr_p = new_sx_mgmt_phy_mod_pwr_attr_t_p() + sx_mgmt_phy_mod_pwr_attr = sx_mgmt_phy_mod_pwr_attr_t() + sx_mgmt_phy_mod_pwr_attr.power_attr_type = power_attr_type + sx_mgmt_phy_mod_pwr_attr_t_p_assign(sx_mgmt_phy_mod_pwr_attr_p, sx_mgmt_phy_mod_pwr_attr) + try: + rc = sx_mgmt_phy_mod_pwr_attr_get(handle, module_id, sx_mgmt_phy_mod_pwr_attr_p) + assert SX_STATUS_SUCCESS == rc, "sx_mgmt_phy_mod_pwr_attr_get failed" + sx_mgmt_phy_mod_pwr_attr = sx_mgmt_phy_mod_pwr_attr_t_p_value(sx_mgmt_phy_mod_pwr_attr_p) + pwr_mode_attr = sx_mgmt_phy_mod_pwr_attr.pwr_mode_attr + return pwr_mode_attr.admin_pwr_mode_e, pwr_mode_attr.oper_pwr_mode_e + finally: + delete_sx_mgmt_phy_mod_pwr_attr_t_p(sx_mgmt_phy_mod_pwr_attr_p) + + +def pwr_attr_set(handle, module_id, ports, attr_type, power_mode): + # Check if the module already works in the same mode + admin_pwr_mode, oper_pwr_mode = mgmt_phy_mod_pwr_attr_get(handle, module_id, attr_type) + if (power_mode == SX_MGMT_PHY_MOD_PWR_MODE_LOW_E and oper_pwr_mode == SX_MGMT_PHY_MOD_PWR_MODE_LOW_E) \ + or (power_mode == SX_MGMT_PHY_MOD_PWR_MODE_AUTO_E and admin_pwr_mode == SX_MGMT_PHY_MOD_PWR_MODE_AUTO_E): + return + try: + # Bring the port down + for port in ports: + set_port_admin_status_by_log_port(handle, port, SX_PORT_ADMIN_STATUS_DOWN) + # Set the desired power mode + mgmt_phy_mod_pwr_attr_set(handle, module_id, attr_type, power_mode) + # Bring the port up + finally: + for port in ports: + set_port_admin_status_by_log_port(handle, port, SX_PORT_ADMIN_STATUS_UP) + + +def set_lpmode(handle, cmd, module_id): + # Construct the port module map. + log_port_list = get_log_ports(handle, module_id) + + if cmd == "enable": + pwr_attr_set(handle, module_id, log_port_list, + SX_MGMT_PHY_MOD_PWR_ATTR_PWR_MODE_E, SX_MGMT_PHY_MOD_PWR_MODE_LOW_E) + print("Enabled low power mode for module [%d]" % module_id) + elif cmd == "disable": + pwr_attr_set(handle, module_id, log_port_list, + SX_MGMT_PHY_MOD_PWR_ATTR_PWR_MODE_E, SX_MGMT_PHY_MOD_PWR_MODE_AUTO_E) + print("Disabled low power mode for module [%d]" % module_id) else: - pmmp.eeprom_override = pmmp.eeprom_override & (~lpm_mask) + print("Error: Invalid command") + sys.exit(0) - meta.access_cmd = SXD_ACCESS_CMD_SET - rc = sxd_access_reg_pmmp(pmmp, meta, REGISTER_NUM, None, None) - assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmmp failed, rc = %d" % rc -# Check if SFP port number is provided if len(sys.argv) < 3: - print "SFP module number or LPM is missed." - print "Usage: sfplpmset.py " + print("SFP module number or LPM is missed.") + print("Usage: sfplpmset.py ") sys.exit(errno.EINVAL) +cmd = None lpm_enable = None if sys.argv[2] == 'on': lpm_enable = True + cmd = 'enable' elif sys.argv[2] == 'off': lpm_enable = False + cmd = 'disable' else: - print "Unrecognized LPM parameter. Please use or values" + print("Unrecognized LPM parameter. Please use or values") sys.exit(errno.EINVAL) -# Init SDK API -rc, handle = sx_api_open(None) -if (rc != SX_STATUS_SUCCESS): - print "Failed to open api handle.\nPlease check that SDK is running." - sys.exit(errno.EACCES) - -pid = os.getpid() -rc = sxd_access_reg_init(pid, None, SXD_LOG_VERBOSITY_LEVEL) -if (rc != SXD_STATUS_SUCCESS): - print "Failed to initializing register access.\nPlease check that SDK is running." - sys.exit(errno.EACCES); - # Get SFP module -sfp_module = int(sys.argv[1]) +sfp_module = int(sys.argv[1]) - 1 -# Get all ports at admin up status that related to the SFP module -log_port_list = get_log_ports(handle, sfp_module) - -# SET SFP related ports to admin down status -for log_port in log_port_list: - set_port_admin_status_by_log_port(handle, log_port, SX_PORT_ADMIN_STATUS_DOWN) - -# Disable admin status before LPM settings -set_sfp_admin_status(sfp_module, SX_PORT_ADMIN_STATUS_DOWN) +print("[+] opening sdk") +rc, handle = sx_api_open(None) -# Set low power mode status -set_sfp_lpmode(sfp_module, lpm_enable) +if (rc != SX_STATUS_SUCCESS): + print("Failed to open api handle.\nPlease check that SDK is running.") + sys.exit(errno.EACCES) -# Enable admin status after LPM settings -set_sfp_admin_status(sfp_module, SX_PORT_ADMIN_STATUS_UP) +# Set low power mode +set_lpmode(handle, cmd, sfp_module) -# SET SFP related ports to admin up status -for log_port in log_port_list: - set_port_admin_status_by_log_port(handle, log_port, SX_PORT_ADMIN_STATUS_UP) +sx_api_close(handle) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfpreset.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfpreset.py index 69fa2be614c2..af237b705e9f 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfpreset.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfpreset.py @@ -1,45 +1,29 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 -import sys, errno -import os -from python_sdk_api.sxd_api import * +""" +This utility reset the given SFP module. +""" + +import sys +import errno from python_sdk_api.sx_api import * # Check if SFP port number is provided if len(sys.argv) < 2: - print "SFP module number or LPM is missed." - print "Usage: sfpreset.py " + print("SFP module number or LPM is missed.") + print("Usage: sfpreset.py ") sys.exit(errno.EINVAL) # Init SDK API rc, handle = sx_api_open(None) -if (rc != SX_STATUS_SUCCESS): - print "Failed to open api handle.\nPlease check that SDK is running." - sys.exit(errno.EACCES) - -pid = os.getpid() -rc = sxd_access_reg_init(pid, None, 0) -if (rc != 0): - print "Failed to initializing register access.\nPlease check that SDK is running." +if rc != SX_STATUS_SUCCESS: + print("Failed to open api handle.\nPlease check that SDK is running.") sys.exit(errno.EACCES) # Get SFP module number -sfp_module = int(sys.argv[1]) - -# Get PMAOS -pmaos = ku_pmaos_reg() -pmaos.module = sfp_module -meta = sxd_reg_meta_t() -meta.dev_id = 1 -meta.swid = 0 -meta.access_cmd = SXD_ACCESS_CMD_GET +sfp_module = int(sys.argv[1]) - 1 -rc = sxd_access_reg_pmaos(pmaos, meta, 1, None, None) -assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmaos failed, rc = %d" % rc +rc = sx_mgmt_phy_mod_reset(handle, sfp_module) +assert rc == SX_STATUS_SUCCESS, "sx_mgmt_phy_mod_reset failed, rc = %d" % rc -# Reset SFP -pmaos.rst = 1 -meta.access_cmd = SXD_ACCESS_CMD_SET -rc = sxd_access_reg_pmaos(pmaos, meta, 1, None, None) -assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmaos failed, rc = %d" % rc -print "Reset flag is set" +sx_api_close(handle) 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..df60c5256f2a 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py @@ -21,7 +21,7 @@ # I2C page size for sfp SFP_I2C_PAGE_SIZE = 256 -# parameters for DB connection +# parameters for DB connection REDIS_TIMEOUT_USECS = 0 # parameters for SFP presence @@ -33,27 +33,32 @@ SYSTEM_READY = 'system_become_ready' SYSTEM_FAIL = 'system_fail' -GET_HWSKU_CMD = "sonic-cfggen -d -v DEVICE_METADATA.localhost.hwsku" +GET_PLATFORM_CMD = "sonic-cfggen -d -v DEVICE_METADATA.localhost.platform" # Ethernet <=> sfp -SFP_PORT_NAME_OFFSET = 1 +SFP_PORT_NAME_OFFSET = 0 SFP_PORT_NAME_CONVENTION = "sfp{}" -# magic code defnition for port number, qsfp port position of each hwsku +# magic code defnition for port number, qsfp port position of each platform # 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} -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)] +platform_dict = {'x86_64-mlnx_msn2700-r0': 0, 'x86_64-mlnx_msn2740-r0': 0, 'x86_64-mlnx_msn2100-r0': 1, 'x86_64-mlnx_msn2410-r0': 2, 'x86_64-mlnx_msn2010-r0': 3, + 'x86_64-mlnx_msn3420-r0': 5, 'x86_64-mlnx_msn3700-r0': 0, 'x86_64-mlnx_msn3700c-r0': 0, 'x86_64-mlnx_msn3800-r0': 4, 'x86_64-mlnx_msn4600c': 4, 'x86_64-mlnx_msn4700-r0': 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), (0, 48, 59, 60, 1)] + def log_info(msg, also_print_to_console=False): syslog.openlog("sfputil") syslog.syslog(syslog.LOG_INFO, msg) syslog.closelog() + def log_err(msg, also_print_to_console=False): syslog.openlog("sfputil") syslog.syslog(syslog.LOG_ERR, msg) syslog.closelog() + class SfpUtil(SfpUtilBase): """Platform-specific SfpUtil class""" PORT_START = 0 @@ -79,24 +84,24 @@ def port_end(self): @property def qsfp_ports(self): - return range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1) + return list(range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): - print "dependency on sysfs has been removed" - raise Exception() + print("dependency on sysfs has been removed") + raise Exception() - def get_port_position_tuple_by_sku_name(self): - p = subprocess.Popen(GET_HWSKU_CMD, shell=True, stdout=subprocess.PIPE) + def get_port_position_tuple_by_platform_name(self): + p = subprocess.Popen(GET_PLATFORM_CMD, shell=True, universal_newlines=True, stdout=subprocess.PIPE) out, err = p.communicate() - position_tuple = port_position_tuple_list[hwsku_dict[out.rstrip('\n')]] + position_tuple = port_position_tuple_list[platform_dict[out.rstrip('\n')]] return position_tuple def __init__(self): - port_position_tuple = self.get_port_position_tuple_by_sku_name() - self.PORT_START = port_position_tuple[0] - self.QSFP_PORT_START = port_position_tuple[1] - self.PORT_END = port_position_tuple[2] + port_position_tuple = self.get_port_position_tuple_by_platform_name() + self.PORT_START = port_position_tuple[0] + 1 + self.QSFP_PORT_START = port_position_tuple[1] + 1 + self.PORT_END = port_position_tuple[2] + 1 self.PORTS_IN_BLOCK = port_position_tuple[3] self.EEPROM_OFFSET = port_position_tuple[4] self.mlnx_sfpd_started = False @@ -115,14 +120,14 @@ def get_presence(self, port_num): ethtool_cmd = "ethtool -m {} 2>/dev/null".format(sfpname) try: - proc = subprocess.Popen(ethtool_cmd, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT) + proc = subprocess.Popen(ethtool_cmd, stdout=subprocess.PIPE, shell=True, universal_newlines=True, stderr=subprocess.STDOUT) stdout = proc.communicate()[0] proc.wait() result = stdout.rstrip('\n') if result != '': presence = True - except OSError, e: + except OSError as e: return presence return presence @@ -135,11 +140,11 @@ def get_low_power_mode(self, port_num): lpm_cmd = "docker exec syncd python /usr/share/sonic/platform/plugins/sfplpmget.py {}".format(port_num) try: - output = subprocess.check_output(lpm_cmd, shell=True) + output = subprocess.check_output(lpm_cmd, shell=True, universal_newlines=True) if 'LPM ON' in output: return True except subprocess.CalledProcessError as e: - print "Error! Unable to get LPM for {}, rc = {}, err msg: {}".format(port_num, e.returncode, e.output) + print("Error! Unable to get LPM for {}, rc = {}, err msg: {}".format(port_num, e.returncode, e.output)) return False return False @@ -159,9 +164,9 @@ def set_low_power_mode(self, port_num, lpmode): # Set LPM try: - subprocess.check_output(lpm_cmd, shell=True) + subprocess.check_output(lpm_cmd, shell=True, universal_newlines=True) except subprocess.CalledProcessError as e: - print "Error! Unable to set LPM for {}, rc = {}, err msg: {}".format(port_num, e.returncode, e.output) + print("Error! Unable to set LPM for {}, rc = {}, err msg: {}".format(port_num, e.returncode, e.output)) return False return True @@ -174,10 +179,10 @@ def reset(self, port_num): lpm_cmd = "docker exec syncd python /usr/share/sonic/platform/plugins/sfpreset.py {}".format(port_num) try: - subprocess.check_output(lpm_cmd, shell=True) + subprocess.check_output(lpm_cmd, shell=True, universal_newlines=True) return True except subprocess.CalledProcessError as e: - print "Error! Unable to set LPM for {}, rc = {}, err msg: {}".format(port_num, e.returncode, e.output) + print("Error! Unable to set LPM for {}, rc = {}, err msg: {}".format(port_num, e.returncode, e.output)) return False return False @@ -186,7 +191,7 @@ def get_transceiver_change_event(self, timeout=0): phy_port_dict = {} status = True - if self.db_sel == None: + if self.db_sel is None: from swsscommon import swsscommon self.state_db = swsscommon.DBConnector("STATE_DB", REDIS_TIMEOUT_USECS, @@ -247,7 +252,7 @@ def _read_eeprom_specific_bytes_via_ethtool(self, port_num, offset, num_bytes): eeprom_raw = [] ethtool_cmd = "ethtool -m {} hex on offset {} length {}".format(sfpname, offset, num_bytes) try: - output = subprocess.check_output(ethtool_cmd, shell=True) + output = subprocess.check_output(ethtool_cmd, shell=True, universal_newlines=True) output_lines = output.splitlines() first_line_raw = output_lines[0] if "Offset" in first_line_raw: @@ -260,13 +265,13 @@ def _read_eeprom_specific_bytes_via_ethtool(self, port_num, offset, num_bytes): return eeprom_raw # Read eeprom - def _read_eeprom_devid(self, port_num, devid, offset, num_bytes = 512): + def _read_eeprom_devid(self, port_num, devid, offset, num_bytes=512): if port_num in self.osfp_ports: pass elif port_num in self.qsfp_ports: pass elif (self.DOM_EEPROM_ADDR == devid): - offset += 256 + offset += 256 eeprom_raw = self._read_eeprom_specific_bytes_via_ethtool(port_num, offset, num_bytes) @@ -289,45 +294,50 @@ def get_transceiver_info_dict(self, port_num): print("Error: sfp_object open failed") return None - sfp_type_raw = self._read_eeprom_specific_bytes_via_ethtool(port_num, (offset + OSFP_TYPE_OFFSET), XCVR_TYPE_WIDTH) + sfp_type_raw = self._read_eeprom_specific_bytes_via_ethtool( + port_num, (offset + OSFP_TYPE_OFFSET), XCVR_TYPE_WIDTH) if sfp_type_raw is not None: sfp_type_data = sfpi_obj.parse_sfp_type(sfp_type_raw, 0) else: return None - sfp_vendor_name_raw = self._read_eeprom_specific_bytes_via_ethtool(port_num, (offset + OSFP_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) + sfp_vendor_name_raw = self._read_eeprom_specific_bytes_via_ethtool( + port_num, (offset + OSFP_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) if sfp_vendor_name_raw is not None: sfp_vendor_name_data = sfpi_obj.parse_vendor_name(sfp_vendor_name_raw, 0) else: return None - sfp_vendor_pn_raw = self._read_eeprom_specific_bytes_via_ethtool(port_num, (offset + OSFP_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + sfp_vendor_pn_raw = self._read_eeprom_specific_bytes_via_ethtool( + port_num, (offset + OSFP_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) if sfp_vendor_pn_raw is not None: sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0) else: return None - sfp_vendor_rev_raw = self._read_eeprom_specific_bytes_via_ethtool(port_num, (offset + OSFP_HW_REV_OFFSET), vendor_rev_width) + sfp_vendor_rev_raw = self._read_eeprom_specific_bytes_via_ethtool( + port_num, (offset + OSFP_HW_REV_OFFSET), vendor_rev_width) if sfp_vendor_rev_raw is not None: sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_vendor_rev_raw, 0) else: return None - sfp_vendor_sn_raw = self._read_eeprom_specific_bytes_via_ethtool(port_num, (offset + OSFP_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + sfp_vendor_sn_raw = self._read_eeprom_specific_bytes_via_ethtool( + port_num, (offset + OSFP_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) if sfp_vendor_sn_raw is not None: sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_vendor_sn_raw, 0) else: return None transceiver_info_dict['type'] = sfp_type_data['data']['type']['value'] - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] # Below part is added to avoid fail the xcvrd, shall be implemented later transceiver_info_dict['vendor_oui'] = 'N/A' transceiver_info_dict['vendor_date'] = 'N/A' - transceiver_info_dict['Connector'] = 'N/A' + transceiver_info_dict['connector'] = 'N/A' transceiver_info_dict['encoding'] = 'N/A' transceiver_info_dict['ext_identifier'] = 'N/A' transceiver_info_dict['ext_rateselect_compliance'] = 'N/A' @@ -361,56 +371,64 @@ def get_transceiver_info_dict(self, port_num): print("Error: sfp_object open failed") return None - sfp_interface_bulk_raw = self._read_eeprom_specific_bytes_via_ethtool(port_num, (offset + XCVR_INTFACE_BULK_OFFSET), interface_info_bulk_width) + sfp_interface_bulk_raw = self._read_eeprom_specific_bytes_via_ethtool( + port_num, (offset + XCVR_INTFACE_BULK_OFFSET), interface_info_bulk_width) if sfp_interface_bulk_raw is not None: sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(sfp_interface_bulk_raw, 0) else: return None - sfp_vendor_name_raw = self._read_eeprom_specific_bytes_via_ethtool(port_num, (offset + XCVR_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) + sfp_vendor_name_raw = self._read_eeprom_specific_bytes_via_ethtool( + port_num, (offset + XCVR_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) if sfp_vendor_name_raw is not None: sfp_vendor_name_data = sfpi_obj.parse_vendor_name(sfp_vendor_name_raw, 0) else: return None - sfp_vendor_pn_raw = self._read_eeprom_specific_bytes_via_ethtool(port_num, (offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + sfp_vendor_pn_raw = self._read_eeprom_specific_bytes_via_ethtool( + port_num, (offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) if sfp_vendor_pn_raw is not None: sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0) else: return None - sfp_vendor_rev_raw = self._read_eeprom_specific_bytes_via_ethtool(port_num, (offset + XCVR_HW_REV_OFFSET), vendor_rev_width) + sfp_vendor_rev_raw = self._read_eeprom_specific_bytes_via_ethtool( + port_num, (offset + XCVR_HW_REV_OFFSET), vendor_rev_width) if sfp_vendor_rev_raw is not None: sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_vendor_rev_raw, 0) else: return None - sfp_vendor_sn_raw = self._read_eeprom_specific_bytes_via_ethtool(port_num, (offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + sfp_vendor_sn_raw = self._read_eeprom_specific_bytes_via_ethtool( + port_num, (offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) if sfp_vendor_sn_raw is not None: sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_vendor_sn_raw, 0) else: return None - sfp_vendor_oui_raw = self._read_eeprom_specific_bytes_via_ethtool(port_num, (offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH) + sfp_vendor_oui_raw = self._read_eeprom_specific_bytes_via_ethtool( + port_num, (offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH) if sfp_vendor_oui_raw is not None: sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(sfp_vendor_oui_raw, 0) else: return None - sfp_vendor_date_raw = self._read_eeprom_specific_bytes_via_ethtool(port_num, (offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH) + sfp_vendor_date_raw = self._read_eeprom_specific_bytes_via_ethtool( + port_num, (offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH) if sfp_vendor_date_raw is not None: sfp_vendor_date_data = sfpi_obj.parse_vendor_date(sfp_vendor_date_raw, 0) else: return None transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] - transceiver_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] - transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['vendor_date'] = sfp_vendor_date_data[ + 'data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] @@ -424,8 +442,9 @@ def get_transceiver_info_dict(self, port_num): if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) - - transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value']) + + transceiver_info_dict['nominal_bit_rate'] = str( + sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value']) else: for key in sfp_cable_length_tup: if key in sfp_interface_bulk_data['data']: @@ -437,7 +456,8 @@ def get_transceiver_info_dict(self, port_num): compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) - transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) + transceiver_info_dict['nominal_bit_rate'] = str( + sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) return transceiver_info_dict @@ -447,15 +467,15 @@ def get_transceiver_dom_info_dict(self, port_num): # Below part is added to avoid failing xcvrd # Currently, the way in which dom data is read has been changed from # using sysfs to using ethtool. - # The ethtool returns None for ports without dom support, resulting in - # None being returned. However, this fails xcvrd to add the + # The ethtool returns None for ports without dom support, resulting in + # None being returned. However, this fails xcvrd to add the # TRANSCEIVER_DOM_SENSOR table entry of associated port to CONFIG_DB # and then causes SNMP fail. # To address this issue a default dict is initialized with all data set to # 'N/A' and is returned is the above case. # BTW, in the original implementation which sysfs is used to read dom data, - # even though non-None data is returned for ports without dom support, - # it does not contain valid data. This can result in wrong data in + # even though non-None data is returned for ports without dom support, + # it does not contain valid data. This can result in wrong data in # TRANSCEIVER_DOM_SENSOR table. transceiver_dom_info_dict['temperature'] = 'N/A' transceiver_dom_info_dict['voltage'] = 'N/A' @@ -486,30 +506,33 @@ def get_transceiver_dom_info_dict(self, port_num): if sfpi_obj is None: return None - # 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_via_ethtool(port_num, (offset_xcvr + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) + qsfp_dom_capability_raw = self._read_eeprom_specific_bytes_via_ethtool( + port_num, (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) + qspf_dom_capability_data = sfpi_obj.parse_dom_capability(qsfp_dom_capability_raw, 0) else: return transceiver_dom_info_dict - dom_temperature_raw = self._read_eeprom_specific_bytes_via_ethtool(port_num, (offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) + dom_temperature_raw = self._read_eeprom_specific_bytes_via_ethtool( + port_num, (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_via_ethtool(port_num, (offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) + dom_voltage_raw = self._read_eeprom_specific_bytes_via_ethtool( + port_num, (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_via_ethtool(port_num, (offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH) + qsfp_dom_rev_raw = self._read_eeprom_specific_bytes_via_ethtool( + port_num, (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: @@ -524,15 +547,18 @@ def get_transceiver_dom_info_dict(self, port_num): 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_via_ethtool(port_num, (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WIDTH) + dom_channel_monitor_raw = self._read_eeprom_specific_bytes_via_ethtool( + port_num, (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 else: - dom_channel_monitor_raw = self._read_eeprom_specific_bytes_via_ethtool(port_num, (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + dom_channel_monitor_raw = self._read_eeprom_specific_bytes_via_ethtool( + port_num, (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) + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power( + dom_channel_monitor_raw, 0) else: return transceiver_dom_info_dict @@ -556,8 +582,9 @@ def get_transceiver_dom_info_dict(self, port_num): offset = SFP_I2C_PAGE_SIZE eeprom_raw = ['0'] * SFP_I2C_PAGE_SIZE - eeprom_raw[XCVR_DOM_CAPABILITY_OFFSET : XCVR_DOM_CAPABILITY_OFFSET + XCVR_DOM_CAPABILITY_WIDTH] = \ - self._read_eeprom_specific_bytes_via_ethtool(port_num, XCVR_DOM_CAPABILITY_OFFSET, XCVR_DOM_CAPABILITY_WIDTH) + eeprom_raw[XCVR_DOM_CAPABILITY_OFFSET: XCVR_DOM_CAPABILITY_OFFSET + XCVR_DOM_CAPABILITY_WIDTH] = \ + self._read_eeprom_specific_bytes_via_ethtool( + port_num, XCVR_DOM_CAPABILITY_OFFSET, XCVR_DOM_CAPABILITY_WIDTH) sfp_obj = sff8472InterfaceId() calibration_type = sfp_obj._get_calibration_type(eeprom_raw) @@ -571,7 +598,7 @@ def get_transceiver_dom_info_dict(self, port_num): sfpd_obj = sff8472Dom(None, calibration_type) if sfpd_obj is None: - print "no sff8472Dom" + print("no sff8472Dom") return None dom_temperature_raw = eeprom_domraw[SFP_TEMPE_OFFSET:SFP_TEMPE_OFFSET+SFP_TEMPE_WIDTH] @@ -604,7 +631,7 @@ def get_transceiver_dom_threshold_info_dict(self, port_num): '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: @@ -614,8 +641,9 @@ def get_transceiver_dom_threshold_info_dict(self, port_num): offset = SFP_I2C_PAGE_SIZE eeprom_raw = ['0'] * SFP_I2C_PAGE_SIZE - eeprom_raw[XCVR_DOM_CAPABILITY_OFFSET : XCVR_DOM_CAPABILITY_OFFSET + XCVR_DOM_CAPABILITY_WIDTH] = \ - self._read_eeprom_specific_bytes_via_ethtool(port_num, XCVR_DOM_CAPABILITY_OFFSET, XCVR_DOM_CAPABILITY_WIDTH) + eeprom_raw[XCVR_DOM_CAPABILITY_OFFSET: XCVR_DOM_CAPABILITY_OFFSET + XCVR_DOM_CAPABILITY_WIDTH] = \ + self._read_eeprom_specific_bytes_via_ethtool( + port_num, XCVR_DOM_CAPABILITY_OFFSET, XCVR_DOM_CAPABILITY_WIDTH) sfp_obj = sff8472InterfaceId() calibration_type = sfp_obj._get_calibration_type(eeprom_raw) @@ -628,8 +656,8 @@ def get_transceiver_dom_threshold_info_dict(self, port_num): return transceiver_dom_threshold_info_dict dom_module_threshold_raw = self._read_eeprom_specific_bytes_via_ethtool(port_num, - (offset + SFP_MODULE_THRESHOLD_OFFSET), - SFP_MODULE_THRESHOLD_WIDTH) + (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: diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/thermalutil.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/thermalutil.py index 73d27a41ac23..980ef8a9fc38 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/thermalutil.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/thermalutil.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Mellanox # @@ -14,7 +12,8 @@ import subprocess from sonic_thermal.thermal_base import ThermalBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + def log_info(msg): syslog.openlog("thermalutil") @@ -44,57 +43,57 @@ def log_info(msg): HW_MGMT_THERMAL_ROOT = "/var/run/hw-management/thermal/" thermal_api_handler_cpu_core = { - THERMAL_API_GET_TEMPERATURE:"cpu_core{}", - THERMAL_API_GET_HIGH_THRESHOLD:"cpu_core{}_max", - THERMAL_API_GET_HIGH_CRITICAL_THRESHOLD:"cpu_core{}_crit" + THERMAL_API_GET_TEMPERATURE: "cpu_core{}", + THERMAL_API_GET_HIGH_THRESHOLD: "cpu_core{}_max", + THERMAL_API_GET_HIGH_CRITICAL_THRESHOLD: "cpu_core{}_crit" } thermal_api_handler_cpu_pack = { - THERMAL_API_GET_TEMPERATURE:"cpu_pack", - THERMAL_API_GET_HIGH_THRESHOLD:"cpu_pack_max", - THERMAL_API_GET_HIGH_CRITICAL_THRESHOLD:"cpu_pack_crit" + THERMAL_API_GET_TEMPERATURE: "cpu_pack", + THERMAL_API_GET_HIGH_THRESHOLD: "cpu_pack_max", + THERMAL_API_GET_HIGH_CRITICAL_THRESHOLD: "cpu_pack_crit" } thermal_api_handler_module = { - THERMAL_API_GET_TEMPERATURE:"module{}_temp_input", - THERMAL_API_GET_HIGH_THRESHOLD:"module{}_temp_crit", - THERMAL_API_GET_HIGH_CRITICAL_THRESHOLD:"module{}_temp_emergency" + THERMAL_API_GET_TEMPERATURE: "module{}_temp_input", + THERMAL_API_GET_HIGH_THRESHOLD: "module{}_temp_crit", + THERMAL_API_GET_HIGH_CRITICAL_THRESHOLD: "module{}_temp_emergency" } thermal_api_handler_psu = { - THERMAL_API_GET_TEMPERATURE:"psu{}_temp", - THERMAL_API_GET_HIGH_THRESHOLD:"psu{}_temp_max", - THERMAL_API_GET_HIGH_CRITICAL_THRESHOLD:None + THERMAL_API_GET_TEMPERATURE: "psu{}_temp", + THERMAL_API_GET_HIGH_THRESHOLD: "psu{}_temp_max", + THERMAL_API_GET_HIGH_CRITICAL_THRESHOLD: None } thermal_api_handler_gearbox = { - THERMAL_API_GET_TEMPERATURE:"gearbox{}_temp_input", - THERMAL_API_GET_HIGH_THRESHOLD:None, - THERMAL_API_GET_HIGH_CRITICAL_THRESHOLD:None + THERMAL_API_GET_TEMPERATURE: "gearbox{}_temp_input", + THERMAL_API_GET_HIGH_THRESHOLD: None, + THERMAL_API_GET_HIGH_CRITICAL_THRESHOLD: None } thermal_ambient_apis = { - THERMAL_DEV_ASIC_AMBIENT : "asic", - THERMAL_DEV_PORT_AMBIENT : "port_amb", - THERMAL_DEV_FAN_AMBIENT : "fan_amb", - THERMAL_DEV_COMEX_AMBIENT : "comex_amb", - THERMAL_DEV_BOARD_AMBIENT : "board_amb" + THERMAL_DEV_ASIC_AMBIENT: "asic", + THERMAL_DEV_PORT_AMBIENT: "port_amb", + THERMAL_DEV_FAN_AMBIENT: "fan_amb", + THERMAL_DEV_COMEX_AMBIENT: "comex_amb", + THERMAL_DEV_BOARD_AMBIENT: "board_amb" } thermal_ambient_name = { - THERMAL_DEV_ASIC_AMBIENT : "Ambient ASIC Temp", - THERMAL_DEV_PORT_AMBIENT : "Ambient Port Side Temp", - THERMAL_DEV_FAN_AMBIENT : "Ambient Fan Side Temp", - THERMAL_DEV_COMEX_AMBIENT : "Ambient COMEX Temp", - THERMAL_DEV_BOARD_AMBIENT : "Ambient Board Temp" + THERMAL_DEV_ASIC_AMBIENT: "Ambient ASIC Temp", + THERMAL_DEV_PORT_AMBIENT: "Ambient Port Side Temp", + THERMAL_DEV_FAN_AMBIENT: "Ambient Fan Side Temp", + THERMAL_DEV_COMEX_AMBIENT: "Ambient COMEX Temp", + THERMAL_DEV_BOARD_AMBIENT: "Ambient Board Temp" } thermal_api_handlers = { - THERMAL_DEV_CATEGORY_CPU_CORE : thermal_api_handler_cpu_core, - THERMAL_DEV_CATEGORY_CPU_PACK : thermal_api_handler_cpu_pack, - THERMAL_DEV_CATEGORY_MODULE : thermal_api_handler_module, - THERMAL_DEV_CATEGORY_PSU : thermal_api_handler_psu, - THERMAL_DEV_CATEGORY_GEARBOX : thermal_api_handler_gearbox + THERMAL_DEV_CATEGORY_CPU_CORE: thermal_api_handler_cpu_core, + THERMAL_DEV_CATEGORY_CPU_PACK: thermal_api_handler_cpu_pack, + THERMAL_DEV_CATEGORY_MODULE: thermal_api_handler_module, + THERMAL_DEV_CATEGORY_PSU: thermal_api_handler_psu, + THERMAL_DEV_CATEGORY_GEARBOX: thermal_api_handler_gearbox } thermal_name = { - THERMAL_DEV_CATEGORY_CPU_CORE : "CPU Core {} Temp", - THERMAL_DEV_CATEGORY_CPU_PACK : "CPU Pack Temp", - THERMAL_DEV_CATEGORY_MODULE : "xSFP module {} Temp", - THERMAL_DEV_CATEGORY_PSU : "PSU-{} Temp", - THERMAL_DEV_CATEGORY_GEARBOX : "Gearbox {} Temp" + THERMAL_DEV_CATEGORY_CPU_CORE: "CPU Core {} Temp", + THERMAL_DEV_CATEGORY_CPU_PACK: "CPU Pack Temp", + THERMAL_DEV_CATEGORY_MODULE: "xSFP module {} Temp", + THERMAL_DEV_CATEGORY_PSU: "PSU-{} Temp", + THERMAL_DEV_CATEGORY_GEARBOX: "Gearbox {} Temp" } thermal_device_categories_all = [ @@ -115,130 +114,131 @@ def log_info(msg): 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} thermal_profile_list = [ # 2700 { - THERMAL_DEV_CATEGORY_CPU_CORE:(0, 2), - 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_PORT_AMBIENT, - THERMAL_DEV_FAN_AMBIENT - ] - ) + THERMAL_DEV_CATEGORY_CPU_CORE: (0, 2), + 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_PORT_AMBIENT, + THERMAL_DEV_FAN_AMBIENT + ] + ) }, # 2100 { - THERMAL_DEV_CATEGORY_CPU_CORE:(0, 4), - THERMAL_DEV_CATEGORY_MODULE:(1, 16), - THERMAL_DEV_CATEGORY_PSU:(0, 0), - THERMAL_DEV_CATEGORY_CPU_PACK:(0,0), - THERMAL_DEV_CATEGORY_GEARBOX:(0,0), - THERMAL_DEV_CATEGORY_AMBIENT:(0, - [ - THERMAL_DEV_ASIC_AMBIENT, - THERMAL_DEV_PORT_AMBIENT, - THERMAL_DEV_FAN_AMBIENT, - ] - ) + THERMAL_DEV_CATEGORY_CPU_CORE: (0, 4), + THERMAL_DEV_CATEGORY_MODULE: (1, 16), + THERMAL_DEV_CATEGORY_PSU: (0, 0), + THERMAL_DEV_CATEGORY_CPU_PACK: (0, 0), + THERMAL_DEV_CATEGORY_GEARBOX: (0, 0), + THERMAL_DEV_CATEGORY_AMBIENT: (0, + [ + THERMAL_DEV_ASIC_AMBIENT, + THERMAL_DEV_PORT_AMBIENT, + THERMAL_DEV_FAN_AMBIENT, + ] + ) }, # 2410 { - THERMAL_DEV_CATEGORY_CPU_CORE:(0, 2), - THERMAL_DEV_CATEGORY_MODULE:(1, 56), - 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_PORT_AMBIENT, - THERMAL_DEV_FAN_AMBIENT, - ] - ) + THERMAL_DEV_CATEGORY_CPU_CORE: (0, 2), + THERMAL_DEV_CATEGORY_MODULE: (1, 56), + 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_PORT_AMBIENT, + THERMAL_DEV_FAN_AMBIENT, + ] + ) }, # 2740 { - 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,0), - THERMAL_DEV_CATEGORY_GEARBOX:(0,0), - THERMAL_DEV_CATEGORY_AMBIENT:(0, - [ - THERMAL_DEV_ASIC_AMBIENT, - THERMAL_DEV_PORT_AMBIENT, - THERMAL_DEV_FAN_AMBIENT, - ] - ) + 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, 0), + THERMAL_DEV_CATEGORY_GEARBOX: (0, 0), + THERMAL_DEV_CATEGORY_AMBIENT: (0, + [ + THERMAL_DEV_ASIC_AMBIENT, + THERMAL_DEV_PORT_AMBIENT, + THERMAL_DEV_FAN_AMBIENT, + ] + ) }, # 2010 { - THERMAL_DEV_CATEGORY_CPU_CORE:(0, 4), - THERMAL_DEV_CATEGORY_MODULE:(1, 22), - THERMAL_DEV_CATEGORY_PSU:(0, 0), - THERMAL_DEV_CATEGORY_CPU_PACK:(0,0), - THERMAL_DEV_CATEGORY_GEARBOX:(0,0), - THERMAL_DEV_CATEGORY_AMBIENT:(0, - [ - THERMAL_DEV_ASIC_AMBIENT, - THERMAL_DEV_PORT_AMBIENT, - THERMAL_DEV_FAN_AMBIENT, - ] - ) + THERMAL_DEV_CATEGORY_CPU_CORE: (0, 4), + THERMAL_DEV_CATEGORY_MODULE: (1, 22), + THERMAL_DEV_CATEGORY_PSU: (0, 0), + THERMAL_DEV_CATEGORY_CPU_PACK: (0, 0), + THERMAL_DEV_CATEGORY_GEARBOX: (0, 0), + THERMAL_DEV_CATEGORY_AMBIENT: (0, + [ + THERMAL_DEV_ASIC_AMBIENT, + THERMAL_DEV_PORT_AMBIENT, + THERMAL_DEV_FAN_AMBIENT, + ] + ) }, # 3700 { - 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 - ] - ) + 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 + ] + ) }, # 3700c { - THERMAL_DEV_CATEGORY_CPU_CORE:(0, 2), - 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 - ] - ) + THERMAL_DEV_CATEGORY_CPU_CORE: (0, 2), + 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 + ] + ) }, # 3800 { - THERMAL_DEV_CATEGORY_CPU_CORE:(0, 4), - THERMAL_DEV_CATEGORY_MODULE:(1, 64), - THERMAL_DEV_CATEGORY_PSU:(1, 2), - THERMAL_DEV_CATEGORY_CPU_PACK:(0,1), - THERMAL_DEV_CATEGORY_GEARBOX:(1,32), - THERMAL_DEV_CATEGORY_AMBIENT:(0, - [ - THERMAL_DEV_ASIC_AMBIENT, - THERMAL_DEV_COMEX_AMBIENT, - THERMAL_DEV_PORT_AMBIENT, - THERMAL_DEV_FAN_AMBIENT - ] - ) + THERMAL_DEV_CATEGORY_CPU_CORE: (0, 4), + THERMAL_DEV_CATEGORY_MODULE: (1, 64), + THERMAL_DEV_CATEGORY_PSU: (1, 2), + THERMAL_DEV_CATEGORY_CPU_PACK: (0, 1), + THERMAL_DEV_CATEGORY_GEARBOX: (1, 32), + THERMAL_DEV_CATEGORY_AMBIENT: (0, + [ + THERMAL_DEV_ASIC_AMBIENT, + THERMAL_DEV_COMEX_AMBIENT, + THERMAL_DEV_PORT_AMBIENT, + THERMAL_DEV_FAN_AMBIENT + ] + ) }, ] @@ -364,7 +364,7 @@ class ThermalUtil(ThermalBase): thermal_list = [] def _get_sku_name(self): - p = subprocess.Popen(self.GET_HWSKU_CMD, shell=True, stdout=subprocess.PIPE) + p = subprocess.Popen(self.GET_HWSKU_CMD, shell=True, universal_newlines=True, stdout=subprocess.PIPE) out, err = p.communicate() return out.rstrip('\n') diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/pmon_daemon_control.json b/device/mellanox/x86_64-mlnx_msn2700-r0/pmon_daemon_control.json index 44bad6494229..dec2ba6d7826 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/pmon_daemon_control.json +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/pmon_daemon_control.json @@ -1,4 +1,7 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_fancontrol": true, + "delay_xcvrd": true, + "python2_daemons": ["xcvrd"] } diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn2700-r0/sensors.conf index 247db54f99d8..62f100d757e7 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/sensors.conf +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/sensors.conf @@ -1,95 +1,81 @@ -bus "i2c-7" "i2c-1-mux (chan_id 5)" -chip "lm75-i2c-7-4a" - label temp1 "Ambient Port Temp" +################################################################################ +# Copyright (c) 2020 Mellanox Technologies +# +# Platform specific sensors config for SN2700 +################################################################################ -bus "i2c-5" "i2c-1-mux (chan_id 3)" -chip "ucd9200-i2c-5-27" - label in1 "UCD1 vin" - label in2 "ASIC 3.3 vout" - label in3 "ASIC 1.2 vout" - label temp1 "UCD1 Temp" - label temp2 "UCD1 Temp2" +# Temperature sensors +bus "i2c-2" "i2c-1-mux (chan_id 2)" + chip "mlxsw-i2c-*-48" + label temp1 "Ambient ASIC Temp" -chip "ucd9200-i2c-5-41" - label in1 "UCD2 vin" - label in2 "ASIC Vcore vout" - label temp1 "UCD2 Temp1" - label temp2 "UCD2 Temp2" +bus "i2c-7" "i2c-1-mux (chan_id 7)" + chip "lm75-i2c-7-4a" + label temp1 "Ambient Port Temp" -bus "i2c-17" "i2c-1-mux (chan_id 7)" -chip "lm75-i2c-17-49" - label temp1 "Ambient Board Temp" +bus "i2c-17" "i2c-1-mux (chan_id 17)" + chip "lm75-i2c-17-49" + label temp1 "Ambient Fan Temp" -chip "mlxsw-*" - ignore temp2 - ignore temp3 - ignore temp4 - ignore temp5 - ignore temp6 - ignore temp7 - ignore temp8 - ignore temp9 - ignore temp10 - ignore temp11 - ignore temp12 - ignore temp13 - ignore temp14 - ignore temp15 - ignore temp16 - ignore temp17 - ignore temp18 - ignore temp19 - ignore temp20 - ignore temp21 - ignore temp22 - ignore temp23 - ignore temp24 - ignore temp25 - ignore temp26 - ignore temp27 - ignore temp28 - ignore temp29 - ignore temp30 - ignore temp31 - ignore temp32 - ignore temp33 - ignore temp34 - ignore temp35 - ignore temp36 - ignore temp37 - ignore temp38 - ignore temp39 - ignore temp40 - ignore temp41 - ignore temp42 - ignore temp43 - ignore temp44 - ignore temp45 - ignore temp46 - ignore temp47 - ignore temp48 - ignore temp49 - ignore temp50 - ignore temp51 - ignore temp52 - ignore temp53 - ignore temp54 - ignore temp55 - ignore temp56 - ignore temp57 - ignore temp58 - ignore temp59 - ignore temp60 - ignore temp61 - ignore temp62 - ignore temp63 - ignore temp64 +chip "acpitz-virtual-0" + label temp1 "ACPI CPU Temp" + label temp2 "ACPI Board Temp" -chip "*-virtual-*" - ignore temp1 - ignore temp2 +# Power controllers +bus "i2c-5" "i2c-1-mux (chan_id 5)" + chip "pmbus-i2c-5-41" + label in1 "PMB-1 PSU 12V Rail (in)" + label in2 "PMB-1 0.9V VCORE Rail (out)" + label temp1 "PMB-1 Temp 1" + label temp2 "PMB-1 Temp 2" + ignore power1 + label power2 "PMB-1 0.9V VCORE Rail Pwr (out)" + ignore curr1 + label curr2 "PMB-1 0.9V VCORE Rail Curr (out)" + chip "pmbus-i2c-5-27" + label in1 "PMB-2 PSU 12V Rail (in)" + label in2 "PMB-2 3.3V Rail (out)" + label in3 "PMB-2 1.2V Rail (out)" + label temp1 "PMB-2 Temp 1" + label temp2 "PMB-2 Temp 2" + ignore power1 + label power2 "PMB-2 3.3V Rail Pwr (out)" + label power3 "PMB-2 1.2V Rail Pwr (out)" + ignore curr1 + label curr2 "PMB-2 3.3V Rail Curr (out)" + label curr3 "PMB-2 1.2V Rail Curr (out)" -chip "dps460-*" - ignore fan2 - ignore fan3 +# Power supplies +bus "i2c-10" "i2c-1-mux (chan_id 10)" + chip "dps460-i2c-*-58" + label in1 "PSU-2(R) 220V Rail (in)" + label in2 "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 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)" + chip "dps460-i2c-*-59" + label in1 "PSU-1(L) 220V Rail (in)" + label in2 "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 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)" +# Chassis fans +bus "i2c-2" "i2c-1-mux (chan_id 2)" + chip "mlxsw-i2c-*-48" + label fan1 "Chassis Drawer-1 Fan-1" + label fan2 "Chassis Drawer-1 Fan-2" + label fan3 "Chassis Drawer-2 Fan-1" + label fan4 "Chassis Drawer-2 Fan-2" + label fan5 "Chassis Drawer-3 Fan-1" + label fan6 "Chassis Drawer-3 Fan-2" + label fan7 "Chassis Drawer-4 Fan-1" + label fan8 "Chassis Drawer-4 Fan-2" diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_msn2700-r0/system_health_monitoring_config.json new file mode 100644 index 000000000000..bff6ab4b38ee --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/system_health_monitoring_config.json @@ -0,0 +1,11 @@ +{ + "services_to_ignore": [], + "devices_to_ignore": ["psu.voltage"], + "user_defined_checkers": [], + "polling_interval": 60, + "led_color": { + "fault": "orange", + "normal": "green", + "booting": "orange_blink" + } +} diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/thermal_policy.json b/device/mellanox/x86_64-mlnx_msn2700-r0/thermal_policy.json index 054d797be951..1e23d6c8b2bd 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/thermal_policy.json +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/thermal_policy.json @@ -1,6 +1,6 @@ { "thermal_control_algorithm": { - "run_at_boot_up": "false", + "run_at_boot_up": "true", "fan_speed_when_suspend": "60" }, "info_types": [ @@ -23,10 +23,6 @@ } ], "actions": [ - { - "type": "thermal_control.control", - "status": "false" - }, { "type": "fan.all.set_speed", "speed": "100" @@ -42,9 +38,19 @@ ], "actions": [ { - "type": "thermal_control.control", - "status": "false" - }, + "type": "fan.all.set_speed", + "speed": "100" + } + ] + }, + { + "name": "any fan broken", + "conditions": [ + { + "type": "fan.any.fault" + } + ], + "actions": [ { "type": "fan.all.set_speed", "speed": "100" @@ -59,12 +65,14 @@ }, { "type": "psu.all.presence" + }, + { + "type": "fan.all.good" } ], "actions": [ { - "type": "fan.all.set_speed", - "speed": "60" + "type": "thermal.recover" } ] } diff --git a/device/mellanox/x86_64-mlnx_msn2700_simx-r0/pmon_daemon_control.json b/device/mellanox/x86_64-mlnx_msn2700_simx-r0/pmon_daemon_control.json index 40fc367acf32..dd83c2db12c5 100644 --- a/device/mellanox/x86_64-mlnx_msn2700_simx-r0/pmon_daemon_control.json +++ b/device/mellanox/x86_64-mlnx_msn2700_simx-r0/pmon_daemon_control.json @@ -1,5 +1,7 @@ { "skip_ledd": true, "skip_xcvrd": true, - "skip_psud": true + "skip_psud": true, + "skip_pcied": true, + "skip_thermalctld": true } diff --git a/device/mellanox/x86_64-mlnx_msn2700_simx-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_msn2700_simx-r0/system_health_monitoring_config.json new file mode 100644 index 000000000000..23cb74dd3f96 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700_simx-r0/system_health_monitoring_config.json @@ -0,0 +1,11 @@ +{ + "services_to_ignore": [], + "devices_to_ignore": ["psu","asic","fan"], + "user_defined_checkers": [], + "polling_interval": 60, + "led_color": { + "fault": "orange", + "normal": "green", + "booting": "orange_blink" + } +} diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/buffers_dynamic.json.j2 b/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/buffers_dynamic.json.j2 new file mode 120000 index 000000000000..8c4117c66214 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/buffers_dynamic.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_dynamic.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/port_config.ini b/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/port_config.ini index 816bb0e94a70..2ef052c68d52 100644 --- a/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/port_config.ini +++ b/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/port_config.ini @@ -1,33 +1,33 @@ -# name lanes -Ethernet0 0,1,2,3 -Ethernet4 4,5,6,7 -Ethernet8 8,9,10,11 -Ethernet12 12,13,14,15 -Ethernet16 16,17,18,19 -Ethernet20 20,21,22,23 -Ethernet24 24,25,26,27 -Ethernet28 28,29,30,31 -Ethernet32 32,33,34,35 -Ethernet36 36,37,38,39 -Ethernet40 40,41,42,43 -Ethernet44 44,45,46,47 -Ethernet48 48,49,50,51 -Ethernet52 52,53,54,55 -Ethernet56 56,57,58,59 -Ethernet60 60,61,62,63 -Ethernet64 64,65,66,67 -Ethernet68 68,69,70,71 -Ethernet72 72,73,74,75 -Ethernet76 76,77,78,79 -Ethernet80 80,81,82,83 -Ethernet84 84,85,86,87 -Ethernet88 88,89,90,91 -Ethernet92 92,93,94,95 -Ethernet96 96,97,98,99 -Ethernet100 100,101,102,103 -Ethernet104 104,105,106,107 -Ethernet108 108,109,110,111 -Ethernet112 112,113,114,115 -Ethernet116 116,117,118,119 -Ethernet120 120,121,122,123 -Ethernet124 124,125,126,127 +# name lanes index +Ethernet0 0,1,2,3 1 +Ethernet4 4,5,6,7 2 +Ethernet8 8,9,10,11 3 +Ethernet12 12,13,14,15 4 +Ethernet16 16,17,18,19 5 +Ethernet20 20,21,22,23 6 +Ethernet24 24,25,26,27 7 +Ethernet28 28,29,30,31 8 +Ethernet32 32,33,34,35 9 +Ethernet36 36,37,38,39 10 +Ethernet40 40,41,42,43 11 +Ethernet44 44,45,46,47 12 +Ethernet48 48,49,50,51 13 +Ethernet52 52,53,54,55 14 +Ethernet56 56,57,58,59 15 +Ethernet60 60,61,62,63 16 +Ethernet64 64,65,66,67 17 +Ethernet68 68,69,70,71 18 +Ethernet72 72,73,74,75 19 +Ethernet76 76,77,78,79 20 +Ethernet80 80,81,82,83 21 +Ethernet84 84,85,86,87 22 +Ethernet88 88,89,90,91 23 +Ethernet92 92,93,94,95 24 +Ethernet96 96,97,98,99 25 +Ethernet100 100,101,102,103 26 +Ethernet104 104,105,106,107 27 +Ethernet108 108,109,110,111 28 +Ethernet112 112,113,114,115 29 +Ethernet116 116,117,118,119 30 +Ethernet120 120,121,122,123 31 +Ethernet124 124,125,126,127 32 diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/sai_2740.xml b/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/sai_2740.xml index 559f2bdd10c8..955ea3f8b1b6 100644 --- a/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/sai_2740.xml +++ b/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/sai_2740.xml @@ -5,6 +5,9 @@ 00:02:03:04:05:00 + + 1 + 32 diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/pcie.yaml b/device/mellanox/x86_64-mlnx_msn2740-r0/pcie.yaml new file mode 100644 index 000000000000..ca73122aaa81 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2740-r0/pcie.yaml @@ -0,0 +1,83 @@ +- bus: '00' + dev: '00' + fn: '0' + id: 1f0b + name: 'Host bridge: Intel Corporation Atom processor C2000 SoC Transaction Router + (rev 02)' +- bus: '00' + dev: '01' + fn: '0' + id: 1f10 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 1 (rev + 02)' +- bus: '00' + dev: '02' + fn: '0' + id: 1f11 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 2 (rev + 02)' +- bus: '00' + dev: '03' + fn: '0' + id: 1f12 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 3 (rev + 02)' +- bus: '00' + dev: 0b + fn: '0' + id: 1f18 + name: 'Co-processor: Intel Corporation Atom processor C2000 QAT (rev 02)' +- bus: '00' + dev: 0e + fn: '0' + id: 1f14 + name: 'Host bridge: Intel Corporation Atom processor C2000 RAS (rev 02)' +- bus: '00' + dev: 0f + fn: '0' + id: 1f16 + name: 'IOMMU: Intel Corporation Atom processor C2000 RCEC (rev 02)' +- bus: '00' + dev: '13' + fn: '0' + id: 1f15 + name: 'System peripheral: Intel Corporation Atom processor C2000 SMBus 2.0 (rev + 02)' +- bus: '00' + dev: '14' + fn: '0' + id: 1f41 + name: 'Ethernet controller: Intel Corporation Ethernet Connection I354 (rev 03)' +- bus: '00' + dev: '16' + fn: '0' + id: 1f2c + name: 'USB controller: Intel Corporation Atom processor C2000 USB Enhanced Host + Controller (rev 02)' +- bus: '00' + dev: '17' + fn: '0' + id: 1f22 + name: 'SATA controller: Intel Corporation Atom processor C2000 AHCI SATA2 Controller + (rev 02)' +- bus: '00' + dev: '18' + fn: '0' + id: 1f32 + name: 'SATA controller: Intel Corporation Atom processor C2000 AHCI SATA3 Controller + (rev 02)' +- bus: '00' + dev: 1f + fn: '0' + id: 1f38 + name: 'ISA bridge: Intel Corporation Atom processor C2000 PCU (rev 02)' +- bus: '00' + dev: 1f + fn: '3' + id: 1f3c + name: 'SMBus: Intel Corporation Atom processor C2000 PCU SMBus (rev 02)' +- bus: '01' + dev: '00' + fn: '0' + id: cb84 + name: 'Ethernet controller: Mellanox Technologies MT52100' diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn2740-r0/platform_components.json index 7964d9cb8713..da85f2b5792e 100644 --- a/device/mellanox/x86_64-mlnx_msn2740-r0/platform_components.json +++ b/device/mellanox/x86_64-mlnx_msn2740-r0/platform_components.json @@ -1,9 +1,12 @@ { "chassis": { - "x86_64-mlnx_msn2740-r0": { + "MSN2740": { "component": { + "ONIE": { }, + "SSD": { }, "BIOS": { }, - "CPLD": { } + "CPLD1": { }, + "CPLD2": { } } } } diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn2740-r0/sensors.conf deleted file mode 120000 index ea04d66d008c..000000000000 --- a/device/mellanox/x86_64-mlnx_msn2740-r0/sensors.conf +++ /dev/null @@ -1 +0,0 @@ -../x86_64-mlnx_msn2700-r0/sensors.conf \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn2740-r0/sensors.conf new file mode 100644 index 000000000000..ffc36fe2168c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2740-r0/sensors.conf @@ -0,0 +1,76 @@ +################################################################################ +# Copyright (c) 2020 Mellanox Technologies +# +# Platform specific sensors config for SN2740 +################################################################################ + +# 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-*-48" + label temp1 "Ambient Port Temp" + +bus "i2c-6" "i2c-1-mux (chan_id 5)" + chip "tmp102-i2c-*-49" + label temp1 "Ambient Fan Temp" + +# Power controllers +bus "i2c-5" "i2c-1-mux (chan_id 4)" + chip "pmbus-i2c-*-41" + label in1 "PMB-1 PSU 12V Rail (in)" + label in2 "PMB-1 0.9V VCORE Rail (out)" + label in3 "PMB-1 1.8V VCORE Rail (out)" + label temp1 "PMB-1 Temp 1" + label temp2 "PMB-1 Temp 2" + ignore power1 + label power2 "PMB-1 0.9V VCORE Rail Pwr (out)" + label power3 "PMB-1 1.8V Rail Pwr (out)" + ignore curr1 + label curr2 "PMB-1 0.9V VCORE Rail Curr (out)" + label curr3 "PMB-1 1.8V Rail Curr (out)" + chip "pmbus-i2c-*-27" + label in1 "PMB-2 PSU 12V Rail (in)" + label in2 "PMB-2 3.3V Rail (out)" + label in3 "PMB-2 1.2V Rail (out)" + label temp1 "PMB-2 Temp 1" + label temp2 "PMB-2 Temp 2" + ignore power1 + label power2 "PMB-2 3.3V Rail Pwr (out)" + label power3 "PMB-2 1.2V Rail Pwr (out)" + ignore curr1 + label curr2 "PMB-2 3.3V Rail Curr (out)" + label curr3 "PMB-2 1.2V Rail Curr (out)" + +# Power supplies +bus "i2c-4" "i2c-1-mux (chan_id 3)" + chip "dps460-i2c-*-58" + label in1 "PSU-2(R) 220V Rail (in)" + label in2 "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 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)" + chip "dps460-i2c-*-59" + label in1 "PSU-1(L) 220V Rail (in)" + label in2 "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 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)" + +# Chassis fans +bus "i2c-2" "i2c-1-mux (chan_id 1)" + chip "mlxsw-i2c-*-48" + label fan1 "Chassis Fan Drawer-1" + label fan2 "Chassis Fan Drawer-2" + label fan3 "Chassis Fan Drawer-3" + label fan4 "Chassis Fan Drawer-4" diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_msn2740-r0/system_health_monitoring_config.json new file mode 120000 index 000000000000..98df66c27ca5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2740-r0/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/buffers.json.j2 new file mode 120000 index 000000000000..7888381852d8 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/buffers.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/buffers_defaults_t0.j2 new file mode 120000 index 000000000000..85f0b6b6b354 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/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_msn3420-r0/ACS-MSN3420/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/buffers_defaults_t1.j2 new file mode 120000 index 000000000000..3bb496a5103b --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/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_msn3420-r0/ACS-MSN3420/buffers_dynamic.json.j2 b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/buffers_dynamic.json.j2 new file mode 120000 index 000000000000..8c4117c66214 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/buffers_dynamic.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_dynamic.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/hwsku.json b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/hwsku.json new file mode 100644 index 000000000000..59c3aa2c968b --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/hwsku.json @@ -0,0 +1,184 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet4": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet8": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet12": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet16": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet20": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet24": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet28": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet32": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet36": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet40": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet44": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet48": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet52": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet56": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet60": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet64": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet68": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet72": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet76": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet80": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet84": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet88": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet92": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet96": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet100": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet104": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet108": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet112": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet116": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet120": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet124": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet128": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet132": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet136": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet140": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet144": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet148": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet152": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet156": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet160": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet164": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet168": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet172": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet176": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet180": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet184": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet188": { + "default_brkout_mode": "1x25G[10G,1G]" + }, + "Ethernet192": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet196": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet200": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet204": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet208": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet212": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet216": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet220": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet224": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet228": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet232": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet236": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/pg_profile_lookup.ini new file mode 120000 index 000000000000..252ae8d4149b --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/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_msn3420-r0/ACS-MSN3420/port_config.ini b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/port_config.ini new file mode 100644 index 000000000000..38441f21f003 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/port_config.ini @@ -0,0 +1,61 @@ +# name lanes alias index +Ethernet0 0 etp1 1 +Ethernet4 4 etp2 2 +Ethernet8 8 etp3 3 +Ethernet12 12 etp4 4 +Ethernet16 16 etp5 5 +Ethernet20 20 etp6 6 +Ethernet24 24 etp7 7 +Ethernet28 28 etp8 8 +Ethernet32 32 etp9 9 +Ethernet36 36 etp10 10 +Ethernet40 40 etp11 11 +Ethernet44 44 etp12 12 +Ethernet48 48 etp13 13 +Ethernet52 52 etp14 14 +Ethernet56 56 etp15 15 +Ethernet60 60 etp16 16 +Ethernet64 64 etp17 17 +Ethernet68 68 etp18 18 +Ethernet72 72 etp19 19 +Ethernet76 76 etp20 20 +Ethernet80 80 etp21 21 +Ethernet84 84 etp22 22 +Ethernet88 88 etp23 23 +Ethernet92 92 etp24 24 +Ethernet96 96 etp25 25 +Ethernet100 100 etp26 26 +Ethernet104 104 etp27 27 +Ethernet108 108 etp28 28 +Ethernet112 112 etp29 29 +Ethernet116 116 etp30 30 +Ethernet120 120 etp31 31 +Ethernet124 124 etp32 32 +Ethernet128 128 etp33 33 +Ethernet132 132 etp34 34 +Ethernet136 136 etp35 35 +Ethernet140 140 etp36 36 +Ethernet144 144 etp37 37 +Ethernet148 148 etp38 38 +Ethernet152 152 etp39 39 +Ethernet156 156 etp40 40 +Ethernet160 160 etp41 41 +Ethernet164 164 etp42 42 +Ethernet168 168 etp43 43 +Ethernet172 172 etp44 44 +Ethernet176 176 etp45 45 +Ethernet180 180 etp46 46 +Ethernet184 184 etp47 47 +Ethernet188 188 etp48 48 +Ethernet192 192,193,194,195 etp49 49 +Ethernet196 196,197,198,199 etp50 50 +Ethernet200 200,201,202,203 etp51 51 +Ethernet204 204,205,206,207 etp52 52 +Ethernet208 208,209,210,211 etp53 53 +Ethernet212 212,213,214,215 etp54 54 +Ethernet216 216,217,218,219 etp55 55 +Ethernet220 220,221,222,223 etp56 56 +Ethernet224 224,225,226,227 etp57 57 +Ethernet228 228,229,230,231 etp58 58 +Ethernet232 232,233,234,235 etp59 59 +Ethernet236 236,237,238,239 etp60 60 diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/qos.json.j2 b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/qos.json.j2 new file mode 120000 index 000000000000..379f542893f3 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/qos.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn3700-r0/ACS-MSN3700/qos.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/sai.profile b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/sai.profile new file mode 100644 index 000000000000..a30106c8674d --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/sai_3420.xml diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/sai_3420.xml b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/sai_3420.xml new file mode 100644 index 000000000000..5064ee3ef81b --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/sai_3420.xml @@ -0,0 +1,442 @@ + + + + + + 00:02:03:04:05:80 + + + 1 + + + 60 + + + + + 105 + 1 + 0 + + + 0 + + + 64 + + + 106 + 1 + 1 + 0 + 64 + + + 49 + 1 + 2 + 0 + 64 + + + 113 + 1 + 3 + 0 + 64 + + + 114 + 1 + 4 + 0 + 64 + + + 50 + 1 + 5 + 0 + 64 + + + 115 + 1 + 6 + 0 + 64 + + + 116 + 1 + 7 + 0 + 64 + + + 41 + 1 + 8 + 0 + 64 + + + 121 + 1 + 9 + 0 + 64 + + + 122 + 1 + 10 + 0 + 64 + + + 42 + 1 + 11 + 0 + 64 + + + 123 + 1 + 12 + 0 + 64 + + + 124 + 1 + 13 + 0 + 64 + + + 43 + 1 + 14 + 0 + 64 + + + 57 + 1 + 15 + 0 + 64 + + + 58 + 1 + 16 + 0 + 64 + + + 44 + 1 + 17 + 0 + 64 + + + 59 + 1 + 18 + 0 + 64 + + + 60 + 1 + 19 + 0 + 64 + + + 33 + 1 + 20 + 0 + 64 + + + 51 + 1 + 21 + 0 + 64 + + + 52 + 1 + 22 + 0 + 64 + + + 34 + 1 + 23 + 0 + 64 + + + 53 + 1 + 24 + 0 + 64 + + + 54 + 1 + 25 + 0 + 64 + + + 35 + 1 + 26 + 0 + 64 + + + 45 + 1 + 27 + 0 + 64 + + + 46 + 1 + 28 + 0 + 64 + + + 36 + 1 + 29 + 0 + 64 + + + 47 + 1 + 30 + 0 + 64 + + + 48 + 1 + 31 + 0 + 64 + + + 1 + 1 + 32 + 0 + 64 + + + 37 + 1 + 33 + 0 + 64 + + + 38 + 1 + 34 + 0 + 64 + + + 2 + 1 + 35 + 0 + 64 + + + 39 + 1 + 36 + 0 + 64 + + + 40 + 1 + 37 + 0 + 64 + + + 3 + 1 + 38 + 0 + 64 + + + 4 + 1 + 39 + 0 + 64 + + + 5 + 1 + 40 + 0 + 64 + + + 6 + 1 + 41 + 0 + 64 + + + 7 + 1 + 42 + 0 + 64 + + + 8 + 1 + 43 + 0 + 64 + + + 9 + 1 + 44 + 0 + 64 + + + 10 + 1 + 45 + 0 + 64 + + + 11 + 1 + 46 + 0 + 64 + + + 12 + 1 + 47 + 0 + 64 + + + 17 + 4 + 48 + 3 + 1536 + + + 21 + 4 + 49 + 3 + 1536 + + + 25 + 4 + 50 + 3 + 1536 + + + 29 + 4 + 51 + 3 + 1536 + + + 89 + 4 + 52 + 3 + 1536 + + + 93 + 4 + 53 + 3 + 1536 + + + 81 + 4 + 54 + 3 + 1536 + + + 85 + 4 + 55 + 3 + 1536 + + + 73 + 4 + 56 + 3 + 1536 + + + 77 + 4 + 57 + 3 + 1536 + + + 65 + 4 + 58 + 3 + 1536 + + + 69 + 4 + 59 + 3 + 1536 + + + + \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/default_sku b/device/mellanox/x86_64-mlnx_msn3420-r0/default_sku new file mode 100644 index 000000000000..a572bdce4e5e --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/default_sku @@ -0,0 +1 @@ +ACS-MSN3420 t1 diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/pcie.yaml b/device/mellanox/x86_64-mlnx_msn3420-r0/pcie.yaml new file mode 120000 index 000000000000..3dc31739f7d9 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/pcie.yaml @@ -0,0 +1 @@ +../x86_64-mlnx_msn3700c-r0/pcie.yaml \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/platform.json b/device/mellanox/x86_64-mlnx_msn3420-r0/platform.json new file mode 100644 index 000000000000..401cd4b660e3 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/platform.json @@ -0,0 +1,364 @@ +{ + "interfaces": { + "Ethernet0": { + "index": "1", + "lanes": "0", + "alias_at_lanes": "etp1", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet4": { + "index": "2", + "lanes": "4", + "alias_at_lanes": "etp2", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet8": { + "index": "3", + "lanes": "8", + "alias_at_lanes": "etp3", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet12": { + "index": "4", + "lanes": "12", + "alias_at_lanes": "etp4", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet16": { + "index": "5", + "lanes": "16", + "alias_at_lanes": "etp5", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet20": { + "index": "6", + "lanes": "20", + "alias_at_lanes": "etp6", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet24": { + "index": "7", + "lanes": "24", + "alias_at_lanes": "etp7", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet28": { + "index": "8", + "lanes": "28", + "alias_at_lanes": "etp8", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet32": { + "index": "9", + "lanes": "32", + "alias_at_lanes": "etp9", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet36": { + "index": "10", + "lanes": "36", + "alias_at_lanes": "etp10", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet40": { + "index": "11", + "lanes": "40", + "alias_at_lanes": "etp11", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet44": { + "index": "12", + "lanes": "44", + "alias_at_lanes": "etp12", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet48": { + "index": "13", + "lanes": "48", + "alias_at_lanes": "etp13", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet52": { + "index": "14", + "lanes": "52", + "alias_at_lanes": "etp14", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet56": { + "index": "15", + "lanes": "56", + "alias_at_lanes": "etp15", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet60": { + "index": "16", + "lanes": "60", + "alias_at_lanes": "etp16", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet64": { + "index": "17", + "lanes": "64", + "alias_at_lanes": "etp17", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet68": { + "index": "18", + "lanes": "68", + "alias_at_lanes": "etp18", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet72": { + "index": "19", + "lanes": "72", + "alias_at_lanes": "etp19", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet76": { + "index": "20", + "lanes": "76", + "alias_at_lanes": "etp20", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet80": { + "index": "21", + "lanes": "80", + "alias_at_lanes": "etp21", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet84": { + "index": "22", + "lanes": "84", + "alias_at_lanes": "etp22", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet88": { + "index": "23", + "lanes": "88", + "alias_at_lanes": "etp23", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet92": { + "index": "24", + "lanes": "92", + "alias_at_lanes": "etp24", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet96": { + "index": "25", + "lanes": "96", + "alias_at_lanes": "etp25", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet100": { + "index": "26", + "lanes": "100", + "alias_at_lanes": "etp26", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet104": { + "index": "27", + "lanes": "104", + "alias_at_lanes": "etp27", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet108": { + "index": "28", + "lanes": "108", + "alias_at_lanes": "etp28", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet112": { + "index": "29", + "lanes": "112", + "alias_at_lanes": "etp29", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet116": { + "index": "30", + "lanes": "116", + "alias_at_lanes": "etp30", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet120": { + "index": "31", + "lanes": "120", + "alias_at_lanes": "etp31", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet124": { + "index": "32", + "lanes": "124", + "alias_at_lanes": "etp32", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet128": { + "index": "33", + "lanes": "128", + "alias_at_lanes": "etp33", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet132": { + "index": "34", + "lanes": "132", + "alias_at_lanes": "etp34", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet136": { + "index": "35", + "lanes": "136", + "alias_at_lanes": "etp35", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet140": { + "index": "36", + "lanes": "140", + "alias_at_lanes": "etp36", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet144": { + "index": "37", + "lanes": "144", + "alias_at_lanes": "etp37", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet148": { + "index": "38", + "lanes": "148", + "alias_at_lanes": "etp38", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet152": { + "index": "39", + "lanes": "152", + "alias_at_lanes": "etp39", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet156": { + "index": "40", + "lanes": "156", + "alias_at_lanes": "etp40", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet160": { + "index": "41", + "lanes": "160", + "alias_at_lanes": "etp41", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet164": { + "index": "42", + "lanes": "164", + "alias_at_lanes": "etp42", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet168": { + "index": "43", + "lanes": "168", + "alias_at_lanes": "etp43", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet172": { + "index": "44", + "lanes": "172", + "alias_at_lanes": "etp44", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet176": { + "index": "45", + "lanes": "176", + "alias_at_lanes": "etp45", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet180": { + "index": "46", + "lanes": "180", + "alias_at_lanes": "etp46", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet184": { + "index": "47", + "lanes": "184", + "alias_at_lanes": "etp47", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet188": { + "index": "48", + "lanes": "188", + "alias_at_lanes": "etp48", + "breakout_modes": "1x25G[10G,1G]" + }, + "Ethernet192": { + "index": "49,49,49,49", + "lanes": "192,193,194,195", + "alias_at_lanes": "etp49a, etp49b, etp49c, etp49d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet196": { + "index": "50,50,50,50", + "lanes": "196,197,198,199", + "alias_at_lanes": "etp50a, etp50b, etp50c, etp50d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet200": { + "index": "51,51,51,51", + "lanes": "200,201,202,203", + "alias_at_lanes": "etp51a, etp51b, etp51c, etp51d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet204": { + "index": "52,52,52,52", + "lanes": "204,205,206,207", + "alias_at_lanes": "etp52a, etp52b, etp52c, etp52d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet208": { + "index": "53,53,53,53", + "lanes": "208,209,210,211", + "alias_at_lanes": "etp53a, etp53b, etp53c, etp53d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet212": { + "index": "54,54,54,54", + "lanes": "212,213,214,215", + "alias_at_lanes": "etp54a, etp54b, etp54c, etp54d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet216": { + "index": "55,55,55,55", + "lanes": "216,217,218,219", + "alias_at_lanes": "etp55a, etp55b, etp55c, etp55d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet220": { + "index": "56,56,56,56", + "lanes": "220,221,222,223", + "alias_at_lanes": "etp56a, etp56b, etp56c, etp56d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet224": { + "index": "57,57,57,57", + "lanes": "224,225,226,227", + "alias_at_lanes": "etp57a, etp57b, etp57c, etp57d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet228": { + "index": "58,58,58,58", + "lanes": "228,229,230,231", + "alias_at_lanes": "etp58a, etp58b, etp58c, etp58d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet232": { + "index": "59,59,59,59", + "lanes": "232,233,234,235", + "alias_at_lanes": "etp59a, etp59b, etp59c, etp59d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet236": { + "index": "60,60,60,60", + "lanes": "236,237,238,239", + "alias_at_lanes": "etp60a, etp60b, etp60c, etp60d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn3420-r0/platform_components.json new file mode 100644 index 000000000000..9b5cceae9fc8 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/platform_components.json @@ -0,0 +1,14 @@ +{ + "chassis": { + "MSN3420": { + "component": { + "ONIE": { }, + "SSD": { }, + "BIOS": { }, + "CPLD1": { }, + "CPLD2": { }, + "CPLD3": { } + } + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/platform_reboot b/device/mellanox/x86_64-mlnx_msn3420-r0/platform_reboot new file mode 120000 index 000000000000..43c8ea567493 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-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_msn3420-r0/platform_wait b/device/mellanox/x86_64-mlnx_msn3420-r0/platform_wait new file mode 120000 index 000000000000..4b30bd429854 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-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_msn3420-r0/plugins/eeprom.py b/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/eeprom.py new file mode 120000 index 000000000000..b4e2a6a61671 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-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_msn3420-r0/plugins/psuutil.py b/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/psuutil.py new file mode 120000 index 000000000000..9f724238a8d5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-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_msn3420-r0/plugins/sfplpmget.py b/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfplpmget.py new file mode 120000 index 000000000000..2e84f435abd9 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-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_msn3420-r0/plugins/sfplpmset.py b/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfplpmset.py new file mode 120000 index 000000000000..6a88bac30467 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-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_msn3420-r0/plugins/sfpreset.py b/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfpreset.py new file mode 120000 index 000000000000..fef2063e3496 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-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_msn3420-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfputil.py new file mode 120000 index 000000000000..45909b880fc9 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-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_msn3420-r0/pmon_daemon_control.json b/device/mellanox/x86_64-mlnx_msn3420-r0/pmon_daemon_control.json new file mode 120000 index 000000000000..435a2ce7c0ba --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-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_msn3420-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn3420-r0/sensors.conf new file mode 100644 index 000000000000..f31cbe7adbc7 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/sensors.conf @@ -0,0 +1,121 @@ +################################################################################ +# Copyright (c) 2020 Mellanox Technologies +# +# Platform specific sensors config for SN3420 +################################################################################ + +# 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 "xdpe12284-i2c-*-62" + label in1 "PMIC-1 PSU 12V Rail (in1)" + label in2 "PMIC-1 PSU 12V Rail (in2)" + label in3 "PMIC-1 VCORE 0.8V Rail (out)" + label in4 "PMIC-1 COMEX 1.2V Rail (out)" + label temp1 "PMIC-1 Temp 1" + label temp2 "PMIC-1 Temp 2" + label power1 "PMIC-1 PSU 12V Rail Pwr (in1)" + label power2 "PMIC-1 PSU 12V Rail Pwr (in2)" + label power3 "PMIC-1 VCORE 0.8V Rail Pwr (out)" + label power4 "PMIC-1 COMEX 1.2V Rail Pwr (out)" + label curr1 "PMIC-1 PSU 12V Rail Curr (in1)" + label curr2 "PMIC-1 PSU 12V Rail Curr (in2)" + label curr3 "PMIC-1 VCORE 0.8V Rail Curr (out)" + label curr4 "PMIC-1 COMEX 1.2V Rail Curr (out)" + chip "xdpe12284-i2c-*-64" + label in1 "PMIC-2 PSU 12V Rail (in1)" + label in2 "PMIC-2 PSU 12V Rail (in2)" + label in3 "PMIC-2 1.8V Rail (out)" + ignore in4 + label temp1 "PMIC-2 Temp 1" + ignore temp2 + label power1 "PMIC-2 PSU 12V Rail Pwr (in1)" + label power2 "PMIC-2 PSU 12V Rail Pwr (in2)" + label power3 "PMIC-2 1.8V Rail Pwr (out)" + ignore power4 + label curr1 "PMIC-2 PSU 12V Rail Curr (in1)" + label curr2 "PMIC-2 PSU 12V Rail Curr (in2)" + label curr3 "PMIC-2 1.8V Rail Curr (out)" + ignore curr4 + +bus "i2c-15" "i2c-1-mux (chan_id 6)" + chip "tps53679-i2c-*-58" + label in1 "PMIC-3 PSU 12V Rail (in1)" + label in2 "PMIC-3 PSU 12V Rail (in2)" + label in3 "PMIC-3 COMEX 1.8V Rail (out)" + label in4 "PMIC-3 COMEX 1.05V Rail (out)" + label temp1 "PMIC-3 Temp 1" + label temp2 "PMIC-3 Temp 2" + label power1 "PMIC-3 COMEX 1.8V Rail Pwr (out)" + label power2 "PMIC-3 COMEX 1.05V Rail Pwr (out)" + label curr1 "PMIC-3 COMEX 1.8V Rail Curr (out)" + label curr2 "PMIC-3 COMEX 1.05V Rail Curr (out)" + chip "tps53679-i2c-*-61" + label in1 "PMIC-4 PSU 12V Rail (in1)" + label in2 "PMIC-4 PSU 12V Rail (in2)" + label in3 "PMIC-4 COMEX 1.2V Rail (out)" + ignore in4 + label temp1 "PMIC-4 Temp 1" + label temp2 "PMIC-4 Temp 2" + label power1 "PMIC-4 COMEX 1.2V Rail Pwr (out)" + ignore power2 + label curr1 "PMIC-4 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 220V Rail (in)" + label in2 "PSU-1 12V Rail (out)" + label fan1 "PSU-1 Fan 1" + label temp1 "PSU-1 Temp 1" + label temp2 "PSU-1 Temp 2" + label temp3 "PSU-1 Temp 3" + label power1 "PSU-1 220V Rail Pwr (in)" + label power2 "PSU-1 12V Rail Pwr (out)" + label curr1 "PSU-1 220V Rail Curr (in)" + label curr2 "PSU-1 12V Rail Curr (out)" + chip "dps460-i2c-*-59" + label in1 "PSU-2 220V Rail (in)" + label in2 "PSU-2 12V Rail (out)" + label fan1 "PSU-2 Fan 1" + label temp1 "PSU-2 Temp 1" + label temp2 "PSU-2 Temp 2" + label temp3 "PSU-2 Temp 3" + label power1 "PSU-2 220V Rail Pwr (in)" + label power2 "PSU-2 12V Rail Pwr (out)" + label curr1 "PSU-2 220V Rail Curr (in)" + label curr2 "PSU-2 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_msn3420-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_msn3420-r0/system_health_monitoring_config.json new file mode 120000 index 000000000000..98df66c27ca5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/thermal_policy.json b/device/mellanox/x86_64-mlnx_msn3420-r0/thermal_policy.json new file mode 120000 index 000000000000..5a25cd87f70c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/thermal_policy.json \ No newline at end of file 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 e26ad28b9f0e..035a14177705 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 = '14983147' %} -{% set ingress_lossy_pool_size = '14983147' %} -{% set egress_lossless_pool_size = '34340822' %} -{% set egress_lossy_pool_size = '14983147' %} +{% set ingress_lossless_pool_size = '14542848' %} +{% set ingress_lossy_pool_size = '14542848' %} +{% set egress_lossless_pool_size = '34287552' %} +{% set egress_lossy_pool_size = '14542848' %} {%- macro generate_port_lists(PORT_ALL) %} {# Generate list of ports #} @@ -14,12 +14,16 @@ {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { + {%- if dynamic_mode is not defined %} "size": "{{ ingress_lossless_pool_size }}", + {%- endif %} "type": "ingress", "mode": "dynamic" }, "ingress_lossy_pool": { + {%- if dynamic_mode is not defined %} "size": "{{ ingress_lossy_pool_size }}", + {%- endif %} "type": "ingress", "mode": "dynamic" }, @@ -29,7 +33,9 @@ "mode": "dynamic" }, "egress_lossy_pool": { + {%- if dynamic_mode is not defined %} "size": "{{ egress_lossy_pool_size }}", + {%- endif %} "type": "egress", "mode": "dynamic" } @@ -38,7 +44,7 @@ "ingress_lossless_profile": { "pool":"[BUFFER_POOL|ingress_lossless_pool]", "size":"0", - "dynamic_th":"0" + "dynamic_th":"7" }, "ingress_lossy_profile": { "pool":"[BUFFER_POOL|ingress_lossy_pool]", @@ -52,8 +58,8 @@ }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", - "size":"4096", - "dynamic_th":"3" + "size":"9216", + "dynamic_th":"7" }, "q_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", 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 b5e4ff8d1747..1032b455b8f1 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 = '9158635' %} -{% set ingress_lossy_pool_size = '9158635' %} -{% set egress_lossless_pool_size = '34340822' %} -{% set egress_lossy_pool_size = '9158635' %} +{% set ingress_lossless_pool_size = '11622400' %} +{% set ingress_lossy_pool_size = '11622400' %} +{% set egress_lossless_pool_size = '34287552' %} +{% set egress_lossy_pool_size = '11622400' %} {%- macro generate_port_lists(PORT_ALL) %} {# Generate list of ports #} @@ -14,12 +14,16 @@ {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { + {%- if dynamic_mode is not defined %} "size": "{{ ingress_lossless_pool_size }}", + {%- endif %} "type": "ingress", "mode": "dynamic" }, "ingress_lossy_pool": { + {%- if dynamic_mode is not defined %} "size": "{{ ingress_lossy_pool_size }}", + {%- endif %} "type": "ingress", "mode": "dynamic" }, @@ -29,7 +33,9 @@ "mode": "dynamic" }, "egress_lossy_pool": { + {%- if dynamic_mode is not defined %} "size": "{{ egress_lossy_pool_size }}", + {%- endif %} "type": "egress", "mode": "dynamic" } @@ -38,7 +44,7 @@ "ingress_lossless_profile": { "pool":"[BUFFER_POOL|ingress_lossless_pool]", "size":"0", - "dynamic_th":"0" + "dynamic_th":"7" }, "ingress_lossy_profile": { "pool":"[BUFFER_POOL|ingress_lossy_pool]", @@ -52,8 +58,8 @@ }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", - "size":"4096", - "dynamic_th":"3" + "size":"9216", + "dynamic_th":"7" }, "q_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", diff --git a/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_dynamic.json.j2 b/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_dynamic.json.j2 new file mode 120000 index 000000000000..8c4117c66214 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_dynamic.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_dynamic.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/hwsku.json b/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/hwsku.json new file mode 100644 index 000000000000..8d9471e141fb --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/hwsku.json @@ -0,0 +1,100 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet4": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet8": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet12": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet16": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet20": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet24": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet28": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet32": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet36": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet40": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet44": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet48": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet52": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet56": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet60": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet64": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet68": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet72": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet76": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet80": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet84": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet88": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet92": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet96": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet100": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet104": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet108": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet112": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet116": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet120": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet124": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/pg_profile_lookup.ini index 6cd06326cf3b..2e420e15871a 100644 --- a/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/pg_profile_lookup.ini +++ b/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/pg_profile_lookup.ini @@ -1,22 +1,20 @@ -# speed cable size xon xoff threshold - 1000 5m 35840 18432 17408 0 - 10000 5m 36864 18432 18432 0 - 25000 5m 36864 18432 18432 0 - 40000 5m 36864 18432 18432 0 - 50000 5m 37888 18432 19456 0 - 100000 5m 38912 18432 20480 0 - 200000 5m 41984 18432 23552 0 - 1000 40m 36864 18432 18432 0 - 10000 40m 38912 18432 20480 0 - 25000 40m 41984 18432 23552 0 - 40000 40m 45056 18432 26624 0 - 50000 40m 47104 18432 28672 0 - 100000 40m 59392 18432 40960 0 - 200000 40m 81920 18432 63488 0 - 1000 300m 37888 18432 19456 0 - 10000 300m 53248 18432 34816 0 - 25000 300m 78848 18432 60416 0 - 40000 300m 104448 18432 86016 0 - 50000 300m 121856 18432 103424 0 - 100000 300m 206848 18432 188416 0 - 200000 300m 376832 18432 358400 0 +# PG lossless profiles. +# speed cable size xon xoff threshold + 10000 5m 52224 19456 32768 0 + 25000 5m 52224 19456 32768 0 + 40000 5m 53248 19456 33792 0 + 50000 5m 53248 19456 33792 0 + 100000 5m 53248 19456 33792 0 + 200000 5m 55296 19456 35840 0 + 10000 40m 53248 19456 33792 0 + 25000 40m 55296 19456 35840 0 + 40000 40m 57344 19456 37888 0 + 50000 40m 58368 19456 38912 0 + 100000 40m 63488 19456 44032 0 + 200000 40m 74752 19456 55296 0 + 10000 300m 60416 19456 40960 0 + 25000 300m 73728 19456 54272 0 + 40000 300m 86016 19456 66560 0 + 50000 300m 95232 19456 75776 0 + 100000 300m 137216 19456 117760 0 + 200000 300m 223232 19456 203776 0 diff --git a/device/mellanox/x86_64-mlnx_msn3700-r0/pcie.yaml b/device/mellanox/x86_64-mlnx_msn3700-r0/pcie.yaml new file mode 100644 index 000000000000..947e9f43f8b3 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3700-r0/pcie.yaml @@ -0,0 +1,420 @@ +- bus: '00' + dev: '00' + fn: '0' + id: 6f00 + name: 'Host bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D DMI2 + (rev 03)' +- bus: '00' + dev: '01' + fn: '0' + id: 6f02 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 1 (rev 03)' +- bus: '00' + dev: '01' + fn: '1' + id: 6f03 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 1 (rev 03)' +- bus: '00' + dev: '02' + fn: '0' + id: 6f04 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 2 (rev 03)' +- bus: '00' + dev: '02' + fn: '2' + id: 6f06 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 2 (rev 03)' +- bus: '00' + dev: '03' + fn: '0' + id: 6f08 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 3 (rev 03)' +- bus: '00' + dev: '03' + fn: '2' + id: 6f0a + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 3 (rev 03)' +- bus: '00' + dev: '05' + fn: '0' + id: 6f28 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Map/VTd_Misc/System Management (rev 03)' +- bus: '00' + dev: '05' + fn: '1' + id: 6f29 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Hot Plug (rev 03)' +- bus: '00' + dev: '05' + fn: '2' + id: 6f2a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO RAS/Control Status/Global Errors (rev 03)' +- bus: '00' + dev: '05' + fn: '4' + id: 6f2c + name: 'PIC: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D I/O APIC (rev + 03)' +- bus: '00' + dev: '14' + fn: '0' + id: 8c31 + name: 'USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB + xHCI (rev 05)' +- bus: '00' + dev: 1c + fn: '0' + id: 8c10 + name: 'PCI bridge: Intel Corporation 8 Series/C220 Series Chipset Family PCI Express + Root Port #1 (rev d5)' +- bus: '00' + dev: 1c + fn: '7' + id: 8c1e + name: 'PCI bridge: Intel Corporation 8 Series/C220 Series Chipset Family PCI Express + Root Port #8 (rev d5)' +- bus: '00' + dev: 1d + fn: '0' + id: 8c26 + name: 'USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB + EHCI #1 (rev 05)' +- bus: '00' + dev: 1f + fn: '0' + id: 8c54 + name: 'ISA bridge: Intel Corporation C224 Series Chipset Family Server Standard + SKU LPC Controller (rev 05)' +- bus: '00' + dev: 1f + fn: '2' + id: 8c02 + name: 'SATA controller: Intel Corporation 8 Series/C220 Series Chipset Family 6-port + SATA Controller 1 [AHCI mode] (rev 05)' +- bus: '00' + dev: 1f + fn: '3' + id: 8c22 + name: 'SMBus: Intel Corporation 8 Series/C220 Series Chipset Family SMBus Controller + (rev 05)' +- bus: '03' + dev: '00' + fn: '0' + id: 6f50 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 0' +- bus: '03' + dev: '00' + fn: '1' + id: 6f51 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 1' +- bus: '03' + dev: '00' + fn: '2' + id: 6f52 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 2' +- bus: '03' + dev: '00' + fn: '3' + id: 6f53 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 3' +- bus: '06' + dev: '00' + fn: '0' + id: cf6c + name: 'Ethernet controller: Mellanox Technologies MT53100 [Spectrum-2, 64 x 100GbE + switch]' +- bus: 08 + dev: '00' + fn: '0' + id: '1533' + name: 'Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev + 03)' +- bus: ff + dev: 0b + fn: '0' + id: 6f81 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '1' + id: 6f36 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '2' + id: 6f37 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '3' + id: 6f76 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link Debug (rev 03)' +- bus: ff + dev: 0c + fn: '0' + id: 6fe0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0c + fn: '1' + id: 6fe1 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0c + fn: '2' + id: 6fe2 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0c + fn: '3' + id: 6fe3 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '0' + id: 6ff8 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '4' + id: 6ffc + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '5' + id: 6ffd + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '6' + id: 6ffe + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: '10' + fn: '0' + id: 6f1d + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R2PCIe Agent (rev 03)' +- bus: ff + dev: '10' + fn: '1' + id: 6f34 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R2PCIe Agent (rev 03)' +- bus: ff + dev: '10' + fn: '5' + id: 6f1e + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '10' + fn: '6' + id: 6f7d + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '10' + fn: '7' + id: 6f1f + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '12' + fn: '0' + id: 6fa0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Home Agent 0 (rev 03)' +- bus: ff + dev: '12' + fn: '1' + id: 6f30 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Home Agent 0 (rev 03)' +- bus: ff + dev: '13' + fn: '0' + id: 6fa8 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Target Address/Thermal/RAS (rev 03)' +- bus: ff + dev: '13' + fn: '1' + id: 6f71 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Target Address/Thermal/RAS (rev 03)' +- bus: ff + dev: '13' + fn: '2' + id: 6faa + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '3' + id: 6fab + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '4' + id: 6fac + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '5' + id: 6fad + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '6' + id: 6fae + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Broadcast (rev 03)' +- bus: ff + dev: '13' + fn: '7' + id: 6faf + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Global Broadcast (rev 03)' +- bus: ff + dev: '14' + fn: '0' + id: 6fb0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 0 Thermal Control (rev 03)' +- bus: ff + dev: '14' + fn: '1' + id: 6fb1 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 1 Thermal Control (rev 03)' +- bus: ff + dev: '14' + fn: '2' + id: 6fb2 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 0 Error (rev 03)' +- bus: ff + dev: '14' + fn: '3' + id: 6fb3 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 1 Error (rev 03)' +- bus: ff + dev: '14' + fn: '4' + id: 6fbc + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '5' + id: 6fbd + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '6' + id: 6fbe + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '7' + id: 6fbf + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '15' + fn: '0' + id: 6fb4 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 2 Thermal Control (rev 03)' +- bus: ff + dev: '15' + fn: '1' + id: 6fb5 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 3 Thermal Control (rev 03)' +- bus: ff + dev: '15' + fn: '2' + id: 6fb6 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 2 Error (rev 03)' +- bus: ff + dev: '15' + fn: '3' + id: 6fb7 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 3 Error (rev 03)' +- bus: ff + dev: 1e + fn: '0' + id: 6f98 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '1' + id: 6f99 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '2' + id: 6f9a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '3' + id: 6fc0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '4' + id: 6f9c + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1f + fn: '0' + id: 6f88 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1f + fn: '2' + id: 6f8a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' diff --git a/device/mellanox/x86_64-mlnx_msn3700-r0/platform.json b/device/mellanox/x86_64-mlnx_msn3700-r0/platform.json new file mode 100644 index 000000000000..8231004e9290 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3700-r0/platform.json @@ -0,0 +1,196 @@ +{ + "interfaces": { + "Ethernet0": { + "index": "1,1,1,1", + "lanes": "0,1,2,3", + "alias_at_lanes": "etp1a, etp1b, etp1c, etp1d", + "breakout_modes": "1x200G[100G,50G,40G,25G,10G,1G],2x100G[50G,40G,25G,10G,1G],4x50G[40G,25G,10G,1G]" + }, + "Ethernet4": { + "index": "2,2,2,2", + "lanes": "4,5,6,7", + "alias_at_lanes": "etp2a, etp2b, etp2c, etp2d", + "breakout_modes": "1x200G[100G,50G,40G,25G,10G,1G],2x100G[50G,40G,25G,10G,1G],4x50G[40G,25G,10G,1G]" + }, + "Ethernet8": { + "index": "3,3,3,3", + "lanes": "8,9,10,11", + "alias_at_lanes": "etp3a, etp3b, etp3c, etp3d", + "breakout_modes": "1x200G[100G,50G,40G,25G,10G,1G],2x100G[50G,40G,25G,10G,1G],4x50G[40G,25G,10G,1G]" + }, + "Ethernet12": { + "index": "4,4,4,4", + "lanes": "12,13,14,15", + "alias_at_lanes": "etp4a, etp4b, etp4c, etp4d", + "breakout_modes": "1x200G[100G,50G,40G,25G,10G,1G],2x100G[50G,40G,25G,10G,1G],4x50G[40G,25G,10G,1G]" + }, + "Ethernet16": { + "index": "5,5,5,5", + "lanes": "16,17,18,19", + "alias_at_lanes": "etp5a, etp5b, etp5c, etp5d", + "breakout_modes": "1x200G[100G,50G,40G,25G,10G,1G],2x100G[50G,40G,25G,10G,1G],4x50G[40G,25G,10G,1G]" + }, + "Ethernet20": { + "index": "6,6,6,6", + "lanes": "20,21,22,23", + "alias_at_lanes": "etp6a, etp6b, etp6c, etp6d", + "breakout_modes": "1x200G[100G,50G,40G,25G,10G,1G],2x100G[50G,40G,25G,10G,1G],4x50G[40G,25G,10G,1G]" + }, + "Ethernet24": { + "index": "7,7,7,7", + "lanes": "24,25,26,27", + "alias_at_lanes": "etp7a, etp7b, etp7c, etp7d", + "breakout_modes": "1x200G[100G,50G,40G,25G,10G,1G],2x100G[50G,40G,25G,10G,1G],4x50G[40G,25G,10G,1G]" + }, + "Ethernet28": { + "index": "8,8,8,8", + "lanes": "28,29,30,31", + "alias_at_lanes": "etp8a, etp8b, etp8c, etp8d", + "breakout_modes": "1x200G[100G,50G,40G,25G,10G,1G],2x100G[50G,40G,25G,10G,1G],4x50G[40G,25G,10G,1G]" + }, + "Ethernet32": { + "index": "9,9,9,9", + "lanes": "32,33,34,35", + "alias_at_lanes": "etp9a, etp9b, etp9c, etp9d", + "breakout_modes": "1x200G[100G,50G,40G,25G,10G,1G],2x100G[50G,40G,25G,10G,1G],4x50G[40G,25G,10G,1G]" + }, + "Ethernet36": { + "index": "10,10,10,10", + "lanes": "36,37,38,39", + "alias_at_lanes": "etp10a, etp10b, etp10c, etp10d", + "breakout_modes": "1x200G[100G,50G,40G,25G,10G,1G],2x100G[50G,40G,25G,10G,1G],4x50G[40G,25G,10G,1G]" + }, + "Ethernet40": { + "index": "11,11,11,11", + "lanes": "40,41,42,43", + "alias_at_lanes": "etp11a, etp11b, etp11c, etp11d", + "breakout_modes": "1x200G[100G,50G,40G,25G,10G,1G],2x100G[50G,40G,25G,10G,1G],4x50G[40G,25G,10G,1G]" + }, + "Ethernet44": { + "index": "12,12,12,12", + "lanes": "44,45,46,47", + "alias_at_lanes": "etp12a, etp12b, etp12c, etp12d", + "breakout_modes": "1x200G[100G,50G,40G,25G,10G,1G],2x100G[50G,40G,25G,10G,1G],4x50G[40G,25G,10G,1G]" + }, + "Ethernet48": { + "index": "13,13,13,13", + "lanes": "48,49,50,51", + "alias_at_lanes": "etp13a, etp13b, etp13c, etp13d", + "breakout_modes": "1x200G[100G,50G,40G,25G,10G,1G],2x100G[50G,40G,25G,10G,1G],4x50G[40G,25G,10G,1G]" + }, + "Ethernet52": { + "index": "14,14,14,14", + "lanes": "52,53,54,55", + "alias_at_lanes": "etp14a, etp14b, etp14c, etp14d", + "breakout_modes": "1x200G[100G,50G,40G,25G,10G,1G],2x100G[50G,40G,25G,10G,1G],4x50G[40G,25G,10G,1G]" + }, + "Ethernet56": { + "index": "15,15,15,15", + "lanes": "56,57,58,59", + "alias_at_lanes": "etp15a, etp15b, etp15c, etp15d", + "breakout_modes": "1x200G[100G,50G,40G,25G,10G,1G],2x100G[50G,40G,25G,10G,1G],4x50G[40G,25G,10G,1G]" + }, + "Ethernet60": { + "index": "16,16,16,16", + "lanes": "60,61,62,63", + "alias_at_lanes": "etp16a, etp16b, etp16c, etp16d", + "breakout_modes": "1x200G[100G,50G,40G,25G,10G,1G],2x100G[50G,40G,25G,10G,1G],4x50G[40G,25G,10G,1G]" + }, + "Ethernet64": { + "index": "17,17,17,17", + "lanes": "64,65,66,67", + "alias_at_lanes": "etp17a, etp17b, etp17c, etp17d", + "breakout_modes": "1x200G[100G,50G,40G,25G,10G,1G],2x100G[50G,40G,25G,10G,1G],4x50G[40G,25G,10G,1G]" + }, + "Ethernet68": { + "index": "18,18,18,18", + "lanes": "68,69,70,71", + "alias_at_lanes": "etp18a, etp18b, etp18c, etp18d", + "breakout_modes": "1x200G[100G,50G,40G,25G,10G,1G],2x100G[50G,40G,25G,10G,1G],4x50G[40G,25G,10G,1G]" + }, + "Ethernet72": { + "index": "19,19,19,19", + "lanes": "72,73,74,75", + "alias_at_lanes": "etp19a, etp19b, etp19c, etp19d", + "breakout_modes": "1x200G[100G,50G,40G,25G,10G,1G],2x100G[50G,40G,25G,10G,1G],4x50G[40G,25G,10G,1G]" + }, + "Ethernet76": { + "index": "20,20,20,20", + "lanes": "76,77,78,79", + "alias_at_lanes": "etp20a, etp20b, etp20c, etp20d", + "breakout_modes": "1x200G[100G,50G,40G,25G,10G,1G],2x100G[50G,40G,25G,10G,1G],4x50G[40G,25G,10G,1G]" + }, + "Ethernet80": { + "index": "21,21,21,21", + "lanes": "80,81,82,83", + "alias_at_lanes": "etp21a, etp21b, etp21c, etp21d", + "breakout_modes": "1x200G[100G,50G,40G,25G,10G,1G],2x100G[50G,40G,25G,10G,1G],4x50G[40G,25G,10G,1G]" + }, + "Ethernet84": { + "index": "22,22,22,22", + "lanes": "84,85,86,87", + "alias_at_lanes": "etp22a, etp22b, etp22c, etp22d", + "breakout_modes": "1x200G[100G,50G,40G,25G,10G,1G],2x100G[50G,40G,25G,10G,1G],4x50G[40G,25G,10G,1G]" + }, + "Ethernet88": { + "index": "23,23,23,23", + "lanes": "88,89,90,91", + "alias_at_lanes": "etp23a, etp23b, etp23c, etp23d", + "breakout_modes": "1x200G[100G,50G,40G,25G,10G,1G],2x100G[50G,40G,25G,10G,1G],4x50G[40G,25G,10G,1G]" + }, + "Ethernet92": { + "index": "24,24,24,24", + "lanes": "92,93,94,95", + "alias_at_lanes": "etp24a, etp24b, etp24c, etp24d", + "breakout_modes": "1x200G[100G,50G,40G,25G,10G,1G],2x100G[50G,40G,25G,10G,1G],4x50G[40G,25G,10G,1G]" + }, + "Ethernet96": { + "index": "25,25,25,25", + "lanes": "96,97,98,99", + "alias_at_lanes": "etp25a, etp25b, etp25c, etp25d", + "breakout_modes": "1x200G[100G,50G,40G,25G,10G,1G],2x100G[50G,40G,25G,10G,1G],4x50G[40G,25G,10G,1G]" + }, + "Ethernet100": { + "index": "26,26,26,26", + "lanes": "100,101,102,103", + "alias_at_lanes": "etp26a, etp26b, etp26c, etp26d", + "breakout_modes": "1x200G[100G,50G,40G,25G,10G,1G],2x100G[50G,40G,25G,10G,1G],4x50G[40G,25G,10G,1G]" + }, + "Ethernet104": { + "index": "27,27,27,27", + "lanes": "104,105,106,107", + "alias_at_lanes": "etp27a, etp27b, etp27c, etp27d", + "breakout_modes": "1x200G[100G,50G,40G,25G,10G,1G],2x100G[50G,40G,25G,10G,1G],4x50G[40G,25G,10G,1G]" + }, + "Ethernet108": { + "index": "28,28,28,28", + "lanes": "108,109,110,111", + "alias_at_lanes": "etp28a, etp28b, etp28c, etp28d", + "breakout_modes": "1x200G[100G,50G,40G,25G,10G,1G],2x100G[50G,40G,25G,10G,1G],4x50G[40G,25G,10G,1G]" + }, + "Ethernet112": { + "index": "29,29,29,29", + "lanes": "112,113,114,115", + "alias_at_lanes": "etp29a, etp29b, etp29c, etp29d", + "breakout_modes": "1x200G[100G,50G,40G,25G,10G,1G],2x100G[50G,40G,25G,10G,1G],4x50G[40G,25G,10G,1G]" + }, + "Ethernet116": { + "index": "30,30,30,30", + "lanes": "116,117,118,119", + "alias_at_lanes": "etp30a, etp30b, etp30c, etp30d", + "breakout_modes": "1x200G[100G,50G,40G,25G,10G,1G],2x100G[50G,40G,25G,10G,1G],4x50G[40G,25G,10G,1G]" + }, + "Ethernet120": { + "index": "31,31,31,31", + "lanes": "120,121,122,123", + "alias_at_lanes": "etp31a, etp31b, etp31c, etp31d", + "breakout_modes": "1x200G[100G,50G,40G,25G,10G,1G],2x100G[50G,40G,25G,10G,1G],4x50G[40G,25G,10G,1G]" + }, + "Ethernet124": { + "index": "32,32,32,32", + "lanes": "124,125,126,127", + "alias_at_lanes": "etp32a, etp32b, etp32c, etp32d", + "breakout_modes": "1x200G[100G,50G,40G,25G,10G,1G],2x100G[50G,40G,25G,10G,1G],4x50G[40G,25G,10G,1G]" + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn3700-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn3700-r0/platform_components.json index 7c0b7598aff7..6ca284d3f341 100644 --- a/device/mellanox/x86_64-mlnx_msn3700-r0/platform_components.json +++ b/device/mellanox/x86_64-mlnx_msn3700-r0/platform_components.json @@ -1,9 +1,13 @@ { "chassis": { - "x86_64-mlnx_msn3700-r0": { + "MSN3700": { "component": { + "ONIE": { }, + "SSD": { }, "BIOS": { }, - "CPLD": { } + "CPLD1": { }, + "CPLD2": { }, + "CPLD3": { } } } } diff --git a/device/mellanox/x86_64-mlnx_msn3700-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn3700-r0/sensors.conf index 376d079390a6..28a889aa27d2 100644 --- a/device/mellanox/x86_64-mlnx_msn3700-r0/sensors.conf +++ b/device/mellanox/x86_64-mlnx_msn3700-r0/sensors.conf @@ -22,9 +22,10 @@ bus "i2c-15" "i2c-1-mux (chan_id 6)" # Power controllers bus "i2c-5" "i2c-1-mux (chan_id 4)" chip "tps53679-i2c-*-70" - label in1 "PMIC-1 PSU 12V Rail (in)" - label in2 "PMIC-1 ASIC 0.8V VCORE Rail (out)" - label in3 "PMIC-1 ASIC 1.2V Rail (out)" + label in1 "PMIC-1 PSU 12V Rail (in1)" + label in2 "PMIC-1 PSU 12V Rail (in2)" + label in3 "PMIC-1 ASIC 0.8V VCORE Rail (out)" + label in4 "PMIC-1 ASIC 1.2V Rail (out)" label temp1 "PMIC-1 Temp 1" label temp2 "PMIC-1 Temp 2" label power1 "PMIC-1 ASIC 0.8V VCORE Rail Pwr (out)" @@ -32,10 +33,11 @@ bus "i2c-5" "i2c-1-mux (chan_id 4)" label curr1 "PMIC-1 ASIC 0.8V VCORE Rail Curr (out)" label curr2 "PMIC-1 ASIC 1.2V Rail Curr (out)" chip "tps53679-i2c-*-71" - label in1 "PMIC-2 PSU 12V Rail (in)" - label in2 "PMIC-2 ASIC 3.3V Rail (out)" - compute in2 (1.5)*@, @/(1.5) - label in3 "PMIC-2 ASIC 1.8V Rail (out)" + label in1 "PMIC-2 PSU 12V Rail (in1)" + label in2 "PMIC-2 PSU 12V Rail (in2)" + label in3 "PMIC-2 ASIC 3.3V Rail (out)" + compute in3 (1.5)*@, @/(1.5) + label in4 "PMIC-2 ASIC 1.8V Rail (out)" label temp1 "PMIC-2 Temp 1" label temp2 "PMIC-2 Temp 2" label power1 "PMIC-2 ASIC 3.3V Rail Pwr (out)" @@ -45,9 +47,10 @@ bus "i2c-5" "i2c-1-mux (chan_id 4)" bus "i2c-15" "i2c-1-mux (chan_id 6)" chip "tps53679-i2c-*-58" - label in1 "PMIC-3 PSU 12V Rail (in)" - label in2 "PMIC-3 COMEX 1.8V Rail (out)" - label in3 "PMIC-3 COMEX 1.05V Rail (out)" + label in1 "PMIC-3 PSU 12V Rail (in1)" + label in2 "PMIC-3 PSU 12V Rail (in2)" + label in3 "PMIC-3 COMEX 1.8V Rail (out)" + label in4 "PMIC-3 COMEX 1.05V Rail (out)" label temp1 "PMIC-3 Temp 1" label temp2 "PMIC-3 Temp 2" label power1 "PMIC-3 COMEX 1.8V Rail Pwr (out)" @@ -55,9 +58,10 @@ bus "i2c-15" "i2c-1-mux (chan_id 6)" label curr1 "PMIC-3 COMEX 1.8V Rail Curr (out)" label curr2 "PMIC-3 COMEX 1.05V Rail Curr (out)" chip "tps53679-i2c-*-61" - label in1 "PMIC-4 PSU 12V Rail (in)" - label in2 "PMIC-4 COMEX 1.2V Rail (out)" - ignore in3 + label in1 "PMIC-4 PSU 12V Rail (in1)" + label in2 "PMIC-4 PSU 12V Rail (in2)" + label in3 "PMIC-4 COMEX 1.2V Rail (out)" + ignore in4 label temp1 "PMIC-4 Temp 1" label temp2 "PMIC-4 Temp 2" label power1 "PMIC-4 COMEX 1.2V Rail Pwr (out)" diff --git a/device/mellanox/x86_64-mlnx_msn3700-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_msn3700-r0/system_health_monitoring_config.json new file mode 120000 index 000000000000..98df66c27ca5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3700-r0/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3700_simx-r0/pmon_daemon_control.json b/device/mellanox/x86_64-mlnx_msn3700_simx-r0/pmon_daemon_control.json index 40fc367acf32..dd83c2db12c5 100644 --- a/device/mellanox/x86_64-mlnx_msn3700_simx-r0/pmon_daemon_control.json +++ b/device/mellanox/x86_64-mlnx_msn3700_simx-r0/pmon_daemon_control.json @@ -1,5 +1,7 @@ { "skip_ledd": true, "skip_xcvrd": true, - "skip_psud": true + "skip_psud": true, + "skip_pcied": true, + "skip_thermalctld": true } diff --git a/device/mellanox/x86_64-mlnx_msn3700_simx-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_msn3700_simx-r0/system_health_monitoring_config.json new file mode 120000 index 000000000000..42fe945344c9 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3700_simx-r0/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700_simx-r0/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3700c-r0/ACS-MSN3700C/buffers_dynamic.json.j2 b/device/mellanox/x86_64-mlnx_msn3700c-r0/ACS-MSN3700C/buffers_dynamic.json.j2 new file mode 120000 index 000000000000..8c4117c66214 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3700c-r0/ACS-MSN3700C/buffers_dynamic.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_dynamic.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3700c-r0/ACS-MSN3700C/hwsku.json b/device/mellanox/x86_64-mlnx_msn3700c-r0/ACS-MSN3700C/hwsku.json new file mode 100644 index 000000000000..cac9d1d14da2 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3700c-r0/ACS-MSN3700C/hwsku.json @@ -0,0 +1,100 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet4": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet8": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet12": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet16": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet20": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet24": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet28": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet32": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet36": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet40": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet44": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet48": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet52": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet56": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet60": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet64": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet68": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet72": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet76": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet80": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet84": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet88": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet92": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet96": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet100": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet104": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet108": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet112": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet116": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet120": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet124": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn3700c-r0/pcie.yaml b/device/mellanox/x86_64-mlnx_msn3700c-r0/pcie.yaml new file mode 100644 index 000000000000..21c48fe64008 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3700c-r0/pcie.yaml @@ -0,0 +1,408 @@ +- bus: '00' + dev: '00' + fn: '0' + id: 6f00 + name: 'Host bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D DMI2 + (rev 03)' +- bus: '00' + dev: '01' + fn: '0' + id: 6f02 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 1 (rev 03)' +- bus: '00' + dev: '01' + fn: '1' + id: 6f03 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 1 (rev 03)' +- bus: '00' + dev: '02' + fn: '0' + id: 6f04 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 2 (rev 03)' +- bus: '00' + dev: '02' + fn: '2' + id: 6f06 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 2 (rev 03)' +- bus: '00' + dev: '03' + fn: '0' + id: 6f08 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 3 (rev 03)' +- bus: '00' + dev: '03' + fn: '2' + id: 6f0a + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 3 (rev 03)' +- bus: '00' + dev: '05' + fn: '0' + id: 6f28 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Map/VTd_Misc/System Management (rev 03)' +- bus: '00' + dev: '05' + fn: '1' + id: 6f29 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Hot Plug (rev 03)' +- bus: '00' + dev: '05' + fn: '2' + id: 6f2a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO RAS/Control Status/Global Errors (rev 03)' +- bus: '00' + dev: '05' + fn: '4' + id: 6f2c + name: 'PIC: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D I/O APIC (rev + 03)' +- bus: '00' + dev: '14' + fn: '0' + id: 8c31 + name: 'USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB + xHCI (rev 05)' +- bus: '00' + dev: 1c + fn: '0' + id: 8c10 + name: 'PCI bridge: Intel Corporation 8 Series/C220 Series Chipset Family PCI Express + Root Port #1 (rev d5)' +- bus: '00' + dev: 1c + fn: '7' + id: 8c1e + name: 'PCI bridge: Intel Corporation 8 Series/C220 Series Chipset Family PCI Express + Root Port #8 (rev d5)' +- bus: '00' + dev: 1d + fn: '0' + id: 8c26 + name: 'USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB + EHCI #1 (rev 05)' +- bus: '00' + dev: 1f + fn: '0' + id: 8c54 + name: 'ISA bridge: Intel Corporation C224 Series Chipset Family Server Standard + SKU LPC Controller (rev 05)' +- bus: '00' + dev: 1f + fn: '2' + id: 8c02 + name: 'SATA controller: Intel Corporation 8 Series/C220 Series Chipset Family 6-port + SATA Controller 1 [AHCI mode] (rev 05)' +- bus: '00' + dev: 1f + fn: '3' + id: 8c22 + name: 'SMBus: Intel Corporation 8 Series/C220 Series Chipset Family SMBus Controller + (rev 05)' +- bus: '03' + dev: '00' + fn: '0' + id: 6f50 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 0' +- bus: '03' + dev: '00' + fn: '1' + id: 6f51 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 1' +- bus: '03' + dev: '00' + fn: '2' + id: 6f52 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 2' +- bus: '03' + dev: '00' + fn: '3' + id: 6f53 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 3' +- bus: '06' + dev: '00' + fn: '0' + id: cf6c + name: 'Ethernet controller: Mellanox Technologies MT53100 [Spectrum-2, 64 x 100GbE + switch]' +- bus: 08 + dev: '00' + fn: '0' + id: '1533' + name: 'Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev + 03)' +- bus: ff + dev: 0b + fn: '0' + id: 6f81 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '1' + id: 6f36 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '2' + id: 6f37 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '3' + id: 6f76 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link Debug (rev 03)' +- bus: ff + dev: 0c + fn: '0' + id: 6fe0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0c + fn: '1' + id: 6fe1 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '0' + id: 6ff8 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '4' + id: 6ffc + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '5' + id: 6ffd + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '6' + id: 6ffe + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: '10' + fn: '0' + id: 6f1d + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R2PCIe Agent (rev 03)' +- bus: ff + dev: '10' + fn: '1' + id: 6f34 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R2PCIe Agent (rev 03)' +- bus: ff + dev: '10' + fn: '5' + id: 6f1e + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '10' + fn: '6' + id: 6f7d + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '10' + fn: '7' + id: 6f1f + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '12' + fn: '0' + id: 6fa0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Home Agent 0 (rev 03)' +- bus: ff + dev: '12' + fn: '1' + id: 6f30 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Home Agent 0 (rev 03)' +- bus: ff + dev: '13' + fn: '0' + id: 6fa8 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Target Address/Thermal/RAS (rev 03)' +- bus: ff + dev: '13' + fn: '1' + id: 6f71 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Target Address/Thermal/RAS (rev 03)' +- bus: ff + dev: '13' + fn: '2' + id: 6faa + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '3' + id: 6fab + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '4' + id: 6fac + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '5' + id: 6fad + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '6' + id: 6fae + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Broadcast (rev 03)' +- bus: ff + dev: '13' + fn: '7' + id: 6faf + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Global Broadcast (rev 03)' +- bus: ff + dev: '14' + fn: '0' + id: 6fb0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 0 Thermal Control (rev 03)' +- bus: ff + dev: '14' + fn: '1' + id: 6fb1 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 1 Thermal Control (rev 03)' +- bus: ff + dev: '14' + fn: '2' + id: 6fb2 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 0 Error (rev 03)' +- bus: ff + dev: '14' + fn: '3' + id: 6fb3 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 1 Error (rev 03)' +- bus: ff + dev: '14' + fn: '4' + id: 6fbc + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '5' + id: 6fbd + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '6' + id: 6fbe + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '7' + id: 6fbf + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '15' + fn: '0' + id: 6fb4 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 2 Thermal Control (rev 03)' +- bus: ff + dev: '15' + fn: '1' + id: 6fb5 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 3 Thermal Control (rev 03)' +- bus: ff + dev: '15' + fn: '2' + id: 6fb6 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 2 Error (rev 03)' +- bus: ff + dev: '15' + fn: '3' + id: 6fb7 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 3 Error (rev 03)' +- bus: ff + dev: 1e + fn: '0' + id: 6f98 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '1' + id: 6f99 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '2' + id: 6f9a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '3' + id: 6fc0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '4' + id: 6f9c + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1f + fn: '0' + id: 6f88 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1f + fn: '2' + id: 6f8a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' diff --git a/device/mellanox/x86_64-mlnx_msn3700c-r0/platform.json b/device/mellanox/x86_64-mlnx_msn3700c-r0/platform.json new file mode 100644 index 000000000000..33db99b06a3a --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3700c-r0/platform.json @@ -0,0 +1,196 @@ +{ + "interfaces": { + "Ethernet0": { + "index": "1,1,1,1", + "lanes": "0,1,2,3", + "alias_at_lanes": "etp1a, etp1b, etp1c, etp1d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet4": { + "index": "2,2,2,2", + "lanes": "4,5,6,7", + "alias_at_lanes": "etp2a, etp2b, etp2c, etp2d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet8": { + "index": "3,3,3,3", + "lanes": "8,9,10,11", + "alias_at_lanes": "etp3a, etp3b, etp3c, etp3d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet12": { + "index": "4,4,4,4", + "lanes": "12,13,14,15", + "alias_at_lanes": "etp4a, etp4b, etp4c, etp4d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet16": { + "index": "5,5,5,5", + "lanes": "16,17,18,19", + "alias_at_lanes": "etp5a, etp5b, etp5c, etp5d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet20": { + "index": "6,6,6,6", + "lanes": "20,21,22,23", + "alias_at_lanes": "etp6a, etp6b, etp6c, etp6d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet24": { + "index": "7,7,7,7", + "lanes": "24,25,26,27", + "alias_at_lanes": "etp7a, etp7b, etp7c, etp7d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet28": { + "index": "8,8,8,8", + "lanes": "28,29,30,31", + "alias_at_lanes": "etp8a, etp8b, etp8c, etp8d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet32": { + "index": "9,9,9,9", + "lanes": "32,33,34,35", + "alias_at_lanes": "etp9a, etp9b, etp9c, etp9d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet36": { + "index": "10,10,10,10", + "lanes": "36,37,38,39", + "alias_at_lanes": "etp10a, etp10b, etp10c, etp10d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet40": { + "index": "11,11,11,11", + "lanes": "40,41,42,43", + "alias_at_lanes": "etp11a, etp11b, etp11c, etp11d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet44": { + "index": "12,12,12,12", + "lanes": "44,45,46,47", + "alias_at_lanes": "etp12a, etp12b, etp12c, etp12d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet48": { + "index": "13,13,13,13", + "lanes": "48,49,50,51", + "alias_at_lanes": "etp13a, etp13b, etp13c, etp13d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet52": { + "index": "14,14,14,14", + "lanes": "52,53,54,55", + "alias_at_lanes": "etp14a, etp14b, etp14c, etp14d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet56": { + "index": "15,15,15,15", + "lanes": "56,57,58,59", + "alias_at_lanes": "etp15a, etp15b, etp15c, etp15d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet60": { + "index": "16,16,16,16", + "lanes": "60,61,62,63", + "alias_at_lanes": "etp16a, etp16b, etp16c, etp16d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet64": { + "index": "17,17,17,17", + "lanes": "64,65,66,67", + "alias_at_lanes": "etp17a, etp17b, etp17c, etp17d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet68": { + "index": "18,18,18,18", + "lanes": "68,69,70,71", + "alias_at_lanes": "etp18a, etp18b, etp18c, etp18d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet72": { + "index": "19,19,19,19", + "lanes": "72,73,74,75", + "alias_at_lanes": "etp19a, etp19b, etp19c, etp19d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet76": { + "index": "20,20,20,20", + "lanes": "76,77,78,79", + "alias_at_lanes": "etp20a, etp20b, etp20c, etp20d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet80": { + "index": "21,21,21,21", + "lanes": "80,81,82,83", + "alias_at_lanes": "etp21a, etp21b, etp21c, etp21d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet84": { + "index": "22,22,22,22", + "lanes": "84,85,86,87", + "alias_at_lanes": "etp22a, etp22b, etp22c, etp22d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet88": { + "index": "23,23,23,23", + "lanes": "88,89,90,91", + "alias_at_lanes": "etp23a, etp23b, etp23c, etp23d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet92": { + "index": "24,24,24,24", + "lanes": "92,93,94,95", + "alias_at_lanes": "etp24a, etp24b, etp24c, etp24d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet96": { + "index": "25,25,25,25", + "lanes": "96,97,98,99", + "alias_at_lanes": "etp25a, etp25b, etp25c, etp25d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet100": { + "index": "26,26,26,26", + "lanes": "100,101,102,103", + "alias_at_lanes": "etp26a, etp26b, etp26c, etp26d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet104": { + "index": "27,27,27,27", + "lanes": "104,105,106,107", + "alias_at_lanes": "etp27a, etp27b, etp27c, etp27d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet108": { + "index": "28,28,28,28", + "lanes": "108,109,110,111", + "alias_at_lanes": "etp28a, etp28b, etp28c, etp28d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet112": { + "index": "29,29,29,29", + "lanes": "112,113,114,115", + "alias_at_lanes": "etp29a, etp29b, etp29c, etp29d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet116": { + "index": "30,30,30,30", + "lanes": "116,117,118,119", + "alias_at_lanes": "etp30a, etp30b, etp30c, etp30d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet120": { + "index": "31,31,31,31", + "lanes": "120,121,122,123", + "alias_at_lanes": "etp31a, etp31b, etp31c, etp31d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet124": { + "index": "32,32,32,32", + "lanes": "124,125,126,127", + "alias_at_lanes": "etp32a, etp32b, etp32c, etp32d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn3700c-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn3700c-r0/platform_components.json index c55b9feab7cb..807503fced45 100644 --- a/device/mellanox/x86_64-mlnx_msn3700c-r0/platform_components.json +++ b/device/mellanox/x86_64-mlnx_msn3700c-r0/platform_components.json @@ -1,9 +1,13 @@ { "chassis": { - "x86_64-mlnx_msn3700c-r0": { + "MSN3700C": { "component": { + "ONIE": { }, + "SSD": { }, "BIOS": { }, - "CPLD": { } + "CPLD1": { }, + "CPLD2": { }, + "CPLD3": { } } } } diff --git a/device/mellanox/x86_64-mlnx_msn3700c-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn3700c-r0/sensors.conf index 7efcefc5f740..3c58e27f3e68 100644 --- a/device/mellanox/x86_64-mlnx_msn3700c-r0/sensors.conf +++ b/device/mellanox/x86_64-mlnx_msn3700c-r0/sensors.conf @@ -22,9 +22,10 @@ bus "i2c-15" "i2c-1-mux (chan_id 6)" # Power controllers bus "i2c-5" "i2c-1-mux (chan_id 4)" chip "tps53679-i2c-*-70" - label in1 "PMIC-1 PSU 12V Rail (in)" - label in2 "PMIC-1 ASIC 0.8V VCORE Rail (out)" - label in3 "PMIC-1 ASIC 1.2V Rail (out)" + label in1 "PMIC-1 PSU 12V Rail (in1)" + label in2 "PMIC-1 PSU 12V Rail (in2)" + label in3 "PMIC-1 ASIC 0.8V VCORE Rail (out)" + label in4 "PMIC-1 ASIC 1.2V Rail (out)" label temp1 "PMIC-1 Temp 1" label temp2 "PMIC-1 Temp 2" label power1 "PMIC-1 ASIC 0.8V VCORE Rail Pwr (out)" @@ -32,10 +33,11 @@ bus "i2c-5" "i2c-1-mux (chan_id 4)" label curr1 "PMIC-1 ASIC 0.8V VCORE Rail Curr (out)" label curr2 "PMIC-1 ASIC 1.2V Rail Curr (out)" chip "tps53679-i2c-*-71" - label in1 "PMIC-2 PSU 12V Rail (in)" - label in2 "PMIC-2 ASIC 3.3V Rail (out)" - compute in2 (1.5)*@, @/(1.5) - label in3 "PMIC-2 ASIC 1.8V Rail (out)" + label in1 "PMIC-2 PSU 12V Rail (in1)" + label in2 "PMIC-2 PSU 12V Rail (in2)" + label in3 "PMIC-2 ASIC 3.3V Rail (out)" + compute in3 (1.5)*@, @/(1.5) + label in4 "PMIC-2 ASIC 1.8V Rail (out)" label temp1 "PMIC-2 Temp 1" label temp2 "PMIC-2 Temp 2" label power1 "PMIC-2 ASIC 3.3V Rail Pwr (out)" @@ -45,9 +47,10 @@ bus "i2c-5" "i2c-1-mux (chan_id 4)" bus "i2c-15" "i2c-1-mux (chan_id 6)" chip "tps53679-i2c-*-58" - label in1 "PMIC-3 PSU 12V Rail (in)" - label in2 "PMIC-3 COMEX 1.8V Rail (out)" - label in3 "PMIC-3 COMEX 1.05V Rail (out)" + label in1 "PMIC-3 PSU 12V Rail (in1)" + label in2 "PMIC-3 PSU 12V Rail (in2)" + label in3 "PMIC-3 COMEX 1.8V Rail (out)" + label in4 "PMIC-3 COMEX 1.05V Rail (out)" label temp1 "PMIC-3 Temp 1" label temp2 "PMIC-3 Temp 2" label power1 "PMIC-3 COMEX 1.8V Rail Pwr (out)" @@ -55,9 +58,10 @@ bus "i2c-15" "i2c-1-mux (chan_id 6)" label curr1 "PMIC-3 COMEX 1.8V Rail Curr (out)" label curr2 "PMIC-3 COMEX 1.05V Rail Curr (out)" chip "tps53679-i2c-*-61" - label in1 "PMIC-4 PSU 12V Rail (in)" - label in2 "PMIC-4 COMEX 1.2V Rail (out)" - ignore in3 + label in1 "PMIC-4 PSU 12V Rail (in1)" + label in2 "PMIC-4 PSU 12V Rail (in2)" + label in3 "PMIC-4 COMEX 1.2V Rail (out)" + ignore in4 label temp1 "PMIC-4 Temp 1" label temp2 "PMIC-4 Temp 2" label power1 "PMIC-4 COMEX 1.2V Rail Pwr (out)" diff --git a/device/mellanox/x86_64-mlnx_msn3700c-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_msn3700c-r0/system_health_monitoring_config.json new file mode 120000 index 000000000000..98df66c27ca5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3700c-r0/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/system_health_monitoring_config.json \ 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 index d69a0cc13835..b83e142448d6 100644 --- 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 @@ -1,8 +1,8 @@ {% 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' %} +{% set ingress_lossless_pool_size = '13924352' %} +{% set ingress_lossy_pool_size = '13924352' %} +{% set egress_lossless_pool_size = '34287552' %} +{% set egress_lossy_pool_size = '13924352' %} {%- macro generate_port_lists(PORT_ALL) %} {# Generate list of ports #} @@ -14,12 +14,16 @@ {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { + {%- if dynamic_mode is not defined %} "size": "{{ ingress_lossless_pool_size }}", + {%- endif %} "type": "ingress", "mode": "dynamic" }, "ingress_lossy_pool": { + {%- if dynamic_mode is not defined %} "size": "{{ ingress_lossy_pool_size }}", + {%- endif %} "type": "ingress", "mode": "dynamic" }, @@ -29,7 +33,9 @@ "mode": "dynamic" }, "egress_lossy_pool": { + {%- if dynamic_mode is not defined %} "size": "{{ egress_lossy_pool_size }}", + {%- endif %} "type": "egress", "mode": "dynamic" } @@ -38,7 +44,7 @@ "ingress_lossless_profile": { "pool":"[BUFFER_POOL|ingress_lossless_pool]", "size":"0", - "dynamic_th":"0" + "dynamic_th":"7" }, "ingress_lossy_profile": { "pool":"[BUFFER_POOL|ingress_lossy_pool]", @@ -52,8 +58,8 @@ }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", - "size":"4096", - "dynamic_th":"3" + "size":"9216", + "dynamic_th":"7" }, "q_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", 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 index 78d43455a424..abcab930c63e 100644 --- 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 @@ -1,8 +1,8 @@ {% 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' %} +{% set ingress_lossless_pool_size = '12457984' %} +{% set ingress_lossy_pool_size = '12457984' %} +{% set egress_lossless_pool_size = '34287552' %} +{% set egress_lossy_pool_size = '12457984' %} {%- macro generate_port_lists(PORT_ALL) %} {# Generate list of ports #} @@ -14,12 +14,16 @@ {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { + {%- if dynamic_mode is not defined %} "size": "{{ ingress_lossless_pool_size }}", + {%- endif %} "type": "ingress", "mode": "dynamic" }, "ingress_lossy_pool": { + {%- if dynamic_mode is not defined %} "size": "{{ ingress_lossy_pool_size }}", + {%- endif %} "type": "ingress", "mode": "dynamic" }, @@ -29,7 +33,9 @@ "mode": "dynamic" }, "egress_lossy_pool": { + {%- if dynamic_mode is not defined %} "size": "{{ egress_lossy_pool_size }}", + {%- endif %} "type": "egress", "mode": "dynamic" } @@ -38,7 +44,7 @@ "ingress_lossless_profile": { "pool":"[BUFFER_POOL|ingress_lossless_pool]", "size":"0", - "dynamic_th":"0" + "dynamic_th":"7" }, "ingress_lossy_profile": { "pool":"[BUFFER_POOL|ingress_lossy_pool]", @@ -52,8 +58,8 @@ }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", - "size":"4096", - "dynamic_th":"3" + "size":"9216", + "dynamic_th":"7" }, "q_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_dynamic.json.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_dynamic.json.j2 new file mode 120000 index 000000000000..8c4117c66214 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_dynamic.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_dynamic.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/hwsku.json b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/hwsku.json new file mode 100644 index 000000000000..33fe1cc94a7b --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/hwsku.json @@ -0,0 +1,196 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet4": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet8": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet12": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet16": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet20": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet24": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet28": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet32": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet36": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet40": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet44": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet48": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet52": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet56": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet60": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet64": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet68": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet72": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet76": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet80": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet84": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet88": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet92": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet96": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet100": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet104": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet108": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet112": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet116": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet120": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet124": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet128": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet132": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet136": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet140": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet144": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet148": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet152": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet156": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet160": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet164": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet168": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet172": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet176": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet180": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet184": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet188": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet192": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet196": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet200": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet204": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet208": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet212": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet216": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet220": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet224": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet228": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet232": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet236": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet240": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet244": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet248": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet252": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + } + } +} 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 index 7c28e4c0d500..320daa45d29b 100644 --- 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 @@ -1,23 +1,17 @@ -# 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 +# PG lossless profiles. +# speed cable size xon xoff threshold + 10000 5m 54272 19456 34816 0 + 25000 5m 58368 19456 38912 0 + 40000 5m 61440 19456 41984 0 + 50000 5m 64512 19456 45056 0 + 100000 5m 75776 19456 56320 0 + 10000 40m 55296 19456 35840 0 + 25000 40m 60416 19456 40960 0 + 40000 40m 65536 19456 46080 0 + 50000 40m 69632 19456 50176 0 + 100000 40m 86016 19456 66560 0 + 10000 300m 63488 19456 44032 0 + 25000 300m 78848 19456 59392 0 + 40000 300m 95232 19456 75776 0 + 50000 300m 106496 19456 87040 0 + 100000 300m 159744 19456 140288 0 diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/port_config.ini b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/port_config.ini index db5216ccf24f..d43b11a22eb6 100644 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/port_config.ini +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/port_config.ini @@ -1,65 +1,65 @@ -# 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 -Ethernet128 128,129,130,131 etp33 -Ethernet132 132,133,134,135 etp34 -Ethernet136 136,137,138,139 etp35 -Ethernet140 140,141,142,143 etp36 -Ethernet144 144,145,146,147 etp37 -Ethernet148 148,149,150,151 etp38 -Ethernet152 152,153,154,155 etp39 -Ethernet156 156,157,158,159 etp40 -Ethernet160 160,161,162,163 etp41 -Ethernet164 164,165,166,167 etp42 -Ethernet168 168,169,170,171 etp43 -Ethernet172 172,173,174,175 etp44 -Ethernet176 176,177,178,179 etp45 -Ethernet180 180,181,182,183 etp46 -Ethernet184 184,185,186,187 etp47 -Ethernet188 188,189,190,191 etp48 -Ethernet192 192,193,194,195 etp49 -Ethernet196 196,197,198,199 etp50 -Ethernet200 200,201,202,203 etp51 -Ethernet204 204,205,206,207 etp52 -Ethernet208 208,209,210,211 etp53 -Ethernet212 212,213,214,215 etp54 -Ethernet216 216,217,218,219 etp55 -Ethernet220 220,221,222,223 etp56 -Ethernet224 224,225,226,227 etp57 -Ethernet228 228,229,230,231 etp58 -Ethernet232 232,233,234,235 etp59 -Ethernet236 236,237,238,239 etp60 -Ethernet240 240,241,242,243 etp61 -Ethernet244 244,245,246,247 etp62 -Ethernet248 248,249,250,251 etp63 -Ethernet252 252,253,254,255 etp64 +# name lanes alias index +Ethernet0 0,1,2,3 etp1 1 +Ethernet4 4,5,6,7 etp2 2 +Ethernet8 8,9,10,11 etp3 3 +Ethernet12 12,13,14,15 etp4 4 +Ethernet16 16,17,18,19 etp5 5 +Ethernet20 20,21,22,23 etp6 6 +Ethernet24 24,25,26,27 etp7 7 +Ethernet28 28,29,30,31 etp8 8 +Ethernet32 32,33,34,35 etp9 9 +Ethernet36 36,37,38,39 etp10 10 +Ethernet40 40,41,42,43 etp11 11 +Ethernet44 44,45,46,47 etp12 12 +Ethernet48 48,49,50,51 etp13 13 +Ethernet52 52,53,54,55 etp14 14 +Ethernet56 56,57,58,59 etp15 15 +Ethernet60 60,61,62,63 etp16 16 +Ethernet64 64,65,66,67 etp17 17 +Ethernet68 68,69,70,71 etp18 18 +Ethernet72 72,73,74,75 etp19 19 +Ethernet76 76,77,78,79 etp20 20 +Ethernet80 80,81,82,83 etp21 21 +Ethernet84 84,85,86,87 etp22 22 +Ethernet88 88,89,90,91 etp23 23 +Ethernet92 92,93,94,95 etp24 24 +Ethernet96 96,97,98,99 etp25 25 +Ethernet100 100,101,102,103 etp26 26 +Ethernet104 104,105,106,107 etp27 27 +Ethernet108 108,109,110,111 etp28 28 +Ethernet112 112,113,114,115 etp29 29 +Ethernet116 116,117,118,119 etp30 30 +Ethernet120 120,121,122,123 etp31 31 +Ethernet124 124,125,126,127 etp32 32 +Ethernet128 128,129,130,131 etp33 33 +Ethernet132 132,133,134,135 etp34 34 +Ethernet136 136,137,138,139 etp35 35 +Ethernet140 140,141,142,143 etp36 36 +Ethernet144 144,145,146,147 etp37 37 +Ethernet148 148,149,150,151 etp38 38 +Ethernet152 152,153,154,155 etp39 39 +Ethernet156 156,157,158,159 etp40 40 +Ethernet160 160,161,162,163 etp41 41 +Ethernet164 164,165,166,167 etp42 42 +Ethernet168 168,169,170,171 etp43 43 +Ethernet172 172,173,174,175 etp44 44 +Ethernet176 176,177,178,179 etp45 45 +Ethernet180 180,181,182,183 etp46 46 +Ethernet184 184,185,186,187 etp47 47 +Ethernet188 188,189,190,191 etp48 48 +Ethernet192 192,193,194,195 etp49 49 +Ethernet196 196,197,198,199 etp50 50 +Ethernet200 200,201,202,203 etp51 51 +Ethernet204 204,205,206,207 etp52 52 +Ethernet208 208,209,210,211 etp53 53 +Ethernet212 212,213,214,215 etp54 54 +Ethernet216 216,217,218,219 etp55 55 +Ethernet220 220,221,222,223 etp56 56 +Ethernet224 224,225,226,227 etp57 57 +Ethernet228 228,229,230,231 etp58 58 +Ethernet232 232,233,234,235 etp59 59 +Ethernet236 236,237,238,239 etp60 60 +Ethernet240 240,241,242,243 etp61 61 +Ethernet244 244,245,246,247 etp62 62 +Ethernet248 248,249,250,251 etp63 63 +Ethernet252 252,253,254,255 etp64 64 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 1b3c77ce381c..4d9cc3cf7f8c 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,8 +5,8 @@ 00:02:03:04:05:00 - - 1 + + 1 64 diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers.json.j2 new file mode 120000 index 000000000000..add8bf8bb7c2 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/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-C64/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..a59beaeeb698 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_defaults_t0.j2 @@ -0,0 +1,104 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '25866240' %} +{% set ingress_lossless_pool_xoff = '2523136' %} +{% set egress_lossless_pool_size = '34287552' %} +{% set egress_lossy_pool_size = '25866240' %} + +{%- 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": { + {%- if dynamic_mode is not defined %} + "size": "{{ ingress_lossless_pool_size }}", + "xoff": "{{ ingress_lossless_pool_xoff }}", + {%- endif %} + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + {%- if dynamic_mode is not defined %} + "size": "{{ egress_lossy_pool_size }}", + {%- endif %} + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "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", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"9216", + "dynamic_th":"7" + }, + "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]" + }{% 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/Mellanox-SN3800-C64/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..d610abeb4f26 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_defaults_t1.j2 @@ -0,0 +1,104 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '23900160' %} +{% set ingress_lossless_pool_xoff = '4489216' %} +{% set egress_lossless_pool_size = '34287552' %} +{% set egress_lossy_pool_size = '23900160' %} + +{%- 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": { + {%- if dynamic_mode is not defined %} + "size": "{{ ingress_lossless_pool_size }}", + "xoff": "{{ ingress_lossless_pool_xoff }}", + {%- endif %} + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + {%- if dynamic_mode is not defined %} + "size": "{{ egress_lossy_pool_size }}", + {%- endif %} + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "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", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"9216", + "dynamic_th":"7" + }, + "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]" + }{% 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/Mellanox-SN3800-C64/buffers_dynamic.json.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_dynamic.json.j2 new file mode 120000 index 000000000000..8c4117c66214 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_dynamic.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_dynamic.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/hwsku.json b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/hwsku.json new file mode 100644 index 000000000000..33fe1cc94a7b --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/hwsku.json @@ -0,0 +1,196 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet4": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet8": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet12": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet16": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet20": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet24": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet28": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet32": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet36": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet40": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet44": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet48": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet52": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet56": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet60": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet64": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet68": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet72": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet76": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet80": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet84": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet88": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet92": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet96": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet100": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet104": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet108": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet112": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet116": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet120": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet124": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet128": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet132": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet136": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet140": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet144": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet148": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet152": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet156": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet160": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet164": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet168": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet172": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet176": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet180": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet184": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet188": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet192": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet196": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet200": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet204": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet208": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet212": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet216": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet220": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet224": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet228": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet232": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet236": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet240": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet244": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet248": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet252": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/pg_profile_lookup.ini new file mode 120000 index 000000000000..ccbbfa44cd9c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/pg_profile_lookup.ini @@ -0,0 +1 @@ +../Mellanox-SN3800-D112C8/pg_profile_lookup.ini \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/port_config.ini b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/port_config.ini new file mode 120000 index 000000000000..3302c4ce12d8 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/port_config.ini @@ -0,0 +1 @@ +../ACS-MSN3800/port_config.ini \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/qos.json.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/qos.json.j2 new file mode 120000 index 000000000000..eccf286dc879 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/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-C64/sai.profile b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/sai.profile new file mode 120000 index 000000000000..f6fb0ccbfc97 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/sai.profile @@ -0,0 +1 @@ +../ACS-MSN3800/sai.profile \ No newline at end of file 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-C64/sai_3800.xml similarity index 100% rename from device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800.xml rename to device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/sai_3800.xml 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 deleted file mode 120000 index 0987f6724863..000000000000 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 +++ /dev/null @@ -1 +0,0 @@ -../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_t0.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..63e5d5f3a85a --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 @@ -0,0 +1,104 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '20017152' %} +{% set ingress_lossless_pool_xoff = '3440640' %} +{% set egress_lossless_pool_size = '34287552' %} +{% set egress_lossy_pool_size = '20017152' %} + +{%- 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": { + {%- if dynamic_mode is not defined %} + "size": "{{ ingress_lossless_pool_size }}", + "xoff": "{{ ingress_lossless_pool_xoff }}", + {%- endif %} + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + {%- if dynamic_mode is not defined %} + "size": "{{ egress_lossy_pool_size }}", + {%- endif %} + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "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", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"9216", + "dynamic_th":"7" + }, + "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]" + }{% 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/Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 deleted file mode 120000 index 119460bfa556..000000000000 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 +++ /dev/null @@ -1 +0,0 @@ -../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/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..d1ccce62bb14 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 @@ -0,0 +1,104 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '19124224' %} +{% set ingress_lossless_pool_xoff = '4333568' %} +{% set egress_lossless_pool_size = '34287552' %} +{% set egress_lossy_pool_size = '19124224' %} + +{%- 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": { + {%- if dynamic_mode is not defined %} + "size": "{{ ingress_lossless_pool_size }}", + "xoff": "{{ ingress_lossless_pool_xoff }}", + {%- endif %} + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + {%- if dynamic_mode is not defined %} + "size": "{{ egress_lossy_pool_size }}", + {%- endif %} + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "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", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"9216", + "dynamic_th":"7" + }, + "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]" + }{% 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/Mellanox-SN3800-D112C8/buffers_dynamic.json.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_dynamic.json.j2 new file mode 120000 index 000000000000..8c4117c66214 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_dynamic.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_dynamic.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/hwsku.json b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/hwsku.json new file mode 100644 index 000000000000..5901836014fe --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/hwsku.json @@ -0,0 +1,364 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet2": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet4": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet6": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet8": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet10": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet12": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet14": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet16": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet18": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet20": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet22": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet24": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet26": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet28": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet30": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet32": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet34": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet36": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet38": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet40": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet42": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet44": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet46": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet48": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet50": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet52": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet54": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet56": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet58": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet60": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet62": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet64": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet66": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet68": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet70": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet72": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet74": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet76": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet78": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet80": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet82": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet84": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet86": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet88": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet90": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet92": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet94": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet96": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet100": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet104": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet106": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet108": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet110": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet112": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet116": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet120": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet122": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet124": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet126": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet128": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet132": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet136": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet138": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet140": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet142": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet144": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet148": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet152": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet154": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet156": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet158": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet160": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet162": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet164": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet166": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet168": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet170": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet172": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet174": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet176": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet178": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet180": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet182": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet184": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet186": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet188": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet190": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet192": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet194": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet196": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet198": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet200": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet202": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet204": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet206": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet208": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet210": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet212": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet214": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet216": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet218": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet220": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet222": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet224": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet226": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet228": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet230": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet232": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet234": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet236": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet238": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet240": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet242": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet244": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet246": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet248": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet250": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet252": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet254": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + } + } +} 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 deleted file mode 120000 index db2f74508aad..000000000000 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/pg_profile_lookup.ini +++ /dev/null @@ -1 +0,0 @@ -../ACS-MSN3800/pg_profile_lookup.ini \ 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 100644 index 000000000000..810d7e77e61f --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 10000 5m 19456 19456 25600 0 + 25000 5m 19456 19456 28672 0 + 40000 5m 19456 19456 30720 0 + 50000 5m 19456 19456 32768 0 + 100000 5m 19456 19456 40960 0 + 10000 40m 19456 19456 26624 0 + 25000 40m 19456 19456 30720 0 + 40000 40m 19456 19456 33792 0 + 50000 40m 19456 19456 36864 0 + 100000 40m 19456 19456 48128 0 + 10000 300m 19456 19456 31744 0 + 25000 300m 19456 19456 44032 0 + 40000 300m 19456 19456 55296 0 + 50000 300m 19456 19456 63488 0 + 100000 300m 19456 19456 102400 0 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 index 9559119c7e38..8e40d6bd41ec 100644 --- 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 @@ -1,105 +1,121 @@ -# 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 +# name lanes alias index speed +Ethernet0 0,1 etp1a 1 50000 +Ethernet2 2,3 etp1b 1 50000 +Ethernet4 4,5 etp2a 2 50000 +Ethernet6 6,7 etp2b 2 50000 +Ethernet8 8,9 etp3a 3 50000 +Ethernet10 10,11 etp3b 3 50000 +Ethernet12 12,13 etp4a 4 50000 +Ethernet14 14,15 etp4b 4 50000 +Ethernet16 16,17 etp5a 5 50000 +Ethernet18 18,19 etp5b 5 50000 +Ethernet20 20,21 etp6a 6 50000 +Ethernet22 22,23 etp6b 6 50000 +Ethernet24 24,25 etp7a 7 50000 +Ethernet26 26,27 etp7b 7 50000 +Ethernet28 28,29 etp8a 8 50000 +Ethernet30 30,31 etp8b 8 50000 +Ethernet32 32,33 etp9a 9 50000 +Ethernet34 34,35 etp9b 9 50000 +Ethernet36 36,37 etp10a 10 50000 +Ethernet38 38,39 etp10b 10 50000 +Ethernet40 40,41 etp11a 11 50000 +Ethernet42 42,43 etp11b 11 50000 +Ethernet44 44,45 etp12a 12 50000 +Ethernet46 46,47 etp12b 12 50000 +Ethernet48 48,49 etp13a 13 50000 +Ethernet50 50,51 etp13b 13 50000 +Ethernet52 52,53 etp14a 14 50000 +Ethernet54 54,55 etp14b 14 50000 +Ethernet56 56,57 etp15a 15 50000 +Ethernet58 58,59 etp15b 15 50000 +Ethernet60 60,61 etp16a 16 50000 +Ethernet62 62,63 etp16b 16 50000 +Ethernet64 64,65 etp17a 17 50000 +Ethernet66 66,67 etp17b 17 50000 +Ethernet68 68,69 etp18a 18 50000 +Ethernet70 70,71 etp18b 18 50000 +Ethernet72 72,73 etp19a 19 50000 +Ethernet74 74,75 etp19b 19 50000 +Ethernet76 76,77 etp20a 20 50000 +Ethernet78 78,79 etp20b 20 50000 +Ethernet80 80,81 etp21a 21 50000 +Ethernet82 82,83 etp21b 21 50000 +Ethernet84 84,85 etp22a 22 50000 +Ethernet86 86,87 etp22b 22 50000 +Ethernet88 88,89 etp23a 23 50000 +Ethernet90 90,91 etp23b 23 50000 +Ethernet92 92,93 etp24a 24 50000 +Ethernet94 94,95 etp24b 24 50000 +Ethernet96 96,97,98,99 etp25 25 100000 +Ethernet100 100,101,102,103 etp26 26 100000 +Ethernet104 104,105 etp27a 27 50000 +Ethernet106 106,107 etp27b 27 50000 +Ethernet108 108,109 etp28a 28 50000 +Ethernet110 110,111 etp28b 28 50000 +Ethernet112 112,113,114,115 etp29 29 100000 +Ethernet116 116,117,118,119 etp30 30 100000 +Ethernet120 120,121 etp31a 31 50000 +Ethernet122 122,123 etp31b 31 50000 +Ethernet124 124,125 etp32a 32 50000 +Ethernet126 126,127 etp32b 32 50000 +Ethernet128 128,129,130,131 etp33 33 100000 +Ethernet132 132,133,134,135 etp34 34 100000 +Ethernet136 136,137 etp35a 35 50000 +Ethernet138 138,139 etp35b 35 50000 +Ethernet140 140,141 etp36a 36 50000 +Ethernet142 142,143 etp36b 36 50000 +Ethernet144 144,145,146,147 etp37 37 100000 +Ethernet148 148,149,150,151 etp38 38 100000 +Ethernet152 152,153 etp39a 39 50000 +Ethernet154 154,155 etp39b 39 50000 +Ethernet156 156,157 etp40a 40 50000 +Ethernet158 158,159 etp40b 40 50000 +Ethernet160 160,161 etp41a 41 50000 +Ethernet162 162,163 etp41b 41 50000 +Ethernet164 164,165 etp42a 42 50000 +Ethernet166 166,167 etp42b 42 50000 +Ethernet168 168,169 etp43a 43 50000 +Ethernet170 170,171 etp43b 43 50000 +Ethernet172 172,173 etp44a 44 50000 +Ethernet174 174,175 etp44b 44 50000 +Ethernet176 176,177 etp45a 45 50000 +Ethernet178 178,179 etp45b 45 50000 +Ethernet180 180,181 etp46a 46 50000 +Ethernet182 182,183 etp46b 46 50000 +Ethernet184 184,185 etp47a 47 50000 +Ethernet186 186,187 etp47b 47 50000 +Ethernet188 188,189 etp48a 48 50000 +Ethernet190 190,191 etp48b 48 50000 +Ethernet192 192,193 etp49a 49 50000 +Ethernet194 194,195 etp49b 49 50000 +Ethernet196 196,197 etp50a 50 50000 +Ethernet198 198,199 etp50b 50 50000 +Ethernet200 200,201 etp51a 51 50000 +Ethernet202 202,203 etp51b 51 50000 +Ethernet204 204,205 etp52a 52 50000 +Ethernet206 206,207 etp52b 52 50000 +Ethernet208 208,209 etp53a 53 50000 +Ethernet210 210,211 etp53b 53 50000 +Ethernet212 212,213 etp54a 54 50000 +Ethernet214 214,215 etp54b 54 50000 +Ethernet216 216,217 etp55a 55 50000 +Ethernet218 218,219 etp55b 55 50000 +Ethernet220 220,221 etp56a 56 50000 +Ethernet222 222,223 etp56b 56 50000 +Ethernet224 224,225 etp57a 57 50000 +Ethernet226 226,227 etp57b 57 50000 +Ethernet228 228,229 etp58a 58 50000 +Ethernet230 230,231 etp58b 58 50000 +Ethernet232 232,233 etp59a 59 50000 +Ethernet234 234,235 etp59b 59 50000 +Ethernet236 236,237 etp60a 60 50000 +Ethernet238 238,239 etp60b 60 50000 +Ethernet240 240,241 etp61a 61 50000 +Ethernet242 242,243 etp61b 61 50000 +Ethernet244 244,245 etp62a 62 50000 +Ethernet246 246,247 etp62b 62 50000 +Ethernet248 248,249 etp63a 63 50000 +Ethernet250 250,251 etp63b 63 50000 +Ethernet252 252,253 etp64a 64 50000 +Ethernet254 254,255 etp64b 64 50000 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_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..a72edb85633d --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800_112x50g_8x100g.xml @@ -0,0 +1,510 @@ + + + + + + 00:02:03:04:05:00 + + + 1 + + + 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 + + + + diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers.json.j2 new file mode 120000 index 000000000000..dc17caa0aa32 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers.json.j2 @@ -0,0 +1 @@ +../ACS-MSN3800/buffers.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..0ff424a30a57 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t0.j2 @@ -0,0 +1,104 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '24576000' %} +{% set ingress_lossless_pool_xoff = '2756608' %} +{% set egress_lossless_pool_size = '34287552' %} +{% set egress_lossy_pool_size = '24576000' %} + +{%- 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": { + {%- if dynamic_mode is not defined %} + "size": "{{ ingress_lossless_pool_size }}", + "xoff": "{{ ingress_lossless_pool_xoff }}", + {%- endif %} + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + {%- if dynamic_mode is not defined %} + "size": "{{ egress_lossy_pool_size }}", + {%- endif %} + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "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", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"9216", + "dynamic_th":"7" + }, + "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]" + }{% 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/Mellanox-SN3800-D24C52/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..49adf1331c1c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t1.j2 @@ -0,0 +1,104 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '22597632' %} +{% set ingress_lossless_pool_xoff = '4734976' %} +{% set egress_lossless_pool_size = '34287552' %} +{% set egress_lossy_pool_size = '22597632' %} + +{%- 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": { + {%- if dynamic_mode is not defined %} + "size": "{{ ingress_lossless_pool_size }}", + "xoff": "{{ ingress_lossless_pool_xoff }}", + {%- endif %} + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + {%- if dynamic_mode is not defined %} + "size": "{{ egress_lossy_pool_size }}", + {%- endif %} + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "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", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"9216", + "dynamic_th":"7" + }, + "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]" + }{% 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/Mellanox-SN3800-D24C52/buffers_dynamic.json.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_dynamic.json.j2 new file mode 120000 index 000000000000..8c4117c66214 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_dynamic.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_dynamic.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/hwsku.json b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/hwsku.json new file mode 100644 index 000000000000..1c76295f197d --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/hwsku.json @@ -0,0 +1,232 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet4": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet8": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet12": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet16": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet20": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet24": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet28": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet32": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet34": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet36": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet38": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet40": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet42": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet44": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet46": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet48": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet52": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet56": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet60": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet64": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet68": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet72": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet76": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet80": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet84": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet88": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet92": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet96": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet100": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet104": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet106": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet108": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet110": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet112": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet116": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet120": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet124": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet128": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet132": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet136": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet140": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet144": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet148": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet152": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet156": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet160": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet164": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet168": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet172": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet176": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet178": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet180": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet182": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet184": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet186": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet188": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet190": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet192": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet196": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet200": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet204": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet208": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet212": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet216": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet220": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet224": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet228": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet232": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet236": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet240": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet242": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet244": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet246": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet248": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet252": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/pg_profile_lookup.ini new file mode 120000 index 000000000000..ccbbfa44cd9c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/pg_profile_lookup.ini @@ -0,0 +1 @@ +../Mellanox-SN3800-D112C8/pg_profile_lookup.ini \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/port_config.ini b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/port_config.ini new file mode 100644 index 000000000000..87d4485963f7 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/port_config.ini @@ -0,0 +1,77 @@ +# name lanes alias index speed +Ethernet0 0,1,2,3 etp1 1 100000 +Ethernet4 4,5,6,7 etp2 2 100000 +Ethernet8 8,9,10,11 etp3 3 100000 +Ethernet12 12,13,14,15 etp4 4 100000 +Ethernet16 16,17,18,19 etp5 5 100000 +Ethernet20 20,21,22,23 etp6 6 100000 +Ethernet24 24,25,26,27 etp7 7 100000 +Ethernet28 28,29,30,31 etp8 8 100000 +Ethernet32 32,33 etp9a 9 50000 +Ethernet34 34,35 etp9b 9 50000 +Ethernet36 36,37 etp10a 10 50000 +Ethernet38 38,39 etp10b 10 50000 +Ethernet40 40,41 etp11a 11 50000 +Ethernet42 42,43 etp11b 11 50000 +Ethernet44 44,45 etp12a 12 50000 +Ethernet46 46,47 etp12b 12 50000 +Ethernet48 48,49,50,51 etp13 13 100000 +Ethernet52 52,53,54,55 etp14 14 100000 +Ethernet56 56,57,58,59 etp15 15 100000 +Ethernet60 60,61,62,63 etp16 16 100000 +Ethernet64 64,65,66,67 etp17 17 100000 +Ethernet68 68,69,70,71 etp18 18 100000 +Ethernet72 72,73,74,75 etp19 19 100000 +Ethernet76 76,77,78,79 etp20 20 100000 +Ethernet80 80,81,82,83 etp21 21 100000 +Ethernet84 84,85,86,87 etp22 22 100000 +Ethernet88 88,89,90,91 etp23 23 100000 +Ethernet92 92,93,94,95 etp24 24 100000 +Ethernet96 96,97,98,99 etp25 25 100000 +Ethernet100 100,101,102,103 etp26 26 100000 +Ethernet104 104,105 etp27a 27 50000 +Ethernet106 106,107 etp27b 27 50000 +Ethernet108 108,109 etp28a 28 50000 +Ethernet110 110,111 etp28b 28 50000 +Ethernet112 112,113,114,115 etp29 29 100000 +Ethernet116 116,117,118,119 etp30 30 100000 +Ethernet120 120,121,122,123 etp31 31 100000 +Ethernet124 124,125,126,127 etp32 32 100000 +Ethernet128 128,129,130,131 etp33 33 100000 +Ethernet132 132,133,134,135 etp34 34 100000 +Ethernet136 136,137,138,139 etp35 35 100000 +Ethernet140 140,141,142,143 etp36 36 100000 +Ethernet144 144,145,146,147 etp37 37 100000 +Ethernet148 148,149,150,151 etp38 38 100000 +Ethernet152 152,153,154,155 etp39 39 100000 +Ethernet156 156,157,158,159 etp40 40 100000 +Ethernet160 160,161,162,163 etp41 41 100000 +Ethernet164 164,165,166,167 etp42 42 100000 +Ethernet168 168,169,170,171 etp43 43 100000 +Ethernet172 172,173,174,175 etp44 44 100000 +Ethernet176 176,177 etp45a 45 50000 +Ethernet178 178,179 etp45b 45 50000 +Ethernet180 180,181 etp46a 46 50000 +Ethernet182 182,183 etp46b 46 50000 +Ethernet184 184,185 etp47a 47 50000 +Ethernet186 186,187 etp47b 47 50000 +Ethernet188 188,189 etp48a 48 50000 +Ethernet190 190,191 etp48b 48 50000 +Ethernet192 192,193,194,195 etp49 49 100000 +Ethernet196 196,197,198,199 etp50 50 100000 +Ethernet200 200,201,202,203 etp51 51 100000 +Ethernet204 204,205,206,207 etp52 52 100000 +Ethernet208 208,209,210,211 etp53 53 100000 +Ethernet212 212,213,214,215 etp54 54 100000 +Ethernet216 216,217,218,219 etp55 55 100000 +Ethernet220 220,221,222,223 etp56 56 100000 +Ethernet224 224,225,226,227 etp57 57 100000 +Ethernet228 228,229,230,231 etp58 58 100000 +Ethernet232 232,233,234,235 etp59 59 100000 +Ethernet236 236,237,238,239 etp60 60 100000 +Ethernet240 240,241 etp61a 61 50000 +Ethernet242 242,243 etp61b 61 50000 +Ethernet244 244,245 etp62a 62 50000 +Ethernet246 246,247 etp62b 62 50000 +Ethernet248 248,249,250,251 etp63 63 100000 +Ethernet252 252,253,254,255 etp64 64 100000 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/qos.json.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/qos.json.j2 new file mode 120000 index 000000000000..26b0dac51846 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/qos.json.j2 @@ -0,0 +1 @@ +../ACS-MSN3800/qos.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/sai.profile b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/sai.profile new file mode 100644 index 000000000000..7c632389b58c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/sai_3800_24x50g_52x100g.xml diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/sai_3800_24x50g_52x100g.xml b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/sai_3800_24x50g_52x100g.xml new file mode 100644 index 000000000000..1b3c77ce381c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/sai_3800_24x50g_52x100g.xml @@ -0,0 +1,470 @@ + + + + + + 00:02:03:04:05:00 + + + 1 + + + 64 + + + + + 1 + 4 + 48 + + + 3 + + + 1536 + + + 3 + 4 + 49 + 3 + 1536 + + + 5 + 4 + 50 + 3 + 1536 + + + 7 + 4 + 51 + 3 + 1536 + + + 9 + 4 + 52 + 3 + 1536 + + + 11 + 4 + 53 + 3 + 1536 + + + 13 + 4 + 54 + 3 + 1536 + + + 15 + 4 + 55 + 3 + 1536 + + + 17 + 4 + 56 + 3 + 1536 + + + 19 + 4 + 57 + 3 + 1536 + + + 21 + 4 + 58 + 3 + 1536 + + + 23 + 4 + 59 + 3 + 1536 + + + 25 + 4 + 60 + 3 + 1536 + + + 27 + 4 + 61 + 3 + 1536 + + + 29 + 4 + 62 + 3 + 1536 + + + 31 + 4 + 63 + 3 + 1536 + + + 33 + 4 + 12 + 3 + 1536 + + + 35 + 4 + 13 + 3 + 1536 + + + 37 + 4 + 14 + 3 + 1536 + + + 39 + 4 + 15 + 3 + 1536 + + + 41 + 4 + 8 + 3 + 1536 + + + 43 + 4 + 9 + 3 + 1536 + + + 45 + 4 + 10 + 3 + 1536 + + + 47 + 4 + 11 + 3 + 1536 + + + 49 + 4 + 4 + 3 + 1536 + + + 51 + 4 + 5 + 3 + 1536 + + + 53 + 4 + 6 + 3 + 1536 + + + 55 + 4 + 7 + 3 + 1536 + + + 57 + 4 + 0 + 3 + 1536 + + + 59 + 4 + 1 + 3 + 1536 + + + 61 + 4 + 2 + 3 + 1536 + + + 63 + 4 + 3 + 3 + 1536 + + + 65 + 4 + 44 + 3 + 1536 + + + 67 + 4 + 45 + 3 + 1536 + + + 69 + 4 + 46 + 3 + 1536 + + + 71 + 4 + 47 + 3 + 1536 + + + 73 + 4 + 40 + 3 + 1536 + + + 75 + 4 + 41 + 3 + 1536 + + + 77 + 4 + 42 + 3 + 1536 + + + 79 + 4 + 43 + 3 + 1536 + + + 81 + 4 + 36 + 3 + 1536 + + + 83 + 4 + 37 + 3 + 1536 + + + 85 + 4 + 38 + 3 + 1536 + + + 87 + 4 + 39 + 3 + 1536 + + + 89 + 4 + 32 + 3 + 1536 + + + 91 + 4 + 33 + 3 + 1536 + + + 93 + 4 + 34 + 3 + 1536 + + + 95 + 4 + 35 + 3 + 1536 + + + 97 + 4 + 16 + 3 + 1536 + + + 99 + 4 + 17 + 3 + 1536 + + + 101 + 4 + 18 + 3 + 1536 + + + 103 + 4 + 19 + 3 + 1536 + + + 105 + 4 + 20 + 3 + 1536 + + + 107 + 4 + 21 + 3 + 1536 + + + 109 + 4 + 22 + 3 + 1536 + + + 111 + 4 + 23 + 3 + 1536 + + + 113 + 4 + 24 + 3 + 1536 + + + 115 + 4 + 25 + 3 + 1536 + + + 117 + 4 + 26 + 3 + 1536 + + + 119 + 4 + 27 + 3 + 1536 + + + 121 + 4 + 28 + 3 + 1536 + + + 123 + 4 + 29 + 3 + 1536 + + + 125 + 4 + 30 + 3 + 1536 + + + 127 + 4 + 31 + 3 + 1536 + + + + diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers.json.j2 new file mode 120000 index 000000000000..dc17caa0aa32 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers.json.j2 @@ -0,0 +1 @@ +../ACS-MSN3800/buffers.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..c64f1c548631 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t0.j2 @@ -0,0 +1,104 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '24360960' %} +{% set ingress_lossless_pool_xoff = '2795520' %} +{% set egress_lossless_pool_size = '34287552' %} +{% set egress_lossy_pool_size = '24360960' %} + +{%- 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": { + {%- if dynamic_mode is not defined %} + "size": "{{ ingress_lossless_pool_size }}", + "xoff": "{{ ingress_lossless_pool_xoff }}", + {%- endif %} + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + {%- if dynamic_mode is not defined %} + "size": "{{ egress_lossy_pool_size }}", + {%- endif %} + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "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", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"9216", + "dynamic_th":"7" + }, + "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]" + }{% 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/Mellanox-SN3800-D28C50/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..bbb51cc778b2 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t1.j2 @@ -0,0 +1,104 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '22380544' %} +{% set ingress_lossless_pool_xoff = '4775936' %} +{% set egress_lossless_pool_size = '34287552' %} +{% set egress_lossy_pool_size = '22380544' %} + +{%- 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": { + {%- if dynamic_mode is not defined %} + "size": "{{ ingress_lossless_pool_size }}", + "xoff": "{{ ingress_lossless_pool_xoff }}", + {%- endif %} + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + {%- if dynamic_mode is not defined %} + "size": "{{ egress_lossy_pool_size }}", + {%- endif %} + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "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", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"9216", + "dynamic_th":"7" + }, + "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]" + }{% 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/Mellanox-SN3800-D28C50/buffers_dynamic.json.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_dynamic.json.j2 new file mode 120000 index 000000000000..8c4117c66214 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_dynamic.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_dynamic.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/hwsku.json b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/hwsku.json new file mode 100644 index 000000000000..fd7584babec5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/hwsku.json @@ -0,0 +1,238 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet4": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet8": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet12": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet16": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet20": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet24": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet28": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet32": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet34": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet36": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet38": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet40": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet42": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet44": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet46": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet48": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet52": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet56": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet60": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet64": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet68": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet72": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet76": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet80": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet84": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet88": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet92": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet96": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet100": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet104": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet106": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet108": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet110": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet112": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet116": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet120": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet124": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet128": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet132": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet136": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet140": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet144": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet148": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet152": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet156": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet160": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet164": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet168": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet172": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet176": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet178": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet180": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet182": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet184": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet186": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet188": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet190": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet192": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet196": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet200": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet204": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet208": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet212": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet216": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet220": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet224": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet228": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet232": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet236": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G]" + }, + "Ethernet240": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet242": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet244": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet246": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet248": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet250": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet252": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + }, + "Ethernet254": { + "default_brkout_mode": "2x50G[40G,25G,10G]" + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/pg_profile_lookup.ini new file mode 120000 index 000000000000..ccbbfa44cd9c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/pg_profile_lookup.ini @@ -0,0 +1 @@ +../Mellanox-SN3800-D112C8/pg_profile_lookup.ini \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/port_config.ini b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/port_config.ini new file mode 100644 index 000000000000..4c169a5fb48f --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/port_config.ini @@ -0,0 +1,79 @@ +# name lanes alias index speed +Ethernet0 0,1,2,3 etp1 1 100000 +Ethernet4 4,5,6,7 etp2 2 100000 +Ethernet8 8,9,10,11 etp3 3 100000 +Ethernet12 12,13,14,15 etp4 4 100000 +Ethernet16 16,17,18,19 etp5 5 100000 +Ethernet20 20,21,22,23 etp6 6 100000 +Ethernet24 24,25,26,27 etp7 7 100000 +Ethernet28 28,29,30,31 etp8 8 100000 +Ethernet32 32,33 etp9a 9 50000 +Ethernet34 34,35 etp9b 9 50000 +Ethernet36 36,37 etp10a 10 50000 +Ethernet38 38,39 etp10b 10 50000 +Ethernet40 40,41 etp11a 11 50000 +Ethernet42 42,43 etp11b 11 50000 +Ethernet44 44,45 etp12a 12 50000 +Ethernet46 46,47 etp12b 12 50000 +Ethernet48 48,49,50,51 etp13 13 100000 +Ethernet52 52,53,54,55 etp14 14 100000 +Ethernet56 56,57,58,59 etp15 15 100000 +Ethernet60 60,61,62,63 etp16 16 100000 +Ethernet64 64,65,66,67 etp17 17 100000 +Ethernet68 68,69,70,71 etp18 18 100000 +Ethernet72 72,73,74,75 etp19 19 100000 +Ethernet76 76,77,78,79 etp20 20 100000 +Ethernet80 80,81,82,83 etp21 21 100000 +Ethernet84 84,85,86,87 etp22 22 100000 +Ethernet88 88,89,90,91 etp23 23 100000 +Ethernet92 92,93,94,95 etp24 24 100000 +Ethernet96 96,97,98,99 etp25 25 100000 +Ethernet100 100,101,102,103 etp26 26 100000 +Ethernet104 104,105 etp27a 27 50000 +Ethernet106 106,107 etp27b 27 50000 +Ethernet108 108,109 etp28a 28 50000 +Ethernet110 110,111 etp28b 28 50000 +Ethernet112 112,113,114,115 etp29 29 100000 +Ethernet116 116,117,118,119 etp30 30 100000 +Ethernet120 120,121,122,123 etp31 31 100000 +Ethernet124 124,125,126,127 etp32 32 100000 +Ethernet128 128,129,130,131 etp33 33 100000 +Ethernet132 132,133,134,135 etp34 34 100000 +Ethernet136 136,137,138,139 etp35 35 100000 +Ethernet140 140,141,142,143 etp36 36 100000 +Ethernet144 144,145,146,147 etp37 37 100000 +Ethernet148 148,149,150,151 etp38 38 100000 +Ethernet152 152,153,154,155 etp39 38 100000 +Ethernet156 156,157,158,159 etp40 40 100000 +Ethernet160 160,161,162,163 etp41 41 100000 +Ethernet164 164,165,166,167 etp42 42 100000 +Ethernet168 168,169,170,171 etp43 43 100000 +Ethernet172 172,173,174,175 etp44 44 100000 +Ethernet176 176,177 etp45a 45 50000 +Ethernet178 178,179 etp45b 45 50000 +Ethernet180 180,181 etp46a 46 50000 +Ethernet182 182,183 etp46b 46 50000 +Ethernet184 184,185 etp47a 47 50000 +Ethernet186 186,187 etp47b 47 50000 +Ethernet188 188,189 etp48a 48 50000 +Ethernet190 190,191 etp48b 48 50000 +Ethernet192 192,193,194,195 etp49 49 100000 +Ethernet196 196,197,198,199 etp50 50 100000 +Ethernet200 200,201,202,203 etp51 51 100000 +Ethernet204 204,205,206,207 etp52 52 100000 +Ethernet208 208,209,210,211 etp53 53 100000 +Ethernet212 212,213,214,215 etp54 54 100000 +Ethernet216 216,217,218,219 etp55 55 100000 +Ethernet220 220,221,222,223 etp56 56 100000 +Ethernet224 224,225,226,227 etp57 57 100000 +Ethernet228 228,229,230,231 etp58 58 100000 +Ethernet232 232,233,234,235 etp59 59 100000 +Ethernet236 236,237,238,239 etp60 60 100000 +Ethernet240 240,241 etp61a 61 50000 +Ethernet242 242,243 etp61b 61 50000 +Ethernet244 244,245 etp62a 62 50000 +Ethernet246 246,247 etp62b 62 50000 +Ethernet248 248,249 etp63a 63 50000 +Ethernet250 250,251 etp63b 63 50000 +Ethernet252 252,253 etp64a 64 50000 +Ethernet254 254,255 etp64b 64 50000 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/qos.json.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/qos.json.j2 new file mode 120000 index 000000000000..26b0dac51846 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/qos.json.j2 @@ -0,0 +1 @@ +../ACS-MSN3800/qos.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/sai.profile b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/sai.profile new file mode 100644 index 000000000000..aa37fb30dbd0 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/sai_3800_28x50g_52x100g.xml diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/sai_3800_28x50g_52x100g.xml b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/sai_3800_28x50g_52x100g.xml new file mode 100644 index 000000000000..1b3c77ce381c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/sai_3800_28x50g_52x100g.xml @@ -0,0 +1,470 @@ + + + + + + 00:02:03:04:05:00 + + + 1 + + + 64 + + + + + 1 + 4 + 48 + + + 3 + + + 1536 + + + 3 + 4 + 49 + 3 + 1536 + + + 5 + 4 + 50 + 3 + 1536 + + + 7 + 4 + 51 + 3 + 1536 + + + 9 + 4 + 52 + 3 + 1536 + + + 11 + 4 + 53 + 3 + 1536 + + + 13 + 4 + 54 + 3 + 1536 + + + 15 + 4 + 55 + 3 + 1536 + + + 17 + 4 + 56 + 3 + 1536 + + + 19 + 4 + 57 + 3 + 1536 + + + 21 + 4 + 58 + 3 + 1536 + + + 23 + 4 + 59 + 3 + 1536 + + + 25 + 4 + 60 + 3 + 1536 + + + 27 + 4 + 61 + 3 + 1536 + + + 29 + 4 + 62 + 3 + 1536 + + + 31 + 4 + 63 + 3 + 1536 + + + 33 + 4 + 12 + 3 + 1536 + + + 35 + 4 + 13 + 3 + 1536 + + + 37 + 4 + 14 + 3 + 1536 + + + 39 + 4 + 15 + 3 + 1536 + + + 41 + 4 + 8 + 3 + 1536 + + + 43 + 4 + 9 + 3 + 1536 + + + 45 + 4 + 10 + 3 + 1536 + + + 47 + 4 + 11 + 3 + 1536 + + + 49 + 4 + 4 + 3 + 1536 + + + 51 + 4 + 5 + 3 + 1536 + + + 53 + 4 + 6 + 3 + 1536 + + + 55 + 4 + 7 + 3 + 1536 + + + 57 + 4 + 0 + 3 + 1536 + + + 59 + 4 + 1 + 3 + 1536 + + + 61 + 4 + 2 + 3 + 1536 + + + 63 + 4 + 3 + 3 + 1536 + + + 65 + 4 + 44 + 3 + 1536 + + + 67 + 4 + 45 + 3 + 1536 + + + 69 + 4 + 46 + 3 + 1536 + + + 71 + 4 + 47 + 3 + 1536 + + + 73 + 4 + 40 + 3 + 1536 + + + 75 + 4 + 41 + 3 + 1536 + + + 77 + 4 + 42 + 3 + 1536 + + + 79 + 4 + 43 + 3 + 1536 + + + 81 + 4 + 36 + 3 + 1536 + + + 83 + 4 + 37 + 3 + 1536 + + + 85 + 4 + 38 + 3 + 1536 + + + 87 + 4 + 39 + 3 + 1536 + + + 89 + 4 + 32 + 3 + 1536 + + + 91 + 4 + 33 + 3 + 1536 + + + 93 + 4 + 34 + 3 + 1536 + + + 95 + 4 + 35 + 3 + 1536 + + + 97 + 4 + 16 + 3 + 1536 + + + 99 + 4 + 17 + 3 + 1536 + + + 101 + 4 + 18 + 3 + 1536 + + + 103 + 4 + 19 + 3 + 1536 + + + 105 + 4 + 20 + 3 + 1536 + + + 107 + 4 + 21 + 3 + 1536 + + + 109 + 4 + 22 + 3 + 1536 + + + 111 + 4 + 23 + 3 + 1536 + + + 113 + 4 + 24 + 3 + 1536 + + + 115 + 4 + 25 + 3 + 1536 + + + 117 + 4 + 26 + 3 + 1536 + + + 119 + 4 + 27 + 3 + 1536 + + + 121 + 4 + 28 + 3 + 1536 + + + 123 + 4 + 29 + 3 + 1536 + + + 125 + 4 + 30 + 3 + 1536 + + + 127 + 4 + 31 + 3 + 1536 + + + + diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/pcie.yaml b/device/mellanox/x86_64-mlnx_msn3800-r0/pcie.yaml new file mode 120000 index 000000000000..d4a25d40bd54 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/pcie.yaml @@ -0,0 +1 @@ +../x86_64-mlnx_msn3700-r0/pcie.yaml \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/platform.json b/device/mellanox/x86_64-mlnx_msn3800-r0/platform.json new file mode 100644 index 000000000000..eff763be7d75 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/platform.json @@ -0,0 +1,388 @@ +{ + "interfaces": { + "Ethernet0": { + "index": "1,1,1,1", + "lanes": "0,1,2,3", + "alias_at_lanes": "etp1a, etp1b, etp1c, etp1d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet4": { + "index": "2,2,2,2", + "lanes": "4,5,6,7", + "alias_at_lanes": "etp2a, etp2b, etp2c, etp2d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet8": { + "index": "3,3,3,3", + "lanes": "8,9,10,11", + "alias_at_lanes": "etp3a, etp3b, etp3c, etp3d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet12": { + "index": "4,4,4,4", + "lanes": "12,13,14,15", + "alias_at_lanes": "etp4a, etp4b, etp4c, etp4d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet16": { + "index": "5,5,5,5", + "lanes": "16,17,18,19", + "alias_at_lanes": "etp5a, etp5b, etp5c, etp5d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet20": { + "index": "6,6,6,6", + "lanes": "20,21,22,23", + "alias_at_lanes": "etp6a, etp6b, etp6c, etp6d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet24": { + "index": "7,7,7,7", + "lanes": "24,25,26,27", + "alias_at_lanes": "etp7a, etp7b, etp7c, etp7d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet28": { + "index": "8,8,8,8", + "lanes": "28,29,30,31", + "alias_at_lanes": "etp8a, etp8b, etp8c, etp8d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet32": { + "index": "9,9,9,9", + "lanes": "32,33,34,35", + "alias_at_lanes": "etp9a, etp9b, etp9c, etp9d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet36": { + "index": "10,10,10,10", + "lanes": "36,37,38,39", + "alias_at_lanes": "etp10a, etp10b, etp10c, etp10d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet40": { + "index": "11,11,11,11", + "lanes": "40,41,42,43", + "alias_at_lanes": "etp11a, etp11b, etp11c, etp11d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet44": { + "index": "12,12,12,12", + "lanes": "44,45,46,47", + "alias_at_lanes": "etp12a, etp12b, etp12c, etp12d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet48": { + "index": "13,13,13,13", + "lanes": "48,49,50,51", + "alias_at_lanes": "etp13a, etp13b, etp13c, etp13d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet52": { + "index": "14,14,14,14", + "lanes": "52,53,54,55", + "alias_at_lanes": "etp14a, etp14b, etp14c, etp14d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet56": { + "index": "15,15,15,15", + "lanes": "56,57,58,59", + "alias_at_lanes": "etp15a, etp15b, etp15c, etp15d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet60": { + "index": "16,16,16,16", + "lanes": "60,61,62,63", + "alias_at_lanes": "etp16a, etp16b, etp16c, etp16d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet64": { + "index": "17,17,17,17", + "lanes": "64,65,66,67", + "alias_at_lanes": "etp17a, etp17b, etp17c, etp17d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet68": { + "index": "18,18,18,18", + "lanes": "68,69,70,71", + "alias_at_lanes": "etp18a, etp18b, etp18c, etp18d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet72": { + "index": "19,19,19,19", + "lanes": "72,73,74,75", + "alias_at_lanes": "etp19a, etp19b, etp19c, etp19d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet76": { + "index": "20,20,20,20", + "lanes": "76,77,78,79", + "alias_at_lanes": "etp20a, etp20b, etp20c, etp20d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet80": { + "index": "21,21,21,21", + "lanes": "80,81,82,83", + "alias_at_lanes": "etp21a, etp21b, etp21c, etp21d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet84": { + "index": "22,22,22,22", + "lanes": "84,85,86,87", + "alias_at_lanes": "etp22a, etp22b, etp22c, etp22d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet88": { + "index": "23,23,23,23", + "lanes": "88,89,90,91", + "alias_at_lanes": "etp23a, etp23b, etp23c, etp23d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet92": { + "index": "24,24,24,24", + "lanes": "92,93,94,95", + "alias_at_lanes": "etp24a, etp24b, etp24c, etp24d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet96": { + "index": "25,25,25,25", + "lanes": "96,97,98,99", + "alias_at_lanes": "etp25a, etp25b, etp25c, etp25d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet100": { + "index": "26,26,26,26", + "lanes": "100,101,102,103", + "alias_at_lanes": "etp26a, etp26b, etp26c, etp26d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet104": { + "index": "27,27,27,27", + "lanes": "104,105,106,107", + "alias_at_lanes": "etp27a, etp27b, etp27c, etp27d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet108": { + "index": "28,28,28,28", + "lanes": "108,109,110,111", + "alias_at_lanes": "etp28a, etp28b, etp28c, etp28d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet112": { + "index": "29,29,29,29", + "lanes": "112,113,114,115", + "alias_at_lanes": "etp29a, etp29b, etp29c, etp29d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet116": { + "index": "30,30,30,30", + "lanes": "116,117,118,119", + "alias_at_lanes": "etp30a, etp30b, etp30c, etp30d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet120": { + "index": "31,31,31,31", + "lanes": "120,121,122,123", + "alias_at_lanes": "etp31a, etp31b, etp31c, etp31d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet124": { + "index": "32,32,32,32", + "lanes": "124,125,126,127", + "alias_at_lanes": "etp32a, etp32b, etp32c, etp32d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet128": { + "index": "33,33,33,33", + "lanes": "128,129,130,131", + "alias_at_lanes": "etp33a, etp33b, etp33c, etp33d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet132": { + "index": "34,34,34,34", + "lanes": "132,133,134,135", + "alias_at_lanes": "etp34a, etp34b, etp34c, etp34d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet136": { + "index": "35,35,35,35", + "lanes": "136,137,138,139", + "alias_at_lanes": "etp35a, etp35b, etp35c, etp35d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet140": { + "index": "36,36,36,36", + "lanes": "140,141,142,143", + "alias_at_lanes": "etp36a, etp36b, etp36c, etp36d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet144": { + "index": "37,37,37,37", + "lanes": "144,145,146,147", + "alias_at_lanes": "etp37a, etp37b, etp37c, etp37d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet148": { + "index": "38,38,38,38", + "lanes": "148,149,150,151", + "alias_at_lanes": "etp38a, etp38b, etp38c, etp38d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet152": { + "index": "39,39,39,39", + "lanes": "152,153,154,155", + "alias_at_lanes": "etp39a, etp39b, etp39c, etp39d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet156": { + "index": "40,40,40,40", + "lanes": "156,157,158,159", + "alias_at_lanes": "etp40a, etp40b, etp40c, etp40d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet160": { + "index": "41,41,41,41", + "lanes": "160,161,162,163", + "alias_at_lanes": "etp41a, etp41b, etp41c, etp41d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet164": { + "index": "42,42,42,42", + "lanes": "164,165,166,167", + "alias_at_lanes": "etp42a, etp42b, etp42c, etp42d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet168": { + "index": "43,43,43,43", + "lanes": "168,169,170,171", + "alias_at_lanes": "etp43a, etp43b, etp43c, etp43d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet172": { + "index": "44,44,44,44", + "lanes": "172,173,174,175", + "alias_at_lanes": "etp44a, etp44b, etp44c, etp44d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet176": { + "index": "45,45,45,45", + "lanes": "176,177,178,179", + "alias_at_lanes": "etp45a, etp45b, etp45c, etp45d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet180": { + "index": "46,46,46,46", + "lanes": "180,181,182,183", + "alias_at_lanes": "etp46a, etp46b, etp46c, etp46d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet184": { + "index": "47,47,47,47", + "lanes": "184,185,186,187", + "alias_at_lanes": "etp47a, etp47b, etp47c, etp47d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet188": { + "index": "48,48,48,48", + "lanes": "188,189,190,191", + "alias_at_lanes": "etp48a, etp48b, etp48c, etp48d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet192": { + "index": "49,49,49,49", + "lanes": "192,193,194,195", + "alias_at_lanes": "etp49a, etp49b, etp49c, etp49d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet196": { + "index": "50,50,50,50", + "lanes": "196,197,198,199", + "alias_at_lanes": "etp50a, etp50b, etp50c, etp50d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet200": { + "index": "51,51,51,51", + "lanes": "200,201,202,203", + "alias_at_lanes": "etp51a, etp51b, etp51c, etp51d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet204": { + "index": "52,52,52,52", + "lanes": "204,205,206,207", + "alias_at_lanes": "etp52a, etp52b, etp52c, etp52d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet208": { + "index": "53,53,53,53", + "lanes": "208,209,210,211", + "alias_at_lanes": "etp53a, etp53b, etp53c, etp53d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet212": { + "index": "54,54,54,54", + "lanes": "212,213,214,215", + "alias_at_lanes": "etp54a, etp54b, etp54c, etp54d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet216": { + "index": "55,55,55,55", + "lanes": "216,217,218,219", + "alias_at_lanes": "etp55a, etp55b, etp55c, etp55d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet220": { + "index": "56,56,56,56", + "lanes": "220,221,222,223", + "alias_at_lanes": "etp56a, etp56b, etp56c, etp56d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet224": { + "index": "57,57,57,57", + "lanes": "224,225,226,227", + "alias_at_lanes": "etp57a, etp57b, etp57c, etp57d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet228": { + "index": "58,58,58,58", + "lanes": "228,229,230,231", + "alias_at_lanes": "etp58a, etp58b, etp58c, etp58d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet232": { + "index": "59,59,59,59", + "lanes": "232,233,234,235", + "alias_at_lanes": "etp59a, etp59b, etp59c, etp59d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet236": { + "index": "60,60,60,60", + "lanes": "236,237,238,239", + "alias_at_lanes": "etp60a, etp60b, etp60c, etp60d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet240": { + "index": "61,61,61,61", + "lanes": "240,241,242,243", + "alias_at_lanes": "etp61a, etp61b, etp61c, etp61d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet244": { + "index": "62,62,62,62", + "lanes": "244,245,246,247", + "alias_at_lanes": "etp62a, etp62b, etp62c, etp62d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet248": { + "index": "63,63,63,63", + "lanes": "248,249,250,251", + "alias_at_lanes": "etp63a, etp63b, etp63c, etp63d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + }, + "Ethernet252": { + "index": "64,64,64,64", + "lanes": "252,253,254,255", + "alias_at_lanes": "etp64a, etp64b, etp64c, etp64d", + "breakout_modes": "1x100G[50G,40G,25G,10G],2x50G[40G,25G,10G]" + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn3800-r0/platform_components.json index fa3b172b763e..deddbcc04158 100644 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/platform_components.json +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/platform_components.json @@ -1,9 +1,14 @@ { "chassis": { - "x86_64-mlnx_msn3800-r0": { + "MSN3800": { "component": { + "ONIE": { }, + "SSD": { }, "BIOS": { }, - "CPLD": { } + "CPLD1": { }, + "CPLD2": { }, + "CPLD3": { }, + "CPLD4": { } } } } diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/port_peripheral_config.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/port_peripheral_config.j2 new file mode 100644 index 000000000000..1cad105ed1ee --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/port_peripheral_config.j2 @@ -0,0 +1,10 @@ +[ + {%- include 'peripheral_table.j2' %} + , + { + "PORT_PERIPHERAL_TABLE:global": { + "gearbox_model": "MELLANOX-GEARBOX-3800" + }, + "OP": "SET" + } +] diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn3800-r0/sensors.conf index fab58890adfb..9777c5e84398 100644 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/sensors.conf +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/sensors.conf @@ -22,9 +22,10 @@ bus "i2c-15" "i2c-1-mux (chan_id 6)" # Power controllers bus "i2c-5" "i2c-1-mux (chan_id 4)" chip "tps53679-i2c-*-70" - label in1 "PMIC-1 PSU 12V Rail (in)" - label in2 "PMIC-1 ASIC 0.8V VCORE Rail (out)" - label in3 "PMIC-1 ASIC 1.2V Rail (out)" + label in1 "PMIC-1 PSU 12V Rail (in1)" + label in2 "PMIC-1 PSU 12V Rail (in2)" + label in3 "PMIC-1 ASIC 0.8V VCORE Rail (out)" + label in4 "PMIC-1 ASIC 1.2V Rail (out)" label temp1 "PMIC-1 Temp 1" label temp2 "PMIC-1 Temp 2" label power1 "PMIC-1 ASIC 0.8V VCORE Rail Pwr (out)" @@ -32,9 +33,10 @@ bus "i2c-5" "i2c-1-mux (chan_id 4)" label curr1 "PMIC-1 ASIC 0.8V VCORE Rail Curr (out)" label curr2 "PMIC-1 ASIC 1.2V Rail Curr (out)" chip "tps53679-i2c-*-71" - label in1 "PMIC-2 PSU 12V Rail (in)" - label in2 "PMIC-2 GB 0.8V Rail (out)" - label in3 "PMIC-2 GB 1.125V Rail (out)" + label in1 "PMIC-2 PSU 12V Rail (in1)" + label in2 "PMIC-2 PSU 12V Rail (in2)" + label in3 "PMIC-2 GB 0.8V Rail (out)" + label in4 "PMIC-2 GB 1.125V Rail (out)" label temp1 "PMIC-2 Temp 1" label temp2 "PMIC-2 Temp 2" label power1 "PMIC-2 GB 0.8V Rail Pwr (out)" @@ -42,9 +44,10 @@ bus "i2c-5" "i2c-1-mux (chan_id 4)" label curr1 "PMIC-2 GB 0.8V Rail Curr (out)" label curr2 "PMIC-2 GB 1.125V Rail Curr (out)" chip "tps53679-i2c-*-72" - label in1 "PMIC-3 PSU 12V Rail (in)" - label in2 "PMIC-3 ASIC 1.8V Rail (out)" - ignore in3 + label in1 "PMIC-3 PSU 12V Rail (in1)" + label in2 "PMIC-3 PSU 12V Rail (in2)" + label in3 "PMIC-3 ASIC 1.8V Rail (out)" + ignore in4 label temp1 "PMIC-3 Temp 1" label temp2 "PMIC-3 Temp 2" label power1 "PMIC-3 ASIC 1.8V Rail Pwr (out)" @@ -52,9 +55,10 @@ bus "i2c-5" "i2c-1-mux (chan_id 4)" label curr1 "PMIC-3 ASIC 1.8V Rail Curr (out)" ignore curr2 chip "tps53679-i2c-*-73" - label in1 "PMIC-4 PSU 12V Rail (in)" - label in2 "PMIC-4 GB 0.8V Rail (out)" - label in3 "PMIC-4 GB 1.125V Rail (out)" + label in1 "PMIC-4 PSU 12V Rail (in1)" + label in2 "PMIC-4 PSU 12V Rail (in2)" + label in3 "PMIC-4 GB 0.8V Rail (out)" + label in4 "PMIC-4 GB 1.125V Rail (out)" label temp1 "PMIC-4 Temp 1" label temp2 "PMIC-4 Temp 2" label power1 "PMIC-4 GB 0.8V Rail Pwr (out)" @@ -64,9 +68,10 @@ bus "i2c-5" "i2c-1-mux (chan_id 4)" bus "i2c-15" "i2c-1-mux (chan_id 6)" chip "tps53679-i2c-*-58" - label in1 "PMIC-5 PSU 12V Rail (in)" - label in2 "PMIC-5 COMEX 1.8V Rail (out)" - label in3 "PMIC-5 COMEX 1.05V Rail (out)" + label in1 "PMIC-5 PSU 12V Rail (in1)" + label in2 "PMIC-5 PSU 12V Rail (in2)" + label in3 "PMIC-5 COMEX 1.8V Rail (out)" + label in4 "PMIC-5 COMEX 1.05V Rail (out)" label temp1 "PMIC-5 Temp 1" label temp2 "PMIC-5 Temp 2" label power1 "PMIC-5 COMEX 1.8V Rail Pwr (out)" @@ -74,9 +79,10 @@ bus "i2c-15" "i2c-1-mux (chan_id 6)" label curr1 "PMIC-5 COMEX 1.8V Rail Curr (out)" label curr2 "PMIC-5 COMEX 1.05V Rail Curr (out)" chip "tps53679-i2c-*-61" - label in1 "PMIC-6 PSU 12V Rail (in)" - label in2 "PMIC-6 COMEX 1.2V Rail (out)" - ignore in3 + label in1 "PMIC-6 PSU 12V Rail (in1)" + label in2 "PMIC-6 PSU 12V Rail (in2)" + label in3 "PMIC-6 COMEX 1.2V Rail (out)" + ignore in4 label temp1 "PMIC-6 Temp 1" label temp2 "PMIC-6 Temp 2" label power1 "PMIC-6 COMEX 1.2V Rail Pwr (out)" diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_msn3800-r0/system_health_monitoring_config.json new file mode 120000 index 000000000000..98df66c27ca5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4410-r0/ACS-MSN4410/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn4410-r0/ACS-MSN4410/buffers.json.j2 new file mode 120000 index 000000000000..add8bf8bb7c2 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4410-r0/ACS-MSN4410/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_msn4410-r0/ACS-MSN4410/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn4410-r0/ACS-MSN4410/buffers_defaults_t0.j2 new file mode 120000 index 000000000000..ddb883a1daa4 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4410-r0/ACS-MSN4410/buffers_defaults_t0.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_defaults_t0.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4410-r0/ACS-MSN4410/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn4410-r0/ACS-MSN4410/buffers_defaults_t1.j2 new file mode 120000 index 000000000000..f8bbb6e631e7 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4410-r0/ACS-MSN4410/buffers_defaults_t1.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_defaults_t1.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4410-r0/ACS-MSN4410/hwsku.json b/device/mellanox/x86_64-mlnx_msn4410-r0/ACS-MSN4410/hwsku.json new file mode 100644 index 000000000000..f170ecd32b98 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4410-r0/ACS-MSN4410/hwsku.json @@ -0,0 +1,100 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet8": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet16": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet24": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet32": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet40": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet48": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet56": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet64": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet72": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet80": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet88": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet96": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet104": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet112": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet120": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet128": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet136": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet144": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet152": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet160": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet168": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet176": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet184": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet192": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet200": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet208": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet216": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet224": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet232": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet240": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet248": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn4410-r0/ACS-MSN4410/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn4410-r0/ACS-MSN4410/pg_profile_lookup.ini new file mode 120000 index 000000000000..88e51ceae044 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4410-r0/ACS-MSN4410/pg_profile_lookup.ini @@ -0,0 +1 @@ +../../x86_64-mlnx_msn4700-r0/ACS-MSN4700/pg_profile_lookup.ini \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4410-r0/ACS-MSN4410/port_config.ini b/device/mellanox/x86_64-mlnx_msn4410-r0/ACS-MSN4410/port_config.ini new file mode 100644 index 000000000000..5b76c3a59d40 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4410-r0/ACS-MSN4410/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias index +Ethernet0 0,1,2,3 etp1 1 +Ethernet8 8,9,10,11 etp2 2 +Ethernet16 16,17,18,19 etp3 3 +Ethernet24 24,25,26,27 etp4 4 +Ethernet32 32,33,34,35 etp5 5 +Ethernet40 40,41,42,43 etp6 6 +Ethernet48 48,49,50,51 etp7 7 +Ethernet56 56,57,58,59 etp8 8 +Ethernet64 64,65,66,67 etp9 9 +Ethernet72 72,73,74,75 etp10 10 +Ethernet80 80,81,82,83 etp11 11 +Ethernet88 88,89,90,91 etp12 12 +Ethernet96 96,97,98,99 etp13 13 +Ethernet104 104,105,106,107 etp14 14 +Ethernet112 112,113,114,115 etp15 15 +Ethernet120 120,121,122,123 etp16 16 +Ethernet128 128,129,130,131 etp17 17 +Ethernet136 136,137,138,139 etp18 18 +Ethernet144 144,145,146,147 etp19 19 +Ethernet152 152,153,154,155 etp20 20 +Ethernet160 160,161,162,163 etp21 21 +Ethernet168 168,169,170,171 etp22 22 +Ethernet176 176,177,178,179 etp23 23 +Ethernet184 184,185,186,187 etp24 24 +Ethernet192 192,193,194,195,196,197,198,199 etp25 25 +Ethernet200 200,201,202,203,204,205,206,207 etp26 26 +Ethernet208 208,209,210,211,212,213,214,215 etp27 27 +Ethernet216 216,217,218,219,220,221,222,223 etp28 28 +Ethernet224 224,225,226,227,228,229,230,231 etp29 29 +Ethernet232 232,233,234,235,236,237,238,239 etp30 30 +Ethernet240 240,241,242,243,244,245,246,247 etp31 31 +Ethernet248 248,249,250,251,252,253,254,255 etp32 32 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4410-r0/ACS-MSN4410/qos.json.j2 b/device/mellanox/x86_64-mlnx_msn4410-r0/ACS-MSN4410/qos.json.j2 new file mode 120000 index 000000000000..eccf286dc879 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4410-r0/ACS-MSN4410/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_msn4410-r0/ACS-MSN4410/sai.profile b/device/mellanox/x86_64-mlnx_msn4410-r0/ACS-MSN4410/sai.profile new file mode 100644 index 000000000000..be729cb4e06a --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4410-r0/ACS-MSN4410/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/sai_4410.xml diff --git a/device/mellanox/x86_64-mlnx_msn4410-r0/ACS-MSN4410/sai_4410.xml b/device/mellanox/x86_64-mlnx_msn4410-r0/ACS-MSN4410/sai_4410.xml new file mode 100644 index 000000000000..5e5b01cad626 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4410-r0/ACS-MSN4410/sai_4410.xml @@ -0,0 +1,247 @@ + + + + + + 00:02:03:04:05:00 + + + 1 + + + 32 + + + + + 1 + 8 + 17 + 3 + 1536 + + + 5 + 8 + 16 + 3 + 1536 + + + 9 + 8 + 19 + 3 + 1536 + + + 13 + 8 + 18 + 3 + 1536 + + + 17 + 8 + 21 + 3 + 1536 + + + 21 + 8 + 20 + 3 + 1536 + + + 25 + 8 + 23 + 3 + 1536 + + + 29 + 8 + 22 + 3 + 1536 + + + 33 + 8 + 29 + 3 + 1536 + + + 37 + 8 + 28 + 3 + 1536 + + + 41 + 8 + 31 + 3 + 1536 + + + 45 + 8 + 30 + 3 + 1536 + + + 49 + 8 + 25 + 3 + 1536 + + + 53 + 8 + 24 + 3 + 1536 + + + 57 + 8 + 27 + 3 + 1536 + + + 61 + 8 + 26 + 3 + 1536 + + + 65 + 8 + 14 + 3 + 1536 + + + 69 + 8 + 15 + 3 + 1536 + + + 73 + 8 + 12 + 3 + 1536 + + + 77 + 8 + 13 + 3 + 1536 + + + 81 + 8 + 10 + 3 + 1536 + + + 85 + 8 + 11 + 3 + 1536 + + + 89 + 8 + 8 + 3 + 1536 + + + 93 + 8 + 9 + 3 + 1536 + + + 97 + 8 + 2 + 3 + 1536 + + + 101 + 8 + 3 + 3 + 1536 + + + 105 + 8 + 0 + + + 3 + + + 1536 + + + 109 + 8 + 1 + 3 + 1536 + + + 113 + 8 + 6 + 3 + 1536 + + + 117 + 8 + 7 + 3 + 1536 + + + 121 + 8 + 4 + 3 + 1536 + + + 125 + 8 + 5 + 3 + 1536 + + + + + diff --git a/device/mellanox/x86_64-mlnx_msn4410-r0/default_sku b/device/mellanox/x86_64-mlnx_msn4410-r0/default_sku new file mode 100644 index 000000000000..d175094cfe24 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4410-r0/default_sku @@ -0,0 +1 @@ +ACS-MSN4410 t1 diff --git a/device/mellanox/x86_64-mlnx_msn4410-r0/pcie.yaml b/device/mellanox/x86_64-mlnx_msn4410-r0/pcie.yaml new file mode 120000 index 000000000000..187649f4b860 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4410-r0/pcie.yaml @@ -0,0 +1 @@ +../x86_64-mlnx_msn4600c-r0/pcie.yaml \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4410-r0/platform.json b/device/mellanox/x86_64-mlnx_msn4410-r0/platform.json new file mode 100644 index 000000000000..01ad8221815b --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4410-r0/platform.json @@ -0,0 +1,196 @@ +{ + "interfaces": { + "Ethernet0": { + "index": "1,1,1,1", + "lanes": "0,1,2,3", + "alias_at_lanes": "etp1a, etp1b, etp1c, etp1d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet8": { + "index": "2,2,2,2", + "lanes": "8,9,10,11", + "alias_at_lanes": "etp2a, etp2b, etp2c, etp2d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet16": { + "index": "3,3,3,3", + "lanes": "16,17,18,19", + "alias_at_lanes": "etp3a, etp3b, etp3c, etp3d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet24": { + "index": "4,4,4,4", + "lanes": "24,25,26,27", + "alias_at_lanes": "etp4a, etp4b, etp4c, etp4d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet32": { + "index": "5,5,5,5", + "lanes": "32,33,34,35", + "alias_at_lanes": "etp5a, etp5b, etp5c, etp5d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet40": { + "index": "6,6,6,6", + "lanes": "40,41,42,43", + "alias_at_lanes": "etp6a, etp6b, etp6c, etp6d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet48": { + "index": "7,7,7,7", + "lanes": "48,49,50,51", + "alias_at_lanes": "etp7a, etp7b, etp7c, etp7d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet56": { + "index": "8,8,8,8", + "lanes": "56,57,58,59", + "alias_at_lanes": "etp8a, etp8b, etp8c, etp8d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet64": { + "index": "9,9,9,9", + "lanes": "64,65,66,67", + "alias_at_lanes": "etp9a, etp9b, etp9c, etp9d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet72": { + "index": "10,10,10,10", + "lanes": "72,73,74,75", + "alias_at_lanes": "etp10a, etp10b, etp10c, etp10d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet80": { + "index": "11,11,11,11", + "lanes": "80,81,82,83", + "alias_at_lanes": "etp11a, etp11b, etp11c, etp11d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet88": { + "index": "12,12,12,12", + "lanes": "88,89,90,91", + "alias_at_lanes": "etp12a, etp12b, etp12c, etp12d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet96": { + "index": "13,13,13,13", + "lanes": "96,97,98,99", + "alias_at_lanes": "etp13a, etp13b, etp13c, etp13d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet104": { + "index": "14,14,14,14", + "lanes": "104,105,106,107", + "alias_at_lanes": "etp14a, etp14b, etp14c, etp14d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet112": { + "index": "15,15,15,15", + "lanes": "112,113,114,115", + "alias_at_lanes": "etp15a, etp15b, etp15c, etp15d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet120": { + "index": "16,16,16,16", + "lanes": "120,121,122,123", + "alias_at_lanes": "etp16a, etp16b, etp16c, etp16d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet128": { + "index": "17,17,17,17", + "lanes": "128,129,130,131", + "alias_at_lanes": "etp17a, etp17b, etp17c, etp17d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet136": { + "index": "18,18,18,18", + "lanes": "136,137,138,139", + "alias_at_lanes": "etp18a, etp18b, etp18c, etp18d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet144": { + "index": "19,19,19,19", + "lanes": "144,145,146,147", + "alias_at_lanes": "etp19a, etp19b, etp19c, etp19d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet152": { + "index": "20,20,20,20", + "lanes": "152,153,154,155", + "alias_at_lanes": "etp20a, etp20b, etp20c, etp20d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet160": { + "index": "21,21,21,21", + "lanes": "160,161,162,163", + "alias_at_lanes": "etp21a, etp21b, etp21c, etp21d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet168": { + "index": "22,22,22,22", + "lanes": "168,169,170,171", + "alias_at_lanes": "etp22a, etp22b, etp22c, etp22d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet176": { + "index": "23,23,23,23", + "lanes": "176,177,178,179", + "alias_at_lanes": "etp23a, etp23b, etp23c, etp23d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet184": { + "index": "24,24,24,24", + "lanes": "184,185,186,187", + "alias_at_lanes": "etp24a, etp24b, etp24c, etp24d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G],4x25G[10G,1G]" + }, + "Ethernet192": { + "index": "25,25,25,25,25,25,25,25", + "lanes": "192,193,194,195,196,197,198,199", + "alias_at_lanes": "etp25a, etp25b, etp25c, etp25d, etp25e, etp25f, etp25g, etp25h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet200": { + "index": "26,26,26,26,26,26,26,26", + "lanes": "200,201,202,203,204,205,206,207", + "alias_at_lanes": "etp26a, etp26b, etp26c, etp26d, etp26e, etp26f, etp26g, etp26h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet208": { + "index": "27,27,27,27,27,27,27,27", + "lanes": "208,209,210,211,212,213,214,215", + "alias_at_lanes": "etp27a, etp27b, etp27c, etp27d, etp27e, etp27f, etp27g, etp27h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet216": { + "index": "28,28,28,28,28,28,28,28", + "lanes": "216,217,218,219,220,221,222,223", + "alias_at_lanes": "etp28a, etp28b, etp28c, etp28d, etp28e, etp28f, etp28g, etp28h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet224": { + "index": "29,29,29,29,29,29,29,29", + "lanes": "224,225,226,227,228,229,230,231", + "alias_at_lanes": "etp29a, etp29b, etp29c, etp29d, etp29e, etp29f, etp29g, etp29h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet232": { + "index": "30,30,30,30,30,30,30,30", + "lanes": "232,233,234,235,236,237,238,239", + "alias_at_lanes": "etp30a, etp30b, etp30c, etp30d, etp30e, etp30f, etp30g, etp30h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet240": { + "index": "31,31,31,31,31,31,31,31", + "lanes": "240,241,242,243,244,245,246,247", + "alias_at_lanes": "etp31a, etp31b, etp31c, etp31d, etp31e, etp31f, etp31g, etp31h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet248": { + "index": "32,32,32,32,32,32,32,32", + "lanes": "248,249,250,251,252,253,254,255", + "alias_at_lanes": "etp32a, etp32b, etp32c, etp32d, etp32e, etp32f, etp32g, etp32h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn4410-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn4410-r0/platform_components.json new file mode 100644 index 000000000000..bb1afce80161 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4410-r0/platform_components.json @@ -0,0 +1,14 @@ +{ + "chassis": { + "x86_64-mlnx_msn4410-r0": { + "component": { + "ONIE": { }, + "SSD": { }, + "BIOS": { }, + "CPLD1": { }, + "CPLD2": { }, + "CPLD3": { } + } + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn4410-r0/platform_reboot b/device/mellanox/x86_64-mlnx_msn4410-r0/platform_reboot new file mode 120000 index 000000000000..43c8ea567493 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4410-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_msn4410-r0/platform_wait b/device/mellanox/x86_64-mlnx_msn4410-r0/platform_wait new file mode 120000 index 000000000000..4b30bd429854 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4410-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_msn4410-r0/plugins/eeprom.py b/device/mellanox/x86_64-mlnx_msn4410-r0/plugins/eeprom.py new file mode 120000 index 000000000000..b4e2a6a61671 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4410-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_msn4410-r0/plugins/psuutil.py b/device/mellanox/x86_64-mlnx_msn4410-r0/plugins/psuutil.py new file mode 120000 index 000000000000..9f724238a8d5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4410-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_msn4410-r0/plugins/sfplpmget.py b/device/mellanox/x86_64-mlnx_msn4410-r0/plugins/sfplpmget.py new file mode 120000 index 000000000000..2e84f435abd9 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4410-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_msn4410-r0/plugins/sfplpmset.py b/device/mellanox/x86_64-mlnx_msn4410-r0/plugins/sfplpmset.py new file mode 120000 index 000000000000..6a88bac30467 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4410-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_msn4410-r0/plugins/sfpreset.py b/device/mellanox/x86_64-mlnx_msn4410-r0/plugins/sfpreset.py new file mode 120000 index 000000000000..fef2063e3496 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4410-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_msn4410-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_msn4410-r0/plugins/sfputil.py new file mode 100644 index 000000000000..c94b65881fe9 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4410-r0/plugins/sfputil.py @@ -0,0 +1,655 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# + +try: + import subprocess + from sonic_sfp.sfputilbase import * + import syslog +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + +# sfp supports dom +XCVR_DOM_CAPABILITY_DOM_SUPPORT_BIT = 0x40 + +# sfp module threshold offset and width +SFP_MODULE_THRESHOLD_OFFSET = 0 +SFP_MODULE_THRESHOLD_WIDTH = 56 + +# I2C page size for sfp +SFP_I2C_PAGE_SIZE = 256 + +# parameters for DB connection +REDIS_TIMEOUT_USECS = 0 + +# parameters for SFP presence +SFP_STATUS_INSERTED = '1' + +# system level event/error +EVENT_ON_ALL_SFP = '-1' +SYSTEM_NOT_READY = 'system_not_ready' +SYSTEM_READY = 'system_become_ready' +SYSTEM_FAIL = 'system_fail' + +GET_PLATFORM_CMD = "sonic-cfggen -d -v DEVICE_METADATA.localhost.platform" + +# Ethernet <=> sfp +SFP_PORT_NAME_OFFSET = 0 +SFP_PORT_NAME_CONVENTION = "sfp{}" + +# magic code defnition for port number, qsfp port position of each platform +# port_position_tuple = (PORT_START, QSFP_PORT_START, PORT_END, PORT_IN_BLOCK, EEPROM_OFFSET) +platform_dict = {'x86_64-mlnx_msn2700-r0': 0, 'x86_64-mlnx_msn2740-r0': 0, 'x86_64-mlnx_msn2100-r0': 1, 'x86_64-mlnx_msn2410-r0': 2, 'x86_64-mlnx_msn2010-r0': 3, 'x86_64-mlnx_msn3420-r0':5, 'x86_64-mlnx_msn3700-r0': 0, 'x86_64-mlnx_msn3700c-r0': 0, 'x86_64-mlnx_msn3800-r0': 4, 'x86_64-mlnx_msn4410-r0': 0, 'x86_64-mlnx_msn4600c':4, 'x86_64-mlnx_msn4700-r0': 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), (0, 48, 59, 60, 1)] + +def log_info(msg, also_print_to_console=False): + syslog.openlog("sfputil") + syslog.syslog(syslog.LOG_INFO, msg) + syslog.closelog() + +def log_err(msg, also_print_to_console=False): + syslog.openlog("sfputil") + syslog.syslog(syslog.LOG_ERR, msg) + syslog.closelog() + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + PORT_START = 0 + QSFP_PORT_START = 0 + PORT_END = 0 + PORTS_IN_BLOCK = 0 + EEPROM_OFFSET = 0 + + db_sel = None + db_sel_timeout = None + db_sel_object = None + db_sel_tbl = None + state_db = None + sfpd_status_tbl = None + + @property + def port_start(self): + return self.PORT_START + + @property + def port_end(self): + return self.PORT_END + + @property + def qsfp_ports(self): + return range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1) + + @property + def port_to_eeprom_mapping(self): + print "dependency on sysfs has been removed" + raise Exception() + + def get_port_position_tuple_by_platform_name(self): + p = subprocess.Popen(GET_PLATFORM_CMD, shell=True, stdout=subprocess.PIPE) + out, err = p.communicate() + position_tuple = port_position_tuple_list[platform_dict[out.rstrip('\n')]] + return position_tuple + + def __init__(self): + port_position_tuple = self.get_port_position_tuple_by_platform_name() + self.PORT_START = port_position_tuple[0] + 1 + self.QSFP_PORT_START = port_position_tuple[1] + 1 + self.PORT_END = port_position_tuple[2] + 1 + self.PORTS_IN_BLOCK = port_position_tuple[3] + self.EEPROM_OFFSET = port_position_tuple[4] + self.mlnx_sfpd_started = False + + SfpUtilBase.__init__(self) + + def get_presence(self, port_num): + presence = False + + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return presence + + port_num += SFP_PORT_NAME_OFFSET + sfpname = SFP_PORT_NAME_CONVENTION.format(port_num) + + ethtool_cmd = "ethtool -m {} 2>/dev/null".format(sfpname) + try: + proc = subprocess.Popen(ethtool_cmd, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + result = stdout.rstrip('\n') + if result != '': + presence = True + + except OSError, e: + return presence + + return presence + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + lpm_cmd = "docker exec syncd python /usr/share/sonic/platform/plugins/sfplpmget.py {}".format(port_num) + + try: + output = subprocess.check_output(lpm_cmd, shell=True) + if 'LPM ON' in output: + return True + except subprocess.CalledProcessError as e: + print "Error! Unable to get LPM for {}, rc = {}, err msg: {}".format(port_num, e.returncode, e.output) + return False + + return False + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + curr_lpmode = self.get_low_power_mode(port_num) + if curr_lpmode == lpmode: + return True + + # Compose LPM command + lpm = 'on' if lpmode else 'off' + lpm_cmd = "docker exec syncd python /usr/share/sonic/platform/plugins/sfplpmset.py {} {}".format(port_num, lpm) + + # Set LPM + try: + subprocess.check_output(lpm_cmd, shell=True) + except subprocess.CalledProcessError as e: + print "Error! Unable to set LPM for {}, rc = {}, err msg: {}".format(port_num, e.returncode, e.output) + return False + + return True + + def reset(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + lpm_cmd = "docker exec syncd python /usr/share/sonic/platform/plugins/sfpreset.py {}".format(port_num) + + try: + subprocess.check_output(lpm_cmd, shell=True) + return True + except subprocess.CalledProcessError as e: + print "Error! Unable to set LPM for {}, rc = {}, err msg: {}".format(port_num, e.returncode, e.output) + return False + + def get_transceiver_change_event(self, timeout=0): + phy_port_dict = {} + status = True + + if self.db_sel is None: + from swsscommon import swsscommon + self.state_db = swsscommon.DBConnector("STATE_DB", + REDIS_TIMEOUT_USECS, + True) + + # Subscribe to state table for SFP change notifications + self.db_sel = swsscommon.Select() + self.db_sel_tbl = swsscommon.NotificationConsumer(self.state_db, 'TRANSCEIVER_NOTIFY') + self.db_sel.addSelectable(self.db_sel_tbl) + self.db_sel_timeout = swsscommon.Select.TIMEOUT + self.db_sel_object = swsscommon.Select.OBJECT + self.sfpd_status_tbl = swsscommon.Table(self.state_db, 'MLNX_SFPD_TASK') + + # Check the liveness of mlnx-sfpd, if it failed, return system_fail event + # If mlnx-sfpd not started, return system_not_ready event + keys = self.sfpd_status_tbl.getKeys() + if 'LIVENESS' not in keys: + if self.mlnx_sfpd_started: + log_err("mlnx-sfpd exited, return false to notify xcvrd.") + phy_port_dict[EVENT_ON_ALL_SFP] = SYSTEM_FAIL + return False, phy_port_dict + else: + log_info("mlnx-sfpd not ready, return false to notify xcvrd.") + phy_port_dict[EVENT_ON_ALL_SFP] = SYSTEM_NOT_READY + return False, phy_port_dict + else: + if not self.mlnx_sfpd_started: + self.mlnx_sfpd_started = True + log_info("mlnx-sfpd is running") + phy_port_dict[EVENT_ON_ALL_SFP] = SYSTEM_READY + return False, phy_port_dict + + if timeout: + (state, c) = self.db_sel.select(timeout) + else: + (state, c) = self.db_sel.select() + + if state == self.db_sel_timeout: + status = True + elif state != self.db_sel_object: + status = False + else: + (key, op, fvp) = self.db_sel_tbl.pop() + phy_port_dict[key] = op + + return status, phy_port_dict + + def _read_eeprom_specific_bytes(self, sysfsfile_eeprom, offset, num_bytes): + print("_read_eeprom_specific_bytes should not be called since the sysfs it dependents on will no longer exist.") + print("_read_eeprom_specific_bytes_via_ethtool should be called instead") + raise Exception() + + # Read out any bytes from any offset + def _read_eeprom_specific_bytes_via_ethtool(self, port_num, offset, num_bytes): + port_num += SFP_PORT_NAME_OFFSET + sfpname = SFP_PORT_NAME_CONVENTION.format(port_num) + + eeprom_raw = [] + ethtool_cmd = "ethtool -m {} hex on offset {} length {}".format(sfpname, offset, num_bytes) + try: + output = subprocess.check_output(ethtool_cmd, shell=True) + output_lines = output.splitlines() + first_line_raw = output_lines[0] + if "Offset" in first_line_raw: + for line in output_lines[2:]: + line_split = line.split() + eeprom_raw = eeprom_raw + line_split[1:] + except subprocess.CalledProcessError as e: + return None + + return eeprom_raw + + # Read eeprom + def _read_eeprom_devid(self, port_num, devid, offset, num_bytes = 512): + if port_num in self.osfp_ports: + pass + elif port_num in self.qsfp_ports: + pass + elif (self.DOM_EEPROM_ADDR == devid): + offset += 256 + + eeprom_raw = self._read_eeprom_specific_bytes_via_ethtool(port_num, offset, num_bytes) + + return eeprom_raw + + # Read out SFP type, vendor name, PN, REV, SN from eeprom. + def get_transceiver_info_dict(self, port_num): + transceiver_info_dict = {} + compliance_code_dict = {} + + # ToDo: OSFP tranceiver info parsing not fully supported. + # in inf8628.py lack of some memory map definition + # will be implemented when the inf8628 memory map ready + if port_num in self.osfp_ports: + offset = 0 + vendor_rev_width = XCVR_HW_REV_WIDTH_OSFP + + sfpi_obj = inf8628InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + + sfp_type_raw = self._read_eeprom_specific_bytes_via_ethtool(port_num, (offset + OSFP_TYPE_OFFSET), XCVR_TYPE_WIDTH) + if sfp_type_raw is not None: + sfp_type_data = sfpi_obj.parse_sfp_type(sfp_type_raw, 0) + else: + return None + + sfp_vendor_name_raw = self._read_eeprom_specific_bytes_via_ethtool(port_num, (offset + OSFP_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) + if sfp_vendor_name_raw is not None: + sfp_vendor_name_data = sfpi_obj.parse_vendor_name(sfp_vendor_name_raw, 0) + else: + return None + + sfp_vendor_pn_raw = self._read_eeprom_specific_bytes_via_ethtool(port_num, (offset + OSFP_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + if sfp_vendor_pn_raw is not None: + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0) + else: + return None + + sfp_vendor_rev_raw = self._read_eeprom_specific_bytes_via_ethtool(port_num, (offset + OSFP_HW_REV_OFFSET), vendor_rev_width) + if sfp_vendor_rev_raw is not None: + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_vendor_rev_raw, 0) + else: + return None + + sfp_vendor_sn_raw = self._read_eeprom_specific_bytes_via_ethtool(port_num, (offset + OSFP_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + if sfp_vendor_sn_raw is not None: + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_vendor_sn_raw, 0) + else: + return None + + transceiver_info_dict['type'] = sfp_type_data['data']['type']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + # Below part is added to avoid fail the xcvrd, shall be implemented later + transceiver_info_dict['vendor_oui'] = 'N/A' + transceiver_info_dict['vendor_date'] = 'N/A' + transceiver_info_dict['connector'] = 'N/A' + transceiver_info_dict['encoding'] = 'N/A' + transceiver_info_dict['ext_identifier'] = 'N/A' + transceiver_info_dict['ext_rateselect_compliance'] = 'N/A' + transceiver_info_dict['cable_type'] = 'N/A' + transceiver_info_dict['cable_length'] = 'N/A' + transceiver_info_dict['specification_compliance'] = 'N/A' + transceiver_info_dict['nominal_bit_rate'] = 'N/A' + + else: + if port_num in self.qsfp_ports: + offset = 128 + vendor_rev_width = XCVR_HW_REV_WIDTH_QSFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_QSFP + sfp_type = 'QSFP' + + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + + else: + offset = 0 + vendor_rev_width = XCVR_HW_REV_WIDTH_SFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_SFP + sfp_type = 'SFP' + + sfpi_obj = sff8472InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + + sfp_interface_bulk_raw = self._read_eeprom_specific_bytes_via_ethtool(port_num, (offset + XCVR_INTFACE_BULK_OFFSET), interface_info_bulk_width) + if sfp_interface_bulk_raw is not None: + sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(sfp_interface_bulk_raw, 0) + else: + return None + + sfp_vendor_name_raw = self._read_eeprom_specific_bytes_via_ethtool(port_num, (offset + XCVR_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) + if sfp_vendor_name_raw is not None: + sfp_vendor_name_data = sfpi_obj.parse_vendor_name(sfp_vendor_name_raw, 0) + else: + return None + + sfp_vendor_pn_raw = self._read_eeprom_specific_bytes_via_ethtool(port_num, (offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + if sfp_vendor_pn_raw is not None: + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0) + else: + return None + + sfp_vendor_rev_raw = self._read_eeprom_specific_bytes_via_ethtool(port_num, (offset + XCVR_HW_REV_OFFSET), vendor_rev_width) + if sfp_vendor_rev_raw is not None: + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_vendor_rev_raw, 0) + else: + return None + + sfp_vendor_sn_raw = self._read_eeprom_specific_bytes_via_ethtool(port_num, (offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + if sfp_vendor_sn_raw is not None: + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_vendor_sn_raw, 0) + else: + return None + + sfp_vendor_oui_raw = self._read_eeprom_specific_bytes_via_ethtool(port_num, (offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH) + if sfp_vendor_oui_raw is not None: + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(sfp_vendor_oui_raw, 0) + else: + return None + + sfp_vendor_date_raw = self._read_eeprom_specific_bytes_via_ethtool(port_num, (offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH) + if sfp_vendor_date_raw is not None: + sfp_vendor_date_data = sfpi_obj.parse_vendor_date(sfp_vendor_date_raw, 0) + else: + return None + + transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] + transceiver_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] + transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] + transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] + if sfp_type == 'QSFP': + for key in qsfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str(sfp_interface_bulk_data['data'][key]['value']) + + for key in qsfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) + + transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value']) + else: + for key in sfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str(sfp_interface_bulk_data['data'][key]['value']) + + for key in sfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) + + transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) + + return transceiver_info_dict + + def get_transceiver_dom_info_dict(self, port_num): + transceiver_dom_info_dict = {} + + # Below part is added to avoid failing xcvrd + # Currently, the way in which dom data is read has been changed from + # using sysfs to using ethtool. + # The ethtool returns None for ports without dom support, resulting in + # None being returned. However, this fails xcvrd to add the + # TRANSCEIVER_DOM_SENSOR table entry of associated port to CONFIG_DB + # and then causes SNMP fail. + # To address this issue a default dict is initialized with all data set to + # 'N/A' and is returned is the above case. + # BTW, in the original implementation which sysfs is used to read dom data, + # even though non-None data is returned for ports without dom support, + # it does not contain valid data. This can result in wrong data in + # TRANSCEIVER_DOM_SENSOR table. + transceiver_dom_info_dict['temperature'] = 'N/A' + transceiver_dom_info_dict['voltage'] = 'N/A' + transceiver_dom_info_dict['rx1power'] = 'N/A' + 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'] = 'N/A' + 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'] = 'N/A' + transceiver_dom_info_dict['tx2power'] = 'N/A' + transceiver_dom_info_dict['tx3power'] = 'N/A' + transceiver_dom_info_dict['tx4power'] = 'N/A' + + if port_num in self.osfp_ports: + pass + elif port_num in self.qsfp_ports: + offset = 0 + offset_xcvr = 128 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + return None + + + # 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_via_ethtool(port_num, (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_dom_capability(qsfp_dom_capability_raw, 0) + else: + return transceiver_dom_info_dict + + dom_temperature_raw = self._read_eeprom_specific_bytes_via_ethtool(port_num, (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_via_ethtool(port_num, (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_via_ethtool(port_num, (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_via_ethtool(port_num, (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 + else: + dom_channel_monitor_raw = self._read_eeprom_specific_bytes_via_ethtool(port_num, (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 transceiver_dom_info_dict + + 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'] + + 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'] + + else: + offset = SFP_I2C_PAGE_SIZE + + eeprom_raw = ['0'] * SFP_I2C_PAGE_SIZE + eeprom_raw[XCVR_DOM_CAPABILITY_OFFSET : XCVR_DOM_CAPABILITY_OFFSET + XCVR_DOM_CAPABILITY_WIDTH] = \ + self._read_eeprom_specific_bytes_via_ethtool(port_num, XCVR_DOM_CAPABILITY_OFFSET, XCVR_DOM_CAPABILITY_WIDTH) + sfp_obj = sff8472InterfaceId() + calibration_type = sfp_obj._get_calibration_type(eeprom_raw) + + dom_supported = (int(eeprom_raw[XCVR_DOM_CAPABILITY_OFFSET], 16) & XCVR_DOM_CAPABILITY_DOM_SUPPORT_BIT != 0) + if not dom_supported: + return transceiver_dom_info_dict + + eeprom_domraw = self._read_eeprom_specific_bytes_via_ethtool(port_num, offset, SFP_I2C_PAGE_SIZE) + if eeprom_domraw is None: + return transceiver_dom_info_dict + + sfpd_obj = sff8472Dom(None, calibration_type) + if sfpd_obj is None: + print "no sff8472Dom" + return None + + dom_temperature_raw = eeprom_domraw[SFP_TEMPE_OFFSET:SFP_TEMPE_OFFSET+SFP_TEMPE_WIDTH] + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + + dom_voltage_raw = eeprom_domraw[SFP_VOLT_OFFSET:SFP_VOLT_OFFSET+SFP_VOLT_WIDTH] + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + + dom_channel_monitor_raw = eeprom_domraw[SFP_CHANNL_MON_OFFSET:SFP_CHANNL_MON_OFFSET+SFP_CHANNL_MON_WIDTH] + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + + 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['tx1bias'] = dom_channel_monitor_data['data']['TXBias']['value'] + transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TXPower']['value'] + + 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: + # current we don't support qsfp since threshold data is on page 3 and the way to read this page is under discussion. + return transceiver_dom_threshold_info_dict + else: + offset = SFP_I2C_PAGE_SIZE + + eeprom_raw = ['0'] * SFP_I2C_PAGE_SIZE + eeprom_raw[XCVR_DOM_CAPABILITY_OFFSET : XCVR_DOM_CAPABILITY_OFFSET + XCVR_DOM_CAPABILITY_WIDTH] = \ + self._read_eeprom_specific_bytes_via_ethtool(port_num, XCVR_DOM_CAPABILITY_OFFSET, XCVR_DOM_CAPABILITY_WIDTH) + sfp_obj = sff8472InterfaceId() + calibration_type = sfp_obj._get_calibration_type(eeprom_raw) + + dom_supported = (int(eeprom_raw[XCVR_DOM_CAPABILITY_OFFSET], 16) & XCVR_DOM_CAPABILITY_DOM_SUPPORT_BIT != 0) + if not dom_supported: + return transceiver_dom_threshold_info_dict + + sfpd_obj = sff8472Dom(None, calibration_type) + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_raw = self._read_eeprom_specific_bytes_via_ethtool(port_num, + (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 + + # 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 diff --git a/device/mellanox/x86_64-mlnx_msn4410-r0/pmon_daemon_control.json b/device/mellanox/x86_64-mlnx_msn4410-r0/pmon_daemon_control.json new file mode 120000 index 000000000000..435a2ce7c0ba --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4410-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_msn4410-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn4410-r0/sensors.conf new file mode 120000 index 000000000000..e484524c164e --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4410-r0/sensors.conf @@ -0,0 +1 @@ +../x86_64-mlnx_msn4700-r0/sensors.conf \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4410-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_msn4410-r0/system_health_monitoring_config.json new file mode 120000 index 000000000000..98df66c27ca5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4410-r0/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4410-r0/thermal_policy.json b/device/mellanox/x86_64-mlnx_msn4410-r0/thermal_policy.json new file mode 120000 index 000000000000..5a25cd87f70c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4410-r0/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/thermal_policy.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers.json.j2 new file mode 120000 index 000000000000..f46e9600153b --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers_defaults_t0.j2 new file mode 120000 index 000000000000..ddb883a1daa4 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers_defaults_t0.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_defaults_t0.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers_defaults_t1.j2 new file mode 120000 index 000000000000..f8bbb6e631e7 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers_defaults_t1.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_defaults_t1.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers_dynamic.json.j2 b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers_dynamic.json.j2 new file mode 120000 index 000000000000..8c4117c66214 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers_dynamic.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_dynamic.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/hwsku.json b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/hwsku.json new file mode 100644 index 000000000000..b73944cba7a0 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/hwsku.json @@ -0,0 +1,196 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet8": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet16": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet24": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet32": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet40": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet48": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet56": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet64": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet72": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet80": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet88": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet96": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet104": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet112": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet120": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet128": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet136": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet144": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet152": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet160": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet168": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet176": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet184": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet192": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet200": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet208": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet216": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet224": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet232": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet240": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet248": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet256": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet264": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet272": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet280": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet288": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet296": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet304": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet312": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet320": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet328": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet336": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet344": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet352": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet360": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet368": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet376": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet384": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet392": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet400": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet408": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet416": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet424": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet432": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet440": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet448": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet456": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet464": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet472": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet480": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet488": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet496": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet504": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + } + } +} \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/pg_profile_lookup.ini new file mode 120000 index 000000000000..88e51ceae044 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/pg_profile_lookup.ini @@ -0,0 +1 @@ +../../x86_64-mlnx_msn4700-r0/ACS-MSN4700/pg_profile_lookup.ini \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/port_config.ini b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/port_config.ini new file mode 100644 index 000000000000..a1ecf9aa3266 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/port_config.ini @@ -0,0 +1,65 @@ +# name lanes alias index +Ethernet0 0,1,2,3 etp1 1 +Ethernet8 8,9,10,11 etp2 2 +Ethernet16 16,17,18,19 etp3 3 +Ethernet24 24,25,26,27 etp4 4 +Ethernet32 32,33,34,35 etp5 5 +Ethernet40 40,41,42,43 etp6 6 +Ethernet48 48,49,50,51 etp7 7 +Ethernet56 56,57,58,59 etp8 8 +Ethernet64 64,65,66,67 etp9 9 +Ethernet72 72,73,74,75 etp10 10 +Ethernet80 80,81,82,83 etp11 11 +Ethernet88 88,89,90,91 etp12 12 +Ethernet96 96,97,98,99 etp13 13 +Ethernet104 104,105,106,107 etp14 14 +Ethernet112 112,113,114,115 etp15 15 +Ethernet120 120,121,122,123 etp16 16 +Ethernet128 128,129,130,131 etp17 17 +Ethernet136 136,137,138,139 etp18 18 +Ethernet144 144,145,146,147 etp19 19 +Ethernet152 152,153,154,155 etp20 20 +Ethernet160 160,161,162,163 etp21 21 +Ethernet168 168,169,170,171 etp22 22 +Ethernet176 176,177,178,179 etp23 23 +Ethernet184 184,185,186,187 etp24 24 +Ethernet192 192,193,194,195 etp25 25 +Ethernet200 200,201,202,203 etp26 26 +Ethernet208 208,209,210,211 etp27 27 +Ethernet216 216,217,218,219 etp28 28 +Ethernet224 224,225,226,227 etp29 29 +Ethernet232 232,233,234,235 etp30 30 +Ethernet240 240,241,242,243 etp31 31 +Ethernet248 248,249,250,251 etp32 32 +Ethernet256 256,257,258,259 etp33 33 +Ethernet264 264,265,266,267 etp34 34 +Ethernet272 272,273,274,275 etp35 35 +Ethernet280 280,281,282,283 etp36 36 +Ethernet288 288,289,290,291 etp37 37 +Ethernet296 296,297,298,299 etp38 38 +Ethernet304 304,305,306,307 etp39 39 +Ethernet312 312,313,314,315 etp40 40 +Ethernet320 320,321,322,323 etp41 41 +Ethernet328 328,329,330,331 etp42 42 +Ethernet336 336,337,338,339 etp43 43 +Ethernet344 344,345,346,347 etp44 44 +Ethernet352 352,353,354,355 etp45 45 +Ethernet360 360,361,362,363 etp46 46 +Ethernet368 368,369,370,371 etp47 47 +Ethernet376 376,377,378,379 etp48 48 +Ethernet384 384,385,386,387 etp49 49 +Ethernet392 392,393,394,395 etp50 50 +Ethernet400 400,401,402,403 etp51 51 +Ethernet408 408,409,410,411 etp52 52 +Ethernet416 416,417,418,419 etp53 53 +Ethernet424 424,425,426,427 etp54 54 +Ethernet432 432,433,434,435 etp55 55 +Ethernet440 440,441,442,443 etp56 56 +Ethernet448 448,449,450,451 etp57 57 +Ethernet456 456,457,458,459 etp58 58 +Ethernet464 464,465,466,467 etp59 59 +Ethernet472 472,473,474,475 etp60 60 +Ethernet480 480,481,482,483 etp61 61 +Ethernet488 488,489,490,491 etp62 62 +Ethernet496 496,497,498,499 etp63 63 +Ethernet504 504,505,506,507 etp64 64 diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/qos.json.j2 b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/qos.json.j2 new file mode 120000 index 000000000000..8633303ece77 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/qos.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn4700-r0/ACS-MSN4700/qos.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/sai.profile b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/sai.profile new file mode 100644 index 000000000000..e9d1e3e5f591 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/sai_4600C.xml diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/sai_4600C.xml b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/sai_4600C.xml new file mode 100644 index 000000000000..02d0ed6ccd8e --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/sai_4600C.xml @@ -0,0 +1,470 @@ + + + + + + 00:02:03:04:05:80 + + + 1 + + + 64 + + + + + 105 + 4 + 0 + + + 3 + + + 1536 + + + 107 + 4 + 1 + 3 + 1536 + + + 109 + 4 + 2 + 3 + 1536 + + + 111 + 4 + 3 + 3 + 1536 + + + 97 + 4 + 4 + 3 + 1536 + + + 99 + 4 + 5 + 3 + 1536 + + + 101 + 4 + 6 + 3 + 1536 + + + 103 + 4 + 7 + 3 + 1536 + + + 121 + 4 + 8 + 3 + 1536 + + + 123 + 4 + 9 + 3 + 1536 + + + 125 + 4 + 10 + 3 + 1536 + + + 127 + 4 + 11 + 3 + 1536 + + + 113 + 4 + 12 + 3 + 1536 + + + 115 + 4 + 13 + 3 + 1536 + + + 117 + 4 + 14 + 3 + 1536 + + + 119 + 4 + 15 + 3 + 1536 + + + 89 + 4 + 16 + 3 + 1536 + + + 91 + 4 + 17 + 3 + 1536 + + + 93 + 4 + 18 + 3 + 1536 + + + 95 + 4 + 19 + 3 + 1536 + + + 81 + 4 + 20 + 3 + 1536 + + + 83 + 4 + 21 + 3 + 1536 + + + 85 + 4 + 22 + 3 + 1536 + + + 87 + 4 + 23 + 3 + 1536 + + + 73 + 4 + 24 + 3 + 1536 + + + 75 + 4 + 25 + 3 + 1536 + + + 77 + 4 + 26 + 3 + 1536 + + + 79 + 4 + 27 + 3 + 1536 + + + 65 + 4 + 28 + 3 + 1536 + + + 67 + 4 + 29 + 3 + 1536 + + + 69 + 4 + 30 + 3 + 1536 + + + 71 + 4 + 31 + 3 + 1536 + + + 5 + 4 + 32 + 3 + 1536 + + + 7 + 4 + 33 + 3 + 1536 + + + 1 + 4 + 34 + 3 + 1536 + + + 3 + 4 + 35 + 3 + 1536 + + + 13 + 4 + 36 + 3 + 1536 + + + 15 + 4 + 37 + 3 + 1536 + + + 9 + 4 + 38 + 3 + 1536 + + + 11 + 4 + 39 + 3 + 1536 + + + 21 + 4 + 40 + 3 + 1536 + + + 23 + 4 + 41 + 3 + 1536 + + + 17 + 4 + 42 + 3 + 1536 + + + 19 + 4 + 43 + 3 + 1536 + + + 29 + 4 + 44 + 3 + 1536 + + + 31 + 4 + 45 + 3 + 1536 + + + 25 + 4 + 46 + 3 + 1536 + + + 27 + 4 + 47 + 3 + 1536 + + + 53 + 4 + 48 + 3 + 1536 + + + 55 + 4 + 49 + 3 + 1536 + + + 49 + 4 + 50 + 3 + 1536 + + + 51 + 4 + 51 + 3 + 1536 + + + 61 + 4 + 52 + 3 + 1536 + + + 63 + 4 + 53 + 3 + 1536 + + + 57 + 4 + 54 + 3 + 1536 + + + 59 + 4 + 55 + 3 + 1536 + + + 37 + 4 + 56 + 3 + 1536 + + + 39 + 4 + 57 + 3 + 1536 + + + 33 + 4 + 58 + 3 + 1536 + + + 35 + 4 + 59 + 3 + 1536 + + + 45 + 4 + 60 + 3 + 1536 + + + 47 + 4 + 61 + 3 + 1536 + + + 41 + 4 + 62 + 3 + 1536 + + + 43 + 4 + 63 + 3 + 1536 + + + + \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/buffers.json.j2 new file mode 120000 index 000000000000..117d740b0f5b --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/buffers.json.j2 @@ -0,0 +1 @@ +../ACS-MSN4600C/buffers.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..aa74c4645678 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/buffers_defaults_t0.j2 @@ -0,0 +1,104 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '47587328' %} +{% set ingress_lossless_xoff_size = '2400256' %} +{% set egress_lossless_pool_size = '60817392' %} +{% set egress_lossy_pool_size = '47587328' %} + +{%- 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": { + {%- if dynamic_mode is not defined %} + "size": "{{ ingress_lossless_pool_size }}", + "xoff": "{{ ingress_lossless_xoff_size }}", + {%- endif %} + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + {%- if dynamic_mode is not defined %} + "size": "{{ egress_lossy_pool_size }}", + {%- endif %} + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "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", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"9216", + "dynamic_th":"7" + }, + "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]" + }{% 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_msn4600c-r0/Mellanox-SN4600C-D112C8/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..1cc727f8c85e --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/buffers_defaults_t1.j2 @@ -0,0 +1,104 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '46702592' %} +{% set ingress_lossless_xoff_size = '3284992' %} +{% set egress_lossless_pool_size = '60817392' %} +{% set egress_lossy_pool_size = '46702592' %} + +{%- 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": { + {%- if dynamic_mode is not defined %} + "size": "{{ ingress_lossless_pool_size }}", + "xoff": "{{ ingress_lossless_xoff_size }}", + {%- endif %} + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + {%- if dynamic_mode is not defined %} + "size": "{{ egress_lossy_pool_size }}", + {%- endif %} + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "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", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"9216", + "dynamic_th":"7" + }, + "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]" + }{% 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_msn4600c-r0/Mellanox-SN4600C-D112C8/buffers_dynamic.json.j2 b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/buffers_dynamic.json.j2 new file mode 120000 index 000000000000..8c4117c66214 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/buffers_dynamic.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_dynamic.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/hwsku.json b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/hwsku.json new file mode 100644 index 000000000000..2e095568b91c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/hwsku.json @@ -0,0 +1,316 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet2": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet8": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet10": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet16": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet18": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet24": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet32": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet34": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet40": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet42": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet48": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet50": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet56": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet64": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet66": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet72": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet74": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet80": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet82": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet88": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet96": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet98": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet104": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet106": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet112": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet114": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet120": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet128": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet130": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet136": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet138": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet144": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet146": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet152": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet160": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet162": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet168": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet170": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet176": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet178": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet184": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet192": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet200": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet208": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet210": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet216": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet224": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet232": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet240": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet242": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet248": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet256": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet264": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet272": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet274": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet280": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet288": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet296": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet304": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet306": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet312": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet320": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet322": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet328": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet330": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet336": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet338": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet344": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet352": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet354": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet360": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet362": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet368": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet370": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet376": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet384": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet386": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet392": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet394": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet400": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet402": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet408": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet416": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet418": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet424": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet426": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet432": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet434": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet440": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet448": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet450": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet456": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet458": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet464": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet466": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet472": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet480": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet482": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet488": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet490": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet496": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet498": { + "default_brkout_mode": "2x50G[40G,25G,10G,1G]" + }, + "Ethernet504": { + "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]" + } + } +} \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/pg_profile_lookup.ini new file mode 100644 index 000000000000..4931d4e1d7ae --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 10000 5m 19456 19456 24576 0 + 25000 5m 19456 19456 24576 0 + 40000 5m 19456 19456 24576 0 + 50000 5m 19456 19456 24576 0 + 100000 5m 19456 19456 25600 0 + 10000 40m 19456 19456 24576 0 + 25000 40m 19456 19456 26624 0 + 40000 40m 19456 19456 27648 0 + 50000 40m 19456 19456 28672 0 + 100000 40m 19456 19456 32768 0 + 10000 300m 19456 19456 30720 0 + 25000 300m 19456 19456 39936 0 + 40000 300m 19456 19456 49152 0 + 50000 300m 19456 19456 55296 0 + 100000 300m 19456 19456 86016 0 diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/port_config.ini b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/port_config.ini new file mode 100644 index 000000000000..eb4cdc35637b --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/port_config.ini @@ -0,0 +1,105 @@ +# name lanes alias index speed fec +Ethernet0 0,1 etp1a 1 50000 none +Ethernet2 2,3 etp1b 1 50000 none +Ethernet8 8,9 etp2a 2 50000 none +Ethernet10 10,11 etp2b 2 50000 none +Ethernet16 16,17 etp3a 3 50000 none +Ethernet18 18,19 etp3b 3 50000 none +Ethernet24 24,25,26,27 etp4 4 100000 rs +Ethernet32 32,33 etp5a 5 50000 none +Ethernet34 34,35 etp5b 5 50000 none +Ethernet40 40,41 etp6a 6 50000 none +Ethernet42 42,43 etp6b 6 50000 none +Ethernet48 48,49 etp7a 7 50000 none +Ethernet50 50,51 etp7b 7 50000 none +Ethernet56 56,57,58,59 etp8 8 100000 rs +Ethernet64 64,65 etp9a 9 50000 none +Ethernet66 66,67 etp9b 9 50000 none +Ethernet72 72,73 etp10a 10 50000 none +Ethernet74 74,75 etp10b 10 50000 none +Ethernet80 80,81 etp11a 11 50000 none +Ethernet82 82,83 etp11b 11 50000 none +Ethernet88 88,89,90,91 etp12 12 100000 rs +Ethernet96 96,97 etp13a 13 50000 none +Ethernet98 98,99 etp13b 13 50000 none +Ethernet104 104,105 etp14a 14 50000 none +Ethernet106 106,107 etp14b 14 50000 none +Ethernet112 112,113 etp15a 15 50000 none +Ethernet114 114,115 etp15b 15 50000 none +Ethernet120 120,121,122,123 etp16 16 100000 rs +Ethernet128 128,129 etp17a 17 50000 none +Ethernet130 130,131 etp17b 17 50000 none +Ethernet136 136,137 etp18a 18 50000 none +Ethernet138 138,139 etp18b 18 50000 none +Ethernet144 144,145 etp19a 19 50000 none +Ethernet146 146,147 etp19b 19 50000 none +Ethernet152 152,153,154,155 etp20 20 100000 rs +Ethernet160 160,161 etp21a 21 50000 none +Ethernet162 162,163 etp21b 21 50000 none +Ethernet168 168,169 etp22a 22 50000 none +Ethernet170 170,171 etp22b 22 50000 none +Ethernet176 176,177 etp23a 23 50000 none +Ethernet178 178,179 etp23b 23 50000 none +Ethernet184 184,185,186,187 etp24 24 100000 rs +Ethernet192 192,193,194,195 etp25 25 100000 rs +Ethernet200 200,201,202,203 etp26 26 100000 rs +Ethernet208 208,209 etp27a 27 50000 none +Ethernet210 210,211 etp27b 27 50000 none +Ethernet216 216,217,218,219 etp28 28 100000 rs +Ethernet224 224,225,226,227 etp29 29 100000 rs +Ethernet232 232,233,234,235 etp30 30 100000 rs +Ethernet240 240,241 etp31a 31 50000 none +Ethernet242 242,243 etp31b 31 50000 none +Ethernet248 248,249,250,251 etp32 32 100000 rs +Ethernet256 256,257,258,259 etp33 33 100000 rs +Ethernet264 264,265,266,267 etp34 34 100000 rs +Ethernet272 272,273 etp35a 35 50000 none +Ethernet274 274,275 etp35b 35 50000 none +Ethernet280 280,281,282,283 etp36 36 100000 rs +Ethernet288 288,289,290,291 etp37 37 100000 rs +Ethernet296 296,297,298,299 etp38 38 100000 rs +Ethernet304 304,305 etp39a 39 50000 none +Ethernet306 306,307 etp39b 39 50000 none +Ethernet312 312,313,314,315 etp40 40 100000 rs +Ethernet320 320,321 etp41a 41 50000 none +Ethernet322 322,323 etp41b 41 50000 none +Ethernet328 328,329 etp42a 42 50000 none +Ethernet330 330,331 etp42b 42 50000 none +Ethernet336 336,337 etp43a 43 50000 none +Ethernet338 338,339 etp43b 43 50000 none +Ethernet344 344,345,346,347 etp44 44 100000 rs +Ethernet352 352,353 etp45a 45 50000 none +Ethernet354 354,355 etp45b 45 50000 none +Ethernet360 360,361 etp46a 46 50000 none +Ethernet362 362,363 etp46b 46 50000 none +Ethernet368 368,369 etp47a 47 50000 none +Ethernet370 370,371 etp47b 47 50000 none +Ethernet376 376,377,378,379 etp48 48 100000 rs +Ethernet384 384,385 etp49a 49 50000 none +Ethernet386 386,387 etp49b 49 50000 none +Ethernet392 392,393 etp50a 50 50000 none +Ethernet394 394,395 etp50b 50 50000 none +Ethernet400 400,401 etp51a 51 50000 none +Ethernet402 402,403 etp51b 51 50000 none +Ethernet408 408,409,410,411 etp52 52 100000 rs +Ethernet416 416,417 etp53a 53 50000 none +Ethernet418 418,419 etp53b 53 50000 none +Ethernet424 424,425 etp54a 54 50000 none +Ethernet426 426,427 etp54b 54 50000 none +Ethernet432 432,433 etp55a 55 50000 none +Ethernet434 434,435 etp55b 55 50000 none +Ethernet440 440,441,442,443 etp56 56 100000 rs +Ethernet448 448,449 etp57a 57 50000 none +Ethernet450 450,451 etp57b 57 50000 none +Ethernet456 456,457 etp58a 58 50000 none +Ethernet458 458,459 etp58b 58 50000 none +Ethernet464 464,465 etp59a 59 50000 none +Ethernet466 466,467 etp59b 59 50000 none +Ethernet472 472,473,474,475 etp60 60 100000 rs +Ethernet480 480,481 etp61a 61 50000 none +Ethernet482 482,483 etp61b 61 50000 none +Ethernet488 488,489 etp62a 62 50000 none +Ethernet490 490,491 etp62b 62 50000 none +Ethernet496 496,497 etp63a 63 50000 none +Ethernet498 498,499 etp63b 63 50000 none +Ethernet504 504,505,506,507 etp64 64 100000 rs diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/qos.json.j2 b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/qos.json.j2 new file mode 120000 index 000000000000..05394016a129 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/qos.json.j2 @@ -0,0 +1 @@ +../ACS-MSN4600C/qos.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/sai.profile b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/sai.profile new file mode 100644 index 000000000000..15fccb416efd --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/sai_4600c_112x50g_8x100g.xml diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/sai_4600c_112x50g_8x100g.xml b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/sai_4600c_112x50g_8x100g.xml new file mode 100644 index 000000000000..199c251fbee2 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/sai_4600c_112x50g_8x100g.xml @@ -0,0 +1,510 @@ + + + + + + 00:02:03:04:05:80 + + + 1 + + + 64 + + + + + 105 + 2 + 4 + 0 + + + 3 + + + 384 + + + 107 + 2 + 4 + 1 + 3 + 384 + + + 109 + 2 + 4 + 2 + 3 + 384 + + + 111 + 4 + 3 + 3 + 1536 + + + 97 + 2 + 4 + 4 + 3 + 384 + + + 99 + 2 + 4 + 5 + 3 + 384 + + + 101 + 2 + 4 + 6 + 3 + 384 + + + 103 + 4 + 7 + 3 + 1536 + + + 121 + 2 + 4 + 8 + 3 + 384 + + + 123 + 2 + 4 + 9 + 3 + 384 + + + 125 + 2 + 4 + 10 + 3 + 384 + + + 127 + 4 + 11 + 3 + 1536 + + + 113 + 2 + 4 + 12 + 3 + 384 + + + 115 + 2 + 4 + 13 + 3 + 384 + + + 117 + 2 + 4 + 14 + 3 + 384 + + + 119 + 4 + 15 + 3 + 1536 + + + 89 + 2 + 4 + 16 + 3 + 384 + + + 91 + 2 + 4 + 17 + 3 + 384 + + + 93 + 2 + 4 + 18 + 3 + 384 + + + 95 + 4 + 19 + 3 + 1536 + + + 81 + 2 + 4 + 20 + 3 + 384 + + + 83 + 2 + 4 + 21 + 3 + 384 + + + 85 + 2 + 4 + 22 + 3 + 384 + + + 87 + 4 + 23 + 3 + 1536 + + + 73 + 4 + 24 + 3 + 1536 + + + 75 + 4 + 25 + 3 + 1536 + + + 77 + 2 + 4 + 26 + 3 + 384 + + + 79 + 4 + 27 + 3 + 1536 + + + 65 + 4 + 28 + 3 + 1536 + + + 67 + 4 + 29 + 3 + 1536 + + + 69 + 2 + 4 + 30 + 3 + 384 + + + 71 + 4 + 31 + 3 + 1536 + + + 5 + 4 + 32 + 3 + 1536 + + + 7 + 4 + 33 + 3 + 1536 + + + 1 + 2 + 4 + 34 + 3 + 384 + + + 3 + 4 + 35 + 3 + 1536 + + + 13 + 4 + 36 + 3 + 1536 + + + 15 + 4 + 37 + 3 + 1536 + + + 9 + 2 + 4 + 38 + 3 + 384 + + + 11 + 4 + 39 + 3 + 1536 + + + 21 + 2 + 4 + 40 + 3 + 384 + + + 23 + 2 + 4 + 41 + 3 + 384 + + + 17 + 2 + 4 + 42 + 3 + 384 + + + 19 + 4 + 43 + 3 + 1536 + + + 29 + 2 + 4 + 44 + 3 + 384 + + + 31 + 2 + 4 + 45 + 3 + 384 + + + 25 + 2 + 4 + 46 + 3 + 384 + + + 27 + 4 + 47 + 3 + 1536 + + + 53 + 2 + 4 + 48 + 3 + 384 + + + 55 + 2 + 4 + 49 + 3 + 384 + + + 49 + 2 + 4 + 50 + 3 + 384 + + + 51 + 4 + 51 + 3 + 1536 + + + 61 + 2 + 4 + 52 + 3 + 384 + + + 63 + 2 + 4 + 53 + 3 + 384 + + + 57 + 2 + 4 + 54 + 3 + 384 + + + 59 + 4 + 55 + 3 + 1536 + + + 37 + 2 + 4 + 56 + 3 + 384 + + + 39 + 2 + 4 + 57 + 3 + 384 + + + 33 + 2 + 4 + 58 + 3 + 384 + + + 35 + 4 + 59 + 3 + 1536 + + + 45 + 2 + 4 + 60 + 3 + 384 + + + 47 + 2 + 4 + 61 + 3 + 384 + + + 41 + 2 + 4 + 62 + 3 + 384 + + + 43 + 4 + 63 + 3 + 1536 + + + + diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/default_sku b/device/mellanox/x86_64-mlnx_msn4600c-r0/default_sku new file mode 100644 index 000000000000..451382f6d8b8 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/default_sku @@ -0,0 +1 @@ +ACS-MSN4600C t1 diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/pcie.yaml b/device/mellanox/x86_64-mlnx_msn4600c-r0/pcie.yaml new file mode 100644 index 000000000000..dcfdf1c9a59c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/pcie.yaml @@ -0,0 +1,419 @@ +- bus: '00' + dev: '00' + fn: '0' + id: 6f00 + name: 'Host bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D DMI2 + (rev 03)' +- bus: '00' + dev: '01' + fn: '0' + id: 6f02 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 1 (rev 03)' +- bus: '00' + dev: '01' + fn: '1' + id: 6f03 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 1 (rev 03)' +- bus: '00' + dev: '02' + fn: '0' + id: 6f04 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 2 (rev 03)' +- bus: '00' + dev: '02' + fn: '2' + id: 6f06 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 2 (rev 03)' +- bus: '00' + dev: '03' + fn: '0' + id: 6f08 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 3 (rev 03)' +- bus: '00' + dev: '03' + fn: '2' + id: 6f0a + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 3 (rev 03)' +- bus: '00' + dev: '05' + fn: '0' + id: 6f28 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Map/VTd_Misc/System Management (rev 03)' +- bus: '00' + dev: '05' + fn: '1' + id: 6f29 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Hot Plug (rev 03)' +- bus: '00' + dev: '05' + fn: '2' + id: 6f2a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO RAS/Control Status/Global Errors (rev 03)' +- bus: '00' + dev: '05' + fn: '4' + id: 6f2c + name: 'PIC: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D I/O APIC (rev + 03)' +- bus: '00' + dev: '14' + fn: '0' + id: 8c31 + name: 'USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB + xHCI (rev 05)' +- bus: '00' + dev: 1c + fn: '0' + id: 8c10 + name: 'PCI bridge: Intel Corporation 8 Series/C220 Series Chipset Family PCI Express + Root Port #1 (rev d5)' +- bus: '00' + dev: 1c + fn: '7' + id: 8c1e + name: 'PCI bridge: Intel Corporation 8 Series/C220 Series Chipset Family PCI Express + Root Port #8 (rev d5)' +- bus: '00' + dev: 1d + fn: '0' + id: 8c26 + name: 'USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB + EHCI #1 (rev 05)' +- bus: '00' + dev: 1f + fn: '0' + id: 8c54 + name: 'ISA bridge: Intel Corporation C224 Series Chipset Family Server Standard + SKU LPC Controller (rev 05)' +- bus: '00' + dev: 1f + fn: '2' + id: 8c02 + name: 'SATA controller: Intel Corporation 8 Series/C220 Series Chipset Family 6-port + SATA Controller 1 [AHCI mode] (rev 05)' +- bus: '00' + dev: 1f + fn: '3' + id: 8c22 + name: 'SMBus: Intel Corporation 8 Series/C220 Series Chipset Family SMBus Controller + (rev 05)' +- bus: '03' + dev: '00' + fn: '0' + id: 6f50 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 0' +- bus: '03' + dev: '00' + fn: '1' + id: 6f51 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 1' +- bus: '03' + dev: '00' + fn: '2' + id: 6f52 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 2' +- bus: '03' + dev: '00' + fn: '3' + id: 6f53 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 3' +- bus: '06' + dev: '00' + fn: '0' + id: cf70 + name: 'Ethernet controller: Mellanox Technologies Device cf70' +- bus: 08 + dev: '00' + fn: '0' + id: '1533' + name: 'Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev + 03)' +- bus: ff + dev: 0b + fn: '0' + id: 6f81 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '1' + id: 6f36 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '2' + id: 6f37 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '3' + id: 6f76 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link Debug (rev 03)' +- bus: ff + dev: 0c + fn: '0' + id: 6fe0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0c + fn: '1' + id: 6fe1 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0c + fn: '2' + id: 6fe2 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0c + fn: '3' + id: 6fe3 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '0' + id: 6ff8 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '4' + id: 6ffc + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '5' + id: 6ffd + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '6' + id: 6ffe + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: '10' + fn: '0' + id: 6f1d + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R2PCIe Agent (rev 03)' +- bus: ff + dev: '10' + fn: '1' + id: 6f34 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R2PCIe Agent (rev 03)' +- bus: ff + dev: '10' + fn: '5' + id: 6f1e + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '10' + fn: '6' + id: 6f7d + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '10' + fn: '7' + id: 6f1f + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '12' + fn: '0' + id: 6fa0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Home Agent 0 (rev 03)' +- bus: ff + dev: '12' + fn: '1' + id: 6f30 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Home Agent 0 (rev 03)' +- bus: ff + dev: '13' + fn: '0' + id: 6fa8 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Target Address/Thermal/RAS (rev 03)' +- bus: ff + dev: '13' + fn: '1' + id: 6f71 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Target Address/Thermal/RAS (rev 03)' +- bus: ff + dev: '13' + fn: '2' + id: 6faa + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '3' + id: 6fab + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '4' + id: 6fac + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '5' + id: 6fad + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '6' + id: 6fae + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Broadcast (rev 03)' +- bus: ff + dev: '13' + fn: '7' + id: 6faf + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Global Broadcast (rev 03)' +- bus: ff + dev: '14' + fn: '0' + id: 6fb0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 0 Thermal Control (rev 03)' +- bus: ff + dev: '14' + fn: '1' + id: 6fb1 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 1 Thermal Control (rev 03)' +- bus: ff + dev: '14' + fn: '2' + id: 6fb2 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 0 Error (rev 03)' +- bus: ff + dev: '14' + fn: '3' + id: 6fb3 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 1 Error (rev 03)' +- bus: ff + dev: '14' + fn: '4' + id: 6fbc + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '5' + id: 6fbd + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '6' + id: 6fbe + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '7' + id: 6fbf + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '15' + fn: '0' + id: 6fb4 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 2 Thermal Control (rev 03)' +- bus: ff + dev: '15' + fn: '1' + id: 6fb5 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 3 Thermal Control (rev 03)' +- bus: ff + dev: '15' + fn: '2' + id: 6fb6 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 2 Error (rev 03)' +- bus: ff + dev: '15' + fn: '3' + id: 6fb7 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 3 Error (rev 03)' +- bus: ff + dev: 1e + fn: '0' + id: 6f98 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '1' + id: 6f99 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '2' + id: 6f9a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '3' + id: 6fc0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '4' + id: 6f9c + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1f + fn: '0' + id: 6f88 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1f + fn: '2' + id: 6f8a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/platform.json b/device/mellanox/x86_64-mlnx_msn4600c-r0/platform.json new file mode 100644 index 000000000000..7f9b9202b9b2 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/platform.json @@ -0,0 +1,388 @@ +{ + "interfaces": { + "Ethernet0": { + "index": "1,1,1,1", + "lanes": "0,1,2,3", + "alias_at_lanes": "etp1a, etp1b, etp1c, etp1d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet8": { + "index": "2,2,2,2", + "lanes": "8,9,10,11", + "alias_at_lanes": "etp2a, etp2b, etp2c, etp2d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet16": { + "index": "3,3,3,3", + "lanes": "16,17,18,19", + "alias_at_lanes": "etp3a, etp3b, etp3c, etp3d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet24": { + "index": "4,4,4,4", + "lanes": "24,25,26,27", + "alias_at_lanes": "etp4a, etp4b, etp4c, etp4d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet32": { + "index": "5,5,5,5", + "lanes": "32,33,34,35", + "alias_at_lanes": "etp5a, etp5b, etp5c, etp5d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet40": { + "index": "6,6,6,6", + "lanes": "40,41,42,43", + "alias_at_lanes": "etp6a, etp6b, etp6c, etp6d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet48": { + "index": "7,7,7,7", + "lanes": "48,49,50,51", + "alias_at_lanes": "etp7a, etp7b, etp7c, etp7d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet56": { + "index": "8,8,8,8", + "lanes": "56,57,58,59", + "alias_at_lanes": "etp8a, etp8b, etp8c, etp8d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet64": { + "index": "9,9,9,9", + "lanes": "64,65,66,67", + "alias_at_lanes": "etp9a, etp9b, etp9c, etp9d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet72": { + "index": "10,10,10,10", + "lanes": "72,73,74,75", + "alias_at_lanes": "etp10a, etp10b, etp10c, etp10d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet80": { + "index": "11,11,11,11", + "lanes": "80,81,82,83", + "alias_at_lanes": "etp11a, etp11b, etp11c, etp11d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet88": { + "index": "12,12,12,12", + "lanes": "88,89,90,91", + "alias_at_lanes": "etp12a, etp12b, etp12c, etp12d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet96": { + "index": "13,13,13,13", + "lanes": "96,97,98,99", + "alias_at_lanes": "etp13a, etp13b, etp13c, etp13d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet104": { + "index": "14,14,14,14", + "lanes": "104,105,106,107", + "alias_at_lanes": "etp14a, etp14b, etp14c, etp14d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet112": { + "index": "15,15,15,15", + "lanes": "112,113,114,115", + "alias_at_lanes": "etp15a, etp15b, etp15c, etp15d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet120": { + "index": "16,16,16,16", + "lanes": "120,121,122,123", + "alias_at_lanes": "etp16a, etp16b, etp16c, etp16d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet128": { + "index": "17,17,17,17", + "lanes": "128,129,130,131", + "alias_at_lanes": "etp17a, etp17b, etp17c, etp17d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet136": { + "index": "18,18,18,18", + "lanes": "136,137,138,139", + "alias_at_lanes": "etp18a, etp18b, etp18c, etp18d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet144": { + "index": "19,19,19,19", + "lanes": "144,145,146,147", + "alias_at_lanes": "etp19a, etp19b, etp19c, etp19d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet152": { + "index": "20,20,20,20", + "lanes": "152,153,154,155", + "alias_at_lanes": "etp20a, etp20b, etp20c, etp20d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet160": { + "index": "21,21,21,21", + "lanes": "160,161,162,163", + "alias_at_lanes": "etp21a, etp21b, etp21c, etp21d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet168": { + "index": "22,22,22,22", + "lanes": "168,169,170,171", + "alias_at_lanes": "etp22a, etp22b, etp22c, etp22d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet176": { + "index": "23,23,23,23", + "lanes": "176,177,178,179", + "alias_at_lanes": "etp23a, etp23b, etp23c, etp23d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet184": { + "index": "24,24,24,24", + "lanes": "184,185,186,187", + "alias_at_lanes": "etp24a, etp24b, etp24c, etp24d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet192": { + "index": "25,25,25,25", + "lanes": "192,193,194,195", + "alias_at_lanes": "etp25a, etp25b, etp25c, etp25d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet200": { + "index": "26,26,26,26", + "lanes": "200,201,202,203", + "alias_at_lanes": "etp26a, etp26b, etp26c, etp26d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet208": { + "index": "27,27,27,27", + "lanes": "208,209,210,211", + "alias_at_lanes": "etp27a, etp27b, etp27c, etp27d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet216": { + "index": "28,28,28,28", + "lanes": "216,217,218,219", + "alias_at_lanes": "etp28a, etp28b, etp28c, etp28d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet224": { + "index": "29,29,29,29", + "lanes": "224,225,226,227", + "alias_at_lanes": "etp29a, etp29b, etp29c, etp29d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet232": { + "index": "30,30,30,30", + "lanes": "232,233,234,235", + "alias_at_lanes": "etp30a, etp30b, etp30c, etp30d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet240": { + "index": "31,31,31,31", + "lanes": "240,241,242,243", + "alias_at_lanes": "etp31a, etp31b, etp31c, etp31d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet248": { + "index": "32,32,32,32", + "lanes": "248,249,250,251", + "alias_at_lanes": "etp32a, etp32b, etp32c, etp32d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet256": { + "index": "33,33,33,33", + "lanes": "256,257,258,259", + "alias_at_lanes": "etp33a, etp33b, etp33c, etp33d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet264": { + "index": "34,34,34,34", + "lanes": "264,265,266,267", + "alias_at_lanes": "etp34a, etp34b, etp34c, etp34d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet272": { + "index": "35,35,35,35", + "lanes": "272,273,274,275", + "alias_at_lanes": "etp35a, etp35b, etp35c, etp35d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet280": { + "index": "36,36,36,36", + "lanes": "280,281,282,283", + "alias_at_lanes": "etp36a, etp36b, etp36c, etp36d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet288": { + "index": "37,37,37,37", + "lanes": "288,289,290,291", + "alias_at_lanes": "etp37a, etp37b, etp37c, etp37d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet296": { + "index": "38,38,38,38", + "lanes": "296,297,298,299", + "alias_at_lanes": "etp38a, etp38b, etp38c, etp38d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet304": { + "index": "39,39,39,39", + "lanes": "304,305,306,307", + "alias_at_lanes": "etp39a, etp39b, etp39c, etp39d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet312": { + "index": "40,40,40,40", + "lanes": "312,313,314,315", + "alias_at_lanes": "etp40a, etp40b, etp40c, etp40d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet320": { + "index": "41,41,41,41", + "lanes": "320,321,322,323", + "alias_at_lanes": "etp41a, etp41b, etp41c, etp41d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet328": { + "index": "42,42,42,42", + "lanes": "328,329,330,331", + "alias_at_lanes": "etp42a, etp42b, etp42c, etp42d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet336": { + "index": "43,43,43,43", + "lanes": "336,337,338,339", + "alias_at_lanes": "etp43a, etp43b, etp43c, etp43d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet344": { + "index": "44,44,44,44", + "lanes": "344,345,346,347", + "alias_at_lanes": "etp44a, etp44b, etp44c, etp44d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet352": { + "index": "45,45,45,45", + "lanes": "352,353,354,355", + "alias_at_lanes": "etp45a, etp45b, etp45c, etp45d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet360": { + "index": "46,46,46,46", + "lanes": "360,361,362,363", + "alias_at_lanes": "etp46a, etp46b, etp46c, etp46d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet368": { + "index": "47,47,47,47", + "lanes": "368,369,370,371", + "alias_at_lanes": "etp47a, etp47b, etp47c, etp47d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet376": { + "index": "48,48,48,48", + "lanes": "376,377,378,379", + "alias_at_lanes": "etp48a, etp48b, etp48c, etp48d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet384": { + "index": "49,49,49,49", + "lanes": "384,385,386,387", + "alias_at_lanes": "etp49a, etp49b, etp49c, etp49d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet392": { + "index": "50,50,50,50", + "lanes": "392,393,394,395", + "alias_at_lanes": "etp50a, etp50b, etp50c, etp50d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet400": { + "index": "51,51,51,51", + "lanes": "400,401,402,403", + "alias_at_lanes": "etp51a, etp51b, etp51c, etp51d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet408": { + "index": "52,52,52,52", + "lanes": "408,409,410,411", + "alias_at_lanes": "etp52a, etp52b, etp52c, etp52d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet416": { + "index": "53,53,53,53", + "lanes": "416,417,418,419", + "alias_at_lanes": "etp53a, etp53b, etp53c, etp53d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet424": { + "index": "54,54,54,54", + "lanes": "424,425,426,427", + "alias_at_lanes": "etp54a, etp54b, etp54c, etp54d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet432": { + "index": "55,55,55,55", + "lanes": "432,433,434,435", + "alias_at_lanes": "etp55a, etp55b, etp55c, etp55d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet440": { + "index": "56,56,56,56", + "lanes": "440,441,442,443", + "alias_at_lanes": "etp56a, etp56b, etp56c, etp56d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet448": { + "index": "57,57,57,57", + "lanes": "448,449,450,451", + "alias_at_lanes": "etp57a, etp57b, etp57c, etp57d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet456": { + "index": "58,58,58,58", + "lanes": "456,457,458,459", + "alias_at_lanes": "etp58a, etp58b, etp58c, etp58d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet464": { + "index": "59,59,59,59", + "lanes": "464,465,466,467", + "alias_at_lanes": "etp59a, etp59b, etp59c, etp59d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet472": { + "index": "60,60,60,60", + "lanes": "472,473,474,475", + "alias_at_lanes": "etp60a, etp60b, etp60c, etp60d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet480": { + "index": "61,61,61,61", + "lanes": "480,481,482,483", + "alias_at_lanes": "etp61a, etp61b, etp61c, etp61d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet488": { + "index": "62,62,62,62", + "lanes": "488,489,490,491", + "alias_at_lanes": "etp62a, etp62b, etp62c, etp62d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet496": { + "index": "63,63,63,63", + "lanes": "496,497,498,499", + "alias_at_lanes": "etp63a, etp63b, etp63c, etp63d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + }, + "Ethernet504": { + "index": "64,64,64,64", + "lanes": "504,505,506,507", + "alias_at_lanes": "etp64a, etp64b, etp64c, etp64d", + "breakout_modes": "1x100G[50G,40G,25G,10G,1G],2x50G[40G,25G,10G,1G]" + } + } +} \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_components.json new file mode 100644 index 000000000000..22bcfcc29700 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_components.json @@ -0,0 +1,14 @@ +{ + "chassis": { + "MSN4600C": { + "component": { + "ONIE": { }, + "SSD": { }, + "BIOS": { }, + "CPLD1": { }, + "CPLD2": { }, + "CPLD3": { } + } + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_reboot b/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_reboot new file mode 120000 index 000000000000..43c8ea567493 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-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_msn4600c-r0/platform_wait b/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_wait new file mode 120000 index 000000000000..4b30bd429854 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-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_msn4600c-r0/plugins/eeprom.py b/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/eeprom.py new file mode 120000 index 000000000000..b4e2a6a61671 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-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_msn4600c-r0/plugins/psuutil.py b/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/psuutil.py new file mode 120000 index 000000000000..9f724238a8d5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-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_msn4600c-r0/plugins/sfplpmget.py b/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfplpmget.py new file mode 120000 index 000000000000..2e84f435abd9 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-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_msn4600c-r0/plugins/sfplpmset.py b/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfplpmset.py new file mode 120000 index 000000000000..6a88bac30467 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-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_msn4600c-r0/plugins/sfpreset.py b/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfpreset.py new file mode 120000 index 000000000000..fef2063e3496 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-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_msn4600c-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfputil.py new file mode 120000 index 000000000000..45909b880fc9 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-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_msn4600c-r0/pmon_daemon_control.json b/device/mellanox/x86_64-mlnx_msn4600c-r0/pmon_daemon_control.json new file mode 120000 index 000000000000..435a2ce7c0ba --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-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_msn4600c-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn4600c-r0/sensors.conf new file mode 100644 index 000000000000..9c80350e19ad --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/sensors.conf @@ -0,0 +1,189 @@ +################################################################################ +# Copyright (c) 2020 Mellanox Technologies +# +# Platform specific sensors config for SN4600C +################################################################################ + +# 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 "xdpe12284-i2c-*-62" + label in1 "PMIC-1 PSU 12V Rail (in)" + ignore in2 + label in3 "PMIC-1 ASIC 0.8V VCORE_MAIN Rail (out)" + ignore in4 + label temp1 "PMIC-1 Temp 1" + label temp2 "PMIC-1 Temp 2" + label power1 "PMIC-1 ASIC 12V VCORE_MAIN Rail Pwr (in)" + ignore power2 + label power3 "PMIC-1 ASIC 0.8V VCORE_MAIN Rail Pwr (out)" + ignore power4 + label curr1 "PMIC-1 ASIC 12V VCORE_MAIN Rail Curr (in)" + ignore curr2 + label curr3 "PMIC-1 ASIC 0.8V VCORE_MAIN Rail Curr (out)" + ignore curr4 + chip "xdpe12284-i2c-*-64" + label in1 "PMIC-2 PSU 12V Rail_1 (in)" + label in2 "PMIC-2 PSU 12V Rail_2 (in)" + label in3 "PMIC-2 ASIC 1.8V Rail_1 (out)" + label in4 "PMIC-2 ASIC 1.2V Rail_2 (out)" + label temp1 "PMIC-2 Temp 1" + label temp2 "PMIC-2 Temp 2" + label power1 "PMIC-2 ASIC 12V Rail_1 Pwr (in)" + label power2 "PMIC-2 ASIC 12V Rail_2 Pwr (in)" + label power3 "PMIC-2 ASIC 1.8V Rail_1 Pwr (out)" + label power4 "PMIC-2 ASIC 1.2V Rail_2 Pwr (out)" + label curr1 "PMIC-2 ASIC 12V Rail_1 Curr (in)" + label curr2 "PMIC-2 ASIC 12V Rail_2 Curr (in)" + label curr3 "PMIC-2 ASIC 1.8V Rail_1 Curr (out)" + label curr4 "PMIC-2 ASIC 1.2V Rail_2 Curr (out)" + chip "xdpe12284-i2c-*-66" + label in1 "PMIC-3 PSU 12V Rail_1 (in)" + label in2 "PMIC-3 PSU 12V Rail_2 (in)" + label in3 "PMIC-3 ASIC 0.85V Rail_1 T0_1 (out)" + label in4 "PMIC-3 ASIC 1.8V Rail_2 T0_1 (out)" + label temp1 "PMIC-3 Temp 1" + label temp2 "PMIC-3 Temp 2" + label power1 "PMIC-3 ASIC 12V Rail_1 Pwr (in)" + label power2 "PMIC-3 ASIC 12V Rail_2 Pwr (in)" + label power3 "PMIC-3 ASIC 0.85V Rail_1 T0_1 Pwr (out)" + label power4 "PMIC-3 ASIC 1.8V Rail_2 T0_1 Pwr (out)" + label curr1 "PMIC-3 ASIC 12V Rail_1 Curr (in)" + label curr2 "PMIC-3 ASIC 12V Rail_2 Curr (in)" + label curr3 "PMIC-3 ASIC 0.85V Rail_1 T0_1 Curr (out)" + label curr4 "PMIC-3 ASIC 1.8V Rail_2 T0_1 Curr (out)" + chip "xdpe12284-i2c-*-68" + label in1 "PMIC-4 PSU 12V Rail_1 (in)" + label in2 "PMIC-4 PSU 12V Rail_2 (in)" + label in3 "PMIC-4 ASIC 0.85V Rail_1 T2_3 (out)" + label in4 "PMIC-4 ASIC 1.8V Rail_2 T2_3 (out)" + label temp1 "PMIC-4 Temp 1" + label temp2 "PMIC-4 Temp 2" + label power1 "PMIC-4 ASIC 12V Rail_1 Pwr (in)" + label power2 "PMIC-4 ASIC 12V Rail_2 Pwr (in)" + label power3 "PMIC-4 ASIC 0.85V Rail_1 T2_3 Pwr (out)" + label power4 "PMIC-4 ASIC 1.8V Rail_2 T2_3 Pwr (out)" + label curr1 "PMIC-4 ASIC 12V Rail_1 Curr (in)" + label curr2 "PMIC-4 ASIC 12V Rail_2 Curr (in)" + label curr3 "PMIC-4 ASIC 0.85V Rail_1 T2_3 Curr (out)" + label curr4 "PMIC-4 ASIC 1.8V Rail_2 T2_3 Curr (out)" + chip "xdpe12284-i2c-*-6a" + label in1 "PMIC-5 PSU 12V Rail_1 (in)" + label in2 "PMIC-5 PSU 12V Rail_2 (in)" + label in3 "PMIC-5 ASIC 0.85V Rail_1 T4_5 (out)" + label in4 "PMIC-5 ASIC 1.8V Rail_2 T4_5 (out)" + label temp1 "PMIC-5 Temp 1" + label temp2 "PMIC-5 Temp 2" + label power1 "PMIC-5 ASIC 12V Rail_1 Pwr (in)" + label power2 "PMIC-5 ASIC 12V Rail_2 Pwr (in)" + label power3 "PMIC-5 ASIC 0.85V Rail_1 T4_5 Pwr (out)" + label power4 "PMIC-5 ASIC 1.8V Rail_2 T4_5 Pwr (out)" + label curr1 "PMIC-5 ASIC 12V Rail_1 Curr (in)" + label curr2 "PMIC-5 ASIC 12V Rail_2 Curr (in)" + label curr3 "PMIC-5 ASIC 0.85V Rail_1 T4_5 Curr (out)" + label curr4 "PMIC-5 ASIC 1.8V Rail_2 T4_5 Curr (out)" + chip "xdpe12284-i2c-*-6c" + label in1 "PMIC-6 PSU 12V Rail_1 (in)" + label in2 "PMIC-6 PSU 12V Rail_2 (in)" + label in3 "PMIC-6 ASIC 0.85V Rail_1 T6_7 (out)" + label in4 "PMIC-6 ASIC 1.8V Rail_2 T6_7 (out)" + label temp1 "PMIC-6 Temp 1" + label temp2 "PMIC-6 Temp 2" + label power1 "PMIC-6 ASIC 12V Rail_1 Pwr (in)" + label power2 "PMIC-6 ASIC 12V Rail_2 Pwr (in)" + label power3 "PMIC-6 ASIC 0.85V Rail_1 T6_7 Pwr (out)" + label power4 "PMIC-6 ASIC 1.8V Rail_2 T6_7 Pwr (out)" + label curr1 "PMIC-6 ASIC 12V Rail_1 Curr (in)" + label curr2 "PMIC-6 ASIC 12V Rail_2 Curr (in)" + label curr3 "PMIC-6 ASIC 0.85V Rail_1 T6_7 Curr (out)" + label curr4 "PMIC-6 ASIC 1.8V Rail_2 T6_7 Curr (out)" + chip "xdpe12284-i2c-*-6e" + label in1 "PMIC-7 PSU 12V Rail_1 (in)" + label in2 "PMIC-7 PSU 12V Rail_2 (in)" + label in3 "PMIC-7 ASIC 1.2V Rail_1 T0_3 (out)" + label in4 "PMIC-7 ASIC 1.2V Rail_2 T4_7 (out)" + label temp1 "PMIC-7 Temp 1" + label temp2 "PMIC-7 Temp 2" + label power1 "PMIC-7 ASIC 12V Rail_1 Pwr (in)" + label power2 "PMIC-7 ASIC 12V Rail_2 Pwr (in)" + label power3 "PMIC-7 ASIC 1.2V Rail_1 T0_3 Pwr (out)" + label power4 "PMIC-7 ASIC 1.2V Rail_2 T4_7 Pwr (out)" + label curr1 "PMIC-7 ASIC 12V Rail_1 Curr (in)" + label curr2 "PMIC-7 ASIC 12V Rail_2 Curr (in)" + label curr3 "PMIC-7 ASIC 1.2V Rail_1 T0_3 Curr (out)" + label curr4 "PMIC-7 ASIC 1.2V Rail_2 T4_7 Curr (out)" + +bus "i2c-15" "i2c-1-mux (chan_id 6)" + chip "tps53679-i2c-*-58" + label in1 "PMIC-8 PSU 12V Rail (in1)" + label in2 "PMIC-8 PSU 12V Rail (in2)" + label in3 "PMIC-8 COMEX 1.8V Rail (out)" + label in4 "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 (in1)" + label in2 "PMIC-9 PSU 12V Rail (in2)" + label in3 "PMIC-9 COMEX 1.2V Rail (out)" + ignore in4 + 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" + ignore fan2 + ignore fan3 + 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" + ignore fan2 + ignore fan3 + 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" + label fan2 "Chassis Fan Drawer-2" + label fan3 "Chassis Fan Drawer-3" diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_msn4600c-r0/system_health_monitoring_config.json new file mode 120000 index 000000000000..98df66c27ca5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/thermal_policy.json b/device/mellanox/x86_64-mlnx_msn4600c-r0/thermal_policy.json new file mode 120000 index 000000000000..5a25cd87f70c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/thermal_policy.json \ No newline at end of file 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..c115d141e152 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_defaults_t0.j2 @@ -0,0 +1,112 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '26451968' %} +{% set ingress_lossy_pool_size = '26451968' %} +{% set egress_lossless_pool_size = '60817392' %} +{% set egress_lossy_pool_size = '26451968' %} + +{%- 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": { + {%- if dynamic_mode is not defined %} + "size": "{{ ingress_lossless_pool_size }}", + {%- endif %} + "type": "ingress", + "mode": "dynamic" + }, + "ingress_lossy_pool": { + {%- if dynamic_mode is not defined %} + "size": "{{ ingress_lossy_pool_size }}", + {%- endif %} + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + {%- if dynamic_mode is not defined %} + "size": "{{ egress_lossy_pool_size }}", + {%- endif %} + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "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":"9216", + "dynamic_th":"7" + }, + "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..0550c6dd3103 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_defaults_t1.j2 @@ -0,0 +1,112 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '20627456' %} +{% set ingress_lossy_pool_size = '20627456' %} +{% set egress_lossless_pool_size = '60817392' %} +{% set egress_lossy_pool_size = '20627456' %} + +{%- 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": { + {%- if dynamic_mode is not defined %} + "size": "{{ ingress_lossless_pool_size }}", + {%- endif %} + "type": "ingress", + "mode": "dynamic" + }, + "ingress_lossy_pool": { + {%- if dynamic_mode is not defined %} + "size": "{{ ingress_lossy_pool_size }}", + {%- endif %} + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + {%- if dynamic_mode is not defined %} + "size": "{{ egress_lossy_pool_size }}", + {%- endif %} + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "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":"9216", + "dynamic_th":"7" + }, + "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_dynamic.json.j2 b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_dynamic.json.j2 new file mode 120000 index 000000000000..8c4117c66214 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_dynamic.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_dynamic.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/hwsku.json b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/hwsku.json new file mode 100644 index 000000000000..c226252e525e --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/hwsku.json @@ -0,0 +1,100 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet8": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet16": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet24": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet32": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet40": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet48": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet56": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet64": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet72": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet80": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet88": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet96": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet104": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet112": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet120": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet128": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet136": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet144": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet152": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet160": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet168": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet176": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet184": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet192": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet200": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet208": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet216": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet224": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet232": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet240": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + }, + "Ethernet248": { + "default_brkout_mode": "1x400G[200G,100G,50G,40G,25G,10G,1G]" + } + } +} 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..1fb3f9c328c9 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/pg_profile_lookup.ini @@ -0,0 +1,23 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 10000 5m 52224 19456 32768 0 + 25000 5m 52224 19456 32768 0 + 40000 5m 53248 19456 33792 0 + 50000 5m 53248 19456 33792 0 + 100000 5m 53248 19456 33792 0 + 200000 5m 55296 19456 35840 0 + 400000 5m 86016 37888 38912 0 + 10000 40m 53248 19456 33792 0 + 25000 40m 55296 19456 35840 0 + 40000 40m 57344 19456 37888 0 + 50000 40m 58368 19456 38912 0 + 100000 40m 63488 19456 44032 0 + 200000 40m 74752 19456 55296 0 + 400000 40m 124928 37888 77824 0 + 10000 300m 60416 19456 40960 0 + 25000 300m 73728 19456 54272 0 + 40000 300m 86016 19456 66560 0 + 50000 300m 95232 19456 75776 0 + 100000 300m 137216 19456 117760 0 + 200000 300m 223232 19456 203776 0 + 400000 300m 420864 37888 373760 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..ea7219932624 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias index +Ethernet0 0,1,2,3,4,5,6,7 etp1 1 +Ethernet8 8,9,10,11,12,13,14,15 etp2 2 +Ethernet16 16,17,18,19,20,21,22,23 etp3 3 +Ethernet24 24,25,26,27,28,29,30,31 etp4 4 +Ethernet32 32,33,34,35,36,37,38,39 etp5 5 +Ethernet40 40,41,42,43,44,45,46,47 etp6 6 +Ethernet48 48,49,50,51,52,53,54,55 etp7 7 +Ethernet56 56,57,58,59,60,61,62,63 etp8 8 +Ethernet64 64,65,66,67,68,69,70,71 etp9 9 +Ethernet72 72,73,74,75,76,77,78,79 etp10 10 +Ethernet80 80,81,82,83,84,85,86,87 etp11 11 +Ethernet88 88,89,90,91,92,93,94,95 etp12 12 +Ethernet96 96,97,98,99,100,101,102,103 etp13 13 +Ethernet104 104,105,106,107,108,109,110,111 etp14 14 +Ethernet112 112,113,114,115,116,117,118,119 etp15 15 +Ethernet120 120,121,122,123,124,125,126,127 etp16 16 +Ethernet128 128,129,130,131,132,133,134,135 etp17 17 +Ethernet136 136,137,138,139,140,141,142,143 etp18 18 +Ethernet144 144,145,146,147,148,149,150,151 etp19 19 +Ethernet152 152,153,154,155,156,157,158,159 etp20 20 +Ethernet160 160,161,162,163,164,165,166,167 etp21 21 +Ethernet168 168,169,170,171,172,173,174,175 etp22 22 +Ethernet176 176,177,178,179,180,181,182,183 etp23 23 +Ethernet184 184,185,186,187,188,189,190,191 etp24 24 +Ethernet192 192,193,194,195,196,197,198,199 etp25 25 +Ethernet200 200,201,202,203,204,205,206,207 etp26 26 +Ethernet208 208,209,210,211,212,213,214,215 etp27 27 +Ethernet216 216,217,218,219,220,221,222,223 etp28 28 +Ethernet224 224,225,226,227,228,229,230,231 etp29 29 +Ethernet232 232,233,234,235,236,237,238,239 etp30 30 +Ethernet240 240,241,242,243,244,245,246,247 etp31 31 +Ethernet248 248,249,250,251,252,253,254,255 etp32 32 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..d145093cab96 --- /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.xml diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700.xml b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700.xml new file mode 100644 index 000000000000..e3d0e4ea723d --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700.xml @@ -0,0 +1,247 @@ + + + + + + 00:02:03:04:05:00 + + + 1 + + + 32 + + + + + 1 + 8 + 17 + 3 + 1536 + + + 5 + 8 + 16 + 3 + 1536 + + + 9 + 8 + 19 + 3 + 1536 + + + 13 + 8 + 18 + 3 + 1536 + + + 17 + 8 + 21 + 3 + 1536 + + + 21 + 8 + 20 + 3 + 1536 + + + 25 + 8 + 23 + 3 + 1536 + + + 29 + 8 + 22 + 3 + 1536 + + + 33 + 8 + 29 + 3 + 1536 + + + 37 + 8 + 28 + 3 + 1536 + + + 41 + 8 + 31 + 3 + 1536 + + + 45 + 8 + 30 + 3 + 1536 + + + 49 + 8 + 25 + 3 + 1536 + + + 53 + 8 + 24 + 3 + 1536 + + + 57 + 8 + 27 + 3 + 1536 + + + 61 + 8 + 26 + 3 + 1536 + + + 65 + 8 + 14 + 3 + 1536 + + + 69 + 8 + 15 + 3 + 1536 + + + 73 + 8 + 12 + 3 + 1536 + + + 77 + 8 + 13 + 3 + 1536 + + + 81 + 8 + 10 + 3 + 1536 + + + 85 + 8 + 11 + 3 + 1536 + + + 89 + 8 + 8 + 3 + 1536 + + + 93 + 8 + 9 + 3 + 1536 + + + 97 + 8 + 2 + 3 + 1536 + + + 101 + 8 + 3 + 3 + 1536 + + + 105 + 8 + 0 + + + 3 + + + 1536 + + + 109 + 8 + 1 + 3 + 1536 + + + 113 + 8 + 6 + 3 + 1536 + + + 117 + 8 + 7 + 3 + 1536 + + + 121 + 8 + 4 + 3 + 1536 + + + 125 + 8 + 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/pcie.yaml b/device/mellanox/x86_64-mlnx_msn4700-r0/pcie.yaml new file mode 120000 index 000000000000..187649f4b860 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/pcie.yaml @@ -0,0 +1 @@ +../x86_64-mlnx_msn4600c-r0/pcie.yaml \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/platform.json b/device/mellanox/x86_64-mlnx_msn4700-r0/platform.json new file mode 100644 index 000000000000..750fc49f6e33 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/platform.json @@ -0,0 +1,196 @@ +{ + "interfaces": { + "Ethernet0": { + "index": "1,1,1,1,1,1,1,1", + "lanes": "0,1,2,3,4,5,6,7", + "alias_at_lanes": "etp1a, etp1b, etp1c, etp1d, etp1e, etp1f, etp1g, etp1h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet8": { + "index": "2,2,2,2,2,2,2,2", + "lanes": "8,9,10,11,12,13,14,15", + "alias_at_lanes": "etp2a, etp2b, etp2c, etp2d, etp2e, etp2f, etp2g, etp2h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet16": { + "index": "3,3,3,3,3,3,3,3", + "lanes": "16,17,18,19,20,21,22,23", + "alias_at_lanes": "etp3a, etp3b, etp3c, etp3d, etp3e, etp3f, etp3g, etp3h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet24": { + "index": "4,4,4,4,4,4,4,4", + "lanes": "24,25,26,27,28,29,30,31", + "alias_at_lanes": "etp4a, etp4b, etp4c, etp4d, etp4e, etp4f, etp4g, etp4h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet32": { + "index": "5,5,5,5,5,5,5,5", + "lanes": "32,33,34,35,36,37,38,39", + "alias_at_lanes": "etp5a, etp5b, etp5c, etp5d, etp5e, etp5f, etp5g, etp5h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet40": { + "index": "6,6,6,6,6,6,6,6", + "lanes": "40,41,42,43,44,45,46,47", + "alias_at_lanes": "etp6a, etp6b, etp6c, etp6d, etp6e, etp6f, etp6g, etp6h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet48": { + "index": "7,7,7,7,7,7,7,7", + "lanes": "48,49,50,51,52,53,54,55", + "alias_at_lanes": "etp7a, etp7b, etp7c, etp7d, etp7e, etp7f, etp7g, etp7h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet56": { + "index": "8,8,8,8,8,8,8,8", + "lanes": "56,57,58,59,60,61,62,63", + "alias_at_lanes": "etp8a, etp8b, etp8c, etp8d, etp8e, etp8f, etp8g, etp8h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet64": { + "index": "9,9,9,9,9,9,9,9", + "lanes": "64,65,66,67,68,69,70,71", + "alias_at_lanes": "etp9a, etp9b, etp9c, etp9d, etp9e, etp9f, etp9g, etp9h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet72": { + "index": "10,10,10,10,10,10,10,10", + "lanes": "72,73,74,75,76,77,78,79", + "alias_at_lanes": "etp10a, etp10b, etp10c, etp10d, etp10e, etp10f, etp10g, etp10h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet80": { + "index": "11,11,11,11,11,11,11,11", + "lanes": "80,81,82,83,84,85,86,87", + "alias_at_lanes": "etp11a, etp11b, etp11c, etp11d, etp11e, etp11f, etp11g, etp11h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet88": { + "index": "12,12,12,12,12,12,12,12", + "lanes": "88,89,90,91,92,93,94,95", + "alias_at_lanes": "etp12a, etp12b, etp12c, etp12d, etp12e, etp12f, etp12g, etp12h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet96": { + "index": "13,13,13,13,13,13,13,13", + "lanes": "96,97,98,99,100,101,102,103", + "alias_at_lanes": "etp13a, etp13b, etp13c, etp13d, etp13e, etp13f, etp13g, etp13h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet104": { + "index": "14,14,14,14,14,14,14,14", + "lanes": "104,105,106,107,108,109,110,111", + "alias_at_lanes": "etp14a, etp14b, etp14c, etp14d, etp14e, etp14f, etp14g, etp14h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet112": { + "index": "15,15,15,15,15,15,15,15", + "lanes": "112,113,114,115,116,117,118,119", + "alias_at_lanes": "etp15a, etp15b, etp15c, etp15d, etp15e, etp15f, etp15g, etp15h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet120": { + "index": "16,16,16,16,16,16,16,16", + "lanes": "120,121,122,123,124,125,126,127", + "alias_at_lanes": "etp16a, etp16b, etp16c, etp16d, etp16e, etp16f, etp16g, etp16h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet128": { + "index": "17,17,17,17,17,17,17,17", + "lanes": "128,129,130,131,132,133,134,135", + "alias_at_lanes": "etp17a, etp17b, etp17c, etp17d, etp17e, etp17f, etp17g, etp17h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet136": { + "index": "18,18,18,18,18,18,18,18", + "lanes": "136,137,138,139,140,141,142,143", + "alias_at_lanes": "etp18a, etp18b, etp18c, etp18d, etp18e, etp18f, etp18g, etp18h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet144": { + "index": "19,19,19,19,19,19,19,19", + "lanes": "144,145,146,147,148,149,150,151", + "alias_at_lanes": "etp19a, etp19b, etp19c, etp19d, etp19e, etp19f, etp19g, etp19h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet152": { + "index": "20,20,20,20,20,20,20,20", + "lanes": "152,153,154,155,156,157,158,159", + "alias_at_lanes": "etp20a, etp20b, etp20c, etp20d, etp20e, etp20f, etp20g, etp20h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet160": { + "index": "21,21,21,21,21,21,21,21", + "lanes": "160,161,162,163,164,165,166,167", + "alias_at_lanes": "etp21a, etp21b, etp21c, etp21d, etp21e, etp21f, etp21g, etp21h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet168": { + "index": "22,22,22,22,22,22,22,22", + "lanes": "168,169,170,171,172,173,174,175", + "alias_at_lanes": "etp22a, etp22b, etp22c, etp22d, etp22e, etp22f, etp22g, etp22h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet176": { + "index": "23,23,23,23,23,23,23,23", + "lanes": "176,177,178,179,180,181,182,183", + "alias_at_lanes": "etp23a, etp23b, etp23c, etp23d, etp23e, etp23f, etp23g, etp23h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet184": { + "index": "24,24,24,24,24,24,24,24", + "lanes": "184,185,186,187,188,189,190,191", + "alias_at_lanes": "etp24a, etp24b, etp24c, etp24d, etp24e, etp24f, etp24g, etp24h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet192": { + "index": "25,25,25,25,25,25,25,25", + "lanes": "192,193,194,195,196,197,198,199", + "alias_at_lanes": "etp25a, etp25b, etp25c, etp25d, etp25e, etp25f, etp25g, etp25h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet200": { + "index": "26,26,26,26,26,26,26,26", + "lanes": "200,201,202,203,204,205,206,207", + "alias_at_lanes": "etp26a, etp26b, etp26c, etp26d, etp26e, etp26f, etp26g, etp26h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet208": { + "index": "27,27,27,27,27,27,27,27", + "lanes": "208,209,210,211,212,213,214,215", + "alias_at_lanes": "etp27a, etp27b, etp27c, etp27d, etp27e, etp27f, etp27g, etp27h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet216": { + "index": "28,28,28,28,28,28,28,28", + "lanes": "216,217,218,219,220,221,222,223", + "alias_at_lanes": "etp28a, etp28b, etp28c, etp28d, etp28e, etp28f, etp28g, etp28h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet224": { + "index": "29,29,29,29,29,29,29,29", + "lanes": "224,225,226,227,228,229,230,231", + "alias_at_lanes": "etp29a, etp29b, etp29c, etp29d, etp29e, etp29f, etp29g, etp29h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet232": { + "index": "30,30,30,30,30,30,30,30", + "lanes": "232,233,234,235,236,237,238,239", + "alias_at_lanes": "etp30a, etp30b, etp30c, etp30d, etp30e, etp30f, etp30g, etp30h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet240": { + "index": "31,31,31,31,31,31,31,31", + "lanes": "240,241,242,243,244,245,246,247", + "alias_at_lanes": "etp31a, etp31b, etp31c, etp31d, etp31e, etp31f, etp31g, etp31h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + }, + "Ethernet248": { + "index": "32,32,32,32,32,32,32,32", + "lanes": "248,249,250,251,252,253,254,255", + "alias_at_lanes": "etp32a, etp32b, etp32c, etp32d, etp32e, etp32f, etp32g, etp32h", + "breakout_modes": "1x400G[200G,100G,50G,40G,25G,10G,1G],2x200G[100G,50G,40G,25G,10G,1G],4x100G[50G,40G,25G,10G,1G]" + } + } +} \ No newline at end of file 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..c663b782187e --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/platform_components.json @@ -0,0 +1,14 @@ +{ + "chassis": { + "MSN4700": { + "component": { + "ONIE": { }, + "SSD": { }, + "BIOS": { }, + "CPLD1": { }, + "CPLD2": { }, + "CPLD3": { } + } + } + } +} 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..3b19dc80c6ce --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/sensors.conf @@ -0,0 +1,198 @@ +################################################################################ +# 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 "xdpe12284-i2c-*-62" + label in1 "PMIC-1 PSU 12V Rail (in1)" + label in2 "PMIC-1 PSU 12V Rail (in2)" + label in3 "PMIC-1 ASIC 0.8V VCORE MAIN Rail (out)" + ignore in4 + label temp1 "PMIC-1 Temp 1" + label temp2 "PMIC-1 Temp 2" + label power1 "PMIC-1 PSU 12V Rail Pwr (in1)" + label power2 "PMIC-1 PSU 12V Rail Pwr (in2)" + label power3 "PMIC-1 ASIC 0.8V VCORE MAIN Rail Pwr (out)" + ignore power4 + label curr1 "PMIC-1 PSU 12V Rail Curr (in1)" + label curr2 "PMIC-1 PSU 12V Rail Curr (in2)" + label curr3 "PMIC-1 ASIC 0.8V VCORE MAIN Rail Curr (out)" + ignore curr4 + chip "xdpe12284-i2c-*-64" + label in1 "PMIC-2 PSU 12V Rail (in1)" + label in2 "PMIC-2 PSU 12V Rail (in2)" + label in3 "PMIC-2 ASIC 1.8V VCORE MAIN Rail (out)" + label in4 "PMIC-2 ASIC 1.2V VCORE MAIN Rail (out)" + label temp1 "PMIC-2 Temp 1" + label temp2 "PMIC-2 Temp 2" + label power1 "PMIC-2 PSU 12V Rail Pwr (in1)" + label power2 "PMIC-2 PSU 12V Rail Pwr (in2)" + label power3 "PMIC-2 ASIC 1.8V VCORE MAIN Rail Pwr (out)" + label power4 "PMIC-2 ASIC 1.2V VCORE MAIN Rail Pwr (out)" + label curr1 "PMIC-2 PSU 12V Rail Curr (in1)" + label curr2 "PMIC-2 PSU 12V Rail Curr (in2)" + label curr3 "PMIC-2 ASIC 1.8V VCORE MAIN Rail Curr (out)" + label curr4 "PMIC-2 ASIC 1.2V VCORE MAIN Rail Curr (out)" + chip "xdpe12284-i2c-*-66" + label in1 "PMIC-3 PSU 12V Rail (in1)" + label in2 "PMIC-3 PSU 12V Rail (in2)" + label in3 "PMIC-3 ASIC 0.85V T0_1 Rail (out)" + label in4 "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 PSU 12V Rail Pwr (in1)" + label power2 "PMIC-3 PSU 12V Rail Pwr (in2)" + label power3 "PMIC-3 ASIC 0.85V T0_1 Rail Pwr (out)" + label power4 "PMIC-3 ASIC 1.8V T0_1 Rail Pwr (out)" + label curr1 "PMIC-3 PSU 12V Rail Curr (in1)" + label curr2 "PMIC-3 PSU 12V Rail Curr (in2)" + label curr3 "PMIC-3 ASIC 0.85V T0_1 Rail Curr (out)" + label curr4 "PMIC-3 ASIC 1.8V T0_1 Rail Curr (out)" + chip "xdpe12284-i2c-*-68" + label in1 "PMIC-4 PSU 12V Rail (in1)" + label in2 "PMIC-4 PSU 12V Rail (in2)" + label in3 "PMIC-4 ASIC 0.85V T2_3 Rail (out)" + label in4 "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 PSU 12V Rail Pwr (in1)" + label power2 "PMIC-4 PSU 12V Rail Pwr (in2)" + label power3 "PMIC-4 ASIC 0.85V T2_3 Rail Pwr (out)" + label power4 "PMIC-4 ASIC 1.8V T2_3 Rail Pwr (out)" + label curr1 "PMIC-4 PSU 12V Rail Curr (in1)" + label curr2 "PMIC-4 PSU 12V Rail Curr (in2)" + label curr3 "PMIC-4 ASIC 0.85V T2_3 Rail Curr (out)" + label curr4 "PMIC-4 ASIC 1.8V T2_3 Rail Curr (out)" + chip "xdpe12284-i2c-*-6a" + label in1 "PMIC-5 PSU 12V Rail (in1)" + label in2 "PMIC-5 PSU 12V Rail (in2)" + label in3 "PMIC-5 ASIC 0.85V T4_5 Rail (out)" + label in4 "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 PSU 12V Rail Pwr (in1)" + label power2 "PMIC-5 PSU 12V Rail Pwr (in2)" + label power3 "PMIC-5 ASIC 0.85V T4_5 Rail Pwr (out)" + label power4 "PMIC-5 ASIC 1.8V T4_5 Rail Pwr (out)" + label curr1 "PMIC-5 PSU 12V Rail Curr (in1)" + label curr2 "PMIC-5 PSU 12V Rail Curr (in2)" + label curr3 "PMIC-5 ASIC 0.85V T4_5 Rail Curr (out)" + label curr4 "PMIC-5 ASIC 1.8V T4_5 Rail Curr (out)" + chip "xdpe12284-i2c-*-6c" + label in1 "PMIC-6 PSU 12V Rail (in1)" + label in2 "PMIC-6 PSU 12V Rail (in2)" + label in3 "PMIC-6 ASIC 0.85V T6_7 Rail (out)" + label in4 "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 PSU 12V Rail Pwr (in1)" + label power2 "PMIC-6 PSU 12V Rail Pwr (in2)" + label power3 "PMIC-6 ASIC 0.85V T6_7 Rail Pwr (out)" + label power4 "PMIC-6 ASIC 1.8V T6_7 Rail Pwr (out)" + label curr1 "PMIC-6 PSU 12V Rail Curr (in1)" + label curr2 "PMIC-6 PSU 12V Rail Curr (in2)" + label curr3 "PMIC-6 ASIC 0.85V T6_7 Rail Curr (out)" + label curr4 "PMIC-6 ASIC 1.8V T6_7 Rail Curr (out)" + chip "xdpe12284-i2c-*-6e" + label in1 "PMIC-7 PSU 12V Rail (in1)" + label in2 "PMIC-7 PSU 12V Rail (in2)" + label in3 "PMIC-7 ASIC 1.2V T0_3 Rail_1 (out)" + label in4 "PMIC-7 ASIC 1.2V T4_7 Rail_2 (out)" + label temp1 "PMIC-7 Temp 1" + label temp2 "PMIC-7 Temp 2" + label power1 "PMIC-7 PSU 12V Rail Pwr (in1)" + label power2 "PMIC-7 PSU 12V Rail Pwr (in2)" + label power3 "PMIC-7 ASIC 1.2V T0_3 Rail_1 Pwr (out)" + label power4 "PMIC-7 ASIC 1.2V T4_7 Rail_2 Pwr (out)" + label curr1 "PMIC-7 PSU 12V Rail Curr (in1)" + label curr2 "PMIC-7 PSU 12V Rail Curr (in2)" + label curr3 "PMIC-7 ASIC 1.2V T0_3 Rail_1 Curr (out)" + label curr4 "PMIC-7 ASIC 1.2V T4_7 Rail_2 Curr (out)" + +bus "i2c-15" "i2c-1-mux (chan_id 6)" + chip "tps53679-i2c-*-58" + label in1 "PMIC-8 PSU 12V Rail (in1)" + label in2 "PMIC-8 PSU 12V Rail (in2)" + label in3 "PMIC-8 COMEX 1.8V Rail (out)" + label in4 "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 (in1)" + label in2 "PMIC-9 PSU 12V Rail (in2)" + label in3 "PMIC-9 COMEX 1.2V Rail (out)" + ignore in4 + 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-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_msn4700-r0/system_health_monitoring_config.json new file mode 120000 index 000000000000..98df66c27ca5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/thermal_policy.json b/device/mellanox/x86_64-mlnx_msn4700-r0/thermal_policy.json new file mode 120000 index 000000000000..5a25cd87f70c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/thermal_policy.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/thermal_policy.json \ No newline at end of file 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..dd83c2db12c5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/pmon_daemon_control.json @@ -0,0 +1,7 @@ +{ + "skip_ledd": true, + "skip_xcvrd": true, + "skip_psud": true, + "skip_pcied": true, + "skip_thermalctld": 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/device/mellanox/x86_64-mlnx_msn4700_simx-r0/system_health_monitoring_config.json b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/system_health_monitoring_config.json new file mode 120000 index 000000000000..42fe945344c9 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/system_health_monitoring_config.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700_simx-r0/system_health_monitoring_config.json \ No newline at end of file diff --git a/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/sai.profile b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/sai.profile index a58c3ac6eabf..c32774b9677c 100644 --- a/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/sai.profile +++ b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-ly1200-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/th-ly1200-32x100G.config.bcm b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/th-ly1200-32x100G.config.bcm index 84b2c572664f..9bf869f16bcf 100644 --- a/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/th-ly1200-32x100G.config.bcm +++ b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/th-ly1200-32x100G.config.bcm @@ -1,6 +1,6 @@ ### BMS (start) ## Global settings -bcm_num_cos=8 +bcm_num_cos=10 dport_map_indexed=0 ## Switch settings diff --git a/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/plugins/eeprom.py b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/plugins/eeprom.py index 96dcc5975328..96dc19ad5b36 100644 --- a/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/plugins/eeprom.py +++ b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -11,14 +8,16 @@ 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") +except ImportError as 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/2-0050/eeprom" - #Two i2c buses might get flipped order, check them both. + # Two i2c buses might get flipped order, check them both. if not os.path.exists(self.eeprom_path): self.eeprom_path = "/sys/bus/i2c/devices/2-0050/eeprom" super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/plugins/sfputil.py b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/plugins/sfputil.py index 33e98016384a..97c04f6d0d43 100644 --- a/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/plugins/sfputil.py +++ b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/plugins/sfputil.py @@ -31,7 +31,7 @@ def port_end(self): @property def qsfp_ports(self): - return range(0, self.PORTS_IN_BLOCK + 1) + return list(range(0, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): @@ -51,16 +51,17 @@ def get_presence(self, port_num): return False if port_num > 16: - cpld_addr=33 + cpld_addr = 33 else: - cpld_addr=32 + cpld_addr = 32 - file_path="/sys/bus/i2c/devices/1-00" + str(cpld_addr) + "/port" + str(port_num) + "/port" + str(port_num) + "_present" + file_path = "/sys/bus/i2c/devices/1-00" + \ + str(cpld_addr) + "/port" + str(port_num) + "/port" + str(port_num) + "_present" try: reg_file = open("file_path") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -68,7 +69,6 @@ def get_presence(self, port_num): # content is a string containing the hex representation of the register reg_value = int(content, 16) - # ModPrsL is active low if reg_value == 0: return True @@ -81,17 +81,17 @@ def get_low_power_mode(self, port_num): return False if port_num > 16: - cpld_addr=33 + cpld_addr = 33 else: - cpld_addr=32 - + cpld_addr = 32 - file_path="/sys/bus/i2c/devices/1-00" + str(cpld_addr) + "/port" + str(port_num) + "/port" + str(port_num) + "_lpmode" + file_path = "/sys/bus/i2c/devices/1-00" + \ + str(cpld_addr) + "/port" + str(port_num) + "/port" + str(port_num) + "_lpmode" try: reg_file = open(file_path) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) content = reg_file.readline().rstrip() @@ -110,21 +110,22 @@ def set_low_power_mode(self, port_num, lpmode): return False if port_num > 16: - cpld_addr=33 + cpld_addr = 33 else: - cpld_addr=32 + cpld_addr = 32 - file_path="/sys/bus/i2c/devices/1-00" + str(cpld_num) + "/port" + str(port_num) + "/port" + str(port_num) + "_lpmode" + file_path = "/sys/bus/i2c/devices/1-00" + \ + str(cpld_num) + "/port" + str(port_num) + "/port" + str(port_num) + "_lpmode" try: reg_file = open(file_path, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False # LPMode is active high; set or clear the bit accordingly if lpmode is True: - reg_value = 1 + reg_value = 1 else: reg_value = 0 @@ -144,16 +145,17 @@ def reset(self, port_num): return False if port_num > 16: - cpld_addr=33 + cpld_addr = 33 else: - cpld_addr=32 + cpld_addr = 32 - file_path="/sys/bus/i2c/devices/1-00" + str(cpld_num) + "/port" + str(port_num) + "/port" + str(port_num) + "_rst" + file_path = "/sys/bus/i2c/devices/1-00" + \ + str(cpld_num) + "/port" + str(port_num) + "/port" + str(port_num) + "_rst" try: reg_file = open(file_path, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False # ResetL is active low @@ -171,7 +173,7 @@ def reset(self, port_num): try: reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "w") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = 1 diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/buffers.json.j2 b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/buffers.json.j2 new file mode 100644 index 000000000000..a38350a982bc --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/buffers.json.j2 @@ -0,0 +1,10 @@ +{# Default values placeholder M0- Marvell SAI TBD buffers configuration #} + +{% set default_cable = '40m' %} +{% set default_ports_num = 54 -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{} + diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/buffers_defaults_t1.j2 b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/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/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/port_config.ini b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/port_config.ini new file mode 100644 index 000000000000..062c252ce195 --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/port_config.ini @@ -0,0 +1,53 @@ +# name lanes alias index speed +Ethernet0 1 Ethernet0 1 1000 +Ethernet1 2 Ethernet1 2 1000 +Ethernet2 3 Ethernet2 3 1000 +Ethernet3 4 Ethernet3 4 1000 +Ethernet4 5 Ethernet4 5 1000 +Ethernet5 6 Ethernet5 6 1000 +Ethernet6 7 Ethernet6 7 1000 +Ethernet7 8 Ethernet7 8 1000 +Ethernet8 9 Ethernet8 9 1000 +Ethernet9 10 Ethernet9 10 1000 +Ethernet10 11 Ethernet10 11 1000 +Ethernet11 12 Ethernet11 12 1000 +Ethernet12 13 Ethernet12 13 1000 +Ethernet13 14 Ethernet13 14 1000 +Ethernet14 15 Ethernet14 15 1000 +Ethernet15 16 Ethernet15 16 1000 +Ethernet16 17 Ethernet16 17 1000 +Ethernet17 18 Ethernet17 18 1000 +Ethernet18 19 Ethernet18 19 1000 +Ethernet19 20 Ethernet19 20 1000 +Ethernet20 21 Ethernet20 21 1000 +Ethernet21 22 Ethernet21 22 1000 +Ethernet22 23 Ethernet22 23 1000 +Ethernet23 24 Ethernet23 24 1000 +Ethernet24 25 Ethernet24 25 1000 +Ethernet25 26 Ethernet25 26 1000 +Ethernet26 27 Ethernet26 27 1000 +Ethernet27 28 Ethernet27 28 1000 +Ethernet28 29 Ethernet28 29 1000 +Ethernet29 30 Ethernet29 30 1000 +Ethernet30 31 Ethernet30 31 1000 +Ethernet31 32 Ethernet31 32 1000 +Ethernet32 33 Ethernet32 33 1000 +Ethernet33 34 Ethernet33 34 1000 +Ethernet34 35 Ethernet34 35 1000 +Ethernet35 36 Ethernet35 36 1000 +Ethernet36 37 Ethernet36 37 1000 +Ethernet37 38 Ethernet37 38 1000 +Ethernet38 39 Ethernet38 39 1000 +Ethernet39 40 Ethernet39 40 1000 +Ethernet40 41 Ethernet40 41 1000 +Ethernet41 42 Ethernet41 42 1000 +Ethernet42 43 Ethernet42 43 1000 +Ethernet43 44 Ethernet43 44 1000 +Ethernet44 45 Ethernet44 45 1000 +Ethernet45 46 Ethernet45 46 1000 +Ethernet46 47 Ethernet46 47 1000 +Ethernet47 48 Ethernet47 48 1000 +Ethernet48 49 Ethernet48 49 10000 +Ethernet49 50 Ethernet49 50 10000 +Ethernet50 51 Ethernet50 51 10000 +Ethernet51 52 Ethernet51 52 10000 diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/port_config.ini.inband b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/port_config.ini.inband new file mode 100644 index 000000000000..556da9c62254 --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/port_config.ini.inband @@ -0,0 +1,52 @@ +# name lanes alias index speed +Ethernet0 1 Ethernet0 1 1000 +Ethernet1 2 Ethernet1 2 1000 +Ethernet2 3 Ethernet2 3 1000 +Ethernet3 4 Ethernet3 4 1000 +Ethernet4 5 Ethernet4 5 1000 +Ethernet5 6 Ethernet5 6 1000 +Ethernet6 7 Ethernet6 7 1000 +Ethernet7 8 Ethernet7 8 1000 +Ethernet8 9 Ethernet8 9 1000 +Ethernet9 10 Ethernet9 10 1000 +Ethernet10 11 Ethernet10 11 1000 +Ethernet11 12 Ethernet11 12 1000 +Ethernet12 13 Ethernet12 13 1000 +Ethernet13 14 Ethernet13 14 1000 +Ethernet14 15 Ethernet14 15 1000 +Ethernet15 16 Ethernet15 16 1000 +Ethernet16 17 Ethernet16 17 1000 +Ethernet17 18 Ethernet17 18 1000 +Ethernet18 19 Ethernet18 19 1000 +Ethernet19 20 Ethernet19 20 1000 +Ethernet20 21 Ethernet20 21 1000 +Ethernet21 22 Ethernet21 22 1000 +Ethernet22 23 Ethernet22 23 1000 +Ethernet23 24 Ethernet23 24 1000 +Ethernet24 25 Ethernet24 25 1000 +Ethernet25 26 Ethernet25 26 1000 +Ethernet26 27 Ethernet26 27 1000 +Ethernet27 28 Ethernet27 28 1000 +Ethernet28 29 Ethernet28 29 1000 +Ethernet29 30 Ethernet29 30 1000 +Ethernet30 31 Ethernet30 31 1000 +Ethernet31 32 Ethernet31 32 1000 +Ethernet32 33 Ethernet32 33 1000 +Ethernet33 34 Ethernet33 34 1000 +Ethernet34 35 Ethernet34 35 1000 +Ethernet35 36 Ethernet35 36 1000 +Ethernet36 37 Ethernet36 37 1000 +Ethernet37 38 Ethernet37 38 1000 +Ethernet38 39 Ethernet38 39 1000 +Ethernet39 40 Ethernet39 40 1000 +Ethernet40 41 Ethernet40 41 1000 +Ethernet41 42 Ethernet41 42 1000 +Ethernet42 43 Ethernet42 43 1000 +Ethernet43 44 Ethernet43 44 1000 +Ethernet44 45 Ethernet44 45 1000 +Ethernet45 46 Ethernet45 46 1000 +Ethernet46 47 Ethernet46 47 1000 +Ethernet48 49 Ethernet48 49 10000 +Ethernet49 50 Ethernet49 50 10000 +Ethernet50 51 Ethernet50 51 10000 +Ethernet51 52 Ethernet51 52 10000 diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/port_config.ini.noinband b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/port_config.ini.noinband new file mode 100644 index 000000000000..062c252ce195 --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/port_config.ini.noinband @@ -0,0 +1,53 @@ +# name lanes alias index speed +Ethernet0 1 Ethernet0 1 1000 +Ethernet1 2 Ethernet1 2 1000 +Ethernet2 3 Ethernet2 3 1000 +Ethernet3 4 Ethernet3 4 1000 +Ethernet4 5 Ethernet4 5 1000 +Ethernet5 6 Ethernet5 6 1000 +Ethernet6 7 Ethernet6 7 1000 +Ethernet7 8 Ethernet7 8 1000 +Ethernet8 9 Ethernet8 9 1000 +Ethernet9 10 Ethernet9 10 1000 +Ethernet10 11 Ethernet10 11 1000 +Ethernet11 12 Ethernet11 12 1000 +Ethernet12 13 Ethernet12 13 1000 +Ethernet13 14 Ethernet13 14 1000 +Ethernet14 15 Ethernet14 15 1000 +Ethernet15 16 Ethernet15 16 1000 +Ethernet16 17 Ethernet16 17 1000 +Ethernet17 18 Ethernet17 18 1000 +Ethernet18 19 Ethernet18 19 1000 +Ethernet19 20 Ethernet19 20 1000 +Ethernet20 21 Ethernet20 21 1000 +Ethernet21 22 Ethernet21 22 1000 +Ethernet22 23 Ethernet22 23 1000 +Ethernet23 24 Ethernet23 24 1000 +Ethernet24 25 Ethernet24 25 1000 +Ethernet25 26 Ethernet25 26 1000 +Ethernet26 27 Ethernet26 27 1000 +Ethernet27 28 Ethernet27 28 1000 +Ethernet28 29 Ethernet28 29 1000 +Ethernet29 30 Ethernet29 30 1000 +Ethernet30 31 Ethernet30 31 1000 +Ethernet31 32 Ethernet31 32 1000 +Ethernet32 33 Ethernet32 33 1000 +Ethernet33 34 Ethernet33 34 1000 +Ethernet34 35 Ethernet34 35 1000 +Ethernet35 36 Ethernet35 36 1000 +Ethernet36 37 Ethernet36 37 1000 +Ethernet37 38 Ethernet37 38 1000 +Ethernet38 39 Ethernet38 39 1000 +Ethernet39 40 Ethernet39 40 1000 +Ethernet40 41 Ethernet40 41 1000 +Ethernet41 42 Ethernet41 42 1000 +Ethernet42 43 Ethernet42 43 1000 +Ethernet43 44 Ethernet43 44 1000 +Ethernet44 45 Ethernet44 45 1000 +Ethernet45 46 Ethernet45 46 1000 +Ethernet46 47 Ethernet46 47 1000 +Ethernet47 48 Ethernet47 48 1000 +Ethernet48 49 Ethernet48 49 10000 +Ethernet49 50 Ethernet49 50 10000 +Ethernet50 51 Ethernet50 51 10000 +Ethernet51 52 Ethernet51 52 10000 diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/profile.ini b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/profile.ini new file mode 100644 index 000000000000..c908d9235215 --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/profile.ini @@ -0,0 +1,2 @@ +switchMacAddress=XX:XX:XX:XX:XX:XX +ledMode=ac3x97bits diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/profile.ini.inband b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/profile.ini.inband new file mode 100644 index 000000000000..6a82d5939c3b --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/profile.ini.inband @@ -0,0 +1,3 @@ +switchMacAddress=XX:XX:XX:XX:XX:XX +inbandMgmtPortNum=48 +ledMode=ac3x97bits diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/profile.ini.noinband b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/profile.ini.noinband new file mode 100644 index 000000000000..c908d9235215 --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/profile.ini.noinband @@ -0,0 +1,2 @@ +switchMacAddress=XX:XX:XX:XX:XX:XX +ledMode=ac3x97bits diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/qos.json.j2 b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/qos.json.j2 new file mode 100644 index 000000000000..c28e2e13e974 --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/qos.json.j2 @@ -0,0 +1,2 @@ +{# this file empty temporarily until qos supported SAI Marvell #} +{} diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/sai.profile b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/sai.profile new file mode 100644 index 000000000000..10053fa935a1 --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/Nokia-7215/sai.profile @@ -0,0 +1,3 @@ +mode=1 +hwId=et6448m +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/profile.ini diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/default_sku b/device/nokia/armhf-nokia_ixs7215_52x-r0/default_sku new file mode 100644 index 000000000000..5c41b116898d --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/default_sku @@ -0,0 +1 @@ +Nokia-7215 l2 diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/platform.json b/device/nokia/armhf-nokia_ixs7215_52x-r0/platform.json new file mode 100644 index 000000000000..d6a28d19b026 --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/platform.json @@ -0,0 +1,226 @@ +{ + "chassis": { + "name": "7215 IXS-T1", + "components": [ + { + "name": "System-CPLD" + }, + { + "name": "U-Boot" + } + ], + "fans": [ + { + "name": "Fan1" + }, + { + "name": "Fan2" + } + ], + "fan_drawers": [ + { + "name": "drawer1", + "fans": [ + { + "name": "Fan1" + } + ] + }, + { + "name": "drawer2", + "fans": [ + { + "name": "Fan2" + } + ] + } + ], + "psus": [ + { + "name": "PSU1" + }, + { + "name": "PSU2" + } + ], + "thermals": [ + { + "name": "PCB PHY" + }, + { + "name": "PCB MAC" + }, + { + "name": "ADT7473-CPU" + }, + { + "name": "ADT7473-LOC" + }, + { + "name": "ADT7473-MAC" + }, + { + "name": "CPU Core" + } + ], + "sfps": [ + { + "name": "Ethernet0" + }, + { + "name": "Ethernet1" + }, + { + "name": "Ethernet2" + }, + { + "name": "Ethernet3" + }, + { + "name": "Ethernet4" + }, + { + "name": "Ethernet5" + }, + { + "name": "Ethernet6" + }, + { + "name": "Ethernet7" + }, + { + "name": "Ethernet8" + }, + { + "name": "Ethernet9" + }, + { + "name": "Ethernet10" + }, + { + "name": "Ethernet11" + }, + { + "name": "Ethernet12" + }, + { + "name": "Ethernet13" + }, + { + "name": "Ethernet14" + }, + { + "name": "Ethernet15" + }, + { + "name": "Ethernet16" + }, + { + "name": "Ethernet17" + }, + { + "name": "Ethernet18" + }, + { + "name": "Ethernet19" + }, + { + "name": "Ethernet20" + }, + { + "name": "Ethernet21" + }, + { + "name": "Ethernet22" + }, + { + "name": "Ethernet23" + }, + { + "name": "Ethernet24" + }, + { + "name": "Ethernet25" + }, + { + "name": "Ethernet26" + }, + { + "name": "Ethernet27" + }, + { + "name": "Ethernet28" + }, + { + "name": "Ethernet29" + }, + { + "name": "Ethernet30" + }, + { + "name": "Ethernet31" + }, + { + "name": "Ethernet32" + }, + { + "name": "Ethernet33" + }, + { + "name": "Ethernet34" + }, + { + "name": "Ethernet35" + }, + { + "name": "Ethernet36" + }, + { + "name": "Ethernet37" + }, + { + "name": "Ethernet38" + }, + { + "name": "Ethernet39" + }, + { + "name": "Ethernet40" + }, + { + "name": "Ethernet41" + }, + { + "name": "Ethernet42" + }, + { + "name": "Ethernet43" + }, + { + "name": "Ethernet44" + }, + { + "name": "Ethernet45" + }, + { + "name": "Ethernet46" + }, + { + "name": "Ethernet47" + }, + { + "name": "Ethernet48" + }, + { + "name": "Ethernet49" + }, + { + "name": "Ethernet50" + }, + { + "name": "Ethernet51" + } + ] + }, + "interfaces": {} +} diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/platform_components.json b/device/nokia/armhf-nokia_ixs7215_52x-r0/platform_components.json new file mode 100644 index 000000000000..51dfea452f54 --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/platform_components.json @@ -0,0 +1,10 @@ +{ + "chassis": { + "7215 IXS-T1": { + "component": { + "U-Boot": { }, + "System-CPLD": { } + } + } + } +} diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/plugins/eeprom.py b/device/nokia/armhf-nokia_ixs7215_52x-r0/plugins/eeprom.py new file mode 100644 index 000000000000..cbd48237cc10 --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/plugins/eeprom.py @@ -0,0 +1,14 @@ +try: + import os + from sonic_eeprom import eeprom_tlvinfo +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/class/i2c-adapter/i2c-0/0-0053/eeprom" + if not os.path.exists(self.eeprom_path): + os.system("echo 24c02 0x53 > /sys/class/i2c-adapter/i2c-0/new_device") + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/plugins/led_control.py b/device/nokia/armhf-nokia_ixs7215_52x-r0/plugins/led_control.py new file mode 100644 index 000000000000..935343a84ce1 --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/plugins/led_control.py @@ -0,0 +1,132 @@ +# +# led_control.py +# +# Platform-specific LED control functionality for SONiC +# + +try: + from sonic_led.led_control_base import LedControlBase + import os + import time + import syslog + import sonic_platform.platform + import sonic_platform.chassis +except ImportError as e: + raise ImportError(str(e) + " - required module not found") + +smbus_present = 1 + +try: + import smbus +except ImportError as e: + smbus_present = 0 + + +def DBG_PRINT(str): + syslog.openlog("nokia-led") + syslog.syslog(syslog.LOG_INFO, str) + syslog.closelog() + + +class LedControl(LedControlBase): + """Platform specific LED control class""" + + # Constructor + def __init__(self): + self.chassis = sonic_platform.platform.Platform().get_chassis() + self._initDefaultConfig() + + def _initDefaultConfig(self): + # The fan tray leds and system led managed by new chassis class API + # leaving only a couple other front panel leds to be done old style + DBG_PRINT("starting system leds") + self._initSystemLed() + DBG_PRINT(" led done") + + def _set_i2c_register(self, reg_file, value): + # On successful write, the value read will be written on + # reg_name and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(reg_file)): + return rv + try: + with open(reg_file, 'w') as fd: + rv = fd.write(str(value)) + except Exception as e: + rv = 'ERR' + + return rv + + def _initSystemLed(self): + # Front Panel System LEDs setting + oldfan = 0xf + oldpsu = 0xf + + # Write sys led + if smbus_present == 0: + DBG_PRINT(" PMON LED SET ERROR -> smbus present = 0 ") + else: + bus = smbus.SMBus(0) + DEVICE_ADDRESS = 0x41 + DEVICEREG = 0x7 + bus.write_byte_data(DEVICE_ADDRESS, DEVICEREG, 0x02) + DBG_PRINT(" System LED set O.K. ") + + while True: + # Front Panel FAN Panel LED setting in register 0x08 + if (self.chassis.get_fan(0).get_status() == self.chassis.get_fan(1).get_status() == True): + if (os.path.isfile("/sys/class/gpio/fanLedAmber/value")): + if oldfan != 0x1: + self._set_i2c_register("/sys/class/gpio/fanLedAmber/value", 0) + self._set_i2c_register("/sys/class/gpio/fanLedGreen/value", 1) + oldfan = 0x1 + else: + oldfan = 0xf + else: + if (os.path.isfile("/sys/class/gpio/fanLedGreen/value")): + if oldfan != 0x0: + self._set_i2c_register("/sys/class/gpio/fanLedGreen/value", 0) + self._set_i2c_register("/sys/class/gpio/fanLedAmber/value", 1) + oldfan = 0x0 + else: + oldfan = 0xf + + # Front Panel PSU Panel LED setting in register 0x09 + if (self.chassis.get_psu(0).get_status() == self.chassis.get_psu(1).get_status() == True): + if (os.path.isfile("/sys/class/gpio/psuLedAmber/value")): + if oldpsu != 0x1: + self._set_i2c_register("/sys/class/gpio/psuLedAmber/value", 0) + self._set_i2c_register("/sys/class/gpio/psuLedGreen/value", 1) + oldpsu = 0x1 + else: + oldpsu = 0xf + else: + if (os.path.isfile("/sys/class/gpio/psuLedGreen/value")): + if oldpsu != 0x0: + self._set_i2c_register("/sys/class/gpio/psuLedGreen/value", 0) + self._set_i2c_register("/sys/class/gpio/psuLedAmber/value", 1) + oldpsu = 0x0 + else: + oldpsu = 0xf + time.sleep(6) + + # Helper method to map SONiC port name to index + def _port_name_to_index(self, port_name): + # Strip "Ethernet" off port name + if not port_name.startswith(self.SONIC_PORT_NAME_PREFIX): + return -1 + + port_idx = int(port_name[len(self.SONIC_PORT_NAME_PREFIX):]) + return port_idx + + def _port_state_to_mode(self, port_idx, state): + DBG_PRINT("_port_state_to_mode") + + def _port_led_mode_update(self, port_idx, ledMode): + DBG_PRINT("_port_led_mode_update") + + # called when port states change- implementation of port_link_state_change() method if needed + def port_link_state_change(self, portname, state): + # DBG_PRINT("port_link_state_change ") + return diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/plugins/pcie.yaml b/device/nokia/armhf-nokia_ixs7215_52x-r0/plugins/pcie.yaml new file mode 100644 index 000000000000..f24086a2228b --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/plugins/pcie.yaml @@ -0,0 +1,20 @@ +- bus: '00' + dev: '01' + fn: '0' + id: '6820' + name: 'PCI bridge: Marvell Technology Group Ltd. Device 6820 (rev 0a)' +- bus: '00' + dev: '02' + fn: '0' + id: '6820' + name: 'PCI bridge: Marvell Technology Group Ltd. Device 6820 (rev 0a)' +- bus: '01' + dev: '00' + fn: '0' + id: c804 + name: 'Ethernet controller: Marvell Technology Group Ltd. Device c804' +- bus: '02' + dev: '00' + fn: '0' + id: c804 + name: 'Ethernet controller: Marvell Technology Group Ltd. Device c804' diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/plugins/psuutil.py b/device/nokia/armhf-nokia_ixs7215_52x-r0/plugins/psuutil.py new file mode 100755 index 000000000000..513b3ae4085b --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/plugins/psuutil.py @@ -0,0 +1,32 @@ +try: + import sonic_platform.platform + import sonic_platform.chassis + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + PsuBase.__init__(self) + self.chassis = sonic_platform.platform.Platform().get_chassis() + + def get_num_psus(self): + MAX_PSUS = 2 + return MAX_PSUS + + def get_psu_status(self, index): + # print " psuUtil redirect to PMON 2.0 " + if self.chassis is not None: + return self.chassis.get_psu(index-1).get_status() + else: + return False + + def get_psu_presence(self, index): + # print " psuUtil redirect to PMON 2.0 " + if self.chassis is not None: + return self.chassis.get_psu(index-1).get_presence() + else: + return False diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/plugins/sfputil.py b/device/nokia/armhf-nokia_ixs7215_52x-r0/plugins/sfputil.py new file mode 100755 index 000000000000..1ca3b9ec6f2d --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/plugins/sfputil.py @@ -0,0 +1,65 @@ +try: + import sonic_platform.platform + import sonic_platform.chassis + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class SfpUtil(SfpUtilBase): + """Platform specific sfputil class""" + + _port_start = 49 + _port_end = 52 + ports_in_block = 4 + + _port_to_eeprom_mapping = {} + _changed_ports = [0, 0, 0, 0] + + @property + def port_start(self): + return self._port_start + + @property + def port_end(self): + return self._port_end + + @property + def qsfp_ports(self): + return list(range(0, 0)) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + def __init__(self): + # print " SfpUtil(SfpUtilBase) re-directed to chassis PMON 2.0 " + SfpUtilBase.__init__(self) + self.chassis = sonic_platform.platform.Platform().get_chassis() + + def reset(self, port_num): + # print " SfpUtil(SfpUtilBase) re-directed to chassis PMON 2.0 " + if self.chassis is not None: + return self.chassis.get_sfp(port_num).reset() + else: + return False + + def set_low_power_mode(self, port_nuM, lpmode): + # print " SfpUtil(SfpUtilBase) targeted for deprecation " + return False + + def get_low_power_mode(self, port_num): + # print " SfpUtil(SfpUtilBase) targeted for deprecation " + return False + + def get_presence(self, port_num): + # print " SfpUtil(SfpUtilBase) re-directed to chassis PMON 2.0 " + if self.chassis is not None: + return self.chassis.get_sfp(port_num).get_presence() + else: + return False + + def get_transceiver_change_event(self, timeout): + # print " SfpUtil(SfpUtilBase) targeted for deprecation " + + raise NotImplementedError diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/sensors.conf b/device/nokia/armhf-nokia_ixs7215_52x-r0/sensors.conf new file mode 100644 index 000000000000..de73eab6e987 --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/sensors.conf @@ -0,0 +1,19 @@ +chip "adt7473-*" + label fan1 "rear fan 1" + label fan2 "rear fan 2" + ignore fan3 + ignore fan4 + ignore in1 + +chip "lm75a-i2c-*-4a" + label temp1 "MAC temp sensor" + set temp1_max 65 + set temp1_crit 75 + +chip "lm75a-i2c-*-4b" + label temp1 "Board temp sensor" + set temp2_max 65 + set temp2_crit 75 + +chip "armada_thermal-*" + ignore temp1 diff --git a/device/nokia/armhf-nokia_ixs7215_52x-r0/thermal_policy.json b/device/nokia/armhf-nokia_ixs7215_52x-r0/thermal_policy.json new file mode 100644 index 000000000000..fb6e044e266c --- /dev/null +++ b/device/nokia/armhf-nokia_ixs7215_52x-r0/thermal_policy.json @@ -0,0 +1,65 @@ +{ + "thermal_control_algorithm": { + "run_at_boot_up": "false", + "fan_speed_when_suspend": "50" + }, + "info_types": [ + { + "type": "fan_info" + }, + { + "type": "thermal_info" + }, + { + "type": "chassis_info" + } + ], + "policies": [ + { + "name": "any fan absence", + "conditions": [ + { + "type": "fan.any.absence" + } + ], + "actions": [ + { + "type": "thermal_control.control", + "status": "false" + }, + { + "type": "fan.all.set_speed", + "speed": "100" + } + ] + }, + { + "name": "all fan presence", + "conditions": [ + { + "type": "fan.all.presence" + } + ], + "actions": [ + { + "type": "thermal.temp_check_and_set_all_fan_speed", + "default_speed": "50", + "hightemp_speed": "100" + } + ] + }, + { + "name": "temp over high critical threshold", + "conditions": [ + { + "type": "thermal.over.high_critical_threshold" + } + ], + "actions": [ + { + "type": "switch.shutdown" + } + ] + } + ] +} diff --git a/device/pegatron/x86_64-pegatron_porsche-r0/plugins/eeprom.py b/device/pegatron/x86_64-pegatron_porsche-r0/plugins/eeprom.py index 6964c6bade4f..5c2a90e81c2f 100755 --- a/device/pegatron/x86_64-pegatron_porsche-r0/plugins/eeprom.py +++ b/device/pegatron/x86_64-pegatron_porsche-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -11,11 +8,13 @@ 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") +except ImportError as 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/4-0054/eeprom" super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/pegatron/x86_64-pegatron_porsche-r0/plugins/psuutil.py b/device/pegatron/x86_64-pegatron_porsche-r0/plugins/psuutil.py index a23a7b7fe73e..ce859cb70c77 100755 --- a/device/pegatron/x86_64-pegatron_porsche-r0/plugins/psuutil.py +++ b/device/pegatron/x86_64-pegatron_porsche-r0/plugins/psuutil.py @@ -19,12 +19,12 @@ class PsuUtil(PsuBase): def __init__(self): PsuBase.__init__(self) - - + # Get sysfs attribute + def get_attr_value(self, attr_path): - - retval = 'ERR' + + retval = 'ERR' if (not os.path.isfile(attr_path)): return retval @@ -56,16 +56,16 @@ def get_psu_status(self, index): faulty """ status = 0 - attr_file = 'psu_'+str(index)+'_status' - attr_path = self.SYSFS_PSU_DIR +'/' + attr_file - + attr_file = 'psu_'+str(index)+'_status' + attr_path = self.SYSFS_PSU_DIR + '/' + 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 + status = 1 return status @@ -78,15 +78,14 @@ def get_psu_presence(self, index): """ status = 0 attr_file = 'psu_'+str(index)+'_present' - attr_path = self.SYSFS_PSU_DIR +'/' + attr_file - + attr_path = self.SYSFS_PSU_DIR + '/' + 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 == 0): - status = 1 + status = 1 return status - diff --git a/device/pegatron/x86_64-pegatron_porsche-r0/plugins/sfputil.py b/device/pegatron/x86_64-pegatron_porsche-r0/plugins/sfputil.py index 28909f00110c..3a757333cd2f 100755 --- a/device/pegatron/x86_64-pegatron_porsche-r0/plugins/sfputil.py +++ b/device/pegatron/x86_64-pegatron_porsche-r0/plugins/sfputil.py @@ -1,12 +1,10 @@ -#!/usr/bin/env python - try: import os import re import time from sonic_sfp.sfputilbase import SfpUtilBase -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class SfpUtil(SfpUtilBase): @@ -21,18 +19,17 @@ class SfpUtil(SfpUtilBase): port_to_eeprom_mapping = {} port_to_i2c_mapping = {} - sfp_ports = range(0, ports_in_block) - qsfp_ports = range(ports_in_block - 6, ports_in_block) - + sfp_ports = list(range(0, ports_in_block)) + qsfp_ports = list(range(ports_in_block - 6, ports_in_block)) def __init__(self): for x in range(self.port_start, self.port_end + 1): if x < self.cpldb_sfp_num: - self.port_to_i2c_mapping.update({x:7}) + self.port_to_i2c_mapping.update({x: 7}) elif x < self.cplda_sfp_num + self.cpldb_sfp_num: - self.port_to_i2c_mapping.update({x:6}) + self.port_to_i2c_mapping.update({x: 6}) else: - self.port_to_i2c_mapping.update({x:8}) + self.port_to_i2c_mapping.update({x: 8}) for x in range(self.port_start, self.port_end+1): eeprom_path = '/sys/bus/i2c/devices/{0}-0050/sfp'+str(x+1)+'_eeprom' @@ -40,7 +37,6 @@ def __init__(self): self.port_to_eeprom_mapping[x] = port_eeprom_path SfpUtilBase.__init__(self) - def get_presence(self, port_num): if port_num < self.port_start or port_num > self.port_end: return False @@ -51,11 +47,11 @@ def get_presence(self, port_num): presence_path = '/sys/bus/i2c/devices/6-0074/sfp'+str(port_num+1)+'_present' else: presence_path = '/sys/bus/i2c/devices/8-0076/sfp'+str(port_num+1)+'_present' - + try: file = open(presence_path) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False value = int(file.readline().rstrip()) @@ -71,11 +67,11 @@ def get_low_power_mode(self, port_num): return False lowpower_path = '/sys/bus/i2c/devices/8-0076/sfp'+str(port_num+1)+'_lowpower' - + try: file = open(lowpower_path) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False value = int(file.readline().rstrip()) @@ -101,7 +97,7 @@ def set_low_power_mode(self, port_num, lpmode): try: file = open(lowpower_path, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False file.seek(0) @@ -118,7 +114,7 @@ def reset(self, port_num): try: file = open(reset_path, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False file.seek(0) @@ -131,7 +127,7 @@ def reset(self, port_num): try: file = open(reset_path, "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False file.seek(0) @@ -233,6 +229,3 @@ def read_porttab_mappings(self, porttabfile): print "logical to physical: " + self.logical_to_physical print "physical to logical: " + self.physical_to_logical """ - - - diff --git a/device/quanta/x86_64-quanta_ix1b_rglbmc-r0/Quanta-IX1B-32X/sai.profile b/device/quanta/x86_64-quanta_ix1b_rglbmc-r0/Quanta-IX1B-32X/sai.profile index fbd01105a4f3..219465108df8 100755 --- a/device/quanta/x86_64-quanta_ix1b_rglbmc-r0/Quanta-IX1B-32X/sai.profile +++ b/device/quanta/x86_64-quanta_ix1b_rglbmc-r0/Quanta-IX1B-32X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-ix1b-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/quanta/x86_64-quanta_ix1b_rglbmc-r0/plugins/eeprom.py b/device/quanta/x86_64-quanta_ix1b_rglbmc-r0/plugins/eeprom.py index 989f7fe50794..ddefcf8877fb 100755 --- a/device/quanta/x86_64-quanta_ix1b_rglbmc-r0/plugins/eeprom.py +++ b/device/quanta/x86_64-quanta_ix1b_rglbmc-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -11,11 +8,13 @@ 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") +except ImportError as 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/22-0054/eeprom" super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/quanta/x86_64-quanta_ix1b_rglbmc-r0/plugins/psuutil.py b/device/quanta/x86_64-quanta_ix1b_rglbmc-r0/plugins/psuutil.py index 1986aa846c5e..0b2027afdda4 100755 --- a/device/quanta/x86_64-quanta_ix1b_rglbmc-r0/plugins/psuutil.py +++ b/device/quanta/x86_64-quanta_ix1b_rglbmc-r0/plugins/psuutil.py @@ -15,64 +15,73 @@ DEBUG = False + def show_log(txt): if DEBUG == True: print("[IX2]"+txt) return + def exec_cmd(cmd, show): logging.info('Run :'+cmd) try: - output = subprocess.check_output(cmd, shell=True) - show_log (cmd +"output:"+str(output)) + output = subprocess.check_output(cmd, shell=True, universal_newlines=True) + show_log(cmd + "output:"+str(output)) except subprocess.CalledProcessError as e: logging.info("Failed :"+cmd) if show: - print("Failed :"+cmd +"returncode = {}, err msg: {}".format(e.returncode, e.output)) - return output + print("Failed :"+cmd + "returncode = {}, err msg: {}".format(e.returncode, e.output)) + return output + def my_log(txt): if DEBUG == True: print("[QUANTA DBG]: "+txt) return + def log_os_system(cmd, show): logging.info('Run :'+cmd) status = 1 output = "" try: - output = subprocess.check_output(cmd, shell=True) - my_log (cmd +"output:"+str(output)) + output = subprocess.check_output(cmd, shell=True, universal_newlines=True) + my_log(cmd + "output:"+str(output)) except subprocess.CalledProcessError as e: logging.info('Failed :'+cmd) if show: - print("Failed :"+cmd +"returncode = {}, err msg: {}".format(e.returncode, e.output)) - return output + print("Failed :"+cmd + "returncode = {}, err msg: {}".format(e.returncode, e.output)) + return output + def gpio16_exist(): ls = log_os_system("ls /sys/class/gpio/ | grep gpio16", 0) logging.info('mods:'+ls) - if len(ls) ==0: + if len(ls) == 0: return False + def gpio17_exist(): ls = log_os_system("ls /sys/class/gpio/ | grep gpio17", 0) logging.info('mods:'+ls) - if len(ls) ==0: + if len(ls) == 0: return False + def gpio19_exist(): ls = log_os_system("ls /sys/class/gpio/ | grep gpio19", 0) logging.info('mods:'+ls) - if len(ls) ==0: + if len(ls) == 0: return False + def gpio20_exist(): ls = log_os_system("ls /sys/class/gpio/ | grep gpio20", 0) logging.info('mods:'+ls) - if len(ls) ==0: + if len(ls) == 0: return False + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" @@ -81,6 +90,7 @@ class PsuUtil(PsuBase): SYSFS_PSU_POWERGOOD_DIR = ["/sys/class/gpio/gpio17", "/sys/class/gpio/gpio20"] + def __init__(self): PsuBase.__init__(self) @@ -134,7 +144,7 @@ def get_psu_status(self, index): """ status = 0 attr_file = 'value' - attr_path = self.SYSFS_PSU_POWERGOOD_DIR[index-1] +'/' + attr_file + attr_path = self.SYSFS_PSU_POWERGOOD_DIR[index-1] + '/' + attr_file attr_value = self.get_attr_value(attr_path) @@ -142,7 +152,7 @@ def get_psu_status(self, index): attr_value = int(attr_value, 16) # Check for PSU status if (attr_value == 1): - status = 1 + status = 1 return status @@ -155,8 +165,8 @@ def get_psu_presence(self, index): """ status = 0 psu_absent = 0 - attr_file ='value' - attr_path = self.SYSFS_PSU_PRESENT_DIR[index-1] +'/' + attr_file + attr_file = 'value' + attr_path = self.SYSFS_PSU_PRESENT_DIR[index-1] + '/' + attr_file attr_value = self.get_attr_value(attr_path) @@ -164,7 +174,6 @@ def get_psu_presence(self, index): attr_value = int(attr_value, 16) # Check for PSU presence if (attr_value == 0): - status = 1 + status = 1 return status - diff --git a/device/quanta/x86_64-quanta_ix1b_rglbmc-r0/plugins/sfputil.py b/device/quanta/x86_64-quanta_ix1b_rglbmc-r0/plugins/sfputil.py index 851f4b90277d..cbaf8b71832f 100755 --- a/device/quanta/x86_64-quanta_ix1b_rglbmc-r0/plugins/sfputil.py +++ b/device/quanta/x86_64-quanta_ix1b_rglbmc-r0/plugins/sfputil.py @@ -1,10 +1,8 @@ -#!/usr/bin/env python - try: import time - from sonic_sfp.sfputilbase import SfpUtilBase -except ImportError, e: - raise ImportError (str(e) + "- required module not found") + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class SfpUtil(SfpUtilBase): @@ -16,41 +14,41 @@ class SfpUtil(SfpUtilBase): _port_to_eeprom_mapping = {} port_to_i2c_mapping = { - 1 : 32, - 2 : 33, - 3 : 34, - 4 : 35, - 5 : 36, - 6 : 37, - 7 : 38, - 8 : 39, - 9 : 40, - 10 : 41, - 11 : 42, - 12 : 43, - 13 : 44, - 14 : 45, - 15 : 46, - 16 : 47, - 17 : 48, - 18 : 49, - 19 : 50, - 20 : 51, - 21 : 52, - 22 : 53, - 23 : 54, - 24 : 55, - 25 : 56, - 26 : 57, - 27 : 58, - 28 : 59, - 29 : 60, - 30 : 61, - 31 : 62, - 32 : 63, + 1: 32, + 2: 33, + 3: 34, + 4: 35, + 5: 36, + 6: 37, + 7: 38, + 8: 39, + 9: 40, + 10: 41, + 11: 42, + 12: 43, + 13: 44, + 14: 45, + 15: 46, + 16: 47, + 17: 48, + 18: 49, + 19: 50, + 20: 51, + 21: 52, + 22: 53, + 23: 54, + 24: 55, + 25: 56, + 26: 57, + 27: 58, + 28: 59, + 29: 60, + 30: 61, + 31: 62, + 32: 63, } - _qsfp_ports = range(0, ports_in_block + 1) + _qsfp_ports = list(range(0, ports_in_block + 1)) def __init__(self): eeprom_path = '/sys/bus/i2c/devices/{0}-0050/eeprom' @@ -67,7 +65,7 @@ def reset(self, port_num): try: reg_file = open("/sys/class/cpld-qsfp28/port-"+str(port_num+1)+"/reset", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = 0 @@ -81,7 +79,7 @@ def reset(self, port_num): try: reg_file = open("/sys/class/cpld-qsfp28/port-"+str(port_num+1)+"/reset", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = 1 @@ -91,14 +89,14 @@ def reset(self, port_num): return True def set_low_power_mode(self, port_num, lpmode): - # Check for invalid port_num + # Check for invalid port_num if port_num < self.port_start or port_num > self.port_end: return False try: reg_file = open("/sys/class/cpld-qsfp28/port-"+str(port_num+1)+"/lpmode", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = int(reg_file.readline().rstrip()) @@ -115,14 +113,14 @@ def set_low_power_mode(self, port_num, lpmode): return True def get_low_power_mode(self, port_num): - # Check for invalid port_num + # Check for invalid port_num if port_num < self.port_start or port_num > self.port_end: return False try: reg_file = open("/sys/class/cpld-qsfp28/port-"+str(port_num+1)+"/lpmode") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = int(reg_file.readline().rstrip()) @@ -131,7 +129,7 @@ def get_low_power_mode(self, port_num): return False return True - + def get_presence(self, port_num): # Check for invalid port_num if port_num < self._port_start or port_num > self._port_end: @@ -139,11 +137,11 @@ def get_presence(self, port_num): #path = "/sys/class/cpld-qsfp28/port-{0}/module_present" #port_ps = path.format(self.port_to_i2c_mapping[port_num+1]) - + try: reg_file = open("/sys/class/cpld-qsfp28/port-"+str(port_num+1)+"/module_present") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = reg_file.readline().rstrip() @@ -159,14 +157,14 @@ def port_start(self): @property def port_end(self): return self._port_end - + @property def qsfp_ports(self): - return range(0, self.ports_in_block + 1) + return list(range(0, self.ports_in_block + 1)) - @property + @property def port_to_eeprom_mapping(self): - return self._port_to_eeprom_mapping + return self._port_to_eeprom_mapping def get_transceiver_change_event(self): """ @@ -175,5 +173,3 @@ def get_transceiver_change_event(self): on this platform. """ raise NotImplementedError - - diff --git a/device/quanta/x86_64-quanta_ix7_rglbmc-r0/Quanta-IX7-32X/sai.profile b/device/quanta/x86_64-quanta_ix7_rglbmc-r0/Quanta-IX7-32X/sai.profile index 8088d09edc12..367f18e369fa 100644 --- a/device/quanta/x86_64-quanta_ix7_rglbmc-r0/Quanta-IX7-32X/sai.profile +++ b/device/quanta/x86_64-quanta_ix7_rglbmc-r0/Quanta-IX7-32X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-ix7-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/quanta/x86_64-quanta_ix7_rglbmc-r0/Quanta-IX7-32X/td3-ix7-32x100G.config.bcm b/device/quanta/x86_64-quanta_ix7_rglbmc-r0/Quanta-IX7-32X/td3-ix7-32x100G.config.bcm index 54abc9ddae7b..7361ad2f57f3 100644 --- a/device/quanta/x86_64-quanta_ix7_rglbmc-r0/Quanta-IX7-32X/td3-ix7-32x100G.config.bcm +++ b/device/quanta/x86_64-quanta_ix7_rglbmc-r0/Quanta-IX7-32X/td3-ix7-32x100G.config.bcm @@ -1,3 +1,4 @@ +sai_load_hw_config=/etc/bcm/flex/bcm56870_a0_issu/b870.6.4.1/ bcm_tunnel_term_compatible_mode=1 core_clock_frequency=1525 dpp_clock_ratio=2:3 @@ -8,7 +9,7 @@ l3_mem_entries=40960 fpem_mem_entries=16384 l2xmsg_mode=1 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 cdma_timeout_usec=3000000 diff --git a/device/quanta/x86_64-quanta_ix7_rglbmc-r0/plugins/eeprom.py b/device/quanta/x86_64-quanta_ix7_rglbmc-r0/plugins/eeprom.py index 2a35f3a22a17..fa34110c04ea 100644 --- a/device/quanta/x86_64-quanta_ix7_rglbmc-r0/plugins/eeprom.py +++ b/device/quanta/x86_64-quanta_ix7_rglbmc-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -11,11 +8,13 @@ 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") +except ImportError as 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/18-0054/eeprom" super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/quanta/x86_64-quanta_ix7_rglbmc-r0/plugins/psuutil.py b/device/quanta/x86_64-quanta_ix7_rglbmc-r0/plugins/psuutil.py index 885842bbda5a..5cf06fb5d66a 100644 --- a/device/quanta/x86_64-quanta_ix7_rglbmc-r0/plugins/psuutil.py +++ b/device/quanta/x86_64-quanta_ix7_rglbmc-r0/plugins/psuutil.py @@ -8,7 +8,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" diff --git a/device/quanta/x86_64-quanta_ix7_rglbmc-r0/plugins/sfputil.py b/device/quanta/x86_64-quanta_ix7_rglbmc-r0/plugins/sfputil.py index 85a4aad26dae..14b0ef6674be 100644 --- a/device/quanta/x86_64-quanta_ix7_rglbmc-r0/plugins/sfputil.py +++ b/device/quanta/x86_64-quanta_ix7_rglbmc-r0/plugins/sfputil.py @@ -21,38 +21,38 @@ class SfpUtil(SfpUtilBase): _port_to_eeprom_mapping = {} _port_to_i2c_mapping = { - 1 : 32, - 2 : 33, - 3 : 34, - 4 : 35, - 5 : 36, - 6 : 37, - 7 : 38, - 8 : 39, - 9 : 40, - 10 : 41, - 11 : 42, - 12 : 43, - 13 : 44, - 14 : 45, - 15 : 46, - 16 : 47, - 17 : 48, - 18 : 49, - 19 : 50, - 20 : 51, - 21 : 52, - 22 : 53, - 23 : 54, - 24 : 55, - 25 : 56, - 26 : 57, - 27 : 58, - 28 : 59, - 29 : 60, - 30 : 61, - 31 : 62, - 32 : 63, + 1: 32, + 2: 33, + 3: 34, + 4: 35, + 5: 36, + 6: 37, + 7: 38, + 8: 39, + 9: 40, + 10: 41, + 11: 42, + 12: 43, + 13: 44, + 14: 45, + 15: 46, + 16: 47, + 17: 48, + 18: 49, + 19: 50, + 20: 51, + 21: 52, + 22: 53, + 23: 54, + 24: 55, + 25: 56, + 26: 57, + 27: 58, + 28: 59, + 29: 60, + 30: 61, + 31: 62, + 32: 63, } @property @@ -65,11 +65,11 @@ def port_end(self): @property def qsfp_ports(self): - return range(self.PORT_START, self.PORTS_IN_BLOCK + 1) + return list(range(self.PORT_START, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): - return self._port_to_eeprom_mapping + return self._port_to_eeprom_mapping def __init__(self): eeprom_path = '/sys/bus/i2c/devices/{0}-0050/eeprom' @@ -85,7 +85,7 @@ def get_presence(self, port_num): try: reg_file = open("/sys/class/cpld-qsfp28/port-"+str(port_num)+"/module_present") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = reg_file.readline().rstrip() @@ -102,7 +102,7 @@ def get_low_power_mode(self, port_num): try: reg_file = open("/sys/class/cpld-qsfp28/port-"+str(port_num)+"/lpmode") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = int(reg_file.readline().rstrip()) @@ -120,7 +120,7 @@ def set_low_power_mode(self, port_num, lpmode): try: reg_file = open("/sys/class/cpld-qsfp28/port-"+str(port_num)+"/lpmode", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = int(reg_file.readline().rstrip()) @@ -144,7 +144,7 @@ def reset(self, port_num): try: reg_file = open("/sys/class/cpld-qsfp28/port-"+str(port_num)+"/reset", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = 0 @@ -158,7 +158,7 @@ def reset(self, port_num): try: reg_file = open("/sys/class/cpld-qsfp28/port-"+str(port_num)+"/reset", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = 1 diff --git a/device/quanta/x86_64-quanta_ix8_rglbmc-r0/Quanta-IX8-56X/sai.profile b/device/quanta/x86_64-quanta_ix8_rglbmc-r0/Quanta-IX8-56X/sai.profile index faf28ace4c10..62ee26ea8c15 100644 --- a/device/quanta/x86_64-quanta_ix8_rglbmc-r0/Quanta-IX8-56X/sai.profile +++ b/device/quanta/x86_64-quanta_ix8_rglbmc-r0/Quanta-IX8-56X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-ix8-48x25G+8x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/quanta/x86_64-quanta_ix8_rglbmc-r0/Quanta-IX8-56X/td3-ix8-48x25G+8x100G.config.bcm b/device/quanta/x86_64-quanta_ix8_rglbmc-r0/Quanta-IX8-56X/td3-ix8-48x25G+8x100G.config.bcm index e4c8f8b656e1..94560fb7e86c 100644 --- a/device/quanta/x86_64-quanta_ix8_rglbmc-r0/Quanta-IX8-56X/td3-ix8-48x25G+8x100G.config.bcm +++ b/device/quanta/x86_64-quanta_ix8_rglbmc-r0/Quanta-IX8-56X/td3-ix8-48x25G+8x100G.config.bcm @@ -1,3 +1,4 @@ +sai_load_hw_config=/etc/bcm/flex/bcm56870_a0_issu/b870.6.4.1/ bcm_tunnel_term_compatible_mode=1 core_clock_frequency=1525 dpp_clock_ratio=2:3 @@ -8,7 +9,7 @@ l3_mem_entries=40960 fpem_mem_entries=16384 l2xmsg_mode=1 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 cdma_timeout_usec=3000000 diff --git a/device/quanta/x86_64-quanta_ix8_rglbmc-r0/plugins/eeprom.py b/device/quanta/x86_64-quanta_ix8_rglbmc-r0/plugins/eeprom.py index 2a35f3a22a17..fa34110c04ea 100644 --- a/device/quanta/x86_64-quanta_ix8_rglbmc-r0/plugins/eeprom.py +++ b/device/quanta/x86_64-quanta_ix8_rglbmc-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -11,11 +8,13 @@ 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") +except ImportError as 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/18-0054/eeprom" super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/quanta/x86_64-quanta_ix8_rglbmc-r0/plugins/psuutil.py b/device/quanta/x86_64-quanta_ix8_rglbmc-r0/plugins/psuutil.py index 885842bbda5a..5cf06fb5d66a 100644 --- a/device/quanta/x86_64-quanta_ix8_rglbmc-r0/plugins/psuutil.py +++ b/device/quanta/x86_64-quanta_ix8_rglbmc-r0/plugins/psuutil.py @@ -8,7 +8,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" diff --git a/device/quanta/x86_64-quanta_ix8_rglbmc-r0/plugins/sfputil.py b/device/quanta/x86_64-quanta_ix8_rglbmc-r0/plugins/sfputil.py index 627c99fee0c9..3067919795d5 100644 --- a/device/quanta/x86_64-quanta_ix8_rglbmc-r0/plugins/sfputil.py +++ b/device/quanta/x86_64-quanta_ix8_rglbmc-r0/plugins/sfputil.py @@ -23,62 +23,62 @@ class SfpUtil(SfpUtilBase): _port_to_eeprom_mapping = {} _port_to_i2c_mapping = { - 1 : 32, - 2 : 33, - 3 : 34, - 4 : 35, - 5 : 36, - 6 : 37, - 7 : 38, - 8 : 39, - 9 : 40, - 10 : 41, - 11 : 42, - 12 : 43, - 13 : 44, - 14 : 45, - 15 : 46, - 16 : 47, - 17 : 48, - 18 : 49, - 19 : 50, - 20 : 51, - 21 : 52, - 22 : 53, - 23 : 54, - 24 : 55, - 25 : 56, - 26 : 57, - 27 : 58, - 28 : 59, - 29 : 60, - 30 : 61, - 31 : 62, - 32 : 63, - 33 : 64, - 34 : 65, - 35 : 66, - 36 : 67, - 37 : 68, - 38 : 69, - 39 : 70, - 40 : 71, - 41 : 72, - 42 : 73, - 43 : 74, - 44 : 75, - 45 : 76, - 46 : 77, - 47 : 78, - 48 : 79, - 49 : 80,#QSFP49 - 50 : 81,#QSFP50 - 51 : 82,#QSFP51 - 52 : 83,#QSFP52 - 53 : 84,#QSFP53 - 54 : 85,#QSFP54 - 55 : 86,#QSFP55 - 56 : 87,#QSFP56 + 1: 32, + 2: 33, + 3: 34, + 4: 35, + 5: 36, + 6: 37, + 7: 38, + 8: 39, + 9: 40, + 10: 41, + 11: 42, + 12: 43, + 13: 44, + 14: 45, + 15: 46, + 16: 47, + 17: 48, + 18: 49, + 19: 50, + 20: 51, + 21: 52, + 22: 53, + 23: 54, + 24: 55, + 25: 56, + 26: 57, + 27: 58, + 28: 59, + 29: 60, + 30: 61, + 31: 62, + 32: 63, + 33: 64, + 34: 65, + 35: 66, + 36: 67, + 37: 68, + 38: 69, + 39: 70, + 40: 71, + 41: 72, + 42: 73, + 43: 74, + 44: 75, + 45: 76, + 46: 77, + 47: 78, + 48: 79, + 49: 80, # QSFP49 + 50: 81, # QSFP50 + 51: 82, # QSFP51 + 52: 83, # QSFP52 + 53: 84, # QSFP53 + 54: 85, # QSFP54 + 55: 86, # QSFP55 + 56: 87, # QSFP56 } @property @@ -99,11 +99,11 @@ def qsfp_port_end(self): @property def qsfp_ports(self): - return range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1) + return list(range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): - return self._port_to_eeprom_mapping + return self._port_to_eeprom_mapping def __init__(self): eeprom_path = '/sys/bus/i2c/devices/{0}-0050/eeprom' @@ -122,7 +122,7 @@ def get_presence(self, port_num): else: reg_file = open("/sys/class/gpio/gpio"+str((port_num-self.qsfp_port_start)*4+34)+"/value") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = reg_file.readline().rstrip() @@ -143,7 +143,7 @@ def get_low_power_mode(self, port_num): try: reg_file = open("/sys/class/gpio/gpio"+str((port_num-self.qsfp_port_start)*4+35)+"/value") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = int(reg_file.readline().rstrip()) @@ -161,7 +161,7 @@ def set_low_power_mode(self, port_num, lpmode): try: reg_file = open("/sys/class/gpio/gpio"+str((port_num-self.qsfp_port_start)*4+35)+"/value", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = int(reg_file.readline().rstrip()) @@ -185,7 +185,7 @@ def reset(self, port_num): try: reg_file = open("/sys/class/gpio/gpio"+str((port_num-self.qsfp_port_start)*4+32)+"/value", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = 0 @@ -199,7 +199,7 @@ def reset(self, port_num): try: reg_file = open("/sys/class/gpio/gpio"+str((port_num-self.qsfp_port_start)*4+32)+"/value", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = 1 diff --git a/device/quanta/x86_64-quanta_ix8c_bwde-r0/Quanta-IX8C-56X/sai.profile b/device/quanta/x86_64-quanta_ix8c_bwde-r0/Quanta-IX8C-56X/sai.profile index 04b43d5a4d33..936f0d0cddcf 100644 --- a/device/quanta/x86_64-quanta_ix8c_bwde-r0/Quanta-IX8C-56X/sai.profile +++ b/device/quanta/x86_64-quanta_ix8c_bwde-r0/Quanta-IX8C-56X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-ix8c-48x25G+8x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/quanta/x86_64-quanta_ix8c_bwde-r0/Quanta-IX8C-56X/td3-ix8c-48x25G+8x100G.config.bcm b/device/quanta/x86_64-quanta_ix8c_bwde-r0/Quanta-IX8C-56X/td3-ix8c-48x25G+8x100G.config.bcm index e4c8f8b656e1..94560fb7e86c 100644 --- a/device/quanta/x86_64-quanta_ix8c_bwde-r0/Quanta-IX8C-56X/td3-ix8c-48x25G+8x100G.config.bcm +++ b/device/quanta/x86_64-quanta_ix8c_bwde-r0/Quanta-IX8C-56X/td3-ix8c-48x25G+8x100G.config.bcm @@ -1,3 +1,4 @@ +sai_load_hw_config=/etc/bcm/flex/bcm56870_a0_issu/b870.6.4.1/ bcm_tunnel_term_compatible_mode=1 core_clock_frequency=1525 dpp_clock_ratio=2:3 @@ -8,7 +9,7 @@ l3_mem_entries=40960 fpem_mem_entries=16384 l2xmsg_mode=1 -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 cdma_timeout_usec=3000000 diff --git a/device/quanta/x86_64-quanta_ix8c_bwde-r0/plugins/eeprom.py b/device/quanta/x86_64-quanta_ix8c_bwde-r0/plugins/eeprom.py index 2a35f3a22a17..fa34110c04ea 100644 --- a/device/quanta/x86_64-quanta_ix8c_bwde-r0/plugins/eeprom.py +++ b/device/quanta/x86_64-quanta_ix8c_bwde-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -11,11 +8,13 @@ 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") +except ImportError as 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/18-0054/eeprom" super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/quanta/x86_64-quanta_ix8c_bwde-r0/plugins/psuutil.py b/device/quanta/x86_64-quanta_ix8c_bwde-r0/plugins/psuutil.py index cc9be248aa1b..319c35d490e4 100644 --- a/device/quanta/x86_64-quanta_ix8c_bwde-r0/plugins/psuutil.py +++ b/device/quanta/x86_64-quanta_ix8c_bwde-r0/plugins/psuutil.py @@ -8,7 +8,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" diff --git a/device/quanta/x86_64-quanta_ix8c_bwde-r0/plugins/sfputil.py b/device/quanta/x86_64-quanta_ix8c_bwde-r0/plugins/sfputil.py index 627c99fee0c9..3067919795d5 100644 --- a/device/quanta/x86_64-quanta_ix8c_bwde-r0/plugins/sfputil.py +++ b/device/quanta/x86_64-quanta_ix8c_bwde-r0/plugins/sfputil.py @@ -23,62 +23,62 @@ class SfpUtil(SfpUtilBase): _port_to_eeprom_mapping = {} _port_to_i2c_mapping = { - 1 : 32, - 2 : 33, - 3 : 34, - 4 : 35, - 5 : 36, - 6 : 37, - 7 : 38, - 8 : 39, - 9 : 40, - 10 : 41, - 11 : 42, - 12 : 43, - 13 : 44, - 14 : 45, - 15 : 46, - 16 : 47, - 17 : 48, - 18 : 49, - 19 : 50, - 20 : 51, - 21 : 52, - 22 : 53, - 23 : 54, - 24 : 55, - 25 : 56, - 26 : 57, - 27 : 58, - 28 : 59, - 29 : 60, - 30 : 61, - 31 : 62, - 32 : 63, - 33 : 64, - 34 : 65, - 35 : 66, - 36 : 67, - 37 : 68, - 38 : 69, - 39 : 70, - 40 : 71, - 41 : 72, - 42 : 73, - 43 : 74, - 44 : 75, - 45 : 76, - 46 : 77, - 47 : 78, - 48 : 79, - 49 : 80,#QSFP49 - 50 : 81,#QSFP50 - 51 : 82,#QSFP51 - 52 : 83,#QSFP52 - 53 : 84,#QSFP53 - 54 : 85,#QSFP54 - 55 : 86,#QSFP55 - 56 : 87,#QSFP56 + 1: 32, + 2: 33, + 3: 34, + 4: 35, + 5: 36, + 6: 37, + 7: 38, + 8: 39, + 9: 40, + 10: 41, + 11: 42, + 12: 43, + 13: 44, + 14: 45, + 15: 46, + 16: 47, + 17: 48, + 18: 49, + 19: 50, + 20: 51, + 21: 52, + 22: 53, + 23: 54, + 24: 55, + 25: 56, + 26: 57, + 27: 58, + 28: 59, + 29: 60, + 30: 61, + 31: 62, + 32: 63, + 33: 64, + 34: 65, + 35: 66, + 36: 67, + 37: 68, + 38: 69, + 39: 70, + 40: 71, + 41: 72, + 42: 73, + 43: 74, + 44: 75, + 45: 76, + 46: 77, + 47: 78, + 48: 79, + 49: 80, # QSFP49 + 50: 81, # QSFP50 + 51: 82, # QSFP51 + 52: 83, # QSFP52 + 53: 84, # QSFP53 + 54: 85, # QSFP54 + 55: 86, # QSFP55 + 56: 87, # QSFP56 } @property @@ -99,11 +99,11 @@ def qsfp_port_end(self): @property def qsfp_ports(self): - return range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1) + return list(range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1)) @property def port_to_eeprom_mapping(self): - return self._port_to_eeprom_mapping + return self._port_to_eeprom_mapping def __init__(self): eeprom_path = '/sys/bus/i2c/devices/{0}-0050/eeprom' @@ -122,7 +122,7 @@ def get_presence(self, port_num): else: reg_file = open("/sys/class/gpio/gpio"+str((port_num-self.qsfp_port_start)*4+34)+"/value") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = reg_file.readline().rstrip() @@ -143,7 +143,7 @@ def get_low_power_mode(self, port_num): try: reg_file = open("/sys/class/gpio/gpio"+str((port_num-self.qsfp_port_start)*4+35)+"/value") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = int(reg_file.readline().rstrip()) @@ -161,7 +161,7 @@ def set_low_power_mode(self, port_num, lpmode): try: reg_file = open("/sys/class/gpio/gpio"+str((port_num-self.qsfp_port_start)*4+35)+"/value", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = int(reg_file.readline().rstrip()) @@ -185,7 +185,7 @@ def reset(self, port_num): try: reg_file = open("/sys/class/gpio/gpio"+str((port_num-self.qsfp_port_start)*4+32)+"/value", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = 0 @@ -199,7 +199,7 @@ def reset(self, port_num): try: reg_file = open("/sys/class/gpio/gpio"+str((port_num-self.qsfp_port_start)*4+32)+"/value", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = 1 diff --git a/device/quanta/x86_64-quanta_ix9_bwde-r0/Quanta-IX9-32X/sai.profile b/device/quanta/x86_64-quanta_ix9_bwde-r0/Quanta-IX9-32X/sai.profile index 54b62b1d097c..70397851c909 100644 --- a/device/quanta/x86_64-quanta_ix9_bwde-r0/Quanta-IX9-32X/sai.profile +++ b/device/quanta/x86_64-quanta_ix9_bwde-r0/Quanta-IX9-32X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-ix9-32x400G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/quanta/x86_64-quanta_ix9_bwde-r0/plugins/eeprom.py b/device/quanta/x86_64-quanta_ix9_bwde-r0/plugins/eeprom.py index 2a35f3a22a17..fa34110c04ea 100644 --- a/device/quanta/x86_64-quanta_ix9_bwde-r0/plugins/eeprom.py +++ b/device/quanta/x86_64-quanta_ix9_bwde-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -11,11 +8,13 @@ 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") +except ImportError as 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/18-0054/eeprom" super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/quanta/x86_64-quanta_ix9_bwde-r0/plugins/psuutil.py b/device/quanta/x86_64-quanta_ix9_bwde-r0/plugins/psuutil.py index 885842bbda5a..5cf06fb5d66a 100644 --- a/device/quanta/x86_64-quanta_ix9_bwde-r0/plugins/psuutil.py +++ b/device/quanta/x86_64-quanta_ix9_bwde-r0/plugins/psuutil.py @@ -8,7 +8,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" diff --git a/device/quanta/x86_64-quanta_ix9_bwde-r0/plugins/sfputil.py b/device/quanta/x86_64-quanta_ix9_bwde-r0/plugins/sfputil.py index 6dc23d8195f4..832dac4e0570 100644 --- a/device/quanta/x86_64-quanta_ix9_bwde-r0/plugins/sfputil.py +++ b/device/quanta/x86_64-quanta_ix9_bwde-r0/plugins/sfputil.py @@ -1,10 +1,8 @@ -#!/usr/bin/env python - try: import time - from sonic_sfp.sfputilbase import SfpUtilBase -except ImportError, e: - raise ImportError (str(e) + "- required module not found") + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class SfpUtil(SfpUtilBase): @@ -16,41 +14,41 @@ class SfpUtil(SfpUtilBase): _port_to_eeprom_mapping = {} port_to_i2c_mapping = { - 1 : 32, - 2 : 33, - 3 : 34, - 4 : 35, - 5 : 36, - 6 : 37, - 7 : 38, - 8 : 39, - 9 : 40, - 10 : 41, - 11 : 42, - 12 : 43, - 13 : 44, - 14 : 45, - 15 : 46, - 16 : 47, - 17 : 48, - 18 : 49, - 19 : 50, - 20 : 51, - 21 : 52, - 22 : 53, - 23 : 54, - 24 : 55, - 25 : 56, - 26 : 57, - 27 : 58, - 28 : 59, - 29 : 60, - 30 : 61, - 31 : 62, - 32 : 63, + 1: 32, + 2: 33, + 3: 34, + 4: 35, + 5: 36, + 6: 37, + 7: 38, + 8: 39, + 9: 40, + 10: 41, + 11: 42, + 12: 43, + 13: 44, + 14: 45, + 15: 46, + 16: 47, + 17: 48, + 18: 49, + 19: 50, + 20: 51, + 21: 52, + 22: 53, + 23: 54, + 24: 55, + 25: 56, + 26: 57, + 27: 58, + 28: 59, + 29: 60, + 30: 61, + 31: 62, + 32: 63, } - _qsfp_ports = range(0, ports_in_block + 1) + _qsfp_ports = list(range(0, ports_in_block + 1)) def __init__(self): eeprom_path = '/sys/bus/i2c/devices/{0}-0050/eeprom' @@ -67,7 +65,7 @@ def reset(self, port_num): try: reg_file = open("/sys/class/cpld-qsfpdd/port-"+str(port_num+1)+"/reset", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = 0 @@ -81,7 +79,7 @@ def reset(self, port_num): try: reg_file = open("/sys/class/cpld-qsfpdd/port-"+str(port_num+1)+"/reset", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = 1 @@ -91,14 +89,14 @@ def reset(self, port_num): return True def set_low_power_mode(self, port_num, lpmode): - # Check for invalid port_num + # Check for invalid port_num if port_num < self.port_start or port_num > self.port_end: return False try: reg_file = open("/sys/class/cpld-qsfpdd/port-"+str(port_num+1)+"/lpmode", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = int(reg_file.readline().rstrip()) @@ -115,14 +113,14 @@ def set_low_power_mode(self, port_num, lpmode): return True def get_low_power_mode(self, port_num): - # Check for invalid port_num + # Check for invalid port_num if port_num < self.port_start or port_num > self.port_end: return False try: reg_file = open("/sys/class/cpld-qsfpdd/port-"+str(port_num+1)+"/lpmode") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = int(reg_file.readline().rstrip()) @@ -131,16 +129,16 @@ def get_low_power_mode(self, port_num): return False return True - + def get_presence(self, port_num): # Check for invalid port_num if port_num < self._port_start or port_num > self._port_end: return False - + try: reg_file = open("/sys/class/cpld-qsfpdd/port-"+str(port_num+1)+"/module_present") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = reg_file.readline().rstrip() @@ -156,14 +154,14 @@ def port_start(self): @property def port_end(self): return self._port_end - + @property def qsfp_ports(self): - return range(0, self.ports_in_block + 1) + return list(range(0, self.ports_in_block + 1)) - @property + @property def port_to_eeprom_mapping(self): - return self._port_to_eeprom_mapping + return self._port_to_eeprom_mapping def get_transceiver_change_event(self): """ @@ -172,5 +170,3 @@ def get_transceiver_change_event(self): on this platform. """ raise NotImplementedError - - diff --git a/device/virtual/x86_64-kvm_x86_64-r0/README.md b/device/virtual/x86_64-kvm_x86_64-r0/README.md new file mode 100644 index 000000000000..0347432d67b4 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/README.md @@ -0,0 +1,88 @@ +# Changing the virtual device + +You can control the hw sku and default factory configuration for the VS image +by modifying the content of the file default_sku in this directory. + +The format of default_sku is a single line: + +``` + +``` + +## Allowable values for hw_key + +| hw_key | Device | +| ------ | ------ | +| Force10-S6000 | Dell Force10 S6000| +| brcm_gearbox_vs | Similar to Force10-S6000, but implements a virtual BRCM81724 Gearbox Phy | + +## Allowable values for default_preset + +These include "t1", "l2", and "empty". See the file +sonic-buildimage/src/sonic-config-engine/config_samples.py for details on how +each default_preset value is interpreted. + +# Changing the hwsku of an existing VS switch + +To change the default hwsku for a VS image that has already been built and installed, follow these steps: + +- Edit /usr/share/sonic/device/x86_64-kvm_x86_64-r0/default_sku. For details, see the section below (Device Specific Documentation) +- Edit /etc/sonic/config_db.json, and change the "hwsku" key in DEVICE_METADATA:localhost to match the hw_key used in default_sku. Example: + + "DEVICE_METADATA": { + "localhost": { + ... + "hwsku": "brcm_gearbox_vs", + ... + } + }, + ... +- Reboot the switch +- Use "show platform summary" to verify, and follow any steps specific to the platform, as needed, such as those described below for the brcm_gearbox_vs hwsku. + +# Device Specific Documentation + +For general info on building, see https://github.com/Azure/sonic-buildimage/blob/master/README.md + +## Force-10-S6000 + +This is the default VS for SONiC. To enable, set contents of default_sku to: + +``` +Force10-S6000 t1 +``` + +To build: + +``` +make init +make configure PLATFORM=vs +make target/sonic-vs.img.gz +``` + +## brcm_gearbox_vs + +This sku simulates a device with a Broadcom BRCM81724 gearbox PHY. To enable, +set default_sku to: + + +``` +brcm_gearbox_vs t1 +``` + +To build (same as Force-10-S6000): + +``` +make init +make configure PLATFORM=vs +make target/sonic-vs.img.gz +``` + +To verify, install and bring up SONiC. There will be a new gbsyncd docker +which is designed to respond to configuration directed towards the gearbox phy +"switch". swss will create that gearbox switch on startup after detecting the +gearbox is present (this is done by a short lived gearsyncd that runs in the +swss docker). + +The commands "show gearbox interfaces status" and "show gearbox phys status" can be +used to verify the virtual gearbox phy has been created. See https://github.com/Azure/sonic-utilities/blob/master/doc/Command-Reference.md#gearbox for details. diff --git a/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers.json.j2 new file mode 100644 index 000000000000..b67cf577ab75 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/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/brcm_gearbox_vs/buffers_defaults_def.j2 b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers_defaults_def.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/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/brcm_gearbox_vs/buffers_defaults_t0.j2 b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/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/brcm_gearbox_vs/buffers_defaults_t1.j2 b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/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/brcm_gearbox_vs/context_config.json b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/context_config.json new file mode 100644 index 000000000000..9f9f80ba0d36 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/context_config.json @@ -0,0 +1,32 @@ +{ + "CONTEXTS": [ + { + "guid" : 0, + "name" : "sw0", + "dbAsic" : "ASIC_DB", + "dbCounters" : "COUNTERS_DB", + "dbFlex": "FLEX_COUNTER_DB", + "dbState" : "STATE_DB", + "switches": [ + { + "index" : 0, + "hwinfo" : "" + } + ] + }, + { + "guid" : 1, + "name" : "phy1", + "dbAsic" : "GB_ASIC_DB", + "dbCounters" : "GB_COUNTERS_DB", + "dbFlex": "GB_FLEX_COUNTER_DB", + "dbState" : "STATE_DB", + "switches": [ + { + "index" : 1, + "hwinfo" : "" + } + ] + } + ] +} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/gearbox_config.json b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/gearbox_config.json new file mode 100644 index 000000000000..2de95c4d806d --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/gearbox_config.json @@ -0,0 +1,38 @@ +{ + "phys": [ + { + "phy_id": 1, + "name": "sesto-1", + "address": "0x1000", + "lib_name": "libsai_phy_sesto-1.so", + "firmware_path": "/tmp/phy-sesto-1.bin", + "config_file": "/usr/share/sonic/hwsku/phy1_config_1.json", + "sai_init_config_file": "/usr/share/sonic/hwsku/sesto-1.bcm", + "phy_access": "mdio", + "bus_id": 0 + } + ], + "interfaces": [ + { + "name": "Ethernet0", + "index": 0, + "phy_id" : 1, + "system_lanes": [200,201], + "line_lanes": [206] + }, + { + "name": "Ethernet4", + "index": 1, + "phy_id" : 1, + "system_lanes": [202,203], + "line_lanes": [207] + }, + { + "name": "Ethernet8", + "index": 2, + "phy_id" : 1, + "system_lanes": [204,205], + "line_lanes": [208] + } + ] +} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/lanemap.ini b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/lanemap.ini new file mode 100644 index 000000000000..36278a01778c --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/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/brcm_gearbox_vs/pg_profile_lookup.ini b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/pg_profile_lookup.ini new file mode 100644 index 000000000000..9f2eacb6fc42 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/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/brcm_gearbox_vs/phy1_config_1.json b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/phy1_config_1.json new file mode 100644 index 000000000000..1b81394e9936 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/phy1_config_1.json @@ -0,0 +1,168 @@ +{ + "lanes": [ + { + "index": 200, + "local_lane_id": 0, + "system_side": true, + "tx_polarity": 0, + "rx_polarity": 0, + "line_tx_lanemap": 0, + "line_rx_lanemap": 0, + "line_to_system_lanemap": 0, + "mdio_addr": "0x0200" + }, + { + "index": 201, + "local_lane_id": 0, + "system_side": true, + "tx_polarity": 0, + "rx_polarity": 0, + "line_tx_lanemap": 0, + "line_rx_lanemap": 0, + "line_to_system_lanemap": 0, + "mdio_addr": "0x0201" + }, + { + "index": 202, + "local_lane_id": 0, + "system_side": true, + "tx_polarity": 0, + "rx_polarity": 0, + "line_tx_lanemap": 0, + "line_rx_lanemap": 0, + "line_to_system_lanemap": 0, + "mdio_addr": "0x0202" + }, + { + "index": 203, + "local_lane_id": 0, + "system_side": true, + "tx_polarity": 0, + "rx_polarity": 0, + "line_tx_lanemap": 0, + "line_rx_lanemap": 0, + "line_to_system_lanemap": 0, + "mdio_addr": "0x0203" + }, + { + "index": 204, + "local_lane_id": 0, + "system_side": false, + "tx_polarity": 0, + "rx_polarity": 0, + "line_tx_lanemap": 0, + "line_rx_lanemap": 0, + "line_to_system_lanemap": 200, + "mdio_addr": "0x0204" + }, + { + "index": 205, + "local_lane_id": 0, + "system_side": false, + "tx_polarity": 0, + "rx_polarity": 0, + "line_tx_lanemap": 0, + "line_rx_lanemap": 0, + "line_to_system_lanemap": 202, + "mdio_addr": "0x0205" + }, + { + "index": 206, + "local_lane_id": 0, + "system_side": true, + "tx_polarity": 0, + "rx_polarity": 0, + "line_tx_lanemap": 0, + "line_rx_lanemap": 0, + "line_to_system_lanemap": 0, + "mdio_addr": "0x0206" + }, + { + "index": 207, + "local_lane_id": 0, + "system_side": false, + "tx_polarity": 0, + "rx_polarity": 0, + "line_tx_lanemap": 0, + "line_rx_lanemap": 0, + "line_to_system_lanemap": 0, + "mdio_addr": "0x0207" + }, + { + "index": 208, + "local_lane_id": 0, + "system_side": true, + "tx_polarity": 0, + "rx_polarity": 0, + "line_tx_lanemap": 0, + "line_rx_lanemap": 0, + "line_to_system_lanemap": 0, + "mdio_addr": "0x0208" + } + ], + "ports": [ + { + "index": 0, + "mdio_addr": "0x2000", + "system_speed": 20000, + "system_fec": "none", + "system_auto_neg": true, + "system_loopback": "none", + "system_training": false, + "line_speed": 40000, + "line_fec": "none", + "line_auto_neg": true, + "line_media_type": "fiber", + "line_intf_type": "none", + "line_loopback": "none", + "line_training": false, + "line_adver_speed": [], + "line_adver_fec": [], + "line_adver_auto_neg": false, + "line_adver_asym_pause": false, + "line_adver_media_type": "fiber" + }, + { + "index": 1, + "mdio_addr": "0x3000", + "system_speed": 20000, + "system_fec": "none", + "system_auto_neg": true, + "system_loopback": "none", + "system_training": false, + "line_speed": 40000, + "line_fec": "none", + "line_auto_neg": true, + "line_media_type": "fiber", + "line_intf_type": "none", + "line_loopback": "none", + "line_training": false, + "line_adver_speed": [], + "line_adver_fec": [], + "line_adver_auto_neg": false, + "line_adver_asym_pause": false, + "line_adver_media_type": "fiber" + }, + { + "index": 2, + "mdio_addr": "0x4000", + "system_speed": 20000, + "system_fec": "none", + "system_auto_neg": true, + "system_loopback": "none", + "system_training": false, + "line_speed": 40000, + "line_fec": "none", + "line_auto_neg": true, + "line_media_type": "fiber", + "line_intf_type": "none", + "line_loopback": "none", + "line_training": false, + "line_adver_speed": [], + "line_adver_fec": [], + "line_adver_auto_neg": false, + "line_adver_asym_pause": false, + "line_adver_media_type": "fiber" + } + ] +} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/port_config.ini b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/port_config.ini new file mode 100644 index 000000000000..95cf5eec9e4e --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/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/brcm_gearbox_vs/qos.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/sai.profile new file mode 100644 index 000000000000..0a2df177f1c5 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/sai.profile @@ -0,0 +1,3 @@ +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/brcm_gearbox_vs/td2-s6000-32x40G.config.bcm b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/td2-s6000-32x40G.config.bcm new file mode 100644 index 000000000000..4c94db7107c7 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/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/installer.conf b/device/virtual/x86_64-kvm_x86_64-r0/installer.conf index e69de29bb2d1..530ee964f330 100644 --- a/device/virtual/x86_64-kvm_x86_64-r0/installer.conf +++ b/device/virtual/x86_64-kvm_x86_64-r0/installer.conf @@ -0,0 +1 @@ +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="swiotlb=65536" 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/port_config.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/port_config.ini index 95cf5eec9e4e..3ec90708cc05 100644 --- 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 @@ -1,33 +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 +# name lanes alias index asic_port_name role speed +Ethernet0 25,26,27,28 Ethernet1/1 0 Eth0-ASIC0 Ext 40000 +Ethernet4 29,30,31,32 Ethernet1/2 1 Eth1-ASIC0 Ext 40000 +Ethernet8 33,34,35,36 Ethernet1/3 2 Eth2-ASIC0 Ext 40000 +Ethernet12 37,38,39,40 Ethernet1/4 3 Eth3-ASIC0 Ext 40000 +Ethernet16 45,46,47,48 Ethernet1/5 4 Eth4-ASIC0 Ext 40000 +Ethernet20 41,42,43,44 Ethernet1/6 5 Eth5-ASIC0 Ext 40000 +Ethernet24 1,2,3,4 Ethernet1/7 6 Eth6-ASIC0 Ext 40000 +Ethernet28 5,6,7,8 Ethernet1/8 7 Eth7-ASIC0 Ext 40000 +Ethernet32 13,14,15,16 Ethernet1/9 8 Eth8-ASIC0 Ext 40000 +Ethernet36 9,10,11,12 Ethernet1/10 9 Eth9-ASIC0 Ext 40000 +Ethernet40 17,18,19,20 Ethernet1/11 10 Eth10-ASIC0 Ext 40000 +Ethernet44 21,22,23,24 Ethernet1/12 11 Eth11-ASIC0 Ext 40000 +Ethernet48 53,54,55,56 Ethernet1/13 12 Eth12-ASIC0 Ext 40000 +Ethernet52 49,50,51,52 Ethernet1/14 13 Eth13-ASIC0 Ext 40000 +Ethernet56 57,58,59,60 Ethernet1/15 14 Eth14-ASIC0 Ext 40000 +Ethernet60 61,62,63,64 Ethernet1/16 15 Eth15-ASIC0 Ext 40000 +Ethernet-BP0 69,70,71,72 Eth16-ASIC0 0 Eth16-ASIC0 Int 40000 +Ethernet-BP4 65,66,67,68 Eth17-ASIC0 1 Eth17-ASIC0 Int 40000 +Ethernet-BP8 73,74,75,76 Eth18-ASIC0 2 Eth18-ASIC0 Int 40000 +Ethernet-BP12 77,78,79,80 Eth19-ASIC0 3 Eth19-ASIC0 Int 40000 +Ethernet-BP16 109,110,111,112 Eth20-ASIC0 4 Eth20-ASIC0 Int 40000 +Ethernet-BP20 105,106,107,108 Eth21-ASIC0 5 Eth21-ASIC0 Int 40000 +Ethernet-BP24 113,114,115,116 Eth22-ASIC0 6 Eth22-ASIC0 Int 40000 +Ethernet-BP28 117,118,119,120 Eth23-ASIC0 7 Eth23-ASIC0 Int 40000 +Ethernet-BP32 125,126,127,128 Eth24-ASIC0 8 Eth24-ASIC0 Int 40000 +Ethernet-BP36 121,122,123,124 Eth25-ASIC0 9 Eth25-ASIC0 Int 40000 +Ethernet-BP40 81,82,83,84 Eth26-ASIC0 10 Eth26-ASIC0 Int 40000 +Ethernet-BP44 85,86,87,88 Eth27-ASIC0 11 Eth27-ASIC0 Int 40000 +Ethernet-BP48 93,94,95,96 Eth28-ASIC0 12 Eth28-ASIC0 Int 40000 +Ethernet-BP52 89,90,91,92 Eth29-ASIC0 13 Eth29-ASIC0 Int 40000 +Ethernet-BP56 101,102,103,104 Eth30-ASIC0 14 Eth30-ASIC0 Int 40000 +Ethernet-BP60 97,98,99,100 Eth31-ASIC0 15 Eth31-ASIC0 Int 40000 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..0a2df177f1c5 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,3 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm -SAI_NUM_ECMP_MEMBERS=32 +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/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 index 4c94db7107c7..0e25b4d4232d 100644 --- 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 @@ -20,7 +20,7 @@ parity_enable=1 stat_if_parity_enable=0 # -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 l2xmsg_hostbuf_size=8192 l2xmsg_mode=1 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/port_config.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/port_config.ini index 95cf5eec9e4e..61d38693526e 100644 --- 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 @@ -1,33 +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 +# name lanes alias index asic_port_name role speed +Ethernet64 25,26,27,28 Ethernet1/17 16 Eth0-ASIC1 Ext 40000 +Ethernet68 29,30,31,32 Ethernet1/18 17 Eth1-ASIC1 Ext 40000 +Ethernet72 33,34,35,36 Ethernet1/19 18 Eth2-ASIC1 Ext 40000 +Ethernet76 37,38,39,40 Ethernet1/20 19 Eth3-ASIC1 Ext 40000 +Ethernet80 45,46,47,48 Ethernet1/21 20 Eth4-ASIC1 Ext 40000 +Ethernet84 41,42,43,44 Ethernet1/22 21 Eth5-ASIC1 Ext 40000 +Ethernet88 1,2,3,4 Ethernet1/23 22 Eth6-ASIC1 Ext 40000 +Ethernet92 5,6,7,8 Ethernet1/24 23 Eth7-ASIC1 Ext 40000 +Ethernet96 13,14,15,16 Ethernet1/25 24 Eth8-ASIC1 Ext 40000 +Ethernet100 9,10,11,12 Ethernet1/26 25 Eth9-ASIC1 Ext 40000 +Ethernet104 17,18,19,20 Ethernet1/27 26 Eth10-ASIC1 Ext 40000 +Ethernet108 21,22,23,24 Ethernet1/28 27 Eth11-ASIC1 Ext 40000 +Ethernet112 53,54,55,56 Ethernet1/29 28 Eth12-ASIC1 Ext 40000 +Ethernet116 49,50,51,52 Ethernet1/30 29 Eth13-ASIC1 Ext 40000 +Ethernet120 57,58,59,60 Ethernet1/31 30 Eth14-ASIC1 Ext 40000 +Ethernet124 61,62,63,64 Ethernet1/32 31 Eth15-ASIC1 Ext 40000 +Ethernet-BP64 69,70,71,72 Eth16-ASIC1 16 Eth16-ASIC1 Int 40000 +Ethernet-BP68 65,66,67,68 Eth17-ASIC1 17 Eth17-ASIC1 Int 40000 +Ethernet-BP72 73,74,75,76 Eth18-ASIC1 18 Eth18-ASIC1 Int 40000 +Ethernet-BP76 77,78,79,80 Eth19-ASIC1 19 Eth19-ASIC1 Int 40000 +Ethernet-BP80 109,110,111,112 Eth20-ASIC1 20 Eth20-ASIC1 Int 40000 +Ethernet-BP84 105,106,107,108 Eth21-ASIC1 21 Eth21-ASIC1 Int 40000 +Ethernet-BP88 113,114,115,116 Eth22-ASIC1 22 Eth22-ASIC1 Int 40000 +Ethernet-BP92 117,118,119,120 Eth23-ASIC1 23 Eth23-ASIC1 Int 40000 +Ethernet-BP96 125,126,127,128 Eth24-ASIC1 24 Eth24-ASIC1 Int 40000 +Ethernet-BP100 121,122,123,124 Eth25-ASIC1 25 Eth25-ASIC1 Int 40000 +Ethernet-BP104 81,82,83,84 Eth26-ASIC1 26 Eth26-ASIC1 Int 40000 +Ethernet-BP108 85,86,87,88 Eth27-ASIC1 27 Eth27-ASIC1 Int 40000 +Ethernet-BP112 93,94,95,96 Eth28-ASIC1 28 Eth28-ASIC1 Int 40000 +Ethernet-BP116 89,90,91,92 Eth29-ASIC1 29 Eth29-ASIC1 Int 40000 +Ethernet-BP120 101,102,103,104 Eth30-ASIC1 30 Eth30-ASIC1 Int 40000 +Ethernet-BP124 97,98,99,100 Eth31-ASIC1 31 Eth31-ASIC1 Int 40000 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..0a2df177f1c5 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,3 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm -SAI_NUM_ECMP_MEMBERS=32 +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/td2-s6000-32x40G.config.bcm b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/td2-s6000-32x40G.config.bcm index 4c94db7107c7..0e25b4d4232d 100644 --- 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 @@ -20,7 +20,7 @@ parity_enable=1 stat_if_parity_enable=0 # -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 l2xmsg_hostbuf_size=8192 l2xmsg_mode=1 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/port_config.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/port_config.ini index 95cf5eec9e4e..af8a37f09549 100644 --- 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 @@ -1,33 +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 +# name lanes alias index asic_port_name role speed +Ethernet128 25,26,27,28 Ethernet1/33 32 Eth0-ASIC2 Ext 40000 +Ethernet132 29,30,31,32 Ethernet1/34 33 Eth1-ASIC2 Ext 40000 +Ethernet136 33,34,35,36 Ethernet1/35 34 Eth2-ASIC2 Ext 40000 +Ethernet140 37,38,39,40 Ethernet1/36 35 Eth3-ASIC2 Ext 40000 +Ethernet144 45,46,47,48 Ethernet1/37 36 Eth4-ASIC2 Ext 40000 +Ethernet148 41,42,43,44 Ethernet1/38 37 Eth5-ASIC2 Ext 40000 +Ethernet152 1,2,3,4 Ethernet1/39 38 Eth6-ASIC2 Ext 40000 +Ethernet156 5,6,7,8 Ethernet1/40 39 Eth7-ASIC2 Ext 40000 +Ethernet160 13,14,15,16 Ethernet1/41 40 Eth8-ASIC2 Ext 40000 +Ethernet164 9,10,11,12 Ethernet1/42 41 Eth9-ASIC2 Ext 40000 +Ethernet168 17,18,19,20 Ethernet1/43 42 Eth10-ASIC2 Ext 40000 +Ethernet172 21,22,23,24 Ethernet1/44 43 Eth11-ASIC2 Ext 40000 +Ethernet176 53,54,55,56 Ethernet1/45 44 Eth12-ASIC2 Ext 40000 +Ethernet180 49,50,51,52 Ethernet1/46 45 Eth13-ASIC2 Ext 40000 +Ethernet184 57,58,59,60 Ethernet1/47 46 Eth14-ASIC2 Ext 40000 +Ethernet188 61,62,63,64 Ethernet1/48 47 Eth15-ASIC2 Ext 40000 +Ethernet-BP128 69,70,71,72 Eth16-ASIC2 32 Eth16-ASIC2 Int 40000 +Ethernet-BP132 65,66,67,68 Eth17-ASIC2 33 Eth17-ASIC2 Int 40000 +Ethernet-BP136 73,74,75,76 Eth18-ASIC2 34 Eth18-ASIC2 Int 40000 +Ethernet-BP140 77,78,79,80 Eth19-ASIC2 35 Eth19-ASIC2 Int 40000 +Ethernet-BP144 109,110,111,112 Eth20-ASIC2 36 Eth20-ASIC2 Int 40000 +Ethernet-BP148 105,106,107,108 Eth21-ASIC2 37 Eth21-ASIC2 Int 40000 +Ethernet-BP152 113,114,115,116 Eth22-ASIC2 38 Eth22-ASIC2 Int 40000 +Ethernet-BP156 117,118,119,120 Eth23-ASIC2 39 Eth23-ASIC2 Int 40000 +Ethernet-BP160 125,126,127,128 Eth24-ASIC2 40 Eth24-ASIC2 Int 40000 +Ethernet-BP164 121,122,123,124 Eth25-ASIC2 41 Eth25-ASIC2 Int 40000 +Ethernet-BP168 81,82,83,84 Eth26-ASIC2 42 Eth26-ASIC2 Int 40000 +Ethernet-BP172 85,86,87,88 Eth27-ASIC2 43 Eth27-ASIC2 Int 40000 +Ethernet-BP176 93,94,95,96 Eth28-ASIC2 44 Eth28-ASIC2 Int 40000 +Ethernet-BP180 89,90,91,92 Eth29-ASIC2 45 Eth29-ASIC2 Int 40000 +Ethernet-BP184 101,102,103,104 Eth30-ASIC2 46 Eth30-ASIC2 Int 40000 +Ethernet-BP188 97,98,99,100 Eth31-ASIC2 47 Eth31-ASIC2 Int 40000 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..0a2df177f1c5 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,3 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm -SAI_NUM_ECMP_MEMBERS=32 +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/td2-s6000-32x40G.config.bcm b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/td2-s6000-32x40G.config.bcm index 4c94db7107c7..0e25b4d4232d 100644 --- 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 @@ -20,7 +20,7 @@ parity_enable=1 stat_if_parity_enable=0 # -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 l2xmsg_hostbuf_size=8192 l2xmsg_mode=1 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/port_config.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/port_config.ini index 95cf5eec9e4e..6e10b45cbc4c 100644 --- 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 @@ -1,33 +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 +# name lanes alias index asic_port_name role speed +Ethernet192 25,26,27,28 Ethernet1/49 48 Eth0-ASIC3 Ext 40000 +Ethernet196 29,30,31,32 Ethernet1/50 49 Eth1-ASIC3 Ext 40000 +Ethernet200 33,34,35,36 Ethernet1/51 50 Eth2-ASIC3 Ext 40000 +Ethernet204 37,38,39,40 Ethernet1/52 51 Eth3-ASIC3 Ext 40000 +Ethernet208 45,46,47,48 Ethernet1/53 52 Eth4-ASIC3 Ext 40000 +Ethernet212 41,42,43,44 Ethernet1/54 53 Eth5-ASIC3 Ext 40000 +Ethernet216 1,2,3,4 Ethernet1/55 54 Eth6-ASIC3 Ext 40000 +Ethernet220 5,6,7,8 Ethernet1/56 55 Eth7-ASIC3 Ext 40000 +Ethernet224 13,14,15,16 Ethernet1/57 56 Eth8-ASIC3 Ext 40000 +Ethernet228 9,10,11,12 Ethernet1/58 57 Eth9-ASIC3 Ext 40000 +Ethernet232 17,18,19,20 Ethernet1/59 58 Eth10-ASIC3 Ext 40000 +Ethernet236 21,22,23,24 Ethernet1/60 59 Eth11-ASIC3 Ext 40000 +Ethernet240 53,54,55,56 Ethernet1/61 60 Eth12-ASIC3 Ext 40000 +Ethernet244 49,50,51,52 Ethernet1/62 61 Eth13-ASIC3 Ext 40000 +Ethernet248 57,58,59,60 Ethernet1/63 62 Eth14-ASIC3 Ext 40000 +Ethernet252 61,62,63,64 Ethernet1/64 63 Eth15-ASIC3 Ext 40000 +Ethernet-BP192 69,70,71,72 Eth16-ASIC3 48 Eth16-ASIC3 Int 40000 +Ethernet-BP196 65,66,67,68 Eth17-ASIC3 49 Eth17-ASIC3 Int 40000 +Ethernet-BP200 73,74,75,76 Eth18-ASIC3 50 Eth18-ASIC3 Int 40000 +Ethernet-BP204 77,78,79,80 Eth19-ASIC3 51 Eth19-ASIC3 Int 40000 +Ethernet-BP208 109,110,111,112 Eth20-ASIC3 52 Eth20-ASIC3 Int 40000 +Ethernet-BP212 105,106,107,108 Eth21-ASIC3 53 Eth21-ASIC3 Int 40000 +Ethernet-BP216 113,114,115,116 Eth22-ASIC3 54 Eth22-ASIC3 Int 40000 +Ethernet-BP220 117,118,119,120 Eth23-ASIC3 55 Eth23-ASIC3 Int 40000 +Ethernet-BP224 125,126,127,128 Eth24-ASIC3 56 Eth24-ASIC3 Int 40000 +Ethernet-BP228 121,122,123,124 Eth25-ASIC3 57 Eth25-ASIC3 Int 40000 +Ethernet-BP232 81,82,83,84 Eth26-ASIC3 58 Eth26-ASIC3 Int 40000 +Ethernet-BP236 85,86,87,88 Eth27-ASIC3 59 Eth27-ASIC3 Int 40000 +Ethernet-BP240 93,94,95,96 Eth28-ASIC3 60 Eth28-ASIC3 Int 40000 +Ethernet-BP244 89,90,91,92 Eth29-ASIC3 61 Eth29-ASIC3 Int 40000 +Ethernet-BP248 101,102,103,104 Eth30-ASIC3 62 Eth30-ASIC3 Int 40000 +Ethernet-BP252 97,98,99,100 Eth31-ASIC3 63 Eth31-ASIC3 Int 40000 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..0a2df177f1c5 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,3 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm -SAI_NUM_ECMP_MEMBERS=32 +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/td2-s6000-32x40G.config.bcm b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/td2-s6000-32x40G.config.bcm index 4c94db7107c7..0e25b4d4232d 100644 --- 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 @@ -20,7 +20,7 @@ parity_enable=1 stat_if_parity_enable=0 # -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 l2xmsg_hostbuf_size=8192 l2xmsg_mode=1 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/port_config.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/port_config.ini index 95cf5eec9e4e..f6b9ccf3da98 100644 --- 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 @@ -1,33 +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 +# name lanes alias index asic_port_name role speed +Ethernet-BP256 25,26,27,28 Eth0-ASIC4 64 Eth0-ASIC4 Int 40000 +Ethernet-BP260 29,30,31,32 Eth1-ASIC4 65 Eth1-ASIC4 Int 40000 +Ethernet-BP264 33,34,35,36 Eth2-ASIC4 66 Eth2-ASIC4 Int 40000 +Ethernet-BP268 37,38,39,40 Eth3-ASIC4 67 Eth3-ASIC4 Int 40000 +Ethernet-BP272 45,46,47,48 Eth4-ASIC4 68 Eth4-ASIC4 Int 40000 +Ethernet-BP276 41,42,43,44 Eth5-ASIC4 69 Eth5-ASIC4 Int 40000 +Ethernet-BP280 1,2,3,4 Eth6-ASIC4 70 Eth6-ASIC4 Int 40000 +Ethernet-BP284 5,6,7,8 Eth7-ASIC4 71 Eth7-ASIC4 Int 40000 +Ethernet-BP288 13,14,15,16 Eth8-ASIC4 72 Eth8-ASIC4 Int 40000 +Ethernet-BP292 9,10,11,12 Eth9-ASIC4 73 Eth9-ASIC4 Int 40000 +Ethernet-BP296 17,18,19,20 Eth10-ASIC4 74 Eth10-ASIC4 Int 40000 +Ethernet-BP300 21,22,23,24 Eth11-ASIC4 75 Eth11-ASIC4 Int 40000 +Ethernet-BP304 53,54,55,56 Eth12-ASIC4 76 Eth12-ASIC4 Int 40000 +Ethernet-BP308 49,50,51,52 Eth13-ASIC4 77 Eth13-ASIC4 Int 40000 +Ethernet-BP312 57,58,59,60 Eth14-ASIC4 78 Eth14-ASIC4 Int 40000 +Ethernet-BP316 61,62,63,64 Eth15-ASIC4 79 Eth15-ASIC4 Int 40000 +Ethernet-BP320 69,70,71,72 Eth16-ASIC4 80 Eth16-ASIC4 Int 40000 +Ethernet-BP324 65,66,67,68 Eth17-ASIC4 81 Eth17-ASIC4 Int 40000 +Ethernet-BP328 73,74,75,76 Eth18-ASIC4 82 Eth18-ASIC4 Int 40000 +Ethernet-BP332 77,78,79,80 Eth19-ASIC4 83 Eth19-ASIC4 Int 40000 +Ethernet-BP336 109,110,111,112 Eth20-ASIC4 84 Eth20-ASIC4 Int 40000 +Ethernet-BP340 105,106,107,108 Eth21-ASIC4 85 Eth21-ASIC4 Int 40000 +Ethernet-BP344 113,114,115,116 Eth22-ASIC4 86 Eth22-ASIC4 Int 40000 +Ethernet-BP348 117,118,119,120 Eth23-ASIC4 87 Eth23-ASIC4 Int 40000 +Ethernet-BP352 125,126,127,128 Eth24-ASIC4 88 Eth24-ASIC4 Int 40000 +Ethernet-BP356 121,122,123,124 Eth25-ASIC4 89 Eth25-ASIC4 Int 40000 +Ethernet-BP360 81,82,83,84 Eth26-ASIC4 90 Eth26-ASIC4 Int 40000 +Ethernet-BP364 85,86,87,88 Eth27-ASIC4 91 Eth27-ASIC4 Int 40000 +Ethernet-BP368 93,94,95,96 Eth28-ASIC4 92 Eth28-ASIC4 Int 40000 +Ethernet-BP372 89,90,91,92 Eth29-ASIC4 93 Eth29-ASIC4 Int 40000 +Ethernet-BP376 101,102,103,104 Eth30-ASIC4 94 Eth30-ASIC4 Int 40000 +Ethernet-BP380 97,98,99,100 Eth31-ASIC4 95 Eth31-ASIC4 Int 40000 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..0a2df177f1c5 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,3 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm -SAI_NUM_ECMP_MEMBERS=32 +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/td2-s6000-32x40G.config.bcm b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/td2-s6000-32x40G.config.bcm index 4c94db7107c7..0e25b4d4232d 100644 --- 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 @@ -20,7 +20,7 @@ parity_enable=1 stat_if_parity_enable=0 # -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 l2xmsg_hostbuf_size=8192 l2xmsg_mode=1 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/port_config.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/port_config.ini index 95cf5eec9e4e..96e863b87349 100644 --- 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 @@ -1,33 +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 +# name lanes alias index asic_port_name role speed +Ethernet-BP384 25,26,27,28 Eth0-ASIC5 96 Eth0-ASIC5 Int 40000 +Ethernet-BP388 29,30,31,32 Eth1-ASIC5 97 Eth1-ASIC5 Int 40000 +Ethernet-BP392 33,34,35,36 Eth2-ASIC5 98 Eth2-ASIC5 Int 40000 +Ethernet-BP396 37,38,39,40 Eth3-ASIC5 99 Eth3-ASIC5 Int 40000 +Ethernet-BP400 45,46,47,48 Eth4-ASIC5 100 Eth4-ASIC5 Int 40000 +Ethernet-BP404 41,42,43,44 Eth5-ASIC5 101 Eth5-ASIC5 Int 40000 +Ethernet-BP408 1,2,3,4 Eth6-ASIC5 102 Eth6-ASIC5 Int 40000 +Ethernet-BP412 5,6,7,8 Eth7-ASIC5 103 Eth7-ASIC5 Int 40000 +Ethernet-BP416 13,14,15,16 Eth8-ASIC5 104 Eth8-ASIC5 Int 40000 +Ethernet-BP420 9,10,11,12 Eth9-ASIC5 105 Eth9-ASIC5 Int 40000 +Ethernet-BP424 17,18,19,20 Eth10-ASIC5 106 Eth10-ASIC5 Int 40000 +Ethernet-BP428 21,22,23,24 Eth11-ASIC5 107 Eth11-ASIC5 Int 40000 +Ethernet-BP432 53,54,55,56 Eth12-ASIC5 108 Eth12-ASIC5 Int 40000 +Ethernet-BP436 49,50,51,52 Eth13-ASIC5 109 Eth13-ASIC5 Int 40000 +Ethernet-BP440 57,58,59,60 Eth14-ASIC5 110 Eth14-ASIC5 Int 40000 +Ethernet-BP444 61,62,63,64 Eth15-ASIC5 111 Eth15-ASIC5 Int 40000 +Ethernet-BP448 69,70,71,72 Eth16-ASIC5 112 Eth16-ASIC5 Int 40000 +Ethernet-BP452 65,66,67,68 Eth17-ASIC5 113 Eth17-ASIC5 Int 40000 +Ethernet-BP456 73,74,75,76 Eth18-ASIC5 114 Eth18-ASIC5 Int 40000 +Ethernet-BP460 77,78,79,80 Eth19-ASIC5 115 Eth19-ASIC5 Int 40000 +Ethernet-BP464 109,110,111,112 Eth20-ASIC5 116 Eth20-ASIC5 Int 40000 +Ethernet-BP468 105,106,107,108 Eth21-ASIC5 117 Eth21-ASIC5 Int 40000 +Ethernet-BP472 113,114,115,116 Eth22-ASIC5 118 Eth22-ASIC5 Int 40000 +Ethernet-BP476 117,118,119,120 Eth23-ASIC5 119 Eth23-ASIC5 Int 40000 +Ethernet-BP480 125,126,127,128 Eth24-ASIC5 120 Eth24-ASIC5 Int 40000 +Ethernet-BP484 121,122,123,124 Eth25-ASIC5 121 Eth25-ASIC5 Int 40000 +Ethernet-BP488 81,82,83,84 Eth26-ASIC5 122 Eth26-ASIC5 Int 40000 +Ethernet-BP492 85,86,87,88 Eth27-ASIC5 123 Eth27-ASIC5 Int 40000 +Ethernet-BP496 93,94,95,96 Eth28-ASIC5 124 Eth28-ASIC5 Int 40000 +Ethernet-BP500 89,90,91,92 Eth29-ASIC5 125 Eth29-ASIC5 Int 40000 +Ethernet-BP504 101,102,103,104 Eth30-ASIC5 126 Eth30-ASIC5 Int 40000 +Ethernet-BP508 97,98,99,100 Eth31-ASIC5 127 Eth31-ASIC5 Int 40000 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..0a2df177f1c5 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,3 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm -SAI_NUM_ECMP_MEMBERS=32 +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/td2-s6000-32x40G.config.bcm b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/td2-s6000-32x40G.config.bcm index 4c94db7107c7..0e25b4d4232d 100644 --- 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 @@ -20,7 +20,7 @@ parity_enable=1 stat_if_parity_enable=0 # -bcm_num_cos=8 +bcm_num_cos=10 bcm_stat_interval=2000000 l2xmsg_hostbuf_size=8192 l2xmsg_mode=1 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/device/virtual/x86_64-kvm_x86_64-r0/plugins/eeprom.py b/device/virtual/x86_64-kvm_x86_64-r0/plugins/eeprom.py index 5cc8cb68018f..163c31ba20fc 100644 --- a/device/virtual/x86_64-kvm_x86_64-r0/plugins/eeprom.py +++ b/device/virtual/x86_64-kvm_x86_64-r0/plugins/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # SONiC Virtual switch platform # @@ -18,7 +16,7 @@ def is_checksum_valid(self, e): def read_eeprom(self): return \ -""" + """ TLV Name Code Len Value -------------------- ---- --- ----- Product Name 0x21 5 SONiC @@ -35,7 +33,7 @@ def read_eeprom(self): """ def decode_eeprom(self, e): - print e + print(e) def serial_number_str(self, e): """Return service tag instead of serial number""" diff --git a/device/virtual/x86_64-kvm_x86_64-r0/pmon_daemon_control.json b/device/virtual/x86_64-kvm_x86_64-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..101db0ffea1a --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/pmon_daemon_control.json @@ -0,0 +1,8 @@ +{ + "skip_ledd": true, + "skip_xcvrd": true, + "skip_pcied": true, + "skip_psud": true, + "skip_syseepromd": true, + "skip_thermalctld": true +} diff --git a/device/wnc/x86_64-wnc_osw1800-r0/plugins/eeprom.py b/device/wnc/x86_64-wnc_osw1800-r0/plugins/eeprom.py index a073374794fa..7c36371812ae 100644 --- a/device/wnc/x86_64-wnc_osw1800-r0/plugins/eeprom.py +++ b/device/wnc/x86_64-wnc_osw1800-r0/plugins/eeprom.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - try: - import exceptions import binascii import time import optparse @@ -10,8 +7,8 @@ import sys from sonic_eeprom import eeprom_base from sonic_eeprom import eeprom_tlvinfo -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class board(eeprom_tlvinfo.TlvInfoDecoder): @@ -19,4 +16,3 @@ class board(eeprom_tlvinfo.TlvInfoDecoder): def __init__(self, name, path, cpld_root, ro): self.eeprom_path = "/sys/class/i2c-adapter/i2c-8/8-0052/eeprom" super(board, self).__init__(self.eeprom_path, 0, '', True) - diff --git a/device/wnc/x86_64-wnc_osw1800-r0/plugins/sfputil.py b/device/wnc/x86_64-wnc_osw1800-r0/plugins/sfputil.py index 549790bfb44f..ebb3d1c9bfa7 100644 --- a/device/wnc/x86_64-wnc_osw1800-r0/plugins/sfputil.py +++ b/device/wnc/x86_64-wnc_osw1800-r0/plugins/sfputil.py @@ -12,7 +12,7 @@ from sff8472 import sff8472Dom from sff8436 import sff8436InterfaceId from sff8436 import sff8436Dom -except ImportError, e: +except ImportError as e: raise ImportError("%s - required module not found" % str(e)) @@ -37,7 +37,7 @@ def port_end(self): @property def qsfp_ports(self): - return range(self.PORT_START + 48, self.PORTS_IN_BLOCK) + return list(range(self.PORT_START + 48, self.PORTS_IN_BLOCK)) @property def port_to_eeprom_mapping(self): @@ -77,7 +77,7 @@ def get_presence(self, port_num): try: reg_file = open(presence_path, "rb") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -98,7 +98,7 @@ def get_low_power_mode(self, port_num): try: reg_file = open("/sys/bus/i2c/devices/4-0032/qsfp_lpmode") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) content = reg_file.readline().rstrip() reg_value = int(content, 16) @@ -118,7 +118,7 @@ def set_low_power_mode(self, port_num, lpmode): try: reg_file = open("/sys/bus/i2c/devices/4-0032/qsfp_lpmode", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -144,7 +144,7 @@ def reset(self, port_num): try: reg_file = open("/sys/bus/i2c/devices/4-0032/reset_control", "r+") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False content = reg_file.readline().rstrip() @@ -160,7 +160,7 @@ def reset(self, port_num): try: reg_file = open("/sys/bus/i2c/devices/4-0032/reset_control", "w") except IOError as e: - print "Error: unable to open file: %s" % str(e) + print("Error: unable to open file: %s" % str(e)) return False reg_value = reg_value | (1 << bit_mask) diff --git a/dockers/docker-base-buster/Dockerfile.j2 b/dockers/docker-base-buster/Dockerfile.j2 new file mode 100644 index 000000000000..1f80775f11a4 --- /dev/null +++ b/dockers/docker-base-buster/Dockerfile.j2 @@ -0,0 +1,131 @@ +{% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} +{% if CONFIGURED_ARCH == "armhf" %} +FROM multiarch/debian-debootstrap:armhf-buster +{% elif CONFIGURED_ARCH == "arm64" %} +FROM multiarch/debian-debootstrap:arm64-buster +{% else %} +FROM debian:buster +{% endif %} + +# Clean documentation in FROM image +RUN find /usr/share/doc -depth \( -type f -o -type l \) ! -name copyright | xargs rm || true + +# Clean doc directories that are empty or only contain empty directories +RUN while [ -n "$(find /usr/share/doc -depth -type d -empty -print -exec rmdir {} +)" ]; do :; done && \ + rm -rf \ + /usr/share/man/* \ + /usr/share/groff/* \ + /usr/share/info/* \ + /usr/share/lintian/* \ + /usr/share/linda/* \ + /var/cache/man/* \ + /usr/share/locale/* + +# Make apt-get non-interactive +ENV DEBIAN_FRONTEND=noninteractive + +# Configure data sources for apt/dpkg +COPY ["dpkg_01_drop", "/etc/dpkg/dpkg.cfg.d/01_drop"] +{% if CONFIGURED_ARCH == "armhf" %} +COPY ["sources.list.armhf", "/etc/apt/sources.list"] +{% elif CONFIGURED_ARCH == "arm64" %} +COPY ["sources.list.arm64", "/etc/apt/sources.list"] +{% else %} +COPY ["sources.list", "/etc/apt/sources.list"] +{% endif %} +COPY ["no_install_recommend_suggest", "/etc/apt/apt.conf.d"] +COPY ["no-check-valid-until", "/etc/apt/apt.conf.d"] + +# Update apt cache and +# pre-install fundamental packages +RUN apt-get update && \ + apt-get -y install \ + curl \ + less \ + perl \ + procps \ + python3 \ + python3-distutils \ + python3-pip \ + rsyslog \ + vim-tiny \ +# Install dependencies of redis-tools + libatomic1 \ + libjemalloc2 \ + liblua5.1-0 \ + lua-bitop \ + lua-cjson \ +# common dependencies + libdaemon0 \ + libdbus-1-3 \ + libjansson4 \ +# ip and ifconfig utility missing in docker for arm arch + iproute2 \ + net-tools \ +# for processing/handling json files in bash environment + jq \ +# for sairedis zmq rpc channel + libzmq5 + +# Install redis-tools +{% if CONFIGURED_ARCH == "armhf" %} +RUN curl -k -o redis-tools_6.0.6-1~bpo10+1_armhf.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-tools_6.0.6-1_bpo10+1_armhf.deb?sv=2015-04-05&sr=b&sig=67vHAMxsl%2BS3X1KsqhdYhakJkGdg5FKSPgU8kUiw4as%3D&se=2030-10-24T04%3A22%3A40Z&sp=r" +RUN dpkg -i redis-tools_6.0.6-1~bpo10+1_armhf.deb || apt-get install -f -y +RUN rm redis-tools_6.0.6-1~bpo10+1_armhf.deb +{% elif CONFIGURED_ARCH == "arm64" %} +RUN curl -o redis-tools_6.0.6-1~bpo10+1_arm64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-tools_6.0.6-1_bpo10+1_arm64.deb?sv=2015-04-05&sr=b&sig=GbkJV2wWln3hoz27zKi5erdk3NDKrAFrQriA97bcRCY%3D&se=2030-10-24T04%3A22%3A21Z&sp=r" +RUN dpkg -i redis-tools_6.0.6-1~bpo10+1_arm64.deb || apt-get install -f -y +RUN rm redis-tools_6.0.6-1~bpo10+1_arm64.deb +{% else %} +RUN curl -o redis-tools_6.0.6-1~bpo10+1_amd64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-tools_6.0.6-1~bpo10+1_amd64.deb?sv=2015-04-05&sr=b&sig=73zbmjkf3pi%2Bn0R8Hy7CWT2EUvOAyzM5aLYJWCLySGM%3D&se=2030-09-06T19%3A44%3A59Z&sp=r" +RUN dpkg -i redis-tools_6.0.6-1~bpo10+1_amd64.deb || apt-get install -f -y +RUN rm redis-tools_6.0.6-1~bpo10+1_amd64.deb +{% endif %} + +# Upgrade pip via PyPI and uninstall the Debian version +RUN pip3 install --upgrade pip +RUN apt-get purge -y python3-pip + +# setuptools and wheel are necessary for installing some Python wheel packages +RUN pip3 install --no-cache-dir setuptools==49.6.00 +RUN pip3 install --no-cache-dir wheel==0.35.1 + +# For templating +RUN pip3 install j2cli + +# Install supervisor +RUN pip3 install supervisor==4.2.1 + +# Add support for supervisord to handle startup dependencies +RUN pip3 install supervisord-dependent-startup==1.4.0 + +RUN mkdir -p /etc/supervisor /var/log/supervisor + +RUN apt-get -y purge \ + exim4 \ + exim4-base \ + exim4-config \ + exim4-daemon-light + +{% if docker_base_buster_debs.strip() -%} +# Copy locally-built Debian package dependencies +{{ copy_files("debs/", docker_base_buster_debs.split(' '), "/debs/") }} + +# Install built Debian packages and implicitly install their dependencies +{{ install_debian_packages(docker_base_buster_debs.split(' ')) }} +{%- endif %} + +# Clean up apt +# Remove /var/lib/apt/lists/*, could be obsoleted for derived images +RUN apt-get clean -y && \ + apt-get autoclean -y && \ + apt-get autoremove -y && \ + rm -rf /var/lib/apt/lists/* /tmp/* + +COPY ["etc/rsyslog.conf", "/etc/rsyslog.conf"] +COPY ["etc/rsyslog.d/*", "/etc/rsyslog.d/"] +COPY ["root/.vimrc", "/root/.vimrc"] + +RUN ln /usr/bin/vim.tiny /usr/bin/vim + +COPY ["etc/supervisor/supervisord.conf", "/etc/supervisor/"] diff --git a/dockers/docker-base-buster/LICENSE b/dockers/docker-base-buster/LICENSE new file mode 100644 index 000000000000..03d8f31e513c --- /dev/null +++ b/dockers/docker-base-buster/LICENSE @@ -0,0 +1,13 @@ +Copyright 2016 Microsoft, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/dockers/docker-base-buster/dpkg_01_drop b/dockers/docker-base-buster/dpkg_01_drop new file mode 100644 index 000000000000..d749943797d9 --- /dev/null +++ b/dockers/docker-base-buster/dpkg_01_drop @@ -0,0 +1,30 @@ +## Drop unnecessary files +## ref: https://wiki.ubuntu.com/ReducingDiskFootprint + +## Documentation +path-exclude /usr/share/doc/* +# we need to keep copyright files for legal reasons +path-include /usr/share/doc/*/copyright +path-exclude /usr/share/man/* +path-exclude /usr/share/groff/* +path-exclude /usr/share/info/* +# lintian stuff is small, but really unnecessary +path-exclude /usr/share/lintian/* +path-exclude /usr/share/linda/* + +## Translations +path-exclude /usr/share/locale/* + +## Landscape +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-buster/etc/rsyslog.conf b/dockers/docker-base-buster/etc/rsyslog.conf new file mode 100644 index 000000000000..ef249229ab1e --- /dev/null +++ b/dockers/docker-base-buster/etc/rsyslog.conf @@ -0,0 +1,76 @@ +# +# /etc/rsyslog.conf Configuration file for rsyslog. +# +# For more information see +# /usr/share/doc/rsyslog-doc/html/rsyslog_conf.html + + +################# +#### MODULES #### +################# + +$ModLoad imuxsock # provides support for local system logging + +# +# Set a rate limit on messages from the container +# +$SystemLogRateLimitInterval 300 +$SystemLogRateLimitBurst 20000 + +#$ModLoad imklog # provides kernel logging support +#$ModLoad immark # provides --MARK-- message capability + +# provides UDP syslog reception +#$ModLoad imudp +#$UDPServerRun 514 + +# provides TCP syslog reception +#$ModLoad imtcp +#$InputTCPServerRun 514 + + +########################### +#### GLOBAL DIRECTIVES #### +########################### + +# Set remote syslog server +template (name="ForwardFormatInContainer" type="string" string="<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg%") +*.* action(type="omfwd" target="127.0.0.1" port="514" protocol="udp" Template="ForwardFormatInContainer") + +# +# Use traditional timestamp format. +# To enable high precision timestamps, comment out the following line. +# +#$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat + +# Define a custom template +$template SONiCFileFormat,"%TIMESTAMP%.%timestamp:::date-subseconds% %HOSTNAME% %syslogseverity-text:::uppercase% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n" +$ActionFileDefaultTemplate SONiCFileFormat + +# +# Set the default permissions for all log files. +# +$FileOwner root +$FileGroup adm +$FileCreateMode 0640 +$DirCreateMode 0755 +$Umask 0022 + +# +# Where to place spool and state files +# +$WorkDirectory /var/spool/rsyslog + +# +# Include all config files in /etc/rsyslog.d/ +# +$IncludeConfig /etc/rsyslog.d/*.conf + +# +# Suppress duplicate messages and report "message repeated n times" +# +$RepeatedMsgReduction on + +############### +#### RULES #### +############### diff --git a/dockers/docker-base-buster/etc/rsyslog.d/supervisor.conf b/dockers/docker-base-buster/etc/rsyslog.d/supervisor.conf new file mode 100644 index 000000000000..fde8d8a6c994 --- /dev/null +++ b/dockers/docker-base-buster/etc/rsyslog.d/supervisor.conf @@ -0,0 +1,9 @@ +module(load="imfile" mode="inotify") # Ensure "inotify" mode is used +$WorkDirectory /var/log/supervisor +# Start Monitoring the file +input(type="imfile" + File="/var/log/supervisor/supervisord.log" + Tag="supervisord" + Severity="info" + Facility="local0" + PersistStateInterval="1") diff --git a/dockers/docker-base-buster/etc/supervisor/supervisord.conf b/dockers/docker-base-buster/etc/supervisor/supervisord.conf new file mode 100644 index 000000000000..6d7d7390e854 --- /dev/null +++ b/dockers/docker-base-buster/etc/supervisor/supervisord.conf @@ -0,0 +1,29 @@ +; supervisor config file + +[unix_http_server] +file=/var/run/supervisor.sock ; (the path to the socket file) +chmod=0700 ; socket file mode (default 0700) + +[supervisord] +logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log) +pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid) +childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP) +user=root + +; the below section must remain in the config file for RPC +; (supervisorctl/web interface) to work, additional interfaces may be +; added by defining them in separate rpcinterface: sections +[rpcinterface:supervisor] +supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface + +[supervisorctl] +serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket + +; The [include] section can just contain the "files" setting. This +; setting can list multiple files (separated by whitespace or +; newlines). It can also contain wildcards. The filenames are +; interpreted as relative to this file. Included files *cannot* +; include files themselves. + +[include] +files = /etc/supervisor/conf.d/*.conf diff --git a/dockers/docker-base-buster/no-check-valid-until b/dockers/docker-base-buster/no-check-valid-until new file mode 100644 index 000000000000..c7c25d017f7f --- /dev/null +++ b/dockers/docker-base-buster/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-buster/no_install_recommend_suggest b/dockers/docker-base-buster/no_install_recommend_suggest new file mode 100644 index 000000000000..b5bca577de1e --- /dev/null +++ b/dockers/docker-base-buster/no_install_recommend_suggest @@ -0,0 +1,5 @@ +# Instruct apt-get to NOT install "recommended" or "suggested" packages by +# default when installing a package. + +APT::Install-Recommends "false"; +APT::Install-Suggests "false"; diff --git a/dockers/docker-base-buster/root/.vimrc b/dockers/docker-base-buster/root/.vimrc new file mode 100644 index 000000000000..5c1ba8a04f47 --- /dev/null +++ b/dockers/docker-base-buster/root/.vimrc @@ -0,0 +1,2 @@ +" enable vim features +set nocompatible diff --git a/dockers/docker-base-buster/sources.list b/dockers/docker-base-buster/sources.list new file mode 100644 index 000000000000..0eef72d9fa2d --- /dev/null +++ b/dockers/docker-base-buster/sources.list @@ -0,0 +1,13 @@ +## Debian mirror on Microsoft Azure +## Ref: http://debian-archive.trafficmanager.net/ + +deb [arch=amd64] http://debian-archive.trafficmanager.net/debian/ buster main contrib non-free +deb-src [arch=amd64] http://debian-archive.trafficmanager.net/debian/ buster main contrib non-free +deb [arch=amd64] http://debian-archive.trafficmanager.net/debian-security/ buster/updates main contrib non-free +deb-src [arch=amd64] http://debian-archive.trafficmanager.net/debian-security/ buster/updates main contrib non-free +deb [arch=amd64] http://debian-archive.trafficmanager.net/debian/ buster-backports main contrib non-free + +# Debian mirror supports multiple versions for a package +deb [arch=amd64] http://packages.trafficmanager.net/debian/debian buster main contrib non-free +deb [arch=amd64] http://packages.trafficmanager.net/debian/debian buster-updates main contrib non-free +deb [arch=amd64] http://packages.trafficmanager.net/debian/debian buster-backports main contrib non-free diff --git a/dockers/docker-base-buster/sources.list.arm64 b/dockers/docker-base-buster/sources.list.arm64 new file mode 100644 index 000000000000..6375734e99e6 --- /dev/null +++ b/dockers/docker-base-buster/sources.list.arm64 @@ -0,0 +1,11 @@ +## Debian mirror for ARM repo + +# ARM repo +deb [arch=arm64] http://deb.debian.org/debian buster main contrib non-free +deb-src [arch=arm64] http://deb.debian.org/debian buster main contrib non-free +deb [arch=arm64] http://security.debian.org buster/updates main contrib non-free +deb-src [arch=arm64] http://security.debian.org buster/updates main contrib non-free +deb [arch=arm64] http://deb.debian.org/debian/ buster-backports main contrib non-free +deb [arch=arm64] http://packages.trafficmanager.net/debian/debian buster main contrib non-free +deb [arch=arm64] http://packages.trafficmanager.net/debian/debian buster-updates main contrib non-free +deb [arch=arm64] http://packages.trafficmanager.net/debian/debian buster-backports main contrib non-free diff --git a/dockers/docker-base-buster/sources.list.armhf b/dockers/docker-base-buster/sources.list.armhf new file mode 100644 index 000000000000..a03af1a33ac0 --- /dev/null +++ b/dockers/docker-base-buster/sources.list.armhf @@ -0,0 +1,11 @@ +## Debian mirror for ARM repo + +# ARM repo +deb [arch=armhf] http://deb.debian.org/debian buster main contrib non-free +deb-src [arch=armhf] http://deb.debian.org/debian buster main contrib non-free +deb [arch=armhf] http://security.debian.org buster/updates main contrib non-free +deb-src [arch=armhf] http://security.debian.org buster/updates main contrib non-free +deb [arch=armhf] http://deb.debian.org/debian/ buster-backports main contrib non-free +deb [arch=armhf] http://packages.trafficmanager.net/debian/debian buster main contrib non-free +deb [arch=armhf] http://packages.trafficmanager.net/debian/debian buster-updates main contrib non-free +deb [arch=armhf] http://packages.trafficmanager.net/debian/debian buster-backports main contrib non-free diff --git a/dockers/docker-base-stretch/Dockerfile.j2 b/dockers/docker-base-stretch/Dockerfile.j2 index 65b7f9d537ce..aa6eda8a955c 100644 --- a/dockers/docker-base-stretch/Dockerfile.j2 +++ b/dockers/docker-base-stretch/Dockerfile.j2 @@ -40,26 +40,60 @@ COPY ["no-check-valid-until", "/etc/apt/apt.conf.d"] # pre-install fundamental packages RUN apt-get update && \ apt-get -y install \ + curl \ less \ perl \ procps \ python \ - rsyslog \ + python-pip \ vim-tiny \ -# Install dependencies of supervisor - python-pkg-resources \ - python-meld3 \ -# dependencies of redis-tools - libatomic1 \ - libjemalloc1 \ - liblua5.1-0 \ - lua-bitop \ - lua-cjson - +# Install redis-tools + redis-tools=5:5.0.3-3~bpo9+2 \ +# common dependencies + libpython2.7 \ + libdaemon0 \ + libdbus-1-3 \ + libjansson4 \ # ip and ifconfig utility missing in docker for arm arch -RUN apt-get -y install \ iproute2 \ - net-tools + net-tools \ +# for processing json files in bash environment + jq \ +# for sairedis zmq rpc channel + libzmq5 + +# Install a newer version of rsyslog from stretch-backports to support -iNONE +RUN apt-get -y -t stretch-backports install rsyslog + +# Install redis-tools + +{% if CONFIGURED_ARCH == "armhf" %} + RUN curl -o redis-tools_6.0.6-1~bpo10+1_armhf.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-tools_6.0.6-1_bpo10+1_armhf.deb?sv=2015-04-05&sr=b&sig=67vHAMxsl%2BS3X1KsqhdYhakJkGdg5FKSPgU8kUiw4as%3D&se=2030-10-24T04%3A22%3A40Z&sp=r" + RUN dpkg -i redis-tools_6.0.6-1~bpo10+1_armhf.deb || apt-get install -f -y + RUN rm redis-tools_6.0.6-1~bpo10+1_armhf.deb +{% elif CONFIGURED_ARCH == "arm64" %} + RUN curl -o redis-tools_6.0.6-1~bpo10+1_arm64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-tools_6.0.6-1_bpo10+1_arm64.deb?sv=2015-04-05&sr=b&sig=GbkJV2wWln3hoz27zKi5erdk3NDKrAFrQriA97bcRCY%3D&se=2030-10-24T04%3A22%3A21Z&sp=r" + RUN dpkg -i redis-tools_6.0.6-1~bpo10+1_arm64.deb || apt-get install -f -y + RUN rm redis-tools_6.0.6-1~bpo10+1_arm64.deb +{% else %} + RUN curl -o redis-tools_6.0.6-1~bpo10+1_amd64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-tools_6.0.6-1~bpo10+1_amd64.deb?sv=2015-04-05&sr=b&sig=73zbmjkf3pi%2Bn0R8Hy7CWT2EUvOAyzM5aLYJWCLySGM%3D&se=2030-09-06T19%3A44%3A59Z&sp=r" + RUN dpkg -i redis-tools_6.0.6-1~bpo10+1_amd64.deb || apt-get install -f -y + RUN rm redis-tools_6.0.6-1~bpo10+1_amd64.deb +{% endif %} + +# Some Python packages require setuptools (or pkg_resources, which is supplied by setuptools) +# and some require wheel +RUN pip install setuptools==40.8.0 +RUN pip install wheel + +# For templating +RUN pip install j2cli + +# Install supervisor +RUN pip install supervisor>=3.4.0 + +# Add support for supervisord to handle startup dependencies +RUN pip install supervisord-dependent-startup==1.4.0 RUN mkdir -p /etc/supervisor /var/log/supervisor diff --git a/dockers/docker-base-stretch/etc/rsyslog.d/supervisor.conf b/dockers/docker-base-stretch/etc/rsyslog.d/supervisor.conf index 7c7a64d7afe0..fde8d8a6c994 100644 --- a/dockers/docker-base-stretch/etc/rsyslog.d/supervisor.conf +++ b/dockers/docker-base-stretch/etc/rsyslog.d/supervisor.conf @@ -1,9 +1,9 @@ -$ModLoad imfile - -$InputFileName /var/log/supervisor/supervisord.log -$InputFileTag supervisord -$InputFileStateFile state-supervisor -$InputFileSeverity info -$InputFileFacility local0 -$InputFilePersistStateInterval 1 -$InputRunFileMonitor +module(load="imfile" mode="inotify") # Ensure "inotify" mode is used +$WorkDirectory /var/log/supervisor +# Start Monitoring the file +input(type="imfile" + File="/var/log/supervisor/supervisord.log" + Tag="supervisord" + Severity="info" + Facility="local0" + PersistStateInterval="1") diff --git a/dockers/docker-base-stretch/etc/supervisor/supervisord.conf b/dockers/docker-base-stretch/etc/supervisor/supervisord.conf index 5d1010e8fa4e..6d7d7390e854 100644 --- a/dockers/docker-base-stretch/etc/supervisor/supervisord.conf +++ b/dockers/docker-base-stretch/etc/supervisor/supervisord.conf @@ -3,8 +3,6 @@ [unix_http_server] file=/var/run/supervisor.sock ; (the path to the socket file) chmod=0700 ; socket file mode (default 0700) -username=dummy -password=dummy [supervisord] logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log) @@ -20,8 +18,6 @@ supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface [supervisorctl] serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket -username=dummy -password=dummy ; The [include] section can just contain the "files" setting. This ; setting can list multiple files (separated by whitespace or diff --git a/dockers/docker-base-stretch/sources.list b/dockers/docker-base-stretch/sources.list index 752b1bb4fc60..0c29b339bb87 100644 --- a/dockers/docker-base-stretch/sources.list +++ b/dockers/docker-base-stretch/sources.list @@ -6,3 +6,6 @@ deb-src [arch=amd64] http://debian-archive.trafficmanager.net/debian/ stretch ma deb [arch=amd64] http://debian-archive.trafficmanager.net/debian-security/ stretch/updates main contrib non-free deb-src [arch=amd64] http://debian-archive.trafficmanager.net/debian-security/ stretch/updates main contrib non-free deb [arch=amd64] http://debian-archive.trafficmanager.net/debian/ stretch-backports main contrib non-free +deb [arch=amd64] http://packages.trafficmanager.net/debian/debian stretch main contrib non-free +deb [arch=amd64] http://packages.trafficmanager.net/debian/debian stretch-updates main contrib non-free +deb [arch=amd64] http://packages.trafficmanager.net/debian/debian stretch-backports main contrib non-free diff --git a/dockers/docker-base-stretch/sources.list.arm64 b/dockers/docker-base-stretch/sources.list.arm64 index b2e0a329d0b1..520c46519919 100644 --- a/dockers/docker-base-stretch/sources.list.arm64 +++ b/dockers/docker-base-stretch/sources.list.arm64 @@ -5,3 +5,7 @@ deb [arch=arm64] http://deb.debian.org/debian stretch main contrib non-free deb-src [arch=arm64] http://deb.debian.org/debian stretch main contrib non-free deb [arch=arm64] http://security.debian.org stretch/updates main contrib non-free deb-src [arch=arm64] http://security.debian.org stretch/updates main contrib non-free +deb [arch=arm64] http://deb.debian.org/debian/ stretch-backports main contrib non-free +deb [arch=arm64] http://packages.trafficmanager.net/debian/debian stretch main contrib non-free +deb [arch=arm64] http://packages.trafficmanager.net/debian/debian stretch-updates main contrib non-free +deb [arch=arm64] http://packages.trafficmanager.net/debian/debian stretch-backports main contrib non-free diff --git a/dockers/docker-base-stretch/sources.list.armhf b/dockers/docker-base-stretch/sources.list.armhf index 884a091175ab..58077f310424 100644 --- a/dockers/docker-base-stretch/sources.list.armhf +++ b/dockers/docker-base-stretch/sources.list.armhf @@ -5,3 +5,7 @@ deb [arch=armhf] http://deb.debian.org/debian stretch main contrib non-free deb-src [arch=armhf] http://deb.debian.org/debian stretch main contrib non-free deb [arch=armhf] http://security.debian.org stretch/updates main contrib non-free deb-src [arch=armhf] http://security.debian.org stretch/updates main contrib non-free +deb [arch=armhf] http://deb.debian.org/debian/ stretch-backports main contrib non-free +deb [arch=armhf] http://packages.trafficmanager.net/debian/debian stretch main contrib non-free +deb [arch=armhf] http://packages.trafficmanager.net/debian/debian stretch-updates main contrib non-free +deb [arch=armhf] http://packages.trafficmanager.net/debian/debian stretch-backports main contrib non-free diff --git a/dockers/docker-base/Dockerfile.j2 b/dockers/docker-base/Dockerfile.j2 index e45235a1e139..fc293da9da1e 100644 --- a/dockers/docker-base/Dockerfile.j2 +++ b/dockers/docker-base/Dockerfile.j2 @@ -44,6 +44,7 @@ RUN apt-get -y install \ vim-tiny \ perl \ python \ + python-pip \ rsyslog \ less @@ -51,8 +52,16 @@ COPY ["etc/rsyslog.conf", "/etc/rsyslog.conf"] COPY ["etc/rsyslog.d/*", "/etc/rsyslog.d/"] COPY ["root/.vimrc", "/root/.vimrc"] -# Install dependencies of supervisor -RUN apt-get -y install python-pkg-resources python-meld3 +RUN pip install --upgrade 'pip<21' +RUN apt-get purge -y python-pip + +# Some Python packages require setuptools (or pkg_resources, which is supplied by setuptools) +# and some require wheel +RUN pip install setuptools==40.8.0 +RUN pip install wheel + +# Install supervisor +RUN pip install supervisor>=3.4.0 RUN mkdir -p /etc/supervisor RUN mkdir -p /var/log/supervisor diff --git a/dockers/docker-base/etc/rsyslog.d/supervisor.conf b/dockers/docker-base/etc/rsyslog.d/supervisor.conf index 7c7a64d7afe0..fde8d8a6c994 100644 --- a/dockers/docker-base/etc/rsyslog.d/supervisor.conf +++ b/dockers/docker-base/etc/rsyslog.d/supervisor.conf @@ -1,9 +1,9 @@ -$ModLoad imfile - -$InputFileName /var/log/supervisor/supervisord.log -$InputFileTag supervisord -$InputFileStateFile state-supervisor -$InputFileSeverity info -$InputFileFacility local0 -$InputFilePersistStateInterval 1 -$InputRunFileMonitor +module(load="imfile" mode="inotify") # Ensure "inotify" mode is used +$WorkDirectory /var/log/supervisor +# Start Monitoring the file +input(type="imfile" + File="/var/log/supervisor/supervisord.log" + Tag="supervisord" + Severity="info" + Facility="local0" + PersistStateInterval="1") diff --git a/dockers/docker-basic_router/Dockerfile b/dockers/docker-basic_router/Dockerfile index 7d7c724920c2..5f579b53d6da 100644 --- a/dockers/docker-basic_router/Dockerfile +++ b/dockers/docker-basic_router/Dockerfile @@ -19,4 +19,4 @@ RUN mv /deps/basic_router /usr/sbin/basic_router COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/dockers/docker-config-engine-buster/Dockerfile.j2 b/dockers/docker-config-engine-buster/Dockerfile.j2 new file mode 100644 index 000000000000..3022546a068c --- /dev/null +++ b/dockers/docker-config-engine-buster/Dockerfile.j2 @@ -0,0 +1,52 @@ +{% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} +FROM docker-base-buster + +## Make apt-get non-interactive +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && \ + apt-get install -y \ + apt-utils \ + build-essential \ + python3-dev + +{%- if CONFIGURED_ARCH == "armhf" or CONFIGURED_ARCH == "arm64" %} +RUN apt-get install -y \ + libxslt-dev \ + libz-dev +{%- endif %} + +# For sonic-config-engine Python 3 package +# Explicitly install pyangbind here, as pyangbind causes enum34 to be installed. +# enum34 causes Python 're' package to not work properly as it redefines an incompatible enum.py module +# https://github.com/robshakir/pyangbind/issues/232 +RUN pip3 install pyangbind==0.8.1 +RUN pip3 uninstall -y enum34 + +{% if docker_config_engine_buster_debs.strip() %} +# Copy locally-built Debian package dependencies +{{ copy_files("debs/", docker_config_engine_buster_debs.split(' '), "/debs/") }} + +# Install locally-built Debian packages and implicitly install their dependencies +{{ install_debian_packages(docker_config_engine_buster_debs.split(' ')) }} +{% endif %} + +{% if docker_config_engine_buster_whls.strip() %} +# Copy locally-built Python wheel dependencies +{{ copy_files("python-wheels/", docker_config_engine_buster_whls.split(' '), "/python-wheels/") }} + +# Install locally-built Python wheel dependencies +{{ install_python_wheels(docker_config_engine_buster_whls.split(' ')) }} +{% endif %} + +# Copy files +COPY ["files/swss_vars.j2", "/usr/share/sonic/templates/"] + +## Clean up +RUN apt-get purge -y \ + python3-dev \ + build-essential && \ + apt-get clean -y && \ + apt-get autoclean -y && \ + apt-get autoremove -y && \ + rm -rf /debs /python-wheels diff --git a/dockers/docker-config-engine-stretch/Dockerfile.j2 b/dockers/docker-config-engine-stretch/Dockerfile.j2 index 8b958b8f4f59..813f41bc296b 100644 --- a/dockers/docker-config-engine-stretch/Dockerfile.j2 +++ b/dockers/docker-config-engine-stretch/Dockerfile.j2 @@ -7,21 +7,14 @@ ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && \ apt-get install -y \ # Dependencies for sonic-cfggen - python-lxml \ - python-yaml \ - python-bitarray \ - python-pip \ - python-dev \ - python-natsort \ - python-setuptools - -RUN pip install --upgrade pip - -RUN pip install \ - netaddr \ - ipaddr \ - jinja2 \ - pyangbind==0.5.10 + build-essential \ + python-dev + +{%- if CONFIGURED_ARCH == "armhf" or CONFIGURED_ARCH == "arm64" %} +RUN apt-get install -y \ + libxslt-dev \ + libz-dev +{%- endif %} {% if docker_config_engine_stretch_debs.strip() %} # Copy locally-built Debian package dependencies @@ -39,9 +32,12 @@ RUN pip install \ {{ install_python_wheels(docker_config_engine_stretch_whls.split(' ')) }} {% endif %} +# Copy files +COPY ["files/swss_vars.j2", "/usr/share/sonic/templates/"] + ## Clean up RUN apt-get purge -y \ - python-pip \ + build-essential \ python-dev && \ apt-get clean -y && \ apt-get autoclean -y && \ diff --git a/dockers/docker-config-engine/Dockerfile.j2 b/dockers/docker-config-engine/Dockerfile.j2 index ba72cce31d47..8790ba67d7f9 100644 --- a/dockers/docker-config-engine/Dockerfile.j2 +++ b/dockers/docker-config-engine/Dockerfile.j2 @@ -6,11 +6,7 @@ ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update # Dependencies for sonic-cfggen -RUN apt-get install -y python-lxml python-yaml python-bitarray python-pip python-dev python-natsort - -RUN pip install --upgrade pip - -RUN pip install netaddr ipaddr jinja2 pyangbind==0.5.10 +RUN apt-get install -y build-essential python-dev {% if docker_config_engine_debs.strip() %} COPY \ @@ -42,6 +38,9 @@ python-wheels/{{ whl }}{{' '}} {%- endfor %} {%- endif -%} +# Copy files +COPY ["files/swss_vars.j2", "/usr/share/sonic/templates/"] + ## Clean up -RUN apt-get purge -y python-pip python-dev; apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y +RUN apt-get purge -y build-essential python-dev; apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs /python-wheels diff --git a/dockers/docker-database/Dockerfile.j2 b/dockers/docker-database/Dockerfile.j2 index 8cd181614672..aef22e24379c 100644 --- a/dockers/docker-database/Dockerfile.j2 +++ b/dockers/docker-database/Dockerfile.j2 @@ -1,5 +1,5 @@ {% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} -FROM docker-config-engine-stretch +FROM docker-config-engine-buster ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf @@ -10,6 +10,24 @@ ENV DEBIAN_FRONTEND=noninteractive # Update apt's cache of available packages RUN apt-get update +# Install redis-server +{% if CONFIGURED_ARCH == "armhf" %} +RUN curl -k -o redis-tools_6.0.6-1~bpo10+1_armhf.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-tools_6.0.6-1_bpo10+1_armhf.deb?sv=2015-04-05&sr=b&sig=67vHAMxsl%2BS3X1KsqhdYhakJkGdg5FKSPgU8kUiw4as%3D&se=2030-10-24T04%3A22%3A40Z&sp=r" +RUN curl -k -o redis-server_6.0.6-1~bpo10+1_armhf.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-server_6.0.6-1_bpo10+1_armhf.deb?sv=2015-04-05&sr=b&sig=xTdayvm0RBguxi9suyv855jKRjU%2FmKQ8nHuct4WSX%2FA%3D&se=2030-10-24T04%3A22%3A05Z&sp=r" +RUN dpkg -i redis-tools_6.0.6-1~bpo10+1_armhf.deb redis-server_6.0.6-1~bpo10+1_armhf.deb || apt-get install -f +RUN rm redis-tools_6.0.6-1~bpo10+1_armhf.deb redis-server_6.0.6-1~bpo10+1_armhf.deb +{% elif CONFIGURED_ARCH == "arm64" %} +RUN curl -o redis-tools_6.0.6-1~bpo10+1_arm64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-tools_6.0.6-1_bpo10+1_arm64.deb?sv=2015-04-05&sr=b&sig=GbkJV2wWln3hoz27zKi5erdk3NDKrAFrQriA97bcRCY%3D&se=2030-10-24T04%3A22%3A21Z&sp=r" +RUN curl -o redis-server_6.0.6-1~bpo10+1_arm64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-server_6.0.6-1_bpo10+1_arm64.deb?sv=2015-04-05&sr=b&sig=622w2KzIKIjAaaA0Bz12MzU%2BUBzY2AiXFIFfuKNoKSk%3D&se=2030-10-24T04%3A21%3A44Z&sp=r" +RUN dpkg -i redis-tools_6.0.6-1~bpo10+1_arm64.deb redis-server_6.0.6-1~bpo10+1_arm64.deb || apt-get install -f +RUN rm redis-tools_6.0.6-1~bpo10+1_arm64.deb redis-server_6.0.6-1~bpo10+1_arm64.deb +{% else %} +RUN curl -o redis-tools_6.0.6-1~bpo10+1_amd64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-tools_6.0.6-1~bpo10+1_amd64.deb?sv=2015-04-05&sr=b&sig=73zbmjkf3pi%2Bn0R8Hy7CWT2EUvOAyzM5aLYJWCLySGM%3D&se=2030-09-06T19%3A44%3A59Z&sp=r" +RUN curl -o redis-server_6.0.6-1~bpo10+1_amd64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-server_6.0.6-1~bpo10+1_amd64.deb?sv=2015-04-05&sr=b&sig=2Ketg7BmkZEaTxR%2FgvAFVmhjn7ywdmkc7l2T2rsL57o%3D&se=2030-09-06T19%3A45%3A20Z&sp=r" +RUN dpkg -i redis-tools_6.0.6-1~bpo10+1_amd64.deb redis-server_6.0.6-1~bpo10+1_amd64.deb || apt-get install -f +RUN rm redis-tools_6.0.6-1~bpo10+1_amd64.deb redis-server_6.0.6-1~bpo10+1_amd64.deb +{% endif %} + {% if docker_database_debs.strip() -%} # Copy locally-built Debian package dependencies {{ copy_files("debs/", docker_database_debs.split(' '), "/debs/") }} @@ -34,9 +52,12 @@ RUN apt-get clean -y && \ 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 ["database_config.json.j2", "/usr/share/sonic/templates/"] +COPY ["database_global.json.j2", "/usr/share/sonic/templates/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["files/sysctl-net.conf", "/etc/sysctl.d/"] COPY ["critical_processes", "/etc/supervisor"] +COPY ["files/update_chassisdb_config", "/usr/local/bin/"] +COPY ["flush_unused_database", "/usr/local/bin/"] ENTRYPOINT ["/usr/local/bin/docker-database-init.sh"] diff --git a/dockers/docker-database/base_image_files/monit_database b/dockers/docker-database/base_image_files/monit_database index c5508922864e..47c9d1b2d47f 100644 --- a/dockers/docker-database/base_image_files/monit_database +++ b/dockers/docker-database/base_image_files/monit_database @@ -3,5 +3,5 @@ ## 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 +check program database|redis_server with path "/usr/bin/process_checker database /usr/bin/redis-server" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/dockers/docker-database/critical_processes b/dockers/docker-database/critical_processes index 7800f0fad3ff..53a45931dfc9 100644 --- a/dockers/docker-database/critical_processes +++ b/dockers/docker-database/critical_processes @@ -1 +1 @@ -redis +program:redis diff --git a/dockers/docker-database/database_config.json b/dockers/docker-database/database_config.json deleted file mode 100644 index b86ae11bba98..000000000000 --- a/dockers/docker-database/database_config.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "INSTANCES": { - "redis":{ - "hostname" : "127.0.0.1", - "port" : 6379, - "unix_socket_path" : "/var/run/redis/redis.sock" - } - }, - "DATABASES" : { - "APPL_DB" : { - "id" : 0, - "separator": ":", - "instance" : "redis" - }, - "ASIC_DB" : { - "id" : 1, - "separator": ":", - "instance" : "redis" - }, - "COUNTERS_DB" : { - "id" : 2, - "separator": ":", - "instance" : "redis" - }, - "LOGLEVEL_DB" : { - "id" : 3, - "separator": ":", - "instance" : "redis" - }, - "CONFIG_DB" : { - "id" : 4, - "separator": "|", - "instance" : "redis" - }, - "PFC_WD_DB" : { - "id" : 5, - "separator": ":", - "instance" : "redis" - }, - "FLEX_COUNTER_DB" : { - "id" : 5, - "separator": ":", - "instance" : "redis" - }, - "STATE_DB" : { - "id" : 6, - "separator": "|", - "instance" : "redis" - }, - "SNMP_OVERLAY_DB" : { - "id" : 7, - "separator": "|", - "instance" : "redis" - } - }, - "VERSION" : "1.0" -} diff --git a/dockers/docker-database/database_config.json.j2 b/dockers/docker-database/database_config.json.j2 new file mode 100644 index 000000000000..5ad730f10015 --- /dev/null +++ b/dockers/docker-database/database_config.json.j2 @@ -0,0 +1,94 @@ +{ + "INSTANCES": { + "redis":{ + "hostname" : "{{HOST_IP}}", + "port" : 6379, + "unix_socket_path" : "/var/run/redis{{NAMESPACE_ID}}/redis.sock", + "persistence_for_warm_boot" : "yes" + }, + "redis_chassis":{ + "hostname" : "redis_chassis.server", + "port": 6380, + "unix_socket_path": "/var/run/redis-chassis/redis_chassis.sock", + "persistence_for_warm_boot" : "yes" + } + }, + "DATABASES" : { + "APPL_DB" : { + "id" : 0, + "separator": ":", + "instance" : "redis" + }, + "ASIC_DB" : { + "id" : 1, + "separator": ":", + "instance" : "redis" + }, + "COUNTERS_DB" : { + "id" : 2, + "separator": ":", + "instance" : "redis" + }, + "LOGLEVEL_DB" : { + "id" : 3, + "separator": ":", + "instance" : "redis" + }, + "CONFIG_DB" : { + "id" : 4, + "separator": "|", + "instance" : "redis" + }, + "PFC_WD_DB" : { + "id" : 5, + "separator": ":", + "instance" : "redis" + }, + "FLEX_COUNTER_DB" : { + "id" : 5, + "separator": ":", + "instance" : "redis" + }, + "STATE_DB" : { + "id" : 6, + "separator": "|", + "instance" : "redis" + }, + "SNMP_OVERLAY_DB" : { + "id" : 7, + "separator": "|", + "instance" : "redis" + }, + "RESTAPI_DB" : { + "id" : 8, + "separator": "|", + "instance" : "redis" + }, + "GB_ASIC_DB" : { + "id" : 9, + "separator": "|", + "instance" : "redis" + }, + "GB_COUNTERS_DB" : { + "id" : 10, + "separator": "|", + "instance" : "redis" + }, + "GB_FLEX_COUNTER_DB" : { + "id" : 11, + "separator": "|", + "instance" : "redis" + }, + "CHASSIS_APP_DB" : { + "id" : 12, + "separator": "|", + "instance" : "redis_chassis" + }, + "CHASSIS_STATE_DB" : { + "id" : 13, + "separator": "|", + "instance" : "redis_chassis" + } + }, + "VERSION" : "1.0" +} diff --git a/dockers/docker-database/database_global.json.j2 b/dockers/docker-database/database_global.json.j2 new file mode 100644 index 000000000000..777bce43b324 --- /dev/null +++ b/dockers/docker-database/database_global.json.j2 @@ -0,0 +1,21 @@ +{% set namespace_cnt = NAMESPACE_COUNT|int %} +{ + "INCLUDES" : [ + { + "include" : "../../redis/sonic-db/database_config.json" + }, +{% if namespace_cnt > 1 %} +{% for ns in range(namespace_cnt) %} + { + "namespace" : "{{NAMESPACE_PREFIX}}{{ns}}", + "include" : "../../redis{{ns}}/sonic-db/database_config.json" +{% if ns == namespace_cnt-1 %} + } +{% else %} + }, +{% endif %} +{% endfor %} + ], + "VERSION" : "1.0" +} +{% endif %} diff --git a/dockers/docker-database/docker-database-init.sh b/dockers/docker-database/docker-database-init.sh index ebdcc6abb694..413bbc0b20df 100755 --- a/dockers/docker-database/docker-database-init.sh +++ b/dockers/docker-database/docker-database-init.sh @@ -1,14 +1,96 @@ #!/usr/bin/env bash -mkdir -p /var/run/redis/sonic-db -if [ -f /etc/sonic/database_config.json ]; then - cp /etc/sonic/database_config.json /var/run/redis/sonic-db +# For linux host namespace, in both single and multi ASIC platform use the loopback interface +# For other namespaces, use eth0 interface which is connected to the docker0 bridge in the host. +if [[ $NAMESPACE_ID == "" ]] +then + INTFC=lo else - cp /etc/default/sonic-db/database_config.json /var/run/redis/sonic-db + INTFC=eth0 fi +# Get the ip address of the interface +# if the ip address was not retrieved correctly, put localhost(127.0.0.1) as the default. +host_ip=$(ip -4 -o addr show $INTFC | awk '{print $4}' | cut -d'/' -f1 | head -1) +if [[ $host_ip == "" ]] +then + host_ip=127.0.0.1 +fi + +REDIS_DIR=/var/run/redis$NAMESPACE_ID +mkdir -p $REDIS_DIR/sonic-db mkdir -p /etc/supervisor/conf.d/ -# generate all redis server supervisord configuration file -sonic-cfggen -j /var/run/redis/sonic-db/database_config.json -t /usr/share/sonic/templates/supervisord.conf.j2 > /etc/supervisor/conf.d/supervisord.conf -exec /usr/bin/supervisord +if [ -f /etc/sonic/database_config$NAMESPACE_ID.json ]; then + cp /etc/sonic/database_config$NAMESPACE_ID.json $REDIS_DIR/sonic-db/database_config.json +else + HOST_IP=$host_ip j2 /usr/share/sonic/templates/database_config.json.j2 > $REDIS_DIR/sonic-db/database_config.json +fi + +# on VoQ system, we only publish redis_chassis instance and CHASSIS_APP_DB when +# either chassisdb.conf indicates starts chassis_db or connect to chassis_db, +# and redis_chassis instance is started in different container. +# in order to do that, first we save original database config file, then +# call update_chasissdb_config to remove chassis_db config from +# the original database config file and use the modified config file to generate +# supervisord config, so that we won't start redis_chassis service. +# then we will decide to publish modified or original database config file based +# on the setting in chassisdb.conf +start_chassis_db=0 +chassis_db_address="" +chassis_db_port="" +chassisdb_config="/usr/share/sonic/platform/chassisdb.conf" +[ -f $chassisdb_config ] && source $chassisdb_config + +db_cfg_file="/var/run/redis/sonic-db/database_config.json" +db_cfg_file_tmp="/var/run/redis/sonic-db/database_config.json.tmp" +cp $db_cfg_file $db_cfg_file_tmp + +if [[ $DATABASE_TYPE == "chassisdb" ]]; then + # Docker init for database-chassis + echo "Init docker-database-chassis..." + update_chassisdb_config -j $db_cfg_file_tmp -k -p $chassis_db_port + # generate all redis server supervisord configuration file + sonic-cfggen -j $db_cfg_file_tmp -t /usr/share/sonic/templates/supervisord.conf.j2 > /etc/supervisor/conf.d/supervisord.conf + rm $db_cfg_file_tmp + exec /usr/local/bin/supervisord + exit 0 +fi + +# copy/generate the database_global.json file if this is global database service in multi asic platform. +if [[ $NAMESPACE_ID == "" ]] && [[ $NAMESPACE_COUNT -gt 1 ]] +then + if [ -f /etc/sonic/database_global.json ]; then + cp /etc/sonic/database_global.json $REDIS_DIR/sonic-db/database_global.json + else + j2 /usr/share/sonic/templates/database_global.json.j2 > $REDIS_DIR/sonic-db/database_global.json + fi +fi +# delete chassisdb config to generate supervisord config +update_chassisdb_config -j $db_cfg_file_tmp -d +sonic-cfggen -j $db_cfg_file_tmp -t /usr/share/sonic/templates/supervisord.conf.j2 > /etc/supervisor/conf.d/supervisord.conf + +if [[ "$start_chassis_db" != "1" ]] && [[ -z "$chassis_db_address" ]]; then + cp $db_cfg_file_tmp $db_cfg_file +else + update_chassisdb_config -j $db_cfg_file -p $chassis_db_port +fi +rm $db_cfg_file_tmp + +# copy dump.rdb file to each instance for restoration +DUMPFILE=/var/lib/redis/dump.rdb +redis_inst_list=`/usr/bin/python3 -c "import swsssdk; print(' '.join(swsssdk.SonicDBConfig.get_instancelist().keys()))"` +for inst in $redis_inst_list +do + mkdir -p /var/lib/$inst + if [[ -f $DUMPFILE ]]; then + # copy warmboot rdb file into each new instance location + if [[ "$DUMPFILE" != "/var/lib/$inst/dump.rdb" ]]; then + cp $DUMPFILE /var/lib/$inst/dump.rdb + fi + else + echo -n > /var/lib/$inst/dump.rdb + fi +done + +exec /usr/local/bin/supervisord diff --git a/dockers/docker-database/flush_unused_database b/dockers/docker-database/flush_unused_database new file mode 100755 index 000000000000..10cacb5e0b33 --- /dev/null +++ b/dockers/docker-database/flush_unused_database @@ -0,0 +1,28 @@ +#!/usr/bin/python +import swsssdk +import redis +import subprocess +import time + +while(True): + output = subprocess.Popen(['sonic-db-cli', 'PING'], stdout=subprocess.PIPE).communicate()[0] + if 'PONG' in output: + break + time.sleep(1) + +instlists = swsssdk.SonicDBConfig.get_instancelist() +for instname, v in instlists.items(): + insthost = v['hostname'] + instsocket = v['unix_socket_path'] + + dblists = swsssdk.SonicDBConfig.get_dblist() + for dbname in dblists: + dbid = swsssdk.SonicDBConfig.get_dbid(dbname) + dbinst = swsssdk.SonicDBConfig.get_instancename(dbname) + + # this DB is on current instance, skip flush + if dbinst == instname: + continue + + r = redis.Redis(host=insthost, unix_socket_path=instsocket, db=dbid) + r.flushdb() diff --git a/dockers/docker-database/ping_pong_db_insts b/dockers/docker-database/ping_pong_db_insts deleted file mode 100755 index 484d4da0cfb0..000000000000 --- a/dockers/docker-database/ping_pong_db_insts +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/python -import json -import os -import subprocess -import time -import syslog - -def ping_redis(cmd): - output = '' - while True: - try: - output = subprocess.check_output(cmd, shell=True) - except subprocess.CalledProcessError as e: - syslog.syslog(syslog.LOG_ERR, 'ping redis failed, cmd : {}'.format(cmd)) - - if 'PONG' in output: - break - syslog.syslog(syslog.LOG_ERR, 'ping response : {}'.format(output)) - time.sleep(1) - -database_config_file = "/var/run/redis/sonic-db/database_config.json" - -data = {} -while True: - if os.path.isfile(database_config_file): - with open(database_config_file, "r") as read_file: - data = json.load(read_file) - break - time.sleep(1) - syslog.syslog(syslog.LOG_ERR, 'config file {} does not exist right now'.format(database_config_file)) - -while True: - if 'INSTANCES' in data: - for inst in data["INSTANCES"]: - port = data["INSTANCES"][inst]["port"] - cmd = "redis-cli -p " + str(port) + " ping" - ping_redis(cmd) - break - time.sleep(1) - syslog.syslog(syslog.LOG_ERR, 'config file {} does not have INSTANCES'.format(database_config_file)) diff --git a/dockers/docker-database/supervisord.conf.j2 b/dockers/docker-database/supervisord.conf.j2 index 9e855527edba..616475fb07ce 100644 --- a/dockers/docker-database/supervisord.conf.j2 +++ b/dockers/docker-database/supervisord.conf.j2 @@ -5,12 +5,12 @@ nodaemon=true [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name database -events=PROCESS_STATE_EXITED +events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING autostart=true autorestart=unexpected [program:rsyslogd] -command=/bin/bash -c "rm -f /var/run/rsyslogd.pid && /usr/sbin/rsyslogd -n" +command=/usr/sbin/rsyslogd -n -iNONE priority=1 autostart=true autorestart=false @@ -18,9 +18,14 @@ stdout_logfile=syslog stderr_logfile=syslog {% if INSTANCES %} -{% for redis_inst, redis_items in INSTANCES.iteritems() %} +{% for redis_inst, redis_items in INSTANCES.items() %} [program: {{ redis_inst }}] -command=/bin/bash -c "{ [[ -s /var/lib/{{ redis_inst }}/dump.rdb ]] || rm -f /var/lib/{{ redis_inst }}/dump.rdb; } && mkdir -p /var/lib/{{ redis_inst }} && exec /usr/bin/redis-server /etc/redis/redis.conf --port {{ redis_items['port'] }} --unixsocket {{ redis_items['unix_socket_path'] }} --pidfile /var/run/redis/{{ redis_inst }}.pid --dir /var/lib/{{ redis_inst }}" +{% if redis_items['hostname'] != '127.0.0.1' and redis_inst != 'redis_chassis' %} +{%- set LOOPBACK_IP = '127.0.0.1' -%} +{%- else -%} +{%- set LOOPBACK_IP = '' -%} +{%- endif -%} +command=/bin/bash -c "{ [[ -s /var/lib/{{ redis_inst }}/dump.rdb ]] || rm -f /var/lib/{{ redis_inst }}/dump.rdb; } && mkdir -p /var/lib/{{ redis_inst }} && exec /usr/bin/redis-server /etc/redis/redis.conf --bind {{ LOOPBACK_IP }} {{ redis_items['hostname'] }} --port {{ redis_items['port'] }} --unixsocket {{ redis_items['unix_socket_path'] }} --pidfile /var/run/redis/{{ redis_inst }}.pid --dir /var/lib/{{ redis_inst }}" priority=2 autostart=true autorestart=false @@ -28,3 +33,11 @@ stdout_logfile=syslog stderr_logfile=syslog {% endfor %} {% endif %} + +[program:flushdb] +command=/bin/bash -c "sleep 300 && /usr/local/bin/flush_unused_database" +priority=3 +autostart=true +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog diff --git a/dockers/docker-dhcp-relay/Dockerfile.j2 b/dockers/docker-dhcp-relay/Dockerfile.j2 index d3c09f9ba260..1100aa510742 100644 --- a/dockers/docker-dhcp-relay/Dockerfile.j2 +++ b/dockers/docker-dhcp-relay/Dockerfile.j2 @@ -1,12 +1,16 @@ {% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} -FROM docker-config-engine-stretch +FROM docker-config-engine-buster ARG docker_container_name +ARG image_version 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 +# Pass the image_version to container +ENV IMAGE_VERSION=$image_version + # Update apt's cache of available packages RUN apt-get update @@ -25,7 +29,7 @@ RUN apt-get clean -y && \ rm -rf /debs COPY ["docker_init.sh", "start.sh", "/usr/bin/"] -COPY ["docker-dhcp-relay.supervisord.conf.j2", "wait_for_intf.sh.j2", "/usr/share/sonic/templates/"] +COPY ["docker-dhcp-relay.supervisord.conf.j2", "port-name-alias-map.txt.j2", "wait_for_intf.sh.j2", "/usr/share/sonic/templates/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor"] diff --git a/dockers/docker-dhcp-relay/critical_processes b/dockers/docker-dhcp-relay/critical_processes index ddb183963a67..855851bf2d68 100644 --- a/dockers/docker-dhcp-relay/critical_processes +++ b/dockers/docker-dhcp-relay/critical_processes @@ -1 +1 @@ -isc-dhcp-relay +group:isc-dhcp-relay 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 d52400480775..19a6cc294f7f 100644 --- a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 +++ b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 @@ -3,34 +3,47 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python3 -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE +buffer_size=50 + [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name dhcp_relay -events=PROCESS_STATE_EXITED +events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING autostart=true autorestart=unexpected -[program:start.sh] -command=/usr/bin/start.sh +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE priority=1 -autostart=true +autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true -[program:rsyslogd] -command=/usr/sbin/rsyslogd -n +[program:start] +command=/usr/bin/start.sh priority=2 autostart=false autorestart=false +startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running {# If our configuration has VLANs... #} -{% if VLAN %} +{% if VLAN_INTERFACE %} {# Count how many VLANs require a DHCP relay agent... #} {% set num_relays = { 'count': 0 } %} -{% for vlan_name in VLAN %} -{% if VLAN[vlan_name]['dhcp_servers'] %} +{% for vlan_name in VLAN_INTERFACE %} +{% if VLAN and vlan_name in VLAN and VLAN[vlan_name]['dhcp_servers'] %} {% set _dummy = num_relays.update({'count': num_relays.count + 1}) %} {% endif %} {% endfor %} @@ -39,8 +52,8 @@ stderr_logfile=syslog [group:isc-dhcp-relay] programs= {%- set add_preceding_comma = { 'flag': False } %} -{% for vlan_name in VLAN %} -{% if VLAN[vlan_name]['dhcp_servers'] %} +{% for vlan_name in VLAN_INTERFACE %} +{% if VLAN and vlan_name in VLAN and VLAN[vlan_name]['dhcp_servers'] %} {% if add_preceding_comma.flag %},{% endif %} {% set _dummy = add_preceding_comma.update({'flag': True}) %} isc-dhcp-relay-{{ vlan_name }} @@ -50,8 +63,8 @@ isc-dhcp-relay-{{ vlan_name }} {# Create a program entry for each DHCP relay agent instance #} {% set relay_for_ipv4 = { 'flag': False } %} -{% for vlan_name in VLAN %} -{% if VLAN[vlan_name]['dhcp_servers'] %} +{% for vlan_name in VLAN_INTERFACE %} +{% if VLAN and vlan_name in VLAN and 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}) %} @@ -62,6 +75,8 @@ isc-dhcp-relay-{{ vlan_name }} [program:isc-dhcp-relay-{{ vlan_name }}] {# We treat this VLAN as a downstream interface (-id), as we only want to listen for requests #} command=/usr/sbin/dhcrelay -d -m discard -a %%h:%%p %%P --name-alias-map-file /tmp/port-name-alias-map.txt -id {{ vlan_name }} +{#- Dual ToR Option #} +{% if 'subtype' in DEVICE_METADATA['localhost'] and DEVICE_METADATA['localhost']['subtype'] == 'DualToR' %} -U Loopback0 -dt{% endif -%} {#- 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 -%} @@ -81,6 +96,8 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited {% endif %} {% endif %} @@ -89,8 +106,8 @@ stderr_logfile=syslog [group:dhcpmon] programs= {%- set add_preceding_comma = { 'flag': False } %} -{% for vlan_name in VLAN %} -{% if VLAN[vlan_name]['dhcp_servers'] %} +{% for vlan_name in VLAN_INTERFACE %} +{% if VLAN and vlan_name in VLAN and VLAN[vlan_name]['dhcp_servers'] %} {% if add_preceding_comma.flag %},{% endif %} {% set _dummy = add_preceding_comma.update({'flag': True}) %} dhcpmon-{{ vlan_name }} @@ -100,8 +117,8 @@ dhcpmon-{{ vlan_name }} {# 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 vlan_name in VLAN_INTERFACE %} +{% if VLAN and vlan_name in VLAN and 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}) %} @@ -122,12 +139,19 @@ command=/usr/sbin/dhcpmon -id {{ vlan_name }} {% for (name, prefix) in PORTCHANNEL_INTERFACE|pfx_filter %} {% if prefix | ipv4 %} -iu {{ name }}{% endif -%} {% endfor %} +{% if MGMT_INTERFACE %} +{% for (name, prefix) in MGMT_INTERFACE|pfx_filter %} +{% if prefix | ipv4 %} -im {{ name }}{% endif -%} +{% endfor %} +{% endif %} priority=4 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=isc-dhcp-relay-{{ vlan_name }}:running {% endif %} {% endif %} diff --git a/dockers/docker-dhcp-relay/docker_init.sh b/dockers/docker-dhcp-relay/docker_init.sh index f6d402e6f780..1ff0e936ff68 100755 --- a/dockers/docker-dhcp-relay/docker_init.sh +++ b/dockers/docker-dhcp-relay/docker_init.sh @@ -2,17 +2,23 @@ # Generate supervisord config file mkdir -p /etc/supervisor/conf.d/ -sonic-cfggen -d -t /usr/share/sonic/templates/docker-dhcp-relay.supervisord.conf.j2 > /etc/supervisor/conf.d/docker-dhcp-relay.supervisord.conf -# Generate the script that waits for all interfaces to come up and make it executable -sonic-cfggen -d -t /usr/share/sonic/templates/wait_for_intf.sh.j2 > /usr/bin/wait_for_intf.sh -chmod +x /usr/bin/wait_for_intf.sh +# Generate the following files from templates: +# 1. supervisord configuration +# 2. wait_for_intf.sh, which waits for all interfaces to come up +# 3. port-to-alias name map +CFGGEN_PARAMS=" \ + -d \ + -t /usr/share/sonic/templates/docker-dhcp-relay.supervisord.conf.j2,/etc/supervisor/conf.d/docker-dhcp-relay.supervisord.conf \ + -t /usr/share/sonic/templates/wait_for_intf.sh.j2,/usr/bin/wait_for_intf.sh \ + -t /usr/share/sonic/templates/port-name-alias-map.txt.j2,/tmp/port-name-alias-map.txt \ +" +sonic-cfggen $CFGGEN_PARAMS -# Generate port name-alias map for isc-dhcp-relay to parse. Each line contains one -# name-alias pair of the form " " -sonic-cfggen -d --var-json "PORT" | python -c "import sys, json, os; [sys.stdout.write('%s %s\n' % (k, v['alias'] if 'alias' in v else k)) for (k, v) in json.load(sys.stdin).iteritems()]" > /tmp/port-name-alias-map.txt +# Make the script that waits for all interfaces to come up executable +chmod +x /usr/bin/wait_for_intf.sh # The docker container should start this script as PID 1, so now that supervisord is -# properly configured, we exec supervisord so that it runs as PID 1 for the +# properly configured, we exec /usr/local/bin/supervisord so that it runs as PID 1 for the # duration of the container's lifetime -exec /usr/bin/supervisord +exec /usr/local/bin/supervisord diff --git a/dockers/docker-dhcp-relay/port-name-alias-map.txt.j2 b/dockers/docker-dhcp-relay/port-name-alias-map.txt.j2 new file mode 100644 index 000000000000..b2290a9ffbf2 --- /dev/null +++ b/dockers/docker-dhcp-relay/port-name-alias-map.txt.j2 @@ -0,0 +1,5 @@ +{# Generate port name-alias map for isc-dhcp-relay to parse. Each line contains one #} +{# name-alias pair of the form " " #} +{% for port, config in PORT.items() %} + {{- port }} {% if "alias" in config %}{{ config["alias"] }}{% else %}{{ port }}{% endif %} {{- "\n" -}} +{% endfor -%} diff --git a/dockers/docker-dhcp-relay/start.sh b/dockers/docker-dhcp-relay/start.sh index dbbf32251080..cb563eb003c3 100755 --- a/dockers/docker-dhcp-relay/start.sh +++ b/dockers/docker-dhcp-relay/start.sh @@ -1,10 +1,14 @@ #!/usr/bin/env bash -# Remove stale rsyslog PID file if it exists -rm -f /var/run/rsyslogd.pid +if [ "${RUNTIME_OWNER}" == "" ]; then + RUNTIME_OWNER="kube" +fi -# Start rsyslog -supervisorctl start rsyslogd +CTR_SCRIPT="/usr/share/sonic/scripts/container_startup.py" +if test -f ${CTR_SCRIPT} +then + ${CTR_SCRIPT} -f dhcp_relay -o ${RUNTIME_OWNER} -v ${IMAGE_VERSION} +fi # If our supervisor config has entries in the "isc-dhcp-relay" group... if [ $(supervisorctl status | grep -c "^isc-dhcp-relay:") -gt 0 ]; then @@ -15,13 +19,4 @@ if [ $(supervisorctl status | grep -c "^isc-dhcp-relay:") -gt 0 ]; then # relay agent starts, it will not listen or send on that interface for the # lifetime of the process. /usr/bin/wait_for_intf.sh - - # Start 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/dockers/docker-fpm-frr/Dockerfile.j2 b/dockers/docker-fpm-frr/Dockerfile.j2 index 1c670682a342..42df1c6f38f8 100644 --- a/dockers/docker-fpm-frr/Dockerfile.j2 +++ b/dockers/docker-fpm-frr/Dockerfile.j2 @@ -1,5 +1,5 @@ {% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} -FROM docker-config-engine-stretch +FROM docker-config-engine-buster ARG docker_container_name ARG frr_user_uid @@ -14,12 +14,8 @@ ENV DEBIAN_FRONTEND=noninteractive # Install required packages RUN apt-get update && \ apt-get install -y \ - libdbus-1-3 \ - libdaemon0 \ - libjansson4 \ libc-ares2 \ iproute2 \ - libpython2.7 \ libjson-c3 \ logrotate \ libunwind8 @@ -35,25 +31,34 @@ RUN useradd -u ${frr_user_uid} -g ${frr_user_gid} -M -s /bin/false frr {{ install_debian_packages(docker_fpm_frr_debs.split(' ')) }} {%- endif %} +{% if docker_fpm_frr_whls.strip() %} +# Copy locally-built Python wheel dependencies +{{ copy_files("python-wheels/", docker_fpm_frr_whls.split(' '), "/python-wheels/") }} + +# Install locally-built Python wheel dependencies +{{ install_python_wheels(docker_fpm_frr_whls.split(' ')) }} +{% endif %} + RUN chown -R ${frr_user_uid}:${frr_user_gid} /etc/frr/ # Clean up RUN apt-get clean -y && \ apt-get autoclean -y && \ apt-get autoremove -y && \ - rm -rf /debs ~/.cache + rm -rf /debs ~/.cache /python-wheels -COPY ["bgpcfgd", "start.sh", "/usr/bin/"] -COPY ["*.j2", "/usr/share/sonic/templates/"] -COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["frr", "/usr/share/sonic/templates"] +COPY ["docker_init.sh", "/usr/bin/"] COPY ["snmp.conf", "/etc/snmp/frr.conf"] COPY ["TSA", "/usr/bin/TSA"] COPY ["TSB", "/usr/bin/TSB"] COPY ["TSC", "/usr/bin/TSC"] +COPY ["TS", "/usr/bin/TS"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] -COPY ["critical_processes", "/etc/supervisor"] +COPY ["zsocket.sh", "/usr/bin/"] RUN chmod a+x /usr/bin/TSA && \ chmod a+x /usr/bin/TSB && \ - chmod a+x /usr/bin/TSC + chmod a+x /usr/bin/TSC && \ + chmod a+x /usr/bin/zsocket.sh -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/bin/docker_init.sh"] diff --git a/dockers/docker-fpm-frr/TS b/dockers/docker-fpm-frr/TS new file mode 100755 index 000000000000..78ba24d5db63 --- /dev/null +++ b/dockers/docker-fpm-frr/TS @@ -0,0 +1,40 @@ +#!/bin/bash + +# Check whether the routemap is for internal BGP sessions. +function is_internal_route_map() +{ + [[ "$1" =~ .*"_INTERNAL_".* ]] +} + +function check_not_installed() +{ + c=0 + config=$(vtysh -c "show run") + for route_map_name in $(echo "$config" | sed -ne 's/ neighbor \S* route-map \(\S*\) out/\1/p' | egrep 'V4|V6'); + do + is_internal_route_map $route_map_name && continue + echo "$config" | egrep -q "^route-map $route_map_name permit 20$" + c=$((c+$?)) + echo "$config" | egrep -q "^route-map $route_map_name deny 30$" + c=$((c+$?)) + done + return $c +} + +function check_installed() +{ + c=0 + e=0 + config=$(vtysh -c "show run") + for route_map_name in $(echo "$config" | sed -ne 's/ neighbor \S* route-map \(\S*\) out/\1/p' | egrep 'V4|V6'); + do + is_internal_route_map $route_map_name && continue + echo "$config" | egrep -q "^route-map $route_map_name permit 20$" + c=$((c+$?)) + e=$((e+1)) + echo "$config" | egrep -q "^route-map $route_map_name deny 30$" + c=$((c+$?)) + e=$((e+1)) + done + return $((e-c)) +} diff --git a/dockers/docker-fpm-frr/TSA b/dockers/docker-fpm-frr/TSA index 1d74757b2d5f..6312bf0ba5e6 100755 --- a/dockers/docker-fpm-frr/TSA +++ b/dockers/docker-fpm-frr/TSA @@ -1,22 +1,33 @@ #!/bin/bash -c=0 -config=$(vtysh -c "show run") -echo "$config" | grep -q "route-map TO_BGP_PEER_V4 permit 2" -c=$((c+$?)) -echo "$config" | grep -q "route-map TO_BGP_PEER_V4 deny 3" -c=$((c+$?)) -echo "$config" | grep -q "route-map TO_BGP_PEER_V6 permit 2" -c=$((c+$?)) -echo "$config" | grep -q "route-map TO_BGP_PEER_V6 deny 3" -c=$((c+$?)) +# Load the common functions +source /usr/bin/TS -if [[ $c -eq 4 ]]; +check_not_installed +not_installed=$? +if [[ $not_installed -ne 0 ]]; then TSA_FILE=$(mktemp) - sonic-cfggen -d -y /etc/sonic/constants.yml -t /usr/share/sonic/templates/bgpd.tsa.isolate.conf.j2 > "$TSA_FILE" - vtysh -f "$TSA_FILE" - rm -f "$TSA_FILE" + for route_map_name in $(echo "$config" | sed -ne 's/ neighbor \S* route-map \(\S*\) out/\1/p'); + do + is_internal_route_map $route_map_name && continue + case "$route_map_name" in + *V4*) + ip_version=V4 + ip_protocol=ip + ;; + *V6*) + ip_version=V6 + ip_protocol=ipv6 + ;; + *) + continue + ;; + esac + sonic-cfggen -d -a "{\"route_map_name\":\"$route_map_name\", \"ip_version\": \"$ip_version\", \"ip_protocol\": \"$ip_protocol\"}" -y /etc/sonic/constants.yml -t /usr/share/sonic/templates/bgpd/tsa/bgpd.tsa.isolate.conf.j2 > "$TSA_FILE" + vtysh -f "$TSA_FILE" + rm -f "$TSA_FILE" + done echo "System Mode: Normal -> Maintenance" else echo "System is already in Maintenance mode" diff --git a/dockers/docker-fpm-frr/TSB b/dockers/docker-fpm-frr/TSB index 83ead86952c3..44f9b15aea27 100755 --- a/dockers/docker-fpm-frr/TSB +++ b/dockers/docker-fpm-frr/TSB @@ -1,22 +1,29 @@ #!/bin/bash -c=0 -config=$(vtysh -c "show run") -echo "$config" | grep -q "route-map TO_BGP_PEER_V4 permit 2" -c=$((c+$?)) -echo "$config" | grep -q "route-map TO_BGP_PEER_V4 deny 3" -c=$((c+$?)) -echo "$config" | grep -q "route-map TO_BGP_PEER_V6 permit 2" -c=$((c+$?)) -echo "$config" | grep -q "route-map TO_BGP_PEER_V6 deny 3" -c=$((c+$?)) +# Load the common functions +source /usr/bin/TS -if [[ $c -eq 0 ]]; +check_installed +installed=$? +if [[ $installed -ne 0 ]]; then TSB_FILE=$(mktemp) - sonic-cfggen -d -y /etc/sonic/constants.yml -t /usr/share/sonic/templates/bgpd.tsa.unisolate.conf.j2 > "$TSB_FILE" - vtysh -f "$TSB_FILE" - rm -f "$TSB_FILE" + for route_map_name in $(echo "$config" | sed -ne 's/ neighbor \S* route-map \(\S*\) out/\1/p'); + do + is_internal_route_map $route_map_name && continue + case "$route_map_name" in + *V4*) + ;; + *V6*) + ;; + *) + continue + ;; + esac + sonic-cfggen -d -a "{\"route_map_name\":\"$route_map_name\"}" -t /usr/share/sonic/templates/bgpd/tsa/bgpd.tsa.unisolate.conf.j2 > "$TSB_FILE" + vtysh -f "$TSB_FILE" + rm -f "$TSB_FILE" + done echo "System Mode: Maintenance -> Normal" else echo "System is already in Normal mode" diff --git a/dockers/docker-fpm-frr/TSC b/dockers/docker-fpm-frr/TSC index c79f4bb2a41b..a0e908439e41 100755 --- a/dockers/docker-fpm-frr/TSC +++ b/dockers/docker-fpm-frr/TSC @@ -1,25 +1,20 @@ #!/bin/bash -echo "Traffic Shift Check:" -c=0 -config=$(vtysh -c "show run") -echo "$config" | grep -q "route-map TO_BGP_PEER_V4 permit 2" -c=$((c+$?)) -echo "$config" | grep -q "route-map TO_BGP_PEER_V4 deny 3" -c=$((c+$?)) -echo "$config" | grep -q "route-map TO_BGP_PEER_V6 permit 2" -c=$((c+$?)) -echo "$config" | grep -q "route-map TO_BGP_PEER_V6 deny 3" -c=$((c+$?)) +# Load the common functions +source /usr/bin/TS -if [[ $c -eq 4 ]]; +check_not_installed +not_installed=$? + +check_installed +installed=$? + +if [[ $installed -eq 0 ]]; then echo "System Mode: Normal" -elif [[ $c -eq 0 ]]; +elif [[ $not_installed -eq 0 ]]; then echo "System Mode: Maintenance" else echo "System Mode: Not consistent" fi - -echo diff --git a/dockers/docker-fpm-frr/base_image_files/TS b/dockers/docker-fpm-frr/base_image_files/TS new file mode 100755 index 000000000000..de1e50b7a306 --- /dev/null +++ b/dockers/docker-fpm-frr/base_image_files/TS @@ -0,0 +1,29 @@ +#!/bin/bash + +# read SONiC immutable variables +[ -f /etc/sonic/sonic-environment ] && . /etc/sonic/sonic-environment + +PLATFORM=${PLATFORM:-`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform`} + +# Parse the device specific asic conf file, if it exists +ASIC_CONF=/usr/share/sonic/device/$PLATFORM/asic.conf +[ -f $ASIC_CONF ] && . $ASIC_CONF + +if [[ ($NUM_ASIC -gt 1) ]]; then + asic=0 + NAMESPACE_PREFIX='asic' + + while [ $asic -lt $NUM_ASIC ] + do + # Run TSA/TSB/TSC scripts in BGP instance for frontend ASICs. + sub_role=`sonic-cfggen -d -v "DEVICE_METADATA['localhost']['sub_role']" -n $NAMESPACE_PREFIX$asic` + if [ $sub_role == 'FrontEnd' ] + then + echo -e "BGP"$asic" : \c" + docker exec -i bgp$asic /usr/bin/$1 + fi + asic=$[$asic+1] + done +else + docker exec -i bgp /usr/bin/$1 +fi diff --git a/dockers/docker-fpm-frr/base_image_files/TSA b/dockers/docker-fpm-frr/base_image_files/TSA index 95c7957f7dc1..e96c76dd67b2 100755 --- a/dockers/docker-fpm-frr/base_image_files/TSA +++ b/dockers/docker-fpm-frr/base_image_files/TSA @@ -1,3 +1,3 @@ #!/bin/bash -docker exec -i bgp /usr/bin/TSA +/usr/bin/TS TSA diff --git a/dockers/docker-fpm-frr/base_image_files/TSB b/dockers/docker-fpm-frr/base_image_files/TSB index f292d2031db3..176b10c684c8 100755 --- a/dockers/docker-fpm-frr/base_image_files/TSB +++ b/dockers/docker-fpm-frr/base_image_files/TSB @@ -1,3 +1,3 @@ #!/bin/bash -docker exec -i bgp /usr/bin/TSB +/usr/bin/TS TSB diff --git a/dockers/docker-fpm-frr/base_image_files/TSC b/dockers/docker-fpm-frr/base_image_files/TSC index f0ccebb73d60..09d1409c50c7 100755 --- a/dockers/docker-fpm-frr/base_image_files/TSC +++ b/dockers/docker-fpm-frr/base_image_files/TSC @@ -1,5 +1,5 @@ #!/bin/bash -docker exec -i bgp /usr/bin/TSC +/usr/bin/TS TSC -/usr/bin/portstat -p 5 +portstat -p 5 diff --git a/dockers/docker-fpm-frr/base_image_files/monit_bgp b/dockers/docker-fpm-frr/base_image_files/monit_bgp index 5b943ea7c0bb..07705e84179d 100644 --- a/dockers/docker-fpm-frr/base_image_files/monit_bgp +++ b/dockers/docker-fpm-frr/base_image_files/monit_bgp @@ -6,18 +6,22 @@ ## bgpd ## staticd ## bgpcfgd +## bgpmon ############################################################################### -check process zebra matching "/usr/lib/frr/zebra" - if does not exist for 5 times within 5 cycles then alert +check program bgp|zebra with path "/usr/bin/process_checker bgp /usr/lib/frr/zebra" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles -check process fpmsyncd matching "fpmsyncd" - if does not exist for 5 times within 5 cycles then alert +check program bgp|fpmsyncd with path "/usr/bin/process_checker bgp fpmsyncd" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles -check process bgpd matching "/usr/lib/frr/bgpd" - if does not exist for 5 times within 5 cycles then alert +check program bgp|bgpd with path "/usr/bin/process_checker bgp /usr/lib/frr/bgpd" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles -check process staticd matching "/usr/lib/frr/staticd" - if does not exist for 5 times within 5 cycles then alert +check program bgp|staticd with path "/usr/bin/process_checker bgp /usr/lib/frr/staticd" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles -check process bgpcfgd matching "python /usr/bin/bgpcfgd" - if does not exist for 5 times within 5 cycles then alert +check program bgp|bgpcfgd with path "/usr/bin/process_checker bgp /usr/bin/python3 /usr/local/bin/bgpcfgd" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles + +check program bgp|bgpmon with path "/usr/bin/process_checker bgp /usr/bin/python3 /usr/local/bin/bgpmon" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/dockers/docker-fpm-frr/base_image_files/vtysh b/dockers/docker-fpm-frr/base_image_files/vtysh index 24016bd96b2c..e4efeb454cb3 100755 --- a/dockers/docker-fpm-frr/base_image_files/vtysh +++ b/dockers/docker-fpm-frr/base_image_files/vtysh @@ -1,4 +1,37 @@ #!/bin/bash +# read SONiC immutable variables +[ -f /etc/sonic/sonic-environment ] && . /etc/sonic/sonic-environment + +function help() +{ + echo -e "Usage: $0 -n [0 to $(($NUM_ASIC-1))] [OPTION]... " 1>&2; exit 1; +} + +DEV="" +PLATFORM=${PLATFORM:-`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform`} + +# Parse the device specific asic conf file, if it exists +ASIC_CONF=/usr/share/sonic/device/$PLATFORM/asic.conf +[ -f $ASIC_CONF ] && . $ASIC_CONF + +if [[ ($NUM_ASIC -gt 1) ]]; then + while getopts ":n:h:" opt; do + case "${opt}" in + h) help + ;; + n) DEV=${OPTARG} + [ $DEV -lt $NUM_ASIC -a $DEV -ge 0 ] || help + ;; + esac + done + + if [ -z "${DEV}" ]; then + help + fi + + # Skip the arguments -n while passing to docker command + shift 2 +fi # Determine whether stdout is on a terminal if [ -t 1 ] ; then @@ -7,10 +40,10 @@ if [ -t 1 ] ; then TTY=$(tty) function cleanup { - docker exec -i bgp pkill -HUP -f "vtysh $TTY" + docker exec -i bgp$DEV pkill -HUP -f "vtysh $TTY" } trap cleanup HUP - docker exec -ti bgp vtysh "$TTY" "$@" + docker exec -ti bgp$DEV vtysh "$TTY" "$@" else - docker exec -i bgp vtysh "$@" + docker exec -i bgp$DEV vtysh "$@" fi diff --git a/dockers/docker-fpm-frr/bgpcfgd b/dockers/docker-fpm-frr/bgpcfgd deleted file mode 100755 index 4348d22bcb8f..000000000000 --- a/dockers/docker-fpm-frr/bgpcfgd +++ /dev/null @@ -1,444 +0,0 @@ -#!/usr/bin/env python - -import sys -import subprocess -import datetime -import time -import syslog -import signal -import traceback -import os -import tempfile -import json -from collections import defaultdict -from pprint import pprint -from pprint import pformat - -import jinja2 -import netaddr -from swsscommon import swsscommon - - -g_run = True -g_debug = False - - -def run_command(command, shell=False): - str_cmd = " ".join(command) - if g_debug: - syslog.syslog(syslog.LOG_DEBUG, "execute command {}.".format(str_cmd)) - p = subprocess.Popen(command, shell=shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - stdout, stderr = p.communicate() - if p.returncode != 0: - syslog.syslog(syslog.LOG_ERR, 'command execution returned {}. Command: "{}", stdout: "{}", stderr: "{}"'.format(p.returncode, str_cmd, stdout, stderr)) - - return p.returncode, stdout, stderr - - -class TemplateFabric(object): - def __init__(self): - j2_template_paths = ['/usr/share/sonic/templates'] - j2_loader = jinja2.FileSystemLoader(j2_template_paths) - j2_env = jinja2.Environment(loader=j2_loader, trim_blocks=True) - j2_env.filters['ipv4'] = self.is_ipv4 - j2_env.filters['ipv6'] = self.is_ipv6 - self.env = j2_env - - def from_file(self, filename): - return self.env.get_template(filename) - - def from_string(self, tmpl): - return self.env.from_string(tmpl) - - @staticmethod - def is_ipv4(value): - if not value: - return False - if isinstance(value, netaddr.IPNetwork): - addr = value - else: - try: - addr = netaddr.IPNetwork(str(value)) - except: - return False - return addr.version == 4 - - @staticmethod - def is_ipv6(value): - if not value: - return False - if isinstance(value, netaddr.IPNetwork): - addr = value - else: - try: - addr = netaddr.IPNetwork(str(value)) - except: - return False - return addr.version == 6 - - -class Daemon(object): - SELECT_TIMEOUT = 1000 - - def __init__(self): - self.db_connectors = {} - self.selector = swsscommon.Select() - self.callbacks = defaultdict(lambda : defaultdict(list)) # db -> table -> [] - self.subscribers = set() - - 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_name, 0) - - if table_name not in self.callbacks[db]: - conn = self.db_connectors[db] - subscriber = swsscommon.SubscriberStateTable(conn, table_name) - self.subscribers.add(subscriber) - self.selector.addSelectable(subscriber) - self.callbacks[db][table_name].append(callback) - - def run(self): - while g_run: - state, _ = self.selector.select(Daemon.SELECT_TIMEOUT) - if state == self.selector.TIMEOUT: - continue - elif state == self.selector.ERROR: - raise Exception("Received error from select") - - for subscriber in self.subscribers: - key, op, fvs = subscriber.pop() - if not key: - continue - if g_debug: - syslog.syslog(syslog.LOG_DEBUG, "Received message : {}".format((key, op, fvs))) - for callback in self.callbacks[subscriber.getDbConnector().getDbId()][subscriber.getTableName()]: - callback(key, op, dict(fvs)) - - -class Directory(object): - def __init__(self): - self.data = defaultdict(dict) - self.notify = defaultdict(lambda: defaultdict(list)) - - def path_traverse(self, slot, path): - if slot not in self.data: - return False, None - elif path == '': - return True, self.data[slot] - d = self.data[slot] - for p in path.split("/"): - if p not in d: - return False, None - d = d[p] - return True, d - - def path_exist(self, slot, path): - return self.path_traverse(slot, path)[0] - - def get_path(self, slot, path): - return self.path_traverse(slot, path)[1] - - def put(self, slot, key, value): - self.data[slot][key] = value - if slot in self.notify: - for path in self.notify[slot].keys(): - if self.path_exist(slot, path): - for handler in self.notify[slot][path]: - handler() - - def get(self, slot, key): - return self.data[slot][key] - - def remove(self, slot, key): - if slot in self.data: - if key in self.data[slot]: - del self.data[slot][key] - else: - syslog.syslog(syslog.LOG_ERR, "Directory: Can't remove key '%s' from slot '%s'. The key doesn't exist" % (key, slot)) - else: - syslog.syslog(syslog.LOG_ERR, "Directory: Can't remove key '%s' from slot '%s'. The slot doesn't exist" % (key, slot)) - - def remove_slot(self, slot, key): - if slot in self.data: - del self.data[slot] - else: - syslog.syslog(syslog.LOG_ERR, "Directory: Can't remove slot '%s'. The slot doesn't exist" % slot) - - def get_slot(self, slot): - return self.data[slot] - - def available_slot(self, slot): - return slot in self.data - - def available_deps(self, deps): - res = True - for slot, path in deps: - res = res and self.path_exist(slot, path) - return res - - def subscribe(self, deps, handler): - for slot, path in deps: - self.notify[slot][path].append(handler) - - -class Manager(object): - def __init__(self, daemon, directory, deps, database, table_name): - self.directory = directory - self.deps = deps - self.set_queue = [] - daemon.add_manager(database, table_name, self.handler) - directory.subscribe(deps, self.on_deps_change) - - def handler(self, key, op, data): - if op == swsscommon.SET_COMMAND: - if self.directory.available_deps(self.deps): - res = self.set_handler(key, data) - if not res: - self.set_queue.append((key, data)) - else: - self.set_queue.append((key, data)) - elif op == swsscommon.DEL_COMMAND: - self.del_handler(key) - else: - 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) - if not res: - new_queue.append((key, data)) - self.set_queue = new_queue - - def set_handler(self, key, data): - syslog.syslog(syslog.LOG_ERR, "%s wasn't implemented for %s" % (self.__name__, self.__class__)) - - def del_handler(self, key): - syslog.syslog(syslog.LOG_ERR, "%s wasn't implemented for %s" % (self.__name__, self.__class__)) - - -class BGPDeviceMetaMgr(Manager): - def __init__(self, daemon, directory): - super(BGPDeviceMetaMgr, self).__init__( - daemon, - directory, - [], - "CONFIG_DB", - swsscommon.CFG_DEVICE_METADATA_TABLE_NAME - ) - - def set_handler(self, key, data): - if key != "localhost" or "bgp_asn" not in data: - return - if self.directory.path_exist("meta", "localhost/bgp_asn"): - bgp_asn = self.directory.get_path("meta", "localhost/bgp_asn") - if bgp_asn == data["bgp_asn"]: - return - self.directory.put("meta", key, data) - - return True - - def del_handler(self, key): - self.directory.remove("meta", key) - - -class BGPNeighborMetaMgr(Manager): - def __init__(self, daemon, directory): - super(BGPNeighborMetaMgr, self).__init__( - daemon, - directory, - [], - "CONFIG_DB", - swsscommon.CFG_DEVICE_NEIGHBOR_METADATA_TABLE_NAME - ) - - def set_handler(self, key, data): - self.directory.put("neigmeta", key, data) - - return True - - def del_handler(self, key): - self.directory.remove("neigmeta", key) - - -class BGPPeerMgr(Manager): - def __init__(self, daemon, directory): - super(BGPPeerMgr, self).__init__( - daemon, - directory, - [ - ("meta", "localhost/bgp_asn"), - ("neigmeta", ""), - ], - "CONFIG_DB", - swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME - ) - self.peers = self.load_peers() - fabric = TemplateFabric() - self.templates = { - "add": fabric.from_file('bgpd.peer.conf.j2'), - "delete": fabric.from_string('no neighbor {{ neighbor_addr }}'), - "shutdown": fabric.from_string('neighbor {{ neighbor_addr }} shutdown'), - "no shutdown": fabric.from_string('no neighbor {{ neighbor_addr }} shutdown'), - } - - def set_handler(self, key, data): - key = self.normalize_key(key) - vrf, nbr = key.split('|', 1) - if key not in self.peers: - cmd = None - neigmeta = self.directory.get_slot("neigmeta") - if 'name' in data and data["name"] not in neigmeta: - return False - try: - cmd = self.templates["add"].render( - DEVICE_METADATA=self.directory.get_slot("meta"), - DEVICE_NEIGHBOR_METADATA=neigmeta, - neighbor_addr=nbr, - bgp_session=data - ) - except: - syslog.syslog(syslog.LOG_ERR, 'Peer {}. Error in rendering the template for "SET" command {}'.format(key, data)) - return True - if cmd is not None: - rc = self.apply_op(cmd, vrf) - if rc: - self.peers.add(key) - syslog.syslog(syslog.LOG_INFO, 'Peer {} added with attributes {}'.format(key, data)) - else: - syslog.syslog(syslog.LOG_ERR, "Peer {} wasn't added.".format(key)) - else: - # when the peer is already configured we support "shutdown/no shutdown" - # commands for the peers only - if "admin_status" in data: - if data['admin_status'] == 'up': - rc = self.apply_op(self.templates["no shutdown"].render(neighbor_addr=nbr), vrf) - if rc: - syslog.syslog(syslog.LOG_INFO, 'Peer {} admin state is set to "up"'.format(key)) - else: - syslog.syslog(syslog.LOG_ERR, "Peer {} admin state wasn't set to 'up'.".format(key)) - elif data['admin_status'] == 'down': - rc = self.apply_op(self.templates["shutdown"].render(neighbor_addr=nbr), vrf) - if rc: - syslog.syslog(syslog.LOG_INFO, 'Peer {} admin state is set to "down"'.format(key)) - else: - syslog.syslog(syslog.LOG_ERR, "Peer {} admin state wasn't set to 'down'.".format(key)) - else: - syslog.syslog(syslog.LOG_ERR, "Peer {}: Can't update the peer. has wrong attribute value attr['admin_status'] = '{}'".format(key, data['admin_status'])) - else: - syslog.syslog(syslog.LOG_ERR, "Peer {}: Can't update the peer. No 'admin_status' attribute in the request".format(key)) - return True - - def del_handler(self, key): - key = self.normalize_key(key) - vrf, nbr = key.split('|', 1) - if key not in self.peers: - syslog.syslog(syslog.LOG_WARNING, 'Peer {} has not been found'.format(key)) - return - cmd = self.templates["delete"].render(neighbor_addr=nbr) - rc = self.apply_op(cmd, vrf) - if rc: - syslog.syslog(syslog.LOG_INFO, 'Peer {} has been removed'.format(key)) - self.peers.remove(key) - else: - syslog.syslog(syslog.LOG_ERR, "Peer {} hasn't been removed".format(key)) - - def apply_op(self, cmd, vrf): - bgp_asn = self.directory.get_slot("meta")["localhost"]["bgp_asn"] - fd, tmp_filename = tempfile.mkstemp(dir='/tmp') - os.close(fd) - with open(tmp_filename, 'w') as fp: - if vrf == 'default': - fp.write('router bgp %s\n' % bgp_asn) - else: - fp.write('router bgp %s vrf %s\n' % (bgp_asn, vrf)) - fp.write("%s\n" % cmd) - - command = ["vtysh", "-f", tmp_filename] - rc, _, _ = run_command(command) - os.remove(tmp_filename) - return rc == 0 - - @staticmethod - def normalize_key(key): - if '|' not in key: - return 'default|' + key - else: - return key - - @staticmethod - def load_peers(): - vrfs = [] - command = ["vtysh", "-c", "show bgp vrfs json"] - rc, out, err = run_command(command) - if rc == 0: - js_vrf = json.loads(out) - vrfs = js_vrf['vrfs'].keys() - - peers = set() - for vrf in vrfs: - command = ["vtysh", "-c", 'show bgp vrf {} neighbors json'.format(vrf)] - rc, out, err = run_command(command) - if rc == 0: - js_bgp = json.loads(out) - for nbr in js_bgp.keys(): - peers.add((vrf, nbr)) - - return peers - - -def wait_for_bgpd(): - # wait for 20 seconds - stop_time = datetime.datetime.now() + datetime.timedelta(seconds=20) - syslog.syslog(syslog.LOG_INFO, "Start waiting for bgpd: %s" % str(datetime.datetime.now())) - while datetime.datetime.now() < stop_time: - rc, out, err = run_command(["vtysh", "-c", "show daemons"]) - if rc == 0 and "bgpd" in out: - syslog.syslog(syslog.LOG_INFO, "bgpd connected to vtysh: %s" % str(datetime.datetime.now())) - return - time.sleep(0.1) # sleep 100 ms - raise RuntimeError("bgpd hasn't been started in 20 seconds") - - -def main(): - managers = [ - BGPDeviceMetaMgr, - BGPNeighborMetaMgr, - BGPPeerMgr, - ] - wait_for_bgpd() - daemon = Daemon() - directory = Directory() - manager_instanses = [ manager(daemon, directory) for manager in managers ] - daemon.run() - - -def signal_handler(signum, frame): - global g_run - g_run = False - - -if __name__ == '__main__': - rc = 0 - try: - syslog.openlog('bgpcfgd') - signal.signal(signal.SIGTERM, signal_handler) - signal.signal(signal.SIGINT, signal_handler) - main() - except KeyboardInterrupt: - syslog.syslog(syslog.LOG_NOTICE, "Keyboard interrupt") - except RuntimeError as e: - syslog.syslog(syslog.LOG_CRIT, "%s" % str(e)) - rc = -2 - except Exception as e: - syslog.syslog(syslog.LOG_CRIT, "Got an exception %s: Traceback: %s" % (str(e), traceback.format_exc())) - rc = -1 - finally: - syslog.closelog() - try: - sys.exit(rc) - except SystemExit: - os._exit(rc) diff --git a/dockers/docker-fpm-frr/bgpd.conf.default.j2 b/dockers/docker-fpm-frr/bgpd.conf.default.j2 deleted file mode 100644 index e12782b035aa..000000000000 --- a/dockers/docker-fpm-frr/bgpd.conf.default.j2 +++ /dev/null @@ -1,160 +0,0 @@ -! -{% if DEVICE_METADATA['localhost'].has_key('bgp_asn') %} -{% block bgp_init %} -! -! bgp multiple-instance -! -route-map FROM_BGP_SPEAKER_V4 permit 10 -! -route-map TO_BGP_SPEAKER_V4 deny 10 -! -{# generate loopback prefix-lists #} -{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} -{% if prefix | ipv4 and name == 'Loopback0' %} -ip prefix-list PL_LoopbackV4 permit {{ prefix | ip }}/32 -{% elif prefix | ipv6 and name == 'Loopback0' %} -ipv6 prefix-list PL_LoopbackV6 permit {{ prefix | replace('/128', '/64') | ip_network }}/64 -{% endif %} -{% endfor %} -! -{# generate default peer route-maps #} -! -route-map TO_BGP_PEER_V4 permit 100 -! -route-map TO_BGP_PEER_V6 permit 100 -! -{% if BGP_MONITORS is defined and BGP_MONITORS|length > 0 %} -route-map FROM_BGPMON deny 10 -! -route-map TO_BGPMON permit 10 -! -{% endif %} -! -route-map ISOLATE permit 10 - set as-path prepend {{ DEVICE_METADATA['localhost']['bgp_asn'] }} -! -route-map set-next-hop-global-v6 permit 10 - set ipv6 next-hop prefer-global -! -router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} - bgp log-neighbor-changes - bgp bestpath as-path multipath-relax - no bgp default ipv4-unicast - bgp graceful-restart restart-time 240 - bgp graceful-restart -{% if DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} - bgp graceful-restart preserve-fw-state -{% endif %} -{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} -{% if prefix | ipv4 and name == 'Loopback0' %} - bgp router-id {{ prefix | ip }} -{% endif %} -{% endfor %} -{# advertise loopback #} -{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} -{% if prefix | ipv4 and name == 'Loopback0' %} - network {{ prefix | ip }}/32 -{% elif prefix | ipv6 and name == 'Loopback0' %} - address-family ipv6 - network {{ prefix | ip }}/64 - exit-address-family -{% endif %} -{% endfor %} -{% endblock bgp_init %} -{% endif %} -{% block vlan_advertisement %} -{% for (name, prefix) in VLAN_INTERFACE|pfx_filter %} -{% if prefix | ipv4 %} - network {{ prefix }} -{% elif prefix | ipv6 %} - address-family ipv6 - network {{ prefix }} - exit-address-family -{% endif %} -{% endfor %} -{% endblock vlan_advertisement %} -{% block maximum_paths %} - address-family ipv4 - maximum-paths 64 - exit-address-family - address-family ipv6 - maximum-paths 64 - exit-address-family -{% endblock maximum_paths %} -{% block peers_peer_group %} - neighbor PEER_V4 peer-group - neighbor PEER_V6 peer-group - address-family ipv4 -{% if DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} - neighbor PEER_V4 allowas-in 1 -{% endif %} - neighbor PEER_V4 soft-reconfiguration inbound - neighbor PEER_V4 route-map TO_BGP_PEER_V4 out - exit-address-family - address-family ipv6 -{% if DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} - neighbor PEER_V6 allowas-in 1 -{% endif %} - neighbor PEER_V6 soft-reconfiguration inbound - neighbor PEER_V6 route-map TO_BGP_PEER_V6 out - exit-address-family -{% endblock peers_peer_group %} -{% block bgp_peers_with_range %} -{% if BGP_PEER_RANGE %} -{% for bgp_peer in BGP_PEER_RANGE.values() %} - neighbor {{ bgp_peer['name'] }} peer-group - neighbor {{ bgp_peer['name'] }} passive -{% if bgp_peer['peer_asn'] is defined %} - neighbor {{ bgp_peer['name'] }} remote-as {{ bgp_peer['peer_asn'] }} -{% else %} - neighbor {{ bgp_peer['name'] }} remote-as {{ constants.deployment_id_asn_map[DEVICE_METADATA['localhost']['deployment_id']] }} -{% endif %} - neighbor {{ bgp_peer['name'] }} ebgp-multihop 255 - neighbor {{ bgp_peer['name'] }} soft-reconfiguration inbound -{% if bgp_peer['src_address'] is defined %} - neighbor {{ bgp_peer['name'] }} update-source {{ bgp_peer['src_address'] | ip }} -{% else %} -{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} -{% if name == 'Loopback1' %} - neighbor {{ bgp_peer['name'] }} update-source {{ prefix | ip }} -{% endif %} -{% endfor %} -{% endif %} - neighbor {{ bgp_peer['name'] }} route-map FROM_BGP_SPEAKER_V4 in - neighbor {{ bgp_peer['name'] }} route-map TO_BGP_SPEAKER_V4 out -{% for ip_range in bgp_peer['ip_range'] %} - bgp listen range {{ip_range}} peer-group {{ bgp_peer['name'] }} -{% endfor %} - address-family ipv4 - neighbor {{ bgp_peer['name'] }} activate - exit-address-family - address-family ipv6 - neighbor {{ bgp_peer['name'] }} activate - exit-address-family -{% endfor %} -{% endif %} -{% endblock bgp_peers_with_range %} -{% block bgp_monitors %} -{% if BGP_MONITORS is defined and BGP_MONITORS|length > 0 %} - neighbor BGPMON peer-group -{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} -{% if prefix | ipv4 and name == 'Loopback0' %} - neighbor BGPMON update-source {{ prefix | ip }} -{% endif %} -{% endfor %} - neighbor BGPMON route-map FROM_BGPMON in - neighbor BGPMON route-map TO_BGPMON out - neighbor BGPMON send-community - neighbor BGPMON maximum-prefix 1 -{% for neighbor_addr, bgp_session in BGP_MONITORS.items() %} - neighbor {{ neighbor_addr }} remote-as {{ DEVICE_METADATA['localhost']['bgp_asn'] }} - neighbor {{ neighbor_addr }} peer-group BGPMON - neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} - neighbor {{ neighbor_addr }} activate - address-family ipv6 - neighbor {{ neighbor_addr }} activate - exit-address-family -{% endfor %} -{% endif %} -{% endblock bgp_monitors %} -! diff --git a/dockers/docker-fpm-frr/bgpd.conf.j2 b/dockers/docker-fpm-frr/bgpd.conf.j2 deleted file mode 100644 index b4b2cd59c9b9..000000000000 --- a/dockers/docker-fpm-frr/bgpd.conf.j2 +++ /dev/null @@ -1,18 +0,0 @@ -! -{% block banner %} -! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== -! generated by templates/quagga/bgpd.conf.j2 with config DB data -! file: bgpd.conf -! -{% endblock banner %} -! -{% include "daemons.common.conf.j2" %} -! -agentx -! -{% if DEVICE_METADATA['localhost']['type'] == "SpineChassisFrontendRouter" %} -{% include "bgpd.conf.spine_chassis_frontend_router.j2" %} -{% endif %} -! -{% include "bgpd.conf.default.j2" %} -! diff --git a/dockers/docker-fpm-frr/bgpd.conf.spine_chassis_frontend_router.j2 b/dockers/docker-fpm-frr/bgpd.conf.spine_chassis_frontend_router.j2 deleted file mode 100644 index afb621b0bf61..000000000000 --- a/dockers/docker-fpm-frr/bgpd.conf.spine_chassis_frontend_router.j2 +++ /dev/null @@ -1,63 +0,0 @@ -! -{# VNET BGP Instance #} -! Vnet BGP instance -{% set interfaces_in_vnets = [] %} -{% block vnet_bgp_instance %} -{% for vnet_name, vnet_metadata in VNET.iteritems() %} -router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} vrf {{ vnet_name }} - no bgp default ipv4-unicast - bgp log-neighbor-changes - bgp bestpath as-path multipath-relax - no bgp default ipv4-unicast - bgp graceful-restart restart-time 240 - bgp graceful-restart -{# Router ID #} -{% for (name, prefix) in LOOPBACK_INTERFACE | pfx_filter %} -{% if prefix | ipv4 and name == 'Loopback0' %} - bgp router-id {{ prefix | ip }} -{% endif %} -{% endfor %} -{# Got interfaces that belong this vnet #} -{% set interfaces_in_vnet = [] %} -{% for (key, metadata) in INTERFACE.iteritems() %} -{% if metadata.has_key("vnet_name") and metadata["vnet_name"] == vnet_name %} -{% for (name_prefix_pair, metadata) in INTERFACE.iteritems() %} -{% if key == name_prefix_pair[0] %} -{% if interfaces_in_vnet.append( name_prefix_pair[1] | ip ) %} -{% endif %} -{% if interfaces_in_vnets.append( name_prefix_pair[1] | ip ) %} -{% endif %} -{% endif %} -{% endfor %} -{% endif %} -{% endfor %} -{# Each bgp neighbors #} -{% for neighbor_addr, bgp_session in BGP_NEIGHBOR.iteritems() %} -{% if bgp_session.has_key("local_addr") and bgp_session["local_addr"] in interfaces_in_vnet %} -{% if bgp_session['asn'] | int != 0 %} - neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }} - neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} -{# set the bgp neighbor timers if they have not default values #} -{% if (bgp_session['keepalive'] is defined and bgp_session['keepalive'] | int != 60) - or (bgp_session['holdtime'] is defined and bgp_session['holdtime'] | int != 180) %} - neighbor {{ neighbor_addr }} timers {{ bgp_session['keepalive'] }} {{ bgp_session['holdtime'] }} -{% endif %} -{% if bgp_session.has_key('admin_status') and bgp_session['admin_status'] == 'down' or not bgp_session.has_key('admin_status') and DEVICE_METADATA['localhost'].has_key('default_bgp_status') and DEVICE_METADATA['localhost']['default_bgp_status'] == 'down' %} - neighbor {{ neighbor_addr }} shutdown -{% endif %} -{% if neighbor_addr | ipv4 %} - address-family ipv4 unicast - neighbor {{ neighbor_addr }} activate - neighbor {{ neighbor_addr }} soft-reconfiguration inbound - maximum-paths 64 - exit-address-family -{% endif %} - address-family l2vpn evpn - advertise ipv4 unicast - exit-address-family -{% endif %} -{% endif %} -{% endfor %} -{% endfor %} -{% endblock vnet_bgp_instance %} -! diff --git a/dockers/docker-fpm-frr/bgpd.peer.conf.j2 b/dockers/docker-fpm-frr/bgpd.peer.conf.j2 deleted file mode 100644 index c3dc50449d35..000000000000 --- a/dockers/docker-fpm-frr/bgpd.peer.conf.j2 +++ /dev/null @@ -1,38 +0,0 @@ -{% block bgp_peer %} - neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }} - neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} -{# set the bgp neighbor timers if they have not default values #} -{% if (bgp_session['keepalive'] is defined and bgp_session['keepalive'] | int != 60) - or (bgp_session['holdtime'] is defined and bgp_session['holdtime'] | int != 180) %} - neighbor {{ neighbor_addr }} timers {{ bgp_session['keepalive'] }} {{ bgp_session['holdtime'] }} -{% endif %} -{% if bgp_session.has_key('admin_status') and bgp_session['admin_status'] == 'down' or not bgp_session.has_key('admin_status') and DEVICE_METADATA['localhost'].has_key('default_bgp_status') and DEVICE_METADATA['localhost']['default_bgp_status'] == 'down' %} - neighbor {{ neighbor_addr }} shutdown -{% endif %} -{% if neighbor_addr | ipv4 %} - address-family ipv4 - neighbor {{ neighbor_addr }} peer-group PEER_V4 -{% elif neighbor_addr | ipv6 %} - address-family ipv6 -{% if bgp_session['asn'] != DEVICE_METADATA['localhost']['bgp_asn'] %} - neighbor {{ neighbor_addr }} route-map set-next-hop-global-v6 in -{% endif %} - neighbor {{ neighbor_addr }} peer-group PEER_V6 -{% endif %} -{% if bgp_session['rrclient'] | int != 0 %} - neighbor {{ neighbor_addr }} route-reflector-client -{% endif %} -{% if bgp_session['nhopself'] | int != 0 %} - 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) %} - address-family l2vpn evpn - neighbor {{ neighbor_addr }} activate - advertise-all-vni - exit-address-family -{% endif %} - neighbor {{ neighbor_addr }} activate - exit-address-family -{% endblock bgp_peer %} diff --git a/dockers/docker-fpm-frr/bgpd.tsa.isolate.conf.j2 b/dockers/docker-fpm-frr/bgpd.tsa.isolate.conf.j2 deleted file mode 100644 index 9cd61b899071..000000000000 --- a/dockers/docker-fpm-frr/bgpd.tsa.isolate.conf.j2 +++ /dev/null @@ -1,10 +0,0 @@ -route-map TO_BGP_PEER_V4 permit 2 - match ip address prefix-list PL_LoopbackV4 - set community {{ constants.traffic_shift_community }} -route-map TO_BGP_PEER_V4 deny 3 -! -route-map TO_BGP_PEER_V6 permit 2 - match ipv6 address prefix-list PL_LoopbackV6 - set community {{ constants.traffic_shift_community }} -route-map TO_BGP_PEER_V6 deny 3 -! diff --git a/dockers/docker-fpm-frr/bgpd.tsa.unisolate.conf.j2 b/dockers/docker-fpm-frr/bgpd.tsa.unisolate.conf.j2 deleted file mode 100644 index 25d7c49125e1..000000000000 --- a/dockers/docker-fpm-frr/bgpd.tsa.unisolate.conf.j2 +++ /dev/null @@ -1,6 +0,0 @@ -no route-map TO_BGP_PEER_V4 permit 2 -no route-map TO_BGP_PEER_V4 deny 3 -! -no route-map TO_BGP_PEER_V6 permit 2 -no route-map TO_BGP_PEER_V6 deny 3 -! diff --git a/dockers/docker-fpm-frr/critical_processes b/dockers/docker-fpm-frr/critical_processes deleted file mode 100644 index 8ea09e1bb538..000000000000 --- a/dockers/docker-fpm-frr/critical_processes +++ /dev/null @@ -1,5 +0,0 @@ -zebra -staticd -bgpd -fpmsyncd -bgpcfgd diff --git a/dockers/docker-fpm-frr/daemons.common.conf.j2 b/dockers/docker-fpm-frr/daemons.common.conf.j2 deleted file mode 100644 index 23eb5184f5e0..000000000000 --- a/dockers/docker-fpm-frr/daemons.common.conf.j2 +++ /dev/null @@ -1,12 +0,0 @@ -! -{% block sys_init %} -hostname {{ DEVICE_METADATA['localhost']['hostname'] }} -password zebra -enable password zebra -{% endblock sys_init %} -! -{% block logging %} -log syslog informational -log facility local4 -{% endblock logging %} -! diff --git a/dockers/docker-fpm-frr/docker_init.sh b/dockers/docker-fpm-frr/docker_init.sh new file mode 100755 index 000000000000..96149de4c379 --- /dev/null +++ b/dockers/docker-fpm-frr/docker_init.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env bash + +mkdir -p /etc/frr +mkdir -p /etc/supervisor/conf.d + +CFGGEN_PARAMS=" \ + -d \ + -y /etc/sonic/constants.yml \ + -t /usr/share/sonic/templates/frr_vars.j2 \ + -t /usr/share/sonic/templates/supervisord/supervisord.conf.j2,/etc/supervisor/conf.d/supervisord.conf \ + -t /usr/share/sonic/templates/bgpd/gen_bgpd.conf.j2,/etc/frr/bgpd.conf \ + -t /usr/share/sonic/templates/supervisord/critical_processes.j2,/etc/supervisor/critical_processes \ + -t /usr/share/sonic/templates/zebra/zebra.conf.j2,/etc/frr/zebra.conf \ + -t /usr/share/sonic/templates/staticd/gen_staticd.conf.j2,/etc/frr/staticd.conf \ + -t /usr/share/sonic/templates/gen_frr.conf.j2,/etc/frr/frr.conf \ + -t /usr/share/sonic/templates/isolate.j2,/usr/sbin/bgp-isolate \ + -t /usr/share/sonic/templates/unisolate.j2,/usr/sbin/bgp-unisolate \ + -t /usr/local/sonic/frrcfgd/bfdd.conf.j2,/etc/frr/bfdd.conf \ + -t /usr/local/sonic/frrcfgd/ospfd.conf.j2,/etc/frr/ospfd.conf \ +" + +FRR_VARS=$(sonic-cfggen $CFGGEN_PARAMS) +MGMT_FRAMEWORK_CONFIG=$(echo $FRR_VARS | jq -r '.frr_mgmt_framework_config') +CONFIG_TYPE=$(echo $FRR_VARS | jq -r '.docker_routing_config_mode') +if [ -z "$MGMT_FRAMEWORK_CONFIG" ] || [ "$MGMT_FRAMEWORK_CONFIG" == "false" ]; then + rm /etc/frr/bfdd.conf /etc/frr/ospfd.conf +fi + +update_default_gw() +{ + IP_VER=${1} + # FRR is not running in host namespace so we need to delete + # default gw kernel route added by docker network via eth0 and add it back + # with higher administrative distance so that default route learnt + # by FRR becomes best route if/when available + GATEWAY_IP=$(ip -${IP_VER} route show default dev eth0 | awk '{print $3}') + #Check if docker default route is there + if [[ ! -z "$GATEWAY_IP" ]]; then + ip -${IP_VER} route del default dev eth0 + #Make sure route is deleted + CHECK_GATEWAY_IP=$(ip -${IP_VER} route show default dev eth0 | awk '{print $3}') + if [[ -z "$CHECK_GATEWAY_IP" ]]; then + # Ref: http://docs.frrouting.org/en/latest/zebra.html#zebra-vrf + # Zebra does treat Kernel routes as special case for the purposes of Admin Distance. \ + # Upon learning about a route that is not originated by FRR we read the metric value as a uint32_t. + # The top byte of the value is interpreted as the Administrative Distance and + # the low three bytes are read in as the metric. + # so here we are programming administrative distance of 210 (210 << 24) > 200 (for routes learnt via IBGP) + ip -${IP_VER} route add default via $GATEWAY_IP dev eth0 metric 3523215360 + fi + fi +} + +if [[ ! -z "$NAMESPACE_ID" ]]; then + update_default_gw 4 + update_default_gw 6 +fi + +if [ -z "$CONFIG_TYPE" ] || [ "$CONFIG_TYPE" == "separated" ]; then + echo "no service integrated-vtysh-config" > /etc/frr/vtysh.conf + rm -f /etc/frr/frr.conf +elif [ "$CONFIG_TYPE" == "unified" ]; then + echo "service integrated-vtysh-config" > /etc/frr/vtysh.conf + rm -f /etc/frr/bgpd.conf /etc/frr/zebra.conf /etc/frr/staticd.conf \ + /etc/frr/bfdd.conf /etc/frr/ospfd.conf /etc/frr/pimd.conf +fi + +chown -R frr:frr /etc/frr/ + +chown root:root /usr/sbin/bgp-isolate +chmod 0755 /usr/sbin/bgp-isolate + +chown root:root /usr/sbin/bgp-unisolate +chmod 0755 /usr/sbin/bgp-unisolate + +mkdir -p /var/sonic +echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status + +exec /usr/local/bin/supervisord diff --git a/dockers/docker-fpm-frr/frr.conf.j2 b/dockers/docker-fpm-frr/frr.conf.j2 deleted file mode 100644 index afa40ad8ba75..000000000000 --- a/dockers/docker-fpm-frr/frr.conf.j2 +++ /dev/null @@ -1,18 +0,0 @@ -! -{% block banner %} -! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== -! generated by templates/frr/frr.conf.j2 with config DB data -! file: frr.conf -! -{% endblock banner %} -! -{% include "daemons.common.conf.j2" %} -! -agentx -! -{% include "zebra.interfaces.conf.j2" %} -! -{% include "staticd.default_route.conf.j2" %} -! -{% include "bgpd.conf.default.j2" %} -! diff --git a/dockers/docker-fpm-frr/frr/bgpd/bgpd.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/bgpd.conf.j2 new file mode 100644 index 000000000000..85182e5430e8 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/bgpd.conf.j2 @@ -0,0 +1,24 @@ +! +! template: bgpd/bgpd.conf.j2 +! +{% from "common/functions.conf.j2" import get_ipv4_loopback_address, get_ipv6_loopback_address %} +! +{% block banner %} +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/quagga/bgpd.conf.j2 with config DB data +! file: bgpd.conf +! +{% endblock banner %} +! +{% include "common/daemons.common.conf.j2" %} +! +agentx +! +{% if DEVICE_METADATA['localhost']['type'] == "SpineChassisFrontendRouter" %} +{% include "bgpd.spine_chassis_frontend_router.conf.j2" %} +{% endif %} +! +{% include "bgpd.main.conf.j2" %} +! +! end of template: bgpd/bgpd.conf.j2 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 new file mode 100644 index 000000000000..9568d4821547 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 @@ -0,0 +1,117 @@ +{% from "common/functions.conf.j2" import get_ipv4_loopback_address, get_ipv6_loopback_address, get_vnet_interfaces %} +! +! template: bgpd/bgpd.main.conf.j2 +! +! bgp multiple-instance +! +! BGP configuration +! +! TSA configuration +! +ip prefix-list PL_LoopbackV4 permit {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }}/32 +! +{% if get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback0") != 'None' %} +ipv6 prefix-list PL_LoopbackV6 permit {{ get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | replace('/128', '/64') | ip_network }}/64 +{% endif %} +! +{% if VLAN_INTERFACE is defined %} +{% set vnet_intfs = get_vnet_interfaces(VLAN_INTERFACE) %} +{% endif %} +{% for (name, prefix) in VLAN_INTERFACE|pfx_filter %} +{% if prefix | ipv4 and name not in vnet_intfs %} +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq {{ loop.index * 5 }} permit {{ prefix | ip_network }}/{{ prefix | prefixlen }} +! +{% endif %} +{% endfor %} +{% for (name, prefix) in VLAN_INTERFACE|pfx_filter %} +{% if prefix | ipv6 and name not in vnet_intfs %} +ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq {{ loop.index * 5 }} permit {{ prefix | ip_network }}/{{ prefix | prefixlen }} +! +{% endif %} +{% endfor %} +! +{% if DEVICE_METADATA['localhost']['sub_role'] == 'FrontEnd' or DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} +route-map HIDE_INTERNAL permit 10 + set community local-AS +! +{% endif %} +! +router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} +! +{% block bgp_init %} + bgp log-neighbor-changes + no bgp default ipv4-unicast + no bgp ebgp-requires-policy +! +{% if constants.bgp.multipath_relax.enabled is defined and constants.bgp.multipath_relax.enabled %} + bgp bestpath as-path multipath-relax +{% endif %} +! +{% if constants.bgp.graceful_restart.enabled is defined and constants.bgp.graceful_restart.enabled %} + bgp graceful-restart restart-time {{ constants.bgp.graceful_restart.restart_time | default(240) }} + bgp graceful-restart + bgp graceful-restart preserve-fw-state +{% endif %} +! +{# set router-id #} +{% if multi_asic() %} + bgp router-id {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback4096") | ip }} +{% else %} + bgp router-id {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }} +{% endif %} +! +{# advertise loopback #} + network {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }}/32 +{% if multi_asic() %} + network {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback4096") | ip }}/32 route-map HIDE_INTERNAL +{% endif %} +! +{% if get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback0") != 'None' %} + address-family ipv6 + network {{ get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }}/64 + exit-address-family +{% endif %} +{% if multi_asic() %} +{% if get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback4096") != 'None' %} + address-family ipv6 + network {{ get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback4096") | ip }}/64 route-map HIDE_INTERNAL + exit-address-family +{% endif %} +{% endif %} +{% endblock bgp_init %} +! +{% block vlan_advertisement %} +{% for (name, prefix) in VLAN_INTERFACE|pfx_filter %} +{% if prefix | ipv4 and name not in vnet_intfs %} + network {{ prefix }} +{% elif prefix | ipv6 and name not in vnet_intfs %} + address-family ipv6 + network {{ prefix }} + exit-address-family +{% endif %} +{% endfor %} +{% endblock vlan_advertisement %} +! +! +{% if DEVICE_METADATA['localhost']['sub_role'] == 'FrontEnd' %} + address-family ipv4 + redistribute connected route-map HIDE_INTERNAL + exit-address-family + address-family ipv6 + redistribute connected route-map HIDE_INTERNAL + exit-address-family +{% endif %} +! +{% if constants.bgp.maximum_paths.enabled is defined and constants.bgp.maximum_paths.enabled %} +{% block maximum_paths %} + address-family ipv4 + maximum-paths {{ constants.bgp.maximum_paths.ipv4 | default(64) }} + exit-address-family + address-family ipv6 + maximum-paths {{ constants.bgp.maximum_paths.ipv6 | default(64) }} + exit-address-family +{% endblock maximum_paths %} +{% endif %} +! +! end of template: bgpd/bgpd.main.conf.j2 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/bgpd.spine_chassis_frontend_router.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/bgpd.spine_chassis_frontend_router.conf.j2 new file mode 100644 index 000000000000..94dacbc3af78 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/bgpd.spine_chassis_frontend_router.conf.j2 @@ -0,0 +1,63 @@ +! +{# VNET BGP Instance #} +! Vnet BGP instance +{% set interfaces_in_vnets = [] %} +{% block vnet_bgp_instance %} +{% for vnet_name, vnet_metadata in VNET.items() %} +router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} vrf {{ vnet_name }} + no bgp default ipv4-unicast + bgp log-neighbor-changes + bgp bestpath as-path multipath-relax + no bgp default ipv4-unicast + bgp graceful-restart restart-time 240 + bgp graceful-restart +{# Router ID #} +{% for (name, prefix) in LOOPBACK_INTERFACE | pfx_filter %} +{% if prefix | ipv4 and name == 'Loopback0' %} + bgp router-id {{ prefix | ip }} +{% endif %} +{% endfor %} +{# Got interfaces that belong this vnet #} +{% set interfaces_in_vnet = [] %} +{% for (key, metadata) in INTERFACE.items() %} +{% if "vnet_name" in metadata and metadata["vnet_name"] == vnet_name %} +{% for (name_prefix_pair, metadata) in INTERFACE.items() %} +{% if key == name_prefix_pair[0] %} +{% if interfaces_in_vnet.append( name_prefix_pair[1] | ip ) %} +{% endif %} +{% if interfaces_in_vnets.append( name_prefix_pair[1] | ip ) %} +{% endif %} +{% endif %} +{% endfor %} +{% endif %} +{% endfor %} +{# Each bgp neighbors #} +{% for neighbor_addr, bgp_session in BGP_NEIGHBOR.items() %} +{% if "local_addr" in bgp_session and bgp_session["local_addr"] in interfaces_in_vnet %} +{% if bgp_session['asn'] | int != 0 %} + neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }} + neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} +{# set the bgp neighbor timers if they have not default values #} +{% if (bgp_session['keepalive'] is defined and bgp_session['keepalive'] | int != 60) + or (bgp_session['holdtime'] is defined and bgp_session['holdtime'] | int != 180) %} + neighbor {{ neighbor_addr }} timers {{ bgp_session['keepalive'] }} {{ bgp_session['holdtime'] }} +{% endif %} +{% if 'admin_status' in bgp_session and bgp_session['admin_status'] == 'down' or 'admin_status' not in bgp_session and 'default_bgp_status' in DEVICE_METADATA['localhost'] and DEVICE_METADATA['localhost']['default_bgp_status'] == 'down' %} + neighbor {{ neighbor_addr }} shutdown +{% endif %} +{% if neighbor_addr | ipv4 %} + address-family ipv4 unicast + neighbor {{ neighbor_addr }} activate + neighbor {{ neighbor_addr }} soft-reconfiguration inbound + maximum-paths 64 + exit-address-family +{% endif %} + address-family l2vpn evpn + advertise ipv4 unicast + exit-address-family +{% endif %} +{% endif %} +{% endfor %} +{% endfor %} +{% endblock vnet_bgp_instance %} +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/gen_bgpd.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/gen_bgpd.conf.j2 new file mode 100644 index 000000000000..bb6d7f6a5a65 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/gen_bgpd.conf.j2 @@ -0,0 +1,5 @@ +{% if DEVICE_METADATA.localhost.frr_mgmt_framework_config is defined and DEVICE_METADATA.localhost.frr_mgmt_framework_config == "true" %} + {% include "/usr/local/sonic/frrcfgd/bgpd.conf.j2" %} +{% else %} + {% include "/usr/share/sonic/templates/bgpd/bgpd.conf.j2" %} +{% endif %} diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/instance.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/instance.conf.j2 new file mode 100644 index 000000000000..5082b75005c2 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/instance.conf.j2 @@ -0,0 +1,38 @@ +! +! template: bgpd/templates/dynamic/instance.conf.j2 +! +{% from "common/functions.conf.j2" import get_ipv4_loopback_address %} +! + neighbor {{ bgp_session['name'] }} peer-group + neighbor {{ bgp_session['name'] }} passive + neighbor {{ bgp_session['name'] }} ebgp-multihop 255 + neighbor {{ bgp_session['name'] }} soft-reconfiguration inbound + neighbor {{ bgp_session['name'] }} route-map FROM_BGP_SPEAKER in + neighbor {{ bgp_session['name'] }} route-map TO_BGP_SPEAKER out +! +{% if bgp_session['peer_asn'] is defined %} + neighbor {{ bgp_session['name'] }} remote-as {{ bgp_session['peer_asn'] }} +{% else %} + neighbor {{ bgp_session['name'] }} remote-as {{ constants.deployment_id_asn_map[CONFIG_DB__DEVICE_METADATA['localhost']['deployment_id']] }} +{% endif %} +! +{# FIXME: bgp_session['ip_range'] check the type #} +{% for ip_range in bgp_session['ip_range'].split(',') %} + bgp listen range {{ ip_range }} peer-group {{ bgp_session['name'] }} +{% endfor %} +! +{% if bgp_session['src_address'] is defined %} + neighbor {{ bgp_session['name'] }} update-source {{ bgp_session['src_address'] | ip }} +{% else %} + neighbor {{ bgp_session['name'] }} update-source {{ get_ipv4_loopback_address(CONFIG_DB__LOOPBACK_INTERFACE, "Loopback1") | ip }} +{% endif %} +! + address-family ipv4 + neighbor {{ bgp_session['name'] }} activate + exit-address-family + address-family ipv6 + neighbor {{ bgp_session['name'] }} activate + exit-address-family +! +! end of template: bgpd/templates/dynamic/instance.conf.j2 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/peer-group.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/peer-group.conf.j2 new file mode 100644 index 000000000000..86d5c0297227 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/peer-group.conf.j2 @@ -0,0 +1,7 @@ +! +! template: bgpd/templates/BGP_SPEAKER/peer-group.conf.j2 +! +! nothing is here +! +! end of template: bgpd/templates/BGP_SPEAKER/peer-group.conf.j2 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/policies.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/policies.conf.j2 new file mode 100644 index 000000000000..17ca09ec2a36 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/policies.conf.j2 @@ -0,0 +1,9 @@ +! +! template: bgpd/templates/BGP_SPEAKER/policies.conf.j2 +! +route-map FROM_BGP_SPEAKER permit 10 +! +route-map TO_BGP_SPEAKER deny 1 +! +! end of template: bgpd/templates/BGP_SPEAKER/policies.conf.j2 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/general/instance.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/general/instance.conf.j2 new file mode 100644 index 000000000000..c8c9906bc98d --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/instance.conf.j2 @@ -0,0 +1,45 @@ +! +! template: bgpd/templates/general/instance.conf.j2 +! + neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }} + neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} +{# set the bgp neighbor timers if they have not default values #} +{% if (bgp_session['keepalive'] is defined and bgp_session['keepalive'] | int != 60) + or (bgp_session['holdtime'] is defined and bgp_session['holdtime'] | int != 180) %} + neighbor {{ neighbor_addr }} timers {{ bgp_session['keepalive'] | default("60") }} {{ bgp_session['holdtime'] | default("180") }} +{% endif %} +! +{% if 'admin_status' in bgp_session and bgp_session['admin_status'] == 'down' or 'admin_status' not in bgp_session and 'default_bgp_status' in CONFIG_DB__DEVICE_METADATA['localhost'] and CONFIG_DB__DEVICE_METADATA['localhost']['default_bgp_status'] == 'down' %} + neighbor {{ neighbor_addr }} shutdown +{% endif %} +! +{% if neighbor_addr | ipv4 %} + address-family ipv4 + neighbor {{ neighbor_addr }} peer-group PEER_V4 +! +{% elif neighbor_addr | ipv6 %} + address-family ipv6 + neighbor {{ neighbor_addr }} peer-group PEER_V6 +! +{% endif %} +! +{% if 'rrclient' in bgp_session and bgp_session['rrclient'] | int != 0 %} + neighbor {{ neighbor_addr }} route-reflector-client +{% endif %} +! +{% if 'nhopself' in bgp_session and bgp_session['nhopself'] | int != 0 %} + neighbor {{ neighbor_addr }} next-hop-self +{% endif %} +! + neighbor {{ neighbor_addr }} activate + exit-address-family +! +{% if bgp_session["asn"] == bgp_asn and CONFIG_DB__DEVICE_METADATA['localhost']['type'] == "SpineChassisFrontendRouter" %} + address-family l2vpn evpn + neighbor {{ neighbor_addr }} activate + advertise-all-vni + exit-address-family +{% endif %} +! +! end of template: bgpd/templates/general/instance.conf.j2 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 new file mode 100644 index 000000000000..2617cc94c2d2 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 @@ -0,0 +1,32 @@ +! +! template: bgpd/templates/general/peer-group.conf.j2 +! + neighbor PEER_V4 peer-group + neighbor PEER_V6 peer-group + address-family ipv4 +{% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} + neighbor PEER_V4 allowas-in 1 +{% elif CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'LeafRouter' %} +{% if CONFIG_DB__BGP_BBR['status'] == 'enabled' %} + neighbor PEER_V4 allowas-in 1 +{% endif %} +{% endif %} + neighbor PEER_V4 soft-reconfiguration inbound + neighbor PEER_V4 route-map FROM_BGP_PEER_V4 in + neighbor PEER_V4 route-map TO_BGP_PEER_V4 out + exit-address-family + address-family ipv6 +{% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} + neighbor PEER_V6 allowas-in 1 +{% elif CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'LeafRouter' %} +{% if CONFIG_DB__BGP_BBR['status'] == 'enabled' %} + neighbor PEER_V6 allowas-in 1 +{% endif %} +{% endif %} + neighbor PEER_V6 soft-reconfiguration inbound + neighbor PEER_V6 route-map FROM_BGP_PEER_V6 in + neighbor PEER_V6 route-map TO_BGP_PEER_V6 out + exit-address-family +! +! end of template: bgpd/templates/general/peer-group.conf.j2 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 new file mode 100644 index 000000000000..7cf5e148f694 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 @@ -0,0 +1,64 @@ +! +! template: bgpd/templates/general/policies.conf.j2 +! +! +! +{% if constants.bgp.allow_list is defined and constants.bgp.allow_list.enabled is defined and constants.bgp.allow_list.enabled and constants.bgp.allow_list.drop_community is defined %} +! +! +! please don't remove. 65535 entries are default rules +! which works when allow_list is enabled, but new configuration +! is not applied +! +{% if allow_list_default_action == 'deny' %} +! +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535 + set community no-export additive +! +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535 + set community no-export additive +{% else %} +! +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535 + set community {{ constants.bgp.allow_list.drop_community }} additive +! +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535 + set community {{ constants.bgp.allow_list.drop_community }} additive +{% endif %} +! +bgp community-list standard allow_list_default_community permit no-export +bgp community-list standard allow_list_default_community permit {{ constants.bgp.allow_list.drop_community }} +! +route-map FROM_BGP_PEER_V4 permit 10 + call ALLOW_LIST_DEPLOYMENT_ID_0_V4 + on-match next +! +route-map FROM_BGP_PEER_V4 permit 11 + match community allow_list_default_community +! +route-map FROM_BGP_PEER_V6 permit 10 + call ALLOW_LIST_DEPLOYMENT_ID_0_V6 + on-match next +! +route-map FROM_BGP_PEER_V6 permit 11 + match community allow_list_default_community +! +{% endif %} +! +! +! +route-map FROM_BGP_PEER_V4 permit 100 +! +route-map TO_BGP_PEER_V4 permit 100 +! +! +route-map FROM_BGP_PEER_V6 permit 1 + on-match next + set ipv6 next-hop prefer-global +! +route-map FROM_BGP_PEER_V6 permit 100 +! +route-map TO_BGP_PEER_V6 permit 100 +! +! end of template: bgpd/templates/general/policies.conf.j2 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/internal/instance.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/internal/instance.conf.j2 new file mode 100644 index 000000000000..e0e23b7f60c8 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/internal/instance.conf.j2 @@ -0,0 +1,35 @@ +! +! template: bgpd/templates/internal/instance.conf.j2 +! + neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }} + neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} + neighbor {{ neighbor_addr }} timers 3 10 +! +{% if neighbor_addr | ipv4 %} + address-family ipv4 + neighbor {{ neighbor_addr }} peer-group INTERNAL_PEER_V4 +! +{% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} + neighbor {{ neighbor_addr }} route-map FROM_BGP_INTERNAL_PEER_V4 in +{% endif %} +! +{% elif neighbor_addr | ipv6 %} + address-family ipv6 + neighbor {{ neighbor_addr }} peer-group INTERNAL_PEER_V6 +! +{% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} + neighbor {{ neighbor_addr }} route-map FROM_BGP_INTERNAL_PEER_V6 in +{% endif %} +{% endif %} +! +{% if 'rrclient' in bgp_session and bgp_session['rrclient'] | int != 0 %} + neighbor {{ neighbor_addr }} route-reflector-client +{% endif %} +! + neighbor {{ neighbor_addr }} next-hop-self force +! + neighbor {{ neighbor_addr }} activate + exit-address-family +! +! end of template: bgpd/templates/internal/instance.conf.j2 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/internal/peer-group.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/internal/peer-group.conf.j2 new file mode 100644 index 000000000000..323c13447ed0 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/internal/peer-group.conf.j2 @@ -0,0 +1,24 @@ +! +! template: bgpd/templates/internal/peer-group.conf.j2 +! + neighbor INTERNAL_PEER_V4 peer-group + neighbor INTERNAL_PEER_V6 peer-group + address-family ipv4 +{% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} + neighbor INTERNAL_PEER_V4 route-reflector-client +{% endif %} + neighbor INTERNAL_PEER_V4 soft-reconfiguration inbound + neighbor INTERNAL_PEER_V4 route-map FROM_BGP_INTERNAL_PEER_V4 in + neighbor INTERNAL_PEER_V4 route-map TO_BGP_INTERNAL_PEER_V4 out + exit-address-family + address-family ipv6 +{% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} + neighbor INTERNAL_PEER_V6 route-reflector-client +{% endif %} + neighbor INTERNAL_PEER_V6 soft-reconfiguration inbound + neighbor INTERNAL_PEER_V6 route-map FROM_BGP_INTERNAL_PEER_V6 in + neighbor INTERNAL_PEER_V6 route-map TO_BGP_INTERNAL_PEER_V6 out + exit-address-family +! +! end of template: bgpd/templates/internal/peer-group.conf.j2 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/internal/policies.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/internal/policies.conf.j2 new file mode 100644 index 000000000000..81d3b0041179 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/internal/policies.conf.j2 @@ -0,0 +1,28 @@ +! +! template: bgpd/templates/internal/policies.conf.j2 +! +! +! +route-map FROM_BGP_INTERNAL_PEER_V4 permit 100 +! +route-map TO_BGP_INTERNAL_PEER_V4 permit 100 +! +! +route-map FROM_BGP_INTERNAL_PEER_V6 permit 1 + on-match next + set ipv6 next-hop prefer-global +! +route-map FROM_BGP_INTERNAL_PEER_V6 permit 100 +! +route-map TO_BGP_INTERNAL_PEER_V6 permit 100 +! +{% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} +route-map FROM_BGP_INTERNAL_PEER_V4 permit 2 + set originator-id {{ loopback0_ipv4 | ip }} +! +route-map FROM_BGP_INTERNAL_PEER_V6 permit 2 + set originator-id {{ loopback0_ipv4 | ip }} +{% endif %} +! +! end of template: bgpd/templates/internal/policies.conf.j2 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/monitors/instance.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/monitors/instance.conf.j2 new file mode 100644 index 000000000000..0aa22a3a7f87 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/monitors/instance.conf.j2 @@ -0,0 +1,13 @@ +! +! template: bgpd/templates/monitors/instance.conf.j2 +! + neighbor {{ neighbor_addr }} remote-as {{ bgp_asn }} + neighbor {{ neighbor_addr }} peer-group BGPMON + neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} + neighbor {{ neighbor_addr }} activate + address-family ipv6 + neighbor {{ neighbor_addr }} activate + exit-address-family +! +! end of template: bgpd/templates/BGPMON/instance.conf.j2 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/monitors/peer-group.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/monitors/peer-group.conf.j2 new file mode 100644 index 000000000000..a36278619015 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/monitors/peer-group.conf.j2 @@ -0,0 +1,12 @@ +! +! template: bgpd/templates/BGPMON/peer-group.conf.j2 +! + neighbor BGPMON peer-group + neighbor BGPMON update-source {{ loopback0_ipv4 | ip }} + neighbor BGPMON route-map FROM_BGPMON in + neighbor BGPMON route-map TO_BGPMON out + neighbor BGPMON send-community + neighbor BGPMON maximum-prefix 1 +! +! end of template: bgpd/templates/BGPMON/peer-group.conf.j2 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/monitors/policies.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/monitors/policies.conf.j2 new file mode 100644 index 000000000000..8d53991064de --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/monitors/policies.conf.j2 @@ -0,0 +1,9 @@ +! +! template: bgpd/templates/BGPMON/policies.conf.j2 +! +route-map FROM_BGPMON deny 10 +! +route-map TO_BGPMON permit 10 +! +! end of template: bgpd/templates/BGPMON/policies.conf.j2 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/tsa/bgpd.tsa.isolate.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/tsa/bgpd.tsa.isolate.conf.j2 new file mode 100644 index 000000000000..1256d1cd4f96 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/tsa/bgpd.tsa.isolate.conf.j2 @@ -0,0 +1,5 @@ +route-map {{ route_map_name }} permit 20 + match {{ ip_protocol }} address prefix-list PL_Loopback{{ ip_version }} + set community {{ constants.bgp.traffic_shift_community }} +route-map {{ route_map_name }} deny 30 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/tsa/bgpd.tsa.unisolate.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/tsa/bgpd.tsa.unisolate.conf.j2 new file mode 100644 index 000000000000..649f6d8e9db8 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/tsa/bgpd.tsa.unisolate.conf.j2 @@ -0,0 +1,3 @@ +no route-map {{ route_map_name }} permit 20 +no route-map {{ route_map_name }} deny 30 +! diff --git a/dockers/docker-fpm-frr/frr/common/daemons.common.conf.j2 b/dockers/docker-fpm-frr/frr/common/daemons.common.conf.j2 new file mode 100644 index 000000000000..1c3efdfa72fb --- /dev/null +++ b/dockers/docker-fpm-frr/frr/common/daemons.common.conf.j2 @@ -0,0 +1,14 @@ +! template: common/daemons.common.conf.j2 +! +{% block sys_init %} +hostname {{ DEVICE_METADATA['localhost']['hostname'] }} +password zebra +enable password zebra +{% endblock sys_init %} +! +{% block logging %} +log syslog informational +log facility local4 +{% endblock logging %} +! +! end of template: common/daemons.common.conf.j2 diff --git a/dockers/docker-fpm-frr/frr/common/functions.conf.j2 b/dockers/docker-fpm-frr/frr/common/functions.conf.j2 new file mode 100644 index 000000000000..34700db329ca --- /dev/null +++ b/dockers/docker-fpm-frr/frr/common/functions.conf.j2 @@ -0,0 +1,35 @@ +{% macro get_ipv4_loopback_address(interfaces, loopbackname) -%} +{% set L = namespace(ip=None) %} +{% for name, prefix in interfaces|pfx_filter %} +{% if name == loopbackname %} +{% if prefix | ipv4 %} +{% set L.ip = prefix %} +{% endif %} +{% endif %} +{% endfor %} +{{ L.ip }} +{%- endmacro %} + +{% macro get_ipv6_loopback_address(interfaces, loopbackname) -%} +{% set L = namespace(ip=None) %} +{% for name, prefix in interfaces|pfx_filter %} +{% if name == loopbackname %} +{% if prefix | ipv6 %} +{% set L.ip = prefix %} +{% endif %} +{% endif %} +{% endfor %} +{{ L.ip }} +{%- endmacro %} + +{% macro get_vnet_interfaces(interfaces) -%} +{% set L = namespace(intfs=[]) %} +{% set vnet_intfs = [] %} +{% for (key, metadata) in interfaces.items() %} +{% if "vnet_name" in metadata %} +{% set vnet_intfs = vnet_intfs.append(key) %} +{% endif %} +{% endfor %} +{% set L.intfs = vnet_intfs %} +{{ L.intfs }} +{%- endmacro %} diff --git a/dockers/docker-fpm-frr/frr/frr.conf.j2 b/dockers/docker-fpm-frr/frr/frr.conf.j2 new file mode 100644 index 000000000000..99900790366c --- /dev/null +++ b/dockers/docker-fpm-frr/frr/frr.conf.j2 @@ -0,0 +1,21 @@ +! +{% block banner %} +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/frr.conf.j2 with config DB data +! file: frr.conf +! +{% endblock banner %} +! +{% include "common/daemons.common.conf.j2" %} +{% from "common/functions.conf.j2" import get_ipv4_loopback_address, get_ipv6_loopback_address %} +! +agentx +! +{% include "zebra/zebra.interfaces.conf.j2" %} +! +{% include "staticd/staticd.default_route.conf.j2" %} +! +{% include "staticd/staticd.loopback_route.conf.j2" %} +! +{% include "bgpd/bgpd.main.conf.j2" %} +! diff --git a/dockers/docker-fpm-frr/frr/frr_vars.j2 b/dockers/docker-fpm-frr/frr/frr_vars.j2 new file mode 100644 index 000000000000..662608a1fd8b --- /dev/null +++ b/dockers/docker-fpm-frr/frr/frr_vars.j2 @@ -0,0 +1,14 @@ +{ + "frr_mgmt_framework_config": + {% if "frr_mgmt_framework_config" in DEVICE_METADATA["localhost"].keys() %} + "{{ DEVICE_METADATA["localhost"]["frr_mgmt_framework_config"] }}" + {% else %} + "" + {% endif %}, + "docker_routing_config_mode": + {% if "docker_routing_config_mode" in DEVICE_METADATA["localhost"].keys() %} + "{{ DEVICE_METADATA["localhost"]["docker_routing_config_mode"] }}" + {% else %} + "" + {% endif %} +} diff --git a/dockers/docker-fpm-frr/frr/gen_frr.conf.j2 b/dockers/docker-fpm-frr/frr/gen_frr.conf.j2 new file mode 100644 index 000000000000..181437da07a0 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/gen_frr.conf.j2 @@ -0,0 +1,5 @@ +{% if DEVICE_METADATA.localhost.frr_mgmt_framework_config is defined and DEVICE_METADATA.localhost.frr_mgmt_framework_config == "true" %} + {% include "/usr/local/sonic/frrcfgd/frr.conf.j2" %} +{% else %} + {% include "/usr/share/sonic/templates/frr.conf.j2" %} +{% endif %} diff --git a/dockers/docker-fpm-frr/isolate.j2 b/dockers/docker-fpm-frr/frr/isolate.j2 similarity index 100% rename from dockers/docker-fpm-frr/isolate.j2 rename to dockers/docker-fpm-frr/frr/isolate.j2 diff --git a/dockers/docker-fpm-frr/frr/staticd/gen_staticd.conf.j2 b/dockers/docker-fpm-frr/frr/staticd/gen_staticd.conf.j2 new file mode 100644 index 000000000000..1346c9a4993b --- /dev/null +++ b/dockers/docker-fpm-frr/frr/staticd/gen_staticd.conf.j2 @@ -0,0 +1,5 @@ +{% if DEVICE_METADATA.localhost.frr_mgmt_framework_config is defined and DEVICE_METADATA.localhost.frr_mgmt_framework_config == "true" %} + {% include "/usr/local/sonic/frrcfgd/staticd.conf.j2" %} +{% else %} + {% include "/usr/share/sonic/templates/staticd/staticd.conf.j2" %} +{% endif %} diff --git a/dockers/docker-fpm-frr/frr/staticd/staticd.conf.j2 b/dockers/docker-fpm-frr/frr/staticd/staticd.conf.j2 new file mode 100644 index 000000000000..4831325276c7 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/staticd/staticd.conf.j2 @@ -0,0 +1,14 @@ +! +{% block banner %} +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/frr/staticd.conf.j2 using config DB data +! file: staticd.conf +! +{% endblock banner %} +! +{% include "common/daemons.common.conf.j2" %} +! +{% include "staticd.default_route.conf.j2" %} +! +{% include "staticd.loopback_route.conf.j2" %} +! diff --git a/dockers/docker-fpm-frr/staticd.default_route.conf.j2 b/dockers/docker-fpm-frr/frr/staticd/staticd.default_route.conf.j2 similarity index 100% rename from dockers/docker-fpm-frr/staticd.default_route.conf.j2 rename to dockers/docker-fpm-frr/frr/staticd/staticd.default_route.conf.j2 diff --git a/dockers/docker-fpm-frr/frr/staticd/staticd.loopback_route.conf.j2 b/dockers/docker-fpm-frr/frr/staticd/staticd.loopback_route.conf.j2 new file mode 100644 index 000000000000..95c2a901e4a3 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/staticd/staticd.loopback_route.conf.j2 @@ -0,0 +1,10 @@ +! +{% from "common/functions.conf.j2" import get_ipv4_loopback_address, get_ipv6_loopback_address, get_vnet_interfaces %} +! +{% block loopback_route %} +! add static ipv6 /64 loopback route to allow bgpd to advertise the loopback route prefix +{% if get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback0") != 'None' %} +ipv6 route {{ get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | replace('/128', '/64') | ip_network }}/64 Loopback0 +{% endif %} +{% endblock loopback_route %} +! diff --git a/dockers/docker-fpm-frr/frr/supervisord/critical_processes.j2 b/dockers/docker-fpm-frr/frr/supervisord/critical_processes.j2 new file mode 100644 index 000000000000..69f4e8e6931e --- /dev/null +++ b/dockers/docker-fpm-frr/frr/supervisord/critical_processes.j2 @@ -0,0 +1,12 @@ +program:zebra +program:staticd +program:bgpd +program:fpmsyncd +{% if DEVICE_METADATA.localhost.frr_mgmt_framework_config is defined and DEVICE_METADATA.localhost.frr_mgmt_framework_config == "true" %} +program:bfdd +program:ospfd +program:pimd +program:frrcfgd +{%- else %} +program:bgpcfgd +{%- endif %} diff --git a/dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 b/dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 new file mode 100644 index 000000000000..dd43e0cc4ec7 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 @@ -0,0 +1,179 @@ +[supervisord] +logfile_maxbytes=1MB +logfile_backups=2 +nodaemon=true + +[eventlistener:dependent-startup] +command=python3 -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE +buffer_size=50 + +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name bgp +events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING +autostart=true +autorestart=unexpected + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 +autostart=false +autorestart=unexpected +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true + +[program:zebra] +command=/usr/lib/frr/zebra -A 127.0.0.1 -s 90000000 -M fpm -M snmp +priority=4 +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running + +[program:zsocket] +command=/usr/bin/zsocket.sh +priority=4 +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=zebra:running + +[program:staticd] +command=/usr/lib/frr/staticd -A 127.0.0.1 +priority=4 +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=zsocket:exited + +{% if DEVICE_METADATA.localhost.frr_mgmt_framework_config is defined and DEVICE_METADATA.localhost.frr_mgmt_framework_config == "true" %} +[program:bfdd] +command=/usr/lib/frr/bfdd -A 127.0.0.1 +priority=4 +stopsignal=KILL +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=zebra:running +{% endif %} + +[program:bgpd] +command=/usr/lib/frr/bgpd -A 127.0.0.1 -M snmp +priority=5 +stopsignal=KILL +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=zsocket:exited + +{% if DEVICE_METADATA.localhost.frr_mgmt_framework_config is defined and DEVICE_METADATA.localhost.frr_mgmt_framework_config == "true" %} +[program:ospfd] +command=/usr/lib/frr/ospfd -A 127.0.0.1 -M snmp +priority=5 +stopsignal=KILL +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=zebra:running + +[program:pimd] +command=/usr/lib/frr/pimd -A 127.0.0.1 +priority=5 +stopsignal=KILL +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=zebra:running +{% endif %} + +[program:fpmsyncd] +command=fpmsyncd +priority=6 +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=bgpd:running + +{% if DEVICE_METADATA.localhost.frr_mgmt_framework_config is defined and DEVICE_METADATA.localhost.frr_mgmt_framework_config == "true" %} +[program:frrcfgd] +command=/usr/local/bin/frrcfgd +{% else %} +[program:bgpcfgd] +command=/usr/local/bin/bgpcfgd +{% endif %} +priority=6 +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=bgpd:running + +[program:bgpmon] +command=/usr/local/bin/bgpmon +priority=6 +autostart=false +autorestart=true +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=bgpd:running + +{% if DEVICE_METADATA.localhost.docker_routing_config_mode is defined and DEVICE_METADATA.localhost.docker_routing_config_mode == "unified" %} +[program:vtysh_b] +command=/usr/bin/vtysh -b +priority=6 +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=bgpd:running +{% endif %} + +{% if WARM_RESTART is defined and WARM_RESTART.bgp is defined and WARM_RESTART.bgp.bgp_eoiu is defined and WARM_RESTART.bgp.bgp_eoiu == "true" %} +[program:bgp_eoiu_marker] +command=/usr/bin/bgp_eoiu_marker.py +priority=7 +autostart=false +autorestart=false +startsecs=0 +startretries=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=bgpd:running +{% endif %} diff --git a/dockers/docker-fpm-frr/unisolate.j2 b/dockers/docker-fpm-frr/frr/unisolate.j2 similarity index 100% rename from dockers/docker-fpm-frr/unisolate.j2 rename to dockers/docker-fpm-frr/frr/unisolate.j2 diff --git a/dockers/docker-fpm-frr/frr/zebra/zebra.conf.j2 b/dockers/docker-fpm-frr/frr/zebra/zebra.conf.j2 new file mode 100644 index 000000000000..51d998e90d36 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/zebra/zebra.conf.j2 @@ -0,0 +1,12 @@ +! +{% block banner %} +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/zebra/zebra.conf.j2 using config DB data +! file: zebra.conf +! +{% endblock banner %} +! +{% include "common/daemons.common.conf.j2" %} +! +{% include "zebra.interfaces.conf.j2" %} +! diff --git a/dockers/docker-fpm-frr/frr/zebra/zebra.interfaces.conf.j2 b/dockers/docker-fpm-frr/frr/zebra/zebra.interfaces.conf.j2 new file mode 100644 index 000000000000..57d83163d67b --- /dev/null +++ b/dockers/docker-fpm-frr/frr/zebra/zebra.interfaces.conf.j2 @@ -0,0 +1,27 @@ +! +{% block vrf %} +{% if VNET is defined %} +{% for vnet_name, vnet_metadata in VNET.items() %} +vrf {{ vnet_name }} +vni {{ vnet_metadata['vni'] }} +! +{% endfor %} +{% endif %} +{% endblock vrf %} +! +{% block interfaces %} +! Enable nht through default route +ip nht resolve-via-default +! Enable link-detect (default disabled) +{% for (name, prefix) in INTERFACE|pfx_filter %} +interface {{ name }} +link-detect +! +{% endfor %} +{% for pc in PORTCHANNEL %} +interface {{ pc }} +link-detect +! +{% endfor %} +{% endblock interfaces %} +! diff --git a/dockers/docker-fpm-frr/frr/zebra/zebra.set_src.conf.j2 b/dockers/docker-fpm-frr/frr/zebra/zebra.set_src.conf.j2 new file mode 100644 index 000000000000..4dce3250ed1b --- /dev/null +++ b/dockers/docker-fpm-frr/frr/zebra/zebra.set_src.conf.j2 @@ -0,0 +1,8 @@ +! +! Set ip source to loopback for bgp learned routes +! +route-map {{ rm_name }} permit 10 + set src {{ lo_ip }} +! +ip{{ ip_proto }} protocol bgp route-map {{ rm_name }} +! diff --git a/dockers/docker-fpm-frr/start.sh b/dockers/docker-fpm-frr/start.sh deleted file mode 100755 index b3cef5e63244..000000000000 --- a/dockers/docker-fpm-frr/start.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env bash - -mkdir -p /etc/frr - -CONFIG_TYPE=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["docker_routing_config_mode"]'` - -if [ -z "$CONFIG_TYPE" ] || [ "$CONFIG_TYPE" == "separated" ]; then - sonic-cfggen -d -y /etc/sonic/constants.yml -t /usr/share/sonic/templates/bgpd.conf.j2 > /etc/frr/bgpd.conf - sonic-cfggen -d -t /usr/share/sonic/templates/zebra.conf.j2 > /etc/frr/zebra.conf - sonic-cfggen -d -t /usr/share/sonic/templates/staticd.conf.j2 > /etc/frr/staticd.conf - echo "no service integrated-vtysh-config" > /etc/frr/vtysh.conf - rm -f /etc/frr/frr.conf -elif [ "$CONFIG_TYPE" == "unified" ]; then - sonic-cfggen -d -y /etc/sonic/constants.yml -t /usr/share/sonic/templates/frr.conf.j2 >/etc/frr/frr.conf - echo "service integrated-vtysh-config" > /etc/frr/vtysh.conf - rm -f /etc/frr/bgpd.conf /etc/frr/zebra.conf /etc/frr/staticd.conf -fi - -chown -R frr:frr /etc/frr/ - -sonic-cfggen -d -t /usr/share/sonic/templates/isolate.j2 > /usr/sbin/bgp-isolate -chown root:root /usr/sbin/bgp-isolate -chmod 0755 /usr/sbin/bgp-isolate - -sonic-cfggen -d -t /usr/share/sonic/templates/unisolate.j2 > /usr/sbin/bgp-unisolate -chown root:root /usr/sbin/bgp-unisolate -chmod 0755 /usr/sbin/bgp-unisolate - -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 - -# start eoiu pulling, only if configured so -if [[ $(sonic-cfggen -d -v 'WARM_RESTART.bgp.bgp_eoiu') == 'true' ]]; then - supervisorctl start bgp_eoiu_marker -fi - -# Start Quagga processes -supervisorctl start zebra -supervisorctl start staticd -supervisorctl start bgpd - -if [ "$CONFIG_TYPE" == "unified" ]; then - supervisorctl start vtysh_b -fi - -supervisorctl start fpmsyncd - -supervisorctl start bgpcfgd diff --git a/dockers/docker-fpm-frr/staticd.conf.j2 b/dockers/docker-fpm-frr/staticd.conf.j2 deleted file mode 100644 index 4e39e17d7dbf..000000000000 --- a/dockers/docker-fpm-frr/staticd.conf.j2 +++ /dev/null @@ -1,12 +0,0 @@ -! -{% block banner %} -! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== -! generated by templates/frr/staticd.conf.j2 using config DB data -! file: staticd.conf -! -{% endblock banner %} -! -{% include "daemons.common.conf.j2" %} -! -{% include "staticd.default_route.conf.j2" %} -! diff --git a/dockers/docker-fpm-frr/supervisord.conf b/dockers/docker-fpm-frr/supervisord.conf deleted file mode 100644 index 3e544b64b296..000000000000 --- a/dockers/docker-fpm-frr/supervisord.conf +++ /dev/null @@ -1,93 +0,0 @@ -[supervisord] -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 -autostart=true -autorestart=false -startsecs=0 -stdout_logfile=syslog -stderr_logfile=syslog - -[program:bgpcfgd] -command=/usr/bin/bgpcfgd -priority=2 -autostart=false -autorestart=false -startsecs=0 -stdout_logfile=syslog -stderr_logfile=syslog - -[program:rsyslogd] -command=/usr/sbin/rsyslogd -n -priority=3 -autostart=false -autorestart=unexpected -startsecs=0 -stdout_logfile=syslog -stderr_logfile=syslog - -[program:zebra] -command=/usr/lib/frr/zebra -A 127.0.0.1 -s 90000000 -M fpm -M snmp -priority=4 -autostart=false -autorestart=false -startsecs=0 -stdout_logfile=syslog -stderr_logfile=syslog - -[program:staticd] -command=/usr/lib/frr/staticd -A 127.0.0.1 -priority=4 -autostart=false -autorestart=false -startsecs=0 -stdout_logfile=syslog -stderr_logfile=syslog - -[program:bgpd] -command=/usr/lib/frr/bgpd -A 127.0.0.1 -M snmp -priority=5 -stopsignal=KILL -autostart=false -autorestart=false -startsecs=0 -stdout_logfile=syslog -stderr_logfile=syslog - -[program:vtysh_b] -command=/usr/bin/vtysh -b -priority=6 -autostart=false -autorestart=false -startsecs=0 -stdout_logfile=syslog -stderr_logfile=syslog - -[program:fpmsyncd] -command=fpmsyncd -priority=6 -autostart=false -autorestart=false -startsecs=0 -stdout_logfile=syslog -stderr_logfile=syslog - -[program:bgp_eoiu_marker] -command=/usr/bin/bgp_eoiu_marker.py -priority=7 -autostart=false -autorestart=false -startsecs=0 -startretries=0 -stdout_logfile=syslog -stderr_logfile=syslog diff --git a/dockers/docker-fpm-frr/zebra.conf.j2 b/dockers/docker-fpm-frr/zebra.conf.j2 deleted file mode 100644 index 8c1c6f96484b..000000000000 --- a/dockers/docker-fpm-frr/zebra.conf.j2 +++ /dev/null @@ -1,12 +0,0 @@ -! -{% block banner %} -! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== -! generated by templates/quagga/zebra.conf.j2 using config DB data -! file: zebra.conf -! -{% endblock banner %} -! -{% include "daemons.common.conf.j2" %} -! -{% include "zebra.interfaces.conf.j2" %} -! diff --git a/dockers/docker-fpm-frr/zebra.interfaces.conf.j2 b/dockers/docker-fpm-frr/zebra.interfaces.conf.j2 deleted file mode 100644 index 4a089e4dc726..000000000000 --- a/dockers/docker-fpm-frr/zebra.interfaces.conf.j2 +++ /dev/null @@ -1,60 +0,0 @@ -! -{% block vrf %} -{% if VNET is defined %} -{% for vnet_name, vnet_metadata in VNET.iteritems() %} -vrf {{ vnet_name }} -vni {{ vnet_metadata['vni'] }} -! -{% endfor %} -{% endif %} -{% endblock vrf %} -! -{% block interfaces %} -! Enable link-detect (default disabled) -{% for (name, prefix) in INTERFACE|pfx_filter %} -interface {{ name }} -link-detect -! -{% endfor %} -{% for pc in PORTCHANNEL %} -interface {{ pc }} -link-detect -! -{% endfor %} -{% endblock interfaces %} -! -{% block source_loopback %} -{% set lo_ipv4_addrs = [] %} -{% set lo_ipv6_addrs = [] %} -{% if LOOPBACK_INTERFACE %} -{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} -{% if name == 'Loopback0' %} -{% if prefix | ipv6 %} -{% if lo_ipv6_addrs.append(prefix) %} -{% endif %} -{% else %} -{% if lo_ipv4_addrs.append(prefix) %} -{% endif %} -{% endif %} -{% endif %} -{% endfor %} -{% endif %} -! Set ip source to loopback for bgp learned routes -{% if lo_ipv4_addrs|length > 0 -%} -route-map RM_SET_SRC permit 10 - set src {{ lo_ipv4_addrs[0] | ip }} -! -{% endif %} -{% if lo_ipv6_addrs|length > 0 %} -route-map RM_SET_SRC6 permit 10 - set src {{ lo_ipv6_addrs[0] | ip }} -! -{% endif %} -ip protocol bgp route-map RM_SET_SRC -! -{% if lo_ipv6_addrs|length > 0 %} -ipv6 protocol bgp route-map RM_SET_SRC6 -! -{% endif %} -{% endblock source_loopback %} -! diff --git a/dockers/docker-fpm-frr/zsocket.sh b/dockers/docker-fpm-frr/zsocket.sh new file mode 100755 index 000000000000..111492f960ed --- /dev/null +++ b/dockers/docker-fpm-frr/zsocket.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash + +addr="127.0.0.1" +port=2601 + +function help() +{ + echo "This script aims to ensure zebra is ready to accept connections" + echo "Usage: $0 [options]" + echo "Options:" + echo " -a Zebra address" + echo " -o Zebra port" + exit 1 +} + +while getopts ":a:o:h" opt; do + case "${opt}" in + h) help + ;; + a) addr=${OPTARG} + ;; + o) port=${OPTARG} + ;; + esac +done + +start=$(date +%s.%N) +timeout 5s bash -c -- "until /etc/gobgp/gobgpd.conf -sonic-cfggen -d -t /usr/share/sonic/templates/zebra.conf.j2 > /etc/quagga/zebra.conf -sonic-cfggen -d -t /usr/share/sonic/templates/isolate.j2 > /usr/sbin/bgp-isolate +CFGGEN_PARAMS=" \ + -d \ + -t /usr/share/sonic/templates/gobgpd.conf.j2,/etc/gobgp/gobgpd.conf \ + -t /usr/share/sonic/templates/zebra.conf.j2,/etc/quagga/zebra.conf \ + -t /usr/share/sonic/templates/isolate.j2,/usr/sbin/bgp-isolate \ + -t /usr/share/sonic/templates/unisolate.j2,/usr/sbin/bgp-unisolate \ +" +sonic-cfggen $CFGGEN_PARAMS + chown root:root /usr/sbin/bgp-isolate chmod 0755 /usr/sbin/bgp-isolate -sonic-cfggen -d -t /usr/share/sonic/templates/unisolate.j2 > /usr/sbin/bgp-unisolate chown root:root /usr/sbin/bgp-unisolate chmod 0755 /usr/sbin/bgp-unisolate diff --git a/dockers/docker-fpm-gobgp/supervisord.conf b/dockers/docker-fpm-gobgp/supervisord.conf index b814dc024fa3..e7e3ee9f301a 100644 --- a/dockers/docker-fpm-gobgp/supervisord.conf +++ b/dockers/docker-fpm-gobgp/supervisord.conf @@ -5,7 +5,7 @@ nodaemon=true [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name bgp -events=PROCESS_STATE_EXITED +events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING autostart=true autorestart=unexpected diff --git a/dockers/docker-fpm-quagga/Dockerfile.j2 b/dockers/docker-fpm-quagga/Dockerfile.j2 index 9d1312d073ee..ac382afbe5b2 100644 --- a/dockers/docker-fpm-quagga/Dockerfile.j2 +++ b/dockers/docker-fpm-quagga/Dockerfile.j2 @@ -36,4 +36,4 @@ COPY ["*.j2", "/usr/share/sonic/templates/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/dockers/docker-fpm-quagga/bgpcfgd b/dockers/docker-fpm-quagga/bgpcfgd index 012a766c20b9..ef936247cc2c 100755 --- a/dockers/docker-fpm-quagga/bgpcfgd +++ b/dockers/docker-fpm-quagga/bgpcfgd @@ -6,6 +6,7 @@ import subprocess import syslog from swsssdk import ConfigDBConnector + class BGPConfigDaemon: def __init__(self): @@ -15,17 +16,18 @@ class BGPConfigDaemon: self.bgp_neighbor = self.config_db.get_table('BGP_NEIGHBOR') def __run_command(self, command): -# print command p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) stdout = p.communicate()[0] p.wait() if p.returncode != 0: - syslog.syslog(syslog.LOG_ERR, '[bgp cfgd] command execution returned {}. Command: "{}", stdout: "{}"'.format(p.returncode, command, stdout)) + syslog.syslog(syslog.LOG_ERR, '[bgp cfgd] command execution returned {}. Command: "{}", stdout: "{}"'.format( + p.returncode, command, stdout)) def metadata_handler(self, key, data): if key == 'localhost' and data.has_key('bgp_asn'): if data['bgp_asn'] != self.bgp_asn: - syslog.syslog(syslog.LOG_INFO, '[bgp cfgd] ASN changed to {} from {}, restart BGP...'.format(data['bgp_asn'], self.bgp_asn)) + syslog.syslog(syslog.LOG_INFO, '[bgp cfgd] ASN changed to {} from {}, restart BGP...'.format( + data['bgp_asn'], self.bgp_asn)) self.__run_command("supervisorctl restart start.sh") self.__run_command("service quagga restart") self.bgp_asn = data['bgp_asn'] @@ -38,22 +40,25 @@ class BGPConfigDaemon: self.__run_command(command) self.bgp_neighbor.pop(key) else: - command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c 'neighbor {} remote-as {}'".format(self.bgp_asn, key, data['asn']) + command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c 'neighbor {} remote-as {}'".format( + self.bgp_asn, key, data['asn']) self.__run_command(command) if data.has_key('name'): - command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c 'neighbor {} description {}'".format(self.bgp_asn, key, data['name']) + command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c 'neighbor {} description {}'".format( + self.bgp_asn, key, data['name']) self.__run_command(command) if data.has_key('admin_status'): command_mod = 'no ' if data['admin_status'] == 'up' else '' - command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c '{}neighbor {} shutdown'".format(self.bgp_asn, command_mod, key) + command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c '{}neighbor {} shutdown'".format( + self.bgp_asn, command_mod, key) self.__run_command(command) self.bgp_neighbor[key] = data def start(self): - self.config_db.subscribe('BGP_NEIGHBOR', - lambda table, key, data: self.bgp_handler(key, data)) + self.config_db.subscribe('BGP_NEIGHBOR', + lambda table, key, data: self.bgp_handler(key, data)) self.config_db.subscribe('DEVICE_METADATA', - lambda table, key, data: self.metadata_handler(key, data)) + lambda table, key, data: self.metadata_handler(key, data)) self.config_db.listen() @@ -61,5 +66,6 @@ def main(): daemon = BGPConfigDaemon() daemon.start() + if __name__ == "__main__": main() diff --git a/dockers/docker-fpm-quagga/bgpd.conf.j2 b/dockers/docker-fpm-quagga/bgpd.conf.j2 index 2f4c741303a4..8c838f8ffc9d 100644 --- a/dockers/docker-fpm-quagga/bgpd.conf.j2 +++ b/dockers/docker-fpm-quagga/bgpd.conf.j2 @@ -14,7 +14,7 @@ log facility local4 ! enable password {# {{ en_passwd }} TODO: param needed #} {% endblock system_init %} ! -{% if DEVICE_METADATA['localhost'].has_key('bgp_asn') %} +{% if 'bgp_asn' in DEVICE_METADATA['localhost'] %} {% block bgp_init %} ! ! bgp multiple-instance @@ -58,7 +58,7 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} {% endfor %} {% endblock vlan_advertisement %} {% block bgp_sessions %} -{% for neighbor_addr, bgp_session in BGP_NEIGHBOR.iteritems() %} +{% for neighbor_addr, bgp_session in BGP_NEIGHBOR.items() %} {% if bgp_session['asn'] | int != 0 %} neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }} neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} @@ -67,7 +67,7 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} or (bgp_session['holdtime'] is defined and bgp_session['holdtime'] | int != 180) %} neighbor {{ neighbor_addr }} timers {{ bgp_session['keepalive'] }} {{ bgp_session['holdtime'] }} {% endif %} -{% if bgp_session.has_key('admin_status') and bgp_session['admin_status'] == 'down' or not bgp_session.has_key('admin_status') and DEVICE_METADATA['localhost'].has_key('default_bgp_status') and DEVICE_METADATA['localhost']['default_bgp_status'] == 'down' %} +{% if 'admin_status' in bgp_session and bgp_session['admin_status'] == 'down' or 'admin_status' not in bgp_session and 'default_bgp_status' in DEVICE_METADATA['localhost'] and DEVICE_METADATA['localhost']['default_bgp_status'] == 'down' %} neighbor {{ neighbor_addr }} shutdown {% endif %} {% if neighbor_addr | ipv4 %} @@ -131,7 +131,7 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} {% endif %} {% endblock bgp_peers_with_range %} ! -{% if DEVICE_METADATA['localhost'].has_key('bgp_asn') %} +{% if 'bgp_asn' in DEVICE_METADATA['localhost'] %} maximum-paths 64 ! route-map ISOLATE permit 10 diff --git a/dockers/docker-fpm-quagga/critical_processes b/dockers/docker-fpm-quagga/critical_processes index f151af9c4bdd..2dceb501e3e5 100644 --- a/dockers/docker-fpm-quagga/critical_processes +++ b/dockers/docker-fpm-quagga/critical_processes @@ -1,4 +1,4 @@ -zebra -bgpd -fpmsyncd -bgpcfgd +program:zebra +program:bgpd +program:fpmsyncd +program:bgpcfgd diff --git a/dockers/docker-fpm-quagga/start.sh b/dockers/docker-fpm-quagga/start.sh index 1ffda3d17732..37d9c5072d9d 100755 --- a/dockers/docker-fpm-quagga/start.sh +++ b/dockers/docker-fpm-quagga/start.sh @@ -1,15 +1,20 @@ #!/usr/bin/env bash mkdir -p /etc/quagga -sonic-cfggen -d -y /etc/sonic/constants.yml -t /usr/share/sonic/templates/bgpd.conf.j2 > /etc/quagga/bgpd.conf -sonic-cfggen -d -t /usr/share/sonic/templates/zebra.conf.j2 > /etc/quagga/zebra.conf +CFGGEN_PARAMS=" \ + -d \ + -y /etc/sonic/constants.yml \ + -t /usr/share/sonic/templates/bgpd.conf.j2,/etc/quagga/bgpd.conf \ + -t /usr/share/sonic/templates/zebra.conf.j2,/etc/quagga/zebra.conf \ + -t /usr/share/sonic/templates/isolate.j2,/usr/sbin/bgp-isolate \ + -t /usr/share/sonic/templates/unisolate.j2,/usr/sbin/bgp-unisolate \ +" +sonic-cfggen $CFGGEN_PARAMS -sonic-cfggen -d -t /usr/share/sonic/templates/isolate.j2 > /usr/sbin/bgp-isolate chown root:root /usr/sbin/bgp-isolate chmod 0755 /usr/sbin/bgp-isolate -sonic-cfggen -d -t /usr/share/sonic/templates/unisolate.j2 > /usr/sbin/bgp-unisolate chown root:root /usr/sbin/bgp-unisolate chmod 0755 /usr/sbin/bgp-unisolate diff --git a/dockers/docker-fpm-quagga/supervisord.conf b/dockers/docker-fpm-quagga/supervisord.conf index 7397a7428a08..470dea18a16d 100644 --- a/dockers/docker-fpm-quagga/supervisord.conf +++ b/dockers/docker-fpm-quagga/supervisord.conf @@ -5,7 +5,7 @@ nodaemon=true [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name bgp -events=PROCESS_STATE_EXITED +events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING autostart=true autorestart=unexpected diff --git a/dockers/docker-iccpd/Dockerfile.j2 b/dockers/docker-iccpd/Dockerfile.j2 new file mode 100644 index 000000000000..51cc306bdd55 --- /dev/null +++ b/dockers/docker-iccpd/Dockerfile.j2 @@ -0,0 +1,34 @@ +{% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} +FROM docker-config-engine-buster + +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 && \ + apt-get install -y ebtables + +COPY \ +{% for deb in docker_iccpd_debs.split(' ') -%} +debs/{{ deb }}{{' '}} +{%- endfor -%} +debs/ + +RUN dpkg -i \ +{% for deb in docker_iccpd_debs.split(' ') -%} +debs/{{ deb }}{{' '}} +{%- endfor %} + +COPY ["start.sh", "iccpd.sh", "/usr/bin/"] +COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["iccpd.j2", "/usr/share/sonic/templates/"] + +RUN chmod +x /usr/bin/start.sh /usr/bin/iccpd.sh +RUN apt-get clean -y && \ + apt-get autoclean -y && \ + apt-get autoremove -y && \ + rm -rf /debs + +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/dockers/docker-iccpd/base_image_files/mclagdctl b/dockers/docker-iccpd/base_image_files/mclagdctl new file mode 100755 index 000000000000..7c0b45dd0625 --- /dev/null +++ b/dockers/docker-iccpd/base_image_files/mclagdctl @@ -0,0 +1,10 @@ +#!/bin/bash + +DOCKER_EXEC_FLAGS="i" + +# Determine whether stdout is on a terminal +if [ -t 1 ] ; then + DOCKER_EXEC_FLAGS+="t" +fi + +docker exec -$DOCKER_EXEC_FLAGS iccpd mclagdctl "$@" diff --git a/dockers/docker-iccpd/iccpd.j2 b/dockers/docker-iccpd/iccpd.j2 new file mode 100644 index 000000000000..6c6f9fab1afa --- /dev/null +++ b/dockers/docker-iccpd/iccpd.j2 @@ -0,0 +1,11 @@ +{% for mclag_id in MC_LAG %} +mclag_id:{{mclag_id}} + local_ip:{{MC_LAG[mclag_id]['local_ip']}} + peer_ip:{{MC_LAG[mclag_id]['peer_ip']}} +{% if MC_LAG[mclag_id].has_key('peer_link') %} + peer_link:{{MC_LAG[mclag_id]['peer_link']}} +{% endif %} + mclag_interface:{{MC_LAG[mclag_id]['mclag_interface']}} +{% endfor %} +system_mac:{{DEVICE_METADATA['localhost']['mac']}} + diff --git a/dockers/docker-iccpd/iccpd.sh b/dockers/docker-iccpd/iccpd.sh new file mode 100644 index 000000000000..d3b2888344ac --- /dev/null +++ b/dockers/docker-iccpd/iccpd.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +function start_app { + rm -f /var/run/iccpd/* + mclagsyncd & + iccpd +} + +function clean_up { + pkill -9 mclagsyncd + pkill -9 iccpd + exit +} + +trap clean_up SIGTERM SIGKILL +start_app +read diff --git a/dockers/docker-iccpd/start.sh b/dockers/docker-iccpd/start.sh new file mode 100644 index 000000000000..f2e9807f314f --- /dev/null +++ b/dockers/docker-iccpd/start.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + + +ICCPD_CONF_PATH=/etc/iccpd + +rm -rf $ICCPD_CONF_PATH +mkdir -p $ICCPD_CONF_PATH + +sonic-cfggen -d -t /usr/share/sonic/templates/iccpd.j2 > $ICCPD_CONF_PATH/iccpd.conf + +mkdir -p /var/sonic +echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status diff --git a/dockers/docker-iccpd/supervisord.conf b/dockers/docker-iccpd/supervisord.conf new file mode 100644 index 000000000000..716ca96b40c8 --- /dev/null +++ b/dockers/docker-iccpd/supervisord.conf @@ -0,0 +1,42 @@ +[supervisord] +logfile_maxbytes=1MB +logfile_backups=2 +nodaemon=true + +[eventlistener:dependent-startup] +command=python3 -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true + +[program:start] +command=/usr/bin/start.sh +priority=2 +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running + +[program:iccpd] +command=/usr/bin/iccpd.sh +priority=3 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited diff --git a/dockers/docker-lldp-sv2/Dockerfile.j2 b/dockers/docker-lldp-sv2/Dockerfile.j2 deleted file mode 100644 index 6a720514ef9b..000000000000 --- a/dockers/docker-lldp-sv2/Dockerfile.j2 +++ /dev/null @@ -1,46 +0,0 @@ -{% 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 - -# Update apt's cache of available packages -RUN apt-get update - -{% if docker_lldp_sv2_debs.strip() -%} -# Copy locally-built Debian package dependencies -{{ copy_files("debs/", docker_lldp_sv2_debs.split(' '), "/debs/") }} - -# Install locally-built Debian packages and implicitly install their dependencies -{{ install_debian_packages(docker_lldp_sv2_debs.split(' ')) }} -{%- endif %} - -{% if docker_lldp_sv2_whls.strip() -%} -# Copy locally-built Python wheel dependencies -{{ copy_files("python-wheels/", docker_lldp_sv2_whls.split(' '), "/python-wheels/") }} - -# Install locally-built Python wheel dependencies -{{ install_python_wheels(docker_lldp_sv2_whls.split(' ')) }} -{% endif %} - -# Clean up -RUN apt-get purge -y python-pip && \ - apt-get clean -y && \ - apt-get autoclean -y && \ - apt-get autoremove -y && \ - rm -rf /debs \ - /python-wheels \ - ~/.cache - -COPY ["start.sh", "/usr/bin/"] -COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] -COPY ["lldpd.conf.j2", "/usr/share/sonic/templates/"] -COPY ["lldpd", "/etc/default/"] -COPY ["lldpmgrd", "/usr/bin/"] -COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] -COPY ["critical_processes", "/etc/supervisor"] - -ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/dockers/docker-lldp-sv2/base_image_files/monit_lldp b/dockers/docker-lldp-sv2/base_image_files/monit_lldp deleted file mode 100644 index 200c52c7d332..000000000000 --- a/dockers/docker-lldp-sv2/base_image_files/monit_lldp +++ /dev/null @@ -1,15 +0,0 @@ -############################################################################### -## 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-lldp-sv2/critical_processes b/dockers/docker-lldp-sv2/critical_processes deleted file mode 100644 index b845b70bb3f7..000000000000 --- a/dockers/docker-lldp-sv2/critical_processes +++ /dev/null @@ -1,3 +0,0 @@ -lldpd -lldp-syncd -lldpmgrd diff --git a/dockers/docker-lldp-sv2/lldpd.conf.j2 b/dockers/docker-lldp-sv2/lldpd.conf.j2 deleted file mode 100644 index d5b6dba8700c..000000000000 --- a/dockers/docker-lldp-sv2/lldpd.conf.j2 +++ /dev/null @@ -1,12 +0,0 @@ -{% if MGMT_INTERFACE %} -{# If MGMT port alias is available, use it for port ID subtype, otherwise use port name #} -{% set mgmt_port_name = MGMT_INTERFACE.keys()[0][0] %} -{% set ipv4 = MGMT_INTERFACE.keys()[0][1].split('/')[0] %} -{% if MGMT_PORT and MGMT_PORT[mgmt_port_name] and MGMT_PORT[mgmt_port_name].alias %} -configure ports eth0 lldp portidsubtype local {{ MGMT_PORT[mgmt_port_name].alias }} -{% else %} -configure ports eth0 lldp portidsubtype local {{ mgmt_port_name }} -{% endif %} -configure system ip management pattern {{ ipv4 }} -{% endif %} -configure system hostname {{ DEVICE_METADATA['localhost']['hostname'] }} diff --git a/dockers/docker-lldp-sv2/lldpmgrd b/dockers/docker-lldp-sv2/lldpmgrd deleted file mode 100755 index 7e9ef1642a06..000000000000 --- a/dockers/docker-lldp-sv2/lldpmgrd +++ /dev/null @@ -1,262 +0,0 @@ -#!/usr/bin/env python - -""" - lldpmgrd - - LLDP manager daemon for SONiC - - Daemon which listens for changes in the PORT table of the State DB - and updates LLDP configuration accordingly for that port by calling - lldpcli. - - TODO: Also listen for changes in DEVICE_NEIGHBOR and PORT tables in - Config DB and update LLDP config upon changes. -""" - - -try: - import os - import signal - import subprocess - import sys - import syslog - import os.path - from swsscommon import swsscommon -except ImportError as err: - raise ImportError("%s - required module not found" % str(err)) - -VERSION = "1.0" - -SYSLOG_IDENTIFIER = "lldpmgrd" - - -# ========================== Syslog wrappers ========================== - -def log_debug(msg): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_DEBUG, msg) - syslog.closelog() - - -def log_info(msg): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_INFO, msg) - syslog.closelog() - - -def log_warning(msg): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_WARNING, msg) - syslog.closelog() - - -def log_error(msg): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_ERR, msg) - syslog.closelog() - - -# ========================== Signal Handling ========================== - -def signal_handler(sig, frame): - if sig == signal.SIGHUP: - log_info("Caught SIGHUP - ignoring...") - return - elif sig == signal.SIGINT: - log_info("Caught SIGINT - exiting...") - sys.exit(128 + sig) - elif sig == signal.SIGTERM: - log_info("Caught SIGTERM - exiting...") - sys.exit(128 + sig) - else: - log_warning("Caught unhandled signal '" + sig + "'") - -# ============================== Classes ============================== - -class LldpManager(object): - """ - Class which subscribes to notifications of changes in the PORT table of - the Redis State database and updates LLDP configuration accordingly for - that port by calling lldpcli. - Attributes: - state_db: Handle to Redis State database via swsscommon lib - config_db: Handle to Redis Config database via swsscommon lib - pending_cmds: Dictionary where key is port name, value is pending - LLDP configuration command to run - """ - REDIS_TIMEOUT_MS = 0 - - def __init__(self): - # Open a handle to the Config database - self.config_db = swsscommon.DBConnector("CONFIG_DB", - self.REDIS_TIMEOUT_MS, - True) - - # Open a handle to the Application database - self.appl_db = swsscommon.DBConnector("APPL_DB", - self.REDIS_TIMEOUT_MS, - True) - - self.pending_cmds = {} - - def is_port_up(self, port_name): - """ - Determine if a port is up or down by looking into the oper-status for the port in - PORT TABLE in the Application DB - """ - # Retrieve all entires for this port from the Port table - port_table = swsscommon.Table(self.appl_db, swsscommon.APP_PORT_TABLE_NAME) - (status, fvp) = port_table.get(port_name) - if status: - # Convert list of tuples to a dictionary - port_table_dict = dict(fvp) - - # Get the oper-status for the port - if port_table_dict.has_key("oper_status"): - port_oper_status = port_table_dict.get("oper_status") - log_info("Port name {} oper status: {}".format(port_name, port_oper_status)) - return port_oper_status == "up" - else: - return False - else: - log_error("Port '{}' not found in {} table in App DB".format(port_name, swsscommon.APP_PORT_TABLE_NAME)) - return False - - def generate_pending_lldp_config_cmd_for_port(self, port_name): - """ - For port `port_name`, look up the description and alias in the Config database, - then form the appropriate lldpcli configuration command and run it. - """ - port_desc = None - - # Retrieve all entires for this port from the Port table - port_table = swsscommon.Table(self.config_db, swsscommon.CFG_PORT_TABLE_NAME) - (status, fvp) = port_table.get(port_name) - if status: - # Convert list of tuples to a dictionary - port_table_dict = dict(fvp) - - # Get the port alias. If None or empty string, use port name instead - port_alias = port_table_dict.get("alias") - if not port_alias: - log_info("Unable to retrieve port alias for port '{}'. Using port name instead.".format(port_name)) - port_alias = port_name - - # Get the port description. If None or empty string, we'll skip this configuration - port_desc = port_table_dict.get("description") - - else: - log_error("Port '{}' not found in {} table in Config DB. Using port name instead of port alias.".format(port_name, swsscommon.CFG_PORT_TABLE_NAME)) - port_alias = port_name - - lldpcli_cmd = "lldpcli configure ports {0} lldp portidsubtype local {1}".format(port_name, port_alias) - - # if there is a description available, also configure that - if port_desc: - lldpcli_cmd += " description '{}'".format(port_desc) - else: - log_info("Unable to retrieve description for port '{}'. Not adding port description".format(port_name)) - - # Add the command to our dictionary of pending commands, overwriting any - # previous pending command for this port - self.pending_cmds[port_name] = lldpcli_cmd - - def process_pending_cmds(self): - # List of port names (keys of elements) to delete from self.pending_cmds - to_delete = [] - - for (port_name, cmd) in self.pending_cmds.iteritems(): - log_debug("Running command: '{}'".format(cmd)) - - proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - - (stdout, stderr) = proc.communicate() - - # If the command succeeds, add the port name to our to_delete list. - # We will delete this command from self.pending_cmds below. - # If the command fails, log a message, but don't delete the command - # from self.pending_cmds, so that the command will be retried the - # next time this method is called. - if proc.returncode == 0: - to_delete.append(port_name) - else: - log_warning("Command failed '{}': {}".format(cmd, stderr)) - - # Delete all successful commands from self.pending_cmds - for port_name in to_delete: - self.pending_cmds.pop(port_name, None) - - def run(self): - """ - Subscribes to notifications of changes in the PORT table - of the Redis Config/Application database. - Subscribe to APP_DB - get port oper status - Subscribe to CONFIG_DB - get notified of port config changes - Update LLDP configuration accordingly. - """ - # Set select timeout to 10 seconds - SELECT_TIMEOUT_MS = 1000 * 10 - - sel = swsscommon.Select() - - # Subscribe to PORT table notifications in the Config DB - sst_confdb = swsscommon.SubscriberStateTable(self.config_db, swsscommon.CFG_PORT_TABLE_NAME) - sel.addSelectable(sst_confdb) - - # Subscribe to PORT table notifications in the App DB - sst_appdb = swsscommon.SubscriberStateTable(self.appl_db, swsscommon.APP_PORT_TABLE_NAME) - sel.addSelectable(sst_appdb) - - # Listen for changes to the PORT table in the CONFIG_DB and APP_DB - while True: - (state, c) = sel.select(SELECT_TIMEOUT_MS) - - if state == swsscommon.Select.OBJECT: - (key, op, fvp) = sst_confdb.pop() - if fvp: - fvp_dict = dict(fvp) - - # handle config change - if (fvp_dict.has_key("alias") or fvp_dict.has_key("description")) and (op in ["SET", "DEL"]): - if self.is_port_up(key): - self.generate_pending_lldp_config_cmd_for_port(key) - else: - self.pending_cmds.pop(key, None) - - (key, op, fvp) = sst_appdb.pop() - if (key != "PortInitDone") and (key != "PortConfigDone"): - if fvp: - fvp_dict = dict(fvp) - - # handle port status change - if fvp_dict.has_key("oper_status"): - if "up" in fvp_dict.get("oper_status"): - self.generate_pending_lldp_config_cmd_for_port(key) - else: - self.pending_cmds.pop(key, None) - - # Process all pending commands - self.process_pending_cmds() - - -# ============================= Functions ============================= - -def main(): - log_info("Starting up...") - - if not os.geteuid() == 0: - log_error("Must be root to run this daemon") - print "Error: Must be root to run this daemon" - sys.exit(1) - - # Register our signal handlers - signal.signal(signal.SIGHUP, signal_handler) - signal.signal(signal.SIGINT, signal_handler) - signal.signal(signal.SIGTERM, signal_handler) - - # Instantiate a LldpManager object - lldpmgr = LldpManager() - lldpmgr.run() - -if __name__ == "__main__": - main() diff --git a/dockers/docker-lldp-sv2/start.sh b/dockers/docker-lldp-sv2/start.sh deleted file mode 100755 index 76666e77aca2..000000000000 --- a/dockers/docker-lldp-sv2/start.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env bash - -sonic-cfggen -d -t /usr/share/sonic/templates/lldpd.conf.j2 > /etc/lldpd.conf - -mkdir -p /var/sonic -echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status - -rm -f /var/run/rsyslogd.pid -rm -f /var/run/lldpd.socket - -supervisorctl start rsyslogd -supervisorctl start lldpd - -# Current lldpd version has a bug. -# When lldpd starts it is in the pause state by default -# But then it execute 'lldpcli resume' to configure and unpause itself. -# When lldpd execute lldpcli, it doesn't check the return code -# Sometimes lldpcli returns failure, but lldpd doesn't catch it -# and keeps working paused and unconfigured -# -# The fix below addresses the issue. -# - -# wait until lldpd started -until [[ -e /var/run/lldpd.socket ]]; -do - sleep 1; -done - -# Manually try to resume lldpd, until it's successful -while /bin/true; -do - lldpcli -u /var/run/lldpd.socket -c /etc/lldpd.conf -c /etc/lldpd.d resume > /dev/null && break - sleep 1 -done - -supervisorctl start lldp-syncd -supervisorctl start lldpmgrd diff --git a/dockers/docker-lldp-sv2/supervisord.conf b/dockers/docker-lldp-sv2/supervisord.conf deleted file mode 100644 index 73ff52f4420e..000000000000 --- a/dockers/docker-lldp-sv2/supervisord.conf +++ /dev/null @@ -1,55 +0,0 @@ -[supervisord] -logfile_maxbytes=1MB -logfile_backups=2 -nodaemon=true - -[eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener --container-name lldp -events=PROCESS_STATE_EXITED -autostart=true -autorestart=unexpected - -[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:lldpd] -# https://github.com/vincentbernat/lldpd/commit/9856f2792c301116cc4a3fcfba91b9672ee5db1f -# - `-d` means to stay in foreground, log to syslog -# - `-dd` means to stay in foreground, log warnings to console -# - `-ddd` means to stay in foreground, log warnings and info to console -# - `-dddd` means to stay in foreground, log all to console -command=/usr/sbin/lldpd -d -I Ethernet*,eth0 -C eth0 -priority=3 -autostart=false -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog - -[program:lldp-syncd] -command=/usr/bin/env python2 -m lldp_syncd -priority=4 -autostart=false -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog - -[program:lldpmgrd] -command=/usr/bin/lldpmgrd -priority=5 -autostart=false -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog diff --git a/dockers/docker-lldp/Dockerfile.j2 b/dockers/docker-lldp/Dockerfile.j2 new file mode 100644 index 000000000000..a1c7a1c1bee2 --- /dev/null +++ b/dockers/docker-lldp/Dockerfile.j2 @@ -0,0 +1,52 @@ +{% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} +FROM docker-config-engine-buster + +ARG docker_container_name +ARG image_version +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 + +# Pass the image_version to container +ENV IMAGE_VERSION=$image_version + +# Update apt's cache of available packages +RUN apt-get update + +{% if docker_lldp_debs.strip() -%} +# Copy locally-built Debian package dependencies +{{ copy_files("debs/", docker_lldp_debs.split(' '), "/debs/") }} + +# Install locally-built Debian packages and implicitly install their dependencies +{{ install_debian_packages(docker_lldp_debs.split(' ')) }} +{%- endif %} + +{% if docker_lldp_whls.strip() -%} +# Copy locally-built Python wheel dependencies +{{ copy_files("python-wheels/", docker_lldp_whls.split(' '), "/python-wheels/") }} + +# Install locally-built Python wheel dependencies +{{ install_python_wheels(docker_lldp_whls.split(' ')) }} +{% endif %} + +# Clean up +RUN apt-get clean -y && \ + apt-get autoclean -y && \ + apt-get autoremove -y && \ + rm -rf /debs \ + /python-wheels \ + ~/.cache + +COPY ["docker-lldp-init.sh", "/usr/bin/"] +COPY ["start.sh", "/usr/bin/"] +COPY ["waitfor_lldp_ready.sh", "/usr/bin/"] +COPY ["supervisord.conf.j2", "/usr/share/sonic/templates/"] +COPY ["lldpd.conf.j2", "/usr/share/sonic/templates/"] +COPY ["lldpdSysDescr.conf.j2", "/usr/share/sonic/templates/"] +COPY ["lldpd", "/etc/default/"] +COPY ["lldpmgrd", "/usr/bin/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] + +ENTRYPOINT ["/usr/bin/docker-lldp-init.sh"] diff --git a/dockers/docker-lldp-sv2/base_image_files/lldpcli b/dockers/docker-lldp/base_image_files/lldpcli old mode 100644 new mode 100755 similarity index 100% rename from dockers/docker-lldp-sv2/base_image_files/lldpcli rename to dockers/docker-lldp/base_image_files/lldpcli diff --git a/dockers/docker-lldp-sv2/base_image_files/lldpctl b/dockers/docker-lldp/base_image_files/lldpctl similarity index 100% rename from dockers/docker-lldp-sv2/base_image_files/lldpctl rename to dockers/docker-lldp/base_image_files/lldpctl diff --git a/dockers/docker-lldp/base_image_files/monit_lldp b/dockers/docker-lldp/base_image_files/monit_lldp new file mode 100644 index 000000000000..d470972ace30 --- /dev/null +++ b/dockers/docker-lldp/base_image_files/monit_lldp @@ -0,0 +1,15 @@ +############################################################################### +## Monit configuration for lldp container +## process list: +## lldpd +## lldp-syncd +## lldpmgrd +############################################################################### +check program lldp|lldpd_monitor with path "/usr/bin/process_checker lldp lldpd:" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles + +check program lldp|lldp_syncd with path "/usr/bin/process_checker lldp python3 -m lldp_syncd" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles + +check program lldp|lldpmgrd with path "/usr/bin/process_checker lldp python3 /usr/bin/lldpmgrd" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/dockers/docker-lldp/critical_processes b/dockers/docker-lldp/critical_processes new file mode 100644 index 000000000000..90586536a4f5 --- /dev/null +++ b/dockers/docker-lldp/critical_processes @@ -0,0 +1,3 @@ +program:lldpd +program:lldp-syncd +program:lldpmgrd diff --git a/dockers/docker-lldp/docker-lldp-init.sh b/dockers/docker-lldp/docker-lldp-init.sh new file mode 100755 index 000000000000..135ff48255d6 --- /dev/null +++ b/dockers/docker-lldp/docker-lldp-init.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +#Generate supervisord.conf based on device metadata +mkdir -p /etc/supervisor/conf.d/ +sonic-cfggen -d -t /usr/share/sonic/templates/supervisord.conf.j2 > /etc/supervisor/conf.d/supervisord.conf +exec /usr/local/bin/supervisord diff --git a/dockers/docker-lldp-sv2/lldpd b/dockers/docker-lldp/lldpd similarity index 100% rename from dockers/docker-lldp-sv2/lldpd rename to dockers/docker-lldp/lldpd diff --git a/dockers/docker-lldp/lldpd.conf.j2 b/dockers/docker-lldp/lldpd.conf.j2 new file mode 100644 index 000000000000..904784ef67b1 --- /dev/null +++ b/dockers/docker-lldp/lldpd.conf.j2 @@ -0,0 +1,21 @@ +{% set mgmt_if = {} %} +{% if MGMT_INTERFACE %} +{% for (mgmt_name, mgmt_prefix) in MGMT_INTERFACE|pfx_filter %} +{% if mgmt_prefix|ipv4 %} +{% if mgmt_if.update({'port_name' : mgmt_name}) %} {% endif %} +{% if mgmt_if.update({'ipv4' : mgmt_prefix|ip}) %} {% endif %} +{% endif %} +{% endfor %} +{% endif %} +{% if mgmt_if %} +{# If MGMT port alias is available, use it for port ID subtype, otherwise use port name #} +{% if MGMT_PORT and MGMT_PORT[mgmt_if.port_name] and MGMT_PORT[mgmt_if.port_name].alias %} +configure ports eth0 lldp portidsubtype local {{ MGMT_PORT[mgmt_if.port_name].alias }} +{% else %} +configure ports eth0 lldp portidsubtype local {{ mgmt_if.port_name }} +{% endif %} +configure system ip management pattern {{ mgmt_if.ipv4 }} +{% endif %} +configure system hostname {{ DEVICE_METADATA['localhost']['hostname'] }} +{# pause lldpd operations until all interfaces are well configured, resume command will run in lldpmgrd #} +pause diff --git a/dockers/docker-lldp/lldpdSysDescr.conf.j2 b/dockers/docker-lldp/lldpdSysDescr.conf.j2 new file mode 100644 index 000000000000..047b3c68b34f --- /dev/null +++ b/dockers/docker-lldp/lldpdSysDescr.conf.j2 @@ -0,0 +1 @@ +configure system description "SONiC Software Version: SONiC.{{ build_version }} - HwSku: {{ DEVICE_METADATA['localhost']['hwsku'] }} - Distribution: Debian {{ debian_version }} - Kernel: {{ kernel_version }}" diff --git a/dockers/docker-lldp/lldpmgrd b/dockers/docker-lldp/lldpmgrd new file mode 100755 index 000000000000..61d6034faa15 --- /dev/null +++ b/dockers/docker-lldp/lldpmgrd @@ -0,0 +1,263 @@ +#!/usr/bin/env python3 + +""" + lldpmgrd + + LLDP manager daemon for SONiC + + Daemon which listens for changes in the PORT table of the State DB + and updates LLDP configuration accordingly for that port by calling + lldpcli. + + TODO: Also listen for changes in DEVICE_NEIGHBOR and PORT tables in + Config DB and update LLDP config upon changes. +""" + + +try: + import os + import subprocess + import sys + import time + + from sonic_py_common import daemon_base + from swsscommon import swsscommon +except ImportError as err: + raise ImportError("%s - required module not found" % str(err)) + +VERSION = "1.0" + +SYSLOG_IDENTIFIER = "lldpmgrd" +PORT_INIT_TIMEOUT = 300 + + +class LldpManager(daemon_base.DaemonBase): + """ + Class which subscribes to notifications of changes in the PORT table of + the Redis State database and updates LLDP configuration accordingly for + that port by calling lldpcli. + Attributes: + state_db: Handle to Redis State database via swsscommon lib + config_db: Handle to Redis Config database via swsscommon lib + pending_cmds: Dictionary where key is port name, value is pending + LLDP configuration command to run + """ + REDIS_TIMEOUT_MS = 0 + + def __init__(self, log_identifier): + super(LldpManager, self).__init__(log_identifier) + + # Open a handle to the Config database + self.config_db = swsscommon.DBConnector("CONFIG_DB", + self.REDIS_TIMEOUT_MS, + True) + + # Open a handle to the Application database + self.appl_db = swsscommon.DBConnector("APPL_DB", + self.REDIS_TIMEOUT_MS, + True) + + self.pending_cmds = {} + + def is_port_up(self, port_name): + """ + Determine if a port is up or down by looking into the oper-status for the port in + PORT TABLE in the Application DB + """ + # Retrieve all entires for this port from the Port table + port_table = swsscommon.Table(self.appl_db, swsscommon.APP_PORT_TABLE_NAME) + (status, fvp) = port_table.get(port_name) + if status: + # Convert list of tuples to a dictionary + port_table_dict = dict(fvp) + + # Get the oper-status for the port + if "oper_status" in port_table_dict: + port_oper_status = port_table_dict.get("oper_status") + self.log_info("Port name {} oper status: {}".format(port_name, port_oper_status)) + return port_oper_status == "up" + else: + return False + else: + # Retrieve PortInitDone entry from the Port table + (init_status, init_fvp) = port_table.get("PortInitDone") + # The initialization procedure is done, but don't have this port entry + if init_status: + self.log_error("Port '{}' not found in {} table in App DB".format( + port_name, swsscommon.APP_PORT_TABLE_NAME)) + return False + + def generate_pending_lldp_config_cmd_for_port(self, port_name): + """ + For port `port_name`, look up the description and alias in the Config database, + then form the appropriate lldpcli configuration command and run it. + """ + port_desc = None + + # Retrieve all entires for this port from the Port table + port_table = swsscommon.Table(self.config_db, swsscommon.CFG_PORT_TABLE_NAME) + (status, fvp) = port_table.get(port_name) + if status: + # Convert list of tuples to a dictionary + port_table_dict = dict(fvp) + + # Get the port alias. If None or empty string, use port name instead + port_alias = port_table_dict.get("alias") + if not port_alias: + self.log_info("Unable to retrieve port alias for port '{}'. Using port name instead.".format(port_name)) + port_alias = port_name + + # Get the port description. If None or empty string, we'll skip this configuration + port_desc = port_table_dict.get("description") + + else: + self.log_error("Port '{}' not found in {} table in Config DB. Using port name instead of port alias.".format( + port_name, swsscommon.CFG_PORT_TABLE_NAME)) + port_alias = port_name + + lldpcli_cmd = "lldpcli configure ports {0} lldp portidsubtype local {1}".format(port_name, port_alias) + + # if there is a description available, also configure that + if port_desc: + lldpcli_cmd += " description '{}'".format(port_desc) + else: + self.log_info("Unable to retrieve description for port '{}'. Not adding port description".format(port_name)) + + # Add the command to our dictionary of pending commands, overwriting any + # previous pending command for this port + self.pending_cmds[port_name] = lldpcli_cmd + + def process_pending_cmds(self): + # List of port names (keys of elements) to delete from self.pending_cmds + to_delete = [] + + for (port_name, cmd) in self.pending_cmds.items(): + self.log_debug("Running command: '{}'".format(cmd)) + + rc, stderr = run_cmd(self, cmd) + + # If the command succeeds, add the port name to our to_delete list. + # We will delete this command from self.pending_cmds below. + # If the command fails, log a message, but don't delete the command + # from self.pending_cmds, so that the command will be retried the + # next time this method is called. + if rc == 0: + to_delete.append(port_name) + else: + self.log_warning("Command failed '{}': {}".format(cmd, stderr)) + + # Delete all successful commands from self.pending_cmds + for port_name in to_delete: + self.pending_cmds.pop(port_name, None) + + def run(self): + """ + Subscribes to notifications of changes in the PORT table + of the Redis Config/Application database. + Subscribe to APP_DB - get port oper status + Subscribe to CONFIG_DB - get notified of port config changes + Update LLDP configuration accordingly. + """ + self.log_info("Starting up...") + + if not os.geteuid() == 0: + self.log_error("Must be root to run this daemon") + print("Error: Must be root to run this daemon") + sys.exit(1) + + # Set select timeout to 10 seconds + SELECT_TIMEOUT_MS = 1000 * 10 + + # Daemon is paused on the configuration file to avoid lldp packets with wrong information + # until all interfaces are well configured on lldpd + port_init_done = False + port_config_done = False + resume_lldp_sent = False + start_time = time.time() + + sel = swsscommon.Select() + + # Subscribe to PORT table notifications in the Config DB + sst_confdb = swsscommon.SubscriberStateTable(self.config_db, swsscommon.CFG_PORT_TABLE_NAME) + sel.addSelectable(sst_confdb) + + # Subscribe to PORT table notifications in the App DB + sst_appdb = swsscommon.SubscriberStateTable(self.appl_db, swsscommon.APP_PORT_TABLE_NAME) + sel.addSelectable(sst_appdb) + + # Listen for changes to the PORT table in the CONFIG_DB and APP_DB + while True: + (state, c) = sel.select(SELECT_TIMEOUT_MS) + + if state == swsscommon.Select.OBJECT: + (key, op, fvp) = sst_confdb.pop() + if fvp: + fvp_dict = dict(fvp) + + # handle config change + if ("alias" in fvp_dict or "description" in fvp_dict) and (op in ["SET", "DEL"]): + if self.is_port_up(key): + self.generate_pending_lldp_config_cmd_for_port(key) + else: + self.pending_cmds.pop(key, None) + + (key, op, fvp) = sst_appdb.pop() + if (key != "PortInitDone") and (key != "PortConfigDone"): + if fvp: + fvp_dict = dict(fvp) + + # handle port status change + if "oper_status" in fvp_dict: + if "up" in fvp_dict.get("oper_status"): + self.generate_pending_lldp_config_cmd_for_port(key) + else: + self.pending_cmds.pop(key, None) + + elif key == "PortInitDone": + port_init_done = True + elif key == "PortConfigDone": + port_config_done = True + + # Process all pending commands + self.process_pending_cmds() + + # Resume the daemon since all interfaces data updated and configured to the lldpd so no miss leading packets will be sent + if not resume_lldp_sent: + if check_timeout(self, start_time): + port_init_done = port_config_done = True + if port_init_done and port_config_done: + port_init_done = port_config_done = False + rc, stderr = run_cmd(self, "lldpcli resume") + if rc != 0: + self.log_error("Failed to resume lldpd with command: 'lldpcli resume': {}".format(stderr)) + sys.exit(1) + resume_lldp_sent = True + +# ============================= Functions ============================= + + +def main(): + # Instantiate a LldpManager object + lldpmgr = LldpManager(SYSLOG_IDENTIFIER) + + # Log all messages from INFO level and higher + lldpmgr.set_min_log_priority_info() + + lldpmgr.run() + + +def run_cmd(self, cmd): + proc = subprocess.Popen(cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + (stdout, stderr) = proc.communicate() + return proc.returncode, stderr + + +def check_timeout(self, start_time): + if time.time() - start_time > PORT_INIT_TIMEOUT: + self.log_error("Port init timeout reached ({} seconds), resuming lldpd...".format(PORT_INIT_TIMEOUT)) + return True + return False + + +if __name__ == "__main__": + main() diff --git a/dockers/docker-lldp/start.sh b/dockers/docker-lldp/start.sh new file mode 100755 index 000000000000..5a489884aea9 --- /dev/null +++ b/dockers/docker-lldp/start.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +CFGGEN_PARAMS=" \ + -d \ + -t /usr/share/sonic/templates/lldpd.conf.j2 \ + -y /etc/sonic/sonic_version.yml \ + -t /usr/share/sonic/templates/lldpdSysDescr.conf.j2 \ +" + +if [ "${RUNTIME_OWNER}" == "" ]; then + RUNTIME_OWNER="kube" +fi + +CTR_SCRIPT="/usr/share/sonic/scripts/container_startup.py" +if test -f ${CTR_SCRIPT} +then + ${CTR_SCRIPT} -f lldp -o ${RUNTIME_OWNER} -v ${IMAGE_VERSION} +fi + +sonic-cfggen $CFGGEN_PARAMS > /etc/lldpd.conf + +mkdir -p /var/sonic +echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status + +rm -f /var/run/lldpd.socket diff --git a/dockers/docker-lldp/supervisord.conf.j2 b/dockers/docker-lldp/supervisord.conf.j2 new file mode 100644 index 000000000000..3a84caee3040 --- /dev/null +++ b/dockers/docker-lldp/supervisord.conf.j2 @@ -0,0 +1,89 @@ +[supervisord] +logfile_maxbytes=1MB +logfile_backups=2 +nodaemon=true + +[eventlistener:dependent-startup] +command=python3 -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE +buffer_size=25 + +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name lldp +events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING +autostart=true +autorestart=unexpected + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true + +[program:start] +command=/usr/bin/start.sh +priority=2 +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running + +[program:lldpd] +# https://github.com/vincentbernat/lldpd/commit/9856f2792c301116cc4a3fcfba91b9672ee5db1f +# - `-d` means to stay in foreground, log to syslog +# - `-dd` means to stay in foreground, log warnings to console +# - `-ddd` means to stay in foreground, log warnings and info to console +# - `-dddd` means to stay in foreground, log all to console +{% if DEVICE_METADATA['localhost']['sub_role'] is defined and DEVICE_METADATA['localhost']['sub_role']|length %} +command=/usr/sbin/lldpd -d -I Ethernet* -C Ethernet* +{% else %} +command=/usr/sbin/lldpd -d -I Ethernet*,eth0 -C eth0 +{% endif %} +priority=3 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited + +[program:waitfor_lldp_ready] +command=/usr/bin/waitfor_lldp_ready.sh +priority=3 +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=lldpd:running + +[program:lldp-syncd] +command=/usr/bin/env python3 -m lldp_syncd +priority=4 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=waitfor_lldp_ready:exited + +[program:lldpmgrd] +command=/usr/bin/lldpmgrd +priority=5 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=lldp-syncd:running diff --git a/dockers/docker-lldp/waitfor_lldp_ready.sh b/dockers/docker-lldp/waitfor_lldp_ready.sh new file mode 100755 index 000000000000..ecb16dc2e5f0 --- /dev/null +++ b/dockers/docker-lldp/waitfor_lldp_ready.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +# Current lldpd version has a bug. +# When lldpd starts it is in the pause state by default +# But then it execute 'lldpcli resume' to configure and unpause itself. +# When lldpd execute lldpcli, it doesn't check the return code +# Sometimes lldpcli returns failure, but lldpd doesn't catch it +# and keeps working paused and unconfigured +# +# The fix below addresses the issue. +# + +# wait until lldpd started +until [[ -e /var/run/lldpd.socket ]]; +do + sleep 1; +done + +# Manually try to resume lldpd, until it's successful +while /bin/true; +do + lldpcli -u /var/run/lldpd.socket -c /etc/lldpd.conf -c /etc/lldpd.d resume > /dev/null && break + sleep 1 +done diff --git a/dockers/docker-macsec/Dockerfile.j2 b/dockers/docker-macsec/Dockerfile.j2 new file mode 100644 index 000000000000..bf8db48079e0 --- /dev/null +++ b/dockers/docker-macsec/Dockerfile.j2 @@ -0,0 +1,30 @@ +{% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} +FROM docker-config-engine-buster + +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_macsec_debs.strip() -%} +# Copy locally-built Debian package dependencies +{{ copy_files("debs/", docker_macsec_debs.split(' '), "/debs/") }} + +# Install locally-built Debian packages and implicitly install their dependencies +{{ install_debian_packages(docker_macsec_debs.split(' ')) }} +{%- endif %} + +RUN apt-get clean -y && \ + apt-get autoclean -y && \ + apt-get autoremove -y && \ + rm -rf /debs + +COPY ["start.sh", "/usr/bin/"] +COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] + +# ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/dockers/docker-macsec/critical_processes b/dockers/docker-macsec/critical_processes new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/dockers/docker-macsec/start.sh b/dockers/docker-macsec/start.sh new file mode 100644 index 000000000000..20d602bdd370 --- /dev/null +++ b/dockers/docker-macsec/start.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash + diff --git a/dockers/docker-macsec/supervisord.conf b/dockers/docker-macsec/supervisord.conf new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/dockers/docker-nat/Dockerfile.j2 b/dockers/docker-nat/Dockerfile.j2 index a74147cc26fd..36a178a68af2 100644 --- a/dockers/docker-nat/Dockerfile.j2 +++ b/dockers/docker-nat/Dockerfile.j2 @@ -1,5 +1,5 @@ {% from "dockers/dockerfile-macros.j2" import install_debian_packages, copy_files %} -FROM docker-config-engine-stretch +FROM docker-config-engine-buster ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf @@ -13,15 +13,6 @@ ENV DEBIAN_FRONTEND=noninteractive ## 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 \ @@ -44,5 +35,4 @@ COPY ["critical_processes", "/etc/supervisor"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["/usr/bin/supervisord"] - +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/dockers/docker-nat/critical_processes b/dockers/docker-nat/critical_processes index d442976143f1..5edc5eedc3d5 100644 --- a/dockers/docker-nat/critical_processes +++ b/dockers/docker-nat/critical_processes @@ -1,2 +1,2 @@ -natmgrd -natsyncd +program:natmgrd +program:natsyncd diff --git a/dockers/docker-nat/restore_nat_entries.py b/dockers/docker-nat/restore_nat_entries.py index 9fb62e82f573..cf10d983ab98 100755 --- a/dockers/docker-nat/restore_nat_entries.py +++ b/dockers/docker-nat/restore_nat_entries.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 """" Description: restore_nat_entries.py -- restoring nat entries table into kernel during system warm reboot. @@ -11,25 +11,26 @@ reconciliation process. """ -import sys +import os +import re import subprocess +import sys + +from sonic_py_common.logger import Logger from swsscommon import swsscommon -import logging -import logging.handlers -import re -import os + +SYSLOG_IDENTIFIER = os.path.basename(__file__) WARM_BOOT_FILE_DIR = '/var/warmboot/nat/' NAT_WARM_BOOT_FILE = 'nat_entries.dump' -IP_PROTO_TCP = '6' +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) +# Global logger instance +logger = Logger(SYSLOG_IDENTIFIER) +logger.set_min_log_priority_info() + 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. @@ -37,19 +38,21 @@ def add_nat_conntrack_entry_in_kernel(ipproto, srcip, dstip, srcport, dstport, n 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' + ' --protonum ' + ipproto + state + ' --timeout 432000 --src ' + srcip + ' --sport ' + srcport + \ + ' --dst ' + dstip + ' --dport ' + dstport + ' -u ASSURED' subprocess.call(ctcmd, shell=True) - logger.info("Restored NAT entry: {}".format(ctcmd)) + logger.log_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) + statedb = swsscommon.DBConnector("STATE_DB", 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 @@ -62,11 +65,12 @@ def restore_update_kernel_nat_entries(filename): cmdargs = list(ctline.pop(0)) proto = cmdargs.pop(0) if proto not in ('tcp', 'udp'): - continue + continue add_nat_conntrack_entry_in_kernel(*cmdargs) + def main(): - logger.info("restore_nat_entries service is started") + logger.log_info("restore_nat_entries service is started") # Use warmstart python binding to check warmstart information warmstart = swsscommon.WarmStart() @@ -75,13 +79,13 @@ def main(): # 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") + logger.log_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") + logger.log_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 @@ -89,16 +93,17 @@ def main(): try: restore_update_kernel_nat_entries(WARM_BOOT_FILE_DIR + NAT_WARM_BOOT_FILE) except Exception as e: - logger.exception(str(e)) + logger.log_error(str(e)) sys.exit(1) # Remove the dump file after restoration - os.remove(WARM_BOOT_FILE_DIR + NAT_WARM_BOOT_FILE) + 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") + logger.log_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 index e1f303fee6f2..68603d007a51 100755 --- a/dockers/docker-nat/start.sh +++ b/dockers/docker-nat/start.sh @@ -1,15 +1,5 @@ #!/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 index 839d6f59ab3c..f03b0b3772b8 100644 --- a/dockers/docker-nat/supervisord.conf +++ b/dockers/docker-nat/supervisord.conf @@ -3,27 +3,40 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python3 -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE +buffer_size=25 + [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name nat -events=PROCESS_STATE_EXITED +events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING autostart=true autorestart=unexpected -[program:start.sh] -command=/usr/bin/start.sh +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE priority=1 -autostart=true -autorestart=false +autostart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true -[program:rsyslogd] -command=/usr/sbin/rsyslogd -n +[program:start] +command=/usr/bin/start.sh priority=2 autostart=false -autorestart=unexpected +autorestart=false +startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running [program:natmgrd] command=/usr/bin/natmgrd @@ -32,6 +45,8 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited [program:natsyncd] command=/usr/bin/natsyncd @@ -40,6 +55,8 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=natmgrd:running [program:restore_nat_entries] command=/usr/bin/restore_nat_entries.py @@ -50,4 +67,5 @@ startsecs=0 startretries=0 stdout_logfile=syslog stderr_logfile=syslog - +dependent_startup=true +dependent_startup_wait_for=natsyncd:running diff --git a/dockers/docker-orchagent/Dockerfile.j2 b/dockers/docker-orchagent/Dockerfile.j2 index f95acd48fdbd..17c0983c58b2 100755 --- a/dockers/docker-orchagent/Dockerfile.j2 +++ b/dockers/docker-orchagent/Dockerfile.j2 @@ -1,51 +1,49 @@ {% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} -FROM docker-config-engine-stretch +FROM docker-config-engine-buster 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 +# Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && \ apt-get install -f -y \ ifupdown \ arping \ - libdbus-1-3 \ - libdaemon0 \ - libjansson4 \ - libpython2.7 \ iproute2 \ ndisc6 \ tcpdump \ libelf1 \ libmnl0 \ bridge-utils \ - conntrack + conntrack \ + ndppd \ + # Needed for installing netifaces Python package + build-essential \ + python3-dev {% if ( CONFIGURED_ARCH == "armhf" or CONFIGURED_ARCH == "arm64" ) %} -## Fix for gcc/python not found in arm docker +# Fix for gcc/python not found in arm docker RUN apt-get install -f -y python2.7 python2.7-dev -RUN apt-get install -y gcc-6 +RUN apt-get install -y gcc-8 {% endif %} {% if CONFIGURED_ARCH == "armhf" %} -RUN ln -s -f /usr/bin/gcc-6 /usr/bin/arm-linux-gnueabihf-gcc +RUN ln -s -f /usr/bin/gcc-8 /usr/bin/arm-linux-gnueabihf-gcc {% endif %} {% if CONFIGURED_ARCH == "arm64" %} -RUN ln -s -f /usr/bin/gcc-6 /usr/bin/aarch64-linux-gnu-gcc +RUN ln -s -f /usr/bin/gcc-8 /usr/bin/aarch64-linux-gnu-gcc {% endif %} -RUN pip install \ - scapy==2.4.2 \ - setuptools \ - pyroute2==0.5.3 -RUN pip install \ - netifaces==0.10.7 \ - monotonic==1.5 +# Dependencies of restore_neighbors.py +RUN pip3 install \ + scapy==2.4.4 \ + pyroute2==0.5.14 \ + netifaces==0.10.9 {% if ( CONFIGURED_ARCH == "armhf" or CONFIGURED_ARCH == "arm64" ) %} # Remove installed gcc -RUN apt-get remove -y gcc-6 +RUN apt-get remove -y gcc-8 {% endif %} {% if docker_orchagent_debs.strip() -%} @@ -56,20 +54,25 @@ RUN apt-get remove -y gcc-6 {{ install_debian_packages(docker_orchagent_debs.split(' ')) }} {%- endif %} -## Clean up -RUN apt-get clean -y && \ - apt-get autoclean -y && \ - apt-get autoremove -y && \ +# Clean up +RUN apt-get purge -y \ + build-essential \ + python3-dev && \ + apt-get clean -y && \ + apt-get autoclean -y && \ + apt-get autoremove -y && \ rm -rf /debs COPY ["files/arp_update", "/usr/bin"] +COPY ["arp_update.conf", "files/arp_update_vars.j2", "/usr/share/sonic/templates/"] +COPY ["ndppd.conf", "/usr/share/sonic/templates/"] COPY ["enable_counters.py", "/usr/bin"] -COPY ["start.sh", "orchagent.sh", "swssconfig.sh", "/usr/bin/"] +COPY ["docker-init.sh", "orchagent.sh", "swssconfig.sh", "buffermgrd.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor/"] -## Copy all Jinja2 template files into the templates folder +# Copy all Jinja2 template files into the templates folder COPY ["*.j2", "/usr/share/sonic/templates/"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/bin/docker-init.sh"] diff --git a/dockers/docker-orchagent/arp_update.conf b/dockers/docker-orchagent/arp_update.conf new file mode 100644 index 000000000000..a27a3b391cd2 --- /dev/null +++ b/dockers/docker-orchagent/arp_update.conf @@ -0,0 +1,9 @@ +[program:arp_update] +command=/usr/bin/arp_update +priority=7 +autostart=false +autorestart=unexpected +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=swssconfig:exited diff --git a/dockers/docker-orchagent/base_image_files/monit_swss b/dockers/docker-orchagent/base_image_files/monit_swss index 5928dbd4ddb0..1dcf4bf9b6d9 100644 --- a/dockers/docker-orchagent/base_image_files/monit_swss +++ b/dockers/docker-orchagent/base_image_files/monit_swss @@ -4,6 +4,7 @@ ## orchagent ## portsyncd ## neighsyncd +## fdbsyncd ## vrfmgrd ## vlanmgrd ## intfmgrd @@ -11,33 +12,45 @@ ## 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 +## coppmgrd +## tunnelmgrd + +############################################################################## +check program swss|orchagent with path "/usr/bin/process_checker swss /usr/bin/orchagent -d /var/log/swss" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles + +check program swss|portsyncd with path "/usr/bin/process_checker swss /usr/bin/portsyncd" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles + +check program swss|neighsyncd with path "/usr/bin/process_checker swss /usr/bin/neighsyncd" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles + +check program swss|fdbsyncd with path "/usr/bin/process_checker swss /usr/bin/fdbsyncd" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles -check process portsyncd matching "/usr/bin/portsyncd" - if does not exist for 5 times within 5 cycles then alert +check program swss|vrfmgrd with path "/usr/bin/process_checker swss /usr/bin/vrfmgrd" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles -check process neighsyncd matching "/usr/bin/neighsyncd" - if does not exist for 5 times within 5 cycles then alert +check program swss|vlanmgrd with path "/usr/bin/process_checker swss /usr/bin/vlanmgrd" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles -check process vrfmgrd matching "/usr/bin/vrfmgrd" - if does not exist for 5 times within 5 cycles then alert +check program swss|intfmgrd with path "/usr/bin/process_checker swss /usr/bin/intfmgrd" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles -check process vlanmgrd matching "/usr/bin/vlanmgrd" - if does not exist for 5 times within 5 cycles then alert +check program swss|portmgrd with path "/usr/bin/process_checker swss /usr/bin/portmgrd" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles -check process intfmgrd matching "/usr/bin/intfmgrd" - if does not exist for 5 times within 5 cycles then alert +check program swss|buffermgrd with path "/usr/bin/process_checker swss /usr/bin/buffermgrd -l" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles -check process portmgrd matching "/usr/bin/portmgrd" - if does not exist for 5 times within 5 cycles then alert +check program swss|nbrmgrd with path "/usr/bin/process_checker swss /usr/bin/nbrmgrd" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles -check process buffermgrd matching "/usr/bin/buffermgrd -l" - if does not exist for 5 times within 5 cycles then alert +check program swss|vxlanmgrd with path "/usr/bin/process_checker swss /usr/bin/vxlanmgrd" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles -check process nbrmgrd matching "/usr/bin/nbrmgrd" - if does not exist for 5 times within 5 cycles then alert +check program swss|coppmgrd with path "/usr/bin/process_checker swss /usr/bin/coppmgrd" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles -check process vxlanmgrd matching "/usr/bin/vxlanmgrd" - if does not exist for 5 times within 5 cycles then alert +check program swss|tunnelmgrd with path "/usr/bin/process_checker swss /usr/bin/tunnelmgrd" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/dockers/docker-orchagent/base_image_files/swssloglevel b/dockers/docker-orchagent/base_image_files/swssloglevel index d03685ed383c..533bcb893a02 100755 --- a/dockers/docker-orchagent/base_image_files/swssloglevel +++ b/dockers/docker-orchagent/base_image_files/swssloglevel @@ -1,5 +1,13 @@ #!/bin/bash +# read SONiC immutable variables +[ -f /etc/sonic/sonic-environment ] && . /etc/sonic/sonic-environment + +function help() +{ + echo -e "Usage: $0 -n [0 to $(($NUM_ASIC-1))] [OPTION]... " 1>&2; exit 1; +} + DOCKER_EXEC_FLAGS="i" # Determine whether stdout is on a terminal @@ -7,4 +15,30 @@ if [ -t 1 ] ; then DOCKER_EXEC_FLAGS+="t" fi -docker exec -$DOCKER_EXEC_FLAGS swss swssloglevel "$@" +DEV="" +PLATFORM=${PLATFORM:-`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform`} + +# Parse the device specific asic conf file, if it exists +ASIC_CONF=/usr/share/sonic/device/$PLATFORM/asic.conf +[ -f $ASIC_CONF ] && . $ASIC_CONF + +if [[ ($NUM_ASIC -gt 1) ]]; then + while getopts ":n:h:" opt; do + case "${opt}" in + h) help + ;; + n) DEV=${OPTARG} + [ $DEV -lt $NUM_ASIC -a $DEV -ge 0 ] || help + ;; + esac + done + + if [ -z "${DEV}" ]; then + help + fi + + # Skip the arguments -n while passing to docker command + shift 2 +fi + +docker exec -$DOCKER_EXEC_FLAGS swss$DEV swssloglevel "$@" diff --git a/dockers/docker-orchagent/buffermgrd.sh b/dockers/docker-orchagent/buffermgrd.sh new file mode 100755 index 000000000000..1d09cfc7d6ee --- /dev/null +++ b/dockers/docker-orchagent/buffermgrd.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +BUFFER_CALCULATION_MODE=$(redis-cli -n 4 hget "DEVICE_METADATA|localhost" buffer_model) + +if [ "$BUFFER_CALCULATION_MODE" == "dynamic" ]; then + if [ -f /etc/sonic/peripheral_table.json ]; then + BUFFERMGRD_ARGS="-a /etc/sonic/asic_table.json -p /etc/sonic/peripheral_table.json" + else + BUFFERMGRD_ARGS="-a /etc/sonic/asic_table.json" + fi +else + # Should we use the fallback MAC in case it is not found in Device.Metadata + BUFFERMGRD_ARGS="-l /usr/share/sonic/hwsku/pg_profile_lookup.ini" +fi + +exec /usr/bin/buffermgrd ${BUFFERMGRD_ARGS} diff --git a/dockers/docker-orchagent/critical_processes b/dockers/docker-orchagent/critical_processes index 7fd8a516520c..a650bdca2a93 100644 --- a/dockers/docker-orchagent/critical_processes +++ b/dockers/docker-orchagent/critical_processes @@ -1,10 +1,13 @@ -orchagent -portsyncd -neighsyncd -vlanmgrd -intfmgrd -portmgrd -buffermgrd -vrfmgrd -nbrmgrd -vxlanmgrd +program:orchagent +program:portsyncd +program:neighsyncd +program:fdbsyncd +program:vlanmgrd +program:intfmgrd +program:portmgrd +program:buffermgrd +program:vrfmgrd +program:nbrmgrd +program:vxlanmgrd +program:coppmgrd +program:tunnelmgrd diff --git a/dockers/docker-orchagent/docker-init.sh b/dockers/docker-orchagent/docker-init.sh new file mode 100755 index 000000000000..5bf5bf2d06cf --- /dev/null +++ b/dockers/docker-orchagent/docker-init.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +mkdir -p /etc/swss/config.d/ + +CFGGEN_PARAMS=" \ + -d \ + -y /etc/sonic/constants.yml \ + -t /usr/share/sonic/templates/switch.json.j2,/etc/swss/config.d/switch.json \ + -t /usr/share/sonic/templates/ipinip.json.j2,/etc/swss/config.d/ipinip.json \ + -t /usr/share/sonic/templates/ports.json.j2,/etc/swss/config.d/ports.json \ + -t /usr/share/sonic/templates/vlan_vars.j2 \ + -t /usr/share/sonic/templates/ndppd.conf.j2,/etc/ndppd.conf \ +" +VLAN=$(sonic-cfggen $CFGGEN_PARAMS) + +# Executed HWSKU specific initialization tasks. +if [ -x /usr/share/sonic/hwsku/hwsku-init ]; then + /usr/share/sonic/hwsku/hwsku-init +fi + +# Start arp_update and NDP proxy daemon when VLAN exists +if [ "$VLAN" != "" ]; then + cp /usr/share/sonic/templates/arp_update.conf /etc/supervisor/conf.d/ + cp /usr/share/sonic/templates/ndppd.conf /etc/supervisor/conf.d/ +fi + +exec /usr/local/bin/supervisord diff --git a/dockers/docker-orchagent/enable_counters.py b/dockers/docker-orchagent/enable_counters.py index 75f8ef82cb4c..5455f5923571 100755 --- a/dockers/docker-orchagent/enable_counters.py +++ b/dockers/docker-orchagent/enable_counters.py @@ -1,26 +1,51 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 -import swsssdk import time +import swsssdk + +# ALPHA defines the size of the window over which we calculate the average value. ALPHA is 2/(N+1) where N is the interval(window size) +# In this case we configure the window to be 10s. This way if we have a huge 1s spike in traffic, +# the average rate value will show a curve descending from the spike to the usual rate over approximately 10s. +DEFAULT_SMOOTH_INTERVAL = '10' +DEFAULT_ALPHA = '0.18' + def enable_counter_group(db, name): info = {} info['FLEX_COUNTER_STATUS'] = 'enable' db.mod_entry("FLEX_COUNTER_TABLE", name, info) + +def enable_rates(): + # set the default interval for rates + counters_db = swsssdk.SonicV2Connector() + counters_db.connect('COUNTERS_DB') + counters_db.set('COUNTERS_DB', 'RATES:PORT', 'PORT_SMOOTH_INTERVAL', DEFAULT_SMOOTH_INTERVAL) + counters_db.set('COUNTERS_DB', 'RATES:PORT', 'PORT_ALPHA', DEFAULT_ALPHA) + counters_db.set('COUNTERS_DB', 'RATES:RIF', 'RIF_SMOOTH_INTERVAL', DEFAULT_SMOOTH_INTERVAL) + counters_db.set('COUNTERS_DB', 'RATES:RIF', 'RIF_ALPHA', DEFAULT_ALPHA) + + def enable_counters(): db = swsssdk.ConfigDBConnector() db.connect() enable_counter_group(db, 'PORT') + enable_counter_group(db, 'RIF') enable_counter_group(db, 'QUEUE') enable_counter_group(db, 'PFCWD') enable_counter_group(db, 'PG_WATERMARK') + enable_counter_group(db, 'PG_DROP') enable_counter_group(db, 'QUEUE_WATERMARK') + enable_counter_group(db, 'BUFFER_POOL_WATERMARK') + enable_counter_group(db, 'PORT_BUFFER_DROP') + enable_rates() + def get_uptime(): with open('/proc/uptime') as fp: return float(fp.read().split(' ')[0]) + def main(): # If the switch was just started (uptime less than 5 minutes), # wait for 3 minutes and enable counters @@ -32,5 +57,6 @@ def main(): time.sleep(60) enable_counters() + if __name__ == '__main__': main() diff --git a/dockers/docker-orchagent/ipinip.json.j2 b/dockers/docker-orchagent/ipinip.json.j2 index 66bec75da7dc..cbfeb784b057 100644 --- a/dockers/docker-orchagent/ipinip.json.j2 +++ b/dockers/docker-orchagent/ipinip.json.j2 @@ -2,12 +2,17 @@ {% set ipv6_addresses = [] %} {% set ipv4_loopback_addresses = [] %} {% set ipv6_loopback_addresses = [] %} +{% if DEVICE_METADATA['localhost']['sub_role'] == 'FrontEnd' or DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd'%} +{% set loopback_intf_names = ['Loopback0', 'Loopback4096'] %} +{% else %} +{% set loopback_intf_names = ['Loopback0'] %} +{% endif %} {% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} - {%- if prefix | ipv4 and name == 'Loopback0' %} + {%- if prefix | ipv4 and name in loopback_intf_names %} {%- set ipv4_addresses = ipv4_addresses.append(prefix) %} {%- set ipv4_loopback_addresses = ipv4_loopback_addresses.append(prefix) %} {%- endif %} - {%- if prefix | ipv6 and name == 'Loopback0' %} + {%- if prefix | ipv6 and name in loopback_intf_names %} {%- set ipv6_addresses = ipv6_addresses.append(prefix) %} {%- set ipv6_loopback_addresses = ipv6_loopback_addresses.append(prefix) %} {%- endif %} @@ -41,19 +46,18 @@ { "TUNNEL_DECAP_TABLE:IPINIP_TUNNEL" : { "tunnel_type":"IPINIP", + "dst_ip":"{% for prefix in ipv4_addresses|sort %}{{ prefix | ip }}{% if not loop.last %},{% endif %}{% endfor %}", {% if "mlnx" in DEVICE_METADATA.localhost.platform %} - "dst_ip":"{% for prefix in ipv4_loopback_addresses %}{{ prefix | ip }}{% if not loop.last %},{% endif %}{% endfor %}", "dscp_mode":"uniform", "ecn_mode":"standard", {% else %} - "dst_ip":"{% for prefix in ipv4_addresses %}{{ prefix | ip }}{% if not loop.last %},{% endif %}{% endfor %}", "dscp_mode":"pipe", "ecn_mode":"copy_from_outer", {% endif %} "ttl_mode":"pipe" }, "OP": "SET" - } + } {% endif %} {% if ipv4_loopback_addresses and ipv6_loopback_addresses %} , {% endif %} @@ -61,12 +65,11 @@ { "TUNNEL_DECAP_TABLE:IPINIP_V6_TUNNEL" : { "tunnel_type":"IPINIP", + "dst_ip":"{% for prefix in ipv6_addresses|sort %}{{ prefix | ip }}{% if not loop.last %},{% endif %}{% endfor %}", {% if "mlnx" in DEVICE_METADATA.localhost.platform %} - "dst_ip":"{% for prefix in ipv6_loopback_addresses %}{{ prefix | ip }}{% if not loop.last %},{% endif %}{% endfor %}", "dscp_mode":"uniform", "ecn_mode":"standard", {% else %} - "dst_ip":"{% for prefix in ipv6_addresses %}{{ prefix | ip }}{% if not loop.last %},{% endif %}{% endfor %}", "dscp_mode":"pipe", "ecn_mode":"copy_from_outer", {% endif %} diff --git a/dockers/docker-orchagent/ndppd.conf b/dockers/docker-orchagent/ndppd.conf new file mode 100644 index 000000000000..1e97bf97e313 --- /dev/null +++ b/dockers/docker-orchagent/ndppd.conf @@ -0,0 +1,9 @@ +[program:ndppd] +command=bash -c "/usr/sbin/ndppd | /usr/bin/logger" +priority=7 +autostart=false +autorestart=unexpected +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=swssconfig:exited \ No newline at end of file diff --git a/dockers/docker-orchagent/ndppd.conf.j2 b/dockers/docker-orchagent/ndppd.conf.j2 new file mode 100644 index 000000000000..bc375f3c4987 --- /dev/null +++ b/dockers/docker-orchagent/ndppd.conf.j2 @@ -0,0 +1,37 @@ +{% block banner %} +# =========== Managed by sonic-cfggen -- DO NOT edit manually! ==================== +# Generated by /usr/share/sonic/templates/ndppd.conf.j2 using config DB data +# File: /etc/ndppd.conf +# +{% endblock banner %} +# Config file for ndppd, the NDP Proxy Daemon +# See man page for ndppd.conf.5 for descriptions of all available options +{% if VLAN_INTERFACE and VLAN_INTERFACE|pfx_filter|length > 0%} +{# Get all VLAN interfaces that have proxy_arp enabled #} +{% set proxy_interfaces = {} %} +{% for intf in VLAN_INTERFACE %} +{% if "proxy_arp" in VLAN_INTERFACE[intf] and VLAN_INTERFACE[intf]["proxy_arp"] == "enabled" %} +{% set _x = proxy_interfaces.update({intf: []}) %} +{% endif %} +{% endfor -%} + +{# Add each IPv6 prefix from each proxy_arp interface #} +{% for (intf, prefix) in VLAN_INTERFACE|pfx_filter %} +{% if intf in proxy_interfaces and prefix | ipv6 %} +{% set _x = proxy_interfaces[intf].append(prefix) %} +{% endif %} +{% endfor -%} + +{% for intf, prefix_list in proxy_interfaces.items() %} +{% if prefix_list %} + +proxy {{ intf }} { +{% for prefix in prefix_list %} + rule {{ prefix | network }}/{{ prefix | prefixlen }} { + static + } +{% endfor %} +} +{% endif %} +{% endfor %} +{% endif %} \ No newline at end of file diff --git a/dockers/docker-orchagent/orchagent.sh b/dockers/docker-orchagent/orchagent.sh index 3352e5fbb7ec..aaa047a42036 100755 --- a/dockers/docker-orchagent/orchagent.sh +++ b/dockers/docker-orchagent/orchagent.sh @@ -1,10 +1,12 @@ #!/usr/bin/env bash -# Export platform information. Required to be able to write -# vendor specific code. -export platform=`sonic-cfggen -y /etc/sonic/sonic_version.yml -v asic_type` +SWSS_VARS_FILE=/usr/share/sonic/templates/swss_vars.j2 -MAC_ADDRESS=$(sonic-cfggen -d -v 'DEVICE_METADATA.localhost.mac') +# Retrieve SWSS vars from sonic-cfggen +SWSS_VARS=$(sonic-cfggen -d -y /etc/sonic/sonic_version.yml -t $SWSS_VARS_FILE) || exit 1 +export platform=$(echo $SWSS_VARS | jq -r '.asic_type') + +MAC_ADDRESS=$(echo $SWSS_VARS | jq -r '.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" @@ -17,6 +19,33 @@ ORCHAGENT_ARGS="-d /var/log/swss " # Set orchagent pop batch size to 8192 ORCHAGENT_ARGS+="-b 8192 " +# Set synchronous mode if it is enabled in CONFIG_DB +SYNC_MODE=$(echo $SWSS_VARS | jq -r '.synchronous_mode') +if [ "$SYNC_MODE" == "enable" ]; then + ORCHAGENT_ARGS+="-s " +fi + +# Check if there is an "asic_id field" in the DEVICE_METADATA in configDB. +#"DEVICE_METADATA": { +# "localhost": { +# .... +# "asic_id": "0", +# } +#}, +# ID field could be integers just to denote the asic instance like 0,1,2... +# OR could be PCI device ID's which will be strings like "03:00.0" +# depending on what the SAI/SDK expects. +asic_id=$(echo $SWSS_VARS | jq -r '.asic_id') +if [ -n "$asic_id" ] +then + ORCHAGENT_ARGS+="-i $asic_id " +fi + +# for multi asic platforms add the asic name to the record file names +if [[ "$NAMESPACE_ID" ]]; then + ORCHAGENT_ARGS+="-f swss.asic$NAMESPACE_ID.rec -j sairedis.asic$NAMESPACE_ID.rec " +fi + # Add platform specific arguments if necessary if [ "$platform" == "broadcom" ]; then ORCHAGENT_ARGS+="-m $MAC_ADDRESS" @@ -25,10 +54,7 @@ elif [ "$platform" == "cavium" ]; then elif [ "$platform" == "nephos" ]; then ORCHAGENT_ARGS+="-m $MAC_ADDRESS" elif [ "$platform" == "centec" ]; then - last_byte=$(python -c "print '$MAC_ADDRESS'[-2:]") - aligned_last_byte=$(python -c "print format(int(int('$last_byte', 16) + 1), '02x')") # put mask and take away the 0x prefix - ALIGNED_MAC_ADDRESS=$(python -c "print '$MAC_ADDRESS'[:-2] + '$aligned_last_byte'") # put aligned byte into the end of MAC - ORCHAGENT_ARGS+="-m $ALIGNED_MAC_ADDRESS" + ORCHAGENT_ARGS+="-m $MAC_ADDRESS" elif [ "$platform" == "barefoot" ]; then ORCHAGENT_ARGS+="-m $MAC_ADDRESS" elif [ "$platform" == "vs" ]; then @@ -38,7 +64,7 @@ elif [ "$platform" == "mellanox" ]; then elif [ "$platform" == "innovium" ]; then ORCHAGENT_ARGS+="-m $MAC_ADDRESS" else - MAC_ADDRESS=`sonic-cfggen -d -v 'DEVICE_METADATA.localhost.mac'` + # Should we use the fallback MAC in case it is not found in Device.Metadata ORCHAGENT_ARGS+="-m $MAC_ADDRESS" fi diff --git a/dockers/docker-orchagent/ports.json.j2 b/dockers/docker-orchagent/ports.json.j2 index b10d4d58a43d..296d97cde07b 100644 --- a/dockers/docker-orchagent/ports.json.j2 +++ b/dockers/docker-orchagent/ports.json.j2 @@ -2,7 +2,7 @@ {% set ports_with_speed_set=[] %} {% if PORT %} {% for port in PORT %} -{% if PORT[port].has_key('speed') %} +{% if 'speed' in PORT[port] %} {%- if ports_with_speed_set.append(port) -%}{%- endif -%} {%- endif -%} {% endfor %} diff --git a/dockers/docker-orchagent/start.sh b/dockers/docker-orchagent/start.sh deleted file mode 100755 index b7357ad58f67..000000000000 --- a/dockers/docker-orchagent/start.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env bash - -mkdir -p /etc/swss/config.d/ - -sonic-cfggen -d -y /etc/sonic/sonic_version.yml -t /usr/share/sonic/templates/switch.json.j2 > /etc/swss/config.d/switch.json -sonic-cfggen -d -t /usr/share/sonic/templates/ipinip.json.j2 > /etc/swss/config.d/ipinip.json -sonic-cfggen -d -t /usr/share/sonic/templates/ports.json.j2 > /etc/swss/config.d/ports.json - -# Executed HWSKU specific initialization tasks. -if [ -x /usr/share/sonic/hwsku/hwsku-init ]; then - /usr/share/sonic/hwsku/hwsku-init -fi - -export platform=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` - -rm -f /var/run/rsyslogd.pid - -supervisorctl start rsyslogd - -supervisorctl start orchagent - -supervisorctl start restore_neighbors - -supervisorctl start portsyncd - -supervisorctl start neighsyncd - -supervisorctl start swssconfig - -supervisorctl start vrfmgrd - -supervisorctl start vlanmgrd - -supervisorctl start intfmgrd - -supervisorctl start portmgrd - -supervisorctl start buffermgrd - -supervisorctl start enable_counters - -supervisorctl start nbrmgrd - -supervisorctl start vxlanmgrd - -# Start arp_update when VLAN exists -VLAN=`sonic-cfggen -d -v 'VLAN.keys() | join(" ") if VLAN'` -if [ "$VLAN" != "" ]; then - supervisorctl start arp_update -fi diff --git a/dockers/docker-orchagent/supervisord.conf b/dockers/docker-orchagent/supervisord.conf index 6b21d73f3c81..af68c8c38ab7 100644 --- a/dockers/docker-orchagent/supervisord.conf +++ b/dockers/docker-orchagent/supervisord.conf @@ -3,69 +3,107 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true -[eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener --container-name swss -events=PROCESS_STATE_EXITED +[eventlistener:dependent-startup] +command=python3 -m supervisord_dependent_startup autostart=true autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE +buffer_size=100 -[program:start.sh] -command=/usr/bin/start.sh -priority=1 +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name swss +events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING autostart=true -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog +autorestart=unexpected [program:rsyslogd] -command=/usr/sbin/rsyslogd -n -priority=2 +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 autostart=false autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true -[program:orchagent] -command=/usr/bin/orchagent.sh +[program:gearsyncd] +command=/usr/bin/gearsyncd -p /usr/share/sonic/hwsku/gearbox_config.json priority=3 autostart=false autorestart=false +startsecs=0 +startretries=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running [program:portsyncd] command=/usr/bin/portsyncd -priority=4 +priority=3 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running -[program:neighsyncd] -command=/usr/bin/neighsyncd -priority=5 +[program:orchagent] +command=/usr/bin/orchagent.sh +priority=4 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=portsyncd:running [program:swssconfig] command=/usr/bin/swssconfig.sh -priority=6 +priority=5 autostart=false autorestart=unexpected startretries=0 startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=orchagent:running + +[program:restore_neighbors] +command=/usr/bin/restore_neighbors.py +priority=6 +autostart=false +autorestart=false +startsecs=0 +startretries=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=swssconfig:exited -[program:arp_update] -command=/usr/bin/arp_update +[program:coppmgrd] +command=/usr/bin/coppmgrd +priority=6 +autostart=false +autorestart=false +startretries=0 +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=orchagent:running + +[program:neighsyncd] +command=/usr/bin/neighsyncd priority=7 autostart=false -autorestart=unexpected +autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=swssconfig:exited [program:vlanmgrd] command=/usr/bin/vlanmgrd @@ -74,6 +112,8 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=swssconfig:exited [program:intfmgrd] command=/usr/bin/intfmgrd @@ -82,6 +122,8 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=swssconfig:exited [program:portmgrd] command=/usr/bin/portmgrd @@ -90,53 +132,76 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=swssconfig:exited [program:buffermgrd] -command=/usr/bin/buffermgrd -l /usr/share/sonic/hwsku/pg_profile_lookup.ini +command=/usr/bin/buffermgrd.sh priority=11 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=swssconfig:exited -[program:enable_counters] -command=/usr/bin/enable_counters.py -priority=12 +[program:vrfmgrd] +command=/usr/bin/vrfmgrd +priority=13 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=swssconfig:exited -[program:vrfmgrd] -command=/usr/bin/vrfmgrd -priority=13 +[program:nbrmgrd] +command=/usr/bin/nbrmgrd +priority=15 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=swssconfig:exited -[program:restore_neighbors] -command=/usr/bin/restore_neighbors.py -priority=14 +[program:vxlanmgrd] +command=/usr/bin/vxlanmgrd +priority=16 autostart=false autorestart=false -startsecs=0 -startretries=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=swssconfig:exited -[program:nbrmgrd] -command=/usr/bin/nbrmgrd -priority=15 +[program:tunnelmgrd] +command=/usr/bin/tunnelmgrd +priority=17 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=swssconfig:exited -[program:vxlanmgrd] -command=/usr/bin/vxlanmgrd -priority=16 +[program:enable_counters] +command=/usr/bin/enable_counters.py +priority=12 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=swssconfig:exited + +[program:fdbsyncd] +command=/usr/bin/fdbsyncd +priority=17 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=swssconfig:exited + diff --git a/dockers/docker-orchagent/switch.json.j2 b/dockers/docker-orchagent/switch.json.j2 index f8beffbc9ad7..4d2a0be1b051 100644 --- a/dockers/docker-orchagent/switch.json.j2 +++ b/dockers/docker-orchagent/switch.json.j2 @@ -1,20 +1,25 @@ {# the range of hash_seed is 0-15 #} {# set default hash seed to 0 #} {% set hash_seed = 0 %} +{% set hash_seed_offset = 0 %} {% if DEVICE_METADATA.localhost.type %} -{% if DEVICE_METADATA.localhost.type == "ToRRouter" %} +{% if "ToRRouter" in DEVICE_METADATA.localhost.type %} {% set hash_seed = 0 %} -{% elif DEVICE_METADATA.localhost.type == "LeafRouter" %} +{% elif "LeafRouter" in DEVICE_METADATA.localhost.type %} {% set hash_seed = 10 %} -{% elif DEVICE_METADATA.localhost.type == "SpineRouter" %} -{% set hash_seed = 15 %} +{% elif "SpineRouter" in DEVICE_METADATA.localhost.type %} +{% set hash_seed = 25 %} {% endif %} {% endif %} +{% if DEVICE_METADATA.localhost.namespace_id %} +{% set hash_seed_offset = DEVICE_METADATA.localhost.namespace_id | int %} +{% endif %} +{% set hash_seed_value = hash_seed_offset + hash_seed %} [ { "SWITCH_TABLE:switch": { - "ecmp_hash_seed": "{{ hash_seed }}", - "lag_hash_seed": "{{ hash_seed }}", + "ecmp_hash_seed": "{{ hash_seed_value }}", + "lag_hash_seed": "{{ hash_seed_value }}", "fdb_aging_time": "600" }, "OP": "SET" diff --git a/dockers/docker-orchagent/swssconfig.sh b/dockers/docker-orchagent/swssconfig.sh index 856b3bcd0e41..0081d074ad60 100755 --- a/dockers/docker-orchagent/swssconfig.sh +++ b/dockers/docker-orchagent/swssconfig.sh @@ -8,19 +8,19 @@ function fast_reboot { if [[ -f /fdb.json ]]; then swssconfig /fdb.json - rm -f /fdb.json + mv -f /fdb.json /fdb.json.1 fi if [[ -f /arp.json ]]; then swssconfig /arp.json - rm -f /arp.json + mv -f /arp.json /arp.json.1 fi if [[ -f /default_routes.json ]]; then swssconfig /default_routes.json - rm -f /default_routes.json + mv -f /default_routes.json /default_routes.json.1 fi ;; @@ -39,21 +39,20 @@ rm -f /ready # Restore FDB and ARP table ASAP fast_reboot -HWSKU=`sonic-cfggen -d -v "DEVICE_METADATA['localhost']['hwsku']"` +# read SONiC immutable variables +[ -f /etc/sonic/sonic-environment ] && . /etc/sonic/sonic-environment + +HWSKU=${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=`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=`sonic-db-cli STATE_DB hget "WARM_RESTART_TABLE|orchagent" restore_count` - if [[ -n "$RESTORE_COUNT" ]] && [[ "$RESTORE_COUNT" != "0" ]]; then - exit 0 - fi + exit 0 fi -SWSSCONFIG_ARGS="00-copp.config.json ipinip.json ports.json switch.json " +SWSSCONFIG_ARGS="ipinip.json ports.json switch.json " for file in $SWSSCONFIG_ARGS; do swssconfig /etc/swss/config.d/$file diff --git a/dockers/docker-orchagent/vlan_vars.j2 b/dockers/docker-orchagent/vlan_vars.j2 new file mode 100644 index 000000000000..55db548043a3 --- /dev/null +++ b/dockers/docker-orchagent/vlan_vars.j2 @@ -0,0 +1 @@ +{%- if VLAN -%}{{- VLAN.keys() | join(' ') -}}{%- endif -%} diff --git a/dockers/docker-platform-monitor/Dockerfile.j2 b/dockers/docker-platform-monitor/Dockerfile.j2 index fd11f628559c..fc46dc6a52b9 100755 --- a/dockers/docker-platform-monitor/Dockerfile.j2 +++ b/dockers/docker-platform-monitor/Dockerfile.j2 @@ -1,24 +1,50 @@ {% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} -FROM docker-config-engine-stretch +FROM docker-config-engine-buster ARG docker_container_name +ARG image_version 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 +# Pass the image_version to container +ENV IMAGE_VERSION=$image_version + # Install required packages RUN apt-get update && \ apt-get install -y \ - python-pip \ - libpython2.7 \ + build-essential \ + python3-dev \ ipmitool \ librrd8 \ librrd-dev \ rrdtool \ python-smbus \ + python3-smbus \ ethtool \ - dmidecode + dmidecode \ + i2c-tools + +# TODO: Remove these lines once we no longer need Python 2 +RUN apt-get install -f -y python-dev python-pip +RUN pip2 install --upgrade 'pip<21' +RUN apt-get purge -y python-pip +RUN pip2 install 'setuptools==40.8.0' + +# On Arista devices, the sonic_platform wheel is not installed in the container. +# Instead, the installation directory is mounted from the host OS. However, this method +# doesn't ensure all dependencies are installed in the container. So here we +# install any dependencies required by the Arista sonic_platform package. +# TODO: eliminate the need to install these explicitly. +# NOTE: Only install enum34 for Python 2, as our version of Python 3 is 3.7, which +# contains 'enum' as part of the standard library. Installing enum34 there will +# cause conflicts. +RUN pip2 install enum34 + +# Barefoot platform vendors' sonic_platform packages import the Python 'thrift' library +RUN pip2 install thrift==0.13.0 +RUN pip3 install thrift==0.13.0 {% if docker_platform_monitor_debs.strip() -%} # Copy locally-built Debian package dependencies @@ -44,9 +70,14 @@ RUN apt-get update && \ {{ install_python_wheels(docker_platform_monitor_whls.split(' ')) }} {% endif %} + +# TODO: Remove this line once we no longer need Python 2 +RUN apt-get purge -y python-dev + # Clean up RUN apt-get purge -y \ - python-pip && \ + build-essential \ + python3-dev && \ apt-get clean -y && \ apt-get autoclean -y && \ apt-get autoremove -y && \ @@ -55,7 +86,7 @@ RUN apt-get purge -y \ ~/.cache COPY ["docker_init.sh", "lm-sensors.sh", "/usr/bin/"] -COPY ["docker-pmon.supervisord.conf.j2", "start.sh.j2", "/usr/share/sonic/templates/"] +COPY ["docker-pmon.supervisord.conf.j2", "/usr/share/sonic/templates/"] COPY ["ssd_tools/*", "/usr/bin/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor"] diff --git a/dockers/docker-platform-monitor/critical_processes b/dockers/docker-platform-monitor/critical_processes index 4233cda34982..3165d13ecdbc 100644 --- a/dockers/docker-platform-monitor/critical_processes +++ b/dockers/docker-platform-monitor/critical_processes @@ -1,5 +1,3 @@ -fancontrol -ledd -xcvrd -psud -syseepromd +program:ledd +program:xcvrd +program:psud diff --git a/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 b/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 index ca5e521abec9..c205d3cc25dc 100644 --- a/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 +++ b/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 @@ -3,29 +3,44 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python3 -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE +buffer_size=100 + [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name pmon -events=PROCESS_STATE_EXITED +events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING autostart=true autorestart=unexpected -[program:start.sh] -command=/usr/bin/start.sh +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE priority=1 -autostart=true +autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog -startsecs=0 +dependent_startup=true -[program:rsyslogd] -command=/usr/sbin/rsyslogd -n -priority=2 +{% if not skip_chassisd and IS_MODULAR_CHASSIS == 1 %} +[program:chassisd] +command=/usr/local/bin/chassisd +priority=3 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +startsecs=0 +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running +{% endif %} +{% if not skip_sensors and HAVE_SENSORS_CONF == 1 %} [program:lm-sensors] command=/usr/bin/lm-sensors.sh priority=3 @@ -34,66 +49,102 @@ autorestart=false stdout_logfile=syslog stderr_logfile=syslog startsecs=0 +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running +{% endif %} +{% if not skip_fancontrol and HAVE_FANCONTROL_CONF == 1 %} [program:fancontrol] command=/usr/sbin/fancontrol priority=4 autostart=false -autorestart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog +startsecs=10 +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running +{% endif %} {% if not skip_ledd %} [program:ledd] -command=/usr/bin/ledd +command={% if API_VERSION == 3 and 'ledd' not in python2_daemons %}python3 {% else %} python2 {% endif %}/usr/local/bin/ledd priority=5 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog startsecs=0 +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running {% endif %} {% if not skip_xcvrd %} [program:xcvrd] -command=/usr/bin/xcvrd +{% if delay_xcvrd %} +command=bash -c "sleep 30 && {% if API_VERSION == 3 and 'xcvrd' not in python2_daemons %}python3 {% else %} python2 {% endif %}/usr/local/bin/xcvrd" +{% else %} +command={% if API_VERSION == 3 and 'xcvrd' not in python2_daemons %}python3 {% else %} python2 {% endif %}/usr/local/bin/xcvrd +{% endif %} priority=6 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog startsecs=0 +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running {% endif %} {% if not skip_psud %} [program:psud] -command=/usr/bin/psud +command={% if API_VERSION == 3 and 'psud' not in python2_daemons %}python3 {% else %} python2 {% endif %}/usr/local/bin/psud priority=7 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog startsecs=0 +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running {% endif %} {% if not skip_syseepromd %} [program:syseepromd] -command=/usr/bin/syseepromd +command={% if API_VERSION == 3 and 'syseepromd' not in python2_daemons %}python3 {% else %} python2 {% endif %}/usr/local/bin/syseepromd priority=8 autostart=false -autorestart=true +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog -startsecs=0 +startsecs=10 +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running {% endif %} {% if not skip_thermalctld %} [program:thermalctld] -command=/usr/bin/thermalctld +command={% if API_VERSION == 3 and 'thermalctld' not in python2_daemons %}python3 {% else %} python2 {% endif %}/usr/local/bin/thermalctld priority=9 autostart=false -autorestart=true +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog -startsecs=0 +startsecs=10 +startretries=50 +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running +{% endif %} + +{% if not skip_pcied %} +[program:pcied] +command=/usr/local/bin/pcied +priority=10 +autostart=false +autorestart=unexpected +stdout_logfile=syslog +stderr_logfile=syslog +startsecs=10 +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running {% endif %} diff --git a/dockers/docker-platform-monitor/docker_init.sh b/dockers/docker-platform-monitor/docker_init.sh index a2be49f49dd3..6fc7ffeb5114 100755 --- a/dockers/docker-platform-monitor/docker_init.sh +++ b/dockers/docker-platform-monitor/docker_init.sh @@ -3,16 +3,104 @@ # Generate supervisord config file and the start.sh scripts mkdir -p /etc/supervisor/conf.d/ -if [ -e /usr/share/sonic/platform/pmon_daemon_control.json ]; +SENSORS_CONF_FILE="/usr/share/sonic/platform/sensors.conf" +FANCONTROL_CONF_FILE="/usr/share/sonic/platform/fancontrol" + +SUPERVISOR_CONF_TEMPLATE="/usr/share/sonic/templates/docker-pmon.supervisord.conf.j2" +SUPERVISOR_CONF_FILE="/etc/supervisor/conf.d/supervisord.conf" +PMON_DAEMON_CONTROL_FILE="/usr/share/sonic/platform/pmon_daemon_control.json" +MODULAR_CHASSISDB_CONF_FILE="/usr/share/sonic/platform/chassisdb.conf" + +HAVE_SENSORS_CONF=0 +HAVE_FANCONTROL_CONF=0 +IS_MODULAR_CHASSIS=0 +# Default use python2 version +SONIC_PLATFORM_API_PYTHON_VERSION=2 + +declare -r EXIT_SUCCESS="0" + +if [ "${RUNTIME_OWNER}" == "" ]; then + RUNTIME_OWNER="kube" +fi + +CTR_SCRIPT="/usr/share/sonic/scripts/container_startup.py" +if test -f ${CTR_SCRIPT} then - sonic-cfggen -j /usr/share/sonic/platform/pmon_daemon_control.json -t /usr/share/sonic/templates/docker-pmon.supervisord.conf.j2 > /etc/supervisor/conf.d/supervisord.conf - sonic-cfggen -j /usr/share/sonic/platform/pmon_daemon_control.json -t /usr/share/sonic/templates/start.sh.j2 > /usr/bin/start.sh - chmod +x /usr/bin/start.sh + ${CTR_SCRIPT} -f pmon -o ${RUNTIME_OWNER} -v ${IMAGE_VERSION} +fi + +mkdir -p /var/sonic +echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status + +# If this platform has synchronization script, run it +if [ -e /usr/share/sonic/platform/platform_wait ]; then + /usr/share/sonic/platform/platform_wait + EXIT_CODE="$?" + if [ "${EXIT_CODE}" != "${EXIT_SUCCESS}" ]; then + exit "${EXIT_CODE}" + fi +fi + +# If the Python 2 sonic-platform package is not installed, try to install it +python2 -c "import sonic_platform" > /dev/null 2>&1 || pip2 show sonic-platform > /dev/null 2>&1 +if [ $? -ne 0 ]; then + SONIC_PLATFORM_WHEEL="/usr/share/sonic/platform/sonic_platform-1.0-py2-none-any.whl" + echo "sonic-platform package not installed, attempting to install..." + if [ -e ${SONIC_PLATFORM_WHEEL} ]; then + pip2 install ${SONIC_PLATFORM_WHEEL} + if [ $? -eq 0 ]; then + echo "Successfully installed ${SONIC_PLATFORM_WHEEL}" + else + echo "Error: Failed to install ${SONIC_PLATFORM_WHEEL}" + fi + else + echo "Error: Unable to locate ${SONIC_PLATFORM_WHEEL}" + fi +fi + +# If the Python 3 sonic-platform package is not installed, try to install it +python3 -c "import sonic_platform" > /dev/null 2>&1 || pip3 show sonic-platform > /dev/null 2>&1 +if [ $? -ne 0 ]; then + SONIC_PLATFORM_WHEEL="/usr/share/sonic/platform/sonic_platform-1.0-py3-none-any.whl" + echo "sonic-platform package not installed, attempting to install..." + if [ -e ${SONIC_PLATFORM_WHEEL} ]; then + pip3 install ${SONIC_PLATFORM_WHEEL} + if [ $? -eq 0 ]; then + echo "Successfully installed ${SONIC_PLATFORM_WHEEL}" + SONIC_PLATFORM_API_PYTHON_VERSION=3 + else + echo "Error: Failed to install ${SONIC_PLATFORM_WHEEL}" + fi + else + echo "Error: Unable to locate ${SONIC_PLATFORM_WHEEL}" + fi else - sonic-cfggen -t /usr/share/sonic/templates/docker-pmon.supervisord.conf.j2 > /etc/supervisor/conf.d/supervisord.conf - sonic-cfggen -t /usr/share/sonic/templates/start.sh.j2 > /usr/bin/start.sh - chmod +x /usr/bin/start.sh + SONIC_PLATFORM_API_PYTHON_VERSION=3 +fi + +if [ -e $SENSORS_CONF_FILE ]; then + HAVE_SENSORS_CONF=1 + mkdir -p /etc/sensors.d + /bin/cp -f $SENSORS_CONF_FILE /etc/sensors.d/ fi -exec /usr/bin/supervisord +if [ -e $FANCONTROL_CONF_FILE ]; then + HAVE_FANCONTROL_CONF=1 + rm -f /var/run/fancontrol.pid + /bin/cp -f $FANCONTROL_CONF_FILE /etc/ +fi + +if [ -e $MODULAR_CHASSISDB_CONF_FILE ]; then + IS_MODULAR_CHASSIS=1 +fi + +confvar="{\"HAVE_SENSORS_CONF\":$HAVE_SENSORS_CONF, \"HAVE_FANCONTROL_CONF\":$HAVE_FANCONTROL_CONF, \"API_VERSION\":$SONIC_PLATFORM_API_PYTHON_VERSION, \"IS_MODULAR_CHASSIS\":$IS_MODULAR_CHASSIS}" + +if [ -e $PMON_DAEMON_CONTROL_FILE ]; +then + sonic-cfggen -j $PMON_DAEMON_CONTROL_FILE -a "$confvar" -t $SUPERVISOR_CONF_TEMPLATE > $SUPERVISOR_CONF_FILE +else + sonic-cfggen -a "$confvar" -t $SUPERVISOR_CONF_TEMPLATE > $SUPERVISOR_CONF_FILE +fi +exec /usr/local/bin/supervisord diff --git a/dockers/docker-platform-monitor/start.sh.j2 b/dockers/docker-platform-monitor/start.sh.j2 deleted file mode 100644 index a72f4fa8eb85..000000000000 --- a/dockers/docker-platform-monitor/start.sh.j2 +++ /dev/null @@ -1,77 +0,0 @@ -#!/usr/bin/env bash - -declare -r EXIT_SUCCESS="0" - -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 - -# If this platform has synchronization script, run it -if [ -e /usr/share/sonic/platform/platform_wait ]; then - /usr/share/sonic/platform/platform_wait - EXIT_CODE="$?" - if [ "${EXIT_CODE}" != "${EXIT_SUCCESS}" ]; then - supervisorctl shutdown - exit "${EXIT_CODE}" - fi -fi - -# If this platform has an lm-sensors config file, copy it to it's proper place -# and start lm-sensors -if [ -e /usr/share/sonic/platform/sensors.conf ]; then - mkdir -p /etc/sensors.d - /bin/cp -f /usr/share/sonic/platform/sensors.conf /etc/sensors.d/ - supervisorctl start lm-sensors -fi - -# If this platform has a fancontrol config file, copy it to it's proper place -# and start fancontrol -if [ -e /usr/share/sonic/platform/fancontrol ]; then - # Remove stale pid file if it exists - rm -f /var/run/fancontrol.pid - - /bin/cp -f /usr/share/sonic/platform/fancontrol /etc/ - supervisorctl start fancontrol -fi - - -# If the sonic-platform package is not installed, try to install it -pip show sonic-platform > /dev/null 2>&1 -if [ $? -ne 0 ]; then - SONIC_PLATFORM_WHEEL="/usr/share/sonic/platform/sonic_platform-1.0-py2-none-any.whl" - echo "sonic-platform package not installed, attempting to install..." - if [ -e ${SONIC_PLATFORM_WHEEL} ]; then - pip install ${SONIC_PLATFORM_WHEEL} - if [ $? -eq 0 ]; then - echo "Successfully installed ${SONIC_PLATFORM_WHEEL}" - else - echo "Error: Failed to install ${SONIC_PLATFORM_WHEEL}" - fi - else - echo "Error: Unable to locate ${SONIC_PLATFORM_WHEEL}" - fi -fi - -{% if not skip_ledd %} -supervisorctl start ledd -{% endif %} - -{% if not skip_xcvrd %} -supervisorctl start xcvrd -{% endif %} - -{% if not skip_psud %} -supervisorctl start psud -{% endif %} - -{% if not skip_syseepromd %} -supervisorctl start syseepromd -{% endif %} - -{% if not skip_thermalctld %} -supervisorctl start thermalctld -{% endif %} - diff --git a/dockers/docker-ptf-saithrift/Dockerfile.j2 b/dockers/docker-ptf-saithrift/Dockerfile.j2 deleted file mode 100644 index 3076de4878b6..000000000000 --- a/dockers/docker-ptf-saithrift/Dockerfile.j2 +++ /dev/null @@ -1,17 +0,0 @@ -FROM docker-ptf - -## Make apt-get non-interactive -ENV DEBIAN_FRONTEND=noninteractive - -COPY \ -{% for deb in docker_ptf_saithrift_debs.split(' ') -%} -debs/{{ deb }}{{' '}} -{%- endfor -%} -debs/ - -RUN dpkg -i \ -{% for deb in docker_ptf_saithrift_debs.split(' ') -%} -debs/{{ deb }}{{' '}} -{%- endfor %} - -COPY ["*.ini", "/etc/ptf/"] diff --git a/dockers/docker-ptf/Dockerfile.j2 b/dockers/docker-ptf/Dockerfile.j2 index 73c881cab1a9..43eefcd9eeff 100644 --- a/dockers/docker-ptf/Dockerfile.j2 +++ b/dockers/docker-ptf/Dockerfile.j2 @@ -22,6 +22,7 @@ debs/ ENV DEBIAN_FRONTEND=noninteractive ## Set the apt source, update package cache and install necessary packages +## TODO: Clean up this step RUN sed --in-place 's/httpredir.debian.org/debian-archive.trafficmanager.net/' /etc/apt/sources.list \ && apt-get update \ && apt-get upgrade -y \ @@ -39,7 +40,6 @@ RUN sed --in-place 's/httpredir.debian.org/debian-archive.trafficmanager.net/' / unzip \ pkg-config \ binutils \ - net-tools \ build-essential \ libssl-dev \ libffi-dev \ @@ -53,7 +53,6 @@ RUN sed --in-place 's/httpredir.debian.org/debian-archive.trafficmanager.net/' / iputils-ping \ hping3 \ curl \ - tcpdump \ tmux \ python \ python-dev \ @@ -61,7 +60,12 @@ RUN sed --in-place 's/httpredir.debian.org/debian-archive.trafficmanager.net/' / python-scapy \ python-six \ tacacs+ \ - rsyslog + rsyslog \ + ntp \ + ntpstat \ + ntpdate \ + arping \ + bridge-utils RUN dpkg -i \ {% for deb in docker_ptf_debs.split(' ') -%} @@ -69,11 +73,12 @@ debs/{{ deb }}{{' '}} {%- endfor %} # Install all python modules from pypi. python-scapy is exception, ptf debian package requires python-scapy +# TODO: Clean up this step RUN rm -rf /debs \ && apt-get -y autoclean \ && apt-get -y autoremove \ && rm -rf /var/lib/apt/lists/* \ - && wget --https-only https://bootstrap.pypa.io/get-pip.py \ + && wget --https-only https://bootstrap.pypa.io/2.7/get-pip.py \ && python get-pip.py \ && rm -f get-pip.py \ && pip install setuptools \ @@ -112,6 +117,7 @@ RUN rm -rf /debs \ && pip install flask \ && pip install exabgp==3.4.17\ && pip install pyaml \ + && pip install pybrctl pyro4 rpyc yabgp \ && mkdir -p /opt \ && cd /opt \ && wget https://raw.githubusercontent.com/p4lang/ptf/master/ptf_nn/ptf_nn_agent.py @@ -123,8 +129,9 @@ RUN mkdir /var/run/sshd \ && sed -ri '/^#?UsePAM/c\UsePAM no' /etc/ssh/sshd_config \ && sed -ri '/^#?UseDNS/c\UseDNS no' /etc/ssh/sshd_config -COPY ["supervisord.conf", "/etc/supervisor/"] -COPY ["conf.d/supervisord.conf", "conf.d/sshd.conf", "conf.d/ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] +COPY supervisord.conf /etc/supervisor/ +COPY conf.d/ /etc/supervisor/conf.d/ +COPY ptf_tgen.sh /ptf_tgen/ # Move tcpdump into /usr/bin Otherwise it's impossible to run tcpdump due to a docker bug RUN mv /usr/sbin/tcpdump /usr/bin/tcpdump @@ -132,6 +139,25 @@ RUN ln -s /usr/bin/tcpdump /usr/sbin/tcpdump RUN mkdir -p /var/log/supervisor -EXPOSE 22 +# Install Python-based GNMI client +RUN git clone https://github.com/lguohan/gnxi.git \ + && cd gnxi \ + && git checkout 53901ab \ + && cd gnmi_cli_py \ + && pip install -r requirements.txt + +COPY \ +{% for deb in docker_ptf_debs.split(' ') -%} +debs/{{ deb }}{{' '}} +{%- endfor -%} +debs/ + +RUN dpkg -i \ +{% for deb in docker_ptf_debs.split(' ') -%} +debs/{{ deb }}{{' '}} +{%- endfor %} + +COPY ["*.ini", "/etc/ptf/"] +EXPOSE 22 8009 ENTRYPOINT ["/usr/local/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"] diff --git a/dockers/docker-ptf-saithrift/brcm_interface_to_front_map.ini b/dockers/docker-ptf/brcm_interface_to_front_map.ini similarity index 100% rename from dockers/docker-ptf-saithrift/brcm_interface_to_front_map.ini rename to dockers/docker-ptf/brcm_interface_to_front_map.ini diff --git a/dockers/docker-ptf/conf.d/ptf_tgen.conf b/dockers/docker-ptf/conf.d/ptf_tgen.conf new file mode 100644 index 000000000000..8efd3f1c15f7 --- /dev/null +++ b/dockers/docker-ptf/conf.d/ptf_tgen.conf @@ -0,0 +1,10 @@ +[program:ptf_tgen] +command=/ptf_tgen/ptf_tgen.sh +process_name=ptf_tgen +stdout_logfile=/tmp/ptf_tgen.out.log +stderr_logfile=/tmp/ptf_tgen.err.log +redirect_stderr=false +autostart=false +autorestart=true +startsecs=1 +numprocs=1 diff --git a/dockers/docker-ptf-saithrift/msn_2700_interface_to_front_map.ini b/dockers/docker-ptf/msn_2700_interface_to_front_map.ini similarity index 100% rename from dockers/docker-ptf-saithrift/msn_2700_interface_to_front_map.ini rename to dockers/docker-ptf/msn_2700_interface_to_front_map.ini diff --git a/dockers/docker-ptf/ptf_tgen.sh b/dockers/docker-ptf/ptf_tgen.sh new file mode 100755 index 000000000000..03593276bdd9 --- /dev/null +++ b/dockers/docker-ptf/ptf_tgen.sh @@ -0,0 +1 @@ +# PLACEHOLDER - This file is intended to be overwritten by SPYTest. diff --git a/dockers/docker-router-advertiser/Dockerfile.j2 b/dockers/docker-router-advertiser/Dockerfile.j2 index 39e7b28effc1..7d225cbd4e79 100644 --- a/dockers/docker-router-advertiser/Dockerfile.j2 +++ b/dockers/docker-router-advertiser/Dockerfile.j2 @@ -1,15 +1,22 @@ {% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} -FROM docker-config-engine-stretch +FROM docker-config-engine-buster ARG docker_container_name +ARG image_version 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 +# Pass the image_version to container +ENV IMAGE_VERSION=$image_version + # Update apt's cache of available packages RUN apt-get update +# Install radvd Debian package +RUN apt-get -y install radvd=1:2.17-2 + {% if docker_router_advertiser_debs.strip() -%} # Copy built Debian packages {{ copy_files("debs/", docker_router_advertiser_debs.split(' '), "/debs/") }} @@ -25,9 +32,9 @@ RUN apt-get clean -y && \ rm -rf /debs COPY ["start.sh", "/usr/bin/"] -COPY ["docker-router-advertiser.supervisord.conf", "/etc/supervisor/conf.d/"] -COPY ["radvd.conf.j2", "wait_for_intf.sh.j2", "/usr/share/sonic/templates/"] +COPY ["docker-init.sh", "/usr/bin/"] +COPY ["radvd.conf.j2", "wait_for_link.sh.j2", "docker-router-advertiser.supervisord.conf.j2", "/usr/share/sonic/templates/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/bin/docker-init.sh"] diff --git a/dockers/docker-router-advertiser/critical_processes b/dockers/docker-router-advertiser/critical_processes index 238a0346ac9f..a343765f78e0 100644 --- a/dockers/docker-router-advertiser/critical_processes +++ b/dockers/docker-router-advertiser/critical_processes @@ -1 +1 @@ -radvd +program:radvd diff --git a/dockers/docker-router-advertiser/docker-init.sh b/dockers/docker-router-advertiser/docker-init.sh new file mode 100755 index 000000000000..6e1bb5545f82 --- /dev/null +++ b/dockers/docker-router-advertiser/docker-init.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +mkdir -p /etc/supervisor/conf.d + +# Generate supervisord router advertiser config, /etc/radvd.conf config file, and +# the script that waits for pertinent interfaces to come up and make it executable +CFGGEN_PARAMS=" \ + -d \ + -t /usr/share/sonic/templates/docker-router-advertiser.supervisord.conf.j2,/etc/supervisor/conf.d/supervisord.conf \ + -t /usr/share/sonic/templates/radvd.conf.j2,/etc/radvd.conf \ + -t /usr/share/sonic/templates/wait_for_link.sh.j2,/usr/bin/wait_for_link.sh \ +" +sonic-cfggen $CFGGEN_PARAMS + +chmod +x /usr/bin/wait_for_link.sh + +exec /usr/local/bin/supervisord diff --git a/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf b/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf deleted file mode 100644 index bf9320acc776..000000000000 --- a/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf +++ /dev/null @@ -1,35 +0,0 @@ -[supervisord] -logfile_maxbytes=1MB -logfile_backups=2 -nodaemon=true - -[eventlistener:supervisor-proc-exit-script] -command=/usr/bin/supervisor-proc-exit-listener --container-name radv -events=PROCESS_STATE_EXITED -autostart=true -autorestart=unexpected - -[program:start.sh] -command=/usr/bin/start.sh -priority=1 -autostart=true -autorestart=false -startsecs=0 -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:radvd] -command=/usr/sbin/radvd -n -priority=3 -autostart=false -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog diff --git a/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf.j2 b/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf.j2 new file mode 100644 index 000000000000..5cbfd60322e1 --- /dev/null +++ b/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf.j2 @@ -0,0 +1,76 @@ +[supervisord] +logfile_maxbytes=1MB +logfile_backups=2 +nodaemon=true + +[eventlistener:dependent-startup] +command=python3 -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE +buffer_size=25 + +[eventlistener:supervisor-proc-exit-script] +command=/usr/bin/supervisor-proc-exit-listener --container-name radv +events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING +autostart=true +autorestart=unexpected + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true + +[program:start] +command=/usr/bin/start.sh +priority=1 +autostart=true +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running + +{# Router advertiser should only run on ToR (T0) devices which have #} +{# at least one VLAN interface which has an IPv6 address asigned #} +{%- set vlan_v6 = namespace(count=0) -%} +{%- if "ToRRouter" in DEVICE_METADATA.localhost.type and DEVICE_METADATA.localhost.type != "MgmtToRRouter" -%} + {%- if VLAN_INTERFACE -%} + {%- for (name, prefix) in VLAN_INTERFACE|pfx_filter -%} + {# If this VLAN has an IPv6 address... #} + {%- if prefix | ipv6 -%} + {%- set vlan_v6.count = vlan_v6.count + 1 -%} + {%- endif -%} + {%- endfor -%} + {%- endif -%} +{%- endif -%} + +{%- if vlan_v6.count > 0 %} +[program:wait_for_link] +command=/usr/bin/wait_for_link.sh +priority=3 +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited + +[program:radvd] +command=/usr/sbin/radvd -n +priority=4 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=wait_for_link:exited +{% endif -%} diff --git a/dockers/docker-router-advertiser/start.sh b/dockers/docker-router-advertiser/start.sh index 8d5f73a8bcb0..561cd5d7cee1 100755 --- a/dockers/docker-router-advertiser/start.sh +++ b/dockers/docker-router-advertiser/start.sh @@ -1,32 +1,12 @@ -#!/usr/bin/env bash +#! /bin/bash -rm -f /var/run/rsyslogd.pid - -supervisorctl start rsyslogd - -# Router advertiser should only run on ToR (T0) devices -DEVICE_ROLE=$(sonic-cfggen -d -v "DEVICE_METADATA.localhost.type") -if [ "$DEVICE_ROLE" != "ToRRouter" ]; then - echo "Device role is not ToRRouter. Not starting router advertiser process." - exit 0 +if [ "${RUNTIME_OWNER}" == "" ]; then + RUNTIME_OWNER="kube" fi -# Generate /etc/radvd.conf config file -sonic-cfggen -d -t /usr/share/sonic/templates/radvd.conf.j2 > /etc/radvd.conf - -# Enusre at least one interface is specified in radvd.conf -NUM_IFACES=$(grep -c "^interface " /etc/radvd.conf) -if [ $NUM_IFACES -eq 0 ]; then - echo "No interfaces specified in radvd.conf. Not starting router advertiser process." - exit 0 +CTR_SCRIPT="/usr/share/sonic/scripts/container_startup.py" +if test -f ${CTR_SCRIPT} +then + ${CTR_SCRIPT} -f radv -o ${RUNTIME_OWNER} -v ${IMAGE_VERSION} fi -# Generate the script that waits for pertinent interfaces to come up and make it executable -sonic-cfggen -d -t /usr/share/sonic/templates/wait_for_intf.sh.j2 > /usr/bin/wait_for_intf.sh -chmod +x /usr/bin/wait_for_intf.sh - -# Wait for pertinent interfaces to come up -/usr/bin/wait_for_intf.sh - -# Start the router advertiser -supervisorctl start radvd diff --git a/dockers/docker-router-advertiser/wait_for_intf.sh.j2 b/dockers/docker-router-advertiser/wait_for_link.sh.j2 similarity index 100% rename from dockers/docker-router-advertiser/wait_for_intf.sh.j2 rename to dockers/docker-router-advertiser/wait_for_link.sh.j2 diff --git a/dockers/docker-sflow/Dockerfile.j2 b/dockers/docker-sflow/Dockerfile.j2 index 75da64e02e4d..476ff3514ace 100644 --- a/dockers/docker-sflow/Dockerfile.j2 +++ b/dockers/docker-sflow/Dockerfile.j2 @@ -1,5 +1,5 @@ {% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} -FROM docker-config-engine-stretch +FROM docker-config-engine-buster ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf @@ -27,9 +27,9 @@ RUN apt-get clean -y && \ RUN sed -ri '/^DAEMON_ARGS=""/c DAEMON_ARGS="-c /var/log/hsflowd.crash"' /etc/init.d/hsflowd -COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor"] +COPY ["port_index_mapper.py", "/usr/bin"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/dockers/docker-sflow/base_image_files/monit_sflow b/dockers/docker-sflow/base_image_files/monit_sflow index d041f81001ea..84b36b18ce65 100644 --- a/dockers/docker-sflow/base_image_files/monit_sflow +++ b/dockers/docker-sflow/base_image_files/monit_sflow @@ -3,5 +3,5 @@ ## process list: ## sflowmgrd ############################################################################### -check process sflowmgrd matching "/usr/bin/sflowmgrd" - if does not exist for 5 times within 5 cycles then alert +check program sflow|sflowmgrd with path "/usr/bin/process_checker sflow /usr/bin/sflowmgrd" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/dockers/docker-sflow/critical_processes b/dockers/docker-sflow/critical_processes index 5b24e2d8e1da..8180f8ad1c37 100644 --- a/dockers/docker-sflow/critical_processes +++ b/dockers/docker-sflow/critical_processes @@ -1 +1 @@ -sflowmgrd +program:sflowmgrd diff --git a/dockers/docker-sflow/port_index_mapper.py b/dockers/docker-sflow/port_index_mapper.py new file mode 100755 index 000000000000..3ee73181a5b4 --- /dev/null +++ b/dockers/docker-sflow/port_index_mapper.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python3 + +import signal +import sys +import traceback +from sonic_py_common.logger import Logger +from socket import if_nametoindex +from swsssdk import SonicV2Connector, port_util +from swsscommon import swsscommon + +SYSLOG_IDENTIFIER = 'port_index_mapper' + +# Global logger instance +logger = Logger(SYSLOG_IDENTIFIER) +logger.set_min_log_priority_info() + + +class PortIndexMapper(object): + + def __init__(self): + REDIS_TIMEOUT_MS = 0 + # Update this list to support more interfaces + tbl_lst = [swsscommon.STATE_PORT_TABLE_NAME, + swsscommon.STATE_VLAN_TABLE_NAME] + self.appl_db = swsscommon.DBConnector("STATE_DB", + REDIS_TIMEOUT_MS, + True) + + self.state_db = SonicV2Connector(host='127.0.0.1', decode_responses=True) + self.state_db.connect(self.state_db.STATE_DB, False) + self.sel = swsscommon.Select() + self.tbls = [swsscommon.SubscriberStateTable(self.appl_db, t) + for t in tbl_lst] + + self.cur_interfaces = {} + + for t in self.tbls: + self.sel.addSelectable(t) + + def set_port_index_table_entry(self, key, index, ifindex): + self.state_db.set(self.state_db.STATE_DB, key, 'index', index) + self.state_db.set(self.state_db.STATE_DB, key, 'ifindex', ifindex) + + def update_db(self, ifname, op): + index = port_util.get_index_from_str(ifname) + if op == 'SET' and index is None: + return + ifindex = if_nametoindex(ifname) + if op == 'SET' and ifindex is None: + return + + # Check if ifname already exist or if index/ifindex changed due to + # syncd restart + if (ifname in self.cur_interfaces and + self.cur_interfaces[ifname] == (index, ifindex)): + return + + _hash = '{}|{}'.format('PORT_INDEX_TABLE', ifname) + + if op == 'SET': + self.cur_interfaces[ifname] = (index, ifindex) + self.set_port_index_table_entry(_hash, str(index), str(ifindex)) + elif op == 'DEL': + del self.cur_interfaces[ifname] + self.state_db.delete(self.state_db.STATE_DB, _hash) + + def listen(self): + SELECT_TIMEOUT_MS = -1 # Infinite wait + + while True: + (state, c) = self.sel.select(SELECT_TIMEOUT_MS) + if state == swsscommon.Select.OBJECT: + for t in self.tbls: + (key, op, cfvs) = t.pop() + if op == 'DEL' and key in self.cur_interfaces: + self.update_db(key, op) + elif (op == 'SET' and key != 'PortInitDone' and + key != 'PortConfigDone' and + key not in self.cur_interfaces): + self.update_db(key, op) + elif state == swsscomm.Select.ERROR: + logger.log_error("Receieved error from select()") + break + + def populate(self): + SELECT_TIMEOUT_MS = 0 + + while True: + (state, c) = self.sel.select(SELECT_TIMEOUT_MS) + if state == swsscommon.Select.OBJECT: + for t in self.tbls: + (key, op, cfvs) = t.pop() + if (key and key != 'PortInitDone' and + key != 'PortConfigDone'): + self.update_db(key, op) + else: + break + + +def signal_handler(signum, frame): + logger.log_notice("got signal {}".format(signum)) + sys.exit(0) + + +def main(): + port_mapper = PortIndexMapper() + port_mapper.populate() + port_mapper.listen() + + +if __name__ == '__main__': + rc = 0 + try: + signal.signal(signal.SIGTERM, signal_handler) + signal.signal(signal.SIGINT, signal_handler) + main() + except Exception as e: + tb = sys.exc_info()[2] + traceback.print_tb(tb) + logger.log_error("%s" % str(e)) + rc = -1 + finally: + sys.exit(rc) diff --git a/dockers/docker-sflow/start.sh b/dockers/docker-sflow/start.sh deleted file mode 100755 index aaefb4d6d004..000000000000 --- a/dockers/docker-sflow/start.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -rm -f /var/run/rsyslogd.pid - -supervisorctl start rsyslogd - -supervisorctl start sflowmgrd diff --git a/dockers/docker-sflow/supervisord.conf b/dockers/docker-sflow/supervisord.conf index 8eb1bdc05e57..3ff5ff564544 100644 --- a/dockers/docker-sflow/supervisord.conf +++ b/dockers/docker-sflow/supervisord.conf @@ -3,32 +3,46 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python3 -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE +buffer_size=25 + [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name sflow -events=PROCESS_STATE_EXITED +events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING autostart=true autorestart=unexpected -[program:start.sh] -command=/usr/bin/start.sh +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE priority=1 -autostart=true +autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true -[program:rsyslogd] -command=/usr/sbin/rsyslogd -n +[program:sflowmgrd] +command=/usr/bin/sflowmgrd priority=2 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running -[program:sflowmgrd] -command=/usr/bin/sflowmgrd +[program:port_index_mapper] +command=/usr/bin/port_index_mapper.py priority=3 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running diff --git a/dockers/docker-snmp-sv2/Dockerfile.j2 b/dockers/docker-snmp-sv2/Dockerfile.j2 deleted file mode 100644 index b62ff61eaf95..000000000000 --- a/dockers/docker-snmp-sv2/Dockerfile.j2 +++ /dev/null @@ -1,93 +0,0 @@ -{% 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 - -# Enable -O for all Python calls -ENV PYTHONOPTIMIZE 1 - -# Make apt-get non-interactive -ENV DEBIAN_FRONTEND=noninteractive - -# Update apt's cache of available packages -# Install curl so we can download and install pip later -# Also install major root CA certificates for curl to reference -# Install gcc which is required for installing hiredis -# Install libdpkg-perl which is required for python3.6-3.6.0 as one of its specs i.e. no-pie-compile.specs -# The file referenced (`/usr/share/dpkg/no-pie-compile.specs`) is in the `libdpkg-perl` package on Debian -RUN apt-get update && \ - apt-get install -y \ - curl \ - ca-certificates \ - gcc \ - make \ - libdpkg-perl \ - ipmitool - -{% if docker_snmp_sv2_debs.strip() -%} -# Copy locally-built Debian package dependencies -{{ copy_files("debs/", docker_snmp_sv2_debs.split(' '), "/debs/") }} - -# Install locally-built Debian packages and implicitly install their dependencies -{{ install_debian_packages(docker_snmp_sv2_debs.split(' ')) }} -{%- endif %} - -# Fix for hiredis compilation issues for ARM -# python will throw for missing locale -RUN apt-get install -y locales -RUN locale-gen "en_US.UTF-8" -RUN dpkg-reconfigure --frontend noninteractive locales -ENV LC_CTYPE=en_US.UTF-8 -RUN sed -i '/^#.* en_US.* /s/^#//' /etc/locale.gen -RUN locale-gen - -# Install up-to-date version of pip -RUN curl https://bootstrap.pypa.io/get-pip.py | python3.6 - -# Install pyyaml dependency for use by some plugins -# Install smbus dependency for use by some plugins -RUN python3.6 -m pip install --no-cache-dir \ - hiredis \ - pyyaml \ - smbus - -{% if docker_snmp_sv2_whls.strip() -%} -# Copy locally-built Python wheel dependencies -{{ copy_files("python-wheels/", docker_snmp_sv2_whls.split(' '), "/python-wheels/") }} - -# Install locally-built Python wheel dependencies -{{ install_python_wheels(docker_snmp_sv2_whls.split(' ')) }} -{% endif %} - -RUN python3.6 -m sonic_ax_impl install - -# Clean up -RUN apt-get -y purge \ - libpython3.6-dev \ - libpython3.6 \ - curl \ - gcc \ - make \ - libdpkg-perl \ - # Note: these packages should be removed with autoremove but actually not, so explicitly purged - libldap-2.4-2 \ - libsasl2-2 \ - libsasl2-modules \ - libsasl2-modules-db && \ - apt-get clean -y && \ - apt-get autoclean -y && \ - apt-get autoremove -y --purge && \ - find / | grep -E "__pycache__" | xargs rm -rf && \ - rm -rf /debs /python-wheels ~/.cache - -COPY ["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"] - -# Although exposing ports is not needed for host net mode, keep it for possible bridge mode -EXPOSE 161/udp 162/udp - -ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/dockers/docker-snmp-sv2/base_image_files/monit_snmp b/dockers/docker-snmp-sv2/base_image_files/monit_snmp deleted file mode 100644 index 811f9d14b3d4..000000000000 --- a/dockers/docker-snmp-sv2/base_image_files/monit_snmp +++ /dev/null @@ -1,11 +0,0 @@ -############################################################################### -## 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-snmp-sv2/critical_processes b/dockers/docker-snmp-sv2/critical_processes deleted file mode 100644 index e6039c5b9840..000000000000 --- a/dockers/docker-snmp-sv2/critical_processes +++ /dev/null @@ -1,2 +0,0 @@ -snmpd -snmp-subagent diff --git a/dockers/docker-snmp-sv2/start.sh b/dockers/docker-snmp-sv2/start.sh deleted file mode 100755 index 6ec3379df58f..000000000000 --- a/dockers/docker-snmp-sv2/start.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env bash - -mkdir -p /etc/ssw -sonic-cfggen -d -y /etc/sonic/sonic_version.yml -t /usr/share/sonic/templates/sysDescription.j2 > /etc/ssw/sysDescription - -mkdir -p /etc/snmp -sonic-cfggen -d -y /etc/sonic/snmp.yml -t /usr/share/sonic/templates/snmpd.conf.j2 > /etc/snmp/snmpd.conf - -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 snmpd -supervisorctl start snmp-subagent diff --git a/dockers/docker-snmp-sv2/supervisord.conf b/dockers/docker-snmp-sv2/supervisord.conf deleted file mode 100644 index 992292330552..000000000000 --- a/dockers/docker-snmp-sv2/supervisord.conf +++ /dev/null @@ -1,42 +0,0 @@ -[supervisord] -logfile_maxbytes=1MB -logfile_backups=2 -nodaemon=true - -[eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener --container-name snmp -events=PROCESS_STATE_EXITED -autostart=true -autorestart=unexpected - -[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=unexpected -stdout_logfile=syslog -stderr_logfile=syslog - -[program:snmpd] -command=/usr/sbin/snmpd -f -LS4d -u Debian-snmp -g Debian-snmp -I -smux,mteTrigger,mteTriggerConf,ifTable,ifXTable,inetCidrRouteTable,ipCidrRouteTable,ip,disk_hw -p /run/snmpd.pid -priority=3 -autostart=false -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog - -[program:snmp-subagent] -command=/usr/bin/env python3.6 -m sonic_ax_impl -priority=4 -autostart=false -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog diff --git a/dockers/docker-snmp/Dockerfile.j2 b/dockers/docker-snmp/Dockerfile.j2 new file mode 100644 index 000000000000..528189c2014f --- /dev/null +++ b/dockers/docker-snmp/Dockerfile.j2 @@ -0,0 +1,80 @@ +{% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python3_wheels, copy_files %} +FROM docker-config-engine-buster + +ARG docker_container_name +ARG image_version +RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf + +# Enable -O for all Python calls +ENV PYTHONOPTIMIZE 1 + +# Make apt-get non-interactive +ENV DEBIAN_FRONTEND=noninteractive + +# Pass the image_version to container +ENV IMAGE_VERSION=$image_version + +# Update apt's cache of available packages +# Install make/gcc which is required for installing hiredis +RUN apt-get update && \ + apt-get install -y \ + python3-dev \ + gcc \ + make \ + ipmitool + +{% if docker_snmp_debs.strip() -%} +# Copy locally-built Debian package dependencies +{{ copy_files("debs/", docker_snmp_debs.split(' '), "/debs/") }} + +# Install locally-built Debian packages and implicitly install their dependencies +{{ install_debian_packages(docker_snmp_debs.split(' ')) }} +{%- endif %} + +# Fix for hiredis compilation issues for ARM +# python will throw for missing locale +RUN apt-get install -y locales +RUN locale-gen "en_US.UTF-8" +RUN dpkg-reconfigure --frontend noninteractive locales +ENV LC_CTYPE=en_US.UTF-8 +RUN sed -i '/^#.* en_US.* /s/^#//' /etc/locale.gen +RUN locale-gen + +# Install dependencies used by some plugins +RUN pip3 install --no-cache-dir \ + hiredis \ + pyyaml \ + smbus + +{% if docker_snmp_whls.strip() -%} +# Copy locally-built Python wheel dependencies +{{ copy_files("python-wheels/", docker_snmp_whls.split(' '), "/python-wheels/") }} + +# Install locally-built Python wheel dependencies +{{ install_python3_wheels(docker_snmp_whls.split(' ')) }} +{% endif %} + +RUN python3 -m sonic_ax_impl install + +# Clean up +RUN apt-get -y purge \ + python3-dev \ + gcc \ + make && \ + apt-get clean -y && \ + apt-get autoclean -y && \ + apt-get autoremove -y --purge && \ + find / | grep -E "__pycache__" | xargs rm -rf && \ + rm -rf /debs /python-wheels ~/.cache + +COPY ["start.sh", "/usr/bin/"] +COPY ["snmp_yml_to_configdb.py", "/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"] + +# Although exposing ports is not needed for host net mode, keep it for possible bridge mode +EXPOSE 161/udp 162/udp + +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/dockers/docker-snmp/base_image_files/monit_snmp b/dockers/docker-snmp/base_image_files/monit_snmp new file mode 100644 index 000000000000..6a368a9b6035 --- /dev/null +++ b/dockers/docker-snmp/base_image_files/monit_snmp @@ -0,0 +1,11 @@ +############################################################################### +## Monit configuration for snmp container +## process list: +## snmpd +## snmpd_subagent +############################################################################### +check program snmp|snmpd with path "/usr/bin/process_checker snmp /usr/sbin/snmpd" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles + +check program snmp|snmp_subagent with path "/usr/bin/process_checker snmp python3 -m sonic_ax_impl" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/dockers/docker-snmp/critical_processes b/dockers/docker-snmp/critical_processes new file mode 100644 index 000000000000..cff479d7fa11 --- /dev/null +++ b/dockers/docker-snmp/critical_processes @@ -0,0 +1,2 @@ +program:snmpd +program:snmp-subagent diff --git a/dockers/docker-snmp/snmp_yml_to_configdb.py b/dockers/docker-snmp/snmp_yml_to_configdb.py new file mode 100755 index 000000000000..7d4289926240 --- /dev/null +++ b/dockers/docker-snmp/snmp_yml_to_configdb.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 + +import os +import sys + +import yaml +from sonic_py_common.logger import Logger +from swsssdk import ConfigDBConnector + +db = ConfigDBConnector() +db.connect() + + +SYSLOG_IDENTIFIER = 'snmp_yml_to_configdb.py' +logger = Logger(SYSLOG_IDENTIFIER) +logger.set_min_log_priority_info() + +snmp_comm_config_db = db.get_table('SNMP_COMMUNITY') +snmp_config_db_communities = snmp_comm_config_db.keys() +snmp_general_config_db = db.get_table('SNMP') +snmp_general_keys = snmp_general_config_db.keys() + +full_snmp_comm_list = ['snmp_rocommunity', 'snmp_rocommunities', 'snmp_rwcommunity', 'snmp_rwcommunities'] + +if not os.path.exists('/etc/sonic/snmp.yml'): + logger.log_info('/etc/sonic/snmp.yml does not exist') + sys.exit(1) + +with open('/etc/sonic/snmp.yml', 'r') as yaml_file: + yaml_snmp_info = yaml.load(yaml_file, Loader=yaml.FullLoader) + +for comm_type in full_snmp_comm_list: + if comm_type in yaml_snmp_info.keys(): + if comm_type.startswith('snmp_rocommunities'): + for community in yaml_snmp_info[comm_type]: + if community not in snmp_config_db_communities: + db.set_entry('SNMP_COMMUNITY', community, {"TYPE": "RO"}) + elif comm_type.startswith('snmp_rocommunity'): + community = yaml_snmp_info['snmp_rocommunity'] + if community not in snmp_config_db_communities: + db.set_entry('SNMP_COMMUNITY', community, {"TYPE": "RO"}) + elif comm_type.startswith('snmp_rwcommunities'): + for community in yaml_snmp_info[comm_type]: + if community not in snmp_config_db_communities: + db.set_entry('SNMP_COMMUNITY', community, {"TYPE": "RW"}) + elif comm_type.startswith('snmp_rwcommunity'): + community = yaml_snmp_info['snmp_rwcommunity'] + if community not in snmp_config_db_communities: + db.set_entry('SNMP_COMMUNITY', community, {"TYPE": "RW"}) + +if yaml_snmp_info.get('snmp_location'): + if 'LOCATION' not in snmp_general_keys: + db.set_entry('SNMP', 'LOCATION', {'Location': yaml_snmp_info['snmp_location']}) +else: + logger.log_info('snmp_location does not exist in snmp.yml file') + sys.exit(1) diff --git a/dockers/docker-snmp-sv2/snmpd.conf.j2 b/dockers/docker-snmp/snmpd.conf.j2 similarity index 80% rename from dockers/docker-snmp-sv2/snmpd.conf.j2 rename to dockers/docker-snmp/snmpd.conf.j2 index 7d4022501fbb..b83fbffda025 100644 --- a/dockers/docker-snmp-sv2/snmpd.conf.j2 +++ b/dockers/docker-snmp/snmpd.conf.j2 @@ -34,16 +34,40 @@ view systemonly included .1.3.6.1.2.1.1 view systemonly included .1.3.6.1.2.1.25.1 # Default access to basic system info -{% if snmp_rocommunities %} -{% for community in snmp_rocommunities %} + + +{% if SNMP_COMMUNITY is defined %} +{% for community in SNMP_COMMUNITY %} +{% if SNMP_COMMUNITY[community]['TYPE'] == 'RO' %} rocommunity {{ community }} rocommunity6 {{ community }} +{% endif %} +{% endfor %} +{% endif %} + +{% if SNMP_COMMUNITY is defined %} +{% for community in SNMP_COMMUNITY %} +{% if SNMP_COMMUNITY[community]['TYPE'] == 'RW' %} +rwcommunity {{ community }} +rwcommunity6 {{ community }} +{% endif %} +{% endfor %} +{% endif %} + +{% if SNMP_USER is defined %} +{% for user in SNMP_USER %} +{% if SNMP_USER[user]['SNMP_USER_PERMISSION'] == 'RO' %} +rouser {{ user }} {{ SNMP_USER[user]['SNMP_USER_TYPE'] }} +CreateUser {{ user }} {{ SNMP_USER[user]['SNMP_USER_AUTH_TYPE'] }} {{ SNMP_USER[user]['SNMP_USER_AUTH_PASSWORD'] }} {{ SNMP_USER[user]['SNMP_USER_ENCRYPTION_TYPE'] }} {{ SNMP_USER[user]['SNMP_USER_ENCRYPTION_PASSWORD'] }} +{% elif SNMP_USER[user]['SNMP_USER_PERMISSION'] == 'RW' %} +rwuser {{ user }} {{ SNMP_USER[user]['SNMP_USER_TYPE'] }} +CreateUser {{ user }} {{ SNMP_USER[user]['SNMP_USER_AUTH_TYPE'] }} {{ SNMP_USER[user]['SNMP_USER_AUTH_PASSWORD'] }} {{ SNMP_USER[user]['SNMP_USER_ENCRYPTION_TYPE'] }} {{ SNMP_USER[user]['SNMP_USER_ENCRYPTION_PASSWORD'] }} +{% endif %} {% endfor %} {% else %} -rocommunity {{ snmp_rocommunity }} -rocommunity6 {{ snmp_rocommunity }} {% endif %} + ############################################################################### # # SYSTEM INFORMATION @@ -51,8 +75,18 @@ rocommunity6 {{ snmp_rocommunity }} # Note that setting these values here, results in the corresponding MIB objects being 'read-only' # See snmpd.conf(5) for more details -sysLocation {{ snmp_location }} + +{% if SNMP is defined and SNMP.LOCATION is defined %} +sysLocation {{ SNMP.LOCATION.Location }} +{% else %} +sysLocation public +{% endif %} +{% if SNMP is defined and SNMP.CONTACT is defined %} +sysContact {{ SNMP.CONTACT.keys()[0] }} {{ SNMP.CONTACT.values()[0] }} +{% else %} sysContact Azure Cloud Switch vteam +{% endif %} + # Application + End-to-End layers sysServices 72 diff --git a/dockers/docker-snmp/start.sh b/dockers/docker-snmp/start.sh new file mode 100755 index 000000000000..aefd0bfc3db6 --- /dev/null +++ b/dockers/docker-snmp/start.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + + +if [ "${RUNTIME_OWNER}" == "" ]; then + RUNTIME_OWNER="kube" +fi + +CTR_SCRIPT="/usr/share/sonic/scripts/container_startup.py" +if test -f ${CTR_SCRIPT} +then + ${CTR_SCRIPT} -f snmp -o ${RUNTIME_OWNER} -v ${IMAGE_VERSION} +fi + +mkdir -p /etc/ssw /etc/snmp + +# Parse snmp.yml and insert the data in Config DB +/usr/bin/snmp_yml_to_configdb.py + +SONIC_CFGGEN_ARGS=" \ + -d \ + -y /etc/sonic/sonic_version.yml \ + -t /usr/share/sonic/templates/sysDescription.j2,/etc/ssw/sysDescription \ + -t /usr/share/sonic/templates/snmpd.conf.j2,/etc/snmp/snmpd.conf \ +" + +sonic-cfggen $SONIC_CFGGEN_ARGS + +mkdir -p /var/sonic +echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status diff --git a/dockers/docker-snmp/supervisord.conf b/dockers/docker-snmp/supervisord.conf new file mode 100644 index 000000000000..414445fdd6d6 --- /dev/null +++ b/dockers/docker-snmp/supervisord.conf @@ -0,0 +1,59 @@ +[supervisord] +logfile_maxbytes=1MB +logfile_backups=2 +nodaemon=true + +[eventlistener:dependent-startup] +command=python3 -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE +buffer_size=50 + +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name snmp +events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING +autostart=true +autorestart=unexpected + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 +autostart=false +autorestart=unexpected +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true + +[program:start] +command=/usr/bin/start.sh +priority=1 +autostart=true +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running + +[program:snmpd] +command=/usr/sbin/snmpd -f -LS4d -u Debian-snmp -g Debian-snmp -I -smux,mteTrigger,mteTriggerConf,ifTable,ifXTable,inetCidrRouteTable,ipCidrRouteTable,ip,disk_hw -p /run/snmpd.pid +priority=3 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited + +[program:snmp-subagent] +command=/usr/bin/env python3 -m sonic_ax_impl +priority=4 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=snmpd:running diff --git a/dockers/docker-snmp-sv2/sysDescription.j2 b/dockers/docker-snmp/sysDescription.j2 similarity index 100% rename from dockers/docker-snmp-sv2/sysDescription.j2 rename to dockers/docker-snmp/sysDescription.j2 diff --git a/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 b/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 index 08c819c1cc14..5ee8cae84466 100644 --- a/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 @@ -1,4 +1,4 @@ -FROM docker-config-engine-stretch +FROM docker-config-engine-buster ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf @@ -6,21 +6,30 @@ RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%s ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive -RUN apt-get update -RUN pip install connexion==1.1.15 \ - setuptools==21.0.0 \ - grpcio-tools==1.20.0 \ - pyangbind==0.6.0 \ - certifi==2017.4.17 \ - python-dateutil==2.6.0 \ - six==1.11.0 \ - urllib3==1.21.1 - - - -## Install redis-tools dependencies -## TODO: implicitly install dependencies -RUN apt-get -y install libjemalloc1 libatomic1 liblua5.1-0 lua-bitop lua-cjson +RUN apt-get update && \ + apt-get install -y g++ python3-dev libxml2 + +# TODO: Remove these lines once we no longer need Python 2 +RUN apt-get install -f -y python-dev python-pip +RUN pip2 install --upgrade 'pip<21' +RUN apt-get purge -y python-pip +RUN pip2 install setuptools==40.8.0 +RUN pip2 install wheel==0.35.1 +RUN pip2 install connexion==1.1.15 \ + setuptools==21.0.0 \ + grpcio-tools==1.20.0 \ + certifi==2017.4.17 \ + python-dateutil==2.6.0 \ + six==1.11.0 \ + urllib3==1.21.1 + +RUN pip3 install connexion==2.7.0 \ + setuptools==21.0.0 \ + grpcio-tools==1.20.0 \ + certifi==2017.4.17 \ + python-dateutil==2.6.0 \ + six==1.11.0 \ + urllib3==1.21.1 COPY \ {% for deb in docker_sonic_mgmt_framework_debs.split(' ') -%} @@ -34,9 +43,14 @@ debs/{{ deb }}{{' '}} {%- endfor %} COPY ["start.sh", "rest-server.sh", "/usr/bin/"] +COPY ["mgmt_vars.j2", "/usr/share/sonic/templates/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +# TODO: Remove this line once we no longer need Python 2 +RUN apt-get purge -y python-dev + +RUN apt-get remove -y g++ python3-dev RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/dockers/docker-sonic-mgmt-framework/mgmt_vars.j2 b/dockers/docker-sonic-mgmt-framework/mgmt_vars.j2 new file mode 100644 index 000000000000..f43b11ba4199 --- /dev/null +++ b/dockers/docker-sonic-mgmt-framework/mgmt_vars.j2 @@ -0,0 +1,4 @@ +{ + "rest_server": {% if REST_SERVER is defined and "default" in RESET_SERVER.keys() %}{{ REST_SERVER['default'] }}{% else %}""{% endif %}, + "x509" : {% if "x509" in DEVICE_METADATA.keys() %}{{ DEVICE_METADATA["x509"] }}{% else %}""{% endif %} +} diff --git a/dockers/docker-sonic-mgmt-framework/rest-server.sh b/dockers/docker-sonic-mgmt-framework/rest-server.sh index e450f707dfd1..56a7e2999402 100755 --- a/dockers/docker-sonic-mgmt-framework/rest-server.sh +++ b/dockers/docker-sonic-mgmt-framework/rest-server.sh @@ -1,28 +1,39 @@ #!/usr/bin/env bash # Startup script for SONiC Management REST Server +EXIT_MGMT_VARS_FILE_NOT_FOUND=1 +MGMT_VARS_FILE=/usr/share/sonic/templates/mgmt_vars.j2 -SERVER_PORT= -LOG_LEVEL= -CLIENT_AUTH= -SERVER_CRT= -SERVER_KEY= -CA_CERT= - -# Read basic server settings from REST_SERVER|default entry -HAS_REST_CONFIG=$(sonic-cfggen -d -v "1 if REST_SERVER and REST_SERVER['default']") -if [ "$HAS_REST_CONFIG" == "1" ]; then - SERVER_PORT=$(sonic-cfggen -d -v "REST_SERVER['default']['port']") - CLIENT_AUTH=$(sonic-cfggen -d -v "REST_SERVER['default']['client_auth']") - LOG_LEVEL=$(sonic-cfggen -d -v "REST_SERVER['default']['log_level']") +if [ ! -f "$MGMT_VARS_FILE" ]; then + echo "Mgmt vars template file not found" + exit $EXIT_MGMT_VARS_FILE_NOT_FOUND +fi + +# Read basic server settings from mgmt vars entries +MGMT_VARS=$(sonic-cfggen -d -t $MGMT_VARS_FILE) +MGMT_VARS=${MGMT_VARS//[\']/\"} + +REST_SERVER=$(echo $MGMT_VARS | jq -r '.rest_server') + +if [ -n "$REST_SERVER" ]; then + SERVER_PORT=$(echo $REST_SERVER | jq -r '.port') + CLIENT_AUTH=$(echo $REST_SERVER | jq -r '.client_auth') + LOG_LEVEL=$(echo $REST_SERVER | jq -r '.log_level') + + SERVER_CRT=$(echo $REST_SERVER | jq -r '.server_crt') + SERVER_KEY=$(echo $REST_SERVER | jq -r '.server_key') + CA_CRT=$(echo $REST_SERVER | jq -r '.ca_crt') +fi + +if [[ -z $SERVER_CRT ]] && [[ -z $SERVER_KEY ]] && [[ -z $CA_CRT ]]; then + X509=$(echo $MGMT_VARS | jq -r '.x509') fi # Read certificate file paths from DEVICE_METADATA|x509 entry. -HAS_X509_CONFIG=$(sonic-cfggen -d -v "1 if DEVICE_METADATA and DEVICE_METADATA['x509']") -if [ "$HAS_X509_CONFIG" == "1" ]; then - SERVER_CRT=$(sonic-cfggen -d -v "DEVICE_METADATA['x509']['server_crt']") - SERVER_KEY=$(sonic-cfggen -d -v "DEVICE_METADATA['x509']['server_key']") - CA_CRT=$(sonic-cfggen -d -v "DEVICE_METADATA['x509']['ca_crt']") +if [ -n "$X509" ]; then + SERVER_CRT=$(echo $X509 | jq -r '.server_crt') + SERVER_KEY=$(echo $X509 | jq -r '.server_key') + CA_CRT=$(echo $X509 | jq -r '.ca_crt') fi # Create temporary server certificate if they not configured in ConfigDB diff --git a/dockers/docker-sonic-mgmt-framework/start.sh b/dockers/docker-sonic-mgmt-framework/start.sh index 24d355670e87..d6722a27fc77 100755 --- a/dockers/docker-sonic-mgmt-framework/start.sh +++ b/dockers/docker-sonic-mgmt-framework/start.sh @@ -2,9 +2,3 @@ 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 rest-server diff --git a/dockers/docker-sonic-mgmt-framework/supervisord.conf b/dockers/docker-sonic-mgmt-framework/supervisord.conf index e26f815f5fb9..f3060fb95d57 100644 --- a/dockers/docker-sonic-mgmt-framework/supervisord.conf +++ b/dockers/docker-sonic-mgmt-framework/supervisord.conf @@ -3,21 +3,34 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true -[program:start.sh] -command=/usr/bin/start.sh -priority=1 +[eventlistener:dependent-startup] +command=python3 -m supervisord_dependent_startup autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE +buffer_size=25 + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 +autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true -[program:rsyslogd] -command=/usr/sbin/rsyslogd -n +[program:start] +command=/usr/bin/start.sh priority=2 -autostart=false +autostart=true autorestart=false +startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running [program:rest-server] command=/usr/bin/rest-server.sh @@ -26,3 +39,5 @@ autostart=false autorestart=true stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited diff --git a/dockers/docker-sonic-mgmt-spytest/Dockerfile.j2 b/dockers/docker-sonic-mgmt-spytest/Dockerfile.j2 deleted file mode 100644 index 4f6b0d8fffac..000000000000 --- a/dockers/docker-sonic-mgmt-spytest/Dockerfile.j2 +++ /dev/null @@ -1,29 +0,0 @@ -FROM docker-sonic-mgmt:latest - -ENV CC=gcc CPP=cpp CXX=c++ LDSHARED="gcc -pthread -shared" PYMSSQL_BUILD_WITH_BUNDLED_FREETDS=1 - -RUN sudo -H pip install \ - "cryptography>=2.5" \ - "future>=0.16.0" \ - gitpython \ - jinja2 \ - jsonpatch \ - "netmiko==2.4.2" \ - prettytable \ - psutil \ - pycryptodome \ - pyfiglet \ - "pylint==1.8.1" \ - pyro4 \ - pytest-repeat \ - "pytest-xdist==1.28.0" \ - "pytest==4.6.5" \ - redis \ - requests \ - rpyc \ - tabulate \ - textfsm - -RUN sudo apt-get update && sudo apt-get install -y \ - inetutils-ping \ - telnet diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index 662f781dc7c0..b6abdb8d9363 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -1,58 +1,73 @@ -FROM ubuntu:16.04 +FROM ubuntu:18.04 ENV DEBIAN_FRONTEND=noninteractive -RUN apt-get update -RUN apt-get install -y \ - openssh-server \ - gcc \ - vim \ - make \ - git \ - sudo \ - python \ - python-dev \ - python-cffi \ - libffi-dev \ - libssl-dev \ - sshpass \ - libxml2 \ - libxslt1-dev \ - python-setuptools \ - build-essential \ - curl \ - cmake \ - tcpdump \ - snmp \ - python-dev \ - python-scapy - -# For JNLP launcher -RUN apt-get install -y default-jre - -# For syslog test -RUN apt-get install -y rsyslog psmisc - -# Remove cffi 1.5.2, will install 1.10.0 by pip later -RUN apt-get purge -y python-cffi python-cffi-backend -# Remove pycparser 2.14, will install >=2.17 by pip later -RUN apt-get purge -y python-ply python-pycparser - -RUN easy_install pip - -RUN pip install ipaddr \ +RUN apt-get update && apt-get install -y build-essential \ + cmake \ + curl \ + default-jre \ + gcc \ + git \ + inetutils-ping \ + iproute2 \ + isc-dhcp-client \ + libffi-dev \ + libssl-dev \ + libxml2 \ + libxslt1-dev \ + make \ + openssh-server \ + psmisc \ + python \ + python-dev \ + python-scapy \ + python-setuptools \ + python-pip \ + python3-pip \ + python3-venv \ + rsyslog \ + snmp \ + sshpass \ + sudo \ + tcpdump \ + telnet \ + vim + +RUN pip install cffi==1.10.0 \ + "cryptography>=2.5" \ + "future>=0.16.0" \ + gitpython \ + ipaddr \ + ipython==5.4.1 \ + ixnetwork-restpy==1.0.52 \ + ixnetwork-open-traffic-generator==0.0.70 \ + jinja2==2.7.2 \ + jsonpatch \ lxml \ - netaddr \ natsort \ - six \ + netaddr \ + netmiko==2.4.2 \ + paramiko==2.7.1 \ + passlib \ pexpect \ + prettytable \ + psutil \ pyasn1==0.1.9 \ + pyfiglet \ + pylint==1.8.1 \ + pyro4 \ pysnmp==4.2.5 \ - jinja2==2.7.2 \ - cffi==1.10.0 \ - paramiko==2.1.2 \ - passlib \ - ipython==5.4.1 \ + pytest-repeat \ + pytest-html \ + pytest-xdist==1.28.0 \ + pytest==4.6.5 \ + redis \ + requests \ + rpyc \ + six \ + tabulate \ + textfsm \ + virtualenv \ && git clone https://github.com/p4lang/scapy-vxlan.git \ && cd scapy-vxlan \ && python setup.py install \ @@ -85,13 +100,14 @@ RUN apt-get update \ && apt-get update \ && apt-get install -y docker-ce-cli +# Install Azure CLI +RUN curl -sL https://aka.ms/InstallAzureCLIDeb | bash + # Install Microsoft Azure Kusto Library for Python RUN pip install azure-kusto-data==0.0.13 \ azure-kusto-ingest==0.0.13 -# Install pytest-ansible module RUN pip install wheel==0.33.6 -RUN pip install pytest-ansible==2.2.2 ## Copy and install sonic-mgmt docker dependencies COPY \ @@ -105,10 +121,18 @@ RUN dpkg -i \ debs/{{ deb }}{{' '}} {%- endfor %} -RUN pip install ansible==2.8.7 +RUN pip install ansible==2.8.12 RUN pip install pysubnettree +# Install pytest-ansible module with 'become', 'become_user' parameters support +RUN git clone https://github.com/ansible/pytest-ansible.git \ + && cd pytest-ansible \ + && git checkout d33c025f070a9c870220a157cc5a999fda68de44 \ + && python setup.py install \ + && cd .. \ + && rm -fr pytest-ansible + RUN mkdir /var/run/sshd EXPOSE 22 @@ -120,6 +144,7 @@ ARG hostname ENV BUILD_HOSTNAME $hostname ENV USER $user +ENV CC=gcc CPP=cpp CXX=c++ LDSHARED="gcc -pthread -shared" PYMSSQL_BUILD_WITH_BUNDLED_FREETDS=1 RUN groupadd -f -r -g $guid g$user @@ -135,16 +160,18 @@ RUN chmod go= /var/$user/.ssh -R RUN echo "$user ALL=(ALL) NOPASSWD:ALL" >>/etc/sudoers USER $user - -# Install Azure CLI WORKDIR /var/$user -RUN curl -L https://aka.ms/InstallAzureCliBundled -o azure-cli_bundle.tar.gz -RUN tar -xvzf azure-cli_bundle.tar.gz -RUN azure-cli_bundle_*/installer -# Known bug: azure keyvault cannot work behind a proxy -# Temporary fix: upgrade the azure-keyvault package within az cli -# TODO: if azure-cli contains newer version azure-keyvault, remove this -RUN ~/lib/azure-cli/bin/python -m pip install azure-keyvault==0.3.7 -U +# Add az symlink for backwards compatibility +RUN mkdir bin && ln -s /usr/bin/az bin/az + +# Install Virtual Environments +RUN python -m virtualenv --system-site-packages env-201811 +RUN env-201811/bin/pip install ansible==2.0.0.2 + +RUN python3 -m venv env-python3 +RUN env-python3/bin/pip3 install azure-kusto-data azure-kusto-ingest defusedxml pytest -RUN git clone https://github.com/Azure/sonic-mgmt +# NOTE: There is an ordering dependency for pycryptodome. Leaving this at +# the end until we figure that out. +RUN pip install pycryptodome==3.9.8 diff --git a/dockers/docker-sonic-restapi/Dockerfile.j2 b/dockers/docker-sonic-restapi/Dockerfile.j2 index de8080880fc7..837796e66d82 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"] +ENTRYPOINT ["/usr/local/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..6752100b84f2 --- /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 program restapi|restapi with path "/usr/bin/process_checker restapi /usr/sbin/go-server-server" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/dockers/docker-sonic-restapi/critical_processes b/dockers/docker-sonic-restapi/critical_processes new file mode 100644 index 000000000000..455b7fb2fa46 --- /dev/null +++ b/dockers/docker-sonic-restapi/critical_processes @@ -0,0 +1 @@ +program:restapi diff --git a/dockers/docker-sonic-restapi/restapi.sh b/dockers/docker-sonic-restapi/restapi.sh new file mode 100755 index 000000000000..3a0997a2e66a --- /dev/null +++ b/dockers/docker-sonic-restapi/restapi.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +RESTAPI_ARGS="" +while true +do + has_client_auth=$(sonic-cfggen -d -v "1 if RESTAPI and RESTAPI['config']") + if [ "$has_client_auth" == "1" ]; then + client_auth=$(sonic-cfggen -d -v "RESTAPI['config']['client_auth']") + fi + 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']"` + CA_CRT=`sonic-cfggen -d -v "RESTAPI['certs']['ca_crt']"` + CLIENT_CRT_CNAME=`sonic-cfggen -d -v "RESTAPI['certs']['client_crt_cname']"` + if [[ -f $SERVER_CRT && -f $SERVER_KEY && -f $CA_CRT ]]; then + RESTAPI_ARGS+=" -enablehttps=true -servercert=$SERVER_CRT -serverkey=$SERVER_KEY -clientcert=$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..d6722a27fc77 100755 --- a/dockers/docker-sonic-restapi/start.sh +++ b/dockers/docker-sonic-restapi/start.sh @@ -2,9 +2,3 @@ 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 index 284c8aef423b..44508ce88138 100644 --- a/dockers/docker-sonic-restapi/supervisord.conf +++ b/dockers/docker-sonic-restapi/supervisord.conf @@ -3,10 +3,49 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true -[program:restapi] -command=/usr/sbin/go-server-server -loglevel trace -priority=1 +[eventlistener:dependent-startup] +command=python3 -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE +buffer_size=25 + +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name restapi +events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING autostart=true autorestart=false -stdout_logfile=/tmp/rest-api.out.log -stderr_logfile=/tmp/rest-api.err.log + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 +autostart=false +autorestart=true +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true + +[program:start] +command=/usr/bin/start.sh +priority=2 +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running + +[program:restapi] +command=/usr/bin/restapi.sh +priority=1 +autostart=false +autorestart=true +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited + + diff --git a/dockers/docker-sonic-telemetry/Dockerfile.j2 b/dockers/docker-sonic-telemetry/Dockerfile.j2 index e94441b4f066..88ff94318208 100644 --- a/dockers/docker-sonic-telemetry/Dockerfile.j2 +++ b/dockers/docker-sonic-telemetry/Dockerfile.j2 @@ -1,17 +1,17 @@ {% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} -FROM docker-config-engine-stretch +FROM docker-config-engine-buster ARG docker_container_name +ARG image_version 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 && \ - apt-get install -f -y \ - libdbus-1-3 \ - libdaemon0 \ - libjansson4 +# Pass the image_version to container +ENV IMAGE_VERSION=$image_version + +RUN apt-get update {% if docker_sonic_telemetry_debs.strip() -%} # Copy locally-built Debian package dependencies @@ -27,8 +27,9 @@ RUN apt-get clean -y && \ rm -rf /debs COPY ["start.sh", "telemetry.sh", "dialout.sh", "/usr/bin/"] +COPY ["telemetry_vars.j2", "/usr/share/sonic/templates/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/dockers/docker-sonic-telemetry/base_image_files/monit_telemetry b/dockers/docker-sonic-telemetry/base_image_files/monit_telemetry index 555822c57f80..3680bbe6cf9a 100644 --- a/dockers/docker-sonic-telemetry/base_image_files/monit_telemetry +++ b/dockers/docker-sonic-telemetry/base_image_files/monit_telemetry @@ -4,8 +4,8 @@ ## 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 program telemetry|telemetry with path "/usr/bin/process_checker telemetry /usr/sbin/telemetry" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles -check process dialout_client matching "/usr/sbin/dialout_client_cli -insecure -logtostderr" - if does not exist for 5 times within 5 cycles then alert +check program telemetry|dialout_client with path "/usr/bin/process_checker telemetry /usr/sbin/dialout_client_cli" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/dockers/docker-sonic-telemetry/critical_processes b/dockers/docker-sonic-telemetry/critical_processes index d6953dd0c883..612a94d9edac 100644 --- a/dockers/docker-sonic-telemetry/critical_processes +++ b/dockers/docker-sonic-telemetry/critical_processes @@ -1,2 +1,2 @@ -telemetry -dialout +program:telemetry +program:dialout diff --git a/dockers/docker-sonic-telemetry/start.sh b/dockers/docker-sonic-telemetry/start.sh index b307e387d557..08f7292f55ba 100755 --- a/dockers/docker-sonic-telemetry/start.sh +++ b/dockers/docker-sonic-telemetry/start.sh @@ -1,11 +1,14 @@ #!/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 +if [ "${RUNTIME_OWNER}" == "" ]; then + RUNTIME_OWNER="kube" +fi -supervisorctl start rsyslogd +CTR_SCRIPT="/usr/share/sonic/scripts/container_startup.py" +if test -f ${CTR_SCRIPT} +then + ${CTR_SCRIPT} -f telemetry -o ${RUNTIME_OWNER} -v ${IMAGE_VERSION} +fi -supervisorctl start telemetry -supervisorctl start dialout +mkdir -p /var/sonic +echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status diff --git a/dockers/docker-sonic-telemetry/supervisord.conf b/dockers/docker-sonic-telemetry/supervisord.conf index 54f4c5b2348d..fa8c86f597c7 100644 --- a/dockers/docker-sonic-telemetry/supervisord.conf +++ b/dockers/docker-sonic-telemetry/supervisord.conf @@ -3,27 +3,40 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python3 -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE +buffer_size=50 + [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name telemetry -events=PROCESS_STATE_EXITED +events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING autostart=true autorestart=false -[program:start.sh] -command=/usr/bin/start.sh +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE priority=1 -autostart=true -autorestart=false +autostart=false +autorestart=true stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true -[program:rsyslogd] -command=/usr/sbin/rsyslogd -n +[program:start] +command=/usr/bin/start.sh priority=2 autostart=false -autorestart=true +autorestart=false +startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running [program:telemetry] command=/usr/bin/telemetry.sh @@ -32,6 +45,8 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited [program:dialout] command=/usr/bin/dialout.sh @@ -40,3 +55,5 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=telemetry:running diff --git a/dockers/docker-sonic-telemetry/telemetry.sh b/dockers/docker-sonic-telemetry/telemetry.sh index 37ab4dd2d04f..1f92657e3b8f 100755 --- a/dockers/docker-sonic-telemetry/telemetry.sh +++ b/dockers/docker-sonic-telemetry/telemetry.sh @@ -1,50 +1,72 @@ #!/usr/bin/env bash -# Try to read telemetry and x509 config from ConfigDB. +EXIT_TELEMETRY_VARS_FILE_NOT_FOUND=1 +TELEMETRY_VARS_FILE=/usr/share/sonic/templates/telemetry_vars.j2 + +if [ ! -f "$TELEMETRY_VARS_FILE" ]; then + echo "Telemetry vars template file not found" + exit $EXIT_TELEMETRY_VARS_FILE_NOT_FOUND +fi + +# 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'` +TELEMETRY_VARS=$(sonic-cfggen -d -t $TELEMETRY_VARS_FILE) +TELEMETRY_VARS=${TELEMETRY_VARS//[\']/\"} +X509=$(echo $TELEMETRY_VARS | jq -r '.x509') +GNMI=$(echo $TELEMETRY_VARS | jq -r '.gnmi') +CERTS=$(echo $TELEMETRY_VARS | jq -r '.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=$(echo $CERTS | jq -r '.server_crt') + SERVER_KEY=$(echo $CERTS | jq -r '.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=$(echo $CERTS | jq -r '.ca_crt') + if [ ! -z $CA_CRT ]; then + TELEMETRY_ARGS+=" --ca_crt $CA_CRT" + fi +elif [ -n "$X509" ]; then + SERVER_CRT=$(echo $X509 | jq -r '.server_crt') + SERVER_KEY=$(echo $X509 | jq -r '.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=$(echo $X509 | jq -r '.ca_crt') + if [ ! -z $CA_CRT ]; then + TELEMETRY_ARGS+=" --ca_crt $CA_CRT" + fi +else + TELEMETRY_ARGS+=" --noTLS" fi # If no configuration entry exists for TELEMETRY, create one default port -if [ -z $TELEMETRY ]; then - sonic-db-cli CONFIG_DB hset "TELEMETRY|gnmi" port 8080 +if [ -z "$GNMI" ]; then + PORT=8080 +else + PORT=$(echo $GNMI | jq -r '.port') fi - -PORT=`sonic-cfggen -d -v "TELEMETRY['gnmi']['port']"` TELEMETRY_ARGS+=" --port $PORT" -CLIENT_AUTH=`sonic-cfggen -d -v "TELEMETRY['gnmi']['client_auth']"` +CLIENT_AUTH=$(echo $GNMI | jq -r '.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']"` +LOG_LEVEL=$(echo $GNMI | jq -r '.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/dockers/docker-sonic-telemetry/telemetry_vars.j2 b/dockers/docker-sonic-telemetry/telemetry_vars.j2 new file mode 100644 index 000000000000..d1d2d8977f1f --- /dev/null +++ b/dockers/docker-sonic-telemetry/telemetry_vars.j2 @@ -0,0 +1,5 @@ +{ + "certs": {% if "certs" in TELEMETRY.keys() %}{{ TELEMETRY["certs"] }}{% else %}""{% endif %}, + "gnmi" : {% if "gnmi" in TELEMETRY.keys() %}{{ TELEMETRY["gnmi"] }}{% else %}""{% endif %}, + "x509" : {% if "x509" in DEVICE_METADATA.keys() %}{{ DEVICE_METADATA["x509"] }}{% else %}""{% endif %} +} diff --git a/dockers/docker-teamd/Dockerfile.j2 b/dockers/docker-teamd/Dockerfile.j2 index 4282a10d0c86..7f4db2936857 100644 --- a/dockers/docker-teamd/Dockerfile.j2 +++ b/dockers/docker-teamd/Dockerfile.j2 @@ -1,5 +1,5 @@ {% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} -FROM docker-config-engine-stretch +FROM docker-config-engine-buster ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf @@ -7,12 +7,7 @@ RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%s ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive -RUN apt-get update && \ - apt-get install -f -y \ - libdbus-1-3 \ - libdaemon0 \ - libjansson4 \ - libpython2.7 +RUN apt-get update {% if docker_teamd_debs.strip() -%} # Copy locally-built Debian package dependencies @@ -32,4 +27,4 @@ COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/dockers/docker-teamd/base_image_files/monit_teamd b/dockers/docker-teamd/base_image_files/monit_teamd new file mode 100644 index 000000000000..626a6145604e --- /dev/null +++ b/dockers/docker-teamd/base_image_files/monit_teamd @@ -0,0 +1,11 @@ +############################################################################### +## Monit configuration for teamd container +## process list: +## teamsyncd +## teammgrd +############################################################################### +check program teamd|teamsyncd with path "/usr/bin/process_checker teamd /usr/bin/teamsyncd" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles + +check program teamd|teammgrd with path "/usr/bin/process_checker teamd /usr/bin/teammgrd" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/dockers/docker-teamd/base_image_files/teamdctl b/dockers/docker-teamd/base_image_files/teamdctl index 615bc3d953fa..d4e02ccd707d 100755 --- a/dockers/docker-teamd/base_image_files/teamdctl +++ b/dockers/docker-teamd/base_image_files/teamdctl @@ -1,5 +1,12 @@ #!/bin/bash +[ -f /etc/sonic/sonic-environment ] && . /etc/sonic/sonic-environment + +function help() +{ + echo -e "Usage: $0 -n [0 to $(($NUM_ASIC-1))] [OPTION]... " 1>&2; exit 1; +} + DOCKER_EXEC_FLAGS="i" # Determine whether stdout is on a terminal @@ -7,4 +14,30 @@ if [ -t 1 ] ; then DOCKER_EXEC_FLAGS+="t" fi -docker exec -$DOCKER_EXEC_FLAGS teamd teamdctl "$@" +DEV="" +PLATFORM=${PLATFORM:-`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform`} + +# Parse the device specific asic conf file, if it exists +ASIC_CONF=/usr/share/sonic/device/$PLATFORM/asic.conf +[ -f $ASIC_CONF ] && . $ASIC_CONF + +if [[ ($NUM_ASIC -gt 1) ]]; then + while getopts ":n:h:" opt; do + case "${opt}" in + h) help + ;; + n) DEV=${OPTARG} + [ $DEV -lt $NUM_ASIC -a $DEV -ge 0 ] || help + ;; + esac + done + + if [ -z "${DEV}" ]; then + help + fi + + # Skip the arguments -n while passing to docker command + shift 2 +fi + +docker exec -$DOCKER_EXEC_FLAGS teamd$DEV teamdctl "$@" diff --git a/dockers/docker-teamd/critical_processes b/dockers/docker-teamd/critical_processes index b5c543df050d..bb7d3c4b0810 100644 --- a/dockers/docker-teamd/critical_processes +++ b/dockers/docker-teamd/critical_processes @@ -1,2 +1,3 @@ -teammgrd -teamsyncd +program:teammgrd +program:teamsyncd +program:tlm_teamd \ No newline at end of file diff --git a/dockers/docker-teamd/start.sh b/dockers/docker-teamd/start.sh index 4cbc65ab0cc3..d67bc4e925c8 100755 --- a/dockers/docker-teamd/start.sh +++ b/dockers/docker-teamd/start.sh @@ -1,12 +1,5 @@ #!/usr/bin/env bash -rm -f /var/run/rsyslogd.pid rm -f /var/run/teamd/* mkdir -p /var/warmboot/teamd - -supervisorctl start rsyslogd - -supervisorctl start teammgrd - -supervisorctl start teamsyncd diff --git a/dockers/docker-teamd/supervisord.conf b/dockers/docker-teamd/supervisord.conf index 0c3071bbfdda..04432a31239a 100644 --- a/dockers/docker-teamd/supervisord.conf +++ b/dockers/docker-teamd/supervisord.conf @@ -3,27 +3,40 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python3 -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE +buffer_size=50 + [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name teamd -events=PROCESS_STATE_EXITED +events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING autostart=true autorestart=unexpected -[program:start.sh] -command=/usr/bin/start.sh +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE priority=1 -autostart=true -autorestart=false +autostart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true -[program:rsyslogd] -command=/usr/sbin/rsyslogd -n +[program:start] +command=/usr/bin/start.sh priority=2 -autostart=false -autorestart=unexpected +autostart=true +autorestart=false +startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running [program:teammgrd] command=/usr/bin/teammgrd @@ -32,12 +45,27 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited [program:teamsyncd] command=/usr/bin/teamsyncd -priority=3 +priority=4 startsecs=5 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=teammgrd:running + +[program:tlm_teamd] +command=/usr/bin/tlm_teamd +priority=4 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited + diff --git a/dockers/dockerfile-macros.j2 b/dockers/dockerfile-macros.j2 index 408ee9fec622..9917cb17aba2 100644 --- a/dockers/dockerfile-macros.j2 +++ b/dockers/dockerfile-macros.j2 @@ -5,8 +5,29 @@ RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return {%- endfor %} {%- endmacro %} +{% macro install_python2_wheels(packages) -%} +RUN cd /python-wheels/ && pip2 install {{ packages | join(' ') }} +{%- endmacro %} + +{% macro install_python3_wheels(packages) -%} +RUN cd /python-wheels/ && pip3 install {{ packages | join(' ') }} +{%- endmacro %} + {% macro install_python_wheels(packages) -%} -RUN cd /python-wheels/ && pip install {{ packages | join(' ') }} +{%- set py2_pkgs, py3_pkgs = [], [] %} +{%- for pkg in packages %} + {%- if 'py3' in pkg %} + {{- py3_pkgs.append(pkg) or '' }} + {%- else %} + {{- py2_pkgs.append(pkg) or '' }} + {%- endif %} +{%- endfor %} +{%- if py3_pkgs | length %} +{{ install_python3_wheels(py3_pkgs) }} +{%- endif %} +{%- if py2_pkgs | length %} +{{ install_python2_wheels(py2_pkgs) }} +{%- endif %} {%- endmacro %} {% macro copy_files(prefix, files, dest) -%} diff --git a/files/Aboot/boot0.j2 b/files/Aboot/boot0.j2 index 5a2f2555d1ea..ee4c61b710d0 100644 --- a/files/Aboot/boot0.j2 +++ b/files/Aboot/boot0.j2 @@ -38,10 +38,18 @@ # Options can be provided to only run some features of this script. # # Extra kernel parameters can be provided at runtime by the user by adding them -# into a kernel-params file. +# into the kernel-params file. +# +# Secureboot of SONiC SWI images is also supported. +# In such cases, there will only be a partial install on the flash. +# SONiC will be mostly booting in RAM as a live operating system. +# All templated variables should be declared here image_name="image-%%IMAGE_VERSION%%" dockerfs="{{ FILESYSTEM_DOCKERFS }}" +boot_image="{{ ABOOT_BOOT_IMAGE }}" +installer_image="sonic.swi" +docker_dir="{{ DOCKERFS_DIR }}" do_not_clean="do-not-clean" kernel_params="kernel-params" @@ -52,37 +60,50 @@ info() { printf "%04.2f: $@\n" "$(cut -f1 -d' ' /proc/uptime)"; } err() { info "Error: $@"; } warn() { info "Warning: $@"; } +if [ $# -ne 0 ]; then + echo "usage: $0 (see code)" + exit 1 +fi + +mountpoint_for_file() { + local file="$1" + df "$file" | tail -1 | tr -s " " | cut -d ' ' -f6 +} + # extract mount point from the swi path, e.g., /mnt/flash/sonic.swi --> /mnt/flash if [ -z "$target_path" ]; then if [ -z "$swipath" ]; then err "target_path= is required when swipath= is not provided" exit 1 fi - target_path=$(df "$swipath" | tail -1 | tr -s " " | cut -d ' ' -f6) + target_path=$(mountpoint_for_file "$swipath") fi image_path="$target_path/$image_name" hook_path="$image_path/platform/hooks" data_path="$image_path/platform/data" +boot_image_path="$image_path/$boot_image" +installer_image_path="$image_path/$installer_image" -cmdline_base="$target_path/kernel-params-base" -cmdline_image="$image_path/kernel-cmdline" boot_config="$target_path/boot-config" -swi_tmpfs="/tmp/tmp-swi" - -bootconfigvars="KERNEL INITRD CONSOLESPEED PASSWORD NETDEV NETAUTO NETIP NETMASK NETGW NETDOMAIN NETDNS NETHW memtest" -flash_re=" /mnt/flash| /host" +cmdline_allowlist="crashkernel hwaddr_ma1" # for backward compatibility with the sonic_upgrade= behavior install="${install:-${sonic_upgrade:-}}" -parse_environment_config() { - for n in ${bootconfigvars}; do - eval v="\$$n" - if [ "$v" ]; then - echo "$n=$v" +is_secureboot_enabled() { + if $in_aboot; then + if [ -x /bin/securebootctl ] && securebootctl sb -display | grep -q "Secure Boot enabled"; then + return 0 fi - done + return 1 + else + if grep -q aboot.secureboot /proc/cmdline; then + return 0 + fi + # FIXME: EOS is not handled here + return 1 + fi } clean_flash() { @@ -90,8 +111,8 @@ clean_flash() { for f in $(ls -A $target_path); do if [ $f != "${swipath##*/}" ] && [ $f != "boot-config" ] && + [ $f != "preserve-installer" ] && [ $f != "$kernel_params" ] && - [ $f != "$cmdline_base" ] && [ $f != "aquota.user" ] && [ $f != "old_config" ] && [ $f != "minigraph.xml" ] && @@ -103,6 +124,19 @@ clean_flash() { done } +in_array() { + local value="$1" + shift + + for other in $@; do + if [ "$value" = "$other" ]; then + return 0 + fi + done + + return 1 +} + update_boot_config() { local key="$1" local value="$2" @@ -126,37 +160,190 @@ update_next_boot() { if [ -z "$default" ]; then warn "boot-config has no variable SWI_DEFAULT" else + info "Next reboot will use $default" update_boot_config SWI "$default" fi } +get_sorted_hooks() { + echo $(find "$1" -name '[0-9][0-9]-*' -type f) +} + +run_hooks() { + if [ -d "$hook_path/$1" ]; then + for hook in $(get_sorted_hooks "$hook_path/$1"); do + if [ ! -z "$hook" ]; then + info "Running hook $(basename $hook)" + . "$hook" + fi + done + fi +} + +get_uuid_for() { + local dev="$1" + + if type lsblk 2>&1 > /dev/null; then + lsblk "$dev" -n --output UUID + elif type blkid 2>&1 > /dev/null; then + blkid | grep "^$dev" | sed -n 's/^.* UUID="//p' | sed 's/".*$//' + fi +} + +cmdline_append() { + cat >> /tmp/append +} + +cmdline_clear() { + echo -n > /tmp/append +} + +cmdline_add() { + echo "$@" >> /tmp/append +} + +cmdline_has() { + grep -q "$1" /tmp/append +} + +cmdline_echo() { + # echo trims and remove whitespace duplicates + echo $(cat /tmp/append | tr '\n' ' ') +} + +cmdline_get() { + # extract last matching value for key + sed -nr "s/.*$1=([^ ]+).*/\1/p" /tmp/append | tail -n 1 +} + +find_first_kernel_under() { + local path="$1" + find "$path" -name 'vmlinuz-*' -type f | head -n 1 +} + +find_first_initrd_under() { + local path="$1" + find "$path" -name 'initrd.img-*' -type f | head -n 1 +} + +is_file_in_memory() { + local file="$1" + local filemnt=$(mountpoint_for_file "$file") + local filemntfs=$(mount | grep " $filemnt " | cut -f5 -d' ') + + case "$filemntfs" in + tmpfs|ramfs) return 0;; + *) return 1;; + esac +} + +get_tmpfs() { + local tmpfs="$(mktemp -d)" + + mkdir -p "$tmpfs" + if ! $in_aboot && ! mount | grep -q ' /tmp type tmpfs'; then + # mount a real tmpfs on /tmp/xxx if /tmp is not one already. + mount -t tmpfs "$(dirname $tmpfs)" "$tmpfs" + fi + echo "$tmpfs" +} + +clean_tmpfs() { + local tmpfs="$1" + + case "$tmpfs" in + /tmp) return 0;; + /tmp/*);; # only cleanup tmpfs created by this script + *) return 0;; + esac + + if mount | grep -q "$tmpfs"; then + umount "$tmpfs" || : + fi +} + move_swi_to_tmpfs() { local oldswi="$1" - local newswi="$swi_tmpfs/$(basename $oldswi)" - mkdir -p "$swi_tmpfs" - if ! $in_aboot && ! mount | grep -q ' /tmp type tmpfs'; then - # mount a real tmpfs on /tmp/tmp-swi if /tmp is not one already. - mount -t tmpfs tmp-swi "$swi_tmpfs" + if is_file_in_memory "$oldswi"; then + echo "$oldswi" + return 0 fi + local tmpfs="$(get_tmpfs)" + local newswi="$tmpfs/$(basename "$oldswi")" + mv "$oldswi" "$newswi" echo "$newswi" } cleanup_swi_tmpfs() { rm -f "$swipath" - if mount | grep -q "$swi_tmpfs"; then - umount "$swi_tmpfs" || : - fi + clean_tmpfs "$(mountpoint_for_file "$swipath")" } -extract_image() { - mkdir -p "$image_path" +mount_relpath() { + local abspath="$1" + local mountpath="$(df "$abspath" | sed -nr '/\//s/^.* ([^ ]+)$/\1/p')" + echo "$abspath" | sed "s#^$mountpath/##" +} + +zip_file_offset() { + local zipfile="$1" + local filename="$2" + + if $in_aboot; then + unzip -qqf "$zipfile" "$filename" + else + local hexoffset="$(zipdetails "$zipfile" | sed -En "/Filename +'$filename'/,/^$/p" | sed -En 's/^([^ ]+) PAYLOAD$/\1/p')" + echo "$((0x$hexoffset))" + fi +} + +SWI_ALREADY_INSTALLED=0 +SWI_NOT_INSTALLED=1 +SWI_VERSION_MISMATCH=2 +SWI_OTHER_VARIANT_INSTALLED=3 + +is_swi_installed() { + local swi_path="$1" + local swi_version="$(unzip -qp "$swi_path" .imagehash)" + local local_version="$(cat $image_path/.imagehash 2>/dev/null || :)" + + if [ -z "$local_version" ]; then + # no image installed for this version + return $SWI_NOT_INSTALLED + fi + + if [ "$swi_version" != "$local_version" ]; then + warn "Installed image has a different version than $swipath" + return $SWI_VERSION_MISMATCH + fi + + if $secureboot; then + if [ -s "$installer_image_path" ]; then + # secureboot image already installed + return $SWI_ALREADY_INSTALLED + else + # regular image of the same version already installed + return $SWI_OTHER_VARIANT_INSTALLED + fi + else + if [ -s "$boot_image_path" ]; then + # regular image already installed + return $SWI_ALREADY_INSTALLED + else + # secureboot image of the same version already installed + return $SWI_OTHER_VARIANT_INSTALLED + fi + fi +} + +extract_image() { info "Moving swi to a tmpfs" ## Avoid problematic flash usage spike on older systems, also improves I/O - swipath="$(move_swi_to_tmpfs $swipath)" + swipath="$(move_swi_to_tmpfs "$swipath")" info "Extracting swi content" ## Unzip the image except boot0 and dockerfs archive @@ -169,15 +356,15 @@ extract_image() { ## Unpacking dockerfs delayed ## 1. when disk is vfat as it does not support symbolic link ## 2. when disk is small, expand it into ramfs during initrd - if [ "$rootfs_type" != "vfat" -a x"$docker_inram" != x"on" ]; then - mkdir -p "$image_path/{{ DOCKERFS_DIR }}" + if [ "$rootfs_type" != "vfat" ] && ! cmdline_has docker_inram=on; then + mkdir -p "$image_path/$docker_dir" if [ -n "$install" ]; then TAR_EXTRA_OPTION="--numeric-owner --warning=no-timestamp" fi ## extract docker archive - unzip -oqp "$swipath" "$dockerfs" | tar xzf - -C "$image_path/{{ DOCKERFS_DIR }}" $TAR_EXTRA_OPTION + unzip -oqp "$swipath" "$dockerfs" | tar xzf - -C "$image_path/$docker_dir" $TAR_EXTRA_OPTION else ## save dockerfs archive in the image directory unzip -oq "$swipath" "$dockerfs" -d "$image_path" @@ -185,11 +372,17 @@ extract_image() { fi ## remove installer since it's not needed anymore - info "Remove installer" - cleanup_swi_tmpfs + if $preserve_installer; then + info "Preserving installer under $installer_image_path" + mv "$swipath" "$installer_image_path" + chmod a+r "$installer_image_path" + else + info "Remove installer" + cleanup_swi_tmpfs "$swipath" + fi ## use new reduced-size boot swi - local swi_boot_path="flash:$image_name/{{ ABOOT_BOOT_IMAGE }}" + local swi_boot_path="flash:$image_name/$boot_image" update_boot_config SWI "$swi_boot_path" update_boot_config SWI_DEFAULT "$swi_boot_path" @@ -197,9 +390,43 @@ extract_image() { sync } +extract_image_secureboot() { + info "Extracting necessary swi content" + # NOTE: boot/ is not used by the boot process but only extracted for kdump + unzip -oq "$swipath" 'boot/*' platform/firsttime .imagehash -d "$image_path" + + info "Installing image as $installer_image_path" + mv "$swipath" "$installer_image_path" + chmod a+r "$installer_image_path" + swipath="$installer_image_path" + + local swi_boot_path="flash:$image_name/$installer_image" + update_boot_config SWI "$swi_boot_path" + update_boot_config SWI_DEFAULT "$swi_boot_path" + + sync +} + +prepare_image_secureboot() { + local boot_tmpfs="$(get_tmpfs)" + + info "Extracting boot content in tmpfs" + unzip -oq "$swipath" 'boot/*' -d "$boot_tmpfs" + + info "Generating machine.conf and cmdline" + write_secureboot_configs + + sync + + # override environment variables preventing external tamper on kernel execution + CMDLINE="$(cmdline_echo) $ENV_EXTRA_CMDLINE" + KERNEL="$(find_first_kernel_under "$boot_tmpfs")" + INITRD="$(find_first_initrd_under "$boot_tmpfs")" +} + write_machine_config() { ## Detect SKU and create a hardware description file - aboot_version=$(grep ^Aboot "$cmdline_base" | sed 's/^.*norcal.-//' | tail -n 1) + aboot_version=$(cmdline_get Aboot | sed 's/^.*norcal.-//') if [ -x /bin/sysinit ]; then aboot_build_date=$(stat -c %y /bin/sysinit | sed 's/ /T/') else @@ -216,21 +443,8 @@ 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 + if [ -x /bin/readprefdl ] && [ -f /tmp/.system-prefdl ]; then readprefdl -f /tmp/.system-prefdl -d > $target_path/.system-prefdl elif [ -f /etc/prefdl ]; then cp /etc/prefdl $target_path/.system-prefdl @@ -238,33 +452,42 @@ read_system_eeprom() { fi } -platform_specific() { - local platform="$(sed -nr 's/.*platform=([^ ]+).*/\1/p' "$cmdline_base")" - local sid="$(sed -nr 's/.*sid=([^ ]+).*/\1/p' "$cmdline_base" | sed 's/Ssd$//')" +write_platform_specific_cmdline() { + local platform="$(cmdline_get platform)" + local sid="$(cmdline_get sid | sed 's/Ssd$//')" # set varlog size to 100MB local varlog_size=100 + # sonic_mode is set to fixed by default. + sonic_mode="fixed" + supervisor_mode="supervisor" + linecard_mode="linecard" + # detect the size of the flash partition from name in Aboot/EOS/SONiC - local flash_size=$(($(df | grep -E "$flash_re" | tr -s ' ' | cut -f2 -d' ') / 1000)) + local flash_size=$(($(df "$target_path" | tail -1 | 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 + cmdline_add modprobe.blacklist=radeon,sp5100_tco + cmdline_add acpi=off fi if [ "$platform" = "crow" ]; then # Assuming sid=Clearlake aboot_machine=arista_7050_qx32s flash_size=3700 - echo "modprobe.blacklist=radeon,sp5100_tco" >>/tmp/append + cmdline_add modprobe.blacklist=radeon,sp5100_tco fi if [ "$sid" = "Upperlake" ] || [ "$sid" = "UpperlakeES" ]; then aboot_machine=arista_7060_cx32s flash_size=3700 fi + 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 @@ -272,7 +495,17 @@ platform_specific() { if [ "$sid" = "Alhambra" ]; then aboot_machine=arista_7170_64c flash_size=28000 - echo "hugepages=128" >> /tmp/append + cmdline_add hugepages=128 + fi + if [ "$sid" = "Mineral" ]; then + aboot_machine=arista_7170_32c + flash_size=28000 + cmdline_add hugepages=128 + fi + if [ "$sid" = "MineralD" ]; then + aboot_machine=arista_7170_32cd + flash_size=28000 + cmdline_add hugepages=128 fi if [ "$sid" = "Lodoga" ]; then aboot_machine=arista_7050cx3_32s @@ -282,7 +515,7 @@ platform_specific() { aboot_machine=arista_7060px4_32 flash_size=28000 fi - if [ "$sid" = "BlackhawkDD" ]; then + if [ "$sid" = "BlackhawkDD" ] || [ "$sid" = "BlackhawkDDM" ]; then aboot_machine=arista_7060dx4_32 flash_size=28000 fi @@ -298,17 +531,47 @@ platform_specific() { aboot_machine=arista_7280cr3_32d4 flash_size=7382 fi - 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 - echo "reassign_prefmem" >> /tmp/append + if [ "$sid" = "SmartsvilleDDBK" ]; then + aboot_machine=arista_7280cr3k_32d4 + flash_size=7382 fi - if in_array "$platform" "rook"; then - echo "iommu=on intel_iommu=on" >>/tmp/append + if [ "$sid" = "Clearwater2" ]; then + aboot_machine=arista_7800r3_48cq2_lc + sonic_mode="$linecard_mode" + fi + if [ "$sid" = "Clearwater2Ms" ]; then + aboot_machine=arista_7800r3_48cqm2_lc + sonic_mode="$linecard_mode" + fi + if [ "$sid" = "OtterLake" ]; then + aboot_machine=arista_7800_sup + flash_size=30000 + sonic_mode=$supervisor_mode + fi + if in_array "$platform" "rook" "magpie" "woodpecker" "sprucefish"; then + cmdline_add tsc=reliable + cmdline_add pcie_ports=native + cmdline_add rhash_entries=1 + cmdline_add usb-storage.delay_use=0 + cmdline_add reassign_prefmem + fi + if in_array "$platform" "rook" "sprucefish"; then + cmdline_add iommu=on + cmdline_add intel_iommu=on + cmdline_add intel_idle.max_cstate=0 read_system_eeprom fi - if in_array "$platform" "crow" "woodpecker" "magpie"; then - echo "amd_iommu=off modprobe.blacklist=snd_hda_intel,hdaudio" >> /tmp/append + if in_array "$platform" "crow" "magpie"; then + cmdline_add amd_iommu=off + cmdline_add modprobe.blacklist=snd_hda_intel,hdaudio + read_system_eeprom + fi + if in_array "$platform" "woodpecker"; then + cmdline_add modprobe.blacklist=snd_hda_intel,hdaudio + read_system_eeprom + fi + if in_array "$platform" "lorikeet" "hedgehog"; then + cmdline_add processor.max_cstate=1 read_system_eeprom fi @@ -316,108 +579,195 @@ platform_specific() { varlog_size=4096 elif [ $flash_size -ge 3700 ]; then varlog_size=400 + elif [ $flash_size -le 2000 ]; then + # enable docker_inram for switches with less than 2G of flash + cmdline_add docker_inram=on + cmdline_add logs_inram=on fi - echo "varlog_size=$varlog_size" >>/tmp/append - # disable deterministic interface naming - echo "net.ifnames=0" >>/tmp/append -} - -get_uuid_for() { - local dev="$1" + cmdline_add "varlog_size=$varlog_size" - if type lsblk 2>&1 > /dev/null; then - lsblk "$dev" -n --output UUID - elif type blkid 2>&1 > /dev/null; then - blkid | grep "^$dev" | sed -n "s/^.* UUID=\"//p" | grep -Eo '[^"]+' - fi + cmdline_add "sonic.mode=$sonic_mode" } -write_boot_configs() { - if $in_aboot; then - # generate the default kernel parameters for the platform - echo "$append" > $cmdline_base - cat /etc/cmdline | sed "/^\(${bootconfigvars// /\|}\|crashkernel\|loglevel\|ignore_loglevel\)\(\$\|=\)/d;/^\$/d" >> $cmdline_base - parse_environment_config >> $cmdline_base - elif [ ! -f "$cmdline_base" ]; then - # some systems were started with other versions of this script and therefore - # do not have the $cmdline_base file. we assume that we are on Sonic or EOS. - cat /proc/cmdline | sed -E 's/^(.*) rw .*$/\1/' | tr ' ' '\n' > $cmdline_base - fi +write_image_specific_cmdline() { + # security + cmdline_add security=apparmor + cmdline_add apparmor=1 + + # fs configuration + cmdline_add rw - cp $cmdline_base /tmp/append + # disable deterministic interface naming + cmdline_add net.ifnames=0 - platform_specific - echo "rw loop=$image_name/fs.squashfs loopfstype=squashfs apparmor=1 security=apparmor quiet" >> /tmp/append + # verbosity + cmdline_add quiet + # Start showing systemd information from the first failing unit if any. + # systemd.show_status=false or quiet can be used to silence systemd entierly + cmdline_add systemd.show_status=auto # Pass the MAC address to the new kernel as a command line parameter. This makes it # possible to restore the MAC address in the new kernel without requiring driver modifications. if [ -f /sys/class/net/ma1/address ]; then - echo "hwaddr_ma1=$(cat /sys/class/net/ma1/address)" >> /tmp/append + cmdline_add "hwaddr_ma1=$(cat /sys/class/net/ma1/address)" elif [ -f /sys/class/net/eth0/address ]; then - echo "hwaddr_ma1=$(cat /sys/class/net/eth0/address)" >> /tmp/append + cmdline_add "hwaddr_ma1=$(cat /sys/class/net/eth0/address)" else err "Management port not found." fi + # Obtain root partition uuid + local mountstr="$(mount | grep " $target_path ")" + local rootdev="$(echo $mountstr | cut -f1 -d' ')" + local rootfstype="$(echo $mountstr | cut -f5 -d' ')" + local rootuuid="$(get_uuid_for $rootdev)" + if [ -z "$rootuuid" ] || [ "$rootfstype" = "vfat" ] ; then + cmdline_add "root=$rootdev" + else + cmdline_add "root=UUID=$rootuuid" + fi +} + +write_default_cmdline() { + local delimiter="cmdline-aboot-end" + + cmdline_clear + + if $in_aboot; then + # generate the default kernel parameters for the platform + cat /etc/cmdline | sed "/^\(${bootconfigvars// /\|}\|crashkernel\|loglevel\|ignore_loglevel\)\(\$\|=\)/d;/^\$/d" | cmdline_append + elif grep -q "$delimiter" /proc/cmdline; then + # we are on a recent sonic image using delimiter. extracting the part of the + # cmdline coming from aboot is trivial. + cat /proc/cmdline | sed -E "s/^(.*) $delimiter .*$/\1/" | tr ' ' '\n' | cmdline_append + else + # we are either on SONiC or EOS and the commandline doesn't have a delimiter + # for the Aboot part. Take an educated guess at a right delimiter. + # Subject to breakage if EOS or SONiC cmdline change. + cat /proc/cmdline | sed -E 's/^(.*) rw .*$/\1/' | tr ' ' '\n' | cmdline_append + fi + + cmdline_add "$delimiter" +} + +write_cmdline() { # use extra parameters from kernel-params hook if the file exists - if [ -f "$target_path/$kernel_params" ]; then - cat "$target_path/$kernel_params" >> /tmp/append + if [ -f "$target_path/$kernel_params" ] && ! $secureboot; then + info "Loading extra kernel parameters from $kernel_params" + cat "$target_path/$kernel_params" | cmdline_append fi - # setting root partition if not overridden by kernel-params - if ! grep -q "root=" /tmp/append; then - rootdev="$(mount | grep -E "$flash_re" | cut -f1 -d' ')" - rootfstype="$(mount | grep -E "$flash_re" | cut -f5 -d' ')" - rootuuid="$(get_uuid_for $rootdev)" - if [ -z "$rootuuid" ] || [ "$rootfstype" = "vfat" ] ; then - echo "root=$rootdev" >> /tmp/append - else - echo "root=UUID=$rootuuid" >> /tmp/append - fi + # FIXME: sonic sometimes adds extra kernel parameters from user space + # this is unsafe but some will be kept as part of the regular boot + if [ -f "$image_path/kernel-cmdline" ]; then + for field in $cmdline_allowlist; do + cat "$image_path/kernel-cmdline" | tr ' ' '\n' | grep -E "$field" | tail -n 1 | cmdline_append + done fi - mkdir -p "$image_path" - cat /tmp/append > $cmdline_image - [ -e ${target_path}/machine.conf ] || write_machine_config + # FIXME: legacy configuration files used by fast-reboot and eos2sonic + # these should be deprecated over time. + cmdline_echo > "$image_path/kernel-cmdline" + cmdline_echo | sed 's/ cmdline-aboot-end.*$//' > "$target_path/kernel-params-base" +} + +write_common_configs() { + write_default_cmdline + write_platform_specific_cmdline + write_image_specific_cmdline + write_machine_config +} + +write_secureboot_configs() { + write_common_configs + cmdline_add "loop=$(mount_relpath "$installer_image_path")" + cmdline_add loopfstype=squashfs + cmdline_add "loopoffset=$(zip_file_offset "$installer_image_path" fs.squashfs)" + cmdline_add docker_inram=on + cmdline_add secure_boot_enable=y + cmdline_add aboot.secureboot=enabled + # setting panic= has the side effect of disabling the initrd shell on error + cmdline_add panic=0 + write_cmdline +} + +write_regular_configs() { + write_common_configs + cmdline_add "loop=$image_name/fs.squashfs" + cmdline_add loopfstype=squashfs + write_cmdline } run_kexec() { - 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)}" + local cmdline="${CMDLINE:-$(cmdline_echo) $ENV_EXTRA_CMDLINE}" + local kernel="${KERNEL:-$(find_first_kernel_under "$image_path/boot")}" + local initrd="${INITRD:-$(find_first_initrd_under "$image_path/boot")}" if $verbose; then - # show systemd showdown sequence when verbose is set - cmdline="$cmdline systemd.show_status=true" - else - # Start showing systemd information from the first failing unit if any. - # systemd.show_status=false or quiet can be used to silence systemd entierly - cmdline="$cmdline systemd.show_status=auto" + # show systemd showdown sequence when verbose is set + cmdline="$(echo "$cmdline" | sed 's/systemd.show_status=auto/systemd.show_status=true/')" + fi + + if $debug; then + # enable initrd debug as well as kernel verbose output + cmdline="$(echo "$cmdline" | sed 's/ quiet//')" + cmdline="$cmdline debug loglevel=7 log_buf_len=8M printk.devmsg=on" fi + sync kexec --load --initrd="$initrd" --append="$cmdline" "$kernel" - [ -z "$testonly" ] || exit 0 + ( [ -z "$testonly" ] && [ -z "$loadonly" ] ) || exit 0 info "Kexecing..." kexec --exec } -get_sorted_hooks() { - echo $(find "$1" -name '[0-9][0-9]-*' -type f) +secureboot_install() { + if [ -e "$image_path" ]; then + warn "Image folder $image_path already exist (likely regular install)" + fi + + mkdir -p "$image_path" + + info "Installing image as $installer_image_path" + extract_image_secureboot } -run_hooks() { - if [ -d "$hook_path/$1" ]; then - for hook in $(get_sorted_hooks "$hook_path/$1"); do - if [ ! -z "$hook" ]; then - info "Running hook $(basename $hook)" - . "$hook" - fi - done +regular_install() { + if [ -e "$image_path" ]; then + warn "Image folder $image_path already exist (likely secureboot install)" fi + + mkdir -p $image_path + + info "Generating boot-config, machine.conf and cmdline" + write_regular_configs "$image_path" + + info "Installing image under $image_path" + extract_image + + run_hooks post-install } +secureboot_boot() { + # boot material is extracted and generated in RAM. + # SONiC starts as a live OS. + info "Preparing image for secureboot" + prepare_image_secureboot + update_next_boot + run_kexec +} + +regular_boot() { + # boot uses the image installed on the flash + write_regular_configs "$image_path" + run_hooks pre-kexec + update_next_boot + run_kexec +} + + # In Aboot no option will be provided therefore these are the default values to use in_aboot=true do_clean=true @@ -440,49 +790,70 @@ elif [ ! -z "$kexec" ]; then in_aboot=false do_install=false do_clean=false -elif [ $# -ne 0 ]; then - echo "usage: $0 (see code)" - exit 1 fi +# Make sure boot-config exists to avoid noise +touch "$boot_config" + # Verbosity can be defined by the caller, default to false otherwise verbose=${verbose:-false} +debug=${debug:-false} if [ -f "$target_path/verbose-boot" ] || [ "$(get_boot_config VERBOSE)" = "1" ] || ! $in_aboot; then - verbose=true + verbose=true +fi +if [ -f "$target_path/debug-boot" ] || [ "$(get_boot_config DEBUG)" = "1" ]; then + verbose=true + debug=true +fi + +# behavioral configuration for secureboot +# can be overidden by passing secureboot=true via env +if [ -z "$secureboot" ]; then + if is_secureboot_enabled; then + secureboot=true + else + secureboot=false + fi +fi + +# preserve original installer during regular install when set +preserve_installer=false +if [ -f "$target_path/preserve-installer" ] || + [ "$(get_boot_config PRESERVE_INSTALLER)" = "1" ]; then + preserve_installer=true fi # enable shell debug mode to get the most verbosity if $verbose; then - set -x + set -x fi # install the image if newer if $do_install; then - # we expect the swi to install to be a non empty file - if [ ! -s "$swipath" ]; then + if ! unzip -ql "$swipath" 2>&1 > /dev/null; then err "The swipath= environment variable does not point to a valid SWI" exit 1 fi - # check the hash file in the image, and determine to install or just skip - GIT_REVISION=$(unzip -p "$swipath" .imagehash) - LOCAL_IMAGEHASH=$(cat $image_path/.imagehash 2>/dev/null || true) + swi_installed=0 + is_swi_installed "$swipath" || swi_installed=$? - if [ "$GIT_REVISION" != "$LOCAL_IMAGEHASH" ] || [ ! -z "$force" ]; then - if $do_clean; then + if [ "$swi_installed" -ne $SWI_ALREADY_INSTALLED ] || [ -n "$force" ]; then + if [ "$swi_installed" -eq $SWI_VERSION_MISMATCH ] || [ -n "$force" ]; then + warn "Removing existing installation folder $image_path" + rm -rf $image_path + fi + if [ "$swi_installed" -ne $SWI_OTHER_VARIANT_INSTALLED ] && $do_clean; then info "Cleaning flash content $target_path" clean_flash fi - - info "Generating boot-config, machine.conf and cmdline" - write_boot_configs - - info "Installing image under $image_path" - extract_image - - run_hooks post-install + if $secureboot; then + secureboot_install + else + regular_install + fi else info "Using previously installed image" fi @@ -490,7 +861,9 @@ fi # chainloading using kexec if $do_kexec; then - run_hooks pre-kexec - update_next_boot - run_kexec + if $secureboot; then + secureboot_boot + else + regular_boot + fi fi diff --git a/files/apt/sources.list.amd64 b/files/apt/sources.list.amd64 index 752b1bb4fc60..45902be1078c 100644 --- a/files/apt/sources.list.amd64 +++ b/files/apt/sources.list.amd64 @@ -1,8 +1,13 @@ ## Debian mirror on Microsoft Azure ## Ref: http://debian-archive.trafficmanager.net/ -deb [arch=amd64] http://debian-archive.trafficmanager.net/debian/ stretch main contrib non-free -deb-src [arch=amd64] http://debian-archive.trafficmanager.net/debian/ stretch main contrib non-free -deb [arch=amd64] http://debian-archive.trafficmanager.net/debian-security/ stretch/updates main contrib non-free -deb-src [arch=amd64] http://debian-archive.trafficmanager.net/debian-security/ stretch/updates main contrib non-free -deb [arch=amd64] http://debian-archive.trafficmanager.net/debian/ stretch-backports main contrib non-free +deb [arch=amd64] http://debian-archive.trafficmanager.net/debian/ buster main contrib non-free +deb-src [arch=amd64] http://debian-archive.trafficmanager.net/debian/ buster main contrib non-free +deb [arch=amd64] http://debian-archive.trafficmanager.net/debian-security/ buster/updates main contrib non-free +deb-src [arch=amd64] http://debian-archive.trafficmanager.net/debian-security/ buster/updates main contrib non-free +deb [arch=amd64] http://debian-archive.trafficmanager.net/debian/ buster-backports main contrib non-free +deb [arch=amd64] http://packages.trafficmanager.net/debian/debian buster main contrib non-free +deb-src [arch=amd64] http://packages.trafficmanager.net/debian/debian buster main contrib non-free +deb [arch=amd64] http://packages.trafficmanager.net/debian/debian-security/ buster_updates main contrib non-free +deb-src [arch=amd64] http://packages.trafficmanager.net/debian/debian-security/ buster_updates main contrib non-free +deb [arch=amd64] http://packages.trafficmanager.net/debian/debian buster-backports main contrib non-free diff --git a/files/apt/sources.list.arm64 b/files/apt/sources.list.arm64 index bbe8fe2e9407..58b84978d023 100644 --- a/files/apt/sources.list.arm64 +++ b/files/apt/sources.list.arm64 @@ -1,8 +1,13 @@ ## Debian mirror for ARM ## Not the repo mirror site can change in future, and needs to be updated to be in sync -deb [arch=arm64] http://deb.debian.org/debian stretch main contrib non-free -deb-src [arch=arm64] http://deb.debian.org/debian stretch main contrib non-free -deb [arch=arm64] http://deb.debian.org/debian stretch-updates main contrib non-free -deb-src [arch=arm64] http://deb.debian.org/debian stretch-updates main contrib non-free -deb [arch=arm64] http://ftp.debian.org/debian stretch-backports main +deb [arch=arm64] http://deb.debian.org/debian buster main contrib non-free +deb-src [arch=arm64] http://deb.debian.org/debian buster main contrib non-free +deb [arch=arm64] http://deb.debian.org/debian buster-updates main contrib non-free +deb-src [arch=arm64] http://deb.debian.org/debian buster-updates main contrib non-free +deb [arch=arm64] http://ftp.debian.org/debian buster-backports main +deb [arch=arm64] http://packages.trafficmanager.net/debian/debian buster main contrib non-free +deb-src [arch=arm64] http://packages.trafficmanager.net/debian/debian buster main contrib non-free +deb [arch=arm64] http://packages.trafficmanager.net/debian/debian buster-updates main contrib non-free +deb-src [arch=arm64] http://packages.trafficmanager.net/debian/debian buster-updates main contrib non-free +deb [arch=arm64] http://packages.trafficmanager.net/debian/debian buster-backports main diff --git a/files/apt/sources.list.armhf b/files/apt/sources.list.armhf index 5dd0c306724b..eb6fe3be6889 100644 --- a/files/apt/sources.list.armhf +++ b/files/apt/sources.list.armhf @@ -1,8 +1,13 @@ ## Debian mirror for ARM ## Not the repo mirror site can change in future, and needs to be updated to be in sync -deb [arch=armhf] http://deb.debian.org/debian stretch main contrib non-free -deb-src [arch=armhf] http://deb.debian.org/debian stretch main contrib non-free -deb [arch=armhf] http://deb.debian.org/debian stretch-updates main contrib non-free -deb-src [arch=armhf] http://deb.debian.org/debian stretch-updates main contrib non-free -deb [arch=armhf] http://ftp.debian.org/debian stretch-backports main +deb [arch=armhf] http://deb.debian.org/debian buster main contrib non-free +deb-src [arch=armhf] http://deb.debian.org/debian buster main contrib non-free +deb [arch=armhf] http://deb.debian.org/debian buster-updates main contrib non-free +deb-src [arch=armhf] http://deb.debian.org/debian buster-updates main contrib non-free +deb [arch=armhf] http://ftp.debian.org/debian buster-backports main +deb [arch=armhf] http://packages.trafficmanager.net/debian/debian buster main contrib non-free +deb-src [arch=armhf] http://packages.trafficmanager.net/debian/debian buster main contrib non-free +deb [arch=armhf] http://packages.trafficmanager.net/debian/debian buster-updates main contrib non-free +deb-src [arch=armhf] http://packages.trafficmanager.net/debian/debian buster-updates main contrib non-free +deb [arch=armhf] http://packages.trafficmanager.net/debian/debian buster-backports main diff --git a/files/build_scripts/generate_asic_config_checksum.py b/files/build_scripts/generate_asic_config_checksum.py old mode 100644 new mode 100755 index ca83f4f26a6f..546cf5c7f58e --- a/files/build_scripts/generate_asic_config_checksum.py +++ b/files/build_scripts/generate_asic_config_checksum.py @@ -1,29 +1,32 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 -import syslog -import os import hashlib +import os +import syslog SYSLOG_IDENTIFIER = 'asic_config_checksum' CHUNK_SIZE = 8192 CONFIG_FILES = { - os.path.abspath('./src/sonic-swss/swssconfig/sample/'): ['netbouncer.json', '00-copp.config.json'] + os.path.abspath('./src/sonic-swss/swssconfig/sample/'): ['netbouncer.json'] } OUTPUT_FILE = os.path.abspath('./asic_config_checksum') + def log_info(msg): syslog.openlog(SYSLOG_IDENTIFIER) syslog.syslog(syslog.LOG_INFO, msg) syslog.closelog() + def log_error(msg): syslog.openlog(SYSLOG_IDENTIFIER) syslog.syslog(syslog.LOG_ERR, msg) syslog.closelog() + def get_config_files(config_file_map): ''' Generates a list of absolute paths to ASIC config files. @@ -34,18 +37,19 @@ def get_config_files(config_file_map): config_files.append(os.path.join(path, config_file)) return config_files + def generate_checksum(checksum_files): ''' Generates a checksum for a given list of files. Returns None if an error occurs while reading the files. - + NOTE: The checksum is performed in the order provided. This function does NOT do any re-ordering of the files before creating the checksum. ''' checksum = hashlib.sha1() for checksum_file in checksum_files: try: - with open(checksum_file, 'r') as f: + with open(checksum_file, 'rb') as f: for chunk in iter(lambda: f.read(CHUNK_SIZE), b""): checksum.update(chunk) except IOError as e: @@ -54,14 +58,16 @@ def generate_checksum(checksum_files): return checksum.hexdigest() + def main(): config_files = sorted(get_config_files(CONFIG_FILES)) checksum = generate_checksum(config_files) - if checksum == None: + if checksum is None: exit(1) with open(OUTPUT_FILE, 'w') as output: output.write(checksum + '\n') + if __name__ == '__main__': main() diff --git a/files/build_scripts/mask_disabled_services.py b/files/build_scripts/mask_disabled_services.py new file mode 100755 index 000000000000..f3a1d76bf102 --- /dev/null +++ b/files/build_scripts/mask_disabled_services.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python3 + +import json +import subprocess + +INIT_CFG_FILE_PATH = '/etc/sonic/init_cfg.json' + +with open(INIT_CFG_FILE_PATH) as init_cfg_file: + init_cfg = json.load(init_cfg_file) + if 'FEATURE' in init_cfg: + for feature_name, feature_props in init_cfg['FEATURE'].items(): + if 'state' in feature_props and feature_props['state'] == 'disabled': + subprocess.run(['systemctl', 'mask', '{}.service'.format(feature_name)]) diff --git a/files/build_templates/arp_update_vars.j2 b/files/build_templates/arp_update_vars.j2 new file mode 100644 index 000000000000..b9315b5ebe50 --- /dev/null +++ b/files/build_templates/arp_update_vars.j2 @@ -0,0 +1,5 @@ +{ + "interface": "{% for (name, prefix) in INTERFACE|pfx_filter %}{% if prefix|ipv6 %}{{ name }} {% endif %}{% endfor %}", + "pc_interface" : "{% for (name, prefix) in PORTCHANNEL_INTERFACE|pfx_filter %}{% if prefix|ipv6 %}{{ name }} {% endif %}{% endfor %}", + "vlan" : "{% if VLAN %}{{ VLAN.keys() | join(' ') }}{% endif %}" +} diff --git a/files/build_templates/buffers_config.j2 b/files/build_templates/buffers_config.j2 index a5212d979fcb..3b11b406c738 100644 --- a/files/build_templates/buffers_config.j2 +++ b/files/build_templates/buffers_config.j2 @@ -7,11 +7,11 @@ def {%- endmacro -%} {# Determine device topology and filename postfix #} -{%- if DEVICE_METADATA is defined %} +{%- if DEVICE_METADATA is defined and DEVICE_METADATA['localhost']['type'] is defined %} {%- set switch_role = DEVICE_METADATA['localhost']['type'] %} -{%- if switch_role.lower() == 'torrouter' %} +{%- if 'torrouter' in switch_role.lower() and 'mgmt' not in switch_role.lower()%} {%- set filename_postfix = 't0' %} -{%- elif switch_role.lower() == 'leafrouter' %} +{%- elif 'leafrouter' in switch_role.lower() and 'mgmt' not in switch_role.lower()%} {%- set filename_postfix = 't1' %} {%- else %} {%- set filename_postfix = set_default_topology() %} @@ -22,7 +22,7 @@ def {%- endif -%} {# Import default values from device HWSKU folder #} -{%- import 'buffers_defaults_%s.j2' % filename_postfix as defs %} +{%- import 'buffers_defaults_%s.j2' % filename_postfix as defs with context %} {%- set default_cable = defs.default_cable -%} @@ -47,10 +47,19 @@ def {%- if DEVICE_NEIGHBOR_METADATA is defined and 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 'asic' == neighbor_role | lower %} + {%- set roles1 = 'internal' %} + {%- if 'internal' not in ports2cable %} + {%- set _ = ports2cable.update({'internal': '5m'}) %} + {%- endif -%} + {%- else %} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role %} + {%- set roles1 = roles1 | lower %} + {%- set roles2 = roles2 | lower %} + {%- set roles1 = roles1.replace('backend', '') %} + {%- set roles2 = roles2.replace('backend', '') %} + {%- endif %} {%- if roles1 in ports2cable %} {%- if cable_len.append(ports2cable[roles1]) %}{% endif %} {%- elif roles2 in ports2cable %} @@ -62,11 +71,12 @@ def {%- if cable_len -%} {{ cable_len.0 }} {%- else %} - {%- if switch_role.lower() == 'torrouter' %} + {%- if 'torrouter' in switch_role.lower() and 'mgmt' not in switch_role.lower()%} {%- for local_port in VLAN_MEMBER %} {%- if local_port[1] == port_name %} {%- set roles3 = switch_role + '_' + 'server' %} {%- set roles3 = roles3 | lower %} + {%- set roles3 = roles3.replace('backend', '') %} {%- if roles3 in ports2cable %} {%- if cable_len.append(ports2cable[roles3]) %}{% endif %} {%- endif %} @@ -132,6 +142,11 @@ def {% else %} "BUFFER_PG": { {% for port in PORT_ACTIVE %} +{% if dynamic_mode is defined %} + "{{ port }}|3-4": { + "profile" : "NULL" + }, +{% endif %} "{{ port }}|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }{% if not loop.last %},{% endif %} @@ -162,4 +177,18 @@ def {% endfor %} } {% endif %} +{% if dynamic_mode is defined %} + , + "DEFAULT_LOSSLESS_BUFFER_PARAMETER": { + "AZURE": { + "default_dynamic_th": "0" + } + }, + "LOSSLESS_TRAFFIC_PATTERN": { + "AZURE": { + "mtu": "1024", + "small_packet_percentage": "100" + } + } +{% endif %} } diff --git a/files/build_templates/config-chassisdb.service.j2 b/files/build_templates/config-chassisdb.service.j2 new file mode 100644 index 000000000000..a50d0de72fb1 --- /dev/null +++ b/files/build_templates/config-chassisdb.service.j2 @@ -0,0 +1,12 @@ +[Unit] +Description=Config chassis_db +After=rc-local.service +Requires=rc-local.service + +[Service] +Type=oneshot +ExecStart=/usr/bin/config-chassisdb +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target 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..388451fe720c 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -12,23 +12,52 @@ link_namespace() { # /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")" + PID="$(docker inspect -f {{"'{{.State.Pid}}'"}} "${DOCKERNAME}")" - 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 %} +function updateSyslogConf() +{ + # On multiNPU platforms, change the syslog target ip to docker0 ip to allow logs from containers + # running on the namespace to reach the rsyslog service running on the host + # Also update the container name + if [[ ($NUM_ASIC -gt 1) ]]; then + TARGET_IP=$(docker network inspect bridge --format={{ "'{{(index .IPAM.Config 0).Gateway}}'" }}) + CONTAINER_NAME="$DOCKERNAME" + TMP_FILE="/tmp/rsyslog.$CONTAINER_NAME.conf" + + sonic-cfggen -t /usr/share/sonic/templates/rsyslog-container.conf.j2 -a "{\"target_ip\": \"$TARGET_IP\", \"container_name\": \"$CONTAINER_NAME\" }" > $TMP_FILE + docker cp $TMP_FILE ${DOCKERNAME}:/etc/rsyslog.conf + rm -rf $TMP_FILE + fi +} +function ebtables_config() +{ + if [ "$DEV" ]; then + # Install ebtables filter in namespaces on multi-asic. + ip netns exec $NET_NS ebtables-restore < /etc/ebtables.filter.cfg + else + if [[ ! ($NUM_ASIC -gt 1) ]]; then + # Install ebtables filter in host for single asic. + ebtables-restore < /etc/ebtables.filter.cfg + fi + fi +} + 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 + 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.abspath(mnts[0]['Source'])" 2>/dev/null } function getBootType() @@ -54,62 +83,97 @@ function preStartAction() { {%- if docker_container_name == "database" %} 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 - 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/ + if [ "$DATABASE_TYPE" != "chassisdb" ]; then + 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 + 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/ + fi fi {%- elif docker_container_name == "snmp" %} - 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 %} + updateSyslogConf } function postStartAction() { {%- if docker_container_name == "database" %} if [ "$DEV" ]; then + # Enable the forwarding on eth0 interface in namespace. + SYSCTL_NET_CONFIG="/etc/sysctl.d/sysctl-net.conf" + docker exec -i database$DEV sed -i -e "s/^net.ipv4.conf.eth0.forwarding=0/net.ipv4.conf.eth0.forwarding=1/; + s/^net.ipv6.conf.eth0.forwarding=0/net.ipv6.conf.eth0.forwarding=1/" $SYSCTL_NET_CONFIG + docker exec -i database$DEV sysctl --system -e 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 - 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/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 + # Setup ebtables configuration + ebtables_config + + # chassisdb starts before database starts, bypass the PING check since other + # databases are not availbale until database container is ready. + # also chassisdb doesn't support warm/fast reboot, its dump.rdb is deleted + # at service startup time, nothing need to be done here. + if [ "$DATABASE_TYPE" != "chassisdb" ]; then + # Wait until supervisord and redis starts. This change is needed + # because now database_config.json is jinja2 templated based + # and by the time file gets generated if we do redis ping + # then we catch python exception of file not valid + # that comes to syslog which is unwanted so wait till database + # config is ready and then ping + until [[ ($(docker exec -i database$DEV pgrep -x -c supervisord) -gt 0) && ($($SONIC_DB_CLI PING | grep -c PONG) -gt 0) ]]; do + sleep 1; + done + 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/init_cfg.json ]; then + $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$DEV.json --write-to-db + fi 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" - 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" + fi - sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" - fi + $SONIC_DB_CLI CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" + 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 + if [[ -x /usr/local/bin/db_migrator.py ]]; then + # Migrate the DB to the latest schema version if needed + if [ -z "$DEV" ]; then + /usr/local/bin/db_migrator.py -o migrate + fi + fi + # Add redis UDS to the redis group and give read/write access to the group + REDIS_SOCK="/var/run/redis${DEV}/redis.sock" + else + until [[ ($(docker exec -i ${DOCKERNAME} pgrep -x -c supervisord) -gt 0) && + ($(docker exec -i ${DOCKERNAME} $SONIC_DB_CLI CHASSIS_APP_DB PING | grep -c True) -gt 0) ]]; do + sleep 1 + done + REDIS_SOCK="/var/run/redis-chassis/redis_chassis.sock" fi + chgrp -f redis $REDIS_SOCK && chmod -f 0760 $REDIS_SOCK {%- 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,66 +195,170 @@ 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=${PLATFORM:-`$SONIC_CFGGEN -H -v DEVICE_METADATA.localhost.platform`} + + + # Parse the device specific asic conf file, if it exists + ASIC_CONF=/usr/share/sonic/device/$PLATFORM/asic.conf + if [ -f "$ASIC_CONF" ]; then + source $ASIC_CONF + fi {%- if docker_container_name == "database" %} # Don't mount HWSKU in {{docker_container_name}} container. HWSKU="" + MOUNTPATH="" {%- 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=${HWSKU:-`$SONIC_CFGGEN -d -v 'DEVICE_METADATA["localhost"]["hwsku"]'`} + MOUNTPATH="/usr/share/sonic/device/$PLATFORM/$HWSKU" + if [ "$DEV" ]; then + MOUNTPATH="$MOUNTPATH/$DEV" + fi {%- endif %} - - DOCKERCHECK=`docker inspect --type container {{docker_container_name}}$DEV 2>/dev/null` + DOCKERCHECK=`docker inspect --type container ${DOCKERNAME} 2>/dev/null` if [ "$?" -eq "0" ]; then {%- if docker_container_name == "database" %} DOCKERMOUNT="" {%- else %} DOCKERMOUNT=`getMountPoint "$DOCKERCHECK"` {%- endif %} - if [ x"$DOCKERMOUNT" == x"$HWSKU" ]; then + if [ x"$DOCKERMOUNT" == x"$MOUNTPATH" ]; then + preStartAction {%- if docker_container_name == "database" %} - echo "Starting existing {{docker_container_name}}$DEV container" + echo "Starting existing ${DOCKERNAME} container" + docker start ${DOCKERNAME} {%- else %} - echo "Starting existing {{docker_container_name}}$DEV container with HWSKU $HWSKU" + echo "Starting existing ${DOCKERNAME} container with HWSKU $HWSKU" + /usr/local/bin/container start ${DOCKERNAME} {%- endif %} - preStartAction - docker start {{docker_container_name}}$DEV postStartAction exit $? fi # docker created with a different HWSKU, remove and recreate - echo "Removing obsolete {{docker_container_name}}$DEV container with HWSKU $DOCKERMOUNT" - docker rm -f {{docker_container_name}}$DEV + echo "Removing obsolete ${DOCKERNAME} container with HWSKU $DOCKERMOUNT" + docker rm -f ${DOCKERNAME} fi {%- 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/ + + echo "Creating new ${DOCKERNAME} container" + if [ "$DATABASE_TYPE" != "chassisdb" ]; then + if [ -z "$DEV" ]; then + # if database_global exists in old_config, use it; otherwise use the default one in new image + if [ -f /etc/sonic/old_config/database_global.json ]; then + echo "Use database_global.json from old system..." + mv /etc/sonic/old_config/database_global.json /etc/sonic/ + fi + fi + # 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$DEV.json ]; then + echo "Use database_config.json from old system..." + mv /etc/sonic/old_config/database_config$DEV.json /etc/sonic/ + fi fi {%- else %} - echo "Creating new {{docker_container_name}}$DEV container with HWSKU $HWSKU" + echo "Creating new ${DOCKERNAME} container with HWSKU $HWSKU" + {%- endif %} + + {%- if docker_container_name == "swss" %} + # Obtain the vendor name + ASIC_VENDOR=`$SONIC_CFGGEN -y /etc/sonic/sonic_version.yml -v asic_type` + + # Generate the asic_table.json and peripheral_table.json + if [ ! -f /etc/sonic/asic_table.json ] && [ -f /usr/share/sonic/templates/asic_table.j2 ]; then + sonic-cfggen -d -t /usr/share/sonic/templates/asic_table.j2 > /etc/sonic/asic_table.json + fi + if [ ! -f /etc/sonic/peripheral_table.json ] && [ -f /usr/share/sonic/device/$PLATFORM/port_peripheral_config.j2 ]; then + sonic-cfggen -d -t /usr/share/sonic/device/$PLATFORM/port_peripheral_config.j2 > /etc/sonic/peripheral_table.json + fi + {%- endif %} + + # In Multi ASIC platforms the global database config file database_global.json will exist. + # Parse the file and get the include path for the database_config.json files used in + # various namesapces. The database_config paths are relative to the DIR of SONIC_DB_GLOBAL_JSON. + SONIC_DB_GLOBAL_JSON="/var/run/redis/sonic-db/database_global.json" + if [ -f "$SONIC_DB_GLOBAL_JSON" ]; then + # TODO Create a separate python script with the below logic and invoke it here. + redis_dir_list=`/usr/bin/python -c "import sys; import os; import json; f=open(sys.argv[1]); \ + global_db_dir = os.path.dirname(sys.argv[1]); data=json.load(f); \ + print(\" \".join([os.path.normpath(global_db_dir+'/'+elem['include']).partition('sonic-db')[0]\ + for elem in data['INCLUDES'] if 'namespace' in elem])); f.close()" $SONIC_DB_GLOBAL_JSON` + fi + + {%- if docker_container_name == "database" %} + start_chassis_db=0 + chassis_db_address="" + chassisdb_config="/usr/share/sonic/device/$PLATFORM/chassisdb.conf" + [ -f $chassisdb_config ] && source $chassisdb_config + DB_OPT=" -v /var/run/redis-chassis:/var/run/redis-chassis:ro " + if [[ "$start_chassis_db" != "1" ]] && [[ -z "$chassis_db_address" ]]; then + DB_OPT="" + else + DB_OPT=$DB_OPT" --add-host=redis_chassis.server:$chassis_db_address " + fi {%- endif %} if [ -z "$DEV" ]; then NET="host" + + # For Multi-ASIC platform we have to mount the redis paths for database instances running in different + # namespaces, into the single instance dockers like snmp, pmon on linux host. These global dockers + # will need to get/set tables from databases in different namespaces. + # /var/run/redis0 ---> mounted as --> /var/run/redis0 + # /var/run/redis1 ---> mounted as --> /var/run/redis1 .. etc + # The below logic extracts the base DIR's where database_config.json's for various namespaces exist. + # redis_dir_list is a string of form "/var/run/redis0/ /var/run/redis1/ /var/run/redis2/" + + {%- if docker_container_name != "database" %} + if [ -n "$redis_dir_list" ]; then + for redis_dir in $redis_dir_list + do + REDIS_MNT=$REDIS_MNT" -v $redis_dir:$redis_dir:rw " + done + fi + {%- else %} + if [ "$DATABASE_TYPE" == "chassisdb" ]; then + DB_OPT=${DB_OPT/redis-chassis:ro/redis-chassis:rw} + DB_OPT=$DB_OPT" -v /var/run/redis-chassis:/var/run/redis:rw " + DB_OPT=$DB_OPT" --env DATABASE_TYPE=$DATABASE_TYPE" + else + DB_OPT=$DB_OPT" -v /var/run/redis$DEV:/var/run/redis:rw " + fi + {%- endif %} else + # This part of code is applicable for Multi-ASIC platforms. Here we mount the namespace specific + # redis directory into the docker running in that namespace. Below eg: is for namespace "asic1" + # /var/run/redis1 ---> mounted as --> /var/run/redis1 + # redis_dir_list is a string of form "/var/run/redis0/ /var/run/redis1/ /var/run/redis2/" + if [ -n "$redis_dir_list" ]; then + id=`expr $DEV + 1` + redis_dir=`echo $redis_dir_list | cut -d " " -f $id` + REDIS_MNT=" -v $redis_dir:$redis_dir:rw " + fi + {%- if docker_container_name == "database" %} - NET="bridge" + DB_OPT=$DB_OPT" -v /var/run/redis$DEV:/var/run/redis:rw " {%- else %} NET="container:database$DEV" + DB_OPT="" {%- 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 %} docker create {{docker_image_run_opt}} \ --net=$NET \ + -e RUNTIME_OWNER=local \ --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 \ @@ -215,39 +383,94 @@ start() { --tmpfs /tmp \ {%- endif %} {%- endif %} - -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:/usr/share/sonic/hwsku:ro \ +{%- if sonic_asic_platform == "broadcom" %} +{%- if docker_container_name == "syncd" %} + -v /var/run/docker-syncd$DEV:/var/run/sswsyncd \ +{%- endif %} +{%- endif %} +{%- if docker_container_name == "swss" %} + -e ASIC_VENDOR=$ASIC_VENDOR \ +{%- endif -%} +{%- if docker_container_name == "bgp" %} + -v /etc/sonic/frr/$DEV:/etc/frr:rw \ {%- endif %} +{%- if docker_container_name == "database" %} + $DB_OPT \ +{%- else %} + -v /var/run/redis$DEV:/var/run/redis:rw \ + -v /var/run/redis-chassis:/var/run/redis-chassis:ro \ + -v /usr/share/sonic/device/$PLATFORM/$HWSKU/$DEV:/usr/share/sonic/hwsku:ro \ +{%- endif %} + $REDIS_MNT \ + -v /usr/share/sonic/device/$PLATFORM:/usr/share/sonic/platform:ro \ {%- if sonic_asic_platform != "mellanox" %} --tmpfs /tmp \ {%- endif %} --tmpfs /var/tmp \ - --name={{docker_container_name}}$DEV {{docker_image_name}}:latest || { + --env "NAMESPACE_ID"="$DEV" \ + --env "NAMESPACE_PREFIX"="$NAMESPACE_PREFIX" \ + --env "NAMESPACE_COUNT"=$NUM_ASIC \ + --name=$DOCKERNAME {{docker_image_name}}:latest || { echo "Failed to docker run" >&1 exit 4 } preStartAction - docker start {{docker_container_name}} + {%- if docker_container_name == "database" %} + docker start $DOCKERNAME + {%- else %} + /usr/local/bin/container start ${DOCKERNAME} + {%- endif %} postStartAction } wait() { - docker wait {{docker_container_name}}$DEV + {%- if docker_container_name == "database" %} + docker wait $DOCKERNAME + {%- else %} + /usr/local/bin/container wait $DOCKERNAME + {%- endif %} } stop() { - docker stop {{docker_container_name}}$DEV -{%- if docker_container_name == "database" %} - ip netns delete "$NET_NS$DEV" -{%- endif %} + {%- if docker_container_name == "database" %} + docker stop $DOCKERNAME + if [ "$DEV" ]; then + ip netns delete "$NET_NS" + fi + {%- elif docker_container_name == "teamd" %} + # Longer timeout of 60 sec to wait for Portchannels to be cleaned. + /usr/local/bin/container stop -t 60 $DOCKERNAME + {%- else %} + /usr/local/bin/container stop $DOCKERNAME + {%- endif %} } +DOCKERNAME={{docker_container_name}} OP=$1 DEV=$2 # namespace/device number to operate on -NET_NS="asic" #name of the network namespace +{%- if docker_container_name == "database" %} +if [ "$DEV" == "chassisdb" ]; then + DATABASE_TYPE="chassisdb" + DOCKERNAME=$DOCKERNAME"-chassis" + unset DEV +fi +{%- endif %} +NAMESPACE_PREFIX="asic" +DOCKERNAME=$DOCKERNAME$DEV +if [ "$DEV" ]; then + NET_NS="$NAMESPACE_PREFIX$DEV" #name of the network namespace + + SONIC_CFGGEN="sonic-cfggen -n $NET_NS" + SONIC_DB_CLI="sonic-db-cli -n $NET_NS" + else + NET_NS="" + SONIC_CFGGEN="sonic-cfggen" + SONIC_DB_CLI="sonic-db-cli" +fi + +# read SONiC immutable variables +[ -f /etc/sonic/sonic-environment ] && . /etc/sonic/sonic-environment case "$1" in start|wait|stop) diff --git a/files/build_templates/gbsyncd.service.j2 b/files/build_templates/gbsyncd.service.j2 new file mode 100644 index 000000000000..e1080ae7d526 --- /dev/null +++ b/files/build_templates/gbsyncd.service.j2 @@ -0,0 +1,18 @@ +[Unit] +Description=gbsyncd service +Requires=database.service updategraph.service +ConditionPathExists=!/usr/share/sonic/hwsku/gearbox_config.json +After=database.service updategraph.service +After=interfaces-config.service +After=swss.service +Before=ntp-config.service + +[Service] +User=root +Environment=sonic_asic_platform={{ sonic_asic_platform }} +ExecStartPre=/usr/local/bin/gbsyncd.sh start +ExecStart=/usr/local/bin/gbsyncd.sh wait +ExecStop=/usr/local/bin/gbsyncd.sh stop + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/iccpd.service.j2 b/files/build_templates/iccpd.service.j2 new file mode 100644 index 000000000000..979c45de72c5 --- /dev/null +++ b/files/build_templates/iccpd.service.j2 @@ -0,0 +1,13 @@ +[Unit] +Description=ICCPD container +Requires=updategraph.service swss.service +After=updategraph.service swss.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/init_cfg.json.j2 b/files/build_templates/init_cfg.json.j2 index 17617ee1a3cb..0cf85cd8ab06 100644 --- a/files/build_templates/init_cfg.json.j2 +++ b/files/build_templates/init_cfg.json.j2 @@ -1,6 +1,7 @@ { "DEVICE_METADATA": { "localhost": { + "buffer_model": {% if default_buffer_model == "dynamic" %}"dynamic"{% else %}"traditional"{% endif %}, "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 %} } @@ -10,25 +11,43 @@ "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"] %} + "acl_group", "acl_entry", "acl_counter", "fdb_entry", "snat_entry", "dnat_entry", "ipmc_entry"] %} "{{crm_res}}_threshold_type": "percentage", "{{crm_res}}_low_threshold": "70", "{{crm_res}}_high_threshold": "85"{% if not loop.last %},{% endif -%} {% endfor %} } }, +{%- set features = [("bgp", "enabled", false, "enabled"), + ("database", "always_enabled", false, "always_enabled"), + ("dhcp_relay", "enabled", false, "enabled"), + ("lldp", "enabled", false, "enabled"), + ("pmon", "enabled", false, "enabled"), + ("radv", "enabled", false, "enabled"), + ("snmp", "enabled", true, "enabled"), + ("swss", "enabled", false, "enabled"), + ("syncd", "enabled", false, "enabled"), + ("teamd", "enabled", false, "enabled")] %} +{%- if sonic_asic_platform == "vs" %}{% do features.append(("gbsyncd", "enabled", false, "enabled")) %}{% endif %} +{%- if include_iccpd == "y" %}{% do features.append(("iccpd", "disabled", false, "enabled")) %}{% endif %} +{%- if include_mgmt_framework == "y" %}{% do features.append(("mgmt-framework", "enabled", true, "enabled")) %}{% endif %} +{%- if include_nat == "y" %}{% do features.append(("nat", "disabled", false, "enabled")) %}{% endif %} +{%- if include_restapi == "y" %}{% do features.append(("restapi", "enabled", false, "enabled")) %}{% endif %} +{%- if include_sflow == "y" %}{% do features.append(("sflow", "disabled", false, "enabled")) %}{% endif %} +{%- if include_system_telemetry == "y" %}{% do features.append(("telemetry", "enabled", true, "enabled")) %}{% endif %} "FEATURE": { -{%- for feature in ["sflow", "telemetry"] %} +{# has_timer field if set, will start the feature systemd .timer unit instead of .service unit #} +{%- for feature, state, has_timer, autorestart in features %} "{{feature}}": { - "status": "disabled" - }{% if not loop.last %},{% endif -%} -{% endfor %} - }, - "CONTAINER_FEATURE": { -{%- for container in ["bgp", "database", "dhcp_relay", "lldp", "pmon", "radv", "restapi", "sflow", - "snmp", "swss", "syncd", "teamd", "telemetry"] %} - "{{container}}": { - "auto_restart": "disabled", + "state": "{{state}}", + "has_timer" : {{has_timer | lower()}}, + "has_global_scope": {% if feature + '.service' in installer_services.split(' ') %}true{% else %}false{% endif %}, + "has_per_asic_scope": {% if feature + '@.service' in installer_services.split(' ') %}true{% else %}false{% endif %}, + "auto_restart": "{{autorestart}}", +{%- if include_kubernetes == "y" %} +{%- if feature in ["dhcp_relay", "lldp", "pmon", "radv", "snmp", "telemetry"] %} + "set_owner": "kube", {% else %} + "set_owner": "local", {% endif %} {% endif %} "high_mem_alert": "disabled" }{% if not loop.last %},{% endif -%} {% endfor %} diff --git a/files/build_templates/kube_cni.10-flannel.conflist b/files/build_templates/kube_cni.10-flannel.conflist new file mode 100644 index 000000000000..17b50fda1214 --- /dev/null +++ b/files/build_templates/kube_cni.10-flannel.conflist @@ -0,0 +1,21 @@ +{ + "_comment": "This is a dummy file to simulate flannel so that node status will show as Ready", + "name": "cbr0", + "cniVersion": "0.3.1", + "plugins": [ + { + "type": "flannel", + "delegate": { + "hairpinMode": true, + "isDefaultGateway": true + } + }, + { + "type": "portmap", + "capabilities": { + "portMappings": true + } + } + ] +} + 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/lldp.service.j2 b/files/build_templates/lldp.service.j2 new file mode 120000 index 000000000000..1adb318b9154 --- /dev/null +++ b/files/build_templates/lldp.service.j2 @@ -0,0 +1 @@ +per_namespace/lldp.service.j2 \ No newline at end of file diff --git a/files/build_templates/mgmt-framework.service.j2 b/files/build_templates/mgmt-framework.service.j2 index acc938c13d90..883711aa82eb 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 syncd.service +Requires=database.service +After=database.service swss.service syncd.service Before=ntp-config.service [Service] @@ -10,5 +10,3 @@ 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 diff --git a/files/build_templates/mgmt-framework.timer b/files/build_templates/mgmt-framework.timer new file mode 100644 index 000000000000..62ab8ef1bd58 --- /dev/null +++ b/files/build_templates/mgmt-framework.timer @@ -0,0 +1,9 @@ +[Unit] +Description=Delays management framework container until SONiC has started + +[Timer] +OnBootSec=3min 30 sec +Unit=mgmt-framework.service + +[Install] +WantedBy=timers.target diff --git a/files/build_templates/nat.service.j2 b/files/build_templates/nat.service.j2 index 79a56f67ca89..1d267cfe9302 100644 --- a/files/build_templates/nat.service.j2 +++ b/files/build_templates/nat.service.j2 @@ -1,6 +1,6 @@ [Unit] Description=NAT container -Requires=updategraph.service swss.service +Requires=updategraph.service After=updategraph.service swss.service syncd.service Before=ntp-config.service StartLimitIntervalSec=1200 @@ -15,5 +15,5 @@ Restart=always RestartSec=30 [Install] -WantedBy=multi-user.target swss.service +WantedBy=multi-user.target diff --git a/files/build_templates/pcie-check.timer b/files/build_templates/pcie-check.timer new file mode 100644 index 000000000000..4ad5c6481861 --- /dev/null +++ b/files/build_templates/pcie-check.timer @@ -0,0 +1,9 @@ +[Unit] +Description=Start the pcie-check.service 10 seconds after boot + +[Timer] +OnBootSec=10sec +Unit=pcie-check.service + +[Install] +WantedBy=timers.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..9f3c72e20db5 --- /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/local/bin/{{docker_container_name}}.sh start{% if multi_instance == 'true' %} %i{% endif %} +ExecStart=/usr/local/bin/{{docker_container_name}}.sh wait{% if multi_instance == 'true' %} %i{% endif %} +ExecStop=/usr/local/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..c8a59ab25bbd --- /dev/null +++ b/files/build_templates/per_namespace/database.service.j2 @@ -0,0 +1,24 @@ +[Unit] +Description=Database container +{% if multi_instance == 'true' %} +Requires=database.service +After=database.service +{% endif %} +Wants=database-chassis.service +After=database-chassis.service +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..8ac19037ffe7 --- /dev/null +++ b/files/build_templates/per_namespace/swss.service.j2 @@ -0,0 +1,29 @@ +[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 +{% endif %} +Requires=updategraph.service +After=updategraph.service +After=interfaces-config.service +Before=ntp-config.service pmon.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..8e0029a29421 --- /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.service +After=nps-modules.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=480 +{% 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..f5936baa6a79 --- /dev/null +++ b/files/build_templates/per_namespace/teamd.service.j2 @@ -0,0 +1,23 @@ +[Unit] +Description=TEAMD container +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 %} +Requires=updategraph.service +After=updategraph.service +Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 + +[Service] +User={{ sonicadmin_user }} +ExecStartPre=/usr/local/bin/{{docker_container_name}}.sh start{% if multi_instance == 'true' %} %i{% endif %} +ExecStart=/usr/local/bin/{{docker_container_name}}.sh wait{% if multi_instance == 'true' %} %i{% endif %} +ExecStop=/usr/local/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/qos_config.j2 b/files/build_templates/qos_config.j2 index 2a9a5be8d83c..a7c361d69fa5 100644 --- a/files/build_templates/qos_config.j2 +++ b/files/build_templates/qos_config.j2 @@ -73,7 +73,7 @@ "7": "7" } }, -{% if 'type' in DEVICE_METADATA['localhost'] and DEVICE_METADATA['localhost']['type'] in backend_device_types %} +{% if 'type' in DEVICE_METADATA['localhost'] and DEVICE_METADATA['localhost']['type'] in backend_device_types and 'storage_device' in DEVICE_METADATA['localhost'] and DEVICE_METADATA['localhost']['storage_device'] == 'true' %} "DOT1P_TO_TC_MAP": { "AZURE": { "0": "0", @@ -177,7 +177,7 @@ "PORT_QOS_MAP": { {% for port in PORT_ACTIVE %} "{{ port }}": { -{% if 'type' in DEVICE_METADATA['localhost'] and DEVICE_METADATA['localhost']['type'] in backend_device_types %} +{% if 'type' in DEVICE_METADATA['localhost'] and DEVICE_METADATA['localhost']['type'] in backend_device_types and 'storage_device' in DEVICE_METADATA['localhost'] and DEVICE_METADATA['localhost']['storage_device'] == 'true' %} "dot1p_to_tc_map" : "[DOT1P_TO_TC_MAP|AZURE]", {% else %} "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", @@ -193,6 +193,9 @@ {% endfor %} }, +{% if generate_wred_profiles is defined %} + {{- generate_wred_profiles() }} +{% else %} "WRED_PROFILE": { "AZURE_LOSSLESS" : { "wred_green_enable" : "true", @@ -210,6 +213,7 @@ "red_drop_probability" : "5" } }, +{% endif %} "QUEUE": { {% for port in PORT_ACTIVE %} "{{ port }}|3": { diff --git a/files/build_templates/radv.service.j2 b/files/build_templates/radv.service.j2 index b3dd3a8d8bcb..5cf25a21046d 100644 --- a/files/build_templates/radv.service.j2 +++ b/files/build_templates/radv.service.j2 @@ -8,9 +8,9 @@ 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 +ExecStartPre=/usr/local/bin/{{ docker_container_name }}.sh start +ExecStart=/usr/local/bin/{{ docker_container_name }}.sh wait +ExecStop=/usr/local/bin/{{ docker_container_name }}.sh stop Restart=always RestartSec=30 diff --git a/files/build_templates/sflow.service.j2 b/files/build_templates/sflow.service.j2 index 643bf646964d..e9d5a871432d 100644 --- a/files/build_templates/sflow.service.j2 +++ b/files/build_templates/sflow.service.j2 @@ -1,7 +1,7 @@ [Unit] Description=sFlow container Requisite=swss.service -After=swss.service syncd.service +After=swss.service syncd.service hostcfgd.service Before=ntp-config.service StartLimitIntervalSec=1200 StartLimitBurst=3 diff --git a/files/build_templates/share_image/database.service.j2 b/files/build_templates/share_image/database.service.j2 new file mode 100644 index 000000000000..cc3f1b0a4364 --- /dev/null +++ b/files/build_templates/share_image/database.service.j2 @@ -0,0 +1,20 @@ +[Unit] +Description=database-chassis container +Requires=docker.service +ConditionPathExists=/etc/sonic/chassisdb.conf +After=docker.service +After=config-chassisdb.service +Requires=config-chassisdb.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 + +[Service] +User=root +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start chassisdb +ExecStart=/usr/bin/{{docker_container_name}}.sh wait chassisdb +ExecStop=/usr/bin/{{docker_container_name}}.sh stop chassisdb +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/snmp.timer b/files/build_templates/snmp.timer index 6d1838554d0e..1b3ccf633ce4 100644 --- a/files/build_templates/snmp.timer +++ b/files/build_templates/snmp.timer @@ -1,6 +1,7 @@ [Unit] Description=Delays snmp container until SONiC has started Conflicts=snmp.service +After=swss.service [Timer] OnUnitActiveSec=0 sec diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 50f242a0a0c4..ba1d781b11ab 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -1,6 +1,6 @@ #!/bin/bash ## This script is to automate loading of vendor specific docker images -## and instalation of configuration files and vendor specific packages +## and installation of configuration files and vendor specific packages ## to debian file system. ## ## USAGE: @@ -27,14 +27,17 @@ set -x -e CONFIGURED_ARCH=$([ -f .arch ] && cat .arch || echo amd64) . functions.sh +BUILD_SCRIPTS_DIR=files/build_scripts BUILD_TEMPLATES=files/build_templates IMAGE_CONFIGS=files/image_config SCRIPTS_DIR=files/scripts # Define target fold macro FILESYSTEM_ROOT_USR="$FILESYSTEM_ROOT/usr" +FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM="$FILESYSTEM_ROOT/usr/lib/systemd/system" FILESYSTEM_ROOT_USR_SHARE="$FILESYSTEM_ROOT_USR/share" FILESYSTEM_ROOT_USR_SHARE_SONIC="$FILESYSTEM_ROOT_USR_SHARE/sonic" +FILESYSTEM_ROOT_USR_SHARE_SONIC_SCRIPTS="$FILESYSTEM_ROOT_USR_SHARE_SONIC/scripts" FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES="$FILESYSTEM_ROOT_USR_SHARE_SONIC/templates" FILESYSTEM_ROOT_ETC="$FILESYSTEM_ROOT/etc" FILESYSTEM_ROOT_ETC_SONIC="$FILESYSTEM_ROOT_ETC/sonic" @@ -42,9 +45,9 @@ FILESYSTEM_ROOT_ETC_SONIC="$FILESYSTEM_ROOT_ETC/sonic" GENERATED_SERVICE_FILE="$FILESYSTEM_ROOT/etc/sonic/generated_services.conf" clean_sys() { - sudo umount $FILESYSTEM_ROOT/sys/fs/cgroup/* \ - $FILESYSTEM_ROOT/sys/fs/cgroup \ - $FILESYSTEM_ROOT/sys || true + sudo chroot $FILESYSTEM_ROOT umount /sys/fs/cgroup/* \ + /sys/fs/cgroup \ + /sys || true } trap_push clean_sys sudo LANG=C chroot $FILESYSTEM_ROOT mount sysfs /sys -t sysfs @@ -76,6 +79,9 @@ sudo mkdir -p $FILESYSTEM_ROOT/etc/sonic/ sudo mkdir -p $FILESYSTEM_ROOT/etc/modprobe.d/ sudo mkdir -p $FILESYSTEM_ROOT/var/cache/sonic/ sudo mkdir -p $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ +# This is needed for Stretch and might not be needed for Buster where Linux create this directory by default. +# Keeping it generic. It should not harm anyways. +sudo mkdir -p $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM # Install a more recent version of ifupdown2 (and its dependencies via 'apt-get -y install -f') sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/ifupdown2_*.deb || \ @@ -85,66 +91,176 @@ sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/ifupdown2_*.deb || \ 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 a more recent version of ntp (and its dependencies via 'apt-get -y install -f') +sudo dpkg --root=$FILESYSTEM_ROOT --force-confdef --force-confold -i $debs_path/ntp_*.deb || \ + sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y \ + -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" install -f + # Install dependencies for SONiC config engine sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install \ python-dev \ - python-lxml \ - python-yaml \ - python-bitarray - -# Install SONiC config engine Python package -CONFIG_ENGINE_WHEEL_NAME=$(basename {{config_engine_wheel_path}}) -sudo cp {{config_engine_wheel_path}} $FILESYSTEM_ROOT/$CONFIG_ENGINE_WHEEL_NAME -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $CONFIG_ENGINE_WHEEL_NAME -sudo rm -rf $FILESYSTEM_ROOT/$CONFIG_ENGINE_WHEEL_NAME + python3-dev # Install Python client for Redis -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install "redis==2.10.6" +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install "redis==3.5.3" +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install "redis==3.5.3" + +# Install redis-dump-load Python 3 package +# Note: the scripts will be overwritten by corresponding Python 2 package +REDIS_DUMP_LOAD_PY3_WHEEL_NAME=$(basename {{redis_dump_load_py3_wheel_path}}) +sudo cp {{redis_dump_load_py3_wheel_path}} $FILESYSTEM_ROOT/$REDIS_DUMP_LOAD_PY3_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $REDIS_DUMP_LOAD_PY3_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$REDIS_DUMP_LOAD_PY3_WHEEL_NAME # Install redis-dump-load Python 2 package REDIS_DUMP_LOAD_PY2_WHEEL_NAME=$(basename {{redis_dump_load_py2_wheel_path}}) sudo cp {{redis_dump_load_py2_wheel_path}} $FILESYSTEM_ROOT/$REDIS_DUMP_LOAD_PY2_WHEEL_NAME -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $REDIS_DUMP_LOAD_PY2_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install $REDIS_DUMP_LOAD_PY2_WHEEL_NAME sudo rm -rf $FILESYSTEM_ROOT/$REDIS_DUMP_LOAD_PY2_WHEEL_NAME -# Install Python module for ipaddress -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install ipaddress +# Install Python module for psutil +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install psutil + +# Install SwSS SDK Python 3 package +# Note: the scripts will be overwritten by corresponding Python 2 package +SWSSSDK_PY3_WHEEL_NAME=$(basename {{swsssdk_py3_wheel_path}}) +sudo cp {{swsssdk_py3_wheel_path}} $FILESYSTEM_ROOT/$SWSSSDK_PY3_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $SWSSSDK_PY3_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$SWSSSDK_PY3_WHEEL_NAME # Install SwSS SDK Python 2 package SWSSSDK_PY2_WHEEL_NAME=$(basename {{swsssdk_py2_wheel_path}}) sudo cp {{swsssdk_py2_wheel_path}} $FILESYSTEM_ROOT/$SWSSSDK_PY2_WHEEL_NAME -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $SWSSSDK_PY2_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install $SWSSSDK_PY2_WHEEL_NAME sudo rm -rf $FILESYSTEM_ROOT/$SWSSSDK_PY2_WHEEL_NAME +# Install sonic-py-common Python 2 package +SONIC_PY_COMMON_PY2_WHEEL_NAME=$(basename {{sonic_py_common_py2_wheel_path}}) +sudo cp {{sonic_py_common_py2_wheel_path}} $FILESYSTEM_ROOT/$SONIC_PY_COMMON_PY2_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install $SONIC_PY_COMMON_PY2_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$SONIC_PY_COMMON_PY2_WHEEL_NAME + +# Install sonic-py-common Python 3 package +SONIC_PY_COMMON_PY3_WHEEL_NAME=$(basename {{sonic_py_common_py3_wheel_path}}) +sudo cp {{sonic_py_common_py3_wheel_path}} $FILESYSTEM_ROOT/$SONIC_PY_COMMON_PY3_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $SONIC_PY_COMMON_PY3_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$SONIC_PY_COMMON_PY3_WHEEL_NAME + +# Install dependency pkgs for SONiC config engine Python 2 package +if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then + sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install libxslt-dev libz-dev +fi + +# Install SONiC config engine Python 2 package +CONFIG_ENGINE_PY2_WHEEL_NAME=$(basename {{config_engine_py2_wheel_path}}) +sudo cp {{config_engine_py2_wheel_path}} $FILESYSTEM_ROOT/$CONFIG_ENGINE_PY2_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install $CONFIG_ENGINE_PY2_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$CONFIG_ENGINE_PY2_WHEEL_NAME + +# For sonic-config-engine Python 3 package +# Install pyangbind here, outside sonic-config-engine dependencies, as pyangbind causes enum34 to be installed. +# Then immediately uninstall enum34, as enum34 should not be installed for Python >= 3.4, as it causes a +# conflict with the new 'enum' module in the standard library +# https://github.com/robshakir/pyangbind/issues/232 +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install pyangbind==0.8.1 +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 uninstall -y enum34 + +# Install SONiC config engine Python 3 package +CONFIG_ENGINE_PY3_WHEEL_NAME=$(basename {{config_engine_py3_wheel_path}}) +sudo cp {{config_engine_py3_wheel_path}} $FILESYSTEM_ROOT/$CONFIG_ENGINE_PY3_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $CONFIG_ENGINE_PY3_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$CONFIG_ENGINE_PY3_WHEEL_NAME + +# Install sonic-yang-models py3 package, install dependencies +sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/libyang_*.deb +sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/libyang-cpp_*.deb +sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/python2-yang_*.deb +sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/python3-yang_*.deb +SONIC_YANG_MODEL_PY3_WHEEL_NAME=$(basename {{sonic_yang_models_py3_wheel_path}}) +sudo cp {{sonic_yang_models_py3_wheel_path}} $FILESYSTEM_ROOT/$SONIC_YANG_MODEL_PY3_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $SONIC_YANG_MODEL_PY3_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$SONIC_YANG_MODEL_PY3_WHEEL_NAME + +# Install sonic-yang-mgmt Python3 package +SONIC_YANG_MGMT_PY3_WHEEL_NAME=$(basename {{sonic_yang_mgmt_py3_wheel_path}}) +sudo cp {{sonic_yang_mgmt_py3_wheel_path}} $FILESYSTEM_ROOT/$SONIC_YANG_MGMT_PY3_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $SONIC_YANG_MGMT_PY3_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$SONIC_YANG_MGMT_PY3_WHEEL_NAME + # Install sonic-platform-common Python 2 package PLATFORM_COMMON_PY2_WHEEL_NAME=$(basename {{platform_common_py2_wheel_path}}) sudo cp {{platform_common_py2_wheel_path}} $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY2_WHEEL_NAME -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $PLATFORM_COMMON_PY2_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install $PLATFORM_COMMON_PY2_WHEEL_NAME sudo rm -rf $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY2_WHEEL_NAME -# Install sonic-daemon-base Python 2 package -DAEMON_BASE_PY2_WHEEL_NAME=$(basename {{daemon_base_py2_wheel_path}}) -sudo cp {{daemon_base_py2_wheel_path}} $FILESYSTEM_ROOT/$DAEMON_BASE_PY2_WHEEL_NAME -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $DAEMON_BASE_PY2_WHEEL_NAME -sudo rm -rf $FILESYSTEM_ROOT/$DAEMON_BASE_PY2_WHEEL_NAME +# Install sonic-platform-common Python 3 package +PLATFORM_COMMON_PY3_WHEEL_NAME=$(basename {{platform_common_py3_wheel_path}}) +sudo cp {{platform_common_py3_wheel_path}} $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY3_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $PLATFORM_COMMON_PY3_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY3_WHEEL_NAME + +{% if pddf_support == "y" %} +# Install pddf-platform-api-base Python 2 package +PLATFORM_PDDF_COMMON_PY2_WHEEL_NAME=$(basename {{pddf_platform_api_base_py2_wheel_path}}) +sudo cp {{pddf_platform_api_base_py2_wheel_path}} $FILESYSTEM_ROOT/$PLATFORM_PDDF_COMMON_PY2_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install $PLATFORM_PDDF_COMMON_PY2_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$PLATFORM_PDDF_COMMON_PY2_WHEEL_NAME + +# Install pddf-platform-api-base Python 3 package +PLATFORM_PDDF_COMMON_PY3_WHEEL_NAME=$(basename {{pddf_platform_api_base_py3_wheel_path}}) +sudo cp {{pddf_platform_api_base_py3_wheel_path}} $FILESYSTEM_ROOT/$PLATFORM_PDDF_COMMON_PY3_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $PLATFORM_PDDF_COMMON_PY3_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$PLATFORM_PDDF_COMMON_PY3_WHEEL_NAME +{% endif %} + +{# Barefoot platform vendors' sonic_platform packages import the Python 'thrift' library #} +{% if sonic_asic_platform == "barefoot" %} +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install thrift==0.13.0 +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install thrift==0.13.0 +{% endif %} + +# Install system-health Python 3 package +SYSTEM_HEALTH_PY3_WHEEL_NAME=$(basename {{system_health_py3_wheel_path}}) +sudo cp {{system_health_py3_wheel_path}} $FILESYSTEM_ROOT/$SYSTEM_HEALTH_PY3_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $SYSTEM_HEALTH_PY3_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$SYSTEM_HEALTH_PY3_WHEEL_NAME + +# Install prerequisites needed for installing the Python m2crypto package, used by sonic-utilities +# These packages can be uninstalled after intallation +sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install build-essential libssl-dev swig + +# Install prerequisites needed for using the Python m2crypto package, used by sonic-utilities +sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install openssl + +# Install SONiC Utilities Python package +SONIC_UTILITIES_PY3_WHEEL_NAME=$(basename {{sonic_utilities_py3_wheel_path}}) +sudo cp {{sonic_utilities_py3_wheel_path}} $FILESYSTEM_ROOT/$SONIC_UTILITIES_PY3_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $SONIC_UTILITIES_PY3_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$SONIC_UTILITIES_PY3_WHEEL_NAME -# Install built Python Click package (and its dependencies via 'apt-get -y install -f') -# Do this before installing sonic-utilities so that it doesn't attempt to install -# an older version as part of its dependencies -sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/python-click*_all.deb || \ +# Install sonic-utilities data files (and any dependencies via 'apt-get -y install -f') +sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/sonic-utilities-data_*.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f -# Install python pexpect used by sonic-utilities consutil -# using pip install instead to get a more recent version than is available through debian -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install pexpect -# Install python click-default-group by sonic-utilities -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install click-default-group==1.2 +# sonic-utilities-data 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/ + +# Install prerequisites needed for installing the dependent Python packages of sonic-host-services +# These packages can be uninstalled after installation +sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install libcairo2-dev libdbus-1-dev libgirepository1.0-dev libsystemd-dev pkg-config -# Install tabulate >= 0.8.1 via pip in order to support multi-line row output for sonic-utilities -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install tabulate==0.8.2 +# Manually install runtime dependencies to avoid them being auto-removed while uninstalling build dependencies +sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install gir1.2-glib-2.0 libdbus-1-3 libgirepository-1.0-1 libsystemd0 -# Install SONiC Utilities (and its dependencies via 'apt-get -y install -f') -sudo dpkg --root=$FILESYSTEM_ROOT -i $python_debs_path/python-sonic-utilities_*.deb || \ +# Install SONiC host services package +SONIC_HOST_SERVICES_PY3_WHEEL_NAME=$(basename {{sonic_host_services_py3_wheel_path}}) +sudo cp {{sonic_host_services_py3_wheel_path}} $FILESYSTEM_ROOT/$SONIC_HOST_SERVICES_PY3_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $SONIC_HOST_SERVICES_PY3_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$SONIC_HOST_SERVICES_PY3_WHEEL_NAME + +# Install SONiC host services data files (and any dependencies via 'apt-get -y install -f') +sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/sonic-host-services-data_*.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f {% if enable_ztp == "y" %} @@ -153,10 +269,6 @@ 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/ - # Install SONiC Device Data (and its dependencies via 'apt-get -y install -f') sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/sonic-device-data_*.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f @@ -176,8 +288,16 @@ sudo sed -i -e '/^passwd/s/ tacplus//' $FILESYSTEM_ROOT/etc/nsswitch.conf 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=true chroot $FILESYSTEM_ROOT apt-get -q --no-install-suggests --no-install-recommends --force-no install + cat $IMAGE_CONFIGS/kdump/kdump-tools | sudo tee -a $FILESYSTEM_ROOT/etc/default/kdump-tools > /dev/null fi +# Install python-swss-common package and all its dependent packages +{% if python_swss_debs.strip() -%} +{% for deb in python_swss_debs.strip().split(' ') -%} +sudo dpkg --root=$FILESYSTEM_ROOT -i {{deb}} || sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f +{% endfor %} +{% endif %} + # Install custom-built monit package and SONiC configuration files sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/monit_*.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f @@ -185,28 +305,54 @@ sudo cp $IMAGE_CONFIGS/monit/monitrc $FILESYSTEM_ROOT/etc/monit/ sudo chmod 600 $FILESYSTEM_ROOT/etc/monit/monitrc sudo cp $IMAGE_CONFIGS/monit/conf.d/* $FILESYSTEM_ROOT/etc/monit/conf.d/ sudo chmod 600 $FILESYSTEM_ROOT/etc/monit/conf.d/* +sudo cp $IMAGE_CONFIGS/monit/process_checker $FILESYSTEM_ROOT/usr/bin/ +sudo chmod 755 $FILESYSTEM_ROOT/usr/bin/process_checker +sudo cp $IMAGE_CONFIGS/monit/container_checker $FILESYSTEM_ROOT/usr/bin/ +sudo chmod 755 $FILESYSTEM_ROOT/usr/bin/container_checker + + +# Install custom-built openssh sshd +sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/openssh-server_*.deb # Copy crontabs sudo cp -f $IMAGE_CONFIGS/cron.d/* $FILESYSTEM_ROOT/etc/cron.d/ # Copy NTP configuration files and templates -sudo cp $IMAGE_CONFIGS/ntp/ntp-config.service $FILESYSTEM_ROOT/etc/systemd/system/ +sudo cp $IMAGE_CONFIGS/ntp/ntp-config.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM echo "ntp-config.service" | sudo tee -a $GENERATED_SERVICE_FILE sudo cp $IMAGE_CONFIGS/ntp/ntp-config.sh $FILESYSTEM_ROOT/usr/bin/ sudo cp $IMAGE_CONFIGS/ntp/ntp.conf.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ +sudo cp $IMAGE_CONFIGS/ntp/ntp-systemd-wrapper $FILESYSTEM_ROOT/usr/lib/ntp/ +sudo cp $IMAGE_CONFIGS/ntp/ntp.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM +echo "ntp.service" | sudo tee -a $GENERATED_SERVICE_FILE # Copy warmboot-finalizer files sudo LANG=C cp $IMAGE_CONFIGS/warmboot-finalizer/finalize-warmboot.sh $FILESYSTEM_ROOT/usr/local/bin/finalize-warmboot.sh -sudo LANG=C cp $IMAGE_CONFIGS/warmboot-finalizer/warmboot-finalizer.service $FILESYSTEM_ROOT/etc/systemd/system/ +sudo LANG=C cp $IMAGE_CONFIGS/warmboot-finalizer/warmboot-finalizer.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM echo "warmboot-finalizer.service" | sudo tee -a $GENERATED_SERVICE_FILE +# Copy watchdog-control files +sudo LANG=C cp $IMAGE_CONFIGS/watchdog-control/watchdog-control.sh $FILESYSTEM_ROOT/usr/local/bin/watchdog-control.sh +sudo LANG=C cp $IMAGE_CONFIGS/watchdog-control/watchdog-control.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM +echo "watchdog-control.service" | sudo tee -a $GENERATED_SERVICE_FILE + # Copy rsyslog configuration files and templates -sudo cp $IMAGE_CONFIGS/rsyslog/rsyslog-config.service $FILESYSTEM_ROOT/etc/systemd/system/ +sudo cp $IMAGE_CONFIGS/rsyslog/rsyslog-config.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM sudo cp $IMAGE_CONFIGS/rsyslog/rsyslog-config.sh $FILESYSTEM_ROOT/usr/bin/ sudo cp $IMAGE_CONFIGS/rsyslog/rsyslog.conf.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ +sudo cp $IMAGE_CONFIGS/rsyslog/rsyslog-container.conf.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ sudo cp $IMAGE_CONFIGS/rsyslog/rsyslog.d/* $FILESYSTEM_ROOT/etc/rsyslog.d/ echo "rsyslog-config.service" | sudo tee -a $GENERATED_SERVICE_FILE +# Copy syslog override files +sudo mkdir -p $FILESYSTEM_ROOT/etc/systemd/system/syslog.socket.d +sudo cp $IMAGE_CONFIGS/syslog/override.conf $FILESYSTEM_ROOT/etc/systemd/system/syslog.socket.d/override.conf +sudo cp $IMAGE_CONFIGS/syslog/host_umount.sh $FILESYSTEM_ROOT/usr/bin/ + +# Copy system-health files +sudo LANG=C cp $IMAGE_CONFIGS/system-health/system-health.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM +echo "system-health.service" | sudo tee -a $GENERATED_SERVICE_FILE + # Copy logrotate.d configuration files sudo cp -f $IMAGE_CONFIGS/logrotate/logrotate.d/* $FILESYSTEM_ROOT/etc/logrotate.d/ @@ -214,11 +360,17 @@ sudo cp -f $IMAGE_CONFIGS/logrotate/logrotate.d/* $FILESYSTEM_ROOT/etc/logrotate sudo cp -f $IMAGE_CONFIGS/systemd/journald.conf $FILESYSTEM_ROOT/etc/systemd/ # Copy interfaces configuration files and templates -sudo cp $IMAGE_CONFIGS/interfaces/interfaces-config.service $FILESYSTEM_ROOT/etc/systemd/system/ +sudo cp $IMAGE_CONFIGS/interfaces/interfaces-config.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM 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 CoPP configuration files and templates +sudo cp $IMAGE_CONFIGS/copp/copp-config.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM +sudo cp $IMAGE_CONFIGS/copp/copp-config.sh $FILESYSTEM_ROOT/usr/bin/ +sudo cp $IMAGE_CONFIGS/copp/copp_cfg.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ +echo "copp-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 @@ -229,21 +381,60 @@ sudo cp files/dhcp/90-dhcp6-systcl.conf.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMP sudo cp $IMAGE_CONFIGS/interfaces/init_interfaces $FILESYSTEM_ROOT/etc/network/interfaces sudo mkdir -p $FILESYSTEM_ROOT/etc/network/interfaces.d -# Copy hostcfgd files -sudo cp $IMAGE_CONFIGS/hostcfgd/hostcfgd.service $FILESYSTEM_ROOT/etc/systemd/system/ -echo "hostcfgd.service" | sudo tee -a $GENERATED_SERVICE_FILE -sudo cp $IMAGE_CONFIGS/hostcfgd/hostcfgd $FILESYSTEM_ROOT/usr/bin/ -sudo cp $IMAGE_CONFIGS/hostcfgd/*.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ - # copy core file uploader files -sudo cp $IMAGE_CONFIGS/corefile_uploader/core_uploader.service $FILESYSTEM_ROOT/etc/systemd/system/ +sudo cp $IMAGE_CONFIGS/corefile_uploader/core_uploader.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM sudo LANG=C chroot $FILESYSTEM_ROOT systemctl disable core_uploader.service sudo cp $IMAGE_CONFIGS/corefile_uploader/core_uploader.py $FILESYSTEM_ROOT/usr/bin/ sudo cp $IMAGE_CONFIGS/corefile_uploader/core_analyzer.rc.json $FILESYSTEM_ROOT_ETC_SONIC/ sudo chmod og-rw $FILESYSTEM_ROOT_ETC_SONIC/core_analyzer.rc.json -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install azure-storage -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 + +sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install libffi-dev libssl-dev + +if [[ $CONFIGURED_ARCH == armhf ]]; then + # The azure-storage package depends on the cryptography package. Newer + # versions of cryptography require the rust compiler, the correct version + # for which is not readily available in buster. Hence we pre-install an + # older version here to satisfy the azure-storage dependency. + # Note: This is not a problem for other architectures as pre-built versions + # of cryptography are available for those. This sequence can be removed + # after upgrading to debian bullseye. + sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install cryptography==3.3.1 +fi +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install azure-storage==0.36.0 +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install watchdog==0.10.3 + +{% if include_kubernetes == "y" %} +# Install remote Container mgmt package +# Required even if include_kubernetes != y, as it contains the +# the container wrapper for docker start/stop/wait commands. +# +SONIC_CTRMGMT_WHEEL_NAME=$(basename {{sonic_ctrmgmt_py3_wheel_path}}) +sudo cp {{sonic_ctrmgmt_py3_wheel_path}} $FILESYSTEM_ROOT/$SONIC_CTRMGMT_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $SONIC_CTRMGMT_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$SONIC_CTRMGMT_WHEEL_NAME + +# Copy remote container mangement files +# File called from each container upon start/stop to record the state +sudo mkdir -p ${FILESYSTEM_ROOT_USR_SHARE_SONIC_SCRIPTS} +sudo cp ${files_path}/container_startup.py ${FILESYSTEM_ROOT_USR_SHARE_SONIC_SCRIPTS}/ +sudo chmod a+x ${FILESYSTEM_ROOT_USR_SHARE_SONIC_SCRIPTS}/container_startup.py + +# Config file used by container mgmt scripts/service +sudo cp ${files_path}/remote_ctr.config.json ${FILESYSTEM_ROOT_ETC_SONIC}/ + +# Remote container management service files +sudo cp ${files_path}/ctrmgrd.service ${FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM}/ +sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable ctrmgrd.service + +# kubelet service is controlled by ctrmgrd daemon. +sudo LANG=C chroot $FILESYSTEM_ROOT systemctl disable kubelet.service +{% else %} +# container script for docker commands, which is required as +# all docker commands are replaced with container commands. +# So just copy that file only. +# +sudo cp ${files_path}/container $FILESYSTEM_ROOT/usr/local/bin/ +{% endif %} # Copy the buffer configuration template sudo cp $BUILD_TEMPLATES/buffers_config.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ @@ -251,8 +442,21 @@ sudo cp $BUILD_TEMPLATES/buffers_config.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMP # Copy the qos configuration template sudo cp $BUILD_TEMPLATES/qos_config.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ +# Copy the templates for dynamically buffer calculation +{% if sonic_asic_platform == "mellanox" or sonic_asic_platform == "vs" %} +if [ -f platform/{{ sonic_asic_platform }}/asic_table.j2 ] +then + sudo cp platform/{{ sonic_asic_platform }}/asic_table.j2 $FILESYSTEM_ROOT/usr/share/sonic/templates/asic_table.j2 +fi + +if [ -f platform/{{ sonic_asic_platform }}/peripheral_table.j2 ] +then + sudo cp platform/{{ sonic_asic_platform }}/peripheral_table.j2 $FILESYSTEM_ROOT/usr/share/sonic/templates/peripheral_table.j2 +fi +{% endif %} + # Copy hostname configuration scripts -sudo cp $IMAGE_CONFIGS/hostname/hostname-config.service $FILESYSTEM_ROOT/etc/systemd/system/ +sudo cp $IMAGE_CONFIGS/hostname/hostname-config.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM echo "hostname-config.service" | sudo tee -a $GENERATED_SERVICE_FILE sudo cp $IMAGE_CONFIGS/hostname/hostname-config.sh $FILESYSTEM_ROOT/usr/bin/ @@ -261,13 +465,13 @@ 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/ +sudo cp $IMAGE_CONFIGS/topology/topology.service $FILESYSTEM_ROOT_USR_LIB_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 +j2 files/build_templates/updategraph.service.j2 | sudo tee $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM/updategraph.service sudo cp $IMAGE_CONFIGS/updategraph/updategraph $FILESYSTEM_ROOT/usr/bin/ echo "updategraph.service" | sudo tee -a $GENERATED_SERVICE_FILE {% if enable_dhcp_graph_service == "y" %} @@ -282,10 +486,17 @@ sudo bash -c "echo enabled=false > $FILESYSTEM_ROOT/etc/sonic/updategraph.conf" 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 +j2 files/build_templates/config-setup.service.j2 | sudo tee $FILESYSTEM_ROOT_USR_LIB_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 config-chassisdb script and service file +j2 files/build_templates/config-chassisdb.service.j2 | sudo tee $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM/config-chassisdb.service +sudo cp $IMAGE_CONFIGS/config-chassisdb/config-chassisdb $FILESYSTEM_ROOT/usr/bin/config-chassisdb +echo "config-chassisdb.service" | sudo tee -a $GENERATED_SERVICE_FILE +sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable config-chassisdb.service + # Copy SNMP configuration files sudo cp $IMAGE_CONFIGS/snmp/snmp.yml $FILESYSTEM_ROOT/etc/sonic/ @@ -296,25 +507,14 @@ sudo cp $IMAGE_CONFIGS/constants/constants.yml $FILESYSTEM_ROOT/etc/sonic/ sudo cp $IMAGE_CONFIGS/sudoers/sudoers $FILESYSTEM_ROOT/etc/ sudo cp $IMAGE_CONFIGS/sudoers/sudoers.lecture $FILESYSTEM_ROOT/etc/ -# Copy control plane ACL management daemon files -sudo cp $IMAGE_CONFIGS/caclmgrd/caclmgrd.service $FILESYSTEM_ROOT/etc/systemd/system/ -echo "caclmgrd.service" | sudo tee -a $GENERATED_SERVICE_FILE -sudo cp $IMAGE_CONFIGS/caclmgrd/caclmgrd $FILESYSTEM_ROOT/usr/bin/ - -# Copy process/docker cpu/memory utilization data export daemon -sudo cp $IMAGE_CONFIGS/procdockerstatsd/procdockerstatsd.service $FILESYSTEM_ROOT/etc/systemd/system/ -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 +sudo cp $BUILD_TEMPLATES/pcie-check.timer $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM +sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable pcie-check.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 -sudo cp $IMAGE_CONFIGS/process-reboot-cause/process-reboot-cause $FILESYSTEM_ROOT/usr/bin/ +# Copy pcie-check service files +sudo cp $IMAGE_CONFIGS/pcie-check/pcie-check.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM +echo "pcie-check.service" | sudo tee -a $GENERATED_SERVICE_FILE +sudo cp $IMAGE_CONFIGS/pcie-check/pcie-check.sh $FILESYSTEM_ROOT/usr/bin/ ## Install package without starting service ## ref: https://wiki.debian.org/chroot @@ -326,11 +526,7 @@ sudo chmod a+x $FILESYSTEM_ROOT/usr/sbin/policy-rc.d {% if installer_debs.strip() -%} {% for deb in installer_debs.strip().split(' ') -%} -{% if sonic_asic_platform == "mellanox" %} -sudo dpkg --extract {{deb}} $FILESYSTEM_ROOT -{% else %} sudo dpkg --root=$FILESYSTEM_ROOT -i {{deb}} || sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f -{% endif %} {% endfor %} {% endif %} @@ -362,7 +558,7 @@ sudo dpkg --root=$FILESYSTEM_ROOT -P {{ debname }} sudo rm -f $FILESYSTEM_ROOT/usr/sbin/policy-rc.d # Copy fstrim service and timer file, enable fstrim timer -sudo cp $IMAGE_CONFIGS/fstrim/* $FILESYSTEM_ROOT/etc/systemd/system/ +sudo cp $IMAGE_CONFIGS/fstrim/* $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable fstrim.timer ## copy platform rc.local @@ -386,18 +582,35 @@ if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then fi {% if installer_images.strip() -%} +clean_proc() { + sudo umount /proc || true +} +trap_push clean_proc +sudo mount proc /proc -t proc +sudo mkdir $FILESYSTEM_ROOT/target +sudo mount --bind target $FILESYSTEM_ROOT/target sudo chroot $FILESYSTEM_ROOT docker $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS info {% for image in installer_images.strip().split(' ') -%} {% set imagefilename = image.split('/')|last -%} {% set imagename = imagefilename.split('.')|first -%} -sudo LANG=C chroot $FILESYSTEM_ROOT docker $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS load < {{image}} -sudo LANG=C chroot $FILESYSTEM_ROOT docker $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS tag {{imagename}}:latest {{imagename}}:$(sonic_get_version) +sudo LANG=C chroot $FILESYSTEM_ROOT docker $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS load -i {{image}} +sudo LANG=C chroot $FILESYSTEM_ROOT docker $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS tag {{imagename}}:latest {{imagename}}:"${SONIC_IMAGE_VERSION}" {% if imagename.endswith('-dbg') %} {% set imagebasename = imagename.replace('-dbg', '') -%} -sudo LANG=C chroot $FILESYSTEM_ROOT docker $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS tag {{imagename}}:latest {{imagebasename}}:$(sonic_get_version) +sudo LANG=C chroot $FILESYSTEM_ROOT docker $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS tag {{imagename}}:latest {{imagebasename}}:"${SONIC_IMAGE_VERSION}" sudo LANG=C chroot $FILESYSTEM_ROOT docker $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS tag {{imagename}}:latest {{imagebasename}}:latest {% endif %} {% endfor %} + +{% if include_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} +echo "docker images pull complete" +{% endif %} + +sudo umount $FILESYSTEM_ROOT/target +sudo rm -r $FILESYSTEM_ROOT/target if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then sudo umount $FILESYSTEM_ROOT/dockerfs sudo rm -fr $FILESYSTEM_ROOT/dockerfs @@ -405,41 +618,77 @@ if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then else sudo chroot $FILESYSTEM_ROOT service docker stop fi +sudo umount /proc || true sudo rm $FILESYSTEM_ROOT/etc/init.d/docker + +sudo bash -c "echo { > $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ctr_image_names.json" +{% for entry in feature_vs_image_names.split(' ') -%} +{% if entry|length %} +{% set lst = entry.split(':') %} +{% set lst1 = lst[1].split('.') %} + sudo bash -c "echo -n -e \"\x22{{ lst[0] }}\x22 : \x22{{ lst1[0] }}\x22\" >> $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ctr_image_names.json" +{% if not loop.last %} + sudo bash -c "echo \",\" >> $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ctr_image_names.json" +{% else %} + sudo bash -c "echo \"\" >> $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ctr_image_names.json" +{% endif %} +{% endif %} +{% endfor %} +sudo bash -c "echo } >> $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ctr_image_names.json" + {% for script in installer_start_scripts.split(' ') -%} sudo cp {{script}} $FILESYSTEM_ROOT/usr/bin/ {% endfor %} {% for service in installer_services.split(' ') -%} if [ -f {{service}} ]; then - sudo cp {{service}} $FILESYSTEM_ROOT/etc/systemd/system/ + sudo cp {{service}} $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM {% if "@" in service %} MULTI_INSTANCE="{{service}}" SINGLE_INSTANCE=${MULTI_INSTANCE/"@"} - sudo cp $SINGLE_INSTANCE $FILESYSTEM_ROOT/etc/systemd/system/ + sudo cp $SINGLE_INSTANCE $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM {% endif %} echo "{{service}}" | sudo tee -a $GENERATED_SERVICE_FILE fi {% endfor %} +if [ -f iccpd.service ]; then + sudo LANG=C chroot $FILESYSTEM_ROOT systemctl disable iccpd.service +fi sudo LANG=C chroot $FILESYSTEM_ROOT fuser -km /sys || true sudo LANG=C chroot $FILESYSTEM_ROOT umount -lf /sys {% endif %} -# Copy swss and syncd service script +# Copy service scripts (swss, syncd, bgp, teamd, radv) 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 +sudo LANG=C cp $SCRIPTS_DIR/syncd_common.sh $FILESYSTEM_ROOT/usr/local/bin/syncd_common.sh +sudo LANG=C cp $SCRIPTS_DIR/gbsyncd.sh $FILESYSTEM_ROOT/usr/local/bin/gbsyncd.sh +sudo LANG=C cp $SCRIPTS_DIR/bgp.sh $FILESYSTEM_ROOT/usr/local/bin/bgp.sh +sudo LANG=C cp $SCRIPTS_DIR/teamd.sh $FILESYSTEM_ROOT/usr/local/bin/teamd.sh +sudo LANG=C cp $SCRIPTS_DIR/radv.sh $FILESYSTEM_ROOT/usr/local/bin/radv.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/ -sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable snmp.timer -{% if enable_system_telemetry == 'y' %} -sudo cp $BUILD_TEMPLATES/telemetry.timer $FILESYSTEM_ROOT/etc/systemd/system/ -sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable telemetry.timer +sudo cp $BUILD_TEMPLATES/snmp.timer $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM +echo "snmp.timer" | sudo tee -a $GENERATED_SERVICE_FILE + +{% if include_system_telemetry == 'y' %} +sudo cp $BUILD_TEMPLATES/telemetry.timer $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM +echo "telemetry.timer" | sudo tee -a $GENERATED_SERVICE_FILE +{% endif %} + +{% if include_mgmt_framework == 'y' %} +sudo cp $BUILD_TEMPLATES/mgmt-framework.timer $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM +echo "mgmt-framework.timer" | sudo tee -a $GENERATED_SERVICE_FILE {% endif %} -sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get purge -y python-dev +sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get purge -y python-dev python3-dev +sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get purge -y build-essential libssl-dev swig +sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get purge -y libcairo2-dev libdbus-1-dev libgirepository1.0-dev libsystemd-dev pkg-config sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get clean -y sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get autoremove -y @@ -455,17 +704,25 @@ 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 +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 -# Install mlnx-sonic-platform-common Python 2 package -MLNX_PLATFORM_COMMON_PY2_WHEEL_NAME=$(basename {{mlnx_platform_api_py2_wheel_path}}) -sudo cp {{mlnx_platform_api_py2_wheel_path}} $FILESYSTEM_ROOT/$MLNX_PLATFORM_COMMON_PY2_WHEEL_NAME -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $MLNX_PLATFORM_COMMON_PY2_WHEEL_NAME -sudo rm -rf $FILESYSTEM_ROOT/$MLNX_PLATFORM_COMMON_PY2_WHEEL_NAME +# Install mlnx-sonic-platform Python 2 package +MLNX_SONIC_PLATFORM_PY2_WHEEL_NAME=$(basename {{mlnx_platform_api_py2_wheel_path}}) +sudo cp {{mlnx_platform_api_py2_wheel_path}} $FILESYSTEM_ROOT/$MLNX_SONIC_PLATFORM_PY2_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install $MLNX_SONIC_PLATFORM_PY2_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$MLNX_SONIC_PLATFORM_PY2_WHEEL_NAME + +# Install mlnx-sonic-platform Python 3 package +MLNX_SONIC_PLATFORM_PY3_WHEEL_NAME=$(basename {{mlnx_platform_api_py3_wheel_path}}) +sudo cp {{mlnx_platform_api_py3_wheel_path}} $FILESYSTEM_ROOT/$MLNX_SONIC_PLATFORM_PY3_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $MLNX_SONIC_PLATFORM_PY3_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$MLNX_SONIC_PLATFORM_PY3_WHEEL_NAME {% endif %} {%- if SONIC_ROUTING_STACK == "frr" %} @@ -476,3 +733,9 @@ sudo chown -R $FRR_USER_UID:$FRR_USER_GID $FILESYSTEM_ROOT/etc/sonic/frr sudo chmod -R 640 $FILESYSTEM_ROOT/etc/sonic/frr/ sudo chmod 750 $FILESYSTEM_ROOT/etc/sonic/frr {%- endif %} + +# Mask services which are disabled by default +sudo cp $BUILD_SCRIPTS_DIR/mask_disabled_services.py $FILESYSTEM_ROOT/tmp/ +sudo chmod a+x $FILESYSTEM_ROOT/tmp/mask_disabled_services.py +sudo LANG=C chroot $FILESYSTEM_ROOT /tmp/mask_disabled_services.py +sudo rm -rf $FILESYSTEM_ROOT/tmp/mask_disabled_services.py diff --git a/files/build_templates/swss_vars.j2 b/files/build_templates/swss_vars.j2 new file mode 100644 index 000000000000..a9bd01565c89 --- /dev/null +++ b/files/build_templates/swss_vars.j2 @@ -0,0 +1,6 @@ +{ + "asic_type": "{{ asic_type }}", + "asic_id": "{{ DEVICE_METADATA.localhost.asic_id }}", + "mac": "{{ DEVICE_METADATA.localhost.mac }}", + "synchronous_mode": {% if DEVICE_METADATA.localhost.synchronous_mode == "disable" %}"disable"{% else %}"enable"{% endif %} +} diff --git a/files/docker/docker.service.conf b/files/docker/docker.service.conf index e9ba55c8afa8..7debd85a50ac 100644 --- a/files/docker/docker.service.conf +++ b/files/docker/docker.service.conf @@ -1,3 +1,3 @@ [Service] ExecStart= -ExecStart=/usr/bin/dockerd -H unix:// --storage-driver=overlay2 --bip=240.127.1.1/24 --iptables=false +ExecStart=/usr/bin/dockerd -H unix:// --storage-driver=overlay2 --bip=240.127.1.1/24 --iptables=false --ipv6=true --fixed-cidr-v6=fd00::/80 diff --git a/files/image_config/apt/sources.list.d/amd64/debian_archive_trafficmanager_net_debian.list b/files/image_config/apt/sources.list.d/amd64/debian_archive_trafficmanager_net_debian.list index a6a2c2afc607..d35c618112bb 100644 --- a/files/image_config/apt/sources.list.d/amd64/debian_archive_trafficmanager_net_debian.list +++ b/files/image_config/apt/sources.list.d/amd64/debian_archive_trafficmanager_net_debian.list @@ -1,3 +1,3 @@ -deb [arch=amd64] http://debian-archive.trafficmanager.net/debian/ stretch main contrib non-free -deb [arch=amd64] http://debian-archive.trafficmanager.net/debian-security/ stretch/updates main contrib non-free -deb [arch=amd64] http://debian-archive.trafficmanager.net/debian/ stretch-backports main contrib non-free +deb [arch=amd64] http://debian-archive.trafficmanager.net/debian/ buster main contrib non-free +deb [arch=amd64] http://debian-archive.trafficmanager.net/debian-security/ buster/updates main contrib non-free +deb [arch=amd64] http://debian-archive.trafficmanager.net/debian/ buster-backports main contrib non-free diff --git a/files/image_config/apt/sources.list.d/amd64/packages_microsoft_com_repos_sonic_dev.list b/files/image_config/apt/sources.list.d/amd64/packages_microsoft_com_repos_sonic_dev.list deleted file mode 100644 index 468dcccc6eec..000000000000 --- a/files/image_config/apt/sources.list.d/amd64/packages_microsoft_com_repos_sonic_dev.list +++ /dev/null @@ -1 +0,0 @@ -deb [arch=amd64] http://packages.microsoft.com/repos/sonic-dev/ jessie main diff --git a/files/image_config/apt/sources.list.d/arm64/debian_mirror_arm64.list b/files/image_config/apt/sources.list.d/arm64/debian_mirror_arm64.list index 773f58882ae1..9e7dec92d39e 100644 --- a/files/image_config/apt/sources.list.d/arm64/debian_mirror_arm64.list +++ b/files/image_config/apt/sources.list.d/arm64/debian_mirror_arm64.list @@ -1,9 +1,9 @@ -deb [arch=arm64] http://deb.debian.org/debian stretch main contrib non-free -deb-src [arch=arm64] http://deb.debian.org/debian stretch main contrib non-free -deb [arch=arm64] http://deb.debian.org/debian stretch-updates main contrib non-free -deb-src [arch=arm64] http://deb.debian.org/debian stretch-updates main contrib non-free -deb [arch=arm64] http://security.debian.org stretch/updates main contrib non-free -deb-src [arch=arm64] http://security.debian.org stretch/updates main contrib non-free -deb [arch=arm64] https://download.docker.com/linux/debian stretch stable -deb [arch=arm64] http://ftp.debian.org/debian stretch-backports main +deb [arch=arm64] http://deb.debian.org/debian buster main contrib non-free +deb-src [arch=arm64] http://deb.debian.org/debian buster main contrib non-free +deb [arch=arm64] http://deb.debian.org/debian buster-updates main contrib non-free +deb-src [arch=arm64] http://deb.debian.org/debian buster-updates main contrib non-free +deb [arch=arm64] http://security.debian.org buster/updates main contrib non-free +deb-src [arch=arm64] http://security.debian.org buster/updates main contrib non-free +deb [arch=arm64] https://download.docker.com/linux/debian buster stable +deb [arch=arm64] http://ftp.debian.org/debian buster-backports main diff --git a/files/image_config/apt/sources.list.d/armhf/debian_mirror_armhf.list b/files/image_config/apt/sources.list.d/armhf/debian_mirror_armhf.list index 501419c6735f..a7b831ef301c 100644 --- a/files/image_config/apt/sources.list.d/armhf/debian_mirror_armhf.list +++ b/files/image_config/apt/sources.list.d/armhf/debian_mirror_armhf.list @@ -1,9 +1,9 @@ -deb [arch=armhf] http://deb.debian.org/debian stretch main contrib non-free -deb-src [arch=armhf] http://deb.debian.org/debian stretch main contrib non-free -deb [arch=armhf] http://deb.debian.org/debian stretch-updates main contrib non-free -deb-src [arch=armhf] http://deb.debian.org/debian stretch-updates main contrib non-free -deb [arch=armhf] http://security.debian.org stretch/updates main contrib non-free -deb-src [arch=armhf] http://security.debian.org stretch/updates main contrib non-free -deb [arch=armhf] https://download.docker.com/linux/debian stretch stable -deb [arch=armhf] http://ftp.debian.org/debian stretch-backports main +deb [arch=armhf] http://deb.debian.org/debian buster main contrib non-free +deb-src [arch=armhf] http://deb.debian.org/debian buster main contrib non-free +deb [arch=armhf] http://deb.debian.org/debian buster-updates main contrib non-free +deb-src [arch=armhf] http://deb.debian.org/debian buster-updates main contrib non-free +deb [arch=armhf] http://security.debian.org buster/updates main contrib non-free +deb-src [arch=armhf] http://security.debian.org buster/updates main contrib non-free +deb [arch=armhf] https://download.docker.com/linux/debian buster stable +deb [arch=armhf] http://ftp.debian.org/debian buster-backports main diff --git a/files/image_config/bash/bash.bashrc b/files/image_config/bash/bash.bashrc index 6651a51ceed0..0f19263ae04a 100644 --- a/files/image_config/bash/bash.bashrc +++ b/files/image_config/bash/bash.bashrc @@ -56,3 +56,20 @@ fi # Automatically log out console ttyS* sessions after 15 minutes of inactivity tty | grep ttyS >/dev/null && TMOUT=900 + +# if SSH_TARGET_CONSOLE_LINE was set, attach to console line interactive cli directly +if [ -n "$SSH_TARGET_CONSOLE_LINE" ]; then + if [ $SSH_TARGET_CONSOLE_LINE -eq $SSH_TARGET_CONSOLE_LINE 2>/dev/null ]; then + # enter the interactive cli + connect line $SSH_TARGET_CONSOLE_LINE + + # test exit code, 1 means the console switch feature not enabled + if [ $? -ne 1 ]; then + # exit after console session ended + exit + fi + else + # exit directly when target console line variable is invalid + exit + fi +fi diff --git a/files/image_config/caclmgrd/caclmgrd b/files/image_config/caclmgrd/caclmgrd deleted file mode 100755 index e5744c7ca65b..000000000000 --- a/files/image_config/caclmgrd/caclmgrd +++ /dev/null @@ -1,300 +0,0 @@ -#!/usr/bin/env python -# -# caclmgrd -# -# Control plane ACL manager daemon for SONiC -# -# Upon starting, this daemon reads control plane ACL tables and rules from -# Config DB, converts the rules into iptables rules and installs the iptables -# rules. The daemon then indefintely listens for notifications from Config DB -# and updates iptables rules if control plane ACL configuration has changed. -# - -try: - import ipaddr as ipaddress - import os - import subprocess - import sys - import syslog - from swsssdk import ConfigDBConnector -except ImportError as err: - raise ImportError("%s - required module not found" % str(err)) - -VERSION = "1.0" - -SYSLOG_IDENTIFIER = "caclmgrd" - - -# ========================== Syslog wrappers ========================== - -def log_info(msg): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_INFO, msg) - syslog.closelog() - - -def log_warning(msg): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_WARNING, msg) - syslog.closelog() - - -def log_error(msg): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_ERR, msg) - syslog.closelog() - - -# ============================== Classes ============================== - -class ControlPlaneAclManager(object): - """ - Class which reads control plane ACL tables and rules from Config DB, - translates them into equivalent iptables commands and runs those - commands in order to apply the control plane ACLs. - - Attributes: - config_db: Handle to Config Redis database via SwSS SDK - """ - ACL_TABLE = "ACL_TABLE" - ACL_RULE = "ACL_RULE" - - ACL_TABLE_TYPE_CTRLPLANE = "CTRLPLANE" - - # To specify a port range, use iptables format: separate start and end - # ports with a colon, e.g., "1000:2000" - ACL_SERVICES = { - "NTP": {"ip_protocols": ["udp"], "dst_ports": ["123"]}, - "SNMP": {"ip_protocols": ["tcp", "udp"], "dst_ports": ["161"]}, - "SSH": {"ip_protocols": ["tcp"], "dst_ports": ["22"]} - } - - def __init__(self): - # Open a handle to the Config database - self.config_db = ConfigDBConnector() - self.config_db.connect() - - def run_commands(self, commands): - """ - Given a list of shell commands, run them in order - - Args: - commands: List of strings, each string is a shell command - """ - for cmd in commands: - proc = subprocess.Popen(cmd, shell=True) - - (stdout, stderr) = proc.communicate() - - if proc.returncode != 0: - log_error("Error running command '{}'".format(cmd)) - - def parse_int_to_tcp_flags(self, hex_value): - tcp_flags_str = "" - if hex_value & 0x01: - tcp_flags_str += "FIN," - if hex_value & 0x02: - tcp_flags_str += "SYN," - if hex_value & 0x04: - tcp_flags_str += "RST," - if hex_value & 0x08: - tcp_flags_str += "PSH," - if hex_value & 0x10: - tcp_flags_str += "ACK," - if hex_value & 0x20: - tcp_flags_str += "URG," - # iptables doesn't handle the flags below now. It has some special keys for it: - # --ecn-tcp-cwr This matches if the TCP ECN CWR (Congestion Window Received) bit is set. - # --ecn-tcp-ece This matches if the TCP ECN ECE (ECN Echo) bit is set. - # if hex_value & 0x40: - # tcp_flags_str += "ECE," - # if hex_value & 0x80: - # tcp_flags_str += "CWR," - - # Delete the trailing comma - tcp_flags_str = tcp_flags_str[:-1] - return tcp_flags_str - - def get_acl_rules_and_translate_to_iptables_commands(self): - """ - Retrieves current ACL tables and rules from Config DB, translates - control plane ACLs into a list of iptables commands that can be run - in order to install ACL rules. - - Returns: - A list of strings, each string is an iptables shell command - - """ - iptables_cmds = [] - - # First, add iptables commands to set default policies to accept all - # traffic. In case we are connected remotely, the connection will not - # drop when we flush the current rules - iptables_cmds.append("iptables -P INPUT ACCEPT") - iptables_cmds.append("iptables -P FORWARD ACCEPT") - iptables_cmds.append("iptables -P OUTPUT ACCEPT") - - # Add iptables command to flush the current rules - iptables_cmds.append("iptables -F") - - # Add iptables command to delete all non-default chains - iptables_cmds.append("iptables -X") - - # Add same set of commands for ip6tables - iptables_cmds.append("ip6tables -P INPUT ACCEPT") - iptables_cmds.append("ip6tables -P FORWARD ACCEPT") - iptables_cmds.append("ip6tables -P OUTPUT ACCEPT") - iptables_cmds.append("ip6tables -F") - iptables_cmds.append("ip6tables -X") - - # Add iptables commands to allow all IPv4 and IPv6 traffic from localhost - iptables_cmds.append("iptables -A INPUT -s 127.0.0.1 -i lo -j ACCEPT") - iptables_cmds.append("ip6tables -A INPUT -s ::1 -i lo -j ACCEPT") - - # Get current ACL tables and rules from Config DB - self._tables_db_info = self.config_db.get_table(self.ACL_TABLE) - self._rules_db_info = self.config_db.get_table(self.ACL_RULE) - - # Walk the ACL tables - for (table_name, table_data) in self._tables_db_info.iteritems(): - - table_ip_version = None - - # Ignore non-control-plane ACL tables - if table_data["type"] != self.ACL_TABLE_TYPE_CTRLPLANE: - continue - - acl_services = table_data["services"] - - for acl_service in acl_services: - if acl_service not in self.ACL_SERVICES: - log_warning("Ignoring control plane ACL '{}' with unrecognized service '{}'" - .format(table_name, acl_service)) - continue - - log_info("Translating ACL rules for control plane ACL '{}' (service: '{}')" - .format(table_name, acl_service)) - - # Obtain default IP protocol(s) and destination port(s) for this service - ip_protocols = self.ACL_SERVICES[acl_service]["ip_protocols"] - dst_ports = self.ACL_SERVICES[acl_service]["dst_ports"] - - acl_rules = {} - - for ((rule_table_name, rule_id), rule_props) in self._rules_db_info.iteritems(): - if rule_table_name == table_name: - if not rule_props: - log_warning("rule_props for rule_id {} empty or null!".format(rule_id)) - continue - - try: - acl_rules[rule_props["PRIORITY"]] = rule_props - except KeyError: - log_error("rule_props for rule_id {} does not have key 'PRIORITY'!".format(rule_id)) - continue - - # If we haven't determined the IP version for this ACL table yet, - # try to do it now. We attempt to determine heuristically based on - # whether the src or dst IP of this rule is an IPv4 or IPv6 address. - if not table_ip_version: - if (("SRC_IPV6" in rule_props and rule_props["SRC_IPV6"]) or - ("DST_IPV6" in rule_props and rule_props["DST_IPV6"])): - table_ip_version = 6 - elif (("SRC_IP" in rule_props and rule_props["SRC_IP"]) or - ("DST_IP" in rule_props and rule_props["DST_IP"])): - table_ip_version = 4 - - # If we were unable to determine whether this ACL table contains - # IPv4 or IPv6 rules, log a message and skip processing this table. - if not table_ip_version: - log_warning("Unable to determine if ACL table '{}' contains IPv4 or IPv6 rules. Skipping table..." - .format(table_name)) - continue - - # For each ACL rule in this table (in descending order of priority) - for priority in sorted(acl_rules.iterkeys(), reverse=True): - rule_props = acl_rules[priority] - - if "PACKET_ACTION" not in rule_props: - log_error("ACL rule does not contain PACKET_ACTION property") - continue - - # Apply the rule to the default protocol(s) for this ACL service - for ip_protocol in ip_protocols: - for dst_port in dst_ports: - rule_cmd = "ip6tables" if table_ip_version == 6 else "iptables" - rule_cmd += " -A INPUT -p {}".format(ip_protocol) - - 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) - - # If there are TCP flags present and ip protocol is TCP, append them - if ip_protocol == "tcp" and "TCP_FLAGS" in rule_props and rule_props["TCP_FLAGS"]: - tcp_flags, tcp_flags_mask = rule_props["TCP_FLAGS"].split("/") - - tcp_flags = int(tcp_flags, 16) - tcp_flags_mask = int(tcp_flags_mask, 16) - - if tcp_flags_mask > 0: - rule_cmd += " --tcp-flags {mask} {flags}".format(mask = self.parse_int_to_tcp_flags(tcp_flags_mask), flags = self.parse_int_to_tcp_flags(tcp_flags)) - - # Append the packet action as the jump target - rule_cmd += " -j {}".format(rule_props["PACKET_ACTION"]) - - iptables_cmds.append(rule_cmd) - - return iptables_cmds - - def update_control_plane_acls(self): - """ - Convenience wrapper which retrieves current ACL tables and rules from - Config DB, translates control plane ACLs into a list of iptables - commands and runs them. - """ - iptables_cmds = self.get_acl_rules_and_translate_to_iptables_commands() - - log_info("Issuing the following iptables commands:") - for cmd in iptables_cmds: - log_info(" " + cmd) - - self.run_commands(iptables_cmds) - - def notification_handler(self, key, data): - log_info("ACL configuration changed. Updating iptables rules for control plane ACLs...") - self.update_control_plane_acls() - - def run(self): - # Unconditionally update control plane ACLs once at start - self.update_control_plane_acls() - - # Subscribe to notifications when ACL tables or rules change - self.config_db.subscribe(self.ACL_TABLE, - lambda table, key, data: self.notification_handler(key, data)) - self.config_db.subscribe(self.ACL_RULE, - lambda table, key, data: self.notification_handler(key, data)) - - # Indefinitely listen for Config DB notifications - self.config_db.listen() - - -# ============================= Functions ============================= - -def main(): - log_info("Starting up...") - - if not os.geteuid() == 0: - log_error("Must be root to run this daemon") - print "Error: Must be root to run this daemon" - sys.exit(1) - - # Instantiate a ControlPlaneAclManager object - caclmgr = ControlPlaneAclManager() - caclmgr.run() - - -if __name__ == "__main__": - main() diff --git a/files/image_config/caclmgrd/caclmgrd.service b/files/image_config/caclmgrd/caclmgrd.service deleted file mode 100644 index f385384375c0..000000000000 --- a/files/image_config/caclmgrd/caclmgrd.service +++ /dev/null @@ -1,11 +0,0 @@ -[Unit] -Description=Control Plane ACL configuration daemon -Requires=updategraph.service -After=updategraph.service - -[Service] -Type=simple -ExecStart=/usr/bin/caclmgrd - -[Install] -WantedBy=multi-user.target diff --git a/files/image_config/config-chassisdb/config-chassisdb b/files/image_config/config-chassisdb/config-chassisdb new file mode 100755 index 000000000000..3bdcf0a0fbe2 --- /dev/null +++ b/files/image_config/config-chassisdb/config-chassisdb @@ -0,0 +1,59 @@ +#!/bin/bash +########################################################################### +# Copyright 2020 Arista. The term "Arista" refers to Arista 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 chassis_db configuration # +# # +# This script is used to add chassis_db address in local hosts and # +# indicate to start database-chassis service. It should be excuted before # +# database-chassis.service started. # +# # +########################################################################### + +config_chassis_db() { + startdb_file="/etc/sonic/chassisdb.conf" + [ ! -e $startdb_file ] || rm $startdb_file + platform=$(sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) + # database-chassis services will start when $chassis_config file exists + chassis_config="/usr/share/sonic/device/$platform/chassisdb.conf" + if [ ! -e $chassis_config ]; then + echo "no chassisdb.conf found, bypass config-chassisdb service" + exit 0 + fi + start_chassis_db=0 + chassis_db_address="" + source $chassis_config + if [[ "$start_chassis_db" == "1" ]]; then + cp $chassis_config $startdb_file + echo "start chassisdb" + fi + if [[ "$start_chassis_db" == "1" ]] || [[ -n "$chassis_db_address" ]]; then + if [ -z "$chassis_db_address" ]; then + echo "no user configured chassisdb address" + else + grep redis_chassis /etc/hosts + if [ $? -ne 0 ]; then + echo "$chassis_db_address redis_chassis.server" >> /etc/hosts + echo "update chassis db address to $chassis_db_address" + fi + fi + fi +} + +config_chassis_db + +exit 0 diff --git a/files/image_config/config-setup/config-setup b/files/image_config/config-setup/config-setup index f19abd266e95..9bb7b33b6be6 100755 --- a/files/image_config/config-setup/config-setup +++ b/files/image_config/config-setup/config-setup @@ -26,7 +26,11 @@ # Initialize constants UPDATEGRAPH_CONF=/etc/sonic/updategraph.conf +INIT_CFG_JSON=/etc/sonic/init_cfg.json CONFIG_DB_JSON=/etc/sonic/config_db.json +CONFIG_DB_PATH=/etc/sonic/ +CONFIG_DB_PREFIX=config_db +CONFIG_DB_SUFFIX=.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 @@ -37,6 +41,8 @@ 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 +TACACS_JSON_BACKUP=tacacs.json + # Command usage and help usage() { @@ -103,24 +109,24 @@ run_hookdir() { reload_minigraph() { echo "Reloading minigraph..." - if [ ! -f /etc/sonic/init_cfg.json ]; then - echo "{}" > /etc/sonic/init_cfg.json - fi - sonic-db-cli CONFIG_DB FLUSHDB - sonic-cfggen -H -m -j /etc/sonic/init_cfg.json --write-to-db - 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 - 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 + config load_minigraph -y -n + if [ -r /etc/sonic/old_config/${TACACS_JSON_BACKUP} ]; then + sonic-cfggen -j /etc/sonic/old_config/${TACACS_JSON_BACKUP} --write-to-db + else + echo "Missing tacacs json to restore tacacs credentials" fi + config save -y } +# Reload exisitng config db file on disk +# Usage: reload_configdb +reload_configdb() +{ + CONFIG_FILE=${1} + + echo "Reloading existing config db..." + config reload ${CONFIG_FILE} -y -n +} # Restore SONiC configuration from a backup copy function copy_config_files_and_directories() { @@ -175,33 +181,6 @@ ztp_is_enabled() 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 - - sonic-db-cli CONFIG_DB 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 - - sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" - return 0 -} - - # Generate requested SONiC configuration and save it as destination file # Usage: generate_config < factory | ztp > # @@ -212,7 +191,7 @@ load_config() generate_config() { # Collect all information needed to generate configuration - PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` + PLATFORM=${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]} @@ -247,20 +226,20 @@ 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 echo "No configuration detected, generating factory default configuration..." generate_config factory ${CONFIG_DB_JSON} - load_config ${CONFIG_DB_JSON} + reload_configdb ${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} + reload_configdb ${TMP_ZTP_CONFIG_DB_JSON} rm -f ${TMP_ZTP_CONFIG_DB_JSON} fi @@ -281,15 +260,49 @@ copy_post_migration_hooks() fi } +# Get the list of config db for both +# single and multi-npu platforms +get_config_db_file_list() +{ + config_db_file_list=${CONFIG_DB_PREFIX}${CONFIG_DB_SUFFIX} + asic_num=0 + while [[ ($asic_num -lt $NUM_ASIC) && ($NUM_ASIC -gt 1) ]]; do + config_db_file_list+=' '${CONFIG_DB_PREFIX}$asic_num${CONFIG_DB_SUFFIX} + ((asic_num = asic_num + 1)) + done + + echo $config_db_file_list +} +# Check if all needed config db are prsesnt for both +# single and multi-npu platforms +check_all_config_db_present() +{ + if [[ ! -r ${CONFIG_DB_JSON} ]]; then + return 1 + fi + asic_num=0 + while [[ ($asic_num -lt $NUM_ASIC) && ($NUM_ASIC -gt 1) ]]; do + if [[ ! -r ${CONFIG_DB_PATH}${CONFIG_DB_PREFIX}$asic_num${CONFIG_DB_SUFFIX} ]]; then + return 1 + fi + ((asic_num = asic_num + 1)) + done + + return 0 +} + # 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" + copy_list="minigraph.xml snmp.yml acl.json frr telemetry" # Migrate all configuration files from old to new copy_config_files_and_directories $copy_list + + # Migrate all config_db from old to new + copy_config_files_and_directories $(get_config_db_file_list) # Migrate post-migration hooks copy_post_migration_hooks @@ -302,19 +315,14 @@ do_config_migration() disable_updategraph rm -f /tmp/pending_config_migration exit 0 - elif [ -r ${CONFIG_DB_JSON} ]; then + elif check_all_config_db_present; 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 + reload_configdb + # Disable updategraph + disable_updategraph 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 @@ -349,13 +357,21 @@ boot_config() do_config_migration fi + # For multi-npu platfrom we don't support config initlaiztion. Assumption + # is there should be existing minigraph or config_db from previous image + # file system to trigger. pending_config_initialization will remain set + # for multi-npu platforms if we reach this case. + if [[ ($NUM_ASIC -gt 1) ]]; then + return 0 + 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) @@ -370,7 +386,17 @@ boot_config() fi } +# read SONiC immutable variables +[ -f /etc/sonic/sonic-environment ] && . /etc/sonic/sonic-environment + ### Execution starts here ### +PLATFORM=${PLATFORM:-`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform`} +# Parse the device specific asic conf file, if it exists +ASIC_CONF=/usr/share/sonic/device/$PLATFORM/asic.conf +if [[ -f "$ASIC_CONF" ]]; then + source $ASIC_CONF +fi + CMD=$1 # Default command is boot diff --git a/files/image_config/constants/constants.yml b/files/image_config/constants/constants.yml index 3834717a8bfc..86179aee430e 100644 --- a/files/image_config/constants/constants.yml +++ b/files/image_config/constants/constants.yml @@ -1,4 +1,56 @@ constants: deployment_id_asn_map: "1" : 65432 - traffic_shift_community: 12345:12345 + "2" : 65433 + bgp: + traffic_shift_community: 12345:12345 + families: + - ipv4 + - ipv6 + use_deployment_id: false + use_neighbors_meta: false + graceful_restart: + enabled: true + restart_time: 240 + multipath_relax: + enabled: true + maximum_paths: + enabled: true + ipv4: 64 + ipv6: 64 + allow_list: + enabled: true + default_action: "permit" # or "deny" + drop_community: 5060:12345 # value of the community to identify a prefix to drop. Make sense only with allow_list_default_action equal to 'permit' + default_pl_rules: + v4: + - "deny 0.0.0.0/0 le 17" + - "permit 127.0.0.1/32" + v6: + - "deny 0::/0 le 59" + - "deny 0::/0 ge 65" + bbr: + enabled: true + default_state: "disabled" + peers: + general: # peer_type + db_table: "BGP_NEIGHBOR" + template_dir: "general" + bbr: + PEER_V4: + - ipv4 + PEER_V6: + - ipv6 + internal: # peer_type + db_table: "BGP_INTERNAL_NEIGHBOR" + template_dir: "internal" + monitors: # peer_type + enabled: true + db_table: "BGP_MONITORS" + peer_group: "BGPMON" + template_dir: "monitors" + dynamic: # peer_type + enabled: true + db_table: "BGP_PEER_RANGE" + peer_group: "BGP_SPEAKER" + template_dir: "dynamic" diff --git a/files/image_config/copp/copp-config.service b/files/image_config/copp/copp-config.service new file mode 100755 index 000000000000..8eed2353eddf --- /dev/null +++ b/files/image_config/copp/copp-config.service @@ -0,0 +1,11 @@ +[Unit] +Description=Update CoPP configuration +Requires=updategraph.service +After=updategraph.service + +[Service] +Type=oneshot +ExecStart=/usr/bin/copp-config.sh + +[Install] +WantedBy=multi-user.target diff --git a/files/image_config/copp/copp-config.sh b/files/image_config/copp/copp-config.sh new file mode 100755 index 000000000000..0660528a54da --- /dev/null +++ b/files/image_config/copp/copp-config.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +sonic-cfggen -d -t /usr/share/sonic/templates/copp_cfg.j2 > /etc/sonic/copp_cfg.json diff --git a/files/image_config/copp/copp_cfg.j2 b/files/image_config/copp/copp_cfg.j2 new file mode 100755 index 000000000000..61f051f43de8 --- /dev/null +++ b/files/image_config/copp/copp_cfg.j2 @@ -0,0 +1,105 @@ +{ + "COPP_GROUP": { + "default": { + "queue": "0", + "meter_type":"packets", + "mode":"sr_tcm", + "cir":"600", + "cbs":"600", + "red_action":"drop" + }, + "queue4_group1": { + "trap_action":"trap", + "trap_priority":"4", + "queue": "4" + }, + "queue4_group2": { + "trap_action":"copy", + "trap_priority":"4", + "queue": "4", + "meter_type":"packets", + "mode":"sr_tcm", + "cir":"600", + "cbs":"600", + "red_action":"drop" + }, + "queue4_group3": { + "trap_action":"trap", + "trap_priority":"4", + "queue": "4" + }, + "queue1_group1": { + "trap_action":"trap", + "trap_priority":"1", + "queue": "1", + "meter_type":"packets", + "mode":"sr_tcm", + "cir":"6000", + "cbs":"6000", + "red_action":"drop" + }, + "queue1_group2": { + "trap_action":"trap", + "trap_priority":"1", + "queue": "1", + "meter_type":"packets", + "mode":"sr_tcm", + "cir":"600", + "cbs":"600", + "red_action":"drop" + }, + "queue2_group1": { + "cbs": "1000", + "cir": "1000", + "genetlink_mcgrp_name": "packets", + "genetlink_name": "psample", + "meter_type": "packets", + "mode": "sr_tcm", + "queue": "2", + "red_action": "drop", + "trap_action": "trap", + "trap_priority": "1" + + } + }, + "COPP_TRAP": { + "bgp": { + "trap_ids": "bgp,bgpv6", + "trap_group": "queue4_group1" + }, + "lacp": { + "trap_ids": "lacp", + "trap_group": "queue4_group1" + }, + "arp": { + "trap_ids": "arp_req,arp_resp,neigh_discovery", + "trap_group": "queue4_group2" + }, + "lldp": { + "trap_ids": "lldp", + "trap_group": "queue4_group3" + }, +{% if not (DEVICE_METADATA is defined and DEVICE_METADATA['localhost'] is defined and DEVICE_METADATA['localhost']['type'] is defined and DEVICE_METADATA['localhost']['type'] != "ToRRouter") %} + "dhcp": { + "trap_ids": "dhcp,dhcpv6", + "trap_group": "queue4_group3" + }, +{% endif %} + "udld": { + "trap_ids": "udld", + "trap_group": "queue4_group3" + }, + "ip2me": { + "trap_ids": "ip2me", + "trap_group": "queue1_group1" + }, + "nat": { + "trap_ids": "src_nat_miss,dest_nat_miss", + "trap_group": "queue1_group2" + }, + "sflow": { + "trap_group": "queue2_group1", + "trap_ids": "sample_packet" + } + } +} diff --git a/files/image_config/corefile_uploader/core_uploader.py b/files/image_config/corefile_uploader/core_uploader.py index 2ae91ce0896b..aba78618307c 100755 --- a/files/image_config/corefile_uploader/core_uploader.py +++ b/files/image_config/corefile_uploader/core_uploader.py @@ -1,25 +1,19 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 +import json import os -import time -import tarfile import socket +import tarfile +import time + import yaml -import json -import syslog +from azure.storage.file import FileService +from sonic_py_common.logger import Logger from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler -from azure.storage.file import FileService - -global CORE_FILE_PATH, RC_FILE -global hostname, sonicversion, asicname, acctname, acctkey, sharename, cwd -global INIT_CWD -global log_level -global this_file -this_file = os.path.basename(__file__) +SYSLOG_IDENTIFIER = os.path.basename(__file__) -global cfg cfg = "" CORE_FILE_PATH = "/var/core/" @@ -37,37 +31,21 @@ HOURS_4 = (4 * 60 * 60) PAUSE_ON_FAIL = (60 * 60) WAIT_FILE_WRITE1 = (10 * 60) -WAIT_FILE_WRITE2= (5 * 60) +WAIT_FILE_WRITE2 = (5 * 60) POLL_SLEEP = (60 * 60) MAX_RETRIES = 5 UPLOAD_PREFIX = "UPLOADED_" -log_level = syslog.LOG_DEBUG - -def log_msg(lvl, fname, m): - if (lvl <= log_level): - syslog.syslog(lvl, "{}: {}".format(fname, m)) - - if log_level == syslog.LOG_DEBUG: - print("{}: {}".format(fname, m)) - -def log_err(m): - log_msg(syslog.LOG_ERR, this_file, m) - -def log_info(m): - log_msg(syslog.LOG_INFO, this_file, m) - -def log_warn(m): - log_msg(syslog.LOG_WARNING, this_file, m) - -def log_debug(m): - log_msg(syslog.LOG_DEBUG, this_file, m) +# Global logger instance +logger = Logger(SYSLOG_IDENTIFIER) +logger.set_min_log_priority_info() def make_new_dir(p): os.system("rm -rf " + p) os.system("mkdir -p " + p) + def parse_a_json(data, prefix, val): for i in data: if type(data[i]) == dict: @@ -75,6 +53,7 @@ def parse_a_json(data, prefix, val): else: val[prefix + (i,)] = data[i] + class config: parsed_data = {} cfg_data = {} @@ -82,15 +61,15 @@ class config: def __init__(self): while not os.path.exists(RC_FILE): # Wait here until service restart - log_err("Unable to retrieve Azure storage credentials") - time.sleep (HOURS_4) + logger.log_error("Unable to retrieve Azure storage credentials") + time.sleep(HOURS_4) with open(RC_FILE, 'r') as f: self.parsed_data = json.load(f) parse_a_json(self.parsed_data, (), self.cfg_data) def get_data(self, k): - return self.cfg_data[k] if self.cfg_data.has_key(k) else "" + return self.cfg_data[k] if k in self.cfg_data else "" def get_dict(self): return self.parsed_data @@ -123,15 +102,17 @@ def run(self): time.sleep(POLL_SLEEP) except: self.observer.stop() - log_err("Error in watcher") + logger.log_error("Error in watcher") self.observer.join() + def set_env(lst): for k in lst: if lst[k]: os.environ[k] = lst[k] - log_debug("set env {} = {}".format(k, lst[k])) + logger.log_debug("set env {} = {}".format(k, lst[k])) + class Handler(FileSystemEventHandler): @@ -155,8 +136,8 @@ def init(): if not acctname or not acctkey or not sharename: while True: # Wait here until service restart - log_err("Unable to retrieve Azure storage credentials") - time.sleep (HOURS_4) + logger.log_error("Unable to retrieve Azure storage credentials") + time.sleep(HOURS_4) with open("/etc/sonic/sonic_version.yml", 'r') as stream: l = yaml.safe_load(stream) @@ -182,11 +163,10 @@ def on_any_event(event): elif event.event_type == 'created': # Take any action here when a file is first created. - log_debug("Received create event - " + event.src_path) + logger.log_debug("Received create event - " + event.src_path) Handler.wait_for_file_write_complete(event.src_path) Handler.handle_file(event.src_path) - @staticmethod def wait_for_file_write_complete(path): mtime = 0 @@ -205,8 +185,7 @@ def wait_for_file_write_complete(path): raise Exception("Dump file creation is too slow: " + path) # Give up as something is terribly wrong with this file. - log_debug("File write complete - " + path) - + logger.log_debug("File write complete - " + path) @staticmethod def handle_file(path): @@ -221,25 +200,24 @@ def handle_file(path): tarf_name = fname + ".tar.gz" cfg.get_core_info(path, hostname) - + tar = tarfile.open(tarf_name, "w:gz") for e in metafiles: tar.add(metafiles[e]) tar.add(path) tar.close() - log_debug("Tar file for upload created: " + tarf_name) + logger.log_debug("Tar file for upload created: " + tarf_name) Handler.upload_file(tarf_name, tarf_name, path) - log_debug("File uploaded - " + path) + logger.log_debug("File uploaded - " + path) os.chdir(INIT_CWD) @staticmethod def upload_file(fname, fpath, coref): daemonname = fname.split(".")[0] i = 0 - fail_msg = "" - + while True: try: svc = FileService(account_name=acctname, account_key=acctkey) @@ -250,22 +228,22 @@ def upload_file(fname, fpath, coref): e.append(l[len(e)]) svc.create_directory(sharename, "/".join(e)) - log_debug("Remote dir created: " + "/".join(e)) + logger.log_debug("Remote dir created: " + "/".join(e)) svc.create_file_from_path(sharename, "/".join(l), fname, fpath) - log_debug("Remote file created: name{} path{}".format(fname, fpath)) + logger.log_debug("Remote file created: name{} path{}".format(fname, fpath)) newcoref = os.path.dirname(coref) + "/" + UPLOAD_PREFIX + os.path.basename(coref) os.rename(coref, newcoref) break except Exception as ex: - log_err("core uploader failed: Failed during upload (" + coref + ") err: ("+ str(ex) +") retry:" + str(i)) + logger.log_error("core uploader failed: Failed during upload (" + + coref + ") err: (" + str(ex) + ") retry:" + str(i)) if not os.path.exists(fpath): break i += 1 time.sleep(PAUSE_ON_FAIL) - @staticmethod def scan(): for e in os.listdir(CORE_FILE_PATH): @@ -281,5 +259,4 @@ def scan(): Handler.scan() w.run() except Exception as e: - log_err("core uploader failed: " + str(e) + " Exiting ...") - + logger.log_err("core uploader failed: " + str(e) + " Exiting ...") diff --git a/files/image_config/ebtables/ebtables.filter b/files/image_config/ebtables/ebtables.filter deleted file mode 100644 index 4faad1f5f4bd..000000000000 Binary files a/files/image_config/ebtables/ebtables.filter and /dev/null differ diff --git a/files/image_config/ebtables/ebtables.filter.cfg b/files/image_config/ebtables/ebtables.filter.cfg new file mode 100644 index 000000000000..7a2dc5c8b6ec --- /dev/null +++ b/files/image_config/ebtables/ebtables.filter.cfg @@ -0,0 +1,11 @@ +# SONiC ebtables filter table configuration +# Generated using ebtables-save + +*filter +:INPUT ACCEPT +:FORWARD ACCEPT +:OUTPUT ACCEPT +-A FORWARD -d BGA -j DROP +-A FORWARD -p ARP -j DROP +-A FORWARD -p 802_1Q --vlan-encap ARP -j DROP + diff --git a/files/image_config/fstrim/fstrim.service b/files/image_config/fstrim/fstrim.service index cf740d3af34d..c61683400831 100644 --- a/files/image_config/fstrim/fstrim.service +++ b/files/image_config/fstrim/fstrim.service @@ -3,4 +3,5 @@ Description=Discard unused blocks [Service] Type=oneshot +ExecStartPre=/usr/local/bin/log_ssd_health ExecStart=/sbin/fstrim -av diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd deleted file mode 100755 index 4ac3be83d06e..000000000000 --- a/files/image_config/hostcfgd/hostcfgd +++ /dev/null @@ -1,319 +0,0 @@ -#!/usr/bin/python -u -# -*- coding: utf-8 -*- - -import os -import sys -import subprocess -import syslog -import copy -import jinja2 -import ipaddr as ipaddress -from swsssdk import ConfigDBConnector - -# FILE -PAM_AUTH_CONF = "/etc/pam.d/common-auth-sonic" -PAM_AUTH_CONF_TEMPLATE = "/usr/share/sonic/templates/common-auth-sonic.j2" -NSS_TACPLUS_CONF = "/etc/tacplus_nss.conf" -NSS_TACPLUS_CONF_TEMPLATE = "/usr/share/sonic/templates/tacplus_nss.conf.j2" -NSS_CONF = "/etc/nsswitch.conf" - -# TACACS+ -TACPLUS_SERVER_PASSKEY_DEFAULT = "" -TACPLUS_SERVER_TIMEOUT_DEFAULT = "5" -TACPLUS_SERVER_AUTH_TYPE_DEFAULT = "pap" - - -def is_true(val): - if val == 'True' or val == 'true': - return True - else: - return False - - -def sub(l, start, end): - return l[start:end] - - -def obfuscate(data): - if data: - return data[0] + '*****' - else: - return data - -class Iptables(object): - def __init__(self): - ''' - Default MSS to 1460 - (MTU 1500 - 40 (TCP/IP Overhead)) - For IPv6, it would be 1440 - (MTU 1500 - 60 octects) - ''' - self.tcpmss = 1460 - self.tcp6mss = 1440 - - def is_ip_prefix_in_key(self, key): - ''' - Function to check if IP address is present in the key. If it - is present, then the key would be a tuple or else, it shall be - be string - ''' - return (isinstance(key, tuple)) - - def load(self, lpbk_table): - for row in lpbk_table: - self.iptables_handler(row, lpbk_table[row]) - - def command(self, chain, ip, ver, op): - cmd = 'iptables' if ver == '4' else 'ip6tables' - cmd += ' -t mangle --{} {} -p tcp --tcp-flags SYN SYN'.format(op, chain) - cmd += ' -d' if chain == 'PREROUTING' else ' -s' - mss = self.tcpmss if ver == '4' else self.tcp6mss - cmd += ' {} -j TCPMSS --set-mss {}'.format(ip, mss) - - return cmd - - def iptables_handler(self, key, data, add=True): - if not self.is_ip_prefix_in_key(key): - return - - iface, ip = key - ip_str = ip.split("/")[0] - ip_addr = ipaddress.IPAddress(ip_str) - if isinstance(ip_addr, ipaddress.IPv6Address): - ver = '6' - else: - ver = '4' - - self.mangle_handler(ip_str, ver, add) - - def mangle_handler(self, ip, ver, add): - if not add: - op = 'delete' - else: - op = 'check' - - iptables_cmds = [] - chains = ['PREROUTING', 'POSTROUTING'] - for chain in chains: - cmd = self.command(chain, ip, ver, op) - if not add: - iptables_cmds.append(cmd) - else: - ''' - For add case, first check if rule exists. Iptables just appends to the chain - as a new rule even if it is the same as an existing one. Check this and - do nothing if rule exists - ''' - ret = subprocess.call(cmd, shell=True) - if ret == 0: - syslog.syslog(syslog.LOG_INFO, "{} rule exists in {}".format(ip, chain)) - else: - # Modify command from Check to Append - iptables_cmds.append(cmd.replace("check", "append")) - - for cmd in iptables_cmds: - syslog.syslog(syslog.LOG_INFO, "Running cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) - -class AaaCfg(object): - def __init__(self): - self.auth_default = { - 'login': 'local', - } - self.tacplus_global_default = { - 'auth_type': TACPLUS_SERVER_AUTH_TYPE_DEFAULT, - 'timeout': TACPLUS_SERVER_TIMEOUT_DEFAULT, - 'passkey': TACPLUS_SERVER_PASSKEY_DEFAULT - } - self.auth = {} - self.tacplus_global = {} - self.tacplus_servers = {} - self.debug = False - - # Load conf from ConfigDb - def load(self, aaa_conf, tac_global_conf, tacplus_conf): - for row in aaa_conf: - self.aaa_update(row, aaa_conf[row], modify_conf=False) - for row in tac_global_conf: - self.tacacs_global_update(row, tac_global_conf[row], modify_conf=False) - for row in tacplus_conf: - self.tacacs_server_update(row, tacplus_conf[row], modify_conf=False) - self.modify_conf_file() - - def aaa_update(self, key, data, modify_conf=True): - if key == 'authentication': - self.auth = data - if 'failthrough' in data: - self.auth['failthrough'] = is_true(data['failthrough']) - if 'debug' in data: - self.debug = is_true(data['debug']) - if modify_conf: - self.modify_conf_file() - - def tacacs_global_update(self, key, data, modify_conf=True): - if key == 'global': - self.tacplus_global = data - if modify_conf: - self.modify_conf_file() - - def tacacs_server_update(self, key, data, modify_conf=True): - if data == {}: - if key in self.tacplus_servers: - del self.tacplus_servers[key] - else: - self.tacplus_servers[key] = data - - if modify_conf: - self.modify_conf_file() - - def modify_single_file(self, filename, operations=None): - if operations: - cmd = "sed -e {0} {1} > {1}.new; mv -f {1} {1}.old; mv -f {1}.new {1}".format(' -e '.join(operations), filename) - os.system(cmd) - - def modify_conf_file(self): - auth = self.auth_default.copy() - auth.update(self.auth) - tacplus_global = self.tacplus_global_default.copy() - tacplus_global.update(self.tacplus_global) - - servers_conf = [] - if self.tacplus_servers: - for addr in self.tacplus_servers: - server = tacplus_global.copy() - server['ip'] = addr - server.update(self.tacplus_servers[addr]) - servers_conf.append(server) - servers_conf = sorted(servers_conf, key=lambda t: int(t['priority']), reverse=True) - - template_file = os.path.abspath(PAM_AUTH_CONF_TEMPLATE) - env = jinja2.Environment(loader=jinja2.FileSystemLoader('/'), trim_blocks=True) - env.filters['sub'] = sub - template = env.get_template(template_file) - pam_conf = template.render(auth=auth, servers=servers_conf) - with open(PAM_AUTH_CONF, 'w') as f: - f.write(pam_conf) - - # Modify common-auth include file in /etc/pam.d/login and sshd - if os.path.isfile(PAM_AUTH_CONF): - self.modify_single_file('/etc/pam.d/sshd', [ "'/^@include/s/common-auth$/common-auth-sonic/'" ]) - self.modify_single_file('/etc/pam.d/login', [ "'/^@include/s/common-auth$/common-auth-sonic/'" ]) - else: - self.modify_single_file('/etc/pam.d/sshd', [ "'/^@include/s/common-auth-sonic$/common-auth/'" ]) - self.modify_single_file('/etc/pam.d/login', [ "'/^@include/s/common-auth-sonic$/common-auth/'" ]) - - # Add tacplus in nsswitch.conf if TACACS+ enable - if 'tacacs+' in auth['login']: - if os.path.isfile(NSS_CONF): - self.modify_single_file(NSS_CONF, [ "'/tacplus/b'", "'/^passwd/s/compat/tacplus &/'"]) - else: - if os.path.isfile(NSS_CONF): - self.modify_single_file(NSS_CONF, [ "'/^passwd/s/tacplus //'" ]) - - # Set tacacs+ server in nss-tacplus conf - template_file = os.path.abspath(NSS_TACPLUS_CONF_TEMPLATE) - template = env.get_template(template_file) - nss_tacplus_conf = template.render(debug=self.debug, servers=servers_conf) - with open(NSS_TACPLUS_CONF, 'w') as f: - f.write(nss_tacplus_conf) - - -class HostConfigDaemon: - def __init__(self): - self.config_db = ConfigDBConnector() - self.config_db.connect(wait_for_init=True, retry_on=True) - syslog.syslog(syslog.LOG_INFO, 'ConfigDB connect success') - aaa = self.config_db.get_table('AAA') - tacacs_global = self.config_db.get_table('TACPLUS') - tacacs_server = self.config_db.get_table('TACPLUS_SERVER') - self.aaacfg = AaaCfg() - self.aaacfg.load(aaa, tacacs_global, tacacs_server) - lpbk_table = self.config_db.get_table('LOOPBACK_INTERFACE') - self.iptables = Iptables() - self.iptables.load(lpbk_table) - - def aaa_handler(self, key, data): - self.aaacfg.aaa_update(key, data) - - def tacacs_server_handler(self, key, data): - self.aaacfg.tacacs_server_update(key, data) - log_data = copy.deepcopy(data) - if log_data.has_key('passkey'): - log_data['passkey'] = obfuscate(log_data['passkey']) - syslog.syslog(syslog.LOG_INFO, 'value of {} changed to {}'.format(key, log_data)) - - def tacacs_global_handler(self, key, data): - self.aaacfg.tacacs_global_update(key, data) - log_data = copy.deepcopy(data) - if log_data.has_key('passkey'): - log_data['passkey'] = obfuscate(log_data['passkey']) - syslog.syslog(syslog.LOG_INFO, 'value of {} changed to {}'.format(key, log_data)) - - def lpbk_handler(self, key, data): - key = ConfigDBConnector.deserialize_key(key) - #Check if delete operation by fetch existing keys - keys = self.config_db.get_keys('LOOPBACK_INTERFACE') - if key in keys: - add = True - else: - add = False - - self.iptables.iptables_handler(key, data, add) - - def feature_status_handler(self, key, data): - status_data = self.config_db.get_table('FEATURE') - for key in status_data.keys(): - if not key: - syslog.syslog(syslog.LOG_WARNING, "FEATURE key is missing") - return - status = status_data[key]['status'] - if not status: - syslog.syslog(syslog.LOG_WARNING, "status is missing for {}".format(key)) - return - if status == "enabled": - start_cmds=[] - start_cmds.append("sudo systemctl enable {}".format(key)) - start_cmds.append("sudo systemctl start {}".format(key)) - for cmd in start_cmds: - syslog.syslog(syslog.LOG_INFO, "Running cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) - return - syslog.syslog(syslog.LOG_INFO, "Feature '{}' is enabled and started".format(key)) - elif status == "disabled": - stop_cmds=[] - stop_cmds.append("sudo systemctl stop {}".format(key)) - stop_cmds.append("sudo systemctl disable {}".format(key)) - for cmd in stop_cmds: - syslog.syslog(syslog.LOG_INFO, "Running cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) - return - syslog.syslog(syslog.LOG_INFO, "Feature '{}' is stopped and disabled".format(key)) - else: - syslog.syslog(syslog.LOG_ERR, "Unexpected status value '{}' for '{}'".format(status, key)) - - def start(self): - self.config_db.subscribe('AAA', lambda table, key, data: self.aaa_handler(key, data)) - self.config_db.subscribe('TACPLUS_SERVER', lambda table, key, data: self.tacacs_server_handler(key, data)) - self.config_db.subscribe('TACPLUS', lambda table, key, data: self.tacacs_global_handler(key, data)) - self.config_db.subscribe('LOOPBACK_INTERFACE', lambda table, key, data: self.lpbk_handler(key, data)) - self.config_db.subscribe('FEATURE', lambda table, key, data: self.feature_status_handler(key, data)) - self.config_db.listen() - - -def main(): - daemon = HostConfigDaemon() - daemon.start() - - -if __name__ == "__main__": - main() diff --git a/files/image_config/hostcfgd/hostcfgd.service b/files/image_config/hostcfgd/hostcfgd.service deleted file mode 100644 index 762786ad830e..000000000000 --- a/files/image_config/hostcfgd/hostcfgd.service +++ /dev/null @@ -1,11 +0,0 @@ -[Unit] -Description=Host config enforcer daemon -Requires=updategraph.service -After=updategraph.service - -[Service] -Type=simple -ExecStart=/usr/bin/hostcfgd - -[Install] -WantedBy=multi-user.target diff --git a/files/image_config/interfaces/interfaces-config.sh b/files/image_config/interfaces/interfaces-config.sh index b5352745a7ef..688b2f8433a5 100755 --- a/files/image_config/interfaces/interfaces-config.sh +++ b/files/image_config/interfaces/interfaces-config.sh @@ -18,8 +18,14 @@ 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 +# Create /e/n/i file for existing and active interfaces, dhcp6 sytcl.conf and dhclient.conf +CFGGEN_PARAMS=" \ + -d -j /tmp/ztp_input.json \ + -t /usr/share/sonic/templates/interfaces.j2,/etc/network/interfaces \ + -t /usr/share/sonic/templates/90-dhcp6-systcl.conf.j2,/etc/sysctl.d/90-dhcp6-systcl.conf \ + -t /usr/share/sonic/templates/dhclient.conf.j2,/etc/dhcp/dhclient.conf \ +" +sonic-cfggen $CFGGEN_PARAMS [ -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 @@ -28,11 +34,9 @@ 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 diff --git a/files/image_config/interfaces/interfaces.j2 b/files/image_config/interfaces/interfaces.j2 index dbb2b1f3418a..98e43dd13be4 100644 --- a/files/image_config/interfaces/interfaces.j2 +++ b/files/image_config/interfaces/interfaces.j2 @@ -13,7 +13,7 @@ iface mgmt # 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 addr add 127.0.0.1/16 dev lo-m up ip link set lo-m up down ip link delete dev lo-m {% endif %} @@ -22,6 +22,9 @@ iface mgmt # The loopback network interface auto lo iface lo inet loopback + address 127.0.0.1 + netmask 255.255.0.0 + post-up ip addr del 127.0.0.1/8 dev lo {% endblock loopback %} {% block mgmt_interface %} @@ -64,6 +67,8 @@ iface {{ port }} inet6 dhcp iface eth0 {{ 'inet' if prefix | ipv4 else 'inet6' }} static address {{ prefix | ip }} netmask {{ prefix | netmask if prefix | ipv4 else prefix | prefixlen }} + network {{ prefix | network }} + broadcast {{ prefix | broadcast }} {% set vrf_table = 'default' %} {% if (MGMT_VRF_CONFIG) and (MGMT_VRF_CONFIG['vrf_global']['mgmtVrfEnabled'] == "true") %} {% set vrf_table = '5000' %} @@ -73,23 +78,16 @@ iface eth0 {{ 'inet' if prefix | ipv4 else 'inet6' }} static # management port up rules up ip {{ '-4' if prefix | ipv4 else '-6' }} route add default via {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} dev eth0 table {{ vrf_table }} metric 201 up ip {{ '-4' if prefix | ipv4 else '-6' }} route add {{ prefix | network }}/{{ prefix | prefixlen }} dev eth0 table {{ vrf_table }} - up ip {{ '-4' if prefix | ipv4 else '-6' }} rule add from {{ prefix | ip }}/{{ '32' if prefix | ipv4 else '128' }} table {{ vrf_table }} -{% if (MGMT_VRF_CONFIG) and (MGMT_VRF_CONFIG['vrf_global']['mgmtVrfEnabled'] == "true") %} - up cgcreate -g l3mdev:mgmt - up cgset -r l3mdev.master-device=mgmt mgmt -{% endif %} + up ip {{ '-4' if prefix | ipv4 else '-6' }} rule add pref 32765 from {{ prefix | ip }}/{{ '32' if prefix | ipv4 else '128' }} table {{ vrf_table }} {% for route in MGMT_INTERFACE[(name, prefix)]['forced_mgmt_routes'] %} - up ip rule add to {{ route }} table {{ vrf_table }} + up ip rule add pref 32764 to {{ route }} table {{ vrf_table }} {% endfor %} # management port down rules 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 %} + pre-down ip {{ '-4' if prefix | ipv4 else '-6' }} rule delete pref 32765 from {{ prefix | ip }}/{{ '32' if prefix | ipv4 else '128' }} table {{ vrf_table }} {% for route in MGMT_INTERFACE[(name, prefix)]['forced_mgmt_routes'] %} - pre-down ip rule delete to {{ route }} table {{ vrf_table }} + pre-down ip rule delete pref 32764 to {{ route }} table {{ vrf_table }} {% endfor %} {# TODO: COPP policy type rules #} {% endfor %} @@ -98,9 +96,6 @@ iface eth0 inet dhcp metric 202 {% if (MGMT_VRF_CONFIG) and (MGMT_VRF_CONFIG['vrf_global']['mgmtVrfEnabled'] == "true") %} vrf mgmt - up cgcreate -g l3mdev:mgmt - 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 diff --git a/files/image_config/kdump/kdump-tools b/files/image_config/kdump/kdump-tools new file mode 100644 index 000000000000..61a41eb31902 --- /dev/null +++ b/files/image_config/kdump/kdump-tools @@ -0,0 +1,16 @@ +# Default configuration +KDUMP_CMDLINE_APPEND="irqpoll nr_cpus=1 nousb systemd.unit=kdump-tools.service ata_piix.prefer_ms_hyperv=0" + +# --------------------------------------------------------------------------- +# Additional Kdump environment settings used in SONiC +# + +# Reboot crash kernel on panic +# Enable debug level logging of crash kernel for better visibility +# Disable advanced pcie features +# Disable high precision event timer as on some platforms it is interfering with the kdump operation +# Pass platform identifier string as part of crash kernel command line to be used by the reboot script during kdump +KDUMP_CMDLINE_APPEND+=" panic=10 debug hpet=disable pcie_port=compat pci=nommconf sonic_platform=__PLATFORM__" + +# Use SONiC reboot wrapper script present in /usr/local/bin post kdump +PATH=/usr/local/bin:$PATH diff --git a/files/image_config/kdump/vmcore-sysctl.conf b/files/image_config/kdump/vmcore-sysctl.conf new file mode 100755 index 000000000000..9a4016197cbd --- /dev/null +++ b/files/image_config/kdump/vmcore-sysctl.conf @@ -0,0 +1,7 @@ +kernel.panic_on_oops=1 +kernel.panic_on_unrecovered_nmi=1 +kernel.panic_on_io_nmi=1 +kernel.panic_on_stackoverflow=1 +kernel.hung_task_panic=1 +kernel.unknown_nmi_panic=1 +vm.panic_on_oom=1 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/files/image_config/logrotate/logrotate.d/alternatives b/files/image_config/logrotate/logrotate.d/alternatives new file mode 100644 index 000000000000..7c4c93c85834 --- /dev/null +++ b/files/image_config/logrotate/logrotate.d/alternatives @@ -0,0 +1,9 @@ +/var/log/alternatives.log { + size 100k + rotate 1 + compress + delaycompress + missingok + notifempty + create 644 root root +} diff --git a/files/image_config/logrotate/logrotate.d/dpkg b/files/image_config/logrotate/logrotate.d/dpkg index 5e24c7ed74e1..51b8f46fe105 100644 --- a/files/image_config/logrotate/logrotate.d/dpkg +++ b/files/image_config/logrotate/logrotate.d/dpkg @@ -7,12 +7,3 @@ notifempty create 644 root root } -/var/log/alternatives.log { - size 100k - rotate 1 - compress - delaycompress - missingok - notifempty - create 644 root root -} diff --git a/files/image_config/logrotate/logrotate.d/rsyslog b/files/image_config/logrotate/logrotate.d/rsyslog index 76737ba14420..cbf6e722eb90 100644 --- a/files/image_config/logrotate/logrotate.d/rsyslog +++ b/files/image_config/logrotate/logrotate.d/rsyslog @@ -28,10 +28,10 @@ /var/log/syslog /var/log/teamd.log /var/log/telemetry.log -/var/log/quagga/bgpd.log -/var/log/quagga/zebra.log -/var/log/swss/sairedis.rec -/var/log/swss/swss.rec +/var/log/frr/bgpd.log +/var/log/frr/zebra.log +/var/log/swss/sairedis*.rec +/var/log/swss/swss*.rec { size 1M rotate 5000 @@ -85,7 +85,22 @@ endscript postrotate if [ $(echo $1 | grep -c "/var/log/swss/") -gt 0 ]; then - pgrep -x orchagent | xargs /bin/kill -HUP 2>/dev/null || true + # for multi asic platforms, there are multiple orchagents + # send the SIGHUP only to the orchagent the which needs log file rotation + PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` + ASIC_CONF=/usr/share/sonic/device/$PLATFORM/asic.conf + if [ -f "$ASIC_CONF" ]; then + . $ASIC_CONF + fi + if [ $NUM_ASIC -gt 1 ]; then + log_file=$1 + log_file_name=${log_file#/var/log/swss/} + logger -p syslog.info -t "logrotate" "Sending SIGHUP to OA log_file_name: $log_file_name" + pgrep -xa orchagent | grep $log_file_name | awk '{ print $1; }' | xargs /bin/kill -HUP 2>/dev/null || true + else + logger -p syslog.info -t "logrotate" "Sending SIGHUP to OA log_file_name: $1" + pgrep -x orchagent | xargs /bin/kill -HUP 2>/dev/null || true + fi else /bin/kill -HUP $(cat /var/run/rsyslogd.pid) fi diff --git a/files/image_config/misc/docker-wait-any b/files/image_config/misc/docker-wait-any index 3988a9fbdf57..4200bb43c87f 100755 --- a/files/image_config/misc/docker-wait-any +++ b/files/image_config/misc/docker-wait-any @@ -1,52 +1,98 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 """ docker-wait-any This script takes one or more Docker container names as arguments, - and it will block indefinitely while all of the specified containers - are running. If any of the specified containers stop, the script will + [-s] argument is for the service which invokes this script + [-d] argument is to list the dependent services for the above service. + It will block indefinitely while all of the specified containers + are running.If any of the specified containers stop, the script will exit. + This script was created because the 'docker wait' command is lacking this functionality. It will block until ALL specified containers have stopped running. Here, we spawn multiple threads and wait on one container per thread. If any of the threads exit, the entire - application will exit. - NOTE: This script is written against docker-py version 1.6.0. Newer - versions of docker-py have a different API. + application will exit, unless we are in a scenario where the following + conditions are met. + (i) the container is a dependent service + (ii) warm restart is enabled at system level or for that container OR + fast reboot is enabled system level + In this scenario, the g_thread_exit_event won't be propogated to the parent, + instead the thread will continue to do docker_client.wait again.This help's + cases where we need the dependent container to be warm-restarted without + affecting other services (eg: warm restart of teamd service) + + NOTE: This script is written against docker Python package 4.3.1. Newer + versions of docker may have a different API. """ - +import argparse import sys import threading -from docker import Client +import time + +from docker import APIClient +from sonic_py_common import logger, device_info + +SYSLOG_IDENTIFIER = 'docker-wait-any' + +# Global logger instance +log = logger.Logger(SYSLOG_IDENTIFIER) # Instantiate a global event to share among our threads g_thread_exit_event = threading.Event() +g_service = [] +g_dep_services = [] -def usage(): - print("Usage: {} [ ...]".format(sys.argv[0])) - sys.exit(1) +def wait_for_container(docker_client, container_name): + while True: + while docker_client.inspect_container(container_name)['State']['Status'] != "running": + time.sleep(1) + docker_client.wait(container_name) -def wait_for_container(docker_client, container_name): - docker_client.wait(container_name) + log.log_info("No longer waiting on container '{}'".format(container_name)) - print("No longer waiting on container '{}'".format(container_name)) + # If this is a dependent service and warm restart is enabled for the system/container, + # OR if the system is going through a fast-reboot, DON'T signal main thread to exit + if (container_name in g_dep_services and + (device_info.is_warm_restart_enabled(container_name) or device_info.is_fast_reboot_enabled())): + continue - # Signal the main thread to exit - g_thread_exit_event.set() + # Signal the main thread to exit + g_thread_exit_event.set() def main(): thread_list = [] - docker_client = Client(base_url='unix://var/run/docker.sock') + docker_client = APIClient(base_url='unix://var/run/docker.sock') + + parser = argparse.ArgumentParser(description='Wait for dependent docker services', + formatter_class=argparse.RawTextHelpFormatter, + epilog=""" +Examples: + docker-wait-any -s swss -d syncd teamd +""") + + parser.add_argument('-s', '--service', nargs='+', default=None, help='name of the service') + parser.add_argument('-d', '--dependent', nargs='*', default=None, help='other dependent services') + args = parser.parse_args() - # Ensure we were passed at least one argument - if len(sys.argv) < 2: - usage() + global g_service + global g_dep_services - container_names = sys.argv[1:] + if args.service is not None: + g_service = args.service + if args.dependent is not None: + g_dep_services = args.dependent + + container_names = g_service + g_dep_services + + # If the service and dependents passed as args is empty, then exit + if container_names == []: + sys.exit(0) for container_name in container_names: t = threading.Thread(target=wait_for_container, args=[docker_client, container_name]) @@ -58,5 +104,6 @@ def main(): g_thread_exit_event.wait() sys.exit(0) + if __name__ == '__main__': main() diff --git a/files/image_config/monit/conf.d/sonic-host b/files/image_config/monit/conf.d/sonic-host index 5a67f7a9909b..17d7c64af7e2 100644 --- a/files/image_config/monit/conf.d/sonic-host +++ b/files/image_config/monit/conf.d/sonic-host @@ -6,17 +6,30 @@ ############################################################################### check filesystem root-overlay with path / - if space usage > 90% for 10 times within 20 cycles then alert + if space usage > 90% for 10 times within 20 cycles then alert repeat every 1 cycles check filesystem var-log with path /var/log - if space usage > 90% for 10 times within 20 cycles then alert + if space usage > 90% for 10 times within 20 cycles then alert repeat every 1 cycles check system $HOST - 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 + if memory usage > 90% for 10 times within 20 cycles then alert repeat every 1 cycles + if cpu usage (user) > 90% for 10 times within 20 cycles then alert repeat every 1 cycles + if cpu usage (system) > 90% for 10 times within 20 cycles then alert repeat every 1 cycles 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 10 times within 20 cycles then restart + +# route_check.py Verify routes between APPL-DB & ASIC-DB are in sync. +# For any discrepancy, details are logged and a non-zero code is returned +# which would trigger a monit alert. +# Hence for any discrepancy, there will be log messages for "ERR" level +# from both route_check.py & monit. +# +check program routeCheck with path "/usr/local/bin/route_check.py" + every 5 cycles + if status != 0 for 3 cycle then alert repeat every 1 cycles + +check program container_checker with path "/usr/bin/container_checker" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/files/image_config/monit/container_checker b/files/image_config/monit/container_checker new file mode 100755 index 000000000000..abfbb34430bb --- /dev/null +++ b/files/image_config/monit/container_checker @@ -0,0 +1,116 @@ +#!/usr/bin/env python3 + +""" +container_checker + +This script is intended to be run by Monit. It will write an alerting message into +syslog if it found containers which were expected to run but were not running. At +the same time, if some containers were unexpected to run, it also writes an alerting +syslog message. Note that if print(...) statement in this script was executed, the +string in it will be appended to Monit syslog messages. + +The following is an example in Monit configuration file to show how Monit will run +this script: + +check program container_checker with path "/usr/bin/container_checker" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles +""" + +import subprocess +import sys + +import swsssdk +from sonic_py_common import multi_asic + + +def get_command_result(command): + """ + @summary: This function will execute the command and return the resulting output. + @return: A string which contains the output of command. + """ + command_stdout = "" + + try: + proc_instance = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, + shell=True, universal_newlines=True) + command_stdout, command_stderr = proc_instance.communicate() + if proc_instance.returncode != 0: + print("Failed to execute the command '{}'. Return code: '{}'".format( + command, proc_instance.returncode)) + sys.exit(1) + except (OSError, ValueError) as err: + print("Failed to execute the command '{}'. Error: '{}'".format(command, err)) + sys.exit(2) + + return command_stdout.rstrip().split("\n") + + +def get_expected_running_containers(): + """ + @summary: This function will get the expected running containers by following the rule: + The 'state' field of container in 'FEATURE' table should not be 'disabled'. Then + if the device has Multi-ASIC, this function will get container list by determining the + value of field 'has_global_scope', the number of ASICs and the value of field + 'has_per_asic_scope'. If the device has single ASIC, the container name was put into + the list. + @return: A set which contains the expected running containers. + """ + config_db = swsssdk.ConfigDBConnector() + config_db.connect() + feature_table = config_db.get_table("FEATURE") + + expected_running_containers = set() + + for container_name in feature_table.keys(): + if feature_table[container_name]["state"] != "disabled": + if multi_asic.is_multi_asic(): + if feature_table[container_name]["has_global_scope"] == "True": + expected_running_containers.add(container_name) + if feature_table[container_name]["has_per_asic_scope"] == "True": + num_asics = multi_asic.get_num_asics() + for asic_id in range(num_asics): + expected_running_containers.add(container_name + str(asic_id)) + else: + expected_running_containers.add(container_name) + + return expected_running_containers + + +def get_current_running_containers(): + """ + @summary: This function will get the current running container list by analyzing the + output of command `docker ps`. + @return: A set which contains the current running contianers. + """ + running_containers = set() + + command = "docker ps" + command_stdout = get_command_result(command) + for line in command_stdout[1:]: + running_containers.add(line.split()[-1].strip()) + + return running_containers + + +def main(): + """ + @summary: This function will compare the difference between the current running containers + and the containers which were expected to run. If containers which were exepcted + to run were not running, then an alerting message will be written into syslog. + """ + expected_running_containers = get_expected_running_containers() + current_running_containers = get_current_running_containers() + + not_running_containers = expected_running_containers.difference(current_running_containers) + if not_running_containers: + print("Expected containers not running: " + ", ".join(not_running_containers)) + sys.exit(3) + + unexpected_running_containers = current_running_containers.difference(expected_running_containers) + if unexpected_running_containers: + print("Unexpected running containers: " + ", ".join(unexpected_running_containers)) + sys.exit(4) + + +if __name__ == "__main__": + main() 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, diff --git a/files/image_config/monit/process_checker b/files/image_config/monit/process_checker new file mode 100755 index 000000000000..68c8f3e945fd --- /dev/null +++ b/files/image_config/monit/process_checker @@ -0,0 +1,98 @@ +#!/usr/bin/python3 + +import argparse +import ast +import sys +import syslog + +import psutil +from sonic_py_common import multi_asic +import swsssdk + + +def check_process_existence(container_name, process_cmdline): + """ + @summary: Check whether the process in the specified container is running or not and + an alerting message will written into syslog if it failed to run. + """ + config_db = swsssdk.ConfigDBConnector() + config_db.connect() + feature_table = config_db.get_table("FEATURE") + + if container_name in feature_table: + # We look into the 'FEATURE' table to verify whether the container is disabled or not. + # If the container is diabled, we exit. + if ("state" in feature_table[container_name] + and feature_table[container_name]["state"] == "disabled"): + sys.exit(0) + else: + # We leveraged the psutil library to help us check whether the process is running or not. + # If the process entity is found in process tree and it is also in the 'running' or 'sleeping' + # state, then it will be marked as 'running'. + + # For given feature we get the host and network namespace instances it's processes should be running + # based on it's scope and add it to expected set. + + # From psutil we get number of running instances of the processes and add it to the the actual set + + # Difference bwetween expected and actual set provides instances where the processes are not running + # and will be logged as syslog message by monit + + process_namespace_expected_set = set() + process_namespace_found_set = set() + + has_global_scope = ast.literal_eval(feature_table[container_name].get('has_global_scope', 'True')) + has_per_asic_scope = ast.literal_eval(feature_table[container_name].get('has_per_asic_scope', 'False')) + + if has_global_scope: + process_namespace_expected_set.add(multi_asic.DEFAULT_NAMESPACE) + + if has_per_asic_scope: + process_namespace_expected_set.update(multi_asic.get_namespace_list()) + + for process in psutil.process_iter(["cmdline", "status", "pid"]): + try: + if ((' '.join(process.cmdline())).startswith(process_cmdline) and process.status() in ["running", "sleeping"]): + process_namespace_found_set.add(multi_asic.get_current_namespace(process.info['pid'])) + except psutil.NoSuchProcess: + pass + + process_namespace_diff_set = process_namespace_expected_set.difference(process_namespace_found_set) + + if process_namespace_diff_set: + host_display_str = "" + namespace_display_str = "" + + for ns in process_namespace_diff_set: + if ns == multi_asic.DEFAULT_NAMESPACE: + host_display_str = " in host" + else: + if not namespace_display_str: + namespace_display_str = " in namespace " + ns + else: + namespace_display_str += ", " + ns + + join_str = " and" if host_display_str and namespace_display_str else "" + + # If this script is run by Monit, then the following output will be appended to + # Monit's syslog message. + print("'{}' is not running{}{}{}".format(process_cmdline, host_display_str, join_str, namespace_display_str)) + sys.exit(1) + else: + syslog.syslog(syslog.LOG_ERR, "container '{}' is not included in SONiC image or the given container name is invalid!" + .format(container_name)) + + +def main(): + parser = argparse.ArgumentParser(description="Check whether the process in the specified \ + container is running and an alerting message will be written into syslog if it \ + failed to run.", usage="/usr/bin/process_checker ") + parser.add_argument("container_name", help="container name") + parser.add_argument("process_cmdline", nargs=argparse.REMAINDER, help="process command line") + args = parser.parse_args() + + check_process_existence(args.container_name, ' '.join(args.process_cmdline)) + + +if __name__ == '__main__': + main() diff --git a/files/image_config/ntp/ntp b/files/image_config/ntp/ntp index ecf0e5089071..f0ca500fb8f3 100755 --- a/files/image_config/ntp/ntp +++ b/files/image_config/ntp/ntp @@ -50,11 +50,20 @@ case $1 in fi ( flock -w 180 9 + + # when mgmt vrf is configured, ntp starts in mgmt vrf by default unless user configures otherwise vrfEnabled=$(/usr/local/bin/sonic-cfggen -d -v 'MGMT_VRF_CONFIG["vrf_global"]["mgmtVrfEnabled"]' 2> /dev/null) + vrfConfigured=$(/usr/local/bin/sonic-cfggen -d -v 'NTP["global"]["vrf"]' 2> /dev/null) if [ "$vrfEnabled" = "true" ] then - log_daemon_msg "Starting NTP server in mgmt-vrf" "ntpd" - cgexec -g l3mdev:mgmt start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --startas $DAEMON -- -p $PIDFILE $NTPD_OPTS + if [ "$vrfConfigured" = "default" ] + then + log_daemon_msg "Starting NTP server in default-vrf for default set as NTP vrf" "ntpd" + start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --startas $DAEMON -- -p $PIDFILE $NTPD_OPTS + else + log_daemon_msg "Starting NTP server in mgmt-vrf" "ntpd" + cgexec -g l3mdev:mgmt start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --startas $DAEMON -- -p $PIDFILE $NTPD_OPTS + fi else log_daemon_msg "Starting NTP server in default-vrf" "ntpd" start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --startas $DAEMON -- -p $PIDFILE $NTPD_OPTS diff --git a/files/image_config/ntp/ntp-apparmor b/files/image_config/ntp/ntp-apparmor new file mode 100644 index 000000000000..78edef66a51f --- /dev/null +++ b/files/image_config/ntp/ntp-apparmor @@ -0,0 +1,9 @@ +# Apparmor configuration +# /etc/apparmor.d/local/usr.sbin.ntpd + + # Allow read access to "rw" mount path of fs.squashfs + # Eg: /host/image-HEAD-sonic.../rw/usr/sbin + /**/{,s}bin/ r, + /**/usr/{,s}bin/ r, + /**/usr/local/{,s}bin/ r, + diff --git a/files/image_config/ntp/ntp-config.service b/files/image_config/ntp/ntp-config.service index c86710e3d209..a22a0331045d 100644 --- a/files/image_config/ntp/ntp-config.service +++ b/files/image_config/ntp/ntp-config.service @@ -2,6 +2,8 @@ Description=Update NTP configuration Requires=updategraph.service After=updategraph.service +Before=ntp.service +StartLimitIntervalSec=0 [Service] Type=oneshot diff --git a/files/image_config/ntp/ntp-config.sh b/files/image_config/ntp/ntp-config.sh index 601b7bd421f0..9b982d8707b6 100755 --- a/files/image_config/ntp/ntp-config.sh +++ b/files/image_config/ntp/ntp-config.sh @@ -1,5 +1,32 @@ #!/bin/bash +ntp_default_file='/etc/default/ntp' +ntp_temp_file='/tmp/ntp.orig' + +reboot_type='cold' + +function get_database_reboot_type() +{ + SYSTEM_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SYSTEM_FAST_START=`sonic-db-cli STATE_DB get "FAST_REBOOT|system"` + + if [[ x"${SYSTEM_WARM_START}" == x"true" ]]; then + reboot_type='warm' + elif [[ x"${SYSTEM_FAST_START}" == x"1" ]]; then + reboot_type='fast' + fi +} + +function modify_ntp_default +{ + cp ${ntp_default_file} ${ntp_temp_file} + sed -e "$1" ${ntp_temp_file} >${ntp_default_file} +} + sonic-cfggen -d -t /usr/share/sonic/templates/ntp.conf.j2 >/etc/ntp.conf -systemctl restart ntp +get_database_reboot_type +echo "Disabling NTP long jump for reboot type ${reboot_type} ..." +modify_ntp_default "s/NTPD_OPTS='-g'/NTPD_OPTS='-x'/" + +systemctl --no-block restart ntp diff --git a/files/image_config/ntp/ntp-systemd-wrapper b/files/image_config/ntp/ntp-systemd-wrapper new file mode 100644 index 000000000000..1e646f39369d --- /dev/null +++ b/files/image_config/ntp/ntp-systemd-wrapper @@ -0,0 +1,48 @@ +#!/bin/sh + +# This file was originally created automatically as part of default NTP application installation from debian package. +# This is now manually modified for supporting NTP in management VRF. +# When management VRF is enabled, the NTP application should be started using "ip vrf exec mgmt". +# Check has been added to verify the management VRF enabled status and use "ip vrf exec mgmt" when it is enabled. +# This file will be copied to /usr/lib/ntp/ntp-systemd-wrapper file that gets created during build process. + +DAEMON=/usr/sbin/ntpd +PIDFILE=/var/run/ntpd.pid + +if [ -r /etc/default/ntp ]; then + . /etc/default/ntp +fi + +if [ -e /run/ntp.conf.dhcp ]; then + NTPD_OPTS="$NTPD_OPTS -c /run/ntp.conf.dhcp" +fi + +LOCKFILE=/run/lock/ntpdate + +RUNASUSER=ntp +UGID=$(getent passwd $RUNASUSER | cut -f 3,4 -d:) || true +if test "$(uname -s)" = "Linux"; then + NTPD_OPTS="$NTPD_OPTS -u $UGID" +fi + +( + flock -w 180 9 + # when mgmt vrf is configured, ntp starts in mgmt vrf by default unless user configures otherwise + vrfEnabled=$(/usr/local/bin/sonic-cfggen -d -v 'MGMT_VRF_CONFIG["vrf_global"]["mgmtVrfEnabled"]' 2> /dev/null) + vrfConfigured=$(/usr/local/bin/sonic-cfggen -d -v 'NTP["global"]["vrf"]' 2> /dev/null) + if [ "$vrfEnabled" = "true" ] + then + if [ "$vrfConfigured" = "default" ] + then + log_daemon_msg "Starting NTP server in default-vrf for default set as NTP vrf" "ntpd" + start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --startas $DAEMON -- -p $PIDFILE $NTPD_OPTS + else + log_daemon_msg "Starting NTP server in mgmt-vrf" "ntpd" + ip vrf exec mgmt start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --startas $DAEMON -- -p $PIDFILE $NTPD_OPTS + fi + else + log_daemon_msg "Starting NTP server in default-vrf" "ntpd" + start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --startas $DAEMON -- -p $PIDFILE $NTPD_OPTS + fi +) 9>$LOCKFILE + diff --git a/files/image_config/ntp/ntp.conf.j2 b/files/image_config/ntp/ntp.conf.j2 index cef6527fc28f..4b763219325c 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 @@ -27,10 +31,49 @@ filegen clockstats file clockstats type day enable server {{ ntp_server }} iburst {% endfor %} +#listen on source interface if configured, else #only listen on MGMT_INTERFACE, LOOPBACK_INTERFACE ip when MGMT_INTERFACE is not defined, or eth0 # if we don't have both of them (default is to listen on all ip addresses) interface ignore wildcard -{% if MGMT_INTERFACE %} + +# set global variable for configured source interface name +# set global boolean to indicate if the ip of the configured source interface is configured +# if the source interface is configured but no ip on that interface, then listen on another +# interface based on existing logic +{%- macro check_ip_on_interface(interface_name, table_name) %} + {%- if table_name %} + {%- for (name, source_prefix) in table_name|pfx_filter %} + {%- if source_prefix and name == interface_name %} +true + {%- endif %} + {%- endfor %} + {%- endif %} +{%- endmacro %} + +{% set ns = namespace(source_intf = "") %} +{% set ns = namespace(source_intf_ip = 'false') %} +{% if (NTP) and (NTP['global']['src_intf']) %} + {% set ns.source_intf = (NTP['global']['src_intf']) %} + {% if ns.source_intf != "" %} + {% if ns.source_intf == "eth0" %} + {% set ns.source_intf_ip = 'true' %} + {% elif ns.source_intf.startswith('Vlan') %} + {% set ns.source_intf_ip = check_ip_on_interface(ns.source_intf, VLAN_INTERFACE) %} + {% elif ns.source_intf.startswith('Ethernet') %} + {% set ns.source_intf_ip = check_ip_on_interface(ns.source_intf, INTERFACE) %} + {% elif ns.source_intf.startswith('PortChannel') %} + {% set ns.source_intf_ip = check_ip_on_interface(ns.source_intf, PORTCHANNEL_INTERFACE) %} + {% elif ns.source_intf.startswith('Loopback') %} + {% set ns.source_intf_ip = check_ip_on_interface(ns.source_intf, LOOPBACK_INTERFACE) %} + {% endif %} + {% endif %} +{% endif %} + +{% if ns.source_intf_ip == 'true' %} +interface listen {{ns.source_intf}} +{% elif (NTP) and NTP['global']['vrf'] == 'mgmt' %} +interface listen eth0 +{% elif MGMT_INTERFACE %} {% for (mgmt_intf, mgmt_prefix) in MGMT_INTERFACE|pfx_filter %} interface listen {{ mgmt_prefix | ip }} {% endfor %} diff --git a/files/image_config/ntp/ntp.service b/files/image_config/ntp/ntp.service new file mode 100644 index 000000000000..acfd7e17266a --- /dev/null +++ b/files/image_config/ntp/ntp.service @@ -0,0 +1,16 @@ +[Unit] +Description=Network Time Service +Documentation=man:ntpd(8) +After=network.target +Conflicts=systemd-timesyncd.service +StartLimitIntervalSec=0 + +[Service] +Type=forking +# Debian uses a shell wrapper to process /etc/default/ntp +# and select DHCP-provided NTP servers if available +ExecStart=/usr/lib/ntp/ntp-systemd-wrapper +PrivateTmp=true + +[Install] +WantedBy=multi-user.target diff --git a/files/image_config/pcie-check/pcie-check.service b/files/image_config/pcie-check/pcie-check.service new file mode 100644 index 000000000000..fbf3cfd3f19d --- /dev/null +++ b/files/image_config/pcie-check/pcie-check.service @@ -0,0 +1,7 @@ +[Unit] +Description=Check the PCIe device presence and status +After=rc.local.service database.service + +[Service] +Type=simple +ExecStart=/usr/bin/pcie-check.sh diff --git a/files/image_config/pcie-check/pcie-check.sh b/files/image_config/pcie-check/pcie-check.sh new file mode 100755 index 000000000000..4257a2544c4a --- /dev/null +++ b/files/image_config/pcie-check/pcie-check.sh @@ -0,0 +1,59 @@ +#! /bin/bash +## Check the platform PCIe device presence and status + +VERBOSE="no" +RESULTS="PCIe Device Checking All Test" +EXPECTED="PCIe Device Checking All Test ----------->>> PASSED" +MAX_WAIT_SECONDS=15 + +function debug() +{ + /usr/bin/logger "$0 : $1" + if [[ x"${VERBOSE}" == x"yes" ]]; then + echo "$(date) $0: $1" + fi +} + +function check_and_rescan_pcie_devices() +{ + PCIE_CHK_CMD='sudo pcieutil check | grep "$RESULTS"' + PLATFORM=$(sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) + + if [ ! -f /usr/share/sonic/device/$PLATFORM/plugins/pcie.yaml ]; then + debug "pcie.yaml does not exist! Can't check PCIe status!" + exit + fi + + begin=$SECONDS + end=$((begin + MAX_WAIT_SECONDS)) + rescan_time=$((MAX_WAIT_SECONDS/2)) + rescan_time=$((begin + rescan_time)) + + while true + do + now=$SECONDS + if [[ $now -gt $end ]]; then + break + fi + + if [ "$(eval $PCIE_CHK_CMD)" = "$EXPECTED" ]; then + redis-cli -n 6 HSET "PCIE_DEVICES" "status" "PASSED" + debug "PCIe check passed" + exit + else + debug "sleep 0.1 seconds" + sleep 0.1 + fi + + if [ $now -gt $rescan_time ]; then + debug "PCIe check failed, try pci bus rescan" + echo 1 > /sys/bus/pci/rescan + rescan_time=$end + fi + + done + debug "PCIe check failed" + redis-cli -n 6 HSET "PCIE_DEVICES" "status" "FAILED" +} + +check_and_rescan_pcie_devices diff --git a/files/image_config/platform/rc.local b/files/image_config/platform/rc.local index 2884270b7870..b299f9fe2bba 100755 --- a/files/image_config/platform/rc.local +++ b/files/image_config/platform/rc.local @@ -11,9 +11,17 @@ # # By default this script does nothing. -SONIC_VERSION=$(sonic-cfggen -y /etc/sonic/sonic_version.yml -v build_version) +SONIC_VERSION=$(cat /etc/sonic/sonic_version.yml | grep "build_version" | sed -e "s/build_version: //g;s/'//g") FIRST_BOOT_FILE="/host/image-${SONIC_VERSION}/platform/firsttime" +# Move sonic-environment to /etc/sonic +SONIC_CONFIG_DIR="/host/image-${SONIC_VERSION}/sonic-config" +SONIC_ENV_FILE=${SONIC_CONFIG_DIR}/sonic-environment +if [ -d ${SONIC_CONFIG_DIR} -a -f ${SONIC_ENV_FILE} ]; then + echo "moving file ${SONIC_ENV_FILE} to /etc/sonic" 1>&2 + mv ${SONIC_ENV_FILE} /etc/sonic +fi + # In case the unit is migrating from another NOS, save the logs log_migration() { echo $1 >> /host/migration/migration.log @@ -53,8 +61,8 @@ update_mgmt_interface_macaddr() { fi # Get the ethtool magic and offset for changing the mac address in the EEPROM - ethtool_magic=$(grep "ethtool_magic" $mgmt_config | awk -F'=' '{print $2}') - ethtool_offset=$(grep "ethtool_offset" $mgmt_config | awk -F'=' '{print $2}') + ethtool_magic=$(grep "ethtool_magic" $mgmt_config | awk -F'=' '{print $2}') + ethtool_offset=$(grep "ethtool_offset" $mgmt_config | awk -F'=' '{print $2}') if [ -z "$ethtool_magic" ] || [ -z "$ethtool_offset" ]; then log_migration "Unable to retrieve ethtool params ($ethtool_magic,$ethtool_offset)" return @@ -82,10 +90,69 @@ update_mgmt_interface_macaddr() { log_migration "eth0 mac in EEPROM after update:" ethtool -e eth0 offset $ethtool_offset length 6 >> /host/migration/migration.log +} + +migrate_nos_configuration() +{ + rm -rf /host/migration + mkdir -p /host/migration + + # Extract the previous NOS's partition that contains the migration artifacts + set -- $(cat /proc/cmdline) + for x in "$@"; do + case "$x" in + nos-config-part=*) + nos_dev="${x#nos-config-part=}" + ;; + SONIC_BOOT_TYPE=fast*) + sonic_fast_reboot=true + ;; + esac + done + + if [ -n "$nos_dev" ]; then + # remove nos-config-part from cmdline + sed -r -i.bak "s/nos-config-part=[^[:space:]]+//" /host/grub/grub.cfg - # Update the 70-persistent-net.rules with the new mac for eth0 - log_migration "/etc/udev/rules.d/70-persistent-net.rules : replacing $old_mac with $new_mac for eth0" - sed -i "/eth0/ s/ATTR{address}==\"$old_mac\"/ATTR{address}==\"$new_mac\"/g" /etc/udev/rules.d/70-persistent-net.rules + # Mount the previous NOS's partition + NOS_DIR=/mnt/nos_migration + MG_GZFILE=$NOS_DIR/minigraph.xml.gz.base64.txt + MG_FILE=$NOS_DIR/minigraph.xml + ACL_GZFILE=$NOS_DIR/acl.json.gz.base64.txt + ACL_FILE=$NOS_DIR/acl.json + SNMP_FILE=$NOS_DIR/snmp.yml + mkdir -p $NOS_DIR + + mount $nos_dev $NOS_DIR + if [ $? != 0 ]; then + log_migration "ERROR: cannot mount $nos_dev" + else + + # decode & unzip minigraph.xml.gz.base64.txt + [ -f $MG_GZFILE ] && /usr/bin/base64 -d $MG_GZFILE | /bin/gunzip > $MG_FILE + [ -f $ACL_GZFILE ] && /usr/bin/base64 -d $ACL_GZFILE | /bin/gunzip > $ACL_FILE + + # Copy relevant files + nos_migration_import $NOS_DIR/mgmt_interface.cfg /host/migration + nos_migration_import $MG_FILE /host/migration + nos_migration_import $ACL_FILE /host/migration + nos_migration_import $SNMP_FILE /host/migration + + if [ "$sonic_fast_reboot" == true ]; then + mkdir -p /host/fast-reboot + nos_migration_import $NOS_DIR/arp.json /host/fast-reboot + nos_migration_import $NOS_DIR/fdb.json /host/fast-reboot + nos_migration_import $NOS_DIR/default_routes.json /host/fast-reboot + fi + + umount $NOS_DIR + rmdir $NOS_DIR + fi + + [ -f /host/migration/mgmt_interface.cfg ] && update_mgmt_interface_macaddr /host/migration/mgmt_interface.cfg + + migration="TRUE" + fi } firsttime_exit() { @@ -119,20 +186,20 @@ program_console_speed() systemctl daemon-reload } + #### Begin Main Body #### logger "SONiC version ${SONIC_VERSION} starting up..." # If the machine.conf is absent, it indicates that the unit booted # into SONiC from another NOS. Extract the machine.conf from ONIE. +grub_installation_needed="" if [ ! -e /host/machine.conf ]; then - mkdir -p /host/migration - onie_dev=$(blkid | grep ONIE-BOOT | head -n 1 | awk '{print $1}' | sed -e 's/:.*$//') mkdir -p /mnt/onie-boot mount $onie_dev /mnt/onie-boot onie_grub_cfg=/mnt/onie-boot/onie/grub/grub-machine.cfg - + if [ ! -e $onie_grub_cfg ]; then log_migration "$onie_grub_cfg not found" else @@ -141,62 +208,14 @@ if [ ! -e /host/machine.conf ]; then eval val='$'onie_$var echo "onie_${var}=${val}" >> /host/machine.conf done + grub_installation_needed="TRUE" fi - # Extract the previous NOS's partition that contains the migration artifacts - set -- $(cat /proc/cmdline) - for x in "$@"; do - case "$x" in - nos-config-part=*) - nos_val="${x#nos-config-part=}" - ;; - esac - done - - if [ -n "$nos_val" ]; then - nos_dev=$(findfs $nos_val) - if [ $? != 0 ]; then - log_migration "ERROR: nos_dev not found. Check grub parameters" - fi - else - log_migration "ERROR: nos_val not found. Check grub parameters" - fi - - if [ -n "$nos_dev" ]; then - # Mount the previous NOS's partition - NOS_DIR=/mnt/nos_migration - MG_GZFILE=$NOS_DIR/minigraph.xml.gz.base64.txt - MG_FILE=$NOS_DIR/minigraph.xml - ACL_GZFILE=$NOS_DIR/acl.json.gz.base64.txt - ACL_FILE=$NOS_DIR/acl.json - SNMP_FILE=$NOS_DIR/snmp.yml - mkdir -p $NOS_DIR - mount $nos_dev $NOS_DIR - mkdir -p /host/fast-reboot - - # decode & unzip minigraph.xml.gz.base64.txt - [ -f $MG_GZFILE ] && /usr/bin/base64 -d $MG_GZFILE | /bin/gunzip > $MG_FILE - [ -f $ACL_GZFILE ] && /usr/bin/base64 -d $ACL_GZFILE | /bin/gunzip > $ACL_FILE - - # Copy relevant files - nos_migration_import $NOS_DIR/mgmt_interface.cfg /host/migration - nos_migration_import $MG_FILE /host/migration - nos_migration_import $ACL_FILE /host/migration - nos_migration_import $SNMP_FILE /host/migration - nos_migration_import $NOS_DIR/arp.json /host/fast-reboot - nos_migration_import $NOS_DIR/fdb.json /host/fast-reboot - nos_migration_import $NOS_DIR/default_routes.json /host/fast-reboot - - umount $NOS_DIR - rmdir $NOS_DIR - fi - - update_mgmt_interface_macaddr /host/migration/mgmt_interface.cfg - - migration="TRUE" umount /mnt/onie-boot fi +migrate_nos_configuration + . /host/machine.conf program_console_speed @@ -254,7 +273,7 @@ if [ -f $FIRST_BOOT_FILE ]; then # If the unit booted into SONiC from another NOS's grub, # we now install a grub for SONiC. - if [ -n "$onie_platform" ] && [ -n "$migration" ]; then + if [ -n "$onie_platform" ] && [ -n "$grub_installation_needed" ]; then grub_bin=$(ls /host/image-$SONIC_VERSION/platform/x86_64-grub/grub-pc-bin*.deb 2> /dev/null) if [ -z "$grub_bin" ]; then @@ -337,7 +356,16 @@ if [ -f $FIRST_BOOT_FILE ]; then # Create dir where following scripts put their output files mkdir -p /var/platform + # Kdump tools configuration + sed -i -e "s/__PLATFORM__/$platform/g" /etc/default/kdump-tools + firsttime_exit fi +# Copy the fsck log into syslog +if [ -f /var/log/fsck.log.gz ]; then + gunzip -d -c /var/log/fsck.log.gz | logger -t "FSCK" + rm -f /var/log/fsck.log.gz +fi + exit 0 diff --git a/files/image_config/procdockerstatsd/procdockerstatsd b/files/image_config/procdockerstatsd/procdockerstatsd deleted file mode 100755 index a7bdcd6e6ce6..000000000000 --- a/files/image_config/procdockerstatsd/procdockerstatsd +++ /dev/null @@ -1,214 +0,0 @@ -#!/usr/bin/env python -''' -procdockerstatsd -Daemon which periodically gathers process and docker statistics and pushes the data to STATE_DB -''' - -import os -import re -import subprocess -import sys -import syslog -import time -from datetime import datetime - -import swsssdk - -VERSION = '1.0' - -SYSLOG_IDENTIFIER = "procdockerstatsd" - -REDIS_HOSTIP = "127.0.0.1" - -# ========================== Syslog wrappers ========================== -def log_info(msg, also_print_to_console=False): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_INFO, msg) - syslog.closelog() - -def log_warning(msg, also_print_to_console=False): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_WARNING, msg) - syslog.closelog() - -def log_error(msg, also_print_to_console=False): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_ERR, msg) - syslog.closelog() - -# ========================== ProcessDocker class ========================== -class ProcDockerStats: - - def __init__(self): - self.state_db = swsssdk.SonicV2Connector(host=REDIS_HOSTIP) - self.state_db.connect("STATE_DB") - - def run_command(self, cmd): - proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) - (stdout, stderr) = proc.communicate() - if proc.returncode != 0: - log_error("Error running command '{}'".format(cmd)) - return None - else: - return stdout - - def format_docker_cmd_output(self, cmdout): - lines = re.split("\n", cmdout) - keys = re.split(" +", lines[0]) - docker_data = dict() - docker_data_list = [] - for item in lines[1:]: - values1 = re.split(" +", item) - docker_data = dict(zip(keys, values1)) - docker_data_list.append(docker_data) - formatted_dict = self.create_docker_dict(docker_data_list) - return formatted_dict - - def format_process_cmd_output(self, cmdout): - lines = re.split("\n", cmdout) - keys = re.split(" +", lines[0]) - keylist = list(filter(None, keys)) - process_data = dict() - process_data_list = [] - for item in lines[1:]: - values1 = re.split(" +", str(item)) - # 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:])] - process_data = dict(zip(keylist, val)) - process_data_list.append(process_data) - return process_data_list - - def convert_to_bytes(self, value): - unit_value = re.search('[a-zA-Z]+', value) - value_to_convert = float(filter(str.isdigit, value)) - unit = unit_value.group(0) - UNITS_B = 'B' - UNITS_KB = 'KB' - UNITS_MB = 'MB' - UNITS_MiB = 'MiB' - UNITS_GiB = 'GiB' - if unit.lower() == UNITS_B.lower(): - return int(round(value_to_convert)) - elif unit.lower() == UNITS_KB.lower(): - value_converted = value_to_convert * 1000 - return int(round(value_converted)) - elif unit.lower() == UNITS_MB.lower(): - value_converted = value_to_convert * 1000 * 1000 - return int(round(value_converted)) - elif unit.lower() == UNITS_MiB.lower(): - value_converted = value_to_convert * 1024 * 1024 - return int(round(value_converted)) - elif unit.lower() == UNITS_GiB.lower(): - value_converted = value_to_convert * 1024 * 1024 * 1024 - return int(round(value_converted)) - - def create_docker_dict(self, dict_list): - dockerdict = {} - for row in dict_list[0:]: - cid = row.get('CONTAINER ID') - if 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]) - - splitcol = row.get('MEM USAGE / LIMIT') - memuse = re.split(" / ", str(splitcol)) - # converting MiB and GiB to bytes - dockerdict[key]['MEM_BYTES'] = str(self.convert_to_bytes(memuse[0])) - dockerdict[key]['MEM_LIMIT_BYTES'] = str(self.convert_to_bytes(memuse[1])) - - splitcol = row.get('MEM %') - mem = re.split("%", str(splitcol)) - dockerdict[key]['MEM%'] = str(mem[0]) - - splitcol = row.get('NET I/O') - 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])) - dockerdict[key]['BLOCK_OUT_BYTES'] = str(self.convert_to_bytes(blockio[1])) - - dockerdict[key]['PIDS'] = row.get('PIDS') - return dockerdict - - def update_dockerstats_command(self): - cmd = "docker stats --no-stream -a" - data = self.run_command(cmd) - if not data: - log_error("'{}' returned null output".format(cmd)) - return False - dockerdata = self.format_docker_cmd_output(data) - if not dockerdata: - log_error("formatting for docker output failed") - return False - # wipe out all data from state_db before updating - self.state_db.delete_all_by_pattern('STATE_DB', 'DOCKER_STATS|*') - for k1,v1 in dockerdata.iteritems(): - for k2,v2 in v1.iteritems(): - self.update_state_db(k1, k2, v2) - return True - - def update_processstats_command(self): - data = self.run_command("ps -eo uid,pid,ppid,%mem,%cpu,stime,tty,time,cmd --sort -%cpu | head -1024") - processdata = self.format_process_cmd_output(data) - value = "" - # wipe out all data before updating with new values - self.state_db.delete_all_by_pattern('STATE_DB', 'PROCESS_STATS|*') - for row in processdata[0:]: - cid = row.get('PID') - if cid: - value = 'PROCESS_STATS|' + str(cid) - uid = row.get('UID') - self.update_state_db(value, 'UID', uid) - ppid = row.get('PPID') - self.update_state_db(value, 'PPID', ppid) - cpu = row.get('%CPU') - self.update_state_db(value, '%CPU', str(cpu)) - mem = row.get('%MEM') - self.update_state_db(value, '%MEM', str(mem)) - stime = row.get('STIME') - self.update_state_db(value, 'STIME', stime) - tty = row.get('TT') - self.update_state_db(value, 'TT', tty) - time = row.get('TIME') - self.update_state_db(value, 'TIME', time) - cmd = row.get('CMD') - self.update_state_db(value, 'CMD', cmd) - - def update_state_db(self, key1, key2, value2): - self.state_db.set('STATE_DB', key1, key2, value2) - - def run(self): - self.update_dockerstats_command() - datetimeobj = datetime.now() - # Adding key to store latest update time. - self.update_state_db('DOCKER_STATS|LastUpdateTime', 'lastupdate', datetimeobj) - self.update_processstats_command() - self.update_state_db('PROCESS_STATS|LastUpdateTime', 'lastupdate', datetimeobj) - -# main start -def main(): - log_info("process-docker stats daemon starting up..") - if not os.getuid() == 0: - log_error("Must be root to run process-docker daemon") - print "Error: Must be root to run process-docker daemon" - sys.exit(1) - pd = ProcDockerStats() - # Data need to be updated every 2 mins. hence adding delay of 120 seconds - while True: - pd.run() - time.sleep(120) - log_info("process-docker stats daemon exited") - -if __name__ == '__main__': - main() - diff --git a/files/image_config/procdockerstatsd/procdockerstatsd.service b/files/image_config/procdockerstatsd/procdockerstatsd.service deleted file mode 100644 index 010dac15b2e6..000000000000 --- a/files/image_config/procdockerstatsd/procdockerstatsd.service +++ /dev/null @@ -1,13 +0,0 @@ -[Unit] -Description=Process and docker CPU/memory utilization data export daemon -Requires=database.service updategraph.service -After=database.service updategraph.service - -[Service] -Type=simple -ExecStart=/usr/bin/procdockerstatsd -Restart=always - -[Install] -WantedBy=multi-user.target - diff --git a/files/image_config/process-reboot-cause/process-reboot-cause b/files/image_config/process-reboot-cause/process-reboot-cause deleted file mode 100755 index 409deb7d6859..000000000000 --- a/files/image_config/process-reboot-cause/process-reboot-cause +++ /dev/null @@ -1,195 +0,0 @@ -#!/usr/bin/env python -# -# process-reboot-cause -# -# Program designed to run once, soon after system boot which will -# determine the cause of the previous reboot and store it to the disk, -# - -try: - import os - import pwd - import sys - import syslog - import re -except ImportError as err: - raise ImportError("%s - required module not found" % str(err)) - -VERSION = "1.0" - -SYSLOG_IDENTIFIER = "process-reboot-cause" - -REBOOT_CAUSE_DIR = "/host/reboot-cause/" -REBOOT_CAUSE_FILE = REBOOT_CAUSE_DIR + "reboot-cause.txt" -PREVIOUS_REBOOT_CAUSE_FILE = REBOOT_CAUSE_DIR + "previous-reboot-cause.txt" -FIRST_BOOT_PLATFORM_FILE = "/tmp/notify_firstboot_to_platform" -REBOOT_TYPE_KEXEC_FILE = "/proc/cmdline" -# The following SONIC_BOOT_TYPEs come from the warm/fast reboot script which is in sonic-utilities -# Because the system can be rebooted from some old versions, we have to take all possible BOOT options into consideration. -# On 201803, 201807 we have -# BOOT_OPTIONS="$(echo $KERNEL_OPTIONS | sed -e 's/\s*linux\s*/BOOT_IMAGE=/') fast-reboot" -# On 201811 and later we have -# BOOT_OPTIONS="$(echo $KERNEL_OPTIONS | sed -e 's/\s*linux\s*/BOOT_IMAGE=/') SONIC_BOOT_TYPE=${BOOT_TYPE_ARG}" where BOOT_TYPE_ARG can be warm, fastfast or fast -# To extract the commom part of them, we should have the following PATTERN -REBOOT_TYPE_KEXEC_PATTERN_WARM = ".*SONIC_BOOT_TYPE=(warm|fastfast).*" -REBOOT_TYPE_KEXEC_PATTERN_FAST = ".*SONIC_BOOT_TYPE=(fast|fast-reboot).*" - -UNKNOWN_REBOOT_CAUSE = "Unknown" - - -# ========================== Syslog wrappers ========================== - -def log_info(msg): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_INFO, msg) - syslog.closelog() - - -def log_warning(msg): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_WARNING, msg) - syslog.closelog() - - -def log_error(msg): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_ERR, msg) - syslog.closelog() - - -# ============================= Functions ============================= -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.search(REBOOT_TYPE_KEXEC_PATTERN_WARM, cause_file_kexec) - if m and m.group(1): - return 'warm-reboot' - m = re.search(REBOOT_TYPE_KEXEC_PATTERN_FAST, cause_file_kexec) - if m and m.group(1): - return 'fast-reboot' - return None - - -def find_software_reboot_cause(): - software_reboot_cause = UNKNOWN_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...") - - if not os.geteuid() == 0: - log_error("User {} does not have permission to execute".format(pwd.getpwuid(os.getuid()).pw_name)) - sys.exit("This utility must be run as root") - - # Create REBOOT_CAUSE_DIR if it doesn't exist - if not os.path.exists(REBOOT_CAUSE_DIR): - os.makedirs(REBOOT_CAUSE_DIR) - - # Remove stale PREVIOUS_REBOOT_CAUSE_FILE if it exists - 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 - - # 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: - prev_cause_file.write(previous_reboot_cause) - - # Also log the previous reboot cause to the syslog - log_info("Previous reboot cause: {}".format(previous_reboot_cause)) - - # Remove the old REBOOT_CAUSE_FILE - if os.path.exists(REBOOT_CAUSE_FILE): - os.remove(REBOOT_CAUSE_FILE) - - # Write a new default reboot cause file for the next reboot - with open(REBOOT_CAUSE_FILE, "w") as cause_file: - cause_file.write(UNKNOWN_REBOOT_CAUSE) - - -if __name__ == "__main__": - main() diff --git a/files/image_config/process-reboot-cause/process-reboot-cause.service b/files/image_config/process-reboot-cause/process-reboot-cause.service deleted file mode 100644 index b9821f60c420..000000000000 --- a/files/image_config/process-reboot-cause/process-reboot-cause.service +++ /dev/null @@ -1,7 +0,0 @@ -[Unit] -Description=Reboot cause determination service -After=rc-local.service - -[Service] -Type=simple -ExecStart=/usr/bin/process-reboot-cause diff --git a/files/image_config/rsyslog/rsyslog-config.sh b/files/image_config/rsyslog/rsyslog-config.sh index c8ba7b99453c..26767d84fbe0 100755 --- a/files/image_config/rsyslog/rsyslog-config.sh +++ b/files/image_config/rsyslog/rsyslog-config.sh @@ -1,4 +1,23 @@ #!/bin/bash -sonic-cfggen -d -t /usr/share/sonic/templates/rsyslog.conf.j2 >/etc/rsyslog.conf +PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` + +# Parse the device specific asic conf file, if it exists +ASIC_CONF=/usr/share/sonic/device/$PLATFORM/asic.conf +if [ -f "$ASIC_CONF" ]; then + source $ASIC_CONF +fi + +# On Multi NPU platforms we need to start the rsyslog server on the docker0 ip address +# for the syslogs from the containers in the namespaces to work. +# on Single NPU platforms we continue to use loopback adddres + +if [[ ($NUM_ASIC -gt 1) ]]; then + udp_server_ip=$(ip -o -4 addr list docker0 | awk '{print $4}' | cut -d/ -f1) +else + udp_server_ip=$(ip -o -4 addr list lo scope host | awk '{print $4}' | cut -d/ -f1) +fi + +sonic-cfggen -d -t /usr/share/sonic/templates/rsyslog.conf.j2 -a "{\"udp_server_ip\": \"$udp_server_ip\"}" >/etc/rsyslog.conf + systemctl restart rsyslog diff --git a/files/image_config/rsyslog/rsyslog-container.conf.j2 b/files/image_config/rsyslog/rsyslog-container.conf.j2 new file mode 100644 index 000000000000..d17fbb6767ba --- /dev/null +++ b/files/image_config/rsyslog/rsyslog-container.conf.j2 @@ -0,0 +1,76 @@ +# +# /etc/rsyslog.conf Configuration file for rsyslog. +# +# For more information see +# /usr/share/doc/rsyslog-doc/html/rsyslog_conf.html + + +################# +#### MODULES #### +################# + +$ModLoad imuxsock # provides support for local system logging + +# +# Set a rate limit on messages from the container +# +$SystemLogRateLimitInterval 300 +$SystemLogRateLimitBurst 20000 + +#$ModLoad imklog # provides kernel logging support +#$ModLoad immark # provides --MARK-- message capability + +# provides UDP syslog reception +#$ModLoad imudp +#$UDPServerRun 514 + +# provides TCP syslog reception +#$ModLoad imtcp +#$InputTCPServerRun 514 + + +########################### +#### GLOBAL DIRECTIVES #### +########################### + +# Set remote syslog server +template (name="ForwardFormatInContainer" type="string" string="<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% {{container_name}}#%syslogtag%%msg:::sp-if-no-1st-sp%%msg%") +*.* action(type="omfwd" target="{{target_ip}}" port="514" protocol="udp" Template="ForwardFormatInContainer") + +# +# Use traditional timestamp format. +# To enable high precision timestamps, comment out the following line. +# +#$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat + +# Define a custom template +$template SONiCFileFormat,"%TIMESTAMP%.%timestamp:::date-subseconds% %HOSTNAME% %syslogseverity-text:::uppercase% {{container_name}}#%syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n" +$ActionFileDefaultTemplate SONiCFileFormat + +# +# Set the default permissions for all log files. +# +$FileOwner root +$FileGroup adm +$FileCreateMode 0640 +$DirCreateMode 0755 +$Umask 0022 + +# +# Where to place spool and state files +# +$WorkDirectory /var/spool/rsyslog + +# +# Include all config files in /etc/rsyslog.d/ +# +$IncludeConfig /etc/rsyslog.d/*.conf + +# +# Suppress duplicate messages and report "message repeated n times" +# +$RepeatedMsgReduction on + +############### +#### RULES #### +############### diff --git a/files/image_config/rsyslog/rsyslog.conf.j2 b/files/image_config/rsyslog/rsyslog.conf.j2 index fbf8bf20160a..37410293a45f 100644 --- a/files/image_config/rsyslog/rsyslog.conf.j2 +++ b/files/image_config/rsyslog/rsyslog.conf.j2 @@ -19,7 +19,7 @@ $ModLoad imklog # provides kernel logging support # provides UDP syslog reception $ModLoad imudp -$UDPServerAddress 127.0.0.1 # bind to localhost before udp server run +$UDPServerAddress {{udp_server_ip}} #bind to localhost before udp server run $UDPServerRun 514 # provides TCP syslog reception diff --git a/files/image_config/rsyslog/rsyslog.d/00-sonic.conf b/files/image_config/rsyslog/rsyslog.d/00-sonic.conf index 455fe89fd2bf..bc69af74b8b3 100644 --- a/files/image_config/rsyslog/rsyslog.d/00-sonic.conf +++ b/files/image_config/rsyslog/rsyslog.d/00-sonic.conf @@ -1,15 +1,12 @@ ## Quagga rules -if $programname == ["bgp#quagga", - "bgp#watchquagga", - "bgp#zebra"] - then { - /var/log/quagga/zebra.log +if re_match($programname, "bgp[0-9]*#(frr|zebra|staticd|watchfrr)") then { + /var/log/frr/zebra.log stop } -if $programname == "bgp#bgpd" then { - /var/log/quagga/bgpd.log +if re_match($programname, "bgp[0-9]*#bgpd") then { + /var/log/frr/bgpd.log stop } diff --git a/files/image_config/secureboot/allowlist_paths.conf b/files/image_config/secureboot/allowlist_paths.conf new file mode 100644 index 000000000000..f1021f5c13e9 --- /dev/null +++ b/files/image_config/secureboot/allowlist_paths.conf @@ -0,0 +1,37 @@ +home/.* +var/core/.* +var/crash/.* +var/log/.* +etc/adjtime +etc/default/ntp +etc/dhcp/dhclient.conf +etc/ebtables.filter +etc/group +etc/gshadow +etc/hostname +etc/hosts +etc/machine-id +etc/network/interfaces +etc/nsswitch.conf +etc/ntp.conf +etc/pam.d/common-auth-sonic +etc/pam.d/sshd +etc/pam.d/login +etc/pam.d/sshd.old +etc/passwd +etc/rsyslog.conf +etc/shadow +etc/sonic/acl.json +etc/sonic/config_db.json +etc/sonic/minigraph.xml +etc/sonic/old_config/.* +etc/sonic/snmp.yml +etc/sonic/sonic-environment +etc/sonic/updategraph.conf +etc/ssh/ssh_host_rsa_key.pub +etc/ssh/ssh_host_rsa_key +etc/subgid +etc/subuid +etc/tacplus_nss.conf +etc/tacplus_user +lib/systemd/system/serial-getty@.service diff --git a/files/image_config/secureboot/allowlist_paths.md b/files/image_config/secureboot/allowlist_paths.md new file mode 100644 index 000000000000..7ce86b9bc90c --- /dev/null +++ b/files/image_config/secureboot/allowlist_paths.md @@ -0,0 +1,11 @@ +# Configuration Guide +It is the patterns of the relative paths in /host/image-{{hash}}/rw folder. +The patterns will not be used if the Sonic Secure Boot feature is not enabled. +The files that are not in the allowlist will be removed when the Sonic System cold reboot. + +### Example config to add all the files in a folder to allowlist +home/.* + +### Example config to add a file to allowlist +etc/nsswitch.conf + diff --git a/files/image_config/sudoers/sudoers b/files/image_config/sudoers/sudoers index 45b943846cb1..8ec8799c7cca 100644 --- a/files/image_config/sudoers/sudoers +++ b/files/image_config/sudoers/sudoers @@ -19,25 +19,29 @@ Defaults lecture_file = /etc/sudoers.lecture # Cmnd alias specification # Note: bcmcmd is dangerous for users in read only netgroups because it may operate ASIC -Cmnd_Alias READ_ONLY_CMDS = /sbin/brctl show, \ - /usr/bin/decode-syseeprom, \ - /usr/bin/docker images *, \ +Cmnd_Alias READ_ONLY_CMDS = /bin/cat /var/log/syslog*, \ + /sbin/brctl show, \ /usr/bin/docker exec snmp cat /etc/snmp/snmpd.conf, \ /usr/bin/docker exec bgp cat /etc/quagga/bgpd.conf, \ - /usr/bin/docker exec * ps aux, \ - /usr/bin/docker ps*, \ - /usr/bin/generate_dump, \ + /usr/bin/docker images *, \ + /usr/bin/docker ps *, \ + /usr/bin/docker ps, \ /usr/bin/lldpctl, \ - /usr/bin/lldpshow, \ - /usr/bin/psuutil *, \ /usr/bin/sensors, \ - /usr/bin/sfputil show *, \ - /usr/bin/teamshow, \ + /usr/bin/tail -F /var/log/syslog, \ /usr/bin/vtysh -c show *, \ - /bin/cat /var/log/syslog*, \ - /usr/bin/tail -F /var/log/syslog - -Cmnd_Alias PASSWD_CMDS = /usr/bin/config tacacs passkey *, \ + /usr/bin/vtysh -n [0-9] -c show *, \ + /usr/local/bin/decode-syseeprom, \ + /usr/local/bin/generate_dump, \ + /usr/local/bin/lldpshow, \ + /usr/local/bin/pcieutil *, \ + /usr/local/bin/psuutil *, \ + /usr/local/bin/sonic-installer list, \ + /usr/local/bin/sfputil show *, \ + /bin/ip netns identify [0-9]* + + +Cmnd_Alias PASSWD_CMDS = /usr/local/bin/config tacacs passkey *, \ /usr/sbin/chpasswd * # User privilege specification diff --git a/files/image_config/sysctl/sysctl-net.conf b/files/image_config/sysctl/sysctl-net.conf new file mode 100644 index 000000000000..84c24c8b0a8a --- /dev/null +++ b/files/image_config/sysctl/sysctl-net.conf @@ -0,0 +1,39 @@ +# All the sysctl for ipv4/ipv6 network. +# Same will be used in host or docker namespace +# It should be provided as key=value format for parsing +net.ipv6.conf.all.disable_ipv6=0 +net.ipv4.conf.default.forwarding=1 +net.ipv4.conf.all.forwarding=1 +net.ipv4.conf.eth0.forwarding=0 +net.ipv4.conf.default.arp_accept=0 +net.ipv4.conf.default.arp_announce=0 +net.ipv4.conf.default.arp_filter=0 +net.ipv4.conf.default.arp_notify=0 +net.ipv4.conf.default.arp_ignore=0 +net.ipv4.conf.all.arp_accept=0 +net.ipv4.conf.all.arp_announce=1 +net.ipv4.conf.all.arp_filter=0 +net.ipv4.conf.all.arp_notify=1 +net.ipv4.conf.all.arp_ignore=2 +net.ipv4.neigh.default.base_reachable_time_ms=1800000 +net.ipv6.neigh.default.base_reachable_time_ms=1800000 +net.ipv4.neigh.default.gc_thresh1=1024 +net.ipv6.neigh.default.gc_thresh1=1024 +net.ipv4.neigh.default.gc_thresh2=2048 +net.ipv6.neigh.default.gc_thresh2=2048 +net.ipv4.neigh.default.gc_thresh3=4096 +net.ipv6.neigh.default.gc_thresh3=4096 +net.ipv6.conf.default.forwarding=1 +net.ipv6.conf.all.forwarding=1 +net.ipv6.conf.eth0.forwarding=0 +net.ipv6.conf.default.accept_dad=0 +net.ipv6.conf.all.accept_dad=0 +net.ipv6.conf.eth0.accept_dad=0 +net.ipv6.conf.default.keep_addr_on_down=1 +net.ipv6.conf.all.keep_addr_on_down=1 +net.ipv6.conf.eth0.keep_addr_on_down=1 +net.ipv4.tcp_l3mdev_accept=1 +net.ipv4.udp_l3mdev_accept=1 +net.core.rmem_max=3145728 +net.core.wmem_max=3145728 +net.core.somaxconn=512 diff --git a/files/image_config/syslog/host_umount.sh b/files/image_config/syslog/host_umount.sh new file mode 100755 index 000000000000..6a057f16d582 --- /dev/null +++ b/files/image_config/syslog/host_umount.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# This script is invoked at the closure of syslog socket during reboot +# This will stop journal services, unmount /var/log and delete loop device +# associated to /host to ensure proper unmount of /host + +journal_stop() { + systemctl stop systemd-journald.service +} + +delete_loop_device() { + umount /var/log + if [[ $? -ne 0 ]] + then + exit 0 + fi + loop_exist=$(losetup -a | grep loop1 | wc -l) + if [ $loop_exist -ne 0 ]; then + losetup -d /dev/loop1 + fi +} + +case "$1" in + journal_stop|delete_loop_device) + $1 + ;; + *) + echo "Usage: $0 {journal_stop|delete_loop_device}" >&2 + exit 1 + ;; +esac + diff --git a/files/image_config/syslog/override.conf b/files/image_config/syslog/override.conf new file mode 100644 index 000000000000..5806cce0ecdc --- /dev/null +++ b/files/image_config/syslog/override.conf @@ -0,0 +1,6 @@ +[Unit] +After=var-log.mount host.mount local-fs.target + +[Socket] +ExecStopPre=/usr/bin/host_umount.sh journal_stop +ExecStopPost=/usr/bin/host_umount.sh delete_loop_device diff --git a/files/image_config/system-health/system-health.service b/files/image_config/system-health/system-health.service new file mode 100644 index 000000000000..3de6a51584cb --- /dev/null +++ b/files/image_config/system-health/system-health.service @@ -0,0 +1,11 @@ +[Unit] +Description=SONiC system health monitor +Requires=database.service updategraph.service +After=database.service updategraph.service + +[Service] +ExecStart=/usr/local/bin/healthd +Restart=always + +[Install] +WantedBy=multi-user.target diff --git a/files/image_config/topology/topology.sh b/files/image_config/topology/topology.sh index 7013920ec016..aba7565c8213 100755 --- a/files/image_config/topology/topology.sh +++ b/files/image_config/topology/topology.sh @@ -6,20 +6,21 @@ # 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=${PLATFORM:-`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform`} + HWSKU=${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=${PLATFORM:-`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform`} + HWSKU=${HWSKU:-`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]'`} + usr/share/sonic/device/$PLATFORM/$HWSKU/$TOPOLOGY_SCRIPT stop } +# read SONiC immutable variables +[ -f /etc/sonic/sonic-environment ] && . /etc/sonic/sonic-environment + case "$1" in start|stop) $1 diff --git a/files/image_config/updategraph/updategraph b/files/image_config/updategraph/updategraph index a24d452b1ad2..5c767b83d95c 100755 --- a/files/image_config/updategraph/updategraph +++ b/files/image_config/updategraph/updategraph @@ -3,27 +3,13 @@ reload_minigraph() { echo "Reloading minigraph..." - if [ ! -f /etc/sonic/init_cfg.json ]; then - echo "{}" > /etc/sonic/init_cfg.json - fi - sonic-db-cli CONFIG_DB FLUSHDB - sonic-cfggen -H -m -j /etc/sonic/init_cfg.json --write-to-db - 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 - config qos reload - DEVICE_TYPE=`sonic-cfggen -m -v DEVICE_METADATA.localhost.type` - if [ "${DEVICE_TYPE}" != "MgmtToRRouter" ]; then - pfcwd start_default - fi - - if [[ -x /usr/bin/db_migrator.py ]]; then - # Set latest version number - /usr/bin/db_migrator.py -o set_version - fi + config load_minigraph -y -n + config save -y } +# read SONiC immutable variables +[ -f /etc/sonic/sonic-environment ] && . /etc/sonic/sonic-environment + if [ ! -f /etc/sonic/updategraph.conf ]; then echo "No updategraph.conf found, generating a default one." echo "enabled=false" >/etc/sonic/updategraph.conf @@ -63,7 +49,7 @@ if [ "$src" = "dhcp" ]; then if [ "`cat /tmp/dhcp_graph_url`" = "N/A" ]; then echo "No graph_url option in DHCP response. Skipping graph update and generating an empty configuration." - PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` + PLATFORM=${PLATFORM:-`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform`} if [ -f /etc/sonic/minigraph.xml ]; then sonic-cfggen -H -m /etc/sonic/minigraph.xml --preset empty > /tmp/device_meta.json else @@ -141,7 +127,6 @@ else fi reload_minigraph -sonic-cfggen -d --print-data > /etc/sonic/config_db.json # Mark as disabled after graph is successfully downloaded sed -i "/enabled=/d" /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 0f9e0f7da299..172fd95ab2e9 100755 --- a/files/image_config/warmboot-finalizer/finalize-warmboot.sh +++ b/files/image_config/warmboot-finalizer/finalize-warmboot.sh @@ -2,11 +2,18 @@ VERBOSE=no -# Check components -COMP_LIST="orchagent neighsyncd bgp natsyncd" +# Define components that needs to reconcile during warm +# boot: +# The key is the name of the service that the components belong to. +# The value is list of component names that will reconcile. +declare -A RECONCILE_COMPONENTS=( \ + ["swss"]="orchagent neighsyncd" \ + ["bgp"]="bgp" \ + ["nat"]="natsyncd" \ + ) EXP_STATE="reconciled" -ASSISTANT_SCRIPT="/usr/bin/neighbor_advertiser" +ASSISTANT_SCRIPT="/usr/local/bin/neighbor_advertiser" function debug() @@ -18,6 +25,20 @@ function debug() } +function get_component_list() +{ + SVC_LIST=${!RECONCILE_COMPONENTS[@]} + COMPONENT_LIST="" + for service in ${SVC_LIST}; do + components=${RECONCILE_COMPONENTS[${service}]} + status=$(sonic-db-cli CONFIG_DB HGET "FEATURE|${service}" state) + if [[ x"${status}" == x"enabled" || x"${status}" == x"always_enabled" ]]; then + COMPONENT_LIST="${COMPONENT_LIST} ${components}" + fi + done +} + + function check_warm_boot() { WARM_BOOT=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` @@ -29,7 +50,9 @@ function wait_for_database_service() debug "Wait for database to become ready..." # Wait for redis server start before database clean - /usr/bin/docker exec database ping_pong_db_insts + until [[ $(sonic-db-cli PING | grep -c PONG) -gt 0 ]]; do + sleep 1; + done # Wait for configDB initialization until [[ $(sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; @@ -51,9 +74,9 @@ function check_list() RET_LIST='' for comp in $@; do state=`get_component_state ${comp}` - if [[ x"${state}" != x"${EXP_STATE}" ]]; then + if [[ x"${state}" != x"${EXP_STATE}" ]]; then RET_LIST="${RET_LIST} ${comp}" - fi + fi done echo ${RET_LIST} @@ -74,6 +97,20 @@ function stop_control_plane_assistant() fi } +function restore_counters_folder() +{ + debug "Restoring counters folder after warmboot..." + + modules=("portstat-0" "dropstat" "pfcstat-0" "queuestat-0" "intfstat-0") + for module in ${modules[@]} + do + statfile="/host/counters/$module" + if [[ -d $statfile ]]; then + mv $statfile /tmp/ + fi + done +} + wait_for_database_service @@ -84,13 +121,19 @@ if [[ x"${WARM_BOOT}" != x"true" ]]; then exit 0 fi -list=${COMP_LIST} +restore_counters_folder + +get_component_list + +debug "Waiting for components: '${COMPONENT_LIST}' to reconcile ..." + +list=${COMPONENT_LIST} # Wait up to 5 minutes for i in `seq 60`; do list=`check_list ${list}` if [[ -z "${list}" ]]; then - break + break fi sleep 5 done diff --git a/files/image_config/watchdog-control/watchdog-control.service b/files/image_config/watchdog-control/watchdog-control.service new file mode 100644 index 000000000000..579e645e248d --- /dev/null +++ b/files/image_config/watchdog-control/watchdog-control.service @@ -0,0 +1,10 @@ +[Unit] +Description=watchdog control service +After=swss.service + +[Service] +Type=simple +ExecStart=/usr/local/bin/watchdog-control.sh + +[Install] +WantedBy=multi-user.target diff --git a/files/image_config/watchdog-control/watchdog-control.sh b/files/image_config/watchdog-control/watchdog-control.sh new file mode 100755 index 000000000000..892039964620 --- /dev/null +++ b/files/image_config/watchdog-control/watchdog-control.sh @@ -0,0 +1,44 @@ +#! /bin/bash + +VERBOSE=no +WATCHDOG_UTIL="/usr/local/bin/watchdogutil" + +function debug() +{ + /usr/bin/logger "$0 : $1" + if [[ x"${VERBOSE}" == x"yes" ]]; then + echo "$(date) $0: $1" + fi +} + + +function getBootType() +{ + # same code snippet in files/scripts/syncd.sh + case "$(cat /proc/cmdline)" in + *SONIC_BOOT_TYPE=warm*) + TYPE='warm' + ;; + *SONIC_BOOT_TYPE=fastfast*) + TYPE='fastfast' + ;; + *SONIC_BOOT_TYPE=fast*|*fast-reboot*) + TYPE='fast' + ;; + *) + TYPE='cold' + esac + echo "${TYPE}" +} + +function disable_watchdog() +{ + # Obtain boot type from kernel arguments + BOOT_TYPE=`getBootType` + if [[ -x ${WATCHDOG_UTIL} ]]; then + debug "Disabling Watchdog during bootup after $BOOT_TYPE" + ${WATCHDOG_UTIL} disarm + fi +} + +disable_watchdog diff --git a/files/initramfs-tools/arista-convertfs.j2 b/files/initramfs-tools/arista-convertfs.j2 index 56616d2ba04a..9af44f221fe9 100644 --- a/files/initramfs-tools/arista-convertfs.j2 +++ b/files/initramfs-tools/arista-convertfs.j2 @@ -19,7 +19,8 @@ block_flash='' aboot_flag='' backup_file='' prev_os='' -sonic_fast_reboot='' +sonic_fast_reboot=false +in_kdump=false # Wait until get the fullpath of flash device, e.g., /dev/sda wait_get_flash_dev() { @@ -141,14 +142,20 @@ for x in "$@"; do SONIC_BOOT_TYPE=warm*|SONIC_BOOT_TYPE=fast*) sonic_fast_reboot=true ;; + systemd.unit=kdump-tools.service) + in_kdump=true + ;; esac done # Check aboot [ -z "$aboot_flag" ] && exit 0 +# Check kdump +[ "$in_kdump" = true ] && exit 0 + # Skip this script for warm-reboot/fast-reboot from sonic -[ "$sonic_fast_reboot" == true ] && [ "$prev_os" != eos ] && exit 0 +[ "$sonic_fast_reboot" = true ] && [ "$prev_os" != eos ] && exit 0 # Get flash dev name if [ -z "$block_flash" ]; then @@ -213,6 +220,9 @@ umount "$root_mnt" if [ $(echo -n "$root_dev" | tail -c 1) == "1" ]; then # Create a new partition table (content in flash_dev will be deleted) + err_msg="Error: Failed to zero out first MB" + cmd="dd if=/dev/zero of=$flash_dev bs=512 count=2048" + run_cmd "$cmd" "$err_msg" err_msg="Error: repartitioning $flash_dev failed" cmd="echo '2048' | sfdisk $flash_dev || (sleep 3; blockdev --rereadpt $flash_dev && fdisk -l $flash_dev | grep -q ${root_dev}.*Linux)" run_cmd "$cmd" "$err_msg" @@ -224,7 +234,7 @@ cmd="wait_for_root_dev" run_cmd "$cmd" "$err_msg" err_msg="Error: formatting to ext4 failed" -cmd="mke2fs -t ext4 -F -O '^huge_file,^metadata_csum' $root_dev" +cmd="/usr/local/sbin/mke2fs -t ext4 -F -O '^huge_file,^metadata_csum' $root_dev" run_cmd "$cmd" "$err_msg" err_msg="Error: mounting $root_dev to $root_mnt failed" diff --git a/files/initramfs-tools/arista-hook b/files/initramfs-tools/arista-hook index 521e38435b3d..868521b0db9d 100644 --- a/files/initramfs-tools/arista-hook +++ b/files/initramfs-tools/arista-hook @@ -45,6 +45,10 @@ for x in "$@"; do # Skip this script for warm-reboot and fast-reboot exit 0 ;; + systemd.unit=kdump-tools.service) + # In kdump environment, skip hooks + exit 0 + ;; esac done diff --git a/files/initramfs-tools/fsck-rootfs b/files/initramfs-tools/fsck-rootfs new file mode 100644 index 000000000000..25b1c096aa5b --- /dev/null +++ b/files/initramfs-tools/fsck-rootfs @@ -0,0 +1,34 @@ +#!/bin/sh + +case $1 in + prereqs) + exit 0 + ;; +esac + +# Extract kernel parameters +root_val="" +set -- $(cat /proc/cmdline) +for x in "$@"; do + case "$x" in + root=*) + root_val="${x#root=}" + ;; + esac +done + +# Check the filesystem we are using +if [ ! -z $root_val ]; then + fstype=$(blkid -o value -s TYPE $root_val) + case "$fstype" in + ext4) + cmd="fsck.ext4 -v -p" + ;; + ext3) + cmd="fsck.ext3 -v -p" + ;; + esac + if [ ! -z "$cmd" ]; then + $cmd $root_val 2>&1 | gzip -c > /tmp/fsck.log.gz + fi +fi diff --git a/files/initramfs-tools/mke2fs b/files/initramfs-tools/mke2fs index 52933d644a87..1f98f20c23c4 100644 --- a/files/initramfs-tools/mke2fs +++ b/files/initramfs-tools/mke2fs @@ -17,7 +17,7 @@ esac . /usr/share/initramfs-tools/hook-functions -copy_exec /sbin/mke2fs +copy_exec /usr/sbin/mke2fs /usr/local/sbin/ copy_exec /sbin/sfdisk copy_exec /sbin/fdisk copy_exec /sbin/resize2fs @@ -30,7 +30,7 @@ for type in $fstypes; do if [ -h "$prog" ]; then link=$(readlink -f "$prog") copy_exec "$link" - ln -s "$link" "${DESTDIR}/$prog" + ln -s "/usr/local/sbin/$(basename $link)" "${DESTDIR}/$prog" elif [ -x "$prog" ] ; then copy_exec "$prog" else diff --git a/files/initramfs-tools/modules b/files/initramfs-tools/modules index e7fcbef870d2..349bf37619e4 100644 --- a/files/initramfs-tools/modules +++ b/files/initramfs-tools/modules @@ -4,3 +4,4 @@ vfat nls_ascii nls_cp437 nls_utf8 +nvme diff --git a/files/initramfs-tools/modules.arm b/files/initramfs-tools/modules.arm index a923920bb1b2..0741051950c4 100644 --- a/files/initramfs-tools/modules.arm +++ b/files/initramfs-tools/modules.arm @@ -5,3 +5,10 @@ m25p80 ubi ubifs squashfs +marvell_nand +i2c_mv64xxx +ar7part +ofpart +mtdswap +mtd_blkdevs +adt7475 diff --git a/files/initramfs-tools/union-mount.j2 b/files/initramfs-tools/union-mount.j2 index 2376ea490e64..a97137a00c2f 100644 --- a/files/initramfs-tools/union-mount.j2 +++ b/files/initramfs-tools/union-mount.j2 @@ -11,17 +11,41 @@ case $1 in ;; esac +docker_inram=false +logs_inram=false +secureboot=false +bootloader=generic +in_kdump=false + +# Extract kernel parameters +for x in $(cat /proc/cmdline); do + case "$x" in + Aboot=*) + bootloader=aboot + ;; + docker_inram=on) + docker_inram=true + ;; + logs_inram=on) + logs_inram=true + ;; + secure_boot_enable=[y1]) + secureboot=true + docker_inram=true + ;; + platform=*) + platform_flag="${x#platform=}" + ;; + systemd.unit=kdump-tools.service) + in_kdump=true + ;; + esac +done + set_tmpfs_log_partition_size() { varlogsize=128 - # NOTE: certain platforms, when reaching initramfs stage, have a small - # limit of mounting tmpfs partition, potentially due to amount - # of RAM available in this stage. e.g. Arista 7050-qx32[s] and 7060-cx32s - [ 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 - # set varlogsize to existing var-log.ext4 size if [ -f ${rootmnt}/host/disk-img/var-log.ext4 ]; then varlogsize=$(ls -l ${rootmnt}/host/disk-img/var-log.ext4 | awk '{print $5}') @@ -38,18 +62,58 @@ set_tmpfs_log_partition_size() [ $maxsize -le $varlogsize ] && varlogsize=$maxsize } +remove_not_in_allowlist_files() +{ + local allowlist_file="$1" + local targeted_dir="$2" + local allowlist_pattern_file=/tmp/allowlist_paths.pattern + + # Return if the allowlist file does not exist + if ! test -f "${allowlist_file}"; then + echo "The file ${allowlist_file} is missing, failed to mount rw folder." 1>&2 + exit 1 + fi + + # Set the grep pattern file, remove the blank line in config file + awk -v rw_dir="$targeted_dir" 'NF {print rw_dir"/"$0"$"}' ${allowlist_file} > $allowlist_pattern_file + + # Find the files in the rw folder, and remove the files not in the allowlist + find ${targeted_dir} -type f | grep -v -f $allowlist_pattern_file | xargs /bin/rm -f + rm -f $allowlist_pattern_file +} + ## Mount the overlay file system: rw layer over squashfs image_dir=$(cat /proc/cmdline | sed -e 's/.*loop=\(\S*\)\/.*/\1/') -mkdir -p ${rootmnt}/host/$image_dir/rw -mkdir -p ${rootmnt}/host/$image_dir/work -mount -n -o lowerdir=${rootmnt},upperdir=${rootmnt}/host/$image_dir/rw,workdir=${rootmnt}/host/$image_dir/work -t overlay root-overlay ${rootmnt} +rw_dir=${rootmnt}/host/$image_dir/rw +work_dir=${rootmnt}/host/$image_dir/work +mkdir -p "$rw_dir" +mkdir -p "$work_dir" + +## Remove the files not in allowlist in the rw folder +if [ "$secureboot" = true ] && [ "$in_kdump" = false ]; then + if [ "$bootloader" = "aboot" ]; then + swi_path="${rootmnt}/host/$(sed -E 's/.*loop=([^ ]+).*/\1/' /proc/cmdline)" + unzip -q "$swi_path" allowlist_paths.conf -d /tmp + allowlist_file=/tmp/allowlist_paths.conf + else + allowlist_file=${rootmnt}/host/$image_dir/allowlist_paths.conf + fi + + remove_not_in_allowlist_files "$allowlist_file" "$rw_dir" + + ## Remove the executable permission for all the files in rw folder except home folder + find ${rw_dir} -type f -not -path ${rw_dir}/home -exec chmod a-x {} + +fi + +mount -n -o lowerdir=${rootmnt},upperdir=${rw_dir},workdir=${work_dir} -t overlay root-overlay ${rootmnt} + ## Check if the root block device is still there [ -b ${ROOT} ] || mdev -s case "${ROOT}" in ubi*) mtd=$(cat /proc/cmdline | sed -e 's/.*ubi.mtd=\([0-9]\) .*/\1/') if [ ! -f /dev/${ROOT}_0 ]; then - ubiattach /dev/ubi_ctrl -m $mtd || true + ubiattach /dev/ubi_ctrl -m $mtd 2>dev/null || true fi mount -t ubifs /dev/${ROOT}_0 ${rootmnt}/host ;; @@ -60,29 +124,46 @@ case "${ROOT}" in esac mkdir -p ${rootmnt}/var/lib/docker -if [ -f ${rootmnt}/host/$image_dir/{{ FILESYSTEM_DOCKERFS }} ]; then - ## mount tmpfs and extract docker into it - mount -t tmpfs -o rw,nodev,size={{ DOCKER_RAMFS_SIZE }} tmpfs ${rootmnt}/var/lib/docker - tar xz --numeric-owner -f ${rootmnt}/host/$image_dir/{{ FILESYSTEM_DOCKERFS }} -C ${rootmnt}/var/lib/docker -else - ## Mount the working directory of docker engine in the raw partition, bypass the overlay - mount --bind ${rootmnt}/host/$image_dir/{{ DOCKERFS_DIR }} ${rootmnt}/var/lib/docker +if [ "$in_kdump" = false ]; then + if [ "$secureboot" = true ]; then + mount -t tmpfs -o rw,nodev,size={{ DOCKER_RAMFS_SIZE }} tmpfs ${rootmnt}/var/lib/docker + if [ "$bootloader" = "aboot" ]; then + unzip -qp "$swi_path" dockerfs.tar.gz | tar xz --numeric-owner -C ${rootmnt}/var/lib/docker + ## Boot folder is not extracted during secureboot since content would inherently become unsafe + mkdir -p ${rootmnt}/host/$image_dir/boot + else + echo "secureboot unsupported for bootloader $bootloader" 1>&2 + exit 1 + fi + elif [ -f ${rootmnt}/host/$image_dir/{{ FILESYSTEM_DOCKERFS }} ]; then + ## mount tmpfs and extract docker into it + mount -t tmpfs -o rw,nodev,size={{ DOCKER_RAMFS_SIZE }} tmpfs ${rootmnt}/var/lib/docker + tar xz --numeric-owner -f ${rootmnt}/host/$image_dir/{{ FILESYSTEM_DOCKERFS }} -C ${rootmnt}/var/lib/docker + else + ## Mount the working directory of docker engine in the raw partition, bypass the overlay + mount --bind ${rootmnt}/host/$image_dir/{{ DOCKERFS_DIR }} ${rootmnt}/var/lib/docker + fi fi ## Mount the boot directory in the raw partition, bypass the overlay mkdir -p ${rootmnt}/boot mount --bind ${rootmnt}/host/$image_dir/boot ${rootmnt}/boot + ## Mount loop device or tmpfs for /var/log -onie_platform="" -aboot_platform="" -. ${rootmnt}/host/machine.conf -if [ X"$aboot_platform" = X"x86_64-arista_7050_qx32" ] || - [ X"$aboot_platform" = X"x86_64-arista_7050_qx32s" ] || - [ X"$aboot_platform" = X"x86_64-arista_7060_cx32s" ] -then +if $logs_inram; then + # NOTE: some platforms, when reaching initramfs stage, have a small + # limit of mounting tmpfs partition, potentially due to amount + # of RAM available in this stage. e.g. Arista 7050-qx32[s] and 7060-cx32s set_tmpfs_log_partition_size mount -t tmpfs -o rw,nosuid,nodev,size=${varlogsize}M tmpfs ${rootmnt}/var/log [ -f ${rootmnt}/host/disk-img/var-log.ext4 ] && rm -rf ${rootmnt}/host/disk-img/var-log.ext4 else + [ -f ${rootmnt}/host/disk-img/var-log.ext4 ] && fsck.ext4 -v -p ${rootmnt}/host/disk-img/var-log.ext4 2>&1 \ + | gzip -c >> /tmp/fsck.log.gz [ -f ${rootmnt}/host/disk-img/var-log.ext4 ] && mount -t ext4 -o loop,rw ${rootmnt}/host/disk-img/var-log.ext4 ${rootmnt}/var/log fi + +## fscklog file: /tmp will be lost when overlayfs is mounted +if [ -f /tmp/fsck.log.gz ]; then + mv /tmp/fsck.log.gz ${rootmnt}/var/log +fi diff --git a/files/scripts/arp_update b/files/scripts/arp_update index 3cc9cd267985..2fec40c14beb 100755 --- a/files/scripts/arp_update +++ b/files/scripts/arp_update @@ -7,12 +7,13 @@ # Send gratuitous ARP/NDP requests to VLAN member neighbors to refresh # the ipv4/ipv6 neighbors state. +ARP_UPDATE_VARS_FILE="/usr/share/sonic/templates/arp_update_vars.j2" + while /bin/true; do # find L3 interfaces which are UP, send ipv6 multicast pings - echo "{% for (name, prefix) in INTERFACE|pfx_filter %} {{name}} {% endfor %}" > /tmp/intf_tmp.j2 - INTERFACE=`sonic-cfggen -d -t /tmp/intf_tmp.j2` - echo "{% for (name, prefix) in PORTCHANNEL_INTERFACE|pfx_filter %} {{name}} {% endfor %}" > /tmp/pc_intf_tmp.j2 - PC_INTERFACE=`sonic-cfggen -d -t /tmp/pc_intf_tmp.j2` + ARP_UPDATE_VARS=$(sonic-cfggen -d -t ${ARP_UPDATE_VARS_FILE}) + INTERFACE=$(echo $ARP_UPDATE_VARS | jq -r '.interface') + PC_INTERFACE=$(echo $ARP_UPDATE_VARS | jq -r '.pc_interface') ALL_INTERFACE="$INTERFACE $PC_INTERFACE" for intf in $ALL_INTERFACE; do @@ -23,7 +24,7 @@ while /bin/true; do fi done - VLAN=`sonic-cfggen -d -v 'VLAN.keys() | join(" ") if VLAN'` + VLAN=$(echo $ARP_UPDATE_VARS | jq -r '.vlan') for vlan in $VLAN; do # generate a list of arping commands: # arping -q -w 0 -c 1 -i ; diff --git a/files/scripts/bgp.sh b/files/scripts/bgp.sh new file mode 100755 index 000000000000..b7a383ebbdd7 --- /dev/null +++ b/files/scripts/bgp.sh @@ -0,0 +1,102 @@ +#!/bin/bash + +function debug() +{ + /usr/bin/logger $1 + /bin/echo `date` "- $1" >> ${DEBUGLOG} +} + +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` + if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then + WARM_BOOT="true" + else + WARM_BOOT="false" + fi +} + +function validate_restore_count() +{ + if [[ x"$WARM_BOOT" == x"true" ]]; then + RESTORE_COUNT=`$SONIC_DB_CLI STATE_DB hget "WARM_RESTART_TABLE|bgp" restore_count` + # We have to make sure db data has not been flushed. + if [[ -z "$RESTORE_COUNT" ]]; then + WARM_BOOT="false" + fi + fi +} + +function check_fast_boot () +{ + if [[ $($SONIC_DB_CLI STATE_DB GET "FAST_REBOOT|system") == "1" ]]; then + FAST_BOOT="true" + else + FAST_BOOT="false" + fi +} + +start() { + debug "Starting ${SERVICE}$DEV service..." + + check_warm_boot + validate_restore_count + + check_fast_boot + + debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." + debug "Fast boot flag: ${SERVICE}$DEV ${Fast_BOOT}." + + # start service docker + /usr/bin/${SERVICE}.sh start $DEV + debug "Started ${SERVICE}$DEV service..." + +} + +wait() { + /usr/bin/${SERVICE}.sh wait $DEV +} + +stop() { + debug "Stopping ${SERVICE}$DEV service..." + + check_warm_boot + check_fast_boot + debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." + debug "Fast boot flag: ${SERVICE}$DEV ${FAST_BOOT}." + + # Kill bgpd to start the bgp graceful restart procedure + if [[ x"$WARM_BOOT" == x"true" ]] || [[ x"$FAST_BOOT" == x"true" ]]; then + debug "Kill zebra first" + /usr/bin/docker exec -i bgp pkill -9 zebra || [ $? == 1 ] + /usr/bin/docker exec -i bgp pkill -9 bgpd || [ $? == 1 ] + fi + + /usr/bin/${SERVICE}.sh stop $DEV + debug "Stopped ${SERVICE}$DEV service..." + +} + +DEV=$2 + +SERVICE="bgp" +DEBUGLOG="/tmp/bgp-debug$DEV.log" +NAMESPACE_PREFIX="asic" +if [ "$DEV" ]; then + NET_NS="$NAMESPACE_PREFIX$DEV" #name of the network namespace + SONIC_DB_CLI="sonic-db-cli -n $NET_NS" +else + NET_NS="" + SONIC_DB_CLI="sonic-db-cli" +fi + +case "$1" in + start|wait|stop) + $1 + ;; + *) + echo "Usage: $0 {start|wait|stop}" + exit 1 + ;; +esac diff --git a/files/scripts/configdb-load.sh b/files/scripts/configdb-load.sh index b1bf761371bf..fde2de5c6f2b 100755 --- a/files/scripts/configdb-load.sh +++ b/files/scripts/configdb-load.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # Wait until redis starts -until [[ $(redis-cli ping | grep -c PONG) -gt 0 ]]; do +until [[ $(sonic-db-cli PING | grep -c PONG) -gt 0 ]]; do sleep 1; done diff --git a/files/scripts/core_cleanup.py b/files/scripts/core_cleanup.py index 67620b2397de..bf68416c7009 100755 --- a/files/scripts/core_cleanup.py +++ b/files/scripts/core_cleanup.py @@ -1,31 +1,25 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 -import syslog import os - from collections import defaultdict from datetime import datetime +from sonic_py_common.logger import Logger + SYSLOG_IDENTIFIER = 'core_cleanup.py' -CORE_FILE_DIR = os.path.basename(__file__) +CORE_FILE_DIR = '/var/core/' MAX_CORE_FILES = 4 -def log_info(msg): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_INFO, msg) - syslog.closelog() - -def log_error(msg): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_ERR, msg) - syslog.closelog() def main(): + logger = Logger(SYSLOG_IDENTIFIER) + logger.set_min_log_priority_info() + if os.getuid() != 0: - log_error('Root required to clean up core files') + logger.log_error('Root required to clean up core files') return - log_info('Cleaning up core files') + logger.log_info('Cleaning up core files') core_files = [f for f in os.listdir(CORE_FILE_DIR) if os.path.isfile(os.path.join(CORE_FILE_DIR, f))] core_files_by_process = defaultdict(list) @@ -35,17 +29,17 @@ def main(): curr_files.append(f) if len(curr_files) > MAX_CORE_FILES: - curr_files.sort(reverse = True, key = lambda x: datetime.utcfromtimestamp(int(x.split('.')[1]))) + curr_files.sort(reverse=True, key=lambda x: datetime.utcfromtimestamp(int(x.split('.')[1]))) oldest_core = curr_files[MAX_CORE_FILES] - log_info('Deleting {}'.format(oldest_core)) + logger.log_info('Deleting {}'.format(oldest_core)) try: os.remove(os.path.join(CORE_FILE_DIR, oldest_core)) except: - log_error('Unexpected error occured trying to delete {}'.format(oldest_core)) + logger.log_error('Unexpected error occured trying to delete {}'.format(oldest_core)) core_files_by_process[process] = curr_files[0:MAX_CORE_FILES] - log_info('Finished cleaning up core files') + logger.log_info('Finished cleaning up core files') + if __name__ == '__main__': main() - diff --git a/files/scripts/gbsyncd.sh b/files/scripts/gbsyncd.sh new file mode 100755 index 000000000000..996fbf8cdf31 --- /dev/null +++ b/files/scripts/gbsyncd.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +. /usr/local/bin/syncd_common.sh + +function startplatform() { + : +} + +function waitplatform() { + : +} + +function stopplatform1() { + : +} + +function stopplatform2() { + : +} + +OP=$1 +DEV=$2 + +SERVICE="gbsyncd" +PEER="swss" +DEBUGLOG="/tmp/swss-gbsyncd-debug$DEV.log" +LOCKFILE="/tmp/swss-gbsyncd-lock$DEV" +NAMESPACE_PREFIX="asic" +if [ "$DEV" ]; then + NET_NS="$NAMESPACE_PREFIX$DEV" #name of the network namespace + SONIC_DB_CLI="sonic-db-cli -n $NET_NS" +else + NET_NS="" + SONIC_DB_CLI="sonic-db-cli" +fi + +case "$1" in + start|wait|stop) + $1 + ;; + *) + echo "Usage: $0 {start|wait|stop}" + exit 1 + ;; +esac diff --git a/files/scripts/radv.sh b/files/scripts/radv.sh new file mode 100755 index 000000000000..1047808e4e44 --- /dev/null +++ b/files/scripts/radv.sh @@ -0,0 +1,84 @@ +#!/bin/bash + +function debug() +{ + /usr/bin/logger $1 + /bin/echo `date` "- $1" >> ${DEBUGLOG} +} + +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` + if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then + WARM_BOOT="true" + else + WARM_BOOT="false" + fi +} + +function check_fast_boot () +{ + if [[ $($SONIC_DB_CLI STATE_DB GET "FAST_REBOOT|system") == "1" ]]; then + FAST_BOOT="true" + else + FAST_BOOT="false" + fi +} + +start() { + debug "Starting ${SERVICE}$DEV service..." + + check_warm_boot + check_fast_boot + debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." + debug "Fast boot flag: ${SERVICE}$DEV ${FAST_BOOT}." + + # start service docker + /usr/bin/${SERVICE}.sh start $DEV + debug "Started ${SERVICE}$DEV service..." +} + +wait() { + /usr/bin/${SERVICE}.sh wait $DEV +} + +stop() { + debug "Stopping ${SERVICE}$DEV service..." + + check_warm_boot + check_fast_boot + debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." + debug "Fast boot flag: ${SERVICE}$DEV ${FAST_BOOT}." + + # For WARM/FAST boot do not perform service stop + if [[ x"$WARM_BOOT" != x"true" ]] && [[ x"$FAST_BOOT" != x"true" ]]; then + /usr/bin/${SERVICE}.sh stop $DEV + debug "Stopped ${SERVICE}$DEV service..." + else + debug "Killing Docker radv..." + /usr/bin/docker kill radv &> /dev/null || debug "Docker radv is not running ($?) ..." + fi +} + +DEV=$2 + +SERVICE="radv" +DEBUGLOG="/tmp/radv-debug$DEV.log" +NAMESPACE_PREFIX="asic" +if [ "$DEV" ]; then + NET_NS="$NAMESPACE_PREFIX$DEV" #name of the network namespace + SONIC_DB_CLI="sonic-db-cli -n $NET_NS" +else + SONIC_DB_CLI="sonic-db-cli" +fi + +case "$1" in + start|wait|stop) + $1 + ;; + *) + echo "Usage: $0 {start|wait|stop}" + exit 1 + ;; +esac diff --git a/files/scripts/sonic-netns-exec b/files/scripts/sonic-netns-exec new file mode 100755 index 000000000000..a0dfc6f9ab07 --- /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 [ ! -z "$NS" ]; then + ip netns exec $NS "$@" +else + "$@" +fi diff --git a/files/scripts/supervisor-proc-exit-listener b/files/scripts/supervisor-proc-exit-listener index cf154b3a5c10..e8565b4d52f2 100755 --- a/files/scripts/supervisor-proc-exit-listener +++ b/files/scripts/supervisor-proc-exit-listener @@ -1,22 +1,109 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import getopt import os +import re +import select import signal import sys import syslog +import time 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 +# Each line of this file should specify either one critical process or one +# critical process group, (as defined in supervisord.conf file), in the +# following format: +# +# program: +# group: CRITICAL_PROCESSES_FILE = '/etc/supervisor/critical_processes' -# 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' +# The FEATURE table in config db contains auto-restart field +FEATURE_TABLE_NAME = 'FEATURE' + +# Value of parameter 'timeout' in select(...) method +SELECT_TIMEOUT_SECS = 1.0 + +# Alerting message will be written into syslog in the following interval +ALERTING_INTERVAL_SECS = 60 + + +def get_critical_group_and_process_list(): + """ + @summary: Read the critical processes/group names from CRITICAL_PROCESSES_FILE. + @return: Two lists which contain critical processes and group names respectively. + """ + critical_group_list = [] + critical_process_list = [] + + with open(CRITICAL_PROCESSES_FILE, 'r') as file: + for line in file: + # ignore blank lines + if re.match(r"^\s*$", line): + continue + line_info = line.strip(' \n').split(':') + if len(line_info) != 2: + syslog.syslog(syslog.LOG_ERR, + "Syntax of the line {} in critical_processes file is incorrect. Exiting...".format(line)) + sys.exit(5) + + identifier_key = line_info[0].strip() + identifier_value = line_info[1].strip() + if identifier_key == "group" and identifier_value: + critical_group_list.append(identifier_value) + elif identifier_key == "program" and identifier_value: + critical_process_list.append(identifier_value) + else: + syslog.syslog(syslog.LOG_ERR, + "Syntax of the line {} in critical_processes file is incorrect. Exiting...".format(line)) + sys.exit(6) + + return critical_group_list, critical_process_list + + +def generate_alerting_message(process_name): + """ + @summary: If a critical process was not running, this function will determine it resides in host + or in a specific namespace. Then an alerting message will be written into syslog. + """ + namespace_prefix = os.environ.get("NAMESPACE_PREFIX") + namespace_id = os.environ.get("NAMESPACE_ID") + + if not namespace_prefix or not namespace_id: + namespace = "host" + else: + namespace = namespace_prefix + namespace_id + + syslog.syslog(syslog.LOG_ERR, "Process '{}' is not running in namespace '{}'.".format(process_name, namespace)) + + +def get_autorestart_state(container_name): + """ + @summary: Read the status of auto-restart feature from Config_DB. + @return: Return the status of auto-restart feature. + """ + config_db = swsssdk.ConfigDBConnector() + config_db.connect() + features_table = config_db.get_table(FEATURE_TABLE_NAME) + if not features_table: + syslog.syslog(syslog.LOG_ERR, "Unable to retrieve features table from Config DB. Exiting...") + sys.exit(2) + + if container_name not in features_table: + syslog.syslog(syslog.LOG_ERR, "Unable to retrieve feature '{}'. Exiting...".format(container_name)) + sys.exit(3) + + is_auto_restart = features_table[container_name].get('auto_restart') + if not is_auto_restart: + syslog.syslog( + syslog.LOG_ERR, "Unable to determine auto-restart feature status for '{}'. Exiting...".format(container_name)) + sys.exit(4) + + return is_auto_restart + def main(argv): container_name = None @@ -29,55 +116,57 @@ def main(argv): 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] + critical_group_list, critical_process_list = get_critical_group_and_process_list() + + process_under_alerting = {} + # Transition from ACKNOWLEDGED to READY + childutils.listener.ready() while True: - # Transition from ACKNOWLEDGED to READY - childutils.listener.ready() - - line = sys.stdin.readline() - headers = childutils.get_headers(line) - payload = sys.stdin.read(int(headers['len'])) - - # Transition from READY to ACKNOWLEDGED - childutils.listener.ok() - - # We only care about PROCESS_STATE_EXITED events - if headers['eventname'] == 'PROCESS_STATE_EXITED': - payload_headers, payload_data = childutils.eventdata(payload + '\n') - - expected = int(payload_headers['expected']) - processname = payload_headers['processname'] - groupname = payload_headers['groupname'] - - # 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) - os.kill(os.getppid(), signal.SIGTERM) + file_descriptor_list = select.select([sys.stdin], [], [], SELECT_TIMEOUT_SECS)[0] + if len(file_descriptor_list) > 0: + line = file_descriptor_list[0].readline() + headers = childutils.get_headers(line) + payload = sys.stdin.read(int(headers['len'])) + + # Handle the PROCESS_STATE_EXITED event + if headers['eventname'] == 'PROCESS_STATE_EXITED': + payload_headers, payload_data = childutils.eventdata(payload + '\n') + + expected = int(payload_headers['expected']) + process_name = payload_headers['processname'] + group_name = payload_headers['groupname'] + + if (process_name in critical_process_list or group_name in critical_group_list) and expected == 0: + is_auto_restart = get_autorestart_state(container_name) + if is_auto_restart != "disabled": + MSG_FORMAT_STR = "Process '{}' exited unexpectedly. Terminating supervisor '{}'" + msg = MSG_FORMAT_STR.format(payload_headers['processname'], container_name) + syslog.syslog(syslog.LOG_INFO, msg) + os.kill(os.getppid(), signal.SIGTERM) + else: + process_under_alerting[process_name] = time.time() + + # Handle the PROCESS_STATE_RUNNING event + elif headers['eventname'] == 'PROCESS_STATE_RUNNING': + payload_headers, payload_data = childutils.eventdata(payload + '\n') + process_name = payload_headers['processname'] + + if process_name in process_under_alerting: + process_under_alerting.pop(process_name) + + # Transition from BUSY to ACKNOWLEDGED + childutils.listener.ok() + + # Transition from ACKNOWLEDGED to READY + childutils.listener.ready() + + # Check whether we need write alerting messages into syslog + for process in process_under_alerting.keys(): + epoch_time = time.time() + if epoch_time - process_under_alerting[process] >= ALERTING_INTERVAL_SECS: + process_under_alerting[process] = epoch_time + generate_alerting_message(process) if __name__ == "__main__": diff --git a/files/scripts/swss.sh b/files/scripts/swss.sh index a14d03e40f50..97e50cb975e7 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_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,10 +37,19 @@ function check_warm_boot() fi } +function check_fast_boot() +{ + if [[ $($SONIC_DB_CLI STATE_DB GET "FAST_REBOOT|system") == "1" ]]; then + FAST_BOOT="true" + else + FAST_BOOT="false" + fi +} + 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_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 +60,12 @@ 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 + until [[ $($SONIC_DB_CLI PING | grep -c PONG) -gt 0 ]]; do + sleep 1; + done # Wait for configDB initialization - until [[ $(sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $($SONIC_DB_CLI CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done } @@ -67,7 +75,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_DB_CLI $1 EVAL " local tables = {$2} for i = 1, table.getn(tables) do local matches = redis.call('KEYS', tables[i]) @@ -81,25 +89,47 @@ 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 warm/fast start enabled or peer lock exists, don't stop peer service docker + if [[ x"$WARM_BOOT" != x"true" ]] && [[ x"$FAST_BOOT" != x"true" ]]; then + for dep in ${MULTI_INST_DEPENDENT}; do + if [[ ! -z $DEV ]]; then + /bin/systemctl stop ${dep}@$DEV + else + /bin/systemctl stop ${dep} + fi + done for dep in ${DEPENDENT}; do /bin/systemctl stop ${dep} done + if [[ ! -z $DEV ]]; then + /bin/systemctl stop ${PEER}@$DEV + else + /bin/systemctl stop ${PEER} + fi fi } start() { - debug "Starting ${SERVICE} service..." + debug "Starting ${SERVICE}$DEV service..." lock_service_state_change @@ -107,21 +137,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 - 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*'" + $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*', 'FG_ROUTE_TABLE*', 'BUFFER_POOL*', 'BUFFER_PROFILE*', '*MUX_CABLE_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,8 +164,25 @@ 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 [[ x"$RUNNING" == x"true" ]]; then + if [[ ! -z $DEV ]]; then + RUNNING=$(docker inspect -f '{{.State.Running}}' ${PEER}$DEV) + else + RUNNING=$(docker inspect -f '{{.State.Running}}' ${PEER}) + fi + ALL_DEPS_RUNNING=true + for dep in ${MULTI_INST_DEPENDENT}; do + if [[ ! -z $DEV ]]; then + DEP_RUNNING=$(docker inspect -f '{{.State.Running}}' ${dep}$DEV) + else + DEP_RUNNING=$(docker inspect -f '{{.State.Running}}' ${dep}) + fi + if [[ x"$DEP_RUNNING" != x"true" ]]; then + ALL_DEPS_RUNNING=false + break + fi + done + + if [[ x"$RUNNING" == x"true" && x"$ALL_DEPS_RUNNING" == x"true" ]]; then break else sleep 1 @@ -144,34 +191,70 @@ wait() { # NOTE: This assumes Docker containers share the same names as their # corresponding services - /usr/bin/docker-wait-any ${SERVICE} ${PEER} + for dep in ${MULTI_INST_DEPENDENT}; do + if [[ ! -z $DEV ]]; then + ALL_DEPS="$ALL_DEPS ${dep}$DEV" + else + ALL_DEPS="$ALL_DEPS ${dep}" + fi + done + + if [[ ! -z $DEV ]]; then + /usr/bin/docker-wait-any -s ${SERVICE}$DEV -d ${PEER}$DEV ${ALL_DEPS} + else + /usr/bin/docker-wait-any -s ${SERVICE} -d ${PEER} ${ALL_DEPS} + 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}." - - /usr/bin/${SERVICE}.sh stop - debug "Stopped ${SERVICE} service..." + debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." + check_fast_boot + debug "Fast boot flag: ${SERVICE}$DEV ${FAST_BOOT}." + + # For WARM/FAST boot do not perform service stop + if [[ x"$WARM_BOOT" != x"true" ]] && [[ x"$FAST_BOOT" != x"true" ]]; then + /usr/bin/${SERVICE}.sh stop $DEV + debug "Stopped ${SERVICE}$DEV service..." + else + debug "Killing Docker swss..." + /usr/bin/docker kill swss &> /dev/null || debug "Docker swss is not running ($?) ..." + fi # Flush FAST_REBOOT table when swss needs to stop. The only # time when this would take effect is when fast-reboot # encountered error, e.g. syncd crashed. And swss needs to # be restarted. - debug "Clearing FAST_REBOOT flag..." - clean_up_tables STATE_DB "'FAST_REBOOT*'" - + if [[ x"$FAST_BOOT" != x"true" ]]; then + debug "Clearing FAST_REBOOT flag..." + clean_up_tables STATE_DB "'FAST_REBOOT*'" + fi # Unlock has to happen before reaching out to peer service unlock_service_state_change stop_peer_and_dependent_services } +DEV=$2 + +SERVICE="swss" +PEER="syncd" +DEBUGLOG="/tmp/swss-syncd-debug$DEV.log" +LOCKFILE="/tmp/swss-syncd-lock$DEV" +NAMESPACE_PREFIX="asic" +if [ "$DEV" ]; then + NET_NS="$NAMESPACE_PREFIX$DEV" #name of the network namespace + SONIC_DB_CLI="sonic-db-cli -n $NET_NS" +else + NET_NS="" + SONIC_DB_CLI="sonic-db-cli" +fi + case "$1" in start|wait|stop) $1 diff --git a/files/scripts/syncd.sh b/files/scripts/syncd.sh index 4b47e7ad4c45..95c3e3841ba8 100755 --- a/files/scripts/syncd.sh +++ b/files/scripts/syncd.sh @@ -1,98 +1,8 @@ #!/bin/bash -SERVICE="syncd" -PEER="swss" -DEBUGLOG="/tmp/swss-syncd-debug.log" -LOCKFILE="/tmp/swss-syncd-lock" - -function debug() -{ - /usr/bin/logger $1 - /bin/echo `date` "- $1" >> ${DEBUGLOG} -} - -function lock_service_state_change() -{ - 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} service" -} - -function unlock_service_state_change() -{ - debug "Unlocking ${LOCKFILE} (${LOCKFD}) from ${SERVICE} 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 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" - else - WARM_BOOT="false" - fi -} - -function wait_for_database_service() -{ - # Wait for redis server start before database clean - /usr/bin/docker exec database ping_pong_db_insts - - # Wait for configDB initialization - until [[ $(sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; - do sleep 1; - done -} - -function getBootType() -{ - # same code snippet in files/build_templates/docker_image_ctl.j2 - case "$(cat /proc/cmdline)" in - *SONIC_BOOT_TYPE=warm*) - TYPE='warm' - ;; - *SONIC_BOOT_TYPE=fastfast*) - TYPE='fastfast' - ;; - *SONIC_BOOT_TYPE=fast*|*fast-reboot*) - # check that the key exists - if [[ $(sonic-db-cli STATE_DB GET "FAST_REBOOT|system") == "1" ]]; then - TYPE='fast' - else - TYPE='cold' - fi - ;; - *) - TYPE='cold' - esac - echo "${TYPE}" -} +. /usr/local/bin/syncd_common.sh -start() { - debug "Starting ${SERVICE} service..." - - lock_service_state_change - - mkdir -p /host/warmboot - - wait_for_database_service - check_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. - touch /host/warmboot/warm-starting - else - rm -f /host/warmboot/warm-starting - fi +function startplatform() { # platform specific tasks @@ -111,13 +21,11 @@ start() { fi fi - if [[ x"$BOOT_TYPE" == x"fast" ]]; then - /usr/bin/hw-management.sh chipupdis - fi - - /usr/bin/mst start + debug "Starting Firmware update procedure" + /usr/bin/mst start --with_i2cdev /usr/bin/mlnx-fw-upgrade.sh /etc/init.d/sxdkernel start + debug "Firmware update procedure ended" fi if [[ x"$WARM_BOOT" != x"true" ]]; then @@ -125,35 +33,18 @@ start() { /etc/init.d/xpnet.sh start fi fi - - # start service docker - /usr/bin/${SERVICE}.sh start - debug "Started ${SERVICE} service..." - - unlock_service_state_change } -wait() { +function waitplatform() { + if [[ x"$sonic_asic_platform" == x"mellanox" ]]; then debug "Starting pmon service..." /bin/systemctl start pmon debug "Started pmon service" fi - /usr/bin/${SERVICE}.sh wait } -stop() { - debug "Stopping ${SERVICE} service..." - - lock_service_state_change - check_warm_boot - debug "Warm boot flag: ${SERVICE} ${WARM_BOOT}." - - if [[ x"$WARM_BOOT" == x"true" ]]; then - TYPE=warm - else - TYPE=cold - fi +function stopplatform1() { if [[ x$sonic_asic_platform == x"mellanox" ]] && [[ x$TYPE == x"cold" ]]; then debug "Stopping pmon service ahead of syncd..." @@ -163,20 +54,29 @@ 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} - - # wait until syncd quits gracefully - while docker top syncd | grep -q /usr/bin/syncd; do + /usr/bin/docker exec -i syncd$DEV /usr/bin/syncd_request_shutdown --${TYPE} + + # wait until syncd quits gracefully or force syncd to exit after + # waiting for 20 seconds + start_in_secs=${SECONDS} + end_in_secs=${SECONDS} + timer_threshold=20 + while docker top syncd$DEV | grep -q /usr/bin/syncd \ + && [[ $((end_in_secs - start_in_secs)) -le $timer_threshold ]]; do sleep 0.1 + end_in_secs=${SECONDS} done - /usr/bin/docker exec -i syncd /bin/sync + if [[ $((end_in_secs - start_in_secs)) -gt $timer_threshold ]]; then + debug "syncd process in container syncd$DEV did not exit gracefully" + fi + + /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..." - +function stopplatform2() { # platform specific tasks if [[ x"$WARM_BOOT" != x"true" ]]; then @@ -188,10 +88,24 @@ stop() { /etc/init.d/xpnet.sh start fi fi - - 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" +NAMESPACE_PREFIX="asic" +if [ "$DEV" ]; then + NET_NS="$NAMESPACE_PREFIX$DEV" #name of the network namespace + SONIC_DB_CLI="sonic-db-cli -n $NET_NS" +else + NET_NS="" + SONIC_DB_CLI="sonic-db-cli" +fi + case "$1" in start|wait|stop) $1 diff --git a/files/scripts/syncd_common.sh b/files/scripts/syncd_common.sh new file mode 100755 index 000000000000..0e9fc8ac2d7a --- /dev/null +++ b/files/scripts/syncd_common.sh @@ -0,0 +1,141 @@ +#!/bin/bash + +# +# common functions used by "syncd" scipts (syncd.sh, gbsyncd.sh, etc..) +# scripts using this must provide implementations of the following functions: +# +# startplatform +# waitplatform +# stopplatform1 and stopplatform2 +# +# For examples of these, see gbsyncd.sh and syncd.sh. +# + +function debug() +{ + /usr/bin/logger $1 + /bin/echo `date` "- $1" >> ${DEBUGLOG} +} + +function lock_service_state_change() +{ + 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}$DEV service" +} + +function unlock_service_state_change() +{ + 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 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" + else + WARM_BOOT="false" + fi +} + +function wait_for_database_service() +{ + # Wait for redis server start before database clean + until [[ $($SONIC_DB_CLI PING | grep -c PONG) -gt 0 ]]; do + sleep 1; + done + + # Wait for configDB initialization + until [[ $($SONIC_DB_CLI CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; + do sleep 1; + done +} + +function getBootType() +{ + # same code snippet in files/build_templates/docker_image_ctl.j2 + case "$(cat /proc/cmdline)" in + *SONIC_BOOT_TYPE=warm*) + TYPE='warm' + ;; + *SONIC_BOOT_TYPE=fastfast*) + TYPE='fastfast' + ;; + *SONIC_BOOT_TYPE=fast*|*fast-reboot*) + # check that the key exists + if [[ $($SONIC_DB_CLI STATE_DB GET "FAST_REBOOT|system") == "1" ]]; then + TYPE='fast' + else + TYPE='cold' + fi + ;; + *) + TYPE='cold' + esac + echo "${TYPE}" +} + +start() { + debug "Starting ${SERVICE}$DEV service..." + + lock_service_state_change + + mkdir -p /host/warmboot + + wait_for_database_service + check_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. + touch /host/warmboot/warm-starting + else + rm -f /host/warmboot/warm-starting + fi + + startplatform + + # start service docker + /usr/bin/${SERVICE}.sh start $DEV + debug "Started ${SERVICE} service..." + + unlock_service_state_change +} + +wait() { + waitplatform + + /usr/bin/${SERVICE}.sh wait $DEV +} + +stop() { + debug "Stopping ${SERVICE}$DEV service..." + + lock_service_state_change + check_warm_boot + debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." + + if [[ x"$WARM_BOOT" == x"true" ]]; then + TYPE=warm + else + TYPE=cold + fi + + stopplatform1 + + /usr/bin/${SERVICE}.sh stop $DEV + debug "Stopped ${SERVICE}$DEV service..." + + stopplatform2 + + unlock_service_state_change +} diff --git a/files/scripts/teamd.sh b/files/scripts/teamd.sh new file mode 100755 index 000000000000..626bb5186ca0 --- /dev/null +++ b/files/scripts/teamd.sh @@ -0,0 +1,108 @@ +#!/bin/bash + +function debug() +{ + /usr/bin/logger $1 + /bin/echo `date` "- $1" >> ${DEBUGLOG} +} + +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` + if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then + WARM_BOOT="true" + else + WARM_BOOT="false" + fi +} + +function validate_restore_count() +{ + if [[ x"$WARM_BOOT" == x"true" ]]; then + RESTORE_COUNT=`$SONIC_DB_CLI STATE_DB hget "WARM_RESTART_TABLE|${SERVICE}" restore_count` + # We have to make sure db data has not been flushed. + if [[ -z "$RESTORE_COUNT" ]]; then + WARM_BOOT="false" + fi + fi +} + +function check_fast_boot () +{ + if [[ $($SONIC_DB_CLI STATE_DB GET "FAST_REBOOT|system") == "1" ]]; then + FAST_BOOT="true" + else + FAST_BOOT="false" + fi +} + +start() { + debug "Starting ${SERVICE}$DEV service..." + + check_warm_boot + validate_restore_count + + check_fast_boot + + debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." + debug "Fast boot flag: ${SERVICE}$DEV ${Fast_BOOT}." + + # start service docker + /usr/bin/${SERVICE}.sh start $DEV + debug "Started ${SERVICE}$DEV service..." +} + +wait() { + /usr/bin/${SERVICE}.sh wait $DEV +} + +stop() { + debug "Stopping ${SERVICE}$DEV service..." + + check_warm_boot + check_fast_boot + debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." + debug "Fast boot flag: ${SERVICE}$DEV ${FAST_BOOT}." + + if [[ x"$WARM_BOOT" == x"true" ]]; then + # Send USR1 signal to all teamd instances to stop them + # It will prepare teamd for warm-reboot + # Note: We must send USR1 signal before syncd, because it will send the last packet through CPU port + docker exec -i ${SERVICE}$DEV pkill -USR1 ${SERVICE} > /dev/null || [ $? == 1 ] + elif [[ x"$FAST_BOOT" == x"true" ]]; then + # Kill teamd processes inside of teamd container with SIGUSR2 to allow them to send last LACP frames + # We call `docker kill teamd` to ensure the container stops as quickly as possible, + # Note: teamd must be killed before syncd, because it will send the last packet through CPU port + docker exec -i ${SERVICE}$DEV pkill -USR2 ${SERVICE} || [ $? == 1 ] + while docker exec -i ${SERVICE}$DEV pgrep ${SERVICE} > /dev/null; do + sleep 0.05 + done + docker kill ${SERVICE}$DEV &> /dev/null || debug "Docker ${SERVICE}$DEV is not running ($?) ..." + fi + + /usr/bin/${SERVICE}.sh stop $DEV + debug "Stopped ${SERVICE}$DEV service..." +} + +DEV=$2 + +SERVICE="teamd" +DEBUGLOG="/tmp/teamd-debug$DEV.log" +NAMESPACE_PREFIX="asic" +if [ "$DEV" ]; then + NET_NS="$NAMESPACE_PREFIX$DEV" #name of the network namespace + SONIC_DB_CLI="sonic-db-cli -n $NET_NS" +else + SONIC_DB_CLI="sonic-db-cli" +fi + +case "$1" in + start|wait|stop) + $1 + ;; + *) + echo "Usage: $0 {start|wait|stop}" + exit 1 + ;; +esac diff --git a/files/scripts/update_chassisdb_config b/files/scripts/update_chassisdb_config new file mode 100755 index 000000000000..292b1df719d9 --- /dev/null +++ b/files/scripts/update_chassisdb_config @@ -0,0 +1,71 @@ +#!/usr/bin/python3 + +import argparse +import json +import os +import syslog + +database_config_file = "/var/run/redis/sonic-db/database_config.json" +redis_chassis = 'redis_chassis' +chassis_db_list = ['CHASSIS_APP_DB', 'CHASSIS_STATE_DB'] + + +def main(): + parser = argparse.ArgumentParser(description="Update chassis_db config from database-config.json") + parser.add_argument("-j", "--json", help="databse-config json file", nargs='?', + const=database_config_file) + parser.add_argument("-p", "--port", help="update port number", nargs='?') + group = parser.add_mutually_exclusive_group() + group.add_argument("-k", "--keep", help="keep configuration", action='store_true') + group.add_argument("-d", "--delete", help="delete configuration", action='store_true') + + args = parser.parse_args() + jsonfile = "" + if args.json != None: + jsonfile = args.json + else: + return + if args.port != None: + port_number = args.port + else: + port_number = "" + if args.keep: + keep_config = True + else: + keep_config = False + if args.delete: + delete_config = True + else: + delete_config = False + data = {} + data_keep = {} + if os.path.isfile(jsonfile): + with open(jsonfile, "r") as read_file: + data = json.load(read_file) + else: + syslog.syslog(syslog.LOG_ERR, + 'config file {} does notexist'.format(jsonfile)) + return + if 'INSTANCES' in data and redis_chassis in data['INSTANCES']: + data_keep['INSTANCES'] = {} + data_keep['INSTANCES'][redis_chassis] = data['INSTANCES'][redis_chassis] + if delete_config: + del data['INSTANCES'][redis_chassis] + for chassis_db in chassis_db_list: + if 'DATABASES' in data and chassis_db in data['DATABASES']: + data_keep['DATABASES'] = {} + data_keep['DATABASES'][chassis_db] = data['DATABASES'][chassis_db] + if delete_config: + del data['DATABASES'][chassis_db] + + with open(jsonfile, "w") as write_file: + data_publish = data_keep if keep_config else data + if port_number: + data_publish['INSTANCES']['redis_chassis']['port'] = int(port_number) + json.dump(data_publish, write_file, indent=4, separators=(',', ': ')) + syslog.syslog(syslog.LOG_INFO, + 'remove chassis_db from config file {}'.format(jsonfile)) + + +if __name__ == "__main__": + main() diff --git a/files/sshd/sshd.service b/files/sshd/sshd.service index d79c574da516..25d524171c6f 100644 --- a/files/sshd/sshd.service +++ b/files/sshd/sshd.service @@ -10,6 +10,8 @@ ExecStart=/usr/sbin/sshd -D $SSHD_OPTS ExecReload=/bin/kill -HUP $MAINPID KillMode=process Restart=on-failure +RuntimeDirectory=sshd +RuntimeDirectoryMode=0755 [Install] WantedBy=multi-user.target diff --git a/installer/x86_64/install.sh b/installer/x86_64/install.sh index d0aa7818df9b..a21054db3689 100755 --- a/installer/x86_64/install.sh +++ b/installer/x86_64/install.sh @@ -20,6 +20,26 @@ _trap_push() { } _trap_push true +read_conf_file() { + local conf_file=$1 + while IFS='=' read -r var value || [ -n "$var" ] + do + # remove newline character + var=$(echo $var | tr -d '\r\n') + value=$(echo $value | tr -d '\r\n') + # remove comment string + var=${var%#*} + value=${value%#*} + # skip blank line + [ -z "$var" ] && continue + # remove double quote in the beginning + tmp_val=${value#\"} + # remove double quote in the end + value=${tmp_val%\"} + eval "$var=\"$value\"" + done < "$conf_file" +} + # Main set -e cd $(dirname $0) @@ -37,7 +57,7 @@ else fi if [ -r ./machine.conf ]; then -. ./machine.conf + read_conf_file "./machine.conf" fi if [ -r ./onie-image.conf ]; then @@ -54,9 +74,9 @@ fi # get running machine from conf file if [ -r /etc/machine.conf ]; then - . /etc/machine.conf + read_conf_file "/etc/machine.conf" elif [ -r /host/machine.conf ]; then - . /host/machine.conf + read_conf_file "/host/machine.conf" elif [ "$install_env" != "build" ]; then echo "cannot find machine.conf" exit 1 @@ -106,6 +126,11 @@ fi if [ "$install_env" != "build" ]; then onie_dev=$(blkid | grep ONIE-BOOT | head -n 1 | awk '{print $1}' | sed -e 's/:.*$//') blk_dev=$(echo $onie_dev | sed -e 's/[1-9][0-9]*$//' | sed -e 's/\([0-9]\)\(p\)/\1/') + + # check if we have an nvme device + blk_suffix= + echo $blk_dev | grep -q nvme0 && blk_suffix="p" + # Note: ONIE has no mount setting for / with device node, so below will be empty string cur_part=$(cat /proc/mounts | awk "{ if(\$2==\"/\") print \$1 }" | grep $blk_dev || true) @@ -225,7 +250,7 @@ create_demo_gpt_partition() echo "Partition #$demo_part is available" # Create new partition - echo "Creating new $demo_volume_label partition ${blk_dev}$demo_part ..." + echo "Creating new $demo_volume_label partition ${blk_dev}${blk_suffix}$demo_part ..." if [ "$demo_type" = "DIAG" ] ; then # set the GPT 'system partition' attribute bit for the DIAG @@ -424,6 +449,7 @@ image_dir="image-$image_version" if [ "$install_env" = "onie" ]; then eval $create_demo_partition $blk_dev demo_dev=$(echo $blk_dev | sed -e 's/\(mmcblk[0-9]\)/\1p/')$demo_part + echo $blk_dev | grep -q nvme0 && demo_dev=$(echo $blk_dev | sed -e 's/\(nvme[0-9]n[0-9]\)/\1p/')$demo_part # Make filesystem mkfs.ext4 -L $demo_volume_label $demo_dev @@ -535,8 +561,17 @@ trap_push "rm $grub_cfg || true" [ -r ./platform.conf ] && . ./platform.conf +# Check if the CPU vendor is 'Intel' and disable c-states if True +CPUVENDOR=$(cat /proc/cpuinfo | grep -m 1 vendor_id | awk '{print $3}') +echo "Switch CPU vendor is: $CPUVENDOR" +if [[ $(echo $CPUVENDOR | grep -i "Intel") ]] ; then + CSTATES="intel_idle.max_cstate=0" +else + CSTATES="" +fi + DEFAULT_GRUB_SERIAL_COMMAND="serial --port=${CONSOLE_PORT} --speed=${CONSOLE_SPEED} --word=8 --parity=no --stop=1" -DEFAULT_GRUB_CMDLINE_LINUX="console=tty0 console=ttyS${CONSOLE_DEV},${CONSOLE_SPEED}n8 quiet" +DEFAULT_GRUB_CMDLINE_LINUX="console=tty0 console=ttyS${CONSOLE_DEV},${CONSOLE_SPEED}n8 quiet $CSTATES" GRUB_SERIAL_COMMAND=${GRUB_SERIAL_COMMAND:-"$DEFAULT_GRUB_SERIAL_COMMAND"} GRUB_CMDLINE_LINUX=${GRUB_CMDLINE_LINUX:-"$DEFAULT_GRUB_CMDLINE_LINUX"} export GRUB_SERIAL_COMMAND @@ -545,8 +580,8 @@ export GRUB_CMDLINE_LINUX # Add common configuration, like the timeout and serial console. cat < $grub_cfg $GRUB_SERIAL_COMMAND -terminal_input serial -terminal_output serial +terminal_input console serial +terminal_output console serial set timeout=5 @@ -583,19 +618,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 @@ -606,12 +644,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-11-2-amd64 root=$grub_cfg_root rw $GRUB_CMDLINE_LINUX \ + linux /$image_dir/boot/vmlinuz-4.19.0-12-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-11-2-amd64 + initrd /$image_dir/boot/initrd.img-4.19.0-12-2-amd64 } EOF diff --git a/installer/x86_64/tests/sample_machine.conf b/installer/x86_64/tests/sample_machine.conf new file mode 100644 index 000000000000..a8028cc6d8d2 --- /dev/null +++ b/installer/x86_64/tests/sample_machine.conf @@ -0,0 +1,16 @@ +# sample_machine.conf for onie + # A space in front of comment line +# One blank line below + +onie_machine_rev=0 +onie_arch=x86_64# some comment after declaration +# no value declaration +onie_config_version= +onie_build_date="2021-02-03T01:50+0800" +onie_partition_type=gpt +onie_disco_ntpsrv=192.168.0.1 192.168.0.2 +onie_firmware=auto +# another blank line below + +onie_skip_ethmgmt_macs=no +onie_grub_image_name=grubx64.efi \ No newline at end of file diff --git a/installer/x86_64/tests/test_read_conf.sh b/installer/x86_64/tests/test_read_conf.sh new file mode 100644 index 000000000000..06b7fc145eab --- /dev/null +++ b/installer/x86_64/tests/test_read_conf.sh @@ -0,0 +1,61 @@ +#!/bin/sh +# This is a standalone test file to test read_conf_file function for +# some types of machine.conf file. +# The read_conf_file function is copy from the install.sh + +MACHINE_CONF="sample_machine.conf" + +read_conf_file() { + local conf_file=$1 + while IFS='=' read -r var value || [ -n "$var" ] + do + # remove newline character + var=$(echo $var | tr -d '\r\n') + value=$(echo $value | tr -d '\r\n') + # remove comment string + var=${var%#*} + value=${value%#*} + # skip blank line + [ -z "$var" ] && continue + # remove double quote in the beginning + tmp_val=${value#\"} + # remove double quote in the end + value=${tmp_val%\"} + eval "$var=\"$value\"" + done < "$conf_file" +} + +TEST_CONF() { + input_value=$1 + exp_value=$2 + if [ "$input_value" != "$exp_value" ]; then + echo "[ERR] Expect value($exp_value) is not equal to input value($input_value)" + exit 1 + fi +} + +# define the expected variable value +exp_onie_machine_rev="0" +exp_onie_arch="x86_64" +exp_onie_build_date="2021-02-03T01:50+0800" +exp_onie_partition_type="gpt" +exp_onie_disco_ntpsrv="192.168.0.1 192.168.0.2" +exp_onie_firmware="auto" +exp_onie_skip_ethmgmt_macs="no" +exp_onie_grub_image_name="grubx64.efi" + +# read the sample conf file +read_conf_file $MACHINE_CONF + +# check each variable and its expected value +TEST_CONF "$onie_machine_rev" "$exp_onie_machine_rev" +TEST_CONF "$onie_arch" "$exp_onie_arch" +TEST_CONF "$onie_build_date" "$exp_onie_build_date" +TEST_CONF "$onie_partition_type" "$exp_onie_partition_type" +TEST_CONF "$onie_disco_ntpsrv" "$exp_onie_disco_ntpsrv" +TEST_CONF "$onie_firmware" "$exp_onie_firmware" +TEST_CONF "$onie_skip_ethmgmt_macs" "$exp_onie_skip_ethmgmt_macs" +TEST_CONF "$onie_grub_image_name" "$exp_onie_grub_image_name" + +echo "PASS!!" +exit 0 \ No newline at end of file diff --git a/onie-image-arm64.conf b/onie-image-arm64.conf index 2bbadb3aeac4..ff280207e192 100644 --- a/onie-image-arm64.conf +++ b/onie-image-arm64.conf @@ -18,14 +18,14 @@ FILESYSTEM_SQUASHFS=fs.squashfs ## Filename for onie installer payload, will be the main part of onie installer ONIE_INSTALLER_PAYLOAD=fs.zip -## Filename for docker file system +## Filename for docker file system FILESYSTEM_DOCKERFS=dockerfs.tar.gz ## docker directory on the root filesystem DOCKERFS_DIR=docker ## docker ramfs disk space -DOCKER_RAMFS_SIZE=900M +DOCKER_RAMFS_SIZE=1500M ## Output file name for onie installer OUTPUT_ONIE_IMAGE=target/sonic-$TARGET_MACHINE.bin @@ -34,7 +34,7 @@ OUTPUT_ONIE_IMAGE=target/sonic-$TARGET_MACHINE.bin OUTPUT_RAW_IMAGE=target/sonic-$TARGET_MACHINE.raw ## Raw image size in MB -RAW_IMAGE_DISK_SIZE=2048 +RAW_IMAGE_DISK_SIZE=3072 ## Output file name for kvm image OUTPUT_KVM_IMAGE=target/sonic-$TARGET_MACHINE.img diff --git a/onie-image-armhf.conf b/onie-image-armhf.conf index bbff03f64041..48fe793c768c 100644 --- a/onie-image-armhf.conf +++ b/onie-image-armhf.conf @@ -18,14 +18,14 @@ FILESYSTEM_SQUASHFS=fs.squashfs ## Filename for onie installer payload, will be the main part of onie installer ONIE_INSTALLER_PAYLOAD=fs.zip -## Filename for docker file system +## Filename for docker file system FILESYSTEM_DOCKERFS=dockerfs.tar.gz ## docker directory on the root filesystem DOCKERFS_DIR=docker ## docker ramfs disk space -DOCKER_RAMFS_SIZE=900M +DOCKER_RAMFS_SIZE=1500M ## Output file name for onie installer OUTPUT_ONIE_IMAGE=target/sonic-$TARGET_MACHINE.bin @@ -34,7 +34,7 @@ OUTPUT_ONIE_IMAGE=target/sonic-$TARGET_MACHINE.bin OUTPUT_RAW_IMAGE=target/sonic-$TARGET_MACHINE.raw ## Raw image size in MB -RAW_IMAGE_DISK_SIZE=2048 +RAW_IMAGE_DISK_SIZE=3072 ## Output file name for kvm image OUTPUT_KVM_IMAGE=target/sonic-$TARGET_MACHINE.img diff --git a/onie-image.conf b/onie-image.conf index 2ca0a68484e2..419095b24470 100644 --- a/onie-image.conf +++ b/onie-image.conf @@ -18,14 +18,14 @@ FILESYSTEM_SQUASHFS=fs.squashfs ## Filename for onie installer payload, will be the main part of onie installer ONIE_INSTALLER_PAYLOAD=fs.zip -## Filename for docker file system +## Filename for docker file system FILESYSTEM_DOCKERFS=dockerfs.tar.gz ## docker directory on the root filesystem DOCKERFS_DIR=docker ## docker ramfs disk space -DOCKER_RAMFS_SIZE=900M +DOCKER_RAMFS_SIZE=1500M ## Output file name for onie installer OUTPUT_ONIE_IMAGE=target/sonic-$TARGET_MACHINE.bin @@ -34,7 +34,7 @@ OUTPUT_ONIE_IMAGE=target/sonic-$TARGET_MACHINE.bin OUTPUT_RAW_IMAGE=target/sonic-$TARGET_MACHINE.raw ## Raw image size in MB -RAW_IMAGE_DISK_SIZE=2048 +RAW_IMAGE_DISK_SIZE=3072 ## Output file name for kvm image OUTPUT_KVM_IMAGE=target/sonic-$TARGET_MACHINE.img diff --git a/platform/barefoot/bfn-modules.mk b/platform/barefoot/bfn-modules.mk index 67b7fa924da1..46d504f56812 100644 --- a/platform/barefoot/bfn-modules.mk +++ b/platform/barefoot/bfn-modules.mk @@ -6,5 +6,3 @@ BFN_MODULE = bfn-modules_$(VERSION)_amd64.deb $(BFN_MODULE)_SRC_PATH = $(PLATFORM_PATH)/bfn-modules $(BFN_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) SONIC_DPKG_DEBS += $(BFN_MODULE) - -SONIC_STRETCH_DEBS += $(BFN_MODULE) diff --git a/platform/barefoot/bfn-modules/debian/control b/platform/barefoot/bfn-modules/debian/control index d6f7a991107d..be1f6cc0443a 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-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for bfn asic for mmap 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_ */ diff --git a/platform/barefoot/bfn-modules/modules/bf_tun.c b/platform/barefoot/bfn-modules/modules/bf_tun.c index 45913a681a9a..a20f5e4db585 100644 --- a/platform/barefoot/bfn-modules/modules/bf_tun.c +++ b/platform/barefoot/bfn-modules/modules/bf_tun.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -69,13 +70,21 @@ #include #include #include +#include #include #include #include +#include +#include +#include -#include +#include +#include -#define TUN_MINOR1 201 +#define BF_TUN_MINOR 201 + +static void tun_default_link_ksettings(struct net_device *dev, + struct ethtool_link_ksettings *cmd); /* Uncomment to enable debugging */ /* #define TUN_DEBUG 1 */ @@ -106,6 +115,9 @@ do { \ } while (0) #endif +#define TUN_HEADROOM 256 +#define TUN_RX_PAD (NET_IP_ALIGN + NET_SKB_PAD) + /* TUN device flags */ /* IFF_ATTACH_QUEUE is never stored in device flags, @@ -117,7 +129,8 @@ do { \ #define TUN_VNET_BE 0x40000000 #define TUN_FEATURES (IFF_NO_PI | IFF_ONE_QUEUE | IFF_VNET_HDR | \ - IFF_MULTI_QUEUE) + IFF_MULTI_QUEUE | IFF_NAPI | IFF_NAPI_FRAGS) + #define GOODCOPY_LEN 128 #define FLT_EXACT_COUNT 8 @@ -168,9 +181,14 @@ struct tun_file { u16 queue_index; unsigned int ifindex; }; + struct napi_struct napi; + bool napi_enabled; + bool napi_frags_enabled; + struct mutex napi_mutex; /* Protects access to the above napi */ struct list_head next; struct tun_struct *detached; - struct skb_array tx_array; + struct ptr_ring tx_ring; + struct xdp_rxq_info xdp_rxq; }; struct tun_flow_entry { @@ -185,6 +203,12 @@ struct tun_flow_entry { }; #define TUN_NUM_FLOW_ENTRIES 1024 +#define TUN_MASK_FLOW_ENTRIES (TUN_NUM_FLOW_ENTRIES - 1) + +struct tun_prog { + struct rcu_head rcu; + struct bpf_prog *prog; +}; /* Since the socket were moved to tun_file, to preserve the behavior of persist * device, socket filter, sndbuf and vnet header size were restore when the @@ -200,7 +224,7 @@ struct tun_struct { struct net_device *dev; netdev_features_t set_features; #define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \ - NETIF_F_TSO6|NETIF_F_UFO) + NETIF_F_TSO6) int align; int vnet_hdr_sz; @@ -220,9 +244,106 @@ struct tun_struct { struct list_head disabled; void *security; u32 flow_count; + u32 rx_batched; struct tun_pcpu_stats __percpu *pcpu_stats; + struct bpf_prog __rcu *xdp_prog; + struct tun_prog __rcu *steering_prog; + struct tun_prog __rcu *filter_prog; + struct ethtool_link_ksettings link_ksettings; }; +struct veth { + __be16 h_vlan_proto; + __be16 h_vlan_TCI; +}; + +bool tun_is_xdp_frame(void *ptr) +{ + return (unsigned long)ptr & TUN_XDP_FLAG; +} +EXPORT_SYMBOL(tun_is_xdp_frame); + +void *tun_xdp_to_ptr(void *ptr) +{ + return (void *)((unsigned long)ptr | TUN_XDP_FLAG); +} +EXPORT_SYMBOL(tun_xdp_to_ptr); + +void *tun_ptr_to_xdp(void *ptr) +{ + return (void *)((unsigned long)ptr & ~TUN_XDP_FLAG); +} +EXPORT_SYMBOL(tun_ptr_to_xdp); + +static int tun_napi_receive(struct napi_struct *napi, int budget) +{ + struct tun_file *tfile = container_of(napi, struct tun_file, napi); + struct sk_buff_head *queue = &tfile->sk.sk_write_queue; + struct sk_buff_head process_queue; + struct sk_buff *skb; + int received = 0; + + __skb_queue_head_init(&process_queue); + + spin_lock(&queue->lock); + skb_queue_splice_tail_init(queue, &process_queue); + spin_unlock(&queue->lock); + + while (received < budget && (skb = __skb_dequeue(&process_queue))) { + napi_gro_receive(napi, skb); + ++received; + } + + if (!skb_queue_empty(&process_queue)) { + spin_lock(&queue->lock); + skb_queue_splice(&process_queue, queue); + spin_unlock(&queue->lock); + } + + return received; +} + +static int tun_napi_poll(struct napi_struct *napi, int budget) +{ + unsigned int received; + + received = tun_napi_receive(napi, budget); + + if (received < budget) + napi_complete_done(napi, received); + + return received; +} + +static void tun_napi_init(struct tun_struct *tun, struct tun_file *tfile, + bool napi_en, bool napi_frags) +{ + tfile->napi_enabled = napi_en; + tfile->napi_frags_enabled = napi_en && napi_frags; + if (napi_en) { + netif_napi_add(tun->dev, &tfile->napi, tun_napi_poll, + NAPI_POLL_WEIGHT); + napi_enable(&tfile->napi); + } +} + +static void tun_napi_disable(struct tun_file *tfile) +{ + if (tfile->napi_enabled) + napi_disable(&tfile->napi); +} + +static void tun_napi_del(struct tun_file *tfile) +{ + if (tfile->napi_enabled) + netif_napi_del(&tfile->napi); +} + +static bool tun_napi_frags_enabled(const struct tun_file *tfile) +{ + return tfile->napi_frags_enabled; +} + #ifdef CONFIG_TUN_VNET_CROSS_LE static inline bool tun_legacy_is_little_endian(struct tun_struct *tun) { @@ -289,7 +410,7 @@ static inline __virtio16 cpu_to_tun16(struct tun_struct *tun, u16 val) static inline u32 tun_hashfn(u32 rxhash) { - return rxhash & 0x3ff; + return rxhash & TUN_MASK_FLOW_ENTRIES; } static struct tun_flow_entry *tun_flow_find(struct hlist_head *head, u32 rxhash) @@ -364,9 +485,9 @@ static void tun_flow_delete_by_queue(struct tun_struct *tun, u16 queue_index) spin_unlock_bh(&tun->lock); } -static void tun_flow_cleanup(unsigned long data) +static void tun_flow_cleanup(struct timer_list *t) { - struct tun_struct *tun = (struct tun_struct *)data; + struct tun_struct *tun = from_timer(tun, t, flow_gc_timer); unsigned long delay = tun->ageing_time; unsigned long next_timer = jiffies + delay; unsigned long count = 0; @@ -374,25 +495,28 @@ static void tun_flow_cleanup(unsigned long data) tun_debug(KERN_INFO, tun, "tun_flow_cleanup\n"); - spin_lock_bh(&tun->lock); + spin_lock(&tun->lock); for (i = 0; i < TUN_NUM_FLOW_ENTRIES; i++) { struct tun_flow_entry *e; struct hlist_node *n; hlist_for_each_entry_safe(e, n, &tun->flows[i], hash_link) { unsigned long this_timer; - count++; + this_timer = e->updated + delay; - if (time_before_eq(this_timer, jiffies)) + if (time_before_eq(this_timer, jiffies)) { tun_flow_delete(tun, e); - else if (time_before(this_timer, next_timer)) + continue; + } + count++; + if (time_before(this_timer, next_timer)) next_timer = this_timer; } } if (count) mod_timer(&tun->flow_gc_timer, round_jiffies_up(next_timer)); - spin_unlock_bh(&tun->lock); + spin_unlock(&tun->lock); } static void tun_flow_update(struct tun_struct *tun, u32 rxhash, @@ -410,11 +534,6 @@ static void tun_flow_update(struct tun_struct *tun, u32 rxhash, rcu_read_lock(); - /* We may get a very small possibility of OOO during switching, not - * worth to optimize.*/ - if (tun->numqueues == 1 || tfile->detached) - goto unlock; - e = tun_flow_find(head, rxhash); if (likely(e)) { /* TODO: keep queueing to old queue until it's empty? */ @@ -433,7 +552,6 @@ static void tun_flow_update(struct tun_struct *tun, u32 rxhash, spin_unlock_bh(&tun->lock); } -unlock: rcu_read_unlock(); } @@ -454,18 +572,15 @@ static inline void tun_flow_save_rps_rxhash(struct tun_flow_entry *e, u32 hash) * different rxq no. here. If we could not get rxhash, then we would * hope the rxq no. may help here. */ -static u16 tun_select_queue(struct net_device *dev, struct sk_buff *skb, - void *accel_priv, select_queue_fallback_t fallback) +static u16 tun_automq_select_queue(struct tun_struct *tun, struct sk_buff *skb) { - struct tun_struct *tun = netdev_priv(dev); struct tun_flow_entry *e; u32 txq = 0; u32 numqueues = 0; - rcu_read_lock(); - numqueues = ACCESS_ONCE(tun->numqueues); + numqueues = READ_ONCE(tun->numqueues); - txq = skb_get_hash(skb); + txq = __skb_get_hash_symmetric(skb); if (txq) { e = tun_flow_find(&tun->flows[tun_hashfn(txq)], txq); if (e) { @@ -480,10 +595,43 @@ static u16 tun_select_queue(struct net_device *dev, struct sk_buff *skb, txq -= numqueues; } - rcu_read_unlock(); return txq; } +static u16 tun_ebpf_select_queue(struct tun_struct *tun, struct sk_buff *skb) +{ + struct tun_prog *prog; + u32 numqueues; + u16 ret = 0; + + numqueues = READ_ONCE(tun->numqueues); + if (!numqueues) + return 0; + + prog = rcu_dereference(tun->steering_prog); + if (prog) + ret = bpf_prog_run_clear_cb(prog->prog, skb); + + return ret % numqueues; +} + +static u16 tun_select_queue(struct net_device *dev, struct sk_buff *skb, + struct net_device *sb_dev, + select_queue_fallback_t fallback) +{ + struct tun_struct *tun = netdev_priv(dev); + u16 ret; + + rcu_read_lock(); + if (rcu_dereference(tun->steering_prog)) + ret = tun_ebpf_select_queue(tun, skb); + else + ret = tun_automq_select_queue(tun, skb); + rcu_read_unlock(); + + return ret; +} + static inline bool tun_not_capable(struct tun_struct *tun) { const struct cred *cred = current_cred(); @@ -517,22 +665,29 @@ static struct tun_struct *tun_enable_queue(struct tun_file *tfile) return tun; } -static void tun_queue_purge(struct tun_file *tfile) +void tun_ptr_free(void *ptr) { - struct sk_buff *skb; - - while ((skb = skb_array_consume(&tfile->tx_array)) != NULL) - kfree_skb(skb); + if (!ptr) + return; + if (tun_is_xdp_frame(ptr)) { + struct xdp_frame *xdpf = tun_ptr_to_xdp(ptr); - skb_queue_purge(&tfile->sk.sk_error_queue); + xdp_return_frame(xdpf); + } else { + __skb_array_destroy_skb(ptr); + } } +EXPORT_SYMBOL_GPL(tun_ptr_free); -static void tun_cleanup_tx_array(struct tun_file *tfile) +static void tun_queue_purge(struct tun_file *tfile) { - if (tfile->tx_array.ring.queue) { - skb_array_cleanup(&tfile->tx_array); - memset(&tfile->tx_array, 0, sizeof(tfile->tx_array)); - } + void *ptr; + + while ((ptr = ptr_ring_consume(&tfile->tx_ring)) != NULL) + tun_ptr_free(ptr); + + skb_queue_purge(&tfile->sk.sk_write_queue); + skb_queue_purge(&tfile->sk.sk_error_queue); } static void __tun_detach(struct tun_file *tfile, bool clean) @@ -542,6 +697,11 @@ static void __tun_detach(struct tun_file *tfile, bool clean) tun = rtnl_dereference(tfile->tun); + if (tun && clean) { + tun_napi_disable(tfile); + tun_napi_del(tfile); + } + if (tun && !tfile->detached) { u16 index = tfile->queue_index; BUG_ON(index >= tun->numqueues); @@ -550,6 +710,8 @@ static void __tun_detach(struct tun_file *tfile, bool clean) tun->tfiles[tun->numqueues - 1]); ntfile = rtnl_dereference(tun->tfiles[index]); ntfile->queue_index = index; + rcu_assign_pointer(tun->tfiles[tun->numqueues - 1], + NULL); --tun->numqueues; if (clean) { @@ -576,15 +738,24 @@ static void __tun_detach(struct tun_file *tfile, bool clean) tun->dev->reg_state == NETREG_REGISTERED) unregister_netdevice(tun->dev); } - tun_cleanup_tx_array(tfile); + if (tun) + xdp_rxq_info_unreg(&tfile->xdp_rxq); + ptr_ring_cleanup(&tfile->tx_ring, tun_ptr_free); sock_put(&tfile->sk); } } static void tun_detach(struct tun_file *tfile, bool clean) { + struct tun_struct *tun; + struct net_device *dev; + rtnl_lock(); + tun = rtnl_dereference(tfile->tun); + dev = tun ? tun->dev : NULL; __tun_detach(tfile, clean); + if (dev) + netdev_state_change(dev); rtnl_unlock(); } @@ -597,6 +768,7 @@ static void tun_detach_all(struct net_device *dev) for (i = 0; i < n; i++) { tfile = rtnl_dereference(tun->tfiles[i]); BUG_ON(!tfile); + tun_napi_disable(tfile); tfile->socket.sk->sk_shutdown = RCV_SHUTDOWN; tfile->socket.sk->sk_data_ready(tfile->socket.sk); RCU_INIT_POINTER(tfile->tun, NULL); @@ -612,16 +784,17 @@ static void tun_detach_all(struct net_device *dev) synchronize_net(); for (i = 0; i < n; i++) { tfile = rtnl_dereference(tun->tfiles[i]); + tun_napi_del(tfile); /* Drop read queue */ tun_queue_purge(tfile); + xdp_rxq_info_unreg(&tfile->xdp_rxq); sock_put(&tfile->sk); - tun_cleanup_tx_array(tfile); } list_for_each_entry_safe(tfile, tmp, &tun->disabled, next) { tun_enable_queue(tfile); tun_queue_purge(tfile); + xdp_rxq_info_unreg(&tfile->xdp_rxq); sock_put(&tfile->sk); - tun_cleanup_tx_array(tfile); } BUG_ON(tun->numdisabled != 0); @@ -629,7 +802,8 @@ static void tun_detach_all(struct net_device *dev) module_put(THIS_MODULE); } -static int tun_attach(struct tun_struct *tun, struct file *file, bool skip_filter) +static int tun_attach(struct tun_struct *tun, struct file *file, + bool skip_filter, bool napi, bool napi_frags) { struct tun_file *tfile = file->private_data; struct net_device *dev = tun->dev; @@ -664,33 +838,60 @@ static int tun_attach(struct tun_struct *tun, struct file *file, bool skip_filte } if (!tfile->detached && - skb_array_init(&tfile->tx_array, dev->tx_queue_len, GFP_KERNEL)) { + ptr_ring_resize(&tfile->tx_ring, dev->tx_queue_len, + GFP_KERNEL, tun_ptr_free)) { err = -ENOMEM; goto out; } tfile->queue_index = tun->numqueues; tfile->socket.sk->sk_shutdown &= ~RCV_SHUTDOWN; - rcu_assign_pointer(tfile->tun, tun); - rcu_assign_pointer(tun->tfiles[tun->numqueues], tfile); - tun->numqueues++; - if (tfile->detached) + if (tfile->detached) { + /* Re-attach detached tfile, updating XDP queue_index */ + WARN_ON(!xdp_rxq_info_is_reg(&tfile->xdp_rxq)); + + if (tfile->xdp_rxq.queue_index != tfile->queue_index) + tfile->xdp_rxq.queue_index = tfile->queue_index; + } else { + /* Setup XDP RX-queue info, for new tfile getting attached */ + err = xdp_rxq_info_reg(&tfile->xdp_rxq, + tun->dev, tfile->queue_index); + if (err < 0) + goto out; + err = xdp_rxq_info_reg_mem_model(&tfile->xdp_rxq, + MEM_TYPE_PAGE_SHARED, NULL); + if (err < 0) { + xdp_rxq_info_unreg(&tfile->xdp_rxq); + goto out; + } + err = 0; + } + + if (tfile->detached) { tun_enable_queue(tfile); - else + } else { sock_hold(&tfile->sk); - - tun_set_real_num_queues(tun); + tun_napi_init(tun, tfile, napi, napi_frags); + } /* device is allowed to go away first, so no need to hold extra * refcnt. */ + /* Publish tfile->tun and tun->tfiles only after we've fully + * initialized tfile; otherwise we risk using half-initialized + * object. + */ + rcu_assign_pointer(tfile->tun, tun); + rcu_assign_pointer(tun->tfiles[tun->numqueues], tfile); + tun->numqueues++; + tun_set_real_num_queues(tun); out: return err; } -static struct tun_struct *__tun_get(struct tun_file *tfile) +static struct tun_struct *tun_get(struct tun_file *tfile) { struct tun_struct *tun; @@ -703,11 +904,6 @@ static struct tun_struct *__tun_get(struct tun_file *tfile) return tun; } -static struct tun_struct *tun_get(struct file *file) -{ - return __tun_get(file->private_data); -} - static void tun_put(struct tun_struct *tun) { dev_put(tun->dev); @@ -830,18 +1026,8 @@ static void tun_net_uninit(struct net_device *dev) /* Net device open. */ static int tun_net_open(struct net_device *dev) { - struct tun_struct *tun = netdev_priv(dev); - int i; - netif_tx_start_all_queues(dev); - for (i = 0; i < tun->numqueues; i++) { - struct tun_file *tfile; - - tfile = rtnl_dereference(tun->tfiles[i]); - tfile->socket.sk->sk_write_space(tfile->socket.sk); - } - return 0; } @@ -853,29 +1039,16 @@ static int tun_net_close(struct net_device *dev) } /* Net device start xmit */ -static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) +static void tun_automq_xmit(struct tun_struct *tun, struct sk_buff *skb) { - struct tun_struct *tun = netdev_priv(dev); - int txq = skb->queue_mapping; - struct tun_file *tfile; - u32 numqueues = 0; - - rcu_read_lock(); - tfile = rcu_dereference(tun->tfiles[txq]); - numqueues = ACCESS_ONCE(tun->numqueues); - - /* Drop packet if interface is not attached */ - if (txq >= numqueues) - goto drop; - #ifdef CONFIG_RPS - if (numqueues == 1 && static_key_false(&rps_needed)) { + if (tun->numqueues == 1 && static_key_false(&rps_needed)) { /* Select queue was not called for the skbuff, so we extract the * RPS hash and save it into the flow_table here. */ __u32 rxhash; - rxhash = skb_get_hash(skb); + rxhash = __skb_get_hash_symmetric(skb); if (rxhash) { struct tun_flow_entry *e; e = tun_flow_find(&tun->flows[tun_hashfn(rxhash)], @@ -885,6 +1058,37 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) } } #endif +} + +static unsigned int run_ebpf_filter(struct tun_struct *tun, + struct sk_buff *skb, + int len) +{ + struct tun_prog *prog = rcu_dereference(tun->filter_prog); + + if (prog) + len = bpf_prog_run_clear_cb(prog->prog, skb); + + return len; +} + +/* Net device start xmit */ +static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct tun_struct *tun = netdev_priv(dev); + int txq = skb->queue_mapping; + struct tun_file *tfile; + int len = skb->len; + + rcu_read_lock(); + tfile = rcu_dereference(tun->tfiles[txq]); + + /* Drop packet if interface is not attached */ + if (!tfile) + goto drop; + + if (!rcu_dereference(tun->steering_prog)) + tun_automq_xmit(tun, skb); tun_debug(KERN_INFO, tun, "tun_net_xmit %d\n", skb->len); @@ -900,14 +1104,11 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) sk_filter(tfile->socket.sk, skb)) goto drop; - /* Limit the number of packets queued by dividing txq length with the - * number of queues. - */ - if (skb_queue_len(&tfile->socket.sk->sk_receive_queue) * numqueues - >= dev->tx_queue_len) + len = run_ebpf_filter(tun, skb, len); + if (len == 0 || pskb_trim(skb, len)) goto drop; - if (unlikely(skb_orphan_frags(skb, GFP_ATOMIC))) + if (unlikely(skb_orphan_frags_rx(skb, GFP_ATOMIC))) goto drop; skb_tx_timestamp(skb); @@ -919,7 +1120,7 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) nf_reset(skb); - if (skb_array_produce(&tfile->tx_array, skb)) + if (ptr_ring_produce(&tfile->tx_ring, skb)) goto drop; /* Notify and wake up reader process */ @@ -947,18 +1148,6 @@ static void tun_net_mclist(struct net_device *dev) */ } -#define MIN_MTU 68 -#define MAX_MTU 65535 - -static int -tun_net_change_mtu(struct net_device *dev, int new_mtu) -{ - if (new_mtu < MIN_MTU || new_mtu + dev->hard_header_len > MAX_MTU) - return -EINVAL; - dev->mtu = new_mtu; - return 0; -} - static netdev_features_t tun_net_fix_features(struct net_device *dev, netdev_features_t features) { @@ -966,23 +1155,6 @@ static netdev_features_t tun_net_fix_features(struct net_device *dev, return (features & tun->set_features) | (features & ~TUN_USER_FEATURES); } -#ifdef CONFIG_NET_POLL_CONTROLLER -static void tun_poll_controller(struct net_device *dev) -{ - /* - * Tun only receives frames when: - * 1) the char device endpoint gets data from user space - * 2) the tun socket gets a sendmsg call from user space - * Since both of those are synchronous operations, we are guaranteed - * never to have pending data when we poll for it - * so there is nothing to do here but return. - * We need this though so netpoll recognizes us as an interface that - * supports polling, which enables bridge devices in virt setups to - * still use netconsole - */ - return; -} -#endif static void tun_set_headroom(struct net_device *dev, int new_hr) { @@ -994,7 +1166,7 @@ static void tun_set_headroom(struct net_device *dev, int new_hr) tun->align = new_hr; } -static struct rtnl_link_stats64 * +static void tun_net_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) { u32 rx_dropped = 0, tx_dropped = 0, rx_frame_errors = 0; @@ -1028,16 +1200,66 @@ tun_net_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) stats->rx_dropped = rx_dropped; stats->rx_frame_errors = rx_frame_errors; stats->tx_dropped = tx_dropped; - return stats; } -static int -tun_change_carrier(struct net_device *dev, bool new_carrier) { - if (new_carrier) - netif_carrier_on(dev); - else - netif_carrier_off(dev); - return 0; +static int tun_xdp_set(struct net_device *dev, struct bpf_prog *prog, + struct netlink_ext_ack *extack) +{ + struct tun_struct *tun = netdev_priv(dev); + struct bpf_prog *old_prog; + + old_prog = rtnl_dereference(tun->xdp_prog); + rcu_assign_pointer(tun->xdp_prog, prog); + if (old_prog) + bpf_prog_put(old_prog); + + return 0; +} + +static u32 tun_xdp_query(struct net_device *dev) +{ + struct tun_struct *tun = netdev_priv(dev); + const struct bpf_prog *xdp_prog; + + xdp_prog = rtnl_dereference(tun->xdp_prog); + if (xdp_prog) + return xdp_prog->aux->id; + + return 0; +} + +static int tun_xdp(struct net_device *dev, struct netdev_bpf *xdp) +{ + switch (xdp->command) { + case XDP_SETUP_PROG: + return tun_xdp_set(dev, xdp->prog, xdp->extack); + case XDP_QUERY_PROG: + xdp->prog_id = tun_xdp_query(dev); + return 0; + default: + return -EINVAL; + } +} + +static int tun_net_change_carrier(struct net_device *dev, bool new_carrier) +{ + if (new_carrier) { + netif_carrier_on(dev); + } else { + netif_carrier_off(dev); + } + return 0; +} + +#define MIN_MTU 68 +#define MAX_MTU 65535 + +static int tun_net_change_mtu(struct net_device *dev, int new_mtu) +{ + if (new_mtu < MIN_MTU || new_mtu + dev->hard_header_len > MAX_MTU) + return -EINVAL; + dev->mtu = new_mtu; + return 0; } static const struct net_device_ops tun_netdev_ops = { @@ -1045,35 +1267,99 @@ static const struct net_device_ops tun_netdev_ops = { .ndo_open = tun_net_open, .ndo_stop = tun_net_close, .ndo_start_xmit = tun_net_xmit, - .ndo_change_mtu = tun_net_change_mtu, .ndo_fix_features = tun_net_fix_features, .ndo_select_queue = tun_select_queue, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = tun_poll_controller, -#endif .ndo_set_rx_headroom = tun_set_headroom, .ndo_get_stats64 = tun_net_get_stats64, - .ndo_change_carrier = tun_change_carrier, + .ndo_change_carrier = tun_net_change_carrier, + .ndo_change_mtu = tun_net_change_mtu, }; +static void __tun_xdp_flush_tfile(struct tun_file *tfile) +{ + /* Notify and wake up reader process */ + if (tfile->flags & TUN_FASYNC) + kill_fasync(&tfile->fasync, SIGIO, POLL_IN); + tfile->socket.sk->sk_data_ready(tfile->socket.sk); +} + +static int tun_xdp_xmit(struct net_device *dev, int n, + struct xdp_frame **frames, u32 flags) +{ + struct tun_struct *tun = netdev_priv(dev); + struct tun_file *tfile; + u32 numqueues; + int drops = 0; + int cnt = n; + int i; + + if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK)) + return -EINVAL; + + rcu_read_lock(); + +resample: + numqueues = READ_ONCE(tun->numqueues); + if (!numqueues) { + rcu_read_unlock(); + return -ENXIO; /* Caller will free/return all frames */ + } + + tfile = rcu_dereference(tun->tfiles[smp_processor_id() % + numqueues]); + if (unlikely(!tfile)) + goto resample; + + spin_lock(&tfile->tx_ring.producer_lock); + for (i = 0; i < n; i++) { + struct xdp_frame *xdp = frames[i]; + /* Encode the XDP flag into lowest bit for consumer to differ + * XDP buffer from sk_buff. + */ + void *frame = tun_xdp_to_ptr(xdp); + + if (__ptr_ring_produce(&tfile->tx_ring, frame)) { + this_cpu_inc(tun->pcpu_stats->tx_dropped); + xdp_return_frame_rx_napi(xdp); + drops++; + } + } + spin_unlock(&tfile->tx_ring.producer_lock); + + if (flags & XDP_XMIT_FLUSH) + __tun_xdp_flush_tfile(tfile); + + rcu_read_unlock(); + return cnt - drops; +} + +static int tun_xdp_tx(struct net_device *dev, struct xdp_buff *xdp) +{ + struct xdp_frame *frame = convert_to_xdp_frame(xdp); + + if (unlikely(!frame)) + return -EOVERFLOW; + + return tun_xdp_xmit(dev, 1, &frame, XDP_XMIT_FLUSH); +} + static const struct net_device_ops tap_netdev_ops = { .ndo_uninit = tun_net_uninit, .ndo_open = tun_net_open, .ndo_stop = tun_net_close, .ndo_start_xmit = tun_net_xmit, - .ndo_change_mtu = tun_net_change_mtu, .ndo_fix_features = tun_net_fix_features, .ndo_set_rx_mode = tun_net_mclist, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, .ndo_select_queue = tun_select_queue, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = tun_poll_controller, -#endif .ndo_features_check = passthru_features_check, .ndo_set_rx_headroom = tun_set_headroom, .ndo_get_stats64 = tun_net_get_stats64, - .ndo_change_carrier = tun_change_carrier, + .ndo_bpf = tun_xdp, + .ndo_xdp_xmit = tun_xdp_xmit, + .ndo_change_carrier = tun_net_change_carrier, + .ndo_change_mtu = tun_net_change_mtu, }; static void tun_flow_init(struct tun_struct *tun) @@ -1084,7 +1370,7 @@ static void tun_flow_init(struct tun_struct *tun) INIT_HLIST_HEAD(&tun->flows[i]); tun->ageing_time = TUN_FLOW_EXPIRE; - setup_timer(&tun->flow_gc_timer, tun_flow_cleanup, (unsigned long)tun); + timer_setup(&tun->flow_gc_timer, tun_flow_cleanup, 0); mod_timer(&tun->flow_gc_timer, round_jiffies_up(jiffies + tun->ageing_time)); } @@ -1095,6 +1381,9 @@ static void tun_flow_uninit(struct tun_struct *tun) tun_flow_flush(tun); } +#define MIN_MTU 68 +#define MAX_MTU 65535 + /* Initialize net device. */ static void tun_net_init(struct net_device *dev) { @@ -1125,20 +1414,30 @@ static void tun_net_init(struct net_device *dev) break; } + + dev->min_mtu = MIN_MTU; + dev->max_mtu = MAX_MTU - dev->hard_header_len; +} + +static bool tun_sock_writeable(struct tun_struct *tun, struct tun_file *tfile) +{ + struct sock *sk = tfile->socket.sk; + + return (tun->dev->flags & IFF_UP) && sock_writeable(sk); } /* Character device part */ /* Poll */ -static unsigned int tun_chr_poll(struct file *file, poll_table *wait) +static __poll_t tun_chr_poll(struct file *file, poll_table *wait) { struct tun_file *tfile = file->private_data; - struct tun_struct *tun = __tun_get(tfile); + struct tun_struct *tun = tun_get(tfile); struct sock *sk; - unsigned int mask = 0; + __poll_t mask = 0; if (!tun) - return POLLERR; + return EPOLLERR; sk = tfile->socket.sk; @@ -1146,53 +1445,292 @@ static unsigned int tun_chr_poll(struct file *file, poll_table *wait) poll_wait(file, sk_sleep(sk), wait); - if (!skb_array_empty(&tfile->tx_array)) - mask |= POLLIN | POLLRDNORM; + if (!ptr_ring_empty(&tfile->tx_ring)) + mask |= EPOLLIN | EPOLLRDNORM; - if (tun->dev->flags & IFF_UP && - (sock_writeable(sk) || - (!test_and_set_bit(SOCKWQ_ASYNC_NOSPACE, &sk->sk_socket->flags) && - sock_writeable(sk)))) - mask |= POLLOUT | POLLWRNORM; + /* Make sure SOCKWQ_ASYNC_NOSPACE is set if not writable to + * guarantee EPOLLOUT to be raised by either here or + * tun_sock_write_space(). Then process could get notification + * after it writes to a down device and meets -EIO. + */ + if (tun_sock_writeable(tun, tfile) || + (!test_and_set_bit(SOCKWQ_ASYNC_NOSPACE, &sk->sk_socket->flags) && + tun_sock_writeable(tun, tfile))) + mask |= EPOLLOUT | EPOLLWRNORM; if (tun->dev->reg_state != NETREG_REGISTERED) - mask = POLLERR; + mask = EPOLLERR; tun_put(tun); return mask; } -/* prepad is the amount to reserve at front. len is length after that. - * linear is a hint as to how much to copy (usually headers). */ -static struct sk_buff *tun_alloc_skb(struct tun_file *tfile, - size_t prepad, size_t len, - size_t linear, int noblock) +static struct sk_buff *tun_napi_alloc_frags(struct tun_file *tfile, + size_t len, + const struct iov_iter *it) +{ + struct sk_buff *skb; + size_t linear; + int err; + int i; + + if (it->nr_segs > MAX_SKB_FRAGS + 1) + return ERR_PTR(-ENOMEM); + + local_bh_disable(); + skb = napi_get_frags(&tfile->napi); + local_bh_enable(); + if (!skb) + return ERR_PTR(-ENOMEM); + + linear = iov_iter_single_seg_count(it); + err = __skb_grow(skb, linear); + if (err) + goto free; + + skb->len = len; + skb->data_len = len - linear; + skb->truesize += skb->data_len; + + for (i = 1; i < it->nr_segs; i++) { + struct page_frag *pfrag = ¤t->task_frag; + size_t fragsz = it->iov[i].iov_len; + + if (fragsz == 0 || fragsz > PAGE_SIZE) { + err = -EINVAL; + goto free; + } + + if (!skb_page_frag_refill(fragsz, pfrag, GFP_KERNEL)) { + err = -ENOMEM; + goto free; + } + + skb_fill_page_desc(skb, i - 1, pfrag->page, + pfrag->offset, fragsz); + page_ref_inc(pfrag->page); + pfrag->offset += fragsz; + } + + return skb; +free: + /* frees skb and all frags allocated with napi_alloc_frag() */ + napi_free_frags(&tfile->napi); + return ERR_PTR(err); +} + +/* prepad is the amount to reserve at front. len is length after that. + * linear is a hint as to how much to copy (usually headers). */ +static struct sk_buff *tun_alloc_skb(struct tun_file *tfile, + size_t prepad, size_t len, + size_t linear, int noblock) +{ + struct sock *sk = tfile->socket.sk; + struct sk_buff *skb; + int err; + + /* Under a page? Don't bother with paged skb. */ + if (prepad + len < PAGE_SIZE || !linear) + linear = len; + + skb = sock_alloc_send_pskb(sk, prepad + linear, len - linear, noblock, + &err, 0); + if (!skb) + return ERR_PTR(err); + + skb_reserve(skb, prepad); + skb_put(skb, linear); + skb->data_len = len - linear; + skb->len += len - linear; + + return skb; +} + +static void tun_rx_batched(struct tun_struct *tun, struct tun_file *tfile, + struct sk_buff *skb, int more) +{ + struct sk_buff_head *queue = &tfile->sk.sk_write_queue; + struct sk_buff_head process_queue; + u32 rx_batched = tun->rx_batched; + bool rcv = false; + + if (!rx_batched || (!more && skb_queue_empty(queue))) { + local_bh_disable(); + skb_record_rx_queue(skb, tfile->queue_index); + netif_receive_skb(skb); + local_bh_enable(); + return; + } + + spin_lock(&queue->lock); + if (!more || skb_queue_len(queue) == rx_batched) { + __skb_queue_head_init(&process_queue); + skb_queue_splice_tail_init(queue, &process_queue); + rcv = true; + } else { + __skb_queue_tail(queue, skb); + } + spin_unlock(&queue->lock); + + if (rcv) { + struct sk_buff *nskb; + + local_bh_disable(); + while ((nskb = __skb_dequeue(&process_queue))) { + skb_record_rx_queue(nskb, tfile->queue_index); + netif_receive_skb(nskb); + } + skb_record_rx_queue(skb, tfile->queue_index); + netif_receive_skb(skb); + local_bh_enable(); + } +} + +static bool tun_can_build_skb(struct tun_struct *tun, struct tun_file *tfile, + int len, int noblock, bool zerocopy) +{ + if ((tun->flags & TUN_TYPE_MASK) != IFF_TAP) + return false; + + if (tfile->socket.sk->sk_sndbuf != INT_MAX) + return false; + + if (!noblock) + return false; + + if (zerocopy) + return false; + + if (SKB_DATA_ALIGN(len + TUN_RX_PAD) + + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) > PAGE_SIZE) + return false; + + return true; +} + +static struct sk_buff *tun_build_skb(struct tun_struct *tun, + struct tun_file *tfile, + struct iov_iter *from, + struct virtio_net_hdr *hdr, + int len, int *skb_xdp) { - struct sock *sk = tfile->socket.sk; + struct page_frag *alloc_frag = ¤t->task_frag; struct sk_buff *skb; - int err; + struct bpf_prog *xdp_prog; + int buflen = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); + unsigned int delta = 0; + char *buf; + size_t copied; + int err, pad = TUN_RX_PAD; - /* Under a page? Don't bother with paged skb. */ - if (prepad + len < PAGE_SIZE || !linear) - linear = len; + rcu_read_lock(); + xdp_prog = rcu_dereference(tun->xdp_prog); + if (xdp_prog) + pad += TUN_HEADROOM; + buflen += SKB_DATA_ALIGN(len + pad); + rcu_read_unlock(); - skb = sock_alloc_send_pskb(sk, prepad + linear, len - linear, noblock, - &err, 0); - if (!skb) - return ERR_PTR(err); + alloc_frag->offset = ALIGN((u64)alloc_frag->offset, SMP_CACHE_BYTES); + if (unlikely(!skb_page_frag_refill(buflen, alloc_frag, GFP_KERNEL))) + return ERR_PTR(-ENOMEM); - skb_reserve(skb, prepad); - skb_put(skb, linear); - skb->data_len = len - linear; - skb->len += len - linear; + buf = (char *)page_address(alloc_frag->page) + alloc_frag->offset; + copied = copy_page_from_iter(alloc_frag->page, + alloc_frag->offset + pad, + len, from); + if (copied != len) + return ERR_PTR(-EFAULT); + + /* There's a small window that XDP may be set after the check + * of xdp_prog above, this should be rare and for simplicity + * we do XDP on skb in case the headroom is not enough. + */ + if (hdr->gso_type || !xdp_prog) + *skb_xdp = 1; + else + *skb_xdp = 0; + + local_bh_disable(); + rcu_read_lock(); + xdp_prog = rcu_dereference(tun->xdp_prog); + if (xdp_prog && !*skb_xdp) { + struct xdp_buff xdp; + void *orig_data; + u32 act; + + xdp.data_hard_start = buf; + xdp.data = buf + pad; + xdp_set_data_meta_invalid(&xdp); + xdp.data_end = xdp.data + len; + xdp.rxq = &tfile->xdp_rxq; + orig_data = xdp.data; + act = bpf_prog_run_xdp(xdp_prog, &xdp); + + switch (act) { + case XDP_REDIRECT: + get_page(alloc_frag->page); + alloc_frag->offset += buflen; + err = xdp_do_redirect(tun->dev, &xdp, xdp_prog); + xdp_do_flush_map(); + if (err) + goto err_redirect; + rcu_read_unlock(); + local_bh_enable(); + return NULL; + case XDP_TX: + get_page(alloc_frag->page); + alloc_frag->offset += buflen; + if (tun_xdp_tx(tun->dev, &xdp) < 0) + goto err_redirect; + rcu_read_unlock(); + local_bh_enable(); + return NULL; + case XDP_PASS: + delta = orig_data - xdp.data; + len = xdp.data_end - xdp.data; + break; + default: + bpf_warn_invalid_xdp_action(act); + /* fall through */ + case XDP_ABORTED: + trace_xdp_exception(tun->dev, xdp_prog, act); + /* fall through */ + case XDP_DROP: + goto err_xdp; + } + } + + skb = build_skb(buf, buflen); + if (!skb) { + rcu_read_unlock(); + local_bh_enable(); + return ERR_PTR(-ENOMEM); + } + + skb_reserve(skb, pad - delta); + skb_put(skb, len); + skb_set_owner_w(skb, tfile->socket.sk); + get_page(alloc_frag->page); + alloc_frag->offset += buflen; + + rcu_read_unlock(); + local_bh_enable(); return skb; + +err_redirect: + put_page(alloc_frag->page); +err_xdp: + rcu_read_unlock(); + local_bh_enable(); + this_cpu_inc(tun->pcpu_stats->rx_dropped); + return NULL; } /* Get packet from user space buffer */ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, void *msg_control, struct iov_iter *from, - int noblock) + int noblock, bool more) { struct tun_pi pi = { 0, cpu_to_be16(ETH_P_IP) }; struct sk_buff *skb; @@ -1204,19 +1742,16 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, int copylen; bool zerocopy = false; int err; - u32 rxhash; - ssize_t n; - - if (!(tun->dev->flags & IFF_UP)) - return -EIO; + u32 rxhash = 0; + int skb_xdp = 1; + bool frags = tun_napi_frags_enabled(tfile); if (!(tun->flags & IFF_NO_PI)) { if (len < sizeof(pi)) return -EINVAL; len -= sizeof(pi); - n = copy_from_iter(&pi, sizeof(pi), from); - if (n != sizeof(pi)) + if (!copy_from_iter_full(&pi, sizeof(pi), from)) return -EFAULT; } @@ -1227,8 +1762,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, return -EINVAL; len -= vnet_hdr_sz; - n = copy_from_iter(&gso, sizeof(gso), from); - if (n != sizeof(gso)) + if (!copy_from_iter_full(&gso, sizeof(gso), from)) return -EFAULT; if ((gso.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && @@ -1265,36 +1799,75 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, zerocopy = true; } - if (!zerocopy) { - copylen = len; - if (tun16_to_cpu(tun, gso.hdr_len) > good_linear) - linear = good_linear; + if (!frags && tun_can_build_skb(tun, tfile, len, noblock, zerocopy)) { + /* For the packet that is not easy to be processed + * (e.g gso or jumbo packet), we will do it at after + * skb was created with generic XDP routine. + */ + skb = tun_build_skb(tun, tfile, from, &gso, len, &skb_xdp); + if (IS_ERR(skb)) { + this_cpu_inc(tun->pcpu_stats->rx_dropped); + return PTR_ERR(skb); + } + if (!skb) + return total_len; + } else { + if (!zerocopy) { + copylen = len; + if (tun16_to_cpu(tun, gso.hdr_len) > good_linear) + linear = good_linear; + else + linear = tun16_to_cpu(tun, gso.hdr_len); + } + + if (frags) { + mutex_lock(&tfile->napi_mutex); + skb = tun_napi_alloc_frags(tfile, copylen, from); + /* tun_napi_alloc_frags() enforces a layout for the skb. + * If zerocopy is enabled, then this layout will be + * overwritten by zerocopy_sg_from_iter(). + */ + zerocopy = false; + } else { + skb = tun_alloc_skb(tfile, align, copylen, linear, + noblock); + } + + if (IS_ERR(skb)) { + if (PTR_ERR(skb) != -EAGAIN) + this_cpu_inc(tun->pcpu_stats->rx_dropped); + if (frags) + mutex_unlock(&tfile->napi_mutex); + return PTR_ERR(skb); + } + + if (zerocopy) + err = zerocopy_sg_from_iter(skb, from); else - linear = tun16_to_cpu(tun, gso.hdr_len); - } + err = skb_copy_datagram_from_iter(skb, 0, from, len); - skb = tun_alloc_skb(tfile, align, copylen, linear, noblock); - if (IS_ERR(skb)) { - if (PTR_ERR(skb) != -EAGAIN) + if (err) { + err = -EFAULT; +drop: this_cpu_inc(tun->pcpu_stats->rx_dropped); - return PTR_ERR(skb); - } - - if (zerocopy) - err = zerocopy_sg_from_iter(skb, from); - else - err = skb_copy_datagram_from_iter(skb, 0, from, len); + kfree_skb(skb); + if (frags) { + tfile->napi.skb = NULL; + mutex_unlock(&tfile->napi_mutex); + } - if (err) { - this_cpu_inc(tun->pcpu_stats->rx_dropped); - kfree_skb(skb); - return -EFAULT; + return err; + } } - err = virtio_net_hdr_to_skb(skb, &gso, tun_is_little_endian(tun)); - if (err) { + if (virtio_net_hdr_to_skb(skb, &gso, tun_is_little_endian(tun))) { this_cpu_inc(tun->pcpu_stats->rx_frame_errors); kfree_skb(skb); + if (frags) { + tfile->napi.skb = NULL; + mutex_unlock(&tfile->napi_mutex); + } + return -EINVAL; } @@ -1322,7 +1895,8 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, skb->dev = tun->dev; break; case IFF_TAP: - skb->protocol = eth_type_trans(skb, tun->dev); + if (!frags) + skb->protocol = eth_type_trans(skb, tun->dev); break; } @@ -1339,8 +1913,76 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, skb_reset_network_header(skb); skb_probe_transport_header(skb, 0); - rxhash = skb_get_hash(skb); - netif_rx_ni(skb); + if (skb_xdp) { + struct bpf_prog *xdp_prog; + int ret; + + local_bh_disable(); + rcu_read_lock(); + xdp_prog = rcu_dereference(tun->xdp_prog); + if (xdp_prog) { + ret = do_xdp_generic(xdp_prog, skb); + if (ret != XDP_PASS) { + rcu_read_unlock(); + local_bh_enable(); + return total_len; + } + } + rcu_read_unlock(); + local_bh_enable(); + } + + /* Compute the costly rx hash only if needed for flow updates. + * We may get a very small possibility of OOO during switching, not + * worth to optimize. + */ + if (!rcu_access_pointer(tun->steering_prog) && tun->numqueues > 1 && + !tfile->detached) + rxhash = __skb_get_hash_symmetric(skb); + + rcu_read_lock(); + if (unlikely(!(tun->dev->flags & IFF_UP))) { + err = -EIO; + rcu_read_unlock(); + goto drop; + } + + if (frags) { + /* Exercise flow dissector code path. */ + u32 headlen = eth_get_headlen(skb->data, skb_headlen(skb)); + + if (unlikely(headlen > skb_headlen(skb))) { + this_cpu_inc(tun->pcpu_stats->rx_dropped); + napi_free_frags(&tfile->napi); + rcu_read_unlock(); + mutex_unlock(&tfile->napi_mutex); + WARN_ON(1); + return -ENOMEM; + } + + local_bh_disable(); + napi_gro_frags(&tfile->napi); + local_bh_enable(); + mutex_unlock(&tfile->napi_mutex); + } else if (tfile->napi_enabled) { + struct sk_buff_head *queue = &tfile->sk.sk_write_queue; + int queue_len; + + spin_lock_bh(&queue->lock); + __skb_queue_tail(queue, skb); + queue_len = skb_queue_len(queue); + spin_unlock(&queue->lock); + + if (!more || queue_len > NAPI_POLL_WEIGHT) + napi_schedule(&tfile->napi); + + local_bh_enable(); + } else if (!IS_ENABLED(CONFIG_4KSTACKS)) { + tun_rx_batched(tun, tfile, skb, more); + } else { + netif_rx_ni(skb); + } + rcu_read_unlock(); stats = get_cpu_ptr(tun->pcpu_stats); u64_stats_update_begin(&stats->syncp); @@ -1349,26 +1991,63 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, u64_stats_update_end(&stats->syncp); put_cpu_ptr(stats); - tun_flow_update(tun, rxhash, tfile); + if (rxhash) + tun_flow_update(tun, rxhash, tfile); + return total_len; } static ssize_t tun_chr_write_iter(struct kiocb *iocb, struct iov_iter *from) { struct file *file = iocb->ki_filp; - struct tun_struct *tun = tun_get(file); struct tun_file *tfile = file->private_data; + struct tun_struct *tun = tun_get(tfile); ssize_t result; if (!tun) return -EBADFD; - result = tun_get_user(tun, tfile, NULL, from, file->f_flags & O_NONBLOCK); + result = tun_get_user(tun, tfile, NULL, from, + file->f_flags & O_NONBLOCK, false); tun_put(tun); return result; } +static ssize_t tun_put_user_xdp(struct tun_struct *tun, + struct tun_file *tfile, + struct xdp_frame *xdp_frame, + struct iov_iter *iter) +{ + int vnet_hdr_sz = 0; + size_t size = xdp_frame->len; + struct tun_pcpu_stats *stats; + size_t ret; + + if (tun->flags & IFF_VNET_HDR) { + struct virtio_net_hdr gso = { 0 }; + + vnet_hdr_sz = READ_ONCE(tun->vnet_hdr_sz); + if (unlikely(iov_iter_count(iter) < vnet_hdr_sz)) + return -EINVAL; + if (unlikely(copy_to_iter(&gso, sizeof(gso), iter) != + sizeof(gso))) + return -EFAULT; + iov_iter_advance(iter, vnet_hdr_sz - sizeof(gso)); + } + + ret = copy_to_iter(xdp_frame->data, size, iter) + vnet_hdr_sz; + + stats = get_cpu_ptr(tun->pcpu_stats); + u64_stats_update_begin(&stats->syncp); + stats->tx_packets++; + stats->tx_bytes += ret; + u64_stats_update_end(&stats->syncp); + put_cpu_ptr(tun->pcpu_stats); + + return ret; +} + /* Put packet to the user space buffer */ static ssize_t tun_put_user(struct tun_struct *tun, struct tun_file *tfile, @@ -1405,15 +2084,14 @@ static ssize_t tun_put_user(struct tun_struct *tun, } if (vnet_hdr_sz) { - struct virtio_net_hdr gso = { 0 }; /* no info leak */ - int ret; + struct virtio_net_hdr gso; if (iov_iter_count(iter) < vnet_hdr_sz) return -EINVAL; - ret = virtio_net_hdr_from_skb(skb, &gso, - tun_is_little_endian(tun), true); - if (ret) { + if (virtio_net_hdr_from_skb(skb, &gso, + tun_is_little_endian(tun), true, + vlan_hlen)) { struct skb_shared_info *sinfo = skb_shinfo(skb); pr_err("unexpected GSO type: " "0x%x, gso_size %d, hdr_len %d\n", @@ -1435,10 +2113,7 @@ static ssize_t tun_put_user(struct tun_struct *tun, if (vlan_hlen) { int ret; - struct { - __be16 h_vlan_proto; - __be16 h_vlan_TCI; - } veth; + struct veth veth; veth.h_vlan_proto = skb->vlan_proto; veth.h_vlan_TCI = htons(skb_vlan_tag_get(skb)); @@ -1468,15 +2143,14 @@ static ssize_t tun_put_user(struct tun_struct *tun, return total; } -static struct sk_buff *tun_ring_recv(struct tun_file *tfile, int noblock, - int *err) +static void *tun_ring_recv(struct tun_file *tfile, int noblock, int *err) { DECLARE_WAITQUEUE(wait, current); - struct sk_buff *skb = NULL; + void *ptr = NULL; int error = 0; - skb = skb_array_consume(&tfile->tx_array); - if (skb) + ptr = ptr_ring_consume(&tfile->tx_ring); + if (ptr) goto out; if (noblock) { error = -EAGAIN; @@ -1484,11 +2158,11 @@ static struct sk_buff *tun_ring_recv(struct tun_file *tfile, int noblock, } add_wait_queue(&tfile->wq.wait, &wait); - current->state = TASK_INTERRUPTIBLE; while (1) { - skb = skb_array_consume(&tfile->tx_array); - if (skb) + set_current_state(TASK_INTERRUPTIBLE); + ptr = ptr_ring_consume(&tfile->tx_ring); + if (ptr) break; if (signal_pending(current)) { error = -ERESTARTSYS; @@ -1502,37 +2176,49 @@ static struct sk_buff *tun_ring_recv(struct tun_file *tfile, int noblock, schedule(); } - current->state = TASK_RUNNING; + __set_current_state(TASK_RUNNING); remove_wait_queue(&tfile->wq.wait, &wait); out: *err = error; - return skb; + return ptr; } static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile, struct iov_iter *to, - int noblock) + int noblock, void *ptr) { - struct sk_buff *skb; ssize_t ret; int err; tun_debug(KERN_INFO, tun, "tun_do_read\n"); - if (!iov_iter_count(to)) + if (!iov_iter_count(to)) { + tun_ptr_free(ptr); return 0; + } - /* Read frames from ring */ - skb = tun_ring_recv(tfile, noblock, &err); - if (!skb) - return err; + if (!ptr) { + /* Read frames from ring */ + ptr = tun_ring_recv(tfile, noblock, &err); + if (!ptr) + return err; + } - ret = tun_put_user(tun, tfile, skb, to); - if (unlikely(ret < 0)) - kfree_skb(skb); - else - consume_skb(skb); + if (tun_is_xdp_frame(ptr)) { + struct xdp_frame *xdpf = tun_ptr_to_xdp(ptr); + + ret = tun_put_user_xdp(tun, tfile, xdpf, to); + xdp_return_frame(xdpf); + } else { + struct sk_buff *skb = ptr; + + ret = tun_put_user(tun, tfile, skb, to); + if (unlikely(ret < 0)) + kfree_skb(skb); + else + consume_skb(skb); + } return ret; } @@ -1541,12 +2227,12 @@ static ssize_t tun_chr_read_iter(struct kiocb *iocb, struct iov_iter *to) { struct file *file = iocb->ki_filp; struct tun_file *tfile = file->private_data; - struct tun_struct *tun = __tun_get(tfile); + struct tun_struct *tun = tun_get(tfile); ssize_t len = iov_iter_count(to), ret; if (!tun) return -EBADFD; - ret = tun_do_read(tun, tfile, to, file->f_flags & O_NONBLOCK); + ret = tun_do_read(tun, tfile, to, file->f_flags & O_NONBLOCK, NULL); ret = min_t(ssize_t, ret, len); if (ret > 0) iocb->ki_pos = ret; @@ -1554,6 +2240,39 @@ static ssize_t tun_chr_read_iter(struct kiocb *iocb, struct iov_iter *to) return ret; } +static void tun_prog_free(struct rcu_head *rcu) +{ + struct tun_prog *prog = container_of(rcu, struct tun_prog, rcu); + + bpf_prog_destroy(prog->prog); + kfree(prog); +} + +static int __tun_set_ebpf(struct tun_struct *tun, + struct tun_prog __rcu **prog_p, + struct bpf_prog *prog) +{ + struct tun_prog *old, *new = NULL; + + if (prog) { + new = kmalloc(sizeof(*new), GFP_KERNEL); + if (!new) + return -ENOMEM; + new->prog = prog; + } + + spin_lock_bh(&tun->lock); + old = rcu_dereference_protected(*prog_p, + lockdep_is_held(&tun->lock)); + rcu_assign_pointer(*prog_p, new); + spin_unlock_bh(&tun->lock); + + if (old) + call_rcu(&old->rcu, tun_prog_free); + + return 0; +} + static void tun_free_netdev(struct net_device *dev) { struct tun_struct *tun = netdev_priv(dev); @@ -1562,7 +2281,8 @@ static void tun_free_netdev(struct net_device *dev) free_percpu(tun->pcpu_stats); tun_flow_uninit(tun); security_tun_dev_free_security(tun->security); - free_netdev(dev); + __tun_set_ebpf(tun, &tun->steering_prog, NULL); + __tun_set_ebpf(tun, &tun->filter_prog, NULL); } static void tun_setup(struct net_device *dev) @@ -1571,9 +2291,11 @@ static void tun_setup(struct net_device *dev) tun->owner = INVALID_UID; tun->group = INVALID_GID; + tun_default_link_ksettings(dev, &tun->link_ksettings); dev->ethtool_ops = &tun_ethtool_ops; - dev->destructor = tun_free_netdev; + dev->needs_free_netdev = true; + dev->priv_destructor = tun_free_netdev; /* We prefer our own queue length */ dev->tx_queue_len = TUN_READQ_SIZE; } @@ -1581,9 +2303,66 @@ static void tun_setup(struct net_device *dev) /* Trivial set of netlink ops to allow deleting tun or tap * device with netlink. */ -static int tun_validate(struct nlattr *tb[], struct nlattr *data[]) +static int tun_validate(struct nlattr *tb[], struct nlattr *data[], + struct netlink_ext_ack *extack) { - return -EINVAL; + NL_SET_ERR_MSG(extack, + "tun/tap creation via rtnetlink is not supported."); + return -EOPNOTSUPP; +} + +static size_t tun_get_size(const struct net_device *dev) +{ + BUILD_BUG_ON(sizeof(u32) != sizeof(uid_t)); + BUILD_BUG_ON(sizeof(u32) != sizeof(gid_t)); + + return nla_total_size(sizeof(uid_t)) + /* OWNER */ + nla_total_size(sizeof(gid_t)) + /* GROUP */ + nla_total_size(sizeof(u8)) + /* TYPE */ + nla_total_size(sizeof(u8)) + /* PI */ + nla_total_size(sizeof(u8)) + /* VNET_HDR */ + nla_total_size(sizeof(u8)) + /* PERSIST */ + nla_total_size(sizeof(u8)) + /* MULTI_QUEUE */ + nla_total_size(sizeof(u32)) + /* NUM_QUEUES */ + nla_total_size(sizeof(u32)) + /* NUM_DISABLED_QUEUES */ + 0; +} + +static int tun_fill_info(struct sk_buff *skb, const struct net_device *dev) +{ + struct tun_struct *tun = netdev_priv(dev); + + if (nla_put_u8(skb, IFLA_TUN_TYPE, tun->flags & TUN_TYPE_MASK)) + goto nla_put_failure; + if (uid_valid(tun->owner) && + nla_put_u32(skb, IFLA_TUN_OWNER, + from_kuid_munged(current_user_ns(), tun->owner))) + goto nla_put_failure; + if (gid_valid(tun->group) && + nla_put_u32(skb, IFLA_TUN_GROUP, + from_kgid_munged(current_user_ns(), tun->group))) + goto nla_put_failure; + if (nla_put_u8(skb, IFLA_TUN_PI, !(tun->flags & IFF_NO_PI))) + goto nla_put_failure; + if (nla_put_u8(skb, IFLA_TUN_VNET_HDR, !!(tun->flags & IFF_VNET_HDR))) + goto nla_put_failure; + if (nla_put_u8(skb, IFLA_TUN_PERSIST, !!(tun->flags & IFF_PERSIST))) + goto nla_put_failure; + if (nla_put_u8(skb, IFLA_TUN_MULTI_QUEUE, + !!(tun->flags & IFF_MULTI_QUEUE))) + goto nla_put_failure; + if (tun->flags & IFF_MULTI_QUEUE) { + if (nla_put_u32(skb, IFLA_TUN_NUM_QUEUES, tun->numqueues)) + goto nla_put_failure; + if (nla_put_u32(skb, IFLA_TUN_NUM_DISABLED_QUEUES, + tun->numdisabled)) + goto nla_put_failure; + } + + return 0; + +nla_put_failure: + return -EMSGSIZE; } static struct rtnl_link_ops tun_link_ops __read_mostly = { @@ -1591,6 +2370,8 @@ static struct rtnl_link_ops tun_link_ops __read_mostly = { .priv_size = sizeof(struct tun_struct), .setup = tun_setup, .validate = tun_validate, + .get_size = tun_get_size, + .fill_info = tun_fill_info, }; static void tun_sock_write_space(struct sock *sk) @@ -1606,8 +2387,8 @@ static void tun_sock_write_space(struct sock *sk) wqueue = sk_sleep(sk); if (wqueue && waitqueue_active(wqueue)) - wake_up_interruptible_sync_poll(wqueue, POLLOUT | - POLLWRNORM | POLLWRBAND); + wake_up_interruptible_sync_poll(wqueue, EPOLLOUT | + EPOLLWRNORM | EPOLLWRBAND); tfile = container_of(sk, struct tun_file, sk); kill_fasync(&tfile->fasync, SIGIO, POLL_OUT); @@ -1617,13 +2398,14 @@ static int tun_sendmsg(struct socket *sock, struct msghdr *m, size_t total_len) { int ret; struct tun_file *tfile = container_of(sock, struct tun_file, socket); - struct tun_struct *tun = __tun_get(tfile); + struct tun_struct *tun = tun_get(tfile); if (!tun) return -EBADFD; ret = tun_get_user(tun, tfile, m->msg_control, &m->msg_iter, - m->msg_flags & MSG_DONTWAIT); + m->msg_flags & MSG_DONTWAIT, + m->msg_flags & MSG_MORE); tun_put(tun); return ret; } @@ -1632,22 +2414,25 @@ static int tun_recvmsg(struct socket *sock, struct msghdr *m, size_t total_len, int flags) { struct tun_file *tfile = container_of(sock, struct tun_file, socket); - struct tun_struct *tun = __tun_get(tfile); + struct tun_struct *tun = tun_get(tfile); + void *ptr = m->msg_control; int ret; - if (!tun) - return -EBADFD; + if (!tun) { + ret = -EBADFD; + goto out_free; + } if (flags & ~(MSG_DONTWAIT|MSG_TRUNC|MSG_ERRQUEUE)) { ret = -EINVAL; - goto out; + goto out_put_tun; } if (flags & MSG_ERRQUEUE) { ret = sock_recv_errqueue(sock->sk, m, total_len, SOL_PACKET, TUN_TX_TIMESTAMP); goto out; } - ret = tun_do_read(tun, tfile, &m->msg_iter, flags & MSG_DONTWAIT); + ret = tun_do_read(tun, tfile, &m->msg_iter, flags & MSG_DONTWAIT, ptr); if (ret > (ssize_t)total_len) { m->msg_flags |= MSG_TRUNC; ret = flags & MSG_TRUNC ? ret : total_len; @@ -1655,6 +2440,26 @@ static int tun_recvmsg(struct socket *sock, struct msghdr *m, size_t total_len, out: tun_put(tun); return ret; + +out_put_tun: + tun_put(tun); +out_free: + tun_ptr_free(ptr); + return ret; +} + +static int tun_ptr_peek_len(void *ptr) +{ + if (likely(ptr)) { + if (tun_is_xdp_frame(ptr)) { + struct xdp_frame *xdpf = tun_ptr_to_xdp(ptr); + + return xdpf->len; + } + return __skb_array_len_with_tag(ptr); + } else { + return 0; + } } static int tun_peek_len(struct socket *sock) @@ -1663,11 +2468,11 @@ static int tun_peek_len(struct socket *sock) struct tun_struct *tun; int ret = 0; - tun = __tun_get(tfile); + tun = tun_get(tfile); if (!tun) return 0; - ret = skb_array_peek_len(&tfile->tx_array); + ret = PTR_RING_PEEK_CALL(&tfile->tx_ring, tun_ptr_peek_len); tun_put(tun); return ret; @@ -1743,6 +2548,15 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) if (tfile->detached) return -EINVAL; + if ((ifr->ifr_flags & IFF_NAPI_FRAGS)) { + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + if (!(ifr->ifr_flags & IFF_NAPI) || + (ifr->ifr_flags & TUN_TYPE_MASK) != IFF_TAP) + return -EINVAL; + } + dev = __dev_get_by_name(net, ifr->ifr_name); if (dev) { if (ifr->ifr_flags & IFF_TUN_EXCL) @@ -1764,7 +2578,9 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) if (err < 0) return err; - err = tun_attach(tun, file, ifr->ifr_flags & IFF_NOFILTER); + err = tun_attach(tun, file, ifr->ifr_flags & IFF_NOFILTER, + ifr->ifr_flags & IFF_NAPI, + ifr->ifr_flags & IFF_NAPI_FRAGS); if (err < 0) return err; @@ -1773,10 +2589,15 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) /* One or more queue has already been attached, no need * to initialize the device again. */ + netdev_state_change(dev); return 0; } - } - else { + + tun->flags = (tun->flags & ~TUN_FEATURES) | + (ifr->ifr_flags & TUN_FEATURES); + + netdev_state_change(dev); + } else { char *name; unsigned long flags = 0; int queues = ifr->ifr_flags & IFF_MULTI_QUEUE ? @@ -1809,11 +2630,10 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) if (!dev) return -ENOMEM; -#if 0 err = dev_get_valid_name(net, dev, name); if (err < 0) goto err_free_dev; -#endif + dev_net_set(dev, net); dev->rtnl_link_ops = &tun_link_ops; dev->ifindex = tfile->ifindex; @@ -1828,6 +2648,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) tun->align = NET_SKB_PAD; tun->filter_attached = false; tun->sndbuf = tfile->socket.sk->sk_sndbuf; + tun->rx_batched = 0; + RCU_INIT_POINTER(tun->steering_prog, NULL); tun->pcpu_stats = netdev_alloc_pcpu_stats(struct tun_pcpu_stats); if (!tun->pcpu_stats) { @@ -1852,8 +2674,12 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) ~(NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX); + tun->flags = (tun->flags & ~TUN_FEATURES) | + (ifr->ifr_flags & TUN_FEATURES); + INIT_LIST_HEAD(&tun->disabled); - err = tun_attach(tun, file, false); + err = tun_attach(tun, file, false, ifr->ifr_flags & IFF_NAPI, + ifr->ifr_flags & IFF_NAPI_FRAGS); if (err < 0) goto err_free_flow; @@ -1866,9 +2692,6 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) tun_debug(KERN_INFO, tun, "tun_set_iff\n"); - tun->flags = (tun->flags & ~TUN_FEATURES) | - (ifr->ifr_flags & TUN_FEATURES); - /* Make sure persistent devices do not get stuck in * xoff state. */ @@ -1880,6 +2703,9 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) err_detach: tun_detach_all(dev); + /* register_netdevice() already called tun_free_netdev() */ + goto err_free_dev; + err_free_flow: tun_flow_uninit(tun); security_tun_dev_free_security(tun->security); @@ -1923,10 +2749,7 @@ static int set_offload(struct tun_struct *tun, unsigned long arg) arg &= ~(TUN_F_TSO4|TUN_F_TSO6); } - if (arg & TUN_F_UFO) { - features |= NETIF_F_UFO; - arg &= ~TUN_F_UFO; - } + arg &= ~TUN_F_UFO; } /* This gives the user a way to test for new features in future by @@ -1935,6 +2758,8 @@ static int set_offload(struct tun_struct *tun, unsigned long arg) return -EINVAL; tun->set_features = features; + tun->dev->wanted_features &= ~TUN_USER_FEATURES; + tun->dev->wanted_features |= features; netdev_update_features(tun->dev); return 0; @@ -2003,7 +2828,8 @@ static int tun_set_queue(struct file *file, struct ifreq *ifr) ret = security_tun_dev_attach_queue(tun->security); if (ret < 0) goto unlock; - ret = tun_attach(tun, file, false); + ret = tun_attach(tun, file, false, tun->flags & IFF_NAPI, + tun->flags & IFF_NAPI_FRAGS); } else if (ifr->ifr_flags & IFF_DETACH_QUEUE) { tun = rtnl_dereference(tfile->tun); if (!tun || !(tun->flags & IFF_MULTI_QUEUE) || tfile->detached) @@ -2013,15 +2839,39 @@ static int tun_set_queue(struct file *file, struct ifreq *ifr) } else ret = -EINVAL; + if (ret >= 0) + netdev_state_change(tun->dev); + unlock: rtnl_unlock(); return ret; } +static int tun_set_ebpf(struct tun_struct *tun, struct tun_prog **prog_p, + void __user *data) +{ + struct bpf_prog *prog; + int fd; + + if (copy_from_user(&fd, data, sizeof(fd))) + return -EFAULT; + + if (fd == -1) { + prog = NULL; + } else { + prog = bpf_prog_get_type(fd, BPF_PROG_TYPE_SOCKET_FILTER); + if (IS_ERR(prog)) + return PTR_ERR(prog); + } + + return __tun_set_ebpf(tun, prog_p, prog); +} + static long __tun_chr_ioctl(struct file *file, unsigned int cmd, unsigned long arg, int ifreq_len) { struct tun_file *tfile = file->private_data; + struct net *net = sock_net(&tfile->sk); struct tun_struct *tun; void __user* argp = (void __user*)arg; struct ifreq ifr; @@ -2032,8 +2882,10 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, unsigned int ifindex; int le; int ret; + bool do_notify = false; - if (cmd == TUNSETIFF || cmd == TUNSETQUEUE || _IOC_TYPE(cmd) == 0x89) { + if (cmd == TUNSETIFF || cmd == TUNSETQUEUE || + (_IOC_TYPE(cmd) == SOCK_IOC_TYPE && cmd != SIOCGSKNS)) { if (copy_from_user(&ifr, argp, ifreq_len)) return -EFAULT; } else { @@ -2046,17 +2898,26 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, */ return put_user(IFF_TUN | IFF_TAP | TUN_FEATURES, (unsigned int __user*)argp); - } else if (cmd == TUNSETQUEUE) + } else if (cmd == TUNSETQUEUE) { return tun_set_queue(file, &ifr); + } else if (cmd == SIOCGSKNS) { + if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) + return -EPERM; + return open_related_ns(&net->ns, get_net_ns); + } ret = 0; rtnl_lock(); - tun = __tun_get(tfile); - if (cmd == TUNSETIFF && !tun) { + tun = tun_get(tfile); + if (cmd == TUNSETIFF) { + ret = -EEXIST; + if (tun) + goto unlock; + ifr.ifr_name[IFNAMSIZ-1] = '\0'; - ret = tun_set_iff(sock_net(&tfile->sk), file, &ifr); + ret = tun_set_iff(net, file, &ifr); if (ret) goto unlock; @@ -2114,10 +2975,12 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, if (arg && !(tun->flags & IFF_PERSIST)) { tun->flags |= IFF_PERSIST; __module_get(THIS_MODULE); + do_notify = true; } if (!arg && (tun->flags & IFF_PERSIST)) { tun->flags &= ~IFF_PERSIST; module_put(THIS_MODULE); + do_notify = true; } tun_debug(KERN_INFO, tun, "persist %s\n", @@ -2132,6 +2995,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, break; } tun->owner = owner; + do_notify = true; tun_debug(KERN_INFO, tun, "owner set to %u\n", from_kuid(&init_user_ns, tun->owner)); break; @@ -2144,6 +3008,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, break; } tun->group = group; + do_notify = true; tun_debug(KERN_INFO, tun, "group set to %u\n", from_kgid(&init_user_ns, tun->group)); break; @@ -2290,11 +3155,22 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, ret = 0; break; + case TUNSETSTEERINGEBPF: + ret = tun_set_ebpf(tun, &tun->steering_prog, argp); + break; + + case TUNSETFILTEREBPF: + ret = tun_set_ebpf(tun, &tun->filter_prog, argp); + break; + default: ret = -EINVAL; break; } + if (do_notify) + netdev_state_change(tun->dev); + unlock: rtnl_unlock(); if (tun) @@ -2346,7 +3222,7 @@ static int tun_chr_fasync(int fd, struct file *file, int on) goto out; if (on) { - __f_setown(file, task_pid(current), PIDTYPE_PID, 0); + __f_setown(file, task_pid(current), PIDTYPE_TGID, 0); tfile->flags |= TUN_FASYNC; } else tfile->flags &= ~TUN_FASYNC; @@ -2366,6 +3242,12 @@ static int tun_chr_open(struct inode *inode, struct file * file) &tun_proto, 0); if (!tfile) return -ENOMEM; + if (ptr_ring_init(&tfile->tx_ring, 0, GFP_KERNEL)) { + sk_free(&tfile->sk); + return -ENOMEM; + } + + mutex_init(&tfile->napi_mutex); RCU_INIT_POINTER(tfile->tun, NULL); tfile->flags = 0; tfile->ifindex = 0; @@ -2386,8 +3268,6 @@ static int tun_chr_open(struct inode *inode, struct file * file) sock_set_flag(&tfile->sk, SOCK_ZEROCOPY); - memset(&tfile->tx_array, 0, sizeof(tfile->tx_array)); - return 0; } @@ -2401,15 +3281,16 @@ static int tun_chr_close(struct inode *inode, struct file *file) } #ifdef CONFIG_PROC_FS -static void tun_chr_show_fdinfo(struct seq_file *m, struct file *f) +static void tun_chr_show_fdinfo(struct seq_file *m, struct file *file) { + struct tun_file *tfile = file->private_data; struct tun_struct *tun; struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); rtnl_lock(); - tun = tun_get(f); + tun = tun_get(tfile); if (tun) tun_get_iff(current->nsproxy->net_ns, tun, &ifr); rtnl_unlock(); @@ -2440,7 +3321,7 @@ static const struct file_operations tun_fops = { }; static struct miscdevice tun_miscdev = { - .minor = TUN_MINOR1, + .minor = BF_TUN_MINOR, .name = "bf_tun", .nodename = "net/bf_tun", .fops = &tun_fops, @@ -2448,18 +3329,33 @@ static struct miscdevice tun_miscdev = { /* ethtool interface */ -static int tun_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - cmd->supported = 0; - cmd->advertising = 0; - ethtool_cmd_speed_set(cmd, SPEED_10); - cmd->duplex = DUPLEX_FULL; - cmd->port = PORT_TP; - cmd->phy_address = 0; - cmd->transceiver = XCVR_INTERNAL; - cmd->autoneg = AUTONEG_DISABLE; - cmd->maxtxpkt = 0; - cmd->maxrxpkt = 0; +static void tun_default_link_ksettings(struct net_device *dev, + struct ethtool_link_ksettings *cmd) +{ + ethtool_link_ksettings_zero_link_mode(cmd, supported); + ethtool_link_ksettings_zero_link_mode(cmd, advertising); + cmd->base.speed = SPEED_10; + cmd->base.duplex = DUPLEX_FULL; + cmd->base.port = PORT_TP; + cmd->base.phy_address = 0; + cmd->base.autoneg = AUTONEG_DISABLE; +} + +static int tun_get_link_ksettings(struct net_device *dev, + struct ethtool_link_ksettings *cmd) +{ + struct tun_struct *tun = netdev_priv(dev); + + memcpy(cmd, &tun->link_ksettings, sizeof(*cmd)); + return 0; +} + +static int tun_set_link_ksettings(struct net_device *dev, + const struct ethtool_link_ksettings *cmd) +{ + struct tun_struct *tun = netdev_priv(dev); + + memcpy(&tun->link_ksettings, cmd, sizeof(*cmd)); return 0; } @@ -2498,38 +3394,65 @@ static void tun_set_msglevel(struct net_device *dev, u32 value) #endif } +static int tun_get_coalesce(struct net_device *dev, + struct ethtool_coalesce *ec) +{ + struct tun_struct *tun = netdev_priv(dev); + + ec->rx_max_coalesced_frames = tun->rx_batched; + + return 0; +} + +static int tun_set_coalesce(struct net_device *dev, + struct ethtool_coalesce *ec) +{ + struct tun_struct *tun = netdev_priv(dev); + + if (ec->rx_max_coalesced_frames > NAPI_POLL_WEIGHT) + tun->rx_batched = NAPI_POLL_WEIGHT; + else + tun->rx_batched = ec->rx_max_coalesced_frames; + + return 0; +} + static const struct ethtool_ops tun_ethtool_ops = { - .get_settings = tun_get_settings, .get_drvinfo = tun_get_drvinfo, .get_msglevel = tun_get_msglevel, .set_msglevel = tun_set_msglevel, .get_link = ethtool_op_get_link, .get_ts_info = ethtool_op_get_ts_info, + .get_coalesce = tun_get_coalesce, + .set_coalesce = tun_set_coalesce, + .get_link_ksettings = tun_get_link_ksettings, + .set_link_ksettings = tun_set_link_ksettings, }; static int tun_queue_resize(struct tun_struct *tun) { struct net_device *dev = tun->dev; struct tun_file *tfile; - struct skb_array **arrays; + struct ptr_ring **rings; int n = tun->numqueues + tun->numdisabled; int ret, i; - arrays = kmalloc(sizeof *arrays * n, GFP_KERNEL); - if (!arrays) + rings = kmalloc_array(n, sizeof(*rings), GFP_KERNEL); + if (!rings) return -ENOMEM; for (i = 0; i < tun->numqueues; i++) { tfile = rtnl_dereference(tun->tfiles[i]); - arrays[i] = &tfile->tx_array; + rings[i] = &tfile->tx_ring; } list_for_each_entry(tfile, &tun->disabled, next) - arrays[i++] = &tfile->tx_array; + rings[i++] = &tfile->tx_ring; - ret = skb_array_resize_multiple(arrays, n, - dev->tx_queue_len, GFP_KERNEL); + ret = ptr_ring_resize_multiple(rings, n, + dev->tx_queue_len, GFP_KERNEL, + tun_ptr_free); - kfree(arrays); + kfree(rings); return ret; } @@ -2538,6 +3461,7 @@ static int tun_device_event(struct notifier_block *unused, { struct net_device *dev = netdev_notifier_info_to_dev(ptr); struct tun_struct *tun = netdev_priv(dev); + int i; if (dev->rtnl_link_ops != &tun_link_ops) return NOTIFY_DONE; @@ -2547,6 +3471,14 @@ static int tun_device_event(struct notifier_block *unused, if (tun_queue_resize(tun)) return NOTIFY_BAD; break; + case NETDEV_UP: + for (i = 0; i < tun->numqueues; i++) { + struct tun_file *tfile; + + tfile = rtnl_dereference(tun->tfiles[i]); + tfile->socket.sk->sk_write_space(tfile->socket.sk); + } + break; default: break; } @@ -2563,7 +3495,6 @@ static int __init tun_init(void) int ret = 0; pr_info("%s, %s\n", DRV_DESCRIPTION, DRV_VERSION); - pr_info("%s\n", DRV_COPYRIGHT); ret = rtnl_link_register(&tun_link_ops); if (ret) { @@ -2573,12 +3504,20 @@ static int __init tun_init(void) ret = misc_register(&tun_miscdev); if (ret) { - pr_err("Can't register misc device %d\n", TUN_MINOR1); + pr_err("Can't register misc device %d\n", BF_TUN_MINOR); goto err_misc; } - register_netdevice_notifier(&tun_notifier_block); + ret = register_netdevice_notifier(&tun_notifier_block); + if (ret) { + pr_err("Can't register netdevice notifier\n"); + goto err_notifier; + } + return 0; + +err_notifier: + misc_deregister(&tun_miscdev); err_misc: rtnl_link_unregister(&tun_link_ops); err_linkops: @@ -2608,10 +3547,23 @@ struct socket *tun_get_socket(struct file *file) } EXPORT_SYMBOL_GPL(tun_get_socket); +struct ptr_ring *tun_get_tx_ring(struct file *file) +{ + struct tun_file *tfile; + + if (file->f_op != &tun_fops) + return ERR_PTR(-EINVAL); + tfile = file->private_data; + if (!tfile) + return ERR_PTR(-EBADFD); + return &tfile->tx_ring; +} +EXPORT_SYMBOL_GPL(tun_get_tx_ring); + module_init(tun_init); module_exit(tun_cleanup); MODULE_DESCRIPTION(DRV_DESCRIPTION); MODULE_AUTHOR(DRV_COPYRIGHT); MODULE_LICENSE("GPL"); -MODULE_ALIAS_MISCDEV(TUN_MINOR1); +MODULE_ALIAS_MISCDEV(BF_TUN_MINOR); MODULE_ALIAS("devname:net/bf_tun"); diff --git a/platform/barefoot/bfn-platform.mk b/platform/barefoot/bfn-platform.mk index 622563e09853..1db534775acd 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_20201228_deb10.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..4f6322239d05 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -1,7 +1,8 @@ -BFN_SAI = bfnsdk_20200205_deb9.deb +BFN_SAI = bfnsdk_20201228_deb10.deb $(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/$(BFN_SAI)" $(BFN_SAI)_DEPENDS += $(LIBNL_GENL3_DEV) +$(eval $(call add_conflict_package,$(BFN_SAI),$(LIBSAIVS_DEV))) $(BFN_SAI)_RDEPENDS += $(LIBNL_GENL3) SONIC_ONLINE_DEBS += $(BFN_SAI) diff --git a/platform/barefoot/docker-ptf-bfn.mk b/platform/barefoot/docker-ptf-bfn.mk deleted file mode 100644 index 573e9cd9cffa..000000000000 --- a/platform/barefoot/docker-ptf-bfn.mk +++ /dev/null @@ -1,5 +0,0 @@ -# docker image for docker-ptf - -DOCKER_PTF_BFN = docker-ptf-bfn.gz -$(DOCKER_PTF_BFN)_PATH = $(DOCKERS_PATH)/docker-ptf-saithrift -$(DOCKER_PTF_BFN)_LOAD_DOCKERS += $(DOCKER_PTF) diff --git a/platform/barefoot/docker-saiserver-bfn/Dockerfile b/platform/barefoot/docker-saiserver-bfn/Dockerfile index 427a551e0096..6fa5b1818a18 100755 --- a/platform/barefoot/docker-saiserver-bfn/Dockerfile +++ b/platform/barefoot/docker-saiserver-bfn/Dockerfile @@ -34,5 +34,4 @@ COPY ["profile.ini", "portmap.ini", "/etc/sai/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /deps -ENTRYPOINT ["/usr/bin/supervisord"] - +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/barefoot/docker-syncd-bfn-rpc.mk b/platform/barefoot/docker-syncd-bfn-rpc.mk index d9cb0b5d6172..aee465151d84 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) \ @@ -12,7 +12,6 @@ $(DOCKER_SYNCD_BFN_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ endif $(DOCKER_SYNCD_BFN_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_BASE) SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_BFN_RPC) -SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_BFN_RPC) ifeq ($(ENABLE_SYNCD_RPC),y) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_BFN_RPC) endif diff --git a/platform/barefoot/docker-syncd-bfn-rpc/Dockerfile.j2 b/platform/barefoot/docker-syncd-bfn-rpc/Dockerfile.j2 index f10eb7fb5267..5e5f5f166e5e 100644 --- a/platform/barefoot/docker-syncd-bfn-rpc/Dockerfile.j2 +++ b/platform/barefoot/docker-syncd-bfn-rpc/Dockerfile.j2 @@ -11,24 +11,28 @@ debs/ RUN apt-get purge -y syncd -RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; } ; \ -{% for deb in docker_syncd_bfn_rpc_debs.split(' ') -%} -dpkg_apt debs/{{ deb }}{{'; '}} -{%- endfor %} - ## Pre-install the fundamental packages RUN apt-get update \ && apt-get -y install \ net-tools \ python-pip \ + python-setuptools \ build-essential \ libssl-dev \ libffi-dev \ python-dev \ wget \ cmake \ - libpython3.4 \ - && wget https://github.com/nanomsg/nanomsg/archive/1.0.0.tar.gz \ + libqt5core5a \ + libqt5network5 \ + libboost-atomic1.71.0 + +RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; } ; \ +{% for deb in docker_syncd_bfn_rpc_debs.split(' ') -%} +dpkg_apt debs/{{ deb }}{{'; '}} +{%- endfor %} + +RUN wget https://github.com/nanomsg/nanomsg/archive/1.0.0.tar.gz \ && tar xvfz 1.0.0.tar.gz \ && cd nanomsg-1.0.0 \ && mkdir -p build \ @@ -38,9 +42,10 @@ RUN apt-get update \ && cd .. \ && rm -fr nanomsg-1.0.0 \ && rm -f 1.0.0.tar.gz \ - && pip install cffi==1.7.0 \ - && pip install --upgrade cffi==1.7.0 \ - && pip install nnpy \ + && pip2 install cffi==1.7.0 \ + && pip2 install --upgrade cffi==1.7.0 \ + && pip2 install wheel \ + && pip2 install nnpy \ && mkdir -p /opt \ && cd /opt \ && wget https://raw.githubusercontent.com/p4lang/ptf/master/ptf_nn/ptf_nn_agent.py \ @@ -48,6 +53,5 @@ RUN apt-get update \ && rm -rf /root/deps COPY ["ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] - -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/barefoot/docker-syncd-bfn/Dockerfile.j2 b/platform/barefoot/docker-syncd-bfn/Dockerfile.j2 index c12c36b1260b..b9dbad963665 100755 --- a/platform/barefoot/docker-syncd-bfn/Dockerfile.j2 +++ b/platform/barefoot/docker-syncd-bfn/Dockerfile.j2 @@ -1,4 +1,4 @@ -FROM docker-config-engine-stretch +FROM docker-config-engine-buster ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive @@ -15,7 +15,7 @@ RUN apt-get install -y \ libxml2 \ libpcap-dev \ libusb-1.0-0-dev \ - libcurl3 \ + libcurl4 \ libcurl4-gnutls-dev \ libunwind8-dev \ libpython3.4 \ @@ -36,5 +36,4 @@ COPY ["critical_processes", "/etc/supervisor/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["/usr/bin/supervisord"] - +ENTRYPOINT ["/usr/local/bin/supervisord"] 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 3079618990ed..61e290e3189e 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" - if does not exist for 5 times within 5 cycles then alert +check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/platform/barefoot/docker-syncd-bfn/critical_processes b/platform/barefoot/docker-syncd-bfn/critical_processes index 6082f242b872..bdd6903c5690 100644 --- a/platform/barefoot/docker-syncd-bfn/critical_processes +++ b/platform/barefoot/docker-syncd-bfn/critical_processes @@ -1 +1 @@ -syncd +program:syncd diff --git a/platform/barefoot/docker-syncd-bfn/start.sh b/platform/barefoot/docker-syncd-bfn/start.sh index 1a39db4a9d83..0fcdef4a961e 100755 --- a/platform/barefoot/docker-syncd-bfn/start.sh +++ b/platform/barefoot/docker-syncd-bfn/start.sh @@ -1,9 +1,4 @@ #!/usr/bin/env bash -rm -f /var/run/rsyslogd.pid - -supervisorctl start rsyslogd - . /opt/bfn/install/bin/dma_setup.sh # . /opt/bfn/install/bin/bf_kdrv_mod_load /opt/bfn/install -LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/bfn/install/lib supervisorctl start syncd diff --git a/platform/barefoot/docker-syncd-bfn/supervisord.conf b/platform/barefoot/docker-syncd-bfn/supervisord.conf index 1744d6ffefb5..c83484e5e93b 100644 --- a/platform/barefoot/docker-syncd-bfn/supervisord.conf +++ b/platform/barefoot/docker-syncd-bfn/supervisord.conf @@ -3,33 +3,48 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python3 -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE +buffer_size=25 + [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name syncd -events=PROCESS_STATE_EXITED +events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING autostart=true autorestart=unexpected -[program:start.sh] -command=/usr/bin/start.sh +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE priority=1 -autostart=true +autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true -[program:rsyslogd] -command=/usr/sbin/rsyslogd -n +[program:start] +command=/usr/bin/start.sh priority=2 autostart=false autorestart=false +startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running [program:syncd] +environment=LD_LIBRARY_PATH="/opt/bfn/install/lib" command=/usr/bin/syncd_start.sh priority=3 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog - +dependent_startup=true +dependent_startup_wait_for=start:exited diff --git a/platform/barefoot/one-aboot.mk b/platform/barefoot/one-aboot.mk index 4e5e808d2ab9..a2cdf2ac0391 100644 --- a/platform/barefoot/one-aboot.mk +++ b/platform/barefoot/one-aboot.mk @@ -11,5 +11,10 @@ $(SONIC_ONE_ABOOT_IMAGE)_INSTALLS += $(ARISTA_PLATFORM_MODULE_DRIVERS) \ $(ARISTA_PLATFORM_MODULE_PYTHON2) \ $(ARISTA_PLATFORM_MODULE_PYTHON3) \ $(ARISTA_PLATFORM_MODULE) +ifeq ($(INSTALL_DEBUG_TOOLS),y) +$(SONIC_ONE_ABOOT_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES) +$(SONIC_ONE_ABOOT_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES)) +else $(SONIC_ONE_ABOOT_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_IMAGES) +endif SONIC_INSTALLERS += $(SONIC_ONE_ABOOT_IMAGE) diff --git a/platform/barefoot/one-image.mk b/platform/barefoot/one-image.mk index 0147b62d00a1..8ed212c6f7a8 100644 --- a/platform/barefoot/one-image.mk +++ b/platform/barefoot/one-image.mk @@ -3,11 +3,12 @@ SONIC_ONE_IMAGE = sonic-barefoot.bin $(SONIC_ONE_IMAGE)_MACHINE = barefoot $(SONIC_ONE_IMAGE)_IMAGE_TYPE = onie -$(SONIC_ONE_IMAGE)_INSTALLS += $(BFN_MODULE) $(PYTHON_THRIFT) +$(SONIC_ONE_IMAGE)_INSTALLS += $(BFN_MODULE) $(SONIC_ONE_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(BFN_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(BFN_MONTARA_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(BFN_NEWPORT_PLATFORM_MODULE) +$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(BFN_NEWPORT_BF_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(WNC_OSW1800_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(INGRASYS_S9180_32X_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(INGRASYS_S9280_64X_PLATFORM_MODULE) diff --git a/platform/barefoot/platform-modules-arista.mk b/platform/barefoot/platform-modules-arista.mk index 480aa0cf8396..298bc93d9250 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))) @@ -21,5 +21,3 @@ $(eval $(call add_extra_package,$(ARISTA_PLATFORM_MODULE),$(ARISTA_PLATFORM_MODU export ARISTA_PLATFORM_MODULE ARISTA_PLATFORM_MODULE_PYTHON2 ARISTA_PLATFORM_MODULE_PYTHON3 ARISTA_PLATFORM_MODULE_DRIVERS export ARISTA_SCD_DRIVER_CONFIG=m - -SONIC_STRETCH_DEBS += $(ARISTA_PLATFORM_MODULE) diff --git a/platform/barefoot/platform-modules-bfn-montara.mk b/platform/barefoot/platform-modules-bfn-montara.mk index d089218c9454..375f100475cf 100644 --- a/platform/barefoot/platform-modules-bfn-montara.mk +++ b/platform/barefoot/platform-modules-bfn-montara.mk @@ -9,5 +9,3 @@ $(BFN_MONTARA_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-module $(BFN_MONTARA_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) $(BFN_MONTARA_PLATFORM_MODULE)_PLATFORM = x86_64-accton_wedge100bf_32x-r0 SONIC_DPKG_DEBS += $(BFN_MONTARA_PLATFORM_MODULE) - -SONIC_STRETCH_DEBS += $(BFN_MONTARA_PLATFORM_MODULE) diff --git a/platform/barefoot/platform-modules-bfn-newport.mk b/platform/barefoot/platform-modules-bfn-newport.mk index ff251ed1ddd7..151d8d0e58c2 100644 --- a/platform/barefoot/platform-modules-bfn-newport.mk +++ b/platform/barefoot/platform-modules-bfn-newport.mk @@ -4,10 +4,12 @@ BFN_NEWPORT_PLATFORM_MODULE_VERSION = 1.0 export BFN_NEWPORT_PLATFORM_MODULE_VERSION -BFN_NEWPORT_PLATFORM_MODULE = sonic-platform-modules-bfn-newport_$(BFN_NEWPORT_PLATFORM_MODULE_VERSION)_amd64.deb +BFN_NEWPORT_PLATFORM_MODULE = sonic-platform-modules-bfn-newport-as9516_$(BFN_NEWPORT_PLATFORM_MODULE_VERSION)_amd64.deb $(BFN_NEWPORT_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-bfn-newport $(BFN_NEWPORT_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) -$(BFN_NEWPORT_PLATFORM_MODULE)_PLATFORM = x86_64-accton_as9516bf_32d-r0 +$(BFN_NEWPORT_PLATFORM_MODULE)_PLATFORM = x86_64-accton_as9516_32d-r0 SONIC_DPKG_DEBS += $(BFN_NEWPORT_PLATFORM_MODULE) -SONIC_STRETCH_DEBS += $(BFN_NEWPORT_PLATFORM_MODULE) +BFN_NEWPORT_BF_PLATFORM_MODULE = sonic-platform-modules-bfn-newport-as9516bf_$(BFN_NEWPORT_PLATFORM_MODULE_VERSION)_amd64.deb +$(BFN_NEWPORT_BF_PLATFORM_MODULE)_PLATFORM = x86_64-accton_as9516bf_32d-r0 +$(eval $(call add_extra_package,$(BFN_NEWPORT_PLATFORM_MODULE),$(BFN_NEWPORT_BF_PLATFORM_MODULE))) diff --git a/platform/barefoot/platform-modules-bfn.mk b/platform/barefoot/platform-modules-bfn.mk index 1caa92c8f2b3..28b6ec112788 100644 --- a/platform/barefoot/platform-modules-bfn.mk +++ b/platform/barefoot/platform-modules-bfn.mk @@ -10,4 +10,3 @@ $(BFN_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) $(BFN_PLATFORM_MODULE)_PLATFORM = x86_64-accton_wedge100bf_65x-r0 SONIC_DPKG_DEBS += $(BFN_PLATFORM_MODULE) -SONIC_STRETCH_DEBS += $(BFN_PLATFORM_MODULE) diff --git a/platform/barefoot/platform-modules-ingrasys.mk b/platform/barefoot/platform-modules-ingrasys.mk index ea8f68c003fc..60153e5dee75 100644 --- a/platform/barefoot/platform-modules-ingrasys.mk +++ b/platform/barefoot/platform-modules-ingrasys.mk @@ -17,4 +17,3 @@ $(INGRASYS_S9280_64X_PLATFORM_MODULE)_PLATFORM = x86_64-ingrasys_s9280_64x-r0 $(eval $(call add_extra_package,$(INGRASYS_S9180_32X_PLATFORM_MODULE),$(INGRASYS_S9280_64X_PLATFORM_MODULE))) -SONIC_STRETCH_DEBS += $(INGRASYS_S9180_32X_PLATFORM_MODULE) diff --git a/platform/barefoot/platform-modules-wnc-osw1800.mk b/platform/barefoot/platform-modules-wnc-osw1800.mk index 5703d069c97e..a203aa93f7ec 100644 --- a/platform/barefoot/platform-modules-wnc-osw1800.mk +++ b/platform/barefoot/platform-modules-wnc-osw1800.mk @@ -10,4 +10,3 @@ $(WNC_OSW1800_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMO $(WNC_OSW1800_PLATFORM_MODULE)_PLATFORM = x86_64-wnc_osw1800-r0 SONIC_DPKG_DEBS += $(WNC_OSW1800_PLATFORM_MODULE) -SONIC_STRETCH_DEBS += $(WNC_OSW1800_PLATFORM_MODULE) diff --git a/platform/barefoot/rules.mk b/platform/barefoot/rules.mk index 8a218b3ff169..98dcef0f7b8a 100644 --- a/platform/barefoot/rules.mk +++ b/platform/barefoot/rules.mk @@ -10,7 +10,6 @@ include $(PLATFORM_PATH)/docker-syncd-bfn-rpc.mk include $(PLATFORM_PATH)/one-aboot.mk include $(PLATFORM_PATH)/one-image.mk include $(PLATFORM_PATH)/libsaithrift-dev.mk -include $(PLATFORM_PATH)/docker-ptf-bfn.mk include $(PLATFORM_PATH)/bfn-platform.mk #include $(PLATFORM_PATH)/bfn-platform-wnc.mk #include $(PLATFORM_PATH)/bfn-platform-ingrasys.mk @@ -19,8 +18,15 @@ include $(PLATFORM_PATH)/bfn-modules.mk SONIC_ALL += $(SONIC_ONE_IMAGE) $(SONIC_ONE_ABOOT) \ $(DOCKER_FPM) -# Inject sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(BFN_SAI) $(WNC_OSW1800_PLATFORM) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM) #$(LIBSAITHRIFT_DEV_BFN) +# Inject sai into syncd +#$(SYNCD)_DEPENDS += $(BFN_SAI) $(WNC_OSW1800_PLATFORM) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM) +$(SYNCD)_DEPENDS += $(BFN_SAI) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM) +$(SYNCD)_UNINSTALLS += $(BFN_SAI) + +ifeq ($(ENABLE_SYNCD_RPC),y) +$(SYNCD)_DEPENDS += $(LIBSAITHRIFT_DEV) +endif # Runtime dependency on sai is set only for syncd -$(SYNCD)_RDEPENDS += $(BFN_SAI) $(WNC_OSW1800_PLATFORM) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM) +#$(SYNCD)_RDEPENDS += $(BFN_SAI) $(WNC_OSW1800_PLATFORM) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM) +$(SYNCD)_RDEPENDS += $(BFN_SAI) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM) diff --git a/platform/barefoot/sonic-platform-modules-arista b/platform/barefoot/sonic-platform-modules-arista index b1940cf49a18..937ea8abc1de 160000 --- a/platform/barefoot/sonic-platform-modules-arista +++ b/platform/barefoot/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit b1940cf49a185745cc9365afed8efb511478807e +Subproject commit 937ea8abc1de457b26b7bb7a5208dab6ce40f4a1 diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/compat b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/compat index 45a4fb75db86..ec635144f600 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/compat +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/compat @@ -1 +1 @@ -8 +9 diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control index e3f5356f22db..a3ea06992dc4 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control @@ -2,11 +2,11 @@ Source: sonic-platform-modules-bfn-montara Section: main Priority: extra Maintainer: Support -Build-Depends: debhelper (>= 8.0.0), bzip2 +Build-Depends: debhelper (>= 9.0.0), bzip2 Standards-Version: 3.9.3 Package: sonic-platform-modules-bfn-montara Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/postinst b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/postinst new file mode 100755 index 000000000000..a218d59e2652 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/postinst @@ -0,0 +1,10 @@ +#!/bin/sh +set -e + +PLATFORM_NAME=x86_64-accton_wedge100bf_32x-r0 +SONIC_PLATFORM_WHEEL_PY2="/usr/share/sonic/device/${PLATFORM_NAME}/sonic_platform-1.0-py2-none-any.whl" +python2 -m pip install ${SONIC_PLATFORM_WHEEL_PY2} +SONIC_PLATFORM_WHEEL_PY3="/usr/share/sonic/device/${PLATFORM_NAME}/sonic_platform-1.0-py3-none-any.whl" +python3 -m pip install ${SONIC_PLATFORM_WHEEL_PY3} + +#DEBHELPER# diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/prerm b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/prerm new file mode 100755 index 000000000000..ee19dbb1db98 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/prerm @@ -0,0 +1,6 @@ +#!/bin/sh + +python2 -m pip uninstall -y sonic-platform +python3 -m pip uninstall -y sonic-platform + +#DEBHELPER# diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/rules b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/rules index 972f49ff91d0..b04234a0df1b 100755 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/rules +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/rules @@ -1,22 +1,36 @@ #!/usr/bin/make -f +PLATFORM_NAME := x86_64-accton_wedge100bf_32x-r0 PACKAGE_NAME := sonic-platform-modules-bfn-montara SCRIPT_SRC := $(shell pwd)/scripts CONFIGS_SRC := $(shell pwd)/configs +BUILD_DIR := $(shell pwd)/build +WHEEL_BUILD_DIR := $(BUILD_DIR)/wheel +PLUGINS_DIR := $(shell pwd)/plugins %: dh $@ +override_dh_auto_build: + set -e + python2.7 setup.py bdist_wheel -d $(WHEEL_BUILD_DIR) + python3 setup.py bdist_wheel -d $(WHEEL_BUILD_DIR) + set +e + override_dh_auto_install: dh_installdirs -p$(PACKAGE_NAME) usr/local/bin cp -r $(SCRIPT_SRC)/* debian/$(PACKAGE_NAME)/usr/local/bin dh_installdirs -p$(PACKAGE_NAME) etc/network/interfaces.d/ cp -r $(CONFIGS_SRC)/network/interfaces.d/* debian/$(PACKAGE_NAME)/etc/network/interfaces.d/ + dh_installdirs -p$(PACKAGE_NAME) usr/share/sonic/device/$(PLATFORM_NAME)/ + cp -r $(WHEEL_BUILD_DIR)/* debian/$(PACKAGE_NAME)/usr/share/sonic/device/$(PLATFORM_NAME)/ + dh_installdirs -p$(PACKAGE_NAME) usr/share/sonic/device/$(PLATFORM_NAME)/plugins + cp -r $(PLUGINS_DIR)/* debian/$(PACKAGE_NAME)/usr/share/sonic/device/$(PLATFORM_NAME)/plugins/ override_dh_usrlocal: -override_dh_pysupport: - override_dh_clean: + rm -fr $(WHEEL_BUILD_DIR) + rm -fr *.egg-info + rm -fr $(BUILD) dh_clean - diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/plugins/pcie.yaml b/platform/barefoot/sonic-platform-modules-bfn-montara/plugins/pcie.yaml new file mode 100644 index 000000000000..ab38096c9740 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/plugins/pcie.yaml @@ -0,0 +1,412 @@ +- bus: '00' + dev: '00' + fn: '0' + id: 6f00 + name: 'Host bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D DMI2 + (rev 03)' +- bus: '00' + dev: '01' + fn: '0' + id: 6f02 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 1 (rev 03)' +- bus: '00' + dev: '01' + fn: '1' + id: 6f03 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 1 (rev 03)' +- bus: '00' + dev: '02' + fn: '0' + id: 6f04 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 2 (rev 03)' +- bus: '00' + dev: '02' + fn: '2' + id: 6f06 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 2 (rev 03)' +- bus: '00' + dev: '03' + fn: '0' + id: 6f08 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 3 (rev 03)' +- bus: '00' + dev: '05' + fn: '0' + id: 6f28 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Map/VTd_Misc/System Management (rev 03)' +- bus: '00' + dev: '05' + fn: '1' + id: 6f29 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Hot Plug (rev 03)' +- bus: '00' + dev: '05' + fn: '2' + id: 6f2a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO RAS/Control Status/Global Errors (rev 03)' +- bus: '00' + dev: '05' + fn: '4' + id: 6f2c + name: 'PIC: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D I/O APIC (rev + 03)' +- bus: '00' + dev: '14' + fn: '0' + id: 8c31 + name: 'USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB + xHCI (rev 05)' +- bus: '00' + dev: 1d + fn: '0' + id: 8c26 + name: 'USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB + EHCI #1 (rev 05)' +- bus: '00' + dev: 1f + fn: '0' + id: 8c54 + name: 'ISA bridge: Intel Corporation C224 Series Chipset Family Server Standard + SKU LPC Controller (rev 05)' +- bus: '00' + dev: 1f + fn: '2' + id: 8c02 + name: 'SATA controller: Intel Corporation 8 Series/C220 Series Chipset Family 6-port + SATA Controller 1 [AHCI mode] (rev 05)' +- bus: '00' + dev: 1f + fn: '3' + id: 8c22 + name: 'SMBus: Intel Corporation 8 Series/C220 Series Chipset Family SMBus Controller + (rev 05)' +- bus: '00' + dev: 1f + fn: '6' + id: 8c24 + name: 'Signal processing controller: Intel Corporation 8 Series Chipset Family Thermal + Management Controller (rev 05)' +- bus: '02' + dev: '00' + fn: '0' + id: '1533' + name: 'Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev + 03)' +- bus: '03' + dev: '00' + fn: '0' + id: 6f50 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 0' +- bus: '03' + dev: '00' + fn: '1' + id: 6f51 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 1' +- bus: '03' + dev: '00' + fn: '2' + id: 6f52 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 2' +- bus: '03' + dev: '00' + fn: '3' + id: 6f53 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 3' +- bus: '04' + dev: '00' + fn: '0' + id: 10a6 + name: 'Unassigned class [ff00]: Intel Corporation 82599EB 10-Gigabit Dummy Function' +- bus: '05' + dev: '00' + fn: '0' + id: '0010' + name: 'Unassigned class [ff00]: Device 1d1c:0010 (rev 10)' +- bus: ff + dev: 0b + fn: '0' + id: 6f81 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '1' + id: 6f36 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '2' + id: 6f37 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '3' + id: 6f76 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link Debug (rev 03)' +- bus: ff + dev: 0c + fn: '0' + id: 6fe0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0c + fn: '1' + id: 6fe1 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0c + fn: '2' + id: 6fe2 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0c + fn: '3' + id: 6fe3 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '0' + id: 6ff8 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '4' + id: 6ffc + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '5' + id: 6ffd + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '6' + id: 6ffe + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: '10' + fn: '0' + id: 6f1d + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R2PCIe Agent (rev 03)' +- bus: ff + dev: '10' + fn: '1' + id: 6f34 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R2PCIe Agent (rev 03)' +- bus: ff + dev: '10' + fn: '5' + id: 6f1e + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '10' + fn: '6' + id: 6f7d + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '10' + fn: '7' + id: 6f1f + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '12' + fn: '0' + id: 6fa0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Home Agent 0 (rev 03)' +- bus: ff + dev: '12' + fn: '1' + id: 6f30 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Home Agent 0 (rev 03)' +- bus: ff + dev: '13' + fn: '0' + id: 6fa8 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Target Address/Thermal/RAS (rev 03)' +- bus: ff + dev: '13' + fn: '1' + id: 6f71 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Target Address/Thermal/RAS (rev 03)' +- bus: ff + dev: '13' + fn: '2' + id: 6faa + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '3' + id: 6fab + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '4' + id: 6fac + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '5' + id: 6fad + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '6' + id: 6fae + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Broadcast (rev 03)' +- bus: ff + dev: '13' + fn: '7' + id: 6faf + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Global Broadcast (rev 03)' +- bus: ff + dev: '14' + fn: '0' + id: 6fb0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 0 Thermal Control (rev 03)' +- bus: ff + dev: '14' + fn: '1' + id: 6fb1 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 1 Thermal Control (rev 03)' +- bus: ff + dev: '14' + fn: '2' + id: 6fb2 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 0 Error (rev 03)' +- bus: ff + dev: '14' + fn: '3' + id: 6fb3 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 1 Error (rev 03)' +- bus: ff + dev: '14' + fn: '4' + id: 6fbc + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '5' + id: 6fbd + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '6' + id: 6fbe + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '7' + id: 6fbf + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '15' + fn: '0' + id: 6fb4 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 2 Thermal Control (rev 03)' +- bus: ff + dev: '15' + fn: '1' + id: 6fb5 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 3 Thermal Control (rev 03)' +- bus: ff + dev: '15' + fn: '2' + id: 6fb6 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 2 Error (rev 03)' +- bus: ff + dev: '15' + fn: '3' + id: 6fb7 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 3 Error (rev 03)' +- bus: ff + dev: 1e + fn: '0' + id: 6f98 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '1' + id: 6f99 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '2' + id: 6f9a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '3' + id: 6fc0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '4' + id: 6f9c + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1f + fn: '0' + id: 6f88 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1f + fn: '2' + id: 6f8a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/setup.py b/platform/barefoot/sonic-platform-modules-bfn-montara/setup.py new file mode 100755 index 000000000000..fc14c94ac4a0 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/setup.py @@ -0,0 +1,31 @@ +from setuptools import setup + +setup( + name='sonic-platform', + version='1.0', + description='SONiC platform API implementation', + license='Apache 2.0', + author='SONiC Team', + author_email='', + url='https://github.com/Azure/sonic-buildimage', + maintainer='Barefoot', + maintainer_email='', + packages=[ + 'sonic_platform', + 'sonic_platform/pltfm_mgr_rpc' + ], + package_data = {'sonic_platform':['logging.conf']}, + classifiers=[ + 'Development Status :: 3 - Alpha', + 'Environment :: Plugins', + 'Intended Audience :: Developers', + 'Intended Audience :: Information Technology', + 'Intended Audience :: System Administrators', + 'License :: OSI Approved :: Apache Software License', + 'Natural Language :: English', + 'Operating System :: POSIX :: Linux', + 'Programming Language :: Python :: 2.7', + 'Topic :: Utilities', + ], + keywords='sonic SONiC platform PLATFORM', +) diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/__init__.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/__init__.py new file mode 100644 index 000000000000..d5f19f74f4c6 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/__init__.py @@ -0,0 +1,2 @@ +__all__ = ['chassis', 'eeprom', 'platform', 'psu', 'sfp'] +from . import platform diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/chassis.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/chassis.py new file mode 100644 index 000000000000..fad16cbdb8a2 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/chassis.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python + +try: + import sys + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform.sfp import Sfp + from sonic_platform.psu import Psu + from eeprom import Eeprom +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +class Chassis(ChassisBase): + """ + Platform-specific Chassis class + """ + def __init__(self): + ChassisBase.__init__(self) + + self._eeprom = Eeprom() + + for index in range(Sfp.port_start(), Sfp.port_end() + 1): + sfp_node = Sfp(index) + self._sfp_list.append(sfp_node) + + for i in range(1, Psu.get_num_psus() + 1): + psu = Psu(i) + self._psu_list.append(psu) + + def get_name(self): + """ + Retrieves the name of the chassis + Returns: + string: The name of the chassis + """ + return self._eeprom.modelstr() + + def get_presence(self): + """ + Retrieves the presence of the chassis + Returns: + bool: True if chassis is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the chassis + Returns: + string: Model/part number of chassis + """ + return self._eeprom.part_number_str() + + def get_serial(self): + """ + Retrieves the serial number of the chassis (Service tag) + Returns: + string: Serial number of chassis + """ + return self._eeprom.serial_number_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): + """ + Retrieves the operational status of the chassis + Returns: + bool: A boolean value, True if chassis is operating properly + False if not + """ + return True + + def get_base_mac(self): + """ + Retrieves the base MAC address for the chassis + + Returns: + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' + """ + return self._eeprom.base_mac_addr() + + def get_system_eeprom_info(self): + """ + Retrieves the full content of system EEPROM information for the chassis + + Returns: + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their corresponding + values. + """ + return self._eeprom.system_eeprom_info() + + def get_change_event(self, timeout=0): + ready, event_sfp = Sfp.get_transceiver_change_event(timeout) + return ready, { 'sfp': event_sfp } if ready else {} diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/eeprom.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/eeprom.py new file mode 100644 index 000000000000..587f57826fb5 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/eeprom.py @@ -0,0 +1,155 @@ +try: + import os + import sys + import errno + import datetime + import logging + import logging.config + import yaml + import re + + sys.path.append(os.path.dirname(__file__)) + + if sys.version_info.major == 3: + from io import StringIO + else: + from cStringIO import StringIO + + from sonic_platform_base.sonic_eeprom import eeprom_base + from sonic_platform_base.sonic_eeprom import eeprom_tlvinfo + + from platform_thrift_client import thrift_try +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + + +_platform_eeprom_map = { + "prod_name" : ("Product Name", "0x21", 12), + "odm_pcba_part_num" : ("Part Number", "0x22", 13), + "prod_ser_num" : ("Serial Number", "0x23", 12), + "ext_mac_addr" : ("Extended MAC Address Base", "0x24", 12), + "sys_mfg_date" : ("System Manufacturing Date", "0x25", 4), + "prod_ver" : ("Product Version", "0x26", 1), + "ext_mac_addr_size" : ("Extende MAC Address Size", "0x2A", 2), + "sys_mfger" : ("Manufacturer", "0x2B", 8) +} + +_product_dict = { "Montara" : "Wedge100BF-32X-O-AC-F-BF", + "Lower MAV" : "Wedge100BF-65X-O-AC-F-BF", + "Upper MAV" : "Wedge100BF-65X-O-AC-F-BF" + } + +_EEPROM_SYMLINK = "/var/run/platform/eeprom/syseeprom" +_EEPROM_STATUS = "/var/run/platform/eeprom/status" + +try: + _str_type = basestring +except NameError: + _str_type = str + +class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): + def __init__(self): + with open(os.path.dirname(__file__) + "/logging.conf", 'r') as f: + config_dict = yaml.load(f, yaml.SafeLoader) + logging.config.dictConfig(config_dict) + + if not os.path.exists(os.path.dirname(_EEPROM_SYMLINK)): + try: + os.makedirs(os.path.dirname(_EEPROM_SYMLINK)) + except OSError as e: + if e.errno != errno.EEXIST: + raise + + open(_EEPROM_SYMLINK, 'a').close() + with open(_EEPROM_STATUS, 'w') as f: + f.write("initializing..") + + self.eeprom_path = _EEPROM_SYMLINK + super(Eeprom, self).__init__(self.eeprom_path, 0, _EEPROM_STATUS, True) + + def sys_eeprom_get(client): + return client.pltfm_mgr.pltfm_mgr_sys_eeprom_get() + try: + platform_eeprom = thrift_try(sys_eeprom_get) + except Exception: + raise RuntimeError("eeprom.py: Initialization failed") + + self.__eeprom_init(platform_eeprom) + + def __eeprom_init(self, platform_eeprom): + with open(_EEPROM_STATUS, 'w') as f: + f.write("ok") + + eeprom_params = "" + for attr, val in platform_eeprom.__dict__.items(): + if val is None: + continue + + elem = _platform_eeprom_map.get(attr) + if elem is None: + continue + + if isinstance(val, _str_type): + value = val.replace('\0', '') + else: + value = str(val) + + if attr == "sys_mfg_date": + value = datetime.datetime.strptime(value, '%m-%d-%y').strftime('%m/%d/%Y 00:00:00') + + product = _product_dict.get(value) + if product is not None: + value = product + if len(eeprom_params) > 0: + eeprom_params += "," + eeprom_params += "{0:s}={1:s}".format(elem[1], value) + + orig_stdout = sys.stdout + sys.stdout = StringIO() + try: + eeprom_data = eeprom_tlvinfo.TlvInfoDecoder.set_eeprom(self, "", [eeprom_params]) + finally: + decode_output = sys.stdout.getvalue() + sys.stdout = orig_stdout + + eeprom_base.EepromDecoder.write_eeprom(self, eeprom_data) + self.__eeprom_tlv_dict = self.__parse_output(decode_output) + + def __parse_output(self, decode_output): + EEPROM_DECODE_HEADLINES = 6 + lines = decode_output.replace('\0', '').split('\n') + lines = lines[EEPROM_DECODE_HEADLINES:] + res = dict() + + for line in lines: + try: + # match whitespace-separated tag hex, length and value (value is mathced with its whitespaces) + match = re.search('(0x[0-9a-fA-F]{2})([\s]+[\S]+[\s]+)([\S]+[\s]*[\S]*)', line) + if match is not None: + code = match.group(1) + value = match.group(3).rstrip('\0') + res[code] = value + except Exception: + pass + return res + + def __tlv_get(self, code): + return self.__eeprom_tlv_dict.get("0x{:X}".format(code), 'N/A') + + def system_eeprom_info(self): + return self.__eeprom_tlv_dict + + def serial_number_str(self): + return self.__tlv_get(self._TLV_CODE_SERIAL_NUMBER) + + def serial_str(self): + return self.serial_number_str() + + def base_mac_addr(self): + return self.__tlv_get(self._TLV_CODE_MAC_BASE) + + def part_number_str(self): + return self.__tlv_get(self._TLV_CODE_PART_NUMBER) + + def modelstr(self): + return self.__tlv_get(self._TLV_CODE_PRODUCT_NAME) diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/logging.conf b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/logging.conf new file mode 100644 index 000000000000..d7fd84773404 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/logging.conf @@ -0,0 +1,17 @@ +version: 1 +disable_existing_loggers: False + +formatters: + simple: + format: '%(asctime)s %(name)-30s %(levelname)-7s %(message)s' + +handlers: + file: + class: logging.handlers.RotatingFileHandler + formatter: simple + filename: /var/log/platform.log + +root: + level: ERROR + handlers: + - file diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform.py new file mode 100644 index 000000000000..ebc68a895362 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python + +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PlatformBase): + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform_thrift_client.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform_thrift_client.py new file mode 100644 index 000000000000..96c0e09ba1c0 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform_thrift_client.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +try: + import os + import sys + import time + import importlib + + sys.path.append(os.path.dirname(__file__)) + + from thrift.transport import TSocket + from thrift.transport import TTransport + from thrift.protocol import TBinaryProtocol + from thrift.protocol import TMultiplexedProtocol + from thrift.Thrift import TException +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +THRIFT_SERVER = 'localhost' + +class ThriftClient(object): + def open(self): + self.transport = TSocket.TSocket(THRIFT_SERVER, 9090) + + self.transport = TTransport.TBufferedTransport(self.transport) + bprotocol = TBinaryProtocol.TBinaryProtocol(self.transport) + + pltfm_mgr_client_module = importlib.import_module(".".join(["pltfm_mgr_rpc", "pltfm_mgr_rpc"])) + pltfm_mgr_protocol = TMultiplexedProtocol.TMultiplexedProtocol(bprotocol, "pltfm_mgr_rpc") + self.pltfm_mgr = pltfm_mgr_client_module.Client(pltfm_mgr_protocol) + + self.transport.open() + return self + def close(self): + self.transport.close() + def __enter__(self): + return self.open() + def __exit__(self, exc_type, exc_value, tb): + self.close() + +def thrift_try(func, attempts=35): + for attempt in range(attempts): + try: + with ThriftClient() as client: + return func(client) + except TException as e: + if attempt + 1 == attempts: + raise e + time.sleep(1) diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/__init__.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/__init__.py new file mode 100644 index 000000000000..414c3d6389c5 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/__init__.py @@ -0,0 +1 @@ +__all__ = ['ttypes', 'pltfm_mgr_rpc'] diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/pltfm_mgr_rpc.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/pltfm_mgr_rpc.py new file mode 100644 index 000000000000..b256b6285fc3 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/pltfm_mgr_rpc.py @@ -0,0 +1,2924 @@ +# +# Autogenerated by Thrift Compiler (0.10.0) +# +# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING +# +# options string: py +# + +from thrift.Thrift import TType, TMessageType, TFrozenDict, TException, TApplicationException +from thrift.protocol.TProtocol import TProtocolException +import sys +import logging +from .ttypes import * +from thrift.Thrift import TProcessor +from thrift.transport import TTransport + + +class Iface(object): + def pltfm_mgr_dummy(self, device): + """ + Parameters: + - device + """ + pass + + def pltfm_mgr_sys_tmp_get(self): + pass + + def pltfm_mgr_sys_eeprom_get(self): + pass + + def pltfm_mgr_pwr_supply_present_get(self, ps_num): + """ + Parameters: + - ps_num + """ + pass + + def pltfm_mgr_pwr_supply_info_get(self, ps_num): + """ + Parameters: + - ps_num + """ + pass + + def pltfm_mgr_pwr_rail_info_get(self, ps_num): + """ + Parameters: + - ps_num + """ + pass + + def pltfm_mgr_fan_speed_set(self, fan_num, percent): + """ + Parameters: + - fan_num + - percent + """ + pass + + def pltfm_mgr_fan_info_get(self, fan_num): + """ + Parameters: + - fan_num + """ + pass + + def pltfm_mgr_qsfp_presence_get(self, port_num): + """ + Parameters: + - port_num + """ + pass + + def pltfm_mgr_qsfp_info_get(self, port_num): + """ + Parameters: + - port_num + """ + pass + + def pltfm_mgr_qsfp_get_max_port(self): + pass + + def pltfm_mgr_qsfp_reset(self, port_num, reset): + """ + Parameters: + - port_num + - reset + """ + pass + + def pltfm_mgr_qsfp_lpmode_get(self, port_num): + """ + Parameters: + - port_num + """ + pass + + def pltfm_mgr_qsfp_lpmode_set(self, port_num, lpmode): + """ + Parameters: + - port_num + - lpmode + """ + pass + + def pltfm_mgr_sensor_info_get(self, options): + """ + Parameters: + - options + """ + pass + + +class Client(Iface): + def __init__(self, iprot, oprot=None): + self._iprot = self._oprot = iprot + if oprot is not None: + self._oprot = oprot + self._seqid = 0 + + def pltfm_mgr_dummy(self, device): + """ + Parameters: + - device + """ + self.send_pltfm_mgr_dummy(device) + return self.recv_pltfm_mgr_dummy() + + def send_pltfm_mgr_dummy(self, device): + self._oprot.writeMessageBegin('pltfm_mgr_dummy', TMessageType.CALL, self._seqid) + args = pltfm_mgr_dummy_args() + args.device = device + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_dummy(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_dummy_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_dummy failed: unknown result") + + def pltfm_mgr_sys_tmp_get(self): + self.send_pltfm_mgr_sys_tmp_get() + return self.recv_pltfm_mgr_sys_tmp_get() + + def send_pltfm_mgr_sys_tmp_get(self): + self._oprot.writeMessageBegin('pltfm_mgr_sys_tmp_get', TMessageType.CALL, self._seqid) + args = pltfm_mgr_sys_tmp_get_args() + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_sys_tmp_get(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_sys_tmp_get_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_sys_tmp_get failed: unknown result") + + def pltfm_mgr_sys_eeprom_get(self): + self.send_pltfm_mgr_sys_eeprom_get() + return self.recv_pltfm_mgr_sys_eeprom_get() + + def send_pltfm_mgr_sys_eeprom_get(self): + self._oprot.writeMessageBegin('pltfm_mgr_sys_eeprom_get', TMessageType.CALL, self._seqid) + args = pltfm_mgr_sys_eeprom_get_args() + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_sys_eeprom_get(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_sys_eeprom_get_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_sys_eeprom_get failed: unknown result") + + def pltfm_mgr_pwr_supply_present_get(self, ps_num): + """ + Parameters: + - ps_num + """ + self.send_pltfm_mgr_pwr_supply_present_get(ps_num) + return self.recv_pltfm_mgr_pwr_supply_present_get() + + def send_pltfm_mgr_pwr_supply_present_get(self, ps_num): + self._oprot.writeMessageBegin('pltfm_mgr_pwr_supply_present_get', TMessageType.CALL, self._seqid) + args = pltfm_mgr_pwr_supply_present_get_args() + args.ps_num = ps_num + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_pwr_supply_present_get(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_pwr_supply_present_get_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_pwr_supply_present_get failed: unknown result") + + def pltfm_mgr_pwr_supply_info_get(self, ps_num): + """ + Parameters: + - ps_num + """ + self.send_pltfm_mgr_pwr_supply_info_get(ps_num) + return self.recv_pltfm_mgr_pwr_supply_info_get() + + def send_pltfm_mgr_pwr_supply_info_get(self, ps_num): + self._oprot.writeMessageBegin('pltfm_mgr_pwr_supply_info_get', TMessageType.CALL, self._seqid) + args = pltfm_mgr_pwr_supply_info_get_args() + args.ps_num = ps_num + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_pwr_supply_info_get(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_pwr_supply_info_get_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_pwr_supply_info_get failed: unknown result") + + def pltfm_mgr_pwr_rail_info_get(self, ps_num): + """ + Parameters: + - ps_num + """ + self.send_pltfm_mgr_pwr_rail_info_get(ps_num) + return self.recv_pltfm_mgr_pwr_rail_info_get() + + def send_pltfm_mgr_pwr_rail_info_get(self, ps_num): + self._oprot.writeMessageBegin('pltfm_mgr_pwr_rail_info_get', TMessageType.CALL, self._seqid) + args = pltfm_mgr_pwr_rail_info_get_args() + args.ps_num = ps_num + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_pwr_rail_info_get(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_pwr_rail_info_get_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_pwr_rail_info_get failed: unknown result") + + def pltfm_mgr_fan_speed_set(self, fan_num, percent): + """ + Parameters: + - fan_num + - percent + """ + self.send_pltfm_mgr_fan_speed_set(fan_num, percent) + return self.recv_pltfm_mgr_fan_speed_set() + + def send_pltfm_mgr_fan_speed_set(self, fan_num, percent): + self._oprot.writeMessageBegin('pltfm_mgr_fan_speed_set', TMessageType.CALL, self._seqid) + args = pltfm_mgr_fan_speed_set_args() + args.fan_num = fan_num + args.percent = percent + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_fan_speed_set(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_fan_speed_set_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_fan_speed_set failed: unknown result") + + def pltfm_mgr_fan_info_get(self, fan_num): + """ + Parameters: + - fan_num + """ + self.send_pltfm_mgr_fan_info_get(fan_num) + return self.recv_pltfm_mgr_fan_info_get() + + def send_pltfm_mgr_fan_info_get(self, fan_num): + self._oprot.writeMessageBegin('pltfm_mgr_fan_info_get', TMessageType.CALL, self._seqid) + args = pltfm_mgr_fan_info_get_args() + args.fan_num = fan_num + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_fan_info_get(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_fan_info_get_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_fan_info_get failed: unknown result") + + def pltfm_mgr_qsfp_presence_get(self, port_num): + """ + Parameters: + - port_num + """ + self.send_pltfm_mgr_qsfp_presence_get(port_num) + return self.recv_pltfm_mgr_qsfp_presence_get() + + def send_pltfm_mgr_qsfp_presence_get(self, port_num): + self._oprot.writeMessageBegin('pltfm_mgr_qsfp_presence_get', TMessageType.CALL, self._seqid) + args = pltfm_mgr_qsfp_presence_get_args() + args.port_num = port_num + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_qsfp_presence_get(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_qsfp_presence_get_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_qsfp_presence_get failed: unknown result") + + def pltfm_mgr_qsfp_info_get(self, port_num): + """ + Parameters: + - port_num + """ + self.send_pltfm_mgr_qsfp_info_get(port_num) + return self.recv_pltfm_mgr_qsfp_info_get() + + def send_pltfm_mgr_qsfp_info_get(self, port_num): + self._oprot.writeMessageBegin('pltfm_mgr_qsfp_info_get', TMessageType.CALL, self._seqid) + args = pltfm_mgr_qsfp_info_get_args() + args.port_num = port_num + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_qsfp_info_get(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_qsfp_info_get_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_qsfp_info_get failed: unknown result") + + def pltfm_mgr_qsfp_get_max_port(self): + self.send_pltfm_mgr_qsfp_get_max_port() + return self.recv_pltfm_mgr_qsfp_get_max_port() + + def send_pltfm_mgr_qsfp_get_max_port(self): + self._oprot.writeMessageBegin('pltfm_mgr_qsfp_get_max_port', TMessageType.CALL, self._seqid) + args = pltfm_mgr_qsfp_get_max_port_args() + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_qsfp_get_max_port(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_qsfp_get_max_port_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_qsfp_get_max_port failed: unknown result") + + def pltfm_mgr_qsfp_reset(self, port_num, reset): + """ + Parameters: + - port_num + - reset + """ + self.send_pltfm_mgr_qsfp_reset(port_num, reset) + return self.recv_pltfm_mgr_qsfp_reset() + + def send_pltfm_mgr_qsfp_reset(self, port_num, reset): + self._oprot.writeMessageBegin('pltfm_mgr_qsfp_reset', TMessageType.CALL, self._seqid) + args = pltfm_mgr_qsfp_reset_args() + args.port_num = port_num + args.reset = reset + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_qsfp_reset(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_qsfp_reset_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_qsfp_reset failed: unknown result") + + def pltfm_mgr_qsfp_lpmode_get(self, port_num): + """ + Parameters: + - port_num + """ + self.send_pltfm_mgr_qsfp_lpmode_get(port_num) + return self.recv_pltfm_mgr_qsfp_lpmode_get() + + def send_pltfm_mgr_qsfp_lpmode_get(self, port_num): + self._oprot.writeMessageBegin('pltfm_mgr_qsfp_lpmode_get', TMessageType.CALL, self._seqid) + args = pltfm_mgr_qsfp_lpmode_get_args() + args.port_num = port_num + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_qsfp_lpmode_get(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_qsfp_lpmode_get_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_qsfp_lpmode_get failed: unknown result") + + def pltfm_mgr_qsfp_lpmode_set(self, port_num, lpmode): + """ + Parameters: + - port_num + - lpmode + """ + self.send_pltfm_mgr_qsfp_lpmode_set(port_num, lpmode) + return self.recv_pltfm_mgr_qsfp_lpmode_set() + + def send_pltfm_mgr_qsfp_lpmode_set(self, port_num, lpmode): + self._oprot.writeMessageBegin('pltfm_mgr_qsfp_lpmode_set', TMessageType.CALL, self._seqid) + args = pltfm_mgr_qsfp_lpmode_set_args() + args.port_num = port_num + args.lpmode = lpmode + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_qsfp_lpmode_set(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_qsfp_lpmode_set_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_qsfp_lpmode_set failed: unknown result") + + def pltfm_mgr_sensor_info_get(self, options): + """ + Parameters: + - options + """ + self.send_pltfm_mgr_sensor_info_get(options) + return self.recv_pltfm_mgr_sensor_info_get() + + def send_pltfm_mgr_sensor_info_get(self, options): + self._oprot.writeMessageBegin('pltfm_mgr_sensor_info_get', TMessageType.CALL, self._seqid) + args = pltfm_mgr_sensor_info_get_args() + args.options = options + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_sensor_info_get(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_sensor_info_get_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_sensor_info_get failed: unknown result") + + +class Processor(Iface, TProcessor): + def __init__(self, handler): + self._handler = handler + self._processMap = {} + self._processMap["pltfm_mgr_dummy"] = Processor.process_pltfm_mgr_dummy + self._processMap["pltfm_mgr_sys_tmp_get"] = Processor.process_pltfm_mgr_sys_tmp_get + self._processMap["pltfm_mgr_sys_eeprom_get"] = Processor.process_pltfm_mgr_sys_eeprom_get + self._processMap["pltfm_mgr_pwr_supply_present_get"] = Processor.process_pltfm_mgr_pwr_supply_present_get + self._processMap["pltfm_mgr_pwr_supply_info_get"] = Processor.process_pltfm_mgr_pwr_supply_info_get + self._processMap["pltfm_mgr_pwr_rail_info_get"] = Processor.process_pltfm_mgr_pwr_rail_info_get + self._processMap["pltfm_mgr_fan_speed_set"] = Processor.process_pltfm_mgr_fan_speed_set + self._processMap["pltfm_mgr_fan_info_get"] = Processor.process_pltfm_mgr_fan_info_get + self._processMap["pltfm_mgr_qsfp_presence_get"] = Processor.process_pltfm_mgr_qsfp_presence_get + self._processMap["pltfm_mgr_qsfp_info_get"] = Processor.process_pltfm_mgr_qsfp_info_get + self._processMap["pltfm_mgr_qsfp_get_max_port"] = Processor.process_pltfm_mgr_qsfp_get_max_port + self._processMap["pltfm_mgr_qsfp_reset"] = Processor.process_pltfm_mgr_qsfp_reset + self._processMap["pltfm_mgr_qsfp_lpmode_get"] = Processor.process_pltfm_mgr_qsfp_lpmode_get + self._processMap["pltfm_mgr_qsfp_lpmode_set"] = Processor.process_pltfm_mgr_qsfp_lpmode_set + self._processMap["pltfm_mgr_sensor_info_get"] = Processor.process_pltfm_mgr_sensor_info_get + + def process(self, iprot, oprot): + (name, type, seqid) = iprot.readMessageBegin() + if name not in self._processMap: + iprot.skip(TType.STRUCT) + iprot.readMessageEnd() + x = TApplicationException(TApplicationException.UNKNOWN_METHOD, 'Unknown function %s' % (name)) + oprot.writeMessageBegin(name, TMessageType.EXCEPTION, seqid) + x.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + return + else: + self._processMap[name](self, seqid, iprot, oprot) + return True + + def process_pltfm_mgr_dummy(self, seqid, iprot, oprot): + args = pltfm_mgr_dummy_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_dummy_result() + try: + result.success = self._handler.pltfm_mgr_dummy(args.device) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_dummy", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_sys_tmp_get(self, seqid, iprot, oprot): + args = pltfm_mgr_sys_tmp_get_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_sys_tmp_get_result() + try: + result.success = self._handler.pltfm_mgr_sys_tmp_get() + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_sys_tmp_get", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_sys_eeprom_get(self, seqid, iprot, oprot): + args = pltfm_mgr_sys_eeprom_get_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_sys_eeprom_get_result() + try: + result.success = self._handler.pltfm_mgr_sys_eeprom_get() + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_sys_eeprom_get", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_pwr_supply_present_get(self, seqid, iprot, oprot): + args = pltfm_mgr_pwr_supply_present_get_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_pwr_supply_present_get_result() + try: + result.success = self._handler.pltfm_mgr_pwr_supply_present_get(args.ps_num) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_pwr_supply_present_get", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_pwr_supply_info_get(self, seqid, iprot, oprot): + args = pltfm_mgr_pwr_supply_info_get_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_pwr_supply_info_get_result() + try: + result.success = self._handler.pltfm_mgr_pwr_supply_info_get(args.ps_num) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_pwr_supply_info_get", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_pwr_rail_info_get(self, seqid, iprot, oprot): + args = pltfm_mgr_pwr_rail_info_get_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_pwr_rail_info_get_result() + try: + result.success = self._handler.pltfm_mgr_pwr_rail_info_get(args.ps_num) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_pwr_rail_info_get", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_fan_speed_set(self, seqid, iprot, oprot): + args = pltfm_mgr_fan_speed_set_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_fan_speed_set_result() + try: + result.success = self._handler.pltfm_mgr_fan_speed_set(args.fan_num, args.percent) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_fan_speed_set", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_fan_info_get(self, seqid, iprot, oprot): + args = pltfm_mgr_fan_info_get_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_fan_info_get_result() + try: + result.success = self._handler.pltfm_mgr_fan_info_get(args.fan_num) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_fan_info_get", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_qsfp_presence_get(self, seqid, iprot, oprot): + args = pltfm_mgr_qsfp_presence_get_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_qsfp_presence_get_result() + try: + result.success = self._handler.pltfm_mgr_qsfp_presence_get(args.port_num) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_qsfp_presence_get", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_qsfp_info_get(self, seqid, iprot, oprot): + args = pltfm_mgr_qsfp_info_get_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_qsfp_info_get_result() + try: + result.success = self._handler.pltfm_mgr_qsfp_info_get(args.port_num) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_qsfp_info_get", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_qsfp_get_max_port(self, seqid, iprot, oprot): + args = pltfm_mgr_qsfp_get_max_port_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_qsfp_get_max_port_result() + try: + result.success = self._handler.pltfm_mgr_qsfp_get_max_port() + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_qsfp_get_max_port", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_qsfp_reset(self, seqid, iprot, oprot): + args = pltfm_mgr_qsfp_reset_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_qsfp_reset_result() + try: + result.success = self._handler.pltfm_mgr_qsfp_reset(args.port_num, args.reset) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_qsfp_reset", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_qsfp_lpmode_get(self, seqid, iprot, oprot): + args = pltfm_mgr_qsfp_lpmode_get_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_qsfp_lpmode_get_result() + try: + result.success = self._handler.pltfm_mgr_qsfp_lpmode_get(args.port_num) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_qsfp_lpmode_get", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_qsfp_lpmode_set(self, seqid, iprot, oprot): + args = pltfm_mgr_qsfp_lpmode_set_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_qsfp_lpmode_set_result() + try: + result.success = self._handler.pltfm_mgr_qsfp_lpmode_set(args.port_num, args.lpmode) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_qsfp_lpmode_set", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_sensor_info_get(self, seqid, iprot, oprot): + args = pltfm_mgr_sensor_info_get_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_sensor_info_get_result() + try: + result.success = self._handler.pltfm_mgr_sensor_info_get(args.options) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_sensor_info_get", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + +# HELPER FUNCTIONS AND STRUCTURES + + +class pltfm_mgr_dummy_args(object): + """ + Attributes: + - device + """ + + thrift_spec = ( + None, # 0 + (1, TType.BYTE, 'device', None, None, ), # 1 + ) + + def __init__(self, device=None,): + self.device = device + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.BYTE: + self.device = iprot.readByte() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_dummy_args') + if self.device is not None: + oprot.writeFieldBegin('device', TType.BYTE, 1) + oprot.writeByte(self.device) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_dummy_result(object): + """ + Attributes: + - success + """ + + thrift_spec = ( + (0, TType.I32, 'success', None, None, ), # 0 + ) + + def __init__(self, success=None,): + self.success = success + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.I32: + self.success = iprot.readI32() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_dummy_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.I32, 0) + oprot.writeI32(self.success) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_sys_tmp_get_args(object): + + thrift_spec = ( + ) + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_sys_tmp_get_args') + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_sys_tmp_get_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.STRUCT, 'success', (pltfm_mgr_sys_tmp_t, pltfm_mgr_sys_tmp_t.thrift_spec), None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.STRUCT: + self.success = pltfm_mgr_sys_tmp_t() + self.success.read(iprot) + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_sys_tmp_get_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.STRUCT, 0) + self.success.write(oprot) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_sys_eeprom_get_args(object): + + thrift_spec = ( + ) + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_sys_eeprom_get_args') + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_sys_eeprom_get_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.STRUCT, 'success', (pltfm_mgr_eeprom_t, pltfm_mgr_eeprom_t.thrift_spec), None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.STRUCT: + self.success = pltfm_mgr_eeprom_t() + self.success.read(iprot) + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_sys_eeprom_get_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.STRUCT, 0) + self.success.write(oprot) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_pwr_supply_present_get_args(object): + """ + Attributes: + - ps_num + """ + + thrift_spec = ( + None, # 0 + (1, TType.I16, 'ps_num', None, None, ), # 1 + ) + + def __init__(self, ps_num=None,): + self.ps_num = ps_num + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I16: + self.ps_num = iprot.readI16() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_pwr_supply_present_get_args') + if self.ps_num is not None: + oprot.writeFieldBegin('ps_num', TType.I16, 1) + oprot.writeI16(self.ps_num) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_pwr_supply_present_get_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.BOOL, 'success', None, None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.BOOL: + self.success = iprot.readBool() + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_pwr_supply_present_get_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.BOOL, 0) + oprot.writeBool(self.success) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_pwr_supply_info_get_args(object): + """ + Attributes: + - ps_num + """ + + thrift_spec = ( + None, # 0 + (1, TType.I16, 'ps_num', None, None, ), # 1 + ) + + def __init__(self, ps_num=None,): + self.ps_num = ps_num + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I16: + self.ps_num = iprot.readI16() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_pwr_supply_info_get_args') + if self.ps_num is not None: + oprot.writeFieldBegin('ps_num', TType.I16, 1) + oprot.writeI16(self.ps_num) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_pwr_supply_info_get_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.STRUCT, 'success', (pltfm_mgr_pwr_supply_info_t, pltfm_mgr_pwr_supply_info_t.thrift_spec), None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.STRUCT: + self.success = pltfm_mgr_pwr_supply_info_t() + self.success.read(iprot) + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_pwr_supply_info_get_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.STRUCT, 0) + self.success.write(oprot) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_pwr_rail_info_get_args(object): + """ + Attributes: + - ps_num + """ + + thrift_spec = ( + None, # 0 + (1, TType.I16, 'ps_num', None, None, ), # 1 + ) + + def __init__(self, ps_num=None,): + self.ps_num = ps_num + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I16: + self.ps_num = iprot.readI16() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_pwr_rail_info_get_args') + if self.ps_num is not None: + oprot.writeFieldBegin('ps_num', TType.I16, 1) + oprot.writeI16(self.ps_num) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_pwr_rail_info_get_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.STRUCT, 'success', (pltfm_mgr_pwr_rail_info_t, pltfm_mgr_pwr_rail_info_t.thrift_spec), None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.STRUCT: + self.success = pltfm_mgr_pwr_rail_info_t() + self.success.read(iprot) + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_pwr_rail_info_get_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.STRUCT, 0) + self.success.write(oprot) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_fan_speed_set_args(object): + """ + Attributes: + - fan_num + - percent + """ + + thrift_spec = ( + None, # 0 + (1, TType.I32, 'fan_num', None, None, ), # 1 + (2, TType.I32, 'percent', None, None, ), # 2 + ) + + def __init__(self, fan_num=None, percent=None,): + self.fan_num = fan_num + self.percent = percent + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I32: + self.fan_num = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.I32: + self.percent = iprot.readI32() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_fan_speed_set_args') + if self.fan_num is not None: + oprot.writeFieldBegin('fan_num', TType.I32, 1) + oprot.writeI32(self.fan_num) + oprot.writeFieldEnd() + if self.percent is not None: + oprot.writeFieldBegin('percent', TType.I32, 2) + oprot.writeI32(self.percent) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_fan_speed_set_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.I32, 'success', None, None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.I32: + self.success = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_fan_speed_set_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.I32, 0) + oprot.writeI32(self.success) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_fan_info_get_args(object): + """ + Attributes: + - fan_num + """ + + thrift_spec = ( + None, # 0 + (1, TType.I32, 'fan_num', None, None, ), # 1 + ) + + def __init__(self, fan_num=None,): + self.fan_num = fan_num + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I32: + self.fan_num = iprot.readI32() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_fan_info_get_args') + if self.fan_num is not None: + oprot.writeFieldBegin('fan_num', TType.I32, 1) + oprot.writeI32(self.fan_num) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_fan_info_get_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.STRUCT, 'success', (pltfm_mgr_fan_info_t, pltfm_mgr_fan_info_t.thrift_spec), None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.STRUCT: + self.success = pltfm_mgr_fan_info_t() + self.success.read(iprot) + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_fan_info_get_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.STRUCT, 0) + self.success.write(oprot) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_presence_get_args(object): + """ + Attributes: + - port_num + """ + + thrift_spec = ( + None, # 0 + (1, TType.I32, 'port_num', None, None, ), # 1 + ) + + def __init__(self, port_num=None,): + self.port_num = port_num + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I32: + self.port_num = iprot.readI32() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_presence_get_args') + if self.port_num is not None: + oprot.writeFieldBegin('port_num', TType.I32, 1) + oprot.writeI32(self.port_num) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_presence_get_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.BOOL, 'success', None, None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.BOOL: + self.success = iprot.readBool() + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_presence_get_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.BOOL, 0) + oprot.writeBool(self.success) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_info_get_args(object): + """ + Attributes: + - port_num + """ + + thrift_spec = ( + None, # 0 + (1, TType.I32, 'port_num', None, None, ), # 1 + ) + + def __init__(self, port_num=None,): + self.port_num = port_num + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I32: + self.port_num = iprot.readI32() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_info_get_args') + if self.port_num is not None: + oprot.writeFieldBegin('port_num', TType.I32, 1) + oprot.writeI32(self.port_num) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_info_get_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.STRING, 'success', 'UTF8', None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.STRING: + self.success = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_info_get_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.STRING, 0) + oprot.writeString(self.success.encode('utf-8') if sys.version_info[0] == 2 else self.success) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_get_max_port_args(object): + + thrift_spec = ( + ) + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_get_max_port_args') + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_get_max_port_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.I32, 'success', None, None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.I32: + self.success = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_get_max_port_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.I32, 0) + oprot.writeI32(self.success) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_reset_args(object): + """ + Attributes: + - port_num + - reset + """ + + thrift_spec = ( + None, # 0 + (1, TType.I32, 'port_num', None, None, ), # 1 + (2, TType.BOOL, 'reset', None, None, ), # 2 + ) + + def __init__(self, port_num=None, reset=None,): + self.port_num = port_num + self.reset = reset + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I32: + self.port_num = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.BOOL: + self.reset = iprot.readBool() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_reset_args') + if self.port_num is not None: + oprot.writeFieldBegin('port_num', TType.I32, 1) + oprot.writeI32(self.port_num) + oprot.writeFieldEnd() + if self.reset is not None: + oprot.writeFieldBegin('reset', TType.BOOL, 2) + oprot.writeBool(self.reset) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_reset_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.I32, 'success', None, None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.I32: + self.success = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_reset_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.I32, 0) + oprot.writeI32(self.success) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_lpmode_get_args(object): + """ + Attributes: + - port_num + """ + + thrift_spec = ( + None, # 0 + (1, TType.I32, 'port_num', None, None, ), # 1 + ) + + def __init__(self, port_num=None,): + self.port_num = port_num + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I32: + self.port_num = iprot.readI32() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_lpmode_get_args') + if self.port_num is not None: + oprot.writeFieldBegin('port_num', TType.I32, 1) + oprot.writeI32(self.port_num) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_lpmode_get_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.BOOL, 'success', None, None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.BOOL: + self.success = iprot.readBool() + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_lpmode_get_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.BOOL, 0) + oprot.writeBool(self.success) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_lpmode_set_args(object): + """ + Attributes: + - port_num + - lpmode + """ + + thrift_spec = ( + None, # 0 + (1, TType.I32, 'port_num', None, None, ), # 1 + (2, TType.BOOL, 'lpmode', None, None, ), # 2 + ) + + def __init__(self, port_num=None, lpmode=None,): + self.port_num = port_num + self.lpmode = lpmode + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I32: + self.port_num = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.BOOL: + self.lpmode = iprot.readBool() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_lpmode_set_args') + if self.port_num is not None: + oprot.writeFieldBegin('port_num', TType.I32, 1) + oprot.writeI32(self.port_num) + oprot.writeFieldEnd() + if self.lpmode is not None: + oprot.writeFieldBegin('lpmode', TType.BOOL, 2) + oprot.writeBool(self.lpmode) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_lpmode_set_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.I32, 'success', None, None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.I32: + self.success = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_lpmode_set_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.I32, 0) + oprot.writeI32(self.success) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_sensor_info_get_args(object): + """ + Attributes: + - options + """ + + thrift_spec = ( + None, # 0 + (1, TType.STRING, 'options', 'UTF8', None, ), # 1 + ) + + def __init__(self, options=None,): + self.options = options + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.STRING: + self.options = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_sensor_info_get_args') + if self.options is not None: + oprot.writeFieldBegin('options', TType.STRING, 1) + oprot.writeString(self.options.encode('utf-8') if sys.version_info[0] == 2 else self.options) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_sensor_info_get_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.STRING, 'success', 'UTF8', None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.STRING: + self.success = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_sensor_info_get_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.STRING, 0) + oprot.writeString(self.success.encode('utf-8') if sys.version_info[0] == 2 else self.success) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/ttypes.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/ttypes.py new file mode 100644 index 000000000000..ce03e14f8691 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/ttypes.py @@ -0,0 +1,1060 @@ +# +# Autogenerated by Thrift Compiler (0.10.0) +# +# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING +# +# options string: py +# + +from thrift.Thrift import TType, TMessageType, TFrozenDict, TException, TApplicationException +from thrift.protocol.TProtocol import TProtocolException +import sys + +from thrift.transport import TTransport + + +class pltfm_mgr_sys_tmp_t(object): + """ + Attributes: + - tmp1 + - tmp2 + - tmp3 + - tmp4 + - tmp5 + - tmp6 + - tmp7 + - tmp8 + - tmp9 + - tmp10 + """ + + thrift_spec = ( + None, # 0 + (1, TType.DOUBLE, 'tmp1', None, None, ), # 1 + (2, TType.DOUBLE, 'tmp2', None, None, ), # 2 + (3, TType.DOUBLE, 'tmp3', None, None, ), # 3 + (4, TType.DOUBLE, 'tmp4', None, None, ), # 4 + (5, TType.DOUBLE, 'tmp5', None, None, ), # 5 + (6, TType.DOUBLE, 'tmp6', None, None, ), # 6 + (7, TType.DOUBLE, 'tmp7', None, None, ), # 7 + (8, TType.DOUBLE, 'tmp8', None, None, ), # 8 + (9, TType.DOUBLE, 'tmp9', None, None, ), # 9 + (10, TType.DOUBLE, 'tmp10', None, None, ), # 10 + ) + + def __init__(self, tmp1=None, tmp2=None, tmp3=None, tmp4=None, tmp5=None, tmp6=None, tmp7=None, tmp8=None, tmp9=None, tmp10=None,): + self.tmp1 = tmp1 + self.tmp2 = tmp2 + self.tmp3 = tmp3 + self.tmp4 = tmp4 + self.tmp5 = tmp5 + self.tmp6 = tmp6 + self.tmp7 = tmp7 + self.tmp8 = tmp8 + self.tmp9 = tmp9 + self.tmp10 = tmp10 + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.DOUBLE: + self.tmp1 = iprot.readDouble() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.DOUBLE: + self.tmp2 = iprot.readDouble() + else: + iprot.skip(ftype) + elif fid == 3: + if ftype == TType.DOUBLE: + self.tmp3 = iprot.readDouble() + else: + iprot.skip(ftype) + elif fid == 4: + if ftype == TType.DOUBLE: + self.tmp4 = iprot.readDouble() + else: + iprot.skip(ftype) + elif fid == 5: + if ftype == TType.DOUBLE: + self.tmp5 = iprot.readDouble() + else: + iprot.skip(ftype) + elif fid == 6: + if ftype == TType.DOUBLE: + self.tmp6 = iprot.readDouble() + else: + iprot.skip(ftype) + elif fid == 7: + if ftype == TType.DOUBLE: + self.tmp7 = iprot.readDouble() + else: + iprot.skip(ftype) + elif fid == 8: + if ftype == TType.DOUBLE: + self.tmp8 = iprot.readDouble() + else: + iprot.skip(ftype) + elif fid == 9: + if ftype == TType.DOUBLE: + self.tmp9 = iprot.readDouble() + else: + iprot.skip(ftype) + elif fid == 10: + if ftype == TType.DOUBLE: + self.tmp10 = iprot.readDouble() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_sys_tmp_t') + if self.tmp1 is not None: + oprot.writeFieldBegin('tmp1', TType.DOUBLE, 1) + oprot.writeDouble(self.tmp1) + oprot.writeFieldEnd() + if self.tmp2 is not None: + oprot.writeFieldBegin('tmp2', TType.DOUBLE, 2) + oprot.writeDouble(self.tmp2) + oprot.writeFieldEnd() + if self.tmp3 is not None: + oprot.writeFieldBegin('tmp3', TType.DOUBLE, 3) + oprot.writeDouble(self.tmp3) + oprot.writeFieldEnd() + if self.tmp4 is not None: + oprot.writeFieldBegin('tmp4', TType.DOUBLE, 4) + oprot.writeDouble(self.tmp4) + oprot.writeFieldEnd() + if self.tmp5 is not None: + oprot.writeFieldBegin('tmp5', TType.DOUBLE, 5) + oprot.writeDouble(self.tmp5) + oprot.writeFieldEnd() + if self.tmp6 is not None: + oprot.writeFieldBegin('tmp6', TType.DOUBLE, 6) + oprot.writeDouble(self.tmp6) + oprot.writeFieldEnd() + if self.tmp7 is not None: + oprot.writeFieldBegin('tmp7', TType.DOUBLE, 7) + oprot.writeDouble(self.tmp7) + oprot.writeFieldEnd() + if self.tmp8 is not None: + oprot.writeFieldBegin('tmp8', TType.DOUBLE, 8) + oprot.writeDouble(self.tmp8) + oprot.writeFieldEnd() + if self.tmp9 is not None: + oprot.writeFieldBegin('tmp9', TType.DOUBLE, 9) + oprot.writeDouble(self.tmp9) + oprot.writeFieldEnd() + if self.tmp10 is not None: + oprot.writeFieldBegin('tmp10', TType.DOUBLE, 10) + oprot.writeDouble(self.tmp10) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_eeprom_t(object): + """ + Attributes: + - version + - prod_name + - prod_part_num + - sys_asm_part_num + - bfn_pcba_part_num + - bfn_pcbb_part_num + - odm_pcba_part_num + - odm_pcba_ser_num + - prod_state + - prod_ver + - prod_sub_ver + - prod_ser_num + - prod_ast_tag + - sys_mfger + - sys_mfg_date + - pcb_mfger + - assembled_at + - loc_mac_addr + - ext_mac_addr + - ext_mac_addr_size + - location + - crc8 + """ + + thrift_spec = ( + None, # 0 + (1, TType.I16, 'version', None, None, ), # 1 + (2, TType.STRING, 'prod_name', 'UTF8', None, ), # 2 + (3, TType.STRING, 'prod_part_num', 'UTF8', None, ), # 3 + (4, TType.STRING, 'sys_asm_part_num', 'UTF8', None, ), # 4 + (5, TType.STRING, 'bfn_pcba_part_num', 'UTF8', None, ), # 5 + (6, TType.STRING, 'bfn_pcbb_part_num', 'UTF8', None, ), # 6 + (7, TType.STRING, 'odm_pcba_part_num', 'UTF8', None, ), # 7 + (8, TType.STRING, 'odm_pcba_ser_num', 'UTF8', None, ), # 8 + (9, TType.I16, 'prod_state', None, None, ), # 9 + (10, TType.I16, 'prod_ver', None, None, ), # 10 + (11, TType.I16, 'prod_sub_ver', None, None, ), # 11 + (12, TType.STRING, 'prod_ser_num', 'UTF8', None, ), # 12 + (13, TType.STRING, 'prod_ast_tag', 'UTF8', None, ), # 13 + (14, TType.STRING, 'sys_mfger', 'UTF8', None, ), # 14 + (15, TType.STRING, 'sys_mfg_date', 'UTF8', None, ), # 15 + (16, TType.STRING, 'pcb_mfger', 'UTF8', None, ), # 16 + (17, TType.STRING, 'assembled_at', 'UTF8', None, ), # 17 + (18, TType.STRING, 'loc_mac_addr', 'UTF8', None, ), # 18 + (19, TType.STRING, 'ext_mac_addr', 'UTF8', None, ), # 19 + (20, TType.I32, 'ext_mac_addr_size', None, None, ), # 20 + (21, TType.STRING, 'location', 'UTF8', None, ), # 21 + (22, TType.I16, 'crc8', None, None, ), # 22 + ) + + def __init__(self, version=None, prod_name=None, prod_part_num=None, sys_asm_part_num=None, bfn_pcba_part_num=None, bfn_pcbb_part_num=None, odm_pcba_part_num=None, odm_pcba_ser_num=None, prod_state=None, prod_ver=None, prod_sub_ver=None, prod_ser_num=None, prod_ast_tag=None, sys_mfger=None, sys_mfg_date=None, pcb_mfger=None, assembled_at=None, loc_mac_addr=None, ext_mac_addr=None, ext_mac_addr_size=None, location=None, crc8=None,): + self.version = version + self.prod_name = prod_name + self.prod_part_num = prod_part_num + self.sys_asm_part_num = sys_asm_part_num + self.bfn_pcba_part_num = bfn_pcba_part_num + self.bfn_pcbb_part_num = bfn_pcbb_part_num + self.odm_pcba_part_num = odm_pcba_part_num + self.odm_pcba_ser_num = odm_pcba_ser_num + self.prod_state = prod_state + self.prod_ver = prod_ver + self.prod_sub_ver = prod_sub_ver + self.prod_ser_num = prod_ser_num + self.prod_ast_tag = prod_ast_tag + self.sys_mfger = sys_mfger + self.sys_mfg_date = sys_mfg_date + self.pcb_mfger = pcb_mfger + self.assembled_at = assembled_at + self.loc_mac_addr = loc_mac_addr + self.ext_mac_addr = ext_mac_addr + self.ext_mac_addr_size = ext_mac_addr_size + self.location = location + self.crc8 = crc8 + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I16: + self.version = iprot.readI16() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.STRING: + self.prod_name = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 3: + if ftype == TType.STRING: + self.prod_part_num = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 4: + if ftype == TType.STRING: + self.sys_asm_part_num = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 5: + if ftype == TType.STRING: + self.bfn_pcba_part_num = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 6: + if ftype == TType.STRING: + self.bfn_pcbb_part_num = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 7: + if ftype == TType.STRING: + self.odm_pcba_part_num = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 8: + if ftype == TType.STRING: + self.odm_pcba_ser_num = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 9: + if ftype == TType.I16: + self.prod_state = iprot.readI16() + else: + iprot.skip(ftype) + elif fid == 10: + if ftype == TType.I16: + self.prod_ver = iprot.readI16() + else: + iprot.skip(ftype) + elif fid == 11: + if ftype == TType.I16: + self.prod_sub_ver = iprot.readI16() + else: + iprot.skip(ftype) + elif fid == 12: + if ftype == TType.STRING: + self.prod_ser_num = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 13: + if ftype == TType.STRING: + self.prod_ast_tag = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 14: + if ftype == TType.STRING: + self.sys_mfger = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 15: + if ftype == TType.STRING: + self.sys_mfg_date = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 16: + if ftype == TType.STRING: + self.pcb_mfger = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 17: + if ftype == TType.STRING: + self.assembled_at = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 18: + if ftype == TType.STRING: + self.loc_mac_addr = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 19: + if ftype == TType.STRING: + self.ext_mac_addr = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 20: + if ftype == TType.I32: + self.ext_mac_addr_size = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 21: + if ftype == TType.STRING: + self.location = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 22: + if ftype == TType.I16: + self.crc8 = iprot.readI16() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_eeprom_t') + if self.version is not None: + oprot.writeFieldBegin('version', TType.I16, 1) + oprot.writeI16(self.version) + oprot.writeFieldEnd() + if self.prod_name is not None: + oprot.writeFieldBegin('prod_name', TType.STRING, 2) + oprot.writeString(self.prod_name.encode('utf-8') if sys.version_info[0] == 2 else self.prod_name) + oprot.writeFieldEnd() + if self.prod_part_num is not None: + oprot.writeFieldBegin('prod_part_num', TType.STRING, 3) + oprot.writeString(self.prod_part_num.encode('utf-8') if sys.version_info[0] == 2 else self.prod_part_num) + oprot.writeFieldEnd() + if self.sys_asm_part_num is not None: + oprot.writeFieldBegin('sys_asm_part_num', TType.STRING, 4) + oprot.writeString(self.sys_asm_part_num.encode('utf-8') if sys.version_info[0] == 2 else self.sys_asm_part_num) + oprot.writeFieldEnd() + if self.bfn_pcba_part_num is not None: + oprot.writeFieldBegin('bfn_pcba_part_num', TType.STRING, 5) + oprot.writeString(self.bfn_pcba_part_num.encode('utf-8') if sys.version_info[0] == 2 else self.bfn_pcba_part_num) + oprot.writeFieldEnd() + if self.bfn_pcbb_part_num is not None: + oprot.writeFieldBegin('bfn_pcbb_part_num', TType.STRING, 6) + oprot.writeString(self.bfn_pcbb_part_num.encode('utf-8') if sys.version_info[0] == 2 else self.bfn_pcbb_part_num) + oprot.writeFieldEnd() + if self.odm_pcba_part_num is not None: + oprot.writeFieldBegin('odm_pcba_part_num', TType.STRING, 7) + oprot.writeString(self.odm_pcba_part_num.encode('utf-8') if sys.version_info[0] == 2 else self.odm_pcba_part_num) + oprot.writeFieldEnd() + if self.odm_pcba_ser_num is not None: + oprot.writeFieldBegin('odm_pcba_ser_num', TType.STRING, 8) + oprot.writeString(self.odm_pcba_ser_num.encode('utf-8') if sys.version_info[0] == 2 else self.odm_pcba_ser_num) + oprot.writeFieldEnd() + if self.prod_state is not None: + oprot.writeFieldBegin('prod_state', TType.I16, 9) + oprot.writeI16(self.prod_state) + oprot.writeFieldEnd() + if self.prod_ver is not None: + oprot.writeFieldBegin('prod_ver', TType.I16, 10) + oprot.writeI16(self.prod_ver) + oprot.writeFieldEnd() + if self.prod_sub_ver is not None: + oprot.writeFieldBegin('prod_sub_ver', TType.I16, 11) + oprot.writeI16(self.prod_sub_ver) + oprot.writeFieldEnd() + if self.prod_ser_num is not None: + oprot.writeFieldBegin('prod_ser_num', TType.STRING, 12) + oprot.writeString(self.prod_ser_num.encode('utf-8') if sys.version_info[0] == 2 else self.prod_ser_num) + oprot.writeFieldEnd() + if self.prod_ast_tag is not None: + oprot.writeFieldBegin('prod_ast_tag', TType.STRING, 13) + oprot.writeString(self.prod_ast_tag.encode('utf-8') if sys.version_info[0] == 2 else self.prod_ast_tag) + oprot.writeFieldEnd() + if self.sys_mfger is not None: + oprot.writeFieldBegin('sys_mfger', TType.STRING, 14) + oprot.writeString(self.sys_mfger.encode('utf-8') if sys.version_info[0] == 2 else self.sys_mfger) + oprot.writeFieldEnd() + if self.sys_mfg_date is not None: + oprot.writeFieldBegin('sys_mfg_date', TType.STRING, 15) + oprot.writeString(self.sys_mfg_date.encode('utf-8') if sys.version_info[0] == 2 else self.sys_mfg_date) + oprot.writeFieldEnd() + if self.pcb_mfger is not None: + oprot.writeFieldBegin('pcb_mfger', TType.STRING, 16) + oprot.writeString(self.pcb_mfger.encode('utf-8') if sys.version_info[0] == 2 else self.pcb_mfger) + oprot.writeFieldEnd() + if self.assembled_at is not None: + oprot.writeFieldBegin('assembled_at', TType.STRING, 17) + oprot.writeString(self.assembled_at.encode('utf-8') if sys.version_info[0] == 2 else self.assembled_at) + oprot.writeFieldEnd() + if self.loc_mac_addr is not None: + oprot.writeFieldBegin('loc_mac_addr', TType.STRING, 18) + oprot.writeString(self.loc_mac_addr.encode('utf-8') if sys.version_info[0] == 2 else self.loc_mac_addr) + oprot.writeFieldEnd() + if self.ext_mac_addr is not None: + oprot.writeFieldBegin('ext_mac_addr', TType.STRING, 19) + oprot.writeString(self.ext_mac_addr.encode('utf-8') if sys.version_info[0] == 2 else self.ext_mac_addr) + oprot.writeFieldEnd() + if self.ext_mac_addr_size is not None: + oprot.writeFieldBegin('ext_mac_addr_size', TType.I32, 20) + oprot.writeI32(self.ext_mac_addr_size) + oprot.writeFieldEnd() + if self.location is not None: + oprot.writeFieldBegin('location', TType.STRING, 21) + oprot.writeString(self.location.encode('utf-8') if sys.version_info[0] == 2 else self.location) + oprot.writeFieldEnd() + if self.crc8 is not None: + oprot.writeFieldBegin('crc8', TType.I16, 22) + oprot.writeI16(self.crc8) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_pwr_supply_info_t(object): + """ + Attributes: + - vin + - vout + - iout + - pwr_out + - fspeed + - ffault + - load_sharing + - model + - serial + - rev + """ + + thrift_spec = ( + None, # 0 + (1, TType.I32, 'vin', None, None, ), # 1 + (2, TType.I32, 'vout', None, None, ), # 2 + (3, TType.I32, 'iout', None, None, ), # 3 + (4, TType.I32, 'pwr_out', None, None, ), # 4 + (5, TType.I32, 'fspeed', None, None, ), # 5 + (6, TType.BOOL, 'ffault', None, None, ), # 6 + (7, TType.BOOL, 'load_sharing', None, None, ), # 7 + (8, TType.STRING, 'model', 'UTF8', None, ), # 8 + (9, TType.STRING, 'serial', 'UTF8', None, ), # 9 + (10, TType.STRING, 'rev', 'UTF8', None, ), # 10 + ) + + def __init__(self, vin=None, vout=None, iout=None, pwr_out=None, fspeed=None, ffault=None, load_sharing=None, model=None, serial=None, rev=None,): + self.vin = vin + self.vout = vout + self.iout = iout + self.pwr_out = pwr_out + self.fspeed = fspeed + self.ffault = ffault + self.load_sharing = load_sharing + self.model = model + self.serial = serial + self.rev = rev + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I32: + self.vin = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.I32: + self.vout = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 3: + if ftype == TType.I32: + self.iout = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 4: + if ftype == TType.I32: + self.pwr_out = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 5: + if ftype == TType.I32: + self.fspeed = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 6: + if ftype == TType.BOOL: + self.ffault = iprot.readBool() + else: + iprot.skip(ftype) + elif fid == 7: + if ftype == TType.BOOL: + self.load_sharing = iprot.readBool() + else: + iprot.skip(ftype) + elif fid == 8: + if ftype == TType.STRING: + self.model = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 9: + if ftype == TType.STRING: + self.serial = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 10: + if ftype == TType.STRING: + self.rev = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_pwr_supply_info_t') + if self.vin is not None: + oprot.writeFieldBegin('vin', TType.I32, 1) + oprot.writeI32(self.vin) + oprot.writeFieldEnd() + if self.vout is not None: + oprot.writeFieldBegin('vout', TType.I32, 2) + oprot.writeI32(self.vout) + oprot.writeFieldEnd() + if self.iout is not None: + oprot.writeFieldBegin('iout', TType.I32, 3) + oprot.writeI32(self.iout) + oprot.writeFieldEnd() + if self.pwr_out is not None: + oprot.writeFieldBegin('pwr_out', TType.I32, 4) + oprot.writeI32(self.pwr_out) + oprot.writeFieldEnd() + if self.fspeed is not None: + oprot.writeFieldBegin('fspeed', TType.I32, 5) + oprot.writeI32(self.fspeed) + oprot.writeFieldEnd() + if self.ffault is not None: + oprot.writeFieldBegin('ffault', TType.BOOL, 6) + oprot.writeBool(self.ffault) + oprot.writeFieldEnd() + if self.load_sharing is not None: + oprot.writeFieldBegin('load_sharing', TType.BOOL, 7) + oprot.writeBool(self.load_sharing) + oprot.writeFieldEnd() + if self.model is not None: + oprot.writeFieldBegin('model', TType.STRING, 8) + oprot.writeString(self.model.encode('utf-8') if sys.version_info[0] == 2 else self.model) + oprot.writeFieldEnd() + if self.serial is not None: + oprot.writeFieldBegin('serial', TType.STRING, 9) + oprot.writeString(self.serial.encode('utf-8') if sys.version_info[0] == 2 else self.serial) + oprot.writeFieldEnd() + if self.rev is not None: + oprot.writeFieldBegin('rev', TType.STRING, 10) + oprot.writeString(self.rev.encode('utf-8') if sys.version_info[0] == 2 else self.rev) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_pwr_rail_info_t(object): + """ + Attributes: + - vrail1 + - vrail2 + - vrail3 + - vrail4 + - vrail5 + - vrail6 + - vrail7 + - vrail8 + - vrail9 + - vrail10 + - vrail11 + - vrail12 + - vrail13 + - vrail14 + - vrail15 + - vrail16 + """ + + thrift_spec = ( + None, # 0 + (1, TType.I32, 'vrail1', None, None, ), # 1 + (2, TType.I32, 'vrail2', None, None, ), # 2 + (3, TType.I32, 'vrail3', None, None, ), # 3 + (4, TType.I32, 'vrail4', None, None, ), # 4 + (5, TType.I32, 'vrail5', None, None, ), # 5 + (6, TType.I32, 'vrail6', None, None, ), # 6 + (7, TType.I32, 'vrail7', None, None, ), # 7 + (8, TType.I32, 'vrail8', None, None, ), # 8 + (9, TType.I32, 'vrail9', None, None, ), # 9 + (10, TType.I32, 'vrail10', None, None, ), # 10 + (11, TType.I32, 'vrail11', None, None, ), # 11 + (12, TType.I32, 'vrail12', None, None, ), # 12 + (13, TType.I32, 'vrail13', None, None, ), # 13 + (14, TType.I32, 'vrail14', None, None, ), # 14 + (15, TType.I32, 'vrail15', None, None, ), # 15 + (16, TType.I32, 'vrail16', None, None, ), # 16 + ) + + def __init__(self, vrail1=None, vrail2=None, vrail3=None, vrail4=None, vrail5=None, vrail6=None, vrail7=None, vrail8=None, vrail9=None, vrail10=None, vrail11=None, vrail12=None, vrail13=None, vrail14=None, vrail15=None, vrail16=None,): + self.vrail1 = vrail1 + self.vrail2 = vrail2 + self.vrail3 = vrail3 + self.vrail4 = vrail4 + self.vrail5 = vrail5 + self.vrail6 = vrail6 + self.vrail7 = vrail7 + self.vrail8 = vrail8 + self.vrail9 = vrail9 + self.vrail10 = vrail10 + self.vrail11 = vrail11 + self.vrail12 = vrail12 + self.vrail13 = vrail13 + self.vrail14 = vrail14 + self.vrail15 = vrail15 + self.vrail16 = vrail16 + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I32: + self.vrail1 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.I32: + self.vrail2 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 3: + if ftype == TType.I32: + self.vrail3 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 4: + if ftype == TType.I32: + self.vrail4 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 5: + if ftype == TType.I32: + self.vrail5 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 6: + if ftype == TType.I32: + self.vrail6 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 7: + if ftype == TType.I32: + self.vrail7 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 8: + if ftype == TType.I32: + self.vrail8 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 9: + if ftype == TType.I32: + self.vrail9 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 10: + if ftype == TType.I32: + self.vrail10 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 11: + if ftype == TType.I32: + self.vrail11 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 12: + if ftype == TType.I32: + self.vrail12 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 13: + if ftype == TType.I32: + self.vrail13 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 14: + if ftype == TType.I32: + self.vrail14 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 15: + if ftype == TType.I32: + self.vrail15 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 16: + if ftype == TType.I32: + self.vrail16 = iprot.readI32() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_pwr_rail_info_t') + if self.vrail1 is not None: + oprot.writeFieldBegin('vrail1', TType.I32, 1) + oprot.writeI32(self.vrail1) + oprot.writeFieldEnd() + if self.vrail2 is not None: + oprot.writeFieldBegin('vrail2', TType.I32, 2) + oprot.writeI32(self.vrail2) + oprot.writeFieldEnd() + if self.vrail3 is not None: + oprot.writeFieldBegin('vrail3', TType.I32, 3) + oprot.writeI32(self.vrail3) + oprot.writeFieldEnd() + if self.vrail4 is not None: + oprot.writeFieldBegin('vrail4', TType.I32, 4) + oprot.writeI32(self.vrail4) + oprot.writeFieldEnd() + if self.vrail5 is not None: + oprot.writeFieldBegin('vrail5', TType.I32, 5) + oprot.writeI32(self.vrail5) + oprot.writeFieldEnd() + if self.vrail6 is not None: + oprot.writeFieldBegin('vrail6', TType.I32, 6) + oprot.writeI32(self.vrail6) + oprot.writeFieldEnd() + if self.vrail7 is not None: + oprot.writeFieldBegin('vrail7', TType.I32, 7) + oprot.writeI32(self.vrail7) + oprot.writeFieldEnd() + if self.vrail8 is not None: + oprot.writeFieldBegin('vrail8', TType.I32, 8) + oprot.writeI32(self.vrail8) + oprot.writeFieldEnd() + if self.vrail9 is not None: + oprot.writeFieldBegin('vrail9', TType.I32, 9) + oprot.writeI32(self.vrail9) + oprot.writeFieldEnd() + if self.vrail10 is not None: + oprot.writeFieldBegin('vrail10', TType.I32, 10) + oprot.writeI32(self.vrail10) + oprot.writeFieldEnd() + if self.vrail11 is not None: + oprot.writeFieldBegin('vrail11', TType.I32, 11) + oprot.writeI32(self.vrail11) + oprot.writeFieldEnd() + if self.vrail12 is not None: + oprot.writeFieldBegin('vrail12', TType.I32, 12) + oprot.writeI32(self.vrail12) + oprot.writeFieldEnd() + if self.vrail13 is not None: + oprot.writeFieldBegin('vrail13', TType.I32, 13) + oprot.writeI32(self.vrail13) + oprot.writeFieldEnd() + if self.vrail14 is not None: + oprot.writeFieldBegin('vrail14', TType.I32, 14) + oprot.writeI32(self.vrail14) + oprot.writeFieldEnd() + if self.vrail15 is not None: + oprot.writeFieldBegin('vrail15', TType.I32, 15) + oprot.writeI32(self.vrail15) + oprot.writeFieldEnd() + if self.vrail16 is not None: + oprot.writeFieldBegin('vrail16', TType.I32, 16) + oprot.writeI32(self.vrail16) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_fan_info_t(object): + """ + Attributes: + - fan_num + - front_rpm + - rear_rpm + - percent + """ + + thrift_spec = ( + None, # 0 + (1, TType.I32, 'fan_num', None, None, ), # 1 + (2, TType.I32, 'front_rpm', None, None, ), # 2 + (3, TType.I32, 'rear_rpm', None, None, ), # 3 + (4, TType.I32, 'percent', None, None, ), # 4 + ) + + def __init__(self, fan_num=None, front_rpm=None, rear_rpm=None, percent=None,): + self.fan_num = fan_num + self.front_rpm = front_rpm + self.rear_rpm = rear_rpm + self.percent = percent + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I32: + self.fan_num = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.I32: + self.front_rpm = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 3: + if ftype == TType.I32: + self.rear_rpm = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 4: + if ftype == TType.I32: + self.percent = iprot.readI32() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_fan_info_t') + if self.fan_num is not None: + oprot.writeFieldBegin('fan_num', TType.I32, 1) + oprot.writeI32(self.fan_num) + oprot.writeFieldEnd() + if self.front_rpm is not None: + oprot.writeFieldBegin('front_rpm', TType.I32, 2) + oprot.writeI32(self.front_rpm) + oprot.writeFieldEnd() + if self.rear_rpm is not None: + oprot.writeFieldBegin('rear_rpm', TType.I32, 3) + oprot.writeI32(self.rear_rpm) + oprot.writeFieldEnd() + if self.percent is not None: + oprot.writeFieldBegin('percent', TType.I32, 4) + oprot.writeI32(self.percent) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class InvalidPltfmMgrOperation(TException): + """ + Attributes: + - code + """ + + thrift_spec = ( + None, # 0 + (1, TType.I32, 'code', None, None, ), # 1 + ) + + def __init__(self, code=None,): + self.code = code + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I32: + self.code = iprot.readI32() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('InvalidPltfmMgrOperation') + if self.code is not None: + oprot.writeFieldBegin('code', TType.I32, 1) + oprot.writeI32(self.code) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __str__(self): + return repr(self) + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/psu.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/psu.py new file mode 100644 index 000000000000..7e7e4403ad5c --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/psu.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python + +try: + import os + import sys + + sys.path.append(os.path.dirname(__file__)) + + from .platform_thrift_client import thrift_try + + from sonic_platform_base.psu_base import PsuBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +class Psu(PsuBase): + """Platform-specific PSU class""" + + def __init__(self, index): + PsuBase.__init__(self) + self.index = index + + @staticmethod + def get_num_psus(): + """ + Retrieves the number of PSUs available on the device + :return: An integer, the number of PSUs available on the device + """ + return 2 + + def get_powergood_status(self): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by 1-based self.index + :param self.index: An integer, 1-based self.index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is faulty + """ + def psu_info_get(client): + return client.pltfm_mgr.pltfm_mgr_pwr_supply_info_get(self.index) + + try: + psu_info = thrift_try(psu_info_get) + except Exception: + return False + + return (psu_info.ffault == False) + + def get_presence(self): + """ + Retrieves the presence status of power supply unit (PSU) defined + by 1-based self.index + :param self.index: An integer, 1-based self.index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + def psu_present_get(client): + return client.pltfm_mgr.pltfm_mgr_pwr_supply_present_get(self.index) + + try: + status = thrift_try(psu_present_get) + except Exception: + return False + + return status diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/sfp.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/sfp.py new file mode 100644 index 000000000000..739a48a8f1eb --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/sfp.py @@ -0,0 +1,271 @@ +#!/usr/bin/env python + +try: + import os + import sys + import time + + import tempfile + from contextlib import contextmanager + from copy import copy + + sys.path.append(os.path.dirname(__file__)) + + from .platform_thrift_client import ThriftClient + from .platform_thrift_client import thrift_try + + from sonic_platform_base.sfp_base import SfpBase + from sonic_platform_base.sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + PORT_START = 1 + PORT_END = 0 + PORTS_IN_BLOCK = 0 + QSFP_PORT_START = 1 + QSFP_PORT_END = 0 + EEPROM_OFFSET = 0 + QSFP_CHECK_INTERVAL = 4 + + @property + def port_start(self): + self.update_port_info() + return self.PORT_START + + @property + def port_end(self): + self.update_port_info() + return self.PORT_END + + @property + def qsfp_ports(self): + self.update_port_info() + return range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1) + + @property + def port_to_eeprom_mapping(self): + print("dependency on sysfs has been removed") + raise Exception() + + def __init__(self): + self.ready = False + self.phy_port_dict = {'-1': 'system_not_ready'} + self.phy_port_cur_state = {} + self.qsfp_interval = self.QSFP_CHECK_INTERVAL + + SfpUtilBase.__init__(self) + + def update_port_info(self): + def qsfp_max_port_get(client): + return client.pltfm_mgr.pltfm_mgr_qsfp_get_max_port(); + + if self.QSFP_PORT_END == 0: + self.QSFP_PORT_END = thrift_try(qsfp_max_port_get) + self.PORT_END = self.QSFP_PORT_END + self.PORTS_IN_BLOCK = self.QSFP_PORT_END + + 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 + + presence = False + + def qsfp_presence_get(client): + return client.pltfm_mgr.pltfm_mgr_qsfp_presence_get(port_num) + + try: + presence = thrift_try(qsfp_presence_get) + except Exception as e: + print( e.__doc__) + print(e.message) + + return presence + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + def qsfp_lpmode_get(client): + return client.pltfm_mgr.pltfm_mgr_qsfp_lpmode_get(port_num) + + lpmode = thrift_try(qsfp_lpmode_get) + + return lpmode + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + def qsfp_lpmode_set(client): + return client.pltfm_mgr.pltfm_mgr_qsfp_lpmode_set(port_num, lpmode) + + status = thrift_try(qsfp_lpmode_set) + + return (status == 0) + + def reset(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + def qsfp_reset(client): + client.pltfm_mgr.pltfm_mgr_qsfp_reset(port_num, True) + return client.pltfm_mgr.pltfm_mgr_qsfp_reset(port_num, False) + + err = thrift_try(qsfp_reset) + + return not err + + def check_transceiver_change(self): + if not self.ready: + return + + self.phy_port_dict = {} + + try: + client = ThriftClient().open() + except Exception: + return + + # Get presence of each SFP + for port in range(self.port_start, self.port_end + 1): + try: + sfp_resent = client.pltfm_mgr.pltfm_mgr_qsfp_presence_get(port) + except Exception: + sfp_resent = False + sfp_state = '1' if sfp_resent else '0' + + if port in self.phy_port_cur_state: + if self.phy_port_cur_state[port] != sfp_state: + self.phy_port_dict[port] = sfp_state + else: + self.phy_port_dict[port] = sfp_state + + # Update port current state + self.phy_port_cur_state[port] = sfp_state + + client.close() + + def get_transceiver_change_event(self, timeout=0): + forever = False + if timeout == 0: + forever = True + elif timeout > 0: + timeout = timeout / float(1000) # Convert to secs + else: + print("get_transceiver_change_event:Invalid timeout value", timeout) + return False, {} + + while forever or timeout > 0: + if not self.ready: + try: + with ThriftClient(): pass + except Exception: + pass + else: + self.ready = True + self.phy_port_dict = {} + break + elif self.qsfp_interval == 0: + self.qsfp_interval = self.QSFP_CHECK_INTERVAL + + # Process transceiver plug-in/out event + self.check_transceiver_change() + + # Break if tranceiver state has changed + if bool(self.phy_port_dict): + break + + if timeout: + timeout -= 1 + + if self.qsfp_interval: + self.qsfp_interval -= 1 + + time.sleep(1) + + return self.ready, self.phy_port_dict + + @contextmanager + def eeprom_action(self): + u = copy(self) + with tempfile.NamedTemporaryFile() as f: + u.eeprom_path = f.name + yield u + + def _sfp_eeprom_present(self, client_eeprompath, offset): + return client_eeprompath and super(SfpUtil, self)._sfp_eeprom_present(client_eeprompath, offset) + + def _get_port_eeprom_path(self, port_num, devid): + def qsfp_info_get(client): + return client.pltfm_mgr.pltfm_mgr_qsfp_info_get(port_num) + + if self.get_presence(port_num): + eeprom_hex = thrift_try(qsfp_info_get) + eeprom_raw = bytearray.fromhex(eeprom_hex) + with open(self.eeprom_path, 'wb') as eeprom_cache: + eeprom_cache.write(eeprom_raw) + return self.eeprom_path + + return None + +class Sfp(SfpBase): + """Platform-specific Sfp class""" + + sfputil = SfpUtil() + + @staticmethod + def port_start(): + return Sfp.sfputil.port_start + + @staticmethod + def port_end(): + return Sfp.sfputil.port_end + + @staticmethod + def qsfp_ports(): + return Sfp.sfputil.qsfp_ports() + + @staticmethod + def get_transceiver_change_event(timeout=0): + return Sfp.sfputil.get_transceiver_change_event() + + def __init__(self, port_num): + self.port_num = port_num + SfpBase.__init__(self) + + def get_presence(self): + with Sfp.sfputil.eeprom_action() as u: + return u.get_presence(self.port_num) + + def get_lpmode(self): + with Sfp.sfputil.eeprom_action() as u: + return u.get_low_power_mode(self.port_num) + + def set_lpmode(self, lpmode): + with Sfp.sfputil.eeprom_action() as u: + return u.set_low_power_mode(self.port_num, lpmode) + + def reset(self): + return Sfp.sfputil.reset(self.port_num) + + def get_transceiver_info(self): + with Sfp.sfputil.eeprom_action() as u: + return u.get_transceiver_info_dict(self.port_num) + + def get_transceiver_bulk_status(self): + with Sfp.sfputil.eeprom_action() as u: + return u.get_transceiver_dom_info_dict(self.port_num) + + def get_transceiver_threshold_info(self): + with Sfp.sfputil.eeprom_action() as u: + return u.get_transceiver_dom_threshold_info_dict(self.port_num) + + def get_change_event(self, timeout=0): + return Sfp.get_transceiver_change_event(timeout) diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/compat b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/compat index 45a4fb75db86..ec635144f600 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/compat +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/compat @@ -1 +1 @@ -8 +9 diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control index bc6c990efebb..d2c37fe8d2b9 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control @@ -2,11 +2,16 @@ Source: sonic-platform-modules-bfn-newport Section: main Priority: extra Maintainer: Support -Build-Depends: debhelper (>= 8.0.0), bzip2 +Build-Depends: debhelper (>= 9.0.0), bzip2 Standards-Version: 3.9.3 -Package: sonic-platform-modules-bfn-newport +Package: sonic-platform-modules-bfn-newport-as9516 Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned +Description: kernel module for bfn platform fpga and scripts for the devices such as fan, led, sfp + +Package: sonic-platform-modules-bfn-newport-as9516bf +Architecture: amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned 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-newport/debian/postinst b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/postinst index a89ac4f4f5b2..90d772ef89df 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/postinst +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/postinst @@ -1,6 +1,27 @@ #!/bin/sh set -e -depmod -a +depmod -a systemctl enable bfn-newport.service systemctl start bfn-newport.service + +PLATFORM_NAME=x86_64-accton_as9516bf_32d-r0 +SONIC_PLATFORM_WHEEL_PY2="/usr/share/sonic/device/${PLATFORM_NAME}/sonic_platform-1.0-py2-none-any.whl" +if [ -e ${SONIC_PLATFORM_WHEEL_PY2} ]; then + python2 -m pip install ${SONIC_PLATFORM_WHEEL_PY2} +fi +SONIC_PLATFORM_WHEEL_PY3="/usr/share/sonic/device/${PLATFORM_NAME}/sonic_platform-1.0-py3-none-any.whl" +if [ -e ${SONIC_PLATFORM_WHEEL_PY3} ]; then + python3 -m pip install ${SONIC_PLATFORM_WHEEL_PY3} +fi + +PLATFORM_NAME=x86_64-accton_as9516_32d-r0 +SONIC_PLATFORM_WHEEL_PY2="/usr/share/sonic/device/${PLATFORM_NAME}/sonic_platform-1.0-py2-none-any.whl" +if [ -e ${SONIC_PLATFORM_WHEEL_PY2} ]; then + python2 -m pip install ${SONIC_PLATFORM_WHEEL_PY2} +fi +SONIC_PLATFORM_WHEEL_PY3="/usr/share/sonic/device/${PLATFORM_NAME}/sonic_platform-1.0-py3-none-any.whl" +if [ -e ${SONIC_PLATFORM_WHEEL_PY3} ]; then + python3 -m pip install ${SONIC_PLATFORM_WHEEL_PY3} +fi + #DEBHELPER# diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/prerm b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/prerm new file mode 100644 index 000000000000..ee19dbb1db98 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/prerm @@ -0,0 +1,6 @@ +#!/bin/sh + +python2 -m pip uninstall -y sonic-platform +python3 -m pip uninstall -y sonic-platform + +#DEBHELPER# diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/rules b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/rules index 951069a6016a..962a1de8204e 100755 --- a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/rules +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/rules @@ -2,26 +2,40 @@ export INSTALL_MOD_DIR:=extra -PACKAGE_NAME := sonic-platform-modules-bfn-newport +PACKAGE_PRE_NAME := sonic-platform-modules-bfn-newport KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MODULE_SRC := $(shell pwd)/modules SCRIPT_SRC := $(shell pwd)/scripts CONFIGS_SRC := $(shell pwd)/configs +BUILD_DIR := $(shell pwd)/build +WHEEL_BUILD_DIR := $(BUILD_DIR)/wheel +PLUGINS_DIR := $(shell pwd)/plugins +MODULE_NAMES := as9516 as9516bf %: dh $@ override_dh_auto_build: make -C $(KERNEL_SRC)/build M=$(MODULE_SRC) + set -e + python2.7 setup.py bdist_wheel -d $(WHEEL_BUILD_DIR) + python3 setup.py bdist_wheel -d $(WHEEL_BUILD_DIR) + set +e override_dh_auto_install: - dh_installdirs -p$(PACKAGE_NAME) $(KERNEL_SRC)/$(INSTALL_MOD_DIR) - cp $(MODULE_SRC)/*.ko debian/$(PACKAGE_NAME)/$(KERNEL_SRC)/$(INSTALL_MOD_DIR) - dh_installdirs -p$(PACKAGE_NAME) usr/local/bin - cp -r $(SCRIPT_SRC)/* debian/$(PACKAGE_NAME)/usr/local/bin - dh_installdirs -p$(PACKAGE_NAME) etc/network/interfaces.d/ - cp -r $(CONFIGS_SRC)/network/interfaces.d/* debian/$(PACKAGE_NAME)/etc/network/interfaces.d/ + (for mod in $(MODULE_NAMES); do \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + cp $(MODULE_SRC)/*.ko debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} usr/local/bin; \ + cp -r $(SCRIPT_SRC)/* debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin; \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} etc/network/interfaces.d/; \ + cp -r $(CONFIGS_SRC)/network/interfaces.d/* debian/$(PACKAGE_PRE_NAME)-$${mod}/etc/network/interfaces.d/; \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} usr/share/sonic/device/x86_64-accton_$${mod}_32d-r0/; \ + cp -r $(WHEEL_BUILD_DIR)/* debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/share/sonic/device/x86_64-accton_$${mod}_32d-r0/; \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} usr/share/sonic/device/x86_64-accton_$${mod}_32d-r0/plugins; \ + cp -r $(PLUGINS_DIR)/* debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/share/sonic/device/x86_64-accton_$${mod}_32d-r0/plugins/; \ + done) override_dh_usrlocal: @@ -29,6 +43,9 @@ override_dh_pysupport: override_dh_clean: dh_clean + rm -fr $(WHEEL_BUILD_DIR) + rm -fr *.egg-info + rm -fr $(BUILD) rm -f $(MODULE_SRC)/*.o $(MODULE_SRC)/*.ko $(MODULE_SRC)/*.mod.c $(MODULE_SRC)/.*.cmd rm -f $(MODULE_SRC)/Module.markers $(MODULE_SRC)/Module.symvers $(MODULE_SRC)/modules.order rm -rf $(MODULE_SRC)/.tmp_versions diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/plugins/pcie.yaml b/platform/barefoot/sonic-platform-modules-bfn-newport/plugins/pcie.yaml new file mode 100644 index 000000000000..c45064a9f73c --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/plugins/pcie.yaml @@ -0,0 +1,428 @@ +- bus: '00' + dev: '00' + fn: '0' + id: 6f00 + name: 'Host bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D DMI2 + (rev 03)' +- bus: '00' + dev: '01' + fn: '0' + id: 6f02 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 1 (rev 03)' +- bus: '00' + dev: '01' + fn: '1' + id: 6f03 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 1 (rev 03)' +- bus: '00' + dev: '02' + fn: '0' + id: 6f04 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 2 (rev 03)' +- bus: '00' + dev: '02' + fn: '2' + id: 6f06 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 2 (rev 03)' +- bus: '00' + dev: '03' + fn: '0' + id: 6f08 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 3 (rev 03)' +- bus: '00' + dev: '05' + fn: '0' + id: 6f28 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Map/VTd_Misc/System Management (rev 03)' +- bus: '00' + dev: '05' + fn: '1' + id: 6f29 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Hot Plug (rev 03)' +- bus: '00' + dev: '05' + fn: '2' + id: 6f2a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO RAS/Control Status/Global Errors (rev 03)' +- bus: '00' + dev: '05' + fn: '4' + id: 6f2c + name: 'PIC: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D I/O APIC (rev + 03)' +- bus: '00' + dev: '16' + fn: '0' + id: 8c3a + name: 'Communication controller: Intel Corporation 8 Series/C220 Series Chipset + Family MEI Controller #1 (rev 04)' +- bus: '00' + dev: '16' + fn: '1' + id: 8c3b + name: 'Communication controller: Intel Corporation 8 Series/C220 Series Chipset + Family MEI Controller #2 (rev 04)' +- bus: '00' + dev: 1c + fn: '0' + id: 8c10 + name: 'PCI bridge: Intel Corporation 8 Series/C220 Series Chipset Family PCI Express + Root Port #1 (rev d5)' +- bus: '00' + dev: 1d + fn: '0' + id: 8c26 + name: 'USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB + EHCI #1 (rev 05)' +- bus: '00' + dev: 1f + fn: '0' + id: 8c54 + name: 'ISA bridge: Intel Corporation C224 Series Chipset Family Server Standard + SKU LPC Controller (rev 05)' +- bus: '00' + dev: 1f + fn: '2' + id: 8c02 + name: 'SATA controller: Intel Corporation 8 Series/C220 Series Chipset Family 6-port + SATA Controller 1 [AHCI mode] (rev 05)' +- bus: '00' + dev: 1f + fn: '3' + id: 8c22 + name: 'SMBus: Intel Corporation 8 Series/C220 Series Chipset Family SMBus Controller + (rev 05)' +- bus: '02' + dev: '00' + fn: '0' + id: '1533' + name: 'Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev + 03)' +- bus: '03' + dev: '00' + fn: '0' + id: 6f50 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 0' +- bus: '03' + dev: '00' + fn: '1' + id: 6f51 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 1' +- bus: '03' + dev: '00' + fn: '2' + id: 6f52 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 2' +- bus: '03' + dev: '00' + fn: '3' + id: 6f53 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 3' +- bus: '04' + dev: '00' + fn: '0' + id: 15ab + name: 'Ethernet controller: Intel Corporation Ethernet Connection X552 10 GbE Backplane' +- bus: '04' + dev: '00' + fn: '1' + id: 15ab + name: 'Ethernet controller: Intel Corporation Ethernet Connection X552 10 GbE Backplane' +- bus: '06' + dev: '00' + fn: '0' + id: '0100' + name: 'Ethernet controller: Device 1d1c:0100' +- bus: '07' + dev: '00' + fn: '0' + id: 01f0 + name: 'Memory controller: Device 1d1c:01f0' +- bus: ff + dev: 0b + fn: '0' + id: 6f81 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '1' + id: 6f36 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '2' + id: 6f37 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '3' + id: 6f76 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link Debug (rev 03)' +- bus: ff + dev: 0c + fn: '0' + id: 6fe0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0c + fn: '1' + id: 6fe1 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0c + fn: '2' + id: 6fe2 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0c + fn: '3' + id: 6fe3 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '0' + id: 6ff8 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '4' + id: 6ffc + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '5' + id: 6ffd + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '6' + id: 6ffe + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: '10' + fn: '0' + id: 6f1d + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R2PCIe Agent (rev 03)' +- bus: ff + dev: '10' + fn: '1' + id: 6f34 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R2PCIe Agent (rev 03)' +- bus: ff + dev: '10' + fn: '5' + id: 6f1e + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '10' + fn: '6' + id: 6f7d + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '10' + fn: '7' + id: 6f1f + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '12' + fn: '0' + id: 6fa0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Home Agent 0 (rev 03)' +- bus: ff + dev: '12' + fn: '1' + id: 6f30 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Home Agent 0 (rev 03)' +- bus: ff + dev: '13' + fn: '0' + id: 6fa8 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Target Address/Thermal/RAS (rev 03)' +- bus: ff + dev: '13' + fn: '1' + id: 6f71 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Target Address/Thermal/RAS (rev 03)' +- bus: ff + dev: '13' + fn: '2' + id: 6faa + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '3' + id: 6fab + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '4' + id: 6fac + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '5' + id: 6fad + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '6' + id: 6fae + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Broadcast (rev 03)' +- bus: ff + dev: '13' + fn: '7' + id: 6faf + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Global Broadcast (rev 03)' +- bus: ff + dev: '14' + fn: '0' + id: 6fb0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 0 Thermal Control (rev 03)' +- bus: ff + dev: '14' + fn: '1' + id: 6fb1 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 1 Thermal Control (rev 03)' +- bus: ff + dev: '14' + fn: '2' + id: 6fb2 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 0 Error (rev 03)' +- bus: ff + dev: '14' + fn: '3' + id: 6fb3 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 1 Error (rev 03)' +- bus: ff + dev: '14' + fn: '4' + id: 6fbc + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '5' + id: 6fbd + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '6' + id: 6fbe + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '7' + id: 6fbf + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '15' + fn: '0' + id: 6fb4 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 2 Thermal Control (rev 03)' +- bus: ff + dev: '15' + fn: '1' + id: 6fb5 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 3 Thermal Control (rev 03)' +- bus: ff + dev: '15' + fn: '2' + id: 6fb6 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 2 Error (rev 03)' +- bus: ff + dev: '15' + fn: '3' + id: 6fb7 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 3 Error (rev 03)' +- bus: ff + dev: 1e + fn: '0' + id: 6f98 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '1' + id: 6f99 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '2' + id: 6f9a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '3' + id: 6fc0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '4' + id: 6f9c + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1f + fn: '0' + id: 6f88 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1f + fn: '2' + id: 6f8a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/setup.py b/platform/barefoot/sonic-platform-modules-bfn-newport/setup.py new file mode 120000 index 000000000000..a68e2eec6762 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/setup.py @@ -0,0 +1 @@ +../sonic-platform-modules-bfn-montara/setup.py \ No newline at end of file diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/sonic_platform b/platform/barefoot/sonic-platform-modules-bfn-newport/sonic_platform new file mode 120000 index 000000000000..b2918418aad1 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/sonic_platform @@ -0,0 +1 @@ +../sonic-platform-modules-bfn-montara/sonic_platform \ No newline at end of file diff --git a/platform/barefoot/sonic-platform-modules-bfn/debian/compat b/platform/barefoot/sonic-platform-modules-bfn/debian/compat index 45a4fb75db86..ec635144f600 100644 --- a/platform/barefoot/sonic-platform-modules-bfn/debian/compat +++ b/platform/barefoot/sonic-platform-modules-bfn/debian/compat @@ -1 +1 @@ -8 +9 diff --git a/platform/barefoot/sonic-platform-modules-bfn/debian/control b/platform/barefoot/sonic-platform-modules-bfn/debian/control index cca87831f1f1..89c597303a78 100644 --- a/platform/barefoot/sonic-platform-modules-bfn/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn/debian/control @@ -2,11 +2,11 @@ Source: sonic-platform-modules-bfn Section: main Priority: extra Maintainer: support -Build-Depends: debhelper (>= 8.0.0), bzip2 +Build-Depends: debhelper (>= 9.0.0), bzip2 Standards-Version: 3.9.3 Package: sonic-platform-modules-bfn Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/barefoot/sonic-platform-modules-bfn/debian/postinst b/platform/barefoot/sonic-platform-modules-bfn/debian/postinst new file mode 100644 index 000000000000..bd24c078778a --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn/debian/postinst @@ -0,0 +1,10 @@ +#!/bin/sh +set -e + +PLATFORM_NAME=x86_64-accton_wedge100bf_65x-r0 +SONIC_PLATFORM_WHEEL_PY2="/usr/share/sonic/device/${PLATFORM_NAME}/sonic_platform-1.0-py2-none-any.whl" +python2 -m pip install ${SONIC_PLATFORM_WHEEL_PY2} +SONIC_PLATFORM_WHEEL_PY3="/usr/share/sonic/device/${PLATFORM_NAME}/sonic_platform-1.0-py3-none-any.whl" +python3 -m pip install ${SONIC_PLATFORM_WHEEL_PY3} + +#DEBHELPER# diff --git a/platform/barefoot/sonic-platform-modules-bfn/debian/prerm b/platform/barefoot/sonic-platform-modules-bfn/debian/prerm new file mode 100755 index 000000000000..ee19dbb1db98 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn/debian/prerm @@ -0,0 +1,6 @@ +#!/bin/sh + +python2 -m pip uninstall -y sonic-platform +python3 -m pip uninstall -y sonic-platform + +#DEBHELPER# diff --git a/platform/barefoot/sonic-platform-modules-bfn/debian/rules b/platform/barefoot/sonic-platform-modules-bfn/debian/rules index 83cdefe640ba..0ee3dcfaf0e2 100755 --- a/platform/barefoot/sonic-platform-modules-bfn/debian/rules +++ b/platform/barefoot/sonic-platform-modules-bfn/debian/rules @@ -1,22 +1,36 @@ #!/usr/bin/make -f +PLATFORM_NAME := x86_64-accton_wedge100bf_65x-r0 PACKAGE_NAME := sonic-platform-modules-bfn SCRIPT_SRC := $(shell pwd)/scripts CONFIGS_SRC := $(shell pwd)/configs +BUILD_DIR := $(shell pwd)/build +WHEEL_BUILD_DIR := $(BUILD_DIR)/wheel %: dh $@ +override_dh_auto_build: + set -e + python2.7 setup.py bdist_wheel -d $(WHEEL_BUILD_DIR) + python3 setup.py bdist_wheel -d $(WHEEL_BUILD_DIR) + set +e + override_dh_auto_install: dh_installdirs -p$(PACKAGE_NAME) usr/local/bin cp -r $(SCRIPT_SRC)/* debian/$(PACKAGE_NAME)/usr/local/bin dh_installdirs -p$(PACKAGE_NAME) etc/network/interfaces.d/ cp -r $(CONFIGS_SRC)/network/interfaces.d/* debian/$(PACKAGE_NAME)/etc/network/interfaces.d/ + dh_installdirs -p$(PACKAGE_NAME) usr/share/sonic/device/$(PLATFORM_NAME)/ + cp -r $(WHEEL_BUILD_DIR)/* debian/$(PACKAGE_NAME)/usr/share/sonic/device/$(PLATFORM_NAME)/ override_dh_usrlocal: override_dh_pysupport: override_dh_clean: + rm -fr $(WHEEL_BUILD_DIR) + rm -fr *.egg-info + rm -fr $(BUILD) dh_clean diff --git a/platform/barefoot/sonic-platform-modules-bfn/setup.py b/platform/barefoot/sonic-platform-modules-bfn/setup.py new file mode 120000 index 000000000000..a68e2eec6762 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn/setup.py @@ -0,0 +1 @@ +../sonic-platform-modules-bfn-montara/setup.py \ No newline at end of file diff --git a/platform/barefoot/sonic-platform-modules-bfn/sonic_platform b/platform/barefoot/sonic-platform-modules-bfn/sonic_platform new file mode 120000 index 000000000000..b2918418aad1 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn/sonic_platform @@ -0,0 +1 @@ +../sonic-platform-modules-bfn-montara/sonic_platform \ No newline at end of file diff --git a/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/control b/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/control index 6070cf9ad1fc..eab1adcadecd 100644 --- a/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/control +++ b/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: platform-modules-wnc-osw1800 Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/wnc_eeprom.c b/platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/wnc_eeprom.c index 8ddf1f2af279..8f05e5c09ada 100644 --- a/platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/wnc_eeprom.c +++ b/platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/wnc_eeprom.c @@ -18,7 +18,8 @@ #include #include -#include +#include +#include #include #include #include @@ -59,7 +60,6 @@ static void eeprom_update_client(struct i2c_client *client, u8 slice) dev_dbg(&client->dev, "Starting eeprom update, slice %u\n", slice); if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { - //for (i = slice << 5; i < (slice + 1) << 5; i += 32) for (i = slice << 5; i < (slice + 1) << 5; i += 24) if (i2c_smbus_read_i2c_block_data(client, i, 24, data->data + i) @@ -85,17 +85,10 @@ static ssize_t eeprom_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { - struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj)); + struct i2c_client *client = to_i2c_client(kobj_to_dev(kobj)); struct eeprom_data *data = i2c_get_clientdata(client); u8 slice; - data->valid = 0; - - if (off > EEPROM_SIZE) - return 0; - if (off + count > EEPROM_SIZE) - count = EEPROM_SIZE - off; - /* Only refresh slices which contain requested bytes */ for (slice = off >> 5; slice <= (off + count - 1) >> 5; slice++) eeprom_update_client(client, slice); @@ -125,7 +118,7 @@ static ssize_t eeprom_write(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { - struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj)); + struct i2c_client *client = to_i2c_client(kobj_to_dev(kobj)); struct eeprom_data *data = i2c_get_clientdata(client); u8 temp; int error, reg; @@ -208,12 +201,11 @@ static int eeprom_probe(struct i2c_client *client, { struct i2c_adapter *adapter = client->adapter; struct eeprom_data *data; - int err; - if (!(data = kzalloc(sizeof(struct eeprom_data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&client->dev, sizeof(struct eeprom_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; memset(data->data, 0xff, EEPROM_SIZE); i2c_set_clientdata(client, data); @@ -239,22 +231,12 @@ static int eeprom_probe(struct i2c_client *client, } /* create the sysfs eeprom file */ - err = sysfs_create_bin_file(&client->dev.kobj, &eeprom_attr); - if (err) - goto exit_kfree; - - return 0; - -exit_kfree: - kfree(data); -exit: - return err; + return sysfs_create_bin_file(&client->dev.kobj, &eeprom_attr); } static int eeprom_remove(struct i2c_client *client) { sysfs_remove_bin_file(&client->dev.kobj, &eeprom_attr); - kfree(i2c_get_clientdata(client)); return 0; } diff --git a/platform/broadcom/docker-ptf-brcm.dep b/platform/broadcom/docker-ptf-brcm.dep deleted file mode 100644 index b899d058d445..000000000000 --- a/platform/broadcom/docker-ptf-brcm.dep +++ /dev/null @@ -1,10 +0,0 @@ - -DPATH := $($(DOCKER_PTF_BRCM)_PATH) -DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/broadcom/docker-ptf-brcm.mk platform/broadcom/docker-ptf-brcm.dep -DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) -DEP_FILES += $(shell git ls-files $(DPATH)) - -$(DOCKER_PTF_BRCM)_CACHE_MODE := GIT_CONTENT_SHA -$(DOCKER_PTF_BRCM)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) -$(DOCKER_PTF_BRCM)_DEP_FILES := $(DEP_FILES) - diff --git a/platform/broadcom/docker-ptf-brcm.mk b/platform/broadcom/docker-ptf-brcm.mk deleted file mode 100644 index 510f21e8a436..000000000000 --- a/platform/broadcom/docker-ptf-brcm.mk +++ /dev/null @@ -1,7 +0,0 @@ -# docker image for docker-ptf-brcm - -DOCKER_PTF_BRCM = docker-ptf-brcm.gz -$(DOCKER_PTF_BRCM)_PATH = $(DOCKERS_PATH)/docker-ptf-saithrift -$(DOCKER_PTF_BRCM)_DEPENDS += $(PYTHON_SAITHRIFT) -$(DOCKER_PTF_BRCM)_LOAD_DOCKERS += $(DOCKER_PTF) -SONIC_DOCKER_IMAGES += $(DOCKER_PTF_BRCM) diff --git a/platform/broadcom/docker-saiserver-brcm.mk b/platform/broadcom/docker-saiserver-brcm.mk index b754ab679884..bb8499eab1fb 100644 --- a/platform/broadcom/docker-saiserver-brcm.mk +++ b/platform/broadcom/docker-saiserver-brcm.mk @@ -4,7 +4,7 @@ DOCKER_SAISERVER_BRCM = docker-saiserver-brcm.gz $(DOCKER_SAISERVER_BRCM)_PATH = $(PLATFORM_PATH)/docker-saiserver-brcm $(DOCKER_SAISERVER_BRCM)_DEPENDS += $(SAISERVER) $(DOCKER_SAISERVER_BRCM)_FILES += $(DSSERVE) $(BCMCMD) -$(DOCKER_SAISERVER_BRCM)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) +$(DOCKER_SAISERVER_BRCM)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) SONIC_DOCKER_IMAGES += $(DOCKER_SAISERVER_BRCM) $(DOCKER_SAISERVER_BRCM)_CONTAINER_NAME = saiserver diff --git a/platform/broadcom/docker-saiserver-brcm/Dockerfile.j2 b/platform/broadcom/docker-saiserver-brcm/Dockerfile.j2 index 79dccf8f37a0..a4b4fedd39ad 100644 --- a/platform/broadcom/docker-saiserver-brcm/Dockerfile.j2 +++ b/platform/broadcom/docker-saiserver-brcm/Dockerfile.j2 @@ -1,4 +1,4 @@ -FROM docker-config-engine-stretch +FROM docker-config-engine-buster ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf @@ -33,4 +33,4 @@ COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/broadcom/docker-syncd-brcm-rpc.mk b/platform/broadcom/docker-syncd-brcm-rpc.mk index bd2ef01c5eed..27a041d95016 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) \ @@ -12,13 +12,12 @@ endif $(DOCKER_SYNCD_BRCM_RPC)_FILES += $(DSSERVE) $(BCMCMD) $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) $(DOCKER_SYNCD_BRCM_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_BASE) SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_BRCM_RPC) -SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_BRCM_RPC) ifeq ($(ENABLE_SYNCD_RPC),y) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_BRCM_RPC) endif $(DOCKER_SYNCD_BRCM_RPC)_CONTAINER_NAME = syncd -$(DOCKER_SYNCD_BRCM_RPC)_RUN_OPT += --net=host --privileged -t +$(DOCKER_SYNCD_BRCM_RPC)_RUN_OPT += --privileged -t $(DOCKER_SYNCD_BRCM_RPC)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf $(DOCKER_SYNCD_BRCM_RPC)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_SYNCD_BRCM_RPC)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd diff --git a/platform/broadcom/docker-syncd-brcm-rpc/Dockerfile.j2 b/platform/broadcom/docker-syncd-brcm-rpc/Dockerfile.j2 index 5b4f71144c2f..b832fd58864f 100644 --- a/platform/broadcom/docker-syncd-brcm-rpc/Dockerfile.j2 +++ b/platform/broadcom/docker-syncd-brcm-rpc/Dockerfile.j2 @@ -11,23 +11,28 @@ debs/ RUN apt-get purge -y syncd -RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; } ; \ -{% for deb in docker_syncd_brcm_rpc_debs.split(' ') -%} -dpkg_apt debs/{{ deb }}{{'; '}} -{%- endfor %} - ## Pre-install the fundamental packages RUN apt-get update \ && apt-get -y install \ net-tools \ python-pip \ + python-setuptools \ build-essential \ libssl-dev \ libffi-dev \ python-dev \ wget \ cmake \ - && wget https://github.com/nanomsg/nanomsg/archive/1.0.0.tar.gz \ + libqt5core5a \ + libqt5network5 \ + libboost-atomic1.71.0 + +RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; } ; \ +{% for deb in docker_syncd_brcm_rpc_debs.split(' ') -%} +dpkg_apt debs/{{ deb }}{{'; '}} +{%- endfor %} + +RUN wget https://github.com/nanomsg/nanomsg/archive/1.0.0.tar.gz \ && tar xvfz 1.0.0.tar.gz \ && cd nanomsg-1.0.0 \ && mkdir -p build \ @@ -37,9 +42,10 @@ RUN apt-get update \ && cd .. \ && rm -fr nanomsg-1.0.0 \ && rm -f 1.0.0.tar.gz \ - && pip install cffi==1.7.0 \ - && pip install --upgrade cffi==1.7.0 \ - && pip install nnpy \ + && pip2 install cffi==1.7.0 \ + && pip2 install --upgrade cffi==1.7.0 \ + && pip2 install wheel \ + && pip2 install nnpy \ && mkdir -p /opt \ && cd /opt \ && wget https://raw.githubusercontent.com/p4lang/ptf/master/ptf_nn/ptf_nn_agent.py \ @@ -48,4 +54,4 @@ RUN apt-get update \ COPY ["ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/broadcom/docker-syncd-brcm.dep b/platform/broadcom/docker-syncd-brcm.dep index 48fa57f33479..c020a72f2a08 100644 --- a/platform/broadcom/docker-syncd-brcm.dep +++ b/platform/broadcom/docker-syncd-brcm.dep @@ -1,6 +1,6 @@ #DPKG FRK DPATH := $($(DOCKER_SYNCD_BASE)_PATH) -DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/broadcom/docker-syncd-brcm.mk platform/broadcom/docker-syncd-brcm.dep +DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/broadcom/docker-syncd-brcm.mk platform/broadcom/docker-syncd-brcm.dep platform/broadcom/sai.mk DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) DEP_FILES += $(shell git ls-files $(DPATH)) diff --git a/platform/broadcom/docker-syncd-brcm.mk b/platform/broadcom/docker-syncd-brcm.mk index d3a6d67c5cbc..d23141481915 100644 --- a/platform/broadcom/docker-syncd-brcm.mk +++ b/platform/broadcom/docker-syncd-brcm.mk @@ -12,8 +12,8 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSAIREDIS_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 += bcmcmd:/usr/bin/bcmcmd $(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += bcmsh:/usr/bin/bcmsh +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += bcm_common:/usr/bin/bcm_common $(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 b/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 index 1ef1c588777c..0ba71bb5d780 100755 --- a/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 +++ b/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 @@ -1,5 +1,5 @@ {% from "dockers/dockerfile-macros.j2" import install_debian_packages %} -FROM docker-config-engine-stretch +FROM docker-config-engine-buster ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf @@ -21,7 +21,10 @@ debs/ ## TODO: add kmod into Depends RUN apt-get install -yf kmod -COPY ["files/dsserve", "files/bcmcmd", "start.sh", "bcmsh", "/usr/bin/"] +## BRCM uses ethtool to set host interface speed +RUN apt-get install -y ethtool + +COPY ["files/dsserve", "files/bcmcmd", "start.sh", "start_led.sh", "bcmsh", "/usr/bin/"] RUN chmod +x /usr/bin/dsserve /usr/bin/bcmcmd COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] @@ -32,4 +35,4 @@ COPY ["critical_processes", "/etc/supervisor/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/broadcom/docker-syncd-brcm/base_image_files/bcm_common b/platform/broadcom/docker-syncd-brcm/base_image_files/bcm_common new file mode 100644 index 000000000000..1b560a1a1522 --- /dev/null +++ b/platform/broadcom/docker-syncd-brcm/base_image_files/bcm_common @@ -0,0 +1,40 @@ +#!/bin/bash + +function help() +{ + echo "Usage: $0 -n [0 to $(($NUM_ASIC-1))]" 1>&2; exit 1; + +} + + +DEV="" + +PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` + +# Parse the device specific asic conf file, if it exists + +ASIC_CONF=/usr/share/sonic/device/$PLATFORM/asic.conf +if [ -f "$ASIC_CONF" ]; then + source $ASIC_CONF +fi + + +if [[ ($NUM_ASIC -gt 1) ]]; then + OPTIND=1 + + while getopts ":n:h:" opt; do + case "${opt}" in + h) help + exit 0 + ;; + n) DEV=${OPTARG} + [ $DEV -lt $NUM_ASIC -a $DEV -ge 0 ] || help + ;; + esac + done + shift "$((OPTIND-1))" + + if [ -z "${DEV}" ]; then + help + fi +fi diff --git a/platform/broadcom/docker-syncd-brcm/base_image_files/bcmcmd b/platform/broadcom/docker-syncd-brcm/base_image_files/bcmcmd index 7903db6ed6a3..76362fc64804 100755 --- a/platform/broadcom/docker-syncd-brcm/base_image_files/bcmcmd +++ b/platform/broadcom/docker-syncd-brcm/base_image_files/bcmcmd @@ -1,3 +1,8 @@ #!/bin/bash -docker exec -i syncd bcmcmd "$@" +BCM_COMMON=/usr/bin/bcm_common +if [ -f "$BCM_COMMON" ]; then + source $BCM_COMMON +fi +docker exec -i syncd$DEV bcmcmd "$@" + diff --git a/platform/broadcom/docker-syncd-brcm/base_image_files/bcmsh b/platform/broadcom/docker-syncd-brcm/base_image_files/bcmsh index 3bb78b0da796..3cb2aad7afb6 100755 --- a/platform/broadcom/docker-syncd-brcm/base_image_files/bcmsh +++ b/platform/broadcom/docker-syncd-brcm/base_image_files/bcmsh @@ -1,3 +1,8 @@ #!/bin/bash -docker exec -it syncd bcmsh "$@" +BCM_COMMON=/usr/bin/bcm_common +if [ -f "$BCM_COMMON" ]; then + source $BCM_COMMON +fi + +docker exec -it syncd$DEV bcmsh "$@" 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 0b9ec741cd57..d63346d9ee20 100644 --- a/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd +++ b/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd @@ -4,8 +4,8 @@ ## syncd ## dsserve ############################################################################### -check process syncd matching "/usr/bin/syncd" - if does not exist for 5 times within 5 cycles then alert +check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles -check process dsserve matching "/usr/bin/dsserve /usr/bin/syncd" - if does not exist for 5 times within 5 cycles then alert +check program syncd|dsserve with path "/usr/bin/process_checker syncd /usr/bin/dsserve /usr/bin/syncd" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/platform/broadcom/docker-syncd-brcm/critical_processes b/platform/broadcom/docker-syncd-brcm/critical_processes index 489668a89e08..d1163a9c3046 100644 --- a/platform/broadcom/docker-syncd-brcm/critical_processes +++ b/platform/broadcom/docker-syncd-brcm/critical_processes @@ -1,2 +1,2 @@ -dsserve -syncd +program:dsserve +program:syncd diff --git a/platform/broadcom/docker-syncd-brcm/start.sh b/platform/broadcom/docker-syncd-brcm/start.sh index 146b2efa7406..9927b877a619 100755 --- a/platform/broadcom/docker-syncd-brcm/start.sh +++ b/platform/broadcom/docker-syncd-brcm/start.sh @@ -1,43 +1,12 @@ #!/usr/bin/env bash -PLATFORM_DIR=/usr/share/sonic/platform HWSKU_DIR=/usr/share/sonic/hwsku SYNCD_SOCKET_FILE=/var/run/sswsyncd/sswsyncd.socket -# Function: wait until syncd has created the socket for bcmcmd to connect to -wait_syncd() { - while true; do - if [ -e ${SYNCD_SOCKET_FILE} ]; then - break - fi - sleep 1 - done - - # wait until bcm sdk is ready to get a request - counter=0 - while true; do - /usr/bin/bcmcmd -t 1 "show unit" | grep BCM >/dev/null 2>&1 - rv=$? - if [ $rv -eq 0 ]; then - break - fi - counter=$((counter+1)) - if [ $counter -ge 60 ]; then - echo "syncd is not ready to take commands after $counter re-tries; Exiting!" - break - fi - sleep 1 - done -} - - # Remove stale files if they exist -rm -f /var/run/rsyslogd.pid rm -f ${SYNCD_SOCKET_FILE} -supervisorctl start rsyslogd - mkdir -p /etc/sai.d/ # Create/Copy the sai.profile to /etc/sai.d/sai.profile @@ -48,11 +17,3 @@ else cp $HWSKU_DIR/sai.profile /etc/sai.d/sai.profile fi fi - -supervisorctl start syncd - -# If this platform has an initialization file for the Broadcom LED microprocessor, load it -if [[ -r ${PLATFORM_DIR}/led_proc_init.soc && ! -f /var/warmboot/warm-starting ]]; then - wait_syncd - supervisorctl start ledinit -fi diff --git a/platform/broadcom/docker-syncd-brcm/start_led.sh b/platform/broadcom/docker-syncd-brcm/start_led.sh new file mode 100755 index 000000000000..964aa23eb04f --- /dev/null +++ b/platform/broadcom/docker-syncd-brcm/start_led.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +PLATFORM_DIR=/usr/share/sonic/platform +SYNCD_SOCKET_FILE=/var/run/sswsyncd/sswsyncd.socket +LED_PROC_INIT_SOC=${PLATFORM_DIR}/led_proc_init.soc + +if [ ! -f "$LED_PROC_INIT_SOC" ]; then + echo "No soc led configuration found under $LED_SOC_INIT_SOC" + exit 0 +fi + +# Function: wait until syncd has created the socket for bcmcmd to connect to +wait_syncd() { + while true; do + if [ -e ${SYNCD_SOCKET_FILE} ]; then + break + fi + sleep 1 + done + + # wait until bcm sdk is ready to get a request + counter=0 + while true; do + /usr/bin/bcmcmd -t 1 "show unit" | grep BCM >/dev/null 2>&1 + rv=$? + if [ $rv -eq 0 ]; then + break + fi + counter=$((counter+1)) + if [ $counter -ge 60 ]; then + echo "syncd is not ready to take commands after $counter re-tries; Exiting!" + break + fi + sleep 1 + done +} + +# If this platform has an initialization file for the Broadcom LED microprocessor, load it +if [[ -r "$LED_PROC_INIT_SOC" && ! -f /var/warmboot/warm-starting ]]; then + wait_syncd +fi + +/usr/bin/bcmcmd -t 60 "rcload $LED_PROC_INIT_SOC" diff --git a/platform/broadcom/docker-syncd-brcm/supervisord.conf b/platform/broadcom/docker-syncd-brcm/supervisord.conf index 3fa8febb85d8..5e801106972f 100644 --- a/platform/broadcom/docker-syncd-brcm/supervisord.conf +++ b/platform/broadcom/docker-syncd-brcm/supervisord.conf @@ -3,27 +3,40 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python3 -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE +buffer_size=25 + [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name syncd -events=PROCESS_STATE_EXITED +events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING autostart=true autorestart=unexpected -[program:start.sh] -command=/usr/bin/start.sh +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE priority=1 -autostart=true -autorestart=false +autostart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true -[program:rsyslogd] -command=/usr/sbin/rsyslogd -n +[program:start] +command=/usr/bin/start.sh priority=2 autostart=false -autorestart=unexpected +autorestart=false +startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running [program:syncd] command=/usr/bin/syncd_start.sh @@ -32,12 +45,16 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited [program:ledinit] -command=/usr/bin/bcmcmd -t 60 "rcload /usr/share/sonic/platform/led_proc_init.soc" +command=/usr/bin/start_led.sh priority=4 autostart=false autorestart=false startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=syncd:running diff --git a/platform/broadcom/one-aboot.mk b/platform/broadcom/one-aboot.mk index f68319ab6449..959cda20907e 100644 --- a/platform/broadcom/one-aboot.mk +++ b/platform/broadcom/one-aboot.mk @@ -6,5 +6,10 @@ $(SONIC_ONE_ABOOT_IMAGE)_IMAGE_TYPE = aboot $(SONIC_ONE_ABOOT_IMAGE)_INSTALLS += $(BRCM_OPENNSL_KERNEL) $(ARISTA_PLATFORM_MODULE_DRIVERS) $(ARISTA_PLATFORM_MODULE_PYTHON2) $(ARISTA_PLATFORM_MODULE_PYTHON3) $(ARISTA_PLATFORM_MODULE) $(SONIC_ONE_ABOOT_IMAGE)_INSTALLS += $(PHY_CREDO) $(SONIC_ONE_ABOOT_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) +ifeq ($(INSTALL_DEBUG_TOOLS),y) +$(SONIC_ONE_ABOOT_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES) +$(SONIC_ONE_ABOOT_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES)) +else $(SONIC_ONE_ABOOT_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_IMAGES) +endif SONIC_INSTALLERS += $(SONIC_ONE_ABOOT_IMAGE) diff --git a/platform/broadcom/one-image.mk b/platform/broadcom/one-image.mk index b833f9ee2bc3..f557f17c7cea 100644 --- a/platform/broadcom/one-image.mk +++ b/platform/broadcom/one-image.mk @@ -4,12 +4,14 @@ SONIC_ONE_IMAGE = sonic-broadcom.bin $(SONIC_ONE_IMAGE)_MACHINE = broadcom $(SONIC_ONE_IMAGE)_IMAGE_TYPE = onie $(SONIC_ONE_IMAGE)_INSTALLS += $(BRCM_OPENNSL_KERNEL) +$(SONIC_ONE_IMAGE)_INSTALLS += $(PDDF_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \ $(DELL_Z9264F_PLATFORM_MODULE) \ $(DELL_S5232F_PLATFORM_MODULE) \ $(DELL_S5248F_PLATFORM_MODULE) \ $(DELL_Z9332F_PLATFORM_MODULE) \ + $(DELL_S5296F_PLATFORM_MODULE) \ $(DELL_Z9100_PLATFORM_MODULE) \ $(DELL_S6100_PLATFORM_MODULE) \ $(INGRASYS_S8900_54XC_PLATFORM_MODULE) \ @@ -39,6 +41,7 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \ $(INVENTEC_D7054Q28B_PLATFORM_MODULE) \ $(INVENTEC_D7264Q28B_PLATFORM_MODULE) \ $(INVENTEC_D6356_PLATFORM_MODULE) \ + $(INVENTEC_D6332_PLATFORM_MODULE) \ $(CEL_DX010_PLATFORM_MODULE) \ $(CEL_HALIBURTON_PLATFORM_MODULE) \ $(CEL_SEASTONE2_PLATFORM_MODULE) \ @@ -57,7 +60,9 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \ $(BRCM_XLR_GTS_PLATFORM_MODULE) \ $(DELTA_AG9032V2A_PLATFORM_MODULE) \ $(JUNIPER_QFX5210_PLATFORM_MODULE) \ - $(CEL_SILVERSTONE_PLATFORM_MODULE) + $(CEL_SILVERSTONE_PLATFORM_MODULE) \ + $(JUNIPER_QFX5200_PLATFORM_MODULE) \ + $(DELTA_AGC032_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/broadcom/platform-modules-accton.mk b/platform/broadcom/platform-modules-accton.mk index bab9c5ef9fef..395040d7561d 100755 --- a/platform/broadcom/platform-modules-accton.mk +++ b/platform/broadcom/platform-modules-accton.mk @@ -111,5 +111,3 @@ $(eval $(call add_extra_package,$(ACCTON_AS7712_32X_PLATFORM_MODULE),$(ACCTON_AS ACCTON_AS7315_27XB_PLATFORM_MODULE = sonic-platform-accton-as7315-27xb_$(ACCTON_AS7315_27XB_PLATFORM_MODULE_VERSION)_amd64.deb $(ACCTON_AS7315_27XB_PLATFORM_MODULE)_PLATFORM = x86_64-accton_as7315_27xb-r0 $(eval $(call add_extra_package,$(ACCTON_AS7712_32X_PLATFORM_MODULE),$(ACCTON_AS7315_27XB_PLATFORM_MODULE))) - -SONIC_STRETCH_DEBS += $(ACCTON_AS7712_32X_PLATFORM_MODULE) diff --git a/platform/broadcom/platform-modules-alphanetworks.mk b/platform/broadcom/platform-modules-alphanetworks.mk index 425656e06653..13e5fc4ff9e2 100644 --- a/platform/broadcom/platform-modules-alphanetworks.mk +++ b/platform/broadcom/platform-modules-alphanetworks.mk @@ -16,6 +16,5 @@ ALPHANETWORKS_SNH60B0_640F_PLATFORM_MODULE = sonic-platform-alphanetworks-snh60b $(ALPHANETWORKS_SNH60B0_640F_PLATFORM_MODULE)_PLATFORM = x86_64-alphanetworks_snh60b0_640f-r0 $(eval $(call add_extra_package,$(ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE),$(ALPHANETWORKS_SNH60B0_640F_PLATFORM_MODULE))) -SONIC_STRETCH_DEBS += $(ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE) diff --git a/platform/broadcom/platform-modules-arista.mk b/platform/broadcom/platform-modules-arista.mk index 480aa0cf8396..ac2c65fdf3c5 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))) @@ -22,4 +22,3 @@ export ARISTA_PLATFORM_MODULE ARISTA_PLATFORM_MODULE_PYTHON2 ARISTA_PLATFORM_MOD export ARISTA_SCD_DRIVER_CONFIG=m -SONIC_STRETCH_DEBS += $(ARISTA_PLATFORM_MODULE) diff --git a/platform/broadcom/platform-modules-brcm-xlr-gts.mk b/platform/broadcom/platform-modules-brcm-xlr-gts.mk index c35609c39476..28abe890acbd 100644 --- a/platform/broadcom/platform-modules-brcm-xlr-gts.mk +++ b/platform/broadcom/platform-modules-brcm-xlr-gts.mk @@ -12,4 +12,3 @@ SONIC_MAKE_DEBS += $(BRCM_XLR_GTS_PLATFORM_MODULE) export BRCM_XLR_GTS_PLATFORM_MODULE -SONIC_STRETCH_DEBS += $(BRCM_XLR_GTS_PLATFORM_MODULE) diff --git a/platform/broadcom/platform-modules-cel.mk b/platform/broadcom/platform-modules-cel.mk index 9fe4eb7b6932..de021df7e4db 100644 --- a/platform/broadcom/platform-modules-cel.mk +++ b/platform/broadcom/platform-modules-cel.mk @@ -28,4 +28,3 @@ CEL_SILVERSTONE_PLATFORM_MODULE = platform-modules-silverstone_$(CEL_SILVERSTONE $(CEL_SILVERSTONE_PLATFORM_MODULE)_PLATFORM = x86_64-cel_silverstone-r0 $(eval $(call add_extra_package,$(CEL_DX010_PLATFORM_MODULE),$(CEL_SILVERSTONE_PLATFORM_MODULE))) -SONIC_STRETCH_DEBS += $(CEL_DX010_PLATFORM_MODULE) diff --git a/platform/broadcom/platform-modules-dell.mk b/platform/broadcom/platform-modules-dell.mk index 298e3c4f7396..e4d4f56c53aa 100644 --- a/platform/broadcom/platform-modules-dell.mk +++ b/platform/broadcom/platform-modules-dell.mk @@ -7,6 +7,7 @@ DELL_Z9264F_PLATFORM_MODULE_VERSION = 1.1 DELL_S5232F_PLATFORM_MODULE_VERSION = 1.1 DELL_Z9332F_PLATFORM_MODULE_VERSION = 1.1 DELL_S5248F_PLATFORM_MODULE_VERSION = 1.1 +DELL_S5296F_PLATFORM_MODULE_VERSION = 1.1 export DELL_S6000_PLATFORM_MODULE_VERSION export DELL_Z9100_PLATFORM_MODULE_VERSION @@ -15,6 +16,7 @@ export DELL_Z9264F_PLATFORM_MODULE_VERSION export DELL_S5232F_PLATFORM_MODULE_VERSION export DELL_Z9332F_PLATFORM_MODULE_VERSION export DELL_S5248F_PLATFORM_MODULE_VERSION +export DELL_S5296F_PLATFORM_MODULE_VERSION DELL_Z9100_PLATFORM_MODULE = platform-modules-z9100_$(DELL_Z9100_PLATFORM_MODULE_VERSION)_amd64.deb $(DELL_Z9100_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-dell @@ -46,7 +48,10 @@ $(eval $(call add_extra_package,$(DELL_Z9100_PLATFORM_MODULE),$(DELL_Z9332F_PLAT DELL_S5248F_PLATFORM_MODULE = platform-modules-s5248f_$(DELL_S5248F_PLATFORM_MODULE_VERSION)_amd64.deb $(DELL_S5248F_PLATFORM_MODULE)_PLATFORM = x86_64-dellemc_s5248f_c3538-r0 $(eval $(call add_extra_package,$(DELL_Z9100_PLATFORM_MODULE),$(DELL_S5248F_PLATFORM_MODULE))) -SONIC_STRETCH_DEBS += $(DELL_Z9100_PLATFORM_MODULE) + +DELL_S5296F_PLATFORM_MODULE = platform-modules-s5296f_$(DELL_S5296F_PLATFORM_MODULE_VERSION)_amd64.deb +$(DELL_S5296F_PLATFORM_MODULE)_PLATFORM = x86_64-dellemc_s5296f_c3538-r0 +$(eval $(call add_extra_package,$(DELL_Z9100_PLATFORM_MODULE),$(DELL_S5296F_PLATFORM_MODULE))) #flashrom tool $(shell ./$(PLATFORM_PATH)/sonic-platform-modules-dell/tools/flashrom.sh > /dev/null 2>&1) diff --git a/platform/broadcom/platform-modules-delta.mk b/platform/broadcom/platform-modules-delta.mk index 17746488e02f..a524f2592fa8 100644 --- a/platform/broadcom/platform-modules-delta.mk +++ b/platform/broadcom/platform-modules-delta.mk @@ -5,12 +5,14 @@ DELTA_AG9064_PLATFORM_MODULE_VERSION = 1.1 DELTA_AG5648_PLATFORM_MODULE_VERSION = 1.1 DELTA_ET6248BRB_PLATFORM_MODULE_VERSION = 1.1 DELTA_AG9032V2A_PLATFORM_MODULE_VERSION = 1.1 +DELTA_AGC032_PLATFORM_MODULE_VERSION = 1.1 export DELTA_AG9032V1_PLATFORM_MODULE_VERSION export DELTA_AG9064_PLATFORM_MODULE_VERSION export DELTA_AG5648_PLATFORM_MODULE_VERSION export DELTA_ET6248BRB_PLATFORM_MODULE_VERSION export DELTA_AG9032V2A_PLATFORM_MODULE_VERSION +export DELTA_AGC032_PLATFORM_MODULE_VERSION DELTA_AG9032V1_PLATFORM_MODULE = platform-modules-ag9032v1_$(DELTA_AG9032V1_PLATFORM_MODULE_VERSION)_amd64.deb $(DELTA_AG9032V1_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-delta @@ -34,4 +36,8 @@ DELTA_AG9032V2A_PLATFORM_MODULE = platform-modules-ag9032v2a_$(DELTA_AG9032V2A_P $(DELTA_AG9032V2A_PLATFORM_MODULE)_PLATFORM = x86_64-delta_ag9032v2a-r0 $(eval $(call add_extra_package,$(DELTA_AG9032V1_PLATFORM_MODULE),$(DELTA_AG9032V2A_PLATFORM_MODULE))) +DELTA_AGC032_PLATFORM_MODULE = platform-modules-agc032_$(DELTA_AGC032_PLATFORM_MODULE_VERSION)_amd64.deb +$(DELTA_AGC032_PLATFORM_MODULE)_PLATFORM = x86_64-delta_agc032-r0 +$(eval $(call add_extra_package,$(DELTA_AG9032V1_PLATFORM_MODULE),$(DELTA_AGC032_PLATFORM_MODULE))) + SONIC_STRETCH_DEBS += $(DELTA_AG9032V1_PLATFORM_MODULE) diff --git a/platform/broadcom/platform-modules-ingrasys.mk b/platform/broadcom/platform-modules-ingrasys.mk index b6195698a1f9..9ce7cdb26487 100644 --- a/platform/broadcom/platform-modules-ingrasys.mk +++ b/platform/broadcom/platform-modules-ingrasys.mk @@ -35,4 +35,3 @@ $(eval $(call add_extra_package,$(INGRASYS_S9100_PLATFORM_MODULE),$(INGRASYS_S89 $(eval $(call add_extra_package,$(INGRASYS_S9100_PLATFORM_MODULE),$(INGRASYS_S8810_32Q_PLATFORM_MODULE))) $(eval $(call add_extra_package,$(INGRASYS_S9100_PLATFORM_MODULE),$(INGRASYS_S9200_64X_PLATFORM_MODULE))) -SONIC_STRETCH_DEBS += $(INGRASYS_S9100_PLATFORM_MODULE) diff --git a/platform/broadcom/platform-modules-inventec.mk b/platform/broadcom/platform-modules-inventec.mk index 871604ce91d9..4f88f5b92163 100644 --- a/platform/broadcom/platform-modules-inventec.mk +++ b/platform/broadcom/platform-modules-inventec.mk @@ -6,6 +6,7 @@ INVENTEC_D6254QS_PLATFORM_MODULE_VERSION = 1.1.0 INVENTEC_D6556_PLATFORM_MODULE_VERSION = 1.1.0 INVENTEC_D6356_PLATFORM_MODULE_VERSION = 1.1.0 INVENTEC_D7264Q28B_PLATFORM_MODULE_VERSION = 1.1.0 +INVENTEC_D6332_PLATFORM_MODULE_VERSION = 1.1.0 export INVENTEC_D7032Q28B_PLATFORM_MODULE_VERSION export INVENTEC_D7054Q28B_PLATFORM_MODULE_VERSION @@ -13,6 +14,7 @@ export INVENTEC_D6254QS_PLATFORM_MODULE_VERSION export INVENTEC_D6556_PLATFORM_MODULE_VERSION export INVENTEC_D6356_PLATFORM_MODULE_VERSION export INVENTEC_D7264Q28B_PLATFORM_MODULE_VERSION +export INVENTEC_D6332_PLATFORM_MODULE_VERSION INVENTEC_D7032Q28B_PLATFORM_MODULE = platform-modules-d7032q28b_$(INVENTEC_D7032Q28B_PLATFORM_MODULE_VERSION)_amd64.deb $(INVENTEC_D7032Q28B_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-inventec @@ -40,4 +42,7 @@ INVENTEC_D7264Q28B_PLATFORM_MODULE = platform-modules-d7264q28b_$(INVENTEC_D7264 $(INVENTEC_D7264Q28B_PLATFORM_MODULE)_PLATFORM = x86_64-inventec_d7264q28b-r0 $(eval $(call add_extra_package,$(INVENTEC_D7032Q28B_PLATFORM_MODULE),$(INVENTEC_D7264Q28B_PLATFORM_MODULE))) -SONIC_STRETCH_DEBS += $(INVENTEC_D7032Q28B_PLATFORM_MODULE) +INVENTEC_D6332_PLATFORM_MODULE = platform-modules-d6332_$(INVENTEC_D6332_PLATFORM_MODULE_VERSION)_amd64.deb +$(INVENTEC_D6332_PLATFORM_MODULE)_PLATFORM = x86_64-inventec_d6332-r0 +$(eval $(call add_extra_package,$(INVENTEC_D7032Q28B_PLATFORM_MODULE),$(INVENTEC_D6332_PLATFORM_MODULE))) + diff --git a/platform/broadcom/platform-modules-juniper.mk b/platform/broadcom/platform-modules-juniper.mk index 083dabda6d97..f6a9b68d70de 100755 --- a/platform/broadcom/platform-modules-juniper.mk +++ b/platform/broadcom/platform-modules-juniper.mk @@ -1,8 +1,10 @@ # Juniper Platform modules JUNIPER_QFX5210_PLATFORM_MODULE_VERSION = 1.1 +JUNIPER_QFX5200_PLATFORM_MODULE_VERSION = 1.1 export JUNIPER_QFX5210_PLATFORM_MODULE_VERSION +export JUNIPER_QFX5200_PLATFORM_MODULE_VERSION JUNIPER_QFX5210_PLATFORM_MODULE = sonic-platform-juniper-qfx5210_$(JUNIPER_QFX5210_PLATFORM_MODULE_VERSION)_amd64.deb $(JUNIPER_QFX5210_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-juniper @@ -10,4 +12,7 @@ $(JUNIPER_QFX5210_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_C $(JUNIPER_QFX5210_PLATFORM_MODULE)_PLATFORM = x86_64-juniper_qfx5210-r0 SONIC_DPKG_DEBS += $(JUNIPER_QFX5210_PLATFORM_MODULE) -SONIC_STRETCH_DEBS += $(JUNIPER_QFX5210_PLATFORM_MODULE) +JUNIPER_QFX5200_PLATFORM_MODULE = sonic-platform-juniper-qfx5200_$(JUNIPER_QFX5200_PLATFORM_MODULE_VERSION)_amd64.deb +$(JUNIPER_QFX5200_PLATFORM_MODULE)_PLATFORM = x86_64-juniper_qfx5200-r0 + +$(eval $(call add_extra_package,$(JUNIPER_QFX5210_PLATFORM_MODULE),$(JUNIPER_QFX5200_PLATFORM_MODULE))) diff --git a/platform/broadcom/platform-modules-mitac.mk b/platform/broadcom/platform-modules-mitac.mk index 6e7e05bf6c57..5a0c303f19d4 100644 --- a/platform/broadcom/platform-modules-mitac.mk +++ b/platform/broadcom/platform-modules-mitac.mk @@ -10,4 +10,3 @@ $(MITAC_LY1200_32X_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_ $(MITAC_LY1200_32X_PLATFORM_MODULE)_PLATFORM = x86_64-mitac_ly1200_b32h0_c3-r0 SONIC_DPKG_DEBS += $(MITAC_LY1200_32X_PLATFORM_MODULE) -SONIC_STRETCH_DEBS += $(MITAC_LY1200_32X_PLATFORM_MODULE) diff --git a/platform/broadcom/platform-modules-quanta.mk b/platform/broadcom/platform-modules-quanta.mk index 456af3019e38..267d3d9e7378 100644 --- a/platform/broadcom/platform-modules-quanta.mk +++ b/platform/broadcom/platform-modules-quanta.mk @@ -34,4 +34,3 @@ QUANTA_IX9_32X_PLATFORM_MODULE = sonic-platform-quanta-ix9-32x_$(QUANTA_IX9_32X_ $(QUANTA_IX9_32X_PLATFORM_MODULE)_PLATFORM = x86_64-quanta_ix9_bwde-r0 $(eval $(call add_extra_package,$(QUANTA_IX1B_32X_PLATFORM_MODULE),$(QUANTA_IX9_32X_PLATFORM_MODULE))) -SONIC_STRETCH_DEBS += $(QUANTA_IX1B_32X_PLATFORM_MODULE) diff --git a/platform/broadcom/rules.dep b/platform/broadcom/rules.dep index d8142ae3fb76..2e2d44ed018a 100644 --- a/platform/broadcom/rules.dep +++ b/platform/broadcom/rules.dep @@ -22,4 +22,3 @@ include $(PLATFORM_PATH)/one-pde-image.dep include $(PLATFORM_PATH)/raw-image.dep include $(PLATFORM_PATH)/one-aboot.dep include $(PLATFORM_PATH)/libsaithrift-dev.dep -include $(PLATFORM_PATH)/docker-ptf-brcm.dep diff --git a/platform/broadcom/rules.mk b/platform/broadcom/rules.mk index 8dd7b2c8cbb2..fbe0dd689a2e 100644 --- a/platform/broadcom/rules.mk +++ b/platform/broadcom/rules.mk @@ -19,7 +19,6 @@ include $(PLATFORM_PATH)/one-image.mk include $(PLATFORM_PATH)/raw-image.mk include $(PLATFORM_PATH)/one-aboot.mk include $(PLATFORM_PATH)/libsaithrift-dev.mk -include $(PLATFORM_PATH)/docker-ptf-brcm.mk BCMCMD = bcmcmd $(BCMCMD)_URL = "https://sonicstorage.blob.core.windows.net/packages/20190307/bcmcmd?sv=2015-04-05&sr=b&sig=sUdbU7oVbh5exbXXHVL5TDFBTWDDBASHeJ8Cp0B0TIc%3D&se=2038-05-06T22%3A34%3A19Z&sp=r" @@ -32,10 +31,12 @@ SONIC_ONLINE_FILES += $(BCMCMD) $(DSSERVE) SONIC_ALL += $(SONIC_ONE_IMAGE) $(SONIC_ONE_ABOOT_IMAGE) \ $(DOCKER_FPM) -# Inject brcm sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(BRCM_SAI) $(BRCM_SAI_DEV) +# Inject brcm sai into syncd +$(SYNCD)_DEPENDS += $(BRCM_SAI) $(BRCM_SAI_DEV) +$(SYNCD)_UNINSTALLS += $(BRCM_SAI_DEV) + ifeq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV) +$(SYNCD)_DEPENDS += $(LIBSAITHRIFT_DEV) endif # Runtime dependency on brcm sai is set only for syncd diff --git a/platform/broadcom/sai-modules.mk b/platform/broadcom/sai-modules.mk index 93132c2287bd..2d4262518c68 100644 --- a/platform/broadcom/sai-modules.mk +++ b/platform/broadcom/sai-modules.mk @@ -1,11 +1,8 @@ # Broadcom SAI modules -KVERSION = 4.9.0-11-2-amd64 -BRCM_OPENNSL_KERNEL_VERSION = 3.7.3.3-1 +BRCM_OPENNSL_KERNEL_VERSION = 4.3.0.10-2 BRCM_OPENNSL_KERNEL = opennsl-modules_$(BRCM_OPENNSL_KERNEL_VERSION)_amd64.deb $(BRCM_OPENNSL_KERNEL)_SRC_PATH = $(PLATFORM_PATH)/saibcm-modules $(BRCM_OPENNSL_KERNEL)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) SONIC_DPKG_DEBS += $(BRCM_OPENNSL_KERNEL) - -SONIC_STRETCH_DEBS += $(BRCM_OPENNSL_KERNEL) diff --git a/platform/broadcom/sai.dep b/platform/broadcom/sai.dep index 11cc72b192fb..c5b10a4e93a3 100644 --- a/platform/broadcom/sai.dep +++ b/platform/broadcom/sai.dep @@ -3,12 +3,16 @@ SPATH := $($(BRCM_SAI)_SRC_PATH) DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/broadcom/sai.mk platform/broadcom/sai.dep DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +# Get the Latest HTTP Header and calculate the SHA value as it is a softlink that always points to LATEST_INT_OCP_SAI_X.X.X +SAI_FLAGS := $(shell wget --spider --server-response $($(BRCM_SAI)_URL) $($(BRCM_SAI_DEV)_URL) 2>&1 \ + | grep -Ev -- '--|Date:|x-ms-request-id'|sha256sum|awk '{print $$1}' ) $(BRCM_SAI)_CACHE_MODE := GIT_CONTENT_SHA -$(BRCM_SAI)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(BRCM_SAI)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) $(SAI_FLAGS) $(BRCM_SAI)_DEP_FILES := $(DEP_FILES) + $(BRCM_SAI_DEV)_CACHE_MODE := GIT_CONTENT_SHA -$(BRCM_SAI_DEV)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(BRCM_SAI_DEV)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) $(SAI_FLAGS) $(BRCM_SAI_DEV)_DEP_FILES := $(DEP_FILES) diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 3d38c760d85b..046aca2af658 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,9 +1,9 @@ -BRCM_SAI = libsaibcm_3.7.3.3-3_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm_3.7.3.3-3_amd64.deb?sv=2015-04-05&sr=b&sig=1MS77TFH1wpXHIQuxvysznffb8shDJa7QWTCpXX3qH4%3D&se=2033-11-14T01%3A39%3A44Z&sp=r" - -BRCM_SAI_DEV = libsaibcm-dev_3.7.3.3-3_amd64.deb +BRCM_SAI = libsaibcm_4.3.0.13-1_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/4.3/master/libsaibcm_4.3.0.13-1_amd64.deb?sv=2015-04-05&sr=b&sig=e%2BBucofzEwCC%2BclqK1OeCi5YFpQAD4ID4FfODzszsuM%3D&se=2034-10-22T06%3A00%3A14Z&sp=r" +BRCM_SAI_DEV = libsaibcm-dev_4.3.0.13-1_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-3_amd64.deb?sv=2015-04-05&sr=b&sig=Y%2FXr6tZPrUQn5bLZqXYr6Nba%2BBbhz8lJdXyNEKZ3Sh8%3D&se=2033-11-14T01%3A44%3A38Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/4.3/master/libsaibcm-dev_4.3.0.13-1_amd64.deb?sv=2015-04-05&sr=b&sig=twfshldM6GQEphfU%2BQ4xmJlGJkv2Sy7KU1F72RYYM0A%3D&se=2034-10-22T06%3A00%3A45Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) +$(eval $(call add_conflict_package,$(BRCM_SAI_DEV),$(LIBSAIVS_DEV))) diff --git a/platform/broadcom/saibcm-modules/.gitignore b/platform/broadcom/saibcm-modules/.gitignore index 338005f50ce9..f2e54da55c5f 100644 --- a/platform/broadcom/saibcm-modules/.gitignore +++ b/platform/broadcom/saibcm-modules/.gitignore @@ -2,3 +2,9 @@ *.debhelper *.substvars *.ko + +build-arch-stamp +build/ +configure-stamp +debian/files +debian/opennsl-modules/ diff --git a/platform/broadcom/saibcm-modules/debian/changelog b/platform/broadcom/saibcm-modules/debian/changelog index 2be513ed0435..87d659d21a61 100644 --- a/platform/broadcom/saibcm-modules/debian/changelog +++ b/platform/broadcom/saibcm-modules/debian/changelog @@ -1,19 +1,32 @@ +opennsl (4.3.0.10-2) unstable; urgency=medium + + * Update to Broadcom SAI 4.3.0.10 + * Added SDKLT modules 4.3.0.10-2 + + -- Mahesh Maddikayala Thu, 21 Jan 2021 18:36:38 +0000 + +opennsl (4.2.1.3-1) unstable; urgency=medium + + * Update to Broadcom SAI 4.2.1.3 + + -- Mahesh Maddikayala Fri, 18 Sep 2029 10:57:47 +0000 + opennsl (3.7.3.3-1) unstable; urgency=medium - + * Port Broadcom SAI 3.7.3.3 * Cherry-pick change from master branch, 3.7.3.3-1 -- Judy Joseph Fri, 2 Dec 2019 15:32:47 +0000 opennsl (3.7.3.2-1) unstable; urgency=medium - + * Port Broadcom SAI 3.7.3.2 * Cherry-pick change from master branch, 3.7.3.2-1 -- Judy Joseph Fri, 12 Nov 2019 15:22:47 +0000 opennsl (3.7.3.1-1) unstable; urgency=medium - + * Port Broadcom SAI 3.7.3.1 * Cherry-pick change from master branch, 3.7.3.1-1 diff --git a/platform/broadcom/saibcm-modules/debian/control b/platform/broadcom/saibcm-modules/debian/control index fafe7dfb9299..60bcbafb1b1a 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-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned 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 a32540eadcf5..140d1186059e 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-11-2-amd64/extra +lib/modules/4.19.0-12-2-amd64/extra diff --git a/platform/broadcom/saibcm-modules/debian/opennsl-modules.init b/platform/broadcom/saibcm-modules/debian/opennsl-modules.init index 7def10cbff86..09112f5331ce 100755 --- a/platform/broadcom/saibcm-modules/debian/opennsl-modules.init +++ b/platform/broadcom/saibcm-modules/debian/opennsl-modules.init @@ -18,7 +18,9 @@ function create_devices() rm -f /dev/linux-bcm-knet rm -f /dev/linux-bcm-bde rm -f /dev/linux-kernel-bde + rm -f /dev/linux_ngbde + mknod /dev/linux_ngbde c 120 0 mknod /dev/linux-knet-cb c 121 0 mknod /dev/linux-bcm-knet c 122 0 mknod /dev/linux-bcm-bde c 126 0 @@ -57,8 +59,9 @@ function load_kernel_modules() # There is a different psample.ko module getting created at net/psample/psample.ko insmod /lib/modules/$(uname -r)/extra/psample.ko - modprobe linux-bcm-knet use_rx_skb=1 rx_buffer_size=9238 debug=0x5020 + modprobe linux-bcm-knet use_rx_skb=1 rx_buffer_size=9238 debug=0x5020 default_mtu=9100 modprobe linux-knet-cb + modprobe linux_ngbde } function remove_kernel_modules() @@ -68,6 +71,7 @@ function remove_kernel_modules() rmmod linux-bcm-knet rmmod linux-user-bde rmmod linux-kernel-bde + rmmod linux_ngbde } case "$1" in diff --git a/platform/broadcom/saibcm-modules/debian/opennsl-modules.install b/platform/broadcom/saibcm-modules/debian/opennsl-modules.install index 9802d2f2443a..5e8e70bb189f 100644 --- a/platform/broadcom/saibcm-modules/debian/opennsl-modules.install +++ b/platform/broadcom/saibcm-modules/debian/opennsl-modules.install @@ -1,6 +1,8 @@ -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 +systems/linux/user/x86-smp_generic_64-2_6/linux-bcm-knet.ko lib/modules/4.19.0-12-2-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/linux-kernel-bde.ko lib/modules/4.19.0-12-2-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/linux-user-bde.ko lib/modules/4.19.0-12-2-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/linux-knet-cb.ko lib/modules/4.19.0-12-2-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/psample.ko lib/modules/4.19.0-12-2-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/linux-bcm-ptp-clock.ko lib/modules/4.19.0-12-2-amd64/extra systemd/opennsl-modules.service lib/systemd/system +sdklt/linux/bde/linux_ngbde.ko lib/modules/4.19.0-12-2-amd64/extra diff --git a/platform/broadcom/saibcm-modules/debian/rules b/platform/broadcom/saibcm-modules/debian/rules index 636874251aa9..572471027c87 100755 --- a/platform/broadcom/saibcm-modules/debian/rules +++ b/platform/broadcom/saibcm-modules/debian/rules @@ -34,6 +34,9 @@ sname:=opennsl PACKAGE=opennsl-modules # modifieable for experiments or debugging m-a MA_DIR ?= /usr/share/modass +KVERSION ?= 4.19.0-12-2-amd64 +KERNVERSION ?= 4.19.0-12-2 + # load generic variable handling -include $(MA_DIR)/include/generic.make # load default rules, including kdist, kdist_image, ... @@ -60,7 +63,13 @@ 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-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 + SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 \ + KERNDIR=/usr/src/linux-headers-$(KERNVERSION)-common \ + KERNEL_SRC=/usr/src/linux-headers-$(KERNVERSION)-amd64 \ + $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean + SDK=$(realpath .) BUILD_KNET_CB=1 BUILD_PSAMPLE=1 \ + KDIR=/usr/src/linux-headers-$(KERNVERSION)-common \ + $(MAKE) -C sdklt/ clean # rm -f driver/*.o driver/*.ko # ### end KERNEL SETUP @@ -74,18 +83,36 @@ configure-stamp: build-arch: configure-stamp build-arch-stamp -build-arch-stamp: +build-arch-stamp: dh_testdir + # create links + cd /; sudo mkdir -p /lib/modules/$(KERNVERSION)-amd64 + cd /; sudo rm /lib/modules/$(KERNVERSION)-amd64/build + cd /; sudo rm /lib/modules/$(KERNVERSION)-amd64/source + cd /; sudo ln -s /usr/src/linux-headers-$(KERNVERSION)-common/ /lib/modules/$(KERNVERSION)-amd64/source + cd /; sudo ln -s /usr/src/linux-headers-$(KERNVERSION)-amd64/ /lib/modules/$(KERNVERSION)-amd64/build + cd /; sudo ln -s /usr/src/linux-headers-$(KERNVERSION)-amd64/include/generated/ /usr/src/linux-headers-$(KERNVERSION)-common/include/generated + cd /; sudo ln -s /usr/src/linux-headers-$(KERNVERSION)-amd64/arch/x86/include/generated/ /usr/src/linux-headers-$(KERNVERSION)-common/arch/x86/include/generated + cd /; sudo ln -s /usr/src/linux-headers-$(KERNVERSION)-amd64/include/config/ /usr/src/linux-headers-$(KERNVERSION)-common/include/config + cd /; sudo cp /usr/src/linux-headers-$(KERNVERSION)-amd64/Module.symvers /usr/src/linux-headers-$(KERNVERSION)-common/Module.symvers + # 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-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 + SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 \ + KERNDIR=/usr/src/linux-headers-$(KERNVERSION)-common \ + KERNEL_SRC=/usr/src/linux-headers-$(KERNVERSION)-amd64 \ + $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 + + SDK=$(realpath .) BUILD_KNET_CB=1 BUILD_PSAMPLE=1 \ + KDIR=/usr/src/linux-headers-$(KERNVERSION)-common \ + $(MAKE) -C sdklt/ kmod touch $@ #k = $(shell echo $(KVERS) | grep -q ^2.6 && echo k) build-indep: configure-stamp build-indep-stamp -build-indep-stamp: +build-indep-stamp: dh_testdir # Add here command to compile/build the arch indep package. @@ -97,13 +124,20 @@ build-indep-stamp: build: build-arch -clean: +clean: dh_testdir #dh_testroot 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-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 + SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 \ + KERNDIR=/usr/src/linux-headers-$(KERNVERSION)-common \ + KERNEL_SRC=/usr/src/linux-headers-$(KERNVERSION)-amd64 \ + $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean + + SDK=$(realpath .) BUILD_KNET_CB=1 BUILD_PSAMPLE=1 \ + KDIR=/usr/src/linux-headers-$(KERNVERSION)-common \ + $(MAKE) -C sdklt/ clean dh_clean diff --git a/platform/broadcom/saibcm-modules/include/ibde.h b/platform/broadcom/saibcm-modules/include/ibde.h index 45112eadcb4b..fb9d13d1d5fe 100644 --- a/platform/broadcom/saibcm-modules/include/ibde.h +++ b/platform/broadcom/saibcm-modules/include/ibde.h @@ -1,5 +1,10 @@ /* - * Copyright 2017 Broadcom + * Copyright 2007-2020 Broadcom Inc. All rights reserved. + * + * Permission is granted to use, copy, modify and/or distribute this + * software under either one of the licenses below. + * + * License Option 1: GPL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. + * + * + * License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license + * + * This software is governed by the Broadcom Open Network Switch APIs license: + * https://www.broadcom.com/products/ethernet-connectivity/software/opennsa */ /* * $Id: ibde.h,v 1.27 Broadcom SDK $ @@ -34,6 +45,12 @@ typedef struct ibde_dev_s { sal_vaddr_t base_address; sal_vaddr_t base_address1; sal_vaddr_t base_address2; + /* a unique number representing the specific device. + * Must be different for different devices. + * May be used to identify specific devices in the system. + * May be implemented as a full PCIe address, a persistent configurable user value, ... + * Possible implementation value stores in QSPI flash memory of the device. */ + uint32 dev_unique_id; } ibde_dev_t; diff --git a/platform/broadcom/saibcm-modules/include/kcom.h b/platform/broadcom/saibcm-modules/include/kcom.h index 1e3cad0753bc..5129400ca8cd 100644 --- a/platform/broadcom/saibcm-modules/include/kcom.h +++ b/platform/broadcom/saibcm-modules/include/kcom.h @@ -1,5 +1,10 @@ /* - * Copyright 2017 Broadcom + * Copyright 2007-2020 Broadcom Inc. All rights reserved. + * + * Permission is granted to use, copy, modify and/or distribute this + * software under either one of the licenses below. + * + * License Option 1: GPL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. + * + * + * License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license + * + * This software is governed by the Broadcom Open Network Switch APIs license: + * https://www.broadcom.com/products/ethernet-connectivity/software/opennsa */ /* * $Id: kcom.h,v 1.9 Broadcom SDK $ @@ -59,8 +70,9 @@ #define KCOM_M_DBGPKT_SET 41 /* Enbale debug packet function */ #define KCOM_M_DBGPKT_GET 42 /* Get debug packet function info */ #define KCOM_M_WB_CLEANUP 51 /* Clean up for warmbooting */ +#define KCOM_M_CLOCK_CMD 52 /* Clock Commands */ -#define KCOM_VERSION 10 /* Protocol version */ +#define KCOM_VERSION 12 /* Protocol version */ /* * Message status codes @@ -138,11 +150,10 @@ typedef struct kcom_netif_s { uint16 vlan; uint16 qnum; uint8 macaddr[6]; - uint8 ptch[2]; - uint8 itmh[4]; uint8 system_headers[KCOM_NETIF_SYSTEM_HEADERS_SIZE_MAX]; uint8 system_headers_size; char name[KCOM_NETIF_NAME_MAX]; + uint8 phys_port; } kcom_netif_t; /* @@ -225,13 +236,9 @@ typedef struct kcom_filter_s { uint8 b[KCOM_FILTER_BYTES_MAX]; uint32 w[KCOM_FILTER_WORDS_MAX]; } mask; - /** Information to parse Dune system headers */ - uint32 ftmh_lb_key_ext_size; - uint32 ftmh_stacking_ext_size; - uint32 pph_base_size; - uint32 pph_lif_ext_size[8]; - uint8 udh_enable; - uint32 udh_length_type[4]; + /** Mark to match source modid and modport */ + uint8 is_src_modport; + uint8 spa_unit; } kcom_filter_t; /* @@ -338,6 +345,21 @@ typedef struct kcom_msg_version_s { uint32 filter_max; } kcom_msg_version_t; +/* + * Request KCOM interface clock info. + */ +#define KSYNC_M_HW_INIT 0 +#define KSYNC_M_HW_DEINIT 1 +#define KSYNC_M_VERSION 2 +#define KSYNC_M_HW_TS_DISABLE 3 +#define KSYNC_M_MTP_TS_UPDATE_ENABLE 4 +#define KSYNC_M_MTP_TS_UPDATE_DISABLE 5 + +typedef struct kcom_clock_info_s { + uint8 cmd; + int32 data[8]; +} kcom_clock_info_t; + /* * Send literal string to/from kernel module. * Mainly for debugging purposes. @@ -386,6 +408,19 @@ typedef struct kcom_msg_hw_init_s { uint8 pkt_hdr_size; uint32 dma_hi; uint32 cdma_channels; + /* + * Information to parse Dune system headers + */ + uint32 ftmh_lb_key_ext_size; + uint32 ftmh_stacking_ext_size; + uint32 pph_base_size; + uint32 pph_lif_ext_size[8]; + uint32 udh_length_type[4]; + uint32 udh_size; + uint32 oamp_punted; + uint8 no_skip_udh_check; + uint8 system_headers_mode; + uint8 udh_enable; } kcom_msg_hw_init_t; /* @@ -445,6 +480,14 @@ typedef struct kcom_msg_netif_destroy_s { kcom_msg_hdr_t hdr; } kcom_msg_netif_destroy_t; +/* + * Destroy system network interface. + */ +typedef struct kcom_msg_clock_s{ + kcom_msg_hdr_t hdr; + kcom_clock_info_t clock_info; +} kcom_msg_clock_cmd_t; + /* * Get list of currently defined system network interfaces. */ @@ -486,7 +529,7 @@ typedef struct kcom_msg_filter_destroy_s { * Get list of currently defined packet filters. */ #ifndef KCOM_FILTER_MAX -#define KCOM_FILTER_MAX 128 +#define KCOM_FILTER_MAX 128 #endif typedef struct kcom_msg_filter_list_s { @@ -535,6 +578,7 @@ typedef union kcom_msg_s { kcom_msg_dbg_pkt_set_t dbg_pkt_set; kcom_msg_dbg_pkt_get_t dbg_pkt_get; kcom_msg_wb_cleanup_t wb_cleanup; + kcom_msg_clock_cmd_t clock_cmd; } kcom_msg_t; /* diff --git a/platform/broadcom/saibcm-modules/include/sal/core/sync.h b/platform/broadcom/saibcm-modules/include/sal/core/sync.h index 75dd6ce68312..03fd2facc907 100644 --- a/platform/broadcom/saibcm-modules/include/sal/core/sync.h +++ b/platform/broadcom/saibcm-modules/include/sal/core/sync.h @@ -1,5 +1,10 @@ /* - * Copyright 2017 Broadcom + * Copyright 2007-2020 Broadcom Inc. All rights reserved. + * + * Permission is granted to use, copy, modify and/or distribute this + * software under either one of the licenses below. + * + * License Option 1: GPL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. + * + * + * License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license + * + * This software is governed by the Broadcom Open Network Switch APIs license: + * https://www.broadcom.com/products/ethernet-connectivity/software/opennsa */ /* * $Id: sync.h,v 1.1 Broadcom SDK $ diff --git a/platform/broadcom/saibcm-modules/include/sal/core/thread.h b/platform/broadcom/saibcm-modules/include/sal/core/thread.h index b7ecb722489f..86713d1e0742 100644 --- a/platform/broadcom/saibcm-modules/include/sal/core/thread.h +++ b/platform/broadcom/saibcm-modules/include/sal/core/thread.h @@ -1,5 +1,10 @@ /* - * Copyright 2017 Broadcom + * Copyright 2007-2020 Broadcom Inc. All rights reserved. + * + * Permission is granted to use, copy, modify and/or distribute this + * software under either one of the licenses below. + * + * License Option 1: GPL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. + * + * + * License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license + * + * This software is governed by the Broadcom Open Network Switch APIs license: + * https://www.broadcom.com/products/ethernet-connectivity/software/opennsa */ /* * $Id: thread.h,v 1.1 Broadcom SDK $ diff --git a/platform/broadcom/saibcm-modules/include/sal/types.h b/platform/broadcom/saibcm-modules/include/sal/types.h index b6b40f762939..43d64dbcc6b9 100644 --- a/platform/broadcom/saibcm-modules/include/sal/types.h +++ b/platform/broadcom/saibcm-modules/include/sal/types.h @@ -1,5 +1,10 @@ /* - * Copyright 2017 Broadcom + * Copyright 2007-2020 Broadcom Inc. All rights reserved. + * + * Permission is granted to use, copy, modify and/or distribute this + * software under either one of the licenses below. + * + * License Option 1: GPL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. + * + * + * License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license + * + * This software is governed by the Broadcom Open Network Switch APIs license: + * https://www.broadcom.com/products/ethernet-connectivity/software/opennsa */ /* * $Id: types.h,v 1.3 Broadcom SDK $ @@ -92,17 +103,25 @@ typedef signed int int32; /* 32-bit quantity */ #define COUNTOF(ary) ((int) (sizeof (ary) / sizeof ((ary)[0]))) -typedef uint32 sal_paddr_t; /* Physical address (PCI address) */ - #ifdef PTRS_ARE_64BITS -typedef uint64 sal_vaddr_t; /* Virtual address (Host address) */ -#define PTR_TO_INT(x) ((uint32)(((sal_vaddr_t)(x))&0xFFFFFFFF)) +typedef uint64 sal_vaddr_t; /* Virtual address (Host address) */ +typedef uint64 sal_paddr_t; /* Physical address (PCI address) */ +#define PTR_TO_INT(x) ((uint32)(((sal_vaddr_t)(x))&0xFFFFFFFF)) +#define PTR_HI_TO_INT(x) ((uint32)((((sal_vaddr_t)(x))>>32)&0xFFFFFFFF)) #else -typedef uint32 sal_vaddr_t; /* Virtual address (Host address) */ -#define PTR_TO_INT(x) ((uint32)(x)) +typedef uint32 sal_vaddr_t; /* Virtual address (Host address) */ +/* Physical address (PCI address) */ +#ifdef PHYS_ADDRS_ARE_64BITS +typedef uint64 sal_paddr_t; +#define PTR_HI_TO_INT(x) ((uint32)((((uint64)(x))>>32)&0xFFFFFFFF)) +#else +typedef uint32 sal_paddr_t; +#define PTR_HI_TO_INT(x) (0) +#endif +#define PTR_TO_INT(x) ((uint32)(x)) #endif -#define INT_TO_PTR(x) ((void *)((sal_vaddr_t)(x))) +#define INT_TO_PTR(x) ((void *)((sal_vaddr_t)(x))) #define PTR_TO_UINTPTR(x) ((sal_vaddr_t)(x)) #define UINTPTR_TO_PTR(x) ((void *)(x)) @@ -128,6 +147,7 @@ typedef union #define SAL_I2C_DEV_TYPE 0x00040 /* I2C device */ #define SAL_AXI_DEV_TYPE 0x00080 /* AXI device */ #define SAL_EMMI_DEV_TYPE 0x10000 /* EMMI device */ +#define SAL_COMPOSITE_DEV_TYPE 0x20000 /* Composite device, composed of sub-devices with buses */ #define SAL_DEV_BUS_TYPE_MASK 0xf00ff /* Odd for historical reasons */ /* Device types */ @@ -152,4 +172,4 @@ typedef union /* Special access addresses */ #define SAL_DEV_OP_EMMI_INIT 0x0fff1000 -#endif /* !_SAL_TYPES_H */ +#endif /* !_SAL_TYPES_H */ diff --git a/platform/broadcom/saibcm-modules/include/sdk_config.h b/platform/broadcom/saibcm-modules/include/sdk_config.h index 9d781114bdf3..6ce7d77d52d0 100644 --- a/platform/broadcom/saibcm-modules/include/sdk_config.h +++ b/platform/broadcom/saibcm-modules/include/sdk_config.h @@ -1,5 +1,10 @@ /* - * Copyright 2017 Broadcom + * Copyright 2007-2020 Broadcom Inc. All rights reserved. + * + * Permission is granted to use, copy, modify and/or distribute this + * software under either one of the licenses below. + * + * License Option 1: GPL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. + * + * + * License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license + * + * This software is governed by the Broadcom Open Network Switch APIs license: + * https://www.broadcom.com/products/ethernet-connectivity/software/opennsa */ /* * $Id: sdk_config.h,v 1.5 Broadcom SDK $ diff --git a/platform/broadcom/saibcm-modules/include/soc/devids.h b/platform/broadcom/saibcm-modules/include/soc/devids.h index 7546ef392298..89fabac44537 100644 --- a/platform/broadcom/saibcm-modules/include/soc/devids.h +++ b/platform/broadcom/saibcm-modules/include/soc/devids.h @@ -1,5 +1,10 @@ /* - * Copyright 2017 Broadcom + * Copyright 2007-2020 Broadcom Inc. All rights reserved. + * + * Permission is granted to use, copy, modify and/or distribute this + * software under either one of the licenses below. + * + * License Option 1: GPL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as @@ -12,9 +17,15 @@ * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. + * + * + * License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license + * + * This software is governed by the Broadcom Open Network Switch APIs license: + * https://www.broadcom.com/products/ethernet-connectivity/software/opennsa */ /* - * Copyright: (c) 2019 Broadcom. + * Copyright: (c) 2020 Broadcom. * All Rights Reserved. */ @@ -1211,11 +1222,13 @@ #define BCM56169_B0_REV_ID 0x11 #define BCM56169_B1_REV_ID 0x12 +#define BCM56980_DEVICE_ID_MASK 0xFFF0 #define BCM56980_DEVICE_ID 0xb980 #define BCM56980_A0_REV_ID 1 #define BCM56980_B0_REV_ID 0x11 #define BCM56981_DEVICE_ID 0xb981 #define BCM56981_A0_REV_ID 1 +#define BCM56981_B0_REV_ID 0x11 #define BCM56982_DEVICE_ID 0xb982 #define BCM56982_A0_REV_ID 1 #define BCM56982_B0_REV_ID 0x11 @@ -1248,6 +1261,42 @@ #define BCM56166_A0_REV_ID 1 #define BCM56166_B0_REV_ID 0x11 +#define BCM56273_DEVICE_ID 0xb273 +#define BCM56273_A0_REV_ID 1 +#define BCM56273_A1_REV_ID 2 + +#define BCM56274_DEVICE_ID 0xb274 +#define BCM56274_A0_REV_ID 1 +#define BCM56274_A1_REV_ID 2 + +#define BCM56275_DEVICE_ID 0xb275 +#define BCM56275_A0_REV_ID 1 +#define BCM56275_A1_REV_ID 2 + +#define BCM56276_DEVICE_ID 0xb276 +#define BCM56276_A0_REV_ID 1 +#define BCM56276_A1_REV_ID 2 + +#define BCM56277_DEVICE_ID 0xb277 +#define BCM56277_A0_REV_ID 1 +#define BCM56277_A1_REV_ID 2 + +#define BCM56278_DEVICE_ID 0xb278 +#define BCM56278_A0_REV_ID 1 +#define BCM56278_A1_REV_ID 2 + +#define BCM56279_DEVICE_ID 0xb279 +#define BCM56279_A1_REV_ID 2 + +#define BCM56575_DEVICE_ID 0xb575 +#define BCM56575_A1_REV_ID 2 + +#define BCM56175_DEVICE_ID 0xb175 +#define BCM56175_A1_REV_ID 2 + +#define BCM56176_DEVICE_ID 0xb176 +#define BCM56176_A1_REV_ID 2 + #define BCM53440_DEVICE_ID 0x8440 #define BCM53440_A0_REV_ID 1 #define BCM53440_B0_REV_ID 0x11 @@ -1277,18 +1326,23 @@ #define BCM56670_DEVICE_ID 0xb670 #define BCM56670_A0_REV_ID 1 #define BCM56670_B0_REV_ID 0x11 +#define BCM56670_C0_REV_ID 0x21 + #define BCM56671_DEVICE_ID 0xb671 #define BCM56671_A0_REV_ID 1 #define BCM56671_B0_REV_ID 0x11 +#define BCM56671_C0_REV_ID 0x21 #define BCM56672_DEVICE_ID 0xb672 #define BCM56672_A0_REV_ID 1 #define BCM56672_B0_REV_ID 0x11 +#define BCM56672_C0_REV_ID 0x21 #define BCM56675_DEVICE_ID 0xb675 #define BCM56675_A0_REV_ID 1 #define BCM56675_B0_REV_ID 0x11 +#define BCM56675_C0_REV_ID 0x21 #define BCM56565_DEVICE_ID 0xb565 @@ -1312,9 +1366,6 @@ #define BCM56760_A1_REV_ID 2 #define BCM56760_B0_REV_ID 0x11 -#define BCM56761_DEVICE_ID 0xb761 -#define BCM56761_A0_REV_ID 1 -#define BCM56761_B0_REV_ID 0x11 #define BCM56761_DEVICE_ID 0xb761 #define BCM56761_A0_REV_ID 1 @@ -1372,6 +1423,13 @@ #define BCM53575_A0_REV_ID 1 #define BCM53575_B0_REV_ID 0x11 +#define BCM56070_DEVICE_ID 0xb070 +#define BCM56070_A0_REV_ID 1 +#define BCM56071_DEVICE_ID 0xb071 +#define BCM56071_A0_REV_ID 1 +#define BCM56072_DEVICE_ID 0xb072 +#define BCM56072_A0_REV_ID 1 + #define BCM56965_DEVICE_ID 0xb965 #define BCM56965_A0_REV_ID 1 @@ -1407,42 +1465,52 @@ #define BCM56370_DEVICE_ID 0xb370 #define BCM56370_A0_REV_ID 1 #define BCM56370_A1_REV_ID 0x02 +#define BCM56370_A2_REV_ID 0x03 #define BCM56371_DEVICE_ID 0xb371 #define BCM56371_A0_REV_ID 1 #define BCM56371_A1_REV_ID 0x02 +#define BCM56371_A2_REV_ID 0x03 #define BCM56372_DEVICE_ID 0xb372 #define BCM56372_A0_REV_ID 1 #define BCM56372_A1_REV_ID 0x02 +#define BCM56372_A2_REV_ID 0x03 #define BCM56374_DEVICE_ID 0xb374 #define BCM56374_A0_REV_ID 1 #define BCM56374_A1_REV_ID 0x02 +#define BCM56374_A2_REV_ID 0x03 #define BCM56375_DEVICE_ID 0xb375 #define BCM56375_A0_REV_ID 1 #define BCM56375_A1_REV_ID 0x02 +#define BCM56375_A2_REV_ID 0x03 #define BCM56376_DEVICE_ID 0xb376 #define BCM56376_A0_REV_ID 1 #define BCM56376_A1_REV_ID 0x02 +#define BCM56376_A2_REV_ID 0x03 #define BCM56377_DEVICE_ID 0xb377 #define BCM56377_A0_REV_ID 1 #define BCM56377_A1_REV_ID 0x02 +#define BCM56377_A2_REV_ID 0x03 #define BCM56577_DEVICE_ID 0xb577 #define BCM56577_A0_REV_ID 1 #define BCM56577_A1_REV_ID 0x02 +#define BCM56577_A2_REV_ID 0x03 #define BCM56578_DEVICE_ID 0xb578 #define BCM56578_A0_REV_ID 1 #define BCM56578_A1_REV_ID 0x02 +#define BCM56578_A2_REV_ID 0x03 #define BCM56579_DEVICE_ID 0xb579 #define BCM56579_A0_REV_ID 1 #define BCM56579_A1_REV_ID 0x02 +#define BCM56579_A2_REV_ID 0x03 #define BCM56770_DEVICE_ID 0xb770 #define BCM56770_A0_REV_ID 1 @@ -1450,6 +1518,16 @@ #define BCM56771_DEVICE_ID 0xb771 #define BCM56771_A0_REV_ID 1 +#define BCM56470_DEVICE_ID 0xb470 +#define BCM56470_A0_REV_ID 1 +#define BCM56471_DEVICE_ID 0xb471 +#define BCM56471_A0_REV_ID 1 +#define BCM56472_DEVICE_ID 0xb472 +#define BCM56472_A0_REV_ID 1 +#define BCM56475_DEVICE_ID 0xb475 +#define BCM56475_A0_REV_ID 1 + + #define BCM53540_DEVICE_ID 0x8540 #define BCM53540_A0_REV_ID 1 #define BCM53547_DEVICE_ID 0x8547 @@ -1486,19 +1564,6 @@ #define BCM88650_A0_REV_ID ARAD_A0_REV_ID #define BCM88650_B0_REV_ID ARAD_B0_REV_ID #define BCM88650_B1_REV_ID ARAD_B1_REV_ID -#define BCM88750_DEVICE_ID 0x8750 -#define BCM88750_A0_REV_ID 0x0000 -#define BCM88750_B0_REV_ID 0x0011 -#define BCM88753_DEVICE_ID 0x8753 -#define BCM88753_A0_REV_ID 0x0000 -#define BCM88753_B0_REV_ID 0x0011 -#define BCM88754_DEVICE_ID 0x8754 -#define BCM88754_A0_REV_ID 0x0000 -#define BCM88754_ORIGINAL_VENDOR_ID 0x16FC -#define BCM88754_ORIGINAL_DEVICE_ID 0x020F -#define BCM88754_A0_ORIGINAL_REV_ID 0x0001 -#define BCM88755_DEVICE_ID 0x8755 -#define BCM88755_B0_REV_ID 0x0011 #define BCM88770_DEVICE_ID 0x8770 #define BCM88770_A1_REV_ID 0x0002 #define BCM88773_DEVICE_ID 0x8773 @@ -1526,6 +1591,7 @@ #define DNXC_A1_REV_ID 0x0002 #define DNXC_B0_REV_ID 0x0011 #define DNXC_B1_REV_ID 0x0012 +#define DNXC_DEVID_FAMILY_MASK 0xfff0 #define BCM88790_DEVICE_ID 0x8790 #define BCM88790_A0_REV_ID DNXC_A0_REV_ID #define BCM88790_B0_REV_ID DNXC_B0_REV_ID @@ -1544,7 +1610,6 @@ #define BCM8879D_DEVICE_ID 0x879D #define BCM8879E_DEVICE_ID 0x879E #define BCM8879F_DEVICE_ID 0x879F -#define BCM_DNXF_DEVID_MASK 0xFFF0 #define ARADPLUS_DEVICE_ID 0x8660 #define ARADPLUS_A0_REV_ID 0x0001 #define BCM88660_DEVICE_ID ARADPLUS_DEVICE_ID @@ -1675,19 +1740,22 @@ #define BCM88685_DEVICE_ID 0x8685 #define BCM88685_A0_REV_ID JERICHO_PLUS_A0_REV_ID +#define BCM88687_DEVICE_ID 0x8687 +#define BCM88687_A0_REV_ID JERICHO_PLUS_A0_REV_ID + #define BCM88380_DEVICE_ID 0x8380 #define BCM88380_A0_REV_ID JERICHO_PLUS_A0_REV_ID #define BCM88381_DEVICE_ID 0x8381 #define BCM88381_A0_REV_ID JERICHO_PLUS_A0_REV_ID -#define JERICHO_2_DEVICE_ID 0x8690 -#define JERICHO_2_A0_REV_ID DNXC_A0_REV_ID -#define JERICHO_2_B0_REV_ID DNXC_B0_REV_ID -#define JERICHO_2_B1_REV_ID DNXC_B1_REV_ID -#define BCM88690_DEVICE_ID JERICHO_2_DEVICE_ID -#define BCM88690_A0_REV_ID JERICHO_2_A0_REV_ID -#define BCM88690_B0_REV_ID JERICHO_2_B0_REV_ID -#define BCM88690_B1_REV_ID JERICHO_2_B1_REV_ID +#define JERICHO2_DEVICE_ID 0x8690 +#define JERICHO2_A0_REV_ID DNXC_A0_REV_ID +#define JERICHO2_B0_REV_ID DNXC_B0_REV_ID +#define JERICHO2_B1_REV_ID DNXC_B1_REV_ID +#define BCM88690_DEVICE_ID JERICHO2_DEVICE_ID +#define BCM88690_A0_REV_ID JERICHO2_A0_REV_ID +#define BCM88690_B0_REV_ID JERICHO2_B0_REV_ID +#define BCM88690_B1_REV_ID JERICHO2_B1_REV_ID #define BCM88691_DEVICE_ID 0x8691 #define BCM88692_DEVICE_ID 0x8692 #define BCM88693_DEVICE_ID 0x8693 @@ -1703,12 +1771,109 @@ #define BCM8869D_DEVICE_ID 0x869D #define BCM8869E_DEVICE_ID 0x869E #define BCM8869F_DEVICE_ID 0x869F -#define BCM_JR2_DEVID_MASK 0xFFF0 -#define J2C_DEVICE_ID 0x8800 +#define J2C_DEVICE_ID 0x8800 +#define J2C_2ND_DEVICE_ID 0x8820 +#define J2C_DEVID_FAMILY_MASK 0xffd0 #define J2C_A0_REV_ID DNXC_A0_REV_ID +#define J2C_A1_REV_ID DNXC_A1_REV_ID #define BCM88800_DEVICE_ID J2C_DEVICE_ID +#define BCM88820_DEVICE_ID J2C_2ND_DEVICE_ID #define BCM88800_A0_REV_ID J2C_A0_REV_ID +#define BCM88800_A1_REV_ID J2C_A1_REV_ID +#define BCM88801_DEVICE_ID 0x8801 +#define BCM88802_DEVICE_ID 0x8802 +#define BCM88803_DEVICE_ID 0x8803 +#define BCM88804_DEVICE_ID 0x8804 +#define BCM88805_DEVICE_ID 0x8805 +#define BCM88806_DEVICE_ID 0x8806 +#define BCM88807_DEVICE_ID 0x8807 +#define BCM88808_DEVICE_ID 0x8808 +#define BCM88809_DEVICE_ID 0x8809 +#define BCM8880A_DEVICE_ID 0x880A +#define BCM8880B_DEVICE_ID 0x880B +#define BCM8880C_DEVICE_ID 0x880C +#define BCM8880D_DEVICE_ID 0x880D +#define BCM8880E_DEVICE_ID 0x880E +#define BCM8880F_DEVICE_ID 0x880F +#define BCM88821_DEVICE_ID 0x8821 +#define BCM88822_DEVICE_ID 0x8822 +#define BCM88823_DEVICE_ID 0x8823 +#define BCM88824_DEVICE_ID 0x8824 +#define BCM88825_DEVICE_ID 0x8825 +#define BCM88826_DEVICE_ID 0x8826 +#define BCM88827_DEVICE_ID 0x8827 +#define BCM88828_DEVICE_ID 0x8828 +#define BCM88829_DEVICE_ID 0x8829 +#define BCM8882A_DEVICE_ID 0x882A +#define BCM8882B_DEVICE_ID 0x882B +#define BCM8882C_DEVICE_ID 0x882C +#define BCM8882D_DEVICE_ID 0x882D +#define BCM8882E_DEVICE_ID 0x882E +#define BCM8882F_DEVICE_ID 0x882F + +#define J2P_DEVICE_ID 0x8850 +#define J2P_A0_REV_ID DNXC_A0_REV_ID +#define BCM88850_DEVICE_ID J2P_DEVICE_ID +#define BCM88850_A0_REV_ID J2P_A0_REV_ID +#define BCM88851_DEVICE_ID 0x8851 +#define BCM88852_DEVICE_ID 0x8852 +#define BCM88853_DEVICE_ID 0x8853 +#define BCM88854_DEVICE_ID 0x8854 +#define BCM88855_DEVICE_ID 0x8855 +#define BCM88856_DEVICE_ID 0x8856 +#define BCM88857_DEVICE_ID 0x8857 +#define BCM88858_DEVICE_ID 0x8858 +#define BCM88859_DEVICE_ID 0x8859 +#define BCM8885A_DEVICE_ID 0x885A +#define BCM8885B_DEVICE_ID 0x885B +#define BCM8885C_DEVICE_ID 0x885C +#define BCM8885D_DEVICE_ID 0x885D +#define BCM8885E_DEVICE_ID 0x885E +#define BCM8885F_DEVICE_ID 0x885F + + +#define Q2A_DEVICE_ID 0x8480 +#define Q2A_A0_REV_ID DNXC_A0_REV_ID +#define Q2A_B0_REV_ID DNXC_B0_REV_ID +#define Q2A_B1_REV_ID DNXC_B1_REV_ID +#define BCM88480_DEVICE_ID Q2A_DEVICE_ID +#define BCM88480_A0_REV_ID Q2A_A0_REV_ID +#define BCM88480_B0_REV_ID Q2A_B0_REV_ID +#define BCM88480_B1_REV_ID Q2A_B1_REV_ID +#define BCM88481_DEVICE_ID 0x8481 +#define BCM88482_DEVICE_ID 0x8482 +#define BCM88483_DEVICE_ID 0x8483 +#define BCM88484_DEVICE_ID 0x8484 +#define BCM88485_DEVICE_ID 0x8485 +#define BCM88486_DEVICE_ID 0x8486 +#define BCM88487_DEVICE_ID 0x8487 +#define BCM88488_DEVICE_ID 0x8488 +#define BCM88489_DEVICE_ID 0x8489 +#define BCM8848A_DEVICE_ID 0x848A +#define BCM8848B_DEVICE_ID 0x848B +#define BCM8848C_DEVICE_ID 0x848C +#define BCM8848D_DEVICE_ID 0x848D +#define BCM8848E_DEVICE_ID 0x848E +#define BCM8848F_DEVICE_ID 0x848F + +#define Q2U_DEVICE_ID 0x8280 +#define BCM88280_DEVICE_ID Q2U_DEVICE_ID +#define BCM88281_DEVICE_ID 0x8281 +#define BCM88282_DEVICE_ID 0x8282 +#define BCM88283_DEVICE_ID 0x8283 +#define BCM88284_DEVICE_ID 0x8284 +#define BCM88285_DEVICE_ID 0x8285 +#define BCM88286_DEVICE_ID 0x8286 +#define BCM88287_DEVICE_ID 0x8287 +#define BCM88288_DEVICE_ID 0x8288 +#define BCM88289_DEVICE_ID 0x8289 +#define BCM8828A_DEVICE_ID 0x828A +#define BCM8828B_DEVICE_ID 0x828B +#define BCM8828C_DEVICE_ID 0x828C +#define BCM8828D_DEVICE_ID 0x828D +#define BCM8828E_DEVICE_ID 0x828E +#define BCM8828F_DEVICE_ID 0x828F #define QAX_DEVICE_ID 0x8470 #define QAX_A0_REV_ID 0x0001 @@ -1735,9 +1900,11 @@ #define BCM88270_DEVICE_ID QUX_DEVICE_ID #define BCM88270_A0_REV_ID QUX_A0_REV_ID #define BCM88270_A1_REV_ID QUX_A1_REV_ID +#define BCM88271_DEVICE_ID 0x8271 #define BCM88272_DEVICE_ID 0x8272 #define BCM88273_DEVICE_ID 0x8273 #define BCM88274_DEVICE_ID 0x8274 +#define BCM88276_DEVICE_ID 0x8276 #define BCM88278_DEVICE_ID 0x8278 #define BCM88279_DEVICE_ID 0x8279 @@ -1746,16 +1913,6 @@ #define BCM8206_DEVICE_ID FLAIR_DEVICE_ID #define BCM8206_A0_REV_ID FLAIR_A0_REV_ID -#define ARDON_DEVICE_ID 0x8202 -#define ARDON_A0_REV_ID 0x0000 -#define BCM88202_DEVICE_ID ARDON_DEVICE_ID -#define BCM88202_A0_REV_ID ARDON_A0_REV_ID -#define ARDON_A1_REV_ID 0x0001 -#define BCM88202_A1_REV_ID ARDON_A1_REV_ID -#define ARDON_A2_REV_ID 0x0002 -#define BCM88202_A2_REV_ID ARDON_A2_REV_ID -#define BCM2801PM_DEVICE_ID 0x2801 -#define BCM2801PM_A0_REV_ID 0x0000 #define BCM88360_DEVICE_ID 0x8360 #define BCM88360_A0_REV_ID ARADPLUS_A0_REV_ID #define BCM88361_DEVICE_ID 0x8361 @@ -1803,16 +1960,6 @@ #define BCM88952_A0_REV_ID 0x0001 #define BCM88952_A1_REV_ID 0x0002 -#define BCM88752_DEVICE_ID 0x8752 -#define BCM88752_A0_REV_ID 0x0000 -#define BCM88752_B0_REV_ID 0x0011 - - -#define BCM83207_DEVICE_ID 0x3207 -#define BCM83208_DEVICE_ID 0x3208 -#define BCM83207_A0_REV_ID 0x0001 -#define BCM83208_A0_REV_ID 1 - #define PCP_PCI_VENDOR_ID 0x1172 #define PCP_PCI_DEVICE_ID 0x4 @@ -1822,5 +1969,43 @@ #define PLX9056_DEVICE_ID 0x9056 +#ifdef BCM_LTSW_SUPPORT +#define BCM56880_DEVICE_ID 0xb880 +#define BCM56880_A0_REV_ID 0x0001 +#define BCM56880_B0_REV_ID 0x0011 +#define BCM56881_DEVICE_ID 0xb881 +#define BCM56881_A0_REV_ID 0x0001 +#define BCM56881_B0_REV_ID 0x0011 +#define BCM56883_DEVICE_ID 0xb883 +#define BCM56883_A0_REV_ID 0x0001 +#define BCM56883_B0_REV_ID 0x0011 +#define BCM56889_DEVICE_ID 0xb889 +#define BCM56889_A0_REV_ID 0x0001 +#define BCM56889_B0_REV_ID 0x0011 + +#define BCM56780_DEVICE_ID 0xb780 +#define BCM56780_A0_REV_ID 0x0001 +#define BCM56782_DEVICE_ID 0xb782 +#define BCM56782_A0_REV_ID 0x0001 +#define BCM56784_DEVICE_ID 0xb784 +#define BCM56784_A0_REV_ID 0x0001 +#define BCM56786_DEVICE_ID 0xb786 +#define BCM56786_A0_REV_ID 0x0001 +#define BCM56788_DEVICE_ID 0xb788 +#define BCM56788_A0_REV_ID 0x0001 +#define BCM56789_DEVICE_ID 0xb789 +#define BCM56789_A0_REV_ID 0x0001 + +#define BCM56990_DEVICE_ID 0xb990 +#define BCM56990_A0_REV_ID 0x0001 +#define BCM56990_B0_REV_ID 0x0011 +#define BCM56992_DEVICE_ID 0xb992 +#define BCM56992_B0_REV_ID 0x0011 + +#define BCM56996_DEVICE_ID 0xb996 +#define BCM56996_A0_REV_ID 0x0001 +#define BCM56997_DEVICE_ID 0xb997 +#define BCM56997_A0_REV_ID 0x0001 +#endif #endif diff --git a/platform/broadcom/saibcm-modules/make/Make.config b/platform/broadcom/saibcm-modules/make/Make.config index 409a6a49b3f3..b086aa3aa79b 100644 --- a/platform/broadcom/saibcm-modules/make/Make.config +++ b/platform/broadcom/saibcm-modules/make/Make.config @@ -1,5 +1,10 @@ # -# Copyright 2017 Broadcom +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ # # You should have received a copy of the GNU General Public License # version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa # # $Id: Make.config,v 1.3 Broadcom SDK $ # $Copyright: (c) 2005 Broadcom Corp. diff --git a/platform/broadcom/saibcm-modules/make/Make.depend b/platform/broadcom/saibcm-modules/make/Make.depend index de7099387666..802f5f4483c2 100644 --- a/platform/broadcom/saibcm-modules/make/Make.depend +++ b/platform/broadcom/saibcm-modules/make/Make.depend @@ -1,5 +1,10 @@ # -# Copyright 2017 Broadcom +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ # # You should have received a copy of the GNU General Public License # version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa # # $Id: Make.depend,v 1.14 Broadcom SDK $ # $Copyright: (c) 2005 Broadcom Corp. diff --git a/platform/broadcom/saibcm-modules/make/Make.kernlib b/platform/broadcom/saibcm-modules/make/Make.kernlib index 6ec8a1c8df77..94801acd4a69 100644 --- a/platform/broadcom/saibcm-modules/make/Make.kernlib +++ b/platform/broadcom/saibcm-modules/make/Make.kernlib @@ -1,5 +1,10 @@ # -# Copyright 2017 Broadcom +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ # # You should have received a copy of the GNU General Public License # version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa # # $Id: Make.kernlib,v 1.7 Broadcom SDK $ # $Copyright: (c) 2005 Broadcom Corp. diff --git a/platform/broadcom/saibcm-modules/make/Make.lib b/platform/broadcom/saibcm-modules/make/Make.lib index d67325c5dd2f..ac81cc134f6d 100644 --- a/platform/broadcom/saibcm-modules/make/Make.lib +++ b/platform/broadcom/saibcm-modules/make/Make.lib @@ -1,5 +1,10 @@ # -# Copyright 2017 Broadcom +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ # # You should have received a copy of the GNU General Public License # version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa # # $Id: Make.lib,v 1.14 Broadcom SDK $ # $Copyright: (c) 2005 Broadcom Corp. @@ -62,7 +73,7 @@ endif ifeq ($(LINUX_MAKE_SHARED_LIB),1) $(CC) -shared -Wl,-soname,${lib}.${LIBSUFFIX}${EXTRA_LIB_LDFLAGS} -o ${targetlib} ${BOBJS} -lc else - ${Q}cd $(dir $(word 1,${BOBJS}));$(AR) ${ARFLAGS} $@ $(sort $(notdir ${BOBJS})) + $(AR) ${ARFLAGS} $@ $(sort ${BOBJS}) endif endif # !Borland diff --git a/platform/broadcom/saibcm-modules/make/Make.linux b/platform/broadcom/saibcm-modules/make/Make.linux index bd86ca351b6e..ad18872a34eb 100644 --- a/platform/broadcom/saibcm-modules/make/Make.linux +++ b/platform/broadcom/saibcm-modules/make/Make.linux @@ -1,5 +1,10 @@ # -# Copyright 2017 Broadcom +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ # # You should have received a copy of the GNU General Public License # version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa # # # $Id: Make.linux,v 1.18 Broadcom SDK $ @@ -85,7 +96,7 @@ endif build: $(MAKE) $(CMD) -DELIVER clean C_COMPILER CXX_COMPILER variable mod bcm user: +DELIVER clean C_COMPILER CXX_COMPILER variable mod bcm user issu libopennsa: $(MAKE) $(CMD) $@ clean_d: clean @@ -93,5 +104,5 @@ clean_d: clean distclean: $(MAKE) $(CMD) $@ -.PHONY: build clean distclean clean_d DELIVER variable mod bcm user +.PHONY: build clean distclean clean_d DELIVER variable mod bcm user issu diff --git a/platform/broadcom/saibcm-modules/make/Make.subdirs b/platform/broadcom/saibcm-modules/make/Make.subdirs index 1033e296c0a3..374d817d212d 100644 --- a/platform/broadcom/saibcm-modules/make/Make.subdirs +++ b/platform/broadcom/saibcm-modules/make/Make.subdirs @@ -1,5 +1,10 @@ # -# Copyright 2017 Broadcom +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ # # You should have received a copy of the GNU General Public License # version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa # # $Id: Make.subdirs,v 1.8 Broadcom SDK $ # $Copyright: (c) 2005 Broadcom Corp. diff --git a/platform/broadcom/saibcm-modules/make/Make.tools b/platform/broadcom/saibcm-modules/make/Make.tools index 8ed77727fef2..0d55eb2e653a 100644 --- a/platform/broadcom/saibcm-modules/make/Make.tools +++ b/platform/broadcom/saibcm-modules/make/Make.tools @@ -1,5 +1,10 @@ # -# Copyright 2017 Broadcom +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ # # You should have received a copy of the GNU General Public License # version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa # # $Id: Make.tools,v 1.2 Broadcom SDK $ # $Copyright: (c) 2005 Broadcom Corp. diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-gto b/platform/broadcom/saibcm-modules/make/Makefile.linux-gto index 786b4cc26bc3..4a20a99dac69 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-gto +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-gto @@ -97,6 +97,21 @@ ifdef SHADOW_PLX CFLAGS += -DBCM_PLX9656_LOCAL_BUS -DBDE_LINUX_NON_INTERRUPTIBLE -DSHADOW_SVK endif +ifdef LTSW_CHIPS +# Default open source target build +OPENSRC_BUILD ?= uclibc_201402_ppc + +# Hardware interface (see $SDKLT/bcma/sys/probe directory) +SYSTEM_INTERFACE ?= ngbde + +# Turn on direct register access if running on real hardware. +ifeq (ngbde,$(SYSTEM_INTERFACE)) +LTSW_ADD_CPPFLAGS += -DBCMDRD_CONFIG_MEMMAP_DIRECT=1 +endif + +export SYSTEM_INTERFACE +endif + ifeq (,$(KFLAGS)) KFLAGS := -D__KERNEL__ -m32 -nostdinc -isystem $(KFLAG_INCLD) -I$(LINUX_INCLUDE) -include $(LINUX_INCLUDE)/generated/uapi/linux/version.h -include $(LINUX_INCLUDE)/generated/autoconf.h -I$(KERNDIR)/arch/powerpc -I$(KERNDIR)/arch/powerpc/include -I$(KERNDIR)/include/asm-powerpc -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -msoft-float -pipe -ffixed-r2 -mmultiple -mno-altivec -funit-at-a-time -Wa,-me500 -fomit-frame-pointer -Wdeclaration-after-statement -Wno-pointer-sign endif diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-gts b/platform/broadcom/saibcm-modules/make/Makefile.linux-gts new file mode 100644 index 000000000000..726dfdf505bd --- /dev/null +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-gts @@ -0,0 +1,164 @@ +# +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa +# +# $Id: Makefile.linux-xlr-4_19,v 0.1 Broadcom SDK $ +# $Copyright: (c) 2015 Broadcom Corp. +# All Rights Reserved.$ + +# +# XLR system make file. +# +# Most of this was taken from target x86-smp_generic_64-2_6. +# + + +############################################################################# +# this segment is custom and not sourced from any existing makefile # +# (base thanks to http:confluence.broadcom.com/display/NTSWSW/X86+System) # +############################################################################# + +# set up a basic feature list. tcl, etc. # +#ifeq (,$(FEATURE_LIST)) +#FEATURE_LIST = TCL BFD PTP CINT L3 I2C MEM_SCAN EDITLINE BCM_SAL_PROFILE CUSTOMER TEST CHASSIS MSTP RCPU +#endif + +# some basic path variables for tools and kernel source, etc # +export XLR_TOOLS_BASE = /projects/ntsw-tools/linux/xlr-419 +TOOLCHAIN_DIR = $(XLR_TOOLS_BASE)/buildroot/host/usr +# Target machine for EDK-Host defconfig +TARGET_MACHINE ?= x86_64 +KERNDIR = $(XLR_TOOLS_BASE)/kernel/linux + +# set up cross compile prefix, tools dir variables. # +export CROSS_COMPILE := x86_64-broadcom-linux-gnu- +export TOOLS_DIR := $(TOOLCHAIN_DIR)/bin + +# architecture. # +ARCH = x86_64 +TARGET_ARCHITECTURE = x86_64-broadcom-linux-gnu + +# Noisy kernel build +KBUILD_VERBOSE = 1 + +export ARCH KBUILD_VERBOSE + +# set up paths. # +export LIBRARY_PATH := $(TOOLCHAIN_DIR)/lib:$(TOOLCHAIN_DIR)/lib64:$(LIBRARY_PATH) +export PATH := $(TOOLCHAIN_DIR)/bin:$(KERNDIR):$(PATH) + +# set up SYSINC path # +export SYSINC := $(XLR_TOOLS_BASE)/buildroot/host/usr/lib/gcc/$(TARGET_ARCHITECTURE)/5.4.0/include + + +# CFLAGS/CFGFLAGS # +CFLAGS += -DUSE_LINUX_BDE_MMAP=1 +#CFLAGS += -DBDE_LINUX_USE_MSI_INTERRUPT +CFLAGS += -Wno-error=unused-value +CFLAGS += -Wno-error=unused-but-set-variable +CFLAGS += -Wno-error=maybe-uninitialized +CFLAGS += -Wno-error=cpp +CFLAGS += -Wno-error=aggressive-loop-optimizations +CFLAGS += -Wno-error=array-bounds +CFLAGS += -Wno-error=strict-overflow +CFLAGS += -L$(TOOLCHAIN_DIR)/lib +CFLAGS += -L$(TOOLCHAIN_DIR)/lib64 +#CFLAGS += -Wl,--rpath=/lib64 # may need to set rpath and dynamic-linker path here (and possibly in KLFAGS below) in the future, # +#CFLAGS += -Wl,--dynamic-linker=/lib64/ld-linux-x86-64.so.2 # if we want to build the target executable to be used with shared libs # + +#XLDK-568 fix inline references +CFGFLAGS += -fgnu89-inline + + +# set up KFLAGS appropriately. # +ifeq (,$(KFLAGS)) +KFLAGS := -L$(TOOLCHAIN_DIR)/lib -L$(TOOLCHAIN_DIR)/lib64 -I$(KERNDIR) -lc -nostdinc -isystem $(SYSINC) -Iinclude -I$(KERNDIR)/arch/x86/include -I$(KERNDIR)/arch/x86/include/generated -I$(KERNDIR)/arch/x86/include/generated/uapi -I$(KERNDIR)/arch/x86/include/uapi -I$(KERNDIR)/include -I$(KERNDIR)/include/generated -I$(KERNDIR)/include/generated/uapi -I$(KERNDIR)/include/uapi -include $(KERNDIR)/include/generated/autoconf.h -D__KERNEL__ -DNDEBUG -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Wno-format-security -fno-delete-null-pointer-checks -O2 -m64 -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -maccumulate-outgoing-args -fstack-protector -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -Wframe-larger-than=1024 -fno-omit-frame-pointer -Wdeclaration-after-statement -Wno-pointer-sign -fno-dwarf2-cfi-asm -fconserve-stack +endif + + +###################################################################### +# this segment comes from make/Makefile.linux-x86-smp_generic_64-2_6 # +###################################################################### +CFGFLAGS += -DLONGS_ARE_64BITS +CFGFLAGS += -DPTRS_ARE_64BITS +CFGFLAGS += -DSAL_SPL_LOCK_ON_IRQ + + +############################################################## +# This segment comes from make/Makefile.linux-x86-common-2_6 # +############################################################## +CFGFLAGS += -DSYS_BE_PIO=0 -DSYS_BE_PACKET=0 -DSYS_BE_OTHER=0 +ENDIAN = LE_HOST=1 +CFGFLAGS += -D$(ENDIAN) +CFGFLAGS += -DBCM_PLATFORM_STRING=\"X86\" +CFGFLAGS += -DSAL_BDE_DMA_MEM_DEFAULT=32 + +# Extra variables. +EXTRA_CFLAGS = -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) + +comma = , +basetarget = $(basename $(notdir $@)) +modname = $(basetarget) + +name-fix = $(subst $(comma),_,$(subst -,_,$1)) +basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" +modname_flags = $(if $(filter 1,$(words $(modname))),\ +-D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") + +ifdef LTSW_CHIPS +# Ensure we do not use an out-of-date libelf.so +ELFUTILS_MIN = 158 +ELFUTILS_DIR ?= /projects/ntsw-tools/lib + +# Default open source target build +OPENSRC_BUILD ?= fed21-x86_64 + +# Hardware interface (see $SDKLT/bcma/sys/probe directory) +SYSTEM_INTERFACE ?= ngbde + +# Support BCMSIM in the same build +ifeq (1,$(BCM_SIM_PATH_SUPPORT)) +EXTRA_SYSTEM_INTERFACES = plisim +endif + +# Turn on direct register access if running on real hardware. +ifeq (ngbde,$(SYSTEM_INTERFACE)) +# Except if using multiple probe interfaces +ifeq (,$(EXTRA_SYSTEM_INTERFACES)) +LTSW_ADD_CPPFLAGS += -DBCMDRD_CONFIG_MEMMAP_DIRECT=1 +endif +endif + +export SYSTEM_INTERFACE +export EXTRA_SYSTEM_INTERFACES +endif + +ifneq ($(targetplat),user) +# By default we exclude -Werror from x86 kernel builds +BCM_CFLAGS = -Wall +include ${SDK}/make/Makefile.linux-kernel-2_6 +endif + + diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc b/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc index 092e474e2563..fa4911185aa8 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc @@ -1,5 +1,10 @@ # -# Copyright 2017 Broadcom +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ # # You should have received a copy of the GNU General Public License # version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa # # $Id: Makefile.linux-iproc Exp $ # $Copyright: (c) 2007 Broadcom Corp. @@ -27,11 +38,14 @@ endif # TARGET_ARCHITECTURE Compiler for target architecture # KERNDIR Kernel directory for iPROC-CMICd devices ifeq (BE,$(ENDIAN_MODE)) +#While BE mode is supported, it's use is very limited. We had a specific customer +#request for BE support but don't currently mainstream it. So a 5.1.0 version +#has not been built. Continue using 5.0.3 for any BE support TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk50-be/XLDK32 TARGET_ARCHITECTURE:=armeb-broadcom-linux-uclibcgnueabi KERNDIR ?= $(TOOLCHAIN_BASE_DIR)/kernel/linux else -TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk50/XLDK32 +TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk51/XLDK32 TARGET_ARCHITECTURE:= arm-broadcom-linux-uclibcgnueabi KERNDIR ?= $(TOOLCHAIN_BASE_DIR)/kernel/linux endif @@ -44,9 +58,10 @@ endif TOOLCHAIN_BIN_DIR=$(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/bin override PATH:=$(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/$(TARGET_ARCHITECTURE)/bin:$(TOOLCHAIN_BIN_DIR):$(PATH) LD_LIBRARY_PATH=$(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/lib - export TOOLCHAIN_BIN_DIR LD_LIBRARY_PATH +CROSS_GCC_VER ?= $(shell $(TOOLCHAIN_BIN_DIR)/$(CROSS_COMPILE)gcc -dumpversion) + # Default Linux include directory ifeq (,$(LINUX_INCLUDE)) LINUX_INCLUDE := $(KERNDIR)/include @@ -61,6 +76,12 @@ ENDIAN = LE_HOST=1 endif CFLAGS += -fno-aggressive-loop-optimizations +CFLAGS += -Wno-error=maybe-uninitialized +CFLAGS += -Wno-error=array-bounds +CFLAGS += -fgnu89-inline +ifeq "$(shell expr `echo $(CROSS_GCC_VER) | cut -f1 -d.` \>= 7)" "1" + CFLAGS += -Wno-error=bool-operation +endif CFGFLAGS += -D$(ENDIAN) -DIPROC_CMICD CFGFLAGS += -DBCM_PLATFORM_STRING=\"IPROC_CMICD\" @@ -82,7 +103,7 @@ basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" modname_flags = $(if $(filter 1,$(words $(modname))),\ -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") -KFLAG_INCLD ?= $(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/lib/gcc/$(TARGET_ARCHITECTURE)/4.9.4/include +KFLAG_INCLD ?= $(LD_LIBRARY_PATH)/gcc/$(TARGET_ARCHITECTURE)/$(CROSS_GCC_VER)/include ifeq (,$(KFLAGS)) KFLAGS := -D__LINUX_ARM_ARCH__=7 -D__KERNEL__ -nostdinc -isystem $(KFLAG_INCLD) -I$(LINUX_INCLUDE) -include $(LINUX_INCLUDE)/generated/autoconf.h -I$(KERNDIR)/arch/arm/include -I$(KERNDIR)/arch/arm/include/generated -I$(KERNDIR)/arch/arm/mach-iproc/include -Wall -Wstrict-prototypes -Wno-trigraphs -Os -fno-strict-aliasing -fno-common -marm -mabi=aapcs-linux -fno-pic -pipe -msoft-float -ffreestanding -march=armv7-a -mfpu=vfp -mfloat-abi=softfp -fomit-frame-pointer -g -fno-stack-protector -Wdeclaration-after-statement -Wno-pointer-sign -mlong-calls diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc-3_14 b/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc-3_14 index 723fea6c73cf..8d9f66aa50a0 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc-3_14 +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc-3_14 @@ -1,5 +1,10 @@ # -# Copyright 2017 Broadcom +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ # # You should have received a copy of the GNU General Public License # version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa # # $Id: Makefile.linux-iproc-3_6,v 1.1 Broadcom SDK $ # $Copyright: (c) 2007 Broadcom Corp. diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc-4_4 b/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc-4_4 new file mode 100644 index 000000000000..bcef1ff69dd4 --- /dev/null +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc-4_4 @@ -0,0 +1,103 @@ +# +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa +# +# $Id: Makefile.linux-iproc Exp $ +# $Copyright: (c) 2007 Broadcom Corp. +# All Rights Reserved.$ +# Makefile for iproc-CMICd + +# User must select one platform from below.By default ARM_LINUX is selected. . +ifeq (,$(BUILD_PLATFORM)) +BUILD_PLATFORM=ARM_LINUX +endif + +# TOOLCHAIN_BASE_DIR Toolchain base directory for iPROC-CMICd devices +# TARGET_ARCHITECTURE Compiler for target architecture +# KERNDIR Kernel directory for iPROC-CMICd devices +ifeq (BE,$(ENDIAN_MODE)) +TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk40-be/XLDK +TARGET_ARCHITECTURE:=armeb-broadcom-linux-uclibcgnueabi +KERNDIR ?= $(TOOLCHAIN_BASE_DIR)/kernel/linux +else +TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk40/XLDK +TARGET_ARCHITECTURE:= arm-broadcom-linux-uclibcgnueabi +KERNDIR ?= $(TOOLCHAIN_BASE_DIR)/kernel/linux +endif + +ifeq (,$(CROSS_COMPILE)) +CROSS_COMPILE:= $(TARGET_ARCHITECTURE)- +endif + +# arm9tools +TOOLCHAIN_BIN_DIR=$(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/bin +override PATH:=$(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/$(TARGET_ARCHITECTURE)/bin:$(TOOLCHAIN_BIN_DIR):$(PATH) +LD_LIBRARY_PATH=$(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/lib + +export TOOLCHAIN_BIN_DIR LD_LIBRARY_PATH + +# Default Linux include directory +ifeq (,$(LINUX_INCLUDE)) +LINUX_INCLUDE := $(KERNDIR)/include +endif + +ifeq (BE,$(ENDIAN_MODE)) +CFGFLAGS += -DSYS_BE_PIO=1 -DSYS_BE_PACKET=0 -DSYS_BE_OTHER=1 +ENDIAN = BE_HOST=1 +else +CFGFLAGS += -DSYS_BE_PIO=0 -DSYS_BE_PACKET=0 -DSYS_BE_OTHER=0 +ENDIAN = LE_HOST=1 +endif + +CFGFLAGS += -D$(ENDIAN) -DIPROC_CMICD +CFGFLAGS += -DBCM_PLATFORM_STRING=\"IPROC_CMICD\" + +ARCH = arm +KBUILD_VERBOSE = 1 + +export ARCH KBUILD_VERBOSE + +comma = , +basetarget = $(basename $(notdir $@)) +modname = $(basetarget) + +# Extra variables. +EXTRA_CFLAGS = -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) + +name-fix = $(subst $(comma),_,$(subst -,_,$1)) +basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" +modname_flags = $(if $(filter 1,$(words $(modname))),\ + -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") + +KFLAG_INCLD ?= $(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/lib/gcc/$(TARGET_ARCHITECTURE)/4.9.3/include + +ifeq (,$(KFLAGS)) +KFLAGS := -D__LINUX_ARM_ARCH__=7 -D__KERNEL__ -nostdinc -isystem $(KFLAG_INCLD) -I$(LINUX_INCLUDE) -include $(LINUX_INCLUDE)/generated/autoconf.h -I$(KERNDIR)/arch/arm/include -I$(KERNDIR)/arch/arm/include/generated -I$(KERNDIR)/arch/arm/mach-iproc/include -Wall -Wstrict-prototypes -Wno-trigraphs -Os -fno-strict-aliasing -fno-common -marm -mabi=aapcs-linux -fno-pic -pipe -msoft-float -ffreestanding -march=armv7-a -mfpu=vfp -mfloat-abi=softfp -fomit-frame-pointer -g -fno-stack-protector -Wdeclaration-after-statement -Wno-pointer-sign -mlong-calls +KFLAGS += -I$(LINUX_INCLUDE)/uapi -I$(LINUX_INCLUDE)/generated/uapi -I$(KERNDIR)/arch/arm/include/uapi -I$(KERNDIR)/arch/arm/include/generated/uapi +endif + +ifneq ($(targetplat),user) +include ${SDK}/make/Makefile.linux-kernel-3_6 +endif diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc_64 b/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc_64 new file mode 100644 index 000000000000..247da7386370 --- /dev/null +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc_64 @@ -0,0 +1,117 @@ +# +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa +# +# $Id: Makefile.linux-iproc Exp $ +# $Copyright: (c) 2007 Broadcom Corp. +# All Rights Reserved.$ +# Makefile for iproc-CMICd + +# User must select one platform from below.By default ARM_LINUX is selected. . +ifeq (,$(BUILD_PLATFORM)) +BUILD_PLATFORM=ARM_LINUX +endif + +# TOOLCHAIN_BASE_DIR Toolchain base directory for iPROC-CMICd devices +# TARGET_ARCHITECTURE Compiler for target architecture +# KERNDIR Kernel directory for iPROC-CMICd devices +ifeq (BE,$(ENDIAN_MODE)) +#We've never actually built a 64 BE executable. Just here for any future +#customer requirements. +TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk51-be/XLDK64 +TARGET_ARCHITECTURE ?= aarch64_be-broadcom-linux-uclibc +KERNDIR ?= $(TOOLCHAIN_BASE_DIR)/kernel/linux +else +TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk51/XLDK64 +TARGET_ARCHITECTURE ?= aarch64-broadcom-linux-uclibc +KERNDIR ?= $(TOOLCHAIN_BASE_DIR)/kernel/linux +endif + +ifeq (,$(CROSS_COMPILE)) +CROSS_COMPILE:= $(TARGET_ARCHITECTURE)- +endif + +# A72 tools +TOOLCHAIN_BIN_DIR=$(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/bin +override PATH:=$(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/$(TARGET_ARCHITECTURE)/bin:$(TOOLCHAIN_BIN_DIR):$(PATH) +LD_LIBRARY_PATH=$(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/lib +export TOOLCHAIN_BIN_DIR LD_LIBRARY_PATH + +CROSS_GCC_VER ?= $(shell $(TOOLCHAIN_BIN_DIR)/$(CROSS_COMPILE)gcc -dumpversion) + +# Default Linux include directory +ifeq (,$(LINUX_INCLUDE)) +LINUX_INCLUDE := $(KERNDIR)/include +endif + +ifeq (BE,$(ENDIAN_MODE)) +CFGFLAGS += -DSYS_BE_PIO=1 -DSYS_BE_PACKET=0 -DSYS_BE_OTHER=1 +ENDIAN = BE_HOST=1 +else +CFGFLAGS += -DSYS_BE_PIO=0 -DSYS_BE_PACKET=0 -DSYS_BE_OTHER=0 +ENDIAN = LE_HOST=1 +endif + +CFLAGS += -DPTRS_ARE_64BITS -DLONGS_ARE_64BITS +CFLAGS += -DPHYS_ADDRS_ARE_64BITS +CFLAGS += -fno-aggressive-loop-optimizations -fno-strict-overflow +CFLAGS += -Wno-error=maybe-uninitialized +CFLAGS += -Wno-error=array-bounds +CFLAGS += -fgnu89-inline +ifeq "$(shell expr `echo $(CROSS_GCC_VER) | cut -f1 -d.` \>= 7)" "1" + CFLAGS += -Wno-error=bool-operation +endif + + +CFGFLAGS += -D$(ENDIAN) -DIPROC_CMICD +CFGFLAGS += -DBCM_PLATFORM_STRING=\"IPROC_CMICD\" +CFGFLAGS += -DSAL_BDE_DMA_MEM_DEFAULT=16 + +ARCH = arm64 +KBUILD_VERBOSE = 1 + +export ARCH KBUILD_VERBOSE + +comma = , +basetarget = $(basename $(notdir $@)) +modname = $(basetarget) + +# Extra variables. +EXTRA_CFLAGS = -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) + +name-fix = $(subst $(comma),_,$(subst -,_,$1)) +basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" +modname_flags = $(if $(filter 1,$(words $(modname))),\ + -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") + +KFLAG_INCLD ?= $(LD_LIBRARY_PATH)/gcc/$(TARGET_ARCHITECTURE)/$(CROSS_GCC_VER)/include + +ifeq (,$(KFLAGS)) +KFLAGS := -D__LINUX_ARM_ARCH__=8 -D__KERNEL__ -DPTRS_ARE_64BITS -DLONGS_ARE_64BITS -nostdinc -isystem $(KFLAG_INCLD) -I$(LINUX_INCLUDE) -include $(LINUX_INCLUDE)/generated/autoconf.h -I$(KERNDIR)/arch/arm64/include -I$(KERNDIR)/arch/arm64/include/generated -I$(KERNDIR)/arch/arm64/include/generated/uapi -I$(KERNDIR)/arch/arm64/include/generated/asm -I$(KERNDIR)/include/uapi -I$(KERNDIR)/include/generated/uapi -I$(KERNDIR)/arch/arm64/include/uapi -Wall -Wstrict-prototypes -Wno-trigraphs -Os -fno-strict-aliasing -fno-common -fno-pic -pipe -ffreestanding -fomit-frame-pointer -g -fno-stack-protector -Wdeclaration-after-statement -Wno-pointer-sign -mcmodel=large +endif + +ifneq ($(targetplat),user) +include ${SDK}/make/Makefile.linux-kernel-3_6 +endif diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-kernel b/platform/broadcom/saibcm-modules/make/Makefile.linux-kernel index 7cbf8451f91e..ccb0c30d2acc 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-kernel +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-kernel @@ -1,5 +1,10 @@ # -# Copyright 2017 Broadcom +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ # # You should have received a copy of the GNU General Public License # version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa # # $Id: Makefile.linux-kernel,v 1.27 Broadcom SDK $ # $Copyright: (c) 2005 Broadcom Corp. diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-kernel-2_6 b/platform/broadcom/saibcm-modules/make/Makefile.linux-kernel-2_6 index 559f2ae5e5e5..08461e4c4b7c 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-kernel-2_6 +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-kernel-2_6 @@ -1,5 +1,10 @@ # -# Copyright 2017 Broadcom +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ # # You should have received a copy of the GNU General Public License # version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa # # $Id: Makefile.linux-kernel-2_6,v 1.40 Broadcom SDK $ # $Copyright: (c) 2005 Broadcom Corp. diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-kernel-3_6 b/platform/broadcom/saibcm-modules/make/Makefile.linux-kernel-3_6 index 0d54c4474fc8..528522ec4bd3 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-kernel-3_6 +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-kernel-3_6 @@ -1,5 +1,10 @@ # -# Copyright 2017 Broadcom +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ # # You should have received a copy of the GNU General Public License # version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa # # $Id: Makefile.linux-kernel-3_6,v 1.2 Broadcom SDK $ # $Copyright: (c) 2005 Broadcom Corp. diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-kernel-4_4 b/platform/broadcom/saibcm-modules/make/Makefile.linux-kernel-4_4 index 0e8e22e1b32d..c02fc0edd89b 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-kernel-4_4 +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-kernel-4_4 @@ -1,5 +1,10 @@ # -# Copyright 2017 Broadcom +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ # # You should have received a copy of the GNU General Public License # version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa # # $Id: Makefile.linux-kernel-2_6,v 1.40 Broadcom SDK $ # $Copyright: (c) 2005 Broadcom Corp. diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-kmodule b/platform/broadcom/saibcm-modules/make/Makefile.linux-kmodule index 540c497ea258..46caf00f20b5 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-kmodule +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-kmodule @@ -1,5 +1,10 @@ # -# Copyright 2017 Broadcom +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ # # You should have received a copy of the GNU General Public License # version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa # # $Id: Makefile.linux-kmodule-3_6,v 1.2 Broadcom SDK $ # $Copyright: (c) 2006 Broadcom Corp. @@ -61,6 +72,13 @@ KERNBLDDIR ?= $(KERNDIR) # kernel symbols. override EXTRA_CFLAGS = -I${SDK}/include -I${SDK}/systems/linux/kernel/modules/include -I${SDK}/systems/bde/linux/include +# +# If, for any reason, the definition of LD was erased, then +# set it, again. +# +ifeq ($(LD),) +LD = $(CROSS_COMPILE)ld +endif # The precopiled object needs a dummy command file to avoid warnings # from the Kbuild scripts (modpost stage). diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-slk b/platform/broadcom/saibcm-modules/make/Makefile.linux-slk new file mode 100644 index 000000000000..656835019a05 --- /dev/null +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-slk @@ -0,0 +1,161 @@ +# +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa +# +# $Id: Makefile.linux-slk-3_14,v 1.2 Broadcom SDK $ +# $Copyright: (c) 2013 Broadcom Corp. +# All Rights Reserved.$ +# Makefile for SLK(BCM957812) + +# User must select one platform from below.By default ARM_LINUX is selected. . +ifeq (,$(BUILD_PLATFORM)) +BUILD_PLATFORM=ARM_LINUX +endif + +# Toolchain base directory for NS2 XMC card +ifeq (BE,$(ENDIAN_MODE)) +TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/toolchains/slk/linaro-be +TARGET_ARCHITECTURE:=aarch64_be-linux-gnu +# Target machine for EDK-Host defconfig +TARGET_MACHINE ?= slk_be +KERNDIR ?= /projects/ntsw-tools/linux/iproc_ldks/slk-be/poky/brcm-released-source/git +else +TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/toolchains/slk/linaro-le +# Compiler for target architecture +TARGET_ARCHITECTURE:= aarch64-linux-gnu +# Target machine for EDK-Host defconfig +TARGET_MACHINE ?= slk_le +# Kernel directory +KERNDIR ?= /projects/ntsw-tools/linux/iproc_ldks/slk/poky/brcm-released-source/git +endif + +ifeq (,$(CROSS_COMPILE)) +CROSS_COMPILE:= $(TARGET_ARCHITECTURE)- +endif + +# armtools +TOOLCHAIN_BIN_DIR=$(TOOLCHAIN_BASE_DIR)/bin +override PATH:=$(TOOLCHAIN_BIN_DIR):$(PATH) +LD_LIBRARY_PATH=$(TOOLCHAIN_BASE_DIR)/lib + +export TOOLCHAIN_BIN_DIR LD_LIBRARY_PATH + +# Default Linux include directory +ifeq (,$(LINUX_INCLUDE)) +LINUX_INCLUDE := $(KERNDIR)/include +endif + +ifeq (BE,$(ENDIAN_MODE)) +CFGFLAGS += -DSYS_BE_PIO=1 -DSYS_BE_PACKET=0 -DSYS_BE_OTHER=1 +ENDIAN = BE_HOST=1 +else +CFGFLAGS += -DSYS_BE_PIO=0 -DSYS_BE_PACKET=0 -DSYS_BE_OTHER=0 +ENDIAN = LE_HOST=1 +endif + +CFGFLAGS += -D$(ENDIAN) -DBCM958525 +CFGFLAGS += -DBCM_PLATFORM_STRING=\"SLK_BCM957812\" +CFGFLAGS += -DSAL_BDE_DMA_MEM_DEFAULT=32 +ifeq (1,$(SLK_32BIT)) +CFGFLAGS += -DSAL_BDE_32BIT_USER_64BIT_KERNEL +else +CFGFLAGS += -DPTRS_ARE_64BITS -DLONGS_ARE_64BITS +endif +CFGFLAGS += -DPHYS_ADDRS_ARE_64BITS + +CFLAGS += -Wno-unused-value -Wno-unused-but-set-variable -Wno-sizeof-pointer-memaccess -fno-aggressive-loop-optimizations + +ifdef DPP_CHIPS +CFLAGS += -DDUNE_BCM -D__DUNE_LINUX_BCM_CPU_PCP_DMA__ +CFGFLAGS += -DSOC_CM_FUNCTION +endif + +ifdef DFE_CHIPS +CFLAGS += -DDUNE_BCM +CFGFLAGS += -DSOC_CM_FUNCTION +endif + +ifdef SAND_CHIPS +CFLAGS += -D__DUNE_SLK_BCM_CPU__ -D__DUNE_LINUX_BCM_CPU_PCIE__ +endif + +# Enable cached DMA memory by default +ifeq (,$(SAL_BDE_USE_CACHED_DMA_MEM)) +SAL_BDE_USE_CACHED_DMA_MEM = 1 +endif +ifeq ($(SAL_BDE_USE_CACHED_DMA_MEM),1) +CFGFLAGS += -DSAL_BDE_CACHE_DMA_MEM +endif + +ifeq (1,$(SLK_32BIT)) +ARCH = arm +else +ARCH = arm64 +endif + +KBUILD_VERBOSE = 1 + +export ARCH KBUILD_VERBOSE + +comma = , +basetarget = $(basename $(notdir $@)) +modname = $(basetarget) + +# Extra variables. +EXTRA_CFLAGS = -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) + +name-fix = $(subst $(comma),_,$(subst -,_,$1)) +basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" +modname_flags = $(if $(filter 1,$(words $(modname))),\ + -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") + +KFLAG_INCLD = $(TOOLCHAIN_BASE_DIR)/lib/gcc/$(TARGET_ARCHITECTURE)/4.9.2/include + +ifeq (,$(KFLAGS)) +KFLAGS := -D__LINUX_ARM_ARCH__=8 -D__KERNEL__ -DPTRS_ARE_64BITS -DLONGS_ARE_64BITS -nostdinc -isystem $(KFLAG_INCLD) -I$(LINUX_INCLUDE) -include $(LINUX_INCLUDE)/generated/autoconf.h -I$(KERNDIR)/arch/arm64/include -I$(KERNDIR)/arch/arm64/include/generated -I$(KERNDIR)/arch/arm64/include/generated/asm -I$(KERNDIR)/include/uapi -I$(KERNDIR)/include/generated/uapi -I$(KERNDIR)/arch/arm64/include/uapi -Wall -Wstrict-prototypes -Wno-trigraphs -Os -fno-strict-aliasing -fno-common -fno-pic -pipe -ffreestanding -fomit-frame-pointer -g -fno-stack-protector -Wdeclaration-after-statement -Wno-pointer-sign +endif + +ifdef LTSW_CHIPS +# Default open source target build +ifeq (BE,$(ENDIAN_MODE)) +OPENSRC_BUILD ?= linaro_arm64_be +else +OPENSRC_BUILD ?= linaro_arm64_le +endif + +# Hardware interface (see $SDKLT/bcma/sys/probe directory) +SYSTEM_INTERFACE ?= ngbde + +# Turn on direct register access if running on real hardware. +ifeq (ngbde,$(SYSTEM_INTERFACE)) +LTSW_ADD_CPPFLAGS += -DBCMDRD_CONFIG_MEMMAP_DIRECT=1 +endif + +export SYSTEM_INTERFACE +endif + +ifneq ($(targetplat),user) +include ${SDK}/make/Makefile.linux-kernel-3_6 +endif diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-common-2_6 b/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-common-2_6 index 25e953136bc0..dbd51ee1f627 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-common-2_6 +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-common-2_6 @@ -1,5 +1,10 @@ # -# Copyright 2017 Broadcom +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ # # You should have received a copy of the GNU General Public License # version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa # # $Id: Makefile.linux-x86-common-2_6,v 1.13 Broadcom SDK $ # $Copyright: (c) 2005 Broadcom Corp. diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-generic-common-2_6 b/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-generic-common-2_6 index bf0ea85d578e..4b02aa53cda8 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-generic-common-2_6 +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-generic-common-2_6 @@ -1,5 +1,10 @@ # -# Copyright 2017 Broadcom +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ # # You should have received a copy of the GNU General Public License # version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa # # $Id: Makefile.linux-x86-generic-common-2_6,v 1.2 Broadcom SDK $ # $Copyright: (c) 2008 Broadcom Corp. diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-smp_generic_64-2_6 b/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-smp_generic_64-2_6 index bc0230ec8226..9df0bee5a774 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-smp_generic_64-2_6 +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-smp_generic_64-2_6 @@ -1,5 +1,10 @@ # -# Copyright 2017 Broadcom +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ # # You should have received a copy of the GNU General Public License # version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa # # $Id: Makefile.linux-x86-smp_generic_64-2_6,v 1.5 Broadcom SDK $ # $Copyright: (c) 2008 Broadcom Corp. @@ -25,21 +36,37 @@ CFGFLAGS += -DSAL_SPL_LOCK_ON_IRQ include ${SDK}/make/Makefile.linux-x86-generic-common-2_6 ifeq (,$(KFLAGS)) -KFLAGS := -nostdinc -isystem $(SYSINC) -I$(KERNDIR)/include -I$(KERNDIR)/arch/x86/include -include $(AUTOCONF) -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -fno-delete-null-pointer-checks -Os -m64 -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -maccumulate-outgoing-args -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -fno-stack-protector -fomit-frame-pointer -g -Wdeclaration-after-statement -Wno-pointer-sign +KFLAGS := -nostdinc -isystem $(SYSINC) -I$(KERNDIR)/include -I$(KERNDIR)/arch/x86/include -include $(AUTOCONF) -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -fno-delete-null-pointer-checks -Os -m64 -mtune=generic -mno-red-zone -fno-pie -mcmodel=kernel -funit-at-a-time -maccumulate-outgoing-args -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -fno-stack-protector -fomit-frame-pointer -g -Wdeclaration-after-statement -Wno-pointer-sign endif ifeq ($(LINUX_MAKE_SHARED_LIB), 1) -KFLAGS += -fPIC -mcmodel=small + KFLAGS += -fPIC -mcmodel=small else -KFLAGS += -fno-pie -mcmodel=kernel + KFLAGS += -fno-pie -mcmodel=kernel endif LINUX_UAPI = $(LINUX_INCLUDE)/uapi +ifneq (,$(shell ls $(LINUX_UAPI) 2>/dev/null)) KFLAGS += -I$(LINUX_INCLUDE)/uapi -I$(LINUX_INCLUDE)/generated/uapi -I$(KERNDIR)/arch/x86/include/generated -I$(KERNDIR)/arch/x86/include/uapi -I$(KERNDIR)/arch/x86/include/generated/uapi +endif + +ifdef LTSW_CHIPS +# Ensure we do not use an out-of-date libelf.so +ELFUTILS_MIN = 158 +ELFUTILS_DIR ?= /projects/ntsw-tools/lib + +# Default open source target build +OPENSRC_BUILD ?= x86_64 + +# Hardware interface (see $SDKLT/bcma/sys/probe directory) +SYSTEM_INTERFACE ?= ngbde + +# Turn on direct register access if running on real hardware. +ifeq (ngbde,$(SYSTEM_INTERFACE)) +LTSW_ADD_CPPFLAGS += -DBCMDRD_CONFIG_MEMMAP_DIRECT=1 +endif -ifeq (1,$(DEBIAN_LINUX_HEADER)) -KERNDIR_COMMON := $(subst amd64,common,$(KERNDIR)) -KFLAGS += -I$(KERNDIR_COMMON)/include -I$(KERNDIR_COMMON)/include/uapi -I$(KERNDIR_COMMON)/arch/x86/include -I$(KERNDIR_COMMON)/arch/x86/include/uapi +export SYSTEM_INTERFACE endif include ${SDK}/make/Makefile.linux-x86-common-2_6 diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-xlr b/platform/broadcom/saibcm-modules/make/Makefile.linux-xlr new file mode 100644 index 000000000000..726dfdf505bd --- /dev/null +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-xlr @@ -0,0 +1,164 @@ +# +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa +# +# $Id: Makefile.linux-xlr-4_19,v 0.1 Broadcom SDK $ +# $Copyright: (c) 2015 Broadcom Corp. +# All Rights Reserved.$ + +# +# XLR system make file. +# +# Most of this was taken from target x86-smp_generic_64-2_6. +# + + +############################################################################# +# this segment is custom and not sourced from any existing makefile # +# (base thanks to http:confluence.broadcom.com/display/NTSWSW/X86+System) # +############################################################################# + +# set up a basic feature list. tcl, etc. # +#ifeq (,$(FEATURE_LIST)) +#FEATURE_LIST = TCL BFD PTP CINT L3 I2C MEM_SCAN EDITLINE BCM_SAL_PROFILE CUSTOMER TEST CHASSIS MSTP RCPU +#endif + +# some basic path variables for tools and kernel source, etc # +export XLR_TOOLS_BASE = /projects/ntsw-tools/linux/xlr-419 +TOOLCHAIN_DIR = $(XLR_TOOLS_BASE)/buildroot/host/usr +# Target machine for EDK-Host defconfig +TARGET_MACHINE ?= x86_64 +KERNDIR = $(XLR_TOOLS_BASE)/kernel/linux + +# set up cross compile prefix, tools dir variables. # +export CROSS_COMPILE := x86_64-broadcom-linux-gnu- +export TOOLS_DIR := $(TOOLCHAIN_DIR)/bin + +# architecture. # +ARCH = x86_64 +TARGET_ARCHITECTURE = x86_64-broadcom-linux-gnu + +# Noisy kernel build +KBUILD_VERBOSE = 1 + +export ARCH KBUILD_VERBOSE + +# set up paths. # +export LIBRARY_PATH := $(TOOLCHAIN_DIR)/lib:$(TOOLCHAIN_DIR)/lib64:$(LIBRARY_PATH) +export PATH := $(TOOLCHAIN_DIR)/bin:$(KERNDIR):$(PATH) + +# set up SYSINC path # +export SYSINC := $(XLR_TOOLS_BASE)/buildroot/host/usr/lib/gcc/$(TARGET_ARCHITECTURE)/5.4.0/include + + +# CFLAGS/CFGFLAGS # +CFLAGS += -DUSE_LINUX_BDE_MMAP=1 +#CFLAGS += -DBDE_LINUX_USE_MSI_INTERRUPT +CFLAGS += -Wno-error=unused-value +CFLAGS += -Wno-error=unused-but-set-variable +CFLAGS += -Wno-error=maybe-uninitialized +CFLAGS += -Wno-error=cpp +CFLAGS += -Wno-error=aggressive-loop-optimizations +CFLAGS += -Wno-error=array-bounds +CFLAGS += -Wno-error=strict-overflow +CFLAGS += -L$(TOOLCHAIN_DIR)/lib +CFLAGS += -L$(TOOLCHAIN_DIR)/lib64 +#CFLAGS += -Wl,--rpath=/lib64 # may need to set rpath and dynamic-linker path here (and possibly in KLFAGS below) in the future, # +#CFLAGS += -Wl,--dynamic-linker=/lib64/ld-linux-x86-64.so.2 # if we want to build the target executable to be used with shared libs # + +#XLDK-568 fix inline references +CFGFLAGS += -fgnu89-inline + + +# set up KFLAGS appropriately. # +ifeq (,$(KFLAGS)) +KFLAGS := -L$(TOOLCHAIN_DIR)/lib -L$(TOOLCHAIN_DIR)/lib64 -I$(KERNDIR) -lc -nostdinc -isystem $(SYSINC) -Iinclude -I$(KERNDIR)/arch/x86/include -I$(KERNDIR)/arch/x86/include/generated -I$(KERNDIR)/arch/x86/include/generated/uapi -I$(KERNDIR)/arch/x86/include/uapi -I$(KERNDIR)/include -I$(KERNDIR)/include/generated -I$(KERNDIR)/include/generated/uapi -I$(KERNDIR)/include/uapi -include $(KERNDIR)/include/generated/autoconf.h -D__KERNEL__ -DNDEBUG -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Wno-format-security -fno-delete-null-pointer-checks -O2 -m64 -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -maccumulate-outgoing-args -fstack-protector -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -Wframe-larger-than=1024 -fno-omit-frame-pointer -Wdeclaration-after-statement -Wno-pointer-sign -fno-dwarf2-cfi-asm -fconserve-stack +endif + + +###################################################################### +# this segment comes from make/Makefile.linux-x86-smp_generic_64-2_6 # +###################################################################### +CFGFLAGS += -DLONGS_ARE_64BITS +CFGFLAGS += -DPTRS_ARE_64BITS +CFGFLAGS += -DSAL_SPL_LOCK_ON_IRQ + + +############################################################## +# This segment comes from make/Makefile.linux-x86-common-2_6 # +############################################################## +CFGFLAGS += -DSYS_BE_PIO=0 -DSYS_BE_PACKET=0 -DSYS_BE_OTHER=0 +ENDIAN = LE_HOST=1 +CFGFLAGS += -D$(ENDIAN) +CFGFLAGS += -DBCM_PLATFORM_STRING=\"X86\" +CFGFLAGS += -DSAL_BDE_DMA_MEM_DEFAULT=32 + +# Extra variables. +EXTRA_CFLAGS = -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) + +comma = , +basetarget = $(basename $(notdir $@)) +modname = $(basetarget) + +name-fix = $(subst $(comma),_,$(subst -,_,$1)) +basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" +modname_flags = $(if $(filter 1,$(words $(modname))),\ +-D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") + +ifdef LTSW_CHIPS +# Ensure we do not use an out-of-date libelf.so +ELFUTILS_MIN = 158 +ELFUTILS_DIR ?= /projects/ntsw-tools/lib + +# Default open source target build +OPENSRC_BUILD ?= fed21-x86_64 + +# Hardware interface (see $SDKLT/bcma/sys/probe directory) +SYSTEM_INTERFACE ?= ngbde + +# Support BCMSIM in the same build +ifeq (1,$(BCM_SIM_PATH_SUPPORT)) +EXTRA_SYSTEM_INTERFACES = plisim +endif + +# Turn on direct register access if running on real hardware. +ifeq (ngbde,$(SYSTEM_INTERFACE)) +# Except if using multiple probe interfaces +ifeq (,$(EXTRA_SYSTEM_INTERFACES)) +LTSW_ADD_CPPFLAGS += -DBCMDRD_CONFIG_MEMMAP_DIRECT=1 +endif +endif + +export SYSTEM_INTERFACE +export EXTRA_SYSTEM_INTERFACES +endif + +ifneq ($(targetplat),user) +# By default we exclude -Werror from x86 kernel builds +BCM_CFLAGS = -Wall +include ${SDK}/make/Makefile.linux-kernel-2_6 +endif + + diff --git a/platform/broadcom/saibcm-modules/sdklt/LICENSES/gpl-2.0.txt b/platform/broadcom/saibcm-modules/sdklt/LICENSES/gpl-2.0.txt new file mode 100644 index 000000000000..d159169d1050 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/LICENSES/gpl-2.0.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/platform/broadcom/saibcm-modules/sdklt/Makefile b/platform/broadcom/saibcm-modules/sdklt/Makefile new file mode 100644 index 000000000000..d6f358c55283 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/Makefile @@ -0,0 +1,83 @@ +# +# $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. +# The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# version 2 as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# A copy of the GNU General Public License version 2 (GPLv2) can +# be found in the LICENSES folder.$ +# + +help: + @echo '' + @echo 'Build Linux GPL kernel modules for SDKLT.' + @echo '' + @echo 'Available make targets:' + @echo 'kmod - Build kernel modules' + @echo 'clean - Remove object files' + @echo '' + @echo 'Supported make variables:' + @echo 'KDIR - Linux kernel source directory (mandatory)' + @echo 'CROSS_COPILE - Cross-compiler prefix (optional)' + @echo '' + @echo 'Examples:' + @echo 'make -s KDIR=$$KERNEL/linux kmod' + @echo 'make -s clean' + @echo '' + +ifndef KDIR +nokdir: + @echo 'Error: The $$KDIR environment variable is not set.' + @echo '$$KDIR must point to a configured Linux kernel source tree.' + exit 1 +endif + +export KDIR +export CROSS_COMPILE + +override SDK := $(CURDIR) + +ifeq ($(BUILD_PSAMPLE),1) +PSAMPLE=psample +PSAMPLE_SYMVERS=$(SDK)/linux/psample/Module.symvers +endif + +kmod: bde knet knetcb $(PSAMPLE) + +bde: + $(MAKE) -C $(SDK)/linux/bde SDK=$(SDK) \ + $(TARGET) + ln -sf $(SDK)/linux/bde/*.ko + +knet: bde + $(MAKE) -C $(SDK)/linux/knet SDK=$(SDK) \ + KBUILD_EXTRA_SYMBOLS=$(SDK)/linux/bde/Module.symvers \ + $(TARGET) + ln -sf $(SDK)/linux/knet/*.ko + +knetcb: knet $(PSAMPLE) + $(MAKE) -C $(SDK)/linux/knetcb SDK=$(SDK) \ + KBUILD_EXTRA_SYMBOLS=$(SDK)/linux/knet/Module.symvers \ + KBUILD_EXTRA_SYMBOLS+=$(PSAMPLE_SYMVERS) \ + $(TARGET) + ln -sf $(SDK)/linux/knetcb/*.ko + +ifeq ($(BUILD_PSAMPLE),1) +$(PSAMPLE): + $(MAKE) -C $(SDK)/linux/psample SDK=$(SDK) \ + $(TARGET) + ln -sf $(SDK)/linux/psample/*.ko +endif + +clean: + $(MAKE) kmod TARGET=clean + rm -f *.ko + +.PHONY: help kmod bde knet knetcb $(PSAMPLE) clean diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56780_a0/bcm56780_a0_pdma_attach.c b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56780_a0/bcm56780_a0_pdma_attach.c new file mode 100644 index 000000000000..e06dcb68bfc8 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56780_a0/bcm56780_a0_pdma_attach.c @@ -0,0 +1,38 @@ +/*! \file bcm56780_a0_pdma_attach.c + * + * Initialize PDMA driver resources. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include +#include +#include + +int +bcm56780_a0_cnet_pdma_attach(struct pdma_dev *dev) +{ + return bcmcnet_cmicx_pdma_driver_attach(dev); +} + +int +bcm56780_a0_cnet_pdma_detach(struct pdma_dev *dev) +{ + return bcmcnet_cmicx_pdma_driver_detach(dev); +} + diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56880_a0/bcm56880_a0_pdma_attach.c b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56880_a0/bcm56880_a0_pdma_attach.c new file mode 100644 index 000000000000..9a2152e99ac0 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56880_a0/bcm56880_a0_pdma_attach.c @@ -0,0 +1,38 @@ +/*! \file bcm56880_a0_pdma_attach.c + * + * Initialize PDMA driver resources. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include +#include +#include + +int +bcm56880_a0_cnet_pdma_attach(struct pdma_dev *dev) +{ + return bcmcnet_cmicx_pdma_driver_attach(dev); +} + +int +bcm56880_a0_cnet_pdma_detach(struct pdma_dev *dev) +{ + return bcmcnet_cmicx_pdma_driver_detach(dev); +} + diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56990_a0/bcm56990_a0_pdma_attach.c b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56990_a0/bcm56990_a0_pdma_attach.c new file mode 100644 index 000000000000..7827ef25de3d --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56990_a0/bcm56990_a0_pdma_attach.c @@ -0,0 +1,38 @@ +/*! \file bcm56990_a0_pdma_attach.c + * + * Initialize PDMA driver resources. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include +#include +#include + +int +bcm56990_a0_cnet_pdma_attach(struct pdma_dev *dev) +{ + return bcmcnet_cmicx_pdma_driver_attach(dev); +} + +int +bcm56990_a0_cnet_pdma_detach(struct pdma_dev *dev) +{ + return bcmcnet_cmicx_pdma_driver_detach(dev); +} + diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56990_b0/bcm56990_b0_pdma_attach.c b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56990_b0/bcm56990_b0_pdma_attach.c new file mode 100644 index 000000000000..e34ae1f0b45c --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56990_b0/bcm56990_b0_pdma_attach.c @@ -0,0 +1,38 @@ +/*! \file bcm56990_b0_pdma_attach.c + * + * Initialize PDMA driver resources. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include +#include +#include + +int +bcm56990_b0_cnet_pdma_attach(struct pdma_dev *dev) +{ + return bcmcnet_cmicx_pdma_driver_attach(dev); +} + +int +bcm56990_b0_cnet_pdma_detach(struct pdma_dev *dev) +{ + return bcmcnet_cmicx_pdma_driver_detach(dev); +} + diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56996_a0/bcm56996_a0_pdma_attach.c b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56996_a0/bcm56996_a0_pdma_attach.c new file mode 100644 index 000000000000..aab5822f68b7 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56996_a0/bcm56996_a0_pdma_attach.c @@ -0,0 +1,38 @@ +/*! \file bcm56996_a0_pdma_attach.c + * + * Initialize PDMA driver resources. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include +#include +#include + +int +bcm56996_a0_cnet_pdma_attach(struct pdma_dev *dev) +{ + return bcmcnet_cmicx_pdma_driver_attach(dev); +} + +int +bcm56996_a0_cnet_pdma_detach(struct pdma_dev *dev) +{ + return bcmcnet_cmicx_pdma_driver_detach(dev); +} + diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/hmi/cmicd/bcmcnet_cmicd_pdma_hw.c b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/hmi/cmicd/bcmcnet_cmicd_pdma_hw.c new file mode 100644 index 000000000000..83ce4d11b97f --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/hmi/cmicd/bcmcnet_cmicd_pdma_hw.c @@ -0,0 +1,530 @@ +/*! \file bcmcnet_cmicd_pdma_hw.c + * + * Utility routines for handling BCMCNET hardware (CMICd). + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include +#include +#include +#include + +/*! + * Read 32-bit register + */ +static inline void +cmicd_pdma_reg_read32(struct pdma_hw *hw, uint32_t addr, uint32_t *data) +{ + if (hw->dev->dev_read32) { + hw->dev->dev_read32(hw->dev, addr, data); + } else { + DEV_READ32(&hw->dev->ctrl, addr, data); + } +} + +/*! + * Write 32-bit register + */ +static inline void +cmicd_pdma_reg_write32(struct pdma_hw *hw, uint32_t addr, uint32_t data) +{ + if (hw->dev->dev_write32) { + hw->dev->dev_write32(hw->dev, addr, data); + } else { + DEV_WRITE32(&hw->dev->ctrl, addr, data); + } +} + +/*! + * Enable interrupt for a channel + */ +static inline void +cmicd_pdma_intr_enable(struct pdma_hw *hw, int cmc, int chan, uint32_t mask) +{ + uint32_t reg = CMICD_IRQ_STAT(cmc); + + hw->dev->intr_unmask(hw->dev, cmc, chan, reg, mask); +} + +/*! + * Disable interrupt for a channel + */ +static inline void +cmicd_pdma_intr_disable(struct pdma_hw *hw, int cmc, int chan, uint32_t mask) +{ + uint32_t reg = CMICD_IRQ_STAT(cmc); + + hw->dev->intr_mask(hw->dev, cmc, chan, reg, mask); +} + +/*! + * Initialize HW + */ +static int +cmicd_pdma_hw_init(struct pdma_hw *hw) +{ + dev_mode_t mode = DEV_MODE_MAX; + uint32_t val; + + /* Temporarily upgrade work mode to get HW information in VNET mode. */ + if (hw->dev->mode == DEV_MODE_VNET) { + mode = DEV_MODE_VNET; + hw->dev->mode = DEV_MODE_UNET; + } + + /* Release credits to EP. Only do this once when HW is initialized. */ + hw->hdls.reg_rd32(hw, CMICD_EPINTF_RELEASE_CREDITS, &val); + if (!val) { + hw->hdls.reg_wr32(hw, CMICD_EPINTF_RELEASE_CREDITS, 1); + } + + hw->info.name = CMICD_DEV_NAME; + hw->hdls.reg_rd32(hw, CMICD_CMICM_REV_ID, &val); + hw->info.ver_no = val; + hw->hdls.reg_rd32(hw, CMICD_DEV_REV_ID, &val); + hw->info.dev_id = val & 0xffff; + hw->info.rev_id = val >> 16; + hw->info.num_cmcs = CMICD_PDMA_CMC_MAX; + hw->info.cmc_chans = CMICD_PDMA_CMC_CHAN; + hw->info.num_chans = CMICD_PDMA_CMC_MAX * CMICD_PDMA_CMC_CHAN; + hw->info.rx_dcb_size = CMICD_PDMA_DCB_SIZE; + hw->info.tx_dcb_size = CMICD_PDMA_DCB_SIZE; + hw->info.rx_ph_size = 0; + hw->info.tx_ph_size = 0; + + /* Restore work mode to VNET. */ + if (mode == DEV_MODE_VNET) { + hw->dev->mode = DEV_MODE_VNET; + } + + return SHR_E_NONE; +} + +/*! + * Configure HW + */ +static int +cmicd_pdma_hw_config(struct pdma_hw *hw) +{ + struct dev_ctrl *ctrl = &hw->dev->ctrl; + struct pdma_rx_queue *rxq = NULL; + struct pdma_tx_queue *txq = NULL; + uint32_t val, que_ctrl; + int grp, que; + uint32_t qi; + + for (qi = 0; qi < ctrl->nb_rxq; qi++) { + rxq = (struct pdma_rx_queue *)ctrl->rx_queue[qi]; + grp = rxq->group_id; + que = rxq->chan_id % CMICD_PDMA_CMC_CHAN; + que_ctrl = ctrl->grp[grp].que_ctrl[que]; + + hw->hdls.reg_wr32(hw, CMICD_PDMA_STAT_CLR(grp), CMICD_PDMA_DESC_CMPLT(que)); + hw->hdls.reg_wr32(hw, CMICD_PDMA_STAT_CLR(grp), CMICD_PDMA_DESC_CNTLD(que)); + val = 0; + if (que_ctrl & PDMA_PKT_BYTE_SWAP) { + val |= CMICD_PDMA_PKT_BIG_ENDIAN; + } + if (que_ctrl & PDMA_OTH_BYTE_SWAP) { + val |= CMICD_PDMA_DESC_BIG_ENDIAN; + } + if (!(hw->dev->flags & PDMA_CHAIN_MODE)) { + val |= CMICD_PDMA_CONTINUOUS; + } + val |= CMICD_PDMA_CNTLD_INTR; + val &= ~CMICD_PDMA_DIR; + hw->hdls.reg_wr32(hw, CMICD_PDMA_CTRL(grp, que), val); + } + + for (qi = 0; qi < ctrl->nb_txq; qi++) { + txq = (struct pdma_tx_queue *)ctrl->tx_queue[qi]; + grp = txq->group_id; + que = txq->chan_id % CMICD_PDMA_CMC_CHAN; + que_ctrl = ctrl->grp[grp].que_ctrl[que]; + + hw->hdls.reg_wr32(hw, CMICD_PDMA_STAT_CLR(grp), CMICD_PDMA_DESC_CMPLT(que)); + hw->hdls.reg_wr32(hw, CMICD_PDMA_STAT_CLR(grp), CMICD_PDMA_DESC_CNTLD(que)); + val = 0; + if (que_ctrl & PDMA_PKT_BYTE_SWAP) { + val |= CMICD_PDMA_PKT_BIG_ENDIAN; + } + if (que_ctrl & PDMA_OTH_BYTE_SWAP) { + val |= CMICD_PDMA_DESC_BIG_ENDIAN; + } + if (!(hw->dev->flags & PDMA_CHAIN_MODE)) { + val |= CMICD_PDMA_CONTINUOUS; + } + val |= CMICD_PDMA_CNTLD_INTR | CMICD_PDMA_DIR; + hw->hdls.reg_wr32(hw, CMICD_PDMA_CTRL(grp, que), val); + } + + return SHR_E_NONE; +} + +/*! + * Reset HW + */ +static int +cmicd_pdma_hw_reset(struct pdma_hw *hw) +{ + int gi, qi; + + for (gi = 0; gi < hw->dev->num_groups; gi++) { + if (!hw->dev->ctrl.grp[gi].attached) { + continue; + } + for (qi = 0; qi < CMICD_PDMA_CMC_CHAN; qi++) { + if (1 << qi & hw->dev->ctrl.grp[gi].bm_rxq || + 1 << qi & hw->dev->ctrl.grp[gi].bm_txq) { + hw->hdls.reg_wr32(hw, CMICD_PDMA_CTRL(gi, qi), 0); + } + } + } + + return SHR_E_NONE; +} + +/*! + * Start a channel + */ +static int +cmicd_pdma_chan_start(struct pdma_hw *hw, int chan) +{ + uint32_t val; + int grp, que; + + grp = chan / CMICD_PDMA_CMC_CHAN; + que = chan % CMICD_PDMA_CMC_CHAN; + + hw->hdls.reg_rd32(hw, CMICD_PDMA_CTRL(grp, que), &val); + val |= CMICD_PDMA_ENABLE; + hw->hdls.reg_wr32(hw, CMICD_PDMA_CTRL(grp, que), val); + + MEMORY_BARRIER; + + return SHR_E_NONE; +} + +/*! + * Stop a channel + */ +static int +cmicd_pdma_chan_stop(struct pdma_hw *hw, int chan) +{ + uint32_t val; + int grp, que; + int retry = CMICD_HW_RETRY_TIMES; + + grp = chan / CMICD_PDMA_CMC_CHAN; + que = chan % CMICD_PDMA_CMC_CHAN; + + hw->hdls.reg_rd32(hw, CMICD_PDMA_CTRL(grp, que), &val); + val |= CMICD_PDMA_ENABLE | CMICD_PDMA_ABORT; + hw->hdls.reg_wr32(hw, CMICD_PDMA_CTRL(grp, que), val); + + MEMORY_BARRIER; + + do { + val = ~CMICD_PDMA_ACTIVE(que); + hw->hdls.reg_rd32(hw, CMICD_PDMA_STAT(grp), &val); + } while ((val & CMICD_PDMA_ACTIVE(que)) && (--retry > 0)); + + hw->hdls.reg_rd32(hw, CMICD_PDMA_CTRL(grp, que), &val); + val &= ~(CMICD_PDMA_ENABLE | CMICD_PDMA_ABORT); + hw->hdls.reg_wr32(hw, CMICD_PDMA_CTRL(grp, que), val); + + hw->hdls.reg_wr32(hw, CMICD_PDMA_STAT_CLR(grp), CMICD_PDMA_DESC_CNTLD(que)); + + MEMORY_BARRIER; + + return SHR_E_NONE; +} + +/*! + * Setup a channel + */ +static int +cmicd_pdma_chan_setup(struct pdma_hw *hw, int chan, uint64_t addr) +{ + int grp, que; + + grp = chan / CMICD_PDMA_CMC_CHAN; + que = chan % CMICD_PDMA_CMC_CHAN; + + hw->hdls.reg_wr32(hw, CMICD_PDMA_DESC(grp, que), addr); + + MEMORY_BARRIER; + + return SHR_E_NONE; +} + +/*! + * Set halt point for a channel + */ +static int +cmicd_pdma_chan_goto(struct pdma_hw *hw, int chan, uint64_t addr) +{ + int grp, que; + + grp = chan / CMICD_PDMA_CMC_CHAN; + que = chan % CMICD_PDMA_CMC_CHAN; + + hw->hdls.reg_wr32(hw, CMICD_PDMA_DESC_HALT(grp, que), addr); + + MEMORY_BARRIER; + + return SHR_E_NONE; +} + +/*! + * Clear a channel + */ +static int +cmicd_pdma_chan_clear(struct pdma_hw *hw, int chan) +{ + int grp, que; + + grp = chan / CMICD_PDMA_CMC_CHAN; + que = chan % CMICD_PDMA_CMC_CHAN; + + hw->hdls.reg_wr32(hw, CMICD_PDMA_STAT_CLR(grp), CMICD_PDMA_DESC_CNTLD(que)); + + MEMORY_BARRIER; + + return SHR_E_NONE; +} + +/*! + * Get interrupt number for a channel + */ +static int +cmicd_pdma_chan_intr_num_get(struct pdma_hw *hw, int chan) +{ + int grp, que, start_num, mask_shift; + + grp = chan / CMICD_PDMA_CMC_CHAN; + que = chan % CMICD_PDMA_CMC_CHAN; + + mask_shift = 0; + if (grp > 0) { + mask_shift = CMICD_IRQ_MASK_SHIFT + grp * 32; + } + start_num = CMICD_IRQ_START_NUM + mask_shift; + + return start_num + (que * CMICD_IRQ_NUM_OFFSET); +} + +/*! + * Enable interrupt for a channel + */ +static int +cmicd_pdma_chan_intr_enable(struct pdma_hw *hw, int chan) +{ + int grp, que; + + grp = chan / CMICD_PDMA_CMC_CHAN; + que = chan % CMICD_PDMA_CMC_CHAN; + + cmicd_pdma_intr_enable(hw, grp, que, CMICD_IRQ_DESC_CNTLD(que)); + + return SHR_E_NONE; +} + +/*! + * Disable interrupt for a channel + */ +static int +cmicd_pdma_chan_intr_disable(struct pdma_hw *hw, int chan) +{ + int grp, que; + + grp = chan / CMICD_PDMA_CMC_CHAN; + que = chan % CMICD_PDMA_CMC_CHAN; + + cmicd_pdma_intr_disable(hw, grp, que, CMICD_IRQ_DESC_CNTLD(que)); + + return SHR_E_NONE; +} + +/*! + * Query interrupt status for a channel + * + * In group mode (interrupt processing per CMC), need to query each channel's + * interrupt status. + * + */ +static int +cmicd_pdma_chan_intr_query(struct pdma_hw *hw, int chan) +{ + uint32_t val; + int grp, que; + + grp = chan / CMICD_PDMA_CMC_CHAN; + que = chan % CMICD_PDMA_CMC_CHAN; + + hw->hdls.reg_rd32(hw, CMICD_IRQ_STAT(grp), &val); + + return val & CMICD_IRQ_DESC_CNTLD(que); +} + +/*! + * Check interrupt validity for a channel + * + * In group mode (interrupt processing per CMC), need to check each channel's + * interrupt validity based on its interrupt mask. + * + */ +static int +cmicd_pdma_chan_intr_check(struct pdma_hw *hw, int chan) +{ + int grp, que; + + grp = chan / CMICD_PDMA_CMC_CHAN; + que = chan % CMICD_PDMA_CMC_CHAN; + + if (!(hw->dev->ctrl.grp[grp].irq_mask & CMICD_IRQ_DESC_CNTLD(que))) { + return 0; + } + + return cmicd_pdma_chan_intr_query(hw, chan); +} + +/*! + * Coalesce interrupt for a channel + */ +static int +cmicd_pdma_chan_intr_coalesce(struct pdma_hw *hw, int chan, int count, int timer) +{ + uint32_t val; + int grp, que; + + grp = chan / CMICD_PDMA_CMC_CHAN; + que = chan % CMICD_PDMA_CMC_CHAN; + + val = CMICD_PDMA_INTR_COAL_ENA | + CMICD_PDMA_INTR_THRESH(count) | + CMICD_PDMA_INTR_TIMER(timer); + hw->hdls.reg_wr32(hw, CMICD_PDMA_INTR_COAL(grp, que), val); + + return SHR_E_NONE; +} + +/*! + * Dump registers for a channel + */ +static int +cmicd_pdma_chan_reg_dump(struct pdma_hw *hw, int chan) +{ + uint32_t val; + int grp, que; + + grp = chan / CMICD_PDMA_CMC_CHAN; + que = chan % CMICD_PDMA_CMC_CHAN; + + hw->hdls.reg_rd32(hw, CMICD_PDMA_CTRL(grp, que), &val); + CNET_PR("CMIC_CMC%d_CH%d_DMA_CTRL: 0x%08x\n", grp, que, val); + + hw->hdls.reg_rd32(hw, CMICD_PDMA_DESC(grp, que), &val); + CNET_PR("CMIC_CMC%d_DMA_DESC%d: 0x%08x\n", grp, que, val); + + hw->hdls.reg_rd32(hw, CMICD_PDMA_CURR_DESC(grp, que), &val); + CNET_PR("CMIC_CMC%d_CH%d_DMA_CURR_DESC: 0x%08x\n", grp, que, val); + + hw->hdls.reg_rd32(hw, CMICD_PDMA_DESC_HALT(grp, que), &val); + CNET_PR("CMIC_CMC%d_DMA_CH%d_DESC_HALT_ADDR: 0x%08x\n", grp, que, val); + + hw->hdls.reg_rd32(hw, CMICD_PDMA_COS_RX0(grp, que), &val); + CNET_PR("CMIC_CMC%d_CH%d_COS_CTRL_RX_0: 0x%08x\n", grp, que, val); + + hw->hdls.reg_rd32(hw, CMICD_PDMA_COS_RX1(grp, que), &val); + CNET_PR("CMIC_CMC%d_CH%d_COS_CTRL_RX_1: 0x%08x\n", grp, que, val); + + hw->hdls.reg_rd32(hw, CMICD_PDMA_COS_MASK0(grp), &val); + CNET_PR("CMIC_CMC%d_PROGRAMMABLE_COS_MASK0: 0x%08x\n", grp, val); + + hw->hdls.reg_rd32(hw, CMICD_PDMA_COS_MASK1(grp), &val); + CNET_PR("CMIC_CMC%d_PROGRAMMABLE_COS_MASK1: 0x%08x\n", grp, val); + + hw->hdls.reg_rd32(hw, CMICD_PDMA_INTR_COAL(grp, que), &val); + CNET_PR("CMIC_CMC%d_DMA_CH%d_INTR_COAL: 0x%08x\n", grp, que, val); + + hw->hdls.reg_rd32(hw, CMICD_PDMA_RBUF_THRE(grp, que), &val); + CNET_PR("CMIC_CMC%d_CH%d_RXBUF_THRESHOLD_CONFIG: 0x%08x\n", grp, que, val); + + hw->hdls.reg_rd32(hw, CMICD_PDMA_STAT(grp), &val); + CNET_PR("CMIC_CMC%d_DMA_STAT: 0x%08x\n", grp, val); + + hw->hdls.reg_rd32(hw, CMICD_PDMA_STAT_HI(grp), &val); + CNET_PR("CMIC_CMC%d_DMA_STAT_HI: 0x%08x\n", grp, val); + + hw->hdls.reg_rd32(hw, CMICD_PDMA_STAT_CLR(grp), &val); + CNET_PR("CMIC_CMC%d_DMA_STAT_CLR: 0x%08x\n", grp, val); + + hw->hdls.reg_rd32(hw, CMICD_PDMA_COUNT_RX(grp, que), &val); + CNET_PR("CMIC_CMC%d_PKT_COUNT_CH%d_RXPKT: 0x%08x\n", grp, que, val); + + hw->hdls.reg_rd32(hw, CMICD_PDMA_COUNT_TX(grp, que), &val); + CNET_PR("CMIC_CMC%d_PKT_COUNT_CH%d_TXPKT: 0x%08x\n", grp, que, val); + + hw->hdls.reg_rd32(hw, CMICD_IRQ_STAT(grp), &val); + CNET_PR("CMIC_CMC%d_IRQ_STAT0: 0x%08x\n", grp, val); + + hw->hdls.reg_rd32(hw, CMICD_IRQ_PCI_MASK(grp), &val); + CNET_PR("CMIC_CMC%d_PCIE_IRQ_MASK0: 0x%08x\n", grp, val); + + hw->hdls.reg_rd32(hw, CMICD_DEV_REV_ID, &val); + CNET_PR("CMIC_DEV_REV_ID: 0x%08x\n", val); + + hw->hdls.reg_rd32(hw, CMICD_CMICM_REV_ID, &val); + CNET_PR("CMIC_CMICM_REV_ID: 0x%08x\n", val); + + return SHR_E_NONE; +} + +/*! + * Initialize function pointers + */ +int +bcmcnet_cmicd_pdma_hw_hdls_init(struct pdma_hw *hw) +{ + if (!hw) { + return SHR_E_PARAM; + } + + hw->hdls.reg_rd32 = cmicd_pdma_reg_read32; + hw->hdls.reg_wr32 = cmicd_pdma_reg_write32; + hw->hdls.hw_init = cmicd_pdma_hw_init; + hw->hdls.hw_config = cmicd_pdma_hw_config; + hw->hdls.hw_reset = cmicd_pdma_hw_reset; + hw->hdls.chan_start = cmicd_pdma_chan_start; + hw->hdls.chan_stop = cmicd_pdma_chan_stop; + hw->hdls.chan_setup = cmicd_pdma_chan_setup; + hw->hdls.chan_goto = cmicd_pdma_chan_goto; + hw->hdls.chan_clear = cmicd_pdma_chan_clear; + hw->hdls.chan_intr_num_get = cmicd_pdma_chan_intr_num_get; + hw->hdls.chan_intr_enable = cmicd_pdma_chan_intr_enable; + hw->hdls.chan_intr_disable = cmicd_pdma_chan_intr_disable; + hw->hdls.chan_intr_query = cmicd_pdma_chan_intr_query; + hw->hdls.chan_intr_check = cmicd_pdma_chan_intr_check; + hw->hdls.chan_intr_coalesce = cmicd_pdma_chan_intr_coalesce; + hw->hdls.chan_reg_dump = cmicd_pdma_chan_reg_dump; + + return SHR_E_NONE; +} + diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/hmi/cmicd/bcmcnet_cmicd_pdma_rxtx.c b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/hmi/cmicd/bcmcnet_cmicd_pdma_rxtx.c new file mode 100644 index 000000000000..c4a10e160db9 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/hmi/cmicd/bcmcnet_cmicd_pdma_rxtx.c @@ -0,0 +1,1062 @@ +/*! \file bcmcnet_cmicd_pdma_rxtx.c + * + * Utility routines for BCMCNET hardware (CMICd) specific Rx/Tx. + * + * Here are the CMIC specific Rx/Tx routines including DCBs resource allocation + * and clean up, DCBs configuration, Rx buffers allocation, Tx buffers release, + * Rx/Tx packets processing, etc. + * They are shared among all the modes (UNET, KNET, VNET, HNET) and in both of + * user space and kernel space. + * + * The driver uses a ring of DCBs per DMA channel based on Continuous DMA mode. + * The beginning is written to register pointing to the physical address of the + * start of the ring. The ring size is maintained by the driver. A HALT DCB + * physical address is written to DMA register timely to indicate how many DCBs + * can be handled by HW. + * + * When a packet is received, an interrupt is triggered. The handler will go + * through the Rx DCB ring to process the current completed DCB and every + * subsequent DCBs until no one is left. The received packet is processed and + * passed up to the high level SW. After that, a new buffer is allocated and + * the DCB is updated for receiving a new packet. A new HALT DCB is selected + * and its physical address is written to DMA register. + * + * When a packet is transmitted, the driver starts where it left off last time + * in the Tx DCB ring, updates the DCB and writes its physical address to DMA + * register so as to start DMA. Once the transmitting is finished, the handler + * is informed to clean up the buffer based on the work mode. In KNET or HNET + * mode, an interrupt will be triggered. Polling mode is used in CNET or VNET + * mode, the buffers will be cleaned up when the number of dirty DCBs reaches + * a pre-defined threshold. + * + * In VNET and HNET modes, DCB updating between virtual ring and real ring and + * a IOCTL based notification mechanism are involved. The hypervisor in kernel + * emulates the DMA HW behaviors to update DCBs in virtual network and inform + * the handler something happened. Likewise, the hypervisor updates itself real + * DCB ring from the virtual ring to start DMA for transmitting a packet once a + * notification is received from the virtual network. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include +#include +#include +#include +#include + +/*! + * Configure Rx descriptor + */ +static inline void +cmicd_rx_desc_config(struct cmicd_rx_desc *rd, uint32_t addr, uint32_t len) +{ + rd->addr = addr; + rd->md.status = 0; + rd->ctrl = CMICD_DESC_CTRL_CNTLD_INTR | CMICD_DESC_CTRL_CHAIN | + CMICD_DESC_CTRL_LEN(len); +} + +/*! + * Configure Tx descriptor + */ +static inline void +cmicd_tx_desc_config(struct cmicd_tx_desc *td, uint32_t addr, uint32_t len, uint32_t flags) +{ + td->addr = addr; + td->md.status = 0; + td->ctrl = CMICD_DESC_CTRL_CNTLD_INTR | CMICD_DESC_CTRL_CHAIN | + CMICD_DESC_CTRL_FLAGS(flags) | CMICD_DESC_CTRL_LEN(len); +} + +/*! + * Configure Rx reload descriptor + */ +static inline void +cmicd_rx_rldesc_config(struct cmicd_rx_desc *rd, uint32_t addr) +{ + rd->addr = addr; + rd->md.status = 0; + rd->ctrl = CMICD_DESC_CTRL_CNTLD_INTR | CMICD_DESC_CTRL_CHAIN | + CMICD_DESC_CTRL_RELOAD; +} + +/*! + * Configure Tx reload descriptor + */ +static inline void +cmicd_tx_rldesc_config(struct cmicd_tx_desc *td, uint32_t addr) +{ + td->addr = addr; + td->md.status = 0; + td->ctrl = CMICD_DESC_CTRL_CNTLD_INTR | CMICD_DESC_CTRL_CHAIN | + CMICD_DESC_CTRL_RELOAD; +} + +/*! + * Chain Rx descriptor + */ +static inline void +cmicd_rx_desc_chain(struct cmicd_rx_desc *rd, int chain) +{ + if (chain) { + rd->ctrl |= CMICD_DESC_CTRL_CHAIN; + } else { + rd->ctrl &= ~CMICD_DESC_CTRL_CHAIN; + } +} + +/*! + * Chain Tx descriptor + */ +static inline void +cmicd_tx_desc_chain(struct cmicd_tx_desc *td, int chain) +{ + if (chain) { + td->ctrl |= CMICD_DESC_CTRL_CHAIN; + } else { + td->ctrl &= ~CMICD_DESC_CTRL_CHAIN; + } +} + +/*! + * Get unused descriptors in a Rx ring + */ +static inline int +cmicd_pdma_rx_ring_unused(struct pdma_rx_queue *rxq) +{ + /* Leave one descriptor unused so as not to halt */ + return rxq->curr > rxq->halt ? + rxq->curr - rxq->halt - 1 : + rxq->nb_desc + rxq->curr - rxq->halt - 1; +} + +/*! + * Get unused descriptors in a Tx ring + */ +static inline int +cmicd_pdma_tx_ring_unused(struct pdma_tx_queue *txq) +{ + /* Leave one descriptor unused so as not to halt */ + return txq->dirt > txq->curr ? + txq->dirt - txq->curr - 1 : + txq->nb_desc + txq->dirt - txq->curr - 1; +} + +/*! + * Initialize Rx descriptors + */ +static int +cmicd_pdma_rx_desc_init(struct pdma_hw *hw, struct pdma_rx_queue *rxq) +{ + struct pdma_dev *dev = hw->dev; + struct pdma_buf_mngr *bm = (struct pdma_buf_mngr *)dev->ctrl.buf_mngr; + struct cmicd_rx_desc *ring = (struct cmicd_rx_desc *)rxq->ring; + dma_addr_t addr; + uint32_t di; + int rv; + + for (di = 0; di < rxq->nb_desc; di++) { + if (!rxq->pbuf[di].dma) { + /* Allocate pktbuf for ring entry */ + rxq->pbuf[di].adj = CMICD_RX_META_RESV; + rv = bm->rx_buf_alloc(dev, rxq, &rxq->pbuf[di]); + if (SHR_FAILURE(rv)) { + goto cleanup; + } + } + /* Config receive descriptor ring */ + bm->rx_buf_dma(dev, rxq, &rxq->pbuf[di], &addr); + cmicd_rx_desc_config(&ring[di], addr, rxq->buf_size); + if (hw->dev->flags & PDMA_CHAIN_MODE && di == rxq->nb_desc - 1) { + cmicd_rx_desc_chain(&ring[di], 0); + } + } + /* Config the last descriptor in the ring as reload descriptor */ + cmicd_rx_rldesc_config(&ring[di], rxq->ring_addr); + + rxq->curr = 0; + rxq->halt = rxq->state & PDMA_RX_BATCH_REFILL ? 0 : rxq->nb_desc; + + rxq->halt_addr = rxq->ring_addr + sizeof(struct cmicd_rx_desc) * di; + hw->hdls.chan_goto(hw, rxq->chan_id, rxq->halt_addr); + hw->hdls.chan_setup(hw, rxq->chan_id, rxq->ring_addr); + + return SHR_E_NONE; + +cleanup: + for (di = 0; di < rxq->nb_desc; di++) { + if (rxq->pbuf[di].dma) { + bm->rx_buf_free(dev, rxq, &rxq->pbuf[di]); + } + cmicd_rx_desc_config(&ring[di], 0, 0); + } + + CNET_PR("RX: Failed to allocate mem\n"); + + return SHR_E_MEMORY; +} + +/*! + * Cleanup Rx descriptors + */ +static int +cmicd_pdma_rx_desc_clean(struct pdma_hw *hw, struct pdma_rx_queue *rxq) +{ + struct pdma_dev *dev = hw->dev; + struct pdma_buf_mngr *bm = (struct pdma_buf_mngr *)dev->ctrl.buf_mngr; + struct cmicd_rx_desc *ring = (struct cmicd_rx_desc *)rxq->ring; + uint32_t di; + + /* Go through all the descriptors and free pktbuf */ + for (di = 0; di < rxq->nb_desc; di++) { + if (rxq->pbuf[di].dma) { + bm->rx_buf_free(dev, rxq, &rxq->pbuf[di]); + } + cmicd_rx_desc_config(&ring[di], 0, 0); + } + + rxq->curr = 0; + rxq->halt = 0; + + return SHR_E_NONE; +} + +/*! + * Initialize Tx descriptors + */ +static int +cmicd_pdma_tx_desc_init(struct pdma_hw *hw, struct pdma_tx_queue *txq) +{ + struct pdma_dev *dev = hw->dev; + struct pdma_buf_mngr *bm = (struct pdma_buf_mngr *)dev->ctrl.buf_mngr; + struct cmicd_tx_desc *ring = (struct cmicd_tx_desc *)txq->ring; + uint32_t di; + + for (di = 0; di < txq->nb_desc; di++) { + if (txq->pbuf[di].dma) { + bm->tx_buf_free(dev, txq, &txq->pbuf[di]); + } + /* Config transmit descriptor ring */ + cmicd_tx_desc_config(&ring[di], 0, 0, 0); + if (hw->dev->flags & PDMA_CHAIN_MODE) { + cmicd_tx_desc_chain(&ring[di], 0); + } + } + /* Config the last descriptor in the ring as reload descriptor */ + cmicd_tx_rldesc_config(&ring[di], txq->ring_addr); + + txq->curr = 0; + txq->dirt = 0; + txq->halt = 0; + + txq->halt_addr = txq->ring_addr; + hw->hdls.chan_goto(hw, txq->chan_id, txq->halt_addr); + hw->hdls.chan_setup(hw, txq->chan_id, txq->ring_addr); + + return SHR_E_NONE; +} + +/*! + * Cleanup Tx descriptors + */ +static int +cmicd_pdma_tx_desc_clean(struct pdma_hw *hw, struct pdma_tx_queue *txq) +{ + struct pdma_dev *dev = hw->dev; + struct pdma_buf_mngr *bm = (struct pdma_buf_mngr *)dev->ctrl.buf_mngr; + struct cmicd_tx_desc *ring = (struct cmicd_tx_desc *)txq->ring; + uint32_t di; + + /* Go through all the descriptors and free pktbuf */ + for (di = 0; di < txq->nb_desc; di++) { + if (txq->pbuf[di].dma) { + bm->tx_buf_free(dev, txq, &txq->pbuf[di]); + } + cmicd_tx_desc_config(&ring[di], 0, 0, 0); + } + + txq->curr = 0; + txq->dirt = 0; + txq->halt = 0; + + return SHR_E_NONE; +} + +/*! + * Process Rx vring + */ +static int +cmicd_pdma_rx_vring_process(struct pdma_hw *hw, struct pdma_rx_queue *rxq, + struct pdma_rx_buf *pbuf) +{ + struct pdma_dev *dev = hw->dev; + struct cmicd_rx_desc *ring = (struct cmicd_rx_desc *)rxq->ring; + struct pdma_rx_queue *vrxq = NULL; + struct cmicd_rx_desc *vring = NULL; + struct pkt_hdr *pkh = &pbuf->pkb->pkh; + + vrxq = (struct pdma_rx_queue *)dev->ctrl.vnet_rxq[rxq->queue_id]; + vring = (struct cmicd_rx_desc *)vrxq->ring; + if (!vring) { + rxq->stats.dropped++; + return SHR_E_UNAVAIL; + } + + if (vring[vrxq->curr].md.status & CMICD_DESC_STAT_RTX_DONE) { + dev->xnet_wake(dev); + return SHR_E_BUSY; + } + + /* Copy descriptor and packet to vring */ + sal_memcpy(dev->sys_p2v(dev, (uint64_t)vring[vrxq->curr].addr), + &pbuf->pkb->data + pkh->meta_len, pkh->data_len); + sal_memcpy(&vring[vrxq->curr].md, &ring[rxq->curr].md, + sizeof(((struct rx_metadata *)0)->data)); + vring[vrxq->curr].md.status = ring[rxq->curr].md.status; + + MEMORY_BARRIER; + + /* Notify VNET to process if needed */ + if (!vring[(vrxq->curr + vrxq->nb_desc - 1) % vrxq->nb_desc].md.status) { + dev->xnet_wake(dev); + } + vrxq->curr = (vrxq->curr + 1) % vrxq->nb_desc; + + return SHR_E_NONE; +} + +/*! + * Refill Rx ring + */ +static int +cmicd_pdma_rx_ring_refill(struct pdma_hw *hw, struct pdma_rx_queue *rxq) +{ + struct pdma_dev *dev = hw->dev; + struct pdma_buf_mngr *bm = (struct pdma_buf_mngr *)dev->ctrl.buf_mngr; + struct cmicd_rx_desc *ring = (struct cmicd_rx_desc *)rxq->ring; + struct pdma_rx_buf *pbuf = NULL; + int unused = cmicd_pdma_rx_ring_unused(rxq); + dma_addr_t addr; + uint32_t halt; + int rv; + + for (halt = rxq->halt; halt < rxq->halt + unused; halt++) { + pbuf = &rxq->pbuf[halt % rxq->nb_desc]; + /* Allocate a new pktbuf */ + if (!bm->rx_buf_avail(dev, rxq, pbuf)) { + rv = bm->rx_buf_alloc(dev, rxq, pbuf); + if (SHR_FAILURE(rv)) { + rxq->halt = halt % rxq->nb_desc; + rxq->stats.nomems++; + goto fail; + } + } + /* Setup the new descriptor */ + bm->rx_buf_dma(dev, rxq, pbuf, &addr); + cmicd_rx_desc_config(&ring[halt % rxq->nb_desc], addr, rxq->buf_size); + if (dev->flags & PDMA_CHAIN_MODE && halt % rxq->nb_desc == rxq->nb_desc - 1) { + cmicd_rx_desc_chain(&ring[halt % rxq->nb_desc], 0); + } + } + + sal_spinlock_lock(rxq->lock); + rxq->halt = halt % rxq->nb_desc; + if (!(rxq->state & PDMA_RX_QUEUE_XOFF)) { + /* Descriptor cherry pick */ + rxq->halt_addr = rxq->ring_addr + sizeof(struct cmicd_rx_desc) * rxq->halt; + hw->hdls.chan_goto(hw, rxq->chan_id, rxq->halt_addr); + } + sal_spinlock_unlock(rxq->lock); + + return SHR_E_NONE; + +fail: + CNET_PR("RX: Failed to allocate mem\n"); + + return SHR_E_MEMORY; +} + +/*! + * \brief Clean Rx ring + * + * \param [in] hw HW structure point. + * \param [in] rxq Rx queue structure point. + * \param [in] budget Polling budget. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +static int +cmicd_pdma_rx_ring_clean(struct pdma_hw *hw, struct pdma_rx_queue *rxq, int budget) +{ + struct pdma_dev *dev = hw->dev; + struct pdma_buf_mngr *bm = (struct pdma_buf_mngr *)dev->ctrl.buf_mngr; + struct cmicd_rx_desc *ring = (struct cmicd_rx_desc *)rxq->ring; + struct pdma_rx_buf *pbuf = NULL; + struct pkt_hdr *pkh = NULL; + dma_addr_t addr; + uint32_t stat, curr; + int len, done = 0; + int rv; + + curr = rxq->curr; + while (CMICD_DESC_STAT_DONE(ring[curr].md.status)) { + if (dev->mode == DEV_MODE_VNET && rxq->state & PDMA_RX_QUEUE_XOFF) { + break; + } + if (!(rxq->state & PDMA_RX_BATCH_REFILL) && + !(rxq->state & PDMA_RX_QUEUE_XOFF)) { + /* Descriptor cherry pick */ + rxq->halt_addr = rxq->ring_addr + sizeof(struct cmicd_rx_desc) * curr; + hw->hdls.chan_goto(hw, rxq->chan_id, rxq->halt_addr); + rxq->halt = curr; + } + if (done == budget) { + break; + } + + /* Get the current pktbuf to process */ + pbuf = &rxq->pbuf[curr]; + stat = ring[curr].md.status; + len = CMICD_DESC_STAT_LEN(stat); + pkh = bm->rx_buf_get(dev, rxq, pbuf, len); + if (!pkh) { + rxq->stats.nomems++; + goto fail; + } + + /* Setup packet header */ + pkh->data_len = len; + pkh->meta_len = pbuf->adj; + pkh->queue_id = rxq->queue_id; + pkh->attrs = CMICD_DESC_STAT_FLAGS(stat); + sal_memcpy(&pbuf->pkb->data, &ring[curr].md, sizeof(struct rx_metadata)); + + /* Send up the packet */ + rv = dev->pkt_recv(dev, rxq->queue_id, (void *)pbuf->skb); + if (SHR_FAILURE(rv)) { + if (dev->mode == DEV_MODE_HNET && pkh->attrs & PDMA_RX_TO_VNET) { + rv = cmicd_pdma_rx_vring_process(hw, rxq, pbuf); + if (SHR_FAILURE(rv) && rv == SHR_E_BUSY) { + rxq->state |= PDMA_RX_QUEUE_BUSY; + return done; + } + } else { + rxq->stats.dropped++; + } + bm->rx_buf_put(dev, rxq, pbuf, len); + } + + /* Count the packets/bytes */ + rxq->stats.packets++; + rxq->stats.bytes += len; + + /* Count the errors if any */ + if (stat & CMICD_DESC_STAT_ERR_MASK) { + rxq->stats.errors++; + if (stat & CMICD_DESC_STAT_HEAD_ERR) { + rxq->stats.head_errors++; + } + if (stat & CMICD_DESC_STAT_DATA_ERR) { + rxq->stats.data_errors++; + } + if (stat & CMICD_DESC_STAT_CELL_ERR) { + rxq->stats.cell_errors++; + } + } + + /* Setup the new descriptor */ + if (!(rxq->state & PDMA_RX_BATCH_REFILL)) { + if (!bm->rx_buf_avail(dev, rxq, pbuf)) { + rv = bm->rx_buf_alloc(dev, rxq, pbuf); + if (SHR_FAILURE(rv)) { + rxq->stats.nomems++; + goto fail; + } + } + bm->rx_buf_dma(dev, rxq, pbuf, &addr); + cmicd_rx_desc_config(&ring[curr], addr, rxq->buf_size); + if (dev->flags & PDMA_CHAIN_MODE && curr == rxq->nb_desc - 1) { + cmicd_rx_desc_chain(&ring[curr], 0); + } + } else { + cmicd_rx_desc_config(&ring[curr], 0, 0); + } + + /* Notify HNET to process if needed */ + if (dev->mode == DEV_MODE_VNET) { + MEMORY_BARRIER; + if (ring[(curr + rxq->nb_desc - 1) % rxq->nb_desc].md.status) { + dev->xnet_wake(dev); + } + } + + /* Update the indicators */ + if (!(rxq->state & PDMA_RX_BATCH_REFILL) && rxq->halt != curr) { + sal_spinlock_lock(rxq->lock); + if (!(rxq->state & PDMA_RX_QUEUE_XOFF)) { + /* Descriptor cherry pick */ + rxq->halt_addr = rxq->ring_addr + sizeof(struct cmicd_rx_desc) * curr; + hw->hdls.chan_goto(hw, rxq->chan_id, rxq->halt_addr); + rxq->halt = curr; + } + curr = (curr + 1) % rxq->nb_desc; + sal_spinlock_unlock(rxq->lock); + } else { + curr = (curr + 1) % rxq->nb_desc; + } + rxq->curr = curr; + done++; + + /* Restart DMA if in chain mode */ + if (dev->flags & PDMA_CHAIN_MODE) { + if (curr == 0 && !(rxq->state & PDMA_RX_QUEUE_XOFF)) { + hw->hdls.chan_stop(hw, rxq->chan_id); + hw->hdls.chan_start(hw, rxq->chan_id); + } + } + } + + /* One more poll for chain done in chain mode */ + if (dev->flags & PDMA_CHAIN_MODE) { + if (curr == rxq->nb_desc - 1 && done) { + done = budget; + } + } + + /* In batching mode, replenish all the unused descriptors */ + if (rxq->state & PDMA_RX_BATCH_REFILL && + cmicd_pdma_rx_ring_unused(rxq) >= (int)rxq->free_thresh) { + cmicd_pdma_rx_ring_refill(hw, rxq); + } + + /* Notify the other side to process */ + if (dev->mode == DEV_MODE_VNET || dev->mode == DEV_MODE_HNET) { + if (done) { + dev->xnet_wake(dev); + } + } + + return done; + +fail: + CNET_PR("RX: Failed to allocate mem\n"); + + return done; +} + +/*! + * Process Tx vring + */ +static int +cmicd_pdma_tx_vring_process(struct pdma_hw *hw, struct pdma_tx_queue *txq, + struct pdma_tx_buf *pbuf) +{ + struct pdma_dev *dev = hw->dev; + struct cmicd_tx_desc *ring = (struct cmicd_tx_desc *)txq->ring; + struct pdma_tx_queue *vtxq = NULL; + struct cmicd_tx_desc *vring = NULL; + + vtxq = (struct pdma_tx_queue *)dev->ctrl.vnet_txq[txq->queue_id]; + vring = (struct cmicd_tx_desc *)vtxq->ring; + if (!vring) { + return SHR_E_UNAVAIL; + } + + /* Update vring descriptor */ + vring[vtxq->dirt].md.status = ring[txq->dirt].md.status; + pbuf->dma = 0; + + MEMORY_BARRIER; + + /* Notify VNET to process if needed */ + if (!vring[(vtxq->dirt + vtxq->nb_desc - 1) % vtxq->nb_desc].md.status) { + dev->xnet_wake(dev); + } + vtxq->dirt = (vtxq->dirt + 1) % vtxq->nb_desc; + + return SHR_E_NONE; +} + +/*! + * \brief Clean Tx ring + * + * \param [in] hw HW structure point. + * \param [in] txq Tx queue structure point. + * \param [in] budget Polling budget. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +static int +cmicd_pdma_tx_ring_clean(struct pdma_hw *hw, struct pdma_tx_queue *txq, int budget) +{ + struct pdma_dev *dev = hw->dev; + struct pdma_buf_mngr *bm = (struct pdma_buf_mngr *)dev->ctrl.buf_mngr; + struct cmicd_tx_desc *ring = (struct cmicd_tx_desc *)txq->ring; + uint32_t dirt, curr; + int done = 0; + + dirt = txq->dirt; + while (txq->pbuf[dirt].dma) { + if (!CMICD_DESC_STAT_DONE(ring[dirt].md.status)) { + break; + } + if (done == budget) { + break; + } + + if (dev->mode == DEV_MODE_HNET && !txq->pbuf[dirt].skb) { + cmicd_pdma_tx_vring_process(hw, txq, &txq->pbuf[dirt]); + } else { + /* Free the done pktbuf */ + bm->tx_buf_free(dev, txq, &txq->pbuf[dirt]); + } + + cmicd_tx_desc_config(&ring[dirt], 0, 0, 0); + + /* Update the indicators */ + dirt = (dirt + 1) % txq->nb_desc; + txq->dirt = dirt; + done++; + + /* Restart DMA if in chain mode */ + if (dev->flags & PDMA_CHAIN_MODE) { + sal_spinlock_lock(txq->lock); + curr = txq->curr; + if (dirt == txq->halt && dirt != curr) { + hw->hdls.chan_stop(hw, txq->chan_id); + cmicd_tx_desc_chain(&ring[(curr + txq->nb_desc - 1) % txq->nb_desc], 0); + hw->hdls.chan_setup(hw, txq->chan_id, + txq->ring_addr + sizeof(struct cmicd_tx_desc) * txq->halt); + hw->hdls.chan_start(hw, txq->chan_id); + txq->halt = curr; + } + sal_spinlock_unlock(txq->lock); + } + } + + /* One more poll for chain done in chain mode */ + if (dev->flags & PDMA_CHAIN_MODE) { + sal_spinlock_lock(txq->lock); + if (dirt != txq->halt) { + done = budget; + } + sal_spinlock_unlock(txq->lock); + } + + /* Resume Tx if any */ + sal_spinlock_lock(txq->lock); + if (cmicd_pdma_tx_ring_unused(txq) && txq->state & PDMA_TX_QUEUE_XOFF) { + txq->state &= ~PDMA_TX_QUEUE_XOFF; + sal_spinlock_unlock(txq->lock); + if (dev->tx_resume) { + dev->tx_resume(dev, txq->queue_id); + } else if (!(txq->state & PDMA_TX_QUEUE_POLL)) { + sal_sem_give(txq->sem); + } + return done; + } + sal_spinlock_unlock(txq->lock); + + return done; +} + +/*! + * Dump Rx ring + */ +static int +cmicd_pdma_rx_ring_dump(struct pdma_hw *hw, struct pdma_rx_queue *rxq) +{ + struct cmicd_rx_desc *ring = (struct cmicd_rx_desc *)rxq->ring; + struct cmicd_rx_desc *rd; + uint32_t di; + + CNET_PR("\nRX: queue=%d, chan=%d, curr=%d, halt=%d, halt@%p\n", + rxq->queue_id, rxq->chan_id, rxq->curr, rxq->halt, (void *)&ring[rxq->halt]); + CNET_PR("----------------------------------------------------------------\n"); + for (di = 0; di < rxq->nb_desc + 1; di++) { + rd = &ring[di]; + CNET_PR("DESC[%03d]: (%p)->%08x %08x ... %08x\n", + di, (void *)(unsigned long)(rxq->ring_addr + di * CMICD_PDMA_DCB_SIZE), + rd->addr, rd->ctrl, rd->md.status); + } + + return SHR_E_NONE; +} + +/*! + * Dump Tx ring + */ +static int +cmicd_pdma_tx_ring_dump(struct pdma_hw *hw, struct pdma_tx_queue *txq) +{ + struct cmicd_tx_desc *ring = (struct cmicd_tx_desc *)txq->ring; + struct cmicd_tx_desc *td; + uint32_t di; + + CNET_PR("\nTX: queue=%d, chan=%d, curr=%d, dirt=%d, halt@%p\n", + txq->queue_id, txq->chan_id, txq->curr, txq->dirt, (void *)&ring[txq->curr]); + CNET_PR("----------------------------------------------------------------\n"); + for (di = 0; di < txq->nb_desc + 1; di++) { + td = &ring[di]; + CNET_PR("DESC[%03d]: (%p)->%08x %08x ... %08x\n", + di, (void *)(unsigned long)(txq->ring_addr + di * CMICD_PDMA_DCB_SIZE), + td->addr, td->ctrl, td->md.status); + } + + return SHR_E_NONE; +} + +/*! + * Fetch Tx vring + */ +static int +cmicd_pdma_tx_vring_fetch(struct pdma_hw *hw, struct pdma_tx_queue *txq, + struct pdma_tx_buf *pbuf) +{ + struct pdma_dev *dev = hw->dev; + struct cmicd_tx_desc *ring = (struct cmicd_tx_desc *)txq->ring; + struct pdma_tx_queue *vtxq = NULL; + struct cmicd_tx_desc *vring = NULL; + + vtxq = (struct pdma_tx_queue *)dev->ctrl.vnet_txq[txq->queue_id]; + vring = (struct cmicd_tx_desc *)vtxq->ring; + if (!vring || !CMICD_DESC_CTRL_LEN(vring[vtxq->curr].ctrl)) { + return SHR_E_UNAVAIL; + } + + /* Fetch vring descriptor */ + sal_memcpy(&ring[txq->curr], &vring[vtxq->curr], sizeof(struct cmicd_tx_desc)); + vring[vtxq->curr].ctrl &= ~CMICD_DESC_CTRL_LEN(-1); + + MEMORY_BARRIER; + + pbuf->dma = vring[vtxq->curr].addr; + pbuf->len = CMICD_DESC_CTRL_LEN(ring[txq->curr].ctrl); + vtxq->curr = (vtxq->curr + 1) % vtxq->nb_desc; + + return SHR_E_NONE; +} + +/*! + * Check Tx ring + */ +static inline int +cmicd_pdma_tx_ring_check(struct pdma_hw *hw, struct pdma_tx_queue *txq) +{ + if (cmicd_pdma_tx_ring_unused(txq)) { + return SHR_E_NONE; + } + + sal_spinlock_lock(txq->lock); + if (!cmicd_pdma_tx_ring_unused(txq)) { + txq->state |= PDMA_TX_QUEUE_XOFF; + txq->stats.xoffs++; + sal_spinlock_unlock(txq->lock); + if (hw->dev->tx_suspend) { + hw->dev->tx_suspend(hw->dev, txq->queue_id); + } + return SHR_E_BUSY; + } + sal_spinlock_unlock(txq->lock); + + return SHR_E_NONE; +} + +/*! + * \brief Start packet transmission + * + * \param [in] hw HW structure point. + * \param [in] txq Tx queue structure point. + * \param [in] buf Tx packet buffer. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +static int +cmicd_pdma_pkt_xmit(struct pdma_hw *hw, struct pdma_tx_queue *txq, void *buf) +{ + struct pdma_dev *dev = hw->dev; + struct pdma_buf_mngr *bm = (struct pdma_buf_mngr *)dev->ctrl.buf_mngr; + struct cmicd_tx_desc *ring = (struct cmicd_tx_desc *)txq->ring; + struct pdma_tx_buf *pbuf = NULL; + struct pkt_hdr *pkh = NULL; + dma_addr_t addr; + uint32_t curr, flags = 0; + int retry = 5000000; + int rv; + + if (!(txq->state & PDMA_TX_QUEUE_ACTIVE)) { + return SHR_E_UNAVAIL; + } + + if (dev->tx_suspend) { + sal_spinlock_lock(txq->mutex); + } else { + sal_sem_take(txq->sem, SAL_SEM_FOREVER); + } + + /* Check Tx resource */ + if (dev->tx_suspend) { + /* Suspend Tx if no resource */ + rv = cmicd_pdma_tx_ring_check(hw, txq); + if (SHR_FAILURE(rv)) { + sal_spinlock_unlock(txq->mutex); + return rv; + } + } else { + /* Abort Tx if a fatal error happened */ + if (txq->state & PDMA_TX_QUEUE_XOFF) { + sal_sem_give(txq->sem); + return SHR_E_RESOURCE; + } + } + + /* Setup the new descriptor */ + curr = txq->curr; + pbuf = &txq->pbuf[curr]; + if (dev->mode == DEV_MODE_HNET && !buf) { + rv = cmicd_pdma_tx_vring_fetch(hw, txq, pbuf); + if (SHR_FAILURE(rv)) { + sal_spinlock_unlock(txq->mutex); + return SHR_E_EMPTY; + } + } else { + pbuf->adj = 0; + pkh = bm->tx_buf_get(dev, txq, pbuf, buf); + if (!pkh) { + txq->stats.dropped++; + if (dev->tx_suspend) { + sal_spinlock_unlock(txq->mutex); + } else { + sal_sem_give(txq->sem); + } + return SHR_E_NONE; + } + bm->tx_buf_dma(dev, txq, pbuf, &addr); + flags |= pkh->attrs & PDMA_TX_HIGIG_PKT ? CMICD_DESC_TX_HIGIG_PKT : 0; + flags |= pkh->attrs & PDMA_TX_PAUSE_PKT ? CMICD_DESC_TX_PAUSE_PKT : 0; + flags |= pkh->attrs & PDMA_TX_PURGE_PKT ? CMICD_DESC_TX_PURGE_PKT : 0; + cmicd_tx_desc_config(&ring[curr], addr, pbuf->len, flags); + if (pkh->meta_len) { + sal_memcpy(&ring[curr].md, &pbuf->pkb->data, sizeof(ring->md.data)); + } + } + + /* Notify HNET to process if needed */ + if (dev->mode == DEV_MODE_VNET) { + MEMORY_BARRIER; + if (!CMICD_DESC_CTRL_LEN(ring[(curr + txq->nb_desc - 1) % txq->nb_desc].ctrl)) { + dev->xnet_wake(dev); + } + } + + /* Update the indicators */ + curr = (curr + 1) % txq->nb_desc; + txq->curr = curr; + + /* Start DMA if in chain mode */ + if (dev->flags & PDMA_CHAIN_MODE) { + if (txq->state & PDMA_TX_QUEUE_POLL) { + do { + rv = cmicd_pdma_tx_ring_clean(hw, txq, txq->nb_desc - 1); + if (rv != (int)txq->nb_desc - 1) { + break; + } + sal_usleep(1); + } while (retry--); + if (retry <= 0) { + CNET_PR("Last Tx could not be done in given time\n"); + } + } + sal_spinlock_lock(txq->lock); + if (txq->dirt == txq->halt && txq->dirt != curr) { + hw->hdls.chan_stop(hw, txq->chan_id); + cmicd_tx_desc_chain(&ring[(curr + txq->nb_desc - 1) % txq->nb_desc], 0); + hw->hdls.chan_setup(hw, txq->chan_id, + txq->ring_addr + sizeof(struct cmicd_tx_desc) * txq->halt); + hw->hdls.chan_start(hw, txq->chan_id); + txq->halt = curr; + } + sal_spinlock_unlock(txq->lock); + } + + /* Kick off DMA */ + txq->halt_addr = txq->ring_addr + sizeof(struct cmicd_tx_desc) * curr; + hw->hdls.chan_goto(hw, txq->chan_id, txq->halt_addr); + + /* Count the packets/bytes */ + txq->stats.packets++; + txq->stats.bytes += pbuf->len; + + /* Clean up ring if in polling mode */ + if (txq->state & PDMA_TX_QUEUE_POLL && + cmicd_pdma_tx_ring_unused(txq) <= (int)txq->free_thresh) { + cmicd_pdma_tx_ring_clean(hw, txq, txq->nb_desc - txq->free_thresh); + } + + /* Suspend Tx if no resource */ + rv = cmicd_pdma_tx_ring_check(hw, txq); + if (SHR_FAILURE(rv)) { + if (dev->mode == DEV_MODE_VNET) { + dev->xnet_wake(dev); + } + + if (txq->state & PDMA_TX_QUEUE_POLL) { + /* In polling mode, must wait till the ring is available */ + do { + cmicd_pdma_tx_ring_clean(hw, txq, txq->free_thresh); + if (!(txq->state & PDMA_TX_QUEUE_XOFF)) { + break; + } + sal_usleep(1); + } while (retry--); + if (retry <= 0) { + CNET_PR("Fatal error: Tx ring is full, packets have not been transmitted for 5 seconds\n"); + if (!dev->tx_suspend) { + sal_sem_give(txq->sem); + return SHR_E_RESOURCE; + } + } + } else { + /* In interrupt mode, the handle thread will wake up Tx */ + if (!dev->tx_suspend) { + return SHR_E_NONE; + } + } + } + + if (dev->tx_suspend) { + sal_spinlock_unlock(txq->mutex); + } else { + sal_sem_give(txq->sem); + } + + return SHR_E_NONE; +} + +/*! + * Suspend Rx queue + */ +static int +cmicd_pdma_rx_suspend(struct pdma_hw *hw, struct pdma_rx_queue *rxq) +{ + sal_spinlock_lock(rxq->lock); + rxq->state |= PDMA_RX_QUEUE_XOFF; + if (hw->dev->flags & PDMA_CHAIN_MODE) { + hw->hdls.chan_stop(hw, rxq->chan_id); + } + sal_spinlock_unlock(rxq->lock); + + return SHR_E_NONE; +} + +/*! + * Resume Rx queue + */ +static int +cmicd_pdma_rx_resume(struct pdma_hw *hw, struct pdma_rx_queue *rxq) +{ + sal_spinlock_lock(rxq->lock); + if (!(rxq->state & PDMA_RX_QUEUE_XOFF)) { + sal_spinlock_unlock(rxq->lock); + return SHR_E_NONE; + } + if (rxq->state & PDMA_RX_BATCH_REFILL) { + rxq->halt_addr = rxq->ring_addr + sizeof(struct cmicd_rx_desc) * rxq->halt; + hw->hdls.chan_goto(hw, rxq->chan_id, rxq->halt_addr); + } else if (rxq->halt == rxq->curr || (rxq->halt == rxq->nb_desc && rxq->curr == 0)) { + rxq->halt = (rxq->curr + 1) % rxq->nb_desc; + rxq->halt_addr = rxq->ring_addr + sizeof(struct cmicd_rx_desc) * rxq->halt; + hw->hdls.chan_goto(hw, rxq->chan_id, rxq->halt_addr); + } + if (hw->dev->flags & PDMA_CHAIN_MODE) { + rxq->curr = 0; + hw->hdls.chan_start(hw, rxq->chan_id); + } + rxq->state &= ~PDMA_RX_QUEUE_XOFF; + sal_spinlock_unlock(rxq->lock); + + return SHR_E_NONE; +} + +/*! + * Initialize function pointers + */ +int +bcmcnet_cmicd_pdma_desc_ops_init(struct pdma_hw *hw) +{ + if (!hw) { + return SHR_E_PARAM; + } + + hw->dops.rx_desc_init = cmicd_pdma_rx_desc_init; + hw->dops.rx_desc_clean = cmicd_pdma_rx_desc_clean; + hw->dops.rx_ring_clean = cmicd_pdma_rx_ring_clean; + hw->dops.rx_ring_dump = cmicd_pdma_rx_ring_dump; + hw->dops.rx_suspend = cmicd_pdma_rx_suspend; + hw->dops.rx_resume = cmicd_pdma_rx_resume; + hw->dops.tx_desc_init = cmicd_pdma_tx_desc_init; + hw->dops.tx_desc_clean = cmicd_pdma_tx_desc_clean; + hw->dops.tx_ring_clean = cmicd_pdma_tx_ring_clean; + hw->dops.tx_ring_dump = cmicd_pdma_tx_ring_dump; + hw->dops.pkt_xmit = cmicd_pdma_pkt_xmit; + + return SHR_E_NONE; +} + +/*! + * Attach device driver + */ +int +bcmcnet_cmicd_pdma_driver_attach(struct pdma_dev *dev) +{ + struct pdma_hw *hw = NULL; + + /* Allocate memory for HW data */ + hw = sal_alloc(sizeof(*hw), "bcmcnetPdmaHw"); + if (!hw) { + return SHR_E_MEMORY; + } + sal_memset(hw, 0, sizeof(*hw)); + hw->unit = dev->unit; + hw->dev = dev; + dev->ctrl.hw = hw; + + bcmcnet_cmicd_pdma_hw_hdls_init(hw); + bcmcnet_cmicd_pdma_desc_ops_init(hw); + + return SHR_E_NONE; +} + +/*! + * Detach device driver + */ +int +bcmcnet_cmicd_pdma_driver_detach(struct pdma_dev *dev) +{ + if (dev->ctrl.hw) { + sal_free(dev->ctrl.hw); + } + dev->ctrl.hw = NULL; + + return SHR_E_NONE; +} + diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/hmi/cmicx/bcmcnet_cmicx_pdma_hw.c b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/hmi/cmicx/bcmcnet_cmicx_pdma_hw.c new file mode 100644 index 000000000000..6dc77c4b7c04 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/hmi/cmicx/bcmcnet_cmicx_pdma_hw.c @@ -0,0 +1,604 @@ +/*! \file bcmcnet_cmicx_pdma_hw.c + * + * Utility routines for handling BCMCNET hardware (CMICx). + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include +#include +#include +#include + +/*! + * Read 32-bit register + */ +static inline void +cmicx_pdma_reg_read32(struct pdma_hw *hw, uint32_t addr, uint32_t *data) +{ + if (hw->dev->dev_read32) { + hw->dev->dev_read32(hw->dev, addr, data); + } else { + DEV_READ32(&hw->dev->ctrl, addr, data); + } +} + +/*! + * Write 32-bit register + */ +static inline void +cmicx_pdma_reg_write32(struct pdma_hw *hw, uint32_t addr, uint32_t data) +{ + if (hw->dev->dev_write32) { + hw->dev->dev_write32(hw->dev, addr, data); + } else { + DEV_WRITE32(&hw->dev->ctrl, addr, data); + } +} + +/*! + * Enable interrupt for a channel + */ +static inline void +cmicx_pdma_intr_enable(struct pdma_hw *hw, int cmc, int chan, uint32_t mask) +{ + uint32_t reg, irq_mask; + + hw->dev->ctrl.grp[cmc].irq_mask |= mask; + irq_mask = hw->dev->ctrl.grp[cmc].irq_mask; + if (cmc == 0) { + reg = CMICX_PDMA_IRQ_RAW_STAT0; + } else { + if (chan < 4) { + reg = CMICX_PDMA_IRQ_RAW_STAT1; + hw->dev->ctrl.grp[cmc].irq_mask <<= CMICX_IRQ_MASK_SHIFT; + } else { + reg = CMICX_PDMA_IRQ_RAW_STAT2; + hw->dev->ctrl.grp[cmc].irq_mask >>= 32 - CMICX_IRQ_MASK_SHIFT; + } + } + + hw->dev->intr_unmask(hw->dev, cmc, chan, reg & 0xfff, 0); + hw->dev->ctrl.grp[cmc].irq_mask = irq_mask; +} + +/*! + * Disable interrupt for a channel + */ +static inline void +cmicx_pdma_intr_disable(struct pdma_hw *hw, int cmc, int chan, uint32_t mask) +{ + uint32_t reg, irq_mask; + + hw->dev->ctrl.grp[cmc].irq_mask &= ~mask; + irq_mask = hw->dev->ctrl.grp[cmc].irq_mask; + if (cmc == 0) { + reg = CMICX_PDMA_IRQ_RAW_STAT0; + } else { + if (chan < 4) { + reg = CMICX_PDMA_IRQ_RAW_STAT1; + hw->dev->ctrl.grp[cmc].irq_mask <<= CMICX_IRQ_MASK_SHIFT; + } else { + reg = CMICX_PDMA_IRQ_RAW_STAT2; + hw->dev->ctrl.grp[cmc].irq_mask >>= 32 - CMICX_IRQ_MASK_SHIFT; + } + } + + hw->dev->intr_mask(hw->dev, cmc, chan, reg & 0xfff, 0); + hw->dev->ctrl.grp[cmc].irq_mask = irq_mask; +} + +/*! + * Release Packet DMA credits to EP. + */ +static int +cmicx_pdma_credits_release(struct pdma_hw *hw) +{ + int credits; + uint32_t val; + + /* + * Since only 6 bits of iproc_cmic_to_ep_credits[5:0] are being used, + * so we have to set the max credits value twice in order to release + * 64 credits to EP. + * Only do this once when HW is initialized. + */ + hw->hdls.reg_rd32(hw, CMICX_EPINTF_RELEASE_CREDITS, &val); + if (!val) { + credits = 63; + hw->hdls.reg_wr32(hw, CMICX_EPINTF_MAX_CREDITS, (0x1 << 8) | credits); + hw->hdls.reg_wr32(hw, CMICX_EPINTF_RELEASE_CREDITS, 1); + + hw->hdls.reg_wr32(hw, CMICX_EPINTF_RELEASE_CREDITS, 0); + credits = 1; + hw->hdls.reg_wr32(hw, CMICX_EPINTF_MAX_CREDITS, (0x1 << 8) | credits); + hw->hdls.reg_wr32(hw, CMICX_EPINTF_RELEASE_CREDITS, 1); + } + + return SHR_E_NONE; +} + +/*! + * Initialize HW + */ +static int +cmicx_pdma_hw_init(struct pdma_hw *hw) +{ + dev_mode_t mode = DEV_MODE_MAX; + uint32_t val; + + /* Temporarily upgrade work mode to get HW information in VNET mode. */ + if (hw->dev->mode == DEV_MODE_VNET) { + mode = DEV_MODE_VNET; + hw->dev->mode = DEV_MODE_UNET; + } + + /* Release Packet DMA credits to EP. */ + cmicx_pdma_credits_release(hw); + + hw->info.name = CMICX_DEV_NAME; + hw->info.dev_id = hw->dev->dev_id; + hw->info.num_cmcs = CMICX_PDMA_CMC_MAX; + hw->info.cmc_chans = CMICX_PDMA_CMC_CHAN; + hw->info.num_chans = CMICX_PDMA_CMC_MAX * CMICX_PDMA_CMC_CHAN; + hw->info.rx_dcb_size = CMICX_PDMA_DCB_SIZE; + hw->info.tx_dcb_size = CMICX_PDMA_DCB_SIZE; + hw->hdls.reg_rd32(hw, CMICX_EP_TO_CPU_HEADER_SIZE, &val); + hw->info.rx_ph_size = (val & 0xf) * 8; + hw->info.tx_ph_size = CMICX_TX_PKT_HDR_SIZE; + + /* Restore work mode to VNET. */ + if (mode == DEV_MODE_VNET) { + hw->dev->mode = DEV_MODE_VNET; + } + + return SHR_E_NONE; +} + +/*! + * Configure HW + */ +static int +cmicx_pdma_hw_config(struct pdma_hw *hw) +{ + struct dev_ctrl *ctrl = &hw->dev->ctrl; + struct pdma_rx_queue *rxq = NULL; + struct pdma_tx_queue *txq = NULL; + uint32_t val, que_ctrl; + int grp, que; + uint32_t qi; + int ip_if_hdr_endian = 0; + + for (qi = 0; qi < ctrl->nb_rxq; qi++) { + rxq = (struct pdma_rx_queue *)ctrl->rx_queue[qi]; + grp = rxq->group_id; + que = rxq->chan_id % CMICX_PDMA_CMC_CHAN; + que_ctrl = ctrl->grp[grp].que_ctrl[que]; + + hw->hdls.reg_wr32(hw, CMICX_PDMA_IRQ_STAT_CLR(grp), CMICX_PDMA_IRQ_MASK(que)); + val = 0; + if (que_ctrl & PDMA_PKT_BYTE_SWAP) { + val |= CMICX_PDMA_PKT_BIG_ENDIAN; + } + if (que_ctrl & PDMA_OTH_BYTE_SWAP) { + val |= CMICX_PDMA_DESC_BIG_ENDIAN; + } + if (que_ctrl & PDMA_HDR_BYTE_SWAP) { + val |= CMICX_PDMA_HDR_BIG_ENDIAN; + } + if (!(hw->dev->flags & PDMA_CHAIN_MODE)) { + val |= CMICX_PDMA_CONTINUOUS; + } + if (hw->dev->flags & PDMA_DESC_PREFETCH) { + val |= CMICX_PDMA_CONTINUOUS_DESC; + } + val |= CMICX_PDMA_INTR_ON_DESC; + hw->hdls.reg_wr32(hw, CMICX_PDMA_CTRL(grp, que), val); + } + + for (qi = 0; qi < ctrl->nb_txq; qi++) { + txq = (struct pdma_tx_queue *)ctrl->tx_queue[qi]; + grp = txq->group_id; + que = txq->chan_id % CMICX_PDMA_CMC_CHAN; + que_ctrl = ctrl->grp[grp].que_ctrl[que]; + + hw->hdls.reg_wr32(hw, CMICX_PDMA_IRQ_STAT_CLR(grp), CMICX_PDMA_IRQ_MASK(que)); + val = 0; + if (que_ctrl & PDMA_PKT_BYTE_SWAP) { + val |= CMICX_PDMA_PKT_BIG_ENDIAN; + val |= CMICX_PDMA_HDR_BIG_ENDIAN; + ip_if_hdr_endian = 1; + } + if (que_ctrl & PDMA_OTH_BYTE_SWAP) { + val |= CMICX_PDMA_DESC_BIG_ENDIAN; + } + if (que_ctrl & PDMA_HDR_BYTE_SWAP) { + ip_if_hdr_endian = 1; + } + if (!(hw->dev->flags & PDMA_CHAIN_MODE)) { + val |= CMICX_PDMA_CONTINUOUS; + } + if (hw->dev->flags & PDMA_DESC_PREFETCH) { + val |= CMICX_PDMA_CONTINUOUS_DESC; + } + val |= CMICX_PDMA_INTR_ON_DESC | CMICX_PDMA_DIR; + hw->hdls.reg_wr32(hw, CMICX_PDMA_CTRL(grp, que), val); + } + + if (ip_if_hdr_endian == 1) { + hw->hdls.reg_rd32(hw, CMICX_TOP_CONFIG, &val); + val |= 0x80; + hw->hdls.reg_wr32(hw, CMICX_TOP_CONFIG, val); + } + + return SHR_E_NONE; +} + +/*! + * Reset HW + */ +static int +cmicx_pdma_hw_reset(struct pdma_hw *hw) +{ + int gi, qi; + + for (gi = 0; gi < hw->dev->num_groups; gi++) { + if (!hw->dev->ctrl.grp[gi].attached) { + continue; + } + for (qi = 0; qi < CMICX_PDMA_CMC_CHAN; qi++) { + if (1 << qi & hw->dev->ctrl.grp[gi].bm_rxq || + 1 << qi & hw->dev->ctrl.grp[gi].bm_txq) { + hw->hdls.reg_wr32(hw, CMICX_PDMA_CTRL(gi, qi), 0); + } + } + } + + return SHR_E_NONE; +} + +/*! + * Start a channel + */ +static int +cmicx_pdma_chan_start(struct pdma_hw *hw, int chan) +{ + uint32_t val; + int grp, que; + + grp = chan / CMICX_PDMA_CMC_CHAN; + que = chan % CMICX_PDMA_CMC_CHAN; + + hw->hdls.reg_rd32(hw, CMICX_PDMA_CTRL(grp, que), &val); + val |= CMICX_PDMA_ENABLE; + hw->hdls.reg_wr32(hw, CMICX_PDMA_CTRL(grp, que), val); + + MEMORY_BARRIER; + + return SHR_E_NONE; +} + +/*! + * Stop a channel + */ +static int +cmicx_pdma_chan_stop(struct pdma_hw *hw, int chan) +{ + uint32_t val; + int grp, que; + int retry = CMICX_HW_RETRY_TIMES; + + grp = chan / CMICX_PDMA_CMC_CHAN; + que = chan % CMICX_PDMA_CMC_CHAN; + + hw->hdls.reg_rd32(hw, CMICX_PDMA_CTRL(grp, que), &val); + val |= CMICX_PDMA_ENABLE | CMICX_PDMA_ABORT; + hw->hdls.reg_wr32(hw, CMICX_PDMA_CTRL(grp, que), val); + + MEMORY_BARRIER; + + do { + val = ~CMICX_PDMA_IS_ACTIVE; + hw->hdls.reg_rd32(hw, CMICX_PDMA_STAT(grp, que), &val); + } while ((val & CMICX_PDMA_IS_ACTIVE) && (--retry > 0)); + + hw->hdls.reg_rd32(hw, CMICX_PDMA_CTRL(grp, que), &val); + val &= ~(CMICX_PDMA_ENABLE | CMICX_PDMA_ABORT); + hw->hdls.reg_wr32(hw, CMICX_PDMA_CTRL(grp, que), val); + + hw->hdls.reg_wr32(hw, CMICX_PDMA_IRQ_STAT_CLR(grp), CMICX_PDMA_IRQ_MASK(que)); + + MEMORY_BARRIER; + + return SHR_E_NONE; +} + +/*! + * Setup a channel + */ +static int +cmicx_pdma_chan_setup(struct pdma_hw *hw, int chan, uint64_t addr) +{ + int grp, que; + + grp = chan / CMICX_PDMA_CMC_CHAN; + que = chan % CMICX_PDMA_CMC_CHAN; + + hw->hdls.reg_wr32(hw, CMICX_PDMA_DESC_LO(grp, que), addr); + hw->hdls.reg_wr32(hw, CMICX_PDMA_DESC_HI(grp, que), DMA_TO_BUS_HI(addr >> 32)); + + MEMORY_BARRIER; + + return SHR_E_NONE; +} + +/*! + * Set halt point for a channel + */ +static int +cmicx_pdma_chan_goto(struct pdma_hw *hw, int chan, uint64_t addr) +{ + int grp, que; + + grp = chan / CMICX_PDMA_CMC_CHAN; + que = chan % CMICX_PDMA_CMC_CHAN; + + hw->hdls.reg_wr32(hw, CMICX_PDMA_DESC_HALT_LO(grp, que), addr); + hw->hdls.reg_wr32(hw, CMICX_PDMA_DESC_HALT_HI(grp, que), DMA_TO_BUS_HI(addr >> 32)); + + MEMORY_BARRIER; + + return SHR_E_NONE; +} + +/*! + * Clear a channel + */ +static int +cmicx_pdma_chan_clear(struct pdma_hw *hw, int chan) +{ + int grp, que; + + grp = chan / CMICX_PDMA_CMC_CHAN; + que = chan % CMICX_PDMA_CMC_CHAN; + + hw->hdls.reg_wr32(hw, CMICX_PDMA_IRQ_STAT_CLR(grp), CMICX_PDMA_IRQ_CTRLD_INTR(que)); + + MEMORY_BARRIER; + + return SHR_E_NONE; +} + +/*! + * Get interrupt number for a channel + */ +static int +cmicx_pdma_chan_intr_num_get(struct pdma_hw *hw, int chan) +{ + int grp, que, start_num, mask_shift; + + grp = chan / CMICX_PDMA_CMC_CHAN; + que = chan % CMICX_PDMA_CMC_CHAN; + + mask_shift = 0; + if (grp > 0) { + mask_shift = CMICX_IRQ_MASK_SHIFT + grp * 32; + } + start_num = CMICX_IRQ_START_NUM + mask_shift; + + return start_num + (que * CMICX_IRQ_NUM_OFFSET); +} + +/*! + * Enable interrupt for a channel + */ +static int +cmicx_pdma_chan_intr_enable(struct pdma_hw *hw, int chan) +{ + int grp, que; + + grp = chan / CMICX_PDMA_CMC_CHAN; + que = chan % CMICX_PDMA_CMC_CHAN; + + cmicx_pdma_intr_enable(hw, grp, que, CMICX_PDMA_IRQ_CTRLD_INTR(que)); + + return SHR_E_NONE; +} + +/*! + * Disable interrupt for a channel + */ +static int +cmicx_pdma_chan_intr_disable(struct pdma_hw *hw, int chan) +{ + int grp, que; + + grp = chan / CMICX_PDMA_CMC_CHAN; + que = chan % CMICX_PDMA_CMC_CHAN; + + cmicx_pdma_intr_disable(hw, grp, que, CMICX_PDMA_IRQ_CTRLD_INTR(que)); + + return SHR_E_NONE; +} + +/*! + * Query interrupt status for a channel + * + * In group mode (interrupt processing per CMC), need to query each channel's + * interrupt status. + * + */ +static int +cmicx_pdma_chan_intr_query(struct pdma_hw *hw, int chan) +{ + uint32_t val; + int grp, que; + + grp = chan / CMICX_PDMA_CMC_CHAN; + que = chan % CMICX_PDMA_CMC_CHAN; + + hw->hdls.reg_rd32(hw, CMICX_PDMA_IRQ_STAT(grp), &val); + + return val & CMICX_PDMA_IRQ_CTRLD_INTR(que); +} + +/*! + * Check interrupt validity for a channel + * + * In group mode (interrupt processing per CMC), need to check each channel's + * interrupt validity based on its interrupt mask. + * + */ +static int +cmicx_pdma_chan_intr_check(struct pdma_hw *hw, int chan) +{ + int grp, que; + + grp = chan / CMICX_PDMA_CMC_CHAN; + que = chan % CMICX_PDMA_CMC_CHAN; + + if (!(hw->dev->ctrl.grp[grp].irq_mask & CMICX_PDMA_IRQ_CTRLD_INTR(que))) { + return 0; + } + + return cmicx_pdma_chan_intr_query(hw, chan); +} + +/*! + * Coalesce interrupt for a channel + */ +static int +cmicx_pdma_chan_intr_coalesce(struct pdma_hw *hw, int chan, int count, int timer) +{ + uint32_t val; + int grp, que; + + grp = chan / CMICX_PDMA_CMC_CHAN; + que = chan % CMICX_PDMA_CMC_CHAN; + + val = CMICX_PDMA_INTR_COAL_ENA | + CMICX_PDMA_INTR_THRESH(count) | + CMICX_PDMA_INTR_TIMER(timer); + hw->hdls.reg_wr32(hw, CMICX_PDMA_INTR_COAL(grp, que), val); + + return SHR_E_NONE; +} + +/*! + * Dump registers for a channel + */ +static int +cmicx_pdma_chan_reg_dump(struct pdma_hw *hw, int chan) +{ + uint32_t val; + int grp, que; + + grp = chan / CMICX_PDMA_CMC_CHAN; + que = chan % CMICX_PDMA_CMC_CHAN; + + hw->hdls.reg_rd32(hw, CMICX_PDMA_CTRL(grp, que), &val); + CNET_PR("CMIC_CMC%d_DMA_CH%d_CTRL: 0x%08x\n", grp, que, val); + + hw->hdls.reg_rd32(hw, CMICX_PDMA_DESC_LO(grp, que), &val); + CNET_PR("CMIC_CMC%d_DMA_CH%d_DESC_LO: 0x%08x\n", grp, que, val); + + hw->hdls.reg_rd32(hw, CMICX_PDMA_DESC_HI(grp, que), &val); + CNET_PR("CMIC_CMC%d_DMA_CH%d_DESC_HI: 0x%08x\n", grp, que, val); + + hw->hdls.reg_rd32(hw, CMICX_PDMA_CURR_DESC_LO(grp, que), &val); + CNET_PR("CMIC_CMC%d_DMA_CH%d_CURR_DESC_LO: 0x%08x\n", grp, que, val); + + hw->hdls.reg_rd32(hw, CMICX_PDMA_CURR_DESC_HI(grp, que), &val); + CNET_PR("CMIC_CMC%d_DMA_CH%d_CURR_DESC_HI: 0x%08x\n", grp, que, val); + + hw->hdls.reg_rd32(hw, CMICX_PDMA_DESC_HALT_LO(grp, que), &val); + CNET_PR("CMIC_CMC%d_DMA_CH%d_DESC_HALT_ADDR_LO: 0x%08x\n", grp, que, val); + + hw->hdls.reg_rd32(hw, CMICX_PDMA_DESC_HALT_HI(grp, que), &val); + CNET_PR("CMIC_CMC%d_DMA_CH%d_DESC_HALT_ADDR_HI: 0x%08x\n", grp, que, val); + + hw->hdls.reg_rd32(hw, CMICX_PDMA_COS_CTRL_RX0(grp, que), &val); + CNET_PR("CMIC_CMC%d_DMA_CH%d_COS_CTRL_RX_0: 0x%08x\n", grp, que, val); + + hw->hdls.reg_rd32(hw, CMICX_PDMA_COS_CTRL_RX1(grp, que), &val); + CNET_PR("CMIC_CMC%d_DMA_CH%d_COS_CTRL_RX_1: 0x%08x\n", grp, que, val); + + hw->hdls.reg_rd32(hw, CMICX_PDMA_INTR_COAL(grp, que), &val); + CNET_PR("CMIC_CMC%d_DMA_CH%d_INTR_COAL: 0x%08x\n", grp, que, val); + + hw->hdls.reg_rd32(hw, CMICX_PDMA_RBUF_THRE(grp, que), &val); + CNET_PR("CMIC_CMC%d_DMA_CH%d_RXBUF_THRESHOLD_CONFIG: 0x%08x\n", grp, que, val); + + hw->hdls.reg_rd32(hw, CMICX_PDMA_STAT(grp, que), &val); + CNET_PR("CMIC_CMC%d_DMA_CH%d_STAT: 0x%08x\n", grp, que, val); + + hw->hdls.reg_rd32(hw, CMICX_PDMA_COUNT_RX(grp, que), &val); + CNET_PR("CMIC_CMC%d_DMA_CH%d_PKT_COUNT_RXPKT: 0x%08x\n", grp, que, val); + + hw->hdls.reg_rd32(hw, CMICX_PDMA_COUNT_TX(grp, que), &val); + CNET_PR("CMIC_CMC%d_DMA_CH%d_PKT_COUNT_TXPKT: 0x%08x\n", grp, que, val); + + hw->hdls.reg_rd32(hw, CMICX_PDMA_COUNT_RX_DROP(grp, que), &val); + CNET_PR("CMIC_CMC%d_DMA_CH%d_PKT_COUNT_RXPKT_DROP: 0x%08x\n", grp, que, val); + + hw->hdls.reg_rd32(hw, CMICX_PDMA_IRQ_STAT(grp), &val); + CNET_PR("CMIC_CMC%d_IRQ_STAT: 0x%08x\n", grp, val); + + hw->hdls.reg_rd32(hw, CMICX_PDMA_IRQ_STAT_CLR(grp), &val); + CNET_PR("CMIC_CMC%d_IRQ_STAT_CLR: 0x%08x\n", grp, val); + + val = hw->dev->ctrl.grp[grp].irq_mask; + CNET_PR("CMIC_CMC%d_IRQ_ENAB: 0x%08x\n", grp, val); + + hw->hdls.reg_rd32(hw, CMICX_EP_TO_CPU_HEADER_SIZE, &val); + CNET_PR("CMIC_EP_TO_CPU_HEADER_SIZE: 0x%08x\n", val); + + return SHR_E_NONE; +} + +/*! + * Initialize function pointers + */ +int +bcmcnet_cmicx_pdma_hw_hdls_init(struct pdma_hw *hw) +{ + if (!hw) { + return SHR_E_PARAM; + } + + hw->hdls.reg_rd32 = cmicx_pdma_reg_read32; + hw->hdls.reg_wr32 = cmicx_pdma_reg_write32; + hw->hdls.hw_init = cmicx_pdma_hw_init; + hw->hdls.hw_config = cmicx_pdma_hw_config; + hw->hdls.hw_reset = cmicx_pdma_hw_reset; + hw->hdls.chan_start = cmicx_pdma_chan_start; + hw->hdls.chan_stop = cmicx_pdma_chan_stop; + hw->hdls.chan_setup = cmicx_pdma_chan_setup; + hw->hdls.chan_goto = cmicx_pdma_chan_goto; + hw->hdls.chan_clear = cmicx_pdma_chan_clear; + hw->hdls.chan_intr_num_get = cmicx_pdma_chan_intr_num_get; + hw->hdls.chan_intr_enable = cmicx_pdma_chan_intr_enable; + hw->hdls.chan_intr_disable = cmicx_pdma_chan_intr_disable; + hw->hdls.chan_intr_query = cmicx_pdma_chan_intr_query; + hw->hdls.chan_intr_check = cmicx_pdma_chan_intr_check; + hw->hdls.chan_intr_coalesce = cmicx_pdma_chan_intr_coalesce; + hw->hdls.chan_reg_dump = cmicx_pdma_chan_reg_dump; + + return SHR_E_NONE; +} + diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/hmi/cmicx/bcmcnet_cmicx_pdma_rxtx.c b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/hmi/cmicx/bcmcnet_cmicx_pdma_rxtx.c new file mode 100644 index 000000000000..651728465d56 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/hmi/cmicx/bcmcnet_cmicx_pdma_rxtx.c @@ -0,0 +1,1094 @@ +/*! \file bcmcnet_cmicx_pdma_rxtx.c + * + * Utility routines for BCMCNET hardware (CMICx) specific Rx/Tx. + * + * Here are the CMIC specific Rx/Tx routines including DCBs resource allocation + * and clean up, DCBs configuration, Rx buffers allocation, Tx buffers release, + * Rx/Tx packets processing, etc. + * They are shared among all the modes (UNET, KNET, VNET, HNET) and in both of + * user space and kernel space. + * + * The driver uses a ring of DCBs per DMA channel based on Continuous DMA mode. + * The beginning is written to register pointing to the physical address of the + * start of the ring. The ring size is maintained by the driver. A HALT DCB + * physical address is written to DMA register timely to indicate how many DCBs + * can be handled by HW. + * + * When a packet is received, an interrupt is triggered. The handler will go + * through the Rx DCB ring to process the current completed DCB and every + * subsequent DCBs until no one is left. The received packet is processed and + * passed up to the high level SW. After that, a new buffer is allocated and + * the DCB is updated for receiving a new packet. A new HALT DCB is selected + * and its physical address is written to DMA register. + * + * When a packet is transmitted, the driver starts where it left off last time + * in the Tx DCB ring, updates the DCB and writes its physical address to DMA + * register so as to start DMA. Once the transmitting is finished, the handler + * is informed to clean up the buffer based on the work mode. In KNET or HNET + * mode, an interrupt will be triggered. Polling mode is used in CNET or VNET + * mode, the buffers will be cleaned up when the number of dirty DCBs reaches + * a pre-defined threshold. + * + * In VNET and HNET modes, DCB updating between virtual ring and real ring and + * a IOCTL based notification mechanism are involved. The hypervisor in kernel + * emulates the DMA HW behaviors to update DCBs in virtual network and inform + * the handler something happened. Likewise, the hypervisor updates itself real + * DCB ring from the virtual ring to start DMA for transmitting a packet once a + * notification is received from the virtual network. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include +#include +#include +#include +#include + +/*! + * Configure Rx descriptor + */ +static inline void +cmicx_rx_desc_config(struct cmicx_rx_desc *rd, uint64_t addr, uint32_t len) +{ + uint32_t ctrl; + + rd->addr_lo = addr; + rd->addr_hi = DMA_TO_BUS_HI(addr >> 32); + rd->status = 0; + ctrl = rd->ctrl; + ctrl &= CMICX_DESC_CTRL_REMAIN(0xf); + ctrl |= CMICX_DESC_CTRL_CNTLD_INTR | CMICX_DESC_CTRL_CHAIN | + CMICX_DESC_CTRL_LEN(len); + rd->ctrl = ctrl; +} + +/*! + * Configure Tx descriptor + */ +static inline void +cmicx_tx_desc_config(struct cmicx_tx_desc *td, uint64_t addr, uint32_t len, uint32_t flags) +{ + uint32_t ctrl; + + td->addr_lo = addr; + td->addr_hi = DMA_TO_BUS_HI(addr >> 32); + td->status = 0; + ctrl = td->ctrl; + ctrl &= CMICX_DESC_CTRL_REMAIN(0xf); + ctrl |= CMICX_DESC_CTRL_CNTLD_INTR | CMICX_DESC_CTRL_CHAIN | + CMICX_DESC_CTRL_FLAGS(flags) | CMICX_DESC_CTRL_LEN(len); + td->ctrl = ctrl; +} + +/*! + * Configure Rx reload descriptor + */ +static inline void +cmicx_rx_rldesc_config(struct cmicx_rx_desc *rd, uint64_t addr) +{ + rd->addr_lo = addr; + rd->addr_hi = DMA_TO_BUS_HI(addr >> 32); + rd->status = 0; + rd->ctrl = CMICX_DESC_CTRL_CNTLD_INTR | CMICX_DESC_CTRL_CHAIN | + CMICX_DESC_CTRL_RELOAD; +} + +/*! + * Configure Tx reload descriptor + */ +static inline void +cmicx_tx_rldesc_config(struct cmicx_tx_desc *td, uint64_t addr) +{ + td->addr_lo = addr; + td->addr_hi = DMA_TO_BUS_HI(addr >> 32); + td->status = 0; + td->ctrl = CMICX_DESC_CTRL_CNTLD_INTR | CMICX_DESC_CTRL_CHAIN | + CMICX_DESC_CTRL_RELOAD; +} + +/*! + * Chain Rx descriptor + */ +static inline void +cmicx_rx_desc_chain(struct cmicx_rx_desc *rd, int chain) +{ + if (chain) { + rd->ctrl |= CMICX_DESC_CTRL_CHAIN; + } else { + rd->ctrl &= ~CMICX_DESC_CTRL_CHAIN; + } +} + +/*! + * Chain Tx descriptor + */ +static inline void +cmicx_tx_desc_chain(struct cmicx_tx_desc *td, int chain) +{ + if (chain) { + td->ctrl |= CMICX_DESC_CTRL_CHAIN; + } else { + td->ctrl &= ~CMICX_DESC_CTRL_CHAIN; + } +} + +/*! + * Set Rx descriptor remain + */ +static inline void +cmicx_rx_desc_remain(struct cmicx_rx_desc *rd, uint32_t rm) +{ + rd->ctrl &= ~CMICX_DESC_CTRL_REMAIN(0xf); + rd->ctrl |= CMICX_DESC_CTRL_REMAIN(rm); +} + +/*! + * Set Tx descriptor remain + */ +static inline void +cmicx_tx_desc_remain(struct cmicx_tx_desc *td, uint32_t rm) +{ + td->ctrl &= ~CMICX_DESC_CTRL_REMAIN(0xf); + td->ctrl |= CMICX_DESC_CTRL_REMAIN(rm); +} + +/*! + * Get unused descriptors in a Rx ring + */ +static inline int +cmicx_pdma_rx_ring_unused(struct pdma_rx_queue *rxq) +{ + /* Leave one descriptor unused so as not to halt */ + return rxq->curr > rxq->halt ? + rxq->curr - rxq->halt - 1 : + rxq->nb_desc + rxq->curr - rxq->halt - 1; +} + +/*! + * Get unused descriptors in a Tx ring + */ +static inline int +cmicx_pdma_tx_ring_unused(struct pdma_tx_queue *txq) +{ + /* Leave one descriptor unused so as not to halt */ + return txq->dirt > txq->curr ? + txq->dirt - txq->curr - 1 : + txq->nb_desc + txq->dirt - txq->curr - 1; +} + +/*! + * Initialize Rx descriptors + */ +static int +cmicx_pdma_rx_desc_init(struct pdma_hw *hw, struct pdma_rx_queue *rxq) +{ + struct pdma_dev *dev = hw->dev; + struct pdma_buf_mngr *bm = (struct pdma_buf_mngr *)dev->ctrl.buf_mngr; + struct cmicx_rx_desc *ring = (struct cmicx_rx_desc *)rxq->ring; + dma_addr_t addr; + uint32_t di, rm; + int rv; + + for (di = 0; di < rxq->nb_desc; di++) { + if (!rxq->pbuf[di].dma) { + /* Allocate pktbuf for ring entry */ + rv = bm->rx_buf_alloc(dev, rxq, &rxq->pbuf[di]); + if (SHR_FAILURE(rv)) { + goto cleanup; + } + } + /* Config receive descriptor ring */ + bm->rx_buf_dma(dev, rxq, &rxq->pbuf[di], &addr); + cmicx_rx_desc_config(&ring[di], addr, rxq->buf_size); + rm = (rxq->nb_desc - di) >= CMICX_DESC_REMAIN_MAX ? + CMICX_DESC_REMAIN_MAX : rxq->nb_desc - di; + cmicx_rx_desc_remain(&ring[di], rm); + if (hw->dev->flags & PDMA_CHAIN_MODE && di == rxq->nb_desc - 1) { + cmicx_rx_desc_chain(&ring[di], 0); + } + } + /* Config the last descriptor in the ring as reload descriptor */ + cmicx_rx_rldesc_config(&ring[di], rxq->ring_addr); + + rxq->curr = 0; + rxq->halt = rxq->state & PDMA_RX_BATCH_REFILL ? 0 : rxq->nb_desc; + + rxq->halt_addr = rxq->ring_addr + sizeof(struct cmicx_rx_desc) * di; + hw->hdls.chan_goto(hw, rxq->chan_id, rxq->halt_addr); + hw->hdls.chan_setup(hw, rxq->chan_id, rxq->ring_addr); + + return SHR_E_NONE; + +cleanup: + for (di = 0; di < rxq->nb_desc; di++) { + if (rxq->pbuf[di].dma) { + bm->rx_buf_free(dev, rxq, &rxq->pbuf[di]); + } + cmicx_rx_desc_config(&ring[di], 0, 0); + } + + CNET_PR("RX: Failed to allocate mem\n"); + + return SHR_E_MEMORY; +} + +/*! + * Cleanup Rx descriptors + */ +static int +cmicx_pdma_rx_desc_clean(struct pdma_hw *hw, struct pdma_rx_queue *rxq) +{ + struct pdma_dev *dev = hw->dev; + struct pdma_buf_mngr *bm = (struct pdma_buf_mngr *)dev->ctrl.buf_mngr; + struct cmicx_rx_desc *ring = (struct cmicx_rx_desc *)rxq->ring; + uint32_t di; + + /* Go through all the descriptors and free pktbuf */ + for (di = 0; di < rxq->nb_desc; di++) { + if (rxq->pbuf[di].dma) { + bm->rx_buf_free(dev, rxq, &rxq->pbuf[di]); + } + cmicx_rx_desc_config(&ring[di], 0, 0); + } + + rxq->curr = 0; + rxq->halt = 0; + + return SHR_E_NONE; +} + +/*! + * Initialize Tx descriptors + */ +static int +cmicx_pdma_tx_desc_init(struct pdma_hw *hw, struct pdma_tx_queue *txq) +{ + struct pdma_dev *dev = hw->dev; + struct pdma_buf_mngr *bm = (struct pdma_buf_mngr *)dev->ctrl.buf_mngr; + struct cmicx_tx_desc *ring = (struct cmicx_tx_desc *)txq->ring; + uint32_t di, rm; + + for (di = 0; di < txq->nb_desc; di++) { + if (txq->pbuf[di].dma) { + bm->tx_buf_free(dev, txq, &txq->pbuf[di]); + } + /* Config transmit descriptor ring */ + cmicx_tx_desc_config(&ring[di], 0, 0, 0); + rm = (txq->nb_desc - di) >= CMICX_DESC_REMAIN_MAX ? + CMICX_DESC_REMAIN_MAX : txq->nb_desc - di; + cmicx_tx_desc_remain(&ring[di], rm); + if (hw->dev->flags & PDMA_CHAIN_MODE) { + cmicx_tx_desc_chain(&ring[di], 0); + } + } + /* Config the last descriptor in the ring as reload descriptor */ + cmicx_tx_rldesc_config(&ring[di], txq->ring_addr); + + txq->curr = 0; + txq->dirt = 0; + txq->halt = 0; + + txq->halt_addr = txq->ring_addr; + hw->hdls.chan_goto(hw, txq->chan_id, txq->halt_addr); + hw->hdls.chan_setup(hw, txq->chan_id, txq->ring_addr); + + return SHR_E_NONE; +} + +/*! + * Cleanup Tx descriptors + */ +static int +cmicx_pdma_tx_desc_clean(struct pdma_hw *hw, struct pdma_tx_queue *txq) +{ + struct pdma_dev *dev = hw->dev; + struct pdma_buf_mngr *bm = (struct pdma_buf_mngr *)dev->ctrl.buf_mngr; + struct cmicx_tx_desc *ring = (struct cmicx_tx_desc *)txq->ring; + uint32_t di; + + /* Go through all the descriptors and free pktbuf */ + for (di = 0; di < txq->nb_desc; di++) { + if (txq->pbuf[di].dma) { + bm->tx_buf_free(dev, txq, &txq->pbuf[di]); + } + cmicx_tx_desc_config(&ring[di], 0, 0, 0); + } + + txq->curr = 0; + txq->dirt = 0; + txq->halt = 0; + + return SHR_E_NONE; +} + +/*! + * Process Rx vring + */ +static int +cmicx_pdma_rx_vring_process(struct pdma_hw *hw, struct pdma_rx_queue *rxq, + struct pdma_rx_buf *pbuf) +{ + struct pdma_dev *dev = hw->dev; + struct cmicx_rx_desc *ring = (struct cmicx_rx_desc *)rxq->ring; + struct pdma_rx_queue *vrxq = NULL; + struct cmicx_rx_desc *vring = NULL; + struct pkt_hdr *pkh = &pbuf->pkb->pkh; + uint64_t buf_addr; + + vrxq = (struct pdma_rx_queue *)dev->ctrl.vnet_rxq[rxq->queue_id]; + vring = (struct cmicx_rx_desc *)vrxq->ring; + if (!vring) { + rxq->stats.dropped++; + return SHR_E_UNAVAIL; + } + + if (vring[vrxq->curr].status & CMICX_DESC_STAT_RTX_DONE) { + dev->xnet_wake(dev); + return SHR_E_BUSY; + } + + /* Copy descriptor and packet to vring */ + buf_addr = BUS_TO_DMA_HI(vring[vrxq->curr].addr_hi); + buf_addr = buf_addr << 32 | vring[vrxq->curr].addr_lo; + sal_memcpy(dev->sys_p2v(dev, buf_addr), &pbuf->pkb->data, + pkh->meta_len + pkh->data_len); + vring[vrxq->curr].status = ring[rxq->curr].status; + + MEMORY_BARRIER; + + /* Notify VNET to process if needed */ + if (!vring[(vrxq->curr + vrxq->nb_desc - 1) % vrxq->nb_desc].status) { + dev->xnet_wake(dev); + } + vrxq->curr = (vrxq->curr + 1) % vrxq->nb_desc; + + return SHR_E_NONE; +} + +/*! + * Refill Rx ring + */ +static int +cmicx_pdma_rx_ring_refill(struct pdma_hw *hw, struct pdma_rx_queue *rxq) +{ + struct pdma_dev *dev = hw->dev; + struct pdma_buf_mngr *bm = (struct pdma_buf_mngr *)dev->ctrl.buf_mngr; + struct cmicx_rx_desc *ring = (struct cmicx_rx_desc *)rxq->ring; + struct pdma_rx_buf *pbuf = NULL; + int unused = cmicx_pdma_rx_ring_unused(rxq); + dma_addr_t addr; + uint32_t halt; + int rv; + + for (halt = rxq->halt; halt < rxq->halt + unused; halt++) { + pbuf = &rxq->pbuf[halt % rxq->nb_desc]; + /* Allocate a new pktbuf */ + if (!bm->rx_buf_avail(dev, rxq, pbuf)) { + rv = bm->rx_buf_alloc(dev, rxq, pbuf); + if (SHR_FAILURE(rv)) { + rxq->halt = halt % rxq->nb_desc; + rxq->stats.nomems++; + goto fail; + } + } + /* Setup the new descriptor */ + bm->rx_buf_dma(dev, rxq, pbuf, &addr); + cmicx_rx_desc_config(&ring[halt % rxq->nb_desc], addr, rxq->buf_size); + if (dev->flags & PDMA_CHAIN_MODE && halt % rxq->nb_desc == rxq->nb_desc - 1) { + cmicx_rx_desc_chain(&ring[halt % rxq->nb_desc], 0); + } + } + + sal_spinlock_lock(rxq->lock); + rxq->halt = halt % rxq->nb_desc; + if (!(rxq->state & PDMA_RX_QUEUE_XOFF)) { + /* Descriptor cherry pick */ + rxq->halt_addr = rxq->ring_addr + sizeof(struct cmicx_rx_desc) * rxq->halt; + hw->hdls.chan_goto(hw, rxq->chan_id, rxq->halt_addr); + } + sal_spinlock_unlock(rxq->lock); + + return SHR_E_NONE; + +fail: + CNET_PR("RX: Failed to allocate mem\n"); + + return SHR_E_MEMORY; +} + +/*! + * \brief Clean Rx ring + * + * \param [in] hw HW structure point. + * \param [in] rxq Rx queue structure point. + * \param [in] budget Polling budget. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +static int +cmicx_pdma_rx_ring_clean(struct pdma_hw *hw, struct pdma_rx_queue *rxq, int budget) +{ + struct pdma_dev *dev = hw->dev; + struct pdma_buf_mngr *bm = (struct pdma_buf_mngr *)dev->ctrl.buf_mngr; + struct cmicx_rx_desc *ring = (struct cmicx_rx_desc *)rxq->ring; + struct pdma_rx_buf *pbuf = NULL; + struct pkt_hdr *pkh = NULL; + dma_addr_t addr; + uint32_t stat, curr; + int len, done = 0; + int rv; + + curr = rxq->curr; + while (CMICX_DESC_STAT_DONE(ring[curr].status)) { + if (dev->mode == DEV_MODE_VNET && rxq->state & PDMA_RX_QUEUE_XOFF) { + break; + } + if (!(rxq->state & PDMA_RX_BATCH_REFILL) && + !(rxq->state & PDMA_RX_QUEUE_XOFF)) { + /* Descriptor cherry pick */ + rxq->halt_addr = rxq->ring_addr + sizeof(struct cmicx_rx_desc) * curr; + hw->hdls.chan_goto(hw, rxq->chan_id, rxq->halt_addr); + rxq->halt = curr; + } + if (done == budget) { + break; + } + + /* Get the current pktbuf to process */ + pbuf = &rxq->pbuf[curr]; + stat = ring[curr].status; + len = CMICX_DESC_STAT_LEN(stat); + pkh = bm->rx_buf_get(dev, rxq, pbuf, len); + if (!pkh) { + rxq->stats.nomems++; + goto fail; + } + + /* Setup packet header */ + pkh->data_len = len - hw->info.rx_ph_size; + pkh->meta_len = hw->info.rx_ph_size; + pkh->queue_id = rxq->queue_id; + pkh->attrs = CMICX_DESC_STAT_FLAGS(stat); + + /* Send up the packet */ + rv = dev->pkt_recv(dev, rxq->queue_id, (void *)pbuf->skb); + if (SHR_FAILURE(rv)) { + if (dev->mode == DEV_MODE_HNET && pkh->attrs & PDMA_RX_TO_VNET) { + rv = cmicx_pdma_rx_vring_process(hw, rxq, pbuf); + if (SHR_FAILURE(rv) && rv == SHR_E_BUSY) { + rxq->state |= PDMA_RX_QUEUE_BUSY; + return done; + } + } else { + rxq->stats.dropped++; + } + bm->rx_buf_put(dev, rxq, pbuf, len); + } + + /* Count the packets/bytes */ + rxq->stats.packets++; + rxq->stats.bytes += len; + + /* Count the errors if any */ + if (stat & CMICX_DESC_STAT_ERR_MASK) { + rxq->stats.errors++; + if (stat & CMICX_DESC_STAT_DATA_ERR) { + rxq->stats.data_errors++; + } + if (stat & CMICX_DESC_STAT_CELL_ERR) { + rxq->stats.cell_errors++; + } + } + + /* Setup the new descriptor */ + if (!(rxq->state & PDMA_RX_BATCH_REFILL)) { + if (!bm->rx_buf_avail(dev, rxq, pbuf)) { + rv = bm->rx_buf_alloc(dev, rxq, pbuf); + if (SHR_FAILURE(rv)) { + rxq->stats.nomems++; + goto fail; + } + } + bm->rx_buf_dma(dev, rxq, pbuf, &addr); + cmicx_rx_desc_config(&ring[curr], addr, rxq->buf_size); + if (dev->flags & PDMA_CHAIN_MODE && curr == rxq->nb_desc - 1) { + cmicx_rx_desc_chain(&ring[curr], 0); + } + } else { + cmicx_rx_desc_config(&ring[curr], 0, 0); + } + + /* Notify HNET to process if needed */ + if (dev->mode == DEV_MODE_VNET) { + MEMORY_BARRIER; + if (ring[(curr + rxq->nb_desc - 1) % rxq->nb_desc].status) { + dev->xnet_wake(dev); + } + } + + /* Update the indicators */ + if (!(rxq->state & PDMA_RX_BATCH_REFILL) && rxq->halt != curr) { + sal_spinlock_lock(rxq->lock); + if (!(rxq->state & PDMA_RX_QUEUE_XOFF)) { + /* Descriptor cherry pick */ + rxq->halt_addr = rxq->ring_addr + sizeof(struct cmicx_rx_desc) * curr; + hw->hdls.chan_goto(hw, rxq->chan_id, rxq->halt_addr); + rxq->halt = curr; + } + curr = (curr + 1) % rxq->nb_desc; + sal_spinlock_unlock(rxq->lock); + } else { + curr = (curr + 1) % rxq->nb_desc; + } + rxq->curr = curr; + done++; + + /* Restart DMA if in chain mode */ + if (dev->flags & PDMA_CHAIN_MODE) { + if (curr == 0 && !(rxq->state & PDMA_RX_QUEUE_XOFF)) { + hw->hdls.chan_stop(hw, rxq->chan_id); + hw->hdls.chan_start(hw, rxq->chan_id); + } + } + } + + /* One more poll for chain done in chain mode */ + if (dev->flags & PDMA_CHAIN_MODE) { + if (curr == rxq->nb_desc - 1 && done) { + done = budget; + } + } + + /* In batching mode, replenish all the unused descriptors */ + if (rxq->state & PDMA_RX_BATCH_REFILL && + cmicx_pdma_rx_ring_unused(rxq) >= (int)rxq->free_thresh) { + cmicx_pdma_rx_ring_refill(hw, rxq); + } + + /* Notify the other side to process */ + if (dev->mode == DEV_MODE_VNET || dev->mode == DEV_MODE_HNET) { + if (done) { + dev->xnet_wake(dev); + } + } + + return done; + +fail: + CNET_PR("RX: Failed to allocate mem\n"); + + return done; +} + +/*! + * Process Tx vring + */ +static int +cmicx_pdma_tx_vring_process(struct pdma_hw *hw, struct pdma_tx_queue *txq, + struct pdma_tx_buf *pbuf) +{ + struct pdma_dev *dev = hw->dev; + struct cmicx_tx_desc *ring = (struct cmicx_tx_desc *)txq->ring; + struct pdma_tx_queue *vtxq = NULL; + struct cmicx_tx_desc *vring = NULL; + + vtxq = (struct pdma_tx_queue *)dev->ctrl.vnet_txq[txq->queue_id]; + vring = (struct cmicx_tx_desc *)vtxq->ring; + if (!vring) { + return SHR_E_UNAVAIL; + } + + /* Update vring descriptor */ + vring[vtxq->dirt].status = ring[txq->dirt].status; + pbuf->dma = 0; + + MEMORY_BARRIER; + + /* Notify VNET to process if needed */ + if (!vring[(vtxq->dirt + vtxq->nb_desc - 1) % vtxq->nb_desc].status) { + dev->xnet_wake(dev); + } + vtxq->dirt = (vtxq->dirt + 1) % vtxq->nb_desc; + + return SHR_E_NONE; +} + +/*! + * \brief Clean Tx ring + * + * \param [in] hw HW structure point. + * \param [in] txq Tx queue structure point. + * \param [in] budget Polling budget. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +static int +cmicx_pdma_tx_ring_clean(struct pdma_hw *hw, struct pdma_tx_queue *txq, int budget) +{ + struct pdma_dev *dev = hw->dev; + struct pdma_buf_mngr *bm = (struct pdma_buf_mngr *)dev->ctrl.buf_mngr; + struct cmicx_tx_desc *ring = (struct cmicx_tx_desc *)txq->ring; + uint32_t dirt, curr; + int done = 0; + + dirt = txq->dirt; + while (txq->pbuf[dirt].dma) { + if (!CMICX_DESC_STAT_DONE(ring[dirt].status)) { + break; + } + if (done == budget) { + break; + } + + if (dev->mode == DEV_MODE_HNET && !txq->pbuf[dirt].skb) { + cmicx_pdma_tx_vring_process(hw, txq, &txq->pbuf[dirt]); + } else { + /* Free the done pktbuf */ + bm->tx_buf_free(dev, txq, &txq->pbuf[dirt]); + } + + cmicx_tx_desc_config(&ring[dirt], 0, 0, 0); + + /* Update the indicators */ + dirt = (dirt + 1) % txq->nb_desc; + txq->dirt = dirt; + done++; + + /* Restart DMA if in chain mode */ + if (dev->flags & PDMA_CHAIN_MODE) { + sal_spinlock_lock(txq->lock); + curr = txq->curr; + if (dirt == txq->halt && dirt != curr) { + hw->hdls.chan_stop(hw, txq->chan_id); + cmicx_tx_desc_chain(&ring[(curr + txq->nb_desc - 1) % txq->nb_desc], 0); + hw->hdls.chan_setup(hw, txq->chan_id, + txq->ring_addr + sizeof(struct cmicx_tx_desc) * txq->halt); + hw->hdls.chan_start(hw, txq->chan_id); + txq->halt = curr; + } + sal_spinlock_unlock(txq->lock); + } + } + + /* One more poll for chain done in chain mode */ + if (dev->flags & PDMA_CHAIN_MODE) { + sal_spinlock_lock(txq->lock); + if (dirt != txq->halt) { + done = budget; + } + sal_spinlock_unlock(txq->lock); + } + + /* Resume Tx if any */ + sal_spinlock_lock(txq->lock); + if (cmicx_pdma_tx_ring_unused(txq) && txq->state & PDMA_TX_QUEUE_XOFF) { + txq->state &= ~PDMA_TX_QUEUE_XOFF; + sal_spinlock_unlock(txq->lock); + if (dev->tx_resume) { + dev->tx_resume(dev, txq->queue_id); + } else if (!(txq->state & PDMA_TX_QUEUE_POLL)) { + sal_sem_give(txq->sem); + } + return done; + } + sal_spinlock_unlock(txq->lock); + + return done; +} + +/*! + * Dump Rx ring + */ +static int +cmicx_pdma_rx_ring_dump(struct pdma_hw *hw, struct pdma_rx_queue *rxq) +{ + struct cmicx_rx_desc *ring = (struct cmicx_rx_desc *)rxq->ring; + struct cmicx_rx_desc *rd; + uint32_t di; + + CNET_PR("\nRX: queue=%d, chan=%d, curr=%d, halt=%d, halt@%p\n", + rxq->queue_id, rxq->chan_id, rxq->curr, rxq->halt, (void *)&ring[rxq->halt]); + CNET_PR("----------------------------------------------------------------\n"); + for (di = 0; di < rxq->nb_desc + 1; di++) { + rd = &ring[di]; + CNET_PR("DESC[%03d]: (%p)->%08x %08x %08x %08x\n", + di, (void *)(unsigned long)(rxq->ring_addr + di * CMICX_PDMA_DCB_SIZE), + rd->addr_lo, rd->addr_hi, rd->ctrl, rd->status); + } + + return SHR_E_NONE; +} + +/*! + * Dump Tx ring + */ +static int +cmicx_pdma_tx_ring_dump(struct pdma_hw *hw, struct pdma_tx_queue *txq) +{ + struct cmicx_tx_desc *ring = (struct cmicx_tx_desc *)txq->ring; + struct cmicx_tx_desc *td; + uint32_t di; + + CNET_PR("\nTX: queue=%d, chan=%d, curr=%d, dirt=%d, halt@%p\n", + txq->queue_id, txq->chan_id, txq->curr, txq->dirt, (void *)&ring[txq->curr]); + CNET_PR("----------------------------------------------------------------\n"); + for (di = 0; di < txq->nb_desc + 1; di++) { + td = &ring[di]; + CNET_PR("DESC[%03d]: (%p)->%08x %08x %08x %08x\n", + di, (void *)(unsigned long)(txq->ring_addr + di * CMICX_PDMA_DCB_SIZE), + td->addr_lo, td->addr_hi, td->ctrl, td->status); + } + + return SHR_E_NONE; +} + +/*! + * Fetch Tx vring + */ +static int +cmicx_pdma_tx_vring_fetch(struct pdma_hw *hw, struct pdma_tx_queue *txq, + struct pdma_tx_buf *pbuf) +{ + struct pdma_dev *dev = hw->dev; + struct cmicx_tx_desc *ring = (struct cmicx_tx_desc *)txq->ring; + struct pdma_tx_queue *vtxq = NULL; + struct cmicx_tx_desc *vring = NULL; + + vtxq = (struct pdma_tx_queue *)dev->ctrl.vnet_txq[txq->queue_id]; + vring = (struct cmicx_tx_desc *)vtxq->ring; + if (!vring || !CMICX_DESC_CTRL_LEN(vring[vtxq->curr].ctrl)) { + return SHR_E_UNAVAIL; + } + + /* Fetch vring descriptor */ + sal_memcpy(&ring[txq->curr], &vring[vtxq->curr], sizeof(struct cmicx_tx_desc)); + vring[vtxq->curr].ctrl &= ~CMICX_DESC_CTRL_LEN(-1); + + MEMORY_BARRIER; + + pbuf->dma = vring[vtxq->curr].addr_lo; + pbuf->len = CMICX_DESC_CTRL_LEN(ring[txq->curr].ctrl); + vtxq->curr = (vtxq->curr + 1) % vtxq->nb_desc; + + return SHR_E_NONE; +} + +/*! + * Check Tx ring + */ +static inline int +cmicx_pdma_tx_ring_check(struct pdma_hw *hw, struct pdma_tx_queue *txq) +{ + if (cmicx_pdma_tx_ring_unused(txq)) { + return SHR_E_NONE; + } + + sal_spinlock_lock(txq->lock); + if (!cmicx_pdma_tx_ring_unused(txq)) { + txq->state |= PDMA_TX_QUEUE_XOFF; + txq->stats.xoffs++; + sal_spinlock_unlock(txq->lock); + if (hw->dev->tx_suspend) { + hw->dev->tx_suspend(hw->dev, txq->queue_id); + } + return SHR_E_BUSY; + } + sal_spinlock_unlock(txq->lock); + + return SHR_E_NONE; +} + +/*! + * \brief Start packet transmission + * + * \param [in] hw HW structure point. + * \param [in] txq Tx queue structure point. + * \param [in] buf Tx packet buffer. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +static int +cmicx_pdma_pkt_xmit(struct pdma_hw *hw, struct pdma_tx_queue *txq, void *buf) +{ + struct pdma_dev *dev = hw->dev; + struct pdma_buf_mngr *bm = (struct pdma_buf_mngr *)dev->ctrl.buf_mngr; + struct cmicx_tx_desc *ring = (struct cmicx_tx_desc *)txq->ring; + struct pdma_tx_buf *pbuf = NULL; + struct pkt_hdr *pkh = NULL; + dma_addr_t addr; + uint32_t curr, flags = 0; + int retry = 5000000; + int rv; + + if (!(txq->state & PDMA_TX_QUEUE_ACTIVE)) { + return SHR_E_UNAVAIL; + } + + if (dev->tx_suspend) { + sal_spinlock_lock(txq->mutex); + } else { + sal_sem_take(txq->sem, SAL_SEM_FOREVER); + } + + /* Check Tx resource */ + if (dev->tx_suspend) { + /* Suspend Tx if no resource */ + rv = cmicx_pdma_tx_ring_check(hw, txq); + if (SHR_FAILURE(rv)) { + sal_spinlock_unlock(txq->mutex); + return rv; + } + } else { + /* Abort Tx if a fatal error happened */ + if (txq->state & PDMA_TX_QUEUE_XOFF) { + sal_sem_give(txq->sem); + return SHR_E_RESOURCE; + } + } + + /* Setup the new descriptor */ + curr = txq->curr; + pbuf = &txq->pbuf[curr]; + if (dev->mode == DEV_MODE_HNET && !buf) { + rv = cmicx_pdma_tx_vring_fetch(hw, txq, pbuf); + if (SHR_FAILURE(rv)) { + sal_spinlock_unlock(txq->mutex); + return SHR_E_EMPTY; + } + } else { + pbuf->adj = 1; + pkh = bm->tx_buf_get(dev, txq, pbuf, buf); + if (!pkh) { + txq->stats.dropped++; + if (dev->tx_suspend) { + sal_spinlock_unlock(txq->mutex); + } else { + sal_sem_give(txq->sem); + } + return SHR_E_NONE; + } + bm->tx_buf_dma(dev, txq, pbuf, &addr); + flags |= pkh->attrs & PDMA_TX_HIGIG_PKT ? CMICX_DESC_TX_HIGIG_PKT : 0; + flags |= pkh->attrs & PDMA_TX_PURGE_PKT ? CMICX_DESC_TX_PURGE_PKT : 0; + cmicx_tx_desc_config(&ring[curr], addr, pbuf->len, flags); + } + + /* Notify HNET to process if needed */ + if (dev->mode == DEV_MODE_VNET) { + MEMORY_BARRIER; + if (!CMICX_DESC_CTRL_LEN(ring[(curr + txq->nb_desc - 1) % txq->nb_desc].ctrl)) { + dev->xnet_wake(dev); + } + } + + /* Update the indicators */ + curr = (curr + 1) % txq->nb_desc; + txq->curr = curr; + + /* Start DMA if in chain mode */ + if (dev->flags & PDMA_CHAIN_MODE) { + if (txq->state & PDMA_TX_QUEUE_POLL) { + do { + rv = cmicx_pdma_tx_ring_clean(hw, txq, txq->nb_desc - 1); + if (rv != (int)txq->nb_desc - 1) { + break; + } + sal_usleep(1); + } while (retry--); + if (retry <= 0) { + CNET_PR("Last Tx could not be done in given time\n"); + } + } + sal_spinlock_lock(txq->lock); + if (txq->dirt == txq->halt && txq->dirt != curr) { + hw->hdls.chan_stop(hw, txq->chan_id); + cmicx_tx_desc_chain(&ring[(curr + txq->nb_desc - 1) % txq->nb_desc], 0); + hw->hdls.chan_setup(hw, txq->chan_id, + txq->ring_addr + sizeof(struct cmicx_tx_desc) * txq->halt); + hw->hdls.chan_start(hw, txq->chan_id); + txq->halt = curr; + } + sal_spinlock_unlock(txq->lock); + } + + /* Kick off DMA */ + txq->halt_addr = txq->ring_addr + sizeof(struct cmicx_tx_desc) * curr; + hw->hdls.chan_goto(hw, txq->chan_id, txq->halt_addr); + + /* Count the packets/bytes */ + txq->stats.packets++; + txq->stats.bytes += pbuf->len; + + /* Clean up ring if in polling mode */ + if (txq->state & PDMA_TX_QUEUE_POLL && + cmicx_pdma_tx_ring_unused(txq) <= (int)txq->free_thresh) { + cmicx_pdma_tx_ring_clean(hw, txq, txq->nb_desc - txq->free_thresh); + } + + /* Suspend Tx if no resource */ + rv = cmicx_pdma_tx_ring_check(hw, txq); + if (SHR_FAILURE(rv)) { + if (dev->mode == DEV_MODE_VNET) { + dev->xnet_wake(dev); + } + + if (txq->state & PDMA_TX_QUEUE_POLL) { + /* In polling mode, must wait till the ring is available */ + do { + cmicx_pdma_tx_ring_clean(hw, txq, txq->free_thresh); + if (!(txq->state & PDMA_TX_QUEUE_XOFF)) { + break; + } + sal_usleep(1); + } while (retry--); + if (retry <= 0) { + CNET_PR("Fatal error: Tx ring is full, packets have not been transmitted for 5 seconds\n"); + if (!dev->tx_suspend) { + sal_sem_give(txq->sem); + return SHR_E_RESOURCE; + } + } + } else { + /* In interrupt mode, the handle thread will wake up Tx */ + if (!dev->tx_suspend) { + return SHR_E_NONE; + } + } + } + + if (dev->tx_suspend) { + sal_spinlock_unlock(txq->mutex); + } else { + sal_sem_give(txq->sem); + } + + return SHR_E_NONE; +} + +/*! + * Suspend Rx queue + */ +static int +cmicx_pdma_rx_suspend(struct pdma_hw *hw, struct pdma_rx_queue *rxq) +{ + sal_spinlock_lock(rxq->lock); + rxq->state |= PDMA_RX_QUEUE_XOFF; + if (hw->dev->flags & PDMA_CHAIN_MODE) { + hw->hdls.chan_stop(hw, rxq->chan_id); + } + sal_spinlock_unlock(rxq->lock); + + return SHR_E_NONE; +} + +/*! + * Resume Rx queue + */ +static int +cmicx_pdma_rx_resume(struct pdma_hw *hw, struct pdma_rx_queue *rxq) +{ + sal_spinlock_lock(rxq->lock); + if (!(rxq->state & PDMA_RX_QUEUE_XOFF)) { + sal_spinlock_unlock(rxq->lock); + return SHR_E_NONE; + } + if (rxq->state & PDMA_RX_BATCH_REFILL) { + rxq->halt_addr = rxq->ring_addr + sizeof(struct cmicx_rx_desc) * rxq->halt; + hw->hdls.chan_goto(hw, rxq->chan_id, rxq->halt_addr); + } else if (rxq->halt == rxq->curr || (rxq->halt == rxq->nb_desc && rxq->curr == 0)) { + rxq->halt = (rxq->curr + 1) % rxq->nb_desc; + rxq->halt_addr = rxq->ring_addr + sizeof(struct cmicx_rx_desc) * rxq->halt; + hw->hdls.chan_goto(hw, rxq->chan_id, rxq->halt_addr); + } + if (hw->dev->flags & PDMA_CHAIN_MODE) { + rxq->curr = 0; + hw->hdls.chan_start(hw, rxq->chan_id); + } + rxq->state &= ~PDMA_RX_QUEUE_XOFF; + sal_spinlock_unlock(rxq->lock); + + return SHR_E_NONE; +} + +/*! + * Initialize function pointers + */ +int +bcmcnet_cmicx_pdma_desc_ops_init(struct pdma_hw *hw) +{ + if (!hw) { + return SHR_E_PARAM; + } + + hw->dops.rx_desc_init = cmicx_pdma_rx_desc_init; + hw->dops.rx_desc_clean = cmicx_pdma_rx_desc_clean; + hw->dops.rx_ring_clean = cmicx_pdma_rx_ring_clean; + hw->dops.rx_ring_dump = cmicx_pdma_rx_ring_dump; + hw->dops.rx_suspend = cmicx_pdma_rx_suspend; + hw->dops.rx_resume = cmicx_pdma_rx_resume; + hw->dops.tx_desc_init = cmicx_pdma_tx_desc_init; + hw->dops.tx_desc_clean = cmicx_pdma_tx_desc_clean; + hw->dops.tx_ring_clean = cmicx_pdma_tx_ring_clean; + hw->dops.tx_ring_dump = cmicx_pdma_tx_ring_dump; + hw->dops.pkt_xmit = cmicx_pdma_pkt_xmit; + + return SHR_E_NONE; +} + +/*! + * Attach device driver + */ +int +bcmcnet_cmicx_pdma_driver_attach(struct pdma_dev *dev) +{ + struct pdma_hw *hw = NULL; + + /* Allocate memory for HW data */ + hw = sal_alloc(sizeof(*hw), "bcmcnetPdmaHw"); + if (!hw) { + return SHR_E_MEMORY; + } + sal_memset(hw, 0, sizeof(*hw)); + hw->unit = dev->unit; + hw->dev = dev; + dev->ctrl.hw = hw; + + bcmcnet_cmicx_pdma_hw_hdls_init(hw); + bcmcnet_cmicx_pdma_desc_ops_init(hw); + + return SHR_E_NONE; +} + +/*! + * Detach device driver + */ +int +bcmcnet_cmicx_pdma_driver_detach(struct pdma_dev *dev) +{ + if (dev->ctrl.hw) { + sal_free(dev->ctrl.hw); + } + dev->ctrl.hw = NULL; + + return SHR_E_NONE; +} + diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_cmicd.h b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_cmicd.h new file mode 100644 index 000000000000..ef9717923e70 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_cmicd.h @@ -0,0 +1,369 @@ +/*! \file bcmcnet_cmicd.h + * + * CMICd registers and descriptors definitions. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#ifndef BCMCNET_CMICD_H +#define BCMCNET_CMICD_H + +/*! + * \name CMICD PDMA HW definitions + */ +/*! \{ */ +/*! CMICD CMC number */ +#define CMICD_PDMA_CMC_MAX 3 +/*! CMICD CMC PDMA channels */ +#define CMICD_PDMA_CMC_CHAN 4 +/*! CMICD PDMA DCB size */ +#define CMICD_PDMA_DCB_SIZE 64 +/*! \} */ + +/*! + * \name CMICD PDMA register definitions + */ +/*! \{ */ +#define CMICD_PDMA_CTRLr 0x0140 +#define CMICD_PDMA_STATr 0x0150 +#define CMICD_PDMA_STAT_HIr 0x0130 +#define CMICD_PDMA_STAT_CLRr 0x01a4 +#define CMICD_PDMA_DESCr 0x0158 +#define CMICD_PDMA_CURR_DESCr 0x01a8 +#define CMICD_PDMA_DESC_HALTr 0x0120 +#define CMICD_PDMA_COS_RX0r 0x0168 +#define CMICD_PDMA_COS_RX1r 0x016c +#define CMICD_PDMA_COS_MASK0r 0x019c +#define CMICD_PDMA_COS_MASK1r 0x01a0 +#define CMICD_PDMA_INTR_COALr 0x0188 +#define CMICD_PDMA_RBUF_THREr 0x0110 +#define CMICD_PDMA_COUNT_RXr 0x0480 +#define CMICD_PDMA_COUNT_TXr 0x0484 +#define CMICD_PDMA_COUNT_ALL_RXr 0x04a0 +#define CMICD_PDMA_COUNT_ALL_TXr 0x04a4 +#define CMICD_IRQ_STATr 0x0400 +#define CMICD_IRQ_PCI_MASKr 0x0414 +#define CMICD_IRQ_UC0_MASKr 0x0428 +/*! \} */ + +/*! + * \name CMICD PDMA register address + */ +/*! \{ */ +/*! Base address */ +#define CMICD_GRP_BASE(g) (0x00031000 + 0x1000 * g) +/*! Control register address */ +#define CMICD_PDMA_CTRL(g, q) (CMICD_GRP_BASE(g) + CMICD_PDMA_CTRLr + q * 4) +/*! Status register address */ +#define CMICD_PDMA_STAT(g) (CMICD_GRP_BASE(g) + CMICD_PDMA_STATr) +/*! Status higher register address */ +#define CMICD_PDMA_STAT_HI(g) (CMICD_GRP_BASE(g) + CMICD_PDMA_STAT_HIr) +/*! Status clear register address */ +#define CMICD_PDMA_STAT_CLR(g) (CMICD_GRP_BASE(g) + CMICD_PDMA_STAT_CLRr) +/*! Descriptor register address */ +#define CMICD_PDMA_DESC(g, q) (CMICD_GRP_BASE(g) + CMICD_PDMA_DESCr + q * 4) +/*! Current descriptor register address */ +#define CMICD_PDMA_CURR_DESC(g, q) (CMICD_GRP_BASE(g) + CMICD_PDMA_CURR_DESCr + q * 4) +/*! Descriptor halt register address */ +#define CMICD_PDMA_DESC_HALT(g, q) (CMICD_GRP_BASE(g) + CMICD_PDMA_DESC_HALTr + q * 4) +/*! COS Rx0 register address */ +#define CMICD_PDMA_COS_RX0(g, q) (CMICD_GRP_BASE(g) + CMICD_PDMA_COS_RX0r + q * 8) +/*! COS Rx1 register address */ +#define CMICD_PDMA_COS_RX1(g, q) (CMICD_GRP_BASE(g) + CMICD_PDMA_COS_RX1r + q * 8) +/*! COS Mask0 register address */ +#define CMICD_PDMA_COS_MASK0(g) (CMICD_GRP_BASE(g) + CMICD_PDMA_COS_MASK0r) +/*! COS Mask1 register address */ +#define CMICD_PDMA_COS_MASK1(g) (CMICD_GRP_BASE(g) + CMICD_PDMA_COS_MASK1r) +/*! Interrupt coalesce register address */ +#define CMICD_PDMA_INTR_COAL(g, q) (CMICD_GRP_BASE(g) + CMICD_PDMA_INTR_COALr + q * 4) +/*! Rx buffer threshhold register address */ +#define CMICD_PDMA_RBUF_THRE(g, q) (CMICD_GRP_BASE(g) + CMICD_PDMA_RBUF_THREr + q * 4) +/*! Rx counter register address */ +#define CMICD_PDMA_COUNT_RX(g, q) (CMICD_GRP_BASE(g) + CMICD_PDMA_COUNT_RXr + q * 8) +/*! Tx counter register address */ +#define CMICD_PDMA_COUNT_TX(g, q) (CMICD_GRP_BASE(g) + CMICD_PDMA_COUNT_TXr + q * 8) +/*! Rx global counter register address */ +#define CMICD_PDMA_COUNT_ALL_RX(g) (CMICD_GRP_BASE(g) + CMICD_PDMA_COUNT_ALL_RXr) +/*! Tx gloable counter register address */ +#define CMICD_PDMA_COUNT_ALL_TX(g) (CMICD_GRP_BASE(g) + CMICD_PDMA_COUNT_ALL_TXr) +/*! Interrupt status register address */ +#define CMICD_IRQ_STAT(g) (CMICD_GRP_BASE(g) + CMICD_IRQ_STATr) +/*! Interrupt PCI mask register address */ +#define CMICD_IRQ_PCI_MASK(g) (CMICD_GRP_BASE(g) + CMICD_IRQ_PCI_MASKr) +/*! Interrupt UC0 mask register address */ +#define CMICD_IRQ_UC0_MASK(g) (CMICD_GRP_BASE(g) + CMICD_IRQ_UC0_MASKr) +/*! Credits release release register address */ +#define CMICD_EPINTF_RELEASE_CREDITS 0x0001a000 +/*! Device revision register address */ +#define CMICD_DEV_REV_ID 0x00010224 +/*! CMIC revison register address */ +#define CMICD_CMICM_REV_ID 0x00010228 +/*! \} */ + +/*! + * \name Control register definitions + */ +/*! \{ */ +/*! Continuous DMA mode */ +#define CMICD_PDMA_CONTINUOUS 0x00000200 +/*! Controlled interrupt */ +#define CMICD_PDMA_CNTLD_INTR 0x00000100 +/*! Update status on reload */ +#define CMICD_PDMA_RLD_STAT_DIS 0x00000080 +/*! Dropped on chain end */ +#define CMICD_PDMA_DROP_ON_END 0x00000040 +/*! Descriptor big endianess */ +#define CMICD_PDMA_DESC_BIG_ENDIAN 0x00000020 +/*! Packet DMA big endianess */ +#define CMICD_PDMA_PKT_BIG_ENDIAN 0x00000010 +/*! Interrupt after descriptor */ +#define CMICD_PDMA_INTR_ON_DESC 0x00000008 +/*! Abort DMA */ +#define CMICD_PDMA_ABORT 0x00000004 +/*! Enable DMA */ +#define CMICD_PDMA_ENABLE 0x00000002 +/*! DMA direction */ +#define CMICD_PDMA_DIR 0x00000001 +/*! \} */ + +/*! + * \name Status register definitions + */ +/*! \{ */ +/*! Chain done */ +#define CMICD_PDMA_CHAIN_DONE(q) (0x00000001 << (q)) +/*! Descriptor done */ +#define CMICD_PDMA_DESC_DONE(q) (0x00000010 << (q)) +/*! Active */ +#define CMICD_PDMA_ACTIVE(q) (0x00000100 << (q)) +/*! \} */ + +/*! + * \name Status clear register definitions + */ +/*! \{ */ +/*! Clear completed interrupt */ +#define CMICD_PDMA_DESC_CMPLT(q) (0x00000001 << (q)) +/*! Clear controlled interrupt */ +#define CMICD_PDMA_DESC_CNTLD(q) (0x00000100 << (q)) +/*! \} */ + +/*! + * \name Interrupt_coalesce register definitions + */ +/*! \{ */ +/*! Interrupt coalesce enable */ +#define CMICD_PDMA_INTR_COAL_ENA (1 << 31) +/*! Interrupt coalesce threshhold */ +#define CMICD_PDMA_INTR_THRESH(cnt) (((cnt) & 0x7fff) << 16) +/*! Interrupt coalesce timeout */ +#define CMICD_PDMA_INTR_TIMER(tmr) ((tmr) & 0xffff) +/*! \} */ + +/*! + * \name Interrupt status&mask register definitions + */ +/*! \{ */ +/*! Interrupt mask */ +#define CMICD_PDMA_IRQ_MASK 0x78000000 +/*! Descriptor done */ +#define CMICD_IRQ_DESC_DONE(q) (0x00004000 >> (2 * (q))) +/*! Chain done */ +#define CMICD_IRQ_CHAIN_DONE(q) (0x00008000 >> (2 * (q))) +/*! Controlled interrupt */ +#define CMICD_IRQ_DESC_CNTLD(q) (0x08000000 << (q)) +/*! Interrupt start number */ +#define CMICD_IRQ_START_NUM 27 +/*! Interrupt number offset */ +#define CMICD_IRQ_NUM_OFFSET 1 +/*! Interrupt mask shift */ +#define CMICD_IRQ_MASK_SHIFT 0 +/*! Interrupt mask zeroing */ +#define CMICD_IRQ_ACT_CHAN(mask) (((mask) & CMICD_PDMA_IRQ_MASK) >> CMICD_IRQ_START_NUM) +/*! \} */ + +/*! 32-bit register read */ +#define DEV_READ32(_c, _a, _p) \ + do { \ + if ((_c)->dev->mode != DEV_MODE_VNET) { \ + *(_p) = ((volatile uint32_t *)(_c)->hw_addr)[(_a) / 4]; \ + } \ + } while (0) + +/*! 32-bit register write */ +#define DEV_WRITE32(_c, _a, _v) \ + do { \ + if ((_c)->dev->mode != DEV_MODE_VNET) { \ + ((volatile uint32_t *)(_c)->hw_addr)[(_a) / 4] = (_v); \ + } \ + } while (0) + +/*! + * \brief Rx metadata in descriptor. + */ +struct rx_metadata { + /*! Metadata */ + volatile uint32_t data[13]; + + /*! Status */ + volatile uint32_t status; +} __attribute__((packed)); + +/*! + * \brief Rx descriptor. + */ +struct cmicd_rx_desc { + /*! Packet address */ + volatile uint32_t addr; + + /*! Packet control */ + volatile uint32_t ctrl; + + /*! Metadata fields */ + struct rx_metadata md; +} __attribute__((packed)); + +/*! Reserve Rx meta data size in packet buffer */ +#define CMICD_RX_META_RESV 64 + +/*! + * \brief Tx metadata in descriptor. + */ +struct tx_metadata { + /*! Metadata */ + volatile uint32_t data[4]; + + /*! Reserved */ + volatile uint32_t rsvd[9]; + + /*! Status */ + volatile uint32_t status; +} __attribute__((packed)); + +/*! + * \brief Tx descriptor. + */ +struct cmicd_tx_desc { + /*! Packet address */ + volatile uint32_t addr; + + /*! Packet control */ + volatile uint32_t ctrl; + + /*! Metadata fields */ + struct tx_metadata md; +} __attribute__((packed)); + +/*! Reserve Tx meta data size in packet buffer */ +#define CMICD_TX_META_RESV 16 + +/*! + * Flags related to descriptors. + */ +/*! Controlled interrupt */ +#define CMICD_DESC_CTRL_CNTLD_INTR (1 << 24) +/*! Completed interrupt */ +#define CMICD_DESC_CTRL_CMPLT_INTR (1 << 23) +/*! Reload DCB */ +#define CMICD_DESC_CTRL_RELOAD (1 << 18) +/*! Scatter DCB */ +#define CMICD_DESC_CTRL_SCATTER (1 << 17) +/*! Chained DCB */ +#define CMICD_DESC_CTRL_CHAIN (1 << 16) +/*! Control flags */ +#define CMICD_DESC_CTRL_FLAGS(f) (((f) & 0xffff) << 16) +/*! Purge packet */ +#define CMICD_DESC_TX_PURGE_PKT (1 << 6) +/*! Pause packet */ +#define CMICD_DESC_TX_PAUSE_PKT (1 << 5) +/*! Higig packet */ +#define CMICD_DESC_TX_HIGIG_PKT (1 << 3) +/*! Packet length */ +#define CMICD_DESC_CTRL_LEN(len) ((len) & 0xffff) +/*! Done */ +#define CMICD_DESC_STAT_RTX_DONE (1 << 31) +/*! Head error */ +#define CMICD_DESC_STAT_HEAD_ERR (1 << 20) +/*! Data error */ +#define CMICD_DESC_STAT_DATA_ERR (1 << 19) +/*! Cell error */ +#define CMICD_DESC_STAT_CELL_ERR (1 << 18) +/*! Error mask */ +#define CMICD_DESC_STAT_ERR_MASK (CMICD_DESC_STAT_HEAD_ERR | \ + CMICD_DESC_STAT_DATA_ERR | \ + CMICD_DESC_STAT_CELL_ERR) +/*! Packet start */ +#define CMICD_DESC_STAT_PKT_START (1 << 17) +/*! Packet end */ +#define CMICD_DESC_STAT_PKT_END (1 << 16) +/*! Get done state */ +#define CMICD_DESC_STAT_DONE(stat) ((stat) & CMICD_DESC_STAT_RTX_DONE) +/*! Get flags */ +#define CMICD_DESC_STAT_FLAGS(stat) (((stat) >> 16) & ~0x8003) +/*! Get packet length */ +#define CMICD_DESC_STAT_LEN(stat) ((stat) & 0xffff) + +/*! HW access retry times */ +#define CMICD_HW_RETRY_TIMES 100000 + +/*! + * \brief Initialize HW handles. + * + * \param [in] hw HW structure point. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_cmicd_pdma_hw_hdls_init(struct pdma_hw *hw); + +/*! + * \brief Initialize descriptor operations. + * + * \param [in] hw HW structure point. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_cmicd_pdma_desc_ops_init(struct pdma_hw *hw); + +/*! + * \brief Attach device driver. + * + * \param [in] dev Device structure point. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_cmicd_pdma_driver_attach(struct pdma_dev *dev); + +/*! + * \brief Detach device driver. + * + * \param [in] dev Device structure point. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_cmicd_pdma_driver_detach(struct pdma_dev *dev); + +#endif /* BCMCNET_CMICD_H */ + diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_cmicx.h b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_cmicx.h new file mode 100644 index 000000000000..a8657c8b46a9 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_cmicx.h @@ -0,0 +1,379 @@ +/*! \file bcmcnet_cmicx.h + * + * CMICx registers and descriptors definitions. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#ifndef BCMCNET_CMICX_H +#define BCMCNET_CMICX_H + +/*! + * \name CMICX PDMA HW definitions + */ +/*! \{ */ +/*! CMICX CMC number */ +#define CMICX_PDMA_CMC_MAX 2 +/*! CMICX CMC PDMA channels */ +#define CMICX_PDMA_CMC_CHAN 8 +/*! CMICX PDMA DCB size */ +#define CMICX_PDMA_DCB_SIZE 16 +/*! \} */ + +/*! + * \name CMICX PCIe device address definitions + */ +/*! \{ */ +/*! CMICX PCIE offset */ +#define CMICX_PCIE_SO_OFFSET 0x10000000 +/*! Higher DMA address to bus address */ +#define DMA_TO_BUS_HI(dma) ((dma) | CMICX_PCIE_SO_OFFSET) +/*! Higher bus address to DMA address */ +#define BUS_TO_DMA_HI(bus) ((bus) & ~CMICX_PCIE_SO_OFFSET) +/*! \} */ + +/*! + * \name CMICX PDMA register definitions + */ +/*! \{ */ +#define CMICX_PDMA_CTRLr 0x2100 +#define CMICX_PDMA_STATr 0x2114 +#define CMICX_PDMA_DESC_LOr 0x2104 +#define CMICX_PDMA_DESC_HIr 0x2108 +#define CMICX_PDMA_CURR_DESC_LOr 0x2124 +#define CMICX_PDMA_CURR_DESC_HIr 0x2128 +#define CMICX_PDMA_DESC_HALT_LOr 0x210c +#define CMICX_PDMA_DESC_HALT_HIr 0x2110 +#define CMICX_PDMA_COS_CTRL_RX0r 0x2118 +#define CMICX_PDMA_COS_CTRL_RX1r 0x211c +#define CMICX_PDMA_INTR_COALr 0x2120 +#define CMICX_PDMA_RBUF_THREr 0x212c +#define CMICX_PDMA_DEBUG_CTRLr 0x2130 +#define CMICX_PDMA_DEBUG_SM_STATr 0x2134 +#define CMICX_PDMA_DEBUG_STATr 0x2138 +#define CMICX_PDMA_COUNT_RXr 0x213c +#define CMICX_PDMA_COUNT_TXr 0x2140 +#define CMICX_PDMA_COUNT_RX_DROPr 0x2144 +#define CMICX_PDMA_DESC_CNT_REQr 0x2148 +#define CMICX_PDMA_DESC_CNT_RXr 0x214c +#define CMICX_PDMA_DESC_CNT_STATr 0x2150 +#define CMICX_PDMA_IRQ_STATr 0x106c +#define CMICX_PDMA_IRQ_STAT_CLRr 0x1074 +/*! \} */ + +/*! + * \name CMICX PDMA register address + */ +/*! \{ */ +/*! Base address */ +#define CMICX_GRP_BASE(g) (0x00000000 + 0x3000 * g) +/*! Control register address */ +#define CMICX_PDMA_CTRL(g, q) (CMICX_GRP_BASE(g) + CMICX_PDMA_CTRLr + q * 0x80) +/*! Status register address */ +#define CMICX_PDMA_STAT(g, q) (CMICX_GRP_BASE(g) + CMICX_PDMA_STATr + q * 0x80) +/*! Descriptor Address Lower register address */ +#define CMICX_PDMA_DESC_LO(g, q) (CMICX_GRP_BASE(g) + CMICX_PDMA_DESC_LOr + q * 0x80) +/*! Descriptor Address Higher register address */ +#define CMICX_PDMA_DESC_HI(g, q) (CMICX_GRP_BASE(g) + CMICX_PDMA_DESC_HIr + q * 0x80) +/*! Current Descriptor Address Lower register address */ +#define CMICX_PDMA_CURR_DESC_LO(g, q) (CMICX_GRP_BASE(g) + CMICX_PDMA_CURR_DESC_LOr + q * 0x80) +/*! Current Descriptor Address Higher register address */ +#define CMICX_PDMA_CURR_DESC_HI(g, q) (CMICX_GRP_BASE(g) + CMICX_PDMA_CURR_DESC_HIr + q * 0x80) +/*! Descriptor Halt Address Lower register address */ +#define CMICX_PDMA_DESC_HALT_LO(g, q) (CMICX_GRP_BASE(g) + CMICX_PDMA_DESC_HALT_LOr + q * 0x80) +/*! Descriptor Halt Address Higher register address */ +#define CMICX_PDMA_DESC_HALT_HI(g, q) (CMICX_GRP_BASE(g) + CMICX_PDMA_DESC_HALT_HIr + q * 0x80) +/*! COS Control Rx0 register address */ +#define CMICX_PDMA_COS_CTRL_RX0(g, q) (CMICX_GRP_BASE(g) + CMICX_PDMA_COS_CTRL_RX0r + q * 0x80) +/*! COS Control Rx1 register address */ +#define CMICX_PDMA_COS_CTRL_RX1(g, q) (CMICX_GRP_BASE(g) + CMICX_PDMA_COS_CTRL_RX1r + q * 0x80) +/*! Interrupt Coalesce register address */ +#define CMICX_PDMA_INTR_COAL(g, q) (CMICX_GRP_BASE(g) + CMICX_PDMA_INTR_COALr + q * 0x80) +/*! Rx Buffer Threshhold register address */ +#define CMICX_PDMA_RBUF_THRE(g, q) (CMICX_GRP_BASE(g) + CMICX_PDMA_RBUF_THREr + q * 0x80) +/*! Debug Control register address */ +#define CMICX_PDMA_DEBUG_CTRL(g, q) (CMICX_GRP_BASE(g) + CMICX_PDMA_DEBUG_CTRLr + q * 0x80) +/*! Debug Status register address */ +#define CMICX_PDMA_DEBUG_STAT(g, q) (CMICX_GRP_BASE(g) + CMICX_PDMA_DEBUG_STATr + q * 0x80) +/*! Debug State Machine Status register address */ +#define CMICX_PDMA_DEBUG_SM_STAT(g, q) (CMICX_GRP_BASE(g) + CMICX_PDMA_DEBUG_SM_STATr + q * 0x80) +/*! Rx Packet Count register address */ +#define CMICX_PDMA_COUNT_RX(g, q) (CMICX_GRP_BASE(g) + CMICX_PDMA_COUNT_RXr + q * 0x80) +/*! Tx Packet Count register address */ +#define CMICX_PDMA_COUNT_TX(g, q) (CMICX_GRP_BASE(g) + CMICX_PDMA_COUNT_TXr + q * 0x80) +/*! Dropped Rx Packet Count register address */ +#define CMICX_PDMA_COUNT_RX_DROP(g, q) (CMICX_GRP_BASE(g) + CMICX_PDMA_COUNT_RX_DROPr + q * 0x80) +/*! Requested Descriptor Count register address */ +#define CMICX_PDMA_DESC_CNT_REQ(g, q) (CMICX_GRP_BASE(g) + CMICX_PDMA_DESC_CNT_REQr + q * 0x80) +/*! Received Descriptor Count register address */ +#define CMICX_PDMA_DESC_CNT_RX(g, q) (CMICX_GRP_BASE(g) + CMICX_PDMA_DESC_CNT_RXr + q * 0x80) +/*! Updated Descriptor Count register address */ +#define CMICX_PDMA_DESC_CNT_STAT(g, q) (CMICX_GRP_BASE(g) + CMICX_PDMA_DESC_CNT_STATr + q * 0x80) +/*! Interrupt Status register address */ +#define CMICX_PDMA_IRQ_STAT(g) (CMICX_GRP_BASE(g) + CMICX_PDMA_IRQ_STATr) +/*! Interrupt Status Clear register address */ +#define CMICX_PDMA_IRQ_STAT_CLR(g) (CMICX_GRP_BASE(g) + CMICX_PDMA_IRQ_STAT_CLRr) +/*! Interrupt Enable register address0 */ +#define CMICX_PDMA_IRQ_ENAB0 0x18013100 +/*! Interrupt Enable register address1 */ +#define CMICX_PDMA_IRQ_ENAB1 0x18013104 +/*! Interrupt Enable register address2 */ +#define CMICX_PDMA_IRQ_ENAB2 0x18013108 +/*! Interrupt raw status register address0 */ +#define CMICX_PDMA_IRQ_RAW_STAT0 0x18013150 +/*! Interrupt raw status register address1 */ +#define CMICX_PDMA_IRQ_RAW_STAT1 0x18013154 +/*! Interrupt raw status register address2 */ +#define CMICX_PDMA_IRQ_RAW_STAT2 0x18013158 +/*! EP_TO_CPU Header Size register address */ +#define CMICX_EP_TO_CPU_HEADER_SIZE 0x00000004 +/*! Top config register address */ +#define CMICX_TOP_CONFIG 0x00000008 +/*! Credits release register address */ +#define CMICX_EPINTF_RELEASE_CREDITS 0x0000006c +/*! Max credits register address */ +#define CMICX_EPINTF_MAX_CREDITS 0x00000070 +/*! \} */ + +/*! + * \name Control register definitions + */ +/*! \{ */ +/*! Disable abort on error */ +#define CMICX_PDMA_NO_ABORT_ON_ERR 0x00002000 +/*! EP_TO_CPU header big endianess */ +#define CMICX_PDMA_HDR_BIG_ENDIAN 0x00001000 +/*! Continuous descriptor mode */ +#define CMICX_PDMA_CONTINUOUS_DESC 0x00000200 +/*! Continuous DMA mode */ +#define CMICX_PDMA_CONTINUOUS 0x00000100 +/*! Interrupt after descriptor */ +#define CMICX_PDMA_INTR_ON_DESC 0x00000080 +/*! Update status on reload */ +#define CMICX_PDMA_RLD_STAT_DIS 0x00000040 +/*! Dropped on chain end */ +#define CMICX_PDMA_DROP_ON_END 0x00000020 +/*! Descriptor big endianess */ +#define CMICX_PDMA_DESC_BIG_ENDIAN 0x00000010 +/*! Packet DMA big endianess */ +#define CMICX_PDMA_PKT_BIG_ENDIAN 0x00000008 +/*! Abort DMA */ +#define CMICX_PDMA_ABORT 0x00000004 +/*! Enable DMA */ +#define CMICX_PDMA_ENABLE 0x00000002 +/*! DMA direction */ +#define CMICX_PDMA_DIR 0x00000001 +/*! EP_TO_CPU header alignment bytes */ +#define CMICX_PDMA_HDR_ALMNT(bytes) (((bytes) & 0x3) << 10) +/*! \} */ + +/*! + * \name Status register definitions + */ +/*! \{ */ +/*! Channel in halt */ +#define CMICX_PDMA_IN_HALT 0x00000040 +/*! Channel active */ +#define CMICX_PDMA_IS_ACTIVE 0x00000002 +/*! Chain done */ +#define CMICX_PDMA_CHAIN_DONE 0x00000001 +/*! \} */ + +/*! + * \name Interrupt_coalesce register definitions + */ +/*! \{ */ +/*! Interrupt coalesce enable */ +#define CMICX_PDMA_INTR_COAL_ENA (1 << 31) +/*! Interrupt coalesce threshhold */ +#define CMICX_PDMA_INTR_THRESH(cnt) (((cnt) & 0x7fff) << 16) +/*! Interrupt coalesce timeout */ +#define CMICX_PDMA_INTR_TIMER(tmr) ((tmr) & 0xffff) +/*! \} */ + +/*! + * \name Interrupt status&clear register definitions + */ +/*! \{ */ +/*! Descriptor done */ +#define CMICX_PDMA_IRQ_DESC_DONE(q) (0x00000001 << ((q) * 4)) +/*! Chain done */ +#define CMICX_PDMA_IRQ_CHAIN_DONE(q) (0x00000002 << ((q) * 4)) +/*! Coalescing interrupt */ +#define CMICX_PDMA_IRQ_COALESCE_INTR(q) (0x00000004 << ((q) * 4)) +/*! Controlled interrupt */ +#define CMICX_PDMA_IRQ_CTRLD_INTR(q) (0x00000008 << ((q) * 4)) +/*! Interrupt mask */ +#define CMICX_PDMA_IRQ_MASK(q) (0xf << ((q) * 4)) +/*! Interrupt start number */ +#define CMICX_IRQ_START_NUM (128 + 3) +/*! Interrupt number offset */ +#define CMICX_IRQ_NUM_OFFSET 4 +/*! Interrupt mask shift */ +#define CMICX_IRQ_MASK_SHIFT 16 +/*! \} */ + +/*! 32-bit register read */ +#define DEV_READ32(_c, _a, _p) \ + do { \ + if ((_c)->dev->mode != DEV_MODE_VNET) { \ + *(_p) = ((volatile uint32_t *)(_c)->hw_addr)[(_a) / 4]; \ + } \ + } while (0) + +/*! 32-bit register write */ +#define DEV_WRITE32(_c, _a, _v) \ + do { \ + if ((_c)->dev->mode != DEV_MODE_VNET) { \ + ((volatile uint32_t *)(_c)->hw_addr)[(_a) / 4] = (_v); \ + } \ + } while (0) + +/*! + * \brief Rx descriptor. + */ +struct cmicx_rx_desc { + /*! Packet address lower */ + volatile uint32_t addr_lo; + + /*! Packet address higher */ + volatile uint32_t addr_hi; + + /*! Packet control */ + volatile uint32_t ctrl; + + /*! Packet status */ + volatile uint32_t status; +} __attribute__((packed)); + +/*! + * \brief Tx descriptor. + */ +struct cmicx_tx_desc { + /*! Packet address lower */ + volatile uint32_t addr_lo; + + /*! Packet address higher */ + volatile uint32_t addr_hi; + + /*! Packet control */ + volatile uint32_t ctrl; + + /*! Packet status */ + volatile uint32_t status; +} __attribute__((packed)); + +/*! + * Flags related to descriptors. + */ +/*! Disable descriptor status write */ +#define CMICX_DESC_CTRL_STAT_WR_DIS (1 << 29) +/*! Descriptors remaining */ +#define CMICX_DESC_CTRL_REMAIN(cnt) (((cnt) & 0xf) << 25) +/*! Max remaining descriptors */ +#define CMICX_DESC_REMAIN_MAX 8 +/*! Controlled interrupt */ +#define CMICX_DESC_CTRL_CNTLD_INTR (1 << 24) +/*! Completed interrupt */ +#define CMICX_DESC_CTRL_CMPLT_INTR (1 << 23) +/*! Reload DCB */ +#define CMICX_DESC_CTRL_RELOAD (1 << 18) +/*! Scatter DCB */ +#define CMICX_DESC_CTRL_SCATTER (1 << 17) +/*! Chained DCB */ +#define CMICX_DESC_CTRL_CHAIN (1 << 16) +/*! Control flags */ +#define CMICX_DESC_CTRL_FLAGS(f) (((f) & 0xffff) << 16) +/*! Purge packet */ +#define CMICX_DESC_TX_PURGE_PKT (1 << 6) +/*! Higig packet */ +#define CMICX_DESC_TX_HIGIG_PKT (1 << 3) +/*! Packet length */ +#define CMICX_DESC_CTRL_LEN(len) ((len) & 0xffff) +/*! Done */ +#define CMICX_DESC_STAT_RTX_DONE (1 << 31) +/*! Ecc error */ +#define CMICX_DESC_STAT_DATA_ERR (1 << 19) +/*! Cell error */ +#define CMICX_DESC_STAT_CELL_ERR (1 << 18) +/*! Error mask */ +#define CMICX_DESC_STAT_ERR_MASK (CMICX_DESC_STAT_DATA_ERR | \ + CMICX_DESC_STAT_CELL_ERR) +/*! Packet start */ +#define CMICX_DESC_STAT_PKT_START (1 << 17) +/*! Packet end */ +#define CMICX_DESC_STAT_PKT_END (1 << 16) +/*! Get done state */ +#define CMICX_DESC_STAT_DONE(stat) ((stat) & CMICX_DESC_STAT_RTX_DONE) +/*! Get flags */ +#define CMICX_DESC_STAT_FLAGS(stat) (((stat) >> 16) & ~0x8003) +/*! Get packet length */ +#define CMICX_DESC_STAT_LEN(stat) ((stat) & 0xffff) + +/*! Tx packet header size */ +#define CMICX_TX_PKT_HDR_SIZE 16 + +/*! HW access retry times */ +#define CMICX_HW_RETRY_TIMES 100000 + +/*! + * \brief Initialize HW handles. + * + * \param [in] hw HW structure point. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_cmicx_pdma_hw_hdls_init(struct pdma_hw *hw); + +/*! + * \brief Initialize descriptor operations. + * + * \param [in] hw HW structure point. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_cmicx_pdma_desc_ops_init(struct pdma_hw *hw); + +/*! + * \brief Attach device driver. + * + * \param [in] dev Device structure point. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_cmicx_pdma_driver_attach(struct pdma_dev *dev); + +/*! + * \brief Detach device driver. + * + * \param [in] dev Device structure point. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_cmicx_pdma_driver_detach(struct pdma_dev *dev); + +#endif /* BCMCNET_CMICX_H */ + diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_core.h b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_core.h new file mode 100644 index 000000000000..13db809dda36 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_core.h @@ -0,0 +1,1323 @@ +/*! \file bcmcnet_core.h + * + * Generic data structure definitions and APIs for BCMCNET driver. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#ifndef BCMCNET_CORE_H +#define BCMCNET_CORE_H + +#include +#include + +/*! + * \brief Packet header structure. + */ +struct pkt_hdr { + /*! Meta data or outer header */ + uint8_t meta_data[16]; + + /*! Reserved */ + uint16_t rsvd0; + + /*! Packet signature */ + uint16_t pkt_sig; + + /*! Reserved */ + uint32_t rsvd1; + + /*! Data length */ + uint16_t data_len; + + /*! Reserved */ + uint16_t rsvd2; + + /*! Meta length */ + uint8_t meta_len; + + /*! Queue index */ + uint8_t queue_id; + + /*! Attributes */ + uint16_t attrs; + /*! Tx higig packet */ +#define PDMA_TX_HIGIG_PKT (1 << 0) + /*! Tx pause packet */ +#define PDMA_TX_PAUSE_PKT (1 << 1) + /*! Tx purge packet */ +#define PDMA_TX_PURGE_PKT (1 << 2) + /*! Tx queue number */ +#define PDMA_TX_BIND_QUE (1 << 3) + /*! Tx cookded header */ +#define PDMA_TX_HDR_COOKED (1 << 4) + /*! Tx to HNET */ +#define PDMA_TX_TO_HNET (1 << 5) + /*! Rx to VNET */ +#define PDMA_RX_TO_VNET (1 << 10) + /*! Rx strip vlan tag */ +#define PDMA_RX_STRIP_TAG (1 << 11) + /*! Rx set protocol type */ +#define PDMA_RX_SET_PROTO (1 << 12) + /*! Rx IP checksum */ +#define PDMA_RX_IP_CSUM (1 << 13) + /*! Rx TCPUDP checksum */ +#define PDMA_RX_TU_CSUM (1 << 14) +}; + +/*! Packet header size */ +#define PKT_HDR_SIZE sizeof(struct pkt_hdr) + +/*! + * \brief Packet buffer structure. + */ +struct pkt_buf { + /*! Packet header */ + struct pkt_hdr pkh; + + /*! Packet data */ + uint8_t data; +}; + +/*! + * \brief Interrupt handle. + */ +struct intr_handle { + /*! Device number */ + int unit; + + /*! Group number */ + int group; + + /*! Channel number */ + int chan; + + /*! Queue number */ + int queue; + + /*! Direction */ + int dir; + + /*! Polling budget */ + int budget; + + /*! Device point */ + void *dev; + + /*! Private point */ + void *priv; + + /*! Interrupt number */ + int intr_num; + + /*! Interrupt flags */ + uint32_t intr_flags; +}; + +/*! + * \brief Queue group structure. + */ +struct queue_group { + /*! Pointer to the device control structure */ + struct dev_ctrl *ctrl; + + /*! Interrupt handles */ + struct intr_handle intr_hdl[NUM_Q_PER_GRP]; + + /*! Rx queue pointers */ + void *rx_queue[NUM_Q_PER_GRP]; + + /*! Tx queue pointers */ + void *tx_queue[NUM_Q_PER_GRP]; + + /*! Virtual Rx queue pointers */ + void *vnet_rxq[NUM_Q_PER_GRP]; + + /*! Virtual Tx queue pointers */ + void *vnet_txq[NUM_Q_PER_GRP]; + + /*! Bitmap for Rx queues at work */ + uint32_t bm_rxq; + + /*! Bitmap for Tx queues at work */ + uint32_t bm_txq; + + /*! Number of Rx queues at work */ + uint32_t nb_rxq; + + /*! Number of Tx queues at work */ + uint32_t nb_txq; + + /*! Number of descriptors */ + uint32_t nb_desc[NUM_Q_PER_GRP]; + + /*! Rx buffer size */ + uint32_t rx_size[NUM_Q_PER_GRP]; + + /*! Queue mode */ + uint32_t que_ctrl[NUM_Q_PER_GRP]; + /*! Packet_byte_swap */ +#define PDMA_PKT_BYTE_SWAP (1 << 0) + /*! Non packet_byte_swap */ +#define PDMA_OTH_BYTE_SWAP (1 << 1) + /*! Header_byte_swap */ +#define PDMA_HDR_BYTE_SWAP (1 << 2) + + /*! Group ID */ + int id; + + /*! Queues need to poll */ + uint32_t poll_queues; + + /*! Active IRQs for DMA control */ + uint32_t irq_mask; + + /*! Indicating the group is attached */ + int attached; +}; + +/*! + * \brief Device control structure. + */ +struct dev_ctrl { + /*! Pointer to the device structure */ + struct pdma_dev *dev; + + /*! Pointer to hardware-specific data */ + void *hw; + + /*! HW base address */ + volatile void *hw_addr; + + /*! Queue groups */ + struct queue_group grp[NUM_GRP_MAX]; + + /*! Pointers to Rx queues */ + void *rx_queue[NUM_QUE_MAX]; + + /*! Pointers to Tx queues */ + void *tx_queue[NUM_QUE_MAX]; + + /*! Pointers to virtual Rx queues */ + void *vnet_rxq[NUM_QUE_MAX]; + + /*! Pointers to virtual Tx queues */ + void *vnet_txq[NUM_QUE_MAX]; + + /*! Pointer to buffer manager */ + void *buf_mngr; + + /*! VNET sync data */ + vnet_sync_t vsync; + + /*! Bitmap of groups at work */ + uint32_t bm_grp; + + /*! Bitmap of Rx queues at work */ + uint32_t bm_rxq; + + /*! Bitmap of Tx queues at work */ + uint32_t bm_txq; + + /*! Number of groups at work */ + uint32_t nb_grp; + + /*! Number of Rx queues at work */ + uint32_t nb_rxq; + + /*! Number of Tx queues at work */ + uint32_t nb_txq; + + /*! Number of descriptors for a queue */ + uint32_t nb_desc; + + /*! Budget for once queue processing */ + uint32_t budget; + + /*! Common Rx buffer size for all queues */ + uint32_t rx_buf_size; + + /*! Rx descriptor size */ + uint32_t rx_desc_size; + + /*! Tx descriptor size */ + uint32_t tx_desc_size; +}; + +/*! + * Configure device. + * + * \param [in] dev Pointer to device structure. + * \param [in] bm_rxq Rx queue bitmap. + * \param [in] bm_txq Tx queue bitmap. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +typedef int (*pdma_dev_config_f)(struct pdma_dev *dev, uint32_t bm_rxq, uint32_t bm_txq); + +/*! + * Start device. + * + * \param [in] dev Pointer to device structure. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +typedef int (*pdma_dev_start_f)(struct pdma_dev *dev); + +/*! + * Stop device. + * + * \param [in] dev Pointer to device structure. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +typedef int (*pdma_dev_stop_f)(struct pdma_dev *dev); + +/*! + * Close device. + * + * \param [in] dev Pointer to device structure. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +typedef int (*pdma_dev_close_f)(struct pdma_dev *dev); + +/*! + * Suspend device. + * + * \param [in] dev Pointer to device structure. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +typedef int (*pdma_dev_suspend_f)(struct pdma_dev *dev); + +/*! + * Resume device. + * + * \param [in] dev Pointer to device structure. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +typedef int (*pdma_dev_resume_f)(struct pdma_dev *dev); + +/*! + * Get device information. + * + * \param [in] dev Pointer to device structure. + */ +typedef void (*pdma_dev_info_get_f)(struct pdma_dev *dev); + +/*! + * Get device statistics. + * + * \param [in] dev Pointer to device structure. + */ +typedef void (*pdma_dev_stats_get_f)(struct pdma_dev *dev); + +/*! + * Reset device statistics. + * + * \param [in] dev Pointer to device structure. + */ +typedef void (*pdma_dev_stats_reset_f)(struct pdma_dev *dev); + +/*! + * Convert logic queue to physical queue. + * + * \param [in] dev Pointer to device structure. + * \param [in] queue Logic queue number. + * \param [in] dir Transmit direction. + * \param [in] chan Channel number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +typedef int (*pdma_dev_lq2pq_f)(struct pdma_dev *dev, int queue, int dir, int *chan); + +/*! + * Convert physical queue to logic queue. + * + * \param [in] dev Pointer to device structure. + * \param [in] chan Channel number. + * \param [in] queue Logic queue number. + * \param [in] dir Transmit direction. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +typedef int (*pdma_dev_pq2lq_f)(struct pdma_dev *dev, int chan, int *queue, int *dir); + +/*! + * Start queue. + * + * \param [in] dev Pointer to device structure. + * \param [in] queue Queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +typedef int (*pdma_queue_start_f)(struct pdma_dev *dev, int queue); + +/*! + * Stop queue. + * + * \param [in] dev Pointer to device structure. + * \param [in] queue Queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +typedef int (*pdma_queue_stop_f)(struct pdma_dev *dev, int queue); + +/*! + * Set up queue. + * + * \param [in] dev Pointer to device structure. + * \param [in] queue Queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +typedef int (*pdma_queue_setup_f)(struct pdma_dev *dev, int queue); + +/*! + * Release queue. + * + * \param [in] dev Pointer to device structure. + * \param [in] queue Queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +typedef int (*pdma_queue_release_f)(struct pdma_dev *dev, int queue); + +/*! + * Restore queue. + * + * \param [in] dev Pointer to device structure. + * \param [in] queue Queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +typedef int (*pdma_queue_restore_f)(struct pdma_dev *dev, int queue); + +/*! + * Enable queue interrupt. + * + * \param [in] dev Pointer to device structure. + * \param [in] queue Queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +typedef int (*pdma_intr_enable_f)(struct pdma_dev *dev, int queue); + +/*! + * Disable queue interrupt. + * + * \param [in] dev Pointer to device structure. + * \param [in] queue Queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +typedef int (*pdma_intr_disable_f)(struct pdma_dev *dev, int queue); + +/*! + * Acknowledge queue interrupt. + * + * \param [in] dev Pointer to device structure. + * \param [in] queue Queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +typedef int (*pdma_intr_ack_f)(struct pdma_dev *dev, int queue); + +/*! + * Query queue interrupt. + * + * \param [in] dev Pointer to device structure. + * \param [in] queue Queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +typedef int (*pdma_intr_query_f)(struct pdma_dev *dev, int queue); + +/*! + * Check queue interrupt. + * + * \param [in] dev Pointer to device structure. + * \param [in] queue Queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +typedef int (*pdma_intr_check_f)(struct pdma_dev *dev, int queue); + +/*! + * Suspend Rx queue. + * + * \param [in] dev Pointer to device structure. + * \param [in] queue Queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +typedef int (*pdma_rx_queue_suspend_f)(struct pdma_dev *dev, int queue); + +/*! + * Resume Rx queue. + * + * \param [in] dev Pointer to device structure. + * \param [in] queue Queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +typedef int (*pdma_rx_queue_resume_f)(struct pdma_dev *dev, int queue); + +/*! + * Wake up Tx queue. + * + * \param [in] dev Pointer to device structure. + * \param [in] queue Queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +typedef int (*pdma_tx_queue_wakeup_f)(struct pdma_dev *dev, int queue); + +/*! + * Poll Rx queue. + * + * \param [in] dev Pointer to device structure. + * \param [in] queue Queue number. + * \param [in] budget Max number of descriptor to poll. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +typedef int (*pdma_rx_queue_poll_f)(struct pdma_dev *dev, int queue, int budget); + +/*! + * Poll Tx queue. + * + * \param [in] dev Pointer to device structure. + * \param [in] queue Queue number. + * \param [in] budget Max number of descriptor to poll. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +typedef int (*pdma_tx_queue_poll_f)(struct pdma_dev *dev, int queue, int budget); + +/*! + * Poll queue group. + * + * \param [in] dev Pointer to device structure. + * \param [in] queue Queue number. + * \param [in] budget Max number of descriptor to poll. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +typedef int (*pdma_group_poll_f)(struct pdma_dev *dev, int group, int budget); + +/*! + * \brief Exported functions structure. + */ +struct dev_ops { + /*! Configure device */ + pdma_dev_config_f dev_config; + + /*! Start device */ + pdma_dev_start_f dev_start; + + /*! Stop device */ + pdma_dev_stop_f dev_stop; + + /*! Close device */ + pdma_dev_close_f dev_close; + + /*! Suspend device */ + pdma_dev_suspend_f dev_suspend; + + /*! Resume device */ + pdma_dev_resume_f dev_resume; + + /*! Get device information */ + pdma_dev_info_get_f dev_info_get; + + /*! Get device statistics */ + pdma_dev_stats_get_f dev_stats_get; + + /*! Reset device statistics */ + pdma_dev_stats_reset_f dev_stats_reset; + + /*! Logic queue to physical queue */ + pdma_dev_lq2pq_f dev_lq_to_pq; + + /*! Physical queue to logic queue */ + pdma_dev_pq2lq_f dev_pq_to_lq; + + /*! Start Rx for a queue */ + pdma_queue_start_f rx_queue_start; + + /*! Stop Rx for a queue */ + pdma_queue_stop_f rx_queue_stop; + + /*! Start Tx for a queue */ + pdma_queue_start_f tx_queue_start; + + /*! Stop Tx for a queue */ + pdma_queue_stop_f tx_queue_stop; + + /*! Set up Rx queue */ + pdma_queue_setup_f rx_queue_setup; + + /*! Release Rx queue */ + pdma_queue_release_f rx_queue_release; + + /*! Restore stopped Rx queue */ + pdma_queue_restore_f rx_queue_restore; + + /*! Set up virtual Rx queue */ + pdma_queue_setup_f rx_vqueue_setup; + + /*! Release virtual Rx queue */ + pdma_queue_release_f rx_vqueue_release; + + /*! Set up Tx queue */ + pdma_queue_setup_f tx_queue_setup; + + /*! Release Tx queue */ + pdma_queue_release_f tx_queue_release; + + /*! Restore stopped Tx queue */ + pdma_queue_restore_f tx_queue_restore; + + /*! Set up virtual Tx queue */ + pdma_queue_setup_f tx_vqueue_setup; + + /*! Release virtual Tx queue */ + pdma_queue_release_f tx_vqueue_release; + + /*! Enable Rx queue interrupt */ + pdma_intr_enable_f rx_queue_intr_enable; + + /*! Disable Rx queue interrupt */ + pdma_intr_disable_f rx_queue_intr_disable; + + /*! Acknowledge interrupt for Rx queue */ + pdma_intr_ack_f rx_queue_intr_ack; + + /*! Query interrupt status for Rx queue */ + pdma_intr_query_f rx_queue_intr_query; + + /*! Check interrupt validity for Rx queue */ + pdma_intr_check_f rx_queue_intr_check; + + /*! Enable Tx queue interrupt */ + pdma_intr_enable_f tx_queue_intr_enable; + + /*! Disable Tx queue interrupt */ + pdma_intr_disable_f tx_queue_intr_disable; + + /*! Acknowledge interrupt for Tx queue */ + pdma_intr_ack_f tx_queue_intr_ack; + + /*! Query interrupt status for Tx queue */ + pdma_intr_query_f tx_queue_intr_query; + + /*! Check interrupt validity for Tx queue */ + pdma_intr_check_f tx_queue_intr_check; + + /*! Suspend a Rx queue */ + pdma_rx_queue_suspend_f rx_queue_suspend; + + /*! Resume a Rx queue */ + pdma_rx_queue_resume_f rx_queue_resume; + + /*! Wake up a Tx queue to transmit */ + pdma_tx_queue_wakeup_f tx_queue_wakeup; + + /*! Poll for a Rx queue */ + pdma_rx_queue_poll_f rx_queue_poll; + + /*! Poll for a Tx queue */ + pdma_tx_queue_poll_f tx_queue_poll; + + /*! Poll for a group */ + pdma_group_poll_f group_poll; +}; + +/*! + * Read 32-bit device register. + * + * \param [in] dev Pointer to device structure. + * \param [in] addr Register address. + * \param [in] data Pointer to read data. + * + * \retval SHR_E_NONE No errors. + */ +typedef int (*reg32_read_f)(struct pdma_dev *dev, uint32_t addr, uint32_t *data); + +/*! + * Write 32-bit device register. + * + * \param [in] dev Pointer to device structure. + * \param [in] addr Register address. + * \param [in] data Data to write. + * + * \retval SHR_E_NONE No errors. + */ +typedef int (*reg32_write_f)(struct pdma_dev *dev, uint32_t addr, uint32_t data); + +/*! + * Receive packet. + * + * \param [in] dev Pointer to device structure. + * \param [in] queue Rx queue number. + * \param [in] buf Pointer to packet buffer. + * + * \retval SHR_E_NONE No errors. + */ +typedef int (*pdma_rx_f)(struct pdma_dev *dev, int queue, void *buf); + +/*! + * Transmit packet. + * + * \param [in] dev Pointer to device structure. + * \param [in] queue Tx queue number. + * \param [in] buf Pointer to packet buffer. + * + * \retval SHR_E_NONE No errors. + */ +typedef int (*pdma_tx_f)(struct pdma_dev *dev, int queue, void *buf); + +/*! + * Suspend Tx queue. + * + * \param [in] dev Pointer to device structure. + * \param [in] queue Tx queue number. + */ +typedef void (*sys_tx_suspend_f)(struct pdma_dev *dev, int queue); + +/*! + * Resume Tx queue. + * + * \param [in] dev Pointer to device structure. + * \param [in] queue Tx queue number. + */ +typedef void (*sys_tx_resume_f)(struct pdma_dev *dev, int queue); + +/*! + * Enable interrupts. + * + * \param [in] dev Pointer to device structure. + * \param [in] group Channel group number. + * \param [in] chan Channel number. + * \param [in] reg Interrupt enable register. + * \param [in] mask Interrupt mask. + */ +typedef void (*sys_intr_unmask_f)(struct pdma_dev *dev, int group, int chan, + uint32_t reg, uint32_t mask); + +/*! + * Disable interrupts. + * + * \param [in] dev Pointer to device structure. + * \param [in] group Channel group number. + * \param [in] chan Channel number. + * \param [in] reg Interrupt enable register. + * \param [in] mask Interrupt mask. + */ +typedef void (*sys_intr_mask_f)(struct pdma_dev *dev, int group, int chan, + uint32_t reg, uint32_t mask); + +/*! + * Wait for notification from the other side. + * + * \param [in] dev Pointer to device structure. + * + * \retval SHR_E_NONE No errors. + */ +typedef int (*xnet_wait_f)(struct pdma_dev *dev); + +/*! + * Wake up the other side. + * + * \param [in] dev Pointer to device structure. + * + * \retval SHR_E_NONE No errors. + */ +typedef int (*xnet_wake_f)(struct pdma_dev *dev); + +/*! + * Convert physical address to virtual address. + * + * \param [in] dev Pointer to device structure. + * \param [in] paddr Physical address. + * + * \retval Virtual address. + */ +typedef void *(*sys_p2v_f)(struct pdma_dev *dev, uint64_t paddr); + +/*! + * Convert virtual address to physical address. + * + * \param [in] dev Pointer to device structure. + * \param [in] vaddr Virtual address. + * + * \retval Physical address. + */ +typedef uint64_t (*sys_v2p_f)(struct pdma_dev *dev, void *vaddr); + +/*! + * \brief Device structure. + */ +struct pdma_dev { + /*! Device name */ + char name[DEV_NAME_LEN_MAX]; + + /*! Device ID */ + uint32_t dev_id; + + /*! Device type */ + uint32_t dev_type; + + /*! Device Number */ + int unit; + + /*! Device control structure */ + struct dev_ctrl ctrl; + + /*! Pointer to the exported funtions structure */ + struct dev_ops *ops; + + /*! Device information */ + struct bcmcnet_dev_info info; + + /*! Device statistics data */ + struct bcmcnet_dev_stats stats; + + /*! Private data */ + void *priv; + + /*! Read 32-bit device register */ + reg32_read_f dev_read32; + + /*! Write 32-bit device register */ + reg32_write_f dev_write32; + + /*! Packet reception */ + pdma_rx_f pkt_recv; + + /*! Packet transmission */ + pdma_tx_f pkt_xmit; + + /*! Tx suspend */ + sys_tx_suspend_f tx_suspend; + + /*! Tx resume */ + sys_tx_resume_f tx_resume; + + /*! Enable a set of interrupts */ + sys_intr_unmask_f intr_unmask; + + /*! Disable a set of interrupts */ + sys_intr_mask_f intr_mask; + + /*! Virtual network wait for */ + xnet_wait_f xnet_wait; + + /*! Virtual network wake up */ + xnet_wake_f xnet_wake; + + /*! Physical address to virtual address */ + sys_p2v_f sys_p2v; + + /*! Virtual address to physical address */ + sys_v2p_f sys_v2p; + + /*! Maximum number of groups */ + int num_groups; + + /*! Maximum number of group queues */ + int grp_queues; + + /*! Maximum number of queues */ + int num_queues; + + /*! Rx packet header size */ + uint32_t rx_ph_size; + + /*! Tx packet header size */ + uint32_t tx_ph_size; + + /*! Flags */ + uint32_t flags; + /*! Interrupt processing per group */ +#define PDMA_GROUP_INTR (1 << 0) + /*! Tx polling mode */ +#define PDMA_TX_POLLING (1 << 1) + /*! Rx batch refilling */ +#define PDMA_RX_BATCHING (1 << 2) + /*! DMA chain mode */ +#define PDMA_CHAIN_MODE (1 << 3) + /*! Descriptor prefetch mode */ +#define PDMA_DESC_PREFETCH (1 << 4) + /*! VNET is docked */ +#define PDMA_VNET_DOCKED (1 << 5) + + /*! Device mode */ + dev_mode_t mode; + + /*! Device is started */ + int started; + + /*! Device is initialized and HMI driver is attached */ + int attached; +}; + +/*! + * \brief Initialize device. + * + * \param [in] dev Device structure point. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_dev_init(struct pdma_dev *dev); + +/*! + * \brief Clean up device. + * + * \param [in] dev Device structure point. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_dev_cleanup(struct pdma_dev *dev); + +/*! + * \brief Start device. + * + * \param [in] dev Device structure point. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_dev_start(struct pdma_dev *dev); + +/*! + * \brief Stop device. + * + * \param [in] dev Device structure point. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_dev_stop(struct pdma_dev *dev); + +/*! + * \brief Suspend device. + * + * \param [in] dev Device structure point. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_dev_suspend(struct pdma_dev *dev); + +/*! + * \brief Resume device. + * + * \param [in] dev Device structure point. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_dev_resume(struct pdma_dev *dev); + +/*! + * \brief Suspend device Rx. + * + * \param [in] dev Device structure point. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_dev_rx_suspend(struct pdma_dev *dev); + +/*! + * \brief Resume device Rx. + * + * \param [in] dev Device structure point. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_dev_rx_resume(struct pdma_dev *dev); + +/*! + * \brief Dock device. + * + * \param [in] dev Device structure point. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_dev_dock(struct pdma_dev *dev); + +/*! + * \brief Undock device. + * + * \param [in] dev Device structure point. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_dev_undock(struct pdma_dev *dev); + +/*! + * \brief Get device information. + * + * \param [in] dev Device structure point. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_dev_info_get(struct pdma_dev *dev); + +/*! + * \brief Get device statistics. + * + * \param [in] dev Device structure point. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_dev_stats_get(struct pdma_dev *dev); + +/*! + * \brief Reset device statistics. + * + * \param [in] dev Device structure point. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_dev_stats_reset(struct pdma_dev *dev); + +/*! + * \brief Change queue number to channel number. + * + * \param [in] dev Device structure point. + * \param [in] queue Queue number. + * \param [in] dir Transmit direction. + * \param [out] chan Channel number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_dev_queue_to_chan(struct pdma_dev *dev, int queue, int dir, int *chan); + +/*! + * \brief Change channel number to queue number. + * + * \param [in] dev Device structure point. + * \param [in] chan Channel number. + * \param [out] queue Queue number. + * \param [out] dir Transmit direction. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_dev_chan_to_queue(struct pdma_dev *dev, int chan, int *queue, int *dir); + +/*! + * \brief Enable Rx queue interrupt. + * + * \param [in] dev Device structure point. + * \param [in] queue Rx queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_rx_queue_intr_enable(struct pdma_dev *dev, int queue); + +/*! + * \brief Disable Rx queue interrupt. + * + * \param [in] dev Device structure point. + * \param [in] queue Rx queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_rx_queue_intr_disable(struct pdma_dev *dev, int queue); + +/*! + * \brief Acknowledge Rx queue interrupt. + * + * \param [in] dev Device structure point. + * \param [in] queue Rx queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_rx_queue_intr_ack(struct pdma_dev *dev, int queue); + +/*! + * \brief Check Rx queue interrupt. + * + * \param [in] dev Device structure point. + * \param [in] queue Rx queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_rx_queue_intr_check(struct pdma_dev *dev, int queue); + +/*! + * \brief Enable Tx queue interrupt. + * + * \param [in] dev Device structure point. + * \param [in] queue Tx queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_tx_queue_intr_enable(struct pdma_dev *dev, int queue); + +/*! + * \brief Disable Tx queue interrupt. + * + * \param [in] dev Device structure point. + * \param [in] queue Tx queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_tx_queue_intr_disable(struct pdma_dev *dev, int queue); + +/*! + * \brief Acknowledge Tx queue interrupt. + * + * \param [in] dev Device structure point. + * \param [in] queue Tx queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_tx_queue_intr_ack(struct pdma_dev *dev, int queue); + +/*! + * \brief Check Tx queue interrupt. + * + * \param [in] dev Device structure point. + * \param [in] queue Tx queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_tx_queue_intr_check(struct pdma_dev *dev, int queue); + +/*! + * \brief Enable queue interrupt. + * + * \param [in] dev Device structure point. + * \param [in] hdl Queue interrupt handle. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_queue_intr_enable(struct pdma_dev *dev, struct intr_handle *hdl); + +/*! + * \brief Disable queue interrupt. + * + * \param [in] dev Device structure point. + * \param [in] hdl Queue interrupt handle. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_queue_intr_disable(struct pdma_dev *dev, struct intr_handle *hdl); + +/*! + * \brief Acknowledge queue interrupt. + * + * \param [in] dev Device structure point. + * \param [in] hdl Queue interrupt handle. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_queue_intr_ack(struct pdma_dev *dev, struct intr_handle *hdl); + +/*! + * \brief Check queue interrupt. + * + * \param [in] dev Device structure point. + * \param [in] hdl Queue interrupt handle. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_queue_intr_check(struct pdma_dev *dev, struct intr_handle *hdl); + +/*! + * \brief Enable group interrupt. + * + * \param [in] dev Device structure point. + * \param [in] group Group number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_group_intr_enable(struct pdma_dev *dev, int group); + +/*! + * \brief Disable group interrupt. + * + * \param [in] dev Device structure point. + * \param [in] group Group number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_group_intr_disable(struct pdma_dev *dev, int group); + +/*! + * \brief Acknowledge group interrupt. + * + * \param [in] dev Device structure point. + * \param [in] group Group number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_group_intr_ack(struct pdma_dev *dev, int group); + +/*! + * \brief Check group interrupt. + * + * \param [in] dev Device structure point. + * \param [in] group Group number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_group_intr_check(struct pdma_dev *dev, int group); + +/*! + * \brief Poll Rx queue. + * + * \param [in] dev Device structure point. + * \param [in] queue Rx queue number. + * \param [in] budget Poll budget. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_rx_queue_poll(struct pdma_dev *dev, int queue, int budget); + +/*! + * \brief Poll Tx queue. + * + * \param [in] dev Device structure point. + * \param [in] queue Tx queue number. + * \param [in] budget Poll budget. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_tx_queue_poll(struct pdma_dev *dev, int queue, int budget); + +/*! + * \brief Poll queue. + * + * \param [in] dev Device structure point. + * \param [in] hdl Queue interrupt handle. + * \param [in] budget Poll budget. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_queue_poll(struct pdma_dev *dev, struct intr_handle *hdl, int budget); + +/*! + * \brief Poll group. + * + * \param [in] dev Device structure point. + * \param [in] group Group number. + * \param [in] budget Poll budget. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_group_poll(struct pdma_dev *dev, int group, int budget); + +#endif /* BCMCNET_CORE_H */ + diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_dev.h b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_dev.h new file mode 100644 index 000000000000..bc3367b34fae --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_dev.h @@ -0,0 +1,544 @@ +/*! \file bcmcnet_dev.h + * + * Generic data structure and macro definitions for BCMCNET device. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#ifndef BCMCNET_DEV_H +#define BCMCNET_DEV_H + +#include + +/*! + * \brief HW information. + */ +struct hw_info { + /*! HW name */ + char *name; + + /*! HW version */ + int ver_no; + + /*! Device ID */ + uint32_t dev_id; + + /*! Revision ID */ + uint32_t rev_id; + + /*! Number of CMCs */ + uint32_t num_cmcs; + + /*! Number of CMC channels */ + uint32_t cmc_chans; + + /*! Number of channels */ + uint32_t num_chans; + + /*! Rx DCB size */ + uint32_t rx_dcb_size; + + /*! Tx DCB size */ + uint32_t tx_dcb_size; + + /*! Rx packet header size */ + uint32_t rx_ph_size; + + /*! Tx packet header size */ + uint32_t tx_ph_size; + + /*! HW structure point */ + struct pdma_hw *hw; +}; + +/*! + * \brief Read 32-bit register. + * + * \param [in] hw Pointer to hardware structure. + * \param [in] addr Register address. + * \param [in] data Pointer to read data. + */ +typedef void (*reg_rd32_f)(struct pdma_hw *hw, uint32_t addr, uint32_t *data); + +/*! + * \brief Write 32-bit register. + * + * \param [in] hw Pointer to hardware structure. + * \param [in] addr Register address. + * \param [in] data Data to write. + */ +typedef void (*reg_wr32_f)(struct pdma_hw *hw, uint32_t addr, uint32_t data); + +/*! + * \brief Pre-initialize hardware. + * + * \param [in] hw Pointer to hardware structure. + * + * \retval SHR_E_NONE No errors. + */ +typedef int (*pre_init_f)(struct pdma_hw *hw); + +/*! + * \brief Initialize hardware. + * + * \param [in] hw Pointer to hardware structure. + * + * \retval SHR_E_NONE No errors. + */ +typedef int (*hw_init_f)(struct pdma_hw *hw); + +/*! + * \brief Configure hardware. + * + * \param [in] hw Pointer to hardware structure. + * + * \retval SHR_E_NONE No errors. + */ +typedef int (*hw_config_f)(struct pdma_hw *hw); + +/*! + * \brief Reset hardware. + * + * \param [in] hw Pointer to hardware structure. + * + * \retval SHR_E_NONE No errors. + */ +typedef int (*hw_reset_f)(struct pdma_hw *hw); + +/*! + * \brief Start channel. + * + * \param [in] hw Pointer to hardware structure. + * \param [in] chan Channel number. + * + * \retval SHR_E_NONE No errors. + */ +typedef int (*chan_start_f)(struct pdma_hw *hw, int chan); + +/*! + * \brief Stop channel. + * + * \param [in] hw Pointer to hardware structure. + * \param [in] chan Channel number. + * + * \retval SHR_E_NONE No errors. + */ +typedef int (*chan_stop_f)(struct pdma_hw *hw, int chan); + +/*! + * \brief Set up channel. + * + * \param [in] hw Pointer to hardware structure. + * \param [in] chan Channel number. + * \param [in] addr Start DMA address of descriptors. + * + * \retval SHR_E_NONE No errors. + */ +typedef int (*chan_setup_f)(struct pdma_hw *hw, int chan, uint64_t addr); + +/*! + * \brief Go to ohter descriptor. + * + * \param [in] hw Pointer to hardware structure. + * \param [in] chan Channel number. + * \param [in] addr Destination DMA address of descriptors. + * + * \retval SHR_E_NONE No errors. + */ +typedef int (*chan_goto_f)(struct pdma_hw *hw, int chan, uint64_t addr); + +/*! + * \brief Clear channel. + * + * \param [in] hw Pointer to hardware structure. + * \param [in] chan Channel number. + * + * \retval SHR_E_NONE No errors. + */ +typedef int (*chan_clear_f)(struct pdma_hw *hw, int chan); + +/*! + * \brief Get interrupt number. + * + * \param [in] hw Pointer to hardware structure. + * \param [in] chan Channel number. + * + * \retval Returned interrupt number, errors if negative value. + */ +typedef int (*chan_intr_num_get_f)(struct pdma_hw *hw, int chan); + +/*! + * \brief Enable interrupt. + * + * \param [in] hw Pointer to hardware structure. + * \param [in] chan Channel number. + * + * \retval SHR_E_NONE No errors. + */ +typedef int (*chan_intr_enable_f)(struct pdma_hw *hw, int chan); + +/*! + * \brief Disable interrupt. + * + * \param [in] hw Pointer to hardware structure. + * \param [in] chan Channel number. + * + * \retval SHR_E_NONE No errors. + */ +typedef int (*chan_intr_disable_f)(struct pdma_hw *hw, int chan); + +/*! + * \brief Query interrupt. + * + * \param [in] hw Pointer to hardware structure. + * \param [in] chan Channel number. + * + * \retval SHR_E_NONE No errors. + */ +typedef int (*chan_intr_query_f)(struct pdma_hw *hw, int chan); + +/*! + * \brief Check interrupt. + * + * \param [in] hw Pointer to hardware structure. + * \param [in] chan Channel number. + * + * \retval SHR_E_NONE No errors. + */ +typedef int (*chan_intr_check_f)(struct pdma_hw *hw, int chan); + +/*! + * \brief Coalesce interrupt. + * + * \param [in] hw Pointer to hardware structure. + * \param [in] chan Channel number. + * \param [in] count Count value to trigger interrupt. + * \param [in] timer Timer value to triggre interrupt. + * + * \retval SHR_E_NONE No errors. + */ +typedef int (*chan_intr_coalesce_f)(struct pdma_hw *hw, int chan, int count, int timer); + +/*! + * \brief Dump registers. + * + * \param [in] hw Pointer to hardware structure. + * \param [in] chan Channel number. + * + * \retval SHR_E_NONE No errors. + */ +typedef int (*chan_reg_dump_f)(struct pdma_hw *hw, int chan); + +/*! + * \brief HW handlers. + */ +struct hw_handlers { + /*! 32 bits register read */ + reg_rd32_f reg_rd32; + + /*! 32 bits register write */ + reg_wr32_f reg_wr32; + + /*! HW pre-initialize */ + pre_init_f pre_init; + + /*! HW initialize */ + hw_init_f hw_init; + + /*! HW configure */ + hw_config_f hw_config; + + /*! HW reset */ + hw_reset_f hw_reset; + + /*! Channel start */ + chan_start_f chan_start; + + /*! Channel stop */ + chan_stop_f chan_stop; + + /*! Channel setup */ + chan_setup_f chan_setup; + + /*! Channel goto */ + chan_goto_f chan_goto; + + /*! Channel clear */ + chan_clear_f chan_clear; + + /*! Channel interrupt number get */ + chan_intr_num_get_f chan_intr_num_get; + + /*! Channel interrupt enable */ + chan_intr_enable_f chan_intr_enable; + + /*! Channel interrupt disable */ + chan_intr_disable_f chan_intr_disable; + + /*! Channel interrupt query */ + chan_intr_query_f chan_intr_query; + + /*! Channel interrupt check */ + chan_intr_check_f chan_intr_check; + + /*! Channel interrupt coalesce */ + chan_intr_coalesce_f chan_intr_coalesce; + + /*! Channel registers dump */ + chan_reg_dump_f chan_reg_dump; +}; + +/*! + * \brief Initialize Rx descriptor. + * + * \param [in] hw Pointer to hardware structure. + * \param [in] rxq Pointer to Rx queue struture. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_MEMORY Allocation failed. + */ +typedef int (*rx_desc_init_f)(struct pdma_hw *hw, struct pdma_rx_queue *rxq); + +/*! + * \brief Clean up Rx descriptor. + * + * \param [in] hw Pointer to hardware structure. + * \param [in] rxq Pointer to Rx queue struture. + * + * \retval SHR_E_NONE No errors. + */ +typedef int (*rx_desc_clean_f)(struct pdma_hw *hw, struct pdma_rx_queue *rxq); + +/*! + * \brief Clean up Rx ring. + * + * \param [in] hw Pointer to hardware structure. + * \param [in] rxq Pointer to Rx queue struture. + * \param [in] budget Budget for each operation. + * + * \retval Number of descriptors finished. + */ +typedef int (*rx_ring_clean_f)(struct pdma_hw *hw, struct pdma_rx_queue *rxq, int budget); + +/*! + * \brief Dump Rx ring. + * + * \param [in] hw Pointer to hardware structure. + * \param [in] rxq Pointer to Rx queue struture. + * + * \retval SHR_E_NONE No errors. + */ +typedef int (*rx_ring_dump_f)(struct pdma_hw *hw, struct pdma_rx_queue *rxq); + +/*! + * \brief Suspend Rx queue. + * + * \param [in] hw Pointer to hardware structure. + * \param [in] rxq Pointer to Rx queue struture. + * + * \retval SHR_E_NONE No errors. + */ +typedef int (*rx_suspend_f)(struct pdma_hw *hw, struct pdma_rx_queue *rxq); + +/*! + * \brief Resume Rx queue. + * + * \param [in] hw Pointer to hardware structure. + * \param [in] rxq Pointer to Rx queue struture. + * + * \retval SHR_E_NONE No errors. + */ +typedef int (*rx_resume_f)(struct pdma_hw *hw, struct pdma_rx_queue *rxq); + +/*! + * \brief Initialize Tx descriptor. + * + * \param [in] hw Pointer to hardware structure. + * \param [in] txq Pointer to Tx queue struture. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_MEMORY Allocation failed. + */ +typedef int (*tx_desc_init_f)(struct pdma_hw *hw, struct pdma_tx_queue *txq); + +/*! + * \brief Clean up Tx descriptor. + * + * \param [in] hw Pointer to hardware structure. + * \param [in] txq Pointer to Tx queue struture. + * + * \retval SHR_E_NONE No errors. + */ +typedef int (*tx_desc_clean_f)(struct pdma_hw *hw, struct pdma_tx_queue *txq); + +/*! + * \brief Clean up Tx ring. + * + * \param [in] hw Pointer to hardware structure. + * \param [in] txq Pointer to Tx queue struture. + * \param [in] budget Budget for each operation. + * + * \retval Number of descriptors finished. + */ +typedef int (*tx_ring_clean_f)(struct pdma_hw *hw, struct pdma_tx_queue *txq, int budget); + +/*! + * \brief Dump Tx ring. + * + * \param [in] hw Pointer to hardware structure. + * \param [in] txq Pointer to Tx queue struture. + * + * \retval SHR_E_NONE No errors. + */ +typedef int (*tx_ring_dump_f)(struct pdma_hw *hw, struct pdma_tx_queue *txq); + +/*! + * \brief Transmit packet. + * + * \param [in] hw Pointer to hardware structure. + * \param [in] txq Pointer to Tx queue struture. + * \param [in] buf Pointer to packet buffer struture. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +typedef int (*pkt_xmit_f)(struct pdma_hw *hw, struct pdma_tx_queue *txq, void *buf); + +/*! + * \brief Descriptor operations. + */ +struct desc_operations { + /*! Rx descriptor initialize */ + rx_desc_init_f rx_desc_init; + + /*! Rx descriptor cleanup */ + rx_desc_clean_f rx_desc_clean; + + /*! Rx ring cleanup */ + rx_ring_clean_f rx_ring_clean; + + /*! Rx ring dump */ + rx_ring_dump_f rx_ring_dump; + + /*! Rx suspend */ + rx_suspend_f rx_suspend; + + /*! Rx resume */ + rx_resume_f rx_resume; + + /*! Tx descriptor initialize */ + tx_desc_init_f tx_desc_init; + + /*! Tx descriptor cleanup */ + tx_desc_clean_f tx_desc_clean; + + /*! Tx ring cleanup */ + tx_ring_clean_f tx_ring_clean; + + /*! Tx ring dump */ + tx_ring_dump_f tx_ring_dump; + + /*! Tx transmit */ + pkt_xmit_f pkt_xmit; +}; + +/*! + * \brief HW structure. + */ +struct pdma_hw { + /*! Device number */ + int unit; + + /*! Device structure point */ + struct pdma_dev *dev; + + /*! HW information */ + struct hw_info info; + + /*! HW handlers */ + struct hw_handlers hdls; + + /*! HW operations */ + struct desc_operations dops; +}; + +/*! + * \brief Open device. + * + * \param [in] dev Device structure point. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_open(struct pdma_dev *dev); + +/*! + * \brief Coalesce Rx interrupt. + * + * \param [in] dev Device structure point. + * \param [in] queue Rx queue number. + * \param [in] count Interrupt threshhold. + * \param [in] timer Timer value. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_rx_queue_int_coalesce(struct pdma_dev *dev, int queue, int count, int timer); + +/*! + * \brief Coalesce Tx interrupt. + * + * \param [in] dev Device structure point. + * \param [in] queue Tx queue number. + * \param [in] count Interrupt threshhold. + * \param [in] timer Timer value. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_tx_queue_int_coalesce(struct pdma_dev *dev, int queue, int count, int timer); + +/*! + * \brief Dump Rx queue registers. + * + * \param [in] dev Device structure point. + * \param [in] queue Rx queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_rx_queue_reg_dump(struct pdma_dev *dev, int queue); + +/*! + * \brief Dump Tx queue registers. + * + * \param [in] dev Device structure point. + * \param [in] queue Tx queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_tx_queue_reg_dump(struct pdma_dev *dev, int queue); + +#endif /* BCMCNET_DEV_H */ + diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_internal.h b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_internal.h new file mode 100644 index 000000000000..e4b2051a34bc --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_internal.h @@ -0,0 +1,305 @@ +/*! \file bcmcnet_internal.h + * + * BCMCNET internal data structure and macro definitions. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#ifndef BCMCNET_INTERNAL_H +#define BCMCNET_INTERNAL_H + +#include + +/*! CMICD name */ +#define CMICD_DEV_NAME "cmicd" + +/*! CMICX name */ +#define CMICX_DEV_NAME "cmicx" + +/*! + * \brief Allocate descriptor ring buffer. + * + * \param [in] dev Pointer to Packet DMA device. + * \param [in] dma DMA address of ring buffer. + * + * \retval Pointer to DMA buffer or NULL if an error occurred. + */ +typedef void *(*ring_buf_alloc_f)(struct pdma_dev *dev, uint32_t, dma_addr_t *dma); + +/*! + * \brief Free descriptor ring buffer. + * + * \param [in] dev Pointer to Packet DMA device. + * \param [in] size Size of DMA buffer. + * \param [in] mem Pointer to DMA buffer. + * \param [in] dma DMA address of ring buffer. + */ +typedef void (*ring_buf_free_f)(struct pdma_dev *dev, uint32_t size, void *mem, + dma_addr_t dma); + +/*! + * \brief Allocate Rx packet buffer. + * + * \param [in] dev Pointer to Packet DMA device. + * \param [in] rxq Pointer to Rx queue struture. + * \param [in] pbuf Pointer to packet buffer structure. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_MEMORY Allocation failed. + */ +typedef int (*rx_buf_alloc_f)(struct pdma_dev *dev, struct pdma_rx_queue *rxq, + struct pdma_rx_buf *pbuf); + +/*! + * \brief Get Rx packet buffer DMA address. + * + * \param [in] dev Pointer to Packet DMA device. + * \param [in] rxq Pointer to Rx queue struture. + * \param [in] pbuf Pointer to packet buffer structure. + * \param [in] dma DMA address of packet buffer. + */ +typedef void (*rx_buf_dma_f)(struct pdma_dev *dev, struct pdma_rx_queue *rxq, + struct pdma_rx_buf *pbuf, dma_addr_t *dma); + +/*! + * \brief Check Rx packet buffer validity. + * + * \param [in] dev Pointer to Packet DMA device. + * \param [in] rxq Pointer to Rx queue struture. + * \param [in] pbuf Pointer to packet buffer structure. + * + * \retval Ture Buffer is available or FALSE. + */ +typedef int (*rx_buf_avail_f)(struct pdma_dev *dev, struct pdma_rx_queue *rxq, + struct pdma_rx_buf *pbuf); + +/*! + * \brief Get Rx packet buffer. + * + * \param [in] dev Pointer to Packet DMA device. + * \param [in] rxq Pointer to Rx queue struture. + * \param [in] pbuf Pointer to packet buffer structure. + * \param [in] len Packet length. + * + * \retval Pointer to packet header structure or NULL if failed. + */ +typedef struct pkt_hdr *(*rx_buf_get_f)(struct pdma_dev *dev, struct pdma_rx_queue *rxq, + struct pdma_rx_buf *pbuf, int len); + +/*! + * \brief Put Rx packet buffer. + * + * \param [in] dev Pointer to Packet DMA device. + * \param [in] rxq Pointer to Rx queue struture. + * \param [in] pbuf Pointer to packet buffer structure. + * \param [in] len Packet length. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_MEMORY Allocation failed. + */ +typedef int (*rx_buf_put_f)(struct pdma_dev *dev, struct pdma_rx_queue *rxq, + struct pdma_rx_buf *pbuf, int len); + +/*! + * \brief Free Rx packet buffer. + * + * \param [in] dev Pointer to Packet DMA device. + * \param [in] rxq Pointer to Rx queue struture. + * \param [in] pbuf Pointer to packet buffer structure. + */ +typedef void (*rx_buf_free_f)(struct pdma_dev *dev, struct pdma_rx_queue *rxq, + struct pdma_rx_buf *pbuf); + +/*! + * \brief Get Rx packet buffer mode. + * + * \param [in] dev Pointer to Packet DMA device. + * \param [in] rxq Pointer to Rx queue struture. + * + * \retval Buffer mode. + */ +typedef enum buf_mode (*rx_buf_mode_f)(struct pdma_dev *dev, struct pdma_rx_queue *rxq); + +/*! + * \brief Get Tx packet buffer. + * + * \param [in] dev Pointer to Packet DMA device. + * \param [in] txq Pointer to Rx queue struture. + * \param [in] pbuf Pointer to packet buffer structure. + * \param [in] buf Packet buffer. + * + * \retval Pointer to packet header structure or NULL if failed. + */ +typedef struct pkt_hdr *(*tx_buf_get_f)(struct pdma_dev *dev, struct pdma_tx_queue *txq, + struct pdma_tx_buf *pbuf, void *buf); + +/*! + * \brief Get Tx packet buffer DMA address. + * + * \param [in] dev Pointer to Packet DMA device. + * \param [in] txq Pointer to Rx queue struture. + * \param [in] pbuf Pointer to packet buffer structure. + * \param [in] dma DMA address of packet buffer. + */ +typedef void (*tx_buf_dma_f)(struct pdma_dev *dev, struct pdma_tx_queue *txq, + struct pdma_tx_buf *pbuf, dma_addr_t *dma); + +/*! + * \brief Free Tx packet buffer. + * + * \param [in] dev Pointer to Packet DMA device. + * \param [in] txq Pointer to Rx queue struture. + * \param [in] pbuf Pointer to packet buffer structure. + */ +typedef void (*tx_buf_free_f)(struct pdma_dev *dev, struct pdma_tx_queue *txq, + struct pdma_tx_buf *pbuf); + +/*! + * \brief Buffer manager. + */ +struct pdma_buf_mngr { + /*! Allocate descriptor ring buffer */ + ring_buf_alloc_f ring_buf_alloc; + + /*! Free descriptor ring buffer */ + ring_buf_free_f ring_buf_free; + + /*! Allocate Rx packet buffer */ + rx_buf_alloc_f rx_buf_alloc; + + /*! Get Rx packet buffer DMA address */ + rx_buf_dma_f rx_buf_dma; + + /*! Check Rx packet buffer validity */ + rx_buf_avail_f rx_buf_avail; + + /*! Get Rx packet buffer */ + rx_buf_get_f rx_buf_get; + + /*! Put Rx packet buffer */ + rx_buf_put_f rx_buf_put; + + /*! Free Rx packet buffer */ + rx_buf_free_f rx_buf_free; + + /*! Get Rx packet buffer mode */ + rx_buf_mode_f rx_buf_mode; + + /*! Get Tx packet buffer */ + tx_buf_get_f tx_buf_get; + + /*! Get Tx packet buffer DMA address */ + tx_buf_dma_f tx_buf_dma; + + /*! Free Tx packet buffer */ + tx_buf_free_f tx_buf_free; +}; + +/*! + * \brief Wait for the kernel networking subsystem. + * + * \param [in] unit Device number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_FAIL Operation failed. + */ +typedef int (*bcmcnet_vnet_wait_f)(int unit); + +/*! + * \brief Wake up the kernel networking subsystem. + * + * \param [in] unit Device number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_FAIL Operation failed. + */ +typedef int (*bcmcnet_hnet_wake_f)(int unit); + +/*! + * \brief Dock to the kernel networking subsystem. + * + * \param [in] unit Device number. + * \param [in] vsync Sync data. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_FAIL Operation failed. + */ +typedef int (*bcmcnet_vnet_dock_f)(int unit, vnet_sync_t *vsync); + +/*! + * \brief Undock from the kernel networking subsystem. + * + * \param [in] unit Device number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_FAIL Operation failed. + */ +typedef int (*bcmcnet_vnet_undock_f)(int unit); + +/*! + * \brief VNET operations. + */ +typedef struct bcmcnet_vnet_ops_s { + /*! + * VNET wait for HNET. + * VNET calls this to wait for any notification from HNET. + */ + bcmcnet_vnet_wait_f vnet_wait; + + /*! + * VNET wake up HNET. + * VNET calls this to notify HNET that Tx/Rx is ready. + */ + bcmcnet_hnet_wake_f hnet_wake; + + /*! + * VNET dock to HNET. + * This is called to notify HNET that VNET is ready to work and synchronize + * vrings information to HNET. + */ + bcmcnet_vnet_dock_f vnet_dock; + + /*! + * VNET undock from HNET. + * This is called to notify HNET that VNET is ready to leave. + */ + bcmcnet_vnet_undock_f vnet_undock; +} bcmcnet_vnet_ops_t; + +/*! + * \brief Initialize buffer manager. + * + * \param [in] dev Device structure pointer. + */ +extern void +bcmcnet_buf_mngr_init(struct pdma_dev *dev); + +/*! + * \brief Register VNET operations. + * + * \param [in] unit Device number. + * \param [in] vnet_ops VNET operations. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_PARAM Invalid parameters. + */ +extern int +bcmcnet_vnet_ops_register(int unit, bcmcnet_vnet_ops_t *vnet_ops); + +#endif /* BCMCNET_INTERNAL_H */ + diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_rxtx.h b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_rxtx.h new file mode 100644 index 000000000000..eb5834d895b0 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_rxtx.h @@ -0,0 +1,512 @@ +/*! \file bcmcnet_rxtx.h + * + * Generic data structure and macro definitions for BCMCNET Rx/Tx. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#ifndef BCMCNET_RXTX_H +#define BCMCNET_RXTX_H + +/*! Default descriptor number in each ring */ +#define NUM_RING_DESC 64 + +/*! Maximum number of packets to be handled in one poll call */ +#define NUM_RXTX_BUDGET 64 + +/*! + * \brief Rx buffer mode definitions. + */ +enum buf_mode { + /*! Private DMA buffer in user space */ + PDMA_BUF_MODE_PRIV, + + /*! SKB in kernel */ + PDMA_BUF_MODE_SKB, + + /*! Paged buffer in kernel */ + PDMA_BUF_MODE_PAGE, + + /*! Kernel buffer mapped to user space */ + PDMA_BUF_MODE_MAPPED, + + /*! MAX mode */ + PDMA_BUF_MODE_MAX +}; + +/*! + * \brief Rx queue statistics. + */ +struct rx_stats { + /*! Number of received packets */ + uint64_t packets; + + /*! Number of received bytes */ + uint64_t bytes; + + /*! Number of dropped packets */ + uint64_t dropped; + + /*! Number of errors */ + uint64_t errors; + + /*! Number of head errors */ + uint64_t head_errors; + + /*! Number of data errors */ + uint64_t data_errors; + + /*! Number of cell errors */ + uint64_t cell_errors; + + /*! Number of failed allocation */ + uint64_t nomems; +}; + +/*! + * Rx queue structure + */ +struct pdma_rx_queue { + /*! Group index to which this queue belongs */ + uint32_t group_id; + + /*! Global channel index */ + uint32_t chan_id; + + /*! Queue index */ + uint32_t queue_id; + + /*! Pointer to the device control structure */ + struct dev_ctrl *ctrl; + + /*! Rx packet buffer pointers */ + struct pdma_rx_buf *pbuf; + + /*! Rx ring address */ + void *ring; + + /*! Rx ring DMA address */ + dma_addr_t ring_addr; + + /*! Rx ring DMA halt address */ + dma_addr_t halt_addr; + + /*! Rx buffer size */ + uint32_t buf_size; + + /*! Total number of descriptors */ + uint32_t nb_desc; + + /*! Next free ring entry */ + uint32_t curr; + + /*! Halt ring entry */ + uint32_t halt; + + /*! Max free descriptors to hold */ + uint32_t free_thresh; + + /*! Rx interrupt coalesce value */ + uint32_t ic_val; + + /*! Rx interrupt coalescing */ + int intr_coalescing; + + /*! Queue statistics */ + struct rx_stats stats; + + /*! Rx queue spin lock */ + sal_spinlock_t lock; + + /*! Queue state */ + int state; + /*! Queue is used */ +#define PDMA_RX_QUEUE_USED (1 << 0) + /*! Queue is setup */ +#define PDMA_RX_QUEUE_SETUP (1 << 1) + /*! Queue is active */ +#define PDMA_RX_QUEUE_ACTIVE (1 << 2) + /*! Queue is busy */ +#define PDMA_RX_QUEUE_BUSY (1 << 3) + /*! Queue is suspended */ +#define PDMA_RX_QUEUE_XOFF (1 << 4) + /*! Queue is batch refilled */ +#define PDMA_RX_BATCH_REFILL (1 << 5) + + /*! DMA buffer mode */ + enum buf_mode mode; +}; + +/*! + * \brief Tx queue statistics. + */ +struct tx_stats { + /*! Number of sent packets */ + uint64_t packets; + + /*! Number of sent bytes */ + uint64_t bytes; + + /*! Number of dropped packets */ + uint64_t dropped; + + /*! Number of errors */ + uint64_t errors; + + /*! Number of suspends */ + uint64_t xoffs; +}; + +/*! + * \brief Tx queue structure. + */ +struct pdma_tx_queue { + /*! Group index to which this queue belongs */ + uint32_t group_id; + + /*! Global channel index */ + uint32_t chan_id; + + /*! Queue index */ + uint32_t queue_id; + + /*! pointer to the device control structure */ + struct dev_ctrl *ctrl; + + /*! Tx packet buffer pointers */ + struct pdma_tx_buf *pbuf; + + /*! Tx ring address */ + void *ring; + + /*! Tx ring DMA address */ + dma_addr_t ring_addr; + + /*! Tx ring DMA halt address */ + dma_addr_t halt_addr; + + /*! Total number of descriptors */ + uint32_t nb_desc; + + /*! Next free ring entry */ + uint32_t curr; + + /*! First entry to be transmitted */ + uint32_t dirt; + + /*! Halt ring entry */ + uint32_t halt; + + /*! Max free descriptors to hold in non-intr mode */ + uint32_t free_thresh; + + /*! Tx interrupt coalesce value */ + uint32_t ic_val; + + /*! Tx interrupt coalescing */ + int intr_coalescing; + + /*! Queue statistics */ + struct tx_stats stats; + + /*! Tx queue spin lock */ + sal_spinlock_t lock; + + /*! Tx mutex spin lock */ + sal_spinlock_t mutex; + + /*! Tx mutex and flow control semaphore */ + sal_sem_t sem; + + /*! Queue state */ + int state; + /*! Queue is used */ +#define PDMA_TX_QUEUE_USED (1 << 0) + /*! Queue is setup */ +#define PDMA_TX_QUEUE_SETUP (1 << 1) + /*! Queue is active */ +#define PDMA_TX_QUEUE_ACTIVE (1 << 2) + /*! Queue is setup */ +#define PDMA_TX_QUEUE_BUSY (1 << 3) + /*! Queue is suspended */ +#define PDMA_TX_QUEUE_XOFF (1 << 4) + /*! Queue is poll mode */ +#define PDMA_TX_QUEUE_POLL (1 << 5) + + /*! DMA buffer mode */ + enum buf_mode mode; +}; + +/*! + * \brief Setup Rx queue. + * + * \param [in] dev Device structure point. + * \param [in] queue Rx queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_rx_queue_setup(struct pdma_dev *dev, int queue); + +/*! + * \brief Release Rx queue. + * + * \param [in] dev Device structure point. + * \param [in] queue Rx queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_rx_queue_release(struct pdma_dev *dev, int queue); + +/*! + * \brief Restore Rx queue. + * + * \param [in] dev Device structure point. + * \param [in] queue Rx queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_rx_queue_restore(struct pdma_dev *dev, int queue); + +/*! + * \brief Setup virtual Rx queue. + * + * \param [in] dev Device structure point. + * \param [in] queue Rx queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_rx_vqueue_setup(struct pdma_dev *dev, int queue); + +/*! + * \brief Release virtual Rx queue. + * + * \param [in] dev Device structure point. + * \param [in] queue Rx queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_rx_vqueue_release(struct pdma_dev *dev, int queue); + +/*! + * \brief Setup Tx queue. + * + * \param [in] dev Device structure point. + * \param [in] queue Tx queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_tx_queue_setup(struct pdma_dev *dev, int queue); + +/*! + * \brief Release Tx queue. + * + * \param [in] dev Device structure point. + * \param [in] queue Tx queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_tx_queue_release(struct pdma_dev *dev, int queue); + +/*! + * \brief Restore Tx queue. + * + * \param [in] dev Device structure point. + * \param [in] queue Tx queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_tx_queue_restore(struct pdma_dev *dev, int queue); + +/*! + * \brief Setup virtual Tx queue. + * + * \param [in] dev Device structure point. + * \param [in] queue Rx queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_tx_vqueue_setup(struct pdma_dev *dev, int queue); + +/*! + * \brief Release virtual Tx queue. + * + * \param [in] dev Device structure point. + * \param [in] queue Rx queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_tx_vqueue_release(struct pdma_dev *dev, int queue); + +/*! + * \brief Suspend Rx queue. + * + * \param [in] dev Device structure point. + * \param [in] queue Rx queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_rx_queue_suspend(struct pdma_dev *dev, int queue); + +/*! + * \brief Resume Rx queue. + * + * \param [in] dev Device structure point. + * \param [in] queue Rx queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_rx_queue_resume(struct pdma_dev *dev, int queue); + +/*! + * \brief Suspend Tx queue. + * + * \param [in] dev Device structure point. + * \param [in] queue Tx queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_tx_queue_suspend(struct pdma_dev *dev, int queue); + +/*! + * \brief Resume Tx queue. + * + * \param [in] dev Device structure point. + * \param [in] queue Tx queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_tx_queue_resume(struct pdma_dev *dev, int queue); + +/*! + * \brief Wakeup Tx queue. + * + * \param [in] dev Device structure point. + * \param [in] queue Tx queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_tx_queue_wakeup(struct pdma_dev *dev, int queue); + +/*! + * \brief Start Tx queue transmission. + * + * \param [in] dev Device structure point. + * \param [in] queue Tx queue number. + * \param [in] buf Tx packet buffer. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_tx_queue_xmit(struct pdma_dev *dev, int queue, void *buf); + +/*! + * \brief Poll Rx queue. + * + * \param [in] dev Device structure point. + * \param [in] queue Rx queue number. + * \param [in] budget Poll budget. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_rx_queue_poll(struct pdma_dev *dev, int queue, int budget); + +/*! + * \brief Poll Tx queue. + * + * \param [in] dev Device structure point. + * \param [in] queue Tx queue number. + * \param [in] budget Poll budget. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_tx_queue_poll(struct pdma_dev *dev, int queue, int budget); + +/*! + * \brief Poll queue group. + * + * \param [in] dev Device structure point. + * \param [in] group Group number. + * \param [in] budget Poll budget. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_group_poll(struct pdma_dev *dev, int group, int budget); + +/*! + * \brief Dump Rx ring. + * + * \param [in] dev Device structure point. + * \param [in] queue Rx queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_rx_ring_dump(struct pdma_dev *dev, int queue); + +/*! + * \brief Dump Tx ring. + * + * \param [in] dev Device structure point. + * \param [in] queue Tx queue number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +bcmcnet_pdma_tx_ring_dump(struct pdma_dev *dev, int queue); + +#endif /* BCMCNET_RXTX_H */ + diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_types.h b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_types.h new file mode 100644 index 000000000000..42bd9240828b --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_types.h @@ -0,0 +1,263 @@ +/*! \file bcmcnet_types.h + * + * BCMCNET public data structure and macro definitions. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#ifndef BCMCNET_TYPES_H +#define BCMCNET_TYPES_H + +#include + +/*! Maximum length of device name */ +#define DEV_NAME_LEN_MAX 16 + +/*! Maximum number of groups supported each device */ +#define NUM_GRP_MAX 4 + +/*! Maximum number of queues supported each group */ +#define NUM_Q_PER_GRP 8 + +/*! Maximum number of queues supported each device */ +#define NUM_QUE_MAX (NUM_GRP_MAX * NUM_Q_PER_GRP) + +/*! Maximum length of jumbo frame */ +#define JUMBO_FRAME_LEN_MAX 0xffff + +/*! Maximum Rx buffer size */ +#define RX_BUF_SIZE_MAX JUMBO_FRAME_LEN_MAX + +/*! Minimum Rx buffer size */ +#define RX_BUF_SIZE_MIN 68 + +/*! Default Rx buffer size */ +#define RX_BUF_SIZE_DFLT 9216 + +/*! + * \brief Transmission direction. + */ +enum pdma_dir { + PDMA_Q_RX = 0, + PDMA_Q_TX +}; + +/*! + * \brief Device information. + */ +typedef struct bcmcnet_dev_info { + /*! Device name */ + char dev_name[DEV_NAME_LEN_MAX]; + + /*! Device ID */ + uint32_t dev_id; + + /*! Device type */ + uint32_t dev_type; + + /*! Maximum number of groups */ + uint32_t max_groups; + + /*! Maximum number of queues */ + uint32_t max_queues; + + /*! Bitmap of groups at work */ + uint32_t bm_groups; + + /*! Bitmap of Rx queues at work */ + uint32_t bm_rx_queues; + + /*! Bitmap of Tx queues at work */ + uint32_t bm_tx_queues; + + /*! Number of groups at work */ + uint32_t nb_groups; + + /*! Number of Rx queues at work */ + uint32_t nb_rx_queues; + + /*! Number of Tx queues at work */ + uint32_t nb_tx_queues; + + /*! Rx descriptor size */ + uint32_t rx_desc_size; + + /*! Tx descriptor size */ + uint32_t tx_desc_size; + + /*! Rx packet header size */ + uint32_t rx_ph_size; + + /*! Tx packet header size */ + uint32_t tx_ph_size; + + /*! Rx buffer size */ + uint32_t rx_buf_dflt; + + /*! Number of descriptors for a queue */ + uint32_t nb_desc_dflt; + + /*! Rx buffer size per queue */ + uint32_t rx_buf_size[NUM_QUE_MAX]; + + /*! Number of Rx descriptors per queue */ + uint32_t nb_rx_desc[NUM_QUE_MAX]; + + /*! Number of Tx descriptors per queue */ + uint32_t nb_tx_desc[NUM_QUE_MAX]; +} bcmcnet_dev_info_t; + +/*! + * \brief Device statistics. + */ +typedef struct bcmcnet_dev_stats { + /*! Number of successfully received packets */ + uint64_t rx_packets; + + /*! Number of successfully received bytes */ + uint64_t rx_bytes; + + /*! Number of dropped packets */ + uint64_t rx_dropped; + + /*! Number of erroneous received packets */ + uint64_t rx_errors; + + /*! Number of error head packets */ + uint64_t rx_head_errors; + + /*! Number of error data packets */ + uint64_t rx_data_errors; + + /*! Number of error cell packets */ + uint64_t rx_cell_errors; + + /*! Number of RX pktbuf allocation failures */ + uint64_t rx_nomems; + + /*! Number of successfully transmitted packets */ + uint64_t tx_packets; + + /*! Number of successfully transmitted bytes */ + uint64_t tx_bytes; + + /*! Number of dropped packets */ + uint64_t tx_dropped; + + /*! Number of failed transmitted packets */ + uint64_t tx_errors; + + /*! Number of suspended transmission */ + uint64_t tx_xoffs; + + /*! Number of interrupts */ + uint64_t intrs; + + /*! Number of successfully received packets per queue */ + uint64_t rxq_packets[NUM_QUE_MAX]; + + /*! Number of successfully received bytes per queue */ + uint64_t rxq_bytes[NUM_QUE_MAX]; + + /*! Number of dropped packets per queue */ + uint64_t rxq_dropped[NUM_QUE_MAX]; + + /*! Number of erroneous received packets per queue */ + uint64_t rxq_errors[NUM_QUE_MAX]; + + /*! Number of error head packets per queue */ + uint64_t rxq_head_errors[NUM_QUE_MAX]; + + /*! Number of error data packets per queue */ + uint64_t rxq_data_errors[NUM_QUE_MAX]; + + /*! Number of error cell packets per queue */ + uint64_t rxq_cell_errors[NUM_QUE_MAX]; + + /*! Number of RX pktbuf allocation failures per queue */ + uint64_t rxq_nomems[NUM_QUE_MAX]; + + /*! Number of successfully transmitted bytes per queue */ + uint64_t txq_packets[NUM_QUE_MAX]; + + /*! Number of successfully transmitted bytes per queue */ + uint64_t txq_bytes[NUM_QUE_MAX]; + + /*! Number of dropped packets per queue */ + uint64_t txq_dropped[NUM_QUE_MAX]; + + /*! Number of failed transmitted packets per queue */ + uint64_t txq_errors[NUM_QUE_MAX]; + + /*! Number of suspended transmission per queue */ + uint64_t txq_xoffs[NUM_QUE_MAX]; +} bcmcnet_dev_stats_t; + +/*! + * \brief Device modes. + */ +typedef enum dev_mode_e { + /*! + * User network mode. + * The standalone CNET works in user space. + */ + DEV_MODE_UNET = 0, + + /*! + * Kernel network mode. + * Combined with KNET module, CNET works in kernel space. + */ + DEV_MODE_KNET, + + /*! + * Virtual network mode. + * CNET works in user space as a virtual network. + * The hypervisor must be deployed in KNET module. + */ + DEV_MODE_VNET, + + /*! + * Hyper network mode. + * Combined with KNET module, CNET works in kernel space as a hypervisor. + * The virtual network is not neccessary in this mode. + */ + DEV_MODE_HNET, + + /*! Maximum number of mode */ + DEV_MODE_MAX +} dev_mode_t; + +/*! + * \brief VNET sync data. + */ +typedef struct vnet_sync_s { + /*! Rx ring address */ + uint64_t rx_ring_addr[NUM_QUE_MAX]; + + /*! Rx ring size */ + uint32_t rx_ring_size[NUM_QUE_MAX]; + + /*! Tx ring address */ + uint64_t tx_ring_addr[NUM_QUE_MAX]; + + /*! Tx ring size */ + uint32_t tx_ring_size[NUM_QUE_MAX]; +} vnet_sync_t; + +#endif /* BCMCNET_TYPES_H */ + diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/main/bcmcnet_core.c b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/main/bcmcnet_core.c new file mode 100644 index 000000000000..ef4aca7da49e --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/main/bcmcnet_core.c @@ -0,0 +1,701 @@ +/*! \file bcmcnet_core.c + * + * Utility routines for BCMCNET driver. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include +#include + +/*! + * Initialize a device + */ +int +bcmcnet_pdma_dev_init(struct pdma_dev *dev) +{ + int rv; + + /* Open the device */ + rv = bcmcnet_pdma_open(dev); + if (SHR_FAILURE(rv)) { + return rv; + } + + dev->attached = 1; + + return SHR_E_NONE; +} + +/*! + * Clean up a device + */ +int +bcmcnet_pdma_dev_cleanup(struct pdma_dev *dev) +{ + if (!dev->attached) { + return SHR_E_NONE; + } + + dev->ops->dev_close(dev); + dev->ops = NULL; + + dev->attached = 0; + + return SHR_E_NONE; +} + +/*! + * Start a device + */ +int +bcmcnet_pdma_dev_start(struct pdma_dev *dev) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + uint32_t qi; + int rv; + + if (!dev->attached) { + return SHR_E_UNAVAIL; + } + + if (dev->started) { + return SHR_E_NONE; + } + + rv = dev->ops->dev_config(dev, ctrl->bm_rxq, ctrl->bm_txq); + if (SHR_FAILURE(rv)) { + return rv; + } + + /* Start all the Rx queues */ + for (qi = 0; qi < ctrl->nb_rxq; qi++) { + rv = dev->ops->rx_queue_setup(dev, qi); + if (SHR_FAILURE(rv)) { + return rv; + } + dev->ops->rx_queue_intr_enable(dev, qi); + dev->ops->rx_queue_start(dev, qi); + } + + /* Start all the Tx queues */ + for (qi = 0; qi < ctrl->nb_txq; qi++) { + dev->ops->tx_queue_setup(dev, qi); + dev->ops->tx_queue_intr_enable(dev, qi); + dev->ops->tx_queue_start(dev, qi); + dev->ops->tx_queue_wakeup(dev, qi); + } + + bcmcnet_pdma_dev_info_get(dev); + + dev->started = 1; + + return SHR_E_NONE; +} + +/*! + * Stop a device + */ +int +bcmcnet_pdma_dev_stop(struct pdma_dev *dev) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + uint32_t qi; + + if (!dev->attached) { + return SHR_E_UNAVAIL; + } + + if (!dev->started) { + return SHR_E_NONE; + } + + /* Stop all the Rx queues */ + for (qi = 0; qi < ctrl->nb_rxq; qi++) { + dev->ops->rx_queue_intr_disable(dev, qi); + dev->ops->rx_queue_stop(dev, qi); + dev->ops->rx_queue_release(dev, qi); + } + + /* Stop all the Tx queues */ + for (qi = 0; qi < ctrl->nb_txq; qi++) { + dev->ops->tx_queue_intr_disable(dev, qi); + dev->ops->tx_queue_stop(dev, qi); + dev->ops->tx_queue_wakeup(dev, qi); + dev->ops->tx_queue_release(dev, qi); + } + + dev->started = 0; + + return SHR_E_NONE; +} + +/*! + * Suspend a device + */ +int +bcmcnet_pdma_dev_suspend(struct pdma_dev *dev) +{ + if (!dev->attached) { + return SHR_E_UNAVAIL; + } + + return dev->ops->dev_suspend(dev); +} + +/*! + * Resume a device + */ +int +bcmcnet_pdma_dev_resume(struct pdma_dev *dev) +{ + if (!dev->attached) { + return SHR_E_UNAVAIL; + } + + return dev->ops->dev_resume(dev); +} + +/*! + * Suspend Rx + */ +int +bcmcnet_pdma_dev_rx_suspend(struct pdma_dev *dev) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + uint32_t qi; + + if (!dev->attached) { + return SHR_E_UNAVAIL; + } + + /* Suspend all the Rx queues */ + for (qi = 0; qi < ctrl->nb_rxq; qi++) { + dev->ops->rx_queue_suspend(dev, qi); + } + + return SHR_E_NONE; +} + +/*! + * Resume Rx + */ +int +bcmcnet_pdma_dev_rx_resume(struct pdma_dev *dev) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + uint32_t qi; + + if (!dev->attached) { + return SHR_E_UNAVAIL; + } + + /* Resume all the Rx queues */ + for (qi = 0; qi < ctrl->nb_rxq; qi++) { + dev->ops->rx_queue_resume(dev, qi); + } + + return SHR_E_NONE; +} + +/*! + * Dock to HNET + */ +int +bcmcnet_pdma_dev_dock(struct pdma_dev *dev) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + uint32_t qi; + int rv; + + if (!dev->attached) { + return SHR_E_UNAVAIL; + } + + /* Set up all the virtual Rx queues */ + for (qi = 0; qi < ctrl->nb_rxq; qi++) { + rv = dev->ops->rx_vqueue_setup(dev, qi); + if (SHR_FAILURE(rv)) { + return rv; + } + } + + /* Set up all the virtual Tx queues */ + for (qi = 0; qi < ctrl->nb_txq; qi++) { + rv = dev->ops->tx_vqueue_setup(dev, qi); + if (SHR_FAILURE(rv)) { + return rv; + } + } + + return SHR_E_NONE; +} + +/*! + * Undock from HNET + */ +int +bcmcnet_pdma_dev_undock(struct pdma_dev *dev) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + uint32_t qi; + + if (!dev->attached) { + return SHR_E_UNAVAIL; + } + + /* Release all the virtual Rx queues */ + for (qi = 0; qi < ctrl->nb_rxq; qi++) { + dev->ops->rx_vqueue_release(dev, qi); + } + + /* Release all the virtual Tx queues */ + for (qi = 0; qi < ctrl->nb_txq; qi++) { + dev->ops->tx_vqueue_release(dev, qi); + } + + return SHR_E_NONE; +} + +/*! + * Get device information + */ +int +bcmcnet_pdma_dev_info_get(struct pdma_dev *dev) +{ + if (!dev->ops || !dev->ops->dev_info_get) { + return SHR_E_INTERNAL; + } + + dev->ops->dev_info_get(dev); + + return SHR_E_NONE; +} + +/*! + * Get device statistics + */ +int +bcmcnet_pdma_dev_stats_get(struct pdma_dev *dev) +{ + if (!dev->ops || !dev->ops->dev_stats_get) { + return SHR_E_INTERNAL; + } + + dev->ops->dev_stats_get(dev); + + return SHR_E_NONE; +} + +/*! + * Reset device statistics + */ +int +bcmcnet_pdma_dev_stats_reset(struct pdma_dev *dev) +{ + if (!dev->ops || !dev->ops->dev_stats_reset) { + return SHR_E_INTERNAL; + } + + dev->ops->dev_stats_reset(dev); + + return SHR_E_NONE; +} + +/*! + * Convert a queue index to channel index + */ +int +bcmcnet_pdma_dev_queue_to_chan(struct pdma_dev *dev, int queue, int dir, int *chan) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + + if (dir == PDMA_Q_RX) { + if ((uint32_t)queue >= ctrl->nb_rxq || chan == NULL) { + return SHR_E_PARAM; + } + } else { + if ((uint32_t)queue >= ctrl->nb_txq || chan == NULL) { + return SHR_E_PARAM; + } + } + + if (!dev->ops || !dev->ops->dev_lq_to_pq) { + return SHR_E_INTERNAL; + } + + return dev->ops->dev_lq_to_pq(dev, queue, dir, chan); +} + +/*! + * Convert a channel index to queue index + */ +int +bcmcnet_pdma_dev_chan_to_queue(struct pdma_dev *dev, int chan, int *queue, int *dir) +{ + if (chan < 0 || chan >= dev->num_queues || queue == NULL || dir == NULL) { + return SHR_E_PARAM; + } + + if (!dev->ops || !dev->ops->dev_pq_to_lq) { + return SHR_E_INTERNAL; + } + + return dev->ops->dev_pq_to_lq(dev, chan, queue, dir); +} + +/*! + * Enable interrupt for a Rx queue + */ +int +bcmcnet_rx_queue_intr_enable(struct pdma_dev *dev, int queue) +{ + if (!dev->ops || !dev->ops->rx_queue_intr_enable) { + return SHR_E_INTERNAL; + } + + return dev->ops->rx_queue_intr_enable(dev, queue); +} + +/*! + * Disable interrupt for a Rx queue + */ +int +bcmcnet_rx_queue_intr_disable(struct pdma_dev *dev, int queue) +{ + if (!dev->ops || !dev->ops->rx_queue_intr_disable) { + return SHR_E_INTERNAL; + } + + return dev->ops->rx_queue_intr_disable(dev, queue); +} + +/*! + * Acknowledge interrupt for a Rx queue + */ +int +bcmcnet_rx_queue_intr_ack(struct pdma_dev *dev, int queue) +{ + if (!dev->ops || !dev->ops->rx_queue_intr_ack) { + return SHR_E_INTERNAL; + } + + return dev->ops->rx_queue_intr_ack(dev, queue); +} + +/*! + * Check interrupt for a Rx queue + */ +int +bcmcnet_rx_queue_intr_check(struct pdma_dev *dev, int queue) +{ + if (!dev->ops || !dev->ops->rx_queue_intr_check) { + return SHR_E_INTERNAL; + } + + return dev->ops->rx_queue_intr_check(dev, queue); +} + +/*! + * Enable interrupt for a Tx queue + */ +int +bcmcnet_tx_queue_intr_enable(struct pdma_dev *dev, int queue) +{ + if (!dev->ops || !dev->ops->tx_queue_intr_enable) { + return SHR_E_INTERNAL; + } + + return dev->ops->tx_queue_intr_enable(dev, queue); +} + +/*! + * Disable interrupt for a Tx queue + */ +int +bcmcnet_tx_queue_intr_disable(struct pdma_dev *dev, int queue) +{ + if (!dev->ops || !dev->ops->tx_queue_intr_disable) { + return SHR_E_INTERNAL; + } + + return dev->ops->tx_queue_intr_disable(dev, queue); +} + +/*! + * Acknowledge interrupt for a Tx queue + */ +int +bcmcnet_tx_queue_intr_ack(struct pdma_dev *dev, int queue) +{ + if (!dev->ops || !dev->ops->tx_queue_intr_ack) { + return SHR_E_INTERNAL; + } + + return dev->ops->tx_queue_intr_ack(dev, queue); +} + +/*! + * Check interrupt for a Tx queue + */ +int +bcmcnet_tx_queue_intr_check(struct pdma_dev *dev, int queue) +{ + if (!dev->ops || !dev->ops->tx_queue_intr_check) { + return SHR_E_INTERNAL; + } + + return dev->ops->tx_queue_intr_check(dev, queue); +} + +/*! + * Enable interrupt for a queue + */ +int +bcmcnet_queue_intr_enable(struct pdma_dev *dev, struct intr_handle *hdl) +{ + if (hdl->dir == PDMA_Q_RX) { + return bcmcnet_rx_queue_intr_enable(dev, hdl->queue); + } else { + return bcmcnet_tx_queue_intr_enable(dev, hdl->queue); + } +} + +/*! + * Disable interrupt for a queue + */ +int +bcmcnet_queue_intr_disable(struct pdma_dev *dev, struct intr_handle *hdl) +{ + if (hdl->dir == PDMA_Q_RX) { + return bcmcnet_rx_queue_intr_disable(dev, hdl->queue); + } else { + return bcmcnet_tx_queue_intr_disable(dev, hdl->queue); + } +} + +/*! + * Acknowledge interrupt for a queue + */ +int +bcmcnet_queue_intr_ack(struct pdma_dev *dev, struct intr_handle *hdl) +{ + if (hdl->dir == PDMA_Q_RX) { + return bcmcnet_rx_queue_intr_ack(dev, hdl->queue); + } else { + return bcmcnet_tx_queue_intr_ack(dev, hdl->queue); + } +} + +/*! + * Check interrupt for a queue + */ +int +bcmcnet_queue_intr_check(struct pdma_dev *dev, struct intr_handle *hdl) +{ + if (hdl->dir == PDMA_Q_RX) { + return bcmcnet_rx_queue_intr_check(dev, hdl->queue); + } else { + return bcmcnet_tx_queue_intr_check(dev, hdl->queue); + } +} + +/*! + * Enable interrupt for a queue group + */ +int +bcmcnet_group_intr_enable(struct pdma_dev *dev, int group) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct queue_group *grp = &ctrl->grp[group]; + int queue, dir; + int i; + + if (!dev->ops) { + return SHR_E_INTERNAL; + } + + for (i = 0; i < dev->grp_queues; i++) { + if (1 << i & grp->bm_rxq) { + dev->ops->dev_pq_to_lq(dev, i + group * dev->grp_queues, &queue, &dir); + dev->ops->rx_queue_intr_enable(dev, queue); + } + } + + for (i = 0; i < dev->grp_queues; i++) { + if (1 << i & grp->bm_txq) { + dev->ops->dev_pq_to_lq(dev, i + group * dev->grp_queues, &queue, &dir); + dev->ops->tx_queue_intr_enable(dev, queue); + } + } + + return SHR_E_NONE; +} + +/*! + * Disable interrupt for a queue group + */ +int +bcmcnet_group_intr_disable(struct pdma_dev *dev, int group) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct queue_group *grp = &ctrl->grp[group]; + int queue, dir; + int i; + + if (!dev->ops) { + return SHR_E_INTERNAL; + } + + for (i = 0; i < dev->grp_queues; i++) { + if (1 << i & grp->bm_rxq) { + dev->ops->dev_pq_to_lq(dev, i + group * dev->grp_queues, &queue, &dir); + dev->ops->rx_queue_intr_disable(dev, queue); + } + } + + for (i = 0; i < dev->grp_queues; i++) { + if (1 << i & grp->bm_txq) { + dev->ops->dev_pq_to_lq(dev, i + group * dev->grp_queues, &queue, &dir); + dev->ops->tx_queue_intr_disable(dev, queue); + } + } + + return SHR_E_NONE; +} + +/*! + * Acknowledge interrupt for a queue group + */ +int +bcmcnet_group_intr_ack(struct pdma_dev *dev, int group) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct queue_group *grp = &ctrl->grp[group]; + int queue, dir; + int i; + + if (!dev->ops) { + return SHR_E_INTERNAL; + } + + for (i = 0; i < dev->grp_queues; i++) { + if (1 << i & grp->bm_rxq) { + dev->ops->dev_pq_to_lq(dev, i + group * dev->grp_queues, &queue, &dir); + dev->ops->rx_queue_intr_ack(dev, queue); + } + } + + for (i = 0; i < dev->grp_queues; i++) { + if (1 << i & grp->bm_txq) { + dev->ops->dev_pq_to_lq(dev, i + group * dev->grp_queues, &queue, &dir); + dev->ops->tx_queue_intr_ack(dev, queue); + } + } + + return SHR_E_NONE; +} + +/*! + * Check interrupt for a queue group + */ +int +bcmcnet_group_intr_check(struct pdma_dev *dev, int group) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct queue_group *grp = &ctrl->grp[group]; + int queue, dir; + int i; + + if (!dev->ops) { + return SHR_E_INTERNAL; + } + + for (i = 0; i < dev->grp_queues; i++) { + if (1 << i & grp->bm_rxq) { + dev->ops->dev_pq_to_lq(dev, i + group * dev->grp_queues, &queue, &dir); + if (dev->ops->rx_queue_intr_check(dev, queue)) { + return TRUE; + } + } + } + + for (i = 0; i < dev->grp_queues; i++) { + if (1 << i & grp->bm_txq) { + dev->ops->dev_pq_to_lq(dev, i + group * dev->grp_queues, &queue, &dir); + if (dev->ops->tx_queue_intr_check(dev, queue)) { + return TRUE; + } + } + } + + return FALSE; +} + +/*! + * Poll a Rx queue + */ +int +bcmcnet_rx_queue_poll(struct pdma_dev *dev, int queue, int budget) +{ + if (!dev->ops || !dev->ops->rx_queue_poll) { + return SHR_E_INTERNAL; + } + + return dev->ops->rx_queue_poll(dev, queue, budget); +} + +/*! + * Poll a Tx queue + */ +int +bcmcnet_tx_queue_poll(struct pdma_dev *dev, int queue, int budget) +{ + if (!dev->ops || !dev->ops->tx_queue_poll) { + return SHR_E_INTERNAL; + } + + return dev->ops->tx_queue_poll(dev, queue, budget); +} + +/*! + * Poll a queue + */ +int +bcmcnet_queue_poll(struct pdma_dev *dev, struct intr_handle *hdl, int budget) +{ + if (hdl->dir == PDMA_Q_RX) { + return bcmcnet_rx_queue_poll(dev, hdl->queue, budget); + } else { + return bcmcnet_tx_queue_poll(dev, hdl->queue, budget); + } +} + +/*! + * Poll a queue group + */ +int +bcmcnet_group_poll(struct pdma_dev *dev, int group, int budget) +{ + if (!dev->ops || !dev->ops->group_poll) { + return SHR_E_INTERNAL; + } + + return dev->ops->group_poll(dev, group, budget); +} + diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/main/bcmcnet_dev.c b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/main/bcmcnet_dev.c new file mode 100644 index 000000000000..1f39515a7a62 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/main/bcmcnet_dev.c @@ -0,0 +1,1059 @@ +/*! \file bcmcnet_dev.c + * + * Utility routines for BCMCNET device. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include +#include +#include +#include + +/*! + * Free resource for a Rx queue + */ +static void +bcn_rx_queues_free(struct pdma_dev *dev) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_rx_queue *rxq = NULL; + int gi, qi; + + for (gi = 0; gi < dev->num_groups; gi++) { + for (qi = 0; qi < dev->grp_queues; qi++) { + rxq = (struct pdma_rx_queue *)ctrl->grp[gi].rx_queue[qi]; + if (!rxq) { + continue; + } + sal_free(rxq); + ctrl->grp[gi].rx_queue[qi] = NULL; + if (dev->mode == DEV_MODE_HNET && ctrl->grp[gi].vnet_rxq[qi]) { + sal_free(ctrl->grp[gi].vnet_rxq[qi]); + ctrl->grp[gi].vnet_rxq[qi] = NULL; + } + } + } +} + +/*! + * Allocate resource for a Rx queue + */ +static int +bcn_rx_queues_alloc(struct pdma_dev *dev) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_rx_queue *rxq = NULL, *vrxq = NULL; + int gi, qi; + + for (gi = 0; gi < dev->num_groups; gi++) { + for (qi = 0; qi < dev->grp_queues; qi++) { + rxq = sal_alloc(sizeof(*rxq), "bcmcnetRxQueue"); + if (!rxq) { + goto error; + } + sal_memset(rxq, 0, sizeof(*rxq)); + rxq->group_id = gi; + rxq->chan_id = qi + gi * dev->grp_queues; + rxq->ctrl = ctrl; + ctrl->grp[gi].rx_queue[qi] = rxq; + if (dev->mode == DEV_MODE_HNET) { + vrxq = sal_alloc(sizeof(*vrxq), "bcmcnetVnetRxQueue"); + if (!vrxq) { + goto error; + } + sal_memset(vrxq, 0, sizeof(*vrxq)); + vrxq->group_id = gi; + vrxq->chan_id = qi + gi * dev->grp_queues; + vrxq->ctrl = ctrl; + ctrl->grp[gi].vnet_rxq[qi] = vrxq; + } + } + } + + return SHR_E_NONE; + +error: + bcn_rx_queues_free(dev); + + return SHR_E_MEMORY; +} + +/*! + * Free resource for a Tx queue + */ +static void +bcn_tx_queues_free(struct pdma_dev *dev) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_tx_queue *txq = NULL; + int gi, qi; + + for (gi = 0; gi < dev->num_groups; gi++) { + for (qi = 0; qi < dev->grp_queues; qi++) { + txq = (struct pdma_tx_queue *)ctrl->grp[gi].tx_queue[qi]; + if (!txq) { + continue; + } + sal_free(txq); + ctrl->grp[gi].tx_queue[qi] = NULL; + if (dev->mode == DEV_MODE_HNET && ctrl->grp[gi].vnet_txq[qi]) { + sal_free(ctrl->grp[gi].vnet_txq[qi]); + ctrl->grp[gi].vnet_txq[qi] = NULL; + } + } + } +} + +/*! + * Allocate resource for a Tx queue + */ +static int +bcn_tx_queues_alloc(struct pdma_dev *dev) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_tx_queue *txq = NULL, *vtxq = NULL; + int gi, qi; + + for (gi = 0; gi < dev->num_groups; gi++) { + for (qi = 0; qi < dev->grp_queues; qi++) { + txq = sal_alloc(sizeof(*txq), "bcmcnetTxQueue"); + if (!txq) { + goto error; + } + sal_memset(txq, 0, sizeof(*txq)); + txq->group_id = gi; + txq->chan_id = qi + gi * dev->grp_queues; + txq->ctrl = ctrl; + ctrl->grp[gi].tx_queue[qi] = txq; + if (dev->mode == DEV_MODE_HNET) { + vtxq = sal_alloc(sizeof(*vtxq), "bcmcnetVnetTxQueue"); + if (!vtxq) { + goto error; + } + sal_memset(vtxq, 0, sizeof(*vtxq)); + vtxq->group_id = gi; + vtxq->chan_id = qi + gi * dev->grp_queues; + vtxq->ctrl = ctrl; + ctrl->grp[gi].vnet_txq[qi] = vtxq; + } + } + } + + return SHR_E_NONE; + +error: + bcn_tx_queues_free(dev); + + return SHR_E_MEMORY; +} + +/*! + * \brief Parse Rx groups + * + * \param [in] dev Device structure point. + * \param [in] qbm Rx queue bitmap. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +static int +bcn_rx_queue_group_parse(struct pdma_dev *dev, uint32_t qbm) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_buf_mngr *bm = (struct pdma_buf_mngr *)ctrl->buf_mngr; + struct pdma_rx_queue *rxq = NULL; + struct intr_handle *hdl = NULL; + uint32_t mask; + int gi, qi, qn; + + ctrl->nb_rxq = 0; + sal_memset(ctrl->rx_queue, 0, sizeof(ctrl->rx_queue)); + + /* Figure out available groups and Rx queues */ + for (gi = 0; gi < dev->num_groups; gi++) { + if (!ctrl->grp[gi].attached) { + continue; + } + qn = 0; + mask = 0; + for (qi = 0; qi < dev->grp_queues; qi++) { + rxq = (struct pdma_rx_queue *)ctrl->grp[gi].rx_queue[qi]; + hdl = &ctrl->grp[gi].intr_hdl[qi]; + if (1 << (qi + gi * dev->grp_queues) & qbm) { + /* Set the number of descriptors */ + rxq->nb_desc = ctrl->grp[gi].nb_desc[qi]; + if (!rxq->nb_desc) { + rxq->nb_desc = ctrl->nb_desc; + ctrl->grp[gi].nb_desc[qi] = rxq->nb_desc; + } + /* Set Rx buffer size */ + rxq->buf_size = ctrl->grp[gi].rx_size[qi]; + if (rxq->buf_size < RX_BUF_SIZE_MIN) { + rxq->buf_size = RX_BUF_SIZE_MIN; + ctrl->grp[gi].rx_size[qi] = rxq->buf_size; + } else if (rxq->buf_size > RX_BUF_SIZE_MAX) { + rxq->buf_size = ctrl->rx_buf_size; + ctrl->grp[gi].rx_size[qi] = rxq->buf_size; + } + rxq->buf_size += dev->rx_ph_size; + /* Set mode and state for the queue */ + rxq->mode = bm->rx_buf_mode(dev, rxq); + rxq->state = PDMA_RX_QUEUE_USED; + if (dev->flags & PDMA_RX_BATCHING) { + rxq->free_thresh = rxq->nb_desc / 4; + rxq->state |= PDMA_RX_BATCH_REFILL; + } + /* Update queue index */ + rxq->queue_id = ctrl->nb_rxq; + ctrl->rx_queue[rxq->queue_id] = rxq; + ctrl->nb_rxq++; + qn++; + mask |= 1 << qi; + /* Set up handler for the queue */ + hdl->queue = rxq->queue_id; + hdl->dir = PDMA_Q_RX; + hdl->budget = ctrl->budget < rxq->nb_desc ? + ctrl->budget : rxq->nb_desc; + if (dev->mode == DEV_MODE_HNET) { + ctrl->vnet_rxq[rxq->queue_id] = ctrl->grp[gi].vnet_rxq[qi]; + } + } else { + rxq->state = 0; + } + } + + /* Set group metadata */ + if (qn) { + ctrl->grp[gi].bm_rxq = mask; + ctrl->grp[gi].nb_rxq = qn; + } else { + ctrl->grp[gi].bm_rxq = 0; + ctrl->grp[gi].nb_rxq = 0; + } + } + + return SHR_E_NONE; +} + +/*! + * \brief Parse Tx groups + * + * \param [in] dev Device structure point. + * \param [in] qbm Tx queue bitmap. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +static int +bcn_tx_queue_group_parse(struct pdma_dev *dev, uint32_t qbm) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_tx_queue *txq = NULL; + struct intr_handle *hdl = NULL; + uint32_t mask; + int gi, qi, qn; + + ctrl->nb_txq = 0; + sal_memset(ctrl->tx_queue, 0, sizeof(ctrl->tx_queue)); + + /* Figure out available groups and Tx queues */ + for (gi = 0; gi < dev->num_groups; gi++) { + if (!ctrl->grp[gi].attached) { + continue; + } + qn = 0; + mask = 0; + for (qi = 0; qi < dev->grp_queues; qi++) { + txq = (struct pdma_tx_queue *)ctrl->grp[gi].tx_queue[qi]; + hdl = &ctrl->grp[gi].intr_hdl[qi]; + if (1 << (qi + gi * dev->grp_queues) & qbm) { + /* Set the number of descriptors */ + txq->nb_desc = ctrl->grp[gi].nb_desc[qi]; + if (!txq->nb_desc) { + txq->nb_desc = ctrl->nb_desc; + ctrl->grp[gi].nb_desc[qi] = txq->nb_desc; + } + /* Set mode and state for the queue */ + txq->state = PDMA_TX_QUEUE_USED; + if (dev->flags & PDMA_TX_POLLING) { + txq->free_thresh = txq->nb_desc / 4; + txq->state |= PDMA_TX_QUEUE_POLL; + } + /* Update queue index */ + txq->queue_id = ctrl->nb_txq; + ctrl->tx_queue[txq->queue_id] = txq; + ctrl->nb_txq++; + qn++; + mask |= 1 << qi; + /* Set up handler for the queue */ + hdl->queue = txq->queue_id; + hdl->dir = PDMA_Q_TX; + hdl->budget = ctrl->budget < txq->nb_desc ? + ctrl->budget : txq->nb_desc; + if (dev->mode == DEV_MODE_HNET) { + ctrl->vnet_txq[txq->queue_id] = ctrl->grp[gi].vnet_txq[qi]; + } + } else { + txq->state = 0; + } + } + + /* Set group metadata */ + if (qn) { + ctrl->grp[gi].bm_txq = mask; + ctrl->grp[gi].nb_txq = qn; + } else { + ctrl->grp[gi].bm_txq = 0; + ctrl->grp[gi].nb_txq = 0; + } + } + + return SHR_E_NONE; +} + +/*! + * \brief Configure device + * + * \param [in] dev Device structure point. + * \param [in] bm_rxq Rx queue bitmap. + * \param [in] bm_txq Tx queue bitmap. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +static int +bcmcnet_pdma_config(struct pdma_dev *dev, uint32_t bm_rxq, uint32_t bm_txq) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; + int gi; + + if (!bm_rxq || !bm_txq || (bm_rxq & bm_txq)) { + return SHR_E_PARAM; + } + + bcn_rx_queue_group_parse(dev, bm_rxq); + bcn_tx_queue_group_parse(dev, bm_txq); + + for (gi = 0; gi < dev->num_groups; gi++) { + if (!ctrl->grp[gi].attached) { + continue; + } + /* Update group metadata */ + if (!ctrl->grp[gi].bm_rxq && !ctrl->grp[gi].bm_txq) { + ctrl->grp[gi].attached = 0; + ctrl->bm_grp &= ~(1 << gi); + ctrl->nb_grp--; + continue; + } + ctrl->grp[gi].ctrl = ctrl; + ctrl->grp[gi].id = gi; + ctrl->grp[gi].irq_mask = 0; + } + + return hw->hdls.hw_config(hw); +} + +/*! + * Close device + */ +static int +bcmcnet_pdma_close(struct pdma_dev *dev) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_hw *hw = (struct pdma_hw *)dev->ctrl.hw; + int gi; + + hw->hdls.hw_reset(hw); + + for (gi = 0; gi < dev->num_groups; gi++) { + if (!ctrl->grp[gi].attached) { + continue; + } + /* Reset group metadata */ + ctrl->bm_grp &= ~(1 << gi); + ctrl->nb_grp--; + ctrl->grp[gi].irq_mask = 0; + ctrl->grp[gi].poll_queues = 0; + ctrl->grp[gi].attached = 0; + } + + bcn_rx_queues_free(dev); + bcn_tx_queues_free(dev); + + return SHR_E_NONE; +} + +/*! + * Suspend device + */ +static int +bcmcnet_pdma_suspend(struct pdma_dev *dev) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + uint32_t qi; + + for (qi = 0; qi < ctrl->nb_rxq; qi++) { + bcmcnet_pdma_rx_queue_suspend(dev, qi); + } + + for (qi = 0; qi < ctrl->nb_txq; qi++) { + bcmcnet_pdma_tx_queue_suspend(dev, qi); + } + + return SHR_E_NONE; +} + +/*! + * Resume device + */ +static int +bcmcnet_pdma_resume(struct pdma_dev *dev) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + uint32_t qi; + + for (qi = 0; qi < ctrl->nb_rxq; qi++) { + bcmcnet_pdma_rx_queue_resume(dev, qi); + } + + for (qi = 0; qi < ctrl->nb_txq; qi++) { + bcmcnet_pdma_tx_queue_resume(dev, qi); + } + + return SHR_E_NONE; +} + +/*! + * Get device information + */ +static void +bcmcnet_pdma_info_get(struct pdma_dev *dev) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; + struct pdma_rx_queue *rxq = NULL; + struct pdma_tx_queue *txq = NULL; + uint32_t qi; + + sal_strncpy(dev->info.dev_name, dev->name, sizeof(dev->info.dev_name) - 1); + dev->info.dev_name[sizeof(dev->info.dev_name) - 1] = 0; + dev->info.dev_id = dev->dev_id; + dev->info.dev_type = dev->dev_type; + dev->info.max_groups = hw->info.num_cmcs; + dev->info.max_queues = hw->info.num_chans; + dev->info.bm_groups = ctrl->bm_grp; + dev->info.bm_rx_queues = ctrl->bm_rxq; + dev->info.bm_tx_queues = ctrl->bm_txq; + dev->info.nb_groups = ctrl->nb_grp; + dev->info.nb_rx_queues = ctrl->nb_rxq; + dev->info.nb_tx_queues = ctrl->nb_txq; + dev->info.rx_desc_size = hw->info.rx_dcb_size; + dev->info.tx_desc_size = hw->info.tx_dcb_size; + dev->info.rx_ph_size = hw->info.rx_ph_size; + dev->info.tx_ph_size = hw->info.tx_ph_size; + dev->info.rx_buf_dflt = ctrl->rx_buf_size; + dev->info.nb_desc_dflt = ctrl->nb_desc; + + for (qi = 0; qi < ctrl->nb_rxq; qi++) { + rxq = (struct pdma_rx_queue *)ctrl->rx_queue[qi]; + if (!rxq) { + continue; + } + dev->info.rx_buf_size[qi] = rxq->buf_size; + dev->info.nb_rx_desc[qi] = rxq->nb_desc; + } + + for (qi = 0; qi < ctrl->nb_txq; qi++) { + txq = (struct pdma_tx_queue *)ctrl->tx_queue[qi]; + if (!txq) { + continue; + } + dev->info.nb_tx_desc[qi] = txq->nb_desc; + } +} + +/*! + * Get device statistics + */ +static void +bcmcnet_pdma_stats_get(struct pdma_dev *dev) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_rx_queue *rxq = NULL; + struct pdma_tx_queue *txq = NULL; + uint32_t packets = 0, bytes = 0, dropped = 0, errors = 0, nomems = 0, xoffs = 0; + uint32_t head_errors = 0, data_errors = 0, cell_errors = 0; + uint32_t qi; + + for (qi = 0; qi < ctrl->nb_rxq; qi++) { + rxq = (struct pdma_rx_queue *)ctrl->rx_queue[qi]; + if (!rxq) { + continue; + } + packets += rxq->stats.packets; + bytes += rxq->stats.bytes; + dropped += rxq->stats.dropped; + errors += rxq->stats.errors; + head_errors += rxq->stats.head_errors; + data_errors += rxq->stats.data_errors; + cell_errors += rxq->stats.cell_errors; + nomems += rxq->stats.nomems; + dev->stats.rxq_packets[qi] = rxq->stats.packets; + dev->stats.rxq_bytes[qi] = rxq->stats.bytes; + dev->stats.rxq_dropped[qi] = rxq->stats.dropped; + dev->stats.rxq_errors[qi] = rxq->stats.errors; + dev->stats.rxq_head_errors[qi] = rxq->stats.head_errors; + dev->stats.rxq_data_errors[qi] = rxq->stats.data_errors; + dev->stats.rxq_cell_errors[qi] = rxq->stats.cell_errors; + dev->stats.rxq_nomems[qi] = rxq->stats.nomems; + } + + dev->stats.rx_packets = packets; + dev->stats.rx_bytes = bytes; + dev->stats.rx_dropped = dropped; + dev->stats.rx_errors = errors; + dev->stats.rx_head_errors = head_errors; + dev->stats.rx_data_errors = data_errors; + dev->stats.rx_cell_errors = cell_errors; + dev->stats.rx_nomems = nomems; + + packets = bytes = dropped = errors = 0; + for (qi = 0; qi < ctrl->nb_txq; qi++) { + txq = (struct pdma_tx_queue *)ctrl->tx_queue[qi]; + if (!txq) { + continue; + } + packets += txq->stats.packets; + bytes += txq->stats.bytes; + dropped += txq->stats.dropped; + errors += txq->stats.errors; + xoffs += txq->stats.xoffs; + dev->stats.txq_packets[qi] = txq->stats.packets; + dev->stats.txq_bytes[qi] = txq->stats.bytes; + dev->stats.txq_dropped[qi] = txq->stats.dropped; + dev->stats.txq_errors[qi] = txq->stats.errors; + dev->stats.txq_xoffs[qi] = txq->stats.xoffs; + } + + dev->stats.tx_packets = packets; + dev->stats.tx_bytes = bytes; + dev->stats.tx_dropped = dropped; + dev->stats.tx_errors = errors; + dev->stats.tx_xoffs = xoffs; +} + +/*! + * Reset device statistics + */ +static void +bcmcnet_pdma_stats_reset(struct pdma_dev *dev) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_rx_queue *rxq = NULL; + struct pdma_tx_queue *txq = NULL; + uint32_t qi; + + sal_memset(&dev->stats, 0, sizeof(struct bcmcnet_dev_stats)); + + for (qi = 0; qi < ctrl->nb_rxq; qi++) { + rxq = (struct pdma_rx_queue *)ctrl->rx_queue[qi]; + if (!rxq) { + continue; + } + rxq->stats.packets = 0; + rxq->stats.bytes = 0; + rxq->stats.dropped = 0; + rxq->stats.errors = 0; + rxq->stats.head_errors = 0; + rxq->stats.data_errors = 0; + rxq->stats.cell_errors = 0; + rxq->stats.nomems = 0; + } + + for (qi = 0; qi < ctrl->nb_txq; qi++) { + txq = (struct pdma_tx_queue *)ctrl->tx_queue[qi]; + if (!txq) { + continue; + } + txq->stats.packets = 0; + txq->stats.bytes = 0; + txq->stats.dropped = 0; + txq->stats.errors = 0; + txq->stats.xoffs = 0; + } +} + +/*! + * Convert logic queue to physical queue + */ +static int +bcmcnet_pdma_lq_to_pq(struct pdma_dev *dev, int queue, int dir, int *chan) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_rx_queue *rxq = NULL; + struct pdma_tx_queue *txq = NULL; + + if (dir == PDMA_Q_RX) { + rxq = (struct pdma_rx_queue *)ctrl->rx_queue[queue]; + if (rxq->state & PDMA_RX_QUEUE_USED) { + *chan = rxq->chan_id; + return SHR_E_NONE; + } + } else { + txq = (struct pdma_tx_queue *)ctrl->tx_queue[queue]; + if (txq->state & PDMA_TX_QUEUE_USED) { + *chan = txq->chan_id; + return SHR_E_NONE; + } + } + + return SHR_E_UNAVAIL; +} + +/*! + * Convert physical queue to logic queue + */ +static int +bcmcnet_pdma_pq_to_lq(struct pdma_dev *dev, int chan, int *queue, int *dir) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_rx_queue *rxq = NULL; + struct pdma_tx_queue *txq = NULL; + + rxq = ctrl->grp[chan / dev->grp_queues].rx_queue[chan % dev->grp_queues]; + if (rxq->state & PDMA_RX_QUEUE_USED) { + *queue = rxq->queue_id; + *dir = PDMA_Q_RX; + return SHR_E_NONE; + } + + txq = ctrl->grp[chan / dev->grp_queues].tx_queue[chan % dev->grp_queues]; + if (txq->state & PDMA_TX_QUEUE_USED) { + *queue = txq->queue_id; + *dir = PDMA_Q_TX; + return SHR_E_NONE; + } + + return SHR_E_UNAVAIL; +} + +/*! + * Start Rx queue + */ +static int +bcmcnet_pdma_rx_queue_start(struct pdma_dev *dev, int queue) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; + struct pdma_rx_queue *rxq = NULL; + + rxq = (struct pdma_rx_queue *)ctrl->rx_queue[queue]; + rxq->state |= PDMA_RX_QUEUE_ACTIVE; + + return hw->hdls.chan_start(hw, rxq->chan_id); +} + +/*! + * Stop Rx queue + */ +static int +bcmcnet_pdma_rx_queue_stop(struct pdma_dev *dev, int queue) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; + struct pdma_rx_queue *rxq = NULL; + + rxq = (struct pdma_rx_queue *)ctrl->rx_queue[queue]; + rxq->state &= ~PDMA_RX_QUEUE_ACTIVE; + + return hw->hdls.chan_stop(hw, rxq->chan_id); +} + +/*! + * Start Tx queue + */ +static int +bcmcnet_pdma_tx_queue_start(struct pdma_dev *dev, int queue) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; + struct pdma_tx_queue *txq = NULL; + + txq = (struct pdma_tx_queue *)ctrl->tx_queue[queue]; + txq->state |= PDMA_TX_QUEUE_ACTIVE; + + return dev->flags & PDMA_CHAIN_MODE ? SHR_E_NONE : + hw->hdls.chan_start(hw, txq->chan_id); +} + +/*! + * Stop Tx queue + */ +static int +bcmcnet_pdma_tx_queue_stop(struct pdma_dev *dev, int queue) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; + struct pdma_tx_queue *txq = NULL; + + txq = (struct pdma_tx_queue *)ctrl->tx_queue[queue]; + txq->state &= ~PDMA_TX_QUEUE_ACTIVE; + + return hw->hdls.chan_stop(hw, txq->chan_id); +} + +/*! + * Enable Rx queue interrupt + */ +static int +bcmcnet_pdma_rx_queue_intr_enable(struct pdma_dev *dev, int queue) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; + struct pdma_rx_queue *rxq = NULL; + + rxq = (struct pdma_rx_queue *)ctrl->rx_queue[queue]; + + return hw->hdls.chan_intr_enable(hw, rxq->chan_id); +} + +/*! + * Disable Rx queue interrupt + */ +static int +bcmcnet_pdma_rx_queue_intr_disable(struct pdma_dev *dev, int queue) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; + struct pdma_rx_queue *rxq = NULL; + + rxq = (struct pdma_rx_queue *)ctrl->rx_queue[queue]; + + return hw->hdls.chan_intr_disable(hw, rxq->chan_id); +} + +/*! + * Acknowledge Rx queue interrupt + */ +static int +bcmcnet_pdma_rx_queue_intr_ack(struct pdma_dev *dev, int queue) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; + struct pdma_rx_queue *rxq = NULL; + + rxq = (struct pdma_rx_queue *)ctrl->rx_queue[queue]; + + return hw->hdls.chan_clear(hw, rxq->chan_id); +} + +/*! + * Query Rx queue interrupt + */ +static int +bcmcnet_pdma_rx_queue_intr_query(struct pdma_dev *dev, int queue) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; + struct pdma_rx_queue *rxq = NULL; + + rxq = (struct pdma_rx_queue *)ctrl->rx_queue[queue]; + + return hw->hdls.chan_intr_query(hw, rxq->chan_id); +} + +/*! + * Check Rx queue interrupt + */ +static int +bcmcnet_pdma_rx_queue_intr_check(struct pdma_dev *dev, int queue) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; + struct pdma_rx_queue *rxq = NULL; + + rxq = (struct pdma_rx_queue *)ctrl->rx_queue[queue]; + + return hw->hdls.chan_intr_check(hw, rxq->chan_id); +} + +/*! + * Enable Tx queue interrupt + */ +static int +bcmcnet_pdma_tx_queue_intr_enable(struct pdma_dev *dev, int queue) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; + struct pdma_tx_queue *txq = NULL; + + txq = (struct pdma_tx_queue *)ctrl->tx_queue[queue]; + + if (txq->state & PDMA_TX_QUEUE_POLL) { + return SHR_E_NONE; + } else { + return hw->hdls.chan_intr_enable(hw, txq->chan_id); + } +} + +/*! + * Disable Tx queue interrupt + */ +static int +bcmcnet_pdma_tx_queue_intr_disable(struct pdma_dev *dev, int queue) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; + struct pdma_tx_queue *txq = NULL; + + txq = (struct pdma_tx_queue *)ctrl->tx_queue[queue]; + + return hw->hdls.chan_intr_disable(hw, txq->chan_id); +} + +/*! + * Acknowledge Tx queue interrupt + */ +static int +bcmcnet_pdma_tx_queue_intr_ack(struct pdma_dev *dev, int queue) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; + struct pdma_tx_queue *txq = NULL; + + txq = (struct pdma_tx_queue *)ctrl->tx_queue[queue]; + + return hw->hdls.chan_clear(hw, txq->chan_id); +} + +/*! + * Query Tx queue interrupt + */ +static int +bcmcnet_pdma_tx_queue_intr_query(struct pdma_dev *dev, int queue) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; + struct pdma_tx_queue *txq = NULL; + + txq = (struct pdma_tx_queue *)ctrl->tx_queue[queue]; + + return hw->hdls.chan_intr_query(hw, txq->chan_id); +} + +/*! + * Check Tx queue interrupt + */ +static int +bcmcnet_pdma_tx_queue_intr_check(struct pdma_dev *dev, int queue) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; + struct pdma_tx_queue *txq = NULL; + + txq = (struct pdma_tx_queue *)ctrl->tx_queue[queue]; + + return hw->hdls.chan_intr_check(hw, txq->chan_id); +} + +/*! + * \brief Device operation functions. + */ +static const struct dev_ops pdma_dev_ops = { + .dev_config = bcmcnet_pdma_config, + .dev_close = bcmcnet_pdma_close, + .dev_suspend = bcmcnet_pdma_suspend, + .dev_resume = bcmcnet_pdma_resume, + .dev_info_get = bcmcnet_pdma_info_get, + .dev_stats_get = bcmcnet_pdma_stats_get, + .dev_stats_reset = bcmcnet_pdma_stats_reset, + .dev_lq_to_pq = bcmcnet_pdma_lq_to_pq, + .dev_pq_to_lq = bcmcnet_pdma_pq_to_lq, + .rx_queue_start = bcmcnet_pdma_rx_queue_start, + .rx_queue_stop = bcmcnet_pdma_rx_queue_stop, + .tx_queue_start = bcmcnet_pdma_tx_queue_start, + .tx_queue_stop = bcmcnet_pdma_tx_queue_stop, + .rx_queue_setup = bcmcnet_pdma_rx_queue_setup, + .rx_queue_release = bcmcnet_pdma_rx_queue_release, + .rx_queue_restore = bcmcnet_pdma_rx_queue_restore, + .rx_vqueue_setup = bcmcnet_pdma_rx_vqueue_setup, + .rx_vqueue_release = bcmcnet_pdma_rx_vqueue_release, + .tx_queue_setup = bcmcnet_pdma_tx_queue_setup, + .tx_queue_release = bcmcnet_pdma_tx_queue_release, + .tx_queue_restore = bcmcnet_pdma_tx_queue_restore, + .tx_vqueue_setup = bcmcnet_pdma_tx_vqueue_setup, + .tx_vqueue_release = bcmcnet_pdma_tx_vqueue_release, + .rx_queue_intr_enable = bcmcnet_pdma_rx_queue_intr_enable, + .rx_queue_intr_disable = bcmcnet_pdma_rx_queue_intr_disable, + .rx_queue_intr_ack = bcmcnet_pdma_rx_queue_intr_ack, + .rx_queue_intr_query = bcmcnet_pdma_rx_queue_intr_query, + .rx_queue_intr_check = bcmcnet_pdma_rx_queue_intr_check, + .tx_queue_intr_enable = bcmcnet_pdma_tx_queue_intr_enable, + .tx_queue_intr_disable = bcmcnet_pdma_tx_queue_intr_disable, + .tx_queue_intr_ack = bcmcnet_pdma_tx_queue_intr_ack, + .tx_queue_intr_query = bcmcnet_pdma_tx_queue_intr_query, + .tx_queue_intr_check = bcmcnet_pdma_tx_queue_intr_check, + .rx_queue_suspend = bcmcnet_pdma_rx_queue_suspend, + .rx_queue_resume = bcmcnet_pdma_rx_queue_resume, + .tx_queue_wakeup = bcmcnet_pdma_tx_queue_wakeup, + .rx_queue_poll = bcmcnet_pdma_rx_queue_poll, + .tx_queue_poll = bcmcnet_pdma_tx_queue_poll, + .group_poll = bcmcnet_pdma_group_poll, +}; + +/*! + * Open a device + */ +int +bcmcnet_pdma_open(struct pdma_dev *dev) +{ + struct pdma_hw *hw = (struct pdma_hw *)dev->ctrl.hw; + struct intr_handle *hdl = NULL; + int chan, gi, qi; + + if (!hw) { + return SHR_E_INIT; + } + + /* Initialize the hardware */ + hw->hdls.hw_reset(hw); + hw->hdls.hw_init(hw); + + if ((uint32_t)dev->num_groups > hw->info.num_cmcs) { + return SHR_E_PARAM; + } + dev->grp_queues = hw->info.cmc_chans; + dev->num_queues = hw->info.num_chans; + dev->rx_ph_size = hw->info.rx_ph_size; + dev->tx_ph_size = hw->info.tx_ph_size; + dev->ctrl.nb_desc = NUM_RING_DESC; + dev->ctrl.budget = NUM_RXTX_BUDGET; + dev->ctrl.rx_desc_size = hw->info.rx_dcb_size; + dev->ctrl.tx_desc_size = hw->info.tx_dcb_size; + + /* Initialize interrupt handler */ + for (chan = 0; chan < dev->num_queues; chan++) { + gi = chan / dev->grp_queues; + qi = chan % dev->grp_queues; + hdl = &dev->ctrl.grp[gi].intr_hdl[qi]; + hdl->unit = dev->unit; + hdl->group = gi; + hdl->chan = chan; + hdl->dev = dev; + hdl->intr_num = hw->hdls.chan_intr_num_get(hw, chan); + if (hdl->intr_num < 0) { + return SHR_E_INTERNAL; + } + } + + /* Initialize buffer manager */ + bcmcnet_buf_mngr_init(dev); + + /* Allocate all the queues */ + bcn_rx_queues_alloc(dev); + bcn_tx_queues_alloc(dev); + + dev->pkt_xmit = bcmcnet_pdma_tx_queue_xmit; + + dev->ops = (struct dev_ops *)&pdma_dev_ops; + + return SHR_E_NONE; +} + +/*! + * Coalesce Rx interrupt + */ +int +bcmcnet_pdma_rx_queue_int_coalesce(struct pdma_dev *dev, int queue, int count, int timer) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; + struct pdma_rx_queue *rxq = NULL; + + if ((uint32_t)queue >= ctrl->nb_rxq) { + return SHR_E_PARAM; + } + + rxq = (struct pdma_rx_queue *)ctrl->rx_queue[queue]; + rxq->intr_coalescing = 1; + rxq->ic_val = (count & 0x7fff) << 16 | (timer & 0xffff); + + return hw->hdls.chan_intr_coalesce(hw, rxq->chan_id, count, timer); +} + +/*! + * Coalesce Tx interrupt + */ +int +bcmcnet_pdma_tx_queue_int_coalesce(struct pdma_dev *dev, int queue, int count, int timer) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; + struct pdma_tx_queue *txq = NULL; + + if ((uint32_t)queue >= ctrl->nb_txq) { + return SHR_E_PARAM; + } + + txq = (struct pdma_tx_queue *)ctrl->tx_queue[queue]; + txq->intr_coalescing = 1; + txq->ic_val = (count & 0x7fff) << 16 | (timer & 0xffff); + + return hw->hdls.chan_intr_coalesce(hw, txq->chan_id, count, timer); +} + +/*! + * Dump Rx queue registers + */ +int +bcmcnet_pdma_rx_queue_reg_dump(struct pdma_dev *dev, int queue) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; + struct pdma_rx_queue *rxq = NULL; + + if ((uint32_t)queue >= ctrl->nb_rxq) { + return SHR_E_PARAM; + } + + rxq = (struct pdma_rx_queue *)ctrl->rx_queue[queue]; + + return hw->hdls.chan_reg_dump(hw, rxq->chan_id); +} + +/*! + * Dump Tx queue registers + */ +int +bcmcnet_pdma_tx_queue_reg_dump(struct pdma_dev *dev, int queue) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; + struct pdma_tx_queue *txq = NULL; + + if ((uint32_t)queue >= ctrl->nb_txq) { + return SHR_E_PARAM; + } + + txq = (struct pdma_tx_queue *)ctrl->tx_queue[queue]; + + return hw->hdls.chan_reg_dump(hw, txq->chan_id); +} + diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/main/bcmcnet_rxtx.c b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/main/bcmcnet_rxtx.c new file mode 100644 index 000000000000..cfabe9d95d56 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/main/bcmcnet_rxtx.c @@ -0,0 +1,708 @@ +/*! \file bcmcnet_rxtx.c + * + * Utility routines for BCMCNET Rx/Tx. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include +#include +#include +#include + +/*! + * Free a Rx ring + */ +static void +bcn_rx_ring_free(struct pdma_rx_queue *rxq) +{ + struct dev_ctrl *ctrl = rxq->ctrl; + struct pdma_buf_mngr *bm = (struct pdma_buf_mngr *)ctrl->buf_mngr; + + if (rxq->lock) { + sal_spinlock_destroy(rxq->lock); + rxq->lock = NULL; + } + + if (rxq->ring) { + bm->ring_buf_free(ctrl->dev, ctrl->rx_desc_size * (rxq->nb_desc + 1), + rxq->ring, rxq->ring_addr); + rxq->ring = NULL; + } + + if (rxq->pbuf) { + sal_free(rxq->pbuf); + rxq->pbuf = NULL; + } +} + +/*! + * Allocate a Rx ring + */ +static int +bcn_rx_ring_alloc(struct pdma_rx_queue *rxq) +{ + struct dev_ctrl *ctrl = rxq->ctrl; + struct pdma_buf_mngr *bm = (struct pdma_buf_mngr *)ctrl->buf_mngr; + + /* Setup pktbuf ring */ + rxq->pbuf = sal_alloc(sizeof(*rxq->pbuf) * rxq->nb_desc, "bcmcnetRxBufRing"); + if (!rxq->pbuf) { + goto cleanup; + } + sal_memset(rxq->pbuf, 0, sizeof(*rxq->pbuf) * rxq->nb_desc); + + /* Allocate memory for descriptors */ + rxq->ring = bm->ring_buf_alloc(ctrl->dev, ctrl->rx_desc_size * (rxq->nb_desc + 1), + &rxq->ring_addr); + if (!rxq->ring) { + goto cleanup; + } + sal_memset(rxq->ring, 0, ctrl->rx_desc_size * (rxq->nb_desc + 1)); + + rxq->lock = sal_spinlock_create("bcmcnetRxQueueLock"); + if (!rxq->lock) { + goto cleanup; + } + + return SHR_E_NONE; + +cleanup: + bcn_rx_ring_free(rxq); + + return SHR_E_MEMORY; +} + +/*! + * Free a Tx ring + */ +static void +bcn_tx_ring_free(struct pdma_tx_queue *txq) +{ + struct dev_ctrl *ctrl = txq->ctrl; + struct pdma_buf_mngr *bm = (struct pdma_buf_mngr *)ctrl->buf_mngr; + + if (txq->sem) { + sal_sem_destroy(txq->sem); + txq->sem = NULL; + } + + if (txq->mutex) { + sal_spinlock_destroy(txq->mutex); + txq->mutex = NULL; + } + + if (txq->lock) { + sal_spinlock_destroy(txq->lock); + txq->lock = NULL; + } + + if (txq->ring) { + bm->ring_buf_free(ctrl->dev, ctrl->tx_desc_size * (txq->nb_desc + 1), + txq->ring, txq->ring_addr); + txq->ring = NULL; + } + + if (txq->pbuf) { + sal_free(txq->pbuf); + txq->pbuf = NULL; + } +} + +/*! + * Allocate a Tx ring + */ +static int +bcn_tx_ring_alloc(struct pdma_tx_queue *txq) +{ + struct dev_ctrl *ctrl = txq->ctrl; + struct pdma_buf_mngr *bm = (struct pdma_buf_mngr *)ctrl->buf_mngr; + + /* Setup pktbuf ring */ + txq->pbuf = sal_alloc(sizeof(*txq->pbuf) * txq->nb_desc, "bcmcnetTxBufRing"); + if (!txq->pbuf) { + goto cleanup; + } + sal_memset(txq->pbuf, 0, sizeof(*txq->pbuf) * txq->nb_desc); + + /* Allocate memory for descriptors */ + txq->ring = bm->ring_buf_alloc(ctrl->dev, ctrl->tx_desc_size * (txq->nb_desc + 1), + &txq->ring_addr); + if (!txq->ring) { + goto cleanup; + } + sal_memset(txq->ring, 0, ctrl->tx_desc_size * (txq->nb_desc + 1)); + + txq->lock = sal_spinlock_create("bcmcnetTxQueueLock"); + if (!txq->lock) { + goto cleanup; + } + + txq->mutex = sal_spinlock_create("bcmcnetTxMutexLock"); + if (!txq->mutex) { + goto cleanup; + } + + txq->sem = sal_sem_create("bcmcnetTxMutexSem", SAL_SEM_BINARY, 0); + if (!txq->sem) { + goto cleanup; + } + + return SHR_E_NONE; + +cleanup: + bcn_tx_ring_free(txq); + + return SHR_E_MEMORY; +} + +/*! + * Rx polling + */ +static int +bcn_rx_poll(struct pdma_rx_queue *rxq, int budget) +{ + struct dev_ctrl *ctrl = rxq->ctrl; + struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; + + return hw->dops.rx_ring_clean(hw, rxq, budget); +} + +/*! + * Tx polling + */ +static int +bcn_tx_poll(struct pdma_tx_queue *txq, int budget) +{ + struct dev_ctrl *ctrl = txq->ctrl; + struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; + + return hw->dops.tx_ring_clean(hw, txq, budget); +} + +/*! + * Setup a Rx queue + */ +int +bcmcnet_pdma_rx_queue_setup(struct pdma_dev *dev, int queue) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; + struct pdma_rx_queue *rxq = NULL; + int rv; + + rxq = (struct pdma_rx_queue *)ctrl->rx_queue[queue]; + if (rxq->state & PDMA_RX_QUEUE_SETUP) { + return SHR_E_NONE; + } + + rv = bcn_rx_ring_alloc(rxq); + if (SHR_FAILURE(rv)) { + return rv; + } + + rv = hw->dops.rx_desc_init(hw, rxq); + if (SHR_FAILURE(rv)) { + return rv; + } + + if (dev->mode == DEV_MODE_VNET) { + ctrl->vsync.rx_ring_addr[queue] = rxq->ring_addr; + ctrl->vsync.rx_ring_size[queue] = rxq->nb_desc; + } + + rxq->state |= PDMA_RX_QUEUE_SETUP; + + return SHR_E_NONE; +} + +/*! + * Release a Rx queue + */ +int +bcmcnet_pdma_rx_queue_release(struct pdma_dev *dev, int queue) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; + struct pdma_rx_queue *rxq = NULL; + + rxq = (struct pdma_rx_queue *)ctrl->rx_queue[queue]; + if (rxq->state & PDMA_RX_QUEUE_SETUP) { + hw->dops.rx_desc_clean(hw, rxq); + bcn_rx_ring_free(rxq); + rxq->state &= ~PDMA_RX_QUEUE_SETUP; + } + + return SHR_E_NONE; +} + +/*! + * Restore a Rx queue + */ +int +bcmcnet_pdma_rx_queue_restore(struct pdma_dev *dev, int queue) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; + struct pdma_rx_queue *rxq = NULL; + + rxq = (struct pdma_rx_queue *)ctrl->rx_queue[queue]; + if (rxq->state & PDMA_RX_QUEUE_SETUP) { + hw->dops.rx_desc_init(hw, rxq); + } + + return SHR_E_NONE; +} + +/*! + * Set up a virtual Rx queue + */ +int +bcmcnet_pdma_rx_vqueue_setup(struct pdma_dev *dev, int queue) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_rx_queue *vrxq = NULL; + + vrxq = (struct pdma_rx_queue *)ctrl->vnet_rxq[queue]; + if (vrxq->state & PDMA_RX_QUEUE_SETUP) { + return SHR_E_NONE; + } + + if (dev->ctrl.vsync.rx_ring_addr[queue]) { + vrxq->curr = 0; + vrxq->nb_desc = dev->ctrl.vsync.rx_ring_size[queue]; + vrxq->ring_addr = dev->ctrl.vsync.rx_ring_addr[queue]; + vrxq->ring = dev->sys_p2v(dev, vrxq->ring_addr); + vrxq->state |= PDMA_RX_QUEUE_SETUP; + } else { + return SHR_E_UNAVAIL; + } + + return SHR_E_NONE; +} + +/*! + * Release a virtual Rx queue + */ +int +bcmcnet_pdma_rx_vqueue_release(struct pdma_dev *dev, int queue) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_rx_queue *vrxq = NULL; + + vrxq = (struct pdma_rx_queue *)ctrl->vnet_rxq[queue]; + if (vrxq->state & PDMA_RX_QUEUE_SETUP) { + vrxq->state &= ~PDMA_RX_QUEUE_SETUP; + vrxq->ring = NULL; + } + + return SHR_E_NONE; +} + +/*! + * Setup a Tx queue + */ +int +bcmcnet_pdma_tx_queue_setup(struct pdma_dev *dev, int queue) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; + struct pdma_tx_queue *txq = NULL; + int rv; + + txq = (struct pdma_tx_queue *)ctrl->tx_queue[queue]; + if (txq->state & PDMA_TX_QUEUE_SETUP) { + return SHR_E_NONE; + } + + rv = bcn_tx_ring_alloc(txq); + if (SHR_FAILURE(rv)) { + return rv; + } + + rv = hw->dops.tx_desc_init(hw, txq); + if (SHR_FAILURE(rv)) { + return rv; + } + + if (dev->mode == DEV_MODE_VNET) { + ctrl->vsync.tx_ring_addr[queue] = txq->ring_addr; + ctrl->vsync.tx_ring_size[queue] = txq->nb_desc; + } + + txq->state |= PDMA_TX_QUEUE_SETUP; + + return SHR_E_NONE; +} + +/*! + * Release a Tx queue + */ +int +bcmcnet_pdma_tx_queue_release(struct pdma_dev *dev, int queue) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; + struct pdma_tx_queue *txq = NULL; + + txq = (struct pdma_tx_queue *)ctrl->tx_queue[queue]; + if (txq->state & PDMA_TX_QUEUE_SETUP) { + hw->dops.tx_desc_clean(hw, txq); + bcn_tx_ring_free(txq); + txq->state &= ~PDMA_TX_QUEUE_SETUP; + } + + return SHR_E_NONE; +} + +/*! + * Restore a Tx queue + */ +int +bcmcnet_pdma_tx_queue_restore(struct pdma_dev *dev, int queue) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; + struct pdma_tx_queue *txq = NULL; + + txq = (struct pdma_tx_queue *)ctrl->tx_queue[queue]; + if (txq->state & PDMA_TX_QUEUE_SETUP) { + hw->dops.tx_desc_init(hw, txq); + } + + return SHR_E_NONE; +} + +/*! + * Set up a virtual Tx queue + */ +int +bcmcnet_pdma_tx_vqueue_setup(struct pdma_dev *dev, int queue) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_tx_queue *vtxq = NULL; + + vtxq = (struct pdma_tx_queue *)ctrl->vnet_txq[queue]; + if (vtxq->state & PDMA_TX_QUEUE_SETUP) { + return SHR_E_NONE; + } + + if (dev->ctrl.vsync.tx_ring_addr[queue]) { + vtxq->curr = 0; + vtxq->dirt = 0; + vtxq->nb_desc = dev->ctrl.vsync.tx_ring_size[queue]; + vtxq->ring_addr = dev->ctrl.vsync.tx_ring_addr[queue]; + vtxq->ring = dev->sys_p2v(dev, vtxq->ring_addr); + vtxq->state |= PDMA_TX_QUEUE_SETUP; + } else { + return SHR_E_UNAVAIL; + } + + return SHR_E_NONE; +} + +/*! + * Release a virtual Tx queue + */ +int +bcmcnet_pdma_tx_vqueue_release(struct pdma_dev *dev, int queue) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_tx_queue *vtxq = NULL; + + vtxq = (struct pdma_tx_queue *)ctrl->vnet_txq[queue]; + if (vtxq->state & PDMA_TX_QUEUE_SETUP) { + vtxq->state &= ~PDMA_TX_QUEUE_SETUP; + vtxq->ring = NULL; + } + + return SHR_E_NONE; +} + +/*! + * Suspend a Rx queue + */ +int +bcmcnet_pdma_rx_queue_suspend(struct pdma_dev *dev, int queue) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; + struct pdma_rx_queue *rxq = NULL; + + rxq = (struct pdma_rx_queue *)ctrl->rx_queue[queue]; + if (!rxq || !(rxq->state & PDMA_RX_QUEUE_ACTIVE)) { + return SHR_E_UNAVAIL; + } + + return hw->dops.rx_suspend(hw, rxq); +} + +/*! + * Resume a Rx queue + */ +int +bcmcnet_pdma_rx_queue_resume(struct pdma_dev *dev, int queue) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; + struct pdma_rx_queue *rxq = NULL; + + rxq = (struct pdma_rx_queue *)ctrl->rx_queue[queue]; + if (!rxq || !(rxq->state & PDMA_RX_QUEUE_ACTIVE)) { + return SHR_E_UNAVAIL; + } + + return hw->dops.rx_resume(hw, rxq); +} + +/*! + * Suspend a Tx queue + */ +int +bcmcnet_pdma_tx_queue_suspend(struct pdma_dev *dev, int queue) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_tx_queue *txq = NULL; + + txq = (struct pdma_tx_queue *)ctrl->tx_queue[queue]; + if (!txq || !(txq->state & PDMA_TX_QUEUE_ACTIVE)) { + return SHR_E_UNAVAIL; + } + + if (txq->sem) { + sal_sem_take(txq->sem, SAL_SEM_FOREVER); + } + if (dev->tx_suspend) { + dev->tx_suspend(dev, txq->queue_id); + } + + return SHR_E_NONE; +} + +/*! + * Resume a Tx queue + */ +int +bcmcnet_pdma_tx_queue_resume(struct pdma_dev *dev, int queue) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_tx_queue *txq = NULL; + + txq = (struct pdma_tx_queue *)ctrl->tx_queue[queue]; + if (!txq || !(txq->state & PDMA_TX_QUEUE_ACTIVE)) { + return SHR_E_UNAVAIL; + } + + if (txq->sem) { + sal_sem_give(txq->sem); + } + if (dev->tx_resume) { + dev->tx_resume(dev, txq->queue_id); + } + + return SHR_E_NONE; +} + +/*! + * Wake up a Tx queue + */ +int +bcmcnet_pdma_tx_queue_wakeup(struct pdma_dev *dev, int queue) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_tx_queue *txq = NULL; + + txq = (struct pdma_tx_queue *)ctrl->tx_queue[queue]; + if (txq->sem) { + sal_sem_give(txq->sem); + } + + return SHR_E_NONE; +} + +/*! + * Transmit a outputing packet + */ +int +bcmcnet_pdma_tx_queue_xmit(struct pdma_dev *dev, int queue, void *buf) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; + struct pdma_tx_queue *txq = NULL; + + txq = (struct pdma_tx_queue *)ctrl->tx_queue[queue]; + if (!txq || !(txq->state & PDMA_TX_QUEUE_ACTIVE)) { + return SHR_E_UNAVAIL; + } + + return hw->dops.pkt_xmit(hw, txq, buf); +} + +/*! + * Poll a Rx queues + */ +int +bcmcnet_pdma_rx_queue_poll(struct pdma_dev *dev, int queue, int budget) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_rx_queue *rxq = ctrl->rx_queue[queue]; + + return bcn_rx_poll(rxq, budget); +} + +/*! + * Poll a Tx queues + */ +int +bcmcnet_pdma_tx_queue_poll(struct pdma_dev *dev, int queue, int budget) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_tx_queue *txq = ctrl->tx_queue[queue]; + + return bcn_tx_poll(txq, budget); +} + +/*! + * Poll for Rx/Tx queues in a group + */ +int +bcmcnet_pdma_group_poll(struct pdma_dev *dev, int group, int budget) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; + struct pdma_rx_queue *rxq = NULL; + struct pdma_tx_queue *txq = NULL; + struct queue_group *grp = &ctrl->grp[group]; + int done = 0, done_que, budget_que; + int i; + + /* Acknowledge the interrupts */ + for (i = 0; i < dev->grp_queues; i++) { + rxq = grp->rx_queue[i]; + if (rxq->state & PDMA_RX_QUEUE_ACTIVE) { + if (hw->hdls.chan_intr_query(hw, rxq->chan_id)) { + hw->hdls.chan_clear(hw, rxq->chan_id); + grp->poll_queues |= 1 << i; + } else if (rxq->state & PDMA_RX_QUEUE_BUSY) { + rxq->state &= ~PDMA_RX_QUEUE_BUSY; + grp->poll_queues |= 1 << i; + } + continue; + } + txq = grp->tx_queue[i]; + if (txq->state & PDMA_TX_QUEUE_ACTIVE) { + if (hw->hdls.chan_intr_query(hw, txq->chan_id)) { + hw->hdls.chan_clear(hw, txq->chan_id); + grp->poll_queues |= 1 << i; + } + } + } + + /* Calculate per queue budget */ + if (!grp->poll_queues) { + grp->poll_queues = grp->bm_rxq | grp->bm_txq; + budget_que = budget / grp->nb_rxq; + } else { + budget_que = 0; + for (i = 0; i < dev->grp_queues; i++) { + if (1 << i & grp->bm_rxq & grp->poll_queues) { + budget_que++; + } + } + if (budget_que) { + budget_que = budget / budget_que; + } + } + + /* Poll Rx queues */ + for (i = 0; i < dev->grp_queues; i++) { + if (1 << i & grp->bm_rxq & grp->poll_queues) { + rxq = grp->rx_queue[i]; + done_que = bcn_rx_poll(rxq, budget_que); + if (done_que < budget_que) { + grp->poll_queues &= ~(1 << i); + } + done += done_que; + } + } + + /* Poll Tx queues */ + for (i = 0; i < dev->grp_queues; i++) { + txq = grp->tx_queue[i]; + if (1 << i & grp->bm_txq & grp->poll_queues && !txq->free_thresh) { + if (bcn_tx_poll(txq, budget) < budget) { + grp->poll_queues &= ~(1 << i); + } + } + } + + return grp->poll_queues ? budget : done; +} + +/*! + * Dump a Rx ring + */ +int +bcmcnet_pdma_rx_ring_dump(struct pdma_dev *dev, int queue) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_hw *hw = ctrl->hw; + struct pdma_rx_queue *rxq = NULL; + + if ((uint32_t)queue >= ctrl->nb_rxq) { + return SHR_E_PARAM; + } + + rxq = (struct pdma_rx_queue *)ctrl->rx_queue[queue]; + if (rxq->state & PDMA_RX_QUEUE_ACTIVE) { + hw->dops.rx_ring_dump(hw, rxq); + } + if (dev->mode == DEV_MODE_HNET) { + rxq = (struct pdma_rx_queue *)ctrl->vnet_rxq[queue]; + hw->dops.rx_ring_dump(hw, rxq); + } + + return SHR_E_NONE; +} + +/*! + * Dump a Tx ring + */ +int +bcmcnet_pdma_tx_ring_dump(struct pdma_dev *dev, int queue) +{ + struct dev_ctrl *ctrl = &dev->ctrl; + struct pdma_hw *hw = ctrl->hw; + struct pdma_tx_queue *txq = NULL; + + if ((uint32_t)queue >= ctrl->nb_txq) { + return SHR_E_PARAM; + } + + txq = (struct pdma_tx_queue *)ctrl->tx_queue[queue]; + if (txq->state & PDMA_TX_QUEUE_ACTIVE) { + hw->dops.tx_ring_dump(hw, txq); + } + if (dev->mode == DEV_MODE_HNET) { + txq = (struct pdma_tx_queue *)ctrl->vnet_txq[queue]; + hw->dops.tx_ring_dump(hw, txq); + } + + return SHR_E_NONE; +} + diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmdrd/include/bcmdrd/bcmdrd_devlist.h b/platform/broadcom/saibcm-modules/sdklt/bcmdrd/include/bcmdrd/bcmdrd_devlist.h new file mode 100644 index 000000000000..675b9426ea01 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/bcmdrd/include/bcmdrd/bcmdrd_devlist.h @@ -0,0 +1,337 @@ +/* + * DO NOT EDIT THIS FILE! + * This file is auto-generated. + * Edits to this file will be lost when it is regenerated. + * Tool: INTERNAL/drd/instpkgs.pl + * + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +/* + * This file contains the complete list of supported devices. + * No other device lists should be used anywhere in the SDK. + */ + +#ifndef BCMDRD_DEVIDS_H +#define BCMDRD_DEVIDS_H + +#include + +/* + * All Supported Devices and Revisions + */ + +#define BROADCOM_VENDOR_ID 0x14e4 +#define BROADCOM_PHYID_MSB 0x0143 + +/* BCM56780 */ +#define BCM56780_VENDOR_ID 0x14e4 +#define BCM56780_DEVICE_ID 0xb780 +#define BCM56780_REV_A0 0x01 + +/* BCM56782 */ +#define BCM56782_VENDOR_ID 0x14e4 +#define BCM56782_DEVICE_ID 0xb782 +#define BCM56782_REV_A0 0x01 + +/* BCM56784 */ +#define BCM56784_VENDOR_ID 0x14e4 +#define BCM56784_DEVICE_ID 0xb784 +#define BCM56784_REV_A0 0x01 + +/* BCM56786 */ +#define BCM56786_VENDOR_ID 0x14e4 +#define BCM56786_DEVICE_ID 0xb786 +#define BCM56786_REV_A0 0x01 + +/* BCM56788 */ +#define BCM56788_VENDOR_ID 0x14e4 +#define BCM56788_DEVICE_ID 0xb788 +#define BCM56788_REV_A0 0x01 + +/* BCM56789 */ +#define BCM56789_VENDOR_ID 0x14e4 +#define BCM56789_DEVICE_ID 0xb789 +#define BCM56789_REV_A0 0x01 + +/* BCM56880 */ +#define BCM56880_VENDOR_ID 0x14e4 +#define BCM56880_DEVICE_ID 0xb880 +#define BCM56880_REV_A0 0x01 +#define BCM56880_REV_B0 0x11 + +/* BCM56881 */ +#define BCM56881_VENDOR_ID 0x14e4 +#define BCM56881_DEVICE_ID 0xb881 +#define BCM56881_REV_A0 0x01 +#define BCM56881_REV_B0 0x11 + +/* BCM56883 */ +#define BCM56883_VENDOR_ID 0x14e4 +#define BCM56883_DEVICE_ID 0xb883 +#define BCM56883_REV_A0 0x01 +#define BCM56883_REV_B0 0x11 + +/* BCM56889 */ +#define BCM56889_VENDOR_ID 0x14e4 +#define BCM56889_DEVICE_ID 0xb889 +#define BCM56889_REV_A0 0x01 +#define BCM56889_REV_B0 0x11 + +/* BCM56990 */ +#define BCM56990_VENDOR_ID 0x14e4 +#define BCM56990_DEVICE_ID 0xb990 +#define BCM56990_REV_A0 0x01 +#define BCM56990_REV_B0 0x11 + +/* BCM56992 */ +#define BCM56992_VENDOR_ID 0x14e4 +#define BCM56992_DEVICE_ID 0xb992 +#define BCM56992_REV_B0 0x11 + +/* BCM56996 */ +#define BCM56996_VENDOR_ID 0x14e4 +#define BCM56996_DEVICE_ID 0xb996 +#define BCM56996_REV_A0 0x01 + +/* BCM56997 */ +#define BCM56997_VENDOR_ID 0x14e4 +#define BCM56997_DEVICE_ID 0xb997 +#define BCM56997_REV_A0 0x01 + +/* + * End of Supported Devices and Revisions + */ + +#endif /* BCMDRD_DEVIDS_H */ + +#ifdef BCMDRD_DEVLIST_ENTRY +/* + * BCMDRD_DEVLIST_ENTRY macros. + * + * Before including this file, define BCMDRD_DEVLIST_ENTRY + * as a macro to operate on the following parameters: + * + * #define BCMDRD_DEVLIST_ENTRY(_nm,_vn,_dv,_rv,_md,_pi,_bd,_bc,_fn,_cn,_pf,_pd,_r0,_r1) + * + * _nm: Chip Name + * _vn: Chip Vendor ID + * _dv: Chip Device ID + * _rv: Chip Revision + * _md: Chip Model + * _pi: Probe Information + * _bd: SW Base Driver + * _bc: SW Base Configuration + * _fn: SW Full Name + * _cn: Code Name + * _pf: Product Family + * _pd: Product Description + * _r0: Reserved + * _r1: Reserved + * + * Note that this macro will be undefined at the end of this file. + */ + +#if BCMDRD_CONFIG_INCLUDE_BCM56780_A0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) +BCMDRD_DEVLIST_ENTRY(BCM56780, BCM56780_VENDOR_ID, BCM56780_DEVICE_ID, BCM56780_REV_A0, \ + 0, 0, \ + bcm56780_a0, bcm56780_a0, bcm56780_a0, \ + "Trident4-X9", "BCM56780", \ + "8 Tb/s 160x50G-PAM4 Programmable Switch", 0, 0) +#endif + +#if BCMDRD_CONFIG_INCLUDE_BCM56782_A0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) +#ifdef BCMDRD_DEVLIST_INCLUDE_ALL +BCMDRD_DEVLIST_ENTRY(BCM56782, BCM56782_VENDOR_ID, BCM56782_DEVICE_ID, BCM56782_REV_A0, \ + 0, 0, \ + bcm56780_a0, bcm56782_a0, bcm56782_a0, \ + "Trident4-X9", "BCM56780", \ + "8 Tb/s 160x50G-PAM4 Programmable Switch w/MACsec", 0, 0) +#endif +#endif + +#if BCMDRD_CONFIG_INCLUDE_BCM56784_A0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) +#ifdef BCMDRD_DEVLIST_INCLUDE_ALL +BCMDRD_DEVLIST_ENTRY(BCM56784, BCM56784_VENDOR_ID, BCM56784_DEVICE_ID, BCM56784_REV_A0, \ + 0, 0, \ + bcm56780_a0, bcm56784_a0, bcm56784_a0, \ + "Trident4-X9", "BCM56780", \ + "5.6 Tb/s 96x50G-PAM4/32x35G-NRZ Programmable Switch", 0, 0) +#endif +#endif + +#if BCMDRD_CONFIG_INCLUDE_BCM56786_A0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) +#ifdef BCMDRD_DEVLIST_INCLUDE_ALL +BCMDRD_DEVLIST_ENTRY(BCM56786, BCM56786_VENDOR_ID, BCM56786_DEVICE_ID, BCM56786_REV_A0, \ + 0, 0, \ + bcm56780_a0, bcm56786_a0, bcm56786_a0, \ + "Trident4-X9", "BCM56780", \ + "5.6 Tb/s 96x50G-PAM4/32x35G-NRZ Programmable Switch w/MACsec", 0, 0) +#endif +#endif + +#if BCMDRD_CONFIG_INCLUDE_BCM56788_A0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) +#ifdef BCMDRD_DEVLIST_INCLUDE_ALL +BCMDRD_DEVLIST_ENTRY(BCM56788, BCM56788_VENDOR_ID, BCM56788_DEVICE_ID, BCM56788_REV_A0, \ + 0, 0, \ + bcm56780_a0, bcm56788_a0, bcm56788_a0, \ + "Trident4-X9", "BCM56780", \ + "8 Tb/s 160x50G-PAM4 Programmable Switch w/MACsec w/MTop", 0, 0) +#endif +#endif + +#if BCMDRD_CONFIG_INCLUDE_BCM56789_A0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) +#ifdef BCMDRD_DEVLIST_INCLUDE_ALL +BCMDRD_DEVLIST_ENTRY(BCM56789, BCM56789_VENDOR_ID, BCM56789_DEVICE_ID, BCM56789_REV_A0, \ + 0, 0, \ + bcm56780_a0, bcm56789_a0, bcm56789_a0, \ + "Trident4-X9", "BCM56780", \ + "8 Tb/s 160x50G-PAM4 Programmable Switch w/MTop", 0, 0) +#endif +#endif + +#if BCMDRD_CONFIG_INCLUDE_BCM56880_A0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) +BCMDRD_DEVLIST_ENTRY(BCM56880, BCM56880_VENDOR_ID, BCM56880_DEVICE_ID, BCM56880_REV_A0, \ + 0, 0, \ + bcm56880_a0, bcm56880_a0, bcm56880_a0, \ + "Trident4", "BCM56880", \ + "12.8 Tb/s Switch Fabric 128x100G/64x200G/32x400G Multilayer Switch", 0, 0) +#endif + +#if BCMDRD_CONFIG_INCLUDE_BCM56880_B0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) +#ifdef BCMDRD_DEVLIST_INCLUDE_ALL +BCMDRD_DEVLIST_ENTRY(BCM56880, BCM56880_VENDOR_ID, BCM56880_DEVICE_ID, BCM56880_REV_B0, \ + 0, 0, \ + bcm56880_a0, bcm56880_a0, bcm56880_b0, \ + "Trident4", "BCM56880", \ + "12.8 Tb/s Switch Fabric 128x100G/64x200G/32x400G Multilayer Switch", 0, 0) +#endif +#endif + +#if BCMDRD_CONFIG_INCLUDE_BCM56881_A0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) +#ifdef BCMDRD_DEVLIST_INCLUDE_ALL +BCMDRD_DEVLIST_ENTRY(BCM56881, BCM56881_VENDOR_ID, BCM56881_DEVICE_ID, BCM56881_REV_A0, \ + 0, 0, \ + bcm56880_a0, bcm56881_a0, bcm56881_a0, \ + "Trident4", "BCM56880", \ + "12.8 Tb/s Switch Fabric 128x100G/64x200G/32x400G Multilayer Switch", 0, 0) +#endif +#endif + +#if BCMDRD_CONFIG_INCLUDE_BCM56881_B0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) +#ifdef BCMDRD_DEVLIST_INCLUDE_ALL +BCMDRD_DEVLIST_ENTRY(BCM56881, BCM56881_VENDOR_ID, BCM56881_DEVICE_ID, BCM56881_REV_B0, \ + 0, 0, \ + bcm56880_a0, bcm56881_a0, bcm56881_b0, \ + "Trident4", "BCM56880", \ + "12.8 Tb/s Switch Fabric 128x100G/64x200G/32x400G Multilayer Switch", 0, 0) +#endif +#endif + +#if BCMDRD_CONFIG_INCLUDE_BCM56883_A0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) +#ifdef BCMDRD_DEVLIST_INCLUDE_ALL +BCMDRD_DEVLIST_ENTRY(BCM56883, BCM56883_VENDOR_ID, BCM56883_DEVICE_ID, BCM56883_REV_A0, \ + 0, 0, \ + bcm56880_a0, bcm56883_a0, bcm56883_a0, \ + "Trident4", "BCM56880", \ + "8.0 Tb/s Switch Fabric 80x100G/40x200G/20x400G Multilayer Switch", 0, 0) +#endif +#endif + +#if BCMDRD_CONFIG_INCLUDE_BCM56883_B0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) +#ifdef BCMDRD_DEVLIST_INCLUDE_ALL +BCMDRD_DEVLIST_ENTRY(BCM56883, BCM56883_VENDOR_ID, BCM56883_DEVICE_ID, BCM56883_REV_B0, \ + 0, 0, \ + bcm56880_a0, bcm56883_a0, bcm56883_b0, \ + "Trident4", "BCM56880", \ + "8.0 Tb/s Switch Fabric 80x100G/40x200G/20x400G Multilayer Switch", 0, 0) +#endif +#endif + +#if BCMDRD_CONFIG_INCLUDE_BCM56889_A0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) +#ifdef BCMDRD_DEVLIST_INCLUDE_ALL +BCMDRD_DEVLIST_ENTRY(BCM56889, BCM56889_VENDOR_ID, BCM56889_DEVICE_ID, BCM56889_REV_A0, \ + 0, 0, \ + bcm56880_a0, bcm56889_a0, bcm56889_a0, \ + "Trident4", "BCM56880", \ + "12.8 Tb/s Switch Fabric 128x100G/64x200G/32x400G Multilayer Switch", 0, 0) +#endif +#endif + +#if BCMDRD_CONFIG_INCLUDE_BCM56889_B0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) +#ifdef BCMDRD_DEVLIST_INCLUDE_ALL +BCMDRD_DEVLIST_ENTRY(BCM56889, BCM56889_VENDOR_ID, BCM56889_DEVICE_ID, BCM56889_REV_B0, \ + 0, 0, \ + bcm56880_a0, bcm56889_a0, bcm56889_b0, \ + "Trident4", "BCM56880", \ + "12.8 Tb/s Switch Fabric 128x100G/64x200G/32x400G Multilayer Switch", 0, 0) +#endif +#endif + +#if BCMDRD_CONFIG_INCLUDE_BCM56990_A0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) +BCMDRD_DEVLIST_ENTRY(BCM56990, BCM56990_VENDOR_ID, BCM56990_DEVICE_ID, BCM56990_REV_A0, \ + 0, 0, \ + bcm56990_a0, bcm56990_a0, bcm56990_a0, \ + "Tomahawk4", "BCM56990", \ + "25.6 Tbps Multilayer Switch", 0, 0) +#endif + +#if BCMDRD_CONFIG_INCLUDE_BCM56990_B0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) +BCMDRD_DEVLIST_ENTRY(BCM56990, BCM56990_VENDOR_ID, BCM56990_DEVICE_ID, BCM56990_REV_B0, \ + 0, 0, \ + bcm56990_b0, bcm56990_b0, bcm56990_b0, \ + "Tomahawk4", "BCM56990", \ + "25.6 Tbps Multilayer Switch", 0, 0) +#endif + +#if BCMDRD_CONFIG_INCLUDE_BCM56992_B0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) +#ifdef BCMDRD_DEVLIST_INCLUDE_ALL +BCMDRD_DEVLIST_ENTRY(BCM56992, BCM56992_VENDOR_ID, BCM56992_DEVICE_ID, BCM56992_REV_B0, \ + 0, 0, \ + bcm56990_b0, bcm56992_b0, bcm56992_b0, \ + "Tomahawk4", "BCM56990", \ + "25.6 Tbps Multilayer Switch", 0, 0) +#endif +#endif + +#if BCMDRD_CONFIG_INCLUDE_BCM56996_A0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) +BCMDRD_DEVLIST_ENTRY(BCM56996, BCM56996_VENDOR_ID, BCM56996_DEVICE_ID, BCM56996_REV_A0, \ + 0, 0, \ + bcm56996_a0, bcm56996_a0, bcm56996_a0, \ + "Tomahawk4G", "BCM56996", \ + "25.6 Tbps Multilayer Switch", 0, 0) +#endif + +#if BCMDRD_CONFIG_INCLUDE_BCM56997_A0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) +#ifdef BCMDRD_DEVLIST_INCLUDE_ALL +BCMDRD_DEVLIST_ENTRY(BCM56997, BCM56997_VENDOR_ID, BCM56997_DEVICE_ID, BCM56997_REV_A0, \ + 0, 0, \ + bcm56996_a0, bcm56997_a0, bcm56997_a0, \ + "Tomahawk4G", "BCM56996", \ + "12.8 Tbps Multilayer Switch", 0, 0) +#endif +#endif + +/* End BCMDRD_DEVLIST_ENTRY Macros */ + +#ifdef BCMDRD_DEVLIST_INCLUDE_ALL +#undef BCMDRD_DEVLIST_INCLUDE_ALL +#endif +#ifdef BCMDRD_DEVLIST_OVERRIDE +#undef BCMDRD_DEVLIST_OVERRIDE +#endif +#undef BCMDRD_DEVLIST_ENTRY +#endif /* BCMDRD_DEVLIST_ENTRY */ diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmdrd/include/bcmdrd_config.h b/platform/broadcom/saibcm-modules/sdklt/bcmdrd/include/bcmdrd_config.h new file mode 100644 index 000000000000..68e5a0891098 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/bcmdrd/include/bcmdrd_config.h @@ -0,0 +1,166 @@ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + * + * DO NOT EDIT THIS FILE! + * This file will be auto-generated in the near future. + * + * This config file defines all compilation-time specifications for + * the BCMDRD. + * + * Reasonable defaults are provided for all configuration options + * where appropriate. + * + * You need not edit this file directly to change your configuration, + * nor is modifying this file advised -- so doing will require + * manually merging whenever the BCMDRD is upgraded. + * + * You should provide your own configuration options or overrides + * through a combination of: + * + * 1. The compiler command line, such as -D{OPTION}={VALUE} + * + * 2. Create your own custom configuration file: + * a) Create a file called 'bcmdrd_custom_config.h' + * b) Define all custom settings, using this file as + * the reference + * c) Add -DBCMDRD_INCLUDE_CUSTOM_CONFIG to your + * compilation + * d) Make sure the compilation include path includes + * 'bcmdrd_custom_config.h' + * + */ + +#ifndef BCMDRD_CONFIG_H +#define BCMDRD_CONFIG_H + + +/* + * Include system config file if specified: + */ +#ifdef BCMDRD_INCLUDE_CUSTOM_CONFIG +#include +#endif + + +/* + * OPTIONAL configuration and feature values. + * Defaults are provided for all non-specified values. + */ + +/* Maximum number of chips supported */ +#ifndef BCMDRD_CONFIG_MAX_UNITS +#define BCMDRD_CONFIG_MAX_UNITS 8 +#endif + +/* Maximum number of ports per chip supported */ +#ifndef BCMDRD_CONFIG_MAX_PORTS +#define BCMDRD_CONFIG_MAX_PORTS 576 +#endif + +/* Maximum number of SCHAN polls */ +#ifndef BCMDRD_CONFIG_SCHAN_MAX_POLLS +#define BCMDRD_CONFIG_SCHAN_MAX_POLLS 100000 +#endif + +/* Maximum number of MIIM polls */ +#ifndef BCMDRD_CONFIG_MIIM_MAX_POLLS +#define BCMDRD_CONFIG_MIIM_MAX_POLLS 100000 +#endif + +/* Direct access to memory-mapped registers */ +#ifndef BCMDRD_CONFIG_MEMMAP_DIRECT +#define BCMDRD_CONFIG_MEMMAP_DIRECT 0 +#endif + +/* + * Include chip symbol tables for the debug shell. + * + * No symbolic debugging (register/memory names) will be available + * without this defined. + * + * You should enable at least these symbols if you can afford the + * space. + * + * This define is required to get any symbols at all. + * + * If you only wish to include symbols for a subset of chips in the + * system (probably for code space reasons), you can define the + * following for each chip whose symbols you wish to EXCLUDE: + * + * BCMDRD_CONFIG_EXCLUDE_CHIP_SYMBOLS_ + * + */ +#ifndef BCMDRD_CONFIG_INCLUDE_CHIP_SYMBOLS +#define BCMDRD_CONFIG_INCLUDE_CHIP_SYMBOLS 1 +#endif + +/* + * Include register and memory field information for the debug shell. + * + * This provides encoding, decoding, and displaying individual field + * values for each register and memory. + * + * Requires more code space than just the chip symbols alone. + * + * The per-chip exclusion define + * (BCMDRD_CONFIG_EXCLUDE_FIELD_INFO_) also applies. + */ +#ifndef BCMDRD_CONFIG_INCLUDE_FIELD_INFO +#define BCMDRD_CONFIG_INCLUDE_FIELD_INFO 1 +#endif + +/* + * Include alternative symbol names for registers and memories. + * + * Mainly for internal Broadcom use, so you can safely leave this + * option off. + */ +#ifndef BCMDRD_CONFIG_INCLUDE_ALIAS_NAMES +#define BCMDRD_CONFIG_INCLUDE_ALIAS_NAMES 1 +#endif + +#endif /* BCMDRD_CONFIG_H */ + +#ifdef CONFIG_OPTION +#ifdef BCMDRD_INCLUDE_CUSTOM_CONFIG +CONFIG_OPTION(BCMDRD_INCLUDE_CUSTOM_CONFIG) +#endif +#ifdef BCMDRD_CONFIG_MAX_UNITS +CONFIG_OPTION(BCMDRD_CONFIG_MAX_UNITS) +#endif +#ifdef BCMDRD_CONFIG_MAX_PORTS +CONFIG_OPTION(BCMDRD_CONFIG_MAX_PORTS) +#endif +#ifdef BCMDRD_CONFIG_SCHAN_MAX_POLLS +CONFIG_OPTION(BCMDRD_CONFIG_SCHAN_MAX_POLLS) +#endif +#ifdef BCMDRD_CONFIG_MIIM_MAX_POLLS +CONFIG_OPTION(BCMDRD_CONFIG_MIIM_MAX_POLLS) +#endif +#ifdef BCMDRD_CONFIG_MEMMAP_DIRECT +CONFIG_OPTION(BCMDRD_CONFIG_MEMMAP_DIRECT) +#endif +#ifdef BCMDRD_CONFIG_INCLUDE_CHIP_SYMBOLS +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_CHIP_SYMBOLS) +#endif +#ifdef BCMDRD_CONFIG_INCLUDE_FIELD_INFO +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_FIELD_INFO) +#endif +#ifdef BCMDRD_CONFIG_INCLUDE_ALIAS_NAMES +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_ALIAS_NAMES) +#endif +#endif /* CONFIG_OPTION */ +#include "bcmdrd_config_chips.h" diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmdrd/include/bcmdrd_config_chips.h b/platform/broadcom/saibcm-modules/sdklt/bcmdrd/include/bcmdrd_config_chips.h new file mode 100644 index 000000000000..5b45879c90e9 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/bcmdrd/include/bcmdrd_config_chips.h @@ -0,0 +1,545 @@ +/* + * DO NOT EDIT THIS FILE! + * This file is auto-generated. + * Edits to this file will be lost when it is regenerated. + * Tool: INTERNAL/drd/instpkgs.pl + * + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +/* + * Chip inclusion and exclusion support within the BCMDRD can be + * specified as a combination of the following defines: + * + * (1) #define BCMDRD_CONFIG_INCLUDE_ [1|0] + * -- Include or exclude all revisions of the given device + * Example: #define BCMDRD_CONFIG_INCLUDE_BCM56780 1 + * + * (2) #define BCMDRD_CONFIG_INCLUDE__X [1|0] + * -- Include or exclude all versions of the given revision + * Example: #define BCMDRD_CONFIG_INCLUDE_BCM56780_Ax 0 + * #define BCMDRD_CONFIG_INCLUde_BCM56780_Bx 1 + * + * (3) #define BCMDRD_CONFIG_INCLUDE_ [1|0] + * -- Include or exclude an exact device + * Example: #define BCMDRD_CONFIG_INCLUDE_BCM56780_A0 1 + * #define BCMDRD_CONFIG_INCLUDE_BCM56780_A1 0 + * + * + * The value of BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT is used for any + * chips which are left unspecified. Set this value to 1 or 0 to + * include or exclude all chips by default. + * + */ + +#ifndef BCMDRD_CONFIG_CHIPS_H +#define BCMDRD_CONFIG_CHIPS_H + +/* This determines whether a chip is included or excluded by default */ +#ifndef BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#define BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT 1 +#endif + +/* + * Default configuration and dependencies for all chips + */ + +/* + * BCM56780 + */ + +/* Sets the default include state if it was not given */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56780 +#define BCMDRD_CONFIG_INCLUDE_BCM56780 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#endif +/* Resolve revision dependencies */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56780_Ax +#define BCMDRD_CONFIG_INCLUDE_BCM56780_Ax BCMDRD_CONFIG_INCLUDE_BCM56780 +#endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56780_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56780_A0 BCMDRD_CONFIG_INCLUDE_BCM56780_Ax +#endif + + +/* + * BCM56782 + */ + +/* Sets the default include state if it was not given */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56782 +#define BCMDRD_CONFIG_INCLUDE_BCM56782 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#endif +/* Resolve revision dependencies */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56782_Ax +#define BCMDRD_CONFIG_INCLUDE_BCM56782_Ax BCMDRD_CONFIG_INCLUDE_BCM56782 +#endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56782_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56782_A0 BCMDRD_CONFIG_INCLUDE_BCM56782_Ax +#endif +/* Resolve all interchip dependencies */ +#if BCMDRD_CONFIG_INCLUDE_BCM56782_A0 == 1 +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56780_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56780_A0 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#endif +#if BCMDRD_CONFIG_INCLUDE_BCM56780_A0 != 1 +#undef BCMDRD_CONFIG_INCLUDE_BCM56780_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56780_A0 1 +#define BCMDRD_CONFIG_INCLUDE_BCM56780_A0_IMPLIED 1 +#endif +#endif + + +/* + * BCM56784 + */ + +/* Sets the default include state if it was not given */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56784 +#define BCMDRD_CONFIG_INCLUDE_BCM56784 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#endif +/* Resolve revision dependencies */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56784_Ax +#define BCMDRD_CONFIG_INCLUDE_BCM56784_Ax BCMDRD_CONFIG_INCLUDE_BCM56784 +#endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56784_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56784_A0 BCMDRD_CONFIG_INCLUDE_BCM56784_Ax +#endif +/* Resolve all interchip dependencies */ +#if BCMDRD_CONFIG_INCLUDE_BCM56784_A0 == 1 +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56780_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56780_A0 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#endif +#if BCMDRD_CONFIG_INCLUDE_BCM56780_A0 != 1 +#undef BCMDRD_CONFIG_INCLUDE_BCM56780_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56780_A0 1 +#define BCMDRD_CONFIG_INCLUDE_BCM56780_A0_IMPLIED 1 +#endif +#endif + + +/* + * BCM56786 + */ + +/* Sets the default include state if it was not given */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56786 +#define BCMDRD_CONFIG_INCLUDE_BCM56786 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#endif +/* Resolve revision dependencies */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56786_Ax +#define BCMDRD_CONFIG_INCLUDE_BCM56786_Ax BCMDRD_CONFIG_INCLUDE_BCM56786 +#endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56786_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56786_A0 BCMDRD_CONFIG_INCLUDE_BCM56786_Ax +#endif +/* Resolve all interchip dependencies */ +#if BCMDRD_CONFIG_INCLUDE_BCM56786_A0 == 1 +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56780_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56780_A0 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#endif +#if BCMDRD_CONFIG_INCLUDE_BCM56780_A0 != 1 +#undef BCMDRD_CONFIG_INCLUDE_BCM56780_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56780_A0 1 +#define BCMDRD_CONFIG_INCLUDE_BCM56780_A0_IMPLIED 1 +#endif +#endif + + +/* + * BCM56788 + */ + +/* Sets the default include state if it was not given */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56788 +#define BCMDRD_CONFIG_INCLUDE_BCM56788 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#endif +/* Resolve revision dependencies */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56788_Ax +#define BCMDRD_CONFIG_INCLUDE_BCM56788_Ax BCMDRD_CONFIG_INCLUDE_BCM56788 +#endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56788_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56788_A0 BCMDRD_CONFIG_INCLUDE_BCM56788_Ax +#endif +/* Resolve all interchip dependencies */ +#if BCMDRD_CONFIG_INCLUDE_BCM56788_A0 == 1 +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56780_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56780_A0 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#endif +#if BCMDRD_CONFIG_INCLUDE_BCM56780_A0 != 1 +#undef BCMDRD_CONFIG_INCLUDE_BCM56780_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56780_A0 1 +#define BCMDRD_CONFIG_INCLUDE_BCM56780_A0_IMPLIED 1 +#endif +#endif + + +/* + * BCM56789 + */ + +/* Sets the default include state if it was not given */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56789 +#define BCMDRD_CONFIG_INCLUDE_BCM56789 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#endif +/* Resolve revision dependencies */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56789_Ax +#define BCMDRD_CONFIG_INCLUDE_BCM56789_Ax BCMDRD_CONFIG_INCLUDE_BCM56789 +#endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56789_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56789_A0 BCMDRD_CONFIG_INCLUDE_BCM56789_Ax +#endif +/* Resolve all interchip dependencies */ +#if BCMDRD_CONFIG_INCLUDE_BCM56789_A0 == 1 +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56780_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56780_A0 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#endif +#if BCMDRD_CONFIG_INCLUDE_BCM56780_A0 != 1 +#undef BCMDRD_CONFIG_INCLUDE_BCM56780_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56780_A0 1 +#define BCMDRD_CONFIG_INCLUDE_BCM56780_A0_IMPLIED 1 +#endif +#endif + + +/* + * BCM56880 + */ + +/* Sets the default include state if it was not given */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56880 +#define BCMDRD_CONFIG_INCLUDE_BCM56880 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#endif +/* Resolve revision dependencies */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56880_Ax +#define BCMDRD_CONFIG_INCLUDE_BCM56880_Ax BCMDRD_CONFIG_INCLUDE_BCM56880 +#endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56880_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56880_A0 BCMDRD_CONFIG_INCLUDE_BCM56880_Ax +#endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56880_Bx +#define BCMDRD_CONFIG_INCLUDE_BCM56880_Bx BCMDRD_CONFIG_INCLUDE_BCM56880 +#endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56880_B0 +#define BCMDRD_CONFIG_INCLUDE_BCM56880_B0 BCMDRD_CONFIG_INCLUDE_BCM56880_Bx +#endif +/* Resolve all interchip dependencies */ +#if BCMDRD_CONFIG_INCLUDE_BCM56880_B0 == 1 +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56880_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56880_A0 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#endif +#if BCMDRD_CONFIG_INCLUDE_BCM56880_A0 != 1 +#undef BCMDRD_CONFIG_INCLUDE_BCM56880_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56880_A0 1 +#define BCMDRD_CONFIG_INCLUDE_BCM56880_A0_IMPLIED 1 +#endif +#endif + + +/* + * BCM56881 + */ + +/* Sets the default include state if it was not given */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56881 +#define BCMDRD_CONFIG_INCLUDE_BCM56881 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#endif +/* Resolve revision dependencies */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56881_Ax +#define BCMDRD_CONFIG_INCLUDE_BCM56881_Ax BCMDRD_CONFIG_INCLUDE_BCM56881 +#endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56881_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56881_A0 BCMDRD_CONFIG_INCLUDE_BCM56881_Ax +#endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56881_Bx +#define BCMDRD_CONFIG_INCLUDE_BCM56881_Bx BCMDRD_CONFIG_INCLUDE_BCM56881 +#endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56881_B0 +#define BCMDRD_CONFIG_INCLUDE_BCM56881_B0 BCMDRD_CONFIG_INCLUDE_BCM56881_Bx +#endif +/* Resolve all interchip dependencies */ +#if BCMDRD_CONFIG_INCLUDE_BCM56881_A0 == 1 +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56880_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56880_A0 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#endif +#if BCMDRD_CONFIG_INCLUDE_BCM56880_A0 != 1 +#undef BCMDRD_CONFIG_INCLUDE_BCM56880_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56880_A0 1 +#define BCMDRD_CONFIG_INCLUDE_BCM56880_A0_IMPLIED 1 +#endif +#endif +#if BCMDRD_CONFIG_INCLUDE_BCM56881_B0 == 1 +#if BCMDRD_CONFIG_INCLUDE_BCM56880_A0 != 1 +#undef BCMDRD_CONFIG_INCLUDE_BCM56880_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56880_A0 1 +#define BCMDRD_CONFIG_INCLUDE_BCM56880_A0_IMPLIED 1 +#endif +#endif + + +/* + * BCM56883 + */ + +/* Sets the default include state if it was not given */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56883 +#define BCMDRD_CONFIG_INCLUDE_BCM56883 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#endif +/* Resolve revision dependencies */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56883_Ax +#define BCMDRD_CONFIG_INCLUDE_BCM56883_Ax BCMDRD_CONFIG_INCLUDE_BCM56883 +#endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56883_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56883_A0 BCMDRD_CONFIG_INCLUDE_BCM56883_Ax +#endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56883_Bx +#define BCMDRD_CONFIG_INCLUDE_BCM56883_Bx BCMDRD_CONFIG_INCLUDE_BCM56883 +#endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56883_B0 +#define BCMDRD_CONFIG_INCLUDE_BCM56883_B0 BCMDRD_CONFIG_INCLUDE_BCM56883_Bx +#endif +/* Resolve all interchip dependencies */ +#if BCMDRD_CONFIG_INCLUDE_BCM56883_A0 == 1 +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56880_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56880_A0 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#endif +#if BCMDRD_CONFIG_INCLUDE_BCM56880_A0 != 1 +#undef BCMDRD_CONFIG_INCLUDE_BCM56880_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56880_A0 1 +#define BCMDRD_CONFIG_INCLUDE_BCM56880_A0_IMPLIED 1 +#endif +#endif +#if BCMDRD_CONFIG_INCLUDE_BCM56883_B0 == 1 +#if BCMDRD_CONFIG_INCLUDE_BCM56880_A0 != 1 +#undef BCMDRD_CONFIG_INCLUDE_BCM56880_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56880_A0 1 +#define BCMDRD_CONFIG_INCLUDE_BCM56880_A0_IMPLIED 1 +#endif +#endif + + +/* + * BCM56889 + */ + +/* Sets the default include state if it was not given */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56889 +#define BCMDRD_CONFIG_INCLUDE_BCM56889 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#endif +/* Resolve revision dependencies */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56889_Ax +#define BCMDRD_CONFIG_INCLUDE_BCM56889_Ax BCMDRD_CONFIG_INCLUDE_BCM56889 +#endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56889_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56889_A0 BCMDRD_CONFIG_INCLUDE_BCM56889_Ax +#endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56889_Bx +#define BCMDRD_CONFIG_INCLUDE_BCM56889_Bx BCMDRD_CONFIG_INCLUDE_BCM56889 +#endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56889_B0 +#define BCMDRD_CONFIG_INCLUDE_BCM56889_B0 BCMDRD_CONFIG_INCLUDE_BCM56889_Bx +#endif +/* Resolve all interchip dependencies */ +#if BCMDRD_CONFIG_INCLUDE_BCM56889_A0 == 1 +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56880_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56880_A0 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#endif +#if BCMDRD_CONFIG_INCLUDE_BCM56880_A0 != 1 +#undef BCMDRD_CONFIG_INCLUDE_BCM56880_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56880_A0 1 +#define BCMDRD_CONFIG_INCLUDE_BCM56880_A0_IMPLIED 1 +#endif +#endif +#if BCMDRD_CONFIG_INCLUDE_BCM56889_B0 == 1 +#if BCMDRD_CONFIG_INCLUDE_BCM56880_A0 != 1 +#undef BCMDRD_CONFIG_INCLUDE_BCM56880_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56880_A0 1 +#define BCMDRD_CONFIG_INCLUDE_BCM56880_A0_IMPLIED 1 +#endif +#endif + + +/* + * BCM56990 + */ + +/* Sets the default include state if it was not given */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56990 +#define BCMDRD_CONFIG_INCLUDE_BCM56990 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#endif +/* Resolve revision dependencies */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56990_Ax +#define BCMDRD_CONFIG_INCLUDE_BCM56990_Ax BCMDRD_CONFIG_INCLUDE_BCM56990 +#endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56990_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56990_A0 BCMDRD_CONFIG_INCLUDE_BCM56990_Ax +#endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56990_Bx +#define BCMDRD_CONFIG_INCLUDE_BCM56990_Bx BCMDRD_CONFIG_INCLUDE_BCM56990 +#endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56990_B0 +#define BCMDRD_CONFIG_INCLUDE_BCM56990_B0 BCMDRD_CONFIG_INCLUDE_BCM56990_Bx +#endif + + +/* + * BCM56992 + */ + +/* Sets the default include state if it was not given */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56992 +#define BCMDRD_CONFIG_INCLUDE_BCM56992 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#endif +/* Resolve revision dependencies */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56992_Bx +#define BCMDRD_CONFIG_INCLUDE_BCM56992_Bx BCMDRD_CONFIG_INCLUDE_BCM56992 +#endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56992_B0 +#define BCMDRD_CONFIG_INCLUDE_BCM56992_B0 BCMDRD_CONFIG_INCLUDE_BCM56992_Bx +#endif +/* Resolve all interchip dependencies */ +#if BCMDRD_CONFIG_INCLUDE_BCM56992_B0 == 1 +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56990_B0 +#define BCMDRD_CONFIG_INCLUDE_BCM56990_B0 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#endif +#if BCMDRD_CONFIG_INCLUDE_BCM56990_B0 != 1 +#undef BCMDRD_CONFIG_INCLUDE_BCM56990_B0 +#define BCMDRD_CONFIG_INCLUDE_BCM56990_B0 1 +#define BCMDRD_CONFIG_INCLUDE_BCM56990_B0_IMPLIED 1 +#endif +#endif + + +/* + * BCM56996 + */ + +/* Sets the default include state if it was not given */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56996 +#define BCMDRD_CONFIG_INCLUDE_BCM56996 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#endif +/* Resolve revision dependencies */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56996_Ax +#define BCMDRD_CONFIG_INCLUDE_BCM56996_Ax BCMDRD_CONFIG_INCLUDE_BCM56996 +#endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56996_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56996_A0 BCMDRD_CONFIG_INCLUDE_BCM56996_Ax +#endif + + +/* + * BCM56997 + */ + +/* Sets the default include state if it was not given */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56997 +#define BCMDRD_CONFIG_INCLUDE_BCM56997 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#endif +/* Resolve revision dependencies */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56997_Ax +#define BCMDRD_CONFIG_INCLUDE_BCM56997_Ax BCMDRD_CONFIG_INCLUDE_BCM56997 +#endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56997_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56997_A0 BCMDRD_CONFIG_INCLUDE_BCM56997_Ax +#endif +/* Resolve all interchip dependencies */ +#if BCMDRD_CONFIG_INCLUDE_BCM56997_A0 == 1 +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56996_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56996_A0 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#endif +#if BCMDRD_CONFIG_INCLUDE_BCM56996_A0 != 1 +#undef BCMDRD_CONFIG_INCLUDE_BCM56996_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56996_A0 1 +#define BCMDRD_CONFIG_INCLUDE_BCM56996_A0_IMPLIED 1 +#endif +#endif + + +#endif /* BCMDRD_CONFIG_CHIPS_H */ + +/* + * CONFIG_OPTION Macros. Can be used to determine the build configuration. + */ + +#ifdef CONFIG_OPTION +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56780) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56780_Ax) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56780_A0) +#ifdef BCMDRD_CONFIG_INCLUDE_BCM56780_A0_IMPLIED +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56780_A0_IMPLIED) +#endif +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56782) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56782_Ax) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56782_A0) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56784) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56784_Ax) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56784_A0) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56786) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56786_Ax) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56786_A0) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56788) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56788_Ax) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56788_A0) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56789) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56789_Ax) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56789_A0) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56880) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56880_Ax) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56880_A0) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56880_Bx) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56880_B0) +#ifdef BCMDRD_CONFIG_INCLUDE_BCM56880_A0_IMPLIED +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56880_A0_IMPLIED) +#endif +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56881) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56881_Ax) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56881_A0) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56881_Bx) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56881_B0) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56883) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56883_Ax) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56883_A0) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56883_Bx) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56883_B0) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56889) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56889_Ax) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56889_A0) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56889_Bx) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56889_B0) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56990) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56990_Ax) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56990_A0) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56990_Bx) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56990_B0) +#ifdef BCMDRD_CONFIG_INCLUDE_BCM56990_A0_IMPLIED +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56990_A0_IMPLIED) +#endif +#ifdef BCMDRD_CONFIG_INCLUDE_BCM56990_B0_IMPLIED +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56990_B0_IMPLIED) +#endif +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56992) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56992_Bx) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56992_B0) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56996) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56996_Ax) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56996_A0) +#ifdef BCMDRD_CONFIG_INCLUDE_BCM56996_A0_IMPLIED +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56996_A0_IMPLIED) +#endif +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56997) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56997_Ax) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56997_A0) +#undef CONFIG_OPTION +#endif /* #ifdef CONFIG_OPTION */ diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/bde/Kbuild b/platform/broadcom/saibcm-modules/sdklt/linux/bde/Kbuild new file mode 100644 index 000000000000..76581c02eed2 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/bde/Kbuild @@ -0,0 +1,39 @@ +# -*- Kbuild -*- +# +# Linux kernel BDE module. +# +# $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. +# The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# version 2 as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# A copy of the GNU General Public License version 2 (GPLv2) can +# be found in the LICENSES folder.$ +# + +obj-m := linux_ngbde.o + +ccflags-y := $(LKM_CFLAGS) \ + -I$(SDK)/linux/include \ + -I$(SDK)/linux/bde \ + -I$(SDK)/bcmdrd/include + +linux_ngbde-y := ngbde_main.o \ + ngbde_kapi.o \ + ngbde_ioctl.o \ + ngbde_procfs.o \ + ngbde_pio.o \ + ngbde_iio.o \ + ngbde_dma.o \ + ngbde_intr.o \ + ngbde_pgmem.o \ + ngbde_pci_probe.o \ + ngbde_iproc_probe.o \ + ngbde_swdev.o diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/bde/Makefile b/platform/broadcom/saibcm-modules/sdklt/linux/bde/Makefile new file mode 100644 index 000000000000..590f4132306f --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/bde/Makefile @@ -0,0 +1,33 @@ +# -*- Makefile -*- +# +# Linux kernel BDE module. +# +# $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. +# The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# version 2 as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# A copy of the GNU General Public License version 2 (GPLv2) can +# be found in the LICENSES folder.$ +# + +include Kbuild + +ifeq ($(KERNELRELEASE),) + +MOD_NAME = linux_ngbde + +include $(SDK)/make/lkm.mk + +endif + +.PHONY: distclean + +distclean: diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde.h b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde.h new file mode 100644 index 000000000000..56e925f7098d --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde.h @@ -0,0 +1,836 @@ +/*! \file ngbde.h + * + * Shared definitions and APIs for NGBDE kernel module. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#ifndef NGBDE_H +#define NGBDE_H + +#include +#include + +/*! Module name. */ +#define MOD_NAME "linux_ngbde" + +/*! Major number for associated charcter device file. */ +#define MOD_MAJOR 120 + +/*! Read memory-mapped device register without byte-swap. */ +#define NGBDE_IOREAD32(_a) __raw_readl(_a) + +/*! Write memory-mapped device register without byte-swap. */ +#define NGBDE_IOWRITE32(_v, _a) __raw_writel(_v, _a) + +/*! Maximum number of I/O windows supported per device. */ +#define NGBDE_NUM_IOWIN_MAX 3 + +/*! Maximum number of DMA memory pools supported per device. */ +#define NGBDE_NUM_DMAPOOL_MAX 2 + +/*! Maximum number of IRQ status registers per interrupt source. */ +#define NGBDE_NUM_IRQ_REGS_MAX 16 + +/*! Maximum number of IRQ lines (MSI vectors) per device. */ +#define NGBDE_NUM_IRQS_MAX 1 + +/*! + * Maximum number of interrupt controller registers which may be + * written from both a user mode driver and a kernel mode driver. + * + * This feature is used when the kernel mode driver owns a subset of + * bits within a register, which is also used by the user mode driver. + * + * Both drivers must access such registers through a lock-protected + * access function. + */ +#define NGBDE_NUM_INTR_SHR_REGS_MAX 1 + +/*! I/O memory window definition. */ +struct ngbde_memwin_s { + + /*! Physical address of I/O window. */ + phys_addr_t addr; + + /*! Size of I/O window (in bytes). */ + phys_addr_t size; +}; + +/*! + * \brief Shared register value. + * + * This structure contains the current value of a register where user + * mode and kernel mode owns different bits within the same + * register. In this case access must be carefully controlled to avoid + * that one context overwrites the bits owned by the other context. + * + * The structure also contains the offset of the shared register in + * order to identify the register (in case there is more than one + * shared register). + */ +typedef struct ngbde_shr_reg_s { + + /*! Offset of the shared register. */ + uint32_t reg_offs; + + /*! Current value of the shared register. */ + uint32_t cur_val; + +} ngbde_shr_reg_t; + +/*! + * \brief Shared interrupt mask register control. + * + * This defines which bits of an interrupt mask register are owned by + * user mode context, and which are owned by kernel context. + * + * The structure contains the corresponding interrupt status register + * in order to allow identification of the interrupt mask register + * irrespective of the host CPU being used. + * + * For example, if the host CPU is connected via PCI, then we use one + * mask register, but if the host CPU is an embedded ARM CPU, then we + * use a different mask register (for the same interrupt status + * register). By using the status register to identify the shared mask + * register, the kernel mode driver does not need to know which host + * CPU it is running off. + */ +typedef struct ngbde_irq_reg_s { + + /*! Interrupt status register corresponding to the mask register. */ + uint32_t status_reg; + + /*! Shared interrupt mask register. */ + uint32_t mask_reg; + + /*! Mask identifying the register bits owned by the kernel mode driver. */ + uint32_t kmask; + +} ngbde_irq_reg_t; + +/*! + * \name Interrupt ACK register access flags. + * \anchor NGBDE_INTR_ACK_F_xxx + */ + +/*! \{ */ + +/*! ACK registers resides in PCI bridge I/O window. */ +#define NGBDE_INTR_ACK_F_PAXB (1 << 0) + +/*! \} */ + +/*! + * \brief Interrupt ACK register control. + * + * The structure contains the corresponding register offset + * and value in order to acknowledge interrupt in kernel driver. + * + * For example, if the host CPU is connected via PCI, then we use one + * ACK register, but if the host CPU is an embedded ARM CPU, then we + * use a different ACK register. + */ +typedef struct ngbde_intr_ack_reg_s { + + /*! Ack register offset. */ + uint32_t ack_reg; + + /*! Ack value. */ + uint32_t ack_val; + + /*! Flags to indicate ack_reg resides in PCI bridge window. */ + uint32_t flags; + +} ngbde_intr_ack_reg_t; + +/*! + * \brief BDE interrupt handler. + * + * The BDE will use a function of this type to register an interrupt + * handler with the Linux kernel. + * + * \param [in] data Interrupt handler context. + * + * \retval 0 Interrupt not recognized. + * \retval 1 Interrupt recognized and handled. + */ +typedef int (*ngbde_isr_f)(void *data); + +/*! + * \brief Kernel interrupt control. + * + * This structure controls the sharing of interrupt processing between + * a user mode thread and a kernel mode interrupt handler. + */ +typedef struct ngbde_intr_ctrl_s { + + /*! Handle for device I/O (for writing interrupt registers). */ + uint8_t *iomem; + + /*! Kernel device number (similar to user mode unit number). */ + int kdev; + + /*! Indicates that our interrupt handler is connected to the kernel. */ + int irq_active; + + /*! Interrupt number (IRQ# or MSI vector). */ + int irq_vect; + + /*! Number of interrupt status/mask register pairs. */ + int num_regs; + + /*! Interrupt status/mask register pairs for this device. */ + ngbde_irq_reg_t regs[NGBDE_NUM_IRQ_REGS_MAX]; + + /*! Interrupt ACK register/value for this device. */ + ngbde_intr_ack_reg_t intr_ack; + + /*! Wait queue for user mode interrupt thread. */ + wait_queue_head_t user_thread_wq; + + /*! Flag to wake up user mode interrupt thread. */ + atomic_t run_user_thread; + + /*! Primary interrupt handler. */ + ngbde_isr_f isr_func; + + /*! Context for primary interrupt handler. */ + void *isr_data; + +} ngbde_intr_ctrl_t; + +/*! Convenience macro for 1 kilobyte. */ +#define ONE_KB 1024 + +/*! Convenience macro for 1 megabyte. */ +#define ONE_MB (1024*1024) + +/*! + * \name DMA allocation types. + * \anchor NGBDE_DMA_T_xxx + */ + +/*! \{ */ + +/*! + * Do not allocate any DMA memory. + */ +#define NGBDE_DMA_T_NONE 0 + +/*! + * Try different allocation methods until DMA memory is successfully + * allocated. + */ +#define NGBDE_DMA_T_AUTO 1 + +/*! Use kernel DMA API (dma_alloc_coherent). */ +#define NGBDE_DMA_T_KAPI 2 + +/*! Use page allocator and map to physical address manually. */ +#define NGBDE_DMA_T_PGMEM 3 + +/*! \} */ + +/*! DMA memory allocation control structure. */ +typedef struct ngbde_dmactrl_s { + + /*! Requested size of DMA memory block (in bytes). */ + size_t size; + + /*! Kernel flags for memory allocation. */ + gfp_t flags; + + /*! Preferred DMA memory type (NGBDE_DMA_T_xxx). */ + int pref_type; + + /*! Kernel device for DMA memory management. */ + struct device *dev; + +} ngbde_dmactrl_t; + +/*! DMA memory descriptor. */ +typedef struct ngbde_dmamem_s { + + /*! Logical address of DMA memory block. */ + void *vaddr; + + /*! Physical address of DMA memory block. */ + dma_addr_t paddr; + + /*! Bus address of DMA memory block. */ + dma_addr_t baddr; + + /*! Actual size of DMA memory block (in bytes). */ + size_t size; + + /*! Actual DMA memory type (NGBDE_DMA_T_xxx). */ + int type; + + /*! Kernel device for DMA memory management. */ + struct device *dev; + +} ngbde_dmamem_t; + +/*! DMA memory pool. */ +typedef struct ngbde_dmapool_s { + + /*! DMA control parameters. */ + struct ngbde_dmactrl_s dmactrl; + + /*! DMA memory resources. */ + struct ngbde_dmamem_s dmamem; + +} ngbde_dmapool_t; + +/*! Switch device descriptor. */ +struct ngbde_dev_s { + + /*! Vendor ID (typically PCI vendor ID). */ + uint16_t vendor_id; + + /*! Device ID (typically PCI device ID). */ + uint16_t device_id; + + /*! Device revision (typically PCI revision). */ + uint16_t revision; + + /*! Additional device identification when primary ID is not unique. */ + uint16_t model; + + /*! Bus number (typically PCI bus number). */ + int bus_no; + + /*! Slot number (typically PCI slot number). */ + int slot_no; + + /*! Interrupt line associated with this device. */ + int irq_line; + + /*! Use MSI interrupts with this device. */ + int use_msi; + + /*! Non-zero if device was removed. */ + int inactive; + + /*! Physical I/O window for kernel driver device access. */ + struct ngbde_memwin_s pio_win; + + /*! Memory mapped I/O window for kernel driver device access. */ + uint8_t *pio_mem; + + /*! Physical I/O window for interrupt controller access. */ + struct ngbde_memwin_s iio_win; + + /*! Memory mapped I/O window for interrupt controller access. */ + uint8_t *iio_mem; + + /*! Physical I/O window for device PCI bridge access. */ + struct ngbde_memwin_s paxb_win; + + /*! Memory mapped I/O window for device PCI bridge access. */ + uint8_t *paxb_mem; + + /*! Current value of shared register (typically an IRQ mask register). */ + struct ngbde_shr_reg_s intr_shr_reg[NGBDE_NUM_INTR_SHR_REGS_MAX]; + + /*! Lock for shared register synchronization. */ + spinlock_t lock; + + /*! Interrupt control information. */ + struct ngbde_intr_ctrl_s intr_ctrl[NGBDE_NUM_IRQS_MAX]; + + /*! Linux PCI handle. */ + struct pci_dev *pci_dev; + + /*! Kernel device for DMA memory management. */ + struct device *dma_dev; + + /*! Physical device I/O. */ + struct ngbde_memwin_s iowin[NGBDE_NUM_IOWIN_MAX]; + + /*! DMA memory pools. */ + struct ngbde_dmapool_s dmapool[NGBDE_NUM_DMAPOOL_MAX]; +}; + +/*! + * \brief Linux IOCTL handler. + * + * This function handles communication between user mode and kernel + * mode. + * + * \param [in] file Device file handle. + * \param [in] cmd IOCTL command. + * \param [in] arg IOCTL command argument. + * + * \retval 0 No errors + */ +extern long +ngbde_ioctl(struct file *file, unsigned int cmd, unsigned long arg); + +/*! + * \brief Initialize procfs for BDE driver. + * + * Create procfs read interface for dumping probe information. + * + * \return 0 if no errors, otherwise -1. + */ +extern int +ngbde_procfs_init(void); + +/*! + * \brief Clean up procfs for BDE driver. + * + * Clean up resources allocated by \ref ngbde_procfs_init. + * + * \return 0 if no errors, otherwise -1. + */ +extern int +ngbde_procfs_cleanup(void); + +/*! + * \brief Allocate DMA memory pools for all probed devices. + * + * \return 0 if no errors, otherwise -1. + */ +extern int +ngbde_dma_init(void); + +/*! + * \brief Free DMA memory pools for all probed devices. + * + * \return Nothing. + */ +extern void +ngbde_dma_cleanup(void); + +/*! + * \brief Connect to hardware interrupt handler. + * + * \param [in] kdev Device number. + * \param [in] irq_num Interrupt number (MSI vector). + * + * \retval 0 No errors + * \retval -1 Something went wrong. + */ +extern int +ngbde_intr_connect(int kdev, unsigned int irq_num); + +/*! + * \brief Disconnect from hardware interrupt handler. + * + * \param [in] kdev Device number. + * \param [in] irq_num Interrupt number (MSI vector). + * + * \retval 0 No errors + * \retval -1 Something went wrong. + */ +extern int +ngbde_intr_disconnect(int kdev, unsigned int irq_num); + +/*! + * \brief Disconnect from all hardware interrupt handlers. + */ +void +ngbde_intr_cleanup(void); + +/*! + * \brief Wait for hardware interrupt. + * + * A user mode thread will call this function and sleep until a + * hardware interrupt occurs. + * + * \param [in] kdev Device number. + * \param [in] irq_num Interrupt number (MSI vector). + * + * \retval 0 No errors + * \retval -1 Something went wrong. + */ +extern int +ngbde_intr_wait(int kdev, unsigned int irq_num); + +/*! + * \brief Wake up sleeping interrupt thread. + * + * Wake up interrupt thread even if no interrupt has occurred. + * + * Intended for graceful shut-down procedure. + * + * \param [in] kdev Device number. + * \param [in] irq_num Interrupt number (MSI vector). + * + * \retval 0 No errors + * \retval -1 Something went wrong. + */ +extern int +ngbde_intr_stop(int kdev, unsigned int irq_num); + +/*! + * \brief Clear list of interrupt status/mask registers. + * + * This function is typically called before new interrupt register + * information is added. + * + * \param [in] kdev Device number. + * \param [in] irq_num Interrupt number (MSI vector). + * + * \retval 0 No errors + * \retval -1 Something went wrong. + */ +extern int +ngbde_intr_regs_clr(int kdev, unsigned int irq_num); + +/*! + * \brief Add interrupt status/mask register to monitor. + * + * This function adds a new interrupt status/mask register set to the + * list of registers monitored by the user-mode interrupt handler. + * + * The register list is used to determine whether a user-mode + * interrupt has occurred. + * + * See also \ref ngbde_intr_regs_clr. + * + * \param [in] kdev Device number. + * \param [in] irq_num Interrupt number (MSI vector). + * \param [in] ireg Interrupt status/mask register information. + * + * \retval 0 No errors + * \retval -1 Something went wrong. + */ +extern int +ngbde_intr_reg_add(int kdev, unsigned int irq_num, + struct ngbde_irq_reg_s *ireg); + +/*! + * \brief Add interrupt ack register to monitor. + * + * This function adds a interrupt register and mask value + * to acknowledge corresponding irq_num. + * + * \param [in] kdev Device number. + * \param [in] irq_num Interrupt number (MSI vector). + * \param [in] ackreg Interrupt ack register information. + * + * \retval 0 No errors + * \retval -1 Something went wrong. + */ +extern int +ngbde_intr_ack_reg_add(int kdev, unsigned int irq_num, + struct ngbde_intr_ack_reg_s *ackreg); + +/*! + * \brief Write shared interrupt mask register. + * + * This function is used by an interrupt handler when a shared + * interrupt mask register needs to be updated. + * + * Since the register is shared between multiple interrupt handlers, + * access must be protected by a lock. + * + * The register information provided via \ref ngbde_intr_reg_add is + * used to detemine which bits of the mask register belong to the user + * mode driver. + * + * Note that the mask register to access is referenced by the + * corresponding status register. This is because the mask register + * may be different depending on the host CPU interface being used + * (e.g. PCI vs. AXI). On the other hand, the status register is the + * same irrespective of the host CPU interface. + * + * \param [in] kdev Device number. + * \param [in] irq_num Interrupt number (MSI vector). + * \param [in] kapi Must be set to 1 if called from kernel API. + * \param [in] status_reg Corresponding interrupt status register offset. + * \param [in] mask_val New value to write to mask register. + * + * \retval 0 No errors + * \retval -1 Something went wrong. + */ +extern int +ngbde_intr_mask_write(int kdev, unsigned int irq_num, int kapi, + uint32_t status_reg, uint32_t mask_val); + +/*! + * \brief Probe for PCI-attached Broadcom switch devices. + * + * \return 0 if no errors, otherwise -1. + */ +extern int +ngbde_pci_probe(void); + +/*! + * \brief Clean up resources for PCI-attached Broadcom switch devices. + * + * \return 0 if no errors, otherwise -1. + */ +extern int +ngbde_pci_cleanup(void); + +/*! + * \brief Add new switch device to BDE database. + * + * Add device information for probed or fixed switch device. + * + * \param [in] nd Switch device information. + * + * \return 0 if no errors, otherwise -1. + */ +extern int +ngbde_swdev_add(struct ngbde_dev_s *nd); + +/*! + * \brief Get device information for a BDE switch device. + * + * \param [in] kdev Switch device number. + * + * \return Pointer to switch device structure or NULL on error. + */ +struct ngbde_dev_s * +ngbde_swdev_get(int kdev); + +/*! + * \brief Get list of all probed switch devices. + * + * Return a pointer to the array of registered switch devices. + * + * \param [out] nd Pointer to array of switch devices. + * \param [in] num_nd number of valid entries in switch device array. + * + * \retval 0 No errors + */ +extern int +ngbde_swdev_get_all(struct ngbde_dev_s **nd, unsigned int *num_nd); + +/*! + * \brief Allocate memory using page allocator + * + * For any sizes less than MEM_CHUNK_SIZE, we ask the page allocator + * for the entire memory block, otherwise we try to assemble a + * contiguous cmblock ourselves. + * + * Upon successful allocation, the memory block will be added to the + * global list of allocated memory blocks. + * + * \param [in] size Number of bytes to allocate. + * \param [in] flags Kernel flags (GFP_xxx) for memory allocation. + * + * \return Pointer to allocated memory or NULL if failure. + */ +void * +ngbde_pgmem_alloc(size_t size, gfp_t flags); + +/*! + * \brief Free memory block allocated by ngbde_pgmem_alloc. + * + * \param [in] ptr Pointer returned by ngbde_pgmem_alloc. + * + * \return 0 if succesfully freed, otherwise -1. + */ +extern int +ngbde_pgmem_free(void *ptr); + +/*! + * \brief Free all memory blocks allocated by ngbde_pgmem_alloc. + * + * This function will walk the global list of allocated memory blocks + * and free all associated resources. + * + * Intended for a full clean up before the module is unloaded. + * + * \return Nothing. + */ +extern void +ngbde_pgmem_free_all(void); + +/*! + * \brief Map I/O memory in kernel driver. + * + * This function is used to provide device I/O access to a kernel mode + * driver. + * + * \param [in] devh Device handle (\ref ngbde_dev_s). + * \param [in] addr Physical address to map. + * \param [in] size Size of I/O window to map. + * + * \return Pointer to mapped I/O memory, or NULL on error. + */ +extern void * +ngbde_pio_map(void *devh, phys_addr_t addr, phys_addr_t size); + +/*! + * \brief Unmap I/O memory in kernel driver. + * + * Unmap I/O memory previously mapped via \ref ngbde_pio_map. + * + * \param [in] devh Device handle (\ref ngbde_dev_s). + * + * \return Nothing. + */ +extern void +ngbde_pio_unmap(void *devh); + +/*! + * \brief Unmap all I/O windows. + */ +extern void +ngbde_pio_cleanup(void); + +/*! + * \brief Write a memory-mapped register from kernel driver. + * + * Write a 32-bit register using I/O memory previously mapped via \ref + * ngbde_pio_map. + * + * \param [in] devh Device handle (\ref ngbde_dev_s). + * \param [in] offs Register address offset. + * \param [in] val Value to write to register. + * + * \return Nothing. + */ +extern void +ngbde_pio_write32(void *devh, uint32_t offs, uint32_t val); + +/*! + * \brief Read a memory-mapped register from kernel driver. + * + * Read a 32-bit register using I/O memory previously mapped via \ref + * ngbde_pio_map. + * + * \param [in] devh Device handle (\ref ngbde_dev_s). + * \param [in] offs Register address offset. + * + * \return Value read from register. + */ +extern uint32_t +ngbde_pio_read32(void *devh, uint32_t offs); + +/*! + * \brief Map interrupt controller I/O memory. + * + * On some devices the interrupt controller is a device separate from + * the main switch device. This function is used to provide interrupt + * controller I/O access to a kernel mode driver. + * + * \param [in] devh Device handle (\ref ngbde_dev_s). + * \param [in] addr Physical address to map. + * \param [in] size Size of I/O window to map. + * + * \return Pointer to mapped I/O memory, or NULL on error. + */ +extern void * +ngbde_iio_map(void *devh, phys_addr_t addr, phys_addr_t size); + +/*! + * \brief Unmap interrupt controller I/O memory. + * + * Unmap I/O memory previously mapped via \ref ngbde_iio_map. + * + * \param [in] devh Device handle (\ref ngbde_dev_s). + * + * \return Nothing. + */ +extern void +ngbde_iio_unmap(void *devh); + +/*! + * \brief Unmap all interrupt controller I/O windows. + */ +extern void +ngbde_iio_cleanup(void); + +/*! + * \brief Write a memory-mapped interrupt controller register. + * + * Write a 32-bit register using I/O memory previously mapped via \ref + * ngbde_iio_map. + * + * \param [in] devh Device handle (\ref ngbde_dev_s). + * \param [in] offs Register address offset. + * \param [in] val Value to write to register. + * + * \return Nothing. + */ +extern void +ngbde_iio_write32(void *devh, uint32_t offs, uint32_t val); + +/*! + * \brief Read a memory-mapped interrupt controller register. + * + * Read a 32-bit register using I/O memory previously mapped via \ref + * ngbde_iio_map. + * + * \param [in] devh Device handle (\ref ngbde_dev_s). + * \param [in] offs Register address offset. + * + * \return Value read from register. + */ +extern uint32_t +ngbde_iio_read32(void *devh, uint32_t offs); + +/*! + * \brief Map PCI bridge I/O memory. + * + * On some devices the interrupt controller is a device separate from + * the main switch device. This function is used to provide interrupt + * controller I/O access to a kernel mode driver. + * + * \param [in] devh Device handle (\ref ngbde_dev_s). + * \param [in] addr Physical address to map. + * \param [in] size Size of I/O window to map. + * + * \return Pointer to mapped I/O memory, or NULL on error. + */ +extern void * +ngbde_paxb_map(void *devh, phys_addr_t addr, phys_addr_t size); + +/*! + * \brief Unmap PCI bridge I/O memory. + * + * Unmap I/O memory previously mapped via \ref ngbde_paxb_map. + * + * \param [in] devh Device handle (\ref ngbde_dev_s). + * + * \return Nothing. + */ +extern void +ngbde_paxb_unmap(void *devh); + +/*! + * \brief Unmap all PCI bridge I/O windows. + */ +extern void +ngbde_paxb_cleanup(void); + +/*! + * \brief Probe for Broadcom switch devices on IPROC internal bus. + * + * \return 0 if no errors, otherwise -1. + */ +extern int +ngbde_iproc_probe(void); + +/*! + * \brief Clean up resources for Broadcom switch devices on IPROC internal bus. + * + * \return 0 if no errors, otherwise -1. + */ +extern int +ngbde_iproc_cleanup(void); + +#endif /* NGBDE_H */ diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_dma.c b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_dma.c new file mode 100644 index 000000000000..9cc2b191f48c --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_dma.c @@ -0,0 +1,340 @@ +/*! \file ngbde_dma.c + * + * This module handles allocation of DMA memory pools. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include + +/*! \cond */ +static int dma_debug = 0; +module_param(dma_debug, int, 0); +MODULE_PARM_DESC(dma_debug, +"DMA debug output enable (default 0)."); +/*! \endcond */ + +/*! Default size of of DMA memory pools (in MB). */ +#define DMAPOOL_SIZE_DEFAULT 16 + +/*! Default number of DMA memory pools per device. */ +#define NUM_DMAPOOL_DEFAULT 1 + +/*! \cond */ +static int dma_size = DMAPOOL_SIZE_DEFAULT; +module_param(dma_size, int, 0); +MODULE_PARM_DESC(dma_size, +"Size of of DMA memory pools in MB (default 16 MB)."); +/*! \endcond */ + +/*! \cond */ +static char *dma_alloc; +module_param(dma_alloc, charp, 0); +MODULE_PARM_DESC(dma_alloc, +"DMA allocation method auto|kapi|pgmem (default auto)"); +/*! \endcond */ + +/*! \cond */ +static int dma_pools = NUM_DMAPOOL_DEFAULT; +module_param(dma_pools, int, 0); +MODULE_PARM_DESC(dma_pools, +"Number of DMA memory pools to pre-allocate per device (default 1)."); +/*! \endcond */ + +/*! + * \brief Allocate DMA memory via kernel API. + * + * \param [in] dmactrl DMA allocation control. + * \param [out] dmamem DMA allocation result. + * + * \return Nothing. + */ +static void +ngbde_dmamem_kapi_alloc(ngbde_dmactrl_t *dmactrl, ngbde_dmamem_t *dmamem) +{ + void *vaddr; + dma_addr_t baddr; + + vaddr = dma_alloc_coherent(dmactrl->dev, dmactrl->size, &baddr, + dmactrl->flags); + if (vaddr) { + /* Store allocation information in dmamem structure */ + dmamem->vaddr = vaddr; + dmamem->paddr = virt_to_phys(vaddr); + dmamem->dev = dmactrl->dev; + dmamem->size = dmactrl->size; + dmamem->type = NGBDE_DMA_T_KAPI; + dmamem->baddr = baddr; + + /* Write small signature for debug purposes */ + strcpy((char *)vaddr, "DMA_KAPI"); + + if (dma_debug) { + printk("DMA: Allocated %d KB of KAPI memory at 0x%08lx\n", + (int)(dmamem->size / ONE_KB), + (unsigned long)dmamem->paddr); + } + } else { + if (dma_debug) { + printk("DMA: Failed to allocate KAPI memory\n"); + } + } +} + +/*! + * \brief Allocate DMA memory via page allocator. + * + * \param [in] dmactrl DMA allocation control. + * \param [out] dmamem DMA allocation result. + * + * \return Nothing. + */ +static void +ngbde_dmamem_pgmem_alloc(ngbde_dmactrl_t *dmactrl, ngbde_dmamem_t *dmamem) +{ + void *vaddr; + + vaddr = ngbde_pgmem_alloc(dmactrl->size, dmactrl->flags); + if (vaddr) { + /* Store allocation information in dmamem structure */ + dmamem->vaddr = vaddr; + dmamem->paddr = virt_to_phys(vaddr); + dmamem->dev = dmactrl->dev; + dmamem->size = dmactrl->size; + dmamem->type = NGBDE_DMA_T_PGMEM; + dmamem->baddr = dma_map_single(dmamem->dev, dmamem->vaddr, + dmamem->size, DMA_BIDIRECTIONAL); + if (dma_mapping_error(dmactrl->dev, dmamem->baddr)) { + dmamem->baddr = 0; + if (dma_debug) { + printk("DMA: Failed to map PGMEM memory\n"); + } + } + + /* Write small signature for debug purposes */ + strcpy((char *)vaddr, "DMA_PGMEM"); + + if (dma_debug) { + printk("DMA: Allocated %d KB of PGMEM memory at 0x%08lx\n", + (int)(dmamem->size / ONE_KB), + (unsigned long)dmamem->paddr); + } + } else { + if (dma_debug) { + printk("DMA: Failed to allocate PGMEM memory\n"); + } + } +} + +/*! + * \brief Allocate DMA memory. + * + * Depending on the DMA allocation control parameters, we select one + * of several DMA memory allocation methods. + * + * \param [in] dmactrl DMA allocation control. + * \param [out] dmamem DMA allocation result. + * + * \return Nothing. + */ +static int +ngbde_dmamem_alloc(ngbde_dmactrl_t *dmactrl, ngbde_dmamem_t *dmamem) +{ + int kapi = 0; + + if (dmamem->vaddr) { + /* Already allocated */ + return 0; + } + +#ifdef CONFIG_CMA + /* Always allow KAPI when CMA is available */ + kapi = 1; +#else + if (dmactrl->size <= (1 << (MAX_ORDER - 1 + PAGE_SHIFT))) { + kapi = 1; + } +#endif + + /* Allocation via kernel DMA API (if allowed) */ + if (kapi) { + switch (dmactrl->pref_type) { + case NGBDE_DMA_T_AUTO: + case NGBDE_DMA_T_KAPI: + ngbde_dmamem_kapi_alloc(dmactrl, dmamem); + break; + default: + break; + } + } + + /* Allocation via private page allocator */ + if (dmamem->vaddr == NULL) { + switch (dmactrl->pref_type) { + case NGBDE_DMA_T_AUTO: + case NGBDE_DMA_T_PGMEM: + ngbde_dmamem_pgmem_alloc(dmactrl, dmamem); + break; + default: + break; + } + } + + if (dmamem->vaddr == NULL) { + printk(KERN_WARNING "%s: Failed to allocate DMA memory\n", + MOD_NAME); + return -1; + } + + return 0; +} + +/*! + * \brief Free DMA memory. + * + * Free DMA memory allocated via \ref ngbde_dmamem_alloc. + * + * \param [in] dmamem DMA allocation result from \ref ngbde_dmamem_alloc. + * + * \return Nothing. + */ +static int +ngbde_dmamem_free(ngbde_dmamem_t *dmamem) +{ + switch (dmamem->type) { + case NGBDE_DMA_T_KAPI: + if (dma_debug) { + printk("DMA: Freeing %d KB of KAPI memory\n", + (int)(dmamem->size / ONE_KB)); + } + dma_free_coherent(dmamem->dev, dmamem->size, + dmamem->vaddr, dmamem->paddr); + memset(dmamem, 0, sizeof(*dmamem)); + break; + case NGBDE_DMA_T_PGMEM: + if (dma_debug) { + printk("DMA: Freeing %d KB of PGMEM memory\n", + (int)(dmamem->size / ONE_KB)); + } + if (dmamem->baddr) { + if (dma_debug) { + printk("DMA: Unmapping PGMEM memory at 0x%08lx\n", + (unsigned long)dmamem->baddr); + } + dma_unmap_single(dmamem->dev, dmamem->baddr, + dmamem->size, DMA_BIDIRECTIONAL); + } + ngbde_pgmem_free(dmamem->vaddr); + memset(dmamem, 0, sizeof(*dmamem)); + break; + case NGBDE_DMA_T_NONE: + /* Nothing to free */ + break; + default: + printk(KERN_WARNING "%s: Unable to free unknown DMA memory type\n", + MOD_NAME); + break; + } + return 0; +} + +/*! + * \brief Free all DMA memory pools for all devices. + * + * \return Nothing. + */ +void +ngbde_dma_cleanup(void) +{ + struct ngbde_dev_s *swdev; + unsigned int num_swdev, idx; + unsigned int pool; + + ngbde_swdev_get_all(&swdev, &num_swdev); + + for (idx = 0; idx < num_swdev; idx++) { + for (pool = 0; pool < NGBDE_NUM_DMAPOOL_MAX; pool++) { + if (swdev[idx].inactive) { + ngbde_dmamem_free(&swdev[idx].dmapool[pool].dmamem); + } + } + } +} + +/*! + * \brief Allocate DMA memory pools for all devices. + * + * \return Nothing. + */ +int +ngbde_dma_init(void) +{ + int rv; + struct ngbde_dev_s *swdev; + unsigned int num_swdev, idx; + int dma_type = NGBDE_DMA_T_AUTO; + struct ngbde_dmapool_s *dmapool; + unsigned int pool; + + /* Default DMA memory size per device */ + if (dma_size < 0) { + dma_size = DMAPOOL_SIZE_DEFAULT; + } + + /* Check for forced DMA allocation method */ + if (dma_alloc) { + if (strcmp(dma_alloc, "kapi") == 0) { + dma_type = NGBDE_DMA_T_KAPI; + } else if (strcmp(dma_alloc, "pgmem") == 0) { + dma_type = NGBDE_DMA_T_PGMEM; + } else { + printk(KERN_WARNING "%s: Unknown DMA type: %s\n", + MOD_NAME, dma_alloc); + } + } + + /* Number of DMA memory pools per device */ + if ((unsigned int)dma_pools >= NGBDE_NUM_DMAPOOL_MAX) { + dma_pools = NUM_DMAPOOL_DEFAULT; + } + + ngbde_swdev_get_all(&swdev, &num_swdev); + + for (idx = 0; idx < num_swdev; idx++) { + + /* Set DMA allocation parameters */ + for (pool = 0; pool < NGBDE_NUM_DMAPOOL_MAX; pool++) { + dmapool = &swdev[idx].dmapool[pool]; + dmapool->dmactrl.dev = swdev[idx].dma_dev; + dmapool->dmactrl.size = dma_size * ONE_MB; + dmapool->dmactrl.pref_type = dma_type; + dmapool->dmactrl.flags = GFP_KERNEL | GFP_DMA32; + } + + /* Allocate DMA pools */ + for (pool = 0; pool < dma_pools; pool++) { + dmapool = &swdev[idx].dmapool[pool]; + rv = ngbde_dmamem_alloc(&dmapool->dmactrl, &dmapool->dmamem); + if (rv < 0) { + printk(KERN_WARNING "%s: Unable to allocate DMA pool %d %d\n", + MOD_NAME, idx, pool); + } + } + } + return 0; +} diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_iio.c b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_iio.c new file mode 100644 index 000000000000..e97f1fcea730 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_iio.c @@ -0,0 +1,143 @@ +/*! \file ngbde_iio.c + * + * API for managing and accessing memory-mapped I/O for interrupt + * controller registers. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include + +void * +ngbde_iio_map(void *devh, phys_addr_t addr, phys_addr_t size) +{ + struct ngbde_dev_s *sd = (struct ngbde_dev_s *)devh; + + if (sd->iio_mem) { + if (addr == sd->iio_win.addr && size == sd->iio_win.size) { + /* Already mapped */ + return sd->iio_mem; + } + ngbde_iio_unmap(devh); + } + + sd->iio_mem = ioremap_nocache(addr, size); + + if (sd->iio_mem) { + /* Save mapped resources */ + sd->iio_win.addr = addr; + sd->iio_win.size = size; + } + + return sd->iio_mem; +} + +void +ngbde_iio_unmap(void *devh) +{ + struct ngbde_dev_s *sd = (struct ngbde_dev_s *)devh; + + if (sd->iio_mem) { + iounmap(sd->iio_mem); + sd->iio_mem = NULL; + } +} + +void +ngbde_iio_cleanup(void) +{ + struct ngbde_dev_s *swdev, *sd; + unsigned int num_swdev, idx; + + ngbde_swdev_get_all(&swdev, &num_swdev); + + for (idx = 0; idx < num_swdev; idx++) { + sd = ngbde_swdev_get(idx); + ngbde_iio_unmap(sd); + } +} + +void +ngbde_iio_write32(void *devh, uint32_t offs, uint32_t val) +{ + struct ngbde_dev_s *sd = (struct ngbde_dev_s *)devh; + + if (sd->iio_mem) { + NGBDE_IOWRITE32(val, sd->iio_mem + offs); + } +} + +uint32_t +ngbde_iio_read32(void *devh, uint32_t offs) +{ + struct ngbde_dev_s *sd = (struct ngbde_dev_s *)devh; + + if (sd->iio_mem) { + return NGBDE_IOREAD32(sd->iio_mem + offs); + } + return 0; +} + +void * +ngbde_paxb_map(void *devh, phys_addr_t addr, phys_addr_t size) +{ + struct ngbde_dev_s *sd = (struct ngbde_dev_s *)devh; + + if (sd->paxb_mem) { + if (addr == sd->paxb_win.addr && size == sd->paxb_win.size) { + /* Already mapped */ + return sd->paxb_mem; + } + iounmap(sd->paxb_mem); + } + + sd->paxb_mem = ioremap_nocache(addr, size); + + if (sd->paxb_mem) { + /* Save mapped resources */ + sd->paxb_win.addr = addr; + sd->paxb_win.size = size; + } + + return sd->paxb_mem; +} + +void +ngbde_paxb_unmap(void *devh) +{ + struct ngbde_dev_s *sd = (struct ngbde_dev_s *)devh; + + if (sd->paxb_mem) { + iounmap(sd->paxb_mem); + sd->paxb_mem = NULL; + } +} + +void +ngbde_paxb_cleanup(void) +{ + struct ngbde_dev_s *swdev, *sd; + unsigned int num_swdev, idx; + + ngbde_swdev_get_all(&swdev, &num_swdev); + + for (idx = 0; idx < num_swdev; idx++) { + sd = ngbde_swdev_get(idx); + ngbde_paxb_unmap(sd); + } +} diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_intr.c b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_intr.c new file mode 100644 index 000000000000..acec7da100f7 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_intr.c @@ -0,0 +1,550 @@ +/*! \file ngbde_intr.c + * + * API for controlling a thread-based user-mode interrupt handler. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include + +/*! \cond */ +static int intr_debug = 0; +module_param(intr_debug, int, 0); +MODULE_PARM_DESC(intr_debug, +"Interrupt debug output enable (default 0)."); +/*! \endcond */ + +static int +ngbde_intr_shared_write32(struct ngbde_dev_s *sd, struct ngbde_intr_ctrl_s *ic, + uint32_t reg_offs, uint32_t reg_val, uint32_t shr_mask) +{ + unsigned long flags; + struct ngbde_shr_reg_s *sr; + int idx; + + sr = NULL; + for (idx = 0; idx < NGBDE_NUM_INTR_SHR_REGS_MAX; idx++) { + if (sd->intr_shr_reg[idx].reg_offs == 0) { + /* If not found, then we add a new entry */ + sd->intr_shr_reg[idx].reg_offs = reg_offs; + } + if (sd->intr_shr_reg[idx].reg_offs == reg_offs) { + sr = &sd->intr_shr_reg[idx]; + break; + } + } + + if (sr == NULL) { + return -1; + } + + spin_lock_irqsave(&sd->lock, flags); + + sr->cur_val &= ~shr_mask; + sr->cur_val |= (reg_val & shr_mask); + + NGBDE_IOWRITE32(sr->cur_val, ic->iomem + reg_offs); + + spin_unlock_irqrestore(&sd->lock, flags); + + return 0; +} + +/*! + * \brief Interrupt handler for user mode thread. + * + * This function will determine whether a user-mode interrupt has + * occurred by reading the configured interrupt status and mask + * registers. + * + * If an interrupt has occurred, any waiting user-mode thread is woken + * up. + * + * \param [in] ic Interrupt control information. + * + * \retval 1 One or more user mode interrupts occurred. + * \retval 0 No user mode interrupts occurred. + */ +static int +ngbde_user_isr(ngbde_intr_ctrl_t *ic) +{ + int idx; + int active_interrupts = 0; + uint32_t stat = 0, mask = 0; + uint32_t kmask; + + /* Check if any enabled interrupts are active */ + for (idx = 0; idx < ic->num_regs; idx++) { + ngbde_irq_reg_t *ir = &ic->regs[idx]; + + /* Get mask of all kernel interrupt sources for this register address */ + kmask = ir->kmask; + + stat = NGBDE_IOREAD32(&ic->iomem[ir->status_reg]); + mask = NGBDE_IOREAD32(&ic->iomem[ir->mask_reg]); + + if (stat & mask & ~kmask) { + active_interrupts = 1; + break; + } + } + + /* No active interrupts to service */ + if (!active_interrupts) { + return 0; + } + + /* Disable (mask off) all interrupts */ + for (idx = 0; idx < ic->num_regs; idx++) { + ngbde_irq_reg_t *ir = &ic->regs[idx]; + + /* Get mask of all kernel interrupt sources for this register address */ + kmask = ir->kmask; + + if (kmask == 0xffffffff) { + /* Kernel driver owns all interrupts in this register */ + continue; + } else if (kmask) { + /* Synchronized write */ + struct ngbde_dev_s *sd = ngbde_swdev_get(ic->kdev); + if (ngbde_intr_shared_write32(sd, ic, ir->mask_reg, 0, ~kmask) < 0) { + printk(KERN_WARNING + "%s: Failed to write shared register for device %d\n", + MOD_NAME, ic->kdev); + /* Fall back to normal write to ensure interrupts are masked */ + NGBDE_IOWRITE32(0, &ic->iomem[ir->mask_reg]); + } + } else { + NGBDE_IOWRITE32(0, &ic->iomem[ir->mask_reg]); + } + } + + atomic_set(&ic->run_user_thread, 1); + wake_up_interruptible(&ic->user_thread_wq); + + return 1; +} + +/*! + * \brief Interrupt handler for kernel driver. + * + * Typically used by the KNET driver. + * + * \param [in] ic Interrupt control information. + * + * \retval 1 One or more kernel mode interrupts occurred. + * \retval 0 No kernel mode interrupts occurred. + */ +static int +ngbde_kernel_isr(ngbde_intr_ctrl_t *ic) +{ + if (ic->isr_func) { + return ic->isr_func(ic->isr_data); + } + return 0; +} + +/*! + * \brief Acknowledge interrupt + * + * \param [in] data Interrupt control information + * + * \retval 0 + */ +static int +ngbde_intr_ack(ngbde_intr_ctrl_t *ic) +{ + struct ngbde_dev_s *sd = ngbde_swdev_get(ic->kdev); + struct ngbde_intr_ack_reg_s *ar = &ic->intr_ack; + + if (sd->use_msi) { + if (ar->flags & NGBDE_INTR_ACK_F_PAXB) { + NGBDE_IOWRITE32(ar->ack_val, &sd->paxb_mem[ar->ack_reg]); + } else { + NGBDE_IOWRITE32(ar->ack_val, &sd->pio_mem[ar->ack_reg]); + } + } + + return 0; +} + +/*! + * \brief Linux ISR + * + * Will call the user-mode interrupts handler and optionally also a + * kernel mode interrupt handler (typically KNET). + * + * \param [in] irq_num Interrupt vector from kernel. + * \param [in] data Interrupt control information + * + * \retval IRQ_NONE Interrupt not recognized. + * \retval IRQ_HANDLED Interrupt recognized and handled (masked off). + */ +static irqreturn_t +ngbde_isr(int irq_num, void *data) +{ + struct ngbde_intr_ctrl_s *ic = (struct ngbde_intr_ctrl_s *)data; + irqreturn_t rv = IRQ_NONE; + + ngbde_intr_ack(ic); + + if (ngbde_user_isr(ic)) { + rv = IRQ_HANDLED; + } + if (ngbde_kernel_isr(ic)) { + rv = IRQ_HANDLED; + } + return rv; +} + +int +ngbde_intr_connect(int kdev, unsigned int irq_num) +{ + struct ngbde_dev_s *sd; + struct ngbde_intr_ctrl_s *ic; + unsigned long irq_flags; + + sd = ngbde_swdev_get(kdev); + if (!sd) { + return -1; + } + + if (irq_num >= NGBDE_NUM_IRQS_MAX) { + return -1; + } + + ic = &sd->intr_ctrl[irq_num]; + + if (ic->irq_active) { + return 0; + } + + if (sd->irq_line >= 0) { + if (sd->pio_mem == NULL) { + printk(KERN_WARNING "%s: No memory-mapped I/O for device %d\n", + MOD_NAME, kdev); + return -1; + } + ic->kdev = kdev; + ic->iomem = sd->pio_mem; + if (sd->iio_mem) { + if (intr_debug) { + printk("INTR: Using dedicated interrupt controller\n"); + } + ic->iomem = sd->iio_mem; + } + init_waitqueue_head(&ic->user_thread_wq); + atomic_set(&ic->run_user_thread, 0); + irq_flags = IRQF_SHARED; + ic->irq_vect = sd->irq_line; + + /* + * The pci_enable_msi function must be called after enabling + * BAR0_PAXB_OARR_FUNC0_MSI_PAGE, otherwise, MSI interrupts + * cannot be triggered! + */ + if (sd->use_msi) { + if (pci_enable_msi(sd->pci_dev) == 0) { + irq_flags = 0; + ic->irq_vect = sd->pci_dev->irq; + if (intr_debug) { + printk("INTR: Enabled MSI interrupts\n"); + } + } else { + printk(KERN_WARNING "%s: Failed to enable MSI for device %d\n", + MOD_NAME, kdev); + sd->use_msi = 0; + } + } + if (intr_debug) { + printk("INTR: Request IRQ %d\n", ic->irq_vect); + } + if (request_irq(ic->irq_vect, ngbde_isr, irq_flags, MOD_NAME, ic) < 0) { + printk(KERN_WARNING "%s: Could not get IRQ %d for device %d\n", + MOD_NAME, ic->irq_vect, kdev); + return -1; + } + ic->irq_active = 1; + } + + return 0; +} + +int +ngbde_intr_disconnect(int kdev, unsigned int irq_num) +{ + struct ngbde_dev_s *sd; + struct ngbde_intr_ctrl_s *ic; + + sd = ngbde_swdev_get(kdev); + if (!sd) { + return -1; + } + + if (irq_num >= NGBDE_NUM_IRQS_MAX) { + return -1; + } + + ic = &sd->intr_ctrl[irq_num]; + + if (!ic->irq_active) { + return 0; + } + + if (ic->isr_func) { + printk(KERN_WARNING "%s: Disconnecting IRQ %d blocked by kernel ISR\n", + MOD_NAME, irq_num); + return 0; + } + + if (ic->irq_vect >= 0) { + free_irq(ic->irq_vect, ic); + if (sd->use_msi) { + pci_disable_msi(sd->pci_dev); + } + ic->irq_active = 0; + } + + return 0; +} + +void +ngbde_intr_cleanup(void) +{ + struct ngbde_dev_s *swdev; + unsigned int num_swdev, idx, irq_num; + + ngbde_swdev_get_all(&swdev, &num_swdev); + + for (idx = 0; idx < num_swdev; idx++) { + for (irq_num = 0; irq_num < NGBDE_NUM_IRQS_MAX; irq_num++) { + ngbde_intr_disconnect(idx, irq_num); + } + } +} + +int +ngbde_intr_wait(int kdev, unsigned int irq_num) +{ + struct ngbde_dev_s *sd; + struct ngbde_intr_ctrl_s *ic; + + sd = ngbde_swdev_get(kdev); + if (!sd) { + return -1; + } + + if (irq_num >= NGBDE_NUM_IRQS_MAX) { + return -1; + } + + ic = &sd->intr_ctrl[irq_num]; + + if (!ic->irq_active) { + return 0; + } + + wait_event_interruptible(ic->user_thread_wq, + atomic_read(&ic->run_user_thread) != 0); + atomic_set(&ic->run_user_thread, 0); + + return 0; +} + +int +ngbde_intr_stop(int kdev, unsigned int irq_num) +{ + struct ngbde_dev_s *sd; + struct ngbde_intr_ctrl_s *ic; + + sd = ngbde_swdev_get(kdev); + if (!sd) { + return -1; + } + + if (irq_num >= NGBDE_NUM_IRQS_MAX) { + return -1; + } + + ic = &sd->intr_ctrl[irq_num]; + + if (!ic->irq_active) { + return 0; + } + + /* Wake up user thread */ + atomic_set(&ic->run_user_thread, 1); + wake_up_interruptible(&ic->user_thread_wq); + + return 0; +} + +int +ngbde_intr_regs_clr(int kdev, unsigned int irq_num) +{ + struct ngbde_dev_s *sd; + struct ngbde_intr_ctrl_s *ic; + + sd = ngbde_swdev_get(kdev); + if (!sd) { + return -1; + } + + if (irq_num >= NGBDE_NUM_IRQS_MAX) { + return -1; + } + + ic = &sd->intr_ctrl[irq_num]; + + if (ic->irq_active) { + /* Do not clear configuration with interrupt connected */ + return 0; + } + + ic->num_regs = 0; + memset(ic->regs, 0, sizeof(ic->regs)); + + return 0; +} + +int +ngbde_intr_reg_add(int kdev, unsigned int irq_num, + struct ngbde_irq_reg_s *ireg) +{ + struct ngbde_dev_s *sd; + struct ngbde_intr_ctrl_s *ic; + struct ngbde_irq_reg_s *ir; + unsigned int idx; + + sd = ngbde_swdev_get(kdev); + if (!sd) { + return -1; + } + + if (irq_num >= NGBDE_NUM_IRQS_MAX) { + return -1; + } + + ic = &sd->intr_ctrl[irq_num]; + + if (ic->irq_active) { + /* + * If the interrupt is connected, then we only update the + * kernel mask for existing entries. + */ + for (idx = 0; idx < ic->num_regs; idx++) { + ir = &ic->regs[idx]; + if (ir->status_reg == ireg->status_reg && + ir->mask_reg == ireg->mask_reg) { + ir->kmask = ireg->kmask; + if (intr_debug) { + printk("INTR: Updating interrupt register " + "0x%08x/0x%08x (0x%08x)\n", + ir->status_reg, ir->mask_reg, ir->kmask); + } + return 0; + } + } + return -1; + } + + if (ic->num_regs >= NGBDE_NUM_IRQ_REGS_MAX) { + return -1; + } + + ir = &ic->regs[ic->num_regs++]; + + memcpy(ir, ireg, sizeof (*ir)); + + if (intr_debug) { + printk("INTR: Adding interrupt register 0x%08x/0x%08x (0x%08x)\n", + ir->status_reg, ir->mask_reg, ir->kmask); + } + + return ic->num_regs; +} + +int +ngbde_intr_ack_reg_add(int kdev, unsigned int irq_num, + struct ngbde_intr_ack_reg_s *ackreg) +{ + struct ngbde_dev_s *sd; + struct ngbde_intr_ctrl_s *ic; + struct ngbde_intr_ack_reg_s *ar; + + sd = ngbde_swdev_get(kdev); + if (!sd) { + return -1; + } + + if (irq_num >= NGBDE_NUM_IRQS_MAX) { + return -1; + } + + ic = &sd->intr_ctrl[irq_num]; + + if (ic->irq_active) { + /* Ignore request if interrupt is connected */ + return 0; + } + + ar = &ic->intr_ack; + + memcpy(ar, ackreg, sizeof (*ar)); + + if (intr_debug) { + printk("INTR: Adding interrupt ACK register 0x%08x/0x%08x (0x%08x)\n", + ar->ack_reg, ar->ack_val, ar->flags); + } + + return 0; +} + +int +ngbde_intr_mask_write(int kdev, unsigned int irq_num, int kapi, + uint32_t status_reg, uint32_t mask_val) +{ + struct ngbde_dev_s *sd; + struct ngbde_intr_ctrl_s *ic; + struct ngbde_irq_reg_s *ir; + unsigned int idx; + uint32_t bmask; + + sd = ngbde_swdev_get(kdev); + if (!sd) { + return -1; + } + + if (irq_num >= NGBDE_NUM_IRQS_MAX) { + return -1; + } + + ic = &sd->intr_ctrl[irq_num]; + + ir = ic->regs; + for (idx = 0; idx < ic->num_regs; idx++) { + if (ir->status_reg == status_reg) { + bmask = kapi ? ir->kmask : ~ir->kmask; + ngbde_intr_shared_write32(sd, ic, ir->mask_reg, mask_val, bmask); + return 0; + } + ir++; + } + + return -1; +} diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_ioctl.c b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_ioctl.c new file mode 100644 index 000000000000..ccd0b7ee01d0 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_ioctl.c @@ -0,0 +1,237 @@ +/*! \file ngbde_ioctl.c + * + * NGBDE IOCTL interface. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include + +#include + +long +ngbde_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct ngbde_ioc_cmd_s ioc; + struct ngbde_dev_s *swdev; + struct ngbde_irq_reg_s ireg; + struct ngbde_intr_ack_reg_s ackreg; + phys_addr_t addr, size; + unsigned int num_swdev; + unsigned int rsrc_type, rsrc_idx; + unsigned int irq_num, intr_cmd; + uint32_t mreg, mval; + + if (copy_from_user(&ioc, (void *)arg, sizeof(ioc))) { + return -EFAULT; + } + + ioc.rc = NGBDE_IOC_SUCCESS; + + switch (cmd) { + case NGBDE_IOC_MOD_INFO: + ioc.op.mod_info.version = NGBDE_IOC_VERSION; + break; + case NGBDE_IOC_PROBE_INFO: + ngbde_swdev_get_all(NULL, &num_swdev); + ioc.op.probe_info.num_swdev = num_swdev; + break; + case NGBDE_IOC_DEV_INFO: + swdev = ngbde_swdev_get(ioc.devid); + if (!swdev) { + ioc.rc = NGBDE_IOC_FAIL; + break; + } + ioc.op.dev_info.vendor_id = swdev->vendor_id; + ioc.op.dev_info.device_id = swdev->device_id; + ioc.op.dev_info.revision = swdev->revision; + ioc.op.dev_info.model = swdev->model; + if (swdev->use_msi) { + ioc.op.dev_info.flags |= NGBDE_DEV_F_MSI; + } + break; + case NGBDE_IOC_PHYS_ADDR: + swdev = ngbde_swdev_get(ioc.devid); + if (!swdev) { + ioc.rc = NGBDE_IOC_FAIL; + break; + } + rsrc_type = ioc.op.rsrc_id.type; + rsrc_idx = ioc.op.rsrc_id.inst; + switch (rsrc_type) { + case NGBDE_IO_RSRC_DEV_IO: + if (rsrc_idx >= NGBDE_NUM_IOWIN_MAX) { + printk(KERN_WARNING + "ngbde: invalid resource index (%d)\n", + rsrc_idx); + ioc.rc = NGBDE_IOC_FAIL; + break; + } + ioc.op.phys_addr.addr = swdev->iowin[rsrc_idx].addr; + ioc.op.phys_addr.size = swdev->iowin[rsrc_idx].size; + break; + case NGBDE_IO_RSRC_DMA_MEM: + if (rsrc_idx >= NGBDE_NUM_DMAPOOL_MAX) { + printk(KERN_WARNING + "ngbde: invalid resource index (%d)\n", + rsrc_idx); + ioc.rc = NGBDE_IOC_FAIL; + break; + } + ioc.op.phys_addr.addr = swdev->dmapool[rsrc_idx].dmamem.paddr; + ioc.op.phys_addr.size = swdev->dmapool[rsrc_idx].dmactrl.size; + break; + case NGBDE_IO_RSRC_DMA_BUS: + if (rsrc_idx >= NGBDE_NUM_DMAPOOL_MAX) { + printk(KERN_WARNING + "ngbde: invalid resource index (%d)\n", + rsrc_idx); + ioc.rc = NGBDE_IOC_FAIL; + break; + } + ioc.op.phys_addr.addr = swdev->dmapool[rsrc_idx].dmamem.baddr; + ioc.op.phys_addr.size = swdev->dmapool[rsrc_idx].dmactrl.size; + break; + default: + printk(KERN_WARNING + "ngbde: unknown resource type (%d)\n", + rsrc_type); + ioc.rc = NGBDE_IOC_FAIL; + break; + } + break; + case NGBDE_IOC_INTR_CTRL: + irq_num = ioc.op.intr_ctrl.irq_num; + intr_cmd = ioc.op.intr_ctrl.cmd; + switch (intr_cmd) { + case NGBDE_ICTL_INTR_CONN: + if (ngbde_intr_connect(ioc.devid, irq_num) < 0) { + ioc.rc = NGBDE_IOC_FAIL; + } + break; + case NGBDE_ICTL_INTR_DISC: + if (ngbde_intr_disconnect(ioc.devid, irq_num) < 0) { + ioc.rc = NGBDE_IOC_FAIL; + } + break; + case NGBDE_ICTL_INTR_WAIT: + if (ngbde_intr_wait(ioc.devid, irq_num) < 0) { + ioc.rc = NGBDE_IOC_FAIL; + } + break; + case NGBDE_ICTL_INTR_STOP: + if (ngbde_intr_stop(ioc.devid, irq_num) < 0) { + ioc.rc = NGBDE_IOC_FAIL; + } + break; + case NGBDE_ICTL_REGS_CLR: + if (ngbde_intr_regs_clr(ioc.devid, irq_num) < 0) { + ioc.rc = NGBDE_IOC_FAIL; + } + break; + default: + printk(KERN_WARNING + "%s: unknown interrupt control command (%d)\n", + MOD_NAME, intr_cmd); + ioc.rc = NGBDE_IOC_FAIL; + break; + } + break; + case NGBDE_IOC_IRQ_REG_ADD: + irq_num = ioc.op.irq_reg_add.irq_num; + ireg.status_reg = ioc.op.irq_reg_add.status_reg; + ireg.mask_reg = ioc.op.irq_reg_add.mask_reg; + ireg.kmask = ioc.op.irq_reg_add.kmask; + if (ngbde_intr_reg_add(ioc.devid, irq_num, &ireg) < 0) { + printk(KERN_WARNING + "%s: Unable to add interrupt register\n", + MOD_NAME); + ioc.rc = NGBDE_IOC_FAIL; + } + break; + case NGBDE_IOC_INTR_ACK_REG_ADD: + irq_num = ioc.op.intr_ack_reg_add.irq_num; + ackreg.ack_reg = ioc.op.intr_ack_reg_add.ack_reg; + ackreg.ack_val = ioc.op.intr_ack_reg_add.ack_val; + ackreg.flags = ioc.op.intr_ack_reg_add.flags; + if (ngbde_intr_ack_reg_add(ioc.devid, irq_num, &ackreg) < 0) { + printk(KERN_WARNING + "%s: Unable to add interrupt ack register\n", + MOD_NAME); + ioc.rc = NGBDE_IOC_FAIL; + } + break; + case NGBDE_IOC_IRQ_MASK_WR: + irq_num = ioc.op.irq_mask_wr.irq_num; + mreg = ioc.op.irq_mask_wr.offs; + mval = ioc.op.irq_mask_wr.val; + if (ngbde_intr_mask_write(ioc.devid, irq_num, 0, mreg, mval) < 0) { + printk(KERN_WARNING + "%s: Unable to write shared register\n", + MOD_NAME); + ioc.rc = NGBDE_IOC_FAIL; + } + break; + case NGBDE_IOC_PIO_WIN_MAP: + swdev = ngbde_swdev_get(ioc.devid); + if (!swdev) { + ioc.rc = NGBDE_IOC_FAIL; + break; + } + addr = ioc.op.pio_win.addr; + size = ioc.op.pio_win.size; + if (ngbde_pio_map(swdev, addr, size) == NULL) { + ioc.rc = NGBDE_IOC_FAIL; + } + break; + case NGBDE_IOC_IIO_WIN_MAP: + swdev = ngbde_swdev_get(ioc.devid); + if (!swdev) { + ioc.rc = NGBDE_IOC_FAIL; + break; + } + addr = ioc.op.pio_win.addr; + size = ioc.op.pio_win.size; + if (ngbde_iio_map(swdev, addr, size) == NULL) { + ioc.rc = NGBDE_IOC_FAIL; + } + break; + case NGBDE_IOC_PAXB_WIN_MAP: + swdev = ngbde_swdev_get(ioc.devid); + if (!swdev) { + ioc.rc = NGBDE_IOC_FAIL; + break; + } + addr = ioc.op.pio_win.addr; + size = ioc.op.pio_win.size; + if (ngbde_paxb_map(swdev, addr, size) == NULL) { + ioc.rc = NGBDE_IOC_FAIL; + } + break; + default: + printk(KERN_ERR "ngbde: invalid ioctl (%08x)\n", cmd); + ioc.rc = NGBDE_IOC_FAIL; + break; + } + + if (copy_to_user((void *)arg, &ioc, sizeof(ioc))) { + return -EFAULT; + } + + return 0; +} diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_iproc_probe.c b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_iproc_probe.c new file mode 100644 index 000000000000..63b02a4075a3 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_iproc_probe.c @@ -0,0 +1,164 @@ +/*! \file ngbde_iproc_probe.c + * + * BDE probe for IPROC internal bus devices. + * + * Validate CMICD existence on the platform. If Linux device tree matched, + * probe function of platform driver is called and the switch device read from + * CMICD register is added to the device list. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include +#include +#include + +/*! \cond */ +static int iproc_debug = 0; +module_param(iproc_debug, int, 0); +MODULE_PARM_DESC(iproc_debug, +"IPROC debug output enable (default 0)."); +/*! \endcond */ + +/*! + * \brief Probe devices on the IPROC internal bus. + * + * \param [in] pldev Platform device. + * + * \retval 0 No errors + * \retval -1 Something went wrong. + */ +static int +iproc_cmicd_probe(struct platform_device *pldev) +{ + int rv; + uint32_t size; + void *base_address; + uint32_t dev_rev_id; + struct ngbde_dev_s ngbde_dev, *nd = &ngbde_dev; + struct resource *memres, *irqres; + + memres = platform_get_resource(pldev, IORESOURCE_MEM, 0); + if (memres == NULL) { + printk("Unable to retrieve iProc CMIC memory resource."); + return -1; + } + size = memres->end - memres->start + 1; + + if (iproc_debug) { + printk("CMIC info : Memory start=%p, end=%p\n", + (void *)memres->start, (void *)memres->end); + } + + base_address = ioremap_nocache(memres->start, size); + if (!base_address) { + printk(KERN_WARNING "Error mapping iProc CMIC registers"); + return -1; + } + + memset(nd, 0, sizeof(*nd)); + nd->pci_dev = NULL; /* No PCI bus */ + nd->dma_dev = &pldev->dev; + + /* Read switch device ID from CMIC */ + dev_rev_id = *((uint32_t*)(base_address + 0x10224)); + nd->vendor_id = 0x14e4; + nd->device_id = dev_rev_id & 0xffff; + nd->revision = (dev_rev_id >> 16) & 0xff; + + irqres = platform_get_resource(pldev, IORESOURCE_IRQ, 0); + if (irqres == NULL) { + printk(KERN_WARNING "Unable to retrieve iProc CMIC IRQ resource."); + return -1; + } + nd->irq_line = irqres->start; + if (iproc_debug) { + printk("CMIC info : IRQ line=%p\n", (void *)irqres->start); + } + + nd->iowin[0].addr = memres->start; + nd->iowin[0].size = size; + + if (base_address) { + iounmap(base_address); + } + rv = ngbde_swdev_add(nd); + + return rv; +} + +/*! + * \brief Remove the platform device. + * + * \param [in] pldev Platform device. + * + * \retval 0 No errors + */ +static int +iproc_cmicd_remove(struct platform_device *pldev) +{ + return 0; +} + +/*! Matching compatible property with device tree. */ +static const struct of_device_id iproc_cmicd_of_match[] = { + { .compatible = "brcm,iproc-cmicd" }, + {}, +}; +MODULE_DEVICE_TABLE(of, iproc_cmicd_of_match); + +static char iproc_cmicd_string[] = "bcmiproc-cmicd"; + +/*! Platform driver definition. */ +static struct platform_driver iproc_cmicd_driver = +{ + .probe = iproc_cmicd_probe, + .remove = iproc_cmicd_remove, + .driver = + { + .name = iproc_cmicd_string, + .owner = THIS_MODULE, + .of_match_table = iproc_cmicd_of_match, + }, +}; + +/*! + * \brief Probe for Broadcom switch devices on IPROC internal bus. + * + * \return 0 if no errors, otherwise -1. + */ +int +ngbde_iproc_probe(void) +{ + platform_driver_register(&iproc_cmicd_driver); + + return 0; +} + +/*! + * \brief Clean up resources for Broadcom switch devices on IPROC internal bus. + * + * \return 0 if no errors, otherwise -1. + */ +int +ngbde_iproc_cleanup(void) +{ + platform_driver_unregister(&iproc_cmicd_driver); + + return 0; +} diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_kapi.c b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_kapi.c new file mode 100644 index 000000000000..340e7b057d44 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_kapi.c @@ -0,0 +1,216 @@ +/*! \file ngbde_kapi.c + * + * Public BDE kernel API for use with other kernel modules. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include + +#include + +struct pci_dev * +ngbde_kapi_pci_dev_get(int kdev) +{ + struct ngbde_dev_s *sd; + + sd = ngbde_swdev_get(kdev); + if (!sd) { + return NULL; + } + + return sd->pci_dev; +} +/*! \cond */ +EXPORT_SYMBOL(ngbde_kapi_pci_dev_get); +/*! \endcond */ + +struct device * +ngbde_kapi_dma_dev_get(int kdev) +{ + struct ngbde_dev_s *sd; + + sd = ngbde_swdev_get(kdev); + if (!sd) { + return NULL; + } + + return sd->dma_dev; +} +/*! \cond */ +EXPORT_SYMBOL(ngbde_kapi_dma_dev_get); +/*! \endcond */ + +void * +ngbde_kapi_dma_bus_to_virt(int kdev, dma_addr_t baddr) +{ + struct ngbde_dev_s *sd; + struct ngbde_dmamem_s *dmamem; + size_t dma_offset; + int idx; + + sd = ngbde_swdev_get(kdev); + if (!sd) { + return NULL; + } + + for (idx = 0; idx < NGBDE_NUM_DMAPOOL_MAX; idx++) { + dmamem = &sd->dmapool[idx].dmamem; + dma_offset = baddr - dmamem->baddr; + if (dma_offset < dmamem->size) { + return (uint8_t *)dmamem->vaddr + dma_offset; + } + } + return NULL; +} +/*! \cond */ +EXPORT_SYMBOL(ngbde_kapi_dma_bus_to_virt); +/*! \endcond */ + +dma_addr_t +ngbde_kapi_dma_virt_to_bus(int kdev, void *vaddr) +{ + struct ngbde_dev_s *sd; + struct ngbde_dmamem_s *dmamem; + size_t dma_offset; + int idx; + + sd = ngbde_swdev_get(kdev); + if (!sd) { + return 0UL; + } + + for (idx = 0; idx < NGBDE_NUM_DMAPOOL_MAX; idx++) { + dmamem = &sd->dmapool[idx].dmamem; + dma_offset = (uintptr_t)vaddr - (uintptr_t)dmamem->vaddr; + if (dma_offset < dmamem->size) { + return dmamem->baddr + dma_offset; + } + } + return 0UL; +} +/*! \cond */ +EXPORT_SYMBOL(ngbde_kapi_dma_virt_to_bus); +/*! \endcond */ + +void +ngbde_kapi_pio_write32(int kdev, uint32_t offs, uint32_t val) +{ + struct ngbde_dev_s *sd; + + sd = ngbde_swdev_get(kdev); + if (sd) { + return ngbde_pio_write32(sd, offs, val); + } +} +/*! \cond */ +EXPORT_SYMBOL(ngbde_kapi_pio_write32); +/*! \endcond */ + +uint32_t +ngbde_kapi_pio_read32(int kdev, uint32_t offs) +{ + struct ngbde_dev_s *sd; + + sd = ngbde_swdev_get(kdev); + if (sd) { + return ngbde_pio_read32(sd, offs); + } + + return (uint32_t)-1; +} +/*! \cond */ +EXPORT_SYMBOL(ngbde_kapi_pio_read32); +/*! \endcond */ + +void * +ngbde_kapi_pio_membase(int kdev) +{ + struct ngbde_dev_s *sd; + + sd = ngbde_swdev_get(kdev); + if (!sd) { + return NULL; + } + + return sd->pio_mem; +} +/*! \cond */ +EXPORT_SYMBOL(ngbde_kapi_pio_membase); +/*! \endcond */ + +int +ngbde_kapi_intr_connect(int kdev, unsigned int irq_num, + int (*isr_func)(void *), void *isr_data) +{ + struct ngbde_dev_s *sd; + struct ngbde_intr_ctrl_s *ic; + + sd = ngbde_swdev_get(kdev); + if (!sd) { + return -1; + } + + if (irq_num >= NGBDE_NUM_IRQS_MAX) { + return -1; + } + + ic = &sd->intr_ctrl[irq_num]; + ic->isr_func = isr_func; + ic->isr_data = isr_data; + + return 0; +} +/*! \cond */ +EXPORT_SYMBOL(ngbde_kapi_intr_connect); +/*! \endcond */ + +int +ngbde_kapi_intr_disconnect(int kdev, unsigned int irq_num) +{ + struct ngbde_dev_s *sd; + struct ngbde_intr_ctrl_s *ic; + + sd = ngbde_swdev_get(kdev); + if (!sd) { + return -1; + } + + if (irq_num >= NGBDE_NUM_IRQS_MAX) { + return -1; + } + + ic = &sd->intr_ctrl[irq_num]; + ic->isr_func = NULL; + ic->isr_data = NULL; + + return 0; +} +/*! \cond */ +EXPORT_SYMBOL(ngbde_kapi_intr_disconnect); +/*! \endcond */ + +int +ngbde_kapi_intr_mask_write(int kdev, unsigned int irq_num, + uint32_t status_reg, uint32_t mask_val) +{ + return ngbde_intr_mask_write(kdev, irq_num, 1, status_reg, mask_val); +} +/*! \cond */ +EXPORT_SYMBOL(ngbde_kapi_intr_mask_write); +/*! \endcond */ diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_main.c b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_main.c new file mode 100644 index 000000000000..5ce48ebc5134 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_main.c @@ -0,0 +1,297 @@ +/*! \file ngbde_main.c + * + * NGBDE module entry. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include + +/*! \cond */ +MODULE_AUTHOR("Broadcom Corporation"); +MODULE_DESCRIPTION("NG BDE Module"); +MODULE_LICENSE("GPL"); +/*! \endcond */ + +/*! \cond */ +static int mmap_debug = 0; +module_param(mmap_debug, int, 0); +MODULE_PARM_DESC(mmap_debug, +"MMAP debug output enable (default 0)."); +/*! \endcond */ + +/*! + * \brief Remap user space DMA memory to non-cached area. + * + * Since we cannot flush and invalidate DMA memory from user space, + * the DMA memory pools need to be cache-coherent, even if this means + * that we need to remap the DMA memory as non-cached. + * + * If undefined, we set this value according to kernel configuration. + */ +#ifndef REMAP_DMA_NONCACHED +# ifdef CONFIG_DMA_NONCOHERENT +# define REMAP_DMA_NONCACHED 1 +# else +# define REMAP_DMA_NONCACHED 0 +# endif +#endif + +static int +ngbde_open(struct inode *inode, struct file *filp) +{ + return 0; +} + +static int +ngbde_release(struct inode *inode, struct file *filp) +{ + return 0; +} + +/*! + * \brief Check if memory range is within existing DMA memory pools. + * + * \param [in] paddr Physical start address of memory range. + * \param [in] size Size of memory range. + * + * \retval true Range is valid. + * \retval false Range is not valid. + */ +static bool +ngbde_dma_range_valid(unsigned long paddr, unsigned long size) +{ + struct ngbde_dev_s *swdev; + unsigned int num_swdev, idx; + struct ngbde_dmamem_s *dmamem; + unsigned int pool; + + ngbde_swdev_get_all(&swdev, &num_swdev); + + for (idx = 0; idx < num_swdev; idx++) { + for (pool = 0; pool < NGBDE_NUM_DMAPOOL_MAX; pool++) { + dmamem = &swdev[idx].dmapool[pool].dmamem; + if (paddr >= dmamem->paddr && + (paddr + size) <= (dmamem->paddr + dmamem->size)) { + return true; + } + } + } + return false; +} + +/*! + * \brief Check if memory range is within device I/O ranges. + * + * \param [in] paddr Physical start address of I/O memory range. + * \param [in] size Size of memory range. + * + * \retval true Range is valid. + * \retval false Range is not valid. + */ +static bool +ngbde_pio_range_valid(unsigned long paddr, unsigned long size) +{ + struct ngbde_dev_s *swdev; + unsigned int num_swdev, idx; + struct ngbde_memwin_s *iowin; + unsigned long iowin_size; + unsigned int wdx; + + ngbde_swdev_get_all(&swdev, &num_swdev); + + for (idx = 0; idx < num_swdev; idx++) { + for (wdx = 0; wdx < NGBDE_NUM_IOWIN_MAX; wdx++) { + iowin = &swdev[idx].iowin[wdx]; + iowin_size = iowin->size; + if (iowin_size < PAGE_SIZE) { + iowin_size = PAGE_SIZE; + } + if (mmap_debug) { + printk("MMAP: Check 0x%08lx/0x%08lx against " + "0x%08lx/0x%08lx(0x%08lx)\n", + paddr, size, + (unsigned long)iowin->addr, + (unsigned long)iowin->size, iowin_size); + } + if (paddr >= iowin->addr && + (paddr + size) <= (iowin->addr + iowin_size)) { + return true; + } + } + } + return false; +} + +/*! + * \brief Match incomplete address with device base addresses. + * + * Use for physical addresses larger than 44 bits. + * + * \param [in] paddr Physical address from user space. + * + * \return Matched device base addess or 0 if no match. + */ +static unsigned long +ngbde_pio_base_match(unsigned long paddr) +{ + struct ngbde_dev_s *swdev; + unsigned int num_swdev, idx; + struct ngbde_memwin_s *iowin; + unsigned int wdx; + + ngbde_swdev_get_all(&swdev, &num_swdev); + + for (idx = 0; idx < num_swdev; idx++) { + for (wdx = 0; wdx < NGBDE_NUM_IOWIN_MAX; wdx++) { + iowin = &swdev[idx].iowin[wdx]; + if (((paddr ^ iowin->addr) & 0xfffffffffffULL) == 0) { + if (mmap_debug) { + printk("MMAP: Matched 0x%08lx to 0x%08lx\n", + (unsigned long)paddr, + (unsigned long)iowin->addr); + } + return iowin->addr; + } + } + } + return 0; +} + +/* + * Some kernels are configured to prevent mapping of kernel RAM memory + * into user space via the /dev/mem device. + * + * The function below provides a backdoor to mapping the DMA pool to + * user space via the BDE device file. + */ +static int +ngbde_mmap(struct file *filp, struct vm_area_struct *vma) +{ + unsigned long paddr = vma->vm_pgoff << PAGE_SHIFT; + unsigned long size = vma->vm_end - vma->vm_start; + int map_noncached = REMAP_DMA_NONCACHED; + int range_valid = 0; + + if (mmap_debug) { + printk("MMAP: Mapping %lu Kbytes at 0x%08lx (0x%lx)\n", + size / 1024, paddr, vma->vm_pgoff); + } + + if (ngbde_dma_range_valid(paddr, size)) { + range_valid = 1; + } else { + map_noncached = 1; + if (ngbde_pio_range_valid(paddr, size)) { + range_valid = 1; + } else { + paddr = ngbde_pio_base_match(paddr); + if (ngbde_pio_range_valid(paddr, size)) { + range_valid = 1; + } + } + } + + if (!range_valid) { + printk("BDE: Invalid mmap range 0x%08lx/0x%lx\n", paddr, size); + return -EINVAL; + } + + if (map_noncached) { + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + } + + if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, + size, vma->vm_page_prot)) { + printk("BDE: Failed to mmap phys range 0x%lx-0x%lx to 0x%lx-0x%lx\n", + paddr, paddr + size, vma->vm_start, vma->vm_end); + return -EAGAIN; + } + + return 0; +} + +static struct file_operations fops = { + .open = ngbde_open, + .release = ngbde_release, + .unlocked_ioctl = ngbde_ioctl, + .compat_ioctl = ngbde_ioctl, + .mmap = ngbde_mmap, +}; + +/*! + * \brief Standard module cleanup. + * + * \return Nothing. + */ +void __exit +cleanup_module(void) +{ + ngbde_intr_cleanup(); + ngbde_iio_cleanup(); + ngbde_paxb_cleanup(); + ngbde_pio_cleanup(); + ngbde_dma_cleanup(); + ngbde_procfs_cleanup(); + unregister_chrdev(MOD_MAJOR, MOD_NAME); + ngbde_pci_cleanup(); + ngbde_iproc_cleanup(); + printk(KERN_INFO "Broadcom NGBDE unloaded successfully\n"); +} + +/*! + * \brief Standard module initialization. + * + * \return Nothing. + */ +int __init +init_module(void) +{ + int rv; + + rv = register_chrdev(MOD_MAJOR, MOD_NAME, &fops); + if (rv < 0) { + printk(KERN_WARNING "%s: can't get major %d\n", + MOD_NAME, MOD_MAJOR); + return rv; + } + + rv = ngbde_iproc_probe(); + if (rv < 0) { + printk(KERN_WARNING "%s: Error probing for AXI bus devices.\n", + MOD_NAME); + return rv; + } + + rv = ngbde_pci_probe(); + if (rv < 0) { + printk(KERN_WARNING "%s: Error probing for PCI bus devices.\n", + MOD_NAME); + return rv; + } + + rv = ngbde_procfs_init(); + if (rv < 0) { + printk(KERN_WARNING "%s: Unable to initialize proc files\n", + MOD_NAME); + return rv; + } + + printk(KERN_INFO "Broadcom NGBDE loaded successfully\n"); + return 0; +} diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_pci_probe.c b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_pci_probe.c new file mode 100644 index 000000000000..37da39cd38a7 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_pci_probe.c @@ -0,0 +1,211 @@ +/*! \file ngbde_pci_probe.c + * + * NG BDE probe for PCI devices. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include + +/*! \cond */ +static int use_msi = 1; +module_param(use_msi, int, 0); +MODULE_PARM_DESC(use_msi, +"Use MSI interrupts if supported by the kernel (default 1)."); +/*! \endcond */ + +/*! \cond */ +static int pci_debug = 0; +module_param(pci_debug, int, 0); +MODULE_PARM_DESC(pci_debug, +"PCI debug output enable (default 0)."); +/*! \endcond */ + +/*! + * Use BCMDRD_DEVLIST_ENTRY macro to generate a device list based on + * supported/installed devices. + */ +#define BCMDRD_DEVLIST_ENTRY(_nm,_vn,_dv,_rv,_md,_pi,_bd,_bc,_fn,_cn,_pf,_pd,_r0,_r1) \ + { _vn, _dv, PCI_ANY_ID, PCI_ANY_ID }, + +/*! Include all chip variants in the list of supported devices. */ +#define BCMDRD_DEVLIST_INCLUDE_ALL + +static struct pci_device_id pci_id_table[] = { +#include + { BROADCOM_VENDOR_ID, 0xb524, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, 0xb684, PCI_ANY_ID, PCI_ANY_ID }, + { 0, 0, 0, 0 } +}; + +static int +pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *ent) +{ + int rv; + int bdx; + int cmic_bar = 0; + uint8_t rev; + struct ngbde_dev_s ngbde_dev, *nd = &ngbde_dev; + int bus_no = pci_dev->bus ? pci_dev->bus->number : 0; + int slot_no = PCI_SLOT(pci_dev->devfn); + + if (PCI_FUNC(pci_dev->devfn) > 0) { + return 0; + } + + if (pci_debug) { + printk("PCI: pci_probe: bus %d slot %d: %04x:%04x\n", + bus_no, slot_no, + pci_dev->vendor, pci_dev->device); + } + + memset(nd, 0, sizeof(*nd)); + nd->pci_dev = pci_dev; + nd->dma_dev = &pci_dev->dev; + nd->vendor_id = pci_dev->vendor; + nd->device_id = pci_dev->device; + nd->bus_no = bus_no; + nd->slot_no = slot_no; + + /* PCI revision must extracted "manually */ + pci_read_config_byte(pci_dev, PCI_REVISION_ID, &rev); + nd->revision = rev; + + if (pci_enable_device(pci_dev)) { + printk(KERN_WARNING "%s: Cannot enable PCI device: " + "vendor_id = %x, device_id = %x\n", + MOD_NAME, pci_dev->vendor, pci_dev->device); + } + pci_set_master(pci_dev); + + /* IRQ number is only valid if PCI device is enabled */ + nd->irq_line = pci_dev->irq; + + /* Check for iProc */ + if (pci_resource_len(pci_dev, 2)) { + nd->iowin[1].addr = pci_resource_start(pci_dev, 0); + nd->iowin[1].size = pci_resource_len(pci_dev, 0); + cmic_bar = 2; + } + nd->iowin[0].addr = pci_resource_start(pci_dev, cmic_bar); + nd->iowin[0].size = pci_resource_len(pci_dev, cmic_bar); + + /* Verify basic I/O access by reading first word of each BAR window */ + for (bdx = 0; bdx < 2; bdx++) { + if (nd->iowin[bdx].size == 0) { + continue; + } + if (ngbde_pio_map(nd, nd->iowin[bdx].addr, nd->iowin[bdx].size)) { + if (pci_debug) { + printk("PCI: BAR %d adddress 0 = 0x%x\n", + bdx, (unsigned int)ngbde_pio_read32(nd, 0)); + } + ngbde_pio_unmap(nd); + } else { + printk(KERN_WARNING "%s: Cannot map PCI BAR %d: " + "start = %08lx, len = %lx\n", + MOD_NAME, bdx, + (unsigned long)nd->iowin[bdx].addr, + (unsigned long)nd->iowin[bdx].size); + } + } + + spin_lock_init(&nd->lock); + + /* Determine MSI configuration by enabling MSI on the device */ + nd->use_msi = use_msi; + if (nd->use_msi) { + if (pci_enable_msi(nd->pci_dev) == 0) { + pci_disable_msi(nd->pci_dev); + } else { + nd->use_msi = 0; + } + } + + rv = ngbde_swdev_add(nd); + + if (rv == 0) { + /* Update DMA pools for all devices */ + rv = ngbde_dma_init(); + if (rv < 0) { + printk(KERN_WARNING "%s: Error initializing DMA memory\n", + MOD_NAME); + /* Mark device as inactive */ + nd->inactive = 1; + } + } + + return rv; +} + +static void +pci_remove(struct pci_dev* pci_dev) +{ + struct ngbde_dev_s *swdev; + unsigned int num_swdev, idx; + int bus_no = pci_dev->bus ? pci_dev->bus->number : 0; + int slot_no = PCI_SLOT(pci_dev->devfn); + + if (pci_debug) { + printk("PCI: pci_remove: bus %d slot %d: %04x:%04x\n", + bus_no, slot_no, + pci_dev->vendor, pci_dev->device); + } + + ngbde_swdev_get_all(&swdev, &num_swdev); + for (idx = 0; idx < num_swdev; idx++) { + if (swdev[idx].bus_no == bus_no && + swdev[idx].slot_no == slot_no) { + if (swdev[idx].inactive) { + printk(KERN_WARNING "%s: Device already removed\n", + MOD_NAME); + } + /* Active device in this slot already? */ + swdev[idx].inactive = 1; + } + } + + /* Update DMA pools for all devices */ + ngbde_dma_cleanup(); +} + +static struct pci_driver pci_driver = { + .name = MOD_NAME, + .probe = pci_probe, + .remove = pci_remove, + .id_table = pci_id_table, + /* The rest are dynamic */ +}; + +int +ngbde_pci_probe(void) +{ + if (pci_register_driver(&pci_driver) < 0) { + return -ENODEV; + } + + return 0; +} + +int +ngbde_pci_cleanup(void) +{ + pci_unregister_driver(&pci_driver); + + return 0; +} diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_pgmem.c b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_pgmem.c new file mode 100644 index 000000000000..e473f0c545cb --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_pgmem.c @@ -0,0 +1,472 @@ +/*! \file ngbde_pgmem.c + * + * \brief PGMEM allocator. + * + * This module is used to allocate large physically contiguous memory + * blocks using the Linux kernel page allocator. + * + * The Linux page allocator can allocate contiguous memory up until a + * certain size, which depends on the kernel version and the CPU + * architecture. + * + * If a larger contiguous memory block is requested, then we need to + * allocate multiple blocks from the Linux page allocator and then + * check if which ones are contiguous. + * + * The smaller memory blocks from which the larger block is assembled + * are referred to as "chunks". + * + * The PGMEM allocator will continue to allocate chunks from the Linux + * page allocator, until a contiguous memory block of the requested + * size has been assembled, or until a predefined maximum number of + * chunks have been allocated. Obviously the process is also stopped + * if the Linux page allocator returns an error. + * + * A physically contiguous memory block assembled from smaller memory + * chunks are referred to as "cmblocks". + * + * The chance of success depends on the requested memory block size as + * well as the fragmentation level of the system memory, i.e. the + * sooner after system boot these memory block are requested, the more + * likely these requests are to succeed. + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include + + +/******************************************************************************* + * Local definitions + ******************************************************************************/ + +/*! Maximum size the kernel can allocate in a single allocation. */ +#define MEM_CHUNK_SIZE_MAX (1 << (MAX_ORDER - 1 + PAGE_SHIFT)) + +/*! Default block size we wil request from the kernel. */ +#define MEM_CHUNK_SIZE_DEFAULT (512 * ONE_KB) + +/*! \cond */ +static int pgmem_chunk_size = 0; +module_param(pgmem_chunk_size, int, 0); +MODULE_PARM_DESC(pgmem_chunk_size, +"Memory chunk size in KB used by page allocator (default auto)."); +/*! \endcond */ + +/*! \cond */ +static int pgmem_debug = 0; +module_param(pgmem_debug, int, 0); +MODULE_PARM_DESC(pgmem_debug, +"Enable page memory allocator debug output (default 0)."); +/*! \endcond */ + +/*! Helper macro for debug trace output. */ +#define PGMEM_TRACE(_s) \ + do { \ + if (pgmem_debug) { \ + printk(_s); \ + } \ + } while (0) + +/*! + * Chunk memory block descriptor. + */ +typedef struct cmblock_desc_s { + + /*! Linked-list handle. */ + struct list_head list; + + /*! Requested cmblock size. */ + unsigned long req_size; + + /*! Memory chunk size. */ + unsigned long chunk_size; + + /*! Memory chunk size in alternate format (2^x). */ + unsigned long chunk_order; + + /*! Current cmblock size. */ + unsigned long cmblk_size; + + /*! Logical address of cmblock. */ + unsigned long cmblk_begin; + + /*! Logical end address of cmblock. */ + unsigned long cmblk_end; + + /*! Array of logical chunk addresses. */ + unsigned long *chunk_ptr; + + /*! Maximum number of chunks to allocate. */ + int chunk_cnt_max; + + /*! Current number of chunks allocated. */ + int chunk_cnt; + +} cmblock_desc_t; + +static LIST_HEAD(cmblocks_list); + + +/*! + * \name Chunk tag mask. + * \anchor CT_xxx + * + * The lower two bits of the chunk address is used to tag the chunk + * with its current state. + */ +#define CT_MASK 0x3 + +/*! Chunk is untagged. */ +#define CT_UNTAGGED 0 + +/*! Chunk was discarded. */ +#define CT_DISCARDED 1 + +/*! Chunk is part of largest cmblock. */ +#define CT_LARGEST 2 + +/*! Chunk is part of current cmblock. */ +#define CT_CURRENT 3 + +/*! Set block as untagged. */ +#define CTAG_SET(_a, _t) \ + do { \ + (_a) &= ~CT_MASK; \ + (_a) |= _t; \ + } while (0) + +/*! Set block as untagged. */ +#define CTAG_GET(_a) \ + ((_a) & CT_MASK) + + +/******************************************************************************* + * Private Functions + ******************************************************************************/ + +/*! + * \brief Find largest contiguous memory block. + * + * Find largest contiguous memory block from a pool of memory chunks. + * + * Assembly stops if a cmblock of the requested cmblock size has been + * obtained. + * + * The lower two address bits of the memory chunks are encoded as a + * tag according to \ref CT_xxx. + * + * \param [in] cmbd cmblock descriptor. + * + * \return Always 0. + */ +static int +find_largest_cmblock(cmblock_desc_t *cmbd) +{ + int i, j, chunks, found; + unsigned long b, e, a; + unsigned long *cptr; + + /* Convenience variable */ + chunks = cmbd->chunk_cnt; + cptr = cmbd->chunk_ptr; + + /* Clear all chunk tags */ + for (i = 0; i < chunks; i++) { + CTAG_SET(cptr[i], CT_UNTAGGED); + } + for (i = 0; i < chunks && cmbd->cmblk_size < cmbd->req_size; i++) { + /* First chunk must be an untagged chunk */ + if (CTAG_GET(cptr[i]) == CT_UNTAGGED) { + /* Initial cmblock size is the chunk size */ + b = cptr[i]; + e = b + cmbd->chunk_size; + CTAG_SET(cptr[i], CT_CURRENT); + /* Loop looking for adjacent chunks */ + do { + found = 0; + for (j = i + 1; j < chunks && (e - b) < cmbd->req_size; j++) { + a = cptr[j]; + /* Check untagged chunks only */ + if (CTAG_GET(a) == CT_UNTAGGED) { + if (a == (b - cmbd->chunk_size)) { + /* Found adjacent chunk below current cmblock */ + CTAG_SET(cptr[j], CT_CURRENT); + b = a; + found = 1; + } else if (a == e) { + /* Found adjacent chunk above current cmblock */ + CTAG_SET(cptr[j], CT_CURRENT); + e += cmbd->chunk_size; + found = 1; + } + } + } + } while (found); + /* Now check the size of the assembled memory block */ + if ((e - b) > cmbd->cmblk_size) { + /* The current block is largest so far */ + cmbd->cmblk_begin = b; + cmbd->cmblk_end = e; + cmbd->cmblk_size = e - b; + /* Re-tag current and previous largest cmblock */ + for (j = 0; j < chunks; j++) { + if (CTAG_GET(cptr[j]) == CT_CURRENT) { + /* Tag current cmblock as the largest */ + CTAG_SET(cptr[j], CT_LARGEST); + } else if (CTAG_GET(cptr[j]) == CT_LARGEST) { + /* Discard previous largest cmblock */ + CTAG_SET(cptr[j], CT_DISCARDED); + } + } + } else { + /* Discard all chunks in current cmblock */ + for (j = 0; j < chunks; j++) { + if (CTAG_GET(cptr[j]) == CT_CURRENT) { + CTAG_SET(cptr[j], CT_DISCARDED); + } + } + } + } + } + return 0; +} + +/*! + * \brief Allocate memory chunks and add them to the pool. + * + * Memory chunks are allocated using the kernel page allocator. + * + * \param [in] cmbd - cmblock descriptor. + * \param [in] chunks - Number of memory chunks to allocate. + * + * \return 0 if no errors, otherwise -1. + */ +static int +alloc_mem_chunks(cmblock_desc_t *cmbd, int chunks) +{ + int i, start; + unsigned long addr; + + if (cmbd->chunk_cnt + chunks > cmbd->chunk_cnt_max) { + printk("PGMEM: No more memory chunks\n"); + return -1; + } + start = cmbd->chunk_cnt; + cmbd->chunk_cnt += chunks; + for (i = start; i < cmbd->chunk_cnt; i++) { + /* Get chunk from kernel allocator */ + addr = __get_free_pages(GFP_KERNEL | GFP_DMA32, cmbd->chunk_order); + PGMEM_TRACE("."); + if (addr) { + cmbd->chunk_ptr[i] = addr; + } else { + printk("PGMEM: Page memory allocation failed\n"); + return -1; + } + } + return 0; +} + +/*! + * \brief Allocate large physically contiguous memory block. + * + * If we cannot allocate a sufficiently large block of contiguous + * memory from the kernel, then we simply keep allocating smaller + * chunks until we can assemble a contiguous block of the desired + * size. + * + * When maximum amount of system memory has been allocated without the + * successful assembly of a contiguous memory block, the allocation + * function will return the largest contiguous block found so far. It + * is then up to the calling function to decide whether this amount is + * sufficient to proceed. + * + * \param [in] size Requested memory block size. + * \param [in] chunk_size Assemble cmblock from chunks of this size. + * + * \return Pointer to cmblock descriptor, or NULL if error. + */ +static cmblock_desc_t * +cmblock_alloc(size_t size, size_t chunk_size) +{ + cmblock_desc_t *cmbd; + int i, chunk_ptr_size; + unsigned long page_addr; + struct sysinfo si; + + /* Sanity check */ + if (size == 0 || chunk_size == 0) { + return NULL; + } + + /* Allocate an initialize memory cmblock descriptor */ + if ((cmbd = kmalloc(sizeof(cmblock_desc_t), GFP_KERNEL)) == NULL) { + return NULL; + } + memset(cmbd, 0, sizeof(*cmbd)); + cmbd->req_size = size; + cmbd->chunk_size = PAGE_ALIGN(chunk_size); + while ((PAGE_SIZE << cmbd->chunk_order) < cmbd->chunk_size) { + cmbd->chunk_order++; + } + + /* Determine the maximum possible number of memory chunks */ + si_meminfo(&si); + cmbd->chunk_cnt_max = (si.totalram << PAGE_SHIFT) / cmbd->chunk_size; + chunk_ptr_size = cmbd->chunk_cnt_max * sizeof(unsigned long); + + /* Allocate an initialize memory chunk pool */ + cmbd->chunk_ptr = kmalloc(chunk_ptr_size, GFP_KERNEL); + if (cmbd->chunk_ptr == NULL) { + kfree(cmbd); + return NULL; + } + memset(cmbd->chunk_ptr, 0, chunk_ptr_size); + + /* Allocate minimum number of memory chunks */ + (void)alloc_mem_chunks(cmbd, cmbd->req_size / cmbd->chunk_size); + + /* Allocate more chunks until we have a complete cmblock */ + do { + find_largest_cmblock(cmbd); + PGMEM_TRACE("o"); + if (cmbd->cmblk_size >= cmbd->req_size) { + break; + } + } while (alloc_mem_chunks(cmbd, 8) == 0); + + /* Reserve all pages in the cmblock and free unused chunks */ + for (i = 0; i < cmbd->chunk_cnt; i++) { + if (CTAG_GET(cmbd->chunk_ptr[i]) == CT_LARGEST) { + CTAG_SET(cmbd->chunk_ptr[i], CT_UNTAGGED); + for (page_addr = cmbd->chunk_ptr[i]; + page_addr < cmbd->chunk_ptr[i] + cmbd->chunk_size; + page_addr += PAGE_SIZE) { + SetPageReserved(virt_to_page((void *)page_addr)); + } + } else if (cmbd->chunk_ptr[i]) { + CTAG_SET(cmbd->chunk_ptr[i], CT_UNTAGGED); + free_pages(cmbd->chunk_ptr[i], cmbd->chunk_order); + PGMEM_TRACE("x"); + cmbd->chunk_ptr[i] = 0; + } + } + PGMEM_TRACE("O\n"); + return cmbd; +} + +/*! + * \brief Free cmblock and associated resources. + * + * Free all memory chunks and other associated resources associated + * with a contiguous memory block. + * + * See alse \ref cmblock_alloc. + * + * \param [in] cmbd Command block descriptor to free. + * + * \return Nothing. + */ +static void +cmblock_free(cmblock_desc_t *cmbd) +{ + int i; + unsigned long page_addr; + + if (cmbd->chunk_ptr) { + for (i = 0; i < cmbd->chunk_cnt; i++) { + if (cmbd->chunk_ptr[i]) { + for (page_addr = cmbd->chunk_ptr[i]; + page_addr < cmbd->chunk_ptr[i] + cmbd->chunk_size; + page_addr += PAGE_SIZE) { + ClearPageReserved(virt_to_page((void *)page_addr)); + } + free_pages(cmbd->chunk_ptr[i], cmbd->chunk_order); + PGMEM_TRACE("X"); + } + } + kfree(cmbd->chunk_ptr); + kfree(cmbd); + } +} + + +/******************************************************************************* + * Public Functions + ******************************************************************************/ + +void * +ngbde_pgmem_alloc(size_t size, gfp_t flags) +{ + cmblock_desc_t *cmbd; + size_t chunk_size; + + chunk_size = size; + + if (pgmem_chunk_size > 0) { + chunk_size = pgmem_chunk_size * ONE_KB; + } + + if (chunk_size > MEM_CHUNK_SIZE_MAX) { + chunk_size = MEM_CHUNK_SIZE_DEFAULT; + } + + if (pgmem_debug) { + printk("PGMEM: Allocate %d MB in %d KB chunks\n", + (int)(size / ONE_MB), (int)(chunk_size / ONE_KB)); + } + + if ((cmbd = cmblock_alloc(size, chunk_size)) == NULL) { + return NULL; + } + if (cmbd->cmblk_size < size) { + /* If we didn't get the full size then forget it */ + cmblock_free(cmbd); + return NULL; + } + list_add(&cmbd->list, &cmblocks_list); + return (void *)cmbd->cmblk_begin; +} + +int +ngbde_pgmem_free(void *ptr) +{ + struct list_head *pos; + + list_for_each(pos, &cmblocks_list) { + cmblock_desc_t *cmbd = list_entry(pos, cmblock_desc_t, list); + if (ptr == (void *)cmbd->cmblk_begin) { + list_del(&cmbd->list); + cmblock_free(cmbd); + return 0; + } + } + return -1; +} + +void +ngbde_pgmem_free_all(void) +{ + struct list_head *pos, *tmp; + + list_for_each_safe(pos, tmp, &cmblocks_list) { + cmblock_desc_t *cmbd = list_entry(pos, cmblock_desc_t, list); + list_del(&cmbd->list); + cmblock_free(cmbd); + } +} diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_pio.c b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_pio.c new file mode 100644 index 000000000000..cab094a2feca --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_pio.c @@ -0,0 +1,97 @@ +/*! \file ngbde_pio.c + * + * API for managing and accessing memory-mapped I/O for switch + * registers. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include + +void * +ngbde_pio_map(void *devh, phys_addr_t addr, phys_addr_t size) +{ + struct ngbde_dev_s *sd = (struct ngbde_dev_s *)devh; + + if (sd->pio_mem) { + if (addr == sd->pio_win.addr && size == sd->pio_win.size) { + /* Already mapped */ + return sd->pio_mem; + } + ngbde_pio_unmap(devh); + } + + sd->pio_mem = ioremap_nocache(addr, size); + + if (sd->pio_mem) { + /* Save mapped resources */ + sd->pio_win.addr = addr; + sd->pio_win.size = size; + } else { + printk(KERN_WARNING "%s: Unable to map address 0x%08lu\n", + MOD_NAME, (unsigned long)addr); + } + + return sd->pio_mem; +} + +void +ngbde_pio_unmap(void *devh) +{ + struct ngbde_dev_s *sd = (struct ngbde_dev_s *)devh; + + if (sd->pio_mem) { + iounmap(sd->pio_mem); + sd->pio_mem = NULL; + } +} + +void +ngbde_pio_cleanup(void) +{ + struct ngbde_dev_s *swdev, *sd; + unsigned int num_swdev, idx; + + ngbde_swdev_get_all(&swdev, &num_swdev); + + for (idx = 0; idx < num_swdev; idx++) { + sd = ngbde_swdev_get(idx); + ngbde_pio_unmap(sd); + } +} + +void +ngbde_pio_write32(void *devh, uint32_t offs, uint32_t val) +{ + struct ngbde_dev_s *sd = (struct ngbde_dev_s *)devh; + + if (sd->pio_mem) { + NGBDE_IOWRITE32(val, sd->pio_mem + offs); + } +} + +uint32_t +ngbde_pio_read32(void *devh, uint32_t offs) +{ + struct ngbde_dev_s *sd = (struct ngbde_dev_s *)devh; + + if (sd->pio_mem) { + return NGBDE_IOREAD32(sd->pio_mem + offs); + } + return 0; +} diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_procfs.c b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_procfs.c new file mode 100644 index 000000000000..f99339a5b0dc --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_procfs.c @@ -0,0 +1,120 @@ +/*! \file ngbde_procfs.c + * + * + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include + +static int +proc_show(struct seq_file *m, void *v) +{ + struct ngbde_dev_s *swdev; + unsigned int num_swdev, idx; + struct ngbde_dmamem_s *dmamem; + unsigned int pool; + unsigned int dma_pools; + char *dma_str; + + ngbde_swdev_get_all(&swdev, &num_swdev); + + seq_printf(m, "Broadcom Device Enumerator (%s)\n", MOD_NAME); + + seq_printf(m, "Found %d switch device(s):\n", num_swdev); + for (idx = 0; idx < num_swdev; idx++) { + if (swdev->inactive) { + seq_printf(m, "%d:removed\n", idx); + continue; + } + seq_printf(m, "%d:%04x:%04x:%02x,%s(%d)\n", idx, + swdev->vendor_id, swdev->device_id, swdev->revision, + swdev->use_msi ? "MSI" : "IRQ", swdev->irq_line); + } + + seq_printf(m, "DMA pools:\n"); + for (idx = 0; idx < num_swdev; idx++) { + seq_printf(m, "%d", idx); + dma_pools = 0; + for (pool = 0; pool < NGBDE_NUM_DMAPOOL_MAX; pool++) { + dmamem = &swdev[idx].dmapool[pool].dmamem; + dma_str = "unknown"; + if (dmamem->type == NGBDE_DMA_T_NONE) { + /* Skip empty DMA pools */ + continue; + } else if (dmamem->type == NGBDE_DMA_T_KAPI) { + dma_str = "kapi"; + } else if (dmamem->type == NGBDE_DMA_T_PGMEM) { + dma_str = "pgmem"; + } + seq_printf(m, ":%dMB@0x%08lx(%s)", + (int)(dmamem->size / ONE_MB), + (unsigned long)dmamem->baddr, dma_str); + dma_pools++; + } + if (dma_pools == 0) { + seq_printf(m, ":none"); + } + seq_printf(m, "\n"); + } + + return 0; +} + +static int +proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, proc_show, NULL); +} + +static int +proc_release(struct inode *inode, struct file *file) +{ + return single_release(inode, file); +} + +static struct file_operations proc_fops = { + owner: THIS_MODULE, + open: proc_open, + read: seq_read, + llseek: seq_lseek, + release: proc_release, +}; + +int +ngbde_procfs_init(void) +{ + struct proc_dir_entry *entry; + + PROC_CREATE(entry, MOD_NAME, 0666, NULL, &proc_fops); + + if (entry == NULL) { + printk(KERN_ERR "ngbde: proc_create failed\n"); + return -1; + } + + return 0; +} + +int +ngbde_procfs_cleanup(void) +{ + remove_proc_entry(MOD_NAME, NULL); + + return 0; +} diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_swdev.c b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_swdev.c new file mode 100644 index 000000000000..60d328ad2526 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_swdev.c @@ -0,0 +1,79 @@ +/*! \file ngbde_swdev.c + * + * + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include + +/* Switch devices */ +static struct ngbde_dev_s swdevs[NGBDE_NUM_SWDEV_MAX]; + +/* Number of probed switch devices */ +static unsigned int num_swdev; + +int +ngbde_swdev_add(struct ngbde_dev_s *nd) +{ + unsigned int idx; + + /* Look for existing slot */ + for (idx = 0; idx < num_swdev; idx++) { + if (swdevs[idx].bus_no == nd->bus_no && + swdevs[idx].slot_no == nd->slot_no) { + if (swdevs[idx].inactive) { + memcpy(&swdevs[idx], nd, sizeof(swdevs[0])); + return 0; + } + /* Active device in this slot already? */ + printk(KERN_WARNING "%s: Device exists\n", + MOD_NAME); + return -EBUSY; + } + } + + /* Add new device */ + if (num_swdev >= NGBDE_NUM_SWDEV_MAX) { + return -ENOMEM; + } + memcpy(&swdevs[num_swdev], nd, sizeof(swdevs[0])); + ++num_swdev; + return 0; +} + +struct ngbde_dev_s * +ngbde_swdev_get(int kdev) +{ + if ((unsigned int)kdev < num_swdev) { + return &swdevs[kdev]; + } + return NULL; +} + +int +ngbde_swdev_get_all(struct ngbde_dev_s **nd, unsigned int *num_nd) +{ + if (nd) { + *nd = swdevs; + } + if (num_nd) { + *num_nd = num_swdev; + } + return 0; +} diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/lkm.h b/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/lkm.h new file mode 100644 index 000000000000..c0ba0a319767 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/lkm.h @@ -0,0 +1,126 @@ +/*! \file lkm.h + * + * + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#ifndef LKM_H +#define LKM_H + +#include +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +#error Kernel too old +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0) +#include +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) +#include +#endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39) +#include +#endif +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef CONFIG_DEVFS_FS +#include +#endif + +/* Compatibility Macros */ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) +#define PROC_CREATE(_entry, _name, _acc, _path, _fops) \ + do { \ + _entry = proc_create(_name, _acc, _path, _fops); \ + } while (0) + +#define PROC_CREATE_DATA(_entry, _name, _acc, _path, _fops, _data) \ + do { \ + _entry = proc_create_data(_name, _acc, _path, _fops, _data); \ + } while (0) + +#define PROC_PDE_DATA(_node) PDE_DATA(_node) +#else +#define PROC_CREATE(_entry, _name, _acc, _path, _fops) \ + do { \ + _entry = create_proc_entry(_name, _acc, _path); \ + if (_entry) { \ + _entry->proc_fops = _fops; \ + } \ + } while (0) + +#define PROC_CREATE_DATA(_entry, _name, _acc, _path, _fops, _data) \ + do { \ + _entry = create_proc_entry(_name, _acc, _path); \ + if (_entry) { \ + _entry->proc_fops = _fops; \ + _entry->data=_data; \ + } \ + } while (0) + +#define PROC_PDE_DATA(_node) PROC_I(_node)->pde->data +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0) +#define timer_arg(var, context, timer_fieldname) \ + (typeof(var))(context) +#define timer_context_t unsigned long +#else +#define timer_context_t struct timer_list * +#define timer_arg(var, context, timer_fieldname) \ + from_timer(var, context, timer_fieldname) +#endif + +#ifndef setup_timer +#define setup_timer(timer, fn, data) \ + timer_setup(timer, fn, 0) +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) +static inline void page_ref_inc(struct page *page) +{ + atomic_inc(&page->_count); +} + +static inline void page_ref_dec(struct page *page) +{ + atomic_dec(&page->_count); +} +#endif + +#endif /* LKM_H */ diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/ngbde_ioctl.h b/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/ngbde_ioctl.h new file mode 100644 index 000000000000..b90486ce06f2 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/ngbde_ioctl.h @@ -0,0 +1,345 @@ +/*! \file ngbde_ioctl.h + * + * NGBDE device I/O control definitions. + * + * This file is intended for use in both kernel mode and user mode. + * + * IMPORTANT! + * All shared structures must be properly 64-bit aligned. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#ifndef NGBDE_IOCTL_H +#define NGBDE_IOCTL_H + +#include +#include + +/*! Must be updated if backward compatibility is broken. */ +#define NGBDE_IOC_VERSION 2 + +/*! LUBDE IOCTL command magic. */ +#define NGBDE_IOC_MAGIC 'L' + +/*! + * \name IOCTL commands for the NGBDE kernel module. + * \anchor NGBDE_IOC_xxx + * + * Note that we use __u64 for the IOCTL parameter size because + * sizeof(void *) is different between 32-bit and 64-bit code, and we + * need a 32-bit user mode application to generate the same IOCTL + * command codes as a 64-bit kernel when using the _IOW macro. + */ + +/*! \{ */ + +/*! Get kernel module information. */ +#define NGBDE_IOC_MOD_INFO _IOW(NGBDE_IOC_MAGIC, 0, __u64) + +/*! Get information about registered devices. */ +#define NGBDE_IOC_PROBE_INFO _IOW(NGBDE_IOC_MAGIC, 1, __u64) + +/*! Get detailed switch device information. */ +#define NGBDE_IOC_DEV_INFO _IOW(NGBDE_IOC_MAGIC, 2, __u64) + +/*! Get a physical memory address associated with a switch device. */ +#define NGBDE_IOC_PHYS_ADDR _IOW(NGBDE_IOC_MAGIC, 3, __u64) + +/*! Interrupt control command (see \ref NGBDE_ICTL_xxx). */ +#define NGBDE_IOC_INTR_CTRL _IOW(NGBDE_IOC_MAGIC, 4, __u64) + +/*! Add interrupt status/mask register for kernel to control. */ +#define NGBDE_IOC_IRQ_REG_ADD _IOW(NGBDE_IOC_MAGIC, 5, __u64) + +/*! Write to a shared interrupt mask register. */ +#define NGBDE_IOC_IRQ_MASK_WR _IOW(NGBDE_IOC_MAGIC, 6, __u64) + +/*! Map device registers in kernel space. */ +#define NGBDE_IOC_PIO_WIN_MAP _IOW(NGBDE_IOC_MAGIC, 7, __u64) + +/*! Map interrupt controller registers in kernel space. */ +#define NGBDE_IOC_IIO_WIN_MAP _IOW(NGBDE_IOC_MAGIC, 8, __u64) + +/*! Map PCI bridge registers in kernel space. */ +#define NGBDE_IOC_PAXB_WIN_MAP _IOW(NGBDE_IOC_MAGIC, 9, __u64) + +/*! Add interrupt ACK register for kernel to control. */ +#define NGBDE_IOC_INTR_ACK_REG_ADD _IOW(NGBDE_IOC_MAGIC, 10, __u64) + +/*! \} */ + +/*! IOCTL command return code for success. */ +#define NGBDE_IOC_SUCCESS 0 + +/*! IOCTL command return code for failure. */ +#define NGBDE_IOC_FAIL ((__u32)-1) + +/*! + * \name Device flags. + * \anchor NGBDE_DEV_F_xxx + */ + +/*! \{ */ + +/*! Message-signaled interrupts, PCI interrupts are operating in MSI mode. */ +#define NGBDE_DEV_F_MSI (1 << 0) + +/*! \} */ + +/*! + * \name Interrupt control commands. + * \anchor NGBDE_ICTL_xxx + */ + +/*! \{ */ + +/*! Connect interrupt handler. */ +#define NGBDE_ICTL_INTR_CONN 0 + +/*! Disconnect interrupt handler. */ +#define NGBDE_ICTL_INTR_DISC 1 + +/*! Wait for interrupt. */ +#define NGBDE_ICTL_INTR_WAIT 2 + +/*! Force waiting thread to return. */ +#define NGBDE_ICTL_INTR_STOP 3 + +/*! Clear list of interrupt status/mask registers. */ +#define NGBDE_ICTL_REGS_CLR 4 + +/*! \} */ + +/*! Kernel module information. */ +struct ngbde_ioc_mod_info_s { + + /*! IOCTL version used by kernel module. */ + __u16 version; +}; + +/*! Probing results. */ +struct ngbde_ioc_probe_info_s { + + /*! Number of switch devices. */ + __u16 num_swdev; +}; + +/*! Device information. */ +struct ngbde_ioc_dev_info_s { + + /*! Device type. */ + __u16 type; + + /*! Device flags (\ref NGBDE_DEV_F_xxx). */ + __u16 flags; + + /*! Vendor ID (typically the PCI vendor ID). */ + __u16 vendor_id; + + /*! Device ID (typically the PCI vendor ID). */ + __u16 device_id; + + /*! Device revision (typically the PCI device revision). */ + __u16 revision; + + /*! Device model (device-identification beyond PCI generic ID). */ + __u16 model; +}; + +/*! + * \name I/O resource types. + * \anchor NGBDE_IO_RSRC_xxx + */ + +/*! \{ */ + +/*! Memory-mapped I/O. */ +#define NGBDE_IO_RSRC_DEV_IO 0 + +/*! DMA memory pool. */ +#define NGBDE_IO_RSRC_DMA_MEM 1 + +/*! DMA memory pool as mapped by IOMMU. */ +#define NGBDE_IO_RSRC_DMA_BUS 2 + +/*! \} */ + +/*! + * \brief Resource ID (IOCTL input). + * + * This structure is used to query a physical address resource in the + * kernel module. The caller must provide a resource type (device I/O, + * DMA memory, etc.) and a resource instance number (e.g. a PCI BAR + * address will have multiple instances). + * + * Also see \ref ngbde_ioc_phys_addr_s. + */ +struct ngbde_ioc_rsrc_id_s { + + /*! Resource type (\ref NGBDE_IO_RSRC_xxx). */ + __u32 type; + + /*! Resource instance number. */ + __u32 inst; +}; + +/*! + * \brief Physical device address. + * + * This structure is returned in response to the \ref + * NGBDE_IOC_PHYS_ADDR command. The caller must identify the requested + * physical address using the \ref ngbde_ioc_rsrc_id_s structure. + */ +struct ngbde_ioc_phys_addr_s { + + /*! Physical address. */ + __u64 addr; + + /*! Resource size (in bytes). */ + __u32 size; +}; + +/*! Interrupt control operation */ +struct ngbde_ioc_intr_ctrl_s { + + /*! Interrupt instance for this device. */ + __u32 irq_num; + + /*! Interrupt control command. */ + __u32 cmd; +}; + +/*! Add interrupt register information. */ +struct ngbde_ioc_irq_reg_add_s { + + /*! Interrupt instance for this device. */ + __u32 irq_num; + + /*! Interrupt status register address offset. */ + __u32 status_reg; + + /*! Interrupt mask register address offset. */ + __u32 mask_reg; + + /*! Interrupt mask for interrupts handled by the kernel. */ + __u32 kmask; + + /*! Reserved for future use. */ + __u32 flags; +}; + +/*! + * \name Interrupt ACK register access flags. + * \anchor NGBDE_DEV_INTR_ACK_F_xxx + */ + +/*! \{ */ + +/*! ACK registers resides in PCI bridge I/O window. */ +#define NGBDE_DEV_INTR_ACK_F_PAXB (1 << 0) + +/*! \} */ + +/*! Add interrupt ACK register information. */ +struct ngbde_ioc_intr_ack_reg_add_s { + + /*! Interrupt instance for this device. */ + __u32 irq_num; + + /*! Interrupt ACK register address offset. */ + __u32 ack_reg; + + /*! Interrupt ACK value. */ + __u32 ack_val; + + /*! Flags to indicate ack_reg resides in PCI bridge window. */ + __u32 flags; +}; + +/*! Memory-mapped I/O window */ +struct ngbde_ioc_pio_win_s { + + /*! Physical address */ + __u64 addr; + + /*! Resource size */ + __u32 size; +}; + +/*! Interrupt mask register write */ +struct ngbde_ioc_irq_mask_wr_s { + + /*! Interrupt instance for this device. */ + __u32 irq_num; + + /*! Register offset. */ + __u32 offs; + + /*! Value to write. */ + __u32 val; +}; + +/*! IOCTL operation data. */ +union ngbde_ioc_op_s { + + /*! Get kernel module information. */ + struct ngbde_ioc_mod_info_s mod_info; + + /*! Get information about registered devices. */ + struct ngbde_ioc_probe_info_s probe_info; + + /*! Get detailed switch device information. */ + struct ngbde_ioc_dev_info_s dev_info; + + /*! Resource ID (input). */ + struct ngbde_ioc_rsrc_id_s rsrc_id; + + /*! Get a physical memory address associated with a switch device. */ + struct ngbde_ioc_phys_addr_s phys_addr; + + /*! Interrupt control command (see \ref NGBDE_ICTL_xxx). */ + struct ngbde_ioc_intr_ctrl_s intr_ctrl; + + /*! Add interrupt status/mask register for kernel to control. */ + struct ngbde_ioc_irq_reg_add_s irq_reg_add; + + /*! Add interrupt ACK register for kernel to control. */ + struct ngbde_ioc_intr_ack_reg_add_s intr_ack_reg_add; + + /*! Write to a shared interrupt mask register. */ + struct ngbde_ioc_irq_mask_wr_s irq_mask_wr; + + /*! Map device registers in kernel space. */ + struct ngbde_ioc_pio_win_s pio_win; +}; + +/*! IOCTL command message. */ +typedef struct ngbde_ioc_cmd_s { + + /*! Device handle. */ + __u32 devid; + + /*! Return code (0 means success). */ + __u32 rc; + + /*! IOCTL operation. */ + union ngbde_ioc_op_s op; +} ngbde_ioc_cmd_t; + +#endif /* NGBDE_IOCTL_H */ diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/ngbde_kapi.h b/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/ngbde_kapi.h new file mode 100644 index 000000000000..142aa63b572c --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/ngbde_kapi.h @@ -0,0 +1,169 @@ +/*! \file ngbde_kapi.h + * + * NGBDE kernel API. + * + * This file is intended for use by other kernel modules relying on the BDE. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#ifndef NGBDE_KAPI_H +#define NGBDE_KAPI_H + +#include + +/*! Maximum number of switch devices supported. */ +#ifndef NGBDE_NUM_SWDEV_MAX +#define NGBDE_NUM_SWDEV_MAX 16 +#endif + +/*! + * \brief Get Linux PCI device handle for a switch device. + * + * \param [in] kdev Device number. + * + * \return Linux PCI device handle or NULL if unavailable. + */ +extern struct pci_dev * +ngbde_kapi_pci_dev_get(int kdev); + +/*! + * \brief Get Linux kernel device handle for a switch device. + * + * \param [in] kdev Device number. + * + * \return Linux kernel device handle or NULL if unavailable. + */ +extern struct device * +ngbde_kapi_dma_dev_get(int kdev); + +/*! + * \brief Convert DMA bus address to virtual address. + * + * This API will convert a physical DMA bus address to a kernel + * virtual address for a memory location that belongs to one of the + * DMA memory pools allocated by the BDE module. + * + * \param [in] kdev Device number. + * \param [in] baddr Physical DMA bus address for this device. + * + * \return Virtual kernel address or NULL on error. + */ +void * +ngbde_kapi_dma_bus_to_virt(int kdev, dma_addr_t baddr); + +/*! + * \brief Convert virtual address to DMA bus address. + * + * This API will convert a kernel virtual address to a physical DMA + * bus address for a memory location that belongs to one of the DMA + * memory pools allocated by the BDE module. + * + * \param [in] kdev Device number. + * \param [in] vaddr Virtual kernel address. + * + * \return Physical DMA bus address for this device or 0 on error. + */ +dma_addr_t +ngbde_kapi_dma_virt_to_bus(int kdev, void *vaddr); + +/*! + * \brief Write a memory-mapped register from kernel driver. + * + * \param [in] kdev Device number. + * \param [in] offs Register address offset. + * \param [in] val Value to write to register. + * + * \return Nothing. + */ +extern void +ngbde_kapi_pio_write32(int kdev, uint32_t offs, uint32_t val); + +/*! + * \brief Read a memory-mapped register from kernel driver. + * + * \param [in] kdev Device number. + * \param [in] offs Register address offset. + * + * \return Value read from register. + */ +extern uint32_t +ngbde_kapi_pio_read32(int kdev, uint32_t offs); + +/*! + * \brief Get base address fo memory-mapped I/O memory. + * + * The lgical base address returned can be used with ioread32, etc. + * + * \param [in] kdev Device number. + * + * \return Logical base address or NULL if unavailable. + */ +extern void * +ngbde_kapi_pio_membase(int kdev); + +/*! + * \brief Install kernel mode interrupt handler. + * + * \param [in] kdev Device number. + * \param [in] irq_num MSI interrupt number. + * \param [in] isr_func Interrupt handler function. + * \param [in] isr_data Interrupt handler context. + * + * \retval 0 No errors + */ +extern int +ngbde_kapi_intr_connect(int kdev, unsigned int irq_num, + int (*isr_func)(void *), void *isr_data); + +/*! + * \brief Uninstall kernel mode interrupt handler. + * + * \param [in] kdev Device number. + * \param [in] irq_num MSI interrupt number. + * + * \retval 0 No errors + */ +extern int +ngbde_kapi_intr_disconnect(int kdev, unsigned int irq_num); + +/*! + * \brief Write shared interrupt mask register. + * + * This function is used by an interrupt handler when a shared + * interrupt mask register needs to be updated. + * + * Note that the mask register to access is referenced by the + * corrsponding status register. This is because the mask register may + * be different depending on the host CPU interface being used + * (e.g. PCI vs. AXI). On the other hand, the status register is the + * same irrespective of the host CPU interface. + * + * \param [in] kdev Device number. + * \param [in] irq_num Interrupt number (MSI vector). + * \param [in] status_reg Corresponding interrupt status register offset. + * \param [in] mask_val New value to write to mask register. + * + * \retval 0 No errors + * \retval -1 Something went wrong. + */ +extern int +ngbde_kapi_intr_mask_write(int kdev, unsigned int irq_num, + uint32_t status_reg, uint32_t mask_val); + +#endif /* NGBDE_KAPI_H */ diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/ngknet_dev.h b/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/ngknet_dev.h new file mode 100644 index 000000000000..74d3d5b350b0 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/ngknet_dev.h @@ -0,0 +1,408 @@ +/*! \file ngknet_dev.h + * + * NGKNET device definitions. + * + * This file is intended for use in both kernel mode and user mode. + * + * IMPORTANT! + * All shared structures must be properly 64-bit aligned. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#ifndef NGKNET_DEV_H +#define NGKNET_DEV_H + +#include + +/*! Device name length */ +#define NGKNET_DEV_NAME_MAX 16 + +/*! Maximum number of virtual network devices */ +#ifndef NGKNET_NETIF_MAX +#define NUM_VDEV_MAX 128 +#else +#define NUM_VDEV_MAX NGKNET_NETIF_MAX +#endif + +/*! Maximum number of filters */ +#ifndef NGKNET_FILTER_MAX +#define NUM_FILTER_MAX 128 +#else +#define NUM_FILTER_MAX NGKNET_FILTER_MAX +#endif + +/*! + * \brief System network interface + * + * Network interface types: + * + * NGKNET_NETIF_T_VLAN + * Transmits to this interface will go to ingress PIPE of switch + * CPU port using specified VLAN ID. Packet will be switched. + * + * NGKNET_NETIF_T_PORT + * Transmits to this interface will go to unmodified to specified + * physical switch port. All switching logic is bypassed. Meta data + * should be provided when this interface is created. + * + * NGKNET_NETIF_T_META + * Transmits to this interface will be done using raw meta data + * as DMA descriptors. + * + * Network interface flags: + * + * NGKNET_NETIF_F_RCPU_ENCAP + * Use RCPU encapsulation for packets that enter and exit this + * interface. + * + * NGKNET_NETIF_F_ADD_TAG + * Add VLAN tag to packets sent directly to physical port. + * + * NGKNET_NETIF_F_BIND_CHAN + * Bind this interface to a Rx channel. + */ +/*! Max network interface name length */ +#define NGKNET_NETIF_NAME_MAX 16 +/*! Max network interface meta bytes */ +#define NGKNET_NETIF_META_MAX 16 +/*! Max netif user data in bytes */ +#define NGKNET_NETIF_USER_DATA 64 + +/*! Send packets to switch */ +#define NGKNET_NETIF_T_VLAN 0 +/*! Send packets to port */ +#define NGKNET_NETIF_T_PORT 1 +/*! Send packets with matadata attached */ +#define NGKNET_NETIF_T_META 2 + +/*! Send packets with RCPU encapsulation */ +#define NGKNET_NETIF_F_RCPU_ENCAP (1U << 0) +/*! Send packets with vlan tag */ +#define NGKNET_NETIF_F_ADD_TAG (1U << 1) +/*! Bind network interface to Rx channel */ +#define NGKNET_NETIF_F_BIND_CHAN (1U << 2) + +/*! + * \brief Network interface description. + */ +typedef struct ngknet_netif_s { + /*! This network interface ID */ + uint16_t id; + + /*! Next network interface ID */ + uint16_t next; + + /*! Network interface type */ + uint16_t type; + + /*! Network interface flags */ + uint16_t flags; + + /*! Network interface VLAN ID */ + uint16_t vlan; + + /*! Network interface MAC address */ + uint8_t macaddr[6]; + + /*! Network interface MTU */ + uint32_t mtu; + + /*! Network interface bound to channel */ + uint32_t chan; + + /*! Network interface name */ + char name[NGKNET_NETIF_NAME_MAX]; + + /*! Metadata offset from Ethernet header */ + uint16_t meta_off; + + /*! Metadata length */ + uint16_t meta_len; + + /*! Metadata used to send packets to physical port */ + uint8_t meta_data[NGKNET_NETIF_META_MAX]; + + /*! User data gotten back through callbacks */ + uint8_t user_data[NGKNET_NETIF_USER_DATA]; +} ngknet_netif_t; + +/*! + * \brief Packet filters + * + * Filters work like software TCAMs where a mask is applied to the + * source data, and the result is then compared to the filter data. + * + * Filters are checked in priority order with the lowest priority + * values being checked first (i.e. 0 is the highest priority). + * + * Filter types: + * + * NGKNET_FILTER_T_RX_PKT + * Filter data and mask are applied to the Rx DMA control block + * as well as to the Rx packet contents. + * + * Destination types: + * + * NGKNET_FILTER_DEST_T_NULL + * Packet is dropped. + * + * NGKNET_FILTER_DEST_T_NETIF + * Packet is sent to network interface with ID . + * + * NGKNET_FILTER_DEST_T_VNET + * Packet is sent to VNET in user space. + * + * Filter flags: + * + * NGKNET_FILTER_F_ANY_DATA + * When this flags is set the filter will match any packet on + * the associated unit. + * + * NGKNET_FILTER_F_STRIP_TAG + * Strip VLAN tag before packet is sent to destination. + */ +/*! Roundup to word */ +#define NGKNET_BYTES2WORDS(bytes) ((bytes + 3) / 4) + +/*! Max filter description length */ +#define NGKNET_FILTER_DESC_MAX 32 +/*! Max filter bytes size */ +#define NGKNET_FILTER_BYTES_MAX 256 +/*! Max filter words size */ +#define NGKNET_FILTER_WORDS_MAX NGKNET_BYTES2WORDS(NGKNET_FILTER_BYTES_MAX) +/*! Max filter user data in bytes */ +#define NGKNET_FILTER_USER_DATA 64 + +/*! Filter to Rx */ +#define NGKNET_FILTER_T_RX_PKT 1 + +/*! Drop packet */ +#define NGKNET_FILTER_DEST_T_NULL 0 +/*! Send packet to netif */ +#define NGKNET_FILTER_DEST_T_NETIF 1 +/*! Send packet to VNET */ +#define NGKNET_FILTER_DEST_T_VNET 2 +/*! Send packet to kernel callback function (BCMPKT_DEST_T_CALLBACK) */ +#define NGKNET_FILTER_DEST_T_CB 3 + +/*! Match any data */ +#define NGKNET_FILTER_F_ANY_DATA (1U << 0) +/*! Strip vlan tag */ +#define NGKNET_FILTER_F_STRIP_TAG (1U << 1) +/*! Match Rx channel */ +#define NGKNET_FILTER_F_MATCH_CHAN (1U << 2) +/*! Filter created with raw metadata */ +#define NGKNET_FILTER_F_RAW_PMD (1U << 15) + +/*! + * \brief Filter description. + */ +typedef struct ngknet_filter_s { + /*! This filter ID */ + uint16_t id; + + /*! Next filter ID */ + uint16_t next; + + /*! Filter type. Refer to \ref NGKNET_FILTER_T_XXX. */ + uint16_t type; + + /*! Filter flags. Refer to \ref NGKNET_FILTER_F_XXX. */ + uint16_t flags; + + /*! Filter priority */ + uint32_t priority; + + /*! Filter belong to */ + uint32_t chan; + + /*! Filter description */ + char desc[NGKNET_FILTER_DESC_MAX]; + + /*! Destination type. Refer to \ref NGKNET_FILTER_DEST_T_XXX. */ + uint16_t dest_type; + + /*! Destination network interface ID */ + uint16_t dest_id; + + /*! Destination network interface protocol type */ + uint16_t dest_proto; + + /*! Mirror type */ + uint16_t mirror_type; + + /*! Mirror network interface ID */ + uint16_t mirror_id; + + /*! Mirror network interface protocol type */ + uint16_t mirror_proto; + + /*! Out band data offset */ + uint16_t oob_data_offset; + + /*! Out band data size */ + uint16_t oob_data_size; + + /*! Packet data offset */ + uint16_t pkt_data_offset; + + /*! Packet data size */ + uint16_t pkt_data_size; + + /*! Filtering data */ + union { + uint8_t b[NGKNET_FILTER_BYTES_MAX]; + uint32_t w[NGKNET_FILTER_WORDS_MAX]; + } data; + + /*! Filtering mask */ + union { + uint8_t b[NGKNET_FILTER_BYTES_MAX]; + uint32_t w[NGKNET_FILTER_WORDS_MAX]; + } mask; + + /*! User data gotten back through callbacks */ + uint8_t user_data[NGKNET_FILTER_USER_DATA]; +} ngknet_filter_t; + +/*! + * \brief Device configure structure. + */ +typedef struct ngknet_dev_cfg_s { + /*! Device name */ + char name[NGKNET_DEV_NAME_MAX]; + + /*! Device type string */ + char type_str[NGKNET_DEV_NAME_MAX]; + + /*! Device ID */ + uint32_t dev_id; + + /*! Device mode */ + dev_mode_t mode; + + /*! Number of groups */ + uint32_t nb_grp; + + /*! Bitmap of groups */ + uint32_t bm_grp; + + /*! Rx packet header size */ + uint32_t rx_ph_size; + + /*! Tx packet header size */ + uint32_t tx_ph_size; + + /*! Base network interface */ + ngknet_netif_t base_netif; +} ngknet_dev_cfg_t; + +/*! + * \brief Channel configure structure. + */ +typedef struct ngknet_chan_cfg_s { + /*! Channel number */ + int chan; + + /*! Number of descriptors */ + uint32_t nb_desc; + + /*! Rx buffer size */ + uint32_t rx_buf_size; + + /*! Channel control */ + uint32_t chan_ctrl; + /*! Packet_byte_swap */ +#define NGKNET_PKT_BYTE_SWAP (1 << 0) + /*! Non packet_byte_swap */ +#define NGKNET_OTH_BYTE_SWAP (1 << 1) + /*! Header_byte_swap */ +#define NGKNET_HDR_BYTE_SWAP (1 << 2) + + /*! Rx or Tx */ + int dir; + /*! Rx channel */ +#define NGKNET_RX_CHAN 0 + /*! Tx channel */ +#define NGKNET_TX_CHAN 1 +} ngknet_chan_cfg_t; + +/*! + * \brief RCPU header structure. + */ +struct ngknet_rcpu_hdr { + /*! Destination MAC address */ + uint8_t dst_mac[6]; + + /*! Source MAC address */ + uint8_t src_mac[6]; + + /*! VLAN TPID */ + uint16_t vlan_tpid; + + /*! VLAN TCI */ + uint16_t vlan_tci; + + /*! Ethernet type */ + uint16_t eth_type; + + /*! Packet signature */ + uint16_t pkt_sig; + + /*! Operation code */ + uint8_t op_code; + + /*! Flags */ + uint8_t flags; + + /*! Transaction number */ + uint16_t trans_id; + + /*! Packet data length */ + uint16_t data_len; + + /*! Reserved must be 0 */ + uint16_t rsvd0; + + /*! packet meta data length */ + uint8_t meta_len; + + /*! Transmission queue number */ + uint8_t queue_id; + + /*! Reserved must be 0 */ + uint16_t rsvd1; +}; + +/*! RCPU Rx operation */ +#define RCPU_OPCODE_RX 0x10 +/*! RCPU Tx operation */ +#define RCPU_OPCODE_TX 0x20 + +/*! RCPU purge flag */ +#define RCPU_FLAG_PURGE (1 << 0) +/*! RCPU pause flag */ +#define RCPU_FLAG_PAUSE (1 << 1) +/*! RCPU modhdr flag */ +#define RCPU_FLAG_MODHDR (1 << 2) +/*! RCPU bind queue flag */ +#define RCPU_FLAG_BIND_QUE (1 << 3) + +#endif /* NGKNET_DEV_H */ + diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/ngknet_ioctl.h b/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/ngknet_ioctl.h new file mode 100644 index 000000000000..6da52c778191 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/ngknet_ioctl.h @@ -0,0 +1,112 @@ +/*! \file ngknet_ioctl.h + * + * NGKNET I/O control definitions. + * + * This file is intended for use in both kernel mode and user mode. + * + * IMPORTANT! + * All shared structures must be properly 64-bit aligned. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#ifndef NGKNET_IOCTL_H +#define NGKNET_IOCTL_H + +/*! Module information */ +#define NGKNET_MODULE_NAME "linux_ngknet" +#define NGKNET_MODULE_MAJOR 121 + +/*! Must be updated if backward compatibility is broken */ +#define NGKNET_IOC_VERSION 2 + +/*! Max number of input arguments */ +#define NGKNET_IOC_IARG_MAX 2 + +#define NGKNET_IOC_MAGIC 'K' + +#define NGKNET_VERSION_GET _IOR(NGKNET_IOC_MAGIC, 0xa0, unsigned int) +#define NGKNET_RX_RATE_LIMIT _IOWR(NGKNET_IOC_MAGIC, 0xa1, unsigned int) +#define NGKNET_DEV_INIT _IOWR(NGKNET_IOC_MAGIC, 0xb0, unsigned int) +#define NGKNET_DEV_DEINIT _IOWR(NGKNET_IOC_MAGIC, 0xb1, unsigned int) +#define NGKNET_DEV_SUSPEND _IOWR(NGKNET_IOC_MAGIC, 0xb2, unsigned int) +#define NGKNET_DEV_RESUME _IOWR(NGKNET_IOC_MAGIC, 0xb3, unsigned int) +#define NGKNET_DEV_VNET_WAIT _IOWR(NGKNET_IOC_MAGIC, 0xb4, unsigned int) +#define NGKNET_DEV_HNET_WAKE _IOWR(NGKNET_IOC_MAGIC, 0xb5, unsigned int) +#define NGKNET_DEV_VNET_DOCK _IOWR(NGKNET_IOC_MAGIC, 0xb6, unsigned int) +#define NGKNET_DEV_VNET_UNDOCK _IOWR(NGKNET_IOC_MAGIC, 0xb7, unsigned int) +#define NGKNET_QUEUE_CONFIG _IOWR(NGKNET_IOC_MAGIC, 0xc0, unsigned int) +#define NGKNET_QUEUE_QUERY _IOR(NGKNET_IOC_MAGIC, 0xc1, unsigned int) +#define NGKNET_RCPU_CONFIG _IOWR(NGKNET_IOC_MAGIC, 0xc2, unsigned int) +#define NGKNET_RCPU_GET _IOR(NGKNET_IOC_MAGIC, 0xc3, unsigned int) +#define NGKNET_NETIF_CREATE _IOWR(NGKNET_IOC_MAGIC, 0xd0, unsigned int) +#define NGKNET_NETIF_DESTROY _IOWR(NGKNET_IOC_MAGIC, 0xd1, unsigned int) +#define NGKNET_NETIF_GET _IOR(NGKNET_IOC_MAGIC, 0xd2, unsigned int) +#define NGKNET_NETIF_NEXT _IOR(NGKNET_IOC_MAGIC, 0xd3, unsigned int) +#define NGKNET_NETIF_LINK_SET _IOW(NGKNET_IOC_MAGIC, 0xd4, unsigned int) +#define NGKNET_FILT_CREATE _IOWR(NGKNET_IOC_MAGIC, 0xe0, unsigned int) +#define NGKNET_FILT_DESTROY _IOWR(NGKNET_IOC_MAGIC, 0xe1, unsigned int) +#define NGKNET_FILT_GET _IOR(NGKNET_IOC_MAGIC, 0xe2, unsigned int) +#define NGKNET_FILT_NEXT _IOR(NGKNET_IOC_MAGIC, 0xe3, unsigned int) +#define NGKNET_INFO_GET _IOR(NGKNET_IOC_MAGIC, 0xf0, unsigned int) +#define NGKNET_STATS_GET _IOR(NGKNET_IOC_MAGIC, 0xf1, unsigned int) +#define NGKNET_STATS_RESET _IOWR(NGKNET_IOC_MAGIC, 0xf2, unsigned int) +#define NGKNET_PTP_DEV_CTRL _IOWR(NGKNET_IOC_MAGIC, 0x90, unsigned int) + +/*! Kernel module information. */ +struct ngknet_ioc_mod_info { + /*! IOCTL version used by kernel module */ + uint32_t version; +}; + +/*! Data transmission */ +struct ngknet_ioc_data_xmit { + /*! Data buffer address */ + uint64_t buf; + + /*! Data buffer length */ + uint32_t len; +}; + +/*! IOCTL operations */ +union ngknet_ioc_op { + /*! Get module info */ + struct ngknet_ioc_mod_info info; + /*! Transmit data */ + struct ngknet_ioc_data_xmit data; +}; + +/*! + * \brief NGKNET IOCTL command message. + */ +struct ngknet_ioctl { + /*! Device number */ + uint32_t unit; + + /*! Return code (0 means success) */ + uint32_t rc; + + /*! Input arguments */ + int iarg[NGKNET_IOC_IARG_MAX]; + + /*! IOCTL operation */ + union ngknet_ioc_op op; +}; + +#endif /* NGKNET_IOCTL_H */ + diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/include/net/psample.h b/platform/broadcom/saibcm-modules/sdklt/linux/include/net/psample.h new file mode 100644 index 000000000000..64188c95daeb --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/include/net/psample.h @@ -0,0 +1,24 @@ +#ifndef __NET_PSAMPLE_H +#define __NET_PSAMPLE_H + +#include +#include +#include +#include + +struct psample_group { + struct list_head list; + struct net *net; + u32 group_num; + u32 refcount; + u32 seq; +}; + +extern struct psample_group *psample_group_get(struct net *net, u32 group_num); +extern void psample_group_put(struct psample_group *group); + +extern void psample_sample_packet(struct psample_group *group, struct sk_buff *skb, + u32 trunc_size, int in_ifindex, int out_ifindex, + u32 sample_rate); + +#endif /* __NET_PSAMPLE_H */ diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/include/uapi/linux/psample.h b/platform/broadcom/saibcm-modules/sdklt/linux/include/uapi/linux/psample.h new file mode 100644 index 000000000000..ed48996ec0e8 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/include/uapi/linux/psample.h @@ -0,0 +1,35 @@ +#ifndef __UAPI_PSAMPLE_H +#define __UAPI_PSAMPLE_H + +enum { + /* sampled packet metadata */ + PSAMPLE_ATTR_IIFINDEX, + PSAMPLE_ATTR_OIFINDEX, + PSAMPLE_ATTR_ORIGSIZE, + PSAMPLE_ATTR_SAMPLE_GROUP, + PSAMPLE_ATTR_GROUP_SEQ, + PSAMPLE_ATTR_SAMPLE_RATE, + PSAMPLE_ATTR_DATA, + + /* commands attributes */ + PSAMPLE_ATTR_GROUP_REFCOUNT, + + __PSAMPLE_ATTR_MAX +}; + +enum psample_command { + PSAMPLE_CMD_SAMPLE, + PSAMPLE_CMD_GET_GROUP, + PSAMPLE_CMD_NEW_GROUP, + PSAMPLE_CMD_DEL_GROUP, +}; + +/* Can be overridden at runtime by module option */ +#define PSAMPLE_ATTR_MAX (__PSAMPLE_ATTR_MAX - 1) + +#define PSAMPLE_NL_MCGRP_CONFIG_NAME "config" +#define PSAMPLE_NL_MCGRP_SAMPLE_NAME "packets" +#define PSAMPLE_GENL_NAME "psample" +#define PSAMPLE_GENL_VERSION 1 + +#endif diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/Kbuild b/platform/broadcom/saibcm-modules/sdklt/linux/knet/Kbuild new file mode 100644 index 000000000000..fe5d5c5bfefc --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/Kbuild @@ -0,0 +1,44 @@ +# -*- Kbuild -*- +# +# Linux KNET module. +# +# $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. +# The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# version 2 as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# A copy of the GNU General Public License version 2 (GPLv2) can +# be found in the LICENSES folder.$ +# + +obj-m := linux_ngknet.o + +ccflags-y := $(KNET_CPPFLAGS) $(LKM_CFLAGS) \ + -I$(SDK)/shr/include \ + -I$(SDK)/bcmdrd/include \ + -I$(SDK)/linux/include \ + -I$(SDK)/linux/knet/include \ + -I$(SDK)/linux/knet + +linux_ngknet-y := $(CHIP_OBJS) \ + bcmcnet_cmicd_pdma_hw.o \ + bcmcnet_cmicd_pdma_rxtx.o \ + bcmcnet_cmicx_pdma_hw.o \ + bcmcnet_cmicx_pdma_rxtx.o \ + bcmcnet_core.o \ + bcmcnet_dev.o \ + bcmcnet_rxtx.o \ + ngknet_buff.o \ + ngknet_callback.o \ + ngknet_extra.o \ + ngknet_linux.o \ + ngknet_main.o \ + ngknet_procfs.o \ + ngknet_ptp.o diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/Makefile b/platform/broadcom/saibcm-modules/sdklt/linux/knet/Makefile new file mode 100644 index 000000000000..785b81fadb17 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/Makefile @@ -0,0 +1,105 @@ +# -*- Makefile -*- +# +# Linux KNET module. +# +# $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. +# The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# version 2 as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# A copy of the GNU General Public License version 2 (GPLv2) can +# be found in the LICENSES folder.$ +# + +CNETDIR = $(SDK)/bcmcnet +KNETDIR = $(SDK)/linux/knet +SRCIDIR = $(CNETDIR)/include/bcmcnet +DSTIDIR = $(KNETDIR)/include/bcmcnet + +# Change comma-separated list to space-separated list +comma = , +empty = +space = $(empty) $(empty) +spc_sep = $(subst $(comma),$(space),$1) + +# Convert chip name to uppercase +chip_uc = $(subst a,A,$(subst b,B,$(subst c,C,$(subst m,M,$1)))) + +# Convert chip name to lowercase +chip_lc = $(subst A,a,$(subst B,b,$(subst C,c,$(subst M,m,$1)))) + +# +# If SDK_CHIPS is defined, then exclude any chip directory which is +# not part of this list. +# +KNET_CHIPS := $(subst $(CNETDIR)/chip/,,$(wildcard $(CNETDIR)/chip/bcm*)) +ifdef SDK_CHIPS +# Create space-separated lowercase version of chip list +SDK_CHIPS_SPC := $(call spc_sep,$(SDK_CHIPS)) +SDK_CHIPS_LC := $(call chip_lc,$(SDK_CHIPS_SPC)) +# Configure build flags according to chip list +KNET_CHIPS := $(filter $(SDK_CHIPS_LC),$(KNET_CHIPS)) +KNET_CPPFLAGS := CHIP_DEFAULT=0 $(addsuffix =1,$(call chip_uc,$(KNET_CHIPS))) +KNET_CPPFLAGS := $(addprefix -DBCMDRD_CONFIG_INCLUDE_,$(KNET_CPPFLAGS)) +export KNET_CPPFLAGS +endif + +.PHONY: mklinks rmlinks + +knet: mklinks + $(MAKE) all + +# +# Suppress symlink error messages. +# +# Note that we do not use "ln -f" as this may cause failures if +# multiple builds are done in parallel on the same source tree. +# +R = 2>/dev/null + +mklinks: + mkdir -p $(DSTIDIR) + -ln -s $(KNETDIR)/ngknet_dep.h $(DSTIDIR)/bcmcnet_dep.h $(R) + -ln -s $(KNETDIR)/ngknet_buff.h $(DSTIDIR)/bcmcnet_buff.h $(R) + -ln -s $(SRCIDIR)/bcmcnet_types.h $(DSTIDIR) $(R) + -ln -s $(SRCIDIR)/bcmcnet_internal.h $(DSTIDIR) $(R) + -ln -s $(SRCIDIR)/bcmcnet_core.h $(DSTIDIR) $(R) + -ln -s $(SRCIDIR)/bcmcnet_dev.h $(DSTIDIR) $(R) + -ln -s $(SRCIDIR)/bcmcnet_rxtx.h $(DSTIDIR) $(R) + -ln -s $(SRCIDIR)/bcmcnet_cmicd.h $(DSTIDIR) $(R) + -ln -s $(SRCIDIR)/bcmcnet_cmicx.h $(DSTIDIR) $(R) + -ln -s $(CNETDIR)/chip/*/*attach.c $(KNETDIR) $(R) + -ln -s $(CNETDIR)/hmi/cmicd/*.c $(KNETDIR) $(R) + -ln -s $(CNETDIR)/hmi/cmicx/*.c $(KNETDIR) $(R) + -ln -s $(CNETDIR)/main/bcmcnet_core.c $(KNETDIR) $(R) + -ln -s $(CNETDIR)/main/bcmcnet_dev.c $(KNETDIR) $(R) + -ln -s $(CNETDIR)/main/bcmcnet_rxtx.c $(KNETDIR) $(R) + +rmlinks: + -rm -f bcm* + -rm -rf include + +CHIP_SRCS := $(addsuffix _pdma_attach.c,$(KNET_CHIPS)) +CHIP_OBJS ?= $(patsubst %.c, %.o, $(CHIP_SRCS)) +export CHIP_OBJS + +include Kbuild + +ifeq ($(KERNELRELEASE),) + +MOD_NAME = linux_ngknet + +include $(SDK)/make/lkm.mk + +endif + +.PHONY: distclean + +distclean: rmlinks diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_buff.c b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_buff.c new file mode 100644 index 000000000000..750fff69caf3 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_buff.c @@ -0,0 +1,326 @@ +/*! \file ngknet_buff.c + * + * Utility routines for NGKNET packet buffer management in Linux kernel mode. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include +#include +#include +#include "ngknet_main.h" +#include "ngknet_buff.h" + +/*! + * Allocate coherent memory + */ +static void * +bcmcnet_ring_buf_alloc(struct pdma_dev *dev, uint32_t size, dma_addr_t *dma) +{ + struct ngknet_dev *kdev = (struct ngknet_dev *)dev->priv; + + return dma_alloc_coherent(kdev->dev, size, dma, GFP_KERNEL); +} + +/*! + * Free coherent memory + */ +static void +bcmcnet_ring_buf_free(struct pdma_dev *dev, uint32_t size, void *addr, dma_addr_t dma) +{ + struct ngknet_dev *kdev = (struct ngknet_dev *)dev->priv; + + dma_free_coherent(kdev->dev, size, addr, dma); +} + +/*! + * Allocate Rx buffer + */ +static int +bcmcnet_rx_buf_alloc(struct pdma_dev *dev, struct pdma_rx_queue *rxq, + struct pdma_rx_buf *pbuf) +{ + struct ngknet_dev *kdev = (struct ngknet_dev *)dev->priv; + dma_addr_t dma; + struct page *page; + struct sk_buff *skb; + + if (rxq->mode == PDMA_BUF_MODE_PAGE) { + page = kal_dev_alloc_page(); + if (unlikely(!page)) { + return SHR_E_MEMORY; + } + dma = dma_map_page(kdev->dev, page, 0, PAGE_SIZE, DMA_FROM_DEVICE); + if (unlikely(dma_mapping_error(kdev->dev, dma))) { + __free_page(page); + return SHR_E_MEMORY; + } + pbuf->dma = dma; + pbuf->page = page; + pbuf->page_offset = 0; + } else { + skb = netdev_alloc_skb(kdev->net_dev, PDMA_RXB_RESV + pbuf->adj + rxq->buf_size); + if (unlikely(!skb)) { + return SHR_E_MEMORY; + } + skb_reserve(skb, PDMA_RXB_ALIGN - (((unsigned long)skb->data) & (PDMA_RXB_ALIGN - 1))); + pbuf->skb = skb; + pbuf->pkb = (struct pkt_buf *)skb->data; + dma = dma_map_single(kdev->dev, &pbuf->pkb->data + pbuf->adj, rxq->buf_size, DMA_FROM_DEVICE); + if (unlikely(dma_mapping_error(kdev->dev, dma))) { + dev_kfree_skb_any(skb); + return SHR_E_MEMORY; + } + pbuf->dma = dma; + } + + return SHR_E_NONE; +} + +/*! + * Get Rx buffer DMA address + */ +static void +bcmcnet_rx_buf_dma(struct pdma_dev *dev, struct pdma_rx_queue *rxq, + struct pdma_rx_buf *pbuf, dma_addr_t *addr) +{ + if (rxq->mode == PDMA_BUF_MODE_PAGE) { + *addr = pbuf->dma + pbuf->page_offset + PDMA_RXB_RESV + pbuf->adj; + } else { + *addr = pbuf->dma; + } +} + +/*! + * Check Rx buffer + */ +static int +bcmcnet_rx_buf_avail(struct pdma_dev *dev, struct pdma_rx_queue *rxq, + struct pdma_rx_buf *pbuf) +{ + if (rxq->mode == PDMA_BUF_MODE_PAGE) { + pbuf->skb = NULL; + } + + return pbuf->dma != 0; +} + +/*! + * Get Rx buffer + */ +static struct pkt_hdr * +bcmcnet_rx_buf_get(struct pdma_dev *dev, struct pdma_rx_queue *rxq, + struct pdma_rx_buf *pbuf, int len) +{ + struct ngknet_dev *kdev = (struct ngknet_dev *)dev->priv; + struct sk_buff *skb; + + if (rxq->mode == PDMA_BUF_MODE_PAGE) { + if (pbuf->skb) { + return &pbuf->pkb->pkh; + } + skb = kal_build_skb(page_address(pbuf->page) + pbuf->page_offset, + PDMA_SKB_RESV + pbuf->adj + rxq->buf_size); + if (unlikely(!skb)) { + return NULL; + } + skb_reserve(skb, PDMA_RXB_ALIGN); + dma_sync_single_range_for_cpu(kdev->dev, pbuf->dma, pbuf->page_offset, + PDMA_PAGE_BUF_MAX, DMA_FROM_DEVICE); + pbuf->skb = skb; + pbuf->pkb = (struct pkt_buf *)skb->data; + + /* Try to reuse this page */ + if (unlikely(page_count(pbuf->page) != 1)) { + dma_unmap_page(kdev->dev, pbuf->dma, PAGE_SIZE, DMA_FROM_DEVICE); + pbuf->dma = 0; + } else { + pbuf->page_offset ^= PDMA_PAGE_BUF_MAX; + page_ref_inc(pbuf->page); + dma_sync_single_range_for_device(kdev->dev, pbuf->dma, pbuf->page_offset, + PDMA_PAGE_BUF_MAX, DMA_FROM_DEVICE); + } + } else { + if (!pbuf->dma) { + return &pbuf->pkb->pkh; + } + skb = pbuf->skb; + dma_unmap_single(kdev->dev, pbuf->dma, rxq->buf_size, DMA_FROM_DEVICE); + pbuf->dma = 0; + } + + skb_put(skb, PKT_HDR_SIZE + pbuf->adj + len); + + return &pbuf->pkb->pkh; +} + +/*! + * Put Rx buffer + */ +static int +bcmcnet_rx_buf_put(struct pdma_dev *dev, struct pdma_rx_queue *rxq, + struct pdma_rx_buf *pbuf, int len) +{ + struct ngknet_dev *kdev = (struct ngknet_dev *)dev->priv; + dma_addr_t dma; + struct sk_buff *skb; + + if (rxq->mode == PDMA_BUF_MODE_PAGE) { + dev_kfree_skb_any(pbuf->skb); + } else { + skb = pbuf->skb; + dma = dma_map_single(kdev->dev, &pbuf->pkb->data + pbuf->adj, + rxq->buf_size, DMA_FROM_DEVICE); + if (unlikely(dma_mapping_error(kdev->dev, dma))) { + dev_kfree_skb_any(skb); + pbuf->dma = 0; + return SHR_E_MEMORY; + } + pbuf->dma = dma; + skb_trim(skb, skb->len - (PKT_HDR_SIZE + pbuf->adj + len)); + } + + return SHR_E_NONE; +} + +/*! + * Free Rx buffer + */ +static void +bcmcnet_rx_buf_free(struct pdma_dev *dev, struct pdma_rx_queue *rxq, + struct pdma_rx_buf *pbuf) +{ + struct ngknet_dev *kdev = (struct ngknet_dev *)dev->priv; + + if (rxq->mode == PDMA_BUF_MODE_PAGE) { + dma_unmap_single(kdev->dev, pbuf->dma, PAGE_SIZE, DMA_FROM_DEVICE); + __free_page(pbuf->page); + } else { + dma_unmap_single(kdev->dev, pbuf->dma, rxq->buf_size, DMA_FROM_DEVICE); + dev_kfree_skb_any(pbuf->skb); + } + + pbuf->dma = 0; + pbuf->page = NULL; + pbuf->page_offset = 0; + pbuf->skb = NULL; + pbuf->pkb = NULL; + pbuf->adj = 0; +} + +/*! + * Get Rx buffer mode + */ +static enum buf_mode +bcmcnet_rx_buf_mode(struct pdma_dev *dev, struct pdma_rx_queue *rxq) +{ + uint32_t len; + + len = dev->rx_ph_size ? rxq->buf_size : rxq->buf_size + PDMA_RXB_META; + if (PDMA_RXB_SIZE(len) <= PDMA_PAGE_BUF_MAX && PAGE_SIZE < 8192 && + kal_support_paged_skb()) { + return PDMA_BUF_MODE_PAGE; + } + + return PDMA_BUF_MODE_SKB; +} + +/*! + * Get Tx buffer + */ +static struct pkt_hdr * +bcmcnet_tx_buf_get(struct pdma_dev *dev, struct pdma_tx_queue *txq, + struct pdma_tx_buf *pbuf, void *buf) +{ + struct ngknet_dev *kdev = (struct ngknet_dev *)dev->priv; + struct sk_buff *skb = (struct sk_buff *)buf; + struct pkt_buf *pkb = (struct pkt_buf *)skb->data; + dma_addr_t dma; + + pbuf->len = pkb->pkh.data_len + (pbuf->adj ? pkb->pkh.meta_len : 0); + dma = dma_map_single(kdev->dev, &pkb->data + (pbuf->adj ? 0 : pkb->pkh.meta_len), + pbuf->len, DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(kdev->dev, dma))) { + dev_kfree_skb_any(skb); + return NULL; + } + pbuf->dma = dma; + pbuf->skb = skb; + pbuf->pkb = pkb; + + return &pkb->pkh; +} + +/*! + * Get Tx buffer DMA address + */ +static void +bcmcnet_tx_buf_dma(struct pdma_dev *dev, struct pdma_tx_queue *txq, + struct pdma_tx_buf *pbuf, dma_addr_t *addr) +{ + *addr = pbuf->dma; +} + +/*! + * Free Tx buffer + */ +static void +bcmcnet_tx_buf_free(struct pdma_dev *dev, struct pdma_tx_queue *txq, + struct pdma_tx_buf *pbuf) +{ + struct ngknet_dev *kdev = (struct ngknet_dev *)dev->priv; + + dma_unmap_single(kdev->dev, pbuf->dma, pbuf->len, DMA_TO_DEVICE); + if (skb_shinfo(pbuf->skb)->tx_flags & SKBTX_IN_PROGRESS) { + skb_queue_tail(&kdev->ptp_tx_queue, pbuf->skb); + schedule_work(&kdev->ptp_tx_work); + } else { + dev_kfree_skb_any(pbuf->skb); + } + + pbuf->dma = 0; + pbuf->len = 0; + pbuf->skb = NULL; + pbuf->pkb = NULL; + pbuf->adj = 0; +} + +static const struct pdma_buf_mngr buf_mngr = { + .ring_buf_alloc = bcmcnet_ring_buf_alloc, + .ring_buf_free = bcmcnet_ring_buf_free, + .rx_buf_alloc = bcmcnet_rx_buf_alloc, + .rx_buf_dma = bcmcnet_rx_buf_dma, + .rx_buf_avail = bcmcnet_rx_buf_avail, + .rx_buf_get = bcmcnet_rx_buf_get, + .rx_buf_put = bcmcnet_rx_buf_put, + .rx_buf_free = bcmcnet_rx_buf_free, + .rx_buf_mode = bcmcnet_rx_buf_mode, + .tx_buf_get = bcmcnet_tx_buf_get, + .tx_buf_dma = bcmcnet_tx_buf_dma, + .tx_buf_free = bcmcnet_tx_buf_free, +}; + +/*! + * Open a device + */ +void +bcmcnet_buf_mngr_init(struct pdma_dev *dev) +{ + dev->ctrl.buf_mngr = (struct pdma_buf_mngr *)&buf_mngr; +} + diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_buff.h b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_buff.h new file mode 100644 index 000000000000..54768e826917 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_buff.h @@ -0,0 +1,83 @@ +/*! \file ngknet_buff.h + * + * Generic data structure definitions for NGKNET packet buffer management. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#ifndef NGKNET_BUFF_H +#define NGKNET_BUFF_H + +/*! Rx buffer align size */ +#define PDMA_RXB_ALIGN 32 +/*! Rx buffer reserved size */ +#define PDMA_RXB_RESV (PDMA_RXB_ALIGN + PKT_HDR_SIZE) +/*! Rx SKB reserved size */ +#define PDMA_SKB_RESV (PDMA_RXB_RESV + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) +/*! Rx buffer size */ +#define PDMA_RXB_SIZE(len) (SKB_DATA_ALIGN(len + NET_SKB_PAD) + PDMA_SKB_RESV) +/*! Rx reserved meta size */ +#define PDMA_RXB_META 64 +/*! Max page buffer size */ +#define PDMA_PAGE_BUF_MAX 2048 + +/*! + * \brief Rx buffer. + */ +struct pdma_rx_buf { + /*! DMA address */ + dma_addr_t dma; + + /*! Buffer page */ + struct page *page; + + /*! Buffer page offset */ + unsigned int page_offset; + + /*! Rx SKB */ + struct sk_buff *skb; + + /*! Packet buffer point */ + struct pkt_buf *pkb; + + /*! Packet buffer adjustment */ + uint32_t adj; +}; + +/*! + * \brief Tx buffer. + */ +struct pdma_tx_buf { + /*! DMA address */ + dma_addr_t dma; + + /*! Tx buffer length */ + uint32_t len; + + /*! Tx SKB */ + struct sk_buff *skb; + + /*! Packet buffer point */ + struct pkt_buf *pkb; + + /*! Packet buffer adjustment */ + uint32_t adj; +}; + +#endif /* NGKNET_BUFF_H */ + diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_callback.c b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_callback.c new file mode 100644 index 000000000000..21512a51fbd2 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_callback.c @@ -0,0 +1,315 @@ +/*! \file ngknet_callback.c + * + * Utility routines for NGKNET callbacks. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include "ngknet_callback.h" + +static struct ngknet_callback_ctrl callback_ctrl; + +int +ngknet_callback_control_get(struct ngknet_callback_ctrl **cbc) +{ + *cbc = &callback_ctrl; + + return 0; +} + +/*! + * Call-back interfaces for other Linux kernel drivers. + * + * The Rx call-back allows an external module to modify packet contents + * before it is handed off to the Linux network stack. + * + * The Tx call-back allows an external module to modify packet contents + * before it is injected into the switch. + */ + +int +ngknet_rx_cb_register(ngknet_rx_cb_f rx_cb) +{ + if (callback_ctrl.rx_cb != NULL) { + return -1; + } + callback_ctrl.rx_cb = rx_cb; + + return 0; +} + +int +ngknet_rx_cb_unregister(ngknet_rx_cb_f rx_cb) +{ + if (rx_cb == NULL || callback_ctrl.rx_cb != rx_cb) { + return -1; + } + callback_ctrl.rx_cb = NULL; + + return 0; +} + +int +ngknet_tx_cb_register(ngknet_tx_cb_f tx_cb) +{ + if (callback_ctrl.tx_cb != NULL) { + return -1; + } + callback_ctrl.tx_cb = tx_cb; + + return 0; +} + +int +ngknet_tx_cb_unregister(ngknet_tx_cb_f tx_cb) +{ + if (tx_cb == NULL || callback_ctrl.tx_cb != tx_cb) { + return -1; + } + callback_ctrl.tx_cb = NULL; + + return 0; +} + +int +ngknet_ptp_rx_config_set_cb_register(ngknet_ptp_config_set_cb_f ptp_rx_config_set_cb) +{ + if (callback_ctrl.ptp_rx_config_set_cb != NULL) { + return -1; + } + callback_ctrl.ptp_rx_config_set_cb = ptp_rx_config_set_cb; + + return 0; +} + +int +ngknet_ptp_rx_config_set_cb_unregister(ngknet_ptp_config_set_cb_f ptp_rx_config_set_cb) +{ + if (ptp_rx_config_set_cb == NULL || + callback_ctrl.ptp_rx_config_set_cb != ptp_rx_config_set_cb) { + return -1; + } + callback_ctrl.ptp_rx_config_set_cb = NULL; + + return 0; +} + +int +ngknet_ptp_tx_config_set_cb_register(ngknet_ptp_config_set_cb_f ptp_tx_config_set_cb) +{ + if (callback_ctrl.ptp_tx_config_set_cb != NULL) { + return -1; + } + callback_ctrl.ptp_tx_config_set_cb = ptp_tx_config_set_cb; + + return 0; +} + +int +ngknet_ptp_tx_config_set_cb_unregister(ngknet_ptp_config_set_cb_f ptp_tx_config_set_cb) +{ + if (ptp_tx_config_set_cb == NULL || + callback_ctrl.ptp_tx_config_set_cb != ptp_tx_config_set_cb) { + return -1; + } + callback_ctrl.ptp_tx_config_set_cb = NULL; + + return 0; +} + +int +ngknet_ptp_rx_hwts_get_cb_register(ngknet_ptp_hwts_get_cb_f ptp_rx_hwts_get_cb) +{ + if (callback_ctrl.ptp_rx_hwts_get_cb != NULL) { + return -1; + } + callback_ctrl.ptp_rx_hwts_get_cb = ptp_rx_hwts_get_cb; + + return 0; +} + +int +ngknet_ptp_rx_hwts_get_cb_unregister(ngknet_ptp_hwts_get_cb_f ptp_rx_hwts_get_cb) +{ + if (ptp_rx_hwts_get_cb == NULL || + callback_ctrl.ptp_rx_hwts_get_cb != ptp_rx_hwts_get_cb) { + return -1; + } + callback_ctrl.ptp_rx_hwts_get_cb = NULL; + + return 0; +} + +int +ngknet_ptp_tx_hwts_get_cb_register(ngknet_ptp_hwts_get_cb_f ptp_tx_hwts_get_cb) +{ + if (callback_ctrl.ptp_tx_hwts_get_cb != NULL) { + return -1; + } + callback_ctrl.ptp_tx_hwts_get_cb = ptp_tx_hwts_get_cb; + + return 0; +} + +int +ngknet_ptp_tx_hwts_get_cb_unregister(ngknet_ptp_hwts_get_cb_f ptp_tx_hwts_get_cb) +{ + if (ptp_tx_hwts_get_cb == NULL || + callback_ctrl.ptp_tx_hwts_get_cb != ptp_tx_hwts_get_cb) { + return -1; + } + callback_ctrl.ptp_tx_hwts_get_cb = NULL; + + return 0; +} + +int +ngknet_ptp_tx_meta_set_cb_register(ngknet_ptp_meta_set_cb_f ptp_tx_meta_set_cb) +{ + if (callback_ctrl.ptp_tx_meta_set_cb != NULL) { + return -1; + } + callback_ctrl.ptp_tx_meta_set_cb = ptp_tx_meta_set_cb; + + return 0; +} + +int +ngknet_ptp_tx_meta_set_cb_unregister(ngknet_ptp_meta_set_cb_f ptp_tx_meta_set_cb) +{ + if (ptp_tx_meta_set_cb == NULL || + callback_ctrl.ptp_tx_meta_set_cb != ptp_tx_meta_set_cb) { + return -1; + } + callback_ctrl.ptp_tx_meta_set_cb = NULL; + + return 0; +} + +int +ngknet_ptp_phc_index_get_cb_register(ngknet_ptp_phc_index_get_cb_f ptp_phc_index_get_cb) +{ + if (callback_ctrl.ptp_phc_index_get_cb != NULL) { + return -1; + } + callback_ctrl.ptp_phc_index_get_cb = ptp_phc_index_get_cb; + + return 0; +} + +int +ngknet_ptp_phc_index_get_cb_unregister(ngknet_ptp_phc_index_get_cb_f ptp_phc_index_get_cb) +{ + if (ptp_phc_index_get_cb == NULL || + callback_ctrl.ptp_phc_index_get_cb != ptp_phc_index_get_cb) { + return -1; + } + callback_ctrl.ptp_phc_index_get_cb = NULL; + + return 0; +} + +int +ngknet_ptp_dev_ctrl_cb_register(ngknet_ptp_dev_ctrl_cb_f ptp_dev_ctrl_cb) +{ + if (callback_ctrl.ptp_dev_ctrl_cb != NULL) { + return -1; + } + callback_ctrl.ptp_dev_ctrl_cb = ptp_dev_ctrl_cb; + + return 0; +} + +int +ngknet_ptp_dev_ctrl_cb_unregister(ngknet_ptp_dev_ctrl_cb_f ptp_dev_ctrl_cb) +{ + if (ptp_dev_ctrl_cb == NULL || + callback_ctrl.ptp_dev_ctrl_cb != ptp_dev_ctrl_cb) { + return -1; + } + callback_ctrl.ptp_dev_ctrl_cb = NULL; + + return 0; +} + +int +ngknet_netif_create_cb_register(ngknet_netif_cb_f netif_cb) +{ + if (callback_ctrl.netif_create_cb != NULL) { + return -1; + } + callback_ctrl.netif_create_cb = netif_cb; + + return 0; +} + +int +ngknet_netif_create_cb_unregister(ngknet_netif_cb_f netif_cb) +{ + if (netif_cb == NULL || callback_ctrl.netif_create_cb != netif_cb) { + return -1; + } + callback_ctrl.netif_create_cb = NULL; + + return 0; +} + +int +ngknet_netif_destroy_cb_register(ngknet_netif_cb_f netif_cb) +{ + if (callback_ctrl.netif_destroy_cb != NULL) { + return -1; + } + callback_ctrl.netif_destroy_cb = netif_cb; + + return 0; +} + +int +ngknet_netif_destroy_cb_unregister(ngknet_netif_cb_f netif_cb) +{ + if (netif_cb == NULL || callback_ctrl.netif_destroy_cb != netif_cb) { + return -1; + } + callback_ctrl.netif_destroy_cb = NULL; + + return 0; +} + +EXPORT_SYMBOL(ngknet_rx_cb_register); +EXPORT_SYMBOL(ngknet_rx_cb_unregister); +EXPORT_SYMBOL(ngknet_tx_cb_register); +EXPORT_SYMBOL(ngknet_tx_cb_unregister); +EXPORT_SYMBOL(ngknet_ptp_rx_config_set_cb_register); +EXPORT_SYMBOL(ngknet_ptp_rx_config_set_cb_unregister); +EXPORT_SYMBOL(ngknet_ptp_tx_config_set_cb_register); +EXPORT_SYMBOL(ngknet_ptp_tx_config_set_cb_unregister); +EXPORT_SYMBOL(ngknet_ptp_rx_hwts_get_cb_register); +EXPORT_SYMBOL(ngknet_ptp_rx_hwts_get_cb_unregister); +EXPORT_SYMBOL(ngknet_ptp_tx_hwts_get_cb_register); +EXPORT_SYMBOL(ngknet_ptp_tx_hwts_get_cb_unregister); +EXPORT_SYMBOL(ngknet_ptp_tx_meta_set_cb_register); +EXPORT_SYMBOL(ngknet_ptp_tx_meta_set_cb_unregister); +EXPORT_SYMBOL(ngknet_ptp_phc_index_get_cb_register); +EXPORT_SYMBOL(ngknet_ptp_phc_index_get_cb_unregister); +EXPORT_SYMBOL(ngknet_ptp_dev_ctrl_cb_register); +EXPORT_SYMBOL(ngknet_ptp_dev_ctrl_cb_unregister); +EXPORT_SYMBOL(ngknet_netif_create_cb_register); +EXPORT_SYMBOL(ngknet_netif_create_cb_unregister); +EXPORT_SYMBOL(ngknet_netif_destroy_cb_register); +EXPORT_SYMBOL(ngknet_netif_destroy_cb_unregister); diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_callback.h b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_callback.h new file mode 100644 index 000000000000..54583adffa36 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_callback.h @@ -0,0 +1,364 @@ +/*! \file ngknet_callback.h + * + * Data structure definitions for NGKNET callbacks. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#ifndef NGKNET_CALLBACK_H +#define NGKNET_CALLBACK_H + +#include +#include "ngknet_main.h" + +/*! + * \brief NGKNET callback description. + */ +struct ngknet_callback_desc { + /*! Device number */ + int dev_no; + + /*! Device ID */ + uint32_t dev_id; + + /*! Device type string */ + const char *type_str; + + /*! Network interface private data */ + struct ngknet_private *priv; + + /*! Matched filter */ + struct ngknet_filter_s *filt; + + /*! Packet meta data */ + uint8_t *pmd; + + /*! Packet meta data length */ + int pmd_len; + + /*! Packet data length */ + int pkt_len; + + /*! Matched callback filter */ + struct ngknet_filter_s *filt_cb; +}; + +#define NGKNET_SKB_CB(_skb) ((struct ngknet_callback_desc *)_skb->cb) + +/*! Handle Rx packet */ +typedef struct sk_buff * +(*ngknet_rx_cb_f)(struct sk_buff *skb); + +/*! Handle Tx packet */ +typedef struct sk_buff * +(*ngknet_tx_cb_f)(struct sk_buff *skb); + +/*! PTP Rx/Tx config set */ +typedef int +(*ngknet_ptp_config_set_cb_f)(struct ngknet_private *priv, int *value); + +/*! PTP Rx/Tx HW timestamp get */ +typedef int +(*ngknet_ptp_hwts_get_cb_f)(struct sk_buff *skb, uint64_t *ts); + +/*! PTP Tx meta set */ +typedef int +(*ngknet_ptp_meta_set_cb_f)(struct sk_buff *skb); + +/*! PTP PHC index get */ +typedef int +(*ngknet_ptp_phc_index_get_cb_f)(struct ngknet_private *priv, int *index); + +/*! PTP device control */ +typedef int +(*ngknet_ptp_dev_ctrl_cb_f)(struct ngknet_dev *dev, int cmd, char *data, int len); + +/*! Netif callback */ +typedef int +(*ngknet_netif_cb_f)(struct net_device *dev); + +/*! + * \brief NGKNET callback control. + */ +struct ngknet_callback_ctrl { + /*! Handle Rx packet */ + ngknet_rx_cb_f rx_cb; + + /*! Handle Tx packet */ + ngknet_tx_cb_f tx_cb; + + /*! PTP Rx config set */ + ngknet_ptp_config_set_cb_f ptp_rx_config_set_cb; + + /*! PTP Tx config set */ + ngknet_ptp_config_set_cb_f ptp_tx_config_set_cb; + + /*! PTP Rx HW timestamp get */ + ngknet_ptp_hwts_get_cb_f ptp_rx_hwts_get_cb; + + /*! PTP Tx HW timestamp get */ + ngknet_ptp_hwts_get_cb_f ptp_tx_hwts_get_cb; + + /*! PTP Tx meta set */ + ngknet_ptp_meta_set_cb_f ptp_tx_meta_set_cb; + + /*! PTP PHC index get */ + ngknet_ptp_phc_index_get_cb_f ptp_phc_index_get_cb; + + /*! PTP device control */ + ngknet_ptp_dev_ctrl_cb_f ptp_dev_ctrl_cb; + + /*! Handle Netif create */ + ngknet_netif_cb_f netif_create_cb; + + /*! Handle Netif destroy */ + ngknet_netif_cb_f netif_destroy_cb; +}; + +/*! + * \brief Get callback control. + * + * \param [in] cbc Pointer to callback control. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_callback_control_get(struct ngknet_callback_ctrl **cbc); + +/*! + * \brief Register Rx callback. + * + * \param [in] rx_cb Rx callback function. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_rx_cb_register(ngknet_rx_cb_f rx_cb); + +/*! + * \brief Unregister Rx callback. + * + * \param [in] rx_cb Rx callback function. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_rx_cb_unregister(ngknet_rx_cb_f rx_cb); + +/*! + * \brief Register Tx callback. + * + * \param [in] tx_cb Tx callback function. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_tx_cb_register(ngknet_tx_cb_f tx_cb); + +/*! + * \brief Unregister Tx callback. + * + * \param [in] tx_cb Tx callback function. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_tx_cb_unregister(ngknet_tx_cb_f tx_cb); + +/*! + * \brief Register PTP Rx config set callback. + * + * \param [in] ptp_rx_config_set_cb Rx config set callback function. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_ptp_rx_config_set_cb_register(ngknet_ptp_config_set_cb_f ptp_rx_config_set_cb); + +/*! + * \brief Unregister PTP Rx config set callback. + * + * \param [in] ptp_rx_config_set_cb Rx config set callback function. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_ptp_rx_config_set_cb_unregister(ngknet_ptp_config_set_cb_f ptp_rx_config_set_cb); + +/*! + * \brief Register PTP Tx config set callback. + * + * \param [in] ptp_tx_config_set_cb Tx config set callback function. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_ptp_tx_config_set_cb_register(ngknet_ptp_config_set_cb_f ptp_tx_config_set_cb); + +/*! + * \brief Unregister PTP Tx config set callback. + * + * \param [in] ptp_tx_config_set_cb Tx config set callback function. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_ptp_tx_config_set_cb_unregister(ngknet_ptp_config_set_cb_f ptp_tx_config_set_cb); + +/*! + * \brief Register PTP Rx HW timestamp get callback. + * + * \param [in] ptp_rx_hwts_get_cb Rx HW timestamp get callback function. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_ptp_rx_hwts_get_cb_register(ngknet_ptp_hwts_get_cb_f ptp_rx_hwts_get_cb); + +/*! + * \brief Unregister PTP Rx HW timestamp get callback. + * + * \param [in] ptp_rx_hwts_get_cb Rx HW timestamp get callback function. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_ptp_rx_hwts_get_cb_unregister(ngknet_ptp_hwts_get_cb_f ptp_rx_hwts_get_cb); + +/*! + * \brief Register PTP Tx HW timestamp get callback. + * + * \param [in] ptp_tx_hwts_get_cb Tx HW timestamp get callback function. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_ptp_tx_hwts_get_cb_register(ngknet_ptp_hwts_get_cb_f ptp_tx_hwts_get_cb); + +/*! + * \brief Unregister PTP Tx HW timestamp get callback. + * + * \param [in] ptp_tx_hwts_get_cb Tx HW timestamp get callback function. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_ptp_tx_hwts_get_cb_unregister(ngknet_ptp_hwts_get_cb_f ptp_tx_hwts_get_cb); + +/*! + * \brief Register PTP Tx meta set callback. + * + * \param [in] ptp_tx_meta_set_cb Tx meta set callback function. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_ptp_tx_meta_set_cb_register(ngknet_ptp_meta_set_cb_f ptp_tx_meta_set_cb); + +/*! + * \brief Unregister PTP Tx meta set callback. + * + * \param [in] ptp_tx_meta_set_cb Tx meta set callback function. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_ptp_tx_meta_set_cb_unregister(ngknet_ptp_meta_set_cb_f ptp_tx_meta_set_cb); + +/*! + * \brief Register PTP PHC index get callback. + * + * \param [in] ptp_phc_index_get_cb PHC index get callback function. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_ptp_phc_index_get_cb_register(ngknet_ptp_phc_index_get_cb_f ptp_phc_index_get_cb); + +/*! + * \brief Unregister PTP PHC index get callback. + * + * \param [in] ptp_phc_index_get_cb PHC index get callback function. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_ptp_phc_index_get_cb_unregister(ngknet_ptp_phc_index_get_cb_f ptp_phc_index_get_cb); + +/*! + * \brief Register PTP device control callback. + * + * \param [in] ptp_dev_ctrl_cb Device control callback function. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_ptp_dev_ctrl_cb_register(ngknet_ptp_dev_ctrl_cb_f ptp_dev_ctrl_cb); + +/*! + * \brief Unregister PTP device control callback. + * + * \param [in] ptp_dev_ctrl_cb Device control callback function. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_ptp_dev_ctrl_cb_unregister(ngknet_ptp_dev_ctrl_cb_f ptp_dev_ctrl_cb); + +/*! + * \brief Register Netif Create callback. + * + * \param [netif_cb] netif_cb create callback function. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_netif_create_cb_register(ngknet_netif_cb_f netif_cb); + +/*! + * \brief Unregister Netif Create callback. + * + * \param [netif_cb] netif_cb destroy callback function. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_netif_create_cb_unregister(ngknet_netif_cb_f netif_cb); + +/*! + * \brief Register Netif Destroy callback. + * + * \param [netif_cb] netif_cb destroy callback function. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_netif_destroy_cb_register(ngknet_netif_cb_f netif_cb); + +/*! + * \brief Unregister Netif Destroy callback. + * + * \param [netif_cb] netif_cb destroy callback function. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_netif_destroy_cb_unregister(ngknet_netif_cb_f netif_cb); + +#endif /* NGKNET_CALLBACK_H */ + diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_dep.h b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_dep.h new file mode 100644 index 000000000000..919dd6450340 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_dep.h @@ -0,0 +1,61 @@ +/*! \file ngknet_dep.h + * + * Macro definitions for NGKNET dependence. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#ifndef NGKNET_DEP_H +#define NGKNET_DEP_H + +#include +#include + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +/*! Memorry barrier */ +#define MEMORY_BARRIER smp_mb() + +/*! CNET print uitility */ +#define CNET_PR(fmt, args...) printk(fmt, ##args) + +struct pdma_dev; + +/*! Externs for the required functions. */ +#define BCMDRD_DEVLIST_ENTRY(_nm,_vn,_dv,_rv,_md,_pi,_bd,_bc,_fn,_cn,_pf,_pd,_r0,_r1) \ +extern int _bd##_cnet_pdma_attach(struct pdma_dev *dev); \ +extern int _bd##_cnet_pdma_detach(struct pdma_dev *dev); +#include + +/*! Create enumeration values from list of supported devices. */ +#define BCMDRD_DEVLIST_ENTRY(_nm,_vn,_dv,_rv,_md,_pi,_bd,_bc,_fn,_cn,_pf,_pd,_r0,_r1) \ + NGKNET_DEV_T_##_bd, +/*! Enumeration for all base device types. */ +typedef enum { + NGKNET_DEV_T_NONE = 0, +#include + NGKNET_DEV_T_COUNT +} ngknet_dev_type_t; + +#endif /* NGKNET_DEP_H */ + diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_extra.c b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_extra.c new file mode 100644 index 000000000000..00fdb3da8849 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_extra.c @@ -0,0 +1,505 @@ +/*! \file ngknet_extra.c + * + * Utility routines for NGKNET enhancement. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "ngknet_main.h" +#include "ngknet_extra.h" +#include "ngknet_callback.h" + +static struct ngknet_rl_ctrl rl_ctrl; + +int +ngknet_filter_create(struct ngknet_dev *dev, ngknet_filter_t *filter) +{ + struct filt_ctrl *fc = NULL; + struct list_head *list = NULL; + ngknet_filter_t *filt = NULL; + unsigned long flags; + int num, id, done = 0; + + switch (filter->type) { + case NGKNET_FILTER_T_RX_PKT: + break; + default: + return SHR_E_UNAVAIL; + } + + switch (filter->dest_type) { + case NGKNET_FILTER_DEST_T_NULL: + case NGKNET_FILTER_DEST_T_NETIF: + case NGKNET_FILTER_DEST_T_VNET: + case NGKNET_FILTER_DEST_T_CB: /* SDKLT-26907: support NGKNET_FILTER_DEST_T_CB */ + break; + default: + return SHR_E_UNAVAIL; + } + + spin_lock_irqsave(&dev->lock, flags); + + num = (long)dev->fc[0]; + for (id = 1; id < num + 1; id++) { + if (!dev->fc[id]) { + break; + } + } + if (id > NUM_FILTER_MAX) { + spin_unlock_irqrestore(&dev->lock, flags); + return SHR_E_RESOURCE; + } + + fc = kzalloc(sizeof(*fc), GFP_KERNEL); + if (!fc) { + spin_unlock_irqrestore(&dev->lock, flags); + return SHR_E_MEMORY; + } + + dev->fc[id] = fc; + num += id == (num + 1) ? 1 : 0; + dev->fc[0] = (void *)(long)num; + + memcpy(&fc->filt, filter, sizeof(fc->filt)); + fc->filt.id = id; + + list_for_each(list, &dev->filt_list) { + filt = &((struct filt_ctrl *)list)->filt; + if (filt->flags & NGKNET_FILTER_F_MATCH_CHAN) { + if (!(fc->filt.flags & NGKNET_FILTER_F_MATCH_CHAN) || + fc->filt.chan > filt->chan) { + continue; + } + if (fc->filt.chan < filt->chan || + fc->filt.priority < filt->priority) { + list_add_tail(&fc->list, list); + done = 1; + break; + } + } else { + if (fc->filt.flags & NGKNET_FILTER_F_MATCH_CHAN || + fc->filt.priority < filt->priority) { + list_add_tail(&fc->list, list); + done = 1; + break; + } + } + } + if (!done) { + list_add_tail(&fc->list, &dev->filt_list); + } + + filter->id = fc->filt.id; + + spin_unlock_irqrestore(&dev->lock, flags); + + return SHR_E_NONE; +} + +int +ngknet_filter_destroy(struct ngknet_dev *dev, int id) +{ + struct filt_ctrl *fc = NULL; + unsigned long flags; + int num; + + if (id <= 0 || id > NUM_FILTER_MAX) { + return SHR_E_PARAM; + } + + spin_lock_irqsave(&dev->lock, flags); + + fc = (struct filt_ctrl *)dev->fc[id]; + if (!fc) { + spin_unlock_irqrestore(&dev->lock, flags); + return SHR_E_NOT_FOUND; + } + + list_del(&fc->list); + kfree(fc); + + dev->fc[id] = NULL; + num = (long)dev->fc[0]; + while (num-- == id--) { + if (dev->fc[id]) { + dev->fc[0] = (void *)(long)num; + break; + } + } + + spin_unlock_irqrestore(&dev->lock, flags); + + return SHR_E_NONE; +} + +int +ngknet_filter_destroy_all(struct ngknet_dev *dev) +{ + int id; + int rv; + + for (id = 1; id <= NUM_FILTER_MAX; id++) { + rv = ngknet_filter_destroy(dev, id); + if (SHR_FAILURE(rv)) { + return rv; + } + } + + return SHR_E_NONE; +} + +int +ngknet_filter_get(struct ngknet_dev *dev, int id, ngknet_filter_t *filter) +{ + struct filt_ctrl *fc = NULL; + unsigned long flags; + int num; + + if (id <= 0 || id > NUM_FILTER_MAX) { + return SHR_E_PARAM; + } + + spin_lock_irqsave(&dev->lock, flags); + + fc = (struct filt_ctrl *)dev->fc[id]; + if (!fc) { + spin_unlock_irqrestore(&dev->lock, flags); + return SHR_E_NOT_FOUND; + } + + memcpy(filter, &fc->filt, sizeof(*filter)); + + num = (long)dev->fc[0]; + for (id++; id < num + 1; id++) { + if (dev->fc[id]) { + break; + } + } + filter->next = id == (num + 1) ? 0 : id; + + spin_unlock_irqrestore(&dev->lock, flags); + + return SHR_E_NONE; +} + +int +ngknet_filter_get_next(struct ngknet_dev *dev, ngknet_filter_t *filter) +{ + int id; + int rv; + + if (!filter->next) { + for (id = 1; id <= NUM_FILTER_MAX; id++) { + rv = ngknet_filter_get(dev, id, filter); + if (SHR_SUCCESS(rv)) { + return rv; + } + } + if (id > NUM_FILTER_MAX) { + return SHR_E_NOT_FOUND; + } + } + + return ngknet_filter_get(dev, filter->next, filter); +} + +int +ngknet_rx_pkt_filter(struct ngknet_dev *dev, struct sk_buff *skb, struct net_device **ndev, + struct net_device **mndev, struct sk_buff **mskb) +{ + struct pkt_buf *pkb = (struct pkt_buf *)skb->data; + struct net_device *dest_ndev = NULL, *mirror_ndev = NULL; + struct sk_buff *mirror_skb = NULL; + struct ngknet_private *priv = NULL; + struct filt_ctrl *fc = NULL; + struct list_head *list = NULL; + ngknet_filter_t scratch, *filt = NULL, *filt_cb = NULL; + uint8_t *oob = &pkb->data, *data = NULL; + uint16_t tpid; + unsigned long flags; + int wsize; + int chan_id; + int idx, match = 0, match_cb = 0; + + bcmcnet_pdma_dev_queue_to_chan(&dev->pdma_dev, pkb->pkh.queue_id, + PDMA_Q_RX, &chan_id); + + spin_lock_irqsave(&dev->lock, flags); + + dest_ndev = dev->bdev[chan_id]; + if (dest_ndev) { + skb->dev = dest_ndev; + priv = netdev_priv(dest_ndev); + priv->users++; + *ndev = dest_ndev; + spin_unlock_irqrestore(&dev->lock, flags); + return SHR_E_NONE; + } + + if (list_empty(&dev->filt_list)) { + spin_unlock_irqrestore(&dev->lock, flags); + return SHR_E_NONE; + } + + list_for_each(list, &dev->filt_list) { + fc = (struct filt_ctrl *)list; + filt = &fc->filt; + if (filt->flags & NGKNET_FILTER_F_ANY_DATA) { + match = 1; + break; + } + if (filt->flags & NGKNET_FILTER_F_MATCH_CHAN && filt->chan != chan_id) { + continue; + } + memcpy(&scratch.data.b[0], + &oob[filt->oob_data_offset], filt->oob_data_size); + memcpy(&scratch.data.b[filt->oob_data_size], + &pkb->data + pkb->pkh.meta_len + filt->pkt_data_offset, + filt->pkt_data_size); + wsize = NGKNET_BYTES2WORDS(filt->oob_data_size + filt->pkt_data_size); + for (idx = 0; idx < wsize; idx++) { + scratch.data.w[idx] &= filt->mask.w[idx]; + if (scratch.data.w[idx] != filt->data.w[idx]) { + break; + } + } + if (idx == wsize) { + if (NGKNET_FILTER_DEST_T_CB == filt->dest_type) { + match_cb = 1; + filt_cb = filt; + continue; + } + match = 1; + break; + } + } + + if (match) { + fc->hits++; + switch (filt->dest_type) { + case NGKNET_FILTER_DEST_T_NETIF: + if (filt->dest_id == 0) { + dest_ndev = dev->net_dev; + } else { + dest_ndev = dev->vdev[filt->dest_id]; + } + if (dest_ndev) { + skb->dev = dest_ndev; + if (filt->dest_proto) { + pkb->pkh.attrs |= PDMA_RX_SET_PROTO; + skb->protocol = filt->dest_proto; + } + priv = netdev_priv(dest_ndev); + priv->users++; + } + break; + case NGKNET_FILTER_DEST_T_VNET: + pkb->pkh.attrs |= PDMA_RX_TO_VNET; + spin_unlock_irqrestore(&dev->lock, flags); + return SHR_E_NO_HANDLER; + case NGKNET_FILTER_DEST_T_NULL: + default: + spin_unlock_irqrestore(&dev->lock, flags); + return SHR_E_UNAVAIL; + } + } + + spin_unlock_irqrestore(&dev->lock, flags); + + if (!dest_ndev) { + return SHR_E_NONE; + } else { + *ndev = dest_ndev; + } + + if (filt->flags & NGKNET_FILTER_F_STRIP_TAG) { + pkb->pkh.attrs |= PDMA_RX_STRIP_TAG; + data = skb->data + PKT_HDR_SIZE + pkb->pkh.meta_len; + tpid = data[12] << 8 | data[13]; + if (tpid == ETH_P_8021Q || tpid == ETH_P_8021AD) { + pkb->pkh.data_len -= VLAN_HLEN; + memmove(skb->data + VLAN_HLEN, skb->data, + PKT_HDR_SIZE + pkb->pkh.meta_len + 2 * ETH_ALEN); + skb_pull(skb, VLAN_HLEN); + } + } + + if (dev->cbc->rx_cb) { + NGKNET_SKB_CB(skb)->filt = filt; + + /* Add callback filter if matched */ + if (match_cb) { + NGKNET_SKB_CB(skb)->filt_cb = filt_cb; + } + } + + if (filt->mirror_type == NGKNET_FILTER_DEST_T_NETIF) { + spin_lock_irqsave(&dev->lock, flags); + if (filt->mirror_id == 0) { + mirror_ndev = dev->net_dev; + } else { + mirror_ndev = dev->vdev[filt->mirror_id]; + } + if (mirror_ndev) { + mirror_skb = pskb_copy(skb, GFP_ATOMIC); + if (mirror_skb) { + mirror_skb->dev = mirror_ndev; + if (filt->mirror_proto) { + pkb->pkh.attrs |= PDMA_RX_SET_PROTO; + mirror_skb->protocol = filt->mirror_proto; + } + if (dev->cbc->rx_cb) { + NGKNET_SKB_CB(mirror_skb)->filt = filt; + } + priv = netdev_priv(mirror_ndev); + priv->users++; + *mndev = mirror_ndev; + *mskb = mirror_skb; + } + } + spin_unlock_irqrestore(&dev->lock, flags); + } + + return SHR_E_NONE; +} + +static void +ngknet_rl_process(timer_context_t data) +{ + struct ngknet_rl_ctrl *rc = timer_arg(rc, data, timer); + struct ngknet_dev *dev; + unsigned long flags; + int idx; + + spin_lock_irqsave(&rc->lock, flags); + rc->rx_pkts = 0; + for (idx = 0; idx < NUM_PDMA_DEV_MAX; idx++) { + dev = &rc->devs[idx]; + if (rc->dev_active[idx] && rc->dev_paused[idx]) { + bcmcnet_pdma_dev_rx_resume(&dev->pdma_dev); + rl_ctrl.dev_paused[dev->dev_no] = 0; + } + } + spin_unlock_irqrestore(&rc->lock, flags); + + rc->timer.expires = jiffies + HZ / rc->rx_ticks; + add_timer(&rc->timer); +} + +void +ngknet_rx_rate_limit_init(struct ngknet_dev *devs) +{ + sal_memset(&rl_ctrl, 0, sizeof(rl_ctrl)); + rl_ctrl.rx_ticks = 10; + setup_timer(&rl_ctrl.timer, ngknet_rl_process, (timer_context_t)&rl_ctrl); + spin_lock_init(&rl_ctrl.lock); + rl_ctrl.devs = devs; +} + +void +ngknet_rx_rate_limit_cleanup(void) +{ + del_timer_sync(&rl_ctrl.timer); +} + +int +ngknet_rx_rate_limit_started(void) +{ + return rl_ctrl.started; +} + +void +ngknet_rx_rate_limit_start(struct ngknet_dev *dev) +{ + unsigned long flags; + + spin_lock_irqsave(&rl_ctrl.lock, flags); + rl_ctrl.dev_active[dev->dev_no] = 1; + spin_unlock_irqrestore(&rl_ctrl.lock, flags); + + if (!rl_ctrl.started) { + rl_ctrl.started = 1; + rl_ctrl.timer.expires = jiffies + HZ / rl_ctrl.rx_ticks; + add_timer(&rl_ctrl.timer); + } +} + +void +ngknet_rx_rate_limit_stop(struct ngknet_dev *dev) +{ + unsigned long flags; + + spin_lock_irqsave(&rl_ctrl.lock, flags); + rl_ctrl.dev_active[dev->dev_no] = 0; + spin_unlock_irqrestore(&rl_ctrl.lock, flags); +} + +void +ngknet_rx_rate_limit(struct ngknet_dev *dev, int limit) +{ + unsigned long flags; + + spin_lock_irqsave(&rl_ctrl.lock, flags); + if ((++rl_ctrl.rx_pkts + rl_ctrl.rx_overruns > limit / rl_ctrl.rx_ticks) && + !rl_ctrl.dev_paused[dev->dev_no] && rl_ctrl.dev_active[dev->dev_no]) { + rl_ctrl.dev_paused[dev->dev_no] = 1; + rl_ctrl.rx_overruns = 0; + bcmcnet_pdma_dev_rx_suspend(&dev->pdma_dev); + } + if (rl_ctrl.dev_paused[dev->dev_no]) { + rl_ctrl.rx_overruns++; + } + spin_unlock_irqrestore(&rl_ctrl.lock, flags); +} + +void +ngknet_tx_queue_schedule(struct ngknet_dev *dev, struct sk_buff *skb, int *queue) +{ + struct pkt_buf *pkb = (struct pkt_buf *)skb->data; + + if (pkb->pkh.attrs & PDMA_TX_BIND_QUE) { + *queue = pkb->pkh.queue_id; + } +} + diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_extra.h b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_extra.h new file mode 100644 index 000000000000..27dea9e368e7 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_extra.h @@ -0,0 +1,218 @@ +/*! \file ngknet_extra.h + * + * Generic data structure definitions for NGKNET enhancement. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#ifndef NGKNET_EXTRA_H +#define NGKNET_EXTRA_H + +/*! + * \brief Filter control. + */ +struct filt_ctrl { + /*! List head */ + struct list_head list; + + /*! Device number */ + int dev_no; + + /*! Number of hits */ + uint64_t hits; + + /*! Filter description */ + ngknet_filter_t filt; +}; + +/*! + * \brief Create filter. + * + * \param [in] dev Device structure point. + * \param [in] filter Filter structure point. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +ngknet_filter_create(struct ngknet_dev *dev, ngknet_filter_t *filter); + +/*! + * \brief Destroy filter. + * + * \param [in] dev Device structure point. + * \param [in] id Filter ID. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +ngknet_filter_destroy(struct ngknet_dev *dev, int id); + +/*! + * \brief Destroy all the filters. + * + * \param [in] dev Device structure point. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +ngknet_filter_destroy_all(struct ngknet_dev *dev); + +/*! + * \brief Get filter. + * + * \param [in] dev Device structure point. + * \param [in] id Filter ID. + * \param [out] filter Filter structure point. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +ngknet_filter_get(struct ngknet_dev *dev, int id, ngknet_filter_t *filter); + +/*! + * \brief Get the next filter. + * + * \param [in] dev Device structure point. + * \param [out] filter Filter structure point. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +ngknet_filter_get_next(struct ngknet_dev *dev, ngknet_filter_t *filter); + +/*! + * \brief Filter packet. + * + * \param [in] dev Device structure point. + * \param [in] skb Rx packet SKB. + * \param [out] mndev Mirror network interface. + * \param [out] mskb Mirror Rx packet SKB. + * + * \retval Matched network interface. + * \retval NULL No matched network interface. + */ +extern int +ngknet_rx_pkt_filter(struct ngknet_dev *dev, struct sk_buff *skb, struct net_device **ndev, + struct net_device **mndev, struct sk_buff **mskb); + +/*! + * \brief Rx rate limit control. + * + * This contains all the control information for Rx rate limit such as + * the number of Rx packets, status related to Rx rate limit, etc. + * + * The rate limit is kernel-oriented, i.e. all the Rx packets from any + * device/channel will be accounted for. Once the received packets reach + * the limit value in an 1-Sec interval, the driver API XXXX_rx_suspend() + * will be called to suspend Rx. The 1-Sec basis timer will call the driver + * API XXXX_rx_resume() to resume Rx and reset rate-related status/counters + * at the begin of the next 1-Sec interval. + * + * The NGKNET module parameter 'rx_rate_limit' is used to decide the maximum + * Rx rate. Disable Rx rate limit if set 0. It can be set when inserting + * NGKNET module or modified using its SYSFS attributions. + */ +struct ngknet_rl_ctrl { + /*! Rx packets */ + int rx_pkts; + + /*! Rx overruns */ + int rx_overruns; + + /*! Rx ticks */ + int rx_ticks; + + /*! Active devices under rate control */ + int dev_active[NUM_PDMA_DEV_MAX]; + + /*! Paused devices due to no Rx credit */ + int dev_paused[NUM_PDMA_DEV_MAX]; + + /*! Rate limit timer */ + struct timer_list timer; + + /*! Rate limit lock */ + spinlock_t lock; + + /*! Devices */ + struct ngknet_dev *devs; + + /*! Rate limit status indicator */ + int started; +}; + +/*! + * \brief Initialize Rx rate limit. + * + * \param [in] devs Devices array. + */ +extern void +ngknet_rx_rate_limit_init(struct ngknet_dev *devs); + +/*! + * \brief Cleanup Rx rate limit. + */ +extern void +ngknet_rx_rate_limit_cleanup(void); + +/*! + * \brief Get Rx rate limit state. + */ +extern int +ngknet_rx_rate_limit_started(void); + +/*! + * \brief Start Rx rate limit. + * + * \param [in] dev Device structure point. + */ +extern void +ngknet_rx_rate_limit_start(struct ngknet_dev *dev); + +/*! + * \brief Stop Rx rate limit. + * + * \param [in] dev Device structure point. + */ +extern void +ngknet_rx_rate_limit_stop(struct ngknet_dev *dev); + +/*! + * \brief Limit Rx rate. + * + * \param [in] dev Device structure point. + */ +extern void +ngknet_rx_rate_limit(struct ngknet_dev *dev, int limit); + +/*! + * \brief Schedule Tx queue. + * + * \param [in] dev Device structure point. + * \param [in] queue Tx queue number. + */ +extern void +ngknet_tx_queue_schedule(struct ngknet_dev *dev, struct sk_buff *skb, int *queue); + +#endif /* NGKNET_EXTRA_H */ + diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_linux.c b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_linux.c new file mode 100644 index 000000000000..0162ae5b96c1 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_linux.c @@ -0,0 +1,173 @@ +/*! \file ngknet_linux.c + * + * Utility routines for Linux kernel APIs abstraction. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ngknet_linux.h" + +/*! + * Time + */ + +unsigned long +sal_time_usecs(void) +{ + struct timeval tv; + + kal_time_val_get(&tv); + + return tv.tv_sec * 1000000 + tv.tv_usec; +} + +void +sal_usleep(unsigned long usec) +{ + unsigned long then, now, hz; + + hz = usec * HZ / 1000000; + if (hz) { + schedule_timeout(hz); + } + usec = usec * HZ % 1000000 / HZ; + if (usec) { + then = sal_time_usecs(); + do { + schedule(); + now = sal_time_usecs(); + } while (now > then && (now - then) < usec); + } +} + +/*! + * Synchronization + */ + +typedef struct { + struct semaphore sem; + char *desc; + int binary; +} sem_ctrl_t; + +sal_sem_t +sal_sem_create(char *desc, int binary, int count) +{ + sem_ctrl_t *sc = kmalloc(sizeof(*sc), GFP_KERNEL); + + if (sc != NULL) { + sema_init(&sc->sem, count); + sc->desc = desc; + sc->binary = binary; + } + + return (sal_sem_t)sc; +} + +void +sal_sem_destroy(sal_sem_t sem) +{ + sem_ctrl_t *sc = (sem_ctrl_t *)sem; + + kfree(sc); +} + +int +sal_sem_take(sal_sem_t sem, int usec) +{ + sem_ctrl_t *sc = (sem_ctrl_t *)sem; + int rv; + + if (usec == SAL_SEM_FOREVER) { + do { + rv = down_interruptible(&sc->sem); + } while (rv == -EINTR); + return rv ? -1 : 0; + } + + return -1; +} + +int +sal_sem_give(sal_sem_t sem) +{ + sem_ctrl_t *sc = (sem_ctrl_t *)sem; + + up(&sc->sem); + + return 0; +} + +typedef struct spinlock_ctrl_s { + spinlock_t spinlock; + unsigned long flags; + char *desc; +} *spinlock_ctrl_t; + +sal_spinlock_t +sal_spinlock_create(char *desc) +{ + spinlock_ctrl_t sl = kmalloc(sizeof(*sl), GFP_KERNEL); + + if (sl != NULL) { + spin_lock_init(&sl->spinlock); + sl->flags = 0; + sl->desc = desc; + } + + return (sal_spinlock_t)sl; +} + +void +sal_spinlock_destroy(sal_spinlock_t lock) +{ + spinlock_ctrl_t sl = (spinlock_ctrl_t)lock; + + kfree(sl); +} + +int +sal_spinlock_lock(sal_spinlock_t lock) +{ + spinlock_ctrl_t sl = (spinlock_ctrl_t)lock; + + spin_lock_irqsave(&sl->spinlock, sl->flags); + + return 0; +} + +int +sal_spinlock_unlock(sal_spinlock_t lock) +{ + spinlock_ctrl_t sl = (spinlock_ctrl_t)lock; + + spin_unlock_irqrestore(&sl->spinlock, sl->flags); + + return 0; +} + diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_linux.h b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_linux.h new file mode 100644 index 000000000000..686aac8f5571 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_linux.h @@ -0,0 +1,240 @@ +/*! \file ngknet_linux.h + * + * Data structure and macro definitions for Linux kernel APIs abstraction. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#ifndef NGKNET_LINUX_H +#define NGKNET_LINUX_H + +#include +#include +#include +#include + +/*! + * Kernel abstraction + */ + +#define MODULE_PARAM(n, t, p) module_param(n, t, p) + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) +#define kal_vlan_hwaccel_put_tag(skb, proto, tci) \ + __vlan_hwaccel_put_tag(skb, tci) +#define NETIF_F_HW_VLAN_CTAG_RX NETIF_F_HW_VLAN_RX +#define NETIF_F_HW_VLAN_CTAG_TX NETIF_F_HW_VLAN_TX +#else +#define kal_vlan_hwaccel_put_tag(skb, proto, tci) \ + __vlan_hwaccel_put_tag(skb, htons(proto), tci) +#endif /* KERNEL_VERSION(3,10,0) */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0) +static inline int +kal_support_paged_skb(void) +{ + return false; +} +#else +static inline int +kal_support_paged_skb(void) +{ + return true; +} +#endif /* KERNEL_VERSION(3,6,0) */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0) +static inline struct page * +kal_dev_alloc_page(void) +{ + return NULL; +} +#elif LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0) +static inline struct page * +kal_dev_alloc_page(void) +{ + return alloc_pages(GFP_ATOMIC | __GFP_ZERO | __GFP_COLD | + __GFP_COMP | __GFP_MEMALLOC, 0); +} +#else +static inline struct page * +kal_dev_alloc_page(void) +{ + return dev_alloc_page(); +} +#endif /* KERNEL_VERSION(3,6,0) */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0) +static inline struct sk_buff * +kal_build_skb(void *data, unsigned int frag_size) +{ + return NULL; +} +#else +static inline struct sk_buff * +kal_build_skb(void *data, unsigned int frag_size) +{ + return build_skb(data, frag_size); +} +#endif /* KERNEL_VERSION(3,6,0) */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0) +static inline void +kal_netif_trans_update(struct net_device *dev) +{ + dev->trans_start = jiffies; +} +#else +static inline void +kal_netif_trans_update(struct net_device *dev) +{ + netif_trans_update(dev); +} +#endif /* KERNEL_VERSION(4,7,0) */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,17,0) +static inline void +kal_time_val_get(struct timeval *tv) +{ + do_gettimeofday(tv); +} +#else +static inline void +kal_time_val_get(struct timeval *tv) +{ + struct timespec64 ts; + ktime_get_real_ts64(&ts); + tv->tv_sec = ts.tv_sec; + tv->tv_usec = ts.tv_nsec / 1000; +} +#endif /* KERNEL_VERSION(3,17,0) */ + +static inline unsigned long +kal_copy_from_user(void *to, const void __user *from, + unsigned int dl, unsigned int sl) +{ + unsigned int len = dl; + + if (unlikely(len != sl)) { + printk(KERN_WARNING "Unmatched linux_ngknet.ko, please use the latest.\n"); + len = min(dl, sl); + } + + return copy_from_user(to, from, len); +} + +static inline unsigned long +kal_copy_to_user(void __user *to, const void *from, + unsigned int dl, unsigned int sl) +{ + unsigned int len = dl; + + if (unlikely(len != sl)) { + printk(KERN_WARNING "Unmatched linux_ngknet.ko, please use the latest.\n"); + len = min(dl, sl); + } + + return copy_to_user(to, from, len); +} + +/*! + * System abstraction + */ + +static inline void * +sal_alloc(unsigned int sz, char *s) +{ + return kmalloc(sz, GFP_KERNEL); +} + +static inline void +sal_free(void *addr) +{ + kfree(addr); +} + +static inline void * +sal_memset(void *dest, int c, size_t cnt) +{ + return memset(dest, c, cnt); +} + +static inline void * +sal_memcpy(void *dest, const void *src, size_t cnt) +{ + return memcpy(dest, src, cnt); +} + +static inline char * +sal_strncpy(char *dest, const char *src, size_t cnt) +{ + return strncpy(dest, src, cnt); +} + +/*! + * Time + */ + +extern unsigned long +sal_time_usecs(void); + +extern void +sal_usleep(unsigned long usec); + +/*! + * Synchronization + */ + +typedef struct sal_sem_s { + char semaphore_opaque_type; +} *sal_sem_t; + +typedef struct sal_spinlock_s { + char spinlock_opaque_type; +} *sal_spinlock_t; + +#define SAL_SEM_FOREVER -1 +#define SAL_SEM_BINARY 1 +#define SAL_SEM_COUNTING 0 + +extern sal_sem_t +sal_sem_create(char *desc, int binary, int count); + +extern void +sal_sem_destroy(sal_sem_t sem); + +extern int +sal_sem_take(sal_sem_t sem, int usec); + +extern int +sal_sem_give(sal_sem_t sem); + +extern sal_spinlock_t +sal_spinlock_create(char *desc); + +extern void +sal_spinlock_destroy(sal_spinlock_t lock); + +extern int +sal_spinlock_lock(sal_spinlock_t lock); + +extern int +sal_spinlock_unlock(sal_spinlock_t lock); + +#endif /* NGKNET_LINUX_H */ + diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_main.c b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_main.c new file mode 100644 index 000000000000..b8af31d85ff2 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_main.c @@ -0,0 +1,2689 @@ +/*! \file ngknet_main.c + * + * NGKNET module entry. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +/* + * This module implements a Linux network driver for Broadcom + * XGS switch devices. The driver simultaneously serves a + * number of virtual Linux network devices. + * + * Packets received from the switch device are sent to a virtual + * Linux network device based on a set of packet filters. + * + * Packets from the virtual Linux network devices are multiplexed + * with fifo mode if only one Tx queue enabled. + * + * A command-based IOCTL interface is used for managing the devices, + * packet filters and virtual Linux network interfaces. + * + * A virtual network interface can be configured to work in RCPU + * mode, which means that packets from the switch device will + * be encapsulated with a RCPU header and a block of meta data + * that basically contains the core DCB information. Likewise, + * packets received from the Linux network stack are assumed to + * be RCPU encapsulated when going out on an interface in RCPU + * mode. If a virtual network interface does not work in RCPU + * mode and transmits to this interface will unmodified go to + * specified physical switch port, DCB information should be + * provided when the interface is created. + * + * The module implements basic Rx DMA rate control. The rate is + * specified in packets per second, and different Rx DMA channels + * can be configured to use different maximum packet rates. + * The packet rate can be configure as a module parameter, and + * it can also be changed dynamically through the proc file + * system (syntax is described in function header comment). + * + * For a list of supported module parameters, please see below. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "ngknet_main.h" +#include "ngknet_extra.h" +#include "ngknet_procfs.h" +#include "ngknet_callback.h" +#include "ngknet_ptp.h" + +/*! \cond */ +MODULE_AUTHOR("Broadcom Corporation"); +MODULE_DESCRIPTION("Network Device Driver Module"); +MODULE_LICENSE("GPL"); +/*! \endcond */ + +/*! \cond */ +static int debug = 0; +MODULE_PARAM(debug, int, 0); +MODULE_PARM_DESC(debug, +"Debug level (default 0)"); +/*! \endcond */ + +/*! \cond */ +static char *base_dev_name = "bcm"; +MODULE_PARAM(base_dev_name, charp, 0); +MODULE_PARM_DESC(base_dev_name, +"Base device name (default bcm0, bcm1, etc.)"); +/*! \endcond */ + +/*! \cond */ +static char *mac_addr = NULL; +MODULE_PARAM(mac_addr, charp, 0); +MODULE_PARM_DESC(mac_addr, +"Ethernet MAC address (default 02:10:18:xx:xx:xx)"); +/*! \endcond */ + +/*! \cond */ +static int default_mtu = 1500; +MODULE_PARAM(default_mtu, int, 0); +MODULE_PARM_DESC(default_mtu, +"Default MTU for NGKNET network interfaces (default 1500)"); +/*! \endcond */ + +/*! \cond */ +static int rx_buffer_size = RX_BUF_SIZE_DFLT; +MODULE_PARAM(rx_buffer_size, int, 0); +MODULE_PARM_DESC(rx_buffer_size, +"Default size of RX packet buffers (default 9216)"); +/*! \endcond */ + +/*! \cond */ +static int rx_rate_limit = -1; +MODULE_PARAM(rx_rate_limit, int, 0); +MODULE_PARM_DESC(rx_rate_limit, +"Rx rate limit (pps, default -1 no limit)"); +/*! \endcond */ + +/*! \cond */ +static int tx_polling = 0; +MODULE_PARAM(tx_polling, int, 0); +MODULE_PARM_DESC(tx_polling, +"Tx polling mode (default 0 in interrupt mode)"); +/*! \endcond */ + +/*! \cond */ +static int rx_batching = 0; +MODULE_PARAM(rx_batching, int, 0); +MODULE_PARM_DESC(rx_batching, +"Rx batching mode (default 0 in single fill mode)"); +/*! \endcond */ + +typedef int (*drv_ops_attach)(struct pdma_dev *dev); + +struct bcmcnet_drv_ops { + const char *drv_desc; + drv_ops_attach drv_attach; + drv_ops_attach drv_detach; +}; + +#define BCMDRD_DEVLIST_ENTRY(_nm,_vn,_dv,_rv,_md,_pi,_bd,_bc,_fn,_cn,_pf,_pd,_r0,_r1) \ + static struct bcmcnet_drv_ops _bd##_cnet_drv_ops = { \ + #_bd, \ + _bd##_cnet_pdma_attach, \ + _bd##_cnet_pdma_detach, \ + }; +#include + +#define BCMDRD_DEVLIST_ENTRY(_nm,_vn,_dv,_rv,_md,_pi,_bd,_bc,_fn,_cn,_pf,_pd,_r0,_r1) \ + &_bd##_cnet_drv_ops, +static struct bcmcnet_drv_ops *drv_ops[] = { + NULL, +#include + NULL +}; +static int drv_num = sizeof(drv_ops) / sizeof(drv_ops[0]); + +struct ngknet_dev ngknet_devices[NUM_PDMA_DEV_MAX]; + +/* Default random MAC address has Broadcom OUI with local admin bit set */ +static uint8_t ngknet_dev_mac[6] = {0x02, 0x10, 0x18, 0x00, 0x00, 0x00}; + +/* Interrupt handles */ +struct ngknet_intr_handle { + struct napi_struct napi; + struct intr_handle *hdl; + int napi_resched; + int napi_pending; +}; + +static struct ngknet_intr_handle priv_hdl[NUM_PDMA_DEV_MAX][NUM_QUE_MAX]; + +/*! + * Dump packet content for debug + */ +static void +ngknet_pkt_dump(uint8_t *data, int len) +{ + char str[128]; + int i; + + len = len > 256 ? 256 : len; + + for (i = 0; i < len; i++) { + if ((i & 0x1f) == 0) { + sprintf(str, "%04x: ", i); + } + sprintf(&str[strlen(str)], "%02x", data[i]); + if ((i & 0x1f) == 0x1f) { + sprintf(&str[strlen(str)], "\n"); + printk(str); + continue; + } + if ((i & 0x3) == 0x3) { + sprintf(&str[strlen(str)], " "); + } + } + if ((i & 0x1f) != 0) { + sprintf(&str[strlen(str)], "\n"); + printk(str); + } + printk("\n"); +} + +/*! + * Rx packets rate test for debug + */ +static void +ngknet_pkt_stats(struct pdma_dev *pdev, int dir) +{ + static struct timeval tv0[2], tv1[2]; + static uint32_t pkts[2] = {0}, prts[2] = {0}; + static uint64_t intrs = 0; + + if (pkts[dir] == 0) { + kal_time_val_get(&tv0[dir]); + intrs = pdev->stats.intrs; + } + if (++pkts[dir] >= 100000) { + uint32_t iv_time; + uint32_t pps; + kal_time_val_get(&tv1[dir]); + iv_time = (tv1[dir].tv_sec - tv0[dir].tv_sec) * 1000000 + + (tv1[dir].tv_usec - tv0[dir].tv_usec); + pps = 100000 * 1000 / (iv_time / 1000); + prts[dir]++; + if (pps <= 100000 || prts[dir] * 100000 >= pps) { + printk(KERN_CRIT "%s -- limit: %d pps, 100K pkts time: %d usec, rate: %d pps, intrs: %llu\n", + dir == PDMA_Q_RX ? "Rx" : "Tx", + dir == PDMA_Q_RX ? rx_rate_limit : -1, + iv_time, pps, pdev->stats.intrs - intrs); + prts[dir] = 0; + } + pkts[dir] = 0; + } +} + +/*! + * Read 32-bit register callback + */ +static int +ngknet_dev_read32(struct pdma_dev *dev, uint32_t addr, uint32_t *data) +{ + *data = ngbde_kapi_pio_read32(dev->unit, addr); + + return 0; +} + +/*! + * Write 32-bit register callback + */ +static int +ngknet_dev_write32(struct pdma_dev *dev, uint32_t addr, uint32_t data) +{ + ngbde_kapi_pio_write32(dev->unit, addr, data); + + return 0; +} + +/*! + * Set Rx HW timestamping. + */ +static int +ngknet_ptp_rx_hwts_set(struct net_device *ndev, struct sk_buff *skb) +{ + struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb); + uint64_t ts = 0; + int rv; + + rv = ngknet_ptp_rx_hwts_get(ndev, skb, &ts); + if (SHR_FAILURE(rv) || !ts) { + return SHR_E_FAIL; + } + + memset(shhwtstamps, 0, sizeof(*shhwtstamps)); + shhwtstamps->hwtstamp = ns_to_ktime(ts); + + return SHR_E_NONE; +} + +/*! + * \brief Process Rx packet. + * + * Add RCPU encapsulation or strip matadata if needed + * + * \param [in] ndev Network device structure point. + * \param [in] oskb Rx packet SKB. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +static int +ngknet_rx_frame_process(struct net_device *ndev, struct sk_buff **oskb) +{ + struct ngknet_private *priv = netdev_priv(ndev); + struct ngknet_dev *dev = priv->bkn_dev; + struct sk_buff *skb = *oskb; + struct ngknet_rcpu_hdr *rch = (struct ngknet_rcpu_hdr *)skb->data; + struct pkt_hdr *pkh = (struct pkt_hdr *)skb->data; + uint8_t meta_len = pkh->meta_len; + + /* Do Rx timestamping */ + if (priv->hwts_rx_filter) { + ngknet_ptp_rx_hwts_set(ndev, skb); + } + + /* Remove FCS from packet length */ + skb_trim(skb, skb->len - ETH_FCS_LEN); + pkh->data_len -= ETH_FCS_LEN; + + if (priv->flags & NGKNET_NETIF_F_RCPU_ENCAP) { + /* Set up RCPU header */ + memcpy(skb->data, skb->data + PKT_HDR_SIZE + meta_len, 2 * ETH_ALEN); + if (*(uint32_t *)&dev->rcpu_ctrl.dst_mac[0] != 0 || + *(uint16_t *)&dev->rcpu_ctrl.dst_mac[4] != 0) { + memcpy(rch->dst_mac, dev->rcpu_ctrl.dst_mac, ETH_ALEN); + } + if (*(uint32_t *)&dev->rcpu_ctrl.src_mac[0] != 0 || + *(uint16_t *)&dev->rcpu_ctrl.src_mac[4] != 0) { + memcpy(rch->src_mac, dev->rcpu_ctrl.src_mac, ETH_ALEN); + } + rch->vlan_tpid = htons(dev->rcpu_ctrl.vlan_tpid); + rch->vlan_tci = htons(dev->rcpu_ctrl.vlan_tci); + rch->eth_type = htons(dev->rcpu_ctrl.eth_type); + rch->pkt_sig = htons(dev->rcpu_ctrl.pkt_sig); + rch->op_code = RCPU_OPCODE_RX; + rch->flags = RCPU_FLAG_MODHDR; + rch->trans_id = htons(dev->rcpu_ctrl.trans_id); + rch->data_len = htons(pkh->data_len); + } else { + /* Remove packet header and meta data */ + skb_pull(skb, PKT_HDR_SIZE + meta_len); + } + + /* Optional callback handle */ + if (dev->cbc->rx_cb) { + struct ngknet_callback_desc *cbd = NGKNET_SKB_CB(skb); + cbd->dev_no = dev->dev_no; + cbd->dev_id = dev->pdma_dev.dev_id; + cbd->type_str = drv_ops[dev->pdma_dev.dev_type]->drv_desc; + cbd->priv = priv; + if (priv->flags & NGKNET_NETIF_F_RCPU_ENCAP) { + cbd->pmd = skb->data + PKT_HDR_SIZE; + cbd->pkt_len = ntohs(rch->data_len); + } else { + cbd->pmd = skb->data - meta_len; + cbd->pkt_len = pkh->data_len; + } + cbd->pmd_len = meta_len; + skb = dev->cbc->rx_cb(skb); + if (!skb) { + *oskb = NULL; + return SHR_E_UNAVAIL; + } + if (priv->flags & NGKNET_NETIF_F_RCPU_ENCAP) { + rch = (struct ngknet_rcpu_hdr *)skb->data; + rch->data_len = htons(skb->len - PKT_HDR_SIZE - meta_len); + } + } + + /* Update SKB pointer */ + *oskb = skb; + + return SHR_E_NONE; +} + +/*! + * \brief Network interface Rx function. + * + * After processing the packet, send it up to network stack. + * + * \param [in] ndev Network device structure point. + * \param [in] skb Rx packet SKB. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +static int +ngknet_netif_recv(struct net_device *ndev, struct sk_buff *skb) +{ + struct ngknet_private *priv = netdev_priv(ndev); + struct ngknet_dev *dev = priv->bkn_dev; + struct pdma_dev *pdev = &dev->pdma_dev; + struct pkt_hdr *pkh = (struct pkt_hdr *)skb->data; + struct napi_struct *napi = NULL; + uint16_t proto; + int chan, gi, qi; + int rv; + + /* Handle one incoming packet */ + rv = ngknet_rx_frame_process(ndev, &skb); + if (SHR_FAILURE(rv)) { + if (!skb) { + return SHR_E_NONE; + } + } + + DBG_VERB(("Rx packet sent up to ndev%d (%d bytes).\n", priv->id, skb->len)); + if (debug & DBG_LVL_PDMP) { + ngknet_pkt_dump(skb->data, skb->len); + } + + if (ndev->features & NETIF_F_RXCSUM) { + if ((pkh->attrs & (PDMA_RX_TU_CSUM | PDMA_RX_IP_CSUM)) == + (PDMA_RX_TU_CSUM | PDMA_RX_IP_CSUM)) { + skb->ip_summed = CHECKSUM_UNNECESSARY; + } else { + skb_checksum_none_assert(skb); + } + } + + if (!(priv->flags & NGKNET_NETIF_F_RCPU_ENCAP) && + ndev->features & NETIF_F_HW_VLAN_CTAG_RX && + pkh->attrs & PDMA_RX_STRIP_TAG) { + kal_vlan_hwaccel_put_tag(skb, ETH_P_8021Q, priv->vlan); + } + + proto = eth_type_trans(skb, ndev); + if (priv->flags & NGKNET_NETIF_F_RCPU_ENCAP) { + skb->protocol = htons(dev->rcpu_ctrl.eth_type); + } else if (!(pkh->attrs & PDMA_RX_SET_PROTO) || !skb->protocol) { + skb->protocol = proto; + } + + skb_record_rx_queue(skb, pkh->queue_id); + + bcmcnet_pdma_dev_queue_to_chan(pdev, pkh->queue_id, PDMA_Q_RX, &chan); + gi = chan / pdev->grp_queues; + if (pdev->flags & PDMA_GROUP_INTR) { + napi = (struct napi_struct *)pdev->ctrl.grp[gi].intr_hdl[0].priv; + } else { + qi = pkh->queue_id; + napi = (struct napi_struct *)pdev->ctrl.grp[gi].intr_hdl[qi].priv; + } + napi_gro_receive(napi, skb); + + /* Update accounting */ + priv->stats.rx_packets++; + priv->stats.rx_bytes += skb->len; + + /* Rate limit */ + if (rx_rate_limit >= 0) { + if (!ngknet_rx_rate_limit_started()) { + ngknet_rx_rate_limit_start(dev); + } + ngknet_rx_rate_limit(dev, rx_rate_limit); + } + + return SHR_E_NONE; +} + +/*! + * \brief Driver Rx callback. + * + * After processing the packet, send it up to network stack. + * + * \param [in] pdev Packet DMA device structure point. + * \param [in] buf Raw Rx buffer. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +static int +ngknet_frame_recv(struct pdma_dev *pdev, int queue, void *buf) +{ + struct ngknet_dev *dev = (struct ngknet_dev *)pdev->priv; + struct sk_buff *skb = (struct sk_buff *)buf, *mskb = NULL; + struct net_device *ndev = NULL, *mndev = NULL; + struct ngknet_private *priv = NULL; + unsigned long flags; + int rv; + + DBG_VERB(("Rx packet (%d bytes).\n", skb->len)); + if (debug & DBG_LVL_PDMP) { + ngknet_pkt_dump(skb->data, skb->len); + } + + /* Go through the filters */ + rv = ngknet_rx_pkt_filter(dev, skb, &ndev, &mndev, &mskb); + if (SHR_FAILURE(rv) || !ndev) { + return SHR_E_FAIL; + } + + /* Populate header, checksum status, VLAN, and protocol */ + priv = netdev_priv(ndev); + if (netif_carrier_ok(ndev)) { + ngknet_netif_recv(ndev, skb); + } else { + priv->stats.rx_dropped++; + rv = SHR_E_UNAVAIL; + } + + spin_lock_irqsave(&dev->lock, flags); + priv->users--; + if (!priv->users && priv->wait) { + wake_up(&dev->wq); + } + spin_unlock_irqrestore(&dev->lock, flags); + + /* Handle mirrored packet */ + if (mndev && mskb) { + priv = netdev_priv(mndev); + if (netif_carrier_ok(mndev)) { + ngknet_netif_recv(mndev, mskb); + } else { + priv->stats.rx_dropped++; + dev_kfree_skb_any(mskb); + } + spin_lock_irqsave(&dev->lock, flags); + priv->users--; + if (!priv->users && priv->wait) { + wake_up(&dev->wq); + } + spin_unlock_irqrestore(&dev->lock, flags); + } + + /* Measure speed */ + if (debug & DBG_LVL_RATE) { + ngknet_pkt_stats(pdev, PDMA_Q_RX); + } + + return rv; +} + +/*! + * Set Tx HW timestamping. + */ +static int +ngknet_ptp_tx_hwts_set(struct net_device *ndev, struct sk_buff *skb) +{ + struct skb_shared_hwtstamps shhwtstamps; + uint64_t ts = 0; + int rv; + + rv = ngknet_ptp_tx_hwts_get(ndev, skb, &ts); + if (SHR_FAILURE(rv) || !ts) { + return SHR_E_FAIL; + } + + memset(&shhwtstamps, 0, sizeof(shhwtstamps)); + shhwtstamps.hwtstamp = ns_to_ktime(ts); + skb_tstamp_tx(skb, &shhwtstamps); + + return SHR_E_NONE; +} + +/*! + * PTP Tx worker. + */ +static void +ngknet_ptp_tx_work(struct work_struct *work) +{ + struct ngknet_dev *dev = container_of(work, struct ngknet_dev, ptp_tx_work); + struct sk_buff *skb; + int rv; + + while (skb_queue_len(&dev->ptp_tx_queue)) { + skb = skb_dequeue(&dev->ptp_tx_queue); + rv = ngknet_ptp_tx_hwts_set(dev->net_dev, skb); + if (SHR_FAILURE(rv)) { + printk("Timestamp value has not been set for current skb.\n"); + } + dev_kfree_skb_any(skb); + } +} + +/*! + * Config Tx metadata for HW timestamping. + */ +static int +ngknet_ptp_tx_config(struct net_device *ndev, struct sk_buff *skb) +{ + struct ngknet_private *priv = netdev_priv(ndev); + struct ngknet_dev *dev = priv->bkn_dev; + int rv; + + if (priv->type == NGKNET_NETIF_T_PORT) { + rv = ngknet_ptp_tx_meta_set(ndev, skb); + if (SHR_FAILURE(rv)) { + return rv; + } + } else if (priv->hwts_tx_type != HWTSTAMP_TX_ONESTEP_SYNC) { + return SHR_E_UNAVAIL; + } + + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; + + if (priv->hwts_tx_type == HWTSTAMP_TX_ONESTEP_SYNC) { + skb_queue_tail(&dev->ptp_tx_queue, skb_get(skb)); + schedule_work(&dev->ptp_tx_work); + } + + return SHR_E_NONE; +} + +/*! + * \brief Process Tx packet. + * + * Strip RCPU encapsulation, setup CNET packet buffer, add vlan tag + * or pad the packet. + * + * \param [in] ndev Network device structure point. + * \param [in] oskb Tx packet SKB. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +static int +ngknet_tx_frame_process(struct net_device *ndev, struct sk_buff **oskb) +{ + struct ngknet_private *priv = netdev_priv(ndev); + struct ngknet_dev *dev = priv->bkn_dev; + struct sk_buff *skb = *oskb; + struct ngknet_rcpu_hdr *rch = (struct ngknet_rcpu_hdr *)skb->data; + struct pkt_hdr *pkh = (struct pkt_hdr *)skb->data; + struct sk_buff *nskb = NULL; + char *data = NULL; + uint32_t copy_len, meta_len, data_len, pkt_len, tag_len; + uint16_t tpid; + + /* Set up packet header */ + if (priv->flags & NGKNET_NETIF_F_RCPU_ENCAP) { + /* RCPU encapsulation packet */ + data_len = pkh->attrs & PDMA_TX_HDR_COOKED ? + pkh->data_len - ETH_FCS_LEN : ntohs(rch->data_len); + pkt_len = PKT_HDR_SIZE + rch->meta_len + data_len; + if (skb->len != pkt_len || skb->len < (PKT_HDR_SIZE + 14)) { + DBG_WARN(("Tx drop: Invalid RCPU encapsulation\n")); + return SHR_E_FAIL; + } + if (dev->rcpu_ctrl.pkt_sig && dev->rcpu_ctrl.pkt_sig != ntohs(rch->pkt_sig)) { + DBG_WARN(("Tx drop: Invalid RCPU signature\n")); + return SHR_E_FAIL; + } + if (pkh->attrs & PDMA_TX_HDR_COOKED) { + /* Resumed packet */ + return SHR_E_NONE; + } + pkh->data_len = data_len + ETH_FCS_LEN; + pkh->meta_len = rch->meta_len; + pkh->attrs = 0; + if (rch->flags & RCPU_FLAG_MODHDR) { + pkh->attrs |= PDMA_TX_HIGIG_PKT; + } + if (rch->flags & RCPU_FLAG_PAUSE) { + pkh->attrs |= PDMA_TX_PAUSE_PKT; + } + if (rch->flags & RCPU_FLAG_PURGE) { + pkh->attrs |= PDMA_TX_PURGE_PKT; + } + if (rch->flags & RCPU_FLAG_BIND_QUE) { + pkh->attrs |= PDMA_TX_BIND_QUE; + } + } else { + /* Non-RCPU encapsulation packet */ + data_len = pkh->data_len - ETH_FCS_LEN; + pkt_len = PKT_HDR_SIZE + pkh->meta_len + data_len; + if (skb->len == pkt_len && pkh->attrs & PDMA_TX_HDR_COOKED && + pkh->pkt_sig == dev->rcpu_ctrl.pkt_sig) { + /* Resumed packet */ + return SHR_E_NONE; + } + meta_len = 0; + if (priv->type == NGKNET_NETIF_T_PORT) { + meta_len = priv->meta_len; + if (!meta_len) { + printk("Tx abort: no metadata\n"); + return SHR_E_UNAVAIL; + } + } + if (skb_header_cloned(skb) || + skb_headroom(skb) < (PKT_HDR_SIZE + meta_len + VLAN_HLEN) || + skb_tailroom(skb) < ETH_FCS_LEN) { + nskb = skb_copy_expand(skb, PKT_HDR_SIZE + meta_len + VLAN_HLEN, + ETH_FCS_LEN, GFP_ATOMIC); + if (!nskb) { + return SHR_E_MEMORY; + } + skb_shinfo(nskb)->tx_flags = skb_shinfo(skb)->tx_flags; + skb = nskb; + } + skb_push(skb, PKT_HDR_SIZE + meta_len); + memset(skb->data, 0, PKT_HDR_SIZE + meta_len); + pkh = (struct pkt_hdr *)skb->data; + pkh->data_len = skb->len - PKT_HDR_SIZE - meta_len + ETH_FCS_LEN; + pkh->meta_len = meta_len; + pkh->attrs = 0; + if (priv->type == NGKNET_NETIF_T_PORT) { + /* Send to physical port using netif metadata */ + if (priv->meta_off) { + memmove(skb->data + PKT_HDR_SIZE, skb->data + PKT_HDR_SIZE + meta_len, priv->meta_off); + } + memcpy(skb->data + PKT_HDR_SIZE + priv->meta_off, priv->meta_data, priv->meta_len); + pkh->attrs |= PDMA_TX_HIGIG_PKT; + } + pkh->pkt_sig = dev->rcpu_ctrl.pkt_sig; + } + + /* Packet header done here */ + pkh->attrs |= PDMA_TX_HDR_COOKED; + + data = skb->data + PKT_HDR_SIZE + pkh->meta_len; + tpid = data[12] << 8 | data[13]; + tag_len = (tpid == ETH_P_8021Q || tpid == ETH_P_8021AD) ? VLAN_HLEN : 0; + + /* Need to add VLAN tag if packet is untagged */ + if (!tag_len && (!(pkh->attrs & PDMA_TX_HIGIG_PKT) || priv->flags & NGKNET_NETIF_F_ADD_TAG)) { + copy_len = PKT_HDR_SIZE + pkh->meta_len + 2 * ETH_ALEN; + if (skb_header_cloned(skb) || skb_headroom(skb) < VLAN_HLEN) { + nskb = skb_copy_expand(skb, VLAN_HLEN, 0, GFP_ATOMIC); + if (!nskb) { + return SHR_E_MEMORY; + } + skb_shinfo(nskb)->tx_flags = skb_shinfo(skb)->tx_flags; + skb = nskb; + } + skb_push(skb, VLAN_HLEN); + memmove(skb->data, skb->data + VLAN_HLEN, copy_len); + pkh = (struct pkt_hdr *)skb->data; + data = skb->data + PKT_HDR_SIZE + pkh->meta_len; + data[12] = 0x81; + data[13] = 0x00; + data[14] = priv->vlan >> 8 & 0xf; + data[15] = priv->vlan & 0xff; + pkh->data_len += VLAN_HLEN; + tag_len = VLAN_HLEN; + } + + /* Optional callback handle */ + if (dev->cbc->tx_cb) { + struct ngknet_callback_desc *cbd = NGKNET_SKB_CB(skb); + cbd->dev_no = dev->dev_no; + cbd->dev_id = dev->pdma_dev.dev_id; + cbd->type_str = drv_ops[dev->pdma_dev.dev_type]->drv_desc; + cbd->priv = priv; + cbd->pmd = skb->data + PKT_HDR_SIZE; + cbd->pmd_len = pkh->meta_len; + cbd->pkt_len = skb->len - PKT_HDR_SIZE - pkh->meta_len; + skb = dev->cbc->tx_cb(skb); + if (!skb) { + if (!nskb) { + *oskb = NULL; + } + return SHR_E_UNAVAIL; + } + pkh = (struct pkt_hdr *)skb->data; + pkh->data_len = skb->len - PKT_HDR_SIZE - pkh->meta_len + ETH_FCS_LEN; + } + + /* Pad packet if needed */ + if (pkh->data_len < (64 + tag_len)) { + pkh->data_len = 64 + tag_len; + if (skb_padto(skb, PKT_HDR_SIZE + pkh->meta_len + pkh->data_len - ETH_FCS_LEN)) { + if (!nskb) { + *oskb = NULL; + } + return SHR_E_MEMORY; + } + } + + /* Update SKB pointer */ + *oskb = skb; + + return SHR_E_NONE; +} + +/*! + * Suspend Tx queue callback + */ +static void +ngknet_tx_suspend(struct pdma_dev *pdev, int queue) +{ + struct ngknet_dev *dev = (struct ngknet_dev *)pdev->priv; + unsigned long flags; + int vdi; + + netif_stop_subqueue(dev->net_dev, queue); + + spin_lock_irqsave(&dev->lock, flags); + for (vdi = 1; vdi <= NUM_VDEV_MAX; vdi++) { + if (!dev->vdev[vdi]) { + continue; + } + netif_stop_subqueue(dev->vdev[vdi], queue); + } + spin_unlock_irqrestore(&dev->lock, flags); +} + +/*! + * Resume Tx queue callback + */ +static void +ngknet_tx_resume(struct pdma_dev *pdev, int queue) +{ + struct ngknet_dev *dev = (struct ngknet_dev *)pdev->priv; + unsigned long flags; + int vdi; + + if (__netif_subqueue_stopped(dev->net_dev, queue)) { + netif_wake_subqueue(dev->net_dev, queue); + } + + spin_lock_irqsave(&dev->lock, flags); + for (vdi = 1; vdi <= NUM_VDEV_MAX; vdi++) { + if (!dev->vdev[vdi]) { + continue; + } + if (__netif_subqueue_stopped(dev->vdev[vdi], queue)) { + netif_wake_subqueue(dev->vdev[vdi], queue); + } + } + spin_unlock_irqrestore(&dev->lock, flags); + + if (pdev->mode == DEV_MODE_HNET) { + atomic_set(&dev->hnet_active, 1); + wake_up_interruptible(&dev->hnet_wq); + } +} + +/*! + * Enable interrupt callback + */ +static void +ngknet_intr_enable(struct pdma_dev *pdev, int cmc, int chan, + uint32_t reg, uint32_t mask) +{ + pdev->ctrl.grp[cmc].irq_mask |= mask; + ngbde_kapi_intr_mask_write(pdev->unit, 0, reg, pdev->ctrl.grp[cmc].irq_mask); +} + +/*! + * Disable interrupt callback + */ +static void +ngknet_intr_disable(struct pdma_dev *pdev, int cmc, int chan, + uint32_t reg, uint32_t mask) +{ + pdev->ctrl.grp[cmc].irq_mask &= ~mask; + ngbde_kapi_intr_mask_write(pdev->unit, 0, reg, pdev->ctrl.grp[cmc].irq_mask); +} + +/*! + * NAPI polling function + */ +static int +ngknet_poll(struct napi_struct *napi, int budget) +{ + struct ngknet_intr_handle *kih = (struct ngknet_intr_handle *)napi; + struct intr_handle *hdl = kih->hdl; + struct pdma_dev *pdev = (struct pdma_dev *)hdl->dev; + struct ngknet_dev *dev = (struct ngknet_dev *)pdev->priv; + unsigned long flags; + int work_done; + + DBG_NAPI(("Scheduled NAPI on queue %d.\n", hdl->queue)); + + kih->napi_resched = 0; + kih->napi_pending = 0; + + if (pdev->flags & PDMA_GROUP_INTR) { + work_done = bcmcnet_group_poll(pdev, hdl->group, budget); + } else { + work_done = bcmcnet_queue_poll(pdev, hdl, budget); + } + + if (work_done < budget) { + napi_complete(napi); + if (kih->napi_pending && napi_schedule_prep(napi)) { + __napi_schedule(napi); + return work_done; + } + spin_lock_irqsave(&dev->lock, flags); + if (!kih->napi_resched) { + if (pdev->flags & PDMA_GROUP_INTR) { + bcmcnet_group_intr_enable(pdev, hdl->group); + } else { + bcmcnet_queue_intr_enable(pdev, hdl); + } + } + spin_unlock_irqrestore(&dev->lock, flags); + } + + return work_done; +} + +/*! + * NGKNET ISR + */ +static int +ngknet_isr(void *isr_data) +{ + struct ngknet_dev *dev = isr_data; + struct pdma_dev *pdev = &dev->pdma_dev; + struct intr_handle *hdl = NULL; + struct napi_struct *napi = NULL; + unsigned long flags; + int gi, qi; + int iv = 0; + + for (gi = 0; gi < pdev->num_groups; gi++) { + if (!pdev->ctrl.grp[gi].attached) { + continue; + } + for (qi = 0; qi < pdev->grp_queues; qi++) { + hdl = &pdev->ctrl.grp[gi].intr_hdl[qi]; + if (pdev->flags & PDMA_GROUP_INTR) { + if (!bcmcnet_group_intr_check(pdev, gi)) { + break; + } + } else { + if (!bcmcnet_queue_intr_check(pdev, hdl)) { + continue; + } + } + spin_lock_irqsave(&dev->lock, flags); + if (pdev->flags & PDMA_GROUP_INTR) { + bcmcnet_group_intr_disable(pdev, gi); + } else { + bcmcnet_queue_intr_disable(pdev, hdl); + } + spin_unlock_irqrestore(&dev->lock, flags); + napi = (struct napi_struct *)hdl->priv; + if (likely(napi_schedule_prep(napi))) { + __napi_schedule(napi); + } + iv++; + if (pdev->flags & PDMA_GROUP_INTR) { + break; + } + } + } + + if (iv) { + DBG_IRQ(("Got interrupt on device %d.\n", dev->dev_no)); + pdev->stats.intrs++; + return IRQ_HANDLED; + } else { + return IRQ_NONE; + } +} + +/*! + * Hypervisor network work handler + */ +static void +ngknet_dev_hnet_work(struct pdma_dev *pdev) +{ + struct ngknet_dev *dev = (struct ngknet_dev *)pdev->priv; + struct intr_handle *hdl = NULL; + struct napi_struct *napi = NULL; + struct ngknet_intr_handle *kih = NULL; + unsigned long flags; + int gi, qi; + + for (gi = 0; gi < pdev->num_groups; gi++) { + if (!pdev->ctrl.grp[gi].attached) { + continue; + } + for (qi = 0; qi < pdev->grp_queues; qi++) { + hdl = &pdev->ctrl.grp[gi].intr_hdl[qi]; + napi = (struct napi_struct *)hdl->priv; + kih = (struct ngknet_intr_handle *)napi; + kih->napi_pending = 1; + if (napi_schedule_prep(napi)) { + spin_lock_irqsave(&dev->lock, flags); + kih->napi_resched = 1; + spin_unlock_irqrestore(&dev->lock, flags); + local_bh_disable(); + __napi_schedule(napi); + local_bh_enable(); + } + if (pdev->flags & PDMA_GROUP_INTR) { + break; + } + } + } +} + +/*! + * Hypervisor network wait handler + */ +static int +ngknet_dev_hnet_wait(struct pdma_dev *pdev) +{ + struct ngknet_dev *dev = (struct ngknet_dev *)pdev->priv; + int qi; + int rv; + + while (!kthread_should_stop()) { + wait_event_interruptible(dev->hnet_wq, + atomic_read(&dev->hnet_active) != 0); + if (!(dev->flags & NGKNET_DEV_ACTIVE)) { + schedule_timeout(HZ); + continue; + } + atomic_set(&dev->hnet_active, 0); + for (qi = 0; qi < pdev->ctrl.nb_txq; qi++) { + do { + rv = pdev->pkt_xmit(pdev, qi, 0); + } while (rv == SHR_E_NONE); + } + schedule_work(&dev->hnet_work); + } + + return 0; +} + +/*! + * Hypervisor network wake handler + */ +static int +ngknet_dev_vnet_wake(struct pdma_dev *pdev) +{ + struct ngknet_dev *dev = (struct ngknet_dev *)pdev->priv; + + atomic_set(&dev->vnet_active, 1); + wake_up_interruptible(&dev->vnet_wq); + + return SHR_E_NONE; +} + +/*! + * Hypervisor network process + */ +static int +ngknet_dev_hnet_process(void *data) +{ + return ngknet_dev_hnet_wait((struct pdma_dev *)data); +} + +/*! + * Hypervisor network schedule + */ +static void +ngknet_dev_hnet_schedule(struct work_struct *work) +{ + struct ngknet_dev *dev = container_of(work, struct ngknet_dev, hnet_work); + + ngknet_dev_hnet_work(&dev->pdma_dev); +} + +/*! + * Convert physical address to virtual address + */ +static void * +ngknet_sys_p2v(struct pdma_dev *pdev, uint64_t paddr) +{ + return ngbde_kapi_dma_bus_to_virt(pdev->unit, (dma_addr_t)paddr); +} + +/*! + * Convert virtual address to physical address + */ +static uint64_t +ngknet_sys_v2p(struct pdma_dev *pdev, void *vaddr) +{ + return (uint64_t)ngbde_kapi_dma_virt_to_bus(pdev->unit, vaddr); +} + +/*! + * Open network device + */ +static int +ngknet_enet_open(struct net_device *ndev) +{ + struct ngknet_private *priv = netdev_priv(ndev); + struct ngknet_dev *dev = priv->bkn_dev; + struct pdma_dev *pdev = &dev->pdma_dev; + struct napi_struct *napi = NULL; + unsigned long bm_queue; + int gi, qi; + int rv; + + if (!pdev->ctrl.bm_rxq || !pdev->ctrl.bm_txq) { + printk("Not config Rx or Tx queue yet!\n"); + return -EPERM; + } + + if (priv->id <= 0) { + /* Register interrupt handler */ + ngbde_kapi_intr_connect(dev->dev_no, 0, ngknet_isr, dev); + + /* Start PDMA device */ + rv = bcmcnet_pdma_dev_start(pdev); + if (SHR_FAILURE(rv)) { + ngbde_kapi_intr_disconnect(dev->dev_no, 0); + return -EPERM; + } + + /* Start rate limit */ + if (rx_rate_limit >= 0) { + ngknet_rx_rate_limit_start(dev); + } + + /* Notify the stack of the actual queue counts. */ + rv = netif_set_real_num_rx_queues(dev->net_dev, pdev->ctrl.nb_rxq); + if (rv < 0) { + ngbde_kapi_intr_disconnect(dev->dev_no, 0); + return rv; + } + rv = netif_set_real_num_tx_queues(dev->net_dev, pdev->ctrl.nb_txq); + if (rv < 0) { + ngbde_kapi_intr_disconnect(dev->dev_no, 0); + return rv; + } + + for (gi = 0; gi < pdev->num_groups; gi++) { + if (!pdev->ctrl.grp[gi].attached) { + continue; + } + bm_queue = pdev->ctrl.grp[gi].bm_rxq | pdev->ctrl.grp[gi].bm_txq; + for (qi = 0; qi < pdev->grp_queues; qi++) { + napi = (struct napi_struct *)pdev->ctrl.grp[gi].intr_hdl[qi].priv; + if (pdev->flags & PDMA_GROUP_INTR) { + napi_enable(napi); + break; + } + if (1 << qi & bm_queue) { + napi_enable(napi); + } + } + } + } else { + /* Notify the stack of the actual queue counts. */ + rv = netif_set_real_num_rx_queues(ndev, pdev->ctrl.nb_rxq); + if (rv < 0) { + return rv; + } + rv = netif_set_real_num_tx_queues(ndev, pdev->ctrl.nb_txq); + if (rv < 0) { + return rv; + } + } + + /* Prevent tx timeout */ + kal_netif_trans_update(ndev); + + netif_tx_wake_all_queues(ndev); + + return 0; +} + +/*! + * Stop network device + */ +static int +ngknet_enet_stop(struct net_device *ndev) +{ + struct ngknet_private *priv = netdev_priv(ndev); + struct ngknet_dev *dev = priv->bkn_dev; + struct pdma_dev *pdev = &dev->pdma_dev; + struct napi_struct *napi = NULL; + unsigned long bm_queue; + int gi, qi; + + netif_tx_stop_all_queues(ndev); + + if (priv->id <= 0) { + /* Stop rate limit */ + if (rx_rate_limit >= 0) { + ngknet_rx_rate_limit_stop(dev); + } + + /* Suspend PDMA device */ + bcmcnet_pdma_dev_suspend(pdev); + + for (gi = 0; gi < pdev->num_groups; gi++) { + if (!pdev->ctrl.grp[gi].attached) { + continue; + } + bm_queue = pdev->ctrl.grp[gi].bm_rxq | pdev->ctrl.grp[gi].bm_txq; + for (qi = 0; qi < pdev->grp_queues; qi++) { + napi = (struct napi_struct *)pdev->ctrl.grp[gi].intr_hdl[qi].priv; + if (pdev->flags & PDMA_GROUP_INTR) { + napi_disable(napi); + break; + } + if (1 << qi & bm_queue) { + napi_disable(napi); + } + } + } + + /* Stop PDMA device */ + bcmcnet_pdma_dev_stop(pdev); + + /* Unregister interrupt handler */ + ngbde_kapi_intr_disconnect(dev->dev_no, 0); + } + + return 0; +} + +/*! + * Start transmission + */ +static int +ngknet_start_xmit(struct sk_buff *skb, struct net_device *ndev) +{ + struct ngknet_private *priv = netdev_priv(ndev); + struct ngknet_dev *dev = priv->bkn_dev; + struct pdma_dev *pdev = &dev->pdma_dev; + struct sk_buff *bskb = skb; + uint32_t len = skb->len; + int queue; + int rv; + + DBG_VERB(("Tx packet from ndev%d (%d bytes).\n", priv->id, skb->len)); + if (debug & DBG_LVL_PDMP) { + ngknet_pkt_dump(skb->data, skb->len); + } + + /* Do not transmit on base device */ + if (priv->id <= 0) { + priv->stats.tx_dropped++; + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; + } + + /* Measure speed */ + if (debug & DBG_LVL_RATE) { + ngknet_pkt_stats(pdev, PDMA_Q_TX); + } + + queue = skb->queue_mapping; + + /* Handle one outgoing packet */ + rv = ngknet_tx_frame_process(ndev, &skb); + if (SHR_FAILURE(rv)) { + priv->stats.tx_dropped++; + if (skb) { + dev_kfree_skb_any(skb); + } + return NETDEV_TX_OK; + } + + /* Schedule Tx queue */ + ngknet_tx_queue_schedule(dev, skb, &queue); + skb->queue_mapping = queue; + + DBG_VERB(("Tx packet (%d bytes).\n", skb->len)); + if (debug & DBG_LVL_PDMP) { + ngknet_pkt_dump(skb->data, skb->len); + } + + /* Do Tx timestamping */ + if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) { + ngknet_ptp_tx_config(ndev, skb); + } + + skb_tx_timestamp(skb); + + rv = pdev->pkt_xmit(pdev, queue, skb); + + if (rv == SHR_E_UNAVAIL) { + DBG_WARN(("Tx drop: DMA device not ready\n")); + priv->stats.tx_dropped++; + if (skb != bskb) { + dev_kfree_skb_any(skb); + } + dev_kfree_skb_any(bskb); + return NETDEV_TX_OK; + } + + if (rv == SHR_E_BUSY) { + DBG_WARN(("Tx suspend: No DMA resources\n")); + priv->stats.tx_fifo_errors++; + if (skb != bskb) { + dev_kfree_skb_any(skb); + } + return NETDEV_TX_BUSY; + } else { + if (skb != bskb) { + dev_kfree_skb_any(bskb); + } + } + + /* Update accounting */ + priv->stats.tx_packets++; + priv->stats.tx_bytes += len; + + return NETDEV_TX_OK; +} + +/*! + * Get network device stats + */ +static struct net_device_stats * +ngknet_get_stats(struct net_device *ndev) +{ + struct ngknet_private *priv = netdev_priv(ndev); + + return &priv->stats; +} + +/*! + * Set network device MC list + */ +static void +ngknet_set_multicast_list(struct net_device *ndev) +{ + return; +} + +/*! + * Set network device MAC address + */ +static int +ngknet_set_mac_address(struct net_device *ndev, void *addr) +{ + if (!is_valid_ether_addr(((struct sockaddr *)addr)->sa_data)) { + return -EINVAL; + } + + netdev_info(ndev, "Setting new MAC address\n"); + memcpy(ndev->dev_addr, ((struct sockaddr *)addr)->sa_data, ndev->addr_len); + + return 0; +} + +/*! + * Change network device MTU + */ +static int +ngknet_change_mtu(struct net_device *ndev, int new_mtu) +{ + int frame_size = new_mtu + ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN; + + if (frame_size < 68 || frame_size > rx_buffer_size) { + return -EINVAL; + } + + netdev_info(ndev, "Changing MTU from %d to %d\n", ndev->mtu, new_mtu); + ndev->mtu = new_mtu; + + return 0; +} + +/*! + * Do I/O control + */ +static int +ngknet_do_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd) +{ + struct ngknet_private *priv = netdev_priv(ndev); + struct hwtstamp_config config; + int rv; + + if (cmd == SIOCSHWTSTAMP) { + if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) { + return -EFAULT; + } + + if (priv->type != NGKNET_NETIF_T_PORT) { + return -ENOSYS; + } + + switch (config.tx_type) { + case HWTSTAMP_TX_OFF: + priv->hwts_tx_type = HWTSTAMP_TX_OFF; + rv = ngknet_ptp_tx_config_set(ndev, priv->hwts_tx_type); + if (SHR_FAILURE(rv)) { + return -ENOSYS; + } + break; + case HWTSTAMP_TX_ON: + priv->hwts_tx_type = HWTSTAMP_TX_ON; + rv = ngknet_ptp_tx_config_set(ndev, priv->hwts_tx_type); + if (SHR_FAILURE(rv)) { + return -ENOSYS; + } + break; + case HWTSTAMP_TX_ONESTEP_SYNC: + priv->hwts_tx_type = HWTSTAMP_TX_ONESTEP_SYNC; + rv = ngknet_ptp_tx_config_set(ndev, priv->hwts_tx_type); + if (SHR_FAILURE(rv)) { + return -ENOSYS; + } + break; + default: + return -ERANGE; + } + + switch (config.rx_filter) { + case HWTSTAMP_FILTER_NONE: + rv = ngknet_ptp_rx_config_set(ndev, &config.rx_filter); + if (SHR_FAILURE(rv)) { + return -ENOSYS; + } + priv->hwts_rx_filter = HWTSTAMP_FILTER_NONE; + break; + default: + rv = ngknet_ptp_rx_config_set(ndev, &config.rx_filter); + if (SHR_FAILURE(rv)) { + return -ENOSYS; + } + priv->hwts_rx_filter = config.rx_filter; + break; + } + + return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? -EFAULT : 0; + } + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) + if (cmd == SIOCGHWTSTAMP) { + config.flags = 0; + config.tx_type = priv->hwts_tx_type; + config.rx_filter = priv->hwts_rx_filter; + + return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? -EFAULT : 0; + } +#endif + + return -EINVAL; +} + +#ifdef CONFIG_NET_POLL_CONTROLLER +/*! + * Poll network device + */ +static void +ngknet_poll_controller(struct net_device *ndev) +{ + struct ngknet_private *priv = netdev_priv(ndev); + + disable_irq(ndev->irq); + ngknet_isr(priv->bkn_dev); + enable_irq(ndev->irq); +} +#endif + +static const struct net_device_ops ngknet_netdev_ops = { + .ndo_open = ngknet_enet_open, + .ndo_stop = ngknet_enet_stop, + .ndo_start_xmit = ngknet_start_xmit, + .ndo_get_stats = ngknet_get_stats, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_rx_mode = ngknet_set_multicast_list, + .ndo_set_mac_address = ngknet_set_mac_address, + .ndo_change_mtu = ngknet_change_mtu, + .ndo_set_features = NULL, + .ndo_do_ioctl = ngknet_do_ioctl, + .ndo_tx_timeout = NULL, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = ngknet_poll_controller, +#endif +}; + +static void +ngknet_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) +{ + strlcpy(drvinfo->driver, "linux_ngknet", sizeof(drvinfo->driver)); + snprintf(drvinfo->version, sizeof(drvinfo->version), "%d", NGKNET_IOC_VERSION); + strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version)); + strlcpy(drvinfo->bus_info, "N/A", sizeof(drvinfo->bus_info)); +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)) +static int +ngknet_get_ts_info(struct net_device *ndev, struct ethtool_ts_info *info) +{ + int rv; + + info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE | + SOF_TIMESTAMPING_TX_SOFTWARE | + SOF_TIMESTAMPING_RX_HARDWARE | + SOF_TIMESTAMPING_RX_SOFTWARE | + SOF_TIMESTAMPING_SOFTWARE | + SOF_TIMESTAMPING_RAW_HARDWARE; + info->tx_types = 1 << HWTSTAMP_TX_OFF | 1 << HWTSTAMP_TX_ON | 1 << HWTSTAMP_TX_ONESTEP_SYNC; + info->rx_filters = 1 << HWTSTAMP_FILTER_NONE | 1 << HWTSTAMP_FILTER_ALL; + rv = ngknet_ptp_phc_index_get(ndev, &info->phc_index); + if (SHR_FAILURE(rv)) { + info->phc_index = -1; + } + + return 0; +} +#endif + +static const struct ethtool_ops ngknet_ethtool_ops = { + .get_drvinfo = ngknet_get_drvinfo, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)) + .get_ts_info = ngknet_get_ts_info, +#endif +}; + +/*! + * \brief Initialize network device. + * + * \param [in] name Network device name. + * \param [in] mac Network device MAC address. + * \param [out] nd New registered network device. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +static int +ngknet_ndev_init(ngknet_netif_t *netif, struct net_device **nd) +{ + struct net_device *ndev = NULL; + uint8_t *ma; + int rv; + + if (!netif) { + DBG_WARN(("Network interface is NULL.\n")); + return SHR_E_PARAM; + } + if (!nd) { + DBG_WARN(("Network device is NULL.\n")); + return SHR_E_PARAM; + } + + ndev = alloc_etherdev_mq(sizeof(struct ngknet_private), NUM_QUE_MAX); + if (!ndev) { + DBG_WARN(("Error allocating network device.\n")); + return SHR_E_MEMORY; + } + if (!ndev->dev_addr) { + DBG_WARN(("ndev->dev_addr is NULL\n")); + free_netdev(ndev); + return SHR_E_INTERNAL; + } + + /* Device information -- not available right now */ + ndev->irq = 0; + ndev->base_addr = 0; + + /* Fill in the dev structure */ + ndev->watchdog_timeo = 5 * HZ; + + /* Default MTU should not exceed MTU of switch front-panel ports */ + ndev->mtu = netif->mtu; + if (!ndev->mtu) { + ndev->mtu = default_mtu ? default_mtu : rx_buffer_size; + } + + ndev->netdev_ops = &ngknet_netdev_ops; + ndev->ethtool_ops = &ngknet_ethtool_ops; + + /* Network device name */ + if (netif->name && *netif->name) { + strncpy(ndev->name, netif->name, IFNAMSIZ - 1); + } + + /* Set the device MAC address */ + ma = netif->macaddr; + if ((ma[0] | ma[1] | ma[2] | ma[3] | ma[4] | ma[5]) == 0) { + ngknet_dev_mac[5]++; + ma = ngknet_dev_mac; + } + memcpy(ndev->dev_addr, ma, ETH_ALEN); + + /* Initialize the device features */ + ndev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM | + NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_TX; + ndev->features |= NETIF_F_HIGHDMA | NETIF_F_HW_VLAN_CTAG_RX; + + /* Register the kernel network device */ + rv = register_netdev(ndev); + if (rv < 0) { + DBG_WARN(("Error registering network device %s.\n", ndev->name)); + free_netdev(ndev); + return SHR_E_FAIL; + } + + *nd = ndev; + + DBG_VERB(("Created network device %s.\n", ndev->name)); + + return SHR_E_NONE; +} + +/*! + * \brief Initialize Packet DMA device. + * + * \param [in] dev NGKNET device structure point. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +static int +ngknet_pdev_init(struct ngknet_dev *dev) +{ + struct pdma_dev *pdev = &dev->pdma_dev; + int rv; + + /* Initialize PDMA control structure */ + pdev->unit = dev->dev_no; + pdev->priv = dev; + pdev->ctrl.dev = pdev; + pdev->ctrl.hw_addr = dev->base_addr; + pdev->ctrl.rx_buf_size = rx_buffer_size; + + /* Hook callbacks */ + pdev->dev_read32 = ngknet_dev_read32; + pdev->dev_write32 = ngknet_dev_write32; + pdev->pkt_recv = ngknet_frame_recv; + pdev->tx_suspend = ngknet_tx_suspend; + pdev->tx_resume = ngknet_tx_resume; + pdev->intr_unmask = ngknet_intr_enable; + pdev->intr_mask = ngknet_intr_disable; + pdev->xnet_wait = ngknet_dev_hnet_wait; + pdev->xnet_wake = ngknet_dev_vnet_wake; + pdev->sys_p2v = ngknet_sys_p2v; + pdev->sys_v2p = ngknet_sys_v2p; + + pdev->flags |= PDMA_GROUP_INTR; + if (tx_polling) { + pdev->flags |= PDMA_TX_POLLING; + } + if (rx_batching || pdev->mode == DEV_MODE_HNET) { + pdev->flags |= PDMA_RX_BATCHING; + } + + /* Attach PDMA driver */ + rv = drv_ops[pdev->dev_type]->drv_attach(pdev); + if (SHR_FAILURE(rv)) { + DBG_WARN(("Attach DMA driver failed.\n")); + return rv; + } + + /* Initialize PDMA device */ + rv = bcmcnet_pdma_dev_init(pdev); + if (SHR_FAILURE(rv)) { + DBG_WARN(("Init DMA device.failed.\n")); + return rv; + } + + DBG_VERB(("Attached DMA device %s.\n", pdev->name)); + + return SHR_E_NONE; +} + +/*! + * \brief Get device information from BDE. + * + * \param [in] dn Device number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +static int +ngknet_dev_info_get(int dn) +{ + struct ngknet_dev *dev = &ngknet_devices[dn]; + + dev->base_addr = ngbde_kapi_pio_membase(dn); + dev->dev = ngbde_kapi_dma_dev_get(dn); + + if (!dev->base_addr || !dev->dev) { + return SHR_E_ACCESS; + } + + dev->dev_no = dn; + + return SHR_E_NONE; +} + +/*! + * \brief Probe device. + * + * Get the information from BDE, initialize Packet DMA device, + * initialize base network device and allocate other resources. + * + * \param [in] dn Device number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +static int +ngknet_dev_probe(int dn, ngknet_netif_t *netif) +{ + struct ngknet_dev *dev = &ngknet_devices[dn]; + struct pdma_dev *pdev = &dev->pdma_dev; + struct net_device *ndev = NULL; + struct ngknet_private *priv = NULL; + struct intr_handle *hdl = NULL; + struct cpumask mask; + int gi, qi; + int rv; + + DBG_VERB(("%s: dev %d\n",__FUNCTION__, dn)); + + /* Get device information */ + rv = ngknet_dev_info_get(dn); + if (SHR_FAILURE(rv)) { + return rv; + } + + /* Initialize PDMA device */ + rv = ngknet_pdev_init(dev); + if (SHR_FAILURE(rv)) { + return rv; + } + + /* Get base network device name */ + if (netif->name[0] == '\0') { + /* Reserve 6 vacancies for base&vitual device number, i.e. nameAB_XYZ */ + if (strlen(base_dev_name) < IFNAMSIZ - 6) { + snprintf(netif->name, IFNAMSIZ, "%s%d", base_dev_name, dn); + } else { + DBG_WARN(("Too long network device name: %s.\n", base_dev_name)); + return SHR_E_PARAM; + } + } + + rv = ngknet_ndev_init(netif, &ndev); + if (SHR_FAILURE(rv)) { + bcmcnet_pdma_dev_cleanup(pdev); + return rv; + } + dev->net_dev = ndev; + + /* Initialize private information for base network device */ + priv = netdev_priv(ndev); + priv->net_dev = ndev; + priv->bkn_dev = dev; + priv->id = 0; + priv->type = netif->type; + if (priv->type == NGKNET_NETIF_T_PORT) { + priv->meta_off = netif->meta_off; + priv->meta_len = netif->meta_len; + memcpy(priv->meta_data, netif->meta_data, priv->meta_len); + } + priv->flags = netif->flags; + priv->vlan = netif->vlan; + priv->chan = netif->chan; + memcpy(priv->user_data, netif->user_data, sizeof(priv->user_data)); + + netif->id = priv->id; + memcpy(netif->macaddr, ndev->dev_addr, ETH_ALEN); + netif->mtu = ndev->mtu; + memcpy(netif->name, ndev->name, sizeof(netif->name) - 1); + + if (priv->flags & NGKNET_NETIF_F_BIND_CHAN) { + dev->bdev[priv->chan] = ndev; + } + + /* Register for napi */ + for (gi = 0; gi < pdev->num_groups; gi++) { + if (!pdev->ctrl.grp[gi].attached) { + continue; + } + for (qi = 0; qi < pdev->grp_queues; qi++) { + hdl = &pdev->ctrl.grp[gi].intr_hdl[qi]; + priv_hdl[hdl->unit][hdl->chan].hdl = hdl; + hdl->priv = &priv_hdl[hdl->unit][hdl->chan]; + netif_napi_add(ndev, (struct napi_struct *)hdl->priv, + ngknet_poll, pdev->ctrl.budget); + if (pdev->flags & PDMA_GROUP_INTR) { + break; + } + } + } + + /* Get callback control */ + ngknet_callback_control_get(&dev->cbc); + + INIT_LIST_HEAD(&dev->filt_list); + spin_lock_init(&dev->lock); + init_waitqueue_head(&dev->wq); + if (pdev->mode == DEV_MODE_HNET) { + init_waitqueue_head(&dev->vnet_wq); + atomic_set(&dev->vnet_active, 0); + init_waitqueue_head(&dev->hnet_wq); + atomic_set(&dev->hnet_active, 0); + dev->hnet_task = kthread_run(ngknet_dev_hnet_process, pdev, pdev->name); + if (IS_ERR(dev->hnet_task)) { + dev->hnet_task = NULL; + return SHR_E_INTERNAL; + } + cpumask_clear(&mask); + cpumask_set_cpu(1, &mask); + set_cpus_allowed_ptr(dev->hnet_task, &mask); + INIT_WORK(&dev->hnet_work, ngknet_dev_hnet_schedule); + } + + skb_queue_head_init(&dev->ptp_tx_queue); + INIT_WORK(&dev->ptp_tx_work, ngknet_ptp_tx_work); + + dev->flags |= NGKNET_DEV_ACTIVE; + + DBG_NDEV(("Broadcom NGKNET Attached\n")); + DBG_NDEV(("MAC: %pM\n", ndev->dev_addr)); + DBG_NDEV(("Running with NAPI enabled\n")); + + return SHR_E_NONE; +} + +/*! + * \brief Remove device. + * + * Suspend device firstly, destroy all virtual network devices + * and filters, clean up Packet DMA device. + * + * \param [in] dn Device number. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +static int +ngknet_dev_remove(int dn) +{ + struct ngknet_dev *dev = &ngknet_devices[dn]; + struct pdma_dev *pdev = &dev->pdma_dev; + struct net_device *ndev = NULL; + struct intr_handle *hdl = NULL; + int di, gi, qi; + int rv; + + if (!(dev->flags & NGKNET_DEV_ACTIVE)) { + return SHR_E_NONE; + } + + DBG_VERB(("%s: dev %d\n",__FUNCTION__, dn)); + + dev->flags &= ~NGKNET_DEV_ACTIVE; + + skb_queue_purge(&dev->ptp_tx_queue); + + if (pdev->mode == DEV_MODE_HNET && dev->hnet_task) { + atomic_set(&dev->hnet_active, 1); + wake_up_interruptible(&dev->hnet_wq); + kthread_stop(dev->hnet_task); + dev->hnet_task = NULL; + } + + /* Destroy all the filters */ + ngknet_filter_destroy_all(dev); + + /* Destroy all the virtual devices */ + for (di = 1; di <= NUM_VDEV_MAX; di++) { + ndev = dev->vdev[di]; + if (ndev) { + netif_carrier_off(ndev); + unregister_netdev(ndev); + free_netdev(ndev); + dev->vdev[di] = NULL; + } + } + dev->vdev[0] = NULL; + + DBG_VERB(("Removing base network device %s.\n", dev->net_dev->name)); + + /* Destroy the base network device */ + ndev = dev->net_dev; + unregister_netdev(ndev); + free_netdev(ndev); + + for (qi = 0; qi < NUM_QUE_MAX; qi++) { + dev->bdev[qi] = NULL; + } + + for (gi = 0; gi < pdev->num_groups; gi++) { + if (!pdev->ctrl.grp[gi].attached) { + continue; + } + for (qi = 0; qi < pdev->grp_queues; qi++) { + hdl = &pdev->ctrl.grp[gi].intr_hdl[qi]; + netif_napi_del((struct napi_struct *)hdl->priv); + priv_hdl[hdl->unit][hdl->chan].hdl = NULL; + if (pdev->flags & PDMA_GROUP_INTR) { + break; + } + } + } + + /* Clean up PDMA device */ + bcmcnet_pdma_dev_cleanup(pdev); + + /* Detach PDMA driver */ + rv = drv_ops[pdev->dev_type]->drv_detach(pdev); + if (SHR_FAILURE(rv)) { + DBG_WARN(("Detach DMA driver failed.\n")); + } + + return rv; +} + +/*! + * Network interface functions + */ + +int +ngknet_netif_create(struct ngknet_dev *dev, ngknet_netif_t *netif) +{ + struct net_device *ndev = NULL; + struct ngknet_private *priv = NULL; + unsigned long flags; + int num, id; + int rv; + + switch (netif->type) { + case NGKNET_NETIF_T_VLAN: + case NGKNET_NETIF_T_PORT: + case NGKNET_NETIF_T_META: + break; + default: + return SHR_E_UNAVAIL; + } + + /* Get vitual network device name */ + if (netif->name[0] == '\0') { + /* Reserve 6 vacancies for base&vitual device number, i.e. nameAB_XYZ */ + if (strlen(base_dev_name) < IFNAMSIZ - 6) { + snprintf(netif->name, IFNAMSIZ, "%s%d%s", base_dev_name, dev->dev_no, "_"); + strncat(netif->name, "%d", 3); + } else { + DBG_WARN(("Too long network device name: %s.\n", base_dev_name)); + return SHR_E_PARAM; + } + } + + rv = ngknet_ndev_init(netif, &ndev); + if (SHR_FAILURE(rv)) { + return rv; + } + + spin_lock_irqsave(&dev->lock, flags); + + num = (long)dev->vdev[0]; + for (id = 1; id < num + 1; id++) { + if (!dev->vdev[id]) { + break; + } + } + if (id > NUM_VDEV_MAX) { + spin_unlock_irqrestore(&dev->lock, flags); + unregister_netdev(ndev); + free_netdev(ndev); + return SHR_E_RESOURCE; + } + + dev->vdev[id] = ndev; + num += id == (num + 1) ? 1 : 0; + dev->vdev[0] = (struct net_device *)(long)num; + + spin_unlock_irqrestore(&dev->lock, flags); + + priv = netdev_priv(ndev); + priv->net_dev = ndev; + priv->bkn_dev = dev; + priv->id = id; + priv->type = netif->type; + if (priv->type == NGKNET_NETIF_T_PORT) { + priv->meta_off = netif->meta_off; + priv->meta_len = netif->meta_len; + memcpy(priv->meta_data, netif->meta_data, priv->meta_len); + } + priv->flags = netif->flags; + priv->vlan = netif->vlan; + priv->chan = netif->chan; + memcpy(priv->user_data, netif->user_data, sizeof(priv->user_data)); + + netif->id = priv->id; + memcpy(netif->macaddr, ndev->dev_addr, ETH_ALEN); + netif->mtu = ndev->mtu; + memcpy(netif->name, ndev->name, sizeof(netif->name) - 1); + + if (priv->flags & NGKNET_NETIF_F_BIND_CHAN) { + dev->bdev[priv->chan] = ndev; + } + + /* Optional netif create callback handle */ + if (dev->cbc->netif_create_cb) { + rv = dev->cbc->netif_create_cb(ndev); + if (rv) { + DBG_WARN(("Netif create callback failed with rv %d for '%s'\n", rv, ndev->name)); + } + } + + DBG_VERB(("Created virtual network device %s (%d).\n", ndev->name, priv->id)); + + return SHR_E_NONE; +} + +int +ngknet_netif_destroy(struct ngknet_dev *dev, int id) +{ + struct net_device *ndev = NULL; + struct ngknet_private *priv = NULL; + unsigned long flags; + int num; + DECLARE_WAITQUEUE(wait, current); + + if (id <= 0 || id > NUM_VDEV_MAX) { + return SHR_E_PARAM; + } + + spin_lock_irqsave(&dev->lock, flags); + + ndev = dev->vdev[id]; + if (!ndev) { + spin_unlock_irqrestore(&dev->lock, flags); + return SHR_E_NOT_FOUND; + } + priv = netdev_priv(ndev); + + add_wait_queue(&dev->wq, &wait); + + while (priv->users) { + priv->wait = 1; + set_current_state(TASK_INTERRUPTIBLE); + spin_unlock_irqrestore(&dev->lock, flags); + schedule(); + spin_lock_irqsave(&dev->lock, flags); + priv->wait = 0; + set_current_state(TASK_RUNNING); + } + + if (priv->flags & NGKNET_NETIF_F_BIND_CHAN) { + dev->bdev[priv->chan] = NULL; + } + + dev->vdev[id] = NULL; + num = (long)dev->vdev[0]; + while (num-- == id--) { + if (dev->vdev[id]) { + dev->vdev[0] = (struct net_device *)(long)num; + break; + } + } + + spin_unlock_irqrestore(&dev->lock, flags); + + remove_wait_queue(&dev->wq, &wait); + + /* Optional netif destroy callback handle */ + if (dev->cbc->netif_destroy_cb) { + int rv = dev->cbc->netif_destroy_cb(ndev); + if (rv) { + DBG_WARN(("Netif destroy callback failed with rv %d for '%s'\n", rv, ndev->name)); + } + } + DBG_VERB(("Removing virtual network device %s (%d).\n", ndev->name, priv->id)); + + netif_carrier_off(ndev); + unregister_netdev(ndev); + free_netdev(ndev); + + return SHR_E_NONE; +} + +int +ngknet_netif_get(struct ngknet_dev *dev, int id, ngknet_netif_t *netif) +{ + struct net_device *ndev = NULL; + struct ngknet_private *priv = NULL; + unsigned long flags; + int num; + + if (id < 0 || id > NUM_VDEV_MAX) { + return SHR_E_PARAM; + } + + spin_lock_irqsave(&dev->lock, flags); + + ndev = id == 0 ? dev->net_dev : dev->vdev[id]; + if (!ndev) { + spin_unlock_irqrestore(&dev->lock, flags); + return SHR_E_NOT_FOUND; + } + + priv = netdev_priv(ndev); + netif->id = priv->id; + netif->type = priv->type; + netif->flags = priv->flags; + netif->vlan = priv->vlan; + memcpy(netif->macaddr, priv->net_dev->dev_addr, ETH_ALEN); + netif->mtu = priv->net_dev->mtu; + netif->chan = priv->chan; + memcpy(netif->name, priv->net_dev->name, sizeof(netif->name) - 1); + netif->meta_off = priv->meta_off; + netif->meta_len = priv->meta_len; + memcpy(netif->meta_data, priv->meta_data, netif->meta_len); + memcpy(netif->user_data, priv->user_data, sizeof(netif->user_data)); + + num = (long)dev->vdev[0]; + for (id++; id < num + 1; id++) { + if (dev->vdev[id]) { + break; + } + } + netif->next = id == (num + 1) ? 0 : id; + + spin_unlock_irqrestore(&dev->lock, flags); + + DBG_VERB(("Got virtual network device %s (%d).\n", ndev->name, priv->id)); + + return SHR_E_NONE; +} + +int +ngknet_netif_get_next(struct ngknet_dev *dev, ngknet_netif_t *netif) +{ + return ngknet_netif_get(dev, netif->next, netif); +} + +/*! + * System control interfaces + */ + +int +ngknet_debug_level_get(void) +{ + return debug; +} + +void +ngknet_debug_level_set(int debug_level) +{ + debug = debug_level; +} + +int +ngknet_rx_rate_limit_get(void) +{ + return rx_rate_limit; +} + +void +ngknet_rx_rate_limit_set(int rate_limit) +{ + rx_rate_limit = rate_limit; +} + +/*! + * Generic module functions + */ + +static int +ngknet_open(struct inode *inode, struct file *filp) +{ + return 0; +} + +static int +ngknet_release(struct inode *inode, struct file *filp) +{ + return 0; +} + +static long +ngknet_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct ngknet_ioctl ioc; + struct ngknet_dev *dev = NULL; + struct net_device *ndev = NULL; + struct pdma_dev *pdev = NULL; + union { + ngknet_dev_cfg_t dev_cfg; + ngknet_chan_cfg_t chan_cfg; + ngknet_netif_t netif; + ngknet_filter_t filter; + } iod; + ngknet_dev_cfg_t *dev_cfg = &iod.dev_cfg; + ngknet_chan_cfg_t *chan_cfg = &iod.chan_cfg; + ngknet_netif_t *netif = &iod.netif; + ngknet_filter_t *filter = &iod.filter; + char *data = NULL; + int dt, gi, qi; + + if (_IOC_TYPE(cmd) != NGKNET_IOC_MAGIC) { + DBG_WARN(("Unsupported command (cmd=%d)\n", cmd)); + return -EINVAL; + } + + if (copy_from_user(&ioc, (void *)arg, sizeof(ioc))) { + return -EFAULT; + } + + ioc.rc = SHR_E_NONE; + + dev = &ngknet_devices[ioc.unit]; + pdev = &dev->pdma_dev; + + if (cmd != NGKNET_VERSION_GET && + cmd != NGKNET_RX_RATE_LIMIT && + cmd != NGKNET_DEV_INIT && + !(dev->flags & NGKNET_DEV_ACTIVE)) { + ioc.rc = SHR_E_UNAVAIL; + if (copy_to_user((void *)arg, &ioc, sizeof(ioc))) { + return -EFAULT; + } + return 0; + } + + switch (cmd) { + case NGKNET_VERSION_GET: + DBG_CMD(("NGKNET_VERSION_GET\n")); + ioc.op.info.version = NGKNET_IOC_VERSION; + break; + case NGKNET_RX_RATE_LIMIT: + DBG_CMD(("NGKNET_RX_RATE_LIMIT\n")); + if (ioc.iarg[0]) { + ngknet_rx_rate_limit_set(ioc.iarg[1]); + } else { + ioc.iarg[1] = ngknet_rx_rate_limit_get(); + } + break; + case NGKNET_DEV_INIT: + DBG_CMD(("NGKNET_DEV_INIT\n")); + if (dev->flags & NGKNET_DEV_ACTIVE) { + DBG_CMD(("NGKNET_DEV_INIT, retrieve device configurations.\n")); + strlcpy(dev_cfg->name, pdev->name, sizeof(dev_cfg->name)); + dev_cfg->dev_id = pdev->dev_id; + dev_cfg->nb_grp = pdev->ctrl.nb_grp; + dev_cfg->bm_grp = pdev->ctrl.bm_grp; + ioc.rc = ngknet_netif_get(dev, 0, &dev_cfg->base_netif); + if (SHR_FAILURE((int)ioc.rc)) { + break; + } + if (kal_copy_to_user((void *)(unsigned long)ioc.op.data.buf, dev_cfg, + ioc.op.data.len, sizeof(*dev_cfg))) { + return -EFAULT; + } + break; + } + if (kal_copy_from_user(dev_cfg, (void *)(unsigned long)ioc.op.data.buf, + sizeof(*dev_cfg), ioc.op.data.len)) { + return -EFAULT; + } + if (!dev_cfg->name[0] || !dev_cfg->bm_grp || + dev_cfg->bm_grp >= (1 << NUM_GRP_MAX)) { + DBG_WARN(("Invalid parameter: name=%s, bm_grp=0x%x\n", + dev_cfg->name, dev_cfg->bm_grp)); + ioc.rc = SHR_E_PARAM; + break; + } + memset(pdev, 0, sizeof(*pdev)); + strlcpy(pdev->name, dev_cfg->name, sizeof(pdev->name)); + pdev->dev_id = dev_cfg->dev_id; + for (dt = 0; dt < drv_num; dt++) { + if (!drv_ops[dt]) { + continue; + } + if (!strcasecmp(dev_cfg->type_str, drv_ops[dt]->drv_desc)) { + pdev->dev_type = dt; + break; + } + } + if (pdev->dev_type <= NGKNET_DEV_T_NONE || + pdev->dev_type >= NGKNET_DEV_T_COUNT) { + ioc.rc = SHR_E_PARAM; + break; + } + pdev->ctrl.bm_grp = dev_cfg->bm_grp; + for (gi = 0; gi < NUM_GRP_MAX; gi++) { + if (1 << gi & dev_cfg->bm_grp) { + pdev->ctrl.nb_grp++; + pdev->ctrl.grp[gi].attached = 1; + pdev->num_groups = gi + 1; + } + } + pdev->rx_ph_size = dev_cfg->rx_ph_size; + pdev->tx_ph_size = dev_cfg->tx_ph_size; + pdev->mode = dev_cfg->mode; + if (pdev->mode != DEV_MODE_KNET && pdev->mode != DEV_MODE_HNET) { + pdev->mode = DEV_MODE_KNET; + } + ioc.rc = ngknet_dev_probe(ioc.unit, &dev_cfg->base_netif); + if (SHR_FAILURE((int)ioc.rc)) { + break; + } + if (kal_copy_to_user((void *)(unsigned long)ioc.op.data.buf, dev_cfg, + ioc.op.data.len, sizeof(*dev_cfg))) { + return -EFAULT; + } + break; + case NGKNET_DEV_DEINIT: + DBG_CMD(("NGKNET_DEV_DEINIT\n")); + if (dev->flags & NGKNET_DEV_ACTIVE) { + ioc.rc = ngknet_dev_remove(ioc.unit); + } + break; + case NGKNET_QUEUE_CONFIG: + DBG_CMD(("NGKNET_QUEUE_CONFIG\n")); + if (kal_copy_from_user(chan_cfg, (void *)(unsigned long)ioc.op.data.buf, + sizeof(*chan_cfg), ioc.op.data.len)) { + return -EFAULT; + } + gi = chan_cfg->chan / pdev->grp_queues; + if (!(1 << gi & pdev->ctrl.bm_grp)) { + DBG_WARN(("Invalid parameter: chan=%d (bm_grp=0x%x)\n", + chan_cfg->chan, pdev->ctrl.bm_grp)); + ioc.rc = SHR_E_PARAM; + break; + } + if (chan_cfg->dir == PDMA_Q_RX) { + if (1 << chan_cfg->chan & pdev->ctrl.bm_txq) { + pdev->ctrl.bm_txq &= ~(1 << chan_cfg->chan); + pdev->ctrl.nb_txq--; + } + if (!(1 << chan_cfg->chan & pdev->ctrl.bm_rxq)) { + pdev->ctrl.bm_rxq |= 1 << chan_cfg->chan; + pdev->ctrl.nb_rxq++; + } + } else { + if (1 << chan_cfg->chan & pdev->ctrl.bm_rxq) { + pdev->ctrl.bm_rxq &= ~(1 << chan_cfg->chan); + pdev->ctrl.nb_rxq--; + } + if (!(1 << chan_cfg->chan & pdev->ctrl.bm_txq)) { + pdev->ctrl.bm_txq |= 1 << chan_cfg->chan; + pdev->ctrl.nb_txq++; + } + } + qi = chan_cfg->chan % pdev->grp_queues; + pdev->ctrl.grp[gi].nb_desc[qi] = chan_cfg->nb_desc; + pdev->ctrl.grp[gi].rx_size[qi] = chan_cfg->rx_buf_size; + pdev->ctrl.grp[gi].que_ctrl[qi] &= ~(PDMA_PKT_BYTE_SWAP | + PDMA_OTH_BYTE_SWAP | + PDMA_HDR_BYTE_SWAP); + if (chan_cfg->chan_ctrl & NGKNET_PKT_BYTE_SWAP) { + pdev->ctrl.grp[gi].que_ctrl[qi] |= PDMA_PKT_BYTE_SWAP; + } + if (chan_cfg->chan_ctrl & NGKNET_OTH_BYTE_SWAP) { + pdev->ctrl.grp[gi].que_ctrl[qi] |= PDMA_OTH_BYTE_SWAP; + } + if (chan_cfg->chan_ctrl & NGKNET_HDR_BYTE_SWAP) { + pdev->ctrl.grp[gi].que_ctrl[qi] |= PDMA_HDR_BYTE_SWAP; + } + break; + case NGKNET_QUEUE_QUERY: + DBG_CMD(("NGKNET_QUEUE_QUERY\n")); + if (kal_copy_from_user(chan_cfg, (void *)(unsigned long)ioc.op.data.buf, + sizeof(*chan_cfg), ioc.op.data.len)) { + return -EFAULT; + } + if (1 << chan_cfg->chan & pdev->ctrl.bm_rxq) { + chan_cfg->dir = PDMA_Q_RX; + } else if (1 << chan_cfg->chan & pdev->ctrl.bm_txq) { + chan_cfg->dir = PDMA_Q_TX; + } else { + ioc.rc = SHR_E_UNAVAIL; + break; + } + gi = chan_cfg->chan / pdev->grp_queues; + qi = chan_cfg->chan % pdev->grp_queues; + chan_cfg->nb_desc = pdev->ctrl.grp[gi].nb_desc[qi]; + chan_cfg->chan_ctrl = pdev->ctrl.grp[gi].que_ctrl[qi]; + if (chan_cfg->dir == PDMA_Q_RX) { + chan_cfg->rx_buf_size = pdev->ctrl.grp[gi].rx_size[qi]; + } else { + chan_cfg->rx_buf_size = 0; + } + if (kal_copy_to_user((void *)(unsigned long)ioc.op.data.buf, chan_cfg, + ioc.op.data.len, sizeof(*chan_cfg))) { + return -EFAULT; + } + break; + case NGKNET_DEV_SUSPEND: + DBG_CMD(("NGKNET_DEV_SUSPEND\n")); + if (rx_rate_limit >= 0) { + ngknet_rx_rate_limit_stop(dev); + } + ioc.rc = bcmcnet_pdma_dev_suspend(pdev); + break; + case NGKNET_DEV_RESUME: + DBG_CMD(("NGKNET_DEV_RESUME\n")); + ioc.rc = bcmcnet_pdma_dev_resume(pdev); + if (rx_rate_limit >= 0) { + ngknet_rx_rate_limit_start(dev); + } + break; + case NGKNET_DEV_VNET_WAIT: + DBG_CMD(("NGKNET_DEV_VNET_WAIT\n")); + if (pdev->mode != DEV_MODE_HNET) { + ioc.rc = SHR_E_UNAVAIL; + break; + } + wait_event_interruptible(dev->vnet_wq, + atomic_read(&dev->vnet_active) != 0); + atomic_set(&dev->vnet_active, 0); + break; + case NGKNET_DEV_HNET_WAKE: + DBG_CMD(("NGKNET_DEV_HNET_WAKE\n")); + if (pdev->mode != DEV_MODE_HNET) { + ioc.rc = SHR_E_UNAVAIL; + break; + } + atomic_set(&dev->hnet_active, 1); + wake_up_interruptible(&dev->hnet_wq); + break; + case NGKNET_DEV_VNET_DOCK: + DBG_CMD(("NGKNET_DEV_VNET_DOCK\n")); + if (pdev->mode != DEV_MODE_HNET) { + ioc.rc = SHR_E_UNAVAIL; + break; + } + if (kal_copy_from_user(&pdev->ctrl.vsync, (void *)(unsigned long)ioc.op.data.buf, + sizeof(pdev->ctrl.vsync), ioc.op.data.len)) { + return -EFAULT; + } + ioc.rc = bcmcnet_pdma_dev_dock(pdev); + break; + case NGKNET_DEV_VNET_UNDOCK: + DBG_CMD(("NGKNET_DEV_VNET_UNDOCK\n")); + if (pdev->mode != DEV_MODE_HNET) { + ioc.rc = SHR_E_UNAVAIL; + break; + } + ngknet_dev_vnet_wake(pdev); + ioc.rc = bcmcnet_pdma_dev_undock(pdev); + break; + case NGKNET_RCPU_CONFIG: + DBG_CMD(("NGKNET_RCPU_CONFIG\n")); + if (kal_copy_from_user(&dev->rcpu_ctrl, (void *)(unsigned long)ioc.op.data.buf, + sizeof(dev->rcpu_ctrl), ioc.op.data.len)) { + return -EFAULT; + } + break; + case NGKNET_RCPU_GET: + DBG_CMD(("NGKNET_RCPU_GET\n")); + if (kal_copy_to_user((void *)(unsigned long)ioc.op.data.buf, &dev->rcpu_ctrl, + ioc.op.data.len, sizeof(dev->rcpu_ctrl))) { + return -EFAULT; + } + break; + case NGKNET_INFO_GET: + DBG_CMD(("NGKNET_INFO_GET\n")); + bcmcnet_pdma_dev_info_get(pdev); + if (kal_copy_to_user((void *)(unsigned long)ioc.op.data.buf, &pdev->info, + ioc.op.data.len, sizeof(pdev->info))) { + return -EFAULT; + } + break; + case NGKNET_STATS_GET: + DBG_CMD(("NGKNET_STATS_GET\n")); + bcmcnet_pdma_dev_stats_get(pdev); + if (kal_copy_to_user((void *)(unsigned long)ioc.op.data.buf, &pdev->stats, + ioc.op.data.len, sizeof(pdev->stats))) { + return -EFAULT; + } + break; + case NGKNET_STATS_RESET: + DBG_CMD(("NGKNET_STATS_RESET\n")); + bcmcnet_pdma_dev_stats_reset(pdev); + break; + case NGKNET_NETIF_CREATE: + DBG_CMD(("NGKNET_NETIF_CREATE\n")); + if (kal_copy_from_user(netif, (void *)(unsigned long)ioc.op.data.buf, + sizeof(*netif), ioc.op.data.len)) { + return -EFAULT; + } + ioc.rc = ngknet_netif_create(dev, netif); + if (SHR_FAILURE((int)ioc.rc)) { + break; + } + if (kal_copy_to_user((void *)(unsigned long)ioc.op.data.buf, netif, + ioc.op.data.len, sizeof(*netif))) { + return -EFAULT; + } + break; + case NGKNET_NETIF_DESTROY: + DBG_CMD(("NGKNET_NETIF_DESTROY\n")); + ioc.rc = ngknet_netif_destroy(dev, ioc.iarg[0]); + break; + case NGKNET_NETIF_GET: + DBG_CMD(("NGKNET_NETIF_GET\n")); + ioc.rc = ngknet_netif_get(dev, ioc.iarg[0], netif); + if (SHR_FAILURE((int)ioc.rc)) { + break; + } + if (kal_copy_to_user((void *)(unsigned long)ioc.op.data.buf, netif, + ioc.op.data.len, sizeof(*netif))) { + return -EFAULT; + } + break; + case NGKNET_NETIF_NEXT: + DBG_CMD(("NGKNET_NETIF_NEXT\n")); + if (kal_copy_from_user(netif, (void *)(unsigned long)ioc.op.data.buf, + sizeof(*netif), ioc.op.data.len)) { + return -EFAULT; + } + ioc.rc = ngknet_netif_get_next(dev, netif); + if (SHR_FAILURE((int)ioc.rc)) { + break; + } + if (kal_copy_to_user((void *)(unsigned long)ioc.op.data.buf, netif, + ioc.op.data.len, sizeof(*netif))) { + return -EFAULT; + } + break; + case NGKNET_NETIF_LINK_SET: + DBG_CMD(("NGKNET_NETIF_LINK_SET\n")); + ioc.rc = ngknet_netif_get(dev, ioc.iarg[0], netif); + if (SHR_FAILURE((int)ioc.rc)) { + break; + } + ndev = dev->vdev[netif->id]; + if (ioc.iarg[1]) { + if (!netif_carrier_ok(ndev)) { + netif_carrier_on(ndev); + netif_tx_wake_all_queues(ndev); + DBG_LINK(("%s: link up\n", netif->name)); + } + } else { + if (netif_carrier_ok(ndev)) { + netif_carrier_off(ndev); + netif_tx_stop_all_queues(ndev); + DBG_LINK(("%s: link down\n", netif->name)); + } + } + break; + case NGKNET_FILT_CREATE: + DBG_CMD(("NGKNET_FILT_CREATE\n")); + if (kal_copy_from_user(filter, (void *)(unsigned long)ioc.op.data.buf, + sizeof(*filter), ioc.op.data.len)) { + return -EFAULT; + } + ioc.rc = ngknet_filter_create(dev, filter); + if (SHR_FAILURE((int)ioc.rc)) { + break; + } + if (kal_copy_to_user((void *)(unsigned long)ioc.op.data.buf, filter, + ioc.op.data.len, sizeof(*filter))) { + return -EFAULT; + } + break; + case NGKNET_FILT_DESTROY: + DBG_CMD(("NGKNET_FILT_DESTROY\n")); + ioc.rc = ngknet_filter_destroy(dev, ioc.iarg[0]); + break; + case NGKNET_FILT_GET: + DBG_CMD(("NGKNET_FILT_GET\n")); + ioc.rc = ngknet_filter_get(dev, ioc.iarg[0], filter); + if (SHR_FAILURE((int)ioc.rc)) { + break; + } + if (kal_copy_to_user((void *)(unsigned long)ioc.op.data.buf, filter, + ioc.op.data.len, sizeof(*filter))) { + return -EFAULT; + } + break; + case NGKNET_FILT_NEXT: + DBG_CMD(("NGKNET_FILT_NEXT\n")); + if (kal_copy_from_user(filter, (void *)(unsigned long)ioc.op.data.buf, + sizeof(*filter), ioc.op.data.len)) { + return -EFAULT; + } + ioc.rc = ngknet_filter_get_next(dev, filter); + if (SHR_FAILURE((int)ioc.rc)) { + break; + } + if (kal_copy_to_user((void *)(unsigned long)ioc.op.data.buf, filter, + ioc.op.data.len, sizeof(*filter))) { + return -EFAULT; + } + break; + case NGKNET_PTP_DEV_CTRL: + DBG_CMD(("NGKNET_PTP_DEV_CTRL\n")); + if (ioc.op.data.len) { + data = kmalloc(ioc.op.data.len, GFP_ATOMIC); + if (data == NULL) { + printk("Fatal error: no memory for PTP device ioctl\n"); + return -EFAULT; + } + if (copy_from_user(data, (void *)(unsigned long)ioc.op.data.buf, + ioc.op.data.len)) { + kfree(data); + return -EFAULT; + } + } + ioc.rc = ngknet_ptp_dev_ctrl(dev, ioc.iarg[0], data, ioc.op.data.len); + if (SHR_FAILURE((int)ioc.rc)) { + if (data) { + kfree(data); + } + break; + } + if (ioc.op.data.len) { + if (copy_to_user((void *)(unsigned long)ioc.op.data.buf, data, + ioc.op.data.len)) { + kfree(data); + return -EFAULT; + } + kfree(data); + } + break; + default: + ioc.rc = SHR_E_UNAVAIL; + printk("Invalid IOCTL"); + break; + } + + if (copy_to_user((void *)arg, &ioc, sizeof(ioc))) { + return -EFAULT; + } + + return 0; +} + +static int +ngknet_mmap(struct file *filp, struct vm_area_struct *vma) +{ + return 0; +} + +static struct file_operations ngknet_fops = { + .open = ngknet_open, + .release = ngknet_release, + .unlocked_ioctl = ngknet_ioctl, + .compat_ioctl = ngknet_ioctl, + .mmap = ngknet_mmap, +}; + +static int __init +ngknet_init_module(void) +{ + int idx; + int rv; + + rv = register_chrdev(NGKNET_MODULE_MAJOR, NGKNET_MODULE_NAME, &ngknet_fops); + if (rv < 0) { + printk(KERN_WARNING "%s: can't get major %d\n", + NGKNET_MODULE_NAME, NGKNET_MODULE_MAJOR); + return rv; + } + + /* Randomize lower 3 bytes of the MAC address (TESTING ONLY) */ + get_random_bytes(&ngknet_dev_mac[3], 3); + + /* Check for user-supplied MAC address (recommended) */ + if (mac_addr != NULL && strlen(mac_addr) == 17) { + for (idx = 0; idx < 6; idx++) { + ngknet_dev_mac[idx] = simple_strtoul(&mac_addr[idx * 3], NULL, 16); + } + /* Do not allow multicast address */ + ngknet_dev_mac[0] &= ~0x01; + } + + /* Initialize procfs */ + ngknet_procfs_init(); + + /* Initialize Rx rate limit */ + ngknet_rx_rate_limit_init(ngknet_devices); + + return 0; +} + +static void __exit +ngknet_exit_module(void) +{ + int idx; + + /* Cleanup Rx rate limit */ + ngknet_rx_rate_limit_cleanup(); + + /* Cleanup procfs */ + ngknet_procfs_cleanup(); + + /* Remove all the devices */ + for (idx = 0; idx < NUM_PDMA_DEV_MAX; idx++) { + ngknet_dev_remove(idx); + } + + unregister_chrdev(NGKNET_MODULE_MAJOR, NGKNET_MODULE_NAME); +} + +module_init(ngknet_init_module); +module_exit(ngknet_exit_module); + diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_main.h b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_main.h new file mode 100644 index 000000000000..fb38f1b9abc3 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_main.h @@ -0,0 +1,278 @@ +/*! \file ngknet_main.h + * + * Data structure and macro definitions for NGKNET kernel module. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#ifndef NGKNET_MAIN_H +#define NGKNET_MAIN_H + +#include +#include +#include +#include + +/*! Maximum number of PDMA devices supported */ +#ifdef NGBDE_NUM_SWDEV_MAX +#define NUM_PDMA_DEV_MAX NGBDE_NUM_SWDEV_MAX +#else +#define NUM_PDMA_DEV_MAX 16 +#endif + +/*! + * Debug levels + */ +#define DBG_LVL_VERB 0x0001 +#define DBG_LVL_PKT 0x0002 +#define DBG_LVL_CMD 0x0004 +#define DBG_LVL_IRQ 0x0008 +#define DBG_LVL_NAPI 0x0010 +#define DBG_LVL_NDEV 0x0020 +#define DBG_LVL_FILT 0x0040 +#define DBG_LVL_RCPU 0x0080 +#define DBG_LVL_WARN 0x0100 +#define DBG_LVL_PDMP 0x0200 +#define DBG_LVL_RATE 0x0400 +#define DBG_LVL_LINK 0x0800 + +#define DBG_VERB(_s) do { if (debug & DBG_LVL_VERB) printk _s; } while (0) +#define DBG_PKT(_s) do { if (debug & DBG_LVL_PKT) printk _s; } while (0) +#define DBG_CMD(_s) do { if (debug & DBG_LVL_CMD) printk _s; } while (0) +#define DBG_IRQ(_s) do { if (debug & DBG_LVL_IRQ) printk _s; } while (0) +#define DBG_NAPI(_s) do { if (debug & DBG_LVL_NAPI) printk _s; } while (0) +#define DBG_NDEV(_s) do { if (debug & DBG_LVL_NDEV) printk _s; } while (0) +#define DBG_FILT(_s) do { if (debug & DBG_LVL_FILT) printk _s; } while (0) +#define DBG_RCPU(_s) do { if (debug & DBG_LVL_RCPU) printk _s; } while (0) +#define DBG_WARN(_s) do { if (debug & DBG_LVL_WARN) printk _s; } while (0) +#define DBG_PDMP(_s) do { if (debug & DBG_LVL_PDMP) printk _s; } while (0) +#define DBG_RATE(_s) do { if (debug & DBG_LVL_RATE) printk _s; } while (0) +#define DBG_LINK(_s) do { if (debug & DBG_LVL_LINK) printk _s; } while (0) + +/*! + * Device description + */ +struct ngknet_dev { + /*! Base address for PCI register access */ + volatile void *base_addr; + + /*! Required for DMA memory control */ + struct device *dev; + + /*! Required for PCI memory control */ + struct pci_dev *pci_dev; + + /*! Base network device */ + struct net_device *net_dev; + + /*! PDMA device */ + struct pdma_dev pdma_dev; + + /*! Device number (from BDE) */ + int dev_no; + + /*! Vitual network devices, 0 is reserved */ + struct net_device *vdev[NUM_VDEV_MAX + 1]; + + /*! Vitual network devices bound to queue */ + struct net_device *bdev[NUM_QUE_MAX]; + + /*! Filter list */ + struct list_head filt_list; + + /*! Filter control, 0 is reserved */ + void *fc[NUM_FILTER_MAX + 1]; + + /*! Callback control */ + struct ngknet_callback_ctrl *cbc; + + /*! RCPU control */ + struct ngknet_rcpu_hdr rcpu_ctrl; + + /*! NGKNET lock */ + spinlock_t lock; + + /*! NGKNET wait queue */ + wait_queue_head_t wq; + + /*! VNET wait queue */ + wait_queue_head_t vnet_wq; + + /*! VNET is active */ + atomic_t vnet_active; + + /*! HNET wait queue */ + wait_queue_head_t hnet_wq; + + /*! HNET is active */ + atomic_t hnet_active; + + /*! HNET deamon */ + struct task_struct *hnet_task; + + /*! HNET work */ + struct work_struct hnet_work; + + /*! PTP Tx queue */ + struct sk_buff_head ptp_tx_queue; + + /*! PTP Tx work */ + struct work_struct ptp_tx_work; + + /*! Flags */ + int flags; + /*! NGKNET device is active */ +#define NGKNET_DEV_ACTIVE (1 << 0) +}; + +/*! + * Network interface specific private data + */ +struct ngknet_private { + /*! Network device */ + struct net_device *net_dev; + + /*! Network stats */ + struct net_device_stats stats; + + /*! NGKNET device */ + struct ngknet_dev *bkn_dev; + + /*! Network interface ID */ + int id; + + /*! Network interface type */ + int type; + + /*! Network interface flags */ + uint32_t flags; + + /*! Network interface vlan */ + uint32_t vlan; + + /*! Network interface bound to */ + uint32_t chan; + + /*! Metadata offset from Ethernet header */ + uint32_t meta_off; + + /*! Metadata length */ + uint32_t meta_len; + + /*! Metadata used to send packets to physical port */ + uint8_t meta_data[NGKNET_NETIF_META_MAX]; + + /*! User data gotten back through callbacks */ + uint8_t user_data[NGKNET_NETIF_USER_DATA]; + + /*! Users of this network interface */ + int users; + + /*! Wait for this network interface free */ + int wait; + + /*! HW timestamp Rx filter */ + int hwts_rx_filter; + + /*! HW timestamp Tx type */ + int hwts_tx_type; +}; + +/*! + * \brief Create network interface. + * + * \param [in] dev NGKNET device structure point. + * \param [in] netif Network interface structure point. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +ngknet_netif_create(struct ngknet_dev *dev, ngknet_netif_t *netif); + +/*! + * \brief Destroy network interface. + * + * \param [in] dev NGKNET device structure point. + * \param [in] id Network interface ID. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +ngknet_netif_destroy(struct ngknet_dev *dev, int id); + +/*! + * \brief Get network interface. + * + * \param [in] dev NGKNET device structure point. + * \param [in] id Network interface ID. + * \param [out] netif Network interface structure point. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +ngknet_netif_get(struct ngknet_dev *dev, int id, ngknet_netif_t *netif); + +/*! + * \brief Get the next network interface. + * + * \param [in] dev NGKNET device structure point. + * \param [out] netif Network interface structure point. + * + * \retval SHR_E_NONE No errors. + * \retval SHR_E_XXXX Operation failed. + */ +extern int +ngknet_netif_get_next(struct ngknet_dev *dev, ngknet_netif_t *netif); + +/*! + * \brief Get debug level. + * + * \retval Current debug level. + */ +extern int +ngknet_debug_level_get(void); + +/*! + * \brief Set debug level. + * + * \param [in] debug_level Debug level to be set. + */ +extern void +ngknet_debug_level_set(int debug_level); + +/*! + * \brief Get Rx rate limit. + * + * \retval Current Rx rate limit. + */ +extern int +ngknet_rx_rate_limit_get(void); + +/*! + * \brief Set Rx rate limit. + * + * \param [in] rate_limit Rx rate limit to be set. + */ +extern void +ngknet_rx_rate_limit_set(int rate_limit); + +#endif /* NGKNET_MAIN_H */ + diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_procfs.c b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_procfs.c new file mode 100644 index 000000000000..85edaa26abb9 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_procfs.c @@ -0,0 +1,655 @@ +/*! \file ngknet_procfs.c + * + * + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include +#include +#include "ngknet_main.h" +#include "ngknet_extra.h" + +extern struct ngknet_dev ngknet_devices[]; + +static struct proc_dir_entry *proc_root = NULL; + +static void +proc_data_show(struct seq_file *m, const unsigned char *buf, size_t len) +{ + uint32_t i; + + if (!buf || !len) { + seq_printf(m, "\n"); + return; + } + + for (i = 0; i < len; i++) { + seq_printf(m, "%02x ", buf[i]); + if ((i + 1) % 32 == 0 || (i + 1) == len) { + seq_printf(m, "\n"); + if ((i + 1) < len) { + seq_printf(m, " "); + } + } + } +} + +static int +proc_debug_level_show(struct seq_file *m, void *v) +{ + seq_printf(m, "Debug level: 0x%x\n", ngknet_debug_level_get()); + + return 0; +} + +static int +proc_debug_level_open(struct inode *inode, struct file *file) +{ + return single_open(file, proc_debug_level_show, NULL); +} + +static ssize_t +proc_debug_level_write(struct file *file, const char *buf, + size_t count, loff_t *loff) +{ + char level_str[11] = {0}; + int debug_level; + + if (copy_from_user(level_str, buf, sizeof(level_str) - 1)) { + return -EFAULT; + } + debug_level = simple_strtol(level_str, NULL, 16); + + ngknet_debug_level_set(debug_level); + printk("Debug level set to: 0x%x\n", debug_level); + + return count; +} + +static int +proc_debug_level_release(struct inode *inode, struct file *file) +{ + return single_release(inode, file); +} + +static struct file_operations proc_debug_level_fops = { + owner: THIS_MODULE, + open: proc_debug_level_open, + read: seq_read, + write: proc_debug_level_write, + llseek: seq_lseek, + release: proc_debug_level_release, +}; + +static int +proc_device_info_show(struct seq_file *m, void *v) +{ + struct ngknet_dev *dev; + struct bcmcnet_dev_info *info; + int di, qi, ai = 0; + int rv; + + for (di = 0; di < NUM_PDMA_DEV_MAX; di++) { + dev = &ngknet_devices[di]; + if (!(dev->flags & NGKNET_DEV_ACTIVE)) { + continue; + } + ai++; + + rv = bcmcnet_pdma_dev_info_get(&dev->pdma_dev); + if (SHR_FAILURE(rv)) { + printk("ngknet: get device%d info failed\n", di); + break; + } + + info = &dev->pdma_dev.info; + seq_printf(m, "dev_no: %d\n", di); + seq_printf(m, "dev_name: %s\n", info->dev_name); + seq_printf(m, "dev_id: 0x%x\n", info->dev_id); + seq_printf(m, "dev_type: %d\n", info->dev_type); + seq_printf(m, "max_groups: %d\n", info->max_groups); + seq_printf(m, "max_queues: %d\n", info->max_queues); + seq_printf(m, "bm_groups: 0x%x\n", info->bm_groups); + seq_printf(m, "bm_rx_queues: 0x%x\n", info->bm_rx_queues); + seq_printf(m, "bm_tx_queues: 0x%x\n", info->bm_tx_queues); + seq_printf(m, "nb_groups: %d\n", info->nb_groups); + seq_printf(m, "nb_rx_queues: %d\n", info->nb_rx_queues); + seq_printf(m, "nb_tx_queues: %d\n", info->nb_tx_queues); + seq_printf(m, "rx_desc_size: %d\n", info->rx_desc_size); + seq_printf(m, "tx_desc_size: %d\n", info->tx_desc_size); + seq_printf(m, "rx_ph_size: %d\n", info->rx_ph_size); + seq_printf(m, "tx_ph_size: %d\n", info->tx_ph_size); + for (qi = 0; qi < info->nb_rx_queues; qi++) { + seq_printf(m, "rx_buf_sz[%d]: %d\n", qi, info->rx_buf_size[qi]); + } + for (qi = 0; qi < info->nb_rx_queues; qi++) { + seq_printf(m, "nb_rx_desc[%d]: %d\n", qi, info->nb_rx_desc[qi]); + } + for (qi = 0; qi < info->nb_tx_queues; qi++) { + seq_printf(m, "nb_tx_desc[%d]: %d\n", qi, info->nb_tx_desc[qi]); + } + } + + if (!ai) { + seq_printf(m, "%s\n", "No active device"); + } else { + seq_printf(m, "------------------------\n"); + seq_printf(m, "Total %d devices\n", ai); + } + + return 0; +} + +static int +proc_device_info_open(struct inode *inode, struct file *file) +{ + return single_open(file, proc_device_info_show, NULL); +} + +static int +proc_device_info_release(struct inode *inode, struct file *file) +{ + return single_release(inode, file); +} + +static struct file_operations proc_device_info_fops = { + owner: THIS_MODULE, + open: proc_device_info_open, + read: seq_read, + llseek: seq_lseek, + release: proc_device_info_release, +}; + +static int +proc_filter_info_show(struct seq_file *m, void *v) +{ + struct ngknet_dev *dev; + ngknet_filter_t filt = {0}; + int di, dn = 0, fn = 0; + int rv; + + for (di = 0; di < NUM_PDMA_DEV_MAX; di++) { + dev = &ngknet_devices[di]; + if (!(dev->flags & NGKNET_DEV_ACTIVE)) { + continue; + } + dn++; + + do { + rv = ngknet_filter_get_next(dev, &filt); + if (SHR_FAILURE(rv)) { + printk("ngknet: get device%d filter failed\n", di); + break; + } + fn++; + + seq_printf(m, "\n"); + seq_printf(m, "dev_no: %d\n", di); + seq_printf(m, "id: %d\n", filt.id); + seq_printf(m, "next: %d\n", filt.next); + seq_printf(m, "type: %d\n", filt.type); + seq_printf(m, "flags: 0x%x\n", filt.flags); + seq_printf(m, "prio: %d\n", filt.priority); + seq_printf(m, "chan: %d\n", filt.chan); + seq_printf(m, "desc: %s\n", filt.desc); + seq_printf(m, "dest_type: %d\n", filt.dest_type); + seq_printf(m, "dest_id: %d\n", filt.dest_id); + seq_printf(m, "dest_proto: 0x%x\n", filt.dest_proto); + seq_printf(m, "mirror_type: %d\n", filt.mirror_type); + seq_printf(m, "mirror_id: %d\n", filt.mirror_id); + seq_printf(m, "mirror_proto: 0x%x\n", filt.mirror_proto); + seq_printf(m, "oob_offset: %d\n", filt.oob_data_offset); + seq_printf(m, "oob_size: %d\n", filt.oob_data_size); + seq_printf(m, "pkt_offset: %d\n", filt.pkt_data_offset); + seq_printf(m, "pkt_size: %d\n", filt.pkt_data_size); + seq_printf(m, "filt_data: "); + proc_data_show(m, filt.data.b, filt.oob_data_size + filt.pkt_data_size); + seq_printf(m, "filt_mask: "); + proc_data_show(m, filt.mask.b, filt.oob_data_size + filt.pkt_data_size); + seq_printf(m, "user_data: "); + proc_data_show(m, filt.user_data, NGKNET_FILTER_USER_DATA); + seq_printf(m, "hits: %llu\n", ((struct filt_ctrl *)dev->fc[filt.id])->hits); + } while (filt.next); + } + + if (!dn) { + seq_printf(m, "%s\n", "No active device"); + } else { + seq_printf(m, "--------------------------------\n"); + seq_printf(m, "Total %d devices, %d filters\n", dn, fn); + } + + return 0; +} + +static int +proc_filter_info_open(struct inode *inode, struct file *file) +{ + return single_open(file, proc_filter_info_show, NULL); +} + +static int +proc_filter_info_release(struct inode *inode, struct file *file) +{ + return single_release(inode, file); +} + +static struct file_operations proc_filter_info_fops = { + owner: THIS_MODULE, + open: proc_filter_info_open, + read: seq_read, + llseek: seq_lseek, + release: proc_filter_info_release, +}; + +static int +proc_netif_info_show(struct seq_file *m, void *v) +{ + struct ngknet_dev *dev; + struct net_device *ndev; + struct ngknet_private *priv; + ngknet_netif_t netif = {0}; + int di, ma, dn = 0, nn = 0; + int rv; + + for (di = 0; di < NUM_PDMA_DEV_MAX; di++) { + dev = &ngknet_devices[di]; + if (!(dev->flags & NGKNET_DEV_ACTIVE)) { + continue; + } + dn++; + + do { + rv = ngknet_netif_get_next(dev, &netif); + if (SHR_FAILURE(rv)) { + printk("ngknet: get device%d netif failed\n", di); + break; + } + nn++; + ndev = netif.id == 0 ? dev->net_dev : dev->vdev[netif.id]; + priv = netdev_priv(ndev); + + seq_printf(m, "\n"); + seq_printf(m, "dev_no: %d\n", di); + seq_printf(m, "id: %d\n", netif.id); + seq_printf(m, "next: %d\n", netif.next); + seq_printf(m, "type: %d\n", netif.type); + seq_printf(m, "flags: 0x%x\n", netif.flags); + seq_printf(m, "vlan: %d\n", netif.vlan); + seq_printf(m, "mac: "); + for (ma = 0; ma < 6; ma++) { + if (ma == 5) { + seq_printf(m, "%02x\n", netif.macaddr[ma]); + } else { + seq_printf(m, "%02x:", netif.macaddr[ma]); + } + } + seq_printf(m, "mtu: %d\n", netif.mtu); + seq_printf(m, "chan: %d\n", netif.chan); + seq_printf(m, "name: %s\n", netif.name); + seq_printf(m, "meta_off: %d\n", netif.meta_off); + seq_printf(m, "meta_len: %d\n", netif.meta_len); + seq_printf(m, "meta_data: "); + proc_data_show(m, netif.meta_data, netif.meta_len); + seq_printf(m, "user_data: "); + proc_data_show(m, netif.user_data, NGKNET_NETIF_USER_DATA); + seq_printf(m, "rx_packets: %lu\n", priv->stats.rx_packets); + seq_printf(m, "rx_bytes: %lu\n", priv->stats.rx_bytes); + seq_printf(m, "rx_dropped: %lu\n", priv->stats.rx_dropped); + seq_printf(m, "rx_errors: %lu\n", priv->stats.rx_errors); + seq_printf(m, "tx_packets: %lu\n", priv->stats.tx_packets); + seq_printf(m, "tx_bytes: %lu\n", priv->stats.tx_bytes); + seq_printf(m, "tx_dropped: %lu\n", priv->stats.tx_dropped); + seq_printf(m, "tx_errors: %lu\n", priv->stats.tx_errors); + } while (netif.next); + } + + if (!dn) { + seq_printf(m, "%s\n", "No active device"); + } else { + seq_printf(m, "--------------------------------\n"); + seq_printf(m, "Total %d devices, %d netifs\n", dn, nn); + } + + return 0; +} + +static int +proc_netif_info_open(struct inode *inode, struct file *file) +{ + return single_open(file, proc_netif_info_show, NULL); +} + +static int +proc_netif_info_release(struct inode *inode, struct file *file) +{ + return single_release(inode, file); +} + +static struct file_operations proc_netif_info_fops = { + owner: THIS_MODULE, + open: proc_netif_info_open, + read: seq_read, + llseek: seq_lseek, + release: proc_netif_info_release, +}; + +static int +proc_pkt_stats_show(struct seq_file *m, void *v) +{ + struct ngknet_dev *dev; + struct bcmcnet_dev_stats *stats; + int di, qi, ai = 0; + int rv; + + for (di = 0; di < NUM_PDMA_DEV_MAX; di++) { + dev = &ngknet_devices[di]; + if (!(dev->flags & NGKNET_DEV_ACTIVE)) { + continue; + } + ai++; + + rv = bcmcnet_pdma_dev_stats_get(&dev->pdma_dev); + if (SHR_FAILURE(rv)) { + printk("ngknet: get device%d stats failed\n", di); + break; + } + + stats = &dev->pdma_dev.stats; + seq_printf(m, "rx_packets: %llu\n", (unsigned long long)stats->rx_packets); + seq_printf(m, "rx_bytes: %llu\n", (unsigned long long)stats->rx_bytes); + for (qi = 0; qi < dev->pdma_dev.ctrl.nb_rxq; qi++) { + seq_printf(m, "rx_packets[%d]: %llu\n", qi, (unsigned long long)stats->rxq_packets[qi]); + seq_printf(m, "rx_bytes[%d]: %llu\n", qi, (unsigned long long)stats->rxq_bytes[qi]); + } + seq_printf(m, "rx_dropped: %llu\n", (unsigned long long)stats->rx_dropped); + seq_printf(m, "rx_errors: %llu\n", (unsigned long long)stats->rx_errors); + seq_printf(m, "rx_nomems: %llu\n", (unsigned long long)stats->rx_nomems); + seq_printf(m, "tx_packets: %llu\n", (unsigned long long)stats->tx_packets); + seq_printf(m, "tx_bytes: %llu\n", (unsigned long long)stats->tx_bytes); + for (qi = 0; qi < dev->pdma_dev.ctrl.nb_txq; qi++) { + seq_printf(m, "tx_packets[%d]: %llu\n", qi, (unsigned long long)stats->txq_packets[qi]); + seq_printf(m, "tx_bytes[%d]: %llu\n", qi, (unsigned long long)stats->txq_bytes[qi]); + } + seq_printf(m, "tx_dropped: %llu\n", (unsigned long long)stats->tx_dropped); + seq_printf(m, "tx_errors: %llu\n", (unsigned long long)stats->tx_errors); + seq_printf(m, "tx_xoffs: %llu\n", (unsigned long long)stats->tx_xoffs); + seq_printf(m, "interrupts: %llu\n", (unsigned long long)stats->intrs); + } + + if (!ai) { + seq_printf(m, "%s\n", "No active device"); + } else { + seq_printf(m, "------------------------\n"); + seq_printf(m, "Total %d devices\n", ai); + } + + return 0; +} + +static int +proc_pkt_stats_open(struct inode *inode, struct file *file) +{ + return single_open(file, proc_pkt_stats_show, NULL); +} + +static int +proc_pkt_stats_release(struct inode *inode, struct file *file) +{ + return single_release(inode, file); +} + +static struct file_operations proc_pkt_stats_fops = { + owner: THIS_MODULE, + open: proc_pkt_stats_open, + read: seq_read, + llseek: seq_lseek, + release: proc_pkt_stats_release, +}; + +static int +proc_rate_limit_show(struct seq_file *m, void *v) +{ + seq_printf(m, "Rx rate limit: %d pps\n", ngknet_rx_rate_limit_get()); + + return 0; +} + +static int +proc_rate_limit_open(struct inode *inode, struct file *file) +{ + return single_open(file, proc_rate_limit_show, NULL); +} + +static ssize_t +proc_rate_limit_write(struct file *file, const char *buf, + size_t count, loff_t *loff) +{ + char limit_str[9] = {0}; + int rate_limit; + + if (copy_from_user(limit_str, buf, sizeof(limit_str) - 1)) { + return -EFAULT; + } + rate_limit = simple_strtol(limit_str, NULL, 10); + + ngknet_rx_rate_limit_set(rate_limit); + printk("Rx rate limit set to: %d pps\n", rate_limit); + + return count; +} + +static int +proc_rate_limit_release(struct inode *inode, struct file *file) +{ + return single_release(inode, file); +} + +static struct file_operations proc_rate_limit_fops = { + owner: THIS_MODULE, + open: proc_rate_limit_open, + read: seq_read, + write: proc_rate_limit_write, + llseek: seq_lseek, + release: proc_rate_limit_release, +}; + +static int +proc_reg_status_show(struct seq_file *m, void *v) +{ + struct ngknet_dev *dev; + int di, qi, ai = 0; + + for (di = 0; di < NUM_PDMA_DEV_MAX; di++) { + dev = &ngknet_devices[di]; + if (!(dev->flags & NGKNET_DEV_ACTIVE)) { + continue; + } + ai++; + for (qi = 0; qi < dev->pdma_dev.ctrl.nb_rxq; qi++) { + bcmcnet_pdma_rx_queue_reg_dump(&dev->pdma_dev, qi); + } + for (qi = 0; qi < dev->pdma_dev.ctrl.nb_txq; qi++) { + bcmcnet_pdma_tx_queue_reg_dump(&dev->pdma_dev, qi); + } + } + + if (!ai) { + seq_printf(m, "%s\n", "No active device"); + } else { + seq_printf(m, "------------------------\n"); + seq_printf(m, "Total %d devices\n", ai); + } + + return 0; +} + +static int +proc_reg_status_open(struct inode *inode, struct file *file) +{ + return single_open(file, proc_reg_status_show, NULL); +} + +static int +proc_reg_status_release(struct inode *inode, struct file *file) +{ + return single_release(inode, file); +} + +static struct file_operations proc_reg_status_fops = { + owner: THIS_MODULE, + open: proc_reg_status_open, + read: seq_read, + llseek: seq_lseek, + release: proc_reg_status_release, +}; + +static int +proc_ring_status_show(struct seq_file *m, void *v) +{ + struct ngknet_dev *dev; + int di, qi, ai = 0; + + for (di = 0; di < NUM_PDMA_DEV_MAX; di++) { + dev = &ngknet_devices[di]; + if (!(dev->flags & NGKNET_DEV_ACTIVE)) { + continue; + } + ai++; + seq_printf(m, "%s-%d, ", "Unit", di); + for (qi = 0; qi < dev->pdma_dev.ctrl.nb_rxq; qi++) { + bcmcnet_pdma_rx_ring_dump(&dev->pdma_dev, qi); + } + seq_printf(m, "%s%d, ", "Rx queues: ", qi); + for (qi = 0; qi < dev->pdma_dev.ctrl.nb_txq; qi++) { + bcmcnet_pdma_tx_ring_dump(&dev->pdma_dev, qi); + } + seq_printf(m, "%s%d. ", "Tx queues: ", qi); + seq_printf(m, "\n"); + } + + if (!ai) { + seq_printf(m, "%s\n", "No active device"); + } else { + seq_printf(m, "------------------------\n"); + seq_printf(m, "Total %d devices\n", ai); + } + + return 0; +} + +static int +proc_ring_status_open(struct inode *inode, struct file *file) +{ + return single_open(file, proc_ring_status_show, NULL); +} + +static int +proc_ring_status_release(struct inode *inode, struct file *file) +{ + return single_release(inode, file); +} + +static struct file_operations proc_ring_status_fops = { + owner: THIS_MODULE, + open: proc_ring_status_open, + read: seq_read, + llseek: seq_lseek, + release: proc_ring_status_release, +}; + +int +ngknet_procfs_init(void) +{ + struct proc_dir_entry *entry = NULL; + + proc_root = proc_mkdir(NGKNET_MODULE_NAME, NULL); + if (proc_root == NULL) { + printk(KERN_ERR "ngknet: proc_mkdir failed\n"); + return -1; + } + + PROC_CREATE(entry, "debug_level", 0666, proc_root, &proc_debug_level_fops); + if (entry == NULL) { + printk(KERN_ERR "ngknet: proc_create failed\n"); + return -1; + } + + PROC_CREATE(entry, "device_info", 0444, proc_root, &proc_device_info_fops); + if (entry == NULL) { + printk(KERN_ERR "ngknet: proc_create failed\n"); + return -1; + } + + PROC_CREATE(entry, "filter_info", 0444, proc_root, &proc_filter_info_fops); + if (entry == NULL) { + printk(KERN_ERR "ngknet: proc_create failed\n"); + return -1; + } + + PROC_CREATE(entry, "netif_info", 0444, proc_root, &proc_netif_info_fops); + if (entry == NULL) { + printk(KERN_ERR "ngknet: proc_create failed\n"); + return -1; + } + + PROC_CREATE(entry, "pkt_stats", 0444, proc_root, &proc_pkt_stats_fops); + if (entry == NULL) { + printk(KERN_ERR "ngknet: proc_create failed\n"); + return -1; + } + + PROC_CREATE(entry, "rate_limit", 0666, proc_root, &proc_rate_limit_fops); + if (entry == NULL) { + printk(KERN_ERR "ngknet: proc_create failed\n"); + return -1; + } + + PROC_CREATE(entry, "reg_status", 0444, proc_root, &proc_reg_status_fops); + if (entry == NULL) { + printk(KERN_ERR "ngknet: proc_create failed\n"); + return -1; + } + + PROC_CREATE(entry, "ring_status", 0444, proc_root, &proc_ring_status_fops); + if (entry == NULL) { + printk(KERN_ERR "ngknet: proc_create failed\n"); + return -1; + } + + return 0; +} + +int +ngknet_procfs_cleanup(void) +{ + remove_proc_entry("debug_level", proc_root); + remove_proc_entry("device_info", proc_root); + remove_proc_entry("filter_info", proc_root); + remove_proc_entry("netif_info", proc_root); + remove_proc_entry("pkt_stats", proc_root); + remove_proc_entry("rate_limit", proc_root); + remove_proc_entry("reg_status", proc_root); + remove_proc_entry("ring_status", proc_root); + + remove_proc_entry(NGKNET_MODULE_NAME, NULL); + + return 0; +} + diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_procfs.h b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_procfs.h new file mode 100644 index 000000000000..3c1938121ebb --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_procfs.h @@ -0,0 +1,47 @@ +/*! \file ngknet_procfs.h + * + * Procfs-related definitions and APIs for NGKNET module. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#ifndef NGKNET_PROCFS_H +#define NGKNET_PROCFS_H + +/*! + * \brief Initialize procfs for KNET driver. + * + * Create procfs read/write interfaces. + * + * \return 0 if no errors, otherwise -1. + */ +extern int +ngknet_procfs_init(void); + +/*! + * \brief Clean up procfs for KNET driver. + * + * Clean up resources allocated by \ref ngknet_procfs_init. + * + * \return 0 if no errors, otherwise -1. + */ +extern int +ngknet_procfs_cleanup(void); + +#endif /* NGKNET_PROCFS_H */ + diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_ptp.c b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_ptp.c new file mode 100644 index 000000000000..13579208eab0 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_ptp.c @@ -0,0 +1,194 @@ +/*! \file ngknet_ptp.c + * + * Utility routines for PTP. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include "ngknet_callback.h" +#include "ngknet_ptp.h" + +int +ngknet_ptp_rx_config_set(struct net_device *ndev, int *filter) +{ + struct ngknet_private *priv = netdev_priv(ndev); + struct ngknet_dev *dev = priv->bkn_dev; + + if (!dev->cbc->ptp_rx_config_set_cb) { + return SHR_E_UNAVAIL; + } + + /* + * The expected Rx filter value is passed to the callback. The callback + * should pass back the actual filter value by the paramter . + * The callback can use priv->user_data to get other private parameters + * such as phys_port, dev_type, etc, which should be introduced when the + * netif is created. + */ + return dev->cbc->ptp_rx_config_set_cb(priv, filter); +} + +int +ngknet_ptp_tx_config_set(struct net_device *ndev, int type) +{ + struct ngknet_private *priv = netdev_priv(ndev); + struct ngknet_dev *dev = priv->bkn_dev; + + if (!dev->cbc->ptp_tx_config_set_cb) { + return SHR_E_UNAVAIL; + } + + /* + * The Tx type value is passed to the callback by the parameter . + * The callback should do the configuration according to the type. + * The callback can use priv->user_data to get other private parameters + * such as phys_port, dev_type, etc, which should be introduced when the + * netif is created. + */ + return dev->cbc->ptp_tx_config_set_cb(priv, &type); +} + +int +ngknet_ptp_rx_hwts_get(struct net_device *ndev, struct sk_buff *skb, uint64_t *ts) +{ + struct ngknet_private *priv = netdev_priv(ndev); + struct ngknet_dev *dev = priv->bkn_dev; + struct ngknet_callback_desc *cbd = NGKNET_SKB_CB(skb); + struct pkt_hdr *pkh = (struct pkt_hdr *)skb->data; + + if (!dev->cbc->ptp_rx_hwts_get_cb) { + return SHR_E_UNAVAIL; + } + + cbd->dev_no = dev->dev_no; + cbd->dev_id = dev->pdma_dev.dev_id; + cbd->priv = priv; + cbd->pmd = skb->data + PKT_HDR_SIZE; + cbd->pmd_len = pkh->meta_len; + cbd->pkt_len = pkh->data_len; + + /* + * The callback should get timestamp value for a Rx packet and return + * by the parameter . + * Some parameters have been consolidated to SKB as above. They can be + * achieved by NGKNET_SKB_CB(skb). Specially more private paramters are + * in NGKNET_SKB_CB(skb)->priv->user_data[]. + */ + return dev->cbc->ptp_rx_hwts_get_cb(skb, ts); +} + +int +ngknet_ptp_tx_hwts_get(struct net_device *ndev, struct sk_buff *skb, uint64_t *ts) +{ + struct ngknet_private *priv = netdev_priv(ndev); + struct ngknet_dev *dev = priv->bkn_dev; + struct ngknet_callback_desc *cbd = NGKNET_SKB_CB(skb); + struct pkt_hdr *pkh = (struct pkt_hdr *)skb->data; + + if (!dev->cbc->ptp_tx_hwts_get_cb) { + return SHR_E_UNAVAIL; + } + + cbd->dev_no = dev->dev_no; + cbd->dev_id = dev->pdma_dev.dev_id; + cbd->priv = priv; + cbd->pmd = skb->data + PKT_HDR_SIZE; + cbd->pmd_len = pkh->meta_len; + cbd->pkt_len = pkh->data_len; + + /* + * The callback should get timestamp value for a Tx packet and return + * by the parameter . + * For HWTSTAMP_TX_ONESTEP_SYNC type, the time value can be achieved and + * returned immediately. Otherwise, for HWTSTAMP_TX_ON type, the callback + * should wait till the time value can be available, i.e. the packet has + * been tranmitted out from port. + * Some parameters have been consolidated to SKB as above. They can be + * achieved by NGKNET_SKB_CB(skb). Specially more private paramters are + * in NGKNET_SKB_CB(skb)->priv->user_data[] such as phys_port, dev_type, + * and so on. + */ + return dev->cbc->ptp_tx_hwts_get_cb(skb, ts); +} + +int +ngknet_ptp_tx_meta_set(struct net_device *ndev, struct sk_buff *skb) +{ + struct ngknet_private *priv = netdev_priv(ndev); + struct ngknet_dev *dev = priv->bkn_dev; + struct ngknet_callback_desc *cbd = NGKNET_SKB_CB(skb); + struct pkt_hdr *pkh = (struct pkt_hdr *)skb->data; + + if (!dev->cbc->ptp_tx_meta_set_cb) { + return SHR_E_UNAVAIL; + } + + cbd->dev_no = dev->dev_no; + cbd->dev_id = dev->pdma_dev.dev_id; + cbd->priv = priv; + cbd->pmd = skb->data + PKT_HDR_SIZE; + cbd->pmd_len = pkh->meta_len; + cbd->pkt_len = pkh->data_len; + + /* + * The callback should configure the metadata pmd> + * for HW timestamping according to the corresponding switch device. + * Some parameters have been consolidated to SKB as above. They can be + * achieved by NGKNET_SKB_CB(skb). Specially more private paramters are + * in NGKNET_SKB_CB(skb)->priv->user_data[] such as phys_port, dev_type, + * and so on. + */ + return dev->cbc->ptp_tx_meta_set_cb(skb); +} + +int +ngknet_ptp_phc_index_get(struct net_device *ndev, int *index) +{ + struct ngknet_private *priv = netdev_priv(ndev); + struct ngknet_dev *dev = priv->bkn_dev; + + if (!dev->cbc->ptp_phc_index_get_cb) { + return SHR_E_UNAVAIL; + } + + /* + * The callback should return the HPC index by the parameter . + * priv->user_data[] can be used to get other private parameters such as + * phys_port, dev_type, etc, which should be introduced when the netif is + * created. + */ + return dev->cbc->ptp_phc_index_get_cb(priv, index); +} + +int +ngknet_ptp_dev_ctrl(struct ngknet_dev *dev, int cmd, char *data, int len) +{ + if (!dev->cbc->ptp_dev_ctrl_cb) { + return SHR_E_UNAVAIL; + } + + /* + * The callback is IOCTL dispatcher for PTP driver/module. + * The parameter is the command defined by the user. The parameter + * and are used for interactions between the user application + * and the driver for PTP device start/stop, enable/disable, set/get, and + * so on. + */ + return dev->cbc->ptp_dev_ctrl_cb(dev, cmd, data, len); +} + diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_ptp.h b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_ptp.h new file mode 100644 index 000000000000..86dcb6c4904a --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_ptp.h @@ -0,0 +1,111 @@ +/*! \file ngknet_ptp.h + * + * Definitions and APIs declaration for PTP. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#ifndef NGKNET_PTP_H +#define NGKNET_PTP_H + +#include +#include "ngknet_main.h" + +/*! + * \brief PTP Rx config set. + * + * \param [in] ndev Network device structure point. + * \param [in] filter Rx filter. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_ptp_rx_config_set(struct net_device *ndev, int *filter); + +/*! + * \brief PTP Tx config set. + * + * \param [in] ndev Network device structure point. + * \param [in] type Tx type. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_ptp_tx_config_set(struct net_device *ndev, int type); + +/*! + * \brief PTP Rx HW timestamping get. + * + * \param [in] ndev Network device structure point. + * \param [in] skb Rx packet SKB. + * \param [out] ts Timestamp value. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_ptp_rx_hwts_get(struct net_device *ndev, struct sk_buff *skb, uint64_t *ts); + +/*! + * \brief PTP Tx HW timestamping get. + * + * \param [in] ndev Network device structure point. + * \param [in] skb Tx packet SKB. + * \param [out] ts Timestamp value. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_ptp_tx_hwts_get(struct net_device *ndev, struct sk_buff *skb, uint64_t *ts); + +/*! + * \brief PTP Tx meta set. + * + * \param [in] ndev Network device structure point. + * \param [in] skb Tx packet SKB. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_ptp_tx_meta_set(struct net_device *ndev, struct sk_buff *skb); + +/*! + * \brief PTP PHC index get. + * + * \param [in] ndev Network device structure point. + * \param [out] index PHC index. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_ptp_phc_index_get(struct net_device *ndev, int *index); + +/*! + * \brief PTP device control. + * + * \param [in] dev NGKNET device structure point. + * \param [in] cmd Command. + * \param [in] data Data buffer. + * \param [in] len Data length. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_ptp_dev_ctrl(struct ngknet_dev *dev, int cmd, char *data, int len); + +#endif /* NGKNET_PTP_H */ + diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/Kbuild b/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/Kbuild new file mode 100644 index 000000000000..2ce66edb3c63 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/Kbuild @@ -0,0 +1,36 @@ +# -*- Kbuild -*- +# +# Linux KNET Callback module. +# +# $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. +# The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# version 2 as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# A copy of the GNU General Public License version 2 (GPLv2) can +# be found in the LICENSES folder.$ +# +ifeq ($(BUILD_PSAMPLE),1) +PSAMPLE_CFLAGS=-DPSAMPLE_SUPPORT +PSAMPLE_CB_OBJS=psample-cb.o +endif + +obj-m := linux_ngknetcb.o + +ccflags-y := $(LKM_CFLAGS) \ + -I$(SDK)/shr/include \ + -I$(SDK)/bcmdrd/include \ + -I$(SDK)/linux/include \ + -I$(SDK)/linux/knet/include \ + -I$(SDK)/linux/knet \ + $(PSAMPLE_CFLAGS) + +linux_ngknetcb-y := ngknetcb_main.o \ + $(PSAMPLE_CB_OBJS) diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/Makefile b/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/Makefile new file mode 100644 index 000000000000..e2acfed49d6c --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/Makefile @@ -0,0 +1,33 @@ +# -*- Makefile -*- +# +# Linux KNET Callback module. +# +# $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. +# The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# version 2 as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# A copy of the GNU General Public License version 2 (GPLv2) can +# be found in the LICENSES folder.$ +# + +include Kbuild + +ifeq ($(KERNELRELEASE),) + +MOD_NAME = linux_ngknetcb + +include $(SDK)/make/lkm.mk + +endif + +.PHONY: distclean + +distclean: diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/ngknetcb_main.c b/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/ngknetcb_main.c new file mode 100644 index 000000000000..aa248dafce52 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/ngknetcb_main.c @@ -0,0 +1,444 @@ +/*! \file ngknetcb_main.c + * + * NGKNET Callback module entry. + */ +/* + * $Copyright: (c) 2019 Broadcom. + * Broadcom Proprietary and Confidential. All rights reserved.$ + */ + +#include +#include +#include "psample-cb.h" + +/*! \cond */ +MODULE_AUTHOR("Broadcom Corporation"); +MODULE_DESCRIPTION("NGKNET Callback Module"); +MODULE_LICENSE("GPL"); +/*! \endcond */ + +/*! \cond */ +int debug = 0; +MODULE_PARAM(debug, int, 0); +MODULE_PARM_DESC(debug, +"Debug level (default 0)"); +/*! \endcond */ + +/*! Module information */ +#define NGKNETCB_MODULE_NAME "linux_ngknetcb" +#define NGKNETCB_MODULE_MAJOR 122 + +/* set KNET_CB_DEBUG for debug info */ +#define KNET_CB_DEBUG + +/* These below need to match incoming enum values */ +#define FILTER_TAG_STRIP 0 +#define FILTER_TAG_KEEP 1 +#define FILTER_TAG_ORIGINAL 2 + +/* Maintain tag strip statistics */ +struct strip_stats_s { + unsigned long stripped; /* Number of packets that have been stripped */ + unsigned long checked; + unsigned long skipped; +}; + +static struct strip_stats_s strip_stats; +static unsigned int rx_count = 0; + +/* Local function prototypes */ +static void strip_vlan_tag(struct sk_buff *skb); + +/* Remove VLAN tag for select TPIDs */ +static void +strip_vlan_tag(struct sk_buff *skb) +{ + uint16_t vlan_proto; + uint8_t *pkt = skb->data; + + vlan_proto = (uint16_t) ((pkt[12] << 8) | pkt[13]); + if ((vlan_proto == 0x8100) || (vlan_proto == 0x88a8) || (vlan_proto == 0x9100)) { + /* Move first 12 bytes of packet back by 4 */ + memmove(&skb->data[4], skb->data, 12); + skb_pull(skb, 4); /* Remove 4 bytes from start of buffer */ + } +} + +/* + * The function get_tag_status() returns the tag status. + * 0 = Untagged + * 1 = Single inner-tag + * 2 = Single outer-tag + * 3 = Double tagged. + * -1 = Unsupported type + */ +static int +get_tag_status(uint32_t dev_type, void *meta) +{ + uint32_t *valptr; + uint32_t fd_index; + uint32_t outer_l2_hdr; + int tag_status = -1; + + if ((dev_type == 0xb880) || (dev_type == 0xb780)) + { + /* Field BCM_PKTIO_RXPMD_MATCH_ID_LO has tag status in RX PMD */ + fd_index = 2; + valptr = (uint32_t *)meta; + outer_l2_hdr = (valptr[fd_index] >> ((dev_type == 0xb780) ? 2 : 1) & 0xFF); + + if (outer_l2_hdr & 0x1) { +#ifdef KNET_CB_DEBUG + if (debug & 0x1) { + printk(" L2 Header Present\n"); + } +#endif + tag_status = 0; + if (outer_l2_hdr & 0x4) { +#ifdef KNET_CB_DEBUG + if (debug & 0x1) { + printk(" SNAP/LLC\n"); + } +#endif + tag_status = 0; + } + if (outer_l2_hdr & 0x10) { +#ifdef KNET_CB_DEBUG + if (debug & 0x1) { + printk(" Outer Tagged\n"); + } +#endif + tag_status = 2; + if (outer_l2_hdr & 0x20) { +#ifdef KNET_CB_DEBUG + if (debug & 0x1) { + printk(" Double Tagged\n"); + } +#endif + tag_status = 3; + } + } + else if (outer_l2_hdr & 0x20) { +#ifdef KNET_CB_DEBUG + if (debug & 0x1) { + printk(" Inner Tagged\n"); + } +#endif + tag_status = 1; + } + } + } + else if ((dev_type == 0xb990)|| (dev_type == 0xb996)) + { + fd_index = 9; + valptr = (uint32_t *)meta; + /* On TH4, outer_l2_header means INCOMING_TAG_STATUS. + * TH4 only supports single tagging, so if TAG_STATUS + * says there's a tag, then we don't want to strip. + * Otherwise, we do. + */ + outer_l2_hdr = (valptr[fd_index] >> 13) & 3; + + if (outer_l2_hdr) + { + tag_status = 2; +#ifdef KNET_CB_DEBUG + if (debug & 0x1) + { + printk(" Incoming frame tagged\n"); + } +#endif + } + else + { + tag_status = 0; +#ifdef KNET_CB_DEBUG + if (debug & 0x1) + { + printk(" Incoming frame untagged\n"); + } +#endif + } + } +#ifdef KNET_CB_DEBUG + if (debug & 0x1) { + printk("%s; Device Type: %d; tag status: %d\n", __func__, dev_type, tag_status); + } +#endif + return tag_status; +} + +#ifdef KNET_CB_DEBUG +static void +dump_buffer(uint8_t * data, int size) +{ + const char *const to_hex = "0123456789ABCDEF"; + int i; + char buffer[128]; + char *buffer_ptr; + int addr = 0; + + buffer_ptr = buffer; + for (i = 0; i < size; i++) { + *buffer_ptr++ = ' '; + *buffer_ptr++ = to_hex[(data[i] >> 4) & 0xF]; + *buffer_ptr++ = to_hex[data[i] & 0xF]; + if (((i % 16) == 15) || (i == size - 1)) { + *buffer_ptr = '\0'; + buffer_ptr = buffer; + printk(KERN_INFO "%04X %s\n", addr, buffer); + addr = i + 1; + } + } +} + +static void +show_pmd(uint8_t *pmd, int len) +{ + if (debug & 0x1) { + printk("PMD (%d bytes):\n", len); + dump_buffer(pmd, len); + } +} + +static void +show_mac(uint8_t *pkt) +{ + if (debug & 0x1) { + printk("DMAC=%02X:%02X:%02X:%02X:%02X:%02X\n", + pkt[0], pkt[1], pkt[2], pkt[3], pkt[4], pkt[5]); + } +} +#endif + +static struct sk_buff * +strip_tag_rx_cb(struct sk_buff *skb) +{ + const struct ngknet_callback_desc *cbd = NGKNET_SKB_CB(skb); + const struct ngknet_private *priv = cbd->priv; + int rcpu_mode = 0; + int tag_status; + + rcpu_mode = (priv->flags & NGKNET_NETIF_F_RCPU_ENCAP)? 1 : 0; +#ifdef KNET_CB_DEBUG + if (debug & 0x1) + { + printk(KERN_INFO + "\n%4u --------------------------------------------------------------------------------\n", + rx_count); + printk(KERN_INFO + "RX KNET callback: dev_no=%1d; dev_id=0x%04X; type_str=%4s; RCPU: %3s \n", + cbd->dev_no, cbd->dev_id, cbd->type_str, rcpu_mode ? "yes" : "no"); + printk(KERN_INFO " pkt_len=%4d; pmd_len=%2d; SKB len: %4d\n", + cbd->pkt_len, cbd->pmd_len, skb->len); + if (cbd->filt) { + printk(KERN_INFO "Filter user data: 0x%08x\n", + *(uint32_t *) cbd->filt->user_data); + } + printk(KERN_INFO "Before SKB (%d bytes):\n", skb->len); + dump_buffer(skb->data, skb->len); + printk("rx_cb for dev %d: id 0x%x, %s\n", cbd->dev_no, cbd->dev_id, cbd->type_str); + printk("netif user data: 0x%08x\n", *(uint32_t *)cbd->priv->user_data); + show_pmd(cbd->pmd, cbd->pmd_len); + if (rcpu_mode) { + const int RCPU_header_len = PKT_HDR_SIZE + cbd->pmd_len; + const int payload_len = skb->len - RCPU_header_len; + unsigned char *payload_start = skb->data + payload_len; + + printk(KERN_INFO "Packet Payload (%d bytes):\n", payload_len); + dump_buffer(payload_start, payload_len); + } else { + printk(KERN_INFO "Packet (%d bytes):\n", cbd->pkt_len); + dump_buffer(skb->data, cbd->pkt_len); + } + } +#endif + + if ((!rcpu_mode) && (cbd->filt)) { + if (FILTER_TAG_ORIGINAL == cbd->filt->user_data[0]) { + tag_status = get_tag_status(cbd->dev_id, (void *)cbd->pmd); + if (tag_status < 0) { + strip_stats.skipped++; + goto _strip_tag_rx_cb_exit; + } + strip_stats.checked++; + if (tag_status < 2) { + strip_stats.stripped++; + strip_vlan_tag(skb); + } + } + } +_strip_tag_rx_cb_exit: +#ifdef KNET_CB_DEBUG + if (debug & 0x1) { + printk(KERN_INFO "After SKB (%d bytes):\n", skb->len); + dump_buffer(skb->data, skb->len); + printk(KERN_INFO + "\n%4u --------------------------------------------------------------------------------\n", + rx_count++); + } +#endif + return skb; +} + +static struct sk_buff * +strip_tag_tx_cb(struct sk_buff *skb) +{ +#ifdef KNET_CB_DEBUG + struct ngknet_callback_desc *cbd = NGKNET_SKB_CB(skb); + + if (debug & 0x1) { + printk("tx_cb for dev %d: %s\n", cbd->dev_no, cbd->type_str); + } + show_pmd(cbd->pmd, cbd->pmd_len); + show_mac(cbd->pmd + cbd->pmd_len); +#endif + return skb; +} + +static struct sk_buff * +ngknet_rx_cb(struct sk_buff *skb) +{ + skb = strip_tag_rx_cb(skb); +#ifdef PSAMPLE_SUPPORT + skb = psample_rx_cb(skb); +#endif + return skb; +} + +static struct sk_buff * +ngknet_tx_cb(struct sk_buff *skb) +{ + skb = strip_tag_tx_cb(skb); + return skb; +} + +static int +ngknet_netif_create_cb(struct net_device *dev) +{ + int retv = 0; +#ifdef PSAMPLE_SUPPORT + retv = psample_netif_create_cb(dev); +#endif + return retv; +} + +static int +ngknet_netif_destroy_cb(struct net_device *dev) +{ + int retv = 0; +#ifdef PSAMPLE_SUPPORT + retv = psample_netif_destroy_cb(dev); +#endif + return retv; +} + +/*! + * Generic module functions + */ +static int +ngknetcb_show(struct seq_file *m, void *v) +{ + seq_printf(m, "Broadcom Linux NGKNET Callback: Untagged VLAN Stripper\n"); + seq_printf(m, " %lu stripped packets\n", strip_stats.stripped); + seq_printf(m, " %lu packets checked\n", strip_stats.checked); + seq_printf(m, " %lu packets skipped\n", strip_stats.skipped); + return 0; +} + +static int +ngknetcb_open(struct inode *inode, struct file *filp) +{ + return single_open(filp, ngknetcb_show, NULL); +} + +static int +ngknetcb_release(struct inode *inode, struct file *filp) +{ + return 0; +} + +static ssize_t +ngknetcb_write(struct file *file, const char *buf, + size_t count, loff_t *loff) +{ + memset(&strip_stats, 0, sizeof(strip_stats)); + printk("Cleared NGKNET callback stats\n"); + return count; +} + +static long +ngknetcb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + return 0; +} + +static int +ngknetcb_mmap(struct file *filp, struct vm_area_struct *vma) +{ + return 0; +} + +static struct file_operations ngknetcb_fops = { + .owner = THIS_MODULE, + .open = ngknetcb_open, + .read = seq_read, + .write = ngknetcb_write, + .llseek = seq_lseek, + .release = ngknetcb_release, + .unlocked_ioctl = ngknetcb_ioctl, + .compat_ioctl = ngknetcb_ioctl, + .mmap = ngknetcb_mmap, +}; + +static int __init +ngknetcb_init_module(void) +{ + int rv; + struct proc_dir_entry *entry = NULL; + + rv = register_chrdev(NGKNETCB_MODULE_MAJOR, NGKNETCB_MODULE_NAME, &ngknetcb_fops); + if (rv < 0) { + printk(KERN_WARNING "%s: can't get major %d\n", + NGKNETCB_MODULE_NAME, NGKNETCB_MODULE_MAJOR); + return rv; + } + + PROC_CREATE(entry, NGKNETCB_MODULE_NAME, 0666, NULL, &ngknetcb_fops); + if (entry == NULL) { + printk(KERN_ERR "%s: proc_mkdir failed\n", + NGKNETCB_MODULE_NAME); + } + + ngknet_rx_cb_register(ngknet_rx_cb); + ngknet_tx_cb_register(ngknet_tx_cb); + +#ifdef PSAMPLE_SUPPORT + psample_init(); +#endif + + ngknet_netif_create_cb_register(ngknet_netif_create_cb); + ngknet_netif_destroy_cb_register(ngknet_netif_destroy_cb); + return 0; +} + +static void __exit +ngknetcb_exit_module(void) +{ + ngknet_netif_create_cb_unregister(ngknet_netif_create_cb); + ngknet_netif_destroy_cb_unregister(ngknet_netif_destroy_cb); + +#ifdef PSAMPLE_SUPPORT + psample_cleanup(); +#endif + + ngknet_rx_cb_unregister(ngknet_rx_cb); + ngknet_tx_cb_unregister(ngknet_tx_cb); + + remove_proc_entry(NGKNETCB_MODULE_NAME, NULL); + + unregister_chrdev(NGKNETCB_MODULE_MAJOR, NGKNETCB_MODULE_NAME); +} + +module_init(ngknetcb_init_module); +module_exit(ngknetcb_exit_module); diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/psample-cb.c b/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/psample-cb.c new file mode 100644 index 000000000000..be34430218d3 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/psample-cb.c @@ -0,0 +1,995 @@ +/* + * Copyright 2017-2019 Broadcom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2, as + * published by the Free Software Foundation (the "GPL"). + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 (GPLv2) for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 (GPLv2) along with this source code. + */ +/* + * $Id: psample_cb.c $ + * $Copyright: (c) 2019 Broadcom Corp. + * All Rights Reserved.$ + */ + +/* + * Driver for call-back functions for Linux KNET driver. + * + * This code is used to integrate packet sampling KNET callback to + * the psample infra for sending sampled pkts to userspace sflow + * applications such as Host Sflow (https://github.com/sflow/host-sflow) + * using genetlink interfaces. + * + * The module can be built from the standard Linux user mode target + * directories using the following command (assuming bash), e.g. + * + * cd $SDK/systems/linux/user/ + * make BUILD_KNET_CB=1 + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "psample-cb.h" + +#define PSAMPLE_CB_DBG +#ifdef PSAMPLE_CB_DBG +extern int debug; +#define PSAMPLE_CB_DBG_LVL_VERB (0x1) +#define PSAMPLE_CB_DBG_LVL_PMD (0x2) +#define PSAMPLE_CB_DBG_PRINT(...) if (debug & PSAMPLE_CB_DBG_LVL_VERB) { printk(__VA_ARGS__); } +#define PSAMPLE_CB_PMD_PRINT(...) if (debug & PSAMPLE_CB_DBG_LVL_PMD) { printk(__VA_ARGS__); } +#else +#define PSAMPLE_CB_DBG_PRINT(...) +#define PSAMPLE_CB_PMD_PRINT(...) +#endif + +#define FCS_SZ 4 +#define PSAMPLE_NLA_PADDING 4 +#define PSAMPLE_PKT_HANDLED (1) + +#define PSAMPLE_RATE_DFLT 1 +#define PSAMPLE_SIZE_DFLT 128 +static int psample_size = PSAMPLE_SIZE_DFLT; +MODULE_PARAM(psample_size, int, 0); +MODULE_PARM_DESC(psample_size, +"psample pkt size (default 128 bytes)"); + +#define PSAMPLE_QLEN_DFLT 1024 +static int psample_qlen = PSAMPLE_QLEN_DFLT; +MODULE_PARAM(psample_qlen, int, 0); +MODULE_PARM_DESC(psample_qlen, +"psample queue length (default 1024 buffers)"); + +/* driver proc entry root */ +static struct proc_dir_entry *psample_proc_root = NULL; +static struct proc_dir_entry *knet_cb_proc_root = NULL; + +/* psample general info */ +typedef struct { + struct list_head netif_list; + int netif_count; + struct net *netns; + spinlock_t lock; + int dcb_type; +} psample_info_t; +static psample_info_t g_psample_info = {0}; + +/* Maintain sampled pkt statistics */ +typedef struct psample_stats_s { + unsigned long pkts_f_psample_cb; + unsigned long pkts_f_psample_mod; + unsigned long pkts_f_handled; + unsigned long pkts_f_pass_through; + unsigned long pkts_f_dst_mc; + unsigned long pkts_c_qlen_cur; + unsigned long pkts_c_qlen_hi; + unsigned long pkts_d_qlen_max; + unsigned long pkts_d_no_mem; + unsigned long pkts_d_no_group; + unsigned long pkts_d_sampling_disabled; + unsigned long pkts_d_not_ready; + unsigned long pkts_d_metadata; + unsigned long pkts_d_skb; + unsigned long pkts_d_skb_cbd; + unsigned long pkts_d_meta_srcport; + unsigned long pkts_d_meta_dstport; + unsigned long pkts_d_invalid_size; +} psample_stats_t; +static psample_stats_t g_psample_stats = {0}; + +typedef struct psample_meta_s { + int trunc_size; + int src_ifindex; + int dst_ifindex; + int sample_rate; +} psample_meta_t; + +typedef struct psample_pkt_s { + struct list_head list; + struct psample_group *group; + psample_meta_t meta; + struct sk_buff *skb; +} psample_pkt_t; + +typedef struct psample_work_s { + struct list_head pkt_list; + struct work_struct wq; + spinlock_t lock; +} psample_work_t; +static psample_work_t g_psample_work = {0}; + +static psample_netif_t* +psample_netif_lookup_by_ifindex(int ifindex) +{ + struct list_head *list; + psample_netif_t *psample_netif = NULL; + unsigned long flags; + + /* look for port from list of available net_devices */ + spin_lock_irqsave(&g_psample_info.lock, flags); + list_for_each(list, &g_psample_info.netif_list) { + psample_netif = (psample_netif_t*)list; + if (psample_netif->dev->ifindex == ifindex) { + spin_unlock_irqrestore(&g_psample_info.lock, flags); + return psample_netif; + } + } + spin_unlock_irqrestore(&g_psample_info.lock, flags); + return (NULL); +} + +static psample_netif_t* +psample_netif_lookup_by_port(int port) +{ + struct list_head *list; + psample_netif_t *psample_netif = NULL; + unsigned long flags; + + /* look for port from list of available net_devices */ + spin_lock_irqsave(&g_psample_info.lock, flags); + list_for_each(list, &g_psample_info.netif_list) { + psample_netif = (psample_netif_t*)list; + if (psample_netif->port == port) { + spin_unlock_irqrestore(&g_psample_info.lock, flags); + return psample_netif; + } + } + spin_unlock_irqrestore(&g_psample_info.lock, flags); + return (NULL); +} + +static int +psample_meta_sample_reason(uint8_t *pkt, void *pkt_meta) +{ + uint32_t *metadata = (uint32_t*)pkt_meta; + uint32_t reason = 0; + uint32_t reason_hi = 0; + uint32_t sample_rx_reason_mask = 0; + + if (metadata) { + /* Sample Pkt reason code (bcmRxReasonSampleSource) */ + switch(g_psample_info.dcb_type) { + case 36: /* TD3 */ + case 38: /* TH3 */ + reason_hi = *(metadata + 4); + reason = *(metadata + 5); + sample_rx_reason_mask = (1 << 3); + break; + case 32: /* TH1/TH2 */ + case 26: /* TD2 */ + case 23: /* HX4 */ + reason_hi = *(metadata + 2); + reason = *(metadata + 3); + sample_rx_reason_mask = (1 << 5); + break; + default: + break; + } + } + PSAMPLE_CB_DBG_PRINT("%s: DCB%d sample_rx_reason_mask: 0x%08x, reason: 0x%08x, reason_hi: 0x%08x\n", + __func__, g_psample_info.dcb_type, sample_rx_reason_mask, reason, reason_hi); + + /* Check if only sample reason code is set. + * If only sample reason code, then consume pkt. + * If other reason codes exist, then pkt should be + * passed through to Linux network stack. + */ + if ((reason & ~sample_rx_reason_mask) || reason_hi) { + return 0; /* multiple reasons set, pass through */ + } + + /* only sample rx reason set, consume pkt */ + return (PSAMPLE_PKT_HANDLED); +} + +static int +psample_meta_get(struct sk_buff *skb, psample_meta_t *sflow_meta) +{ + int src_ifindex = 0; + int sample_rate = 1; + int sample_size = PSAMPLE_SIZE_DFLT; + psample_netif_t *psample_netif = NULL; + const struct ngknet_callback_desc *cbd = NGKNET_SKB_CB(skb); + const struct ngknet_private *netif = cbd->priv; + memset(sflow_meta, 0, sizeof(psample_meta_t)); + + /* find src port */ + if ((psample_netif = psample_netif_lookup_by_ifindex(netif->net_dev->ifindex))) { + src_ifindex = psample_netif->dev->ifindex; + sample_rate = psample_netif->sample_rate; + sample_size = psample_netif->sample_size; + } else { + g_psample_stats.pkts_d_meta_srcport++; + PSAMPLE_CB_DBG_PRINT("%s: could not find psample netif for src dev %s (ifidx %d)\n", + __func__, netif->net_dev->name, netif->net_dev->ifindex); + } + + sflow_meta->src_ifindex = src_ifindex; + sflow_meta->trunc_size = sample_size; + sflow_meta->sample_rate = sample_rate; + return (0); +} + +static void +psample_task(struct work_struct *work) +{ + psample_work_t *psample_work = container_of(work, psample_work_t, wq); + unsigned long flags; + struct list_head *list_ptr, *list_next; + psample_pkt_t *pkt; + + spin_lock_irqsave(&psample_work->lock, flags); + list_for_each_safe(list_ptr, list_next, &psample_work->pkt_list) { + /* dequeue pkt from list */ + pkt = list_entry(list_ptr, psample_pkt_t, list); + list_del(list_ptr); + g_psample_stats.pkts_c_qlen_cur--; + spin_unlock_irqrestore(&psample_work->lock, flags); + + /* send to psample */ + if (pkt) { + PSAMPLE_CB_DBG_PRINT("%s: group 0x%x, trunc_size %d, src_ifdx 0x%x, dst_ifdx 0x%x, sample_rate %d\n", + __func__, pkt->group->group_num, + pkt->meta.trunc_size, pkt->meta.src_ifindex, + pkt->meta.dst_ifindex, pkt->meta.sample_rate); + + psample_sample_packet(pkt->group, + pkt->skb, + pkt->meta.trunc_size, + pkt->meta.src_ifindex, + pkt->meta.dst_ifindex, + pkt->meta.sample_rate); + g_psample_stats.pkts_f_psample_mod++; + + dev_kfree_skb_any(pkt->skb); + kfree(pkt); + } + spin_lock_irqsave(&psample_work->lock, flags); + } + spin_unlock_irqrestore(&psample_work->lock, flags); +} + +struct sk_buff* +psample_rx_cb(struct sk_buff *skb) +{ + struct psample_group *group; + psample_meta_t meta; + int rv = 0, size; + const struct ngknet_callback_desc *cbd = NULL; + const struct ngknet_private *netif = NULL; + const struct ngknet_filter_s *filt = NULL; + const struct ngknet_filter_s *filt_src = NULL; + + if (!skb) { + printk("%s: skb is NULL\n", __func__); + g_psample_stats.pkts_d_skb++; + return (NULL); + } + cbd = NGKNET_SKB_CB(skb); + netif = cbd->priv; + filt_src = cbd->filt; + filt = cbd->filt_cb; + + if (!cbd || !netif || !filt_src) { + printk("%s: cbd(0x%p) or priv(0x%p) or filter src(0x%p) is NULL\n", + __func__, cbd, netif, filt_src); + g_psample_stats.pkts_d_skb_cbd++; + return (skb); + } + + /* Enable PMD output in dmesg: "echo "debug=0x2" > /proc/bcm/knet-cb/psample/debug" + * Use bshell cmd "pmddecode rxpmd ..." to decode pkt metadata + */ + if (debug & PSAMPLE_CB_DBG_LVL_PMD) { + char str[128]; + int i, len = cbd->pmd_len > 128? 128 : cbd->pmd_len; + PSAMPLE_CB_PMD_PRINT("PMD (%d bytes): %s\n", + cbd->pmd_len, skb->dev->name); + for (i=0; ipmd+i))); + if ((i & 0x1c) == 0x1c) { + sprintf(&str[strlen(str)], "\n"); + printk(str); + continue; + } + } + if ((i & 0x1f) != 0) { + sprintf(&str[strlen(str)], "\n"); + PSAMPLE_CB_PMD_PRINT(str); + } + } + + /* check if this packet is sampled packet (from sample filter) */ + if (!filt || + (NGKNET_FILTER_DEST_T_CB != filt->dest_type) || + (strncmp(filt->desc, PSAMPLE_CB_NAME, NGKNET_FILTER_DESC_MAX) != 0)) { + return (skb); + } + + PSAMPLE_CB_DBG_PRINT("%s: src dev %s, pkt size %d, filt->dest_id %d\n", + __func__, skb->dev->name, cbd->pkt_len, filt->dest_id); + g_psample_stats.pkts_f_psample_cb++; + + /* get psample group info. psample genetlink group ID passed in filt->dest_id */ + group = psample_group_get(g_psample_info.netns, filt->dest_id); + if (!group) { + printk("%s: Could not find psample genetlink group %d\n", __func__, filt->dest_id); + g_psample_stats.pkts_d_no_group++; + goto PSAMPLE_FILTER_CB_PKT_HANDLED; + } + + /* get psample metadata */ + rv = psample_meta_get(skb, &meta); + if (rv < 0) { + printk("%s: Could not parse pkt metadata\n", __func__); + g_psample_stats.pkts_d_metadata++; + goto PSAMPLE_FILTER_CB_PKT_HANDLED; + } + + /* Adjust original pkt size to remove 4B FCS */ + size = cbd->pkt_len; + if (size < FCS_SZ) { + g_psample_stats.pkts_d_invalid_size++; + goto PSAMPLE_FILTER_CB_PKT_HANDLED; + } else { + size -= FCS_SZ; + } + + /* Account for padding in libnl used by psample */ + if (meta.trunc_size >= size) { + meta.trunc_size = size - PSAMPLE_NLA_PADDING; + } + + PSAMPLE_CB_DBG_PRINT("%s: group 0x%x, trunc_size %d, src_ifdx 0x%x, dst_ifdx 0x%x, sample_rate %d\n", + __func__, group->group_num, meta.trunc_size, meta.src_ifindex, meta.dst_ifindex, meta.sample_rate); + + /* drop if configured sample rate is 0 */ + if (meta.sample_rate > 0) { + unsigned long flags; + psample_pkt_t *psample_pkt; + struct sk_buff *skb_psample; + + if (g_psample_stats.pkts_c_qlen_cur >= psample_qlen) { + printk("%s: tail drop due to max qlen %d reached\n", __func__, psample_qlen); + g_psample_stats.pkts_d_qlen_max++; + goto PSAMPLE_FILTER_CB_PKT_HANDLED; + } + + if ((psample_pkt = kmalloc(sizeof(psample_pkt_t), GFP_ATOMIC)) == NULL) { + printk("%s: failed to alloc psample mem for pkt\n", __func__); + g_psample_stats.pkts_d_no_mem++; + goto PSAMPLE_FILTER_CB_PKT_HANDLED; + } + memcpy(&psample_pkt->meta, &meta, sizeof(psample_meta_t)); + psample_pkt->group = group; + + if ((skb_psample = dev_alloc_skb(meta.trunc_size)) == NULL) { + printk("%s: failed to alloc psample mem for pkt skb\n", __func__); + g_psample_stats.pkts_d_no_mem++; + goto PSAMPLE_FILTER_CB_PKT_HANDLED; + } + + /* setup skb to point to pkt */ + memcpy(skb_psample->data, skb->data, meta.trunc_size); + skb_put(skb_psample, meta.trunc_size); + skb_psample->len = meta.trunc_size; + psample_pkt->skb = skb_psample; + + spin_lock_irqsave(&g_psample_work.lock, flags); + list_add_tail(&psample_pkt->list, &g_psample_work.pkt_list); + + g_psample_stats.pkts_c_qlen_cur++; + if (g_psample_stats.pkts_c_qlen_cur > g_psample_stats.pkts_c_qlen_hi) { + g_psample_stats.pkts_c_qlen_hi = g_psample_stats.pkts_c_qlen_cur; + } + + schedule_work(&g_psample_work.wq); + spin_unlock_irqrestore(&g_psample_work.lock, flags); + } else { + g_psample_stats.pkts_d_sampling_disabled++; + } + +PSAMPLE_FILTER_CB_PKT_HANDLED: + /* if sample reason only, consume pkt. else pass through */ + rv = psample_meta_sample_reason(skb->data, cbd->pmd); + if (rv) { + g_psample_stats.pkts_f_handled++; + return NULL; + } + g_psample_stats.pkts_f_pass_through++; + return skb; +} + +int +psample_netif_create_cb(struct net_device *dev) +{ + int found; + struct list_head *list; + psample_netif_t *psample_netif, *lpsample_netif; + unsigned long flags; + struct ngknet_private *netif = NULL; + + if (!dev) { + printk("%s: net_device is NULL\n", __func__); + return (-1); + } + netif = netdev_priv(dev); + + if ((psample_netif = kmalloc(sizeof(psample_netif_t), GFP_ATOMIC)) == NULL) { + printk("%s: failed to alloc psample mem for netif '%s'\n", + __func__, dev->name); + return (-1); + } + + spin_lock_irqsave(&g_psample_info.lock, flags); + + psample_netif->dev = dev; + psample_netif->id = netif->id; + /* FIXME: port is not saved in ngknet_private, need to get from metadata?? */ + //psample_netif->port = netif->port; + psample_netif->vlan = netif->vlan; + psample_netif->sample_rate = PSAMPLE_RATE_DFLT; + psample_netif->sample_size = PSAMPLE_SIZE_DFLT; + + /* insert netif sorted by ID similar to bkn_knet_netif_create() */ + found = 0; + list_for_each(list, &g_psample_info.netif_list) { + lpsample_netif = (psample_netif_t*)list; + if (netif->id < lpsample_netif->id) { + found = 1; + g_psample_info.netif_count++; + break; + } + } + + if (found) { + /* Replace previously removed interface */ + list_add_tail(&psample_netif->list, &lpsample_netif->list); + } else { + /* No holes - add to end of list */ + list_add_tail(&psample_netif->list, &g_psample_info.netif_list); + } + + spin_unlock_irqrestore(&g_psample_info.lock, flags); + + PSAMPLE_CB_DBG_PRINT("%s: added psample netif '%s'\n", __func__, dev->name); + return (0); +} + +int +psample_netif_destroy_cb(struct net_device *dev) +{ + int found; + struct list_head *list; + psample_netif_t *psample_netif; + unsigned long flags; + struct ngknet_private *netif = NULL; + + if (!dev) { + printk("%s: net_device is NULL\n", __func__); + return (-1); + } + netif = netdev_priv(dev); + + spin_lock_irqsave(&g_psample_info.lock, flags); + + list_for_each(list, &g_psample_info.netif_list) { + psample_netif = (psample_netif_t*)list; + if (netif->id == psample_netif->id) { + found = 1; + list_del(&psample_netif->list); + PSAMPLE_CB_DBG_PRINT("%s: removing psample netif '%s'\n", __func__, dev->name); + kfree(psample_netif); + g_psample_info.netif_count--; + break; + } + } + + spin_unlock_irqrestore(&g_psample_info.lock, flags); + + if (!found) { + printk("%s: netif ID %d not found!\n", __func__, netif->id); + return (-1); + } + return (0); +} + +/* + * psample rate Proc Read Entry + */ +static int +psample_proc_rate_show(struct seq_file *m, void *v) +{ + struct list_head *list; + psample_netif_t *psample_netif; + unsigned long flags; + + spin_lock_irqsave(&g_psample_info.lock, flags); + + list_for_each(list, &g_psample_info.netif_list) { + psample_netif = (psample_netif_t*)list; + seq_printf(m, " %-14s %d\n", psample_netif->dev->name, psample_netif->sample_rate); + } + + spin_unlock_irqrestore(&g_psample_info.lock, flags); + + return 0; +} + +static int +psample_proc_rate_open(struct inode * inode, struct file * file) +{ + return single_open(file, psample_proc_rate_show, NULL); +} + +/* + * psample rate Proc Write Entry + * + * Syntax: + * = + * + * Where is a virtual network interface name. + * + * Examples: + * eth4=1000 + */ +static ssize_t +psample_proc_rate_write(struct file *file, const char *buf, + size_t count, loff_t *loff) +{ + int found; + struct list_head *list; + psample_netif_t *psample_netif; + char sample_str[40], *ptr, *newline; + unsigned long flags; + + + if (count > sizeof(sample_str)) { + count = sizeof(sample_str) - 1; + sample_str[count] = '\0'; + } + if (copy_from_user(sample_str, buf, count)) { + return -EFAULT; + } + sample_str[count] = 0; + newline = strchr(sample_str, '\n'); + if (newline) { + /* Chop off the trailing newline */ + *newline = '\0'; + } + + if ((ptr = strchr(sample_str, '=')) == NULL && + (ptr = strchr(sample_str, ':')) == NULL) { + printk("Error: Pkt sample rate syntax not recognized: '%s'\n", sample_str); + return count; + } + *ptr++ = 0; + + spin_lock_irqsave(&g_psample_info.lock, flags); + + found = 0; + list_for_each(list, &g_psample_info.netif_list) { + psample_netif = (psample_netif_t*)list; + if (strcmp(psample_netif->dev->name, sample_str) == 0) { + psample_netif->sample_rate = simple_strtol(ptr, NULL, 10); + // TODO MLI@BRCM - check valid sample rate + found = 1; + break; + } + } + + spin_unlock_irqrestore(&g_psample_info.lock, flags); + + if (!found) { + printk("Warning: Failed setting psample rate on unknown network interface: '%s'\n", sample_str); + } + return count; +} + +struct file_operations psample_proc_rate_file_ops = { + owner: THIS_MODULE, + open: psample_proc_rate_open, + read: seq_read, + llseek: seq_lseek, + write: psample_proc_rate_write, + release: single_release, +}; + +/* + * psample size Proc Read Entry + */ +static int +psample_proc_size_show(struct seq_file *m, void *v) +{ + struct list_head *list; + psample_netif_t *psample_netif; + unsigned long flags; + + spin_lock_irqsave(&g_psample_info.lock, flags); + + list_for_each(list, &g_psample_info.netif_list) { + psample_netif = (psample_netif_t*)list; + seq_printf(m, " %-14s %d\n", psample_netif->dev->name, psample_netif->sample_size); + } + + spin_unlock_irqrestore(&g_psample_info.lock, flags); + return 0; +} + +static int +psample_proc_size_open(struct inode * inode, struct file * file) +{ + return single_open(file, psample_proc_size_show, NULL); +} + +/* + * psample size Proc Write Entry + * + * Syntax: + * = + * + * Where is a virtual network interface name. + * + * Examples: + * eth4=128 + */ +static ssize_t +psample_proc_size_write(struct file *file, const char *buf, + size_t count, loff_t *loff) +{ + int found; + struct list_head *list; + psample_netif_t *psample_netif; + char sample_str[40], *ptr, *newline; + unsigned long flags; + + if (count > sizeof(sample_str)) { + count = sizeof(sample_str) - 1; + sample_str[count] = '\0'; + } + if (copy_from_user(sample_str, buf, count)) { + return -EFAULT; + } + sample_str[count] = 0; + newline = strchr(sample_str, '\n'); + if (newline) { + /* Chop off the trailing newline */ + *newline = '\0'; + } + + if ((ptr = strchr(sample_str, '=')) == NULL && + (ptr = strchr(sample_str, ':')) == NULL) { + printk("Error: Pkt sample size syntax not recognized: '%s'\n", sample_str); + return count; + } + *ptr++ = 0; + + spin_lock_irqsave(&g_psample_info.lock, flags); + + found = 0; + list_for_each(list, &g_psample_info.netif_list) { + psample_netif = (psample_netif_t*)list; + if (strcmp(psample_netif->dev->name, sample_str) == 0) { + psample_netif->sample_size = simple_strtol(ptr, NULL, 10); + // TODO MLI@BRCM - check valid sample size + found = 1; + break; + } + } + + spin_unlock_irqrestore(&g_psample_info.lock, flags); + + if (!found) { + printk("Warning: Failed setting psample size on unknown network interface: '%s'\n", sample_str); + } + return count; +} + +struct file_operations psample_proc_size_file_ops = { + owner: THIS_MODULE, + open: psample_proc_size_open, + read: seq_read, + llseek: seq_lseek, + write: psample_proc_size_write, + release: single_release, +}; + +/* + * psample map Proc Read Entry + */ +static int +psample_proc_map_show(struct seq_file *m, void *v) +{ + struct list_head *list; + psample_netif_t *psample_netif; + unsigned long flags; + + seq_printf(m, " Interface logical port ifindex\n"); + seq_printf(m, "------------- ------------ -------\n"); + spin_lock_irqsave(&g_psample_info.lock, flags); + + list_for_each(list, &g_psample_info.netif_list) { + psample_netif = (psample_netif_t*)list; + seq_printf(m, " %-14s %-14d %d\n", + psample_netif->dev->name, + psample_netif->port, + psample_netif->dev->ifindex); + } + + spin_unlock_irqrestore(&g_psample_info.lock, flags); + return 0; +} + +static int +psample_proc_map_open(struct inode * inode, struct file * file) +{ + return single_open(file, psample_proc_map_show, NULL); +} + +struct file_operations psample_proc_map_file_ops = { + owner: THIS_MODULE, + open: psample_proc_map_open, + read: seq_read, + llseek: seq_lseek, + write: NULL, + release: single_release, +}; + +/* + * psample debug Proc Read Entry + */ +static int +psample_proc_debug_show(struct seq_file *m, void *v) +{ + seq_printf(m, "BCM KNET %s Callback Config\n", PSAMPLE_CB_NAME); + seq_printf(m, " debug: 0x%x\n", debug); + seq_printf(m, " dcb_type: %d\n", g_psample_info.dcb_type); + seq_printf(m, " netif_count: %d\n", g_psample_info.netif_count); + seq_printf(m, " queue length: %d\n", psample_qlen); + + return 0; +} + +static int +psample_proc_debug_open(struct inode * inode, struct file * file) +{ + return single_open(file, psample_proc_debug_show, NULL); +} + +/* + * psample debug Proc Write Entry + * + * Syntax: + * debug= + * + * Where corresponds to the debug module parameter. + * + * Examples: + * debug=0x1 + */ +static ssize_t +psample_proc_debug_write(struct file *file, const char *buf, + size_t count, loff_t *loff) +{ + char debug_str[40]; + char *ptr; + + if (count > sizeof(debug_str)) { + count = sizeof(debug_str) - 1; + debug_str[count] = '\0'; + } + if (copy_from_user(debug_str, buf, count)) { + return -EFAULT; + } + + if ((ptr = strstr(debug_str, "debug=")) != NULL) { + ptr += 6; + debug = simple_strtol(ptr, NULL, 0); + } else { + printk("Warning: unknown configuration setting\n"); + } + + return count; +} + +struct file_operations psample_proc_debug_file_ops = { + owner: THIS_MODULE, + open: psample_proc_debug_open, + read: seq_read, + llseek: seq_lseek, + write: psample_proc_debug_write, + release: single_release, +}; + +static int +psample_proc_stats_show(struct seq_file *m, void *v) +{ + seq_printf(m, "BCM KNET %s Callback Stats\n", PSAMPLE_CB_NAME); + seq_printf(m, " DCB type %d\n", g_psample_info.dcb_type); + seq_printf(m, " pkts filter psample cb %10lu\n", g_psample_stats.pkts_f_psample_cb); + seq_printf(m, " pkts sent to psample module %10lu\n", g_psample_stats.pkts_f_psample_mod); + seq_printf(m, " pkts handled by psample %10lu\n", g_psample_stats.pkts_f_handled); + seq_printf(m, " pkts pass through %10lu\n", g_psample_stats.pkts_f_pass_through); + seq_printf(m, " pkts with mc destination %10lu\n", g_psample_stats.pkts_f_dst_mc); + seq_printf(m, " pkts current queue length %10lu\n", g_psample_stats.pkts_c_qlen_cur); + seq_printf(m, " pkts high queue length %10lu\n", g_psample_stats.pkts_c_qlen_hi); + seq_printf(m, " pkts drop max queue length %10lu\n", g_psample_stats.pkts_d_qlen_max); + seq_printf(m, " pkts drop no memory %10lu\n", g_psample_stats.pkts_d_no_mem); + seq_printf(m, " pkts drop no psample group %10lu\n", g_psample_stats.pkts_d_no_group); + seq_printf(m, " pkts drop sampling disabled %10lu\n", g_psample_stats.pkts_d_sampling_disabled); + seq_printf(m, " pkts drop psample not ready %10lu\n", g_psample_stats.pkts_d_not_ready); + seq_printf(m, " pkts drop metadata parse error %10lu\n", g_psample_stats.pkts_d_metadata); + seq_printf(m, " pkts drop skb error %10lu\n", g_psample_stats.pkts_d_skb); + seq_printf(m, " pkts drop skb cbd error %10lu\n", g_psample_stats.pkts_d_skb_cbd); + seq_printf(m, " pkts with invalid src port %10lu\n", g_psample_stats.pkts_d_meta_srcport); + seq_printf(m, " pkts with invalid dst port %10lu\n", g_psample_stats.pkts_d_meta_dstport); + seq_printf(m, " pkts with invalid orig pkt sz %10lu\n", g_psample_stats.pkts_d_invalid_size); + return 0; +} + +static int +psample_proc_stats_open(struct inode * inode, struct file * file) +{ + return single_open(file, psample_proc_stats_show, NULL); +} + +/* + * psample stats Proc Write Entry + * + * Syntax: + * write any value to clear stats + */ +static ssize_t +psample_proc_stats_write(struct file *file, const char *buf, + size_t count, loff_t *loff) +{ + int qlen_cur = 0; + unsigned long flags; + + spin_lock_irqsave(&g_psample_work.lock, flags); + qlen_cur = g_psample_stats.pkts_c_qlen_cur; + memset(&g_psample_stats, 0, sizeof(psample_stats_t)); + g_psample_stats.pkts_c_qlen_cur = qlen_cur; + spin_unlock_irqrestore(&g_psample_work.lock, flags); + + return count; +} +struct file_operations psample_proc_stats_file_ops = { + owner: THIS_MODULE, + open: psample_proc_stats_open, + read: seq_read, + llseek: seq_lseek, + write: psample_proc_stats_write, + release: single_release, +}; + +int psample_cleanup(void) +{ + cancel_work_sync(&g_psample_work.wq); + remove_proc_entry("stats", psample_proc_root); + remove_proc_entry("rate", psample_proc_root); + remove_proc_entry("size", psample_proc_root); + remove_proc_entry("debug", psample_proc_root); + remove_proc_entry("map" , psample_proc_root); + remove_proc_entry("psample", knet_cb_proc_root); + remove_proc_entry("bcm/knet-cb", NULL); + remove_proc_entry("bcm", NULL); + return 0; +} + +int psample_init(void) +{ + #define PROCFS_MAX_PATH 1024 + char psample_procfs_path[PROCFS_MAX_PATH]; + struct proc_dir_entry *entry; + + /* initialize proc files (for ngknet) */ + proc_mkdir("bcm", NULL); + + /* create procfs for psample */ + snprintf(psample_procfs_path, PROCFS_MAX_PATH, "bcm/knet-cb"); + knet_cb_proc_root = proc_mkdir(psample_procfs_path, NULL); + snprintf(psample_procfs_path, PROCFS_MAX_PATH, "%s/%s", psample_procfs_path, PSAMPLE_CB_NAME); + psample_proc_root = proc_mkdir(psample_procfs_path, NULL); + + /* create procfs for psample stats */ + PROC_CREATE(entry, "stats", 0666, psample_proc_root, &psample_proc_stats_file_ops); + if (entry == NULL) { + printk("%s: Unable to create procfs entry '/procfs/%s/stats'\n", __func__, psample_procfs_path); + return -1; + } + + /* create procfs for setting sample rates */ + PROC_CREATE(entry, "rate", 0666, psample_proc_root, &psample_proc_rate_file_ops); + if (entry == NULL) { + printk("%s: Unable to create procfs entry '/procfs/%s/rate'\n", __func__, psample_procfs_path); + return -1; + } + + /* create procfs for setting sample size */ + PROC_CREATE(entry, "size", 0666, psample_proc_root, &psample_proc_size_file_ops); + if (entry == NULL) { + printk("%s: Unable to create procfs entry '/procfs/%s/size'\n", __func__, psample_procfs_path); + return -1; + } + + /* create procfs for getting netdev mapping */ + PROC_CREATE(entry, "map", 0666, psample_proc_root, &psample_proc_map_file_ops); + if (entry == NULL) { + printk("%s: Unable to create procfs entry '/procfs/%s/map'\n", __func__, psample_procfs_path); + return -1; + } + + /* create procfs for debug log */ + PROC_CREATE(entry, "debug", 0666, psample_proc_root, &psample_proc_debug_file_ops); + if (entry == NULL) { + printk("%s: Unable to create procfs entry '/procfs/%s/debug'\n", __func__, psample_procfs_path); + return -1; + } + + /* clear data structs */ + memset(&g_psample_stats, 0, sizeof(psample_stats_t)); + memset(&g_psample_info, 0, sizeof(psample_info_t)); + memset(&g_psample_work, 0, sizeof(psample_work_t)); + + /* FIXME: How to get DCB type from NGKNET? */ + //g_psample_info.dcb_type + + /* setup psample_info struct */ + INIT_LIST_HEAD(&g_psample_info.netif_list); + spin_lock_init(&g_psample_info.lock); + + /* setup psample work queue */ + spin_lock_init(&g_psample_work.lock); + INIT_LIST_HEAD(&g_psample_work.pkt_list); + INIT_WORK(&g_psample_work.wq, psample_task); + + /* get net namespace */ + g_psample_info.netns = get_net_ns_by_pid(current->pid); + if (!g_psample_info.netns) { + printk("%s: Could not get network namespace for pid %d\n", __func__, current->pid); + return (-1); + } + PSAMPLE_CB_DBG_PRINT("%s: current->pid %d, netns 0x%p, sample_size %d\n", __func__, + current->pid, g_psample_info.netns, psample_size); + + + return 0; +} diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/psample-cb.h b/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/psample-cb.h new file mode 100644 index 000000000000..2e3342ead5c3 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/psample-cb.h @@ -0,0 +1,57 @@ +/* + * Copyright 2017 Broadcom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2, as + * published by the Free Software Foundation (the "GPL"). + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 (GPLv2) for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 (GPLv2) along with this source code. + */ +/* + * $Id: psample_cb.h $ + * $Copyright: (c) 2019 Broadcom Corp. + * All Rights Reserved.$ + */ +#ifndef __PSAMPLE_CB_H__ +#define __PSAMPLE_CB_H__ + +#include +#include + +//#define PSAMPLE_SUPPORT 1 // TODO: MLI@BRCM - Add this as part of conditional in Makefile +#define PSAMPLE_CB_NAME "psample" + +extern int +psample_init(void); + +extern int +psample_cleanup(void); + +extern struct sk_buff* +psample_rx_cb(struct sk_buff *skb); + +/* psample data per interface */ +typedef struct { + struct list_head list; + struct net_device *dev; + uint16_t id; + uint8_t port; + uint16_t vlan; + uint16_t qnum; + uint32_t sample_rate; + uint32_t sample_size; +} psample_netif_t; + +extern int +psample_netif_create_cb(struct net_device *dev); + +extern int +psample_netif_destroy_cb(struct net_device *dev); + +#endif /* __PSAMPLE_CB_H__ */ diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/psample/Kbuild b/platform/broadcom/saibcm-modules/sdklt/linux/psample/Kbuild new file mode 100644 index 000000000000..0049e399076b --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/psample/Kbuild @@ -0,0 +1,18 @@ +# -*- Kbuild -*- +# +# Linux psample module. +# +# $Copyright: (c) 2020 Broadcom. +# Broadcom Proprietary and Confidential. All rights reserved.$ +# + +obj-m := linux_psample.o + +ccflags-y := $(LKM_CFLAGS) \ + -I$(SDK)/shr/include \ + -I$(SDK)/bcmdrd/include \ + -I$(SDK)/linux/include \ + -I$(SDK)/linux/knet/include \ + -I$(SDK)/linux/knet + +linux_psample-y := psample.o diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/psample/Makefile b/platform/broadcom/saibcm-modules/sdklt/linux/psample/Makefile new file mode 100644 index 000000000000..b37b8ebb1c29 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/psample/Makefile @@ -0,0 +1,21 @@ +# -*- Makefile -*- +# +# Linux psample module. +# +# $Copyright: (c) 2020 Broadcom. +# Broadcom Proprietary and Confidential. All rights reserved.$ +# + +include Kbuild + +ifeq ($(KERNELRELEASE),) + +MOD_NAME = linux_psample + +include $(SDK)/make/lkm.mk + +endif + +.PHONY: distclean + +distclean: diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/psample/psample.c b/platform/broadcom/saibcm-modules/sdklt/linux/psample/psample.c new file mode 100644 index 000000000000..f0c9beab5784 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/psample/psample.c @@ -0,0 +1,302 @@ +/* + * net/psample/psample.c - Netlink channel for packet sampling + * Copyright (c) 2017 Yotam Gigi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PSAMPLE_MAX_PACKET_SIZE 0xffff + +static LIST_HEAD(psample_groups_list); +static DEFINE_SPINLOCK(psample_groups_lock); + +/* multicast groups */ +enum psample_nl_multicast_groups { + PSAMPLE_NL_MCGRP_CONFIG, + PSAMPLE_NL_MCGRP_SAMPLE, +}; + +static const struct genl_multicast_group psample_nl_mcgrps[] = { + [PSAMPLE_NL_MCGRP_CONFIG] = { .name = PSAMPLE_NL_MCGRP_CONFIG_NAME }, + [PSAMPLE_NL_MCGRP_SAMPLE] = { .name = PSAMPLE_NL_MCGRP_SAMPLE_NAME }, +}; + +static struct genl_family psample_nl_family; + +static int psample_group_nl_fill(struct sk_buff *msg, + struct psample_group *group, + enum psample_command cmd, u32 portid, u32 seq, + int flags) +{ + void *hdr; + int ret; + + hdr = genlmsg_put(msg, portid, seq, &psample_nl_family, flags, cmd); + if (!hdr) + return -EMSGSIZE; + + ret = nla_put_u32(msg, PSAMPLE_ATTR_SAMPLE_GROUP, group->group_num); + if (ret < 0) + goto error; + + ret = nla_put_u32(msg, PSAMPLE_ATTR_GROUP_REFCOUNT, group->refcount); + if (ret < 0) + goto error; + + ret = nla_put_u32(msg, PSAMPLE_ATTR_GROUP_SEQ, group->seq); + if (ret < 0) + goto error; + + genlmsg_end(msg, hdr); + return 0; + +error: + genlmsg_cancel(msg, hdr); + return -EMSGSIZE; +} + +static int psample_nl_cmd_get_group_dumpit(struct sk_buff *msg, + struct netlink_callback *cb) +{ + struct psample_group *group; + int start = cb->args[0]; + int idx = 0; + int err; + + spin_lock(&psample_groups_lock); + list_for_each_entry(group, &psample_groups_list, list) { + if (!net_eq(group->net, sock_net(msg->sk))) + continue; + if (idx < start) { + idx++; + continue; + } + err = psample_group_nl_fill(msg, group, PSAMPLE_CMD_NEW_GROUP, + NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, NLM_F_MULTI); + if (err) + break; + idx++; + } + + spin_unlock(&psample_groups_lock); + cb->args[0] = idx; + return msg->len; +} + +static const struct genl_ops psample_nl_ops[] = { + { + .cmd = PSAMPLE_CMD_GET_GROUP, + .dumpit = psample_nl_cmd_get_group_dumpit, + /* can be retrieved by unprivileged users */ + } +}; + +static struct genl_family psample_nl_family = { + .name = PSAMPLE_GENL_NAME, + .version = PSAMPLE_GENL_VERSION, + .maxattr = PSAMPLE_ATTR_MAX, + .netnsok = true, + .module = THIS_MODULE, + .mcgrps = psample_nl_mcgrps, + .ops = psample_nl_ops, + .n_ops = ARRAY_SIZE(psample_nl_ops), + .n_mcgrps = ARRAY_SIZE(psample_nl_mcgrps), +}; + +static void psample_group_notify(struct psample_group *group, + enum psample_command cmd) +{ + struct sk_buff *msg; + int err; + + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); + if (!msg) + return; + + err = psample_group_nl_fill(msg, group, cmd, 0, 0, NLM_F_MULTI); + if (!err) + genlmsg_multicast_netns(&psample_nl_family, group->net, msg, 0, + PSAMPLE_NL_MCGRP_CONFIG, GFP_ATOMIC); + else + nlmsg_free(msg); +} + +static struct psample_group *psample_group_create(struct net *net, + u32 group_num) +{ + struct psample_group *group; + + group = kzalloc(sizeof(*group), GFP_ATOMIC); + if (!group) + return NULL; + + group->net = net; + group->group_num = group_num; + list_add_tail(&group->list, &psample_groups_list); + + psample_group_notify(group, PSAMPLE_CMD_NEW_GROUP); + return group; +} + +static void psample_group_destroy(struct psample_group *group) +{ + psample_group_notify(group, PSAMPLE_CMD_DEL_GROUP); + list_del(&group->list); + kfree(group); +} + +static struct psample_group * +psample_group_lookup(struct net *net, u32 group_num) +{ + struct psample_group *group; + + list_for_each_entry(group, &psample_groups_list, list) + if ((group->group_num == group_num) && (group->net == net)) + return group; + return NULL; +} + +struct psample_group *psample_group_get(struct net *net, u32 group_num) +{ + struct psample_group *group; + + spin_lock(&psample_groups_lock); + + group = psample_group_lookup(net, group_num); + if (!group) { + group = psample_group_create(net, group_num); + if (!group) + goto out; + } + group->refcount++; + +out: + spin_unlock(&psample_groups_lock); + return group; +} +EXPORT_SYMBOL_GPL(psample_group_get); + +void psample_group_put(struct psample_group *group) +{ + spin_lock(&psample_groups_lock); + + if (--group->refcount == 0) + psample_group_destroy(group); + + spin_unlock(&psample_groups_lock); +} +EXPORT_SYMBOL_GPL(psample_group_put); + +void psample_sample_packet(struct psample_group *group, struct sk_buff *skb, + u32 trunc_size, int in_ifindex, int out_ifindex, + u32 sample_rate) +{ + struct sk_buff *nl_skb; + int data_len; + int meta_len; + void *data; + int ret; + + meta_len = (in_ifindex ? nla_total_size(sizeof(u16)) : 0) + + (out_ifindex ? nla_total_size(sizeof(u16)) : 0) + + nla_total_size(sizeof(u32)) + /* sample_rate */ + nla_total_size(sizeof(u32)) + /* orig_size */ + nla_total_size(sizeof(u32)) + /* group_num */ + nla_total_size(sizeof(u32)); /* seq */ + + data_len = min(skb->len, trunc_size); + if (meta_len + nla_total_size(data_len) > PSAMPLE_MAX_PACKET_SIZE) + data_len = PSAMPLE_MAX_PACKET_SIZE - meta_len - NLA_HDRLEN + - NLA_ALIGNTO; + + nl_skb = genlmsg_new(meta_len + nla_total_size(data_len), GFP_ATOMIC); + if (unlikely(!nl_skb)) + return; + + data = genlmsg_put(nl_skb, 0, 0, &psample_nl_family, 0, + PSAMPLE_CMD_SAMPLE); + if (unlikely(!data)) + goto error; + + if (in_ifindex) { + ret = nla_put_u16(nl_skb, PSAMPLE_ATTR_IIFINDEX, in_ifindex); + if (unlikely(ret < 0)) + goto error; + } + + if (out_ifindex) { + ret = nla_put_u16(nl_skb, PSAMPLE_ATTR_OIFINDEX, out_ifindex); + if (unlikely(ret < 0)) + goto error; + } + + ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_SAMPLE_RATE, sample_rate); + if (unlikely(ret < 0)) + goto error; + + ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_ORIGSIZE, skb->len); + if (unlikely(ret < 0)) + goto error; + + ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_SAMPLE_GROUP, group->group_num); + if (unlikely(ret < 0)) + goto error; + + ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_GROUP_SEQ, group->seq++); + if (unlikely(ret < 0)) + goto error; + + if (data_len) { + int nla_len = nla_total_size(data_len); + struct nlattr *nla; + + nla = (struct nlattr *)skb_put(nl_skb, nla_len); + nla->nla_type = PSAMPLE_ATTR_DATA; + nla->nla_len = nla_attr_size(data_len); + + if (skb_copy_bits(skb, 0, nla_data(nla), data_len)) + goto error; + } + + genlmsg_end(nl_skb, data); + genlmsg_multicast_netns(&psample_nl_family, group->net, nl_skb, 0, + PSAMPLE_NL_MCGRP_SAMPLE, GFP_ATOMIC); + + return; +error: + pr_err_ratelimited("Could not create psample log message\n"); + nlmsg_free(nl_skb); +} +EXPORT_SYMBOL_GPL(psample_sample_packet); + +static int __init psample_module_init(void) +{ + return genl_register_family(&psample_nl_family); +} + +static void __exit psample_module_exit(void) +{ + genl_unregister_family(&psample_nl_family); +} + +module_init(psample_module_init); +module_exit(psample_module_exit); + +MODULE_AUTHOR("Yotam Gigi "); +MODULE_DESCRIPTION("netlink channel for packet sampling"); +MODULE_LICENSE("GPL v2"); diff --git a/platform/broadcom/saibcm-modules/sdklt/make/lkm.mk b/platform/broadcom/saibcm-modules/sdklt/make/lkm.mk new file mode 100644 index 000000000000..c3d2a4d40b50 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/make/lkm.mk @@ -0,0 +1,76 @@ +# +# $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. +# The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# version 2 as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# A copy of the GNU General Public License version 2 (GPLv2) can +# be found in the LICENSES folder.$ +# +# Shared makefile include for building Linux kernel modules. +# + +# KDIR must point to the Linux kernel sources +ifndef KDIR +nokdir:; @echo 'The $$KDIR variable is not set'; exit 1 +endif + +# Required for older kernels +export EXTRA_CFLAGS = $(ccflags-y) + +PWD := $(shell pwd) + +ifneq ($(LKM_BLDDIR),) +# +# If a build directory has been specified, then we symlink all sources +# to this directory and redirect the module build path. +# +# Note that the KBUILD_OUTPUT variable cannot be used to redirect the +# output as we want it. +# +MDIR = $(LKM_BLDDIR) +MSRCS = $(patsubst %.o,%.c,$($(MOD_NAME)-y)) +MSRCS += Makefile Kbuild +BSRCS = $(addprefix $(PWD)/,$(MSRCS)) +else +# +# Build in current directory by default. +# +MDIR = $(PWD) +endif + +all: + $(Q)echo Building kernel module $(MOD_NAME) +ifneq ($(LKM_BLDDIR),) +ifneq ($(LKM_BLDDIR),$(PWD)) + $(Q)mkdir -p $(MDIR) + (cd $(MDIR); \ + rm -rf *.c Makefile Kbuild; \ + for f in $(BSRCS); do \ + ln -s $$f; \ + done) +endif +endif + $(MAKE) -C $(KDIR) M=$(MDIR) + +clean:: + $(Q)echo Cleaning kernel module $(MOD_NAME) + $(MAKE) -C $(KDIR) M=$(MDIR) clean +ifneq ($(LKM_BLDDIR),) +ifneq ($(LKM_BLDDIR),$(PWD)) +# Remove all files except for Makefile (needed by 'make clean') + rm -f $(LKM_BLDDIR)/*[cdors] +endif +endif + +.PHONY: all clean + +# Standard documentation targets +-include $(SDK)/make/doc.mk diff --git a/platform/broadcom/saibcm-modules/sdklt/shr/include/shr/shr_error.h b/platform/broadcom/saibcm-modules/sdklt/shr/include/shr/shr_error.h new file mode 100644 index 000000000000..1924d600de53 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/shr/include/shr/shr_error.h @@ -0,0 +1,195 @@ +/*! \file shr_error.h + * + * Shared error codes. + * + */ +/* + * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#ifndef SHR_ERROR_H +#define SHR_ERROR_H + +/*! + * \brief Standard SDK error codes. + * + * IMPORTANT: These error codes must match the corresponding text + * messages in shr_error.c. + */ +typedef enum { + + /*! + * The operation completed successfully. + */ + SHR_E_NONE = 0, + + /*! + * This usually indicates that software encountered an internal + * data inconsistency or an unanticipated hardware state. + */ + SHR_E_INTERNAL = -1, + + /*! + * An operation failed due to insufficient dynamically allocated + * memory. + */ + SHR_E_MEMORY = -2, + + /*! + * The first argument of many API routines is a unit number. This + * error occurs if that number refers to a non-existent unit. + */ + SHR_E_UNIT = -3, + + /*! + * A parameter to an API routine was invalid. A null pointer value + * may have been passed to the routine, or an integer parameter + * may be outside of its allowed range. + */ + SHR_E_PARAM = -4, + + /*! + * The operation encountered a pooled resource (e.g. a table or a + * list) with no valid elements. + */ + SHR_E_EMPTY = -5, + + /*! + * The operation encountered a pooled resource (e.g. a table or a + * list) with no room for new elements. + */ + SHR_E_FULL = -6, + + /*! + * The specified entry in a pooled resource (e.g. a table or a + * list) could not be found. + */ + SHR_E_NOT_FOUND = -7, + + /*! + * The specified entry of a pooled resource (e.g. a table or a + * list) already exists. + */ + SHR_E_EXISTS = -8, + + /*! + * The operation did not complete within the maximum allowed time frame. + */ + SHR_E_TIMEOUT = -9, + + /*! + * An operation was attempted before the previous operation had + * completed. + */ + SHR_E_BUSY = -10, + + /*! + * An operation could not be completed. This may be due to a + * hardware or configuration problem. + */ + SHR_E_FAIL = -11, + + /*! + * The operation could not be completed because a required feature + * was disabled. + */ + SHR_E_DISABLED = -12, + + /*! + * The specified identifier was not valid. Note that this error + * code will normally take precedence over \ref SHR_E_PARAM. + */ + SHR_E_BADID = -13, + + /*! + * The operation could not be completed due to lack of hardware + * resources. + */ + SHR_E_RESOURCE = -14, + + /*! + * The operation could not be completed due to incomplete or + * incorrect configuration. + */ + SHR_E_CONFIG = -15, + + /*! + * The hardware does not support the requested operation. + */ + SHR_E_UNAVAIL = -16, + + /*! + * An operation was attempted before initialization was complete. + */ + SHR_E_INIT = -17, + + /*! + * The specified port value was not valid. Note that this error + * code will normally take precedence over \ref SHR_E_PARAM. + */ + SHR_E_PORT = -18, + + /*! + * A low-level register or memory access failed. + */ + SHR_E_IO = -19, + + /*! + * Access method not permitted. Typically returned if attempting + * to write to a read-only object. + */ + SHR_E_ACCESS = -20, + + /*! + * No handler exists to perform the hardware access associated + * with a an operation on a software object. + */ + SHR_E_NO_HANDLER = -21, + + /*! + * The operation was only partially completed, and this could + * potentially leave the system in an unexpected state. + */ + SHR_E_PARTIAL = -22, + + /*! + * The operation failed because of a hash collision. + */ + SHR_E_COLL = -23, + + SHR_E_LIMIT = -24 /* Must come last */ + +} shr_error_t; + +/*! Check for successful return value. */ +#define SHR_SUCCESS(_expr) ((_expr) >= 0) + +/*! Check for error return value. */ +#define SHR_FAILURE(_expr) ((_expr) < 0) + +/*! + * \brief Get standard error message + * + * Returns a text message corresponding to the error code passed in. + * + * \param [in] rv Error code + * + * \return Pointer to error message + */ +extern const char * +shr_errmsg(int rv); + +#endif /* SHR_ERROR_H */ diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/include/linux-bde.h b/platform/broadcom/saibcm-modules/systems/bde/linux/include/linux-bde.h index bdf7a56dcabb..c4d31579bfdf 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/include/linux-bde.h +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/include/linux-bde.h @@ -1,5 +1,10 @@ /* - * Copyright 2017 Broadcom + * Copyright 2007-2020 Broadcom Inc. All rights reserved. + * + * Permission is granted to use, copy, modify and/or distribute this + * software under either one of the licenses below. + * + * License Option 1: GPL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. + * + * + * License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license + * + * This software is governed by the Broadcom Open Network Switch APIs license: + * https://www.broadcom.com/products/ethernet-connectivity/software/opennsa */ /*********************************************************************** * @@ -58,7 +69,6 @@ #define __LINUX_BDE_H__ #include - #include @@ -104,12 +114,17 @@ /* Max devices */ /* 16 switch chips + 2 out-of-band Ethernet + 2 CPUs */ +#ifndef LINUX_BDE_MAX_SWITCH_DEVICES #define LINUX_BDE_MAX_SWITCH_DEVICES 16 +#endif #define LINUX_BDE_MAX_ETHER_DEVICES 2 #define LINUX_BDE_MAX_CPU_DEVICES 2 #define LINUX_BDE_MAX_DEVICES (LINUX_BDE_MAX_SWITCH_DEVICES + \ LINUX_BDE_MAX_ETHER_DEVICES + \ - LINUX_BDE_MAX_CPU_DEVICES) + LINUX_BDE_MAX_CPU_DEVICES) +#define LINUX_BDE_NOF_DEVICE_BITMAP_WORDS ((LINUX_BDE_MAX_DEVICES+31)/32) +#define LINUX_BDE_MAX_IPROC_UC_CORES 12 /* Maximum number of R5 cores per device */ +typedef uint32 linux_bde_device_bitmap_t[LINUX_BDE_NOF_DEVICE_BITMAP_WORDS]; /* * PCI devices will be initialized by the Linux Kernel, @@ -148,14 +163,24 @@ typedef struct linux_bde_bus_s { */ #define BDE_DEV_STATE_CHANGED (2) +/* + * BDE_DEV_INST_ID_INVALID : The invalid instance identifier. + */ +#define BDE_DEV_INST_ID_INVALID ((uint32)-1) + extern int linux_bde_create(linux_bde_bus_t* bus, ibde_t** bde); extern int linux_bde_destroy(ibde_t* bde); #ifdef BCM_INSTANCE_SUPPORT extern int linux_bde_instance_attach(unsigned int dev_mask,unsigned int dma_size); +extern int linux_bde_instance_config(linux_bde_device_bitmap_t dev_mask,unsigned int dma_size); #endif #ifdef __KERNEL__ +#ifdef INCLUDE_EDK +#define BDE_EDK_SUPPORT +#endif + /* * Backdoors provided by the kernel bde * @@ -171,6 +196,10 @@ extern int linux_bde_instance_attach(unsigned int dev_mask,unsigned int dma_size extern int lkbde_get_dma_info(phys_addr_t *cpu_pbase, phys_addr_t *dma_pbase, ssize_t *size); extern uint32 lkbde_get_dev_phys(int d); extern uint32 lkbde_get_dev_phys_hi(int d); +#ifdef BDE_EDK_SUPPORT +extern int lkbde_edk_get_dma_info(int dev_id, phys_addr_t* cpu_pbase, + phys_addr_t* dma_pbase, ssize_t* size); +#endif /* * Virtual device address needed by kernel space @@ -183,8 +212,8 @@ extern void *lkbde_get_dev_virt(int d); * the userland code to mmap. The following functions * supports multiple resources for a single device. */ -extern int lkbde_get_dev_resource(int d, int rsrc, uint32 *flags, - uint32 *phys_lo, uint32 *phys_hi); +extern int lkbde_get_dev_resource(int d, int rsrc, uint32_t *phys_lo, + uint32_t *phys_hi, uint32_t *size); /* * Backdoor to retrieve OS device structure to be used for @@ -215,6 +244,19 @@ extern int lkbde_dev_state_set(int d, uint32 state); extern int lkbde_dev_instid_get(int d, uint32 *instid); extern int lkbde_dev_instid_set(int d, uint32 instid); + +/* + * Return none-zero if the SDK instance with the given instance ID + * manages the given device. + */ +extern int lkbde_is_dev_managed_by_instance(uint32 dev, uint32 inst_id); + +/* + * Return a pointer to the bitmap of the SDK instance managed devices. + */ +extern linux_bde_device_bitmap_t* lkbde_get_inst_devs(uint32 inst_id); + + /* * Functions that allow an interrupt handler in user mode to * coexist with interrupt handler in kernel module. @@ -256,13 +298,6 @@ extern int lkbde_cpu_pci_register(int d); #endif #endif -/* Don't use _SIMPLE_MEMORY_ALLOCATION_ method for newer kernel than 3.10.0 */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)) -#ifndef _SIMPLE_MEMORY_ALLOCATION_ -#define _SIMPLE_MEMORY_ALLOCATION_ 0 -#endif -#endif - /* Allocation via dma_alloc_coherent is turned off by default */ #ifndef _SIMPLE_MEMORY_ALLOCATION_ #define _SIMPLE_MEMORY_ALLOCATION_ 9 /* compile in the allocation method, but do not use it by default */ diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/include/linux_dma.h b/platform/broadcom/saibcm-modules/systems/bde/linux/include/linux_dma.h index 3bf7488abce9..23eb3fa33e9e 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/include/linux_dma.h +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/include/linux_dma.h @@ -1,5 +1,10 @@ /* - * Copyright 2017 Broadcom + * Copyright 2007-2020 Broadcom Inc. All rights reserved. + * + * Permission is granted to use, copy, modify and/or distribute this + * software under either one of the licenses below. + * + * License Option 1: GPL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. + * + * + * License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license + * + * This software is governed by the Broadcom Open Network Switch APIs license: + * https://www.broadcom.com/products/ethernet-connectivity/software/opennsa */ /*********************************************************************** * @@ -60,7 +71,7 @@ extern void _dma_init(int dev_index); extern int _dma_cleanup(void); -extern void _dma_pprint(void); +extern void _dma_pprint(struct seq_file *m); extern uint32_t *_salloc(int d, int size, const char *name); extern void _sfree(int d, void *ptr); extern int _sinval(int d, void *ptr, int length); diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/include/mpool.h b/platform/broadcom/saibcm-modules/systems/bde/linux/include/mpool.h index be4d436f8da9..15d496ff623d 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/include/mpool.h +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/include/mpool.h @@ -1,5 +1,10 @@ /* - * Copyright 2017 Broadcom + * Copyright 2007-2020 Broadcom Inc. All rights reserved. + * + * Permission is granted to use, copy, modify and/or distribute this + * software under either one of the licenses below. + * + * License Option 1: GPL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. + * + * + * License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license + * + * This software is governed by the Broadcom Open Network Switch APIs license: + * https://www.broadcom.com/products/ethernet-connectivity/software/opennsa */ /* * $Id: mpool.h,v 1.2 Broadcom SDK $ diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/Makefile b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/Makefile index aedd487b1f11..2aa3bec11d73 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/Makefile +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/Makefile @@ -1,5 +1,10 @@ # -# Copyright 2017 Broadcom +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ # # You should have received a copy of the GNU General Public License # version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa # # -*- Makefile -*- # $Id: Makefile,v 1.18 Broadcom SDK $ @@ -55,14 +66,16 @@ THIS_MOD_NAME := linux-kernel-bde MODULE = $(LIBDIR)/$(THIS_MOD_NAME).o KMODULE = $(LIBDIR)/$(THIS_MOD_NAME).ko -build: kernel_libs $(MODULE) $(KMODULE) +build: kernel_libs module $(KMODULE) else MODULE = $(LIBDIR)/linux-kernel-bde.o -build: kernel_libs $(MODULE) +build: kernel_libs module endif -$(MODULE): $(BLDDIR)/.tree kernel_libs $(BOBJS) +module: kernel_libs $(MODULE) + +$(MODULE): $(BLDDIR)/.tree $(BOBJS) mkdir -p $(@D) $(LD) $(MODULE_LDFLAGS) -r -d $(BOBJS) $(LIBS) -o $@ ifneq ($(kernel_version),2_4) diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux-kernel-bde.c b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux-kernel-bde.c index 464a72bd3e41..9029b3b51477 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux-kernel-bde.c +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux-kernel-bde.c @@ -1,25 +1,21 @@ /* * Copyright 2017 Broadcom - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as * published by the Free Software Foundation (the "GPL"). - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 (GPLv2) for more details. - * + * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. */ + /* - * $Id: linux-kernel-bde.c,v 1.414 Broadcom SDK $ - * $Copyright: (c) 2005 Broadcom Corp. - * All Rights Reserved.$ - * * Linux Kernel BDE - * */ #include @@ -30,27 +26,32 @@ #include #include #include -#include #include #include "linux_shbde.h" +#define MEMCPY memcpy -#ifdef __GNUC__ -#if __GNUC__ == 8 +#ifdef CONFIG_X86_64 +#if (defined(__GNUC__) && (__GNUC__ == 8)) /* * Prevent gcc 8.1.10 using a compiler inline memcpy even if using -fno-builtin or * -fno-builtin-memcpy . * __inline_memcpy and __memcpy are kernel functions that may be used instead, * for either an inline or non-inline implementations of the function */ -#define MEMCPY __inline_memcpy -#else -#define MEMCPY memcpy -#endif /* __GNUC__ == 8 */ -#else /* ifdef __GNUC__ */ -#define MEMCPY memcpy -#endif /* ifdef __GNUC__ */ +#undef MEMCPY +#define MEMCPY __memcpy +#endif /* (defined(__GNUC__) && (__GNUC__ == 8)) */ +#endif /* CONFIG_X86_64 */ + + +#if defined(CMIC_SOFT_BYTE_SWAP) +#define CMIC_SWAP32(_x) ((((_x) & 0xff000000) >> 24) \ + | (((_x) & 0x00ff0000) >> 8) \ + | (((_x) & 0x0000ff00) << 8) \ + | (((_x) & 0x000000ff) << 24)) +#endif /* defined(CMIC_SOFT_BYTE_SWAP) */ #define PCI_USE_INT_NONE (-1) #define PCI_USE_INT_INTX (0) @@ -68,8 +69,15 @@ MODULE_AUTHOR("Broadcom Corporation"); MODULE_DESCRIPTION("Kernel BDE"); MODULE_LICENSE("GPL"); -/* PCIe max payload */ -int maxpayload = 256; +/* + * PCIe max payload size in bytes. + * The default value if not specified to the kernel module by maxpayload is historically 256. + * The default value may be changed using the BDE_PCIE_MAXPAYLOAD_DEFAULT macro. + */ +#ifndef BDE_PCIE_MAXPAYLOAD_DEFAULT +#define BDE_PCIE_MAXPAYLOAD_DEFAULT 256 +#endif +int maxpayload = BDE_PCIE_MAXPAYLOAD_DEFAULT; LKM_MOD_PARAM(maxpayload, "i", int, 0); MODULE_PARM_DESC(maxpayload, "Limit maximum payload size and request size on PCIe devices"); @@ -256,6 +264,19 @@ struct bde_spi_device_id { uint32 spifreq; }; +/* Maximum number of I/O windows supported per device. */ +#define BDE_NUM_IOWIN_MAX 3 + +/* I/O memory window definition. */ +struct memwin_s { + + /* Physical address of I/O window. */ + resource_size_t addr; + + /* Size of I/O window (in bytes). */ + resource_size_t size; +}; + /* Control Data */ typedef struct bde_ctrl_s { struct list_head list; @@ -285,10 +306,7 @@ typedef struct bde_ctrl_s { struct device *dma_dev; #endif - /* Physical addresses */ - resource_size_t phys_address; - resource_size_t phys_address1; - resource_size_t phys_address2; + struct memwin_s iowin[BDE_NUM_IOWIN_MAX]; /* Secondary mapped base address */ sal_vaddr_t alt_base_addr; @@ -321,10 +339,19 @@ typedef struct bde_ctrl_s { uint32 dev_state; /* inst_id */ - uint32 inst_id; + uint32 inst_id; /* The instance ID of the instance controlling the device */ } bde_ctrl_t; static bde_ctrl_t _devices[LINUX_BDE_MAX_DEVICES]; + +/* information stored per SDK instance, curently the devices it manages */ +typedef struct { + linux_bde_device_bitmap_t devices; /* The devices controlled by this instance */ +} lkbde_inst_info_t; + +/* Information for each SDK instance (array index), the device that it manages */ +static lkbde_inst_info_t _instance_info[LINUX_BDE_MAX_DEVICES] = {{ .devices = {0}}}; + static int _ndevices = 0; static int _switch_ndevices = 0; static int _ether_ndevices = 0; @@ -334,7 +361,7 @@ static int _cpu_ndevices = 0; #if defined(IPROC_CMICD) && defined(CONFIG_OF) #define ICFG_CHIP_ID_REG 0x10236000 -#define IHOST_CMICX_MAX_INTRS 128 +#define IHOST_CMICX_MAX_INTRS 129 static uint32 iproc_cmicx_irqs[IHOST_CMICX_MAX_INTRS]; #endif @@ -415,7 +442,7 @@ static void *cpu_address = NULL; /* PLX PCI-E Switch */ #define PLX_PEX8608_DEV_ID 0x8608 #define PLX_PEX8617_DEV_ID 0x8617 -#define PLX_PEX86XX_DEV_CTRL_REG 0x70 +#define PLX_PEX86XX_DEV_CTRL_REG 0x70 /* Broadcom BCM58525 */ #define BCM58525_PCI_VENDOR_ID 0x14E4 @@ -432,10 +459,11 @@ static void *cpu_address = NULL; #define IHOST_GICD_REG_ADDR_VALID(d, addr) \ (_devices[d].bde_dev.base_address1 && \ - (addr & 0xFFFFFF00) == _devices[d].phys_address1) + (addr & 0xFFFFFF00) == _devices[d].iowin[1].addr) #define IHOST_GICD_REG_ADDR_REMAP(d, addr) \ - (void *)(_devices[d].bde_dev.base_address1 + (addr - _devices[d].phys_address1)) + (void *)(_devices[d].bde_dev.base_address1 + \ + (addr - ((sal_vaddr_t)_devices[d].iowin[1].addr))) static uint32_t _read(int d, uint32_t addr); @@ -554,7 +582,8 @@ _eb_device_create(resource_size_t paddr, int irq, int rd_hw, int wr_hw) /* Map in the device */ ctrl->bde_dev.base_address = (sal_vaddr_t)IOREMAP(paddr, 0x10000); - ctrl->phys_address = paddr; + ctrl->iowin[0].addr = paddr; + ctrl->iowin[0].size = 0x10000; dev_rev_id = _read(dev_id, 0x178); /* CMIC_DEV_REV_ID */ @@ -590,7 +619,8 @@ sand_device_create(void) /* Map in the device */ /* FIX_ME: not realy map anything */ ctrl->bde_dev.base_address = (sal_vaddr_t)IOREMAP(0x40000000, 0x100000); - ctrl->phys_address = 0x40000000; + ctrl->iowin[0].addr = 0x40000000; + ctrl->iowin[0].size = 0x100000; ctrl->iLine = 0; ctrl->isr = NULL; @@ -695,7 +725,8 @@ iproc_cmicd_probe(struct platform_device *pldev) gprintk("Error mapping iProc CMIC registers"); return -1; } - ctrl->phys_address = memres->start; + ctrl->iowin[0].addr = memres->start; + ctrl->iowin[0].size = size; #ifdef CONFIG_OF if (of_find_compatible_node(NULL, NULL, IPROC_CMICX_COMPATIBLE)) { @@ -712,16 +743,18 @@ iproc_cmicd_probe(struct platform_device *pldev) memres = iproc_platform_get_resource(pldev, IORESOURCE_MEM, 1); if (memres) { ctrl->bde_dev.base_address1 = (sal_vaddr_t)IOREMAP(memres->start, memres->end - memres->start + 1); - ctrl->phys_address1 = memres->start; + ctrl->iowin[1].addr = memres->start; + ctrl->iowin[1].size = memres->end - memres->start + 1; } else { /* Use default address if not available in DTB */ ctrl->bde_dev.base_address1 = (sal_vaddr_t)IOREMAP(IHOST_GICD_REG_ADDR, IHOST_GICD_REG_REMAP_LEN); - ctrl->phys_address1 = IHOST_GICD_REG_ADDR; + ctrl->iowin[1].addr = IHOST_GICD_REG_ADDR; + ctrl->iowin[1].size = IHOST_GICD_REG_REMAP_LEN; } if (ctrl->bde_dev.base_address1) { if (debug >= 1) { gprintk("base_address1:0x%lx phys_address1:0x%lx\n", - (unsigned long)ctrl->bde_dev.base_address1, (unsigned long)ctrl->phys_address1); + (unsigned long)ctrl->bde_dev.base_address1, (unsigned long)ctrl->iowin[1].addr); } } else { gprintk("Error mapping ihost GICD registers\n"); @@ -753,9 +786,12 @@ iproc_cmicd_probe(struct platform_device *pldev) #ifdef CONFIG_OF if (of_find_compatible_node(NULL, NULL, IPROC_CMICX_COMPATIBLE)) { int i; + memset(iproc_cmicx_irqs, 0, IHOST_CMICX_MAX_INTRS*sizeof(uint32_t)); for (i = 0; i < IHOST_CMICX_MAX_INTRS; i++) { irqres = iproc_platform_get_resource(pldev, IORESOURCE_IRQ, i); - iproc_cmicx_irqs[i] = irqres->start; + if (irqres) { + iproc_cmicx_irqs[i] = irqres->start; + } if (debug >= 1) { gprintk("iproc_cmicx_irqs[%d] = %d\n", i, iproc_cmicx_irqs[i]); } @@ -783,6 +819,25 @@ iproc_cmicd_probe(struct platform_device *pldev) static int iproc_cmicd_remove(struct platform_device *pldev) { + int i; + uint32 mask = BDE_SWITCH_DEV_TYPE | BDE_AXI_DEV_TYPE; + bde_ctrl_t *ctrl; + + for (i = 0; i < _ndevices; i++) { + ctrl = _devices + i; + if ((ctrl->dev_type & mask) == mask) { + if (ctrl->bde_dev.base_address1) { + iounmap((void *)ctrl->bde_dev.base_address1); + ctrl->bde_dev.base_address1 = 0; + } + + if (ctrl->bde_dev.base_address) { + iounmap((void *)ctrl->bde_dev.base_address); + ctrl->bde_dev.base_address = 0; + } + } + } + return 0; } #ifdef CONFIG_OF @@ -1019,7 +1074,8 @@ _ics_bde_create(void) /* Map in the device */ paddr = BCM_ICS_CMIC_BASE; ctrl->bde_dev.base_address = (sal_vaddr_t)IOREMAP(paddr, 0x10000); - ctrl->phys_address = paddr; + ctrl->iowin[0].addr = paddr; + ctrl->iowin[0].size = 0x10000; dev_rev_id = *((unsigned int *)(KSEG1ADDR(paddr + 0x178))); @@ -1399,6 +1455,9 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM56174_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM53570_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM53575_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56070_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56071_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56072_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9656, PCI_ANY_ID, PCI_ANY_ID }, { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9056, PCI_ANY_ID, PCI_ANY_ID }, { BCM53000_VENDOR_ID, BCM53000PCIE_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1444,9 +1503,11 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM88270_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88271_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88272_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88273_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88274_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88276_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88278_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88279_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1463,9 +1524,9 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM88683_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88684_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88685_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88687_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88380_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88381_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { BROADCOM_VENDOR_ID, BCM88202_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88360_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88361_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88363_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1493,13 +1554,90 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM8869B_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM8869C_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM8869D_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8869E_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM8869F_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88800_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88801_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88802_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88803_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88804_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88805_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88806_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88807_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88808_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88809_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8880A_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8880B_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8880C_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8880D_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8880E_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8880F_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88820_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88821_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88822_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88823_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88824_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88825_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88826_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88827_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88828_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88829_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8882A_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8882B_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8882C_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8882D_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8882E_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8882F_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88480_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88481_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88482_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88483_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88484_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88485_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88486_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88487_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88488_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88489_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8848A_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8848B_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8848C_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8848D_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8848E_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8848F_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88280_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88281_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88282_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88283_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88284_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88285_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88286_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88287_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88288_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88289_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8828A_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8828B_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8828C_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8828D_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8828E_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8828F_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88850_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88851_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88852_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88853_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88854_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88855_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88856_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88857_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88858_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88859_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8885A_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8885B_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8885C_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8885D_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8885E_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8885F_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, #endif /* BCM_DNX_SUPPORT */ #ifdef BCM_DFE_SUPPORT - { BROADCOM_VENDOR_ID, BCM88750_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { BROADCOM_VENDOR_ID, BCM88753_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { BROADCOM_VENDOR_ID, BCM88755_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88770_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88773_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88774_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1513,7 +1651,6 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM88954_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88955_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88956_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { BROADCOM_VENDOR_ID, BCM88752_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88772_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88952_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, #endif @@ -1546,6 +1683,16 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM56832_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56836_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56870_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56273_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56274_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56275_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56276_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56277_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56278_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56279_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56575_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56175_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56176_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56370_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56371_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56372_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1568,6 +1715,10 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM53547_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM53548_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM53549_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56470_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56471_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56472_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56475_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { 0, 0, 0, 0 } };; @@ -2180,7 +2331,7 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) resource_size_t paddr; uint16 cmd = 0; uint32 bar_len; - int cmic_bar; + int i, cmic_bar; int baroff = 0; int iproc = 0; int plx_dev = 0; @@ -2219,7 +2370,7 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) } } #endif /* IPROC_CMICD */ - + /* * Note that a few supported devices have a non-Broadcom PCI vendor ID, * but since none of their associated PCI device IDs collide with the @@ -2441,7 +2592,7 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) ((PCI_FIND_DEV(BCM58525_PCI_VENDOR_ID, BCM58522_PCI_DEVICE_ID, NULL)) != NULL) || ((PCI_FIND_DEV(BCM58712_PCI_VENDOR_ID, BCM58712_PCI_DEVICE_ID, NULL)) != NULL) ) { /* BCM58525/BCM58712 CPU boards support 128 Max payload size */ - if (maxpayload) { + if (maxpayload && maxpayload != 128) { maxpayload = 128; if (debug >= 1) gprintk("force max payload size to 128\n"); } @@ -2470,9 +2621,6 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) #if defined(BCM_DFE_SUPPORT) switch (dev->device) { - case BCM88750_DEVICE_ID: - case BCM88753_DEVICE_ID: - case BCM88755_DEVICE_ID: case BCM88770_DEVICE_ID: case BCM88773_DEVICE_ID: case BCM88774_DEVICE_ID: @@ -2484,7 +2632,6 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) case BCM88954_DEVICE_ID: case BCM88955_DEVICE_ID: case BCM88956_DEVICE_ID: - case BCM88752_DEVICE_ID: case BCM88772_DEVICE_ID: case BCM88952_DEVICE_ID: @@ -2500,19 +2647,6 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) } #endif /* BCM_DFE_SUPPORT */ -#if defined(BCM_DNXF_SUPPORT) - /*All Ramon devices from 0x8790 to 0x879F*/ - if ((dev->device & BCM_DNXF_DEVID_MASK) == BCM88790_DEVICE_ID) { - /* - * For DMA transactions - set Max_Payload_Size and - * Max_Read_Request_Size to 128 bytes. - */ - pci_write_config_byte(dev, 0xb5, 0x0c); - pci_write_config_byte(dev, 0xb4, 0x0); - - } -#endif - /* Prevent compiler warning */ if (ctrl == NULL) { return 0; @@ -2523,6 +2657,15 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) ctrl->pci_device = dev; pci_set_drvdata(dev, ctrl); + /* + * Sample setting of unique ID, used the PCIe address of the device: + * domain, bus, slot, function in hex digits: DDDDBBSS (SS includes the slot/device and function. + * Tested with old kernels from 2.6 . + * Do not use the PCI_DEVID macro which old kernel versions don't have. */ + ctrl->bde_dev.dev_unique_id = dev->bus ? + (((uint32)pci_domain_nr(dev->bus)) << 16) ^ (((uint32)dev->bus->number) << 8) ^ dev->devfn : + dev->devfn; + /* Check for iProc device */ if (shbde_pci_is_iproc(shbde, dev, &cmic_bar)) { iproc = 1; @@ -2557,13 +2700,21 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) } ctrl->bde_dev.base_address = (sal_vaddr_t)IOREMAP(paddr, bar_len); - ctrl->phys_address = paddr; + ctrl->iowin[0].addr = paddr; + ctrl->iowin[0].size = bar_len; + if (debug >= 3) { gprintk("BAR %d: kernel addr:0x%lx phys addr:0x%lx length:%lx\n", baroff, (unsigned long)ctrl->bde_dev.base_address, (unsigned long)paddr, (unsigned long)bar_len); } /* Map secondary address spaces */ + for (i = 1; i < BDE_NUM_IOWIN_MAX; i++) { + ctrl->iowin[i].addr = 0; + ctrl->iowin[i].size = 0; + } + ctrl->bde_dev.base_address1 = 0; + if (iproc #ifdef DNX_TEST_BOARD || (dev->device == PLX9056_DEVICE_ID && baroff == 2) @@ -2572,7 +2723,8 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) paddr = pci_resource_start(dev, 0); bar_len = pci_resource_len(dev, 0); ctrl->bde_dev.base_address1 = (sal_vaddr_t)IOREMAP(paddr, bar_len); - ctrl->phys_address1 = paddr; + ctrl->iowin[1].addr = paddr; + ctrl->iowin[1].size = bar_len; if (debug >= 3) { gprintk("BAR 0: kernel addr:0x%lx phys addr:0x%lx length:%lx\n", (unsigned long)ctrl->bde_dev.base_address1, (unsigned long)paddr, (unsigned long)bar_len); @@ -2726,9 +2878,10 @@ _pci_remove(struct pci_dev* dev) } static struct pci_driver _device_driver = { - probe: _pci_probe, - remove: _pci_remove, - id_table: _id_table, + .name = LINUX_KERNEL_BDE_NAME, + .probe = _pci_probe, + .remove = _pci_remove, + .id_table = _id_table, /* The rest are dynamic */ }; @@ -2773,7 +2926,8 @@ map_local_bus(uint64_t addr, uint32_t size) /* Map in the device */ ctrl->bde_dev.base_address = (sal_vaddr_t)IOREMAP(addr, size); - ctrl->phys_address = addr; + ctrl->iowin[0].addr = addr; + ctrl->iowin[0].size = size; _bde_add_device(); return(ctrl); @@ -2817,7 +2971,8 @@ map_local_bus2(bde_ctrl_t *plx_ctrl, uint32_t dev_base, uint32_t size) /* Map in the device */ ctrl->bde_dev.base_address = plx_ctrl->bde_dev.base_address + dev_base; - ctrl->phys_address = plx_ctrl->phys_address + (resource_size_t)dev_base; + ctrl->iowin[0].addr = plx_ctrl->iowin[0].addr + (resource_size_t)dev_base; + ctrl->iowin[0].size = size; #if 1 addr = (uint8_t *)ctrl->bde_dev.base_address + PL0_REVISION_REG; @@ -2850,12 +3005,12 @@ probe_plx_local_bus(void) } addr_hi_str[0] = 0; #ifdef PHYS_ADDR_IS_64BIT - sprintf(addr_hi_str, "%08x", (uint32_t)(plx_ctrl.phys_address >> 32)); + sprintf(addr_hi_str, "%08x", (uint32_t)(plx_ctrl.iowin[0].addr >> 32)); #endif printk(KERN_ERR "Found PLX %04x:%04x vir: 0x%08x phy: 0x%s%08x\n", plx_ctrl.bde_dev.device, plx_ctrl.bde_dev.rev, plx_ctrl.bde_dev.base_address, addr_hi_str, - (uint32_t)(plx_ctrl.phys_address)); + (uint32_t)(plx_ctrl.iowin[0].addr)); addr = (uint8_t *)plx_ctrl.bde_dev.base_address + CPLD_OFFSET + CPLD_REVISION_REG; val = readl(addr); @@ -2901,7 +3056,13 @@ probe_plx_local_bus(void) static int _init(void) { + unsigned i; #ifdef IPROC_CMICD + /* + * Adjust the PCI driver name to prevent our device file from + * getting removed when the module is unloaded. + */ + _device_driver.name = LINUX_KERNEL_BDE_NAME ".iproc"; #ifdef CONFIG_OF if (of_find_compatible_node(NULL, NULL, IPROC_CMICX_COMPATIBLE)) { iproc_platform_driver_register(&iproc_cmicd_driver); @@ -2923,9 +3084,6 @@ _init(void) #ifdef BCM_ICS _ics_bde_create(); #else /* PCI */ - /* Register our goodies */ - _device_driver.name = LINUX_KERNEL_BDE_NAME; - /* Configure MSI interrupt support */ use_msi = usemsi; @@ -2947,9 +3105,9 @@ _init(void) } #else if (use_msi > PCI_USE_INT_INTX) { - /* Warn if invalid configuration */ - gprintk("MSI interrupts not supported by kernel\n"); - } + /* Warn if invalid configuration */ + gprintk("MSI interrupts not supported by kernel\n"); + } use_msi = PCI_USE_INT_INTX; #endif /* CONFIG_PCI_MSI */ @@ -3001,6 +3159,10 @@ _init(void) } } + for (i = 0; i < LINUX_BDE_MAX_DEVICES; ++i) { + _devices[i].inst_id = BDE_DEV_INST_ID_INVALID; + } + return 0; } @@ -3073,41 +3235,45 @@ _cleanup(void) * Always 0 */ static int -_pprint(void) +_pprint(struct seq_file *m) { int i = 0; - pprintf("Broadcom Device Enumerator (%s)\n", LINUX_KERNEL_BDE_NAME); + pprintf(m, "Broadcom Device Enumerator (%s)\n", LINUX_KERNEL_BDE_NAME); - _dma_pprint(); + pprintf(m, "Module parameters:\n"); + pprintf(m, "\tmaxpayload=%d\n", maxpayload); + pprintf(m, "\tusemsi=%d\n", usemsi); + + _dma_pprint(m); if (_ndevices == 0) { - pprintf("No devices found\n"); + pprintf(m, "No devices found\n"); } else { - pprintf("Devices:\n"); + pprintf(m, "Devices:\n"); } for (i = 0; i < _ndevices; i++) { bde_ctrl_t *ctrl = _devices + i; if (ctrl->dev_type & BDE_SWITCH_DEV_TYPE) { - pprintf("\t%d (swi) : ", i); + pprintf(m, "\t%d (swi) : ", i); } else if (ctrl->dev_type & BDE_ETHER_DEV_TYPE) { - pprintf("\t%d (eth) : ", i); + pprintf(m, "\t%d (eth) : ", i); } else if (ctrl->dev_type & BDE_CPU_DEV_TYPE) { - pprintf("\t%d (cpu) : ", i); + pprintf(m, "\t%d (cpu) : ", i); } else { - pprintf("\t%d (?) : ", i); + pprintf(m, "\t%d (?) : ", i); } if (ctrl->dev_state == BDE_DEV_STATE_REMOVED) { - pprintf("PCI device 0x%x:0x%x:%d REMOVED\n", + pprintf(m, "PCI device 0x%x:0x%x:%d REMOVED\n", ctrl->pci_device->vendor, ctrl->pci_device->device, ctrl->bde_dev.rev); continue; } if (ctrl->dev_type & BDE_PCI_DEV_TYPE) { - pprintf("PCI device %02x:%02x.%x 0x%x:0x%x:%d:0x%.8lx:0x%.8lx:%d%s\n", + pprintf(m, "PCI device %02x:%02x.%x 0x%x:0x%x:%d:0x%.8lx:0x%.8lx:%d%s\n", (unsigned int)ctrl->pci_device->bus->number, PCI_SLOT(ctrl->pci_device->devfn), PCI_FUNC(ctrl->pci_device->devfn), @@ -3119,7 +3285,7 @@ _pprint(void) ctrl->pci_device->irq, ctrl->use_msi ? " (MSI)" : ""); } else if (ctrl->dev_type & BDE_SPI_DEV_TYPE) { - pprintf("SPI Device %d:%x:%x:0x%x:0x%x:%d\n", + pprintf(m, "SPI Device %d:%x:%x:0x%x:0x%x:%d\n", ctrl->spi_device->cid, ctrl->spi_device->part, ctrl->spi_device->rev, @@ -3127,29 +3293,86 @@ _pprint(void) ctrl->spi_device->phyid_low, ctrl->bde_dev.rev); } else if (ctrl->dev_type & BDE_ICS_DEV_TYPE) { - pprintf("ICS Device 0x%x:0x%x\n", + pprintf(m, "ICS Device 0x%x:0x%x\n", ctrl->bde_dev.device, ctrl->bde_dev.rev); } else if (ctrl->dev_type & BDE_AXI_DEV_TYPE) { - pprintf("AXI Device 0x%x:0x%x:0x%.8lx:%d\n", + pprintf(m, "AXI Device 0x%x:0x%x:0x%.8lx:%d\n", ctrl->bde_dev.device, ctrl->bde_dev.rev, - (unsigned long)ctrl->phys_address, + (unsigned long)ctrl->iowin[0].addr, ctrl->iLine); } else if (ctrl->dev_type & BDE_EB_DEV_TYPE) { - pprintf("EB Bus Device 0x%x:0x%x\n", + pprintf(m, "EB Bus Device 0x%x:0x%x\n", ctrl->bde_dev.device, ctrl->bde_dev.rev); } if (debug >= 1) { - pprintf("\t\timask:imask2:fmask 0x%x:0x%x:0x%x\n", + pprintf(m, "\t\timask:imask2:fmask 0x%x:0x%x:0x%x\n", ctrl->imask, ctrl->imask2, ctrl->fmask); } + if (debug >= 1) { + if (ctrl->inst_id == BDE_DEV_INST_ID_INVALID) { + pprintf(m, "\t\tinst_id INVALID\n"); + } else { + pprintf(m, "\t\tinst_id %u%s\n", + ctrl->inst_id, + ctrl->inst_id < LINUX_BDE_MAX_DEVICES ? "":"(Illegal)"); + } + } } return 0; } +/* + * Some kernels are configured to prevent mapping of kernel RAM memory + * into user space via the /dev/mem device. + * + * The function below provides a backdoor to map IO and DMA memory to + * user space via the BDE device file. + */ +static int +_bde_mmap(struct file *filp, struct vm_area_struct *vma) +{ + unsigned long paddr = vma->vm_pgoff << PAGE_SHIFT; + unsigned long size = vma->vm_end - vma->vm_start; + int i, j, pio_range_valid = 0; + + for(i = 0; i < _ndevices; i++) { + bde_ctrl_t *ctrl = _devices + i; + if (ctrl->dev_type & BDE_SWITCH_DEV_TYPE) { + for (j = 0; j < BDE_NUM_IOWIN_MAX; j++) { + if (paddr >= (unsigned long)ctrl->iowin[j].addr && + (paddr + size) <= (unsigned long)(ctrl->iowin[j].addr + ctrl->iowin[j].size)) { + pio_range_valid = 1; + break; + } + if ((ctrl->dev_type & BDE_AXI_DEV_TYPE) && (paddr == ctrl->iowin[j].addr)) { + pio_range_valid = 1; + break; + } + } + } + } + + if (pio_range_valid) { + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + if (remap_pfn_range(vma, + vma->vm_start, + vma->vm_pgoff, + size, + vma->vm_page_prot)) { + gprintk("Failed to mmap phys range 0x%lx-0x%lx to 0x%lx-0x%lx\n", + paddr, paddr + size, vma->vm_start,vma->vm_end); + return -EAGAIN; + } + return 0; + } + + return _dma_mmap(filp, vma); +} /* Workaround for broken Busybox/PPC insmod */ static char _modname[] = LINUX_KERNEL_BDE_NAME; @@ -3160,7 +3383,7 @@ static gmodule_t _gmodule = { init: _init, cleanup: _cleanup, pprint: _pprint, - mmap: _dma_mmap, + mmap: _bde_mmap, }; gmodule_t * @@ -3479,6 +3702,9 @@ _interrupt_connect(int d, if (of_find_compatible_node(NULL, NULL, IPROC_CMICX_COMPATIBLE)) { int i, j; for (i = 0; i < IHOST_CMICX_MAX_INTRS; i++) { + if (!iproc_cmicx_irqs[i]) { + continue; + } if (unlikely(debug >= 1)) gprintk("%s(%d):device# = %d, request_irq(%d)\n", __func__, __LINE__, d, iproc_cmicx_irqs[i]); @@ -3491,6 +3717,9 @@ _interrupt_connect(int d, } if (ret < 0) { for (j = 0; j < i; j++) { + if (!iproc_cmicx_irqs[j]) { + continue; + } free_irq(iproc_cmicx_irqs[j], ctrl); } goto err_disable_msi; @@ -3519,10 +3748,10 @@ _interrupt_connect(int d, msi_exit: #endif gprintk("could not request IRQ\n"); - ctrl->isr = NULL; - ctrl->isr_data = NULL; - ctrl->isr2 = NULL; - ctrl->isr2_data = NULL; + ctrl->isr = NULL; + ctrl->isr_data = NULL; + ctrl->isr2 = NULL; + ctrl->isr2_data = NULL; return -1; } @@ -3600,6 +3829,9 @@ _interrupt_disconnect(int d) if (of_find_compatible_node(NULL, NULL, IPROC_CMICX_COMPATIBLE)) { int i; for (i = 0; i < IHOST_CMICX_MAX_INTRS; i++) { + if (!iproc_cmicx_irqs[i]) { + continue; + } if (unlikely(debug > 1)) { gprintk("%s(%d):device# = %d, free_irq(%d)\n", __func__, __LINE__, d, iproc_cmicx_irqs[i]); @@ -3814,9 +4046,6 @@ lkbde_cpu_pci_register(int d) pci_write_config_byte(ctrl->pci_device, 0x88, 0x2f); pci_write_config_byte(ctrl->pci_device, 0x89, 0x10); break; - case BCM88750_DEVICE_ID: - case BCM88753_DEVICE_ID: - case BCM88755_DEVICE_ID: case BCM88770_DEVICE_ID: case BCM88773_DEVICE_ID: case BCM88774_DEVICE_ID: @@ -3828,7 +4057,6 @@ lkbde_cpu_pci_register(int d) case BCM88954_DEVICE_ID: case BCM88955_DEVICE_ID: case BCM88956_DEVICE_ID: - case BCM88752_DEVICE_ID: case BCM88772_DEVICE_ID: case BCM88952_DEVICE_ID: case ACP_PCI_DEVICE_ID: @@ -3862,10 +4090,10 @@ lkbde_cpu_pci_register(int d) case BCM88683_DEVICE_ID: case BCM88684_DEVICE_ID: case BCM88685_DEVICE_ID: + case BCM88687_DEVICE_ID: case BCM88380_DEVICE_ID: case BCM88381_DEVICE_ID: case BCM88680_DEVICE_ID: - case BCM88800_DEVICE_ID: case BCM88470_DEVICE_ID: case BCM88470P_DEVICE_ID: case BCM88471_DEVICE_ID: @@ -3875,9 +4103,11 @@ lkbde_cpu_pci_register(int d) case BCM88476_DEVICE_ID: case BCM88477_DEVICE_ID: case BCM88270_DEVICE_ID: + case BCM88271_DEVICE_ID: case BCM88272_DEVICE_ID: case BCM88273_DEVICE_ID: case BCM88274_DEVICE_ID: + case BCM88276_DEVICE_ID: case BCM88278_DEVICE_ID: case BCM8206_DEVICE_ID: case BCM88350_DEVICE_ID: @@ -3915,34 +4145,42 @@ lkbde_cpu_pci_register(int d) break; } + /* configure iproc >=14 devices by device family */ +#if defined(BCM_DNXF_SUPPORT) || defined(BCM_DNX_SUPPORT) + switch (ctrl->bde_dev.device & DNXC_DEVID_FAMILY_MASK) { #ifdef BCM_DNX_SUPPORT - /*All Jericho 2 devices from 0x8690 to 0x869F*/ - if (SOC_IS_JERICHO_2_TYPE(ctrl->bde_dev.device)) { - /* Fix bar 0 address */ /* FIXME: write full phy address */ - pci_write_config_byte(ctrl->pci_device, 0x12, 0x10); - pci_write_config_byte(ctrl->pci_device, 0x13, 0x60); - + case JERICHO2_DEVICE_ID: + case J2C_DEVICE_ID: + case J2C_2ND_DEVICE_ID: + case Q2A_DEVICE_ID: + case Q2U_DEVICE_ID: + case J2P_DEVICE_ID: +#endif +#ifdef BCM_DNXF_SUPPORT + case BCM88790_DEVICE_ID: +#endif /* * For DMA transactions - set Max_Payload_Size and * Max_Read_Request_Size to 128 bytes. */ pci_write_config_byte(ctrl->pci_device, 0xb5, 0x0c); pci_write_config_byte(ctrl->pci_device, 0xb4, 0x0); + break; } -#endif +#endif /* defined(BCM_DNXF_SUPPORT) || defined(BCM_DNX_SUPPORT) */ /* Redo ioremap */ if (ctrl->bde_dev.base_address) { iounmap((void *)ctrl->bde_dev.base_address); } - ctrl->bde_dev.base_address = (sal_vaddr_t)IOREMAP(ctrl->phys_address, 0x1000000); + ctrl->bde_dev.base_address = (sal_vaddr_t)IOREMAP(ctrl->iowin[0].addr, 0x1000000); if (debug >= 1) { gprintk("%s, %s(): info:\n", __FILE__, __FUNCTION__); gprintk("_ndevices=%d, _switch_ndevices=%d\n", _ndevices, _switch_ndevices); gprintk("ctrl->dev_type=0x%x, ctrl->phys_address=0x%lx\n", - ctrl->dev_type, (unsigned long)ctrl->phys_address); + ctrl->dev_type, (unsigned long)ctrl->iowin[0].addr); gprintk("ctrl->bde_dev.device=0x%x, ctrl->bde_dev.rev=0x%x, " "ctrl->bde_dev.base_address=0x%lx\n", ctrl->bde_dev.device, ctrl->bde_dev.rev, @@ -4089,7 +4327,7 @@ lkbde_get_dev_phys(int d) d, _devices[d].dev_type); return 0; } - return _devices[d].phys_address; + return _devices[d].iowin[0].addr; } uint32_t @@ -4105,7 +4343,7 @@ lkbde_get_dev_phys_hi(int d) return 0; } #ifdef PHYS_ADDR_IS_64BIT - return (uint32_t)(_devices[d].phys_address >> 32); + return (uint32_t)(_devices[d].iowin[0].addr >> 32); #else return 0; #endif @@ -4132,14 +4370,14 @@ lkbde_get_dev_virt(int d) } int -lkbde_get_dev_resource(int d, int rsrc, uint32_t *flags, - uint32_t *phys_lo, uint32_t *phys_hi) +lkbde_get_dev_resource(int d, int rsrc, uint32_t *phys_lo, + uint32_t *phys_hi, uint32_t *size) { if (!VALID_DEVICE(d)) { return -1; } - *flags = 0; + *size = 0; *phys_lo = 0; *phys_hi = 0; @@ -4151,16 +4389,18 @@ lkbde_get_dev_resource(int d, int rsrc, uint32_t *flags, switch (rsrc) { case 0: - *phys_lo = (uint32_t)(_devices[d].phys_address); + *phys_lo = (uint32_t)(_devices[d].iowin[0].addr); #ifdef PHYS_ADDR_IS_64BIT - *phys_hi = (uint32_t)(_devices[d].phys_address >> 32); + *phys_hi = (uint32_t)(_devices[d].iowin[0].addr >> 32); #endif + *size = _devices[d].iowin[0].size; break; case 1: - *phys_lo = (uint32_t)(_devices[d].phys_address1); + *phys_lo = (uint32_t)(_devices[d].iowin[1].addr); #ifdef PHYS_ADDR_IS_64BIT - *phys_hi = (uint32_t)(_devices[d].phys_address1 >> 32); + *phys_hi = (uint32_t)(_devices[d].iowin[1].addr >> 32); #endif + *size = _devices[d].iowin[1].size; break; default: break; @@ -4326,7 +4566,7 @@ lkbde_irq_mask_get(int d, uint32_t *mask, uint32_t *fmask) *fmask = ctrl->fmask; *mask = ctrl->imask | ctrl->imask2; - + return 0; } @@ -4336,6 +4576,29 @@ lkbde_get_num_devices(int type) return _num_devices(type); } +/* + * Return none-zero if the SDK instance with the given instance ID + * manages the given device. + */ +int lkbde_is_dev_managed_by_instance(uint32 dev, uint32 inst_id) +{ + if (inst_id >= LINUX_BDE_MAX_DEVICES || dev >= _ndevices) { + return 0; + } + return _instance_info[inst_id].devices[dev / 32] & (1 << (dev % 32)) ? 1 : 0; +} + +/* + * Return a pointer to the bitmap of the SDK instance managed devices. + */ +linux_bde_device_bitmap_t* lkbde_get_inst_devs(uint32 inst_id) +{ + if (inst_id >= LINUX_BDE_MAX_DEVICES) { + return NULL; + } + return &_instance_info[inst_id].devices; +} + /* * Export functions */ @@ -4358,3 +4621,5 @@ LKM_EXPORT_SYM(lkbde_cpu_write); LKM_EXPORT_SYM(lkbde_cpu_read); LKM_EXPORT_SYM(lkbde_cpu_pci_register); #endif +LKM_EXPORT_SYM(lkbde_is_dev_managed_by_instance); +LKM_EXPORT_SYM(lkbde_get_inst_devs); diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux_dma.c b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux_dma.c index eb3dc0495195..52711964a533 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux_dma.c +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux_dma.c @@ -1,5 +1,10 @@ /* - * Copyright 2017 Broadcom + * Copyright 2007-2020 Broadcom Inc. All rights reserved. + * + * Permission is granted to use, copy, modify and/or distribute this + * software under either one of the licenses below. + * + * License Option 1: GPL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. + * + * + * License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license + * + * This software is governed by the Broadcom Open Network Switch APIs license: + * https://www.broadcom.com/products/ethernet-connectivity/software/opennsa */ /* * $Id: linux_dma.c,v 1.414 Broadcom SDK $ @@ -67,6 +78,10 @@ #include #include +#if defined(IPROC_CMICD) && defined(CONFIG_OF) +#include +#endif + #ifdef BCM_PLX9656_LOCAL_BUS #include #endif @@ -74,9 +89,10 @@ /* allocation types/methods for the DMA memory pool */ #define ALLOC_TYPE_CHUNK 0 /* use small allocations and join them */ #define ALLOC_TYPE_API 1 /* use one allocation */ + #if _SIMPLE_MEMORY_ALLOCATION_ #include -#if defined(IPROC_CMICD) && defined(CONFIG_CMA) && defined(CONFIG_CMA_SIZE_MBYTES) +#if defined(CONFIG_CMA) && defined(CONFIG_CMA_SIZE_MBYTES) #define DMA_MAX_ALLOC_SIZE (CONFIG_CMA_SIZE_MBYTES * 1024 * 1024) #else #define DMA_MAX_ALLOC_SIZE (1 << (MAX_ORDER - 1 + PAGE_SHIFT)) /* Maximum size the kernel can allocate in one allocation */ @@ -84,6 +100,7 @@ #endif /* _SIMPLE_MEMORY_ALLOCATION_ */ #if _SIMPLE_MEMORY_ALLOCATION_ == 1 +/* Use Linux DMA API to allocate contiguous memory */ #define ALLOC_METHOD_DEFAULT ALLOC_TYPE_API #if defined(__arm__) #define USE_DMA_MMAP_COHERENT @@ -117,9 +134,9 @@ #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) -#define DMA_MAPPING_ERROR(d, p) dma_mapping_error((d),(p)) +#define BDE_DMA_MAPPING_ERROR(d, p) dma_mapping_error((d),(p)) #else -#define DMA_MAPPING_ERROR(d, p) dma_mapping_error((p)) +#define BDE_DMA_MAPPING_ERROR(d, p) dma_mapping_error((p)) #endif #ifndef KMALLOC_MAX_SIZE @@ -192,6 +209,17 @@ MODULE_PARM_DESC(himemaddr, #define DMA_MEM_DEFAULT (8 * ONE_MB) #endif +#ifdef BDE_EDK_SUPPORT +typedef struct { + phys_addr_t cpu_pbase; /* CPU physical base address of the DMA pool */ + phys_addr_t dma_pbase; /* Bus base address of the DMA pool */ + void __iomem *dma_vbase; + uint32 size; /* Total size of the pool */ +}_edk_dma_pool_t; +static _edk_dma_pool_t _edk_dma_pool[LINUX_BDE_MAX_DEVICES]; +static int _edk_use_dma_mapping = 0; +#endif + /* We try to assemble a contiguous segment from chunks of this size */ #define DMA_BLOCK_SIZE (512 * ONE_KB) @@ -548,18 +576,145 @@ _pgfree(void *ptr) return -1; } +#ifdef BDE_EDK_SUPPORT /* - * Function: _pgcleanup + * Function: _edk_mpool_free * * Purpose: - * Free all memory allocated by _pgalloc + * Free all memory allocated by _adk_mpool_alloc * Parameters: * None * Returns: * Nothing. */ static void -_pgcleanup(void) +_edk_mpool_free(void) +{ + int i, ndevices; + + ndevices = BDE_NUM_DEVICES(BDE_SWITCH_DEVICES); + for (i = 0; i < ndevices && DMA_DEV(i); i ++) { + if (_edk_dma_pool[i].dma_vbase) { + if (_edk_use_dma_mapping) { + dma_unmap_single(DMA_DEV(i), (dma_addr_t)_edk_dma_pool[i].dma_pbase, + _edk_dma_pool[i].size, DMA_BIDIRECTIONAL); + } + _pgfree(_edk_dma_pool[i].dma_vbase); + _edk_dma_pool[i].dma_vbase = NULL; + } + } + _edk_use_dma_mapping = 0; +} + +/* + * Function: edk_mpool_alloc + * + * Purpose: + * Allocate DMA memory pool for EDK + * Parameters: + * size - size of DMA memory pool + * Returns: + * Nothing. + */ +static void +_edk_mpool_alloc(int dev_id, size_t size) +{ + static void __iomem *dma_vbase = NULL; + static phys_addr_t cpu_pbase = 0; + static phys_addr_t dma_pbase = 0; + + struct device *dev = DMA_DEV(DMA_DEV_INDEX); + unsigned long pbase = 0; + + dma_vbase = _pgalloc(size); + if (!dma_vbase) { + gprintk("Failed to allocate memory pool of size 0x%lx for EDK\n", + (unsigned long)size); + return; + } + cpu_pbase = virt_to_bus(dma_vbase); + + /* Use dma_map_single to obtain DMA bus address or IOVA if IOMMU is present. */ + if (dev) { + pbase = dma_map_single(dev, dma_vbase, size, DMA_BIDIRECTIONAL); + if (BDE_DMA_MAPPING_ERROR(dev, pbase)) { + gprintk("Failed to map memory at %p for EDK\n", dma_vbase); + _pgfree(dma_vbase); + dma_vbase = NULL; + return; + } + _edk_use_dma_mapping = 1; + } else { + pbase = cpu_pbase; + } + + dma_pbase = pbase; + +#ifdef REMAP_DMA_NONCACHED + _dma_vbase = IOREMAP(dma_pbase, size); +#endif + _edk_dma_pool[dev_id].cpu_pbase = cpu_pbase; + _edk_dma_pool[dev_id].dma_pbase = dma_pbase; + _edk_dma_pool[dev_id].dma_vbase = dma_vbase; + _edk_dma_pool[dev_id].size = size; +} + +int +lkbde_edk_get_dma_info(int dev_id, phys_addr_t* cpu_pbase, phys_addr_t* dma_pbase, ssize_t* size) +{ + if (_edk_dma_pool[dev_id].dma_vbase == NULL) { + _edk_mpool_alloc(dev_id, *size * ONE_MB); + } + + if (cpu_pbase) { + *cpu_pbase = _edk_dma_pool[dev_id].cpu_pbase; + } + + if (dma_pbase) { + *dma_pbase = _edk_dma_pool[dev_id].dma_pbase; + } + + *size = (_edk_dma_pool[dev_id].dma_vbase) ? _edk_dma_pool[dev_id].size : 0; + return 0; +} + +/* + * The below function validates the memory to the EDK allocated DMA pool, + * required to user space via the BDE device file. + */ +static int +_edk_vm_is_valid(struct file *filp, struct vm_area_struct *vma) +{ + unsigned long phys_addr = vma->vm_pgoff << PAGE_SHIFT; + unsigned long size = vma->vm_end - vma->vm_start; + int i, ndevices; + + ndevices = BDE_NUM_DEVICES(BDE_SWITCH_DEVICES); + for (i = 0; i < ndevices; i++) { + if (phys_addr < (unsigned long )_edk_dma_pool[i].cpu_pbase || + (phys_addr + size) > ((unsigned long )_edk_dma_pool[i].cpu_pbase + + _edk_dma_pool[i].size)) { + continue; + } + return 1; + } + + return 0; +} +#endif + +/* + * Function: _mpool_free + * + * Purpose: + * Free all memory allocated by _mpool_alloc + * Parameters: + * None + * Returns: + * Nothing. + */ +static void +_mpool_free(void) { switch (dmaalloc) { #if _SIMPLE_MEMORY_ALLOCATION_ @@ -595,7 +750,7 @@ _pgcleanup(void) } /* - * Function: _alloc_mpool + * Function: _mpool_alloc * * Purpose: * Allocate DMA memory pool @@ -609,9 +764,18 @@ _pgcleanup(void) * It is assumed there is only one pool. */ static void -_alloc_mpool(size_t size) +_mpool_alloc(size_t size) { unsigned long pbase = 0; + struct device *dev = DMA_DEV(DMA_DEV_INDEX); + int dma64_support = 0; + +#if defined(IPROC_CMICD) && defined(CONFIG_OF) + if (of_find_compatible_node(NULL, NULL, "brcm,iproc-cmicx")) { + dma64_support = 1; + } +#endif + #if defined(__arm__) && !defined(CONFIG_HIGHMEM) if (_use_himem) { gprintk("DMA in high memory requires CONFIG_HIGHMEM on ARM CPUs.\n"); @@ -630,7 +794,22 @@ _alloc_mpool(size_t size) gprintk("DMA in high memory at 0x%lx size 0x%lx is beyond the 4GB limit and not supported.\n", pbase, (unsigned long)size); return; } - _cpu_pbase = _dma_pbase = pbase; + _cpu_pbase = pbase; + if (dev) { + /* Use dma_map_single to obtain DMA bus address or I/O virtual address, if + IOMMU is present. */ + pbase = dma_map_single(dev, bus_to_virt(_cpu_pbase), size, DMA_BIDIRECTIONAL); + if (BDE_DMA_MAPPING_ERROR(dev, pbase)) { + gprintk("Error !! Failed to map memory at phys base 0x%lx\n", + (unsigned long)_cpu_pbase); + _cpu_pbase = 0; + return; + } + _use_dma_mapping = 1; + } else { + pbase = _cpu_pbase; + } + _dma_pbase = pbase; _dma_vbase = IOREMAP(_dma_pbase, size); } else { /* Get DMA memory from kernel */ @@ -647,8 +826,8 @@ _alloc_mpool(size_t size) /* get a memory allocation from the kernel */ { dma_addr_t dma_handle; - if (!(_dma_vbase = dma_alloc_coherent(DMA_DEV(DMA_DEV_INDEX), - alloc_size, &dma_handle, GFP_KERNEL)) || !dma_handle) { + _dma_vbase = dma_alloc_coherent(dev, alloc_size, &dma_handle, GFP_KERNEL); + if (!_dma_vbase || !dma_handle) { gprintk("Failed to allocate coherent memory pool of size 0x%lx\n", (unsigned long)alloc_size); return; } @@ -671,14 +850,13 @@ _alloc_mpool(size_t size) return; } _cpu_pbase = virt_to_bus(_dma_vbase); - /* Use dma_map_single to obtain DMA bus address or IOVA if iommu is present. */ - if (DMA_DEV(DMA_DEV_INDEX)) { - pbase = dma_map_single(DMA_DEV(DMA_DEV_INDEX), _dma_vbase, size, DMA_BIDIRECTIONAL); - if (DMA_MAPPING_ERROR(DMA_DEV(DMA_DEV_INDEX), pbase)) { + /* Use dma_map_single to obtain DMA bus address or IOVA if IOMMU is present. */ + if (dev) { + pbase = dma_map_single(dev, _dma_vbase, size, DMA_BIDIRECTIONAL); + if (BDE_DMA_MAPPING_ERROR(dev, pbase)) { gprintk("Failed to map memory at %p\n", _dma_vbase); - _pgcleanup(); + _mpool_free(); _dma_vbase = NULL; - _cpu_pbase = 0; return; } _use_dma_mapping = 1; @@ -692,22 +870,23 @@ _alloc_mpool(size_t size) return; } - if (((pbase + (size - 1)) >> 16) > DMA_BIT_MASK(16)) { + _dma_pbase = pbase; + + if (!dma64_support && ((pbase + (size - 1)) >> 16) > DMA_BIT_MASK(16)) { gprintk("DMA memory allocated at 0x%lx size 0x%lx is beyond the 4GB limit and not supported.\n", pbase, (unsigned long)size); - _pgcleanup(); + _mpool_free(); _dma_vbase = NULL; _dma_pbase = 0; return; } - _dma_pbase = pbase; #ifdef REMAP_DMA_NONCACHED _dma_vbase = IOREMAP(_dma_pbase, size); #endif if (dma_debug >= 1) { - gprintk("_use_dma_mapping:%d _dma_vbase:%p _dma_pbase:%lx _cpu_pbase:%lx allocated:%lx dmaalloc:%d\n", + gprintk("_use_dma_mapping:%d _dma_vbase:%p _dma_pbase:%lx _cpu_pbase:%lx allocated:%lx dmaalloc:%d, dma64_support:%d\n", _use_dma_mapping, _dma_vbase, (unsigned long)_dma_pbase, - (unsigned long)_cpu_pbase, (unsigned long)size, dmaalloc); + (unsigned long)_cpu_pbase, (unsigned long)size, dmaalloc, dma64_support); } } } @@ -725,15 +904,27 @@ _alloc_mpool(size_t size) int _dma_cleanup(void) { +#ifdef BDE_EDK_SUPPORT + _edk_mpool_free(); +#endif if (_dma_vbase) { mpool_destroy(_dma_pool); if (_use_himem) { + int i, ndevices; iounmap(_dma_vbase); + if (_use_dma_mapping) { + ndevices = BDE_NUM_DEVICES(BDE_SWITCH_DEVICES); + for (i = 0; i < ndevices && DMA_DEV(i); i ++) { + dma_unmap_single(DMA_DEV(i), (dma_addr_t)_dma_pbase, _dma_mem_size, + DMA_BIDIRECTIONAL); + } + _use_dma_mapping = 0; + } } else { #ifdef REMAP_DMA_NONCACHED iounmap(_dma_vbase); #endif - _pgcleanup(); + _mpool_free(); } _dma_vbase = NULL; _dma_pbase = 0; @@ -749,7 +940,7 @@ void _dma_init(int dev_index) if (dev_index > DMA_DEV_INDEX) { if (_use_dma_mapping && DMA_DEV(dev_index) && _dma_vbase) { pbase = dma_map_single(DMA_DEV(dev_index), _dma_vbase, _dma_mem_size, DMA_BIDIRECTIONAL); - if (DMA_MAPPING_ERROR(DMA_DEV(dev_index), pbase)) { + if (BDE_DMA_MAPPING_ERROR(DMA_DEV(dev_index), pbase)) { gprintk("Failed to map memory for device %d at %p\n", dev_index, _dma_vbase); return; } @@ -797,7 +988,7 @@ void _dma_init(int dev_index) } if (_dma_mem_size) { - _alloc_mpool(_dma_mem_size); + _mpool_alloc(_dma_mem_size); if (_dma_vbase == NULL) { gprintk("no DMA memory available\n"); } else { @@ -821,10 +1012,17 @@ int _dma_mmap(struct file *filp, struct vm_area_struct *vma) if (phys_addr < (unsigned long )_cpu_pbase || (phys_addr + size) > ((unsigned long )_cpu_pbase + _dma_mem_size)) { +#ifdef BDE_EDK_SUPPORT + if(!_edk_vm_is_valid(filp, vma)) { + gprintk("range 0x%lx-0x%lx outside DMA pool\n", phys_addr, phys_addr + size); + return -EINVAL; + } +#else gprintk("range 0x%lx-0x%lx outside DMA pool 0x%lx-0x%lx\n", phys_addr, phys_addr + size, (unsigned long )_cpu_pbase, (unsigned long )_cpu_pbase + _dma_mem_size); return -EINVAL; +#endif } #ifdef USE_DMA_MMAP_COHERENT @@ -981,7 +1179,7 @@ lkbde_get_dma_info(phys_addr_t* cpu_pbase, phys_addr_t* dma_pbase, ssize_t* size if (_dma_mem_size == 0) { _dma_mem_size = DMA_MEM_DEFAULT; } - _alloc_mpool(_dma_mem_size); + _mpool_alloc(_dma_mem_size); } *cpu_pbase = _cpu_pbase; *dma_pbase = _dma_pbase; @@ -990,9 +1188,12 @@ lkbde_get_dma_info(phys_addr_t* cpu_pbase, phys_addr_t* dma_pbase, ssize_t* size } void -_dma_pprint(void) +_dma_pprint(struct seq_file *m) { - pprintf("DMA Memory (%s): %d bytes, %d used, %d free%s\n", + pprintf(m, "\tdmasize=%s\n", dmasize); + pprintf(m, "\thimem=%s\n", himem); + pprintf(m, "\thimemaddr=%s\n", himemaddr); + pprintf(m, "DMA Memory (%s): %d bytes, %d used, %d free%s\n", (_use_himem) ? "high" : "kernel", (_dma_vbase) ? _dma_mem_size : 0, (_dma_vbase) ? mpool_usage(_dma_pool) : 0, @@ -1003,6 +1204,10 @@ _dma_pprint(void) /* * Export functions */ + +#ifdef BDE_EDK_SUPPORT +LKM_EXPORT_SYM(lkbde_edk_get_dma_info); +#endif LKM_EXPORT_SYM(kmalloc_giant); LKM_EXPORT_SYM(kfree_giant); LKM_EXPORT_SYM(lkbde_get_dma_info); diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux_shbde.c b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux_shbde.c index a2d58858a5a5..dd003e1f9297 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux_shbde.c +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux_shbde.c @@ -1,5 +1,10 @@ /* - * Copyright 2017 Broadcom + * Copyright 2007-2020 Broadcom Inc. All rights reserved. + * + * Permission is granted to use, copy, modify and/or distribute this + * software under either one of the licenses below. + * + * License Option 1: GPL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. + * + * + * License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license + * + * This software is governed by the Broadcom Open Network Switch APIs license: + * https://www.broadcom.com/products/ethernet-connectivity/software/opennsa */ /* * $Id: $ diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux_shbde.h b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux_shbde.h index 5e8a70119e85..ef4b49dc2124 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux_shbde.h +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux_shbde.h @@ -1,5 +1,10 @@ /* - * Copyright 2017 Broadcom + * Copyright 2007-2020 Broadcom Inc. All rights reserved. + * + * Permission is granted to use, copy, modify and/or distribute this + * software under either one of the licenses below. + * + * License Option 1: GPL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. + * + * + * License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license + * + * This software is governed by the Broadcom Open Network Switch APIs license: + * https://www.broadcom.com/products/ethernet-connectivity/software/opennsa */ /* * $Id: $ diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/shared/mpool.c b/platform/broadcom/saibcm-modules/systems/bde/linux/shared/mpool.c index 13206596ee26..4c2db5e4de6c 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/shared/mpool.c +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/shared/mpool.c @@ -1,5 +1,10 @@ /* - * Copyright 2017 Broadcom + * Copyright 2007-2020 Broadcom Inc. All rights reserved. + * + * Permission is granted to use, copy, modify and/or distribute this + * software under either one of the licenses below. + * + * License Option 1: GPL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. + * + * + * License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license + * + * This software is governed by the Broadcom Open Network Switch APIs license: + * https://www.broadcom.com/products/ethernet-connectivity/software/opennsa */ /* * $Id: mpool.c,v 1.18 Broadcom SDK $ @@ -71,7 +82,7 @@ static sal_sem_t _mpool_lock; #endif #define MPOOL_BUF_SIZE 1024 -#define MPOOL_BUF_ALLOC_COUNT_MAX 16 +#define MPOOL_BUF_ALLOC_COUNT_MAX 128 typedef struct mpool_mem_s { unsigned char *address; @@ -80,20 +91,42 @@ typedef struct mpool_mem_s { struct mpool_mem_s *next; } mpool_mem_t; +static int _mpool_count; static int _buf_alloc_count; static mpool_mem_t *mpool_buf[MPOOL_BUF_ALLOC_COUNT_MAX]; static mpool_mem_t *free_list; -#define ALLOC_INIT_MPOOL_BUF(ptr) \ - ptr = MALLOC((sizeof(mpool_mem_t) * MPOOL_BUF_SIZE)); \ - if (ptr) { \ - int i; \ - for (i = 0; i < MPOOL_BUF_SIZE - 1; i++) { \ - ptr[i].next = &ptr[i+1]; \ - } \ - ptr[MPOOL_BUF_SIZE - 1].next = NULL; \ - free_list = &ptr[0]; \ - } +static mpool_mem_t * +_mpool_buf_create(void) +{ + int i; + mpool_mem_t *ptr; + + if (_buf_alloc_count == MPOOL_BUF_ALLOC_COUNT_MAX) { + return NULL; + } + + mpool_buf[_buf_alloc_count] = MALLOC((sizeof(mpool_mem_t) * MPOOL_BUF_SIZE)); + if (!mpool_buf[_buf_alloc_count]) { + return NULL; + } + + ptr = mpool_buf[_buf_alloc_count]; + for (i = 0; i < MPOOL_BUF_SIZE - 1; i++) { + ptr[i].next = &ptr[i+1]; + } + + ptr[MPOOL_BUF_SIZE - 1].next = NULL; + + if (free_list) { + free_list->next = &ptr[0]; + } else { + free_list = &ptr[0]; + } + + _buf_alloc_count++; + return ptr; +} /* * Function: mpool_init @@ -108,7 +141,15 @@ static mpool_mem_t *free_list; int mpool_init(void) { + int i; + MPOOL_LOCK_INIT(); + _buf_alloc_count = 0; + _mpool_count = 0; + for (i = 0; i < MPOOL_BUF_ALLOC_COUNT_MAX; i++) { + mpool_buf[i] = NULL; + } + free_list = NULL; return 0; } @@ -140,7 +181,7 @@ mpool_alloc(mpool_handle_t pool, int size) } mod = size & (BCM_CACHE_LINE_BYTES - 1); - if (mod != 0 ) { + if (mod != 0) { size += (BCM_CACHE_LINE_BYTES - mod); } while (ptr && ptr->next) { @@ -155,20 +196,9 @@ mpool_alloc(mpool_handle_t pool, int size) return NULL; } - if (!free_list) { - if (_buf_alloc_count == MPOOL_BUF_ALLOC_COUNT_MAX) { - MPOOL_UNLOCK(); - return NULL; - } - - ALLOC_INIT_MPOOL_BUF(mpool_buf[_buf_alloc_count]); - - if (mpool_buf[_buf_alloc_count] == NULL) { - MPOOL_UNLOCK(); - return NULL; - } - - _buf_alloc_count++; + if (!free_list && !_mpool_buf_create()) { + MPOOL_UNLOCK(); + return NULL; } newptr = free_list; @@ -251,25 +281,16 @@ mpool_create(void *base_ptr, int size) { mpool_mem_t *head, *tail; int mod = (int)(((unsigned long)base_ptr) & (BCM_CACHE_LINE_BYTES - 1)); - int i; MPOOL_LOCK(); - for (i = 0; i < MPOOL_BUF_ALLOC_COUNT_MAX; i++) { - mpool_buf[i] = NULL; - } - - _buf_alloc_count = 0; - - ALLOC_INIT_MPOOL_BUF(mpool_buf[_buf_alloc_count]); - - if (mpool_buf[_buf_alloc_count] == NULL) { - MPOOL_UNLOCK(); - return NULL; + if (!free_list || !(free_list->next)) { + if (!_mpool_buf_create()) { + MPOOL_UNLOCK(); + return NULL; + } } - _buf_alloc_count++; - if (mod) { base_ptr = (char*)base_ptr + (BCM_CACHE_LINE_BYTES - mod); size -= (BCM_CACHE_LINE_BYTES - mod); @@ -288,6 +309,7 @@ mpool_create(void *base_ptr, int size) head->next = tail; tail->prev = head; tail->next = NULL; + _mpool_count++; MPOOL_UNLOCK(); return head; @@ -307,19 +329,27 @@ int mpool_destroy(mpool_handle_t pool) { int i; + mpool_mem_t *head = pool; MPOOL_LOCK(); - if ((mpool_mem_t *)pool != mpool_buf[0]) { + if (!(head && head->prev)) { MPOOL_UNLOCK(); return 0; } - for (i = 0; i < MPOOL_BUF_ALLOC_COUNT_MAX; i++) { - if (mpool_buf[i]) { - FREE(mpool_buf[i]); - mpool_buf[i] = NULL; + head->prev->next = free_list; + free_list = head; + _mpool_count--; + + if (_mpool_count == 0) { + for (i = 0; i < MPOOL_BUF_ALLOC_COUNT_MAX; i++) { + if (mpool_buf[i]) { + FREE(mpool_buf[i]); + mpool_buf[i] = NULL; + } } + free_list = NULL; } MPOOL_UNLOCK(); diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/Makefile b/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/Makefile index 424f2fe24bee..2cc96df02d0a 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/Makefile +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/Makefile @@ -1,5 +1,10 @@ # -# Copyright 2017 Broadcom +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ # # You should have received a copy of the GNU General Public License # version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa # # -*- Makefile -*- # $Id: Makefile,v 1.1 Broadcom SDK $ diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.c b/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.c index 370f89e022c4..4e6186e2d80d 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.c +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.c @@ -1,23 +1,20 @@ /* * Copyright 2017 Broadcom - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as * published by the Free Software Foundation (the "GPL"). - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 (GPLv2) for more details. - * + * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. */ + /* - * $Id: linux-user-bde.c,v 1.80 Broadcom SDK $ - * $Copyright: (c) 2005 Broadcom Corp. - * All Rights Reserved.$ - * * Linux User BDE Helper Module */ #include @@ -27,14 +24,13 @@ #include #include #include - +#include #include "linux-user-bde.h" #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) #include #endif - MODULE_AUTHOR("Broadcom Corporation"); MODULE_DESCRIPTION("User BDE Helper Module"); MODULE_LICENSE("GPL"); @@ -74,13 +70,36 @@ MODULE_LICENSE("GPL"); /* CMICX defines */ #define INTC_INTR_REG_NUM (8) - +#define PAXB_INTRCLR_DELAY_REG_NUM (16) /* TODO:HX5 The INTR base address values are changed for HX5, hence making new #defines so runtime decisions can be made. */ +#define PAXB_0_PAXB_IC_INTRCLR_0 (0x180123a0) +#define PAXB_0_PAXB_IC_INTRCLR_1 (0x180123a4) +#define PAXB_0_PAXB_IC_INTRCLR_MODE_0 (0x180123a8) +#define PAXB_0_PAXB_IC_INTRCLR_MODE_1 (0x180123ac) +#define PAXB_0_PAXB_INTR_STATUS (0x18012f38) +#define PAXB_0_PAXB_IC_INTR_PACING_CTRL (0x18012398) +#define PAXB_0_PAXB_INTRCLR_DELAY_UNIT (0x1801239c) +#define PAXB_0_PAXB_IC_INTRCLR_DELAY_REG0 (0x180123b0) +#define PAXB_0_PCIE_ERROR_STATUS (0x18012024) + +#define HX5_PAXB_0_PAXB_IC_INTRCLR_0 (0x102303a0) +#define HX5_PAXB_0_PAXB_IC_INTRCLR_1 (0x102303a4) + +#define HX5_PAXB_0_PAXB_IC_INTRCLR_MODE_0 (0x102303a8) +#define HX5_PAXB_0_PAXB_IC_INTRCLR_MODE_1 (0x102303ac) +#define HX5_PAXB_0_PAXB_INTR_STATUS (0x10230f38) +#define HX5_PAXB_0_PAXB_IC_INTR_PACING_CTRL (0x10230398) +#define HX5_PAXB_0_PAXB_INTRCLR_DELAY_UNIT (0x1023039c) +#define HX5_PAXB_0_PAXB_IC_INTRCLR_DELAY_REG0 (0x102303b0) +#define HX5_PAXB_0_PCIE_ERROR_STATUS (0x10230024) + +#define PAXB_0_PAXB_IC_INTRCLR_DELAY_BASE (PAXB_0_PAXB_IC_INTRCLR_DELAY_REG0) +#define HX5_PAXB_0_PAXB_IC_INTRCLR_DELAY_BASE (HX5_PAXB_0_PAXB_IC_INTRCLR_DELAY_REG0) #define INTC_INTR_ENABLE_REG0 (0x180130f0) #define INTC_INTR_STATUS_REG0 (0x18013190) @@ -104,20 +123,26 @@ be made. #define HX5_IHOST_GICD_ISENABLERN_1 (0x10781104) #define HX5_IHOST_GICD_ICENABLERN_1 (0x10781184) #define HX5_IHOST_GICD_ICENABLERN_8 (0x107811a0) +#define HX5_IHOST_GICD_ISPENDRN_8 (0x10781220) /* Offset between ISENABLERN_1 and ICENABLERN_1 in 4-bytes */ #define HX5_IHOST_IRQ_MASK_OFFSET 0x20 -#define HX5_IHOST_INTR_MAP_NUM (HX5_IHOST_GICD_ICENABLERN_8 - HX5_IHOST_GICD_ISENABLERN_0) +/* Offset between ISENABLERN_1 and ISPENDRN_1 in 4-bytes */ +#define HX5_IHOST_IRQ_PEND_OFFSET 0x40 +#define HX5_IHOST_INTR_MAP_NUM (HX5_IHOST_GICD_ISPENDRN_8 - HX5_IHOST_GICD_ISENABLERN_0) #define HX5_IHOST_INTR_STATUS_MAP_NUM (INTC_INTR_REG_NUM * (sizeof(uint32))) #define IRQ_BIT(intr) (intr % (sizeof(uint32)*8)) #define IRQ_MASK_INDEX(intr) (intr / (sizeof(uint32)*8)) +#define HX5_SW_PROG_INTR_PRIORITY 73 +#define INTR_SW_PROG_INTR_BITPOS (1 << IRQ_BIT(HX5_SW_PROG_INTR_PRIORITY)) +#define INTC_SW_PROG_INTR_REG_IND IRQ_MASK_INDEX(HX5_SW_PROG_INTR_PRIORITY) #define HX5_CHIP_INTR_LOW_PRIORITY 119 #define INTR_LOW_PRIORITY_BITPOS (1 << IRQ_BIT(HX5_CHIP_INTR_LOW_PRIORITY)) #define INTC_LOW_PRIORITY_INTR_REG_IND IRQ_MASK_INDEX(HX5_CHIP_INTR_LOW_PRIORITY) #define INTC_PDMA_INTR_REG_IND 4 -#define READ_INTC_INTR(d, reg, v) \ +#define IPROC_READ(d, reg, v) \ (v = user_bde->iproc_read(d, reg)) -#define WRITE_INTC_INTR(d, reg, v) \ +#define IPROC_WRITE(d, reg, v) \ (user_bde->iproc_write(d, reg, v)) #define IHOST_READ_INTR(d, reg, v) \ @@ -141,10 +166,47 @@ be made. static uint32 *ihost_intr_status_base = NULL; static uint32 *ihost_intr_enable_base = NULL; +/* Module parameter for Interruptible timeout */ +static int intr_timeout = 0; +LKM_MOD_PARAM(intr_timeout, "i", int, (S_IRUGO | S_IWUSR)); +MODULE_PARM_DESC(intr_timeout, +"Interruptible wait timeout in milliseconds for Interrupt to be triggered."); + +static ulong intr_count = 0; +LKM_MOD_PARAM(intr_count, "intr_count", ulong, (S_IRUGO | S_IWUSR)); +MODULE_PARM_DESC(intr_count, +"Interrupt count provides information about the number of times the ISR is called."); + +static ulong intr_timeout_count = 0; +LKM_MOD_PARAM(intr_timeout_count, "intr_timeout_count", ulong, (S_IRUGO | S_IWUSR)); +MODULE_PARM_DESC(intr_timeout_count, +"Interrupt timeout count provides information about the number of times the interrupt wait is timeed out."); + +/* Debug output */ +static int debug; +LKM_MOD_PARAM(debug, "i", int, (S_IRUGO | S_IWUSR)); +MODULE_PARM_DESC(debug, +"Set debug level (default 0)."); + static ibde_t *user_bde = NULL; typedef void (*isr_f)(void *); +typedef struct _intr_regs_s { + uint32 intc_intr_status_base; + uint32 intc_intr_enable_base; + uint32 intc_intr_raw_status_base; + uint32 intc_intr_clear_0; + uint32 intc_intr_clear_1; + uint32 intc_intr_clear_mode_0; + uint32 intc_intr_clear_mode_1; + uint32 intc_intr_status; + uint32 intc_intr_pacing_ctrl; + uint32 intc_intr_clear_delay_unit; + uint32 intc_intr_clear_delay_base; + uint32 intc_intr_pcie_err_status; +} _intr_regs_t; + typedef struct bde_ctrl_s { uint32 dev_type; int irq; @@ -152,7 +214,9 @@ typedef struct bde_ctrl_s { int devid; isr_f isr; uint32 *ba; - int inst; /* associate to _bde_inst_resource[] */ + uint32 inst; /* the resource/instance index in _bde_inst_resource[] */ + int edk_irq_enabled; + _intr_regs_t intr_regs; } bde_ctrl_t; #define VALID_DEVICE(_n) (_n < LINUX_BDE_MAX_DEVICES) @@ -169,15 +233,36 @@ static atomic_t _ether_interrupt_has_taken_place = ATOMIC_INIT(0); */ static int _bde_multi_inst = 0; +#define MAX_UC_CORES LINUX_BDE_MAX_IPROC_UC_CORES + +/* Structure to hold info about interrupts handled by EDK */ typedef struct { - unsigned int inst_id; - unsigned int dma_offset; - unsigned int dma_size; + uint32_t timer_intrc_offset; /* Timer interrupts INTC offset */ + uint32_t timer_intrc_mask; /* Timer interrupts mask */ + uint32_t sw_intr_intrc_offset; /* SW Programmable Interrupt's offset */ + uint32_t sw_intr_intrc_mask; /* SW interrupt's mask */ + uint32_t sw_intr_src_bitmap; /* SW interrupt's bitmask to navigate ICFG registers */ + uint32_t sw_intr_icfg_reg[MAX_UC_CORES]; /* ICFG registers for each core */ +} bde_edk_intr_t; + +typedef struct { + int is_active; /* Is the instance active */ + unsigned int dma_offset; /* offset of the instance's DMA memory in the DMA buffer pool */ + unsigned int dma_size; /* size of the instance's DMA memory (in the DMA buffer pool) */ wait_queue_head_t intr_wq; + wait_queue_head_t edk_intr_wq; atomic_t intr; + atomic_t edk_intr; + bde_edk_intr_t edk_irqs; } bde_inst_resource_t; +/* This array contains information for SDK instance, the index in the array is the instance ID */ static bde_inst_resource_t _bde_inst_resource[LINUX_BDE_MAX_DEVICES]; +/* + * Lock used to protect changes to _bde_inst_resource + */ +static spinlock_t bde_resource_lock; + typedef struct { phys_addr_t cpu_pbase; /* CPU physical base address of the DMA pool */ @@ -257,50 +342,114 @@ _cmic_interrupt(bde_ctrl_t *ctrl) #endif } -static void -_cmicx_interrupt(bde_ctrl_t *ctrl) +void +dump_interrupt_regs(bde_ctrl_t *ctrl , int dev) +{ + int ind; + uint32_t val; + + if (debug >= 2) { + gprintk("Interrupt timeout count = %lu\n", intr_timeout_count); + gprintk("Interrupt count = %lu\n", intr_count); + for (ind = 0; ind < INTC_INTR_REG_NUM; ind++) { + IPROC_READ(dev, ctrl->intr_regs.intc_intr_status_base + 4 * ind, val); + gprintk("INTC_INTR_STATUS_REG_%d = 0x%x\n", ind, val); + IPROC_READ(dev, ctrl->intr_regs.intc_intr_raw_status_base + 4 * ind, val); + gprintk("INTC_INTR_RAW_STATUS_REG_%d = 0x%x\n", ind, val); + IPROC_READ(dev, ctrl->intr_regs.intc_intr_enable_base + 4 * ind, val); + gprintk("INTC_INTR_ENABLE_REG_%d = 0x%x\n", ind, val); + } + /* Dump PAXB Register */ + IPROC_READ(dev, ctrl->intr_regs.intc_intr_status, val); + gprintk("PAXB_0_PAXB_INTR_STATUS = 0x%x\n", val); + IPROC_READ(dev, ctrl->intr_regs.intc_intr_pacing_ctrl, val); + gprintk("PAXB_0_PAXB_IC_INTR_PACING_CTRL = 0x%x\n", val); + IPROC_READ(dev, ctrl->intr_regs.intc_intr_clear_delay_unit, val); + gprintk("PAXB_0_PAXB_INTRCLR_DELAY_UNIT = 0x%x\n", val); + IPROC_READ(dev, ctrl->intr_regs.intc_intr_pcie_err_status, val); + gprintk("PAXB_0_PCIE_ERROR_STATUS = 0x%x\n", val); + + for (ind = 0; ind < PAXB_INTRCLR_DELAY_REG_NUM; ind++) { + IPROC_READ(dev, ctrl->intr_regs.intc_intr_clear_delay_base + 4 * ind, val); + gprintk("PAXB_0_PAXB_IC_INTRCLR_DELAY_REG_%d = 0x%x\n", ind, val); + } + } + /* Clear interrupt enable registers */ + for (ind = 0; ind < INTC_INTR_REG_NUM; ind++) { + IPROC_WRITE(dev, ctrl->intr_regs.intc_intr_enable_base + 4 * ind, 0); + } +} + +#ifdef BDE_EDK_SUPPORT +static int +_cmicx_edk_interrupt_check(bde_ctrl_t *ctrl, int d) { - int d, ind; - uint32 stat, iena, mask, fmask; bde_inst_resource_t *res; - uint32 intc_intr_status_base = 0, intc_intr_enable_base = 0; + uint32 stat, mask = 0, bitmap = 0; + int idx; - d = (((uint8 *)ctrl - (uint8 *)_devices) / sizeof (bde_ctrl_t)); res = &_bde_inst_resource[ctrl->inst]; + bitmap = res->edk_irqs.sw_intr_src_bitmap; + + /* Explicitly reading raw_status so as to not clear the status on read */ + IPROC_READ(d, ctrl->intr_regs.intc_intr_raw_status_base + + (res->edk_irqs.sw_intr_intrc_offset * 4), stat); + /* Check whether Software Programmable Interrupt is set */ + if (stat & res->edk_irqs.sw_intr_intrc_mask) { + for (idx = 0; (bitmap && (idx < MAX_UC_CORES)); idx++) { + if (bitmap & 1) { + IPROC_READ(d, res->edk_irqs.sw_intr_icfg_reg[idx], stat); + mask |= (stat & 1) << idx; + } + bitmap = (bitmap >> 1); + } + if (mask) + return 1; + } - lkbde_irq_mask_get(d, &mask, &fmask); + /* EDK uses timer interrupt as watchdog to indicate the the firmware has crashed */ + IPROC_READ(d, ctrl->intr_regs.intc_intr_raw_status_base + + (res->edk_irqs.timer_intrc_offset * 4), stat); + if (stat & res->edk_irqs.timer_intrc_mask) { + return 1; + } + return 0; +} +#endif - if ((ctrl->dev_type & BDE_SWITCH_DEV_TYPE) && - ((user_bde->get_dev(d)->device == BCM56370_DEVICE_ID) || - (user_bde->get_dev(d)->device == BCM56371_DEVICE_ID) || - (user_bde->get_dev(d)->device == BCM56372_DEVICE_ID) || - (user_bde->get_dev(d)->device == BCM56374_DEVICE_ID) || - (user_bde->get_dev(d)->device == BCM56375_DEVICE_ID) || - (user_bde->get_dev(d)->device == BCM56376_DEVICE_ID) || - (user_bde->get_dev(d)->device == BCM56377_DEVICE_ID) || - (user_bde->get_dev(d)->device == BCM56577_DEVICE_ID) || - (user_bde->get_dev(d)->device == BCM56578_DEVICE_ID) || - (user_bde->get_dev(d)->device == BCM56579_DEVICE_ID))) { - intc_intr_status_base = HX5_INTC_INTR_STATUS_BASE; - intc_intr_enable_base = HX5_INTC_INTR_ENABLE_BASE; - } else { - intc_intr_status_base = INTC_INTR_STATUS_BASE; - intc_intr_enable_base = INTC_INTR_ENABLE_BASE; +static int +_cmicx_interrupt_prepare(bde_ctrl_t *ctrl) +{ + int d, ind, ret = 0; + uint32 stat, iena, mask, fmask; + + d = (((uint8 *)ctrl - (uint8 *)_devices) / sizeof (bde_ctrl_t)); + + if (ctrl->dev_type & BDE_PCI_DEV_TYPE) { + IPROC_READ(d, ctrl->intr_regs.intc_intr_clear_mode_0, stat); + /* Clear MSI interrupts immediately to prevent spurious interrupts */ + if (stat == 0) { + IPROC_WRITE(d, ctrl->intr_regs.intc_intr_clear_0, 0xFFFFFFFF); + IPROC_WRITE(d, ctrl->intr_regs.intc_intr_clear_1, 0xFFFFFFFF); + } } + + lkbde_irq_mask_get(d, &mask, &fmask); + if (fmask) { if (ctrl->dev_type & BDE_AXI_DEV_TYPE) { IHOST_READ_INTR(d, ihost_intr_status_base + INTC_PDMA_INTR_REG_IND, stat); IHOST_READ_INTR(d, ihost_intr_enable_base + INTC_PDMA_INTR_REG_IND, iena); } else { - READ_INTC_INTR(d, intc_intr_status_base + 4 * INTC_PDMA_INTR_REG_IND, stat); - READ_INTC_INTR(d, intc_intr_enable_base + 4 * INTC_PDMA_INTR_REG_IND, iena); + IPROC_READ(d, ctrl->intr_regs.intc_intr_status_base + 4 * INTC_PDMA_INTR_REG_IND, stat); + IPROC_READ(d, ctrl->intr_regs.intc_intr_enable_base + 4 * INTC_PDMA_INTR_REG_IND, iena); } if (stat & iena) { if (ctrl->dev_type & BDE_AXI_DEV_TYPE) { IHOST_WRITE_INTR(d, ihost_intr_enable_base + INTC_PDMA_INTR_REG_IND + HX5_IHOST_IRQ_MASK_OFFSET, ~0); } else { - WRITE_INTC_INTR(d, intc_intr_enable_base + 4 * INTC_PDMA_INTR_REG_IND, 0); + IPROC_WRITE(d, ctrl->intr_regs.intc_intr_enable_base + 4 * INTC_PDMA_INTR_REG_IND, 0); } for (ind = 0; ind < INTC_INTR_REG_NUM; ind++) { @@ -308,25 +457,29 @@ _cmicx_interrupt(bde_ctrl_t *ctrl) continue; } if (ctrl->dev_type & BDE_AXI_DEV_TYPE) { - if (ind < INTC_LOW_PRIORITY_INTR_REG_IND) { + if (ind < INTC_SW_PROG_INTR_REG_IND) { continue; } - IHOST_READ_INTR(d, ihost_intr_status_base + ind, stat); - IHOST_READ_INTR(d, ihost_intr_enable_base + ind, iena); - if (ind == INTC_LOW_PRIORITY_INTR_REG_IND) { - stat &= INTR_LOW_PRIORITY_BITPOS; + if (ind == INTC_SW_PROG_INTR_REG_IND) { + IHOST_READ_INTR(d, ihost_intr_enable_base + ind + HX5_IHOST_IRQ_PEND_OFFSET, stat); + stat &= INTR_SW_PROG_INTR_BITPOS; + } else { + IHOST_READ_INTR(d, ihost_intr_status_base + ind, stat); + if (ind == INTC_LOW_PRIORITY_INTR_REG_IND) { + stat &= INTR_LOW_PRIORITY_BITPOS; + } } } else { - READ_INTC_INTR(d, intc_intr_status_base + 4 * ind, stat); - READ_INTC_INTR(d, intc_intr_enable_base + 4 * ind, iena); + IPROC_READ(d, ctrl->intr_regs.intc_intr_status_base + 4 * ind, stat); + IPROC_READ(d, ctrl->intr_regs.intc_intr_enable_base + 4 * ind, iena); } if (stat & iena) { break; } } - + /* No pending interrupts */ if (ind >= INTC_INTR_REG_NUM) { - return; + return -1; } } } @@ -335,15 +488,23 @@ _cmicx_interrupt(bde_ctrl_t *ctrl) * So as to avoid getting new interrupts until the user level driver * enumerates the interrupts to be serviced */ +#ifdef BDE_EDK_SUPPORT + if (ctrl->edk_irq_enabled) + ret = _cmicx_edk_interrupt_check(ctrl, d); +#endif + for (ind = 0; ind < INTC_INTR_REG_NUM; ind++) { if (fmask && ind == INTC_PDMA_INTR_REG_IND) { continue; } if (ctrl->dev_type & BDE_AXI_DEV_TYPE) { - if (ind < INTC_LOW_PRIORITY_INTR_REG_IND) { + if (ind < INTC_SW_PROG_INTR_REG_IND) { continue; } - if (ind == INTC_LOW_PRIORITY_INTR_REG_IND) { + if (ind == INTC_SW_PROG_INTR_REG_IND) { + IHOST_WRITE_INTR(d, ihost_intr_enable_base + INTC_SW_PROG_INTR_REG_IND + + HX5_IHOST_IRQ_MASK_OFFSET, INTR_SW_PROG_INTR_BITPOS); + } else if (ind == INTC_LOW_PRIORITY_INTR_REG_IND) { IHOST_WRITE_INTR(d, ihost_intr_enable_base + INTC_LOW_PRIORITY_INTR_REG_IND + HX5_IHOST_IRQ_MASK_OFFSET, INTR_LOW_PRIORITY_BITPOS); } else { @@ -351,17 +512,42 @@ _cmicx_interrupt(bde_ctrl_t *ctrl) HX5_IHOST_IRQ_MASK_OFFSET, ~0); } } else { - WRITE_INTC_INTR(d, intc_intr_enable_base + 4*ind, 0); + IPROC_WRITE(d, ctrl->intr_regs.intc_intr_enable_base + (4 * ind), 0); } } - /* Notify */ - atomic_set(&res->intr, 1); + return ret; +} + +static void +_cmicx_interrupt(bde_ctrl_t *ctrl) +{ + bde_inst_resource_t *res; + int ret; + + intr_count++; + + res = &_bde_inst_resource[ctrl->inst]; + ret = _cmicx_interrupt_prepare(ctrl); + if (ret < 0) { + return; + } else if (ret > 0) { + /* Notify */ + atomic_set(&res->edk_intr, 1); #ifdef BDE_LINUX_NON_INTERRUPTIBLE - wake_up(&res->intr_wq); + wake_up(&res->edk_intr_wq); #else - wake_up_interruptible(&res->intr_wq); + wake_up_interruptible(&res->edk_intr_wq); #endif + } else { + /* Notify */ + atomic_set(&res->intr, 1); +#ifdef BDE_LINUX_NON_INTERRUPTIBLE + wake_up(&res->intr_wq); +#else + wake_up_interruptible(&res->intr_wq); +#endif + } } static void @@ -567,6 +753,18 @@ _cmicd_interrupt(bde_ctrl_t *ctrl) if (stat & imask) { break; } + /** Check if there are interrupts other than PacketIO interrupts on CMC1 */ + stat = user_bde->read(d, CMIC_CMCx_IRQ_STAT0_OFFSET(1)); + imask = mask & ~fmask; + if (stat & imask) { + break; + } + /** Check if there are interrupts other than PacketIO interrupts on CMC2 */ + stat = user_bde->read(d, CMIC_CMCx_IRQ_STAT0_OFFSET(2)); + imask = mask & ~fmask; + if (stat & imask) { + break; + } stat = user_bde->read(d, CMIC_CMCx_IRQ_STAT1_OFFSET(cmc)); if (ctrl->dev_type & BDE_AXI_DEV_TYPE) { mask = user_bde->read(d, CMIC_CMCx_UC0_IRQ_MASK1_OFFSET(cmc)); @@ -653,25 +851,6 @@ _cmicd_interrupt(bde_ctrl_t *ctrl) #endif } -static void -_bcm88750_interrupt(bde_ctrl_t *ctrl) -{ - int d; - bde_inst_resource_t *res; - - d = (((uint8 *)ctrl - (uint8 *)_devices) / sizeof (bde_ctrl_t)); - res = &_bde_inst_resource[ctrl->inst]; - lkbde_irq_mask_set(d, CMIC_IRQ_MASK, 0, 0); - - lkbde_irq_mask_set(d, CMIC_IRQ_MASK_1, 0, 0); - lkbde_irq_mask_set(d, CMIC_IRQ_MASK_2, 0, 0); - atomic_set(&res->intr, 1); -#ifdef BDE_LINUX_NON_INTERRUPTIBLE - wake_up(&res->intr_wq); -#else - wake_up_interruptible(&res->intr_wq); -#endif -} /* The actual interrupt handler of ethernet devices */ static void @@ -696,7 +875,6 @@ static struct _intr_mode_s { { (isr_f)_cmicm_interrupt, "CMICm" }, { (isr_f)_cmicd_interrupt, "CMICd" }, { (isr_f)_cmicd_cmc0_interrupt, "CMICd CMC0" }, - { (isr_f)_bcm88750_interrupt, "BCM88750" }, { (isr_f)_cmicx_interrupt, "CMICx" }, { NULL, NULL } }; @@ -716,6 +894,40 @@ _intr_mode_str(void *isr) return NULL; } +static void +_intr_regs_init(bde_ctrl_t *ctrl, int hx5_intr) +{ + if (hx5_intr) { + ctrl->intr_regs.intc_intr_status_base = HX5_INTC_INTR_STATUS_BASE; + ctrl->intr_regs.intc_intr_enable_base = HX5_INTC_INTR_ENABLE_BASE; + ctrl->intr_regs.intc_intr_raw_status_base = HX5_INTC_INTR_RAW_STATUS_BASE; + ctrl->intr_regs.intc_intr_clear_0 = HX5_PAXB_0_PAXB_IC_INTRCLR_0; + ctrl->intr_regs.intc_intr_clear_1 = HX5_PAXB_0_PAXB_IC_INTRCLR_1; + ctrl->intr_regs.intc_intr_clear_mode_0 = HX5_PAXB_0_PAXB_IC_INTRCLR_MODE_0; + ctrl->intr_regs.intc_intr_clear_mode_1 = HX5_PAXB_0_PAXB_IC_INTRCLR_MODE_1; + ctrl->intr_regs.intc_intr_status = HX5_PAXB_0_PAXB_INTR_STATUS; + ctrl->intr_regs.intc_intr_pacing_ctrl = HX5_PAXB_0_PAXB_IC_INTR_PACING_CTRL; + ctrl->intr_regs.intc_intr_clear_delay_unit = HX5_PAXB_0_PAXB_INTRCLR_DELAY_UNIT; + ctrl->intr_regs.intc_intr_clear_delay_base = HX5_PAXB_0_PAXB_IC_INTRCLR_DELAY_BASE; + ctrl->intr_regs.intc_intr_pcie_err_status = HX5_PAXB_0_PCIE_ERROR_STATUS; + + } else { + ctrl->intr_regs.intc_intr_status_base = INTC_INTR_STATUS_BASE; + ctrl->intr_regs.intc_intr_raw_status_base = INTC_INTR_RAW_STATUS_BASE; + ctrl->intr_regs.intc_intr_enable_base = INTC_INTR_ENABLE_BASE; + ctrl->intr_regs.intc_intr_clear_0 = PAXB_0_PAXB_IC_INTRCLR_0; + ctrl->intr_regs.intc_intr_clear_1 = PAXB_0_PAXB_IC_INTRCLR_1; + ctrl->intr_regs.intc_intr_clear_mode_0 = PAXB_0_PAXB_IC_INTRCLR_MODE_0; + ctrl->intr_regs.intc_intr_clear_mode_1 = PAXB_0_PAXB_IC_INTRCLR_MODE_1; + ctrl->intr_regs.intc_intr_status = PAXB_0_PAXB_INTR_STATUS; + ctrl->intr_regs.intc_intr_pacing_ctrl = PAXB_0_PAXB_IC_INTR_PACING_CTRL; + ctrl->intr_regs.intc_intr_clear_delay_unit = PAXB_0_PAXB_INTRCLR_DELAY_UNIT; + ctrl->intr_regs.intc_intr_clear_delay_base = PAXB_0_PAXB_IC_INTRCLR_DELAY_BASE; + ctrl->intr_regs.intc_intr_pcie_err_status = PAXB_0_PCIE_ERROR_STATUS; + + } +} + static void _devices_init(int d) { @@ -742,17 +954,12 @@ _devices_init(int d) } if (ctrl->dev_type & BDE_SWITCH_DEV_TYPE) { switch (user_bde->get_dev(d)->device) { - case BCM88750_DEVICE_ID: - case BCM88753_DEVICE_ID: - case BCM88754_DEVICE_ID: - case BCM88755_DEVICE_ID: - case BCM88752_DEVICE_ID: - ctrl->isr = (isr_f)_bcm88750_interrupt; - break; case BCM53540_DEVICE_ID: case BCM53547_DEVICE_ID: case BCM53548_DEVICE_ID: case BCM53549_DEVICE_ID: + ctrl->isr = (isr_f)_cmicd_cmc0_interrupt; + break; case BCM88670_DEVICE_ID: case BCM88671_DEVICE_ID: case BCM88671M_DEVICE_ID: @@ -780,10 +987,10 @@ _devices_init(int d) case BCM88683_DEVICE_ID: case BCM88684_DEVICE_ID: case BCM88685_DEVICE_ID: + case BCM88687_DEVICE_ID: case BCM88380_DEVICE_ID: case BCM88381_DEVICE_ID: case BCM88680_DEVICE_ID: - case BCM88800_DEVICE_ID: case BCM88770_DEVICE_ID: case BCM88773_DEVICE_ID: case BCM88774_DEVICE_ID: @@ -812,10 +1019,7 @@ _devices_init(int d) case BCM88956_DEVICE_ID: case BCM88772_DEVICE_ID: case BCM88952_DEVICE_ID: - ctrl->isr = (isr_f)_cmicd_cmc0_interrupt; - break; - case BCM88790_DEVICE_ID: - ctrl->isr = (isr_f)_cmicx_interrupt; + ctrl->isr = (isr_f)_cmicd_interrupt; break; case BCM56370_DEVICE_ID: case BCM56371_DEVICE_ID: @@ -827,6 +1031,16 @@ _devices_init(int d) case BCM56577_DEVICE_ID: case BCM56578_DEVICE_ID: case BCM56579_DEVICE_ID: + case BCM56273_DEVICE_ID: + case BCM56274_DEVICE_ID: + case BCM56275_DEVICE_ID: + case BCM56276_DEVICE_ID: + case BCM56277_DEVICE_ID: + case BCM56278_DEVICE_ID: + case BCM56279_DEVICE_ID: + case BCM56575_DEVICE_ID: + case BCM56175_DEVICE_ID: + case BCM56176_DEVICE_ID: ctrl->isr = (isr_f)_cmicx_interrupt; if (ctrl->dev_type & BDE_AXI_DEV_TYPE) { if (!ihost_intr_enable_base) { @@ -838,6 +1052,7 @@ _devices_init(int d) HX5_IHOST_INTR_STATUS_MAP_NUM); } } + _intr_regs_init(ctrl, 1); break; default: /* Get CMIC version */ @@ -853,7 +1068,8 @@ _devices_init(int d) } /* check if version is CMICX */ else if (ver == 0x04) { - ctrl->isr = (isr_f)_cmicx_interrupt; + ctrl->isr = (isr_f)_cmicx_interrupt; + _intr_regs_init(ctrl, 0); } else { ctrl->isr = (isr_f)_cmic_interrupt; if ((ctrl->dev_type & BDE_256K_REG_SPACE) && @@ -867,17 +1083,26 @@ _devices_init(int d) break; } + /* configure interrupts for DNX devices using iproc >=14 */ +#if defined(BCM_DNXF_SUPPORT) || defined(BCM_DNX_SUPPORT) + switch (user_bde->get_dev(d)->device & DNXC_DEVID_FAMILY_MASK) { #ifdef BCM_DNX_SUPPORT - /*All Jericho 2 devices from 0x8690 to 0x869F*/ - if (SOC_IS_JERICHO_2_TYPE(user_bde->get_dev(d)->device)) { - ctrl->isr = (isr_f)_cmicx_interrupt; - } + case JERICHO2_DEVICE_ID: + case J2C_DEVICE_ID: + case J2C_2ND_DEVICE_ID: + case Q2A_DEVICE_ID: + case Q2U_DEVICE_ID: + case J2P_DEVICE_ID: +#endif +#ifdef BCM_DNXF_SUPPORT + case BCM88790_DEVICE_ID: #endif - - /*All Ramon devices from 0x8790 to 0x879F*/ - if ((user_bde->get_dev(d)->device & BCM88790_DEVICE_ID) == BCM88790_DEVICE_ID) { ctrl->isr = (isr_f)_cmicx_interrupt; + _intr_regs_init(ctrl, 0); + break; } +#endif /* defined(BCM_DNXF_SUPPORT) || defined(BCM_DNX_SUPPORT) */ + if (_intr_mode_str(ctrl->isr) == NULL) { gprintk("Warning: Unknown interrupt mode\n"); } @@ -897,15 +1122,17 @@ _devices_init(int d) static int _init(void) { - int i; + int i, nof_devices; phys_addr_t cpu_pbase, dma_pbase; ssize_t dmasize; bde_inst_resource_t *res; + uint32 *bitmap_ptr; /* Connect to the kernel bde */ if ((linux_bde_create(NULL, &user_bde) < 0) || user_bde == NULL) { return -ENODEV; } + spin_lock_init(&bde_resource_lock); init_waitqueue_head(&_ether_interrupt_wq); @@ -924,16 +1151,30 @@ _init(void) res->dma_offset = 0; res->dma_size = _dma_pool.total_size; init_waitqueue_head(&res->intr_wq); + init_waitqueue_head(&res->edk_intr_wq); atomic_set(&res->intr, 0); + atomic_set(&res->edk_intr, 0); ihost_intr_enable_base = NULL; ihost_intr_status_base = NULL; - for (i = 0; i < user_bde->num_devices(BDE_ALL_DEVICES); i++) { - res->inst_id |= (1 << i); + nof_devices = user_bde->num_devices(BDE_ALL_DEVICES); + /* for no BDE instances, mark the single SDK as controlling all devices */ + bitmap_ptr = *lkbde_get_inst_devs(0); + for (i = nof_devices; i >=32; i -= 32) { + *(bitmap_ptr++) = 0xffffffff; + } + *bitmap_ptr = (((uint32)1) << i) - 1; + res->is_active = 1; + + for (i = 0; i < nof_devices; i++) { /* init all devices */ _devices_init(i); } + if (intr_timeout > 0) { + gprintk("Interruptible wait timeout = %d msecs\n", intr_timeout); + } + return 0; } @@ -958,7 +1199,7 @@ _cleanup(void) BDE_DEV_MEM_MAPPED(_devices[i].dev_type)) { user_bde->interrupt_disconnect(i); } - lkbde_dev_instid_set(i, 0); + lkbde_dev_instid_set(i, BDE_DEV_INST_ID_INVALID); } linux_bde_destroy(user_bde); user_bde = NULL; @@ -987,48 +1228,53 @@ _cleanup(void) * Always 0 */ static int -_pprint(void) +_pprint(struct seq_file *m) { int idx; const char *name; bde_inst_resource_t *res; uint32 state, instid; - pprintf("Broadcom Device Enumerator (%s)\n", LINUX_USER_BDE_NAME); + pprintf(m, "Broadcom Device Enumerator (%s)\n", LINUX_USER_BDE_NAME); for (idx = 0; idx < user_bde->num_devices(BDE_ALL_DEVICES); idx++) { name = _intr_mode_str(_devices[idx].isr); if (name == NULL) { name = "unknown"; } - pprintf("\t%d: Interrupt mode %s ",idx, name); + pprintf(m, "\t%d: Interrupt mode %s ",idx, name); (void)lkbde_dev_state_get(idx, &state); if (state == BDE_DEV_STATE_REMOVED) { - pprintf(" Device REMOVED ! \n"); + pprintf(m, " Device REMOVED ! \n"); } else { (void)lkbde_dev_instid_get(idx, &instid); - if (instid) { - pprintf("Inst id 0x%x\n",instid); + if (instid != BDE_DEV_INST_ID_INVALID) { + pprintf(m, "Inst id 0x%x\n",instid); } else { - pprintf("\n"); + pprintf(m, "\n"); } } } - pprintf("Instance resource \n"); + pprintf(m, "Instance resource \n"); for (idx = 0; idx < user_bde->num_devices(BDE_ALL_DEVICES); idx++) { res = &_bde_inst_resource[idx]; - if (res->inst_id) { - pprintf("\tDev mask 0x%x : " - "DMA offset %d size %d MB\n", - res->inst_id, + if (res->is_active) { + linux_bde_device_bitmap_t* bitmap_p = lkbde_get_inst_devs(idx); + pprintf(m, "\t%d: DMA offset %d size %d MB Dev mask 0x", + idx, res->dma_offset, res->dma_size); + for (state = 0; state * 32 < user_bde->num_devices(BDE_ALL_DEVICES); ++state) { + pprintf(m,"%.8x ", (*bitmap_p)[state]); + } + pprintf(m,"\n"); } } return 0; } +#ifdef BCM_INSTANCE_SUPPORT /* * Allocate the DMA resource from DMA pool * Parameter : @@ -1049,22 +1295,21 @@ _dma_resource_alloc(unsigned int dma_size, unsigned int *dma_offset) _dma_pool.offset += dma_size; return 0; } +#endif static int -_dma_resource_get(int inst_id, phys_addr_t *cpu_pbase, phys_addr_t *dma_pbase, ssize_t* size) +_dma_resource_get(unsigned inst_id, phys_addr_t *cpu_pbase, phys_addr_t *dma_pbase, ssize_t* size) { - int i; unsigned int dma_size = 0, dma_offset = 0; bde_inst_resource_t *res; - for (i = 0; i < user_bde->num_devices(BDE_ALL_DEVICES); i++) { - res = &_bde_inst_resource[i]; - if (res->inst_id == inst_id) { - dma_size = res->dma_size; - dma_offset = res->dma_offset; - break; - } + if (inst_id >= user_bde->num_devices(BDE_ALL_DEVICES)) { + gprintk("ERROR: requested DMA resources for an instance number out of range: %u\n", inst_id); + return -1; } + res = &_bde_inst_resource[inst_id]; + dma_size = res->dma_size; + dma_offset = res->dma_offset; *cpu_pbase = _dma_pool.cpu_pbase + dma_offset * ONE_MB; *dma_pbase = _dma_pool.dma_pbase + dma_offset * ONE_MB; @@ -1073,28 +1318,49 @@ _dma_resource_get(int inst_id, phys_addr_t *cpu_pbase, phys_addr_t *dma_pbase, s return 0; } +#ifdef BCM_INSTANCE_SUPPORT +/* + * Checks if we have the instance in _bde_inst_resource. If not, return LUBDE_SUCCESS==0 (considered a new instance). + * If it exists with the same dmasize, return 1 (It is considered already in use) + * Otherwise if the device with the same index of the resource, has resource/instance index 0, return LUBDE_SUCCESS==0. (bug) + * Otherwise return LUBDE_FAIL==-1 (It is considered to exist with a different dmasize). + */ static int -_instance_validate(unsigned int inst_id, unsigned int dmasize) +_instance_validate(unsigned int inst_id, unsigned int dmasize, linux_bde_device_bitmap_t inst_devices) { - int i; - bde_inst_resource_t *res; + unsigned i; + uint32 bits; + bde_inst_resource_t *res = _bde_inst_resource + inst_id; + linux_bde_device_bitmap_t* bitmap_p; - for (i = 0; i < user_bde->num_devices(BDE_ALL_DEVICES); i++) { - res = &_bde_inst_resource[i]; - if (res->inst_id == inst_id) { - if (res->dma_size != dmasize) { - if(_devices[i].inst == 0){ - /* Skip _instance_validate (not init yet) */ - return LUBDE_SUCCESS; - } - gprintk("ERROR: dma_size mismatch\n"); - return LUBDE_FAIL; - } - return (1); + if (inst_id >= user_bde->num_devices(BDE_ALL_DEVICES)) { + gprintk("ERROR: instance number out of range: %u\n", inst_id); + return LUBDE_FAIL; + } + + if (res->is_active == 0) { + /* FIXME SDK-225233 check that the devices are not used by another active instance */ + return LUBDE_SUCCESS; + } + + bitmap_p = lkbde_get_inst_devs(inst_id); + for (i = 0; i < LINUX_BDE_NOF_DEVICE_BITMAP_WORDS; ++i) { + bits = inst_devices[i] ^ (*bitmap_p)[i]; + if (bits != 0) { + for (i *= 32; (bits & 1) == 0; bits >>= 1, ++i); + gprintk("ERROR: existing instance number %u does not control the same devices, see device %u\n", inst_id, i); + return LUBDE_FAIL; } } - return LUBDE_SUCCESS; + + if (res->dma_size == dmasize) { + return 1; /* For an existing same instance with the same DMA size, do nothing */ + } + /* with a different DMS size */ + gprintk("ERROR: dma_size mismatch\n"); + return LUBDE_FAIL; } +#endif static int _device_reprobe(void) @@ -1109,57 +1375,110 @@ _device_reprobe(void) return 0; } +#ifdef BCM_INSTANCE_SUPPORT +/* + * Attach an SDK instance: + * _device_reprobe(); + * Check If an instance with the same bitmap exists, if yes with the same dmasize, return, if yes a different dmasize return an error, if no: + * Allocate DMA for the instance. + * This loop finds the first free resource in _bde_inst_resource[] and configure it for the instance. + * Store the resource/instance index in _bde_inst_resource for every device in the instance. + */ static int -_instance_attach(unsigned int inst_id, unsigned int dma_size) +_instance_attach(unsigned int inst_id, unsigned int dma_size, linux_bde_device_bitmap_t inst_devices) { unsigned int dma_offset; int i, exist; bde_inst_resource_t *res; - int inst_idx = -1; - uint32 instid; + uint32 previous_inst_id; /* Reprobe the system for hot-plugged device */ _device_reprobe(); - /* Validate the resource with inst_id */ - exist = _instance_validate(inst_id, dma_size); - if (exist < 0) { + if (debug >= 2) { + gprintk("INFO: Request to attach to instance_id %u with dma size %d!\n", inst_id, dma_size); + } + + spin_lock(&bde_resource_lock); + + /* If not in multi instance mode, move to the mode and fix the first instance that represented all devices */ + if (_bde_multi_inst == 0) { + _bde_multi_inst = 1; + _bde_inst_resource->is_active = 0; + /*_bde_inst_resource->dev will not be used when _bde_inst_resource->is_active == 0 */ + } + + /* Validate the resource with inst_devices */ + exist = _instance_validate(inst_id, dma_size, inst_devices); + + if (exist == LUBDE_FAIL) { + spin_unlock(&bde_resource_lock); return LUBDE_FAIL; } if (exist > 0) { + if (debug >= 2) { + gprintk("INFO: Already attached to instance_id %u with dma size %d!\n", inst_id, dma_size); + } + spin_unlock(&bde_resource_lock); return LUBDE_SUCCESS; } if (_dma_resource_alloc(dma_size, &dma_offset) < 0) { + spin_unlock(&bde_resource_lock); return LUBDE_FAIL; } - for (i = 0; i < user_bde->num_devices(BDE_ALL_DEVICES); i++) { - res = &_bde_inst_resource[i]; - if ((_bde_multi_inst == 0) || (res->inst_id == 0)) { - res->inst_id = inst_id; - res->dma_offset = dma_offset; - res->dma_size = dma_size; - _bde_multi_inst++; - inst_idx = i; - init_waitqueue_head(&res->intr_wq); - atomic_set(&res->intr, 0); - break; - } + + /* configure the instance ID resources */ + res = _bde_inst_resource + inst_id; + res->is_active = 1; + res->dma_offset = dma_offset; + res->dma_size = dma_size; +#ifdef SAI_FIXUP /* SDK-240875 */ + /* skip instance 0, WQ for instance 0 has been initialized in user_bde init, see _init() */ + if (inst_id != 0) { + init_waitqueue_head(&res->intr_wq); + init_waitqueue_head(&res->edk_intr_wq); + atomic_set(&res->intr, 0); + atomic_set(&res->edk_intr, 0); } +#endif + memcpy(*lkbde_get_inst_devs(inst_id), inst_devices, sizeof(linux_bde_device_bitmap_t)); /* SDK-225233 */ + /* store the resource/instance index in _bde_inst_resource for every device in the instance */ for (i = 0; i < user_bde->num_devices(BDE_ALL_DEVICES); i++) { - if (inst_id & (1 << i)) { - _devices[i].inst = inst_idx; - /* Pass the instid to the kernel BDE */ - if (lkbde_dev_instid_get(i, &instid) == 0) { - if (!instid) { + if (inst_devices[i / 32] & (1 << (i % 32))) { + _devices[i].inst = inst_id; + /* Pass the inst_id to the kernel BDE */ + if (lkbde_dev_instid_get(i, &previous_inst_id) == 0) { /* If the linux-kernel-bde inst_id is not set for the device, set it to the instance ID */ + if (previous_inst_id == BDE_DEV_INST_ID_INVALID) { lkbde_dev_instid_set(i, inst_id); } - } + } /* TODO handle the case where the device is marked belonging to a different instance */ } } + spin_unlock(&bde_resource_lock); + if (debug >= 2) { + gprintk("INFO: Attached to instance_id %lu with dma size %d! SUCCESS\n", (unsigned long)inst_devices, dma_size); + } return LUBDE_SUCCESS; } +#endif /* BCM_INSTANCE_SUPPORT */ + +#ifdef BDE_EDK_SUPPORT +static int +_edk_instance_attach(unsigned int inst_id, unsigned int dma_size) +{ + ssize_t size = (ssize_t)dma_size; + if (size) { + lkbde_edk_get_dma_info(inst_id, NULL, NULL, &size); + if (!size) { + gprintk("Error: EDK Attached to instance_id %lu failed\n", (unsigned long)inst_id); + return LUBDE_FAIL; + } + } + return LUBDE_SUCCESS; +} +#endif /* * Function: _ioctl @@ -1179,7 +1498,7 @@ _ioctl(unsigned int cmd, unsigned long arg) phys_addr_t cpu_pbase, dma_pbase; ssize_t size; const ibde_dev_t *bde_dev; - int inst_id; + int inst_id, idx; bde_inst_resource_t *res; uint32_t *mapaddr; @@ -1204,6 +1523,7 @@ _ioctl(unsigned int cmd, unsigned long arg) if (bde_dev) { io.d0 = bde_dev->device; io.d1 = bde_dev->rev; + io.dx.dw[0] = bde_dev->dev_unique_id; if (BDE_DEV_MEM_MAPPED(_devices[io.dev].dev_type)) { /* Get physical address to map */ io.d2 = lkbde_get_dev_phys(io.dev); @@ -1246,10 +1566,19 @@ _ioctl(unsigned int cmd, unsigned long arg) case LUBDE_GET_DMA_INFO: inst_id = io.dev; if (_bde_multi_inst){ - _dma_resource_get(inst_id, &cpu_pbase, &dma_pbase, &size); + if (_dma_resource_get(inst_id, &cpu_pbase, &dma_pbase, &size)) { + io.rc = LUBDE_FAIL; + } } else { lkbde_get_dma_info(&cpu_pbase, &dma_pbase, &size); } +#ifdef BDE_EDK_SUPPORT + case LUBDE_GET_EDK_DMA_INFO: + if (cmd == LUBDE_GET_EDK_DMA_INFO) { + inst_id = io.dev; + lkbde_edk_get_dma_info(inst_id, &cpu_pbase, &dma_pbase, &size); + } +#endif io.d0 = dma_pbase; io.d1 = size; /* Optionally enable DMA mmap via /dev/linux-kernel-bde */ @@ -1258,8 +1587,10 @@ _ioctl(unsigned int cmd, unsigned long arg) io.dx.dw[0] = cpu_pbase; #ifdef PHYS_ADDRS_ARE_64BITS io.dx.dw[1] = cpu_pbase >> 32; + io.d3 = dma_pbase >> 32; #else io.dx.dw[1] = 0; + io.d3 = 0; #endif break; case LUBDE_ENABLE_INTERRUPTS: @@ -1293,6 +1624,32 @@ _ioctl(unsigned int cmd, unsigned long arg) _devices[io.dev].enabled = 0; } break; + case LUBDE_SET_EDK_INTERRUPTS: + if (!VALID_DEVICE(io.dev)) { + return -EINVAL; + } + res = &_bde_inst_resource[_devices[io.dev].inst]; + res->edk_irqs.timer_intrc_offset = io.d0; + res->edk_irqs.timer_intrc_mask = io.d1; + res->edk_irqs.sw_intr_intrc_offset = io.d2; + res->edk_irqs.sw_intr_intrc_mask = io.d3; + res->edk_irqs.sw_intr_src_bitmap = io.dx.dw[0]; + for (idx = 0; idx < MAX_UC_CORES; idx++) { + res->edk_irqs.sw_intr_icfg_reg[idx] = io.dx.dw[idx + 1]; + } + break; + case LUBDE_ENABLE_EDK_INTERRUPTS: + if (!VALID_DEVICE(io.dev)) { + return -EINVAL; + } + _devices[io.dev].edk_irq_enabled = 1; + break; + case LUBDE_DISABLE_EDK_INTERRUPTS: + if (!VALID_DEVICE(io.dev)) { + return -EINVAL; + } + _devices[io.dev].edk_irq_enabled = 0; + break; case LUBDE_WAIT_FOR_INTERRUPT: if (!VALID_DEVICE(io.dev)) { return -EINVAL; @@ -1304,8 +1661,34 @@ _ioctl(unsigned int cmd, unsigned long arg) atomic_read(&res->intr) != 0, 100); #else - wait_event_interruptible(res->intr_wq, - atomic_read(&res->intr) != 0); + /* CMICX Devices */ + if ((_devices[io.dev].dev_type & BDE_PCI_DEV_TYPE) && + (_devices[io.dev].isr == (isr_f)_cmicx_interrupt) && + (intr_timeout > 0)) { + unsigned long t_jiffies; + int err=0; + t_jiffies = msecs_to_jiffies(intr_timeout); + err = wait_event_interruptible_timeout(res->intr_wq, + atomic_read(&res->intr) != 0, + t_jiffies); + /* Timeout happend and condition not set */ + if (err == 0) { + bde_ctrl_t *ctrl; + ctrl = &_devices[io.dev]; + intr_timeout_count++; + if (debug >= 1) { + gprintk("Timeout happend and condition not set\n"); + } + dump_interrupt_regs(ctrl, io.dev); + } else if (err == -ERESTARTSYS) { + if (debug >= 1) { + gprintk("Interrupted by Signal\n"); + } + } + } else { + wait_event_interruptible(res->intr_wq, + atomic_read(&res->intr) != 0); + } #endif /* * Even if we get multiple interrupts, we @@ -1319,14 +1702,56 @@ _ioctl(unsigned int cmd, unsigned long arg) #else wait_event_interruptible(_ether_interrupt_wq, atomic_read(&_ether_interrupt_has_taken_place) != 0); + #endif /* - * Even if we get multiple interrupts, we + * Even if we get multiple interrupts, we * only run the interrupt handler once. */ atomic_set(&_ether_interrupt_has_taken_place, 0); } break; + case LUBDE_WAIT_FOR_EDK_INTERRUPT: + if (!VALID_DEVICE(io.dev)) { + return -EINVAL; + } + res = &_bde_inst_resource[_devices[io.dev].inst]; +#ifdef BDE_LINUX_NON_INTERRUPTIBLE + wait_event_timeout(res->edk_intr_wq, + atomic_read(&res->edk_intr) != 0, 100); + +#else + /* CMICX Devices */ + if ((_devices[io.dev].dev_type & BDE_PCI_DEV_TYPE) && + (_devices[io.dev].isr == (isr_f)_cmicx_interrupt) && + (intr_timeout > 0)) { + unsigned long t_jiffies; + int err = 0; + t_jiffies = msecs_to_jiffies(intr_timeout); + err = wait_event_interruptible_timeout(res->edk_intr_wq, + atomic_read(&res->edk_intr) != 0, t_jiffies); + /* Timeout happend and condition not set */ + if (err == 0) { + bde_ctrl_t *ctrl; + ctrl = &_devices[io.dev]; + intr_timeout_count++; + if (debug >= 1) { + gprintk("EDK Interrrupt: Timeout happened\n"); + } + dump_interrupt_regs(ctrl, io.dev); + } else if (err == -ERESTARTSYS) { + if (debug >= 1) { + gprintk("EDK Interrrupt: Interrupted by Signal\n"); + } + } + } else { + wait_event_interruptible(res->edk_intr_wq, atomic_read(&res->edk_intr) != 0); + } +#endif + /* Even if we get multiple interrupts, we + * only run the interrupt handler once. */ + atomic_set(&res->edk_intr, 0); + break; case LUBDE_USLEEP: case LUBDE_UDELAY: case LUBDE_SEM_OP: @@ -1382,7 +1807,7 @@ _ioctl(unsigned int cmd, unsigned long arg) if (BDE_DEV_MEM_MAPPED(_devices[io.dev].dev_type)) { /* Get physical address to map */ io.rc = lkbde_get_dev_resource(io.dev, io.d0, - &io.d1, &io.d2, &io.d3); + &io.d2, &io.d3, &io.d1); } } else { io.rc = LUBDE_FAIL; @@ -1412,9 +1837,16 @@ _ioctl(unsigned int cmd, unsigned long arg) io.rc = LUBDE_FAIL; } break; +#ifdef BDE_EDK_SUPPORT + case LUBDE_ATTACH_EDK_INSTANCE: + io.rc = _edk_instance_attach(io.d0, io.d1); + break; +#endif +#ifdef BCM_INSTANCE_SUPPORT case LUBDE_ATTACH_INSTANCE: - io.rc = _instance_attach(io.d0, io.d1); + io.rc = _instance_attach(io.d0, io.d1, io.dx.dw); break; +#endif case LUBDE_GET_DEVICE_STATE: io.rc = lkbde_dev_state_get(io.dev, &io.d0); break; diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.h b/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.h index 535ccac9fad9..4bd4b746c521 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.h +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.h @@ -1,5 +1,10 @@ /* - * Copyright 2017 Broadcom + * Copyright 2007-2020 Broadcom Inc. All rights reserved. + * + * Permission is granted to use, copy, modify and/or distribute this + * software under either one of the licenses below. + * + * License Option 1: GPL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. + * + * + * License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license + * + * This software is governed by the Broadcom Open Network Switch APIs license: + * https://www.broadcom.com/products/ethernet-connectivity/software/opennsa */ /* * $Id: linux-user-bde.h,v 1.23 Broadcom SDK $ @@ -45,7 +56,7 @@ typedef struct { unsigned int d3; bde_kernel_addr_t p0; union { - unsigned int dw[2]; + uint32_t dw[16]; unsigned char buf[64]; } dx; } lubde_ioctl_t; @@ -54,34 +65,41 @@ typedef struct { /* LUBDE ioctls */ #define LUBDE_MAGIC 'L' -#define LUBDE_VERSION _IO(LUBDE_MAGIC, 0) -#define LUBDE_GET_NUM_DEVICES _IO(LUBDE_MAGIC, 1) -#define LUBDE_GET_DEVICE _IO(LUBDE_MAGIC, 2) -#define LUBDE_PCI_CONFIG_PUT32 _IO(LUBDE_MAGIC, 3) -#define LUBDE_PCI_CONFIG_GET32 _IO(LUBDE_MAGIC, 4) -#define LUBDE_GET_DMA_INFO _IO(LUBDE_MAGIC, 5) -#define LUBDE_ENABLE_INTERRUPTS _IO(LUBDE_MAGIC, 6) -#define LUBDE_DISABLE_INTERRUPTS _IO(LUBDE_MAGIC, 7) -#define LUBDE_USLEEP _IO(LUBDE_MAGIC, 8) -#define LUBDE_WAIT_FOR_INTERRUPT _IO(LUBDE_MAGIC, 9) -#define LUBDE_SEM_OP _IO(LUBDE_MAGIC, 10) -#define LUBDE_UDELAY _IO(LUBDE_MAGIC, 11) -#define LUBDE_GET_DEVICE_TYPE _IO(LUBDE_MAGIC, 12) -#define LUBDE_SPI_READ_REG _IO(LUBDE_MAGIC, 13) -#define LUBDE_SPI_WRITE_REG _IO(LUBDE_MAGIC, 14) -#define LUBDE_READ_REG_16BIT_BUS _IO(LUBDE_MAGIC, 19) -#define LUBDE_WRITE_REG_16BIT_BUS _IO(LUBDE_MAGIC, 20) -#define LUBDE_GET_BUS_FEATURES _IO(LUBDE_MAGIC, 21) -#define LUBDE_WRITE_IRQ_MASK _IO(LUBDE_MAGIC, 22) -#define LUBDE_CPU_WRITE_REG _IO(LUBDE_MAGIC, 23) -#define LUBDE_CPU_READ_REG _IO(LUBDE_MAGIC, 24) -#define LUBDE_CPU_PCI_REGISTER _IO(LUBDE_MAGIC, 25) -#define LUBDE_DEV_RESOURCE _IO(LUBDE_MAGIC, 26) -#define LUBDE_IPROC_READ_REG _IO(LUBDE_MAGIC, 27) -#define LUBDE_IPROC_WRITE_REG _IO(LUBDE_MAGIC, 28) -#define LUBDE_ATTACH_INSTANCE _IO(LUBDE_MAGIC, 29) -#define LUBDE_GET_DEVICE_STATE _IO(LUBDE_MAGIC, 30) -#define LUBDE_REPROBE _IO(LUBDE_MAGIC, 31) +#define LUBDE_VERSION _IO(LUBDE_MAGIC, 0) +#define LUBDE_GET_NUM_DEVICES _IO(LUBDE_MAGIC, 1) +#define LUBDE_GET_DEVICE _IO(LUBDE_MAGIC, 2) +#define LUBDE_PCI_CONFIG_PUT32 _IO(LUBDE_MAGIC, 3) +#define LUBDE_PCI_CONFIG_GET32 _IO(LUBDE_MAGIC, 4) +#define LUBDE_GET_DMA_INFO _IO(LUBDE_MAGIC, 5) +#define LUBDE_ENABLE_INTERRUPTS _IO(LUBDE_MAGIC, 6) +#define LUBDE_DISABLE_INTERRUPTS _IO(LUBDE_MAGIC, 7) +#define LUBDE_USLEEP _IO(LUBDE_MAGIC, 8) +#define LUBDE_WAIT_FOR_INTERRUPT _IO(LUBDE_MAGIC, 9) +#define LUBDE_SEM_OP _IO(LUBDE_MAGIC, 10) +#define LUBDE_UDELAY _IO(LUBDE_MAGIC, 11) +#define LUBDE_GET_DEVICE_TYPE _IO(LUBDE_MAGIC, 12) +#define LUBDE_SPI_READ_REG _IO(LUBDE_MAGIC, 13) +#define LUBDE_SPI_WRITE_REG _IO(LUBDE_MAGIC, 14) +#define LUBDE_READ_REG_16BIT_BUS _IO(LUBDE_MAGIC, 19) +#define LUBDE_WRITE_REG_16BIT_BUS _IO(LUBDE_MAGIC, 20) +#define LUBDE_GET_BUS_FEATURES _IO(LUBDE_MAGIC, 21) +#define LUBDE_WRITE_IRQ_MASK _IO(LUBDE_MAGIC, 22) +#define LUBDE_CPU_WRITE_REG _IO(LUBDE_MAGIC, 23) +#define LUBDE_CPU_READ_REG _IO(LUBDE_MAGIC, 24) +#define LUBDE_CPU_PCI_REGISTER _IO(LUBDE_MAGIC, 25) +#define LUBDE_DEV_RESOURCE _IO(LUBDE_MAGIC, 26) +#define LUBDE_IPROC_READ_REG _IO(LUBDE_MAGIC, 27) +#define LUBDE_IPROC_WRITE_REG _IO(LUBDE_MAGIC, 28) +#define LUBDE_ATTACH_INSTANCE _IO(LUBDE_MAGIC, 29) +#define LUBDE_GET_DEVICE_STATE _IO(LUBDE_MAGIC, 30) +#define LUBDE_REPROBE _IO(LUBDE_MAGIC, 31) +#define LUBDE_SET_EDK_INTERRUPTS _IO(LUBDE_MAGIC, 32) +#define LUBDE_ENABLE_EDK_INTERRUPTS _IO(LUBDE_MAGIC, 33) +#define LUBDE_DISABLE_EDK_INTERRUPTS _IO(LUBDE_MAGIC, 34) +#define LUBDE_WAIT_FOR_EDK_INTERRUPT _IO(LUBDE_MAGIC, 35) +#define LUBDE_ATTACH_EDK_INSTANCE _IO(LUBDE_MAGIC, 36) +#define LUBDE_GET_EDK_DMA_INFO _IO(LUBDE_MAGIC, 37) + #define LUBDE_SEM_OP_CREATE 1 #define LUBDE_SEM_OP_DESTROY 2 diff --git a/platform/broadcom/saibcm-modules/systems/bde/shared/include/shbde.h b/platform/broadcom/saibcm-modules/systems/bde/shared/include/shbde.h index 53003a40ce53..2d0651191fbb 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/shared/include/shbde.h +++ b/platform/broadcom/saibcm-modules/systems/bde/shared/include/shbde.h @@ -1,5 +1,10 @@ /* - * Copyright 2017 Broadcom + * Copyright 2007-2020 Broadcom Inc. All rights reserved. + * + * Permission is granted to use, copy, modify and/or distribute this + * software under either one of the licenses below. + * + * License Option 1: GPL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. + * + * + * License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license + * + * This software is governed by the Broadcom Open Network Switch APIs license: + * https://www.broadcom.com/products/ethernet-connectivity/software/opennsa */ /* * $Id: $ diff --git a/platform/broadcom/saibcm-modules/systems/bde/shared/include/shbde_iproc.h b/platform/broadcom/saibcm-modules/systems/bde/shared/include/shbde_iproc.h index 4b614ba53139..4b71b8f16ee3 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/shared/include/shbde_iproc.h +++ b/platform/broadcom/saibcm-modules/systems/bde/shared/include/shbde_iproc.h @@ -1,5 +1,10 @@ /* - * Copyright 2017 Broadcom + * Copyright 2007-2020 Broadcom Inc. All rights reserved. + * + * Permission is granted to use, copy, modify and/or distribute this + * software under either one of the licenses below. + * + * License Option 1: GPL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. + * + * + * License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license + * + * This software is governed by the Broadcom Open Network Switch APIs license: + * https://www.broadcom.com/products/ethernet-connectivity/software/opennsa */ /* * $Id: $ diff --git a/platform/broadcom/saibcm-modules/systems/bde/shared/include/shbde_mdio.h b/platform/broadcom/saibcm-modules/systems/bde/shared/include/shbde_mdio.h index 5f8fa63533f4..a51dd2ac6f5f 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/shared/include/shbde_mdio.h +++ b/platform/broadcom/saibcm-modules/systems/bde/shared/include/shbde_mdio.h @@ -1,5 +1,10 @@ /* - * Copyright 2017 Broadcom + * Copyright 2007-2020 Broadcom Inc. All rights reserved. + * + * Permission is granted to use, copy, modify and/or distribute this + * software under either one of the licenses below. + * + * License Option 1: GPL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. + * + * + * License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license + * + * This software is governed by the Broadcom Open Network Switch APIs license: + * https://www.broadcom.com/products/ethernet-connectivity/software/opennsa */ /* * $Id: $ diff --git a/platform/broadcom/saibcm-modules/systems/bde/shared/include/shbde_pci.h b/platform/broadcom/saibcm-modules/systems/bde/shared/include/shbde_pci.h index 1f045d7b02c8..a0b88494823f 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/shared/include/shbde_pci.h +++ b/platform/broadcom/saibcm-modules/systems/bde/shared/include/shbde_pci.h @@ -1,5 +1,10 @@ /* - * Copyright 2017 Broadcom + * Copyright 2007-2020 Broadcom Inc. All rights reserved. + * + * Permission is granted to use, copy, modify and/or distribute this + * software under either one of the licenses below. + * + * License Option 1: GPL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. + * + * + * License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license + * + * This software is governed by the Broadcom Open Network Switch APIs license: + * https://www.broadcom.com/products/ethernet-connectivity/software/opennsa */ /* * $Id: $ diff --git a/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_iproc.c b/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_iproc.c index 05253141b2ff..ca8024c78a32 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_iproc.c +++ b/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_iproc.c @@ -1,5 +1,10 @@ /* - * Copyright 2017 Broadcom + * Copyright 2007-2020 Broadcom Inc. All rights reserved. + * + * Permission is granted to use, copy, modify and/or distribute this + * software under either one of the licenses below. + * + * License Option 1: GPL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. + * + * + * License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license + * + * This software is governed by the Broadcom Open Network Switch APIs license: + * https://www.broadcom.com/products/ethernet-connectivity/software/opennsa */ /* * $Id: $ @@ -290,13 +301,21 @@ shbde_iproc_paxb_init(shbde_hal_t *shbde, void *iproc_regs, } } - /* Configure MSIX interrupt page, only need for iproc ver == 0x10 */ - if ((icfg->use_msi == 2) && (icfg->iproc_ver == 0x10)) { + /* Configure MSIX interrupt page, need for iproc ver 0x10 and 0x12 */ + if ((icfg->use_msi == 2) && + ((icfg->iproc_ver == 0x10) + || (icfg->iproc_ver == 0x12) + || (icfg->iproc_ver == 0x11))){ unsigned int mask = (0x1 << PAXB_0_FUNC0_IMAP1_3_ADDR_SHIFT) - 1; reg = ROFFS(iproc_regs, PAXB_0_FUNC0_IMAP1_3); data = iproc32_read(shbde, reg); data &= mask; - data |= 0x410 << PAXB_0_FUNC0_IMAP1_3_ADDR_SHIFT; + if (icfg->iproc_ver == 0x11) { + data |= 0x400 << PAXB_0_FUNC0_IMAP1_3_ADDR_SHIFT; + } else { + data |= 0x410 << PAXB_0_FUNC0_IMAP1_3_ADDR_SHIFT; + } + iproc32_write(shbde, reg, data); } @@ -341,19 +360,23 @@ shbde_iproc_pci_read(shbde_hal_t *shbde, void *iproc_regs, subwin_base = (addr & ~0xfff); if((icfg->cmic_ver >= 4) && + ((subwin_base == 0x10230000) || (subwin_base == 0x18012000))) { + /* Route the PAXB register through IMAP0_2 */ + reg = ROFFS(iproc_regs, 0x2000 + (addr & 0xfff)); + } else if((icfg->cmic_ver >= 4) && ((subwin_base == 0x10231000) || (subwin_base == 0x18013000))) { /* Route the INTC block access through IMAP0_6 */ reg = ROFFS(iproc_regs, 0x6000 + (addr & 0xfff)); } else { /* Update base address for sub-window 7 */ subwin_base |= 1; /* Valid bit */ - reg = ROFFS(iproc_regs, BAR0_PAXB_IMAP0_7); - iproc32_write(shbde, reg, subwin_base); + reg = ROFFS(iproc_regs, BAR0_PAXB_IMAP0_7); + iproc32_write(shbde, reg, subwin_base); /* Read it to make sure the write actually goes through */ subwin_base = iproc32_read(shbde, reg); - /* Read register through sub-window 7 */ - reg = ROFFS(iproc_regs, 0x7000 + (addr & 0xfff)); + /* Read register through sub-window 7 */ + reg = ROFFS(iproc_regs, 0x7000 + (addr & 0xfff)); } return iproc32_read(shbde, reg); @@ -388,19 +411,23 @@ shbde_iproc_pci_write(shbde_hal_t *shbde, void *iproc_regs, subwin_base = (addr & ~0xfff); if((icfg->cmic_ver >= 4) && + ((subwin_base == 0x10230000) || (subwin_base == 0x18012000))) { + /* Route the PAXB register through IMAP0_2 */ + reg = ROFFS(iproc_regs, 0x2000 + (addr & 0xfff)); + } else if((icfg->cmic_ver >= 4) && ((subwin_base == 0x10231000) || (subwin_base == 0x18013000))) { /* Route the INTC block access through IMAP0_6 */ reg = ROFFS(iproc_regs, 0x6000 + (addr & 0xfff)); } else { /* Update base address for sub-window 7 */ subwin_base |= 1; /* Valid bit */ - reg = ROFFS(iproc_regs, BAR0_PAXB_IMAP0_7); - iproc32_write(shbde, reg, subwin_base); + reg = ROFFS(iproc_regs, BAR0_PAXB_IMAP0_7); + iproc32_write(shbde, reg, subwin_base); /* Read it to make sure the write actually goes through */ subwin_base = iproc32_read(shbde, reg); /* Read register through sub-window 7 */ - reg = ROFFS(iproc_regs, 0x7000 + (addr & 0xfff)); + reg = ROFFS(iproc_regs, 0x7000 + (addr & 0xfff)); } iproc32_write(shbde, reg, data); diff --git a/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_mdio.c b/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_mdio.c index ef4a72071b33..1e38eb024adc 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_mdio.c +++ b/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_mdio.c @@ -1,5 +1,10 @@ /* - * Copyright 2017 Broadcom + * Copyright 2007-2020 Broadcom Inc. All rights reserved. + * + * Permission is granted to use, copy, modify and/or distribute this + * software under either one of the licenses below. + * + * License Option 1: GPL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. + * + * + * License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license + * + * This software is governed by the Broadcom Open Network Switch APIs license: + * https://www.broadcom.com/products/ethernet-connectivity/software/opennsa */ /* * $Id: $ diff --git a/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_pci.c b/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_pci.c index 5cc46d0d463d..8e64b475a41f 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_pci.c +++ b/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_pci.c @@ -1,5 +1,10 @@ /* - * Copyright 2017 Broadcom + * Copyright 2007-2020 Broadcom Inc. All rights reserved. + * + * Permission is granted to use, copy, modify and/or distribute this + * software under either one of the licenses below. + * + * License Option 1: GPL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. + * + * + * License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license + * + * This software is governed by the Broadcom Open Network Switch APIs license: + * https://www.broadcom.com/products/ethernet-connectivity/software/opennsa */ /* * $Id: $ diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/Makefile b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/Makefile index 84c677758cac..b599580ae861 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/Makefile +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/Makefile @@ -1,5 +1,10 @@ # -# Copyright 2017 Broadcom +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ # # You should have received a copy of the GNU General Public License # version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa # # -*- Makefile -*- # $Id: Makefile,v 1.10 Broadcom SDK $ @@ -24,7 +35,7 @@ LOCALDIR = systems/linux/kernel/modules include ${SDK}/make/Make.config -subdirs=shared uk-proxy bcm-diag-full bcm-core bcm-net bcm-diag +subdirs= include ${SDK}/make/Make.subdirs diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/Makefile b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/Makefile index ed1a5000e3ca..9879be69b0b6 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/Makefile +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/Makefile @@ -1,5 +1,10 @@ # -# Copyright 2017 Broadcom +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ # # You should have received a copy of the GNU General Public License # version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa # # -*- Makefile -*- # $Id: Makefile,v 1.3 Broadcom SDK $ @@ -37,9 +48,6 @@ build: $(MODULE) $(KMODULE) endif KBUILD_EXTRA_SYMBOLS := ${BLDDIR}/../../../../bde/linux/kernel/kernel_module/Module.symvers -ifeq (,$(findstring -DPROXY_SUPPORT=0,$(CFLAGS))) -KBUILD_EXTRA_SYMBOLS += ${BLDDIR}/../uk-proxy/kernel_module/Module.symvers -endif # BCM Network Device diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c index 077386e6dcbc..a3f92b17584b 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c @@ -1,23 +1,18 @@ /* * Copyright 2017 Broadcom - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as * published by the Free Software Foundation (the "GPL"). - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 (GPLv2) for more details. - * + * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. */ -/* - * $Id: bcm-knet.c,v 1.90 Broadcom SDK $ - * $Copyright: (c) 2005 Broadcom Corp. - * All Rights Reserved.$ - */ /* * This module implements a Linux network driver for Broadcom @@ -54,7 +49,7 @@ * * To support pci hot-plug in this module, the resource update * should be handled when the PCI device is re-plugged. - * NOTE: the KNET detach should be invoked befere removing the + * NOTE: the KNET detach should be invoked before removing the * device. * * For a list of supported module parameters, please see below. @@ -71,6 +66,7 @@ #include #include #include +#include MODULE_AUTHOR("Broadcom Corporation"); @@ -167,6 +163,39 @@ LKM_MOD_PARAM(basedev_suspend, "i", int, 0); MODULE_PARM_DESC(basedev_suspend, "Pause traffic till base device is up (enabled by default in NAPI mode)"); +/* + * Force to add one layer of VLAN tag to untagged packets on Dune devices + */ +#if defined(SAI_FIXUP) && defined(BCM_DNX_SUPPORT) /* SONIC-16195 CS9129167 - Change the default to NOT add tag */ +static int force_tagged = 0; +#else +static int force_tagged = 1; +#endif +LKM_MOD_PARAM(force_tagged, "i", int, 0); +MODULE_PARM_DESC(force_tagged, +"Always tagged with VLAN tag with spceified VID or VSI(default 1)"); + +static int ft_tpid=0x8100; +LKM_MOD_PARAM(ft_tpid, "i", int, 0); +MODULE_PARM_DESC(ft_tpid, +"Tag Protocol Identifier (TPID) indicates the frame type (default 0x8100)"); + +static int ft_pri=0; +LKM_MOD_PARAM(ft_pri, "i", int, 0); +MODULE_PARM_DESC(ft_cfi, +"Priority (PRI) indicates the frame priority (default 0)"); + +static int ft_cfi=0; +LKM_MOD_PARAM(ft_cfi, "i", int, 0); +MODULE_PARM_DESC(ft_cfi, +"Canonical Format Indicator (CFI) indicates whether a MAC address is encapsulated in canonical format over different transmission media (default 0)"); + +static int ft_vid=0; +LKM_MOD_PARAM(ft_vid, "i", int, 0); +MODULE_PARM_DESC(ft_vid, +"VLAN ID (VID) indicates the VLAN to which a frame belongs (default 0)"); + + /* Debug levels */ #define DBG_LVL_VERB 0x1 #define DBG_LVL_DCB 0x2 @@ -189,6 +218,7 @@ MODULE_PARM_DESC(basedev_suspend, #define DBG_LVL_DCB_RX 0x20000 #define DBG_LVL_PDMP_TX 0x40000 #define DBG_LVL_PDMP_RX 0x80000 +#define DBG_LVL_PTP 0x100000 #define DBG_VERB(_s) do { if (debug & DBG_LVL_VERB) gprintk _s; } while (0) #define DBG_PKT(_s) do { if (debug & DBG_LVL_PKT) gprintk _s; } while (0) @@ -212,6 +242,7 @@ MODULE_PARM_DESC(basedev_suspend, #define DBG_DCB(_s) do { if (debug & (DBG_LVL_DCB|DBG_LVL_DCB_TX| \ DBG_LVL_DCB_RX)) \ gprintk _s; } while (0) +#define DBG_PTP(_s) do { if (debug & DBG_LVL_PTP) gprintk _s; } while (0) /* This flag is used to indicate if debugging packet function is open or closed */ @@ -267,40 +298,6 @@ static int napi_weight = 0; #endif -/* - * If proxy support is compiled in the module will attempt to use - * the user/kernel message service provided by the linux-uk-proxy - * kernel module, otherwise device IOCTL will be used. - */ -#ifndef PROXY_SUPPORT -#define PROXY_SUPPORT 0 -#endif - -#if PROXY_SUPPORT - -#include - -static int use_proxy = 1; -LKM_MOD_PARAM(use_proxy, "i", int, 0); -MODULE_PARM_DESC(use_proxy, -"Use Linux User/Kernel proxy (default 1)"); - -#define PROXY_SERVICE_CREATE(_s,_q,_f) linux_uk_proxy_service_create(_s,_q,_f) -#define PROXY_SERVICE_DESTROY(_s) linux_uk_proxy_service_destroy(_s); -#define PROXY_SEND(_s,_m,_l) linux_uk_proxy_send(_s,_m,_l) -#define PROXY_RECV(_s,_m,_l) linux_uk_proxy_recv(_s,_m,_l) - -#else - -static int use_proxy = 0; - -#define PROXY_SERVICE_CREATE(_s,_q,_f) -#define PROXY_SERVICE_DESTROY(_s) -#define PROXY_SEND(_s,_m,_l) -#define PROXY_RECV(_s,_m,_l) (-1) - -#endif - /* Compatibility */ #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0)) @@ -394,6 +391,10 @@ static inline struct sk_buff *skb_padto(struct sk_buff *skb, unsigned int len) __vlan_hwaccel_put_tag(_skb, htons(_proto), _tci) #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0) +#define ETH_P_8021AD 0x88A8 /* 802.1ad Service VLAN */ +#endif + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) #define bkn_dma_mapping_error(d, a) \ dma_mapping_error(a) @@ -407,6 +408,11 @@ static inline struct sk_buff *skb_padto(struct sk_buff *skb, unsigned int len) #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) +enum hwtstamp_tx_types { + HWTSTAMP_TX_OFF, + HWTSTAMP_TX_ON, + HWTSTAMP_TX_ONESTEP_SYNC +}; enum { SKBTX_HW_TSTAMP = 1 << 0, SKBTX_SW_TSTAMP = 1 << 1, @@ -441,6 +447,7 @@ static inline ktime_t ns_to_ktime(u64 ns) #endif #elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) #include +#define HWTSTAMP_TX_ONESTEP_SYNC 2 enum { SKBTX_HW_TSTAMP = 1 << 0, SKBTX_SW_TSTAMP = 1 << 1, @@ -452,6 +459,11 @@ static inline void bkn_skb_tx_timestamp(struct sk_buff *skb) } #else #include + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0) +#define HWTSTAMP_TX_ONESTEP_SYNC 2 +#endif + #define bkn_skb_tx_flags(_skb) skb_shinfo(_skb)->tx_flags static inline void bkn_skb_tx_timestamp(struct sk_buff *skb) { @@ -459,26 +471,47 @@ static inline void bkn_skb_tx_timestamp(struct sk_buff *skb) } #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) +#define bkn_dev_net_set(dev, net) +#else +#define bkn_dev_net_set(dev, net) dev_net_set(dev, net) +#endif + #ifdef LINUX_BDE_DMA_DEVICE_SUPPORT -#define DMA_DEV device -#define DMA_FROMDEV DMA_FROM_DEVICE -#define DMA_TODEV DMA_TO_DEVICE -#define DMA_MAP_SINGLE(d,p,s,r) dma_map_single(d,p,s,r) -#define DMA_UNMAP_SINGLE(d,a,s,r) dma_unmap_single(d,a,s,r) -#define DMA_ALLOC_COHERENT(d,s,h) dma_alloc_coherent(d,s,h,GFP_ATOMIC|GFP_DMA32) -#define DMA_FREE_COHERENT(d,s,a,h) dma_free_coherent(d,s,a,h) -#define DMA_MAPPING_ERROR(d,a) bkn_dma_mapping_error(d,a) +#define BKN_DMA_DEV device +#define BKN_DMA_FROMDEV DMA_FROM_DEVICE +#define BKN_DMA_TODEV DMA_TO_DEVICE +#define BKN_DMA_MAP_SINGLE(d,p,s,r) dma_map_single(d,p,s,r) +#define BKN_DMA_UNMAP_SINGLE(d,a,s,r) dma_unmap_single(d,a,s,r) +#define BKN_DMA_ALLOC_COHERENT(d,s,h) dma_alloc_coherent(d,s,h,GFP_ATOMIC|GFP_DMA32) +#define BKN_DMA_FREE_COHERENT(d,s,a,h) dma_free_coherent(d,s,a,h) +#define BKN_DMA_MAPPING_ERROR(d,a) bkn_dma_mapping_error(d,a) #else -#define DMA_DEV pci_dev -#define DMA_FROMDEV PCI_DMA_FROMDEVICE -#define DMA_TODEV PCI_DMA_TODEVICE -#define DMA_MAP_SINGLE(d,p,s,r) pci_map_single(d,p,s,r) -#define DMA_UNMAP_SINGLE(d,a,s,r) pci_unmap_single(d,a,s,r) -#define DMA_ALLOC_COHERENT(d,s,h) pci_alloc_consistent(d,s,h) -#define DMA_FREE_COHERENT(d,s,a,h) pci_free_consistent(d,s,a,h) -#define DMA_MAPPING_ERROR(d,a) bkn_pci_dma_mapping_error(d,a) +#define BKN_DMA_DEV pci_dev +#define BKN_DMA_FROMDEV PCI_DMA_FROMDEVICE +#define BKN_DMA_TODEV PCI_DMA_TODEVICE +#define BKN_DMA_MAP_SINGLE(d,p,s,r) pci_map_single(d,p,s,r) +#define BKN_DMA_UNMAP_SINGLE(d,a,s,r) pci_unmap_single(d,a,s,r) +#define BKN_DMA_ALLOC_COHERENT(d,s,h) pci_alloc_consistent(d,s,h) +#define BKN_DMA_FREE_COHERENT(d,s,a,h) pci_free_consistent(d,s,a,h) +#define BKN_DMA_MAPPING_ERROR(d,a) bkn_pci_dma_mapping_error(d,a) #endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) +#define BKN_NETDEV_TX_BUSY NETDEV_TX_BUSY +#else +#define BKN_NETDEV_TX_BUSY 1 +#endif + +/* + * Get a 16-bit value from packet offset + * _data Pointer to packet + * _offset Offset + */ +#define PKT_U16_GET(_data, _offset) \ + (uint16_t)(_data[_offset] << 8 | _data[_offset + 1]) + + /* RCPU operations */ #define RCPU_OPCODE_RX 0x10 #define RCPU_OPCODE_TX 0x20 @@ -536,7 +569,7 @@ typedef struct bkn_switch_info_s { int ndev_max; /* Size of indexed array */ struct list_head rxpf_list; /* Associated Rx packet filters */ volatile void *base_addr; /* Base address for PCI register access */ - struct DMA_DEV *dma_dev; /* Required for DMA memory control */ + struct BKN_DMA_DEV *dma_dev; /* Required for DMA memory control */ struct pci_dev *pdev; /* Required for DMA memory control */ struct net_device *dev; /* Base network device */ struct napi_struct napi; /* New NAPI */ @@ -558,8 +591,12 @@ typedef struct bkn_switch_info_s { uint32_t ftmh_stacking_ext_size; /* FTMH Stacking extension existence/size */ uint32_t pph_base_size; /* Size of PPH base */ uint32_t pph_lif_ext_size[8]; /* Size of PPH Lif extension header */ - uint8_t udh_enable; /* Indicates UDH existence */ uint32_t udh_length_type[4]; /* Size of UDH header per type */ + uint32_t udh_size; /* Size of UDH header on legacy devices */ + uint32_t oamp_punt; /* OAMP port if nonzero */ + uint8_t no_skip_udh_check; /* Indicates UDH won't be skipped */ + uint8_t system_headers_mode; /* Indicates system header mode */ + uint8_t udh_enable; /* Indicates UDH existence */ int rx_chans; /* Number of Rx channels */ uint32_t dma_hi; /* DMA higher address */ uint32_t cmic_type; /* CMIC type (CMICe or CMICm) */ @@ -579,8 +616,6 @@ typedef struct bkn_switch_info_s { uint32_t inst_id; /* Instance id of this device */ int evt_idx; /* Event queue index for this device*/ int basedev_suspended; /* Base device suspended */ - int tx_hwts; /* HW timestamp for Tx */ - int rx_hwts; /* HW timestamp for Rx */ struct sk_buff_head tx_ptp_queue; /* Tx PTP skb queue */ struct work_struct tx_ptp_work; /* Tx PTP work */ struct { @@ -641,6 +676,10 @@ typedef struct bkn_switch_info_s { } rx[NUM_RX_CHAN]; } bkn_switch_info_t; +#define INVALID_INSTANCE_ID BDE_DEV_INST_ID_INVALID + +/* 0x1 - Jericho 2 mode */ +#define BKN_DNX_JR2_MODE 1 /* PTCH_2 */ #define BKN_DNX_PTCH_2_SIZE 2 /* ITMH */ @@ -675,49 +714,49 @@ typedef struct bkn_switch_info_s { /* TSH */ #define BKN_DNX_TSH_SIZE 4 /* PPH */ -#define BKN_DNX_PPH_BASE_TYPE_9 9 -#define BKN_DNX_PPH_BASE_TYPE_10 10 -#define BKN_DNX_PPH_BASE_TYPE_12 12 -#define BKN_DNX_PPH_9_FORWARD_DOMAIN_MSB 5 -#define BKN_DNX_PPH_9_FORWARD_DOMAIN_NOF_BITS 16 -#define BKN_DNX_PPH_9_LEARN_EXT_PRESENT_MSB 53 -#define BKN_DNX_PPH_9_LEARN_EXT_PRESENT_NOF_BITS 1 -#define BKN_DNX_PPH_9_FHEI_SIZE_MSB 54 -#define BKN_DNX_PPH_9_FHEI_SIZE_NOF_BITS 2 -#define BKN_DNX_PPH_9_LIF_EXT_TYPE_MSB 56 -#define BKN_DNX_PPH_9_LIF_EXT_TYPE_NOF_BITS 3 -#define BKN_DNX_PPH_10_FORWARD_DOMAIN_MSB 9 -#define BKN_DNX_PPH_10_FORWARD_DOMAIN_NOF_BITS 16 -#define BKN_DNX_PPH_10_LEARN_EXT_PRESENT_MSB 61 -#define BKN_DNX_PPH_10_LEARN_EXT_PRESENT_NOF_BITS 1 -#define BKN_DNX_PPH_10_FHEI_SIZE_MSB 62 -#define BKN_DNX_PPH_10_FHEI_SIZE_NOF_BITS 2 -#define BKN_DNX_PPH_10_LIF_EXT_TYPE_MSB 64 -#define BKN_DNX_PPH_10_LIF_EXT_TYPE_NOF_BITS 3 -#define BKN_DNX_PPH_12_FORWARD_DOMAIN_MSB 21 -#define BKN_DNX_PPH_12_FORWARD_DOMAIN_NOF_BITS 18 -#define BKN_DNX_PPH_12_LEARN_EXT_PRESENT_MSB 77 -#define BKN_DNX_PPH_12_LEARN_EXT_PRESENT_NOF_BITS 1 -#define BKN_DNX_PPH_12_FHEI_SIZE_MSB 78 -#define BKN_DNX_PPH_12_FHEI_SIZE_NOF_BITS 2 -#define BKN_DNX_PPH_12_LIF_EXT_TYPE_MSB 80 -#define BKN_DNX_PPH_12_LIF_EXT_TYPE_NOF_BITS 3 +#define BKN_DNX_INTERNAL_BASE_TYPE_9 9 +#define BKN_DNX_INTERNAL_BASE_TYPE_10 10 +#define BKN_DNX_INTERNAL_BASE_TYPE_12 12 +#define BKN_DNX_INTERNAL_9_FORWARD_DOMAIN_MSB 5 +#define BKN_DNX_INTERNAL_9_FORWARD_DOMAIN_NOF_BITS 16 +#define BKN_DNX_INTERNAL_9_LEARN_EXT_PRESENT_MSB 53 +#define BKN_DNX_INTERNAL_9_LEARN_EXT_PRESENT_NOF_BITS 1 +#define BKN_DNX_INTERNAL_9_FHEI_SIZE_MSB 54 +#define BKN_DNX_INTERNAL_9_FHEI_SIZE_NOF_BITS 2 +#define BKN_DNX_INTERNAL_9_LIF_EXT_TYPE_MSB 56 +#define BKN_DNX_INTERNAL_9_LIF_EXT_TYPE_NOF_BITS 3 +#define BKN_DNX_INTERNAL_10_FORWARD_DOMAIN_MSB 9 +#define BKN_DNX_INTERNAL_10_FORWARD_DOMAIN_NOF_BITS 16 +#define BKN_DNX_INTERNAL_10_LEARN_EXT_PRESENT_MSB 61 +#define BKN_DNX_INTERNAL_10_LEARN_EXT_PRESENT_NOF_BITS 1 +#define BKN_DNX_INTERNAL_10_FHEI_SIZE_MSB 62 +#define BKN_DNX_INTERNAL_10_FHEI_SIZE_NOF_BITS 2 +#define BKN_DNX_INTERNAL_10_LIF_EXT_TYPE_MSB 64 +#define BKN_DNX_INTERNAL_10_LIF_EXT_TYPE_NOF_BITS 3 +#define BKN_DNX_INTERNAL_12_FORWARD_DOMAIN_MSB 21 +#define BKN_DNX_INTERNAL_12_FORWARD_DOMAIN_NOF_BITS 18 +#define BKN_DNX_INTERNAL_12_LEARN_EXT_PRESENT_MSB 77 +#define BKN_DNX_INTERNAL_12_LEARN_EXT_PRESENT_NOF_BITS 1 +#define BKN_DNX_INTERNAL_12_FHEI_SIZE_MSB 78 +#define BKN_DNX_INTERNAL_12_FHEI_SIZE_NOF_BITS 2 +#define BKN_DNX_INTERNAL_12_LIF_EXT_TYPE_MSB 80 +#define BKN_DNX_INTERNAL_12_LIF_EXT_TYPE_NOF_BITS 3 /* PPH.FHEI_TYPE */ -#define BKN_DNX_PPH_FHEI_TYPE_SZ0 1 -#define BKN_DNX_PPH_FHEI_TYPE_SZ1 2 -#define BKN_DNX_PPH_FHEI_TYPE_SZ2 3 +#define BKN_DNX_INTERNAL_FHEI_TYPE_SZ0 1 +#define BKN_DNX_INTERNAL_FHEI_TYPE_SZ1 2 +#define BKN_DNX_INTERNAL_FHEI_TYPE_SZ2 3 /* FHEI */ -#define BKN_DNX_PPH_FHEI_SZ0_SIZE 3 -#define BKN_DNX_PPH_FHEI_SZ1_SIZE 5 -#define BKN_DNX_PPH_FHEI_SZ2_SIZE 8 -#define BKN_DNX_PPH_FHEI_TRAP_5B_QUALIFIER_MSB 0 -#define BKN_DNX_PPH_FHEI_TRAP_5B_QUALIFIER_NOF_BITS 27 -#define BKN_DNX_PPH_FHEI_TRAP_5B_CODE_MSB 27 -#define BKN_DNX_PPH_FHEI_TRAP_5B_CODE_NOF_BITS 9 -#define BKN_DNX_PPH_FHEI_TRAP_5B_TYPE_MSB 36 -#define BKN_DNX_PPH_FHEI_TRAP_5B_TYPE_NOF_BITS 4 +#define BKN_DNX_INTERNAL_FHEI_SZ0_SIZE 3 +#define BKN_DNX_INTERNAL_FHEI_SZ1_SIZE 5 +#define BKN_DNX_INTERNAL_FHEI_SZ2_SIZE 8 +#define BKN_DNX_INTERNAL_FHEI_TRAP_5B_QUALIFIER_MSB 0 +#define BKN_DNX_INTERNAL_FHEI_TRAP_5B_QUALIFIER_NOF_BITS 27 +#define BKN_DNX_INTERNAL_FHEI_TRAP_5B_CODE_MSB 27 +#define BKN_DNX_INTERNAL_FHEI_TRAP_5B_CODE_NOF_BITS 9 +#define BKN_DNX_INTERNAL_FHEI_TRAP_5B_TYPE_MSB 36 +#define BKN_DNX_INTERNAL_FHEI_TRAP_5B_TYPE_NOF_BITS 4 /* PPH Extension */ -#define BKN_DNX_PPH_LEARN_EXT_SIZE 19 +#define BKN_DNX_INTERNAL_LEARN_EXT_SIZE 19 /* UDH */ #define BKN_DNX_UDH_DATA_TYPE_0_MSB 0 #define BKN_DNX_UDH_DATA_TYPE_0_NOF_BITS 2 @@ -758,29 +797,48 @@ typedef struct bkn_switch_info_s { #define BKN_DPP_FTMH_PPH_TYPE_MSB 45 #define BKN_DPP_FTMH_PPH_TYPE_NOF_BITS 2 +/* OTSH */ +#define BKN_DPP_OTSH_SIZE_BYTE 6 +#define BKN_DPP_OTSH_TYPE_MSB 0 +#define BKN_DPP_OTSH_TYPE_NOF_BITS 2 +#define BKN_DPP_OTSH_OAM_SUB_TYPE_MSB 2 +#define BKN_DPP_OTSH_OAM_SUB_TYPE_NOF_BITS 3 + +#define BKN_DPP_OTSH_TYPE_OAM 0 +#define BKN_DPP_OTSH_OAM_SUB_TYPE_DM_1588 2 +#define BKN_DPP_OTSH_OAM_SUB_TYPE_DM_NTP 3 + +#define BKN_DPP_OAM_DM_TOD_SIZE_BYTE 4 + /* PPH */ -#define BKN_DPP_PPH_SIZE_BYTE 7 -#define BKN_DPP_PPH_EEI_EXTENSION_PRESENT_MSB 0 -#define BKN_DPP_PPH_EEI_EXTENSION_PRESENT_NOF_BITS 1 -#define BKN_DPP_PPH_LEARN_EXENSION_PRESENT_MSB 1 -#define BKN_DPP_PPH_LEARN_EXENSION_PRESENT_NOF_BITS 1 -#define BKN_DPP_PPH_FHEI_SIZE_MSB 2 -#define BKN_DPP_PPH_FHEI_SIZE_NOF_BITS 2 -#define BKN_DPP_PPH_FORWARD_CODE_MSB 4 -#define BKN_DPP_PPH_FORWARD_CODE_NOF_BITS 4 -#define BKN_DPP_PPH_VSI_MSB 22 -#define BKN_DPP_PPH_VSI_NOF_BITS 16 +#define BKN_DPP_INTERNAL_SIZE_BYTE 7 +#define BKN_DPP_INTERNAL_EEI_EXTENSION_PRESENT_MSB 0 +#define BKN_DPP_INTERNAL_EEI_EXTENSION_PRESENT_NOF_BITS 1 +#define BKN_DPP_INTERNAL_LEARN_EXENSION_PRESENT_MSB 1 +#define BKN_DPP_INTERNAL_LEARN_EXENSION_PRESENT_NOF_BITS 1 +#define BKN_DPP_INTERNAL_FHEI_SIZE_MSB 2 +#define BKN_DPP_INTERNAL_FHEI_SIZE_NOF_BITS 2 +#define BKN_DPP_INTERNAL_FORWARD_CODE_MSB 4 +#define BKN_DPP_INTERNAL_FORWARD_CODE_NOF_BITS 4 +#define BKN_DPP_INTERNAL_FORWARD_CODE_CPU_TRAP 7 +#define BKN_DPP_INTERNAL_FORWARDING_HEADER_OFFSET_MSB 8 +#define BKN_DPP_INTERNAL_FORWARDING_HEADER_OFFSET_NOF_BITS 7 +#define BKN_DPP_INTERNAL_VSI_MSB 22 +#define BKN_DPP_INTERNAL_VSI_NOF_BITS 16 + /* FHEI TRAP/SNOOP 3B */ -#define BKN_DPP_PPH_FHEI_3B_SIZE_BYTE 3 -#define BKN_DPP_PPH_FHEI_5B_SIZE_BYTE 5 -#define BKN_DPP_PPH_FHEI_8B_SIZE_BYTE 8 -#define BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_MSB 0 -#define BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_NOF_BITS 16 -#define BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_MSB 16 -#define BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_NOF_BITS 8 +#define BKN_DPP_INTERNAL_FHEI_3B_SIZE_BYTE 3 +#define BKN_DPP_INTERNAL_FHEI_5B_SIZE_BYTE 5 +#define BKN_DPP_INTERNAL_FHEI_8B_SIZE_BYTE 8 +#define BKN_DPP_INTERNAL_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_MSB 0 +#define BKN_DPP_INTERNAL_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_NOF_BITS 16 +#define BKN_DPP_INTERNAL_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_MSB 16 +#define BKN_DPP_INTERNAL_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_NOF_BITS 8 /* PPH extension */ -#define BKN_DPP_PPH_EXPLICIT_EDITING_INFOMATION_EXTENSION_SIZE_BYTE 3 -#define BKN_DPP_PPH_LEARN_EXTENSION_SIZE_BYTE 5 +#define BKN_DPP_INTERNAL_EXPLICIT_EDITING_INFOMATION_EXTENSION_SIZE_BYTE 3 +#define BKN_DPP_INTERNAL_LEARN_EXTENSION_SIZE_BYTE 5 + +#define BKN_SAND_SCRATCH_DATA_SIZE 4 /* ftmh action type. */ typedef enum bkn_dpp_ftmh_action_type_e { @@ -792,31 +850,22 @@ typedef enum bkn_dpp_ftmh_action_type_e { /* ftmh dest extension. */ typedef struct bkn_dpp_ftmh_dest_extension_s { - uint8 valid; /* Set if the extension is present */ + uint8_t valid; /* Set if the extension is present */ uint32_t dst_sys_port; /* Destination System Port */ } bkn_dpp_ftmh_dest_extension_t; /* dnx packet */ typedef struct bkn_dune_system_header_info_s { - uint32_t ntwrk_header_ptr; + uint32_t system_header_size; struct { - uint32_t packet_size; /* Packet size in bytes */ uint32_t action_type; /* Indicates if the copy is one of the Forward Snoop or Mirror packet copies */ - uint32_t pph_type; - uint32_t prio; /* Traffic class */ - uint32_t src_sys_port; /* Source System port*/ + uint32_t source_sys_port_aggregate; /* Source System port*/ } ftmh; struct { - uint32_t vsi; - uint32_t trap_qualifier; /* RAW Data */ - uint32_t trap_id; /* RAW Data */ + uint32_t forward_domain; + uint32_t trap_qualifier; + uint32_t trap_id; } internal; - uint32_t system_header_size; - uint32_t ftmh_spa; /* FTMH: Source-System-Port-Aggregate*/ - uint32_t pph_forward_domain; /* PPH: Forward-Domain*/ - uint32_t fhei_qualifier; /* FHEI: Qualifier */ - uint32_t fhei_code; /* FHEI: Code */ - uint32_t fhei_type; /* FHEI: Type */ } bkn_dune_system_header_info_t; #define PREV_IDX(_cur, _max) (((_cur) == 0) ? (_max) - 1 : (_cur) - 1) @@ -874,13 +923,16 @@ typedef struct bkn_priv_s { int id; int type; int port; - uint8_t itmh[4]; int qnum; uint32_t vlan; uint32_t flags; uint32_t cb_user_data; uint8_t system_headers[27]; uint32_t system_headers_size; + int tx_hwts; /* HW timestamp for Tx */ + int rx_hwts; /* HW timestamp for Rx */ + int phys_port; + struct ethtool_link_settings link_settings; } bkn_priv_t; typedef struct bkn_filter_s { @@ -927,6 +979,7 @@ static knet_hw_tstamp_tx_time_get_cb_f knet_hw_tstamp_tx_time_get_cb = NULL; static knet_hw_tstamp_tx_meta_get_cb_f knet_hw_tstamp_tx_meta_get_cb = NULL; static knet_hw_tstamp_ptp_clock_index_cb_f knet_hw_tstamp_ptp_clock_index_cb = NULL; static knet_hw_tstamp_rx_time_upscale_cb_f knet_hw_tstamp_rx_time_upscale_cb = NULL; +static knet_hw_tstamp_ioctl_cmd_cb_f knet_hw_tstamp_ioctl_cmd_cb = NULL; static knet_netif_cb_f knet_netif_create_cb = NULL; static knet_netif_cb_f knet_netif_destroy_cb = NULL; @@ -935,69 +988,6 @@ static knet_netif_cb_f knet_netif_destroy_cb = NULL; */ #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)) -/* - * Old style using kernel_thread() - */ -typedef struct { - const char * name; - volatile int pid; - volatile int run; - struct completion completion; - int state; -} bkn_thread_ctrl_t; - -static int -bkn_thread_start(bkn_thread_ctrl_t *tc, const char *name, - int (*threadfn)(void *)) -{ - if (name == NULL) { - return -1; - } - tc->name = name; - tc->pid = kernel_thread(threadfn, tc, 0); - if (tc->pid < 0) { - tc->pid = 0; - return -1; - } - tc->run = 1; - init_completion(&tc->completion); - return 0; -} - -static int -bkn_thread_stop(bkn_thread_ctrl_t *tc) -{ - if (tc->pid == 0) { - return 0; - } - tc->run = 0; - kill_proc(tc->pid, SIGTERM, 1); - wait_for_completion(&tc->completion); - return 0; -} - -static int -bkn_thread_should_stop(bkn_thread_ctrl_t *tc) -{ - if (tc->run) { - return 0; - } - tc->pid = 0; - return 1; -} - -static void -bkn_thread_boot(bkn_thread_ctrl_t *tc) -{ - siginitsetinv(¤t->blocked, sigmask(SIGTERM) | sigmask(SIGKILL)); -} - -static void -bkn_thread_exit(bkn_thread_ctrl_t *tc) -{ - complete_and_exit(&tc->completion, 0); -} - static void bkn_sleep(int clicks) { @@ -1007,60 +997,6 @@ bkn_sleep(int clicks) sleep_on_timeout(&wq, clicks); } #else -/* - * New style using kthread API - */ -#include -typedef struct { - const char * name; - struct task_struct *task; - int state; -} bkn_thread_ctrl_t; - -static int -bkn_thread_start(bkn_thread_ctrl_t *tc, const char *name, - int (*threadfn)(void *)) -{ - if (name == NULL) { - return -1; - } - tc->name = name; - tc->task = kthread_run(threadfn, tc, name); - if (IS_ERR(tc->task)) { - tc->task = NULL; - return -1; - } - return 0; -} - -static int -bkn_thread_stop(bkn_thread_ctrl_t *tc) -{ - if (tc->task == NULL) { - return 0; - } - send_sig(SIGTERM, tc->task, 0); - return kthread_stop(tc->task); -} - -static int -bkn_thread_should_stop(bkn_thread_ctrl_t *tc) -{ - return kthread_should_stop(); -} - -static void -bkn_thread_boot(bkn_thread_ctrl_t *tc) -{ - allow_signal(SIGTERM); - allow_signal(SIGKILL); -} - -static void -bkn_thread_exit(bkn_thread_ctrl_t *tc) -{ -} - static void bkn_sleep(int clicks) { @@ -1071,9 +1007,6 @@ bkn_sleep(int clicks) } #endif -static bkn_thread_ctrl_t bkn_cmd_ctrl; -static bkn_thread_ctrl_t bkn_evt_ctrl; - /* * On XGS devices bit 15 fo the Transferred Bytes field in * the DCBs is used to indicate that kernel processing is @@ -1137,6 +1070,7 @@ static bkn_thread_ctrl_t bkn_evt_ctrl; #define DEV_IS_CMICX(_sinfo) ((_sinfo)->cmic_type == 'x') #define DEV_IS_CMICM(_sinfo) ((_sinfo)->cmic_type == 'm') +#define DEV_IS_CMIC(_sinfo) ((_sinfo)->cmic_type != 0) #define CDMA_CH(_d, _ch) ((_d)->cdma_channels & (1 << (_ch))) /* @@ -1399,7 +1333,7 @@ xgsm_cdma_halt_set(bkn_switch_info_t *sinfo, int chan) MEMORY_BARRIER; } -static int +static int xgsm_dma_chan_init(bkn_switch_info_t *sinfo, int chan, int dir) { uint32_t cdc; @@ -1872,7 +1806,7 @@ bkn_alloc_dcbs(bkn_switch_info_t *sinfo) rx_ring_size = dcb_size * (MAX_RX_DCBS + 1); sinfo->dcb_mem_size = tx_ring_size + rx_ring_size * sinfo->rx_chans; - sinfo->dcb_mem = DMA_ALLOC_COHERENT(sinfo->dma_dev, + sinfo->dcb_mem = BKN_DMA_ALLOC_COHERENT(sinfo->dma_dev, sinfo->dcb_mem_size, &dcb_dma); if (sinfo->dcb_mem == NULL) { @@ -1889,7 +1823,7 @@ static void bkn_free_dcbs(bkn_switch_info_t *sinfo) { if (sinfo->dcb_mem != NULL) { - DMA_FREE_COHERENT(sinfo->dma_dev, sinfo->dcb_mem_size, + BKN_DMA_FREE_COHERENT(sinfo->dma_dev, sinfo->dcb_mem_size, sinfo->dcb_mem, (dma_addr_t)sinfo->dcb_dma); sinfo->dcb_mem = NULL; } @@ -1907,9 +1841,9 @@ bkn_clean_tx_dcbs(bkn_switch_info_t *sinfo) if (desc->skb != NULL) { DBG_SKB(("Cleaning Tx SKB from DCB %d.\n", sinfo->tx.dirty)); - DMA_UNMAP_SINGLE(sinfo->dma_dev, + BKN_DMA_UNMAP_SINGLE(sinfo->dma_dev, desc->skb_dma, desc->dma_size, - DMA_TODEV); + BKN_DMA_TODEV); desc->skb_dma = 0; dev_kfree_skb_any(desc->skb); desc->skb = NULL; @@ -1936,9 +1870,9 @@ bkn_clean_rx_dcbs(bkn_switch_info_t *sinfo, int chan) if (desc->skb != NULL) { DBG_SKB(("Cleaning Rx%d SKB from DCB %d.\n", chan, sinfo->rx[chan].dirty)); - DMA_UNMAP_SINGLE(sinfo->dma_dev, + BKN_DMA_UNMAP_SINGLE(sinfo->dma_dev, desc->skb_dma, desc->dma_size, - DMA_FROMDEV); + BKN_DMA_FROMDEV); desc->skb_dma = 0; dev_kfree_skb_any(desc->skb); desc->skb = NULL; @@ -2191,12 +2125,13 @@ bkn_api_rx_chain_done(bkn_switch_info_t *sinfo, int chan) static int bkn_api_rx_copy_from_skb(bkn_switch_info_t *sinfo, - int chan, bkn_desc_info_t *desc) + int chan, bkn_desc_info_t *desc, int rx_hwts) { bkn_dcb_chain_t *dcb_chain; uint32_t *dcb; uint32_t dcb_stat; uint8_t *pkt; + uint8_t *skb_pkt; uint64_t pkt_dma; int pktlen; int i; @@ -2234,8 +2169,18 @@ bkn_api_rx_copy_from_skb(bkn_switch_info_t *sinfo, return -1; } + skb_pkt = desc->skb->data; + + /* Strip custom header from KNETSync packets. */ + if ((rx_hwts) && + ((skb_pkt[0] == 'B') && (skb_pkt[1] == 'C') && + (skb_pkt[2] == 'M') && (skb_pkt[3] == 'C'))) { + + skb_pkt = skb_pkt + skb_pkt[4]; + } + /* Copy packet data */ - memcpy(pkt, desc->skb->data, pktlen); + memcpy(pkt, skb_pkt, pktlen); /* Copy packet metadata and mark as done */ if (sinfo->cmic_type != 'x') { @@ -2301,11 +2246,11 @@ bkn_rx_refill(bkn_switch_info_t *sinfo, int chan) while (sinfo->rx[chan].free < MAX_RX_DCBS) { desc = &sinfo->rx[chan].desc[sinfo->rx[chan].cur]; if (desc->skb == NULL) { - skb = dev_alloc_skb(rx_buffer_size + RCPU_RX_ENCAP_SIZE); + skb = dev_alloc_skb(rx_buffer_size + SKB_DATA_ALIGN(resv_size)); if (skb == NULL) { break; } - skb_reserve(skb, resv_size); + skb_reserve(skb, SKB_DATA_ALIGN(resv_size)); desc->skb = skb; } else { DBG_DCB_RX(("Refill Rx%d SKB in DCB %d recycled.\n", @@ -2327,10 +2272,10 @@ bkn_rx_refill(bkn_switch_info_t *sinfo, int chan) desc->dma_size = 0; } #endif - desc->skb_dma = DMA_MAP_SINGLE(sinfo->dma_dev, + desc->skb_dma = BKN_DMA_MAP_SINGLE(sinfo->dma_dev, skb->data, desc->dma_size, - DMA_FROMDEV); - if (DMA_MAPPING_ERROR(sinfo->dma_dev, desc->skb_dma)) { + BKN_DMA_FROMDEV); + if (BKN_DMA_MAPPING_ERROR(sinfo->dma_dev, desc->skb_dma)) { dev_kfree_skb_any(skb); desc->skb = NULL; break; @@ -2532,8 +2477,7 @@ device_is_dnx(bkn_switch_info_t *sinfo) { int is_dnx = 0; - /* No EP_TO_CPU header for DNX(JR2) */ - is_dnx = ((sinfo->cmic_type == 'x') && (sinfo->pkt_hdr_size ==0)) ? 1 : 0; + is_dnx = (sinfo->dcb_type == 39) ? 1 : 0; return is_dnx; } @@ -2572,7 +2516,7 @@ bkn_match_rx_pkt(bkn_switch_info_t *sinfo, uint8_t *pkt, int pktlen, DBG_VERB(("Filter: size = %d (%d), data = 0x%08x, mask = 0x%08x\n", size, wsize, kf->data.w[0], kf->mask.w[0])); - if (device_is_dnx(sinfo)) { + if (device_is_sand(sinfo)) { DBG_DUNE(("Filter: size = %d (wsize %d)\n", size, wsize)); for (idx = 0; idx < wsize; idx++) { @@ -2587,9 +2531,12 @@ bkn_match_rx_pkt(bkn_switch_info_t *sinfo, uint8_t *pkt, int pktlen, match = 1; if (match) { - if (device_is_sand(sinfo)) + if (device_is_dnx(sinfo)) { - /** priority 0 means no priority check */ + /* + * Mutliple RX channels are enabled on JR2 and above devices + * Bind between priority 0 and RX channel 0 is not checked, then all enabled RX channels can receive packets. + */ if (kf->priority && (kf->priority < (num_rx_prio * sinfo->rx_chans))) { if (kf->priority < (num_rx_prio * chan) || kf->priority >= (num_rx_prio * (chan + 1))) { @@ -2671,51 +2618,37 @@ bkn_netif_lookup(bkn_switch_info_t *sinfo, int id) } static int -bkn_hw_tstamp_rx_set(bkn_switch_info_t *sinfo, struct sk_buff *skb, uint32 *meta) +bkn_hw_tstamp_rx_set(bkn_switch_info_t *sinfo, int phys_port, struct sk_buff *skb, uint32 *meta) { struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb); - uint32_t *md = meta; uint64_t ts = 0; - switch (sinfo->dcb_type) { - case 26: - case 32: - case 33: - ts = md[14]; - ts = ts << 32 | md[12]; - break; - case 36: - ts = md[10]; - break; - case 38: - ts = md[4] & 0xffff; - ts = ts << 32 | md[5]; - break; - default: - return -1; - } if (knet_hw_tstamp_rx_time_upscale_cb) { - if (knet_hw_tstamp_rx_time_upscale_cb(sinfo->dev_no, &ts) < 0) { + if (knet_hw_tstamp_rx_time_upscale_cb(sinfo->dev_no, phys_port, skb, meta, &ts) < 0) { return -1; } } memset(shhwtstamps, 0, sizeof(*shhwtstamps)); - shhwtstamps->hwtstamp = ns_to_ktime(be64_to_cpu(ts)); + shhwtstamps->hwtstamp = ns_to_ktime(ts); return 0; } static int -bkn_add_rcpu_encap(bkn_switch_info_t *sinfo, struct sk_buff *skb, void *meta) +bkn_add_rcpu_encap(bkn_switch_info_t *sinfo, struct sk_buff *skb, void *meta, int len) { int pktlen = skb->len; uint32_t *dmeta, *smeta, wsize, psize; int idx; /* Add and clear RCPU encapsulation */ - if (sinfo->cmic_type == 'x') { + if (device_is_sand(sinfo)) { + psize = RCPU_RX_ENCAP_SIZE; + skb_push(skb, psize); + memset(skb->data, 0, RCPU_RX_ENCAP_SIZE); + } else if (sinfo->cmic_type == 'x') { psize = RCPU_HDR_SIZE + sinfo->pkt_hdr_size; skb_push(skb, psize); memset(skb->data, 0, RCPU_HDR_SIZE); @@ -2747,12 +2680,20 @@ bkn_add_rcpu_encap(bkn_switch_info_t *sinfo, struct sk_buff *skb, void *meta) /* Meta data */ dmeta = (uint32_t *)&skb->data[RCPU_HDR_SIZE]; - smeta = sinfo->cmic_type == 'x' ? (uint32_t *)meta : (uint32_t *)meta + 2; - wsize = sinfo->cmic_type == 'x' ? sinfo->pkt_hdr_size / 4 : sinfo->dcb_wsize - 3; - for (idx = 0; idx < wsize; idx++) { - dmeta[idx] = htonl(smeta[idx]); + + if (device_is_sand(sinfo)) { + /* Copy at most 64 bytes system headers */ + len = len > RCPU_RX_META_SIZE ? RCPU_RX_META_SIZE : len; + memcpy(&skb->data[RCPU_HDR_SIZE], (uint8_t *)meta, len); + } else { + smeta = sinfo->cmic_type == 'x' ? (uint32_t *)meta : (uint32_t *)meta + 2; + wsize = sinfo->cmic_type == 'x' ? sinfo->pkt_hdr_size / 4 : sinfo->dcb_wsize - 3; + for (idx = 0; idx < wsize; idx++) { + dmeta[idx] = htonl(smeta[idx]); + } } + return 0; } @@ -2781,7 +2722,6 @@ packet_is_untagged(uint16_t tpid) { int is_untagged = 0; - /* Fixme SDK-111398 */ /* 0x8100 is used in 802.1Q */ /* 0x8848 is used in 802.11ad, the dtag tpid can be set to anything besides 0x8848, 0x9100 is a typical value, but couldn't cover all scenarios. */ is_untagged = ((tpid != 0x8100) && (tpid != 0x8848) && (tpid != 0x9100)); @@ -2866,615 +2806,707 @@ bkn_bitstream_get_field(uint8_t *input_buffer, uint32_t start_bit, uint32_t no } static void -bkn_dpp_packet_parse_ftmh(bkn_switch_info_t *sinfo, uint8_t hdr_buff[], bkn_dune_system_header_info_t *packet_info) -{ - uint32_t header_ptr = 0; - uint32_t dsp_ext_exist=0; +bkn_dpp_packet_parse_ftmh( + bkn_switch_info_t *sinfo, + uint8_t *buf, + uint32_t buf_len, + bkn_dune_system_header_info_t *packet_info, + uint8_t *is_tsh_en, + uint8_t *is_inter_hdr_en) +{ + uint32_t pkt_offset = packet_info->system_header_size; + uint32_t dsp_ext_exist = 0; uint32_t fld_val; - header_ptr = packet_info->ntwrk_header_ptr; - - /* Packet-size */ - bkn_bitstream_get_field( - &hdr_buff[header_ptr], - BKN_DPP_FTMH_PKT_SIZE_MSB, - BKN_DPP_FTMH_PKT_SIZE_NOF_BITS, - &fld_val); - packet_info->ftmh.packet_size = fld_val; - /* Traffic-class */ + /* FTMH: Source-system-port-aggregate */ bkn_bitstream_get_field( - &hdr_buff[header_ptr], - BKN_DPP_FTMH_TC_MSB, - BKN_DPP_FTMH_TC_NOF_BITS, - &fld_val); - packet_info->ftmh.prio = fld_val; - /* Source-system-port-aggregate */ - bkn_bitstream_get_field( - &hdr_buff[header_ptr], + &buf[pkt_offset], BKN_DPP_FTMH_SRC_SYS_PORT_MSB, BKN_DPP_FTMH_SRC_SYS_PORT_NOF_BITS, - &fld_val); - packet_info->ftmh.src_sys_port = fld_val; - /* TM-action-type */ + &packet_info->ftmh.source_sys_port_aggregate); + /* FTMH: TM-action-type */ bkn_bitstream_get_field( - &hdr_buff[header_ptr], + &buf[pkt_offset], BKN_DPP_FTMH_ACTION_TYPE_MSB, BKN_DPP_FTMH_ACTION_TYPE_NOF_BITS, - &fld_val); - packet_info->ftmh.action_type = fld_val; - /* PPH-type */ + &packet_info->ftmh.action_type); + /* FTMH: Internal-type */ bkn_bitstream_get_field( - &hdr_buff[header_ptr], + &buf[pkt_offset], BKN_DPP_FTMH_PPH_TYPE_MSB, BKN_DPP_FTMH_PPH_TYPE_NOF_BITS, &fld_val); - packet_info->ftmh.pph_type = fld_val; - - packet_info->ntwrk_header_ptr += BKN_DPP_FTMH_SIZE_BYTE; - DBG_DUNE(("FTMH(%d) Packet-size %d Action-type %d PPH-type %d Source-system-port 0x%x Traffic-class %d\n", - packet_info->ntwrk_header_ptr, packet_info->ftmh.packet_size, packet_info->ftmh.action_type, - packet_info->ftmh.pph_type, packet_info->ftmh.src_sys_port, packet_info->ftmh.prio)); - /* LB-Key ext */ - if ((sinfo->pkt_hdr_size & BKN_DPP_FTMH_LB_EXT_EN) == BKN_DPP_FTMH_LB_EXT_EN) - { - packet_info->ntwrk_header_ptr += BKN_DPP_FTMH_LB_EXT_SIZE_BYTE; - DBG_DUNE(("FTMH(%d) FTMH LB-Key Extension is present\n", packet_info->ntwrk_header_ptr)); - } - /* DSP ext*/ - fld_val = 0; + /* FTMH: DSP Extension */ bkn_bitstream_get_field( - &hdr_buff[header_ptr], + &buf[pkt_offset], BKN_DPP_FTMH_EXT_DSP_EXIST_MSB, BKN_DPP_FTMH_EXT_DSP_EXIST_NOF_BITS, &dsp_ext_exist); + + if (fld_val & 0x1) + { + *is_inter_hdr_en = TRUE; + } + if (fld_val & 0x2) + { + *is_tsh_en = TRUE; + } + + pkt_offset += BKN_DPP_FTMH_SIZE_BYTE; + DBG_DUNE(("FTMH(9-%u): Action-type %d Source-system-port 0x%x\n", pkt_offset, + packet_info->ftmh.action_type, + packet_info->ftmh.source_sys_port_aggregate)); + + /* FTMH LB-Key Extension */ + if (sinfo->ftmh_lb_key_ext_size) + { + pkt_offset += sinfo->ftmh_lb_key_ext_size; + DBG_DUNE(("FTMH LB-Key Extension(1-%u) is present\n", pkt_offset)); + } + if (dsp_ext_exist) { - packet_info->ntwrk_header_ptr += BKN_DPP_FTMH_DEST_EXT_SIZE_BYTE; - DBG_DUNE(("FTMH(%d) DSP-extension-present 1\n", packet_info->ntwrk_header_ptr)); + pkt_offset += BKN_DPP_FTMH_DEST_EXT_SIZE_BYTE; + DBG_DUNE(("FTMH DSP Extension(2-%u) is present\n", pkt_offset)); } - /* stacking ext */ - if ((sinfo->pkt_hdr_size & BKN_DPP_FTMH_STACKING_EXT_EN) == BKN_DPP_FTMH_STACKING_EXT_EN) + /* FTMH Stacking Extension */ + if (sinfo->ftmh_stacking_ext_size) { - packet_info->ntwrk_header_ptr += BKN_DPP_FTMH_STACKING_SIZE_BYTE; - DBG_DUNE(("FTMH(%d) FTMH Stacking Extension is present\n", packet_info->ntwrk_header_ptr)); + pkt_offset += sinfo->ftmh_stacking_ext_size; + DBG_DUNE(("FTMH Stacking Extension(2-%u) is present\n", pkt_offset)); } + + packet_info->system_header_size = pkt_offset; return; } static void -bkn_dpp_packet_parse_internal(bkn_switch_info_t *sinfo, uint8_t hdr_buff[], bkn_dune_system_header_info_t *packet_info) -{ - uint32_t header_ptr = 0; - uint32_t fld_val; +bkn_dpp_packet_parse_otsh( + bkn_switch_info_t *sinfo, + uint8_t *buf, + uint32_t buf_len, + bkn_dune_system_header_info_t *packet_info, + uint8_t *is_oam_dm_tod_en, + uint8_t *is_skip_udh) +{ + uint32_t pkt_offset = packet_info->system_header_size; + uint32_t type = 0; + uint32_t oam_sub_type = 0; + + /* OTSH: TYPE */ + bkn_bitstream_get_field( + &buf[pkt_offset], + BKN_DPP_OTSH_TYPE_MSB, + BKN_DPP_OTSH_TYPE_NOF_BITS, + &type); + if (type == BKN_DPP_OTSH_TYPE_OAM) { + /* OTSH: OAM_SUB_TYPE */ + bkn_bitstream_get_field( + &buf[pkt_offset], + BKN_DPP_OTSH_OAM_SUB_TYPE_MSB, + BKN_DPP_OTSH_OAM_SUB_TYPE_NOF_BITS, + &oam_sub_type); + if ((oam_sub_type == BKN_DPP_OTSH_OAM_SUB_TYPE_DM_1588) || (oam_sub_type == BKN_DPP_OTSH_OAM_SUB_TYPE_DM_NTP)) { + *is_oam_dm_tod_en = TRUE; + /* Down MEP DM trapped packets will not have UDH present (even if configured), except for QAX when custom_feature_oam_dm_tod_msb_add_enable=0 */ + if (!sinfo->no_skip_udh_check) { + *is_skip_udh = TRUE; + } + } + } + packet_info->system_header_size += BKN_DPP_OTSH_SIZE_BYTE; + + DBG_DUNE(("OTSH(%d): Type 0x%x OAM-Sub-Type 0x%x\n", BKN_DPP_OTSH_SIZE_BYTE, type, oam_sub_type)); + return; +} + +static void +bkn_dpp_packet_parse_internal( + bkn_switch_info_t *sinfo, + uint8_t *buf, + uint32_t buf_len, + bkn_dune_system_header_info_t *packet_info, + uint8_t is_oamp_punted, + uint8_t *is_trapped) +{ + uint32_t pkt_offset = packet_info->system_header_size; + uint32_t fld_val = 0; uint32_t eei_extension_present = 0; uint32_t learn_extension_present = 0; uint32_t fhei_size = 0; - uint32_t forward_code; - uint8_t is_trapped = 0; - - header_ptr = packet_info->ntwrk_header_ptr; + /* Internal: EEI EXT */ bkn_bitstream_get_field( - &hdr_buff[header_ptr], - BKN_DPP_PPH_EEI_EXTENSION_PRESENT_MSB, - BKN_DPP_PPH_EEI_EXTENSION_PRESENT_NOF_BITS, + &buf[pkt_offset], + BKN_DPP_INTERNAL_EEI_EXTENSION_PRESENT_MSB, + BKN_DPP_INTERNAL_EEI_EXTENSION_PRESENT_NOF_BITS, &eei_extension_present); + /* Internal: LERAN EXT */ bkn_bitstream_get_field( - &hdr_buff[header_ptr], - BKN_DPP_PPH_LEARN_EXENSION_PRESENT_MSB, - BKN_DPP_PPH_LEARN_EXENSION_PRESENT_NOF_BITS, + &buf[pkt_offset], + BKN_DPP_INTERNAL_LEARN_EXENSION_PRESENT_MSB, + BKN_DPP_INTERNAL_LEARN_EXENSION_PRESENT_NOF_BITS, &learn_extension_present); + /* Internal: FHEI EXT */ bkn_bitstream_get_field( - &hdr_buff[header_ptr], - BKN_DPP_PPH_FHEI_SIZE_MSB, - BKN_DPP_PPH_FHEI_SIZE_NOF_BITS, + &buf[pkt_offset], + BKN_DPP_INTERNAL_FHEI_SIZE_MSB, + BKN_DPP_INTERNAL_FHEI_SIZE_NOF_BITS, &fhei_size); + /* Internal: FORWARD_CODE */ bkn_bitstream_get_field( - &hdr_buff[header_ptr], - BKN_DPP_PPH_FORWARD_CODE_MSB, - BKN_DPP_PPH_FORWARD_CODE_NOF_BITS, - &forward_code); - /* 7: CPU-Trap */ - is_trapped = (uint8_t)(forward_code == 7); - + &buf[pkt_offset], + BKN_DPP_INTERNAL_FORWARD_CODE_MSB, + BKN_DPP_INTERNAL_FORWARD_CODE_NOF_BITS, + &fld_val); + *is_trapped = (uint8_t)(fld_val == BKN_DPP_INTERNAL_FORWARD_CODE_CPU_TRAP); + /* Internal: VSI */ bkn_bitstream_get_field( - &hdr_buff[header_ptr], - BKN_DPP_PPH_VSI_MSB, - BKN_DPP_PPH_VSI_NOF_BITS, + &buf[pkt_offset], + BKN_DPP_INTERNAL_VSI_MSB, + BKN_DPP_INTERNAL_VSI_NOF_BITS, &fld_val); - packet_info->internal.vsi = fld_val; + packet_info->internal.forward_domain = fld_val; - /* size of PPH base is 7 */ - packet_info->ntwrk_header_ptr += BKN_DPP_PPH_SIZE_BYTE; - header_ptr = packet_info->ntwrk_header_ptr; + if (is_oamp_punted && *is_trapped) { + if(fhei_size == 3) { + /* Force to FHEI size 1 when packets are punted by OAMP */ + fhei_size = 1; + } + } - DBG_DUNE(("PPH(%d) Forward-Code %d EEI-Extension %d Learn-Extension %d VSI %d FHEI-size %d\n", packet_info->ntwrk_header_ptr, - forward_code, eei_extension_present, learn_extension_present, packet_info->internal.vsi, fhei_size)); + /* Move forward to end of Internal header */ + pkt_offset += BKN_DPP_INTERNAL_SIZE_BYTE; - /* PPH extension */ - if (is_trapped && (fhei_size == 1)) - { - /* CPU trap code qualifier */ - bkn_bitstream_get_field( - &hdr_buff[header_ptr], - BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_MSB, - BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_NOF_BITS, - &fld_val); - packet_info->internal.trap_qualifier = fld_val; - /* CPU trap code */ - bkn_bitstream_get_field( - &hdr_buff[header_ptr], - BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_MSB, - BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_NOF_BITS, - &fld_val); - packet_info->internal.trap_id = fld_val; - } + DBG_DUNE(("PPH(7-%u): EEI-Extension %d Learn-Extension %d VSI %d FHEI-size %d\n", + pkt_offset, eei_extension_present,learn_extension_present, packet_info->internal.forward_domain, fhei_size)); + + /* Advance header according to FHEI Trap extension */ switch(fhei_size) { case 1: - packet_info->ntwrk_header_ptr += BKN_DPP_PPH_FHEI_3B_SIZE_BYTE; + /* 3B FHEI Extension: do nothing, header poniter is in the right location */ break; case 2: - packet_info->ntwrk_header_ptr += BKN_DPP_PPH_FHEI_5B_SIZE_BYTE; + /* 5B FHEI Extension: adavance header pointer in 2B */ + pkt_offset += 2; break; case 3: - packet_info->ntwrk_header_ptr += BKN_DPP_PPH_FHEI_8B_SIZE_BYTE; + /* 8B FHEI Extension: adavance header pointer in 5B */ + pkt_offset += 5; break; default: break; } + + /* Internal extension */ + if (*is_trapped && fhei_size) + { + /* CPU trap code qualifier */ + bkn_bitstream_get_field( + &buf[pkt_offset], + BKN_DPP_INTERNAL_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_MSB, + BKN_DPP_INTERNAL_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_NOF_BITS, + &packet_info->internal.trap_qualifier); + /* CPU trap code */ + bkn_bitstream_get_field( + &buf[pkt_offset], + BKN_DPP_INTERNAL_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_MSB, + BKN_DPP_INTERNAL_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_NOF_BITS, + &packet_info->internal.trap_id); + + DBG_DUNE(("FHEI: trap_qualifier 0x%x trap_id 0x%x\n", + packet_info->internal.trap_qualifier, + packet_info->internal.trap_id)); + } + + /* Move forward to end of FHEI Trap extension */ + if (fhei_size) { + pkt_offset += 3; + } + + /* EEI extension */ if (eei_extension_present) { - packet_info->ntwrk_header_ptr += BKN_DPP_PPH_EXPLICIT_EDITING_INFOMATION_EXTENSION_SIZE_BYTE; + pkt_offset += BKN_DPP_INTERNAL_EXPLICIT_EDITING_INFOMATION_EXTENSION_SIZE_BYTE; } + /* Learn extension */ if (learn_extension_present) { - packet_info->ntwrk_header_ptr += BKN_DPP_PPH_LEARN_EXTENSION_SIZE_BYTE; + pkt_offset += BKN_DPP_INTERNAL_LEARN_EXTENSION_SIZE_BYTE; } - DBG_DUNE(("FHEI(%d) trap_qualifier 0x%x trap_id 0x%x\n", packet_info->ntwrk_header_ptr, packet_info->internal.trap_qualifier, packet_info->internal.trap_id)); + packet_info->system_header_size = pkt_offset; return; } static int -bkn_dpp_packet_header_parse(bkn_switch_info_t *sinfo, uint8 *buff, uint32_t buff_len, bkn_dune_system_header_info_t *packet_info) -{ - uint8_t hdr_buff[BKN_DPP_HDR_MAX_SIZE]; - uint32_t hdr_size; - uint8_t has_internal = 0; - - if ((buff == NULL) || (packet_info == NULL)) { +bkn_dpp_packet_header_parse( + bkn_switch_info_t *sinfo, + uint8_t *buff, + uint32_t buff_len, + bkn_dune_system_header_info_t *packet_info) +{ + uint8_t is_inter_hdr_en = FALSE; + uint8_t is_tsh_en = FALSE; + uint8_t is_oamp_punted = FALSE; + uint8_t is_trapped = FALSE; + uint8_t is_oam_dm_tod_en = FALSE; + uint8_t is_skip_udh = FALSE; + + if ((sinfo == NULL) || (buff == NULL) || (packet_info == NULL)) { return -1; } - hdr_size = buff_len < BKN_DPP_HDR_MAX_SIZE ? buff_len: BKN_DPP_HDR_MAX_SIZE; - memcpy(hdr_buff, buff, hdr_size); /* FTMH */ - bkn_dpp_packet_parse_ftmh(sinfo, hdr_buff, packet_info); - if (packet_info->ftmh.packet_size != (buff_len + 2)) { - DBG_DUNE(("FTMH packet size verfication failed, %d-%d\n", packet_info->ftmh.packet_size, buff_len)); - memset(packet_info, 0, sizeof(bkn_dune_system_header_info_t)); - return -1; + bkn_dpp_packet_parse_ftmh(sinfo, buff, buff_len, packet_info, &is_tsh_en, &is_inter_hdr_en); + /* Check if packet is punted from OAMP */ + if (sinfo->oamp_punt && (packet_info->ftmh.source_sys_port_aggregate == sinfo->oamp_punt)) { + is_oamp_punted = TRUE; } - switch (packet_info->ftmh.pph_type) { - case 0: - has_internal = 0; - break; - case 1: - has_internal = 1; - break; - case 2: /* PPH OAM-TS only */ - case 3: /* PPH Base + OAM-TS */ - /* OTSH immediately follows the FTMH when present */ - packet_info->ntwrk_header_ptr += 6; - DBG_DUNE(("FTMH + OAM-TS(%d)\n", packet_info->ntwrk_header_ptr)); - has_internal = 1; - break; - default: - break; + /* OTSH */ + if (is_tsh_en == TRUE) + { + bkn_dpp_packet_parse_otsh(sinfo, buff, buff_len, packet_info, &is_oam_dm_tod_en, &is_skip_udh); + } + /* Internal header is forced to be present if packet was punted to CPU by OAMP */ + if (sinfo->oamp_punt && (packet_info->ftmh.source_sys_port_aggregate == sinfo->oamp_punt)) + { + is_inter_hdr_en = TRUE; + } + /* Internal */ + if (is_inter_hdr_en) + { + bkn_dpp_packet_parse_internal(sinfo, buff, buff_len, packet_info, is_oamp_punted, &is_trapped); + } + /* Skip UDH for the outer layer when packet is punted by OAM for JR2 in JR1 mode */ + if (device_is_dnx(sinfo) && is_oamp_punted) { + is_skip_udh = TRUE; + } + /* UDH */ + if (sinfo->udh_size && !is_skip_udh) { + packet_info->system_header_size += sinfo->udh_size; + } + /* OAM DM TOD header */ + if(is_oam_dm_tod_en) { + packet_info->system_header_size += BKN_DPP_OAM_DM_TOD_SIZE_BYTE; } - if (has_internal) { - bkn_dpp_packet_parse_internal(sinfo, &hdr_buff[0], packet_info); + /* Additional layer of system headers */ + if (is_oamp_punted && is_trapped) + { + is_inter_hdr_en = FALSE; + is_tsh_en = FALSE; + is_oamp_punted = FALSE; + is_trapped = FALSE; + is_oam_dm_tod_en = FALSE; + is_skip_udh = FALSE; + + /* FTMH */ + bkn_dpp_packet_parse_ftmh(sinfo, buff, buff_len, packet_info, &is_tsh_en, &is_inter_hdr_en); + /* OTSH */ + if (is_tsh_en == TRUE) + { + bkn_dpp_packet_parse_otsh(sinfo, buff, buff_len, packet_info, &is_oam_dm_tod_en, &is_skip_udh); + } + /* Internal */ + if (is_inter_hdr_en) + { + bkn_dpp_packet_parse_internal(sinfo, buff, buff_len, packet_info, is_oamp_punted, &is_trapped); + } + /* OAMP Punted packets do not have UDH in the inner header for both JR1 and JR2 in JR1 mode */ + /* OAM DM TOD header */ + if(is_oam_dm_tod_en) { + packet_info->system_header_size += BKN_DPP_OAM_DM_TOD_SIZE_BYTE; + } } - /* FIXME: */ - /* ignore packets with a double set of FTMH,internals */ - /* ignore the user header size */ + DBG_DUNE(("Total length of headers is %u\n", packet_info->system_header_size)); + return 0; } + static int -bkn_dnx_packet_header_parse(bkn_switch_info_t *sinfo, uint8 *buf, uint32_t buf_len, bkn_dune_system_header_info_t *packet_info) +bkn_dnx_packet_parse_ftmh( + bkn_switch_info_t *sinfo, + uint8_t *buf, + uint32_t buf_len, + bkn_dune_system_header_info_t *packet_info, + uint8_t *is_tsh_en, + uint8_t *is_inter_hdr_en) { uint32_t fld_val; - uint32_t hdr_size = 0; - uint32_t pkt_offset_ingress_untrapped =0; + uint32_t pkt_offset = packet_info->system_header_size; uint8_t tm_dst_ext_present = 0; uint8_t app_specific_ext_size = 0; uint8_t flow_id_ext_size = 0; uint8_t bier_bfr_ext_size = 0; - uint8_t is_pph_en = 0; - uint8_t is_tsh_en = 0; - if ((buf == NULL) || (packet_info == NULL)) { + if ((sinfo == NULL) || (buf == NULL) || (packet_info == NULL)) { return -1; } /* FTMH: Source-System-Port-Aggregate */ bkn_bitstream_get_field( - &buf[hdr_size], + &buf[pkt_offset], BKN_DNX_FTMH_SRC_SYS_PORT_AGGREGATE_MSB, BKN_DNX_FTMH_SRC_SYS_PORT_AGGREGATE_NOF_BITS, &fld_val); - packet_info->ftmh_spa = fld_val; + packet_info->ftmh.source_sys_port_aggregate = fld_val; + /* FTMH: Action-Type */ + bkn_bitstream_get_field( + &buf[pkt_offset], + BKN_DNX_FTMH_ACTION_TYPE_MSB, + BKN_DNX_FTMH_ACTION_TYPE_NOF_BITS, + &fld_val); + packet_info->ftmh.action_type = fld_val; /* FTMH: PPH-Type TSH */ bkn_bitstream_get_field( - &buf[hdr_size], + &buf[pkt_offset], BKN_DNX_FTMH_PPH_TYPE_IS_TSH_EN_MSB, BKN_DNX_FTMH_PPH_TYPE_IS_TSH_EN_NOF_BITS, &fld_val); - is_tsh_en = fld_val; + *is_tsh_en = fld_val; /* FTMH: PPH-Type PPH base */ bkn_bitstream_get_field( - &buf[hdr_size], + &buf[pkt_offset], BKN_DNX_FTMH_PPH_TYPE_IS_PPH_EN_MSB, BKN_DNX_FTMH_PPH_TYPE_IS_PPH_EN_NOF_BITS, &fld_val); - is_pph_en = fld_val; + *is_inter_hdr_en = fld_val; /* FTMH: TM-Destination-Extension-Present */ bkn_bitstream_get_field( - &buf[hdr_size], + &buf[pkt_offset], BKN_DNX_FTMH_TM_DST_EXT_PRESENT_MSB, BKN_DNX_FTMH_TM_DST_EXT_PRESENT_NOF_BITS, &fld_val); tm_dst_ext_present = fld_val; /* FTMH: Application-Specific-Extension-Size */ bkn_bitstream_get_field( - &buf[hdr_size], + &buf[pkt_offset], BKN_DNX_FTMH_APP_SPECIFIC_EXT_SIZE_MSB, BKN_DNX_FTMH_APP_SPECIFIC_EXT_SIZE_NOF_BITS, &fld_val); app_specific_ext_size = fld_val; /* FTMH: Flow-ID-Extension-Size */ bkn_bitstream_get_field( - &buf[hdr_size], + &buf[pkt_offset], BKN_DNX_FTMH_FLOW_ID_EXT_SIZE_MSB, BKN_DNX_FTMH_FLOW_ID_EXT_SIZE_NOF_BITS, &fld_val); flow_id_ext_size = fld_val; /* FTMH: BIER-BFR-Extension-Size */ bkn_bitstream_get_field( - &buf[hdr_size], + &buf[pkt_offset], BKN_DNX_FTMH_BIER_BFR_EXT_SIZE_MSB, BKN_DNX_FTMH_BIER_BFR_EXT_SIZE_NOF_BITS, &fld_val); bier_bfr_ext_size = fld_val; - hdr_size = BKN_DNX_FTMH_BASE_SIZE; - pkt_offset_ingress_untrapped = BKN_DNX_FTMH_BASE_SIZE; + pkt_offset += BKN_DNX_FTMH_BASE_SIZE; - DBG_DUNE(("FTMH(%d) source-system-port 0x%x is_tsh_en %d is_pph_en %d\n", - hdr_size, packet_info->ftmh_spa, is_tsh_en, is_pph_en)); + DBG_DUNE(("FTMH(10-%u): source-system-port 0x%x action_type %u is_tsh_en %u is_inter_hdr_en %u\n", + pkt_offset, packet_info->ftmh.source_sys_port_aggregate, + packet_info->ftmh.action_type, *is_tsh_en, *is_inter_hdr_en)); /* FTMH LB-Key Extension */ if (sinfo->ftmh_lb_key_ext_size > 0) { - hdr_size += sinfo->ftmh_lb_key_ext_size; - DBG_DUNE(("FTMH LB-Key Extension(%d) is present\n", sinfo->ftmh_lb_key_ext_size)); + pkt_offset += sinfo->ftmh_lb_key_ext_size; + DBG_DUNE(("FTMH LB-Key Extension(%u-%u) is present\n", sinfo->ftmh_lb_key_ext_size, pkt_offset)); } /* FTMH Stacking Extension */ if (sinfo->ftmh_stacking_ext_size > 0) { - hdr_size += sinfo->ftmh_stacking_ext_size; - DBG_DUNE(("FTMH Stacking Extension(%d) is present\n", sinfo->ftmh_stacking_ext_size)); + pkt_offset += sinfo->ftmh_stacking_ext_size; + DBG_DUNE(("FTMH Stacking Extension(%u-%u) is present\n", sinfo->ftmh_stacking_ext_size, pkt_offset)); } /* FTMH BIER BFR Extension */ if (bier_bfr_ext_size > 0) { - hdr_size += BKN_DNX_FTMH_BIER_BFR_EXT_SIZE; - DBG_DUNE(("FTMH BIER BFR Extension(2) is present\n")); + pkt_offset += BKN_DNX_FTMH_BIER_BFR_EXT_SIZE; + DBG_DUNE(("FTMH BIER BFR Extension(2-%u) is present\n", pkt_offset)); } /* FTMH TM Destination Extension */ if (tm_dst_ext_present > 0) { - hdr_size += BKN_DNX_FTMH_TM_DST_EXT_SIZE; - DBG_DUNE(("FTMH TM Destination Extension(3) is present\n")); + pkt_offset += BKN_DNX_FTMH_TM_DST_EXT_SIZE; + DBG_DUNE(("FTMH TM Destination Extension(3-%u) is present\n", pkt_offset)); } /* FTMH Application Specific Extension */ if (app_specific_ext_size > 0) { - hdr_size += BKN_DNX_FTMH_APP_SPECIFIC_EXT_SIZE; - DBG_DUNE(("FTMH Application Specific Extension(6) is present\n")); + pkt_offset += BKN_DNX_FTMH_APP_SPECIFIC_EXT_SIZE; + DBG_DUNE(("FTMH Application Specific Extension(6-%u) is present\n", pkt_offset)); } /* FTMH Flow-ID Extension */ if (flow_id_ext_size > 0) { - hdr_size += BKN_DNX_FTMH_FLOW_ID_EXT_SIZE; - DBG_DUNE(("FTMH Flow-ID Extension(3) is present\n")); + pkt_offset += BKN_DNX_FTMH_FLOW_ID_EXT_SIZE; + DBG_DUNE(("FTMH Flow-ID Extension(3-%u) is present\n", pkt_offset)); } - /* Given the packet is trapped to CPU */ + packet_info->system_header_size = pkt_offset; - /* Time-Stamp Header */ - if (is_tsh_en == TRUE) - { - hdr_size += BKN_DNX_TSH_SIZE; - DBG_DUNE(("Time-Stamp Header(4) is present\n")); - } + return 0; +} - /* Packet Processing Header */ - if (is_pph_en) - { - uint8_t learn_ext_present; - uint8_t fhei_size; - uint8_t lif_ext_type; - switch (sinfo->pph_base_size) - { - case BKN_DNX_PPH_BASE_TYPE_9: - /* FTMH: Forward-Domain */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_9_FORWARD_DOMAIN_MSB, - BKN_DNX_PPH_9_FORWARD_DOMAIN_NOF_BITS, - &fld_val); - packet_info->pph_forward_domain = fld_val; - /* FTMH: Learn-Extension-Present */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_9_LEARN_EXT_PRESENT_MSB, - BKN_DNX_PPH_9_LEARN_EXT_PRESENT_NOF_BITS, - &fld_val); - learn_ext_present = fld_val; - /* FTMH: FHEI-Size */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_9_FHEI_SIZE_MSB, - BKN_DNX_PPH_9_FHEI_SIZE_NOF_BITS, - &fld_val); - fhei_size = fld_val; - /* FTMH: LIF-Extension-Type */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_9_LIF_EXT_TYPE_MSB, - BKN_DNX_PPH_9_LIF_EXT_TYPE_NOF_BITS, - &fld_val); - lif_ext_type = fld_val; +static int +bkn_dnx_packet_parse_internal( + bkn_switch_info_t *sinfo, + uint8_t *buf, + uint32_t buf_len, + bkn_dune_system_header_info_t *packet_info, + uint8_t is_oamp_punted, + uint8_t *is_trapped) +{ + uint32_t fld_val; + uint32_t pkt_offset = packet_info->system_header_size; + uint8_t learn_ext_present; + uint8_t fhei_size; + uint8_t lif_ext_type; + uint8_t udh_en = sinfo->udh_enable; - hdr_size += BKN_DNX_PPH_BASE_TYPE_9; - DBG_DUNE(("PPH(10) FWD_DOMAIN %d, LEARN_EXT %d, FHEI_SIZE %d, LIF_EXT %d \n", - packet_info->pph_forward_domain, learn_ext_present, fhei_size, lif_ext_type)); - break; - case BKN_DNX_PPH_BASE_TYPE_10: - /* FTMH: Forward-Domain */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_10_FORWARD_DOMAIN_MSB, - BKN_DNX_PPH_10_FORWARD_DOMAIN_NOF_BITS, - &fld_val); - packet_info->pph_forward_domain = fld_val; - /* FTMH: Learn-Extension-Present */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_10_LEARN_EXT_PRESENT_MSB, - BKN_DNX_PPH_10_LEARN_EXT_PRESENT_NOF_BITS, - &fld_val); - learn_ext_present = fld_val; - /* FTMH: FHEI-Size */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_10_FHEI_SIZE_MSB, - BKN_DNX_PPH_10_FHEI_SIZE_NOF_BITS, - &fld_val); - fhei_size = fld_val; - /* FTMH: LIF-Extension-Type */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_10_LIF_EXT_TYPE_MSB, - BKN_DNX_PPH_10_LIF_EXT_TYPE_NOF_BITS, - &fld_val); - lif_ext_type = fld_val; + if ((sinfo == NULL) || (buf == NULL) || (packet_info == NULL)) { + return -1; + } + + /* Internal: Forward-Domain */ + bkn_bitstream_get_field( + &buf[pkt_offset], + BKN_DNX_INTERNAL_12_FORWARD_DOMAIN_MSB, + BKN_DNX_INTERNAL_12_FORWARD_DOMAIN_NOF_BITS, + &fld_val); + packet_info->internal.forward_domain = fld_val; + /* Internal: Learn-Extension-Present */ + bkn_bitstream_get_field( + &buf[pkt_offset], + BKN_DNX_INTERNAL_12_LEARN_EXT_PRESENT_MSB, + BKN_DNX_INTERNAL_12_LEARN_EXT_PRESENT_NOF_BITS, + &fld_val); + learn_ext_present = fld_val; + /* Internal: FHEI-Size */ + bkn_bitstream_get_field( + &buf[pkt_offset], + BKN_DNX_INTERNAL_12_FHEI_SIZE_MSB, + BKN_DNX_INTERNAL_12_FHEI_SIZE_NOF_BITS, + &fld_val); + fhei_size = fld_val; + /* Internal: LIF-Extension-Type */ + bkn_bitstream_get_field( + &buf[pkt_offset], + BKN_DNX_INTERNAL_12_LIF_EXT_TYPE_MSB, + BKN_DNX_INTERNAL_12_LIF_EXT_TYPE_NOF_BITS, + &fld_val); + lif_ext_type = fld_val; - hdr_size += BKN_DNX_PPH_BASE_TYPE_10; - DBG_DUNE(("PPH(10) FWD_DOMAIN %d, LEARN_EXT %d, FHEI_SIZE %d, LIF_EXT %d \n", - packet_info->pph_forward_domain, learn_ext_present, fhei_size, lif_ext_type)); + pkt_offset += BKN_DNX_INTERNAL_BASE_TYPE_12; + DBG_DUNE(("Internal(12-%u): FWD_DOMAIN %d, LEARN_EXT %d, FHEI_SIZE %d, LIF_EXT %d \n", + pkt_offset, packet_info->internal.forward_domain, + learn_ext_present, fhei_size, lif_ext_type)); + + if (fhei_size) + { + switch (fhei_size) + { + case BKN_DNX_INTERNAL_FHEI_TYPE_SZ0: + pkt_offset += BKN_DNX_INTERNAL_FHEI_SZ0_SIZE; + DBG_DUNE(("FHEI(3-%u) is present\n", pkt_offset)); break; - case BKN_DNX_PPH_BASE_TYPE_12: - /* FTMH: Forward-Domain */ + case BKN_DNX_INTERNAL_FHEI_TYPE_SZ1: + /* FHEI: Type */ bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_12_FORWARD_DOMAIN_MSB, - BKN_DNX_PPH_12_FORWARD_DOMAIN_NOF_BITS, + &buf[pkt_offset], + BKN_DNX_INTERNAL_FHEI_TRAP_5B_TYPE_MSB, + BKN_DNX_INTERNAL_FHEI_TRAP_5B_TYPE_NOF_BITS, &fld_val); - packet_info->pph_forward_domain = fld_val; - /* FTMH: Learn-Extension-Present */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_12_LEARN_EXT_PRESENT_MSB, - BKN_DNX_PPH_12_LEARN_EXT_PRESENT_NOF_BITS, - &fld_val); - learn_ext_present = fld_val; - /* FTMH: FHEI-Size */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_12_FHEI_SIZE_MSB, - BKN_DNX_PPH_12_FHEI_SIZE_NOF_BITS, - &fld_val); - fhei_size = fld_val; - /* FTMH: LIF-Extension-Type */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_12_LIF_EXT_TYPE_MSB, - BKN_DNX_PPH_12_LIF_EXT_TYPE_NOF_BITS, - &fld_val); - lif_ext_type = fld_val; - - hdr_size += BKN_DNX_PPH_BASE_TYPE_12; - DBG_DUNE(("PPH(12) FWD_DOMAIN %d, LEARN_EXT %d, FHEI_SIZE %d, LIF_EXT %d \n", - packet_info->pph_forward_domain, learn_ext_present, fhei_size, lif_ext_type)); - break; - default: - fhei_size = 0; - lif_ext_type = 0; - learn_ext_present = 0; - break; - } - if (fhei_size) - { - switch (fhei_size) - { - case BKN_DNX_PPH_FHEI_TYPE_SZ0: - hdr_size += BKN_DNX_PPH_FHEI_SZ0_SIZE; - DBG_DUNE(("FHEI(3) is present\n")); - break; - case BKN_DNX_PPH_FHEI_TYPE_SZ1: + /* FHEI-Size == 5B, FHEI-Type == Trap/Sniff */ + if (fld_val == 0x5) + { + *is_trapped = TRUE; + /* FHEI: Qualifier */ + bkn_bitstream_get_field( + &buf[pkt_offset], + BKN_DNX_INTERNAL_FHEI_TRAP_5B_QUALIFIER_MSB, + BKN_DNX_INTERNAL_FHEI_TRAP_5B_QUALIFIER_NOF_BITS, + &fld_val); + packet_info->internal.trap_qualifier = fld_val; /* FHEI: Code */ bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_FHEI_TRAP_5B_TYPE_MSB, - BKN_DNX_PPH_FHEI_TRAP_5B_TYPE_NOF_BITS, + &buf[pkt_offset], + BKN_DNX_INTERNAL_FHEI_TRAP_5B_CODE_MSB, + BKN_DNX_INTERNAL_FHEI_TRAP_5B_CODE_NOF_BITS, &fld_val); - packet_info->fhei_type = fld_val; - /* FHEI-Size == 5B, FHEI-Type == Trap/Sniff */ - if (packet_info->fhei_type == 0x5) - { - /* FHEI: Qualifier */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_FHEI_TRAP_5B_QUALIFIER_MSB, - BKN_DNX_PPH_FHEI_TRAP_5B_QUALIFIER_NOF_BITS, - &fld_val); - packet_info->fhei_qualifier = fld_val; - /* FHEI: Code */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_FHEI_TRAP_5B_CODE_MSB, - BKN_DNX_PPH_FHEI_TRAP_5B_CODE_NOF_BITS, - &fld_val); - packet_info->fhei_code = fld_val; - } - hdr_size += BKN_DNX_PPH_FHEI_SZ1_SIZE; - DBG_DUNE(("FHEI(5) is present code 0x%x qualifier 0x%x\n", packet_info->fhei_code, packet_info->fhei_qualifier)); - break; - case BKN_DNX_PPH_FHEI_TYPE_SZ2: - hdr_size += BKN_DNX_PPH_FHEI_SZ1_SIZE; - DBG_DUNE(("FHEI(8) is present\n")); - break; - } + packet_info->internal.trap_id= fld_val; + } + pkt_offset += BKN_DNX_INTERNAL_FHEI_SZ1_SIZE; + DBG_DUNE(("FHEI(5-%u): code 0x%x qualifier 0x%x\n", pkt_offset, packet_info->internal.trap_id, packet_info->internal.trap_qualifier)); + break; + case BKN_DNX_INTERNAL_FHEI_TYPE_SZ2: + pkt_offset += BKN_DNX_INTERNAL_FHEI_SZ1_SIZE; + DBG_DUNE(("FHEI(8-%u) is present\n", pkt_offset)); + break; } + } - /* PPH LIF Extension */ - if (lif_ext_type) - { - hdr_size += sinfo->pph_lif_ext_size[lif_ext_type]; - DBG_DUNE(("PPH LIF Extension(%d) is present\n", sinfo->pph_lif_ext_size[lif_ext_type])); - } + /* PPH LIF Extension */ + if (lif_ext_type) + { + pkt_offset += sinfo->pph_lif_ext_size[lif_ext_type]; + DBG_DUNE(("PPH LIF Extension(%d-%u) is present\n", sinfo->pph_lif_ext_size[lif_ext_type], pkt_offset)); + } - /* PPH Learn Extension */ - if (learn_ext_present) - { - hdr_size += BKN_DNX_PPH_LEARN_EXT_SIZE; - DBG_DUNE(("PPH Learn Extension(19) is present\n")); - } + /* PPH Learn Extension */ + if (learn_ext_present) + { + pkt_offset += BKN_DNX_INTERNAL_LEARN_EXT_SIZE; + DBG_DUNE(("PPH Learn Extension(19-%u) is present\n", pkt_offset)); + } + + /** Skip UDH If packet is punted to CPU by OAMP */ + if (is_oamp_punted) { + udh_en = FALSE; } /* UDH Header */ - if (sinfo->udh_enable) + if (udh_en) { - uint8 data_type_0; - uint8 data_type_1; - uint8 data_type_2; - uint8 data_type_3; - - DBG_DUNE(("UDH base(1) is present\n")); + uint8_t data_type_0; + uint8_t data_type_1; + uint8_t data_type_2; + uint8_t data_type_3; /* UDH: UDH-Data-Type[0] */ bkn_bitstream_get_field( - &buf[hdr_size], + &buf[pkt_offset], BKN_DNX_UDH_DATA_TYPE_0_MSB, BKN_DNX_UDH_DATA_TYPE_0_NOF_BITS, &fld_val); data_type_0 = fld_val; - hdr_size += sinfo->udh_length_type[data_type_0]; /* UDH: UDH-Data-Type[1] */ bkn_bitstream_get_field( - &buf[hdr_size], + &buf[pkt_offset], BKN_DNX_UDH_DATA_TYPE_1_MSB, BKN_DNX_UDH_DATA_TYPE_1_NOF_BITS, &fld_val); data_type_1 = fld_val; - hdr_size += sinfo->udh_length_type[data_type_1]; /* UDH: UDH-Data-Type[2] */ bkn_bitstream_get_field( - &buf[hdr_size], + &buf[pkt_offset], BKN_DNX_UDH_DATA_TYPE_2_MSB, BKN_DNX_UDH_DATA_TYPE_2_NOF_BITS, &fld_val); data_type_2 = fld_val; - hdr_size += sinfo->udh_length_type[data_type_2]; /* UDH: UDH-Data-Type[3] */ bkn_bitstream_get_field( - &buf[hdr_size], + &buf[pkt_offset], BKN_DNX_UDH_DATA_TYPE_3_MSB, BKN_DNX_UDH_DATA_TYPE_3_NOF_BITS, &fld_val); data_type_3 = fld_val; - hdr_size += sinfo->udh_length_type[data_type_3]; - hdr_size += BKN_DNX_UDH_BASE_SIZE; + pkt_offset += BKN_DNX_UDH_BASE_SIZE; + pkt_offset += sinfo->udh_length_type[data_type_0]; + pkt_offset += sinfo->udh_length_type[data_type_1]; + pkt_offset += sinfo->udh_length_type[data_type_2]; + pkt_offset += sinfo->udh_length_type[data_type_3]; + DBG_DUNE(("UDH base(1-%u) is present\n", pkt_offset)); } - /* - * Check if fhei_type if of type trap - * There is a RISK that raw packet data is parsed and fhei_type is 0x5 by chance - */ - if (packet_info->fhei_type == 0x5) + packet_info->system_header_size = pkt_offset; + + return 0; +} + +static int +bkn_dnx_packet_header_parse( + bkn_switch_info_t *sinfo, + uint8_t *buff, + uint32_t buff_len, + bkn_dune_system_header_info_t *packet_info) +{ + uint8_t is_inter_hdr_en = FALSE; + uint8_t is_tsh_en = FALSE; + uint8_t is_oamp_punted = FALSE; + uint8_t is_trapped = FALSE; + + if ((sinfo == NULL) || (buff == NULL) || (packet_info == NULL)) { + return -1; + } + + /* FTMH */ + bkn_dnx_packet_parse_ftmh(sinfo, buff, buff_len, packet_info, &is_tsh_en, &is_inter_hdr_en); + + /* Time-Stamp */ + if (is_tsh_en == TRUE) { - /* Done for ingress trapped packets */ - packet_info->system_header_size = hdr_size; - DBG_DUNE(("Total Size of Headers is %d\n", packet_info->system_header_size)); - return 0; + packet_info->system_header_size += BKN_DNX_TSH_SIZE; + DBG_DUNE(("Time-Stamp Header(4-%u) is present\n", packet_info->system_header_size)); } - else + + /* Check if packet was punted to CPU by OAMP */ + if ((packet_info->ftmh.source_sys_port_aggregate == 232) + || (packet_info->ftmh.source_sys_port_aggregate == 233)) { - /* New generated header will be FTMH(80b), TSH(32b), PPH(96b), FHEI(40b) */ + is_oamp_punted = TRUE; + } - /* Revert packet_info except info from FTHM base header */ - packet_info->fhei_qualifier = 0; - packet_info->fhei_code = 0; - packet_info->fhei_type = 0; - hdr_size = pkt_offset_ingress_untrapped; + /* Internal */ + if (is_inter_hdr_en) + { + bkn_dnx_packet_parse_internal(sinfo, buff, buff_len, packet_info, is_oamp_punted, &is_trapped); + } - /* Time-Stamp Header */ - hdr_size += BKN_DNX_TSH_SIZE; - DBG_DUNE(("Time-Stamp Header(4) is present\n")); + if (is_oamp_punted) + { + is_inter_hdr_en = FALSE; + is_tsh_en = FALSE; + is_oamp_punted = FALSE; + is_trapped = FALSE; + + /* FTMH */ + bkn_dnx_packet_parse_ftmh(sinfo, buff, buff_len, packet_info, &is_tsh_en, &is_inter_hdr_en); + /* Time-Stamp */ + if (is_tsh_en == TRUE) + { + packet_info->system_header_size += BKN_DNX_TSH_SIZE; + DBG_DUNE(("Time-Stamp Header(4-%u) is present\n", packet_info->system_header_size)); + } + /* Internal */ + if (is_inter_hdr_en) + { + bkn_dnx_packet_parse_internal(sinfo, buff, buff_len, packet_info, is_oamp_punted, &is_trapped); + } + } - /** Packet Processing Header */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_12_FORWARD_DOMAIN_MSB, - BKN_DNX_PPH_12_FORWARD_DOMAIN_NOF_BITS, - &fld_val); - packet_info->pph_forward_domain = fld_val; - hdr_size += BKN_DNX_PPH_BASE_TYPE_12; - DBG_DUNE(("PPH(12) is present\n")); + DBG_DUNE(("Total length of headers is %u\n", packet_info->system_header_size)); - /* - * FHEI(Trap,40) - * 5B-FHEI format for sys_hdr_generation_profile:J2-OAM - * 8b' 0 - * 19b'oam_id - * 9b' cpu_trap_code: INGRESS_TRAP_ID is always 0 here - * 4b' type(0x5): J2-Configuration FHEI Type for CPU trap - */ - hdr_size += BKN_DNX_PPH_FHEI_SZ1_SIZE; - DBG_DUNE(("FHEI(5) is present\n")); + return 0; +} + +static int +bkn_packet_header_parse(bkn_switch_info_t *sinfo, uint8_t *buf, uint32_t buf_len, bkn_dune_system_header_info_t *packet_info) +{ + if (device_is_dpp(sinfo)) + { + bkn_dpp_packet_header_parse(sinfo, buf, buf_len, packet_info); + } + else if (device_is_dnx(sinfo)) + { + if (sinfo->system_headers_mode == BKN_DNX_JR2_MODE) + { + /* Jericho 2 mode */ + bkn_dnx_packet_header_parse(sinfo, buf, buf_len, packet_info); + } + else + { + /* Jericho/QMX/QAX mode */ + bkn_dpp_packet_header_parse(sinfo, buf, buf_len, packet_info); + } } - packet_info->system_header_size = hdr_size; - DBG_DUNE(("Total Size of Headers is %d\n", packet_info->system_header_size)); return 0; } - static int bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) { @@ -3492,8 +3524,8 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) int pktlen; int idx; int dcbs_done = 0; - bkn_dune_system_header_info_t packet_info = {0}; - uint32_t dnx_meta_data[3] = {0}; + bkn_dune_system_header_info_t packet_info; + uint32_t sand_scratch_data[BKN_SAND_SCRATCH_DATA_SIZE] = {0}; dcb_chain = sinfo->rx[chan].api_dcb_chain; if (dcb_chain == NULL) { @@ -3536,84 +3568,76 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) pkt_dma = dcb[0]; } pkt = (uint8_t *)kernel_bde->p2l(sinfo->dev_no, (sal_paddr_t)pkt_dma); - if (sinfo->cmic_type == 'x') { - if (device_is_dnx(sinfo)){ - meta = &dnx_meta_data[0]; - /* get error bit from last DCB words */ - err_woff = 2; - meta[err_woff] = dcb[sinfo->dcb_wsize-1]; - } else { + + if (device_is_sand(sinfo)) { + err_woff = BKN_SAND_SCRATCH_DATA_SIZE - 1; + sand_scratch_data[err_woff] = dcb[sinfo->dcb_wsize-1]; + meta = (uint32_t *)pkt; + } else { + if (sinfo->cmic_type == 'x') { meta = (uint32_t *)pkt; err_woff = sinfo->pkt_hdr_size / sizeof(uint32_t) - 1; meta[err_woff] = dcb[sinfo->dcb_wsize-1]; + } else { + meta = dcb; + err_woff = sinfo->dcb_wsize - 1; } - } else { - meta = dcb; - err_woff = sinfo->dcb_wsize - 1; } + pktlen = dcb[sinfo->dcb_wsize-1] & SOC_DCB_KNET_COUNT_MASK; bkn_dump_pkt(pkt, pktlen, XGS_DMA_RX_CHAN); - if (device_is_dpp(sinfo)) { - uint16_t tpid = 0; - uint16_t vid = 0; - int res = -1; - + if (device_is_sand(sinfo)) { memset(&packet_info, 0, sizeof(bkn_dune_system_header_info_t)); - res = bkn_dpp_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); - if (res == 0) { - if (packet_info.ftmh.action_type == 0x2) { - bkn_bitstream_set_field((uint32_t *)dcb, 192, 32, 0x8); - } else if (packet_info.ftmh.action_type == 0x1) { - bkn_bitstream_set_field((uint32_t *)dcb, 231, 25, 0x20); - } - bkn_bitstream_set_field((uint32_t *)dcb, 112, 16, packet_info.ftmh.src_sys_port); - bkn_bitstream_set_field((uint32_t *)dcb, 296, 12, packet_info.internal.vsi); - bkn_bitstream_set_field((uint32_t *)dcb, 64, 32, (packet_info.internal.trap_id << 16 | packet_info.internal.trap_qualifier)); - pkt += packet_info.ntwrk_header_ptr; - pktlen -= packet_info.ntwrk_header_ptr; - bkn_dump_pkt(pkt, 32, XGS_DMA_RX_CHAN); - /* check if vlan tag exists */ - tpid = (uint16_t)((pkt[12] << 8) | pkt[13]); - vid = (uint16_t)(packet_info.internal.vsi & 0xfff); + /* decode system headers and fill sratch data */ + bkn_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); + bkn_bitstream_set_field(sand_scratch_data, 0, 16, packet_info.internal.trap_id); + bkn_bitstream_set_field(sand_scratch_data, 16, 16, packet_info.internal.trap_qualifier); + bkn_bitstream_set_field(sand_scratch_data, 32, 16, packet_info.ftmh.source_sys_port_aggregate); + bkn_bitstream_set_field(sand_scratch_data, 48, 16, packet_info.internal.forward_domain); + bkn_bitstream_set_field(sand_scratch_data, 64, 2, packet_info.ftmh.action_type); + + if (force_tagged) { + uint8_t *eth_hdr = pkt + packet_info.system_header_size; + uint16_t tpid = 0; + + tpid = PKT_U16_GET(eth_hdr, 12); if (packet_is_untagged(tpid)) { + int raw_packet_len = pktlen - packet_info.system_header_size; + uint32_t vid = 0; + if ((pktlen + 4) < rx_buffer_size) { - DBG_DUNE(("add vlan tag (%d) to untagged packets\n", vid)); - for (idx = (pktlen-1); idx >= 12; idx--) { - pkt[idx+4] = pkt[idx]; + for (idx = (raw_packet_len - 1); idx >= 12; idx--) { + eth_hdr[idx+4] = eth_hdr[idx]; + } + if (ft_vid) { + vid = ft_vid; + } + else if (packet_info.internal.forward_domain) { + vid = packet_info.internal.forward_domain & 0xfff; } - pkt[12] = 0x81; - pkt[13] = 0x00; - pkt[14] = (vid >> 8); - pkt[15] = (vid & 0xff); + else { + vid = 1; + } + DBG_DUNE(("add vlan tag (%d) to untagged packets\n", vid)); + + eth_hdr[12] = (ft_tpid >> 8) & 0xff; + eth_hdr[13] = ft_tpid & 0xff; + eth_hdr[14] = (((ft_pri & 0x7) << 5) | ((ft_cfi & 0x1) << 4) | ((vid >> 8) & 0xf)) & 0xff; + eth_hdr[15] = vid & 0xff; /* reset packet length in DCB */ pktlen += 4; + bkn_dump_pkt(pkt, pktlen, XGS_DMA_RX_CHAN); dcb[sinfo->dcb_wsize-1] &= ~SOC_DCB_KNET_COUNT_MASK; - dcb[sinfo->dcb_wsize-1] |= ((pktlen + packet_info.ntwrk_header_ptr) & SOC_DCB_KNET_COUNT_MASK); - bkn_dump_pkt(pkt, 32, XGS_DMA_RX_CHAN); + dcb[sinfo->dcb_wsize-1] |= pktlen & SOC_DCB_KNET_COUNT_MASK; } } } } - else if (device_is_dnx(sinfo)) { - int res = -1; - res = bkn_dnx_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); - if (res == 0) { - bkn_bitstream_set_field(meta, 0, 16, packet_info.fhei_code); - bkn_bitstream_set_field(meta, 16, 16, packet_info.fhei_qualifier); - bkn_bitstream_set_field(meta, 32, 16, packet_info.ftmh_spa); - bkn_bitstream_set_field(meta, 48, 16, (packet_info.pph_forward_domain & 0xffff)); - - pkt += packet_info.system_header_size; - pktlen -= packet_info.system_header_size; - bkn_dump_pkt(pkt, 32, XGS_DMA_RX_CHAN); - } - } - if (device_is_dpp(sinfo)) { - filter = bkn_match_rx_pkt(sinfo, pkt, pktlen, dcb, chan, &cbf); - } else if (device_is_dnx(sinfo)) { - filter = bkn_match_rx_pkt(sinfo, pkt, pktlen, meta, chan, &cbf); + if (device_is_sand(sinfo)) { + filter = bkn_match_rx_pkt(sinfo, pkt + packet_info.system_header_size, + pktlen - packet_info.system_header_size, sand_scratch_data, chan, &cbf); } else { filter = bkn_match_rx_pkt(sinfo, pkt + sinfo->pkt_hdr_size, pktlen - sinfo->pkt_hdr_size, meta, chan, &cbf); @@ -3643,7 +3667,10 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) break; } - if (sinfo->cmic_type == 'x') { + if (device_is_sand(sinfo)) { + pkt += packet_info.system_header_size; + pktlen -= packet_info.system_header_size; + } else if (sinfo->cmic_type == 'x') { pkt += sinfo->pkt_hdr_size; pktlen -= sinfo->pkt_hdr_size; } @@ -3663,12 +3690,14 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) skb_reserve(skb, 2); /* 16 byte align the IP fields. */ /* Save for RCPU before stripping tag */ - ethertype = (pkt[16] << 8) | pkt[17]; + ethertype = PKT_U16_GET(pkt, 16); if ((priv->flags & KCOM_NETIF_F_KEEP_RX_TAG) == 0) { + uint16_t vlan_proto = PKT_U16_GET(pkt, 12); + if (filter->kf.flags & KCOM_FILTER_F_STRIP_TAG) { /* Strip the VLAN tag */ - uint16_t vlan_proto = (uint16_t)((pkt[12] << 8) | pkt[13]); - if (vlan_proto == 0x8100 || vlan_proto == 0x88a8) { + if (vlan_proto == ETH_P_8021Q || + vlan_proto == ETH_P_8021AD) { DBG_FLTR(("Strip VLAN tag\n")); for (idx = 11; idx >= 0; idx--) { pkt[idx+4] = pkt[idx]; @@ -3681,12 +3710,18 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) * Mark packet as VLAN-tagged, otherwise newer * kernels will strip the tag. */ - uint16_t tci = (pkt[14] << 8) | pkt[15]; + uint16_t tci = PKT_U16_GET(pkt, 14); + if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { bkn_vlan_hwaccel_put_tag(skb, ETH_P_8021Q, tci); } else { - bkn_vlan_hwaccel_put_tag(skb, - ((skb->data[12] << 8) | skb->data[13]), tci); + if (vlan_proto == ETH_P_8021AD) { + bkn_vlan_hwaccel_put_tag + (skb, ETH_P_8021AD, tci); + } else { + bkn_vlan_hwaccel_put_tag + (skb, ETH_P_8021Q, tci); + } } } } @@ -3702,11 +3737,16 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) priv->stats.rx_bytes += skb->len; /* Optional SKB updates */ + KNET_SKB_CB(skb)->dcb_type = sinfo->dcb_type & 0xFFFF; if (knet_rx_cb != NULL) { KNET_SKB_CB(skb)->netif_user_data = priv->cb_user_data; KNET_SKB_CB(skb)->filter_user_data = filter->kf.cb_user_data; - KNET_SKB_CB(skb)->dcb_type = sinfo->dcb_type & 0xFFFF; - skb = knet_rx_cb(skb, sinfo->dev_no, meta); + if (device_is_sand(sinfo)) { + skb = knet_rx_cb(skb, sinfo->dev_no, sand_scratch_data); + } + else { + skb = knet_rx_cb(skb, sinfo->dev_no, meta); + } if (skb == NULL) { /* Consumed by call-back */ sinfo->rx[chan].pkts_d_callback++; @@ -3715,12 +3755,12 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) } /* Do Rx timestamping */ - if (sinfo->rx_hwts) { - bkn_hw_tstamp_rx_set(sinfo, skb, meta); + if (priv->rx_hwts) { + bkn_hw_tstamp_rx_set(sinfo, priv->phys_port, skb, meta); } if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { - bkn_add_rcpu_encap(sinfo, skb, meta); + bkn_add_rcpu_encap(sinfo, skb, meta, packet_info.system_header_size); DBG_PDMP(("After add RCPU ENCAP\n")); bkn_dump_pkt(skb->data, pktlen + RCPU_RX_ENCAP_SIZE, XGS_DMA_RX_CHAN); } @@ -3792,7 +3832,9 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) int idx; int dcbs_done = 0; bkn_dune_system_header_info_t packet_info = {0}; - uint32_t dnx_meta_data[3] = {0}; + uint32_t sand_scratch_data[BKN_SAND_SCRATCH_DATA_SIZE] = {0}; + uint8_t sand_system_headers[RCPU_RX_META_SIZE] = {0}; + uint8_t *pkt = NULL; if (!sinfo->rx[chan].running) { /* Rx not ready */ @@ -3801,6 +3843,11 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) while (dcbs_done < budget) { char str[32]; + + if (!sinfo->rx[chan].running) { + /* DCBs might be cleaned up when bkn_knet_hw_reset is triggered. */ + return 0; + } sprintf(str, "Rx DCB (%d)", sinfo->rx[chan].dirty); desc = &sinfo->rx[chan].desc[sinfo->rx[chan].dirty]; dcb = desc->dcb_mem; @@ -3818,93 +3865,84 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) } sinfo->rx[chan].pkts++; skb = desc->skb; - if (sinfo->cmic_type == 'x') { - if (device_is_dnx(sinfo)){ - meta = &dnx_meta_data[0]; - /* get error bit from last DCB words */ - err_woff = 2; - meta[err_woff] = dcb[sinfo->dcb_wsize-1]; - } else { + + DBG_DCB_RX(("Rx%d SKB DMA done (%d).\n", chan, sinfo->rx[chan].dirty)); + BKN_DMA_UNMAP_SINGLE(sinfo->dma_dev, + desc->skb_dma, desc->dma_size, + BKN_DMA_FROMDEV); + desc->skb_dma = 0; + + if (device_is_sand(sinfo)) { + err_woff = BKN_SAND_SCRATCH_DATA_SIZE - 1; + sand_scratch_data[err_woff] = dcb[sinfo->dcb_wsize-1]; + meta = (uint32_t *)skb->data; + pkt = skb->data; + } else { + if (sinfo->cmic_type == 'x') { meta = (uint32_t *)skb->data; err_woff = sinfo->pkt_hdr_size / sizeof(uint32_t) - 1; meta[err_woff] = dcb[sinfo->dcb_wsize-1]; + } else { + meta = dcb; + err_woff = sinfo->dcb_wsize - 1; } - } else { - meta = dcb; - err_woff = sinfo->dcb_wsize - 1; } + pktlen = dcb[sinfo->dcb_wsize-1] & 0xffff; priv = netdev_priv(sinfo->dev); - DBG_DCB_RX(("Rx%d SKB DMA done (%d).\n", chan, sinfo->rx[chan].dirty)); - DMA_UNMAP_SINGLE(sinfo->dma_dev, - desc->skb_dma, desc->dma_size, - DMA_FROMDEV); - desc->skb_dma = 0; bkn_dump_pkt(skb->data, pktlen, XGS_DMA_RX_CHAN); - if (device_is_dpp(sinfo)) { - uint16_t tpid = 0; - uint16_t vid = 0; - uint8_t *pkt = skb->data; - int res = 0; - + if (device_is_sand(sinfo)) { memset(&packet_info, 0, sizeof(bkn_dune_system_header_info_t)); - res = bkn_dpp_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); - if (res == 0) { - if (packet_info.ftmh.action_type == 0x2) { - bkn_bitstream_set_field((uint32_t *)dcb, 192, 32, 0x8); - } else if (packet_info.ftmh.action_type == 0x1) { - bkn_bitstream_set_field((uint32_t *)dcb, 231, 25, 0x20); - } - bkn_bitstream_set_field((uint32_t *)dcb, 112, 16, packet_info.ftmh.src_sys_port); - bkn_bitstream_set_field((uint32_t *)dcb, 296, 12, packet_info.internal.vsi); - bkn_bitstream_set_field((uint32_t *)dcb, 64, 32, (packet_info.internal.trap_id << 16 | packet_info.internal.trap_qualifier)); - pkt = skb->data + packet_info.ntwrk_header_ptr; - /* check if vlan tag exists */ - tpid = (uint16_t)((pkt[12] << 8) | pkt[13]); - vid = (uint16_t)(packet_info.internal.vsi & 0xfff); + /* decode system headers and fill sratch data */ + bkn_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); + bkn_bitstream_set_field(sand_scratch_data, 0, 16, packet_info.internal.trap_id); + bkn_bitstream_set_field(sand_scratch_data, 16, 16, packet_info.internal.trap_qualifier); + bkn_bitstream_set_field(sand_scratch_data, 32, 16, packet_info.ftmh.source_sys_port_aggregate); + bkn_bitstream_set_field(sand_scratch_data, 48, 16, packet_info.internal.forward_domain); + bkn_bitstream_set_field(sand_scratch_data, 64, 2, packet_info.ftmh.action_type); + memcpy(sand_system_headers, pkt, + ((packet_info.system_header_size > RCPU_RX_META_SIZE) ? RCPU_RX_META_SIZE : packet_info.system_header_size)); + meta = (uint32_t *)sand_system_headers; + if (force_tagged) { + uint8_t *eth_hdr = pkt + packet_info.system_header_size; + uint16_t tpid = 0; + + tpid = PKT_U16_GET(eth_hdr, 12); if (packet_is_untagged(tpid)) { + int raw_packet_len = pktlen - packet_info.system_header_size; + uint32_t vid = 0; + if ((pktlen + 4) < rx_buffer_size) { - DBG_DUNE(("add vlan tag to untagged packets\n")); - for (idx = (pktlen-packet_info.ntwrk_header_ptr-1); idx >= 12; idx--) { - pkt[idx+4] = pkt[idx]; - } - pkt[12] = 0x81; - pkt[13] = 0x00; - pkt[14] = (vid >> 8); - pkt[15] = (vid & 0xff); - pktlen += 4; - /* reset packet length in DCB */ - dcb[sinfo->dcb_wsize-1] &= ~SOC_DCB_KNET_COUNT_MASK; - dcb[sinfo->dcb_wsize-1] |= (pktlen & SOC_DCB_KNET_COUNT_MASK); - bkn_dump_pkt(pkt, 32, XGS_DMA_RX_CHAN); + for (idx = (raw_packet_len - 1); idx >= 12; idx--) { + eth_hdr[idx+4] = eth_hdr[idx]; + } + if (ft_vid) { + vid = ft_vid; + } + else if (packet_info.internal.forward_domain) { + vid = packet_info.internal.forward_domain & 0xfff; + } + else { + vid = 1; + } + DBG_DUNE(("add vlan tag (%d) to untagged packets\n", vid)); + eth_hdr[12] = (ft_tpid >> 8) & 0xff; + eth_hdr[13] = ft_tpid & 0xff; + eth_hdr[14] = (((ft_pri & 0x7) << 5) | ((ft_cfi & 0x1) << 4) | ((vid >> 8) & 0xf)) & 0xff; + eth_hdr[15] = vid & 0xff; + /* reset packet length in DCB */ + pktlen += 4; + bkn_dump_pkt(pkt, pktlen, XGS_DMA_RX_CHAN); + dcb[sinfo->dcb_wsize-1] &= ~SOC_DCB_KNET_COUNT_MASK; + dcb[sinfo->dcb_wsize-1] |= pktlen & SOC_DCB_KNET_COUNT_MASK; } } } } - else if (device_is_dnx(sinfo)) { - uint8_t *pkt = skb->data; - int res = -1; - - res = bkn_dnx_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); - if (res == 0) { - bkn_bitstream_set_field(meta, 0, 16, packet_info.fhei_code); - bkn_bitstream_set_field(meta, 16, 16, packet_info.fhei_qualifier); - bkn_bitstream_set_field(meta, 32, 16, packet_info.ftmh_spa); - bkn_bitstream_set_field(meta, 48, 16, (packet_info.pph_forward_domain & 0xffff)); - - pkt += packet_info.system_header_size; - pktlen -= packet_info.ntwrk_header_ptr; - bkn_dump_pkt(pkt, 32, XGS_DMA_RX_CHAN); - } - } - - if (device_is_dpp(sinfo)) { - filter = bkn_match_rx_pkt(sinfo, skb->data + packet_info.ntwrk_header_ptr, - pktlen, dcb, chan, &cbf); - } else if (device_is_dnx(sinfo)) { + if (device_is_sand(sinfo)) { filter = bkn_match_rx_pkt(sinfo, skb->data + packet_info.system_header_size, - pktlen, meta, chan, &cbf); + pktlen - packet_info.system_header_size, sand_scratch_data, chan, &cbf); } else { filter = bkn_match_rx_pkt(sinfo, skb->data + sinfo->pkt_hdr_size, pktlen - sinfo->pkt_hdr_size, meta, chan, &cbf); @@ -3924,7 +3962,7 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) case KCOM_DEST_T_API: DBG_FLTR(("Send to Rx API\n")); sinfo->rx[chan].pkts_f_api++; - bkn_api_rx_copy_from_skb(sinfo, chan, desc); + bkn_api_rx_copy_from_skb(sinfo, chan, desc, 0); break; case KCOM_DEST_T_NETIF: priv = bkn_netif_lookup(sinfo, filter->kf.dest_id); @@ -3938,55 +3976,51 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) priv->id, priv->dev->name)); sinfo->rx[chan].pkts_f_netif++; - if (((filter->kf.mirror_type == KCOM_DEST_T_API) && - (!device_is_sand(sinfo))) || dbg_pkt_enable) { + if ((filter->kf.mirror_type == KCOM_DEST_T_API) || dbg_pkt_enable) { sinfo->rx[chan].pkts_m_api++; - bkn_api_rx_copy_from_skb(sinfo, chan, desc); + bkn_api_rx_copy_from_skb(sinfo, chan, desc, priv->rx_hwts); } - if (device_is_dpp(sinfo)) { - if (filter->kf.mirror_type == KCOM_DEST_T_API) { - sinfo->rx[chan].pkts_m_api++; - bkn_api_rx_copy_from_skb(sinfo, chan, desc); - } - /* Strip Dune headers */ - skb->data += packet_info.ntwrk_header_ptr; - pktlen -= packet_info.ntwrk_header_ptr; - bkn_dump_pkt(skb->data, 32, XGS_DMA_RX_CHAN); - /* CRC has been stripped on Dune*/ - skb_put(skb, pktlen); - } else if (device_is_dnx(sinfo)) { - if (filter->kf.mirror_type == KCOM_DEST_T_API) { - sinfo->rx[chan].pkts_m_api++; - bkn_api_rx_copy_from_skb(sinfo, chan, desc); - } - /* Strip Dune headers */ - skb->data += packet_info.system_header_size; - pktlen -= packet_info.system_header_size; - bkn_dump_pkt(skb->data, 32, XGS_DMA_RX_CHAN); + if (device_is_sand(sinfo)) { /* CRC has been stripped on Dune*/ skb_put(skb, pktlen); } else { skb_put(skb, pktlen - 4); /* Strip CRC */ } - if (sinfo->cmic_type == 'x' && !device_is_dnx(sinfo)) { + if (device_is_sand(sinfo)) { + skb_pull(skb, packet_info.system_header_size); + } else if (sinfo->cmic_type == 'x') { skb_pull(skb, sinfo->pkt_hdr_size); } + /* Optional SKB updates */ + KNET_SKB_CB(skb)->dcb_type = sinfo->dcb_type & 0xFFFF; + /* Do Rx timestamping */ + if (priv->rx_hwts) { + bkn_hw_tstamp_rx_set(sinfo, priv->phys_port, skb, meta); + } + /* Save for RCPU before stripping tag */ - ethertype = (skb->data[16] << 8) | skb->data[17]; + ethertype = PKT_U16_GET(skb->data, 16); if ((priv->flags & KCOM_NETIF_F_KEEP_RX_TAG) == 0) { + uint16_t vlan_proto; + + vlan_proto = PKT_U16_GET(skb->data, 12); if (filter->kf.flags & KCOM_FILTER_F_STRIP_TAG) { /* Strip VLAN tag */ - uint16_t vlan_proto = (uint16_t)((skb->data[12] << 8) | skb->data[13]); - if (vlan_proto == 0x8100 || vlan_proto == 0x88a8) { + if (vlan_proto == ETH_P_8021Q || + vlan_proto == ETH_P_8021AD) { DBG_FLTR(("Strip VLAN tag\n")); ((u32*)skb->data)[3] = ((u32*)skb->data)[2]; ((u32*)skb->data)[2] = ((u32*)skb->data)[1]; ((u32*)skb->data)[1] = ((u32*)skb->data)[0]; skb_pull(skb, 4); - if (sinfo->cmic_type == 'x' && !device_is_dnx(sinfo)) { + if (device_is_sand(sinfo)) { + for (idx = packet_info.system_header_size; idx >= 4; idx--) { + pkt[idx] = pkt[idx - 4]; + } + } else if (sinfo->cmic_type == 'x') { for (idx = sinfo->pkt_hdr_size / sizeof(uint32_t); idx; idx--) { meta[idx] = meta[idx - 1]; } @@ -3998,25 +4032,35 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) * Mark packet as VLAN-tagged, otherwise newer * kernels will strip the tag. */ - uint16_t tci = (skb->data[14] << 8) | skb->data[15]; + uint16_t tci = PKT_U16_GET(skb->data, 14); + if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { bkn_vlan_hwaccel_put_tag(skb, ETH_P_8021Q, tci); } else { - bkn_vlan_hwaccel_put_tag(skb, - ((skb->data[12] << 8) | skb->data[13]), tci); + if (vlan_proto == ETH_P_8021AD) { + bkn_vlan_hwaccel_put_tag + (skb, ETH_P_8021AD, tci); + } else { + bkn_vlan_hwaccel_put_tag + (skb, ETH_P_8021Q, tci); + } } } } + priv->stats.rx_packets++; priv->stats.rx_bytes += skb->len; skb->dev = priv->dev; - /* Optional SKB updates */ if (knet_rx_cb != NULL) { KNET_SKB_CB(skb)->netif_user_data = priv->cb_user_data; KNET_SKB_CB(skb)->filter_user_data = filter->kf.cb_user_data; - KNET_SKB_CB(skb)->dcb_type = sinfo->dcb_type & 0xFFFF; - skb = knet_rx_cb(skb, sinfo->dev_no, meta); + if (device_is_sand(sinfo)) { + skb = knet_rx_cb(skb, sinfo->dev_no, sand_scratch_data); + } + else { + skb = knet_rx_cb(skb, sinfo->dev_no, meta); + } if (skb == NULL) { /* Consumed by call-back */ sinfo->rx[chan].pkts_d_callback++; @@ -4026,13 +4070,8 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) } } - /* Do Rx timestamping */ - if (sinfo->rx_hwts) { - bkn_hw_tstamp_rx_set(sinfo, skb, meta); - } - if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { - bkn_add_rcpu_encap(sinfo, skb, meta); + bkn_add_rcpu_encap(sinfo, skb, meta, packet_info.system_header_size); DBG_PDMP(("After add RCPU ENCAP\n")); bkn_dump_pkt(skb->data, pktlen + RCPU_RX_ENCAP_SIZE, XGS_DMA_RX_CHAN); } @@ -4073,6 +4112,9 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) } } + /* Ensure that we reallocate SKB for this DCB */ + desc->skb = NULL; + /* Unlock while calling up network stack */ spin_unlock(&sinfo->lock); if (use_napi) { @@ -4082,8 +4124,6 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) } spin_lock(&sinfo->lock); - /* Ensure that we reallocate SKB for this DCB */ - desc->skb = NULL; } else { DBG_FLTR(("Unknown netif %d\n", filter->kf.dest_id)); @@ -4228,25 +4268,45 @@ bkn_resume_tx(bkn_switch_info_t *sinfo) } } +static void +bkn_skb_tstamp_copy(struct sk_buff *new_skb, struct sk_buff *skb) +{ + bkn_skb_tx_flags(new_skb) = bkn_skb_tx_flags(skb); + new_skb->sk = skb->sk; + + return; +} + static int bkn_hw_tstamp_tx_set(bkn_switch_info_t *sinfo, struct sk_buff *skb) { - struct skb_shared_hwtstamps shhwtstamps; + int hwts; + int port; uint64_t ts = 0; uint32_t hdrlen = sinfo->cmic_type == 'x' ? PKT_TX_HDR_SIZE : 0; - int port; + struct skb_shared_hwtstamps shhwtstamps; if (!knet_hw_tstamp_tx_time_get_cb) { return -1; } port = KNET_SKB_CB(skb)->port; - if (knet_hw_tstamp_tx_time_get_cb(sinfo->dev_no, port, skb->data + hdrlen, &ts) < 0) { - return -1; + hwts = KNET_SKB_CB(skb)->hwts; + ts = KNET_SKB_CB(skb)->ts; + + + if (hwts == HWTSTAMP_TX_ONESTEP_SYNC) { + if (ts == 0) { + return 1; + } + } else if (hwts == HWTSTAMP_TX_ON) { + if (knet_hw_tstamp_tx_time_get_cb(sinfo->dev_no, port, skb->data + hdrlen, &ts) < 0) { + return -1; + } } memset(&shhwtstamps, 0, sizeof(shhwtstamps)); - shhwtstamps.hwtstamp = ns_to_ktime(be64_to_cpu(ts)); + shhwtstamps.hwtstamp = ns_to_ktime(ts); skb_tstamp_tx(skb, &shhwtstamps); return 0; @@ -4257,11 +4317,28 @@ bkn_hw_tstamp_tx_work(struct work_struct *work) { bkn_switch_info_t *sinfo = container_of(work, bkn_switch_info_t, tx_ptp_work); struct sk_buff *skb; + int ret; while (skb_queue_len(&sinfo->tx_ptp_queue)) { skb = skb_dequeue(&sinfo->tx_ptp_queue); - if (bkn_hw_tstamp_tx_set(sinfo, skb) < 0) { - gprintk("Timestamp has not been taken for the current skb.\n"); + ret = bkn_hw_tstamp_tx_set(sinfo, skb); + if (ret < 0) { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) + ktime_t now; + now = ktime_get(); + DBG_PTP(("2Step TX Timestamp has not been taken for the current skb (%lld us)\n", + ktime_us_delta(now, skb->tstamp))); + } else { + ktime_t now; + now = ktime_get(); + /* Timeout 20 should be same as configured by PTP4L */ + if (ktime_us_delta(now, skb->tstamp) >= 20000) { + DBG_PTP(("2Step TX Timestamp fetch took long time %lld us\n", + ktime_us_delta(now, skb->tstamp))); + } +#else + DBG_PTP(("2Step TX Timestamp has not been taken for the current skb\n")); +#endif } dev_kfree_skb_any(skb); } @@ -4290,10 +4367,23 @@ bkn_do_tx(bkn_switch_info_t *sinfo) } if (desc->skb) { DBG_DCB_TX(("Tx SKB DMA done (%d).\n", sinfo->tx.dirty)); - DMA_UNMAP_SINGLE(sinfo->dma_dev, + BKN_DMA_UNMAP_SINGLE(sinfo->dma_dev, desc->skb_dma, desc->dma_size, - DMA_TODEV); + BKN_DMA_TODEV); + + if ((KNET_SKB_CB(desc->skb)->hwts == HWTSTAMP_TX_ONESTEP_SYNC) && + (bkn_skb_tx_flags(desc->skb) & SKBTX_IN_PROGRESS)) { + + if (bkn_hw_tstamp_tx_set(sinfo, desc->skb) < 0) { + gprintk("Timestamp has not been taken for the current skb.\n"); + } + bkn_skb_tx_flags(desc->skb) &= ~SKBTX_IN_PROGRESS; + } + if (bkn_skb_tx_flags(desc->skb) & SKBTX_IN_PROGRESS) { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) + desc->skb->tstamp = ktime_get(); +#endif skb_queue_tail(&sinfo->tx_ptp_queue, desc->skb); schedule_work(&sinfo->tx_ptp_work); } else { @@ -4858,6 +4948,22 @@ xgsx_isr(bkn_switch_info_t *sinfo) /* Not ours */ return; } + + /* Bypass chain_done from Abort */ + if (device_is_dnx(sinfo)) { + uint32_t ctrl = 0; + int chan = 0; + for (chan = 0; chan < NUM_DMA_CHAN; chan++) { + if (irq_stat & CMICX_DS_CMC_CHAIN_DONE(chan)) { + DEV_READ32(sinfo, CMICX_DMA_CTRLr + 0x80 * chan, &ctrl); + if (ctrl & CMICX_DC_CMC_ABORT) { + DBG_IRQ(("chain %d: chain done for Abort\n", chan)); + return; + } + } + } + } + sinfo->interrupts++; DBG_IRQ(("Got interrupt on device %d (0x%08x)\n", @@ -5010,7 +5116,11 @@ bkn_open(struct net_device *dev) static int bkn_set_mac_address(struct net_device *dev, void *addr) { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,18,12)) + if (!is_valid_ether_addr((const u8*)(((struct sockaddr *)addr)->sa_data))) { +#else if (!is_valid_ether_addr(((struct sockaddr *)addr)->sa_data)) { +#endif return -EINVAL; } memcpy(dev->dev_addr, ((struct sockaddr *)addr)->sa_data, dev->addr_len); @@ -5033,17 +5143,21 @@ bkn_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) if (!knet_hw_tstamp_enable_cb || !knet_hw_tstamp_disable_cb || priv->type != KCOM_NETIF_T_PORT) { - return -ERANGE; + return -ENOSYS; } switch (config.tx_type) { case HWTSTAMP_TX_OFF: - knet_hw_tstamp_disable_cb(sinfo->dev_no, priv->port); - sinfo->tx_hwts = 0; + knet_hw_tstamp_disable_cb(sinfo->dev_no, priv->phys_port, config.tx_type); + priv->tx_hwts = (config.tx_type); break; case HWTSTAMP_TX_ON: - knet_hw_tstamp_enable_cb(sinfo->dev_no, priv->port); - sinfo->tx_hwts = 1; + knet_hw_tstamp_enable_cb(sinfo->dev_no, priv->phys_port, config.tx_type); + priv->tx_hwts = (config.tx_type); + break; + case HWTSTAMP_TX_ONESTEP_SYNC: + knet_hw_tstamp_enable_cb(sinfo->dev_no, priv->phys_port, config.tx_type); + priv->tx_hwts = (config.tx_type); break; default: return -ERANGE; @@ -5051,15 +5165,15 @@ bkn_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) switch (config.rx_filter) { case HWTSTAMP_FILTER_NONE: - if (sinfo->rx_hwts) { - knet_hw_tstamp_disable_cb(sinfo->dev_no, priv->port); - sinfo->rx_hwts = 0; + if (priv->rx_hwts) { + knet_hw_tstamp_disable_cb(sinfo->dev_no, priv->phys_port, config.tx_type); + priv->rx_hwts = 0; } break; default: - if (!sinfo->rx_hwts) { - knet_hw_tstamp_enable_cb(sinfo->dev_no, priv->port); - sinfo->rx_hwts = 1; + if (!priv->rx_hwts) { + knet_hw_tstamp_enable_cb(sinfo->dev_no, priv->phys_port, config.tx_type); + priv->rx_hwts = 1; } config.rx_filter = HWTSTAMP_FILTER_ALL; break; @@ -5071,8 +5185,8 @@ bkn_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) if (cmd == SIOCGHWTSTAMP) { config.flags = 0; - config.tx_type = sinfo->tx_hwts ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF; - config.rx_filter = sinfo->rx_hwts ? HWTSTAMP_FILTER_ALL : HWTSTAMP_FILTER_NONE; + config.tx_type = priv->tx_hwts; + config.rx_filter = priv->rx_hwts ? HWTSTAMP_FILTER_ALL : HWTSTAMP_FILTER_NONE; return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? -EFAULT : 0; } @@ -5208,7 +5322,9 @@ bkn_set_multicast_list(struct net_device *dev) } static int -bkn_hw_tstamp_tx_config(bkn_switch_info_t *sinfo, struct sk_buff *skb, uint32_t *meta) +bkn_hw_tstamp_tx_config(bkn_switch_info_t *sinfo, + int hwts, int hdrlen, + struct sk_buff *skb, u32 *meta) { uint32_t *md = NULL; @@ -5217,7 +5333,13 @@ bkn_hw_tstamp_tx_config(bkn_switch_info_t *sinfo, struct sk_buff *skb, uint32_t } KNET_SKB_CB(skb)->dcb_type = sinfo->dcb_type & 0xFFFF; - knet_hw_tstamp_tx_meta_get_cb(sinfo->dev_no, skb, &md); + knet_hw_tstamp_tx_meta_get_cb(sinfo->dev_no, hwts, hdrlen, skb, + &(KNET_SKB_CB(skb)->ts), (meta ? &md : NULL)); + + if (!meta) { + return 0; + } + if (!md) { return -1; } @@ -5226,6 +5348,7 @@ bkn_hw_tstamp_tx_config(bkn_switch_info_t *sinfo, struct sk_buff *skb, uint32_t case 26: case 32: case 33: + case 35: meta[2] |= md[0]; meta[3] |= md[1]; meta[4] |= md[2]; @@ -5233,10 +5356,10 @@ bkn_hw_tstamp_tx_config(bkn_switch_info_t *sinfo, struct sk_buff *skb, uint32_t break; case 36: case 38: - meta[0] |= md[0]; - meta[1] |= md[1]; - meta[2] |= md[2]; - meta[3] |= md[3]; + meta[0] |= htonl(md[0]); + meta[1] |= htonl(md[1]); + meta[2] |= htonl(md[2]); + meta[3] |= htonl(md[3]); break; default: return -1; @@ -5257,8 +5380,10 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) uint16_t tpid; uint32_t *metadata; unsigned long flags; + uint32_t cpu_channel = 0; + int headroom, tailroom; - DBG_VERB(("Netif Tx: Len=%d\n", skb->len)); + DBG_VERB(("Netif Tx: Len=%d priv->id=%d\n", skb->len, priv->id)); if (priv->id <= 0) { /* Do not transmit on base device */ @@ -5267,8 +5392,14 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) return 0; } + if (device_is_dnx(sinfo) && (skb->len == 0)) { + priv->stats.tx_dropped++; + dev_kfree_skb_any(skb); + return 0; + } + if (!netif_carrier_ok(dev)) { - DBG_WARN(("Tx drop: Invalid RCPU encapsulation\n")); + DBG_WARN(("Tx drop: Netif link is down.\n")); priv->stats.tx_dropped++; sinfo->tx.pkts_d_no_link++; dev_kfree_skb_any(skb); @@ -5283,7 +5414,13 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) pktdata = skb->data; pktlen = skb->len; - hdrlen = (sinfo->cmic_type == 'x' ) ? ((device_is_dnx(sinfo)) ? priv->system_headers_size: PKT_TX_HDR_SIZE) : 0; + + if (device_is_sand(sinfo)) { + hdrlen = priv->system_headers_size; + } + else { + hdrlen = (sinfo->cmic_type == 'x' ) ? PKT_TX_HDR_SIZE : 0; + } rcpulen = 0; sop = 0; @@ -5298,7 +5435,7 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) return 0; } if (check_rcpu_signature && - ((skb->data[18] << 8) | skb->data[19]) != sinfo->rcpu_sig) { + PKT_U16_GET(skb->data, 18) != sinfo->rcpu_sig) { DBG_WARN(("Tx drop: Invalid RCPU signature\n")); priv->stats.tx_dropped++; sinfo->tx.pkts_d_rcpu_sig++; @@ -5306,7 +5443,15 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) spin_unlock_irqrestore(&sinfo->lock, flags); return 0; } - if (skb->data[21] & RCPU_F_MODHDR) { + + if (device_is_sand(sinfo)) { + /* Dune devices don't use meta data */ + sop = 0; + /* Get CPU channel from rcpu_hdr_t.reserved */ + cpu_channel = (skb->data[28] << 24) | (skb->data[29] << 16) | (skb->data[30] << 8) | (skb->data[31]); + /* System headers are supposed to be set by users in RCPU mode. */ + hdrlen = 0; + } else if (skb->data[21] & RCPU_F_MODHDR) { sop = skb->data[RCPU_HDR_SIZE]; switch (sop) { case 0xff: @@ -5332,50 +5477,80 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) /* CPU packets require tag */ if (sop == 0) { - hdrlen = 0; - tpid = (pktdata[12] << 8) | pktdata[13]; - if (tpid != 0x8100) { - if (skb_header_cloned(skb)) { - /* Current SKB cannot be modified */ - DBG_SKB(("Realloc Tx SKB\n")); - new_skb = dev_alloc_skb(pktlen + TAG_SZ + FCS_SZ); - if (new_skb == NULL) { - DBG_WARN(("Tx drop: No SKB memory\n")); - priv->stats.tx_dropped++; - sinfo->tx.pkts_d_no_skb++; + if (device_is_sand(sinfo)) { + /* + * There should be Module Header + PTCH_2 + [ITMH] on JR2, + * PTCH_2 +[ITMH] on JR1 + */ + } else { + hdrlen = 0; + tpid = PKT_U16_GET(pktdata, 12); + if (tpid != 0x8100) { + if (skb_header_cloned(skb)) { + /* Current SKB cannot be modified */ + DBG_SKB(("Realloc Tx SKB\n")); + /* + * New SKB needs extra TAG_SZ for VLAN tag + * and extra FCS_SZ for Ethernet FCS. + */ + headroom = TAG_SZ; + tailroom = FCS_SZ; + new_skb = skb_copy_expand(skb, + headroom + skb_headroom(skb), + tailroom + skb_tailroom(skb), + GFP_ATOMIC); + if (new_skb == NULL) { + DBG_WARN(("Tx drop: No SKB memory\n")); + priv->stats.tx_dropped++; + sinfo->tx.pkts_d_no_skb++; + dev_kfree_skb_any(skb); + spin_unlock_irqrestore(&sinfo->lock, flags); + return 0; + } + /* Remove rcpulen from buffer. */ + skb_pull(new_skb, rcpulen); + /* Extended by TAG_SZ at the start of buffer. */ + skb_push(new_skb, TAG_SZ); + /* Restore the data before the tag. */ + memcpy(new_skb->data, pktdata, 12); + bkn_skb_tstamp_copy(new_skb, skb); dev_kfree_skb_any(skb); - spin_unlock_irqrestore(&sinfo->lock, flags); - return 0; - } - memcpy(new_skb->data, pktdata, 12); - memcpy(&new_skb->data[16], &pktdata[12], pktlen - 12); - skb_put(new_skb, pktlen + TAG_SZ); - dev_kfree_skb_any(skb); - skb = new_skb; - pktdata = skb->data; - rcpulen = 0; - } else { - /* Add tag to RCPU header space */ - DBG_SKB(("Expand into unused RCPU header\n")); - rcpulen -= TAG_SZ; - pktdata = &skb->data[rcpulen]; - for (idx = 0; idx < 12; idx++) { - pktdata[idx] = pktdata[idx + TAG_SZ]; + skb = new_skb; + pktdata = skb->data; + rcpulen = 0; + } else { + /* Add tag to RCPU header space */ + DBG_SKB(("Expand into unused RCPU header\n")); + rcpulen -= TAG_SZ; + pktdata = &skb->data[rcpulen]; + for (idx = 0; idx < 12; idx++) { + pktdata[idx] = pktdata[idx + TAG_SZ]; + } } + pktdata[12] = 0x81; + pktdata[13] = 0x00; + pktdata[14] = (priv->vlan >> 8) & 0xf; + pktdata[15] = priv->vlan & 0xff; + pktlen += TAG_SZ; } - pktdata[12] = 0x81; - pktdata[13] = 0x00; - pktdata[14] = (priv->vlan >> 8) & 0xf; - pktdata[15] = priv->vlan & 0xff; - pktlen += TAG_SZ; } } } else { - if (sinfo->cmic_type == 'x' && priv->port >= 0) { + if (((sinfo->cmic_type == 'x') && (priv->port >= 0)) + || device_is_sand(sinfo)) { if (skb_header_cloned(skb) || skb_headroom(skb) < hdrlen + 4) { /* Current SKB cannot be modified */ DBG_SKB(("Realloc Tx SKB\n")); - new_skb = dev_alloc_skb(pktlen + hdrlen + 4 + FCS_SZ); + if (device_is_sand(sinfo)) { + headroom = hdrlen; + } else { + headroom = hdrlen + 4; + } + tailroom = FCS_SZ; + new_skb = skb_copy_expand(skb, + headroom + skb_headroom(skb), + tailroom + skb_tailroom(skb), + GFP_ATOMIC); if (new_skb == NULL) { DBG_WARN(("Tx drop: No SKB memory\n")); priv->stats.tx_dropped++; @@ -5384,12 +5559,8 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) spin_unlock_irqrestore(&sinfo->lock, flags); return 0; } - if (!device_is_dnx(sinfo)) - { - skb_reserve(new_skb, 4); - } - memcpy(new_skb->data + hdrlen, skb->data, pktlen); - skb_put(new_skb, pktlen + hdrlen); + skb_push(new_skb, hdrlen); + bkn_skb_tstamp_copy(new_skb, skb); dev_kfree_skb_any(skb); skb = new_skb; } else { @@ -5406,12 +5577,17 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) if (priv->port < 0 || (priv->flags & KCOM_NETIF_F_ADD_TAG)) { DBG_DUNE(("ADD VLAN TAG\n")); /* Need to add VLAN tag if packet is untagged */ - tpid = (skb->data[hdrlen + 12] << 8) | skb->data[hdrlen + 13]; + tpid = PKT_U16_GET(skb->data, hdrlen + 12); if (tpid != 0x8100) { if (skb_header_cloned(skb) || skb_headroom(skb) < 4) { /* Current SKB cannot be modified */ DBG_SKB(("Realloc Tx SKB\n")); - new_skb = dev_alloc_skb(pktlen + TAG_SZ + FCS_SZ); + headroom = TAG_SZ; + tailroom = FCS_SZ; + new_skb = skb_copy_expand(skb, + headroom + skb_headroom(skb), + tailroom + skb_tailroom(skb), + GFP_ATOMIC); if (new_skb == NULL) { DBG_WARN(("Tx drop: No SKB memory\n")); priv->stats.tx_dropped++; @@ -5420,10 +5596,9 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) spin_unlock_irqrestore(&sinfo->lock, flags); return 0; } - memcpy(new_skb->data, skb->data, hdrlen + 12); - memcpy(&new_skb->data[hdrlen + 16], &skb->data[hdrlen + 12], - pktlen - hdrlen - 12); - skb_put(new_skb, pktlen + TAG_SZ); + skb_push(new_skb, TAG_SZ); + memcpy(new_skb->data, pktdata, hdrlen + 12); + bkn_skb_tstamp_copy(new_skb, skb); dev_kfree_skb_any(skb); skb = new_skb; } else { @@ -5446,7 +5621,7 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) /* Pad packet if needed */ taglen = 0; - tpid = (pktdata[hdrlen + 12] << 8) | pktdata[hdrlen + 13]; + tpid = PKT_U16_GET(pktdata, hdrlen + 12); if (tpid == 0x8100) { taglen = 4; } @@ -5478,8 +5653,19 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) meta = (sinfo->cmic_type == 'x') ? (uint32_t *)pktdata : dcb; memset(dcb, 0, sinfo->dcb_wsize * sizeof(uint32_t)); if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { - /* If module header SOP is non-zero, use RCPU meta data */ - if (sop != 0) { + if (device_is_sand(sinfo)) { + if (sinfo->cmic_type == 'x') { + dcb[2] |= 1 << 19; + /* Given Module Header exists and set first byte to be CPU channel */ + pktdata[0] = cpu_channel; + } else { + dcb[1] |= 1 << 19; + /* Set CPU channel */ + dcb[2] = (cpu_channel & 0xff) << 24; + } + + } else if (sop != 0) { + /* If module header SOP is non-zero, use RCPU meta data */ if (sinfo->cmic_type == 'x') { dcb[2] |= 1 << 19; } else { @@ -5521,67 +5707,15 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) dcb[4] |= (priv->qnum & 0xfff) << 14; break; case 28: - { - if (priv->type == KCOM_NETIF_T_PORT) { - /* add PTCH ITMH header */ - if (skb_header_cloned(skb) || skb_headroom(skb) < 4) { - /* Current SKB cannot be modified */ - DBG_SKB(("Realloc Tx SKB for DNX ITMH header\n")); - new_skb = dev_alloc_skb(pktlen + 4 + 2 + FCS_SZ); - if (new_skb == NULL) { - DBG_WARN(("Tx drop: No SKB memory for DNX ITMH header\n")); - priv->stats.tx_dropped++; - sinfo->tx.pkts_d_no_skb++; - dev_kfree_skb_any(skb); - spin_unlock_irqrestore(&sinfo->lock, flags); - return 0; - } - memcpy(&new_skb->data[6], skb->data, pktlen); - skb_put(new_skb, pktlen + 6); - dev_kfree_skb_any(skb); - skb = new_skb; - } else { - /* Add tag to existing buffer */ - DBG_SKB(("Expand Tx SKB for DNX ITMH header\n")); - skb_push(skb, 6); - } - pktdata = skb->data; - pktdata[0] = 0x50; - pktdata[1] = 0x00; - memcpy(&pktdata[2], priv->itmh, 4); - pktlen += 6; - } - else if (priv->type == KCOM_NETIF_T_VLAN) { - /* add PTCH header */ - if (skb_header_cloned(skb) || skb_headroom(skb) < 4) { - /* Current SKB cannot be modified */ - DBG_SKB(("Realloc Tx SKB for DNX header\n")); - new_skb = dev_alloc_skb(pktlen + 2 + FCS_SZ); - if (new_skb == NULL) { - DBG_WARN(("Tx drop: No SKB memory for DNX header\n")); - priv->stats.tx_dropped++; - sinfo->tx.pkts_d_no_skb++; - dev_kfree_skb_any(skb); - spin_unlock_irqrestore(&sinfo->lock, flags); - return 0; - } - memcpy(&new_skb->data[2], skb->data, pktlen); - skb_put(new_skb, pktlen + 2); - dev_kfree_skb_any(skb); - skb = new_skb; - } else { - /* Add tag to existing buffer */ - DBG_SKB(("Expand Tx SKB for DNX header\n")); - skb_push(skb, 2); - } - pktdata = skb->data; - pktdata[0] = 0xd0; - pktdata[1] = priv->port; - pktlen += 2; - } - dcb[1] = pktlen; - break; - } + /* + * If KCOM_NETIF_T_PORT, add PTCH+ITMH header + * If KCOM_NETIF_T_VLAN, add PTCH+header + */ + pktdata = skb->data; + memcpy(&pktdata[0], priv->system_headers, priv->system_headers_size); + /* Set CPU channel */ + dcb[2] = ((priv->qnum & 0xff) << 24); + break; case 29: dcb[2] = 0x81000000; dcb[3] = priv->port; @@ -5640,6 +5774,19 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) memcpy(&pktdata[0], priv->system_headers, priv->system_headers_size); } break; + case 40: + if (sinfo->cmic_type == 'x') { + meta[0] = htonl(0x81000000); + meta[1] = htonl(priv->port | (priv->qnum & 0xc00) << 20); + meta[2] = htonl(0x00040000 | (priv->qnum & 0x3ff) << 8); + } else { + dcb[2] = 0x81000000; + dcb[3] = priv->port; + dcb[3] |= (priv->qnum & 0xc00) << 20; + dcb[4] = 0x00040000; + dcb[4] |= (priv->qnum & 0x3ff) << 8; + } + break; default: dcb[2] = 0xff000000; dcb[3] = 0x00000100; @@ -5695,24 +5842,46 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) } /* Do Tx timestamping */ - if (priv->port >= 0) { - if (bkn_skb_tx_flags(skb) & SKBTX_HW_TSTAMP && sinfo->tx_hwts) { - KNET_SKB_CB(skb)->port = priv->port; - bkn_hw_tstamp_tx_config(sinfo, skb, meta); + if (bkn_skb_tx_flags(skb) & SKBTX_HW_TSTAMP) { + KNET_SKB_CB(skb)->hwts = priv->tx_hwts; + if ((priv->port >= 0) && (priv->tx_hwts & HWTSTAMP_TX_ON)) { + /* TwoStep Processing of ptp-packets */ + KNET_SKB_CB(skb)->port = priv->phys_port; + bkn_hw_tstamp_tx_config(sinfo, priv->tx_hwts, PKT_TX_HDR_SIZE, skb, meta); + bkn_skb_tx_flags(skb) |= SKBTX_IN_PROGRESS; + bkn_skb_tx_timestamp(skb); + + } else if (priv->tx_hwts & HWTSTAMP_TX_ONESTEP_SYNC) { + + /* OneStep Processing of ptp-packets */ + KNET_SKB_CB(skb)->port = priv->phys_port; + KNET_SKB_CB(skb)->ts = 0; + bkn_hw_tstamp_tx_config(sinfo, priv->tx_hwts, PKT_TX_HDR_SIZE, skb, + ((priv->port >= 0) ? meta : NULL)); + + if (KNET_SKB_CB(skb)->ts != 0) { + bkn_skb_tx_flags(skb) |= SKBTX_IN_PROGRESS; + bkn_skb_tx_timestamp(skb); + } + } - bkn_skb_tx_timestamp(skb); } /* Prepare for DMA */ desc->skb = skb; - /* Add FCS bytes */ - pktlen = pktlen + FCS_SZ; + /* + * Add FCS bytes + * FCS bytes are always appended to packet by MAC on Dune devices + */ + if (!device_is_sand(sinfo)) { + pktlen = pktlen + FCS_SZ; + } desc->dma_size = pktlen; - desc->skb_dma = DMA_MAP_SINGLE(sinfo->dma_dev, + desc->skb_dma = BKN_DMA_MAP_SINGLE(sinfo->dma_dev, pktdata, desc->dma_size, - DMA_TODEV); - if (DMA_MAPPING_ERROR(sinfo->dma_dev, desc->skb_dma)) { + BKN_DMA_TODEV); + if (BKN_DMA_MAPPING_ERROR(sinfo->dma_dev, desc->skb_dma)) { priv->stats.tx_dropped++; dev_kfree_skb_any(skb); spin_unlock_irqrestore(&sinfo->lock, flags); @@ -5758,15 +5927,11 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) priv->stats.tx_bytes += pktlen; sinfo->tx.pkts++; } else { - DBG_WARN(("Tx drop: No DMA resources\n")); - priv->stats.tx_dropped++; + DBG_VERB(("Tx busy: No DMA resources\n")); sinfo->tx.pkts_d_dma_resrc++; - dev_kfree_skb_any(skb); - } - - /* Check our Tx resources */ - if (sinfo->tx.free <= 1) { bkn_suspend_tx(sinfo); + spin_unlock_irqrestore(&sinfo->lock, flags); + return BKN_NETDEV_TX_BUSY; } NETDEV_UPDATE_TRANS_START_TIME(dev); @@ -5986,6 +6151,7 @@ bkn_create_sinfo(int dev_no) sinfo->dma_dev = lkbde_get_dma_dev(dev_no); sinfo->pdev = lkbde_get_hw_dev(dev_no); sinfo->dev_no = dev_no; + sinfo->inst_id = INVALID_INSTANCE_ID; sinfo->evt_idx = -1; spin_lock_init(&sinfo->lock); @@ -6077,8 +6243,10 @@ bkn_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info) case 26: case 32: case 33: + case 35: case 36: case 38: + case 40: info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE | SOF_TIMESTAMPING_TX_SOFTWARE | SOF_TIMESTAMPING_RX_HARDWARE | @@ -6105,11 +6273,43 @@ bkn_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info) } #endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0)) +static int bkn_get_link_ksettings(struct net_device *netdev, + struct ethtool_link_ksettings *cmd) +{ + bkn_priv_t *priv = netdev_priv(netdev); + + /* only speed info now, can enhance later */ + if (priv) { + cmd->base.speed = priv->link_settings.speed; + cmd->base.duplex = priv->link_settings.duplex; + } + return 0; +} + +static int bkn_set_link_ksettings(struct net_device *netdev, + const struct ethtool_link_ksettings *cmd) +{ + bkn_priv_t *priv = netdev_priv(netdev); + + /* only speed info now, can enhance later */ + if (priv) { + priv->link_settings.speed = cmd->base.speed; + priv->link_settings.duplex = cmd->base.speed? DUPLEX_FULL : 0; + } + return 0; +} +#endif + static const struct ethtool_ops bkn_ethtool_ops = { .get_drvinfo = bkn_get_drvinfo, #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)) .get_ts_info = bkn_get_ts_info, #endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0)) + .get_link_ksettings = bkn_get_link_ksettings, + .set_link_ksettings = bkn_set_link_ksettings, +#endif }; static struct net_device * @@ -6140,10 +6340,6 @@ bkn_init_ndev(u8 *mac, char *name) if (dev->mtu == 0) { dev->mtu = rx_buffer_size; } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)) - dev->min_mtu = 68; - dev->max_mtu = rx_buffer_size; -#endif /* Device vectors */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) @@ -6165,8 +6361,8 @@ bkn_init_ndev(u8 *mac, char *name) strncpy(dev->name, name, IFNAMSIZ-1); } -#ifdef CONFIG_NET_NS - dev_net_set(dev, current->nsproxy->net_ns); +#if defined(CONFIG_NET_NS) + bkn_dev_net_set(dev, current->nsproxy->net_ns); #endif /* Register the kernel Ethernet device */ @@ -6739,9 +6935,11 @@ bkn_proc_debug_show(struct seq_file *m, void *v) seq_printf(m, " use_napi: %d\n", use_napi); seq_printf(m, " napi_weight: %d\n", napi_weight); seq_printf(m, " basedev_susp: %d\n", basedev_suspend); - seq_printf(m, "Thread states:\n"); - seq_printf(m, " Command thread: %d\n", bkn_cmd_ctrl.state); - seq_printf(m, " Event thread: %d\n", bkn_evt_ctrl.state); + seq_printf(m, " force_tagged: %d\n", force_tagged); + seq_printf(m, " ft_tpid: %d\n", ft_tpid); + seq_printf(m, " ft_pri: %d\n", ft_pri); + seq_printf(m, " ft_pri: %d\n", ft_cfi); + seq_printf(m, " ft_tpid: %d\n", ft_vid); seq_printf(m, "Active IOCTLs:\n"); seq_printf(m, " Command: %d\n", ioctl_cmd); seq_printf(m, " Event: %d\n", ioctl_evt); @@ -7142,9 +7340,9 @@ bkn_proc_cleanup(void) */ static int -_pprint(void) +_pprint(struct seq_file *m) { - pprintf("Broadcom BCM KNET Linux Network Driver\n"); + pprintf(m, "Broadcom BCM KNET Linux Network Driver\n"); return 0; } @@ -7306,7 +7504,7 @@ bkn_create_inst(uint32 inst_id) DBG_INST(("%s evt_idx %d inst_id 0x%x\n",__FUNCTION__, i, inst_id)); break; } - if ((_bkn_multi_inst == 0) || (evt->inst_id == 0)) { + if ((_bkn_multi_inst == 0) || (evt->inst_id == INVALID_INSTANCE_ID)) { _bkn_multi_inst ++; evt_idx = i; init_waitqueue_head(&evt->evt_wq); @@ -7321,7 +7519,7 @@ bkn_create_inst(uint32 inst_id) return -1; } for (i = 0; i < kernel_bde->num_devices(BDE_ALL_DEVICES); i++) { - if (inst_id & (1 << i)) { + if (lkbde_is_dev_managed_by_instance(i, inst_id)) { sinfo = bkn_sinfo_from_unit(i); spin_lock_irqsave(&sinfo->lock, flags); sinfo->evt_idx = evt_idx; @@ -7365,23 +7563,28 @@ bkn_knet_dev_inst_set(kcom_msg_reprobe_t *kmsg) { bkn_switch_info_t *sinfo; int d = kmsg->hdr.unit; - uint32 inst = 0; + uint32 inst = INVALID_INSTANCE_ID; unsigned long flags; struct list_head *list; sinfo = bkn_sinfo_from_unit(d); +#ifdef BCM_INSTANCE_SUPPORT lkbde_dev_instid_get(d, &inst); +#else + inst = INVALID_INSTANCE_ID; +#endif + DBG_INST(("%s sinfo->inst_id %d d %d inst %d\n",__FUNCTION__,sinfo->inst_id, d, inst)); spin_lock_irqsave(&sinfo->lock, flags); if (sinfo->inst_id != inst) { /* Instance database changed, reinit the inst_id */ - sinfo->inst_id = 0; + sinfo->inst_id = INVALID_INSTANCE_ID; sinfo->evt_idx = -1; } spin_unlock_irqrestore(&sinfo->lock, flags); - if (inst) { - if (sinfo->inst_id == 0) { + if (inst != INVALID_INSTANCE_ID) { + if (sinfo->inst_id == INVALID_INSTANCE_ID) { if (bkn_create_inst(inst) != 0) { return -1; } @@ -7395,7 +7598,7 @@ bkn_knet_dev_inst_set(kcom_msg_reprobe_t *kmsg) sinfo = (bkn_switch_info_t *)list; spin_lock_irqsave(&sinfo->lock, flags); sinfo->evt_idx = 0; - sinfo->inst_id = 0; + sinfo->inst_id = INVALID_INSTANCE_ID; spin_unlock_irqrestore(&sinfo->lock, flags); } } @@ -7510,6 +7713,27 @@ bkn_knet_hw_init(kcom_msg_hw_init_t *kmsg, int len) } } + if (device_is_sand(sinfo)) { + int idx = 0; + /* Information to parser Dune system headers */ + sinfo->ftmh_lb_key_ext_size = kmsg->ftmh_lb_key_ext_size; + sinfo->ftmh_stacking_ext_size = kmsg->ftmh_stacking_ext_size; + sinfo->pph_base_size = kmsg->pph_base_size; + for (idx = 0; idx < 8; idx++) + { + sinfo->pph_lif_ext_size[idx] = kmsg->pph_lif_ext_size[idx]; + } + for (idx = 0; idx < 4; idx++) + { + sinfo->udh_length_type[idx] = kmsg->udh_length_type[idx]; + } + sinfo->udh_size = kmsg->udh_size; + sinfo->oamp_punt = kmsg->oamp_punted; + sinfo->no_skip_udh_check = kmsg->no_skip_udh_check; + sinfo->system_headers_mode = kmsg->system_headers_mode; + sinfo->udh_enable = kmsg->udh_enable; + } + /* Ensure that we restart properly */ bkn_dma_abort(sinfo); bkn_clean_dcbs(sinfo); @@ -7552,13 +7776,13 @@ bkn_knet_detach(kcom_msg_detach_t *kmsg, int len) } spin_lock_irqsave(&sinfo->lock, flags); - - /* Create dummy event to unblock pending IOCTL */ - sinfo->dma_events |= KCOM_DMA_INFO_F_TX_DONE; - evt = &_bkn_evt[sinfo->evt_idx]; - evt->evt_wq_put++; - wake_up_interruptible(&evt->evt_wq); - + if (sinfo->evt_idx != -1) { + /* Create dummy event to unblock pending IOCTL */ + sinfo->dma_events |= KCOM_DMA_INFO_F_TX_DONE; + evt = &_bkn_evt[sinfo->evt_idx]; + evt->evt_wq_put++; + wake_up_interruptible(&evt->evt_wq); + } spin_unlock_irqrestore(&sinfo->lock, flags); /* Ensure that we return a valid unit number */ @@ -7591,7 +7815,7 @@ bkn_knet_netif_create(kcom_msg_netif_create_t *kmsg, int len) bkn_priv_t *priv, *lpriv; unsigned long flags; int found, id; - uint8 *ma; + uint8_t *ma; kmsg->hdr.type = KCOM_MSG_TYPE_RSP; @@ -7623,26 +7847,26 @@ bkn_knet_netif_create(kcom_msg_netif_create_t *kmsg, int len) priv->sinfo = sinfo; priv->type = kmsg->netif.type; priv->vlan = kmsg->netif.vlan; + /* System headers are prepared at BCM API for Dune headers */ + if (device_is_sand(sinfo)) { + int idx = 0; + for (idx = 0; idx < KCOM_NETIF_SYSTEM_HEADERS_SIZE_MAX; idx++) + { + priv->system_headers[idx] = kmsg->netif.system_headers[idx]; + } + priv->system_headers_size = kmsg->netif.system_headers_size; + } if (priv->type == KCOM_NETIF_T_PORT) { priv->port = kmsg->netif.port; - if (device_is_dpp(sinfo)) { - memcpy(priv->itmh, kmsg->netif.itmh, 4); - } else if (device_is_dnx(sinfo)) { - memcpy(priv->system_headers, kmsg->netif.system_headers, kmsg->netif.system_headers_size); - priv->system_headers_size = kmsg->netif.system_headers_size; - } + priv->phys_port = kmsg->netif.phys_port; priv->qnum = kmsg->netif.qnum; + memset(&(priv->link_settings), 0, sizeof(struct ethtool_link_settings));; } else { - if (device_is_sand(sinfo)) { - if (device_is_dpp(sinfo)) { - priv->port = kmsg->netif.port; - priv->qnum = kmsg->netif.qnum; - }else if (device_is_dnx(sinfo)) { - memcpy(priv->system_headers, kmsg->netif.system_headers, kmsg->netif.system_headers_size); - priv->system_headers_size = kmsg->netif.system_headers_size; - } - } - else { + if (device_is_sand(sinfo) && (priv->type == KCOM_NETIF_T_VLAN)) { + /* PTCH.SSPA */ + priv->port = kmsg->netif.port; + priv->qnum = kmsg->netif.qnum; + } else { priv->port = -1; } } @@ -7705,23 +7929,23 @@ bkn_knet_netif_create(kcom_msg_netif_create_t *kmsg, int len) } } + DBG_VERB(("Assigned ID %d to Ethernet device %s\n", priv->id, dev->name)); kmsg->netif.id = priv->id; memcpy(kmsg->netif.macaddr, dev->dev_addr, 6); memcpy(kmsg->netif.name, dev->name, KCOM_NETIF_NAME_MAX - 1); - if (knet_netif_create_cb != NULL) { int retv = knet_netif_create_cb(kmsg->hdr.unit, &(kmsg->netif), dev); - if (retv) { + if (retv) { gprintk("Warning: knet_netif_create_cb() returned %d for netif '%s'\n", retv, dev->name); } } spin_unlock_irqrestore(&sinfo->lock, flags); - if (device_is_dnx(sinfo)) { + if (device_is_sand(sinfo)) { int idx = 0; for (idx = 0; idx < priv->system_headers_size; idx++) { DBG_DUNE(("System Header[%d]: 0x%02x\n", idx, priv->system_headers[idx])); @@ -7772,6 +7996,7 @@ bkn_knet_netif_destroy(kcom_msg_netif_destroy_t *kmsg, int len) netif.id = priv->id; knet_netif_destroy_cb(kmsg->hdr.unit, &netif, priv->dev); } + list_del(&priv->list); if (priv->id < sinfo->ndev_max) { @@ -7857,6 +8082,7 @@ bkn_knet_netif_get(kcom_msg_netif_get_t *kmsg, int len) kmsg->netif.type = priv->type; kmsg->netif.id = priv->id; kmsg->netif.flags = priv->flags; + kmsg->netif.cb_user_data = priv->cb_user_data; if (priv->port < 0) { kmsg->netif.port = 0; @@ -7918,7 +8144,6 @@ bkn_knet_filter_create(kcom_msg_filter_create_t *kmsg, int len) kmsg->hdr.status = KCOM_E_RESOURCE; return sizeof(kcom_msg_hdr_t); } - filter = kmalloc(sizeof(*filter), GFP_ATOMIC); if (filter == NULL) { spin_unlock_irqrestore(&sinfo->lock, flags); @@ -7927,17 +8152,6 @@ bkn_knet_filter_create(kcom_msg_filter_create_t *kmsg, int len) } memset(filter, 0, sizeof(*filter)); memcpy(&filter->kf, &kmsg->filter, sizeof(filter->kf)); - - if (device_is_dnx(sinfo)) { - /* Information to parser Dune system headers */ - sinfo->ftmh_lb_key_ext_size = kmsg->filter.ftmh_lb_key_ext_size; - sinfo->ftmh_stacking_ext_size = kmsg->filter.ftmh_stacking_ext_size; - sinfo->pph_base_size = kmsg->filter.pph_base_size; - memcpy(sinfo->pph_lif_ext_size, kmsg->filter.pph_lif_ext_size, sizeof(sinfo->pph_lif_ext_size)); - sinfo->udh_enable = kmsg->filter.udh_enable; - memcpy(sinfo->udh_length_type, kmsg->filter.udh_length_type, sizeof(sinfo->udh_length_type)); - } - filter->kf.id = id; /* Add according to priority */ @@ -7960,8 +8174,7 @@ bkn_knet_filter_create(kcom_msg_filter_create_t *kmsg, int len) DBG_VERB(("Created filter ID %d (%s).\n", filter->kf.id, filter->kf.desc)); - - if (device_is_dnx(sinfo)) { + if (device_is_sand(sinfo)) { int idx, wsize; wsize = BYTES2WORDS(filter->kf.oob_data_size + filter->kf.pkt_data_size); DBG_DUNE(("Filter: oob_data_size = %d pkt_data_size=%d wsize %d\n", filter->kf.oob_data_size, filter->kf.pkt_data_size, wsize)); @@ -7974,7 +8187,6 @@ bkn_knet_filter_create(kcom_msg_filter_create_t *kmsg, int len) sinfo->pph_lif_ext_size[1],sinfo->pph_lif_ext_size[2], sinfo->pph_lif_ext_size[3], sinfo->udh_enable, sinfo->udh_length_type[0], sinfo->udh_length_type[1], sinfo->udh_length_type[2], sinfo->udh_length_type[3])); } - return len; } @@ -8055,7 +8267,6 @@ bkn_knet_filter_list(kcom_msg_filter_list_t *kmsg, int len) kmsg->fcnt = idx; spin_unlock_irqrestore(&sinfo->lock, flags); - return sizeof(*kmsg) - sizeof(kmsg->id) + (idx * sizeof(kmsg->id[0])); } @@ -8254,6 +8465,24 @@ bkn_handle_cmd_req(kcom_msg_t *kmsg, int len) /* Clean up for warmbooting */ len = bkn_knet_wb_cleanup(&kmsg->wb_cleanup, len); break; + case KCOM_M_CLOCK_CMD: + /* PHC clock control*/ + if (knet_hw_tstamp_ioctl_cmd_cb) { + bkn_switch_info_t *sinfo; + sinfo = bkn_sinfo_from_unit(kmsg->hdr.unit); + if (sinfo == NULL) { + /* The device is not probed or initialized yet.*/ + return 0; + } + DBG_CMD(("KCOM_M_CLOCK_CMD\n")); + len = knet_hw_tstamp_ioctl_cmd_cb(&kmsg->clock_cmd, len, sinfo->dcb_type); + } else { + DBG_WARN(("Unsupported command (type=%d, opcode=%d)\n", + kmsg->hdr.type, kmsg->hdr.opcode)); + kmsg->hdr.opcode = 0; + len = sizeof(kcom_msg_hdr_t); + } + break; default: DBG_WARN(("Unsupported command (type=%d, opcode=%d)\n", kmsg->hdr.type, kmsg->hdr.opcode)); @@ -8264,39 +8493,6 @@ bkn_handle_cmd_req(kcom_msg_t *kmsg, int len) return len; } -static int -bkn_cmd_thread(void *context) -{ - bkn_thread_ctrl_t *tc = (bkn_thread_ctrl_t *)context; - kcom_msg_t kmsg; - unsigned int len, rlen; - - bkn_thread_boot(tc); - - DBG_VERB(("Command thread starting\n")); - tc->state = 1; - while (!bkn_thread_should_stop(tc)) { - len = sizeof(kmsg); - tc->state = 2; - if (PROXY_RECV(KCOM_CHAN_KNET, &kmsg, &len) >= 0) { - DBG_VERB(("Received %d bytes from KCOM_CHAN_CMD\n", len)); - tc->state = 3; - rlen = bkn_handle_cmd_req(&kmsg, len); - tc->state = 4; - if (rlen > 0) { - PROXY_SEND(KCOM_CHAN_KNET, &kmsg, rlen); - } - } else { - /* Thread interrupted */ - bkn_sleep(1); - } - } - DBG_VERB(("Command thread done\n")); - - bkn_thread_exit(tc); - return 0; -} - static int bkn_get_next_dma_event(kcom_msg_dma_info_t *kmsg) { @@ -8327,8 +8523,8 @@ bkn_get_next_dma_event(kcom_msg_dma_info_t *kmsg) sinfo = bkn_sinfo_from_unit(dev_no); } - if (sinfo && (sinfo->inst_id != 0) && - ((sinfo->inst_id & (1 << dev_evt)) == 0)) { + if (sinfo && (sinfo->inst_id != INVALID_INSTANCE_ID) && + (!lkbde_is_dev_managed_by_instance(dev_evt, sinfo->inst_id))) { DBG_INST((" %s skip dev(%d)\n",__FUNCTION__,dev_no)); continue; } @@ -8370,38 +8566,6 @@ bkn_get_next_dma_event(kcom_msg_dma_info_t *kmsg) return sizeof(*kmsg); } -static int -bkn_evt_thread(void *context) -{ - bkn_thread_ctrl_t *tc = (bkn_thread_ctrl_t *)context; - kcom_msg_dma_info_t kmsg; - int len; - - bkn_thread_boot(tc); - - memset(&kmsg, 0, sizeof(kmsg)); - kmsg.hdr.type = KCOM_MSG_TYPE_EVT; - kmsg.hdr.opcode = KCOM_M_DMA_INFO; - - DBG_VERB(("Event thread starting\n")); - tc->state = 1; - while (!bkn_thread_should_stop(tc)) { - tc->state = 2; - len = bkn_get_next_dma_event(&kmsg); - tc->state = 3; - if (len) { - PROXY_SEND(KCOM_CHAN_KNET, &kmsg, len); - } else { - /* Thread interrupted */ - bkn_sleep(1); - } - } - DBG_VERB(("Event thread done\n")); - - bkn_thread_exit(tc); - return 0; -} - static int _cleanup(void) { @@ -8415,15 +8579,6 @@ _cleanup(void) /* Inidicate that we are shutting down */ module_initialized = 0; - /* Shut down event thread */ - bkn_thread_stop(&bkn_evt_ctrl); - - /* Shut down command thread */ - bkn_thread_stop(&bkn_cmd_ctrl); - - /* Remove KCOM channel */ - PROXY_SERVICE_DESTROY(KCOM_CHAN_KNET); - bkn_proc_cleanup(); remove_proc_entry("bcm/knet", NULL); remove_proc_entry("bcm", NULL); @@ -8435,8 +8590,10 @@ _cleanup(void) del_timer_sync(&sinfo->rxtick); spin_lock_irqsave(&sinfo->lock, flags); - bkn_dma_abort(sinfo); - dev_irq_mask_set(sinfo, 0); + if (DEV_IS_CMIC(sinfo)) { + bkn_dma_abort(sinfo); + dev_irq_mask_set(sinfo, 0); + } spin_unlock_irqrestore(&sinfo->lock, flags); DBG_IRQ(("Unregister ISR.\n")); @@ -8586,7 +8743,6 @@ bkn_knet_dev_init(int d) priv->sinfo = sinfo; priv->vlan = 1; priv->port = -1; - memset(priv->itmh, 0, sizeof(priv->itmh)); priv->id = -1; } @@ -8655,20 +8811,11 @@ _init(void) /* Initialize event queue */ for (idx = 0; idx < LINUX_BDE_MAX_DEVICES; idx++) { memset(&_bkn_evt[idx], 0, sizeof(bkn_evt_resource_t)); + _bkn_evt[idx].inst_id = INVALID_INSTANCE_ID; } evt = &_bkn_evt[0]; init_waitqueue_head(&evt->evt_wq); - if (use_proxy) { - PROXY_SERVICE_CREATE(KCOM_CHAN_KNET, 1, 0); - - DBG_VERB(("Starting command thread\n")); - bkn_thread_start(&bkn_cmd_ctrl, "bkncmd", bkn_cmd_thread); - - DBG_VERB(("Starting event thread\n")); - bkn_thread_start(&bkn_evt_ctrl, "bknevt", bkn_evt_thread); - } - module_initialized = 1; return 0; @@ -8704,7 +8851,7 @@ _ioctl(unsigned int cmd, unsigned long arg) io.len = bkn_handle_cmd_req(&kmsg, io.len); ioctl_cmd--; } else { - memset(&kmsg, 0, sizeof(kcom_msg_dma_info_t)); + memset(&kmsg, 0, sizeof(kcom_msg_t)); /* * Retrive the kmsg.hdr.unit from user space. The dma event queue * selection is based the instance derived from unit. @@ -9018,6 +9165,27 @@ bkn_hw_tstamp_rx_time_upscale_cb_unregister(knet_hw_tstamp_rx_time_upscale_cb_f return 0; } +int +bkn_hw_tstamp_ioctl_cmd_cb_register(knet_hw_tstamp_ioctl_cmd_cb_f hw_tstamp_ioctl_cmd_cb) +{ + if (knet_hw_tstamp_ioctl_cmd_cb != NULL) { + return -1; + } + knet_hw_tstamp_ioctl_cmd_cb = hw_tstamp_ioctl_cmd_cb; + return 0; +} + +int +bkn_hw_tstamp_ioctl_cmd_cb_unregister(knet_hw_tstamp_ioctl_cmd_cb_f hw_tstamp_ioctl_cmd_cb) +{ + if (knet_hw_tstamp_ioctl_cmd_cb == NULL || + knet_hw_tstamp_ioctl_cmd_cb != hw_tstamp_ioctl_cmd_cb) { + return -1; + } + knet_hw_tstamp_ioctl_cmd_cb = NULL; + return 0; +} + LKM_EXPORT_SYM(bkn_rx_skb_cb_register); LKM_EXPORT_SYM(bkn_rx_skb_cb_unregister); LKM_EXPORT_SYM(bkn_tx_skb_cb_register); @@ -9041,3 +9209,5 @@ LKM_EXPORT_SYM(bkn_netif_create_cb_register); LKM_EXPORT_SYM(bkn_netif_create_cb_unregister); LKM_EXPORT_SYM(bkn_netif_destroy_cb_register); LKM_EXPORT_SYM(bkn_netif_destroy_cb_unregister); +LKM_EXPORT_SYM(bkn_hw_tstamp_ioctl_cmd_cb_register); +LKM_EXPORT_SYM(bkn_hw_tstamp_ioctl_cmd_cb_unregister); diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-ptp-clock/Makefile b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-ptp-clock/Makefile new file mode 100644 index 000000000000..9aa3be686851 --- /dev/null +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-ptp-clock/Makefile @@ -0,0 +1,65 @@ +# +# Copyright 2017 Broadcom +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# -*- Makefile -*- +# $Id: Makefile,v 1.3 2012/07/17 07:39:51 mlarsen Exp $ +# $Copyright: (c) 2005 Broadcom Corp. +# All Rights Reserved.$ +# +LOCALDIR = systems/linux/kernel/modules/bcm-ptp-clock + +include ${SDK}/make/Make.config + +LIBS = $(LIBDIR)/libkern.a + +ifeq ($(kernel_version),2_4) +MODULE = $(LIBDIR)/linux-bcm-ptp-clock.o +else +KERNEL_MODULE_DIR = kernel_module + +THIS_MOD_NAME := linux-bcm-ptp-clock +MODULE = $(LIBDIR)/$(THIS_MOD_NAME).o +KMODULE = $(LIBDIR)/$(THIS_MOD_NAME).ko + +build: $(MODULE) $(KMODULE) +endif + +#KBUILD_EXTRA_SYMBOLS := ${BLDDIR}/../../../../bde/linux/kernel/kernel_module/Module.symvers +KBUILD_EXTRA_SYMBOLS += ${BLDDIR}/../bcm-knet/kernel_module/Module.symvers + +# BCM PTP Clock Device + +$(MODULE): $(BLDDIR)/.tree $(BOBJS) $(LIBS) + $(LD) $(MODULE_LDFLAGS) -r -d $(BOBJS) $(LIBS) -o $@ +ifneq ($(kernel_version),2_4) +$(KMODULE): $(MODULE) + rm -fr $(BLDDIR)/$(KERNEL_MODULE_DIR) + mkdir $(BLDDIR)/$(KERNEL_MODULE_DIR) + cp ${SDK}/make/Makefile.linux-kmodule $(BLDDIR)/$(KERNEL_MODULE_DIR)/Makefile + cat ${KBUILD_EXTRA_SYMBOLS} > $(BLDDIR)/$(KERNEL_MODULE_DIR)/Module.symvers + MOD_NAME=$(THIS_MOD_NAME) $(MAKE) -C $(BLDDIR)/$(KERNEL_MODULE_DIR) $(THIS_MOD_NAME).ko +endif + +# Make.depend is before clean:: so that Make.depend's clean:: runs first. + +include ${SDK}/make/Make.depend + +clean:: + $(RM) $(BLDDIR)/version.c $(BLDDIR)/version.o + $(RM) $(BOBJS) $(MODULE) + +ifneq ($(kernel_version),2_4) +.PHONY: build +endif diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-ptp-clock/bcm-ptp-clock.c b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-ptp-clock/bcm-ptp-clock.c new file mode 100644 index 000000000000..edc4a38c741c --- /dev/null +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-ptp-clock/bcm-ptp-clock.c @@ -0,0 +1,2001 @@ +/* + * Copyright 2017 Broadcom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2, as + * published by the Free Software Foundation (the "GPL"). + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 (GPLv2) for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 (GPLv2) along with this source code. + */ + +/* + * This module implements a Linux PTP Clock driver for Broadcom + * XGS switch devices. + * + * For a list of supported module parameters, please see below. + * debug: Debug level (default 0) + * network_transport : Transport Type (default 0 - Raw) + * base_dev_name: Base device name (default ptp0, ptp1, etc.) + * + * - All the data structures and functions work on the physical port. + * For array indexing purposes, we use (phy_port - 1). + */ + +#include /* Must be included first */ +/* Module Information */ +#define MODULE_MAJOR 125 +#define MODULE_NAME "linux-bcm-ptp-clock" + +MODULE_AUTHOR("Broadcom Corporation"); +MODULE_DESCRIPTION("PTP Clock Driver for Broadcom XGS Switch"); +MODULE_LICENSE("GPL"); + +#if LINUX_VERSION_CODE > KERNEL_VERSION(3,17,0) +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* Configuration Parameters */ +static int debug; +LKM_MOD_PARAM(debug, "i", int, 0); +MODULE_PARM_DESC(debug, + "Debug level (default 0)"); + +static int pci_cos; + +static int network_transport; +LKM_MOD_PARAM(network_transport, "i", int, 0); +MODULE_PARM_DESC(network_transport, + "Transport Type (default - Detect from packet)"); + +static char *base_dev_name = "ptp0"; +LKM_MOD_PARAM(base_dev_name, "s", charp, 0); +MODULE_PARM_DESC(base_dev_name, + "Base device name (default ptp0, ptp1, etc.)"); + +static int fw_core; +LKM_MOD_PARAM(fw_core, "i", int, 0); +MODULE_PARM_DESC(fw_core, + "Firmware core (default 0)"); + +/* Debug levels */ +#define DBG_LVL_VERB 0x1 +#define DBG_LVL_WARN 0x2 +#define DBG_LVL_TXTS 0x4 +#define DBG_LVL_CMDS 0x8 + +#define DBG_VERB(_s) do { if (debug & DBG_LVL_VERB) gprintk _s; } while (0) +#define DBG_WARN(_s) do { if (debug & DBG_LVL_WARN) gprintk _s; } while (0) +#define DBG_TXTS(_s) do { if (debug & DBG_LVL_TXTS) gprintk _s; } while (0) +#define DBG_CMDS(_s) do { if (debug & DBG_LVL_CMDS) gprintk _s; } while (0) +#define DBG_ERR(_s) do { if (1) gprintk _s; } while (0) + + +#ifdef LINUX_BDE_DMA_DEVICE_SUPPORT +#define DMA_DEV device +#define DMA_ALLOC_COHERENT(d,s,h) dma_alloc_coherent(d,s,h,GFP_ATOMIC|GFP_DMA32) +#define DMA_FREE_COHERENT(d,s,a,h) dma_free_coherent(d,s,a,h) +#else +#define DMA_DEV pci_dev +#define DMA_ALLOC_COHERENT(d,s,h) pci_alloc_consistent(d,s,h) +#define DMA_FREE_COHERENT(d,s,a,h) pci_free_consistent(d,s,a,h) +#endif + +/* Type length in bytes */ +#define BKSYNC_PACKLEN_U8 1 +#define BKSYNC_PACKLEN_U16 2 +#define BKSYNC_PACKLEN_U24 3 +#define BKSYNC_PACKLEN_U32 4 + +#define BKSYNC_UNPACK_U8(_buf, _var) \ + _var = *_buf++ + +#define BKSYNC_UNPACK_U16(_buf, _var) \ + do { \ + (_var) = (((_buf)[0] << 8) | \ + (_buf)[1]); \ + (_buf) += BKSYNC_PACKLEN_U16; \ + } while (0) + +#define BKSYNC_UNPACK_U24(_buf, _var) \ + do { \ + (_var) = (((_buf)[0] << 16) | \ + ((_buf)[1] << 8) | \ + (_buf)[2]); \ + (_buf) += BKSYNC_PACKLEN_U24; \ + } while (0) + +#define BKSYNC_UNPACK_U32(_buf, _var) \ + do { \ + (_var) = (((_buf)[0] << 24) | \ + ((_buf)[1] << 16) | \ + ((_buf)[2] << 8) | \ + (_buf)[3]); \ + (_buf) += BKSYNC_PACKLEN_U32; \ + } while (0) + + +#define CMICX_DEV_TYPE ((ptp_priv->dcb_type == 38) || \ + (ptp_priv->dcb_type == 36)) + +/* CMIC MCS-0 SCHAN Messaging registers */ +/* Core0:CMC1 Core1:CMC2 */ +#define CMIC_CMC_BASE \ + (CMICX_DEV_TYPE ? (fw_core ? 0x10400 : 0x10300) : \ + (fw_core ? 0x33000 : 0x32000)) + +#define CMIC_CMC_SCHAN_MESSAGE_10r(BASE) (BASE + 0x00000034) +#define CMIC_CMC_SCHAN_MESSAGE_11r(BASE) (BASE + 0x00000038) +#define CMIC_CMC_SCHAN_MESSAGE_12r(BASE) (BASE + 0x0000003c) +#define CMIC_CMC_SCHAN_MESSAGE_13r(BASE) (BASE + 0x00000040) +#define CMIC_CMC_SCHAN_MESSAGE_14r(BASE) (BASE + 0x00000044) +#define CMIC_CMC_SCHAN_MESSAGE_15r(BASE) (BASE + 0x00000048) +#define CMIC_CMC_SCHAN_MESSAGE_16r(BASE) (BASE + 0x0000004c) +#define CMIC_CMC_SCHAN_MESSAGE_17r(BASE) (BASE + 0x00000050) +#define CMIC_CMC_SCHAN_MESSAGE_18r(BASE) (BASE + 0x00000054) +#define CMIC_CMC_SCHAN_MESSAGE_19r(BASE) (BASE + 0x00000058) +#define CMIC_CMC_SCHAN_MESSAGE_20r(BASE) (BASE + 0x0000005c) +#define CMIC_CMC_SCHAN_MESSAGE_21r(BASE) (BASE + 0x00000060) + +u32 hostcmd_regs[5] = { 0 }; + +#define BCMKSYNC_NUM_PORTS 128 /* NUM_PORTS where 2-step is supported. */ +#define BCMKSYNC_MAX_NUM_PORTS 256 /* Max ever NUM_PORTS in the system */ +#define BCMKSYNC_MAX_MTP_IDX 8 /* Max number of mtps in the system */ + +/* Service request commands to Firmware. */ +enum { + BKSYNC_DONE = (0x0), + BKSYNC_INIT = (0x1), + BKSYNC_DEINIT = (0x2), + BKSYNC_GETTIME = (0x3), + BKSYNC_SETTIME = (0x4), + BKSYNC_FREQCOR = (0x5), + BKSYNC_PBM_UPDATE = (0x6), + BKSYNC_ADJTIME = (0x7), + BKSYNC_GET_TSTIME = (0x8), + BKSYNC_MTP_TS_UPDATE_ENABLE = (0x9), + BKSYNC_MTP_TS_UPDATE_DISABLE = (0xa), + BKSYNC_ACK_TSTIME = (0xb), +}; + + +/* 1588 message types. */ +enum +{ + IEEE1588_MSGTYPE_SYNC = (0x0), + IEEE1588_MSGTYPE_DELREQ = (0x1), + IEEE1588_MSGTYPE_PDELREQ = (0x2), + IEEE1588_MSGTYPE_PDELRESP = (0x3), + /* reserved (0x4) */ + /* reserved (0x5) */ + /* reserved (0x6) */ + /* reserved (0x7) */ + IEEE1588_MSGTYPE_GENERALMASK = (0x8), /* all non-event messages have this bit set */ + IEEE1588_MSGTYPE_FLWUP = (0x8), + IEEE1588_MSGTYPE_DELRESP = (0x9), + IEEE1588_MSGTYPE_PDELRES_FLWUP = (0xA), + IEEE1588_MSGTYPE_ANNOUNCE = (0xB), + IEEE1588_MSGTYPE_SGNLNG = (0xC), + IEEE1588_MSGTYPE_MNGMNT = (0xD) + /* reserved (0xE) */ + /* reserved (0xF) */ +}; + +/* Usage macros */ +#define ONE_BILLION (1000000000) + +#define SKB_U16_GET(_skb, _pkt_offset) \ + ((_skb->data[_pkt_offset] << 8) | _skb->data[_pkt_offset + 1]) + +#define BKSYNC_PTP_EVENT_MSG(_ptp_msg_type) \ + ((_ptp_msg_type == IEEE1588_MSGTYPE_DELREQ) || \ + (_ptp_msg_type == IEEE1588_MSGTYPE_SYNC)) + + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) +#define HWTSTAMP_TX_ONESTEP_SYNC 2 +#else +#include +#endif + + +/* + * Hardware specific information. + * 4 words of information used from this data set. + * 0 - 3: 2-step untagged. + * 4 - 7: 2-step tagged. + * 8 - 11: 1-step untagged. + * 12 - 15: 1-step tagged. + * 16 - 19: 1-step untagged with ITS-set. + * 20 - 23: 1-step tagged with ITS-set. + */ +uint32_t sobmhrawpkts_dcb26[24] = {0x00000000, 0x00020E00, 0x00000000, 0x00000000, 0x00000000, 0x00021200, 0x00000000, 0x00000000, + 0x00000000, 0x00100E00, 0x00000000, 0x00000000, 0x00000000, 0x00101200, 0x00000000, 0x00000000, + 0x00000000, 0x00140E00, 0x00000000, 0x00000000, 0x00000000, 0x00141200, 0x00000000, 0x00000000}; + +uint32_t sobmhudpipv4_dcb26[24] = {0x00000000, 0x00022A00, 0x00000000, 0x00000000, 0x00000000, 0x00022E00, 0x00000000, 0x00000000, + 0x00000000, 0x00102A00, 0x00000000, 0x00000000, 0x00000000, 0x00102E00, 0x00000000, 0x00000000, + 0x00000000, 0x00142A00, 0x00000000, 0x00000000, 0x00000000, 0x00142E00, 0x00000000, 0x00000000}; + +uint32_t sobmhudpipv6_dcb26[24] = {0x00000000, 0x00023E00, 0x00000000, 0x00000000, 0x00000000, 0x00024200, 0x00000000, 0x00000000, + 0x00000000, 0x00103E00, 0x00000000, 0x00000000, 0x00000000, 0x00104200, 0x00000000, 0x00000000, + 0x00000000, 0x00143E00, 0x00000000, 0x00000000, 0x00000000, 0x00144200, 0x00000000, 0x00000000}; + +uint32_t sobmhrawpkts_dcb32[24] = {0x00000000, 0x00010E00, 0x00000000, 0x00000000, 0x00000000, 0x00011200, 0x00000000, 0x00000000, + 0x00000000, 0x00080E00, 0x00000000, 0x00000000, 0x00000000, 0x00081200, 0x00000000, 0x00000000, + 0x00000000, 0x00080E00, 0x00000000, 0x00000000, 0x00000000, 0x00081200, 0x00000000, 0x00000000}; + +uint32_t sobmhudpipv4_dcb32[24] = {0x00000000, 0x00012A00, 0x00000000, 0x00000000, 0x00000000, 0x00012E00, 0x00000000, 0x00000000, + 0x00000000, 0x000C2A00, 0x00000000, 0x00000000, 0x00000000, 0x000C2E00, 0x00000000, 0x00000000, + 0x00000000, 0x000C2A00, 0x00000000, 0x00000000, 0x00000000, 0x000C2E00, 0x00000000, 0x00000000}; + +uint32_t sobmhudpipv6_dcb32[24] = {0x00000000, 0x00013E00, 0x00000000, 0x00000000, 0x00000000, 0x00014200, 0x00000000, 0x00000000, + 0x00000000, 0x000C3E00, 0x00000000, 0x00000000, 0x00000000, 0x000C4200, 0x00000000, 0x00000000, + 0x00000000, 0x000C3E00, 0x00000000, 0x00000000, 0x00000000, 0x000C4200, 0x00000000, 0x00000000}; + +uint32_t sobmhrawpkts_dcb35[24] = {0x00000000, 0x0020E000, 0x00000000, 0x00000000, 0x00000000, 0x00212000, 0x00000000, 0x00000000, + 0x00000000, 0x0100E000, 0x00000000, 0x00000000, 0x00000000, 0x01012000, 0x00000000, 0x00000000, + 0x00000000, 0x0140E000, 0x00000000, 0x00000000, 0x00000000, 0x01412000, 0x00000000, 0x00000000}; + +uint32_t sobmhudpipv4_dcb35[24] = {0x00000000, 0x0022A000, 0x00000000, 0x00000000, 0x00000000, 0x0022E000, 0x00000000, 0x00000000, + 0x00000000, 0x0102A000, 0x00000000, 0x00000000, 0x00000000, 0x0102E000, 0x00000000, 0x00000000, + 0x00000000, 0x0142A000, 0x00000000, 0x00000000, 0x00000000, 0x0142E000, 0x00000000, 0x00000000}; + +uint32_t sobmhudpipv6_dcb35[24] = {0x00000000, 0x0023E000, 0x00000000, 0x00000000, 0x00000000, 0x00242000, 0x00000000, 0x00000000, + 0x00000000, 0x0103E000, 0x00000000, 0x00000000, 0x00000000, 0x01042000, 0x00000000, 0x00000000, + 0x00000000, 0x0143E000, 0x00000000, 0x00000000, 0x00000000, 0x01442000, 0x00000000, 0x00000000}; + + +uint32_t sobmhrawpkts_dcb36[24] = {0x00000000, 0x00010E00, 0x00000000, 0x00000000, 0x00000000, 0x00011200, 0x00000000, 0x00000000, + 0x00000000, 0x00080E00, 0x00000000, 0x00000000, 0x00000000, 0x00081200, 0x00000000, 0x00000000, + 0x00000000, 0x00080E00, 0x00000000, 0x00000000, 0x00000000, 0x00081200, 0x00000000, 0x00000000}; + +uint32_t sobmhudpipv4_dcb36[24] = {0x00000000, 0x00012A00, 0x00000000, 0x00000000, 0x00000000, 0x00012E00, 0x00000000, 0x00000000, + 0x00000000, 0x000C2A00, 0x00000000, 0x00000000, 0x00000000, 0x000C2E00, 0x00000000, 0x00000000, + 0x00000000, 0x000C2A00, 0x00000000, 0x00000000, 0x00000000, 0x000C2E00, 0x00000000, 0x00000000}; + +uint32_t sobmhudpipv6_dcb36[24] = {0x00000000, 0x00013E00, 0x00000000, 0x00000000, 0x00000000, 0x00014200, 0x00000000, 0x00000000, + 0x00000000, 0x000C3E00, 0x00000000, 0x00000000, 0x00000000, 0x000C4200, 0x00000000, 0x00000000, + 0x00000000, 0x000C3E00, 0x00000000, 0x00000000, 0x00000000, 0x000C4200, 0x00000000, 0x00000000}; +/* th3: onestep only */ +uint32_t sobmhrawpkts_dcb38[24] = {0x00000000, 0x00080E00, 0x00000000, 0x00000000, 0x00000000, 0x00081200, 0x00000000, 0x00000000, + 0x00000000, 0x00080E00, 0x00000000, 0x00000000, 0x00000000, 0x00081200, 0x00000000, 0x00000000, + 0x00000000, 0x00080E00, 0x00000000, 0x00000000, 0x00000000, 0x00081200, 0x00000000, 0x00000000}; + +uint32_t sobmhudpipv4_dcb38[24] = {0x00000000, 0x00082A00, 0x00000000, 0x00000000, 0x00000000, 0x00082E00, 0x00000000, 0x00000000, + 0x00000000, 0x000C2A00, 0x00000000, 0x00000000, 0x00000000, 0x000C2E00, 0x00000000, 0x00000000, + 0x00000000, 0x000C2A00, 0x00000000, 0x00000000, 0x00000000, 0x000C2E00, 0x00000000, 0x00000000}; + +uint32_t sobmhudpipv6_dcb38[24] = {0x00000000, 0x00083E00, 0x00000000, 0x00000000, 0x00000000, 0x00084200, 0x00000000, 0x00000000, + 0x00000000, 0x000C3E00, 0x00000000, 0x00000000, 0x00000000, 0x000C4200, 0x00000000, 0x00000000, + 0x00000000, 0x000C3E00, 0x00000000, 0x00000000, 0x00000000, 0x000C4200, 0x00000000, 0x00000000}; + +/* Driver Proc Entry root */ +static struct proc_dir_entry *bksync_proc_root = NULL; + +/* Shared data structures with R5 */ +typedef struct _bksync_tx_ts_data_s +{ + u32 ts_valid; /* Timestamp valid indication */ + u32 port_id; /* Port number */ + u32 ts_seq_id; /* Sequency Id */ + u32 ts_cnt; + u64 timestamp; /* Timestamp */ +} bksync_tx_ts_data_t; + +typedef struct _bksync_uc_linux_ipc_s +{ + u32 ksyncinit; + u32 dev_id; + s64 freqcorr; + u64 portmap[BCMKSYNC_NUM_PORTS/64]; /* Two-step enabled ports */ + u64 ptptime; + u64 reftime; + s64 phase_offset; + bksync_tx_ts_data_t port_ts_data[BCMKSYNC_NUM_PORTS]; +} bksync_uc_linux_ipc_t; + +typedef struct bksync_port_stats_s { + u32 pkt_rxctr; /* All ingress packets */ + u32 pkt_txctr; /* All egress packets */ + u32 pkt_txonestep; /* 1-step Tx packet counter */ + u32 tsts_match; /* 2-Step tstamp req match */ + u32 tsts_timeout; /* 2-Step tstamp req timeouts */ + u32 tsts_discard; /* 2-Step tstamp req discards */ + u32 osts_event_pkts; /* 1-step event packet counter */ + u32 osts_tstamp_reqs; /* 1-step events with tstamp request */ + u32 fifo_rxctr; /* 2-Step tstamp req match */ + u64 tsts_best_fetch_time; /* 1-step events with tstamp request */ + u64 tsts_worst_fetch_time; /* 1-step events with tstamp request */ + u32 tsts_avg_fetch_time; /* 1-step events with tstamp request */ +} bksync_port_stats_t; + +/* Clock Private Data */ +struct bksync_ptp_priv { + struct device dev; + int dcb_type; + struct ptp_clock *ptp_clock; + struct ptp_clock_info ptp_caps; + struct mutex ptp_lock; + struct mutex ptp_pair_lock; + volatile void *base_addr; /* address for PCI register access */ + volatile bksync_uc_linux_ipc_t *shared_addr; /* address for shared memory access */ + uint64_t dma_mem; + int dma_mem_size; + struct DMA_DEV *dma_dev; /* Required for DMA memory control */ + int num_pports; + int timekeep_status; + u32 mirror_encap_bmp; + struct delayed_work time_keep; + bksync_port_stats_t *port_stats; +}; + +static struct bksync_ptp_priv *ptp_priv; +volatile bksync_uc_linux_ipc_t *linuxPTPMemory = (bksync_uc_linux_ipc_t*)(0); +static volatile int module_initialized; +static int num_retries = 10; /* Retry count */ + +static void bksync_ptp_time_keep_init(void); +static void bksync_ptp_time_keep_deinit(void); + +#if defined(CMIC_SOFT_BYTE_SWAP) + +#define CMIC_SWAP32(_x) ((((_x) & 0xff000000) >> 24) \ + | (((_x) & 0x00ff0000) >> 8) \ + | (((_x) & 0x0000ff00) << 8) \ + | (((_x) & 0x000000ff) << 24)) + +#define DEV_READ32(_d, _a, _p) \ + do { \ + uint32_t _data; \ + _data = (((volatile uint32_t *)(_d)->base_addr)[(_a)/4]); \ + *(_p) = CMIC_SWAP32(_data); \ + } while(0) + +#define DEV_WRITE32(_d, _a, _v) \ + do { \ + uint32_t _data = CMIC_SWAP32(_v); \ + ((volatile uint32_t *)(_d)->base_addr)[(_a)/4] = (_data); \ + } while(0) + +#else + +#define DEV_READ32(_d, _a, _p) \ + do { \ + *(_p) = (((volatile uint32_t *)(_d)->base_addr)[(_a)/4]); \ + } while(0) + +#define DEV_WRITE32(_d, _a, _v) \ + do { \ + ((volatile uint32_t *)(_d)->base_addr)[(_a)/4] = (_v); \ + } while(0) +#endif /* defined(CMIC_SOFT_BYTE_SWAP) */ + +static void +ptp_usleep(int usec) +{ + usleep_range(usec,usec+1); +} + +static void +ptp_sleep(int jiffies) +{ + wait_queue_head_t wq; + init_waitqueue_head(&wq); + + wait_event_timeout(wq, 0, jiffies); + +} + + +static void bksync_hostcmd_data_op(int setget, u64 *d1, u64 *d2) +{ + u32 w0, w1; + u64 data; + + if (!d1) { + return; + } + + if (setget) { + data = *d1; + w0 = (data & 0xFFFFFFFF); + w1 = (data >> 32); + DEV_WRITE32(ptp_priv, hostcmd_regs[1], w0); + DEV_WRITE32(ptp_priv, hostcmd_regs[2], w1); + } else { + DEV_READ32(ptp_priv, hostcmd_regs[1], &w0); + DEV_READ32(ptp_priv, hostcmd_regs[2], &w1); + data = (((u64)w1 << 32) | (w0)); + *d1 = data; + + if (d2) { + DEV_READ32(ptp_priv, hostcmd_regs[3], &w0); + DEV_READ32(ptp_priv, hostcmd_regs[4], &w1); + data = (((u64)w1 << 32) | (w0)); + *d2 = data; + } + } +} + + +static int bksync_cmd_go(u32 cmd, void *data0, void *data1) +{ + int ret = -1; + int retry_cnt = (1000); /* 1ms default timeout for hostcmd response */ + u32 cmd_status; + char cmd_str[20]; + int port; + uint32_t seq_id; + ktime_t start, now; + + if (ptp_priv == NULL || ptp_priv->shared_addr == NULL) { + return ret; + } + + mutex_lock(&ptp_priv->ptp_lock); + + if (cmd == BKSYNC_GET_TSTIME || cmd == BKSYNC_ACK_TSTIME) { + port = *((uint64_t *)data0) & 0xFFF; + seq_id = *((uint64_t*)data0) >> 16; + } + start = ktime_get(); + + ptp_priv->shared_addr->ksyncinit = cmd; + + /* init data */ + DEV_WRITE32(ptp_priv, hostcmd_regs[1], 0x0); + DEV_WRITE32(ptp_priv, hostcmd_regs[2], 0x0); + DEV_WRITE32(ptp_priv, hostcmd_regs[3], 0x0); + DEV_WRITE32(ptp_priv, hostcmd_regs[4], 0x0); + + switch (cmd) { + case BKSYNC_INIT: + sprintf(cmd_str, "KSYNC_INIT"); + ptp_priv->shared_addr->phase_offset = 0; + bksync_hostcmd_data_op(1, (u64 *)&(ptp_priv->shared_addr->phase_offset), 0); + break; + case BKSYNC_FREQCOR: + sprintf(cmd_str, "KSYNC_FREQCORR"); + ptp_priv->shared_addr->freqcorr = *((s32 *)data0); + bksync_hostcmd_data_op(1, (u64 *)&(ptp_priv->shared_addr->freqcorr), 0); + break; + case BKSYNC_ADJTIME: + sprintf(cmd_str, "KSYNC_ADJTIME"); + ptp_priv->shared_addr->phase_offset = *((s64 *)data0); + bksync_hostcmd_data_op(1, (u64 *)&(ptp_priv->shared_addr->phase_offset), 0); + break; + case BKSYNC_GETTIME: + retry_cnt = (retry_cnt * 2); + sprintf(cmd_str, "KSYNC_GETTIME"); + break; + case BKSYNC_GET_TSTIME: + retry_cnt = (retry_cnt * 2); + sprintf(cmd_str, "KSYNC_GET_TSTIME"); + bksync_hostcmd_data_op(1, data0, data1); + break; + case BKSYNC_ACK_TSTIME: + retry_cnt = (retry_cnt * 2); + sprintf(cmd_str, "KSYNC_ACK_TSTIME"); + bksync_hostcmd_data_op(1, data0, data1); + break; + case BKSYNC_SETTIME: + sprintf(cmd_str, "KSYNC_SETTIME"); + ptp_priv->shared_addr->ptptime = *((s64 *)data0); + ptp_priv->shared_addr->phase_offset = 0; + bksync_hostcmd_data_op(1, (u64 *)&(ptp_priv->shared_addr->ptptime), (u64 *)&(ptp_priv->shared_addr->phase_offset)); + break; + case BKSYNC_MTP_TS_UPDATE_ENABLE: + retry_cnt = (retry_cnt * 6); + sprintf(cmd_str, "KSYNC_MTP_TS_UPDATE_ENABLE"); + bksync_hostcmd_data_op(1, (u64 *)data0, 0); + break; + case BKSYNC_MTP_TS_UPDATE_DISABLE: + retry_cnt = (retry_cnt * 6); + sprintf(cmd_str, "KSYNC_MTP_TS_UPDATE_DISABLE"); + bksync_hostcmd_data_op(1, (u64 *)data0, 0); + break; + case BKSYNC_DEINIT: + retry_cnt = (retry_cnt * 4); + sprintf(cmd_str, "KSYNC_DEINIT"); + break; + default: + sprintf(cmd_str, "KSYNC_XXX"); + break; + } + DEV_WRITE32(ptp_priv, hostcmd_regs[0], ptp_priv->shared_addr->ksyncinit); + + do { + DEV_READ32(ptp_priv, hostcmd_regs[0], &cmd_status); + ptp_priv->shared_addr->ksyncinit = cmd_status; + + if (cmd_status == BKSYNC_DONE) { + ret = 0; + switch (cmd) { + case BKSYNC_GET_TSTIME: + case BKSYNC_GETTIME: + bksync_hostcmd_data_op(0, (u64 *)data0, (u64 *)data1); + break; + default: + break; + } + break; + } + ptp_usleep(100); + retry_cnt--; + } while (retry_cnt); + + now = ktime_get(); + mutex_unlock(&ptp_priv->ptp_lock); + + if (retry_cnt == 0) { + DBG_ERR(("Timeout on response from R5 to cmd %s time taken %lld us\n", cmd_str, ktime_us_delta(now, start))); + if (cmd == BKSYNC_GET_TSTIME) { + DBG_TXTS(("Timeout Port %d SeqId %d\n", port, seq_id)); + } + } + if (debug & DBG_LVL_CMDS) { + if (ktime_us_delta(now, start) > 5000) + DBG_CMDS(("R5 Command %s exceeded time expected (%lld us)\n", cmd_str, ktime_us_delta(now, start))); + } + + + return ret; +} + + +/** + * bksync_ptp_adjfreq + * + * @ptp: pointer to ptp_clock_info structure + * @ppb: frequency correction value + * + * Description: this function will set the frequency correction + */ +static int bksync_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb) +{ + int ret = -1; + u32 cmd_status = BKSYNC_FREQCOR; + + ret = bksync_cmd_go(cmd_status, &ppb, NULL); + DBG_VERB(("applying freq correction: %x\n", ppb)); + + return ret; +} + +/** + * bksync_ptp_adjtime + * + * @ptp: pointer to ptp_clock_info structure + * @delta: desired change in nanoseconds + * + * Description: this function will shift/adjust the hardware clock time. + */ +static int bksync_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) +{ + u32 cmd_status = BKSYNC_ADJTIME; + int ret = -1; + + ret = bksync_cmd_go(cmd_status, (void *)&delta, NULL); + DBG_VERB(("ptp adjtime: 0x%llx \n", delta)); + + return ret; +} + +/** + * bksync_ptp_gettime + * + * @ptp: pointer to ptp_clock_info structure + * @ts: pointer to hold time/result + * + * Description: this function will read the current time from the + * hardware clock and store it in @ts. + */ +static int bksync_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts) +{ + int ret = -1; + u32 cmd_status = BKSYNC_GETTIME; + s64 reftime = 0; + s64 refctr = 0; + + ret = bksync_cmd_go(cmd_status, (void *)&reftime, (void *)&refctr); + if (ret == 0) { + DBG_VERB(("ptp gettime: 0x%llx refctr:0x%llx\n", reftime, refctr)); + mutex_lock(&ptp_priv->ptp_pair_lock); + ptp_priv->shared_addr->ptptime = reftime; + ptp_priv->shared_addr->reftime = refctr; + mutex_unlock(&ptp_priv->ptp_pair_lock); + + *ts = ns_to_timespec64(reftime); + } + return ret; +} + + +/** + * bksync_ptp_settime + * + * @ptp: pointer to ptp_clock_info structure + * @ts: time value to set + * + * Description: this function will set the current time on the + * hardware clock. + */ +static int bksync_ptp_settime(struct ptp_clock_info *ptp, + const struct timespec64 *ts) +{ + s64 reftime, phaseadj; + int ret = -1; + u32 cmd_status = BKSYNC_SETTIME; + + phaseadj = 0; + reftime = timespec64_to_ns(ts); + + ret = bksync_cmd_go(cmd_status, (void *)&reftime, (void *)&phaseadj); + DBG_VERB(("ptp settime: 0x%llx \n", reftime)); + + return ret; +} + +static int bksync_ptp_enable(struct ptp_clock_info *ptp, + struct ptp_clock_request *rq, int on) +{ + return 0; +} + + +static int bksync_ptp_mirror_encap_update(struct ptp_clock_info *ptp, + int mtp_idx, int start) +{ + int ret = -1; + u64 mirror_encap_idx; + u32 cmd_status; + + if (mtp_idx > BCMKSYNC_MAX_MTP_IDX) { + return ret; + } + + mirror_encap_idx = mtp_idx; + if (start) { + cmd_status = BKSYNC_MTP_TS_UPDATE_ENABLE; + ptp_priv->mirror_encap_bmp |= (1 << mtp_idx); + } else { + if (!(ptp_priv->mirror_encap_bmp & mtp_idx)) { + /* Not running */ + return ret; + } + cmd_status = BKSYNC_MTP_TS_UPDATE_DISABLE; + ptp_priv->mirror_encap_bmp &= ~mtp_idx; + } + + ret = bksync_cmd_go(cmd_status, &mirror_encap_idx, NULL); + DBG_VERB(("ptp mmirror_encap_update: %d, mpt_index: %d, ret:%d \n", start, mtp_idx, ret)); + + return ret; + +} + +/* structure describing a PTP hardware clock */ +static struct ptp_clock_info bksync_ptp_caps = { + .owner = THIS_MODULE, + .name = "bksync_ptp_clock", + .max_adj = 200000, + .n_alarm = 0, + .n_ext_ts = 0, + .n_per_out = 0, /* will be overwritten in bksync_ptp_register */ + .n_pins = 0, + .pps = 0, + .adjfreq = bksync_ptp_adjfreq, + .adjtime = bksync_ptp_adjtime, + .gettime64 = bksync_ptp_gettime, + .settime64 = bksync_ptp_settime, + .enable = bksync_ptp_enable, +}; + +/** + * bksync_ptp_hw_tstamp_enable + * + * @dev_no: device number + * @port: port number + * + * Description: this is a callback function to enable the timestamping on + * a given port + */ +int bksync_ptp_hw_tstamp_enable(int dev_no, int port, int tx_type) +{ + uint64_t portmap = 0; + int map = 0; + int ret = 0; + + if (!module_initialized) { + ret = -1; + goto exit; + } + + if (tx_type == HWTSTAMP_TX_ONESTEP_SYNC) { + bksync_ptp_time_keep_init(); + goto exit; + } + + DBG_VERB(("Enable timestamp on a given port:%d\n", port)); + if (port <= 0) { + DBG_ERR(("Error enabling timestamp on port:%d\n", port)); + ret = -1; + goto exit; + } + + port -= 1; + map = port/64; port = port%64; + + /* Update the shared structure member */ + if (ptp_priv->shared_addr) { + portmap = ptp_priv->shared_addr->portmap[map]; + portmap |= (uint64_t)0x1 << port; + ptp_priv->shared_addr->portmap[map] = portmap; + /* Command to R5 for the update */ + ptp_priv->shared_addr->ksyncinit=BKSYNC_PBM_UPDATE; + } + +exit: + return ret; +} + +/** + * bksync_ptp_hw_tstamp_disable + * + * @dev_no: device number + * @port: port number + * + * Description: this is a callback function to disable the timestamping on + * a given port + */ +int bksync_ptp_hw_tstamp_disable(int dev_no, int port, int tx_type) +{ + uint64_t portmap = 0; + int map = 0; + int ret = 0; + + if (!module_initialized) { + ret = -1; + goto exit; + } + + if (tx_type == HWTSTAMP_TX_ONESTEP_SYNC) { + goto exit; + } + + DBG_VERB(("Disable timestamp on a given port:%d\n", port)); + if (port <= 0) { + DBG_ERR(("Error disabling timestamp on port:%d\n", port)); + ret = -1; + goto exit; + } + + port -= 1; + map = port/64; port = port%64; + + /* Update the shared structure member */ + if (ptp_priv->shared_addr) { + portmap = ptp_priv->shared_addr->portmap[map]; + portmap &= ~((uint64_t)0x1 << port); + ptp_priv->shared_addr->portmap[map]= portmap; + + /* Command to R5 for the update */ + ptp_priv->shared_addr->ksyncinit = BKSYNC_PBM_UPDATE; + } +exit: + return ret; +} + +int bksync_ptp_transport_get(uint8_t *pkt) +{ + int transport = 0; + uint16_t ethertype; + uint16_t tpid; + int tpid_offset, ethype_offset; + + /* Need to check VLAN tag if packet is tagged */ + tpid_offset = 12; + tpid = pkt[tpid_offset] << 8 | pkt[tpid_offset + 1]; + if (tpid == 0x8100) { + ethype_offset = tpid_offset + 4; + } else { + ethype_offset = tpid_offset; + } + + ethertype = pkt[ethype_offset] << 8 | pkt[ethype_offset+1]; + + switch (ethertype) { + case 0x88f7: /* ETHERTYPE_PTPV2 */ + transport = 2; + break; + + case 0x0800: /* ETHERTYPE_IPV4 */ + transport = 4; + break; + + case 0x86DD: /* ETHERTYPE_IPV6 */ + transport = 6; + break; + + default: + transport = 0; + } + + return transport; +} + +static int +bksync_txpkt_tsts_tsamp_get(int port, uint32_t pkt_seq_id, uint32_t *ts_valid, uint32_t *seq_id, uint64_t *timestamp) +{ + int ret = 0; + uint64_t tmp; + u32 fifo_rxctr = 0; + + tmp = (port & 0xFFFF) | (pkt_seq_id << 16); + + ret = bksync_cmd_go(BKSYNC_GET_TSTIME, &tmp, timestamp); + + if (ret >= 0) { + fifo_rxctr = (tmp >> 32) & 0xFFFF; + *seq_id = ((tmp >> 16) & 0xFFFF); + *ts_valid = (tmp & 0x1); + if (*ts_valid) { + tmp = (port & 0xFFFF) | (pkt_seq_id << 16); + bksync_cmd_go(BKSYNC_ACK_TSTIME, &tmp, 0); + if (fifo_rxctr != 0) { + if (fifo_rxctr != ptp_priv->port_stats[port].fifo_rxctr + 1) { + DBG_ERR(("FW Reset or Lost Timestamp RxSeq:(Prev %d : Current %d)\n", ptp_priv->port_stats[port].fifo_rxctr, fifo_rxctr)); + } + ptp_priv->port_stats[port].fifo_rxctr = fifo_rxctr; + } + } + } + + + return ret; +} + + +/** + * bksync_ptp_hw_tstamp_tx_time_get + * + * @dev_no: device number + * @port: port number + * @pkt: packet address + * @ts: timestamp to be retrieved + * + * Description: this is a callback function to retrieve the timestamp on + * a given port + */ +int bksync_ptp_hw_tstamp_tx_time_get(int dev_no, int port, uint8_t *pkt, uint64_t *ts) +{ + /* Get Timestamp from R5 or CLMAC */ + uint32_t ts_valid = 0; + uint32_t seq_id = 0; + uint32_t pktseq_id = 0; + uint64_t timestamp = 0; + uint16_t tpid = 0; + ktime_t start; + u64 delta; + int retry_cnt = num_retries; + int seq_id_offset, tpid_offset; + int transport = network_transport; + start = ktime_get(); + + if (!ptp_priv || !pkt || !ts || port < 1 || port > 255 || ptp_priv->shared_addr == NULL) { + return -1; + } + + *ts = 0; + + tpid_offset = 12; + + /* Parse for nw transport */ + if (transport == 0) { + transport = bksync_ptp_transport_get(pkt); + } + + switch(transport) + { + case 2: + seq_id_offset = 0x2c; + break; + case 4: + seq_id_offset = 0x48; + break; + case 6: + seq_id_offset = 0x5c; + break; + default: + seq_id_offset = 0x2c; + break; + } + + /* Need to check VLAN tag if packet is tagged */ + tpid = pkt[tpid_offset] << 8 | pkt[tpid_offset + 1]; + if (tpid == 0x8100) { + seq_id_offset += 4; + } + + + pktseq_id = pkt[seq_id_offset] << 8 | pkt[seq_id_offset + 1]; + + port -= 1; + + /* Fetch the TX timestamp from shadow memory */ + do { + bksync_txpkt_tsts_tsamp_get(port, pktseq_id, &ts_valid, &seq_id, ×tamp); + if (ts_valid) { + + /* Clear the shadow memory to get next entry */ + ptp_priv->shared_addr->port_ts_data[port].timestamp = 0; + ptp_priv->shared_addr->port_ts_data[port].port_id = 0; + ptp_priv->shared_addr->port_ts_data[port].ts_seq_id = 0; + ptp_priv->shared_addr->port_ts_data[port].ts_valid = 0; + + if (seq_id == pktseq_id) { + *ts = timestamp; + ptp_priv->port_stats[port].tsts_match += 1; + + delta = ktime_us_delta(ktime_get(), start); + DBG_VERB(("Port: %d Skb_SeqID %d FW_SeqId %d and TS:%llx FetchTime %lld\n", + port, pktseq_id, seq_id, timestamp, delta)); + + if (delta < ptp_priv->port_stats[port].tsts_best_fetch_time || ptp_priv->port_stats[port].tsts_best_fetch_time == 0) { + ptp_priv->port_stats[port].tsts_best_fetch_time = delta; + } + if (delta > ptp_priv->port_stats[port].tsts_worst_fetch_time || ptp_priv->port_stats[port].tsts_worst_fetch_time == 0) { + ptp_priv->port_stats[port].tsts_worst_fetch_time = delta; + } + /* Calculate Moving Average*/ + ptp_priv->port_stats[port].tsts_avg_fetch_time = ((u32)delta + ((ptp_priv->port_stats[port].tsts_match - 1) * ptp_priv->port_stats[port].tsts_avg_fetch_time)) / ptp_priv->port_stats[port].tsts_match; + break; + } else { + DBG_TXTS(("Discard timestamp on port %d Skb_SeqID %d FW_SeqId %d RetryCnt %d TimeLapsed (%lld us)\n", + port, pktseq_id, seq_id, (num_retries - retry_cnt), ktime_us_delta(ktime_get(),start))); + + ptp_priv->port_stats[port].tsts_discard += 1; + continue; + } + } + ptp_sleep(1); + retry_cnt--; + } while(retry_cnt); + + + ptp_priv->port_stats[port].pkt_txctr += 1; + + if (retry_cnt == 0) { + ptp_priv->port_stats[port].tsts_timeout += 1; + DBG_ERR(("FW Response timeout: Tx TS on phy port:%d Skb_SeqID: %d TimeLapsed (%lld us)\n", + port, pktseq_id, ktime_us_delta(ktime_get(), start))); + } + + + return 0; +} + + +enum { + bxconCustomEncapVersionInvalid = 0, + bxconCustomEncapVersionOne = 1, + + bxconCustomEncapVersionCurrent = bxconCustomEncapVersionOne, + bxconCustomEncapVersionReserved = 255 /* last */ +} bxconCustomEncapVersion; + +enum { + bxconCustomEncapOpcodeInvalid = 0, + bxconCustomEncapOpcodePtpRx = 1, + bxconCustomEncapOpcodeReserved = 255 /* last */ +} bxconCustomEncapOpcode; + +enum { + bxconCustomEncapPtpRxTlvInvalid = 0, + bxconCustomEncapPtpRxTlvPtpRxTime = 1, + bxconCustomEncapPtpRxTlvReserved = 255 /* last */ +} bxconCustomEncapPtpRxTlvType; + +void +bksync_dump_pkt(uint8_t *data, int size) +{ + int idx; + char str[128]; + + for (idx = 0; idx < size; idx++) { + if ((idx & 0xf) == 0) { + sprintf(str, "%04x: ", idx); + } + sprintf(&str[strlen(str)], "%02x ", data[idx]); + if ((idx & 0xf) == 0xf) { + sprintf(&str[strlen(str)], "\n"); + gprintk(str); + } + } + if ((idx & 0xf) != 0) { + sprintf(&str[strlen(str)], "\n"); + gprintk(str); + } +} + + +static inline int +bksync_pkt_custom_encap_ptprx_get(uint8_t *pkt, uint64_t *ing_ptptime) +{ + uint8_t *custom_hdr; + uint8_t id[4]; + uint8_t ver, opc; + uint8_t nh_type, nh_rsvd; + uint16_t len, tot_len; + uint16_t nh_len; + uint32_t seq_id = 0; + uint32_t ptp_rx_time[2]; + uint64_t u64_ptp_rx_time = 0; + + custom_hdr = pkt; + + BKSYNC_UNPACK_U8(custom_hdr, id[0]); + BKSYNC_UNPACK_U8(custom_hdr, id[1]); + BKSYNC_UNPACK_U8(custom_hdr, id[2]); + BKSYNC_UNPACK_U8(custom_hdr, id[3]); + if (!((id[0] == 'B') && (id[1] == 'C') && (id[2] == 'M') && (id[3] == 'C'))) { + /* invalid signature */ + return -1; + } + + BKSYNC_UNPACK_U8(custom_hdr, ver); + switch (ver) { + case bxconCustomEncapVersionCurrent: + break; + default: + gprintk("invalid ver\n"); + return -1; + } + + BKSYNC_UNPACK_U8(custom_hdr, opc); + switch (opc) { + case bxconCustomEncapOpcodePtpRx: + break; + default: + gprintk("invalid opcode\n"); + return -1; + } + + + BKSYNC_UNPACK_U16(custom_hdr, len); + BKSYNC_UNPACK_U32(custom_hdr, seq_id); + tot_len = len; + + /* remaining length of custom encap */ + len = len - (custom_hdr - pkt); + + + /* process tlv */ + while (len > 0) { + BKSYNC_UNPACK_U8(custom_hdr, nh_type); + BKSYNC_UNPACK_U8(custom_hdr, nh_rsvd); + BKSYNC_UNPACK_U16(custom_hdr, nh_len); + len = len - (nh_len); + if (nh_rsvd != 0x0) { + continue; /* invalid tlv */ + } + + switch (nh_type) { + case bxconCustomEncapPtpRxTlvPtpRxTime: + BKSYNC_UNPACK_U32(custom_hdr, ptp_rx_time[0]); + BKSYNC_UNPACK_U32(custom_hdr, ptp_rx_time[1]); + u64_ptp_rx_time = ((uint64_t)ptp_rx_time[1] << 32) | (uint64_t)ptp_rx_time[0]; + *ing_ptptime = u64_ptp_rx_time; + break; + default: + custom_hdr += nh_len; + break; + } + } + +#if 0 +if (!(seq_id % 100)) { + gprintk("****** seq_id = %d ptp time = 0x%llx\n", seq_id, u64_ptp_rx_time); + bksync_dump_pkt(pkt, tot_len); +} +#endif + + DBG_VERB(("Custom encap header: ver=%d opcode=%d seq_id=0x%x\n", ver, opc, seq_id)); + + return (tot_len); +} + + + +/** + * bksync_ptp_hw_tstamp_rx_time_upscale + * + * @dev_no: device number + * @ts: timestamp to be retrieved + * + * Description: this is a callback function to retrieve 64b equivalent of + * rx timestamp + */ +int bksync_ptp_hw_tstamp_rx_time_upscale(int dev_no, int port, struct sk_buff *skb, uint32_t *meta, uint64_t *ts) +{ + int ret = 0; + int custom_encap_len = 0; + + switch (KNET_SKB_CB(skb)->dcb_type) { + case 26: + case 32: + case 35: + if (pci_cos != (meta[4] & 0x3F)) { + return -1; + } + break; + case 38: + if (pci_cos != ((meta[12] >> 22) & 0x2F)) { + return -1; + } + break; + case 36: + if (pci_cos != ((meta[6] >> 22) & 0x2F)) { + return -1; + } + break; + default: + return -1; + } + + /* parse custom encap header in pkt for ptp rxtime */ + custom_encap_len = bksync_pkt_custom_encap_ptprx_get((skb->data), ts); + + /* Remove the custom encap header from pkt */ + if (custom_encap_len > 0) { + skb_pull(skb, custom_encap_len); + + DBG_VERB(("###### ptp message type: %d\n", skb->data[42])); + } + + if (port > 0){ + port -= 1; + ptp_priv->port_stats[port].pkt_rxctr += 1; + } + + return ret; +} + + +void bksync_hton64(u8 *buf, const uint64_t *data) +{ +#ifdef __LITTLE_ENDIAN + /* LITTLE ENDIAN */ + buf[0] = (*(((uint8_t*)(data)) + 7u)); + buf[1] = (*(((uint8_t*)(data)) + 6u)); + buf[2] = (*(((uint8_t*)(data)) + 5u)); + buf[3] = (*(((uint8_t*)(data)) + 4u)); + buf[4] = (*(((uint8_t*)(data)) + 3u)); + buf[5] = (*(((uint8_t*)(data)) + 2u)); + buf[6] = (*(((uint8_t*)(data)) + 1u)); + buf[7] = (*(((uint8_t*)(data)) + 0u)); +#else + memcpy(buf, data, 8); +#endif +} + + + +int bksync_ptp_hw_tstamp_tx_meta_get(int dev_no, + int hwts, int hdrlen, + struct sk_buff *skb, + uint64_t *tstamp, + u32 **md) +{ + uint16_t tpid = 0; + int md_offset = 0; + int pkt_offset = 0; + int ptp_hdr_offset = 0; + int transport = network_transport; + s64 ptptime = 0; + s64 ptpcounter = 0; + int64_t corrField; + int32_t negCurTS32; + int64_t negCurTS64; + + if(!ptp_priv || ptp_priv->shared_addr == NULL) { + return 0; + } + + mutex_lock(&ptp_priv->ptp_pair_lock); + ptptime = ptp_priv->shared_addr->ptptime; + ptpcounter = ptp_priv->shared_addr->reftime; + mutex_unlock(&ptp_priv->ptp_pair_lock); + + negCurTS32 = - (int32_t) ptpcounter; + negCurTS64 = - (int64_t)(ptpcounter); + + if (CMICX_DEV_TYPE) { + pkt_offset = ptp_hdr_offset = hdrlen; + } + + /* Need to check VLAN tag if packet is tagged */ + tpid = SKB_U16_GET(skb, (pkt_offset + 12)); + if (tpid == 0x8100) { + md_offset = 4; + ptp_hdr_offset += 4; + } + + /* One Step Meta Data */ + if (hwts == HWTSTAMP_TX_ONESTEP_SYNC) { + md_offset += 8; + if (KNET_SKB_CB(skb)->dcb_type == 26) { + corrField = (((int64_t)negCurTS32) << 16); + if (negCurTS32 >= 0) { + md_offset += 8; + } + } else { + corrField = (((int64_t)negCurTS64) << 16); + } + } + + + /* Parse for nw transport */ + if (transport == 0) { + transport = bksync_ptp_transport_get(skb->data + pkt_offset); + } + + switch(transport) + { + case 2: /* IEEE 802.3 */ + ptp_hdr_offset += 14; + if (KNET_SKB_CB(skb)->dcb_type == 32) { + if (md) *md = &sobmhrawpkts_dcb32[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 26) { + if (md) *md = &sobmhrawpkts_dcb26[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 35) { + if (md) *md = &sobmhrawpkts_dcb35[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 36) { + if (md) *md = &sobmhrawpkts_dcb36[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 38) { + if (md) *md = &sobmhrawpkts_dcb38[md_offset]; + } + break; + case 4: /* UDP IPv4 */ + ptp_hdr_offset += 42; + if (KNET_SKB_CB(skb)->dcb_type == 32) { + if (md) *md = &sobmhudpipv4_dcb32[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 26) { + if (md) *md = &sobmhudpipv4_dcb26[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 35) { + if (md) *md = &sobmhudpipv4_dcb35[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 36) { + if (md) *md = &sobmhudpipv4_dcb36[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 38) { + if (md) *md = &sobmhudpipv4_dcb38[md_offset]; + } + break; + case 6: /* UDP IPv6 */ + ptp_hdr_offset += 62; + if (KNET_SKB_CB(skb)->dcb_type == 32) { + if (md) *md = &sobmhudpipv6_dcb32[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 26) { + if (md) *md = &sobmhudpipv6_dcb26[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 35) { + if (md) *md = &sobmhudpipv6_dcb35[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 36) { + if (md) *md = &sobmhudpipv6_dcb36[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 38) { + if (md) *md = &sobmhudpipv6_dcb38[md_offset]; + } + break; + default: + ptp_hdr_offset += 42; + if (KNET_SKB_CB(skb)->dcb_type == 32) { + if (md) *md = &sobmhudpipv4_dcb32[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 26) { + if (md) *md = &sobmhudpipv4_dcb26[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 35) { + if (md) *md = &sobmhudpipv4_dcb35[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 36) { + if (md) *md = &sobmhudpipv4_dcb36[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 38) { + if (md) *md = &sobmhudpipv4_dcb38[md_offset]; + } + break; + } + + + if ((hwts == HWTSTAMP_TX_ONESTEP_SYNC) && + BKSYNC_PTP_EVENT_MSG(skb->data[ptp_hdr_offset])) { + /* One Step Timestamp Field updation */ + int corr_offset = ptp_hdr_offset + 8; + int origin_ts_offset = ptp_hdr_offset + 34; + u32 tmp; + struct timespec64 ts; + int udp_csum_regen; + u32 udp_csum20; + u16 udp_csum; + int port; + + udp_csum = SKB_U16_GET(skb, (ptp_hdr_offset - 2)); + + switch (transport) { + case 2: + udp_csum_regen = 0; + break; + case 6: + udp_csum_regen = 1; + break; + default: + udp_csum_regen = (udp_csum != 0x0); + break; + } + + /* Fill the correction field */ + bksync_hton64(&(skb->data[corr_offset]), (const u64 *)&corrField); + + /* Fill the Origin Timestamp Field */ + ts = ns_to_timespec64(ptptime); + + tmp = (ts.tv_sec >> 32); + skb->data[origin_ts_offset + 0] = ((tmp >> 8) & 0xFF); + skb->data[origin_ts_offset + 1] = ((tmp ) & 0xFF); + + tmp = (ts.tv_sec & 0xFFFFFFFFLL); + skb->data[origin_ts_offset + 2] = ((tmp >> 24) & 0xFF); + skb->data[origin_ts_offset + 3] = ((tmp >> 16) & 0xFF); + skb->data[origin_ts_offset + 4] = ((tmp >> 8) & 0xFF); + skb->data[origin_ts_offset + 5] = ((tmp ) & 0xFF); + + tmp = (ts.tv_nsec & 0xFFFFFFFFLL); + skb->data[origin_ts_offset + 6] = ((tmp >> 24) & 0xFF); + skb->data[origin_ts_offset + 7] = ((tmp >> 16) & 0xFF); + skb->data[origin_ts_offset + 8] = ((tmp >> 8) & 0xFF); + skb->data[origin_ts_offset + 9] = ((tmp ) & 0xFF); + + if (udp_csum_regen) { + udp_csum20 = (~udp_csum) & 0xFFFF; + + udp_csum20 += SKB_U16_GET(skb, (corr_offset + 0)); + udp_csum20 += SKB_U16_GET(skb, (corr_offset + 2)); + udp_csum20 += SKB_U16_GET(skb, (corr_offset + 4)); + udp_csum20 += SKB_U16_GET(skb, (corr_offset + 6)); + + udp_csum20 += SKB_U16_GET(skb, (origin_ts_offset + 0)); + udp_csum20 += SKB_U16_GET(skb, (origin_ts_offset + 2)); + udp_csum20 += SKB_U16_GET(skb, (origin_ts_offset + 4)); + udp_csum20 += SKB_U16_GET(skb, (origin_ts_offset + 6)); + udp_csum20 += SKB_U16_GET(skb, (origin_ts_offset + 8)); + + /* Fold 20bit checksum into 16bit udp checksum */ + udp_csum20 = ((udp_csum20 & 0xFFFF) + (udp_csum20 >> 16)); + udp_csum = ((udp_csum20 & 0xFFFF) + (udp_csum20 >> 16)); + + /* invert again to get final checksum. */ + udp_csum = ~udp_csum; + if (udp_csum == 0) { + udp_csum = 0xFFFF; + } + + skb->data[ptp_hdr_offset - 2] = ((udp_csum >> 8) & 0xFF); + skb->data[ptp_hdr_offset - 1] = ((udp_csum ) & 0xFF); + } + + if (skb->data[ptp_hdr_offset] == IEEE1588_MSGTYPE_DELREQ) { + *tstamp = ptptime; + + DBG_VERB(("ptp delay req packet tstamp : 0x%llx corrField: 0x%llx\n", ptptime, corrField)); + } + + port = KNET_SKB_CB(skb)->port; + port -= 1; + ptp_priv->port_stats[port].pkt_txonestep += 1; + } + + return 0; +} + + +int bksync_ptp_hw_tstamp_ptp_clock_index_get(int dev_no) +{ + int phc_index = -1; + if (ptp_priv && ptp_priv->ptp_clock) + phc_index = ptp_clock_index(ptp_priv->ptp_clock); + return phc_index; +} + + +/** +* bcm_ptp_time_keep - call timecounter_read every second to avoid timer overrun +* because a 32bit counter, will timeout in 4s +*/ +static void bksync_ptp_time_keep(struct work_struct *work) +{ + struct delayed_work *dwork = to_delayed_work(work); + struct bksync_ptp_priv *priv = + container_of(dwork, struct bksync_ptp_priv, time_keep); + struct timespec64 ts; + + /* Call bcm_ptp_gettime function to keep the ref_time_64 and ref_counter_48 in sync */ + bksync_ptp_gettime(&(priv->ptp_caps), &ts); + schedule_delayed_work(&priv->time_keep, HZ); +} + +static void bksync_ptp_time_keep_init(void) +{ + if (!ptp_priv->timekeep_status) { + INIT_DELAYED_WORK(&(ptp_priv->time_keep), bksync_ptp_time_keep); + schedule_delayed_work(&ptp_priv->time_keep, HZ); + + ptp_priv->timekeep_status = 1; + } + + return; +} + +static void bksync_ptp_time_keep_deinit(void) +{ + if (ptp_priv->timekeep_status) { + /* Cancel delayed work */ + cancel_delayed_work_sync(&(ptp_priv->time_keep)); + + ptp_priv->timekeep_status = 0; + } + + return; +} + + + +static int bksync_ptp_init(struct ptp_clock_info *ptp) +{ + return bksync_cmd_go(BKSYNC_INIT, NULL, NULL); +} + +static int bksync_ptp_deinit(struct ptp_clock_info *ptp) +{ + bksync_ptp_time_keep_deinit(); + + return bksync_cmd_go(BKSYNC_DEINIT, NULL, NULL); +} + +/* + * Device Debug Statistics Proc Entry + */ +/** +* This function is called at the beginning of a sequence. +* ie, when: +* - the /proc/bcm/ksync/stats file is read (first time) +* - after the function stop (end of sequence) +* +*/ +static void *bksync_proc_seq_start(struct seq_file *s, loff_t *pos) +{ + /* beginning a new sequence ? */ + if ( (int)*pos == 0 && ptp_priv->shared_addr != NULL) + { + seq_printf(s, "TwoStep Port Bitmap : %08llx%08llx\n", + (uint64_t)(ptp_priv->shared_addr->portmap[1]), + (uint64_t)(ptp_priv->shared_addr->portmap[0])); + seq_printf(s,"%4s| %9s| %9s| %9s| %9s| %9s| %9s| %9s| %9s| %9s| %9s| %9s\n", + "Port", "RxCounter", "TxCounter", "TxOneStep", "TSTimeout", "TSRead", "TSMatch", "TSDiscard", + "TimeHi" , "TimeLo", "TimeAvg", "FIFORx"); + } + + if ((int)*pos < (ptp_priv->num_pports)) + return (void *)(unsigned long)(*pos + 1); + /* End of the sequence, return NULL */ + return NULL; +} + +/** +* This function is called after the beginning of a sequence. +* It's called untill the return is NULL (this ends the sequence). +* +*/ +static void *bksync_proc_seq_next(struct seq_file *s, void *v, loff_t *pos) +{ + (*pos)++; + return bksync_proc_seq_start(s, pos); +} +/** +* This function is called at the end of a sequence +* +*/ +static void bksync_proc_seq_stop(struct seq_file *s, void *v) +{ + /* nothing to do, we use a static value in bksync_proc_seq_start() */ +} + +/** +* This function is called for each "step" of a sequence +* +*/ +static int bksync_proc_seq_show(struct seq_file *s, void *v) +{ + unsigned long port = (unsigned long)v; + port = port - 1; + if (ptp_priv->port_stats[port].pkt_rxctr || ptp_priv->port_stats[port].pkt_txctr || + ptp_priv->port_stats[port].pkt_txonestep|| + ptp_priv->port_stats[port].tsts_discard || ptp_priv->port_stats[port].tsts_timeout || + ptp_priv->shared_addr->port_ts_data[port].ts_cnt || ptp_priv->port_stats[port].tsts_match) { + seq_printf(s, "%4lu | %9d| %9d| %9d| %9d| %9d| %9d| %9d| %9lld| %9lld | %9d|%9d | %s\n", (port + 1), + ptp_priv->port_stats[port].pkt_rxctr, + ptp_priv->port_stats[port].pkt_txctr, + ptp_priv->port_stats[port].pkt_txonestep, + ptp_priv->port_stats[port].tsts_timeout, + ptp_priv->shared_addr->port_ts_data[port].ts_cnt, + ptp_priv->port_stats[port].tsts_match, + ptp_priv->port_stats[port].tsts_discard, + ptp_priv->port_stats[port].tsts_worst_fetch_time, + ptp_priv->port_stats[port].tsts_best_fetch_time, + ptp_priv->port_stats[port].tsts_avg_fetch_time, + ptp_priv->port_stats[port].fifo_rxctr, + ptp_priv->port_stats[port].pkt_txctr != ptp_priv->port_stats[port].tsts_match ? "***":""); + } + return 0; +} + +/** +* seq_operations for bsync_proc_*** entries +* +*/ +static struct seq_operations bksync_proc_seq_ops = { + .start = bksync_proc_seq_start, + .next = bksync_proc_seq_next, + .stop = bksync_proc_seq_stop, + .show = bksync_proc_seq_show +}; +static int bksync_proc_txts_open(struct inode * inode, struct file * file) +{ + return seq_open(file, &bksync_proc_seq_ops); +} + +static ssize_t +bksync_proc_txts_write(struct file *file, const char *buf, + size_t count, loff_t *loff) +{ + char debug_str[40]; + char *ptr; + int port; + + if (copy_from_user(debug_str, buf, count)) { + return -EFAULT; + } + + if ((ptr = strstr(debug_str, "clear")) != NULL) { + for (port = 0; port < ptp_priv->num_pports; port++) { + ptp_priv->port_stats[port].pkt_rxctr = 0; + ptp_priv->port_stats[port].pkt_txctr = 0; + ptp_priv->port_stats[port].pkt_txonestep = 0; + ptp_priv->port_stats[port].tsts_timeout = 0; + ptp_priv->port_stats[port].tsts_match = 0; + ptp_priv->port_stats[port].tsts_discard = 0; + if (ptp_priv->shared_addr) + ptp_priv->shared_addr->port_ts_data[port].ts_cnt = 0; + } + } else { + gprintk("Warning: unknown input\n"); + } + + return count; +} + +struct file_operations bksync_proc_txts_file_ops = { + owner: THIS_MODULE, + open: bksync_proc_txts_open, + read: seq_read, + llseek: seq_lseek, + write: bksync_proc_txts_write, + release: seq_release, +}; + +/* + * Driver Debug Proc Entry + */ +static int +bksync_proc_debug_show(struct seq_file *m, void *v) +{ + seq_printf(m, "Configuration:\n"); + seq_printf(m, " debug: 0x%x\n", debug); + return 0; +} + +static ssize_t +bksync_proc_debug_write(struct file *file, const char *buf, + size_t count, loff_t *loff) +{ + char debug_str[40]; + char *ptr; + + if (copy_from_user(debug_str, buf, count)) { + return -EFAULT; + } + + if ((ptr = strstr(debug_str, "debug=")) != NULL) { + ptr += 6; + debug = simple_strtol(ptr, NULL, 0); + } else { + gprintk("Warning: unknown configuration\n"); + } + + return count; +} + +static int bksync_proc_debug_open(struct inode * inode, struct file * file) +{ + return single_open(file, bksync_proc_debug_show, NULL); +} + + +struct file_operations bksync_proc_debug_file_ops = { + owner: THIS_MODULE, + open: bksync_proc_debug_open, + read: seq_read, + llseek: seq_lseek, + write: bksync_proc_debug_write, + release: single_release, +}; + + +static int +bksync_proc_init(void) +{ + struct proc_dir_entry *entry; + + PROC_CREATE(entry, "stats", 0666, bksync_proc_root, &bksync_proc_txts_file_ops); + if (entry == NULL) { + return -1; + } + PROC_CREATE(entry, "debug", 0666, bksync_proc_root, &bksync_proc_debug_file_ops); + if (entry == NULL) { + return -1; + } + return 0; +} + +static int +bksync_proc_cleanup(void) +{ + remove_proc_entry("stats", bksync_proc_root); + remove_proc_entry("debug", bksync_proc_root); + return 0; +} + +static void bksync_ptp_dma_init(int dcb_type) +{ + int endianess; + int num_pports = 256; + + + ptp_priv->num_pports = num_pports; + ptp_priv->dcb_type = dcb_type; + ptp_priv->dma_mem_size = 16384;/*sizeof(bksync_uc_linux_ipc_t);*/ + + if (ptp_priv->shared_addr == NULL) { + ptp_priv->shared_addr = kzalloc(16384, GFP_KERNEL); + ptp_priv->port_stats = kzalloc((sizeof(bksync_port_stats_t) * num_pports), GFP_KERNEL); + } + + if (ptp_priv->shared_addr != NULL) { + /* Reset memory. */ + memset((void *)ptp_priv->shared_addr, 0, ptp_priv->dma_mem_size); + +#ifdef __LITTLE_ENDIAN + endianess = 0; +#else + endianess = 1; +#endif + DEV_WRITE32(ptp_priv, CMIC_CMC_SCHAN_MESSAGE_14r(CMIC_CMC_BASE), ((pci_cos << 16) | endianess)); + + DEV_WRITE32(ptp_priv, CMIC_CMC_SCHAN_MESSAGE_15r(CMIC_CMC_BASE), 1); + DEV_WRITE32(ptp_priv, CMIC_CMC_SCHAN_MESSAGE_16r(CMIC_CMC_BASE), 1); + + } + + if (debug & DBG_LVL_VERB) { + printk(KERN_EMERG"%s %p:%p\n",__FUNCTION__, + ptp_priv->base_addr,(void *)ptp_priv->shared_addr); + } + + ptp_priv->mirror_encap_bmp = 0x0; + + hostcmd_regs[0] = CMIC_CMC_SCHAN_MESSAGE_21r(CMIC_CMC_BASE); + hostcmd_regs[1] = CMIC_CMC_SCHAN_MESSAGE_20r(CMIC_CMC_BASE); + hostcmd_regs[2] = CMIC_CMC_SCHAN_MESSAGE_19r(CMIC_CMC_BASE); + hostcmd_regs[3] = CMIC_CMC_SCHAN_MESSAGE_18r(CMIC_CMC_BASE); + hostcmd_regs[4] = CMIC_CMC_SCHAN_MESSAGE_17r(CMIC_CMC_BASE); + + return; +} + + +/** + * bksync_ioctl_cmd_handler + * @kmsg: kcom message - ptp clock ioctl command. + * Description: This function will handle ioctl commands + * from user mode. + */ +static int +bksync_ioctl_cmd_handler(kcom_msg_clock_cmd_t *kmsg, int len, int dcb_type) +{ + u32 fw_status; + kmsg->hdr.type = KCOM_MSG_TYPE_RSP; + + if (!module_initialized && kmsg->clock_info.cmd != KSYNC_M_HW_INIT) { + kmsg->hdr.status = KCOM_E_NOT_FOUND; + return sizeof(kcom_msg_hdr_t); + } + + switch(kmsg->clock_info.cmd) { + case KSYNC_M_HW_INIT: + pci_cos = kmsg->clock_info.data[0]; + if (kmsg->clock_info.data[1] == 0 || kmsg->clock_info.data[1] == 1) { + fw_core = kmsg->clock_info.data[1]; + DEV_READ32(ptp_priv, CMIC_CMC_SCHAN_MESSAGE_21r(CMIC_CMC_BASE), &fw_status); + + /* Return success if the app is already initialized. */ + if (module_initialized) { + kmsg->hdr.status = KCOM_E_NONE; + return sizeof(kcom_msg_hdr_t); + } + + /* Return error if the app is not ready yet. */ + if (fw_status != 0xBADC0DE1) { + kmsg->hdr.status = KCOM_E_RESOURCE; + return sizeof(kcom_msg_hdr_t); + } + + bksync_ptp_dma_init(dcb_type); + if (bksync_ptp_init(&(ptp_priv->ptp_caps)) >= 0) { + module_initialized = 1; + } + } + break; + case KSYNC_M_HW_DEINIT: + bksync_ptp_deinit(&(ptp_priv->ptp_caps)); + module_initialized = 0; + break; + case KSYNC_M_HW_TS_DISABLE: + bksync_ptp_hw_tstamp_disable(0, kmsg->clock_info.data[0], 0); + break; + case KSYNC_M_MTP_TS_UPDATE_ENABLE: + bksync_ptp_mirror_encap_update(0, kmsg->clock_info.data[0], TRUE); + break; + case KSYNC_M_MTP_TS_UPDATE_DISABLE: + bksync_ptp_mirror_encap_update(0, kmsg->clock_info.data[0], FALSE); + break; + case KSYNC_M_VERSION: + break; + default: + kmsg->hdr.status = KCOM_E_NOT_FOUND; + return sizeof(kcom_msg_hdr_t); + } + + return sizeof(*kmsg); +} + + + +/** + * bksync_ptp_register + * @priv: driver private structure + * Description: this function will register the ptp clock driver + * to kernel. It also does some house keeping work. + */ +static int bksync_ptp_register(void) +{ + int err = -ENODEV; + + /* Support on core-0 or core-1 */ + if (fw_core < 0 || fw_core > 1) { + goto exit; + } + + /* default transport is raw, ieee 802.3 */ + switch (network_transport) { + case 2: /* IEEE 802.3 */ + case 4: /* UDP IPv4 */ + case 6: /* UDP IPv6 */ + break; + default: + network_transport = 0; + } + + ptp_priv = kzalloc(sizeof(*ptp_priv), GFP_KERNEL); + if (!ptp_priv) { + err = -ENOMEM; + goto exit; + } + + /* Reset memory */ + memset(ptp_priv, 0, sizeof(*ptp_priv)); + + err = -ENODEV; + + ptp_priv->ptp_caps = bksync_ptp_caps; + + mutex_init(&(ptp_priv->ptp_lock)); + mutex_init(&(ptp_priv->ptp_pair_lock)); + + /* Register ptp clock driver with bksync_ptp_caps */ + ptp_priv->ptp_clock = ptp_clock_register(&ptp_priv->ptp_caps, NULL); + + /* Initialize the Base address for CMIC and shared Memory access */ + ptp_priv->base_addr = lkbde_get_dev_virt(0); + ptp_priv->dma_dev = lkbde_get_dma_dev(0); + + if (IS_ERR(ptp_priv->ptp_clock)) { + ptp_priv->ptp_clock = NULL; + } else if (ptp_priv->ptp_clock) { + err = 0; + + /* Register BCM-KNET HW Timestamp Callback Functions */ + bkn_hw_tstamp_enable_cb_register(bksync_ptp_hw_tstamp_enable); + bkn_hw_tstamp_disable_cb_register(bksync_ptp_hw_tstamp_disable); + bkn_hw_tstamp_tx_time_get_cb_register(bksync_ptp_hw_tstamp_tx_time_get); + bkn_hw_tstamp_tx_meta_get_cb_register(bksync_ptp_hw_tstamp_tx_meta_get); + bkn_hw_tstamp_rx_time_upscale_cb_register(bksync_ptp_hw_tstamp_rx_time_upscale); + bkn_hw_tstamp_ptp_clock_index_cb_register(bksync_ptp_hw_tstamp_ptp_clock_index_get); + bkn_hw_tstamp_ioctl_cmd_cb_register(bksync_ioctl_cmd_handler); + + } + + /* Initialize proc files */ + bksync_proc_root = proc_mkdir("bcm/ksync", NULL); + bksync_proc_init(); + ptp_priv->shared_addr = NULL; + ptp_priv->port_stats = NULL; +exit: + return err; +} + +static int bksync_ptp_remove(void) +{ + if (!ptp_priv) + return 0; + + bksync_ptp_time_keep_deinit(); + + bksync_proc_cleanup(); + remove_proc_entry("bcm/ksync", NULL); + + /* UnRegister BCM-KNET HW Timestamp Callback Functions */ + bkn_hw_tstamp_enable_cb_unregister(bksync_ptp_hw_tstamp_enable); + bkn_hw_tstamp_disable_cb_unregister(bksync_ptp_hw_tstamp_disable); + bkn_hw_tstamp_tx_time_get_cb_unregister(bksync_ptp_hw_tstamp_tx_time_get); + bkn_hw_tstamp_tx_meta_get_cb_unregister(bksync_ptp_hw_tstamp_tx_meta_get); + bkn_hw_tstamp_rx_time_upscale_cb_unregister(bksync_ptp_hw_tstamp_rx_time_upscale); + bkn_hw_tstamp_ptp_clock_index_cb_unregister(bksync_ptp_hw_tstamp_ptp_clock_index_get); + bkn_hw_tstamp_ioctl_cmd_cb_unregister(bksync_ioctl_cmd_handler); + + if (module_initialized) { + DEV_WRITE32(ptp_priv, CMIC_CMC_SCHAN_MESSAGE_15r(CMIC_CMC_BASE), 0); + DEV_WRITE32(ptp_priv, CMIC_CMC_SCHAN_MESSAGE_16r(CMIC_CMC_BASE), 0); + } + /* Deinitialize the PTP */ + bksync_ptp_deinit(&(ptp_priv->ptp_caps)); + module_initialized = 0; + + if (ptp_priv->port_stats != NULL) { + kfree((void *)ptp_priv->port_stats); + ptp_priv->port_stats = NULL; + } + if (ptp_priv->shared_addr != NULL) { + kfree((void *)ptp_priv->shared_addr); + ptp_priv->shared_addr = NULL; + DBG_ERR(("Free R5 memory\n")); + } + + /* Unregister the bcm ptp clock driver */ + ptp_clock_unregister(ptp_priv->ptp_clock); + + /* Free Memory */ + kfree(ptp_priv); + + return 0; +} +#endif + + +/* + * Generic module functions + */ + +/* + * Function: _pprint + * + * Purpose: + * Print proc filesystem information. + * Parameters: + * None + * Returns: + * Always 0 + */ + static int +_pprint(struct seq_file *m) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(3,17,0) + /* put some goodies here */ + pprintf(m, "Broadcom BCM PTP Hardware Clock Module\n"); +#else + pprintf(m, "Broadcom BCM PTP Hardware Clock Module not supported\n"); +#endif + return 0; +} + +/* + * Function: _init + * + * Purpose: + * Module initialization. + * Attached SOC all devices and optionally initializes these. + * Parameters: + * None + * Returns: + * 0 on success, otherwise -1 + */ + static int +_init(void) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(3,17,0) + bksync_ptp_register(); + return 0; +#else + return -1; +#endif +} + +/* + * Function: _cleanup + * + * Purpose: + * Module cleanup function + * Parameters: + * None + * Returns: + * Always 0 + */ + static int +_cleanup(void) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(3,17,0) + mutex_destroy(&(ptp_priv->ptp_lock)); + mutex_destroy(&(ptp_priv->ptp_pair_lock)); + bksync_ptp_remove(); + return 0; +#else + return -1; +#endif +} + +static gmodule_t _gmodule = { +name: MODULE_NAME, + major: MODULE_MAJOR, + init: _init, + cleanup: _cleanup, + pprint: _pprint, + ioctl: NULL, + open: NULL, + close: NULL, +}; + + gmodule_t* +gmodule_get(void) +{ + EXPORT_NO_SYMBOLS; + return &_gmodule; +} diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/bcm-knet.h b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/bcm-knet.h index 477c037a0c43..8d710869824f 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/bcm-knet.h +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/bcm-knet.h @@ -1,5 +1,10 @@ /* - * Copyright 2017 Broadcom + * Copyright 2007-2020 Broadcom Inc. All rights reserved. + * + * Permission is granted to use, copy, modify and/or distribute this + * software under either one of the licenses below. + * + * License Option 1: GPL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. + * + * + * License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license + * + * This software is governed by the Broadcom Open Network Switch APIs license: + * https://www.broadcom.com/products/ethernet-connectivity/software/opennsa */ /* * $Id: bcm-knet.h,v 1.4 Broadcom SDK $ @@ -47,6 +58,8 @@ typedef struct { uint32 filter_user_data; uint16 dcb_type; int port; + uint64_t ts; + uint32 hwts; } knet_skb_cb_t; #define KNET_SKB_CB(_skb) ((knet_skb_cb_t *)_skb->cb) @@ -59,19 +72,22 @@ typedef int int chan, kcom_filter_t *filter); typedef int -(*knet_hw_tstamp_enable_cb_f)(int dev_no, int port); +(*knet_hw_tstamp_enable_cb_f)(int dev_no, int phys_port, int tx_type); typedef int -(*knet_hw_tstamp_tx_time_get_cb_f)(int dev_no, int port, uint8_t *pkt, uint64_t *ts); +(*knet_hw_tstamp_tx_time_get_cb_f)(int dev_no, int phys_port, uint8_t *pkt, uint64_t *ts); typedef int -(*knet_hw_tstamp_tx_meta_get_cb_f)(int dev_no, struct sk_buff *skb, uint32_t **md); +(*knet_hw_tstamp_tx_meta_get_cb_f)(int dev_no, int hwts, int hdrlen, struct sk_buff *skb, uint64_t *ts, uint32_t **md); typedef int (*knet_hw_tstamp_ptp_clock_index_cb_f)(int dev_no); typedef int -(*knet_hw_tstamp_rx_time_upscale_cb_f)(int dev_no, uint64_t *ts); +(*knet_hw_tstamp_rx_time_upscale_cb_f)(int dev_no, int phys_port, struct sk_buff *skb, uint32_t *meta, uint64_t *ts); + +typedef int +(*knet_hw_tstamp_ioctl_cmd_cb_f)(kcom_msg_clock_cmd_t *kmsg, int len, int dcb_type); extern int bkn_rx_skb_cb_register(knet_skb_cb_f rx_cb); @@ -127,6 +143,11 @@ bkn_hw_tstamp_rx_time_upscale_cb_register(knet_hw_tstamp_rx_time_upscale_cb_f hw extern int bkn_hw_tstamp_rx_time_upscale_cb_unregister(knet_hw_tstamp_rx_time_upscale_cb_f hw_tstamp_rx_time_upscale_cb); +extern int +bkn_hw_tstamp_ioctl_cmd_cb_register(knet_hw_tstamp_ioctl_cmd_cb_f hw_tstamp_ioctl_cmd_cb); + +extern int +bkn_hw_tstamp_ioctl_cmd_cb_unregister(knet_hw_tstamp_ioctl_cmd_cb_f hw_tstamp_ioctl_cmd_cb); typedef struct { uint8 cmic_type; uint8 dcb_type; @@ -153,6 +174,6 @@ bkn_netif_destroy_cb_register(knet_netif_cb_f netif_cb); extern int bkn_netif_destroy_cb_unregister(knet_netif_cb_f netif_cb); -#endif /* __KERNEL__ */ +#endif #endif /* __LINUX_BCM_KNET_H__ */ diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/gmodule.h b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/gmodule.h index 22cef82a8ddc..a9db097f3062 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/gmodule.h +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/gmodule.h @@ -1,5 +1,10 @@ /* - * Copyright 2017 Broadcom + * Copyright 2007-2020 Broadcom Inc. All rights reserved. + * + * Permission is granted to use, copy, modify and/or distribute this + * software under either one of the licenses below. + * + * License Option 1: GPL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. + * + * + * License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license + * + * This software is governed by the Broadcom Open Network Switch APIs license: + * https://www.broadcom.com/products/ethernet-connectivity/software/opennsa */ /* * $Id: gmodule.h,v 1.9 Broadcom SDK $ @@ -23,6 +34,7 @@ #define __COMMON_LINUX_KRN_GMODULE_H__ #include +#include typedef struct gmodule_s { @@ -32,9 +44,7 @@ typedef struct gmodule_s { int (*init)(void); int (*cleanup)(void); - - int (*pprint)(void); - + int (*pprint)(struct seq_file *m); int (*open)(void); int (*ioctl)(unsigned int cmd, unsigned long arg); int (*close)(void); @@ -48,8 +58,8 @@ extern gmodule_t* gmodule_get(void); /* Proc Filesystem information */ -extern int pprintf(const char* fmt, ...) - __attribute__ ((format (printf, 1, 2))); +extern int pprintf(struct seq_file *m, const char* fmt, ...) + __attribute__ ((format (printf, 2, 3))); extern int gmodule_vpprintf(char** page, const char* fmt, va_list args) __attribute__ ((format (printf, 2, 0))); extern int gmodule_pprintf(char** page, const char* fmt, ...) diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/lkm.h b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/lkm.h index a48cb540adaf..9ea8fc5896d8 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/lkm.h +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/lkm.h @@ -1,5 +1,10 @@ /* - * Copyright 2017 Broadcom + * Copyright 2007-2020 Broadcom Inc. All rights reserved. + * + * Permission is granted to use, copy, modify and/or distribute this + * software under either one of the licenses below. + * + * License Option 1: GPL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. + * + * + * License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license + * + * This software is governed by the Broadcom Open Network Switch APIs license: + * https://www.broadcom.com/products/ethernet-connectivity/software/opennsa */ /* * $Id: lkm.h,v 1.22 Broadcom SDK $ @@ -34,10 +45,16 @@ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) #include #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) +/* The version kconfig.h became available in. */ #include #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) +#if defined(INCLUDE_KNET) && LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0) +#ifdef CONFIG_NF_CONNTRACK_MODULE +#include +#endif +#endif #include #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39) diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/Makefile b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/Makefile index 2a167bb9e811..b8697731dd4e 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/Makefile +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/Makefile @@ -1,5 +1,10 @@ # -# Copyright 2017 Broadcom +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ # # You should have received a copy of the GNU General Public License # version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa # # -*- Makefile -*- # $Id: Makefile,v 1.3 Broadcom SDK $ @@ -36,6 +47,7 @@ KMODULE = $(LIBDIR)/$(THIS_MOD_NAME).ko build: $(MODULE) $(KMODULE) endif +KBUILD_EXTRA_SYMBOLS := ${BLDDIR}/../bcm-knet/kernel_module/Module.symvers ifeq ($(BUILD_PSAMPLE),1) KBUILD_EXTRA_SYMBOLS += ${BLDDIR}/../psample/kernel_module/Module.symvers endif diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/knet-cb.c b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/knet-cb.c index 89d1087212c7..650a4ced1d7a 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/knet-cb.c +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/knet-cb.c @@ -1,15 +1,15 @@ /* * Copyright 2017-2019 Broadcom - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as * published by the Free Software Foundation (the "GPL"). - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 (GPLv2) for more details. - * + * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. */ @@ -59,6 +59,26 @@ LKM_MOD_PARAM(debug, "i", int, 0); MODULE_PARM_DESC(debug, "Debug level (default 0)"); +static int tpid=0x8100; +LKM_MOD_PARAM(tpid, "i", int, 0); +MODULE_PARM_DESC(debug, +"Tag Protocol Identifier (TPID) indicates the frame type (default 0x8100)"); + +static int pri=0; +LKM_MOD_PARAM(pri, "i", int, 0); +MODULE_PARM_DESC(pri, +"Priority (PRI) indicates the frame priority (default 0)"); + +static int cfi=0; +LKM_MOD_PARAM(cfi, "i", int, 0); +MODULE_PARM_DESC(cfi, +"Canonical Format Indicator (CFI) indicates whether a MAC address is encapsulated in canonical format over different transmission media (default 0)"); + +static int vid=0; +LKM_MOD_PARAM(vid, "i", int, 0); +MODULE_PARM_DESC(vid, +"VLAN ID (VID) indicates the VLAN to which a frame belongs (default 0)"); + /* Module Information */ #define MODULE_MAJOR 121 #define MODULE_NAME "linux-knet-cb" @@ -67,8 +87,8 @@ MODULE_PARM_DESC(debug, #define KNET_CB_DEBUG /* These below need to match incoming enum values */ -#define FILTER_TAG_STRIP 0 -#define FILTER_TAG_KEEP 1 +#define FILTER_TAG_STRIP 0 +#define FILTER_TAG_KEEP 1 #define FILTER_TAG_ORIGINAL 2 /* Maintain tag strip statistics */ @@ -87,7 +107,7 @@ static struct sk_buff *strip_tag_rx_cb(struct sk_buff *skb, int dev_no, void *me static struct sk_buff *strip_tag_tx_cb(struct sk_buff *skb, int dev_no, void *meta); static int strip_tag_filter_cb(uint8_t * pkt, int size, int dev_no, void *meta, int chan, kcom_filter_t * kf); -static int _pprint(void); +static int _pprint(struct seq_file *m); static int _cleanup(void); static int _init(void); @@ -105,6 +125,31 @@ strip_vlan_tag(struct sk_buff *skb) } } +/* Add VLAN tag to untagged packet */ +static void +add_vlan_tag(struct sk_buff *skb, u32 forward_domain) +{ + u32 vlan = 0; + uint16_t vlan_proto = (uint16_t) ((skb->data[12] << 8) | skb->data[13]); + + if ((vlan_proto != 0x8100) && (vlan_proto != 0x88a8) && (vlan_proto != 0x9100)) { + /* If vid is specified, use configued vid as VLAN ID, or, use forward_domain as vid */ + vlan = vid ? vid: forward_domain; + + skb_push(skb, 4); /* Add 4 bytes from start of buffer */ + /* Move first 12 bytes of packet forward by 4 */ + ((u32 *) skb->data)[0] = ((u32 *) skb->data)[1]; + ((u32 *) skb->data)[1] = ((u32 *) skb->data)[2]; + ((u32 *) skb->data)[2] = ((u32 *) skb->data)[3]; + + /* Set VLAN tag */ + skb->data[12] = (tpid >> 8) & 0xff; + skb->data[13] = tpid & 0xff; + skb->data[14] = (((pri & 0x7) << 5) | ((cfi & 0x1) << 4) | ((vlan >> 8) & 0xf)) & 0xff; + skb->data[15] = vlan & 0xff; + } +} + /* * Location of tagging status in select DCB types found below: * @@ -119,6 +164,7 @@ strip_vlan_tag(struct sk_buff *skb) * 1 = Single inner-tag * 2 = Single outer-tag * 3 = Double tagged. + * 4 = Dedicated for Dune device, packets are received with original tag status. * -1 = Unsupported DCB type */ static int @@ -159,6 +205,11 @@ get_tag_status(int dcb_type, void *meta) tag_status = tag_map[(dcb[9] >> 13) & 0x3]; } break; + case 28: + case 39: + tag_status = 4; + break; + break; default: tag_status = -1; break; @@ -188,12 +239,20 @@ strip_tag_rx_cb(struct sk_buff *skb, int dev_no, void *meta) if (debug & 0x1) { gprintk("%s Enter; netif Flags: %08X filter_flags %08X \n", __func__, netif_flags, filter_flags); - } + } #endif + /* Get DCB type for this packet, passed by KNET driver */ + dcb_type = KNET_SKB_CB(skb)->dcb_type; /* KNET implements this already */ if (filter_flags == FILTER_TAG_KEEP) -{ + { + if (dcb_type ==28 || dcb_type == 39) + { + uint32 *meta_buffer = (uint32 *)meta; + uint32 forward_domain = meta_buffer[1] & 0xffff; + add_vlan_tag(skb, forward_domain); + } strip_stats.skipped++; return skb; } @@ -205,18 +264,16 @@ strip_tag_rx_cb(struct sk_buff *skb, int dev_no, void *meta) { strip_tag = 1; } - /* Get DCB type for this packet, passed by KNET driver */ - dcb_type = KNET_SKB_CB(skb)->dcb_type; + + /* Get tag status from DCB */ tag_status = get_tag_status(dcb_type, meta); - #ifdef KNET_CB_DEBUG if (debug & 0x1) { gprintk("%s; DCB Type: %d; tag status: %d\n", __func__, dcb_type, tag_status); } #endif - if (tag_status < 0) { /* Unsupported DCB type */ return skb; @@ -231,12 +288,13 @@ strip_tag_rx_cb(struct sk_buff *skb, int dev_no, void *meta) strip_tag = 1; } } + strip_stats.checked++; if (strip_tag) { #ifdef KNET_CB_DEBUG if (debug & 0x1) { - gprintk("%s; Stripping VLAN\n", __func__); + gprintk("%s; Stripping VLAN tag\n", __func__); } #endif strip_stats.stripped++; @@ -245,10 +303,11 @@ strip_tag_rx_cb(struct sk_buff *skb, int dev_no, void *meta) #ifdef KNET_CB_DEBUG else { if (debug & 0x1) { - gprintk("%s; Preserve VLAN\n", __func__); + gprintk("%s; Keeping VLAN tag\n", __func__); } } #endif + return skb; } @@ -263,7 +322,7 @@ strip_tag_tx_cb(struct sk_buff *skb, int dev_no, void *meta) /* Filter callback not used */ static int strip_tag_filter_cb(uint8_t * pkt, int size, int dev_no, void *meta, - int chan, kcom_filter_t *kf) + int chan, kcom_filter_t *kf) { /* Pass through for now */ return 0; @@ -274,11 +333,11 @@ knet_filter_cb(uint8_t * pkt, int size, int dev_no, void *meta, int chan, kcom_filter_t *kf) { /* check for filter callback handler */ -#ifdef PSAMPLE_SUPPORT + #ifdef PSAMPLE_SUPPORT if (strncmp(kf->desc, PSAMPLE_CB_NAME, KCOM_FILTER_DESC_MAX) == 0) { return psample_filter_cb (pkt, size, dev_no, meta, chan, kf); } -#endif + #endif return strip_tag_filter_cb (pkt, size, dev_no, meta, chan, kf); } @@ -287,7 +346,7 @@ knet_netif_create_cb(int unit, kcom_netif_t *netif, struct net_device *dev) { int retv = 0; #ifdef PSAMPLE_SUPPORT - retv = psample_netif_create_cb(unit, netif, dev); + retv = psample_netif_create_cb(unit, netif, dev); #endif return retv; } @@ -297,7 +356,7 @@ knet_netif_destroy_cb(int unit, kcom_netif_t *netif, struct net_device *dev) { int retv = 0; #ifdef PSAMPLE_SUPPORT - retv = psample_netif_destroy_cb(unit, netif, dev); + retv = psample_netif_destroy_cb(unit, netif, dev); #endif return retv; } @@ -306,14 +365,13 @@ knet_netif_destroy_cb(int unit, kcom_netif_t *netif, struct net_device *dev) * Get statistics. * % cat /proc/linux-knet-cb */ - static int -_pprint(void) -{ - pprintf("Broadcom Linux KNET Call-Back: Untagged VLAN Stripper\n"); - pprintf(" %lu stripped packets\n", strip_stats.stripped); - pprintf(" %lu packets checked\n", strip_stats.checked); - pprintf(" %lu packets skipped\n", strip_stats.skipped); +_pprint(struct seq_file *m) +{ + pprintf(m, "Broadcom Linux KNET Call-Back: Untagged VLAN Stripper\n"); + pprintf(m, " %lu stripped packets\n", strip_stats.stripped); + pprintf(m ," %lu packets checked\n", strip_stats.checked); + pprintf(m, " %lu packets skipped\n", strip_stats.skipped); return 0; } @@ -322,7 +380,9 @@ static int _cleanup(void) { bkn_rx_skb_cb_unregister(strip_tag_rx_cb); - /* strip_tag_tx_cb is currently a no-op, so no need to unregister */ + /* strip_tag_tx_cb is currently a noop, so + * no need to unregister. + */ if (0) { bkn_tx_skb_cb_unregister(strip_tag_tx_cb); @@ -335,40 +395,44 @@ _cleanup(void) #ifdef PSAMPLE_SUPPORT psample_cleanup(); #endif + return 0; -} +} static int _init(void) { - bkn_rx_skb_cb_register(strip_tag_rx_cb); - /* strip_tag_tx_cb is currently a no-op, so no need to register */ + /* strip_tag_tx_cb is currently a noop, so + * no need to register. + */ if (0) { bkn_tx_skb_cb_register(strip_tag_tx_cb); } -#ifdef PSAMPLE_SUPPORT + #ifdef PSAMPLE_SUPPORT psample_init(); -#endif - + #endif + + bkn_filter_cb_register(knet_filter_cb); bkn_netif_create_cb_register(knet_netif_create_cb); bkn_netif_destroy_cb_register(knet_netif_destroy_cb); + return 0; } static gmodule_t _gmodule = { - name: MODULE_NAME, - major: MODULE_MAJOR, + name: MODULE_NAME, + major: MODULE_MAJOR, init: _init, - cleanup: _cleanup, - pprint: _pprint, + cleanup: _cleanup, + pprint: _pprint, ioctl: NULL, - open: NULL, - close: NULL, -}; + open: NULL, + close: NULL, +}; gmodule_t* gmodule_get(void) diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/psample-cb.c b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/psample-cb.c index ef6fc102ce78..755955b20fdd 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/psample-cb.c +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/psample-cb.c @@ -64,10 +64,24 @@ extern int debug; #define SOC_HIGIG_SRCPORT(x) ((x[1] >> 16) & 0x1f) #define SOC_HIGIG2_SOP (0xfb) //0xfc - TODO: how can we differentiate between Higig and higig2? #define SOC_HIGIG2_START(x) ((x[0] >> 24) & 0xff) +#define SOC_HIGIG2_IS_MC(x) ((x[0] >> 20) & 0x1) #define SOC_HIGIG2_DSTPORT(x) ((x[0] >> 0) & 0xff) #define SOC_HIGIG2_SRCPORT(x) ((x[1] >> 16) & 0xff) #define SOC_DCB32_HG_OFFSET (6) +/* sFlow v5 datagram dst ifindex field type + * dst ifindex encoding bits [31:30] + */ +#define DSTPORT_TYPE_DISCARD 1 +#define DSTPORT_TYPE_MC 2 + +#define DSTPORT_TYPE_OFFSET 30 +#define DSTPORT_TYPE_MASK 0x3 +#define DSTPORT_TYPE_CLR(_dst) (_dst &= ~(DSTPORT_TYPE_MASK << DSTPORT_TYPE_OFFSET)) +#define DSTPORT_TYPE_SET(_dst,_type) (_dst |= ((_type & DSTPORT_TYPE_MASK) << DSTPORT_TYPE_OFFSET)) +#define DSTPORT_TYPE_GET(_dst) ((_dst >> DSTPORT_TYPE_OFFSET) & DSTPORT_TYPE_MASK) +#define DSTPORT_GET(_dst) (_dst & ~(DSTPORT_TYPE_MASK << DSTPORT_TYPE_OFFSET)) + #define FCS_SZ 4 #define PSAMPLE_NLA_PADDING 4 @@ -78,17 +92,25 @@ LKM_MOD_PARAM(psample_size, "i", int, 0); MODULE_PARM_DESC(psample_size, "psample pkt size (default 128 bytes)"); +#define PSAMPLE_QLEN_DFLT 1024 +static int psample_qlen = PSAMPLE_QLEN_DFLT; +LKM_MOD_PARAM(psample_qlen, "i", int, 0); +MODULE_PARM_DESC(psample_qlen, +"psample queue length (default 1024 buffers)"); + /* driver proc entry root */ static struct proc_dir_entry *psample_proc_root = NULL; +static struct proc_dir_entry *knet_cb_proc_root = NULL; /* psample general info */ typedef struct { struct list_head netif_list; + int netif_count; knet_hw_info_t hw; struct net *netns; spinlock_t lock; } psample_info_t; -static psample_info_t g_psample_info = {{0}}; +static psample_info_t g_psample_info = {0}; /* Maintain sampled pkt statistics */ typedef struct psample_stats_s { @@ -96,9 +118,13 @@ typedef struct psample_stats_s { unsigned long pkts_f_psample_mod; unsigned long pkts_f_handled; unsigned long pkts_f_pass_through; + unsigned long pkts_f_dst_mc; + unsigned long pkts_c_qlen_cur; + unsigned long pkts_c_qlen_hi; + unsigned long pkts_d_qlen_max; + unsigned long pkts_d_no_mem; unsigned long pkts_d_no_group; unsigned long pkts_d_sampling_disabled; - unsigned long pkts_d_no_skb; unsigned long pkts_d_not_ready; unsigned long pkts_d_metadata; unsigned long pkts_d_meta_srcport; @@ -114,6 +140,19 @@ typedef struct psample_meta_s { int sample_rate; } psample_meta_t; +typedef struct psample_pkt_s { + struct list_head list; + struct psample_group *group; + psample_meta_t meta; + struct sk_buff *skb; +} psample_pkt_t; + +typedef struct psample_work_s { + struct list_head pkt_list; + struct work_struct wq; + spinlock_t lock; +} psample_work_t; +static psample_work_t g_psample_work = {0}; static psample_netif_t* psample_netif_lookup_by_port(int unit, int port) @@ -170,7 +209,6 @@ psample_meta_srcport_get(uint8_t *pkt, void *pkt_meta) case 26: /* TD2 */ case 23: /* HX4 */ metadata += SOC_DCB32_HG_OFFSET; - break; default: break; } @@ -205,16 +243,23 @@ psample_meta_dstport_get(uint8_t *pkt, void *pkt_meta) case 32: /* TH1/TH2 */ case 26: /* TD2 */ case 23: /* HX4 */ - metadata += SOC_DCB32_HG_OFFSET; - break; default: + metadata += SOC_DCB32_HG_OFFSET; break; } if (SOC_HIGIG2_START(metadata) == SOC_HIGIG2_SOP) { + if (SOC_HIGIG2_IS_MC(metadata)) + { + DSTPORT_TYPE_CLR(dstport); + DSTPORT_TYPE_SET(dstport, DSTPORT_TYPE_MC); + } + else + { dstport = SOC_HIGIG2_DSTPORT(metadata); } + } else if (SOC_HIGIG_START(metadata) == SOC_HIGIG_SOP) { dstport = SOC_HIGIG_DSTPORT(metadata); @@ -273,10 +318,10 @@ psample_meta_sample_reason(uint8_t *pkt, void *pkt_meta) static int psample_meta_get(int unit, uint8_t *pkt, void *pkt_meta, psample_meta_t *sflow_meta) { - int srcport, dstport; + int srcport, dstport, dstport_type; int src_ifindex = 0; int dst_ifindex = 0; - int sample_rate = PSAMPLE_RATE_DFLT; + int sample_rate = 1; int sample_size = PSAMPLE_SIZE_DFLT; psample_netif_t *psample_netif = NULL; @@ -313,8 +358,16 @@ psample_meta_get(int unit, uint8_t *pkt, void *pkt_meta, psample_meta_t *sflow_m } } - /* find dst port netif (no need to lookup CPU port) */ - if (dstport != 0) { + dstport_type = DSTPORT_TYPE_GET(dstport); + dstport = DSTPORT_GET(dstport); + + /* set sFlow dst type for MC pkts */ + if (dstport_type == DSTPORT_TYPE_MC) { + DSTPORT_TYPE_SET(dst_ifindex, DSTPORT_TYPE_MC); + g_psample_stats.pkts_f_dst_mc++; + + /* find dst port netif for UC pkts (no need to lookup CPU port) */ + } else if (dstport != 0) { if ((psample_netif = psample_netif_lookup_by_port(unit, dstport))) { dst_ifindex = psample_netif->dev->ifindex; } else { @@ -323,7 +376,7 @@ psample_meta_get(int unit, uint8_t *pkt, void *pkt_meta, psample_meta_t *sflow_m } } - PSAMPLE_CB_DBG_PRINT("%s: srcport %d, dstport %d, src_ifindex %d, dst_ifindex %d, trunc_size %d, sample_rate %d\n", + PSAMPLE_CB_DBG_PRINT("%s: srcport %d, dstport %d, src_ifindex 0x%x, dst_ifindex 0x%x, trunc_size %d, sample_rate %d\n", __func__, srcport, dstport, src_ifindex, dst_ifindex, sample_size, sample_rate); sflow_meta->src_ifindex = src_ifindex; @@ -334,13 +387,51 @@ psample_meta_get(int unit, uint8_t *pkt, void *pkt_meta, psample_meta_t *sflow_m return (0); } +static void +psample_task(struct work_struct *work) +{ + psample_work_t *psample_work = container_of(work, psample_work_t, wq); + unsigned long flags; + struct list_head *list_ptr, *list_next; + psample_pkt_t *pkt; + + spin_lock_irqsave(&psample_work->lock, flags); + list_for_each_safe(list_ptr, list_next, &psample_work->pkt_list) { + /* dequeue pkt from list */ + pkt = list_entry(list_ptr, psample_pkt_t, list); + list_del(list_ptr); + g_psample_stats.pkts_c_qlen_cur--; + spin_unlock_irqrestore(&psample_work->lock, flags); + + /* send to psample */ + if (pkt) { + PSAMPLE_CB_DBG_PRINT("%s: group 0x%x, trunc_size %d, src_ifdx 0x%x, dst_ifdx 0x%x, sample_rate %d\n", + __func__, pkt->group->group_num, + pkt->meta.trunc_size, pkt->meta.src_ifindex, + pkt->meta.dst_ifindex, pkt->meta.sample_rate); + + psample_sample_packet(pkt->group, + pkt->skb, + pkt->meta.trunc_size, + pkt->meta.src_ifindex, + pkt->meta.dst_ifindex, + pkt->meta.sample_rate); + g_psample_stats.pkts_f_psample_mod++; + + dev_kfree_skb_any(pkt->skb); + kfree(pkt); + } + spin_lock_irqsave(&psample_work->lock, flags); + } + spin_unlock_irqrestore(&psample_work->lock, flags); +} + int psample_filter_cb(uint8_t * pkt, int size, int dev_no, void *pkt_meta, int chan, kcom_filter_t *kf) { struct psample_group *group; psample_meta_t meta; - struct sk_buff skb; int rv = 0; static int info_get = 0; @@ -386,24 +477,51 @@ psample_filter_cb(uint8_t * pkt, int size, int dev_no, void *pkt_meta, meta.trunc_size = size - PSAMPLE_NLA_PADDING; } - PSAMPLE_CB_DBG_PRINT("%s: group 0x%x, trunc_size %d, src_ifdx %d, dst_ifdx %d, sample_rate %d\n", + PSAMPLE_CB_DBG_PRINT("%s: group 0x%x, trunc_size %d, src_ifdx 0x%x, dst_ifdx 0x%x, sample_rate %d\n", __func__, group->group_num, meta.trunc_size, meta.src_ifindex, meta.dst_ifindex, meta.sample_rate); /* drop if configured sample rate is 0 */ if (meta.sample_rate > 0) { + unsigned long flags; + psample_pkt_t *psample_pkt; + struct sk_buff *skb; + + if (g_psample_stats.pkts_c_qlen_cur >= psample_qlen) { + gprintk("%s: tail drop due to max qlen %d reached\n", __func__, psample_qlen); + g_psample_stats.pkts_d_qlen_max++; + goto PSAMPLE_FILTER_CB_PKT_HANDLED; + } + + if ((psample_pkt = kmalloc(sizeof(psample_pkt_t), GFP_ATOMIC)) == NULL) { + gprintk("%s: failed to alloc psample mem for pkt\n", __func__); + g_psample_stats.pkts_d_no_mem++; + goto PSAMPLE_FILTER_CB_PKT_HANDLED; + } + memcpy(&psample_pkt->meta, &meta, sizeof(psample_meta_t)); + psample_pkt->group = group; + + if ((skb = dev_alloc_skb(meta.trunc_size)) == NULL) { + gprintk("%s: failed to alloc psample mem for pkt skb\n", __func__); + g_psample_stats.pkts_d_no_mem++; + goto PSAMPLE_FILTER_CB_PKT_HANDLED; + } + /* setup skb to point to pkt */ - memset(&skb, 0, sizeof(struct sk_buff)); - skb.len = size; - skb.data = pkt; - - psample_sample_packet(group, - &skb, - meta.trunc_size, - meta.src_ifindex, - meta.dst_ifindex, - meta.sample_rate); - - g_psample_stats.pkts_f_psample_mod++; + memcpy(skb->data, pkt, meta.trunc_size); + skb_put(skb, meta.trunc_size); + skb->len = meta.trunc_size; + psample_pkt->skb = skb; + + spin_lock_irqsave(&g_psample_work.lock, flags); + list_add_tail(&psample_pkt->list, &g_psample_work.pkt_list); + + g_psample_stats.pkts_c_qlen_cur++; + if (g_psample_stats.pkts_c_qlen_cur > g_psample_stats.pkts_c_qlen_hi) { + g_psample_stats.pkts_c_qlen_hi = g_psample_stats.pkts_c_qlen_cur; + } + + schedule_work(&g_psample_work.wq); + spin_unlock_irqrestore(&g_psample_work.lock, flags); } else { g_psample_stats.pkts_d_sampling_disabled++; } @@ -427,7 +545,7 @@ psample_netif_create_cb(int unit, kcom_netif_t *netif, struct net_device *dev) psample_netif_t *psample_netif, *lpsample_netif; unsigned long flags; - if ((psample_netif = kmalloc(sizeof(psample_netif_t), GFP_KERNEL)) == NULL) { + if ((psample_netif = kmalloc(sizeof(psample_netif_t), GFP_ATOMIC)) == NULL) { gprintk("%s: failed to alloc psample mem for netif '%s'\n", __func__, dev->name); return (-1); @@ -449,6 +567,7 @@ psample_netif_create_cb(int unit, kcom_netif_t *netif, struct net_device *dev) lpsample_netif = (psample_netif_t*)list; if (netif->id < lpsample_netif->id) { found = 1; + g_psample_info.netif_count++; break; } } @@ -489,6 +608,7 @@ psample_netif_destroy_cb(int unit, kcom_netif_t *netif, struct net_device *dev) list_del(&psample_netif->list); PSAMPLE_CB_DBG_PRINT("%s: removing psample netif '%s'\n", __func__, dev->name); kfree(psample_netif); + g_psample_info.netif_count--; break; } } @@ -702,6 +822,47 @@ struct file_operations psample_proc_size_file_ops = { release: single_release, }; +/* + * psample map Proc Read Entry + */ +static int +psample_proc_map_show(struct seq_file *m, void *v) +{ + struct list_head *list; + psample_netif_t *psample_netif; + unsigned long flags; + + seq_printf(m, " Interface logical port ifindex\n"); + seq_printf(m, "------------- ------------ -------\n"); + spin_lock_irqsave(&g_psample_info.lock, flags); + + list_for_each(list, &g_psample_info.netif_list) { + psample_netif = (psample_netif_t*)list; + seq_printf(m, " %-14s %-14d %d\n", + psample_netif->dev->name, + psample_netif->port, + psample_netif->dev->ifindex); + } + + spin_unlock_irqrestore(&g_psample_info.lock, flags); + return 0; +} + +static int +psample_proc_map_open(struct inode * inode, struct file * file) +{ + return single_open(file, psample_proc_map_show, NULL); +} + +struct file_operations psample_proc_map_file_ops = { + owner: THIS_MODULE, + open: psample_proc_map_open, + read: seq_read, + llseek: seq_lseek, + write: NULL, + release: single_release, +}; + /* * psample debug Proc Read Entry */ @@ -715,6 +876,8 @@ psample_proc_debug_show(struct seq_file *m, void *v) seq_printf(m, " dcb_size: %d\n", g_psample_info.hw.dcb_size); seq_printf(m, " pkt_hdr_size: %d\n", g_psample_info.hw.pkt_hdr_size); seq_printf(m, " cdma_channels: %d\n", g_psample_info.hw.cdma_channels); + seq_printf(m, " netif_count: %d\n", g_psample_info.netif_count); + seq_printf(m, " queue length: %d\n", psample_qlen); return 0; } @@ -779,9 +942,13 @@ psample_proc_stats_show(struct seq_file *m, void *v) seq_printf(m, " pkts sent to psample module %10lu\n", g_psample_stats.pkts_f_psample_mod); seq_printf(m, " pkts handled by psample %10lu\n", g_psample_stats.pkts_f_handled); seq_printf(m, " pkts pass through %10lu\n", g_psample_stats.pkts_f_pass_through); + seq_printf(m, " pkts with mc destination %10lu\n", g_psample_stats.pkts_f_dst_mc); + seq_printf(m, " pkts current queue length %10lu\n", g_psample_stats.pkts_c_qlen_cur); + seq_printf(m, " pkts high queue length %10lu\n", g_psample_stats.pkts_c_qlen_hi); + seq_printf(m, " pkts drop max queue length %10lu\n", g_psample_stats.pkts_d_qlen_max); + seq_printf(m, " pkts drop no memory %10lu\n", g_psample_stats.pkts_d_no_mem); seq_printf(m, " pkts drop no psample group %10lu\n", g_psample_stats.pkts_d_no_group); seq_printf(m, " pkts drop sampling disabled %10lu\n", g_psample_stats.pkts_d_sampling_disabled); - seq_printf(m, " pkts drop no skb %10lu\n", g_psample_stats.pkts_d_no_skb); seq_printf(m, " pkts drop psample not ready %10lu\n", g_psample_stats.pkts_d_not_ready); seq_printf(m, " pkts drop metadata parse error %10lu\n", g_psample_stats.pkts_d_metadata); seq_printf(m, " pkts with invalid src port %10lu\n", g_psample_stats.pkts_d_meta_srcport); @@ -796,34 +963,59 @@ psample_proc_stats_open(struct inode * inode, struct file * file) return single_open(file, psample_proc_stats_show, NULL); } +/* + * psample stats Proc Write Entry + * + * Syntax: + * write any value to clear stats + */ +static ssize_t +psample_proc_stats_write(struct file *file, const char *buf, + size_t count, loff_t *loff) +{ + int qlen_cur = 0; + unsigned long flags; + + spin_lock_irqsave(&g_psample_work.lock, flags); + qlen_cur = g_psample_stats.pkts_c_qlen_cur; + memset(&g_psample_stats, 0, sizeof(psample_stats_t)); + g_psample_stats.pkts_c_qlen_cur = qlen_cur; + spin_unlock_irqrestore(&g_psample_work.lock, flags); + + return count; +} struct file_operations psample_proc_stats_file_ops = { owner: THIS_MODULE, open: psample_proc_stats_open, read: seq_read, llseek: seq_lseek, - write: NULL, + write: psample_proc_stats_write, release: single_release, }; int psample_cleanup(void) { + cancel_work_sync(&g_psample_work.wq); remove_proc_entry("stats", psample_proc_root); remove_proc_entry("rate", psample_proc_root); remove_proc_entry("size", psample_proc_root); remove_proc_entry("debug", psample_proc_root); + remove_proc_entry("map" , psample_proc_root); + remove_proc_entry("psample", knet_cb_proc_root); + remove_proc_entry("bcm/knet-cb", NULL); return 0; } int psample_init(void) { #define PROCFS_MAX_PATH 1024 + #define PSAMPLE_PROCFS_PATH "bcm/knet-cb" char psample_procfs_path[PROCFS_MAX_PATH]; struct proc_dir_entry *entry; /* create procfs for psample */ - snprintf(psample_procfs_path, PROCFS_MAX_PATH, "bcm/knet-cb"); - proc_mkdir(psample_procfs_path, NULL); - snprintf(psample_procfs_path, PROCFS_MAX_PATH, "%s/%s", psample_procfs_path, PSAMPLE_CB_NAME); + proc_mkdir(PSAMPLE_PROCFS_PATH, NULL); + snprintf(psample_procfs_path, sizeof(psample_procfs_path), "%s/%s", PSAMPLE_PROCFS_PATH, PSAMPLE_CB_NAME); psample_proc_root = proc_mkdir(psample_procfs_path, NULL); /* create procfs for psample stats */ @@ -839,7 +1031,7 @@ int psample_init(void) gprintk("%s: Unable to create procfs entry '/procfs/%s/rate'\n", __func__, psample_procfs_path); return -1; } - + /* create procfs for setting sample size */ PROC_CREATE(entry, "size", 0666, psample_proc_root, &psample_proc_size_file_ops); if (entry == NULL) { @@ -847,6 +1039,13 @@ int psample_init(void) return -1; } + /* create procfs for getting netdev mapping */ + PROC_CREATE(entry, "map", 0666, psample_proc_root, &psample_proc_map_file_ops); + if (entry == NULL) { + gprintk("%s: Unable to create procfs entry '/procfs/%s/map'\n", __func__, psample_procfs_path); + return -1; + } + /* create procfs for debug log */ PROC_CREATE(entry, "debug", 0666, psample_proc_root, &psample_proc_debug_file_ops); if (entry == NULL) { @@ -857,19 +1056,26 @@ int psample_init(void) /* clear data structs */ memset(&g_psample_stats, 0, sizeof(psample_stats_t)); memset(&g_psample_info, 0, sizeof(psample_info_t)); + memset(&g_psample_work, 0, sizeof(psample_work_t)); /* setup psample_info struct */ - INIT_LIST_HEAD(&g_psample_info.netif_list); + INIT_LIST_HEAD(&g_psample_info.netif_list); spin_lock_init(&g_psample_info.lock); - /* get net namespace */ + /* setup psample work queue */ + spin_lock_init(&g_psample_work.lock); + INIT_LIST_HEAD(&g_psample_work.pkt_list); + INIT_WORK(&g_psample_work.wq, psample_task); + + /* get net namespace */ g_psample_info.netns = get_net_ns_by_pid(current->pid); if (!g_psample_info.netns) { gprintk("%s: Could not get network namespace for pid %d\n", __func__, current->pid); return (-1); } - PSAMPLE_CB_DBG_PRINT("%s: current->pid %d, netns 0x%p, sample_size %d\n", __func__, + PSAMPLE_CB_DBG_PRINT("%s: current->pid %d, netns 0x%p, sample_size %d\n", __func__, current->pid, g_psample_info.netns, psample_size); - + + return 0; } diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/psample.c b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/psample.c index e1d4e2353b09..99317cbf30cc 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/psample.c +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/psample.c @@ -35,7 +35,7 @@ static const struct genl_multicast_group psample_nl_mcgrps[] = { [PSAMPLE_NL_MCGRP_SAMPLE] = { .name = PSAMPLE_NL_MCGRP_SAMPLE_NAME }, }; -static struct genl_family psample_nl_family __ro_after_init; +static struct genl_family psample_nl_family; static int psample_group_nl_fill(struct sk_buff *msg, struct psample_group *group, @@ -106,7 +106,7 @@ static const struct genl_ops psample_nl_ops[] = { } }; -static struct genl_family psample_nl_family __ro_after_init = { +static struct genl_family psample_nl_family = { .name = PSAMPLE_GENL_NAME, .version = PSAMPLE_GENL_VERSION, .maxattr = PSAMPLE_ATTR_MAX, @@ -224,7 +224,7 @@ void psample_sample_packet(struct psample_group *group, struct sk_buff *skb, data_len = PSAMPLE_MAX_PACKET_SIZE - meta_len - NLA_HDRLEN - NLA_ALIGNTO; - nl_skb = genlmsg_new(meta_len + data_len, GFP_ATOMIC); + nl_skb = genlmsg_new(meta_len + nla_total_size(data_len), GFP_ATOMIC); if (unlikely(!nl_skb)) return; diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/shared/Makefile b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/shared/Makefile index 5e97a3a32123..966f639f6983 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/shared/Makefile +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/shared/Makefile @@ -1,5 +1,10 @@ # -# Copyright 2017 Broadcom +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ # # You should have received a copy of the GNU General Public License # version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa # # -*- Makefile -*- # $Id: Makefile,v 1.2 Broadcom SDK $ diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/shared/gmodule.c b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/shared/gmodule.c index cdfaf089674a..3ef000961837 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/shared/gmodule.c +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/shared/gmodule.c @@ -1,5 +1,10 @@ /* - * Copyright 2017 Broadcom + * Copyright 2007-2020 Broadcom Inc. All rights reserved. + * + * Permission is granted to use, copy, modify and/or distribute this + * software under either one of the licenses below. + * + * License Option 1: GPL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. + * + * + * License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license + * + * This software is governed by the Broadcom Open Network Switch APIs license: + * https://www.broadcom.com/products/ethernet-connectivity/software/opennsa */ /* * $Id: gmodule.c,v 1.20 Broadcom SDK $ @@ -26,8 +37,6 @@ #include #include #include -#include - /* Module Vector Table */ static gmodule_t* _gmodule = NULL; @@ -94,21 +103,18 @@ gdbg(const char* fmt, ...) * Proc FS Utilities */ #if PROC_INTERFACE_KERN_VER_3_10 -static struct seq_file* _proc_buf = NULL; - int -pprintf(const char* fmt, ...) +pprintf(struct seq_file *m, const char* fmt, ...) { va_list args; va_start(args, fmt); - seq_vprintf(_proc_buf, fmt, args); + seq_vprintf(m, fmt, args); va_end(args); return 0; } static int _gmodule_proc_show(struct seq_file *m, void *v){ - _proc_buf = m; - _gmodule->pprint(); + _gmodule->pprint(m); return 0; } @@ -174,7 +180,7 @@ gmodule_pprintf(char** page_ptr, const char* fmt, ...) static char* _proc_buf = NULL; int -pprintf(const char* fmt, ...) +pprintf(struct seq_file *m, const char* fmt, ...) { int rv; @@ -193,7 +199,7 @@ static int _gmodule_pprint(char* buf) { PSTART(buf); - _gmodule->pprint(); + _gmodule->pprint(NULL); return PEND(buf); } diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/shared/ksal.c b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/shared/ksal.c index d1caf871f0e2..7f90c59c3a39 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/shared/ksal.c +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/shared/ksal.c @@ -1,5 +1,10 @@ /* - * Copyright 2017 Broadcom + * Copyright 2007-2020 Broadcom Inc. All rights reserved. + * + * Permission is granted to use, copy, modify and/or distribute this + * software under either one of the licenses below. + * + * License Option 1: GPL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. + * + * + * License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license + * + * This software is governed by the Broadcom Open Network Switch APIs license: + * https://www.broadcom.com/products/ethernet-connectivity/software/opennsa */ /* * $Id: ksal.c,v 1.1 Broadcom SDK $ diff --git a/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile b/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile index 20d83735fcce..8f59a763e314 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile +++ b/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile @@ -1,5 +1,10 @@ # -# Copyright 2017 Broadcom +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ # # You should have received a copy of the GNU General Public License # version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa # # -*- Makefile -*- # $Id: Makefile,v 1.4 Broadcom SDK $ @@ -65,7 +76,7 @@ ifeq (,$(kernel_version)) kernel_version=2_4 endif -ifeq ($(kernel_version),2_6) +ifneq ($(kernel_version),2_4) KOBJ=ko else KOBJ=o @@ -94,6 +105,9 @@ BCM_KNET=$(DEST_DIR)/$(BCM_KNET_LOCAL) PSAMPLE_LOCAL := psample.$(KOBJ) PSAMPLE := $(DEST_DIR)/$(PSAMPLE_LOCAL) +BCM_LPTP_LOCAL :=linux-bcm-ptp-clock.$(KOBJ) +BCM_LPTP=$(DEST_DIR)/$(BCM_LPTP_LOCAL) + ifeq (,$(findstring DELIVER,$(MAKECMDGOALS))) .DEFAULT_GOAL := all all_targets := kernel_modules $(KERNEL_BDE) $(USER_BDE) @@ -111,6 +125,12 @@ ifndef BUILD_KNET BUILD_KNET = 1 endif +# Remove this when LinuxPTP support becomes optional. +ifndef BUILD_LPTP +BUILD_LPTP = 1 +BUILD_KNETSYNC = 1 +endif + ifeq ($(BUILD_KNET),1) # Kernel network support all_targets += $(BCM_KNET) @@ -132,9 +152,27 @@ endif ifdef BUILD_PSAMPLE all_targets += $(PSAMPLE) ADD_TO_CFLAGS += -DPSAMPLE_SUPPORT + +# KnetSync support +ifdef BUILD_KNETSYNC + +KERNEL_TARGETS += $(BCM_PTP_CLOCK) +LOCAL_KERNEL_TARGETS += $(patsubst %,$(realpath ..)/$(platform)/%,$(BCM_PTP_CLOCK_LOCAL)) + +endif # BUILD_KNETSYNC + ifeq ($(NO_LOCAL_TARGETS),) -LOCAL_TARGETS +=$(patsubst %,../$(platform)/%,$(PSAMPLE_LOCAL)) -all_targets +=$(LOCAL_TARGETS) + LOCAL_TARGETS +=$(patsubst %,../$(platform)/%,$(PSAMPLE_LOCAL)) + all_targets +=$(LOCAL_TARGETS) +endif +endif + +ifdef BUILD_LPTP + all_targets += $(BCM_LPTP) + +ifeq ($(NO_LOCAL_TARGETS),) + LOCAL_TARGETS +=$(patsubst %,../$(platform)/%,$(BCM_LPTP_LOCAL)) + all_targets +=$(LOCAL_TARGETS) endif endif @@ -142,9 +180,6 @@ ADD_TO_CFLAGS += -I$(SDK)/systems/linux/kernel/modules/include COND_KNET_LIBS = libuser.$(libext) endif -#SAI_FIXUP -.NOTPARALLEL: - all: $(BLDDIR)/.tree $(all_targets) ifeq ($(NO_LOCAL_TARGETS),) @@ -161,24 +196,33 @@ ADD_TO_CFLAGS += -I$(SDK)/systems/bde/linux/include ADD_TO_CFLAGS += -DPROXY_SUPPORT=0 CFLAGS += $(ADD_TO_CFLAGS) + #SAI_FIXUP CFLAGS:=$(filter-out -fPIC, $(CFLAGS)) +# KnetSync Support +ifdef BUILD_KNETSYNC + knetsync_subdirs = bcm-ptp-clock +endif # BUILD_KNETSYNC kernel_modules: $(MAKE) -C $(SDK)/systems/bde/linux/kernel kernel_version=$(kernel_version) $(MAKE) -C $(SDK)/systems/bde/linux/user/kernel kernel_version=$(kernel_version) ifeq ($(BUILD_KNET),1) - $(MAKE) -j1 -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ + $(MAKE) -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ subdirs="shared bcm-knet" override-target=linux-$(platform) CFLAGS="$(CFLAGS)" -ifdef BUILD_PSAMPLE - $(MAKE) -j1 -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ +ifdef BUILD_PSAMPLE + $(MAKE) -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ subdirs="psample" override-target=linux-$(platform) CFLAGS="$(CFLAGS)" endif ifdef BUILD_KNET_CB - $(MAKE) -j1 -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ + $(MAKE) -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ subdirs="knet-cb" override-target=linux-$(platform) CFLAGS="$(CFLAGS)" endif +ifdef BUILD_LPTP + $(MAKE) -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ + subdirs="bcm-ptp-clock" override-target=linux-$(platform) CFLAGS="$(CFLAGS)" +endif endif $(KERNEL_BDE): $(KERN_BLDROOT)/linux-kernel-bde.$(KOBJ) @@ -197,6 +241,8 @@ $(KNET_CB): $(KERN_BLDROOT)/linux-knet-cb.$(KOBJ) $(PSAMPLE): $(KERN_BLDROOT)/psample.$(KOBJ) $(OBJCOPY) --strip-debug $< $@ +$(BCM_LPTP): $(KERN_BLDROOT)/linux-bcm-ptp-clock.$(KOBJ) + $(OBJCOPY) --strip-debug $< $@ ifeq ($(NO_LOCAL_TARGETS),) $(foreach targ,$(LOCAL_TARGETS),$(eval $(call LOCAL_TARGET_DEF,$(targ)))) @@ -206,10 +252,10 @@ clean:: $(MAKE) -C $(SDK)/systems/bde/linux/kernel $@ $(MAKE) -C $(SDK)/systems/bde/linux/user/kernel $@ $(MAKE) -C $(SDK)/systems/linux/kernel/modules \ - subdirs="shared bcm-knet knet-cb" \ + subdirs="shared bcm-knet knet-cb psample bcm-ptp-clock" \ override-target=linux-$(platform) $@ $(RM) $(KERNEL_BDE) $(USER_BDE) - $(RM) $(BCM_KNET) $(KNET_CB) + $(RM) $(BCM_KNET) $(KNET_CB) $(PSAMPLE) $(BCM_LPTP) $(RM) $(KERN_BLDROOT)/linux-kernel-bde.$(KOBJ) $(RM) $(KERN_BLDROOT)/linux-user-bde.$(KOBJ) $(RM) $(KERN_BLDROOT)/linux-bcm-knet.$(KOBJ) diff --git a/platform/broadcom/saibcm-modules/systems/linux/user/gts/Makefile b/platform/broadcom/saibcm-modules/systems/linux/user/gts/Makefile new file mode 100644 index 000000000000..5acaeab271cc --- /dev/null +++ b/platform/broadcom/saibcm-modules/systems/linux/user/gts/Makefile @@ -0,0 +1,74 @@ +# +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa +# +# -*- Makefile -*- +# $Id: Makefile,v 0.1 Broadcom SDK $ +# $Copyright: (c) 2015 Broadcom Corp. +# All Rights Reserved.$ + +# +# This make job requires the following environment variables to be set: +# +# SDK - path to StrataXGS SDK root directory +# +# Optionally the following environment variables can be set to +# override the default build server configuration: +# +# TOOLS_DIR - path to build tools (if not in PATH already) +# CROSS_COMPILE - cross compile tools prefix +# LINUX_INCLUDE - path to Linux kernel include directory +# + +SDK :=$(shell if [ -n "$$SDK" ] ; then\ + echo $$SDK;\ + else\ + cd $(dir $(lastword $(MAKEFILE_LIST))); while /usr/bin/test ! -e RELEASE ; do \ + dir=`cd ../;pwd`; \ + if [ "$$dir" = "/" ] ; then \ + echo Cannot find SDK in $(lastword $(MAKEFILE_LIST)) 1>&2; \ + exit 1; \ + fi ; \ + cd $$dir; \ + done ; \ + pwd; \ + fi) + +ifeq ($(SDK),) +$(error Please run this in a tree) +endif + +export SDK + +override kernel_version=4_19 +platform=gts +LINUX_MAKE_USER=1 +export LINKER_RELAX = 1 +export ADD_TO_CFLAGS +export BR_NO_CCACHE + + +include ${SDK}/make/Make.linux + diff --git a/platform/broadcom/saibcm-modules/systems/linux/user/iproc-3_14/Makefile b/platform/broadcom/saibcm-modules/systems/linux/user/iproc-3_14/Makefile index c9f538802f6d..b874340ddec2 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/user/iproc-3_14/Makefile +++ b/platform/broadcom/saibcm-modules/systems/linux/user/iproc-3_14/Makefile @@ -1,5 +1,10 @@ # -# Copyright 2017 Broadcom +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ # # You should have received a copy of the GNU General Public License # version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa # # -*- Makefile -*- # $Id: Makefile,v 1.7 Broadcom SDK $ diff --git a/platform/broadcom/saibcm-modules/systems/linux/user/iproc-4_4/Makefile b/platform/broadcom/saibcm-modules/systems/linux/user/iproc-4_4/Makefile new file mode 100644 index 000000000000..2b724be3202f --- /dev/null +++ b/platform/broadcom/saibcm-modules/systems/linux/user/iproc-4_4/Makefile @@ -0,0 +1,70 @@ +# +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa +# +# -*- Makefile -*- +# $Id: Makefile,v 1.7 Broadcom SDK $ +# $Copyright: (c) 2005 Broadcom Corp. +# All Rights Reserved.$ + +# +# This make job requires the following environment variables to be set: +# +# SDK - path to StrataXGS SDK root directory +# + +SDK :=$(shell if [ -n "$$SDK" ] ; then\ + echo $$SDK;\ + else\ + cd $(dir $(lastword $(MAKEFILE_LIST))); while /usr/bin/test ! -e RELEASE ; do \ + dir=`cd ../;pwd`; \ + if [ "$$dir" = "/" ] ; then \ + echo Cannot find SDK in $(lastword $(MAKEFILE_LIST)) 1>&2; \ + exit 1; \ + fi ; \ + cd $$dir; \ + done ; \ + pwd; \ + fi) + +ifeq ($(SDK),) +$(error Please run this in a tree) +endif + +export SDK + +override kernel_version=4_4 +platform=iproc-$(kernel_version) + +IPROC_BUILD=1 +export IPROC_BUILD +export BUILD_PLATFORM +export ARM_LINUX_VERSION + +LINUX_MAKE_USER=1 +export ADD_TO_CFLAGS +export BR_NO_CCACHE + +include ${SDK}/make/Make.linux diff --git a/platform/broadcom/saibcm-modules/systems/linux/user/iproc/Makefile b/platform/broadcom/saibcm-modules/systems/linux/user/iproc/Makefile index 03300ff8a046..f10c5c37a082 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/user/iproc/Makefile +++ b/platform/broadcom/saibcm-modules/systems/linux/user/iproc/Makefile @@ -1,5 +1,10 @@ # -# Copyright 2017 Broadcom +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ # # You should have received a copy of the GNU General Public License # version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa # # -*- Makefile -*- # $Id: Makefile,v 1.7 Broadcom SDK $ diff --git a/platform/broadcom/saibcm-modules/systems/linux/user/iproc_64/Makefile b/platform/broadcom/saibcm-modules/systems/linux/user/iproc_64/Makefile new file mode 100644 index 000000000000..983b3abbced7 --- /dev/null +++ b/platform/broadcom/saibcm-modules/systems/linux/user/iproc_64/Makefile @@ -0,0 +1,70 @@ +# +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa +# +# -*- Makefile -*- +# $Id: Makefile,v 1.7 Broadcom SDK $ +# $Copyright: (c) 2005 Broadcom Corp. +# All Rights Reserved.$ + +# +# This make job requires the following environment variables to be set: +# +# SDK - path to StrataXGS SDK root directory +# + +SDK :=$(shell if [ -n "$$SDK" ] ; then\ + echo $$SDK;\ + else\ + cd $(dir $(lastword $(MAKEFILE_LIST))); while /usr/bin/test ! -e RELEASE ; do \ + dir=`cd ../;pwd`; \ + if [ "$$dir" = "/" ] ; then \ + echo Cannot find SDK in $(lastword $(MAKEFILE_LIST)) 1>&2; \ + exit 1; \ + fi ; \ + cd $$dir; \ + done ; \ + pwd; \ + fi) + +ifeq ($(SDK),) +$(error Please run this in a tree) +endif + +export SDK + +override kernel_version=4_14 +platform=iproc_64 + +IPROC_BUILD=1 +export IPROC_BUILD +export BUILD_PLATFORM +export ARM_LINUX_VERSION + +LINUX_MAKE_USER=1 +export ADD_TO_CFLAGS +export BR_NO_CCACHE + +include ${SDK}/make/Make.linux diff --git a/platform/broadcom/saibcm-modules/systems/linux/user/slk/Makefile b/platform/broadcom/saibcm-modules/systems/linux/user/slk/Makefile new file mode 100644 index 000000000000..6ef360156572 --- /dev/null +++ b/platform/broadcom/saibcm-modules/systems/linux/user/slk/Makefile @@ -0,0 +1,71 @@ +# +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa +# +# -*- Makefile -*- +# $Id: Makefile,v 0.1 Broadcom SDK $ +# $Copyright: (c) 2015 Broadcom Corp. +# All Rights Reserved.$ + +# +# This make job requires the following environment variables to be set: +# +# SDK - path to StrataXGS SDK root directory +# +# Optionally the following environment variables can be set to +# override the default build server configuration: +# +# TOOLS_DIR - path to build tools (if not in PATH already) +# CROSS_COMPILE - cross compile tools prefix +# LINUX_INCLUDE - path to Linux kernel include directory +# + +SDK :=$(shell if [ -n "$$SDK" ] ; then\ + echo $$SDK;\ + else\ + cd $(dir $(lastword $(MAKEFILE_LIST))); while /usr/bin/test ! -e RELEASE ; do \ + dir=`cd ../;pwd`; \ + if [ "$$dir" = "/" ] ; then \ + echo Cannot find SDK in $(lastword $(MAKEFILE_LIST)) 1>&2; \ + exit 1; \ + fi ; \ + cd $$dir; \ + done ; \ + pwd; \ + fi) + +ifeq ($(SDK),) +$(error Please run this in a tree) +endif + +export SDK + +override kernel_version=3_14 +platform=slk +LINUX_MAKE_USER=1 +export LINKER_RELAX = 1 + +include ${SDK}/make/Make.linux + diff --git a/platform/broadcom/saibcm-modules/systems/linux/user/x86-smp_generic_64-2_6/Makefile b/platform/broadcom/saibcm-modules/systems/linux/user/x86-smp_generic_64-2_6/Makefile index 29717b3af42a..78c2c0cb1702 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/user/x86-smp_generic_64-2_6/Makefile +++ b/platform/broadcom/saibcm-modules/systems/linux/user/x86-smp_generic_64-2_6/Makefile @@ -1,5 +1,10 @@ # -# Copyright 2017 Broadcom +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ # # You should have received a copy of the GNU General Public License # version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa # # -*- Makefile -*- # $Id: Makefile,v 1.2 Broadcom SDK $ diff --git a/platform/broadcom/saibcm-modules/systems/linux/user/xlr/Makefile b/platform/broadcom/saibcm-modules/systems/linux/user/xlr/Makefile new file mode 100644 index 000000000000..e19eeff4aef2 --- /dev/null +++ b/platform/broadcom/saibcm-modules/systems/linux/user/xlr/Makefile @@ -0,0 +1,74 @@ +# +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa +# +# -*- Makefile -*- +# $Id: Makefile,v 0.1 Broadcom SDK $ +# $Copyright: (c) 2015 Broadcom Corp. +# All Rights Reserved.$ + +# +# This make job requires the following environment variables to be set: +# +# SDK - path to StrataXGS SDK root directory +# +# Optionally the following environment variables can be set to +# override the default build server configuration: +# +# TOOLS_DIR - path to build tools (if not in PATH already) +# CROSS_COMPILE - cross compile tools prefix +# LINUX_INCLUDE - path to Linux kernel include directory +# + +SDK :=$(shell if [ -n "$$SDK" ] ; then\ + echo $$SDK;\ + else\ + cd $(dir $(lastword $(MAKEFILE_LIST))); while /usr/bin/test ! -e RELEASE ; do \ + dir=`cd ../;pwd`; \ + if [ "$$dir" = "/" ] ; then \ + echo Cannot find SDK in $(lastword $(MAKEFILE_LIST)) 1>&2; \ + exit 1; \ + fi ; \ + cd $$dir; \ + done ; \ + pwd; \ + fi) + +ifeq ($(SDK),) +$(error Please run this in a tree) +endif + +export SDK + +override kernel_version=4_19 +platform=xlr +LINUX_MAKE_USER=1 +export LINKER_RELAX = 1 +export ADD_TO_CFLAGS +export BR_NO_CCACHE + + +include ${SDK}/make/Make.linux + diff --git a/platform/broadcom/saibcm-modules/tools/mktool.pl b/platform/broadcom/saibcm-modules/tools/mktool.pl index 8800c00613d8..518ab25535c3 100644 --- a/platform/broadcom/saibcm-modules/tools/mktool.pl +++ b/platform/broadcom/saibcm-modules/tools/mktool.pl @@ -1,5 +1,10 @@ # -# Copyright 2017 Broadcom +# Copyright 2007-2020 Broadcom Inc. All rights reserved. +# +# Permission is granted to use, copy, modify and/or distribute this +# software under either one of the licenses below. +# +# License Option 1: GPL # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as @@ -12,6 +17,12 @@ # # You should have received a copy of the GNU General Public License # version 2 (GPLv2) along with this source code. +# +# +# License Option 2: Broadcom Open Network Switch APIs (OpenNSA) license +# +# This software is governed by the Broadcom Open Network Switch APIs license: +# https://www.broadcom.com/products/ethernet-connectivity/software/opennsa # # # mktool.pl diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/fanutil.py b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/fanutil.py index df2e511adef7..d046834ecf33 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/fanutil.py +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/fanutil.py @@ -20,50 +20,79 @@ # ------------------------------------------------------------------ try: - import os import time import logging - import glob - import commands from collections import namedtuple except ImportError as e: raise ImportError('%s - required module not found' % str(e)) + + +class FanUtil(object): + """Platform-specific FanUtil class""" + + FAN_NUM_ON_MAIN_BROAD = 3 + FAN_NUM_1_IDX = 1 + FAN_NUM_2_IDX = 2 + FAN_NUM_3_IDX = 3 -class ThermalUtil(object): - """Platform-specific ThermalUtil class""" - THERMAL_NUM_MAX = 4 - THERMAL_NUM_1_IDX = 1 - THERMAL_NUM_2_IDX = 2 - THERMAL_NUM_3_IDX = 3 - THERMAL_NUM_4_IDX = 4 + FAN_NODE_NUM_OF_MAP = 4 + FAN_NODE_FAULT_IDX_OF_MAP = 1 + FAN_NODE_DIR_IDX_OF_MAP = 2 + FAN_NODE_PRESENT_IDX_OF_MAP= 3 + FAN_NODE_SPEED_IDX_OF_MAP = 4 + + BASE_VAL_PATH = '/sys/bus/i2c/devices/3-0060/{0}' + FAN_DUTY_PATH = '/sys/bus/i2c/devices/3-0060/fan_duty_cycle_percentage' """ Dictionary where - key1 = thermal id index (integer) starting from 1 + key1 = fan id index (integer) starting from 1 + key2 = fan node index (interger) starting from 1 value = path to fan device file (string) """ + _fan_device_path_mapping = {} - thermal_sysfspath ={ - THERMAL_NUM_1_IDX: ["/sys/bus/i2c/devices/14-0048/hwmon/hwmon*/temp1_input"], - THERMAL_NUM_2_IDX: ["/sys/bus/i2c/devices/24-004b/hwmon/hwmon*/temp1_input"], - THERMAL_NUM_3_IDX: ["/sys/bus/i2c/devices/25-004a/hwmon/hwmon*/temp1_input"], - THERMAL_NUM_4_IDX: ["/sys/class/hwmon/hwmon1/temp1_input"], + _fan_device_node_mapping = { + (FAN_NUM_1_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan_fault_1', + (FAN_NUM_1_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan_direction_1', + (FAN_NUM_1_IDX, FAN_NODE_PRESENT_IDX_OF_MAP): 'fan_present_1', + (FAN_NUM_1_IDX, FAN_NODE_SPEED_IDX_OF_MAP): 'fan1_input', + + + (FAN_NUM_2_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan_fault_2', + (FAN_NUM_2_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan_direction_2', + (FAN_NUM_2_IDX, FAN_NODE_PRESENT_IDX_OF_MAP):'fan_present_2', + (FAN_NUM_2_IDX, FAN_NODE_SPEED_IDX_OF_MAP): 'fan2_input', + + (FAN_NUM_3_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan_fault_3', + (FAN_NUM_3_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan_direction_3', + (FAN_NUM_3_IDX, FAN_NODE_PRESENT_IDX_OF_MAP):'fan_present_3', + (FAN_NUM_3_IDX, FAN_NODE_SPEED_IDX_OF_MAP): 'fan3_input', } - def _get_thermal_val(self, thermal_num): - if thermal_num < self.THERMAL_NUM_1_IDX or thermal_num > self.THERMAL_NUM_MAX: - logging.debug('GET. Parameter error. thermal_num, %d', thermal_num) + def _get_fan_device_node(self, fan_num, node_num): + return self._fan_device_node_mapping[(fan_num, node_num)] + + def _get_fan_node_val(self, fan_num, node_num): + if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. fan_num:%d', fan_num) + return None + + if node_num < self.FAN_NODE_FAULT_IDX_OF_MAP or node_num > self.FAN_NODE_NUM_OF_MAP: + logging.debug('GET. Parameter error. node_num:%d', node_num) return None - device_path = self.get_thermal_path(thermal_num) - for filename in glob.glob(device_path): + device_path = self.get_fan_device_path(fan_num, node_num) + try: - val_file = open(filename, 'r') + val_file = open(device_path, 'r') except IOError as e: logging.error('GET. unable to open file: %s', str(e)) return None + content = val_file.readline().rstrip() if content == '': logging.debug('GET. content is NULL. device_path:%s', device_path) return None + try: val_file.close() except: @@ -72,19 +101,103 @@ def _get_thermal_val(self, thermal_num): return int(content) - return 0 + def _set_fan_node_val(self, fan_num, node_num, val): + if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. fan_num:%d', fan_num) + return None - def get_num_thermals(self): - return self.THERMAL_NUM_MAX + if node_num < self.FAN_NODE_FAULT_IDX_OF_MAP or node_num > self.FAN_NODE_NUM_OF_MAP: + logging.debug('GET. Parameter error. node_num:%d', node_num) + return None + + content = str(val) + if content == '': + logging.debug('GET. content is NULL. device_path:%s', device_path) + return None - def get_size_path_map(self): - return len(self.thermal_sysfspath) + device_path = self.get_fan_device_path(fan_num, node_num) + try: + val_file = open(device_path, 'w') + except IOError as e: + logging.error('GET. unable to open file: %s', str(e)) + return None - def get_thermal_path(self, thermal_num): - return self.thermal_sysfspath[thermal_num][0] + val_file.write(content) + + try: + val_file.close() + except: + logging.debug('GET. unable to close file. device_path:%s', device_path) + return None + + return True + + def __init__(self): + fan_path = self.BASE_VAL_PATH + for fan_num in range(self.FAN_NUM_1_IDX, self.FAN_NUM_ON_MAIN_BROAD+1): + for node_num in range(self.FAN_NODE_FAULT_IDX_OF_MAP, self.FAN_NODE_NUM_OF_MAP+1): + self._fan_device_path_mapping[(fan_num, node_num)] = fan_path.format( + self._fan_device_node_mapping[(fan_num, node_num)]) + + def get_size_node_map(self): + return len(self._fan_device_node_mapping) + + def get_fan_device_path(self, fan_num, node_num): + return self._fan_device_path_mapping[(fan_num, node_num)] + + def get_fan_fault(self, fan_num): + return self._get_fan_node_val(fan_num, self.FAN_NODE_FAULT_IDX_OF_MAP) + + def get_fan_present(self, fan_num): + return self._get_fan_node_val(fan_num, self.FAN_NODE_PRESENT_IDX_OF_MAP) + + def get_fan_dir(self, fan_num): + return self._get_fan_node_val(fan_num, self.FAN_NODE_DIR_IDX_OF_MAP) + + def get_fan_duty_cycle(self): + try: + val_file = open(self.FAN_DUTY_PATH) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + content = val_file.readline().rstrip() + val_file.close() + + return int(content) + + def set_fan_duty_cycle(self, val): + try: + fan_file = open(self.FAN_DUTY_PATH, 'r+') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + fan_file.write(str(val)) + fan_file.close() + return True + + def get_fan_speed(self, fan_num): + return self._get_fan_node_val(fan_num, self.FAN_NODE_SPEED_IDX_OF_MAP) + + def get_fan_status(self, fan_num): + if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. fan_num, %d', fan_num) + return None + if self.get_fan_fault(fan_num)==0 and self.get_fan_present(fan_num)>0: + return 1 + else: + logging.debug('GET. FAN fault. fan_num, %d', fan_num) + return 0 def main(): - thermal = ThermalUtil() + fan = FanUtil() + logging.debug('fan_duty_cycle=%d', fan.get_fan_duty_cycle()) + for i in range(1,4): + logging.debug('fan-%d speed=%d', i, fan.get_fan_speed(i)) + logging.debug('fan-%d present=%d', i, fan.get_fan_present(i)) + logging.debug('fan-%d fault=%d', i, fan.get_fan_fault(i)) + logging.debug('fan-%d status=%d', i, fan.get_fan_status(i)) if __name__ == '__main__': - main() \ No newline at end of file + main() diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/x86-64-accton-as4630-54pe-cpld.c b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/x86-64-accton-as4630-54pe-cpld.c index 5e25e824d418..d1205516ef53 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/x86-64-accton-as4630-54pe-cpld.c +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/x86-64-accton-as4630-54pe-cpld.c @@ -36,6 +36,7 @@ #include #include #include +#include #include diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/service/as4630-54pe-platform-monitor-fan.service b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/service/as4630-54pe-platform-monitor-fan.service old mode 100755 new mode 100644 diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/service/as4630-54pe-platform-monitor-psu.service b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/service/as4630-54pe-platform-monitor-psu.service old mode 100755 new mode 100644 diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/service/as4630-54pe-platform-monitor.service b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/service/as4630-54pe-platform-monitor.service old mode 100755 new mode 100644 diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor.py index 6dbf5c2cc720..8913233366e2 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor.py @@ -20,19 +20,13 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time - import traceback import commands - from tabulate import tabulate from as4630_54pe.fanutil import FanUtil from as4630_54pe.thermalutil import ThermalUtil except ImportError as e: diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor_fan.py b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor_fan.py index 11453818b04c..c775e86874b8 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor_fan.py +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor_fan.py @@ -22,19 +22,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate - except ImportError as e: raise ImportError('%s - required module not found' % str(e)) diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor_psu.py b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor_psu.py index 8ef700f33ca0..02f4541127a7 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor_psu.py +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor_psu.py @@ -22,18 +22,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate except ImportError as e: raise ImportError('%s - required module not found' % str(e)) diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_util.py b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_util.py index 2f73726f846d..4039119288a0 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_util.py @@ -17,7 +17,6 @@ """ Usage: %(scriptName)s [options] command object - options: -h | --help : this help message -d | --debug : run with debug mode @@ -30,13 +29,12 @@ set : change board setting with fan|led|sfp """ -import os import commands -import sys, getopt +import getopt +import sys import logging import re import time -from collections import namedtuple PROJECT_NAME = 'as4630_54pe' version = '0.0.1' @@ -55,7 +53,6 @@ 'fan3': ['fan'], 'fan4': ['fan'], 'fan5': ['fan'], - 'fan5': ['fan'], } hwmon_nodes = {'led': ['brightness'] , 'fan1': ['fan_duty_cycle_percentage', 'fan1_fault', 'fan1_speed_rpm', 'fan1_direction', 'fanr1_fault', 'fanr1_speed_rpm'], @@ -108,7 +105,12 @@ 'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-1/new_device', ] - +# Disable CPLD debug mode +cpld_set =[ +'i2cset -y -f 3 0x60 0x2a 0xff', +'i2cset -y -f 3 0x60 0x2b 0xff', +'i2cset -y -f 3 0x60 0x86 0x89' +] FORCE = 0 logging.basicConfig(filename= PROJECT_NAME+'.log', filemode='w',level=logging.DEBUG) @@ -212,10 +214,12 @@ def log_os_system(cmd, show): return status, output def driver_inserted(): - ret, lsmod = log_os_system("lsmod| grep accton", 0) + ret, lsmod = log_os_system("ls /sys/module/*accton*", 0) logging.info('mods:'+lsmod) - if len(lsmod) ==0: + if ret : return False + else : + return True #'modprobe cpr_4011_4mxx', @@ -353,6 +357,12 @@ def do_install(): return status else: print PROJECT_NAME.upper()+" devices detected...." + + for i in range(len(cpld_set)): + status, output = log_os_system(cpld_set[i], 1) + if status: + if FORCE == 0: + return status return def do_uninstall(): diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/leds-accton_as5712_54x.c b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/leds-accton_as5712_54x.c index cdea927368ae..36988aecfc49 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/leds-accton_as5712_54x.c +++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/leds-accton_as5712_54x.c @@ -34,7 +34,6 @@ extern int as5712_54x_cpld_read (unsigned short cpld_addr, u8 reg); extern int as5712_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); extern void led_classdev_unregister(struct led_classdev *led_cdev); -extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); extern void led_classdev_resume(struct led_classdev *led_cdev); extern void led_classdev_suspend(struct led_classdev *led_cdev); diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_monitor.py index 09b2b9ea96bd..f032088dc525 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_monitor.py @@ -23,18 +23,11 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt import logging import logging.config - import types import time # this is only being used as part of the example - import traceback import signal - from tabulate import tabulate from as5712_54x.fanutil import FanUtil from as5712_54x.thermalutil import ThermalUtil except ImportError as e: diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_util.py b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_util.py index 100af5bac826..ed9667da8c99 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_util.py @@ -31,12 +31,11 @@ import os import commands -import sys, getopt +import getopt +import sys import logging import re import time -import pickle -from collections import namedtuple PROJECT_NAME = 'as5712_54x' version = '0.2.0' @@ -81,7 +80,6 @@ 'sfp': ['sfp_is_present ', 'sfp_tx_disable']} QSFP_START = 48 -I2C_BUS_ORDER = -1 sfp_map = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, @@ -242,12 +240,12 @@ def log_os_system(cmd, show): return status, output def driver_inserted(): - ret, lsmod = log_os_system("lsmod| grep accton", 0) + ret, lsmod = log_os_system("ls /sys/module/*accton*", 0) logging.info('mods:'+lsmod) - if len(lsmod) ==0: + if ret : return False - - + else : + return True kos = [ 'depmod -ae', @@ -264,10 +262,10 @@ def driver_inserted(): def driver_install(): global FORCE for i in range(0,len(kos)): - status, output = log_os_system(kos[i], 1) - if status: + ret = log_os_system(kos[i], 1) + if ret[0]: if FORCE == 0: - return status + return ret[0] return 0 def driver_uninstall(): @@ -283,10 +281,10 @@ def driver_uninstall(): #Change to removing commands rm = rm.replace("modprobe", "modprobe -rq") rm = rm.replace("insmod", "rmmod") - status, output = log_os_system(rm, 1) - if status: + ret = log_os_system(rm, 1) + if ret[0]: if FORCE == 0: - return status + return ret[0] return 0 @@ -294,38 +292,23 @@ def driver_uninstall(): def i2c_order_check(): # i2c bus 0 and 1 might be installed in different order. # Here check if 0x70 is exist @ i2c-0 - tmp = "echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-1/new_device" - status, output = log_os_system(tmp, 0) - if not device_exist(): + tmp = "i2cget -y -f 0 0x70" + ret = log_os_system(tmp, 0) + if not ret[0]: order = 1 else: order = 0 - tmp = "echo 0x70 > /sys/bus/i2c/devices/i2c-1/delete_device" - status, output = log_os_system(tmp, 0) + m = "[%s]Detected I2C_BUS_ORDER:%d" % (os.path.basename(__file__), order) + my_log(m) return order -def update_i2c_order(): - global I2C_BUS_ORDER - - order = i2c_order_check() - pickle.dump(order, open("/tmp/accton_util.p", "wb")) # save it - I2C_BUS_ORDER = order - print "[%s]Detected I2C_BUS_ORDER:%d" % (os.path.basename(__file__), I2C_BUS_ORDER) - def get_i2c_order(): - global I2C_BUS_ORDER - if I2C_BUS_ORDER < 0: - if os.path.exists("/tmp/accton_util.p"): - I2C_BUS_ORDER = pickle.load(open("/tmp/accton_util.p", "rb")) - else: - update_i2c_order() + return i2c_order_check() def device_install(): global FORCE - global I2C_BUS_ORDER - update_i2c_order() - order = I2C_BUS_ORDER + order = get_i2c_order() # if 0x76 is not exist @i2c-0, use reversed bus order if order: for i in range(0,len(mknod2)): @@ -349,7 +332,7 @@ def device_install(): print output if FORCE == 0: return status - + for i in range(0,len(sfp_map)): if i < QSFP_START: status, output =log_os_system("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) @@ -364,15 +347,12 @@ def device_install(): print output if FORCE == 0: return status - + return def device_uninstall(): global FORCE - global I2C_BUS_ORDER - get_i2c_order() - order = I2C_BUS_ORDER 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) @@ -381,6 +361,7 @@ def device_uninstall(): if FORCE == 0: return status + order = get_i2c_order() if order == 0: nodelist = mknod else: @@ -533,19 +514,15 @@ def show_eeprom(index): def get_cpld_path(index): - global I2C_BUS_ORDER - - if I2C_BUS_ORDER < 0: - get_i2c_order() - - if I2C_BUS_ORDER !=0 : + order = get_i2c_order() + if order !=0 : return port_cpld_path[index].replace("0-", "1-") else: return port_cpld_path[index] def cpld_path_of_port(port_index): if port_index < 1 and port_index > DEVICE_NO['sfp']: - return None + return None if port_index < 25: return get_cpld_path(0) else: @@ -553,19 +530,19 @@ def cpld_path_of_port(port_index): def get_path_sfp_tx_dis(port_index): cpld_p = cpld_path_of_port(port_index) - if cpld_p == None: + if cpld_p is None: return False, '' else: dev = cpld_p+"module_tx_disable_"+str(port_index) - return True, dev + return True, dev def get_path_sfp_presence(port_index): cpld_p = cpld_path_of_port(port_index) - if cpld_p == None: + if cpld_p is None: return False, '' else: dev = cpld_p+"module_present_"+str(port_index) - return True, dev + return True, dev def set_device(args): @@ -586,9 +563,9 @@ def set_device(args): #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 + ret[0] = log_os_system("echo "+args[1]+" >"+k, 1) + if ret[0]: + return ret[0] elif args[0]=='fan': if int(args[1])>100: show_set_help() @@ -623,8 +600,8 @@ def set_device(args): if ret == False: return False else: - ret, log = log_os_system("echo "+args[2]+" >"+ dev, 1) - return ret + ret = log_os_system("echo "+args[2]+" >"+ dev, 1) + return ret[0] return #get digits inside a string. @@ -642,7 +619,7 @@ def print_1_device_traversal(i, j, k): return func+"="+log+" " else: return func+"="+"X"+" " - + def device_traversal(): if system_ready()==False: print("System's not ready.") @@ -666,18 +643,18 @@ def device_traversal(): if ret == False: continue log = print_1_device_traversal(i, j, k) - print log, + print log, if k.find('present')!= -1: ret, k = get_path_sfp_presence(port_index) if ret == False: continue log = print_1_device_traversal(i, j, k) - print log, - + print log, + else: for k in (ALL_DEVICE[i][j]): log = print_1_device_traversal(i, j, k) - print log, + print log, print print("----------------------------------------------------------------") @@ -686,9 +663,9 @@ def device_traversal(): return def device_exist(): - ret1, log = log_os_system("ls "+i2c_prefix+"*0070", 0) - ret2, log = log_os_system("ls "+i2c_prefix+"i2c-2", 0) - return not(ret1 or ret2) + ret1 = log_os_system("ls "+i2c_prefix+"*0070", 0) + ret2 = log_os_system("ls "+i2c_prefix+"i2c-2", 0) + return not(ret1[0] or ret2[0]) if __name__ == "__main__": main() diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_monitor.py index c8574557b3d1..6f55e703d7d1 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_monitor.py @@ -23,19 +23,13 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback import signal - from tabulate import tabulate from as5812_54t.fanutil import FanUtil from as5812_54t.thermalutil import ThermalUtil except ImportError as e: diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_util.py b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_util.py index cad526e17af5..3859c3279c45 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_util.py @@ -30,13 +30,12 @@ set : change board setting with fan|led|sfp """ -import os import commands -import sys, getopt +import getopt +import sys import logging import re import time -from collections import namedtuple @@ -146,11 +145,12 @@ def log_os_system(cmd, show): return status, output def driver_check(): - ret, lsmod = log_os_system("lsmod| grep accton", 0) + ret, lsmod = log_os_system("ls /sys/module/*accton*", 0) logging.info('mods:'+lsmod) - if len(lsmod) ==0: - return False - return True + if ret : + return False + else : + return True kos = [ 'modprobe i2c_dev', diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/leds-accton_as5812_54x.c b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/leds-accton_as5812_54x.c index 2ebe948612c2..430a16db11e1 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/leds-accton_as5812_54x.c +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/leds-accton_as5812_54x.c @@ -34,7 +34,6 @@ extern int as5812_54x_cpld_read (unsigned short cpld_addr, u8 reg); extern int as5812_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); extern void led_classdev_unregister(struct led_classdev *led_cdev); -extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); extern void led_classdev_resume(struct led_classdev *led_cdev); extern void led_classdev_suspend(struct led_classdev *led_cdev); diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54x/utils/accton_as5812_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/utils/accton_as5812_monitor.py index 8c7303efaa78..5e3b368659cc 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5812-54x/utils/accton_as5812_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/utils/accton_as5812_monitor.py @@ -23,19 +23,13 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback import signal - from tabulate import tabulate from as5812_54x.fanutil import FanUtil from as5812_54x.thermalutil import ThermalUtil except ImportError as e: diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54x/utils/accton_as5812_util.py b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/utils/accton_as5812_util.py index eb1b22f3ef0d..464c85745f90 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5812-54x/utils/accton_as5812_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/utils/accton_as5812_util.py @@ -31,12 +31,11 @@ import os import commands -import sys, getopt +import getopt +import sys import logging import re import time -import pickle -from collections import namedtuple PROJECT_NAME = 'as5812_54x' version = '0.2.0' @@ -81,7 +80,6 @@ 'sfp': ['sfp_is_present ', 'sfp_tx_disable']} QSFP_START = 48 -I2C_BUS_ORDER = -1 sfp_map = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, @@ -242,10 +240,12 @@ def log_os_system(cmd, show): return status, output def driver_inserted(): - ret, lsmod = log_os_system("lsmod| grep accton", 0) + ret, lsmod = log_os_system("ls /sys/module/*accton*", 0) logging.info('mods:'+lsmod) - if len(lsmod) ==0: + if ret : return False + else : + return True @@ -294,38 +294,23 @@ def driver_uninstall(): def i2c_order_check(): # i2c bus 0 and 1 might be installed in different order. # Here check if 0x70 is exist @ i2c-0 - tmp = "echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-1/new_device" - status, output = log_os_system(tmp, 0) - if not device_exist(): + tmp = "i2cget -y -f 0 0x70" + ret = log_os_system(tmp, 0) + if not ret[0]: order = 1 else: order = 0 - tmp = "echo 0x70 > /sys/bus/i2c/devices/i2c-1/delete_device" - status, output = log_os_system(tmp, 0) + m = "[%s]Detected I2C_BUS_ORDER:%d" % (os.path.basename(__file__), order) + my_log(m) return order -def update_i2c_order(): - global I2C_BUS_ORDER - - order = i2c_order_check() - pickle.dump(order, open("/tmp/accton_util.p", "wb")) # save it - I2C_BUS_ORDER = order - print "[%s]Detected I2C_BUS_ORDER:%d" % (os.path.basename(__file__), I2C_BUS_ORDER) - def get_i2c_order(): - global I2C_BUS_ORDER - if I2C_BUS_ORDER < 0: - if os.path.exists("/tmp/accton_util.p"): - I2C_BUS_ORDER = pickle.load(open("/tmp/accton_util.p", "rb")) - else: - update_i2c_order() + return i2c_order_check() def device_install(): global FORCE - global I2C_BUS_ORDER - update_i2c_order() - order = I2C_BUS_ORDER + order = get_i2c_order() # if 0x76 is not exist @i2c-0, use reversed bus order if order: for i in range(0,len(mknod2)): @@ -349,7 +334,7 @@ def device_install(): print output if FORCE == 0: return status - + for i in range(0,len(sfp_map)): if i < QSFP_START: status, output =log_os_system("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) @@ -364,15 +349,12 @@ def device_install(): print output if FORCE == 0: return status - + return def device_uninstall(): global FORCE - global I2C_BUS_ORDER - get_i2c_order() - order = I2C_BUS_ORDER 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) @@ -381,6 +363,7 @@ def device_uninstall(): if FORCE == 0: return status + order = get_i2c_order() if order == 0: nodelist = mknod else: @@ -533,19 +516,15 @@ def show_eeprom(index): def get_cpld_path(index): - global I2C_BUS_ORDER - - if I2C_BUS_ORDER < 0: - get_i2c_order() - - if I2C_BUS_ORDER !=0 : + order = get_i2c_order() + if order !=0 : return port_cpld_path[index].replace("0-", "1-") else: return port_cpld_path[index] def cpld_path_of_port(port_index): if port_index < 1 and port_index > DEVICE_NO['sfp']: - return None + return None if port_index < 25: return get_cpld_path(0) else: @@ -553,19 +532,19 @@ def cpld_path_of_port(port_index): def get_path_sfp_tx_dis(port_index): cpld_p = cpld_path_of_port(port_index) - if cpld_p == None: + if cpld_p is None: return False, '' else: dev = cpld_p+"module_tx_disable_"+str(port_index) - return True, dev + return True, dev def get_path_sfp_presence(port_index): cpld_p = cpld_path_of_port(port_index) - if cpld_p == None: + if cpld_p is None: return False, '' else: dev = cpld_p+"module_present_"+str(port_index) - return True, dev + return True, dev def set_device(args): @@ -642,7 +621,7 @@ def print_1_device_traversal(i, j, k): return func+"="+log+" " else: return func+"="+"X"+" " - + def device_traversal(): if system_ready()==False: print("System's not ready.") @@ -666,18 +645,18 @@ def device_traversal(): if ret == False: continue log = print_1_device_traversal(i, j, k) - print log, + print log, if k.find('present')!= -1: ret, k = get_path_sfp_presence(port_index) if ret == False: continue log = print_1_device_traversal(i, j, k) - print log, - + print log, + else: for k in (ALL_DEVICE[i][j]): log = print_1_device_traversal(i, j, k) - print log, + print log, print print("----------------------------------------------------------------") diff --git a/platform/broadcom/sonic-platform-modules-accton/as5835-54t/modules/accton_as5835_54t_cpld.c b/platform/broadcom/sonic-platform-modules-accton/as5835-54t/modules/accton_as5835_54t_cpld.c old mode 100644 new mode 100755 index ae773b4d8209..9765fd430432 --- a/platform/broadcom/sonic-platform-modules-accton/as5835-54t/modules/accton_as5835_54t_cpld.c +++ b/platform/broadcom/sonic-platform-modules-accton/as5835-54t/modules/accton_as5835_54t_cpld.c @@ -225,7 +225,7 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da, struct i2c_client *client = to_i2c_client(dev); struct as5835_54t_cpld_data *data = i2c_get_clientdata(client); int status = 0; - u8 reg = 0, mask = 0, revert = 0; + u8 reg = 0, mask = 0, invert = 0; switch (attr->index) { case MODULE_PRESENT_49 ... MODULE_PRESENT_54: @@ -239,13 +239,14 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da, case MODULE_RESET_49 ... MODULE_RESET_54: reg = 0x15; mask = 0x1 << (attr->index - MODULE_RESET_49); + invert = 1; break; default: return 0; } if (attr->index >= MODULE_PRESENT_49 && attr->index <= MODULE_PRESENT_54) { - revert = 1; + invert = 1; } mutex_lock(&data->update_lock); @@ -255,7 +256,7 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da, } mutex_unlock(&data->update_lock); - return sprintf(buf, "%d\n", revert ? !(status & mask) : !!(status & mask)); + return sprintf(buf, "%d\n", invert ? !(status & mask) : !!(status & mask)); exit: mutex_unlock(&data->update_lock); @@ -298,6 +299,9 @@ static ssize_t set_control(struct device *dev, struct device_attribute *da, } /* Update tx_disable/lpmode/reset status */ + if (attr->index >= MODULE_RESET_49 && attr->index <= MODULE_RESET_54) { + value = !value; + } if (value) { status |= mask; } diff --git a/platform/broadcom/sonic-platform-modules-accton/as5835-54t/utils/accton_as5835_54t_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as5835-54t/utils/accton_as5835_54t_monitor.py index ce2e0d18d4ff..ceea8e12f852 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5835-54t/utils/accton_as5835_54t_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5835-54t/utils/accton_as5835_54t_monitor.py @@ -25,18 +25,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config - import types import time # this is only being used as part of the example - import traceback import signal - from tabulate import tabulate from as5835_54t.fanutil import FanUtil from as5835_54t.thermalutil import ThermalUtil except ImportError as e: @@ -203,4 +197,4 @@ def main(argv): time.sleep(10) if __name__ == '__main__': - main(sys.argv[1:]) \ No newline at end of file + main(sys.argv[1:]) diff --git a/platform/broadcom/sonic-platform-modules-accton/as5835-54t/utils/accton_as5835_54t_monitor_fan.py b/platform/broadcom/sonic-platform-modules-accton/as5835-54t/utils/accton_as5835_54t_monitor_fan.py index d1d93d4f8aea..7978012b0da0 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5835-54t/utils/accton_as5835_54t_monitor_fan.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5835-54t/utils/accton_as5835_54t_monitor_fan.py @@ -22,18 +22,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate except ImportError as e: raise ImportError('%s - required module not found' % str(e)) diff --git a/platform/broadcom/sonic-platform-modules-accton/as5835-54t/utils/accton_as5835_54t_monitor_psu.py b/platform/broadcom/sonic-platform-modules-accton/as5835-54t/utils/accton_as5835_54t_monitor_psu.py index 51837c7262ba..9be72fda9993 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5835-54t/utils/accton_as5835_54t_monitor_psu.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5835-54t/utils/accton_as5835_54t_monitor_psu.py @@ -22,18 +22,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate except ImportError as e: raise ImportError('%s - required module not found' % str(e)) diff --git a/platform/broadcom/sonic-platform-modules-accton/as5835-54t/utils/accton_as5835_54t_util.py b/platform/broadcom/sonic-platform-modules-accton/as5835-54t/utils/accton_as5835_54t_util.py index a07ab1a1bc7e..48e49cbaba13 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5835-54t/utils/accton_as5835_54t_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5835-54t/utils/accton_as5835_54t_util.py @@ -30,13 +30,12 @@ set : change board setting with fan|led|sfp """ -import os import commands -import sys, getopt +import getopt +import sys import logging import re import time -from collections import namedtuple @@ -146,11 +145,12 @@ def log_os_system(cmd, show): return status, output def driver_check(): - ret, lsmod = log_os_system("lsmod| grep accton", 0) + ret, lsmod = log_os_system("ls /sys/module/*accton*", 0) logging.info('mods:'+lsmod) - if len(lsmod) ==0: - return False - return True + if ret : + return False + else : + return True @@ -291,6 +291,9 @@ def device_install(): print output if FORCE == 0: return status + for i in range(49, 55): #Set qsfp port to normal state + log_os_system("echo 0 > /sys/bus/i2c/devices/3-0062/module_reset_" + str(i), 1) + for i in range(0,len(sfp_map)): status, output =log_os_system("echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) if status: diff --git a/platform/broadcom/sonic-platform-modules-accton/as5835-54x/modules/accton_as5835_54x_cpld.c b/platform/broadcom/sonic-platform-modules-accton/as5835-54x/modules/accton_as5835_54x_cpld.c old mode 100644 new mode 100755 index c9d4f1c31e5e..97b7d879f03a --- a/platform/broadcom/sonic-platform-modules-accton/as5835-54x/modules/accton_as5835_54x_cpld.c +++ b/platform/broadcom/sonic-platform-modules-accton/as5835-54x/modules/accton_as5835_54x_cpld.c @@ -678,7 +678,7 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da, struct i2c_client *client = to_i2c_client(dev); struct as5835_54x_cpld_data *data = i2c_get_clientdata(client); int status = 0; - u8 reg = 0, mask = 0, revert = 0; + u8 reg = 0, mask = 0, invert = 0; switch (attr->index) { case MODULE_PRESENT_1 ... MODULE_PRESENT_8: @@ -804,13 +804,14 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da, case MODULE_RESET_49 ... MODULE_RESET_54: reg = 0x15; mask = 0x1 << (attr->index - MODULE_RESET_49); + invert = 1; break; default: return 0; } if (attr->index >= MODULE_PRESENT_1 && attr->index <= MODULE_PRESENT_54) { - revert = 1; + invert = 1; } mutex_lock(&data->update_lock); @@ -820,7 +821,7 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da, } mutex_unlock(&data->update_lock); - return sprintf(buf, "%d\n", revert ? !(status & mask) : !!(status & mask)); + return sprintf(buf, "%d\n", invert ? !(status & mask) : !!(status & mask)); exit: mutex_unlock(&data->update_lock); @@ -891,6 +892,9 @@ static ssize_t set_control(struct device *dev, struct device_attribute *da, } /* Update tx_disable/lpmode/reset status */ + if (attr->index >= MODULE_RESET_49 && attr->index <= MODULE_RESET_54) { + value = !value; + } if (value) { status |= mask; } diff --git a/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_monitor.py index 5789288546b6..9c5e955ce17d 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_monitor.py @@ -24,18 +24,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config - import types import time # this is only being used as part of the example - import traceback import signal - from tabulate import tabulate from as5835_54x.fanutil import FanUtil from as5835_54x.thermalutil import ThermalUtil except ImportError as e: @@ -202,4 +196,4 @@ def main(argv): time.sleep(10) if __name__ == '__main__': - main(sys.argv[1:]) \ No newline at end of file + main(sys.argv[1:]) diff --git a/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_monitor_fan.py b/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_monitor_fan.py index 791c80a92b89..dec1e036142d 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_monitor_fan.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_monitor_fan.py @@ -22,18 +22,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate except ImportError as e: raise ImportError('%s - required module not found' % str(e)) diff --git a/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_monitor_psu.py b/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_monitor_psu.py index d7bd1a1f2515..f994d635239a 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_monitor_psu.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_monitor_psu.py @@ -22,18 +22,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate except ImportError as e: raise ImportError('%s - required module not found' % str(e)) diff --git a/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_util.py b/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_util.py index fbe3866ad566..738a1766fbef 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5835-54x/utils/accton_as5835_54x_util.py @@ -21,22 +21,21 @@ 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 import commands -import sys, getopt +import getopt +import sys import logging import re import time -from collections import namedtuple @@ -46,7 +45,7 @@ verbose = False DEBUG = False args = [] -ALL_DEVICE = {} +ALL_DEVICE = {} DEVICE_NO = {'led':5, 'fan':5,'thermal':4, 'psu':2, 'sfp':54} FORCE = 0 #logging.basicConfig(filename= PROJECT_NAME+'.log', filemode='w',level=logging.DEBUG) @@ -55,37 +54,37 @@ 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': @@ -95,23 +94,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) @@ -120,37 +119,38 @@ 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) - + print " use \""+ cmd + " fan 0-100\" to set fan duty percetage" + print " use \""+ cmd + " sfp 1-48 {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) - + print " use \""+ cmd + " 1-54 \" to dump sfp# eeprom" + sys.exit(0) + def my_log(txt): if DEBUG == True: - print "[Debug]"+txt + print "[Debug]"+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(): - ret, lsmod = log_os_system("lsmod| grep accton", 0) + ret, lsmod = log_os_system("ls /sys/module/*accton*", 0) logging.info('mods:'+lsmod) - if len(lsmod) ==0: - return False - return True + if ret : + return False + else : + return True @@ -166,30 +166,30 @@ def driver_check(): def driver_install(): global FORCE - status, output = log_os_system("depmod", 1) + log_os_system("depmod", 1) for i in range(0,len(kos)): - status, output = log_os_system(kos[i], 1) - if status: - if FORCE == 0: - return status + ret = log_os_system(kos[i], 1) + if ret[0]: + if FORCE == 0: + return ret[0] 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") lst = rm.split(" ") if len(lst) > 3: del(lst[3]) - rm = " ".join(lst) - status, output = log_os_system(rm, 1) - if status: - if FORCE == 0: - return status + rm = " ".join(lst) + ret = log_os_system(rm, 1) + if ret[0]: + if FORCE == 0: + return ret[0] return 0 -led_prefix ='/sys/class/leds/accton_'+PROJECT_NAME+'_led::' +led_prefix ='/sys/class/leds/'+PROJECT_NAME+'_led::' hwmon_types = {'led': ['diag','fan','loc','psu1','psu2']} hwmon_nodes = {'led': ['brightness'] } hwmon_prefix ={'led': led_prefix} @@ -197,13 +197,13 @@ def driver_uninstall(): i2c_prefix = '/sys/bus/i2c/devices/' i2c_bus = {'fan': ['3-0063'] , 'thermal': ['18-004b','19-004c', '20-0049', '21-004a'] , - 'psu': ['11-0050','12-0053'], + 'psu': ['11-0050','12-0053'], 'sfp': ['-0050']} i2c_nodes = {'fan': ['present', 'front_speed_rpm', 'rear_speed_rpm'] , 'thermal': ['hwmon/hwmon*/temp1_input'] , 'psu': ['psu_present ', 'psu_power_good'] , 'sfp': ['module_present_', 'module_tx_disable_']} - + sfp_map = [42,43,44,45,46,47,48,49,50,51, 52,53,54,55,56,57,58,59,60,61, 62,63,64,65,66,67,68,69,70,71, @@ -213,7 +213,11 @@ def driver_uninstall(): qsfp_start = 48 -mknod =[ +#For sideband signals of SFP/QSFP modules. +cpld_of_module = {'3-0061': list(range(0,38)), + '3-0062': list(range(38,54)) } + +mknod =[ 'echo pca9548 0x77 > /sys/bus/i2c/devices/i2c-1/new_device', 'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-2/new_device' , 'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-2/new_device' , @@ -240,7 +244,7 @@ def driver_uninstall(): 'echo as5835_54x_cpld2 0x61 > /sys/bus/i2c/devices/i2c-3/new_device', 'echo as5835_54x_cpld3 0x62 > /sys/bus/i2c/devices/i2c-3/new_device'] -mknod2 =[ +mknod2 =[ 'echo pca9548 0x77 > /sys/bus/i2c/devices/i2c-0/new_device', 'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-2/new_device' , 'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-2/new_device' , @@ -266,50 +270,52 @@ def driver_uninstall(): 'echo as5835_54x_cpld1 0x60 > /sys/bus/i2c/devices/i2c-3/new_device', 'echo as5835_54x_cpld2 0x61 > /sys/bus/i2c/devices/i2c-3/new_device', 'echo as5835_54x_cpld3 0x62 > /sys/bus/i2c/devices/i2c-3/new_device'] - - -def i2c_order_check(): + + +def i2c_order_check(): # i2c bus 0 and 1 might be installed in different order. # Here check if 0x77 is exist @ i2c-1 - tmp = "echo pca9548 0x77 > /sys/bus/i2c/devices/i2c-1/new_device" - status, output = log_os_system(tmp, 0) - if not device_exist(): + tmp = "i2cget -y -f 0 0x77" + ret = log_os_system(tmp, 0) + if not ret[0]: order = 1 else: order = 0 - tmp = "echo 0x77 > /sys/bus/i2c/devices/i2c-1/delete_device" - status, output = log_os_system(tmp, 0) return order - + def device_install(): global FORCE - + order = i2c_order_check() - - # if 0x77 is not exist @i2c-1, use reversed bus order - if order: + + # if 0x77 is not exist @i2c-1, use reversed bus order + if order: for i in range(0,len(mknod2)): - #for pca954x need times to built new i2c buses + #for pca954x need times to built new i2c buses if mknod2[i].find('pca954') != -1: - time.sleep(1) - + time.sleep(1) + status, output = log_os_system(mknod2[i], 1) time.sleep(0.01) if status: print output if FORCE == 0: - return status + return status else: for i in range(0,len(mknod)): - #for pca954x need times to built new i2c buses + #for pca954x need times to built new i2c buses if mknod[i].find('pca954') != -1: - time.sleep(1) - + time.sleep(1) + status, output = log_os_system(mknod[i], 1) if status: print output - if FORCE == 0: - return status + if FORCE == 0: + return status + + for i in range(49, 55): #Set qsfp port to normal state + log_os_system("echo 0 > /sys/bus/i2c/devices/3-0062/module_reset_" + str(i), 1) + for i in range(0,len(sfp_map)): if i < qsfp_start: status, output =log_os_system("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) @@ -317,32 +323,27 @@ def device_install(): status, output =log_os_system("echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) if status: print output - if FORCE == 0: - return status - return - + if FORCE == 0: + return status + return + def device_uninstall(): global FORCE - - status, output =log_os_system("ls /sys/bus/i2c/devices/0-0077", 0) - if status==0: - I2C_ORDER=1 - else: - I2C_ORDER=0 for i in range(0,len(sfp_map)): target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device" status, output =log_os_system("echo 0x50 > "+ target, 1) if status: print output - if FORCE == 0: + if FORCE == 0: return status - - if I2C_ORDER==0: - nodelist = mknod - else: + + order = i2c_order_check() + if order: nodelist = mknod2 - + else: + nodelist = mknod + for i in range(len(nodelist)): target = nodelist[-(i+1)] temp = target.split() @@ -351,72 +352,72 @@ 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 - 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 'fan' == key: @@ -424,169 +425,171 @@ def devices_info(): node = key+str(k+1) path = i2c_prefix+ buses[i]+"/fan"+str(k+1)+"_"+ nodes[j] my_log(node+": "+ path) - ALL_DEVICE[key][node].append(path) + ALL_DEVICE[key][node].append(path) elif 'sfp' == key: for k in range(0,DEVICE_NO[key]): - node = key+str(k+1) - path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j] - my_log(node+": "+ path) - ALL_DEVICE[key][node].append(path) + for lk in cpld_of_module: + if k in cpld_of_module[lk]: + node = key+str(k+1) + path = i2c_prefix + lk + "/"+ nodes[j] + str(k+1) + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) else: node = key+str(i+1) - path = i2c_prefix+ buses[i]+"/"+ nodes[j] + 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) + #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) - if len(log): + ret, log2 = log_os_system("which busybox hexdump", 0) + if log : hex_cmd = 'hexdump' - elif len(log2): + elif log2 : hex_cmd = ' busybox hexdump' else: 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)]): - ret, log = log_os_system("echo "+args[1]+" >"+k, 1) - if ret: - return ret + for i in range(0,len(ALL_DEVICE['led'])): + for k in (ALL_DEVICE['led']['led'+str(i+1)]): + ret = log_os_system("echo "+args[1]+" >"+k, 1) + if ret[0]: + return ret[0] elif args[0]=='fan': if int(args[1])>100: show_set_help() return #print ALL_DEVICE['fan'] - #fan1~5 is all fine, all fan share same setting - node = ALL_DEVICE['fan'] ['fan1'][0] + #fan1~5 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 + ret = log_os_system("cat "+ node, 1) + if ret[0] == 0: + print ("Previous fan duty: " + log.strip() +"%") + ret = log_os_system("echo "+args[1]+" >"+node, 1) + if ret[0] == 0: + print ("Current fan duty: " + args[1] +"%") + return ret[0] elif args[0]=='sfp': - if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0: + if int(args[1])> qsfp_start 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: - ret, log = log_os_system("echo "+args[2]+" >"+ j, 1) - if ret: - return ret - + + #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_os_system("echo "+args[2]+" >"+ j, 1) + if ret[0]: + return ret[0] + return - -#get digits inside a string. -#Ex: 31 for "sfp31" + +#get digits inside a string. +#Ex: 31 for "sfp31" def get_value(input): digit = re.findall('\d+', input) return int(digit[0]) - + def device_traversal(): if system_ready()==False: - print("System's not ready.") + print("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): + + for j in sorted(ALL_DEVICE[i].keys(), key=get_value): print " "+j+":", for k in (ALL_DEVICE[i][j]): ret, log = log_os_system("cat "+k, 0) func = k.split("/")[-1].strip() func = re.sub(j+'_','',func,1) - func = re.sub(i.lower()+'_','',func,1) + 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-2", 0) - return not(ret1 or ret2) + ret1 = log_os_system("ls "+i2c_prefix+"*0077", 0) + ret2 = log_os_system("ls "+i2c_prefix+"i2c-2", 0) + return not(ret1[0] or ret2[0]) if __name__ == "__main__": main() diff --git a/platform/broadcom/sonic-platform-modules-accton/as6712-32x/modules/leds-accton_as6712_32x.c b/platform/broadcom/sonic-platform-modules-accton/as6712-32x/modules/leds-accton_as6712_32x.c index 2b45bc8777c8..6e5c1d2118e4 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as6712-32x/modules/leds-accton_as6712_32x.c +++ b/platform/broadcom/sonic-platform-modules-accton/as6712-32x/modules/leds-accton_as6712_32x.c @@ -33,7 +33,6 @@ extern int as6712_32x_cpld_read (unsigned short cpld_addr, u8 reg); extern int as6712_32x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); extern void led_classdev_unregister(struct led_classdev *led_cdev); -extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); extern void led_classdev_resume(struct led_classdev *led_cdev); extern void led_classdev_suspend(struct led_classdev *led_cdev); diff --git a/platform/broadcom/sonic-platform-modules-accton/as6712-32x/utils/accton_as6712_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as6712-32x/utils/accton_as6712_monitor.py index fbcc74565d62..07e40f6b7fb4 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as6712-32x/utils/accton_as6712_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as6712-32x/utils/accton_as6712_monitor.py @@ -24,17 +24,11 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate from as6712_32x.fanutil import FanUtil from as6712_32x.thermalutil import ThermalUtil except ImportError as e: diff --git a/platform/broadcom/sonic-platform-modules-accton/as6712-32x/utils/accton_as6712_util.py b/platform/broadcom/sonic-platform-modules-accton/as6712-32x/utils/accton_as6712_util.py index 48e957e31257..10cdac787309 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as6712-32x/utils/accton_as6712_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as6712-32x/utils/accton_as6712_util.py @@ -37,13 +37,12 @@ set : change board setting with fan|led|sfp """ -import os import commands -import sys, getopt +import getopt +import sys import logging import re import time -from collections import namedtuple PROJECT_NAME = 'as6712_32x' version = '0.2.0' @@ -250,10 +249,12 @@ def log_os_system(cmd, show): return status, output def driver_inserted(): - ret, lsmod = log_os_system("lsmod| grep accton", 0) + ret, lsmod = log_os_system("ls /sys/module/*accton*", 0) logging.info('mods:'+lsmod) - if len(lsmod) ==0: + if ret : return False + else : + return True diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/classes/fanutil.py b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/classes/fanutil.py index 207436c1fc96..92e79da72746 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/classes/fanutil.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/classes/fanutil.py @@ -100,26 +100,17 @@ def _get_fan_node_val(self, fan_num, node_num): return None device_path = self.get_fan_to_device_path(fan_num, node_num) - try: - val_file = open(device_path, 'r') + with open(device_path, 'r') as val_file: + content = val_file.readline().rstrip() + if not content: + logging.debug('GET. content is NULL, path:%s', device_path) + return None except IOError as e: - logging.error('GET. unable to open file: %s', str(e)) - return None - - content = val_file.readline().rstrip() - - if content == '': - logging.debug('GET. content is NULL. device_path:%s', device_path) - return None - - try: - val_file.close() - except: - logging.debug('GET. unable to close file. device_path:%s', device_path) - return None + logging.error('GET. unable to read file: %s', str(e)) + else: + return int(content) - return int(content) def _set_fan_node_val(self, fan_num, node_num, val): if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: @@ -137,19 +128,11 @@ def _set_fan_node_val(self, fan_num, node_num, val): device_path = self.get_fan_to_device_path(fan_num, node_num) try: - val_file = open(device_path, 'w') + with open(device_path, 'w') as val_file: + val_file.write(content) except IOError as e: logging.error('GET. unable to open file: %s', str(e)) return None - - val_file.write(content) - - try: - val_file.close() - except: - logging.debug('GET. unable to close file. device_path:%s', device_path) - return None - return True def __init__(self): @@ -193,32 +176,20 @@ def get_fan_dir(self, fan_num): def get_fan_duty_cycle(self): #duty_path = self.FAN_DUTY_PATH try: - val_file = open(self.FAN_DUTY_PATH) + with open(self.FAN_DUTY_PATH) as val_file: + content = val_file.readline().rstrip() except IOError as e: print "Error: unable to open file: %s" % str(e) return False - - content = val_file.readline().rstrip() - val_file.close() - return int(content) - #self._get_fan_node_val(fan_num, self.FAN_NODE_DUTY_IDX_OF_MAP) -#static u32 reg_val_to_duty_cycle(u8 reg_val) -#{ -# reg_val &= FAN_DUTY_CYCLE_REG_MASK; -# return ((u32)(reg_val+1) * 625 + 75)/ 100; -#} -# + def set_fan_duty_cycle(self, val): - try: - fan_file = open(self.FAN_DUTY_PATH, 'r+') + with open(self.FAN_DUTY_PATH, 'r+') as val_file: + val_file.write(str(val)) except IOError as e: print "Error: unable to open file: %s" % str(e) return False - #val = ((val + 1 ) * 625 +75 ) / 100 - fan_file.write(str(val)) - fan_file.close() return True #def get_fanr_fault(self, fan_num): diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/classes/thermalutil.py b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/classes/thermalutil.py index 68f0ef900df6..4b3868ee6ec9 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/classes/thermalutil.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/classes/thermalutil.py @@ -69,26 +69,19 @@ def _get_thermal_node_val(self, thermal_num): device_path = self.get_thermal_to_device_path(thermal_num) for filename in glob.glob(device_path): try: - val_file = open(filename, 'r') + with open(filename, 'r') as val_file: + val_file = open(filename, 'r') + content = val_file.readline().rstrip() + if not content : + logging.debug('File is NULL. path:%s', device_path) + return None + else: + return int(content) except IOError as e: logging.error('GET. unable to open file: %s', str(e)) - return None - content = val_file.readline().rstrip() - - if content == '': - logging.debug('GET. content is NULL. device_path:%s', device_path) - return None - - try: - val_file.close() - except: - logging.debug('GET. unable to close file. device_path:%s', device_path) - return None + return None - return int(content) - - def get_num_thermals(self): return self.THERMAL_NUM_ON_MAIN_BROAD diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_leds.c b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_leds.c index 1d54517c6243..f53716440107 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_leds.c +++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_leds.c @@ -34,7 +34,6 @@ extern int as7312_54x_cpld_read (unsigned short cpld_addr, u8 reg); extern int as7312_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); extern void led_classdev_unregister(struct led_classdev *led_cdev); -extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); extern void led_classdev_resume(struct led_classdev *led_cdev); extern void led_classdev_suspend(struct led_classdev *led_cdev); diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/sonic_platform_setup.py b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/sonic_platform_setup.py new file mode 100755 index 000000000000..672fe89cef6c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/sonic_platform_setup.py @@ -0,0 +1,34 @@ +from setuptools import setup + +DEVICE_NAME = 'accton' +HW_SKU = 'x86_64-accton_as7312_54x-r0' + +setup( + name='sonic-platform', + version='1.0', + description='SONiC platform API implementation on Accton Platforms', + license='Apache 2.0', + author='SONiC Team', + author_email='linuxnetdev@microsoft.com', + url='https://github.com/Azure/sonic-buildimage', + maintainer='Jostar Yang', + maintainer_email='jostar_yang@edge-core.com', + packages=[ + 'sonic_platform', + ], + package_dir={ + 'sonic_platform': '../../../../device/{}/{}/sonic_platform'.format(DEVICE_NAME, HW_SKU)}, + classifiers=[ + 'Development Status :: 3 - Alpha', + 'Environment :: Plugins', + 'Intended Audience :: Developers', + 'Intended Audience :: Information Technology', + 'Intended Audience :: System Administrators', + 'License :: OSI Approved :: Apache Software License', + 'Natural Language :: English', + 'Operating System :: POSIX :: Linux', + 'Programming Language :: Python :: 3.7', + 'Topic :: Utilities', + ], + keywords='sonic SONiC platform PLATFORM', +) diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/accton_as7312_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/accton_as7312_monitor.py index 19d7470515f9..2f87c3f58736 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/accton_as7312_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/accton_as7312_monitor.py @@ -24,18 +24,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config - import types import time # this is only being used as part of the example - import traceback import signal - from tabulate import tabulate from as7312_54x.fanutil import FanUtil from as7312_54x.thermalutil import ThermalUtil except ImportError as e: @@ -78,6 +72,7 @@ class accton_as7312_monitor(object): _new_perc = 0 _ori_perc = 0 + def __init__(self, log_file, log_level): """Needs a logger and a logger level.""" # set up logging to file @@ -99,6 +94,9 @@ def __init__(self, log_file, log_level): logging.debug('SET. logfile:%s / loglevel:%d', log_file, log_level) + self.thermal = ThermalUtil() + self.fan = FanUtil() + def manage_fans(self): max_duty = DUTY_MAX fan_policy_f2b = { @@ -119,8 +117,8 @@ def manage_fans(self): 2: 50000, } - thermal = ThermalUtil() - fan = FanUtil() + thermal = self.thermal + fan = self.fan for x in range(fan.get_idx_fan_start(), fan.get_num_fans()+1): fan_status = fan.get_fan_status(x) if fan_status is None: diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/accton_as7312_util.py b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/accton_as7312_util.py index b8107c47afea..e2f058b4e37a 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/accton_as7312_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/accton_as7312_util.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# # Copyright (C) 2016 Accton Networks, Inc. # # This program is free software: you can redistribute it and/or modify @@ -21,568 +20,629 @@ 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 import commands -import sys, getopt +import getopt +import sys import logging import re import time -from collections import namedtuple - - - +import os PROJECT_NAME = 'as7312_54x' version = '0.1.0' verbose = False DEBUG = False -args = [] -ALL_DEVICE = {} -DEVICE_NO = {'led':5, 'fan':6,'thermal':4, 'psu':2, 'sfp':54} +ARGS = [] +ALL_DEVICE = {} +DEVICE_NO = { + 'led': 5, + 'fan': 6, + 'thermal': 4, + 'psu': 2, + 'sfp': 54, + } FORCE = 0 -#logging.basicConfig(filename= PROJECT_NAME+'.log', filemode='w',level=logging.DEBUG) -#logging.basicConfig(level=logging.INFO) +# logging.basicConfig(filename= PROJECT_NAME+'.log', filemode='w',level=logging.DEBUG) +# logging.basicConfig(level=logging.INFO) if DEBUG == True: print sys.argv[0] - print 'ARGV :', sys.argv[1:] + print 'ARGV :', sys.argv[1:] def main(): global DEBUG - global args + global ARGS global FORCE - - if len(sys.argv)<2: + + if len(sys.argv) < 2: show_help() - - options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', - 'debug', - 'force', - ]) - if DEBUG == True: + + (options, ARGS) = getopt.getopt(sys.argv[1:], 'hdf', + ['help','debug', 'force']) + if DEBUG == True: print options - print args + print ARGS print len(sys.argv) - - for opt, arg in options: + + 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() + do_install() elif arg == 'clean': - do_uninstall() + do_uninstall() + elif arg == 'api': + do_sonic_platform_install() + elif arg == 'api_clean': + do_sonic_platform_clean() elif arg == 'show': - device_traversal() + device_traversal() elif arg == 'sff': - if len(args)!=2: + 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: + 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]} + 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 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-48 {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 + print '[DBG]' + 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) + 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) + logging.info('Failed :' + cmd) if show: - print('Failed :'+cmd) - return status, output - + print 'Failed :' + cmd + return (status, output) + + def driver_check(): - ret, lsmod = log_os_system("lsmod| grep accton", 0) + ret, lsmod = log_os_system("ls /sys/module/*accton*", 0) logging.info('mods:'+lsmod) - if len(lsmod) ==0: - return False - return True - + if ret : + return False + else : + return True kos = [ -'modprobe i2c_dev', -'modprobe i2c_mux_pca954x force_deselect_on_exit=1', -'modprobe accton_i2c_cpld' , -'modprobe ym2651y' , -'modprobe accton_as7312_54x_fan' , -'modprobe optoe' , -'modprobe accton_as7312_54x_leds' , -'modprobe accton_as7312_54x_psu' ] + 'modprobe i2c_dev', + 'modprobe i2c_mux_pca954x force_deselect_on_exit=1', + 'modprobe accton_i2c_cpld', + 'modprobe ym2651y', + 'modprobe accton_as7312_54x_fan', + 'modprobe optoe', + 'modprobe accton_as7312_54x_leds', + 'modprobe accton_as7312_54x_psu', + ] + def driver_install(): global FORCE - status, output = log_os_system("depmod", 1) - for i in range(0,len(kos)): - status, output = log_os_system(kos[i], 1) - if status: - if FORCE == 0: - return status + log_os_system('depmod', 1) + for i in range(0, len(kos)): + ret = log_os_system(kos[i], 1) + if ret[0] and FORCE == 0: + return status return 0 - + + def driver_uninstall(): global FORCE - for i in range(0,len(kos)): - rm = kos[-(i+1)].replace("modprobe", "modprobe -rq") - rm = rm.replace("insmod", "rmmod") - lst = rm.split(" ") + for i in range(0, len(kos)): + rm = kos[-(i + 1)].replace('modprobe', 'modprobe -rq') + rm = rm.replace('insmod', 'rmmod') + lst = rm.split(' ') if len(lst) > 3: - del(lst[3]) - rm = " ".join(lst) - status, output = log_os_system(rm, 1) - if status: - if FORCE == 0: - return status + del lst[3] + rm = ' '.join(lst) + ret = log_os_system(rm, 1) + if ret[0] and FORCE == 0: + return ret[0] return 0 -led_prefix ='/sys/class/leds/accton_'+PROJECT_NAME+'_led::' -hwmon_types = {'led': ['diag','fan','loc','psu1','psu2']} -hwmon_nodes = {'led': ['brightness'] } -hwmon_prefix ={'led': led_prefix} + +led_prefix = '/sys/class/leds/accton_' + PROJECT_NAME + '_led::' +hwmon_types = {'led': ['diag', 'fan', 'loc', 'psu1', 'psu2']} +hwmon_nodes = {'led': ['brightness']} +hwmon_prefix = {'led': led_prefix} i2c_prefix = '/sys/bus/i2c/devices/' -i2c_bus = {'fan': ['2-0066'] , - 'thermal': ['3-0048','3-0049', '3-004a', '3-004b'] , - 'psu': ['10-0051','11-0053'], - 'sfp': ['-0050']} -i2c_nodes = {'fan': ['present', 'front_speed_rpm', 'rear_speed_rpm'] , - 'thermal': ['hwmon/hwmon*/temp1_input'] , - 'psu': ['psu_present ', 'psu_power_good'] , - 'sfp': ['sfp_is_present', 'sfp_tx_disable']} - -sfp_map = [18,19,20,21,22,23,24,25,26,27, - 28,29,30,31,32,33,34,35,36,37, - 38,39,40,41,42,43,44,45,46,47, - 48,49,50,51,52,53,54,55,56,57, - 58,59,60,61,62,63,64,65,66,67, - 68,69,70,71] +i2c_bus = { + 'fan': ['2-0066'], + 'thermal': ['3-0048', '3-0049', '3-004a', '3-004b'], + 'psu': ['10-0050', '11-0053'], + 'sfp': ['-0050'], + } +i2c_nodes = { + 'fan': ['present', 'front_speed_rpm', 'rear_speed_rpm'], + 'thermal': ['hwmon/hwmon*/temp1_input'], + 'psu': ['psu_present ', 'psu_power_good'], + 'sfp': ['module_present', 'module_tx_disable'], + } + +sfp_map = [18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71] qsfp_start = 48 -mknod =[ -'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-0/new_device', -'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-0/new_device' , -'echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-1/new_device' , -'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-1/new_device' , -'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-1/new_device', -'echo pca9548 0x75 > /sys/bus/i2c/devices/i2c-1/new_device', -'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-1/new_device', -'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-1/new_device', -'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-1/new_device', -'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-1/new_device', - -'echo as7312_54x_fan 0x66 > /sys/bus/i2c/devices/i2c-2/new_device ', -'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-3/new_device', -'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-3/new_device', -'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-3/new_device', -'echo lm75 0x4b > /sys/bus/i2c/devices/i2c-3/new_device', -'echo as7312_54x_psu1 0x53 > /sys/bus/i2c/devices/i2c-11/new_device', -'echo ym2651 0x5b > /sys/bus/i2c/devices/i2c-11/new_device', -'echo as7312_54x_psu2 0x50 > /sys/bus/i2c/devices/i2c-10/new_device', -'echo ym2651 0x58 > /sys/bus/i2c/devices/i2c-10/new_device', -'echo as7312_54x_cpld1 0x60 > /sys/bus/i2c/devices/i2c-4/new_device', -'echo as7312_54x_cpld2 0x62 > /sys/bus/i2c/devices/i2c-5/new_device', -'echo as7312_54x_cpld3 0x64 > /sys/bus/i2c/devices/i2c-6/new_device'] - -mknod2 =[ -'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-1/new_device', -'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-1/new_device' , -'echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-0/new_device' , -'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-0/new_device' , -'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-0/new_device', -'echo pca9548 0x75 > /sys/bus/i2c/devices/i2c-0/new_device', -'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-0/new_device', -'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-0/new_device', -'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-0/new_device', -'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-0/new_device', - -'echo as7312_54x_fan 0x66 > /sys/bus/i2c/devices/i2c-2/new_device ', -'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-3/new_device', -'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-3/new_device', -'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-3/new_device', -'echo lm75 0x4b > /sys/bus/i2c/devices/i2c-3/new_device', -'echo as7312_54x_psu1 0x53 > /sys/bus/i2c/devices/i2c-11/new_device', -'echo ym2651 0x5b > /sys/bus/i2c/devices/i2c-11/new_device', -'echo as7312_54x_psu2 0x50 > /sys/bus/i2c/devices/i2c-10/new_device', -'echo ym2651 0x58 > /sys/bus/i2c/devices/i2c-10/new_device', -'echo as7312_54x_cpld1 0x60 > /sys/bus/i2c/devices/i2c-4/new_device', -'echo as7312_54x_cpld2 0x62 > /sys/bus/i2c/devices/i2c-5/new_device', -'echo as7312_54x_cpld3 0x64 > /sys/bus/i2c/devices/i2c-6/new_device'] - - - -def i2c_order_check(): +mknod_common = [ + 'echo as7312_54x_fan 0x66 > /sys/bus/i2c/devices/i2c-2/new_device ', + 'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-3/new_device', + 'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-3/new_device', + 'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-3/new_device', + 'echo lm75 0x4b > /sys/bus/i2c/devices/i2c-3/new_device', + 'echo as7312_54x_psu1 0x53 > /sys/bus/i2c/devices/i2c-11/new_device', + 'echo ym2651 0x5b > /sys/bus/i2c/devices/i2c-11/new_device', + 'echo as7312_54x_psu2 0x50 > /sys/bus/i2c/devices/i2c-10/new_device', + 'echo ym2651 0x58 > /sys/bus/i2c/devices/i2c-10/new_device', + 'echo as7312_54x_cpld1 0x60 > /sys/bus/i2c/devices/i2c-4/new_device', + 'echo as7312_54x_cpld2 0x62 > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo as7312_54x_cpld3 0x64 > /sys/bus/i2c/devices/i2c-6/new_device'] + +mknod = [ + 'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-0/new_device', + 'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-0/new_device', + 'echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-1/new_device', + 'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-1/new_device', + 'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-1/new_device', + 'echo pca9548 0x75 > /sys/bus/i2c/devices/i2c-1/new_device', + 'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-1/new_device', + 'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-1/new_device', + 'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-1/new_device', + 'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-1/new_device',] +mknod = mknod + mknod_common + +mknod2 = [ + 'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-1/new_device', + 'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-1/new_device', + 'echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-0/new_device', + 'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-0/new_device', + 'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-0/new_device', + 'echo pca9548 0x75 > /sys/bus/i2c/devices/i2c-0/new_device', + 'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-0/new_device', + 'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-0/new_device', + 'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-0/new_device', + 'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-0/new_device',] + +mknod2 = mknod2 + mknod_common + + +def i2c_order_check(): # i2c bus 0 and 1 might be installed in different order. # Here check if 0x70 is exist @ i2c-1 - tmp = "echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-1/new_device" - status, output = log_os_system(tmp, 0) - if not device_exist(): + tmp = "i2cget -y -f 0 0x70" + ret = log_os_system(tmp, 0) + if not ret[0]: order = 1 else: order = 0 - tmp = "echo 0x70 > /sys/bus/i2c/devices/i2c-1/delete_device" - status, output = log_os_system(tmp, 0) return order - + + def device_install(): global FORCE - + order = i2c_order_check() - - # if 0x70 is not exist @i2c-1, use reversed bus order - if order: - for i in range(0,len(mknod2)): - #for pca954x need times to built new i2c buses + # if 0x70 is not exist @i2c-1, use reversed bus order + if order: + for i in range(0, len(mknod2)): + # for pca954x need times to built new i2c buses if mknod2[i].find('pca954') != -1: - time.sleep(1) - - status, output = log_os_system(mknod2[i], 1) + time.sleep(1) + + (status, output) = log_os_system(mknod2[i], 1) if status: print output if FORCE == 0: - return status + return status else: - for i in range(0,len(mknod)): - #for pca954x need times to built new i2c buses + for i in range(0, len(mknod)): + # for pca954x need times to built new i2c buses if mknod[i].find('pca954') != -1: - time.sleep(1) - - status, output = log_os_system(mknod[i], 1) + 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 FORCE == 0: + return status + for i in range(0, len(sfp_map)): if i < qsfp_start: - status, output =log_os_system("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) + (status, output) = \ + log_os_system('echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-' + + str(sfp_map[i]) + '/new_device', 1) else: - status, output =log_os_system("echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) + (status, output) = \ + log_os_system('echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-' + + str(sfp_map[i]) + '/new_device', 1) if status: print output - if FORCE == 0: - return status - return - + if FORCE == 0: + return status + return + def device_uninstall(): global FORCE - - status, output =log_os_system("ls /sys/bus/i2c/devices/1-0076", 0) - if status==0: - I2C_ORDER=1 - else: - I2C_ORDER=0 - for i in range(0,len(sfp_map)): - target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device" - status, output =log_os_system("echo 0x50 > "+ target, 1) + 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 - - if I2C_ORDER==0: - nodelist = mknod - else: + + order = i2c_order_check() + if order : nodelist = mknod2 - + else: + nodelist = mknod + for i in range(len(nodelist)): - target = nodelist[-(i+1)] + 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) + (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: + if driver_check() is False: return False - if not device_exist(): + if not device_exist(): return False return True - + +PLATFORM_ROOT_PATH = '/usr/share/sonic/device' +PLATFORM_API2_WHL_FILE_PY3 ='sonic_platform-1.0-py3-none-any.whl' +def do_sonic_platform_install(): + device_path = "{}{}{}{}".format(PLATFORM_ROOT_PATH, '/x86_64-accton_', PROJECT_NAME, '-r0') + SONIC_PLATFORM_BSP_WHL_PKG_PY3 = "/".join([device_path, PLATFORM_API2_WHL_FILE_PY3]) + + #Check API2.0 on py whl file + status, output = log_os_system("pip3 show sonic-platform > /dev/null 2>&1", 0) + if status: + if os.path.exists(SONIC_PLATFORM_BSP_WHL_PKG_PY3): + status, output = log_os_system("pip3 install "+ SONIC_PLATFORM_BSP_WHL_PKG_PY3, 1) + if status: + print "Error: Failed to install {}".format(PLATFORM_API2_WHL_FILE_PY3) + return status + else: + print "Successfully installed {} package".format(PLATFORM_API2_WHL_FILE_PY3) + else: + print('{} is not found'.format(PLATFORM_API2_WHL_FILE_PY3)) + else: + print('{} has installed'.format(PLATFORM_API2_WHL_FILE_PY3)) + + return + +def do_sonic_platform_clean(): + status, output = log_os_system("pip3 show sonic-platform > /dev/null 2>&1", 0) + if status: + print('{} does not install, not need to uninstall'.format(PLATFORM_API2_WHL_FILE_PY3)) + + else: + status, output = log_os_system("pip3 uninstall sonic-platform -y", 0) + if status: + print('Error: Failed to uninstall {}'.format(PLATFORM_API2_WHL_FILE_PY3)) + return status + else: + print('{} is uninstalled'.format(PLATFORM_API2_WHL_FILE_PY3)) + + return + def do_install(): - print "Checking system...." - if driver_check() == False: - print "No driver, installing...." + print 'Checking system....' + if driver_check() is False: + print 'No driver, installing....' status = driver_install() if status: - if FORCE == 0: - return status + 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....' + do_sonic_platform_install() + return - + + def do_uninstall(): - print "Checking system...." + 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() - if status: - if FORCE == 0: - return status - - if driver_check()== False : - print PROJECT_NAME.upper() +" has no driver installed...." + print 'Removing device....' + status = device_uninstall() + if status and FORCE == 0: + return status + + if driver_check() is False: + print PROJECT_NAME.upper() + ' has no driver installed....' else: - print "Removing installed driver...." + print 'Removing installed driver....' status = driver_uninstall() - if status: - if FORCE == 0: - return status - - return + if status and FORCE == 0: + return status + + do_sonic_platform_clean() + + return None + def devices_info(): global DEVICE_NO global ALL_DEVICE global i2c_bus, hwmon_types - for key in DEVICE_NO: - ALL_DEVICE[key]= {} - for i in range(0,DEVICE_NO[key]): - ALL_DEVICE[key][key+str(i+1)] = [] - + for key in DEVICE_NO: + ALL_DEVICE[key] = {} + for i in range(0, DEVICE_NO[key]): + ALL_DEVICE[key][key + str(i + 1)] = [] + for key in i2c_bus: buses = i2c_bus[key] - nodes = i2c_nodes[key] - for i in range(0,len(buses)): - for j in range(0,len(nodes)): - if 'fan' == key: - for k in range(0,DEVICE_NO[key]): - node = key+str(k+1) - path = i2c_prefix+ buses[i]+"/fan"+str(k+1)+"_"+ nodes[j] - my_log(node+": "+ path) - ALL_DEVICE[key][node].append(path) - elif 'sfp' == key: - for k in range(0,DEVICE_NO[key]): - node = key+str(k+1) - path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j] - my_log(node+": "+ path) - ALL_DEVICE[key][node].append(path) + nodes = i2c_nodes[key] + for i in range(0, len(buses)): + for j in range(0, len(nodes)): + if 'fan' == key: + for k in range(0, DEVICE_NO[key]): + node = key + str(k + 1) + path = i2c_prefix + buses[i] + '/fan' + str(k + + 1) + '_' + nodes[j] + my_log(node + ': ' + path) + ALL_DEVICE[key][node].append(path) + elif 'sfp' == key: + for k in range(0, DEVICE_NO[key]): + if k in range(24) or k in range(48, 52): + fmt = i2c_prefix + '5-0062/{0}_{1}' + else: + fmt = i2c_prefix + '6-0064/{0}_{1}' + node = key + str(k + 1) + path = fmt.format(nodes[j], k + 1) + my_log(node + ': ' + path) + ALL_DEVICE[key][node].append(path) else: - node = key+str(i+1) - path = i2c_prefix+ buses[i]+"/"+ nodes[j] - my_log(node+": "+ path) - ALL_DEVICE[key][node].append(path) - + node = key + str(i + 1) + path = i2c_prefix + buses[i] + '/' + nodes[j] + my_log(node + ': ' + path) + ALL_DEVICE[key][node].append(path) + for key in hwmon_types: itypes = hwmon_types[key] - nodes = hwmon_nodes[key] - for i in range(0,len(itypes)): - for j in range(0,len(nodes)): - node = key+"_"+itypes[i] - path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j] - my_log(node+": "+ path) - ALL_DEVICE[key][ key+str(i+1)].append(path) - - #show dict all in the order + nodes = hwmon_nodes[key] + for i in range(0, len(itypes)): + for j in range(0, len(nodes)): + node = key + '_' + itypes[i] + path = hwmon_prefix[key] + itypes[i] + '/' + nodes[j] + my_log(node + ': ' + path) + ALL_DEVICE[key][key + str(i + 1)].append(path) + + # show dict all in the order if DEBUG == True: for i in sorted(ALL_DEVICE.keys()): - print(i+": ") - for j in sorted(ALL_DEVICE[i].keys()): - print(" "+j) - for k in (ALL_DEVICE[i][j]): - print(" "+" "+k) - return - + 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') + if system_ready() is False: + print('Systems 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): + (ret, log) = log_os_system('which hexdump', 0) + (ret, log2) = log_os_system('which busybox hexdump', 0) + if log: hex_cmd = 'hexdump' - elif len(log2): + elif 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 + 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 - + 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: + if system_ready() is False: + print('System is not ready.') + print('Please install first!') + return + + if not ALL_DEVICE: + 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: + + # 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_os_system('echo ' + args[1] + ' >' + k, 1) + if ret[0]: + return ret[0] + 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] +"%") + + # 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_os_system('echo ' + args[1] + ' >' + node, 1) + if ret[0] == 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: + elif args[0] == 'sfp': + if int(args[1]) > qsfp_start or int(args[1]) == 0: show_set_help() - return - if len(args)<2: + return + if len(args) < 2: show_set_help() - return - - if int(args[2])>1: + 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 - + + # print ALL_DEVICE[args[0]] + + for i in range(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_os_system('echo ' + args[2] + ' >' + j, 1) + if ret[0]: + return ret[0] + return - -#get digits inside a string. -#Ex: 31 for "sfp31" -def get_value(input): - digit = re.findall('\d+', input) + + +# get digits inside a string. +# Ex: get 31 from "sfp31" +def get_value(i): + digit = re.findall('\d+', i) return int(digit[0]) - + + def device_traversal(): - if system_ready()==False: - print("System's not ready.") - print("Please install first!") - return - - if len(ALL_DEVICE)==0: + if system_ready() is False: + print "System is not ready." + print 'Please install first!' + return + + if not ALL_DEVICE: devices_info() for i in sorted(ALL_DEVICE.keys()): - print("============================================") - print(i.upper()+": ") - print("============================================") - - for j in sorted(ALL_DEVICE[i].keys(), key=get_value): - print " "+j+":", - for k in (ALL_DEVICE[i][j]): - ret, log = log_os_system("cat "+k, 0) - func = k.split("/")[-1].strip() - func = re.sub(j+'_','',func,1) - func = re.sub(i.lower()+'_','',func,1) - if ret==0: - print func+"="+log+" ", + print '============================================' + print i.upper() + ': ' + print '============================================' + for j in sorted(ALL_DEVICE[i].keys(), key=get_value): + print ' ' + j + ':', + for k in ALL_DEVICE[i][j]: + (ret, log) = log_os_system('cat ' + k, 0) + func = k.split('/')[-1].strip() + func = re.sub(j + '_', '', func, 1) + func = re.sub(i.lower() + '_', '', func, 1) + if ret == 0: + print func + '=' + log + ' ', else: - print func+"="+"X"+" ", - print - print("----------------------------------------------------------------") - - + print func + '=' + 'X' + ' ', + print + print '----------------------------------------------------------------' print return - + + def device_exist(): - ret1, log = log_os_system("ls "+i2c_prefix+"*0070", 0) - ret2, log = log_os_system("ls "+i2c_prefix+"i2c-2", 0) - return not(ret1 or ret2) + ret1 = log_os_system('ls ' + i2c_prefix + '*0070', 0) + ret2 = log_os_system('ls ' + i2c_prefix + 'i2c-2', 0) + return not (ret1[0] or ret2[0]) + -if __name__ == "__main__": +if __name__ == '__main__': main() diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54xs/modules/accton_as7312_54x_leds.c b/platform/broadcom/sonic-platform-modules-accton/as7312-54xs/modules/accton_as7312_54x_leds.c index 1d54517c6243..f53716440107 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as7312-54xs/modules/accton_as7312_54x_leds.c +++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54xs/modules/accton_as7312_54x_leds.c @@ -34,7 +34,6 @@ extern int as7312_54x_cpld_read (unsigned short cpld_addr, u8 reg); extern int as7312_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); extern void led_classdev_unregister(struct led_classdev *led_cdev); -extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); extern void led_classdev_resume(struct led_classdev *led_cdev); extern void led_classdev_suspend(struct led_classdev *led_cdev); diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54xs/utils/accton_as7312_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as7312-54xs/utils/accton_as7312_monitor.py index 09bc99c75aba..58ffe1923a85 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7312-54xs/utils/accton_as7312_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54xs/utils/accton_as7312_monitor.py @@ -24,18 +24,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config - import types import time # this is only being used as part of the example - import traceback import signal - from tabulate import tabulate from as7312_54xs.fanutil import FanUtil from as7312_54xs.thermalutil import ThermalUtil except ImportError as e: diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54xs/utils/accton_as7312_util.py b/platform/broadcom/sonic-platform-modules-accton/as7312-54xs/utils/accton_as7312_util.py index 9b5803b07afd..f6a21bdd3df9 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7312-54xs/utils/accton_as7312_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54xs/utils/accton_as7312_util.py @@ -30,13 +30,12 @@ set : change board setting with fan|led|sfp """ -import os import commands -import sys, getopt +import getopt +import sys import logging import re import time -from collections import namedtuple @@ -146,11 +145,12 @@ def log_os_system(cmd, show): return status, output def driver_check(): - ret, lsmod = log_os_system("lsmod| grep accton", 0) + ret, lsmod = log_os_system("ls /sys/module/*accton*", 0) logging.info('mods:'+lsmod) - if len(lsmod) ==0: - return False - return True + if ret : + return False + else : + return True diff --git a/platform/broadcom/sonic-platform-modules-accton/as7315-27xb/utils/accton_as7315_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as7315-27xb/utils/accton_as7315_monitor.py index 5d821350ac81..d5b868255f4a 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7315-27xb/utils/accton_as7315_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7315-27xb/utils/accton_as7315_monitor.py @@ -24,18 +24,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config - import types import time # this is only being used as part of the example - import traceback import signal - from tabulate import tabulate from as7315_27xb.fanutil import FanUtil from as7315_27xb.thermalutil import ThermalUtil except ImportError as e: diff --git a/platform/broadcom/sonic-platform-modules-accton/as7315-27xb/utils/accton_as7315_util.py b/platform/broadcom/sonic-platform-modules-accton/as7315-27xb/utils/accton_as7315_util.py index ea856e4ff56b..e3810e42102e 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7315-27xb/utils/accton_as7315_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7315-27xb/utils/accton_as7315_util.py @@ -30,13 +30,12 @@ set : change board setting with fan|led|sfp """ -import os import commands -import sys, getopt +import getopt +import sys import logging import re import time -from collections import namedtuple @@ -148,11 +147,12 @@ def log_os_system(cmd, show): return status, output def driver_check(): - ret, lsmod = log_os_system("lsmod| grep accton", 0) + ret, lsmod = log_os_system("ls /sys/module/*accton*", 0) logging.info('mods:'+lsmod) - if len(lsmod) ==0: - return False - return True + if ret : + return False + else : + return True diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_as7326_56x_leds.c b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_as7326_56x_leds.c index 4cb7f1fa25a5..54df5b09eea8 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_as7326_56x_leds.c +++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_as7326_56x_leds.c @@ -34,7 +34,6 @@ extern int as7326_56x_cpld_read (unsigned short cpld_addr, u8 reg); extern int as7326_56x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); extern void led_classdev_unregister(struct led_classdev *led_cdev); -extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); extern void led_classdev_resume(struct led_classdev *led_cdev); extern void led_classdev_suspend(struct led_classdev *led_cdev); diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/service/as7326-platform-handle_mac.service b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/service/as7326-platform-handle_mac.service old mode 100755 new mode 100644 diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/service/as7326-platform-monitor-fan.service b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/service/as7326-platform-monitor-fan.service old mode 100755 new mode 100644 diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/service/as7326-platform-monitor-psu.service b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/service/as7326-platform-monitor-psu.service old mode 100755 new mode 100644 diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/service/as7326-platform-monitor.service b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/service/as7326-platform-monitor.service old mode 100755 new mode 100644 diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_monitor.py index b775d97edda9..07ec446ab88e 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_monitor.py @@ -24,17 +24,12 @@ try: import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate from as7326_56x.fanutil import FanUtil from as7326_56x.thermalutil import ThermalUtil except ImportError as e: diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_monitor_fan.py b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_monitor_fan.py index 6fa429d01314..b52ada307698 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_monitor_fan.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_monitor_fan.py @@ -22,19 +22,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate - except ImportError as e: raise ImportError('%s - required module not found' % str(e)) diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_monitor_psu.py b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_monitor_psu.py index d76c20bd5a9b..cb897b942aeb 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_monitor_psu.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_monitor_psu.py @@ -22,18 +22,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate except ImportError as e: raise ImportError('%s - required module not found' % str(e)) diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_util.py b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_util.py index 0e08f0b62aed..c5d047e9d4e0 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_util.py @@ -39,13 +39,12 @@ set : change board setting with fan|led|sfp """ -import os import commands -import sys, getopt +import getopt +import sys import logging import re import time -from collections import namedtuple @@ -179,11 +178,12 @@ def log_os_system(cmd, show): return status, output def driver_check(): - ret, lsmod = log_os_system("lsmod| grep accton", 0) + ret, lsmod = log_os_system("ls /sys/module/*accton*", 0) logging.info('mods:'+lsmod) - if len(lsmod) ==0: + if ret : return False - return True + else : + return True diff --git a/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/leds-accton_as7712_32x.c b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/leds-accton_as7712_32x.c index 5e1a9282db0e..a3238d4b1615 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/leds-accton_as7712_32x.c +++ b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/leds-accton_as7712_32x.c @@ -34,7 +34,6 @@ extern int accton_i2c_cpld_read (unsigned short cpld_addr, u8 reg); extern int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); extern void led_classdev_unregister(struct led_classdev *led_cdev); -extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); extern void led_classdev_resume(struct led_classdev *led_cdev); extern void led_classdev_suspend(struct led_classdev *led_cdev); diff --git a/platform/broadcom/sonic-platform-modules-accton/as7712-32x/utils/accton_as7712_util.py b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/utils/accton_as7712_util.py index c8b755b85b69..8ebc39e6c9c1 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7712-32x/utils/accton_as7712_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/utils/accton_as7712_util.py @@ -30,13 +30,12 @@ set : change board setting with fan|led|sfp """ -import os import commands -import sys, getopt +import getopt +import sys import logging import re import time -from collections import namedtuple @@ -146,11 +145,12 @@ def log_os_system(cmd, show): return status, output def driver_check(): - ret, lsmod = log_os_system("lsmod| grep accton", 0) + ret, lsmod = log_os_system("ls /sys/module/*accton*", 0) logging.info('mods:'+lsmod) - if len(lsmod) ==0: - return False - return True + if ret : + return False + else : + return True diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_leds.c b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_leds.c index da3d9442035f..cb08189e3360 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_leds.c +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_leds.c @@ -34,7 +34,6 @@ extern int as7716_32x_cpld_read (unsigned short cpld_addr, u8 reg); extern int as7716_32x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); extern void led_classdev_unregister(struct led_classdev *led_cdev); -extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); extern void led_classdev_resume(struct led_classdev *led_cdev); extern void led_classdev_suspend(struct led_classdev *led_cdev); diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/utils/accton_as7716_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/utils/accton_as7716_monitor.py index 63f26d5d2ef6..c423cc441d92 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/utils/accton_as7716_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/utils/accton_as7716_monitor.py @@ -23,17 +23,11 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate from as7716_32x.fanutil import FanUtil from as7716_32x.thermalutil import ThermalUtil except ImportError as e: diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/utils/accton_as7716_util.py b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/utils/accton_as7716_util.py index b195165337d1..142ce754a5c7 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/utils/accton_as7716_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/utils/accton_as7716_util.py @@ -30,13 +30,12 @@ set : change board setting with fan|led|sfp """ -import os import commands -import sys, getopt +import getopt +import sys import logging import re import time -from collections import namedtuple PROJECT_NAME = 'as7716_32x' version = '0.0.1' @@ -55,7 +54,6 @@ 'fan3': ['fan'], 'fan4': ['fan'], 'fan5': ['fan'], - 'fan5': ['fan'], } hwmon_nodes = {'led': ['brightness'] , 'fan1': ['fan_duty_cycle_percentage', 'fan1_fault', 'fan1_speed_rpm', 'fan1_direction', 'fanr1_fault', 'fanr1_speed_rpm'], @@ -269,10 +267,12 @@ def log_os_system(cmd, show): return status, output def driver_inserted(): - ret, lsmod = log_os_system("lsmod| grep accton", 0) + ret, lsmod = log_os_system("ls /sys/module/*accton*", 0) logging.info('mods:'+lsmod) - if len(lsmod) ==0: + if ret : return False + else : + return True #'modprobe cpr_4011_4mxx', diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_leds.c b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_leds.c index 2fa3fd722cb1..4e2162843a9e 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_leds.c +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_leds.c @@ -31,7 +31,6 @@ #include extern void led_classdev_unregister(struct led_classdev *led_cdev); -extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); extern void led_classdev_resume(struct led_classdev *led_cdev); extern void led_classdev_suspend(struct led_classdev *led_cdev); diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_drv_handler.py b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_drv_handler.py index c08a82c7dc45..ed5af4818de3 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_drv_handler.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_drv_handler.py @@ -22,18 +22,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config - import types import time # this is only being used as part of the example - import traceback import commands - from tabulate import tabulate except ImportError as e: raise ImportError('%s - required module not found' % str(e)) diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_monitor.py index 2568312b0955..86b4f1852066 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_monitor.py @@ -23,17 +23,11 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate from as7716_32x.fanutil import FanUtil from as7716_32x.thermalutil import ThermalUtil except ImportError as e: diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_util.py b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_util.py index ffddfb338506..3a31d253f633 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_util.py @@ -30,13 +30,11 @@ set : change board setting with fan|led|sfp """ -import os import commands -import sys, getopt +import getopt +import sys import logging import re -import time -from collections import namedtuple PROJECT_NAME = 'as7716_32xb' version = '0.0.1' @@ -55,7 +53,6 @@ 'fan3': ['fan'], 'fan4': ['fan'], 'fan5': ['fan'], - 'fan5': ['fan'], } hwmon_nodes = {'led': ['brightness'] , 'fan1': ['fan_duty_cycle_percentage', 'fan1_fault', 'fan1_speed_rpm', 'fan1_direction', 'fanr1_fault', 'fanr1_speed_rpm'], @@ -243,10 +240,12 @@ def log_os_system(cmd, show): return status, output def driver_inserted(): - ret, lsmod = log_os_system("lsmod| grep accton", 0) + ret, lsmod = log_os_system("ls /sys/module/*accton*", 0) logging.info('mods:'+lsmod) - if len(lsmod) ==0: + if ret : return False + else : + return True kos = [ diff --git a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/modules/accton_as7726_32x_leds.c b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/modules/accton_as7726_32x_leds.c index 65b962e628cc..c179fd855bd2 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/modules/accton_as7726_32x_leds.c +++ b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/modules/accton_as7726_32x_leds.c @@ -34,7 +34,6 @@ extern int as7726_32x_cpld_read (unsigned short cpld_addr, u8 reg); extern int as7726_32x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); extern void led_classdev_unregister(struct led_classdev *led_cdev); -extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); extern void led_classdev_resume(struct led_classdev *led_cdev); extern void led_classdev_suspend(struct led_classdev *led_cdev); diff --git a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/service/as7726-32x-platform-handle_mac.service b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/service/as7726-32x-platform-handle_mac.service old mode 100755 new mode 100644 diff --git a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/service/as7726-32x-platform-monitor-fan.service b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/service/as7726-32x-platform-monitor-fan.service old mode 100755 new mode 100644 diff --git a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/service/as7726-32x-platform-monitor-psu.service b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/service/as7726-32x-platform-monitor-psu.service old mode 100755 new mode 100644 diff --git a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/service/as7726-32x-platform-monitor.service b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/service/as7726-32x-platform-monitor.service old mode 100755 new mode 100644 diff --git a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_monitor.py index 631a7915383b..aada6ba5c507 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_monitor.py @@ -24,17 +24,12 @@ try: import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate from as7726_32x.fanutil import FanUtil from as7726_32x.thermalutil import ThermalUtil except ImportError as e: diff --git a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_monitor_fan.py b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_monitor_fan.py index de737b99f1f3..a2139341150c 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_monitor_fan.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_monitor_fan.py @@ -22,19 +22,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate - except ImportError as e: raise ImportError('%s - required module not found' % str(e)) diff --git a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_monitor_psu.py b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_monitor_psu.py index 618c58eec872..d139e3f3f1c8 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_monitor_psu.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_monitor_psu.py @@ -22,18 +22,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate except ImportError as e: raise ImportError('%s - required module not found' % str(e)) diff --git a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_util.py b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_util.py index acb0319f5f25..a6aa855174be 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_util.py @@ -30,13 +30,12 @@ set : change board setting with fan|led|sfp """ -import os import commands -import sys, getopt +import getopt +import sys import logging import re import time -from collections import namedtuple PROJECT_NAME = 'as7726_32x' version = '0.0.1' @@ -55,7 +54,6 @@ 'fan3': ['fan'], 'fan4': ['fan'], 'fan5': ['fan'], - 'fan5': ['fan'], } hwmon_nodes = {'led': ['brightness'] , 'fan1': ['fan_duty_cycle_percentage', 'fan1_fault', 'fan1_speed_rpm', 'fan1_direction', 'fanr1_fault', 'fanr1_speed_rpm'], @@ -250,10 +248,12 @@ def log_os_system(cmd, show): return status, output def driver_inserted(): - ret, lsmod = log_os_system("lsmod| grep accton", 0) + ret, lsmod = log_os_system("ls /sys/module/*accton*", 0) logging.info('mods:'+lsmod) - if len(lsmod) ==0: + if ret : return False + else : + return True def cpld_reset_mac(): ret, lsmod = log_os_system("i2cset -y 0 0x77 0x1", 0) diff --git a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/x86-64-accton-as7816-64x-fan.c b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/x86-64-accton-as7816-64x-fan.c index 3de2c200e1e1..2cd85c43a9c2 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/x86-64-accton-as7816-64x-fan.c +++ b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/x86-64-accton-as7816-64x-fan.c @@ -176,7 +176,6 @@ static struct attribute *as7816_64x_fan_attributes[] = { #define FAN_DUTY_CYCLE_REG_MASK 0xF #define FAN_MAX_DUTY_CYCLE 100 -#define FAN_REG_VAL_TO_SPEED_RPM_STEP 100 static int as7816_64x_fan_read_value(struct i2c_client *client, u8 reg) { @@ -220,7 +219,14 @@ static u8 duty_cycle_to_reg_val(u8 duty_cycle) static u32 reg_val_to_speed_rpm(u8 reg_val) { - return (u32)reg_val * FAN_REG_VAL_TO_SPEED_RPM_STEP; + if (reg_val == 0 || reg_val == 255) { + return 0; + } else { + u64 f, dv; + dv = 2 * 2 * 40960 * (u64)(255 - reg_val); + f = 60000000000 / dv; + return (u32)f; + } } static u8 reg_val_to_direction(u8 reg_val, enum fan_id id) diff --git a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/x86-64-accton-as7816-64x-leds.c b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/x86-64-accton-as7816-64x-leds.c index 025f87d692a3..3102e968c93f 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/x86-64-accton-as7816-64x-leds.c +++ b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/x86-64-accton-as7816-64x-leds.c @@ -34,7 +34,6 @@ extern int accton_i2c_cpld_read (u8 cpld_addr, u8 reg); extern int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); extern void led_classdev_unregister(struct led_classdev *led_cdev); -extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); extern void led_classdev_resume(struct led_classdev *led_cdev); extern void led_classdev_suspend(struct led_classdev *led_cdev); diff --git a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/utils/accton_as7816_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/utils/accton_as7816_monitor.py index 3d9f6fc3ce5e..217351ad2a3c 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/utils/accton_as7816_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/utils/accton_as7816_monitor.py @@ -24,18 +24,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config - import types import time # this is only being used as part of the example - import traceback import signal - from tabulate import tabulate from as7816_64x.fanutil import FanUtil from as7816_64x.thermalutil import ThermalUtil except ImportError as e: @@ -60,6 +54,9 @@ class accton_as7816_monitor(object): def __init__(self, log_file, log_level): """Needs a logger and a logger level.""" + + self.thermal = ThermalUtil() + self.fan = FanUtil() # set up logging to file logging.basicConfig( filename=log_file, @@ -89,8 +86,8 @@ def manage_fans(self): 4: [max_duty, 57000, sys.maxsize], } - thermal = ThermalUtil() - fan = FanUtil() + thermal = self.thermal + fan = self.fan for x in range(fan.get_idx_fan_start(), fan.get_num_fans()+1): fan_status = fan.get_fan_status(x) if fan_status is None: diff --git a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/utils/accton_as7816_util.py b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/utils/accton_as7816_util.py index ab5e52cb85bd..3aae150dad5c 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/utils/accton_as7816_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/utils/accton_as7816_util.py @@ -30,14 +30,12 @@ set : change board setting with fan|led|sfp """ -import os import commands -import sys, getopt +import getopt +import sys import logging import re import time -from collections import namedtuple - @@ -169,11 +167,12 @@ def log_os_system(cmd, show): return status, output def driver_check(): - ret, lsmod = log_os_system("lsmod| grep accton", 0) + ret, lsmod = log_os_system("ls /sys/module/*accton*", 0) logging.info('mods:'+lsmod) - if len(lsmod) ==0: - return False - return True + if ret : + return False + else : + return True diff --git a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/modules/accton_as9716_32d_cpld.c b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/modules/accton_as9716_32d_cpld.c index 874bdc33bea4..d473bb452411 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/modules/accton_as9716_32d_cpld.c +++ b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/modules/accton_as9716_32d_cpld.c @@ -72,6 +72,7 @@ MODULE_DEVICE_TABLE(i2c, as9716_32d_cpld_id); #define TRANSCEIVER_RXLOS_ATTR_ID(index) MODULE_RXLOS_##index #define TRANSCEIVER_TXFAULT_ATTR_ID(index) MODULE_TXFAULT_##index #define TRANSCEIVER_RESET_ATTR_ID(index) MODULE_RESET_##index +#define CPLD_INTR_ATTR_ID(index) CPLD_INTR_##index enum as9716_32d_cpld_sysfs_attributes { CPLD_VERSION, @@ -149,10 +150,17 @@ enum as9716_32d_cpld_sysfs_attributes { TRANSCEIVER_RESET_ATTR_ID(30), TRANSCEIVER_RESET_ATTR_ID(31), TRANSCEIVER_RESET_ATTR_ID(32), + CPLD_INTR_ATTR_ID(1), + CPLD_INTR_ATTR_ID(2), + CPLD_INTR_ATTR_ID(3), + CPLD_INTR_ATTR_ID(4), + }; /* sysfs attributes for hwmon */ +static ssize_t show_interrupt(struct device *dev, struct device_attribute *da, + char *buf); static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf); static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, @@ -188,6 +196,11 @@ static int as9716_32d_cpld_write_internal(struct i2c_client *client, u8 reg, u8 static SENSOR_DEVICE_ATTR(module_reset_##index, S_IWUSR | S_IRUGO, get_mode_reset, set_mode_reset, MODULE_RESET_##index) #define DECLARE_TRANSCEIVER_RESET_ATTR(index) &sensor_dev_attr_module_reset_##index.dev_attr.attr +/*cpld interrupt*/ +#define DECLARE_CPLD_DEVICE_INTR_ATTR(index) \ + static SENSOR_DEVICE_ATTR(cpld_intr_##index, S_IRUGO, show_interrupt, NULL, CPLD_INTR_##index) +#define DECLARE_CPLD_INTR_ATTR(index) &sensor_dev_attr_cpld_intr_##index.dev_attr.attr + static SENSOR_DEVICE_ATTR(version, S_IRUGO, show_version, NULL, CPLD_VERSION); @@ -261,6 +274,10 @@ DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(29); DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(30); DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(31); DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(32); +DECLARE_CPLD_DEVICE_INTR_ATTR(1); +DECLARE_CPLD_DEVICE_INTR_ATTR(2); +DECLARE_CPLD_DEVICE_INTR_ATTR(3); +DECLARE_CPLD_DEVICE_INTR_ATTR(4); @@ -309,6 +326,8 @@ static struct attribute *as9716_32d_cpld1_attributes[] = { DECLARE_TRANSCEIVER_RESET_ATTR(14), DECLARE_TRANSCEIVER_RESET_ATTR(15), DECLARE_TRANSCEIVER_RESET_ATTR(16), + DECLARE_CPLD_INTR_ATTR(1), + DECLARE_CPLD_INTR_ATTR(2), NULL }; @@ -355,6 +374,8 @@ static struct attribute *as9716_32d_cpld2_attributes[] = { DECLARE_TRANSCEIVER_RESET_ATTR(30), DECLARE_TRANSCEIVER_RESET_ATTR(31), DECLARE_TRANSCEIVER_RESET_ATTR(32), + DECLARE_CPLD_INTR_ATTR(3), + DECLARE_CPLD_INTR_ATTR(4), NULL }; @@ -363,6 +384,47 @@ static const struct attribute_group as9716_32d_cpld2_group = { }; +static ssize_t show_interrupt(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as9716_32d_cpld_data *data = i2c_get_clientdata(client); + int status = 0; + u8 reg = 0; + + switch (attr->index) + { + case CPLD_INTR_1: + reg = 0x10; + break; + case CPLD_INTR_3: + reg = 0x10; + break; + case CPLD_INTR_2: + reg = 0x11; + break; + case CPLD_INTR_4: + reg = 0x11; + break; + default: + return -ENODEV; + } + mutex_lock(&data->update_lock); + status = as9716_32d_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + + return sprintf(buf, "0x%x\n", status); + +exit: + mutex_unlock(&data->update_lock); + return status; +} + + static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf) { @@ -723,9 +785,21 @@ static int as9716_32d_cpld_probe(struct i2c_client *client, break; case as9716_32d_cpld1: group = &as9716_32d_cpld1_group; + /*Set interrupt mask to 0, and then can get intr from 0x8*/ + status=as9716_32d_cpld_write_internal(client, 0x9, 0x0); + if (status < 0) + { + dev_dbg(&client->dev, "cpld1 reg 0x9 err %d\n", status); + } break; case as9716_32d_cpld2: group = &as9716_32d_cpld2_group; + /*Set interrupt mask to 0, and then can get intr from 0x8*/ + status=as9716_32d_cpld_write_internal(client, 0x9, 0x0); + if (status < 0) + { + dev_dbg(&client->dev, "cpld2 reg 0x65 err %d\n", status); + } break; case as9716_32d_cpld_cpu: /* Disable CPLD reset to avoid DUT will be reset. diff --git a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/service/as9716-32d-platform-monitor-fan.service b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/service/as9716-32d-platform-monitor-fan.service old mode 100755 new mode 100644 diff --git a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/service/as9716-32d-platform-monitor-psu.service b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/service/as9716-32d-platform-monitor-psu.service old mode 100755 new mode 100644 diff --git a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/service/as9716-32d-platform-monitor.service b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/service/as9716-32d-platform-monitor.service old mode 100755 new mode 100644 diff --git a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor.py index 3752161d3ebc..49a99aa777a3 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor.py @@ -20,19 +20,13 @@ # ------------------------------------------------------------------ try: - import os import commands - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate from as9716_32d.fanutil import FanUtil from as9716_32d.thermalutil import ThermalUtil except ImportError as e: diff --git a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor_fan.py b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor_fan.py index 320655361b83..b22dd5d7984d 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor_fan.py +++ b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor_fan.py @@ -22,19 +22,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate - except ImportError as e: raise ImportError('%s - required module not found' % str(e)) diff --git a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor_psu.py b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor_psu.py index a8df99430c81..a3c8a0be65b3 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor_psu.py +++ b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor_psu.py @@ -22,18 +22,12 @@ # ------------------------------------------------------------------ try: - import os - import sys, getopt - import subprocess - import click - import imp + import getopt + import sys import logging import logging.config import logging.handlers - import types import time # this is only being used as part of the example - import traceback - from tabulate import tabulate except ImportError as e: raise ImportError('%s - required module not found' % str(e)) diff --git a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_util.py b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_util.py index 7ccf05a798a0..898fcaa0f0d3 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_util.py @@ -30,13 +30,12 @@ set : change board setting with fan|led|sfp """ -import os import commands -import sys, getopt +import getopt +import sys import logging import re import time -from collections import namedtuple PROJECT_NAME = 'as9716_32d' version = '0.0.1' @@ -55,7 +54,6 @@ 'fan3': ['fan'], 'fan4': ['fan'], 'fan5': ['fan'], - 'fan5': ['fan'], } hwmon_nodes = {'led': ['brightness'] , 'fan1': ['fan_duty_cycle_percentage', 'fan1_fault', 'fan1_speed_rpm', 'fan1_direction', 'fanr1_fault', 'fanr1_speed_rpm'], @@ -123,13 +121,14 @@ # PSU-2 'echo as9716_32d_psu2 0x51 > /sys/bus/i2c/devices/i2c-10/new_device', 'echo acbel_fsh082 0x59 > /sys/bus/i2c/devices/i2c-10/new_device', +] #EERPOM +eeprom_mknod =[ +'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-0/new_device', 'echo 24c02 0x56 > /sys/bus/i2c/devices/i2c-0/new_device', ] - - FORCE = 0 logging.basicConfig(filename= PROJECT_NAME+'.log', filemode='w',level=logging.DEBUG) logging.basicConfig(level=logging.INFO) @@ -255,10 +254,12 @@ def log_os_system(cmd, show): return status, output def driver_inserted(): - ret, lsmod = log_os_system("lsmod| grep accton", 0) + ret, lsmod = log_os_system("ls /sys/module/*accton*", 0) logging.info('mods:'+lsmod) - if len(lsmod) ==0: + if ret : return False + else : + return True kos = [ @@ -301,8 +302,14 @@ def driver_uninstall(): return status return 0 +def eeprom_check(): + cmd = "i2cget -y -f 0 0x57" + status, output = commands.getstatusoutput(cmd) + return status + def device_install(): global FORCE + global use_57_eeprom for i in range(0,len(mknod)): #for pca954x need times to built new i2c buses @@ -315,6 +322,12 @@ def device_install(): if FORCE == 0: return status + ret=eeprom_check() + if ret==0: + log_os_system(eeprom_mknod[0], 1) #new board, 0x57 eeprom + else: + log_os_system(eeprom_mknod[1], 1) #old board, 0x56 eeprom + for i in range(0,len(sfp_map)): status, output =log_os_system("echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) if status: @@ -358,6 +371,17 @@ def device_uninstall(): if FORCE == 0: return status + ret=eeprom_check() + if ret==0: + target = eeprom_mknod[0] #0x57 + else: + target = eeprom_mknod[1] #0x56 + + temp = target.split() + del temp[1] + temp[-1] = temp[-1].replace('new_device', 'delete_device') + status, output = log_os_system(" ".join(temp), 1) + return def system_ready(): diff --git a/platform/broadcom/sonic-platform-modules-accton/common/modules/accton_pmbus_3y.c b/platform/broadcom/sonic-platform-modules-accton/common/modules/accton_pmbus_3y.c index ed176189cdcd..76ac4368a8d4 100644 --- a/platform/broadcom/sonic-platform-modules-accton/common/modules/accton_pmbus_3y.c +++ b/platform/broadcom/sonic-platform-modules-accton/common/modules/accton_pmbus_3y.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include "pmbus.h" diff --git a/platform/broadcom/sonic-platform-modules-accton/common/modules/ym2651y.c b/platform/broadcom/sonic-platform-modules-accton/common/modules/ym2651y.c index 5e9d858fa689..5834b1d4ef8b 100755 --- a/platform/broadcom/sonic-platform-modules-accton/common/modules/ym2651y.c +++ b/platform/broadcom/sonic-platform-modules-accton/common/modules/ym2651y.c @@ -355,6 +355,11 @@ static ssize_t show_ascii(struct device *dev, struct device_attribute *da, switch (attr->index) { case PSU_FAN_DIRECTION: /* psu_fan_dir */ + if (data->chip==YPEB1200AM) + { + memcpy(data->fan_dir, "F2B", 3); + data->fan_dir[3]='\0'; + } ptr = data->fan_dir; break; case PSU_MFR_ID: /* psu_mfr_id */ diff --git a/platform/broadcom/sonic-platform-modules-accton/debian/rules b/platform/broadcom/sonic-platform-modules-accton/debian/rules index 722d4126ad0e..e894b10f8234 100755 --- a/platform/broadcom/sonic-platform-modules-accton/debian/rules +++ b/platform/broadcom/sonic-platform-modules-accton/debian/rules @@ -14,6 +14,7 @@ include /usr/share/dpkg/pkg-info.mk export INSTALL_MOD_DIR:=extra PYTHON ?= python2 +PYTHON3 ?= python3 PACKAGE_PRE_NAME := sonic-platform-accton KVERSION ?= $(shell uname -r) @@ -40,6 +41,12 @@ build: (for mod in $(MODULE_DIRS); do \ make modules -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ $(PYTHON) $${mod}/setup.py build; \ + cd $(MOD_SRC_DIR)/$${mod}; \ + if [ -f sonic_platform_setup.py ]; then \ + $(PYTHON3) sonic_platform_setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}; \ + echo "Finished makig whl package for $$mod"; \ + fi; \ + cd $(MOD_SRC_DIR); \ done) binary: binary-arch binary-indep diff --git a/platform/broadcom/sonic-platform-modules-accton/debian/sonic-platform-accton-as7312-54x.install b/platform/broadcom/sonic-platform-modules-accton/debian/sonic-platform-accton-as7312-54x.install new file mode 100644 index 000000000000..c0e14a1f6b1b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/debian/sonic-platform-accton-as7312-54x.install @@ -0,0 +1,2 @@ +as7312-54x/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/x86_64-accton_as7312_54x-r0 + diff --git a/platform/broadcom/sonic-platform-modules-accton/minipack/utils/accton_minipack_util.py b/platform/broadcom/sonic-platform-modules-accton/minipack/utils/accton_minipack_util.py index 261074c5d99a..25979963bb30 100755 --- a/platform/broadcom/sonic-platform-modules-accton/minipack/utils/accton_minipack_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/minipack/utils/accton_minipack_util.py @@ -37,13 +37,12 @@ set : change board setting with led|sfp """ -import os import commands -import sys, getopt +import getopt +import sys import logging import re import time -from collections import namedtuple PROJECT_NAME = 'minipack' version = '0.2.0' @@ -182,10 +181,12 @@ def log_os_system(cmd, show): return status, output def driver_inserted(): - ret, lsmod = log_os_system("lsmod| grep accton", 0) + ret, lsmod = log_os_system("ls /sys/module/*accton*", 0) logging.info('mods:'+lsmod) - if len(lsmod) ==0: + if ret : return False + else : + return True diff --git a/platform/broadcom/sonic-platform-modules-accton/minipack/utils/setup_qsfp_eeprom.py b/platform/broadcom/sonic-platform-modules-accton/minipack/utils/setup_qsfp_eeprom.py index 84388520b902..257bc1cd90e6 100755 --- a/platform/broadcom/sonic-platform-modules-accton/minipack/utils/setup_qsfp_eeprom.py +++ b/platform/broadcom/sonic-platform-modules-accton/minipack/utils/setup_qsfp_eeprom.py @@ -22,8 +22,8 @@ try: import os - import sys, getopt - import subprocess + import getopt + import sys import subprocess import click import imp diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control b/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control index beba5b5f4e62..6535dbb88bb8 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-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned 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-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-arista b/platform/broadcom/sonic-platform-modules-arista index b1940cf49a18..937ea8abc1de 160000 --- a/platform/broadcom/sonic-platform-modules-arista +++ b/platform/broadcom/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit b1940cf49a185745cc9365afed8efb511478807e +Subproject commit 937ea8abc1de457b26b7bb7a5208dab6ce40f4a1 diff --git a/platform/broadcom/sonic-platform-modules-brcm-xlr-gts/Makefile b/platform/broadcom/sonic-platform-modules-brcm-xlr-gts/Makefile index cd2a5a101ad5..3f93a0bfe52a 100644 --- a/platform/broadcom/sonic-platform-modules-brcm-xlr-gts/Makefile +++ b/platform/broadcom/sonic-platform-modules-brcm-xlr-gts/Makefile @@ -7,7 +7,7 @@ MAIN_TARGET = $(BRCM_XLR_GTS_PLATFORM_MODULE) $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : # Build the package export PYBUILD_INSTALL_ARGS_python2=--install-scripts=/dev/null - dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) + dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) --admindir $(SONIC_DPKG_ADMINDIR) mv $(addprefix ../, $* $(EXTRA_TARGETS)) $(DEST)/ diff --git a/platform/broadcom/sonic-platform-modules-brcm-xlr-gts/utils/brcm-xlr-gts-create-eeprom-file.py b/platform/broadcom/sonic-platform-modules-brcm-xlr-gts/utils/brcm-xlr-gts-create-eeprom-file.py index 71a99471a99f..d8e7ec0ee138 100755 --- a/platform/broadcom/sonic-platform-modules-brcm-xlr-gts/utils/brcm-xlr-gts-create-eeprom-file.py +++ b/platform/broadcom/sonic-platform-modules-brcm-xlr-gts/utils/brcm-xlr-gts-create-eeprom-file.py @@ -93,13 +93,13 @@ def main(): tlvinfo_header.totallen = len(tlvinfo_data.dump())+4; try: - f = open('/etc/sys_eeprom.bin', 'w+') + f = open('/usr/share/sonic/device/x86_64-bcm_xlr-r0/sys_eeprom.bin', 'w+') f.write(tlvinfo_header.dump()) f.write(tlvinfo_data.dump()) f.write(crc(tlvinfo_header.dump(), tlvinfo_data.dump())) f.close() except: - print('Unable to write file /etc/sys_eeprom.bin') + print('Unable to write file /usr/share/sonic/device/x86_64-bcm_xlr-r0/sys_eeprom.bin') if __name__== "__main__": main() diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/control b/platform/broadcom/sonic-platform-modules-cel/debian/control index d5dd43ee4918..a41f92ab54e9 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/control +++ b/platform/broadcom/sonic-platform-modules-cel/debian/control @@ -7,21 +7,21 @@ Standards-Version: 3.9.3 Package: platform-modules-dx010 Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-haliburton Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-seastone2 Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as led, sfp Package: platform-modules-silverstone Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as led, sfp. diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init index 1e124565a41d..e27d4df46782 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init @@ -42,10 +42,11 @@ start) echo -n "Setting up board... " modprobe i2c-dev - modprobe i2c-mux-pca954x + modprobe i2c-mux-pca954x force-deselect-on-exit=1 modprobe dx010_wdt modprobe leds-dx010 modprobe lm75 + modprobe slx_gpio_ich found=0 for devnum in 0 1; do @@ -60,10 +61,6 @@ start) [ $found -eq 0 ] && echo "cannot find iSMT" && exit 1 i2cset -y ${devnum} 0x70 0x10 0x00 0x01 i - - # Attach PCA9541 Ox70 Master Selector - chmod 755 /sys/bus/i2c/devices/i2c-${devnum}/new_device - echo pca9541 0x70 > /sys/bus/i2c/devices/i2c-${devnum}/new_device sleep 1 # Attach PCA9548 0x71 Channel Extender for Main Board 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 9b456a7c9112..a36e2cd1377c 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 @@ -2,7 +2,7 @@ dx010/scripts/dx010_check_qsfp.sh usr/local/bin dx010/cfg/dx010-modules.conf etc/modules-load.d dx010/systemd/platform-modules-dx010.service lib/systemd/system dx010/scripts/fancontrol.sh etc/init.d -services/fancontrol/fancontrol.service lib/systemd/system +dx010/scripts/fancontrol.service lib/systemd/system services/fancontrol/fancontrol usr/local/bin 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 diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.postinst b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.postinst index 8dbf0ece6676..b198584282db 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.postinst +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.postinst @@ -6,4 +6,5 @@ systemctl start platform-modules-dx010.service systemctl start fancontrol.service /usr/local/bin/platform_api_mgnt.sh install +/etc/init.d/fancontrol.sh install diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init index 1dc0ea5cfeeb..80964d5338af 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init @@ -18,6 +18,7 @@ start) modprobe smc modprobe hlx_gpio_ich modprobe dps200 + modprobe cp210x found=0 for devnum in 0 1; do 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 df78b7a34ea4..167de45532db 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 @@ -1,7 +1,10 @@ haliburton/cfg/haliburton-modules.conf etc/modules-load.d haliburton/systemd/platform-modules-haliburton.service lib/systemd/system haliburton/script/fancontrol.sh etc/init.d -services/fancontrol/fancontrol.service lib/systemd/system +haliburton/script/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 +haliburton/script/popmsg.sh usr/local/bin +haliburton/script/udev_prefix.sh usr/local/bin +haliburton/script/50-ttyUSB-C0.rules etc/udev/rules.d diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.postinst b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.postinst index e62799bd591c..74a4a4b17928 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.postinst +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.postinst @@ -6,3 +6,5 @@ systemctl start platform-modules-haliburton.service systemctl start fancontrol.service /usr/local/bin/platform_api_mgnt.sh install +sudo chmod +x /usr/local/bin/udev_prefix.sh +sudo chmod +x /usr/local/bin/popmsg.sh diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.install index e17b5e9cae83..41a381eeb0ce 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.install +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.install @@ -1,2 +1,4 @@ seastone2/cfg/seastone2-modules.conf etc/modules-load.d seastone2/systemd/platform-modules-seastone2.service lib/systemd/system +seastone2/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-cel_seastone_2-r0 +services/platform_api/platform_api_mgnt.sh usr/local/bin \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.postinst b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.postinst index 9a8e57cb8e9c..f232a2cac59d 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.postinst +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.postinst @@ -1,3 +1,5 @@ depmod -a systemctl enable platform-modules-seastone2.service -systemctl start platform-modules-seastone2.service \ No newline at end of file +systemctl start platform-modules-seastone2.service + +/usr/local/bin/platform_api_mgnt.sh install diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/rules b/platform/broadcom/sonic-platform-modules-cel/debian/rules index 0ed48f9feaea..a7293e0b6700 100755 --- a/platform/broadcom/sonic-platform-modules-cel/debian/rules +++ b/platform/broadcom/sonic-platform-modules-cel/debian/rules @@ -16,6 +16,10 @@ override_dh_auto_build: cd $(MOD_SRC_DIR)/$${mod}; \ python2.7 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ cd $(MOD_SRC_DIR); \ + if [ $$mod = "seastone2" ]; then \ + cd services/platform_api; \ + python2 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ + fi \ done) override_dh_auto_install: diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/cfg/dx010-modules.conf b/platform/broadcom/sonic-platform-modules-cel/dx010/cfg/dx010-modules.conf index 66f002a5fc94..5bccc6578850 100644 --- a/platform/broadcom/sonic-platform-modules-cel/dx010/cfg/dx010-modules.conf +++ b/platform/broadcom/sonic-platform-modules-cel/dx010/cfg/dx010-modules.conf @@ -11,5 +11,4 @@ i2c-mux i2c-smbus i2c-mux-gpio -i2c-mux-pca954x diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/Makefile b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/Makefile index 9b0f10604811..29cf0f71d62b 100644 --- a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/Makefile +++ b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/Makefile @@ -1 +1 @@ -obj-m := dx010_cpld.o mc24lc64t.o emc2305.o dx010_wdt.o leds-dx010.o \ No newline at end of file +obj-m := dx010_cpld.o mc24lc64t.o emc2305.o dx010_wdt.o leds-dx010.o slx_gpio_ich.o \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010_cpld.c b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010_cpld.c index 7893220ff6d5..d8142777c6e1 100644 --- a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010_cpld.c +++ b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010_cpld.c @@ -65,6 +65,22 @@ #define INT2229 0x3d6 #define INT3032 0x3d7 +#define ABS_INT0108 0x260 +#define ABS_INT0910 0x261 +#define ABS_INT1118 0x2E0 +#define ABS_INT1921 0x2E1 +#define ABS_INT2229 0x3E0 +#define ABS_INT3032 0x3E1 + +#define ABS_INT_MSK0108 0x262 +#define ABS_INT_MSK0910 0x263 +#define ABS_INT_MSK1118 0x2E2 +#define ABS_INT_MSK1921 0x2E3 +#define ABS_INT_MSK2229 0x3E2 +#define ABS_INT_MSK3032 0x3E3 + +#define CPLD4_INT0 0x313 +#define CPLD4_INT0_MSK 0x315 #define LENGTH_PORT_CPLD 34 #define PORT_BANK1_START 1 @@ -322,12 +338,136 @@ static ssize_t get_modirq(struct device *dev, struct device_attribute *devattr, return sprintf(buf,"0x%8.8lx\n", irq & 0xffffffff); } +static ssize_t get_modprs_irq(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned long prs_int = 0; + + mutex_lock(&cpld_data->cpld_lock); + + /* Clear interrupt source */ + inb(CPLD4_INT0); + + prs_int = + (inb(ABS_INT3032) & 0x07) << (24+5) | + inb(ABS_INT2229) << (24-3) | + (inb(ABS_INT1921) & 0x07) << (16 + 2) | + inb(ABS_INT1118) << (16-6) | + (inb(ABS_INT0910) & 0x03 ) << 8 | + inb(ABS_INT0108); + + mutex_unlock(&cpld_data->cpld_lock); + + return sprintf(buf,"0x%8.8lx\n", prs_int & 0xffffffff); +} + +static ssize_t get_modprs_msk(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned long prs_int_msk = 0; + + mutex_lock(&cpld_data->cpld_lock); + + prs_int_msk = + (inb(ABS_INT_MSK3032) & 0x07) << (24+5) | + inb(ABS_INT_MSK2229) << (24-3) | + (inb(ABS_INT_MSK1921) & 0x07) << (16 + 2) | + inb(ABS_INT_MSK1118) << (16-6) | + (inb(ABS_INT_MSK0910) & 0x03 ) << 8 | + inb(ABS_INT_MSK0108); + + mutex_unlock(&cpld_data->cpld_lock); + + return sprintf(buf,"0x%8.8lx\n", prs_int_msk & 0xffffffff); +} + +static ssize_t set_modprs_msk(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + unsigned long prs_int_msk; + int err; + + mutex_lock(&cpld_data->cpld_lock); + + err = kstrtoul(buf, 16, &prs_int_msk); + if (err) + { + mutex_unlock(&cpld_data->cpld_lock); + return err; + } + + outb( (prs_int_msk >> 0) & 0xFF, ABS_INT_MSK0108); + outb( (prs_int_msk >> 8) & 0x03, ABS_INT_MSK0910); + outb( (prs_int_msk >> 10) & 0xFF, ABS_INT_MSK1118); + outb( (prs_int_msk >> 18) & 0x07, ABS_INT_MSK1921); + outb( (prs_int_msk >> 21) & 0xFF, ABS_INT_MSK2229); + outb( (prs_int_msk >> 29) & 0x07, ABS_INT_MSK3032); + + mutex_unlock(&cpld_data->cpld_lock); + + return count; +} + +static ssize_t get_cpld4_int0(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned char int0 = 0; + + mutex_lock(&cpld_data->cpld_lock); + + int0 = inb(CPLD4_INT0); + + mutex_unlock(&cpld_data->cpld_lock); + + return sprintf(buf,"0x%2.2x\n", int0 & 0xff); +} + +static ssize_t get_cpld4_int0_msk(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned char int0_msk = 0; + + mutex_lock(&cpld_data->cpld_lock); + + int0_msk = inb(CPLD4_INT0_MSK); + + mutex_unlock(&cpld_data->cpld_lock); + + return sprintf(buf,"0x%2.2x\n", int0_msk & 0xff); +} + +static ssize_t set_cpld4_int0_msk(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + unsigned long int0_msk; + int err; + + mutex_lock(&cpld_data->cpld_lock); + + err = kstrtoul(buf, 16, &int0_msk); + if (err) + { + mutex_unlock(&cpld_data->cpld_lock); + return err; + } + + outb(int0_msk & 0x3f, CPLD4_INT0_MSK); + + mutex_unlock(&cpld_data->cpld_lock); + + return count; +} + static DEVICE_ATTR_RW(getreg); static DEVICE_ATTR_WO(setreg); static DEVICE_ATTR(qsfp_reset, S_IRUGO | S_IWUSR, get_reset, set_reset); static DEVICE_ATTR(qsfp_lpmode, S_IRUGO | S_IWUSR, get_lpmode, set_lpmode); static DEVICE_ATTR(qsfp_modprs, S_IRUGO, get_modprs, NULL); static DEVICE_ATTR(qsfp_modirq, S_IRUGO, get_modirq, NULL); +static DEVICE_ATTR(qsfp_modprs_irq, S_IRUGO, get_modprs_irq, NULL); +static DEVICE_ATTR(qsfp_modprs_msk, S_IRUGO | S_IWUSR, get_modprs_msk, set_modprs_msk); +static DEVICE_ATTR(cpld4_int0, S_IRUGO, get_cpld4_int0, NULL); +static DEVICE_ATTR(cpld4_int0_msk, S_IRUGO | S_IWUSR, get_cpld4_int0_msk, set_cpld4_int0_msk); static struct attribute *dx010_lpc_attrs[] = { &dev_attr_getreg.attr, @@ -336,6 +476,10 @@ static struct attribute *dx010_lpc_attrs[] = { &dev_attr_qsfp_lpmode.attr, &dev_attr_qsfp_modprs.attr, &dev_attr_qsfp_modirq.attr, + &dev_attr_qsfp_modprs_irq.attr, + &dev_attr_qsfp_modprs_msk.attr, + &dev_attr_cpld4_int0.attr, + &dev_attr_cpld4_int0_msk.attr, NULL, }; @@ -568,7 +712,7 @@ static struct i2c_adapter * cel_dx010_i2c_init(struct platform_device *pdev, int static int cel_dx010_lpc_drv_probe(struct platform_device *pdev) { struct resource *res; - int ret =0; + int ret = 0; int portid_count; cpld_data = devm_kzalloc(&pdev->dev, sizeof(struct dx010_cpld_data), @@ -594,6 +738,17 @@ static int cel_dx010_lpc_drv_probe(struct platform_device *pdev) cpld_data->i2c_adapter[portid_count-1] = cel_dx010_i2c_init(pdev, portid_count); + /* Enable INT0 interrupt register */ + outb(inb(CPLD4_INT0_MSK) & 0xf8, CPLD4_INT0_MSK); + + /* Enable modprs interrupt register */ + outb(0, ABS_INT_MSK0108); + outb(0, ABS_INT_MSK0910); + outb(0, ABS_INT_MSK1118); + outb(0, ABS_INT_MSK1921); + outb(0, ABS_INT_MSK2229); + outb(0, ABS_INT_MSK3032); + return 0; } @@ -634,7 +789,7 @@ void cel_dx010_lpc_exit(void) module_init(cel_dx010_lpc_init); module_exit(cel_dx010_lpc_exit); -MODULE_AUTHOR("Abhisit Sangjan "); -MODULE_AUTHOR("Pariwat Leamsumran "); +MODULE_AUTHOR("Pradchaya P "); +MODULE_VERSION("1.0.1"); MODULE_DESCRIPTION("Celestica SeaStone DX010 LPC Driver"); MODULE_LICENSE("GPL"); \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/slx_gpio_ich.c b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/slx_gpio_ich.c new file mode 100644 index 000000000000..0d6ca743b1fc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/slx_gpio_ich.c @@ -0,0 +1,1003 @@ +/* Copyright (c) 2018 Dell Inc. + * slx_gpio_ich.c - ICH driver for Rangeley switches + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "slx-ich" + +#define C2000_PCU_DEVICE_ID 0x1f38 + +// GPIO registers +// GPIO Core Control/Access Registers in I/O Space +#define GPIO_SC_USE_SEL 0x0 +#define GPIO_SC_IO_SEL 0x4 +#define GPIO_SC_GP_LVL 0x8 +#define GPIO_SC_TPE 0xC +#define GPIO_SC_TNE 0x10 +#define GPIO_SC_TS 0x14 + +// GPIO SUS Control/Access Registers in I/O Space +#define GPIO_SUS_USE_SEL 0x80 +#define GPIO_SUS_IO_SEL 0x84 +#define GPIO_SUS_GP_LVL 0x88 +#define GPIO_SUS_TPE 0x8C +#define GPIO_SUS_TNE 0x90 +#define GPIO_SUS_TS 0x94 +#define GPIO_SUS_WAKE_EN 0x98 + +static const unsigned char c2000_gpio_regs[] = { + GPIO_SC_USE_SEL, + GPIO_SC_IO_SEL, + GPIO_SC_GP_LVL, + GPIO_SC_TPE, + GPIO_SC_TNE, + GPIO_SC_TS, + GPIO_SUS_USE_SEL, + GPIO_SUS_IO_SEL, + GPIO_SUS_GP_LVL, + GPIO_SUS_TPE, + GPIO_SUS_TNE, + GPIO_SUS_TS, + GPIO_SUS_WAKE_EN +}; + +#define GPIO_REG_LEN 0x4 + +#define GPIOS0_EN (1 << 0) +#define GPIOS1_EN (1 << 1) +#define GPIOS2_EN (1 << 2) +#define GPIOS3_EN (1 << 3) +#define GPIOS4_EN (1 << 4) +#define GPIOS5_EN (1 << 5) +#define GPIOS6_EN (1 << 6) +#define GPIOS7_EN (1 << 7) + +#define GPIOSUS0_EN (1 << 0) +#define GPIOSUS1_EN (1 << 1) +#define GPIOSUS2_EN (1 << 2) +#define GPIOSUS3_EN (1 << 3) +// GPIOSUS4_EN : unused +// GPIOSUS5_EN : unused +#define GPIOSUS6_EN (1 << 6) +#define GPIOSUS7_EN (1 << 7) + + +// GPE0a_EN - General Purpose Event 0 Enables +#define GPIO_GPE0a_EN_SUS0 (1 << 16) +#define GPIO_GPE0a_EN_SUS1 (1 << 17) +#define GPIO_GPE0a_EN_SUS2 (1 << 18) +#define GPIO_GPE0a_EN_SUS3 (1 << 19) +// GPIO_GPE0a_EN_SUS4 : unused +// GPIO_GPE0a_EN_SUS5 : unused +#define GPIO_GPE0a_EN_SUS6 (1 << 22) +#define GPIO_GPE0a_EN_SUS7 (1 << 23) + +#define GPIO_GPE0a_EN_CORE0 (1 << 24) +#define GPIO_GPE0a_EN_CORE1 (1 << 25) +#define GPIO_GPE0a_EN_CORE2 (1 << 26) +#define GPIO_GPE0a_EN_CORE3 (1 << 27) +#define GPIO_GPE0a_EN_CORE4 (1 << 28) +#define GPIO_GPE0a_EN_CORE5 (1 << 29) +#define GPIO_GPE0a_EN_CORE6 (1 << 30) +#define GPIO_GPE0a_EN_CORE7 (1 << 31) + +// GPE0a_STS - General Purpose Event 0 Status +// We're interested in only SUS6 for now +#define GPIO_GPE0a_STS_SUS6 (1 << 22) +#define GPIO_GPE0a_STS_SUS7 (1 << 23) + +// GPIO_ROUT - GPIO_ROUT Register +#define GPIO_ROUT_OFFSET_SUS0 0 +#define GPIO_ROUT_OFFSET_SUS1 2 +#define GPIO_ROUT_OFFSET_SUS2 4 +#define GPIO_ROUT_OFFSET_SUS3 6 +// GPIO_ROUT_OFFSET_SUS4 : unused +// GPIO_ROUT_OFFSET_SUS5 : unused +#define GPIO_ROUT_OFFSET_SUS6 12 +#define GPIO_ROUT_OFFSET_SUS7 14 + +#define GPIO_ROUT_OFFSET_CORE0 16 +#define GPIO_ROUT_OFFSET_CORE1 18 +#define GPIO_ROUT_OFFSET_CORE2 20 +#define GPIO_ROUT_OFFSET_CORE3 22 +#define GPIO_ROUT_OFFSET_CORE4 24 +#define GPIO_ROUT_OFFSET_CORE5 26 +#define GPIO_ROUT_OFFSET_CORE6 28 +#define GPIO_ROUT_OFFSET_CORE7 30 + +enum GPIO_ROUT { + GPIO_NO_EFFECT = 0, + GPIO_SMI, + GPIO_SCI, + GPIO_RESERVED +}; + +/* + * GPIO resources + * defined as in drivers/gpio/gpio-ich.c + */ +#define ICH_RES_GPIO 0 +#define ICH_RES_GPE0 1 +static struct resource gpio_ich_res[] = { + /* GPIO */ + { + .flags = IORESOURCE_IO, + }, + /* ACPI - GPE0 */ + { + .flags = IORESOURCE_IO, + }, +}; + +// ACPI registers +#define ACPI_GPE0a_STS 0x20 +#define ACPI_GPE0a_EN 0x28 + +// PMC registers +#define PMC_GPIO_ROUT 0x58 +#define PMC_REG_LEN 0x4 + +// lpc_ich_priv is derived from drivers/mfd/lpc_ich.c +struct lpc_ich_priv { + int chipset; + + int abase; /* ACPI base */ + int actrl_pbase; /* ACPI control or PMC base */ + int gbase; /* GPIO base */ + int gctrl; /* GPIO control */ + + int abase_save; /* Cached ACPI base value */ + int actrl_pbase_save; /* Cached ACPI control or PMC base value */ + int gctrl_save; /* Cached GPIO control value */ +}; + +#define ICH_RES_MEM_GCS_PMC 0 + +#define IO_REG_WRITE(val, reg, base_res) outl(val, (reg) + (base_res)->start) +#define IO_REG_READ(reg, base_res) inl((reg) + (base_res)->start) + +struct resource pmc_res = {.flags = IORESOURCE_MEM,}; + +static struct kobject *slx_kobj; +static unsigned short force_id; +module_param(force_id, ushort, 0); + +struct slx_ich_data { + struct resource *gpio_base, *acpi_base, *pmc_base; + int gpio_alloc,pmc_alloc; + unsigned int int_gpio_sus6_count; +}; + +// GPIO sysfs attributes + +static ssize_t get_sc_use_sel(struct device *dev, struct device_attribute *devattr, char *buf) +{ + u32 devdata=0; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + if(!ich_data) return sprintf(buf, "read error"); + + devdata = IO_REG_READ(GPIO_SC_USE_SEL,ich_data->gpio_base); + return sprintf(buf,"0x%08x\n",devdata); +} + +static ssize_t set_sc_use_sel(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + unsigned long devdata; + int err; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + err = kstrtoul(buf, 16, &devdata); + if (err) + return err; + + IO_REG_WRITE(devdata,GPIO_SUS_USE_SEL,ich_data->gpio_base); + + return count; +} + +static ssize_t get_sc_io_sel(struct device *dev, struct device_attribute *devattr, char *buf) +{ + u32 devdata=0; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + if(!ich_data) return sprintf(buf, "read error"); + + devdata = IO_REG_READ(GPIO_SC_IO_SEL,ich_data->gpio_base); + return sprintf(buf,"0x%08x\n",devdata); +} + +static ssize_t set_sc_io_sel(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + unsigned long devdata; + int err; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + err = kstrtoul(buf, 16, &devdata); + if (err) + return err; + + IO_REG_WRITE(devdata,GPIO_SC_IO_SEL,ich_data->gpio_base); + + return count; +} + +static ssize_t get_sc_gp_lvl(struct device *dev, struct device_attribute *devattr, char *buf) +{ + u32 devdata=0; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + if(!ich_data) return sprintf(buf, "read error"); + + devdata = IO_REG_READ(GPIO_SC_GP_LVL,ich_data->gpio_base); + return sprintf(buf,"0x%08x\n",devdata); +} + +static ssize_t set_sc_gp_lvl(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + unsigned long devdata; + int err; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + err = kstrtoul(buf, 16, &devdata); + if (err) + return err; + + IO_REG_WRITE(devdata,GPIO_SC_GP_LVL,ich_data->gpio_base); + + return count; +} + +static ssize_t get_sc_gp_tpe(struct device *dev, struct device_attribute *devattr, char *buf) +{ + u32 devdata=0; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + if(!ich_data) return sprintf(buf, "read error"); + + devdata = IO_REG_READ(GPIO_SC_TPE,ich_data->gpio_base); + return sprintf(buf,"0x%08x\n",devdata); +} + +static ssize_t set_sc_gp_tpe(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + unsigned long devdata; + int err; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + err = kstrtoul(buf, 16, &devdata); + if (err) + return err; + + IO_REG_WRITE(devdata,GPIO_SC_TPE,ich_data->gpio_base); + + return count; +} + +static ssize_t get_sc_gp_tne(struct device *dev, struct device_attribute *devattr, char *buf) +{ + u32 devdata=0; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + if(!ich_data) return sprintf(buf, "read error"); + + devdata = IO_REG_READ(GPIO_SC_TNE,ich_data->gpio_base); + return sprintf(buf,"0x%08x\n",devdata); +} + +static ssize_t set_sc_gp_tne(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + unsigned long devdata; + int err; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + err = kstrtoul(buf, 16, &devdata); + if (err) + return err; + + IO_REG_WRITE(devdata,GPIO_SC_TNE,ich_data->gpio_base); + + return count; +} + +static ssize_t get_sc_gp_ts(struct device *dev, struct device_attribute *devattr, char *buf) +{ + u32 devdata=0; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + if(!ich_data) return sprintf(buf, "read error"); + + devdata = IO_REG_READ(GPIO_SC_TS,ich_data->gpio_base); + return sprintf(buf,"0x%08x\n",devdata); +} + +static ssize_t set_sc_gp_ts(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + unsigned long devdata; + int err; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + err = kstrtoul(buf, 16, &devdata); + if (err) + return err; + + IO_REG_WRITE(devdata,GPIO_SC_TS,ich_data->gpio_base); + + return count; +} + +static ssize_t get_sus_use_sel(struct device *dev, struct device_attribute *devattr, char *buf) +{ + u32 devdata=0; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + if(!ich_data) return sprintf(buf, "read error"); + + devdata = IO_REG_READ(GPIO_SUS_USE_SEL,ich_data->gpio_base); + return sprintf(buf,"0x%08x\n",devdata); +} + +static ssize_t set_sus_use_sel(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + unsigned long devdata; + int err; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + err = kstrtoul(buf, 16, &devdata); + if (err) + return err; + + IO_REG_WRITE(devdata,GPIO_SUS_USE_SEL,ich_data->gpio_base); + + return count; +} + +static ssize_t get_sus_io_sel(struct device *dev, struct device_attribute *devattr, char *buf) +{ + u32 devdata=0; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + if(!ich_data) return sprintf(buf, "read error"); + + devdata = IO_REG_READ(GPIO_SUS_IO_SEL,ich_data->gpio_base); + return sprintf(buf,"0x%08x\n",devdata); +} + +static ssize_t set_sus_io_sel(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + unsigned long devdata; + int err; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + err = kstrtoul(buf, 16, &devdata); + if (err) + return err; + + IO_REG_WRITE(devdata,GPIO_SUS_IO_SEL,ich_data->gpio_base); + + return count; +} + +static ssize_t get_sus_gp_lvl(struct device *dev, struct device_attribute *devattr, char *buf) +{ + u32 devdata=0; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + if(!ich_data) return sprintf(buf, "read error"); + + devdata = IO_REG_READ(GPIO_SUS_GP_LVL,ich_data->gpio_base); + return sprintf(buf,"0x%08x\n",devdata); +} + +static ssize_t set_sus_gp_lvl(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + unsigned long devdata; + int err; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + err = kstrtoul(buf, 16, &devdata); + if (err) + return err; + + IO_REG_WRITE(devdata,GPIO_SUS_GP_LVL,ich_data->gpio_base); + + return count; +} + +static ssize_t get_sus_gp_tpe(struct device *dev, struct device_attribute *devattr, char *buf) +{ + u32 devdata=0; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + if(!ich_data) return sprintf(buf, "read error"); + + devdata = IO_REG_READ(GPIO_SUS_TPE,ich_data->gpio_base); + return sprintf(buf,"0x%08x\n",devdata); +} + +static ssize_t set_sus_gp_tpe(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + unsigned long devdata; + int err; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + err = kstrtoul(buf, 16, &devdata); + if (err) + return err; + + IO_REG_WRITE(devdata,GPIO_SUS_TPE,ich_data->gpio_base); + + return count; +} + +static ssize_t get_sus_gp_tne(struct device *dev, struct device_attribute *devattr, char *buf) +{ + u32 devdata=0; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + if(!ich_data) return sprintf(buf, "read error"); + + devdata = IO_REG_READ(GPIO_SUS_TNE,ich_data->gpio_base); + return sprintf(buf,"0x%08x\n",devdata); +} + +static ssize_t set_sus_gp_tne(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + unsigned long devdata; + int err; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + err = kstrtoul(buf, 16, &devdata); + if (err) + return err; + + IO_REG_WRITE(devdata,GPIO_SUS_TNE,ich_data->gpio_base); + + return count; +} + +static ssize_t get_sus_gp_ts(struct device *dev, struct device_attribute *devattr, char *buf) +{ + u32 devdata=0; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + if(!ich_data) return sprintf(buf, "read error"); + + devdata = IO_REG_READ(GPIO_SUS_TS,ich_data->gpio_base); + return sprintf(buf,"0x%08x\n",devdata); +} + +static ssize_t set_sus_gp_ts(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + unsigned long devdata; + int err; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + err = kstrtoul(buf, 16, &devdata); + if (err) + return err; + + IO_REG_WRITE(devdata,GPIO_SUS_TS,ich_data->gpio_base); + + return count; +} + +static DEVICE_ATTR(sc_use_sel, S_IRUGO | S_IWUSR, get_sc_use_sel, set_sc_use_sel); +static DEVICE_ATTR(sc_io_sel, S_IRUGO | S_IWUSR, get_sc_io_sel, set_sc_io_sel); +static DEVICE_ATTR(sc_gp_lvl, S_IRUGO | S_IWUSR, get_sc_gp_lvl, set_sc_gp_lvl); +static DEVICE_ATTR(sc_gp_tpe, S_IRUGO | S_IWUSR, get_sc_gp_tpe, set_sc_gp_tpe); +static DEVICE_ATTR(sc_gp_tne, S_IRUGO | S_IWUSR, get_sc_gp_tne, set_sc_gp_tne); +static DEVICE_ATTR(sc_gp_ts, S_IRUGO | S_IWUSR, get_sc_gp_ts, set_sc_gp_ts); +static DEVICE_ATTR(sus_use_sel, S_IRUGO | S_IWUSR, get_sus_use_sel,set_sus_use_sel); +static DEVICE_ATTR(sus_io_sel, S_IRUGO | S_IWUSR, get_sus_io_sel, set_sus_io_sel); +static DEVICE_ATTR(sus_gp_lvl, S_IRUGO | S_IWUSR, get_sus_gp_lvl, set_sus_gp_lvl); +static DEVICE_ATTR(sus_gp_tpe, S_IRUGO | S_IWUSR, get_sus_gp_tpe, set_sus_gp_tpe); +static DEVICE_ATTR(sus_gp_tne, S_IRUGO | S_IWUSR, get_sus_gp_tne, set_sus_gp_tne); +static DEVICE_ATTR(sus_gp_ts, S_IRUGO | S_IWUSR, get_sus_gp_ts, set_sus_gp_ts); + +static struct attribute *gpio_attrs[] = { + &dev_attr_sc_use_sel.attr, + &dev_attr_sc_io_sel.attr, + &dev_attr_sc_gp_lvl.attr, + &dev_attr_sc_gp_tpe.attr, + &dev_attr_sc_gp_tne.attr, + &dev_attr_sc_gp_ts.attr, + &dev_attr_sus_use_sel.attr, + &dev_attr_sus_io_sel.attr, + &dev_attr_sus_gp_lvl.attr, + &dev_attr_sus_gp_tpe.attr, + &dev_attr_sus_gp_tne.attr, + &dev_attr_sus_gp_ts.attr, + NULL, +}; + +static struct attribute_group gpio_attrs_group= { + .attrs = gpio_attrs, +}; + +// ACPI sysfs attributes + +static ssize_t get_gpe0a_sts(struct device *dev, struct device_attribute *devattr, char *buf) +{ + u32 devdata=0; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + if(!ich_data) return sprintf(buf, "read error"); + + devdata = IO_REG_READ(ACPI_GPE0a_STS,ich_data->acpi_base); + return sprintf(buf,"0x%08x\n",devdata); +} + +static ssize_t set_gpe0a_sts(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + unsigned long devdata; + int err; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + err = kstrtoul(buf, 16, &devdata); + if (err) + return err; + + IO_REG_WRITE(devdata,ACPI_GPE0a_STS,ich_data->acpi_base); + + return count; +} + +static ssize_t get_gpe0a_en(struct device *dev, struct device_attribute *devattr, char *buf) +{ + u32 devdata=0; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + if(!ich_data) return sprintf(buf, "read error"); + + devdata = IO_REG_READ(ACPI_GPE0a_EN,ich_data->acpi_base); + return sprintf(buf,"0x%08x\n",devdata); +} + +static ssize_t set_gpe0a_en(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + unsigned long devdata; + int err; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + err = kstrtoul(buf, 16, &devdata); + if (err) + return err; + + IO_REG_WRITE(devdata,ACPI_GPE0a_EN,ich_data->acpi_base); + + return count; +} + +static DEVICE_ATTR(gpe0a_sts, S_IRUGO | S_IWUSR, get_gpe0a_sts, set_gpe0a_sts); +static DEVICE_ATTR(gpe0a_en, S_IRUGO | S_IWUSR, get_gpe0a_en, set_gpe0a_en); + +static struct attribute *acpi_attrs[] = { + &dev_attr_gpe0a_sts.attr, + &dev_attr_gpe0a_en.attr, + NULL, +}; + +static struct attribute_group acpi_attrs_group= { + .attrs = acpi_attrs, +}; + +static ssize_t get_gpio_rout(struct device *dev, struct device_attribute *devattr, char *buf) +{ + u32 devdata=0; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + if(!ich_data) return sprintf(buf, "read error"); + + devdata = readl(ich_data->pmc_base); + return sprintf(buf,"0x%08x\n",devdata); +} + +// PMC sysfs attributes + +static ssize_t set_gpio_rout(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + unsigned long devdata; + int err; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + err = kstrtoul(buf, 16, &devdata); + if (err) + return err; + + writel(devdata,ich_data->pmc_base); + + return count; +} + +static DEVICE_ATTR(gpio_rout, S_IRUGO | S_IWUSR, get_gpio_rout, set_gpio_rout); + +static struct attribute *pmc_attrs[] = { + &dev_attr_gpio_rout.attr, + NULL, +}; + +static struct attribute_group pmc_attrs_group= { + .attrs = pmc_attrs, +}; + +// SCI interrupt sysfs attributes + +static ssize_t get_sci_int_gpio_sus6(struct device *dev, struct device_attribute *devattr, char *buf) +{ + u32 devdata=0; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + if(!ich_data) return sprintf(buf, "read error"); + + devdata = ich_data->int_gpio_sus6_count; + return sprintf(buf,"0x%08x\n",devdata); +} + +static ssize_t set_sci_int_gpio_sus6(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + unsigned long devdata; + int err; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + err = kstrtoul(buf, 16, &devdata); + if (err) + return err; + + ich_data->int_gpio_sus6_count = devdata; + + return count; +} + +static DEVICE_ATTR(sci_int_gpio_sus6, S_IRUGO | S_IWUSR, get_sci_int_gpio_sus6, set_sci_int_gpio_sus6); + +static struct attribute *sci_attrs[] = { + &dev_attr_sci_int_gpio_sus6.attr, + NULL, +}; + +static struct attribute_group sci_attrs_group= { + .attrs = sci_attrs, +}; + +static u32 slx_ich_sci_handler(void *context) +{ + unsigned int data; + struct device *dev = (struct device *)context; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + if(!dev) return ACPI_INTERRUPT_NOT_HANDLED; + + ich_data = dev_get_platdata(dev); + if(!ich_data) return ACPI_INTERRUPT_NOT_HANDLED; + + data=IO_REG_READ(ACPI_GPE0a_STS,ich_data->acpi_base); + if(data & GPIO_GPE0a_STS_SUS6) { + // Clear the SUS6 status + IO_REG_WRITE(data,ACPI_GPE0a_STS,ich_data->acpi_base); + ich_data->int_gpio_sus6_count++; + // and notify the user space clients + sysfs_notify(&dev->kobj, NULL, "sci_int_gpio_sus6"); + return ACPI_INTERRUPT_HANDLED; + } + + return ACPI_INTERRUPT_NOT_HANDLED; +} + +/* + * Setup GPIO SUS6 to generate an SCI interrupt for optics detection + * This can be alternatively be setup using sysfs + */ +int setup_gpio_sus6_sci_interrupt(struct device *dev) +{ + int ret=0; + unsigned int data; + struct resource *acpi_base, *pmc_base, *gpio_base; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + + gpio_base = ich_data->gpio_base; + acpi_base = ich_data->acpi_base; + pmc_base = ich_data->pmc_base; + + // Enable GPIOSUS6_EN + data = IO_REG_READ(GPIO_SUS_USE_SEL,gpio_base); + data |= GPIOSUS6_EN; + IO_REG_WRITE(data,GPIO_SUS_USE_SEL,gpio_base); + + // GPIOSUS6_EN is input + data = IO_REG_READ(GPIO_SUS_IO_SEL,gpio_base); + data |= GPIOSUS6_EN; + IO_REG_WRITE(data,GPIO_SUS_IO_SEL,gpio_base); + + // Clear the positive edge for GPIOSUS6_EN + data = IO_REG_READ(GPIO_SUS_TPE,gpio_base); + data &= ~(GPIOSUS6_EN); + IO_REG_WRITE(data,GPIO_SUS_TPE,gpio_base); + + // Trigger on negative edge for GPIOSUS6_EN + data = IO_REG_READ(GPIO_SUS_TNE,gpio_base); + data |= GPIOSUS6_EN; + IO_REG_WRITE(data,GPIO_SUS_TNE,gpio_base); + + // Enable GPE for SUS6 to generate an SCI + data=IO_REG_READ(ACPI_GPE0a_EN,acpi_base); + data|=GPIO_GPE0a_EN_SUS6; + IO_REG_WRITE(data,ACPI_GPE0a_EN,acpi_base); + + data=readl(pmc_base); + data=(data & ~(0x3 << GPIO_ROUT_OFFSET_SUS6)) | (GPIO_SCI << GPIO_ROUT_OFFSET_SUS6); + writel(data,pmc_base); + + ret = acpi_install_sci_handler(slx_ich_sci_handler,(void*)dev); + if(ret) { + pr_info("slx_ich acpi_install_sci_handler failed %d\n",ret); + return ret; + } + + return ret; +} + +static int slx_ich_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + struct pci_dev *lpc_ich_dev; + struct lpc_ich_priv *priv; + struct resource *res; + unsigned int base_addr_cfg, base_addr; + int ret,i; + + // Get the PCU device + lpc_ich_dev=pci_get_device(PCI_VENDOR_ID_INTEL,C2000_PCU_DEVICE_ID,NULL); + priv=(struct lpc_ich_priv*) pci_get_drvdata(lpc_ich_dev); + if(!priv) { + pr_info("slx_ich: Unable to retrieve private data\n"); + return -ENODEV; + } + + // Retrieve the GPIO Base (that was initialized by lpc-ich) + pci_read_config_dword(lpc_ich_dev, priv->gbase, &base_addr_cfg); + base_addr = base_addr_cfg & 0x0000ff80; + if (!base_addr) { + pr_info("slx_ich I/O space for GPIO uninitialized\n"); + ret = -ENODEV; + goto probe_err; + } + + res = &gpio_ich_res[ICH_RES_GPIO]; + res->start = base_addr; + res->end = res->start + 0x9c - 1; + ret = acpi_check_resource_conflict(res); + if (ret) { + pr_info("slx_ich gpio resource conflict ret %d\n",ret); + } + + ich_data->gpio_base=res; + // Request regions for GPIO registers + for(i=0; istart+c2000_gpio_regs[i],GPIO_REG_LEN, "slx_ich_gpio")) { + pr_info("slx_ich: request_region failed for GPIO : %x\n",(unsigned int) res->start+c2000_gpio_regs[i]); + ret = -EBUSY; + goto probe_err; + } + ich_data->gpio_alloc |= (1<kobj, &gpio_attrs_group); + if (ret) { + pr_info("slx_ich cannot create sysfs for GPIO %d\n",ret); + ret = -ENOMEM; + goto probe_err; + } + + // Retrieve the ACPI Base (that was initialized by lpc-ich) + pci_read_config_dword(lpc_ich_dev, priv->abase, &base_addr_cfg); + base_addr = base_addr_cfg & 0x0000ff80; + if (!base_addr) { + pr_info("slx_ich I/O space for ACPI uninitialized\n"); + ret = -ENODEV; + goto probe_err; + } + + res = &gpio_ich_res[ICH_RES_GPE0]; + res->start = base_addr; + res->end = base_addr + 0x40; + ret = acpi_check_resource_conflict(res); + if (ret) { + pr_info("slx_ich acpi resource conflict ret %d\n",ret); + } + + // ACPI region is requested by pnp 00:01/ACPI GPE0_BLK + ich_data->acpi_base=res; + + /* Register sysfs hooks for ACPI */ + ret = sysfs_create_group(&dev->kobj, &acpi_attrs_group); + if (ret) { + pr_info("slx_ich cannot create sysfs for ACPI %d\n",ret); + ret = -ENOMEM; + goto probe_err; + } + + // Retrieve the PMC Base (that was initialized by lpc-ich) + pci_read_config_dword(lpc_ich_dev, priv->actrl_pbase, &base_addr_cfg); + base_addr = base_addr_cfg & 0xfffffe00; + pr_info("slx_ich base_addr_cfg %x base_addr %x\n",(int)base_addr_cfg,(int)base_addr); + if (!base_addr) { + pr_info("slx_ich PMC space for GPIO uninitialized\n"); + ret = -ENODEV; + goto probe_err; + } + + res = &pmc_res; + res->start = base_addr + PMC_GPIO_ROUT; + res->end = base_addr + PMC_GPIO_ROUT + PMC_REG_LEN - 1; + pr_info("slx_ich pmc res_start:end %x:%x\n",(int)res->start,(int)res->end); + + ret = acpi_check_resource_conflict(res); + if (ret) { + pr_info("slx_ich acpi resource conflict ret %d\n",ret); + } + + if (!request_mem_region(res->start,resource_size(res),"slx_ich_pmc")) { + pr_info("slx_ich pmc request_region failed\n"); + ret = -EBUSY; + goto probe_err; + } else { + ich_data->pmc_alloc=1; + } + + ich_data->pmc_base = ioremap(res->start, resource_size(res)); + if(!ich_data->pmc_base) { + pr_info("slx_ich pmc ioremap failed\n"); + ret = -ENOMEM; + goto probe_err; + } + + /* Register sysfs hooks for pmc */ + ret = sysfs_create_group(&dev->kobj, &pmc_attrs_group); + if (ret) { + pr_info("slx_ich cannot create sysfs for PMC %d\n",ret); + ret = -ENOMEM; + goto probe_err; + } + + /* Register sysfs hooks for SCI interrupts*/ + ret = sysfs_create_group(&dev->kobj, &sci_attrs_group); + if (ret) { + pr_info("slx_ich cannot create sysfs for SCI %d\n",ret); + ret = -ENOMEM; + goto probe_err; + } + + ret = setup_gpio_sus6_sci_interrupt(dev); + if (ret) { + pr_info("slx_ich unable to setup SCI interrupt %d\n",ret); + goto probe_err; + } + + return 0; + +probe_err: + pr_info("slx_ich slx_ich_probe failed with : %d\n",ret); + return ret; +} + +static int slx_ich_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct slx_ich_data *ich_data = dev_get_platdata(dev); + int i,ret; + + // Release GPIO regions + for(i=0; igpio_alloc & (1<gpio_base->start+c2000_gpio_regs[i], GPIO_REG_LEN); + } + } + + // Unmap and release PMC regions + if(ich_data->pmc_base) iounmap(ich_data->pmc_base); + if(ich_data->pmc_alloc) release_region(pmc_res.start, PMC_REG_LEN); + + ret = acpi_remove_sci_handler(slx_ich_sci_handler); + if(ret) { + pr_info("slx_ich acpi_remove_sci_handler failed %d\n",ret); + return ret; + } + + pr_info("slx_ich : slx_ich_remove done.\n"); + + return 0; +} + +static struct platform_driver slx_ich_driver= { + .driver = { + .name = DRV_NAME, + }, + .probe = slx_ich_probe, + .remove = slx_ich_remove, +}; + +static struct platform_device *pdev; + +static int __init slx_ich_init(void) +{ + int err; + struct slx_ich_data ich_data; + + memset(&ich_data, 0, sizeof(struct slx_ich_data)); + + err = platform_driver_register(&slx_ich_driver); + if (err) + goto exit; + + pdev = platform_device_alloc(DRV_NAME, 0); + if (!pdev) { + err = -ENOMEM; + pr_err("slx_ich: Device allocation failed\n"); + goto exit_unregister; + } + + err = platform_device_add_data(pdev, &ich_data, + sizeof(struct slx_ich_data)); + if (err) { + pr_err("slx_ich: Platform data allocation failed\n"); + goto exit_device_put; + } + + /* platform_device_add calls probe() */ + err = platform_device_add(pdev); + if (err) { + pr_err("slx_ich: Device addition failed (%d)\n", err); + goto exit_device_put; + } + + return 0; + +exit_device_put: + platform_device_put(pdev); +exit_unregister: + platform_driver_unregister(&slx_ich_driver); +exit: + pr_err("slx_ich: slx_ich_init failed (%d)\n", err); + return err; +} + +static void __exit slx_ich_exit(void) +{ + platform_device_unregister(pdev); + platform_driver_unregister(&slx_ich_driver); + + /*Remove sysfs slx_kobj*/ + kobject_put(slx_kobj); +} + +MODULE_AUTHOR("Padmanabhan Narayanan"); +MODULE_DESCRIPTION("ICH driver for Rangeley switches"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:"DRV_NAME); +MODULE_PARM_DESC(force_id, "Override the detected device ID"); + +module_init(slx_ich_init); +module_exit(slx_ich_exit); diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/scripts/fancontrol.service b/platform/broadcom/sonic-platform-modules-cel/dx010/scripts/fancontrol.service new file mode 100644 index 000000000000..25b9f34df2d0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/dx010/scripts/fancontrol.service @@ -0,0 +1,12 @@ +[Unit] +Description=fan speed regulator +After=platform-modules-dx010.service +Before=pmon.service + +[Service] +ExecStart=-/etc/init.d/fancontrol.sh start +ExecStop=-/etc/init.d/fancontrol.sh stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/scripts/fancontrol.sh b/platform/broadcom/sonic-platform-modules-cel/dx010/scripts/fancontrol.sh index 75ad6c65b37f..21274ed6e27d 100644 --- a/platform/broadcom/sonic-platform-modules-cel/dx010/scripts/fancontrol.sh +++ b/platform/broadcom/sonic-platform-modules-cel/dx010/scripts/fancontrol.sh @@ -7,75 +7,42 @@ # Default-Start: 2 3 4 5 # Default-Stop: # Short-Description: fancontrol -# Description: fan speed regulator +# Description: fancontrol configuration selector ### END INIT INFO . /lib/lsb/init-functions [ -f /etc/default/rcS ] && . /etc/default/rcS -PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin -DAEMON=/usr/local/bin/fancontrol -DESC="fan speed regulator" -NAME="fancontrol" -PIDFILE=/var/run/fancontrol.pid MAIN_CONF=/usr/share/sonic/device/x86_64-cel_seastone-r0/fancontrol -DEVPATH=/sys/devices/pci0000:00/0000:00:13.0/i2c-*/i2c-13/13-002e GPIO_DIR=/sys/class/gpio -BASE_GPIO=$(find $GPIO_DIR | grep gpiochip | grep -o '[[:digit:]]*') -DIRGPIO_START=15 -test -x $DAEMON || exit 0 +init() { + DIRGPIO_START=15 + BASE_GPIO=$(find $GPIO_DIR | grep gpiochip | grep -o '[[:digit:]]*') + FANDIR_GPIO_NUMBER=$((DIRGPIO_START + BASE_GPIO)) + FANDIR_VALUE=$(cat ${GPIO_DIR}/gpio${FANDIR_GPIO_NUMBER}/value) + DIRGPIO_START=$((DIRGPIO_START + 1)) + FANDIR=$([ $FANDIR_VALUE = 1 ] && echo "B2F" || echo "F2B") + CONF=${MAIN_CONF}-${FANDIR} + echo $FANDIR > /usr/share/sonic/device/x86_64-cel_seastone-r0/fan_airflow +} -for i in 1 2 3 4 5 -do - FANFAULT=$(cat ${DEVPATH}/fan${i}_fault) - [ $FANFAULT = 1 ] && continue - FANDIR_GPIO_NUMBER=$((DIRGPIO_START + BASE_GPIO)) - FANDIR_VALUE=$(cat ${GPIO_DIR}/gpio${FANDIR_GPIO_NUMBER}/value) - DIRGPIO_START=$((DIRGPIO_START+1)) - FANDIR=$([ $FANDIR_VALUE = 1 ] && echo "B2F" || echo "F2B") -done -CONF=${MAIN_CONF}-${FANDIR} +install() { + find /var/lib/docker/overlay*/ -path */sbin/fancontrol -exec cp /usr/local/bin/fancontrol {} \; +} case "$1" in - start) - if [ -f $CONF ] ; then - if $DAEMON --check $CONF 1>/dev/null 2>/dev/null ; then - log_daemon_msg "Starting $DESC" "$NAME\n" - start-stop-daemon --start --quiet --pidfile $PIDFILE --startas $DAEMON $CONF - log_end_msg $? - else - log_failure_msg "Not starting fancontrol, broken configuration file; please re-run pwmconfig." - fi - else - if [ "$VERBOSE" != no ]; then - log_warning_msg "Not starting fancontrol; run pwmconfig first." - fi - fi - ;; - stop) - log_daemon_msg "Stopping $DESC" "$NAME" - start-stop-daemon --stop --quiet --pidfile $PIDFILE --oknodo --startas $DAEMON $CONF - rm -f $PIDFILE - log_end_msg $? - ;; - restart) - $0 stop - sleep 3 - $0 start - ;; - force-reload) - if start-stop-daemon --stop --test --quiet --pidfile $PIDFILE --startas $DAEMON $CONF ; then - $0 restart - fi - ;; - status) - status_of_proc $DAEMON $NAME $CONF && exit 0 || exit $? - ;; - *) - log_success_msg "Usage: /etc/init.d/fancontrol {start|stop|restart|force-reload|status}" - exit 1 - ;; +start) + init + cp $CONF $MAIN_CONF + ;; +install) + install + ;; +*) + log_success_msg "Usage: /etc/init.d/fancontrol {start} | {install}" + exit 1 + ;; esac exit 0 diff --git a/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/dps200.c b/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/dps200.c index 6d5afdfb78b0..6279ca70decf 100644 --- a/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/dps200.c +++ b/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/dps200.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include "pmbus.h" diff --git a/platform/broadcom/sonic-platform-modules-cel/haliburton/script/50-ttyUSB-C0.rules b/platform/broadcom/sonic-platform-modules-cel/haliburton/script/50-ttyUSB-C0.rules new file mode 100644 index 000000000000..a4200daa71dd --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/haliburton/script/50-ttyUSB-C0.rules @@ -0,0 +1,254 @@ + + +LABEL="parent info" +ACTION=="add",KERNEL=="1-1",SUBSYSTEM=="usb",RUN+="/bin/bash -c '/usr/local/bin/udev_prefix.sh clear'" +ACTION=="add",KERNEL=="ttyUSB*",SUBSYSTEM=="tty",KERNELS=="1-1.1",ATTRS{idProduct}=="2517",ATTRS{idVendor}=="0424",RUN+="/bin/bash -c '/usr/local/bin/udev_prefix.sh C0-'",GOTO="C0 Add" +ACTION=="remove",KERNELS=="1-1.1",ENV{PRODUCT}=="*424/2517/*",RUN+="/bin/bash -c '/usr/local/bin/udev_prefix.sh clear'",GOTO="C0 Remove" + + +LABEL="C0 Add" +ACTION=="add",KERNELS=="1-1.1.1:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-1",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.1:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-2",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.1:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-3",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.1:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-4",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.2:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-5",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.2:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-6",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.2:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-7",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.2:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-8",MODE="0666" + +ACTION=="add",KERNELS=="1-1.1.3:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-9",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.3:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-10",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.3:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-11",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.3:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-12",MODE="0666" + +ACTION=="add",KERNELS=="1-1.1.4:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-13",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.4:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-14",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.4:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-15",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.4:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-16",MODE="0666" + +ACTION=="add",KERNELS=="1-1.1.5:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-17",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.5:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-18",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.5:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-19",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.5:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-20",MODE="0666" + +ACTION=="add",KERNELS=="1-1.1.6:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-21",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.6:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-22",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.6:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-23",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.6:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-24",MODE="0666" + +ACTION=="add",KERNELS=="1-1.1.7.1:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-25",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.1:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-26",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.1:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-27",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.1:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-28",MODE="0666" + +ACTION=="add",KERNELS=="1-1.1.7.2:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-29",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.2:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-30",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.2:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-31",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.2:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-32",MODE="0666" + +ACTION=="add",KERNELS=="1-1.1.7.3:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-33",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.3:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-34",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.3:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-35",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.3:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-36",MODE="0666" + +ACTION=="add",KERNELS=="1-1.1.7.4:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-37",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.4:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-38",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.4:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-39",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.4:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-40",MODE="0666" + +ACTION=="add",KERNELS=="1-1.1.7.5:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-41",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.5:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-42",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.5:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-43",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.5:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-44",MODE="0666" + +ACTION=="add",KERNELS=="1-1.1.7.6:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-45",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.6:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-46",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.6:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-47",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.6:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-48",MODE="0666" + +ACTION=="add",KERNELS=="1-1.1.7.7.1:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-49",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.1:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-50",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.1:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-51",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.1:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-52",MODE="0666" + +ACTION=="add",KERNELS=="1-1.1.7.7.2:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-53",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.2:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-54",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.2:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-55",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.2:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-56",MODE="0666" + +ACTION=="add",KERNELS=="1-1.1.7.7.3:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-57",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.3:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-58",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.3:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-59",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.3:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-60",MODE="0666" + +ACTION=="add",KERNELS=="1-1.1.7.7.4:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-61",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.4:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-62",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.4:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-63",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.4:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-64",MODE="0666" + +ACTION=="add",KERNELS=="1-1.1.7.7.5:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-65",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.5:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-66",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.5:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-67",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.5:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-68",MODE="0666" + +ACTION=="add",KERNELS=="1-1.1.7.7.6:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-69",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.6:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-70",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.6:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-71",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.6:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-72",MODE="0666" + +ACTION=="add",KERNELS=="1-1.1.7.7.7.1:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-73",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.7.1:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-74",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.7.1:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-75",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.7.1:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-76",MODE="0666" + +ACTION=="add",KERNELS=="1-1.1.7.7.7.2:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-77",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.7.2:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-78",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.7.2:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-79",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.7.2:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-80",MODE="0666" + +ACTION=="add",KERNELS=="1-1.1.7.7.7.3:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-81",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.7.3:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-82",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.7.3:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-83",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.7.3:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-84",MODE="0666" + +ACTION=="add",KERNELS=="1-1.1.7.7.7.4:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-85",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.7.4:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-86",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.7.4:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-87",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.7.4:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-88",MODE="0666" + +ACTION=="add",KERNELS=="1-1.1.7.7.7.5:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-89",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.7.5:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-90",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.7.5:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-91",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.7.5:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-92",MODE="0666" + +ACTION=="add",KERNELS=="1-1.1.7.7.7.6:1.0",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="00",ATTRS{interface}=="CP2108 Interface 0",SYMLINK+="C0-93",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.7.6:1.1",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="01",ATTRS{interface}=="CP2108 Interface 1",SYMLINK+="C0-94",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.7.6:1.2",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="02",ATTRS{interface}=="CP2108 Interface 2",SYMLINK+="C0-95",MODE="0666" +ACTION=="add",KERNELS=="1-1.1.7.7.7.6:1.3",DRIVERS=="cp210x",ATTRS{bInterfaceNumber}=="03",ATTRS{interface}=="CP2108 Interface 3",SYMLINK+="C0-96",MODE="0666" + + + +LABEL="C0 Remove" +ACTION=="remove",KERNELS=="1-1.1.1:1.0",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 1'" +ACTION=="remove",KERNELS=="1-1.1.1:1.1",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 2'" +ACTION=="remove",KERNELS=="1-1.1.1:1.2",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 3'" +ACTION=="remove",KERNELS=="1-1.1.1:1.3",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 4'" + +ACTION=="remove",KERNELS=="1-1.1.2:1.0",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 5'" +ACTION=="remove",KERNELS=="1-1.1.2:1.1",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 6'" +ACTION=="remove",KERNELS=="1-1.1.2:1.2",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 7'" +ACTION=="remove",KERNELS=="1-1.1.2:1.3",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 8'" + +ACTION=="remove",KERNELS=="1-1.1.3:1.0",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 9'" +ACTION=="remove",KERNELS=="1-1.1.3:1.1",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 10'" +ACTION=="remove",KERNELS=="1-1.1.3:1.2",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 11'" +ACTION=="remove",KERNELS=="1-1.1.3:1.3",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 12'" + +ACTION=="remove",KERNELS=="1-1.1.4:1.0",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 13" +ACTION=="remove",KERNELS=="1-1.1.4:1.1",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 14" +ACTION=="remove",KERNELS=="1-1.1.4:1.2",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 15" +ACTION=="remove",KERNELS=="1-1.1.4:1.3",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 16" + +ACTION=="remove",KERNELS=="1-1.1.5:1.0",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 17" +ACTION=="remove",KERNELS=="1-1.1.5:1.1",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 18" +ACTION=="remove",KERNELS=="1-1.1.5:1.2",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 19" +ACTION=="remove",KERNELS=="1-1.1.5:1.3",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 20" + +ACTION=="remove",KERNELS=="1-1.1.6:1.0",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 21" +ACTION=="remove",KERNELS=="1-1.1.6:1.1",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 22" +ACTION=="remove",KERNELS=="1-1.1.6:1.2",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 23" +ACTION=="remove",KERNELS=="1-1.1.6:1.3",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 24" + +ACTION=="remove",KERNELS=="1-1.1.7.1:1.0",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 25" +ACTION=="remove",KERNELS=="1-1.1.7.1:1.1",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 26" +ACTION=="remove",KERNELS=="1-1.1.7.1:1.2",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 27" +ACTION=="remove",KERNELS=="1-1.1.7.1:1.3",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 28" + +ACTION=="remove",KERNELS=="1-1.1.7.2:1.0",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 29" +ACTION=="remove",KERNELS=="1-1.1.7.2:1.1",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 30" +ACTION=="remove",KERNELS=="1-1.1.7.2:1.2",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 31" +ACTION=="remove",KERNELS=="1-1.1.7.2:1.3",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 32" + +ACTION=="remove",KERNELS=="1-1.1.7.3:1.0",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 33" +ACTION=="remove",KERNELS=="1-1.1.7.3:1.1",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 34" +ACTION=="remove",KERNELS=="1-1.1.7.3:1.2",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 35" +ACTION=="remove",KERNELS=="1-1.1.7.3:1.3",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 36" + +ACTION=="remove",KERNELS=="1-1.1.7.4:1.0",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 37" +ACTION=="remove",KERNELS=="1-1.1.7.4:1.1",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 38" +ACTION=="remove",KERNELS=="1-1.1.7.4:1.2",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 39" +ACTION=="remove",KERNELS=="1-1.1.7.4:1.3",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 40" + +ACTION=="remove",KERNELS=="1-1.1.7.5:1.0",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 41" +ACTION=="remove",KERNELS=="1-1.1.7.5:1.1",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 42" +ACTION=="remove",KERNELS=="1-1.1.7.5:1.2",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 43" +ACTION=="remove",KERNELS=="1-1.1.7.5:1.3",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 44" + +ACTION=="remove",KERNELS=="1-1.1.7.6:1.0",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 45" +ACTION=="remove",KERNELS=="1-1.1.7.6:1.1",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 46" +ACTION=="remove",KERNELS=="1-1.1.7.6:1.2",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 47" +ACTION=="remove",KERNELS=="1-1.1.7.6:1.3",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 48" + + +ACTION=="remove",KERNELS=="1-1.1.7.7.1:1.0",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 49" +ACTION=="remove",KERNELS=="1-1.1.7.7.1:1.1",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 50" +ACTION=="remove",KERNELS=="1-1.1.7.7.1:1.2",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 51" +ACTION=="remove",KERNELS=="1-1.1.7.7.1:1.3",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 52" + +ACTION=="remove",KERNELS=="1-1.1.7.7.2:1.0",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 53" +ACTION=="remove",KERNELS=="1-1.1.7.7.2:1.1",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 54" +ACTION=="remove",KERNELS=="1-1.1.7.7.2:1.2",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 55" +ACTION=="remove",KERNELS=="1-1.1.7.7.2:1.3",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 56" + +ACTION=="remove",KERNELS=="1-1.1.7.7.3:1.0",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 57" +ACTION=="remove",KERNELS=="1-1.1.7.7.3:1.1",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 58" +ACTION=="remove",KERNELS=="1-1.1.7.7.3:1.2",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 59" +ACTION=="remove",KERNELS=="1-1.1.7.7.3:1.3",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 60" + +ACTION=="remove",KERNELS=="1-1.1.7.7.4:1.0",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 61" +ACTION=="remove",KERNELS=="1-1.1.7.7.4:1.1",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 62" +ACTION=="remove",KERNELS=="1-1.1.7.7.4:1.2",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 63" +ACTION=="remove",KERNELS=="1-1.1.7.7.4:1.3",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 64" + +ACTION=="remove",KERNELS=="1-1.1.7.7.5:1.0",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 65" +ACTION=="remove",KERNELS=="1-1.1.7.7.5:1.1",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 66" +ACTION=="remove",KERNELS=="1-1.1.7.7.5:1.2",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 67" +ACTION=="remove",KERNELS=="1-1.1.7.7.5:1.3",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 68" + +ACTION=="remove",KERNELS=="1-1.1.7.7.6:1.0",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 69" +ACTION=="remove",KERNELS=="1-1.1.7.7.6:1.1",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 70" +ACTION=="remove",KERNELS=="1-1.1.7.7.6:1.2",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 71" +ACTION=="remove",KERNELS=="1-1.1.7.7.6:1.3",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 72" + + +ACTION=="remove",KERNELS=="1-1.1.7.7.7.1:1.0",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 73" +ACTION=="remove",KERNELS=="1-1.1.7.7.7.1:1.1",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 74" +ACTION=="remove",KERNELS=="1-1.1.7.7.7.1:1.2",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 75" +ACTION=="remove",KERNELS=="1-1.1.7.7.7.1:1.3",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 76" + +ACTION=="remove",KERNELS=="1-1.1.7.7.7.2:1.0",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 77" +ACTION=="remove",KERNELS=="1-1.1.7.7.7.2:1.1",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 78" +ACTION=="remove",KERNELS=="1-1.1.7.7.7.2:1.2",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 79" +ACTION=="remove",KERNELS=="1-1.1.7.7.7.2:1.3",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 80" + +ACTION=="remove",KERNELS=="1-1.1.7.7.7.3:1.0",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 81" +ACTION=="remove",KERNELS=="1-1.1.7.7.7.3:1.1",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 82" +ACTION=="remove",KERNELS=="1-1.1.7.7.7.3:1.2",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 83" +ACTION=="remove",KERNELS=="1-1.1.7.7.7.3:1.3",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 84" + +ACTION=="remove",KERNELS=="1-1.1.7.7.7.4:1.0",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 85" +ACTION=="remove",KERNELS=="1-1.1.7.7.7.4:1.1",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 86" +ACTION=="remove",KERNELS=="1-1.1.7.7.7.4:1.2",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 87" +ACTION=="remove",KERNELS=="1-1.1.7.7.7.4:1.3",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 88" + +ACTION=="remove",KERNELS=="1-1.1.7.7.7.5:1.0",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 89" +ACTION=="remove",KERNELS=="1-1.1.7.7.7.5:1.1",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 90" +ACTION=="remove",KERNELS=="1-1.1.7.7.7.5:1.2",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 91" +ACTION=="remove",KERNELS=="1-1.1.7.7.7.5:1.3",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 92" + +ACTION=="remove",KERNELS=="1-1.1.7.7.7.6:1.0",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 93" +ACTION=="remove",KERNELS=="1-1.1.7.7.7.6:1.1",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 94" +ACTION=="remove",KERNELS=="1-1.1.7.7.7.6:1.2",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 95" +ACTION=="remove",KERNELS=="1-1.1.7.7.7.6:1.3",ENV{PRODUCT}=="10c4/ea71/*",RUN+="/bin/bash -c '/usr/local/bin/popmsg.sh 96" + + diff --git a/platform/broadcom/sonic-platform-modules-cel/services/fancontrol/fancontrol.service b/platform/broadcom/sonic-platform-modules-cel/haliburton/script/fancontrol.service similarity index 100% rename from platform/broadcom/sonic-platform-modules-cel/services/fancontrol/fancontrol.service rename to platform/broadcom/sonic-platform-modules-cel/haliburton/script/fancontrol.service diff --git a/platform/broadcom/sonic-platform-modules-cel/haliburton/script/popmsg.sh b/platform/broadcom/sonic-platform-modules-cel/haliburton/script/popmsg.sh new file mode 100644 index 000000000000..0789c3a3ee42 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/haliburton/script/popmsg.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +dev="/dev/" +index=0 + +cnt=$(who | wc -l) +for((i=0;i ${list[$i]} +done + diff --git a/platform/broadcom/sonic-platform-modules-cel/haliburton/script/udev_prefix.sh b/platform/broadcom/sonic-platform-modules-cel/haliburton/script/udev_prefix.sh new file mode 100644 index 000000000000..c5842fab0a7e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/haliburton/script/udev_prefix.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +PREV_REBOOT_CAUSE="/host/reboot-cause/" +DEVICE="/usr/share/sonic/device" +PLATFORM=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) +PLATFORM_PATH=$DEVICE/$PLATFORM +FILENAME="udevprefix.conf" + +if [ "$1" = "clear" ] +then + if [ -e $PLATFORM_PATH/$FILENAME ]; then + rm $PLATFORM_PATH/$FILENAME + fi +else + if [ -e $PLATFORM_PATH/$FILENAME ]; then + : > $PLATFORM_PATH/$FILENAME + echo -n "$1" > $PLATFORM_PATH/$FILENAME + else + touch $PLATFORM_PATH/$FILENMAE + echo -n "$1" > $PLATFORM_PATH/$FILENAME + fi +fi + diff --git a/platform/broadcom/sonic-platform-modules-cel/seastone2/modules/switchboard_fpga.c b/platform/broadcom/sonic-platform-modules-cel/seastone2/modules/switchboard_fpga.c index c7a86e13d3ad..5918d27f3911 100644 --- a/platform/broadcom/sonic-platform-modules-cel/seastone2/modules/switchboard_fpga.c +++ b/platform/broadcom/sonic-platform-modules-cel/seastone2/modules/switchboard_fpga.c @@ -25,7 +25,7 @@ */ #ifndef TEST_MODE -#define MOD_VERSION "2.1.3" +#define MOD_VERSION "2.2.0" #else #define MOD_VERSION "TEST" #endif @@ -51,8 +51,6 @@ #include #include - - static int majorNumber; #define CLASS_NAME "seastone2_fpga" @@ -62,17 +60,16 @@ static int majorNumber; static int smbus_access(struct i2c_adapter *adapter, u16 addr, - unsigned short flags, char rw, u8 cmd, - int size, union i2c_smbus_data *data); + unsigned short flags, char rw, u8 cmd, + int size, union i2c_smbus_data *data); static int fpga_i2c_access(struct i2c_adapter *adapter, u16 addr, - unsigned short flags, char rw, u8 cmd, - int size, union i2c_smbus_data *data); + unsigned short flags, char rw, u8 cmd, + int size, union i2c_smbus_data *data); static int fpgafw_init(void); static void fpgafw_exit(void); - /* ======================================== FPGA PCIe BAR 0 Registers @@ -186,7 +183,6 @@ PORT XCVR 0x00004000 - 0x00004FFF. */ #define INTR_INT_N 5 #define INTR_PRESENT 4 -#define INTR_TXFAULT 2 #define INTR_RXLOS 1 #define INTR_MODABS 0 @@ -201,7 +197,6 @@ PORT XCVR 0x00004000 - 0x00004FFF. */ #define MASK_INT_N 5 #define MASK_PRESENT 4 -#define MASK_TXFAULT 2 #define MASK_RXLOS 1 #define MASK_MODABS 0 @@ -254,6 +249,7 @@ enum { static struct class* fpgafwclass = NULL; ///< The device-driver class struct pointer static struct device* fpgafwdev = NULL; ///< The device-driver device struct pointer +static struct platform_device *seastone2_dev; #define PCI_VENDOR_ID_TEST 0x1af4 @@ -287,7 +283,7 @@ enum PORT_TYPE { SFP }; -struct i2c_switch{ +struct i2c_switch { unsigned char master_bus; // I2C bus number unsigned char switch_addr; // PCA9548 device address, 0xFF if directly connect to a bus. unsigned char channel; // PCA9548 channel number. If the switch_addr is 0xFF, this value is ignored. @@ -303,32 +299,32 @@ struct i2c_dev_data { /* PREDEFINED I2C SWITCH DEVICE TOPOLOGY */ static struct i2c_switch fpga_i2c_bus_dev[] = { /* BUS2 QSFP Exported as virtual bus */ - {I2C_MASTER_CH_2,0x72,0,QSFP,"QSFP1"}, {I2C_MASTER_CH_2,0x72,1,QSFP,"QSFP2"}, - {I2C_MASTER_CH_2,0x72,2,QSFP,"QSFP3"}, {I2C_MASTER_CH_2,0x72,3,QSFP,"QSFP4"}, - {I2C_MASTER_CH_2,0x72,4,QSFP,"QSFP5"}, {I2C_MASTER_CH_2,0x72,5,QSFP,"QSFP6"}, - {I2C_MASTER_CH_2,0x72,6,QSFP,"QSFP7"}, {I2C_MASTER_CH_2,0x72,7,QSFP,"QSFP8"}, - {I2C_MASTER_CH_2,0x73,0,QSFP,"QSFP9"}, {I2C_MASTER_CH_2,0x73,1,QSFP,"QSFP10"}, - {I2C_MASTER_CH_2,0x73,2,QSFP,"QSFP11"},{I2C_MASTER_CH_2,0x73,3,QSFP,"QSFP12"}, - {I2C_MASTER_CH_2,0x73,4,QSFP,"QSFP13"},{I2C_MASTER_CH_2,0x73,5,QSFP,"QSFP14"}, - {I2C_MASTER_CH_2,0x73,6,QSFP,"QSFP15"},{I2C_MASTER_CH_2,0x73,7,QSFP,"QSFP16"}, - {I2C_MASTER_CH_2,0x74,0,QSFP,"QSFP17"},{I2C_MASTER_CH_2,0x74,1,QSFP,"QSFP18"}, - {I2C_MASTER_CH_2,0x74,2,QSFP,"QSFP19"},{I2C_MASTER_CH_2,0x74,3,QSFP,"QSFP20"}, - {I2C_MASTER_CH_2,0x74,4,QSFP,"QSFP21"},{I2C_MASTER_CH_2,0x74,5,QSFP,"QSFP22"}, - {I2C_MASTER_CH_2,0x74,6,QSFP,"QSFP23"},{I2C_MASTER_CH_2,0x74,7,QSFP,"QSFP24"}, - {I2C_MASTER_CH_2,0x75,0,QSFP,"QSFP25"},{I2C_MASTER_CH_2,0x75,1,QSFP,"QSFP26"}, - {I2C_MASTER_CH_2,0x75,2,QSFP,"QSFP27"},{I2C_MASTER_CH_2,0x75,3,QSFP,"QSFP28"}, - {I2C_MASTER_CH_2,0x75,4,QSFP,"QSFP29"},{I2C_MASTER_CH_2,0x75,5,QSFP,"QSFP30"}, - {I2C_MASTER_CH_2,0x75,6,QSFP,"QSFP31"},{I2C_MASTER_CH_2,0x75,7,QSFP,"QSFP32"}, + {I2C_MASTER_CH_2, 0x72, 0, QSFP, "QSFP1"}, {I2C_MASTER_CH_2, 0x72, 1, QSFP, "QSFP2"}, + {I2C_MASTER_CH_2, 0x72, 2, QSFP, "QSFP3"}, {I2C_MASTER_CH_2, 0x72, 3, QSFP, "QSFP4"}, + {I2C_MASTER_CH_2, 0x72, 4, QSFP, "QSFP5"}, {I2C_MASTER_CH_2, 0x72, 5, QSFP, "QSFP6"}, + {I2C_MASTER_CH_2, 0x72, 6, QSFP, "QSFP7"}, {I2C_MASTER_CH_2, 0x72, 7, QSFP, "QSFP8"}, + {I2C_MASTER_CH_2, 0x73, 0, QSFP, "QSFP9"}, {I2C_MASTER_CH_2, 0x73, 1, QSFP, "QSFP10"}, + {I2C_MASTER_CH_2, 0x73, 2, QSFP, "QSFP11"}, {I2C_MASTER_CH_2, 0x73, 3, QSFP, "QSFP12"}, + {I2C_MASTER_CH_2, 0x73, 4, QSFP, "QSFP13"}, {I2C_MASTER_CH_2, 0x73, 5, QSFP, "QSFP14"}, + {I2C_MASTER_CH_2, 0x73, 6, QSFP, "QSFP15"}, {I2C_MASTER_CH_2, 0x73, 7, QSFP, "QSFP16"}, + {I2C_MASTER_CH_2, 0x74, 0, QSFP, "QSFP17"}, {I2C_MASTER_CH_2, 0x74, 1, QSFP, "QSFP18"}, + {I2C_MASTER_CH_2, 0x74, 2, QSFP, "QSFP19"}, {I2C_MASTER_CH_2, 0x74, 3, QSFP, "QSFP20"}, + {I2C_MASTER_CH_2, 0x74, 4, QSFP, "QSFP21"}, {I2C_MASTER_CH_2, 0x74, 5, QSFP, "QSFP22"}, + {I2C_MASTER_CH_2, 0x74, 6, QSFP, "QSFP23"}, {I2C_MASTER_CH_2, 0x74, 7, QSFP, "QSFP24"}, + {I2C_MASTER_CH_2, 0x75, 0, QSFP, "QSFP25"}, {I2C_MASTER_CH_2, 0x75, 1, QSFP, "QSFP26"}, + {I2C_MASTER_CH_2, 0x75, 2, QSFP, "QSFP27"}, {I2C_MASTER_CH_2, 0x75, 3, QSFP, "QSFP28"}, + {I2C_MASTER_CH_2, 0x75, 4, QSFP, "QSFP29"}, {I2C_MASTER_CH_2, 0x75, 5, QSFP, "QSFP30"}, + {I2C_MASTER_CH_2, 0x75, 6, QSFP, "QSFP31"}, {I2C_MASTER_CH_2, 0x75, 7, QSFP, "QSFP32"}, /* BUS1 SFP+ Exported as virtual bus */ - {I2C_MASTER_CH_1,0x72,0,SFP,"SFP1"}, + {I2C_MASTER_CH_1, 0x72, 0, SFP, "SFP1"}, /* BUS3 Switchboard CPLD */ - {I2C_MASTER_CH_3,0xFF,0,NONE,"I2C_3"}, + {I2C_MASTER_CH_3, 0xFF, 0, NONE, "I2C_3"}, }; #define VIRTUAL_I2C_PORT_LENGTH ARRAY_SIZE(fpga_i2c_bus_dev) #define VIRTUAL_I2C_CPLD_INDEX SFF_PORT_TOTAL -struct fpga_device{ +struct fpga_device { /* data mmio region */ void __iomem *data_base_addr; resource_size_t data_mmio_start; @@ -373,82 +369,83 @@ static struct kobject *cpld2 = NULL; static struct device *sff_dev = NULL; /** - * [get_fpga_reg_value description] - * @param dev [description] - * @param devattr [description] - * @param buf [description] - * @return [description] + * Show the value of the register set by 'set_fpga_reg_address' + * If the address is not set by 'set_fpga_reg_address' first, + * The version register is selected by default. + * @param buf register value in hextring + * @return number of bytes read, or an error code */ -static ssize_t get_fpga_reg_value(struct device *dev, struct device_attribute *devattr, - char *buf) +static ssize_t get_fpga_reg_value(struct device *dev, + struct device_attribute *attr, char *buf) { // read data from the address uint32_t data; data = ioread32(fpga_data->fpga_read_addr); - return sprintf(buf,"0x%8.8x\n",data); + return sprintf(buf, "0x%8.8x\n", data); } + /** - * [set_fpga_reg_address description] - * @param dev [description] - * @param devattr [description] - * @param buf [description] - * @param count [description] - * @return [description] + * Store the register address + * @param buf address wanted to be read value of + * @return number of bytes stored, or an error code */ -static ssize_t set_fpga_reg_address(struct device *dev, struct device_attribute *devattr, - const char *buf, size_t count) +static ssize_t set_fpga_reg_address(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { + ssize_t status; uint32_t addr; - char *last; - addr = (uint32_t)strtoul(buf,&last,16); - if(addr == 0 && buf == last){ - return -EINVAL; + status = kstrtou32(buf, 0, &addr); + if (status == 0) { + fpga_data->fpga_read_addr = fpga_dev.data_base_addr + addr; + status = count; } - fpga_data->fpga_read_addr = fpga_dev.data_base_addr+addr; - return count; + return status; } + /** - * [get_fpga_scratch description] - * @param dev [description] - * @param devattr [description] - * @param buf [description] - * @return [description] + * Show value of fpga scratch register + * @param buf register value in hexstring + * @return number of bytes read, or an error code */ -static ssize_t get_fpga_scratch(struct device *dev, struct device_attribute *devattr, - char *buf) +static ssize_t get_fpga_scratch(struct device *dev, + struct device_attribute *attr, char *buf) { - return sprintf(buf,"0x%8.8x\n", ioread32(fpga_dev.data_base_addr+FPGA_SCRATCH) & 0xffffffff); + uint32_t data; + data = ioread32(fpga_dev.data_base_addr + FPGA_SCRATCH); + data &= 0xffffffff; + return sprintf(buf, "0x%8.8x\n", data); } + /** - * [set_fpga_scratch description] - * @param dev [description] - * @param devattr [description] - * @param buf [description] - * @param count [description] - * @return [description] + * Store value of fpga scratch register + * @param buf scratch register value passing from user space + * @return number of bytes stored, or an error code */ -static ssize_t set_fpga_scratch(struct device *dev, struct device_attribute *devattr, - const char *buf, size_t count) +static ssize_t set_fpga_scratch(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { + ssize_t status; uint32_t data; - char *last; - data = (uint32_t)strtoul(buf,&last,16); - if(data == 0 && buf == last){ - return -EINVAL; + + status = kstrtou32(buf, 0, &data); + if (status == 0) { + iowrite32(data, fpga_dev.data_base_addr + FPGA_SCRATCH); + status = count; } - iowrite32(data, fpga_dev.data_base_addr+FPGA_SCRATCH); - return count; + return status; } + /** - * [set_fpga_reg_value description] - * @param dev [description] - * @param devattr [description] - * @param buf [description] - * @return [description] + * Store a value in a specific register address + * @param buf the value and address in format '0xhhhh 0xhhhhhhhh' + * @return number of bytes sent by user space, or an error code */ -static ssize_t set_fpga_reg_value(struct device *dev, struct device_attribute *devattr, - const char *buf, size_t count) +static ssize_t set_fpga_reg_value(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { //register is 4 bytes uint32_t addr; @@ -457,46 +454,46 @@ static ssize_t set_fpga_reg_value(struct device *dev, struct device_attribute *d char *tok; char clone[count]; char *pclone = clone; - char *last; + ssize_t status; strcpy(clone, buf); mutex_lock(&fpga_data->fpga_lock); tok = strsep((char**)&pclone, " "); - if(tok == NULL){ + if (tok == NULL) { mutex_unlock(&fpga_data->fpga_lock); return -EINVAL; } - addr = (uint32_t)strtoul(tok,&last,16); - if(addr == 0 && tok == last){ + status = kstrtou32(tok, 0, &addr); + if (status != 0) { mutex_unlock(&fpga_data->fpga_lock); return -EINVAL; } tok = strsep((char**)&pclone, " "); - if(tok == NULL){ + if (tok == NULL) { mutex_unlock(&fpga_data->fpga_lock); return -EINVAL; } - value = (uint32_t)strtoul(tok,&last,16); - if(value == 0 && tok == last){ + status = kstrtou32(tok, 0, &value); + if (status != 0) { mutex_unlock(&fpga_data->fpga_lock); return -EINVAL; } tok = strsep((char**)&pclone, " "); - if(tok == NULL){ + if (tok == NULL) { mode = 32; - }else{ - mode = (uint32_t)strtoul(tok,&last,10); - if(mode == 0 && tok == last){ + } else { + status = kstrtou32(tok, 0, &mode); + if (status != 0) { mutex_unlock(&fpga_data->fpga_lock); return -EINVAL; } } - if(mode == 32){ - iowrite32(value, fpga_dev.data_base_addr+addr); - }else if(mode == 8){ - iowrite8(value, fpga_dev.data_base_addr+addr); - }else{ + if (mode == 32) { + iowrite32(value, fpga_dev.data_base_addr + addr); + } else if (mode == 8) { + iowrite8(value, fpga_dev.data_base_addr + addr); + } else { mutex_unlock(&fpga_data->fpga_lock); return -EINVAL; } @@ -513,7 +510,7 @@ static ssize_t ready_show(struct device *dev, struct device_attribute *attr, cha unsigned int REGISTER = FPGA_PORT_XCVR_READY; mutex_lock(&fpga_data->fpga_lock); - data = ioread32(fpga_dev.data_base_addr+REGISTER); + data = ioread32(fpga_dev.data_base_addr + REGISTER); mutex_unlock(&fpga_data->fpga_lock); return sprintf(buf, "%d\n", (data >> 0) & 1U); } @@ -525,409 +522,673 @@ static DEVICE_ATTR( setreg, 0200, NULL , set_fpga_reg_value); static DEVICE_ATTR_RO(ready); static struct attribute *fpga_attrs[] = { - &dev_attr_getreg.attr, - &dev_attr_scratch.attr, - &dev_attr_setreg.attr, - &dev_attr_ready.attr, - NULL, + &dev_attr_getreg.attr, + &dev_attr_scratch.attr, + &dev_attr_setreg.attr, + &dev_attr_ready.attr, + NULL, }; static struct attribute_group fpga_attr_grp = { - .attrs = fpga_attrs, + .attrs = fpga_attrs, }; /* SW CPLDs attributes */ -static ssize_t cpld1_getreg_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t cpld1_getreg_show(struct device *dev, + struct device_attribute *attr, char *buf) { // CPLD register is one byte uint8_t data; - fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00,I2C_SMBUS_READ,fpga_data->cpld1_read_addr,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&data); - return sprintf(buf,"0x%2.2x\n",data); + int err; + + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD1_SLAVE_ADDR, 0x00, + I2C_SMBUS_READ, fpga_data->cpld1_read_addr, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + + if (err < 0) + return err; + + return sprintf(buf, "0x%2.2x\n", data); } -static ssize_t cpld1_getreg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) + +static ssize_t cpld1_getreg_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { + ssize_t status; uint8_t addr; - char *last; - addr = (uint8_t)strtoul(buf,&last,16); - if(addr == 0 && buf == last){ - return -EINVAL; + + status = kstrtou8(buf, 0, &addr); + if (status == 0) { + fpga_data->cpld1_read_addr = addr; + status = count; } - fpga_data->cpld1_read_addr = addr; - return size; + return status; } -struct device_attribute dev_attr_cpld1_getreg = __ATTR(getreg,0600,cpld1_getreg_show,cpld1_getreg_store); -static ssize_t cpld1_scratch_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t cpld1_scratch_show(struct device *dev, + struct device_attribute *attr, char *buf) { // CPLD register is one byte - __u8 data; + uint8_t data; int err; - err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00,I2C_SMBUS_READ,0x01,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&data); - if(err < 0) + + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x01, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + if (err < 0) return err; - return sprintf(buf, "0x%2.2x\n",data); + + return sprintf(buf, "0x%2.2x\n", data); } -static ssize_t cpld1_scratch_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) + +static ssize_t cpld1_scratch_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { // CPLD register is one byte - __u8 data; - char *last; + uint8_t data; + ssize_t status; int err; - data = (uint8_t)strtoul(buf,&last,16); - if(data == 0 && buf == last){ - return -EINVAL; + + status = kstrtou8(buf, 0, &data); + if (status != 0) { + return status; } - err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00,I2C_SMBUS_WRITE,0x01,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&data); - if(err < 0) + + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_WRITE, 0x01, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + if (err < 0) return err; - return size; + + return count; } -struct device_attribute dev_attr_cpld1_scratch = __ATTR(scratch,0600,cpld1_scratch_show,cpld1_scratch_store); -static ssize_t cpld1_setreg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +static ssize_t cpld1_setreg_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { - uint8_t addr,value; + uint8_t addr, value; char *tok; - char clone[size]; + char clone[count]; char *pclone = clone; + ssize_t status; int err; - char *last; strcpy(clone, buf); tok = strsep((char**)&pclone, " "); - if(tok == NULL){ + if (tok == NULL) { return -EINVAL; } - addr = (uint8_t)strtoul(tok,&last,16); - if(addr == 0 && tok == last){ + status = kstrtou8(tok, 0, &addr); + if (status != 0) { return -EINVAL; } tok = strsep((char**)&pclone, " "); - if(tok == NULL){ + if (tok == NULL) { return -EINVAL; } - value = (uint8_t)strtoul(tok,&last,16); - if(value == 0 && tok == last){ + status = kstrtou8(tok, 0, &value); + if (status != 0) { return -EINVAL; } - err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00,I2C_SMBUS_WRITE,addr,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&value); - if(err < 0) + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_WRITE, addr, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&value); + if (err < 0) return err; - return size; + return count; } -struct device_attribute dev_attr_cpld1_setreg = __ATTR(setreg,0200,NULL,cpld1_setreg_store); + +struct device_attribute dev_attr_cpld1_getreg = __ATTR(getreg, 0600, cpld1_getreg_show, cpld1_getreg_store); +struct device_attribute dev_attr_cpld1_scratch = __ATTR(scratch, 0600, cpld1_scratch_show, cpld1_scratch_store); +struct device_attribute dev_attr_cpld1_setreg = __ATTR(setreg, 0200, NULL, cpld1_setreg_store); static struct attribute *cpld1_attrs[] = { - &dev_attr_cpld1_getreg.attr, - &dev_attr_cpld1_scratch.attr, - &dev_attr_cpld1_setreg.attr, - NULL, + &dev_attr_cpld1_getreg.attr, + &dev_attr_cpld1_scratch.attr, + &dev_attr_cpld1_setreg.attr, + NULL, }; static struct attribute_group cpld1_attr_grp = { - .attrs = cpld1_attrs, + .attrs = cpld1_attrs, }; -static ssize_t cpld2_getreg_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t cpld2_getreg_show(struct device *dev, + struct device_attribute *attr, char *buf) { // CPLD register is one byte uint8_t data; - fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00,I2C_SMBUS_READ,fpga_data->cpld2_read_addr,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&data); - return sprintf(buf,"0x%2.2x\n",data); + int err; + + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, fpga_data->cpld2_read_addr, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + if (err < 0) + return err; + + return sprintf(buf, "0x%2.2x\n", data); } -static ssize_t cpld2_getreg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) + +static ssize_t cpld2_getreg_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { // CPLD register is one byte - uint32_t addr; - char *last; - addr = (uint8_t)strtoul(buf,&last,16); - if(addr == 0 && buf == last){ - return -EINVAL; + uint8_t addr; + ssize_t status; + + status = kstrtou8(buf, 0, &addr); + if (status == 0) { + fpga_data->cpld2_read_addr = addr; + status = count; } - fpga_data->cpld2_read_addr = addr; - return size; + return status; } -struct device_attribute dev_attr_cpld2_getreg = __ATTR(getreg,0600,cpld2_getreg_show,cpld2_getreg_store); -static ssize_t cpld2_scratch_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t cpld2_scratch_show(struct device *dev, + struct device_attribute *attr, char *buf) { // CPLD register is one byte - __u8 data; + uint8_t data; int err; - err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00,I2C_SMBUS_READ,0x01,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&data); - if(err < 0) + + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x01, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + if (err < 0) return err; - return sprintf(buf, "0x%2.2x\n",data); + + return sprintf(buf, "0x%2.2x\n", data); } -static ssize_t cpld2_scratch_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) + +static ssize_t cpld2_scratch_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { // CPLD register is one byte - __u8 data; - char *last; + uint8_t data; int err; + ssize_t status; - data = (uint8_t)strtoul(buf,&last,16); - if(data == 0 && buf == last){ + status = kstrtou8(buf, 0, &data); + if (status != 0) { return -EINVAL; } - err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00,I2C_SMBUS_WRITE,0x01,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&data); - if(err < 0) + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_WRITE, 0x01, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + if (err < 0) return err; - return size; + + return count; } -struct device_attribute dev_attr_cpld2_scratch = __ATTR(scratch,0600,cpld2_scratch_show,cpld2_scratch_store); -static ssize_t cpld2_setreg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +static ssize_t cpld2_setreg_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { - uint8_t addr,value; + uint8_t addr, value; char *tok; - char clone[size]; + char clone[count]; char *pclone = clone; + ssize_t status; int err; - char *last; strcpy(clone, buf); tok = strsep((char**)&pclone, " "); - if(tok == NULL){ + if (tok == NULL) { return -EINVAL; } - addr = (uint8_t)strtoul(tok,&last,16); - if(addr == 0 && tok == last){ + status = kstrtou8(tok, 0, &addr); + if (status != 0) { return -EINVAL; } tok = strsep((char**)&pclone, " "); - if(tok == NULL){ + if (tok == NULL) { return -EINVAL; } - value = (uint8_t)strtoul(tok,&last,16); - if(value == 0 && tok == last){ + status = kstrtou8(tok, 0, &value); + if (status != 0) { return -EINVAL; } - err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00,I2C_SMBUS_WRITE,addr,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&value); - if(err < 0) + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_WRITE, addr, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&value); + if (err < 0) return err; - return size; + return count; } -struct device_attribute dev_attr_cpld2_setreg = __ATTR(setreg,0200,NULL,cpld2_setreg_store); + +struct device_attribute dev_attr_cpld2_getreg = __ATTR(getreg, 0600, cpld2_getreg_show, cpld2_getreg_store); +struct device_attribute dev_attr_cpld2_scratch = __ATTR(scratch, 0600, cpld2_scratch_show, cpld2_scratch_store); +struct device_attribute dev_attr_cpld2_setreg = __ATTR(setreg, 0200, NULL, cpld2_setreg_store); static struct attribute *cpld2_attrs[] = { - &dev_attr_cpld2_getreg.attr, - &dev_attr_cpld2_scratch.attr, - &dev_attr_cpld2_setreg.attr, - NULL, + &dev_attr_cpld2_getreg.attr, + &dev_attr_cpld2_scratch.attr, + &dev_attr_cpld2_setreg.attr, + NULL, }; static struct attribute_group cpld2_attr_grp = { - .attrs = cpld2_attrs, + .attrs = cpld2_attrs, }; /* QSFP/SFP+ attributes */ -static ssize_t qsfp_modirq_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t qsfp_modirq_show(struct device *dev, + struct device_attribute *attr, char *buf) { u32 data; struct sff_device_data *dev_data = dev_get_drvdata(dev); unsigned int portid = dev_data->portid; - unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid-1)*0x10; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid - 1) * 0x10; mutex_lock(&fpga_data->fpga_lock); - data = ioread32(fpga_dev.data_base_addr+REGISTER); + data = ioread32(fpga_dev.data_base_addr + REGISTER); mutex_unlock(&fpga_data->fpga_lock); return sprintf(buf, "%d\n", (data >> STAT_IRQ) & 1U); } DEVICE_ATTR_RO(qsfp_modirq); -static ssize_t qsfp_modprs_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t qsfp_modprs_show(struct device *dev, + struct device_attribute *attr, char *buf) { u32 data; struct sff_device_data *dev_data = dev_get_drvdata(dev); unsigned int portid = dev_data->portid; - unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid-1)*0x10; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid - 1) * 0x10; mutex_lock(&fpga_data->fpga_lock); - data = ioread32(fpga_dev.data_base_addr+REGISTER); + data = ioread32(fpga_dev.data_base_addr + REGISTER); mutex_unlock(&fpga_data->fpga_lock); return sprintf(buf, "%d\n", (data >> STAT_PRESENT) & 1U); } DEVICE_ATTR_RO(qsfp_modprs); -static ssize_t sfp_txfault_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t sfp_txfault_show(struct device *dev, + struct device_attribute *attr, char *buf) { u32 data; struct sff_device_data *dev_data = dev_get_drvdata(dev); unsigned int portid = dev_data->portid; - unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid-1)*0x10; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid - 1) * 0x10; mutex_lock(&fpga_data->fpga_lock); - data = ioread32(fpga_dev.data_base_addr+REGISTER); + data = ioread32(fpga_dev.data_base_addr + REGISTER); mutex_unlock(&fpga_data->fpga_lock); return sprintf(buf, "%d\n", (data >> STAT_TXFAULT) & 1U); } DEVICE_ATTR_RO(sfp_txfault); -static ssize_t sfp_rxlos_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t sfp_rxlos_show(struct device *dev, + struct device_attribute *attr, char *buf) { u32 data; struct sff_device_data *dev_data = dev_get_drvdata(dev); unsigned int portid = dev_data->portid; - unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid-1)*0x10; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid - 1) * 0x10; mutex_lock(&fpga_data->fpga_lock); - data = ioread32(fpga_dev.data_base_addr+REGISTER); + data = ioread32(fpga_dev.data_base_addr + REGISTER); mutex_unlock(&fpga_data->fpga_lock); return sprintf(buf, "%d\n", (data >> STAT_RXLOS) & 1U); } DEVICE_ATTR_RO(sfp_rxlos); -static ssize_t sfp_modabs_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t sfp_modabs_show(struct device *dev, + struct device_attribute *attr, char *buf) { u32 data; struct sff_device_data *dev_data = dev_get_drvdata(dev); unsigned int portid = dev_data->portid; - unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid-1)*0x10; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid - 1) * 0x10; mutex_lock(&fpga_data->fpga_lock); - data = ioread32(fpga_dev.data_base_addr+REGISTER); + data = ioread32(fpga_dev.data_base_addr + REGISTER); mutex_unlock(&fpga_data->fpga_lock); return sprintf(buf, "%d\n", (data >> STAT_MODABS) & 1U); } DEVICE_ATTR_RO(sfp_modabs); -static ssize_t qsfp_lpmode_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t qsfp_lpmode_show(struct device *dev, + struct device_attribute *attr, char *buf) { u32 data; struct sff_device_data *dev_data = dev_get_drvdata(dev); unsigned int portid = dev_data->portid; - unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid-1)*0x10; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; mutex_lock(&fpga_data->fpga_lock); - data = ioread32(fpga_dev.data_base_addr+REGISTER); + data = ioread32(fpga_dev.data_base_addr + REGISTER); mutex_unlock(&fpga_data->fpga_lock); return sprintf(buf, "%d\n", (data >> CTRL_LPMOD) & 1U); } -static ssize_t qsfp_lpmode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +static ssize_t qsfp_lpmode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { ssize_t status; - long value; + uint32_t value; u32 data; struct sff_device_data *dev_data = dev_get_drvdata(dev); unsigned int portid = dev_data->portid; - unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid-1)*0x10; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; mutex_lock(&fpga_data->fpga_lock); - status = kstrtol(buf, 0, &value); + status = kstrtou32(buf, 0, &value); if (status == 0) { // check if value is 0 clear - data = ioread32(fpga_dev.data_base_addr+REGISTER); - if(!value) + data = ioread32(fpga_dev.data_base_addr + REGISTER); + if (!value) data = data & ~( (u32)0x1 << CTRL_LPMOD); else data = data | ((u32)0x1 << CTRL_LPMOD); - iowrite32(data,fpga_dev.data_base_addr+REGISTER); - status = size; + iowrite32(data, fpga_dev.data_base_addr + REGISTER); + status = count; } mutex_unlock(&fpga_data->fpga_lock); return status; } DEVICE_ATTR_RW(qsfp_lpmode); -static ssize_t qsfp_reset_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t qsfp_reset_show(struct device *dev, + struct device_attribute *attr, char *buf) { u32 data; struct sff_device_data *dev_data = dev_get_drvdata(dev); unsigned int portid = dev_data->portid; - unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid-1)*0x10; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; mutex_lock(&fpga_data->fpga_lock); - data = ioread32(fpga_dev.data_base_addr+REGISTER); + data = ioread32(fpga_dev.data_base_addr + REGISTER); mutex_unlock(&fpga_data->fpga_lock); return sprintf(buf, "%d\n", (data >> CTRL_RST) & 1U); } -static ssize_t qsfp_reset_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +static ssize_t qsfp_reset_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { ssize_t status; - long value; + uint32_t value; u32 data; struct sff_device_data *dev_data = dev_get_drvdata(dev); unsigned int portid = dev_data->portid; - unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid-1)*0x10; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; mutex_lock(&fpga_data->fpga_lock); - status = kstrtol(buf, 0, &value); + status = kstrtou32(buf, 0, &value); if (status == 0) { // check if value is 0 clear - data = ioread32(fpga_dev.data_base_addr+REGISTER); - if(!value) + data = ioread32(fpga_dev.data_base_addr + REGISTER); + if (!value) data = data & ~( (u32)0x1 << CTRL_RST); else data = data | ((u32)0x1 << CTRL_RST); - iowrite32(data,fpga_dev.data_base_addr+REGISTER); - status = size; + iowrite32(data, fpga_dev.data_base_addr + REGISTER); + status = count; } mutex_unlock(&fpga_data->fpga_lock); return status; } DEVICE_ATTR_RW(qsfp_reset); -static ssize_t sfp_txdisable_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t qsfp_isr_flags_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 data; + u8 valid_bits; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_INT_STATUS_BASE + (portid - 1) * 0x10; + valid_bits = BIT(INTR_INT_N) | BIT(INTR_PRESENT); + + mutex_lock(&fpga_data->fpga_lock); + data = (u8) ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + + /* + * Unify the return pattern to 2-bit + * [1] : module interrupt + * [0] : presence + */ + data = data & valid_bits; + data = data >> 4; + + return sprintf(buf, "0x%2.2x\n", data); +} + +static ssize_t qsfp_isr_flags_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + ssize_t status; + u32 value; + u8 valid_bits; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_INT_STATUS_BASE + (portid - 1) * 0x10; + valid_bits = BIT(INTR_INT_N) | BIT(INTR_PRESENT); + + mutex_lock(&fpga_data->fpga_lock); + status = kstrtou32(buf, 0, &value); + if (status == 0) { + value = value << 4; + value = value & valid_bits; + iowrite32(value, fpga_dev.data_base_addr + REGISTER); + status = count; + } + mutex_unlock(&fpga_data->fpga_lock); + return status; +} +DEVICE_ATTR_RW(qsfp_isr_flags); + +static ssize_t qsfp_isr_mask_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u32 data; + u8 valid_bits; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_INT_MASK_BASE + (portid - 1) * 0x10; + valid_bits = BIT(INTR_INT_N) | BIT(INTR_PRESENT); + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + + /* + * Unify the return pattern to 2-bit + * [1] : module interrupt + * [0] : presence + */ + data = data & valid_bits; + data = data >> 4; + + return sprintf(buf, "0x%2.2x\n", data); +} + +static ssize_t qsfp_isr_mask_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + ssize_t status; + u32 value; + u8 valid_bits; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_INT_MASK_BASE + (portid - 1) * 0x10; + valid_bits = BIT(INTR_INT_N) | BIT(INTR_PRESENT); + + mutex_lock(&fpga_data->fpga_lock); + status = kstrtou32(buf, 0, &value); + if (status == 0) { + value = value << 4; + value = value & valid_bits; + iowrite32(value, fpga_dev.data_base_addr + REGISTER); + status = count; + } + mutex_unlock(&fpga_data->fpga_lock); + return status; +} +DEVICE_ATTR_RW(qsfp_isr_mask); + +static ssize_t sfp_txdisable_show(struct device *dev, + struct device_attribute *attr, char *buf) { u32 data; struct sff_device_data *dev_data = dev_get_drvdata(dev); unsigned int portid = dev_data->portid; - unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid-1)*0x10; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; mutex_lock(&fpga_data->fpga_lock); - data = ioread32(fpga_dev.data_base_addr+REGISTER); + data = ioread32(fpga_dev.data_base_addr + REGISTER); mutex_unlock(&fpga_data->fpga_lock); return sprintf(buf, "%d\n", (data >> CTRL_TXDIS) & 1U); } -static ssize_t sfp_txdisable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +static ssize_t sfp_txdisable_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { ssize_t status; long value; u32 data; struct sff_device_data *dev_data = dev_get_drvdata(dev); unsigned int portid = dev_data->portid; - unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid-1)*0x10; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; mutex_lock(&fpga_data->fpga_lock); status = kstrtol(buf, 0, &value); if (status == 0) { // check if value is 0 clear - data = ioread32(fpga_dev.data_base_addr+REGISTER); - if(!value) + data = ioread32(fpga_dev.data_base_addr + REGISTER); + if (!value) data = data & ~( (u32)0x1 << CTRL_TXDIS); else data = data | ((u32)0x1 << CTRL_TXDIS); - iowrite32(data,fpga_dev.data_base_addr+REGISTER); - status = size; + iowrite32(data, fpga_dev.data_base_addr + REGISTER); + status = count; } mutex_unlock(&fpga_data->fpga_lock); return status; } DEVICE_ATTR_RW(sfp_txdisable); +static ssize_t sfp_isr_flags_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 data; + u8 valid_bits; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_INT_STATUS_BASE + (portid - 1) * 0x10; + valid_bits = BIT(INTR_RXLOS) | BIT(INTR_MODABS); + + mutex_lock(&fpga_data->fpga_lock); + data = (u8) ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + + data = data & valid_bits; + + return sprintf(buf, "0x%2.2x\n", data); +} + +static ssize_t sfp_isr_flags_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + ssize_t status; + u32 value; + u8 valid_bits; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_INT_STATUS_BASE + (portid - 1) * 0x10; + valid_bits = BIT(INTR_INT_N) | BIT(INTR_PRESENT); + + mutex_lock(&fpga_data->fpga_lock); + status = kstrtou32(buf, 0, &value); + if (status == 0) { + value = value & valid_bits; + iowrite32(value, fpga_dev.data_base_addr + REGISTER); + status = count; + } + mutex_unlock(&fpga_data->fpga_lock); + return status; +} +DEVICE_ATTR_RW(sfp_isr_flags); + +static ssize_t sfp_isr_mask_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u32 data; + u8 valid_bits; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_INT_MASK_BASE + (portid - 1) * 0x10; + valid_bits = BIT(INTR_RXLOS) | BIT(INTR_MODABS); + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + + data = data & valid_bits; + + return sprintf(buf, "0x%2.2x\n", data); +} + +static ssize_t sfp_isr_mask_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + ssize_t status; + u32 value; + u8 valid_bits; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_INT_MASK_BASE + (portid - 1) * 0x10; + valid_bits = BIT(INTR_RXLOS) | BIT(INTR_MODABS); + + mutex_lock(&fpga_data->fpga_lock); + status = kstrtou32(buf, 0, &value); + if (status == 0) { + value = value & valid_bits; + iowrite32(value, fpga_dev.data_base_addr + REGISTER); + status = count; + } + mutex_unlock(&fpga_data->fpga_lock); + return status; +} +DEVICE_ATTR_RW(sfp_isr_mask); + static struct attribute *sff_attrs[] = { &dev_attr_qsfp_modirq.attr, &dev_attr_qsfp_modprs.attr, &dev_attr_qsfp_lpmode.attr, &dev_attr_qsfp_reset.attr, + &dev_attr_qsfp_isr_flags.attr, + &dev_attr_qsfp_isr_mask.attr, &dev_attr_sfp_txfault.attr, &dev_attr_sfp_rxlos.attr, &dev_attr_sfp_modabs.attr, &dev_attr_sfp_txdisable.attr, + &dev_attr_sfp_isr_flags.attr, + &dev_attr_sfp_isr_mask.attr, NULL, }; static struct attribute_group sff_attr_grp = { - .attrs = sff_attrs, + .attrs = sff_attrs, }; static const struct attribute_group *sff_attr_grps[] = { @@ -936,78 +1197,99 @@ static const struct attribute_group *sff_attr_grps[] = { }; -static ssize_t port_led_mode_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t port_led_mode_show(struct device *dev, + struct device_attribute *attr, char *buf) { // value can be "nomal", "test" - __u8 led_mode_1,led_mode_2; + __u8 led_mode_1, led_mode_2; int err; - err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00,I2C_SMBUS_READ,0x09,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&led_mode_1); - if(err < 0) + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x09, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_mode_1); + if (err < 0) return err; - err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00,I2C_SMBUS_READ,0x09,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&led_mode_2); - if(err < 0) + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x09, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_mode_2); + if (err < 0) return err; + return sprintf(buf, "%s %s\n", - led_mode_1 ? "test" : "normal", - led_mode_2 ? "test" : "normal"); + led_mode_1 ? "test" : "normal", + led_mode_2 ? "test" : "normal"); } -static ssize_t port_led_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +static ssize_t port_led_mode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { int status; __u8 led_mode_1; - if(sysfs_streq(buf, "test")){ + if (sysfs_streq(buf, "test")) { led_mode_1 = 0x01; - }else if(sysfs_streq(buf, "normal")){ + } else if (sysfs_streq(buf, "normal")) { led_mode_1 = 0x00; - }else{ + } else { return -EINVAL; } - status = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00, - I2C_SMBUS_WRITE,0x09,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&led_mode_1); - status = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00, - I2C_SMBUS_WRITE,0x09,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&led_mode_1); - return size; + status = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_WRITE, 0x09, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_mode_1); + status = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_WRITE, 0x09, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_mode_1); + return count; } DEVICE_ATTR_RW(port_led_mode); // Only work when port_led_mode set to 1 -static ssize_t port_led_color_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t port_led_color_show(struct device *dev, + struct device_attribute *attr, char *buf) { // value can be "off", "green", "amber", "both" - __u8 led_color1,led_color2; + __u8 led_color1, led_color2; int err; - err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00,I2C_SMBUS_READ,0x09,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&led_color1); - if(err < 0) + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x0A, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_color1); + if (err < 0) return err; - err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00,I2C_SMBUS_READ,0x09,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&led_color2); - if(err < 0) + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x0A, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_color2); + if (err < 0) return err; return sprintf(buf, "%s %s\n", - led_color1 == 0x03 ? "off" : led_color1 == 0x02 ? "green" : led_color1 ==0x01 ? "amber": "both", - led_color2 == 0x03 ? "off" : led_color2 == 0x02 ? "green" : led_color2 ==0x01 ? "amber": "both"); + led_color1 == 0x03 ? "off" : led_color1 == 0x02 ? "green" : led_color1 == 0x01 ? "amber" : "both", + led_color2 == 0x03 ? "off" : led_color2 == 0x02 ? "green" : led_color2 == 0x01 ? "amber" : "both"); } -static ssize_t port_led_color_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +static ssize_t port_led_color_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { int status; __u8 led_color; - if(sysfs_streq(buf, "off")){ + if (sysfs_streq(buf, "off")) { led_color = 0x03; - }else if(sysfs_streq(buf, "green")){ + } else if (sysfs_streq(buf, "green")) { led_color = 0x02; - }else if(sysfs_streq(buf, "amber")){ + } else if (sysfs_streq(buf, "amber")) { led_color = 0x01; - }else if(sysfs_streq(buf, "both")){ + } else if (sysfs_streq(buf, "both")) { led_color = 0x00; - }else{ + } else { status = -EINVAL; return status; } - status = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00, - I2C_SMBUS_WRITE,0x0A,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&led_color); - status = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00, - I2C_SMBUS_WRITE,0x0A,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&led_color); - return size; + status = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD1_SLAVE_ADDR, 0x00, + I2C_SMBUS_WRITE, 0x0A, I2C_SMBUS_BYTE_DATA, + (union i2c_smbus_data*)&led_color); + status = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD2_SLAVE_ADDR, 0x00, + I2C_SMBUS_WRITE, 0x0A, I2C_SMBUS_BYTE_DATA, + (union i2c_smbus_data*)&led_color); + return count; } DEVICE_ATTR_RW(port_led_color); @@ -1018,10 +1300,10 @@ static struct attribute *sff_led_test[] = { }; static struct attribute_group sff_led_test_grp = { - .attrs = sff_led_test, + .attrs = sff_led_test, }; -static struct device * seastone2_sff_init(int portid){ +static struct device * seastone2_sff_init(int portid) { struct sff_device_data *new_data; struct device *new_device; @@ -1031,9 +1313,11 @@ static struct device * seastone2_sff_init(int portid){ return NULL; } /* The QSFP port ID start from 1 */ - new_data->portid = portid+1; + new_data->portid = portid + 1; new_data->port_type = fpga_i2c_bus_dev[portid].port_type; - new_device = device_create_with_groups(fpgafwclass, sff_dev, MKDEV(0,0), new_data, sff_attr_grps, "%s",fpga_i2c_bus_dev[portid].calling_name); + new_device = device_create_with_groups(fpgafwclass, sff_dev, + MKDEV(0, 0), new_data, sff_attr_grps, "%s", + fpga_i2c_bus_dev[portid].calling_name); if (IS_ERR(new_device)) { printk(KERN_ALERT "Cannot create sff device @port%d", portid); kfree(new_data); @@ -1042,7 +1326,7 @@ static struct device * seastone2_sff_init(int portid){ return new_device; } -static int i2c_wait_ack(struct i2c_adapter *a,unsigned long timeout,int writing){ +static int i2c_wait_ack(struct i2c_adapter *a, unsigned long timeout, int writing) { int error = 0; int Status; @@ -1057,65 +1341,65 @@ static int i2c_wait_ack(struct i2c_adapter *a,unsigned long timeout,int writing) unsigned int master_bus = new_data->pca9548.master_bus; - if(master_bus < I2C_MASTER_CH_1 || master_bus > I2C_MASTER_CH_TOTAL){ + if (master_bus < I2C_MASTER_CH_1 || master_bus > I2C_MASTER_CH_TOTAL) { error = -EINVAL; return error; } - REG_FDR0 = I2C_MASTER_FREQ_1 + (master_bus-1)*0x0100; - REG_CR0 = I2C_MASTER_CTRL_1 + (master_bus-1)*0x0100; - REG_SR0 = I2C_MASTER_STATUS_1 + (master_bus-1)*0x0100; - REG_DR0 = I2C_MASTER_DATA_1 + (master_bus-1)*0x0100; - REG_ID0 = I2C_MASTER_PORT_ID_1 + (master_bus-1)*0x0100; + REG_FDR0 = I2C_MASTER_FREQ_1 + (master_bus - 1) * 0x0100; + REG_CR0 = I2C_MASTER_CTRL_1 + (master_bus - 1) * 0x0100; + REG_SR0 = I2C_MASTER_STATUS_1 + (master_bus - 1) * 0x0100; + REG_DR0 = I2C_MASTER_DATA_1 + (master_bus - 1) * 0x0100; + REG_ID0 = I2C_MASTER_PORT_ID_1 + (master_bus - 1) * 0x0100; - check(pci_bar+REG_SR0); - check(pci_bar+REG_CR0); + check(pci_bar + REG_SR0); + check(pci_bar + REG_CR0); timeout = jiffies + msecs_to_jiffies(timeout); - while(1){ - Status = ioread8(pci_bar+REG_SR0); - if(jiffies > timeout){ - info("Status %2.2X",Status); + while (1) { + Status = ioread8(pci_bar + REG_SR0); + if (jiffies > timeout) { + info("Status %2.2X", Status); info("Error Timeout"); error = -ETIMEDOUT; break; } - if(Status & (1 << I2C_SR_BIT_MIF)){ + if (Status & (1 << I2C_SR_BIT_MIF)) { break; } - if(writing == 0 && (Status & (1<portid; - pci_bar = fpga_dev.data_base_addr; + int error = 0; + int cnt = 0; + int bid = 0; + struct i2c_dev_data *dev_data; + void __iomem *pci_bar; + unsigned int portid, master_bus; + + unsigned int REG_FDR0; + unsigned int REG_CR0; + unsigned int REG_SR0; + unsigned int REG_DR0; + unsigned int REG_ID0; + + REG_FDR0 = 0; + REG_CR0 = 0; + REG_SR0 = 0; + REG_DR0 = 0; + REG_ID0 = 0; + + /* Write the command register */ + dev_data = i2c_get_adapdata(adapter); + portid = dev_data->portid; + pci_bar = fpga_dev.data_base_addr; #ifdef DEBUG_KERN - printk(KERN_INFO "portid %2d|@ 0x%2.2X|f 0x%4.4X|(%d)%-5s| (%d)%-15s|CMD %2.2X " - ,portid,addr,flags,rw,rw == 1 ? "READ ":"WRITE" - ,size, size == 0 ? "QUICK" : - size == 1 ? "BYTE" : - size == 2 ? "BYTE_DATA" : - size == 3 ? "WORD_DATA" : - size == 4 ? "PROC_CALL" : - size == 5 ? "BLOCK_DATA" : - size == 8 ? "I2C_BLOCK_DATA" : "ERROR" - ,cmd); + printk(KERN_INFO "portid %2d|@ 0x%2.2X|f 0x%4.4X|(%d)%-5s| (%d)%-15s|CMD %2.2X " + , portid, addr, flags, rw, rw == 1 ? "READ " : "WRITE" + , size, size == 0 ? "QUICK" : + size == 1 ? "BYTE" : + size == 2 ? "BYTE_DATA" : + size == 3 ? "WORD_DATA" : + size == 4 ? "PROC_CALL" : + size == 5 ? "BLOCK_DATA" : + size == 8 ? "I2C_BLOCK_DATA" : "ERROR" + , cmd); #endif - /* Map the size to what the chip understands */ - switch (size) { - case I2C_SMBUS_QUICK: - case I2C_SMBUS_BYTE: - case I2C_SMBUS_BYTE_DATA: - case I2C_SMBUS_WORD_DATA: - case I2C_SMBUS_BLOCK_DATA: - case I2C_SMBUS_I2C_BLOCK_DATA: - break; - default: - printk(KERN_INFO "Unsupported transaction %d\n", size); - error = -EOPNOTSUPP; - goto Done; - } + /* Map the size to what the chip understands */ + switch (size) { + case I2C_SMBUS_QUICK: + case I2C_SMBUS_BYTE: + case I2C_SMBUS_BYTE_DATA: + case I2C_SMBUS_WORD_DATA: + case I2C_SMBUS_BLOCK_DATA: + case I2C_SMBUS_I2C_BLOCK_DATA: + break; + default: + printk(KERN_INFO "Unsupported transaction %d\n", size); + error = -EOPNOTSUPP; + goto Done; + } - master_bus = dev_data->pca9548.master_bus; + master_bus = dev_data->pca9548.master_bus; - if(master_bus < I2C_MASTER_CH_1 || master_bus > I2C_MASTER_CH_TOTAL){ - error = -ENXIO; - goto Done; - } + if (master_bus < I2C_MASTER_CH_1 || master_bus > I2C_MASTER_CH_TOTAL) { + error = -ENXIO; + goto Done; + } - REG_FDR0 = I2C_MASTER_FREQ_1 + (master_bus-1)*0x0100; - REG_CR0 = I2C_MASTER_CTRL_1 + (master_bus-1)*0x0100; - REG_SR0 = I2C_MASTER_STATUS_1 + (master_bus-1)*0x0100; - REG_DR0 = I2C_MASTER_DATA_1 + (master_bus-1)*0x0100; - REG_ID0 = I2C_MASTER_PORT_ID_1 + (master_bus-1)*0x0100; - - iowrite8(portid,pci_bar+REG_ID0); - - ////[S][ADDR/R] - // Clear status register - iowrite8(0,pci_bar+REG_SR0); - iowrite8(1 << I2C_CR_BIT_MIEN | 1 << I2C_CR_BIT_MTX | 1 << I2C_CR_BIT_MSTA ,pci_bar+REG_CR0); - SET_REG_BIT_H(pci_bar+REG_CR0,I2C_CR_BIT_MEN); - - if(rw == I2C_SMBUS_READ && - (size == I2C_SMBUS_QUICK || size == I2C_SMBUS_BYTE)){ - // sent device address with Read mode - iowrite8(addr << 1 | 0x01,pci_bar+REG_DR0); - }else{ - // sent device address with Write mode - iowrite8(addr << 1 | 0x00,pci_bar+REG_DR0); - } + REG_FDR0 = I2C_MASTER_FREQ_1 + (master_bus - 1) * 0x0100; + REG_CR0 = I2C_MASTER_CTRL_1 + (master_bus - 1) * 0x0100; + REG_SR0 = I2C_MASTER_STATUS_1 + (master_bus - 1) * 0x0100; + REG_DR0 = I2C_MASTER_DATA_1 + (master_bus - 1) * 0x0100; + REG_ID0 = I2C_MASTER_PORT_ID_1 + (master_bus - 1) * 0x0100; + + iowrite8(portid, pci_bar + REG_ID0); + + ////[S][ADDR/R] + // Clear status register + iowrite8(0, pci_bar + REG_SR0); + iowrite8(1 << I2C_CR_BIT_MIEN | + 1 << I2C_CR_BIT_MTX | + 1 << I2C_CR_BIT_MSTA , pci_bar + REG_CR0); + SET_REG_BIT_H(pci_bar + REG_CR0, I2C_CR_BIT_MEN); + + if (rw == I2C_SMBUS_READ && + (size == I2C_SMBUS_QUICK || size == I2C_SMBUS_BYTE)) { + // sent device address with Read mode + iowrite8(addr << 1 | 0x01, pci_bar + REG_DR0); + } else { + // sent device address with Write mode + iowrite8(addr << 1 | 0x00, pci_bar + REG_DR0); + } - info( "MS Start"); + info( "MS Start"); - //// Wait {A} - error = i2c_wait_ack(adapter,12,1); - if(error<0){ - info( "get error %d",error); - goto Done; - } + //// Wait {A} + error = i2c_wait_ack(adapter, 12, 1); + if (error < 0) { + info( "get error %d", error); + goto Done; + } - //// [CMD]{A} - if(size == I2C_SMBUS_BYTE_DATA || + //// [CMD]{A} + if (size == I2C_SMBUS_BYTE_DATA || size == I2C_SMBUS_WORD_DATA || size == I2C_SMBUS_BLOCK_DATA || size == I2C_SMBUS_I2C_BLOCK_DATA || - (size == I2C_SMBUS_BYTE && rw == I2C_SMBUS_WRITE)){ - - // sent command code to data register - iowrite8(cmd,pci_bar+REG_DR0); - info( "MS Send CMD 0x%2.2X",cmd); + (size == I2C_SMBUS_BYTE && rw == I2C_SMBUS_WRITE)) { - // Wait {A} - error = i2c_wait_ack(adapter,12,1); - if(error<0){ - info( "get error %d",error); - goto Done; - } - } + // sent command code to data register + iowrite8(cmd, pci_bar + REG_DR0); + info( "MS Send CMD 0x%2.2X", cmd); - switch(size){ - case I2C_SMBUS_BYTE_DATA: - cnt = 1; break; - case I2C_SMBUS_WORD_DATA: - cnt = 2; break; - case I2C_SMBUS_BLOCK_DATA: - case I2C_SMBUS_I2C_BLOCK_DATA: - /* In block data modes keep number of byte in block[0] */ - cnt = data->block[0]; - break; - default: - cnt = 0; break; + // Wait {A} + error = i2c_wait_ack(adapter, 12, 1); + if (error < 0) { + info( "get error %d", error); + goto Done; } + } - // [CNT] used only block data write - if(size == I2C_SMBUS_BLOCK_DATA && rw == I2C_SMBUS_WRITE){ - - iowrite8(cnt,pci_bar+REG_DR0); - info( "MS Send CNT 0x%2.2X",cnt); + switch (size) { + case I2C_SMBUS_BYTE_DATA: + cnt = 1; break; + case I2C_SMBUS_WORD_DATA: + cnt = 2; break; + case I2C_SMBUS_BLOCK_DATA: + case I2C_SMBUS_I2C_BLOCK_DATA: + /* In block data modes keep number of byte in block[0] */ + cnt = data->block[0]; + break; + default: + cnt = 0; break; + } - // Wait {A} - error = i2c_wait_ack(adapter,12,1); - if(error<0){ - info( "get error %d",error); - goto Done; - } - } + // [CNT] used only block data write + if (size == I2C_SMBUS_BLOCK_DATA && rw == I2C_SMBUS_WRITE) { - // [DATA]{A} - if( rw == I2C_SMBUS_WRITE && ( - size == I2C_SMBUS_BYTE || - size == I2C_SMBUS_BYTE_DATA || - size == I2C_SMBUS_WORD_DATA || - size == I2C_SMBUS_BLOCK_DATA || - size == I2C_SMBUS_I2C_BLOCK_DATA - )){ - bid = 0; - info( "MS prepare to sent [%d bytes]",cnt); - if(size == I2C_SMBUS_BLOCK_DATA || size == I2C_SMBUS_I2C_BLOCK_DATA){ - bid=1; // block[0] is cnt; - cnt+=1; // offset from block[0] - } - for(;bidblock[bid],pci_bar+REG_DR0); - info( " Data > %2.2X",data->block[bid]); - // Wait {A} - error = i2c_wait_ack(adapter,12,1); - if(error<0){ - goto Done; - } - } + iowrite8(cnt, pci_bar + REG_DR0); + info( "MS Send CNT 0x%2.2X", cnt); + // Wait {A} + error = i2c_wait_ack(adapter, 12, 1); + if (error < 0) { + info( "get error %d", error); + goto Done; } + } - // REPEATE START - if( rw == I2C_SMBUS_READ && ( + // [DATA]{A} + if ( rw == I2C_SMBUS_WRITE && ( + size == I2C_SMBUS_BYTE || size == I2C_SMBUS_BYTE_DATA || size == I2C_SMBUS_WORD_DATA || size == I2C_SMBUS_BLOCK_DATA || size == I2C_SMBUS_I2C_BLOCK_DATA - )){ - info( "MS Repeated Start"); - - SET_REG_BIT_L(pci_bar+REG_CR0,I2C_CR_BIT_MEN); - iowrite8(1 << I2C_CR_BIT_MIEN | - 1 << I2C_CR_BIT_MTX | - 1 << I2C_CR_BIT_MSTA | - 1 << I2C_CR_BIT_RSTA ,pci_bar+REG_CR0); - SET_REG_BIT_H(pci_bar+REG_CR0,I2C_CR_BIT_MEN); - - // sent Address with Read mode - iowrite8( addr<<1 | 0x1 ,pci_bar+REG_DR0); + )) { + bid = 0; + info( "MS prepare to sent [%d bytes]", cnt); + if (size == I2C_SMBUS_BLOCK_DATA || size == I2C_SMBUS_I2C_BLOCK_DATA) { + bid = 1; // block[0] is cnt; + cnt += 1; // offset from block[0] + } + for (; bid < cnt; bid++) { + iowrite8(data->block[bid], pci_bar + REG_DR0); + info( " Data > %2.2X", data->block[bid]); // Wait {A} - error = i2c_wait_ack(adapter,12,1); - if(error<0){ + error = i2c_wait_ack(adapter, 12, 1); + if (error < 0) { goto Done; } + } + } + + // REPEATE START + if ( rw == I2C_SMBUS_READ && ( + size == I2C_SMBUS_BYTE_DATA || + size == I2C_SMBUS_WORD_DATA || + size == I2C_SMBUS_BLOCK_DATA || + size == I2C_SMBUS_I2C_BLOCK_DATA + )) { + info( "MS Repeated Start"); + + SET_REG_BIT_L(pci_bar + REG_CR0, I2C_CR_BIT_MEN); + iowrite8(1 << I2C_CR_BIT_MIEN | + 1 << I2C_CR_BIT_MTX | + 1 << I2C_CR_BIT_MSTA | + 1 << I2C_CR_BIT_RSTA , pci_bar + REG_CR0); + SET_REG_BIT_H(pci_bar + REG_CR0, I2C_CR_BIT_MEN); + + // sent Address with Read mode + iowrite8( addr << 1 | 0x1 , pci_bar + REG_DR0); + + // Wait {A} + error = i2c_wait_ack(adapter, 12, 1); + if (error < 0) { + goto Done; } - if( rw == I2C_SMBUS_READ && ( + } + + if ( rw == I2C_SMBUS_READ && ( size == I2C_SMBUS_BYTE || size == I2C_SMBUS_BYTE_DATA || size == I2C_SMBUS_WORD_DATA || size == I2C_SMBUS_BLOCK_DATA || size == I2C_SMBUS_I2C_BLOCK_DATA - )){ - - switch(size){ - case I2C_SMBUS_BYTE: - case I2C_SMBUS_BYTE_DATA: - cnt = 1; break; - case I2C_SMBUS_WORD_DATA: - cnt = 2; break; - case I2C_SMBUS_BLOCK_DATA: - // will be changed after recived first data - cnt = 3; break; - case I2C_SMBUS_I2C_BLOCK_DATA: - cnt = data->block[0]; break; - default: - cnt = 0; break; - } + )) { - bid = 0; - info( "MS Receive"); + switch (size) { + case I2C_SMBUS_BYTE: + case I2C_SMBUS_BYTE_DATA: + cnt = 1; break; + case I2C_SMBUS_WORD_DATA: + cnt = 2; break; + case I2C_SMBUS_BLOCK_DATA: + // will be changed after recived first data + cnt = 3; break; + case I2C_SMBUS_I2C_BLOCK_DATA: + cnt = data->block[0]; break; + default: + cnt = 0; break; + } - //set to Receive mode - iowrite8(1 << I2C_CR_BIT_MEN | - 1 << I2C_CR_BIT_MIEN | - 1 << I2C_CR_BIT_MSTA , pci_bar+REG_CR0); + bid = 0; + info( "MS Receive"); - for(bid=-1;bidblock[bid+1] = ioread8(pci_bar+REG_DR0); - }else { - data->block[bid] = ioread8(pci_bar+REG_DR0); - } - info( "DATA IN [%d] %2.2X",bid,data->block[bid]); + if (bid < 0) { + ioread8(pci_bar + REG_DR0); + info( "READ Dummy Byte" ); + } else { - if(size == I2C_SMBUS_BLOCK_DATA && bid == 0){ - cnt = data->block[0] + 1; - } + if (bid == cnt - 1) { + info ( "SET STOP in read loop"); + SET_REG_BIT_L(pci_bar + REG_CR0, I2C_CR_BIT_MSTA); + } + if (size == I2C_SMBUS_I2C_BLOCK_DATA) { + // block[0] is read length + data->block[bid + 1] = ioread8(pci_bar + REG_DR0); + } else { + data->block[bid] = ioread8(pci_bar + REG_DR0); + } + info( "DATA IN [%d] %2.2X", bid, data->block[bid]); + + if (size == I2C_SMBUS_BLOCK_DATA && bid == 0) { + cnt = data->block[0] + 1; } } } + } - // [P] - SET_REG_BIT_L(pci_bar+REG_CR0,I2C_CR_BIT_MSTA); - info( "MS STOP"); + // [P] + SET_REG_BIT_L(pci_bar + REG_CR0, I2C_CR_BIT_MSTA); + info( "MS STOP"); Done: - iowrite8(1<= 0){ + while (retry--) { + error = smbus_access(adapter, (u16)(prev_switch), flags, + I2C_SMBUS_WRITE, 0x00, + I2C_SMBUS_BYTE, NULL); + if (error >= 0) { break; - }else{ - dev_dbg(&adapter->dev,"Failed to deselect ch %d of 0x%x, CODE %d\n", prev_ch, prev_switch, error); + } else { + dev_dbg(&adapter->dev, + "Failed to deselect ch %d of 0x%x, CODE %d\n", + prev_ch, prev_switch, error); } } - if(retry < 0){ + if (retry < 0) { goto release_unlock; } // set PCA9548 to current channel retry = 3; - while(retry--){ - error = smbus_access(adapter, switch_addr, flags, I2C_SMBUS_WRITE, 1 << channel, I2C_SMBUS_BYTE, NULL); - if(error >= 0){ + while (retry--) { + error = smbus_access(adapter, switch_addr, flags, + I2C_SMBUS_WRITE, 1 << channel, + I2C_SMBUS_BYTE, NULL); + if (error >= 0) { break; - }else{ - dev_dbg(&adapter->dev,"Failed to deselect ch %d of 0x%x, CODE %d\n", prev_ch, prev_switch, error); + } else { + dev_dbg(&adapter->dev, + "Failed to deselect ch %d of 0x%x, CODE %d\n", + prev_ch, prev_switch, error); } } - if(retry < 0){ + if (retry < 0) { goto release_unlock; } // update lasted port @@ -1473,41 +1767,47 @@ static int fpga_i2c_access(struct i2c_adapter *adapter, u16 addr, if ( prev_ch != channel || prev_switch == 0 ) { // set new PCA9548 at switch_addr to current retry = 3; - while(retry--){ - error = smbus_access(adapter, switch_addr, flags, I2C_SMBUS_WRITE, 1 << channel, I2C_SMBUS_BYTE, NULL); - if(error >= 0){ + while (retry--) { + error = smbus_access(adapter, switch_addr, flags, + I2C_SMBUS_WRITE, 1 << channel, + I2C_SMBUS_BYTE, NULL); + if (error >= 0) { break; - }else{ - dev_dbg(&adapter->dev,"Failed to deselect ch %d of 0x%x, CODE %d\n", prev_ch, prev_switch, error); + } else { + dev_dbg(&adapter->dev, + "Failed to deselect ch %d of 0x%x, CODE %d\n", + prev_ch, prev_switch, error); + } } - } - if(retry < 0){ - goto release_unlock; - } - // update lasted port - fpga_i2c_lasted_access_port[master_bus - 1] = switch_addr << 8 | channel; + if (retry < 0) { + goto release_unlock; + } + // update lasted port + fpga_i2c_lasted_access_port[master_bus - 1] = switch_addr << 8 | channel; } } } // Do SMBus communication error = smbus_access(adapter, addr, flags, rw, cmd, size, data); - if(error < 0){ - dev_dbg( &adapter->dev,"smbus_xfer failed (%d) @ 0x%2.2X|f 0x%4.4X|(%d)%-5s| (%d)%-10s|CMD %2.2X " - , error, addr, flags, rw, rw == 1 ? "READ " : "WRITE" - , size, size == 0 ? "QUICK" : - size == 1 ? "BYTE" : - size == 2 ? "BYTE_DATA" : - size == 3 ? "WORD_DATA" : - size == 4 ? "PROC_CALL" : - size == 5 ? "BLOCK_DATA" : - size == 8 ? "I2C_BLOCK_DATA" : "ERROR" - , cmd); + if (error < 0) { + dev_dbg( &adapter->dev, + "smbus_xfer failed (%d) @ 0x%2.2X|f 0x%4.4X|(%d)%-5s| (%d)%-10s|CMD %2.2X " + , error, addr, flags, rw, rw == 1 ? "READ " : "WRITE" + , size, size == 0 ? "QUICK" : + size == 1 ? "BYTE" : + size == 2 ? "BYTE_DATA" : + size == 3 ? "WORD_DATA" : + size == 4 ? "PROC_CALL" : + size == 5 ? "BLOCK_DATA" : + size == 8 ? "I2C_BLOCK_DATA" : "ERROR" + , cmd); } -release_unlock: +release_unlock: mutex_unlock(&fpga_i2c_master_locks[master_bus - 1]); - dev_dbg(&adapter->dev,"switch ch %d of 0x%x -> ch %d of 0x%x\n", prev_ch, prev_switch, channel, switch_addr); + dev_dbg(&adapter->dev, "switch ch %d of 0x%x -> ch %d of 0x%x\n", + prev_ch, prev_switch, channel, switch_addr); return error; } @@ -1519,11 +1819,11 @@ static int fpga_i2c_access(struct i2c_adapter *adapter, u16 addr, static u32 fpga_i2c_func(struct i2c_adapter *a) { return I2C_FUNC_SMBUS_QUICK | - I2C_FUNC_SMBUS_BYTE | - I2C_FUNC_SMBUS_BYTE_DATA | - I2C_FUNC_SMBUS_WORD_DATA | - I2C_FUNC_SMBUS_BLOCK_DATA| - I2C_FUNC_SMBUS_I2C_BLOCK; + I2C_FUNC_SMBUS_BYTE | + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA | + I2C_FUNC_SMBUS_BLOCK_DATA | + I2C_FUNC_SMBUS_I2C_BLOCK; } static const struct i2c_algorithm seastone2_i2c_algorithm = { @@ -1541,7 +1841,8 @@ static const struct i2c_algorithm seastone2_i2c_algorithm = { * When bus_number_offset is -1, created adapter with dynamic bus number. * Otherwise create adapter at i2c bus = bus_number_offset + portid. */ -static struct i2c_adapter * seastone2_i2c_init(struct platform_device *pdev, int portid, int bus_number_offset) +static struct i2c_adapter * seastone2_i2c_init(struct platform_device *pdev, + int portid, int bus_number_offset) { int error; struct i2c_adapter *new_adapter; @@ -1549,8 +1850,9 @@ static struct i2c_adapter * seastone2_i2c_init(struct platform_device *pdev, int void __iomem *i2c_freq_base_reg; new_adapter = kzalloc(sizeof(*new_adapter), GFP_KERNEL); - if (!new_adapter){ - printk(KERN_ALERT "Cannot alloc i2c adapter for %s", fpga_i2c_bus_dev[portid].calling_name); + if (!new_adapter) { + printk(KERN_ALERT "Cannot alloc i2c adapter for %s", + fpga_i2c_bus_dev[portid].calling_name); return NULL; } @@ -1558,15 +1860,16 @@ static struct i2c_adapter * seastone2_i2c_init(struct platform_device *pdev, int new_adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; new_adapter->algo = &seastone2_i2c_algorithm; /* If the bus offset is -1, use dynamic bus number */ - if (bus_number_offset == -1){ + if (bus_number_offset == -1) { new_adapter->nr = -1; - }else{ + } else { new_adapter->nr = bus_number_offset + portid; } new_data = kzalloc(sizeof(*new_data), GFP_KERNEL); - if (!new_data){ - printk(KERN_ALERT "Cannot alloc i2c data for %s", fpga_i2c_bus_dev[portid].calling_name); + if (!new_data) { + printk(KERN_ALERT "Cannot alloc i2c data for %s", + fpga_i2c_bus_dev[portid].calling_name); kzfree(new_adapter); return NULL; } @@ -1575,16 +1878,16 @@ static struct i2c_adapter * seastone2_i2c_init(struct platform_device *pdev, int new_data->pca9548.master_bus = fpga_i2c_bus_dev[portid].master_bus; new_data->pca9548.switch_addr = fpga_i2c_bus_dev[portid].switch_addr; new_data->pca9548.channel = fpga_i2c_bus_dev[portid].channel; - strcpy(new_data->pca9548.calling_name,fpga_i2c_bus_dev[portid].calling_name); + strcpy(new_data->pca9548.calling_name, fpga_i2c_bus_dev[portid].calling_name); snprintf(new_adapter->name, sizeof(new_adapter->name), - "SMBus I2C Adapter PortID: %s", new_data->pca9548.calling_name); + "SMBus I2C Adapter PortID: %s", new_data->pca9548.calling_name); - i2c_freq_base_reg = fpga_dev.data_base_addr+I2C_MASTER_FREQ_1; - iowrite8(0x07,i2c_freq_base_reg+(new_data->pca9548.master_bus-1)*0x100); // 0x07 400kHz - i2c_set_adapdata(new_adapter,new_data); + i2c_freq_base_reg = fpga_dev.data_base_addr + I2C_MASTER_FREQ_1; + iowrite8(0x07, i2c_freq_base_reg + (new_data->pca9548.master_bus - 1) * 0x100); // 0x07 400kHz + i2c_set_adapdata(new_adapter, new_data); error = i2c_add_numbered_adapter(new_adapter); - if(error < 0){ + if (error < 0) { printk(KERN_ALERT "Cannot add i2c adapter %s", new_data->pca9548.calling_name); kzfree(new_adapter); kzfree(new_data); @@ -1594,30 +1897,6 @@ static struct i2c_adapter * seastone2_i2c_init(struct platform_device *pdev, int return new_adapter; }; -// I/O resource need. -static struct resource seastone2_resources[] = { - { - .start = 0x10000000, - .end = 0x10001000, - .flags = IORESOURCE_MEM, - }, -}; - -static void seastone2_dev_release( struct device * dev) -{ - return; -} - -static struct platform_device seastone2_dev = { - .name = DRIVER_NAME, - .id = -1, - .num_resources = ARRAY_SIZE(seastone2_resources), - .resource = seastone2_resources, - .dev = { - .release = seastone2_dev_release, - } -}; - /** * Board info for QSFP/SFP+ eeprom. * Note: Using sff8436 as I2C eeprom driver. @@ -1629,7 +1908,6 @@ static struct i2c_board_info sff8436_eeprom_info[] = { static int seastone2_drv_probe(struct platform_device *pdev) { - struct resource *res; int ret = 0; int portid_count; uint8_t cpld1_version, cpld2_version; @@ -1640,30 +1918,24 @@ static int seastone2_drv_probe(struct platform_device *pdev) BUG_ON(fpgafwclass == NULL); fpga_data = devm_kzalloc(&pdev->dev, sizeof(struct seastone2_fpga_data), - GFP_KERNEL); + GFP_KERNEL); if (!fpga_data) return -ENOMEM; // Set default read address to VERSION - fpga_data->fpga_read_addr = fpga_dev.data_base_addr+FPGA_VERSION; + fpga_data->fpga_read_addr = fpga_dev.data_base_addr + FPGA_VERSION; fpga_data->cpld1_read_addr = 0x00; fpga_data->cpld2_read_addr = 0x00; mutex_init(&fpga_data->fpga_lock); - for(ret=I2C_MASTER_CH_1 ;ret <= I2C_MASTER_CH_TOTAL; ret++){ - mutex_init(&fpga_i2c_master_locks[ret-1]); - } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (unlikely(!res)) { - printk(KERN_ERR "Specified Resource Not Available...\n"); - kzfree(fpga_data); - return -1; + for (ret = I2C_MASTER_CH_1 ; ret <= I2C_MASTER_CH_TOTAL; ret++) { + mutex_init(&fpga_i2c_master_locks[ret - 1]); } fpga = kobject_create_and_add("FPGA", &pdev->dev.kobj); - if (!fpga){ + if (!fpga) { kzfree(fpga_data); return -ENOMEM; } @@ -1677,7 +1949,7 @@ static int seastone2_drv_probe(struct platform_device *pdev) } cpld1 = kobject_create_and_add("CPLD1", &pdev->dev.kobj); - if (!cpld1){ + if (!cpld1) { sysfs_remove_group(fpga, &fpga_attr_grp); kobject_put(fpga); kzfree(fpga_data); @@ -1694,7 +1966,7 @@ static int seastone2_drv_probe(struct platform_device *pdev) } cpld2 = kobject_create_and_add("CPLD2", &pdev->dev.kobj); - if (!cpld2){ + if (!cpld2) { sysfs_remove_group(cpld1, &cpld1_attr_grp); kobject_put(cpld1); sysfs_remove_group(fpga, &fpga_attr_grp); @@ -1714,8 +1986,8 @@ static int seastone2_drv_probe(struct platform_device *pdev) return ret; } - sff_dev = device_create(fpgafwclass, NULL, MKDEV(0,0), NULL, "sff_device"); - if (IS_ERR(sff_dev)){ + sff_dev = device_create(fpgafwclass, NULL, MKDEV(0, 0), NULL, "sff_device"); + if (IS_ERR(sff_dev)) { printk(KERN_ERR "Failed to create sff device\n"); sysfs_remove_group(cpld2, &cpld2_attr_grp); kobject_put(cpld2); @@ -1730,7 +2002,7 @@ static int seastone2_drv_probe(struct platform_device *pdev) ret = sysfs_create_group(&sff_dev->kobj, &sff_led_test_grp); if (ret != 0) { printk(KERN_ERR "Cannot create SFF attributes\n"); - device_destroy(fpgafwclass, MKDEV(0,0)); + device_destroy(fpgafwclass, MKDEV(0, 0)); sysfs_remove_group(cpld2, &cpld2_attr_grp); kobject_put(cpld2); sysfs_remove_group(cpld1, &cpld1_attr_grp); @@ -1741,10 +2013,10 @@ static int seastone2_drv_probe(struct platform_device *pdev) return ret; } - ret = sysfs_create_link(&pdev->dev.kobj,&sff_dev->kobj,"SFF"); - if (ret != 0){ + ret = sysfs_create_link(&pdev->dev.kobj, &sff_dev->kobj, "SFF"); + if (ret != 0) { sysfs_remove_group(&sff_dev->kobj, &sff_led_test_grp); - device_destroy(fpgafwclass, MKDEV(0,0)); + device_destroy(fpgafwclass, MKDEV(0, 0)); sysfs_remove_group(cpld2, &cpld2_attr_grp); kobject_put(cpld2); sysfs_remove_group(cpld1, &cpld1_attr_grp); @@ -1755,27 +2027,27 @@ static int seastone2_drv_probe(struct platform_device *pdev) return ret; } - for(portid_count=0 ; portid_count < VIRTUAL_I2C_PORT_LENGTH ; portid_count++){ + for (portid_count = 0 ; portid_count < VIRTUAL_I2C_PORT_LENGTH ; portid_count++) { fpga_data->i2c_adapter[portid_count] = seastone2_i2c_init(pdev, portid_count, VIRTUAL_I2C_BUS_OFFSET); } /* Init SFF devices */ - for(portid_count=0; portid_count < SFF_PORT_TOTAL; portid_count++){ + for (portid_count = 0; portid_count < SFF_PORT_TOTAL; portid_count++) { struct i2c_adapter *i2c_adap = fpga_data->i2c_adapter[portid_count]; - if(i2c_adap){ + if (i2c_adap) { fpga_data->sff_devices[portid_count] = seastone2_sff_init(portid_count); sff_data = dev_get_drvdata(fpga_data->sff_devices[portid_count]); BUG_ON(sff_data == NULL); - if( sff_data->port_type == QSFP ){ + if ( sff_data->port_type == QSFP ) { fpga_data->sff_i2c_clients[portid_count] = i2c_new_device(i2c_adap, &sff8436_eeprom_info[0]); - }else{ + } else { fpga_data->sff_i2c_clients[portid_count] = i2c_new_device(i2c_adap, &sff8436_eeprom_info[1]); } sff_data = NULL; sysfs_create_link(&fpga_data->sff_devices[portid_count]->kobj, - &fpga_data->sff_i2c_clients[portid_count]->dev.kobj, - "i2c"); + &fpga_data->sff_i2c_clients[portid_count]->dev.kobj, + "i2c"); } } @@ -1785,10 +2057,10 @@ static int seastone2_drv_probe(struct platform_device *pdev) #ifdef TEST_MODE return 0; #endif - fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00, - I2C_SMBUS_READ,0x00,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&cpld1_version); - fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00, - I2C_SMBUS_READ,0x00,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&cpld2_version); + fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, + I2C_SMBUS_READ, 0x00, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&cpld1_version); + fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, + I2C_SMBUS_READ, 0x00, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&cpld2_version); printk(KERN_INFO "CPLD1 VERSON: %2.2x\n", cpld1_version); printk(KERN_INFO "CPLD2 VERSON: %2.2x\n", cpld2_version); @@ -1809,7 +2081,7 @@ static int seastone2_drv_probe(struct platform_device *pdev) if (prev_i2c_switch != ( (master_bus << 8) | switch_addr) ) { // Found the bus with PCA9548, trying to clear all switch in it. smbus_access(fpga_data->i2c_adapter[portid_count], switch_addr, 0x00, - I2C_SMBUS_WRITE, 0x00, I2C_SMBUS_BYTE, NULL); + I2C_SMBUS_WRITE, 0x00, I2C_SMBUS_BYTE, NULL); prev_i2c_switch = ( master_bus << 8 ) | switch_addr; } } @@ -1822,20 +2094,20 @@ static int seastone2_drv_remove(struct platform_device *pdev) int portid_count; struct sff_device_data *rem_data; - for(portid_count=0; portid_count < SFF_PORT_TOTAL; portid_count++){ - sysfs_remove_link(&fpga_data->sff_devices[portid_count]->kobj,"i2c"); + for (portid_count = 0; portid_count < SFF_PORT_TOTAL; portid_count++) { + sysfs_remove_link(&fpga_data->sff_devices[portid_count]->kobj, "i2c"); i2c_unregister_device(fpga_data->sff_i2c_clients[portid_count]); } - for(portid_count=0 ; portid_count < VIRTUAL_I2C_PORT_LENGTH ; portid_count++){ - if(fpga_data->i2c_adapter[portid_count] != NULL){ - info(KERN_INFO "<%x>",fpga_data->i2c_adapter[portid_count]); + for (portid_count = 0 ; portid_count < VIRTUAL_I2C_PORT_LENGTH ; portid_count++) { + if (fpga_data->i2c_adapter[portid_count] != NULL) { + info(KERN_INFO "<%x>", fpga_data->i2c_adapter[portid_count]); i2c_del_adapter(fpga_data->i2c_adapter[portid_count]); } } - for (portid_count=0; portid_count < SFF_PORT_TOTAL; portid_count++){ - if(fpga_data->sff_devices[portid_count] != NULL){ + for (portid_count = 0; portid_count < SFF_PORT_TOTAL; portid_count++) { + if (fpga_data->sff_devices[portid_count] != NULL) { rem_data = dev_get_drvdata(fpga_data->sff_devices[portid_count]); device_unregister(fpga_data->sff_devices[portid_count]); put_device(fpga_data->sff_devices[portid_count]); @@ -1850,7 +2122,7 @@ static int seastone2_drv_remove(struct platform_device *pdev) kobject_put(fpga); kobject_put(cpld1); kobject_put(cpld2); - device_destroy(fpgafwclass, MKDEV(0,0)); + device_destroy(fpgafwclass, MKDEV(0, 0)); devm_kfree(&pdev->dev, fpga_data); return 0; } @@ -1864,9 +2136,9 @@ static struct platform_driver seastone2_drv = { }; #ifdef TEST_MODE - #define FPGA_PCI_BAR_NUM 2 +#define FPGA_PCI_BAR_NUM 2 #else - #define FPGA_PCI_BAR_NUM 0 +#define FPGA_PCI_BAR_NUM 0 #endif static const struct pci_device_id fpga_id_table[] = { @@ -1885,7 +2157,7 @@ static int fpga_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) if ((err = pci_enable_device(pdev))) { dev_err(dev, "pci_enable_device probe error %d for device %s\n", - err, pci_name(pdev)); + err, pci_name(pdev)); return err; } @@ -1900,28 +2172,32 @@ static int fpga_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) fpga_dev.data_base_addr = pci_iomap(pdev, FPGA_PCI_BAR_NUM, 0); if (!fpga_dev.data_base_addr) { dev_err(dev, "cannot iomap region of size %lu\n", - (unsigned long)fpga_dev.data_mmio_len); + (unsigned long)fpga_dev.data_mmio_len); goto pci_release; } dev_info(dev, "data_mmio iomap base = 0x%lx \n", - (unsigned long)fpga_dev.data_base_addr); + (unsigned long)fpga_dev.data_base_addr); dev_info(dev, "data_mmio_start = 0x%lx data_mmio_len = %lu\n", - (unsigned long)fpga_dev.data_mmio_start, - (unsigned long)fpga_dev.data_mmio_len); + (unsigned long)fpga_dev.data_mmio_start, + (unsigned long)fpga_dev.data_mmio_len); printk(KERN_INFO "FPGA PCIe driver probe OK.\n"); - printk(KERN_INFO "FPGA ioremap registers of size %lu\n",(unsigned long)fpga_dev.data_mmio_len); + printk(KERN_INFO "FPGA ioremap registers of size %lu\n", (unsigned long)fpga_dev.data_mmio_len); printk(KERN_INFO "FPGA Virtual BAR %d at %8.8lx - %8.8lx\n", FPGA_PCI_BAR_NUM, - (unsigned long)fpga_dev.data_base_addr, - (unsigned long)(fpga_dev.data_base_addr + fpga_dev.data_mmio_len)); + (unsigned long)fpga_dev.data_base_addr, + (unsigned long)(fpga_dev.data_base_addr + fpga_dev.data_mmio_len)); printk(KERN_INFO ""); fpga_version = ioread32(fpga_dev.data_base_addr); printk(KERN_INFO "FPGA VERSION : %8.8x\n", fpga_version); - fpgafw_init(); - platform_device_register(&seastone2_dev); + if ((err = fpgafw_init()) < 0) { + goto pci_unmap; + } + seastone2_dev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0); platform_driver_register(&seastone2_drv); return 0; +pci_unmap: + pci_iounmap(pdev, fpga_dev.data_base_addr); pci_release: pci_release_regions(pdev); pci_disable: @@ -1932,7 +2208,7 @@ static int fpga_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) static void fpga_pci_remove(struct pci_dev *pdev) { platform_driver_unregister(&seastone2_drv); - platform_device_unregister(&seastone2_dev); + platform_device_unregister(seastone2_dev); fpgafw_exit(); pci_iounmap(pdev, fpga_dev.data_base_addr); pci_release_regions(pdev); @@ -1947,7 +2223,7 @@ static struct pci_driver pci_dev_ops = { .id_table = fpga_id_table, }; -enum{ +enum { READREG, WRITEREG }; @@ -1957,7 +2233,8 @@ struct fpga_reg_data { uint32_t value; }; -static long fpgafw_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg){ +static long fpgafw_unlocked_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) { int ret = 0; struct fpga_reg_data data; mutex_lock(&fpga_data->fpga_lock); @@ -1966,55 +2243,55 @@ static long fpgafw_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned static uint32_t status_reg; #endif // Switch function to read and write. - switch (cmd){ - case READREG: - if (copy_from_user(&data, (void __user*)arg, sizeof(data)) != 0){ - mutex_unlock(&fpga_data->fpga_lock); - return -EFAULT; - } - data.value = ioread32(fpga_dev.data_base_addr+data.addr); - if (copy_to_user((void __user*)arg ,&data, sizeof(data)) != 0){ - mutex_unlock(&fpga_data->fpga_lock); - return -EFAULT; - } + switch (cmd) { + case READREG: + if (copy_from_user(&data, (void __user*)arg, sizeof(data)) != 0) { + mutex_unlock(&fpga_data->fpga_lock); + return -EFAULT; + } + data.value = ioread32(fpga_dev.data_base_addr + data.addr); + if (copy_to_user((void __user*)arg , &data, sizeof(data)) != 0) { + mutex_unlock(&fpga_data->fpga_lock); + return -EFAULT; + } #ifdef TEST_MODE - if(data.addr == 0x1210){ - switch (status_reg){ - case 0x0000 : status_reg=0x8000; - break; + if (data.addr == 0x1210) { + switch (status_reg) { + case 0x0000 : status_reg = 0x8000; + break; - case 0x8080 : status_reg=0x80C0; - break; - case 0x80C0 : status_reg=0x80F0; - break; - case 0x80F0 : status_reg=0x80F8; - break; + case 0x8080 : status_reg = 0x80C0; + break; + case 0x80C0 : status_reg = 0x80F0; + break; + case 0x80F0 : status_reg = 0x80F8; + break; - } - iowrite32(status_reg,fpga_dev.data_base_addr+0x1210); } + iowrite32(status_reg, fpga_dev.data_base_addr + 0x1210); + } #endif - break; - case WRITEREG: - if (copy_from_user(&data, (void __user*)arg, sizeof(data)) != 0){ - mutex_unlock(&fpga_data->fpga_lock); - return -EFAULT; - } - iowrite32(data.value,fpga_dev.data_base_addr+data.addr); + break; + case WRITEREG: + if (copy_from_user(&data, (void __user*)arg, sizeof(data)) != 0) { + mutex_unlock(&fpga_data->fpga_lock); + return -EFAULT; + } + iowrite32(data.value, fpga_dev.data_base_addr + data.addr); #ifdef TEST_MODE - if(data.addr == 0x1204){ - status_reg=0x8080; - iowrite32(status_reg,fpga_dev.data_base_addr+0x1210); - } + if (data.addr == 0x1204) { + status_reg = 0x8080; + iowrite32(status_reg, fpga_dev.data_base_addr + 0x1210); + } #endif - break; - default: - mutex_unlock(&fpga_data->fpga_lock); - return -EINVAL; + break; + default: + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; } mutex_unlock(&fpga_data->fpga_lock); return ret; @@ -2027,50 +2304,49 @@ const struct file_operations fpgafw_fops = { }; -static int fpgafw_init(void){ - printk(KERN_INFO "Initializing the switchboard driver\n"); - // Try to dynamically allocate a major number for the device -- more difficult but worth it - majorNumber = register_chrdev(0, DEVICE_NAME, &fpgafw_fops); - if (majorNumber<0){ - printk(KERN_ALERT "Failed to register a major number\n"); - return majorNumber; - } - printk(KERN_INFO "Device registered correctly with major number %d\n", majorNumber); - - // Register the device class - fpgafwclass = class_create(THIS_MODULE, CLASS_NAME); - if (IS_ERR(fpgafwclass)){ // Check for error and clean up if there is - unregister_chrdev(majorNumber, DEVICE_NAME); - printk(KERN_ALERT "Failed to register device class\n"); - return PTR_ERR(fpgafwclass); // Correct way to return an error on a pointer - } - printk(KERN_INFO "Device class registered correctly\n"); - - // Register the device driver - fpgafwdev = device_create(fpgafwclass, NULL, MKDEV(majorNumber, 0), NULL, DEVICE_NAME); - if (IS_ERR(fpgafwdev)){ // Clean up if there is an error - class_destroy(fpgafwclass); // Repeated code but the alternative is goto statements - unregister_chrdev(majorNumber, DEVICE_NAME); - printk(KERN_ALERT "Failed to create the FW upgrade device node\n"); - return PTR_ERR(fpgafwdev); - } - printk(KERN_INFO "FPGA fw upgrade device node created correctly\n"); // Made it! device was initialized - return 0; +static int fpgafw_init(void) { + printk(KERN_INFO "Initializing the switchboard driver\n"); + // Try to dynamically allocate a major number for the device -- more difficult but worth it + majorNumber = register_chrdev(0, DEVICE_NAME, &fpgafw_fops); + if (majorNumber < 0) { + printk(KERN_ALERT "Failed to register a major number\n"); + return majorNumber; + } + printk(KERN_INFO "Device registered correctly with major number %d\n", majorNumber); + + // Register the device class + fpgafwclass = class_create(THIS_MODULE, CLASS_NAME); + if (IS_ERR(fpgafwclass)) { // Check for error and clean up if there is + unregister_chrdev(majorNumber, DEVICE_NAME); + printk(KERN_ALERT "Failed to register device class\n"); + return PTR_ERR(fpgafwclass); + } + printk(KERN_INFO "Device class registered correctly\n"); + + // Register the device driver + fpgafwdev = device_create(fpgafwclass, NULL, MKDEV(majorNumber, 0), NULL, DEVICE_NAME); + if (IS_ERR(fpgafwdev)) { // Clean up if there is an error + class_destroy(fpgafwclass); // Repeated code but the alternative is goto statements + unregister_chrdev(majorNumber, DEVICE_NAME); + printk(KERN_ALERT "Failed to create the FW upgrade device node\n"); + return PTR_ERR(fpgafwdev); + } + printk(KERN_INFO "FPGA fw upgrade device node created correctly\n"); // Made it! device was initialized + return 0; } -static void fpgafw_exit(void){ - device_destroy(fpgafwclass, MKDEV(majorNumber, 0)); // remove the device - class_unregister(fpgafwclass); // unregister the device class - class_destroy(fpgafwclass); // remove the device class - unregister_chrdev(majorNumber, DEVICE_NAME); // unregister the major number - printk(KERN_INFO "Goodbye!\n"); +static void fpgafw_exit(void) { + device_destroy(fpgafwclass, MKDEV(majorNumber, 0)); // remove the device + class_destroy(fpgafwclass); // remove the device class + unregister_chrdev(majorNumber, DEVICE_NAME); // unregister the major number + printk(KERN_INFO "Goodbye!\n"); } int seastone2_init(void) { int rc; rc = pci_register_driver(&pci_dev_ops); - if(rc) + if (rc) return rc; return 0; } @@ -2083,7 +2359,7 @@ void seastone2_exit(void) module_init(seastone2_init); module_exit(seastone2_exit); -MODULE_AUTHOR("Pradchaya P. pphuhcar@celestica.com"); -MODULE_DESCRIPTION("Celestica seastone2 platform driver"); +MODULE_AUTHOR("Pradchaya P. "); +MODULE_DESCRIPTION("Celestica Seastone2 switchboard driver"); MODULE_VERSION(MOD_VERSION); MODULE_LICENSE("GPL"); \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/services/fancontrol/fancontrol b/platform/broadcom/sonic-platform-modules-cel/services/fancontrol/fancontrol index eb15598b0efa..da32acedd2f9 100755 --- a/platform/broadcom/sonic-platform-modules-cel/services/fancontrol/fancontrol +++ b/platform/broadcom/sonic-platform-modules-cel/services/fancontrol/fancontrol @@ -39,285 +39,291 @@ # PIDFILE="/var/run/fancontrol.pid" +THERMAL_OVERLOAD_CONTROL_FILE="/usr/local/bin/thermal_overload_control.sh" #DEBUG=1 MAX=255 function LoadConfig { - local fcvcount fcv - - echo "Loading configuration from $1 ..." - if [ ! -r "$1" ] - then - echo "Error: Can't read configuration file" >&2 - exit 1 - fi - - # grep configuration from file - INTERVAL=`egrep '^INTERVAL=.*$' $1 | sed -e 's/INTERVAL=//g'` - DEVPATH=`egrep '^DEVPATH=.*$' $1 | sed -e 's/DEVPATH= *//g'` - DEVNAME=`egrep '^DEVNAME=.*$' $1 | sed -e 's/DEVNAME= *//g'` - FCTEMPS=`egrep '^FCTEMPS=.*$' $1 | sed -e 's/FCTEMPS=//g'` - MINTEMP=`egrep '^MINTEMP=.*$' $1 | sed -e 's/MINTEMP=//g'` - MAXTEMP=`egrep '^MAXTEMP=.*$' $1 | sed -e 's/MAXTEMP=//g'` - MINSTART=`egrep '^MINSTART=.*$' $1 | sed -e 's/MINSTART=//g'` - MINSTOP=`egrep '^MINSTOP=.*$' $1 | sed -e 's/MINSTOP=//g'` - # optional settings: - FCFANS=`egrep '^FCFANS=.*$' $1 | sed -e 's/FCFANS=//g'` - MINPWM=`egrep '^MINPWM=.*$' $1 | sed -e 's/MINPWM=//g'` - MAXPWM=`egrep '^MAXPWM=.*$' $1 | sed -e 's/MAXPWM=//g'` - THYST=`egrep '^THYST=.*$' $1 | sed -e 's/THYST=//g'` - echo - # Check whether all mandatory settings are set - if [[ -z ${INTERVAL} || -z ${FCTEMPS} || -z ${MINTEMP} || -z ${MAXTEMP} || -z ${MINSTART} || -z ${MINSTOP} ]] - then - echo "Some mandatory settings missing, please check your config file!" >&2 - exit 1 - fi - if [ "$INTERVAL" -le 0 ] - then - echo "Error in configuration file:" >&2 - echo "INTERVAL must be at least 1" >&2 - exit 1 - fi - - # write settings to arrays for easier use and print them - echo - echo "Common settings:" - echo " INTERVAL=$INTERVAL" - - let fcvcount=0 - for fcv in $FCTEMPS - do - if ! echo $fcv | egrep -q '=' - then - echo "Error in configuration file:" >&2 - echo "FCTEMPS value is improperly formatted" >&2 - exit 1 - fi - - AFCPWM[$fcvcount]=`echo $fcv |cut -d'=' -f1` - AFCTEMP[$fcvcount]=`echo $fcv |cut -d'=' -f2` - AFCFAN[$fcvcount]=`echo $FCFANS |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` - AFCFANFAULT[$fcvcount]=`echo "${AFCFAN[$fcvcount]}" |sed -e 's/input/fault/g'` - AFCMINTEMP[$fcvcount]=`echo $MINTEMP |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` - AFCMAXTEMP[$fcvcount]=`echo $MAXTEMP |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` - AFCMINSTART[$fcvcount]=`echo $MINSTART |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` - AFCMINSTOP[$fcvcount]=`echo $MINSTOP |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` - AFCMINPWM[$fcvcount]=`echo $MINPWM |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` - [ -z "${AFCMINPWM[$fcvcount]}" ] && AFCMINPWM[$fcvcount]=0 - AFCMAXPWM[$fcvcount]=`echo $MAXPWM |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` - [ -z "${AFCMAXPWM[$fcvcount]}" ] && AFCMAXPWM[$fcvcount]=255 - AFCTHYST[$fcvcount]=`echo $THYST |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` - [ -z "${AFCTHYST[$fcvcount]}" ] && AFCTHYST[$fcvcount]=0 - - # verify the validity of the settings - if [ "${AFCMINTEMP[$fcvcount]}" -ge "${AFCMAXTEMP[$fcvcount]}" ] - then - echo "Error in configuration file (${AFCPWM[$fcvcount]}):" >&2 - echo "MINTEMP must be less than MAXTEMP" >&2 - exit 1 - fi - if [ "${AFCMAXPWM[$fcvcount]}" -gt 255 ] - then - echo "Error in configuration file (${AFCPWM[$fcvcount]}):" >&2 - echo "MAXPWM must be at most 255" >&2 - exit 1 - fi - if [ "${AFCMINSTOP[$fcvcount]}" -ge "${AFCMAXPWM[$fcvcount]}" ] - then - echo "Error in configuration file (${AFCPWM[$fcvcount]}):" >&2 - echo "MINSTOP must be less than MAXPWM" >&2 - exit 1 - fi - if [ "${AFCMINSTOP[$fcvcount]}" -lt "${AFCMINPWM[$fcvcount]}" ] - then - echo "Error in configuration file (${AFCPWM[$fcvcount]}):" >&2 - echo "MINSTOP must be greater than or equal to MINPWM" >&2 - exit 1 - fi - if [ "${AFCMINPWM[$fcvcount]}" -lt 0 ] - then - echo "Error in configuration file (${AFCPWM[$fcvcount]}):" >&2 - echo "MINPWM must be at least 0" >&2 - exit 1 - fi - - echo - echo "Settings for ${AFCPWM[$fcvcount]}:" - echo " Depends on ${AFCTEMP[$fcvcount]}" - echo " Controls ${AFCFAN[$fcvcount]}" - echo " MINTEMP=${AFCMINTEMP[$fcvcount]}" - echo " MAXTEMP=${AFCMAXTEMP[$fcvcount]}" - echo " MINSTART=${AFCMINSTART[$fcvcount]}" - echo " MINSTOP=${AFCMINSTOP[$fcvcount]}" - echo " MINPWM=${AFCMINPWM[$fcvcount]}" - echo " MAXPWM=${AFCMAXPWM[$fcvcount]}" - echo " THYST=${AFCTHYST[$fcvcount]}" - let fcvcount=fcvcount+1 - done - echo -} + local fcvcount fcv + + echo "Loading configuration from $1 ..." + if [ ! -r "$1" ] + then + echo "Error: Can't read configuration file" >&2 + exit 1 + fi + + # grep configuration from file + INTERVAL=`egrep '^INTERVAL=.*$' $1 | sed -e 's/INTERVAL=//g'` + DEVPATH=`egrep '^DEVPATH=.*$' $1 | sed -e 's/DEVPATH= *//g'` + DEVNAME=`egrep '^DEVNAME=.*$' $1 | sed -e 's/DEVNAME= *//g'` + FCTEMPS=`egrep '^FCTEMPS=.*$' $1 | sed -e 's/FCTEMPS=//g'` + MINTEMP=`egrep '^MINTEMP=.*$' $1 | sed -e 's/MINTEMP=//g'` + MAXTEMP=`egrep '^MAXTEMP=.*$' $1 | sed -e 's/MAXTEMP=//g'` + MINSTART=`egrep '^MINSTART=.*$' $1 | sed -e 's/MINSTART=//g'` + MINSTOP=`egrep '^MINSTOP=.*$' $1 | sed -e 's/MINSTOP=//g'` + # optional settings: + FCFANS=`egrep '^FCFANS=.*$' $1 | sed -e 's/FCFANS=//g'` + MINPWM=`egrep '^MINPWM=.*$' $1 | sed -e 's/MINPWM=//g'` + MAXPWM=`egrep '^MAXPWM=.*$' $1 | sed -e 's/MAXPWM=//g'` + THYST=`egrep '^THYST=.*$' $1 | sed -e 's/THYST=//g'` + MAXTEMPCRIT=`egrep '^MAXTEMPCRIT=.*$' $1 | sed -e 's/MAXTEMPCRIT=//g'` + MAXTEMPTYPE=`egrep '^MAXTEMPTYPE=.*$' $1 | sed -e 's/MAXTEMPTYPE=//g'` + echo + # Check whether all mandatory settings are set + if [[ -z ${INTERVAL} || -z ${FCTEMPS} || -z ${MINTEMP} || -z ${MAXTEMP} || -z ${MINSTART} || -z ${MINSTOP} ]] + then + echo "Some mandatory settings missing, please check your config file!" >&2 + exit 1 + fi + if [ "$INTERVAL" -le 0 ] + then + echo "Error in configuration file:" >&2 + echo "INTERVAL must be at least 1" >&2 + exit 1 + fi + + # write settings to arrays for easier use and print them + echo + echo "Common settings:" + echo " INTERVAL=$INTERVAL" + + let fcvcount=0 + for fcv in $FCTEMPS + do + if ! echo $fcv | egrep -q '=' + then + echo "Error in configuration file:" >&2 + echo "FCTEMPS value is improperly formatted" >&2 + exit 1 + fi + + AFCPWM[$fcvcount]=`echo $fcv |cut -d'=' -f1` + AFCTEMP[$fcvcount]=`echo $fcv |cut -d'=' -f2` + AFCFAN[$fcvcount]=`echo $FCFANS |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` + AFCFANFAULT[$fcvcount]=`echo "${AFCFAN[$fcvcount]}" |sed -e 's/input/fault/g'` + AFCMINTEMP[$fcvcount]=`echo $MINTEMP |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` + AFCMAXTEMP[$fcvcount]=`echo $MAXTEMP |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` + AFCMINSTART[$fcvcount]=`echo $MINSTART |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` + AFCMINSTOP[$fcvcount]=`echo $MINSTOP |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` + AFCMINPWM[$fcvcount]=`echo $MINPWM |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` + [ -z "${AFCMINPWM[$fcvcount]}" ] && AFCMINPWM[$fcvcount]=0 + AFCMAXPWM[$fcvcount]=`echo $MAXPWM |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` + [ -z "${AFCMAXPWM[$fcvcount]}" ] && AFCMAXPWM[$fcvcount]=255 + AFCTHYST[$fcvcount]=`echo $THYST |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` + [ -z "${AFCTHYST[$fcvcount]}" ] && AFCTHYST[$fcvcount]=0 + + # verify the validity of the settings + if [ "${AFCMINTEMP[$fcvcount]}" -ge "${AFCMAXTEMP[$fcvcount]}" ] + then + echo "Error in configuration file (${AFCPWM[$fcvcount]}):" >&2 + echo "MINTEMP must be less than MAXTEMP" >&2 + exit 1 + fi + if [ "${AFCMAXPWM[$fcvcount]}" -gt 255 ] + then + echo "Error in configuration file (${AFCPWM[$fcvcount]}):" >&2 + echo "MAXPWM must be at most 255" >&2 + exit 1 + fi + if [ "${AFCMINSTOP[$fcvcount]}" -ge "${AFCMAXPWM[$fcvcount]}" ] + then + echo "Error in configuration file (${AFCPWM[$fcvcount]}):" >&2 + echo "MINSTOP must be less than MAXPWM" >&2 + exit 1 + fi + if [ "${AFCMINSTOP[$fcvcount]}" -lt "${AFCMINPWM[$fcvcount]}" ] + then + echo "Error in configuration file (${AFCPWM[$fcvcount]}):" >&2 + echo "MINSTOP must be greater than or equal to MINPWM" >&2 + exit 1 + fi + if [ "${AFCMINPWM[$fcvcount]}" -lt 0 ] + then + echo "Error in configuration file (${AFCPWM[$fcvcount]}):" >&2 + echo "MINPWM must be at least 0" >&2 + exit 1 + fi + + echo + echo "Settings for ${AFCPWM[$fcvcount]}:" + echo " Depends on ${AFCTEMP[$fcvcount]}" + echo " Controls ${AFCFAN[$fcvcount]}" + echo " MINTEMP=${AFCMINTEMP[$fcvcount]}" + echo " MAXTEMP=${AFCMAXTEMP[$fcvcount]}" + echo " MINSTART=${AFCMINSTART[$fcvcount]}" + echo " MINSTOP=${AFCMINSTOP[$fcvcount]}" + echo " MINPWM=${AFCMINPWM[$fcvcount]}" + echo " MAXPWM=${AFCMAXPWM[$fcvcount]}" + echo " THYST=${AFCTHYST[$fcvcount]}" + let fcvcount=fcvcount+1 + done + echo + + + let tscount=0 + for ts in $MAXTEMPCRIT + do + CSTEMP[$tscount]=`echo $ts | cut -d '=' -f1` + CSMAXTEMPCRIT[$tscount]=`echo $ts | cut -d '=' -f2` + CSMAXTEMPTYPE=($(echo $MAXTEMPTYPE |sed -e 's/ /\n/g'| cut -d'=' -f2)) + + echo + echo "Settings for ${CSMAXTEMPTYPE[$tscount]} temperature sensor:" + echo " Depends on ${CSTEMP[$tscount]}" + echo " MAXTEMPCRIT=${CSMAXTEMPCRIT[$tscount]}" + let tscount=tscount+1 + done + echo -function CheckFanFault() -{ - let fancount=0 - while (( $fancount < ${#AFCFANFAULT[@]} )) # go through all fan fault. - do - fault=`cat ${AFCFANFAULT[$fancount]}` - if [[ "$fault" == "1" ]] - then - return 1 # fan fault detected - fi - let fancount=$fancount+1 - done - return 0 } + function DevicePath() { - if [ -h "$1/device" ] - then - readlink -f "$1/device" | sed -e 's/^\/sys\///' - fi + if [ -h "$1/device" ] + then + readlink -f "$1/device" | sed -e 's/^\/sys\///' + fi } function DeviceName() { - if [ -r "$1/name" ] - then - cat "$1/name" | sed -e 's/[[:space:]=]/_/g' - elif [ -r "$1/device/name" ] - then - cat "$1/device/name" | sed -e 's/[[:space:]=]/_/g' - fi + if [ -r "$1/name" ] + then + cat "$1/name" | sed -e 's/[[:space:]=]/_/g' + elif [ -r "$1/device/name" ] + then + cat "$1/device/name" | sed -e 's/[[:space:]=]/_/g' + fi } function ValidateDevices() { - local OLD_DEVPATH="$1" OLD_DEVNAME="$2" outdated=0 - local entry device name path - - for entry in $OLD_DEVPATH - do - device=`echo "$entry" | sed -e 's/=[^=]*$//'` - path=`echo "$entry" | sed -e 's/^[^=]*=//'` - - if [ "`DevicePath "$device"`" != "$path" ] - then - echo "Device path of $device has changed" >&2 - outdated=1 - fi - done - - for entry in $OLD_DEVNAME - do - device=`echo "$entry" | sed -e 's/=[^=]*$//'` - name=`echo "$entry" | sed -e 's/^[^=]*=//'` - - if [ "`DeviceName "$device"`" != "$name" ] - then - echo "Device name of $device has changed" >&2 - outdated=1 - fi - done - - return $outdated + local OLD_DEVPATH="$1" OLD_DEVNAME="$2" outdated=0 + local entry device name path + + for entry in $OLD_DEVPATH + do + device=`echo "$entry" | sed -e 's/=[^=]*$//'` + path=`echo "$entry" | sed -e 's/^[^=]*=//'` + + if [ "`DevicePath "$device"`" != "$path" ] + then + echo "Device path of $device has changed" >&2 + outdated=1 + fi + done + + for entry in $OLD_DEVNAME + do + device=`echo "$entry" | sed -e 's/=[^=]*$//'` + name=`echo "$entry" | sed -e 's/^[^=]*=//'` + + if [ "`DeviceName "$device"`" != "$name" ] + then + echo "Device name of $device has changed" >&2 + outdated=1 + fi + done + + return $outdated } # Check that all referenced sysfs files exist function CheckFiles { - local outdated=0 fcvcount pwmo tsen fan - - let fcvcount=0 - while (( $fcvcount < ${#AFCPWM[@]} )) # go through all pwm outputs - do - pwmo=${AFCPWM[$fcvcount]} - if [ ! -w $pwmo ] - then - echo "Error: file $pwmo doesn't exist" >&2 - outdated=1 - fi - let fcvcount=$fcvcount+1 - done - - let fcvcount=0 - while (( $fcvcount < ${#AFCTEMP[@]} )) # go through all temp inputs - do - tsen=${AFCTEMP[$fcvcount]} - if [ ! -r $tsen ] - then - echo "Error: file $tsen doesn't exist" >&2 - outdated=1 - fi - let fcvcount=$fcvcount+1 - done - - let fcvcount=0 - while (( $fcvcount < ${#AFCFAN[@]} )) # go through all fan inputs - do - # A given PWM output can control several fans - for fan in $(echo ${AFCFAN[$fcvcount]} | sed -e 's/+/ /') - do - if [ ! -r $fan ] - then - echo "Error: file $fan doesn't exist" >&2 - outdated=1 - fi - done - let fcvcount=$fcvcount+1 - done - - if [ $outdated -eq 1 ] - then - echo >&2 - echo "At least one referenced file is missing. Either some required kernel" >&2 - echo "modules haven't been loaded, or your configuration file is outdated." >&2 - echo "In the latter case, you should run pwmconfig again." >&2 - fi - - return $outdated + local outdated=0 fcvcount pwmo tsen fan + + let fcvcount=0 + while (( $fcvcount < ${#AFCPWM[@]} )) # go through all pwm outputs + do + pwmo=${AFCPWM[$fcvcount]} + if [ ! -w $pwmo ] + then + echo "Error: file $pwmo doesn't exist" >&2 + outdated=1 + fi + let fcvcount=$fcvcount+1 + done + + let fcvcount=0 + while (( $fcvcount < ${#AFCTEMP[@]} )) # go through all temp inputs + do + tsen=${AFCTEMP[$fcvcount]} + if [ ! -r $tsen ] + then + echo "Error: file $tsen doesn't exist" >&2 + outdated=1 + fi + let fcvcount=$fcvcount+1 + done + + let fcvcount=0 + while (( $fcvcount < ${#AFCFAN[@]} )) # go through all fan inputs + do + # A given PWM output can control several fans + for fan in $(echo ${AFCFAN[$fcvcount]} | sed -e 's/+/ /') + do + if [ ! -r $fan ] + then + echo "Error: file $fan doesn't exist" >&2 + outdated=1 + fi + done + let fcvcount=$fcvcount+1 + done + + if [ $outdated -eq 1 ] + then + echo >&2 + echo "At least one referenced file is missing. Either some required kernel" >&2 + echo "modules haven't been loaded, or your configuration file is outdated." >&2 + echo "In the latter case, you should run pwmconfig again." >&2 + fi + + return $outdated } if [ "$1" == "--check" ] then - if [ -f "$2" ] - then - LoadConfig $2 - else - LoadConfig /etc/fancontrol - fi - exit 0 + if [ -f "$2" ] + then + LoadConfig $2 + else + LoadConfig /etc/fancontrol + fi + exit 0 fi if [ -f "$1" ] then - LoadConfig $1 + LoadConfig $1 else - LoadConfig /etc/fancontrol + LoadConfig /etc/fancontrol fi # Detect path to sensors if echo "${AFCPWM[0]}" | egrep -q '^/' then - DIR=/ + DIR=/ elif echo "${AFCPWM[0]}" | egrep -q '^hwmon[0-9]' then - DIR=/sys/class/hwmon + DIR=/sys/class/hwmon elif echo "${AFCPWM[0]}" | egrep -q '^[1-9]*[0-9]-[0-9abcdef]{4}' then - DIR=/sys/bus/i2c/devices + DIR=/sys/bus/i2c/devices else - echo "$0: Invalid path to sensors" >&2 - exit 1 + echo "$0: Invalid path to sensors" >&2 + exit 1 fi if [ ! -d $DIR ] then - echo $0: 'No sensors found! (did you load the necessary modules?)' >&2 - exit 1 + echo $0: 'No sensors found! (did you load the necessary modules?)' >&2 + exit 1 fi cd $DIR @@ -325,94 +331,94 @@ cd $DIR # if [ "$DIR" != "/" ] && [ -z "$DEVPATH" -o -z "$DEVNAME" ] # then # echo "Configuration is too old, please run pwmconfig again" >&2 -# exit 1 +# exit 1 # fi if [ "$DIR" = "/" -a -n "$DEVPATH" ] then - echo "Unneeded DEVPATH with absolute device paths" >&2 - exit 1 + echo "Unneeded DEVPATH with absolute device paths" >&2 + exit 1 fi if ! ValidateDevices "$DEVPATH" "$DEVNAME" then - echo "Configuration appears to be outdated, please run pwmconfig again" >&2 - exit 1 + echo "Configuration appears to be outdated, please run pwmconfig again" >&2 + exit 1 fi CheckFiles || exit 1 if [ -f "$PIDFILE" ] then - echo "File $PIDFILE exists, is fancontrol already running?" >&2 - exit 1 + echo "File $PIDFILE exists, is fancontrol already running?" >&2 + exit 1 fi echo $$ > "$PIDFILE" # $1 = pwm file name function pwmdisable() { - local ENABLE=${1}_enable - - # No enable file? Just set to max - if [ ! -f $ENABLE ] - then - echo $MAX > $1 - return 0 - fi - - # Try pwmN_enable=0 - echo 0 > $ENABLE 2> /dev/null - if [ `cat $ENABLE` -eq 0 ] - then - # Success - echo $MAX > $1 - return 0 - fi - - # It didn't work, try pwmN_enable=1 pwmN=255 - echo 1 > $ENABLE 2> /dev/null - echo $MAX > $1 - if [ `cat $ENABLE` -eq 1 -a `cat $1` -ge 190 ] - then - # Success - return 0 - fi - - # Nothing worked - echo "$ENABLE stuck to" `cat $ENABLE` >&2 - return 1 + local ENABLE=${1}_enable + + # No enable file? Just set to max + if [ ! -f $ENABLE ] + then + echo $MAX > $1 + return 0 + fi + + # Try pwmN_enable=0 + echo 0 > $ENABLE 2> /dev/null + if [ `cat $ENABLE` -eq 0 ] + then + # Success + echo $MAX > $1 + return 0 + fi + + # It didn't work, try pwmN_enable=1 pwmN=255 + echo 1 > $ENABLE 2> /dev/null + echo $MAX > $1 + if [ `cat $ENABLE` -eq 1 -a `cat $1` -ge 190 ] + then + # Success + return 0 + fi + + # Nothing worked + echo "$ENABLE stuck to" `cat $ENABLE` >&2 + return 1 } # $1 = pwm file name function pwmenable() { - local ENABLE=${1}_enable - - if [ -f $ENABLE ] - then - echo 1 > $ENABLE 2> /dev/null - if [ $? -ne 0 ] - then - return 1 - fi - fi - echo $MAX > $1 + local ENABLE=${1}_enable + + if [ -f $ENABLE ] + then + echo 1 > $ENABLE 2> /dev/null + if [ $? -ne 0 ] + then + return 1 + fi + fi + echo $MAX > $1 } function restorefans() { - local status=$1 fcvcount pwmo - - echo 'Aborting, restoring fans...' - let fcvcount=0 - while (( $fcvcount < ${#AFCPWM[@]} )) # go through all pwm outputs - do - pwmo=${AFCPWM[$fcvcount]} - pwmdisable $pwmo - let fcvcount=$fcvcount+1 - done - echo 'Verify fans have returned to full speed' - rm -f "$PIDFILE" - exit $status + local status=$1 fcvcount pwmo + + echo 'Aborting, restoring fans...' + let fcvcount=0 + while (( $fcvcount < ${#AFCPWM[@]} )) # go through all pwm outputs + do + pwmo=${AFCPWM[$fcvcount]} + pwmdisable $pwmo + let fcvcount=$fcvcount+1 + done + echo 'Verify fans have returned to full speed' + rm -f "$PIDFILE" + exit $status } trap 'restorefans 0' SIGQUIT SIGTERM @@ -446,163 +452,154 @@ function lowerBound # main function function UpdateFanSpeeds { - local fcvcount - local pwmo tsens fan mint maxt minsa minso minpwm maxpwm tHyst - local tval pwmpval fanval min_fanval one_fan one_fanval - local -i pwmval - - let fcvcount=0 - while (( $fcvcount < ${#AFCPWM[@]} )) # go through all pwm outputs - do - #hopefully shorter vars will improve readability: - pwmo=${AFCPWM[$fcvcount]} - tsens=${AFCTEMP[$fcvcount]} - fan=${AFCFAN[$fcvcount]} - let mint="${AFCMINTEMP[$fcvcount]}*1000" - let maxt="${AFCMAXTEMP[$fcvcount]}*1000" - minsa=${AFCMINSTART[$fcvcount]} - minso=${AFCMINSTOP[$fcvcount]} - minpwm=${AFCMINPWM[$fcvcount]} - maxpwm=${AFCMAXPWM[$fcvcount]} - let tHyst="${AFCTHYST[$fcvcount]}*1000" - - #if some fan fault detected all pwm=100% - CheckFanFault - if [ $? -ne 0 ] - then - echo $MAX > $pwmo - let fcvcount=$fcvcount+1 - continue - fi - - read tval < ${tsens} - if [ $? -ne 0 ] - then - echo "Error reading temperature from $DIR/$tsens" - restorefans 1 - fi - - read pwmpval < ${pwmo} - if [ $? -ne 0 ] - then - echo "Error reading PWM value from $DIR/$pwmo" - restorefans 1 - fi - - # If fanspeed-sensor output shall be used, do it - if [[ -n ${fan} ]] - then - min_fanval=100000 - fanval= - # A given PWM output can control several fans - for one_fan in $(echo $fan | sed -e 's/+/ /') - do - read one_fanval < ${one_fan} - if [ $? -ne 0 ] - then - echo "Error reading Fan value from $DIR/$one_fan" >&2 - restorefans 1 - fi - - # Remember the minimum, it only matters if it is 0 - if [ $one_fanval -lt $min_fanval ] - then - min_fanval=$one_fanval - fi - - if [ -z "$fanval" ] - then - fanval=$one_fanval - else - fanval="$fanval/$one_fanval" - fi - done - else - fanval=1 # set it to a non zero value, so the rest of the script still works - fi - - # debug info - if [ "$DEBUG" != "" ] - then - echo "pwmo=$pwmo" - echo "tsens=$tsens" - echo "fan=$fan" - echo "mint=$mint" - echo "maxt=$maxt" - echo "minsa=$minsa" - echo "minso=$minso" - echo "minpwm=$minpwm" - echo "maxpwm=$maxpwm" - echo "tval=$tval" - echo "pwmpval=$pwmpval" - echo "fanval=$fanval" - echo "min_fanval=$min_fanval" - echo "tHyst=$tHyst" - fi - pwmval=$pwmpval - if (( $tval+$tHyst <= $mint )) - then pwmval=$minpwm # below min temp, use defined min pwm - elif (( $tval >= $maxt )) - then pwmval=$maxpwm # over max temp, use defined max pwm - elif (( $tval+$tHyst >= $maxt )) && (( $pwmpval == $maxpwm )) - then pwmval=$maxpwm - else - # calculate the new value from temperature and settings - # pwmval="(${tval}-${mint})*(${maxpwm}-${minso})/(${maxt}-${mint})+${minso} - lowerBound ${tval} ${mint} ${maxt} ${minpwm} ${maxpwm} ${tHyst} - lb=$lw_b - upperBound ${tval} ${mint} ${maxt} ${minpwm} ${maxpwm} ${tHyst} - ub=$up_b - - if [ "$DEBUG" != "" ] - then - echo "old pwm=$pwmval lw_b=$lw_b up_b=$up_b" - fi - - if [[ "$pwmval" -gt "$ub" ]] - then - pwmval=$ub - else - if [[ "$pwmval" -lt "$lb" ]] - then - pwmval=$lb - fi - fi - - if [ $pwmpval -eq 0 -o $min_fanval -eq 0 ] - then # if fan was stopped start it using a safe value - echo $minsa > $pwmo - # Sleep while still handling signals - sleep 1 & - wait $! - fi - fi - echo $pwmval > $pwmo # write new value to pwm output - if [ $? -ne 0 ] - then - echo "Error writing PWM value to $DIR/$pwmo" >&2 - restorefans 1 - fi - if [ "$DEBUG" != "" ] - then - echo "new pwmval=$pwmval" - fi - let fcvcount=$fcvcount+1 - done + local fcvcount + local pwmo tsens fan mint maxt minsa minso minpwm maxpwm tHyst + local tval pwmpval fanval min_fanval one_fan one_fanval + local -i pwmval + + let fcvcount=0 + while (( $fcvcount < ${#AFCPWM[@]} )) # go through all pwm outputs + do + #hopefully shorter vars will improve readability: + pwmo=${AFCPWM[$fcvcount]} + tsens=${AFCTEMP[$fcvcount]} + fan=${AFCFAN[$fcvcount]} + let mint="${AFCMINTEMP[$fcvcount]}*1000" + let maxt="${AFCMAXTEMP[$fcvcount]}*1000" + minsa=${AFCMINSTART[$fcvcount]} + minso=${AFCMINSTOP[$fcvcount]} + minpwm=${AFCMINPWM[$fcvcount]} + maxpwm=${AFCMAXPWM[$fcvcount]} + let tHyst="${AFCTHYST[$fcvcount]}*1000" + + read tval < ${tsens} + if [ $? -ne 0 ] + then + echo "Error reading temperature from $DIR/$tsens" + restorefans 1 + fi + + read pwmpval < ${pwmo} + if [ $? -ne 0 ] + then + echo "Error reading PWM value from $DIR/$pwmo" + restorefans 1 + fi + + # If fanspeed-sensor output shall be used, do it + if [[ -n ${fan} ]] + then + min_fanval=100000 + fanval= + # A given PWM output can control several fans + for one_fan in $(echo $fan | sed -e 's/+/ /') + do + read one_fanval < ${one_fan} + if [ $? -ne 0 ] + then + echo "Error reading Fan value from $DIR/$one_fan" >&2 + restorefans 1 + fi + + # Remember the minimum, it only matters if it is 0 + if [ $one_fanval -lt $min_fanval ] + then + min_fanval=$one_fanval + fi + + if [ -z "$fanval" ] + then + fanval=$one_fanval + else + fanval="$fanval/$one_fanval" + fi + done + else + fanval=1 # set it to a non zero value, so the rest of the script still works + fi + + # debug info + if [ "$DEBUG" != "" ] + then + echo "pwmo=$pwmo" + echo "tsens=$tsens" + echo "fan=$fan" + echo "mint=$mint" + echo "maxt=$maxt" + echo "minsa=$minsa" + echo "minso=$minso" + echo "minpwm=$minpwm" + echo "maxpwm=$maxpwm" + echo "tval=$tval" + echo "pwmpval=$pwmpval" + echo "fanval=$fanval" + echo "min_fanval=$min_fanval" + echo "tHyst=$tHyst" + fi + pwmval=$pwmpval + if (( $tval+$tHyst <= $mint )) + then pwmval=$minpwm # below min temp, use defined min pwm + elif (( $tval >= $maxt )) + then pwmval=$maxpwm # over max temp, use defined max pwm + elif (( $tval+$tHyst >= $maxt )) && (( $pwmpval == $maxpwm )) + then pwmval=$maxpwm + else + # calculate the new value from temperature and settings + # pwmval="(${tval}-${mint})*(${maxpwm}-${minso})/(${maxt}-${mint})+${minso} + lowerBound ${tval} ${mint} ${maxt} ${minpwm} ${maxpwm} ${tHyst} + lb=$lw_b + upperBound ${tval} ${mint} ${maxt} ${minpwm} ${maxpwm} ${tHyst} + ub=$up_b + + if [ "$DEBUG" != "" ] + then + echo "old pwm=$pwmval lw_b=$lw_b up_b=$up_b" + fi + + if [[ "$pwmval" -gt "$ub" ]] + then + pwmval=$ub + else + if [[ "$pwmval" -lt "$lb" ]] + then + pwmval=$lb + fi + fi + + if [ $pwmpval -eq 0 -o $min_fanval -eq 0 ] + then # if fan was stopped start it using a safe value + echo $minsa > $pwmo + # Sleep while still handling signals + sleep 1 & + wait + fi + fi + echo $pwmval > $pwmo # write new value to pwm output + if [ $? -ne 0 ] + then + echo "Error writing PWM value to $DIR/$pwmo" >&2 + restorefans 1 + fi + if [ "$DEBUG" != "" ] + then + echo "new pwmval=$pwmval" + fi + let fcvcount=$fcvcount+1 + done } echo 'Enabling PWM on fans...' let fcvcount=0 while (( $fcvcount < ${#AFCPWM[@]} )) # go through all pwm outputs do - pwmo=${AFCPWM[$fcvcount]} - pwmenable $pwmo - if [ $? -ne 0 ] - then - echo "Error enabling PWM on $DIR/$pwmo" >&2 - restorefans 1 - fi - let fcvcount=$fcvcount+1 + pwmo=${AFCPWM[$fcvcount]} + pwmenable $pwmo + if [ $? -ne 0 ] + then + echo "Error enabling PWM on $DIR/$pwmo" >&2 + restorefans 1 + fi + let fcvcount=$fcvcount+1 done echo 'Starting automatic fan control...' @@ -610,8 +607,8 @@ echo 'Starting automatic fan control...' # main loop calling the main function at specified intervals while true do - UpdateFanSpeeds - # Sleep while still handling signals - sleep $INTERVAL & - wait $! -done \ No newline at end of file + UpdateFanSpeeds + # Sleep while still handling signals + sleep $INTERVAL & + wait +done diff --git a/platform/broadcom/sonic-platform-modules-cel/services/platform_api/setup.py b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/setup.py new file mode 100755 index 000000000000..b0c8d1d8c9b8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/setup.py @@ -0,0 +1,30 @@ +from setuptools import setup + +setup( + name='sonic-platform', + version='1.0', + description='SONiC platform API implementation on Celestica Platforms', + license='Apache 2.0', + author='SONiC Team', + author_email='linuxnetdev@microsoft.com', + url='https://github.com/Azure/sonic-buildimage', + maintainer='Wirut Getbamrung', + maintainer_email='wgetbumr@celestica.com', + packages=[ + 'sonic_platform', + ], + classifiers=[ + 'Development Status :: 3 - Alpha', + 'Environment :: Plugins', + 'Intended Audience :: Developers', + 'Intended Audience :: Information Technology', + 'Intended Audience :: System Administrators', + 'License :: OSI Approved :: Apache Software License', + 'Natural Language :: English', + 'Operating System :: POSIX :: Linux', + 'Programming Language :: Python :: 2.7', + 'Topic :: Utilities', + ], + keywords='sonic SONiC platform PLATFORM', +) + diff --git a/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/__init__.py new file mode 100644 index 000000000000..7b86fa12b515 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/__init__.py @@ -0,0 +1,2 @@ +import chassis +import platform diff --git a/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/chassis.py new file mode 100644 index 000000000000..aa7671484889 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/chassis.py @@ -0,0 +1,317 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Chassis information which are available in the platform +# +############################################################################# + +try: + import sys + from sonic_platform_base.chassis_base import ChassisBase + from common import Common +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Chassis(ChassisBase): + """Platform-specific Chassis class""" + + CHASSIS_CONFIG = 'chassis.json' + THERMAL_CONFIG = 'thermal.json' + SFP_CONFIG = 'sfp.json' + PSU_CONFIG = 'psu.json' + FAN_CONFIG = 'fan.json' + COMPONENT_CONFIG = 'component.json' + + def __init__(self): + ChassisBase.__init__(self) + self._api_common = Common() + config_path = self._api_common.get_config_path(self.CHASSIS_CONFIG) + self._config = self._api_common.load_json_file(config_path) + + self.sfp_module_initialized = False + self.__initialize_eeprom() + + if not self._api_common.is_host(): + self.__initialize_fan() + self.__initialize_psu() + self.__initialize_thermals() + else: + self.__initialize_components() + + def __initialize_fan(self): + from sonic_platform.fan import Fan + from sonic_platform.fan_drawer import FanDrawer + + fan_config_path = self._api_common.get_config_path(self.FAN_CONFIG) + self._fan_config = self._api_common.load_json_file(fan_config_path) + + if self._fan_config: + fan_index = 0 + for drawer_index in range(0, self._fan_config['drawer_num']): + drawer_fan_list = [] + for index in range(0, self._fan_config['fan_num_per_drawer']): + fan = Fan(fan_index, conf=self._fan_config) + fan_index += 1 + self._fan_list.append(fan) + drawer_fan_list.append(fan) + fan_drawer = FanDrawer(drawer_index, drawer_fan_list) + self._fan_drawer_list.append(fan_drawer) + + def __initialize_sfp(self): + from sonic_platform.sfp import Sfp + + sfp_config_path = self._api_common.get_config_path(self.SFP_CONFIG) + sfp_config = self._api_common.load_json_file(sfp_config_path) + + sfp_index = 0 + for index in range(0, sfp_config['port_num']): + sfp = Sfp(sfp_index, conf=sfp_config) + self._sfp_list.append(sfp) + sfp_index += 1 + self.sfp_module_initialized = True + + def __initialize_psu(self): + from sonic_platform.psu import Psu + + psu_config_path = self._api_common.get_config_path(self.PSU_CONFIG) + psu_config = self._api_common.load_json_file(psu_config_path) + + if psu_config: + psu_index = 0 + for index in range(0, psu_config['psu_num']): + psu = Psu(psu_index, conf=psu_config, + fan_conf=self._fan_config) + psu_index += 1 + self._psu_list.append(psu) + + def __initialize_thermals(self): + from sonic_platform.thermal import Thermal + + thermal_config_path = self._api_common.get_config_path( + self.THERMAL_CONFIG) + thermal_config = self._api_common.load_json_file(thermal_config_path) + + thermal_index = 0 + for index in range(0, thermal_config['thermal_num']): + thermal = Thermal(thermal_index, conf=thermal_config) + thermal_index += 1 + self._thermal_list.append(thermal) + + def __initialize_eeprom(self): + from sonic_platform.eeprom import Tlv + self._eeprom = Tlv(self._config) + + def __initialize_components(self): + from component import Component + + component_config_path = self._api_common.get_config_path( + self.COMPONENT_CONFIG) + component_config = self._api_common.load_json_file( + component_config_path) + + for index in range(0, component_config['component_num']): + component = Component(index, conf=component_config) + self._component_list.append(component) + + def get_base_mac(self): + """ + Retrieves the base MAC address for the chassis + Returns: + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' + """ + return self._eeprom.get_mac() + + def get_system_eeprom_info(self): + """ + Retrieves the full content of system EEPROM information for the chassis + Returns: + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their corresponding + values. + """ + return self._eeprom.get_eeprom() + + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + Returns: + A tuple (string, string) where the first element is a string + containing the cause of the previous reboot. This string must be + one of the predefined strings in this class. If the first string + is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used + to pass a description of the reboot cause. + + Avaliable reboot cause: + REBOOT_CAUSE_POWER_LOSS = "Power Loss" + REBOOT_CAUSE_THERMAL_OVERLOAD_CPU = "Thermal Overload: CPU" + REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC = "Thermal Overload: ASIC" + REBOOT_CAUSE_THERMAL_OVERLOAD_OTHER = "Thermal Overload: Other" + REBOOT_CAUSE_INSUFFICIENT_FAN_SPEED = "Insufficient Fan Speed" + REBOOT_CAUSE_WATCHDOG = "Watchdog" + REBOOT_CAUSE_HARDWARE_OTHER = "Hardware - Other" + REBOOT_CAUSE_NON_HARDWARE = "Non-Hardware" + + """ + reboot_cause = self._api_common.get_output( + 0, self._config['get_reboot_cause'], self.REBOOT_CAUSE_HARDWARE_OTHER) + description = self._api_common.get_output( + 0, self._config['get_reboot_description'], 'Unknown') + + return (reboot_cause, description) + + # ############################################################## + # ######################## SFP methods ######################### + # ############################################################## + + def get_num_sfps(self): + """ + Retrieves the number of sfps available on this chassis + Returns: + An integer, the number of sfps available on this chassis + """ + if not self.sfp_module_initialized: + self.__initialize_sfp() + + return len(self._sfp_list) + + def get_all_sfps(self): + """ + Retrieves all sfps available on this chassis + Returns: + A list of objects derived from SfpBase representing all sfps + available on this chassis + """ + if not self.sfp_module_initialized: + self.__initialize_sfp() + + return self._sfp_list + + 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, 1 for Ethernet0, 2 for Ethernet4 and so on. + Returns: + An object dervied from SfpBase representing the specified sfp + """ + sfp = None + if not self.sfp_module_initialized: + self.__initialize_sfp() + + try: + # The index will start from 1 + sfp = self._sfp_list[index-1] + except IndexError: + sys.stderr.write("SFP index {} out of range (1-{})\n".format( + index, len(self._sfp_list))) + return sfp + + ############################################################## + ###################### Event methods ######################### + ############################################################## + + def get_change_event(self, timeout=0): + """ + Returns a nested dictionary containing all devices which have + experienced a change at chassis level + Args: + timeout: Timeout in milliseconds (optional). If timeout == 0, + this method will block until a change is detected. + Returns: + (bool, dict): + - True if call successful, False if not; + - A nested dictionary where key is a device type, + value is a dictionary with key:value pairs in the format of + {'device_id':'device_event'}, + where device_id is the device ID for this device and + device_event, + status='1' represents device inserted, + status='0' represents device removed. + Ex. {'fan':{'0':'0', '2':'1'}, 'sfp':{'11':'0'}} + indicates that fan 0 has been removed, fan 2 + has been inserted and sfp 11 has been removed. + Specifically for SFP event, besides SFP plug in and plug out, + there are some other error event could be raised from SFP, when + these error happened, SFP eeprom will not be avalaible, XCVRD shall + stop to read eeprom before SFP recovered from error status. + status='2' I2C bus stuck, + status='3' Bad eeprom, + status='4' Unsupported cable, + status='5' High Temperature, + status='6' Bad cable. + """ + + if not self.sfp_module_initialized: + self.__initialize_sfp() + + return self._api_common.get_event(timeout, self._config['get_change_event'], self._sfp_list) + + # ############################################################## + # ###################### Other methods ######################## + # ############################################################## + + 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: + wdt = self._api_common.get_output( + 0, self._config['get_watchdog'], None) + self._watchdog = wdt() + + return self._watchdog + + # ############################################################## + # ###################### Device methods ######################## + # ############################################################## + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + return self._api_common.hwsku + + def get_presence(self): + """ + Retrieves the presence of the PSU + Returns: + bool: True if PSU is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + return self._eeprom.get_pn() + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + return self._eeprom.get_serial() + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return True diff --git a/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/common.py b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/common.py new file mode 100644 index 000000000000..697308b8c3cf --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/common.py @@ -0,0 +1,283 @@ +import os +import imp +import yaml +import subprocess + +from sonic_py_common import device_info + + +class Common: + + DEVICE_PATH = '/usr/share/sonic/device/' + PMON_PLATFORM_PATH = '/usr/share/sonic/platform/' + CONFIG_DIR = 'sonic_platform_config' + + OUTPUT_SOURCE_IPMI = 'ipmitool' + OUTPUT_SOURCE_GIVEN_LIST = 'value_list' + OUTPUT_SOURCE_GIVEN_VALUE = 'value' + OUTPUT_SOURCE_GIVEN_CLASS = 'class' + OUTPUT_SOURCE_SYSFS = 'sysfs_value' + OUTPUT_SOURCE_FUNC = 'function' + OUTPUT_SOURCE_GIVEN_TXT_FILE = 'txt_file' + OUTPUT_SOURCE_GIVEN_VER_HEX_FILE = 'hex_version_file' + OUTPUT_SOURCE_GIVEN_VER_HEX_ADDR = 'hex_version_getreg' + + SET_METHOD_IPMI = 'ipmitool' + NULL_VAL = 'N/A' + HOST_CHK_CMD = "docker > /dev/null 2>&1" + REF_KEY = '$ref:' + + def __init__(self, conf=None): + self._main_conf = conf + (self.platform, self.hwsku) = device_info.get_platform_and_hwsku() + + def _run_command(self, command): + status = False + output = "" + try: + p = subprocess.Popen( + command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err == '': + status, output = True, raw_data.strip() + except Exception: + pass + return status, output + + def _clean_input(self, input, config): + cleaned_input = input + + ai = config.get('avaliable_input') + if ai and input not in ai: + return None + + input_translator = config.get('input_translator') + if type(input_translator) is dict: + cleaned_input = input_translator.get(input) + + elif type(input_translator) is str: + cleaned_input = eval(input_translator.format(input)) + + return cleaned_input + + def _clean_output(self, index, output, config): + output_translator = config.get('output_translator') + + if type(output_translator) is dict: + output = output_translator.get(output) + elif type(output_translator) is str: + output = eval(output_translator.format(output)) + elif type(output_translator) is list: + output = eval(output_translator[index].format(output)) + + return output + + def _ipmi_get(self, index, config): + argument = config.get('argument') + cmd = config['command'].format( + config['argument'][index]) if argument else config['command'] + status, output = self._run_command(cmd) + return output if status else None + + def _sysfs_read(self, index, config): + sysfs_path = config.get('sysfs_path') + argument = config.get('argument', '') + + if self.REF_KEY in argument: + argument = self._main_conf[argument.split(":")[1]] + + if type(argument) is list: + sysfs_path = sysfs_path.format(argument[index]) + + content = "" + try: + content = open(sysfs_path) + content = content.readline().rstrip() + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + return content + + def _sysfs_write(self, index, config, input): + sysfs_path = config.get('sysfs_path') + argument = config.get('argument', '') + + if self.REF_KEY in argument: + argument = self._main_conf[argument.split(":")[1]] + + if type(argument) is list: + sysfs_path = sysfs_path.format(argument[index]) + + write_offset = int(config.get('write_offset', 0)) + output = "" + try: + open_file = open(sysfs_path, "r+") + open_file.seek(write_offset) + open_file.write(input) + open_file.close() + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False, output + return True, output + + def _ipmi_set(self, index, config, input): + arg = config['argument'][index].format(input) + return self._run_command(config['command'].format(arg)) + + def _hex_ver_decode(self, hver, num_of_bits, num_of_points): + ver_list = [] + c_bit = 0 + bin_val = bin(int(hver, 16))[2:].zfill(num_of_bits) + bit_split = num_of_bits / (num_of_points + 1) + for x in range(0, num_of_points+1): + split_bin = bin_val[c_bit:c_bit+bit_split] + ver_list.append(str(int(split_bin, 2))) + c_bit += bit_split + return '.'.join(ver_list) + + def _get_class(self, config): + """ + Retreives value of expected attribute + Returns: + A value of the attribute of object + """ + path = config['host_path'] if self.is_host() else config['pmon_path'] + module = imp.load_source(config['class'], path) + class_ = getattr(module, config['class']) + return class_ + + def get_reg(self, path, reg_addr): + cmd = "echo {1} > {0}; cat {0}".format(path, reg_addr) + status, output = self._run_command(cmd) + return output if status else None + + def read_txt_file(self, path): + with open(path, 'r') as f: + output = f.readline() + return output.strip('\n') + + def write_txt_file(self, file_path, value): + try: + with open(file_path, 'w') as fd: + fd.write(str(value)) + except Exception: + return False + return True + + def is_host(self): + return os.system(self.HOST_CHK_CMD) == 0 + + def load_json_file(self, path): + """ + Retrieves the json object from json file path + + Returns: + A json object + """ + with open(path, 'r') as f: + json_data = yaml.safe_load(f) + + return json_data + + def get_config_path(self, config_name): + """ + Retrieves the path to platform api config directory + + Args: + config_name: A string containing the name of config file. + + Returns: + A string containing the path to json file + """ + return os.path.join(self.DEVICE_PATH, self.platform, self.CONFIG_DIR, config_name) if self.is_host() else os.path.join(self.PMON_PLATFORM_PATH, self.CONFIG_DIR, config_name) + + def get_output(self, index, config, default): + """ + Retrieves the output for each function base on config + + Args: + index: An integer containing the index of device. + config: A dict object containing the configuration of specified function. + default: A string containing the default output of specified function. + + Returns: + A string containing the output of specified function in config + """ + output_source = config.get('output_source') + + if output_source == self.OUTPUT_SOURCE_IPMI: + output = self._ipmi_get(index, config) + + elif output_source == self.OUTPUT_SOURCE_GIVEN_VALUE: + output = config["value"] + + elif output_source == self.OUTPUT_SOURCE_GIVEN_CLASS: + output = self._get_class(config) + + elif output_source == self.OUTPUT_SOURCE_GIVEN_LIST: + output = config["value_list"][index] + + elif output_source == self.OUTPUT_SOURCE_SYSFS: + output = self._sysfs_read(index, config) + + elif output_source == self.OUTPUT_SOURCE_FUNC: + func_conf = self._main_conf[config['function'][index]] + output = self.get_output(index, func_conf, default) + + elif output_source == self.OUTPUT_SOURCE_GIVEN_TXT_FILE: + path = config.get('path') + output = self.read_txt_file(path) + + elif output_source == self.OUTPUT_SOURCE_GIVEN_VER_HEX_FILE: + path = config.get('path') + hex_ver = self.read_txt_file(path) + output = self._hex_ver_decode( + hex_ver, config['num_of_bits'], config['num_of_points']) + + elif output_source == self.OUTPUT_SOURCE_GIVEN_VER_HEX_ADDR: + path = config.get('path') + addr = config.get('reg_addr') + hex_ver = self.get_reg(path, addr) + output = self._hex_ver_decode( + hex_ver, config['num_of_bits'], config['num_of_points']) + + else: + output = default + + return self._clean_output(index, output, config) or default + + def set_output(self, index, input, config): + """ + Sets the output of specified function on config + + Args: + config: A dict object containing the configuration of specified function. + index: An integer containing the index of device. + input: A string containing the input of specified function. + + Returns: + bool: True if set function is successfully, False if not + """ + cleaned_input = self._clean_input(input, config) + if not cleaned_input: + return False + + set_method = config.get('set_method') + if set_method == self.SET_METHOD_IPMI: + output = self._ipmi_set(index, config, cleaned_input)[0] + elif set_method == self.OUTPUT_SOURCE_SYSFS: + output = self._sysfs_write(index, config, cleaned_input)[0] + else: + output = False + + return output + + def get_event(self, timeout, config, sfp_list): + """ + Returns a nested dictionary containing all devices which have + experienced a change at chassis level + + """ + event_class = self._get_class(config) + return event_class(sfp_list).get_event(timeout) diff --git a/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/component.py new file mode 100644 index 000000000000..958b34623222 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/component.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Component contains an implementation of SONiC Platform Base API and +# provides the components firmware management function +# +############################################################################# + +try: + from sonic_platform_base.component_base import ComponentBase + from common import Common +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Component(ComponentBase): + """Platform-specific Component class""" + + def __init__(self, component_index, conf): + ComponentBase.__init__(self) + + self._index = component_index + self._config = conf + self._api_common = Common(self._config) + + def get_name(self): + """ + Retrieves the name of the component + Returns: + A string containing the name of the component + """ + default = 'N/A' + config = self._config["get_name"] + return self._api_common.get_output(self._index, config, default) + + def get_description(self): + """ + Retrieves the description of the component + Returns: + A string containing the description of the component + """ + default = 'N/A' + config = self._config["get_description"] + return self._api_common.get_output(self._index, config, default) + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + Note: the firmware version will be read from HW + Returns: + A string containing the firmware version of the component + """ + default = 'N/A' + config = self._config["get_firmware_version"] + return self._api_common.get_output(self._index, config, default) diff --git a/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/eeprom.py new file mode 100644 index 000000000000..7756c0f2f839 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/eeprom.py @@ -0,0 +1,113 @@ +############################################################################# +# Celestica +# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# + +try: + import os + import sys + import re + + if sys.version_info.major == 3: + from io import StringIO + else: + from cStringIO import StringIO + + from sonic_platform_base.sonic_eeprom import eeprom_tlvinfo +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +CACHE_ROOT = '/var/cache/sonic/decode-syseeprom' +CACHE_FILE = 'syseeprom_cache' + + +class Tlv(eeprom_tlvinfo.TlvInfoDecoder): + + EEPROM_DECODE_HEADLINES = 6 + DEFAULT_EEPROM_PATH = "/sys/class/i2c-adapter/i2c-12/12-0050/eeprom" + + def __init__(self, conf=None): + eeprom_path = conf.get('eeprom', self.DEFAULT_EEPROM_PATH) + super(Tlv, self).__init__(eeprom_path, 0, '', True) + + self._eeprom = self._load_eeprom() + + def _parse_output(self, decode_output): + decode_output.replace('\0', '') + lines = decode_output.split('\n') + lines = lines[self.EEPROM_DECODE_HEADLINES:] + _eeprom_info_dict = dict() + + for line in lines: + try: + match = re.search( + '(0x[0-9a-fA-F]{2})([\s]+[\S]+[\s]+)([\S]+)', line) + if match is not None: + idx = match.group(1) + value = match.group(3).rstrip('\0') + + _eeprom_info_dict[idx] = value + except Exception: + pass + return _eeprom_info_dict + + def _load_eeprom(self): + original_stdout = sys.stdout + sys.stdout = StringIO() + try: + self.read_eeprom_db() + except Exception: + decode_output = sys.stdout.getvalue() + sys.stdout = original_stdout + return self._parse_output(decode_output) + + status = self.check_status() + if 'ok' not in status: + return False + + if not os.path.exists(CACHE_ROOT): + try: + os.makedirs(CACHE_ROOT) + except Exception: + pass + + # + # only the eeprom classes that inherit from eeprom_base + # support caching. Others will work normally + # + try: + self.set_cache_name(os.path.join(CACHE_ROOT, CACHE_FILE)) + except Exception: + pass + + e = self.read_eeprom() + if e is None: + return 0 + + try: + self.update_cache(e) + except Exception: + pass + + self.decode_eeprom(e) + decode_output = sys.stdout.getvalue() + sys.stdout = original_stdout + + # (is_valid, valid_crc) = self.is_checksum_valid(e) + # if not is_valid: + # return False + + return self._parse_output(decode_output) + + def get_eeprom(self): + return self._eeprom + + def get_serial(self): + return self._eeprom.get('0x23', "Undefined.") + + def get_mac(self): + return self._eeprom.get('0x24', "Undefined.") diff --git a/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/fan.py new file mode 100644 index 000000000000..b0ebebccd3d7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/fan.py @@ -0,0 +1,193 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the fan status which are available in the platform +# +############################################################################# + +try: + from sonic_platform_base.fan_base import FanBase + from common import Common +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Fan(FanBase): + """Platform-specific Fan class""" + + def __init__(self, index, is_psu_fan=False, psu_index=0, conf=None): + FanBase.__init__(self) + + self._fan_index = index + self._config = conf + self._api_common = Common() + + self._is_psu_fan = is_psu_fan + if self._is_psu_fan: + self._initialize_psu_fan(psu_index) + + self._name = self.get_name() + + def _initialize_psu_fan(self, psu_index): + self._psu_index = psu_index + self._psu_fan_config = self._config['psu_fan'][self._psu_index] + + def get_direction(self): + """ + Retrieves the direction of fan + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + """ + return self._api_common.get_output(self._fan_index, self._config['get_direction'], self.FAN_DIRECTION_NOT_APPLICABLE) + + def get_speed(self): + """ + Retrieves the speed of fan as a percentage of full speed + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + + Note: + speed = pwm_in/255*100 + """ + config = self._config['get_speed'] if not self._is_psu_fan else self._psu_fan_config['get_speed'] + max_rpm = config['max_rear'] if 'R' in self._name else config['max_front'] + raw_speed = self._api_common.get_output( + self._fan_index, config, 0) + + return int(float(raw_speed) / max_rpm * 100.0) + + def get_target_speed(self): + """ + Retrieves the target (expected) speed of the fan + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + + Note: + 0 : when PWM mode is not in use + pwm : when pwm mode is not use + """ + return self._api_common.get_output(self._fan_index, self._config['get_target_speed'], Common.NULL_VAL) + + def get_speed_tolerance(self): + """ + Retrieves the speed tolerance of the fan + Returns: + An integer, the percentage of variance from target speed which is + considered tolerable + """ + return self._api_common.get_output(self._fan_index, self._config['get_speed_tolerance'], Common.NULL_VAL) + + def set_speed(self, speed): + """ + Sets the fan speed + Args: + speed: An integer, the percentage of full fan speed to set fan to, + in the range 0 (off) to 100 (full speed) + Returns: + A boolean, True if speed is set successfully, False if not + + Note: + Depends on pwm or target mode is selected: + 1) pwm = speed_pc * 255 <-- Currently use this mode. + 2) target_pwm = speed_pc * 100 / 255 + 2.1) set pwm{}_enable to 3 + + ipmitool raw 0x3a 0x0e 0x00 > enable auto fcs + ipmitool raw 0x3a 0x0e 0x01 > disable auto fcs + """ + if speed not in range(1, 101) or self._is_psu_fan: + return False + + return self._api_common.set_output(self._fan_index, speed, self._config['set_speed']) + + def set_status_led(self, color): + """ + Sets the state of the fan module status LED + Args: + color: A string representing the color with which to set the + fan module status LED + Returns: + bool: True if status LED state is set successfully, False if not + + + Note: Required Manual Control LED mode ('ipmitool raw 0x3a 0x0f 0x2 0x0') + """ + config = self._config['set_status_led'] + avaliable_input = config.get('avaliable_input') + if (avaliable_input and color not in avaliable_input) or self._is_psu_fan: + return False + + return self._api_common.set_output(self._fan_index, color, config) + + def get_status_led(self): + """ + Gets the state of the fan status LED + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + + Note: + STATUS_LED_COLOR_GREEN = "green" + STATUS_LED_COLOR_AMBER = "amber" + STATUS_LED_COLOR_RED = "red" + STATUS_LED_COLOR_OFF = "off" + """ + + default = self.STATUS_LED_COLOR_OFF + + if self._is_psu_fan: + return default + + return self._api_common.get_output(self._fan_index, self._config['get_status_led'], default) + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + config = self._config['get_name'] if not self._is_psu_fan else self._psu_fan_config['get_name'] + return self._api_common.get_output(self._fan_index, config, Common.NULL_VAL) + + def get_presence(self): + """ + Retrieves the presence of the FAN + Returns: + bool: True if FAN is present, False if not + """ + return self._api_common.get_output(self._fan_index, self._config['get_presence'], False) + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + default = Common.NULL_VAL + if self._is_psu_fan: + return default + return self._api_common.get_output(self._fan_index, self._config['get_model'], default) + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + default = Common.NULL_VAL + if self._is_psu_fan: + return default + return self._api_common.get_output(self._fan_index, self._config['get_serial'], default) + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self.get_presence() and self.get_speed() > 10 diff --git a/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/fan_drawer.py new file mode 100644 index 000000000000..5ef283a105d4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/fan_drawer.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the fan status which are available in the platform +# +############################################################################# + +try: + from sonic_platform_base.fan_drawer_base import FanDrawerBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class FanDrawer(FanDrawerBase): + + def __init__(self, index, fan_list): + FanDrawerBase.__init__(self) + + self._fan_list = fan_list + self._index = index + 1 + + def set_status_led(self, color): + """ + Sets the state of the fan drawer status LED + Args: + color: A string representing the color with which to set the + fan drawer status LED + Returns: + bool: True if status LED state is set successfully, False if not + """ + return self._fan_list[0].set_status_led(color) + + def get_status_led(self, color): + """ + Gets the state of the fan drawer LED + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + return self._fan_list[0].get_status_led() + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + return 'Fan {}'.format(self._index) + + def get_presence(self): + """ + Retrieves the presence of the FAN + Returns: + bool: True if FAN is present, False if not + """ + return self._fan_list[0].get_presence() + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + return self._fan_list[0].get_model() + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + return self._fan_list[0].get_serial() + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self._fan_list[0].get_status() diff --git a/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/platform.py new file mode 100644 index 000000000000..a632de87e742 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/platform.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PlatformBase): + """Platform-specific Platform class""" + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() diff --git a/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/psu.py new file mode 100644 index 000000000000..68dfe201d33f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/psu.py @@ -0,0 +1,182 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the psu status which are available in the platform +# +############################################################################# + +try: + from sonic_platform_base.psu_base import PsuBase + from common import Common +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Psu(PsuBase): + """Platform-specific Fan class""" + + def __init__(self, index, conf=None, fan_conf=None): + PsuBase.__init__(self) + + self._psu_index = index + self._config = conf + self._api_common = Common(self._config) + self._fan_conf = fan_conf + self._initialize_psu_fan() + + def _initialize_psu_fan(self): + from sonic_platform.fan import Fan + + num_fan = self._fan_conf['psu_fan'][self._psu_index]["num_of_fan"] + for fan_index in range(0, num_fan): + fan = Fan(fan_index, is_psu_fan=True, + psu_index=self._psu_index, conf=self._fan_conf) + self._fan_list.append(fan) + + def get_voltage(self): + """ + Retrieves current PSU voltage output + + Returns: + A float number, the output voltage in volts, + e.g. 12.1 + """ + return self._api_common.get_output(self._psu_index, self._config['get_voltage'], 0.0) + + def get_current(self): + """ + Retrieves present electric current supplied by PSU + + Returns: + A float number, the electric current in amperes, e.g 15.4 + """ + return self._api_common.get_output(self._psu_index, self._config['get_current'], 0.0) + + def get_power(self): + """ + Retrieves current energy supplied by PSU + + Returns: + A float number, the power in watts, e.g. 302.6 + """ + return self._api_common.get_output(self._psu_index, self._config['get_current'], 0.0) + + def get_powergood_status(self): + """ + Retrieves the powergood status of PSU + + Returns: + A boolean, True if PSU has stablized its output voltages and passed all + its internal self-tests, False if not. + """ + return self._api_common.get_output(self._psu_index, self._config['get_powergood_status'], False) + + def set_status_led(self, color): + """ + Sets the state of the PSU status LED + Note: + Seastone2 CPLD able to set only AMBER color. + This function should be disable auto mode before execute + command: ipmitool raw 0x3a 0x0f 0x02 0x00 + Args: + color: A string representing the color with which to set the + PSU status LED + + Returns: + bool: True if status LED state is set successfully, False if not + """ + return self._api_common.set_output(self._psu_index, color, self._config['set_status_led']) + + def get_status_led(self): + """ + Gets the state of the PSU status LED + Note: + Seastone2 PSU LED got only 2 mode, AMBER and Hardware control mode. + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + return self._api_common.get_output(self._psu_index, self._config['get_status_led'], Common.NULL_VAL) + + def get_temperature(self): + """ + Retrieves current temperature reading from PSU + + Returns: + A float number of current temperature in Celsius up to nearest thousandth + of one degree Celsius, e.g. 30.125 + """ + return self._api_common.get_output(self._psu_index, self._config['get_temperature'], 0.0) + + def get_temperature_high_threshold(self): + """ + Retrieves the high threshold temperature of PSU + Returns: + A float number, the high threshold temperature of PSU in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + return self._api_common.get_output(self._psu_index, self._config['get_temperature_high_threshold'], 0.0) + + def get_voltage_high_threshold(self): + """ + Retrieves the high threshold PSU voltage output + + Returns: + ucr as float number and return 0 if the BMC output is na. + A float number, the high threshold output voltage in volts, + e.g. 12.1 + """ + return self._api_common.get_output(self._psu_index, self._config['get_voltage_high_threshold'], 0.0) + + def get_voltage_low_threshold(self): + """ + Retrieves the low threshold PSU voltage output + + Returns: + lcr as float number and return 0 if the BMC output is na. + A float number, the low threshold output voltage in volts, + e.g. 12.1 + """ + return self._api_common.get_output(self._psu_index, self._config['get_voltage_low_threshold'], 0.0) + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + return self._api_common.get_output(self._psu_index, self._config['get_name'], Common.NULL_VAL) + + def get_presence(self): + """ + Retrieves the presence of the PSU + Returns: + bool: True if PSU is present, False if not + """ + return self._api_common.get_output(self._psu_index, self._config['get_name'], False) + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + return self._api_common.get_output(self._psu_index, self._config['get_model'], Common.NULL_VAL) + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + return self._api_common.get_output(self._psu_index, self._config['get_serial'], Common.NULL_VAL) + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self.get_powergood_status() diff --git a/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/sfp.py new file mode 100644 index 000000000000..07eac37d8d82 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/sfp.py @@ -0,0 +1,2037 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the sfp status which are available in the platform +# +############################################################################# + +import time +from ctypes import create_string_buffer + +try: + from sonic_platform_base.sfp_base import SfpBase + from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom + from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom + from sonic_platform_base.sonic_sfp.inf8628 import inf8628InterfaceId + from sonic_platform_base.sonic_sfp.qsfp_dd import qsfp_dd_InterfaceId + from sonic_platform_base.sonic_sfp.qsfp_dd import qsfp_dd_Dom + from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper + from common import Common +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +# definitions of the offset and width for values in XCVR info eeprom +XCVR_INTFACE_BULK_OFFSET = 0 +XCVR_INTFACE_BULK_WIDTH_QSFP = 20 +XCVR_INTFACE_BULK_WIDTH_SFP = 21 +XCVR_TYPE_OFFSET = 0 +XCVR_TYPE_WIDTH = 1 +XCVR_EXT_TYPE_OFFSET = 1 +XCVR_EXT_TYPE_WIDTH = 1 +XCVR_CONNECTOR_OFFSET = 2 +XCVR_CONNECTOR_WIDTH = 1 +XCVR_COMPLIANCE_CODE_OFFSET = 3 +XCVR_COMPLIANCE_CODE_WIDTH = 8 +XCVR_ENCODING_OFFSET = 11 +XCVR_ENCODING_WIDTH = 1 +XCVR_NBR_OFFSET = 12 +XCVR_NBR_WIDTH = 1 +XCVR_EXT_RATE_SEL_OFFSET = 13 +XCVR_EXT_RATE_SEL_WIDTH = 1 +XCVR_CABLE_LENGTH_OFFSET = 14 +XCVR_CABLE_LENGTH_WIDTH_QSFP = 5 +XCVR_CABLE_LENGTH_WIDTH_SFP = 6 +XCVR_VENDOR_NAME_OFFSET = 20 +XCVR_VENDOR_NAME_WIDTH = 16 +XCVR_VENDOR_OUI_OFFSET = 37 +XCVR_VENDOR_OUI_WIDTH = 3 +XCVR_VENDOR_PN_OFFSET = 40 +XCVR_VENDOR_PN_WIDTH = 16 +XCVR_HW_REV_OFFSET = 56 +XCVR_HW_REV_WIDTH_OSFP = 2 +XCVR_HW_REV_WIDTH_QSFP = 2 +XCVR_HW_REV_WIDTH_SFP = 4 +XCVR_EXT_SPECIFICATION_COMPLIANCE_OFFSET = 64 +XCVR_EXT_SPECIFICATION_COMPLIANCE_WIDTH = 1 +XCVR_VENDOR_SN_OFFSET = 68 +XCVR_VENDOR_SN_WIDTH = 16 +XCVR_VENDOR_DATE_OFFSET = 84 +XCVR_VENDOR_DATE_WIDTH = 8 +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 2 + +XCVR_INTERFACE_DATA_START = 0 +XCVR_INTERFACE_DATA_SIZE = 92 + +QSFP_DOM_BULK_DATA_START = 22 +QSFP_DOM_BULK_DATA_SIZE = 36 +SFP_DOM_BULK_DATA_START = 96 +SFP_DOM_BULK_DATA_SIZE = 10 +QSFP_DD_DOM_BULK_DATA_START = 14 +QSFP_DD_DOM_BULK_DATA_SIZE = 4 + +# definitions of the offset for values in OSFP info eeprom +OSFP_TYPE_OFFSET = 0 +OSFP_VENDOR_NAME_OFFSET = 129 +OSFP_VENDOR_PN_OFFSET = 148 +OSFP_HW_REV_OFFSET = 164 +OSFP_VENDOR_SN_OFFSET = 166 + +# definitions of the offset for values in QSFP_DD info eeprom +QSFP_DD_TYPE_OFFSET = 0 +QSFP_DD_VENDOR_NAME_OFFSET = 1 +QSFP_DD_VENDOR_PN_OFFSET = 20 +QSFP_DD_VENDOR_SN_OFFSET = 38 +QSFP_DD_VENDOR_OUI_OFFSET = 17 + +# definitions of the offset and width for values in XCVR_QSFP_DD info eeprom +XCVR_EXT_TYPE_OFFSET_QSFP_DD = 72 +XCVR_EXT_TYPE_WIDTH_QSFP_DD = 2 +XCVR_CONNECTOR_OFFSET_QSFP_DD = 75 +XCVR_CONNECTOR_WIDTH_QSFP_DD = 1 +XCVR_CABLE_LENGTH_OFFSET_QSFP_DD = 74 +XCVR_CABLE_LENGTH_WIDTH_QSFP_DD = 1 +XCVR_HW_REV_OFFSET_QSFP_DD = 36 +XCVR_HW_REV_WIDTH_QSFP_DD = 2 +XCVR_VENDOR_DATE_OFFSET_QSFP_DD = 54 +XCVR_VENDOR_DATE_WIDTH_QSFP_DD = 8 +XCVR_DOM_CAPABILITY_OFFSET_QSFP_DD = 2 +XCVR_DOM_CAPABILITY_WIDTH_QSFP_DD = 1 +XCVR_MEDIA_TYPE_OFFSET_QSFP_DD = 85 +XCVR_MEDIA_TYPE_WIDTH_QSFP_DD = 1 +XCVR_FIRST_APPLICATION_LIST_OFFSET_QSFP_DD = 86 +XCVR_FIRST_APPLICATION_LIST_WIDTH_QSFP_DD = 32 +XCVR_SECOND_APPLICATION_LIST_OFFSET_QSFP_DD = 351 +XCVR_SECOND_APPLICATION_LIST_WIDTH_QSFP_DD = 28 + +# Offset for values in QSFP eeprom +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_VERSION_COMPLIANCE_OFFSET = 1 +QSFP_VERSION_COMPLIANCE_WIDTH = 2 +QSFP_CHANNL_MON_OFFSET = 34 +QSFP_CHANNL_MON_WIDTH = 16 +QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 +QSFP_CHANNL_DISABLE_STATUS_OFFSET = 86 +QSFP_CHANNL_DISABLE_STATUS_WIDTH = 1 +QSFP_CHANNL_RX_LOS_STATUS_OFFSET = 3 +QSFP_CHANNL_RX_LOS_STATUS_WIDTH = 1 +QSFP_CHANNL_TX_FAULT_STATUS_OFFSET = 4 +QSFP_CHANNL_TX_FAULT_STATUS_WIDTH = 1 +QSFP_CONTROL_OFFSET = 86 +QSFP_CONTROL_WIDTH = 8 +QSFP_MODULE_MONITOR_OFFSET = 0 +QSFP_MODULE_MONITOR_WIDTH = 9 +QSFP_POWEROVERRIDE_OFFSET = 93 +QSFP_POWEROVERRIDE_WIDTH = 1 +QSFP_POWEROVERRIDE_BIT = 0 +QSFP_POWERSET_BIT = 1 +QSFP_OPTION_VALUE_OFFSET = 192 +QSFP_OPTION_VALUE_WIDTH = 4 +QSFP_MODULE_UPPER_PAGE3_START = 384 +QSFP_MODULE_THRESHOLD_OFFSET = 128 +QSFP_MODULE_THRESHOLD_WIDTH = 24 +QSFP_CHANNL_THRESHOLD_OFFSET = 176 +QSFP_CHANNL_THRESHOLD_WIDTH = 24 + +SFP_MODULE_ADDRA2_OFFSET = 256 +SFP_MODULE_THRESHOLD_OFFSET = 0 +SFP_MODULE_THRESHOLD_WIDTH = 56 +SFP_CHANNL_THRESHOLD_OFFSET = 112 +SFP_CHANNL_THRESHOLD_WIDTH = 2 + +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VOLT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_CHANNL_MON_OFFSET = 100 +SFP_CHANNL_MON_WIDTH = 6 +SFP_CHANNL_STATUS_OFFSET = 110 +SFP_CHANNL_STATUS_WIDTH = 1 + +QSFP_DD_TEMPE_OFFSET = 14 +QSFP_DD_TEMPE_WIDTH = 2 +QSFP_DD_VOLT_OFFSET = 16 +QSFP_DD_VOLT_WIDTH = 2 +QSFP_DD_TX_BIAS_OFFSET = 42 +QSFP_DD_TX_BIAS_WIDTH = 16 +QSFP_DD_RX_POWER_OFFSET = 58 +QSFP_DD_RX_POWER_WIDTH = 16 +QSFP_DD_TX_POWER_OFFSET = 26 +QSFP_DD_TX_POWER_WIDTH = 16 +QSFP_DD_CHANNL_MON_OFFSET = 154 +QSFP_DD_CHANNL_MON_WIDTH = 48 +QSFP_DD_CHANNL_DISABLE_STATUS_OFFSET = 86 +QSFP_DD_CHANNL_DISABLE_STATUS_WIDTH = 1 +QSFP_DD_CHANNL_RX_LOS_STATUS_OFFSET = 19 +QSFP_DD_CHANNL_RX_LOS_STATUS_WIDTH = 1 +QSFP_DD_CHANNL_TX_FAULT_STATUS_OFFSET = 7 +QSFP_DD_CHANNL_TX_FAULT_STATUS_WIDTH = 1 +QSFP_DD_MODULE_THRESHOLD_OFFSET = 0 +QSFP_DD_MODULE_THRESHOLD_WIDTH = 72 +QSFP_DD_CHANNL_STATUS_OFFSET = 26 +QSFP_DD_CHANNL_STATUS_WIDTH = 1 + + +sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)', + 'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)', + 'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)') + +sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode', + 'ESCONComplianceCodes', 'SONETComplianceCodes', + 'EthernetComplianceCodes', 'FibreChannelLinkLength', + 'FibreChannelTechnology', 'SFP+CableTechnology', + 'FibreChannelTransmissionMedia', 'FibreChannelSpeed') + +qsfp_compliance_code_tup = ('10/40G Ethernet Compliance Code', 'SONET Compliance codes', + 'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes', + 'Fibre Channel link length/Transmitter Technology', + 'Fibre Channel transmission media', 'Fibre Channel Speed') + +info_dict_keys = ['type', 'hardwarerev', 'serial', 'manufacturer', 'model', 'connector', 'encoding', 'ext_identifier', + 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance', + 'vendor_date', 'vendor_oui', 'application_advertisement'] + +qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', + 'Length OM2(m)', 'Length OM1(m)', + 'Length Cable Assembly(m)') + +dom_info_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'lp_mode', 'tx_disable', 'tx_disable_channel', 'temperature', 'voltage', + 'rx1power', 'rx2power', 'rx3power', 'rx4power', 'rx5power', 'rx6power', 'rx7power', 'rx8power', + 'tx1bias', 'tx2bias', 'tx3bias', 'tx4bias', 'tx5bias', 'tx6bias', 'tx7bias', 'tx8bias', + 'tx1power', 'tx2power', 'tx3power', 'tx4power', 'tx5power', 'tx6power', 'tx7power', 'tx8power'] + +threshold_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning', 'vcchighalarm', 'vcchighwarning', + 'vcclowalarm', 'vcclowwarning', 'rxpowerhighalarm', 'rxpowerhighwarning', + 'rxpowerlowalarm', 'rxpowerlowwarning', 'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', + 'txpowerlowwarning', 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning'] + +SFP_TYPE_CODE_LIST = [ + '03' # SFP/SFP+/SFP28 +] +QSFP_TYPE_CODE_LIST = [ + '0d', # QSFP+ or later + '11' # QSFP28 or later +] +QSFP_DD_TYPE_CODE_LIST = [ + '18' # QSFP-DD Double Density 8X Pluggable Transceiver +] + +SFP_TYPE = "SFP" +QSFP_TYPE = "QSFP" +OSFP_TYPE = "OSFP" +QSFP_DD_TYPE = "QSFP_DD" + + +class Sfp(SfpBase): + """Platform-specific Sfp class""" + + def __init__(self, sfp_index=0, conf=None): + SfpBase.__init__(self) + + self._sfp_index = sfp_index + self._config = conf + self._api_common = Common(self._config) + + self._read_porttab_mappings() + self._dom_capability_detect() + + def _read_porttab_mappings(self): + self._sfputil_helper = SfpUtilHelper() + self._sfputil_helper.read_porttab_mappings( + self._get_path_to_port_config_file()) + + def _get_path_to_port_config_file(self): + host_platform_root_path = '/usr/share/sonic/device' + docker_hwsku_path = '/usr/share/sonic/hwsku' + + host_platform_path = "/".join([host_platform_root_path, + self._api_common.platform]) + hwsku_path = "/".join([host_platform_path, self._api_common.hwsku] + ) if self._api_common.is_host() else docker_hwsku_path + + return "/".join([hwsku_path, "port_config.ini"]) + + def _convert_string_to_num(self, value_str): + if "-inf" in value_str: + return Common.NULL_VAL + elif "Unknown" in value_str: + return Common.NULL_VAL + elif 'dBm' in value_str: + t_str = value_str.rstrip('dBm') + return float(t_str) + elif 'mA' in value_str: + t_str = value_str.rstrip('mA') + return float(t_str) + elif 'C' in value_str: + t_str = value_str.rstrip('C') + return float(t_str) + elif 'Volts' in value_str: + t_str = value_str.rstrip('Volts') + return float(t_str) + else: + return Common.NULL_VAL + + def _read_eeprom_specific_bytes(self, offset, num_bytes): + sysfsfile_eeprom = None + eeprom_raw = [] + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + sysfs_sfp_i2c_client_eeprom_path = self._get_eeprom_path() + try: + sysfsfile_eeprom = open( + sysfs_sfp_i2c_client_eeprom_path, mode="rb", buffering=0) + sysfsfile_eeprom.seek(offset) + raw = sysfsfile_eeprom.read(num_bytes) + for n in range(0, num_bytes): + eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + except Exception: + pass + finally: + if sysfsfile_eeprom: + sysfsfile_eeprom.close() + + return eeprom_raw + + def _detect_sfp_type(self): + sfp_type = QSFP_TYPE + eeprom_raw = [] + eeprom_raw = self._read_eeprom_specific_bytes( + XCVR_TYPE_OFFSET, XCVR_TYPE_WIDTH) + if eeprom_raw: + if eeprom_raw[0] in SFP_TYPE_CODE_LIST: + self.sfp_type = SFP_TYPE + elif eeprom_raw[0] in QSFP_TYPE_CODE_LIST: + self.sfp_type = QSFP_TYPE + elif eeprom_raw[0] in QSFP_DD_TYPE_CODE_LIST: + self.sfp_type = QSFP_DD_TYPE + else: + self.sfp_type = sfp_type + else: + self.sfp_type = sfp_type + + def _get_eeprom_path(self): + eeprom_path = self._config['eeprom_path'] + port_to_i2c_mapping = self._config['port_i2c_mapping'] + port_eeprom_path = eeprom_path.format( + port_to_i2c_mapping[self._sfp_index]) + + return port_eeprom_path + + def _dom_capability_detect(self): + if not self.get_presence(): + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.calibration = 0 + return + + self._detect_sfp_type() + + if self.sfp_type == QSFP_TYPE: + self.calibration = 1 + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + self.dom_supported = False + offset = 128 + + # 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( + (offset + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) + if qsfp_dom_capability_raw is not None: + qsfp_version_compliance_raw = self._read_eeprom_specific_bytes( + QSFP_VERSION_COMPLIANCE_OFFSET, QSFP_VERSION_COMPLIANCE_WIDTH) + qsfp_version_compliance = int( + qsfp_version_compliance_raw[0], 16) + dom_capability = sfpi_obj.parse_dom_capability( + qsfp_dom_capability_raw, 0) + if qsfp_version_compliance >= 0x08: + self.dom_temp_supported = dom_capability['data']['Temp_support']['value'] == 'On' + self.dom_volt_supported = dom_capability['data']['Voltage_support']['value'] == 'On' + self.dom_rx_power_supported = dom_capability['data']['Rx_power_support']['value'] == 'On' + self.dom_tx_power_supported = dom_capability['data']['Tx_power_support']['value'] == 'On' + else: + self.dom_temp_supported = True + self.dom_volt_supported = True + self.dom_rx_power_supported = dom_capability['data']['Rx_power_support']['value'] == 'On' + self.dom_tx_power_supported = True + + self.dom_supported = True + self.calibration = 1 + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + qsfp_option_value_raw = self._read_eeprom_specific_bytes( + QSFP_OPTION_VALUE_OFFSET, QSFP_OPTION_VALUE_WIDTH) + if qsfp_option_value_raw is not None: + optional_capability = sfpd_obj.parse_option_params( + qsfp_option_value_raw, 0) + self.dom_tx_disable_supported = optional_capability[ + 'data']['TxDisable']['value'] == 'On' + dom_status_indicator = sfpd_obj.parse_dom_status_indicator( + qsfp_version_compliance_raw, 1) + self.qsfp_page3_available = dom_status_indicator['data']['FlatMem']['value'] == 'Off' + else: + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.calibration = 0 + self.qsfp_page3_available = False + + elif self.sfp_type == QSFP_DD_TYPE: + sfpi_obj = qsfp_dd_InterfaceId() + if sfpi_obj is None: + self.dom_supported = False + + offset = 0 + # two types of QSFP-DD cable types supported: Copper and Optical. + qsfp_dom_capability_raw = self._read_eeprom_specific_bytes( + (offset + XCVR_DOM_CAPABILITY_OFFSET_QSFP_DD), XCVR_DOM_CAPABILITY_WIDTH_QSFP_DD) + if qsfp_dom_capability_raw is not None: + self.dom_temp_supported = True + self.dom_volt_supported = True + dom_capability = sfpi_obj.parse_dom_capability( + qsfp_dom_capability_raw, 0) + if dom_capability['data']['Flat_MEM']['value'] == 'Off': + self.dom_supported = True + self.second_application_list = True + self.dom_rx_power_supported = True + self.dom_tx_power_supported = True + self.dom_tx_bias_power_supported = True + self.dom_thresholds_supported = True + # currently set to False becasue Page 11h is not supported by FW + self.dom_rx_tx_power_bias_supported = False + else: + self.dom_supported = False + self.second_application_list = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.dom_tx_bias_power_supported = False + self.dom_thresholds_supported = False + self.dom_rx_tx_power_bias_supported = False + else: + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.dom_tx_bias_power_supported = False + self.dom_thresholds_supported = False + self.dom_rx_tx_power_bias_supported = False + + elif self.sfp_type == SFP_TYPE: + sfpi_obj = sff8472InterfaceId() + if sfpi_obj is None: + return None + sfp_dom_capability_raw = self._read_eeprom_specific_bytes( + XCVR_DOM_CAPABILITY_OFFSET, XCVR_DOM_CAPABILITY_WIDTH) + if sfp_dom_capability_raw is not None: + sfp_dom_capability = int(sfp_dom_capability_raw[0], 16) + self.dom_supported = (sfp_dom_capability & 0x40 != 0) + if self.dom_supported: + self.dom_temp_supported = True + self.dom_volt_supported = True + self.dom_rx_power_supported = True + self.dom_tx_power_supported = True + if sfp_dom_capability & 0x20 != 0: + self.calibration = 1 + elif sfp_dom_capability & 0x10 != 0: + self.calibration = 2 + else: + self.calibration = 0 + else: + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.calibration = 0 + self.dom_tx_disable_supported = ( + int(sfp_dom_capability_raw[1], 16) & 0x40 != 0) + else: + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + + def get_name(self): + """ + Retrieves the human-readable name of a sfp by 1-based index + + Returns: + :param index: An integer, 1-based index of the sfp of which to query status + :return: String, + A string representing the name of the sfp. + """ + return self._sfputil_helper.logical[self._sfp_index] or "Unknown" + + def get_presence(self): + """ + Retrieves the presence of the device + Returns: + bool: True if device is present, False if not + """ + return self._api_common.get_output(self._sfp_index, self._config['get_presence'], False) + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + + Returns: + string: Model/part number of device + """ + transceiver_dom_info_dict = self.get_transceiver_info() + return transceiver_dom_info_dict.get("model", Common.NULL_VAL) + + def get_serial(self): + """ + Retrieves the serial number of the device + + Returns: + string: Serial number of device + """ + transceiver_dom_info_dict = self.get_transceiver_info() + return transceiver_dom_info_dict.get("serial", Common.NULL_VAL) + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self.get_presence() + + def get_transceiver_info(self): + """ + Retrieves transceiver info of this SFP + Returns: + A dict which contains following keys/values : + ================================================================================ + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + type |1*255VCHAR |type of SFP + hardware_rev |1*255VCHAR |hardware version of SFP + serial |1*255VCHAR |serial number of the SFP + manufacturer |1*255VCHAR |SFP vendor name + model |1*255VCHAR |SFP model name + connector |1*255VCHAR |connector information + encoding |1*255VCHAR |encoding information + ext_identifier |1*255VCHAR |extend identifier + ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance + cable_length |INT |cable length in m + nominal_bit_rate |INT |nominal bit rate by 100Mbs + specification_compliance |1*255VCHAR |specification compliance + vendor_date |1*255VCHAR |vendor date + vendor_oui |1*255VCHAR |vendor OUI + application_advertisement |1*255VCHAR |supported applications advertisement + ================================================================================ + """ + + transceiver_info_dict = {} + compliance_code_dict = {} + transceiver_info_dict = dict.fromkeys( + info_dict_keys, Common.NULL_VAL) + + # ToDo: OSFP tranceiver info parsing not fully supported. + # in inf8628.py lack of some memory map definition + # will be implemented when the inf8628 memory map ready + if self.sfp_type == OSFP_TYPE: + offset = 0 + vendor_rev_width = XCVR_HW_REV_WIDTH_OSFP + + sfpi_obj = inf8628InterfaceId() + if sfpi_obj is None: + return None + + sfp_type_raw = self._read_eeprom_specific_bytes( + (offset + OSFP_TYPE_OFFSET), XCVR_TYPE_WIDTH) + if sfp_type_raw is not None: + sfp_type_data = sfpi_obj.parse_sfp_type(sfp_type_raw, 0) + else: + return None + + sfp_vendor_name_raw = self._read_eeprom_specific_bytes( + (offset + OSFP_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) + if sfp_vendor_name_raw is not None: + sfp_vendor_name_data = sfpi_obj.parse_vendor_name( + sfp_vendor_name_raw, 0) + else: + return None + + sfp_vendor_pn_raw = self._read_eeprom_specific_bytes( + (offset + OSFP_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + if sfp_vendor_pn_raw is not None: + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn( + sfp_vendor_pn_raw, 0) + else: + return None + + sfp_vendor_rev_raw = self._read_eeprom_specific_bytes( + (offset + OSFP_HW_REV_OFFSET), vendor_rev_width) + if sfp_vendor_rev_raw is not None: + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev( + sfp_vendor_rev_raw, 0) + else: + return None + + sfp_vendor_sn_raw = self._read_eeprom_specific_bytes( + (offset + OSFP_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + if sfp_vendor_sn_raw is not None: + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn( + sfp_vendor_sn_raw, 0) + else: + return None + + transceiver_info_dict['type'] = sfp_type_data['data']['type']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + + elif self.sfp_type == QSFP_TYPE: + offset = 128 + vendor_rev_width = XCVR_HW_REV_WIDTH_QSFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_QSFP + + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + + elif self.sfp_type == QSFP_DD_TYPE: + offset = 128 + + sfpi_obj = qsfp_dd_InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + + sfp_type_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_DD_TYPE_OFFSET), XCVR_TYPE_WIDTH) + if sfp_type_raw is not None: + sfp_type_data = sfpi_obj.parse_sfp_type(sfp_type_raw, 0) + else: + return None + + sfp_vendor_name_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_DD_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) + if sfp_vendor_name_raw is not None: + sfp_vendor_name_data = sfpi_obj.parse_vendor_name( + sfp_vendor_name_raw, 0) + else: + return None + + sfp_vendor_pn_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_DD_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + if sfp_vendor_pn_raw is not None: + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn( + sfp_vendor_pn_raw, 0) + else: + return None + + sfp_vendor_rev_raw = self._read_eeprom_specific_bytes( + (offset + XCVR_HW_REV_OFFSET_QSFP_DD), XCVR_HW_REV_WIDTH_QSFP_DD) + if sfp_vendor_rev_raw is not None: + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev( + sfp_vendor_rev_raw, 0) + else: + return None + + sfp_vendor_sn_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_DD_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + if sfp_vendor_sn_raw is not None: + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn( + sfp_vendor_sn_raw, 0) + else: + return None + + sfp_vendor_oui_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_DD_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH) + if sfp_vendor_oui_raw is not None: + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui( + sfp_vendor_oui_raw, 0) + else: + return None + + sfp_vendor_date_raw = self._read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_DATE_OFFSET_QSFP_DD), XCVR_VENDOR_DATE_WIDTH_QSFP_DD) + if sfp_vendor_date_raw is not None: + sfp_vendor_date_data = sfpi_obj.parse_vendor_date( + sfp_vendor_date_raw, 0) + else: + return None + + sfp_connector_raw = self._read_eeprom_specific_bytes( + (offset + XCVR_CONNECTOR_OFFSET_QSFP_DD), XCVR_CONNECTOR_WIDTH_QSFP_DD) + if sfp_connector_raw is not None: + sfp_connector_data = sfpi_obj.parse_connector( + sfp_connector_raw, 0) + else: + return None + + sfp_ext_identifier_raw = self._read_eeprom_specific_bytes( + (offset + XCVR_EXT_TYPE_OFFSET_QSFP_DD), XCVR_EXT_TYPE_WIDTH_QSFP_DD) + if sfp_ext_identifier_raw is not None: + sfp_ext_identifier_data = sfpi_obj.parse_ext_iden( + sfp_ext_identifier_raw, 0) + else: + return None + + sfp_cable_len_raw = self._read_eeprom_specific_bytes( + (offset + XCVR_CABLE_LENGTH_OFFSET_QSFP_DD), XCVR_CABLE_LENGTH_WIDTH_QSFP_DD) + if sfp_cable_len_raw is not None: + sfp_cable_len_data = sfpi_obj.parse_cable_len( + sfp_cable_len_raw, 0) + else: + return None + + sfp_media_type_raw = self._read_eeprom_specific_bytes( + XCVR_MEDIA_TYPE_OFFSET_QSFP_DD, XCVR_MEDIA_TYPE_WIDTH_QSFP_DD) + if sfp_media_type_raw is not None: + sfp_media_type_dict = sfpi_obj.parse_media_type( + sfp_media_type_raw, 0) + if sfp_media_type_dict is None: + return None + + host_media_list = "" + sfp_application_type_first_list = self._read_eeprom_specific_bytes( + (XCVR_FIRST_APPLICATION_LIST_OFFSET_QSFP_DD), XCVR_FIRST_APPLICATION_LIST_WIDTH_QSFP_DD) + if self.second_application_list: + possible_application_count = 15 + sfp_application_type_second_list = self._read_eeprom_specific_bytes( + (XCVR_SECOND_APPLICATION_LIST_OFFSET_QSFP_DD), XCVR_SECOND_APPLICATION_LIST_WIDTH_QSFP_DD) + if sfp_application_type_first_list is not None and sfp_application_type_second_list is not None: + sfp_application_type_list = sfp_application_type_first_list + \ + sfp_application_type_second_list + else: + return None + else: + possible_application_count = 8 + if sfp_application_type_first_list is not None: + sfp_application_type_list = sfp_application_type_first_list + else: + return None + + for i in range(0, possible_application_count): + if sfp_application_type_list[i * 4] == 'ff': + break + host_electrical, media_interface = sfpi_obj.parse_application( + sfp_media_type_dict, sfp_application_type_list[i * 4], sfp_application_type_list[i * 4 + 1]) + host_media_list = host_media_list + host_electrical + \ + ' - ' + media_interface + '\n\t\t\t\t ' + else: + return None + + transceiver_info_dict['type'] = str( + sfp_type_data['data']['type']['value']) + transceiver_info_dict['manufacturer'] = str( + sfp_vendor_name_data['data']['Vendor Name']['value']) + transceiver_info_dict['model'] = str( + sfp_vendor_pn_data['data']['Vendor PN']['value']) + transceiver_info_dict['hardware_rev'] = str( + sfp_vendor_rev_data['data']['Vendor Rev']['value']) + transceiver_info_dict['serial'] = str( + sfp_vendor_sn_data['data']['Vendor SN']['value']) + transceiver_info_dict['vendor_oui'] = str( + sfp_vendor_oui_data['data']['Vendor OUI']['value']) + transceiver_info_dict['vendor_date'] = str( + sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value']) + transceiver_info_dict['connector'] = str( + sfp_connector_data['data']['Connector']['value']) + transceiver_info_dict['encoding'] = "Not supported for CMIS cables" + transceiver_info_dict['ext_identifier'] = str( + sfp_ext_identifier_data['data']['Extended Identifier']['value']) + transceiver_info_dict['ext_rateselect_compliance'] = "Not supported for CMIS cables" + transceiver_info_dict['specification_compliance'] = "Not supported for CMIS cables" + transceiver_info_dict['cable_type'] = "Length Cable Assembly(m)" + transceiver_info_dict['cable_length'] = str( + sfp_cable_len_data['data']['Length Cable Assembly(m)']['value']) + transceiver_info_dict['nominal_bit_rate'] = "Not supported for CMIS cables" + transceiver_info_dict['application_advertisement'] = host_media_list + + else: + offset = 0 + vendor_rev_width = XCVR_HW_REV_WIDTH_SFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_SFP + + sfpi_obj = sff8472InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + + if self.sfp_type != QSFP_DD_TYPE: + sfp_interface_bulk_raw = self._read_eeprom_specific_bytes( + offset + XCVR_INTERFACE_DATA_START, XCVR_INTERFACE_DATA_SIZE) + if sfp_interface_bulk_raw is None: + return None + + start = XCVR_INTFACE_BULK_OFFSET - XCVR_INTERFACE_DATA_START + end = start + interface_info_bulk_width + sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_NAME_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_NAME_WIDTH + sfp_vendor_name_data = sfpi_obj.parse_vendor_name( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_PN_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_PN_WIDTH + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_HW_REV_OFFSET - XCVR_INTERFACE_DATA_START + end = start + vendor_rev_width + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_SN_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_SN_WIDTH + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_OUI_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_OUI_WIDTH + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_DATE_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_DATE_WIDTH + sfp_vendor_date_data = sfpi_obj.parse_vendor_date( + sfp_interface_bulk_raw[start: end], 0) + + transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] + transceiver_info_dict['vendor_date'] = sfp_vendor_date_data[ + 'data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] + transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] + transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] + + if self.sfp_type == QSFP_TYPE: + for key in qsfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str( + sfp_interface_bulk_data['data'][key]['value']) + + for key in qsfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + sfp_ext_specification_compliance_raw = self._read_eeprom_specific_bytes( + offset + XCVR_EXT_SPECIFICATION_COMPLIANCE_OFFSET, XCVR_EXT_SPECIFICATION_COMPLIANCE_WIDTH) + if sfp_ext_specification_compliance_raw is not None: + sfp_ext_specification_compliance_data = sfpi_obj.parse_ext_specification_compliance( + sfp_ext_specification_compliance_raw[0: 1], 0) + if sfp_ext_specification_compliance_data['data']['Extended Specification compliance']['value'] != "Unspecified": + compliance_code_dict['Extended Specification compliance'] = sfp_ext_specification_compliance_data[ + 'data']['Extended Specification compliance']['value'] + transceiver_info_dict['specification_compliance'] = str( + compliance_code_dict) + transceiver_info_dict['nominal_bit_rate'] = str( + sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value']) + else: + for key in sfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str( + sfp_interface_bulk_data['data'][key]['value']) + + for key in sfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + transceiver_info_dict['specification_compliance'] = str( + compliance_code_dict) + + transceiver_info_dict['nominal_bit_rate'] = str( + sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) + + return transceiver_info_dict + + def get_transceiver_bulk_status(self): + """ + Retrieves transceiver bulk status of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + rx_los |BOOLEAN |RX loss-of-signal status, True if has RX los, False if not. + tx_fault |BOOLEAN |TX fault status, True if has TX fault, False if not. + reset_status |BOOLEAN |reset status, True if SFP in reset, False if not. + lp_mode |BOOLEAN |low power mode status, True in lp mode, False if not. + tx_disable |BOOLEAN |TX disable status, True TX disabled, False if not. + tx_disabled_channel |HEX |disabled TX channels in hex, bits 0 to 3 represent channel 0 + | |to channel 3. + temperature |INT |module temperature in Celsius + voltage |INT |supply voltage in mV + txbias |INT |TX Bias Current in mA, n is the channel number, + | |for example, tx2bias stands for tx bias of channel 2. + rxpower |INT |received optical power in mW, n is the channel number, + | |for example, rx2power stands for rx power of channel 2. + txpower |INT |TX output power in mW, n is the channel number, + | |for example, tx2power stands for tx power of channel 2. + ======================================================================== + """ + transceiver_dom_info_dict = dict.fromkeys( + dom_info_dict_keys, Common.NULL_VAL) + + if self.sfp_type == OSFP_TYPE: + pass + + elif self.sfp_type == QSFP_TYPE: + if not self.dom_supported: + return transceiver_dom_info_dict + + offset = 0 + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return transceiver_dom_info_dict + + dom_data_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_DOM_BULK_DATA_START), QSFP_DOM_BULK_DATA_SIZE) + if dom_data_raw is None: + return transceiver_dom_info_dict + + if self.dom_temp_supported: + start = QSFP_TEMPE_OFFSET - QSFP_DOM_BULK_DATA_START + end = start + QSFP_TEMPE_WIDTH + dom_temperature_data = sfpd_obj.parse_temperature( + dom_data_raw[start: end], 0) + temp = dom_temperature_data['data']['Temperature']['value'] + if temp is not None: + transceiver_dom_info_dict['temperature'] = temp + + if self.dom_volt_supported: + start = QSFP_VOLT_OFFSET - QSFP_DOM_BULK_DATA_START + end = start + QSFP_VOLT_WIDTH + dom_voltage_data = sfpd_obj.parse_voltage( + dom_data_raw[start: end], 0) + volt = dom_voltage_data['data']['Vcc']['value'] + if volt is not None: + transceiver_dom_info_dict['voltage'] = volt + + start = QSFP_CHANNL_MON_OFFSET - QSFP_DOM_BULK_DATA_START + end = start + QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power( + dom_data_raw[start: end], 0) + + if self.dom_tx_power_supported: + 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'] + + if self.dom_rx_power_supported: + 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'] + + elif self.sfp_type == QSFP_DD_TYPE: + + offset = 0 + sfpd_obj = qsfp_dd_Dom() + if sfpd_obj is None: + return transceiver_dom_info_dict + + dom_data_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_DD_DOM_BULK_DATA_START), QSFP_DD_DOM_BULK_DATA_SIZE) + if dom_data_raw is None: + return transceiver_dom_info_dict + + if self.dom_temp_supported: + start = QSFP_DD_TEMPE_OFFSET - QSFP_DD_DOM_BULK_DATA_START + end = start + QSFP_DD_TEMPE_WIDTH + dom_temperature_data = sfpd_obj.parse_temperature( + dom_data_raw[start: end], 0) + temp = dom_temperature_data['data']['Temperature']['value'] + if temp is not None: + transceiver_dom_info_dict['temperature'] = temp + + if self.dom_volt_supported: + start = QSFP_DD_VOLT_OFFSET - QSFP_DD_DOM_BULK_DATA_START + end = start + QSFP_DD_VOLT_WIDTH + dom_voltage_data = sfpd_obj.parse_voltage( + dom_data_raw[start: end], 0) + volt = dom_voltage_data['data']['Vcc']['value'] + if volt is not None: + transceiver_dom_info_dict['voltage'] = volt + + if self.dom_rx_tx_power_bias_supported: + # page 11h + dom_data_raw = self._read_eeprom_specific_bytes( + (QSFP_DD_CHANNL_MON_OFFSET), QSFP_DD_CHANNL_MON_WIDTH) + if dom_data_raw is None: + return transceiver_dom_info_dict + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( + dom_data_raw, 0) + + if self.dom_tx_power_supported: + transceiver_dom_info_dict['tx1power'] = str( + dom_channel_monitor_data['data']['TX1Power']['value']) + transceiver_dom_info_dict['tx2power'] = str( + dom_channel_monitor_data['data']['TX2Power']['value']) + transceiver_dom_info_dict['tx3power'] = str( + dom_channel_monitor_data['data']['TX3Power']['value']) + transceiver_dom_info_dict['tx4power'] = str( + dom_channel_monitor_data['data']['TX4Power']['value']) + transceiver_dom_info_dict['tx5power'] = str( + dom_channel_monitor_data['data']['TX5Power']['value']) + transceiver_dom_info_dict['tx6power'] = str( + dom_channel_monitor_data['data']['TX6Power']['value']) + transceiver_dom_info_dict['tx7power'] = str( + dom_channel_monitor_data['data']['TX7Power']['value']) + transceiver_dom_info_dict['tx8power'] = str( + dom_channel_monitor_data['data']['TX8Power']['value']) + + if self.dom_rx_power_supported: + transceiver_dom_info_dict['rx1power'] = str( + dom_channel_monitor_data['data']['RX1Power']['value']) + transceiver_dom_info_dict['rx2power'] = str( + dom_channel_monitor_data['data']['RX2Power']['value']) + transceiver_dom_info_dict['rx3power'] = str( + dom_channel_monitor_data['data']['RX3Power']['value']) + transceiver_dom_info_dict['rx4power'] = str( + dom_channel_monitor_data['data']['RX4Power']['value']) + transceiver_dom_info_dict['rx5power'] = str( + dom_channel_monitor_data['data']['RX5Power']['value']) + transceiver_dom_info_dict['rx6power'] = str( + dom_channel_monitor_data['data']['RX6Power']['value']) + transceiver_dom_info_dict['rx7power'] = str( + dom_channel_monitor_data['data']['RX7Power']['value']) + transceiver_dom_info_dict['rx8power'] = str( + dom_channel_monitor_data['data']['RX8Power']['value']) + + if self.dom_tx_bias_power_supported: + transceiver_dom_info_dict['tx1bias'] = str( + dom_channel_monitor_data['data']['TX1Bias']['value']) + transceiver_dom_info_dict['tx2bias'] = str( + dom_channel_monitor_data['data']['TX2Bias']['value']) + transceiver_dom_info_dict['tx3bias'] = str( + dom_channel_monitor_data['data']['TX3Bias']['value']) + transceiver_dom_info_dict['tx4bias'] = str( + dom_channel_monitor_data['data']['TX4Bias']['value']) + transceiver_dom_info_dict['tx5bias'] = str( + dom_channel_monitor_data['data']['TX5Bias']['value']) + transceiver_dom_info_dict['tx6bias'] = str( + dom_channel_monitor_data['data']['TX6Bias']['value']) + transceiver_dom_info_dict['tx7bias'] = str( + dom_channel_monitor_data['data']['TX7Bias']['value']) + transceiver_dom_info_dict['tx8bias'] = str( + dom_channel_monitor_data['data']['TX8Bias']['value']) + + return transceiver_dom_info_dict + + else: + if not self.dom_supported: + return transceiver_dom_info_dict + + offset = 256 + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return transceiver_dom_info_dict + sfpd_obj._calibration_type = self.calibration + + dom_data_raw = self._read_eeprom_specific_bytes( + (offset + SFP_DOM_BULK_DATA_START), SFP_DOM_BULK_DATA_SIZE) + + start = SFP_TEMPE_OFFSET - SFP_DOM_BULK_DATA_START + end = start + SFP_TEMPE_WIDTH + dom_temperature_data = sfpd_obj.parse_temperature( + dom_data_raw[start: end], 0) + + start = SFP_VOLT_OFFSET - SFP_DOM_BULK_DATA_START + end = start + SFP_VOLT_WIDTH + dom_voltage_data = sfpd_obj.parse_voltage( + dom_data_raw[start: end], 0) + + start = SFP_CHANNL_MON_OFFSET - SFP_DOM_BULK_DATA_START + end = start + SFP_CHANNL_MON_WIDTH + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( + dom_data_raw[start: end], 0) + + 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['tx1bias'] = dom_channel_monitor_data['data']['TXBias']['value'] + transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TXPower']['value'] + + transceiver_dom_info_dict['lp_mode'] = self.get_lpmode() + transceiver_dom_info_dict['reset_status'] = self.get_reset_status() + transceiver_dom_info_dict['tx_disable'] = self.get_tx_disable() + transceiver_dom_info_dict['tx_disabled_channel'] = self.get_tx_disable_channel( + ) + + for key in transceiver_dom_info_dict: + val = transceiver_dom_info_dict[key] + transceiver_dom_info_dict[key] = self._convert_string_to_num( + val) if type(val) is str else val + + return transceiver_dom_info_dict + + def get_transceiver_threshold_info(self): + """ + Retrieves transceiver threshold info of this SFP + + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius. + templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius. + temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius. + templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius. + vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV. + vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV. + vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV. + vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV. + rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm. + rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm. + rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm. + rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm. + txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm. + txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm. + txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm. + txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm. + txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA. + txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA. + txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA. + txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA. + ======================================================================== + """ + transceiver_dom_threshold_info_dict = dict.fromkeys( + threshold_dict_keys, Common.NULL_VAL) + + if self.sfp_type == OSFP_TYPE: + pass + + elif self.sfp_type == QSFP_TYPE: + if not self.dom_supported or not self.qsfp_page3_available: + return transceiver_dom_threshold_info_dict + + # Dom Threshold data starts from offset 384 + # Revert offset back to 0 once data is retrieved + offset = QSFP_MODULE_UPPER_PAGE3_START + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_MODULE_THRESHOLD_OFFSET), QSFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_data = sfpd_obj.parse_module_threshold_values( + dom_module_threshold_raw, 0) + + dom_channel_threshold_raw = self._read_eeprom_specific_bytes((offset + QSFP_CHANNL_THRESHOLD_OFFSET), + QSFP_CHANNL_THRESHOLD_WIDTH) + if dom_channel_threshold_raw is None: + return transceiver_dom_threshold_info_dict + dom_channel_threshold_data = sfpd_obj.parse_channel_threshold_values( + dom_channel_threshold_raw, 0) + + # 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'] + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_channel_threshold_data['data']['TxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_channel_threshold_data['data']['TxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_channel_threshold_data['data']['TxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_channel_threshold_data['data']['TxPowerLowWarning']['value'] + + elif self.sfp_type == QSFP_DD_TYPE: + if not self.dom_supported: + return transceiver_dom_threshold_info_dict + + if not self.dom_thresholds_supported: + return transceiver_dom_threshold_info_dict + + sfpd_obj = qsfp_dd_Dom() + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + # page 02 + offset = 384 + dom_module_threshold_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_DD_MODULE_THRESHOLD_OFFSET), QSFP_DD_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_data = sfpd_obj.parse_module_threshold_values( + dom_module_threshold_raw, 0) + + # 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_module_threshold_data['data']['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RxPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['TxBiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['TxBiasLowWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TxPowerLowWarning']['value'] + + else: + offset = SFP_MODULE_ADDRA2_OFFSET + + if not self.dom_supported: + return transceiver_dom_threshold_info_dict + + sfpd_obj = sff8472Dom(None, self.calibration) + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_raw = self._read_eeprom_specific_bytes((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 + + # 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'] + + for key in transceiver_dom_threshold_info_dict: + transceiver_dom_threshold_info_dict[key] = self._convert_string_to_num( + transceiver_dom_threshold_info_dict[key]) + + return transceiver_dom_threshold_info_dict + + def get_reset_status(self): + """ + Retrieves the reset status of SFP + Returns: + A Boolean, True if reset enabled, False if disabled + """ + return self._api_common.get_output(self._sfp_index, self._config['get_reset_status'], False) + + def get_rx_los(self): + """ + Retrieves the RX LOS (lost-of-signal) status of SFP + Returns: + A Boolean, True if SFP has RX LOS, False if not. + Note : RX LOS status is latched until a call to get_rx_los or a reset. + """ + if not self.dom_supported: + return None + + rx_los_list = [] + if self.sfp_type == OSFP_TYPE: + return None + elif self.sfp_type == QSFP_TYPE: + offset = 0 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_RX_LOS_STATUS_OFFSET), QSFP_CHANNL_RX_LOS_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 16) + rx_los_list.append(rx_los_data & 0x01 != 0) + rx_los_list.append(rx_los_data & 0x02 != 0) + rx_los_list.append(rx_los_data & 0x04 != 0) + rx_los_list.append(rx_los_data & 0x08 != 0) + + elif self.sfp_type == QSFP_DD_TYPE: + # page 11h + if self.dom_rx_tx_power_bias_supported: + offset = 128 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_DD_CHANNL_RX_LOS_STATUS_OFFSET), QSFP_DD_CHANNL_RX_LOS_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 8) + rx_los_list.append(rx_los_data & 0x01 != 0) + rx_los_list.append(rx_los_data & 0x02 != 0) + rx_los_list.append(rx_los_data & 0x04 != 0) + rx_los_list.append(rx_los_data & 0x08 != 0) + rx_los_list.append(rx_los_data & 0x10 != 0) + rx_los_list.append(rx_los_data & 0x20 != 0) + rx_los_list.append(rx_los_data & 0x40 != 0) + rx_los_list.append(rx_los_data & 0x80 != 0) + + else: + offset = 256 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + (offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 16) + rx_los_list.append(rx_los_data & 0x02 != 0) + else: + return None + return rx_los_list + + def get_tx_fault(self): + """ + Retrieves the TX fault status of SFP + Returns: + A Boolean, True if SFP has TX fault, False if not + Note : TX fault status is lached until a call to get_tx_fault or a reset. + """ + if not self.dom_supported: + return None + + tx_fault_list = [] + if self.sfp_type == OSFP_TYPE: + return None + elif self.sfp_type == QSFP_TYPE: + offset = 0 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_TX_FAULT_STATUS_OFFSET), QSFP_CHANNL_TX_FAULT_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 16) + tx_fault_list.append(tx_fault_data & 0x01 != 0) + tx_fault_list.append(tx_fault_data & 0x02 != 0) + tx_fault_list.append(tx_fault_data & 0x04 != 0) + tx_fault_list.append(tx_fault_data & 0x08 != 0) + + elif self.sfp_type == QSFP_DD_TYPE: + # page 11h + if self.dom_rx_tx_power_bias_supported: + offset = 128 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_DD_CHANNL_TX_FAULT_STATUS_OFFSET), QSFP_DD_CHANNL_TX_FAULT_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 8) + tx_fault_list.append(tx_fault_data & 0x01 != 0) + tx_fault_list.append(tx_fault_data & 0x02 != 0) + tx_fault_list.append(tx_fault_data & 0x04 != 0) + tx_fault_list.append(tx_fault_data & 0x08 != 0) + tx_fault_list.append(tx_fault_data & 0x10 != 0) + tx_fault_list.append(tx_fault_data & 0x20 != 0) + tx_fault_list.append(tx_fault_data & 0x40 != 0) + tx_fault_list.append(tx_fault_data & 0x80 != 0) + + else: + offset = 256 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + (offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 16) + tx_fault_list.append(tx_fault_data & 0x04 != 0) + else: + return None + return tx_fault_list + + def get_tx_disable(self): + """ + Retrieves the tx_disable status of this SFP + Returns: + A list of boolean values, representing the TX disable status + of each available channel, value is True if SFP channel + is TX disabled, False if not. + E.g., for a tranceiver with four channels: [False, False, True, False] + """ + if not self.dom_supported: + return None + + tx_disable_list = [] + if self.sfp_type == OSFP_TYPE: + return None + elif self.sfp_type == QSFP_TYPE: + offset = 0 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_DISABLE_STATUS_OFFSET), QSFP_CHANNL_DISABLE_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_disable_data = int(dom_channel_monitor_raw[0], 16) + tx_disable_list.append(tx_disable_data & 0x01 != 0) + tx_disable_list.append(tx_disable_data & 0x02 != 0) + tx_disable_list.append(tx_disable_data & 0x04 != 0) + tx_disable_list.append(tx_disable_data & 0x08 != 0) + + elif self.sfp_type == QSFP_DD_TYPE: + if self.dom_rx_tx_power_bias_supported: + offset = 128 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_DD_CHANNL_DISABLE_STATUS_OFFSET), QSFP_DD_CHANNL_DISABLE_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_disable_data = int(dom_channel_monitor_raw[0], 16) + tx_disable_list.append(tx_disable_data & 0x01 != 0) + tx_disable_list.append(tx_disable_data & 0x02 != 0) + tx_disable_list.append(tx_disable_data & 0x04 != 0) + tx_disable_list.append(tx_disable_data & 0x08 != 0) + tx_disable_list.append(tx_disable_data & 0x10 != 0) + tx_disable_list.append(tx_disable_data & 0x20 != 0) + tx_disable_list.append(tx_disable_data & 0x40 != 0) + tx_disable_list.append(tx_disable_data & 0x80 != 0) + + else: + offset = 256 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + (offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_disable_data = int(dom_channel_monitor_raw[0], 16) + tx_disable_list.append(tx_disable_data & 0xC0 != 0) + else: + return None + return tx_disable_list + + def get_tx_disable_channel(self): + """ + Retrieves the TX disabled channels in this SFP + Returns: + A hex of 4 bits (bit 0 to bit 3 as channel 0 to channel 3) to represent + TX channels which have been disabled in this SFP. + As an example, a returned value of 0x5 indicates that channel 0 + and channel 2 have been disabled. + """ + tx_disable_list = self.get_tx_disable() + if tx_disable_list is None: + return 0 + tx_disabled = 0 + for i in range(len(tx_disable_list)): + if tx_disable_list[i]: + tx_disabled |= 1 << i + return tx_disabled + + def get_lpmode(self): + """ + Retrieves the lpmode (low power mode) status of this SFP + Returns: + A Boolean, True if lpmode is enabled, False if disabled + """ + return self._api_common.get_output(self._sfp_index, self._config['get_lpmode'], False) + + def get_power_override(self): + """ + Retrieves the power-override status of this SFP + Returns: + A Boolean, True if power-override is enabled, False if disabled + """ + if self.sfp_type == QSFP_TYPE: + offset = 0 + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return False + + dom_control_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_CONTROL_OFFSET), QSFP_CONTROL_WIDTH) + if dom_control_raw is not None: + dom_control_data = sfpd_obj.parse_control_bytes( + dom_control_raw, 0) + return ('On' == dom_control_data['data']['PowerOverride']) + else: + return NotImplementedError + + def get_temperature(self): + """ + Retrieves the temperature of this SFP + Returns: + An integer number of current temperature in Celsius + """ + if not self.dom_supported: + return None + if self.sfp_type == QSFP_TYPE: + offset = 0 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + if self.dom_temp_supported: + dom_temperature_raw = self._read_eeprom_specific_bytes( + (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) + temp = self._convert_string_to_num( + dom_temperature_data['data']['Temperature']['value']) + return temp + else: + return None + else: + return None + + elif self.sfp_type == QSFP_DD_TYPE: + offset = 0 + + sfpd_obj = qsfp_dd_Dom() + if sfpd_obj is None: + return None + + if self.dom_temp_supported: + dom_temperature_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_DD_TEMPE_OFFSET), QSFP_DD_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature( + dom_temperature_raw, 0) + temp = self._convert_string_to_num( + dom_temperature_data['data']['Temperature']['value']) + return temp + return None + + else: + offset = 256 + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + sfpd_obj._calibration_type = 1 + + dom_temperature_raw = self._read_eeprom_specific_bytes( + (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) + temp = self._convert_string_to_num( + dom_temperature_data['data']['Temperature']['value']) + return temp + else: + return None + + def get_voltage(self): + """ + Retrieves the supply voltage of this SFP + Returns: + An integer number of supply voltage in mV + """ + if not self.dom_supported: + return None + if self.sfp_type == QSFP_TYPE: + offset = 0 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + if self.dom_volt_supported: + dom_voltage_raw = self._read_eeprom_specific_bytes( + (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) + voltage = self._convert_string_to_num( + dom_voltage_data['data']['Vcc']['value']) + return voltage + else: + return None + return None + + if self.sfp_type == QSFP_DD_TYPE: + offset = 128 + + sfpd_obj = qsfp_dd_Dom() + if sfpd_obj is None: + return None + + if self.dom_volt_supported: + dom_voltage_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_DD_VOLT_OFFSET), QSFP_DD_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage( + dom_voltage_raw, 0) + voltage = self._convert_string_to_num( + dom_voltage_data['data']['Vcc']['value']) + return voltage + return None + + else: + offset = 256 + + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + sfpd_obj._calibration_type = self.calibration + + dom_voltage_raw = self._read_eeprom_specific_bytes( + (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) + voltage = self._convert_string_to_num( + dom_voltage_data['data']['Vcc']['value']) + return voltage + else: + return None + + def get_tx_bias(self): + """ + Retrieves the TX bias current of this SFP + Returns: + A list of four integer numbers, representing TX bias in mA + for channel 0 to channel 4. + Ex. ['110.09', '111.12', '108.21', '112.09'] + """ + tx_bias_list = [] + if self.sfp_type == QSFP_TYPE: + offset = 0 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + (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) + tx_bias_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TX1Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TX2Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TX3Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TX4Bias']['value'])) + + elif self.sfp_type == QSFP_DD_TYPE: + # page 11h + if self.dom_rx_tx_power_bias_supported: + offset = 128 + sfpd_obj = qsfp_dd_Dom() + if sfpd_obj is None: + return None + + if dom_tx_bias_power_supported: + dom_tx_bias_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_DD_TX_BIAS_OFFSET), QSFP_DD_TX_BIAS_WIDTH) + if dom_tx_bias_raw is not None: + dom_tx_bias_data = sfpd_obj.parse_dom_tx_bias( + dom_tx_bias_raw, 0) + tx_bias_list.append(self._convert_string_to_num( + dom_tx_bias_data['data']['TX1Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num( + dom_tx_bias_data['data']['TX2Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num( + dom_tx_bias_data['data']['TX3Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num( + dom_tx_bias_data['data']['TX4Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num( + dom_tx_bias_data['data']['TX5Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num( + dom_tx_bias_data['data']['TX6Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num( + dom_tx_bias_data['data']['TX7Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num( + dom_tx_bias_data['data']['TX8Bias']['value'])) + + else: + offset = 256 + + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + sfpd_obj._calibration_type = self.calibration + + if self.dom_supported: + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + (offset + SFP_CHANNL_MON_OFFSET), SFP_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) + tx_bias_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TXBias']['value'])) + else: + return None + else: + return None + + return tx_bias_list + + def get_rx_power(self): + """ + Retrieves the received optical power for this SFP + Returns: + A list of four integer numbers, representing received optical + power in mW for channel 0 to channel 4. + Ex. ['1.77', '1.71', '1.68', '1.70'] + """ + rx_power_list = [] + if self.sfp_type == OSFP_TYPE: + # OSFP not supported on our platform yet. + return None + + elif self.sfp_type == QSFP_TYPE: + offset = 0 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + if self.dom_rx_power_supported: + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + (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) + rx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['RX1Power']['value'])) + rx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['RX2Power']['value'])) + rx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['RX3Power']['value'])) + rx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['RX4Power']['value'])) + else: + return None + else: + return None + + elif self.sfp_type == QSFP_DD_TYPE: + # page 11 + if self.dom_rx_tx_power_bias_supported: + offset = 128 + sfpd_obj = qsfp_dd_Dom() + if sfpd_obj is None: + return None + + if self.dom_rx_power_supported: + dom_rx_power_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_DD_RX_POWER_OFFSET), QSFP_DD_RX_POWER_WIDTH) + if dom_rx_power_raw is not None: + dom_rx_power_data = sfpd_obj.parse_dom_rx_power( + dom_rx_power_raw, 0) + rx_power_list.append(self._convert_string_to_num( + dom_rx_power_data['data']['RX1Power']['value'])) + rx_power_list.append(self._convert_string_to_num( + dom_rx_power_data['data']['RX2Power']['value'])) + rx_power_list.append(self._convert_string_to_num( + dom_rx_power_data['data']['RX3Power']['value'])) + rx_power_list.append(self._convert_string_to_num( + dom_rx_power_data['data']['RX4Power']['value'])) + rx_power_list.append(self._convert_string_to_num( + dom_rx_power_data['data']['RX5Power']['value'])) + rx_power_list.append(self._convert_string_to_num( + dom_rx_power_data['data']['RX6Power']['value'])) + rx_power_list.append(self._convert_string_to_num( + dom_rx_power_data['data']['RX7Power']['value'])) + rx_power_list.append(self._convert_string_to_num( + dom_rx_power_data['data']['RX8Power']['value'])) + + else: + offset = 256 + + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + if self.dom_supported: + sfpd_obj._calibration_type = self.calibration + + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + (offset + SFP_CHANNL_MON_OFFSET), SFP_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) + rx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['RXPower']['value'])) + else: + return None + else: + return None + return rx_power_list + + def get_tx_power(self): + """ + Retrieves the TX power of this SFP + Returns: + A list of four integer numbers, representing TX power in mW + for channel 0 to channel 4. + Ex. ['1.86', '1.86', '1.86', '1.86'] + """ + tx_power_list = [] + if self.sfp_type == OSFP_TYPE: + # OSFP not supported on our platform yet. + return None + + elif self.sfp_type == QSFP_TYPE: + offset = 0 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + if self.dom_tx_power_supported: + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + (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) + tx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TX1Power']['value'])) + tx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TX2Power']['value'])) + tx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TX3Power']['value'])) + tx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TX4Power']['value'])) + else: + return None + else: + return None + + elif self.sfp_type == QSFP_DD_TYPE: + # page 11 + if self.dom_rx_tx_power_bias_supported: + offset = 128 + sfpd_obj = qsfp_dd_Dom() + if sfpd_obj is None: + return None + + if self.dom_tx_power_supported: + dom_tx_power_raw = self._read_eeprom_specific_bytes( + (offset + QSFP_DD_TX_POWER_OFFSET), QSFP_DD_TX_POWER_WIDTH) + if dom_tx_power_raw is not None: + dom_tx_power_data = sfpd_obj.parse_dom_tx_power( + dom_tx_power_raw, 0) + tx_power_list.append(self._convert_string_to_num( + dom_tx_power_data['data']['TX1Power']['value'])) + tx_power_list.append(self._convert_string_to_num( + dom_tx_power_data['data']['TX2Power']['value'])) + tx_power_list.append(self._convert_string_to_num( + dom_tx_power_data['data']['TX3Power']['value'])) + tx_power_list.append(self._convert_string_to_num( + dom_tx_power_data['data']['TX4Power']['value'])) + tx_power_list.append(self._convert_string_to_num( + dom_tx_power_data['data']['TX5Power']['value'])) + tx_power_list.append(self._convert_string_to_num( + dom_tx_power_data['data']['TX6Power']['value'])) + tx_power_list.append(self._convert_string_to_num( + dom_tx_power_data['data']['TX7Power']['value'])) + tx_power_list.append(self._convert_string_to_num( + dom_tx_power_data['data']['TX8Power']['value'])) + + else: + offset = 256 + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + if self.dom_supported: + sfpd_obj._calibration_type = self.calibration + + dom_channel_monitor_raw = self._read_eeprom_specific_bytes( + (offset + SFP_CHANNL_MON_OFFSET), SFP_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) + tx_power_list.append(self._convert_string_to_num( + dom_channel_monitor_data['data']['TXPower']['value'])) + else: + return None + else: + return None + return tx_power_list + + def reset(self): + """ + Reset SFP and return all user module settings to their default srate. + + Returns: + A boolean, True if successful, False if not + """ + config = self._config['reset'] + # Convert our register value back to a hex string and write back + output1 = self._api_common.set_output(self._sfp_index, "0x0", config) + + # Sleep 1 second to allow it to settle + time.sleep(1) + # Flip the bit back high and write back to the register to take port out of reset + output2 = self._api_common.set_output(self._sfp_index, "0x1", config) + + return True if (output1 and output2) else False + + def tx_disable(self, tx_disable): + """ + Disable SFP TX for all channels + + Args: + tx_disable : A Boolean, True to enable tx_disable mode, False to disable + tx_disable mode. + + Returns: + A boolean, True if tx_disable is set successfully, False if not + """ + if self.sfp_type == QSFP_TYPE: + sysfsfile_eeprom = None + try: + tx_disable_ctl = 0xf if tx_disable else 0x0 + buffer = create_string_buffer(1) + buffer[0] = chr(tx_disable_ctl) + # Write to eeprom + sysfs_sfp_i2c_client_eeprom_path = self._get_eeprom_path() + sysfsfile_eeprom = open( + sysfs_sfp_i2c_client_eeprom_path, "r+b") + sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + finally: + if sysfsfile_eeprom is not None: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + return False + + def tx_disable_channel(self, channel, disable): + """ + Sets the tx_disable for specified SFP channels + + Args: + channel : A hex of 4 bits (bit 0 to bit 3) which represent channel 0 to 3, + e.g. 0x5 for channel 0 and channel 2. + disable : A boolean, True to disable TX channels specified in channel, + False to enable + + Returns: + A boolean, True if successful, False if not + """ + if self.sfp_type == QSFP_TYPE: + sysfsfile_eeprom = None + try: + channel_state = self.get_tx_disable_channel() + tx_enable_mask = [0xe, 0xd, 0xb, 0x7] + tx_disable_mask = [0x1, 0x3, 0x7, 0xf] + tx_disable_ctl = channel_state | tx_disable_mask[ + channel] if disable else channel_state & tx_enable_mask[channel] + buffer = create_string_buffer(1) + buffer[0] = chr(tx_disable_ctl) + # Write to eeprom + sysfs_sfp_i2c_client_eeprom_path = self._get_eeprom_path() + sysfsfile_eeprom = open( + sysfs_sfp_i2c_client_eeprom_path, "r+b") + sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + finally: + if sysfsfile_eeprom is not None: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + return False + + def set_lpmode(self, lpmode): + """ + Sets the lpmode (low power mode) of SFP + + Args: + lpmode: A Boolean, True to enable lpmode, False to disable it + Note : lpmode can be overridden by set_power_override + + Returns: + A boolean, True if lpmode is set successfully, False if not + """ + return self._api_common.set_output(self._sfp_index, str(lpmode), self._config['set_lpmode']) + + def set_power_override(self, power_override, power_set): + """ + Sets SFP power level using power_override and power_set + + Args: + power_override : + A Boolean, True to override set_lpmode and use power_set + to control SFP power, False to disable SFP power control + through power_override/power_set and use set_lpmode + to control SFP power. + power_set : + Only valid when power_override is True. + A Boolean, True to set SFP to low power mode, False to set + SFP to high power mode. + + Returns: + A boolean, True if power-override and power_set are set successfully, + False if not + """ + if self.sfp_type == QSFP_TYPE: + sysfsfile_eeprom = None + try: + power_override_bit = 0 + if power_override: + power_override_bit |= 1 << 0 + + power_set_bit = 0 + if power_set: + power_set_bit |= 1 << 1 + + buffer = create_string_buffer(1) + buffer[0] = chr(power_override_bit | power_set_bit) + # Write to eeprom + sysfs_sfp_i2c_client_eeprom_path = self._get_eeprom_path() + sysfsfile_eeprom = open( + sysfs_sfp_i2c_client_eeprom_path, "r+b") + sysfsfile_eeprom.seek(QSFP_POWEROVERRIDE_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + finally: + if sysfsfile_eeprom is not None: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + + return False diff --git a/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/thermal.py new file mode 100644 index 000000000000..714e073db37d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/sonic_platform/thermal.py @@ -0,0 +1,176 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the thermal status which are available in the platform +# +############################################################################# + +try: + from sonic_platform_base.thermal_base import ThermalBase + from common import Common +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Thermal(ThermalBase): + """Platform-specific Thermal class""" + + def __init__(self, index, _thermal_index=0, conf=None): + ThermalBase.__init__(self) + + self._thermal_index = index + self._config = conf + self._api_common = Common(self._config) + + def get_name(self): + """ + Retrieves the human-readable name of a thermal sensor by 1-based index + + Returns: + :param index: An integer, 1-based index of the thermal sensor of which to query status + :return: String, + A string representing the name of the thermal sensor. + """ + return self._api_common.get_output(self._thermal_index, self._config['get_name'], Common.NULL_VAL) + + def get_temperature(self): + """ + Retrieves current temperature reading from thermal + + by using command ipmitool raw 0x04 0x2D [address] + + Returns: + A float number of current temperature in Celsius up to nearest thousandth + of one degree Celsius, e.g. 30.125 + """ + output = self._api_common.get_output( + self._thermal_index, self._config['get_temperature'], Common.NULL_VAL) + return float(output) if output != Common.NULL_VAL else output + + def get_high_threshold(self): + """ + Retrieves the high threshold temperature of thermal + Returns: + A float number, the high threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + output = self._api_common.get_output( + self._thermal_index, self._config['get_high_threshold'], Common.NULL_VAL) + return float(output) if output != Common.NULL_VAL else output + + def get_low_threshold(self): + """ + Retrieves the low threshold temperature of thermal + + Returns: + lnc as float number and return 0 if the BMC output is na. + A float number, the low threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + output = self._api_common.get_output( + self._thermal_index, self._config['get_low_threshold'], Common.NULL_VAL) + return float(output) if output != Common.NULL_VAL else output + + def set_high_threshold(self, temperature): + """ + Sets the high threshold temperature of thermal + + For AMI BMC device : + use ipmitool command + ipmitool sensor thresh [sensor name] unc [0>= temp_value <=62] + if the current value of unc is 'na' ipmitool can't be set the value + + Args : + temperature: A float number up to nearest thousandth of one degree Celsius, + e.g. 30.125 + + Returns: + A boolean, True if threshold is set successfully, False if not + """ + output = self._api_common.get_output( + self._thermal_index, self._config['set_high_threshold'], Common.NULL_VAL) + return float(output) if output != Common.NULL_VAL else output + + def set_low_threshold(self, temperature): + """ + Sets the low threshold temperature of thermal + + For AMI BMC device : + use ipmitool command + ipmitool sensor thresh [sensor name] lnc [temp_value] + if the current value of lnc is 'na' ipmitool can't be set the value + + Args : + temperature: A float number up to nearest thousandth of one degree Celsius, + e.g. 30.125 + + Returns: + A boolean, True if threshold is set successfully, False if not + """ + output = self._api_common.get_output( + self._thermal_index, self._config['set_low_threshold'], Common.NULL_VAL) + return float(output) if output != Common.NULL_VAL else output + + def get_high_critical_threshold(self): + """ + Retrieves the high critical threshold temperature of thermal + + Returns: + ucr as float number and return 0 if the BMC output is na. + A float number, the high critical threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + output = self._api_common.get_output( + self._thermal_index, self._config['get_high_critical_threshold'], Common.NULL_VAL) + return float(output) if output != Common.NULL_VAL else output + + def get_low_critical_threshold(self): + """ + Retrieves the low critical threshold temperature of thermal + + Returns: + lnr as float number and return 0 if the BMC output is na. + A float number, the low critical threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + output = self._api_common.get_output( + self._thermal_index, self._config['get_low_critical_threshold'], Common.NULL_VAL) + return float(output) if output != Common.NULL_VAL else output + + def get_presence(self): + """ + Retrieves the presence of the device + Returns: + bool: True if device is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + + Returns: + string: Model/part number of device + """ + return Common.NULL_VAL + + def get_serial(self): + """ + Retrieves the serial number of the device + + Returns: + string: Serial number of device + """ + return Common.NULL_VAL + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + return True diff --git a/platform/broadcom/sonic-platform-modules-dell/.gitignore b/platform/broadcom/sonic-platform-modules-dell/.gitignore index 7f287d538227..f62ae4876450 100644 --- a/platform/broadcom/sonic-platform-modules-dell/.gitignore +++ b/platform/broadcom/sonic-platform-modules-dell/.gitignore @@ -48,3 +48,6 @@ dkms.conf *.postrm.debhelper *.prerm.debhelper *.substvars + +# Cloned source repositories +tools/flashrom/ diff --git a/platform/broadcom/sonic-platform-modules-dell/common/dell_ich.c b/platform/broadcom/sonic-platform-modules-dell/common/dell_ich.c index cce36e9056fa..eb164e46fac5 100644 --- a/platform/broadcom/sonic-platform-modules-dell/common/dell_ich.c +++ b/platform/broadcom/sonic-platform-modules-dell/common/dell_ich.c @@ -926,7 +926,7 @@ static int dell_ich_remove(struct platform_device *pdev) // Unmap and release PMC regions if(ich_data->pmc_base) iounmap(ich_data->pmc_base); - if(ich_data->pmc_alloc) release_region(pmc_res.start, PMC_REG_LEN); + if(ich_data->pmc_alloc) release_mem_region(pmc_res.start, PMC_REG_LEN); ret = acpi_remove_sci_handler(dell_ich_sci_handler); if(ret) { 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 e8cddf4fad11..5712c0fbb552 100644 --- a/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c +++ b/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c @@ -174,6 +174,15 @@ /* Mailbox PowerOn Reason */ #define TRACK_POWERON_REASON 0x05FF +/* System Status LED */ +#define SYSTEM_STATUS_LED 0x04DF + +/* CPU Set IO Modules */ +#define CPU_IOM1_CTRL_FLAG 0x04D9 +#define CPU_IOM2_CTRL_FLAG 0x04DA +#define CPU_IOM3_CTRL_FLAG 0x04DB +#define CPU_IOM4_CTRL_FLAG 0x04DC + unsigned long *mmio; static struct kobject *dell_kobj; @@ -601,6 +610,44 @@ static ssize_t show_mb_poweron_reason(struct device *dev, return sprintf(buf, "0x%x\n", ret); } +/* System Status LED */ +static ssize_t set_sys_status_led(struct device *dev, + struct device_attribute *devattr, const char *buf, size_t count) +{ + int err = 0; + unsigned int dev_data = 0; + struct smf_data *data = dev_get_drvdata(dev); + + if (data->kind == z9100smf) + return -1; + + err = kstrtouint(buf, 16, &dev_data); + if (err) + return err; + + err = smf_write_reg(data, SYSTEM_STATUS_LED, dev_data); + if(err < 0) + return err; + + return count; +} + +static ssize_t show_sys_status_led(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + unsigned int ret = 0; + struct smf_data *data = dev_get_drvdata(dev); + + if (data->kind == z9100smf) + return 0; + + ret = smf_read_reg(data, SYSTEM_STATUS_LED); + if(ret < 0) + return ret; + + return sprintf(buf, "0x%x\n", ret); +} + /* FANIN ATTR */ static ssize_t show_fan_label(struct device *dev, struct device_attribute *attr, char *buf) @@ -712,18 +759,13 @@ static ssize_t show_fan_airflow(struct device *dev, { int index = to_sensor_dev_attr(devattr)->index; struct smf_data *data = dev_get_drvdata(dev); - int ret=1, fan_airflow; + int ret, fan_airflow; if (data->kind == s6100smf && index == FAN_TRAY_5) return 0; fan_airflow = smf_read_reg(data, FAN_TRAY_AIRFLOW); - - if (fan_airflow & (1 << (index))) - ret=1; - - if (ret < 0) - return ret; + ret = (fan_airflow >> index) & 1; return sprintf(buf, "%d\n", ret); } @@ -752,6 +794,25 @@ static ssize_t show_psu_fan(struct device *dev, return sprintf(buf, "%d\n", ret); } +static ssize_t show_cpu_iom_control(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int index = to_sensor_dev_attr(devattr)->index; + struct smf_data *data = dev_get_drvdata(dev); + int cpu_iom_status; + + if(index == 0) + cpu_iom_status = smf_read_reg(data, CPU_IOM1_CTRL_FLAG); + else if (index == 1) + cpu_iom_status = smf_read_reg(data, CPU_IOM2_CTRL_FLAG); + else if (index == 2) + cpu_iom_status = smf_read_reg(data, CPU_IOM3_CTRL_FLAG); + else if (index == 3) + cpu_iom_status = smf_read_reg(data, CPU_IOM4_CTRL_FLAG); + + return sprintf(buf, "%x\n", cpu_iom_status); +} + static umode_t smf_fanin_is_visible(struct kobject *kobj, @@ -1785,6 +1846,16 @@ static ssize_t show_psu(struct device *dev, } ret = pow/10; break; + case 11: + psu_status = smf_read_reg(data, PSU_1_STATUS); + if (psu_status &(2)) + ret=1; + break; + case 12: + psu_status = smf_read_reg(data, PSU_2_STATUS); + if (psu_status &(2)) + ret=1; + break; default: return ret; } @@ -2023,10 +2094,17 @@ static SENSOR_DEVICE_ATTR(fan9_serialno, S_IRUGO, show_ppid, NULL, 4); static SENSOR_DEVICE_ATTR(iom_status, S_IRUGO, show_voltage, NULL, 44); static SENSOR_DEVICE_ATTR(iom_presence, S_IRUGO, show_voltage, NULL, 45); +static SENSOR_DEVICE_ATTR(cpu_iom1_control, S_IRUGO, show_cpu_iom_control, NULL, 0); +static SENSOR_DEVICE_ATTR(cpu_iom2_control, S_IRUGO, show_cpu_iom_control, NULL, 1); +static SENSOR_DEVICE_ATTR(cpu_iom3_control, S_IRUGO, show_cpu_iom_control, NULL, 2); +static SENSOR_DEVICE_ATTR(cpu_iom4_control, S_IRUGO, show_cpu_iom_control, NULL, 3); + static SENSOR_DEVICE_ATTR(psu1_presence, S_IRUGO, show_psu, NULL, 1); static SENSOR_DEVICE_ATTR(psu2_presence, S_IRUGO, show_psu, NULL, 6); static SENSOR_DEVICE_ATTR(psu1_serialno, S_IRUGO, show_ppid, NULL, 10); static SENSOR_DEVICE_ATTR(psu2_serialno, S_IRUGO, show_ppid, NULL, 11); +static SENSOR_DEVICE_ATTR(psu1_type, S_IRUGO, show_psu, NULL, 11); +static SENSOR_DEVICE_ATTR(psu2_type, S_IRUGO, show_psu, NULL, 12); static SENSOR_DEVICE_ATTR(current_total_power, S_IRUGO, show_psu, NULL, 10); /* SMF Version */ @@ -2044,12 +2122,17 @@ static SENSOR_DEVICE_ATTR(smf_poweron_reason, S_IRUGO, static SENSOR_DEVICE_ATTR(mb_poweron_reason, S_IRUGO|S_IWUSR, show_mb_poweron_reason, set_mb_poweron_reason, 0); +/* System Status LED */ +static SENSOR_DEVICE_ATTR(sys_status_led, S_IRUGO|S_IWUSR, + show_sys_status_led, set_sys_status_led, 0); + static struct attribute *smf_dell_attrs[] = { &sensor_dev_attr_smf_version.dev_attr.attr, &sensor_dev_attr_smf_firmware_ver.dev_attr.attr, &sensor_dev_attr_smf_reset_reason.dev_attr.attr, &sensor_dev_attr_smf_poweron_reason.dev_attr.attr, &sensor_dev_attr_mb_poweron_reason.dev_attr.attr, + &sensor_dev_attr_sys_status_led.dev_attr.attr, &sensor_dev_attr_fan_tray_presence.dev_attr.attr, &sensor_dev_attr_fan1_airflow.dev_attr.attr, &sensor_dev_attr_fan3_airflow.dev_attr.attr, @@ -2070,6 +2153,10 @@ static struct attribute *smf_dell_attrs[] = { &sensor_dev_attr_fan7_serialno.dev_attr.attr, &sensor_dev_attr_fan9_serialno.dev_attr.attr, &sensor_dev_attr_current_total_power.dev_attr.attr, + &sensor_dev_attr_cpu_iom1_control.dev_attr.attr, + &sensor_dev_attr_cpu_iom2_control.dev_attr.attr, + &sensor_dev_attr_cpu_iom3_control.dev_attr.attr, + &sensor_dev_attr_cpu_iom4_control.dev_attr.attr, NULL }; diff --git a/platform/broadcom/sonic-platform-modules-dell/common/fw-updater b/platform/broadcom/sonic-platform-modules-dell/common/fw-updater index 6905664672ad..baed0565234e 100755 --- a/platform/broadcom/sonic-platform-modules-dell/common/fw-updater +++ b/platform/broadcom/sonic-platform-modules-dell/common/fw-updater @@ -1,24 +1,21 @@ -#!/usr/bin/python +#!/usr/bin/python3 # dell staging fw updater script import os -import sys import subprocess import argparse -onie_boot_folder = '/mnt/onie-boot/onie/tools/bin/onie-fwpkg' -onie_fwpkg_tool = '/mnt/onie-boot/onie/tools/bin/onie-fwpkg' +onie_boot_folder = '/mnt/onie-boot/onie/tools/bin/onie-fwpkg' +onie_fwpkg_tool = '/mnt/onie-boot/onie/tools/bin/onie-fwpkg' ONIE_BOOT_MODE_CMD = '/mnt/onie-boot/onie/tools/bin/onie-boot-mode' HOST_GRUB_DIR = '/host' HOST_GRUB_CFG = HOST_GRUB_DIR + '/grub/grub.cfg' HOST_GRUB_ENV = HOST_GRUB_DIR + '/grub/grubenv' HOST_GRUB_BOOT_DIR = '--boot-directory=' + HOST_GRUB_DIR HOST_PLATFORM_INFO = HOST_GRUB_DIR + '/platform' -dell_reload_tool = '/usr/bin/reboot' - - +dell_reload_tool = '/usr/local/bin/reboot' def set_onie_mode(option): @@ -30,12 +27,12 @@ def set_onie_fw_update_env(): """Select the ONIE boot mode, and set the next_entry to point to ONIE""" if not os.path.exists(onie_boot_folder): - os.makedirs(onie_boot_folder) + os.makedirs(onie_boot_folder) try: - subprocess.check_call(['mount','/dev/disk/by-label/ONIE-BOOT','/mnt/onie-boot']) + subprocess.check_call(['mount', '/dev/disk/by-label/ONIE-BOOT', '/mnt/onie-boot']) except: - print "onie-boot not able to mount" + print("onie-boot not able to mount") def _set_env_option(option, value): """Set an option in the GRUB environment block. Pass None to value to @@ -53,32 +50,32 @@ def _set_env_option(option, value): def dell_firmware_update_staging(image_name): try: - p = subprocess.Popen([onie_fwpkg_tool,"purge"],stdout=subprocess.PIPE,stdin=subprocess.PIPE) + p = subprocess.Popen([onie_fwpkg_tool, "purge"], stdout=subprocess.PIPE, stdin=subprocess.PIPE) p.communicate("y") except: - print "onie-fwpkg command not found for purging old fw updates" + print("onie-fwpkg command not found for purging old fw updates") try: - subprocess.check_call([onie_fwpkg_tool,"add", str(image_name)]) + subprocess.check_call([onie_fwpkg_tool, "add", str(image_name)]) except: - print "onie-fwpkg is not found to stage fw updates" + print("onie-fwpkg is not found to stage fw updates") try: set_onie_mode("update") except: - print "dell-image command not found" + print("dell-image command not found") try: subprocess.check_call([dell_reload_tool]) except: - print "reload command not found" + print("reload command not found") if __name__ == '__main__': parser = argparse.ArgumentParser(description='Dell HOST Firmware updates') opts = parser.add_mutually_exclusive_group(required=True) opts.add_argument('-u', '--update', nargs=1, metavar='IMAGE', - help='update specified image') + help='update specified image') args = parser.parse_args() @@ -88,4 +85,3 @@ if __name__ == '__main__': if args.update: set_onie_fw_update_env() dell_firmware_update_staging(args.update[0]) - diff --git a/platform/broadcom/sonic-platform-modules-dell/common/io_rd_wr.py b/platform/broadcom/sonic-platform-modules-dell/common/io_rd_wr.py index dc9dd09807c2..a8bb096521be 100755 --- a/platform/broadcom/sonic-platform-modules-dell/common/io_rd_wr.py +++ b/platform/broadcom/sonic-platform-modules-dell/common/io_rd_wr.py @@ -1,45 +1,45 @@ -#!/usr/bin/python -#Script to read/write the io based registers +#!/usr/bin/python3 +# Script to read/write the io based registers import sys import os import getopt import struct -io_resource='/dev/port' +io_resource = '/dev/port' def usage(): ''' This is the Usage Method ''' - print 'Utility for IO read/write' - print '\t\t io_rd_wr.py --get --offset ' - print '\t\t io_rd_wr.py --set --val --offset ' + print('Utility for IO read/write') + print('\t\t io_rd_wr.py --get --offset ') + print('\t\t io_rd_wr.py --set --val --offset ') sys.exit(1) -def io_reg_read(io_resource,offset): - fd=os.open(io_resource, os.O_RDONLY) - if(fd<0): - print 'file open failed %s"%io_resource' +def io_reg_read(io_resource, offset): + fd = os.open(io_resource, os.O_RDONLY) + if(fd < 0): + print('file open failed %s' % io_resource) return if(os.lseek(fd, offset, os.SEEK_SET) != offset): - print 'lseek failed on %s'%io_resource + print('lseek failed on %s' % io_resource) return - buf=os.read(fd,1) - reg_val1=ord(buf) - print 'reg value %x'%reg_val1 + buf = os.read(fd, 1) + reg_val1 = ord(buf) + print('reg value %x' % reg_val1) os.close(fd) -def io_reg_write(io_resource,offset,val): - fd=os.open(io_resource,os.O_RDWR) - if(fd<0): - print 'file open failed %s"%io_resource' +def io_reg_write(io_resource, offset, val): + fd = os.open(io_resource, os.O_RDWR) + if(fd < 0): + print('file open failed %s' % io_resource) return if(os.lseek(fd, offset, os.SEEK_SET) != offset): - print 'lseek failed on %s'%io_resource + print('lseek failed on %s' % io_resource) return - ret=os.write(fd,struct.pack('B',val)) + ret = os.write(fd, struct.pack('B', val)) if(ret != 1): - print 'write failed %d'%ret + print('write failed %d' % ret) return os.close(fd) @@ -51,19 +51,17 @@ def main(argv): opts = '' val = '' choice = '' - resouce = '' offset = '' try: - opts, args = getopt.getopt(argv, "hgs:" , \ - ["val=","offset=","help", "get", "set"]) - + opts, args = getopt.getopt(argv, "hgs:", + ["val=", "offset=", "help", "get", "set"]) except getopt.GetoptError: usage() - for opt,arg in opts: + for opt, arg in opts: - if opt in ('-h','--help'): + if opt in ('-h', '--help'): choice = 'help' elif opt in ('-g', '--get'): @@ -72,22 +70,21 @@ def main(argv): elif opt in ('-s', '--set'): choice = 'set' - elif opt == '--offset': - offset = int(arg,16) + elif opt == '--offset': + offset = int(arg, 16) - elif opt == '--val': - val = int(arg,16) + elif opt == '--val': + val = int(arg, 16) if choice == 'get' and offset != '': - io_reg_read(io_resource,offset) + io_reg_read(io_resource, offset) elif choice == 'set' and offset != '' and val != '': - io_reg_write(io_resource,offset,val) + io_reg_write(io_resource, offset, val) else: usage() -#Calling the main method +# Calling the main method if __name__ == "__main__": main(sys.argv[1:]) - diff --git a/platform/broadcom/sonic-platform-modules-dell/common/ipmihelper.py b/platform/broadcom/sonic-platform-modules-dell/common/ipmihelper.py index 182d74c218cf..d95329c40de2 100644 --- a/platform/broadcom/sonic-platform-modules-dell/common/ipmihelper.py +++ b/platform/broadcom/sonic-platform-modules-dell/common/ipmihelper.py @@ -1,4 +1,4 @@ -#! /usr/bin/python +#!/usr/bin/python3 ######################################################################## # DellEMC @@ -23,6 +23,29 @@ # IPMI FRU Device Commands Cmd_ReadFRUData = 0x11 +def get_ipmitool_raw_output(args): + """ + Returns a list the elements of which are the individual bytes of + ipmitool raw command output. + """ + result_bytes = list() + result = "" + command = "ipmitool raw {}".format(args) + try: + proc = subprocess.Popen(command.split(), stdout=subprocess.PIPE, + universal_newlines=True, stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + if not proc.returncode: + result = stdout.rstrip('\n') + except EnvironmentError: + pass + + for i in result.split(): + result_bytes.append(int(i, 16)) + + return result_bytes + class IpmiSensor(object): # Sensor Threshold types and their respective bit masks @@ -39,29 +62,6 @@ def __init__(self, sensor_id, is_discrete=False): self.id = sensor_id self.is_discrete = is_discrete - def _get_ipmitool_raw_output(self, args): - """ - Returns a list the elements of which are the individual bytes of - ipmitool raw command output. - """ - result_bytes = list() - result = "" - command = "ipmitool raw {}".format(args) - try: - proc = subprocess.Popen(command.split(), stdout=subprocess.PIPE, - stderr=subprocess.STDOUT) - stdout = proc.communicate()[0] - proc.wait() - if not proc.returncode: - result = stdout.rstrip('\n') - except: - pass - - for i in result.split(): - result_bytes.append(int(i, 16)) - - return result_bytes - def _get_converted_sensor_reading(self, raw_value): """ Returns a 2 element tuple(bool, int) in which first element @@ -72,7 +72,7 @@ def _get_converted_sensor_reading(self, raw_value): cmd_args = "{} {} {} {}".format(NetFn_SensorEvent, Cmd_GetSensorReadingFactors, self.id, raw_value) - factors = self._get_ipmitool_raw_output(cmd_args) + factors = get_ipmitool_raw_output(cmd_args) if len(factors) != 7: return False, 0 @@ -107,7 +107,7 @@ def get_reading(self): # Get Sensor Reading cmd_args = "{} {} {}".format(NetFn_SensorEvent, Cmd_GetSensorReading, self.id) - output = self._get_ipmitool_raw_output(cmd_args) + output = get_ipmitool_raw_output(cmd_args) if len(output) != 4: return False, 0 @@ -144,17 +144,17 @@ def get_threshold(self, threshold_type): if self.is_discrete: raise TypeError("Threshold is not applicable for Discrete Sensor") - if threshold_type not in self.THRESHOLD_BIT_MASK.keys(): + if threshold_type not in list(self.THRESHOLD_BIT_MASK.keys()): raise ValueError("Invalid threshold type {} provided. Valid types " "are {}".format(threshold_type, - self.THRESHOLD_BIT_MASK.keys())) + list(self.THRESHOLD_BIT_MASK.keys()))) bit_mask = self.THRESHOLD_BIT_MASK[threshold_type] # Get Sensor Threshold cmd_args = "{} {} {}".format(NetFn_SensorEvent, Cmd_GetSensorThreshold, self.id) - thresholds = self._get_ipmitool_raw_output(cmd_args) + thresholds = get_ipmitool_raw_output(cmd_args) if len(thresholds) != 7: return False, 0 @@ -175,43 +175,53 @@ def _get_ipmitool_fru_print(self): command = "ipmitool fru print {}".format(self.id) try: proc = subprocess.Popen(command.split(), stdout=subprocess.PIPE, - stderr=subprocess.STDOUT) + universal_newlines=True, stderr=subprocess.STDOUT) stdout = proc.communicate()[0] proc.wait() if not proc.returncode: result = stdout.rstrip('\n') - except: + except EnvironmentError: pass return result - def get_board_serial(self): + def _get_from_fru(self, info): """ - Returns a string containing the Serial Number of the device. + Returns a string containing the info from FRU """ fru_output = self._get_ipmitool_fru_print() if not fru_output: return "NA" - board_serial = re.search(r'Board Serial\s*:(.*)', fru_output) - if not board_serial: + info_req = re.search(r"%s\s*:(.*)" % info, fru_output) + if not info_req: return "NA" - return board_serial.group(1).strip() + return info_req.group(1).strip() + + def get_board_serial(self): + """ + Returns a string containing the Serial Number of the device. + """ + return self._get_from_fru('Board Serial') def get_board_part_number(self): """ Returns a string containing the Part Number of the device. """ - fru_output = self._get_ipmitool_fru_print() - if not fru_output: - return "NA" + return self._get_from_fru('Board Part Number') - board_pn = re.search(r'Board Part Number\s*:(.*)', fru_output) - if not board_pn: - return "NA" + def get_board_mfr_id(self): + """ + Returns a string containing the manufacturer id of the FRU. + """ + return self._get_from_fru('Board Mfg') - return board_pn.group(1).strip() + def get_board_product(self): + """ + Returns a string containing the manufacturer id of the FRU. + """ + return self._get_from_fru('Board Product') def get_fru_data(self, offset, count=1): """ @@ -238,12 +248,12 @@ def get_fru_data(self, offset, count=1): offset_MSB, count) try: proc = subprocess.Popen(command.split(), stdout=subprocess.PIPE, - stderr=subprocess.STDOUT) + universal_newlines=True, stderr=subprocess.STDOUT) stdout = proc.communicate()[0] proc.wait() if not proc.returncode: result = stdout.rstrip('\n') - except: + except EnvironmentError: is_valid = False if (not result) or (not is_valid): diff --git a/platform/broadcom/sonic-platform-modules-dell/common/nvram_rd_wr.py b/platform/broadcom/sonic-platform-modules-dell/common/nvram_rd_wr.py index 30108892741b..527c531ddfb4 100755 --- a/platform/broadcom/sonic-platform-modules-dell/common/nvram_rd_wr.py +++ b/platform/broadcom/sonic-platform-modules-dell/common/nvram_rd_wr.py @@ -1,45 +1,45 @@ -#!/usr/bin/python -#Script to read/write the nvram +#!/usr/bin/python3 +# Script to read/write the nvram import sys import os import getopt import struct -nvram_resource='/dev/nvram' +nvram_resource = '/dev/nvram' def usage(): ''' This is the Usage Method ''' - print 'Utility for NVRAM read/write' - print '\t\t nvram_rd_wr.py --get --offset ' - print '\t\t nvram_rd_wr.py --set --val --offset ' + print('Utility for NVRAM read/write') + print('\t\t nvram_rd_wr.py --get --offset ') + print('\t\t nvram_rd_wr.py --set --val --offset ') sys.exit(1) -def nvram_reg_read(nvram_resource,offset): - fd=os.open(nvram_resource, os.O_RDONLY) - if(fd<0): - print 'file open failed %s"%nvram_resource' +def nvram_reg_read(nvram_resource, offset): + fd = os.open(nvram_resource, os.O_RDONLY) + if(fd < 0): + print('file open failed %s' % nvram_resource) return if(os.lseek(fd, offset, os.SEEK_SET) != offset): - print 'lseek failed on %s'%nvram_resource + print('lseek failed on %s' % nvram_resource) return - buf=os.read(fd,1) - reg_val1=ord(buf) - print 'value %x'%reg_val1 + buf = os.read(fd, 1) + reg_val1 = ord(buf) + print('value %x' % reg_val1) os.close(fd) -def nvram_reg_write(nvram_resource,offset,val): - fd=os.open(nvram_resource,os.O_RDWR) - if(fd<0): - print 'file open failed %s"%nvram_resource' +def nvram_reg_write(nvram_resource, offset, val): + fd = os.open(nvram_resource, os.O_RDWR) + if(fd < 0): + print('file open failed %s' % nvram_resource) return if(os.lseek(fd, offset, os.SEEK_SET) != offset): - print 'lseek failed on %s'%nvram_resource + print('lseek failed on %s' % nvram_resource) return - ret=os.write(fd,struct.pack('B',val)) + ret = os.write(fd, struct.pack('B', val)) if(ret != 1): - print 'write failed %d'%ret + print('write failed %d' % ret) return os.close(fd) @@ -51,23 +51,21 @@ def main(argv): opts = '' val = '' choice = '' - resouce = '' offset = '' try: - opts, args = getopt.getopt(argv, "hgs:" , \ - ["val=","offset=","help", "get", "set"]) - + opts, args = getopt.getopt(argv, "hgs:", + ["val=", "offset=", "help", "get", "set"]) except getopt.GetoptError: usage() if not os.path.exists(nvram_resource): - print 'NVRAM is not initialized' + print('NVRAM is not initialized') sys.exit(1) - for opt,arg in opts: + for opt, arg in opts: - if opt in ('-h','--help'): + if opt in ('-h', '--help'): choice = 'help' elif opt in ('-g', '--get'): @@ -76,22 +74,21 @@ def main(argv): elif opt in ('-s', '--set'): choice = 'set' - elif opt == '--offset': - offset = int(arg,16) - 0xE + elif opt == '--offset': + offset = int(arg, 16) - 0xE - elif opt == '--val': - val = int(arg,16) + elif opt == '--val': + val = int(arg, 16) if choice == 'get' and offset != '': - nvram_reg_read(nvram_resource,offset) + nvram_reg_read(nvram_resource, offset) elif choice == 'set' and offset != '' and val != '': - nvram_reg_write(nvram_resource,offset,val) + nvram_reg_write(nvram_resource, offset, val) else: usage() -#Calling the main method +# Calling the main method if __name__ == "__main__": main(sys.argv[1:]) - diff --git a/platform/broadcom/sonic-platform-modules-dell/common/pcisysfs.py b/platform/broadcom/sonic-platform-modules-dell/common/pcisysfs.py new file mode 100755 index 000000000000..b305f54eca86 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/common/pcisysfs.py @@ -0,0 +1,105 @@ +#!/usr/bin/python3 +# Copyright (c) 2015 Dell Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +# +# THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT +# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS +# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. +# +# See the Apache Version 2.0 License for specific language governing +# permissions and limitations under the License. + +import struct +import sys +import getopt +from os import * +from mmap import * + +def usage(): + ''' This is the Usage Method ''' + + print('\t\t pcisysfs.py --get --offset --res ') + print('\t\t pcisysfs.py --set --val --offset --res ') + sys.exit(1) + +def pci_mem_read(mm, offset): + mm.seek(offset) + read_data_stream = mm.read(4) + print("") + reg_val = struct.unpack('I', read_data_stream) + print("reg_val read:%x" % reg_val) + return reg_val + +def pci_mem_write(mm, offset, data): + mm.seek(offset) + print("data to write:%x" % data) + mm.write(struct.pack('I', data)) + +def pci_set_value(resource, val, offset): + fd = open(resource, O_RDWR) + mm = mmap(fd, 0) + pci_mem_write(mm, offset, val) + mm.close() + close(fd) + +def pci_get_value(resource, offset): + fd = open(resource, O_RDWR) + mm = mmap(fd, 0) + pci_mem_read(mm, offset) + mm.close() + close(fd) + +def main(argv): + + ''' The main function will read the user input from the + command line argument and process the request ''' + + opts = '' + val = '' + choice = '' + resource = '' + offset = '' + + try: + opts, args = getopt.getopt(argv, "hgsv:", + ["val=", "res=", "offset=", "help", "get", "set"]) + + except getopt.GetoptError: + usage() + + for opt, arg in opts: + + if opt in ('-h', '--help'): + choice = 'help' + + elif opt in ('-g', '--get'): + choice = 'get' + + elif opt in ('-s', '--set'): + choice = 'set' + + elif opt == '--res': + resource = arg + + elif opt == '--val': + val = int(arg, 16) + + elif opt == '--offset': + offset = int(arg, 16) + + if choice == 'set' and val != '' and offset != '' and resource != '': + pci_set_value(resource, val, offset) + + elif choice == 'get' and offset != '' and resource != '': + pci_get_value(resource, offset) + + else: + usage() + +# Calling the main method +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/platform/broadcom/sonic-platform-modules-dell/common/platform_reboot b/platform/broadcom/sonic-platform-modules-dell/common/platform_reboot index 3e165630658b..ca04ac0635a7 100755 --- a/platform/broadcom/sonic-platform-modules-dell/common/platform_reboot +++ b/platform/broadcom/sonic-platform-modules-dell/common/platform_reboot @@ -1,5 +1,4 @@ -#!/usr/bin/python -import sys +#!/usr/bin/python3 import os import struct @@ -9,17 +8,16 @@ PORT_RES = '/dev/port' def portio_reg_write(resource, offset, val): fd = os.open(resource, os.O_RDWR) if(fd < 0): - print 'file open failed %s" % resource' + print('file open failed %s' % resource) return if(os.lseek(fd, offset, os.SEEK_SET) != offset): - print 'lseek failed on %s' % resource + print('lseek failed on %s' % resource) return ret = os.write(fd, struct.pack('B', val)) if(ret != 1): - print 'write failed %d' % ret + print('write failed %d' % ret) return os.close(fd) if __name__ == "__main__": portio_reg_write(PORT_RES, 0xcf9, 0xe) - diff --git a/platform/broadcom/sonic-platform-modules-dell/common/sonic_platform/hwaccess.py b/platform/broadcom/sonic-platform-modules-dell/common/sonic_platform/hwaccess.py new file mode 100644 index 000000000000..567669d36fc0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/common/sonic_platform/hwaccess.py @@ -0,0 +1,53 @@ +# Helper functions to access hardware + +import os +import struct +import mmap +import subprocess + +# Read PCI device + +def pci_mem_read(mm, offset): + mm.seek(offset) + read_data_stream = mm.read(4) + return struct.unpack('I',read_data_stream)[0] + +def pci_get_value(resource, offset): + with open(resource, 'r+b') as fd: + mm = mmap.mmap(fd.fileno(), 0) + val = pci_mem_read(mm, offset) + mm.close() + return val + +# Read I2C device + +def i2c_get(bus, i2caddr, ofs): + return int(subprocess.check_output(['/usr/sbin/i2cget', '-y', str(bus), str(i2caddr), str(ofs)]), 16) + +def io_reg_read(io_resource, offset): + fd = os.open(io_resource, os.O_RDONLY) + if fd < 0: + print('file open failed %s' % io_resource) + return -1 + if os.lseek(fd, offset, os.SEEK_SET) != offset: + print('lseek failed on %s' % io_resource) + return -1 + buf = os.read(fd, 1) + reg_val1 = ord(buf) + os.close(fd) + return reg_val1 + +def io_reg_write(io_resource, offset, val): + fd = os.open(io_resource, os.O_RDWR) + if fd < 0: + print('file open failed %s' % io_resource) + return False + if os.lseek(fd, offset, os.SEEK_SET) != offset: + print('lseek failed on %s' % io_resource) + return False + ret = os.write(fd, struct.pack('B', val)) + if ret != 1: + print('write failed %d' % ret) + return False + os.close(fd) + return True diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/control b/platform/broadcom/sonic-platform-modules-dell/debian/control index e4d5a24f3542..2920602fcd60 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/control +++ b/platform/broadcom/sonic-platform-modules-dell/debian/control @@ -7,35 +7,40 @@ Standards-Version: 3.9.3 Package: platform-modules-s6000 Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-z9100 Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-s6100 Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-z9264f Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-s5232f Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-s5248f Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-z9332f Architecture: amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned +Description: kernel modules for platform devices such as fan, led, sfp + +Package: platform-modules-s5296f +Architecture: amd64 Depends: linux-image-4.9.0-9-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5232f.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5232f.install index 303e978848db..25d2b84ad4ac 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5232f.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5232f.install @@ -2,10 +2,12 @@ s5232f/scripts/s5232f_platform.sh usr/local/bin s5232f/scripts/check_qsfp.sh usr/local/bin s5232f/scripts/platform_sensors.py usr/local/bin s5232f/scripts/sensors usr/bin -s5232f/scripts/pcisysfs.py usr/bin s5232f/scripts/qsfp_irq_enable.py usr/bin s5232f/cfg/s5232f-modules.conf etc/modules-load.d s5232f/systemd/platform-modules-s5232f.service etc/systemd/system +s5232f/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-dellemc_s5232f_c3538-r0 +s5232f/modules/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/x86_64-dellemc_s5232f_c3538-r0 common/platform_reboot usr/share/sonic/device/x86_64-dellemc_s5232f_c3538-r0 common/fw-updater usr/local/bin common/onie_mode_set usr/local/bin +common/pcisysfs.py usr/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.install index e87ea7e37b4e..6e74fbec0ae5 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.install @@ -2,10 +2,10 @@ s5248f/scripts/s5248f_platform.sh usr/local/bin s5248f/scripts/check_qsfp.sh usr/local/bin s5248f/scripts/platform_sensors.py usr/local/bin s5248f/scripts/sensors usr/bin -s5248f/scripts/pcisysfs.py usr/bin s5248f/scripts/qsfp_irq_enable.py usr/bin s5248f/cfg/s5248f-modules.conf etc/modules-load.d s5248f/systemd/platform-modules-s5248f.service etc/systemd/system common/platform_reboot usr/share/sonic/device/x86_64-dellemc_s5248f_c3538-r0 common/fw-updater usr/local/bin common/onie_mode_set usr/local/bin +common/pcisysfs.py usr/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5296f.init b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5296f.init new file mode 100755 index 000000000000..9276679ef004 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5296f.init @@ -0,0 +1,39 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: setup-board +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Setup S5296f board. +### END INIT INFO + +case "$1" in +start) + echo -n "Setting up board... " + + # /usr/local/bin/iom_power_on.sh + /usr/local/bin/s5296f_platform.sh init + + echo "done." + ;; + +stop) + /usr/local/bin/s5296f_platform.sh deinit + echo "done." + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/platform-modules-s5296f.init {start|stop}" + exit 1 + ;; +esac + +exit 0 diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5296f.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5296f.install new file mode 100644 index 000000000000..497554a476c1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5296f.install @@ -0,0 +1,9 @@ +s5296f/scripts/s5296f_platform.sh usr/local/bin +s5296f/scripts/platform_sensors.py usr/local/bin +s5296f/scripts/sensors usr/bin +s5296f/scripts/pcisysfs.py usr/bin +s5296f/cfg/s5296f-modules.conf etc/modules-load.d +s5296f/systemd/platform-modules-s5296f.service etc/systemd/system +common/platform_reboot usr/share/sonic/device/x86_64-dellemc_s5296f_c3538-r0 +common/fw-updater usr/local/bin +common/onie_mode_set usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5296f.postinst b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5296f.postinst new file mode 100644 index 000000000000..21772eafdd02 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5296f.postinst @@ -0,0 +1,10 @@ +# postinst script for S5296f + +# Enable Dell-S5296f-platform-service +depmod -a +systemctl enable platform-modules-s5296f.service +systemctl start platform-modules-s5296f.service + + +#DEBHELPER# + 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 f662e751a3f8..d87efb31c488 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 @@ -6,3 +6,4 @@ 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 +s6000/modules/sonic_platform-1.0-py3-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-s6100.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install index a08f782bdfad..a9eb63eeea45 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install @@ -1,5 +1,8 @@ s6100/scripts/iom_power_*.sh usr/local/bin s6100/scripts/s6100_platform.sh usr/local/bin +s6100/scripts/s6100_i2c_enumeration.sh usr/local/bin +s6100/scripts/s6100_bitbang_reset.sh usr/local/bin +s6100/scripts/pcisysfs.py usr/bin common/dell_i2c_utils.sh usr/local/bin common/io_rd_wr.py usr/local/bin common/nvram_rd_wr.py usr/local/bin @@ -7,16 +10,19 @@ s6100/scripts/platform_reboot_override usr/share/sonic/device/x86_64-dell_s6100_ s6100/scripts/fast-reboot_plugin usr/share/sonic/device/x86_64-dell_s6100_c2538-r0 s6100/scripts/track_reboot_reason.sh usr/share/sonic/device/x86_64-dell_s6100_c2538-r0 s6100/scripts/warm-reboot_plugin usr/share/sonic/device/x86_64-dell_s6100_c2538-r0 +s6100/scripts/ssd-fw-upgrade usr/share/sonic/device/x86_64-dell_s6100_c2538-r0 s6100/scripts/override.conf /etc/systemd/system/systemd-reboot.service.d common/dell_lpc_mon.sh usr/local/bin s6100/scripts/platform_sensors.py usr/local/bin s6100/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-dell_s6100_c2538-r0 +s6100/modules/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/x86_64-dell_s6100_c2538-r0 s6100/scripts/platform_watchdog_enable.sh usr/local/bin s6100/scripts/platform_watchdog_disable.sh usr/local/bin s6100/scripts/sensors usr/bin s6100/systemd/platform-modules-s6100.service etc/systemd/system s6100/systemd/s6100-lpc-monitor.service etc/systemd/system s6100/systemd/s6100-reboot-cause.service etc/systemd/system +s6100/systemd/s6100-i2c-enumerate.service etc/systemd/system tools/flashrom/flashrom usr/local/bin/ common/fw-updater usr/local/bin common/onie_mode_set usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install index a4dffe0d023c..28d77243d639 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install @@ -8,6 +8,7 @@ z9100/scripts/override.conf /etc/systemd/system/systemd-reboot.service.d z9100/scripts/platform_sensors.py usr/local/bin z9100/scripts/sensors usr/bin z9100/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-dell_z9100_c2538-r0 +z9100/modules/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/x86_64-dell_z9100_c2538-r0 z9100/cfg/z9100-modules.conf etc/modules-load.d z9100/systemd/platform-modules-z9100.service etc/systemd/system z9100/systemd/z9100-lpc-monitor.service etc/systemd/system diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.install index ffe23322fb83..9aa3793f5d29 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.install @@ -2,11 +2,12 @@ z9264f/scripts/z9264f_platform.sh usr/local/bin z9264f/scripts/check_qsfp.sh usr/local/bin z9264f/scripts/platform_sensors.py usr/local/bin z9264f/scripts/sensors usr/bin -z9264f/scripts/pcisysfs.py usr/bin -z9264f/scripts/qsfp_irq_enable.py usr/bin +z9264f/scripts/port_irq_enable.py usr/bin z9264f/cfg/z9264f-modules.conf etc/modules-load.d z9264f/systemd/platform-modules-z9264f.service etc/systemd/system z9264f/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-dellemc_z9264f_c3538-r0 +z9264f/modules/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/x86_64-dellemc_z9264f_c3538-r0 common/platform_reboot usr/share/sonic/device/x86_64-dellemc_z9264f_c3538-r0 common/fw-updater usr/local/bin common/onie_mode_set usr/local/bin +common/pcisysfs.py usr/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.install index 16d2b952186f..9915b08b72ee 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.install @@ -1,7 +1,11 @@ z9332f/scripts/z9332f_platform.sh usr/local/bin z9332f/scripts/platform_sensors.py usr/local/bin z9332f/scripts/sensors usr/bin -z9332f/scripts/pcisysfs.py usr/bin z9332f/cfg/z9332f-modules.conf etc/modules-load.d z9332f/systemd/platform-modules-z9332f.service etc/systemd/system +z9332f/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-dellemc_z9332f_d1508-r0 +z9332f/modules/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/x86_64-dellemc_z9332f_d1508-r0 common/platform_reboot usr/share/sonic/device/x86_64-dellemc_z9332f_d1508-r0 +common/pcisysfs.py usr/bin +common/fw-updater usr/local/bin +common/onie_mode_set usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/rules b/platform/broadcom/sonic-platform-modules-dell/debian/rules index 3f0f79979886..2c16f5561f98 100755 --- a/platform/broadcom/sonic-platform-modules-dell/debian/rules +++ b/platform/broadcom/sonic-platform-modules-dell/debian/rules @@ -5,7 +5,7 @@ export INSTALL_MOD_DIR:=extra KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= s6000 z9100 s6100 z9264f s5232f s5248f z9332f +MODULE_DIRS:= s6000 z9100 s6100 z9264f s5232f s5248f z9332f s5296f COMMON_DIR := common %: @@ -19,21 +19,37 @@ override_dh_auto_build: cp $(COMMON_DIR)/dell_ich.c $(MOD_SRC_DIR)/$${mod}/modules/dell_ich.c; \ cd $(MOD_SRC_DIR)/$${mod}; \ python2.7 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ + python3 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ cd $(MOD_SRC_DIR); \ elif [ $$mod = "z9100" ]; then \ cp $(COMMON_DIR)/dell_pmc.c $(MOD_SRC_DIR)/$${mod}/modules/dell_mailbox.c; \ cp $(COMMON_DIR)/dell_ich.c $(MOD_SRC_DIR)/$${mod}/modules/dell_ich.c; \ cd $(MOD_SRC_DIR)/$${mod}; \ python2.7 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ + python3 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ cd $(MOD_SRC_DIR); \ elif [ $$mod = "s6000" ]; then \ cd $(MOD_SRC_DIR)/$${mod}; \ python2.7 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ + python3 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ cd $(MOD_SRC_DIR); \ elif [ $$mod = "z9264f" ]; then \ cp $(COMMON_DIR)/ipmihelper.py $(MOD_SRC_DIR)/$${mod}/sonic_platform/ipmihelper.py; \ cd $(MOD_SRC_DIR)/$${mod}; \ python2.7 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ + python3 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ + cd $(MOD_SRC_DIR); \ + elif [ $$mod = "s5232f" ]; then \ + cp $(COMMON_DIR)/ipmihelper.py $(MOD_SRC_DIR)/$${mod}/sonic_platform/ipmihelper.py; \ + cd $(MOD_SRC_DIR)/$${mod}; \ + python2.7 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ + python3 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ + cd $(MOD_SRC_DIR); \ + elif [ $$mod = "z9332f" ]; then \ + cp $(COMMON_DIR)/ipmihelper.py $(MOD_SRC_DIR)/$${mod}/sonic_platform/ipmihelper.py; \ + cd $(MOD_SRC_DIR)/$${mod}; \ + python2.7 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ + python3 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ cd $(MOD_SRC_DIR); \ fi; \ echo "making man page alias $$mod -> $$mod APIs";\ @@ -82,6 +98,16 @@ override_dh_clean: rm -f $(MOD_SRC_DIR)/$${mod}/modules/*.whl; \ rm -rf $(MOD_SRC_DIR)/$${mod}/build; \ rm -rf $(MOD_SRC_DIR)/$${mod}/build/*.egg-info; \ + elif [ $$mod = "s5232f" ]; then \ + rm -f $(MOD_SRC_DIR)/$${mod}/sonic_platform/ipmihelper.py; \ + rm -f $(MOD_SRC_DIR)/$${mod}/modules/*.whl; \ + rm -rf $(MOD_SRC_DIR)/$${mod}/build; \ + rm -rf $(MOD_SRC_DIR)/$${mod}/build/*.egg-info; \ + elif [ $$mod = "z9332f" ]; then \ + rm -f $(MOD_SRC_DIR)/$${mod}/sonic_platform/ipmihelper.py; \ + rm -f $(MOD_SRC_DIR)/$${mod}/modules/*.whl; \ + rm -rf $(MOD_SRC_DIR)/$${mod}/build; \ + rm -rf $(MOD_SRC_DIR)/$${mod}/build/*.egg-info; \ fi; \ make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules clean; \ done); \ 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..1565d4f5c645 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,28 @@ 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; }; static int use_irq = 1; @@ -100,7 +98,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 +123,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 +145,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 +203,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) @@ -227,13 +226,6 @@ enum { #define I2C_PCI_BUS_NUM_12 12 #define I2C_PCI_BUS_NUM_16 16 -#define IRQ_LTCH_STS 0x20 -#define PRSNT_LTCH_STS 0x10 - -#define PORT_CTRL_OFFSET 0x4000 -#define PORT_STS_OFFSET 0x4004 -#define PORT_IRQ_STS_OFFSET 0x4008 -#define PORT_IRQ_EN_OFFSET 0x400C #define MB_BRD_REV_TYPE 0x0008 #define MB_BRD_REV_MASK 0x00f0 #define MB_BRD_REV_00 0x0000 @@ -292,8 +284,6 @@ enum { #define MSI_VECTOR_REV_00 16 #define MSI_VECTOR_REV_01 32 -#define FPGA_MSI_VECTOR_ID_4 4 -#define FPGA_MSI_VECTOR_ID_5 5 #define FPGA_MSI_VECTOR_ID_8 8 #define FPGA_MSI_VECTOR_ID_9 9 #define FPGA_MSI_VECTOR_ID_10 10 @@ -316,58 +306,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 +374,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,173 +404,106 @@ 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; - } - - /* 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); - - 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); - - 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 (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; - } - } + 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; + } - 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); - } + /* Set read bit if necessary */ + addr |= (i2c->msg->flags & I2C_M_RD) ? 1 : 0; - return 0; -} + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, addr); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_START); -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); - 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)); - 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); -} -static DEVICE_ATTR(port_msi, S_IRUGO, get_mod_msi, NULL); + return 0; + } -static struct attribute *port_attrs[] = { - &dev_attr_port_msi.attr, - NULL, -}; + /* 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); -static struct attribute_group port_attr_grp = { - .attrs = port_attrs, -}; + 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; -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); - 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)); - 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)); + if (stat & FPGAI2C_REG_STAT_NACK) { + i2c->state = STATE_ERROR; + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); + return -ENXIO; } - } - 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; -} - -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); - 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)); - 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)); + } 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; } - } - 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; + } + + 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; } static void fpgai2c_process(struct fpgalogic_i2c *i2c) @@ -590,10 +513,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 +555,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 +574,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 +582,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 +594,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 +609,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 +648,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 +659,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); + + 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); - fpgai2c_reg_set(i2c, FPGAI2C_REG_PRELOW, prescale & 0xff); - fpgai2c_reg_set(i2c, FPGAI2C_REG_PREHIGH, prescale >> 8); + 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; + } - /* 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_reg_set(i2c, FPGAI2C_REG_PRELOW, prescale & 0xff); + fpgai2c_reg_set(i2c, FPGAI2C_REG_PREHIGH, prescale >> 8); - fpgai2c_dump(i2c); + /* Init the device */ + 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); - /* Initialize interrupt handlers if not already done */ - init_waitqueue_head(&i2c->wait); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); + fpgai2c_dump(i2c); - return 0; + /* 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 +795,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: @@ -903,50 +830,51 @@ static int i2c_pci_init (void) break; } } else { - printk("Wrong board_rev_type 0x%x\n", board_rev_type); + printk("unknown board_rev_type 0x%x\n", board_rev_type); + num_bus = I2C_PCI_BUS_NUM_8; } } - 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 +882,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 +947,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 +1017,180 @@ 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) { + 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_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 +1250,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 +1285,209 @@ 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; #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__); - } - 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; + } + + printk("%s:MSI-irq disabled \n", __FUNCTION__); + if (use_irq) { + printk("%s:MSI-irq enabled\n", __FUNCTION__); + 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 +1495,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 +1520,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..5db98374039d 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 @@ -1,9 +1,9 @@ -#!/usr/bin/python +#!/usr/bin/python3 # On S5232F, the BaseBoard Management Controller is an # autonomous subsystem provides monitoring and management # facility independent of the host CPU. IPMI standard # protocol is used with ipmitool to fetch sensor details. -# Current script support X00 board only. X01 support will +# Current script support X00 board only. X01 support will # be added soon. This provies support for the # following objects: # * Onboard temperature sensors @@ -11,22 +11,23 @@ # * PSU -import os import sys import logging -import subprocess -import commands S5232F_MAX_FAN_TRAYS = 4 S5232F_MAX_PSUS = 2 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 @@ -37,12 +38,21 @@ def ipmi_sensor_dump(): status = 1 global ipmi_sdr_list ipmi_cmd = IPMI_SENSOR_DATA - status, ipmi_sdr_list = commands.getstatusoutput(ipmi_cmd) + status, ipmi_sdr_list = subprocess.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 = subprocess.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 @@ -54,7 +64,7 @@ def get_pmc_register(reg_name): output = item.strip() if output is None: - print('\nFailed to fetch: ' + reg_name + ' sensor ') + print('\nFailed to fetch: ' + reg_name + ' sensor ') sys.exit(0) output = output.split('|')[1] @@ -62,27 +72,53 @@ 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 = subprocess.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 'Intake' if 'PS/IO' in line else 'Exhaust' + return '' + +# Fetch FRU on given offset +def fetch_raw_fru(dev_id, offset): + ret_status, ipmi_cmd_ret = subprocess.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)]) -# Print the information for temperature sensors +def get_fan_airflow(fan_id): + Airflow_Direction = ['Exhaust', 'Intake'] + return Airflow_Direction[fetch_raw_fru(fan_id+2, 0x46)] +# Print the information for temperature sensors def print_temperature_sensors(): print("\nOnboard Temperature Sensors:") - print ' PT_Left_temp: ',\ - (get_pmc_register('PT_Left_temp')) - print ' PT_Mid_temp: ',\ - (get_pmc_register('PT_Mid_temp')) - print ' PT_Right_temp: ',\ - (get_pmc_register('PT_Right_temp')) - print ' Broadcom Temp: ',\ - (get_pmc_register('NPU_Near_temp')) - print ' Inlet Airflow Temp: ',\ - (get_pmc_register('ILET_AF_temp')) - print ' CPU Temp: ',\ - (get_pmc_register('CPU_temp')) - + print(' PT_Left_temp: ', + get_pmc_register('PT_Left_temp')) + print(' PT_Mid_temp: ', + get_pmc_register('PT_Mid_temp')) + print(' PT_Right_temp: ', + get_pmc_register('PT_Right_temp')) + print(' Broadcom Temp: ', + get_pmc_register('NPU_Near_temp')) + print(' Inlet Airflow Temp: ', + get_pmc_register('ILET_AF_temp')) + print(' CPU Temp: ', + get_pmc_register('CPU_temp')) + +subprocess.getstatusoutput('echo 0 > /sys/module/ipmi_si/parameters/kipmid_max_busy_us') ipmi_sensor_dump() print_temperature_sensors() @@ -93,75 +129,120 @@ def print_temperature_sensors(): def print_fan_tray(tray): Fan_Status = [' Normal', ' Abnormal'] - Airflow_Direction = ['B2F', 'F2B'] - print ' Fan Tray ' + str(tray) + ':' + print(' Fan Tray ' + str(tray) + ':') if (tray == 1): fan1_status = int(get_pmc_register('FAN1_Front_stat'), 16) fan2_status = int(get_pmc_register('FAN1_Rear_stat'), 16) - print ' Fan1 Speed: ',\ - get_pmc_register('FAN1_Front_rpm') - print ' Fan2 Speed: ',\ - get_pmc_register('FAN1_Rear_rpm') - print ' Fan1 State: ',\ - Fan_Status[fan1_status] - print ' Fan2 State: ',\ - Fan_Status[fan2_status] + print(' Fan1 Speed: ', + get_pmc_register('FAN1_Front_rpm')) + print(' Fan2 Speed: ', + get_pmc_register('FAN1_Rear_rpm')) + print(' Fan1 State: ', + Fan_Status[fan1_status]) + print(' Fan2 State: ', + Fan_Status[fan2_status]) elif (tray == 2): fan1_status = int(get_pmc_register('FAN2_Front_stat'), 16) fan2_status = int(get_pmc_register('FAN2_Rear_stat'), 16) - print ' Fan1 Speed: ',\ - get_pmc_register('FAN2_Front_rpm') - print ' Fan2 Speed: ',\ - get_pmc_register('FAN2_Rear_rpm') - print ' Fan1 State: ',\ - Fan_Status[fan1_status] - print ' Fan2 State: ',\ - Fan_Status[fan2_status] + print(' Fan1 Speed: ', + get_pmc_register('FAN2_Front_rpm')) + print(' Fan2 Speed: ', + get_pmc_register('FAN2_Rear_rpm')) + print(' Fan1 State: ', + Fan_Status[fan1_status]) + print(' Fan2 State: ', + Fan_Status[fan2_status]) elif (tray == 3): fan1_status = int(get_pmc_register('FAN3_Front_stat'), 16) fan2_status = int(get_pmc_register('FAN3_Rear_stat'), 16) - print ' Fan1 Speed: ',\ - get_pmc_register('FAN3_Front_rpm') - print ' Fan2 Speed: ',\ - get_pmc_register('FAN3_Rear_rpm') - print ' Fan1 State: ',\ - Fan_Status[fan1_status] - print ' Fan2 State: ',\ - Fan_Status[fan2_status] + print(' Fan1 Speed: ', + get_pmc_register('FAN3_Front_rpm')) + print(' Fan2 Speed: ', + get_pmc_register('FAN3_Rear_rpm')) + print(' Fan1 State: ', + Fan_Status[fan1_status]) + print(' Fan2 State: ', + Fan_Status[fan2_status]) elif (tray == 4): fan1_status = int(get_pmc_register('FAN4_Front_stat'), 16) fan2_status = int(get_pmc_register('FAN4_Rear_stat'), 16) - print ' Fan1 Speed: ',\ - get_pmc_register('FAN4_Front_rpm') - print ' Fan2 Speed: ',\ - get_pmc_register('FAN4_Rear_rpm') - print ' Fan1 State: ',\ - Fan_Status[fan1_status] - print ' Fan2 State: ',\ - Fan_Status[fan2_status] + print(' Fan1 Speed: ', + get_pmc_register('FAN4_Front_rpm')) + print(' Fan2 Speed: ', + get_pmc_register('FAN4_Rear_rpm')) + print(' Fan1 State: ', + 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 = subprocess.getstatusoutput(IPMI_PSU1_DATA_DOCKER) + elif index == 2: + ret_status, ipmi_cmd_ret = subprocess.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 = subprocess.getstatusoutput(IPMI_PSU1_DATA_DOCKER) + elif index == 2: + ret_status, ipmi_cmd_ret = subprocess.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 +256,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] @@ -185,64 +265,69 @@ def print_psu(psu): # psu1_fan_status = int(get_pmc_register('PSU1_status'),16) - print ' PSU1:' - print ' FAN Normal Temperature: ',\ - get_pmc_register('PSU1_temp') - print ' FAN AirFlow Temperature: ',\ - get_pmc_register('PSU1_AF_temp') - print ' FAN RPM: ',\ - get_pmc_register('PSU1_rpm') + print(' PSU1:') + print(' FAN Normal Temperature: ', + get_pmc_register('PSU1_temp')) + print(' FAN AirFlow Temperature: ', + get_pmc_register('PSU1_AF_temp')) + print(' FAN RPM: ', + get_pmc_register('PSU1_rpm')) # print ' FAN Status: ', Psu_Fan_Status[psu1_fan_status] # PSU input & output monitors - print ' Input Voltage: ',\ - get_pmc_register('PSU1_In_volt') - print ' Output Voltage: ',\ - get_pmc_register('PSU1_Out_volt') - print ' Input Power: ',\ - get_pmc_register('PSU1_In_watt') - print ' Output Power: ',\ - get_pmc_register('PSU1_Out_watt') - print ' Input Current: ',\ - get_pmc_register('PSU1_In_amp') - print ' Output Current: ',\ - get_pmc_register('PSU1_Out_amp') + print(' Input Voltage: ', + get_pmc_register('PSU1_In_volt')) + print(' Output Voltage: ', + get_pmc_register('PSU1_Out_volt')) + print(' Input Power: ', + get_pmc_register('PSU1_In_watt')) + print(' Output Power: ', + get_pmc_register('PSU1_Out_watt')) + print(' Input Current: ', + get_pmc_register('PSU1_In_amp')) + print(' Output Current: ', + get_pmc_register('PSU1_Out_amp')) else: # psu2_fan_status = int(get_pmc_register('PSU1_status'),16) - print ' PSU2:' - print ' FAN Normal Temperature: ',\ - get_pmc_register('PSU2_temp') - print ' FAN AirFlow Temperature: ',\ - get_pmc_register('PSU2_AF_temp') - print ' FAN RPM: ',\ - get_pmc_register('PSU2_rpm') + print(' PSU2:') + print(' FAN Normal Temperature: ', + get_pmc_register('PSU2_temp')) + print(' FAN AirFlow Temperature: ', + get_pmc_register('PSU2_AF_temp')) + print(' FAN RPM: ', + get_pmc_register('PSU2_rpm')) # print ' FAN Status: ', Psu_Fan_Status[psu2_fan_status] # PSU input & output monitors - print ' Input Voltage: ',\ - get_pmc_register('PSU2_In_volt') - print ' Output Voltage: ',\ - get_pmc_register('PSU2_Out_volt') - print ' Input Power: ',\ - get_pmc_register('PSU2_In_watt') - print ' Output Power: ',\ - get_pmc_register('PSU2_Out_watt') - print ' Input Current: ',\ - get_pmc_register('PSU2_In_amp') - print ' Output Current: ',\ - get_pmc_register('PSU2_Out_amp') + print(' Input Voltage: ', + get_pmc_register('PSU2_In_volt')) + print(' Output Voltage: ', + get_pmc_register('PSU2_Out_volt')) + print(' Input Power: ', + get_pmc_register('PSU2_In_watt')) + print(' Output Power: ', + get_pmc_register('PSU2_Out_watt')) + print(' Input Current: ', + 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') +print('\n Total Power: ', + get_pmc_register('PSU_Total_watt')) +subprocess.getstatusoutput('echo 1000 > /sys/module/ipmi_si/parameters/kipmid_max_busy_us') diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/qsfp_irq_enable.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/qsfp_irq_enable.py index 5050475f987e..24bc07f041f8 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/qsfp_irq_enable.py +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/qsfp_irq_enable.py @@ -1,32 +1,31 @@ -#!/usr/bin/python +#!/usr/bin/python3 try: - import struct - import sys - from os import * - from mmap import * + import struct + from os import * + from mmap import * except ImportError as e: - raise ImportError("%s - required module no found" % str(e)) + raise ImportError("%s - required module no found" % str(e)) BASE_RES_PATH = "/sys/bus/pci/devices/0000:04:00.0/resource0" PORT_START = 0 -PORT_END = 32 +PORT_END = 32 def pci_mem_write(mm, offset, data): - mm.seek(offset) - mm.write(struct.pack('I', data)) + mm.seek(offset) + mm.write(struct.pack('I', data)) def pci_set_value(resource, val, offset): - fd = open(resource, O_RDWR) - mm = mmap(fd, 0) - val = pci_mem_write(mm, offset, val) - mm.close() - close(fd) - return val + fd = open(resource, O_RDWR) + mm = mmap(fd, 0) + val = pci_mem_write(mm, offset, val) + mm.close() + close(fd) + return val for port_num in range(PORT_START, PORT_END+1): - port_offset = 0x400c + ((port_num) * 16) - pci_set_value(BASE_RES_PATH, 0x30, port_offset) + port_offset = 0x400c + ((port_num) * 16) + pci_set_value(BASE_RES_PATH, 0x30, port_offset) 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 a419b7d22e5f..cdb3412b7899 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 @@ -104,39 +104,130 @@ switch_board_modsel() { do port_addr=$(( 16384 + ((i - 1) * 16))) hex=$( printf "0x%x" $port_addr ) - python /usr/bin/pcisysfs.py --set --offset $hex --val 0x10 --res $resource > /dev/null 2>&1 + /usr/bin/pcisysfs.py --set --offset $hex --val 0x10 --res $resource > /dev/null 2>&1 done } #This enables the led control for CPU and default states 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 + /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 + +} + +install_python_api_package() { + device="/usr/share/sonic/device" + platform=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) + + rv=$(pip install $device/$platform/sonic_platform-1.0-py2-none-any.whl) + rv=$(pip3 install $device/$platform/sonic_platform-1.0-py3-none-any.whl) +} + +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) + fi + + rv=$(pip3 show sonic-platform > /dev/null 2>/dev/null) + if [ $? -eq 0 ]; then + rv=$(pip3 uninstall -y sonic-platform > /dev/null 2>/dev/null) + fi +} + +get_reboot_cause() { + REBOOT_REASON_FILE="/host/reboot-cause/platform/reboot_reason" + resource="/sys/bus/pci/devices/0000:04:00.0/resource0" + + mkdir -p $(dirname $REBOOT_REASON_FILE) + + # Handle First Boot into software version with reboot cause determination support + if [[ ! -e $REBOOT_REASON_FILE ]]; then + echo "0" > $REBOOT_REASON_FILE + else + /usr/bin/pcisysfs.py --get --offset 0x18 --res $resource | sed '1d; s/.*:\(.*\)$/\1/;' > $REBOOT_REASON_FILE + fi + /usr/bin/pcisysfs.py --set --val 0x0 --offset 0x18 --res $resource +} + +get_reboot_cause() { + REBOOT_REASON_FILE="/host/reboot-cause/platform/reboot_reason" + resource="/sys/bus/pci/devices/0000:04:00.0/resource0" + + mkdir -p $(dirname $REBOOT_REASON_FILE) + + # Handle First Boot into software version with reboot cause determination support + if [[ ! -e $REBOOT_REASON_FILE ]]; then + echo "0" > $REBOOT_REASON_FILE + else + /usr/bin/pcisysfs.py --get --offset 0x18 --res $resource | sed '1d; s/.*:\(.*\)$/\1/;' > $REBOOT_REASON_FILE + fi + /usr/bin/pcisysfs.py --set --val 0x0 --offset 0x18 --res $resource +} + init_devnum if [ "$1" == "init" ]; then modprobe i2c-dev modprobe i2c-mux-pca954x force_deselect_on_exit=1 modprobe ipmi_devintf - modprobe ipmi_si + modprobe ipmi_si kipmid_max_busy_us=1000 modprobe i2c_ocores modprobe dell_s5232f_fpga_ocores sys_eeprom "new_device" + get_reboot_cause switch_board_qsfp_mux "new_device" switch_board_qsfp "new_device" switch_board_sfp "new_device" switch_board_modsel switch_board_led_default - python /usr/bin/qsfp_irq_enable.py + install_python_api_package + /usr/bin/qsfp_irq_enable.py + platform_firmware_versions + echo 1000 > /sys/module/ipmi_si/parameters/kipmid_max_busy_us elif [ "$1" == "deinit" ]; then sys_eeprom "delete_device" switch_board_qsfp "delete_device" - switch_board_qsfp_mux "delete_device" switch_board_sfp "delete_device" + switch_board_qsfp_mux "delete_device" modprobe -r i2c-mux-pca954x modprobe -r i2c-dev + remove_python_api_package + modprobe -r ipmi_devintf + modprobe -r ipmi_si else echo "s5232f_platform : Invalid option !" fi diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/setup.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/setup.py new file mode 120000 index 000000000000..4f6de9941d96 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/setup.py @@ -0,0 +1 @@ +../s6100/setup.py \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/__init__.py new file mode 100644 index 000000000000..4f5d4f6e473d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/__init__.py @@ -0,0 +1,2 @@ +__all__ = ["platform", "chassis", "sfp", "eeprom", "component", "psu", "thermal", "fan", "fan_drawer"] +from sonic_platform import * diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/chassis.py new file mode 100644 index 000000000000..1022d0bb481b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/chassis.py @@ -0,0 +1,262 @@ +#!/usr/bin/env python + +############################################################################# +# DELLEMC S5232F +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +from __future__ import division + +try: + import sys + import time + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform.sfp import Sfp + from sonic_platform.eeprom import Eeprom + from sonic_platform.component import Component + from sonic_platform.psu import Psu + from sonic_platform.thermal import Thermal + from sonic_platform.fan_drawer import FanDrawer + from sonic_platform.watchdog import Watchdog +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +MAX_S5232F_COMPONENT = 6 # BIOS,BMC,FPGA,SYSTEM CPLD,2 SLAVE CPLDs +MAX_S5232F_FANTRAY =4 +MAX_S5232F_FAN = 2 +MAX_S5232F_PSU = 2 +MAX_S5232F_THERMAL = 8 + + +class Chassis(ChassisBase): + """ + DELLEMC Platform-specific Chassis class + """ + + oir_fd = -1 + epoll = -1 + + _global_port_pres_dict = {} + + def __init__(self): + ChassisBase.__init__(self) + # sfp.py will read eeprom contents and retrive the eeprom data. + # We pass the eeprom path from chassis.py + self.PORT_START = 1 + self.PORT_END = 34 + self.PORTS_IN_BLOCK = (self.PORT_END + 1) + _sfp_port = list(range(33, self.PORT_END + 1)) + eeprom_base = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" + + for index in range(self.PORT_START, self.PORTS_IN_BLOCK): + port_num = index + 1 + eeprom_path = eeprom_base.format(port_num) + if index not in _sfp_port: + sfp_node = Sfp(index, 'QSFP', eeprom_path) + else: + sfp_node = Sfp(index, 'SFP', eeprom_path) + self._sfp_list.append(sfp_node) + + self._eeprom = Eeprom() + self._watchdog = Watchdog() + for i in range(MAX_S5232F_FANTRAY): + fandrawer = FanDrawer(i) + self._fan_drawer_list.append(fandrawer) + self._fan_list.extend(fandrawer._fan_list) + + self._num_sfps = self.PORT_END + self._num_fans = MAX_S5232F_FANTRAY * MAX_S5232F_FAN + self._psu_list = [Psu(i) for i in range(MAX_S5232F_PSU)] + self._thermal_list = [Thermal(i) for i in range(MAX_S5232F_THERMAL)] + self._component_list = [Component(i) for i in range(MAX_S5232F_COMPONENT)] + + for port_num in range(self.PORT_START, self.PORTS_IN_BLOCK): + # sfp get uses zero-indexing, but port numbers start from 1 + presence = self.get_sfp(port_num).get_presence() + self._global_port_pres_dict[port_num] = '1' if presence else '0' + + def __del__(self): + if self.oir_fd != -1: + self.epoll.unregister(self.oir_fd.fileno()) + self.epoll.close() + self.oir_fd.close() + +# check for this event change for sfp / do we need to handle timeout/sleep + + def get_change_event(self, timeout=0): + from time import sleep + """ + Returns a nested dictionary containing all devices which have + experienced a change at chassis level + """ + start_ms = time.time() * 1000 + port_dict = {} + change_dict = {} + change_dict['sfp'] = port_dict + while True: + time.sleep(0.5) + for port_num in range(self.PORT_START, (self.PORT_END + 1)): + presence = self.get_sfp(port_num).get_presence() + 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, change_dict + + if timeout: + now_ms = time.time() * 1000 + if (now_ms - start_ms >= timeout): + return True, change_dict + + + def get_sfp(self, index): + """ + Retrieves sfp represented by (0-based) index + + Args: + index: An integer, the index (0-based) of the sfp to retrieve. + The index should be the sequence of a physical port in a chassis, + starting from 0. + For example, 0 for Ethernet0, 1 for Ethernet4 and so on. + + Returns: + An object dervied from SfpBase representing the specified sfp + """ + sfp = None + + try: + # The index will start from 0 + sfp = self._sfp_list[index-1] + except IndexError: + sys.stderr.write("SFP index {} out of range (0-{})\n".format( + index, len(self._sfp_list))) + return sfp + + def get_name(self): + """ + Retrieves the name of the chassis + Returns: + string: The name of the chassis + """ + return self._eeprom.modelstr() + + def get_presence(self): + """ + Retrieves the presence of the chassis + Returns: + bool: True if chassis is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the chassis + Returns: + string: Model/part number of chassis + """ + return self._eeprom.part_number_str() + + def get_serial(self): + """ + Retrieves the serial number of the chassis (Service tag) + Returns: + string: Serial number of chassis + """ + return self._eeprom.serial_str() + + def get_status(self): + """ + Retrieves the operational status of the chassis + Returns: + bool: A boolean value, True if chassis is operating properly + False if not + """ + return True + + def get_base_mac(self): + """ + Retrieves the base MAC address for the chassis + Returns: + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' + """ + return self._eeprom.base_mac_addr('') + + def get_system_eeprom_info(self): + """ + Retrieves the full content of system EEPROM information for the chassis + Returns: + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their corresponding + values. + """ + return self._eeprom.system_eeprom_info() + + def get_eeprom(self): + """ + Retrieves the Sys Eeprom instance for the chassis. + Returns : + The instance of the Sys Eeprom + """ + return self._eeprom + + def get_num_fans(self): + """ + Retrives the number of Fans on the chassis. + Returns : + An integer represents the number of Fans on the chassis. + """ + return self._num_fans + + def get_num_sfps(self): + """ + Retrives the numnber of Media on the chassis. + Returns: + An integer represences the number of SFPs on the chassis. + """ + return self._num_sfps + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + Returns: + A tuple (string, string) where the first element is a string + containing the cause of the previous reboot. This string must be + one of the predefined strings in this class. If the first string + is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used + to pass a description of the reboot cause. + """ + try: + with open(self.REBOOT_CAUSE_PATH) as fd: + reboot_cause = int(fd.read(), 16) + except EnvironmentError: + return (self.REBOOT_CAUSE_NON_HARDWARE, None) + + if reboot_cause & 0x1: + return (self.REBOOT_CAUSE_POWER_LOSS, None) + elif reboot_cause & 0x2: + return (self.REBOOT_CAUSE_NON_HARDWARE, None) + elif reboot_cause & 0x4: + return (self.REBOOT_CAUSE_HARDWARE_OTHER, "PSU Shutdown") + elif reboot_cause & 0x8: + return (self.REBOOT_CAUSE_THERMAL_OVERLOAD_CPU, None) + elif reboot_cause & 0x10: + return (self.REBOOT_CAUSE_WATCHDOG, None) + elif reboot_cause & 0x20: + return (self.REBOOT_CAUSE_HARDWARE_OTHER, "BMC Shutdown") + elif reboot_cause & 0x40: + return (self.REBOOT_CAUSE_HARDWARE_OTHER, "Hot-Swap Shutdown") + elif reboot_cause & 0x80: + return (self.REBOOT_CAUSE_HARDWARE_OTHER, "Reset Button Shutdown") + elif reboot_cause & 0x100: + return (self.REBOOT_CAUSE_HARDWARE_OTHER, "Reset Button Cold Reboot") + else: + return (self.REBOOT_CAUSE_NON_HARDWARE, None) + diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/component.py new file mode 100644 index 000000000000..f7fcc94662c1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/component.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python + +######################################################################## +# DELLEMC S5232F +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Components' (e.g., BIOS, CPLD, FPGA, BMC etc.) available in +# the platform +# +######################################################################## + +try: + import subprocess + from sonic_platform_base.component_base import ComponentBase + import sonic_platform.hwaccess as hwaccess + +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +def get_bios_version(): + return subprocess.check_output(['dmidecode', '-s', 'system-version']).decode('utf-8').strip() + +def get_fpga_version(): + val = hwaccess.pci_get_value('/sys/bus/pci/devices/0000:04:00.0/resource0', 0) + return '{}.{}'.format((val >> 8) & 0xff, val & 0xff) + +def get_bmc_version(): + return subprocess.check_output( + ['cat', '/sys/class/ipmi/ipmi0/device/bmc/firmware_revision'] + ).decode('utf-8').strip() + +def get_cpld_version(bus, i2caddr): + return '{}.{}'.format(hwaccess.i2c_get(bus, i2caddr, 1), + hwaccess.i2c_get(bus, i2caddr, 0) + ) + +def get_cpld0_version(): + return get_cpld_version(601, 0x31) + +def get_cpld1_version(): + return get_cpld_version(600, 0x30) + +def get_cpld2_version(): + return get_cpld_version(600, 0x31) + + +class Component(ComponentBase): + """DellEMC Platform-specific Component class""" + + CHASSIS_COMPONENTS = [ + ['BIOS', + 'Performs initialization of hardware components during booting', + get_bios_version + ], + + ['FPGA', + 'Used for managing the system LEDs', + get_fpga_version + ], + + ['BMC', + 'Platform management controller for on-board temperature monitoring, in-chassis power, Fan and LED control', + get_bmc_version + ], + + ['System CPLD', + 'Used for managing the CPU power sequence and CPU states', + get_cpld0_version + ], + + ['Slave CPLD 1', + 'Used for managing SFP28/QSFP28 port transceivers (SFP28 1-24, QSFP28 1-4)', + get_cpld1_version + ], + + ['Slave CPLD 2', + 'Used for managing SFP28/QSFP28 port transceivers (SFP28 25-48, QSFP28 5-8)', + get_cpld2_version + ] + + ] + + def __init__(self, component_index = 0): + self.index = component_index + self.name = self.CHASSIS_COMPONENTS[self.index][0] + self.description = self.CHASSIS_COMPONENTS[self.index][1] + self.version = self.CHASSIS_COMPONENTS[self.index][2]() + + def get_name(self): + """ + Retrieves the name of the component + Returns: + A string containing the name of the component + """ + return self.name + + def get_description(self): + """ + Retrieves the description of the component + Returns: + A string containing the description of the component + """ + return self.description + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + Returns: + A string containing the firmware version of the component + """ + return self.version + + 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 + """ + return False diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/eeprom.py new file mode 100644 index 000000000000..bf3434733f36 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/eeprom.py @@ -0,0 +1,133 @@ +#!/usr/bin/env python + +############################################################################# +# DellEmc S5248F +# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# +try: + import os.path + from sonic_eeprom import eeprom_tlvinfo +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self): + self.eeprom_path = None + for b in (0, 1): + f = '/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom'.format(b) + if os.path.exists(f): + self.eeprom_path = f + break + if self.eeprom_path is None: + return + super(Eeprom, self).__init__(self.eeprom_path, 0, '', True) + self.eeprom_tlv_dict = dict() + try: + self.eeprom_data = self.read_eeprom() + except: + self.eeprom_data = "N/A" + raise RuntimeError("Eeprom is not Programmed") + + eeprom = self.eeprom_data + + if not self.is_valid_tlvinfo_header(eeprom): + return + + total_length = (eeprom[9] << 8) | eeprom[10] + tlv_index = self._TLV_INFO_HDR_LEN + tlv_end = self._TLV_INFO_HDR_LEN + total_length + + while (tlv_index + 2) < len(eeprom) and tlv_index < tlv_end: + if not self.is_valid_tlv(eeprom[tlv_index:]): + break + + tlv = eeprom[tlv_index:tlv_index + 2 + + eeprom[tlv_index + 1]] + code = "0x%02X" % tlv[0] + + name, value = self.decoder(None, tlv) + + self.eeprom_tlv_dict[code] = value + if eeprom[tlv_index] == self._TLV_CODE_CRC_32: + break + + tlv_index += eeprom[tlv_index+1] + 2 + + def serial_number_str(self): + """ + Returns the serial number + """ + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_SERIAL_NUMBER) + if not is_valid: + return "N/A" + return results[2].decode('ascii') + + def base_mac_addr(self, e): + """ + Returns the base mac address found in the system EEPROM + """ + (is_valid, t) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_MAC_BASE) + if not is_valid or t[1] != 6: + return super(eeprom_tlvinfo.TlvInfoDecoder, self).switchaddrstr(t) + + return ":".join(["{:02x}".format(T) for T in t[2]]).upper() + + def modelstr(self): + """ + Returns the Model name + """ + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_PRODUCT_NAME) + if not is_valid: + return "N/A" + + return results[2].decode('ascii') + + def part_number_str(self): + """ + Returns the part number + """ + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_PART_NUMBER) + if not is_valid: + return "N/A" + + return results[2].decode('ascii') + + def serial_str(self): + """ + Returns the servicetag number + """ + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_SERVICE_TAG) + if not is_valid: + return "N/A" + + return results[2].decode('ascii') + + def revision_str(self): + """ + Returns the device revision + """ + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_DEVICE_VERSION) + if not is_valid: + return "N/A" + + return results[2].decode('ascii') + + def system_eeprom_info(self): + """ + Returns a dictionary, where keys are the type code defined in + ONIE EEPROM format and values are their corresponding values + found in the system EEPROM. + """ + return self.eeprom_tlv_dict diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/fan.py new file mode 100644 index 000000000000..1b624cb76eda --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/fan.py @@ -0,0 +1,182 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC S5232F +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Fans' information which are available in the platform. +# +######################################################################## + +try: + from sonic_platform_base.fan_base import FanBase + from sonic_platform.ipmihelper import IpmiSensor, IpmiFru +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +FAN1_MAX_SPEED_OFFSET = 71 +FAN2_MAX_SPEED_OFFSET = 73 +PSU_FAN_MAX_SPEED_OFFSET = 50 +FAN_DIRECTION_OFFSET = 69 +PSU_FAN_DIRECTION_OFFSET = 47 + + +class Fan(FanBase): + """DellEMC Platform-specific Fan class""" + # { FAN-ID: { Sensor-Name: Sensor-ID } } + FAN_SENSOR_MAPPING = { 1: {"Prsnt": 0x53, "State": 0x57, "Speed": 0x24}, + 2: {"Prsnt": 0x53, "State": 0x5b, "Speed": 0x20}, + 3: {"Prsnt": 0x54, "State": 0x58, "Speed": 0x25}, + 4: {"Prsnt": 0x54, "State": 0x5c, "Speed": 0x21}, + 5: {"Prsnt": 0x55, "State": 0x59, "Speed": 0x26}, + 6: {"Prsnt": 0x55, "State": 0x5d, "Speed": 0x22}, + 7: {"Prsnt": 0x56, "State": 0x5a, "Speed": 0x27}, + 8: {"Prsnt": 0x56, "State": 0x5e, "Speed": 0x23} } + PSU_FAN_SENSOR_MAPPING = { 1: {"State": 0x31, "Speed": 0x28}, + 2: {"State": 0x32, "Speed": 0x29} } + + # { FANTRAY-ID: FRU-ID } + FAN_FRU_MAPPING = { 1: 3, 2: 4, 3: 5, 4: 6 } + PSU_FRU_MAPPING = { 1: 1, 2: 2 } + + def __init__(self, fantray_index=1, fan_index=1, psu_fan=False, + dependency=None): + self.is_psu_fan = psu_fan + if not self.is_psu_fan: + # API index is starting from 0, DellEMC platform index is + # starting from 1 + self.fantrayindex = fantray_index + 1 + self.fanindex = fan_index + 1 + if (self.fanindex == 1): + self.max_speed_offset = FAN1_MAX_SPEED_OFFSET + else: + self.max_speed_offset = FAN2_MAX_SPEED_OFFSET + self.fan_direction_offset = FAN_DIRECTION_OFFSET + self.index = (self.fantrayindex - 1) * 2 + self.fanindex + self.prsnt_sensor = IpmiSensor(self.FAN_SENSOR_MAPPING[self.index]["Prsnt"], + is_discrete=True) + self.state_sensor = IpmiSensor(self.FAN_SENSOR_MAPPING[self.index]["State"], + is_discrete=True) + self.speed_sensor = IpmiSensor(self.FAN_SENSOR_MAPPING[self.index]["Speed"]) + self.fru = IpmiFru(self.FAN_FRU_MAPPING[self.fantrayindex]) + else: + self.dependency = dependency + self.fanindex = fan_index + self.state_sensor = IpmiSensor(self.PSU_FAN_SENSOR_MAPPING[self.fanindex]["State"], + is_discrete=True) + self.speed_sensor = IpmiSensor(self.PSU_FAN_SENSOR_MAPPING[self.fanindex]["Speed"]) + self.fru = IpmiFru(self.PSU_FRU_MAPPING[self.fanindex]) + self.max_speed_offset = PSU_FAN_MAX_SPEED_OFFSET + self.fan_direction_offset = PSU_FAN_DIRECTION_OFFSET + self.max_speed = self.fru.get_fru_data(self.max_speed_offset,2)[1] + self.max_speed = self.max_speed[1] << 8 | self.max_speed[0] + + def get_name(self): + """ + Retrieves the name of the device + Returns: + String: The name of the device + """ + if self.is_psu_fan: + return "PSU{} Fan".format(self.fanindex) + else: + return "FanTray{}-Fan{}".format(self.fantrayindex, self.fanindex) + + def get_model(self): + """ + Retrieves the part number of the FAN + Returns: + String: Part number of FAN + """ + if self.is_psu_fan: + return 'NA' + else: + return self.fru.get_board_part_number() + + def get_serial(self): + """ + Retrieves the serial number of the FAN + Returns: + String: Serial number of FAN + """ + if self.is_psu_fan: + return 'NA' + else: + return self.fru.get_board_serial() + + def get_presence(self): + """ + Retrieves the presence of the FAN + Returns: + bool: True if fan is present, False if not + """ + presence = False + if self.is_psu_fan: + return self.dependency.get_presence() + else: + is_valid, state = self.prsnt_sensor.get_reading() + if is_valid: + if (state & 0b1): + presence = True + return presence + + def get_status(self): + """ + Retrieves the operational status of the FAN + Returns: + bool: True if FAN is operating properly, False if not + """ + status = False + is_valid, state = self.state_sensor.get_reading() + if is_valid: + if not state > 1: + status = True + return status + + def get_direction(self): + """ + Retrieves the fan airfow direction + 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 = [self.FAN_DIRECTION_EXHAUST, self.FAN_DIRECTION_INTAKE] + fan_status = self.get_presence() + if not fan_status: + return 'NA' + is_valid, fan_direction = self.fru.get_fru_data(self.fan_direction_offset) + if is_valid and fan_direction[0] < len(direction): + return direction[fan_direction[0]] + else: + return 'NA' + + def get_speed(self): + """ + Retrieves the speed of the fan + Returns: + int: percentage of the max fan speed + """ + if self.max_speed == 0: + self.max_speed = self.fru.get_fru_data(self.max_speed_offset,2)[1] + self.max_speed = self.max_speed[1] << 8 | self.max_speed[0] + is_valid, fan_speed = self.speed_sensor.get_reading() + if not is_valid or self.max_speed == 0: + speed = 0 + else: + speed = (100 * fan_speed)//self.max_speed + return speed + + def get_speed_rpm(self): + """ + Retrieves the speed of the fan + Returns: + int: percentage of the max fan speed + """ + fan_speed = 0 + is_valid, fan_speed = self.speed_sensor.get_reading() + return fan_speed diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/fan_drawer.py new file mode 100644 index 000000000000..0fdc80e651ed --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/fan_drawer.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC Z9332F +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Fan-Drawers' information available in the platform. +# +######################################################################## + +try: + from sonic_platform_base.fan_drawer_base import FanDrawerBase + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +Z9332F_FANS_PER_FANTRAY = 2 + + +class FanDrawer(FanDrawerBase): + """DellEMC Platform-specific Fan class""" + + def __init__(self, fantray_index): + + FanDrawerBase.__init__(self) + # FanTray is 1-based in DellEMC platforms + self.fantrayindex = fantray_index + 1 + for i in range(Z9332F_FANS_PER_FANTRAY): + self._fan_list.append(Fan(fantray_index, i)) + + def get_name(self): + """ + Retrieves the fan drawer name + Returns: + string: The name of the device + """ + return "FanTray{}".format(self.fantrayindex) diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/hwaccess.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/hwaccess.py new file mode 120000 index 000000000000..e8fa340a444d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/hwaccess.py @@ -0,0 +1 @@ +../../common/sonic_platform/hwaccess.py \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/platform.py new file mode 100644 index 000000000000..996d94cf5a6e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/platform.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python + +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PlatformBase): + """ + DELLEMC Platform-specific class + """ + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/psu.py new file mode 100644 index 000000000000..a7e2add8bd08 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/psu.py @@ -0,0 +1,179 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC S5232F +# +# Module contains an implementation of SONiC Platform Base API and +# provides the PSUs' information which are available in the platform +# +######################################################################## + + +try: + from sonic_platform_base.psu_base import PsuBase + from sonic_platform.ipmihelper import IpmiSensor, IpmiFru + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Psu(PsuBase): + """DellEMC Platform-specific PSU class""" + + # { PSU-ID: { Sensor-Name: Sensor-ID } } + SENSOR_MAPPING = { 1: { "State": 0x31, "Current": 0x39, + "Power": 0x37, "Voltage": 0x38 }, + 2: { "State": 0x32, "Current": 0x3F, + "Power": 0x3D, "Voltage": 0x3E } } + # ( PSU-ID: FRU-ID } + FRU_MAPPING = { 1: 1, 2: 2 } + + def __init__(self, psu_index): + PsuBase.__init__(self) + # PSU is 1-based in DellEMC platforms + self.index = psu_index + 1 + self.state_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["State"], + is_discrete=True) + self.voltage_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["Voltage"]) + self.current_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["Current"]) + self.power_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["Power"]) + self.fru = IpmiFru(self.FRU_MAPPING[self.index]) + + self._fan_list.append(Fan(fan_index=self.index, psu_fan=True, + dependency=self)) + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + return "PSU{}".format(self.index) + + def get_presence(self): + """ + Retrieves the presence of the Power Supply Unit (PSU) + + Returns: + bool: True if PSU is present, False if not + """ + presence = False + is_valid, state = self.state_sensor.get_reading() + if is_valid: + if (state & 0b1): + presence = True + + return presence + + def get_model(self): + """ + Retrieves the part number of the PSU + + Returns: + string: Part number of PSU + """ + return self.fru.get_board_part_number() + + def get_serial(self): + """ + Retrieves the serial number of the PSU + + Returns: + string: Serial number of PSU + """ + return self.fru.get_board_serial() + + def get_status(self): + """ + Retrieves the operational status of the PSU + + Returns: + bool: True if PSU is operating properly, False if not + """ + status = False + is_valid, state = self.state_sensor.get_reading() + if is_valid: + if (state == 0x01): + status = True + + return status + + def get_voltage(self): + """ + Retrieves current PSU voltage output + + Returns: + A float number, the output voltage in volts, + e.g. 12.1 + """ + is_valid, voltage = self.voltage_sensor.get_reading() + if not is_valid: + voltage = 0 + + return float(voltage) + + def get_current(self): + """ + Retrieves present electric current supplied by PSU + + Returns: + A float number, electric current in amperes, + e.g. 15.4 + """ + is_valid, current = self.current_sensor.get_reading() + if not is_valid: + current = 0 + + return float(current) + + def get_power(self): + """ + Retrieves current energy supplied by PSU + + Returns: + A float number, the power in watts, + e.g. 302.6 + """ + is_valid, power = self.power_sensor.get_reading() + if not is_valid: + power = 0 + + return float(power) + + def get_powergood_status(self): + """ + Retrieves the powergood status of PSU + + Returns: + A boolean, True if PSU has stablized its output voltages and + passed all its internal self-tests, False if not. + """ + status = False + is_valid, state = self.state_sensor.get_reading() + if is_valid: + if (state == 0x01): + status = True + + return status + + def get_mfr_id(self): + """ + Retrives the Manufacturer Id of PSU + + Returns: + A string, the manunfacturer id. + """ + return self.fru.get_board_mfr_id() + + def get_type(self): + """ + Retrives the Power Type of PSU + + Returns : + A string, PSU power type + """ + info = self.fru.get_board_product().split(',') + if 'AC' in info : return 'AC' + if 'DC' in info : return 'DC' + return 'Unknown' diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/sfp.py new file mode 100644 index 000000000000..b2cceab9b08f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/sfp.py @@ -0,0 +1,1045 @@ +#!/usr/bin/env python + +############################################################################# +# DELLEMC +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + import os + import time + import struct + import mmap + from sonic_platform_base.sfp_base import SfpBase + from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom + from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom + from sonic_platform_base.sonic_sfp.sff8472 import sffbase + +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +PAGE_OFFSET = 0 +KEY_OFFSET = 1 +KEY_WIDTH = 2 +FUNC_NAME = 3 + +QSFP_INFO_OFFSET = 128 +QSFP_DOM_OFFSET = 0 +QSFP_DOM_OFFSET1 = 384 + +SFP_INFO_OFFSET = 0 +SFP_DOM_OFFSET = 256 + +SFP_STATUS_CONTROL_OFFSET = 110 +SFP_STATUS_CONTROL_WIDTH = 7 +SFP_TX_DISABLE_HARD_BIT = 7 +SFP_TX_DISABLE_SOFT_BIT = 6 + +qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', 'Length OM2(m)', + 'Length OM1(m)', 'Length Cable Assembly(m)') + +qsfp_compliance_code_tup = ( + '10/40G Ethernet Compliance Code', + 'SONET Compliance codes', + 'SAS/SATA compliance codes', + 'Gigabit Ethernet Compliant codes', + 'Fibre Channel link length/Transmitter Technology', + 'Fibre Channel transmission media', + 'Fibre Channel Speed') + +sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)', + 'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)', + 'LengthOM3(UnitsOf10m)', 'LengthCable(UnitsOfm)') + +sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode', + 'ESCONComplianceCodes', 'SONETComplianceCodes', + 'EthernetComplianceCodes', 'FibreChannelLinkLength', + 'FibreChannelTechnology', 'SFP+CableTechnology', + 'FibreChannelTransmissionMedia', 'FibreChannelSpeed') + +info_dict_keys = ['type', 'hardware_rev', 'serial', + 'manufacturer', 'model', 'connector', + 'encoding', 'ext_identifier', 'ext_rateselect_compliance', + 'cable_type', 'cable_length', 'nominal_bit_rate', + 'specification_compliance', 'type_abbrv_name','vendor_date', 'vendor_oui'] + +dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', + 'power_lpmode', 'tx_disable', 'tx_disable_channel', + 'temperature', 'voltage', 'rx1power', + 'rx2power', 'rx3power', 'rx4power', + 'tx1bias', 'tx2bias', 'tx3bias', + 'tx4bias', 'tx1power', 'tx2power', + 'tx3power', 'tx4power'] + +threshold_dict_keys = ['temphighalarm', 'temphighwarning', + 'templowalarm', 'templowwarning', + 'vcchighalarm', 'vcchighwarning', + 'vcclowalarm', 'vcclowwarning', + 'rxpowerhighalarm', 'rxpowerhighwarning', + 'rxpowerlowalarm', 'rxpowerlowwarning', + 'txpowerhighalarm', 'txpowerhighwarning', + 'txpowerlowalarm', 'txpowerlowwarning', + 'txbiashighalarm', 'txbiashighwarning', + 'txbiaslowalarm', 'txbiaslowwarning'] + +sff8436_parser = { + 'reset_status': [QSFP_DOM_OFFSET, 2, 1, 'parse_dom_status_indicator'], + 'rx_los': [QSFP_DOM_OFFSET, 3, 1, 'parse_dom_tx_rx_los'], + 'tx_fault': [QSFP_DOM_OFFSET, 4, 1, 'parse_dom_tx_fault'], + 'tx_disable': [QSFP_DOM_OFFSET, 86, 1, 'parse_dom_tx_disable'], + 'power_lpmode': [QSFP_DOM_OFFSET, 93, 1, 'parse_dom_power_control'], + 'power_override': [QSFP_DOM_OFFSET, 93, 1, 'parse_dom_power_control'], + 'Temperature': [QSFP_DOM_OFFSET, 22, 2, 'parse_temperature'], + 'Voltage': [QSFP_DOM_OFFSET, 26, 2, 'parse_voltage'], + 'ChannelMonitor': [QSFP_DOM_OFFSET, 34, 16, 'parse_channel_monitor_params'], + 'ChannelMonitor_TxPower': + [QSFP_DOM_OFFSET, 34, 24, 'parse_channel_monitor_params_with_tx_power'], + + 'cable_type': [QSFP_INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], + 'cable_length': [QSFP_INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], + 'connector': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'type': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'encoding': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'ext_identifier': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'ext_rateselect_compliance': + [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'nominal_bit_rate': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'specification_compliance': + [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'type_abbrv_name': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'manufacturer': [QSFP_INFO_OFFSET, 20, 16, 'parse_vendor_name'], + 'vendor_oui': [QSFP_INFO_OFFSET, 37, 3, 'parse_vendor_oui'], + 'model': [QSFP_INFO_OFFSET, 40, 16, 'parse_vendor_pn'], + 'hardware_rev': [QSFP_INFO_OFFSET, 56, 2, 'parse_vendor_rev'], + 'serial': [QSFP_INFO_OFFSET, 68, 16, 'parse_vendor_sn'], + 'vendor_date': [QSFP_INFO_OFFSET, 84, 8, 'parse_vendor_date'], + 'dom_capability': [QSFP_INFO_OFFSET, 92, 1, 'parse_dom_capability'], + 'dom_rev': [QSFP_DOM_OFFSET, 1, 1, 'parse_sfp_dom_rev'], + 'ModuleThreshold': [QSFP_DOM_OFFSET1, 128, 24, 'parse_module_threshold_values'], + 'ChannelThreshold': [QSFP_DOM_OFFSET1, 176, 16, 'parse_channel_threshold_values'], +} + +sff8472_parser = { + 'Temperature': [SFP_DOM_OFFSET, 96, 2, 'parse_temperature'], + 'Voltage': [SFP_DOM_OFFSET, 98, 2, 'parse_voltage'], + 'ChannelMonitor': [SFP_DOM_OFFSET, 100, 6, 'parse_channel_monitor_params'], + + 'cable_type': [SFP_INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], + 'cable_length': [SFP_INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], + 'connector': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'type': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'encoding': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'ext_identifier': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'ext_rateselect_compliance': + [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'nominal_bit_rate': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'specification_compliance': + [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'type_abbrv_name': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'manufacturer': [SFP_INFO_OFFSET, 20, 16, 'parse_vendor_name'], + 'vendor_oui': [SFP_INFO_OFFSET, 37, 3, 'parse_vendor_oui'], + 'model': [SFP_INFO_OFFSET, 40, 16, 'parse_vendor_pn'], + 'hardware_rev': [SFP_INFO_OFFSET, 56, 4, 'parse_vendor_rev'], + 'serial': [SFP_INFO_OFFSET, 68, 16, 'parse_vendor_sn'], + 'vendor_date': [SFP_INFO_OFFSET, 84, 8, 'parse_vendor_date'], + 'ModuleThreshold': [SFP_DOM_OFFSET, 0, 56, 'parse_alarm_warning_threshold'], +} + + +class Sfp(SfpBase): + """ + DELLEMC Platform-specific Sfp class + """ + BASE_RES_PATH = "/sys/bus/pci/devices/0000:04:00.0/resource0" + + def __init__(self, index=0, sfp_type=0, eeprom_path=''): + SfpBase.__init__(self) + self.sfp_type = sfp_type + self.index = index + self.eeprom_path = eeprom_path + self.qsfpInfo = sff8436InterfaceId() + self.qsfpDomInfo = sff8436Dom() + self.sfpInfo = sff8472InterfaceId() + self.sfpDomInfo = sff8472Dom(None,1) + + def pci_mem_read(self, mm, offset): + mm.seek(offset) + read_data_stream = mm.read(4) + reg_val = struct.unpack('I', read_data_stream) + mem_val = str(reg_val)[1:-2] + # print "reg_val read:%x"%reg_val + return mem_val + + def pci_mem_write(self, mm, offset, data): + mm.seek(offset) + # print "data to write:%x"%data + mm.write(struct.pack('I', data)) + + def pci_set_value(self, resource, val, offset): + fd = os.open(resource, os.O_RDWR) + mm = mmap.mmap(fd, 0) + val = self.pci_mem_write(mm, offset, val) + mm.close() + os.close(fd) + return val + + def pci_get_value(self, resource, offset): + fd = os.open(resource, os.O_RDWR) + mm = mmap.mmap(fd, 0) + val = self.pci_mem_read(mm, offset) + mm.close() + os.close(fd) + return val + + def _read_eeprom_bytes(self, eeprom_path, offset, num_bytes): + eeprom_raw = [] + try: + eeprom = open(eeprom_path, mode="rb", buffering=0) + except IOError: + return None + + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + try: + eeprom.seek(offset) + raw = eeprom.read(num_bytes) + except IOError: + eeprom.close() + return None + + try: + for n in range(0, num_bytes): + eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + except BaseException: + eeprom.close() + return None + + eeprom.close() + return eeprom_raw + + def _get_eeprom_data(self, eeprom_key): + eeprom_data = None + page_offset = None + + if(self.sfp_type == 'QSFP'): + page_offset = sff8436_parser[eeprom_key][PAGE_OFFSET] + eeprom_data_raw = self._read_eeprom_bytes( + self.eeprom_path, + (sff8436_parser[eeprom_key][PAGE_OFFSET] + + sff8436_parser[eeprom_key][KEY_OFFSET]), + sff8436_parser[eeprom_key][KEY_WIDTH]) + if (eeprom_data_raw is not None): + # Offset 128 is used to retrieve sff8436InterfaceId Info + # Offset 0 is used to retrieve sff8436Dom Info + if (page_offset == 128): + if ( self.qsfpInfo is None): + return None + eeprom_data = getattr( + self.qsfpInfo, sff8436_parser[eeprom_key][FUNC_NAME])( + eeprom_data_raw, 0) + else: + if ( self.qsfpDomInfo is None): + return None + eeprom_data = getattr( + self.qsfpDomInfo, sff8436_parser[eeprom_key][FUNC_NAME])( + eeprom_data_raw, 0) + else: + page_offset = sff8472_parser[eeprom_key][PAGE_OFFSET] + eeprom_data_raw = self._read_eeprom_bytes( + self.eeprom_path, + (sff8472_parser[eeprom_key][PAGE_OFFSET] + + sff8472_parser[eeprom_key][KEY_OFFSET]), + sff8472_parser[eeprom_key][KEY_WIDTH]) + if (eeprom_data_raw is not None): + # Offset 0 is used to retrieve sff8472InterfaceId Info + # Offset 256 is used to retrieve sff8472Dom Info + if (page_offset == 0): + if ( self.sfpInfo is None): + return None + eeprom_data = getattr( + self.sfpInfo, sff8472_parser[eeprom_key][FUNC_NAME])( + eeprom_data_raw, 0) + else: + if ( self.sfpDomInfo is None): + return None + eeprom_data = getattr( + self.sfpDomInfo, sff8472_parser[eeprom_key][FUNC_NAME])( + eeprom_data_raw, 0) + + return eeprom_data + + def get_transceiver_info(self): + """ + Retrieves transceiver info of this SFP + """ + transceiver_info_dict = {} + compliance_code_dict = {} + transceiver_info_dict = dict.fromkeys(info_dict_keys, 'N/A') + # BaseInformation + iface_data = self._get_eeprom_data('type') + if (iface_data is not None): + connector = iface_data['data']['Connector']['value'] + encoding = iface_data['data']['EncodingCodes']['value'] + ext_id = iface_data['data']['Extended Identifier']['value'] + rate_identifier = iface_data['data']['RateIdentifier']['value'] + identifier = iface_data['data']['type']['value'] + type_abbrv_name=iface_data['data']['type_abbrv_name']['value'] + if(self.sfp_type == 'QSFP'): + bit_rate = str( + iface_data['data']['Nominal Bit Rate(100Mbs)']['value']) + for key in qsfp_compliance_code_tup: + if key in iface_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = iface_data['data']['Specification compliance']['value'][key]['value'] + for key in qsfp_cable_length_tup: + if key in iface_data['data']: + cable_type = key + cable_length = str(iface_data['data'][key]['value']) + else: + bit_rate = str( + iface_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) + for key in sfp_compliance_code_tup: + if key in iface_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = iface_data['data']['Specification compliance']['value'][key]['value'] + for key in sfp_cable_length_tup: + if key in iface_data['data']: + cable_type = key + cable_length = str(iface_data['data'][key]['value']) + else: + return transceiver_info_dict + + # Vendor Date + vendor_date_data = self._get_eeprom_data('vendor_date') + if (vendor_date_data is not None): + vendor_date = vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] + else: + return transceiver_info_dict + + # Vendor Name + vendor_name_data = self._get_eeprom_data('manufacturer') + if (vendor_name_data is not None): + vendor_name = vendor_name_data['data']['Vendor Name']['value'] + else: + return transceiver_info_dict + + # Vendor OUI + vendor_oui_data = self._get_eeprom_data('vendor_oui') + if (vendor_oui_data is not None): + vendor_oui = vendor_oui_data['data']['Vendor OUI']['value'] + else: + return transceiver_info_dict + + # Vendor PN + vendor_pn_data = self._get_eeprom_data('model') + if (vendor_pn_data is not None): + vendor_pn = vendor_pn_data['data']['Vendor PN']['value'] + else: + return transceiver_info_dict + + # Vendor Revision + vendor_rev_data = self._get_eeprom_data('hardware_rev') + if (vendor_rev_data is not None): + vendor_rev = vendor_rev_data['data']['Vendor Rev']['value'] + else: + return transceiver_info_dict + + # Vendor Serial Number + vendor_sn_data = self._get_eeprom_data('serial') + if (vendor_sn_data is not None): + vendor_sn = vendor_sn_data['data']['Vendor SN']['value'] + else: + return transceiver_info_dict + + # Fill The Dictionary and return + transceiver_info_dict['type'] = identifier + transceiver_info_dict['hardware_rev'] = vendor_rev + transceiver_info_dict['serial'] = vendor_sn + transceiver_info_dict['manufacturer'] = vendor_name + transceiver_info_dict['model'] = vendor_pn + transceiver_info_dict['connector'] = connector + transceiver_info_dict['encoding'] = encoding + transceiver_info_dict['ext_identifier'] = ext_id + transceiver_info_dict['ext_rateselect_compliance'] = rate_identifier + transceiver_info_dict['cable_type'] = cable_type + transceiver_info_dict['cable_length'] = cable_length + transceiver_info_dict['nominal_bit_rate'] = bit_rate + transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) + transceiver_info_dict['vendor_date'] = vendor_date + transceiver_info_dict['vendor_oui'] = vendor_oui + transceiver_info_dict['type_abbrv_name']=type_abbrv_name + + return transceiver_info_dict + + def get_transceiver_threshold_info(self): + """ + Retrieves transceiver threshold info of this SFP + """ + transceiver_dom_threshold_dict = {} + transceiver_dom_threshold_dict = dict.fromkeys( + threshold_dict_keys, 'N/A') + + # Module Threshold + module_threshold_data = self._get_eeprom_data('ModuleThreshold') + if (self.sfp_type == 'QSFP'): + # Channel Threshold + channel_threshold_data = self._get_eeprom_data('ChannelThreshold') + + if (channel_threshold_data is not None and module_threshold_data is not None): + transceiver_dom_threshold_dict['temphighalarm'] = module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_dict['temphighwarning'] = module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_dict['templowalarm'] = module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_dict['templowwarning'] = module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_dict['vcchighalarm'] = module_threshold_data['data']['VccHighAlarm']['value'] + transceiver_dom_threshold_dict['vcchighwarning'] = module_threshold_data['data']['VccHighWarning']['value'] + transceiver_dom_threshold_dict['vcclowalarm'] = module_threshold_data['data']['VccLowAlarm']['value'] + transceiver_dom_threshold_dict['vcclowwarning'] = module_threshold_data['data']['VccLowWarning']['value'] + transceiver_dom_threshold_dict['rxpowerhighalarm'] = channel_threshold_data['data']['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerhighwarning'] = channel_threshold_data['data']['RxPowerHighWarning']['value'] + transceiver_dom_threshold_dict['rxpowerlowalarm'] = channel_threshold_data['data']['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerlowwarning'] = channel_threshold_data['data']['RxPowerLowWarning']['value'] + transceiver_dom_threshold_dict['txbiashighalarm'] = channel_threshold_data['data']['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_dict['txbiashighwarning'] = channel_threshold_data['data']['TxBiasHighWarning']['value'] + transceiver_dom_threshold_dict['txbiaslowalarm'] = channel_threshold_data['data']['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_dict['txbiaslowwarning'] = channel_threshold_data['data']['TxBiasLowWarning']['value'] + + else: + return transceiver_dom_threshold_dict + else: + #SFP + if (module_threshold_data is not None): + #Threshold Data + transceiver_dom_threshold_dict['temphighalarm'] = module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_dict['templowalarm'] = module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_dict['temphighwarning'] = module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_dict['templowwarning'] = module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_dict['vcchighalarm'] = module_threshold_data['data']['VoltageHighAlarm']['value'] + transceiver_dom_threshold_dict['vcclowalarm'] = module_threshold_data['data']['VoltageLowAlarm']['value'] + transceiver_dom_threshold_dict['vcchighwarning'] = module_threshold_data['data']['VoltageHighWarning']['value'] + transceiver_dom_threshold_dict['vcclowwarning'] = module_threshold_data['data']['VoltageLowWarning']['value'] + transceiver_dom_threshold_dict['txbiashighalarm'] = module_threshold_data['data']['BiasHighAlarm']['value'] + transceiver_dom_threshold_dict['txbiaslowalarm'] = module_threshold_data['data']['BiasLowAlarm']['value'] + transceiver_dom_threshold_dict['txbiashighwarning'] = module_threshold_data['data']['BiasHighWarning']['value'] + transceiver_dom_threshold_dict['txbiaslowwarning'] = module_threshold_data['data']['BiasLowWarning']['value'] + transceiver_dom_threshold_dict['txpowerhighalarm'] = module_threshold_data['data']['TXPowerHighAlarm']['value'] + transceiver_dom_threshold_dict['txpowerlowalarm'] = module_threshold_data['data']['TXPowerLowAlarm']['value'] + transceiver_dom_threshold_dict['txpowerhighwarning'] = module_threshold_data['data']['TXPowerHighWarning']['value'] + transceiver_dom_threshold_dict['txpowerlowwarning'] = module_threshold_data['data']['TXPowerLowWarning']['value'] + transceiver_dom_threshold_dict['rxpowerhighalarm'] = module_threshold_data['data']['RXPowerHighAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerlowalarm'] = module_threshold_data['data']['RXPowerLowAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerhighwarning'] = module_threshold_data['data']['RXPowerHighWarning']['value'] + transceiver_dom_threshold_dict['rxpowerlowwarning'] = module_threshold_data['data']['RXPowerLowWarning']['value'] + else: + return transceiver_dom_threshold_dict + + return transceiver_dom_threshold_dict + + def get_transceiver_bulk_status(self): + """ + Retrieves transceiver bulk status of this SFP + """ + tx_bias_list = [] + rx_power_list = [] + transceiver_dom_dict = {} + transceiver_dom_dict = dict.fromkeys(dom_dict_keys, 'N/A') + + # RxLos + rx_los = self.get_rx_los() + + # TxFault + tx_fault = self.get_tx_fault() + + # ResetStatus + reset_state = self.get_reset_status() + + # LowPower Mode + lp_mode = self.get_lpmode() + + # TxDisable + tx_disable = self.get_tx_disable() + + # TxDisable Channel + tx_disable_channel = self.get_tx_disable_channel() + + # Temperature + temperature = self.get_temperature() + + # Voltage + voltage = self.get_voltage() + + # Channel Monitor + tx_power_list = self.get_tx_power() + + # tx bias + tx_bias_list = self.get_tx_bias() + + # rx power + rx_power_list = self.get_rx_power() + + if (len(tx_bias_list) != 0): + transceiver_dom_dict['tx1bias'] = tx_bias_list[0] + transceiver_dom_dict['tx2bias'] = tx_bias_list[1] + transceiver_dom_dict['tx3bias'] = tx_bias_list[2] + transceiver_dom_dict['tx4bias'] = tx_bias_list[3] + + if (len(rx_power_list) != 0): + transceiver_dom_dict['rx1power'] = rx_power_list[0] + transceiver_dom_dict['rx2power'] = rx_power_list[1] + transceiver_dom_dict['rx3power'] = rx_power_list[2] + transceiver_dom_dict['rx4power'] = rx_power_list[3] + + if (len(tx_power_list) != 0): + transceiver_dom_dict['tx1power'] = tx_power_list[0] + transceiver_dom_dict['tx2power'] = tx_power_list[1] + transceiver_dom_dict['tx3power'] = tx_power_list[2] + transceiver_dom_dict['tx4power'] = tx_power_list[3] + + transceiver_dom_dict['rx_los'] = rx_los + transceiver_dom_dict['tx_fault'] = tx_fault + transceiver_dom_dict['reset_status'] = reset_state + transceiver_dom_dict['power_lpmode'] = lp_mode + transceiver_dom_dict['tx_disable'] = tx_disable + transceiver_dom_dict['tx_disable_channel'] = tx_disable_channel + transceiver_dom_dict['temperature'] = temperature + transceiver_dom_dict['voltage'] = voltage + + return transceiver_dom_dict + + def get_name(self): + """ + Retrieves the name of the sfp + Returns : QSFP or QSFP+ or QSFP28 + """ + + iface_data = self._get_eeprom_data('type') + if (iface_data is not None): + identifier = iface_data['data']['type']['value'] + else: + return None + + return identifier + + def get_presence(self): + """ + Retrieves the presence of the sfp + Returns : True if sfp is present and false if it is absent + """ + # Check for invalid port_num + + # Port offset starts with 0x4004 + port_offset = 16388 + ((self.index-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == ""): + return False + + # Mask off 4th bit for presence + if(self.sfp_type == 'QSFP'): + mask = (1 << 4) + + # Mask off 1st bit for presence 65,66 + if (self.sfp_type == 'SFP'): + mask = (1 << 0) + # ModPrsL is active low + if reg_value & mask == 0: + return True + + return False + + def get_model(self): + """ + Retrieves the model number (or part number) of the sfp + """ + vendor_pn_data = self._get_eeprom_data('model') + if (vendor_pn_data is not None): + vendor_pn = vendor_pn_data['data']['Vendor PN']['value'] + else: + return None + + return vendor_pn + + def get_serial(self): + """ + Retrieves the serial number of the sfp + """ + vendor_sn_data = self._get_eeprom_data('serial') + if (vendor_sn_data is not None): + vendor_sn = vendor_sn_data['data']['Vendor SN']['value'] + else: + return None + + return vendor_sn + + def get_reset_status(self): + """ + Retrives the reset status of SFP + """ + reset_status = False + if (self.sfp_type == 'QSFP'): + # Port offset starts with 0x4000 + port_offset = 16384 + ((self.index-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == ""): + return reset_status + + # Mask off 4th bit for reset status + mask = (1 << 4) + + if ((reg_value & mask) == 0): + reset_status = True + else: + reset_status = False + + return reset_status + + def get_rx_los(self): + """ + Retrieves the RX LOS (lost-of-signal) status of SFP + """ + rx_los = None + rx_los_list = [] + if (self.sfp_type == 'QSFP'): + rx_los_data = self._get_eeprom_data('rx_los') + if (rx_los_data is not None): + rx_los = rx_los_data['data']['Rx1LOS']['value'] + if (rx_los is 'On'): + rx_los_list.append(True) + else: + rx_los_list.append(False) + rx_los = rx_los_data['data']['Rx2LOS']['value'] + if (rx_los is 'On'): + rx_los_list.append(True) + else: + rx_los_list.append(False) + rx_los = rx_los_data['data']['Rx3LOS']['value'] + if (rx_los is 'On'): + rx_los_list.append(True) + else: + rx_los_list.append(False) + rx_los = rx_los_data['data']['Rx4LOS']['value'] + if (rx_los is 'On'): + rx_los_list.append(True) + else: + rx_los_list.append(False) + + if (rx_los_list[0] and rx_los_list[1] + and rx_los_list[2] and rx_los_list[3]): + rx_los = True + else: + rx_los = False + else: + rx_los_data = self._read_eeprom_bytes(self.eeprom_path, SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if (rx_los_data is not None): + data = int(rx_los_data[0], 16) + rx_los = (sffbase().test_bit(data, 1) != 0) + + return rx_los + + def get_tx_fault(self): + """ + Retrieves the TX fault status of SFP + """ + tx_fault = None + tx_fault_list = [] + if (self.sfp_type == 'QSFP'): + tx_fault_data = self._get_eeprom_data('tx_fault') + if (tx_fault_data is not None): + tx_fault = tx_fault_data['data']['Tx1Fault']['value'] + if (tx_fault is 'On'): + tx_fault_list.append(True) + else: + tx_fault_list.append(False) + tx_fault = tx_fault_data['data']['Tx2Fault']['value'] + if (tx_fault is 'On'): + tx_fault_list.append(True) + else: + tx_fault_list.append(False) + tx_fault = tx_fault_data['data']['Tx3Fault']['value'] + if (tx_fault is 'On'): + tx_fault_list.append(True) + else: + tx_fault_list.append(False) + tx_fault = tx_fault_data['data']['Tx4Fault']['value'] + if (tx_fault is 'On'): + tx_fault_list.append(True) + else: + tx_fault_list.append(False) + + if (tx_fault_list[0] and tx_fault_list[1] + and tx_fault_list[2] and tx_fault_list[3]): + tx_fault = True + else: + tx_fault = False + + else: + tx_fault_data = self._read_eeprom_bytes(self.eeprom_path, SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if (tx_fault_data is not None): + data = int(tx_fault_data[0], 16) + tx_fault = (sffbase().test_bit(data, 2) != 0) + + return tx_fault + + def get_tx_disable(self): + """ + Retrieves the tx_disable status of this SFP + """ + tx_disable = None + tx_disable_list = [] + if (self.sfp_type == 'QSFP'): + tx_disable_data = self._get_eeprom_data('tx_disable') + if (tx_disable_data is not None): + tx_disable = tx_disable_data['data']['Tx1Disable']['value'] + if (tx_disable is 'On'): + tx_disable_list.append(True) + else: + tx_disable_list.append(False) + tx_disable = tx_disable_data['data']['Tx2Disable']['value'] + if (tx_disable is 'On'): + tx_disable_list.append(True) + else: + tx_disable_list.append(False) + tx_disable = tx_disable_data['data']['Tx3Disable']['value'] + if (tx_disable is 'On'): + tx_disable_list.append(True) + else: + tx_disable_list.append(False) + tx_disable = tx_disable_data['data']['Tx4Disable']['value'] + if (tx_disable is 'On'): + tx_disable_list.append(True) + else: + tx_disable_list.append(False) + + if (tx_disable_list[0] and tx_disable_list[1] + and tx_disable_list[2] and tx_disable_list[3]): + tx_disable = True + else: + tx_disable = False + + else: + tx_disable_data = self._read_eeprom_bytes(self.eeprom_path, SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if (tx_disable_data is not None): + data = int(tx_disable_data[0], 16) + tx_disable_hard = (sffbase().test_bit(data, SFP_TX_DISABLE_HARD_BIT) != 0) + tx_disable_soft = (sffbase().test_bit(data, SFP_TX_DISABLE_SOFT_BIT) != 0) + tx_disable = tx_disable_hard | tx_disable_soft + + + return tx_disable + + def get_tx_disable_channel(self): + """ + Retrieves the TX disabled channels in this SFP + """ + tx_disable = None + tx_disable_list = [] + tx_disable_channel = 0 + + if (self.sfp_type == 'QSFP'): + tx_disable_data = self._get_eeprom_data('tx_disable') + if (tx_disable_data is not None): + tx_disable = tx_disable_data['data']['Tx1Disable']['value'] + if (tx_disable is 'On'): + tx_disable_list.append(1) + else: + tx_disable_list.append(0) + tx_disable = tx_disable_data['data']['Tx2Disable']['value'] + if (tx_disable is 'On'): + tx_disable_list.append(1) + else: + tx_disable_list.append(0) + tx_disable = tx_disable_data['data']['Tx3Disable']['value'] + if (tx_disable is 'On'): + tx_disable_list.append(1) + else: + tx_disable_list.append(0) + tx_disable = tx_disable_data['data']['Tx4Disable']['value'] + if (tx_disable is 'On'): + tx_disable_list.append(1) + else: + tx_disable_list.append(0) + + bit4 = int(tx_disable_list[3]) * 8 + bit3 = int(tx_disable_list[2]) * 4 + bit2 = int(tx_disable_list[1]) * 2 + bit1 = int(tx_disable_list[0]) * 1 + + tx_disable_channel = hex(bit4 + bit3 + bit2 + bit1) + + return tx_disable_channel + + def get_lpmode(self): + """ + Retrieves the lpmode(low power mode) of this SFP + """ + lpmode_state = False + if (self.sfp_type == 'QSFP'): + + # Port offset starts with 0x4000 + port_offset = 16384 + ((self.index-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == ""): + return lpmode_state + + # Mask off 6th bit for lpmode + mask = (1 << 6) + + # LPMode is active high + if reg_value & mask == 0: + lpmode_state = False + else: + lpmode_state = True + + return lpmode_state + + def get_power_override(self): + """ + Retrieves the power-override status of this SFP + """ + power_override_state = False + + if (self.sfp_type == 'QSFP'): + power_override_data = self._get_eeprom_data('power_override') + if (power_override_data is not None): + power_override = power_override_data['data']['PowerOverRide']['value'] + if (power_override is 'On'): + power_override_state = True + else: + power_override_state = False + + return power_override_state + + def get_temperature(self): + """ + Retrieves the temperature of this SFP + """ + temperature = None + + temperature_data = self._get_eeprom_data('Temperature') + if (temperature_data is not None): + temperature = temperature_data['data']['Temperature']['value'] + + return temperature + + def get_voltage(self): + """ + Retrieves the supply voltage of this SFP + """ + voltage = None + + voltage_data = self._get_eeprom_data('Voltage') + if (voltage_data is not None): + voltage = voltage_data['data']['Vcc']['value'] + + return voltage + + def get_tx_bias(self): + """ + Retrieves the TX bias current of this SFP + """ + tx_bias = None + tx_bias_list = [] + + tx_bias_data = self._get_eeprom_data('ChannelMonitor') + if (tx_bias_data is not None): + if (self.sfp_type == 'QSFP'): + tx_bias = tx_bias_data['data']['TX1Bias']['value'] + tx_bias_list.append(tx_bias) + tx_bias = tx_bias_data['data']['TX2Bias']['value'] + tx_bias_list.append(tx_bias) + tx_bias = tx_bias_data['data']['TX3Bias']['value'] + tx_bias_list.append(tx_bias) + tx_bias = tx_bias_data['data']['TX4Bias']['value'] + tx_bias_list.append(tx_bias) + else: + tx1_bias = tx_bias_data['data']['TXBias']['value'] + return [tx1_bias, "N/A", "N/A", "N/A"] + + return tx_bias_list + + def get_rx_power(self): + """ + Retrieves the received optical power for this SFP + """ + rx_power = None + rx_power_list = [] + + rx_power_data = self._get_eeprom_data('ChannelMonitor') + if (rx_power_data is not None): + if (self.sfp_type == 'QSFP'): + rx_power = rx_power_data['data']['RX1Power']['value'] + rx_power_list.append(rx_power) + rx_power = rx_power_data['data']['RX2Power']['value'] + rx_power_list.append(rx_power) + rx_power = rx_power_data['data']['RX3Power']['value'] + rx_power_list.append(rx_power) + rx_power = rx_power_data['data']['RX4Power']['value'] + rx_power_list.append(rx_power) + else: + rx1_pw = rx_power_data['data']['RXPower']['value'] + return [rx1_pw, "N/A", "N/A", "N/A"] + + return rx_power_list + + def get_tx_power(self): + """ + Retrieves the TX power of this SFP + """ + tx_power_list = [] + if(self.sfp_type == 'QSFP'): + # 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. + qspf_dom_capability_data = self._get_eeprom_data('dom_capability') + qsfp_dom_rev_data = self._get_eeprom_data('dom_rev') + if (qspf_dom_capability_data is not None and qsfp_dom_rev_data is not None): + qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value'] + qsfp_tx_power_support = qspf_dom_capability_data['data']['Tx_power_support']['value'] + else: + return tx_power_list + + # 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. + if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')): + return tx_power_list + else: + channel_monitor_data = self._get_eeprom_data('ChannelMonitor_TxPower') + if (channel_monitor_data is not None): + tx1_pw = channel_monitor_data['data']['TX1Power']['value'] + tx2_pw = channel_monitor_data['data']['TX2Power']['value'] + tx3_pw = channel_monitor_data['data']['TX3Power']['value'] + tx4_pw = channel_monitor_data['data']['TX4Power']['value'] + else: + return tx_power_list + + else: + channel_monitor_data = self._get_eeprom_data('ChannelMonitor') + if (channel_monitor_data is not None): + tx1_pw = channel_monitor_data['data']['TXPower']['value'] + tx2_pw = 'N/A' + tx3_pw = 'N/A' + tx4_pw = 'N/A' + else: + return tx_power_list + + tx_power_list.append(tx1_pw) + tx_power_list.append(tx2_pw) + tx_power_list.append(tx3_pw) + tx_power_list.append(tx4_pw) + + return tx_power_list + + def reset(self): + """ + Reset the SFP and returns all user settings to their default state + """ + if (self.sfp_type == 'QSFP'): + # Port offset starts with 0x4000 + port_offset = 16384 + ((self.index-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == ""): + return False + + # Mask off 4th bit for reset + mask = (1 << 4) + + # ResetL is active low + reg_value = reg_value & ~mask + + # Convert our register value back to a hex string and write back + self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + + # Sleep 1 second to allow it to settle + time.sleep(1) + + reg_value = reg_value | mask + + # Convert our register value back to a hex string and write back + self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + + return True + + else: + return False + + def set_lpmode(self, lpmode): + """ + Sets the lpmode(low power mode) of this SFP + """ + if (self.sfp_type == 'QSFP'): + # Port offset starts with 0x4000 + port_offset = 16384 + ((self.index-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == ""): + return False + + # Mask off 6th bit for lowpower mode + mask = (1 << 6) + + # LPMode is active high; set or clear the bit accordingly + if lpmode is True: + reg_value = reg_value | mask + else: + reg_value = reg_value & ~mask + + # Convert our register value back to a hex string and write back + self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + + return True + + else: + return False + + def tx_disable(self, tx_disable): + """ + Disable SFP TX for all channels + """ + return False + + def tx_disable_channel(self, channel, disable): + """ + Sets the tx_disable for specified SFP channels + """ + return False + + def set_power_override(self, power_override, power_set): + """ + Sets SFP power level using power_override and power_set + """ + return False + + def get_status(self): + """ + Retrieves the operational status of the device + """ + reset = self.get_reset_status() + + if (reset == True): + status = False + else: + status = True + + return status diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/thermal.py new file mode 100644 index 000000000000..d8c4ef14d5b2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/thermal.py @@ -0,0 +1,170 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC S5232F +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Thermals' information which are available in the platform +# +######################################################################## + + +try: + from sonic_platform_base.thermal_base import ThermalBase + from sonic_platform.ipmihelper import IpmiSensor +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Thermal(ThermalBase): + """DellEMC Platform-specific Thermal class""" + + # [ Sensor-Name, Sensor-ID ] + SENSOR_MAPPING = [ + ['CPU On-board', 0xe], + ['ASIC On-board', 0x2], + ['System Front Left', 0x3], + ['System Front Middle', 0x1], + ['System Front Right', 0x4], + ['Inlet Airflow Sensor', 0x5], + ['PSU1 Airflow Sensor', 0x7], + ['PSU2 Airflow Sensor', 0x8] + ] + + def __init__(self, thermal_index=0): + ThermalBase.__init__(self) + self.index = thermal_index + 1 + self.sensor = IpmiSensor(self.SENSOR_MAPPING[self.index - 1][1]) + + def get_name(self): + """ + Retrieves the name of the thermal + + Returns: + string: The name of the thermal + """ + return self.SENSOR_MAPPING[self.index - 1][0] + + def get_presence(self): + """ + Retrieves the presence of the thermal + + Returns: + bool: True if thermal is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the Thermal + + Returns: + string: Model/part number of Thermal + """ + return 'NA' + + def get_serial(self): + """ + Retrieves the serial number of the Thermal + + Returns: + string: Serial number of Thermal + """ + return 'NA' + + def get_status(self): + """ + Retrieves the operational status of the thermal + + Returns: + A boolean value, True if thermal is operating properly, + False if not + """ + return True + + def get_temperature(self): + """ + Retrieves current temperature reading from thermal + + Returns: + A float number of current temperature in Celsius up to + nearest thousandth of one degree Celsius, e.g. 30.125 + """ + is_valid, temperature = self.sensor.get_reading() + if not is_valid: + temperature = 0 + + return float(temperature) + + def get_high_threshold(self): + """ + Retrieves the high threshold temperature of thermal + + Returns: + A float number, the high threshold temperature of thermal in + Celsius up to nearest thousandth of one degree Celsius, + e.g. 30.125 + """ + is_valid, high_threshold = self.sensor.get_threshold("UpperCritical") + if not is_valid: + high_threshold = 0 + + return float(high_threshold) + + def get_low_threshold(self): + """ + Retrieves the low threshold temperature of thermal + + Returns: + A float number, the low threshold temperature of thermal in + Celsius up to nearest thousandth of one degree Celsius, + e.g. 30.125 + """ + is_valid, low_threshold = self.sensor.get_threshold("LowerNonRecoverable") + if not is_valid: + low_threshold = 0 + + return float(low_threshold) + + def get_high_critical_threshold(self): + """ + Retrieves the high critical threshold temperature of thermal + Returns: + A float number, the high critical threshold temperature of + thermal in Celsius up to nearest thousandth of one degree + Celsius, e.g. 30.125 + """ + is_valid, high_crit_threshold = self.sensor.get_threshold("UpperNonRecoverable") + if not is_valid: + high_crit_threshold = 0 + + return float(high_crit_threshold) + + + def set_high_threshold(self, temperature): + """ + Sets the high threshold temperature of thermal + + Args : + temperature: A float number up to nearest thousandth of one + degree Celsius, e.g. 30.125 + Returns: + A boolean, True if threshold is set successfully, False if + not + """ + # Thermal threshold values are pre-defined based on HW. + return False + + def set_low_threshold(self, temperature): + """ + Sets the low threshold temperature of thermal + + Args : + temperature: A float number up to nearest thousandth of one + degree Celsius, e.g. 30.125 + Returns: + A boolean, True if threshold is set successfully, False if + not + """ + # Thermal threshold values are pre-defined based on HW. + return False diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/watchdog.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/watchdog.py new file mode 100644 index 000000000000..878d5f4f952d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/watchdog.py @@ -0,0 +1,210 @@ +#!/usr/bin/env python + +######################################################################## +# +# DELLEMC S5232f +# +# Abstract base class for implementing a platform-specific class with +# which to interact with a hardware watchdog module in SONiC +# +######################################################################## + +try: + import ctypes + import subprocess + from sonic_platform_base.watchdog_base import WatchdogBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class _timespec(ctypes.Structure): + _fields_ = [ + ('tv_sec', ctypes.c_long), + ('tv_nsec', ctypes.c_long) + ] + + +class Watchdog(WatchdogBase): + """ + Abstract base class for interfacing with a hardware watchdog module + """ + + TIMERS = [15,20,30,40,50,60,65,70] + + armed_time = 0 + timeout = 0 + CLOCK_MONOTONIC = 1 + + def __init__(self): + self._librt = ctypes.CDLL('librt.so.1', use_errno=True) + self._clock_gettime = self._librt.clock_gettime + self._clock_gettime.argtypes=[ctypes.c_int, ctypes.POINTER(_timespec)] + + def _get_command_result(self, cmdline): + try: + proc = subprocess.Popen(cmdline.split(), stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + result = stdout.rstrip('\n') + except OSError: + result = None + + return result + + def _get_reg_val(self): + # 0x31 = CPLD I2C Base Address + # 0x07 = Watchdog Function Register + value = self._get_command_result("/usr/sbin/i2cget -y 601 0x31 0x07") + if not value: + return None + else: + return int(value, 16) + + def _set_reg_val(self,val): + # 0x31 = CPLD I2C Base Address + # 0x07 = Watchdog Function Register + value = self._get_command_result("/usr/sbin/i2cset -y 601 0x31 0x07 %s" + % (val)) + return value + + def _get_time(self): + """ + To get clock monotonic time + """ + ts = _timespec() + if self._clock_gettime(self.CLOCK_MONOTONIC, ctypes.pointer(ts)) != 0: + self._errno = ctypes.get_errno() + return 0 + return ts.tv_sec + ts.tv_nsec * 1e-9 + + def arm(self, seconds): + """ + Arm the hardware watchdog with a timeout of seconds. + If the watchdog is currently armed, calling this function will + simply reset the timer to the provided value. If the underlying + hardware does not support the value provided in , this + method should arm the watchdog with the *next greater* + available value. + + Returns: + An integer specifying the *actual* number of seconds the + watchdog was armed with. On failure returns -1. + """ + timer_offset = -1 + for key,timer_seconds in enumerate(self.TIMERS): + if seconds <= timer_seconds: + timer_offset = key + seconds = timer_seconds + break + + if timer_offset == -1: + return -1 + + # Extracting 5th to 7th bits for WD timer values + # 000 - 15 sec + # 001 - 20 sec + # 010 - 30 sec + # 011 - 40 sec + # 100 - 50 sec + # 101 - 60 sec + # 110 - 65 sec + # 111 - 70 sec + reg_val = self._get_reg_val() + wd_timer_offset = (reg_val >> 4) & 0x7 + + if wd_timer_offset != timer_offset: + # Setting 5th to 7th bits + # value from timer_offset + self.disarm() + self._set_reg_val(reg_val | (timer_offset << 4)) + + if self.is_armed(): + # Setting last bit to WD Timer punch + # Last bit = WD Timer punch + self._set_reg_val(reg_val & 0xFE) + + self.armed_time = self._get_time() + self.timeout = seconds + return seconds + else: + # Setting 4th bit to enable WD + # 4th bit = Enable WD + reg_val = self._get_reg_val() + self._set_reg_val(reg_val | 0x8) + + self.armed_time = self._get_time() + self.timeout = seconds + return seconds + + def disarm(self): + """ + Disarm the hardware watchdog + + Returns: + A boolean, True if watchdog is disarmed successfully, False + if not + """ + if self.is_armed(): + # Setting 4th bit to disable WD + # 4th bit = Disable WD + reg_val = self._get_reg_val() + self._set_reg_val(reg_val & 0xF7) + + self.armed_time = 0 + self.timeout = 0 + return True + + return False + + def is_armed(self): + """ + Retrieves the armed state of the hardware watchdog. + + Returns: + A boolean, True if watchdog is armed, False if not + """ + + # Extracting 4th bit to get WD Enable/Disable status + # 0 - Disabled WD + # 1 - Enabled WD + reg_val = self._get_reg_val() + wd_offset = (reg_val >> 3) & 1 + + return bool(wd_offset) + + def get_remaining_time(self): + """ + If the watchdog is armed, retrieve the number of seconds + remaining on the watchdog timer + + Returns: + An integer specifying the number of seconds remaining on + their watchdog timer. If the watchdog is not armed, returns + -1. + + S5232 doesnot have hardware support to show remaining time. + Due to this limitation, this API is implemented in software. + This API would return correct software time difference if it + is called from the process which armed the watchdog timer. + If this API called from any other process, it would return + 0. If the watchdog is not armed, this API would return -1. + """ + if not self.is_armed(): + return -1 + + if self.armed_time > 0 and self.timeout != 0: + cur_time = self._get_time() + + if cur_time <= 0: + return 0 + + diff_time = int(cur_time - self.armed_time) + + if diff_time > self.timeout: + return self.timeout + else: + return self.timeout - diff_time + + return 0 + diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/systemd/platform-modules-s5232f.service b/platform/broadcom/sonic-platform-modules-dell/s5232f/systemd/platform-modules-s5232f.service index 7fb3801e339e..0ca31b522bd4 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/systemd/platform-modules-s5232f.service +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/systemd/platform-modules-s5232f.service @@ -1,6 +1,6 @@ [Unit] Description=Dell S5232f Platform modules -Before=pmon.service +Before=pmon.service determine-reboot-cause.service DefaultDependencies=no [Service] diff --git a/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/pcisysfs.py b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/pcisysfs.py deleted file mode 100755 index 047618e057c8..000000000000 --- a/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/pcisysfs.py +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/python -# Copyright (c) 2015 Dell Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -# -# THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR -# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT -# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS -# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. -# -# See the Apache Version 2.0 License for specific language governing -# permissions and limitations under the License. - -import struct -import sys -import getopt -from os import * -from mmap import * - -def usage(): - ''' This is the Usage Method ''' - - print '\t\t pcisysfs.py --get --offset --res ' - print '\t\t pcisysfs.py --set --val --offset --res ' - sys.exit(1) - -def pci_mem_read(mm,offset): - mm.seek(offset) - read_data_stream=mm.read(4) - print "" - reg_val=struct.unpack('I',read_data_stream) - print "reg_val read:%x"%reg_val - return reg_val - -def pci_mem_write(mm,offset,data): - mm.seek(offset) - print "data to write:%x"%data - mm.write(struct.pack('I',data)) - -def pci_set_value(resource,val,offset): - fd=open(resource,O_RDWR) - mm=mmap(fd,0) - pci_mem_write(mm,offset,val) - -def pci_get_value(resource,offset): - fd=open(resource,O_RDWR) - mm=mmap(fd,0) - pci_mem_read(mm,offset) - -def main(argv): - - ''' The main function will read the user input from the - command line argument and process the request ''' - - opts = '' - val = '' - choice = '' - resource = '' - offset = '' - - try: - opts, args = getopt.getopt(argv, "hgsv:" , \ - ["val=","res=","offset=","help", "get", "set"]) - - except getopt.GetoptError: - usage() - - for opt,arg in opts: - - if opt in ('-h','--help'): - choice = 'help' - - elif opt in ('-g', '--get'): - choice = 'get' - - elif opt in ('-s', '--set'): - choice = 'set' - - elif opt == '--res': - resource = arg - - elif opt == '--val': - val = int(arg,16) - - elif opt == '--offset': - offset = int(arg,16) - - if choice == 'set' and val != '' and offset !='' and resource !='': - pci_set_value(resource,val,offset) - - elif choice == 'get' and offset != '' and resource !='': - pci_get_value(resource,offset) - - else: - usage() - -#Calling the main method -if __name__ == "__main__": - main(sys.argv[1:]) - diff --git a/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/platform_sensors.py index 6f7ba9b55b09..f276e6879d2c 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/platform_sensors.py +++ b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/platform_sensors.py @@ -1,9 +1,9 @@ -#!/usr/bin/python +#!/usr/bin/python3 # On S5248F, the BaseBoard Management Controller is an # autonomous subsystem provides monitoring and management # facility independent of the host CPU. IPMI standard # protocol is used with ipmitool to fetch sensor details. -# Current script support X00 board only. X01 support will +# Current script support X00 board only. X01 support will # be added soon. This provies support for the # following objects: # * Onboard temperature sensors @@ -11,11 +11,9 @@ # * PSU -import os import sys import logging import subprocess -import commands S5248F_MAX_FAN_TRAYS = 4 S5248F_MAX_PSUS = 2 @@ -39,7 +37,7 @@ def ipmi_sensor_dump(): status = 1 global ipmi_sdr_list ipmi_cmd = IPMI_SENSOR_DATA - status, ipmi_sdr_list = commands.getstatusoutput(ipmi_cmd) + status, ipmi_sdr_list = subprocess.getstatusoutput(ipmi_cmd) if status: logging.error('Failed to execute:' + ipmi_sdr_list) @@ -56,7 +54,7 @@ def get_pmc_register(reg_name): output = item.strip() if output is None: - print('\nFailed to fetch: ' + reg_name + ' sensor ') + print('\nFailed to fetch: ' + reg_name + ' sensor ') sys.exit(0) output = output.split('|')[1] @@ -72,18 +70,18 @@ def print_temperature_sensors(): print("\nOnboard Temperature Sensors:") - print ' PT_Left_temp: ',\ - (get_pmc_register('PT_Left_temp')) - print ' PT_Mid_temp: ',\ - (get_pmc_register('PT_Mid_temp')) - print ' PT_Right_temp: ',\ - (get_pmc_register('PT_Right_temp')) - print ' Broadcom Temp: ',\ - (get_pmc_register('NPU_Near_temp')) - print ' Inlet Airflow Temp: ',\ - (get_pmc_register('ILET_AF_temp')) - print ' CPU Temp: ',\ - (get_pmc_register('CPU_temp')) + print(' PT_Left_temp: ', + get_pmc_register('PT_Left_temp')) + print(' PT_Mid_temp: ', + get_pmc_register('PT_Mid_temp')) + print(' PT_Right_temp: ', + get_pmc_register('PT_Right_temp')) + print(' Broadcom Temp: ', + get_pmc_register('NPU_Near_temp')) + print(' Inlet Airflow Temp: ', + get_pmc_register('ILET_AF_temp')) + print(' CPU Temp: ', + get_pmc_register('CPU_temp')) ipmi_sensor_dump() @@ -97,63 +95,63 @@ def print_fan_tray(tray): Fan_Status = [' Normal', ' Abnormal'] Airflow_Direction = ['B2F', 'F2B'] - print ' Fan Tray ' + str(tray) + ':' + print(' Fan Tray ' + str(tray) + ':') if (tray == 1): fan1_status = int(get_pmc_register('FAN1_Front_stat'), 16) fan2_status = int(get_pmc_register('FAN1_Rear_stat'), 16) - print ' Fan1 Speed: ',\ - get_pmc_register('FAN1_Front_rpm') - print ' Fan2 Speed: ',\ - get_pmc_register('FAN1_Rear_rpm') - print ' Fan1 State: ',\ - Fan_Status[fan1_status] - print ' Fan2 State: ',\ - Fan_Status[fan2_status] + print(' Fan1 Speed: ', + get_pmc_register('FAN1_Front_rpm')) + print(' Fan2 Speed: ', + get_pmc_register('FAN1_Rear_rpm')) + print(' Fan1 State: ', + Fan_Status[fan1_status]) + print(' Fan2 State: ', + Fan_Status[fan2_status]) elif (tray == 2): fan1_status = int(get_pmc_register('FAN2_Front_stat'), 16) fan2_status = int(get_pmc_register('FAN2_Rear_stat'), 16) - print ' Fan1 Speed: ',\ - get_pmc_register('FAN2_Front_rpm') - print ' Fan2 Speed: ',\ - get_pmc_register('FAN2_Rear_rpm') - print ' Fan1 State: ',\ - Fan_Status[fan1_status] - print ' Fan2 State: ',\ - Fan_Status[fan2_status] + print(' Fan1 Speed: ', + get_pmc_register('FAN2_Front_rpm')) + print(' Fan2 Speed: ', + get_pmc_register('FAN2_Rear_rpm')) + print(' Fan1 State: ', + Fan_Status[fan1_status]) + print(' Fan2 State: ', + Fan_Status[fan2_status]) elif (tray == 3): fan1_status = int(get_pmc_register('FAN3_Front_stat'), 16) fan2_status = int(get_pmc_register('FAN3_Rear_stat'), 16) - print ' Fan1 Speed: ',\ - get_pmc_register('FAN3_Front_rpm') - print ' Fan2 Speed: ',\ - get_pmc_register('FAN3_Rear_rpm') - print ' Fan1 State: ',\ - Fan_Status[fan1_status] - print ' Fan2 State: ',\ - Fan_Status[fan2_status] + print(' Fan1 Speed: ', + get_pmc_register('FAN3_Front_rpm')) + print(' Fan2 Speed: ', + get_pmc_register('FAN3_Rear_rpm')) + print(' Fan1 State: ', + Fan_Status[fan1_status]) + print(' Fan2 State: ', + Fan_Status[fan2_status]) elif (tray == 4): fan1_status = int(get_pmc_register('FAN4_Front_stat'), 16) fan2_status = int(get_pmc_register('FAN4_Rear_stat'), 16) - print ' Fan1 Speed: ',\ - get_pmc_register('FAN4_Front_rpm') - print ' Fan2 Speed: ',\ - get_pmc_register('FAN4_Rear_rpm') - print ' Fan1 State: ',\ - Fan_Status[fan1_status] - print ' Fan2 State: ',\ - Fan_Status[fan2_status] + print(' Fan1 Speed: ', + get_pmc_register('FAN4_Front_rpm')) + print(' Fan2 Speed: ', + get_pmc_register('FAN4_Rear_rpm')) + print(' Fan1 State: ', + Fan_Status[fan1_status]) + print(' Fan2 State: ', + Fan_Status[fan2_status]) print('\nFan Trays:') @@ -163,7 +161,7 @@ def print_fan_tray(tray): if (get_pmc_register(fan_presence)): print_fan_tray(tray) else: - print '\n Fan Tray ' + str(tray + 1) + ': Not present' + print('\n Fan Tray ' + str(tray + 1) + ': Not present') def get_psu_presence(index): """ @@ -176,9 +174,9 @@ def get_psu_presence(index): ret_status = 1 if index == 1: - status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU1_DATA_DOCKER) + status, ipmi_cmd_ret = subprocess.getstatusoutput(IPMI_PSU1_DATA_DOCKER) elif index == 2: - ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU2_DATA_DOCKER) + ret_status, ipmi_cmd_ret = subprocess.getstatusoutput(IPMI_PSU2_DATA_DOCKER) #if ret_status: # print ipmi_cmd_ret @@ -214,54 +212,54 @@ def print_psu(psu): # psu1_fan_status = int(get_pmc_register('PSU1_status'),16) - print ' PSU1:' - print ' FAN Normal Temperature: ',\ - get_pmc_register('PSU1_temp') - print ' FAN AirFlow Temperature: ',\ - get_pmc_register('PSU1_AF_temp') - print ' FAN RPM: ',\ - get_pmc_register('PSU1_rpm') + print(' PSU1:') + print(' FAN Normal Temperature: ', + get_pmc_register('PSU1_temp')) + print(' FAN AirFlow Temperature: ', + get_pmc_register('PSU1_AF_temp')) + print(' FAN RPM: ', + get_pmc_register('PSU1_rpm')) # print ' FAN Status: ', Psu_Fan_Status[psu1_fan_status] # PSU input & output monitors - print ' Input Voltage: ',\ - get_pmc_register('PSU1_In_volt') - print ' Output Voltage: ',\ - get_pmc_register('PSU1_Out_volt') - print ' Input Power: ',\ - get_pmc_register('PSU1_In_watt') - print ' Output Power: ',\ - get_pmc_register('PSU1_Out_watt') - print ' Input Current: ',\ - get_pmc_register('PSU1_In_amp') - print ' Output Current: ',\ - get_pmc_register('PSU1_Out_amp') + print(' Input Voltage: ', + get_pmc_register('PSU1_In_volt')) + print(' Output Voltage: ', + get_pmc_register('PSU1_Out_volt')) + print(' Input Power: ', + get_pmc_register('PSU1_In_watt')) + print(' Output Power: ', + get_pmc_register('PSU1_Out_watt')) + print(' Input Current: ', + get_pmc_register('PSU1_In_amp')) + print(' Output Current: ', + get_pmc_register('PSU1_Out_amp')) else: # psu2_fan_status = int(get_pmc_register('PSU1_status'),16) - print ' PSU2:' - print ' FAN Normal Temperature: ',\ - get_pmc_register('PSU2_temp') - print ' FAN AirFlow Temperature: ',\ - get_pmc_register('PSU2_AF_temp') - print ' FAN RPM: ',\ - get_pmc_register('PSU2_rpm') + print(' PSU2:') + print(' FAN Normal Temperature: ', + get_pmc_register('PSU2_temp')) + print(' FAN AirFlow Temperature: ', + get_pmc_register('PSU2_AF_temp')) + print(' FAN RPM: ', + get_pmc_register('PSU2_rpm')) # print ' FAN Status: ', Psu_Fan_Status[psu2_fan_status] # PSU input & output monitors - print ' Input Voltage: ',\ - get_pmc_register('PSU2_In_volt') - print ' Output Voltage: ',\ - get_pmc_register('PSU2_Out_volt') - print ' Input Power: ',\ - get_pmc_register('PSU2_In_watt') - print ' Output Power: ',\ - get_pmc_register('PSU2_Out_watt') - print ' Input Current: ',\ - get_pmc_register('PSU2_In_amp') - print ' Output Current: ',\ - get_pmc_register('PSU2_Out_amp') + print(' Input Voltage: ', + get_pmc_register('PSU2_In_volt')) + print(' Output Voltage: ', + get_pmc_register('PSU2_Out_volt')) + print(' Input Power: ', + get_pmc_register('PSU2_In_watt')) + print(' Output Power: ', + get_pmc_register('PSU2_Out_watt')) + print(' Input Current: ', + get_pmc_register('PSU2_In_amp')) + print(' Output Current: ', + get_pmc_register('PSU2_Out_amp')) print('\nPSUs:') @@ -270,8 +268,7 @@ def print_psu(psu): if (get_psu_presence(psu)): print_psu(psu) else: - print '\n PSU ', psu, 'Not present' - -print '\n Total Power: ',\ - get_pmc_register('PSU_Total_watt') + print('\n PSU ', psu, 'Not present') +print('\n Total Power: ', + get_pmc_register('PSU_Total_watt')) diff --git a/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/s5248f_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/s5248f_platform.sh index 77032d643397..e006e53cfc49 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/s5248f_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/s5248f_platform.sh @@ -82,7 +82,7 @@ switch_board_modsel() { do port_addr=$(( 16384 + ((i - 1) * 16))) hex=$( printf "0x%x" $port_addr ) - python /usr/bin/pcisysfs.py --set --offset $hex --val 0x10 --res $resource > /dev/null 2>&1 + /usr/bin/pcisysfs.py --set --offset $hex --val 0x10 --res $resource > /dev/null 2>&1 done } @@ -129,7 +129,7 @@ platform_firmware_versions() { #This enables the led control for CPU and default states 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 + /usr/bin/pcisysfs.py --set --offset 0x24 --val 0x194 --res $resource > /dev/null 2>&1 } init_devnum @@ -145,7 +145,7 @@ if [ "$1" == "init" ]; then switch_board_qsfp "new_device" switch_board_modsel switch_board_led_default - #python /usr/bin/qsfp_irq_enable.py + #/usr/bin/qsfp_irq_enable.py platform_firmware_versions elif [ "$1" == "deinit" ]; then diff --git a/platform/broadcom/sonic-platform-modules-dell/s5296f/cfg/s5296f-modules.conf b/platform/broadcom/sonic-platform-modules-dell/s5296f/cfg/s5296f-modules.conf new file mode 100644 index 000000000000..17045f6b25ab --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5296f/cfg/s5296f-modules.conf @@ -0,0 +1,19 @@ +# /etc/modules: kernel modules to load at boot time. +# +# This file contains the names of kernel modules that should be loaded +# at boot time, one per line. Lines beginning with "#" are ignored. + +i2c-i801 +i2c-isch +i2c-ismt +i2c-dev +i2c-mux +i2c-smbus + +i2c-mux-gpio +i2c-mux-pca954x + +ipmi_devintf +ipmi_si +dell_s5296f_fpga_ocores +i2c_ocores diff --git a/platform/broadcom/sonic-platform-modules-dell/s5296f/modules/Makefile b/platform/broadcom/sonic-platform-modules-dell/s5296f/modules/Makefile new file mode 100644 index 000000000000..d1d103b5f136 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5296f/modules/Makefile @@ -0,0 +1,2 @@ +obj-m := dell_s5296f_fpga_ocores.o + diff --git a/platform/broadcom/sonic-platform-modules-dell/s5296f/modules/dell_s5296f_fpga_ocores.c b/platform/broadcom/sonic-platform-modules-dell/s5296f/modules/dell_s5296f_fpga_ocores.c new file mode 100644 index 000000000000..b9a50c69b225 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5296f/modules/dell_s5296f_fpga_ocores.c @@ -0,0 +1,1626 @@ +/* +* 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_i2ccore.c +* @brief This is a driver to interface with Linux Open Cores drivber for FPGA i2c access +* +************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include //siginfo +#include //rcu_read_lock +#include //kernel_version +#include +#include +#include +#include +#include + + +void __iomem * fpga_base_addr = NULL; +void __iomem * fpga_ctl_addr = NULL; + +#define DRIVER_NAME "fpgapci" +#define PCI_NUM_BARS 4 + +#ifdef DEBUG +# define PRINT(fmt, ...) printk(fmt, ##__VA_ARGS__) +#else +# define PRINT(fmt, ...) +#endif + +/* Maximum size of driver buffer (allocated with kalloc()). + * Needed to copy data from user to kernel space, among other + * things. */ +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; + + /* kernels virtual addr. for the mapped BARs */ + void * __iomem bar[PCI_NUM_BARS]; + + /* length of each memory region. Used for error checking. */ + size_t bar_length[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; + + unsigned int irq_first; + unsigned int irq_length; + unsigned int irq_assigned; + unsigned int xcvr_intr_count; +}; + +static int use_irq = 1; +module_param(use_irq, int, 0644); +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."); + + +/* Xilinx FPGA PCIE info: */ +/* Non-VGA unclassified device: Xilinx Corporation Device 7021*/ +/* Subsystem: Xilinx Corporation Device 0007 */ +//#define VENDOR 0x10EE +#define DEVICE 0x7021 +static phys_addr_t fpga_phys_addr; + +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +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; +}; + +/* global variable declarations */ + +/* Static function declarations */ +static int fpgapci_probe(struct pci_dev *dev, const struct pci_device_id *id); +static void fpgapci_remove(struct pci_dev *dev); + +static int scan_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev); +static int map_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev); +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; +}; +/* 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_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_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 */ + +enum { + STATE_DONE = 0, + STATE_INIT, + STATE_ADDR, + STATE_ADDR10, + STATE_START, + STATE_WRITE, + STATE_READ, + STATE_STOP, + STATE_ERROR, +}; + +#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 i2c_bus_controller_numb 1 +#define I2C_PCI_MAX_BUS (16) +#define I2C_PCI_MAX_BUS_REV00 (7) +#define DELL_I2C_CLOCK_LEGACY 0 +#define DELL_I2C_CLOCK_PRESERVE (~0U) +#define I2C_PCI_BUS_NUM_5 5 +#define I2C_PCI_BUS_NUM_7 7 +#define I2C_PCI_BUS_NUM_8 8 +#define I2C_PCI_BUS_NUM_10 10 +#define I2C_PCI_BUS_NUM_12 12 +#define I2C_PCI_BUS_NUM_16 16 + +#define IRQ_LTCH_STS 0x20 +#define PRSNT_LTCH_STS 0x10 + +#define PORT_CTRL_OFFSET 0x4000 +#define PORT_STS_OFFSET 0x4004 +#define PORT_IRQ_STS_OFFSET 0x4008 +#define PORT_IRQ_EN_OFFSET 0x400C +#define MB_BRD_REV_TYPE 0x0008 +#define MB_BRD_REV_MASK 0x00f0 +#define MB_BRD_REV_00 0x0000 +#define MB_BRD_REV_01 0x0010 +#define MB_BRD_REV_02 0x0020 +#define MB_BRD_REV_03 0x0030 +#define MB_BRD_TYPE_MASK 0x000f +#define BRD_TYPE_Z9232_NON_NEBS 0x0 +#define BRD_TYPE_Z9232_NEBS 0x1 +#define BRD_TYPE_Z9264_NON_NEBS 0x2 +#define BRD_TYPE_Z9264_NEBS 0x3 +#define BRD_TYPE_S5212_NON_NEBS 0x4 +#define BRD_TYPE_S5212_NEBS 0x5 +#define BRD_TYPE_S5224_NON_NEBS 0x6 +#define BRD_TYPE_S5224_NEBS 0x7 +#define BRD_TYPE_S5248_NON_NEBS 0x8 +#define BRD_TYPE_S5248_NEBS 0x9 +#define BRD_TYPE_S5296_NON_NEBS 0xa +#define BRD_TYPE_S5296_NEBS 0xb +#define BRD_TYPE_S5232_NON_NEBS 0xc +#define BRD_TYPE_S5232_NEBS 0xd + +#define FPGA_CTL_REG_SIZE 0x6000 +#define MSI_VECTOR_MAP_MASK 0x1f +#define MSI_VECTOR_MAP1 0x58 +#define I2C_CH1_MSI_MAP_VECT_8 0x00000008 +#define I2C_CH2_MSI_MAP_VECT_9 0x00000120 +#define I2C_CH3_MSI_MAP_VECT_10 0x00002800 +#define I2C_CH4_MSI_MAP_VECT_11 0x00058000 +#define I2C_CH5_MSI_MAP_VECT_12 0x00c00000 +#define I2C_CH6_MSI_MAP_VECT_13 0x15000000 +#define MSI_VECTOR_MAP2 0x5c +#define I2C_CH7_MSI_MAP_VECT_14 0x0000000e +#define MSI_VECTOR_MAP3 0x9c +#define I2C_CH8_MSI_MAP_VECT_8 0x00800000 +#define I2C_CH8_MSI_MAP_VECT_16 0x01100000 +#define I2C_CH9_MSI_MAP_VECT_9 0x12000000 +#define I2C_CH9_MSI_MAP_VECT_17 0x24000000 +#define MSI_VECTOR_MAP4 0xa0 +#define I2C_CH10_MSI_MAP_VECT_10 0x0000000a +#define I2C_CH10_MSI_MAP_VECT_18 0x00000012 +#define I2C_CH11_MSI_MAP_VECT_11 0x00000120 +#define I2C_CH11_MSI_MAP_VECT_19 0x00000260 +#define I2C_CH12_MSI_MAP_VECT_12 0x00002800 +#define I2C_CH12_MSI_MAP_VECT_20 0x00005000 +#define I2C_CH13_MSI_MAP_VECT_13 0x00058000 +#define I2C_CH13_MSI_MAP_VECT_21 0x000a8000 +#define I2C_CH14_MSI_MAP_VECT_14 0x00c00000 +#define I2C_CH14_MSI_MAP_VECT_22 0x01600000 +#define I2C_CH15_MSI_MAP_VECT_8 0x10000000 +#define I2C_CH15_MSI_MAP_VECT_23 0x2e000000 +#define MSI_VECTOR_MAP5 0xa4 +#define I2C_CH16_MSI_MAP_VECT_9 0x00000009 +#define I2C_CH16_MSI_MAP_VECT_24 0x00000018 + +#define MSI_VECTOR_REV_00 16 +#define MSI_VECTOR_REV_01 32 + +#define FPGA_MSI_VECTOR_ID_4 4 +#define FPGA_MSI_VECTOR_ID_5 5 +#define FPGA_MSI_VECTOR_ID_8 8 +#define FPGA_MSI_VECTOR_ID_9 9 +#define FPGA_MSI_VECTOR_ID_10 10 +#define FPGA_MSI_VECTOR_ID_11 11 +#define FPGA_MSI_VECTOR_ID_12 12 +#define FPGA_MSI_VECTOR_ID_13 13 +#define FPGA_MSI_VECTOR_ID_14 14 +#define FPGA_MSI_VECTOR_ID_15 15 /*Note: this is external MSI vector id */ +#define FPGA_MSI_VECTOR_ID_16 16 +#define FPGA_MSI_VECTOR_ID_17 17 +#define FPGA_MSI_VECTOR_ID_18 18 +#define FPGA_MSI_VECTOR_ID_19 19 +#define FPGA_MSI_VECTOR_ID_20 20 +#define FPGA_MSI_VECTOR_ID_21 21 +#define FPGA_MSI_VECTOR_ID_22 22 +#define FPGA_MSI_VECTOR_ID_23 23 +#define FPGA_MSI_VECTOR_ID_24 24 + + + +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 void fpgai2c_reg_set_8(struct fpgalogic_i2c *i2c, int reg, u8 value) +{ + 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)); +} + +static void fpgai2c_reg_set_32(struct fpgalogic_i2c *i2c, int reg, u8 value) +{ + 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)); +} + +static void fpgai2c_reg_set_32be(struct fpgalogic_i2c *i2c, int reg, u8 value) +{ + 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)); +} + +static inline u8 fpgai2c_reg_get_16(struct fpgalogic_i2c *i2c, int reg) +{ + 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)); +} + +static inline u8 fpgai2c_reg_get_16be(struct fpgalogic_i2c *i2c, int reg) +{ + 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)); +} + +static inline void fpgai2c_reg_set(struct fpgalogic_i2c *i2c, int reg, u8 value) +{ + i2c->reg_set(i2c, reg, value); + udelay(100); +} + +static inline u8 fpgai2c_reg_get(struct fpgalogic_i2c *i2c, int reg) +{ + udelay(100); + return i2c->reg_get(i2c, reg); +} + +static void fpgai2c_dump(struct fpgalogic_i2c *i2c) +{ + u8 tmp; + + 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_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_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); +} + +static void fpgai2c_stop(struct fpgalogic_i2c *i2c) +{ + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); +} + +/* + * dell_get_mutex must be called prior to calling this function. + */ +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; + } + + /* 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); + + 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); + + 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 (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); + } + + 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); + 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)); + 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); +} +static DEVICE_ATTR(port_msi, S_IRUGO, get_mod_msi, NULL); + +static struct attribute *port_attrs[] = { + &dev_attr_port_msi.attr, + NULL, +}; + +static struct attribute_group port_attr_grp = { + .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); + 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)); + 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)); + } + } + 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; +} + +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); + 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)); + 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); + iowrite32( IRQ_LTCH_STS|PRSNT_LTCH_STS,fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + } + } + 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; +} + +static void fpgai2c_process(struct fpgalogic_i2c *i2c) +{ + struct i2c_msg *msg = i2c->msg; + u8 stat = fpgai2c_reg_get(i2c, FPGAI2C_REG_STATUS); + + PRINT("fpgai2c_process in. status reg :0x%x\n", stat); + + 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); + 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; + } + + + /* error? */ + if (stat & FPGAI2C_REG_STAT_ARBLOST) { + i2c->state = STATE_ERROR; + PRINT("fpgai2c_process FPGAI2C_REG_STAT_ARBLOST FPGAI2C_REG_CMD_STOP\n"); + fpgai2c_stop(i2c); + return; + } + + 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_stop(i2c); + return; + } + } else + { + msg->buf[i2c->pos++] = fpgai2c_reg_get(i2c, FPGAI2C_REG_DATA); + } + + /* end of msg? */ + if (i2c->pos == msg->len) { + i2c->nmsgs--; + i2c->msg++; + i2c->pos = 0; + msg = i2c->msg; + + if (i2c->nmsgs) { /* end? */ + /* send start? */ + if (!(msg->flags & I2C_M_NOSTART)) { + + u8 addr = (msg->addr << 1); + + if (msg->flags & I2C_M_RD) + addr |= 1; + + i2c->state = STATE_START; + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, addr); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_START); + return; + } else + { + i2c->state = (msg->flags & I2C_M_RD) + ? STATE_READ : STATE_WRITE; + } + } else { + i2c->state = STATE_STOP; + fpgai2c_stop(i2c); + return; + } + } + + 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); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, i2c->pos == (msg->len-1) ? + 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++]); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_WRITE); + } +} + +static irqreturn_t fpgai2c_isr(int irq, void *dev_id) +{ + struct fpgalogic_i2c *i2c = dev_id; + fpgai2c_process(i2c); + + return IRQ_HANDLED; +} +void dell_get_mutex(struct fpgalogic_i2c *i2c) +{ + mutex_lock(&i2c->lock); +} + +/** + * dell_release_mutex - release mutex + */ +void dell_release_mutex(struct fpgalogic_i2c *i2c) +{ + mutex_unlock(&i2c->lock); +} + +static int fpgai2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) +{ + struct fpgalogic_i2c *i2c = i2c_get_adapdata(adap); + int ret; + unsigned long timeout = jiffies + msecs_to_jiffies(1000); + + i2c->msg = msgs; + i2c->pos = 0; + i2c->nmsgs = num; + i2c->state = (use_irq == 1) ? STATE_START : STATE_INIT; + + PRINT("i2c->msg->addr = 0x%x i2c->msg->flags = 0x%x\n",i2c->msg->addr,i2c->msg->flags); + PRINT("I2C_M_RD = 0x%x i2c->msg->addr << 1 = 0x%x\n",I2C_M_RD,i2c->msg->addr << 1); + + if (!use_irq) { + /* Handle the transfer */ + while (time_before(jiffies, timeout)) { + dell_get_mutex(i2c); + ret = fpgai2c_poll(i2c); + dell_release_mutex(i2c); + + if (i2c->state == STATE_DONE || i2c->state == STATE_ERROR) + return (i2c->state == STATE_DONE) ? num : ret; + + if (ret == 0) + timeout = jiffies + HZ; + + usleep_range(5, 15); + } + + i2c->state = STATE_ERROR; + + return -ETIMEDOUT; + + + } 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)); + + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, + (i2c->msg->addr << 1) | + ((i2c->msg->flags & I2C_M_RD) ? 1:0)); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_START); + + /* Interrupt mode */ + if (wait_event_timeout(i2c->wait, (i2c->state == STATE_ERROR) || + (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; + } + } + + 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; + } + + 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; +} + +static const struct i2c_algorithm fpgai2c_algorithm = { + .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; +} + +static int i2c_init_internal_data(void) +{ + 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; +} + + +static int i2c_pci_init (void) +{ + int i; + + if (num_bus == 0) { + board_rev_type = ioread32(fpga_ctl_addr + MB_BRD_REV_TYPE); + + 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)) { + switch (board_rev_type & MB_BRD_TYPE_MASK){ + case BRD_TYPE_S5212_NON_NEBS: + case BRD_TYPE_S5212_NEBS: + num_bus = I2C_PCI_BUS_NUM_5; + break; + case BRD_TYPE_S5224_NON_NEBS: + case BRD_TYPE_S5224_NEBS: + num_bus = I2C_PCI_BUS_NUM_7; + break; + case BRD_TYPE_Z9232_NON_NEBS: + case BRD_TYPE_Z9232_NEBS: + case BRD_TYPE_S5232_NON_NEBS: + case BRD_TYPE_S5232_NEBS: + num_bus = I2C_PCI_BUS_NUM_8; + break; + case BRD_TYPE_S5248_NON_NEBS: + case BRD_TYPE_S5248_NEBS: + num_bus = I2C_PCI_BUS_NUM_10; + break; + case BRD_TYPE_Z9264_NON_NEBS: + case BRD_TYPE_Z9264_NEBS: + num_bus = I2C_PCI_BUS_NUM_12; + break; + case BRD_TYPE_S5296_NON_NEBS: + case BRD_TYPE_S5296_NEBS: + num_bus = I2C_PCI_BUS_NUM_16; + break; + default: + num_bus = I2C_PCI_BUS_NUM_16; + printk("Wrong BRD_TYPE: 0x%x\n", board_rev_type); + break; + } + } else { + printk("Wrong board_rev_type 0x%x\n", board_rev_type); + } + } + + 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]); + + /* Initialize driver's itnernal data structures */ + i2c_init_internal_data(); + + 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].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)); + } + + 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]); + } + +} + +/* Find upstream PCIe root node. + * 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; + } +} + + +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); + } + } + + return 0; +} + + +/** + * Map the device memory regions into kernel virtual address space + * after verifying their sizes respect the minimum sizes needed, given + * by the bar_min_len[] array. + */ +static int map_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev) +{ + 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; + + + 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; + } + + 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); + + 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); + + 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; +} + +static void free_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev) +{ + int i; + + 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" + +/** + * @brief Register specific function with msi interrupt line + * @param dev Pointer to pci-device, which should be allocated + * @param int interrupt number relative to global interrupt number + * @return Returns error code or zero if success + * */ +static int register_intr_handler(struct pci_dev *dev, int irq_num_id) +{ + 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; + } + + 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 + * 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; + } + } 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 */ + 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; + } + } + + return err; +} +/* Mask for MSI Multi message enable bits */ +#define MSI_MME 0x70 +/** + * These enums define the type of interrupt scheme that the overall + * system uses. + */ +enum fpga_irq_type { + INT_MSI_SINGLE, + INT_MSI_MULTI, + INT_MSIX, + INT_NONE, + INT_FENCE /* Last item to guard from loop run-overs */ +}; +/** + * @def PCI_DEVICE_STATUS + * define the offset for STS register + * from the start of PCI config space as specified in the + * NVME_Comliance 1.0b. offset 06h:STS - Device status. + * This register has error status for NVME PCI Exress + * Card. After reading data from this reagister, the driver + * will identify if any error is set during the operation and + * report as kernel alert message. + */ +#define PCI_DEVICE_STATUS 0x6 +/** + * @def NEXT_MASK + * This indicates the location of the next capability item + * in the list. + */ +#define NEXT_MASK 0xFF00 +/** + * @def MSIXCAP_ID + * This bit indicates if the pointer leading to this position + * is a capability. + */ +#define MSIXCAP_ID 0x11 +/** + * @def MSICAP_ID + * This bit indicates if the pointer leading to this position + * is a capability. + */ +#define MSICAP_ID 0x5 + +/** + * @def CL_MASK + * This bit position indicates Capabilities List of the controller + * The controller should support the PCI Power Management cap as a + * minimum. + */ +#define CL_MASK 0x0010 + +/** + * @def CAP_REG + * Set to offset defined in NVME Spec 1.0b. + */ +#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; + + 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; + + + /* + * 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); + + pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control); + } +} +/** + * @brief Enables pcie-device and claims/remaps neccessary bar resources + * @param dev Pointer to pci-device, which should be allocated + * @return Returns error code or zero if success + * */ +static int fpgapci_setup_device(struct fpgapci_dev *fpgapci,struct pci_dev *dev) +{ + 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; + } + + /* 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); + + /* 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); + + if (map_bars(fpgapci, dev)) { + goto fail_map_bars; + } + + i2c_pci_init(); + + return 0; + /* ERROR HANDLING */ +fail_map_bars: + pci_release_regions(dev); +error_pci_req: + pci_disable_device(dev); +error_pci_en: + return -ENODEV; +} + +static int fpgapci_configure_msi(struct fpgapci_dev *fpgapci,struct pci_dev *dev) +{ + int err = 0, i; + int request_vec; + + 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); + + 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)) { + if (err < MSI_VECTOR_REV_01) { + goto error_disable_msi; + } + } + } + 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; + } + } + + 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); + 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); +error_no_msi: + return -ENOSPC; +} + +static int fpgapci_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + 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)); +#endif + fpgapci = kzalloc(sizeof(struct fpgapci_dev), GFP_KERNEL); + + if (!fpgapci) { + PRINT( "Couldn't allocate memory!\n"); + goto fail_kzalloc; + } + + fpgapci->pci_dev = dev; + dev_set_drvdata(&dev->dev, (void*)fpgapci); + + status = sysfs_create_group(&dev->dev.kobj, &port_attr_grp); + if (status) { + printk(KERN_INFO "%s:Cannot create sysfs\n", __FUNCTION__); + } + + fpgapci->upstream = find_upstream_dev (dev); + + 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 */ +error_cannot_configure: + 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"); +fail_kzalloc: + 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); + 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]); + } + } + pci_disable_msi(fpgapci->pci_dev); + free_bars (fpgapci, dev); + pci_disable_device(dev); + pci_release_regions(dev); + + kfree (fpgapci); +} + +static const struct pci_device_id fpgapci_ids[] = { + {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 */ +}; + +/* Initialize the driver module (but not any device) and register + * the module with the kernel PCI subsystem. */ +static int __init fpgapci_init(void) +{ + + if (pci_register_driver(&fpgapci_driver)) { + PRINT("pci_unregister_driver\n"); + pci_unregister_driver(&fpgapci_driver); + return -ENODEV; + } + + return 0; +} + +static void __exit fpgapci_exit(void) +{ + PRINT ("fpgapci_exit"); + + /* unregister this driver from the PCI bus driver */ + pci_unregister_driver(&fpgapci_driver); + +} + + +module_init (fpgapci_init); +module_exit (fpgapci_exit); +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/pcisysfs.py b/platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/pcisysfs.py similarity index 100% rename from platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/pcisysfs.py rename to platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/pcisysfs.py diff --git a/platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/platform_sensors.py new file mode 100755 index 000000000000..4c6ef3b229ab --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/platform_sensors.py @@ -0,0 +1,242 @@ +#!/usr/bin/python +# On S5296F, the BaseBoard Management Controller is an +# autonomous subsystem provides monitoring and management +# facility independent of the host CPU. IPMI standard +# protocol is used with ipmitool to fetch sensor details. +# Current script support X00 board only. X01 support will +# be added soon. This provies support for the +# following objects: +# * Onboard temperature sensors +# * FAN trays +# * PSU + + +import sys +import logging +import commands + +S5296F_MAX_FAN_TRAYS = 4 +S5296F_MAX_PSUS = 2 +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_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_sdr_list = "" + +# Dump sensor registers + + +def ipmi_sensor_dump(): + + global ipmi_sdr_list + ipmi_cmd = IPMI_SENSOR_DATA + status, ipmi_sdr_list = commands.getstatusoutput(ipmi_cmd) + + if status: + logging.error('Failed to execute:' + ipmi_sdr_list) + sys.exit(0) + +# Fetch a BMC register + + +def get_pmc_register(reg_name): + + output = None + for item in ipmi_sdr_list.split("\n"): + if reg_name in item: + output = item.strip() + + if output is None: + print('\nFailed to fetch: ' + reg_name + ' sensor ') + sys.exit(0) + + output = output.split('|')[1] + + logging.basicConfig(level=logging.DEBUG) + return output + + +# Print the information for temperature sensors + + +def print_temperature_sensors(): + + print("\nOnboard Temperature Sensors:") + + print ' PT_Left_temp: ',\ + (get_pmc_register('PT_Left_temp')) + print ' PT_Mid_temp: ',\ + (get_pmc_register('PT_Mid_temp')) + print ' PT_Right_temp: ',\ + (get_pmc_register('PT_Right_temp')) + print ' Broadcom Temp: ',\ + (get_pmc_register('NPU_Near_temp')) + print ' Inlet Airflow Temp: ',\ + (get_pmc_register('ILET_AF_temp')) + print ' CPU Temp: ',\ + (get_pmc_register('CPU_temp')) + +ipmi_sensor_dump() + +print_temperature_sensors() + +# Print the information for 1 Fan Tray + + +def print_fan_tray(tray): + + Fan_Status = [' Normal', ' Abnormal'] + + print ' Fan Tray ' + str(tray) + ':' + + if (tray == 1): + + fan2_status = int(get_pmc_register('FAN1_Rear_stat'), 16) + + print ' Fan Speed: ',\ + get_pmc_register('FAN1_Rear_rpm') + print ' Fan State: ',\ + Fan_Status[fan2_status] + + elif (tray == 2): + + fan2_status = int(get_pmc_register('FAN2_Rear_stat'), 16) + + print ' Fan Speed: ',\ + get_pmc_register('FAN2_Rear_rpm') + print ' Fan State: ',\ + Fan_Status[fan2_status] + + elif (tray == 3): + + fan2_status = int(get_pmc_register('FAN3_Rear_stat'), 16) + + print ' Fan Speed: ',\ + get_pmc_register('FAN3_Rear_rpm') + print ' Fan State: ',\ + Fan_Status[fan2_status] + + elif (tray == 4): + + fan2_status = int(get_pmc_register('FAN4_Rear_stat'), 16) + + print ' Fan Speed: ',\ + get_pmc_register('FAN4_Rear_rpm') + print ' Fan State: ',\ + Fan_Status[fan2_status] + + +print('\nFan Trays:') + +for tray in range(1, S5296F_MAX_FAN_TRAYS + 1): + fan_presence = FAN_PRESENCE.format(tray) + if (get_pmc_register(fan_presence)): + print_fan_tray(tray) + else: + print '\n Fan Tray ' + str(tray + 1) + ': Not present' + + 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 + """ + status = 0 + + if index == 1: + 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: + # print ipmi_cmd_ret + # logging.error('Failed to execute ipmitool') + # sys.exit(0) + + psu_status = ipmi_cmd_ret + + if psu_status == '1': + status = 1 + + return status + + +# Print the information for PSU1, PSU2 +def print_psu(psu): + + # print ' Input: ', Psu_Input_Type[psu_input_type] + # print ' Type: ', Psu_Type[psu_type] + + # PSU FAN details + if (psu == 1): + + # psu1_fan_status = int(get_pmc_register('PSU1_status'),16) + + print ' PSU1:' + print ' FAN Normal Temperature: ',\ + get_pmc_register('PSU1_temp') + print ' FAN AirFlow Temperature: ',\ + get_pmc_register('PSU1_AF_temp') + print ' FAN RPM: ',\ + get_pmc_register('PSU1_rpm') + # print ' FAN Status: ', Psu_Fan_Status[psu1_fan_status] + + # PSU input & output monitors + print ' Input Voltage: ',\ + get_pmc_register('PSU1_In_volt') + print ' Output Voltage: ',\ + get_pmc_register('PSU1_Out_volt') + print ' Input Power: ',\ + get_pmc_register('PSU1_In_watt') + print ' Output Power: ',\ + get_pmc_register('PSU1_Out_watt') + print ' Input Current: ',\ + get_pmc_register('PSU1_In_amp') + print ' Output Current: ',\ + get_pmc_register('PSU1_Out_amp') + + else: + + # psu2_fan_status = int(get_pmc_register('PSU1_status'),16) + print ' PSU2:' + print ' FAN Normal Temperature: ',\ + get_pmc_register('PSU2_temp') + print ' FAN AirFlow Temperature: ',\ + get_pmc_register('PSU2_AF_temp') + print ' FAN RPM: ',\ + get_pmc_register('PSU2_rpm') + # print ' FAN Status: ', Psu_Fan_Status[psu2_fan_status] + + # PSU input & output monitors + print ' Input Voltage: ',\ + get_pmc_register('PSU2_In_volt') + print ' Output Voltage: ',\ + get_pmc_register('PSU2_Out_volt') + print ' Input Power: ',\ + get_pmc_register('PSU2_In_watt') + print ' Output Power: ',\ + get_pmc_register('PSU2_Out_watt') + print ' Input Current: ',\ + get_pmc_register('PSU2_In_amp') + print ' Output Current: ',\ + get_pmc_register('PSU2_Out_amp') + + +print('\nPSUs:') +for psu in range(1, S5296F_MAX_PSUS + 1): + #psu_presence = PSU_PRESENCE.format(psu) + if (get_psu_presence(psu)): + print_psu(psu) + else: + print '\n PSU ', psu, 'Not present' + +print '\n Total Power: ',\ + get_pmc_register('PSU_Total_watt') + diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/qsfp_irq_enable.py b/platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/qsfp_irq_enable.py similarity index 78% rename from platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/qsfp_irq_enable.py rename to platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/qsfp_irq_enable.py index e7442ba168f5..d9bf5b09411a 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/qsfp_irq_enable.py +++ b/platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/qsfp_irq_enable.py @@ -2,7 +2,6 @@ try: import struct - import sys from os import * from mmap import * @@ -11,7 +10,7 @@ BASE_RES_PATH = "/sys/bus/pci/devices/0000:04:00.0/resource0" PORT_START = 0 -PORT_END = 64 +PORT_END = 32 def pci_mem_write(mm, offset, data): @@ -22,12 +21,11 @@ def pci_mem_write(mm, offset, data): def pci_set_value(resource, val, offset): fd = open(resource, O_RDWR) mm = mmap(fd, 0) - val = pci_mem_write(mm, offset, val) + pci_mem_write(mm, offset, val) mm.close() close(fd) return val -#Enabled interrupt for qsfp and sfp for port_num in range(PORT_START, PORT_END+1): port_offset = 0x400c + ((port_num) * 16) - pci_set_value(BASE_RES_PATH, 0x31, port_offset) + pci_set_value(BASE_RES_PATH, 0x30, port_offset) diff --git a/platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/s5296f_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/s5296f_platform.sh new file mode 100755 index 000000000000..f69470756001 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/s5296f_platform.sh @@ -0,0 +1,176 @@ +#!/bin/bash + +init_devnum() { + found=0 + for devnum in 0 1; do + devname=`cat /sys/bus/i2c/devices/i2c-${devnum}/name` + # iSMT adapter can be at either dffd0000 or dfff0000 + if [[ $devname == 'SMBus iSMT adapter at '* ]]; then + found=1 + break + fi + done + + [ $found -eq 0 ] && echo "cannot find iSMT" && exit 1 +} + +# Attach/Detach syseeprom on CPU board +sys_eeprom() { + b='' + for bb in 0 1; do + if [ "$(cat /sys/bus/i2c/devices/i2c-${bb}/name)" = 'SMBus iSMT adapter at dff9f000' ]; then + b=$bb + break + fi + done + if [ "$b" = '' ]; then + echo "s5296f_platform: sys_eeprom : cannot find I2C bus!" + return + fi + + case $1 in + "new_device") echo 24c16 0x50 > /sys/bus/i2c/devices/i2c-${b}/$1 + ;; + + "delete_device") echo 0x50 > /sys/bus/i2c/devices/i2c-${b}/$1 + ;; + + *) echo "s5296f_platform: sys_eeprom : invalid command !" + ;; + esac +} + +#Attach/Detach the MUX connecting all QSFPs +switch_board_qsfp_mux() { + case $1 in + "new_device") + for ((i=603;i<=615;i++)); + do + echo "Attaching PCA9548 @ 0x74" + echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-$i/$1 + done + ;; + + "delete_device") + for ((i=603;i<=615;i++)); + do + echo "Detaching PCA9548 @ 0x74" + echo 0x74 > /sys/bus/i2c/devices/i2c-$i/$1 + done + ;; + + *) + echo "s5296f_platform: switch_board_qsfp_mux: invalid command !" + ;; + esac + sleep 2 +} + +#Attach/Detach 64 instances of EEPROM driver QSFP ports +#eeprom can dump data using below command +switch_board_qsfp() { + case $1 in + "new_device") + for ((i=2;i<=105;i++)); + do + echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 + done + ;; + + "delete_device") + for ((i=2;i<=105;i++)); + do + echo 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 + done + ;; + + *) echo "s5296f_platform: switch_board_qsfp: invalid command !" + ;; + esac +} + +#Modsel 64 ports to applicable QSFP type modules +#This enables the adapter to respond for i2c commands +switch_board_modsel() { + resource="/sys/bus/pci/devices/0000:04:00.0/resource0" + for ((i=1;i<=104;i++)); + do + port_addr=$(( 16384 + ((i - 1) * 16))) + hex=$( printf "0x%x" $port_addr ) + python /usr/bin/pcisysfs.py --set --offset $hex --val 0x10 --res $resource > /dev/null 2>&1 + done +} + +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 +} + +#This enables the led control for CPU and default states +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 +} +init_devnum + +if [ "$1" == "init" ]; then + modprobe i2c-dev + modprobe i2c-mux-pca954x force_deselect_on_exit=1 + modprobe ipmi_devintf + modprobe ipmi_si + modprobe i2c_ocores + modprobe dell_s5296f_fpga_ocores + sys_eeprom "new_device" + switch_board_qsfp_mux "new_device" + switch_board_qsfp "new_device" + 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_qsfp_mux "delete_device" + + modprobe -r i2c-mux-pca954x + modprobe -r i2c-dev +else + echo "s5296f_platform : Invalid option !" +fi + diff --git a/platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/sensors b/platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/sensors new file mode 100755 index 000000000000..d163a09cfc1b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5296f/scripts/sensors @@ -0,0 +1,3 @@ +#!/bin/bash +docker exec -i pmon sensors "$@" +docker exec -i pmon /usr/bin/platform_sensors.py "$@" diff --git a/platform/broadcom/sonic-platform-modules-dell/s5296f/systemd/platform-modules-s5296f.service b/platform/broadcom/sonic-platform-modules-dell/s5296f/systemd/platform-modules-s5296f.service new file mode 100644 index 000000000000..b58673d505ac --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5296f/systemd/platform-modules-s5296f.service @@ -0,0 +1,13 @@ +[Unit] +Description=Dell S5296f Platform modules +Before=pmon.service +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/s5296f_platform.sh init +ExecStop=/usr/local/bin/s5296f_platform.sh deinit +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/modules/dell_s6000_platform.c b/platform/broadcom/sonic-platform-modules-dell/s6000/modules/dell_s6000_platform.c index e8bcd312168f..cbf506940ac9 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/modules/dell_s6000_platform.c +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/modules/dell_s6000_platform.c @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/scripts/s6000_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s6000/scripts/s6000_platform.sh index bf6c730425e7..a98df43ef27b 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/scripts/s6000_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/scripts/s6000_platform.sh @@ -60,22 +60,43 @@ remove_i2c_devices() { done } +# Enable/Disable low power mode on all QSFP ports +switch_board_qsfp_lpmode() { + case $1 in + "enable") value=0xffff + ;; + "disable") value=0x0 + ;; + *) echo "s6000_platform: switch_board_qsfp_lpmode: invalid command $1!" + return + ;; + esac + echo $value > /sys/bus/platform/devices/dell-s6000-cpld.0/qsfp_lpmode +} + install_python_api_package() { device="/usr/share/sonic/device" platform=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) - if [ -e $device/$platform/sonic_platform-1.0-py2-none-any.whl ]; then - rv=$(pip install $device/$platform/sonic_platform-1.0-py2-none-any.whl) - fi + rv=$(pip install $device/$platform/sonic_platform-1.0-py2-none-any.whl) + rv=$(pip3 install $device/$platform/sonic_platform-1.0-py3-none-any.whl) } 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 + + rv=$(pip3 show sonic-platform > /dev/null 2>/dev/null) + if [ $? -eq 0 ]; then + rv=$(pip3 uninstall -y sonic-platform > /dev/null 2>/dev/null) fi } +# read SONiC immutable variables +[ -f /etc/sonic/sonic-environment ] && . /etc/sonic/sonic-environment + if [[ "$1" == "init" ]]; then depmod -a modprobe nvram @@ -86,6 +107,7 @@ if [[ "$1" == "init" ]]; then add_i2c_devices /usr/local/bin/set-fan-speed 15000 + switch_board_qsfp_lpmode "disable" /usr/local/bin/reset-qsfp elif [[ "$1" == "deinit" ]]; then remove_i2c_devices diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/__init__.py index 48057d290357..db8b45acb1b5 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/__init__.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/__init__.py @@ -1,2 +1,2 @@ -__all__ = ["platform", "chassis", "sfp", "psu", "thermal"] +__all__ = ["platform", "chassis", "fan", "fan_drawer", "sfp", "psu", "thermal"] from sonic_platform import * 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 8bb95cac1d63..7f6e9ec573f4 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 @@ -10,13 +10,11 @@ try: import os import time - import datetime import struct - import subprocess from sonic_platform_base.chassis_base import ChassisBase from sonic_platform.sfp import Sfp - from sonic_platform.eeprom import Eeprom - from sonic_platform.fan import Fan + from sonic_platform.eeprom import Eeprom, EepromS6000 + from sonic_platform.fan_drawer import FanDrawer from sonic_platform.psu import Psu from sonic_platform.thermal import Thermal from sonic_platform.component import Component @@ -24,9 +22,9 @@ raise ImportError(str(e) + "- required module not found") -MAX_S6000_FAN = 3 +MAX_S6000_FANTRAY = 3 MAX_S6000_PSU = 2 -MAX_S6000_THERMAL = 10 +MAX_S6000_THERMAL = 6 MAX_S6000_COMPONENT = 4 @@ -46,6 +44,8 @@ class Chassis(ChassisBase): def __init__(self): ChassisBase.__init__(self) + self.status_led_reg = "system_led" + self.supported_led_color = ['green', 'blinking green', 'amber', 'blinking amber'] # Initialize SFP list self.PORT_START = 0 self.PORT_END = 31 @@ -68,10 +68,18 @@ def __init__(self): # Get Transceiver status self.modprs_register = self._get_transceiver_status() - self._eeprom = Eeprom() - for i in range(MAX_S6000_FAN): - fan = Fan(i) - self._fan_list.append(fan) + with open("/sys/class/dmi/id/product_name", "r") as fd: + board_type = fd.read() + + if 'S6000-ON' in board_type: + self._eeprom = Eeprom() + else: + self._eeprom = EepromS6000() + + for i in range(MAX_S6000_FANTRAY): + fandrawer = FanDrawer(i) + self._fan_drawer_list.append(fandrawer) + self._fan_list.extend(fandrawer._fan_list) for i in range(MAX_S6000_PSU): psu = Psu(i) @@ -95,13 +103,30 @@ def _get_cpld_register(self, reg_name): try: with open(mb_reg_file, 'r') as fd: rv = fd.read() - except Exception as error: + except IOError: rv = 'ERR' rv = rv.rstrip('\r\n') rv = rv.lstrip(" ") return rv + def _set_cpld_register(self, reg_name, value): + # On successful write, returns the value will be written on + # reg_name and on failure returns 'ERR' + rv = 'ERR' + cpld_reg_file = self.CPLD_DIR+'/'+reg_name + + if (not os.path.isfile(cpld_reg_file)): + return rv + + try: + with open(cpld_reg_file, 'w') as fd: + rv = fd.write(str(value)) + except IOError: + rv = 'ERR' + + return rv + def _nvram_write(self, offset, val): resource = "/dev/nvram" fd = os.open(resource, os.O_RDWR) @@ -138,7 +163,7 @@ def get_name(self): Returns: string: The name of the chassis """ - return self._eeprom.modelstr() + return self._eeprom.get_model() def get_presence(self): """ @@ -154,7 +179,7 @@ def get_model(self): Returns: string: Model/part number of chassis """ - return self._eeprom.part_number_str() + return self._eeprom.get_part_number() def get_serial(self): """ @@ -162,7 +187,7 @@ def get_serial(self): Returns: string: Serial number of chassis """ - return self._eeprom.serial_str() + return self._eeprom.get_serial() def get_status(self): """ @@ -173,25 +198,32 @@ def get_status(self): """ return True - def get_base_mac(self): + def get_position_in_parent(self): """ - Retrieves the base MAC address for the chassis + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return -1 + def is_replaceable(self): + """ + Indicate whether Chassis is replaceable. Returns: - A string containing the MAC address in the format - 'XX:XX:XX:XX:XX:XX' + bool: True if it is replaceable. """ - return self._eeprom.base_mac_addr() + return False - def get_serial_number(self): + def get_base_mac(self): """ - Retrieves the hardware serial number for the chassis + Retrieves the base MAC address for the chassis Returns: - A string containing the hardware serial number for this - chassis. + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' """ - return self._eeprom.serial_number_str() + return self._eeprom.get_base_mac() def get_system_eeprom_info(self): """ @@ -237,13 +269,32 @@ def _get_transceiver_status(self): return int(content, 16) - def get_transceiver_change_event(self, timeout=0): + def get_change_event(self, timeout=0): """ - Returns a dictionary containing sfp changes which have + Returns a nested dictionary containing all devices which have experienced a change at chassis level + + Args: + timeout: Timeout in milliseconds (optional). If timeout == 0, + this method will block until a change is detected. + + Returns: + (bool, dict): + - True if call successful, False if not; + - A nested dictionary where key is a device type, + value is a dictionary with key:value pairs in the + format of {'device_id':'device_event'}, + where device_id is the device ID for this device and + device_event, + status='1' represents device inserted, + status='0' represents device removed. + Ex. {'fan':{'0':'0', '2':'1'}, 'sfp':{'11':'0'}} + indicates that fan 0 has been removed, fan 2 + has been inserted and sfp 11 has been removed. """ start_time = time.time() port_dict = {} + ret_dict = {"sfp": port_dict} port = self.PORT_START forever = False @@ -256,7 +307,7 @@ def get_transceiver_change_event(self, timeout=0): end_time = start_time + timeout if (start_time > end_time): - return False, {} # Time wrap or possibly incorrect timeout + return False, ret_dict # Time wrap or possibly incorrect timeout while (timeout >= 0): # Check for OIR events and return updated port_dict @@ -276,7 +327,7 @@ def get_transceiver_change_event(self, timeout=0): # Update reg value self.modprs_register = reg_value - return True, port_dict + return True, ret_dict if forever: time.sleep(1) @@ -287,7 +338,44 @@ def get_transceiver_change_event(self, timeout=0): else: if timeout > 0: time.sleep(timeout) - return True, {} - return False, {} + return True, ret_dict + return False, ret_dict + def set_status_led(self, color): + """ + Sets the state of the system LED + + Args: + color: A string representing the color with which to set the + system LED + Returns: + bool: True if system LED state is set successfully, False if not + """ + if color not in self.supported_led_color: + return False + + # Change color string format to the one used by driver + color = color.replace('amber', 'yellow') + color = color.replace('blinking ', 'blink_') + rv = self._set_cpld_register(self.status_led_reg, color) + if (rv != 'ERR'): + return True + else: + return False + + def get_status_led(self): + """ + Gets the state of the system LED + + Returns: + A string, one of the valid LED color strings which could be vendor + specified. + """ + status_led = self._get_cpld_register(self.status_led_reg) + if (status_led != 'ERR'): + status_led = status_led.replace('yellow', 'amber') + status_led = status_led.replace('blink_', 'blinking ') + return status_led + else: + return None diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/component.py index daa30eaafa3b..d9459be47c4f 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/component.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/component.py @@ -29,8 +29,8 @@ class Component(ComponentBase): "booting")], ["System-CPLD", "Used for managing CPU board devices and power"], ["Master-CPLD", ("Used for managing Fan, PSU, system LEDs, QSFP " - "modules (1-16)")], - ["Slave-CPLD", "Used for managing QSFP modules (17-32)"] + "modules (17-32)")], + ["Slave-CPLD", "Used for managing QSFP modules (1-16)"] ] def __init__(self, component_index): @@ -61,7 +61,7 @@ def _get_command_result(self, cmdline): stderr=subprocess.STDOUT) stdout = proc.communicate()[0] proc.wait() - result = stdout.rstrip('\n') + result = stdout.decode('utf-8').rstrip('\n') except OSError: result = None @@ -90,6 +90,55 @@ def get_name(self): """ return self.name + def get_model(self): + """ + Retrieves the part number of the component + Returns: + string: Part number of component + """ + return 'NA' + + def get_serial(self): + """ + Retrieves the serial number of the component + Returns: + string: Serial number of component + """ + return 'NA' + + def get_presence(self): + """ + Retrieves the presence of the component + Returns: + bool: True if present, False if not + """ + return True + + def get_status(self): + """ + Retrieves the operational status of the component + Returns: + bool: True if component is operating properly, False if not + """ + return True + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return -1 + + def is_replaceable(self): + """ + Indicate whether component is replaceable. + Returns: + bool: True if it is replaceable. + """ + return False + def get_description(self): """ Retrieves the description of the component 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 a82fd6a70201..5afe0112441b 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 @@ -17,12 +17,16 @@ try: - import os + import binascii + import redis + import struct + from collections import OrderedDict from sonic_platform_base.sonic_eeprom.eeprom_base import EepromDecoder from sonic_platform_base.sonic_eeprom.eeprom_tlvinfo import TlvInfoDecoder except ImportError as e: raise ImportError(str(e) + "- required module not found") +STATE_DB_INDEX = 6 # PSU eeprom fields in format required by EepromDecoder psu_eeprom_format = [ @@ -32,8 +36,8 @@ ('Fab Rev', 's', 2) ] -# Fan eeprom fields in format required by EepromDecoder -fan_eeprom_format = [ +# FanTray eeprom fields in format required by EepromDecoder +fantray_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', 83), @@ -47,10 +51,10 @@ class Eeprom(TlvInfoDecoder): I2C_DIR = "/sys/class/i2c-adapter/" - def __init__(self, is_psu=False, psu_index=0, is_fan=False, fan_index=0): + def __init__(self, is_psu=False, psu_index=0, is_fantray=False, fantray_index=0): self.is_psu_eeprom = is_psu - self.is_fan_eeprom = is_fan - self.is_sys_eeprom = not (is_psu | is_fan) + self.is_fantray_eeprom = is_fantray + self.is_sys_eeprom = not (is_psu | is_fantray) if self.is_sys_eeprom: self.start_offset = 0 @@ -67,10 +71,10 @@ def __init__(self, is_psu=False, psu_index=0, is_fan=False, fan_index=0): + "i2c-1/1-005{}/eeprom".format(2 - self.index) self.format = psu_eeprom_format else: - self.index = fan_index + self.index = fantray_index self.eeprom_path = self.I2C_DIR \ + "i2c-11/11-005{}/eeprom".format(4 - self.index) - self.format = fan_eeprom_format + self.format = fantray_eeprom_format EepromDecoder.__init__(self, self.eeprom_path, self.format, self.start_offset, '', True) self._load_device_eeprom() @@ -103,7 +107,7 @@ def _load_system_eeprom(self): self.serial = 'NA' return - total_length = (ord(eeprom[9]) << 8) | ord(eeprom[10]) + total_length = (eeprom[9] << 8) | (eeprom[10]) tlv_index = self._TLV_INFO_HDR_LEN tlv_end = self._TLV_INFO_HDR_LEN + total_length @@ -112,21 +116,21 @@ def _load_system_eeprom(self): break tlv = eeprom[tlv_index:tlv_index + 2 - + ord(eeprom[tlv_index + 1])] - code = "0x%02X" % (ord(tlv[0])) + + eeprom[tlv_index + 1]] + code = "0x%02X" % (tlv[0]) - if ord(tlv[0]) == self._TLV_CODE_VENDOR_EXT: - value = str((ord(tlv[2]) << 24) | (ord(tlv[3]) << 16) | - (ord(tlv[4]) << 8) | ord(tlv[5])) - value += str(tlv[6:6 + ord(tlv[1])]) + if tlv[0] == self._TLV_CODE_VENDOR_EXT: + value = str((tlv[2] << 24) | (tlv[3] << 16) | + (tlv[4] << 8) | tlv[5]) + value += tlv[6:6 + tlv[1]].decode('ascii') else: name, value = self.decoder(None, tlv) self.eeprom_tlv_dict[code] = value - if ord(eeprom[tlv_index]) == self._TLV_CODE_CRC_32: + if eeprom[tlv_index] == self._TLV_CODE_CRC_32: break - tlv_index += ord(eeprom[tlv_index+1]) + 2 + tlv_index += eeprom[tlv_index+1] + 2 self.base_mac = self.eeprom_tlv_dict.get( "0x%X" % (self._TLV_CODE_MAC_BASE), 'NA') @@ -186,7 +190,7 @@ def _load_device_eeprom(self): else: self.fan_type = 'NA' - def _get_eeprom_field(self, field_name): + def _get_eeprom_field(self, field_name, decode=True): """ For a field name specified in the EEPROM format, returns the presence of the field and the value for the same. @@ -195,18 +199,21 @@ def _get_eeprom_field(self, field_name): for field in self.format: field_end = field_start + field[2] if field[0] == field_name: - return (True, self.eeprom_data[field_start:field_end]) + if decode: + return (True, self.eeprom_data[field_start:field_end].decode('ascii')) + else: + return (True, self.eeprom_data[field_start:field_end]) field_start = field_end return (False, None) - def serial_number_str(self): + def get_serial_number(self): """ Returns the serial number. """ return self.serial_number - def part_number_str(self): + def get_part_number(self): """ Returns the part number. """ @@ -217,24 +224,24 @@ def airflow_fan_type(self): Returns the airflow fan type. """ if self.is_psu_eeprom: - return int(self.psu_type.encode('hex'), 16) + return int(binascii.hexlify(self.psu_type.encode('utf-8')), 16) else: - return int(self.fan_type.encode('hex'), 16) + return int(binascii.hexlify(self.fan_type.encode('utf-8')), 16) # System EEPROM specific methods - def base_mac_addr(self): + def get_base_mac(self): """ Returns the base MAC address found in the system EEPROM. """ return self.base_mac - def modelstr(self): + def get_model(self): """ Returns the Model name. """ return self.model_str - def serial_str(self): + def get_serial(self): """ Returns the servicetag number. """ @@ -247,3 +254,255 @@ def system_eeprom_info(self): found in the system EEPROM. """ return self.eeprom_tlv_dict + + +class EepromS6000(EepromDecoder): + + _EEPROM_MAX_LEN = 128 + + _BLK_HDR_LEN = 6 + _BLK_HDR_MAGIC = b'\x3a\x29' + _BLK_HDR_REVID = 1 + + _BLK_CODE_MFG = 0x20 + _BLK_CODE_SW = 0x1F + _BLK_CODE_MAC = 0x21 + + _BLK_MFG_FORMAT = [ + ("PPID", 20), ("DPN Rev", 3), ("Service Tag", 7), ("Part Number", 10), + ("Part Number Rev", 3), ("Mfg Test Results", 2) + ] + + _BLK_SW_FORMAT = [("Card ID", 4), ("Module ID", 2)] + _BLK_MAC_FORMAT = [("Base MAC address", 6)] + + _BLK_INFO = OrderedDict([ + (_BLK_CODE_MFG, {"name": "MFG BLOCK", "size": 64, + "offset": 0x0, "format": _BLK_MFG_FORMAT}), + (_BLK_CODE_SW, {"name": "SW BLOCK", "size": 48, + "offset": 0x40, "format": _BLK_SW_FORMAT}), + (_BLK_CODE_MAC, {"name": "MAC BLOCK", "size": 16, + "offset": 0x70, "format": _BLK_MAC_FORMAT}) + ]) + + def __init__(self, is_plugin=False): + self.eeprom_path = "/sys/bus/i2c/devices/i2c-10/10-0053/eeprom" + super(EepromS6000, self).__init__(self.eeprom_path, None, 0, '', True) + + if not is_plugin: + self.eeprom_data = self.read_eeprom() + + def _is_valid_block_checksum(self, e): + crc = self.compute_dell_crc(e[:-2]) + return crc == struct.unpack('3d} {:3d} {: 14000): + if (int(fan_speed) > 1000): status = True return status + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether Fan is replaceable. + Returns: + bool: True if it is replaceable. + """ + return False + def get_direction(self): """ Retrieves the fan airflow direction @@ -234,11 +198,10 @@ def get_direction(self): if self.is_psu_fan: 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: self.FAN_DIRECTION_EXHAUST, 2: self.FAN_DIRECTION_INTAKE} - fan_direction = self.eeprom.airflow_fan_type() + fan_direction = self.dependency.eeprom.airflow_fan_type() return direction.get(fan_direction, self.FAN_DIRECTION_NOT_APPLICABLE) def get_speed(self): @@ -251,7 +214,7 @@ def get_speed(self): fan_speed = self._get_i2c_register(self.get_fan_speed_reg) if (fan_speed != 'ERR') and self.get_presence(): speed_in_rpm = int(fan_speed, 10) - speed = (100 * speed_in_rpm)/self.max_fan_speed + speed = (100 * speed_in_rpm)//self.max_fan_speed else: speed = 0 @@ -282,8 +245,8 @@ def set_speed(self, speed): Returns: bool: True if set success, False if fail. """ - fan_set = (speed * self.max_fan_speed)/ 100 - rv = self._set_i2c_register(self.set_fan_speed_reg , fan_set) + fan_set = (speed * self.max_fan_speed) // 100 + rv = self._set_i2c_register(self.set_fan_speed_reg, fan_set) if (rv != 'ERR'): return True else: @@ -298,16 +261,9 @@ def set_status_led(self, color): Returns: bool: True if set success, False if fail. """ - if self.is_psu_fan or (color not in self.supported_led_color): - return False - if(color == self.STATUS_LED_COLOR_AMBER): - color = 'yellow' - - rv = self._set_cpld_register(self.fan_led_reg ,color) - if (rv != 'ERR'): - return True - else: - return False + # No LED available for FanTray and PSU Fan + # Return True to avoid thermalctld alarm. + return True def get_status_led(self): """ @@ -316,18 +272,8 @@ 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'): - return self.STATUS_LED_COLOR_AMBER - else: - return fan_led - else: - return self.STATUS_LED_COLOR_OFF + # No LED available for FanTray and PSU Fan + return None def get_target_speed(self): """ @@ -337,4 +283,5 @@ def get_target_speed(self): An integer, the percentage of full fan speed, in the range 0 (off) to 100 (full speed) """ - return 79 + # Fan speeds are controlled by fancontrol.sh + return self.get_speed() diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan_drawer.py new file mode 100644 index 000000000000..2e5e3446cd80 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan_drawer.py @@ -0,0 +1,184 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC S6000 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Fan-Drawers' information available in the platform. +# +######################################################################## + +try: + import os + + from sonic_platform_base.fan_drawer_base import FanDrawerBase + from sonic_platform.eeprom import Eeprom + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +MAX_S6000_FANS_PER_FANTRAY = 2 + + +class FanDrawer(FanDrawerBase): + """DellEMC Platform-specific Fan Drawer class""" + + CPLD_DIR = "/sys/devices/platform/dell-s6000-cpld.0/" + + def __init__(self, fantray_index): + FanDrawerBase.__init__(self) + # FanTray is 1-based in DellEMC platforms + self.index = fantray_index + 1 + self.eeprom = Eeprom(is_fantray=True, fantray_index=self.index) + self.fantray_presence_reg = "fan_prs" + self.fantray_led_reg = "fan{}_led".format(self.index - 1) + self.supported_led_color = ['off', 'green', 'amber'] + + for i in range(1, MAX_S6000_FANS_PER_FANTRAY+1): + self._fan_list.append(Fan(fantray_index=self.index, fan_index=i, 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' + rv = 'ERR' + cpld_reg_file = self.CPLD_DIR + reg_name + + if (not os.path.isfile(cpld_reg_file)): + return rv + + try: + with open(cpld_reg_file, 'r') as fd: + rv = fd.read() + except IOError: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + + def _set_cpld_register(self, reg_name, value): + # On successful write, returns the value will be written on + # reg_name and on failure returns 'ERR' + rv = 'ERR' + cpld_reg_file = self.CPLD_DIR + reg_name + + if (not os.path.isfile(cpld_reg_file)): + return rv + + try: + with open(cpld_reg_file, 'w') as fd: + rv = fd.write(str(value)) + except IOError: + rv = 'ERR' + + return rv + + def get_name(self): + """ + Retrieves the Fandrawer name + Returns: + string: The name of the device + """ + return "FanTray{}".format(self.index) + + def get_presence(self): + """ + Retrieves the presence of the Fandrawer + + Returns: + bool: True if Fandrawer is present, False if not + """ + presence = False + + fantray_presence = self._get_cpld_register(self.fantray_presence_reg) + if (fantray_presence != 'ERR'): + fantray_presence = int(fantray_presence, 16) & (1 << (self.index - 1)) + if fantray_presence: + presence = True + + return presence + + def get_model(self): + """ + Retrieves the part number of the Fandrawer + + Returns: + string: Part number of Fandrawer + """ + return self.eeprom.get_part_number() + + def get_serial(self): + """ + Retrieves the serial number of the Fandrawer + + Returns: + string: Serial number of Fandrawer + """ + # Sample Serial number format "US-01234D-54321-25A-0123-A00" + return self.eeprom.get_serial_number() + + def get_status(self): + """ + Retrieves the operational status of the Fandrawer + + Returns: + bool: True if Fandrawer is operating properly, False if not + """ + status = True + for fan in self.get_all_fans(): + status &= fan.get_status() + + return status + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether this fan drawer is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True + + def set_status_led(self, color): + """ + Set led to expected color + Args: + color: A string representing the color with which to set the + fandrawer status LED + Returns: + bool: True if set success, False if fail. + """ + if color not in self.supported_led_color: + return False + if color == self.STATUS_LED_COLOR_AMBER: + color = 'yellow' + + rv = self._set_cpld_register(self.fantray_led_reg, color) + if (rv != 'ERR'): + return True + else: + return False + + def get_status_led(self): + """ + Gets the state of the fandrawer status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings. + """ + fantray_led = self._get_cpld_register(self.fantray_led_reg) + if (fantray_led != 'ERR'): + if (fantray_led == 'yellow'): + return self.STATUS_LED_COLOR_AMBER + else: + return fantray_led + else: + return self.STATUS_LED_COLOR_OFF diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/platform.py index 426db717281b..32230d9c92ce 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/platform.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/platform.py @@ -8,7 +8,6 @@ ############################################################################# try: - import os from sonic_platform_base.platform_base import PlatformBase from sonic_platform.chassis import Chassis except ImportError as e: 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 24200f1c7d39..e217c0a08c40 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 @@ -15,9 +15,12 @@ from sonic_platform_base.psu_base import PsuBase from sonic_platform.eeprom import Eeprom from sonic_platform.fan import Fan + from sonic_platform.thermal import Thermal except ImportError as e: raise ImportError(str(e) + "- required module not found") +MAX_S6000_THERMALS_PER_PSU = 2 + class Psu(PsuBase): """DellEMC Platform-specific PSU class""" @@ -26,6 +29,7 @@ class Psu(PsuBase): I2C_DIR = "/sys/class/i2c-adapter/" def __init__(self, psu_index): + PsuBase.__init__(self) # PSU is 1-based in DellEMC platforms self.index = psu_index + 1 self.psu_presence_reg = "psu{}_prs".format(psu_index) @@ -52,11 +56,10 @@ def __init__(self, psu_index): self.eeprom = Eeprom(is_psu=True, psu_index=self.index) - # Overriding _fan_list class variable defined in PsuBase, to - # make it unique per Psu object - self._fan_list = [] - - self._fan_list.append(Fan(self.index, psu_fan=True, dependency=self)) + self._fan_list.append(Fan(psu_index=self.index, psu_fan=True, dependency=self)) + for i in range(1, MAX_S6000_THERMALS_PER_PSU+1): + self._thermal_list.append(Thermal(psu_index=self.index, thermal_index=i, + psu_thermal=True, dependency=self)) def _get_cpld_register(self, reg_name): # On successful read, returns the value read from given @@ -109,9 +112,9 @@ def _get_sysfs_path(self): 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.psu_voltage_reg = voltage_reg[0] + self.psu_current_reg = current_reg[0] + self.psu_power_reg = power_reg[0] self.is_driver_initialized = True def get_name(self): @@ -146,7 +149,7 @@ def get_model(self): Returns: string: Part number of PSU """ - return self.eeprom.part_number_str() + return self.eeprom.get_part_number() def get_serial(self): """ @@ -156,7 +159,7 @@ def get_serial(self): string: Serial number of PSU """ # Sample Serial number format "US-01234D-54321-25A-0123-A00" - return self.eeprom.serial_number_str() + return self.eeprom.get_serial_number() def get_status(self): """ @@ -168,12 +171,29 @@ def get_status(self): status = False psu_status = self._get_cpld_register(self.psu_status_reg) if (psu_status != 'ERR'): - psu_status = (int(psu_status, 16) >> ((2 - self.index) * 4)) & 0xF + psu_status = (int(psu_status, 16) >> int((2 - self.index) * 4)) & 0xF if (~psu_status & 0b1000) and (~psu_status & 0b0100): status = True return status + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether PSU is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True + def get_voltage(self): """ Retrieves current PSU voltage output @@ -269,3 +289,50 @@ def set_status_led(self, color): # In S6000, the firmware running in the PSU controls the LED # and the PSU LED state cannot be changed from CPU. return False + + def get_temperature(self): + """ + Retrieves current temperature reading from PSU + + Returns: + A float number of current temperature in Celsius up to + nearest thousandth of one degree Celsius, e.g. 30.125 + """ + if self.get_presence(): + return self.get_thermal(0).get_temperature() + else: + return 0.0 + + def get_temperature_high_threshold(self): + """ + Retrieves the high threshold temperature of PSU + + Returns: + A float number, the high threshold temperature of PSU in + Celsius up to nearest thousandth of one degree Celsius, + e.g. 30.125 + """ + if self.get_presence(): + return self.get_thermal(0).get_high_threshold() + else: + return 0.0 + + def get_voltage_high_threshold(self): + """ + Retrieves the high threshold PSU voltage output + + Returns: + A float number, the high threshold output voltage in volts, + e.g. 12.1 + """ + return 12.6 + + def get_voltage_low_threshold(self): + """ + Retrieves the low threshold PSU voltage output + + Returns: + A float number, the low threshold output voltage in volts, + e.g. 12.1 + """ + return 11.4 diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/sfp.py index 9ab89db5d61a..b66cb31ec96b 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/sfp.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/sfp.py @@ -9,9 +9,9 @@ ############################################################################# try: - import os + import re + import struct import time - from sonic_platform_base.chassis_base import ChassisBase from sonic_platform_base.sfp_base import SfpBase from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom @@ -28,6 +28,9 @@ DOM_OFFSET = 0 DOM_OFFSET1 = 384 +QSFP_CONTROL_OFFSET = 86 +QSFP_POWEROVERRIDE_OFFSET = 93 + cable_length_tup = ('Length(km)', 'Length OM3(2m)', 'Length OM2(m)', 'Length OM1(m)', 'Length Cable Assembly(m)') @@ -40,11 +43,12 @@ 'Fibre Channel transmission media', 'Fibre Channel Speed') -info_dict_keys = ['type', 'hardwarerev', 'serialnum', - 'manufacturename', 'modelname', 'Connector', +info_dict_keys = ['type', 'hardware_rev', 'serial', + 'manufacturer', 'model', 'connector', 'encoding', 'ext_identifier', 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', - 'specification_compliance', 'type_abbrv_name','vendor_date', 'vendor_oui'] + 'specification_compliance', 'type_abbrv_name', 'vendor_date', + 'vendor_oui', 'application_advertisement'] dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', @@ -78,7 +82,7 @@ 'cable_type': [INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], 'cable_length': [INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], - 'Connector': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'connector': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'type': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'encoding': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'ext_identifier': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], @@ -87,12 +91,12 @@ 'nominal_bit_rate': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'specification_compliance': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], - 'type_abbrv_name' : [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], - 'manufacturename': [INFO_OFFSET, 20, 16, 'parse_vendor_name'], + 'type_abbrv_name': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'manufacturer': [INFO_OFFSET, 20, 16, 'parse_vendor_name'], 'vendor_oui': [INFO_OFFSET, 37, 3, 'parse_vendor_oui'], - 'modelname': [INFO_OFFSET, 40, 16, 'parse_vendor_pn'], - 'hardwarerev': [INFO_OFFSET, 56, 2, 'parse_vendor_rev'], - 'serialnum': [INFO_OFFSET, 68, 16, 'parse_vendor_sn'], + 'model': [INFO_OFFSET, 40, 16, 'parse_vendor_pn'], + 'hardware_rev': [INFO_OFFSET, 56, 2, 'parse_vendor_rev'], + 'serial': [INFO_OFFSET, 68, 16, 'parse_vendor_sn'], 'vendor_date': [INFO_OFFSET, 84, 8, 'parse_vendor_date'], 'ModuleThreshold': [DOM_OFFSET1, 128, 24, 'parse_module_threshold_values'], 'ChannelThreshold': [DOM_OFFSET1, 176, 16, 'parse_channel_threshold_values'], @@ -108,7 +112,7 @@ def __init__(self, index, sfp_type, eeprom_path, sfp_control, sfp_ctrl_idx): SfpBase.__init__(self) self.sfp_type = sfp_type - self.index = index + self.index = index + 1 self.eeprom_path = eeprom_path self.sfp_control = sfp_control self.sfp_ctrl_idx = sfp_ctrl_idx @@ -132,9 +136,10 @@ def _read_eeprom_bytes(self, eeprom_path, offset, num_bytes): eeprom.close() return None + raw = bytearray(raw) try: for n in range(0, num_bytes): - eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + eeprom_raw[n] = hex(raw[n])[2:].zfill(2) except BaseException: eeprom.close() return None @@ -169,6 +174,14 @@ def _get_eeprom_data(self, eeprom_key): return eeprom_data + def _strip_unit_from_str(self, value_str): + match = re.match(r'(.*)C$|(.*)Volts$|(.*)mA$|(.*)dBm$', value_str) + if match: + for value in match.groups(): + if value is not None: + return float(value) + + return None def get_transceiver_info(self): """ @@ -208,7 +221,7 @@ def get_transceiver_info(self): return None # Vendor Name - vendor_name_data = self._get_eeprom_data('manufacturename') + vendor_name_data = self._get_eeprom_data('manufacturer') if (vendor_name_data is not None): vendor_name = vendor_name_data['data']['Vendor Name']['value'] else: @@ -222,33 +235,33 @@ def get_transceiver_info(self): return transceiver_info_dict # Vendor PN - vendor_pn_data = self._get_eeprom_data('modelname') + vendor_pn_data = self._get_eeprom_data('model') if (vendor_pn_data is not None): vendor_pn = vendor_pn_data['data']['Vendor PN']['value'] else: return transceiver_info_dict # Vendor Revision - vendor_rev_data = self._get_eeprom_data('hardwarerev') + vendor_rev_data = self._get_eeprom_data('hardware_rev') if (vendor_rev_data is not None): vendor_rev = vendor_rev_data['data']['Vendor Rev']['value'] else: return transceiver_info_dict # Vendor Serial Number - vendor_sn_data = self._get_eeprom_data('serialnum') + vendor_sn_data = self._get_eeprom_data('serial') if (vendor_sn_data is not None): vendor_sn = vendor_sn_data['data']['Vendor SN']['value'] else: return transceiver_info_dict - + # Fill The Dictionary and return transceiver_info_dict['type'] = identifier - transceiver_info_dict['hardwarerev'] = vendor_rev - transceiver_info_dict['serialnum'] = vendor_sn - transceiver_info_dict['manufacturename'] = vendor_name - transceiver_info_dict['modelname'] = vendor_pn - transceiver_info_dict['Connector'] = connector + transceiver_info_dict['hardware_rev'] = vendor_rev + transceiver_info_dict['serial'] = vendor_sn + transceiver_info_dict['manufacturer'] = vendor_name + transceiver_info_dict['model'] = vendor_pn + transceiver_info_dict['connector'] = connector transceiver_info_dict['encoding'] = encoding transceiver_info_dict['ext_identifier'] = ext_id transceiver_info_dict['ext_rateselect_compliance'] = rate_identifier @@ -259,7 +272,7 @@ def get_transceiver_info(self): compliance_code_dict) transceiver_info_dict['vendor_date'] = vendor_date transceiver_info_dict['vendor_oui'] = vendor_oui - transceiver_info_dict['type_abbrv_name']=type_abbrv_name + transceiver_info_dict['type_abbrv_name'] = type_abbrv_name return transceiver_info_dict @@ -434,7 +447,7 @@ def get_model(self): """ Retrieves the model number (or part number) of the sfp """ - vendor_pn_data = self._get_eeprom_data('modelname') + vendor_pn_data = self._get_eeprom_data('model') if (vendor_pn_data is not None): vendor_pn = vendor_pn_data['data']['Vendor PN']['value'] else: @@ -446,7 +459,7 @@ def get_serial(self): """ Retrieves the serial number of the sfp """ - vendor_sn_data = self._get_eeprom_data('serialnum') + vendor_sn_data = self._get_eeprom_data('serial') if (vendor_sn_data is not None): vendor_sn = vendor_sn_data['data']['Vendor SN']['value'] else: @@ -487,154 +500,107 @@ def get_rx_los(self): """ Retrieves the RX LOS (lost-of-signal) status of SFP """ - rx_los = None rx_los_list = [] rx_los_data = self._get_eeprom_data('rx_los') if (rx_los_data is not None): rx_los = rx_los_data['data']['Rx1LOS']['value'] - if (rx_los is 'On'): + if (rx_los == 'On'): rx_los_list.append(True) else: rx_los_list.append(False) rx_los = rx_los_data['data']['Rx2LOS']['value'] - if (rx_los is 'On'): + if (rx_los == 'On'): rx_los_list.append(True) else: rx_los_list.append(False) rx_los = rx_los_data['data']['Rx3LOS']['value'] - if (rx_los is 'On'): + if (rx_los == 'On'): rx_los_list.append(True) else: rx_los_list.append(False) rx_los = rx_los_data['data']['Rx4LOS']['value'] - if (rx_los is 'On'): + if (rx_los == 'On'): rx_los_list.append(True) else: rx_los_list.append(False) - if (rx_los_list[0] and rx_los_list[1] - and rx_los_list[2] and rx_los_list[3]): - rx_los = True - else: - rx_los = False - - return rx_los + return rx_los_list def get_tx_fault(self): """ Retrieves the TX fault status of SFP """ - tx_fault = None tx_fault_list = [] tx_fault_data = self._get_eeprom_data('tx_fault') if (tx_fault_data is not None): tx_fault = tx_fault_data['data']['Tx1Fault']['value'] - if (tx_fault is 'On'): + if (tx_fault == 'On'): tx_fault_list.append(True) else: tx_fault_list.append(False) tx_fault = tx_fault_data['data']['Tx2Fault']['value'] - if (tx_fault is 'On'): + if (tx_fault == 'On'): tx_fault_list.append(True) else: tx_fault_list.append(False) tx_fault = tx_fault_data['data']['Tx3Fault']['value'] - if (tx_fault is 'On'): + if (tx_fault == 'On'): tx_fault_list.append(True) else: tx_fault_list.append(False) tx_fault = tx_fault_data['data']['Tx4Fault']['value'] - if (tx_fault is 'On'): + if (tx_fault == 'On'): tx_fault_list.append(True) else: tx_fault_list.append(False) - if (tx_fault_list[0] and tx_fault_list[1] - and tx_fault_list[2] and tx_fault_list[3]): - tx_fault = True - else: - tx_fault = False - - return tx_fault + return tx_fault_list def get_tx_disable(self): """ Retrieves the tx_disable status of this SFP """ - tx_disable = None tx_disable_list = [] tx_disable_data = self._get_eeprom_data('tx_disable') if (tx_disable_data is not None): tx_disable = tx_disable_data['data']['Tx1Disable']['value'] - if (tx_disable is 'On'): + if (tx_disable == 'On'): tx_disable_list.append(True) else: tx_disable_list.append(False) tx_disable = tx_disable_data['data']['Tx2Disable']['value'] - if (tx_disable is 'On'): + if (tx_disable == 'On'): tx_disable_list.append(True) else: tx_disable_list.append(False) tx_disable = tx_disable_data['data']['Tx3Disable']['value'] - if (tx_disable is 'On'): + if (tx_disable == 'On'): tx_disable_list.append(True) else: tx_disable_list.append(False) tx_disable = tx_disable_data['data']['Tx4Disable']['value'] - if (tx_disable is 'On'): + if (tx_disable == 'On'): tx_disable_list.append(True) else: tx_disable_list.append(False) - if (tx_disable_list[0] and tx_disable_list[1] - and tx_disable_list[2] and tx_disable_list[3]): - tx_disable = True - else: - tx_disable = False - - return tx_disable + return tx_disable_list def get_tx_disable_channel(self): """ Retrieves the TX disabled channels in this SFP """ - tx_disable = None - tx_disable_list = [] + tx_disable_channel = 0 - tx_disable_data = self._get_eeprom_data('tx_disable') - if (tx_disable_data is not None): - tx_disable = tx_disable_data['data']['Tx1Disable']['value'] - if (tx_disable is 'On'): - tx_disable_list.append(1) - else: - tx_disable_list.append(0) - tx_disable = tx_disable_data['data']['Tx2Disable']['value'] - if (tx_disable is 'On'): - tx_disable_list.append(1) - else: - tx_disable_list.append(0) - tx_disable = tx_disable_data['data']['Tx3Disable']['value'] - if (tx_disable is 'On'): - tx_disable_list.append(1) - else: - tx_disable_list.append(0) - tx_disable = tx_disable_data['data']['Tx4Disable']['value'] - if (tx_disable is 'On'): - tx_disable_list.append(1) - else: - tx_disable_list.append(0) - - bit4 = int(tx_disable_list[3]) * 8 - bit3 = int(tx_disable_list[2]) * 4 - bit2 = int(tx_disable_list[1]) * 2 - bit1 = int(tx_disable_list[0]) * 1 - - tx_disable_channel = hex(bit4 + bit3 + bit2 + bit1) + tx_disable = self.get_tx_disable() + for channel, disable in enumerate(tx_disable): + if disable: + tx_disable_channel |= 1 << channel - return tx_disable_channel + return tx_disable_channel def get_lpmode(self): """ @@ -674,7 +640,7 @@ def get_power_override(self): power_override_data = self._get_eeprom_data('power_override') if (power_override_data is not None): power_override = power_override_data['data']['PowerOverRide']['value'] - if (power_override is 'On'): + if (power_override == 'On'): power_override_state = True else: power_override_state = False @@ -689,7 +655,7 @@ def get_temperature(self): temperature_data = self._get_eeprom_data('Temperature') if (temperature_data is not None): - temperature = temperature_data['data']['Temperature']['value'] + temperature = self._strip_unit_from_str(temperature_data['data']['Temperature']['value']) return temperature @@ -701,7 +667,7 @@ def get_voltage(self): voltage_data = self._get_eeprom_data('Voltage') if (voltage_data is not None): - voltage = voltage_data['data']['Vcc']['value'] + voltage = self._strip_unit_from_str(voltage_data['data']['Vcc']['value']) return voltage @@ -709,19 +675,14 @@ def get_tx_bias(self): """ Retrieves the TX bias current of this SFP """ - tx_bias = None tx_bias_list = [] tx_bias_data = self._get_eeprom_data('ChannelMonitor') if (tx_bias_data is not None): - tx_bias = tx_bias_data['data']['TX1Bias']['value'] - tx_bias_list.append(tx_bias) - tx_bias = tx_bias_data['data']['TX2Bias']['value'] - tx_bias_list.append(tx_bias) - tx_bias = tx_bias_data['data']['TX3Bias']['value'] - tx_bias_list.append(tx_bias) - tx_bias = tx_bias_data['data']['TX4Bias']['value'] - tx_bias_list.append(tx_bias) + tx_bias_list.append(self._strip_unit_from_str(tx_bias_data['data']['TX1Bias']['value'])) + tx_bias_list.append(self._strip_unit_from_str(tx_bias_data['data']['TX2Bias']['value'])) + tx_bias_list.append(self._strip_unit_from_str(tx_bias_data['data']['TX3Bias']['value'])) + tx_bias_list.append(self._strip_unit_from_str(tx_bias_data['data']['TX4Bias']['value'])) return tx_bias_list @@ -729,34 +690,27 @@ def get_rx_power(self): """ Retrieves the received optical power for this SFP """ - rx_power = None rx_power_list = [] rx_power_data = self._get_eeprom_data('ChannelMonitor') if (rx_power_data is not None): - rx_power = rx_power_data['data']['RX1Power']['value'] - rx_power_list.append(rx_power) - rx_power = rx_power_data['data']['RX2Power']['value'] - rx_power_list.append(rx_power) - rx_power = rx_power_data['data']['RX3Power']['value'] - rx_power_list.append(rx_power) - rx_power = rx_power_data['data']['RX4Power']['value'] - rx_power_list.append(rx_power) + rx_power_list.append(self._strip_unit_from_str(rx_power_data['data']['RX1Power']['value'])) + rx_power_list.append(self._strip_unit_from_str(rx_power_data['data']['RX2Power']['value'])) + rx_power_list.append(self._strip_unit_from_str(rx_power_data['data']['RX3Power']['value'])) + rx_power_list.append(self._strip_unit_from_str(rx_power_data['data']['RX4Power']['value'])) return rx_power_list - def get_tx_power(self): """ Retrieves the TX power of this SFP """ - tx_power = None tx_power_list = [] - tx_power_list.append('-infdBm') - tx_power_list.append('-infdBm') - tx_power_list.append('-infdBm') - tx_power_list.append('-infdBm') + tx_power_list.append(float('-inf')) + tx_power_list.append(float('-inf')) + tx_power_list.append(float('-inf')) + tx_power_list.append(float('-inf')) return tx_power_list @@ -846,25 +800,68 @@ def tx_disable(self, tx_disable): """ Disable SFP TX for all channels """ - return False + eeprom = None + tx_disable_value = 0xf if tx_disable else 0x0 - def tx_disable_channel(self, channel, disable): - """ - Sets the tx_disable for specified SFP channels - """ - return False + try: + eeprom = open(self.eeprom_path, "r+b") + eeprom.seek(QSFP_CONTROL_OFFSET) + eeprom.write(struct.pack('B', tx_disable_value)) + except IOError: + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) + + return True def tx_disable_channel(self, channel, disable): """ Sets the tx_disable for specified SFP channels """ - return False + eeprom = None + current_state = self.get_tx_disable_channel() + + if disable: + tx_disable_value = current_state | channel + else: + tx_disable_value = current_state & (~channel) + + try: + eeprom = open(self.eeprom_path, "r+b") + eeprom.seek(QSFP_CONTROL_OFFSET) + eeprom.write(struct.pack('B', tx_disable_value)) + except IOError: + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) + + return True def set_power_override(self, power_override, power_set): """ Sets SFP power level using power_override and power_set """ - return False + eeprom = None + power_override_bit = 0x1 if power_override else 0 + power_set_bit = 0x2 if power_set else 0 + value = power_override_bit | power_set_bit + + try: + eeprom = open(self.eeprom_path, "r+b") + eeprom.seek(QSFP_POWEROVERRIDE_OFFSET) + eeprom.write(struct.pack('B', value)) + except IOError: + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) + + return True def get_status(self): """ @@ -878,3 +875,20 @@ def get_status(self): status = True return status + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True 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 a54336d40f1c..ad089a8946a9 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 @@ -13,7 +13,6 @@ import os import glob from sonic_platform_base.thermal_base import ThermalBase - from sonic_platform.psu import Psu except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -34,11 +33,20 @@ class Thermal(ThermalBase): 'PSU1-Sensor 1', 'PSU1-Sensor 2', 'PSU2-Sensor 1', 'PSU2-Sensor 2', 'CPU Core 0', 'CPU Core 1') - def __init__(self, thermal_index): - self.index = thermal_index + 1 - self.is_psu_thermal = False + def __init__(self, thermal_index, + psu_index=1, psu_thermal=False, dependency=None): + self.is_psu_thermal = psu_thermal + self.dependency = dependency self.is_driver_initialized = True - self.dependency = None + + if self.is_psu_thermal: + self.index = (2 * psu_index) + thermal_index + 2 + else: + # CPU thermal + if thermal_index > 3: + self.index = thermal_index + 5 + else: + self.index = thermal_index + 1 if self.index < 9: i2c_path = self.I2C_DIR + self.I2C_DEV_MAPPING[self.index - 1][0] @@ -54,10 +62,6 @@ def __init__(self, thermal_index): if self.index == 4: hwmon_temp_suffix = "crit" - - if self.index > 4: - self.is_psu_thermal = True - self.dependency = Psu(self.index / 7) else: dev_path = "/sys/devices/platform/coretemp.0/hwmon/" hwmon_temp_index = self.index - 7 @@ -168,6 +172,23 @@ def get_status(self): else: return True + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether Thermal is replaceable. + Returns: + bool: True if it is replaceable. + """ + return False + def get_temperature(self): """ Retrieves current temperature reading from thermal @@ -179,11 +200,11 @@ def get_temperature(self): thermal_temperature = self._read_sysfs_file( self.thermal_temperature_file) if (thermal_temperature != 'ERR'): - thermal_temperature = float(thermal_temperature) / 1000 + thermal_temperature = float(thermal_temperature) else: thermal_temperature = 0 - return "{:.3f}".format(thermal_temperature) + return thermal_temperature / 1000.0 def get_high_threshold(self): """ @@ -197,11 +218,11 @@ def get_high_threshold(self): thermal_high_threshold = self._read_sysfs_file( self.thermal_high_threshold_file) if (thermal_high_threshold != 'ERR'): - thermal_high_threshold = float(thermal_high_threshold) / 1000 + thermal_high_threshold = float(thermal_high_threshold) else: thermal_high_threshold = 0 - return "{:.3f}".format(thermal_high_threshold) + return thermal_high_threshold / 1000.0 def get_low_threshold(self): """ @@ -215,11 +236,11 @@ def get_low_threshold(self): thermal_low_threshold = self._read_sysfs_file( self.thermal_low_threshold_file) if (thermal_low_threshold != 'ERR'): - thermal_low_threshold = float(thermal_low_threshold) / 1000 + thermal_low_threshold = float(thermal_low_threshold) else: thermal_low_threshold = 0 - return "{:.3f}".format(thermal_low_threshold) + return thermal_low_threshold / 1000.0 def set_high_threshold(self, temperature): """ diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/systemd/platform-modules-s6000.service b/platform/broadcom/sonic-platform-modules-dell/s6000/systemd/platform-modules-s6000.service index b55a466890bd..22de50ca929e 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/systemd/platform-modules-s6000.service +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/systemd/platform-modules-s6000.service @@ -1,7 +1,7 @@ [Unit] Description=Dell S6000 Platform modules After=local-fs.target -Before=pmon.service +Before=pmon.service determine-reboot-cause.service [Service] Type=oneshot diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/fast-reboot_plugin b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/fast-reboot_plugin index d385be3bc685..e32747c7fed5 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/fast-reboot_plugin +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/fast-reboot_plugin @@ -4,3 +4,4 @@ if [[ -d /sys/devices/platform/SMF.512/hwmon/ ]]; then cd /sys/devices/platform/SMF.512/hwmon/* echo 0xcc > mb_poweron_reason fi +/usr/local/bin/s6100_i2c_enumeration.sh deinit & > /dev/null diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/iom_power_off.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/iom_power_off.sh index a7671cfe589c..077d760fdfc0 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/iom_power_off.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/iom_power_off.sh @@ -2,15 +2,15 @@ #This script is used to power off IO modules # IOM can be controlled via SMF using mailbox registers # write 0x2 to 0x04D9 to power off IOM 1 -./io_rd_wr.py --set --val 0x04 --offset 0x210 -./io_rd_wr.py --set --val 0xd9 --offset 0x211 -./io_rd_wr.py --set --val 0x2 --offset 0x213 +io_rd_wr.py --set --val 0x04 --offset 0x210 +io_rd_wr.py --set --val 0xd9 --offset 0x211 +io_rd_wr.py --set --val 0x2 --offset 0x213 # write 0x2 to 0x04DA to power off IOM 2 -./io_rd_wr.py --set --val 0xda --offset 0x211 -./io_rd_wr.py --set --val 0x2 --offset 0x213 +io_rd_wr.py --set --val 0xda --offset 0x211 +io_rd_wr.py --set --val 0x2 --offset 0x213 # write 0x2 to 0x04DB to power off IOM 3 -./io_rd_wr.py --set --val 0xdb --offset 0x211 -./io_rd_wr.py --set --val 0x2 --offset 0x213 +io_rd_wr.py --set --val 0xdb --offset 0x211 +io_rd_wr.py --set --val 0x2 --offset 0x213 # write 0x2 to 0x04DC to power off IOM 4 -./io_rd_wr.py --set --val 0xdc --offset 0x211 -./io_rd_wr.py --set --val 0x2 --offset 0x213 +io_rd_wr.py --set --val 0xdc --offset 0x211 +io_rd_wr.py --set --val 0x2 --offset 0x213 diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/iom_power_on.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/iom_power_on.sh index 3d31170803e1..80b876c216ec 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/iom_power_on.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/iom_power_on.sh @@ -15,3 +15,5 @@ # write 0x1 to 0x04DC to power up IOM 4 /usr/local/bin/io_rd_wr.py --set --val 0xdc --offset 0x211 /usr/local/bin/io_rd_wr.py --set --val 0x1 --offset 0x213 +#Delay for SMF to power on IOMs +sleep 3 diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/pcisysfs.py b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/pcisysfs.py new file mode 100755 index 000000000000..fd3564e75619 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/pcisysfs.py @@ -0,0 +1,92 @@ +#!/usr/bin/python3 + +import struct +import sys +import getopt +from os import * +from mmap import * + +def usage(): + ''' This is the Usage Method ''' + + print('\t\t pcisysfs.py --get --offset --res ') + print('\t\t pcisysfs.py --set --val --offset --res ') + sys.exit(1) + +def pci_mem_read(mm, offset): + mm.seek(offset) + read_data_stream = mm.read(4) + print("") + reg_val = struct.unpack('I', read_data_stream) + print("reg_val read:%x" % reg_val) + return reg_val + +def pci_mem_write(mm, offset, data): + mm.seek(offset) + #print("data to write:%x" % data) + mm.write(struct.pack('I', data)) + +def pci_set_value(resource, val, offset): + fd = open(resource, O_RDWR) + mm = mmap(fd, 0) + pci_mem_write(mm, offset, val) + mm.close() + close(fd) + +def pci_get_value(resource, offset): + fd = open(resource, O_RDWR) + mm = mmap(fd, 0) + pci_mem_read(mm, offset) + mm.close() + close(fd) + +def main(argv): + + ''' The main function will read the user input from the + command line argument and process the request ''' + + opts = '' + val = '' + choice = '' + resource = '' + offset = '' + + try: + opts, args = getopt.getopt(argv, "hgsv:", + ["val=", "res=", "offset=", "help", "get", "set"]) + + except getopt.GetoptError: + usage() + + for opt, arg in opts: + + if opt in ('-h', '--help'): + choice = 'help' + + elif opt in ('-g', '--get'): + choice = 'get' + + elif opt in ('-s', '--set'): + choice = 'set' + + elif opt == '--res': + resource = arg + + elif opt == '--val': + val = int(arg, 16) + + elif opt == '--offset': + offset = int(arg, 16) + + if choice == 'set' and val != '' and offset != '' and resource != '': + pci_set_value(resource, val, offset) + + elif choice == 'get' and offset != '' and resource != '': + pci_get_value(resource, offset) + + else: + usage() + +# Calling the main method +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_reboot_override b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_reboot_override index dcec8067054a..dc681104dac1 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_reboot_override +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_reboot_override @@ -1,5 +1,4 @@ -#!/usr/bin/python -import sys +#!/usr/bin/python3 import os import subprocess import struct @@ -12,21 +11,26 @@ def log_software_reboot(): res = subprocess.check_output(['/usr/share/sonic/device/x86_64-dell_s6100_c2538-r0/fast-reboot_plugin']) return +def ssd_hdparm_upgrade(): + if os.path.exists('/tmp/SSD/SYS_S.bin'): + res = subprocess.check_output(['/usr/share/sonic/device/x86_64-dell_s6100_c2538-r0/ssd-fw-upgrade', 'hdparm-upgrade']) + return + def portio_reg_write(resource, offset, val): fd = os.open(resource, os.O_RDWR) if(fd < 0): - print 'file open failed %s" % resource' + print('file open failed %s" % resource') return if(os.lseek(fd, offset, os.SEEK_SET) != offset): - print 'lseek failed on %s' % resource + print('lseek failed on %s' % resource) return ret = os.write(fd, struct.pack('B', val)) if(ret != 1): - print 'write failed %d' % ret + print('write failed %d' % ret) return os.close(fd) if __name__ == "__main__": log_software_reboot() + ssd_hdparm_upgrade() portio_reg_write(PORT_RES, 0xcf9, 0xe) - 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 b94b69388300..089cf277551d 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 @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # On S6100, the Platform Management Controller runs the # thermal algorithm. It provides a mailbox for the Host @@ -9,7 +9,6 @@ # * PSU # import os -import sys import logging S6100_MAX_FAN_TRAYS = 4 @@ -29,7 +28,7 @@ def get_pmc_register(reg_name): mb_reg_file = MAILBOX_DIR+'/'+reg_name if (not os.path.isfile(mb_reg_file)): - print mb_reg_file, 'not found !' + print(mb_reg_file, 'not found !') return retval try: @@ -45,8 +44,8 @@ def get_pmc_register(reg_name): logging.basicConfig(level=logging.DEBUG) if (os.path.isdir(MAILBOX_DIR)): - print 'dell-s6100-lpc' - print 'Adapter: S6100 Platform Management Controller' + print('dell-s6100-lpc') + print('Adapter: S6100 Platform Management Controller') else: logging.error('S6100 Platform Management Controller module not loaded !') # sys.exit(0) @@ -56,20 +55,20 @@ def get_pmc_register(reg_name): def print_temperature_sensors(): print("\nOnboard Temperature Sensors:") - print ' CPU: ',\ - int(get_pmc_register('temp1_input'))/1000, 'C' - print ' BCM56960 (PSU side): ',\ - int(get_pmc_register('temp2_input'))/1000, 'C' - print ' System Outlet 1 (switch board): ',\ - int(get_pmc_register('temp3_input'))/1000, 'C' - print ' BCM56960 (IO side): ',\ - int(get_pmc_register('temp4_input'))/1000, 'C' - print ' System Outlet 2 (CPU board): ',\ - int(get_pmc_register('temp9_input'))/1000, 'C' - print ' System Inlet Left (IO side): ',\ - int(get_pmc_register('temp10_input'))/1000, 'C' - print ' System Inlet Right (IO side): ',\ - int(get_pmc_register('temp11_input'))/1000, 'C' + print(' CPU: ', + int(get_pmc_register('temp1_input'))/1000, 'C') + print(' BCM56960 (PSU side): ', + int(get_pmc_register('temp2_input'))/1000, 'C') + print(' System Outlet 1 (switch board): ', + int(get_pmc_register('temp3_input'))/1000, 'C') + print(' BCM56960 (IO side): ', + int(get_pmc_register('temp4_input'))/1000, 'C') + print(' System Outlet 2 (CPU board): ', + int(get_pmc_register('temp9_input'))/1000, 'C') + print(' System Inlet Left (IO side): ', + int(get_pmc_register('temp10_input'))/1000, 'C') + print(' System Inlet Right (IO side): ', + int(get_pmc_register('temp11_input'))/1000, 'C') iom_status = get_pmc_register('iom_presence') iom_status = int(iom_status, 16) @@ -84,9 +83,9 @@ def print_temperature_sensors(): for iom in range(0, S6100_MAX_IOMS): if (~iom_presence & (1 << iom)): iom_sensor_indx = iom + 5 - print ' IOM ' + str(iom + 1) + ':\t\t\t ',\ - int(get_pmc_register('temp'+str(iom_sensor_indx) + - '_input'))/1000, 'C' + print(' IOM ' + str(iom + 1) + ':\t\t\t ', + int(get_pmc_register('temp' + str(iom_sensor_indx) + + '_input'))/1000, 'C') # Save the IOM Status for later use if (~iom_status & (1 << iom)): @@ -95,7 +94,7 @@ def print_temperature_sensors(): iom_status_list.append('OFF') else: iom_status_list.append('Not present') - print ' IOM ' + str(iom + 1) + ':\t\t\t ', 'Not present' + print(' IOM ' + str(iom + 1) + ':\t\t\t ', 'Not present') else: logging.error('Unable to check IOM presence') @@ -108,56 +107,56 @@ def print_temperature_sensors(): def print_voltage_sensors(): print("\nOnboard Voltage Sensors:") - print ' CPU XP3R3V_EARLY ',\ - float(get_pmc_register('in1_input'))/1000, 'V' - print ' CPU XP5R0V_CP ',\ - float(get_pmc_register('in2_input'))/1000, 'V' - print ' CPU XP3R3V_STD ',\ - float(get_pmc_register('in3_input'))/1000, 'V' - print ' CPU XP3R3V_CP ',\ - float(get_pmc_register('in4_input'))/1000, 'V' - print ' CPU XP0R75V_VTT_A ',\ - float(get_pmc_register('in5_input'))/1000, 'V' - print ' CPU XPPR75V_VTT_B ',\ - float(get_pmc_register('in6_input'))/1000, 'V' - print ' CPU XP1R07V_CPU ',\ - float(get_pmc_register('in7_input'))/1000, 'V' - print ' CPU XP1R0V_CPU ',\ - float(get_pmc_register('in8_input'))/1000, 'V' - print ' CPU XP12R0V ',\ - float(get_pmc_register('in9_input'))/1000, 'V' - print ' CPU VDDR_CPU_2 ',\ - float(get_pmc_register('in10_input'))/1000, 'V' - print ' CPU VDDR_CPU_1 ',\ - float(get_pmc_register('in11_input'))/1000, 'V' - print ' CPU XP1R5V_CLK ',\ - float(get_pmc_register('in12_input'))/1000, 'V' - print ' CPU XP1R8V_CPU ',\ - float(get_pmc_register('in13_input'))/1000, 'V' - print ' CPU XP1R0V_CPU_VNN ',\ - float(get_pmc_register('in14_input'))/1000, 'V' - print ' CPU XP1R0V_CPU_VCC ',\ - float(get_pmc_register('in15_input'))/1000, 'V' - print ' CPU XP1R5V_EARLY ',\ - float(get_pmc_register('in16_input'))/1000, 'V' - print ' SW XP3R3V_MON ',\ - float(get_pmc_register('in17_input'))/1000, 'V' - print ' SW XP1R25V_MON ',\ - float(get_pmc_register('in19_input'))/1000, 'V' - print ' SW XP1R2V_MON ',\ - float(get_pmc_register('in20_input'))/1000, 'V' - print ' SW XP1R0V_SW_MON ',\ - float(get_pmc_register('in21_input'))/1000, 'V' - print ' SW XP1R0V_ROV_SW_MON ',\ - float(get_pmc_register('in22_input'))/1000, 'V' - print ' SW XR1R0V_BCM84752_MON ',\ - float(get_pmc_register('in23_input'))/1000, 'V' - print ' SW XP5V_MB_MON ',\ - float(get_pmc_register('in24_input'))/1000, 'V' - print ' SW XP3R3V_FPGA_MON ',\ - float(get_pmc_register('in26_input'))/1000, 'V' - print ' SW XP3R3V_EARLY_MON ',\ - float(get_pmc_register('in27_input'))/1000, 'V' + print(' CPU XP3R3V_EARLY ', + float(get_pmc_register('in1_input'))/1000, 'V') + print(' CPU XP5R0V_CP ', + float(get_pmc_register('in2_input'))/1000, 'V') + print(' CPU XP3R3V_STD ', + float(get_pmc_register('in3_input'))/1000, 'V') + print(' CPU XP3R3V_CP ', + float(get_pmc_register('in4_input'))/1000, 'V') + print(' CPU XP0R75V_VTT_A ', + float(get_pmc_register('in5_input'))/1000, 'V') + print(' CPU XPPR75V_VTT_B ', + float(get_pmc_register('in6_input'))/1000, 'V') + print(' CPU XP1R07V_CPU ', + float(get_pmc_register('in7_input'))/1000, 'V') + print(' CPU XP1R0V_CPU ', + float(get_pmc_register('in8_input'))/1000, 'V') + print(' CPU XP12R0V ', + float(get_pmc_register('in9_input'))/1000, 'V') + print(' CPU VDDR_CPU_2 ', + float(get_pmc_register('in10_input'))/1000, 'V') + print(' CPU VDDR_CPU_1 ', + float(get_pmc_register('in11_input'))/1000, 'V') + print(' CPU XP1R5V_CLK ', + float(get_pmc_register('in12_input'))/1000, 'V') + print(' CPU XP1R8V_CPU ', + float(get_pmc_register('in13_input'))/1000, 'V') + print(' CPU XP1R0V_CPU_VNN ', + float(get_pmc_register('in14_input'))/1000, 'V') + print(' CPU XP1R0V_CPU_VCC ', + float(get_pmc_register('in15_input'))/1000, 'V') + print(' CPU XP1R5V_EARLY ', + float(get_pmc_register('in16_input'))/1000, 'V') + print(' SW XP3R3V_MON ', + float(get_pmc_register('in17_input'))/1000, 'V') + print(' SW XP1R25V_MON ', + float(get_pmc_register('in19_input'))/1000, 'V') + print(' SW XP1R2V_MON ', + float(get_pmc_register('in20_input'))/1000, 'V') + print(' SW XP1R0V_SW_MON ', + float(get_pmc_register('in21_input'))/1000, 'V') + print(' SW XP1R0V_ROV_SW_MON ', + float(get_pmc_register('in22_input'))/1000, 'V') + print(' SW XR1R0V_BCM84752_MON ', + float(get_pmc_register('in23_input'))/1000, 'V') + print(' SW XP5V_MB_MON ', + float(get_pmc_register('in24_input'))/1000, 'V') + print(' SW XP3R3V_FPGA_MON ', + float(get_pmc_register('in26_input'))/1000, 'V') + print(' SW XP3R3V_EARLY_MON ', + float(get_pmc_register('in27_input'))/1000, 'V') print_voltage_sensors() @@ -169,40 +168,40 @@ def print_fan_tray(tray): Fan_Status = ['Normal', 'Abnormal'] Airflow_Direction = ['B2F', 'F2B'] - print ' Fan Tray ' + str(tray) + ':' + print(' Fan Tray ' + str(tray) + ':') if (tray == 1): - fan1_speed = get_pmc_register('fan1_input') + fan1_speed = int(get_pmc_register('fan1_input')) air_flow_reg = int(get_pmc_register('fan1_airflow'), 16) fan1_status = 0 if fan1_speed >= 1000 else 1 - print ' Fan Speed: ', fan1_speed, 'RPM' - print ' Fan State: ', Fan_Status[fan1_status] - print ' Air Flow: ', Airflow_Direction[air_flow_reg] + print(' Fan Speed: ', fan1_speed, 'RPM') + print(' Fan State: ', Fan_Status[fan1_status]) + print(' Air Flow: ', Airflow_Direction[air_flow_reg]) elif (tray == 2): - fan1_speed = get_pmc_register('fan3_input') + fan1_speed = int(get_pmc_register('fan3_input')) air_flow_reg = int(get_pmc_register('fan3_airflow'), 16) fan1_status = 0 if fan1_speed >= 1000 else 1 - print ' Fan Speed: ', fan1_speed, 'RPM' - print ' Fan State: ', Fan_Status[fan1_status] - print ' Air Flow: ', Airflow_Direction[air_flow_reg] + print(' Fan Speed: ', fan1_speed, 'RPM') + print(' Fan State: ', Fan_Status[fan1_status]) + print(' Air Flow: ', Airflow_Direction[air_flow_reg]) elif (tray == 3): - fan1_speed = get_pmc_register('fan5_input') + fan1_speed = int(get_pmc_register('fan5_input')) air_flow_reg = int(get_pmc_register('fan5_airflow'), 16) fan1_status = 0 if fan1_speed >= 1000 else 1 - print ' Fan Speed: ', fan1_speed, 'RPM' - print ' Fan State: ', Fan_Status[fan1_status] - print ' Air Flow: ', Airflow_Direction[air_flow_reg] + print(' Fan Speed: ', fan1_speed, 'RPM') + print(' Fan State: ', Fan_Status[fan1_status]) + print(' Air Flow: ', Airflow_Direction[air_flow_reg]) elif (tray == 4): - fan1_speed = get_pmc_register('fan7_input') + fan1_speed = int(get_pmc_register('fan7_input')) air_flow_reg = int(get_pmc_register('fan7_airflow'), 16) fan1_status = 0 if fan1_speed >= 1000 else 1 - print ' Fan Speed: ', fan1_speed, 'RPM' - print ' Fan State: ', Fan_Status[fan1_status] - print ' Air Flow: ', Airflow_Direction[air_flow_reg] + print(' Fan Speed: ', fan1_speed, 'RPM') + print(' Fan State: ', Fan_Status[fan1_status]) + print(' Air Flow: ', Airflow_Direction[air_flow_reg]) print('\nFan Trays:') fan_tray_presence = get_pmc_register('fan_tray_presence') @@ -214,7 +213,7 @@ def print_fan_tray(tray): if (fan_tray_presence & (1 << tray)): print_fan_tray(tray + 1) else: - print '\n Fan Tray ' + str(tray + 1) + ': Not present' + print('\n Fan Tray ' + str(tray + 1) + ': Not present') else: logging.error('Unable to read FAN presence') @@ -233,7 +232,7 @@ def print_psu(psu): Psu_Fan_Status = ['Normal', 'Abnormal'] Psu_Fan_Airflow = ['B2F', 'F2B'] - print ' PSU ' + str(psu) + ':' + print(' PSU ' + str(psu) + ':') if (psu == 1): psu_status = int(get_pmc_register('psu1_presence'), 16) else: @@ -244,12 +243,12 @@ def print_psu(psu): psu_type = (psu_status & (1 << PSU_STATUS_TYPE_BIT)) >>\ PSU_STATUS_TYPE_BIT - print ' Input: ', Psu_Input_Type[psu_input_type] - print ' Type: ', Psu_Type[psu_type] + print(' Input: ', Psu_Input_Type[psu_input_type]) + print(' Type: ', Psu_Type[psu_type]) # PSU FAN details if (psu == 1): - print ' FAN Speed: ', get_pmc_register('fan11_input'), 'RPM' + print(' FAN Speed: ', get_pmc_register('fan11_input'), 'RPM') psu_fan_airflow = int(get_pmc_register('fan11_airflow')) psu_fan_status = int(get_pmc_register('fan11_alarm')) psu_fan_present = int(get_pmc_register('fan11_fault')) @@ -262,7 +261,7 @@ def print_psu(psu): if (input_power != 0): psu_fan_temp = int(get_pmc_register('temp14_input'))/1000 else: - print ' FAN Speed: ', get_pmc_register('fan12_input'), 'RPM' + print(' FAN Speed: ', get_pmc_register('fan12_input'), 'RPM') psu_fan_airflow = int(get_pmc_register('fan12_airflow')) psu_fan_status = int(get_pmc_register('fan12_alarm')) psu_fan_present = int(get_pmc_register('fan12_fault')) @@ -274,28 +273,28 @@ def print_psu(psu): output_power = float(get_pmc_register('power4_input')) / 1000000 if (input_power != 0): psu_fan_temp = int(get_pmc_register('temp15_input'))/1000 - print ' FAN: ', Psu_Fan_Presence[psu_fan_present] - print ' FAN Status: ', Psu_Fan_Status[psu_fan_status] - print ' FAN AIRFLOW: ', Psu_Fan_Airflow[psu_fan_airflow] + print(' FAN: ', Psu_Fan_Presence[psu_fan_present]) + print(' FAN Status: ', Psu_Fan_Status[psu_fan_status]) + print(' FAN AIRFLOW: ', Psu_Fan_Airflow[psu_fan_airflow]) # PSU input & output monitors - print ' Input Voltage: %6.2f' % (input_voltage), 'V' + print(' Input Voltage: %6.2f' % (input_voltage), 'V') - print ' Output Voltage: %6.2f' % (output_voltage), 'V' + print(' Output Voltage: %6.2f' % (output_voltage), 'V') - print ' Input Current: %6.2f' % (input_current), 'A' + print(' Input Current: %6.2f' % (input_current), 'A') - print ' Output Current: %6.2f' % (output_current), 'A' + print(' Output Current: %6.2f' % (output_current), 'A') - print ' Input Power: %6.2f' % (input_power), 'W' + print(' Input Power: %6.2f' % (input_power), 'W') - print ' Output Power: %6.2f' % (output_power), 'W' + print(' Output Power: %6.2f' % (output_power), 'W') # PSU firmware gives spurious temperature reading without input power if (input_power != 0): - print ' Temperature: ', psu_fan_temp, 'C' + print(' Temperature: ', psu_fan_temp, 'C') else: - print ' Temperature: ', 'NA' + print(' Temperature: ', 'NA') print('\nPSUs:') for psu in range(1, S6100_MAX_PSUS + 1): @@ -310,15 +309,15 @@ def print_psu(psu): if (~psu_status & 0b1): print_psu(psu) else: - print '\n PSU ', psu, 'Not present' + print('\n PSU ', psu, 'Not present') else: logging.error('Unable to check PSU presence') -print '\n Total Power: ', get_pmc_register('current_total_power'), 'W' +print('\n Total Power: ', get_pmc_register('current_total_power'), 'W') print('\nIO Modules:') for iom in range(1, S6100_MAX_IOMS+1): - print ' IOM ' + str(iom) + ' :' + iom_status_list[iom - 1] + print(' IOM ' + str(iom) + ' :' + iom_status_list[iom - 1]) -print '\n' +print('\n') diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_bitbang_reset.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_bitbang_reset.sh new file mode 100755 index 000000000000..ff49c0a0f788 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_bitbang_reset.sh @@ -0,0 +1,59 @@ +#!/bin/bash + +# Script to unfreeze a stuck I2C controller, by bit-banging a STOP cycle on the bus + +bit_bang_recovery() +{ + +# Clear the ERRSTS +pcisysfs.py --set --val 0xffffffff --offset 0x018 --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 + +#Enable I2C bit-banging +pcisysfs.py --set --val 0x80000000 --offset 0x388 --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 + +count=1 +while [ $count -le 9 ]; +do + # Bit-bang an I2C STOP cycle + + # SCL=0, SDA=0 + pcisysfs.py --set --val 0x80000000 --offset 0x388 --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 + + sleep 0.01 + + # SCL=1, SDA=0 + pcisysfs.py --set --val 0x80000002 --offset 0x388 --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 + + sleep 0.01 + + # SCL=1, SDA=1 + pcisysfs.py --set --val 0x80000003 --offset 0x388 --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 + + sleep 1 + + # Check I2C DBSTS register + mctrl=$((`pcisysfs.py --get --offset 0x108 --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 | sed 's/^.*:/0x/'`)) + msts=$((`pcisysfs.py --get --offset 0x10c --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 | sed 's/^.*:/0x/'`)) + dbsts=$((`pcisysfs.py --get --offset 0x38c --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 | sed 's/^.*:/0x/'`)) + msts_ip=$((msts&0x1)) + + mctrl=$((10#$mctrl)) + if [ $msts_ip = 0 ]; then + logger -p NOTICE "I2C_bitbang-Bit banging done on I2C bus" + logger -p NOTICE "After I2C_bitbang- MCTRL:$(printf "0x%x" $mctrl)","MSTS:$(printf "0x%x" $msts)","DBSTS:$(printf "0x%x" $dbsts)" + break + fi + count=$(( $count + 1 )) +done + +#Disable I2C bit-banging +pcisysfs.py --set --val 0x00000003 --offset 0x388 --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 + +} + +mctrl=$((`pcisysfs.py --get --offset 0x108 --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 | sed 's/^.*:/0x/'`)) +msts=$((`pcisysfs.py --get --offset 0x10c --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 | sed 's/^.*:/0x/'`)) +dbsts=$((`pcisysfs.py --get --offset 0x38c --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 | sed 's/^.*:/0x/'`)) +logger -p NOTICE "Before I2C_bitbang- MCTRL:$(printf "0x%x" $mctrl)","MSTS:$(printf "0x%x" $msts)","DBSTS:$(printf "0x%x" $dbsts)" +sleep 2 +bit_bang_recovery diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_i2c_enumeration.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_i2c_enumeration.sh new file mode 100755 index 000000000000..d00fec233eaa --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_i2c_enumeration.sh @@ -0,0 +1,305 @@ +#!/bin/bash + +### DellEMC S6100 I2C MUX Enumeration script + +source dell_i2c_utils.sh + +init_devnum() { + found=0 + for devnum in 0 1; do + devname=`cat /sys/bus/i2c/devices/i2c-${devnum}/name` + # iSMT adapter can be at either dffd0000 or dfff0000 + if [[ $devname == 'SMBus iSMT adapter at '* ]]; then + found=1 + break + fi + done + + [[ $found -eq 0 ]] && echo "cannot find iSMT" && exit 1 +} + +# Attach/Detach CPU board mux @ 0x70 +cpu_board_mux() { + case $1 in + "new_device") i2c_mux_create pca9547 0x70 $devnum 2 + ;; + "delete_device") i2c_mux_delete 0x70 $devnum + ;; + *) echo "s6100_platform: cpu_board_mux: invalid command !" + ;; + esac +} + +# Attach/Detach Switchboard MUX @ 0x71 +switch_board_mux() { + case $1 in + "new_device") i2c_mux_create pca9548 0x71 4 10 + ;; + "delete_device") i2c_mux_delete 0x71 4 + ;; + *) echo "s6100_platform: switch_board_mux : invalid command !" + ;; + esac +} + +# Attach/Detach syseeprom on CPU board +sys_eeprom() { + case $1 in + "new_device") i2c_config "echo 24c02 0x50 > /sys/bus/i2c/devices/i2c-2/$1" + ;; + "delete_device") i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-2/$1" + ;; + *) echo "s6100_platform: sys_eeprom : invalid command !" + ;; + esac +} + +#Attach/Detach 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 + "new_device") + for ((i=14;i<=17;i++)); + do + i2c_config "echo dell_s6100_iom_cpld 0x3e > /sys/bus/i2c/devices/i2c-$i/$1" + done + ;; + "delete_device") + for ((i=14;i<=17;i++)); + do + i2c_config "echo 0x3e > /sys/bus/i2c/devices/i2c-$i/$1" + done + ;; + *) echo "s6100_platform: switch_board_cpld : invalid command !" + ;; + esac +} + +#Attach/Detach the MUX connecting all QSFPs on each IOM @0x71 and 0x72 +switch_board_qsfp_mux() { + case $1 in + "new_device") + # The mux for the QSFPs spawn {18..25}, {26..33}... {74..81} + # starting at chennel 18 and 16 channels per IOM. + channel_first=18 + for ((i=9;i>=6;i--)); + do + # 0x71 mux on the IOM 1 + mux_index=$(expr $i - 5) + echo "Attaching PCA9548 $mux_index" + i2c_mux_create pca9548 0x71 $i $channel_first + i2c_mux_create pca9548 0x72 $i $(expr $channel_first + 8) + channel_first=$(expr $channel_first + 16) + done + ;; + "delete_device") + for ((i=9;i>=6;i--)); + do + # 0x71 mux on the IOM 1 + mux_index=$(expr $i - 5) + echo "Detaching PCA9548 $mux_index" + i2c_mux_delete 0x71 $i + i2c_mux_delete 0x72 $i + done + ;; + *) echo "s6100_platform: switch_board_qsfp_mux: invalid command !" + ;; + esac +} + +#Attach/Detach the SFP modules on PCA9548_2 +switch_board_sfp() { + case $1 in + "new_device") i2c_config "echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-11/$1" + i2c_config "echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-12/$1" + ;; + "delete_device") i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-11/$1" + i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-12/$1" + ;; + *) echo "s6100_platform: switch_board_sfp: invalid command !" + ;; + esac +} + +#Add/Delete ($1) a range ($2..$3) of QSFPs +qsfp_device_mod() { + case $1 in + "new_device") for ((i=$2;i<=$3;i++)); + do + i2c_config "echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-$i/$1" + done + ;; + "delete_device") for ((i=$2;i<=$3;i++)); + do + i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-$i/$1" + done + ;; + *) echo "s6100_platform: qsfp_device_mod: invalid command $1:$2,$3!" + ;; + esac +} + +# Attach/Detach 16 instances of QSFP ports on each IO modules +# eeprom can dump data using below command +switch_board_qsfp() { + if i2c_poll_bus_exists "/sys/bus/i2c/devices/i2c-18"; then + qsfp_device_mod $1 18 33 + fi + + if i2c_poll_bus_exists "/sys/bus/i2c/devices/i2c-34"; then + qsfp_device_mod $1 34 49 + fi + + if i2c_poll_bus_exists "/sys/bus/i2c/devices/i2c-50"; then + qsfp_device_mod $1 50 65 + fi + + if i2c_poll_bus_exists "/sys/bus/i2c/devices/i2c-66"; then + qsfp_device_mod $1 66 81 + fi +} + +# Enable/Disable low power mode on all QSFP ports +switch_board_qsfp_lpmode() { + case $1 in + "enable") value=0xffff + ;; + "disable") value=0x0 + ;; + *) echo "s6100_platform: switch_board_qsfp_lpmode: invalid command $1!" + return + ;; + esac + echo $value > /sys/class/i2c-adapter/i2c-14/14-003e/qsfp_lpmode + echo $value > /sys/class/i2c-adapter/i2c-15/15-003e/qsfp_lpmode + echo $value > /sys/class/i2c-adapter/i2c-16/16-003e/qsfp_lpmode + echo $value > /sys/class/i2c-adapter/i2c-17/17-003e/qsfp_lpmode +} + +# Enable/Disable xcvr presence interrupts +xcvr_presence_interrupts() { + case $1 in + "enable") + for ((i=14;i<=17;i++)); + do + echo 0x0 > /sys/class/i2c-adapter/i2c-$i/$i-003e/qsfp_abs_mask + done + ;; + "disable") + for ((i=14;i<=17;i++)); + do + echo 0xffff > /sys/class/i2c-adapter/i2c-$i/$i-003e/qsfp_abs_mask + done + ;; + *) echo "s6100_platform: xcvr_presence_interrupts: invalid command !" + ;; + esac +} + +# Reset the mux tree +reset_muxes() { + local i + + # Reset the IOM muxes (if they have been already instantiated) + for ((i=14;i<=17;i++)); + do + if [[ -e /sys/class/i2c-adapter/i2c-$i/$i-003e ]]; then + echo 0xfc > /sys/class/i2c-adapter/i2c-$i/$i-003e/sep_reset + echo 0xff > /sys/class/i2c-adapter/i2c-$i/$i-003e/sep_reset + fi + done + + # Reset the switch card PCA9548A + io_rd_wr.py --set --val 0xef --offset 0x110 + io_rd_wr.py --set --val 0xff --offset 0x110 + + # Reset the CPU Card PCA9547 + io_rd_wr.py --set --val 0xfd --offset 0x20b + io_rd_wr.py --set --val 0xff --offset 0x20b +} + +init_devnum + +check_iom_status() +{ + SMF_DIR="/sys/devices/platform/SMF.512/hwmon/*" + count=0 + iom_sta=0 + MAX_IOM_STARTUP_DELAY=50 + + if [ -d $SMF_DIR ]; then + iom_status=$(cat $SMF_DIR/iom_status) + cpu_iom1_sta=$(cat $SMF_DIR/cpu_iom1_control) + cpu_iom2_sta=$(cat $SMF_DIR/cpu_iom2_control) + cpu_iom3_sta=$(cat $SMF_DIR/cpu_iom3_control) + cpu_iom4_sta=$(cat $SMF_DIR/cpu_iom4_control) + cpu_iom_sta=$(( cpu_iom1_sta|cpu_iom2_sta|cpu_iom3_sta|cpu_iom4_sta )) + echo "Started polling IOM status" + while [ "$iom_status" != "f0" -o "$cpu_iom_sta" != "0" ]; + do + if [ "$count" -gt "$MAX_IOM_STARTUP_DELAY" ];then + echo "IOM is taking longer than expected to power up.Aborting. + iom_status- $iom_status cpu_iom_sta1- $cpu_iom1_sta cpu_iom_sta2- $cpu_iom2_sta + cpu_iom_sta3- $cpu_iom3_sta cpu_iom_sta4- $cpu_iom4_sta " + iom_sta=1 + break + fi + cpu_iom1_sta=$(cat $SMF_DIR/cpu_iom1_control) + cpu_iom2_sta=$(cat $SMF_DIR/cpu_iom2_control) + cpu_iom3_sta=$(cat $SMF_DIR/cpu_iom3_control) + cpu_iom4_sta=$(cat $SMF_DIR/cpu_iom4_control) + cpu_iom_sta=$(( cpu_iom1_sta|cpu_iom2_sta|cpu_iom3_sta|cpu_iom4_sta )) + iom_status=$(cat $SMF_DIR/iom_status) + sleep .1 + count=`expr $count + 1` + done + + if [ "$iom_sta" != "1" ];then + echo "All IOM's are UP" + fi + fi +} + +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" + check_iom_status + switch_board_qsfp_mux "new_device" + switch_board_sfp "new_device" + switch_board_qsfp "new_device" + switch_board_qsfp_lpmode "disable" + /usr/local/bin/s6100_bitbang_reset.sh + xcvr_presence_interrupts "enable" +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" + switch_board_qsfp_mux "delete_device" + cpu_board_mux "delete_device" +fi 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 1d974f64504a..62a8c1a2812f 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 @@ -2,246 +2,12 @@ #platform init script for Dell S6100 -source dell_i2c_utils.sh - -init_devnum() { - found=0 - for devnum in 0 1; do - devname=`cat /sys/bus/i2c/devices/i2c-${devnum}/name` - # iSMT adapter can be at either dffd0000 or dfff0000 - if [[ $devname == 'SMBus iSMT adapter at '* ]]; then - found=1 - break - fi - done - - [[ $found -eq 0 ]] && echo "cannot find iSMT" && exit 1 -} - -# Attach/Detach CPU board mux @ 0x70 -cpu_board_mux() { - case $1 in - "new_device") i2c_mux_create pca9547 0x70 $devnum 2 - ;; - "delete_device") i2c_mux_delete 0x70 $devnum - ;; - *) echo "s6100_platform: cpu_board_mux: invalid command !" - ;; - esac -} - -# Attach/Detach Switchboard MUX @ 0x71 -switch_board_mux() { - case $1 in - "new_device") i2c_mux_create pca9548 0x71 4 10 - ;; - "delete_device") i2c_mux_delete 0x71 4 - ;; - *) echo "s6100_platform: switch_board_mux : invalid command !" - ;; - esac -} - -# Attach/Detach syseeprom on CPU board -sys_eeprom() { - case $1 in - "new_device") i2c_config "echo 24c02 0x50 > /sys/bus/i2c/devices/i2c-2/$1" - ;; - "delete_device") i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-2/$1" - ;; - *) echo "s6100_platform: sys_eeprom : invalid command !" - ;; - esac -} - -#Attach/Detach 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 - "new_device") - for ((i=14;i<=17;i++)); - do - i2c_config "echo dell_s6100_iom_cpld 0x3e > /sys/bus/i2c/devices/i2c-$i/$1" - done - ;; - "delete_device") - for ((i=14;i<=17;i++)); - do - i2c_config "echo 0x3e > /sys/bus/i2c/devices/i2c-$i/$1" - done - ;; - *) echo "s6100_platform: switch_board_cpld : invalid command !" - ;; - esac -} - -#Attach/Detach the MUX connecting all QSFPs on each IOM @0x71 and 0x72 -switch_board_qsfp_mux() { - case $1 in - "new_device") - # The mux for the QSFPs spawn {18..25}, {26..33}... {74..81} - # starting at chennel 18 and 16 channels per IOM. - channel_first=18 - for ((i=9;i>=6;i--)); - do - # 0x71 mux on the IOM 1 - mux_index=$(expr $i - 5) - echo "Attaching PCA9548 $mux_index" - i2c_mux_create pca9548 0x71 $i $channel_first - i2c_mux_create pca9548 0x72 $i $(expr $channel_first + 8) - channel_first=$(expr $channel_first + 16) - done - ;; - "delete_device") - for ((i=9;i>=6;i--)); - do - # 0x71 mux on the IOM 1 - mux_index=$(expr $i - 5) - echo "Detaching PCA9548 $mux_index" - i2c_mux_delete 0x71 $i - i2c_mux_delete 0x72 $i - done - ;; - *) echo "s6100_platform: switch_board_qsfp_mux: invalid command !" - ;; - esac -} - -#Attach/Detach the SFP modules on PCA9548_2 -switch_board_sfp() { - case $1 in - "new_device") i2c_config "echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-11/$1" - i2c_config "echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-12/$1" - ;; - "delete_device") i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-11/$1" - i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-12/$1" - ;; - *) echo "s6100_platform: switch_board_sfp: invalid command !" - ;; - esac -} - -#Add/Delete ($1) a range ($2..$3) of QSFPs -qsfp_device_mod() { - case $1 in - "new_device") for ((i=$2;i<=$3;i++)); - do - i2c_config "echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-$i/$1" - done - ;; - "delete_device") for ((i=$2;i<=$3;i++)); - do - i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-$i/$1" - done - ;; - *) echo "s6100_platform: qsfp_device_mod: invalid command $1:$2,$3!" - ;; - esac -} - -# Attach/Detach 16 instances of QSFP ports on each IO modules -# eeprom can dump data using below command -switch_board_qsfp() { - if i2c_poll_bus_exists "/sys/bus/i2c/devices/i2c-18"; then - qsfp_device_mod $1 18 33 - fi - - if i2c_poll_bus_exists "/sys/bus/i2c/devices/i2c-34"; then - qsfp_device_mod $1 34 49 - fi - - if i2c_poll_bus_exists "/sys/bus/i2c/devices/i2c-50"; then - qsfp_device_mod $1 50 65 - fi - - if i2c_poll_bus_exists "/sys/bus/i2c/devices/i2c-66"; then - qsfp_device_mod $1 66 81 - fi -} - -# Enable/Disable low power mode on all QSFP ports -switch_board_qsfp_lpmode() { - case $1 in - "enable") value=0xffff - ;; - "disable") value=0x0 - ;; - *) echo "s6100_platform: switch_board_qsfp_lpmode: invalid command $1!" - return - ;; - esac - echo $value > /sys/class/i2c-adapter/i2c-14/14-003e/qsfp_lpmode - echo $value > /sys/class/i2c-adapter/i2c-15/15-003e/qsfp_lpmode - echo $value > /sys/class/i2c-adapter/i2c-16/16-003e/qsfp_lpmode - echo $value > /sys/class/i2c-adapter/i2c-17/17-003e/qsfp_lpmode -} - -# Enable/Disable xcvr presence interrupts -xcvr_presence_interrupts() { - case $1 in - "enable") - for ((i=14;i<=17;i++)); - do - echo 0x0 > /sys/class/i2c-adapter/i2c-$i/$i-003e/qsfp_abs_mask - done - ;; - "disable") - for ((i=14;i<=17;i++)); - do - echo 0xffff > /sys/class/i2c-adapter/i2c-$i/$i-003e/qsfp_abs_mask - done - ;; - *) echo "s6100_platform: xcvr_presence_interrupts: invalid command !" - ;; - esac -} - -# Reset the mux tree -reset_muxes() { - local i - - # Reset the IOM muxes (if they have been already instantiated) - for ((i=14;i<=17;i++)); - do - if [[ -e /sys/class/i2c-adapter/i2c-$i/$i-003e ]]; then - echo 0xfc > /sys/class/i2c-adapter/i2c-$i/$i-003e/sep_reset - echo 0xff > /sys/class/i2c-adapter/i2c-$i/$i-003e/sep_reset - fi - done - - # Reset the switch card PCA9548A - io_rd_wr.py --set --val 0xef --offset 0x110 - io_rd_wr.py --set --val 0xff --offset 0x110 - - # Reset the CPU Card PCA9547 - io_rd_wr.py --set --val 0xfd --offset 0x20b - io_rd_wr.py --set --val 0xff --offset 0x20b -} - install_python_api_package() { device="/usr/share/sonic/device" platform=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) rv=$(pip install $device/$platform/sonic_platform-1.0-py2-none-any.whl) + rv=$(pip3 install $device/$platform/sonic_platform-1.0-py3-none-any.whl) } remove_python_api_package() { @@ -249,11 +15,17 @@ remove_python_api_package() { if [ $? -eq 0 ]; then rv=$(pip uninstall -y sonic-platform > /dev/null 2>/dev/null) fi + + rv=$(pip3 show sonic-platform > /dev/null 2>/dev/null) + if [ $? -eq 0 ]; then + rv=$(pip3 uninstall -y sonic-platform > /dev/null 2>/dev/null) + fi } -init_devnum if [[ "$1" == "init" ]]; then + + pericom="/sys/bus/pci/devices/0000:08:00.0" modprobe i2c-dev modprobe i2c-mux-pca954x force_deselect_on_exit=1 modprobe dell_ich @@ -262,34 +34,27 @@ if [[ "$1" == "init" ]]; then modprobe nvram systemctl start s6100-reboot-cause.service + # Disable pericom/xilinx + echo 1 > /sys/bus/pci/devices/0000:02:00.0/remove + [ -d $pericom ] && echo 1 > $pericom/remove + # Disable Watchdog Timer if [[ -e /usr/local/bin/platform_watchdog_disable.sh ]]; then /usr/local/bin/platform_watchdog_disable.sh fi - 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" - switch_board_qsfp "new_device" - switch_board_qsfp_lpmode "disable" - xcvr_presence_interrupts "enable" + is_fast_warm=$(cat /proc/cmdline | grep SONIC_BOOT_TYPE | wc -l) + + if [[ "$is_fast_warm" == "1" ]]; then + systemctl start --no-block s6100-i2c-enumerate.service + else + systemctl start s6100-i2c-enumerate.service + fi install_python_api_package 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" - switch_board_qsfp_mux "delete_device" - cpu_board_mux "delete_device" + /usr/local/bin/s6100_i2c_enumeration.sh deinit modprobe -r dell_s6100_lpc modprobe -r dell_s6100_iom_cpld diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/ssd-fw-upgrade b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/ssd-fw-upgrade new file mode 100755 index 000000000000..0db6b1f62c66 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/ssd-fw-upgrade @@ -0,0 +1,100 @@ +#!/bin/bash +# This script does the SSD firware upgrade +# This has been integrated as part of reboot/warm-reboot/fast-reboot script. +SKIP_UPGRADE=0 +CHECKSUM_VALUE="b9b6dbb362b7632837af9cd320c5d147" +unmount () { + exist=$(mount | grep " $1 " | wc -l) + if [ $exist -ne 0 ]; then + umount $1 + if [[ $? -ne 0 ]]; then + fuser -vm $1 + SKIP_UPGRADE=1 + fi + fi +} + +mp_tool_reboot() { + if [ ! -d /mnt/ramdisk ]; then + mkdir -p /mnt/ramdisk; + fi + mount -t tmpfs -o size=16m swap /mnt/ramdisk + cp /tmp/SSD.zip /mnt/ramdisk/ + cd /mnt/ramdisk + unzip -q SSD.zip + chmod +x SSD/mp_64 + + #stopped journal and syslog services to unmount /host + systemctl stop systemd-journald.service + systemctl stop systemd-journald.socket + systemctl stop systemd-journald-audit.socket + systemctl stop systemd-journald-dev-log.socket + systemctl stop syslog.service + systemctl stop syslog.socket + systemctl stop docker.socket + sleep 2 + unmount /var/log + loop_exist=$(losetup -a | grep loop1 | wc -l) + if [ $loop_exist -ne 0 ]; then + losetup -d /dev/loop1 + fi + unmount /boot + unmount /var/lib/docker + unmount /host + #start the services whichever we stopped for succesful /host unmount + systemctl start systemd-journald.service + systemctl start systemd-journald.socket + systemctl start systemd-journald-audit.socket + systemctl start systemd-journald-dev-log.socket + systemctl start syslog.service + systemctl start syslog.socket + if [ $SKIP_UPGRADE == 0 ]; then + echo 1 > /sys/class/scsi_device/4\:0\:0\:0/device/delete + echo "0 0 0" > /sys/class/scsi_host/host4/scan + sleep 3 + DEVICE=$(dmesg | grep "Attached SCSI disk" | sed -n \$p | + grep -o -P '(sd[a-z])') + cd /mnt/ramdisk/SSD + ./mp_64 -d /dev/${DEVICE} -c 1 -u -k -r + fi +} + +hdparm-upgrade() { + if [[ -x "$(command -v hdparm)" ]];then + hdparm --fwdownload /tmp/SSD/SYS_S.bin --yes-i-know-what-i-am-doing \ + --please-destroy-my-drive /dev/sda + fi +} + +platform_check() { + platform=$(sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) + version_type=$(dmesg | grep "mSATA") + md5sum_value=$(md5sum /tmp/SSD.zip | cut -d ' ' -f1) + if [[ "$md5sum_value" != "$CHECKSUM_VALUE" || "$platform" != *"s6100"* || + "$version_type" != *"3IE3"* || "$version_type" != *"S16425c1"* ]];then + exit 1 + fi +} + +if [[ ! -f /tmp/SSD.zip ]];then + exit 1 +fi + +case "$1" in + fast-reboot|warm-reboot) + platform_check + mp_tool_reboot + ;; + reboot) + platform_check + cd /tmp + unzip -q SSD.zip + ;; + hdparm-upgrade) + $1 + ;; + *) + echo "Usage: $0 {fast-reboot|warm-reboot|reboot|hdparm-upgrade}" >&2 + exit 2 + ;; +esac diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/track_reboot_reason.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/track_reboot_reason.sh index 0686d577c9e4..775c0c8d05f2 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/track_reboot_reason.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/track_reboot_reason.sh @@ -8,6 +8,7 @@ nvram_missing=0 REBOOT_CAUSE_FILE=/host/reboot-cause/reboot-cause.txt REBOOT_REASON_FILE=/host/reboot-cause/platform/reboot_reason BIOS_VERSION_FILE=/host/reboot-cause/platform/bios_minor_version +SMF_MSS_VERSION_FILE=/sys/devices/platform/SMF.512/hwmon/*/smf_firmware_ver SMF_POWERON_REASON=/sys/devices/platform/SMF.512/hwmon/*/smf_poweron_reason SMF_RESET_REASON=/sys/devices/platform/SMF.512/hwmon/*/smf_reset_reason MAILBOX_POWERON_REASON=/sys/devices/platform/SMF.512/hwmon/*/mb_poweron_reason @@ -34,6 +35,7 @@ if [[ -d /host/reboot-cause/platform ]]; then fi fi +SMF_FPGA_VERSION=$((16#$(io_rd_wr.py --get --offset 0x200 | cut -d " " -f 3))) SMF_BIOS_REG=$(io_rd_wr.py --get --offset 0x203 | cut -d " " -f 3) SMF_BIOS_REG=$((16#$SMF_BIOS_REG)) bios_secondary_boot=$(($SMF_BIOS_REG & 1)) @@ -77,7 +79,7 @@ _get_smf_reset_register(){ echo "Third reset - $third_reset" >> $RESET_REASON_FILE echo "Fourth reset - $fourth_reset" >> $RESET_REASON_FILE fi - + logger -p user.info -t DELL_S6100_REBOOT_CAUSE "RST value in NVRAM: $first_reset, $second_reset, $third_reset, $fourth_reset" # Clearing NVRAM values to holding next reset values nvram_rd_wr.py --set --val 0xee --offset 0x58 nvram_rd_wr.py --set --val 0xee --offset 0x5c @@ -143,24 +145,51 @@ update_mailbox_register(){ _get_smf_reset_register if [[ -d /sys/devices/platform/SMF.512/hwmon/ ]]; then - is_thermal_reboot=$(_is_thermal_reset) - - is_wd_reboot=$(_is_watchdog_reset) - + por=$(cat $SMF_POWERON_REASON) + rst=$(cat $SMF_RESET_REASON) mbr=$(cat $MAILBOX_POWERON_REASON) reason=$(echo $mbr | cut -d 'x' -f2) - if [[ $reason = "ff" ]]; then - echo "None" > $REBOOT_REASON_FILE - echo 0xbb > $MAILBOX_POWERON_REASON - elif [[ $is_thermal_reboot = 1 ]]; then - echo 0xee > $MAILBOX_POWERON_REASON - elif [[ $is_wd_reboot = 1 ]] && [[ $reason != "cc" ]]; then - echo 0xdd > $MAILBOX_POWERON_REASON - elif [[ $reason = "cc" ]]; then - echo 0xaa > $MAILBOX_POWERON_REASON + logger -p user.info -t DELL_S6100_REBOOT_CAUSE "POR: $por, RST: $rst, MBR: $mbr" + + SMF_MSS_VERSION=$(cat $SMF_MSS_VERSION_FILE) + SMF_MSS_VERSION_MAJOR=$(echo $SMF_MSS_VERSION | cut -d '.' -f1) + SMF_MSS_VERSION_MINOR=$(echo $SMF_MSS_VERSION | cut -d '.' -f2) + SMF_FPGA_VERSION_MAJOR=$(( (SMF_FPGA_VERSION & 0xF0) >> 4 )) + SMF_FPGA_VERSION_MINOR=$(( SMF_FPGA_VERSION & 0x0F )) + + if [[ -e $BIOS_VERSION_FILE ]] \ + && [[ $SMF_MSS_VERSION_MAJOR -ge 2 ]] && [[ $SMF_MSS_VERSION_MINOR -ge 7 ]] \ + && [[ $SMF_FPGA_VERSION_MAJOR -ge 1 ]] && [[ $SMF_FPGA_VERSION_MINOR -ge 4 ]]; then + + if [[ $reason = "cc" ]]; then + echo 0xaa > $MAILBOX_POWERON_REASON + elif [[ $SMF_RESET = "11" ]]; then + echo 0xee > $MAILBOX_POWERON_REASON + elif [[ $SMF_RESET = "33" ]]; then + echo 0xdd > $MAILBOX_POWERON_REASON + else + echo "Unknown software reboot" > $REBOOT_CAUSE_FILE + echo 0x99 > $MAILBOX_POWERON_REASON + fi + else - _is_unknown_reset $is_thermal_reboot - echo 0x99 > $MAILBOX_POWERON_REASON + is_thermal_reboot=$(_is_thermal_reset) + + is_wd_reboot=$(_is_watchdog_reset) + + if [[ $reason = "ff" ]]; then + echo "None" > $REBOOT_REASON_FILE + echo 0xbb > $MAILBOX_POWERON_REASON + elif [[ $is_thermal_reboot = 1 ]]; then + echo 0xee > $MAILBOX_POWERON_REASON + elif [[ $is_wd_reboot = 1 ]] && [[ $reason != "cc" ]]; then + echo 0xdd > $MAILBOX_POWERON_REASON + elif [[ $reason = "cc" ]]; then + echo 0xaa > $MAILBOX_POWERON_REASON + else + _is_unknown_reset $is_thermal_reboot + echo 0x99 > $MAILBOX_POWERON_REASON + fi fi fi } diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/setup.py b/platform/broadcom/sonic-platform-modules-dell/s6100/setup.py index eb95775c6677..d031762fbeb8 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/setup.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/setup.py @@ -23,6 +23,7 @@ 'Natural Language :: English', 'Operating System :: POSIX :: Linux', 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3.7', 'Topic :: Utilities', ], keywords='sonic SONiC platform PLATFORM', diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/__init__.py index 96de5a93c4c2..2764c0c33007 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/__init__.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/__init__.py @@ -1,3 +1,3 @@ -__all__ = ["platform", "chassis", "module", "fan", "psu", "sfp", "thermal"] +__all__ = ["platform", "chassis", "module", "fan", "fan_drawer", "psu", "sfp", "thermal"] from sonic_platform import * 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 a1c7692b5f6e..f8e009cdbefd 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 @@ -10,22 +10,21 @@ try: import os - from sonic_platform_base.platform_base import PlatformBase from sonic_platform_base.chassis_base import ChassisBase from sonic_platform.sfp import Sfp from sonic_platform.psu import Psu - from sonic_platform.fan import Fan + from sonic_platform.fan_drawer import FanDrawer from sonic_platform.module import Module from sonic_platform.thermal import Thermal from sonic_platform.component import Component from sonic_platform.watchdog import Watchdog - from eeprom import Eeprom + from sonic_platform.eeprom import Eeprom import time except ImportError as e: raise ImportError(str(e) + "- required module not found") MAX_S6100_MODULE = 4 -MAX_S6100_FAN = 4 +MAX_S6100_FANTRAY = 4 MAX_S6100_PSU = 2 MAX_S6100_THERMAL = 10 MAX_S6100_COMPONENT = 3 @@ -39,6 +38,7 @@ class Chassis(ChassisBase): HWMON_DIR = "/sys/devices/platform/SMF.512/hwmon/" HWMON_NODE = os.listdir(HWMON_DIR)[0] MAILBOX_DIR = HWMON_DIR + HWMON_NODE + POLL_INTERVAL = 1 # Poll interval in seconds reset_reason_dict = {} reset_reason_dict[11] = ChassisBase.REBOOT_CAUSE_POWER_LOSS @@ -54,9 +54,21 @@ class Chassis(ChassisBase): power_reason_dict[33] = ChassisBase.REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC power_reason_dict[44] = ChassisBase.REBOOT_CAUSE_INSUFFICIENT_FAN_SPEED + status_led_reg_to_color = { + 0x00: 'green', 0x01: 'blinking green', 0x02: 'amber', + 0x04: 'amber', 0x08: 'blinking amber', 0x10: 'blinking amber' + } + + color_to_status_led_reg = { + 'green': 0x00, 'blinking green': 0x01, + 'amber': 0x02, 'blinking amber': 0x08 + } + def __init__(self): ChassisBase.__init__(self) + self.status_led_reg = "sys_status_led" + self.supported_led_color = ['green', 'blinking green', 'amber', 'blinking amber'] # Initialize EEPROM self._eeprom = Eeprom() for i in range(MAX_S6100_MODULE): @@ -64,9 +76,10 @@ def __init__(self): self._module_list.append(module) self._sfp_list.extend(module._sfp_list) - for i in range(MAX_S6100_FAN): - fan = Fan(i) - self._fan_list.append(fan) + for i in range(MAX_S6100_FANTRAY): + fandrawer = FanDrawer(i) + self._fan_drawer_list.append(fandrawer) + self._fan_list.extend(fandrawer._fan_list) for i in range(MAX_S6100_PSU): psu = Psu(i) @@ -81,6 +94,7 @@ def __init__(self): self._component_list.append(component) self._watchdog = Watchdog() + self._transceiver_presence = self._get_transceiver_presence() def _get_reboot_reason_smf_register(self): # In S6100, mb_poweron_reason register will @@ -111,6 +125,41 @@ def _get_pmc_register(self, reg_name): rv = rv.lstrip(" ") return rv + def _set_pmc_register(self, reg_name, value): + # On successful write, returns the length of value written on + # reg_name and on failure returns 'ERR' + rv = 'ERR' + mb_reg_file = self.MAILBOX_DIR + '/' + reg_name + + if (not os.path.isfile(mb_reg_file)): + return rv + + try: + with open(mb_reg_file, 'w') as fd: + rv = fd.write(str(value)) + except IOError: + rv = 'ERR' + + return rv + + def _get_register(self, reg_file): + # On successful read, returns the value read from given + # reg_name and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(reg_file)): + return rv + + try: + with open(reg_file, 'r') as fd: + rv = fd.read() + except Exception as error: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + def get_name(self): """ Retrieves the name of the chassis @@ -152,25 +201,32 @@ def get_status(self): """ return True - def get_base_mac(self): + def get_position_in_parent(self): """ - Retrieves the base MAC address for the chassis + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return -1 + def is_replaceable(self): + """ + Indicate whether Chassis is replaceable. Returns: - A string containing the MAC address in the format - 'XX:XX:XX:XX:XX:XX' + bool: True if it is replaceable. """ - return self._eeprom.base_mac_addr() + return False - def get_serial_number(self): + def get_base_mac(self): """ - Retrieves the hardware serial number for the chassis + Retrieves the base MAC address for the chassis Returns: - A string containing the hardware serial number for this - chassis. + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' """ - return self._eeprom.serial_number_str() + return self._eeprom.base_mac_addr() def get_system_eeprom_info(self): """ @@ -215,3 +271,138 @@ def get_reboot_cause(self): return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Invalid Reason") + + def _get_transceiver_presence(self): + + cpld2_modprs = self._get_register( + "/sys/class/i2c-adapter/i2c-14/14-003e/qsfp_modprs") + cpld3_modprs = self._get_register( + "/sys/class/i2c-adapter/i2c-15/15-003e/qsfp_modprs") + cpld4_modprs = self._get_register( + "/sys/class/i2c-adapter/i2c-16/16-003e/qsfp_modprs") + cpld5_modprs = self._get_register( + "/sys/class/i2c-adapter/i2c-17/17-003e/qsfp_modprs") + + # If IOM is not present, register read will fail. + # Handle the scenario gracefully + if (cpld2_modprs == 'read error') or (cpld2_modprs == 'ERR'): + cpld2_modprs = '0x0' + if (cpld3_modprs == 'read error') or (cpld3_modprs == 'ERR'): + cpld3_modprs = '0x0' + if (cpld4_modprs == 'read error') or (cpld4_modprs == 'ERR'): + cpld4_modprs = '0x0' + if (cpld5_modprs == 'read error') or (cpld5_modprs == 'ERR'): + cpld5_modprs = '0x0' + + # Make it contiguous + transceiver_presence = (int(cpld2_modprs, 16) & 0xffff) |\ + ((int(cpld4_modprs, 16) & 0xffff) << 16) |\ + ((int(cpld3_modprs, 16) & 0xffff) << 32) |\ + ((int(cpld5_modprs, 16) & 0xffff) << 48) + + return transceiver_presence + + def get_change_event(self, timeout=0): + """ + Returns a nested dictionary containing all devices which have + experienced a change at chassis level + + Args: + timeout: Timeout in milliseconds (optional). If timeout == 0, + this method will block until a change is detected. + + Returns: + (bool, dict): + - True if call successful, False if not; + - A nested dictionary where key is a device type, + value is a dictionary with key:value pairs in the + format of {'device_id':'device_event'}, + where device_id is the device ID for this device and + device_event, + status='1' represents device inserted, + status='0' represents device removed. + Ex. {'fan':{'0':'0', '2':'1'}, 'sfp':{'11':'0'}} + indicates that fan 0 has been removed, fan 2 + has been inserted and sfp 11 has been removed. + """ + port_dict = {} + ret_dict = {'sfp': port_dict} + forever = False + + if timeout == 0: + forever = True + elif timeout > 0: + timeout = timeout / float(1000) # Convert to secs + else: + return False, ret_dict # Incorrect timeout + + while True: + if forever: + timer = self.POLL_INTERVAL + else: + timer = min(timeout, self.POLL_INTERVAL) + start_time = time.time() + + time.sleep(timer) + cur_presence = self._get_transceiver_presence() + + # Update dict only if a change has been detected + if cur_presence != self._transceiver_presence: + changed_ports = self._transceiver_presence ^ cur_presence + for port in range(self.get_num_sfps()): + # Mask off the bit corresponding to particular port + mask = 1 << port + if changed_ports & mask: + # qsfp_modprs 1 => optics is removed + if cur_presence & mask: + port_dict[port] = '0' + # qsfp_modprs 0 => optics is inserted + else: + port_dict[port] = '1' + + # Update current presence + self._transceiver_presence = cur_presence + break + + if not forever: + elapsed_time = time.time() - start_time + timeout = round(timeout - elapsed_time, 3) + if timeout <= 0: + break + + return True, ret_dict + + def set_status_led(self, color): + """ + Sets the state of the system LED + + Args: + color: A string representing the color with which to set the + system LED + + Returns: + bool: True if system LED state is set successfully, False if not + """ + if color not in self.supported_led_color: + return False + + value = self.color_to_status_led_reg[color] + rv = self._set_pmc_register(self.status_led_reg, value) + if (rv != 'ERR'): + return True + else: + return False + + def get_status_led(self): + """ + Gets the state of the system LED + + Returns: + A string, one of the valid LED color strings which could be + vendor specified. + """ + reg_val = self._get_pmc_register(self.status_led_reg) + if (reg_val != 'ERR'): + return self.status_led_reg_to_color.get(int(reg_val, 16), None) + else: + return None diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/component.py index a92ab5c85db2..bea180d440b5 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/component.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/component.py @@ -39,9 +39,10 @@ class Component(ComponentBase): ] def __init__(self, component_index=0, - is_module=False, iom_index=0, i2c_line=0): + is_module=False, iom_index=0, i2c_line=0, dependency=None): self.is_module_component = is_module + self.dependency = dependency if self.is_module_component: self.index = iom_index @@ -79,7 +80,7 @@ def _get_command_result(self, cmdline): stderr=subprocess.STDOUT) stdout = proc.communicate()[0] proc.wait() - result = stdout.rstrip('\n') + result = stdout.decode('utf-8').rstrip('\n') except OSError: result = None @@ -132,6 +133,61 @@ def get_name(self): """ return self.name + def get_model(self): + """ + Retrieves the part number of the component + Returns: + string: Part number of component + """ + return 'NA' + + def get_serial(self): + """ + Retrieves the serial number of the component + Returns: + string: Serial number of component + """ + return 'NA' + + def get_presence(self): + """ + Retrieves the presence of the component + Returns: + bool: True if present, False if not + """ + if self.is_module_component: + return self.dependency.get_presence() + else: + return True + + def get_status(self): + """ + Retrieves the operational status of the component + Returns: + bool: True if component is operating properly, False if not + """ + if self.is_module_component: + return self.dependency.get_status() + else: + return True + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return -1 + + def is_replaceable(self): + """ + Indicate whether component is replaceable. + Returns: + bool: True if it is replaceable. + """ + return False + def get_description(self): """ Retrieves the description of the component 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 d281783827b6..288c1a2ccfcf 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 @@ -11,9 +11,8 @@ try: from sonic_eeprom import eeprom_tlvinfo - import binascii -except ImportError, e: - raise ImportError (str(e) + "- required module not found") +except ImportError as e: + raise ImportError(str(e) + "- required module not found") class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): @@ -30,7 +29,7 @@ def __init__(self, i2c_line=0, iom_eeprom=False): try: if self.is_module: - self.write_eeprom("\x00\x00") + self.write_eeprom(b"\x00\x00") self.eeprom_data = self.read_eeprom_bytes(256) else: self.eeprom_data = self.read_eeprom() @@ -48,7 +47,7 @@ def __init__(self, i2c_line=0, iom_eeprom=False): if not self.is_valid_tlvinfo_header(eeprom): return - total_length = (ord(eeprom[9]) << 8) | ord(eeprom[10]) + total_length = (eeprom[9] << 8) | eeprom[10] tlv_index = self._TLV_INFO_HDR_LEN tlv_end = self._TLV_INFO_HDR_LEN + total_length @@ -57,22 +56,26 @@ def __init__(self, i2c_line=0, iom_eeprom=False): break tlv = eeprom[tlv_index:tlv_index + 2 - + ord(eeprom[tlv_index + 1])] - code = "0x%02X" % (ord(tlv[0])) + + eeprom[tlv_index + 1]] + code = "0x%02X" % tlv[0] - if ord(tlv[0]) == self._TLV_CODE_VENDOR_EXT: - value = str((ord(tlv[2]) << 24) | (ord(tlv[3]) << 16) | - (ord(tlv[4]) << 8) | ord(tlv[5])) - value += str(tlv[6:6 + ord(tlv[1])]) + if tlv[0] == self._TLV_CODE_VENDOR_EXT: + value = str((tlv[2] << 24) | (tlv[3] << 16) | + (tlv[4] << 8) | tlv[5]) + value += tlv[6:6 + tlv[1]].decode('ascii') else: name, value = self.decoder(None, tlv) self.eeprom_tlv_dict[code] = value - if ord(eeprom[tlv_index]) == self._TLV_CODE_CRC_32: + if eeprom[tlv_index] == self._TLV_CODE_CRC_32: break - tlv_index += ord(eeprom[tlv_index+1]) + 2 + tlv_index += eeprom[tlv_index+1] + 2 + if self.is_module: + # In S6100, individual modules doesn't have MAC address + mac_code = "0x%02X" % self._TLV_CODE_MAC_BASE + self.eeprom_tlv_dict[mac_code] = '00:00:00:00:00:00' def serial_number_str(self): (is_valid, results) = self.get_tlv_field( @@ -80,7 +83,7 @@ def serial_number_str(self): if not is_valid: return "N/A" - return results[2] + return results[2].decode('ascii') def base_mac_addr(self): (is_valid, results) = self.get_tlv_field( @@ -88,7 +91,7 @@ def base_mac_addr(self): if not is_valid or results[1] != 6: return super(TlvInfoDecoder, self).switchaddrstr(e) - return ":".join([binascii.b2a_hex(T) for T in results[2]]) + return ":".join(["{:02x}".format(T) for T in results[2]]).upper() def modelstr(self): if self.is_module: @@ -100,7 +103,7 @@ def modelstr(self): if not is_valid: return "N/A" - return results[2] + return results[2].decode('ascii') def part_number_str(self): (is_valid, results) = self.get_tlv_field( @@ -108,7 +111,7 @@ def part_number_str(self): if not is_valid: return "N/A" - return results[2] + return results[2].decode('ascii') def serial_str(self): (is_valid, results) = self.get_tlv_field( @@ -116,7 +119,7 @@ def serial_str(self): if not is_valid: return "N/A" - return results[2] + return results[2].decode('ascii') def revision_str(self): (is_valid, results) = self.get_tlv_field( @@ -124,7 +127,7 @@ def revision_str(self): if not is_valid: return "N/A" - return results[2] + return results[2].decode('ascii') def system_eeprom_info(self): """ 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 49e95357b6f1..5b3c8977ac0a 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 @@ -26,30 +26,23 @@ class Fan(FanBase): HWMON_NODE = os.listdir(HWMON_DIR)[0] MAILBOX_DIR = HWMON_DIR + HWMON_NODE - def __init__(self, fantray_index=1, fan_index=1, psu_fan=False): + def __init__(self, fantray_index=1, psu_index=1, psu_fan=False, dependency=None): self.is_psu_fan = psu_fan if not self.is_psu_fan: - # API index is starting from 0, DellEMC platform index is starting - # from 1 - self.fantrayindex = fantray_index + 1 - self.fanindex = fan_index + 1 - self.fan_presence_reg = "fan{}_fault".format( - 2 * self.fantrayindex - 1) + self.fantrayindex = fantray_index + self.dependency = dependency 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( 2 * self.fantrayindex - 1) - self.fan_serialno_reg = "fan{}_serialno".format( - 2 * self.fantrayindex - 1) self.max_fan_speed = MAX_S6100_FAN_SPEED 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.psuindex = psu_index + self.fan_presence_reg = "fan{}_fault".format(self.psuindex + 10) + self.get_fan_speed_reg = "fan{}_input".format(self.psuindex + 10) + self.get_fan_dir_reg = "fan{}_airflow".format(self.psuindex + 10) self.max_fan_speed = MAX_S6100_PSU_FAN_SPEED def _get_pmc_register(self, reg_name): @@ -77,10 +70,9 @@ def get_name(self): string: The name of the device """ if not self.is_psu_fan: - return "FanTray{}-Fan{}".format( - self.fantrayindex, self.fanindex - 1) + return "FanTray{}-Fan1".format(self.fantrayindex) else: - return "PSU{} Fan".format(self.fanindex - 10) + return "PSU{} Fan".format(self.psuindex) def get_model(self): """ @@ -88,21 +80,7 @@ def get_model(self): Returns: string: Part number of FAN """ - # 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): - fan_partno = fan_serialno.split('-')[1] - else: - fan_partno = 'NA' - else: - fan_partno = 'NA' - - return fan_partno + return 'NA' def get_serial(self): """ @@ -110,15 +88,7 @@ def get_serial(self): Returns: 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' - - return fan_serialno + return 'NA' def get_presence(self): """ @@ -126,14 +96,17 @@ def get_presence(self): Returns: bool: True if fan is present, False if not """ - status = False - fantray_presence = self._get_pmc_register(self.fan_presence_reg) - if (fantray_presence != 'ERR'): - fantray_presence = int(fantray_presence, 10) - if (~fantray_presence & 0b1): - status = True + if not self.is_psu_fan: + return self.dependency.get_presence() - return status + presence = False + fan_presence = self._get_pmc_register(self.fan_presence_reg) + if (fan_presence != 'ERR'): + fan_presence = int(fan_presence, 10) + if (~fan_presence & 0b1): + presence = True + + return presence def get_status(self): """ @@ -157,6 +130,23 @@ def get_status(self): return status + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return 1 + + def is_replaceable(self): + """ + Indicate whether Fan is replaceable. + Returns: + bool: True if it is replaceable. + """ + return False + def get_direction(self): """ Retrieves the fan airflow direction @@ -186,7 +176,7 @@ def get_speed(self): fan_speed = self._get_pmc_register(self.get_fan_speed_reg) if (fan_speed != 'ERR') and self.get_presence(): speed_in_rpm = int(fan_speed, 10) - speed = (100 * speed_in_rpm)/self.max_fan_speed + speed = (100 * speed_in_rpm)//self.max_fan_speed else: speed = 0 @@ -216,7 +206,6 @@ def set_speed(self, speed): Returns: bool: True if set success, False if fail. """ - # Fan speeds are controlled by Smart-fussion FPGA. return False @@ -229,9 +218,9 @@ def set_status_led(self, color): Returns: bool: True if set success, False if fail. """ - # Leds are controlled by Smart-fussion FPGA. - status = False - return status + # No LED available for FanTray and PSU Fan + # Return True to avoid thermalctld alarm. + return True def get_status_led(self): """ @@ -240,17 +229,8 @@ 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 - else: - 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 + # No LED available for FanTray and PSU Fan + return None def get_target_speed(self): """ @@ -259,6 +239,6 @@ def get_target_speed(self): An integer, the percentage of full fan speed, in the range 0 (off) to 100 (full speed) """ - return 0 - - + # Fan speeds are controlled by Smart-fussion FPGA. + # Return current speed to avoid false thermalctld alarm. + return self.get_speed() diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan_drawer.py new file mode 100644 index 000000000000..41e870a63971 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan_drawer.py @@ -0,0 +1,161 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC S6100 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Fan-Drawers' information available in the platform. +# +######################################################################## + +try: + import os + + from sonic_platform_base.fan_drawer_base import FanDrawerBase + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class FanDrawer(FanDrawerBase): + """DellEMC Platform-specific Fan Drawer class""" + + HWMON_DIR = "/sys/devices/platform/SMF.512/hwmon/" + HWMON_NODE = os.listdir(HWMON_DIR)[0] + MAILBOX_DIR = HWMON_DIR + HWMON_NODE + + def __init__(self, fantray_index): + FanDrawerBase.__init__(self) + # FanTray is 1-based in DellEMC platforms + self.index = fantray_index + 1 + self.presence_reg = "fan{}_fault".format(2 * self.index - 1) + self.serialno_reg = "fan{}_serialno".format(2 * self.index - 1) + + self._fan_list.append(Fan(self.index, dependency=self)) + + def _get_pmc_register(self, reg_name): + # On successful read, returns the value read from given + # reg_name and on failure returns 'ERR' + rv = 'ERR' + mb_reg_file = self.MAILBOX_DIR+'/'+reg_name + + if (not os.path.isfile(mb_reg_file)): + return rv + try: + with open(mb_reg_file, 'r') as fd: + rv = fd.read() + except Exception as error: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + + def get_name(self): + """ + Retrieves the fan drawer name + Returns: + string: The name of the device + """ + return "FanTray{}".format(self.index) + + def get_model(self): + """ + Retrieves the part number of Fandrawer + Returns: + string: Part number of Fandrawer + """ + # For Serial number "US-01234D-54321-25A-0123-A00", the part + # number is "01234D" + fantray_serialno = self._get_pmc_register(self.serialno_reg) + if (fantray_serialno != 'ERR') and self.get_presence(): + if (len(fantray_serialno.split('-')) > 1): + fantray_partno = fantray_serialno.split('-')[1] + else: + fantray_partno = 'NA' + else: + fantray_partno = 'NA' + + return fantray_partno + + def get_serial(self): + """ + Retrieves the serial number of Fandrawer + Returns: + string: Serial number of Fandrawer + """ + # Sample Serial number format "US-01234D-54321-25A-0123-A00" + fantray_serialno = self._get_pmc_register(self.serialno_reg) + if (fantray_serialno == 'ERR') or not self.get_presence(): + fantray_serialno = 'NA' + + return fantray_serialno + + def get_presence(self): + """ + Retrieves the presence of the Fandrawer + Returns: + bool: True if fan is present, False if not + """ + presence = False + fantray_presence = self._get_pmc_register(self.presence_reg) + if (fantray_presence != 'ERR'): + fantray_presence = int(fantray_presence, 10) + if (~fantray_presence & 0b1): + presence = True + + return presence + + def get_status(self): + """ + Retrieves the operational status of the Fandrawer + + Returns: + bool: True if Fandrawer is operating properly, False if not + """ + return self.get_fan(0).get_status() + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether this Fandrawer is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True + + def set_status_led(self, color): + """ + Set led to expected color + Args: + color: A string representing the color with which to set the + fan module status LED + Returns: + bool: True if set success, False if fail. + """ + # Leds are controlled by Smart-fussion FPGA. + # Return True to avoid thermalctld alarm. + return True + + def get_status_led(self): + """ + Gets the state of the Fan status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings. + """ + if self.get_presence(): + if self.get_fan(0).get_status(): + return self.STATUS_LED_COLOR_GREEN + else: + return self.STATUS_LED_COLOR_AMBER + else: + return self.STATUS_LED_COLOR_OFF 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 19198098dfd7..923bb5c0550a 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 @@ -51,6 +51,7 @@ class Module(ModuleBase): } def __init__(self, module_index): + ModuleBase.__init__(self) # Modules are 1-based in DellEMC platforms self.index = module_index + 1 self.port_start = (self.index - 1) * 16 @@ -61,13 +62,8 @@ def __init__(self, module_index): self.iom_status_reg = "iom_status" self.iom_presence_reg = "iom_presence" - # Overriding _component_list and _sfp_list class variables defined in - # ModuleBase, to make them unique per Module object - self._component_list = [] - self._sfp_list = [] - component = Component(is_module=True, iom_index=self.index, - i2c_line=self.port_i2c_line) + i2c_line=self.port_i2c_line, dependency=self) self._component_list.append(component) eeprom_base = "/sys/class/i2c-adapter/i2c-{0}/i2c-{1}/{1}-0050/eeprom" @@ -161,6 +157,23 @@ def get_status(self): return status + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether Module is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True + def get_base_mac(self): """ Retrieves the base MAC address for the module @@ -172,15 +185,6 @@ def get_base_mac(self): # In S6100, individual modules doesn't have MAC address return '00:00:00:00:00:00' - def get_serial_number(self): - """ - Retrieves the hardware serial number for the module - - Returns: - A string containing the hardware serial number for this module. - """ - return self._eeprom.serial_number_str() - def get_system_eeprom_info(self): """ Retrieves the full content of system EEPROM information for the module diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/platform.py index 426db717281b..32230d9c92ce 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/platform.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/platform.py @@ -8,7 +8,6 @@ ############################################################################# try: - import os from sonic_platform_base.platform_base import PlatformBase from sonic_platform.chassis import Chassis except ImportError as e: diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/psu.py index 18a8b5d0354d..4e528b679e4a 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/psu.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/psu.py @@ -25,6 +25,7 @@ class Psu(PsuBase): MAILBOX_DIR = HWMON_DIR + HWMON_NODE def __init__(self, psu_index): + PsuBase.__init__(self) # PSU is 1-based in DellEMC platforms self.index = psu_index + 1 self.psu_presence_reg = "psu{}_presence".format(self.index) @@ -33,17 +34,15 @@ def __init__(self, psu_index): self.psu_voltage_reg = "in30_input" self.psu_current_reg = "curr602_input" self.psu_power_reg = "power2_input" + self.psu_temperature_reg = "temp14_input" elif self.index == 2: self.psu_voltage_reg = "in32_input" self.psu_current_reg = "curr702_input" self.psu_power_reg = "power4_input" - - # Overriding _fan_list class variable defined in PsuBase, to - # make it unique per Psu object - self._fan_list = [] + self.psu_temperature_reg = "temp15_input" # Passing True to specify it is a PSU fan - psu_fan = Fan(fan_index=self.index, psu_fan=True) + psu_fan = Fan(psu_index=self.index, psu_fan=True) self._fan_list.append(psu_fan) def _get_pmc_register(self, reg_name): @@ -235,3 +234,87 @@ def set_status_led(self, color): # In S6100, SmartFusion FPGA controls the PSU LED and the PSU # LED state cannot be changed from CPU. return False + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether this PSU is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True + + def get_temperature(self): + """ + Retrieves current temperature reading from PSU + + Returns: + A float number of current temperature in Celsius up to + nearest thousandth of one degree Celsius, e.g. 30.125 + """ + temperature = 0.0 + if self.get_presence(): + psu_temperature = self._get_pmc_register(self.psu_temperature_reg) + if (psu_temperature != 'ERR'): + temperature = float(psu_temperature) / 1000 + + return temperature + + def get_temperature_high_threshold(self): + """ + Retrieves the high threshold temperature of PSU + + Returns: + A float number, the high threshold temperature of PSU in + Celsius up to nearest thousandth of one degree Celsius, + e.g. 30.125 + """ + return 90.0 + + def get_voltage_high_threshold(self): + """ + Retrieves the high threshold PSU voltage output + + Returns: + A float number, the high threshold output voltage in volts, + e.g. 12.1 + """ + voltage_high_threshold = 0.0 + if self.get_presence(): + psu_type = self._get_pmc_register(self.psu_presence_reg) + if (psu_type != 'ERR'): + psu_type = int(psu_type, 16) + if (psu_type & 0b10): + voltage_high_threshold = 12.6 + else: + voltage_high_threshold = 12.8 + + return voltage_high_threshold + + def get_voltage_low_threshold(self): + """ + Retrieves the low threshold PSU voltage output + + Returns: + A float number, the low threshold output voltage in volts, + e.g. 12.1 + """ + voltage_low_threshold = 0.0 + if self.get_presence(): + psu_type = self._get_pmc_register(self.psu_presence_reg) + if (psu_type != 'ERR'): + psu_type = int(psu_type, 16) + if (psu_type & 0b10): + voltage_low_threshold = 11.4 + else: + voltage_low_threshold = 11.6 + + return voltage_low_threshold diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/sfp.py index e94c53b11a95..0b242ab74d71 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/sfp.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/sfp.py @@ -9,9 +9,9 @@ ############################################################################# try: - import os + import re + import struct import time - from sonic_platform_base.chassis_base import ChassisBase from sonic_platform_base.sfp_base import SfpBase from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom @@ -28,6 +28,9 @@ DOM_OFFSET = 0 DOM_OFFSET1 = 384 +QSFP_CONTROL_OFFSET = 86 +QSFP_POWEROVERRIDE_OFFSET = 93 + cable_length_tup = ('Length(km)', 'Length OM3(2m)', 'Length OM2(m)', 'Length OM1(m)', 'Length Cable Assembly(m)') @@ -40,11 +43,12 @@ 'Fibre Channel transmission media', 'Fibre Channel Speed') -info_dict_keys = ['type', 'hardwarerev', 'serialnum', - 'manufacturename', 'modelname', 'Connector', +info_dict_keys = ['type', 'hardware_rev', 'serial', + 'manufacturer', 'model', 'connector', 'encoding', 'ext_identifier', 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', - 'specification_compliance', 'vendor_date', 'vendor_oui'] + 'specification_compliance', 'vendor_date', 'vendor_oui', + 'application_advertisement'] dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', @@ -78,7 +82,7 @@ 'cable_type': [INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], 'cable_length': [INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], - 'Connector': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'connector': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'type': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'encoding': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'ext_identifier': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], @@ -87,11 +91,11 @@ 'nominal_bit_rate': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'specification_compliance': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], - 'manufacturename': [INFO_OFFSET, 20, 16, 'parse_vendor_name'], + 'manufacturer': [INFO_OFFSET, 20, 16, 'parse_vendor_name'], 'vendor_oui': [INFO_OFFSET, 37, 3, 'parse_vendor_oui'], - 'modelname': [INFO_OFFSET, 40, 16, 'parse_vendor_pn'], - 'hardwarerev': [INFO_OFFSET, 56, 2, 'parse_vendor_rev'], - 'serialnum': [INFO_OFFSET, 68, 16, 'parse_vendor_sn'], + 'model': [INFO_OFFSET, 40, 16, 'parse_vendor_pn'], + 'hardware_rev': [INFO_OFFSET, 56, 2, 'parse_vendor_rev'], + 'serial': [INFO_OFFSET, 68, 16, 'parse_vendor_sn'], 'vendor_date': [INFO_OFFSET, 84, 8, 'parse_vendor_date'], 'ModuleThreshold': [DOM_OFFSET1, 128, 24, 'parse_module_threshold_values'], 'ChannelThreshold': [DOM_OFFSET1, 176, 16, 'parse_channel_threshold_values'], @@ -107,7 +111,7 @@ def __init__(self, index, sfp_type, eeprom_path, sfp_control, sfp_ctrl_idx): SfpBase.__init__(self) self.sfp_type = sfp_type - self.index = index + self.index = index + 1 self.eeprom_path = eeprom_path self.sfp_control = sfp_control self.sfp_ctrl_idx = sfp_ctrl_idx @@ -131,9 +135,10 @@ def _read_eeprom_bytes(self, eeprom_path, offset, num_bytes): eeprom.close() return None + raw = bytearray(raw) try: for n in range(0, num_bytes): - eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + eeprom_raw[n] = hex(raw[n])[2:].zfill(2) except BaseException: eeprom.close() return None @@ -168,6 +173,15 @@ def _get_eeprom_data(self, eeprom_key): return eeprom_data + def _strip_unit_from_str(self, value_str): + match = re.match(r'(.*)C$|(.*)Volts$|(.*)mA$|(.*)dBm$', value_str) + if match: + for value in match.groups(): + if value is not None: + return float(value) + + return None + def get_transceiver_info(self): """ Retrieves transceiver info of this SFP @@ -205,7 +219,7 @@ def get_transceiver_info(self): return transceiver_info_dict # Vendor Name - vendor_name_data = self._get_eeprom_data('manufacturename') + vendor_name_data = self._get_eeprom_data('manufacturer') if (vendor_name_data is not None): vendor_name = vendor_name_data['data']['Vendor Name']['value'] else: @@ -219,21 +233,21 @@ def get_transceiver_info(self): return transceiver_info_dict # Vendor PN - vendor_pn_data = self._get_eeprom_data('modelname') + vendor_pn_data = self._get_eeprom_data('model') if (vendor_pn_data is not None): vendor_pn = vendor_pn_data['data']['Vendor PN']['value'] else: return transceiver_info_dict # Vendor Revision - vendor_rev_data = self._get_eeprom_data('hardwarerev') + vendor_rev_data = self._get_eeprom_data('hardware_rev') if (vendor_rev_data is not None): vendor_rev = vendor_rev_data['data']['Vendor Rev']['value'] else: return transceiver_info_dict # Vendor Serial Number - vendor_sn_data = self._get_eeprom_data('serialnum') + vendor_sn_data = self._get_eeprom_data('serial') if (vendor_sn_data is not None): vendor_sn = vendor_sn_data['data']['Vendor SN']['value'] else: @@ -241,11 +255,11 @@ def get_transceiver_info(self): # Fill The Dictionary and return transceiver_info_dict['type'] = identifier - transceiver_info_dict['hardwarerev'] = vendor_rev - transceiver_info_dict['serialnum'] = vendor_sn - transceiver_info_dict['manufacturename'] = vendor_name - transceiver_info_dict['modelname'] = vendor_pn - transceiver_info_dict['Connector'] = connector + transceiver_info_dict['hardware_rev'] = vendor_rev + transceiver_info_dict['serial'] = vendor_sn + transceiver_info_dict['manufacturer'] = vendor_name + transceiver_info_dict['model'] = vendor_pn + transceiver_info_dict['connector'] = connector transceiver_info_dict['encoding'] = encoding transceiver_info_dict['ext_identifier'] = ext_id transceiver_info_dict['ext_rateselect_compliance'] = rate_identifier @@ -436,7 +450,7 @@ def get_model(self): """ Retrieves the model number (or part number) of the sfp """ - vendor_pn_data = self._get_eeprom_data('modelname') + vendor_pn_data = self._get_eeprom_data('model') if (vendor_pn_data is not None): vendor_pn = vendor_pn_data['data']['Vendor PN']['value'] else: @@ -448,7 +462,7 @@ def get_serial(self): """ Retrieves the serial number of the sfp """ - vendor_sn_data = self._get_eeprom_data('serialnum') + vendor_sn_data = self._get_eeprom_data('serial') if (vendor_sn_data is not None): vendor_sn = vendor_sn_data['data']['Vendor SN']['value'] else: @@ -492,154 +506,107 @@ def get_rx_los(self): """ Retrieves the RX LOS (lost-of-signal) status of SFP """ - rx_los = None rx_los_list = [] rx_los_data = self._get_eeprom_data('rx_los') if (rx_los_data is not None): rx_los = rx_los_data['data']['Rx1LOS']['value'] - if (rx_los is 'On'): + if (rx_los == 'On'): rx_los_list.append(True) else: rx_los_list.append(False) rx_los = rx_los_data['data']['Rx2LOS']['value'] - if (rx_los is 'On'): + if (rx_los == 'On'): rx_los_list.append(True) else: rx_los_list.append(False) rx_los = rx_los_data['data']['Rx3LOS']['value'] - if (rx_los is 'On'): + if (rx_los == 'On'): rx_los_list.append(True) else: rx_los_list.append(False) rx_los = rx_los_data['data']['Rx4LOS']['value'] - if (rx_los is 'On'): + if (rx_los == 'On'): rx_los_list.append(True) else: rx_los_list.append(False) - if (rx_los_list[0] and rx_los_list[1] - and rx_los_list[2] and rx_los_list[3]): - rx_los = True - else: - rx_los = False - - return rx_los + return rx_los_list def get_tx_fault(self): """ Retrieves the TX fault status of SFP """ - tx_fault = None tx_fault_list = [] tx_fault_data = self._get_eeprom_data('tx_fault') if (tx_fault_data is not None): tx_fault = tx_fault_data['data']['Tx1Fault']['value'] - if (tx_fault is 'On'): + if (tx_fault == 'On'): tx_fault_list.append(True) else: tx_fault_list.append(False) tx_fault = tx_fault_data['data']['Tx2Fault']['value'] - if (tx_fault is 'On'): + if (tx_fault == 'On'): tx_fault_list.append(True) else: tx_fault_list.append(False) tx_fault = tx_fault_data['data']['Tx3Fault']['value'] - if (tx_fault is 'On'): + if (tx_fault == 'On'): tx_fault_list.append(True) else: tx_fault_list.append(False) tx_fault = tx_fault_data['data']['Tx4Fault']['value'] - if (tx_fault is 'On'): + if (tx_fault == 'On'): tx_fault_list.append(True) else: tx_fault_list.append(False) - if (tx_fault_list[0] and tx_fault_list[1] - and tx_fault_list[2] and tx_fault_list[3]): - tx_fault = True - else: - tx_fault = False - - return tx_fault + return tx_fault_list def get_tx_disable(self): """ Retrieves the tx_disable status of this SFP """ - tx_disable = None tx_disable_list = [] tx_disable_data = self._get_eeprom_data('tx_disable') if (tx_disable_data is not None): tx_disable = tx_disable_data['data']['Tx1Disable']['value'] - if (tx_disable is 'On'): + if (tx_disable == 'On'): tx_disable_list.append(True) else: tx_disable_list.append(False) tx_disable = tx_disable_data['data']['Tx2Disable']['value'] - if (tx_disable is 'On'): + if (tx_disable == 'On'): tx_disable_list.append(True) else: tx_disable_list.append(False) tx_disable = tx_disable_data['data']['Tx3Disable']['value'] - if (tx_disable is 'On'): + if (tx_disable == 'On'): tx_disable_list.append(True) else: tx_disable_list.append(False) tx_disable = tx_disable_data['data']['Tx4Disable']['value'] - if (tx_disable is 'On'): + if (tx_disable == 'On'): tx_disable_list.append(True) else: tx_disable_list.append(False) - if (tx_disable_list[0] and tx_disable_list[1] - and tx_disable_list[2] and tx_disable_list[3]): - tx_disable = True - else: - tx_disable = False - - return tx_disable + return tx_disable_list def get_tx_disable_channel(self): """ Retrieves the TX disabled channels in this SFP """ - tx_disable = None - tx_disable_list = [] + tx_disable_channel = 0 - tx_disable_data = self._get_eeprom_data('tx_disable') - if (tx_disable_data is not None): - tx_disable = tx_disable_data['data']['Tx1Disable']['value'] - if (tx_disable is 'On'): - tx_disable_list.append(1) - else: - tx_disable_list.append(0) - tx_disable = tx_disable_data['data']['Tx2Disable']['value'] - if (tx_disable is 'On'): - tx_disable_list.append(1) - else: - tx_disable_list.append(0) - tx_disable = tx_disable_data['data']['Tx3Disable']['value'] - if (tx_disable is 'On'): - tx_disable_list.append(1) - else: - tx_disable_list.append(0) - tx_disable = tx_disable_data['data']['Tx4Disable']['value'] - if (tx_disable is 'On'): - tx_disable_list.append(1) - else: - tx_disable_list.append(0) - - bit4 = int(tx_disable_list[3]) * 8 - bit3 = int(tx_disable_list[2]) * 4 - bit2 = int(tx_disable_list[1]) * 2 - bit1 = int(tx_disable_list[0]) * 1 - - tx_disable_channel = hex(bit4 + bit3 + bit2 + bit1) + tx_disable = self.get_tx_disable() + for channel, disable in enumerate(tx_disable): + if disable: + tx_disable_channel |= 1 << channel - return tx_disable_channel + return tx_disable_channel def get_lpmode(self): """ @@ -682,7 +649,7 @@ def get_power_override(self): power_override_data = self._get_eeprom_data('power_override') if (power_override_data is not None): power_override = power_override_data['data']['PowerOverRide']['value'] - if (power_override is 'On'): + if (power_override == 'On'): power_override_state = True else: power_override_state = False @@ -697,7 +664,7 @@ def get_temperature(self): temperature_data = self._get_eeprom_data('Temperature') if (temperature_data is not None): - temperature = temperature_data['data']['Temperature']['value'] + temperature = self._strip_unit_from_str(temperature_data['data']['Temperature']['value']) return temperature @@ -709,7 +676,7 @@ def get_voltage(self): voltage_data = self._get_eeprom_data('Voltage') if (voltage_data is not None): - voltage = voltage_data['data']['Vcc']['value'] + voltage = self._strip_unit_from_str(voltage_data['data']['Vcc']['value']) return voltage @@ -717,19 +684,14 @@ def get_tx_bias(self): """ Retrieves the TX bias current of this SFP """ - tx_bias = None tx_bias_list = [] tx_bias_data = self._get_eeprom_data('ChannelMonitor') if (tx_bias_data is not None): - tx_bias = tx_bias_data['data']['TX1Bias']['value'] - tx_bias_list.append(tx_bias) - tx_bias = tx_bias_data['data']['TX2Bias']['value'] - tx_bias_list.append(tx_bias) - tx_bias = tx_bias_data['data']['TX3Bias']['value'] - tx_bias_list.append(tx_bias) - tx_bias = tx_bias_data['data']['TX4Bias']['value'] - tx_bias_list.append(tx_bias) + tx_bias_list.append(self._strip_unit_from_str(tx_bias_data['data']['TX1Bias']['value'])) + tx_bias_list.append(self._strip_unit_from_str(tx_bias_data['data']['TX2Bias']['value'])) + tx_bias_list.append(self._strip_unit_from_str(tx_bias_data['data']['TX3Bias']['value'])) + tx_bias_list.append(self._strip_unit_from_str(tx_bias_data['data']['TX4Bias']['value'])) return tx_bias_list @@ -737,34 +699,27 @@ def get_rx_power(self): """ Retrieves the received optical power for this SFP """ - rx_power = None rx_power_list = [] rx_power_data = self._get_eeprom_data('ChannelMonitor') if (rx_power_data is not None): - rx_power = rx_power_data['data']['RX1Power']['value'] - rx_power_list.append(rx_power) - rx_power = rx_power_data['data']['RX2Power']['value'] - rx_power_list.append(rx_power) - rx_power = rx_power_data['data']['RX3Power']['value'] - rx_power_list.append(rx_power) - rx_power = rx_power_data['data']['RX4Power']['value'] - rx_power_list.append(rx_power) + rx_power_list.append(self._strip_unit_from_str(rx_power_data['data']['RX1Power']['value'])) + rx_power_list.append(self._strip_unit_from_str(rx_power_data['data']['RX2Power']['value'])) + rx_power_list.append(self._strip_unit_from_str(rx_power_data['data']['RX3Power']['value'])) + rx_power_list.append(self._strip_unit_from_str(rx_power_data['data']['RX4Power']['value'])) return rx_power_list - def get_tx_power(self): """ Retrieves the TX power of this SFP """ - tx_power = None tx_power_list = [] - tx_power_list.append('-infdBm') - tx_power_list.append('-infdBm') - tx_power_list.append('-infdBm') - tx_power_list.append('-infdBm') + tx_power_list.append(float('-inf')) + tx_power_list.append(float('-inf')) + tx_power_list.append(float('-inf')) + tx_power_list.append(float('-inf')) return tx_power_list @@ -860,25 +815,68 @@ def tx_disable(self, tx_disable): """ Disable SFP TX for all channels """ - return False + eeprom = None + tx_disable_value = 0xf if tx_disable else 0x0 - def tx_disable_channel(self, channel, disable): - """ - Sets the tx_disable for specified SFP channels - """ - return False + try: + eeprom = open(self.eeprom_path, "r+b") + eeprom.seek(QSFP_CONTROL_OFFSET) + eeprom.write(struct.pack('B', tx_disable_value)) + except IOError: + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) + + return True def tx_disable_channel(self, channel, disable): """ Sets the tx_disable for specified SFP channels """ - return False + eeprom = None + current_state = self.get_tx_disable_channel() + + if disable: + tx_disable_value = current_state | channel + else: + tx_disable_value = current_state & (~channel) + + try: + eeprom = open(self.eeprom_path, "r+b") + eeprom.seek(QSFP_CONTROL_OFFSET) + eeprom.write(struct.pack('B', tx_disable_value)) + except IOError: + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) + + return True def set_power_override(self, power_override, power_set): """ Sets SFP power level using power_override and power_set """ - return False + eeprom = None + power_override_bit = 0x1 if power_override else 0 + power_set_bit = 0x2 if power_set else 0 + value = power_override_bit | power_set_bit + + try: + eeprom = open(self.eeprom_path, "r+b") + eeprom.seek(QSFP_POWEROVERRIDE_OFFSET) + eeprom.write(struct.pack('B', value)) + except IOError: + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) + + return True def get_status(self): """ @@ -886,9 +884,26 @@ def get_status(self): """ reset = self.get_reset_status() - if (reset == True): + if reset: status = False else: status = True return status + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/thermal.py index 3947f4c84957..cac17f4b83aa 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/thermal.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/thermal.py @@ -49,10 +49,14 @@ def __init__(self, thermal_index): self.thermal_temperature_file = self.HWMON_DIR \ + "temp{}_input".format(hwmon_temp_index) self.thermal_high_threshold_file = self.HWMON_DIR \ - + "temp{}_crit".format(hwmon_temp_index) + + "temp{}_max".format(hwmon_temp_index) self.thermal_low_threshold_file = self.HWMON_DIR \ + "temp{}_min".format(hwmon_temp_index) + if not self.is_cpu_thermal: + self.thermal_high_crit_threshold_file = self.HWMON_DIR \ + + "temp{}_crit".format(hwmon_temp_index) + def _read_sysfs_file(self, sysfs_file): # On successful read, returns the value read from given # sysfs_file and on failure returns 'ERR' @@ -127,6 +131,23 @@ def get_status(self): return status + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether this Thermal is replaceable. + Returns: + bool: True if it is replaceable. + """ + return False + def get_temperature(self): """ Retrieves current temperature reading from thermal @@ -138,11 +159,11 @@ def get_temperature(self): thermal_temperature = self._read_sysfs_file( self.thermal_temperature_file) if (thermal_temperature != 'ERR'): - thermal_temperature = float(thermal_temperature) / 1000 + thermal_temperature = float(thermal_temperature) else: thermal_temperature = 0 - return "{:.3f}".format(thermal_temperature) + return thermal_temperature / 1000.0 def get_high_threshold(self): """ @@ -156,11 +177,11 @@ def get_high_threshold(self): thermal_high_threshold = self._read_sysfs_file( self.thermal_high_threshold_file) if (thermal_high_threshold != 'ERR'): - thermal_high_threshold = float(thermal_high_threshold) / 1000 + thermal_high_threshold = float(thermal_high_threshold) else: thermal_high_threshold = 0 - return "{:.3f}".format(thermal_high_threshold) + return thermal_high_threshold / 1000.0 def get_low_threshold(self): """ @@ -174,11 +195,32 @@ def get_low_threshold(self): thermal_low_threshold = self._read_sysfs_file( self.thermal_low_threshold_file) if (thermal_low_threshold != 'ERR'): - thermal_low_threshold = float(thermal_low_threshold) / 1000 + thermal_low_threshold = float(thermal_low_threshold) else: thermal_low_threshold = 0 - return "{:.3f}".format(thermal_low_threshold) + return thermal_low_threshold / 1000.0 + + def get_high_critical_threshold(self): + """ + Retrieves the high critical threshold temperature of thermal + + Returns: + A float number, the high critical threshold temperature of + thermal in Celsius up to nearest thousandth of one degree + Celsius, e.g. 30.125 + """ + if self.is_cpu_thermal: + return super(Thermal, self).get_high_critical_threshold() + + thermal_high_crit_threshold = self._read_sysfs_file( + self.thermal_high_crit_threshold_file) + if (thermal_high_crit_threshold != 'ERR'): + thermal_high_crit_threshold = float(thermal_high_crit_threshold) + else: + thermal_high_crit_threshold = 0 + + return thermal_high_crit_threshold / 1000.0 def set_high_threshold(self, temperature): """ diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/watchdog.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/watchdog.py index 207ccb8971bc..0e5e102b7b52 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/watchdog.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/watchdog.py @@ -131,7 +131,7 @@ def arm(self, seconds): """ gpio = "/sys/devices/platform/dell_ich.0/sc_gp_lvl" timer_offset = -1 - if seconds <= 30: + if seconds > 0 and seconds <= 30: timer_offset = 1 seconds = 30 elif seconds > 30 and seconds <= 60: @@ -151,9 +151,9 @@ def arm(self, seconds): if self.is_armed(): gpio_val = self._read_gpio_file(gpio) high_val = gpio_val | (1 << 15) - if self._write_gpio_file(gpio, hex(high_val)) != -1: + if self._write_gpio_file(gpio, hex(high_val).encode('utf-8')) != -1: low_val = high_val & 0xFFFF7FFF - if self._write_gpio_file(gpio, hex(low_val)) != -1: + if self._write_gpio_file(gpio, hex(low_val).encode('utf-8')) != -1: self.armed_time = self._get_time() self.timeout = seconds return seconds diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/systemd/platform-modules-s6100.service b/platform/broadcom/sonic-platform-modules-dell/s6100/systemd/platform-modules-s6100.service index 9b5805d5cbbb..4883ecf268fd 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/systemd/platform-modules-s6100.service +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/systemd/platform-modules-s6100.service @@ -1,6 +1,6 @@ [Unit] Description=Dell S6100 Platform modules -Before=pmon.service +Before=pmon.service determine-reboot-cause.service DefaultDependencies=no [Service] diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/systemd/s6100-i2c-enumerate.service b/platform/broadcom/sonic-platform-modules-dell/s6100/systemd/s6100-i2c-enumerate.service new file mode 100644 index 000000000000..c63482831940 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/systemd/s6100-i2c-enumerate.service @@ -0,0 +1,12 @@ +[Unit] +Description=Dell S6100 I2C MUX Enumeration +Before=pmon.service +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/s6100_i2c_enumeration.sh init +RemainAfterExit=no + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/platform_reboot_override b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/platform_reboot_override index 3e165630658b..0cc43644954d 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/platform_reboot_override +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/platform_reboot_override @@ -1,5 +1,4 @@ -#!/usr/bin/python -import sys +#!/usr/bin/python3 import os import struct @@ -9,17 +8,16 @@ PORT_RES = '/dev/port' def portio_reg_write(resource, offset, val): fd = os.open(resource, os.O_RDWR) if(fd < 0): - print 'file open failed %s" % resource' + print('file open failed %s" % resource') return if(os.lseek(fd, offset, os.SEEK_SET) != offset): - print 'lseek failed on %s' % resource + print('lseek failed on %s' % resource) return ret = os.write(fd, struct.pack('B', val)) if(ret != 1): - print 'write failed %d' % ret + print('write failed %d' % ret) return os.close(fd) if __name__ == "__main__": portio_reg_write(PORT_RES, 0xcf9, 0xe) - 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 05cbb3a1a4c1..0caa533c3fa6 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 @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # # On Z9100, the Platform Management Controller runs the # thermal algorithm. It provides a mailbox for the Host @@ -28,7 +28,7 @@ def get_pmc_register(reg_name): mb_reg_file = MAILBOX_DIR+'/'+reg_name if (not os.path.isfile(mb_reg_file)): - print mb_reg_file, 'not found !' + print(mb_reg_file, 'not found !') return retval try: @@ -44,8 +44,8 @@ def get_pmc_register(reg_name): logging.basicConfig(level=logging.DEBUG) if (os.path.isdir(MAILBOX_DIR)): - print 'dell-z9100-lpc' - print 'Adapter: Z9100 Platform Management Controller' + print('dell-z9100-lpc') + print('Adapter: Z9100 Platform Management Controller') else: logging.error('Z9100 Platform Management Controller module not loaded !') # sys.exit(0) @@ -55,18 +55,18 @@ def get_pmc_register(reg_name): def print_temperature_sensors(): print("\nOnboard Temperature Sensors:") - print ' CPU: ',\ - int(get_pmc_register('temp1_input'))/1000, 'C' - print ' BCM56960 (PSU side): ',\ - int(get_pmc_register('temp2_input'))/1000, 'C' - print ' System Outlet 1 (switch board): ',\ - int(get_pmc_register('temp3_input'))/1000, 'C' - print ' BCM56960 (IO side): ',\ - int(get_pmc_register('temp4_input'))/1000, 'C' - print ' System Outlet 2 (CPU board): ',\ - int(get_pmc_register('temp9_input'))/1000, 'C' - print ' System Inlet Left (IO side): ',\ - int(get_pmc_register('temp6_input'))/1000, 'C' + print(' CPU: ', + int(get_pmc_register('temp1_input'))/1000, 'C') + print(' BCM56960 (PSU side): ', + int(get_pmc_register('temp2_input'))/1000, 'C') + print(' System Outlet 1 (switch board): ', + int(get_pmc_register('temp3_input'))/1000, 'C') + print(' BCM56960 (IO side): ', + int(get_pmc_register('temp4_input'))/1000, 'C') + print(' System Outlet 2 (CPU board): ', + int(get_pmc_register('temp9_input'))/1000, 'C') + print(' System Inlet Left (IO side): ', + int(get_pmc_register('temp6_input'))/1000, 'C') print_temperature_sensors() @@ -77,63 +77,62 @@ def print_temperature_sensors(): def print_voltage_sensors(): print("\nOnboard Voltage Sensors:") - print ' CPU XP3R3V_EARLY ',\ - float(get_pmc_register('in1_input'))/1000, 'V' - print '\n CPU XP5R0V_CP ',\ - float(get_pmc_register('in2_input'))/1000, 'V' - print ' CPU XP3R3V_STD ',\ - float(get_pmc_register('in3_input'))/1000, 'V' - print ' CPU XP3R3V_CP ',\ - float(get_pmc_register('in4_input'))/1000, 'V' - print ' CPU XP0R75V_VTT_A ',\ - float(get_pmc_register('in5_input'))/1000, 'V' - print ' CPU XPPR75V_VTT_B ',\ - float(get_pmc_register('in6_input'))/1000, 'V' - print ' CPU XP1R07V_CPU ',\ - float(get_pmc_register('in7_input'))/1000, 'V' - print ' CPU XP1R0V_CPU ',\ - float(get_pmc_register('in8_input'))/1000, 'V' - print ' CPU XP12R0V ',\ - float(get_pmc_register('in9_input'))/1000, 'V' - print ' CPU VDDR_CPU_2 ',\ - float(get_pmc_register('in10_input'))/1000, 'V' - print ' CPU VDDR_CPU_1 ',\ - float(get_pmc_register('in11_input'))/1000, 'V' - print ' CPU XP1R5V_CLK ',\ - float(get_pmc_register('in12_input'))/1000, 'V' - print ' CPU XP1R8V_CPU ',\ - float(get_pmc_register('in13_input'))/1000, 'V' - print ' CPU XP1R0V_CPU_VNN ',\ - float(get_pmc_register('in14_input'))/1000, 'V' - print ' CPU XP1R0V_CPU_VCC ',\ - float(get_pmc_register('in15_input'))/1000, 'V' - print ' CPU XP1R5V_EARLY ',\ - float(get_pmc_register('in16_input'))/1000, 'V' - print ' SW XP3R3V_MON ',\ - float(get_pmc_register('in17_input'))/1000, 'V' - print ' SW XP1R8V_MON ',\ - float(get_pmc_register('in19_input'))/1000, 'V' - print ' SW XP1R2V_MON ',\ - float(get_pmc_register('in20_input'))/1000, 'V' - print ' SW XP1R0V_SW_MON ',\ - float(get_pmc_register('in21_input'))/1000, 'V' - print ' SW XP1R0V_ROV_SW_MON ',\ - float(get_pmc_register('in22_input'))/1000, 'V' - print ' SW XR1R0V_BCM84752_MON ',\ - float(get_pmc_register('in23_input'))/1000, 'V' - print ' SW XP5V_MB_MON ',\ - float(get_pmc_register('in24_input'))/1000, 'V' - print ' SW XP1R8V_FPGA_MON ',\ - float(get_pmc_register('in25_input'))/1000, 'V' - print ' SW XP3R3V_FPGA_MON ',\ - float(get_pmc_register('in26_input'))/1000, 'V' - print ' SW XP3R3V_EARLY_MON ',\ - float(get_pmc_register('in27_input'))/1000, 'V' - print ' SW XP1R0V_ ',\ - float(get_pmc_register('curr21_input'))/10000, 'A' - print ' SW XP1R0V_ROV ',\ - float(get_pmc_register('curr22_input'))/10000, 'A' - + print(' CPU XP3R3V_EARLY ', + float(get_pmc_register('in1_input'))/1000, 'V') + print('\n CPU XP5R0V_CP ', + float(get_pmc_register('in2_input'))/1000, 'V') + print(' CPU XP3R3V_STD ', + float(get_pmc_register('in3_input'))/1000, 'V') + print(' CPU XP3R3V_CP ', + float(get_pmc_register('in4_input'))/1000, 'V') + print(' CPU XP0R75V_VTT_A ', + float(get_pmc_register('in5_input'))/1000, 'V') + print(' CPU XPPR75V_VTT_B ', + float(get_pmc_register('in6_input'))/1000, 'V') + print(' CPU XP1R07V_CPU ', + float(get_pmc_register('in7_input'))/1000, 'V') + print(' CPU XP1R0V_CPU ', + float(get_pmc_register('in8_input'))/1000, 'V') + print(' CPU XP12R0V ', + float(get_pmc_register('in9_input'))/1000, 'V') + print(' CPU VDDR_CPU_2 ', + float(get_pmc_register('in10_input'))/1000, 'V') + print(' CPU VDDR_CPU_1 ', + float(get_pmc_register('in11_input'))/1000, 'V') + print(' CPU XP1R5V_CLK ', + float(get_pmc_register('in12_input'))/1000, 'V') + print(' CPU XP1R8V_CPU ', + float(get_pmc_register('in13_input'))/1000, 'V') + print(' CPU XP1R0V_CPU_VNN ', + float(get_pmc_register('in14_input'))/1000, 'V') + print(' CPU XP1R0V_CPU_VCC ', + float(get_pmc_register('in15_input'))/1000, 'V') + print(' CPU XP1R5V_EARLY ', + float(get_pmc_register('in16_input'))/1000, 'V') + print(' SW XP3R3V_MON ', + float(get_pmc_register('in17_input'))/1000, 'V') + print(' SW XP1R8V_MON ', + float(get_pmc_register('in19_input'))/1000, 'V') + print(' SW XP1R2V_MON ', + float(get_pmc_register('in20_input'))/1000, 'V') + print(' SW XP1R0V_SW_MON ', + float(get_pmc_register('in21_input'))/1000, 'V') + print(' SW XP1R0V_ROV_SW_MON ', + float(get_pmc_register('in22_input'))/1000, 'V') + print(' SW XR1R0V_BCM84752_MON ', + float(get_pmc_register('in23_input'))/1000, 'V') + print(' SW XP5V_MB_MON ', + float(get_pmc_register('in24_input'))/1000, 'V') + print(' SW XP1R8V_FPGA_MON ', + float(get_pmc_register('in25_input'))/1000, 'V') + print(' SW XP3R3V_FPGA_MON ', + float(get_pmc_register('in26_input'))/1000, 'V') + print(' SW XP3R3V_EARLY_MON ', + float(get_pmc_register('in27_input'))/1000, 'V') + print(' SW XP1R0V_ ', + float(get_pmc_register('curr21_input'))/10000, 'A') + print(' SW XP1R0V_ROV ', + float(get_pmc_register('curr22_input'))/10000, 'A') print_voltage_sensors() @@ -146,68 +145,68 @@ def print_fan_tray(tray): Fan_Status = ['Normal', 'Abnormal'] Airflow_Direction = ['B2F', 'F2B'] - print ' Fan Tray ' + str(tray) + ':' + print(' Fan Tray ' + str(tray) + ':') if (tray == 1): - fan1_speed = get_pmc_register('fan1_input') - fan2_speed = get_pmc_register('fan2_input') - air_flow_reg = int(get_pmc_register('fan1_airflow'), 16) + fan1_speed = int(get_pmc_register('fan1_input')) + fan2_speed = int(get_pmc_register('fan2_input')) + air_flow_reg = int(get_pmc_register('fan1_airflow'), 16) fan1_status = 0 if fan1_speed >= 1000 else 1 fan2_status = 0 if fan2_speed >= 1000 else 1 - print ' Fan1 Speed: ', fan1_speed, 'RPM' - print ' Fan2 Speed: ', fan2_speed, 'RPM' - print ' Fan1 State: ', Fan_Status[fan1_status] - print ' Fan2 State: ', Fan_Status[fan2_status] - print ' Air Flow: ', Airflow_Direction[air_flow_reg] + print(' Fan1 Speed: ', fan1_speed, 'RPM') + print(' Fan2 Speed: ', fan2_speed, 'RPM') + print(' Fan1 State: ', Fan_Status[fan1_status]) + print(' Fan2 State: ', Fan_Status[fan2_status]) + print(' Air Flow: ', Airflow_Direction[air_flow_reg]) elif (tray == 2): - fan1_speed = get_pmc_register('fan3_input') - fan2_speed = get_pmc_register('fan4_input') - air_flow_reg = int(get_pmc_register('fan3_airflow'), 16) + fan1_speed = int(get_pmc_register('fan3_input')) + fan2_speed = int(get_pmc_register('fan4_input')) + air_flow_reg = int(get_pmc_register('fan3_airflow'), 16) fan1_status = 0 if fan1_speed >= 1000 else 1 fan2_status = 0 if fan2_speed >= 1000 else 1 - print ' Fan1 Speed: ', fan1_speed, 'RPM' - print ' Fan2 Speed: ', fan2_speed, 'RPM' - print ' Fan1 State: ', Fan_Status[fan1_status] - print ' Fan2 State: ', Fan_Status[fan2_status] - print ' Air Flow: ', Airflow_Direction[air_flow_reg] + print(' Fan1 Speed: ', fan1_speed, 'RPM') + print(' Fan2 Speed: ', fan2_speed, 'RPM') + print(' Fan1 State: ', Fan_Status[fan1_status]) + print(' Fan2 State: ', Fan_Status[fan2_status]) + print(' Air Flow: ', Airflow_Direction[air_flow_reg]) elif (tray == 3): - fan1_speed = get_pmc_register('fan5_input') - fan2_speed = get_pmc_register('fan6_input') - air_flow_reg = int(get_pmc_register('fan5_airflow'), 16) + fan1_speed = int(get_pmc_register('fan5_input')) + fan2_speed = int(get_pmc_register('fan6_input')) + air_flow_reg = int(get_pmc_register('fan5_airflow'), 16) fan1_status = 0 if fan1_speed >= 1000 else 1 fan2_status = 0 if fan2_speed >= 1000 else 1 - print ' Fan1 Speed: ', fan1_speed, 'RPM' - print ' Fan2 Speed: ', fan2_speed, 'RPM' - print ' Fan1 State: ', Fan_Status[fan1_status] - print ' Fan2 State: ', Fan_Status[fan2_status] - print ' Air Flow: ', Airflow_Direction[air_flow_reg] + print(' Fan1 Speed: ', fan1_speed, 'RPM') + print(' Fan2 Speed: ', fan2_speed, 'RPM') + print(' Fan1 State: ', Fan_Status[fan1_status]) + print(' Fan2 State: ', Fan_Status[fan2_status]) + print(' Air Flow: ', Airflow_Direction[air_flow_reg]) elif (tray == 4): - fan1_speed = get_pmc_register('fan7_input') - fan2_speed = get_pmc_register('fan8_input') - air_flow_reg = int(get_pmc_register('fan7_airflow'), 16) + fan1_speed = int(get_pmc_register('fan7_input')) + fan2_speed = int(get_pmc_register('fan8_input')) + air_flow_reg = int(get_pmc_register('fan7_airflow'), 16) fan1_status = 0 if fan1_speed >= 1000 else 1 fan2_status = 0 if fan2_speed >= 1000 else 1 - print ' Fan1 Speed: ', fan1_speed, 'RPM' - print ' Fan2 Speed: ', fan2_speed, 'RPM' - print ' Fan1 State: ', Fan_Status[fan1_status] - print ' Fan2 State: ', Fan_Status[fan2_status] - print ' Air Flow: ', Airflow_Direction[air_flow_reg] + print(' Fan1 Speed: ', fan1_speed, 'RPM') + print(' Fan2 Speed: ', fan2_speed, 'RPM') + print(' Fan1 State: ', Fan_Status[fan1_status]) + print(' Fan2 State: ', Fan_Status[fan2_status]) + print(' Air Flow: ', Airflow_Direction[air_flow_reg]) elif (tray == 5): - fan1_speed = get_pmc_register('fan9_input') - fan2_speed = get_pmc_register('fan10_input') - air_flow_reg = int(get_pmc_register('fan9_airflow'), 16) + fan1_speed = int(get_pmc_register('fan9_input')) + fan2_speed = int(get_pmc_register('fan10_input')) + air_flow_reg = int(get_pmc_register('fan9_airflow'), 16) fan1_status = 0 if fan1_speed >= 1000 else 1 fan2_status = 0 if fan2_speed >= 1000 else 1 - print ' Fan1 Speed: ', fan1_speed, 'RPM' - print ' Fan2 Speed: ', fan2_speed, 'RPM' - print ' Fan1 State: ', Fan_Status[fan1_status] - print ' Fan2 State: ', Fan_Status[fan2_status] - print ' Air Flow: ', Airflow_Direction[air_flow_reg] + print(' Fan1 Speed: ', fan1_speed, 'RPM') + print(' Fan2 Speed: ', fan2_speed, 'RPM') + print(' Fan1 State: ', Fan_Status[fan1_status]) + print(' Fan2 State: ', Fan_Status[fan2_status]) + print(' Air Flow: ', Airflow_Direction[air_flow_reg]) print('\nFan Trays:') @@ -220,7 +219,7 @@ def print_fan_tray(tray): if (fan_tray_presence & (1 << tray)): print_fan_tray(tray + 1) else: - print '\n Fan Tray ' + str(tray + 1) + ': Not present' + print('\n Fan Tray ' + str(tray + 1) + ': Not present') else: logging.error('Unable to read FAN presence') @@ -238,9 +237,8 @@ def print_psu(psu): Psu_Fan_Presence = ['Present', 'Absent'] Psu_Fan_Status = ['Normal', 'Abnormal'] Psu_Fan_Airflow = ['B2F', 'F2B'] - - print ' PSU ' + str(psu) + ':' + print(' PSU ' + str(psu) + ':') if (psu == 1): psu_status = int(get_pmc_register('psu1_presence'), 16) else: @@ -251,12 +249,12 @@ def print_psu(psu): psu_type = (psu_status & (1 << PSU_STATUS_TYPE_BIT)) >>\ PSU_STATUS_TYPE_BIT - print ' Input: ', Psu_Input_Type[psu_input_type] - print ' Type: ', Psu_Type[psu_type] + print(' Input: ', Psu_Input_Type[psu_input_type]) + print(' Type: ', Psu_Type[psu_type]) # PSU FAN details if (psu == 1): - print ' FAN Speed: ', get_pmc_register('fan11_input'), 'RPM' + print(' FAN Speed: ', get_pmc_register('fan11_input'), 'RPM') psu_fan_airflow = int(get_pmc_register('fan11_airflow')) psu_fan_status = int(get_pmc_register('fan11_alarm')) psu_fan_present = int(get_pmc_register('fan11_fault')) @@ -266,10 +264,10 @@ def print_psu(psu): 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): - psu_fan_temp = int(get_pmc_register('temp14_input'))/1000 + if (input_power != 0): + psu_fan_temp = int(get_pmc_register('temp14_input'))/1000 else: - print ' FAN Speed: ', get_pmc_register('fan12_input'), 'RPM' + print(' FAN Speed: ', get_pmc_register('fan12_input'), 'RPM') psu_fan_airflow = int(get_pmc_register('fan12_airflow')) psu_fan_status = int(get_pmc_register('fan12_alarm')) psu_fan_present = int(get_pmc_register('fan12_fault')) @@ -279,31 +277,31 @@ def print_psu(psu): 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): - psu_fan_temp = int(get_pmc_register('temp15_input'))/1000 + if (input_power != 0): + psu_fan_temp = int(get_pmc_register('temp15_input'))/1000 - print ' FAN: ', Psu_Fan_Presence[psu_fan_present] - print ' FAN Status: ', Psu_Fan_Status[psu_fan_status] - print ' FAN AIRFLOW: ', Psu_Fan_Airflow[psu_fan_airflow] + print(' FAN: ', Psu_Fan_Presence[psu_fan_present]) + print(' FAN Status: ', Psu_Fan_Status[psu_fan_status]) + print(' FAN AIRFLOW: ', Psu_Fan_Airflow[psu_fan_airflow]) # PSU input & output monitors - print ' Input Voltage: %6.2f' % (input_voltage), 'V' + print(' Input Voltage: %6.2f' % (input_voltage), 'V') - print ' Output Voltage: %6.2f' % (output_voltage), 'V' + print(' Output Voltage: %6.2f' % (output_voltage), 'V') - print ' Input Current: %6.2f' % (input_current), 'A' + print(' Input Current: %6.2f' % (input_current), 'A') - print ' Output Current: %6.2f' % (output_current), 'A' + print(' Output Current: %6.2f' % (output_current), 'A') - print ' Input Power: %6.2f' % (input_power), 'W' + print(' Input Power: %6.2f' % (input_power), 'W') - print ' Output Power: %6.2f' % (output_power), 'W' + print(' Output Power: %6.2f' % (output_power), 'W') # PSU firmware gives spurious temperature reading without input power if (input_power != 0): - print ' Temperature: ', psu_fan_temp, 'C' + print(' Temperature: ', psu_fan_temp, 'C') else: - print ' Temperature: ', 'NA' + print(' Temperature: ', 'NA') print('\nPSUs:') for psu in range(1, Z9100_MAX_PSUS + 1): @@ -319,8 +317,8 @@ def print_psu(psu): if (~psu_status & 0b1): print_psu(psu) else: - print '\n PSU ', psu, 'Not present' + print('\n PSU ', psu, 'Not present') else: logging.error('Unable to check PSU presence') -print '\n Total Power: ', get_pmc_register('current_total_power'), 'W' +print('\n Total Power: ', get_pmc_register('current_total_power'), 'W') diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh index 7fe841ef5447..8d564c6c2cd5 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh @@ -205,6 +205,7 @@ install_python_api_package() { platform=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) rv=$(pip install $device/$platform/sonic_platform-1.0-py2-none-any.whl) + rv=$(pip3 install $device/$platform/sonic_platform-1.0-py3-none-any.whl) } remove_python_api_package() { @@ -212,6 +213,11 @@ remove_python_api_package() { if [ $? -eq 0 ]; then rv = $(pip uninstall -y sonic-platform > /dev/null 2>/dev/null) fi + + rv=$(pip3 show sonic-platform > /dev/null 2>/dev/null) + if [ $? -eq 0 ]; then + rv=$(pip3 uninstall -y sonic-platform > /dev/null 2>/dev/null) + fi } init_devnum diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/__init__.py index 56f88c6e0fe2..8b4def6e7884 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/__init__.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/__init__.py @@ -1,3 +1,3 @@ -__all__ = ["platform", "chassis", "fan", "psu", "sfp", "thermal"] +__all__ = ["platform", "chassis", "fan", "fan_drawer", "psu", "sfp", "thermal"] from sonic_platform import * 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..82f8ae60f9d7 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 @@ -10,21 +10,20 @@ try: import os - import subprocess - import re + import select + import sys from sonic_platform_base.chassis_base import ChassisBase from sonic_platform.sfp import Sfp - from sonic_platform.fan import Fan + from sonic_platform.fan_drawer import FanDrawer from sonic_platform.psu import Psu from sonic_platform.thermal import Thermal from sonic_platform.component import Component - from eeprom import Eeprom + from sonic_platform.eeprom import Eeprom except ImportError as e: raise ImportError(str(e) + "- required module not found") MAX_Z9100_FANTRAY = 5 -MAX_Z9100_FAN = 2 MAX_Z9100_PSU = 2 MAX_Z9100_THERMAL = 8 MAX_Z9100_COMPONENT = 6 @@ -60,6 +59,8 @@ class Chassis(ChassisBase): 28: [16, 6], 29: [16, 7], 30: [16, 8], 31: [16, 9] } + OIR_FD_PATH = "/sys/devices/platform/dell_ich.0/sci_int_gpio_sus6" + reset_reason_dict = {} reset_reason_dict[11] = ChassisBase.REBOOT_CAUSE_POWER_LOSS reset_reason_dict[33] = ChassisBase.REBOOT_CAUSE_WATCHDOG @@ -74,6 +75,8 @@ class Chassis(ChassisBase): def __init__(self): ChassisBase.__init__(self) + self.oir_fd = -1 + self.epoll = -1 PORT_START = 0 PORT_END = 31 PORTS_IN_BLOCK = (PORT_END + 1) @@ -96,9 +99,9 @@ def __init__(self): # Initialize EEPROM self._eeprom = Eeprom() for i in range(MAX_Z9100_FANTRAY): - for j in range(MAX_Z9100_FAN): - fan = Fan(i, j) - self._fan_list.append(fan) + fandrawer = FanDrawer(i) + self._fan_drawer_list.append(fandrawer) + self._fan_list.extend(fandrawer._fan_list) for i in range(MAX_Z9100_PSU): psu = Psu(i) @@ -112,6 +115,12 @@ def __init__(self): component = Component(i) self._component_list.append(component) + def __del__(self): + if self.oir_fd != -1: + self.epoll.unregister(self.oir_fd.fileno()) + self.epoll.close() + self.oir_fd.close() + def _get_pmc_register(self, reg_name): # On successful read, returns the value read from given # reg_name and on failure returns 'ERR' @@ -131,6 +140,24 @@ def _get_pmc_register(self, reg_name): rv = rv.lstrip(" ") return rv + def _get_register(self, reg_file): + # On successful read, returns the value read from given + # reg_name and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(reg_file)): + return rv + + try: + with open(reg_file, 'r') as fd: + rv = fd.read() + except Exception as error: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + def get_name(self): """ Retrieves the name of the chassis @@ -163,6 +190,28 @@ def get_serial(self): """ 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): """ Retrieves the operational status of the chassis @@ -182,15 +231,6 @@ def get_base_mac(self): """ return self._eeprom.base_mac_addr() - def get_serial_number(self): - """ - Retrieves the hardware serial number for the chassis - - Returns: - A string containing the hardware serial number for this chassis. - """ - return self._eeprom.serial_number_str() - def get_system_eeprom_info(self): """ Retrieves the full content of system EEPROM information for the chassis @@ -230,3 +270,132 @@ def get_reboot_cause(self): return (self.reset_reason_dict[reset_reason], None) return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Invalid Reason") + + def _check_interrupts(self, port_dict): + is_port_dict_updated = False + + cpld2_abs_int = self._get_register( + "/sys/class/i2c-adapter/i2c-14/14-003e/qsfp_abs_int") + cpld2_abs_sta = self._get_register( + "/sys/class/i2c-adapter/i2c-14/14-003e/qsfp_abs_sta") + cpld3_abs_int = self._get_register( + "/sys/class/i2c-adapter/i2c-15/15-003e/qsfp_abs_int") + cpld3_abs_sta = self._get_register( + "/sys/class/i2c-adapter/i2c-15/15-003e/qsfp_abs_sta") + cpld4_abs_int = self._get_register( + "/sys/class/i2c-adapter/i2c-16/16-003e/qsfp_abs_int") + cpld4_abs_sta = self._get_register( + "/sys/class/i2c-adapter/i2c-16/16-003e/qsfp_abs_sta") + + if (cpld2_abs_int == 'ERR' or cpld2_abs_sta == 'ERR' or + cpld3_abs_int == 'ERR' or cpld3_abs_sta == 'ERR' or + cpld4_abs_int == 'ERR' or cpld4_abs_sta == 'ERR'): + return False, is_port_dict_updated + + cpld2_abs_int = int(cpld2_abs_int, 16) + cpld2_abs_sta = int(cpld2_abs_sta, 16) + cpld3_abs_int = int(cpld3_abs_int, 16) + cpld3_abs_sta = int(cpld3_abs_sta, 16) + cpld4_abs_int = int(cpld4_abs_int, 16) + cpld4_abs_sta = int(cpld4_abs_sta, 16) + + # Make it contiguous (discard reserved bits) + interrupt_reg = (cpld2_abs_int & 0xfff) |\ + ((cpld3_abs_int & 0x3ff) << 12) |\ + ((cpld4_abs_int & 0x3ff) << 22) + status_reg = (cpld2_abs_sta & 0xfff) |\ + ((cpld3_abs_sta & 0x3ff) << 12) |\ + ((cpld4_abs_sta & 0x3ff) << 22) + + for port in range(self.get_num_sfps()): + if interrupt_reg & (1 << port): + # update only if atleast one port has generated + # interrupt + is_port_dict_updated = True + if status_reg & (1 << port): + # status reg 1 => optics is removed + port_dict[port+1] = '0' + else: + # status reg 0 => optics is inserted + port_dict[port+1] = '1' + + return True, is_port_dict_updated + + def get_change_event(self, timeout=0): + """ + Returns a nested dictionary containing all devices which have + experienced a change at chassis level + + Args: + timeout: Timeout in milliseconds (optional). If timeout == 0, + this method will block until a change is detected. + + Returns: + (bool, dict): + - True if call successful, False if not; + - A nested dictionary where key is a device type, + value is a dictionary with key:value pairs in the + format of {'device_id':'device_event'}, + where device_id is the device ID for this device and + device_event, + status='1' represents device inserted, + status='0' represents device removed. + Ex. {'fan':{'0':'0', '2':'1'}, 'sfp':{'11':'0'}} + indicates that fan 0 has been removed, fan 2 + has been inserted and sfp 11 has been removed. + """ + port_dict = {} + ret_dict = {'sfp': port_dict} + if timeout != 0: + timeout = timeout / 1000 + try: + # We get notified when there is an SCI interrupt from GPIO SUS6 + # Open the sysfs file and register the epoll object + self.oir_fd = open(self.OIR_FD_PATH, "r") + if self.oir_fd != -1: + # Do a dummy read before epoll register + self.oir_fd.read() + self.epoll = select.epoll() + self.epoll.register(self.oir_fd.fileno(), + select.EPOLLIN & select.EPOLLET) + else: + return False, ret_dict + + # Check for missed interrupts by invoking self.check_interrupts + # which will update the port_dict. + while True: + interrupt_count_start = self._get_register(self.OIR_FD_PATH) + + retval, is_port_dict_updated = \ + self._check_interrupts(port_dict) + if (retval is True) and (is_port_dict_updated is True): + return True, ret_dict + + interrupt_count_end = self._get_register(self.OIR_FD_PATH) + + if (interrupt_count_start == 'ERR' or + interrupt_count_end == 'ERR'): + break + + # check_interrupts() itself may take upto 100s of msecs. + # We detect a missed interrupt based on the count + if interrupt_count_start == interrupt_count_end: + break + + # Block until an xcvr is inserted or removed with timeout = -1 + events = self.epoll.poll(timeout=timeout if timeout != 0 else -1) + if events: + # check interrupts and return the port_dict + retval, is_port_dict_updated = \ + self._check_interrupts(port_dict) + + return retval, ret_dict + except Exception: + return False, ret_dict + finally: + if self.oir_fd != -1: + self.epoll.unregister(self.oir_fd.fileno()) + self.epoll.close() + self.oir_fd.close() + self.oir_fd = -1 + self.epoll = -1 diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/component.py index dccb8f6ac2dc..52dee31a524e 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/component.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/component.py @@ -67,7 +67,7 @@ def _get_command_result(self, cmdline): stderr=subprocess.STDOUT) stdout = proc.communicate()[0] proc.wait() - result = stdout.rstrip('\n') + result = stdout.decode('utf-8').rstrip('\n') except OSError: result = None diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/eeprom.py index 15a2cec80191..f5dd5477be3e 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/eeprom.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/eeprom.py @@ -11,8 +11,7 @@ try: from sonic_eeprom import eeprom_tlvinfo - import binascii -except ImportError, e: +except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -33,7 +32,7 @@ def __init__(self): if not self.is_valid_tlvinfo_header(eeprom): return - total_length = (ord(eeprom[9]) << 8) | ord(eeprom[10]) + total_length = (eeprom[9] << 8) | eeprom[10] tlv_index = self._TLV_INFO_HDR_LEN tlv_end = self._TLV_INFO_HDR_LEN + total_length @@ -42,28 +41,29 @@ def __init__(self): break tlv = eeprom[tlv_index:tlv_index + 2 - + ord(eeprom[tlv_index + 1])] - code = "0x%02X" % (ord(tlv[0])) + + eeprom[tlv_index + 1]] + code = "0x%02X" % tlv[0] - if ord(tlv[0]) == self._TLV_CODE_VENDOR_EXT: - value = str((ord(tlv[2]) << 24) | (ord(tlv[3]) << 16) | - (ord(tlv[4]) << 8) | ord(tlv[5])) - value += str(tlv[6:6 + ord(tlv[1])]) + if tlv[0] == self._TLV_CODE_VENDOR_EXT: + value = str((tlv[2] << 24) | (tlv[3] << 16) | + (tlv[4] << 8) | tlv[5]) + value += tlv[6:6 + tlv[1]].decode('ascii') else: name, value = self.decoder(None, tlv) self.eeprom_tlv_dict[code] = value - if ord(eeprom[tlv_index]) == self._TLV_CODE_CRC_32: + if eeprom[tlv_index] == self._TLV_CODE_CRC_32: break - tlv_index += ord(eeprom[tlv_index+1]) + 2 + tlv_index += eeprom[tlv_index+1] + 2 def serial_number_str(self): (is_valid, results) = self.get_tlv_field( self.eeprom_data, self._TLV_CODE_SERIAL_NUMBER) if not is_valid: return "N/A" - return results[2] + + return results[2].decode('ascii') def base_mac_addr(self): (is_valid, t) = self.get_tlv_field( @@ -71,7 +71,7 @@ def base_mac_addr(self): if not is_valid or t[1] != 6: return super(TlvInfoDecoder, self).switchaddrstr(e) - return ":".join([binascii.b2a_hex(T) for T in t[2]]) + return ":".join(["{:02x}".format(T) for T in t[2]]).upper() def modelstr(self): (is_valid, results) = self.get_tlv_field( @@ -79,7 +79,7 @@ def modelstr(self): if not is_valid: return "N/A" - return results[2] + return results[2].decode('ascii') def part_number_str(self): (is_valid, results) = self.get_tlv_field( @@ -87,7 +87,7 @@ def part_number_str(self): if not is_valid: return "N/A" - return results[2] + return results[2].decode('ascii') def serial_str(self): (is_valid, results) = self.get_tlv_field( @@ -95,7 +95,7 @@ def serial_str(self): if not is_valid: return "N/A" - return results[2] + return results[2].decode('ascii') def revision_str(self): (is_valid, results) = self.get_tlv_field( @@ -103,7 +103,7 @@ def revision_str(self): if not is_valid: return "N/A" - return results[2] + return results[2].decode('ascii') def system_eeprom_info(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 6ff688fa3a1e..31bda2f4cefb 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 @@ -185,7 +185,7 @@ def get_speed(self): fan_speed = self._get_pmc_register(self.get_fan_speed_reg) if (fan_speed != 'ERR') and self.get_presence(): speed_in_rpm = int(fan_speed, 10) - speed = (100 * speed_in_rpm)/self.max_fan_speed + speed = (100 * speed_in_rpm)//self.max_fan_speed else: speed = 0 diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan_drawer.py new file mode 100644 index 000000000000..b74931dd92d3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan_drawer.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC Z9100 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Fan-Drawers' information available in the platform. +# +######################################################################## + +try: + from sonic_platform_base.fan_drawer_base import FanDrawerBase + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +Z9100_FANS_PER_FANTRAY = 2 + + +class FanDrawer(FanDrawerBase): + """DellEMC Platform-specific Fan class""" + + def __init__(self, fantray_index): + + FanDrawerBase.__init__(self) + # FanTray is 1-based in DellEMC platforms + self.fantrayindex = fantray_index + 1 + for i in range(Z9100_FANS_PER_FANTRAY): + self._fan_list.append(Fan(fantray_index, i)) + + def get_name(self): + """ + Retrieves the fan drawer name + Returns: + string: The name of the device + """ + return "FanTray{}".format(self.fantrayindex) diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/sfp.py index 9f5844d2058c..7abe73c2be3d 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/sfp.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/sfp.py @@ -40,8 +40,8 @@ 'Fibre Channel transmission media', 'Fibre Channel Speed') -info_dict_keys = ['type', 'hardwarerev', 'serialnum', - 'manufacturename', 'modelname', 'Connector', +info_dict_keys = ['type', 'hardware_rev', 'serial', + 'manufacturer', 'model', 'connector', 'encoding', 'ext_identifier', 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance','type_abbrv_name','vendor_date', 'vendor_oui'] @@ -78,7 +78,7 @@ 'cable_type': [INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], 'cable_length': [INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], - 'Connector': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'connector': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'type': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'encoding': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'ext_identifier': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], @@ -88,11 +88,11 @@ 'specification_compliance': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'type_abbrv_name': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], - 'manufacturename': [INFO_OFFSET, 20, 16, 'parse_vendor_name'], + 'manufacturer': [INFO_OFFSET, 20, 16, 'parse_vendor_name'], 'vendor_oui': [INFO_OFFSET, 37, 3, 'parse_vendor_oui'], - 'modelname': [INFO_OFFSET, 40, 16, 'parse_vendor_pn'], - 'hardwarerev': [INFO_OFFSET, 56, 2, 'parse_vendor_rev'], - 'serialnum': [INFO_OFFSET, 68, 16, 'parse_vendor_sn'], + 'model': [INFO_OFFSET, 40, 16, 'parse_vendor_pn'], + 'hardware_rev': [INFO_OFFSET, 56, 2, 'parse_vendor_rev'], + 'serial': [INFO_OFFSET, 68, 16, 'parse_vendor_sn'], 'vendor_date': [INFO_OFFSET, 84, 8, 'parse_vendor_date'], 'ModuleThreshold': [DOM_OFFSET1, 128, 24, 'parse_module_threshold_values'], 'ChannelThreshold': [DOM_OFFSET1, 176, 16, 'parse_channel_threshold_values'], @@ -207,7 +207,7 @@ def get_transceiver_info(self): return transceiver_info_dict # Vendor Name - vendor_name_data = self._get_eeprom_data('manufacturename') + vendor_name_data = self._get_eeprom_data('manufacturer') if (vendor_name_data is not None): vendor_name = vendor_name_data['data']['Vendor Name']['value'] else: @@ -221,21 +221,21 @@ def get_transceiver_info(self): return transceiver_info_dict # Vendor PN - vendor_pn_data = self._get_eeprom_data('modelname') + vendor_pn_data = self._get_eeprom_data('model') if (vendor_pn_data is not None): vendor_pn = vendor_pn_data['data']['Vendor PN']['value'] else: return transceiver_info_dict # Vendor Revision - vendor_rev_data = self._get_eeprom_data('hardwarerev') + vendor_rev_data = self._get_eeprom_data('hardware_rev') if (vendor_rev_data is not None): vendor_rev = vendor_rev_data['data']['Vendor Rev']['value'] else: return transceiver_info_dict # Vendor Serial Number - vendor_sn_data = self._get_eeprom_data('serialnum') + vendor_sn_data = self._get_eeprom_data('serial') if (vendor_sn_data is not None): vendor_sn = vendor_sn_data['data']['Vendor SN']['value'] else: @@ -243,11 +243,11 @@ def get_transceiver_info(self): # Fill The Dictionary and return transceiver_info_dict['type'] = identifier - transceiver_info_dict['hardwarerev'] = vendor_rev - transceiver_info_dict['serialnum'] = vendor_sn - transceiver_info_dict['manufacturename'] = vendor_name - transceiver_info_dict['modelname'] = vendor_pn - transceiver_info_dict['Connector'] = connector + transceiver_info_dict['hardware_rev'] = vendor_rev + transceiver_info_dict['serial'] = vendor_sn + transceiver_info_dict['manufacturer'] = vendor_name + transceiver_info_dict['model'] = vendor_pn + transceiver_info_dict['connector'] = connector transceiver_info_dict['encoding'] = encoding transceiver_info_dict['ext_identifier'] = ext_id transceiver_info_dict['ext_rateselect_compliance'] = rate_identifier @@ -258,7 +258,7 @@ def get_transceiver_info(self): compliance_code_dict) transceiver_info_dict['vendor_date'] = vendor_date transceiver_info_dict['vendor_oui'] = vendor_oui - transceiver_info_dict['type_abbrv_name']=type_abbrv_name + transceiver_info_dict['type_abbrv_name'] = type_abbrv_name return transceiver_info_dict @@ -436,7 +436,7 @@ def get_model(self): """ Retrieves the model number (or part number) of the sfp """ - vendor_pn_data = self._get_eeprom_data('modelname') + vendor_pn_data = self._get_eeprom_data('model') if (vendor_pn_data is not None): vendor_pn = vendor_pn_data['data']['Vendor PN']['value'] else: @@ -448,7 +448,7 @@ def get_serial(self): """ Retrieves the serial number of the sfp """ - vendor_sn_data = self._get_eeprom_data('serialnum') + vendor_sn_data = self._get_eeprom_data('serial') if (vendor_sn_data is not None): vendor_sn = vendor_sn_data['data']['Vendor SN']['value'] else: diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/thermal.py index 05d012b114c0..942934ed7638 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/thermal.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/thermal.py @@ -45,10 +45,14 @@ def __init__(self, thermal_index): self.thermal_temperature_file = self.HWMON_DIR \ + "temp{}_input".format(hwmon_temp_index) self.thermal_high_threshold_file = self.HWMON_DIR \ - + "temp{}_crit".format(hwmon_temp_index) + + "temp{}_max".format(hwmon_temp_index) self.thermal_low_threshold_file = self.HWMON_DIR \ + "temp{}_min".format(hwmon_temp_index) + if not self.is_cpu_thermal: + self.thermal_high_crit_threshold_file = self.HWMON_DIR \ + + "temp{}_crit".format(hwmon_temp_index) + def _read_sysfs_file(self, sysfs_file): # On successful read, returns the value read from given # sysfs_file and on failure returns 'ERR' @@ -134,11 +138,11 @@ def get_temperature(self): thermal_temperature = self._read_sysfs_file( self.thermal_temperature_file) if (thermal_temperature != 'ERR'): - thermal_temperature = float(thermal_temperature) / 1000 + thermal_temperature = float(thermal_temperature) else: thermal_temperature = 0 - return "{:.3f}".format(thermal_temperature) + return thermal_temperature / 1000.0 def get_high_threshold(self): """ @@ -152,11 +156,11 @@ def get_high_threshold(self): thermal_high_threshold = self._read_sysfs_file( self.thermal_high_threshold_file) if (thermal_high_threshold != 'ERR'): - thermal_high_threshold = float(thermal_high_threshold) / 1000 + thermal_high_threshold = float(thermal_high_threshold) else: thermal_high_threshold = 0 - return "{:.3f}".format(thermal_high_threshold) + return thermal_high_threshold / 1000.0 def get_low_threshold(self): """ @@ -170,11 +174,32 @@ def get_low_threshold(self): thermal_low_threshold = self._read_sysfs_file( self.thermal_low_threshold_file) if (thermal_low_threshold != 'ERR'): - thermal_low_threshold = float(thermal_low_threshold) / 1000 + thermal_low_threshold = float(thermal_low_threshold) else: thermal_low_threshold = 0 - return "{:.3f}".format(thermal_low_threshold) + return thermal_low_threshold / 1000.0 + + def get_high_critical_threshold(self): + """ + Retrieves the high critical threshold temperature of thermal + + Returns: + A float number, the high critical threshold temperature of + thermal in Celsius up to nearest thousandth of one degree + Celsius, e.g. 30.125 + """ + if self.is_cpu_thermal: + return super(Thermal, self).get_high_critical_threshold() + + thermal_high_crit_threshold = self._read_sysfs_file( + self.thermal_high_crit_threshold_file) + if (thermal_high_crit_threshold != 'ERR'): + thermal_high_crit_threshold = float(thermal_high_crit_threshold) + else: + thermal_high_crit_threshold = 0 + + return thermal_high_crit_threshold / 1000.0 def set_high_threshold(self, temperature): """ diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/systemd/platform-modules-z9100.service b/platform/broadcom/sonic-platform-modules-dell/z9100/systemd/platform-modules-z9100.service index 00fbfa6803ef..390cb6e0f567 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/systemd/platform-modules-z9100.service +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/systemd/platform-modules-z9100.service @@ -1,6 +1,6 @@ [Unit] Description=Dell Z9100 Platform modules -Before=pmon.service +Before=pmon.service determine-reboot-cause.service DefaultDependencies=no [Service] diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/pcisysfs.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/pcisysfs.py deleted file mode 100755 index 047618e057c8..000000000000 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/pcisysfs.py +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/python -# Copyright (c) 2015 Dell Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -# -# THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR -# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT -# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS -# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. -# -# See the Apache Version 2.0 License for specific language governing -# permissions and limitations under the License. - -import struct -import sys -import getopt -from os import * -from mmap import * - -def usage(): - ''' This is the Usage Method ''' - - print '\t\t pcisysfs.py --get --offset --res ' - print '\t\t pcisysfs.py --set --val --offset --res ' - sys.exit(1) - -def pci_mem_read(mm,offset): - mm.seek(offset) - read_data_stream=mm.read(4) - print "" - reg_val=struct.unpack('I',read_data_stream) - print "reg_val read:%x"%reg_val - return reg_val - -def pci_mem_write(mm,offset,data): - mm.seek(offset) - print "data to write:%x"%data - mm.write(struct.pack('I',data)) - -def pci_set_value(resource,val,offset): - fd=open(resource,O_RDWR) - mm=mmap(fd,0) - pci_mem_write(mm,offset,val) - -def pci_get_value(resource,offset): - fd=open(resource,O_RDWR) - mm=mmap(fd,0) - pci_mem_read(mm,offset) - -def main(argv): - - ''' The main function will read the user input from the - command line argument and process the request ''' - - opts = '' - val = '' - choice = '' - resource = '' - offset = '' - - try: - opts, args = getopt.getopt(argv, "hgsv:" , \ - ["val=","res=","offset=","help", "get", "set"]) - - except getopt.GetoptError: - usage() - - for opt,arg in opts: - - if opt in ('-h','--help'): - choice = 'help' - - elif opt in ('-g', '--get'): - choice = 'get' - - elif opt in ('-s', '--set'): - choice = 'set' - - elif opt == '--res': - resource = arg - - elif opt == '--val': - val = int(arg,16) - - elif opt == '--offset': - offset = int(arg,16) - - if choice == 'set' and val != '' and offset !='' and resource !='': - pci_set_value(resource,val,offset) - - elif choice == 'get' and offset != '' and resource !='': - pci_get_value(resource,offset) - - else: - usage() - -#Calling the main method -if __name__ == "__main__": - main(sys.argv[1:]) - diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/platform_sensors.py index 77a9887f9a0a..bcc13452a828 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/platform_sensors.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/platform_sensors.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # On Z9264f, the BaseBoard Management Controller is an # autonomous subsystem provides monitoring and management # facility independent of the host CPU. IPMI standard @@ -11,11 +11,9 @@ # * PSU -import os import sys import logging import subprocess -import commands Z9264F_MAX_FAN_TRAYS = 4 Z9264F_MAX_PSUS = 2 @@ -36,7 +34,7 @@ def ipmi_sensor_dump(): status = 1 global ipmi_sdr_list ipmi_cmd = IPMI_SENSOR_DATA - status, ipmi_sdr_list = commands.getstatusoutput(ipmi_cmd) + status, ipmi_sdr_list = subprocess.getstatusoutput(ipmi_cmd) if status: logging.error('Failed to execute:' + ipmi_sdr_list) @@ -68,24 +66,24 @@ def print_temperature_sensors(): print("\nOnboard Temperature Sensors:") - print ' PT_Left_temp: ',\ - (get_pmc_register('PT_Left_temp')) - print ' PT_Mid_temp: ',\ - (get_pmc_register('PT_Mid_temp')) - print ' PT_Right_temp: ',\ - (get_pmc_register('PT_Right_temp')) - print ' Broadcom Temp: ',\ - (get_pmc_register('TC_Near_temp')) - print ' Inlet Airflow Temp: ',\ - (get_pmc_register('ILET_AF_temp')) - print ' CPU Temp: ',\ - (get_pmc_register('CPU_Near_temp')) - print ' CPU Near Temp: ',\ - (get_pmc_register('CPU_temp')) - print ' PSU FAN AirFlow Temperature 1: ',\ - (get_pmc_register('PSU1_AF_temp')) - print ' PSU FAN AirFlow Temperature 2: ',\ - (get_pmc_register('PSU2_AF_temp')) + print(' PT_Left_temp: ', + get_pmc_register('PT_Left_temp')) + print(' PT_Mid_temp: ', + get_pmc_register('PT_Mid_temp')) + print(' PT_Right_temp: ', + get_pmc_register('PT_Right_temp')) + print(' Broadcom Temp: ', + get_pmc_register('TC_Near_temp')) + print(' Inlet Airflow Temp: ', + get_pmc_register('ILET_AF_temp')) + print(' CPU Temp: ', + get_pmc_register('CPU_Near_temp')) + print(' CPU Near Temp: ', + get_pmc_register('CPU_temp')) + print(' PSU FAN AirFlow Temperature 1: ', + get_pmc_register('PSU1_AF_temp')) + print(' PSU FAN AirFlow Temperature 2: ', + get_pmc_register('PSU2_AF_temp')) ipmi_sensor_dump() @@ -99,7 +97,7 @@ def print_fan_tray(tray): Fan_Status = [' Normal', ' Abnormal', ' no reading'] Airflow_Direction = ['B2F', 'F2B'] - print ' Fan Tray ' + str(tray) + ':' + print(' Fan Tray ' + str(tray) + ':') if (tray == 1): @@ -114,14 +112,14 @@ def print_fan_tray(tray): fan1_status = 2 fan2_status = 2 - print ' Fan1 Speed: ',\ - get_pmc_register('FAN1_Front_rpm') - print ' Fan2 Speed: ',\ - get_pmc_register('FAN1_Rear_rpm') - print ' Fan1 State: ',\ - Fan_Status[fan1_status] - print ' Fan2 State: ',\ - Fan_Status[fan2_status] + print(' Fan1 Speed: ', + get_pmc_register('FAN1_Front_rpm')) + print(' Fan2 Speed: ', + get_pmc_register('FAN1_Rear_rpm')) + print(' Fan1 State: ', + Fan_Status[fan1_status]) + print(' Fan2 State: ', + Fan_Status[fan2_status]) elif (tray == 2): @@ -136,14 +134,14 @@ def print_fan_tray(tray): fan1_status = 2 fan2_status = 2 - print ' Fan1 Speed: ',\ - get_pmc_register('FAN2_Front_rpm') - print ' Fan2 Speed: ',\ - get_pmc_register('FAN2_Rear_rpm') - print ' Fan1 State: ',\ - Fan_Status[fan1_status] - print ' Fan2 State: ',\ - Fan_Status[fan2_status] + print(' Fan1 Speed: ', + get_pmc_register('FAN2_Front_rpm')) + print(' Fan2 Speed: ', + get_pmc_register('FAN2_Rear_rpm')) + print(' Fan1 State: ', + Fan_Status[fan1_status]) + print(' Fan2 State: ', + Fan_Status[fan2_status]) elif (tray == 3): @@ -158,14 +156,14 @@ def print_fan_tray(tray): fan1_status = 2 fan2_status = 2 - print ' Fan1 Speed: ',\ - get_pmc_register('FAN3_Front_rpm') - print ' Fan2 Speed: ',\ - get_pmc_register('FAN3_Rear_rpm') - print ' Fan1 State: ',\ - Fan_Status[fan1_status] - print ' Fan2 State: ',\ - Fan_Status[fan2_status] + print(' Fan1 Speed: ', + get_pmc_register('FAN3_Front_rpm')) + print(' Fan2 Speed: ', + get_pmc_register('FAN3_Rear_rpm')) + print(' Fan1 State: ', + Fan_Status[fan1_status]) + print(' Fan2 State: ', + Fan_Status[fan2_status]) elif (tray == 4): @@ -180,14 +178,14 @@ def print_fan_tray(tray): fan1_status = 2 fan2_status = 2 - print ' Fan1 Speed: ',\ - get_pmc_register('FAN4_Front_rpm') - print ' Fan2 Speed: ',\ - get_pmc_register('FAN4_Rear_rpm') - print ' Fan1 State: ',\ - Fan_Status[fan1_status] - print ' Fan2 State: ',\ - Fan_Status[fan2_status] + print(' Fan1 Speed: ', + get_pmc_register('FAN4_Front_rpm')) + print(' Fan2 Speed: ', + get_pmc_register('FAN4_Rear_rpm')) + print(' Fan1 State: ', + Fan_Status[fan1_status]) + print(' Fan2 State: ', + Fan_Status[fan2_status]) print('\nFan Trays:') @@ -197,7 +195,7 @@ def print_fan_tray(tray): if (get_pmc_register(fan_presence)): print_fan_tray(tray) else: - print '\n Fan Tray ' + str(tray + 1) + ': Not present' + print('\n Fan Tray ' + str(tray + 1) + ': Not present') # Print the information for PSU1, PSU2 @@ -206,51 +204,51 @@ def print_psu(psu): # PSU FAN details if (psu == 1): - print ' PSU1:' - print ' FAN Normal Temperature: ',\ - get_pmc_register('PSU1_Normal_temp') - print ' Chassis Temperature: ',\ - get_pmc_register('PSU1_Chass_temp') - print ' System Temperature: ',\ - get_pmc_register('PSU1_Sys_temp') - print ' FAN RPM: ',\ - get_pmc_register('PSU1_rpm') - print ' Input Voltage: ',\ - get_pmc_register('PSU1_In_volt') - print ' Output Voltage: ',\ - get_pmc_register('PSU1_Out_volt') - print ' Input Power: ',\ - get_pmc_register('PSU1_In_watt') - print ' Output Power: ',\ - get_pmc_register('PSU1_Out_watt') - print ' Input Current: ',\ - get_pmc_register('PSU1_In_amp') - print ' Output Current: ',\ - get_pmc_register('PSU1_Out_amp') + print(' PSU1:') + print(' FAN Normal Temperature: ', + get_pmc_register('PSU1_Normal_temp')) + print(' Chassis Temperature: ', + get_pmc_register('PSU1_Chass_temp')) + print(' System Temperature: ', + get_pmc_register('PSU1_Sys_temp')) + print(' FAN RPM: ', + get_pmc_register('PSU1_rpm')) + print(' Input Voltage: ', + get_pmc_register('PSU1_In_volt')) + print(' Output Voltage: ', + get_pmc_register('PSU1_Out_volt')) + print(' Input Power: ', + get_pmc_register('PSU1_In_watt')) + print(' Output Power: ', + get_pmc_register('PSU1_Out_watt')) + print(' Input Current: ', + get_pmc_register('PSU1_In_amp')) + print(' Output Current: ', + get_pmc_register('PSU1_Out_amp')) else: - print ' PSU2:' - print ' FAN Normal Temperature: ',\ - get_pmc_register('PSU2_Normal_temp') - print ' Chassis Temperature: ',\ - get_pmc_register('PSU2_Chass_temp') - print ' System Temperature: ',\ - get_pmc_register('PSU2_Sys_temp') - print ' FAN RPM: ',\ - get_pmc_register('PSU2_rpm') - print ' Input Voltage: ',\ - get_pmc_register('PSU2_In_volt') - print ' Output Voltage: ',\ - get_pmc_register('PSU2_Out_volt') - print ' Input Power: ',\ - get_pmc_register('PSU2_In_watt') - print ' Output Power: ',\ - get_pmc_register('PSU2_Out_watt') - print ' Input Current: ',\ - get_pmc_register('PSU2_In_amp') - print ' Output Current: ',\ - get_pmc_register('PSU2_Out_amp') + print(' PSU2:') + print(' FAN Normal Temperature: ', + get_pmc_register('PSU2_Normal_temp')) + print(' Chassis Temperature: ', + get_pmc_register('PSU2_Chass_temp')) + print(' System Temperature: ', + get_pmc_register('PSU2_Sys_temp')) + print(' FAN RPM: ', + get_pmc_register('PSU2_rpm')) + print(' Input Voltage: ', + get_pmc_register('PSU2_In_volt')) + print(' Output Voltage: ', + get_pmc_register('PSU2_Out_volt')) + print(' Input Power: ', + get_pmc_register('PSU2_In_watt')) + print(' Output Power: ', + get_pmc_register('PSU2_Out_watt')) + print(' Input Current: ', + get_pmc_register('PSU2_In_amp')) + print(' Output Current: ', + get_pmc_register('PSU2_Out_amp')) print('\nPSUs:') @@ -259,7 +257,7 @@ def print_psu(psu): if (get_pmc_register(psu_presence)): print_psu(psu) else: - print '\n PSU ', psu, 'Not present' + print('\n PSU ', psu, 'Not present') -print '\n Total Power: ',\ - get_pmc_register('PSU_Total_watt') +print('\n Total Power: ', + get_pmc_register('PSU_Total_watt')) diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/port_irq_enable.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/port_irq_enable.py new file mode 100755 index 000000000000..ff9d9ce8d723 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/port_irq_enable.py @@ -0,0 +1,32 @@ +#!/usr/bin/python3 + +try: + import struct + from os import * + from mmap import * + +except ImportError as e: + raise ImportError("%s - required module no found" % str(e)) + +BASE_RES_PATH = "/sys/bus/pci/devices/0000:04:00.0/resource0" +PORT_START = 0 +PORT_END = 64 + + +def pci_mem_write(mm, offset, data): + mm.seek(offset) + mm.write(struct.pack('I', data)) + + +def pci_set_value(resource, val, offset): + fd = open(resource, O_RDWR) + mm = mmap(fd, 0) + val = pci_mem_write(mm, offset, val) + mm.close() + close(fd) + return val + +# Enabled interrupt for qsfp and sfp +for port_num in range(PORT_START, PORT_END+1): + port_offset = 0x400c + ((port_num) * 16) + pci_set_value(BASE_RES_PATH, 0x31, port_offset) diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh index a613fd080384..8469b844757b 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh @@ -100,13 +100,25 @@ switch_board_sfp() { #Modsel 64 ports to applicable QSFP type modules #This enables the adapter to respond for i2c commands switch_board_modsel() { - resource="/sys/bus/pci/devices/0000:04:00.0/resource0" - for ((i=1;i<=64;i++)); - do - port_addr=$(( 16384 + ((i - 1) * 16))) - hex=$( printf "0x%x" $port_addr ) - python /usr/bin/pcisysfs.py --set --offset $hex --val 0x10 --res $resource > /dev/null 2>&1 - done + resource="/sys/bus/pci/devices/0000:04:00.0/resource0" + for ((i=1;i<=64;i++)); + do + port_addr=$(( 16384 + ((i - 1) * 16))) + hex=$( printf "0x%x" $port_addr ) + /usr/bin/pcisysfs.py --set --offset $hex --val 0x10 --res $resource > /dev/null 2>&1 + done + + # Disabling low power mode for last two 10G ports + # From last 6th bit: Disable - 0; Enable - 1 + reg_offset=$(/usr/bin/pcisysfs.py --get --offset 0x4400 --res $resource | cut -d':' -f 2) + reg_offset=$( printf '0x%s' $reg_offset) + reg_offset=$( printf '0x%x' $(( $reg_offset & 0xbf )) ) + /usr/bin/pcisysfs.py --set --offset 0x4400 --val $reg_offset --res $resource > /dev/null 2>&1 + + reg_offset=$(/usr/bin/pcisysfs.py --get --offset 0x4410 --res $resource | cut -d':' -f 2) + reg_offset=$( printf '0x%s' $reg_offset) + reg_offset=$( printf '0x%x' $(( $reg_offset & 0xbf )) ) + /usr/bin/pcisysfs.py --set --offset 0x4410 --val $reg_offset --res $resource > /dev/null 2>&1 } # Copy led_proc_init.soc file according to the HWSKU @@ -130,6 +142,7 @@ install_python_api_package() { platform=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) rv=$(pip install $device/$platform/sonic_platform-1.0-py2-none-any.whl) + rv=$(pip3 install $device/$platform/sonic_platform-1.0-py3-none-any.whl) } remove_python_api_package() { @@ -137,6 +150,11 @@ remove_python_api_package() { if [ $? -eq 0 ]; then rv=$(pip uninstall -y sonic-platform > /dev/null 2>/dev/null) fi + + rv=$(pip3 show sonic-platform > /dev/null 2>/dev/null) + if [ $? -eq 0 ]; then + rv=$(pip3 uninstall -y sonic-platform > /dev/null 2>/dev/null) + fi } # Readout firmware version of the system and @@ -183,6 +201,18 @@ platform_firmware_versions() echo "Slave CPLD 4: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE } +get_reboot_cause() { + REBOOT_REASON_FILE="/host/reboot-cause/platform/reboot_reason" + resource="/sys/bus/pci/devices/0000:04:00.0/resource0" + + # Handle First Boot into software version with reboot cause determination support + if [[ ! -e $REBOOT_REASON_FILE ]]; then + echo "0" > $REBOOT_REASON_FILE + else + /usr/bin/pcisysfs.py --get --offset 0x18 --res $resource | sed '1d; s/.*:\(.*\)$/\1/;' > $REBOOT_REASON_FILE + fi + /usr/bin/pcisysfs.py --set --val 0x0 --offset 0x18 --res $resource +} init_devnum @@ -194,15 +224,17 @@ if [ "$1" == "init" ]; then modprobe i2c_ocores modprobe dell_z9264f_fpga_ocores sys_eeprom "new_device" + get_reboot_cause switch_board_qsfp_mux "new_device" switch_board_qsfp "new_device" switch_board_sfp "new_device" switch_board_modsel init_switch_port_led install_python_api_package - python /usr/bin/qsfp_irq_enable.py + /usr/bin/port_irq_enable.py platform_firmware_versions + elif [ "$1" == "deinit" ]; then sys_eeprom "delete_device" switch_board_qsfp "delete_device" diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/__init__.py index 328d25319343..4f5d4f6e473d 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/__init__.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/__init__.py @@ -1,3 +1,2 @@ -__all__ = ["chassis", "sfp", "eeprom"] +__all__ = ["platform", "chassis", "sfp", "eeprom", "component", "psu", "thermal", "fan", "fan_drawer"] from sonic_platform import * - diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py index 36f2ca8df264..3f99cf503b3b 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/chassis.py @@ -11,15 +11,19 @@ try: import os import select + import sys from sonic_platform_base.chassis_base import ChassisBase from sonic_platform.sfp import Sfp from sonic_platform.eeprom import Eeprom from sonic_platform.component import Component from sonic_platform.psu import Psu + from sonic_platform.watchdog import Watchdog + from sonic_platform.fan_drawer import FanDrawer from sonic_platform.thermal import Thermal except ImportError as e: raise ImportError(str(e) + "- required module not found") +MAX_Z9264F_FANTRAY =4 MAX_Z9264F_COMPONENT = 8 # BIOS,BMC,FPGA,SYSTEM CPLD,4 SLAVE CPLDs MAX_Z9264F_PSU = 2 MAX_Z9264F_THERMAL = 8 @@ -30,6 +34,7 @@ class Chassis(ChassisBase): DELLEMC Platform-specific Chassis class """ + REBOOT_CAUSE_PATH = "/host/reboot-cause/platform/reboot_reason" OIR_FD_PATH = "/sys/bus/pci/devices/0000:04:00.0/port_msi" oir_fd = -1 @@ -44,7 +49,7 @@ def __init__(self): self.PORT_START = 1 self.PORT_END = 66 PORTS_IN_BLOCK = (self.PORT_END + 1) - _sfp_port = range(65, self.PORT_END + 1) + _sfp_port = list(range(65, self.PORT_END + 1)) eeprom_base = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" for index in range(self.PORT_START, PORTS_IN_BLOCK): @@ -57,19 +62,26 @@ def __init__(self): self._sfp_list.append(sfp_node) self._eeprom = Eeprom() - + + self._watchdog = Watchdog() + for i in range(MAX_Z9264F_COMPONENT): component = Component(i) self._component_list.append(component) - + for i in range(MAX_Z9264F_PSU): psu = Psu(i) self._psu_list.append(psu) - + + for i in range(MAX_Z9264F_FANTRAY): + fandrawer = FanDrawer(i) + self._fan_drawer_list.append(fandrawer) + self._fan_list.extend(fandrawer._fan_list) + for i in range(MAX_Z9264F_THERMAL): thermal = Thermal(i) self._thermal_list.append(thermal) - + for port_num in range(self.PORT_START, (self.PORT_END + 1)): presence = self.get_sfp(port_num).get_presence() if presence: @@ -86,7 +98,7 @@ def __del__(self): def _get_register(self, reg_file): retval = 'ERR' if (not os.path.isfile(reg_file)): - print reg_file, 'not found !' + print(reg_file, 'not found !') return retval try: @@ -246,14 +258,6 @@ def get_base_mac(self): """ return self._eeprom.base_mac_addr() - def get_serial_number(self): - """ - Retrieves the hardware serial number for the chassis - Returns: - A string containing the hardware serial number for this chassis. - """ - return self._eeprom.serial_number_str() - def get_system_eeprom_info(self): """ Retrieves the full content of system EEPROM information for the chassis @@ -263,3 +267,40 @@ def get_system_eeprom_info(self): values. """ return self._eeprom.system_eeprom_info() + + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + Returns: + A tuple (string, string) where the first element is a string + containing the cause of the previous reboot. This string must be + one of the predefined strings in this class. If the first string + is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used + to pass a description of the reboot cause. + """ + try: + with open(self.REBOOT_CAUSE_PATH) as fd: + reboot_cause = int(fd.read(), 16) + except: + return (self.REBOOT_CAUSE_NON_HARDWARE, None) + + if reboot_cause & 0x1: + return (self.REBOOT_CAUSE_POWER_LOSS, None) + elif reboot_cause & 0x2: + return (self.REBOOT_CAUSE_NON_HARDWARE, None) + elif reboot_cause & 0x4: + return (self.REBOOT_CAUSE_HARDWARE_OTHER, "PSU Shutdown") + elif reboot_cause & 0x8: + return (self.REBOOT_CAUSE_THERMAL_OVERLOAD_CPU, None) + elif reboot_cause & 0x10: + return (self.REBOOT_CAUSE_WATCHDOG, None) + elif reboot_cause & 0x20: + return (self.REBOOT_CAUSE_HARDWARE_OTHER, "BMC Shutdown") + elif reboot_cause & 0x40: + return (self.REBOOT_CAUSE_HARDWARE_OTHER, "Hot-Swap Shutdown") + elif reboot_cause & 0x80: + return (self.REBOOT_CAUSE_HARDWARE_OTHER, "Reset Button Shutdown") + elif reboot_cause & 0x100: + return (self.REBOOT_CAUSE_HARDWARE_OTHER, "Reset Button Cold Reboot") + else: + return (self.REBOOT_CAUSE_NON_HARDWARE, None) diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/eeprom.py index 82cf6d6489aa..a1b51b8b41fe 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/eeprom.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/eeprom.py @@ -12,8 +12,7 @@ try: import os.path from sonic_eeprom import eeprom_tlvinfo - import binascii -except ImportError, e: +except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -26,8 +25,8 @@ def __init__(self): if os.path.exists(f): self.eeprom_path = f break - if self.eeprom_path is None: - return + if self.eeprom_path is None: + return super(Eeprom, self).__init__(self.eeprom_path, 0, '', True) self.eeprom_tlv_dict = dict() try: @@ -41,7 +40,7 @@ def __init__(self): if not self.is_valid_tlvinfo_header(eeprom): return - total_length = (ord(eeprom[9]) << 8) | ord(eeprom[10]) + total_length = (eeprom[9] << 8) | eeprom[10] tlv_index = self._TLV_INFO_HDR_LEN tlv_end = self._TLV_INFO_HDR_LEN + total_length @@ -50,21 +49,21 @@ def __init__(self): break tlv = eeprom[tlv_index:tlv_index + 2 - + ord(eeprom[tlv_index + 1])] - code = "0x%02X" % (ord(tlv[0])) + + eeprom[tlv_index + 1]] + code = "0x%02X" % tlv[0] - if ord(tlv[0]) == self._TLV_CODE_VENDOR_EXT: - value = str((ord(tlv[2]) << 24) | (ord(tlv[3]) << 16) | - (ord(tlv[4]) << 8) | ord(tlv[5])) - value += str(tlv[6:6 + ord(tlv[1])]) + if tlv[0] == self._TLV_CODE_VENDOR_EXT: + value = str((tlv[2] << 24) | (tlv[3] << 16) | + (tlv[4] << 8) | tlv[5]) + value += tlv[6:6 + tlv[1]].decode('ascii') else: name, value = self.decoder(None, tlv) self.eeprom_tlv_dict[code] = value - if ord(eeprom[tlv_index]) == self._TLV_CODE_CRC_32: + if eeprom[tlv_index] == self._TLV_CODE_CRC_32: break - tlv_index += ord(eeprom[tlv_index+1]) + 2 + tlv_index += eeprom[tlv_index+1] + 2 def serial_number_str(self): """ @@ -74,7 +73,7 @@ def serial_number_str(self): self.eeprom_data, self._TLV_CODE_SERIAL_NUMBER) if not is_valid: return "N/A" - return results[2] + return results[2].decode('ascii') def base_mac_addr(self): """ @@ -85,7 +84,7 @@ def base_mac_addr(self): if not is_valid or t[1] != 6: return super(TlvInfoDecoder, self).switchaddrstr(e) - return ":".join([binascii.b2a_hex(T) for T in t[2]]) + return ":".join(["{:02x}".format(T) for T in t[2]]).upper() def modelstr(self): """ @@ -96,7 +95,7 @@ def modelstr(self): if not is_valid: return "N/A" - return results[2] + return results[2].decode('ascii') def part_number_str(self): """ @@ -107,7 +106,7 @@ def part_number_str(self): if not is_valid: return "N/A" - return results[2] + return results[2].decode('ascii') def serial_str(self): """ @@ -118,7 +117,7 @@ def serial_str(self): if not is_valid: return "N/A" - return results[2] + return results[2].decode('ascii') def revision_str(self): """ @@ -129,7 +128,7 @@ def revision_str(self): if not is_valid: return "N/A" - return results[2] + return results[2].decode('ascii') def system_eeprom_info(self): """ diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/fan.py new file mode 100644 index 000000000000..39307d453486 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/fan.py @@ -0,0 +1,174 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC Z9264F +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Fans' information which are available in the platform. +# +######################################################################## + +try: + from sonic_platform_base.fan_base import FanBase + from sonic_platform.ipmihelper import IpmiSensor, IpmiFru +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +#Derived the offset from BMC management information +FAN1_MAX_SPEED_OFFSET = 71 +FAN2_MAX_SPEED_OFFSET = 73 +PSU_FAN_MAX_SPEED_OFFSET = 50 +FAN_DIRECTION_OFFSET = 69 +PSU_FAN_DIRECTION_OFFSET = 47 + + +class Fan(FanBase): + """DellEMC Platform-specific Fan class""" + #Derived the sensor IDs from BMC + # { FAN-ID: { Sensor-Name: Sensor-ID } } + FAN_SENSOR_MAPPING = { 1: {"Prsnt": 0x51, "State": 0x64, "Speed": 0x24}, + 2: {"Prsnt": 0x51, "State": 0x60, "Speed": 0x20}, + 3: {"Prsnt": 0x52, "State": 0x65, "Speed": 0x25}, + 4: {"Prsnt": 0x52, "State": 0x61, "Speed": 0x21}, + 5: {"Prsnt": 0x53, "State": 0x66, "Speed": 0x26}, + 6: {"Prsnt": 0x53, "State": 0x62, "Speed": 0x22}, + 7: {"Prsnt": 0x54, "State": 0x67, "Speed": 0x27}, + 8: {"Prsnt": 0x54, "State": 0x63, "Speed": 0x23} } + PSU_FAN_SENSOR_MAPPING = { 1: {"State": 0x46, "Speed": 0x2e}, + 2: {"State": 0x47, "Speed": 0x2f} } + + # { FANTRAY-ID: FRU-ID } + FAN_FRU_MAPPING = { 1: 1, 2: 2, 3: 3, 4: 4 } + PSU_FRU_MAPPING = { 1: 6, 2: 7 } + + def __init__(self, fantray_index=1, fan_index=1, psu_fan=False, + dependency=None): + self.is_psu_fan = psu_fan + if not self.is_psu_fan: + # API index is starting from 0, DellEMC platform index is + # starting from 1 + self.fantrayindex = fantray_index + 1 + self.fanindex = fan_index + 1 + if (self.fanindex == 1): + self.max_speed_offset = FAN1_MAX_SPEED_OFFSET + else: + self.max_speed_offset = FAN2_MAX_SPEED_OFFSET + self.fan_direction_offset = FAN_DIRECTION_OFFSET + self.index = (self.fantrayindex - 1) * 2 + self.fanindex + self.prsnt_sensor = IpmiSensor(self.FAN_SENSOR_MAPPING[self.index]["Prsnt"], + is_discrete=True) + self.state_sensor = IpmiSensor(self.FAN_SENSOR_MAPPING[self.index]["State"], + is_discrete=True) + self.speed_sensor = IpmiSensor(self.FAN_SENSOR_MAPPING[self.index]["Speed"]) + self.fru = IpmiFru(self.FAN_FRU_MAPPING[self.fantrayindex]) + else: + self.dependency = dependency + self.fanindex = fan_index + self.state_sensor = IpmiSensor(self.PSU_FAN_SENSOR_MAPPING[self.fanindex]["State"], + is_discrete=True) + self.speed_sensor = IpmiSensor(self.PSU_FAN_SENSOR_MAPPING[self.fanindex]["Speed"]) + self.fru = IpmiFru(self.PSU_FRU_MAPPING[self.fanindex]) + self.max_speed_offset = PSU_FAN_MAX_SPEED_OFFSET + self.fan_direction_offset = PSU_FAN_DIRECTION_OFFSET + self.max_speed = self.fru.get_fru_data(self.max_speed_offset,2)[1] + self.max_speed = self.max_speed[1] << 8 | self.max_speed[0] + + def get_name(self): + """ + Retrieves the name of the device + Returns: + String: The name of the device + """ + if self.is_psu_fan: + return "PSU{} Fan".format(self.fanindex) + else: + return "FanTray{}-Fan{}".format(self.fantrayindex, self.fanindex) + + def get_model(self): + """ + Retrieves the part number of the FAN + Returns: + String: Part number of FAN + """ + if self.is_psu_fan: + return 'NA' + else: + return self.fru.get_board_part_number() + + def get_serial(self): + """ + Retrieves the serial number of the FAN + Returns: + String: Serial number of FAN + """ + if self.is_psu_fan: + return 'NA' + else: + return self.fru.get_board_serial() + + def get_presence(self): + """ + Retrieves the presence of the FAN + Returns: + bool: True if fan is present, False if not + """ + presence = False + if self.is_psu_fan: + return self.dependency.get_presence() + else: + is_valid, state = self.prsnt_sensor.get_reading() + if is_valid: + if (state & 0b1): + presence = True + return presence + + def get_status(self): + """ + Retrieves the operational status of the FAN + Returns: + bool: True if FAN is operating properly, False if not + """ + status = False + is_valid, state = self.state_sensor.get_reading() + if is_valid: + if (state == 0x00): + status = True + return status + + def get_direction(self): + """ + Retrieves the fan airfow direction + 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 = [self.FAN_DIRECTION_EXHAUST, self.FAN_DIRECTION_INTAKE] + fan_status = self.get_status() + if not fan_status: + return 'NA' + is_valid, fan_direction = self.fru.get_fru_data(self.fan_direction_offset) + if is_valid: + return direction[fan_direction[0]] + else: + return 'NA' + + def get_speed(self): + """ + Retrieves the speed of the fan + Returns: + int: percentage of the max fan speed + """ + if self.max_speed == 0: + self.max_speed = self.fru.get_fru_data(self.max_speed_offset,2)[1] + self.max_speed = self.max_speed[1] << 8 | self.max_speed[0] + is_valid, fan_speed = self.speed_sensor.get_reading() + if not is_valid or self.max_speed == 0: + speed = 0 + else: + speed = (100 * fan_speed)//self.max_speed + return speed diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/fan_drawer.py new file mode 100644 index 000000000000..6e8acfa720a4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/fan_drawer.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC Z9264F +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Fan-Drawers' information available in the platform. +# +######################################################################## + +try: + from sonic_platform_base.fan_drawer_base import FanDrawerBase + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +Z9264F_FANS_PER_FANTRAY = 2 + + +class FanDrawer(FanDrawerBase): + """DellEMC Platform-specific Fan class""" + + def __init__(self, fantray_index): + + FanDrawerBase.__init__(self) + # FanTray is 1-based in DellEMC platforms + self.fantrayindex = fantray_index + 1 + for i in range(Z9264F_FANS_PER_FANTRAY): + self._fan_list.append(Fan(fantray_index, i)) + + def get_name(self): + """ + Retrieves the fan drawer name + Returns: + string: The name of the device + """ + return "FanTray{}".format(self.fantrayindex) diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/platform.py new file mode 100644 index 000000000000..996d94cf5a6e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/platform.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python + +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PlatformBase): + """ + DELLEMC Platform-specific class + """ + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/psu.py index 374ac2e1c202..d46d24d0cb91 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/psu.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/psu.py @@ -12,6 +12,7 @@ try: from sonic_platform_base.psu_base import PsuBase from sonic_platform.ipmihelper import IpmiSensor, IpmiFru + from sonic_platform.fan import Fan except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -38,6 +39,9 @@ def __init__(self, psu_index): self.power_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["Power"]) self.fru = IpmiFru(self.FRU_MAPPING[self.index]) + self._fan_list.append(Fan(fan_index=self.index, psu_fan=True, + dependency=self)) + def get_name(self): """ Retrieves the name of the device @@ -107,7 +111,7 @@ def get_voltage(self): if not is_valid: voltage = 0 - return "{:.1f}".format(voltage) + return float(voltage) def get_current(self): """ @@ -121,7 +125,7 @@ def get_current(self): if not is_valid: current = 0 - return "{:.1f}".format(current) + return float(current) def get_power(self): """ @@ -135,7 +139,7 @@ def get_power(self): if not is_valid: power = 0 - return "{:.1f}".format(power) + return float(power) def get_powergood_status(self): """ diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/sfp.py index 19c678f0e9df..225aef90e00a 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/sfp.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/sfp.py @@ -66,8 +66,8 @@ 'FibreChannelTechnology', 'SFP+CableTechnology', 'FibreChannelTransmissionMedia', 'FibreChannelSpeed') -info_dict_keys = ['type', 'hardwarerev', 'serialnum', - 'manufacturename', 'modelname', 'Connector', +info_dict_keys = ['type', 'hardware_rev', 'serial', + 'manufacturer', 'model', 'connector', 'encoding', 'ext_identifier', 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance', 'type_abbrv_name','vendor_date', 'vendor_oui'] @@ -106,7 +106,7 @@ 'cable_type': [QSFP_INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], 'cable_length': [QSFP_INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], - 'Connector': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'connector': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'type': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'encoding': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'ext_identifier': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], @@ -116,13 +116,13 @@ 'specification_compliance': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], 'type_abbrv_name': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], - 'manufacturename': [QSFP_INFO_OFFSET, 20, 16, 'parse_vendor_name'], + 'manufacturer': [QSFP_INFO_OFFSET, 20, 16, 'parse_vendor_name'], 'vendor_oui': [QSFP_INFO_OFFSET, 37, 3, 'parse_vendor_oui'], - 'modelname': [QSFP_INFO_OFFSET, 40, 16, 'parse_vendor_pn'], - 'hardwarerev': [QSFP_INFO_OFFSET, 56, 2, 'parse_vendor_rev'], - 'serialnum': [QSFP_INFO_OFFSET, 68, 16, 'parse_vendor_sn'], + 'model': [QSFP_INFO_OFFSET, 40, 16, 'parse_vendor_pn'], + 'hardware_rev': [QSFP_INFO_OFFSET, 56, 2, 'parse_vendor_rev'], + 'serial': [QSFP_INFO_OFFSET, 68, 16, 'parse_vendor_sn'], 'vendor_date': [QSFP_INFO_OFFSET, 84, 8, 'parse_vendor_date'], - 'dom_capability': [QSFP_INFO_OFFSET, 92, 1, 'parse_qsfp_dom_capability'], + 'dom_capability': [QSFP_INFO_OFFSET, 92, 1, 'parse_dom_capability'], 'dom_rev': [QSFP_DOM_OFFSET, 1, 1, 'parse_sfp_dom_rev'], 'ModuleThreshold': [QSFP_DOM_OFFSET1, 128, 24, 'parse_module_threshold_values'], 'ChannelThreshold': [QSFP_DOM_OFFSET1, 176, 16, 'parse_channel_threshold_values'], @@ -135,7 +135,7 @@ 'cable_type': [SFP_INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], 'cable_length': [SFP_INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], - 'Connector': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'connector': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], 'type': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], 'encoding': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], 'ext_identifier': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], @@ -145,11 +145,11 @@ 'specification_compliance': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], 'type_abbrv_name': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], - 'manufacturename': [SFP_INFO_OFFSET, 20, 16, 'parse_vendor_name'], + 'manufacturer': [SFP_INFO_OFFSET, 20, 16, 'parse_vendor_name'], 'vendor_oui': [SFP_INFO_OFFSET, 37, 3, 'parse_vendor_oui'], - 'modelname': [SFP_INFO_OFFSET, 40, 16, 'parse_vendor_pn'], - 'hardwarerev': [SFP_INFO_OFFSET, 56, 4, 'parse_vendor_rev'], - 'serialnum': [SFP_INFO_OFFSET, 68, 16, 'parse_vendor_sn'], + 'model': [SFP_INFO_OFFSET, 40, 16, 'parse_vendor_pn'], + 'hardware_rev': [SFP_INFO_OFFSET, 56, 4, 'parse_vendor_rev'], + 'serial': [SFP_INFO_OFFSET, 68, 16, 'parse_vendor_sn'], 'vendor_date': [SFP_INFO_OFFSET, 84, 8, 'parse_vendor_date'], 'ModuleThreshold': [SFP_DOM_OFFSET, 0, 56, 'parse_alarm_warning_threshold'], } @@ -326,7 +326,7 @@ def get_transceiver_info(self): return transceiver_info_dict # Vendor Name - vendor_name_data = self._get_eeprom_data('manufacturename') + vendor_name_data = self._get_eeprom_data('manufacturer') if (vendor_name_data is not None): vendor_name = vendor_name_data['data']['Vendor Name']['value'] else: @@ -340,21 +340,21 @@ def get_transceiver_info(self): return transceiver_info_dict # Vendor PN - vendor_pn_data = self._get_eeprom_data('modelname') + vendor_pn_data = self._get_eeprom_data('model') if (vendor_pn_data is not None): vendor_pn = vendor_pn_data['data']['Vendor PN']['value'] else: return transceiver_info_dict # Vendor Revision - vendor_rev_data = self._get_eeprom_data('hardwarerev') + vendor_rev_data = self._get_eeprom_data('hardware_rev') if (vendor_rev_data is not None): vendor_rev = vendor_rev_data['data']['Vendor Rev']['value'] else: return transceiver_info_dict # Vendor Serial Number - vendor_sn_data = self._get_eeprom_data('serialnum') + vendor_sn_data = self._get_eeprom_data('serial') if (vendor_sn_data is not None): vendor_sn = vendor_sn_data['data']['Vendor SN']['value'] else: @@ -362,11 +362,11 @@ def get_transceiver_info(self): # Fill The Dictionary and return transceiver_info_dict['type'] = identifier - transceiver_info_dict['hardwarerev'] = vendor_rev - transceiver_info_dict['serialnum'] = vendor_sn - transceiver_info_dict['manufacturename'] = vendor_name - transceiver_info_dict['modelname'] = vendor_pn - transceiver_info_dict['Connector'] = connector + transceiver_info_dict['hardware_rev'] = vendor_rev + transceiver_info_dict['serial'] = vendor_sn + transceiver_info_dict['manufacturer'] = vendor_name + transceiver_info_dict['model'] = vendor_pn + transceiver_info_dict['connector'] = connector transceiver_info_dict['encoding'] = encoding transceiver_info_dict['ext_identifier'] = ext_id transceiver_info_dict['ext_rateselect_compliance'] = rate_identifier @@ -562,7 +562,7 @@ def get_model(self): """ Retrieves the model number (or part number) of the sfp """ - vendor_pn_data = self._get_eeprom_data('modelname') + vendor_pn_data = self._get_eeprom_data('model') if (vendor_pn_data is not None): vendor_pn = vendor_pn_data['data']['Vendor PN']['value'] else: @@ -574,7 +574,7 @@ def get_serial(self): """ Retrieves the serial number of the sfp """ - vendor_sn_data = self._get_eeprom_data('serialnum') + vendor_sn_data = self._get_eeprom_data('serial') if (vendor_sn_data is not None): vendor_sn = vendor_sn_data['data']['Vendor SN']['value'] else: diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/thermal.py index 58a39005b54e..1f3caaa02dd3 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/thermal.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/thermal.py @@ -94,7 +94,7 @@ def get_temperature(self): if not is_valid: temperature = 0 - return "{:.3f}".format(temperature) + return float(temperature) def get_high_threshold(self): """ @@ -105,11 +105,11 @@ def get_high_threshold(self): Celsius up to nearest thousandth of one degree Celsius, e.g. 30.125 """ - is_valid, high_threshold = self.sensor.get_threshold("UpperNonRecoverable") + is_valid, high_threshold = self.sensor.get_threshold("UpperCritical") if not is_valid: high_threshold = 0 - return "{:.3f}".format(high_threshold) + return float(high_threshold) def get_low_threshold(self): """ @@ -124,7 +124,22 @@ def get_low_threshold(self): if not is_valid: low_threshold = 0 - return "{:.3f}".format(low_threshold) + return float(low_threshold) + + def get_high_critical_threshold(self): + """ + Retrieves the high critical threshold temperature of thermal + + Returns: + A float number, the high critical threshold temperature of + thermal in Celsius up to nearest thousandth of one degree + Celsius, e.g. 30.125 + """ + is_valid, high_crit_threshold = self.sensor.get_threshold("UpperNonRecoverable") + if not is_valid: + high_crit_threshold = 0 + + return float(high_crit_threshold) def set_high_threshold(self, temperature): """ diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/watchdog.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/watchdog.py new file mode 100644 index 000000000000..d3363067db63 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/watchdog.py @@ -0,0 +1,214 @@ +#!/usr/bin/env python + +######################################################################## +# +# DELLEMC Z9264f +# +# Abstract base class for implementing a platform-specific class with +# which to interact with a hardware watchdog module in SONiC +# +######################################################################## + +try: + import sys + import struct + import ctypes + import subprocess + from sonic_platform_base.watchdog_base import WatchdogBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class _timespec(ctypes.Structure): + _fields_ = [ + ('tv_sec', ctypes.c_long), + ('tv_nsec', ctypes.c_long) + ] + + +class Watchdog(WatchdogBase): + """ + Abstract base class for interfacing with a hardware watchdog module + """ + + TIMERS = [15,20,30,40,50,60,65,70] + + armed_time = 0 + timeout = 0 + CLOCK_MONOTONIC = 1 + + def __init__(self): + self._librt = ctypes.CDLL('librt.so.1', use_errno=True) + self._clock_gettime = self._librt.clock_gettime + self._clock_gettime.argtypes=[ctypes.c_int, ctypes.POINTER(_timespec)] + + def _get_command_result(self, cmdline): + try: + proc = subprocess.Popen(cmdline.split(), stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + result = stdout.rstrip('\n') + except OSError: + result = None + + return result + + def _get_reg_val(self): + # 0x31 = CPLD I2C Base Address + # 0x07 = Watchdog Function Register + value = self._get_command_result("/usr/sbin/i2cget -y 601 0x31 0x07") + if not value: + return None + else: + return int(value, 16) + + def _set_reg_val(self,val): + # 0x31 = CPLD I2C Base Address + # 0x07 = Watchdog Function Register + value = self._get_command_result("/usr/sbin/i2cset -y 601 0x31 0x07 %s" + % (val)) + return value + + def _get_time(self): + """ + To get clock monotonic time + """ + ts = _timespec() + if self._clock_gettime(self.CLOCK_MONOTONIC, ctypes.pointer(ts)) != 0: + self._errno = ctypes.get_errno() + return 0 + return ts.tv_sec + ts.tv_nsec * 1e-9 + + def arm(self, seconds): + """ + Arm the hardware watchdog with a timeout of seconds. + If the watchdog is currently armed, calling this function will + simply reset the timer to the provided value. If the underlying + hardware does not support the value provided in , this + method should arm the watchdog with the *next greater* + available value. + + Returns: + An integer specifying the *actual* number of seconds the + watchdog was armed with. On failure returns -1. + """ + timer_offset = -1 + for key,timer_seconds in enumerate(self.TIMERS): + if seconds <= timer_seconds: + timer_offset = key + seconds = timer_seconds + break + + if timer_offset == -1: + return -1 + + # Extracting 5th to 7th bits for WD timer values + # 000 - 15 sec + # 001 - 20 sec + # 010 - 30 sec + # 011 - 40 sec + # 100 - 50 sec + # 101 - 60 sec + # 110 - 65 sec + # 111 - 70 sec + reg_val = self._get_reg_val() + wd_timer_offset = (reg_val >> 4) & 0x7 + + if wd_timer_offset != timer_offset: + # Setting 5th to 7th bits + # value from timer_offset + self.disarm() + self._set_reg_val((reg_val & 0x87) | (timer_offset << 4)) + + if self.is_armed(): + # Setting last bit to WD Timer punch + # Last bit = WD Timer punch + self._set_reg_val(reg_val & 0xFE) + + self.armed_time = self._get_time() + self.timeout = seconds + return seconds + else: + # Setting 4th bit to enable WD + # 4th bit = Enable WD + reg_val = self._get_reg_val() + self._set_reg_val(reg_val | 0x8) + + self.armed_time = self._get_time() + self.timeout = seconds + return seconds + + return -1 + + def disarm(self): + """ + Disarm the hardware watchdog + + Returns: + A boolean, True if watchdog is disarmed successfully, False + if not + """ + if self.is_armed(): + # Setting 4th bit to disable WD + # 4th bit = Disable WD + reg_val = self._get_reg_val() + self._set_reg_val(reg_val & 0xF7) + + self.armed_time = 0 + self.timeout = 0 + return True + + return False + + def is_armed(self): + """ + Retrieves the armed state of the hardware watchdog. + + Returns: + A boolean, True if watchdog is armed, False if not + """ + + # Extracting 4th bit to get WD Enable/Disable status + # 0 - Disabled WD + # 1 - Enabled WD + reg_val = self._get_reg_val() + wd_offset = (reg_val >> 3) & 1 + + return bool(wd_offset) + + def get_remaining_time(self): + """ + If the watchdog is armed, retrieve the number of seconds + remaining on the watchdog timer + + Returns: + An integer specifying the number of seconds remaining on + their watchdog timer. If the watchdog is not armed, returns + -1. + + Z9264 doesnot have hardware support to show remaining time. + Due to this limitation, this API is implemented in software. + This API would return correct software time difference if it + is called from the process which armed the watchdog timer. + If this API called from any other process, it would return + 0. If the watchdog is not armed, this API would return -1. + """ + if not self.is_armed(): + return -1 + + if self.armed_time > 0 and self.timeout != 0: + cur_time = self._get_time() + + if cur_time <= 0: + return 0 + + diff_time = int(cur_time - self.armed_time) + + if diff_time > self.timeout: + return self.timeout + else: + return self.timeout - diff_time + + return 0 + diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/systemd/platform-modules-z9264f.service b/platform/broadcom/sonic-platform-modules-dell/z9264f/systemd/platform-modules-z9264f.service index b89f61ea6226..05d920a8502b 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/systemd/platform-modules-z9264f.service +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/systemd/platform-modules-z9264f.service @@ -1,6 +1,6 @@ [Unit] Description=Dell Z9264f Platform modules -Before=pmon.service +Before=pmon.service determine-reboot-cause.service DefaultDependencies=no [Service] diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-switchboard.c b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-switchboard.c index 240580e577a3..dc1cf8874e39 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-switchboard.c +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-switchboard.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include "cls-i2c-ocore.h" #define MOD_VERSION "2.1.0-1" diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/pcisysfs.py b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/pcisysfs.py deleted file mode 100755 index 047618e057c8..000000000000 --- a/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/pcisysfs.py +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/python -# Copyright (c) 2015 Dell Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -# -# THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR -# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT -# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS -# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. -# -# See the Apache Version 2.0 License for specific language governing -# permissions and limitations under the License. - -import struct -import sys -import getopt -from os import * -from mmap import * - -def usage(): - ''' This is the Usage Method ''' - - print '\t\t pcisysfs.py --get --offset --res ' - print '\t\t pcisysfs.py --set --val --offset --res ' - sys.exit(1) - -def pci_mem_read(mm,offset): - mm.seek(offset) - read_data_stream=mm.read(4) - print "" - reg_val=struct.unpack('I',read_data_stream) - print "reg_val read:%x"%reg_val - return reg_val - -def pci_mem_write(mm,offset,data): - mm.seek(offset) - print "data to write:%x"%data - mm.write(struct.pack('I',data)) - -def pci_set_value(resource,val,offset): - fd=open(resource,O_RDWR) - mm=mmap(fd,0) - pci_mem_write(mm,offset,val) - -def pci_get_value(resource,offset): - fd=open(resource,O_RDWR) - mm=mmap(fd,0) - pci_mem_read(mm,offset) - -def main(argv): - - ''' The main function will read the user input from the - command line argument and process the request ''' - - opts = '' - val = '' - choice = '' - resource = '' - offset = '' - - try: - opts, args = getopt.getopt(argv, "hgsv:" , \ - ["val=","res=","offset=","help", "get", "set"]) - - except getopt.GetoptError: - usage() - - for opt,arg in opts: - - if opt in ('-h','--help'): - choice = 'help' - - elif opt in ('-g', '--get'): - choice = 'get' - - elif opt in ('-s', '--set'): - choice = 'set' - - elif opt == '--res': - resource = arg - - elif opt == '--val': - val = int(arg,16) - - elif opt == '--offset': - offset = int(arg,16) - - if choice == 'set' and val != '' and offset !='' and resource !='': - pci_set_value(resource,val,offset) - - elif choice == 'get' and offset != '' and resource !='': - pci_get_value(resource,offset) - - else: - usage() - -#Calling the main method -if __name__ == "__main__": - main(sys.argv[1:]) - diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/platform_sensors.py index 2fd2b84900da..1a5778525db2 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/platform_sensors.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/platform_sensors.py @@ -1,9 +1,9 @@ -#!/usr/bin/python +#!/usr/bin/python3 # On Z9332F, the BaseBoard Management Controller is an # autonomous subsystem provides monitoring and management # facility independent of the host CPU. IPMI standard # protocol is used with ipmitool to fetch sensor details. -# Current script support X00 board only. X01 support will +# Current script support X00 board only. X01 support will # be added soon. This provies support for the # following objects: # * Onboard temperature sensors @@ -11,11 +11,9 @@ # * PSU -import os import sys import logging import subprocess -import commands Z9332F_MAX_FAN_TRAYS = 7 Z9332F_MAX_PSUS = 2 @@ -40,7 +38,7 @@ def ipmi_sensor_dump(): status = 1 global ipmi_sdr_list ipmi_cmd = IPMI_SENSOR_DATA - status, ipmi_sdr_list = commands.getstatusoutput(ipmi_cmd) + status, ipmi_sdr_list = subprocess.getstatusoutput(ipmi_cmd) if status: logging.error('Failed to execute:' + ipmi_sdr_list) @@ -57,7 +55,7 @@ def get_pmc_register(reg_name): output = item.strip() if output is None: - print('\nFailed to fetch: ' + reg_name + ' sensor ') + print('\nFailed to fetch: ' + reg_name + ' sensor ') sys.exit(0) output = output.split('|')[1] @@ -75,7 +73,7 @@ def print_temperature_sensors(): for x in (('TEMP_FAN_U52', 'Fan U52'), ('TEMP_FAN_U17', 'Fan U17'), - ('TEMP_SW_U52', 'SW U52'), + ('TEMP_SW_U52', 'SW U52'), ('TEMP_SW_U16', 'SW U16'), ('TEMP_BB_U3', 'Baseboard U3'), ('TEMP_CPU', 'Near CPU'), @@ -88,7 +86,7 @@ def print_temperature_sensors(): ('SW_U14_Temp', 'SW U14'), ('SW_U4403_Temp', 'SW U4403') ): - print ' {0:32}{1}'.format(x[1] + ':', get_pmc_register(x[0])) + print(' {0:32}{1}'.format(x[1] + ':', get_pmc_register(x[0]))) ipmi_sensor_dump() @@ -102,14 +100,14 @@ def print_fan_tray(tray): Fan_Status = [' Normal', ' Abnormal'] Airflow_Direction = ['B2F', 'F2B'] - print ' Fan Tray ' + str(tray) + ':' + print(' Fan Tray ' + str(tray) + ':') - print ' Fan1 Speed: ',\ - get_pmc_register('Fan{}_Front'.format(tray)) - print ' Fan2 Speed: ',\ - get_pmc_register('Fan{}_Rear'.format(tray)) - print ' Fan State: ',\ - Fan_Status[int(get_pmc_register('Fan{}_Status'.format(tray)), 16)] + print(' Fan1 Speed: ', + get_pmc_register('Fan{}_Front'.format(tray))) + print(' Fan2 Speed: ', + get_pmc_register('Fan{}_Rear'.format(tray))) + print(' Fan State: ', + Fan_Status[int(get_pmc_register('Fan{}_Status'.format(tray)), 16)]) print('\nFan Trays:') @@ -119,7 +117,7 @@ def print_fan_tray(tray): if (get_pmc_register(fan_presence)): print_fan_tray(tray) else: - print '\n Fan Tray ' + str(tray + 1) + ': Not present' + print('\n Fan Tray ' + str(tray + 1) + ': Not present') def get_psu_presence(index): """ @@ -132,9 +130,9 @@ def get_psu_presence(index): ret_status = 1 if index == 1: - status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU1_DATA_DOCKER) + status, ipmi_cmd_ret = subprocess.getstatusoutput(IPMI_PSU1_DATA_DOCKER) elif index == 2: - ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU2_DATA_DOCKER) + ret_status, ipmi_cmd_ret = subprocess.getstatusoutput(IPMI_PSU2_DATA_DOCKER) #if ret_status: # print ipmi_cmd_ret @@ -144,7 +142,7 @@ def get_psu_presence(index): psu_status = ipmi_cmd_ret if psu_status == '1': - status = 1 + status = 1 return status @@ -165,28 +163,28 @@ def print_psu(psu): # print ' Input: ', Psu_Input_Type[psu_input_type] # print ' Type: ', Psu_Type[psu_type] - print ' PSU{}:'.format(psu) - print ' Inlet Temperature: ',\ - get_pmc_register('PSU{}_Temp1'.format(psu)) - print ' Hotspot Temperature: ',\ - get_pmc_register('PSU{}_Temp2'.format(psu)) - print ' FAN RPM: ',\ - get_pmc_register('PSU{}_Fan'.format(psu)) + print(' PSU{}:'.format(psu)) + print(' Inlet Temperature: ', + get_pmc_register('PSU{}_Temp1'.format(psu))) + print(' Hotspot Temperature: ', + get_pmc_register('PSU{}_Temp2'.format(psu))) + print(' FAN RPM: ', + get_pmc_register('PSU{}_Fan'.format(psu))) # print ' FAN Status: ', Psu_Fan_Status[psu1_fan_status] # PSU input & output monitors - print ' Input Voltage: ',\ - get_pmc_register('PSU{}_VIn'.format(psu)) - print ' Output Voltage: ',\ - get_pmc_register('PSU{}_VOut'.format(psu)) - print ' Input Power: ',\ - get_pmc_register('PSU{}_PIn'.format(psu)) - print ' Output Power: ',\ - get_pmc_register('PSU{}_POut'.format(psu)) - print ' Input Current: ',\ - get_pmc_register('PSU{}_CIn'.format(psu)) - print ' Output Current: ',\ - get_pmc_register('PSU{}_COut'.format(psu)) + print(' Input Voltage: ', + get_pmc_register('PSU{}_VIn'.format(psu))) + print(' Output Voltage: ', + get_pmc_register('PSU{}_VOut'.format(psu))) + print(' Input Power: ', + get_pmc_register('PSU{}_PIn'.format(psu))) + print(' Output Power: ', + get_pmc_register('PSU{}_POut'.format(psu))) + print(' Input Current: ', + get_pmc_register('PSU{}_CIn'.format(psu))) + print(' Output Current: ', + get_pmc_register('PSU{}_COut'.format(psu))) print('\nPSUs:') @@ -195,4 +193,4 @@ def print_psu(psu): if (get_psu_presence(psu)): print_psu(psu) else: - print '\n PSU ', psu, 'Not present' + print('\n PSU ', psu, 'Not present') diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/z9332f_platform.sh b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/z9332f_platform.sh index ab2a787a6627..f80207df8ea2 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/z9332f_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/z9332f_platform.sh @@ -58,7 +58,7 @@ switch_board_qsfp() { "new_device") for ((i=10;i<=41;i++)); do - echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 + echo optoe3 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 done ;; @@ -81,7 +81,7 @@ switch_board_sfp() { "new_device") for ((i=1;i<=2;i++)); do - echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 done ;; @@ -99,13 +99,14 @@ switch_board_sfp() { #Modsel 64 ports to applicable QSFP type modules #This enables the adapter to respond for i2c commands +#Low Power mode enabled by default switch_board_modsel() { resource="/sys/bus/pci/devices/0000:09:00.0/resource0" for ((i=1;i<=32;i++)); do port_addr=$(( 16384 + ((i - 1) * 16))) hex=$( printf "0x%x" $port_addr ) - python /usr/bin/pcisysfs.py --set --offset $hex --val 0x10 --res $resource > /dev/null 2>&1 + /usr/bin/pcisysfs.py --set --offset $hex --val 0x50 --res $resource > /dev/null 2>&1 done } @@ -145,13 +146,48 @@ platform_firmware_versions() { ver=`/usr/sbin/i2cget -y 4 0x31 0x0` echo "Switch CPLD 2: $((ver))" >> $FIRMWARE_VERSION_FILE } + +install_python_api_package() { + device="/usr/share/sonic/device" + platform=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) + + rv=$(pip install $device/$platform/sonic_platform-1.0-py2-none-any.whl) + rv=$(pip3 install $device/$platform/sonic_platform-1.0-py3-none-any.whl) +} + +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) + fi + + rv=$(pip3 show sonic-platform > /dev/null 2>/dev/null) + if [ $? -eq 0 ]; then + rv=$(pip3 uninstall -y sonic-platform > /dev/null 2>/dev/null) + fi +} + +get_reboot_cause() { + REBOOT_REASON_FILE="/host/reboot-cause/platform/reboot_reason" + + mkdir -p $(dirname $REBOOT_REASON_FILE) + + # Handle First Boot into software version with reboot cause determination support + if [[ ! -e $REBOOT_REASON_FILE ]]; then + echo "0" > $REBOOT_REASON_FILE + else + /usr/sbin/i2cget -y 5 0x0d 0x06 > $REBOOT_REASON_FILE + fi +} + + init_devnum if [ "$1" == "init" ]; then modprobe i2c-dev modprobe i2c-mux-pca954x force_deselect_on_exit=1 modprobe ipmi_devintf - modprobe ipmi_si + modprobe ipmi_si kipmid_max_busy_us=1000 modprobe cls-i2c-ocore modprobe cls-switchboard modprobe mc24lc64t @@ -160,8 +196,11 @@ if [ "$1" == "init" ]; then switch_board_qsfp "new_device" switch_board_sfp "new_device" switch_board_led_default - # python /usr/bin/qsfp_irq_enable.py + install_python_api_package + # /usr/bin/qsfp_irq_enable.py platform_firmware_versions + get_reboot_cause + echo 1000 > /sys/module/ipmi_si/parameters/kipmid_max_busy_us elif [ "$1" == "deinit" ]; then sys_eeprom "delete_device" @@ -174,6 +213,7 @@ elif [ "$1" == "deinit" ]; then modprobe -r cls-i2c-ocore modprobe -r cls-switchboard modprobe -r mc24lc64t + remove_python_api_package else echo "z9332f_platform : Invalid option !" fi diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/setup.py b/platform/broadcom/sonic-platform-modules-dell/z9332f/setup.py new file mode 120000 index 000000000000..4f6de9941d96 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/setup.py @@ -0,0 +1 @@ +../s6100/setup.py \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/__init__.py new file mode 100755 index 000000000000..4f5d4f6e473d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/__init__.py @@ -0,0 +1,2 @@ +__all__ = ["platform", "chassis", "sfp", "eeprom", "component", "psu", "thermal", "fan", "fan_drawer"] +from sonic_platform import * diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/chassis.py new file mode 100755 index 000000000000..cead0eb326ef --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/chassis.py @@ -0,0 +1,368 @@ +#!/usr/bin/env python + +############################################################################# +# DELLEMC Z9332F +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + import time + import sys + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform.sfp import Sfp + from sonic_platform.eeprom import Eeprom + from sonic_platform.component import Component + from sonic_platform.psu import Psu + from sonic_platform.thermal import Thermal + from sonic_platform.fan_drawer import FanDrawer + from sonic_platform.watchdog import Watchdog + import sonic_platform.hwaccess as hwaccess +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +MAX_Z9332F_FANTRAY = 7 +MAX_Z9332F_FAN = 2 +MAX_Z9332F_PSU = 2 +MAX_Z9332F_THERMAL = 14 +MAX_Z9332F_COMPONENT = 6 # BIOS,FPGA,BMC,BB CPLD and 2 Switch CPLDs + +media_part_num_list = set([ \ +"8T47V","XTY28","MHVPK","GF76J","J6FGD","F1KMV","9DN5J","H4DHD","6MCNV","0WRX0","X7F70","5R2PT","WTRD1","WTRD1","WTRD1","WTRD1","5250G","WTRD1","C5RNH","C5RNH","FTLX8571D3BCL-FC", +"C5RNH","5250G","N8TDR","7D64H","7D64H","RN84N","RN84N","HMTNW","6K3Y6","6K3Y6","TY5FM","50M0R","PGYJT","WP2PP","85Y13","1HCGH","FP9R1","FYD0M","C6Y7M","C6Y7M","V250M","V250M", +"5CWK6","5CWK6","53HVN","53HVN","358VV","358VV","MV799","MV799","YJF03","P9GND","T1KCN","1DXKP","MT7R2","K0T7R","W5G04","7TCDN","7TCDN","7TCDN","7TCDN","7TCDN","V3XJK","0MV31", +"5FVP7","N6KM9","C41MF","77KC3","XW7J0","V4NJV","2XJHY","H93DH","H93DH","F8CG0","F8CG0","F8CG0","119N6","WFMF5","794RX","288F6","1M31V","1M31V","5NP8R","5NP8R","4TC09","4TC09", +"FC6KV","FC6KV","J90VN","J90VN","05RH0","05RH0","YDN52","0C2YV","YDN52","0C2YV","9JT65","D7M6H","6GW14","FYVFW","0VF5H","P4YPY","P4YPY","TCPM2","TCPM2","JNPF8","JNPF8","27GG5", +"27GG5","P8T4W","P8T4W","JR54Y","M6N0J","XJYD0","K44H9","035KG","P7C7N","76V43","3CC35","FN4FC","26FN3","YFNDD","YFNDD","7R9N9","035KG","P7C7N","76V43","3CC35","PLRXPLSCS43811", +"FN4FC","26FN3","YFNDD","YFNDD","7R9N9","G86YJ","V407F","V407F","9KH6T","G86YJ","V407F","9KH6T","2JVDD","D0R73","VXFJY","9X8JP","2JVDD","D0R73","VXFJY","9X8JP","2JVDD","D0R73","VXFJY", +"9X8JP","GMFC5","GMFC5","GMFC5","D7P80","3MFXG","3MFXG","0GWXJ","THPF3","THPF3","THPF3","THPF3","THPF3","PJ62G","3XCX1","JJYKG","RRRTK","16K56","86JM2","K5R6C","7MG2C","WTPPN","9HTT2", +"NKM4F","VXGGG","JC9W6","6MR8M","RP3GV","M5PPJ","XKY55","TKCXT","05J8P","5WGKD","XFDRT","NW8DM","YPKH3","5WGKD","XFDRT","NW8DM","YPKH3","71XXK","MVCX6","0XYP6","HPPVW","3GHRT","71XXK", +"MVCX6","0XYP6","HPPVW","3GHRT","2X5T6","135V2","KD5MV","2X5T6","KD5MV","HHFK0","3YWG7","5CMT2","RCVP5","X5DH4","HHFK0","3YWG7","5CMT2","RCVP5","X5DH4","3YWG7","5CMT2","RCVP5","X5DH4", +"4WJ41","4WJ41","14NV5","14NV5","14NV5","4WGYD","YKMH7","X7CCC","X7CCC","0X9CT","0CY8V","P7D7R","W4GPP","W4GPP","W4GPP","HHHCHC","07RN7","07RN7","0YR96","0YR96","JCYM9","FTLX8571D3BCL", +"DDW0X","VPFDJ","229KM","9FC7D","DDW0X","VPFDJ","6FMR5","J7K20","N3K9W","6FMR5","8R4VM","7VN5T","D9YM8","8R4VM","VYXPW","87TPX","WY6FK","VYXPW","87TPX","WY6FK","WG8C4","N8K82","2DV6Y", +"77C3C","RC0HM","77C3C","RC0HM","JHXTN","3P3PG","92YVM","4VX5M","4VX5M","6RRGD","W4JWV","22V6R","XR11M","9GMDY","JMCWK","TP2F0","6MGDY","78RHK", "C0TP5","0WDNV","FCLF8522P2BTL"\ +]) + +class Chassis(ChassisBase): + """ + DELLEMC Platform-specific Chassis class + """ + + REBOOT_CAUSE_PATH = "/host/reboot-cause/platform/reboot_reason" + oir_fd = -1 + epoll = -1 + io_res = "/dev/port" + sysled_offset = 0xA162 + SYSLED_COLOR_TO_REG = { + "green": 0xd0, + "yellow": 0xe0, + "flash_green": 0xd2, + "flash_yellow": 0xe2 + } + + REG_TO_SYSLED_COLOR = { + 0xd0 : "green", + 0xe0 : "yellow", + 0xd2 : "flash_green", + 0xd1 : "flash_green", + 0xe2 : "flash_yellow", + 0xe1 : "flash_yellow" + } + + _global_port_pres_dict = {} + _port_to_i2c_mapping = { + 1: 10, + 2: 11, + 3: 12, + 4: 13, + 5: 14, + 6: 15, + 7: 16, + 8: 17, + 9: 18, + 10: 19, + 11: 20, + 12: 21, + 13: 22, + 14: 23, + 15: 24, + 16: 25, + 17: 26, + 18: 27, + 19: 28, + 20: 29, + 21: 30, + 22: 31, + 23: 32, + 24: 33, + 25: 34, + 26: 35, + 27: 36, + 28: 37, + 29: 38, + 30: 39, + 31: 40, + 32: 41, + 33: 1, + 34: 2, + } + + def __init__(self): + ChassisBase.__init__(self) + # sfp.py will read eeprom contents and retrive the eeprom data. + # We pass the eeprom path from chassis.py + self.PORT_START = 1 + self.PORT_END = 34 + self.PORTS_IN_BLOCK = (self.PORT_END + 1) + _sfp_port = range(33, self.PORTS_IN_BLOCK) + eeprom_base = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" + for index in range(self.PORT_START, self.PORTS_IN_BLOCK): + eeprom_path = eeprom_base.format(self._port_to_i2c_mapping[index]) + port_type = 'SFP' if index in _sfp_port else 'QSFP' + sfp_node = Sfp(index, port_type, eeprom_path) + self._sfp_list.append(sfp_node) + + self._eeprom = Eeprom() + self._watchdog = Watchdog() + for i in range(MAX_Z9332F_FANTRAY): + fandrawer = FanDrawer(i) + self._fan_drawer_list.append(fandrawer) + self._fan_list.extend(fandrawer._fan_list) + + self._num_sfps = self.PORT_END + self._num_fans = MAX_Z9332F_FANTRAY * MAX_Z9332F_FAN + self._psu_list = [Psu(i) for i in range(MAX_Z9332F_PSU)] + self._thermal_list = [Thermal(i) for i in range(MAX_Z9332F_THERMAL)] + self._component_list = [Component(i) for i in range(MAX_Z9332F_COMPONENT)] + for port_num in range(self.PORT_START, self.PORTS_IN_BLOCK): + # sfp get uses zero-indexing, but port numbers start from 1 + presence = self.get_sfp(port_num).get_presence() + self._global_port_pres_dict[port_num] = '1' if presence else '0' + + self._watchdog = Watchdog() + def __del__(self): + if self.oir_fd != -1: + self.epoll.unregister(self.oir_fd.fileno()) + self.epoll.close() + self.oir_fd.close() + +# check for this event change for sfp / do we need to handle timeout/sleep + + def get_change_event(self, timeout=0): + """ + Returns a nested dictionary containing all devices which have + experienced a change at chassis level + """ + start_ms = time.time() * 1000 + port_dict = {} + change_dict = {} + change_dict['sfp'] = port_dict + while True: + time.sleep(0.5) + for port_num in range(self.PORT_START, (self.PORT_END + 1)): + presence = self.get_sfp(port_num).get_presence() + 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, change_dict + + if timeout: + now_ms = time.time() * 1000 + if (now_ms - start_ms >= timeout): + return True, change_dict + + + def get_sfp(self, index): + """ + Retrieves sfp represented by (0-based) index + + Args: + index: An integer, the index (0-based) of the sfp to retrieve. + The index should be the sequence of a physical port in a chassis, + starting from 0. + For example, 0 for Ethernet0, 1 for Ethernet4 and so on. + + Returns: + An object dervied from SfpBase representing the specified sfp + """ + sfp = None + + try: + # The index will start from 0 + sfp = self._sfp_list[index-1] + except IndexError: + sys.stderr.write("SFP index {} out of range (0-{})\n".format( + index, len(self._sfp_list))) + return sfp + + def get_name(self): + """ + Retrieves the name of the chassis + Returns: + string: The name of the chassis + """ + return self._eeprom.modelstr() + + def get_presence(self): + """ + Retrieves the presence of the chassis + Returns: + bool: True if chassis is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the chassis + Returns: + string: Model/part number of chassis + """ + return self._eeprom.part_number_str() + + def get_serial(self): + """ + Retrieves the serial number of the chassis (Service tag) + Returns: + string: Serial number of chassis + """ + return self._eeprom.serial_str() + + def get_status(self): + """ + Retrieves the operational status of the chassis + Returns: + bool: A boolean value, True if chassis is operating properly + False if not + """ + return True + + def get_base_mac(self): + """ + Retrieves the base MAC address for the chassis + Returns: + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' + """ + return self._eeprom.base_mac_addr() + + def get_serial_number(self): + """ + Retrieves the hardware serial number for the chassis + Returns: + A string containing the hardware serial number for this chassis. + """ + return self._eeprom.serial_number_str() + + def get_system_eeprom_info(self): + """ + Retrieves the full content of system EEPROM information for the chassis + Returns: + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their corresponding + values. + """ + return self._eeprom.system_eeprom_info() + + def get_eeprom(self): + """ + Retrieves the Sys Eeprom instance for the chassis. + Returns : + The instance of the Sys Eeprom + """ + return self._eeprom + + def get_num_fans(self): + """ + Retrives the number of Fans on the chassis. + Returns : + An integer represents the number of Fans on the chassis. + """ + return self._num_fans + + def get_num_sfps(self): + """ + Retrives the numnber of Media on the chassis. + Returns: + An integer represences the number of SFPs on the chassis. + """ + return self._num_sfps + + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + Returns: + A tuple (string, string) where the first element is a string + containing the cause of the previous reboot. This string must be + one of the predefined strings in this class. If the first string + is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used + to pass a description of the reboot cause. + """ + try: + with open(self.REBOOT_CAUSE_PATH) as fd: + reboot_cause = int(fd.read(), 16) + except EnvironmentError: + return (self.REBOOT_CAUSE_NON_HARDWARE, None) + + if reboot_cause & 0x1: + return (self.REBOOT_CAUSE_POWER_LOSS, None) + elif reboot_cause & 0x2: + return (self.REBOOT_CAUSE_NON_HARDWARE, None) + elif reboot_cause & 0x44: + return (self.REBOOT_CAUSE_HARDWARE_OTHER, "CPU warm reset") + elif reboot_cause & 0x8: + return (self.REBOOT_CAUSE_THERMAL_OVERLOAD_CPU, None) + elif reboot_cause & 0x66: + return (self.REBOOT_CAUSE_WATCHDOG, None) + elif reboot_cause & 0x55: + return (self.REBOOT_CAUSE_HARDWARE_OTHER, "CPU cold reset") + elif reboot_cause & 0x11: + return (self.REBOOT_CAUSE_HARDWARE_OTHER, "Power on reset") + elif reboot_cause & 0x77: + return (self.REBOOT_CAUSE_HARDWARE_OTHER, "Power Cycle reset") + else: + return (self.REBOOT_CAUSE_NON_HARDWARE, None) + + + def get_qualified_media_list(self): + return media_part_num_list + + def initizalize_system_led(self): + self.sys_ledcolor = "green" + + def get_status_led(self): + """ + Gets the current system LED color + + Returns: + A string that represents the supported color + """ + val = hwaccess.io_reg_read(self.io_res, self.sysled_offset) + if val != -1: + return self.REG_TO_SYSLED_COLOR.get(val) + return self.sys_ledcolor + + def set_status_led(self, color): + """ + Set system LED status based on the color type passed in the argument. + Argument: Color to be set + Returns: + bool: True is specified color is set, Otherwise return False + """ + + if color not in list(self.SYSLED_COLOR_TO_REG.keys()): + return False + + if(not hwaccess.io_reg_write(self.io_res, self.sysled_offset, self.SYSLED_COLOR_TO_REG[color])): + return False + self.sys_ledcolor = color + return True + diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/component.py new file mode 100644 index 000000000000..58c944cd6eb3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/component.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python + +######################################################################## +# DELLEMC Z9332F +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Components' (e.g., BIOS, CPLD, FPGA, BMC etc.) available in +# the platform +# +######################################################################## + +try: + import subprocess + from sonic_platform_base.component_base import ComponentBase + import sonic_platform.hwaccess as hwaccess + +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +def get_bios_version(): + return subprocess.check_output(['dmidecode', '-s', 'bios-version']).strip() + +def get_fpga_version(): + val = hwaccess.pci_get_value('/sys/bus/pci/devices/0000:09:00.0/resource0', 0) + return '{}.{}'.format((val >> 8) & 0xff, val & 0xff) + +def get_bmc_version(): + return subprocess.check_output( + ['cat', '/sys/class/ipmi/ipmi0/device/bmc/firmware_revision'] + ).strip() + +def get_cpld_version(bus, i2caddr): + return '{}'.format(hwaccess.i2c_get(bus, i2caddr, 0)) + +def get_cpld0_version(): + return get_cpld_version(5, 0x0d) + +def get_cpld1_version(): + return get_cpld_version(4, 0x30) + +def get_cpld2_version(): + return get_cpld_version(4, 0x31) + + + +class Component(ComponentBase): + """DellEMC Platform-specific Component class""" + + CHASSIS_COMPONENTS = [ + ['BIOS', + 'Performs initialization of hardware components during booting', + get_bios_version + ], + + ['FPGA', + 'Used for managing the system LEDs', + get_fpga_version + ], + + ['BMC', + 'Platform management controller for on-board temperature monitoring,in-chassis power, Fan and LED control', + get_bmc_version + ], + + ['Baseboard CPLD', + 'Used for managing the CPU power sequence and CPU states', + get_cpld0_version + ], + + ['Switch CPLD 1', + 'Used for managing QSFP28/SFP port transceivers ', + get_cpld1_version + ], + + ['Switch CPLD 2', + 'Used for managing QSFP28/SFP port transceivers', + get_cpld2_version + ] + + ] + + def __init__(self, component_index = 0): + self.index = component_index + self.name = self.CHASSIS_COMPONENTS[self.index][0] + self.description = self.CHASSIS_COMPONENTS[self.index][1] + self.version = self.CHASSIS_COMPONENTS[self.index][2]() + + def get_name(self): + """ + Retrieves the name of the component + Returns: + A string containing the name of the component + """ + return self.name + + def get_description(self): + """ + Retrieves the description of the component + Returns: + A string containing the description of the component + """ + return self.description + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + Returns: + A string containing the firmware version of the component + """ + return self.version + + 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 + """ + return False diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/eeprom.py new file mode 100644 index 000000000000..eda04ae3bd8e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/eeprom.py @@ -0,0 +1,139 @@ +#!/usr/bin/env python + +############################################################################# +# DellEmc Z9332F +# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# + +try: + import os.path + from sonic_eeprom import eeprom_tlvinfo +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self): + self.eeprom_path = None + for b in (0, 1): + f = '/sys/class/i2c-adapter/i2c-{0}/{0}-0056/eeprom'.format(b) + if os.path.exists(f): + self.eeprom_path = f + break + if self.eeprom_path is None: + return + super(Eeprom, self).__init__(self.eeprom_path, 0, '', True) + self.eeprom_tlv_dict = dict() + try: + self.eeprom_data = self.read_eeprom() + except: + self.eeprom_data = "N/A" + raise RuntimeError("Eeprom is not Programmed") + else: + eeprom = self.eeprom_data + + if not self.is_valid_tlvinfo_header(eeprom): + return + + total_length = (eeprom[9] << 8) | eeprom[10] + tlv_index = self._TLV_INFO_HDR_LEN + tlv_end = self._TLV_INFO_HDR_LEN + total_length + + while (tlv_index + 2) < len(eeprom) and tlv_index < tlv_end: + if not self.is_valid_tlv(eeprom[tlv_index:]): + break + + tlv = eeprom[tlv_index:tlv_index + 2 + + eeprom[tlv_index + 1]] + code = "0x%02X" % tlv[0] + + if tlv[0] == self._TLV_CODE_VENDOR_EXT: + value = str((tlv[2] << 24) | (tlv[3] << 16) | + (tlv[4] << 8) | tlv[5]) + value += tlv[6:6 + tlv[1]].decode('ascii') + else: + name, value = self.decoder(None, tlv) + + self.eeprom_tlv_dict[code] = value + if eeprom[tlv_index] == self._TLV_CODE_CRC_32: + break + + tlv_index += eeprom[tlv_index+1] + 2 + + def serial_number_str(self): + """ + Returns the serial number + """ + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_SERIAL_NUMBER) + if not is_valid: + return "N/A" + return results[2].decode('ascii') + + def base_mac_addr(self): + """ + Returns the base mac address found in the system EEPROM + """ + (is_valid, t) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_MAC_BASE) + if not is_valid or t[1] != 6: + return super(TlvInfoDecoder, self).switchaddrstr(e) + + return ":".join(["{:02x}".format(T) for T in t[2]]).upper() + + def modelstr(self): + """ + Returns the Model name + """ + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_PRODUCT_NAME) + if not is_valid: + return "N/A" + + return results[2].decode('ascii') + + def part_number_str(self): + """ + Returns the part number + """ + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_PART_NUMBER) + if not is_valid: + return "N/A" + + return results[2].decode('ascii') + + def serial_str(self): + """ + Returns the servicetag number + """ + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_SERVICE_TAG) + if not is_valid: + return "N/A" + + return results[2].decode('ascii') + + def revision_str(self): + """ + Returns the device revision + """ + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_DEVICE_VERSION) + if not is_valid: + return "N/A" + + return results[2].decode('ascii') + + def system_eeprom_info(self): + """ + Returns a dictionary, where keys are the type code defined in + ONIE EEPROM format and values are their corresponding values + found in the system EEPROM. + """ + return self.eeprom_tlv_dict diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/fan.py new file mode 100755 index 000000000000..ff7a08bdd1ad --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/fan.py @@ -0,0 +1,171 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC Z9332F +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Fans' information which are available in the platform. +# +######################################################################## +try: + from sonic_platform_base.fan_base import FanBase + from sonic_platform.ipmihelper import IpmiSensor, IpmiFru, get_ipmitool_raw_output +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +class Fan(FanBase): + """DellEMC Platform-specific Fan class""" + # { FAN-ID: { Sensor-Name: Sensor-ID } } + FAN_SENSOR_MAPPING = { 1: {"Prsnt": 0x6, "State": 0x6, "Speed": 0xd}, + 2: {"Prsnt": 0x6, "State": 0x6, "Speed": 0x45}, + 3: {"Prsnt": 0x7, "State": 0x7, "Speed": 0xe}, + 4: {"Prsnt": 0x7, "State": 0x7, "Speed": 0x46}, + 5: {"Prsnt": 0x8, "State": 0x8, "Speed": 0xf}, + 6: {"Prsnt": 0x8, "State": 0x8, "Speed": 0x47}, + 7: {"Prsnt": 0x9, "State": 0x9, "Speed": 0x10}, + 8: {"Prsnt": 0x9, "State": 0x9, "Speed": 0x48}, + 9: {"Prsnt": 0xa, "State": 0xa, "Speed": 0x11}, + 10: {"Prsnt": 0xa, "State": 0xa, "Speed": 0x49}, + 11: {"Prsnt": 0xb, "State": 0xb, "Speed": 0x12}, + 12: {"Prsnt": 0xb, "State": 0xb, "Speed": 0x4a}, + 13: {"Prsnt": 0xc, "State": 0xc, "Speed": 0x13}, + 14: {"Prsnt": 0xc, "State": 0xc, "Speed": 0x4b} } + PSU_FAN_SENSOR_MAPPING = { 1: {"State": 0x2f, "Speed": 0x33}, + 2: {"State": 0x39, "Speed": 0x3d} } + + # { FANTRAY-ID: FRU-ID } + FAN_FRU_MAPPING = { 1: 6, 2: 7, 3: 8, 4: 9, 5: 10, 6: 11, 7: 12 } + PSU_FRU_MAPPING = { 1: 3, 2: 4 } + + def __init__(self, fantray_index=1, fan_index=1, psu_fan=False, dependency=None): + self.is_psu_fan = psu_fan + if not self.is_psu_fan: + # API index is starting from 0, DellEMC platform index is + # starting from 1 + self.fantrayindex = fantray_index + 1 + self.fanindex = fan_index + 1 + self.index = (self.fantrayindex - 1) * 2 + self.fanindex + self.prsnt_sensor = IpmiSensor(self.FAN_SENSOR_MAPPING[self.index]["Prsnt"], + is_discrete=True) + self.state_sensor = IpmiSensor(self.FAN_SENSOR_MAPPING[self.index]["State"], + is_discrete=True) + self.speed_sensor = IpmiSensor(self.FAN_SENSOR_MAPPING[self.index]["Speed"]) + self.fru = IpmiFru(self.FAN_FRU_MAPPING[self.fantrayindex]) + self.fan_dir_raw_cmd = "0x3a 0x0a {}".format(fantray_index) + else: + self.dependency = dependency + self.fanindex = fan_index + self.state_sensor = IpmiSensor(self.PSU_FAN_SENSOR_MAPPING[self.fanindex]["State"], + is_discrete=True) + self.speed_sensor = IpmiSensor(self.PSU_FAN_SENSOR_MAPPING[self.fanindex]["Speed"]) + self.fru = IpmiFru(self.PSU_FRU_MAPPING[self.fanindex]) + self.fan_dir_raw_cmd = "0x3a 0x0a {}".format(7+(fan_index-1)) + self.max_speed = 23500 + + def get_name(self): + """ + Retrieves the name of the device + Returns: + String: The name of the device + """ + if self.is_psu_fan: + return "PSU{} Fan".format(self.fanindex) + else: + return "FanTray{}-Fan{}".format(self.fantrayindex, self.fanindex) + + def get_model(self): + """ + Retrieves the part number of the FAN + Returns: + String: Part number of FAN + """ + if self.is_psu_fan: + return None + else: + return self.fru.get_board_part_number() + + def get_serial(self): + """ + Retrieves the serial number of the FAN + Returns: + String: Serial number of FAN + """ + if self.is_psu_fan: + return None + else: + return self.fru.get_board_serial() + + def get_presence(self): + """ + Retrieves the presence of the FAN + Returns: + bool: True if fan is present, False if not + """ + presence = False + if self.is_psu_fan: + return self.dependency.get_presence() + else: + is_valid, state = self.prsnt_sensor.get_reading() + if is_valid: + if (state & 0b1): + presence = True + return presence + + def get_status(self): + """ + Retrieves the operational status of the FAN + Returns: + bool: True if FAN is operating properly, False if not + """ + status = False + is_valid, state = self.state_sensor.get_reading() + if is_valid: + if state & 0b1: + status = True + return status + + def get_direction(self): + """ + Retrieves the fan airfow direction + 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 = [self.FAN_DIRECTION_EXHAUST, self.FAN_DIRECTION_INTAKE] + fan_status = self.get_presence() + if not fan_status: + return None + dir_res = get_ipmitool_raw_output(self.fan_dir_raw_cmd) + if dir_res is not None and len(dir_res) == 1 : + return direction[dir_res[0]] + else: + return None + + def get_speed(self): + """ + Retrieves the speed of the fan + Returns: + int: percentage of the max fan speed + """ + if self.max_speed == 0: + self.max_speed = 23500 + is_valid, fan_speed = self.speed_sensor.get_reading() + if not is_valid or self.max_speed == 0: + return None + else: + speed = (100 * fan_speed)/self.max_speed + return speed + + def get_speed_rpm(self): + """ + Retrieves the speed of the fan + Returns: + int: percentage of the max fan speed + """ + is_valid, fan_speed = self.speed_sensor.get_reading() + return fan_speed if is_valid else None diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/fan_drawer.py new file mode 100644 index 000000000000..0fdc80e651ed --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/fan_drawer.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC Z9332F +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Fan-Drawers' information available in the platform. +# +######################################################################## + +try: + from sonic_platform_base.fan_drawer_base import FanDrawerBase + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +Z9332F_FANS_PER_FANTRAY = 2 + + +class FanDrawer(FanDrawerBase): + """DellEMC Platform-specific Fan class""" + + def __init__(self, fantray_index): + + FanDrawerBase.__init__(self) + # FanTray is 1-based in DellEMC platforms + self.fantrayindex = fantray_index + 1 + for i in range(Z9332F_FANS_PER_FANTRAY): + self._fan_list.append(Fan(fantray_index, i)) + + def get_name(self): + """ + Retrieves the fan drawer name + Returns: + string: The name of the device + """ + return "FanTray{}".format(self.fantrayindex) diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/hwaccess.py b/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/hwaccess.py new file mode 120000 index 000000000000..e8fa340a444d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/hwaccess.py @@ -0,0 +1 @@ +../../common/sonic_platform/hwaccess.py \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/platform.py new file mode 100644 index 000000000000..996d94cf5a6e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/platform.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python + +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PlatformBase): + """ + DELLEMC Platform-specific class + """ + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/psu.py new file mode 100644 index 000000000000..0d06c31fcf8f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/psu.py @@ -0,0 +1,214 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC Z9332F +# +# Module contains an implementation of SONiC Platform Base API and +# provides the PSUs' information which are available in the platform +# +######################################################################## + +try: + from sonic_platform_base.psu_base import PsuBase + from sonic_platform.ipmihelper import IpmiSensor, IpmiFru, get_ipmitool_raw_output + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Psu(PsuBase): + """DellEMC Platform-specific PSU class""" + + # { PSU-ID: { Sensor-Name: Sensor-ID } } + SENSOR_MAPPING = { 1: { "State": 0x2f, "Current": 0x37, + "Power": 0x38, "Voltage": 0x36, + "Temperature": 0x35 }, + 2: { "State": 0x39, "Current": 0x41, + "Power": 0x42, "Voltage": 0x40, + "Temperature": 0x3F } } + # ( PSU-ID: FRU-ID } + FRU_MAPPING = { 1: 3, 2: 4 } + + def __init__(self, psu_index): + PsuBase.__init__(self) + # PSU is 1-based in DellEMC platforms + self.index = psu_index + 1 + self.state_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["State"], + is_discrete=True) + self.voltage_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["Voltage"]) + self.current_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["Current"]) + self.power_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["Power"]) + self.temp_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index ]["Temperature"]) + self.fru = IpmiFru(self.FRU_MAPPING[self.index]) + self.psu_type_raw_cmd = "0x3A 0x0B {}".format(psu_index+1) + + self._fan_list.append(Fan(fan_index=self.index, psu_fan=True, dependency=self)) + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + return "PSU{}".format(self.index) + + def get_presence(self): + """ + Retrieves the presence of the Power Supply Unit (PSU) + + Returns: + bool: True if PSU is present, False if not + """ + presence = False + is_valid, state = self.state_sensor.get_reading() + if is_valid: + if state & 0b1: + presence = True + + return presence + + def get_model(self): + """ + Retrieves the part number of the PSU + + Returns: + string: Part number of PSU + """ + return self.fru.get_board_part_number() + + def get_serial(self): + """ + Retrieves the serial number of the PSU + + Returns: + string: Serial number of PSU + """ + return self.fru.get_board_serial() + + def get_status(self): + """ + Retrieves the operational status of the PSU + + Returns: + bool: True if PSU is operating properly, False if not + """ + status = False + is_valid, state = self.state_sensor.get_reading() + if is_valid: + if (state & 0b1010) == 0: + status = True + + return status + + def get_voltage(self): + """ + Retrieves current PSU voltage output + + Returns: + A float number, the output voltage in volts, + e.g. 12.1 + """ + is_valid, voltage = self.voltage_sensor.get_reading() + if not is_valid: + return None + + return "{:.1f}".format(voltage) + + def get_voltage_low_threshold(self): + """ + Returns PSU low threshold in Volts + """ + return 11.4 + + def get_voltage_high_threshold(self): + """ + Returns PSU high threshold in Volts + """ + return 12.6 + + def get_temperature(self): + """ + Retrieves current temperature reading from thermal + + Returns: + A float number of current temperature in Celsius up to + nearest thousandth of one degree Celsius, e.g. 30.125 + """ + is_valid, temperature = self.temp_sensor.get_reading() + if not is_valid: + temperature = 0 + + return float(temperature) + + def get_temperature_high_threshold(self): + """ + Returns the high temperature threshold for PSU in Celsius + """ + return 45.0 + + def get_current(self): + """ + Retrieves present electric current supplied by PSU + + Returns: + A float number, electric current in amperes, + e.g. 15.4 + """ + is_valid, current = self.current_sensor.get_reading() + if not is_valid: + return None + + return "{:.1f}".format(current) + + def get_power(self): + """ + Retrieves current energy supplied by PSU + + Returns: + A float number, the power in watts, + e.g. 302.6 + """ + is_valid, power = self.power_sensor.get_reading() + if not is_valid: + return None + + return "{:.1f}".format(power) + + def get_powergood_status(self): + """ + Retrieves the powergood status of PSU + + Returns: + A boolean, True if PSU has stablized its output voltages and + passed all its internal self-tests, False if not. + """ + status = False + is_valid, state = self.state_sensor.get_reading() + if is_valid: + if (state & 0b1010) == 0: + status = True + + return status + + def get_mfr_id(self): + """ + Retrives the Manufacturer Id of PSU + + Returns: + A string, the manunfacturer id. + """ + return self.fru.get_board_mfr_id() + + def get_type(self): + """ + Retrives the Power Type of PSU + + Returns : + A string, PSU power type + """ + psu_type = [None, 'AC', 'AC', 'DC'] + type_res = get_ipmitool_raw_output(self.psu_type_raw_cmd) + if type_res is not None and len(type_res) == 1 : + return psu_type[type_res[0]] + return None diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/sfp.py new file mode 100644 index 000000000000..ef6a2c5d339a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/sfp.py @@ -0,0 +1,1030 @@ +#!/usr/bin/env python + +############################################################################# +# DELLEMC Z9332F +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + import os + import time + import subprocess + import struct + import mmap + from sonic_platform_base.sfp_base import SfpBase + from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom + from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom + from sonic_platform_base.sonic_sfp.sff8472 import sffbase + +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +# Enabled when ext_media is available +#ext_media_module = None +#try: +# import ext_media_api as ext_media_module +#except : +# ext_media_module = None +# pass + +PAGE_OFFSET = 0 +KEY_OFFSET = 1 +KEY_WIDTH = 2 +FUNC_NAME = 3 + +QSFP_INFO_OFFSET = 128 +QSFP_DOM_OFFSET = 0 +QSFP_DOM_OFFSET1 = 384 + +SFP_INFO_OFFSET = 0 +SFP_DOM_OFFSET = 256 + +SFP_STATUS_CONTROL_OFFSET = 110 +SFP_STATUS_CONTROL_WIDTH = 7 +SFP_TX_DISABLE_HARD_BIT = 7 +SFP_TX_DISABLE_SOFT_BIT = 6 + +qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', 'Length OM2(m)', + 'Length OM1(m)', 'Length Cable Assembly(m)') + +qsfp_compliance_code_tup = ( + '10/40G Ethernet Compliance Code', + 'SONET Compliance codes', + 'SAS/SATA compliance codes', + 'Gigabit Ethernet Compliant codes', + 'Fibre Channel link length/Transmitter Technology', + 'Fibre Channel transmission media', + 'Fibre Channel Speed') + +sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)', + 'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)', + 'LengthOM3(UnitsOf10m)', 'LengthCable(UnitsOfm)') + +sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode', + 'ESCONComplianceCodes', 'SONETComplianceCodes', + 'EthernetComplianceCodes', 'FibreChannelLinkLength', + 'FibreChannelTechnology', 'SFP+CableTechnology', + 'FibreChannelTransmissionMedia', 'FibreChannelSpeed') + +info_dict_keys = ['type', 'hardware_rev', 'serial', + 'manufacturer', 'model', 'connector', + 'encoding', 'ext_identifier', 'ext_rateselect_compliance', + 'cable_type', 'cable_length', 'nominal_bit_rate', + 'specification_compliance', 'type_abbrv_name','vendor_date', 'vendor_oui'] + +dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', + 'power_lpmode', 'tx_disable', 'tx_disable_channel', + 'temperature', 'voltage', 'rx1power', + 'rx2power', 'rx3power', 'rx4power', + 'tx1bias', 'tx2bias', 'tx3bias', + 'tx4bias', 'tx1power', 'tx2power', + 'tx3power', 'tx4power'] + +threshold_dict_keys = ['temphighalarm', 'temphighwarning', + 'templowalarm', 'templowwarning', + 'vcchighalarm', 'vcchighwarning', + 'vcclowalarm', 'vcclowwarning', + 'rxpowerhighalarm', 'rxpowerhighwarning', + 'rxpowerlowalarm', 'rxpowerlowwarning', + 'txpowerhighalarm', 'txpowerhighwarning', + 'txpowerlowalarm', 'txpowerlowwarning', + 'txbiashighalarm', 'txbiashighwarning', + 'txbiaslowalarm', 'txbiaslowwarning'] + +sff8436_parser = { + 'reset_status': [QSFP_DOM_OFFSET, 2, 1, 'parse_dom_status_indicator'], + 'rx_los': [QSFP_DOM_OFFSET, 3, 1, 'parse_dom_tx_rx_los'], + 'tx_fault': [QSFP_DOM_OFFSET, 4, 1, 'parse_dom_tx_fault'], + 'tx_disable': [QSFP_DOM_OFFSET, 86, 1, 'parse_dom_tx_disable'], + 'power_lpmode': [QSFP_DOM_OFFSET, 93, 1, 'parse_dom_power_control'], + 'power_override': [QSFP_DOM_OFFSET, 93, 1, 'parse_dom_power_control'], + 'Temperature': [QSFP_DOM_OFFSET, 22, 2, 'parse_temperature'], + 'Voltage': [QSFP_DOM_OFFSET, 26, 2, 'parse_voltage'], + 'ChannelMonitor': [QSFP_DOM_OFFSET, 34, 16, 'parse_channel_monitor_params'], + 'ChannelMonitor_TxPower': + [QSFP_DOM_OFFSET, 34, 24, 'parse_channel_monitor_params_with_tx_power'], + + 'cable_type': [QSFP_INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], + 'cable_length': [QSFP_INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], + 'connector': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'type': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'encoding': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'ext_identifier': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'ext_rateselect_compliance': + [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'nominal_bit_rate': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'specification_compliance': + [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'type_abbrv_name': [QSFP_INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'manufacturer': [QSFP_INFO_OFFSET, 20, 16, 'parse_vendor_name'], + 'vendor_oui': [QSFP_INFO_OFFSET, 37, 3, 'parse_vendor_oui'], + 'model': [QSFP_INFO_OFFSET, 40, 16, 'parse_vendor_pn'], + 'hardware_rev': [QSFP_INFO_OFFSET, 56, 2, 'parse_vendor_rev'], + 'serial': [QSFP_INFO_OFFSET, 68, 16, 'parse_vendor_sn'], + 'vendor_date': [QSFP_INFO_OFFSET, 84, 8, 'parse_vendor_date'], + 'dom_capability': [QSFP_INFO_OFFSET, 92, 1, 'parse_dom_capability'], + 'dom_rev': [QSFP_DOM_OFFSET, 1, 1, 'parse_sfp_dom_rev'], + 'ModuleThreshold': [QSFP_DOM_OFFSET1, 128, 24, 'parse_module_threshold_values'], + 'ChannelThreshold': [QSFP_DOM_OFFSET1, 176, 16, 'parse_channel_threshold_values'], +} + +sff8472_parser = { + 'Temperature': [SFP_DOM_OFFSET, 96, 2, 'parse_temperature'], + 'Voltage': [SFP_DOM_OFFSET, 98, 2, 'parse_voltage'], + 'ChannelMonitor': [SFP_DOM_OFFSET, 100, 6, 'parse_channel_monitor_params'], + + 'cable_type': [SFP_INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], + 'cable_length': [SFP_INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], + 'connector': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'type': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'encoding': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'ext_identifier': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'ext_rateselect_compliance': + [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'nominal_bit_rate': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'specification_compliance': + [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'type_abbrv_name': [SFP_INFO_OFFSET, 0, 21, 'parse_sfp_info_bulk'], + 'manufacturer': [SFP_INFO_OFFSET, 20, 16, 'parse_vendor_name'], + 'vendor_oui': [SFP_INFO_OFFSET, 37, 3, 'parse_vendor_oui'], + 'model': [SFP_INFO_OFFSET, 40, 16, 'parse_vendor_pn'], + 'hardware_rev': [SFP_INFO_OFFSET, 56, 4, 'parse_vendor_rev'], + 'serial': [SFP_INFO_OFFSET, 68, 16, 'parse_vendor_sn'], + 'vendor_date': [SFP_INFO_OFFSET, 84, 8, 'parse_vendor_date'], + 'ModuleThreshold': [SFP_DOM_OFFSET, 0, 56, 'parse_alarm_warning_threshold'], +} +MEDIA_TYPE_OFFSET = 0 +MEDIA_TYPE_WIDTH = 1 + +SFP_TYPE_LIST = [ + '03' # SFP/SFP+/SFP28 and later +] +QSFP_TYPE_LIST = [ + '0c', # QSFP + '0d', # QSFP+ or later + '11' # QSFP28 or later +] +QSFP_DD_TYPE_LIST = [ + '18' #QSFP-DD Type +] +OSFP_TYPE_LIST=[ + '19' # OSFP 8X Type +] + + + +class Sfp(SfpBase): + """ + DELLEMC Platform-specific Sfp class + """ + BASE_RES_PATH = "/sys/bus/pci/devices/0000:09:00.0/resource0" + _port_to_i2c_mapping = { + 1: 10, + 2: 11, + 3: 12, + 4: 13, + 5: 14, + 6: 15, + 7: 16, + 8: 17, + 9: 18, + 10: 19, + 11: 20, + 12: 21, + 13: 22, + 14: 23, + 15: 24, + 16: 25, + 17: 26, + 18: 27, + 19: 28, + 20: 29, + 21: 30, + 22: 31, + 23: 32, + 24: 33, + 25: 34, + 26: 35, + 27: 36, + 28: 37, + 29: 38, + 30: 39, + 31: 40, + 32: 41, + 33: 1, + 34: 2 + } + + def __init__(self, index, sfp_type, eeprom_path): + SfpBase.__init__(self) + self.index = index + self.eeprom_path = eeprom_path + #sfp_type is the native port type and media_type is the transceiver type + #media_type will be detected in get_transceiver_info + self.sfp_type = sfp_type + self.media_type = self.sfp_type + self.qsfpInfo = sff8436InterfaceId() + self.qsfpDomInfo = sff8436Dom() + self.sfpInfo = sff8472InterfaceId() + self.sfpDomInfo = sff8472Dom(None,1) + + def get_eeprom_sysfs_path(self): + return self.eeprom_path + + def pci_mem_read(self, mm, offset): + mm.seek(offset) + read_data_stream = mm.read(4) + reg_val = struct.unpack('I', read_data_stream) + mem_val = str(reg_val)[1:-2] + # print "reg_val read:%x"%reg_val + return mem_val + + def pci_mem_write(self, mm, offset, data): + mm.seek(offset) + # print "data to write:%x"%data + mm.write(struct.pack('I', data)) + + def pci_set_value(self, resource, val, offset): + fd = os.open(resource, os.O_RDWR) + mm = mmap.mmap(fd, 0) + val = self.pci_mem_write(mm, offset, val) + mm.close() + os.close(fd) + return val + + def pci_get_value(self, resource, offset): + fd = os.open(resource, os.O_RDWR) + mm = mmap.mmap(fd, 0) + val = self.pci_mem_read(mm, offset) + mm.close() + os.close(fd) + return val + + def _read_eeprom_bytes(self, eeprom_path, offset, num_bytes): + eeprom_raw = [] + try: + eeprom = open(eeprom_path, mode="rb", buffering=0) + except IOError: + return None + + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + try: + eeprom.seek(offset) + raw = eeprom.read(num_bytes) + except IOError: + eeprom.close() + return None + + try: + for n in range(0, num_bytes): + eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + except BaseException: + eeprom.close() + return None + + eeprom.close() + return eeprom_raw + + def _get_eeprom_data(self, eeprom_key): + eeprom_data = None + page_offset = None + + if(self.media_type == 'QSFP' or self.media_type == 'QSFP-DD'): + page_offset = sff8436_parser[eeprom_key][PAGE_OFFSET] + eeprom_data_raw = self._read_eeprom_bytes( + self.eeprom_path, + (sff8436_parser[eeprom_key][PAGE_OFFSET] + + sff8436_parser[eeprom_key][KEY_OFFSET]), + sff8436_parser[eeprom_key][KEY_WIDTH]) + if (eeprom_data_raw is not None): + # Offset 128 is used to retrieve sff8436InterfaceId Info + # Offset 0 is used to retrieve sff8436Dom Info + if (page_offset == 128): + if ( self.qsfpInfo is None): + return None + eeprom_data = getattr( + self.qsfpInfo, sff8436_parser[eeprom_key][FUNC_NAME])( + eeprom_data_raw, 0) + else: + if ( self.qsfpDomInfo is None): + return None + eeprom_data = getattr( + self.qsfpDomInfo, sff8436_parser[eeprom_key][FUNC_NAME])( + eeprom_data_raw, 0) + else: + page_offset = sff8472_parser[eeprom_key][PAGE_OFFSET] + eeprom_data_raw = self._read_eeprom_bytes( + self.eeprom_path, + (sff8472_parser[eeprom_key][PAGE_OFFSET] + + sff8472_parser[eeprom_key][KEY_OFFSET]), + sff8472_parser[eeprom_key][KEY_WIDTH]) + if (eeprom_data_raw is not None): + # Offset 0 is used to retrieve sff8472InterfaceId Info + # Offset 256 is used to retrieve sff8472Dom Info + if (page_offset == 0): + if ( self.sfpInfo is None): + return None + eeprom_data = getattr( + self.sfpInfo, sff8472_parser[eeprom_key][FUNC_NAME])( + eeprom_data_raw, 0) + else: + if ( self.sfpDomInfo is None): + return None + eeprom_data = getattr( + self.sfpDomInfo, sff8472_parser[eeprom_key][FUNC_NAME])( + eeprom_data_raw, 0) + + return eeprom_data + + def get_transceiver_info(self): + """ + Retrieves transceiver info of this SFP + """ + transceiver_info_dict = {} + compliance_code_dict = {} + transceiver_info_dict = dict.fromkeys(info_dict_keys, 'N/A') + self.media_type = self.set_media_type() + self.reinit_sfp_driver() + + # BaseInformation + try: + iface_data = self._get_eeprom_data('type') + connector = iface_data['data']['Connector']['value'] + encoding = iface_data['data']['EncodingCodes']['value'] + ext_id = iface_data['data']['Extended Identifier']['value'] + rate_identifier = iface_data['data']['RateIdentifier']['value'] + identifier = iface_data['data']['type']['value'] + type_abbrv_name=iface_data['data']['type_abbrv_name']['value'] + if(self.media_type == 'QSFP' or self.media_type == 'QSFP-DD'): + bit_rate = str( + iface_data['data']['Nominal Bit Rate(100Mbs)']['value']) + for key in qsfp_compliance_code_tup: + if key in iface_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = iface_data['data']['Specification compliance']['value'][key]['value'] + for key in qsfp_cable_length_tup: + if key in iface_data['data']: + cable_type = key + cable_length = str(iface_data['data'][key]['value']) + else: + bit_rate = str( + iface_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) + for key in sfp_compliance_code_tup: + if key in iface_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = iface_data['data']['Specification compliance']['value'][key]['value'] + for key in sfp_cable_length_tup: + if key in iface_data['data']: + cable_type = key + cable_length = str(iface_data['data'][key]['value']) + + transceiver_info_dict['type_abbrv_name']=type_abbrv_name + transceiver_info_dict['type'] = identifier + transceiver_info_dict['connector'] = connector + transceiver_info_dict['encoding'] = encoding + transceiver_info_dict['ext_identifier'] = ext_id + transceiver_info_dict['ext_rateselect_compliance'] = rate_identifier + transceiver_info_dict['cable_type'] = cable_type + transceiver_info_dict['cable_length'] = cable_length + transceiver_info_dict['nominal_bit_rate'] = bit_rate + transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) + except (ValueError, TypeError) : pass + + # Vendor Date + try: + vendor_date_data = self._get_eeprom_data('vendor_date') + vendor_date = vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] + transceiver_info_dict['vendor_date'] = vendor_date + except (ValueError, TypeError) : pass + + # Vendor Name + try: + vendor_name_data = self._get_eeprom_data('manufacturer') + vendor_name = vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['manufacturer'] = vendor_name + except (ValueError, TypeError) : pass + + # Vendor OUI + try: + vendor_oui_data = self._get_eeprom_data('vendor_oui') + vendor_oui = vendor_oui_data['data']['Vendor OUI']['value'] + transceiver_info_dict['vendor_oui'] = vendor_oui + except (ValueError, TypeError) : pass + + # Vendor PN + try: + vendor_pn_data = self._get_eeprom_data('model') + vendor_pn = vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['model'] = vendor_pn + except (ValueError, TypeError) : pass + + # Vendor Revision + try: + vendor_rev_data = self._get_eeprom_data('hardware_rev') + vendor_rev = vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['hardware_rev'] = vendor_rev + except (ValueError, TypeError) : pass + + # Vendor Serial Number + try: + vendor_sn_data = self._get_eeprom_data('serial') + vendor_sn = vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['serial'] = vendor_sn + except (ValueError, TypeError) : pass + + # Attempt ext_media read +# if ext_media_module is not None: +# ext_media_dict = ext_media_module.get_ext_media_info(self) +# for key in ext_media_dict: +# value = ext_media_dict[key] +# if value in [None, 'None', 'none','n/a', '']: +# value = 'N/A' +# transceiver_info_dict[key] = str(value) + + return transceiver_info_dict + + def get_transceiver_threshold_info(self): + """ + Retrieves transceiver threshold info of this SFP + """ + transceiver_dom_threshold_dict = {} + transceiver_dom_threshold_dict = dict.fromkeys( + threshold_dict_keys, 'N/A') + + try: + # Module Threshold + module_threshold_data = self._get_eeprom_data('ModuleThreshold') + if (self.media_type == 'QSFP' or self.media_type == 'QSFP-DD'): + transceiver_dom_threshold_dict['temphighalarm'] = module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_dict['temphighwarning'] = module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_dict['templowalarm'] = module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_dict['templowwarning'] = module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_dict['vcchighalarm'] = module_threshold_data['data']['VccHighAlarm']['value'] + transceiver_dom_threshold_dict['vcchighwarning'] = module_threshold_data['data']['VccHighWarning']['value'] + transceiver_dom_threshold_dict['vcclowalarm'] = module_threshold_data['data']['VccLowAlarm']['value'] + transceiver_dom_threshold_dict['vcclowwarning'] = module_threshold_data['data']['VccLowWarning']['value'] + else: #SFP + transceiver_dom_threshold_dict['temphighalarm'] = module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_dict['templowalarm'] = module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_dict['temphighwarning'] = module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_dict['templowwarning'] = module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_dict['vcchighalarm'] = module_threshold_data['data']['VoltageHighAlarm']['value'] + transceiver_dom_threshold_dict['vcclowalarm'] = module_threshold_data['data']['VoltageLowAlarm']['value'] + transceiver_dom_threshold_dict['vcchighwarning'] = module_threshold_data['data']['VoltageHighWarning']['value'] + transceiver_dom_threshold_dict['vcclowwarning'] = module_threshold_data['data']['VoltageLowWarning']['value'] + transceiver_dom_threshold_dict['txbiashighalarm'] = module_threshold_data['data']['BiasHighAlarm']['value'] + transceiver_dom_threshold_dict['txbiaslowalarm'] = module_threshold_data['data']['BiasLowAlarm']['value'] + transceiver_dom_threshold_dict['txbiashighwarning'] = module_threshold_data['data']['BiasHighWarning']['value'] + transceiver_dom_threshold_dict['txbiaslowwarning'] = module_threshold_data['data']['BiasLowWarning']['value'] + transceiver_dom_threshold_dict['txpowerhighalarm'] = module_threshold_data['data']['TXPowerHighAlarm']['value'] + transceiver_dom_threshold_dict['txpowerlowalarm'] = module_threshold_data['data']['TXPowerLowAlarm']['value'] + transceiver_dom_threshold_dict['txpowerhighwarning'] = module_threshold_data['data']['TXPowerHighWarning']['value'] + transceiver_dom_threshold_dict['txpowerlowwarning'] = module_threshold_data['data']['TXPowerLowWarning']['value'] + transceiver_dom_threshold_dict['rxpowerhighalarm'] = module_threshold_data['data']['RXPowerHighAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerlowalarm'] = module_threshold_data['data']['RXPowerLowAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerhighwarning'] = module_threshold_data['data']['RXPowerHighWarning']['value'] + transceiver_dom_threshold_dict['rxpowerlowwarning'] = module_threshold_data['data']['RXPowerLowWarning']['value'] + except (ValueError, TypeError) : pass + + try: + if (self.media_type == 'QSFP' or self.media_type == 'QSFP-DD'): + channel_threshold_data = self._get_eeprom_data('ChannelThreshold') + transceiver_dom_threshold_dict['rxpowerhighalarm'] = channel_threshold_data['data']['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerhighwarning'] = channel_threshold_data['data']['RxPowerHighWarning']['value'] + transceiver_dom_threshold_dict['rxpowerlowalarm'] = channel_threshold_data['data']['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerlowwarning'] = channel_threshold_data['data']['RxPowerLowWarning']['value'] + transceiver_dom_threshold_dict['txbiashighalarm'] = channel_threshold_data['data']['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_dict['txbiashighwarning'] = channel_threshold_data['data']['TxBiasHighWarning']['value'] + transceiver_dom_threshold_dict['txbiaslowalarm'] = channel_threshold_data['data']['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_dict['txbiaslowwarning'] = channel_threshold_data['data']['TxBiasLowWarning']['value'] + + except (ValueError, TypeError) : pass + return transceiver_dom_threshold_dict + + def get_transceiver_bulk_status(self): + """ + Retrieves transceiver bulk status of this SFP + """ + tx_bias_list = [] + rx_power_list = [] + transceiver_dom_dict = {} + transceiver_dom_dict = dict.fromkeys(dom_dict_keys, 'N/A') + + # RxLos + rx_los = self.get_rx_los() + + # TxFault + tx_fault = self.get_tx_fault() + + # ResetStatus + reset_state = self.get_reset_status() + + # LowPower Mode + lp_mode = self.get_lpmode() + + # TxDisable + tx_disable = self.get_tx_disable() + + # TxDisable Channel + tx_disable_channel = self.get_tx_disable_channel() + + # Temperature + temperature = self.get_temperature() + + # Voltage + voltage = self.get_voltage() + + # Channel Monitor + tx_power_list = self.get_tx_power() + + # tx bias + tx_bias_list = self.get_tx_bias() + + # rx power + rx_power_list = self.get_rx_power() + + if tx_bias_list is not None: + transceiver_dom_dict['tx1bias'] = tx_bias_list[0] + transceiver_dom_dict['tx2bias'] = tx_bias_list[1] + transceiver_dom_dict['tx3bias'] = tx_bias_list[2] + transceiver_dom_dict['tx4bias'] = tx_bias_list[3] + + if rx_power_list is not None: + transceiver_dom_dict['rx1power'] = rx_power_list[0] + transceiver_dom_dict['rx2power'] = rx_power_list[1] + transceiver_dom_dict['rx3power'] = rx_power_list[2] + transceiver_dom_dict['rx4power'] = rx_power_list[3] + + if tx_power_list is not None: + transceiver_dom_dict['tx1power'] = tx_power_list[0] + transceiver_dom_dict['tx2power'] = tx_power_list[1] + transceiver_dom_dict['tx3power'] = tx_power_list[2] + transceiver_dom_dict['tx4power'] = tx_power_list[3] + + transceiver_dom_dict['rx_los'] = rx_los + transceiver_dom_dict['tx_fault'] = tx_fault + transceiver_dom_dict['reset_status'] = reset_state + transceiver_dom_dict['power_lpmode'] = lp_mode + transceiver_dom_dict['tx_disable'] = tx_disable + transceiver_dom_dict['tx_disable_channel'] = tx_disable_channel + transceiver_dom_dict['temperature'] = temperature + transceiver_dom_dict['voltage'] = voltage + + return transceiver_dom_dict + + def get_name(self): + """ + Retrieves the name of the sfp + Returns : QSFP or QSFP+ or QSFP28 + """ + try: + iface_data = self._get_eeprom_data('type') + identifier = iface_data['data']['type']['value'] + except (TypeError, ValueError): + return 'N/A' + return identifier + + def get_presence(self): + """ + Retrieves the presence of the sfp + Returns : True if sfp is present and false if it is absent + """ + # Check for invalid port_num + mask = {'QSFP' : (1 << 4), 'SFP' : (1 << 0)} + # Port offset starts with 0x4004 + port_offset = 16388 + ((self.index-1) * 16) + + try: + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + # ModPrsL is active low + if reg_value & mask[self.sfp_type] == 0: + return True + except ValueError: pass + + return False + + def get_model(self): + """ + Retrieves the model number (or part number) of the sfp + """ + try: + vendor_pn_data = self._get_eeprom_data('model') + vendor_pn = vendor_pn_data['data']['Vendor PN']['value'] + except (TypeError, ValueError): + return 'N/A' + + return vendor_pn + + def get_serial(self): + """ + Retrieves the serial number of the sfp + """ + try: + vendor_sn_data = self._get_eeprom_data('serial') + vendor_sn = vendor_sn_data['data']['Vendor SN']['value'] + except (TypeError, ValueError): + return 'N/A' + + return vendor_sn + + def get_reset_status(self): + """ + Retrives the reset status of SFP + """ + reset_status = False + try: + if (self.sfp_type == 'QSFP'): + # Port offset starts with 0x4000 + port_offset = 16384 + ((self.index-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Mask off 4th bit for reset status + mask = (1 << 4) + reset_status = not (reg_value & mask) + except ValueError: pass + + return reset_status + + def get_rx_los(self): + """ + Retrieves the RX LOS (lost-of-signal) status of SFP + """ + rx_los = False + try: + if (self.media_type == 'QSFP' or self.media_type == 'QSFP-DD'): + rx_los_data = self._get_eeprom_data('rx_los') + # As the function expects a single boolean, if any one channel experience LOS, + # is considered LOS for QSFP + for rx_los_id in ('Rx1LOS', 'Rx2LOS', 'Rx3LOS', 'Rx4LOS') : + rx_los |= (rx_los_data['data'][rx_los_id]['value'] is 'On') + else: + rx_los_data = self._read_eeprom_bytes(self.eeprom_path, SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + data = int(rx_los_data[0], 16) + rx_los = sffbase().test_bit(data, 1) != 0 + except (TypeError, ValueError): + return 'N/A' + return rx_los + + def get_tx_fault(self): + """ + Retrieves the TX fault status of SFP + """ + tx_fault = False + try: + if (self.media_type == 'QSFP' or self.media_type == 'QSFP-DD'): + tx_fault_data = self._get_eeprom_data('tx_fault') + for tx_fault_id in ('Tx1Fault', 'Tx2Fault', 'Tx3Fault', 'Tx4Fault') : + tx_fault |= (tx_fault_data['data'][tx_fault_id]['value'] is 'On') + else: + tx_fault_data = self._read_eeprom_bytes(self.eeprom_path, SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + data = int(tx_fault_data[0], 16) + tx_fault = (sffbase().test_bit(data, 2) != 0) + except (TypeError, ValueError): + return 'N/A' + return tx_fault + + def get_tx_disable(self): + """ + Retrieves the tx_disable status of this SFP + """ + tx_disable = False + try: + if (self.media_type == 'QSFP' or self.media_type == 'QSFP-DD'): + tx_disable_data = self._get_eeprom_data('tx_disable') + for tx_disable_id in ('Tx1Disable', 'Tx2Disable', 'Tx3Disable', 'Tx4Disable'): + tx_disable |= (tx_disable_data['data'][tx_disable_id]['value'] is 'On') + else: + tx_disable_data = self._read_eeprom_bytes(self.eeprom_path, SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + data = int(tx_disable_data[0], 16) + tx_disable_hard = (sffbase().test_bit(data, SFP_TX_DISABLE_HARD_BIT) != 0) + tx_disable_soft = (sffbase().test_bit(data, SFP_TX_DISABLE_SOFT_BIT) != 0) + tx_disable = tx_disable_hard | tx_disable_soft + except (TypeError, ValueError): + return 'N/A' + return tx_disable + + def get_tx_disable_channel(self): + """ + Retrieves the TX disabled channels in this SFP + """ + tx_disable_channel = 0 + try: + if (self.media_type == 'QSFP' or self.media_type == 'QSFP-DD'): + tx_disable_data = self._get_eeprom_data('tx_disable') + for tx_disable_id in ('Tx1Disable', 'Tx2Disable', 'Tx3Disable', 'Tx4Disable'): + tx_disable_channel <<= 1 + tx_disable_channel |= (tx_disable_data['data']['Tx1Disable']['value'] is 'On') + except (TypeError, ValueError): + return 'N/A' + return tx_disable_channel + + def get_lpmode(self): + """ + Retrieves the lpmode(low power mode) of this SFP + """ + lpmode_state = False + try: + if (self.media_type == 'QSFP' or self.media_type == 'QSFP-DD'): + # Port offset starts with 0x4000 + port_offset = 16384 + ((self.index-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Mask off 6th bit for lpmode + mask = (1 << 6) + + lpmode_state = (reg_value & mask) + except ValueError: pass + return lpmode_state + + def get_power_override(self): + """ + Retrieves the power-override status of this SFP + """ + power_override_state = False + + try: + if (self.media_type == 'QSFP' or self.media_type == 'QSFP-DD'): + power_override_data = self._get_eeprom_data('power_override') + power_override = power_override_data['data']['PowerOverRide']['value'] + power_override_state = (power_override is 'On') + except (TypeError, ValueError): pass + return power_override_state + + def get_temperature(self): + """ + Retrieves the temperature of this SFP + """ + temperature = None + try : + temperature_data = self._get_eeprom_data('Temperature') + temperature = temperature_data['data']['Temperature']['value'] + except (TypeError, ValueError): + return None + return temperature + + def get_voltage(self): + """ + Retrieves the supply voltage of this SFP + """ + voltage = None + try: + voltage_data = self._get_eeprom_data('Voltage') + voltage = voltage_data['data']['Vcc']['value'] + except (TypeError, ValueError): + return None + return voltage + + def get_tx_bias(self): + """ + Retrieves the TX bias current of this SFP + """ + tx_bias_list = [] + try: + tx_bias_data = self._get_eeprom_data('ChannelMonitor') + if (self.media_type == 'QSFP' or self.media_type == 'QSFP-DD'): + for tx_bias_id in ('TX1Bias', 'TX2Bias', 'TX3Bias', 'TX4Bias') : + tx_bias = tx_bias_data['data'][tx_bias_id]['value'] + tx_bias_list.append(tx_bias) + else: + tx1_bias = tx_bias_data['data']['TXBias']['value'] + tx_bias_list = [tx1_bias, "N/A", "N/A", "N/A"] + except (TypeError, ValueError): + return None + return tx_bias_list + + def get_rx_power(self): + """ + Retrieves the received optical power for this SFP + """ + rx_power_list = [] + try: + rx_power_data = self._get_eeprom_data('ChannelMonitor') + if (self.media_type == 'QSFP' or self.media_type == 'QSFP-DD'): + for rx_power_id in ('RX1Power', 'RX2Power', 'RX3Power', 'RX4Power'): + rx_power = rx_power_data['data'][rx_power_id]['value'] + rx_power_list.append(rx_power) + else: + rx1_pw = rx_power_data['data']['RXPower']['value'] + rx_power_list = [rx1_pw, "N/A", "N/A", "N/A"] + except (TypeError, ValueError): + return None + return rx_power_list + + def get_tx_power(self): + """ + Retrieves the TX power of this SFP + """ + tx_power_list = [] + try: + if(self.media_type == 'QSFP' or self.media_type == 'QSFP-DD'): + # 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. + qspf_dom_capability_data = self._get_eeprom_data('dom_capability') + qsfp_dom_rev_data = self._get_eeprom_data('dom_rev') + qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value'] + qsfp_tx_power_support = qspf_dom_capability_data['data']['Tx_power_support']['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. + if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')): + return None + channel_monitor_data = self._get_eeprom_data('ChannelMonitor_TxPower') + for tx_power_id in ('TX1Power', 'TX2Power', 'TX3Power', 'TX4Power'): + tx_pw = channel_monitor_data['data'][tx_power_id]['value'] + tx_power_list.append(tx_pw) + else: + channel_monitor_data = self._get_eeprom_data('ChannelMonitor') + tx1_pw = channel_monitor_data['data']['TXPower']['value'] + tx_power_list = [tx1_pw, 'N/A', 'N/A', 'N/A'] + except (TypeError, ValueError): + return None + return tx_power_list + + def reset(self): + """ + Reset the SFP and returns all user settings to their default state + """ + try: + if (self.sfp_type == 'QSFP'): + # Port offset starts with 0x4000 + port_offset = 16384 + ((self.index-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Mask off 4th bit for reset + mask = (1 << 4) + + # ResetL is active low + reg_value = reg_value & ~mask + + # Convert our register value back to a hex string and write back + self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + + # Sleep 1 second to allow it to settle + time.sleep(1) + + reg_value = reg_value | mask + + # Convert our register value back to a hex string and write back + self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + except ValueError: + return False + return True + + def set_lpmode(self, lpmode): + """ + Sets the lpmode(low power mode) of this SFP + """ + try: + if (self.sfp_type == 'QSFP'): + # Port offset starts with 0x4000 + port_offset = 16384 + ((self.index-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Mask off 6th bit for lowpower mode + mask = (1 << 6) + + # LPMode is active high; set or clear the bit accordingly + if lpmode is True: + reg_value = reg_value | mask + else: + reg_value = reg_value & ~mask + + # Convert our register value back to a hex string and write back + self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + except ValueError: + return False + return True + + def get_intl_state(self): + """ + Sets the intL (interrupt; active low) pin of this SFP + """ + intl_state = True + try: + if (self.sfp_type == 'QSFP'): + # Port offset starts with 0x4004 + port_offset = 16388 + ((self.index-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Mask off 4th bit for intL + mask = (1 << 4) + + intl_state = (reg_value & mask) + except ValueError: pass + return intl_state + + def tx_disable(self, tx_disable): + """ + Disable SFP TX for all channels + """ + return False + + def tx_disable_channel(self, channel, disable): + """ + Sets the tx_disable for specified SFP channels + """ + return False + + def set_power_override(self, power_override, power_set): + """ + Sets SFP power level using power_override and power_set + """ + return False + + def get_status(self): + """ + Retrieves the operational status of the device + """ + reset = self.get_reset_status() + return (not reset) + + def get_port_form_factor(self): + """ + Retrieves the native port type + """ + return self.sfp_type + + def get_max_port_power(self): + """ + Retrieves the maximum power allowed on the port in watts + + *** + This method of fetching power values is not ideal. + TODO: enhance by placing power limits in config file + *** + """ + return (12.0 if self.sfp_type=='QSFP' else 2.5) + + def set_media_type(self): + """ + Reads optic eeprom byte to determine media type inserted + """ + eeprom_raw = [] + eeprom_raw = self._read_eeprom_bytes(self.eeprom_path, MEDIA_TYPE_OFFSET, MEDIA_TYPE_WIDTH) + if eeprom_raw is not None: + if eeprom_raw[0] in SFP_TYPE_LIST: + self.media_type = 'SFP' + elif eeprom_raw[0] in QSFP_TYPE_LIST: + self.media_type = 'QSFP' + elif eeprom_raw[0] in QSFP_DD_TYPE_LIST: + self.media_type = 'QSFP-DD' + else: + #Set native port type if EEPROM type is not recognized/readable + self.media_type = self.sfp_type + else: + self.media_type = self.sfp_type + + return self.media_type + + def reinit_sfp_driver(self): + """ + Changes the driver based on media type detected + """ + del_sfp_path = "/sys/class/i2c-adapter/i2c-{0}/delete_device".format(self._port_to_i2c_mapping[self.index]) + new_sfp_path = "/sys/class/i2c-adapter/i2c-{0}/new_device".format(self._port_to_i2c_mapping[self.index]) + driver_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/name".format(self._port_to_i2c_mapping[self.index]) + delete_device = "echo 0x50 >" + del_sfp_path + + try: + with os.fdopen(os.open(driver_path, os.O_RDONLY)) as fd: + driver_name = fd.read() + driver_name = driver_name.rstrip('\r\n') + driver_name = driver_name.lstrip(" ") + + #Avoid re-initialization of the QSFP/SFP optic on QSFP/SFP port. + if (self.media_type == 'SFP' and (driver_name == 'optoe1' or driver_name == 'optoe3')): + subprocess.Popen(delete_device, shell=True, stdout=subprocess.PIPE) + new_device = "echo optoe2 0x50 >" + new_sfp_path + subprocess.Popen(new_device, shell=True, stdout=subprocess.PIPE) + time.sleep(2) + elif (self.media_type == 'QSFP' and (driver_name == 'optoe2' or driver_name == 'optoe3')): + subprocess.Popen(delete_device, shell=True, stdout=subprocess.PIPE) + new_device = "echo optoe1 0x50 >" + new_sfp_path + subprocess.Popen(new_device, shell=True, stdout=subprocess.PIPE) + time.sleep(2) + elif (self.media_type == 'QSFP-DD' and (driver_name == 'optoe1' or driver_name == 'optoe2')): + subprocess.Popen(delete_device, shell=True, stdout=subprocess.PIPE) + new_device = "echo optoe3 0x50 >" + new_sfp_path + subprocess.Popen(new_device, shell=True, stdout=subprocess.PIPE) + time.sleep(2) + + except IOError as e: + print("Error: Unable to open file: %s" % str(e)) diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/thermal.py new file mode 100644 index 000000000000..86d5f9492d50 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/thermal.py @@ -0,0 +1,176 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC Z9332F +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Thermals' information which are available in the platform +# +######################################################################## + + +try: + from sonic_platform_base.thermal_base import ThermalBase + from sonic_platform.ipmihelper import IpmiSensor +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Thermal(ThermalBase): + """DellEMC Platform-specific Thermal class""" + + # [ Sensor-Name, Sensor-ID ] + SENSOR_MAPPING = [ + ['CPU On-board', 0x5], + ['Baseboard U3', 0x4], + ['SW Internal', 0x61], + ['Fan U52', 0x0], + ['Fan U17', 0x1], + ['SW U52', 0x2], + ['SW U16', 0x3], + ['PSU1 Inlet', 0x34], + ['PSU1 Hotspot', 0x35], + ['PSU2 Inlet', 0x3E], + ['PSU2 Hotspot', 0x3F], + ['SW U04', 0x4F], + ['SW U14', 0x56], + ['SW U4403', 0x5D] + ] + + def __init__(self, thermal_index=0): + ThermalBase.__init__(self) + self.index = thermal_index + 1 + self.sensor = IpmiSensor(self.SENSOR_MAPPING[self.index - 1][1]) + + def get_name(self): + """ + Retrieves the name of the thermal + + Returns: + string: The name of the thermal + """ + return self.SENSOR_MAPPING[self.index - 1][0] + + def get_presence(self): + """ + Retrieves the presence of the thermal + + Returns: + bool: True if thermal is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the Thermal + + Returns: + string: Model/part number of Thermal + """ + return 'NA' + + def get_serial(self): + """ + Retrieves the serial number of the Thermal + + Returns: + string: Serial number of Thermal + """ + return 'NA' + + def get_status(self): + """ + Retrieves the operational status of the thermal + + Returns: + A boolean value, True if thermal is operating properly, + False if not + """ + return True + + def get_temperature(self): + """ + Retrieves current temperature reading from thermal + + Returns: + A float number of current temperature in Celsius up to + nearest thousandth of one degree Celsius, e.g. 30.125 + """ + is_valid, temperature = self.sensor.get_reading() + if not is_valid: + temperature = 0 + + return float(temperature) + + def get_high_threshold(self): + """ + Retrieves the high threshold temperature of thermal + + Returns: + A float number, the high threshold temperature of thermal in + Celsius up to nearest thousandth of one degree Celsius, + e.g. 30.125 + """ + is_valid, high_threshold = self.sensor.get_threshold("UpperCritical") + if not is_valid: + high_threshold = 0 + + return float(high_threshold) + + def get_low_threshold(self): + """ + Retrieves the low threshold temperature of thermal + + Returns: + A float number, the low threshold temperature of thermal in + Celsius up to nearest thousandth of one degree Celsius, + e.g. 30.125 + """ + is_valid, low_threshold = self.sensor.get_threshold("LowerNonRecoverable") + if not is_valid: + low_threshold = 0 + + return float(low_threshold) + + def get_high_critical_threshold(self): + """ + Retrieves the high critical threshold temperature of thermal + Returns: + A float number, the high critical threshold temperature of + thermal in Celsius up to nearest thousandth of one degree + Celsius, e.g. 30.125 + """ + is_valid, high_crit_threshold = self.sensor.get_threshold("UpperNonRecoverable") + if not is_valid: + high_crit_threshold = 0 + + return float(high_crit_threshold) + + + def set_high_threshold(self, temperature): + """ + Sets the high threshold temperature of thermal + + Args : + temperature: A float number up to nearest thousandth of one + degree Celsius, e.g. 30.125 + Returns: + A boolean, True if threshold is set successfully, False if + not + """ + # Thermal threshold values are pre-defined based on HW. + return False + + def set_low_threshold(self, temperature): + """ + Sets the low threshold temperature of thermal + + Args : + temperature: A float number up to nearest thousandth of one + degree Celsius, e.g. 30.125 + Returns: + A boolean, True if threshold is set successfully, False if + not + """ + # Thermal threshold values are pre-defined based on HW. + return False diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/watchdog.py b/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/watchdog.py new file mode 100644 index 000000000000..265fab66d922 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/watchdog.py @@ -0,0 +1,211 @@ +#!/usr/bin/env python + +######################################################################## +# +# DELLEMC Z9332F +# +# Abstract base class for implementing a platform-specific class with +# which to interact with a hardware watchdog module in SONiC +# +######################################################################## + +try: + import ctypes + import subprocess + from sonic_platform_base.watchdog_base import WatchdogBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class _timespec(ctypes.Structure): + _fields_ = [ + ('tv_sec', ctypes.c_long), + ('tv_nsec', ctypes.c_long) + ] + + +class Watchdog(WatchdogBase): + """ + Abstract base class for interfacing with a hardware watchdog module + """ + + TIMERS = [15,20,30,40,50,60,65,70] + + armed_time = 0 + timeout = 0 + CLOCK_MONOTONIC = 1 + + def __init__(self): + self._librt = ctypes.CDLL('librt.so.1', use_errno=True) + self._clock_gettime = self._librt.clock_gettime + self._clock_gettime.argtypes=[ctypes.c_int, ctypes.POINTER(_timespec)] + + def _get_command_result(self, cmdline): + try: + proc = subprocess.Popen(cmdline.split(), stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + result = stdout.rstrip('\n') + except OSError: + result = None + + return result + + def _get_reg_val(self): + # 0x31 = CPLD I2C Base Address + # 0x07 = Watchdog Function Register + value = self._get_command_result("/usr/sbin/i2cget -y 601 0x31 0x07") + if not value: + return None + else: + return int(value, 16) + + def _set_reg_val(self,val): + # 0x31 = CPLD I2C Base Address + # 0x07 = Watchdog Function Register + value = self._get_command_result("/usr/sbin/i2cset -y 601 0x31 0x07 %s" + % (val)) + return value + + def _get_time(self): + """ + To get clock monotonic time + """ + ts = _timespec() + if self._clock_gettime(self.CLOCK_MONOTONIC, ctypes.pointer(ts)) != 0: + self._errno = ctypes.get_errno() + return 0 + return ts.tv_sec + ts.tv_nsec * 1e-9 + + def arm(self, seconds): + """ + Arm the hardware watchdog with a timeout of seconds. + If the watchdog is currently armed, calling this function will + simply reset the timer to the provided value. If the underlying + hardware does not support the value provided in , this + method should arm the watchdog with the *next greater* + available value. + + Returns: + An integer specifying the *actual* number of seconds the + watchdog was armed with. On failure returns -1. + """ + timer_offset = -1 + for key,timer_seconds in enumerate(self.TIMERS): + if seconds <= timer_seconds: + timer_offset = key + seconds = timer_seconds + break + + if timer_offset == -1: + return -1 + + # Extracting 5th to 7th bits for WD timer values + # 000 - 15 sec + # 001 - 20 sec + # 010 - 30 sec + # 011 - 40 sec + # 100 - 50 sec + # 101 - 60 sec + # 110 - 65 sec + # 111 - 70 sec + reg_val = self._get_reg_val() + wd_timer_offset = (reg_val >> 4) & 0x7 + + if wd_timer_offset != timer_offset: + # Setting 5th to 7th bits + # value from timer_offset + self.disarm() + self._set_reg_val(reg_val | (timer_offset << 4)) + + if self.is_armed(): + # Setting last bit to WD Timer punch + # Last bit = WD Timer punch + self._set_reg_val(reg_val & 0xFE) + + self.armed_time = self._get_time() + self.timeout = seconds + return seconds + else: + # Setting 4th bit to enable WD + # 4th bit = Enable WD + reg_val = self._get_reg_val() + self._set_reg_val(reg_val | 0x8) + + self.armed_time = self._get_time() + self.timeout = seconds + return seconds + + + def disarm(self): + """ + Disarm the hardware watchdog + + Returns: + A boolean, True if watchdog is disarmed successfully, False + if not + """ + if self.is_armed(): + # Setting 4th bit to disable WD + # 4th bit = Disable WD + reg_val = self._get_reg_val() + self._set_reg_val(reg_val & 0xF7) + + self.armed_time = 0 + self.timeout = 0 + return True + + return False + + def is_armed(self): + """ + Retrieves the armed state of the hardware watchdog. + + Returns: + A boolean, True if watchdog is armed, False if not + """ + + # Extracting 4th bit to get WD Enable/Disable status + # 0 - Disabled WD + # 1 - Enabled WD + reg_val = self._get_reg_val() + wd_offset = (reg_val >> 3) & 1 + + return bool(wd_offset) + + def get_remaining_time(self): + """ + If the watchdog is armed, retrieve the number of seconds + remaining on the watchdog timer + + Returns: + An integer specifying the number of seconds remaining on + their watchdog timer. If the watchdog is not armed, returns + -1. + + S5232 doesnot have hardware support to show remaining time. + Due to this limitation, this API is implemented in software. + This API would return correct software time difference if it + is called from the process which armed the watchdog timer. + If this API called from any other process, it would return + 0. If the watchdog is not armed, this API would return -1. + """ + if not self.is_armed(): + return -1 + + if self.armed_time > 0 and self.timeout != 0: + cur_time = self._get_time() + + if cur_time <= 0: + return 0 + + diff_time = int(cur_time - self.armed_time) + + if diff_time > self.timeout: + return self.timeout + else: + return self.timeout - diff_time + + return 0 + diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/systemd/platform-modules-z9332f.service b/platform/broadcom/sonic-platform-modules-dell/z9332f/systemd/platform-modules-z9332f.service index 49064b00d682..348313718a70 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9332f/systemd/platform-modules-z9332f.service +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/systemd/platform-modules-z9332f.service @@ -1,6 +1,6 @@ [Unit] Description=Dell Z9332f Platform modules -Before=pmon.service +Before=pmon.service determine-reboot-cause.service DefaultDependencies=no [Service] diff --git a/platform/broadcom/sonic-platform-modules-delta/ag5648/modules/delta_ag5648_platform.c b/platform/broadcom/sonic-platform-modules-delta/ag5648/modules/delta_ag5648_platform.c index 16b9ba2fbc4c..1ebcaa39d026 100644 --- a/platform/broadcom/sonic-platform-modules-delta/ag5648/modules/delta_ag5648_platform.c +++ b/platform/broadcom/sonic-platform-modules-delta/ag5648/modules/delta_ag5648_platform.c @@ -9,9 +9,9 @@ #include #include #include -#include +#include #include -#include +#include #include #define BUS4_DEV_NUM 54 diff --git a/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/delta_ag9032v1_platform.c b/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/delta_ag9032v1_platform.c index 9b7a1958c77a..70cd8b581df4 100644 --- a/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/delta_ag9032v1_platform.c +++ b/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/delta_ag9032v1_platform.c @@ -9,9 +9,9 @@ #include #include #include -#include +#include #include -#include +#include #include #include #include diff --git a/platform/broadcom/sonic-platform-modules-delta/ag9032v2a/modules/delta_ag9032v2a_platform.c b/platform/broadcom/sonic-platform-modules-delta/ag9032v2a/modules/delta_ag9032v2a_platform.c index 85719af7ea94..5345ae86e7f9 100644 --- a/platform/broadcom/sonic-platform-modules-delta/ag9032v2a/modules/delta_ag9032v2a_platform.c +++ b/platform/broadcom/sonic-platform-modules-delta/ag9032v2a/modules/delta_ag9032v2a_platform.c @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include #include diff --git a/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_platform.c b/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_platform.c index 4de9799d4601..bdf4f1e07e3d 100644 --- a/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_platform.c +++ b/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_platform.c @@ -3,9 +3,9 @@ #include #include #include -#include +#include #include -#include +#include #include #include #include diff --git a/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/i2c-mei_main.c b/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/i2c-mei_main.c index a5dbbd22b4a5..811877fa8ead 100644 --- a/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/i2c-mei_main.c +++ b/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/i2c-mei_main.c @@ -28,7 +28,7 @@ #if (defined CONFIG_I2C_MUX_GPIO || defined CONFIG_I2C_MUX_GPIO_MODULE) && \ defined CONFIG_DMI #include -#include +#include #endif /* PCI Address Constants */ diff --git a/platform/broadcom/sonic-platform-modules-delta/agc032/cfg/agc032-modules.conf b/platform/broadcom/sonic-platform-modules-delta/agc032/cfg/agc032-modules.conf new file mode 100644 index 000000000000..552b4103ed02 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/agc032/cfg/agc032-modules.conf @@ -0,0 +1,13 @@ +# /etc/modules: kernel modules to load at boot time. +# +# This file contains the names of kernel modules that should be loaded +# at boot time, one per line. Lines beginning with "#" are ignored. + +i2c-i801 +i2c-isch +i2c-ismt +i2c-dev +i2c-mux +i2c-smbus +i2c-mux-gpio +i2c-mux-pca954x diff --git a/platform/broadcom/sonic-platform-modules-delta/agc032/modules/Makefile b/platform/broadcom/sonic-platform-modules-delta/agc032/modules/Makefile new file mode 100644 index 000000000000..93bd96998409 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/agc032/modules/Makefile @@ -0,0 +1 @@ +obj-m := dni_agc032_psu.o dni_emc2305.o delta_agc032_platform.o delta_agc032_cpupld.o dni_emc2302.o delta_agc032_swpld.o delta_agc032_qsfp.o diff --git a/platform/broadcom/sonic-platform-modules-delta/agc032/modules/delta_agc032_cpupld.c b/platform/broadcom/sonic-platform-modules-delta/agc032/modules/delta_agc032_cpupld.c new file mode 100644 index 000000000000..76ae53d314de --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/agc032/modules/delta_agc032_cpupld.c @@ -0,0 +1,746 @@ +#include +#include +#include +#include +#include +#include + +#define CPUPLD_I2C_ADDR 0x31 + +enum cpld_type { + cpld, +}; + +struct platform_data { + int reg_addr; + struct i2c_client *client; +}; + +enum{ + BUS0 = 0, + BUS1, + BUS2, + BUS3, + BUS4, + BUS5, + BUS6, + BUS7, + BUS8, +}; + +enum{ + CPU_PCB_NUM = 0, + CPUPLD_VER_TYPE, + CPUPLD_VER, + BDXDE_PLAT_RST, + BDXDE_SLP3_STAT, + BDXDE_SLP4_STAT, + BDXDE_CPU_RST, + CPLD_DEBUG_MODE, + APWROK_STAT, + EDGE_PROCHOT_SIG_DIS, + PSU_THERMAL_STAT, + PR_THERMAL_STAT, + ME_DRIVE_SIG_EN, + CPU_THERMAL_STAT, + DDR_THERMAL_STAT, + SYS_THERMAL_STAT, + DEBUG_LED3_EN, + DEBUG_LED2_EN, + DEBUG_LED1_EN, + DEBUG_LED0_EN, + CPU_STANDBY_MODE, + CPLD_RST, + MB_POWER_STAT, + BIOS1_SPI_WP, + BIOS2_SPI_WP, + BIOS_MUX_SEL, + GBE_SPI_WP, + PCH_THERMTRIP_EN, + ID_EEPROM_EN, + CPU_I2C_MUX_EN, + CPU_I2C_MUX_SEL, + PSU_FAN_INTR, + WD_TIMER, + WD_EN, + WD_CLEAR_FLAG, +}; + + +static unsigned char cpupld_reg_addr; + +static ssize_t cpupld_reg_value_show(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ret; + struct platform_data *pdata = dev->platform_data; + + ret = i2c_smbus_read_byte_data(pdata[cpld].client, cpupld_reg_addr); + + return scnprintf(buf, PAGE_SIZE, "0x%02x\n", ret); +} + +static ssize_t cpupld_reg_value_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned long data; + int err; + struct platform_data *pdata = dev->platform_data; + + err = kstrtoul(buf, 0, &data); + if (err){ + return err; + } + + if (data > 0xff){ + printk(KERN_ALERT "address out of range (0x00-0xFF)\n"); + return count; + } + + i2c_smbus_write_byte_data(pdata[cpld].client, cpupld_reg_addr, data); + + return count; +} + +static ssize_t cpupld_reg_addr_show(struct device *dev, struct device_attribute *devattr, char *buf) +{ + + return scnprintf(buf, PAGE_SIZE, "0x%02x\n", cpupld_reg_addr); +} + +static ssize_t cpupld_reg_addr_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned long data; + int err; + + err = kstrtoul(buf, 0, &data); + if (err){ + return err; + } + if (data > 0xff){ + printk(KERN_ALERT "address out of range (0x00-0xFF)\n"); + return count; + } + cpupld_reg_addr = data; + + return count; +} + + +static ssize_t cpupld_data_show(struct device *dev, struct device_attribute *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct platform_data *pdata = dev->platform_data; + unsigned int select = 0; + unsigned char offset = 0; + int mask = 0xFF; + int shift = 0; + int value = 0; + bool hex_fmt = 0; + char desc[256] = {0}; + + select = attr->index; + switch(select) { + case CPU_PCB_NUM: + offset = 0x0; + hex_fmt = 1; + scnprintf(desc, PAGE_SIZE, "\nCPU Borad PCB Number.\n"); + break; + case CPUPLD_VER_TYPE: + offset = 0x1; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nCPUPLD Version Type.\n"); + break; + case CPUPLD_VER: + offset = 0x1; + mask = 0x7F; + scnprintf(desc, PAGE_SIZE, "\nCPUPLD Version.\n"); + break; + case BDXDE_PLAT_RST: + offset = 0x9; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Platform Reset State\n“0†= Platform Not Reset State.\n"); + break; + case BDXDE_SLP3_STAT: + offset = 0x9; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= CPU at S3 State\n“0†= CPU Not at S3 State.\n"); + break; + case BDXDE_SLP4_STAT: + offset = 0x9; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= CPU at S4Sstate\n“0†= CPU Not at S4 State.\n"); + break; + case BDXDE_CPU_RST: + offset = 0x9; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= CPU Not Reset State\n“0†= CPU Reset State.\n"); + break; + case CPLD_DEBUG_MODE: + offset = 0x9; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nCPLD Power Sequence\n“1†= Debug Mode\n“0†= Normal Mode.\n"); + break; + case APWROK_STAT: + offset = 0xA; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= APWROK Stable\n“0†= APWROK Unstable.\n"); + break; + case EDGE_PROCHOT_SIG_DIS: + offset = 0xB; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Disable Power Supply Thermal Signal\n“0†= Enable Power Supply Thermal Signal.\n"); + break; + case PSU_THERMAL_STAT: + offset = 0xB; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Power Supply Normal Temperature\n“0†= Power Supply Over Temperature.\n"); + break; + case PR_THERMAL_STAT: + offset = 0xB; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Power Rail Normal Temperature\n“0†= Power Rail Over Temperature.\n"); + break; + case ME_DRIVE_SIG_EN: + offset = 0xB; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Disable System Thermal Alarm to CPU\n“0†= System Thermal Alarm to CPU.\n"); + break; + case CPU_THERMAL_STAT: + offset = 0xB; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= CPU Disomic Normal Temperature\n“0†= CPU Disomic Over Temperatur.\n"); + break; + case DDR_THERMAL_STAT: + offset = 0xB; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= DDR Normal Temperature\n“0†= DDR Over Temperature.\n"); + break; + case SYS_THERMAL_STAT: + offset = 0xC; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= System Normal Temperature.\n“0†= System Over Temperature.\n"); + break; + case DEBUG_LED3_EN: + offset = 0xD; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Disable Debug LED3\n“0†= Enable Debug LED3.\n"); + break; + case DEBUG_LED2_EN: + offset = 0xD; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Disable Debug LED2\n“0†= Enable Debug LED2.\n"); + break; + case DEBUG_LED1_EN: + offset = 0xD; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Disable Debug LED1\n“0†= Enable Debug LED1.\n"); + break; + case DEBUG_LED0_EN: + offset = 0xD; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Disable Debug LED0\n“0†= Enable Debug LED0.\n"); + break; + case CPU_STANDBY_MODE: + offset = 0x11; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= CPU Power Stanby Not Ready\n“0†= CPU Power Stanby Ready.\n"); + break; + case CPLD_RST: + offset = 0x11; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation\n“0†= CPLD Reset.\n"); + break; + case MB_POWER_STAT: + offset = 0x12; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Power Rail Good\n“0†= Power Rail Failed.\n"); + break; + case BIOS2_SPI_WP: + offset = 0x13; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Disable BIOS2 SPI Write Protect\n“0†= Enable BIOS2 SPI Write Protect.\n"); + break; + case BIOS1_SPI_WP: + offset = 0x13; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Disable BIOS1 SPI Write Protect\n“0†= Enable BIOS1 SPI Write Protect.\n"); + break; + case BIOS_MUX_SEL: + offset = 0x13; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Primary BIOS\n“0†= Backup BIOS.\n"); + break; + case GBE_SPI_WP: + offset = 0x13; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Disable GBE SPI Write Protect\n“0†= Enable GBE SPI Write Protect.\n"); + break; + case PCH_THERMTRIP_EN: + offset = 0x14; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Thermal Trip Not Occured\n“0†= Thermal Trip Occured.\n"); + break; + case ID_EEPROM_EN: + offset = 0x14; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Disable ID EEPROM Write Protect\n“0†= Enable ID EEPROM Write Protect.\n"); + break; + case CPU_I2C_MUX_EN: + offset = 0x14; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Enable CPU I2C Mux\n“0†= Disable CPU I2C Mux.\n"); + break; + case CPU_I2C_MUX_SEL: + offset = 0x14; + shift = 0; + mask = 0x3; + scnprintf(desc, PAGE_SIZE, "\n“3†= Select MB Panel Port.\n“2†= Select MB SWPLD.\n“1†= Select MB Mux.\n“0†= Select ONIE EEPROM.\n"); + break; + case PSU_FAN_INTR: + offset = 0x15; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= PSU Fan Interrupt Occured\n“0†= PSU Fan Interrupt Not Occured.\n"); + break; + case WD_TIMER: + offset = 0x1E; + shift = 3; + mask = 0x38; + scnprintf(desc, PAGE_SIZE, "\n“5†= Timer 60 sec.\n“4†= Timer 50 sec.\n“3†= Timer 40 sec.\n“2†= Timer 30 sec.\n“1†= Timer 20 sec.\n“0†= Timer 15 sec.\n"); + break; + case WD_EN: + offset = 0x1E; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Disable Watchdog Function\n“0†= Enable Watchdog Function.\n"); + break; + case WD_CLEAR_FLAG: + offset = 0x1E; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Watchdog Timer Flag Clear\n“0†= Watchdog Timer Flag Not Clear.\n"); + break; + } + + value = i2c_smbus_read_byte_data(pdata[cpld].client, offset); + value = (value & mask) >> shift; + if(hex_fmt) { + return scnprintf(buf, PAGE_SIZE, "0x%02x%s", value, desc); + } else { + return scnprintf(buf, PAGE_SIZE, "%d%s", value, desc); + } +} + +static ssize_t cpupld_data_store(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 platform_data *pdata = dev->platform_data; + unsigned int select = 0; + unsigned char offset = 0; + int mask = 0xFF; + int shift = 0; + int value = 0; + int err = 0; + unsigned long data; + + err = kstrtoul(buf, 0, &data); + if (err){ + return err; + } + + if (data > 0xff){ + printk(KERN_ALERT "address out of range (0x00-0xFF)\n"); + return count; + } + + switch (attr->index) { + case DEBUG_LED3_EN: + offset = 0xD; + shift = 3; + mask = (1 << shift); + break; + case DEBUG_LED2_EN: + offset = 0xD; + shift = 2; + mask = (1 << shift); + break; + case DEBUG_LED1_EN: + offset = 0xD; + shift = 1; + mask = (1 << shift); + break; + case DEBUG_LED0_EN: + offset = 0xD; + shift = 0; + mask = (1 << shift); + break; + case CPLD_RST: + offset = 0x11; + shift = 0; + mask = (1 << shift); + break; + case MB_POWER_STAT: + offset = 0x12; + shift = 2; + mask = (1 << shift); + break; + case BIOS2_SPI_WP: + offset = 0x13; + shift = 3; + mask = (1 << shift); + break; + case BIOS1_SPI_WP: + offset = 0x13; + shift = 2; + mask = (1 << shift); + break; + case BIOS_MUX_SEL: + offset = 0x13; + shift = 1; + mask = (1 << shift); + break; + case GBE_SPI_WP: + offset = 0x13; + shift = 0; + mask = (1 << shift); + break; + case PCH_THERMTRIP_EN: + offset = 0x14; + shift = 4; + mask = (1 << shift); + break; + case ID_EEPROM_EN: + offset = 0x14; + shift = 3; + mask = (1 << shift); + break; + case CPU_I2C_MUX_EN: + offset = 0x14; + shift = 2; + mask = (1 << shift); + break; + case CPU_I2C_MUX_SEL: + offset = 0x14; + shift = 0; + mask = 0x3; + break; + case WD_TIMER: + offset = 0x1E; + shift = 3; + mask = 0x38; + break; + case WD_EN: + offset = 0x1E; + shift = 2; + mask = (1 << shift); + break; + case WD_CLEAR_FLAG: + offset = 0x1E; + shift = 0; + mask = (1 << shift); + break; + } + + value = i2c_smbus_read_byte_data(pdata[cpld].client, offset); + data = (value & ~mask) | (data << shift); + i2c_smbus_write_byte_data(pdata[cpld].client, offset, data); + + return count; +} + +static DEVICE_ATTR(cpupld_reg_value, S_IRUGO | S_IWUSR, cpupld_reg_value_show, cpupld_reg_value_store); +static DEVICE_ATTR(cpupld_reg_addr, S_IRUGO | S_IWUSR, cpupld_reg_addr_show, cpupld_reg_addr_store); + +/* offset 0x0 */ +static SENSOR_DEVICE_ATTR(cpu_pcb_num, S_IRUGO, cpupld_data_show, NULL, CPU_PCB_NUM ); +/* offset 0x1 */ +static SENSOR_DEVICE_ATTR(cpupld_ver_type, S_IRUGO, cpupld_data_show, NULL, CPUPLD_VER_TYPE ); +static SENSOR_DEVICE_ATTR(cpupld_ver, S_IRUGO, cpupld_data_show, NULL, CPUPLD_VER ); +#if 0 +/* offset 0x5 */ +static SENSOR_DEVICE_ATTR(p1v2_vddq_en, S_IRUGO, cpupld_data_show, NULL, P1V2_VDDQ_EN ); +static SENSOR_DEVICE_ATTR(p1v5_pch_en, S_IRUGO, cpupld_data_show, NULL, P1V5_PCH_EN ); +static SENSOR_DEVICE_ATTR(p2v5_vpp_en, S_IRUGO, cpupld_data_show, NULL, P2V5_VPP_EN ); +static SENSOR_DEVICE_ATTR(pvccin_en, S_IRUGO, cpupld_data_show, NULL, PVCCIN_EN ); +static SENSOR_DEVICE_ATTR(pvccioin_en, S_IRUGO, cpupld_data_show, NULL, PVCCIOIN_EN ); +static SENSOR_DEVICE_ATTR(pvcckrhv_en, S_IRUGO, cpupld_data_show, NULL, PVCCKRHV_EN ); +static SENSOR_DEVICE_ATTR(pvccscfusesus_en, S_IRUGO, cpupld_data_show, NULL, PVCCSCFUSESUS_EN ); +static SENSOR_DEVICE_ATTR(vr_p3v3_en, S_IRUGO, cpupld_data_show, NULL, VR_P3V3_EN ); +/* offset 0x6 */ +static SENSOR_DEVICE_ATTR(cpu_sys_power, S_IRUGO, cpupld_data_show, NULL, CPU_SYS_POWER ); +static SENSOR_DEVICE_ATTR(p0v6_vtt_dimm_en, S_IRUGO, cpupld_data_show, NULL, P0V6_VTT_DIMM_EN ); +static SENSOR_DEVICE_ATTR(p1v05_pch_en, S_IRUGO, cpupld_data_show, NULL, P1V05_PCH_EN ); +/* offser 0x7 */ +static SENSOR_DEVICE_ATTR(p1v5_pch_pwrgd, S_IRUGO, cpupld_data_show, NULL, P1V5_PCH_GOOD ); +static SENSOR_DEVICE_ATTR(p2v5_vpp_pwrgd, S_IRUGO, cpupld_data_show, NULL, P2V5_VPP_GOOD ); +static SENSOR_DEVICE_ATTR(pch_pwr_pwrgd, S_IRUGO, cpupld_data_show, NULL, PCH_PWR_GOOD ); +static SENSOR_DEVICE_ATTR(pvccin_pwrgd, S_IRUGO, cpupld_data_show, NULL, PVCCIN_GOOD ); +static SENSOR_DEVICE_ATTR(pvccioin_pwrgd, S_IRUGO, cpupld_data_show, NULL, PVCCIOIN_GOOD ); +static SENSOR_DEVICE_ATTR(pvcckrhv_pwrgd, S_IRUGO, cpupld_data_show, NULL, PVCCKRHV_GOOD ); +static SENSOR_DEVICE_ATTR(pvccscfusesus_pwrgd, S_IRUGO, cpupld_data_show, NULL, PVCCSCFUSESUS_GOOD ); +static SENSOR_DEVICE_ATTR(vr_p3v3_pwrgd, S_IRUGO, cpupld_data_show, NULL, VR_P3V3_GOOD ); +/* offset 0x8 */ +static SENSOR_DEVICE_ATTR(bdxde_lan_pwrgd, S_IRUGO, cpupld_data_show, NULL, BDXDE_LAN_GOOD ); +static SENSOR_DEVICE_ATTR(CPU0_pwrgd, S_IRUGO, cpupld_data_show, NULL, CPU0_GOOD ); +static SENSOR_DEVICE_ATTR(p0v6_vtt_dimm_pwrgd, S_IRUGO, cpupld_data_show, NULL, P0V6_VTT_DIMM_GOOD ); +static SENSOR_DEVICE_ATTR(p1v05_procio_pwrgd, S_IRUGO, cpupld_data_show, NULL, P1V05_PROCIO_GOOD ); +static SENSOR_DEVICE_ATTR(p1v2_vddq_pwrgd, S_IRUGO, cpupld_data_show, NULL, P1V2_VDDQ_GOOD ); +#endif +/* offset 0x9 */ +static SENSOR_DEVICE_ATTR(bdxde_plat_rst, S_IRUGO, cpupld_data_show, NULL, BDXDE_PLAT_RST ); +static SENSOR_DEVICE_ATTR(bdxde_slp3_stat, S_IRUGO, cpupld_data_show, NULL, BDXDE_SLP3_STAT ); +static SENSOR_DEVICE_ATTR(bdxde_slp4_stat, S_IRUGO, cpupld_data_show, NULL, BDXDE_SLP4_STAT ); +static SENSOR_DEVICE_ATTR(bdxde_cpu_rst, S_IRUGO, cpupld_data_show, NULL, BDXDE_CPU_RST ); +static SENSOR_DEVICE_ATTR(cpld_debug_mode, S_IRUGO, cpupld_data_show, NULL, CPLD_DEBUG_MODE ); +/* offset 0xA */ +static SENSOR_DEVICE_ATTR(apwrok_stat, S_IRUGO, cpupld_data_show, NULL, APWROK_STAT ); +//static SENSOR_DEVICE_ATTR(cpu_standby_mode, S_IRUGO, cpupld_data_show, NULL, CPU_STANDBY_MODE ); +/* offset 0xB */ +static SENSOR_DEVICE_ATTR(edge_prochot_sig_dis, S_IRUGO, cpupld_data_show, NULL, EDGE_PROCHOT_SIG_DIS ); +static SENSOR_DEVICE_ATTR(psu_thermal_stat, S_IRUGO, cpupld_data_show, NULL, PSU_THERMAL_STAT ); +static SENSOR_DEVICE_ATTR(pr_thermal_stat, S_IRUGO, cpupld_data_show, NULL, PR_THERMAL_STAT ); +static SENSOR_DEVICE_ATTR(me_drv_sig_en, S_IRUGO, cpupld_data_show, NULL, ME_DRIVE_SIG_EN ); +static SENSOR_DEVICE_ATTR(cpu_thermal_stat, S_IRUGO, cpupld_data_show, NULL, CPU_THERMAL_STAT ); +static SENSOR_DEVICE_ATTR(ddr_thermal_stat, S_IRUGO, cpupld_data_show, NULL, DDR_THERMAL_STAT ); +/* offset 0xC */ +static SENSOR_DEVICE_ATTR(sys_thermal_stat, S_IRUGO, cpupld_data_show, NULL, SYS_THERMAL_STAT ); +/* offset 0xD */ +static SENSOR_DEVICE_ATTR(debug_led3_en, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, DEBUG_LED3_EN ); +static SENSOR_DEVICE_ATTR(debug_led2_en, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, DEBUG_LED2_EN ); +static SENSOR_DEVICE_ATTR(debug_led1_en, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, DEBUG_LED1_EN ); +static SENSOR_DEVICE_ATTR(debug_led0_en, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, DEBUG_LED0_EN ); +/* offset 0x11 */ +static SENSOR_DEVICE_ATTR(cpu_standby_mode, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, CPU_STANDBY_MODE ); +static SENSOR_DEVICE_ATTR(cpld_rst, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, CPLD_RST ); +/* offset 0x12 */ +static SENSOR_DEVICE_ATTR(mb_power_stat, S_IRUGO, cpupld_data_show, NULL, MB_POWER_STAT ); +/* offset 0x13 */ +static SENSOR_DEVICE_ATTR(bios1_spi_wp, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, BIOS1_SPI_WP ); +static SENSOR_DEVICE_ATTR(bios2_spi_wp, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, BIOS2_SPI_WP ); +static SENSOR_DEVICE_ATTR(bios_mux_sel, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, BIOS_MUX_SEL ); +static SENSOR_DEVICE_ATTR(gbe_spi_wp, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, GBE_SPI_WP ); +/* offset 0x14 */ +static SENSOR_DEVICE_ATTR(pch_thermtrip_en, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, PCH_THERMTRIP_EN ); +static SENSOR_DEVICE_ATTR(id_eeprom_wp, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, ID_EEPROM_EN ); +static SENSOR_DEVICE_ATTR(cpu_i2c_mux_en, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, CPU_I2C_MUX_EN ); +static SENSOR_DEVICE_ATTR(cpu_i2c_mux_sel, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, CPU_I2C_MUX_SEL ); +/* offset 0x15 */ +static SENSOR_DEVICE_ATTR(psu_fan_intr, S_IRUGO, cpupld_data_show, NULL, PSU_FAN_INTR ); +/* offset 0x1E */ +static SENSOR_DEVICE_ATTR(wd_timer, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, WD_TIMER ); +static SENSOR_DEVICE_ATTR(wd_en, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, WD_EN ); +static SENSOR_DEVICE_ATTR(wd_clear_flag, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, WD_CLEAR_FLAG ); + + +static struct attribute *agc032_cpupld_attrs[] = { + &dev_attr_cpupld_reg_value.attr, + &dev_attr_cpupld_reg_addr.attr, + &sensor_dev_attr_cpu_pcb_num.dev_attr.attr, + &sensor_dev_attr_cpupld_ver_type.dev_attr.attr, + &sensor_dev_attr_cpupld_ver.dev_attr.attr, + &sensor_dev_attr_bdxde_plat_rst.dev_attr.attr, + &sensor_dev_attr_bdxde_slp3_stat.dev_attr.attr, + &sensor_dev_attr_bdxde_slp4_stat.dev_attr.attr, + &sensor_dev_attr_bdxde_cpu_rst.dev_attr.attr, + &sensor_dev_attr_cpld_debug_mode.dev_attr.attr, + &sensor_dev_attr_apwrok_stat.dev_attr.attr, + &sensor_dev_attr_edge_prochot_sig_dis.dev_attr.attr, + &sensor_dev_attr_psu_thermal_stat.dev_attr.attr, + &sensor_dev_attr_pr_thermal_stat.dev_attr.attr, + &sensor_dev_attr_me_drv_sig_en.dev_attr.attr, + &sensor_dev_attr_cpu_thermal_stat.dev_attr.attr, + &sensor_dev_attr_ddr_thermal_stat.dev_attr.attr, + &sensor_dev_attr_sys_thermal_stat.dev_attr.attr, + &sensor_dev_attr_debug_led3_en.dev_attr.attr, + &sensor_dev_attr_debug_led2_en.dev_attr.attr, + &sensor_dev_attr_debug_led1_en.dev_attr.attr, + &sensor_dev_attr_debug_led0_en.dev_attr.attr, + &sensor_dev_attr_cpu_standby_mode.dev_attr.attr, + &sensor_dev_attr_cpld_rst.dev_attr.attr, + &sensor_dev_attr_mb_power_stat.dev_attr.attr, + &sensor_dev_attr_bios1_spi_wp.dev_attr.attr, + &sensor_dev_attr_bios2_spi_wp.dev_attr.attr, + &sensor_dev_attr_bios_mux_sel.dev_attr.attr, + &sensor_dev_attr_gbe_spi_wp.dev_attr.attr, + &sensor_dev_attr_pch_thermtrip_en.dev_attr.attr, + &sensor_dev_attr_id_eeprom_wp.dev_attr.attr, + &sensor_dev_attr_cpu_i2c_mux_en.dev_attr.attr, + &sensor_dev_attr_cpu_i2c_mux_sel.dev_attr.attr, + &sensor_dev_attr_psu_fan_intr.dev_attr.attr, + &sensor_dev_attr_wd_timer.dev_attr.attr, + &sensor_dev_attr_wd_en.dev_attr.attr, + &sensor_dev_attr_wd_clear_flag.dev_attr.attr, + NULL, +}; + +static struct attribute_group agc032_cpupld_attr_group = { + .attrs = agc032_cpupld_attrs, +}; + +static int __init cpupld_probe(struct platform_device *pdev) +{ + struct platform_data *pdata; + struct i2c_adapter *parent; + int rv; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "CPUPLD platform data not found\n"); + return -ENODEV; + } + + parent = i2c_get_adapter(BUS0); + if (!parent) { + printk(KERN_ERR "Parent adapter (%d) not found\n",BUS0); + return -ENODEV; + } + + pdata[cpld].client = i2c_new_dummy(parent, pdata[cpld].reg_addr); + if (!pdata[cpld].client) { + printk(KERN_ERR "Fail to create dummy i2c client for addr %d\n", pdata[cpld].reg_addr); + goto error; + } +#if 0 + /* set default cpu_i2c_mux 0x14 be 0x1 */ + rv = i2c_smbus_write_byte_data(pdata[cpld].client, 0x14, 0x1); + if (rv < 0) { + printk(KERN_WARNING, "Error: Failed to set addr 0x14.\n"); + goto error; + } +#endif + /* /sys/device/platform */ + rv = sysfs_create_group(&pdev->dev.kobj, &agc032_cpupld_attr_group); + if (rv){ + printk(KERN_ERR "Fail to create cpupld attribute group"); + goto error; + } + return 0; + +error: + i2c_unregister_device(pdata[cpld].client); + i2c_put_adapter(parent); + return -ENODEV; +} + + +static int __exit cpupld_remove(struct platform_device *pdev) +{ + struct i2c_adapter *parent = NULL; + struct platform_data *pdata = pdev->dev.platform_data; + sysfs_remove_group(&pdev->dev.kobj, &agc032_cpupld_attr_group); + + if (!pdata) { + dev_err(&pdev->dev, "Missing platform data\n"); + } + else { + if (pdata[cpld].client) { + if (!parent) { + parent = (pdata[cpld].client)->adapter; + } + i2c_unregister_device(pdata[cpld].client); + } + } + i2c_put_adapter(parent); + return 0; +} + + +static struct platform_driver cpupld_driver = { + .probe = cpupld_probe, + .remove = __exit_p(cpupld_remove), + .driver = { + .owner = THIS_MODULE, + .name = "delta-agc032-cpupld", + }, +}; + + +static struct platform_data agc032_cpupld_platform_data[] = { + [cpld] = { + .reg_addr = CPUPLD_I2C_ADDR, + }, +}; + +static void device_release(struct device *dev) +{ + return; +} + +static struct platform_device cpupld_agc032 = { + .name = "delta-agc032-cpupld", + .id = 0, + .dev = { + .platform_data = agc032_cpupld_platform_data, + .release = device_release + }, +}; + +/* module initialization */ +static int __init delta_agc032_cpupld_init(void) +{ + int rc = 0; + printk(KERN_INFO "CPUPLD module initializating\n"); + + /* register CPUPLD driver */ + rc = platform_driver_register(&cpupld_driver); + if (rc < 0) { + printk(KERN_ERR "Fail to register CPUPLD driver, rc = %d\n", rc); + goto error_register_driver; + } + + /* register CPUPLD device */ + rc = platform_device_register(&cpupld_agc032); + if (rc) { + printk(KERN_ERR "Fail to create cpupld device, rc = %d\n", rc); + goto error_register_device; + } + return 0; + +error_register_device: + platform_driver_unregister(&cpupld_driver); +error_register_driver: + return rc; +} + +static void __exit delta_agc032_cpupld_exit(void) +{ + platform_device_unregister(&cpupld_agc032); + platform_driver_unregister(&cpupld_driver); +} + +module_init(delta_agc032_cpupld_init); +module_exit(delta_agc032_cpupld_exit); + +MODULE_DESCRIPTION("DNI agc032 CPLD Platform Support"); +MODULE_AUTHOR("James Ke "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-delta/agc032/modules/delta_agc032_platform.c b/platform/broadcom/sonic-platform-modules-delta/agc032/modules/delta_agc032_platform.c new file mode 100644 index 000000000000..121ccc4d8b2d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/agc032/modules/delta_agc032_platform.c @@ -0,0 +1,299 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#define agc032_i2c_device_num(c){ \ + .name = "delta-agc032-i2c-device", \ + .id = c, \ + .dev = { \ + .platform_data = &agc032_i2c_device_platform_data[c], \ + .release = device_release, \ + }, \ +} + + + +/* Define struct to get client of i2c_new_deivce at 0x70 */ +struct i2c_client * i2c_client_9548; + +enum{ + BUS0 = 0, + BUS1, + BUS2, + BUS3, + BUS4, + BUS5, + BUS6, + BUS7, + BUS8, +}; + +struct i2c_device_platform_data { + int parent; + struct i2c_board_info info; + struct i2c_client *client; +}; + +/* pca9548 - add 8 bus */ +static struct pca954x_platform_mode pca954x_mode[] = { + { .adap_id = 1, + .deselect_on_exit = 1, + }, + { .adap_id = 2, + .deselect_on_exit = 1, + }, + { .adap_id = 3, + .deselect_on_exit = 1, + }, + { .adap_id = 4, + .deselect_on_exit = 1, + }, + { .adap_id = 5, + .deselect_on_exit = 1, + }, + { .adap_id = 6, + .deselect_on_exit = 1, + }, + { .adap_id = 7, + .deselect_on_exit = 1, + }, + { .adap_id = 8, + .deselect_on_exit = 1, + }, +}; + +static struct pca954x_platform_data pca954x_data = { + .modes = pca954x_mode, + .num_modes = ARRAY_SIZE(pca954x_mode), +}; + +static struct i2c_board_info __initdata i2c_info_pca9548[] = +{ + { + I2C_BOARD_INFO("pca9548", 0x70), + .platform_data = &pca954x_data, + }, +}; + +static struct i2c_device_platform_data agc032_i2c_device_platform_data[] = { + { + /* psu 1 (0x58) */ + .parent = 1, + .info = { .type = "dni_agc032_psu", .addr = 0x58, .platform_data = (void *) 0 }, + .client = NULL, + }, + { + /* psu 2 (0x58) */ + .parent = 2, + .info = { .type = "dni_agc032_psu", .addr = 0x58, .platform_data = (void *) 1 }, + .client = NULL, + }, + { + /* FAN 1 Controller (0x2e) */ + .parent = 4, + .info = { I2C_BOARD_INFO("emc2302", 0x2e) }, + .client = NULL, + }, + { + /* FAN 2 Controller (0x4c) */ + .parent = 4, + .info = { I2C_BOARD_INFO("emc2305", 0x4c) }, + .client = NULL, + }, + { + /* FAN 3 Controller (0x2d) */ + .parent = 4, + .info = { I2C_BOARD_INFO("emc2305", 0x2d) }, + .client = NULL, + }, + { + /* tmp75 (0x4f) */ + .parent = 4, + .info = { I2C_BOARD_INFO("tmp75", 0x4f) }, + .client = NULL, + }, + { + /* tmp75 (0x49) */ + .parent = 5, + .info = { I2C_BOARD_INFO("tmp75", 0x49) }, + .client = NULL, + }, + { + /* tmp75 (0x4a) */ + .parent = 5, + .info = { I2C_BOARD_INFO("tmp75", 0x4a) }, + .client = NULL, + }, + { + /* tmp75 (0x4b) */ + .parent = 5, + .info = { I2C_BOARD_INFO("tmp75", 0x4b) }, + .client = NULL, + }, + { + /* tmp75 (0x4d) */ + .parent = 5, + .info = { I2C_BOARD_INFO("tmp75", 0x4d) }, + .client = NULL, + }, + { + /* tmp75 (0x4e) */ + .parent = 5, + .info = { I2C_BOARD_INFO("tmp75", 0x4e) }, + .client = NULL, + }, +}; + +static void device_release(struct device *dev) +{ + return; +} + +static struct platform_device agc032_i2c_device[] = { + agc032_i2c_device_num(0), + agc032_i2c_device_num(1), + agc032_i2c_device_num(2), + agc032_i2c_device_num(3), + agc032_i2c_device_num(4), + agc032_i2c_device_num(5), + agc032_i2c_device_num(6), + agc032_i2c_device_num(7), + agc032_i2c_device_num(8), + agc032_i2c_device_num(9), + agc032_i2c_device_num(10), +}; + +static int __init i2c_device_probe(struct platform_device *pdev) +{ + struct i2c_device_platform_data *pdata; + struct i2c_adapter *parent; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "Missing platform data\n"); + return -ENODEV; + } + + parent = i2c_get_adapter(pdata->parent); + if (!parent) { + dev_err(&pdev->dev, "Parent adapter (%d) not found\n", + pdata->parent); + return -ENODEV; + } + + pdata->client = i2c_new_device(parent, &pdata->info); + if (!pdata->client) { + dev_err(&pdev->dev, "Failed to create i2c client %s at %d\n", + pdata->info.type, pdata->parent); + return -ENODEV; + } + + return 0; +} + +static int __exit i2c_deivce_remove(struct platform_device *pdev) +{ + struct i2c_adapter *parent; + struct i2c_device_platform_data *pdata; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "Missing platform data\n"); + return -ENODEV; + } + + if (pdata->client) { + parent = (pdata->client)->adapter; + i2c_unregister_device(pdata->client); + i2c_put_adapter(parent); + } + + return 0; +} + + +static struct platform_driver i2c_device_driver = { + .probe = i2c_device_probe, + .remove = __exit_p(i2c_deivce_remove), + .driver = { + .owner = THIS_MODULE, + .name = "delta-agc032-i2c-device", + } +}; + +static int __init delta_agc032_platform_init(void) +{ + struct i2c_adapter *adapter; + struct cpld_platform_data *cpld_pdata; + int ret = 0; + int cnt = 0; + + printk("agc032_platform module initialization\n"); + + adapter = i2c_get_adapter(BUS0); +// i2c_client_9548 = i2c_new_device(adapter, &i2c_info_pca9548[0]); + + i2c_put_adapter(adapter); + + /* register the i2c devices */ + ret = platform_driver_register(&i2c_device_driver); + if (ret) { + printk(KERN_WARNING "Fail to register i2c device driver\n"); + goto error_i2c_device_driver; + } + + for (cnt = 0; cnt < ARRAY_SIZE(agc032_i2c_device); cnt++) + { + ret = platform_device_register(&agc032_i2c_device[cnt]); + if (ret) { + printk(KERN_WARNING "Fail to create i2c device %d\n", cnt); + goto error_agc032_i2c_device; + } + } + + return 0; + +error_agc032_i2c_device: + for (; cnt >= 0; cnt--) { + platform_device_unregister(&agc032_i2c_device[cnt]); + } + platform_driver_unregister(&i2c_device_driver); +error_i2c_device_driver: + return ret; +} + +static void __exit delta_agc032_platform_exit(void) +{ + int i = 0; + + for ( i = 0; i < ARRAY_SIZE(agc032_i2c_device); i++ ) { + platform_device_unregister(&agc032_i2c_device[i]); + } + + platform_driver_unregister(&i2c_device_driver); +// i2c_unregister_device(i2c_client_9548); +} + + +module_init(delta_agc032_platform_init); +module_exit(delta_agc032_platform_exit); + +MODULE_DESCRIPTION("DNI agc032 Platform Support"); +MODULE_AUTHOR("James Ke "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-delta/agc032/modules/delta_agc032_qsfp.c b/platform/broadcom/sonic-platform-modules-delta/agc032/modules/delta_agc032_qsfp.c new file mode 100644 index 000000000000..df58430b6aa6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/agc032/modules/delta_agc032_qsfp.c @@ -0,0 +1,819 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#define agc032_i2c_device1_num(c){ \ + .name = "delta-agc032-i2c-pca9548-1", \ + .id = c, \ + .dev = { \ + .platform_data = &agc032_i2c_device_pca9548_1_data[c], \ + .release = device_release, \ + }, \ +} + +#define agc032_i2c_device2_num(c){ \ + .name = "delta-agc032-i2c-pca9548-2", \ + .id = c, \ + .dev = { \ + .platform_data = &agc032_i2c_device_pca9548_2_data[c], \ + .release = device_release, \ + }, \ +} + +#define agc032_i2c_device3_num(c){ \ + .name = "delta-agc032-i2c-pca9548-3", \ + .id = c, \ + .dev = { \ + .platform_data = &agc032_i2c_device_pca9548_3_data[c], \ + .release = device_release, \ + }, \ +} + +#define agc032_i2c_device4_num(c){ \ + .name = "delta-agc032-i2c-pca9548-4", \ + .id = c, \ + .dev = { \ + .platform_data = &agc032_i2c_device_pca9548_4_data[c], \ + .release = device_release, \ + }, \ +} + +#define agc032_i2c_device5_num(c){ \ + .name = "delta-agc032-i2c-pca9548-5", \ + .id = c, \ + .dev = { \ + .platform_data = &agc032_i2c_device_pca9548_5_data[c], \ + .release = device_release, \ + }, \ +} + +/* Define struct to get client of i2c_new_deivce at 0x70, 0x71, 0x72, 0x73 */ +struct i2c_client * i2c_client_9548_1; +struct i2c_client * i2c_client_9548_2; +struct i2c_client * i2c_client_9548_3; +struct i2c_client * i2c_client_9548_4; +struct i2c_client * i2c_client_9548_5; + +enum{ + BUS0 = 0, + BUS1, + BUS2, + BUS3, + BUS4, + BUS5, + BUS6, + BUS7, + BUS8, +}; + +struct i2c_device_platform_data { + int parent; + struct i2c_board_info info; + struct i2c_client *client; +}; + +/* pca9548-1 - add 8 bus */ +static struct pca954x_platform_mode pca954x_mode[] = { + { .adap_id = 1, + .deselect_on_exit = 1, + }, + { .adap_id = 2, + .deselect_on_exit = 1, + }, + { .adap_id = 3, + .deselect_on_exit = 1, + }, + { .adap_id = 4, + .deselect_on_exit = 1, + }, + { .adap_id = 5, + .deselect_on_exit = 1, + }, + { .adap_id = 6, + .deselect_on_exit = 1, + }, + { .adap_id = 7, + .deselect_on_exit = 1, + }, + { .adap_id = 8, + .deselect_on_exit = 1, + }, +}; + +/* pca9548-2 - add 8 bus */ +static struct pca954x_platform_mode pca954x_mode2[] = { + { .adap_id = 9, + .deselect_on_exit = 1, + }, + { .adap_id = 10, + .deselect_on_exit = 1, + }, + { .adap_id = 11, + .deselect_on_exit = 1, + }, + { .adap_id = 12, + .deselect_on_exit = 1, + }, + { .adap_id = 13, + .deselect_on_exit = 1, + }, + { .adap_id = 14, + .deselect_on_exit = 1, + }, + { .adap_id = 15, + .deselect_on_exit = 1, + }, + { .adap_id = 16, + .deselect_on_exit = 1, + }, +}; + +/* pca9548-3 - add 8 bus */ +static struct pca954x_platform_mode pca954x_mode3[] = { + { .adap_id = 17, + .deselect_on_exit = 1, + }, + { .adap_id = 18, + .deselect_on_exit = 1, + }, + { .adap_id = 19, + .deselect_on_exit = 1, + }, + { .adap_id = 20, + .deselect_on_exit = 1, + }, + { .adap_id = 21, + .deselect_on_exit = 1, + }, + { .adap_id = 22, + .deselect_on_exit = 1, + }, + { .adap_id = 23, + .deselect_on_exit = 1, + }, + { .adap_id = 24, + .deselect_on_exit = 1, + }, +}; + +/* pca9548-4 - add 8 bus */ +static struct pca954x_platform_mode pca954x_mode4[] = { + { .adap_id = 25, + .deselect_on_exit = 1, + }, + { .adap_id = 26, + .deselect_on_exit = 1, + }, + { .adap_id = 27, + .deselect_on_exit = 1, + }, + { .adap_id = 28, + .deselect_on_exit = 1, + }, + { .adap_id = 29, + .deselect_on_exit = 1, + }, + { .adap_id = 30, + .deselect_on_exit = 1, + }, + { .adap_id = 31, + .deselect_on_exit = 1, + }, + { .adap_id = 32, + .deselect_on_exit = 1, + }, +}; + +/* pca9548-5 - add 2 bus */ +static struct pca954x_platform_mode pca954x_mode5[] = { + { .adap_id = 33, + .deselect_on_exit = 1, + }, + { .adap_id = 34, + .deselect_on_exit = 1, + }, +}; + +static struct pca954x_platform_data pca954x_data = { + .modes = pca954x_mode, + .num_modes = ARRAY_SIZE(pca954x_mode), +}; + +static struct pca954x_platform_data pca954x_data2 = { + .modes = pca954x_mode2, + .num_modes = ARRAY_SIZE(pca954x_mode2), +}; + +static struct pca954x_platform_data pca954x_data3 = { + .modes = pca954x_mode3, + .num_modes = ARRAY_SIZE(pca954x_mode3), +}; + +static struct pca954x_platform_data pca954x_data4 = { + .modes = pca954x_mode4, + .num_modes = ARRAY_SIZE(pca954x_mode4), +}; + +static struct pca954x_platform_data pca954x_data5 = { + .modes = pca954x_mode5, + .num_modes = ARRAY_SIZE(pca954x_mode5), +}; + +static struct i2c_board_info __initdata i2c_info_pca9548[] = +{ + { + I2C_BOARD_INFO("pca9548", 0x70), + .platform_data = &pca954x_data, + }, + { + I2C_BOARD_INFO("pca9548", 0x71), + .platform_data = &pca954x_data2, + }, + { + I2C_BOARD_INFO("pca9548", 0x72), + .platform_data = &pca954x_data3, + }, + { + I2C_BOARD_INFO("pca9548", 0x73), + .platform_data = &pca954x_data4, + }, + { + I2C_BOARD_INFO("pca9548", 0x74), + .platform_data = &pca954x_data5, + }, +}; + +static struct i2c_device_platform_data agc032_i2c_device_pca9548_1_data[] = { + { + // qsfp 1 (0x50) + .parent = 1, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 2 (0x50) + .parent = 2, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 3 (0x50) + .parent = 3, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 4 (0x50) + .parent = 4, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 5 (0x50) + .parent = 5, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 6 (0x50) + .parent = 6, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 7 (0x50) + .parent = 7, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 8 (0x50) + .parent = 8, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, +}; + +static struct i2c_device_platform_data agc032_i2c_device_pca9548_2_data[] = { + { + // qsfp 9 (0x50) + .parent = 9, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 10 (0x50) + .parent = 10, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 11 (0x50) + .parent = 11, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 12 (0x50) + .parent = 12, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 13 (0x50) + .parent = 13, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 14 (0x50) + .parent = 14, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 15 (0x50) + .parent = 15, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 16 (0x50) + .parent = 16, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, +}; + +static struct i2c_device_platform_data agc032_i2c_device_pca9548_3_data[] = { + { + // qsfp 17 (0x50) + .parent = 17, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 18 (0x50) + .parent = 18, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 19 (0x50) + .parent = 19, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 20 (0x50) + .parent = 20, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 21 (0x50) + .parent = 21, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 22 (0x50) + .parent = 22, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 23 (0x50) + .parent = 23, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 24 (0x50) + .parent = 24, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, +}; + +static struct i2c_device_platform_data agc032_i2c_device_pca9548_4_data[] = { + { + // qsfp 25 (0x50) + .parent = 25, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 26 (0x50) + .parent = 26, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 27 (0x50) + .parent = 27, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 28 (0x50) + .parent = 28, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 29 (0x50) + .parent = 29, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 30 (0x50) + .parent = 30, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 31 (0x50) + .parent = 31, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 32 (0x50) + .parent = 32, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, +}; + +static struct i2c_device_platform_data agc032_i2c_device_pca9548_5_data[] = { + { + // qsfp 33 (0x50) + .parent = 33, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 34 (0x50) + .parent = 34, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, +}; + +static void device_release(struct device *dev) +{ + return; +} + +static struct platform_device agc032_i2c_device1[] = { + agc032_i2c_device1_num(0), + agc032_i2c_device1_num(1), + agc032_i2c_device1_num(2), + agc032_i2c_device1_num(3), + agc032_i2c_device1_num(4), + agc032_i2c_device1_num(5), + agc032_i2c_device1_num(6), + agc032_i2c_device1_num(7), +}; + +static struct platform_device agc032_i2c_device2[] = { + agc032_i2c_device2_num(0), + agc032_i2c_device2_num(1), + agc032_i2c_device2_num(2), + agc032_i2c_device2_num(3), + agc032_i2c_device2_num(4), + agc032_i2c_device2_num(5), + agc032_i2c_device2_num(6), + agc032_i2c_device2_num(7), +}; + +static struct platform_device agc032_i2c_device3[] = { + agc032_i2c_device3_num(0), + agc032_i2c_device3_num(1), + agc032_i2c_device3_num(2), + agc032_i2c_device3_num(3), + agc032_i2c_device3_num(4), + agc032_i2c_device3_num(5), + agc032_i2c_device3_num(6), + agc032_i2c_device3_num(7), +}; + +static struct platform_device agc032_i2c_device4[] = { + agc032_i2c_device4_num(0), + agc032_i2c_device4_num(1), + agc032_i2c_device4_num(2), + agc032_i2c_device4_num(3), + agc032_i2c_device4_num(4), + agc032_i2c_device4_num(5), + agc032_i2c_device4_num(6), + agc032_i2c_device4_num(7), +}; + +static struct platform_device agc032_i2c_device5[] = { + agc032_i2c_device5_num(0), + agc032_i2c_device5_num(1), +}; + + +static int __init i2c_device_probe(struct platform_device *pdev) +{ + struct i2c_device_platform_data *pdata; + struct i2c_adapter *parent; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "Missing platform data\n"); + return -ENODEV; + } + + parent = i2c_get_adapter(pdata->parent); + if (!parent) { + dev_err(&pdev->dev, "Parent adapter (%d) not found\n", + pdata->parent); + return -ENODEV; + } + + pdata->client = i2c_new_device(parent, &pdata->info); + if (!pdata->client) { + dev_err(&pdev->dev, "Failed to create i2c client %s at %d\n", + pdata->info.type, pdata->parent); + return -ENODEV; + } + + return 0; +} + +static int __exit i2c_deivce_remove(struct platform_device *pdev) +{ + struct i2c_adapter *parent; + struct i2c_device_platform_data *pdata; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "Missing platform data\n"); + return -ENODEV; + } + + if (pdata->client) { + parent = (pdata->client)->adapter; + i2c_unregister_device(pdata->client); + i2c_put_adapter(parent); + } + + return 0; +} + + +static struct platform_driver i2c_device_pca9548_1_driver = { + .probe = i2c_device_probe, + .remove = __exit_p(i2c_deivce_remove), + .driver = { + .owner = THIS_MODULE, + .name = "delta-agc032-i2c-pca9548-1", + } +}; + +static struct platform_driver i2c_device_pca9548_2_driver = { + .probe = i2c_device_probe, + .remove = __exit_p(i2c_deivce_remove), + .driver = { + .owner = THIS_MODULE, + .name = "delta-agc032-i2c-pca9548-2", + } +}; + +static struct platform_driver i2c_device_pca9548_3_driver = { + .probe = i2c_device_probe, + .remove = __exit_p(i2c_deivce_remove), + .driver = { + .owner = THIS_MODULE, + .name = "delta-agc032-i2c-pca9548-3", + } +}; + +static struct platform_driver i2c_device_pca9548_4_driver = { + .probe = i2c_device_probe, + .remove = __exit_p(i2c_deivce_remove), + .driver = { + .owner = THIS_MODULE, + .name = "delta-agc032-i2c-pca9548-4", + } +}; + +static struct platform_driver i2c_device_pca9548_5_driver = { + .probe = i2c_device_probe, + .remove = __exit_p(i2c_deivce_remove), + .driver = { + .owner = THIS_MODULE, + .name = "delta-agc032-i2c-pca9548-5", + } +}; + +static int __init delta_agc032_platform_init(void) +{ + struct i2c_adapter *adapter; + int ret = 0; + int device1_cnt = 0; + int device2_cnt = 0; + int device3_cnt = 0; + int device4_cnt = 0; + int device5_cnt = 0; + + printk("agc032_qsfp module initialization\n"); + + adapter = i2c_get_adapter(BUS0); + i2c_client_9548_1 = i2c_new_device(adapter, &i2c_info_pca9548[0]); + i2c_client_9548_2 = i2c_new_device(adapter, &i2c_info_pca9548[1]); + i2c_client_9548_3 = i2c_new_device(adapter, &i2c_info_pca9548[2]); + i2c_client_9548_4 = i2c_new_device(adapter, &i2c_info_pca9548[3]); + i2c_client_9548_5 = i2c_new_device(adapter, &i2c_info_pca9548[4]); + i2c_put_adapter(adapter); + + /* pca9548-0x70 */ + ret = platform_driver_register(&i2c_device_pca9548_1_driver); + if (ret) { + printk(KERN_WARNING "Fail to register i2c device driver\n"); + goto error_i2c_device_pca9548_1_driver; + } + + for (device1_cnt = 0; device1_cnt < ARRAY_SIZE(agc032_i2c_device1); device1_cnt++) + { + ret = platform_device_register(&agc032_i2c_device1[device1_cnt]); + if (ret) { + printk(KERN_WARNING "Fail to create i2c device %d\n", device1_cnt); + goto error_agc032_i2c_device; + } + } + + + /* pca9548-0x71 */ + ret = platform_driver_register(&i2c_device_pca9548_2_driver); + if (ret) { + printk(KERN_WARNING "Fail to register i2c device driver\n"); + goto error_i2c_device_pca9548_2_driver; + } + + for (device2_cnt = 0; device2_cnt < ARRAY_SIZE(agc032_i2c_device2); device2_cnt++) + { + ret = platform_device_register(&agc032_i2c_device2[device2_cnt]); + if (ret) { + printk(KERN_WARNING "Fail to create i2c device %d\n", device2_cnt); + goto error_agc032_i2c_device2; + } + } + + /* pca9548-0x72 */ + ret = platform_driver_register(&i2c_device_pca9548_3_driver); + if (ret) { + printk(KERN_WARNING "Fail to register i2c device driver\n"); + goto error_i2c_device_pca9548_3_driver; + } + + for (device3_cnt = 0; device3_cnt < ARRAY_SIZE(agc032_i2c_device3); device3_cnt++) + { + ret = platform_device_register(&agc032_i2c_device3[device3_cnt]); + if (ret) { + printk(KERN_WARNING "Fail to create i2c device %d\n", device3_cnt); + goto error_agc032_i2c_device3; + } + } + + /* pca9548-0x73 */ + ret = platform_driver_register(&i2c_device_pca9548_4_driver); + if (ret) { + printk(KERN_WARNING "Fail to register i2c device driver\n"); + goto error_i2c_device_pca9548_4_driver; + } + + for (device4_cnt = 0; device4_cnt < ARRAY_SIZE(agc032_i2c_device4); device4_cnt++) + { + ret = platform_device_register(&agc032_i2c_device4[device4_cnt]); + if (ret) { + printk(KERN_WARNING "Fail to create i2c device %d\n", device4_cnt); + goto error_agc032_i2c_device4; + } + } + + /* pca9548-0x74 */ + ret = platform_driver_register(&i2c_device_pca9548_5_driver); + if (ret) { + printk(KERN_WARNING "Fail to register i2c device driver\n"); + goto error_i2c_device_pca9548_5_driver; + } + + for (device5_cnt = 0; device5_cnt < ARRAY_SIZE(agc032_i2c_device5); device5_cnt++) + { + ret = platform_device_register(&agc032_i2c_device5[device5_cnt]); + if (ret) { + printk(KERN_WARNING "Fail to create i2c device %d\n", device5_cnt); + goto error_agc032_i2c_device5; + } + } + + + return 0; + +/* Error handling */ +error_agc032_i2c_device5: + for (; device5_cnt >= 0; device5_cnt--) { + platform_device_unregister(&agc032_i2c_device5[device5_cnt]); + } + platform_driver_unregister(&i2c_device_pca9548_5_driver); +error_i2c_device_pca9548_5_driver: +error_agc032_i2c_device4: + for (; device4_cnt >= 0; device4_cnt--) { + platform_device_unregister(&agc032_i2c_device4[device4_cnt]); + } + platform_driver_unregister(&i2c_device_pca9548_4_driver); +error_i2c_device_pca9548_4_driver: +error_agc032_i2c_device3: + for (; device3_cnt >= 0; device3_cnt--) { + platform_device_unregister(&agc032_i2c_device3[device3_cnt]); + } + platform_driver_unregister(&i2c_device_pca9548_3_driver); +error_i2c_device_pca9548_3_driver: +error_agc032_i2c_device2: + for (; device2_cnt >= 0; device2_cnt--) { + platform_device_unregister(&agc032_i2c_device2[device2_cnt]); + } + platform_driver_unregister(&i2c_device_pca9548_2_driver); +error_i2c_device_pca9548_2_driver: +error_agc032_i2c_device: + for (; device1_cnt >= 0; device1_cnt--) { + platform_device_unregister(&agc032_i2c_device1[device1_cnt]); + } + platform_driver_unregister(&i2c_device_pca9548_1_driver); +error_i2c_device_pca9548_1_driver: + return ret; +} + +static void __exit delta_agc032_platform_exit(void) +{ + int i = 0; + + // unregister pca9548-1 (0x70) + for ( i = 0; i < ARRAY_SIZE(agc032_i2c_device1); i++ ) { + platform_device_unregister(&agc032_i2c_device1[i]); + } + + platform_driver_unregister(&i2c_device_pca9548_1_driver); + i2c_unregister_device(i2c_client_9548_1); + + // unregister pca9548-2 (0x71) + for ( i = 0; i < ARRAY_SIZE(agc032_i2c_device2); i++ ) { + platform_device_unregister(&agc032_i2c_device2[i]); + } + + platform_driver_unregister(&i2c_device_pca9548_2_driver); + i2c_unregister_device(i2c_client_9548_2); + + // unregister pca9548-3 (0x72) + for ( i = 0; i < ARRAY_SIZE(agc032_i2c_device3); i++ ) { + platform_device_unregister(&agc032_i2c_device3[i]); + } + + platform_driver_unregister(&i2c_device_pca9548_3_driver); + i2c_unregister_device(i2c_client_9548_3); + + // unregister pca9548-4 (0x73) + for ( i = 0; i < ARRAY_SIZE(agc032_i2c_device4); i++ ) { + platform_device_unregister(&agc032_i2c_device4[i]); + } + + platform_driver_unregister(&i2c_device_pca9548_4_driver); + i2c_unregister_device(i2c_client_9548_4); + + // unregister pca9548-5 (0x74) + for ( i = 0; i < ARRAY_SIZE(agc032_i2c_device5); i++ ) { + platform_device_unregister(&agc032_i2c_device5[i]); + } + + platform_driver_unregister(&i2c_device_pca9548_5_driver); + i2c_unregister_device(i2c_client_9548_5); +} + + +module_init(delta_agc032_platform_init); +module_exit(delta_agc032_platform_exit); + +MODULE_DESCRIPTION("Delta agc032 QSFP-DD eeprom Support"); +MODULE_AUTHOR("Zoe Kuan "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-delta/agc032/modules/delta_agc032_swpld.c b/platform/broadcom/sonic-platform-modules-delta/agc032/modules/delta_agc032_swpld.c new file mode 100644 index 000000000000..2396dfff8b48 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/agc032/modules/delta_agc032_swpld.c @@ -0,0 +1,2841 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#define SWPLD1_ADDR 0x32 +#define SWPLD2_ADDR 0x34 +#define SWPLD3_ADDR 0x35 + + + +enum cpld_type { + swpld1 = 0, + swpld2, + swpld3, +}; + +enum { + BUS0 = 0, + BUS1, + BUS2, + BUS3, + BUS4, + BUS5, + BUS6, + BUS7, + BUS8, +}; + +enum swpld1_attr{ + BOARD_ID = 0, + BOARD_VER, + SWPLD1_VER_TYPE, + SWPLD1_VER, + USB_HUB_RST, + SYNCE_RST, + BMC_RST, + LPC_RST, + OOB_PCIE_RST, + MAC_PCIE_RST, + MAC_RST, + VR_3V3_RST, + VR_0V8_RST, + FAN_MUX_RST, + QSFP5_MUX_RST, + QSFP4_MUX_RST, + QSFP3_MUX_RST, + QSFP2_MUX_RST, + QSFP1_MUX_RST, + PSU1_PRESENT, + PSU1_STATE, + PSU1_ALERT, + PSU2_PRESENT, + PSU2_STATE, + PSU2_ALERT, + PSU1_EN, + PSU1_EEPROM_WP, + PSU2_EN, + PSU2_EEPROM_WP, + VCC_5V_EN, + VCC_3V3_EN, + VCC_VCORE_EN, + VCC_MAC_1V8_EN, + VCC_MAC_1V2_EN, + VCC_MAC_0V8_EN, + VCC_PLL_0V8_EN, + VCC_SYS_EN, + OOB_PWR_STATE, + OOB_OP_EN, + USB1_OP_EN, + PSU_INTR, + FAN_ALERT, + SWPLD2_INTR, + SWPLD3_INTR, + PSU1_LED, + PSU2_LED, + SYS_LED, + FAN_LED, + FAN1_LED, + FAN2_LED, + FAN3_LED, + FAN4_LED, + FAN5_LED, + FAN6_LED, + SYNCE_EEPROM_WB, + CONSOLE_SEL, + SYS_EEPROM_WB, +}; + +/* SWPLD2 */ +enum swpld2_attr{ + SWPLD2_VER_TYPE = 0, + SWPLD2_VER, + QSFP_P01_RST, + QSFP_P02_RST, + QSFP_P03_RST, + QSFP_P04_RST, + QSFP_P05_RST, + QSFP_P06_RST, + QSFP_P07_RST, + QSFP_P08_RST, + QSFP_P09_RST, + QSFP_P10_RST, + QSFP_P11_RST, + QSFP_P12_RST, + QSFP_P13_RST, + QSFP_P14_RST, + QSFP_P15_RST, + QSFP_P16_RST, + QSFP_P01_LPMODE, + QSFP_P02_LPMODE, + QSFP_P03_LPMODE, + QSFP_P04_LPMODE, + QSFP_P05_LPMODE, + QSFP_P06_LPMODE, + QSFP_P07_LPMODE, + QSFP_P08_LPMODE, + QSFP_P09_LPMODE, + QSFP_P10_LPMODE, + QSFP_P11_LPMODE, + QSFP_P12_LPMODE, + QSFP_P13_LPMODE, + QSFP_P14_LPMODE, + QSFP_P15_LPMODE, + QSFP_P16_LPMODE, + QSFP_P01_MODPRS, + QSFP_P02_MODPRS, + QSFP_P03_MODPRS, + QSFP_P04_MODPRS, + QSFP_P05_MODPRS, + QSFP_P06_MODPRS, + QSFP_P07_MODPRS, + QSFP_P08_MODPRS, + QSFP_P09_MODPRS, + QSFP_P10_MODPRS, + QSFP_P11_MODPRS, + QSFP_P12_MODPRS, + QSFP_P13_MODPRS, + QSFP_P14_MODPRS, + QSFP_P15_MODPRS, + QSFP_P16_MODPRS, + QSFP_P01_INTR, + QSFP_P02_INTR, + QSFP_P03_INTR, + QSFP_P04_INTR, + QSFP_P05_INTR, + QSFP_P06_INTR, + QSFP_P07_INTR, + QSFP_P08_INTR, + QSFP_P09_INTR, + QSFP_P10_INTR, + QSFP_P11_INTR, + QSFP_P12_INTR, + QSFP_P13_INTR, + QSFP_P14_INTR, + QSFP_P15_INTR, + QSFP_P16_INTR, +}; + +/* SWPLD3 */ +enum swpld3_attr{ + SWPLD3_VER_TYPE = 160, + SWPLD3_VER, + QSFP_P17_RST, + QSFP_P18_RST, + QSFP_P19_RST, + QSFP_P20_RST, + QSFP_P21_RST, + QSFP_P22_RST, + QSFP_P23_RST, + QSFP_P24_RST, + QSFP_P25_RST, + QSFP_P26_RST, + QSFP_P27_RST, + QSFP_P28_RST, + QSFP_P29_RST, + QSFP_P30_RST, + QSFP_P31_RST, + QSFP_P32_RST, + QSFP_P17_LPMODE, + QSFP_P18_LPMODE, + QSFP_P19_LPMODE, + QSFP_P20_LPMODE, + QSFP_P21_LPMODE, + QSFP_P22_LPMODE, + QSFP_P23_LPMODE, + QSFP_P24_LPMODE, + QSFP_P25_LPMODE, + QSFP_P26_LPMODE, + QSFP_P27_LPMODE, + QSFP_P28_LPMODE, + QSFP_P29_LPMODE, + QSFP_P30_LPMODE, + QSFP_P31_LPMODE, + QSFP_P32_LPMODE, + QSFP_P17_MODPRS, + QSFP_P18_MODPRS, + QSFP_P19_MODPRS, + QSFP_P20_MODPRS, + QSFP_P21_MODPRS, + QSFP_P22_MODPRS, + QSFP_P23_MODPRS, + QSFP_P24_MODPRS, + QSFP_P25_MODPRS, + QSFP_P26_MODPRS, + QSFP_P27_MODPRS, + QSFP_P28_MODPRS, + QSFP_P29_MODPRS, + QSFP_P30_MODPRS, + QSFP_P31_MODPRS, + QSFP_P32_MODPRS, + QSFP_P17_INTR, + QSFP_P18_INTR, + QSFP_P19_INTR, + QSFP_P20_INTR, + QSFP_P21_INTR, + QSFP_P22_INTR, + QSFP_P23_INTR, + QSFP_P24_INTR, + QSFP_P25_INTR, + QSFP_P26_INTR, + QSFP_P27_INTR, + QSFP_P28_INTR, + QSFP_P29_INTR, + QSFP_P30_INTR, + QSFP_P31_INTR, + QSFP_P32_INTR, + SFP_P0_MODPRS, + SFP_P0_RXLOS, + SFP_P0_TXFAULT, + SFP_P1_MODPRS, + SFP_P1_RXLOS, + SFP_P1_TXFAULT, + SFP_P0_TXDIS, + SFP_P1_TXDIS, +}; + + +struct platform_data { + int reg_addr; + struct i2c_client *client; +}; + +struct cpld_platform_data { + int reg_addr; + struct i2c_client *client; +}; + +static struct kobject *kobj_swpld1; +static struct kobject *kobj_swpld2; +static struct kobject *kobj_swpld3; + +static struct kobject *kobj_test1; +static struct kobject *kobj_test2; + +unsigned char swpld1_reg_addr; +unsigned char swpld2_reg_addr; +unsigned char swpld3_reg_addr; + + + +static ssize_t swpld1_data_show(struct device *dev, struct device_attribute *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct device *i2cdev = kobj_to_dev(kobj_swpld1->parent); + struct platform_data *pdata = i2cdev->platform_data; + unsigned int select = 0; + unsigned char offset = 0; + int mask = 0xFF; + int shift = 0; + int value = 0; + bool hex_fmt = 0; + char desc[256] = {0}; + + select = attr->index; + switch(select) { + case BOARD_ID: + offset = 0x1; + hex_fmt = 1; + scnprintf(desc, PAGE_SIZE, "\nBorad ID.\n"); + break; + case BOARD_VER: + offset = 0x2; + hex_fmt = 1; + scnprintf(desc, PAGE_SIZE, "\nBorad Version.\n"); + break; + case SWPLD1_VER_TYPE: + offset = 0x3; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nSWPLD1 Version Type.\n"); + break; + case SWPLD1_VER: + offset = 0x3; + mask = 0x7f; + scnprintf(desc, PAGE_SIZE, "\nSWPLD1 Version.\n"); + break; + case USB_HUB_RST: + offset = 0x6; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nUSB Reset.\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case SYNCE_RST: + offset = 0x6; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nSynce Reset.\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case BMC_RST: + offset = 0x6; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nBMC Reset.\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case LPC_RST: + offset = 0x6; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nBMC LPC Reset.\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case OOB_PCIE_RST: + offset = 0x6; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nOOB PCIE Reset.\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case MAC_PCIE_RST: + offset = 0x6; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nMAC PCIE Reset.\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case MAC_RST: + offset = 0x6; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nMAC Reset.\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case VR_3V3_RST: + offset = 0x7; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nVR 3V3 Reset.\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case VR_0V8_RST: + offset = 0x7; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nVR 0V8 Reset.\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case FAN_MUX_RST: + offset = 0x8; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nFAN I2C Mux Reset.\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case QSFP5_MUX_RST: + offset = 0x8; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nQSFP5 Reset.\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case QSFP4_MUX_RST: + offset = 0x8; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nQSFP4 Reset.\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case QSFP3_MUX_RST: + offset = 0x8; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nQSFP3 Reset.\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case QSFP2_MUX_RST: + offset = 0x8; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nQSFP2 Reset.\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case QSFP1_MUX_RST: + offset = 0x8; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nQSFP1 Reset.\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case PSU1_PRESENT: + offset = 0x11; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= PSU1 Not Present.\n“0†= PSU1 Present.\n"); + break; + case PSU1_STATE: + offset = 0x11; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= PSU1 Power Not Good.\n“0†= PSU1 Power Good.\n"); + break; + case PSU1_ALERT: + offset = 0x11; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= PSU1 Alert Active.\n“0†= PSU1 Alert Not Active.\n"); + break; + case PSU2_PRESENT: + offset = 0x11; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= PSU2 Not Present.\n“0†= PSU2 Present.\n"); + break; + case PSU2_STATE: + offset = 0x11; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case PSU2_ALERT: + offset = 0x11; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= PSU2 Alert Active.\n“0†= PSU2 Alert Not Active.\n"); + break; + case PSU1_EN: + offset = 0x12; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Disable PSU1.\n“0†= Enable PSU1.\n"); + break; + case PSU1_EEPROM_WP: + offset = 0x12; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Enable PSU1 EEPROM Write Protect.\n“0†= Disable PSU1 EEPROM Write Protect.\n"); + break; + case PSU2_EN: + offset = 0x12; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Disable PSU2.\n“0†= Enable PSU2.\n"); + break; + case PSU2_EEPROM_WP: + offset = 0x12; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Enable PSU2 EEPROM Write Protect.\n“0†= Disable PSU2 EEPROM Write Protect.\n"); + break; + case VCC_5V_EN: + offset = 0x23; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Enable VCC 5V.\n“0†= Disable VCC 5V.\n"); + break; + case VCC_3V3_EN: + offset = 0x23; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Enable VCC 3V3.\n“0†= Disable VCC 3V3.\n"); + break; + case VCC_VCORE_EN: + offset = 0x23; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Enable AVS 0V91.\n“0†= Disable AVS 0V91.\n"); + break; + case VCC_MAC_1V8_EN: + offset = 0x23; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Enable MAC 1V8.\n“0†= Disable MAC 1V8.\n"); + break; + case VCC_MAC_1V2_EN: + offset = 0x23; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Enable MAC 1V2.\n“0†= Disable MAC 1V2.\n"); + break; + case VCC_MAC_0V8_EN: + offset = 0x23; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Enable MAC 0V8.\n“0†= Disable MAC 0V8.\n"); + break; + case VCC_PLL_0V8_EN: + offset = 0x23; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Enable PLL 0V8.\n“0†= Disable PLL 0V8.\n"); + break; + case VCC_SYS_EN: + offset = 0x23; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Enable System Power.\n“0†= Disable System Power.\n"); + break; + case OOB_PWR_STATE: + offset = 0x24; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= OOB Power Rail Good.\n“0†= OOB Power Rail Not Good.\n"); + break; + case OOB_OP_EN: + offset = 0x24; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Enable OOB Operation.\n“0†= Disable OOB Operation.\n"); + break; + case USB1_OP_EN: + offset = 0x24; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Disable USB Operation.\n“0†= Enable USB Operation.\n"); + break; + case PSU_INTR: + offset = 0x26; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= PSU Interrupt Not Occured.\n“0†= PSU Interrupt Occured.\n"); + break; + case FAN_ALERT: + offset = 0x26; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Fan Interrupt Not Occured.\n“0†= Fan Interrupt Occured.\n"); + break; + case SWPLD2_INTR: + offset = 0x27; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= SWPLD2 Interrupt Not Occured.\n“0†= SWPLD2 Interrupt Occured.\n"); + break; + case SWPLD3_INTR: + offset = 0x27; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= SWPLD3 Interrupt Not Occured.\n“0†= SWPLD3 Interrupt Occured.\n)"); + break; + case PSU1_LED: + offset = 0x41; + shift = 2; + mask = 0x0C; + scnprintf(desc, PAGE_SIZE, "\n“3†= LED Off\n“2†= LED Red.\n“1†= LED Green\n“0†= Auto.\n"); + break; + case PSU2_LED: + offset = 0x41; + shift = 0; + mask = 0x03; + scnprintf(desc, PAGE_SIZE, "\n“3†= LED Off\n“2†= LED Red.\n“1†= LED Green\n“0†= Auto.\n"); + break; + case SYS_LED: + offset = 0x42; + shift = 2; + mask = 0x0C; + scnprintf(desc, PAGE_SIZE, "\n“3†= LED Red\n“2†= LED Blink Green.\n“1†= LED Green\n“0†= LED Off.\n"); + break; + case FAN_LED: + offset = 0x42; + shift = 0; + mask = 0x03; + scnprintf(desc, PAGE_SIZE, "\n“3†= LED Off\n“2†= LED Amber.\n“1†= LED Green\n“0†= LED Off.\n"); + break; + case FAN1_LED: + offset = 0x46; + shift = 6; + mask = 0xc0; + scnprintf(desc, PAGE_SIZE, "\n“3†= LED Off\n“2†= LED Red.\n“1†= LED Green\n“0†= LED Off.\n"); + break; + case FAN2_LED: + offset = 0x46; + shift = 4; + mask = 0x30; + scnprintf(desc, PAGE_SIZE, "\n“3†= LED Off\n“2†= LED Red.\n“1†= LED Green\n“0†= LED Off.\n"); + break; + case FAN3_LED: + offset = 0x46; + shift = 2; + mask = 0x0c; + scnprintf(desc, PAGE_SIZE, "\n“3†= LED Off\n“2†= LED Red.\n“1†= LED Green\n“0†= LED Off.\n"); + break; + case FAN4_LED: + offset = 0x46; + shift = 0; + mask = 0x03; + scnprintf(desc, PAGE_SIZE, "\n“3†= LED Off\n“2†= LED Red.\n“1†= LED Green\n“0†= LED Off.\n"); + break; + case FAN5_LED: + offset = 0x47; + shift = 6; + mask = 0xc0; + scnprintf(desc, PAGE_SIZE, "\n“3†= LED Off\n“2†= LED Red.\n“1†= LED Green\n“0†= LED Off.\n"); + break; + case FAN6_LED: + offset = 0x47; + shift = 4; + mask = 0x30; + scnprintf(desc, PAGE_SIZE, "\n“3†= LED Off\n“2†= LED Red.\n“1†= LED Green\n“0†= LED Off.\n"); + break; + case SYNCE_EEPROM_WB: + offset = 0x51; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case CONSOLE_SEL: + offset = 0x51; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + case SYS_EEPROM_WB: + offset = 0x51; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation\n“0†= Reset.\n"); + break; + } + + value = i2c_smbus_read_byte_data(pdata[swpld1].client, offset); + value = (value & mask) >> shift; + if(hex_fmt) { + return scnprintf(buf, PAGE_SIZE, "0x%02x%s", value, desc); + } else { + return scnprintf(buf, PAGE_SIZE, "%d%s", value, desc); + } +} + + +static ssize_t swpld1_data_store(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 device *i2cdev = kobj_to_dev(kobj_swpld1->parent); + struct platform_data *pdata = i2cdev->platform_data; + unsigned int select = 0; + unsigned char offset = 0; + int mask = 0xFF; + int shift = 0; + int value = 0; + int err = 0; + unsigned long data; + + err = kstrtoul(buf, 0, &data); + if (err){ + return err; + } + + if (data > 0xff){ + printk(KERN_ALERT "address out of range (0x00-0xFF)\n"); + return count; + } + + switch (attr->index) { + case USB_HUB_RST: + offset = 0x6; + shift = 6; + mask = (1 << shift); + break; + case SYNCE_RST: + offset = 0x6; + shift = 5; + mask = (1 << shift); + break; + case BMC_RST: + offset = 0x6; + shift = 4; + mask = (1 << shift); + break; + case LPC_RST: + offset = 0x6; + shift = 3; + mask = (1 << shift); + break; + case OOB_PCIE_RST: + offset = 0x6; + shift = 2; + mask = (1 << shift); + break; + case MAC_PCIE_RST: + offset = 0x6; + shift = 1; + mask = (1 << shift); + break; + case MAC_RST: + offset = 0x6; + shift = 0; + mask = (1 << shift); + break; + case VR_3V3_RST: + offset = 0x7; + shift = 3; + mask = (1 << shift); + break; + case VR_0V8_RST: + offset = 0x7; + shift = 2; + mask = (1 << shift); + break; + case FAN_MUX_RST: + offset = 0x8; + shift = 6; + mask = (1 << shift); + break; + case QSFP5_MUX_RST: + offset = 0x8; + shift = 5; + mask = (1 << shift); + break; + case QSFP4_MUX_RST: + offset = 0x8; + shift = 4; + mask = (1 << shift); + break; + case QSFP3_MUX_RST: + offset = 0x8; + shift = 3; + mask = (1 << shift); + break; + case QSFP2_MUX_RST: + offset = 0x8; + shift = 2; + mask = (1 << shift); + break; + case QSFP1_MUX_RST: + offset = 0x8; + shift = 1; + mask = (1 << shift); + break; + case PSU1_EN: + offset = 0x12; + shift = 7; + mask = (1 << shift); + break; + case PSU1_EEPROM_WP: + offset = 0x12; + shift = 6; + mask = (1 << shift); + break; + case PSU2_EN: + offset = 0x12; + shift = 3; + mask = (1 << shift); + break; + case PSU2_EEPROM_WP: + offset = 0x12; + shift = 2; + mask = (1 << shift); + break; + case VCC_5V_EN: + offset = 0x23; + shift = 7; + mask = (1 << shift); + break; + case VCC_3V3_EN: + offset = 0x23; + shift = 6; + mask = (1 << shift); + break; + case VCC_VCORE_EN: + offset = 0x23; + shift = 5; + mask = (1 << shift); + break; + case VCC_MAC_1V8_EN: + offset = 0x23; + shift = 4; + mask = (1 << shift); + break; + case VCC_MAC_1V2_EN: + offset = 0x23; + shift = 3; + mask = (1 << shift); + break; + case VCC_MAC_0V8_EN: + offset = 0x23; + shift = 2; + mask = (1 << shift); + break; + case VCC_PLL_0V8_EN: + offset = 0x23; + shift = 1; + mask = (1 << shift); + break; + case VCC_SYS_EN: + offset = 0x23; + shift = 0; + mask = (1 << shift); + break; + case OOB_OP_EN: + offset = 0x24; + shift = 6; + mask = (1 << shift); + break; + case USB1_OP_EN: + offset = 0x24; + shift = 1; + mask = (1 << shift); + break; + case PSU1_LED: + offset = 0x41; + shift = 2; + mask = 0x0C; + break; + case PSU2_LED: + offset = 0x41; + shift = 0; + mask = 0x03; + break; + case SYS_LED: + offset = 0x42; + shift = 2; + mask = 0x0C; + break; + case FAN_LED: + offset = 0x42; + shift = 0; + mask = 0x03; + break; + case FAN1_LED: + offset = 0x46; + shift = 6; + mask = 0xc0; + break; + case FAN2_LED: + offset = 0x46; + shift = 4; + mask = 0x30; + break; + case FAN3_LED: + offset = 0x46; + shift = 2; + mask = 0x0c; + break; + case FAN4_LED: + offset = 0x46; + shift = 0; + mask = 0x03; + break; + case FAN5_LED: + offset = 0x47; + shift = 6; + mask = 0xc0; + break; + case FAN6_LED: + offset = 0x47; + shift = 4; + mask = 0x30; + break; + case SYNCE_EEPROM_WB: + offset = 0x51; + shift = 5; + mask = (1 << shift); + break; + case CONSOLE_SEL: + offset = 0x51; + shift = 5; + mask = (1 << shift); + break; + case SYS_EEPROM_WB: + offset = 0x51; + shift = 5; + mask = (1 << shift); + break; + } + + value = i2c_smbus_read_byte_data(pdata[swpld1].client, offset); + data = (value & ~mask) | (data << shift); + i2c_smbus_write_byte_data(pdata[swpld1].client, offset, data); + + return count; +} + + +/* offset 0x01 */ +static SENSOR_DEVICE_ATTR(board_id, S_IRUGO, swpld1_data_show, NULL, BOARD_ID); +/* offser 0x02 */ +static SENSOR_DEVICE_ATTR(board_ver, S_IRUGO, swpld1_data_show, NULL, BOARD_VER); +/* offset 0x03 */ +static SENSOR_DEVICE_ATTR(swpld1_ver_type, S_IRUGO, swpld1_data_show, NULL, SWPLD1_VER_TYPE); +static SENSOR_DEVICE_ATTR(swpld1_ver, S_IRUGO, swpld1_data_show, NULL, SWPLD1_VER); +/* offset 0x06 */ +static SENSOR_DEVICE_ATTR(usb_hub_rst, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, USB_HUB_RST); +static SENSOR_DEVICE_ATTR(synce_rst, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, SYNCE_RST); +static SENSOR_DEVICE_ATTR(bmc_rst, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, BMC_RST); +static SENSOR_DEVICE_ATTR(lpc_rst, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, LPC_RST); +static SENSOR_DEVICE_ATTR(oob_pcie_rst, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, OOB_PCIE_RST); +static SENSOR_DEVICE_ATTR(mac_pcie_rst, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, MAC_PCIE_RST); +static SENSOR_DEVICE_ATTR(mac_rst, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, MAC_RST); +/* offset 0x07 */ +static SENSOR_DEVICE_ATTR(vr_3v3_rst, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, VR_3V3_RST); +static SENSOR_DEVICE_ATTR(vr_0v8_rst, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, VR_0V8_RST); +/* offset 0x08 */ +static SENSOR_DEVICE_ATTR(fan_mux_rst, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, FAN_MUX_RST); +static SENSOR_DEVICE_ATTR(qsfp5_mux_rst, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, QSFP5_MUX_RST); +static SENSOR_DEVICE_ATTR(qsfp4_mux_rst, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, QSFP4_MUX_RST); +static SENSOR_DEVICE_ATTR(qsfp3_mux_rst, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, QSFP3_MUX_RST); +static SENSOR_DEVICE_ATTR(qsfp2_mux_rst, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, QSFP2_MUX_RST); +static SENSOR_DEVICE_ATTR(qsfp1_mux_rst, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, QSFP1_MUX_RST); +/* offset 0x11 */ +static SENSOR_DEVICE_ATTR(psu1_present, S_IRUGO, swpld1_data_show, NULL, PSU1_PRESENT); +static SENSOR_DEVICE_ATTR(psu1_state, S_IRUGO, swpld1_data_show, NULL, PSU1_STATE); +static SENSOR_DEVICE_ATTR(psu1_alert, S_IRUGO, swpld1_data_show, NULL, PSU1_ALERT); +static SENSOR_DEVICE_ATTR(psu2_present, S_IRUGO, swpld1_data_show, NULL, PSU2_PRESENT); +static SENSOR_DEVICE_ATTR(psu2_state, S_IRUGO, swpld1_data_show, NULL, PSU2_STATE); +static SENSOR_DEVICE_ATTR(psu2_alert, S_IRUGO, swpld1_data_show, NULL, PSU2_ALERT); +/* offset 0x12 */ +static SENSOR_DEVICE_ATTR(psu1_en, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, PSU1_EN); +static SENSOR_DEVICE_ATTR(psu1_eeprom_wp, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, PSU1_EEPROM_WP); +static SENSOR_DEVICE_ATTR(psu2_en, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, PSU2_EN); +static SENSOR_DEVICE_ATTR(psu2_eeprom_wp, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, PSU2_EEPROM_WP); +/* offset 0x23 */ +static SENSOR_DEVICE_ATTR(vcc_5v_en, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, VCC_5V_EN); +static SENSOR_DEVICE_ATTR(vcc_3v3_en, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, VCC_3V3_EN); +static SENSOR_DEVICE_ATTR(vcc_vcore_en, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, VCC_VCORE_EN); +static SENSOR_DEVICE_ATTR(vcc_mac_1v8_en, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, VCC_MAC_1V8_EN); +static SENSOR_DEVICE_ATTR(vcc_mac_1v2_en, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, VCC_MAC_1V2_EN); +static SENSOR_DEVICE_ATTR(vcc_mac_0v8_en, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, VCC_MAC_0V8_EN); +static SENSOR_DEVICE_ATTR(vcc_pll_0v8_en, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, VCC_PLL_0V8_EN); +static SENSOR_DEVICE_ATTR(vcc_sys_en, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, VCC_SYS_EN); +/* offset 0x24 */ +static SENSOR_DEVICE_ATTR(oob_pwr_state, S_IRUGO, swpld1_data_show, NULL, OOB_PWR_STATE); +static SENSOR_DEVICE_ATTR(oob_op_en, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, OOB_OP_EN); +static SENSOR_DEVICE_ATTR(usb1_op_en, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, USB1_OP_EN); +/* offset 0x26 */ +static SENSOR_DEVICE_ATTR(psu_intr, S_IRUGO, swpld1_data_show, NULL, PSU_INTR); +static SENSOR_DEVICE_ATTR(fan_alert, S_IRUGO, swpld1_data_show, NULL, FAN_ALERT); +/* offset 0x27 */ +static SENSOR_DEVICE_ATTR(swpld2_intr, S_IRUGO, swpld1_data_show, NULL, SWPLD2_INTR); +static SENSOR_DEVICE_ATTR(swpld3_intr, S_IRUGO, swpld1_data_show, NULL, SWPLD3_INTR); +/* offset 0x41 */ +static SENSOR_DEVICE_ATTR(psu1_led, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, PSU1_LED); +static SENSOR_DEVICE_ATTR(psu2_led, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, PSU2_LED); +/* offset 0x42 */ +static SENSOR_DEVICE_ATTR(sys_led, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, SYS_LED); +static SENSOR_DEVICE_ATTR(fan_led, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, FAN_LED); +/* offset 0x46 */ +static SENSOR_DEVICE_ATTR(fan1_led, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, FAN1_LED); +static SENSOR_DEVICE_ATTR(fan2_led, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, FAN2_LED); +static SENSOR_DEVICE_ATTR(fan3_led, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, FAN3_LED); +static SENSOR_DEVICE_ATTR(fan4_led, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, FAN4_LED); +/* offset 0x47 */ +static SENSOR_DEVICE_ATTR(fan5_led, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, FAN5_LED); +static SENSOR_DEVICE_ATTR(fan6_led, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, FAN6_LED); +/* offset 0x51*/ +static SENSOR_DEVICE_ATTR(synce_eeprom_wb, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, SYNCE_EEPROM_WB); +static SENSOR_DEVICE_ATTR(console_sel, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, CONSOLE_SEL); +static SENSOR_DEVICE_ATTR(sys_eeprom_wb, S_IRUGO | S_IWUSR, swpld1_data_show, swpld1_data_store, SYS_EEPROM_WB); + +static struct attribute *swpld1_device_attrs[] = { + &sensor_dev_attr_board_id.dev_attr.attr, + &sensor_dev_attr_board_ver.dev_attr.attr, + &sensor_dev_attr_swpld1_ver_type.dev_attr.attr, + &sensor_dev_attr_swpld1_ver.dev_attr.attr, + &sensor_dev_attr_usb_hub_rst.dev_attr.attr, + &sensor_dev_attr_synce_rst.dev_attr.attr, + &sensor_dev_attr_bmc_rst.dev_attr.attr, + &sensor_dev_attr_lpc_rst.dev_attr.attr, + &sensor_dev_attr_oob_pcie_rst.dev_attr.attr, + &sensor_dev_attr_mac_pcie_rst.dev_attr.attr, + &sensor_dev_attr_mac_rst.dev_attr.attr, + &sensor_dev_attr_vr_3v3_rst.dev_attr.attr, + &sensor_dev_attr_vr_0v8_rst.dev_attr.attr, + &sensor_dev_attr_fan_mux_rst.dev_attr.attr, + &sensor_dev_attr_qsfp5_mux_rst.dev_attr.attr, + &sensor_dev_attr_qsfp4_mux_rst.dev_attr.attr, + &sensor_dev_attr_qsfp3_mux_rst.dev_attr.attr, + &sensor_dev_attr_qsfp2_mux_rst.dev_attr.attr, + &sensor_dev_attr_qsfp1_mux_rst.dev_attr.attr, + &sensor_dev_attr_psu1_present.dev_attr.attr, + &sensor_dev_attr_psu1_state.dev_attr.attr, + &sensor_dev_attr_psu1_alert.dev_attr.attr, + &sensor_dev_attr_psu2_present.dev_attr.attr, + &sensor_dev_attr_psu2_state.dev_attr.attr, + &sensor_dev_attr_psu2_alert.dev_attr.attr, + &sensor_dev_attr_psu1_en.dev_attr.attr, + &sensor_dev_attr_psu1_eeprom_wp.dev_attr.attr, + &sensor_dev_attr_psu2_en.dev_attr.attr, + &sensor_dev_attr_psu2_eeprom_wp.dev_attr.attr, + &sensor_dev_attr_vcc_5v_en.dev_attr.attr, + &sensor_dev_attr_vcc_3v3_en.dev_attr.attr, + &sensor_dev_attr_vcc_vcore_en.dev_attr.attr, + &sensor_dev_attr_vcc_mac_1v8_en.dev_attr.attr, + &sensor_dev_attr_vcc_mac_1v2_en.dev_attr.attr, + &sensor_dev_attr_vcc_mac_0v8_en.dev_attr.attr, + &sensor_dev_attr_vcc_pll_0v8_en.dev_attr.attr, + &sensor_dev_attr_vcc_sys_en.dev_attr.attr, + &sensor_dev_attr_oob_pwr_state.dev_attr.attr, + &sensor_dev_attr_oob_op_en.dev_attr.attr, + &sensor_dev_attr_usb1_op_en.dev_attr.attr, + &sensor_dev_attr_psu_intr.dev_attr.attr, + &sensor_dev_attr_fan_alert.dev_attr.attr, + &sensor_dev_attr_swpld2_intr.dev_attr.attr, + &sensor_dev_attr_swpld3_intr.dev_attr.attr, + &sensor_dev_attr_psu1_led.dev_attr.attr, + &sensor_dev_attr_psu2_led.dev_attr.attr, + &sensor_dev_attr_sys_led.dev_attr.attr, + &sensor_dev_attr_fan_led.dev_attr.attr, + &sensor_dev_attr_fan1_led.dev_attr.attr, + &sensor_dev_attr_fan2_led.dev_attr.attr, + &sensor_dev_attr_fan3_led.dev_attr.attr, + &sensor_dev_attr_fan4_led.dev_attr.attr, + &sensor_dev_attr_fan5_led.dev_attr.attr, + &sensor_dev_attr_fan6_led.dev_attr.attr, + &sensor_dev_attr_synce_eeprom_wb.dev_attr.attr, + &sensor_dev_attr_console_sel.dev_attr.attr, + &sensor_dev_attr_sys_eeprom_wb.dev_attr.attr, +}; + + +static ssize_t swpld2_data_show(struct device *dev, struct device_attribute *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct device *i2cdev = kobj_to_dev(kobj_swpld2->parent); + struct platform_data *pdata = i2cdev->platform_data; + unsigned int select = 0; + unsigned char offset = 0; + int mask = 0xFF; + int shift = 0; + int value = 0; + bool hex_fmt = 0; + char desc[256] = {0}; + + select = attr->index; + switch(select) { + case SWPLD2_VER_TYPE: + offset = 0x1; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nSWPLD2 Version Type.\n"); + break; + case SWPLD2_VER: + offset = 0x1; + mask = 0x7f; + scnprintf(desc, PAGE_SIZE, "\nSWPLD2 Version.\n"); + break; + case QSFP_P01_RST: + offset = 0x11; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P02_RST: + offset = 0x11; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P03_RST: + offset = 0x11; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P04_RST: + offset = 0x11; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P05_RST: + offset = 0x11; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P06_RST: + offset = 0x11; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P07_RST: + offset = 0x11; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P08_RST: + offset = 0x11; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P09_RST: + offset = 0x12; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P10_RST: + offset = 0x12; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P11_RST: + offset = 0x12; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P12_RST: + offset = 0x12; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P13_RST: + offset = 0x12; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P14_RST: + offset = 0x12; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P15_RST: + offset = 0x12; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P16_RST: + offset = 0x12; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P01_LPMODE: + offset = 0x21; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P02_LPMODE: + offset = 0x21; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P03_LPMODE: + offset = 0x21; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P04_LPMODE: + offset = 0x21; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P05_LPMODE: + offset = 0x21; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P06_LPMODE: + offset = 0x21; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P07_LPMODE: + offset = 0x21; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P08_LPMODE: + offset = 0x21; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P09_LPMODE: + offset = 0x22; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P10_LPMODE: + offset = 0x22; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P11_LPMODE: + offset = 0x22; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P12_LPMODE: + offset = 0x22; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P13_LPMODE: + offset = 0x22; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P14_LPMODE: + offset = 0x22; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P15_LPMODE: + offset = 0x22; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P16_LPMODE: + offset = 0x22; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P01_MODPRS: + offset = 0x51; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P02_MODPRS: + offset = 0x51; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P03_MODPRS: + offset = 0x51; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P04_MODPRS: + offset = 0x51; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P05_MODPRS: + offset = 0x51; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P06_MODPRS: + offset = 0x51; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P07_MODPRS: + offset = 0x51; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P08_MODPRS: + offset = 0x51; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P09_MODPRS: + offset = 0x52; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P10_MODPRS: + offset = 0x52; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P11_MODPRS: + offset = 0x52; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P12_MODPRS: + offset = 0x52; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P13_MODPRS: + offset = 0x52; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P14_MODPRS: + offset = 0x52; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P15_MODPRS: + offset = 0x52; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P16_MODPRS: + offset = 0x52; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P01_INTR: + offset = 0x61; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P02_INTR: + offset = 0x61; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P03_INTR: + offset = 0x61; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P04_INTR: + offset = 0x61; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P05_INTR: + offset = 0x61; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P06_INTR: + offset = 0x61; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P07_INTR: + offset = 0x61; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P08_INTR: + offset = 0x61; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P09_INTR: + offset = 0x62; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P10_INTR: + offset = 0x62; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P11_INTR: + offset = 0x62; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P12_INTR: + offset = 0x62; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P13_INTR: + offset = 0x62; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P14_INTR: + offset = 0x62; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P15_INTR: + offset = 0x62; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P16_INTR: + offset = 0x62; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + } + + value = i2c_smbus_read_byte_data(pdata[swpld2].client, offset); + value = (value & mask) >> shift; + if(hex_fmt) { + return scnprintf(buf, PAGE_SIZE, "0x%02x%s", value, desc); + } else { + return scnprintf(buf, PAGE_SIZE, "%d%s", value, desc); + } +} + +static ssize_t swpld2_data_store(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 device *i2cdev = kobj_to_dev(kobj_swpld2->parent); + struct platform_data *pdata = i2cdev->platform_data; + unsigned int select = 0; + unsigned char offset = 0; + int mask = 0xFF; + int shift = 0; + int value = 0; + int err = 0; + unsigned long data; + + err = kstrtoul(buf, 0, &data); + if (err){ + return err; + } + + if (data > 0xff){ + printk(KERN_ALERT "address out of range (0x00-0xFF)\n"); + return count; + } + + switch (attr->index) { + case QSFP_P01_RST: + offset = 0x11; + shift = 7; + mask = (1 << shift); + break; + case QSFP_P02_RST: + offset = 0x11; + shift = 6; + mask = (1 << shift); + break; + case QSFP_P03_RST: + offset = 0x11; + shift = 5; + mask = (1 << shift); + break; + case QSFP_P04_RST: + offset = 0x11; + shift = 4; + mask = (1 << shift); + break; + case QSFP_P05_RST: + offset = 0x11; + shift = 3; + mask = (1 << shift); + break; + case QSFP_P06_RST: + offset = 0x11; + shift = 2; + mask = (1 << shift); + break; + case QSFP_P07_RST: + offset = 0x11; + shift = 1; + mask = (1 << shift); + break; + case QSFP_P08_RST: + offset = 0x11; + shift = 0; + mask = (1 << shift); + break; + case QSFP_P09_RST: + offset = 0x12; + shift = 7; + mask = (1 << shift); + break; + case QSFP_P10_RST: + offset = 0x12; + shift = 6; + mask = (1 << shift); + break; + case QSFP_P11_RST: + offset = 0x12; + shift = 5; + mask = (1 << shift); + break; + case QSFP_P12_RST: + offset = 0x12; + shift = 4; + mask = (1 << shift); + break; + case QSFP_P13_RST: + offset = 0x12; + shift = 3; + mask = (1 << shift); + break; + case QSFP_P14_RST: + offset = 0x12; + shift = 2; + mask = (1 << shift); + break; + case QSFP_P15_RST: + offset = 0x12; + shift = 1; + mask = (1 << shift); + break; + case QSFP_P16_RST: + offset = 0x12; + shift = 0; + mask = (1 << shift); + break; + case QSFP_P01_LPMODE: + offset = 0x21; + shift = 7; + mask = (1 << shift); + break; + case QSFP_P02_LPMODE: + offset = 0x21; + shift = 6; + mask = (1 << shift); + break; + case QSFP_P03_LPMODE: + offset = 0x21; + shift = 5; + mask = (1 << shift); + break; + case QSFP_P04_LPMODE: + offset = 0x21; + shift = 4; + mask = (1 << shift); + break; + case QSFP_P05_LPMODE: + offset = 0x21; + shift = 3; + mask = (1 << shift); + break; + case QSFP_P06_LPMODE: + offset = 0x21; + shift = 2; + mask = (1 << shift); + break; + case QSFP_P07_LPMODE: + offset = 0x21; + shift = 1; + mask = (1 << shift); + break; + case QSFP_P08_LPMODE: + offset = 0x21; + shift = 0; + mask = (1 << shift); + break; + case QSFP_P09_LPMODE: + offset = 0x22; + shift = 7; + mask = (1 << shift); + break; + case QSFP_P10_LPMODE: + offset = 0x22; + shift = 6; + mask = (1 << shift); + break; + case QSFP_P11_LPMODE: + offset = 0x22; + shift = 5; + mask = (1 << shift); + break; + case QSFP_P12_LPMODE: + offset = 0x22; + shift = 4; + mask = (1 << shift); + break; + case QSFP_P13_LPMODE: + offset = 0x22; + shift = 3; + mask = (1 << shift); + break; + case QSFP_P14_LPMODE: + offset = 0x22; + shift = 2; + mask = (1 << shift); + break; + case QSFP_P15_LPMODE: + offset = 0x22; + shift = 1; + mask = (1 << shift); + break; + case QSFP_P16_LPMODE: + offset = 0x22; + shift = 0; + mask = (1 << shift); + break; + } + + value = i2c_smbus_read_byte_data(pdata[swpld2].client, offset); + data = (value & ~mask) | (data << shift); + i2c_smbus_write_byte_data(pdata[swpld2].client, offset, data); + + return count; +} + + +/* offset 0x01 */ +static SENSOR_DEVICE_ATTR(swpld2_ver_type, S_IRUGO, swpld2_data_show, NULL, SWPLD2_VER_TYPE); +static SENSOR_DEVICE_ATTR(swpld2_ver, S_IRUGO, swpld2_data_show, NULL, SWPLD2_VER); +/* offset 0x11 */ +static SENSOR_DEVICE_ATTR(qsfp_p01_rst, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P01_RST); +static SENSOR_DEVICE_ATTR(qsfp_p02_rst, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P02_RST); +static SENSOR_DEVICE_ATTR(qsfp_p03_rst, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P03_RST); +static SENSOR_DEVICE_ATTR(qsfp_p04_rst, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P04_RST); +static SENSOR_DEVICE_ATTR(qsfp_p05_rst, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P05_RST); +static SENSOR_DEVICE_ATTR(qsfp_p06_rst, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P06_RST); +static SENSOR_DEVICE_ATTR(qsfp_p07_rst, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P07_RST); +static SENSOR_DEVICE_ATTR(qsfp_p08_rst, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P08_RST); +/* offset 0x12 */ +static SENSOR_DEVICE_ATTR(qsfp_p09_rst, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P09_RST); +static SENSOR_DEVICE_ATTR(qsfp_p10_rst, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P10_RST); +static SENSOR_DEVICE_ATTR(qsfp_p11_rst, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P11_RST); +static SENSOR_DEVICE_ATTR(qsfp_p12_rst, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P12_RST); +static SENSOR_DEVICE_ATTR(qsfp_p13_rst, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P13_RST); +static SENSOR_DEVICE_ATTR(qsfp_p14_rst, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P14_RST); +static SENSOR_DEVICE_ATTR(qsfp_p15_rst, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P15_RST); +static SENSOR_DEVICE_ATTR(qsfp_p16_rst, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P16_RST); +/* offset 0x21 */ +static SENSOR_DEVICE_ATTR(qsfp_p01_lpmode, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P01_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p02_lpmode, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P02_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p03_lpmode, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P03_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p04_lpmode, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P04_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p05_lpmode, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P05_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p06_lpmode, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P06_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p07_lpmode, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P07_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p08_lpmode, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P08_LPMODE); +/* offset 0x22 */ +static SENSOR_DEVICE_ATTR(qsfp_p09_lpmode, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P09_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p10_lpmode, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P10_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p11_lpmode, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P11_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p12_lpmode, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P12_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p13_lpmode, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P13_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p14_lpmode, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P14_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p15_lpmode, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P15_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p16_lpmode, S_IRUGO | S_IWUSR, swpld2_data_show, swpld2_data_store, QSFP_P16_LPMODE); +/* offset 0x51 */ +static SENSOR_DEVICE_ATTR(qsfp_p01_modprs, S_IRUGO, swpld2_data_show, NULL, QSFP_P01_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p02_modprs, S_IRUGO, swpld2_data_show, NULL, QSFP_P02_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p03_modprs, S_IRUGO, swpld2_data_show, NULL, QSFP_P03_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p04_modprs, S_IRUGO, swpld2_data_show, NULL, QSFP_P04_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p05_modprs, S_IRUGO, swpld2_data_show, NULL, QSFP_P05_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p06_modprs, S_IRUGO, swpld2_data_show, NULL, QSFP_P06_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p07_modprs, S_IRUGO, swpld2_data_show, NULL, QSFP_P07_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p08_modprs, S_IRUGO, swpld2_data_show, NULL, QSFP_P08_MODPRS); +/* offset 0x52 */ +static SENSOR_DEVICE_ATTR(qsfp_p09_modprs, S_IRUGO, swpld2_data_show, NULL, QSFP_P09_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p10_modprs, S_IRUGO, swpld2_data_show, NULL, QSFP_P10_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p11_modprs, S_IRUGO, swpld2_data_show, NULL, QSFP_P11_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p12_modprs, S_IRUGO, swpld2_data_show, NULL, QSFP_P12_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p13_modprs, S_IRUGO, swpld2_data_show, NULL, QSFP_P13_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p14_modprs, S_IRUGO, swpld2_data_show, NULL, QSFP_P14_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p15_modprs, S_IRUGO, swpld2_data_show, NULL, QSFP_P15_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p16_modprs, S_IRUGO, swpld2_data_show, NULL, QSFP_P16_MODPRS); +/* offset 0x61 */ +static SENSOR_DEVICE_ATTR(qsfp_p01_intr, S_IRUGO, swpld2_data_show, NULL, QSFP_P01_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p02_intr, S_IRUGO, swpld2_data_show, NULL, QSFP_P02_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p03_intr, S_IRUGO, swpld2_data_show, NULL, QSFP_P03_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p04_intr, S_IRUGO, swpld2_data_show, NULL, QSFP_P04_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p05_intr, S_IRUGO, swpld2_data_show, NULL, QSFP_P05_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p06_intr, S_IRUGO, swpld2_data_show, NULL, QSFP_P06_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p07_intr, S_IRUGO, swpld2_data_show, NULL, QSFP_P07_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p08_intr, S_IRUGO, swpld2_data_show, NULL, QSFP_P08_INTR); +/* offset 0x62 */ +static SENSOR_DEVICE_ATTR(qsfp_p09_intr, S_IRUGO, swpld2_data_show, NULL, QSFP_P09_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p10_intr, S_IRUGO, swpld2_data_show, NULL, QSFP_P10_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p11_intr, S_IRUGO, swpld2_data_show, NULL, QSFP_P11_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p12_intr, S_IRUGO, swpld2_data_show, NULL, QSFP_P12_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p13_intr, S_IRUGO, swpld2_data_show, NULL, QSFP_P13_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p14_intr, S_IRUGO, swpld2_data_show, NULL, QSFP_P14_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p15_intr, S_IRUGO, swpld2_data_show, NULL, QSFP_P15_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p16_intr, S_IRUGO, swpld2_data_show, NULL, QSFP_P16_INTR); + + +static struct attribute *swpld2_device_attrs[] = { + &sensor_dev_attr_swpld2_ver_type.dev_attr.attr, + &sensor_dev_attr_swpld2_ver.dev_attr.attr, + &sensor_dev_attr_qsfp_p01_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p02_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p03_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p04_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p05_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p06_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p07_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p08_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p09_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p10_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p11_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p12_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p13_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p14_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p15_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p16_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p01_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p02_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p03_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p04_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p05_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p06_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p07_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p08_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p09_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p10_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p11_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p12_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p13_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p14_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p15_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p16_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p01_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p02_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p03_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p04_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p05_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p06_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p07_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p08_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p09_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p10_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p11_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p12_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p13_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p14_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p15_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p16_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p01_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p02_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p03_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p04_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p05_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p06_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p07_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p08_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p09_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p10_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p11_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p12_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p13_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p14_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p15_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p16_intr.dev_attr.attr, +}; + + +static ssize_t swpld3_data_show(struct device *dev, struct device_attribute *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct device *i2cdev = kobj_to_dev(kobj_swpld3->parent); + struct platform_data *pdata = i2cdev->platform_data; + unsigned int select = 0; + unsigned char offset = 0; + int mask = 0xFF; + int shift = 0; + int value = 0; + bool hex_fmt = 0; + char desc[256] = {0}; + + select = attr->index; + switch(select) { + case SWPLD3_VER_TYPE: + offset = 0x1; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\nSWPLD3 Version Type.\n"); + break; + case SWPLD3_VER: + offset = 0x1; + mask = 0x7f; + scnprintf(desc, PAGE_SIZE, "\nSWPLD3 Version.\n"); + break; + case QSFP_P17_RST: + offset = 0x11; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P18_RST: + offset = 0x11; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P19_RST: + offset = 0x11; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P20_RST: + offset = 0x11; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P21_RST: + offset = 0x11; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P22_RST: + offset = 0x11; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P23_RST: + offset = 0x11; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P24_RST: + offset = 0x11; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P25_RST: + offset = 0x12; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P26_RST: + offset = 0x12; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P27_RST: + offset = 0x12; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P28_RST: + offset = 0x12; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P29_RST: + offset = 0x12; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P30_RST: + offset = 0x12; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P31_RST: + offset = 0x12; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P32_RST: + offset = 0x12; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Normal Operation.\n“0†= Reset.\n"); + break; + case QSFP_P17_LPMODE: + offset = 0x21; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P18_LPMODE: + offset = 0x21; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P19_LPMODE: + offset = 0x21; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P20_LPMODE: + offset = 0x21; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P21_LPMODE: + offset = 0x21; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P22_LPMODE: + offset = 0x21; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P23_LPMODE: + offset = 0x21; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P24_LPMODE: + offset = 0x21; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P25_LPMODE: + offset = 0x22; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P26_LPMODE: + offset = 0x22; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P27_LPMODE: + offset = 0x22; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P28_LPMODE: + offset = 0x22; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P29_LPMODE: + offset = 0x22; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P30_LPMODE: + offset = 0x22; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P31_LPMODE: + offset = 0x22; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P32_LPMODE: + offset = 0x22; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= LP Mode.\n“0†= Not LP Mode.\n"); + break; + case QSFP_P17_MODPRS: + offset = 0x51; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P18_MODPRS: + offset = 0x51; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P19_MODPRS: + offset = 0x51; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P20_MODPRS: + offset = 0x51; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P21_MODPRS: + offset = 0x51; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P22_MODPRS: + offset = 0x51; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P23_MODPRS: + offset = 0x51; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P24_MODPRS: + offset = 0x51; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P25_MODPRS: + offset = 0x52; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P26_MODPRS: + offset = 0x52; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P27_MODPRS: + offset = 0x52; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P28_MODPRS: + offset = 0x52; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P29_MODPRS: + offset = 0x52; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P30_MODPRS: + offset = 0x52; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P31_MODPRS: + offset = 0x52; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P32_MODPRS: + offset = 0x52; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Present.\n“0†= Present.\n"); + break; + case QSFP_P17_INTR: + offset = 0x61; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P18_INTR: + offset = 0x61; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P19_INTR: + offset = 0x61; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P20_INTR: + offset = 0x61; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P21_INTR: + offset = 0x61; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P22_INTR: + offset = 0x61; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P23_INTR: + offset = 0x61; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P24_INTR: + offset = 0x61; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P25_INTR: + offset = 0x62; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P26_INTR: + offset = 0x62; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P27_INTR: + offset = 0x62; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P28_INTR: + offset = 0x62; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P29_INTR: + offset = 0x62; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P30_INTR: + offset = 0x62; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P31_INTR: + offset = 0x62; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case QSFP_P32_INTR: + offset = 0x62; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Not Assert Intrrupt.\n“0†= Assert Intrrupt.\n"); + break; + case SFP_P0_MODPRS: + offset = 0x71; + shift = 6; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Absent.\n“0†= Present.\n"); + break; + case SFP_P0_RXLOS: + offset = 0x71; + shift = 5; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Receive Loss.\n“0†= Normal Operation.\n"); + break; + case SFP_P0_TXFAULT: + offset = 0x71; + shift = 4; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Transmit Fault.\n“0†= Normal Operation.\n"); + break; + case SFP_P1_MODPRS: + offset = 0x71; + shift = 2; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Absent.\n“0†= Present.\n"); + break; + case SFP_P1_RXLOS: + offset = 0x71; + shift = 1; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Receive Loss.\n“0†= Normal Operation.\n"); + break; + case SFP_P1_TXFAULT: + offset = 0x71; + shift = 0; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Transmit Fault.\n“0†= Normal Operation.\n"); + break; + case SFP_P0_TXDIS: + offset = 0x72; + shift = 7; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Disable.\n“0†= Normal Operation.\n"); + break; + case SFP_P1_TXDIS: + offset = 0x72; + shift = 3; + mask = (1 << shift); + scnprintf(desc, PAGE_SIZE, "\n“1†= Disable.\n“0†= Normal Operation.\n"); + break; + } + + value = i2c_smbus_read_byte_data(pdata[swpld3].client, offset); + value = (value & mask) >> shift; + if(hex_fmt) { + return scnprintf(buf, PAGE_SIZE, "0x%02x%s", value, desc); + } else { + return scnprintf(buf, PAGE_SIZE, "%d%s", value, desc); + } +} + + +static ssize_t swpld3_data_store(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 device *i2cdev = kobj_to_dev(kobj_swpld3->parent); + struct platform_data *pdata = i2cdev->platform_data; + unsigned int select = 0; + unsigned char offset = 0; + int mask = 0xFF; + int shift = 0; + int value = 0; + int err = 0; + unsigned long data; + + err = kstrtoul(buf, 0, &data); + if (err){ + return err; + } + + if (data > 0xff){ + printk(KERN_ALERT "address out of range (0x00-0xFF)\n"); + return count; + } + + switch (attr->index) { + case QSFP_P17_RST: + offset = 0x11; + shift = 7; + mask = (1 << shift); + break; + case QSFP_P18_RST: + offset = 0x11; + shift = 6; + mask = (1 << shift); + break; + case QSFP_P19_RST: + offset = 0x11; + shift = 5; + mask = (1 << shift); + break; + case QSFP_P20_RST: + offset = 0x11; + shift = 4; + mask = (1 << shift); + break; + case QSFP_P21_RST: + offset = 0x11; + shift = 3; + mask = (1 << shift); + break; + case QSFP_P22_RST: + offset = 0x11; + shift = 2; + mask = (1 << shift); + break; + case QSFP_P23_RST: + offset = 0x11; + shift = 1; + mask = (1 << shift); + break; + case QSFP_P24_RST: + offset = 0x11; + shift = 0; + mask = (1 << shift); + break; + case QSFP_P25_RST: + offset = 0x12; + shift = 7; + mask = (1 << shift); + break; + case QSFP_P26_RST: + offset = 0x12; + shift = 6; + mask = (1 << shift); + break; + case QSFP_P27_RST: + offset = 0x12; + shift = 5; + mask = (1 << shift); + break; + case QSFP_P28_RST: + offset = 0x12; + shift = 4; + mask = (1 << shift); + break; + case QSFP_P29_RST: + offset = 0x12; + shift = 3; + mask = (1 << shift); + break; + case QSFP_P30_RST: + offset = 0x12; + shift = 2; + mask = (1 << shift); + break; + case QSFP_P31_RST: + offset = 0x12; + shift = 1; + mask = (1 << shift); + break; + case QSFP_P32_RST: + offset = 0x12; + shift = 0; + mask = (1 << shift); + break; + case QSFP_P17_LPMODE: + offset = 0x21; + shift = 7; + mask = (1 << shift); + break; + case QSFP_P18_LPMODE: + offset = 0x21; + shift = 6; + mask = (1 << shift); + break; + case QSFP_P19_LPMODE: + offset = 0x21; + shift = 5; + mask = (1 << shift); + break; + case QSFP_P20_LPMODE: + offset = 0x21; + shift = 4; + mask = (1 << shift); + break; + case QSFP_P21_LPMODE: + offset = 0x21; + shift = 3; + mask = (1 << shift); + break; + case QSFP_P22_LPMODE: + offset = 0x21; + shift = 2; + mask = (1 << shift); + break; + case QSFP_P23_LPMODE: + offset = 0x21; + shift = 1; + mask = (1 << shift); + break; + case QSFP_P24_LPMODE: + offset = 0x21; + shift = 0; + mask = (1 << shift); + break; + case QSFP_P25_LPMODE: + offset = 0x22; + shift = 7; + mask = (1 << shift); + break; + case QSFP_P26_LPMODE: + offset = 0x22; + shift = 6; + mask = (1 << shift); + break; + case QSFP_P27_LPMODE: + offset = 0x22; + shift = 5; + mask = (1 << shift); + break; + case QSFP_P28_LPMODE: + offset = 0x22; + shift = 4; + mask = (1 << shift); + break; + case QSFP_P29_LPMODE: + offset = 0x22; + shift = 3; + mask = (1 << shift); + break; + case QSFP_P30_LPMODE: + offset = 0x22; + shift = 2; + mask = (1 << shift); + break; + case QSFP_P31_LPMODE: + offset = 0x22; + shift = 1; + mask = (1 << shift); + break; + case QSFP_P32_LPMODE: + offset = 0x22; + shift = 0; + mask = (1 << shift); + break; + case SFP_P0_TXDIS: + offset = 0x72; + shift = 7; + break; + case SFP_P1_TXDIS: + offset = 0x72; + shift = 3; + mask = (1 << shift); + break; + + } + + value = i2c_smbus_read_byte_data(pdata[swpld3].client, offset); + data = (value & ~mask) | (data << shift); + i2c_smbus_write_byte_data(pdata[swpld3].client, offset, data); + + return count; +} + +/* offset 0x01 */ +static SENSOR_DEVICE_ATTR(swpld3_ver_type, S_IRUGO, swpld3_data_show, NULL, SWPLD3_VER_TYPE); +static SENSOR_DEVICE_ATTR(swpld3_ver, S_IRUGO, swpld3_data_show, NULL, SWPLD3_VER); +/* offset 0x11 */ +static SENSOR_DEVICE_ATTR(qsfp_p17_rst, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P17_RST); +static SENSOR_DEVICE_ATTR(qsfp_p18_rst, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P18_RST); +static SENSOR_DEVICE_ATTR(qsfp_p19_rst, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P19_RST); +static SENSOR_DEVICE_ATTR(qsfp_p20_rst, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P20_RST); +static SENSOR_DEVICE_ATTR(qsfp_p21_rst, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P21_RST); +static SENSOR_DEVICE_ATTR(qsfp_p22_rst, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P22_RST); +static SENSOR_DEVICE_ATTR(qsfp_p23_rst, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P23_RST); +static SENSOR_DEVICE_ATTR(qsfp_p24_rst, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P24_RST); +/* offset 0x12 */ +static SENSOR_DEVICE_ATTR(qsfp_p25_rst, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P25_RST); +static SENSOR_DEVICE_ATTR(qsfp_p26_rst, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P26_RST); +static SENSOR_DEVICE_ATTR(qsfp_p27_rst, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P27_RST); +static SENSOR_DEVICE_ATTR(qsfp_p28_rst, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P28_RST); +static SENSOR_DEVICE_ATTR(qsfp_p29_rst, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P29_RST); +static SENSOR_DEVICE_ATTR(qsfp_p30_rst, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P30_RST); +static SENSOR_DEVICE_ATTR(qsfp_p31_rst, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P31_RST); +static SENSOR_DEVICE_ATTR(qsfp_p32_rst, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P32_RST); +/* offset 0x21 */ +static SENSOR_DEVICE_ATTR(qsfp_p17_lpmode, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P17_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p18_lpmode, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P18_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p19_lpmode, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P19_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p20_lpmode, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P20_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p21_lpmode, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P21_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p22_lpmode, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P22_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p23_lpmode, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P23_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p24_lpmode, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P24_LPMODE); +/* offset 0x22 */ +static SENSOR_DEVICE_ATTR(qsfp_p25_lpmode, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P25_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p26_lpmode, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P26_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p27_lpmode, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P27_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p28_lpmode, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P28_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p29_lpmode, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P29_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p30_lpmode, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P30_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p31_lpmode, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P31_LPMODE); +static SENSOR_DEVICE_ATTR(qsfp_p32_lpmode, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, QSFP_P32_LPMODE); +/* offset 0x51 */ +static SENSOR_DEVICE_ATTR(qsfp_p17_modprs, S_IRUGO, swpld3_data_show, NULL, QSFP_P17_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p18_modprs, S_IRUGO, swpld3_data_show, NULL, QSFP_P18_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p19_modprs, S_IRUGO, swpld3_data_show, NULL, QSFP_P19_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p20_modprs, S_IRUGO, swpld3_data_show, NULL, QSFP_P20_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p21_modprs, S_IRUGO, swpld3_data_show, NULL, QSFP_P21_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p22_modprs, S_IRUGO, swpld3_data_show, NULL, QSFP_P22_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p23_modprs, S_IRUGO, swpld3_data_show, NULL, QSFP_P23_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p24_modprs, S_IRUGO, swpld3_data_show, NULL, QSFP_P24_MODPRS); +/* offset 0x52 */ +static SENSOR_DEVICE_ATTR(qsfp_p25_modprs, S_IRUGO, swpld3_data_show, NULL, QSFP_P25_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p26_modprs, S_IRUGO, swpld3_data_show, NULL, QSFP_P26_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p27_modprs, S_IRUGO, swpld3_data_show, NULL, QSFP_P27_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p28_modprs, S_IRUGO, swpld3_data_show, NULL, QSFP_P28_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p29_modprs, S_IRUGO, swpld3_data_show, NULL, QSFP_P29_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p30_modprs, S_IRUGO, swpld3_data_show, NULL, QSFP_P30_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p31_modprs, S_IRUGO, swpld3_data_show, NULL, QSFP_P31_MODPRS); +static SENSOR_DEVICE_ATTR(qsfp_p32_modprs, S_IRUGO, swpld3_data_show, NULL, QSFP_P32_MODPRS); +/* offset 0x61 */ +static SENSOR_DEVICE_ATTR(qsfp_p17_intr, S_IRUGO, swpld3_data_show, NULL, QSFP_P17_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p18_intr, S_IRUGO, swpld3_data_show, NULL, QSFP_P18_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p19_intr, S_IRUGO, swpld3_data_show, NULL, QSFP_P19_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p20_intr, S_IRUGO, swpld3_data_show, NULL, QSFP_P20_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p21_intr, S_IRUGO, swpld3_data_show, NULL, QSFP_P21_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p22_intr, S_IRUGO, swpld3_data_show, NULL, QSFP_P22_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p23_intr, S_IRUGO, swpld3_data_show, NULL, QSFP_P23_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p24_intr, S_IRUGO, swpld3_data_show, NULL, QSFP_P24_INTR); +/* offset 0x62 */ +static SENSOR_DEVICE_ATTR(qsfp_p25_intr, S_IRUGO, swpld3_data_show, NULL, QSFP_P25_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p26_intr, S_IRUGO, swpld3_data_show, NULL, QSFP_P26_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p27_intr, S_IRUGO, swpld3_data_show, NULL, QSFP_P27_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p28_intr, S_IRUGO, swpld3_data_show, NULL, QSFP_P28_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p29_intr, S_IRUGO, swpld3_data_show, NULL, QSFP_P29_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p30_intr, S_IRUGO, swpld3_data_show, NULL, QSFP_P30_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p31_intr, S_IRUGO, swpld3_data_show, NULL, QSFP_P31_INTR); +static SENSOR_DEVICE_ATTR(qsfp_p32_intr, S_IRUGO, swpld3_data_show, NULL, QSFP_P32_INTR); +/* offset 0x71 */ +static SENSOR_DEVICE_ATTR(sfp_p0_modprs, S_IRUGO, swpld3_data_show, NULL, SFP_P0_MODPRS); +static SENSOR_DEVICE_ATTR(sfp_p0_rxlos, S_IRUGO, swpld3_data_show, NULL, SFP_P0_RXLOS); +static SENSOR_DEVICE_ATTR(sfp_p0_txfault, S_IRUGO, swpld3_data_show, NULL, SFP_P0_TXFAULT); +static SENSOR_DEVICE_ATTR(sfp_p1_modprs, S_IRUGO, swpld3_data_show, NULL, SFP_P1_MODPRS); +static SENSOR_DEVICE_ATTR(sfp_p1_rxlos, S_IRUGO, swpld3_data_show, NULL, SFP_P1_RXLOS); +static SENSOR_DEVICE_ATTR(sfp_p1_txfault, S_IRUGO, swpld3_data_show, NULL, SFP_P1_TXFAULT); +/* offset 0x72 */ +static SENSOR_DEVICE_ATTR(sfp_p0_txdis, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, SFP_P0_TXDIS); +static SENSOR_DEVICE_ATTR(sfp_p1_txdis, S_IRUGO | S_IWUSR, swpld3_data_show, swpld3_data_store, SFP_P1_TXDIS); + +static struct attribute *swpld3_device_attrs[] = { + &sensor_dev_attr_swpld3_ver_type.dev_attr.attr, + &sensor_dev_attr_swpld3_ver.dev_attr.attr, + &sensor_dev_attr_qsfp_p17_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p18_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p19_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p20_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p21_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p22_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p23_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p24_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p25_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p26_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p27_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p28_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p29_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p30_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p31_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p32_rst.dev_attr.attr, + &sensor_dev_attr_qsfp_p17_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p18_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p19_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p20_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p21_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p22_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p23_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p24_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p25_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p26_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p27_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p28_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p29_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p30_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p31_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p32_lpmode.dev_attr.attr, + &sensor_dev_attr_qsfp_p17_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p18_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p19_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p20_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p21_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p22_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p23_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p24_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p25_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p26_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p27_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p28_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p29_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p30_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p31_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p32_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_p17_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p18_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p19_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p20_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p21_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p22_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p23_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p24_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p25_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p26_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p27_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p28_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p29_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p30_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p31_intr.dev_attr.attr, + &sensor_dev_attr_qsfp_p32_intr.dev_attr.attr, + &sensor_dev_attr_sfp_p0_modprs.dev_attr.attr, + &sensor_dev_attr_sfp_p0_rxlos.dev_attr.attr, + &sensor_dev_attr_sfp_p0_txfault.dev_attr.attr, + &sensor_dev_attr_sfp_p1_modprs.dev_attr.attr, + &sensor_dev_attr_sfp_p1_rxlos.dev_attr.attr, + &sensor_dev_attr_sfp_p1_txfault.dev_attr.attr, + &sensor_dev_attr_sfp_p0_txdis.dev_attr.attr, + &sensor_dev_attr_sfp_p1_txdis.dev_attr.attr, +}; + +static struct attribute_group swpld1_device_attr_group = { + .attrs = swpld1_device_attrs, +}; + +static struct attribute_group swpld2_device_attr_group = { + .attrs = swpld2_device_attrs, +}; + +static struct attribute_group swpld3_device_attr_group = { + .attrs = swpld3_device_attrs, +}; + + +static struct cpld_platform_data agc032_swpld_platform_data[] = { + [swpld1] = { + .reg_addr = SWPLD1_ADDR, + }, + [swpld2] = { + .reg_addr = SWPLD2_ADDR, + }, + [swpld3] = { + .reg_addr = SWPLD3_ADDR, + }, +}; + +static void device_release(struct device *dev) +{ + return; +} + + +static struct platform_device swpld_device = { + .name = "delta-agc032-swpld", + .id = 0, + .dev = { + .platform_data = agc032_swpld_platform_data, + .release = device_release + }, +}; + + +static int __init swpld_probe(struct platform_device *pdev) +{ + int ret; + struct cpld_platform_data *pdata; + struct i2c_adapter *parent; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "CPLD platform data not found\n"); + return -ENODEV; + } + + parent = i2c_get_adapter(BUS8); + if (!parent) { + printk(KERN_ERR "Parent adapter (%d) not found\n", BUS8); + return -ENODEV; + } + + pdata[swpld1].client = i2c_new_dummy(parent, pdata[swpld1].reg_addr); + if (!pdata[swpld1].client) { + printk(KERN_ERR "Fail to create dummy i2c client for addr %d\n", pdata[swpld1].reg_addr); + goto error_swpld1; + } + + pdata[swpld2].client = i2c_new_dummy(parent, pdata[swpld2].reg_addr); + if (!pdata[swpld2].client) { + printk(KERN_ERR "Fail to create dummy i2c client for addr %d\n", pdata[swpld2].reg_addr); + goto error_swpld2; + } + + pdata[swpld3].client = i2c_new_dummy(parent, pdata[swpld3].reg_addr); + if (!pdata[swpld3].client) { + printk(KERN_ERR "Fail to create dummy i2c client for addr %d\n", pdata[swpld3].reg_addr); + goto error_swpld3; + } +#if 1 + kobj_swpld1 = kobject_create_and_add("SWPLD1", &pdev->dev.kobj); + if (!kobj_swpld1){ + printk(KERN_ERR "Fail to create directory"); + goto error_swpld3; + } + + kobj_swpld2 = kobject_create_and_add("SWPLD2", &pdev->dev.kobj); + if (!kobj_swpld2){ + printk(KERN_ERR "Fail to create directory"); + goto error_swpld3; + } + + kobj_swpld3 = kobject_create_and_add("SWPLD3", &pdev->dev.kobj); + if (!kobj_swpld3){ + printk(KERN_ERR "Fail to create directory"); + goto error_swpld3; + } +#endif +#if 1 + ret = sysfs_create_group(kobj_swpld1, &swpld1_device_attr_group); + if (ret) { + printk(KERN_ERR "Fail to create SWPLD1 attribute group"); + goto error_add_swpld1; + } +#endif +#if 1 + ret = sysfs_create_group(kobj_swpld2, &swpld2_device_attr_group); + if (ret) { + printk(KERN_ERR "Fail to create SWPLD2 attribute group"); + goto error_add_swpld2; + } +#endif +#if 1 + ret = sysfs_create_group(kobj_swpld3, &swpld3_device_attr_group); + if (ret) { + printk(KERN_ERR "Fail to create SWPLD3 attribute group"); + goto error_add_swpld3; + } +#endif + return 0; + +error_add_swpld3: + kobject_put(kobj_swpld2); +error_add_swpld2: + kobject_put(kobj_swpld1); +error_add_swpld1: + i2c_unregister_device(pdata[swpld3].client); +error_swpld3: + i2c_unregister_device(pdata[swpld2].client); +error_swpld2: + i2c_unregister_device(pdata[swpld1].client); +error_swpld1: + i2c_put_adapter(parent); +} + +static int __exit swpld_remove(struct platform_device *pdev) +{ + struct i2c_adapter *parent = NULL; + struct cpld_platform_data *pdata = pdev->dev.platform_data; + + if (!kobj_swpld1){ + sysfs_remove_group(kobj_swpld1, &swpld1_device_attr_group); + } + if (!kobj_swpld2){ + sysfs_remove_group(kobj_swpld2, &swpld2_device_attr_group); + } + if (!kobj_swpld3){ + sysfs_remove_group(kobj_swpld3, &swpld3_device_attr_group); + } + if (!pdata) { + dev_err(&pdev->dev, "Missing platform data\n"); + } + else { + if (pdata[swpld1].client) { + if (!parent) { + parent = (pdata[swpld1].client)->adapter; + } + i2c_unregister_device(pdata[swpld1].client); + } + if (pdata[swpld2].client) { + if (!parent) { + parent = (pdata[swpld2].client)->adapter; + } + i2c_unregister_device(pdata[swpld2].client); + } + if (pdata[swpld3].client) { + if (!parent) { + parent = (pdata[swpld3].client)->adapter; + } + i2c_unregister_device(pdata[swpld3].client); + } + } + i2c_put_adapter(parent); + + return 0; +} + +static struct platform_driver swpld_driver = { + .probe = swpld_probe, + .remove = __exit_p(swpld_remove), + .driver = { + .owner = THIS_MODULE, + .name = "delta-agc032-swpld", + }, +}; + +static int __init delta_agc032_swpld_init(void) +{ + int ret; + int i = 0; + + printk(KERN_INFO "agc032_platform_swpld module initialization\n"); + + /* Register SWPLD driver */ + ret = platform_driver_register(&swpld_driver); + if (ret) { + printk(KERN_ERR "Fail to register swpld driver\n"); + goto error_swpld1_driver; + } + + /* Register SWPLD Device */ + ret = platform_device_register(&swpld_device); + if (ret) { + printk(KERN_ERR "Fail to create swpld device\n"); + goto error_swpld1_device; + } + + return 0; + +error_swpld1_device: + platform_driver_unregister(&swpld_driver); +error_swpld1_driver: + return ret; +} + +static void __exit delta_agc032_swpld_exit(void) +{ + + platform_device_unregister(&swpld_device); + platform_driver_unregister(&swpld_driver); +} + +module_init(delta_agc032_swpld_init); +module_exit(delta_agc032_swpld_exit); + +MODULE_DESCRIPTION("DNI agc032 SWPLD Platform Support"); +MODULE_AUTHOR("James Ke "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-delta/agc032/modules/dni_agc032_psu.c b/platform/broadcom/sonic-platform-modules-delta/agc032/modules/dni_agc032_psu.c new file mode 100644 index 000000000000..ee46769fd311 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/agc032/modules/dni_agc032_psu.c @@ -0,0 +1,549 @@ +/* + * An hwmon driver for delta AGC032 PSU + * dps_1600ab_29_a.c - Support for DPS-1600AB-29 A Power Supply Module + * + * Copyright (C) 2016 Delta Network Technology Corporation + * + * DNI + * + * Based on ym2651y.c + * Based on ad7414.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_FAN_DUTY_CYCLE 100 +#define SWPLD_REG 0x31 +#define SWPLD_PSU_MUX_REG 0x21 +#define SELECT_PSU1_EEPROM 0x00 +#define SELECT_PSU2_EEPROM 0x20 + +u8 psu_member_data = 0x00; + + +/* Address scanned */ +static const unsigned short normal_i2c[] = { 0x58, I2C_CLIENT_END }; + +/* This is additional data */ +struct dps_1600ab_29_a_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; + unsigned long last_updated; /* In jiffies */ + + /* Registers value */ + u8 vout_mode; + u16 in1_input; + u16 in2_input; + u16 curr1_input; + u16 curr2_input; + u16 power1_input; + u16 power2_input; + u16 temp_input[2]; + u8 fan_target; + u16 fan_duty_cycle_input[2]; + u16 fan_speed_input[2]; + u8 mfr_model[16]; + u8 mfr_serial[16]; +}; + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask); +static ssize_t set_fan_duty_cycle_input(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_target(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 dps_1600ab_29_a_read_byte(struct i2c_client *client, u8 reg); +static int dps_1600ab_29_a_read_word(struct i2c_client *client, u8 reg); +static int dps_1600ab_29_a_write_word(struct i2c_client *client, u8 reg, \ + u16 value); +static int dps_1600ab_29_a_read_block(struct i2c_client *client, u8 command, \ + u8 *data, int data_len); +static struct dps_1600ab_29_a_data *dps_1600ab_29_a_update_device( \ + struct device *dev); +static ssize_t for_ascii(struct device *dev, struct device_attribute \ + *dev_attr, char *buf); +static ssize_t set_w_member_data(struct device *dev, struct device_attribute \ + *dev_att, const char *buf, size_t count); +static ssize_t for_r_member_data(struct device *dev, struct device_attribute \ + *dev_attr, char *buf); + +enum dps_1600ab_29_a_sysfs_attributes { + PSU_V_IN, + PSU_V_OUT, + PSU_I_IN, + PSU_I_OUT, + PSU_P_IN, + PSU_P_OUT, + PSU_TEMP1_INPUT, + PSU_FAN1_FAULT, + PSU_FAN1_DUTY_CYCLE, + PSU_FAN1_SPEED, + PSU_MFR_MODEL, + PSU_MFR_SERIAL, + PSU_SELECT_MEMBER, +}; + +static ssize_t set_w_member_data(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); + long data; + int error; + if (attr->index == PSU_SELECT_MEMBER) { + error = kstrtol(buf, 16, &data); + if (error) + return error; + if (SELECT_PSU1_EEPROM == data) { + psu_member_data = SELECT_PSU1_EEPROM; + } else if (SELECT_PSU2_EEPROM == data) { + psu_member_data = SELECT_PSU2_EEPROM; + } else { + return -EINVAL; + } + } + return count; +} + +static ssize_t for_r_member_data(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + return sprintf(buf, "0x%02X\n", psu_member_data); +} + +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_input(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 dps_1600ab_29_a_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; + + /* Select SWPLD PSU offset */ + + mutex_lock(&data->update_lock); + data->fan_duty_cycle_input[nr] = speed; + dps_1600ab_29_a_write_word(client, 0x3B + nr, data->fan_duty_cycle_input[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 dps_1600ab_29_a_data *data = dps_1600ab_29_a_update_device(dev); + + u16 value = 0; + int exponent, mantissa; + int multiplier = 1000; + + switch (attr->index) { + case PSU_V_IN: + value = data->in1_input; + break; + case PSU_I_IN: + value = data->curr1_input; + break; + case PSU_I_OUT: + value = data->curr2_input; + break; + case PSU_P_IN: + value = data->power1_input; + multiplier = 1000*1000; + break; + case PSU_P_OUT: + value = data->power2_input; + multiplier = 1000*1000; + break; + case PSU_TEMP1_INPUT: + value = data->temp_input[0]; + break; + case PSU_FAN1_DUTY_CYCLE: + multiplier = 1; + value = data->fan_duty_cycle_input[0]; + break; + case PSU_FAN1_SPEED: + multiplier = 1; + value = data->fan_speed_input[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_target(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct dps_1600ab_29_a_data *data = dps_1600ab_29_a_update_device(dev); + + u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; + + return sprintf(buf, "%d\n", data->fan_target >> shift); +} + +static ssize_t for_vout_data(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct dps_1600ab_29_a_data *data = dps_1600ab_29_a_update_device(dev); + int exponent, mantissa; + int multiplier = 1000; + + exponent = two_complement_to_int(data->vout_mode, 5, 0x1f); + mantissa = data->in2_input; + + return (exponent > 0) ? sprintf(buf, "%d\n", \ + (mantissa * multiplier) / (1 << exponent)): \ + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -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 dps_1600ab_29_a_data *data = dps_1600ab_29_a_update_device(dev); + u8 *ptr = NULL; + + if (!data->valid) + return 0; + + switch (attr->index) { + 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 int dps_1600ab_29_a_read_byte(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int dps_1600ab_29_a_read_word(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_word_data(client, reg); +} + +static int dps_1600ab_29_a_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 dps_1600ab_29_a_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 dps_1600ab_29_a_data *dps_1600ab_29_a_update_device( \ + struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct dps_1600ab_29_a_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + /* Select SWPLD PSU offset */ + + 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_target} + }; + struct reg_data_word regs_word[] = { + {0x88, &data->in1_input}, + {0x8b, &data->in2_input}, + {0x89, &data->curr1_input}, + {0x8c, &data->curr2_input}, + {0x96, &data->power2_input}, + {0x97, &data->power1_input}, + {0x8d, &(data->temp_input[0])}, + {0x8e, &(data->temp_input[1])}, + {0x3b, &(data->fan_duty_cycle_input[0])}, + {0x90, &(data->fan_speed_input[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 = dps_1600ab_29_a_read_byte(client, + regs_byte[i].reg); + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_byte[i].reg, status); + *(regs_byte[i].value) = 0; + } else { + *(regs_byte[i].value) = status; + } + } + + for (i = 0; i < ARRAY_SIZE(regs_word); i++) { + status = dps_1600ab_29_a_read_word(client, + regs_word[i].reg); + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_word[i].reg, status); + *(regs_word[i].value) = 0; + } else { + *(regs_word[i].value) = status; + } + } + + command = 0x9a; /* PSU mfr_model */ + //data->mfr_model[1] = '\0'; + status = dps_1600ab_29_a_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); + data->mfr_model[1] = '\0'; + } + + command = 0x9e; /* PSU mfr_serial */ + //data->mfr_serial[1] = '\0'; + status = dps_1600ab_29_a_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->mfr_serial[1] = '\0'; + } + + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; + +} + +/* sysfs attributes for hwmon */ +static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, for_linear_data, NULL, PSU_V_IN); +static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, for_vout_data, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, for_linear_data, NULL, PSU_I_IN); +static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, for_linear_data, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, for_linear_data, NULL, PSU_P_IN); +static SENSOR_DEVICE_ATTR(power2_input, S_IRUGO, for_linear_data, NULL, PSU_P_OUT); +static SENSOR_DEVICE_ATTR(temp1_input, \ + S_IRUGO, for_linear_data, NULL, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(fan1_target, \ + S_IRUGO, for_fan_target, NULL, PSU_FAN1_FAULT); +static SENSOR_DEVICE_ATTR(fan1_set_percentage, S_IWUSR | S_IRUGO, \ + for_linear_data, set_fan_duty_cycle_input, PSU_FAN1_DUTY_CYCLE); +static SENSOR_DEVICE_ATTR(fan1_input, \ + S_IRUGO, for_linear_data, NULL, PSU_FAN1_SPEED); +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_select_member, S_IWUSR | S_IRUGO, \ + for_r_member_data, set_w_member_data, PSU_SELECT_MEMBER); + +static struct attribute *dps_1600ab_29_a_attributes[] = { + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_in2_input.dev_attr.attr, + &sensor_dev_attr_curr1_input.dev_attr.attr, + &sensor_dev_attr_curr2_input.dev_attr.attr, + &sensor_dev_attr_power1_input.dev_attr.attr, + &sensor_dev_attr_power2_input.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_fan1_target.dev_attr.attr, + &sensor_dev_attr_fan1_set_percentage.dev_attr.attr, + &sensor_dev_attr_fan1_input.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_select_member.dev_attr.attr, + NULL +}; + +static const struct attribute_group dps_1600ab_29_a_group = { + .attrs = dps_1600ab_29_a_attributes, +}; + +static int dps_1600ab_29_a_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct dps_1600ab_29_a_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 */ + status = sysfs_create_group(&client->dev.kobj, &dps_1600ab_29_a_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, &dps_1600ab_29_a_group); +exit_sysfs_create_group: + kfree(data); +exit: + return status; +} + +static int dps_1600ab_29_a_remove(struct i2c_client *client) +{ + struct dps_1600ab_29_a_data *data = i2c_get_clientdata(client); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &dps_1600ab_29_a_group); + kfree(data); + + return 0; +} + +enum id_name { + dni_agc032_psu, + dps_1600ab_29_a +}; + +static const struct i2c_device_id dps_1600ab_29_a_id[] = { + { "dni_agc032_psu", dni_agc032_psu }, + { "dps_1600ab_29_a", dps_1600ab_29_a }, + {} +}; +MODULE_DEVICE_TABLE(i2c, dps_1600ab_29_a_id); + +/* This is the driver that will be inserted */ +static struct i2c_driver dps_1600ab_29_a_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "dps_1600ab_29_a", + }, + .probe = dps_1600ab_29_a_probe, + .remove = dps_1600ab_29_a_remove, + .id_table = dps_1600ab_29_a_id, + .address_list = normal_i2c, +}; + +static int __init dps_1600ab_29_a_init(void) +{ + return i2c_add_driver(&dps_1600ab_29_a_driver); +} + +static void __exit dps_1600ab_29_a_exit(void) +{ + i2c_del_driver(&dps_1600ab_29_a_driver); +} + + +MODULE_DESCRIPTION("DPS_1600AB_29_A Driver"); +MODULE_LICENSE("GPL"); + +module_init(dps_1600ab_29_a_init); +module_exit(dps_1600ab_29_a_exit); diff --git a/platform/broadcom/sonic-platform-modules-delta/agc032/modules/dni_emc2302.c b/platform/broadcom/sonic-platform-modules-delta/agc032/modules/dni_emc2302.c new file mode 100644 index 000000000000..c947db1e96c5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/agc032/modules/dni_emc2302.c @@ -0,0 +1,363 @@ +/* + * + * + * Copyright (C) 2017 Delta Networks, Inc. + * + * This program is free software; you can redistribute it + * and/or modify it under the terms ofthe GNU General Public License as + * published by the Free Software Foundation; either version 2 of the License, + * or (at your option) any later version. + * + * + * + * + * + * A hwmon driver for the SMSC EMC2302 fan controller + * Complete datasheet is available (6/2013) at: + * + */ + +#include +#include +#include +#include +#include + + +static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count); +static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, + char *buf); +static ssize_t set_fan(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count); +static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, + char *buf); +static ssize_t set_fan_percentage(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count); +static ssize_t show_fan_percentage(struct device *dev, struct device_attribute * devattr, + char *buf); +static const unsigned short normal_i2c[] = { 0x2C, 0x2D, 0x2E, 0x2F, 0x4C, + 0x4D, I2C_CLIENT_END + }; + + +#define EMC2302_REG_DEVICE 0xFD +#define EMC2302_REG_VENDOR 0xFE + +//#define FAN_MINIMUN 0x33 /*20%*/ +#define FAN_MINIMUN 0x0 /*0%*/ +#define FAN_RPM_BASED 0xAB + +#define EMC2302_REG_FAN_DRIVE(n) (0x30 + 0x10 * n) +#define EMC2302_REG_FAN_MIN_DRIVE(n) (0x38 + 0x10 * n) +#define EMC2302_REG_FAN_TACH(n) (0x3E + 0x10 * n) +#define EMC2302_REG_FAN_CONF(n) (0x32 + 0x10 * n) +#define EMC2302_REG_FAN_REAR_H_RPM(n) (0x3D + 0x10 * n) +#define EMC2302_REG_FAN_REAR_L_RPM(n) (0x3C + 0x10 * n) + +#define EMC2302_DEVICE 0x36 +#define EMC2302_VENDOR 0x5D +#define MAX_FAN_SPEED 23000 + +struct emc2302_data +{ + struct device *hwmon_dev; + struct attribute_group attrs; + struct mutex lock; +}; + +static int emc2302_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int emc2302_detect(struct i2c_client *client, + struct i2c_board_info *info); +static int emc2302_remove(struct i2c_client *client); + +static const struct i2c_device_id emc2302_id[] = +{ + { "emc2302", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, emc2302_id); + +static struct i2c_driver emc2302_driver = +{ + .class = I2C_CLASS_HWMON, + .driver = { + .name = "emc2302", + }, + .probe = emc2302_probe, + .remove = emc2302_remove, + .id_table = emc2302_id, + .detect = emc2302_detect, + .address_list = normal_i2c, +}; + +static SENSOR_DEVICE_ATTR(fan1_input, S_IWUSR | S_IRUGO, show_fan, set_fan, 0); +static SENSOR_DEVICE_ATTR(fan2_input, S_IWUSR | S_IRUGO, show_fan, set_fan, 1); +static SENSOR_DEVICE_ATTR(fan1_input_percentage, S_IWUSR | S_IRUGO, show_fan_percentage, set_fan_percentage, 0); +static SENSOR_DEVICE_ATTR(fan2_input_percentage, S_IWUSR | S_IRUGO, show_fan_percentage, set_fan_percentage, 1); +static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 0); +static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 1); + +static struct attribute *emc2302_attr[] = +{ + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan2_input.dev_attr.attr, + &sensor_dev_attr_fan1_input_percentage.dev_attr.attr, + &sensor_dev_attr_fan2_input_percentage.dev_attr.attr, + &sensor_dev_attr_pwm1.dev_attr.attr, + &sensor_dev_attr_pwm2.dev_attr.attr, + NULL +}; + +static ssize_t show_fan_percentage(struct device *dev, struct device_attribute * devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct emc2302_data *data = i2c_get_clientdata(client); + int val; + + mutex_lock(&data->lock); + val = i2c_smbus_read_word_swapped(client, + EMC2302_REG_FAN_TACH(attr->index)); + mutex_unlock(&data->lock); + /* Left shift 3 bits for showing correct RPM */ + val = val >> 3; + if ((int)(3932160 * 2 / (val > 0 ? val : 1) == 960))return sprintf(buf, "%d\n", 0); + return sprintf(buf, "%d\n", (int)(3932160 * 2 / (val > 0 ? val : 1) * 100 / MAX_FAN_SPEED)); +} + + +static ssize_t set_fan_percentage(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct emc2302_data *data = i2c_get_clientdata(client); + unsigned long hsb, lsb; + unsigned long tech; + unsigned long val; + int ret; + + ret = kstrtoul(buf, 10, &val); + if (ret) + { + return ret; + } + if (val > 100) + { + return -EINVAL; + } + + if (val <= 5) + { + hsb = 0xff; /*high bit*/ + lsb = 0xe0; /*low bit*/ + } + else + { + val = val * 230; + tech = (3932160 * 2) / (val > 0 ? val : 1); + hsb = (uint8_t)(((tech << 3) >> 8) & 0x0ff); + lsb = (uint8_t)((tech << 3) & 0x0f8); + } + + mutex_lock(&data->lock); + i2c_smbus_write_byte_data(client, EMC2302_REG_FAN_REAR_H_RPM(attr->index), hsb); + i2c_smbus_write_byte_data(client, EMC2302_REG_FAN_REAR_L_RPM(attr->index), lsb); + mutex_unlock(&data->lock); + return count; +} + + +static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct emc2302_data *data = i2c_get_clientdata(client); + int val; + + + mutex_lock(&data->lock); + val = i2c_smbus_read_word_swapped(client, + EMC2302_REG_FAN_TACH(attr->index)); + mutex_unlock(&data->lock); + /* Left shift 3 bits for showing correct RPM */ + val = val >> 3; + return sprintf(buf, "%d\n", 3932160 * 2 / (val > 0 ? val : 1)); +} + +static ssize_t set_fan(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct emc2302_data *data = i2c_get_clientdata(client); + unsigned long hsb, lsb; + unsigned long tech; + unsigned long val; + int ret; + + ret = kstrtoul(buf, 10, &val); + if (ret) + { + return ret; + } + if (val > 23000) + { + return -EINVAL; + } + + if (val <= 960) + { + hsb = 0xff; /*high bit*/ + lsb = 0xe0; /*low bit*/ + } + else + { + tech = (3932160 * 2) / (val > 0 ? val : 1); + hsb = (uint8_t)(((tech << 3) >> 8) & 0x0ff); + lsb = (uint8_t)((tech << 3) & 0x0f8); + } + + mutex_lock(&data->lock); + i2c_smbus_write_byte_data(client, EMC2302_REG_FAN_REAR_H_RPM(attr->index), hsb); + i2c_smbus_write_byte_data(client, EMC2302_REG_FAN_REAR_L_RPM(attr->index), lsb); + mutex_unlock(&data->lock); + return count; +} + +static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct emc2302_data *data = i2c_get_clientdata(client); + int val; + + mutex_lock(&data->lock); + val = i2c_smbus_read_byte_data(client, + EMC2302_REG_FAN_DRIVE(attr->index)); + mutex_unlock(&data->lock); + return sprintf(buf, "%d\n", val); +} + +static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct emc2302_data *data = i2c_get_clientdata(client); + unsigned long val; + int ret; + + ret = kstrtoul(buf, 10, &val); + if (ret) + { + return ret; + } + if (val > 255) + { + return -EINVAL; + } + + mutex_lock(&data->lock); + i2c_smbus_write_byte_data(client, + EMC2302_REG_FAN_DRIVE(attr->index), + val); + mutex_unlock(&data->lock); + return count; +} + +static int emc2302_detect(struct i2c_client *client, + struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = client->adapter; + int vendor, device; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA)) + { + return -ENODEV; + } + + vendor = i2c_smbus_read_byte_data(client, EMC2302_REG_VENDOR); + if (vendor != EMC2302_VENDOR) + { + return -ENODEV; + } + + device = i2c_smbus_read_byte_data(client, EMC2302_REG_DEVICE); + if (device != EMC2302_DEVICE) + { + return -ENODEV; + } + + strlcpy(info->type, "emc2302", I2C_NAME_SIZE); + + return 0; +} + +static int emc2302_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct emc2302_data *data; + int err; + int i; + + data = devm_kzalloc(&client->dev, sizeof(struct emc2302_data), + GFP_KERNEL); + if (!data) + { + return -ENOMEM; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->lock); + + dev_info(&client->dev, "%s chip found\n", client->name); + + data->attrs.attrs = emc2302_attr; + err = sysfs_create_group(&client->dev.kobj, &data->attrs); + if (err) + { + return err; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) + { + err = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + for (i = 0; i < 2; i++) + { + /* set minimum drive to 0% */ + i2c_smbus_write_byte_data(client, EMC2302_REG_FAN_MIN_DRIVE(i), FAN_MINIMUN); + i2c_smbus_write_byte_data(client, EMC2302_REG_FAN_CONF(i), FAN_RPM_BASED); + } + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &data->attrs); + return err; +} + +static int emc2302_remove(struct i2c_client *client) +{ + struct emc2302_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &data->attrs); + return 0; +} + +module_i2c_driver(emc2302_driver); + +MODULE_AUTHOR("Zoe Kuan"); +MODULE_DESCRIPTION("SMSC EMC2302 fan controller driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-delta/agc032/modules/dni_emc2305.c b/platform/broadcom/sonic-platform-modules-delta/agc032/modules/dni_emc2305.c new file mode 120000 index 000000000000..e8f7ae6b3f4d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/agc032/modules/dni_emc2305.c @@ -0,0 +1 @@ +../../common/modules/dni_emc2305.c \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-delta/agc032/scripts/agc032_platform_init.sh b/platform/broadcom/sonic-platform-modules-delta/agc032/scripts/agc032_platform_init.sh new file mode 100755 index 000000000000..e14470a4c908 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/agc032/scripts/agc032_platform_init.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +#platform init script for Delta agc032 + +#fan speed monitor start +/usr/share/sonic/device/x86_64-delta_agc032-r0/fancontrol.service /usr/share/sonic/device/x86_64-delta_agc032-r0/fancontrol & + +# On Delta-agc032 platform, +# syseeprom is on the different mux with main board after CPLD, +# we have to switch CPLD mux from main board to syseeprom before getting syseeprom data. +# +# The purpose of switching CPLD mux and getting syseeprom information here +# is to store data in syseeprom_cache. +# After that, we can read "syseeprom_cache" directly when executing command +# "show platform syseeprom", "sudo decode-syseeprom", "show version". + +echo 0 |sudo tee /sys/devices/platform/delta-agc032-cpupld.0/cpu_i2c_mux_sel +decode-syseeprom +echo 1 |sudo tee /sys/devices/platform/delta-agc032-cpupld.0/cpu_i2c_mux_sel + +exit 0 + diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/control b/platform/broadcom/sonic-platform-modules-delta/debian/control index e2e9883f9b2b..809c58b0c0b1 100644 --- a/platform/broadcom/sonic-platform-modules-delta/debian/control +++ b/platform/broadcom/sonic-platform-modules-delta/debian/control @@ -7,25 +7,30 @@ Standards-Version: 3.9.3 Package: platform-modules-ag9032v1 Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-ag9064 Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-ag5648 Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-et-6248brb Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-ag9032v2a Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as syseeprom, sfp + +Package: platform-modules-agc032 +Architecture: amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned +Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-agc032.init b/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-agc032.init new file mode 100644 index 000000000000..5c106f87f919 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-agc032.init @@ -0,0 +1,62 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: setup-board +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Setup agc032 board. +### END INIT INFO + +case "$1" in +start) + echo -n "Setting up board... " + depmod -a + rmmod i2c-i801 + rmmod i2c-ismt + modprobe i2c-dev + modprobe i2c-i801 + modprobe i2c-ismt + modprobe i2c-mux-pca954x + modprobe dni_agc032_psu + modprobe dni_emc2305 + modprobe dni_emc2302 + modprobe at24 + modprobe optoe + modprobe delta_agc032_cpupld +# Switch CPUPLD to ONIE EEPROM Mux + echo 0 |sudo tee /sys/devices/platform/delta-agc032-cpupld.0/cpu_i2c_mux_sel + modprobe eeprom + +# Switch CPUPLD to Front Port Mux + echo 3 |sudo tee /sys/devices/platform/delta-agc032-cpupld.0/cpu_i2c_mux_sel + modprobe delta_agc032_qsfp + +# Switch CPUPLD to MainBoard Mux + echo 1 |sudo tee /sys/devices/platform/delta-agc032-cpupld.0/cpu_i2c_mux_sel + modprobe delta_agc032_platform + modprobe delta_agc032_swpld + + /usr/local/bin/agc032_platform_init.sh + echo "done." + ;; + +stop) + echo "done." + + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/platform-modules-agc032.init {start|stop}" + exit 1 + ;; +esac + +exit 0 diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-agc032.install b/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-agc032.install new file mode 100644 index 000000000000..e05e3694fd3e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-agc032.install @@ -0,0 +1,3 @@ +agc032/scripts/agc032_platform_init.sh usr/local/bin +agc032/cfg/agc032-modules.conf etc/modules-load.d +systemd/platform-modules-agc032.service lib/systemd/system diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/rules b/platform/broadcom/sonic-platform-modules-delta/debian/rules index b8c34c326fde..39126ff76729 100755 --- a/platform/broadcom/sonic-platform-modules-delta/debian/rules +++ b/platform/broadcom/sonic-platform-modules-delta/debian/rules @@ -5,7 +5,7 @@ export INSTALL_MOD_DIR:=extra KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= ag9032v1 ag9064 ag5648 et-6248brb ag9032v2a +MODULE_DIRS:= ag9032v1 ag9064 ag5648 et-6248brb ag9032v2a agc032 %: dh $@ --with=systemd diff --git a/platform/broadcom/sonic-platform-modules-delta/et-6248brb/modules/delta_et-6248brb_platform.c b/platform/broadcom/sonic-platform-modules-delta/et-6248brb/modules/delta_et-6248brb_platform.c index 72fccd9aa0e8..7cbe161e62b2 100644 --- a/platform/broadcom/sonic-platform-modules-delta/et-6248brb/modules/delta_et-6248brb_platform.c +++ b/platform/broadcom/sonic-platform-modules-delta/et-6248brb/modules/delta_et-6248brb_platform.c @@ -9,11 +9,11 @@ #include #include #include -#include +#include #include #include -#include +#include #include #include #include diff --git a/platform/broadcom/sonic-platform-modules-delta/systemd/platform-modules-agc032.service b/platform/broadcom/sonic-platform-modules-delta/systemd/platform-modules-agc032.service new file mode 100644 index 000000000000..b84b6fba0aeb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/systemd/platform-modules-agc032.service @@ -0,0 +1,13 @@ +[Unit] +Description=Delta agc032 Platform modules +After=local-fs.target +Before=pmon.service + +[Service] +Type=oneshot +ExecStart=-/etc/init.d/platform-modules-agc032 start +ExecStop=-/etc/init.d/platform-modules-agc032 stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/modules/qsfp_cpld.c b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/modules/qsfp_cpld.c index 8ec03ecea340..66ae8d558507 100644 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/modules/qsfp_cpld.c +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/modules/qsfp_cpld.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/modules/cpld.c b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/modules/cpld.c index 7b16f5d3e321..b15ee836b187 100755 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/modules/cpld.c +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/modules/cpld.c @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6254qs/modules/inv_platform.c b/platform/broadcom/sonic-platform-modules-inventec/d6254qs/modules/inv_platform.c index e69b526f4555..e6cb4c3d173d 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d6254qs/modules/inv_platform.c +++ b/platform/broadcom/sonic-platform-modules-inventec/d6254qs/modules/inv_platform.c @@ -6,13 +6,13 @@ */ #include -#include +#include #include #include #include #include -#include +#include struct inv_i2c_board_info { int ch; diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/Makefile b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/Makefile new file mode 100755 index 000000000000..7cb80a281baf --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/Makefile @@ -0,0 +1,8 @@ +obj-m += gpio-ich.o +obj-m += lpc_ich.o +obj-m += inv_cpld.o +obj-m += inv_platform.o +obj-m += inv_eeprom.o +obj-m += i2c-mux-pca9541.o +obj-m += swps.o +swps-objs := inv_swps.o inv_mux.o io_expander.o transceiver.o diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/gpio-ich.c b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/gpio-ich.c new file mode 100644 index 000000000000..687834e3c561 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/gpio-ich.c @@ -0,0 +1,513 @@ +/* + * Intel ICH6-10, Series 5 and 6, Atom C2000 (Avoton/Rangeley) GPIO driver + * + * Copyright (C) 2010 Extreme Engineering Solutions. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You 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 pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "gpio_ich" + +/* + * GPIO register offsets in GPIO I/O space. + * Each chunk of 32 GPIOs is manipulated via its own USE_SELx, IO_SELx, and + * LVLx registers. Logic in the read/write functions takes a register and + * an absolute bit number and determines the proper register offset and bit + * number in that register. For example, to read the value of GPIO bit 50 + * the code would access offset ichx_regs[2(=GPIO_LVL)][1(=50/32)], + * bit 18 (50%32). + */ +enum GPIO_REG { + GPIO_USE_SEL = 0, + GPIO_IO_SEL, + GPIO_LVL, + GPO_BLINK +}; + +static const u8 ichx_regs[4][3] = { + {0x00, 0x30, 0x40}, /* USE_SEL[1-3] offsets */ + {0x04, 0x34, 0x44}, /* IO_SEL[1-3] offsets */ + {0x0c, 0x38, 0x48}, /* LVL[1-3] offsets */ + {0x18, 0x18, 0x18}, /* BLINK offset */ +}; + +static const u8 ichx_reglen[3] = { + 0x30, 0x10, 0x10, +}; + +static const u8 avoton_regs[4][3] = { + {0x00, 0x80, 0x00}, + {0x04, 0x84, 0x00}, + {0x08, 0x88, 0x00}, +}; + +static const u8 avoton_reglen[3] = { + 0x10, 0x10, 0x00, +}; + +#define ICHX_WRITE(val, reg, base_res) outl(val, (reg) + (base_res)->start) +#define ICHX_READ(reg, base_res) inl((reg) + (base_res)->start) + +struct ichx_desc { + /* Max GPIO pins the chipset can have */ + uint ngpio; + + /* chipset registers */ + const u8 (*regs)[3]; + const u8 *reglen; + + /* GPO_BLINK is available on this chipset */ + bool have_blink; + + /* Whether the chipset has GPIO in GPE0_STS in the PM IO region */ + bool uses_gpe0; + + /* USE_SEL is bogus on some chipsets, eg 3100 */ + u32 use_sel_ignore[3]; + + /* Some chipsets have quirks, let these use their own request/get */ + int (*request)(struct gpio_chip *chip, unsigned offset); + int (*get)(struct gpio_chip *chip, unsigned offset); + + /* + * Some chipsets don't let reading output values on GPIO_LVL register + * this option allows driver caching written output values + */ + bool use_outlvl_cache; +}; + +static struct { + spinlock_t lock; + struct platform_device *dev; + struct gpio_chip chip; + struct resource *gpio_base; /* GPIO IO base */ + struct resource *pm_base; /* Power Mangagment IO base */ + struct ichx_desc *desc; /* Pointer to chipset-specific description */ + u32 orig_gpio_ctrl; /* Orig CTRL value, used to restore on exit */ + u8 use_gpio; /* Which GPIO groups are usable */ + int outlvl_cache[3]; /* cached output values */ +} ichx_priv; + +static int modparam_gpiobase = 0; /* dynamic */ +module_param_named(gpiobase, modparam_gpiobase, int, 0444); +MODULE_PARM_DESC(gpiobase, "The GPIO number base. -1 means dynamic, " + "which is the default."); + +static int ichx_write_bit(int reg, unsigned nr, int val, int verify) +{ + unsigned long flags; + u32 data, tmp; + int reg_nr = nr / 32; + int bit = nr & 0x1f; + int ret = 0; + + spin_lock_irqsave(&ichx_priv.lock, flags); + + if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache) + data = ichx_priv.outlvl_cache[reg_nr]; + else + data = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr], + ichx_priv.gpio_base); + + if (val) + data |= 1 << bit; + else + data &= ~(1 << bit); + ICHX_WRITE(data, ichx_priv.desc->regs[reg][reg_nr], + ichx_priv.gpio_base); + if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache) + ichx_priv.outlvl_cache[reg_nr] = data; + + tmp = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr], + ichx_priv.gpio_base); + if (verify && data != tmp) + ret = -EPERM; + + spin_unlock_irqrestore(&ichx_priv.lock, flags); + + return ret; +} + +static int ichx_read_bit(int reg, unsigned nr) +{ + unsigned long flags; + u32 data; + int reg_nr = nr / 32; + int bit = nr & 0x1f; + + spin_lock_irqsave(&ichx_priv.lock, flags); + + data = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr], + ichx_priv.gpio_base); + + if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache) + data = ichx_priv.outlvl_cache[reg_nr] | data; + + spin_unlock_irqrestore(&ichx_priv.lock, flags); + + return data & (1 << bit) ? 1 : 0; +} + +static bool ichx_gpio_check_available(struct gpio_chip *gpio, unsigned nr) +{ + return !!(ichx_priv.use_gpio & (1 << (nr / 32))); +} + +static int ichx_gpio_get_direction(struct gpio_chip *gpio, unsigned nr) +{ + return ichx_read_bit(GPIO_IO_SEL, nr) ? GPIOF_DIR_IN : GPIOF_DIR_OUT; +} + +static int ichx_gpio_direction_input(struct gpio_chip *gpio, unsigned nr) +{ + /* + * Try setting pin as an input and verify it worked since many pins + * are output-only. + */ + if (ichx_write_bit(GPIO_IO_SEL, nr, 1, 1)) + return -EINVAL; + + return 0; +} + +static int ichx_gpio_direction_output(struct gpio_chip *gpio, unsigned nr, + int val) +{ + /* Disable blink hardware which is available for GPIOs from 0 to 31. */ + if (nr < 32 && ichx_priv.desc->have_blink) + ichx_write_bit(GPO_BLINK, nr, 0, 0); + + /* Set GPIO output value. */ + ichx_write_bit(GPIO_LVL, nr, val, 0); + + /* + * Try setting pin as an output and verify it worked since many pins + * are input-only. + */ + if (ichx_write_bit(GPIO_IO_SEL, nr, 0, 1)) + return -EINVAL; + + return 0; +} + +static int ichx_gpio_get(struct gpio_chip *chip, unsigned nr) +{ + return ichx_read_bit(GPIO_LVL, nr); +} + +static int ich6_gpio_get(struct gpio_chip *chip, unsigned nr) +{ + unsigned long flags; + u32 data; + + /* + * GPI 0 - 15 need to be read from the power management registers on + * a ICH6/3100 bridge. + */ + if (nr < 16) { + if (!ichx_priv.pm_base) + return -ENXIO; + + spin_lock_irqsave(&ichx_priv.lock, flags); + + /* GPI 0 - 15 are latched, write 1 to clear*/ + ICHX_WRITE(1 << (16 + nr), 0, ichx_priv.pm_base); + data = ICHX_READ(0, ichx_priv.pm_base); + + spin_unlock_irqrestore(&ichx_priv.lock, flags); + + return (data >> 16) & (1 << nr) ? 1 : 0; + } else { + return ichx_gpio_get(chip, nr); + } +} + +static int ichx_gpio_request(struct gpio_chip *chip, unsigned nr) +{ + if (!ichx_gpio_check_available(chip, nr)) + return -ENXIO; + + /* + * Note we assume the BIOS properly set a bridge's USE value. Some + * chips (eg Intel 3100) have bogus USE values though, so first see if + * the chipset's USE value can be trusted for this specific bit. + * If it can't be trusted, assume that the pin can be used as a GPIO. + */ + if (ichx_priv.desc->use_sel_ignore[nr / 32] & (1 << (nr & 0x1f))) + return 0; + + return ichx_read_bit(GPIO_USE_SEL, nr) ? 0 : -ENODEV; +} + +static int ich6_gpio_request(struct gpio_chip *chip, unsigned nr) +{ + /* + * Fixups for bits 16 and 17 are necessary on the Intel ICH6/3100 + * bridge as they are controlled by USE register bits 0 and 1. See + * "Table 704 GPIO_USE_SEL1 register" in the i3100 datasheet for + * additional info. + */ + if (nr == 16 || nr == 17) + nr -= 16; + + return ichx_gpio_request(chip, nr); +} + +static void ichx_gpio_set(struct gpio_chip *chip, unsigned nr, int val) +{ + ichx_write_bit(GPIO_LVL, nr, val, 0); +} + +static void ichx_gpiolib_setup(struct gpio_chip *chip) +{ + chip->owner = THIS_MODULE; + chip->label = DRV_NAME; + chip->parent = &ichx_priv.dev->dev; + + /* Allow chip-specific overrides of request()/get() */ + chip->request = ichx_priv.desc->request ? + ichx_priv.desc->request : ichx_gpio_request; + chip->get = ichx_priv.desc->get ? + ichx_priv.desc->get : ichx_gpio_get; + + chip->set = ichx_gpio_set; + chip->get_direction = ichx_gpio_get_direction; + chip->direction_input = ichx_gpio_direction_input; + chip->direction_output = ichx_gpio_direction_output; + chip->base = modparam_gpiobase; + chip->ngpio = ichx_priv.desc->ngpio; + chip->can_sleep = false; + chip->dbg_show = NULL; +} + +/* ICH6-based, 631xesb-based */ +static struct ichx_desc ich6_desc = { + /* Bridges using the ICH6 controller need fixups for GPIO 0 - 17 */ + .request = ich6_gpio_request, + .get = ich6_gpio_get, + + /* GPIO 0-15 are read in the GPE0_STS PM register */ + .uses_gpe0 = true, + + .ngpio = 50, + .have_blink = true, + .regs = ichx_regs, + .reglen = ichx_reglen, +}; + +/* Intel 3100 */ +static struct ichx_desc i3100_desc = { + /* + * Bits 16,17, 20 of USE_SEL and bit 16 of USE_SEL2 always read 0 on + * the Intel 3100. See "Table 712. GPIO Summary Table" of 3100 + * Datasheet for more info. + */ + .use_sel_ignore = {0x00130000, 0x00010000, 0x0}, + + /* The 3100 needs fixups for GPIO 0 - 17 */ + .request = ich6_gpio_request, + .get = ich6_gpio_get, + + /* GPIO 0-15 are read in the GPE0_STS PM register */ + .uses_gpe0 = true, + + .ngpio = 50, + .regs = ichx_regs, + .reglen = ichx_reglen, +}; + +/* ICH7 and ICH8-based */ +static struct ichx_desc ich7_desc = { + .ngpio = 50, + .have_blink = true, + .regs = ichx_regs, + .reglen = ichx_reglen, +}; + +/* ICH9-based */ +static struct ichx_desc ich9_desc = { + .ngpio = 61, + .have_blink = true, + .regs = ichx_regs, + .reglen = ichx_reglen, +}; + +/* ICH10-based - Consumer/corporate versions have different amount of GPIO */ +static struct ichx_desc ich10_cons_desc = { + .ngpio = 61, + .have_blink = true, + .regs = ichx_regs, + .reglen = ichx_reglen, +}; +static struct ichx_desc ich10_corp_desc = { + .ngpio = 72, + .have_blink = true, + .regs = ichx_regs, + .reglen = ichx_reglen, +}; + +/* Intel 5 series, 6 series, 3400 series, and C200 series */ +static struct ichx_desc intel5_desc = { + .ngpio = 76, + .regs = ichx_regs, + .reglen = ichx_reglen, +}; + +/* Avoton */ +static struct ichx_desc avoton_desc = { + /* Avoton has only 59 GPIOs, but we assume the first set of register + * (Core) has 32 instead of 31 to keep gpio-ich compliance + */ + .ngpio = 60, + .regs = avoton_regs, + .reglen = avoton_reglen, + .use_outlvl_cache = true, +}; + +static int ichx_gpio_request_regions(struct device *dev, + struct resource *res_base, const char *name, u8 use_gpio) +{ + int i; + + if (!res_base || !res_base->start || !res_base->end) + return -ENODEV; + + for (i = 0; i < ARRAY_SIZE(ichx_priv.desc->regs[0]); i++) { + if (!(use_gpio & (1 << i))) + continue; + if (!devm_request_region(dev, + res_base->start + ichx_priv.desc->regs[0][i], + ichx_priv.desc->reglen[i], name)) + return -EBUSY; + } + return 0; +} + +static int ichx_gpio_probe(struct platform_device *pdev) +{ + struct resource *res_base, *res_pm; + int err; + struct lpc_ich_info *ich_info = dev_get_platdata(&pdev->dev); + + if (!ich_info) + return -ENODEV; + + ichx_priv.dev = pdev; + + switch (ich_info->gpio_version) { + case ICH_I3100_GPIO: + ichx_priv.desc = &i3100_desc; + break; + case ICH_V5_GPIO: + ichx_priv.desc = &intel5_desc; + break; + case ICH_V6_GPIO: + ichx_priv.desc = &ich6_desc; + break; + case ICH_V7_GPIO: + ichx_priv.desc = &ich7_desc; + break; + case ICH_V9_GPIO: + ichx_priv.desc = &ich9_desc; + break; + case ICH_V10CORP_GPIO: + ichx_priv.desc = &ich10_corp_desc; + break; + case ICH_V10CONS_GPIO: + ichx_priv.desc = &ich10_cons_desc; + break; + case AVOTON_GPIO: + ichx_priv.desc = &avoton_desc; + break; + default: + return -ENODEV; + } + + spin_lock_init(&ichx_priv.lock); + res_base = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPIO); + ichx_priv.use_gpio = ich_info->use_gpio; + err = ichx_gpio_request_regions(&pdev->dev, res_base, pdev->name, + ichx_priv.use_gpio); + if (err) + return err; + + ichx_priv.gpio_base = res_base; + + /* + * If necessary, determine the I/O address of ACPI/power management + * registers which are needed to read the the GPE0 register for GPI pins + * 0 - 15 on some chipsets. + */ + if (!ichx_priv.desc->uses_gpe0) + goto init; + + res_pm = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPE0); + if (!res_pm) { + pr_warn("ACPI BAR is unavailable, GPI 0 - 15 unavailable\n"); + goto init; + } + + if (!devm_request_region(&pdev->dev, res_pm->start, + resource_size(res_pm), pdev->name)) { + pr_warn("ACPI BAR is busy, GPI 0 - 15 unavailable\n"); + goto init; + } + + ichx_priv.pm_base = res_pm; + +init: + ichx_gpiolib_setup(&ichx_priv.chip); + err = gpiochip_add_data(&ichx_priv.chip, NULL); + if (err) { + pr_err("Failed to register GPIOs\n"); + return err; + } + + pr_info("GPIO from %d to %d on %s\n", ichx_priv.chip.base, + ichx_priv.chip.base + ichx_priv.chip.ngpio - 1, DRV_NAME); + + return 0; +} + +static int ichx_gpio_remove(struct platform_device *pdev) +{ + gpiochip_remove(&ichx_priv.chip); + + return 0; +} + +static struct platform_driver ichx_gpio_driver = { + .driver = { + .name = DRV_NAME, + }, + .probe = ichx_gpio_probe, + .remove = ichx_gpio_remove, +}; + +module_platform_driver(ichx_gpio_driver); + +MODULE_AUTHOR("Peter Tyser "); +MODULE_DESCRIPTION("GPIO interface for Intel ICH series"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:"DRV_NAME); diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/i2c-gpio.c b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/i2c-gpio.c new file mode 100644 index 000000000000..9b4aa7ec9e6c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/i2c-gpio.c @@ -0,0 +1,290 @@ +/* + * Bitbanging I2C bus driver using the GPIO API + * + * Copyright (C) 2007 Atmel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct i2c_gpio_private_data { + struct i2c_adapter adap; + struct i2c_algo_bit_data bit_data; + struct i2c_gpio_platform_data pdata; +}; + +/* Toggle SDA by changing the direction of the pin */ +static void i2c_gpio_setsda_dir(void *data, int state) +{ + struct i2c_gpio_platform_data *pdata = data; + + if (state) + gpio_direction_input(pdata->sda_pin); + else + gpio_direction_output(pdata->sda_pin, 0); +} + +/* + * Toggle SDA by changing the output value of the pin. This is only + * valid for pins configured as open drain (i.e. setting the value + * high effectively turns off the output driver.) + */ +static void i2c_gpio_setsda_val(void *data, int state) +{ + struct i2c_gpio_platform_data *pdata = data; + + gpio_set_value(pdata->sda_pin, state); +} + +/* Toggle SCL by changing the direction of the pin. */ +static void i2c_gpio_setscl_dir(void *data, int state) +{ + struct i2c_gpio_platform_data *pdata = data; + + if (state) + gpio_direction_input(pdata->scl_pin); + else + gpio_direction_output(pdata->scl_pin, 0); +} + +/* + * Toggle SCL by changing the output value of the pin. This is used + * for pins that are configured as open drain and for output-only + * pins. The latter case will break the i2c protocol, but it will + * often work in practice. + */ +static void i2c_gpio_setscl_val(void *data, int state) +{ + struct i2c_gpio_platform_data *pdata = data; + + gpio_set_value(pdata->scl_pin, state); +} + +static int i2c_gpio_getsda(void *data) +{ + struct i2c_gpio_platform_data *pdata = data; + + return gpio_get_value(pdata->sda_pin); +} + +static int i2c_gpio_getscl(void *data) +{ + struct i2c_gpio_platform_data *pdata = data; + + return gpio_get_value(pdata->scl_pin); +} + +static int of_i2c_gpio_get_pins(struct device_node *np, + unsigned int *sda_pin, unsigned int *scl_pin) +{ + if (of_gpio_count(np) < 2) + return -ENODEV; + + *sda_pin = of_get_gpio(np, 0); + *scl_pin = of_get_gpio(np, 1); + + if (*sda_pin == -EPROBE_DEFER || *scl_pin == -EPROBE_DEFER) + return -EPROBE_DEFER; + + if (!gpio_is_valid(*sda_pin) || !gpio_is_valid(*scl_pin)) { + pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n", + np->full_name, *sda_pin, *scl_pin); + return -ENODEV; + } + + return 0; +} + +static void of_i2c_gpio_get_props(struct device_node *np, + struct i2c_gpio_platform_data *pdata) +{ + u32 reg; + + of_property_read_u32(np, "i2c-gpio,delay-us", &pdata->udelay); + + if (!of_property_read_u32(np, "i2c-gpio,timeout-ms", ®)) + pdata->timeout = msecs_to_jiffies(reg); + + pdata->sda_is_open_drain = + of_property_read_bool(np, "i2c-gpio,sda-open-drain"); + pdata->scl_is_open_drain = + of_property_read_bool(np, "i2c-gpio,scl-open-drain"); + pdata->scl_is_output_only = + of_property_read_bool(np, "i2c-gpio,scl-output-only"); +} + +static int i2c_gpio_probe(struct platform_device *pdev) +{ + struct i2c_gpio_private_data *priv; + struct i2c_gpio_platform_data *pdata; + struct i2c_algo_bit_data *bit_data; + struct i2c_adapter *adap; + unsigned int sda_pin, scl_pin; + int ret; + + /* First get the GPIO pins; if it fails, we'll defer the probe. */ + if (pdev->dev.of_node) { + ret = of_i2c_gpio_get_pins(pdev->dev.of_node, + &sda_pin, &scl_pin); + if (ret) + return ret; + } else { + if (!dev_get_platdata(&pdev->dev)) + return -ENXIO; + pdata = dev_get_platdata(&pdev->dev); + sda_pin = pdata->sda_pin; + scl_pin = pdata->scl_pin; + } + + ret = devm_gpio_request(&pdev->dev, sda_pin, "sda"); + if (ret) { + if (ret == -EINVAL) + ret = -EPROBE_DEFER; /* Try again later */ + return ret; + } + ret = devm_gpio_request(&pdev->dev, scl_pin, "scl"); + if (ret) { + if (ret == -EINVAL) + ret = -EPROBE_DEFER; /* Try again later */ + return ret; + } + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + adap = &priv->adap; + bit_data = &priv->bit_data; + pdata = &priv->pdata; + + if (pdev->dev.of_node) { + pdata->sda_pin = sda_pin; + pdata->scl_pin = scl_pin; + of_i2c_gpio_get_props(pdev->dev.of_node, pdata); + } else { + memcpy(pdata, dev_get_platdata(&pdev->dev), sizeof(*pdata)); + } + + if (pdata->sda_is_open_drain) { + gpio_direction_output(pdata->sda_pin, 1); + bit_data->setsda = i2c_gpio_setsda_val; + } else { + gpio_direction_input(pdata->sda_pin); + bit_data->setsda = i2c_gpio_setsda_dir; + } + + if (pdata->scl_is_open_drain || pdata->scl_is_output_only) { + gpio_direction_output(pdata->scl_pin, 1); + bit_data->setscl = i2c_gpio_setscl_val; + } else { + gpio_direction_input(pdata->scl_pin); + bit_data->setscl = i2c_gpio_setscl_dir; + } + + if (!pdata->scl_is_output_only) + bit_data->getscl = i2c_gpio_getscl; + bit_data->getsda = i2c_gpio_getsda; + + if (pdata->udelay) + bit_data->udelay = pdata->udelay; + else if (pdata->scl_is_output_only) + bit_data->udelay = 50; /* 10 kHz */ + else + bit_data->udelay = 5; /* 100 kHz */ + + if (pdata->timeout) + bit_data->timeout = pdata->timeout; + else + bit_data->timeout = HZ / 10; /* 100 ms */ + + bit_data->data = pdata; + + adap->owner = THIS_MODULE; + if (pdev->dev.of_node) + strlcpy(adap->name, dev_name(&pdev->dev), sizeof(adap->name)); + else + snprintf(adap->name, sizeof(adap->name), "i2c-gpio%d", pdev->id); + + adap->algo_data = bit_data; + adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; + adap->dev.parent = &pdev->dev; + adap->dev.of_node = pdev->dev.of_node; + + adap->nr = pdev->id; + ret = i2c_bit_add_numbered_bus(adap); + if (ret) + return ret; + + platform_set_drvdata(pdev, priv); + + dev_info(&pdev->dev, "using pins %u (SDA) and %u (SCL%s)\n", + pdata->sda_pin, pdata->scl_pin, + pdata->scl_is_output_only + ? ", no clock stretching" : ""); + + return 0; +} + +static int i2c_gpio_remove(struct platform_device *pdev) +{ + struct i2c_gpio_private_data *priv; + struct i2c_adapter *adap; + + priv = platform_get_drvdata(pdev); + adap = &priv->adap; + + i2c_del_adapter(adap); + + return 0; +} + +#if defined(CONFIG_OF) +static const struct of_device_id i2c_gpio_dt_ids[] = { + { .compatible = "i2c-gpio", }, + { /* sentinel */ } +}; + +MODULE_DEVICE_TABLE(of, i2c_gpio_dt_ids); +#endif + +static struct platform_driver i2c_gpio_driver = { + .driver = { + .name = "i2c-gpio", + .of_match_table = of_match_ptr(i2c_gpio_dt_ids), + }, + .probe = i2c_gpio_probe, + .remove = i2c_gpio_remove, +}; + +static int __init i2c_gpio_init(void) +{ + int ret; + + ret = platform_driver_register(&i2c_gpio_driver); + if (ret) + printk(KERN_ERR "i2c-gpio: probe failed: %d\n", ret); + + return ret; +} +subsys_initcall(i2c_gpio_init); + +static void __exit i2c_gpio_exit(void) +{ + platform_driver_unregister(&i2c_gpio_driver); +} +module_exit(i2c_gpio_exit); + +MODULE_AUTHOR("Haavard Skinnemoen (Atmel)"); +MODULE_DESCRIPTION("Platform-independent bitbanging I2C driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:i2c-gpio"); \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/i2c-mux-pca9541.c b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/i2c-mux-pca9541.c new file mode 100644 index 000000000000..9e75d6b9140b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/i2c-mux-pca9541.c @@ -0,0 +1,355 @@ +/* + * I2C multiplexer driver for PCA9541 bus master selector + * + * Copyright (c) 2010 Ericsson AB. + * + * Author: Guenter Roeck + * + * Derived from: + * pca954x.c + * + * Copyright (c) 2008-2009 Rodolfo Giometti + * Copyright (c) 2008-2009 Eurotech S.p.A. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * The PCA9541 is a bus master selector. It supports two I2C masters connected + * to a single slave bus. + * + * Before each bus transaction, a master has to acquire bus ownership. After the + * transaction is complete, bus ownership has to be released. This fits well + * into the I2C multiplexer framework, which provides select and release + * functions for this purpose. For this reason, this driver is modeled as + * single-channel I2C bus multiplexer. + * + * This driver assumes that the two bus masters are controlled by two different + * hosts. If a single host controls both masters, platform code has to ensure + * that only one of the masters is instantiated at any given time. + */ + +#define PCA9541_CONTROL 0x01 +#define PCA9541_ISTAT 0x02 + +#define PCA9541_CTL_MYBUS (1 << 0) +#define PCA9541_CTL_NMYBUS (1 << 1) +#define PCA9541_CTL_BUSON (1 << 2) +#define PCA9541_CTL_NBUSON (1 << 3) +#define PCA9541_CTL_BUSINIT (1 << 4) +#define PCA9541_CTL_TESTON (1 << 6) +#define PCA9541_CTL_NTESTON (1 << 7) + +#define PCA9541_ISTAT_INTIN (1 << 0) +#define PCA9541_ISTAT_BUSINIT (1 << 1) +#define PCA9541_ISTAT_BUSOK (1 << 2) +#define PCA9541_ISTAT_BUSLOST (1 << 3) +#define PCA9541_ISTAT_MYTEST (1 << 6) +#define PCA9541_ISTAT_NMYTEST (1 << 7) + +#define BUSON (PCA9541_CTL_BUSON | PCA9541_CTL_NBUSON) +#define MYBUS (PCA9541_CTL_MYBUS | PCA9541_CTL_NMYBUS) +#define mybus(x) (!((x) & MYBUS) || ((x) & MYBUS) == MYBUS) +#define busoff(x) (!((x) & BUSON) || ((x) & BUSON) == BUSON) + +/* arbitration timeouts, in jiffies */ +#define ARB_TIMEOUT (HZ / 8) /* 125 ms until forcing bus ownership */ +#define ARB2_TIMEOUT (HZ / 4) /* 250 ms until acquisition failure */ + +/* arbitration retry delays, in us */ +#define SELECT_DELAY_SHORT 50 +#define SELECT_DELAY_LONG 1000 + +struct pca9541 { + struct i2c_client *client; + unsigned long select_timeout; + unsigned long arb_timeout; +}; + +static const struct i2c_device_id pca9541_id[] = { + {"pca9541", 0}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, pca9541_id); + +#ifdef CONFIG_OF +static const struct of_device_id pca9541_of_match[] = { + { .compatible = "nxp,pca9541" }, + {} +}; +MODULE_DEVICE_TABLE(of, pca9541_of_match); +#endif + +/* + * Write to chip register. Don't use i2c_transfer()/i2c_smbus_xfer() + * as they will try to lock the adapter a second time. + */ +static int pca9541_reg_write(struct i2c_client *client, u8 command, u8 val) +{ + struct i2c_adapter *adap = client->adapter; + union i2c_smbus_data data = { .byte = val }; + + return __i2c_smbus_xfer(adap, client->addr, client->flags, + I2C_SMBUS_WRITE, command, + I2C_SMBUS_BYTE_DATA, &data); +} + +/* + * Read from chip register. Don't use i2c_transfer()/i2c_smbus_xfer() + * as they will try to lock adapter a second time. + */ +static int pca9541_reg_read(struct i2c_client *client, u8 command) +{ + struct i2c_adapter *adap = client->adapter; + union i2c_smbus_data data; + int ret; + + ret = __i2c_smbus_xfer(adap, client->addr, client->flags, + I2C_SMBUS_READ, command, + I2C_SMBUS_BYTE_DATA, &data); + + return ret ?: data.byte; +} + +/* + * Arbitration management functions + */ + +/* Release bus. Also reset NTESTON and BUSINIT if it was set. */ +static void pca9541_release_bus(struct i2c_client *client) +{ + int reg; + + reg = pca9541_reg_read(client, PCA9541_CONTROL); + if (reg >= 0 && !busoff(reg) && mybus(reg)) + pca9541_reg_write(client, PCA9541_CONTROL, + (reg & PCA9541_CTL_NBUSON) >> 1); +} + +/* + * Arbitration is defined as a two-step process. A bus master can only activate + * the slave bus if it owns it; otherwise it has to request ownership first. + * This multi-step process ensures that access contention is resolved + * gracefully. + * + * Bus Ownership Other master Action + * state requested access + * ---------------------------------------------------- + * off - yes wait for arbitration timeout or + * for other master to drop request + * off no no take ownership + * off yes no turn on bus + * on yes - done + * on no - wait for arbitration timeout or + * for other master to release bus + * + * The main contention point occurs if the slave bus is off and both masters + * request ownership at the same time. In this case, one master will turn on + * the slave bus, believing that it owns it. The other master will request + * bus ownership. Result is that the bus is turned on, and master which did + * _not_ own the slave bus before ends up owning it. + */ + +/* Control commands per PCA9541 datasheet */ +static const u8 pca9541_control[16] = { + 4, 0, 1, 5, 4, 4, 5, 5, 0, 0, 1, 1, 0, 4, 5, 1 +}; + +/* + * Channel arbitration + * + * Return values: + * <0: error + * 0 : bus not acquired + * 1 : bus acquired + */ +static int pca9541_arbitrate(struct i2c_client *client) +{ + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct pca9541 *data = i2c_mux_priv(muxc); + int reg; + + reg = pca9541_reg_read(client, PCA9541_CONTROL); + if (reg < 0) + return reg; + + if (busoff(reg)) { + int istat; + /* + * Bus is off. Request ownership or turn it on unless + * other master requested ownership. + */ + istat = pca9541_reg_read(client, PCA9541_ISTAT); + if (!(istat & PCA9541_ISTAT_NMYTEST) + || time_is_before_eq_jiffies(data->arb_timeout)) { + /* + * Other master did not request ownership, + * or arbitration timeout expired. Take the bus. + */ + pca9541_reg_write(client, + PCA9541_CONTROL, + pca9541_control[reg & 0x0f] + | PCA9541_CTL_NTESTON); + data->select_timeout = SELECT_DELAY_SHORT; + } else { + /* + * Other master requested ownership. + * Set extra long timeout to give it time to acquire it. + */ + data->select_timeout = SELECT_DELAY_LONG * 2; + } + } else if (mybus(reg)) { + /* + * Bus is on, and we own it. We are done with acquisition. + * Reset NTESTON and BUSINIT, then return success. + */ + if (reg & (PCA9541_CTL_NTESTON | PCA9541_CTL_BUSINIT)) + pca9541_reg_write(client, + PCA9541_CONTROL, + reg & ~(PCA9541_CTL_NTESTON + | PCA9541_CTL_BUSINIT)); + return 1; + } else { + /* + * Other master owns the bus. + * If arbitration timeout has expired, force ownership. + * Otherwise request it. + */ + data->select_timeout = SELECT_DELAY_LONG; + if (time_is_before_eq_jiffies(data->arb_timeout)) { + /* Time is up, take the bus and reset it. */ + pca9541_reg_write(client, + PCA9541_CONTROL, + pca9541_control[reg & 0x0f] + | PCA9541_CTL_BUSINIT + | PCA9541_CTL_NTESTON); + } else { + /* Request bus ownership if needed */ + if (!(reg & PCA9541_CTL_NTESTON)) + pca9541_reg_write(client, + PCA9541_CONTROL, + reg | PCA9541_CTL_NTESTON); + } + } + return 0; +} + +static int pca9541_select_chan(struct i2c_mux_core *muxc, u32 chan) +{ + struct pca9541 *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + int ret; + unsigned long timeout = jiffies + ARB2_TIMEOUT; + /* give up after this time */ + + data->arb_timeout = jiffies + ARB_TIMEOUT; + /* force bus ownership after this time */ + + do { + ret = pca9541_arbitrate(client); + if (ret) + return ret < 0 ? ret : 0; + + if (data->select_timeout == SELECT_DELAY_SHORT) + udelay(data->select_timeout); + else + msleep(data->select_timeout / 1000); + } while (time_is_after_eq_jiffies(timeout)); + + return -ETIMEDOUT; +} + +static int pca9541_release_chan(struct i2c_mux_core *muxc, u32 chan) +{ + struct pca9541 *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + + pca9541_release_bus(client); + return 0; +} + +/* + * I2C init/probing/exit functions + */ +static int pca9541_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adap = client->adapter; + struct pca954x_platform_data *pdata = dev_get_platdata(&client->dev); + struct i2c_mux_core *muxc; + struct pca9541 *data; + int force; + int ret; + + if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE_DATA)) + return -ENODEV; + + /* + * I2C accesses are unprotected here. + * We have to lock the I2C segment before releasing the bus. + */ + i2c_lock_bus(adap, I2C_LOCK_SEGMENT); + pca9541_release_bus(client); + i2c_unlock_bus(adap, I2C_LOCK_SEGMENT); + + /* Create mux adapter */ + + force = 0; + if (pdata) + force = pdata->modes[0].adap_id; + muxc = i2c_mux_alloc(adap, &client->dev, 1, sizeof(*data), + I2C_MUX_ARBITRATOR, + pca9541_select_chan, pca9541_release_chan); + if (!muxc) + return -ENOMEM; + + data = i2c_mux_priv(muxc); + data->client = client; + + i2c_set_clientdata(client, muxc); + + ret = i2c_mux_add_adapter(muxc, force, 0, 0); + if (ret) + return ret; + + dev_info(&client->dev, "registered master selector for I2C %s\n", + client->name); + + return 0; +} + +static int pca9541_remove(struct i2c_client *client) +{ + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + + i2c_mux_del_adapters(muxc); + return 0; +} + +static struct i2c_driver pca9541_driver = { + .driver = { + .name = "pca9541", + .of_match_table = of_match_ptr(pca9541_of_match), + }, + .probe = pca9541_probe, + .remove = pca9541_remove, + .id_table = pca9541_id, +}; + +module_i2c_driver(pca9541_driver); + +MODULE_AUTHOR("Guenter Roeck "); +MODULE_DESCRIPTION("PCA9541 I2C master selector driver"); +MODULE_LICENSE("GPL v2"); diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_cpld.c b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_cpld.c new file mode 100644 index 000000000000..883c8b7b00e9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_cpld.c @@ -0,0 +1,1571 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define USE_SMBUS 1 +#define CPLD_POLLING_PERIOD 1000 +#define ENABLE_SIMULATE 0 +#define ENABLE_AUTOFAN 1 + +#define CPLD2_ADDRESS 0x33 +static struct i2c_client *client2; +static u8 hasCPLD2 = 1; + +#if ENABLE_SIMULATE + u8 sim_register[0x90]; +#endif + +/* definition */ +#define CPLD_INFO_OFFSET 0x00 +#define CPLD_BIOSCS_OFFSET 0x04 +#define CPLD_CTL_OFFSET 0x0C +#define CPLD_LED_OFFSET 0x2E +#define CPLD_INT_OFFSET 0x30 +#define CPLD_INTMASK_OFFSET 0x31 +#define CPLD_INT2_OFFSET 0x32 +#define CPLD_INTMASK2_OFFSET 0x33 +#define CPLD_PSU_OFFSET 0x40 +#define CPLD_POWERSTATUS_OFFSET 0x41 +#define CPLD_PWM_OFFSET 0x50 +#define CPLD_RPM_OFFSET 0x55 +#define CPLD_FANSTATUS_OFFSET 0x69 +#define CPLD_FANLED_OFFSET 0x6B +#define CPLD_RESETBUTTONSTATUS_OFFSET 0x75 +#define CPLD_RSTCAUSE_OFFSET 0x76 +#define CPLD_WATCHDOGCOUNTER_OFFSET 0x77 +#define CPLD_WATCHDOGCONFIG_OFFSET 0x78 +#define CPLD_WATCHDOGENABLE_OFFSET 0x79 +#define CPLD_PANICCODE_OFFSET 0x7E +#define FAN_NUM 5 +#define PWM_MIN 30 +#define PWM_DEFAULT 150 + +/* Each client has this additional data */ +struct cpld_data { + struct device *hwmon_dev; + struct mutex update_lock; + struct task_struct *cpld_thread; + u8 diag; + u8 model; + u8 fan_direction; + u8 operation_command; + u8 stack_mode; +}; + +/*-----------------------------------------------------------------------*/ +static ssize_t cpld_i2c_read(struct i2c_client *client, u8 *buf, u8 offset, size_t count) +{ +#if ENABLE_SIMULATE + memcpy(buf,&sim_register[offset],count); + return count; +#else +#if USE_SMBUS + int i; + + for(i=0; iaddr; + msg[0].buf = msgbuf; + msg[0].len = 1; + + msg[1].addr = client->addr; + msg[1].flags = I2C_M_RD; + msg[1].buf = buf; + msg[1].len = count; + + status = i2c_transfer(client->adapter, msg, 2); + + if(status == 2) + status = count; + + return status; +#endif +#endif +} + +static ssize_t cpld_i2c_write(struct i2c_client *client, char *buf, unsigned offset, size_t count) +{ +#if ENABLE_SIMULATE + memcpy(&sim_register[offset],buf,count); + return count; +#else +#if USE_SMBUS + int i; + + for(i=0; iaddr; + msg.flags = 0; + + /* msg.buf is u8 and casts will mask the values */ + msg.buf = writebuf; + + msg.buf[i++] = offset; + memcpy(&msg.buf[i], buf, count); + msg.len = i + count; + + status = i2c_transfer(client->adapter, &msg, 1); + if (status == 1) + status = count; + + return status; +#endif +#endif +} + +/*-----------------------------------------------------------------------*/ +/* sysfs attributes for hwmon */ + +static char* model_str[] = { + "10GBaseT", //0 + "SFP", //1 +}; + +static char* fandirection_str[] = { + "Rear-to-Front", //0 + "Front-to-Rear", //1 +}; + +static ssize_t show_info(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte[4] = {0,0,0,0}; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client, byte, CPLD_INFO_OFFSET, 4); + mutex_unlock(&data->update_lock); + + sprintf (buf, "The CPLD release date is %02d/%02d/%d.\n", + byte[2] & 0xf, (byte[3] & 0x1f), 2014+(byte[2] >> 4)); /* mm/dd/yyyy*/ + sprintf (buf, "%sThe Model is %s %s\n", buf, model_str[(byte[0]>>5) & 0x01],fandirection_str[(byte[0]>>7) & 0x01]); + sprintf (buf, "%sThe PCB version is %X\n", buf, byte[0]&0xf); + sprintf (buf, "%sThe CPLD version is %d.%d\n", buf, byte[1]>>4, byte[1]&0xf); + + if(hasCPLD2) { + mutex_lock(&data->update_lock); + cpld_i2c_read(client2, byte, CPLD_INFO_OFFSET, 4); + mutex_unlock(&data->update_lock); + + sprintf (buf, "%s\nThe CPLD2 release date is %02d/%02d/%d.\n", buf, + byte[2] & 0xf, (byte[3] & 0x1f), 2014+(byte[2] >> 4)); /* mm/dd/yyyy*/ + sprintf (buf, "%sThe CPLD2 version is %d.%d\n", buf, byte[1]>>4, byte[1]&0xf); + } + + return strlen(buf); +} + +static char* powerstatus_str[] = { + "Failed", //0 + "Good", //1 +}; + +static ssize_t show_powerstatus(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte[2] = {0,0}; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client2, byte, CPLD_POWERSTATUS_OFFSET, 2); + mutex_unlock(&data->update_lock); + + sprintf (buf, "PGD_P5V: %s\n", powerstatus_str[(byte[0]>>7) & 0x01]); + sprintf (buf, "%sPGD_P3V3_STBY: %s\n", buf, powerstatus_str[(byte[0]>>6) & 0x01]); + //if(data->model==0) sprintf (buf, "%sPGD_P1V88: %s\n", buf, powerstatus_str[(byte[0]>>5) & 0x01]); + sprintf (buf, "%sPGD_P1V8_A: %s\n", buf, powerstatus_str[(byte[0]>>4) & 0x01]); + sprintf (buf, "%sPGD_P3V3_SYS: %s\n", buf, powerstatus_str[(byte[0]>>3) & 0x01]); + sprintf (buf, "%sPGD_P3V3_A: %s\n", buf, powerstatus_str[(byte[0]>>2) & 0x01]); + sprintf (buf, "%sPGD_P3V3_B: %s\n", buf, powerstatus_str[(byte[0]>>1) & 0x01]); + sprintf (buf, "%sPGD_P1V2: %s\n", buf, powerstatus_str[(byte[0]>>0) & 0x01]); + sprintf (buf, "%sPGD_P0V8_A: %s\n", buf,powerstatus_str[(byte[1]>>7) & 0x01]); + sprintf (buf, "%sPGD_P0V89_ROV: %s\n", buf, powerstatus_str[(byte[1]>>6) & 0x01]); + //if(data->model==0) sprintf (buf, "%sPGD_P1V0_A: %s\n", buf, powerstatus_str[(byte[1]>>5) & 0x01]); + //if(data->model==0) sprintf (buf, "%sPGD_P1V0_B: %s\n", buf, powerstatus_str[(byte[1]>>4) & 0x01]); + sprintf (buf, "%sSW_PWR_READY: %s\n", buf, powerstatus_str[(byte[1]>>3) & 0x01]); + //sprintf (buf, "%sCORE_PWRGD_TO_CPLD: %s\n", buf, powerstatus_str[(byte[1]>>2) & 0x01]); + //sprintf (buf, "%sCPU_STBY_PWROK: %s\n", buf, powerstatus_str[(byte[1]>>1) & 0x01]); + sprintf (buf, "%sPGD_P1V8_A_STBY: %s\n", buf, powerstatus_str[(byte[1]>>0) & 0x01]); + + return strlen(buf); +} + +static ssize_t show_diag(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + return sprintf (buf, "%d\n", data->diag); +} + +static ssize_t set_diag(struct device *dev, + struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 diag = simple_strtol(buf, NULL, 10); + data->diag = diag?1:0; + return count; +} + +static char* stackmode_str[] = { + "Non-Stack member", //0 + "Stack Master", //1 + "Stack Backup/Member", //2 + "Stack Error", //3 +}; + +static ssize_t show_stackmode(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + return sprintf (buf, "%d: %s\n", data->stack_mode,stackmode_str[data->stack_mode]); +} + +static ssize_t set_stackmode(struct device *dev, + struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 stackmode = simple_strtol(buf, NULL, 10); + + if(stackmode<4) data->stack_mode = stackmode; + + return count; +} + +static char* resetbutton_str[] = { + "No press", //0 + "Reserved", //1 + "Press and hold <5s", //2 + "Press and hold >5s", //3 +}; + +static ssize_t show_resetbuttonstatus(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte = 0; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client, &byte, CPLD_RESETBUTTONSTATUS_OFFSET, 1); + mutex_unlock(&data->update_lock); + byte &=0x03; + + return sprintf (buf, "0x%02X:%s\n", byte,resetbutton_str[byte]); +} + +static char* resetcause_str[] = { + "Power-On", //0 + "Watchdog", //1 + "SoftwareReboot", //2 + "ResetButton", //3 + "Panic", //4 + "ThermalTrip" //5 +}; + +static ssize_t show_resetcause(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte = 0; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client, &byte, CPLD_RSTCAUSE_OFFSET, 1); + mutex_unlock(&data->update_lock); + + sprintf (buf, "0x%02X:", byte); + if(byte==0) sprintf (buf, "%sNone",buf); + if(byte&0x01) sprintf (buf, "%s%s ",buf,resetcause_str[0]); + if(byte&0x02) sprintf (buf, "%s%s ",buf,resetcause_str[1]); + if(byte&0x04) sprintf (buf, "%s%s ",buf,resetcause_str[2]); + if(byte&0x08) sprintf (buf, "%s%s ",buf,resetcause_str[3]); + if(byte&0x10) sprintf (buf, "%s%s ",buf,resetcause_str[4]); + if(byte&0x20) sprintf (buf, "%s%s ",buf,resetcause_str[5]); + return sprintf (buf, "%s\n", buf); +} + +static ssize_t set_resetcause(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte = 0; + + mutex_lock(&data->update_lock); + cpld_i2c_write(client, &byte, CPLD_RSTCAUSE_OFFSET, 1); + mutex_unlock(&data->update_lock); + + return count; +} + +static char* interrupt_str[] = { + "PCIE_INTR_L", //0 + "EXT_USB_OC_N", //1 + "PS2_ALERT_N", //2 + "PS1_ALERT_N", //3 + "PLD_SEN5_ALERT_N", //4 + "PLD_SEN4_ALERT_N", //5 + "PLD_SEN3_ALERT_N", //6 + "UCD90160_TEMP_INT_N", //7 + "RSTBTN_INT_N", //8 + "WDT_IRQ_N", //9 + "RSTBTN_5s_INT_N", //10 + "Reserved" //11 +}; + +static ssize_t show_interrupt(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte[4] = {0,0,0,0}; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client, byte, CPLD_INT_OFFSET, 4); + mutex_unlock(&data->update_lock); + + sprintf (buf, "0x%02X 0x%02X:", byte[0],byte[2]); + if(byte[0]==0xff && byte[2]==0x07) sprintf (buf, "%sNone",buf); + if(!(byte[0]&0x01)) sprintf (buf, "%s%s ",buf,interrupt_str[0]); + if(!(byte[0]&0x02)) sprintf (buf, "%s%s ",buf,interrupt_str[1]); + //if(!(byte[0]&0x04)) sprintf (buf, "%s%s ",buf,interrupt_str[2]); + //if(!(byte[0]&0x08)) sprintf (buf, "%s%s ",buf,interrupt_str[3]); + if(!(byte[0]&0x10)) sprintf (buf, "%s%s ",buf,interrupt_str[4]); + if(!(byte[0]&0x20)) sprintf (buf, "%s%s ",buf,interrupt_str[5]); + if(!(byte[0]&0x40)) sprintf (buf, "%s%s ",buf,interrupt_str[6]); + if(!(byte[0]&0x80)) sprintf (buf, "%s%s ",buf,interrupt_str[7]); + if(!(byte[2]&0x01)) sprintf (buf, "%s%s%s ",buf,interrupt_str[8] ,(byte[3]&0x01)?"(Blocked)":""); + if(!(byte[2]&0x02)) sprintf (buf, "%s%s%s ",buf,interrupt_str[9] ,(byte[3]&0x02)?"(Blocked)":""); + if(!(byte[2]&0x04)) sprintf (buf, "%s%s%s ",buf,interrupt_str[10],(byte[3]&0x04)?"(Blocked)":""); + + return sprintf (buf, "%s\n", buf); +} + +static ssize_t show_operationcommand(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + return sprintf (buf, "%d\n", data->operation_command); +} + +static ssize_t set_operationcommand(struct device *dev, + struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 operationcommand = simple_strtol(buf, NULL, 10); + + data->operation_command = operationcommand?1:0; + + return count; +} + +static char* bios_str[] = { + "BIOS1", //0 + "BIOS2", //1 +}; + +static ssize_t show_bios_cs(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte = 0; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client, &byte, CPLD_BIOSCS_OFFSET, 1); + mutex_unlock(&data->update_lock); + + byte &= 0x01; + + return sprintf (buf, "%d:%s\n", byte,bios_str[byte]); +} + +static ssize_t set_bios_cs(struct device *dev, + struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte = 0; + u8 temp = simple_strtol(buf, NULL, 10); + + mutex_lock(&data->update_lock); + cpld_i2c_read(client, &byte, CPLD_BIOSCS_OFFSET, 1); + if(temp) byte |= 0x01; else byte &= ~(0x01); + cpld_i2c_write(client, &byte, CPLD_BIOSCS_OFFSET, 1); + mutex_unlock(&data->update_lock); + + return count; +} + +static char* led_str[] = { + "OFF", //000 + "ON", //001 + "1 Hz", //010 + "2 Hz", //011 +}; + +static ssize_t show_led(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte = 0; + int shift = attr->index; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client, &byte, CPLD_LED_OFFSET, 1); + mutex_unlock(&data->update_lock); + byte = (byte >> shift) & 0x3; + + return sprintf (buf, "%d: %s\n", byte, led_str[byte]); +} + +static ssize_t set_led(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + + u8 temp = simple_strtol(buf, NULL, 16); + u8 byte = 0; + int shift = attr->index; + temp &= 0x3; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client, &byte, CPLD_LED_OFFSET, 1); + byte &= ~(0x3<update_lock); + + return count; +} + +static char* psu_str[] = { + "unpowered", //00 + "normal", //01 + "not installed", //10 + "not installed", //11 +}; + +static ssize_t show_psu(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte=0; + int shift = (attr->index == 0)?0:4; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client2, &byte, CPLD_PSU_OFFSET, 1); + mutex_unlock(&data->update_lock); + byte = (byte >> shift) & 0x3; + + return sprintf (buf, "%d:%s\n", byte, psu_str[byte]); +} + +static ssize_t show_pwm(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte=0; + u8 offset = attr->index + CPLD_PWM_OFFSET; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client2, &byte, offset, 1); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", byte); +} + +static ssize_t set_pwm(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 offset = attr->index + CPLD_PWM_OFFSET; + u8 byte = simple_strtol(buf, NULL, 10); + + mutex_lock(&data->update_lock); + cpld_i2c_write(client2, &byte, offset, 1); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t show_rpm(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 offset = attr->index*2 + CPLD_RPM_OFFSET; + u8 byte[2] = {0,0}; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client2, byte, offset, 2); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", (byte[0]<<8 | byte[1])); +} + +static char* fantype_str[] = { + "Normal Type", //00 + "REVERSAL Type", //01 + "UNPLUGGED", //10 + "UNPLUGGED", //11 +}; + +static ssize_t show_fantype(struct device *dev, struct device_attribute *da, + char *buf) +{ + int status; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 offset = CPLD_FANSTATUS_OFFSET; + u8 byte[2] = {0,0}; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client2, byte, offset, 2); + mutex_unlock(&data->update_lock); + status = (((byte[0] >> attr->index) & 0x01)) | (((byte[1] >> attr->index) & 0x01)<<1); + + return sprintf(buf, "%d:%s\n",status,fantype_str[status]); +} + +static char* fanled_str[] = { + "None", //00 + "Green", //01 + "Red", //10 + "Both", //11 +}; + +static ssize_t show_fanled(struct device *dev, struct device_attribute *da, + char *buf) +{ + int status; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte[2] = {0,0}; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client2, byte, CPLD_FANLED_OFFSET, 2); + mutex_unlock(&data->update_lock); + status = (((byte[0] >> attr->index) & 0x01)) | (((byte[1] >> attr->index) & 0x01)<<1); + + return sprintf(buf, "%d:%s\n",status,fanled_str[status]); +} + +static ssize_t set_fanled(struct device *dev, + struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte[2] = {0,0}; + u8 temp = simple_strtol(buf, NULL, 16); + int shift = attr->index; + + temp &= 0x3; + mutex_lock(&data->update_lock); + cpld_i2c_read(client2, byte, CPLD_FANLED_OFFSET, 2); + byte[0] &= ~(1<> 1) & 0x01)<update_lock); + + return count; +} + +static ssize_t set_watchdog_feed(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte=0; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client, &byte, CPLD_WATCHDOGENABLE_OFFSET, 1); + byte |= 0x02; + cpld_i2c_write(client, &byte, CPLD_WATCHDOGENABLE_OFFSET, 1); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t set_watchdog_enable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte=0x03; + + mutex_lock(&data->update_lock); + cpld_i2c_write(client, &byte, CPLD_WATCHDOGENABLE_OFFSET, 1); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t show_watchdog_enable(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte=0; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client, &byte, CPLD_WATCHDOGENABLE_OFFSET, 1); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n",(byte&0x01)); +} + +static ssize_t set_watchdog_config(struct device *dev, + struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte = simple_strtol(buf, NULL, 10); + + if (byte<6) byte=6; + mutex_lock(&data->update_lock); + cpld_i2c_write(client, &byte, CPLD_WATCHDOGCONFIG_OFFSET, 1); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t show_watchdog_config(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte=0; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client, &byte, CPLD_WATCHDOGCONFIG_OFFSET, 1); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d seconds\n",byte); +} + +static ssize_t show_watchdog_counter(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte=0; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client, &byte, CPLD_WATCHDOGCOUNTER_OFFSET, 1); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d seconds\n",byte); +} + +static ssize_t show_paniccode(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte = 0; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client, &byte, CPLD_PANICCODE_OFFSET, 1); + mutex_unlock(&data->update_lock); + + return sprintf (buf, "0x%02X\n", byte); +} + +#if ENABLE_SIMULATE +static ssize_t show_simdump(struct device *dev, struct device_attribute *da, + char *buf) +{ + u8 i, j; + sprintf(buf,"usage: echo 0xAABB > sim_buffer (AA is address, BB is value)\n\n"); + sprintf(buf,"%s 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n",buf); + sprintf(buf,"%s======================================================\n",buf); + sprintf(buf,"%s0000: ",buf); + for (j = 0, i = 0; j < sizeof(sim_register); j++, i++) + { + sprintf(buf,"%s%02x ", buf, (int)sim_register[i]); + if ((i & 0x0F) == 0x0F) sprintf(buf,"%s\n%04x: ", buf, (i+1)); + } + return sprintf(buf,"%s\n",buf); +} + +static ssize_t set_simbuffer(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + u16 byte = simple_strtol(buf, NULL, 16); + u8 address = (byte >> 8); + u8 value = (byte & 0xff); + + sim_register[address]=value; + + return count; +} +#endif +static SENSOR_DEVICE_ATTR(info, S_IRUGO, show_info, 0, 0); +static SENSOR_DEVICE_ATTR(diag, S_IWUSR|S_IRUGO, show_diag, set_diag, 0); +static SENSOR_DEVICE_ATTR(interrupt, S_IRUGO, show_interrupt, 0, 0); + +static SENSOR_DEVICE_ATTR(stacking_led, S_IWUSR|S_IRUGO, show_led, set_led, 0); +static SENSOR_DEVICE_ATTR(fan_led, S_IWUSR|S_IRUGO, show_led, set_led, 2); +static SENSOR_DEVICE_ATTR(power_led, S_IWUSR|S_IRUGO, show_led, set_led, 4); +static SENSOR_DEVICE_ATTR(service_led, S_IWUSR|S_IRUGO, show_led, set_led, 6); + +static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR|S_IRUGO, show_pwm, set_pwm, 0); +static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR|S_IRUGO, show_pwm, set_pwm, 1); +static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR|S_IRUGO, show_pwm, set_pwm, 2); +static SENSOR_DEVICE_ATTR(pwm4, S_IWUSR|S_IRUGO, show_pwm, set_pwm, 3); +static SENSOR_DEVICE_ATTR(pwm5, S_IWUSR|S_IRUGO, show_pwm, set_pwm, 4); + +static SENSOR_DEVICE_ATTR(fanmodule1_type, S_IRUGO, show_fantype, 0, 0); +static SENSOR_DEVICE_ATTR(fanmodule2_type, S_IRUGO, show_fantype, 0, 1); +static SENSOR_DEVICE_ATTR(fanmodule3_type, S_IRUGO, show_fantype, 0, 2); +static SENSOR_DEVICE_ATTR(fanmodule4_type, S_IRUGO, show_fantype, 0, 3); +static SENSOR_DEVICE_ATTR(fanmodule5_type, S_IRUGO, show_fantype, 0, 4); + +static SENSOR_DEVICE_ATTR(fanmodule1_led, S_IWUSR|S_IRUGO, show_fanled, set_fanled, 0); +static SENSOR_DEVICE_ATTR(fanmodule2_led, S_IWUSR|S_IRUGO, show_fanled, set_fanled, 1); +static SENSOR_DEVICE_ATTR(fanmodule3_led, S_IWUSR|S_IRUGO, show_fanled, set_fanled, 2); +static SENSOR_DEVICE_ATTR(fanmodule4_led, S_IWUSR|S_IRUGO, show_fanled, set_fanled, 3); +static SENSOR_DEVICE_ATTR(fanmodule5_led, S_IWUSR|S_IRUGO, show_fanled, set_fanled, 4); + +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_rpm, 0, 0); +static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_rpm, 0, 1); +static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_rpm, 0, 2); +static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_rpm, 0, 3); +static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, show_rpm, 0, 4); +static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, show_rpm, 0, 5); +static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO, show_rpm, 0, 6); +static SENSOR_DEVICE_ATTR(fan8_input, S_IRUGO, show_rpm, 0, 7); +static SENSOR_DEVICE_ATTR(fan9_input, S_IRUGO, show_rpm, 0, 8); +static SENSOR_DEVICE_ATTR(fan10_input,S_IRUGO, show_rpm, 0, 9); + +static SENSOR_DEVICE_ATTR(psu1, S_IRUGO, show_psu, 0, 0); +static SENSOR_DEVICE_ATTR(psu2, S_IRUGO, show_psu, 0, 1); +static SENSOR_DEVICE_ATTR(power_status, S_IRUGO, show_powerstatus, 0, 0); +static SENSOR_DEVICE_ATTR(reset_cause, S_IWUSR|S_IRUGO, show_resetcause, set_resetcause, 0); +static SENSOR_DEVICE_ATTR(resetbutton_status, S_IRUGO, show_resetbuttonstatus, 0, 0); +static SENSOR_DEVICE_ATTR(panic_code, S_IRUGO, show_paniccode, 0, 0); + +static SENSOR_DEVICE_ATTR(watchdog_feed, S_IWUSR, 0, set_watchdog_feed, 0); +static SENSOR_DEVICE_ATTR(watchdog_enable, S_IWUSR|S_IRUGO, show_watchdog_enable, set_watchdog_enable, 0); +static SENSOR_DEVICE_ATTR(watchdog_config, S_IWUSR|S_IRUGO, show_watchdog_config, set_watchdog_config, 0); +static SENSOR_DEVICE_ATTR(watchdog_counter, S_IRUGO, show_watchdog_counter, 0, 0); + +static SENSOR_DEVICE_ATTR(stack_mode, S_IWUSR|S_IRUGO, show_stackmode, set_stackmode, 0); +static SENSOR_DEVICE_ATTR(operation_command, S_IWUSR|S_IRUGO, show_operationcommand, set_operationcommand, 0); +#if ENABLE_SIMULATE + static SENSOR_DEVICE_ATTR(sim_buffer, S_IWUSR|S_IRUGO, show_simdump, set_simbuffer, 0); +#endif +static SENSOR_DEVICE_ATTR(bios_cs, S_IWUSR|S_IRUGO, show_bios_cs, set_bios_cs, 0); + +static struct attribute *cpld_attributes[] = { + &sensor_dev_attr_info.dev_attr.attr, + &sensor_dev_attr_diag.dev_attr.attr, + + &sensor_dev_attr_stacking_led.dev_attr.attr, + &sensor_dev_attr_fan_led.dev_attr.attr, + &sensor_dev_attr_power_led.dev_attr.attr, + &sensor_dev_attr_service_led.dev_attr.attr, + + &sensor_dev_attr_interrupt.dev_attr.attr, + + &sensor_dev_attr_psu1.dev_attr.attr, + &sensor_dev_attr_psu2.dev_attr.attr, + &sensor_dev_attr_power_status.dev_attr.attr, + &sensor_dev_attr_reset_cause.dev_attr.attr, + &sensor_dev_attr_resetbutton_status.dev_attr.attr, + &sensor_dev_attr_panic_code.dev_attr.attr, + + &sensor_dev_attr_pwm1.dev_attr.attr, + &sensor_dev_attr_pwm2.dev_attr.attr, + &sensor_dev_attr_pwm3.dev_attr.attr, + &sensor_dev_attr_pwm4.dev_attr.attr, + &sensor_dev_attr_pwm5.dev_attr.attr, + + &sensor_dev_attr_fanmodule1_type.dev_attr.attr, + &sensor_dev_attr_fanmodule2_type.dev_attr.attr, + &sensor_dev_attr_fanmodule3_type.dev_attr.attr, + &sensor_dev_attr_fanmodule4_type.dev_attr.attr, + &sensor_dev_attr_fanmodule5_type.dev_attr.attr, + + &sensor_dev_attr_fanmodule1_led.dev_attr.attr, + &sensor_dev_attr_fanmodule2_led.dev_attr.attr, + &sensor_dev_attr_fanmodule3_led.dev_attr.attr, + &sensor_dev_attr_fanmodule4_led.dev_attr.attr, + &sensor_dev_attr_fanmodule5_led.dev_attr.attr, + + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan2_input.dev_attr.attr, + &sensor_dev_attr_fan3_input.dev_attr.attr, + &sensor_dev_attr_fan4_input.dev_attr.attr, + &sensor_dev_attr_fan5_input.dev_attr.attr, + &sensor_dev_attr_fan6_input.dev_attr.attr, + &sensor_dev_attr_fan7_input.dev_attr.attr, + &sensor_dev_attr_fan8_input.dev_attr.attr, + &sensor_dev_attr_fan9_input.dev_attr.attr, + &sensor_dev_attr_fan10_input.dev_attr.attr, + + &sensor_dev_attr_watchdog_feed.dev_attr.attr, + &sensor_dev_attr_watchdog_enable.dev_attr.attr, + &sensor_dev_attr_watchdog_config.dev_attr.attr, + &sensor_dev_attr_watchdog_counter.dev_attr.attr, + + &sensor_dev_attr_stack_mode.dev_attr.attr, + &sensor_dev_attr_operation_command.dev_attr.attr, + + &sensor_dev_attr_bios_cs.dev_attr.attr, +#if ENABLE_SIMULATE + &sensor_dev_attr_sim_buffer.dev_attr.attr, +#endif + NULL +}; + +struct i2c_client *client_notifier; + +static const struct attribute_group cpld_group = { + .attrs = cpld_attributes, +}; + +static int log_reboot_to_cpld (struct notifier_block *self, unsigned long event, void *ptr) +{ + u8 byte=0; + if (event == SYS_DOWN || event == SYS_HALT) + { + cpld_i2c_read(client_notifier, &byte, CPLD_RSTCAUSE_OFFSET, 1); + byte |= 0x04; + cpld_i2c_write(client_notifier, &byte, CPLD_RSTCAUSE_OFFSET, 1); + } + return NOTIFY_DONE; +} + +static int log_panic_to_cpld(struct notifier_block *self, unsigned long event, void *ptr) +{ +#if 1 +// Can't use SMBus if smp is stopped (need patch the panic.c) + if (client_notifier != NULL) + { + u8 byte=0; + cpld_i2c_read(client_notifier, &byte, CPLD_RSTCAUSE_OFFSET, 1); + byte |= 0x10; + cpld_i2c_write(client_notifier, &byte, CPLD_RSTCAUSE_OFFSET, 1); + } +#endif + return NOTIFY_DONE; +} + +static struct notifier_block reboot_notifier = { + .notifier_call = log_reboot_to_cpld, +}; + +static struct notifier_block panic_notifier = { + .notifier_call = log_panic_to_cpld, +}; + +#if ENABLE_AUTOFAN +#define SWITCH_ADDRESS 3-004e +#define ENV_ADDRESS 3-004a +#define CPU_ADDRESS 3-0048 +#define PSU1_ADDRESS 2-0058 +#define PSU2_ADDRESS 2-0059 +#define PSU1_ADDRESS_DVT 2-005a +#define PSU2_ADDRESS_DVT 2-005b + +#define _STR(s) #s +#define __STR(s) _STR(s) +#define __File_input(__file) __STR(/sys/bus/i2c/devices/__file/hwmon/hwmon%d/temp1_input) +#define __File_max(__file) __STR(/sys/bus/i2c/devices/__file/hwmon/hwmon%d/temp1_max) +#define __File_max_hyst(__file) __STR(/sys/bus/i2c/devices/__file/hwmon/hwmon%d/temp1_max_hyst) +#define __File_pwm(__file) __STR(/sys/bus/i2c/devices/__file/hwmon/hwmon%d/pwm1) + +#define SWITCH_TEMPERATURE __File_input(SWITCH_ADDRESS) +#define ENV_TEMPERATURE __File_input(ENV_ADDRESS) +#define CPU_TEMPERATURE __File_input(CPU_ADDRESS) +#define SWITCH_MAX __File_max(SWITCH_ADDRESS) +#define ENV_MAX __File_max(ENV_ADDRESS) +#define CPU_MAX __File_max(CPU_ADDRESS) +#define SWITCH_MAX_HYST __File_max_hyst(SWITCH_ADDRESS) +#define ENV_MAX_HYST __File_max_hyst(ENV_ADDRESS) +#define CPU_MAX_HYST __File_max_hyst(CPU_ADDRESS) +#define PSU1_PWM __File_pwm(PSU1_ADDRESS) +#define PSU2_PWM __File_pwm(PSU2_ADDRESS) +#define PSU1_PWM_DVT __File_pwm(PSU1_ADDRESS_DVT) +#define PSU2_PWM_DVT __File_pwm(PSU2_ADDRESS_DVT) + +#define n_entries 9 +#define temp_hysteresis 2 +#define MAX_HWMON 9 + +//[Model:10G/SFP][FanDirection:R2F/F2R][Type:CPU/ASIC/ENV] +u8 Thermaltrip[2][2][3] ={{{64,68,64},{64,68,64}},{{64,68,64},{64,68,64}}}; +u8 FanTable[2][2][3][n_entries][2]={ +{//10GBastT + {//Rear-to-Front + {//CPU + { 45, 255 }, \ + { 40, 201 }, \ + { 38, 170 }, \ + { 35, 130 }, \ + { 31, 105 }, \ + { 27, 85 }, \ + { 24, 80 }, \ + { 20, 70 }, \ + { 18, 65 } + } + ,{//ASIC + { 52, 255 }, \ + { 47, 201 }, \ + { 44, 170 }, \ + { 42, 130 }, \ + { 39, 105 }, \ + { 36, 85 }, \ + { 33, 80 }, \ + { 30, 70 }, \ + { 28, 65 } + } + ,{//ENV + { 47, 255 }, \ + { 43, 201 }, \ + { 41, 170 }, \ + { 39, 130 }, \ + { 36, 105 }, \ + { 32, 85 }, \ + { 30, 80 }, \ + { 28, 70 }, \ + { 19, 65 } + } + }, + {//Front-to-Rear + {//CPU + { 45, 255 }, \ + { 40, 201 }, \ + { 38, 170 }, \ + { 35, 130 }, \ + { 31, 105 }, \ + { 27, 85 }, \ + { 24, 80 }, \ + { 20, 70 }, \ + { 18, 65 } + } + ,{//ASIC + { 52, 255 }, \ + { 47, 201 }, \ + { 44, 170 }, \ + { 42, 130 }, \ + { 39, 105 }, \ + { 36, 85 }, \ + { 33, 80 }, \ + { 30, 70 }, \ + { 28, 65 } + } + ,{//ENV + { 47, 255 }, \ + { 43, 201 }, \ + { 41, 170 }, \ + { 39, 130 }, \ + { 36, 105 }, \ + { 32, 85 }, \ + { 30, 80 }, \ + { 28, 70 }, \ + { 19, 65 } + } + }, +}, +{//SFP28 + {//Rear-to-Front + {//CPU + { 45, 255 }, \ + { 40, 201 }, \ + { 38, 170 }, \ + { 35, 130 }, \ + { 31, 105 }, \ + { 27, 85 }, \ + { 24, 80 }, \ + { 20, 70 }, \ + { 18, 65 } + } + ,{//ASIC + { 52, 255 }, \ + { 47, 201 }, \ + { 44, 170 }, \ + { 42, 130 }, \ + { 39, 105 }, \ + { 36, 85 }, \ + { 33, 80 }, \ + { 30, 70 }, \ + { 28, 65 } + } + ,{//ENV + { 47, 255 }, \ + { 43, 201 }, \ + { 41, 170 }, \ + { 39, 130 }, \ + { 36, 105 }, \ + { 32, 85 }, \ + { 30, 80 }, \ + { 28, 70 }, \ + { 19, 65 } + } + }, + {//Front-to-Rear + {//CPU + { 45, 255 }, \ + { 40, 201 }, \ + { 38, 170 }, \ + { 35, 130 }, \ + { 31, 105 }, \ + { 27, 85 }, \ + { 24, 80 }, \ + { 20, 70 }, \ + { 18, 65 } + } + ,{//ASIC + { 52, 255 }, \ + { 47, 201 }, \ + { 44, 170 }, \ + { 42, 130 }, \ + { 39, 105 }, \ + { 36, 85 }, \ + { 33, 80 }, \ + { 30, 70 }, \ + { 28, 65 } + } + ,{//ENV + { 47, 255 }, \ + { 43, 201 }, \ + { 41, 170 }, \ + { 39, 130 }, \ + { 36, 105 }, \ + { 32, 85 }, \ + { 30, 80 }, \ + { 28, 70 }, \ + { 19, 65 } + } + } +} +}; + +//type 0:CPU,1:ASIC,2:ENV +static u8 find_duty(u8 model, u8 fan_direction, u8 type, u8 temp) +{ + static u8 fantable_index[3]={n_entries-1, n_entries-1, n_entries-1}; + while(1) + { + if(fantable_index[type] >= 1 && temp > FanTable[model][fan_direction][type][fantable_index[type]-1][0]) + fantable_index[type]--; + else if(fantable_index[type] < (n_entries-1) && temp < (FanTable[model][fan_direction][type][fantable_index[type]][0]-temp_hysteresis)) + fantable_index[type]++; + else + break; + } + return FanTable[model][fan_direction][type][fantable_index[type]][1]; +} + +static u32 getvalue(char *path) +{ + static struct file *f; + mm_segment_t old_fs; + u16 temp = 0; + char temp_str[]={0,0,0,0,0,0,0,0,0}; + loff_t pos = 0; + + f = filp_open(path,O_RDONLY,0644); + if(IS_ERR(f)) return -1; + + old_fs = get_fs(); + set_fs(KERNEL_DS); + vfs_read(f, temp_str,8,&pos); + temp = simple_strtoul(temp_str,NULL,10); + filp_close(f,NULL); + set_fs(old_fs); + + if(temp<0) temp=0; + return temp; +} + +static u8 setvalue(char *path, u32 value) +{ + static struct file *f; + mm_segment_t old_fs; + char temp_str[]={0,0,0,0,0,0,0,0,0}; + u8 len=0; + loff_t pos = 0; + + f = filp_open(path,O_WRONLY,0644); + if(IS_ERR(f)) return -1; + + len = sprintf(temp_str,"%d",value); + + old_fs = get_fs(); + set_fs(KERNEL_DS); + vfs_write(f, temp_str, len, &pos); + filp_close(f,NULL); + set_fs(old_fs); + + return 0; +} + +static u8 probe_gettemp(char *path) +{ + u8 temp_path[64],i; + u32 value; + + for(i=0;imodel,data->fan_direction,0,temp_cpu); + if(temp_switch!=0xff) duty_switch=find_duty(data->model,data->fan_direction,1,temp_switch); + if(temp_env!=0xff) duty_env=find_duty(data->model,data->fan_direction,2,temp_env); + + if(temp_cpu==0xff && temp_switch==0xff && temp_env==0xff) + { + duty=PWM_DEFAULT; + } + else + { + duty=(duty>duty_cpu)?duty:duty_cpu; + duty=(duty>duty_switch)?duty:duty_switch; + duty=(duty>duty_env)?duty:duty_env; + } + + memset(fanpwm,duty,FAN_NUM); + for(i=0;i 200) + psu_duty = 80; + else if (duty <= 200 && duty > 150) + if(data->fan_direction==0) psu_duty = 70; else psu_duty = 65; + else if (duty <= 150 && duty > 100) + if(data->fan_direction==0) psu_duty = 60; else psu_duty = 55; + else + if(data->fan_direction==0) psu_duty = 50; else psu_duty = 35; + probe_setvalue(PSU1_PWM, psu_duty); + probe_setvalue(PSU2_PWM, psu_duty); + probe_setvalue(PSU1_PWM_DVT, psu_duty); + probe_setvalue(PSU2_PWM_DVT, psu_duty); + + mutex_lock(&data->update_lock); + cpld_i2c_write(client2,fanpwm,CPLD_PWM_OFFSET,FAN_NUM); + mutex_unlock(&data->update_lock); +} +#endif + +/*-----------------------------------------------------------------------*/ +static int cpld_polling(void *p) +{ + struct i2c_client *client = p; + struct cpld_data *data = i2c_get_clientdata(client); + u8 fanrpm[22],fanled[2],frontled,i; + u8 fandir=0,fanpresent=0,fanfront,fanrear,fanerror; + u8 fanfail,fanturnoff,psufail,lastStack,retry; + u8 psustatus=0; + u8 initial_thermaltrip[3] = {0,0,0}; + + while (!kthread_should_stop()) + { + //initial tmp75's thermaltrip value + if(initial_thermaltrip[0]==0) + { + if((probe_setvalue(CPU_MAX, Thermaltrip[data->model][data->fan_direction][0]*1000)!=0xff) + && (probe_setvalue(CPU_MAX_HYST, (Thermaltrip[data->model][data->fan_direction][0]-temp_hysteresis)*1000)!=0xff)) + initial_thermaltrip[0]=1; + } + if(initial_thermaltrip[1]==0) + { + if((probe_setvalue(SWITCH_MAX, Thermaltrip[data->model][data->fan_direction][1]*1000)!=0xff) + && (probe_setvalue(SWITCH_MAX_HYST, (Thermaltrip[data->model][data->fan_direction][1]-temp_hysteresis)*1000)!=0xff)) + initial_thermaltrip[1]=1; + } + if(initial_thermaltrip[2]==0) + { + if((probe_setvalue(ENV_MAX, Thermaltrip[data->model][data->fan_direction][2]*1000)!=0xff) + && (probe_setvalue(ENV_MAX_HYST, (Thermaltrip[data->model][data->fan_direction][2]-temp_hysteresis)*1000)!=0xff)) + initial_thermaltrip[2]=1; + } + + //LED control + if (data->diag==0 && i2c_smbus_read_byte_data(client, 0)>=0) + { + for(retry=0;retry<2;retry++) + { + fanfail=0; + fanled[0]=0; //clean green led + fanled[1]=0; //clean red led + fanfront=0; + fanrear=0; + fanerror=0; + fanturnoff=0; + + //------ Fan Check ------- + cpld_i2c_read(client2, fanrpm, CPLD_RPM_OFFSET, 22); + fandir=fanrpm[20]; + fanpresent=fanrpm[21]; + + //Count the fan's direction + for (i=0;i 23500) || (rpm2 < 3000 || rpm2 > 23500)) + fanerror++; + else if(fandir&(1<>i)&0x01)!=data->fan_direction) + fanled[0] |= (1<stack_mode==0) frontled&=~(0x3); //0: Non-Stack member => off + if(data->stack_mode==1) frontled|=0x2; //1: Stack Master => Flash green + if(data->stack_mode==2) frontled|=0x1; //2: Stack Backup/Member => Steady green + if(data->stack_mode==3) frontled|=lastStack;//3: Stack Error => last status + lastStack=frontled; + + if(fanpresent!=0x00) //Fan LED in bit2 bit3 + { + frontled|=(0x02<<2); //Some fan unpresent => 0x02 + } + else + { + if(fanturnoff||fanfail) //some fan no speed => 0x03 + frontled|=(0x03<<2); //some fan dir different => 0x03 + else + frontled|=(0x01<<2); //Normal => 0x01 + } + + if(psustatus&0x22) //POW LED in bit4 bit5 + frontled|=(0x02<<4); //not all psu plug-in => 0x02 + else if (psustatus!=0x11) + frontled|=(0x03<<4); //some power is not ok => 0x03 + else + frontled|=(0x01<<4); //Normal => 0x01 + + if(data->operation_command==1) //Service LED in bit6 bit7 + frontled|=(0x01<<6); //Steady if operation + else if(fanfail>0||psufail>0||data->stack_mode==3) + frontled|=(0x02<<6); //Flash if any error + else if(data->stack_mode==2) + frontled|=(0x01<<6); //Steady if mode in Stack Backup/Member + else + frontled&=~(0x3<<6); //Off if mode in Non-Stack member or Stack Master with no operation and error + cpld_i2c_write(client, &frontled, CPLD_LED_OFFSET, 1); + } + set_current_state(TASK_INTERRUPTIBLE); + if(kthread_should_stop()) break; + schedule_timeout(msecs_to_jiffies(CPLD_POLLING_PERIOD)); + } + return 0; +} + +/*-----------------------------------------------------------------------*/ +/* device probe and removal */ + +static int +cpld_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct cpld_data *data; + int status; + u8 byte[5]={PWM_DEFAULT,PWM_DEFAULT,PWM_DEFAULT,PWM_DEFAULT,PWM_DEFAULT}; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) + return -EIO; + + data = kzalloc(sizeof(struct cpld_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &cpld_group); + + if (status) + goto exit_free; + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + //Check CPLD2 exist or not + client2 = i2c_new_dummy(client->adapter, CPLD2_ADDRESS); + if(!client2) { + hasCPLD2 = 0; + client2 = client; + } else { + status = i2c_smbus_read_byte_data(client2, CPLD_INFO_OFFSET); + if(status<0) { + i2c_unregister_device(client2); + i2c_set_clientdata(client2, NULL); + hasCPLD2 = 0; + client2 = client; + } + } + + dev_info(&client->dev, "%s: sensor '%s'\n", + dev_name(data->hwmon_dev), client->name); + + //initial PWM to 60% + cpld_i2c_write(client2, byte, CPLD_PWM_OFFSET, 5); + + //Handle LED control by the driver + byte[0]=0x01; + cpld_i2c_write(client, byte, CPLD_CTL_OFFSET, 1); + cpld_i2c_write(client2, byte, CPLD_CTL_OFFSET, 1); + + //Get Model type + cpld_i2c_read(client, byte, CPLD_INFO_OFFSET, 1); + data->model = (byte[0]>>5) & 0x01; + data->fan_direction = (byte[0]>>7) & 0x01; + + //kernel panic notifier + atomic_notifier_chain_register(&panic_notifier_list, &panic_notifier); + + //soft reboot notifier + register_reboot_notifier(&reboot_notifier); + + client_notifier=client; + + data->cpld_thread = kthread_run(cpld_polling,client,"%s",dev_name(data->hwmon_dev)); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &cpld_group); +exit_free: + i2c_set_clientdata(client, NULL); + kfree(data); + return status; +} + +static int cpld_remove(struct i2c_client *client) +{ + struct cpld_data *data = i2c_get_clientdata(client); + //Return LED control to the CPLD + u8 byte=0x00; + cpld_i2c_write(client, &byte, CPLD_CTL_OFFSET, 1); + cpld_i2c_write(client2, &byte, CPLD_CTL_OFFSET, 1); + + //unregister soft reboot notifier + unregister_reboot_notifier(&reboot_notifier); + + //unregister kernel panic notifier + atomic_notifier_chain_unregister(&panic_notifier_list, &panic_notifier); + + //stop cpld thread + kthread_stop(data->cpld_thread); + + sysfs_remove_group(&client->dev.kobj, &cpld_group); + hwmon_device_unregister(data->hwmon_dev); + i2c_set_clientdata(client, NULL); + if(hasCPLD2) { + i2c_unregister_device(client2); + i2c_set_clientdata(client2, NULL); + } + + kfree(data); + return 0; +} + +static const struct i2c_device_id cpld_ids[] = { + { "inv_cpld" , 0, }, + { /* LIST END */ } +}; +MODULE_DEVICE_TABLE(i2c, cpld_ids); + +static struct i2c_driver cpld_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "inv_cpld", + }, + .probe = cpld_probe, + .remove = cpld_remove, + .id_table = cpld_ids, +}; + +/*-----------------------------------------------------------------------*/ + +/* module glue */ + +static int __init inv_cpld_init(void) +{ + return i2c_add_driver(&cpld_driver); +} + +static void __exit inv_cpld_exit(void) +{ + i2c_del_driver(&cpld_driver); +} + +MODULE_AUTHOR("jack.ting "); +MODULE_DESCRIPTION("cpld driver"); +MODULE_LICENSE("GPL"); + +module_init(inv_cpld_init); +module_exit(inv_cpld_exit); \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_eeprom.c b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_eeprom.c new file mode 100644 index 000000000000..781ef27671c1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_eeprom.c @@ -0,0 +1,180 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include + + +/* Size of EEPROM in bytes */ +#define EEPROM_SIZE 256 + +#define SLICE_BITS (6) +#define SLICE_SIZE (1 << SLICE_BITS) +#define SLICE_NUM (EEPROM_SIZE/SLICE_SIZE) + +/* Each client has this additional data */ +struct eeprom_data { + struct mutex update_lock; + u8 valid; /* bitfield, bit!=0 if slice is valid */ + unsigned long last_updated[SLICE_NUM]; /* In jiffies, 8 slices */ + u8 data[EEPROM_SIZE]; /* Register values */ +}; + + +static void inv_eeprom_update_client(struct i2c_client *client, u8 slice) +{ + struct eeprom_data *data = i2c_get_clientdata(client); + int i, j; + int ret; + int addr; + + + mutex_lock(&data->update_lock); + + if (!(data->valid & (1 << slice)) || + time_after(jiffies, data->last_updated[slice] + 300 * HZ)) { + dev_dbg(&client->dev, "Starting eeprom update, slice %u\n", slice); + + addr = slice << SLICE_BITS; + + ret = i2c_smbus_write_byte_data(client, ((u8)addr >> 8) & 0xFF, (u8)addr & 0xFF); + /* select the eeprom address */ + if (ret < 0) { + dev_err(&client->dev, "address set failed\n"); + goto exit; + } + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BYTE)) { + goto exit; + } + + for (i = slice << SLICE_BITS; i < (slice + 1) << SLICE_BITS; i+= SLICE_SIZE) { + for (j = i; j < (i+SLICE_SIZE); j++) { + int res; + + res = i2c_smbus_read_byte(client); + if (res < 0) { + goto exit; + } + + data->data[j] = res & 0xFF; + } + } + + data->last_updated[slice] = jiffies; + data->valid |= (1 << slice); + } + +exit: + mutex_unlock(&data->update_lock); +} + +static ssize_t inv_eeprom_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj)); + struct eeprom_data *data = i2c_get_clientdata(client); + u8 slice; + + + if (off > EEPROM_SIZE) { + return 0; + } + if (off + count > EEPROM_SIZE) { + count = EEPROM_SIZE - off; + } + if (count == 0) { + return 0; + } + + /* Only refresh slices which contain requested bytes */ + for (slice = off >> SLICE_BITS; slice <= (off + count - 1) >> SLICE_BITS; slice++) { + inv_eeprom_update_client(client, slice); + } + + memcpy(buf, &data->data[off], count); + + return count; +} + +static struct bin_attribute inv_eeprom_attr = { + .attr = { + .name = "eeprom", + .mode = S_IRUGO, + }, + .size = EEPROM_SIZE, + .read = inv_eeprom_read, +}; + +static int inv_eeprom_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct eeprom_data *data; + int err; + + if (!(data = kzalloc(sizeof(struct eeprom_data), GFP_KERNEL))) { + err = -ENOMEM; + goto exit; + } + + memset(data->data, 0xff, EEPROM_SIZE); + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + /* create the sysfs eeprom file */ + err = sysfs_create_bin_file(&client->dev.kobj, &inv_eeprom_attr); + if (err) { + goto exit_kfree; + } + + return 0; + +exit_kfree: + kfree(data); +exit: + return err; +} + +static int inv_eeprom_remove(struct i2c_client *client) +{ + sysfs_remove_bin_file(&client->dev.kobj, &inv_eeprom_attr); + kfree(i2c_get_clientdata(client)); + + return 0; +} + +static const struct i2c_device_id inv_eeprom_id[] = { + { "inv_eeprom", 0 }, + { } +}; + +static struct i2c_driver inv_eeprom_driver = { + .driver = { + .name = "inv_eeprom", + }, + .probe = inv_eeprom_probe, + .remove = inv_eeprom_remove, + .id_table = inv_eeprom_id, +}; + +module_i2c_driver(inv_eeprom_driver); + +MODULE_AUTHOR("Inventec"); +MODULE_DESCRIPTION("Inventec D6556 Mother Board EEPROM driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_mux.c b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_mux.c new file mode 100644 index 000000000000..40593a96eeb7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_mux.c @@ -0,0 +1,545 @@ +#include +#include +#include +#include +#include +#include +#include "io_expander.h" +#include "inv_mux.h" + +/* For build single module using (Ex: ONL platform) */ +#include +//#include +//#include + +static struct mux_obj_s *mux_head_p = NULL; + +/* ========== MUX object functions ========== + */ +static int +_setup_i2c_value(struct mux_obj_s *self, int offset, int value){ + + return i2c_smbus_write_byte_data(self->i2c_client_p, offset, value); +} + + +static int +_setup_i2c_client(struct mux_obj_s *self, int chan_id, int addr){ + + struct i2c_adapter *adap = NULL; + char *emsg = "ERR"; + + adap = i2c_get_adapter(chan_id); + if (!adap){ + emsg = "can't get adapter"; + goto err_setup_i2c_client; + } + self->i2c_client_p = kzalloc(sizeof(*self->i2c_client_p), GFP_KERNEL); + if (!self->i2c_client_p){ + emsg = "can't kzalloc client"; + goto err_setup_i2c_client; + } + self->i2c_client_p->adapter = adap; + self->i2c_client_p->addr = addr; + return 0; + +err_setup_i2c_client: + SWPS_ERR("%s: %s\n", __func__, emsg); + return ERR_MUX_UNEXCPT; +} + + +int +_common_force_pull_gpio(int mem_addr, + int input, + int bit_offset){ + + unsigned int val = 0; + unsigned int targ = 0; + + /* Get current value */ + val = inl(mem_addr); + if (val == 0) { + SWPS_ERR("%s: inl:%d fail!\n", __func__, val); + return -1; + } + /* Count target value */ + switch (input) { + case 0: /* Pull Low */ + targ = (val & (~(1 << bit_offset))); + break; + case 1: /* Pull high */ + targ = (val | (1 << bit_offset)); + break; + default: + SWPS_ERR("%s: input state:%d incorrect!\n", + __func__, input); + return -1; + } + /* Setup gpio */ + outl(targ, mem_addr); + if (targ != inl(mem_addr)){ + SWPS_ERR("%s: outl:%d fail!\n", __func__, targ); + return -1; + } + SWPS_DEBUG("%s: done.\n", __func__); + return 0; +} + + +int +rangeley_force_pull_high(struct mux_obj_s *self){ + SWPS_ERR("%s: not ready!\n", __func__); + return -1; +} + + +int +rangeley_force_pull_low(struct mux_obj_s *self){ + SWPS_ERR("%s: not ready!\n", __func__); + return -1; +} + + +int +hedera_force_pull_high(struct mux_obj_s *self){ + return _common_force_pull_gpio(MUX_RST_MEM_ADDR_HEDERA, 1, 5); +} + + +int +hedera_force_pull_low(struct mux_obj_s *self){ + return _common_force_pull_gpio(MUX_RST_MEM_ADDR_HEDERA, 0, 5); +} + + +int +normal_gpio_pull_high(struct mux_obj_s *self){ + return gpio_direction_output(self->gpio_num, 1); +} + + +int +normal_gpio_pull_low(struct mux_obj_s *self){ + return gpio_direction_output(self->gpio_num, 0); +} + + +int +cpld_rst_all_4_pull_low(struct mux_obj_s *self){ + + char *emsg = "ERR"; + int err = ERR_MUX_UNEXCPT; + + switch(self->gpio_num) { + case MUX_RST_CPLD_C0_A77_70_74_RST_ALL: + goto setlow_cpld_rst_all_4_c0_a77_70_74_rst_all; + + default: + break; + } + emsg = "Undefined case"; + goto err_cpld_rst_all_4_pull_low; + +setlow_cpld_rst_all_4_c0_a77_70_74_rst_all: + err = _setup_i2c_value(self, 0x70, 0x0); + if (err < 0) { + emsg = "setup 0x70 fail"; + goto err_cpld_rst_all_4_pull_low; + } + err = _setup_i2c_value(self, 0x74, 0x01); + if (err < 0) { + emsg = "setup 0x74 fail"; + goto err_cpld_rst_all_4_pull_low; + } + return 0; + +err_cpld_rst_all_4_pull_low: + SWPS_INFO("%s: %s :%d :%d\n", + __func__, emsg, self->gpio_num, err); + return ERR_MUX_UNEXCPT; +} + + +int +cpld_rst_all_4_pull_high(struct mux_obj_s *self){ + + char *emsg = "ERR"; + int err = ERR_MUX_UNEXCPT; + + switch(self->gpio_num) { + case MUX_RST_CPLD_C0_A77_70_74_RST_ALL: + goto sethigh_cpld_rst_all_4_c0_a77_70_74_rst_all; + + default: + break; + } + emsg = "Undefined case"; + goto err_cpld_rst_all_4_pull_high; + +sethigh_cpld_rst_all_4_c0_a77_70_74_rst_all: + err = _setup_i2c_value(self, 0x70, 0xfe); + if (err < 0) { + emsg = "setup 0x70 fail"; + goto err_cpld_rst_all_4_pull_high; + } + err = _setup_i2c_value(self, 0x74, 0x03); + if (err < 0) { + emsg = "setup 0x74 fail"; + goto err_cpld_rst_all_4_pull_high; + } + return 0; + +err_cpld_rst_all_4_pull_high: + SWPS_INFO("%s: %s :%d :%d\n", + __func__, emsg, self->gpio_num, err); + return ERR_MUX_UNEXCPT; +} + + +int +pca9548_reset_mux_all(struct mux_obj_s *self){ + /* [Note] Power-on reset (PCA9548A-NXP) + * When power is applied to VDD, an internal Power-On Reset (POR) + * holds the PCA9548A in a reset condition until VDD has reached + * VPOR. At this point, the reset condition is released and the + * PCA9548A register and I2C-bus state machine are initialized to + * their default states (all zeroes) causing all the channels to + * be deselected. Thereafter, VDD must be lowered below 0.2 V for + * at least 5 us in order to reset the device. + */ + if (self->_pull_low(self) < 0) { + SWPS_ERR("%s: _pull_low fail!\n", __func__); + return -1; + } + mdelay(MUX_RST_WAIT_MS_PCA9548); + if (self->_pull_high(self) < 0) { + SWPS_ERR("%s: _pull_high fail!\n", __func__); + return -1; + } + mdelay(MUX_RST_WAIT_MS_PCA9548); + return 0; +} + + +int +cpld_reset_mux_all(struct mux_obj_s *self){ + + char *emsg = "ERR"; + int err = ERR_MUX_UNEXCPT; + + switch(self->gpio_num) { + case MUX_RST_CPLD_C0_A77_70_74_RST_ALL: + goto reset_cpld_rst_all_4_c0_a77_70_74_rst_all; + + default: + break; + } + emsg = "Undefined case"; + goto err_cpld_reset_mux_all; + +reset_cpld_rst_all_4_c0_a77_70_74_rst_all: + if (self->_pull_low(self) < 0) { + emsg = "_pull_low fail"; + goto err_cpld_reset_mux_all; + } + mdelay(MUX_RST_WAIT_MS_CPLD); + return 0; + +err_cpld_reset_mux_all: + SWPS_INFO("%s: %s :%d :%d\n", + __func__, emsg, self->gpio_num, err); + return ERR_MUX_UNEXCPT; +} + + +int +common_reset_mux_all(struct mux_obj_s *self){ + SWPS_ERR("%s: not ready!\n", __func__); + return -1; +} + + +int +init_gpio_4_force(struct mux_obj_s *self){ + + if (self->_pull_high(self) < 0) { + SWPS_ERR("%s: setup default fail!\n", __func__); + return -1; + } + return 0; +} + + +int +init_gpio_4_normal(struct mux_obj_s *self){ + + int err = 0; + char *emsg = "ERR"; + + if (!gpio_is_valid(self->gpio_num)) { + emsg = "GPIO invalid"; + goto err_init_gpio_4_normal; + } + err = gpio_request(self->gpio_num, MUX_GPIO_LABEL); + if (err < 0) { + emsg = "gpio_request fail"; + goto err_init_gpio_4_normal; + } + err = self->_pull_high(self); + if (err < 0) { + emsg = "setup default fail"; + goto err_init_gpio_4_normal; + } + SWPS_DEBUG("%s: gpio_request:%d ok.\n", __func__, self->gpio_num); + return 0; + +err_init_gpio_4_normal: + SWPS_ERR("%s: %s :%d :%d\n", + __func__, emsg, self->gpio_num, err); + return -1; +} + + +int +init_cpld_4_rst_all(struct mux_obj_s *self){ + + char *emsg = "ERR"; + int err = ERR_MUX_UNEXCPT; + int chan = ERR_MUX_UNEXCPT; + int addr = ERR_MUX_UNEXCPT; + + switch(self->gpio_num) { + case MUX_RST_CPLD_C0_A77_70_74_RST_ALL: + goto init_cpld_i2c_c0_a77_70_74_rst_all; + + default: + break; + } + emsg = "Undefined case"; + goto err_init_cpld_4_rst_all; + +init_cpld_i2c_c0_a77_70_74_rst_all: + chan = 0; + addr = 0x77; + err = _setup_i2c_client(self, chan, addr); + if (err < 0) { + emsg = "_setup_i2c_client fail"; + goto err_init_cpld_4_rst_all; + } + err = self->_pull_high(self); + if (err < 0) { + emsg = "setup default value fail"; + goto err_init_cpld_4_rst_all; + } + SWPS_DEBUG("%s: init_cpld_i2c_c0_a77_70_74_rst_all ok", __func__); + return 0; + +err_init_cpld_4_rst_all: + SWPS_INFO("%s: %s :%d :%d\n", + __func__, emsg, self->gpio_num, err); + return ERR_MUX_UNEXCPT; +} + + +int +clean_gpio_4_common(struct mux_obj_s *self){ + + if (!self) return 0; + if (!gpio_is_valid(self->gpio_num)) return 0; + self->_pull_high(self); + gpio_free(mux_head_p->gpio_num); + return 0; +} + + +int +clean_cpld_4_rst_all(struct mux_obj_s *self){ + + if (!self) return 0; + self->_pull_high(self); + if (self->i2c_client_p) { + i2c_put_adapter(self->i2c_client_p->adapter); + kfree(self->i2c_client_p); + } + return 0; +} + + +static int +_setup_muxctl_cb(struct mux_obj_s *self, + unsigned gpio){ + + char mod_dsc[32] = "ERR"; + + switch (gpio) { + case MUX_RST_GPIO_FORCE_RANGELEY: + self->gpio_num = gpio; + self->_pull_low = rangeley_force_pull_low; + self->_pull_high = rangeley_force_pull_high; + self->_init = init_gpio_4_force; + self->_clean = clean_gpio_4_common; + self->reset = pca9548_reset_mux_all; + memset(mod_dsc, 0, 32); + snprintf(mod_dsc, 31, "Rangeley force mode"); + goto ok_setup_muxctl_cb; + + case MUX_RST_GPIO_FORCE_HEDERA: + self->gpio_num = gpio; + self->_pull_low = hedera_force_pull_low; + self->_pull_high = hedera_force_pull_high; + self->_init = init_gpio_4_force; + self->_clean = clean_gpio_4_common; + self->reset = pca9548_reset_mux_all; + memset(mod_dsc, 0, 32); + snprintf(mod_dsc, 31, "Hedera force mode"); + goto ok_setup_muxctl_cb; + + case MUX_RST_GPIO_48_PCA9548: + case MUX_RST_GPIO_69_PCA9548: + case MUX_RST_GPIO_249_PCA9548: + case MUX_RST_GPIO_500_PCA9548: + case MUX_RST_GPIO_505_PCA9548: + self->gpio_num = gpio; + self->_pull_low = normal_gpio_pull_low; + self->_pull_high = normal_gpio_pull_high; + self->_init = init_gpio_4_normal; + self->_clean = clean_gpio_4_common; + self->reset = pca9548_reset_mux_all; + memset(mod_dsc, 0, 32); + snprintf(mod_dsc, 31, "Normal mode :%d", (int)gpio); + goto ok_setup_muxctl_cb; + + case MUX_RST_CPLD_C0_A77_70_74_RST_ALL: + self->gpio_num = gpio; + self->_pull_low = cpld_rst_all_4_pull_low; + self->_pull_high = cpld_rst_all_4_pull_high; + self->_init = init_cpld_4_rst_all; + self->_clean = clean_cpld_4_rst_all; + self->reset = cpld_reset_mux_all; + memset(mod_dsc, 0, 32); + snprintf(mod_dsc, 31, "CPLD mode :%d", (int)gpio); + goto ok_setup_muxctl_cb; + + default: + break; + } + SWPS_ERR("%s: Unexpected GPIO:%d\n", __func__, gpio); + return -1; + +ok_setup_muxctl_cb: + SWPS_INFO("muxctl: %s.\n", mod_dsc); + return 0; +} + + +/* ========== MUX public functions ========== + */ +void +clean_mux_objs(void){ + + struct mux_obj_s *curr_p = mux_head_p; + struct mux_obj_s *next_p = NULL; + + if (!curr_p) { + SWPS_DEBUG("%s: mux_head_p is NULL\n", __func__); + return; + } + while (curr_p) { + next_p = curr_p->next; + curr_p->_clean(curr_p); + kfree(curr_p); + curr_p = next_p; + } + SWPS_DEBUG("%s: done.\n", __func__); +} +EXPORT_SYMBOL(clean_mux_objs); + + +int +reset_mux_objs(void){ + + if (!mux_head_p) { + SWPS_ERR("%s: MUX ctl object doesn't exist!\n", __func__); + return -1; + } + if (mux_head_p->reset(mux_head_p) < 0){ + SWPS_ERR("%s: reset fail!\n", __func__); + return -1; + } + return 0; +} +EXPORT_SYMBOL(reset_mux_objs); + + +struct mux_obj_s * +_create_mux_obj(unsigned gpio){ + + char *emsg = "ERR"; + struct mux_obj_s *obj_p = NULL; + + obj_p = kzalloc(sizeof(struct mux_obj_s), GFP_KERNEL); + if (!obj_p) { + emsg = "kzalloc fail!"; + goto err_create_mux_obj_1; + } + if (_setup_muxctl_cb(obj_p, gpio) < 0){ + emsg = "_setup_muxctl_cb fail!"; + goto err_create_mux_obj_2; + } + if (obj_p->_init(obj_p) < 0) { + emsg = "_init() fail!"; + goto err_create_mux_obj_2; + } + SWPS_DEBUG("%s: created MUX object :%d\n", __func__, gpio); + return obj_p; + +err_create_mux_obj_2: + kfree(obj_p); +err_create_mux_obj_1: + SWPS_ERR("%s: %s :%d\n", __func__, emsg, gpio); + return NULL; +} + + +int +init_mux_objs(unsigned gpio){ + + struct mux_obj_s *curr_p = NULL; + char *emsg = "ERR"; + + /* Create MUX control object */ + if (mux_head_p) { + SWPS_DEBUG("%s: mux_head_p is not NULL!\n", __func__); + clean_mux_objs(); + } + /* Currently, it is using single muxctl architecture. + * In the future, it may use the multi-muxctl. + * (Ex: Gulmohar's advance I2C control / Peony's reset single mux) + */ + curr_p = _create_mux_obj(gpio); + if (!curr_p) { + emsg = "_create_mux_obj fail"; + goto err_init_mux_objs; + } + curr_p->next = NULL; + mux_head_p = curr_p; + SWPS_DEBUG("%s: all done. :%d\n", __func__, gpio); + return 0; + +err_init_mux_objs: + clean_mux_objs(); + SWPS_ERR("%s: %s\n", __func__, emsg); + return -1; +} +EXPORT_SYMBOL(init_mux_objs); + + +/* For single ko module + * => You need to declare MODULE_LICENSE If you want to build single module along. + * => Ex: For ONL platform + */ +MODULE_LICENSE("GPL"); + + + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_mux.h b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_mux.h new file mode 100644 index 000000000000..a6b9d98d6e7e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_mux.h @@ -0,0 +1,50 @@ +#ifndef INV_MUX_H +#define INV_MUX_H + +#include + +/* MUX basic information */ +#define MUX_GPIO_LABEL "SWPS_RST_MUX" + +/* MUX reset GPIO define */ +#define MUX_RST_GPIO_FORCE (30100) +#define MUX_RST_GPIO_FORCE_RANGELEY (30101) +#define MUX_RST_GPIO_FORCE_HEDERA (30102) +#define MUX_RST_GPIO_48_PCA9548 (48) +#define MUX_RST_GPIO_69_PCA9548 (69) +#define MUX_RST_GPIO_249_PCA9548 (249) +#define MUX_RST_GPIO_500_PCA9548 (500) +#define MUX_RST_GPIO_505_PCA9548 (505) +#define MUX_RST_CPLD_C0_A77_70_74_RST_ALL (30201) + +/* MUX relate value define */ +#define MUX_RST_WAIT_MS_PCA9548 (1) +#define MUX_RST_WAIT_MS_CPLD (10) +#define MUX_RST_MEM_ADDR_RANGELEY (0) // TBD +#define MUX_RST_MEM_ADDR_HEDERA (0x548) + +/* MUX error code define */ +#define ERR_MUX_UNEXCPT (-399) + +struct mux_obj_s { + struct i2c_client *i2c_client_p; + struct mux_obj_s *next; + unsigned gpio_num; + int (*_pull_high)(struct mux_obj_s *self); + int (*_pull_low)(struct mux_obj_s *self); + int (*_init)(struct mux_obj_s *self); + int (*_clean)(struct mux_obj_s *self); + int (*reset)(struct mux_obj_s *self); +}; + + +void clean_mux_objs(void); +int reset_mux_objs(void); +int init_mux_objs(unsigned gpio); + + +#endif /* INV_MUX_H */ + + + + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_platform.c b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_platform.c new file mode 100644 index 000000000000..c5331ab7319c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_platform.c @@ -0,0 +1,228 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct inv_i2c_board_info { + int ch; + int size; + struct i2c_board_info *board_info; + int probe; +}; + +#define bus_id(id) (id) +#define SCL_PIN 58 +#define SDA_PIN 75 + +static struct pca954x_platform_mode mux_modes_0[] = { + {.adap_id = bus_id(2),}, {.adap_id = bus_id(3),}, +}; + +static struct pca954x_platform_mode mux_modes_1[] = { + {.adap_id = bus_id(4),}, {.adap_id = bus_id(5),}, + {.adap_id = bus_id(6),}, {.adap_id = bus_id(7),}, + {.adap_id = bus_id(8),}, {.adap_id = bus_id(9),}, + {.adap_id = bus_id(10),}, {.adap_id = bus_id(11),}, +}; + +static struct pca954x_platform_mode mux_modes_2_0[] = { + {.adap_id = bus_id(12),}, {.adap_id = bus_id(13),}, + {.adap_id = bus_id(14),}, {.adap_id = bus_id(15),}, + {.adap_id = bus_id(16),}, {.adap_id = bus_id(17),}, + {.adap_id = bus_id(18),}, {.adap_id = bus_id(19),}, +}; + +static struct pca954x_platform_mode mux_modes_2_1[] = { + {.adap_id = bus_id(20),}, {.adap_id = bus_id(21),}, + {.adap_id = bus_id(22),}, {.adap_id = bus_id(23),}, + {.adap_id = bus_id(24),}, {.adap_id = bus_id(25),}, + {.adap_id = bus_id(26),}, {.adap_id = bus_id(27),}, +}; + +static struct pca954x_platform_mode mux_modes_2_2[] = { + {.adap_id = bus_id(28),}, {.adap_id = bus_id(29),}, + {.adap_id = bus_id(30),}, {.adap_id = bus_id(31),}, + {.adap_id = bus_id(32),}, {.adap_id = bus_id(33),}, + {.adap_id = bus_id(34),}, {.adap_id = bus_id(35),}, +}; + +static struct pca954x_platform_mode mux_modes_2_3[] = { + {.adap_id = bus_id(36),}, {.adap_id = bus_id(37),}, + {.adap_id = bus_id(38),}, {.adap_id = bus_id(39),}, + {.adap_id = bus_id(40),}, {.adap_id = bus_id(41),}, + {.adap_id = bus_id(42),}, {.adap_id = bus_id(43),}, +}; + + +static struct pca954x_platform_data mux_data_0 = { + .modes = mux_modes_0, + .num_modes = 2, +}; + +static struct pca954x_platform_data mux_data_1 = { + .modes = mux_modes_1, + .num_modes = 8, +}; + +static struct pca954x_platform_data mux_data_2_0 = { + .modes = mux_modes_2_0, + .num_modes = 8, +}; +static struct pca954x_platform_data mux_data_2_1 = { + .modes = mux_modes_2_1, + .num_modes = 8, +}; +static struct pca954x_platform_data mux_data_2_2 = { + .modes = mux_modes_2_2, + .num_modes = 8, +}; +static struct pca954x_platform_data mux_data_2_3 = { + .modes = mux_modes_2_3, + .num_modes = 8, +}; + +static struct i2c_board_info i2c_device_info0[] __initdata = { + {"inv_cpld", 0, 0x77, "inv_cpld", 0, 0, 0}, // CPLD driver +// {"24c512", 0, 0x55, 0, 0, 0}, // OEM1 VPD +// {"24c512", 0, 0x54, 0, 0, 0}, // OEM2 VPD + {"pca9543", 0, 0x73, "pca9543", &mux_data_0, 0, 0}, // MUX +}; + +static struct i2c_board_info i2c_device_info1[] __initdata = { + {"pca9548", 0, 0x70, "pca9548-1", &mux_data_1, 0, 0}, +}; + +static struct i2c_board_info i2c_device_info2[] __initdata ={ + {"ucd90160", 0, 0x34, "ucd90160", 0, 0 ,0}, +}; + +static struct i2c_board_info i2c_device_info11[] __initdata ={ + {"pmbus", 0, 0x5A, "pmbus-1", 0, 0 ,0}, //PSU1 DVT + {"pmbus", 0, 0x5B, "pmbus-2", 0, 0 ,0}, //PSU2 DVT +}; + +static struct i2c_board_info i2c_device_info3[] __initdata ={ + {"tmp75", 0, 0x48, "tmp75-1", 0, 0 ,0}, //CPU Board Temperature + {"tmp75", 0, 0x4A, "tmp75-2", 0, 0 ,0}, //Front Panel Inlet Temperature + {"tmp75", 0, 0x4D, "tmp75-3", 0, 0 ,0}, + {"tmp75", 0, 0x4E, "tmp75-4", 0, 0 ,0}, //Near ASIC Temperature +}; + +static struct i2c_board_info i2c_device_info4[] __initdata = { + {"pca9548", 0, 0x72, "pca9548-2", &mux_data_2_0, 0, 0}, +}; +static struct i2c_board_info i2c_device_info5[] __initdata = { + {"pca9548", 0, 0x72, "pca9548-3", &mux_data_2_1, 0, 0}, +}; +static struct i2c_board_info i2c_device_info6[] __initdata = { + {"pca9548", 0, 0x72, "pca9548-4", &mux_data_2_2, 0, 0}, +}; +static struct i2c_board_info i2c_device_info7[] __initdata = { + {"pca9548", 0, 0x72, "pca9548-5", &mux_data_2_3, 0, 0}, +}; + +static struct inv_i2c_board_info i2cdev_list[] = { + {bus_id(0), ARRAY_SIZE(i2c_device_info0), i2c_device_info0 , 0}, //i2c-0 smbus + {bus_id(0), ARRAY_SIZE(i2c_device_info1), i2c_device_info1 , 1}, //i2c-0 smbus (for DVT) + {bus_id(1), ARRAY_SIZE(i2c_device_info1), i2c_device_info1 , 1}, //i2c-1 i2c-gpio (for EVT) + {bus_id(3), ARRAY_SIZE(i2c_device_info3), i2c_device_info3 , 0}, //mux 0x73 channel 1 + {bus_id(2), ARRAY_SIZE(i2c_device_info2), i2c_device_info2 , 0}, //mux 0x73 channel 0 + {bus_id(2), ARRAY_SIZE(i2c_device_info11), i2c_device_info11, 1}, //mux 0x73 channel 0 + {bus_id(4), ARRAY_SIZE(i2c_device_info4), i2c_device_info4 , 1}, //mux 0x70 channel 0 + {bus_id(5), ARRAY_SIZE(i2c_device_info5), i2c_device_info5 , 1}, //mux 0x70 channel 1 + {bus_id(6), ARRAY_SIZE(i2c_device_info6), i2c_device_info6 , 1}, //mux 0x70 channel 2 + {bus_id(7), ARRAY_SIZE(i2c_device_info7), i2c_device_info7 , 1}, //mux 0x70 channel 3 +}; + +static struct gpiod_lookup_table inv_i2c_gpiod_table = { + .dev_id = "i2c-gpio.1", + .table = { + GPIO_LOOKUP_IDX("gpio_ich", SDA_PIN, NULL, 0, GPIO_OPEN_DRAIN), //I2C_SDA + GPIO_LOOKUP_IDX("gpio_ich", SCL_PIN, NULL, 1, GPIO_OPEN_DRAIN), //I2C_SCL + }, +}; + +static struct i2c_gpio_platform_data i2c_platform_data = { + .udelay = 5, //5:100kHz + //.sda_is_open_drain = 0, + //.scl_is_open_drain = 0, + //.scl_is_output_only = 0, +}; + +static void i2cgpio_device_release(struct device *dev) +{ + gpiod_remove_lookup_table(&inv_i2c_gpiod_table); +} + +static struct platform_device device_i2c_gpio0 = { + .name = "i2c-gpio", + .id = 1, + .dev = { + .platform_data = &i2c_platform_data, + .release = i2cgpio_device_release, + }, +}; + +static int __init inv_platform_init(void) +{ + struct i2c_adapter *adap = NULL; + struct i2c_client *e = NULL; + int ret = 0; + int i,j,k; + + //use i2c-gpio + //register gpio + outl( inl(0x533) | (1<<2), 0x533); //i2c-gpio sdl(58) + outl( inl(0x541) | (1<<3), 0x541); //i2c gpio sda(75) + outl( inl(0x540) | (1<<5), 0x540); //RST_I2C_MUX_N(69) + outl( inl(0x503) | (1)|(1<<2)|(1<<3), 0x503); //WDT_IRQ_N(24) PSOC_HEART_BEAT(26) CPLD_HEART_BEAT(27) + outl( inl(0x501) | (1<<4), 0x501); //RSTBTN_IN_N(12) + outl( inl(0x533) | (1<<5), 0x533); //RST_BTN_5S_N(61) + + gpiod_add_lookup_table(&inv_i2c_gpiod_table); + + ret = platform_device_register(&device_i2c_gpio0); + if (ret) { + printk(KERN_ERR "i2c-gpio: platform_device_register fail %d\n", ret); + } + msleep(10); + + for(i=0; i +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "inv_swps.h" + +static int ctl_major; +static int port_major; +static int ioexp_total; +static int port_total; +static int block_polling; +static int auto_config; +static int flag_i2c_reset; +static int flag_mod_state; +static unsigned gpio_rest_mux; +static int gpio_base = 0; +static struct class *swp_class_p = NULL; +static struct inv_platform_s *platform_p = NULL; +static struct inv_ioexp_layout_s *ioexp_layout = NULL; +static struct inv_port_layout_s *port_layout = NULL; +int io_no_init = 0; +module_param(io_no_init, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); +static void swp_polling_worker(struct work_struct *work); +static DECLARE_DELAYED_WORK(swp_polling, swp_polling_worker); + +static int reset_i2c_topology(void); + +static int +__swp_match(struct device *dev, +#ifdef SWPS_KERN_VER_AF_3_10 + + const void *data){ +#else + void *data){ +#endif + + char *name = (char *)data; + if (strcmp(dev_name(dev), name) == 0) + return 1; + return 0; +} + + +struct device * +get_swpdev_by_name(char *name){ + struct device *dev = class_find_device(swp_class_p, + NULL, + name, + __swp_match); + return dev; +} + + +static int +sscanf_2_int(const char *buf) { + + int result = -EBFONT; + char *hex_tag = "0x"; + + if (strcspn(buf, hex_tag) == 0) { + if (sscanf(buf,"%x",&result)) { + return result; + } + } else { + if (sscanf(buf,"%d",&result)) { + return result; + } + if(sscanf(buf,"-%d",&result)) { + return -result; + } + if (sscanf(buf,"%x",&result)) { + return result; + } + } + return -EBFONT; +} + + +static int +sscanf_2_binary(const char *buf) { + + int result = sscanf_2_int(buf); + + if (result < 0){ + return -EBFONT; + } + switch (result) { + case 0: + case 1: + return result; + default: + break; + } + return -EBFONT; +} + + +static int +_get_polling_period(void) { + + int retval = 0; + + if (SWP_POLLING_PERIOD == 0) { + return 0; + } + retval = ((SWP_POLLING_PERIOD * HZ) / 1000); + if (retval == 0) { + return 1; + } + return retval; +} + + +static struct transvr_obj_s * +_get_transvr_obj(char *dev_name) { + + struct device *dev_p = NULL; + struct transvr_obj_s *transvr_obj_p = NULL; + + dev_p = get_swpdev_by_name(dev_name); + if (!dev_p){ + return NULL; + } + transvr_obj_p = dev_get_drvdata(dev_p); + if (!transvr_obj_p){ + return NULL; + } + return transvr_obj_p; +} + + +static int +_is_i2c_target_exist(int chan, int addr) { + /* retval: Exist = 1 / Not exist = 0 / Error < 0 + */ + struct i2c_adapter *adap = NULL; + struct i2c_client *client = NULL; + int retval = -1; + int err = -1; + int d_offs = 0; + + adap = i2c_get_adapter(chan); + if (!adap) { + SWPS_DEBUG("%s: can't get adapter\n", __func__); + retval = 0; + goto out_is_i2c_target_exist_1; + } + client = kzalloc(sizeof(*client), GFP_KERNEL); + if (!client) { + SWPS_ERR("%s: kzalloc fail\n", __func__); + retval = -1; + goto out_is_i2c_target_exist_2; + } + client->adapter = adap; + client->addr = addr; + err = i2c_smbus_read_byte_data(client, d_offs); + if (err < 0) { + retval = 0; + } else { + retval = 1; + } + i2c_put_adapter(adap); + kfree(client); + return retval; + +out_is_i2c_target_exist_2: + i2c_put_adapter(adap); +out_is_i2c_target_exist_1: + return retval; +} + + +static void +unlock_tobj_all(void) { + + struct transvr_obj_s *tobj_p; + char port_name[32]; + int port_id = 0; + int minor_curr = 0; + + for (minor_curr=0; minor_currauto_config = auto_config; + unlock_transvr_obj(tobj_p); + SWPS_DEBUG("%s: Set %s auto_config=%d\n", + __func__, tobj_p->swp_name, auto_config); + } + return retval; +} + + +/* ========== R/W Functions module control attribute ========== + */ +static ssize_t +show_attr_platform(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + return snprintf(buf_p, 32, "%s\n", platform_p->name); +} + + +static ssize_t +show_attr_version(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + return snprintf(buf_p, 8, "%s\n", SWP_VERSION); +} + + +static ssize_t +show_attr_status(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + return snprintf(buf_p, 8, "%d\n", flag_mod_state); +} + + +static ssize_t +show_attr_auto_config(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + return snprintf(buf_p, 8, "%d\n", auto_config); +} + + +static ssize_t +show_attr_block_poll(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + return snprintf(buf_p, 8, "%d\n", block_polling); +} +static ssize_t +show_attr_io_no_init(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + return snprintf(buf_p, 8, "%d\n", io_no_init); +} + + +static int +_check_reset_pwd(const char *buf_p, + size_t count) { + + int in_max = 64; + int in_len = (int)count; + char in_val[64] = "ERR"; + char *emsg = "ERR"; + + if (in_len >= in_max) { + emsg = "input too much"; + goto err_check_reset_pwd; + } + if (!sscanf(buf_p,"%s",in_val)) { + emsg = "format incorrect"; + goto err_check_reset_pwd; + } + if (strcmp(in_val, SWP_RESET_PWD) != 0) { + emsg = "password incorrect"; + goto err_check_reset_pwd; + } + return 0; + +err_check_reset_pwd: + SWPS_ERR("%s: %s\n", __func__, emsg); + return -1; +} + + +static ssize_t +store_attr_reset_i2c(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + if (_check_reset_pwd(buf_p, count) < 0) { + return -EBFONT; + } + /* Polling mode */ + if (SWP_POLLING_ENABLE) { + SWPS_INFO("%s: reset I2C :polling\n", __func__); + flag_i2c_reset = 1; + return count; + } + /* Direct mode */ + SWPS_INFO("%s: reset I2C go. :direct\n", __func__); + if (reset_i2c_topology() < 0) { + SWPS_ERR("%s: reset fail!\n", __func__); + return -EIO; + } + SWPS_INFO("%s: reset I2C ok. :direct\n", __func__); + return count; +} + + +static ssize_t +store_attr_reset_swps(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p; + char port_name[32] = "ERR"; + int port_id = 0; + int minor_curr = 0; + + if (_check_reset_pwd(buf_p, count) < 0) { + return -EBFONT; + } + for (minor_curr=0; minor_currstate = STATE_TRANSVR_DISCONNECTED; + unlock_transvr_obj(tobj_p); + SWPS_INFO("%s: reset:%s\n", __func__, tobj_p->swp_name); + } + return count; +} + + +static ssize_t +store_attr_auto_config(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + int input_val = sscanf_2_int(buf_p); + + if (input_val < 0){ + return -EBFONT; + } + if ((input_val != 0) && (input_val != 1)) { + return -EBFONT; + } + auto_config = input_val; + _update_auto_config_2_trnasvr(); + return count; +} + + +static ssize_t +store_attr_block_poll( struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + int input_val = sscanf_2_int(buf_p); + + if (input_val < 0){ + return -EBFONT; + } + if ((input_val != 0) && (input_val != 1)) { + return -EBFONT; + } + + if(input_val != block_polling){ + block_polling = input_val; + if(block_polling){ + cancel_delayed_work_sync(&swp_polling); + } + else{ + schedule_delayed_work(&swp_polling, _get_polling_period()); + } + } + + return count; +} + +static ssize_t +store_attr_io_no_init( struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + int input_val = sscanf_2_int(buf_p); + + if ((input_val != 0) && (input_val != 1)) { + return -EBFONT; + } + + if(input_val != io_no_init){ + io_no_init = input_val; + } + + return count; +} + +/* ========== Show functions: For transceiver attribute ========== + */ +static ssize_t +_show_transvr_hex_attr(struct transvr_obj_s* tobj_p, + int (*get_func)(struct transvr_obj_s* tobj_p), + char *buf_p) { + size_t len; + int result; + + lock_transvr_obj(tobj_p); + result = get_func(tobj_p); + unlock_transvr_obj(tobj_p); + if (result < 0){ + len = snprintf(buf_p, 8, "%d\n", result); + } else { + len = snprintf(buf_p, 8, "0x%02x\n", result); + } + return len; +} + + +static ssize_t +_show_transvr_int_attr(struct transvr_obj_s* tobj_p, + int (*get_func)(struct transvr_obj_s* tobj_p), + char *buf_p) { + size_t len; + + lock_transvr_obj(tobj_p); + len = snprintf(buf_p, 16, "%d\n", get_func(tobj_p)); + unlock_transvr_obj(tobj_p); + return len; +} + + +static ssize_t +_show_transvr_str_attr(struct transvr_obj_s* tobj_p, + int (*get_func)(struct transvr_obj_s* tobj_p, char* buf), + char *buf_p) { + size_t len; + + lock_transvr_obj(tobj_p); + len = get_func(tobj_p, buf_p); + unlock_transvr_obj(tobj_p); + return len; +} + + +static ssize_t +show_attr_id(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_hex_attr(tobj_p, + tobj_p->get_id, + buf_p); +} + + +static ssize_t +show_attr_ext_id(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_hex_attr(tobj_p, + tobj_p->get_ext_id, + buf_p); +} + + +static ssize_t +show_attr_connector(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_hex_attr(tobj_p, + tobj_p->get_connector, + buf_p); +} + + +static ssize_t +show_attr_vendor_name(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_vendor_name, + buf_p); +} + + +static ssize_t +show_attr_vendor_pn(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_vendor_pn, + buf_p); +} + + +static ssize_t +show_attr_vendor_rev(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_vendor_rev, + buf_p); +} + + +static ssize_t +show_attr_vendor_sn(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_vendor_sn, + buf_p); +} + + +static ssize_t +show_attr_power_cls(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + size_t len; + int result; + struct transvr_obj_s *tobj_p; + + tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + lock_transvr_obj(tobj_p); + result = tobj_p->get_power_cls(tobj_p); + unlock_transvr_obj(tobj_p); + if (result < 0){ + len = snprintf(buf_p, 16, "%d\n", result); + } else { + len = snprintf(buf_p, 16, "Power Class %d\n", result); + } + return len; +} + + +static ssize_t +show_attr_br(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_hex_attr(tobj_p, + tobj_p->get_br, + buf_p); +} + + +static ssize_t +show_attr_len_sm(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_int_attr(tobj_p, + tobj_p->get_len_sm, + buf_p); +} + + +static ssize_t +show_attr_len_smf(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_int_attr(tobj_p, + tobj_p->get_len_smf, + buf_p); +} + + +static ssize_t +show_attr_len_om1(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_int_attr(tobj_p, + tobj_p->get_len_om1, + buf_p); +} + + +static ssize_t +show_attr_len_om2(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_int_attr(tobj_p, + tobj_p->get_len_om2, + buf_p); +} + + +static ssize_t +show_attr_len_om3(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_int_attr(tobj_p, + tobj_p->get_len_om3, + buf_p); +} + + +static ssize_t +show_attr_len_om4(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_int_attr(tobj_p, + tobj_p->get_len_om4, + buf_p); +} + + +static ssize_t +show_attr_comp_rev(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_hex_attr(tobj_p, + tobj_p->get_comp_rev, + buf_p); +} + + +static ssize_t +show_attr_comp_eth(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_hex_attr(tobj_p, + tobj_p->get_comp_eth_1, + buf_p); +} + + +static ssize_t +show_attr_comp_eth_10(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_hex_attr(tobj_p, + tobj_p->get_comp_eth_10, + buf_p); +} + + +static ssize_t +show_attr_comp_eth_10_40(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_hex_attr(tobj_p, + tobj_p->get_comp_eth_10_40, + buf_p); +} + + +static ssize_t +show_attr_comp_extend(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_hex_attr(tobj_p, + tobj_p->get_comp_extend, + buf_p); +} + + +static ssize_t +show_attr_rate_id(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_hex_attr(tobj_p, + tobj_p->get_rate_id, + buf_p); +} + + +static ssize_t +show_attr_temperature(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_curr_temp, + buf_p); +} + + +static ssize_t +show_attr_voltage(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_curr_vol, + buf_p); +} + + +static ssize_t +show_attr_tx_bias(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_tx_bias, + buf_p); +} + + +static ssize_t +show_attr_tx_power(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_tx_power, + buf_p); +} + + +static ssize_t +show_attr_tx_eq(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_tx_eq, + buf_p); +} + + +static ssize_t +show_attr_rx_power(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_rx_power, + buf_p); +} + + +static ssize_t +show_attr_rx_am(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_rx_am, + buf_p); +} + + +static ssize_t +show_attr_rx_em(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_rx_em, + buf_p); +} + + +static ssize_t +show_attr_wavelength(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_wavelength, + buf_p); +} + + +static ssize_t +show_attr_extphy_offset(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_extphy_offset, + buf_p); +} + + +static ssize_t +show_attr_extphy_reg(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_extphy_reg, + buf_p); +} + + +static ssize_t +show_attr_info(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_int_attr(tobj_p, + tobj_p->get_info, + buf_p); +} + + +static ssize_t +show_attr_if_type(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_if_type, + buf_p); +} + + +static ssize_t +show_attr_if_speed(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_if_speed, + buf_p); +} + + +static ssize_t +show_attr_if_lane(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_if_lane, + buf_p); +} + + +static ssize_t +show_attr_cdr(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_hex_attr(tobj_p, + tobj_p->get_cdr, + buf_p); +} + + +static ssize_t +show_attr_soft_rs0(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_int_attr(tobj_p, + tobj_p->get_soft_rs0, + buf_p); +} + + +static ssize_t +show_attr_soft_rs1(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_int_attr(tobj_p, + tobj_p->get_soft_rs1, + buf_p); +} + + +static ssize_t +show_attr_soft_rx_los(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_soft_rx_los, + buf_p); +} + + +static ssize_t +show_attr_soft_tx_disable(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_soft_tx_disable, + buf_p); +} + + +static ssize_t +show_attr_soft_tx_fault(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_soft_tx_fault, + buf_p); +} + + +static ssize_t +show_attr_auto_tx_disable(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_auto_tx_disable, + buf_p); +} + + +/* ========== Store functions: transceiver (R/W) attribute ========== + */ +static ssize_t +_store_transvr_int_attr(struct transvr_obj_s* tobj_p, + int (*set_func)(struct transvr_obj_s *tobj_p, int input_val), + const char *buf_p, + size_t count) { + int input, err; + + input = sscanf_2_int(buf_p); + if (input < 0){ + return -EBFONT; + } + lock_transvr_obj(tobj_p); + err = set_func(tobj_p, input); + unlock_transvr_obj(tobj_p); + if (err < 0){ + return err; + } + return count; +} + + +static ssize_t +_store_transvr_byte_hex_attr(struct transvr_obj_s* tobj_p, + int (*set_func)(struct transvr_obj_s *tobj_p, int input_val), + const char *buf_p, + size_t count) { + int input, err; + + input = sscanf_2_int(buf_p); + if ((input < 0) || (input > 0xff)){ + return -EBFONT; + } + lock_transvr_obj(tobj_p); + err = set_func(tobj_p, input); + unlock_transvr_obj(tobj_p); + if (err < 0){ + return err; + } + return count; +} + + +static ssize_t +_store_transvr_binary_attr(struct transvr_obj_s* tobj_p, + int (*set_func)(struct transvr_obj_s *tobj_p, int input_val), + const char *buf_p, + size_t count) { + int input, err; + + input = sscanf_2_binary(buf_p); + if (input < 0){ + return -EBFONT; + } + lock_transvr_obj(tobj_p); + err = set_func(tobj_p, input); + unlock_transvr_obj(tobj_p); + if (err < 0){ + return err; + } + return count; +} + + +static ssize_t +store_attr_cdr(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _store_transvr_byte_hex_attr(tobj_p, + tobj_p->set_cdr, + buf_p, + count); +} + + +static ssize_t +store_attr_soft_rs0(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _store_transvr_binary_attr(tobj_p, + tobj_p->set_soft_rs0, + buf_p, + count); +} + + +static ssize_t +store_attr_soft_rs1(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _store_transvr_binary_attr(tobj_p, + tobj_p->set_soft_rs1, + buf_p, + count); +} + + +static ssize_t +store_attr_soft_tx_disable(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count) { + + int check = sscanf_2_int(buf_p); + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + if ((check < 0) || (check > 0xf)){ + return -EBFONT; + } + return _store_transvr_byte_hex_attr(tobj_p, + tobj_p->set_soft_tx_disable, + buf_p, + count); +} + + +static ssize_t +store_attr_auto_tx_disable(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count) { + + int err = -EPERM; + int input = sscanf_2_int(buf_p); + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + if ((input < 0) || (input > 0xf)){ + if (input != VAL_TRANSVR_FUNCTION_DISABLE) { + return -EBFONT; + } + } + lock_transvr_obj(tobj_p); + err = tobj_p->set_auto_tx_disable(tobj_p, input); + unlock_transvr_obj(tobj_p); + if (err < 0){ + return err; + } + return count; +} + + +static ssize_t +store_attr_tx_eq(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _store_transvr_int_attr(tobj_p, + tobj_p->set_tx_eq, + buf_p, + count); +} + + +static ssize_t +store_attr_rx_am(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _store_transvr_int_attr(tobj_p, + tobj_p->set_rx_am, + buf_p, + count); +} + + +static ssize_t +store_attr_rx_em(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _store_transvr_int_attr(tobj_p, + tobj_p->set_rx_em, + buf_p, + count); +} + + +static ssize_t +store_attr_extphy_offset(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _store_transvr_int_attr(tobj_p, + tobj_p->set_extphy_offset, + buf_p, + count); +} + + +static ssize_t +store_attr_extphy_reg(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _store_transvr_int_attr(tobj_p, + tobj_p->set_extphy_reg, + buf_p, + count); +} + +/* ========== Show functions: For I/O Expander attribute ========== + */ +static ssize_t +_show_ioexp_binary_attr(struct transvr_obj_s *tobj_p, + int (*get_func)(struct ioexp_obj_s *ioexp_p, int voffset), + char *buf_p) { + size_t len; + struct ioexp_obj_s *ioexp_p = tobj_p->ioexp_obj_p; + + if (!ioexp_p) { + SWPS_ERR(" %s: data corruption! :%s\n", __func__, tobj_p->swp_name); + return -ENODATA; + } + mutex_lock(&ioexp_p->lock); + len = snprintf(buf_p, 8, "%d\n", get_func(ioexp_p, tobj_p->ioexp_virt_offset)); + mutex_unlock(&ioexp_p->lock); + return len; +} + + +static ssize_t +show_attr_present(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _show_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->get_present, + buf_p); +} + + +static ssize_t +show_attr_tx_fault(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _show_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->get_tx_fault, + buf_p); +} + + +static ssize_t +show_attr_rxlos(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _show_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->get_rxlos, + buf_p); +} + + +static ssize_t +show_attr_tx_disable(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _show_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->get_tx_disable, + buf_p); +} + + +static ssize_t +show_attr_reset(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _show_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->get_reset, + buf_p); +} + + +static ssize_t +show_attr_lpmod(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _show_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->get_lpmod, + buf_p); +} + + +static ssize_t +show_attr_modsel(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _show_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->get_modsel, + buf_p); +} + + +static ssize_t +show_attr_hard_rs0(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _show_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->get_hard_rs0, + buf_p); +} + + +static ssize_t +show_attr_hard_rs1(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _show_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->get_hard_rs1, + buf_p); +} + + +/* ========== Store functions: For I/O Expander (R/W) attribute ========== + */ +static ssize_t +_store_ioexp_binary_attr(struct transvr_obj_s *tobj_p, + int (*set_func)(struct ioexp_obj_s *ioexp_p, + int virt_offset, int input_val), + const char *buf_p, + size_t count) { + + int input, err; + struct ioexp_obj_s *ioexp_p = tobj_p->ioexp_obj_p; + + if (!ioexp_p) { + SWPS_ERR("%s: data corruption! :%s\n", + __func__, tobj_p->swp_name); + return -ENODATA; + } + input = sscanf_2_binary(buf_p); + if (input < 0) { + return -EBFONT; + } + mutex_lock(&ioexp_p->lock); + err = set_func(ioexp_p, tobj_p->ioexp_virt_offset, input); + mutex_unlock(&ioexp_p->lock); + if (err < 0){ + return err; + } + return count; +} + +static ssize_t +store_attr_tx_disable(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p) { + return -ENODEV; + } + return _store_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->set_tx_disable, + buf_p, + count); +} + + +static ssize_t +store_attr_reset(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p) { + return -ENODEV; + } + return _store_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->set_reset, + buf_p, + count); +} + + +static ssize_t +store_attr_lpmod(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p) { + return -ENODEV; + } + return _store_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->set_lpmod, + buf_p, + count); +} + + +static ssize_t +store_attr_modsel(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p) { + return -ENODEV; + } + return _store_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->set_modsel, + buf_p, + count); +} + + +static ssize_t +store_attr_hard_rs0(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p) { + return -ENODEV; + } + return _store_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->set_hard_rs0, + buf_p, + count); +} + + +static ssize_t +store_attr_hard_rs1(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p) { + return -ENODEV; + } + return _store_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->set_hard_rs1, + buf_p, + count); +} + + +/* ========== SWPS attribute: For module control ========== + */ +static DEVICE_ATTR(platform, S_IRUGO, show_attr_platform, NULL); +static DEVICE_ATTR(version, S_IRUGO, show_attr_version, NULL); +static DEVICE_ATTR(status, S_IRUGO, show_attr_status, NULL); +static DEVICE_ATTR(reset_i2c, S_IWUSR, NULL, store_attr_reset_i2c); +static DEVICE_ATTR(reset_swps, S_IWUSR, NULL, store_attr_reset_swps); +static DEVICE_ATTR(auto_config, S_IRUGO|S_IWUSR, show_attr_auto_config, store_attr_auto_config); +static DEVICE_ATTR(block_poll, S_IRUGO|S_IWUSR, show_attr_block_poll, store_attr_block_poll); +static DEVICE_ATTR(io_no_init, S_IRUGO|S_IWUSR, show_attr_io_no_init, store_attr_io_no_init); + + +/* ========== Transceiver attribute: from eeprom ========== + */ +static DEVICE_ATTR(id, S_IRUGO, show_attr_id, NULL); +static DEVICE_ATTR(ext_id, S_IRUGO, show_attr_ext_id, NULL); +static DEVICE_ATTR(connector, S_IRUGO, show_attr_connector, NULL); +static DEVICE_ATTR(vendor_name, S_IRUGO, show_attr_vendor_name, NULL); +static DEVICE_ATTR(vendor_pn, S_IRUGO, show_attr_vendor_pn, NULL); +static DEVICE_ATTR(vendor_rev, S_IRUGO, show_attr_vendor_rev, NULL); +static DEVICE_ATTR(vendor_sn, S_IRUGO, show_attr_vendor_sn, NULL); +static DEVICE_ATTR(power_cls, S_IRUGO, show_attr_power_cls, NULL); +static DEVICE_ATTR(br, S_IRUGO, show_attr_br, NULL); +static DEVICE_ATTR(len_sm, S_IRUGO, show_attr_len_sm, NULL); +static DEVICE_ATTR(len_smf, S_IRUGO, show_attr_len_smf, NULL); +static DEVICE_ATTR(len_om1, S_IRUGO, show_attr_len_om1, NULL); +static DEVICE_ATTR(len_om2, S_IRUGO, show_attr_len_om2, NULL); +static DEVICE_ATTR(len_om3, S_IRUGO, show_attr_len_om3, NULL); +static DEVICE_ATTR(len_om4, S_IRUGO, show_attr_len_om4, NULL); +static DEVICE_ATTR(comp_rev, S_IRUGO, show_attr_comp_rev, NULL); +static DEVICE_ATTR(comp_eth, S_IRUGO, show_attr_comp_eth, NULL); +static DEVICE_ATTR(comp_eth_10, S_IRUGO, show_attr_comp_eth_10, NULL); +static DEVICE_ATTR(comp_eth_10_40, S_IRUGO, show_attr_comp_eth_10_40, NULL); +static DEVICE_ATTR(comp_extend, S_IRUGO, show_attr_comp_extend, NULL); +static DEVICE_ATTR(rate_id, S_IRUGO, show_attr_rate_id, NULL); +static DEVICE_ATTR(temperature, S_IRUGO, show_attr_temperature, NULL); +static DEVICE_ATTR(voltage, S_IRUGO, show_attr_voltage, NULL); +static DEVICE_ATTR(tx_bias, S_IRUGO, show_attr_tx_bias, NULL); +static DEVICE_ATTR(tx_power, S_IRUGO, show_attr_tx_power, NULL); +static DEVICE_ATTR(rx_power, S_IRUGO, show_attr_rx_power, NULL); +static DEVICE_ATTR(info, S_IRUGO, show_attr_info, NULL); +static DEVICE_ATTR(if_type, S_IRUGO, show_attr_if_type, NULL); +static DEVICE_ATTR(if_speed, S_IRUGO, show_attr_if_speed, NULL); +static DEVICE_ATTR(if_lane, S_IRUGO, show_attr_if_lane, NULL); +static DEVICE_ATTR(soft_rx_los, S_IRUGO, show_attr_soft_rx_los, NULL); +static DEVICE_ATTR(soft_tx_fault, S_IRUGO, show_attr_soft_tx_fault, NULL); +static DEVICE_ATTR(wavelength, S_IRUGO, show_attr_wavelength, NULL); +static DEVICE_ATTR(tx_eq, S_IRUGO|S_IWUSR, show_attr_tx_eq, store_attr_tx_eq); +static DEVICE_ATTR(rx_am, S_IRUGO|S_IWUSR, show_attr_rx_am, store_attr_rx_am); +static DEVICE_ATTR(rx_em, S_IRUGO|S_IWUSR, show_attr_rx_em, store_attr_rx_em); +static DEVICE_ATTR(cdr, S_IRUGO|S_IWUSR, show_attr_cdr, store_attr_cdr); +static DEVICE_ATTR(soft_rs0, S_IRUGO|S_IWUSR, show_attr_soft_rs0, store_attr_soft_rs0); +static DEVICE_ATTR(soft_rs1, S_IRUGO|S_IWUSR, show_attr_soft_rs1, store_attr_soft_rs1); +static DEVICE_ATTR(soft_tx_disable, S_IRUGO|S_IWUSR, show_attr_soft_tx_disable, store_attr_soft_tx_disable); +static DEVICE_ATTR(auto_tx_disable, S_IRUGO|S_IWUSR, show_attr_auto_tx_disable, store_attr_auto_tx_disable); +static DEVICE_ATTR(extphy_offset, S_IRUGO|S_IWUSR, show_attr_extphy_offset, store_attr_extphy_offset); +static DEVICE_ATTR(extphy_reg, S_IRUGO|S_IWUSR, show_attr_extphy_reg, store_attr_extphy_reg); + +/* ========== IO Expander attribute: from expander ========== + */ +static DEVICE_ATTR(present, S_IRUGO, show_attr_present, NULL); +static DEVICE_ATTR(tx_fault, S_IRUGO, show_attr_tx_fault, NULL); +static DEVICE_ATTR(rxlos, S_IRUGO, show_attr_rxlos, NULL); +static DEVICE_ATTR(tx_disable, S_IRUGO|S_IWUSR, show_attr_tx_disable, store_attr_tx_disable); +static DEVICE_ATTR(reset, S_IRUGO|S_IWUSR, show_attr_reset, store_attr_reset); +static DEVICE_ATTR(lpmod, S_IRUGO|S_IWUSR, show_attr_lpmod, store_attr_lpmod); +static DEVICE_ATTR(modsel, S_IRUGO|S_IWUSR, show_attr_modsel, store_attr_modsel); +static DEVICE_ATTR(hard_rs0, S_IRUGO|S_IWUSR, show_attr_hard_rs0, store_attr_hard_rs0); +static DEVICE_ATTR(hard_rs1, S_IRUGO|S_IWUSR, show_attr_hard_rs1, store_attr_hard_rs1); + +/* ========== Functions for module handling ========== + */ +static void +clean_port_objs(void){ + + dev_t dev_num; + char dev_name[32]; + struct device *device_p; + struct transvr_obj_s *tobj_p; + int minor_curr, port_id; + + for (minor_curr=0; minor_curri2c_client_p) { + i2c_put_adapter(tobj_p->i2c_client_p->adapter); + kfree(tobj_p->i2c_client_p); + } + kfree(tobj_p->vendor_name); + kfree(tobj_p->vendor_pn); + kfree(tobj_p->vendor_rev); + kfree(tobj_p->vendor_sn); + kfree(tobj_p->worker_p); + kfree(tobj_p); + } + dev_num = MKDEV(port_major, minor_curr); + device_unregister(device_p); + device_destroy(swp_class_p, dev_num); + } + SWPS_DEBUG("%s: done.\n", __func__); +} + + +static void +clean_swps_common(void){ + + dev_t dev_num; + struct device *device_p; + + device_p = get_swpdev_by_name(SWP_DEV_MODCTL); + if (device_p){ + dev_num = MKDEV(ctl_major, 1); + device_unregister(device_p); + device_destroy(swp_class_p, dev_num); + } + cancel_delayed_work_sync(&swp_polling); + if (platform_p) { + kfree(platform_p); + } + SWPS_DEBUG("%s: done.\n", __func__); +} + + +static int +get_platform_type(void){ + + int i, tmp; + int auto_chan = -1; + int auto_addr = -1; + int pf_total = ARRAY_SIZE(platform_map); + char log_msg[64] = "ERROR"; + + platform_p = kzalloc(sizeof(struct inv_platform_s), GFP_KERNEL); + if (!platform_p){ + snprintf(log_msg, sizeof(log_msg), "kzalloc fail"); + goto err_get_platform_type_1; + } + memset(platform_p->name, 0, sizeof(platform_p->name)); + + switch (PLATFORM_SETTINGS) { + case PLATFORM_TYPE_AUTO: + snprintf(platform_p->name, (sizeof(platform_p->name) - 1), + "%s", dmi_get_system_info(DMI_BOARD_NAME)); + for (i=0; iname, platform_map[i].name) == 0) { + platform_p->id = platform_map[i].id; + snprintf(log_msg, sizeof(log_msg), + "Auto detect platform: %d (%s)", + platform_p->id, platform_p->name); + goto ok_get_platform_type_1; + } + } + snprintf(log_msg, sizeof(log_msg), + "Auto detect fail! detect platform: %s", + platform_p->name); + goto err_get_platform_type_2; + + case PLATFORM_TYPE_PEONY_AUTO: +#ifdef SWPS_PEONY_SFP + auto_chan = peony_sfp_ioexp_layout[0].addr[0].chan_id; + auto_addr = peony_sfp_ioexp_layout[0].addr[0].chip_addr; +#endif + tmp = _is_i2c_target_exist(auto_chan, auto_addr); + switch (tmp) { + case 0: /* Copper SKU */ + SWPS_INFO("Auto-detected :Peony :Copper\n"); + platform_p->id = PLATFORM_TYPE_PEONY_COPPER_GA; + goto map_platform_name; + + case 1: /* SFP SKU */ + SWPS_INFO("Auto-detected :Peony :SFP\n"); + platform_p->id = PLATFORM_TYPE_PEONY_SFP_GA; + goto map_platform_name; + + default: + break; + } + snprintf(log_msg, sizeof(log_msg), + "Auto detect Peony SKU fail! :%d", tmp); + goto err_get_platform_type_2; + + case PLATFORM_TYPE_MAGNOLIA: + case PLATFORM_TYPE_MAGNOLIA_FNC: + case PLATFORM_TYPE_REDWOOD: + case PLATFORM_TYPE_REDWOOD_FSL: + case PLATFORM_TYPE_HUDSON32I_GA: + case PLATFORM_TYPE_SPRUCE: + case PLATFORM_TYPE_CYPRESS_GA1: + case PLATFORM_TYPE_CYPRESS_GA2: + case PLATFORM_TYPE_CYPRESS_BAI: + case PLATFORM_TYPE_TAHOE: + case PLATFORM_TYPE_SEQUOIA_GA: + case PLATFORM_TYPE_LAVENDER_GA: + case PLATFORM_TYPE_LAVENDER_ONL: + case PLATFORM_TYPE_COTTONWOOD_RANGELEY: + case PLATFORM_TYPE_MAPLE_GA: + case PLATFORM_TYPE_MAPLE_B: + case PLATFORM_TYPE_MAPLE_J: + case PLATFORM_TYPE_GULMOHAR_GA: + case PLATFORM_TYPE_GULMOHAR_2T_EVT1_GA: + case PLATFORM_TYPE_PEONY_SFP_GA: + case PLATFORM_TYPE_PEONY_COPPER_GA: + case PLATFORM_TYPE_CEDAR_GA: + platform_p->id = PLATFORM_SETTINGS; + goto map_platform_name; + + default: + break; + } + snprintf(log_msg, sizeof(log_msg), + "PLATFORM_SETTINGS:%d undefined", PLATFORM_SETTINGS); + goto err_get_platform_type_2; + +map_platform_name: + for (i=0; iid == platform_map[i].id) { + snprintf(platform_p->name, (sizeof(platform_p->name) - 1), + "%s", platform_map[i].name); + snprintf(log_msg, sizeof(log_msg), + "User setup platform: %d (%s)", + platform_p->id, platform_p->name); + goto ok_get_platform_type_1; + } + } + snprintf(log_msg, sizeof(log_msg), + "Internal error, can not map id:%d", + platform_p->id ); + goto err_get_platform_type_2; + +ok_get_platform_type_1: + SWPS_DEBUG("%s: %s, :%d\n", __func__, log_msg, PLATFORM_SETTINGS); + return 0; + +err_get_platform_type_2: + kfree(platform_p); +err_get_platform_type_1: + SWPS_ERR("%s: %s :%d\n", __func__, log_msg, PLATFORM_SETTINGS); + return -1; +} + + +static int +get_layout_info(void){ + + switch (platform_p->id) { +#ifdef SWPS_MAGNOLIA + case PLATFORM_TYPE_MAGNOLIA: + case PLATFORM_TYPE_MAGNOLIA_FNC: + gpio_rest_mux = gpio_base + magnolia_gpio_rest_mux; + ioexp_layout = magnolia_ioexp_layout; + port_layout = magnolia_port_layout; + ioexp_total = ARRAY_SIZE(magnolia_ioexp_layout); + port_total = ARRAY_SIZE(magnolia_port_layout); + break; +#endif +#ifdef SWPS_REDWOOD + case PLATFORM_TYPE_REDWOOD: + gpio_rest_mux = gpio_base + redwood_gpio_rest_mux; + ioexp_layout = redwood_ioexp_layout; + port_layout = redwood_port_layout; + ioexp_total = ARRAY_SIZE(redwood_ioexp_layout); + port_total = ARRAY_SIZE(redwood_port_layout); + break; +#endif +#ifdef SWPS_HUDSON32I_GA + case PLATFORM_TYPE_HUDSON32I_GA: + gpio_rest_mux = gpio_base + hudsin32iga_gpio_rest_mux; + ioexp_layout = hudson32iga_ioexp_layout; + port_layout = hudson32iga_port_layout; + ioexp_total = ARRAY_SIZE(hudson32iga_ioexp_layout); + port_total = ARRAY_SIZE(hudson32iga_port_layout); + break; +#endif +#ifdef SWPS_SPRUCE + case PLATFORM_TYPE_SPRUCE: + gpio_rest_mux = gpio_base + spruce_gpio_rest_mux; + ioexp_layout = spruce_ioexp_layout; + port_layout = spruce_port_layout; + ioexp_total = ARRAY_SIZE(spruce_ioexp_layout); + port_total = ARRAY_SIZE(spruce_port_layout); + break; +#endif +#ifdef SWPS_CYPRESS_GA1 + case PLATFORM_TYPE_CYPRESS_GA1: + gpio_rest_mux = gpio_base + cypress_ga1_gpio_rest_mux; + ioexp_layout = cypress_ga1_ioexp_layout; + port_layout = cypress_ga1_port_layout; + ioexp_total = ARRAY_SIZE(cypress_ga1_ioexp_layout); + port_total = ARRAY_SIZE(cypress_ga1_port_layout); + break; +#endif +#ifdef SWPS_CYPRESS_GA2 + case PLATFORM_TYPE_CYPRESS_GA2: + gpio_rest_mux = gpio_base + cypress_ga2_gpio_rest_mux; + ioexp_layout = cypress_ga2_ioexp_layout; + port_layout = cypress_ga2_port_layout; + ioexp_total = ARRAY_SIZE(cypress_ga2_ioexp_layout); + port_total = ARRAY_SIZE(cypress_ga2_port_layout); + break; +#endif +#ifdef SWPS_CYPRESS_BAI + case PLATFORM_TYPE_CYPRESS_BAI: + gpio_rest_mux = gpio_base + cypress_b_gpio_rest_mux; + ioexp_layout = cypress_b_ioexp_layout; + port_layout = cypress_b_port_layout; + ioexp_total = ARRAY_SIZE(cypress_b_ioexp_layout); + port_total = ARRAY_SIZE(cypress_b_port_layout); + break; +#endif +#ifdef SWPS_REDWOOD_FSL + case PLATFORM_TYPE_REDWOOD_FSL: + gpio_rest_mux = gpio_base + redwood_fsl_gpio_rest_mux; + ioexp_layout = redwood_fsl_ioexp_layout; + port_layout = redwood_fsl_port_layout; + ioexp_total = ARRAY_SIZE(redwood_fsl_ioexp_layout); + port_total = ARRAY_SIZE(redwood_fsl_port_layout); + break; +#endif +#ifdef SWPS_TAHOE + case PLATFORM_TYPE_TAHOE: + gpio_rest_mux = gpio_base + tahoe_gpio_rest_mux; + ioexp_layout = tahoe_ioexp_layout; + port_layout = tahoe_port_layout; + ioexp_total = ARRAY_SIZE(tahoe_ioexp_layout); + port_total = ARRAY_SIZE(tahoe_port_layout); + break; +#endif +#ifdef SWPS_SEQUOIA + case PLATFORM_TYPE_SEQUOIA_GA: + gpio_rest_mux = gpio_base + sequoia_gpio_rest_mux; + ioexp_layout = sequoia_ioexp_layout; + port_layout = sequoia_port_layout; + ioexp_total = ARRAY_SIZE(sequoia_ioexp_layout); + port_total = ARRAY_SIZE(sequoia_port_layout); + break; +#endif +#ifdef SWPS_LAVENDER + case PLATFORM_TYPE_LAVENDER_GA: + case PLATFORM_TYPE_LAVENDER_ONL: + gpio_rest_mux = gpio_base + lavender_gpio_rest_mux; + ioexp_layout = lavender_ioexp_layout; + port_layout = lavender_port_layout; + ioexp_total = ARRAY_SIZE(lavender_ioexp_layout); + port_total = ARRAY_SIZE(lavender_port_layout); + break; +#endif +#ifdef SWPS_COTTONWOOD_RANGELEY + case PLATFORM_TYPE_COTTONWOOD_RANGELEY: + gpio_rest_mux = gpio_base + cottonwood_rangeley_gpio_rest_mux; + ioexp_layout = cottonwood_rangeley_ioexp_layout; + port_layout = cottonwood_rangeley_port_layout; + ioexp_total = ARRAY_SIZE(cottonwood_rangeley_ioexp_layout); + port_total = ARRAY_SIZE(cottonwood_rangeley_port_layout); + break; +#endif +#ifdef SWPS_MAPLE_GA + case PLATFORM_TYPE_MAPLE_GA: + gpio_rest_mux = gpio_base + maple_ga_gpio_rest_mux; + ioexp_layout = maple_ga_ioexp_layout; + port_layout = maple_ga_port_layout; + ioexp_total = ARRAY_SIZE(maple_ga_ioexp_layout); + port_total = ARRAY_SIZE(maple_ga_port_layout); + break; +#endif +#ifdef SWPS_MAPLE_B + case PLATFORM_TYPE_MAPLE_B: + gpio_rest_mux = gpio_base + maple_b_gpio_rest_mux; + ioexp_layout = maple_b_ioexp_layout; + port_layout = maple_b_port_layout; + ioexp_total = ARRAY_SIZE(maple_b_ioexp_layout); + port_total = ARRAY_SIZE(maple_b_port_layout); + break; +#endif +#ifdef SWPS_MAPLE_J + case PLATFORM_TYPE_MAPLE_J: + gpio_rest_mux = gpio_base + maple_j_gpio_rest_mux; + ioexp_layout = maple_j_ioexp_layout; + port_layout = maple_j_port_layout; + ioexp_total = ARRAY_SIZE(maple_j_ioexp_layout); + port_total = ARRAY_SIZE(maple_j_port_layout); + break; +#endif +#ifdef SWPS_GULMOHAR + case PLATFORM_TYPE_GULMOHAR_GA: + gpio_rest_mux = gpio_base + gulmohar_gpio_rest_mux; + ioexp_layout = gulmohar_ioexp_layout; + port_layout = gulmohar_port_layout; + ioexp_total = ARRAY_SIZE(gulmohar_ioexp_layout); + port_total = ARRAY_SIZE(gulmohar_port_layout); + break; +#endif +#ifdef SWPS_GULMOHAR_2T_EVT1 + case PLATFORM_TYPE_GULMOHAR_2T_EVT1_GA: + gpio_rest_mux = gpio_base + gulmohar_2t_evt1_gpio_rest_mux; + ioexp_layout = gulmohar_2t_evt1_ioexp_layout; + port_layout = gulmohar_2t_evt1_port_layout; + ioexp_total = ARRAY_SIZE(gulmohar_2t_evt1_ioexp_layout); + port_total = ARRAY_SIZE(gulmohar_2t_evt1_port_layout); + break; +#endif +#ifdef SWPS_PEONY_SFP + case PLATFORM_TYPE_PEONY_SFP_GA: + gpio_rest_mux = gpio_base + peony_sfp_gpio_rest_mux; + ioexp_layout = peony_sfp_ioexp_layout; + port_layout = peony_sfp_port_layout; + ioexp_total = ARRAY_SIZE(peony_sfp_ioexp_layout); + port_total = ARRAY_SIZE(peony_sfp_port_layout); + break; +#endif +#ifdef SWPS_PEONY_COPPER + case PLATFORM_TYPE_PEONY_COPPER_GA: + gpio_rest_mux = gpio_base + peony_copper_gpio_rest_mux; + ioexp_layout = peony_copper_ioexp_layout; + port_layout = peony_copper_port_layout; + ioexp_total = ARRAY_SIZE(peony_copper_ioexp_layout); + port_total = ARRAY_SIZE(peony_copper_port_layout); + break; +#endif +#ifdef SWPS_CEDAR_GA + case PLATFORM_TYPE_CEDAR_GA: + gpio_rest_mux = gpio_base + cedar_ga_gpio_rest_mux; + ioexp_layout = cedar_ga_ioexp_layout; + port_layout = cedar_ga_port_layout; + ioexp_total = ARRAY_SIZE(cedar_ga_ioexp_layout); + port_total = ARRAY_SIZE(cedar_ga_port_layout); + break; +#endif + + default: + SWPS_ERR(" Invalid platform: %d (%s)\n", + platform_p->id, platform_p->name); + return -1; + } + SWPS_INFO("Start to initial platform: %d (%s)\n", + platform_p->id, platform_p->name); + return 0; +} + + +/* ========== Functions for objects operations ========== + */ +static int +__detect_issues_port(int minor_num) { + + struct transvr_obj_s *tobj_p; + int port_id = port_layout[minor_num].port_id; + char port_name[32] = "ERR"; + char *i2c_emsg = "detected bad transceiver/cable"; + + memset(port_name, 0, sizeof(port_name)); + snprintf(port_name, sizeof(port_name), "%s%d", SWP_DEV_PORT, port_id); + tobj_p = _get_transvr_obj(port_name); + if (!tobj_p) { + SWPS_INFO("%s: tobj_p is NULL :%d\n", __func__, minor_num); + return -1; + } + if (resync_channel_tier_2(tobj_p) < 0) { + if (check_channel_tier_1() < 0) { + goto get_target_issues_port; + } + } + /* Re-check again for i2c-gpio special case */ + if (check_channel_tier_1() < 0) { + goto get_target_issues_port; + } + return 0; + +get_target_issues_port: + alarm_msg_2_user(tobj_p, i2c_emsg); + return -2; +} + + +static int +_detect_issues_port(void) { + /* OK : retrun -1; + * Fail: return fail at which minor number (0~N) + */ + char *emsg = "ERR"; + int minor = 0; + int minor_2st = 1; + + /* Force moving the initial channel pointer + * Filter out case of fail at minor-0 port + */ + while (minor_2st < port_total) { + minor = minor_2st; + if (__detect_issues_port(minor_2st) < 0) { + emsg = "detect minor_2st fail"; + goto err_p_detect_issues_port; + } + minor_2st += 8; + } + /* Scan all port */ + for (minor=0; minor:%d\n", __func__, emsg, minor_err); + return -1; +} + + +static int +check_transvr_obj_one(char *dev_name){ + /* [Return] + * 0 : Doesn't need to take care + * -1 : Single error + * -2 : Critical error (I2C topology die) + * -9 : Internal error + */ + struct transvr_obj_s *tobj_p = NULL; + int retval = -9; + + tobj_p = _get_transvr_obj(dev_name); + if (!tobj_p) { + SWPS_ERR("%s: %s _get_transvr_obj fail\n", + __func__, dev_name); + return -9; + } + /* Check transceiver current status */ + lock_transvr_obj(tobj_p); + retval = tobj_p->check(tobj_p); + unlock_transvr_obj(tobj_p); + switch (retval) { + case 0: + case ERR_TRANSVR_UNPLUGGED: + case ERR_TRNASVR_BE_ISOLATED: + case ERR_TRANSVR_TASK_BUSY: + return 0; + + case ERR_TRANSVR_I2C_CRASH: + default: + break; + } + /* Identify abnormal case */ + if (check_channel_tier_1() < 0) { + SWPS_DEBUG("%s: %s critical error :%d\n", + __func__, dev_name, retval); + return -2; + } + SWPS_DEBUG("%s: %s single error :%d\n", + __func__, dev_name, retval); + return -1; +} + + +static int +check_transvr_objs(void){ + + char dev_name[32]; + int port_id, err_code; + int minor_curr = 0; + + for (minor_curr=0; minor_curr:%d\n", + __func__, dev_name, err_code); + break; + } + } + return 0; + +err_check_transvr_objs: + SWPS_ERR("%s: %s reset_i2c_topology fail.\n", + __func__, dev_name); + return -1; +} + + +static void +swp_polling_worker(struct work_struct *work){ + + /* Reset I2C */ + if (flag_i2c_reset) { + goto polling_reset_i2c; + } + /* Check IOEXP */ + if (check_ioexp_objs() < 0) { + goto polling_reset_i2c; + } + /* Check transceiver */ + if (check_transvr_objs() < 0) { + SWPS_DEBUG("%s: check_transvr_objs fail.\n", __func__); + flag_i2c_reset = 1; + } + goto polling_schedule_round; + +polling_reset_i2c: + SWPS_DEBUG("%s: reset_i2c_topology start.\n", __func__); + if (reset_i2c_topology() < 0) { + SWPS_ERR("%s: reset i2c fail!\n", __func__); + flag_i2c_reset = 1; + } else { + SWPS_DEBUG("%s: reset_i2c_topology OK.\n", __func__); + flag_i2c_reset = 0; + } +polling_schedule_round: + schedule_delayed_work(&swp_polling, _get_polling_period()); +} + + +/* ========== Functions for register something ========== + */ +static int +register_transvr_common_attr(struct device *device_p){ + + char *err_attr = NULL; + + if (device_create_file(device_p, &dev_attr_id) < 0) { + err_attr = "dev_attr_id"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_ext_id) < 0) { + err_attr = "dev_attr_ext_id"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_connector) < 0) { + err_attr = "dev_attr_connector"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_vendor_name) < 0) { + err_attr = "dev_attr_vendor_name"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_vendor_pn) < 0) { + err_attr = "dev_attr_vendor_pn"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_vendor_rev) < 0) { + err_attr = "dev_attr_vendor_rev"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_vendor_sn) < 0) { + err_attr = "dev_attr_vendor_sn"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_br) < 0) { + err_attr = "dev_attr_br"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_len_smf) < 0) { + err_attr = "dev_attr_len_smf"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_len_om1) < 0) { + err_attr = "dev_attr_len_om1"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_len_om2) < 0) { + err_attr = "dev_attr_len_om2"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_len_om3) < 0) { + err_attr = "dev_attr_len_om3"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_len_om4) < 0) { + err_attr = "dev_attr_len_om4"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_comp_extend) < 0) { + err_attr = "dev_attr_comp_extend"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_comp_eth) < 0) { + err_attr = "dev_attr_comp_eth"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_comp_rev) < 0) { + err_attr = "dev_attr_comp_rev"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_info) < 0) { + err_attr = "dev_attr_info"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_if_type) < 0) { + err_attr = "dev_attr_if_type"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_if_speed) < 0) { + err_attr = "dev_attr_if_speed"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_if_lane) < 0) { + err_attr = "dev_attr_if_lane"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_temperature) < 0) { + err_attr = "dev_attr_temperature"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_voltage) < 0) { + err_attr = "dev_attr_voltage"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_tx_bias) < 0) { + err_attr = "dev_attr_tx_bias"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_tx_power) < 0) { + err_attr = "dev_attr_tx_power"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_rx_power) < 0) { + err_attr = "dev_attr_rx_power"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_tx_eq) < 0) { + err_attr = "dev_attr_tx_eq"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_rx_em) < 0) { + err_attr = "dev_attr_rx_em"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_wavelength) < 0) { + err_attr = "dev_attr_wavelength"; + goto err_transvr_comm_attr; + } + return 0; + +err_transvr_comm_attr: + SWPS_ERR("%s: %s\n", __func__, err_attr); + return -1; +} + +static int +register_transvr_sfp_attr(struct device *device_p){ + + char *err_attr = NULL; + + if (register_transvr_common_attr(device_p) < 0) { + err_attr = "register_transvr_common_attr"; + goto err_transvr_sfp_attr; + } + if (device_create_file(device_p, &dev_attr_comp_eth_10) < 0) { + err_attr = "dev_attr_comp_eth_10"; + goto err_transvr_sfp_attr; + } + if (device_create_file(device_p, &dev_attr_len_sm) < 0) { + err_attr = "dev_attr_len_sm"; + goto err_transvr_sfp_attr; + } + if (device_create_file(device_p, &dev_attr_rate_id) < 0) { + err_attr = "dev_attr_rate_id"; + goto err_transvr_sfp_attr; + } + if (device_create_file(device_p, &dev_attr_soft_rs0) < 0) { + err_attr = "dev_attr_soft_rs0"; + goto err_transvr_sfp_attr; + } + if (device_create_file(device_p, &dev_attr_soft_rs1) < 0) { + err_attr = "dev_attr_soft_rs1"; + goto err_transvr_sfp_attr; + } + if (device_create_file(device_p, &dev_attr_extphy_offset) < 0) { + err_attr = "dev_attr_extphy_offset"; + goto err_transvr_sfp_attr; + } + if (device_create_file(device_p, &dev_attr_extphy_reg) < 0) { + err_attr = "dev_attr_extphy_reg"; + goto err_transvr_sfp_attr; + } + return 0; + +err_transvr_sfp_attr: + SWPS_ERR("%s: %s\n", __func__, err_attr); + return -1; +} + + +static int +register_transvr_qsfp_attr(struct device *device_p){ + + char *err_attr = NULL; + + if (register_transvr_common_attr(device_p) < 0) { + err_attr = "register_transvr_common_attr"; + goto err_transvr_qsfp_attr; + } + if (device_create_file(device_p, &dev_attr_comp_eth_10_40) < 0) { + err_attr = "dev_attr_comp_eth_10_40"; + goto err_transvr_qsfp_attr; + } + if (device_create_file(device_p, &dev_attr_power_cls) < 0) { + err_attr = "dev_attr_power_cls"; + goto err_transvr_qsfp_attr; + } + if (device_create_file(device_p, &dev_attr_soft_rx_los) < 0) { + err_attr = "soft_rx_los"; + goto err_transvr_qsfp_attr; + } + if (device_create_file(device_p, &dev_attr_soft_tx_disable) < 0) { + err_attr = "soft_tx_disable"; + goto err_transvr_qsfp_attr; + } + if (device_create_file(device_p, &dev_attr_auto_tx_disable) < 0) { + err_attr = "auto_tx_disable"; + goto err_transvr_qsfp_attr; + } + if (device_create_file(device_p, &dev_attr_soft_tx_fault) < 0) { + err_attr = "soft_tx_fault"; + goto err_transvr_qsfp_attr; + } + return 0; + +err_transvr_qsfp_attr: + SWPS_ERR("%s: %s\n", __func__, err_attr); + return -1; +} + + +static int +register_transvr_qsfp28_attr(struct device *device_p){ + + char *err_attr = NULL; + + if (register_transvr_qsfp_attr(device_p) < 0){ + err_attr = "register_transvr_qsfp_attr"; + goto err_transvr_qsfp28_attr; + } + if (device_create_file(device_p, &dev_attr_cdr) < 0) { + err_attr = "dev_attr_cdr"; + goto err_transvr_qsfp28_attr; + } + if (device_create_file(device_p, &dev_attr_rx_am) < 0) { + err_attr = "dev_attr_rx_am"; + goto err_transvr_qsfp28_attr; + } + return 0; + +err_transvr_qsfp28_attr: + SWPS_ERR("%s: %s\n", __func__, err_attr); + return -1; +} + + +static int +register_transvr_attr(struct device *device_p, + struct transvr_obj_s *transvr_obj){ + + switch (transvr_obj->layout){ + case TRANSVR_TYPE_SFP: + if (register_transvr_sfp_attr(device_p) < 0){ + goto err_reg_tvr_attr; + } + break; + case TRANSVR_TYPE_QSFP: + case TRANSVR_TYPE_QSFP_PLUS: + if (register_transvr_qsfp_attr(device_p) < 0){ + goto err_reg_tvr_attr; + } + break; + case TRANSVR_TYPE_QSFP_28: + if (register_transvr_qsfp28_attr(device_p) < 0){ + goto err_reg_tvr_attr; + } + break; + default: + goto err_reg_tvr_attr; + } + return 0; + +err_reg_tvr_attr: + SWPS_ERR("%s: fail! type=%d \n", __func__, transvr_obj->type); + return -1; +} + + +static int +register_ioexp_attr_sfp_1(struct device *device_p){ + /* Support machine type: + * - SFP : Magnolia + */ + char *err_attr = NULL; + + if (device_create_file(device_p, &dev_attr_present) < 0) { + err_attr = "dev_attr_present"; + goto err_ioexp_sfp1_attr; + } + if (device_create_file(device_p, &dev_attr_tx_fault) < 0) { + err_attr = "dev_attr_tx_fault"; + goto err_ioexp_sfp1_attr; + } + if (device_create_file(device_p, &dev_attr_rxlos) < 0) { + err_attr = "dev_attr_rxlos"; + goto err_ioexp_sfp1_attr; + } + if (device_create_file(device_p, &dev_attr_tx_disable) < 0) { + err_attr = "dev_attr_tx_disable"; + goto err_ioexp_sfp1_attr; + } + return 0; + +err_ioexp_sfp1_attr: + SWPS_ERR("Add device attribute:%s failure! \n",err_attr); + return -1; +} + + +static int +register_ioexp_attr_sfp_2(struct device *device_p){ + /* Support machine type: + * - SFP28 : Cypress + */ + char *err_attr = NULL; + + if (register_ioexp_attr_sfp_1(device_p) < 0){ + goto err_ioexp_sfp2_attr; + } + if (device_create_file(device_p, &dev_attr_hard_rs0) < 0) { + err_attr = "dev_attr_hard_rs0"; + goto err_ioexp_sfp2_attr; + } + if (device_create_file(device_p, &dev_attr_hard_rs1) < 0) { + err_attr = "dev_attr_hard_rs1"; + goto err_ioexp_sfp2_attr; + } + return 0; + +err_ioexp_sfp2_attr: + SWPS_ERR("Add device attribute:%s failure! \n",err_attr); + return -1; +} + + +static int +register_ioexp_attr_qsfp_1(struct device *device_p){ + /* Support machine type: + * - QSFP : Magnolia, Redwood, Hudson32i + * - QSFP+ : Magnolia, Redwood, Hudson32i + * - QSFP28: Redwood + */ + char *err_attr = NULL; + + if (device_create_file(device_p, &dev_attr_present) < 0) { + err_attr = "dev_attr_present"; + goto err_ioexp_qsfp1_attr; + } + if (device_create_file(device_p, &dev_attr_reset) < 0) { + err_attr = "dev_attr_reset"; + goto err_ioexp_qsfp1_attr; + } + if (device_create_file(device_p, &dev_attr_lpmod) < 0) { + err_attr = "dev_attr_lpmod"; + goto err_ioexp_qsfp1_attr; + } + if (device_create_file(device_p, &dev_attr_modsel) < 0) { + err_attr = "dev_attr_modsel"; + goto err_ioexp_qsfp1_attr; + } + return 0; + +err_ioexp_qsfp1_attr: + SWPS_ERR("Add device attribute:%s failure! \n",err_attr); + return -1; +} + + +static int +register_modctl_attr(struct device *device_p){ + + char *err_msg = NULL; + + if (device_create_file(device_p, &dev_attr_platform) < 0) { + err_msg = "dev_attr_platform"; + goto err_reg_modctl_attr; + } + if (device_create_file(device_p, &dev_attr_version) < 0) { + err_msg = "dev_attr_version"; + goto err_reg_modctl_attr; + } + if (device_create_file(device_p, &dev_attr_status) < 0) { + err_msg = "dev_attr_status"; + goto err_reg_modctl_attr; + } + if (device_create_file(device_p, &dev_attr_reset_i2c) < 0) { + err_msg = "dev_attr_reset_i2c"; + goto err_reg_modctl_attr; + } + if (device_create_file(device_p, &dev_attr_reset_swps) < 0) { + err_msg = "dev_attr_reset_swps"; + goto err_reg_modctl_attr; + } + if (device_create_file(device_p, &dev_attr_auto_config) < 0) { + err_msg = "dev_attr_auto_config"; + goto err_reg_modctl_attr; + } + if (device_create_file(device_p, &dev_attr_block_poll) < 0) { + err_msg = "dev_attr_block_poll"; + goto err_reg_modctl_attr; + } + if (device_create_file(device_p, &dev_attr_io_no_init) < 0) { + err_msg = "dev_attr_io_no_init"; + goto err_reg_modctl_attr; + } + + return 0; + +err_reg_modctl_attr: + SWPS_ERR("%s: %s\n", __func__, err_msg); + return -1; +} + + +static int +register_ioexp_attr(struct device *device_p, + struct transvr_obj_s *transvr_obj){ + + char *err_msg = "ERR"; + + switch (transvr_obj->ioexp_obj_p->ioexp_type){ + case IOEXP_TYPE_MAGINOLIA_NAB: + case IOEXP_TYPE_MAGINOLIA_4AB: + case CPLD_TYPE_COTTONWOOD: + if (register_ioexp_attr_sfp_1(device_p) < 0){ + err_msg = "register_ioexp_attr_sfp_1 fail"; + goto err_reg_ioexp_attr; + } + break; + + case IOEXP_TYPE_MAPLE_NABC: + case IOEXP_TYPE_GULMOHAR_NABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC: + case IOEXP_TYPE_SFP_8P_LAYOUT_1: + if (register_ioexp_attr_sfp_2(device_p) < 0){ + err_msg = "register_ioexp_attr_sfp_2 fail"; + goto err_reg_ioexp_attr; + } + break; + + case IOEXP_TYPE_MAGINOLIA_7AB: + case IOEXP_TYPE_SPRUCE_7AB: + case IOEXP_TYPE_CYPRESS_7ABC: + case IOEXP_TYPE_REDWOOD_P01P08: + case IOEXP_TYPE_REDWOOD_P09P16: + case IOEXP_TYPE_HUDSON32IGA_P01P08: + case IOEXP_TYPE_HUDSON32IGA_P09P16: + case IOEXP_TYPE_TAHOE_5A: + case IOEXP_TYPE_TAHOE_6ABC: + case IOEXP_TYPE_SEQUOIA_NABC: + case IOEXP_TYPE_LAVENDER_P65: + case IOEXP_TYPE_MAPLE_0ABC: + case IOEXP_TYPE_GULMOHAR_7ABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC: + case IOEXP_TYPE_QSFP_6P_LAYOUT_1: + case IOEXP_TYPE_CEDAR_0ABC: + if (register_ioexp_attr_qsfp_1(device_p) < 0){ + err_msg = "register_ioexp_attr_qsfp_1 fail"; + goto err_reg_ioexp_attr; + } + break; + + default: + err_msg = "Unknow type"; + goto err_reg_ioexp_attr; + } + return 0; + +err_reg_ioexp_attr: + SWPS_ERR("%s: %s :%d \n", + __func__, err_msg, transvr_obj->ioexp_obj_p->ioexp_type); + return -1; +} + + +static int +register_modctl_device(void) { + + struct device *device_p = NULL; + int minor_comm = 0; /* Default minor number for common device */ + dev_t dev_num = MKDEV(ctl_major, minor_comm); + char *err_msg = "ERROR"; + + device_p = device_create(swp_class_p, /* struct class *cls */ + NULL, /* struct device *parent */ + dev_num, /* dev_t devt */ + NULL, /* void *private_data */ + SWP_DEV_MODCTL); /* const char *fmt */ + if (IS_ERR(device_p)){ + err_msg = "device_create fail"; + goto err_register_modctl_device_1; + } + if (register_modctl_attr(device_p) < 0) { + err_msg = "register_modctl_attr fail"; + goto err_register_modctl_device_2; + } + return 0; + +err_register_modctl_device_2: + device_unregister(device_p); + device_destroy(swp_class_p, dev_num); +err_register_modctl_device_1: + SWPS_ERR("%s: %s\n", __func__, err_msg); + return -1; +} + + +static int +register_port_device(char *dev_name, + dev_t dev_num, + struct transvr_obj_s *transvr_obj){ + + struct device *device_p = NULL; + device_p = device_create(swp_class_p, /* struct class *cls */ + NULL, /* struct device *parent */ + dev_num, /* dev_t devt */ + transvr_obj, /* void *private_data */ + dev_name); /* const char *fmt */ + if (IS_ERR(device_p)){ + goto err_regswp_create_dev; + } + if (register_transvr_attr(device_p, transvr_obj) < 0){ + goto err_regswp_reg_attr; + } + if (register_ioexp_attr(device_p, transvr_obj) < 0){ + goto err_regswp_reg_attr; + } + return 0; + +err_regswp_reg_attr: + device_unregister(device_p); + device_destroy(swp_class_p, dev_num); +err_regswp_create_dev: + SWPS_ERR("%s fail! :%s\n", __func__, dev_name); + return -1; +} + + +static int +register_swp_module(void){ + + dev_t ctl_devt = 0; + dev_t port_devt = 0; + //int dev_total = port_total + 1; /* char_dev for module control */ + + /* Register device number */ + if (alloc_chrdev_region(&ctl_devt, 0, 1, SWP_DEV_MODCTL) < 0){ + SWPS_WARN("Allocate CTL MAJOR failure! \n"); + goto err_register_swp_module_1; + } + if (alloc_chrdev_region(&port_devt, 0, port_total, SWP_CLS_NAME) < 0){ + SWPS_WARN("Allocate PORT MAJOR failure! \n"); + goto err_register_swp_module_2; + } + ctl_major = MAJOR(ctl_devt); + port_major = MAJOR(port_devt); + + /* Create class object */ + swp_class_p = class_create(THIS_MODULE, SWP_CLS_NAME); + if (IS_ERR(swp_class_p)) { + SWPS_ERR("Create class failure! \n"); + goto err_register_swp_module_3; + } + return 0; + +err_register_swp_module_3: + unregister_chrdev_region(MKDEV(port_major, 0), port_total); +err_register_swp_module_2: + unregister_chrdev_region(MKDEV(ctl_major, 0), 1); +err_register_swp_module_1: + return -1; +} + + +/* ========== Module initial relate ========== + */ +static int +create_ioexp_objs(void) { + + int i, run_mod; + + /* Clean IOEXP object */ + clean_ioexp_objs(); + /* Get running mode */ + run_mod = IOEXP_MODE_DIRECT; + if (SWP_POLLING_ENABLE){ + run_mod = IOEXP_MODE_POLLING; + } + /* Create IOEXP object */ + for(i=0; i devlen_max) { + snprintf(err_msg, sizeof(err_msg), + "SWP_DEV_PORT too long!"); + goto err_initport_create_tranobj; + } + memset(dev_name, 0, sizeof(dev_name)); + snprintf(dev_name, devlen_max, "%s%d", SWP_DEV_PORT, port_id); + /* Create transceiver object */ + ioexp_obj_p = get_ioexp_obj(ioexp_id); + if (!ioexp_obj_p){ + snprintf(err_msg, sizeof(err_msg), + "IOEXP object:%d not exist", ioexp_id); + goto err_initport_create_tranobj; + } + transvr_obj_p = create_transvr_obj(dev_name, chan_id, ioexp_obj_p, + ioexp_virt_offset, transvr_type, + chipset_type, run_mod); + if (!transvr_obj_p){ + snprintf(err_msg, sizeof(err_msg), + "Create transceiver object fail :%s", dev_name); + goto err_initport_create_tranobj; + } + /* Setup Lane_ID mapping */ + i = ARRAY_SIZE(port_layout[minor_curr].lane_id); + j = ARRAY_SIZE(transvr_obj_p->lane_id); + if (i != j) { + snprintf(err_msg, sizeof(err_msg), + "Lane_id size inconsistent %d/%d", i, j); + goto err_initport_reg_device; + } + memcpy(transvr_obj_p->lane_id, port_layout[minor_curr].lane_id, i*sizeof(int)); + /* Create and register device object */ + if (register_port_device(dev_name, MKDEV(port_major, minor_curr), transvr_obj_p) < 0){ + snprintf(err_msg, sizeof(err_msg), + "register_port_device fail"); + goto err_initport_reg_device; + } + /* Setup device_ptr of transvr_obj */ + dev_p = get_swpdev_by_name(dev_name); + if (!dev_p){ + snprintf(err_msg, sizeof(err_msg), + "get_swpdev_by_name fail"); + goto err_initport_reg_device; + } + transvr_obj_p->transvr_dev_p = dev_p; + /* Success */ + ok_count++; + } + SWPS_INFO("%s: initialed %d port-dev\n",__func__, ok_count); + return 0; + +err_initport_reg_device: + kfree(transvr_obj_p); +err_initport_create_tranobj: + clean_port_objs(); + SWPS_ERR("%s: %s", __func__, err_msg); + SWPS_ERR("Dump: :%d :%d :%d :%d :%d :%d\n", + port_id, chan_id, ioexp_id, ioexp_virt_offset, transvr_type, run_mod); + return -1; +} + + +static int +init_dev_topology(void){ + + int err; + char *emsg = "ERR"; + flag_mod_state = SWP_STATE_NORMAL; + + err = init_ioexp_objs(); + switch(err){ + case 0: /* Normal */ + SWPS_DEBUG("%s: normal case\n", __func__); + break; + + case -1: /* topology error */ + SWPS_DEBUG("%s: detect tier-1 topology initial failure :%d\n", + __func__, err); + /* Reset and isolate */ + err = reset_i2c_topology(); + if (err < 0) { + emsg = "reset i2c topology fail"; + goto err_init_dev_topology; + } + /* Re-initial again */ + err = init_ioexp_objs(); + if (err < 0) { + emsg = "re-init ioexp objects fail"; + goto err_init_dev_topology; + } + break; + + case -2: /* Internal error */ + SWPS_DEBUG("%s: internal error case\n", __func__); + err = -2; + emsg = "internal error"; + goto err_init_dev_topology; + + default: + SWPS_DEBUG("%s: undefined error case\n", __func__); + emsg = "undefined error case"; + goto err_init_dev_topology; + } + SWPS_DEBUG("%s: initial I2C topology success\n", __func__); + return 0; + +err_init_dev_topology: + SWPS_ERR("%s: %s :%d\n", __func__, emsg, err); + return -1; +} + + +static int +init_polling_task(void){ + + if (SWP_POLLING_ENABLE){ + schedule_delayed_work(&swp_polling, _get_polling_period()); + } + return 0; +} + + +static int +init_swps_common(void){ + + char *err_msg = "ERR"; + + block_polling = 0; + auto_config = 0; + if ((SWP_AUTOCONFIG_ENABLE) && (SWP_POLLING_ENABLE)){ + auto_config = 1; + } + if (register_modctl_device() < 0) { + err_msg = "register_modctl_device fail"; + goto err_init_swps_common_1; + } + if (_update_auto_config_2_trnasvr() < 0) { + err_msg = "_update_auto_config_2_trnasvr fail"; + goto err_init_swps_common_1; + } + if (init_polling_task() < 0){ + err_msg = "init_polling_task fail"; + goto err_init_swps_common_1; + } + return 0; + +err_init_swps_common_1: + clean_swps_common(); + SWPS_ERR("%s: %s\n", __func__, err_msg); + return -1; +} + + +static int __init +swp_module_init(void){ + + if (get_platform_type() < 0){ + goto err_init_out; + } + if (get_layout_info() < 0){ + goto err_init_out; + } + if (register_swp_module() < 0){ + goto err_init_out; + } + if (create_ioexp_objs() < 0){ + goto err_init_ioexp; + } + if (create_port_objs() < 0){ + goto err_init_portobj; + } + if (init_mux_objs(gpio_rest_mux) < 0){ + goto err_init_mux; + } + if (init_dev_topology() < 0){ + goto err_init_topology; + } + if (init_swps_common() < 0){ + goto err_init_topology; + } + SWPS_INFO("Inventec switch-port module V.%s initial success.\n", SWP_VERSION); + return 0; + + +err_init_topology: + clean_mux_objs(); +err_init_mux: + clean_port_objs(); +err_init_portobj: + clean_ioexp_objs(); +err_init_ioexp: + class_destroy(swp_class_p); + unregister_chrdev_region(MKDEV(ctl_major, 0), 1); + unregister_chrdev_region(MKDEV(port_major, 0), port_total); +err_init_out: + SWPS_ERR("Inventec switch-port module V.%s initial failure.\n", SWP_VERSION); + return -1; +} + + +static void __exit +swp_module_exit(void){ + + clean_swps_common(); + clean_port_objs(); + clean_ioexp_objs(); + clean_mux_objs(); + class_destroy(swp_class_p); + unregister_chrdev_region(MKDEV(ctl_major, 0), 1); + unregister_chrdev_region(MKDEV(port_major, 0), port_total); + SWPS_INFO("Remove Inventec switch-port module success.\n"); +} + + +/* Module information */ +MODULE_AUTHOR(SWP_AUTHOR); +MODULE_DESCRIPTION(SWP_DESC); +MODULE_VERSION(SWP_VERSION); +MODULE_LICENSE(SWP_LICENSE); +MODULE_SOFTDEP("pre: inv_platform"); +module_param(gpio_base, int, S_IRUGO); + +module_init(swp_module_init); +module_exit(swp_module_exit); + + + + + + + + + + + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_swps.h b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_swps.h new file mode 100644 index 000000000000..00dc1fde0d8e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/inv_swps.h @@ -0,0 +1,1791 @@ +#ifndef INV_SWPS_H +#define INV_SWPS_H + +#include "transceiver.h" +#include "io_expander.h" +#include "inv_mux.h" + +/* Module settings */ +#define SWP_CLS_NAME "swps" +#define SWP_DEV_PORT "port" +#define SWP_DEV_MODCTL "module" +#define SWP_RESET_PWD "inventec" +#define SWP_POLLING_PERIOD (300) /* msec */ +#define SWP_POLLING_ENABLE (1) +#define SWP_AUTOCONFIG_ENABLE (1) + +/* Module information */ +#define SWP_AUTHOR "Neil " +#define SWP_DESC "Inventec port and transceiver driver" +#define SWP_VERSION "4.3.10" +#define SWP_LICENSE "GPL" + +/* Module status define */ +#define SWP_STATE_NORMAL (0) +#define SWP_STATE_I2C_DIE (-91) + +/* [Note]: + * Functions and mechanism for auto-detect platform type is ready, + * But HW and BIOS not ready! We need to wait them. + * So, please do not use PLATFORM_TYPE_AUTO until they are ready. + * (2016.06.13) + */ +#define PLATFORM_TYPE_AUTO (100) +#define PLATFORM_TYPE_MAGNOLIA (111) +#define PLATFORM_TYPE_MAGNOLIA_FNC (112) +#define PLATFORM_TYPE_REDWOOD (121) +#define PLATFORM_TYPE_REDWOOD_FSL (122) +#define PLATFORM_TYPE_HUDSON32I_GA (131) +#define PLATFORM_TYPE_SPRUCE (141) +#define PLATFORM_TYPE_CYPRESS_GA1 (151) /* Up -> Down */ +#define PLATFORM_TYPE_CYPRESS_GA2 (152) /* Down -> Up */ +#define PLATFORM_TYPE_CYPRESS_BAI (153) /* Down -> Up */ +#define PLATFORM_TYPE_TAHOE (161) +#define PLATFORM_TYPE_SEQUOIA_GA (171) +#define PLATFORM_TYPE_LAVENDER_GA (181) +#define PLATFORM_TYPE_LAVENDER_ONL (182) +#define PLATFORM_TYPE_COTTONWOOD_RANGELEY (191) +#define PLATFORM_TYPE_MAPLE_GA (201) +#define PLATFORM_TYPE_GULMOHAR_GA (202) +#define PLATFORM_TYPE_GULMOHAR_2T_EVT1_GA (203) +#define PLATFORM_TYPE_PEONY_SFP_GA (204) +#define PLATFORM_TYPE_PEONY_COPPER_GA (205) +#define PLATFORM_TYPE_PEONY_AUTO (206) +#define PLATFORM_TYPE_MAPLE_B (207) +#define PLATFORM_TYPE_MAPLE_J (208) +#define PLATFORM_TYPE_CEDAR_GA (209) +/* Current running platfrom */ +#define PLATFORM_SETTINGS PLATFORM_TYPE_CEDAR_GA + +/* Define platform flag and kernel version */ +#if (PLATFORM_SETTINGS == PLATFORM_TYPE_MAGNOLIA) + #define SWPS_MAGNOLIA (1) + #define SWPS_KERN_VER_BF_3_8 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_MAGNOLIA_FNC) + #define SWPS_MAGNOLIA (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_REDWOOD) + #define SWPS_REDWOOD (1) + #define SWPS_KERN_VER_BF_3_8 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_REDWOOD_FSL) + #define SWPS_REDWOOD_FSL (1) + #define SWPS_KERN_VER_BF_3_8 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_HUDSON32I_GA) + #define SWPS_HUDSON32I_GA (1) + #define SWPS_KERN_VER_BF_3_8 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_SPRUCE) + #define SWPS_SPRUCE (1) + #define SWPS_KERN_VER_BF_3_8 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_CYPRESS_GA1) + #define SWPS_CYPRESS_GA1 (1) + #define SWPS_KERN_VER_BF_3_8 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_CYPRESS_GA2) + #define SWPS_CYPRESS_GA2 (1) + #define SWPS_KERN_VER_BF_3_8 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_CYPRESS_BAI) + #define SWPS_CYPRESS_BAI (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_TAHOE) + #define SWPS_TAHOE (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_SEQUOIA_GA) + #define SWPS_SEQUOIA (1) + #define SWPS_KERN_VER_BF_3_8 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_LAVENDER_GA) + #define SWPS_LAVENDER (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_LAVENDER_ONL) + #define SWPS_LAVENDER (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_COTTONWOOD_RANGELEY) + #define SWPS_COTTONWOOD_RANGELEY (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_MAPLE_GA) + #define SWPS_MAPLE_GA (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_MAPLE_B) + #define SWPS_MAPLE_B (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_MAPLE_J) + #define SWPS_MAPLE_J (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_GULMOHAR_GA) + #define SWPS_GULMOHAR (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_GULMOHAR_2T_EVT1_GA) + #define SWPS_GULMOHAR_2T_EVT1 (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_PEONY_SFP_GA) + #define SWPS_PEONY_SFP (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_PEONY_COPPER_GA) + #define SWPS_PEONY_COPPER (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_PEONY_AUTO) + #define SWPS_PEONY_SFP (1) + #define SWPS_PEONY_COPPER (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_CEDAR_GA) + #define SWPS_CEDAR_GA (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#endif + +struct inv_platform_s { + int id; + char name[64]; +}; + +struct inv_ioexp_layout_s { + int ioexp_id; + int ioexp_type; + struct ioexp_addr_s addr[4]; +}; + +struct inv_port_layout_s { + int port_id; + int chan_id; + int ioexp_id; + int ioexp_offset; + int transvr_type; + int chipset_type; + int lane_id[8]; +}; + + +/* ========================================== + * Inventec Platform Settings + * ========================================== + */ +struct inv_platform_s platform_map[] = { + {PLATFORM_TYPE_AUTO, "Auto-Detect" }, + {PLATFORM_TYPE_MAGNOLIA, "Magnolia" }, + {PLATFORM_TYPE_MAGNOLIA_FNC, "Magnolia_FNC" }, + {PLATFORM_TYPE_REDWOOD, "Redwood" }, + {PLATFORM_TYPE_REDWOOD_FSL, "Redwood_FSL" }, + {PLATFORM_TYPE_HUDSON32I_GA, "Hudson32i" }, + {PLATFORM_TYPE_SPRUCE, "Spruce" }, + {PLATFORM_TYPE_CYPRESS_GA1, "Cypress_GA1" }, + {PLATFORM_TYPE_CYPRESS_GA2, "Cypress_GA2" }, + {PLATFORM_TYPE_CYPRESS_BAI, "Cypress_BAI" }, + {PLATFORM_TYPE_TAHOE, "Tahoe" }, + {PLATFORM_TYPE_SEQUOIA_GA, "Sequoia_GA" }, + {PLATFORM_TYPE_LAVENDER_GA, "Lavender_GA" }, + {PLATFORM_TYPE_LAVENDER_ONL, "Lavender_ONL" }, + {PLATFORM_TYPE_COTTONWOOD_RANGELEY, "Cottonwood_RANGELEY" }, + {PLATFORM_TYPE_MAPLE_GA, "Maple_GA" }, + {PLATFORM_TYPE_MAPLE_B, "Maple_B" }, + {PLATFORM_TYPE_MAPLE_J, "Maple_J" }, + {PLATFORM_TYPE_GULMOHAR_GA, "Gulmohar_GA" }, + {PLATFORM_TYPE_GULMOHAR_2T_EVT1_GA, "Gulmohar_2T_EVT1_GA" }, + {PLATFORM_TYPE_PEONY_SFP_GA, "Peony_SFP_GA" }, + {PLATFORM_TYPE_PEONY_COPPER_GA, "Peony_Copper_GA" }, + {PLATFORM_TYPE_PEONY_AUTO, "Peony_Auto_Detect" }, + {PLATFORM_TYPE_CEDAR_GA, "Cedar_GA" }, +}; + + +/* ========================================== + * Magnolia Layout configuration + * ========================================== + */ +#ifdef SWPS_MAGNOLIA +unsigned magnolia_gpio_rest_mux = MUX_RST_GPIO_48_PCA9548; + +struct inv_ioexp_layout_s magnolia_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_MAGINOLIA_NAB, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, }, /* addr[1] = I/O Expander N B */ + }, + {1, IOEXP_TYPE_MAGINOLIA_NAB, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, }, /* addr[1] = I/O Expander N B */ + }, + {2, IOEXP_TYPE_MAGINOLIA_NAB, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, }, /* addr[1] = I/O Expander N B */ + }, + {3, IOEXP_TYPE_MAGINOLIA_4AB, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander 4 A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf0, 0xff}, {0xf0, 0xff}, }, }, /* addr[1] = I/O Expander 4 B */ + }, + {4, IOEXP_TYPE_MAGINOLIA_NAB, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, }, /* addr[1] = I/O Expander N B */ + }, + {5, IOEXP_TYPE_MAGINOLIA_NAB, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, }, /* addr[1] = I/O Expander N B */ + }, + {6, IOEXP_TYPE_MAGINOLIA_7AB, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 7 A */ + {8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xf0, 0x33}, }, }, /* addr[1] = I/O Expander 7 B */ + }, +}; + +struct inv_port_layout_s magnolia_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 10, 0, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 16} }, + { 1, 11, 0, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 15} }, + { 2, 12, 0, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 14} }, + { 3, 13, 0, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 13} }, + { 4, 14, 0, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 24} }, + { 5, 15, 0, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 23} }, + { 6, 16, 0, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 22} }, + { 7, 17, 0, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 21} }, + { 8, 18, 1, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 28} }, + { 9, 19, 1, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 27} }, + {10, 20, 1, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 26} }, + {11, 21, 1, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 25} }, + {12, 22, 1, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 32} }, + {13, 23, 1, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 31} }, + {14, 24, 1, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 30} }, + {15, 25, 1, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 29} }, + {16, 26, 2, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 48} }, + {17, 27, 2, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 47} }, + {18, 28, 2, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 46} }, + {19, 29, 2, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 45} }, + {20, 30, 2, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 52} }, + {21, 31, 2, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 51} }, + {22, 32, 2, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 50} }, + {23, 33, 2, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 49} }, + {24, 34, 3, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 56} }, + {25, 35, 3, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 55} }, + {26, 36, 3, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 54} }, + {27, 37, 3, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 53} }, + {28, 38, 3, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 60} }, + {29, 39, 3, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 59} }, + {30, 40, 3, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 58} }, + {31, 41, 3, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 57} }, + {32, 42, 4, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 64} }, + {33, 43, 4, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 63} }, + {34, 44, 4, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 62} }, + {35, 45, 4, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 61} }, + {36, 46, 4, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 68} }, + {37, 47, 4, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 67} }, + {38, 48, 4, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 66} }, + {39, 49, 4, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 65} }, + {40, 50, 5, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 72} }, + {41, 51, 5, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 71} }, + {42, 52, 5, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 70} }, + {43, 53, 5, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 69} }, + {44, 54, 5, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 76} }, + {45, 55, 5, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 75} }, + {46, 56, 5, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 74} }, + {47, 57, 5, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAGNOLIA, { 73} }, + {48, 58, 6, 0, TRANSVR_TYPE_QSFP, CHIP_TYPE_MAGNOLIA, { 81, 82, 83, 84} }, + {49, 59, 6, 1, TRANSVR_TYPE_QSFP, CHIP_TYPE_MAGNOLIA, { 77, 78, 79, 80} }, + {50, 60, 6, 2, TRANSVR_TYPE_QSFP, CHIP_TYPE_MAGNOLIA, { 97, 98, 99,100} }, + {51, 61, 6, 3, TRANSVR_TYPE_QSFP, CHIP_TYPE_MAGNOLIA, {101,102,103,104} }, + {52, 62, 6, 4, TRANSVR_TYPE_QSFP, CHIP_TYPE_MAGNOLIA, {105,106,107,108} }, + {53, 63, 6, 5, TRANSVR_TYPE_QSFP, CHIP_TYPE_MAGNOLIA, {109,110,111,112} }, +}; +#endif + + +/* ========================================== + * Redwood Layout configuration + * ========================================== + */ +#ifdef SWPS_REDWOOD +unsigned redwood_gpio_rest_mux = MUX_RST_GPIO_48_PCA9548; + +struct inv_ioexp_layout_s redwood_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_REDWOOD_P01P08, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */ + {0, 0x25, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */ + }, + {1, IOEXP_TYPE_REDWOOD_P09P16, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */ + {0, 0x25, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */ + }, + {2, IOEXP_TYPE_REDWOOD_P01P08, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */ + {0, 0x24, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */ + }, + {3, IOEXP_TYPE_REDWOOD_P09P16, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */ + {0, 0x24, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */ + }, +}; + +struct inv_port_layout_s redwood_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 22, 0, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 1, 2, 3, 4} }, + { 1, 23, 0, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 5, 6, 7, 8} }, + { 2, 24, 0, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 9, 10, 11, 12} }, + { 3, 25, 0, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 13, 14, 15, 16} }, + { 4, 26, 0, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 17, 18, 19, 20} }, + { 5, 27, 0, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 21, 22, 23, 24} }, + { 6, 28, 0, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 25, 26, 27, 28} }, + { 7, 29, 0, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 29, 30, 31, 32} }, + { 8, 30, 1, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 33, 34, 35, 36} }, + { 9, 31, 1, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 37, 38, 39, 40} }, + {10, 32, 1, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 41, 42, 43, 44} }, + {11, 33, 1, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 45, 46, 47, 48} }, + {12, 34, 1, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 49, 50, 51, 52} }, + {13, 35, 1, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 53, 54, 55, 56} }, + {14, 36, 1, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 57, 58, 59, 60} }, + {15, 37, 1, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 61, 62, 63, 64} }, + {16, 6, 2, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 65, 66, 67, 68} }, + {17, 7, 2, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 69, 70, 71, 72} }, + {18, 8, 2, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 73, 74, 75, 76} }, + {19, 9, 2, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 77, 78, 79, 80} }, + {20, 10, 2, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 81, 82, 83, 84} }, + {21, 11, 2, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 85, 86, 87, 88} }, + {22, 12, 2, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 89, 90, 91, 92} }, + {23, 13, 2, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 93, 94, 95, 96} }, + {24, 14, 3, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 97, 98, 99,100} }, + {25, 15, 3, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {101,102,103,104} }, + {26, 16, 3, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {105,106,107,108} }, + {27, 17, 3, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {109,110,111,112} }, + {28, 18, 3, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {113,114,115,116} }, + {29, 19, 3, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {117,118,119,120} }, + {30, 20, 3, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {121,122,123,124} }, + {31, 21, 3, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {125,126,127,128} }, +}; +#endif + + +/* ========================================== + * Hudson32i Layout configuration + * ========================================== + */ +#ifdef SWPS_HUDSON32I_GA +unsigned hudsin32iga_gpio_rest_mux = MUX_RST_GPIO_48_PCA9548; + +struct inv_ioexp_layout_s hudson32iga_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_HUDSON32IGA_P01P08, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander B */ + {0, 0x24, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0x24 */ + }, + {1, IOEXP_TYPE_HUDSON32IGA_P09P16, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander B */ + {0, 0x24, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0x24 */ + }, + {2, IOEXP_TYPE_HUDSON32IGA_P01P08, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander B */ + {0, 0x25, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0x25 */ + }, + {3, IOEXP_TYPE_HUDSON32IGA_P09P16, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander B */ + {0, 0x25, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0x25 */ + }, +}; + +struct inv_port_layout_s hudson32iga_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 6, 0, 0, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 1, 2, 3, 4} }, + { 1, 7, 0, 1, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 5, 6, 7, 8} }, + { 2, 8, 0, 2, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 9, 10, 11, 12} }, + { 3, 9, 0, 3, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 13, 14, 15, 16} }, + { 4, 10, 0, 4, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 17, 18, 19, 20} }, + { 5, 11, 0, 5, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 21, 22, 23, 24} }, + { 6, 12, 0, 6, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 25, 26, 27, 28} }, + { 7, 13, 0, 7, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 29, 30, 31, 32} }, + { 8, 14, 1, 0, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 33, 34, 35, 36} }, + { 9, 15, 1, 1, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 37, 38, 39, 40} }, + {10, 16, 1, 2, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 41, 42, 43, 44} }, + {11, 17, 1, 3, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 45, 46, 47, 48} }, + {12, 18, 1, 4, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 49, 50, 51, 52} }, + {13, 19, 1, 5, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 53, 54, 55, 56} }, + {14, 20, 1, 6, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 57, 58, 59, 60} }, + {15, 21, 1, 7, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 61, 62, 63, 64} }, + {16, 22, 2, 0, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 65, 66, 67, 68} }, + {17, 23, 2, 1, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 69, 70, 71, 72} }, + {18, 24, 2, 2, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 73, 74, 75, 76} }, + {19, 25, 2, 3, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 77, 78, 79, 80} }, + {20, 26, 2, 4, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 81, 82, 83, 84} }, + {21, 27, 2, 5, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 85, 86, 87, 88} }, + {22, 28, 2, 6, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 89, 90, 91, 92} }, + {23, 29, 2, 7, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 93, 94, 95, 96} }, + {24, 30, 3, 0, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 97, 98, 99,100} }, + {25, 31, 3, 1, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, {101,102,103,104} }, + {26, 32, 3, 2, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, {105,106,107,108} }, + {27, 33, 3, 3, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, {109,110,111,112} }, + {28, 34, 3, 4, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, {113,114,115,116} }, + {29, 35, 3, 5, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, {117,118,119,120} }, + {30, 36, 3, 6, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, {121,122,123,124} }, + {31, 37, 3, 7, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, {125,126,127,128} }, +}; +#endif + + +/* ========================================== + * Spruce Layout configuration + * ========================================== + */ +#ifdef SWPS_SPRUCE +unsigned spruce_gpio_rest_mux = MUX_RST_GPIO_48_PCA9548; + +struct inv_ioexp_layout_s spruce_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_SPRUCE_7AB, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 7A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xf0, 0x33}, }, }, /* addr[2] = I/O Expander 7B */ + }, +}; + +struct inv_port_layout_s spruce_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 6, 0, 0, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 81, 82, 83, 84} }, + { 1, 7, 0, 1, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 77, 78, 79, 80} }, + { 2, 8, 0, 2, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, { 97, 98, 99,100} }, + { 3, 9, 0, 3, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, {101,102,103,104} }, + { 4, 10, 0, 4, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, {105,106,107,108} }, + { 5, 11, 0, 5, TRANSVR_TYPE_QSFP_PLUS, CHIP_TYPE_MAGNOLIA, {109,110,111,112} }, +}; +#endif + + +/* ========================================== + * Cypress Layout configuration (Inventec version [Up->Down]) + * ========================================== + */ +#ifdef SWPS_CYPRESS_GA1 +unsigned cypress_ga1_gpio_rest_mux = MUX_RST_GPIO_69_PCA9548; + +struct inv_ioexp_layout_s cypress_ga1_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {1, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {2, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {3, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {4, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {5, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {6, IOEXP_TYPE_CYPRESS_7ABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 7 A */ + {8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xc0}, {0xff, 0xc0}, }, /* addr[1] = I/O Expander 7 B */ + {8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */ + }, +}; + +struct inv_port_layout_s cypress_ga1_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 10, 0, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 1} }, + { 1, 11, 0, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 2} }, + { 2, 12, 0, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 3} }, + { 3, 13, 0, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 4} }, + { 4, 14, 0, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 5} }, + { 5, 15, 0, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 6} }, + { 6, 16, 0, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 7} }, + { 7, 17, 0, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 8} }, + { 8, 18, 1, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 9} }, + { 9, 19, 1, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 10} }, + {10, 20, 1, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 11} }, + {11, 21, 1, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 12} }, + {12, 22, 1, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 21} }, + {13, 23, 1, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 22} }, + {14, 24, 1, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 23} }, + {15, 25, 1, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 24} }, + {16, 26, 2, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 33} }, + {17, 27, 2, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 34} }, + {18, 28, 2, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 35} }, + {19, 29, 2, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 36} }, + {20, 30, 2, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 37} }, + {21, 31, 2, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 38} }, + {22, 32, 2, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 39} }, + {23, 33, 2, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 40} }, + {24, 34, 3, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 41} }, + {25, 35, 3, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 42} }, + {26, 36, 3, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 43} }, + {27, 37, 3, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 44} }, + {28, 38, 3, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 49} }, + {29, 39, 3, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 50} }, + {30, 40, 3, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 51} }, + {31, 41, 3, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 52} }, + {32, 42, 4, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 53} }, + {33, 43, 4, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 54} }, + {34, 44, 4, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 55} }, + {35, 45, 4, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 56} }, + {36, 46, 4, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 65} }, + {37, 47, 4, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 66} }, + {38, 48, 4, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 67} }, + {39, 49, 4, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 68} }, + {40, 50, 5, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 69} }, + {41, 51, 5, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 70} }, + {42, 52, 5, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 71} }, + {43, 53, 5, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 72} }, + {44, 54, 5, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 81} }, + {45, 55, 5, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 82} }, + {46, 56, 5, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 83} }, + {47, 57, 5, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 84} }, + {48, 58, 6, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 97, 98, 99,100} }, + {49, 59, 6, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 85, 86, 87, 88} }, + {50, 60, 6, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {101,102,103,104} }, + {51, 61, 6, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {105,106,107,108} }, + {52, 62, 6, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {109,110,111,112} }, + {53, 63, 6, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {117,118,119,120} }, +}; +#endif + + +/* ========================================== + * Cypress Layout configuration (Inventec version [Down->Up]) + * ========================================== + */ +#ifdef SWPS_CYPRESS_GA2 +unsigned cypress_ga2_gpio_rest_mux = MUX_RST_GPIO_FORCE_HEDERA; + +struct inv_ioexp_layout_s cypress_ga2_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {1, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {2, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {3, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {4, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {5, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {6, IOEXP_TYPE_CYPRESS_7ABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 7 A */ + {8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xc0}, {0xff, 0xc0}, }, /* addr[1] = I/O Expander 7 B */ + {8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */ + }, +}; + +struct inv_port_layout_s cypress_ga2_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 11, 0, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 2} }, + { 1, 10, 0, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 1} }, + { 2, 13, 0, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 4} }, + { 3, 12, 0, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 3} }, + { 4, 15, 0, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 6} }, + { 5, 14, 0, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 5} }, + { 6, 17, 0, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 8} }, + { 7, 16, 0, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 7} }, + { 8, 19, 1, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 10} }, + { 9, 18, 1, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 9} }, + {10, 21, 1, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 12} }, + {11, 20, 1, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 11} }, + {12, 23, 1, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 22} }, + {13, 22, 1, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 21} }, + {14, 25, 1, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 24} }, + {15, 24, 1, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 23} }, + {16, 27, 2, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 34} }, + {17, 26, 2, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 33} }, + {18, 29, 2, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 36} }, + {19, 28, 2, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 35} }, + {20, 31, 2, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 38} }, + {21, 30, 2, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 37} }, + {22, 33, 2, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 40} }, + {23, 32, 2, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 39} }, + {24, 35, 3, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 42} }, + {25, 34, 3, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 41} }, + {26, 37, 3, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 44} }, + {27, 36, 3, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 43} }, + {28, 39, 3, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 50} }, + {29, 38, 3, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 49} }, + {30, 41, 3, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 52} }, + {31, 40, 3, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 51} }, + {32, 43, 4, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 54} }, + {33, 42, 4, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 53} }, + {34, 45, 4, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 56} }, + {35, 44, 4, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 55} }, + {36, 47, 4, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 66} }, + {37, 46, 4, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 65} }, + {38, 49, 4, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 68} }, + {39, 48, 4, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 67} }, + {40, 51, 5, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 70} }, + {41, 50, 5, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 69} }, + {42, 53, 5, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 72} }, + {43, 52, 5, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 71} }, + {44, 55, 5, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 82} }, + {45, 54, 5, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 81} }, + {46, 57, 5, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 84} }, + {47, 56, 5, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 83} }, + {48, 59, 6, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 85, 86, 87, 88} }, + {49, 58, 6, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 97, 98, 99,100} }, + {50, 61, 6, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {105,106,107,108} }, + {51, 60, 6, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {101,102,103,104} }, + {52, 63, 6, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {117,118,119,120} }, + {53, 62, 6, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {109,110,111,112} }, +}; +#endif + + +/* ========================================== + * Cypress Layout configuration (C1 version) + * ========================================== + */ +#ifdef SWPS_CYPRESS_BAI +unsigned cypress_b_gpio_rest_mux = MUX_RST_GPIO_FORCE_HEDERA; + +struct inv_ioexp_layout_s cypress_b_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {1, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {2, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {3, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {4, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {5, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {6, IOEXP_TYPE_CYPRESS_7ABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 7 A */ + {8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xc0}, {0xff, 0xc0}, }, /* addr[1] = I/O Expander 7 B */ + {8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */ + }, +}; + +struct inv_port_layout_s cypress_b_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 1, 11, 0, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 2} }, + { 2, 10, 0, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 1} }, + { 3, 13, 0, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 4} }, + { 4, 12, 0, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 3} }, + { 5, 15, 0, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 6} }, + { 6, 14, 0, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 5} }, + { 7, 17, 0, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 8} }, + { 8, 16, 0, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 7} }, + { 9, 19, 1, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 10} }, + {10, 18, 1, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 9} }, + {11, 21, 1, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 12} }, + {12, 20, 1, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 11} }, + {13, 23, 1, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 22} }, + {14, 22, 1, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 21} }, + {15, 25, 1, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 24} }, + {16, 24, 1, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 23} }, + {17, 27, 2, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 34} }, + {18, 26, 2, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 33} }, + {19, 29, 2, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 36} }, + {20, 28, 2, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 35} }, + {21, 31, 2, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 38} }, + {22, 30, 2, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 37} }, + {23, 33, 2, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 40} }, + {24, 32, 2, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 39} }, + {25, 35, 3, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 42} }, + {26, 34, 3, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 41} }, + {27, 37, 3, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 44} }, + {28, 36, 3, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 43} }, + {29, 39, 3, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 50} }, + {30, 38, 3, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 49} }, + {31, 41, 3, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 52} }, + {32, 40, 3, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 51} }, + {33, 43, 4, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 54} }, + {34, 42, 4, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 53} }, + {35, 45, 4, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 56} }, + {36, 44, 4, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 55} }, + {37, 47, 4, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 66} }, + {38, 46, 4, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 65} }, + {39, 49, 4, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 68} }, + {40, 48, 4, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 67} }, + {41, 51, 5, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 70} }, + {42, 50, 5, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 69} }, + {43, 53, 5, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 72} }, + {44, 52, 5, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 71} }, + {45, 55, 5, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 82} }, + {46, 54, 5, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 81} }, + {47, 57, 5, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 84} }, + {48, 56, 5, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 83} }, + {49, 59, 6, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 85, 86, 87, 88} }, + {50, 58, 6, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 97, 98, 99,100} }, + {51, 61, 6, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {105,106,107,108} }, + {52, 60, 6, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {101,102,103,104} }, + {53, 63, 6, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {117,118,119,120} }, + {54, 62, 6, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {109,110,111,112} }, +}; +#endif + + +/* ========================================== + * Redwood_fsl Layout configuration + * ========================================== + */ +#ifdef SWPS_REDWOOD_FSL +unsigned redwood_fsl_gpio_rest_mux = MUX_RST_GPIO_48_PCA9548; + +struct inv_ioexp_layout_s redwood_fsl_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_REDWOOD_P01P08, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */ + {0, 0x25, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */ + }, + {1, IOEXP_TYPE_REDWOOD_P09P16, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */ + {0, 0x25, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */ + }, + {2, IOEXP_TYPE_REDWOOD_P01P08, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */ + {0, 0x24, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */ + }, + {3, IOEXP_TYPE_REDWOOD_P09P16, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */ + {0, 0x24, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */ + }, +}; + + +struct inv_port_layout_s redwood_fsl_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 22, 0, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 1, 2, 3, 4} }, + { 1, 23, 0, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 5, 6, 7, 8} }, + { 2, 24, 0, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 9, 10, 11, 12} }, + { 3, 25, 0, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 13, 14, 15, 16} }, + { 4, 26, 0, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 17, 18, 19, 20} }, + { 5, 27, 0, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 21, 22, 23, 24} }, + { 6, 28, 0, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 25, 26, 27, 28} }, + { 7, 29, 0, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 29, 30, 31, 32} }, + { 8, 30, 1, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 33, 34, 35, 36} }, + { 9, 31, 1, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 37, 38, 39, 40} }, + {10, 32, 1, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 41, 42, 43, 44} }, + {11, 33, 1, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 45, 46, 47, 48} }, + {12, 34, 1, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 49, 50, 51, 52} }, + {13, 35, 1, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 53, 54, 55, 56} }, + {14, 36, 1, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 57, 58, 59, 60} }, + {15, 37, 1, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 61, 62, 63, 64} }, + {16, 6, 2, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 65, 66, 67, 68} }, + {17, 7, 2, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 69, 70, 71, 72} }, + {18, 8, 2, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 73, 74, 75, 76} }, + {19, 9, 2, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 77, 78, 79, 80} }, + {20, 10, 2, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 81, 82, 83, 84} }, + {21, 11, 2, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 85, 86, 87, 88} }, + {22, 12, 2, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 89, 90, 91, 92} }, + {23, 13, 2, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 93, 94, 95, 96} }, + {24, 14, 3, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 97, 98, 99,100} }, + {25, 15, 3, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {101,102,103,104} }, + {26, 16, 3, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {105,106,107,108} }, + {27, 17, 3, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {109,110,111,112} }, + {28, 18, 3, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {113,114,115,116} }, + {29, 19, 3, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {117,118,119,120} }, + {30, 20, 3, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {121,122,123,124} }, + {31, 21, 3, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {125,126,127,128} }, +}; +#endif + + +/* ========================================== + * Tahoe Layout configuration + * ========================================== + */ +#ifdef SWPS_TAHOE +unsigned tahoe_gpio_rest_mux = MUX_RST_GPIO_249_PCA9548; + +struct inv_ioexp_layout_s tahoe_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_TAHOE_6ABC, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xce, 0xb9}, {0x18, 0xe3}, }, /* addr[0] = I/O Expander 6 A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xce, 0xb9}, {0x18, 0xe3}, }, /* addr[1] = I/O Expander 6 B */ + {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xce, 0xb9}, {0x18, 0xe3}, }, }, /* addr[2] = I/O Expander 6 C */ + }, + {1, IOEXP_TYPE_TAHOE_5A, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xce, 0xb9}, {0x18, 0xe3}, }, }, /* addr[0] = I/O Expander 5 A */ + }, +}; + + +struct inv_port_layout_s tahoe_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 12, 1, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 65, 66, 67, 68} }, + { 1, 11, 1, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 53, 54, 55, 56} }, + { 2, 22, 0, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 69, 70, 71, 72} }, + { 3, 21, 0, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 81, 82, 83, 84} }, + { 4, 24, 0, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 97, 98, 99, 100} }, + { 5, 23, 0, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 85, 86, 87, 88} }, + { 6, 18, 0, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {101, 102, 103, 104} }, + { 7, 17, 0, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {105, 106, 107, 108} }, + { 8, 20, 0, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {113, 114, 115, 116} }, + { 9, 19, 0, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {109, 110, 111, 112} }, +}; +#endif + + +/* ========================================== + * Sequoia Layout configuration + * ========================================== + */ +#ifdef SWPS_SEQUOIA +unsigned sequoia_gpio_rest_mux = MUX_RST_GPIO_69_PCA9548; + +struct inv_ioexp_layout_s sequoia_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_SEQUOIA_NABC, { {1, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 0 A */ + {1, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 0 B */ + {1, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */ + }, + {1, IOEXP_TYPE_SEQUOIA_NABC, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 1 A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 1 B */ + {2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 1 C */ + }, + {2, IOEXP_TYPE_SEQUOIA_NABC, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 2 A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 2 B */ + {3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 2 C */ + }, + {3, IOEXP_TYPE_SEQUOIA_NABC, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 3 A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 3 B */ + {4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 3 C */ + }, + {4, IOEXP_TYPE_SEQUOIA_NABC, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 4 A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 4 B */ + {5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 4 C */ + }, + {5, IOEXP_TYPE_SEQUOIA_NABC, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 5 A */ + {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 5 B */ + {6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 C */ + }, + {6, IOEXP_TYPE_SEQUOIA_NABC, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 6 A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 6 B */ + {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 6 C */ + }, + {7, IOEXP_TYPE_SEQUOIA_NABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 7 A */ + {8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 7 B */ + {8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */ + }, +}; + + +struct inv_port_layout_s sequoia_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 9, 0, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 9, 10, 11, 12} }, + { 1, 10, 0, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 1, 2, 3, 4} }, + { 2, 11, 0, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 25, 26, 27, 28} }, + { 3, 12, 0, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 17, 18, 19, 20} }, + { 4, 13, 0, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 41, 42, 43, 44} }, + { 5, 14, 0, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 33, 34, 35, 36} }, + { 6, 15, 0, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 57, 58, 59, 60} }, + { 7, 16, 0, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 49, 50, 51, 52} }, + { 8, 17, 1, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 73, 74, 75, 76} }, + { 9, 18, 1, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 65, 66, 67, 68} }, + {10, 19, 1, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 89, 90, 91, 92} }, + {11, 20, 1, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 81, 82, 83, 84} }, + {12, 21, 1, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {105, 106, 107, 108} }, + {13, 22, 1, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 97, 98, 99, 100} }, + {14, 23, 1, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {121, 122, 123, 124} }, + {15, 24, 1, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {113, 114, 115, 116} }, + {16, 25, 2, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {137, 138, 139, 140} }, + {17, 26, 2, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {129, 130, 131, 132} }, + {18, 27, 2, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {153, 154, 155, 156} }, + {19, 28, 2, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {145, 146, 147, 148} }, + {20, 29, 2, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {169, 170, 171, 172} }, + {21, 30, 2, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {161, 162, 163, 164} }, + {22, 31, 2, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {185, 186, 187, 188} }, + {23, 32, 2, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {177, 178, 179, 180} }, + {24, 33, 3, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {201, 202, 203, 204} }, + {25, 34, 3, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {193, 194, 195, 196} }, + {26, 35, 3, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {217, 218, 219, 220} }, + {27, 36, 3, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {209, 210, 211, 212} }, + {28, 37, 3, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {233, 234, 235, 236} }, + {29, 38, 3, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {225, 226, 227, 228} }, + {30, 39, 3, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {249, 250, 251, 252} }, + {31, 40, 3, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {241, 242, 243, 244} }, + {32, 44, 4, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 13, 14, 15, 16} }, + {33, 43, 4, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 5, 6, 7, 8} }, + {34, 42, 4, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 29, 30, 31, 32} }, + {35, 41, 4, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 21, 22, 23, 24} }, + {36, 48, 4, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 45, 46, 47, 48} }, + {37, 47, 4, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 37, 38, 39, 40} }, + {38, 46, 4, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 61, 62, 63, 64} }, + {39, 45, 4, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 53, 54, 55, 56} }, + {40, 52, 5, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 77, 78, 79, 80} }, + {41, 51, 5, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 69, 70, 71, 72} }, + {42, 50, 5, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 93, 94, 95, 96} }, + {43, 49, 5, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, { 85, 86, 87, 88} }, + {44, 56, 5, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {109, 110, 111, 112} }, + {45, 55, 5, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {101, 102, 103, 104} }, + {46, 54, 5, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {125, 126, 127, 128} }, + {47, 53, 5, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {117, 118, 119, 120} }, + {48, 60, 6, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {141, 142, 143, 144} }, + {49, 59, 6, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {133, 134, 135, 136} }, + {50, 58, 6, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {157, 158, 159, 160} }, + {51, 57, 6, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {149, 150, 151, 152} }, + {52, 64, 6, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {173, 174, 175, 176} }, + {53, 63, 6, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {165, 166, 167, 168} }, + {54, 62, 6, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {189, 190, 191, 192} }, + {55, 61, 6, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {181, 182, 183, 184} }, + {56, 68, 7, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {205, 206, 207, 208} }, + {57, 67, 7, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {197, 198, 199, 200} }, + {58, 66, 7, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {221, 222, 223, 224} }, + {59, 65, 7, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {213, 214, 215, 216} }, + {60, 72, 7, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {237, 238, 239, 240} }, + {61, 71, 7, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {229, 230, 231, 232} }, + {62, 70, 7, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {253, 254, 255, 256} }, + {63, 69, 7, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_REDWOOD, {245, 246, 247, 248} }, +}; +#endif + + +/* ========================================== + * Lavender Layout configuration + * ========================================== + */ +#if (PLATFORM_SETTINGS == PLATFORM_TYPE_LAVENDER_GA) +unsigned lavender_gpio_rest_mux = MUX_RST_GPIO_505_PCA9548; +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_LAVENDER_ONL) +unsigned lavender_gpio_rest_mux = MUX_RST_GPIO_69_PCA9548; +#endif + +#ifdef SWPS_LAVENDER +struct inv_ioexp_layout_s lavender_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_SEQUOIA_NABC, { { 1, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 0 A */ + { 1, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 0 B */ + { 1, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */ + }, + {1, IOEXP_TYPE_SEQUOIA_NABC, { { 2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 1 A */ + { 2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 1 B */ + { 2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 1 C */ + }, + {2, IOEXP_TYPE_SEQUOIA_NABC, { { 3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 2 A */ + { 3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 2 B */ + { 3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 2 C */ + }, + {3, IOEXP_TYPE_SEQUOIA_NABC, { { 4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 3 A */ + { 4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 3 B */ + { 4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 3 C */ + }, + {4, IOEXP_TYPE_SEQUOIA_NABC, { { 9, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 4 A */ + { 9, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 4 B */ + { 9, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 4 C */ + }, + {5, IOEXP_TYPE_SEQUOIA_NABC, { {10, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 5 A */ + {10, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 5 B */ + {10, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 C */ + }, + {6, IOEXP_TYPE_SEQUOIA_NABC, { {11, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 6 A */ + {11, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 6 B */ + {11, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 6 C */ + }, + {7, IOEXP_TYPE_SEQUOIA_NABC, { {12, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 7 A */ + {12, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 7 B */ + {12, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */ + }, + {8, IOEXP_TYPE_LAVENDER_P65, { { 5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xF6, 0xff}, {0xF8, 0xff}, }, }, /* addr[0] = I/O Expander CPU */ + }, +}; + + +struct inv_port_layout_s lavender_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 17, 0, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {188, 189, 190, 191} }, + { 1, 18, 0, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {184, 185, 186, 187} }, + { 2, 19, 0, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {180, 181, 182, 183} }, + { 3, 20, 0, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {176, 177, 178, 179} }, + { 4, 21, 0, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {172, 173, 174, 175} }, + { 5, 22, 0, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {168, 169, 170, 171} }, + { 6, 23, 0, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {164, 165, 166, 167} }, + { 7, 24, 0, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {160, 161, 162, 163} }, + { 8, 25, 1, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {156, 157, 158, 159} }, + { 9, 26, 1, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {152, 153, 154, 155} }, + {10, 27, 1, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {148, 149, 150, 151} }, + {11, 28, 1, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {144, 145, 146, 147} }, + {12, 29, 1, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {140, 141, 142, 143} }, + {13, 30, 1, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {136, 137, 138, 139} }, + {14, 31, 1, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {132, 133, 134, 135} }, + {15, 32, 1, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {128, 129, 130, 131} }, + {16, 33, 2, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 0, 1, 2, 3} }, + {17, 34, 2, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 4, 5, 6, 7} }, + {18, 35, 2, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 8, 9, 10, 11} }, + {19, 36, 2, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 12, 13, 14, 15} }, + {20, 37, 2, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 16, 17, 18, 19} }, + {21, 38, 2, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 20, 21, 22, 23} }, + {22, 39, 2, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 24, 25, 26, 27} }, + {23, 40, 2, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 28, 29, 30, 31} }, + {24, 41, 3, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 32, 33, 34, 35} }, + {25, 42, 3, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 36, 37, 38, 39} }, + {26, 43, 3, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 40, 41, 42, 43} }, + {27, 44, 3, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 44, 45, 46, 47} }, + {28, 45, 3, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 48, 49, 50, 51} }, + {29, 46, 3, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 52, 53, 54, 55} }, + {30, 47, 3, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 56, 57, 58, 59} }, + {31, 48, 3, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 60, 61, 62, 63} }, + {32, 49, 4, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {256, 257, 258, 259} }, + {33, 50, 4, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {260, 261, 262, 263} }, + {34, 51, 4, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {264, 265, 266, 267} }, + {35, 52, 4, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {268, 269, 270, 271} }, + {36, 53, 4, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {272, 273, 274, 275} }, + {37, 54, 4, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {276, 277, 278, 279} }, + {38, 55, 4, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {280, 281, 282, 283} }, + {39, 56, 4, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {284, 285, 286, 287} }, + {40, 57, 5, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {288, 289, 290, 291} }, + {41, 58, 5, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {292, 293, 294, 295} }, + {42, 59, 5, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {296, 297, 298, 299} }, + {43, 60, 5, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {300, 301, 302, 303} }, + {44, 61, 5, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {304, 305, 306, 307} }, + {45, 62, 5, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {308, 309, 310, 311} }, + {46, 63, 5, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {312, 313, 314, 315} }, + {47, 64, 5, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {316, 317, 318, 319} }, + {48, 65, 6, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {444, 445, 446, 447} }, + {49, 66, 6, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {440, 441, 442, 443} }, + {50, 67, 6, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {436, 437, 438, 439} }, + {51, 68, 6, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {432, 433, 434, 435} }, + {52, 69, 6, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {428, 429, 430, 431} }, + {53, 70, 6, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {424, 425, 426, 427} }, + {54, 71, 6, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {420, 421, 422, 423} }, + {55, 72, 6, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {416, 417, 418, 419} }, + {56, 73, 7, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {412, 413, 414, 415} }, + {57, 74, 7, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {408, 409, 410, 411} }, + {58, 75, 7, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {404, 405, 406, 407} }, + {59, 76, 7, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {400, 401, 402, 403} }, + {60, 77, 7, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {396, 397, 398, 399} }, + {61, 78, 7, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {392, 393, 394, 395} }, + {62, 79, 7, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {388, 389, 390, 391} }, + {63, 80, 7, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {384, 385, 386, 387} }, + {64, 5, 8, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 64, 65, 66, 67} }, +}; +#endif + +/* =========================================================== + * Cottonwood Layout configuration Rangeley (Rangeley CPU board) + * =========================================================== + */ +#ifdef SWPS_COTTONWOOD_RANGELEY +unsigned cottonwood_rangeley_gpio_rest_mux = MUX_RST_GPIO_500_PCA9548; + +struct inv_ioexp_layout_s cottonwood_rangeley_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, CPLD_TYPE_COTTONWOOD,{ {1, 0x55, {22, 23, 24, 25}, {22, 23, 24, 25}, {-1, -1, -1, -1}, {0xee, 0xee, 0x99, 0x99}, {0x00, 0x00, 0x00, 0x00}, }, + }, + }, +}; + + +struct inv_port_layout_s cottonwood_rangeley_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 2, 0, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 75} }, + { 1, 3, 0, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 77} }, + { 2, 4, 0, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 79} }, + { 3, 5, 0, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_REDWOOD, { 81} }, +}; +#endif + +/* =========================================================== + * Maple Layout configuration (Old) + * =========================================================== + */ +#ifdef SWPS_MAPLE_GA +unsigned maple_ga_gpio_rest_mux = MUX_RST_GPIO_69_PCA9548; + +struct inv_ioexp_layout_s maple_ga_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_MAPLE_0ABC, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 0 A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 0 B */ + {2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */ + }, + {1, IOEXP_TYPE_MAPLE_NABC, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {2, IOEXP_TYPE_MAPLE_NABC, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {3, IOEXP_TYPE_MAPLE_NABC, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {4, IOEXP_TYPE_MAPLE_NABC, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {5, IOEXP_TYPE_MAPLE_NABC, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {6, IOEXP_TYPE_MAPLE_NABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, +}; + +struct inv_port_layout_s maple_ga_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 18, 1, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 1} }, + { 1, 19, 1, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 2} }, + { 2, 20, 1, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 3} }, + { 3, 21, 1, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 4} }, + { 4, 22, 1, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 5} }, + { 5, 23, 1, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 6} }, + { 6, 24, 1, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 7} }, + { 7, 25, 1, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 8} }, + { 8, 26, 2, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 13} }, + { 9, 27, 2, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 14} }, + {10, 28, 2, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 15} }, + {11, 29, 2, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 16} }, + {12, 30, 2, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 21} }, + {13, 31, 2, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 22} }, + {14, 32, 2, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 23} }, + {15, 33, 2, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 24} }, + {16, 34, 3, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 29} }, + {17, 35, 3, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 30} }, + {18, 36, 3, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 31} }, + {19, 37, 3, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 32} }, + {20, 38, 3, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 33} }, + {21, 39, 3, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 34} }, + {22, 40, 3, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 35} }, + {23, 41, 3, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 36} }, + {24, 42, 4, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 41} }, + {25, 43, 4, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 42} }, + {26, 44, 4, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 43} }, + {27, 45, 4, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 44} }, + {28, 46, 4, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 49} }, + {29, 47, 4, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 50} }, + {30, 48, 4, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 51} }, + {31, 49, 4, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 52} }, + {32, 50, 5, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 57} }, + {33, 51, 5, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 58} }, + {34, 52, 5, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 59} }, + {35, 53, 5, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 60} }, + {36, 54, 5, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 61} }, + {37, 55, 5, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 62} }, + {38, 56, 5, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 63} }, + {39, 57, 5, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 64} }, + {40, 58, 6, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 65} }, + {41, 59, 6, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 66} }, + {42, 60, 6, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 67} }, + {43, 61, 6, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 68} }, + {44, 62, 6, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 69} }, + {45, 63, 6, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 70} }, + {46, 64, 6, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 71} }, + {47, 65, 6, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 72} }, + {48, 10, 0, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 77, 78, 79, 80} }, + {49, 11, 0, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 85, 86, 87, 88} }, + {50, 12, 0, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 93, 94, 95, 96} }, + {51, 13, 0, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 97, 98, 99,100} }, + {52, 14, 0, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, {105,106,107,108} }, + {53, 15, 0, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, {113,114,115,116} }, + {54, 16, 0, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, {121,122,123,124} }, + {55, 17, 0, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, {125,126,127,128} }, +}; +#endif + +/* =========================================================== + * Maple Layout configuration (B version) + * =========================================================== + */ +#ifdef SWPS_MAPLE_B +unsigned maple_b_gpio_rest_mux = MUX_RST_GPIO_69_PCA9548; + +struct inv_ioexp_layout_s maple_b_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_MAPLE_0ABC, { { 6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 0 A */ + { 6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 0 B */ + { 6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */ + }, + {1, IOEXP_TYPE_MAPLE_NABC, { { 7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + { 7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + { 7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {2, IOEXP_TYPE_MAPLE_NABC, { { 8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + { 8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + { 8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {3, IOEXP_TYPE_MAPLE_NABC, { { 9, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + { 9, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + { 9, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {4, IOEXP_TYPE_MAPLE_NABC, { {10, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {10, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {10, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {5, IOEXP_TYPE_MAPLE_NABC, { {11, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {11, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {11, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {6, IOEXP_TYPE_MAPLE_NABC, { {12, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {12, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {12, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, +}; + +struct inv_port_layout_s maple_b_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 1, 23, 1, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 2} }, + { 2, 22, 1, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 1} }, + { 3, 25, 1, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 4} }, + { 4, 24, 1, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 3} }, + { 5, 27, 1, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 6} }, + { 6, 26, 1, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 5} }, + { 7, 29, 1, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 8} }, + { 8, 28, 1, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 7} }, + { 9, 31, 2, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 14} }, + {10, 30, 2, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 13} }, + {11, 33, 2, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 16} }, + {12, 32, 2, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 15} }, + {13, 35, 2, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 22} }, + {14, 34, 2, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 21} }, + {15, 37, 2, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 24} }, + {16, 36, 2, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 23} }, + {17, 39, 3, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 30} }, + {18, 38, 3, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 29} }, + {19, 41, 3, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 32} }, + {20, 40, 3, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 31} }, + {21, 43, 3, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 34} }, + {22, 42, 3, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 33} }, + {23, 45, 3, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 36} }, + {24, 44, 3, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 35} }, + {25, 47, 4, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 42} }, + {26, 46, 4, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 41} }, + {27, 49, 4, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 44} }, + {28, 48, 4, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 43} }, + {29, 51, 4, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 50} }, + {30, 50, 4, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 49} }, + {31, 53, 4, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 52} }, + {32, 52, 4, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 51} }, + {33, 55, 5, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 58} }, + {34, 54, 5, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 57} }, + {35, 57, 5, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 60} }, + {36, 56, 5, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 59} }, + {37, 59, 5, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 62} }, + {38, 58, 5, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 61} }, + {39, 61, 5, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 64} }, + {40, 60, 5, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 63} }, + {41, 63, 6, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 66} }, + {42, 62, 6, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 65} }, + {43, 65, 6, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 68} }, + {44, 64, 6, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 67} }, + {45, 67, 6, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 70} }, + {46, 66, 6, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 69} }, + {47, 69, 6, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 72} }, + {48, 68, 6, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 71} }, + {49, 15, 0, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 77, 78, 79, 80} }, + {50, 14, 0, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 85, 86, 87, 88} }, + {51, 17, 0, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 97, 98, 99,100} }, + {52, 16, 0, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 93, 94, 95, 96} }, + {53, 19, 0, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, {105,106,107,108} }, + {54, 18, 0, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, {113,114,115,116} }, + {55, 21, 0, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, {125,126,127,128} }, + {56, 20, 0, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, {121,122,123,124} }, +}; +#endif + +/* =========================================================== + * Maple Layout configuration (J version) + * =========================================================== + */ +#ifdef SWPS_MAPLE_J +unsigned maple_j_gpio_rest_mux = MUX_RST_GPIO_69_PCA9548; + +struct inv_ioexp_layout_s maple_j_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_MAPLE_0ABC, { { 6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 0 A */ + { 6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 0 B */ + { 6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */ + }, + {1, IOEXP_TYPE_MAPLE_NABC, { { 7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + { 7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + { 7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {2, IOEXP_TYPE_MAPLE_NABC, { { 8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + { 8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + { 8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {3, IOEXP_TYPE_MAPLE_NABC, { { 9, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + { 9, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + { 9, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {4, IOEXP_TYPE_MAPLE_NABC, { {10, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {10, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {10, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {5, IOEXP_TYPE_MAPLE_NABC, { {11, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {11, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {11, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {6, IOEXP_TYPE_MAPLE_NABC, { {12, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {12, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {12, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, +}; + +struct inv_port_layout_s maple_j_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 22, 1, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 1} }, + { 1, 23, 1, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 2} }, + { 2, 24, 1, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 3} }, + { 3, 25, 1, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 4} }, + { 4, 26, 1, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 5} }, + { 5, 27, 1, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 6} }, + { 6, 28, 1, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 7} }, + { 7, 29, 1, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 8} }, + { 8, 30, 2, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 13} }, + { 9, 31, 2, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 14} }, + {10, 32, 2, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 15} }, + {11, 33, 2, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 16} }, + {12, 34, 2, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 21} }, + {13, 35, 2, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 22} }, + {14, 36, 2, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 23} }, + {15, 37, 2, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 24} }, + {16, 38, 3, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 29} }, + {17, 39, 3, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 30} }, + {18, 40, 3, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 31} }, + {19, 41, 3, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 32} }, + {20, 42, 3, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 33} }, + {21, 43, 3, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 34} }, + {22, 44, 3, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 35} }, + {23, 45, 3, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 36} }, + {24, 46, 4, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 41} }, + {25, 47, 4, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 42} }, + {26, 48, 4, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 43} }, + {27, 49, 4, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 44} }, + {28, 50, 4, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 49} }, + {29, 51, 4, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 50} }, + {30, 52, 4, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 51} }, + {31, 53, 4, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 52} }, + {32, 54, 5, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 57} }, + {33, 55, 5, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 58} }, + {34, 56, 5, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 59} }, + {35, 57, 5, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 60} }, + {36, 58, 5, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 61} }, + {37, 59, 5, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 62} }, + {38, 60, 5, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 63} }, + {39, 61, 5, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 64} }, + {40, 62, 6, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 65} }, + {41, 63, 6, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 66} }, + {42, 64, 6, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 67} }, + {43, 65, 6, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 68} }, + {44, 66, 6, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 69} }, + {45, 67, 6, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 70} }, + {46, 68, 6, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 71} }, + {47, 69, 6, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 72} }, + {48, 14, 0, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 85, 86, 87, 88} }, + {49, 15, 0, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 77, 78, 79, 80} }, + {50, 16, 0, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 93, 94, 95, 96} }, + {51, 17, 0, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 97, 98, 99,100} }, + {52, 18, 0, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, {113,114,115,116} }, + {53, 19, 0, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, {105,106,107,108} }, + {54, 20, 0, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, {121,122,123,124} }, + {55, 21, 0, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, {125,126,127,128} }, +}; +#endif + +/* ========================================== + * Gulmohar Layout configuration + * ========================================== + */ +#ifdef SWPS_GULMOHAR +unsigned gulmohar_gpio_rest_mux = MUX_RST_GPIO_505_PCA9548; + +struct inv_ioexp_layout_s gulmohar_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_GULMOHAR_NABC, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */ + {2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {1, IOEXP_TYPE_GULMOHAR_NABC, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */ + {3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {2, IOEXP_TYPE_GULMOHAR_NABC, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */ + {4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {3, IOEXP_TYPE_GULMOHAR_NABC, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */ + {5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {4, IOEXP_TYPE_GULMOHAR_NABC, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */ + {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */ + {6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {5, IOEXP_TYPE_GULMOHAR_NABC, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */ + {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {6, IOEXP_TYPE_GULMOHAR_7ABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 7 A */ + {8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xff}, }, /* addr[1] = I/O Expander 7 B */ + {8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */ + }, +}; + + + +struct inv_port_layout_s gulmohar_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 10, 0, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 1} }, + { 1, 11, 0, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 2} }, + { 2, 12, 0, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 3} }, + { 3, 13, 0, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 4} }, + { 4, 14, 0, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 5} }, + { 5, 15, 0, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 6} }, + { 6, 16, 0, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 7} }, + { 7, 17, 0, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 8} }, + { 8, 18, 1, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 9} }, + { 9, 19, 1, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 10} }, + {10, 20, 1, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 11} }, + {11, 21, 1, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 12} }, + {12, 22, 1, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 21} }, + {13, 23, 1, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 22} }, + {14, 24, 1, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 23} }, + {15, 25, 1, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 24} }, + {16, 26, 2, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 33} }, + {17, 27, 2, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 34} }, + {18, 28, 2, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 35} }, + {19, 29, 2, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 36} }, + {20, 30, 2, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 37} }, + {21, 31, 2, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 38} }, + {22, 32, 2, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 39} }, + {23, 33, 2, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 40} }, + {24, 34, 3, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 41} }, + {25, 35, 3, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 42} }, + {26, 36, 3, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 43} }, + {27, 37, 3, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 44} }, + {28, 38, 3, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 49} }, + {29, 39, 3, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 50} }, + {30, 40, 3, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 51} }, + {31, 41, 3, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 52} }, + {32, 42, 4, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 53} }, + {33, 43, 4, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 54} }, + {34, 44, 4, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 55} }, + {35, 45, 4, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 56} }, + {36, 46, 4, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 65} }, + {37, 47, 4, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 66} }, + {38, 48, 4, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 67} }, + {39, 49, 4, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 68} }, + {40, 50, 5, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 69} }, + {41, 51, 5, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 70} }, + {42, 52, 5, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 71} }, + {43, 53, 5, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 72} }, + {44, 54, 5, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 81} }, + {45, 55, 5, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 82} }, + {46, 56, 5, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 83} }, + {47, 57, 5, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 84} }, + {48, 58, 6, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 97, 98, 99,100} }, + {49, 59, 6, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 85, 86, 87, 88} }, + {50, 60, 6, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {101,102,103,104} }, + {51, 61, 6, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {105,106,107,108} }, + {52, 62, 6, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {109,110,111,112} }, + {53, 63, 6, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {109,110,111,112} }, +}; +#endif + + +/* ========================================== + * Gulmohar_2T EVT1 Layout configuration + * ========================================== + */ +#ifdef SWPS_GULMOHAR_2T_EVT1 +unsigned gulmohar_2t_evt1_gpio_rest_mux = MUX_RST_GPIO_505_PCA9548; + +struct inv_ioexp_layout_s gulmohar_2t_evt1_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC,{ {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */ + {2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {1, IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC,{ {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */ + {3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {2, IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC,{ {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */ + {4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {3, IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC,{ {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */ + {5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {4, IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC,{ {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */ + {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */ + {6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {5, IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC,{ {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */ + {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {6, IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC,{ {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xd6, 0xda}, {0x18, 0xe3}, }, /* addr[0] = I/O Expander 7 A */ + {8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xd6, 0xda}, {0x18, 0xe3}, }, /* addr[1] = I/O Expander 7 B */ + {8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xd6, 0xff}, {0x18, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */ + }, +}; + + + +struct inv_port_layout_s gulmohar_2t_evt1_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 10, 0, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + { 1, 11, 0, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + { 2, 12, 0, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + { 3, 13, 0, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + { 4, 14, 0, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + { 5, 15, 0, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + { 6, 16, 0, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + { 7, 17, 0, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + { 8, 18, 1, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + { 9, 19, 1, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {10, 20, 1, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {11, 21, 1, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {12, 22, 1, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {13, 23, 1, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {14, 24, 1, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {15, 25, 1, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {16, 26, 2, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {17, 27, 2, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {18, 28, 2, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {19, 29, 2, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {20, 30, 2, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {21, 31, 2, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {22, 32, 2, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {23, 33, 2, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {24, 34, 3, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {25, 35, 3, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {26, 36, 3, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {27, 37, 3, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {28, 38, 3, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {29, 39, 3, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {30, 40, 3, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {31, 41, 3, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {32, 42, 4, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {33, 43, 4, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {34, 44, 4, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {35, 45, 4, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {36, 46, 4, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {37, 47, 4, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {38, 48, 4, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {39, 49, 4, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {40, 50, 5, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {41, 51, 5, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {42, 52, 5, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {43, 53, 5, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {44, 54, 5, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {45, 55, 5, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {46, 56, 5, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {47, 57, 5, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} }, + {48, 59, 6, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {-99,-99,-99,-99} }, + {49, 58, 6, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {-99,-99,-99,-99} }, + {50, 61, 6, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {-99,-99,-99,-99} }, + {51, 60, 6, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {-99,-99,-99,-99} }, + {52, 63, 6, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {-99,-99,-99,-99} }, + {53, 62, 6, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {-99,-99,-99,-99} }, + {54, 65, 6, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {-99,-99,-99,-99} }, + {55, 64, 6, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {-99,-99,-99,-99} }, +}; +#endif + + +/* =========================================================== + * Peony-SFP Layout configuration + * =========================================================== + */ +#ifdef SWPS_PEONY_SFP +unsigned peony_sfp_gpio_rest_mux = MUX_RST_CPLD_C0_A77_70_74_RST_ALL; + +struct inv_ioexp_layout_s peony_sfp_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_QSFP_6P_LAYOUT_1, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 0 A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xff}, }, /* addr[1] = I/O Expander 0 B */ + {4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */ + }, + {1, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {2, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {3, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {4, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {5, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {9, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {9, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {9, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {6, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {10, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {10, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {10, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, +}; + +struct inv_port_layout_s peony_sfp_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 20, 1, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 1} }, + { 1, 21, 1, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 2} }, + { 2, 22, 1, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 3} }, + { 3, 23, 1, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 4} }, + { 4, 24, 1, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 5} }, + { 5, 25, 1, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 6} }, + { 6, 26, 1, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 7} }, + { 7, 27, 1, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 8} }, + { 8, 28, 2, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 13} }, + { 9, 29, 2, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 14} }, + {10, 30, 2, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 15} }, + {11, 31, 2, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 16} }, + {12, 32, 2, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 21} }, + {13, 33, 2, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 22} }, + {14, 34, 2, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 23} }, + {15, 35, 2, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 24} }, + {16, 36, 3, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 29} }, + {17, 37, 3, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 30} }, + {18, 38, 3, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 31} }, + {19, 39, 3, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 32} }, + {20, 40, 3, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 33} }, + {21, 41, 3, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 34} }, + {22, 42, 3, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 35} }, + {23, 43, 3, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 36} }, + {24, 44, 4, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 65} }, + {25, 45, 4, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 66} }, + {26, 46, 4, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 67} }, + {27, 47, 4, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 68} }, + {28, 48, 4, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 69} }, + {29, 49, 4, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 70} }, + {30, 50, 4, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 71} }, + {31, 51, 4, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 72} }, + {32, 52, 5, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 97} }, + {33, 53, 5, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 98} }, + {34, 54, 5, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, { 99} }, + {35, 55, 5, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, {100} }, + {36, 56, 5, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, {105} }, + {37, 57, 5, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, {106} }, + {38, 58, 5, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, {107} }, + {39, 59, 5, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, {108} }, + {40, 60, 6, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, {113} }, + {41, 61, 6, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, {114} }, + {42, 62, 6, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, {115} }, + {43, 63, 6, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, {116} }, + {44, 64, 6, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, {121} }, + {45, 65, 6, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, {122} }, + {46, 66, 6, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, {123} }, + {47, 67, 6, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_MAPLE, {124} }, + {48, 12, 0, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 49, 50, 51, 52} }, + {49, 13, 0, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 57, 58, 59, 60} }, + {50, 14, 0, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 61, 62, 63, 64} }, + {51, 15, 0, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 77, 78, 79, 80} }, + {52, 16, 0, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 85, 86, 87, 88} }, + {53, 17, 0, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 93, 94, 95, 96} }, +}; +#endif + + +/* =========================================================== + * Peony-Copper Layout configuration + * =========================================================== + */ +#ifdef SWPS_PEONY_COPPER +unsigned peony_copper_gpio_rest_mux = MUX_RST_CPLD_C0_A77_70_74_RST_ALL; + +struct inv_ioexp_layout_s peony_copper_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_QSFP_6P_LAYOUT_1, { {10, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 0 A */ + {10, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xff}, }, /* addr[1] = I/O Expander 0 B */ + {10, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */ + }, +}; + +struct inv_port_layout_s peony_copper_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + {48, 4, 0, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 49, 50, 51, 52} }, + {49, 5, 0, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 57, 58, 59, 60} }, + {50, 6, 0, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 61, 62, 63, 64} }, + {51, 7, 0, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 77, 78, 79, 80} }, + {52, 8, 0, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 85, 86, 87, 88} }, + {53, 9, 0, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 93, 94, 95, 96} }, +}; +#endif + + +/* =========================================================== + * Cedar Layout configuration + * =========================================================== + */ +#ifdef SWPS_CEDAR_GA +unsigned cedar_ga_gpio_rest_mux = MUX_RST_GPIO_69_PCA9548; + +struct inv_ioexp_layout_s cedar_ga_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_CEDAR_0ABC, { { 4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 0 A */ + { 4, 0x21, {0,-1}, {1,-1}, {3,-1}, {0xff }, {0x00 }, }, /* addr[1] = I/O Expander 0 B */ + { 4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */ + }, + {1, IOEXP_TYPE_CEDAR_0ABC, { { 5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 0 A */ + { 5, 0x21, {0,-1}, {1,-1}, {3,-1}, {0xff }, {0x00 }, }, /* addr[1] = I/O Expander 0 B */ + { 5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */ + }, + {2, IOEXP_TYPE_CEDAR_0ABC, { { 6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 0 A */ + { 6, 0x21, {0,-1}, {1,-1}, {3,-1}, {0xff }, {0x00 }, }, /* addr[1] = I/O Expander 0 B */ + { 6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */ + }, + {3, IOEXP_TYPE_CEDAR_0ABC, { { 7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 0 A */ + { 7, 0x21, {0,-1}, {1,-1}, {3,-1}, {0xff }, {0x00 }, }, /* addr[1] = I/O Expander 0 B */ + { 7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */ + }, +}; + +struct inv_port_layout_s cedar_ga_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / CHIP_TYPE / LANE_ID */ + { 0, 12, 0, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 21, 22, 23, 24} }, + { 1, 13, 0, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 17, 18, 19, 20} }, + { 2, 14, 0, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 25, 26, 27, 28} }, + { 3, 15, 0, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 29, 30, 31, 32} }, + { 4, 16, 0, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 37, 38, 39, 40} }, + { 5, 17, 0, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 33, 34, 35, 36} }, + { 6, 18, 0, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 41, 42, 43, 44} }, + { 7, 19, 0, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 45, 46, 47, 48} }, + { 8, 20, 1, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 5, 6, 7, 8} }, + { 9, 21, 1, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 1, 2, 3, 4} }, + {10, 22, 1, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 9, 10, 11, 12} }, + {11, 23, 1, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 13, 14, 15, 16} }, + {12, 24, 1, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 53, 54, 55, 56} }, + {13, 25, 1, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 49, 50, 51, 52} }, + {14, 26, 1, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 57, 58, 59, 60} }, + {15, 27, 1, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 61, 62, 63, 64} }, + {16, 28, 2, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 71, 72, 73, 74} }, + {17, 29, 2, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 67, 68, 69, 70} }, + {18, 30, 2, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 75, 76, 77, 78} }, + {19, 31, 2, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 79, 80, 81, 82} }, + {20, 32, 2, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 119, 120, 121, 122} }, + {21, 33, 2, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 115, 116, 117, 118} }, + {22, 34, 2, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 123, 124, 125, 126} }, + {23, 35, 2, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 127, 128, 129, 130} }, + {24, 36, 3, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 87, 88, 89, 90} }, + {25, 37, 3, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 83, 84, 85, 86} }, + {26, 38, 3, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 91, 92, 93, 94} }, + {27, 39, 3, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 95, 96, 97, 98} }, + {28, 40, 3, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 103, 104, 105, 106} }, + {29, 41, 3, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 99, 100, 101, 102} }, + {30, 42, 3, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 107, 108, 109, 110} }, + {31, 43, 3, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_MAPLE, { 111, 112, 113, 114} }, +}; +#endif + + +#endif /* INV_SWPS_H */ + + + + + + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/io_expander.c b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/io_expander.c new file mode 100644 index 000000000000..6867bbc6030e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/io_expander.c @@ -0,0 +1,2579 @@ +#include +#include +#include "io_expander.h" + +/* For build single module using (Ex: ONL platform) */ +#include +//#include + + +static struct ioexp_obj_s *ioexp_head_p = NULL; +static struct ioexp_obj_s *ioexp_tail_p = NULL; +extern int io_no_init; + +/* ========== Register IOEXP layout ========== + */ +struct ioexp_map_s ioexp_map_magnolia_nab = { + + .chip_amount = 2, + .data_width = 2, + + .map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 0, 5}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 0, 6}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 0, 7}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {1, 0, 6}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {1, 0, 7}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_tx_disable = { {0, 1, 0}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 1, 1}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 2}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 3}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + {1, 1, 0}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */ + {1, 1, 1}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */ + {1, 1, 2}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */ + {1, 1, 3}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */ + }, + .map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 0, 1}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 0, 2}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 0, 3}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + {1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */ + {1, 0, 1}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */ + {1, 0, 2}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */ + {1, 0, 3}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */ + }, + .map_rxlos = { {0, 1, 4}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 1, 5}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 1, 6}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + {1, 1, 4}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */ + {1, 1, 5}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */ + {1, 1, 6}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */ + {1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_magnolia_4ab = { + + .chip_amount = 2, + .data_width = 2, + + .map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 0, 5}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 0, 6}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 0, 7}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {1, 0, 6}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {1, 0, 7}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_tx_disable = { {0, 1, 0}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 1, 1}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 2}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 3}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + {1, 0, 0}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */ + {1, 0, 1}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */ + {1, 0, 2}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */ + {1, 0, 3}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */ + }, + .map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 0, 1}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 0, 2}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 0, 3}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + {1, 1, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */ + {1, 1, 1}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */ + {1, 1, 2}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */ + {1, 1, 3}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */ + }, + .map_rxlos = { {0, 1, 4}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 1, 5}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 1, 6}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + {1, 1, 4}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */ + {1, 1, 5}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */ + {1, 1, 6}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */ + {1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_magnolia_7ab = { + + .chip_amount = 2, + .data_width = 2, + + .map_present = { {1, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */ + {1, 0, 5}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {1, 0, 6}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {1, 0, 7}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 1, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 1, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + }, + .map_reset = { {0, 0, 0}, /* map_reset[0] = QRESET_QSFP_N_P(X) */ + {0, 0, 1}, /* map_reset[1] = QRESET_QSFP_N_P(X+1) */ + {0, 0, 2}, /* map_reset[2] = QRESET_QSFP_N_P(X+2) */ + {0, 0, 3}, /* map_reset[3] = QRESET_QSFP_N_P(X+3) */ + {1, 0, 0}, /* map_reset[4] = QRESET_QSFP_N_P(X+4) */ + {1, 0, 1}, /* map_reset[5] = QRESET_QSFP_N_P(X+5) */ + }, + .map_lpmod = { {0, 0, 4}, /* map_lpmod[0] = LPMODE_QSFP_P(X) */ + {0, 0, 5}, /* map_lpmod[1] = LPMODE_QSFP_P(X+1) */ + {0, 0, 6}, /* map_lpmod[2] = LPMODE_QSFP_P(X+2) */ + {0, 0, 7}, /* map_lpmod[3] = LPMODE_QSFP_P(X+3) */ + {1, 0, 2}, /* map_lpmod[4] = LPMODE_QSFP_P(X+4) */ + {1, 0, 3}, /* map_lpmod[5] = LPMODE_QSFP_P(X+5) */ + }, + .map_modsel = { {0, 1, 4}, /* map_modsel[0] = MODSEL_QSFP_N_P(X) */ + {0, 1, 5}, /* map_modsel[1] = MODSEL_QSFP_N_P(X+1) */ + {0, 1, 6}, /* map_modsel[2] = MODSEL_QSFP_N_P(X+2) */ + {0, 1, 7}, /* map_modsel[3] = MODSEL_QSFP_N_P(X+3) */ + {1, 1, 4}, /* map_modsel[4] = MODSEL_QSFP_N_P(X+4) */ + {1, 1, 5}, /* map_modsel[5] = MODSEL_QSFP_N_P(X+5) */ + }, +}; + + +struct ioexp_map_s ioexp_map_redwood_p01p08_p17p24 = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {2, 0, 0}, /* map_present[0] = MOD_ABS_PORT(X) */ + {2, 0, 1}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {2, 0, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {2, 0, 3}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {2, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {2, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {2, 0, 6}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {2, 0, 7}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_reset = { {0, 0, 0}, /* map_reset[0] = QRESET_QSFP28_N_P(X) */ + {0, 0, 1}, /* map_reset[1] = QRESET_QSFP28_N_P(X+1) */ + {0, 0, 2}, /* map_reset[2] = QRESET_QSFP28_N_P(X+2) */ + {0, 0, 3}, /* map_reset[3] = QRESET_QSFP28_N_P(X+3) */ + {1, 0, 0}, /* map_reset[4] = QRESET_QSFP28_N_P(X+4) */ + {1, 0, 1}, /* map_reset[5] = QRESET_QSFP28_N_P(X+5) */ + {1, 0, 2}, /* map_reset[6] = QRESET_QSFP28_N_P(X+6) */ + {1, 0, 3}, /* map_reset[7] = QRESET_QSFP28_N_P(X+7) */ + }, + .map_lpmod = { {0, 0, 4}, /* map_lpmod[0] = LPMODE_QSFP28_P(X) */ + {0, 0, 5}, /* map_lpmod[1] = LPMODE_QSFP28_P(X+1) */ + {0, 0, 6}, /* map_lpmod[2] = LPMODE_QSFP28_P(X+2) */ + {0, 0, 7}, /* map_lpmod[3] = LPMODE_QSFP28_P(X+3) */ + {1, 0, 4}, /* map_lpmod[4] = LPMODE_QSFP28_P(X+4) */ + {1, 0, 5}, /* map_lpmod[5] = LPMODE_QSFP28_P(X+5) */ + {1, 0, 6}, /* map_lpmod[6] = LPMODE_QSFP28_P(X+6) */ + {1, 0, 7}, /* map_lpmod[7] = LPMODE_QSFP28_P(X+7) */ + }, + .map_modsel = { {0, 1, 4}, /* map_modsel[0] = MODSEL_QSFP28_N_P(X) */ + {0, 1, 5}, /* map_modsel[1] = MODSEL_QSFP28_N_P(X+1) */ + {0, 1, 6}, /* map_modsel[2] = MODSEL_QSFP28_N_P(X+2) */ + {0, 1, 7}, /* map_modsel[3] = MODSEL_QSFP28_N_P(X+3) */ + {1, 1, 4}, /* map_modsel[4] = MODSEL_QSFP28_N_P(X+4) */ + {1, 1, 5}, /* map_modsel[5] = MODSEL_QSFP28_N_P(X+5) */ + {1, 1, 6}, /* map_modsel[6] = MODSEL_QSFP28_N_P(X+6) */ + {1, 1, 7}, /* map_modsel[7] = MODSEL_QSFP28_N_P(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_redwood_p09p16_p25p32 = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {2, 1, 0}, /* map_present[0] = MOD_ABS_PORT(X) */ + {2, 1, 1}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {2, 1, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {2, 1, 3}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {2, 1, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {2, 1, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {2, 1, 6}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {2, 1, 7}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_reset = { {0, 0, 0}, /* map_reset[0] = QRESET_QSFP28_N_P(X) */ + {0, 0, 1}, /* map_reset[1] = QRESET_QSFP28_N_P(X+1) */ + {0, 0, 2}, /* map_reset[2] = QRESET_QSFP28_N_P(X+2) */ + {0, 0, 3}, /* map_reset[3] = QRESET_QSFP28_N_P(X+3) */ + {1, 0, 0}, /* map_reset[4] = QRESET_QSFP28_N_P(X+4) */ + {1, 0, 1}, /* map_reset[5] = QRESET_QSFP28_N_P(X+5) */ + {1, 0, 2}, /* map_reset[6] = QRESET_QSFP28_N_P(X+6) */ + {1, 0, 3}, /* map_reset[7] = QRESET_QSFP28_N_P(X+7) */ + }, + .map_lpmod = { {0, 0, 4}, /* map_lpmod[0] = LPMODE_QSFP28_P(X) */ + {0, 0, 5}, /* map_lpmod[1] = LPMODE_QSFP28_P(X+1) */ + {0, 0, 6}, /* map_lpmod[2] = LPMODE_QSFP28_P(X+2) */ + {0, 0, 7}, /* map_lpmod[3] = LPMODE_QSFP28_P(X+3) */ + {1, 0, 4}, /* map_lpmod[4] = LPMODE_QSFP28_P(X+4) */ + {1, 0, 5}, /* map_lpmod[5] = LPMODE_QSFP28_P(X+5) */ + {1, 0, 6}, /* map_lpmod[6] = LPMODE_QSFP28_P(X+6) */ + {1, 0, 7}, /* map_lpmod[7] = LPMODE_QSFP28_P(X+7) */ + }, + .map_modsel = { {0, 1, 4}, /* map_modsel[0] = MODSEL_QSFP28_N_P(X) */ + {0, 1, 5}, /* map_modsel[1] = MODSEL_QSFP28_N_P(X+1) */ + {0, 1, 6}, /* map_modsel[2] = MODSEL_QSFP28_N_P(X+2) */ + {0, 1, 7}, /* map_modsel[3] = MODSEL_QSFP28_N_P(X+3) */ + {1, 1, 4}, /* map_modsel[4] = MODSEL_QSFP28_N_P(X+4) */ + {1, 1, 5}, /* map_modsel[5] = MODSEL_QSFP28_N_P(X+5) */ + {1, 1, 6}, /* map_modsel[6] = MODSEL_QSFP28_N_P(X+6) */ + {1, 1, 7}, /* map_modsel[7] = MODSEL_QSFP28_N_P(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_hudson32iga_p01p08_p17p24 = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {2, 0, 0}, /* map_present[0] = MODABS_QSFP(X) */ + {2, 0, 1}, /* map_present[1] = MODABS_QSFP(X+1) */ + {2, 0, 2}, /* map_present[2] = MODABS_QSFP(X+2) */ + {2, 0, 3}, /* map_present[3] = MODABS_QSFP(X+3) */ + {2, 0, 4}, /* map_present[4] = MODABS_QSFP(X+4) */ + {2, 0, 5}, /* map_present[5] = MODABS_QSFP(X+5) */ + {2, 0, 6}, /* map_present[6] = MODABS_QSFP(X+6) */ + {2, 0, 7}, /* map_present[7] = MODABS_QSFP(X+7) */ + }, + .map_reset = { {0, 0, 0}, /* map_reset[0] = QRESET_QSFP(X) */ + {0, 0, 1}, /* map_reset[1] = QRESET_QSFP(X+1) */ + {0, 0, 2}, /* map_reset[2] = QRESET_QSFP(X+2) */ + {0, 0, 3}, /* map_reset[3] = QRESET_QSFP(X+3) */ + {1, 0, 0}, /* map_reset[4] = QRESET_QSFP(X+4) */ + {1, 0, 1}, /* map_reset[5] = QRESET_QSFP(X+5) */ + {1, 0, 2}, /* map_reset[6] = QRESET_QSFP(X+6) */ + {1, 0, 3}, /* map_reset[7] = QRESET_QSFP(X+7) */ + }, + .map_lpmod = { {0, 0, 4}, /* map_lpmod[0] = LPMODE_QSFP(X) */ + {0, 0, 5}, /* map_lpmod[1] = LPMODE_QSFP(X+1) */ + {0, 0, 6}, /* map_lpmod[2] = LPMODE_QSFP(X+2) */ + {0, 0, 7}, /* map_lpmod[3] = LPMODE_QSFP(X+3) */ + {1, 0, 4}, /* map_lpmod[4] = LPMODE_QSFP(X+4) */ + {1, 0, 5}, /* map_lpmod[5] = LPMODE_QSFP(X+5) */ + {1, 0, 6}, /* map_lpmod[6] = LPMODE_QSFP(X+6) */ + {1, 0, 7}, /* map_lpmod[7] = LPMODE_QSFP(X+7) */ + }, + .map_modsel = { {0, 1, 4}, /* map_modsel[0] = MODSEL_QSFP(X) */ + {0, 1, 5}, /* map_modsel[1] = MODSEL_QSFP(X+1) */ + {0, 1, 6}, /* map_modsel[2] = MODSEL_QSFP(X+2) */ + {0, 1, 7}, /* map_modsel[3] = MODSEL_QSFP(X+3) */ + {1, 1, 4}, /* map_modsel[4] = MODSEL_QSFP(X+4) */ + {1, 1, 5}, /* map_modsel[5] = MODSEL_QSFP(X+5) */ + {1, 1, 6}, /* map_modsel[6] = MODSEL_QSFP(X+6) */ + {1, 1, 7}, /* map_modsel[7] = MODSEL_QSFP(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_hudson32iga_p09p16_p25p32 = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {2, 1, 0}, /* map_present[0] = MODABS_QSFP(X) */ + {2, 1, 1}, /* map_present[1] = MODABS_QSFP(X+1) */ + {2, 1, 2}, /* map_present[2] = MODABS_QSFP(X+2) */ + {2, 1, 3}, /* map_present[3] = MODABS_QSFP(X+3) */ + {2, 1, 4}, /* map_present[4] = MODABS_QSFP(X+4) */ + {2, 1, 5}, /* map_present[5] = MODABS_QSFP(X+5) */ + {2, 1, 6}, /* map_present[6] = MODABS_QSFP(X+6) */ + {2, 1, 7}, /* map_present[7] = MODABS_QSFP(X+7) */ + }, + .map_reset = { {0, 0, 0}, /* map_reset[0] = QRESET_QSFP(X) */ + {0, 0, 1}, /* map_reset[1] = QRESET_QSFP(X+1) */ + {0, 0, 2}, /* map_reset[2] = QRESET_QSFP(X+2) */ + {0, 0, 3}, /* map_reset[3] = QRESET_QSFP(X+3) */ + {1, 0, 0}, /* map_reset[4] = QRESET_QSFP(X+4) */ + {1, 0, 1}, /* map_reset[5] = QRESET_QSFP(X+5) */ + {1, 0, 2}, /* map_reset[6] = QRESET_QSFP(X+6) */ + {1, 0, 3}, /* map_reset[7] = QRESET_QSFP(X+7) */ + }, + .map_lpmod = { {0, 0, 4}, /* map_lpmod[0] = LPMODE_QSFP(X) */ + {0, 0, 5}, /* map_lpmod[1] = LPMODE_QSFP(X+1) */ + {0, 0, 6}, /* map_lpmod[2] = LPMODE_QSFP(X+2) */ + {0, 0, 7}, /* map_lpmod[3] = LPMODE_QSFP(X+3) */ + {1, 0, 4}, /* map_lpmod[4] = LPMODE_QSFP(X+4) */ + {1, 0, 5}, /* map_lpmod[5] = LPMODE_QSFP(X+5) */ + {1, 0, 6}, /* map_lpmod[6] = LPMODE_QSFP(X+6) */ + {1, 0, 7}, /* map_lpmod[7] = LPMODE_QSFP(X+7) */ + }, + .map_modsel = { {0, 1, 4}, /* map_modsel[0] = MODSEL_QSFP(X) */ + {0, 1, 5}, /* map_modsel[1] = MODSEL_QSFP(X+1) */ + {0, 1, 6}, /* map_modsel[2] = MODSEL_QSFP(X+2) */ + {0, 1, 7}, /* map_modsel[3] = MODSEL_QSFP(X+3) */ + {1, 1, 4}, /* map_modsel[4] = MODSEL_QSFP(X+4) */ + {1, 1, 5}, /* map_modsel[5] = MODSEL_QSFP(X+5) */ + {1, 1, 6}, /* map_modsel[6] = MODSEL_QSFP(X+6) */ + {1, 1, 7}, /* map_modsel[7] = MODSEL_QSFP(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_cypress_nabc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 0, 5}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 0, 6}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 0, 7}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {1, 0, 6}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {1, 0, 7}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_tx_disable = { {0, 1, 0}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 1, 1}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 2}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 3}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + {1, 1, 0}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */ + {1, 1, 1}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */ + {1, 1, 2}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */ + {1, 1, 3}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */ + }, + .map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 0, 1}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 0, 2}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 0, 3}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + {1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */ + {1, 0, 1}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */ + {1, 0, 2}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */ + {1, 0, 3}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */ + }, + .map_rxlos = { {0, 1, 4}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 1, 5}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 1, 6}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + {1, 1, 4}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */ + {1, 1, 5}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */ + {1, 1, 6}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */ + {1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */ + }, + .map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */ + {2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */ + {2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */ + {2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */ + {2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */ + {2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */ + {2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */ + {2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */ + }, + .map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */ + {2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */ + {2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */ + {2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */ + {2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */ + {2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */ + {2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */ + {2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_cypress_7abc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {2, 0, 0}, /* map_present[0] = MOD_ABS_PORT(X) */ + {2, 0, 1}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {2, 0, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {2, 0, 3}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {2, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {2, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + }, + .map_reset = { {0, 0, 0}, /* map_reset[0] = QRESET_QSFP_N_P(X) */ + {0, 0, 1}, /* map_reset[1] = QRESET_QSFP_N_P(X+1) */ + {0, 0, 2}, /* map_reset[2] = QRESET_QSFP_N_P(X+2) */ + {0, 0, 3}, /* map_reset[3] = QRESET_QSFP_N_P(X+3) */ + {0, 0, 4}, /* map_reset[4] = QRESET_QSFP_N_P(X+4) */ + {0, 0, 5}, /* map_reset[5] = QRESET_QSFP_N_P(X+5) */ + }, + .map_lpmod = { {0, 1, 0}, /* map_lpmod[0] = LPMODE_QSFP_P(X) */ + {0, 1, 1}, /* map_lpmod[1] = LPMODE_QSFP_P(X+1) */ + {0, 1, 2}, /* map_lpmod[2] = LPMODE_QSFP_P(X+2) */ + {0, 1, 3}, /* map_lpmod[3] = LPMODE_QSFP_P(X+3) */ + {0, 1, 4}, /* map_lpmod[4] = LPMODE_QSFP_P(X+4) */ + {0, 1, 5}, /* map_lpmod[5] = LPMODE_QSFP_P(X+5) */ + }, + .map_modsel = { {1, 1, 0}, /* map_modsel[0] = MODSEL_QSFP_N_P(X) */ + {1, 1, 1}, /* map_modsel[1] = MODSEL_QSFP_N_P(X+1) */ + {1, 1, 2}, /* map_modsel[2] = MODSEL_QSFP_N_P(X+2) */ + {1, 1, 3}, /* map_modsel[3] = MODSEL_QSFP_N_P(X+3) */ + {1, 1, 4}, /* map_modsel[4] = MODSEL_QSFP_N_P(X+4) */ + {1, 1, 5}, /* map_modsel[5] = MODSEL_QSFP_N_P(X+5) */ + }, +}; + + +struct ioexp_map_s ioexp_map_tahoe_5a = { + + .chip_amount = 1, + .data_width = 2, + + .map_present = { {0, 0, 3}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 1, 0}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 1, 5}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + }, + .map_reset = { {0, 0, 1}, /* map_reset[0] = QRESET_QSFP_N_P(X) */ + {0, 0, 6}, /* map_reset[1] = QRESET_QSFP_N_P(X+1) */ + {0, 1, 3}, /* map_reset[2] = QRESET_QSFP_N_P(X+2) */ + }, + .map_lpmod = { {0, 0, 2}, /* map_lpmod[0] = LPMODE_QSFP_P(X) */ + {0, 0, 7}, /* map_lpmod[1] = LPMODE_QSFP_P(X+1) */ + {0, 1, 4}, /* map_lpmod[2] = LPMODE_QSFP_P(X+2) */ + }, + .map_modsel = { {0, 0, 0}, /* map_modsel[0] = MODSEL_QSFP_N_P(X) */ + {0, 0, 5}, /* map_modsel[1] = MODSEL_QSFP_N_P(X+1) */ + {0, 1, 2}, /* map_modsel[2] = MODSEL_QSFP_N_P(X+2) */ + }, +}; + + +struct ioexp_map_s ioexp_map_tahoe_6abc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {0, 0, 3}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 1, 0}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 1, 5}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {1, 0, 3}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 1, 0}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 1, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {2, 0, 3}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {2, 1, 0}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + {2, 1, 5}, /* map_present[8] = MOD_ABS_PORT(X+8) */ + }, + .map_reset = { {0, 0, 1}, /* map_reset[0] = QRESET_QSFP28_N_P(X) */ + {0, 0, 6}, /* map_reset[1] = QRESET_QSFP28_N_P(X+1) */ + {0, 1, 3}, /* map_reset[2] = QRESET_QSFP28_N_P(X+2) */ + {1, 0, 1}, /* map_reset[3] = QRESET_QSFP28_N_P(X+3) */ + {1, 0, 6}, /* map_reset[4] = QRESET_QSFP28_N_P(X+4) */ + {1, 1, 3}, /* map_reset[5] = QRESET_QSFP28_N_P(X+5) */ + {2, 0, 1}, /* map_reset[6] = QRESET_QSFP28_N_P(X+6) */ + {2, 0, 6}, /* map_reset[7] = QRESET_QSFP28_N_P(X+7) */ + {2, 1, 3}, /* map_reset[7] = QRESET_QSFP28_N_P(X+7) */ + }, + .map_lpmod = { {0, 0, 2}, /* map_lpmod[0] = LPMODE_QSFP28_P(X) */ + {0, 0, 7}, /* map_lpmod[1] = LPMODE_QSFP28_P(X+1) */ + {0, 1, 4}, /* map_lpmod[2] = LPMODE_QSFP28_P(X+2) */ + {1, 0, 2}, /* map_lpmod[3] = LPMODE_QSFP28_P(X+3) */ + {1, 0, 7}, /* map_lpmod[4] = LPMODE_QSFP28_P(X+4) */ + {1, 1, 4}, /* map_lpmod[5] = LPMODE_QSFP28_P(X+5) */ + {2, 0, 2}, /* map_lpmod[6] = LPMODE_QSFP28_P(X+6) */ + {2, 0, 7}, /* map_lpmod[7] = LPMODE_QSFP28_P(X+7) */ + {2, 1, 4}, /* map_lpmod[7] = LPMODE_QSFP28_P(X+8) */ + }, + .map_modsel = { {0, 0, 0}, /* map_modsel[0] = MODSEL_QSFP28_N_P(X) */ + {0, 0, 5}, /* map_modsel[1] = MODSEL_QSFP28_N_P(X+1) */ + {0, 1, 2}, /* map_modsel[2] = MODSEL_QSFP28_N_P(X+2) */ + {1, 0, 0}, /* map_modsel[3] = MODSEL_QSFP28_N_P(X+3) */ + {1, 0, 5}, /* map_modsel[4] = MODSEL_QSFP28_N_P(X+4) */ + {1, 1, 2}, /* map_modsel[5] = MODSEL_QSFP28_N_P(X+5) */ + {2, 0, 0}, /* map_modsel[6] = MODSEL_QSFP28_N_P(X+6) */ + {2, 0, 5}, /* map_modsel[7] = MODSEL_QSFP28_N_P(X+7) */ + {2, 1, 2}, /* map_modsel[7] = MODSEL_QSFP28_N_P(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_sequoia_nabc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {2, 1, 0}, /* map_present[0] = MOD_ABS_PORT(X) */ + {2, 1, 1}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {2, 1, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {2, 1, 3}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {2, 1, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {2, 1, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {2, 1, 6}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {2, 1, 7}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_reset = { {0, 1, 0}, /* map_reset[0] = QRESET_QSFP28_N_P(X) */ + {0, 1, 1}, /* map_reset[1] = QRESET_QSFP28_N_P(X+1) */ + {0, 1, 2}, /* map_reset[2] = QRESET_QSFP28_N_P(X+2) */ + {0, 1, 3}, /* map_reset[3] = QRESET_QSFP28_N_P(X+3) */ + {0, 1, 4}, /* map_reset[4] = QRESET_QSFP28_N_P(X+4) */ + {0, 1, 5}, /* map_reset[5] = QRESET_QSFP28_N_P(X+5) */ + {0, 1, 6}, /* map_reset[6] = QRESET_QSFP28_N_P(X+6) */ + {0, 1, 7}, /* map_reset[7] = QRESET_QSFP28_N_P(X+7) */ + }, + .map_lpmod = { {1, 0, 0}, /* map_lpmod[0] = LPMODE_QSFP28_P(X) */ + {1, 0, 1}, /* map_lpmod[1] = LPMODE_QSFP28_P(X+1) */ + {1, 0, 2}, /* map_lpmod[2] = LPMODE_QSFP28_P(X+2) */ + {1, 0, 3}, /* map_lpmod[3] = LPMODE_QSFP28_P(X+3) */ + {1, 0, 4}, /* map_lpmod[4] = LPMODE_QSFP28_P(X+4) */ + {1, 0, 5}, /* map_lpmod[5] = LPMODE_QSFP28_P(X+5) */ + {1, 0, 6}, /* map_lpmod[6] = LPMODE_QSFP28_P(X+6) */ + {1, 0, 7}, /* map_lpmod[7] = LPMODE_QSFP28_P(X+7) */ + }, + .map_modsel = { {0, 0, 0}, /* map_modsel[0] = MODSEL_QSFP28_N_P(X) */ + {0, 0, 1}, /* map_modsel[1] = MODSEL_QSFP28_N_P(X+1) */ + {0, 0, 2}, /* map_modsel[2] = MODSEL_QSFP28_N_P(X+2) */ + {0, 0, 3}, /* map_modsel[3] = MODSEL_QSFP28_N_P(X+3) */ + {0, 0, 4}, /* map_modsel[4] = MODSEL_QSFP28_N_P(X+4) */ + {0, 0, 5}, /* map_modsel[5] = MODSEL_QSFP28_N_P(X+5) */ + {0, 0, 6}, /* map_modsel[6] = MODSEL_QSFP28_N_P(X+6) */ + {0, 0, 7}, /* map_modsel[7] = MODSEL_QSFP28_N_P(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_lavender_p65 = { + + .chip_amount = 1, + .data_width = 1, + + .map_present = { {0, 0, 4}, }, /* map_present[0] = MOD_ABS_PORT(X) */ + .map_reset = { {0, 0, 1}, }, /* map_reset[0] = QRESET_QSFP28_N_P(X) */ + .map_lpmod = { {0, 0, 2}, }, /* map_lpmod[0] = LPMODE_QSFP28_P(X) */ + .map_modsel = { {0, 0, 0}, }, /* map_modsel[0] = MODSEL_QSFP28_N_P(X) */ +}; + + +struct ioexp_map_s cpld_map_cottonwood = { + + .chip_amount = 1, + .data_width = 4, + + .map_present = { {0, 2, 0}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 2, 4}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 3, 0}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 3, 4}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + }, + .map_tx_disable = { {0, 0, 0}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 0, 4}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 0}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 4}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + }, + .map_tx_fault = { {0, 2, 2}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 2, 6}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 3, 2}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 3, 6}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + }, + .map_rxlos = { {0, 2, 1}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 2, 5}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 3, 1}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 3, 5}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + }, + .map_hard_rs0 = { {0, 0, 2}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */ + {0, 0, 6}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */ + {0, 1, 2}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */ + {0, 1, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */ + }, + .map_hard_rs1 = { {0, 0, 2}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */ + {0, 0, 6}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */ + {0, 1, 2}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */ + {0, 1, 6}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */ + }, +}; + + +struct ioexp_map_s ioexp_map_maple_0abc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {2, 1, 0}, /* map_present[0] = MOD_ABS_PORT(X) */ + {2, 1, 1}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {2, 1, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {2, 1, 3}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {2, 1, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {2, 1, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {2, 1, 6}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {2, 1, 7}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_reset = { {0, 1, 0}, /* map_reset[0] = QRESET_QSFP_N_P(X) */ + {0, 1, 1}, /* map_reset[1] = QRESET_QSFP_N_P(X+1) */ + {0, 1, 2}, /* map_reset[2] = QRESET_QSFP_N_P(X+2) */ + {0, 1, 3}, /* map_reset[3] = QRESET_QSFP_N_P(X+3) */ + {0, 1, 4}, /* map_reset[4] = QRESET_QSFP_N_P(X+4) */ + {0, 1, 5}, /* map_reset[5] = QRESET_QSFP_N_P(X+5) */ + {0, 1, 6}, /* map_reset[6] = QRESET_QSFP_N_P(X+6) */ + {0, 1, 7}, /* map_reset[7] = QRESET_QSFP_N_P(X+7) */ + }, + .map_lpmod = { {1, 0, 0}, /* map_lpmod[0] = LPMODE_QSFP_P(X) */ + {1, 0, 1}, /* map_lpmod[1] = LPMODE_QSFP_P(X+1) */ + {1, 0, 2}, /* map_lpmod[2] = LPMODE_QSFP_P(X+2) */ + {1, 0, 3}, /* map_lpmod[3] = LPMODE_QSFP_P(X+3) */ + {1, 0, 4}, /* map_lpmod[4] = LPMODE_QSFP_P(X+4) */ + {1, 0, 5}, /* map_lpmod[5] = LPMODE_QSFP_P(X+5) */ + {1, 0, 6}, /* map_lpmod[6] = LPMODE_QSFP_P(X+6) */ + {1, 0, 7}, /* map_lpmod[7] = LPMODE_QSFP_P(X+7) */ + }, + .map_modsel = { {0, 0, 0}, /* map_modsel[0] = MODSEL_QSFP_N_P(X) */ + {0, 0, 1}, /* map_modsel[1] = MODSEL_QSFP_N_P(X+1) */ + {0, 0, 2}, /* map_modsel[2] = MODSEL_QSFP_N_P(X+2) */ + {0, 0, 3}, /* map_modsel[3] = MODSEL_QSFP_N_P(X+3) */ + {0, 0, 4}, /* map_modsel[4] = MODSEL_QSFP_N_P(X+4) */ + {0, 0, 5}, /* map_modsel[5] = MODSEL_QSFP_N_P(X+5) */ + {0, 0, 6}, /* map_modsel[6] = MODSEL_QSFP_N_P(X+6) */ + {0, 0, 7}, /* map_modsel[7] = MODSEL_QSFP_N_P(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_maple_nabc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 0, 5}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 0, 6}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 0, 7}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {1, 0, 6}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {1, 0, 7}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_tx_disable = { {0, 1, 0}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 1, 1}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 2}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 3}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + {1, 1, 0}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */ + {1, 1, 1}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */ + {1, 1, 2}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */ + {1, 1, 3}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */ + }, + .map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 0, 1}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 0, 2}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 0, 3}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + {1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */ + {1, 0, 1}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */ + {1, 0, 2}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */ + {1, 0, 3}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */ + }, + .map_rxlos = { {0, 1, 4}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 1, 5}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 1, 6}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + {1, 1, 4}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */ + {1, 1, 5}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */ + {1, 1, 6}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */ + {1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */ + }, + .map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */ + {2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */ + {2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */ + {2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */ + {2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */ + {2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */ + {2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */ + {2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */ + }, + .map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */ + {2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */ + {2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */ + {2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */ + {2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */ + {2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */ + {2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */ + {2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_gulmohar_nabc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 0, 5}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 1, 4}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 1, 5}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {1, 1, 4}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {1, 1, 5}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_tx_disable = { {0, 0, 2}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 0, 3}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 2}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 3}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + {1, 0, 2}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */ + {1, 0, 3}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */ + {1, 1, 2}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */ + {1, 1, 3}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */ + }, + .map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 0, 1}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 1, 0}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 1, 1}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + {1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */ + {1, 0, 1}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */ + {1, 1, 0}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */ + {1, 1, 1}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */ + }, + .map_rxlos = { {0, 0, 6}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 0, 7}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 1, 6}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + {1, 0, 6}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */ + {1, 0, 7}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */ + {1, 1, 6}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */ + {1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */ + }, + .map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */ + {2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */ + {2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */ + {2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */ + {2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */ + {2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */ + {2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */ + {2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */ + }, + .map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */ + {2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */ + {2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */ + {2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */ + {2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */ + {2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */ + {2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */ + {2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_gulmohar_7abc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {2, 1, 0}, /* map_present[0] = MOD_ABS_PORT(X) */ + {2, 1, 1}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {2, 1, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {2, 1, 3}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {2, 1, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {2, 1, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + }, + .map_reset = { {0, 1, 0}, /* map_reset[0] = QRESET_QSFP_N_P(X) */ + {0, 1, 1}, /* map_reset[1] = QRESET_QSFP_N_P(X+1) */ + {0, 1, 2}, /* map_reset[2] = QRESET_QSFP_N_P(X+2) */ + {0, 1, 3}, /* map_reset[3] = QRESET_QSFP_N_P(X+3) */ + {0, 1, 4}, /* map_reset[4] = QRESET_QSFP_N_P(X+4) */ + {0, 1, 5}, /* map_reset[5] = QRESET_QSFP_N_P(X+5) */ + }, + .map_lpmod = { {1, 0, 0}, /* map_lpmod[0] = LPMODE_QSFP_P(X) */ + {1, 0, 1}, /* map_lpmod[1] = LPMODE_QSFP_P(X+1) */ + {1, 0, 2}, /* map_lpmod[2] = LPMODE_QSFP_P(X+2) */ + {1, 0, 3}, /* map_lpmod[3] = LPMODE_QSFP_P(X+3) */ + {1, 0, 4}, /* map_lpmod[4] = LPMODE_QSFP_P(X+4) */ + {1, 0, 5}, /* map_lpmod[5] = LPMODE_QSFP_P(X+5) */ + }, + .map_modsel = { {0, 0, 0}, /* map_modsel[0] = MODSEL_QSFP_N_P(X) */ + {0, 0, 1}, /* map_modsel[1] = MODSEL_QSFP_N_P(X+1) */ + {0, 0, 2}, /* map_modsel[2] = MODSEL_QSFP_N_P(X+2) */ + {0, 0, 3}, /* map_modsel[3] = MODSEL_QSFP_N_P(X+3) */ + {0, 0, 4}, /* map_modsel[4] = MODSEL_QSFP_N_P(X+4) */ + {0, 0, 5}, /* map_modsel[5] = MODSEL_QSFP_N_P(X+5) */ + }, +}; + + +struct ioexp_map_s ioexp_map_gulmohar_2t_evt1_nabc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {0, 0, 2}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 0, 6}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 1, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 1, 6}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 0, 2}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 0, 6}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {1, 1, 2}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {1, 1, 6}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_tx_disable = { {0, 0, 1}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 0, 5}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 1}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 5}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + {1, 0, 1}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */ + {1, 0, 5}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */ + {1, 1, 1}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */ + {1, 1, 5}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */ + }, + .map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 0, 4}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 1, 0}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 1, 4}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + {1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */ + {1, 0, 4}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */ + {1, 1, 0}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */ + {1, 1, 4}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */ + }, + .map_rxlos = { {0, 0, 3}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 0, 7}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 1, 3}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + {1, 0, 3}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */ + {1, 0, 7}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */ + {1, 1, 3}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */ + {1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */ + }, + .map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */ + {2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */ + {2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */ + {2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */ + {2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */ + {2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */ + {2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */ + {2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */ + }, + .map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */ + {2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */ + {2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */ + {2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */ + {2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */ + {2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */ + {2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */ + {2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_gulmohar_2t_evt1_1abc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {0, 0, 2}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 0, 6}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 1, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 1, 6}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {1, 1, 4}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {1, 1, 5}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_tx_disable = { {0, 0, 1}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 0, 5}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 1}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 5}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + {1, 0, 2}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */ + {1, 0, 3}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */ + {1, 1, 2}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */ + {1, 1, 3}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */ + }, + .map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 0, 4}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 1, 0}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 1, 4}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + {1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */ + {1, 0, 1}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */ + {1, 1, 0}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */ + {1, 1, 1}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */ + }, + .map_rxlos = { {0, 0, 3}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 0, 7}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 1, 3}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + {1, 0, 6}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */ + {1, 0, 7}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */ + {1, 1, 6}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */ + {1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */ + }, + .map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */ + {2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */ + {2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */ + {2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */ + {2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */ + {2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */ + {2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */ + {2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */ + }, + .map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */ + {2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */ + {2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */ + {2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */ + {2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */ + {2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */ + {2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */ + {2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_gulmohar_2t_evt1_3abc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 0, 5}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 1, 4}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 1, 5}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 0, 2}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 0, 6}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {1, 1, 2}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {1, 1, 6}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_tx_disable = { {0, 0, 2}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 0, 3}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 2}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 3}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + {1, 0, 1}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */ + {1, 0, 5}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */ + {1, 1, 1}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */ + {1, 1, 5}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */ + }, + .map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 0, 1}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 1, 0}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 1, 1}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + {1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */ + {1, 0, 4}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */ + {1, 1, 0}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */ + {1, 1, 4}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */ + }, + .map_rxlos = { {0, 0, 6}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 0, 7}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 1, 6}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + {1, 0, 3}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */ + {1, 0, 7}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */ + {1, 1, 3}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */ + {1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */ + }, + .map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */ + {2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */ + {2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */ + {2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */ + {2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */ + {2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */ + {2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */ + {2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */ + }, + .map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */ + {2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */ + {2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */ + {2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */ + {2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */ + {2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */ + {2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */ + {2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */ + }, +}; + + + +struct ioexp_map_s ioexp_map_gulmohar_2t_evt1_7abc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 1, 1}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 1, 6}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {1, 0, 4}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 1, 1}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 1, 6}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {2, 0, 4}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {2, 1, 1}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_reset = { {0, 0, 1}, /* map_reset[0] = QRESET_QSFP_N_P(X) */ + {0, 0, 6}, /* map_reset[1] = QRESET_QSFP_N_P(X+1) */ + {0, 1, 3}, /* map_reset[2] = QRESET_QSFP_N_P(X+2) */ + {1, 0, 1}, /* map_reset[3] = QRESET_QSFP_N_P(X+3) */ + {1, 0, 6}, /* map_reset[4] = QRESET_QSFP_N_P(X+4) */ + {1, 1, 3}, /* map_reset[5] = QRESET_QSFP_N_P(X+5) */ + {2, 0, 1}, /* map_reset[6] = QRESET_QSFP_N_P(X+6) */ + {2, 0, 6}, /* map_reset[7] = QRESET_QSFP_N_P(X+7) */ + }, + .map_lpmod = { {0, 0, 2}, /* map_lpmod[0] = LPMODE_QSFP_P(X) */ + {0, 0, 7}, /* map_lpmod[1] = LPMODE_QSFP_P(X+1) */ + {0, 1, 4}, /* map_lpmod[2] = LPMODE_QSFP_P(X+2) */ + {1, 0, 2}, /* map_lpmod[3] = LPMODE_QSFP_P(X+3) */ + {1, 0, 7}, /* map_lpmod[4] = LPMODE_QSFP_P(X+4) */ + {1, 1, 4}, /* map_lpmod[5] = LPMODE_QSFP_P(X+5) */ + {2, 0, 2}, /* map_lpmod[6] = LPMODE_QSFP_P(X+6) */ + {2, 0, 7}, /* map_lpmod[7] = LPMODE_QSFP_P(X+7) */ + }, + .map_modsel = { {0, 0, 0}, /* map_modsel[0] = MODSEL_QSFP_N_P(X) */ + {0, 0, 5}, /* map_modsel[1] = MODSEL_QSFP_N_P(X+1) */ + {0, 1, 2}, /* map_modsel[2] = MODSEL_QSFP_N_P(X+2) */ + {1, 0, 0}, /* map_modsel[3] = MODSEL_QSFP_N_P(X+3) */ + {1, 0, 5}, /* map_modsel[4] = MODSEL_QSFP_N_P(X+4) */ + {1, 1, 2}, /* map_modsel[5] = MODSEL_QSFP_N_P(X+5) */ + {2, 0, 0}, /* map_modsel[6] = MODSEL_QSFP_N_P(X+6) */ + {2, 0, 5}, /* map_modsel[7] = MODSEL_QSFP_N_P(X+7) */ + }, +}; + + +/* PortType: SFP / 8 port + * Platform: Cypress, Peony_SFP + */ +struct ioexp_map_s ioexp_map_sfp_8p_layout_1 = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 0, 5}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 0, 6}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 0, 7}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {1, 0, 6}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {1, 0, 7}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_tx_disable = { {0, 1, 0}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 1, 1}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 2}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 3}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + {1, 1, 0}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */ + {1, 1, 1}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */ + {1, 1, 2}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */ + {1, 1, 3}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */ + }, + .map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 0, 1}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 0, 2}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 0, 3}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + {1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */ + {1, 0, 1}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */ + {1, 0, 2}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */ + {1, 0, 3}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */ + }, + .map_rxlos = { {0, 1, 4}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 1, 5}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 1, 6}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + {1, 1, 4}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */ + {1, 1, 5}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */ + {1, 1, 6}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */ + {1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */ + }, + .map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */ + {2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */ + {2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */ + {2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */ + {2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */ + {2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */ + {2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */ + {2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */ + }, + .map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */ + {2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */ + {2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */ + {2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */ + {2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */ + {2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */ + {2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */ + {2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */ + }, +}; + + +/* PortType: QSFP / 6 port + * Platform: Gulmohar, Peony_SFP, Peony_Copper + */ +struct ioexp_map_s ioexp_map_6p_qsfp_type_1 = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {2, 1, 0}, /* map_present[0] = MOD_ABS_PORT(X) */ + {2, 1, 1}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {2, 1, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {2, 1, 3}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {2, 1, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {2, 1, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + }, + .map_reset = { {0, 1, 0}, /* map_reset[0] = QRESET_QSFP_N_P(X) */ + {0, 1, 1}, /* map_reset[1] = QRESET_QSFP_N_P(X+1) */ + {0, 1, 2}, /* map_reset[2] = QRESET_QSFP_N_P(X+2) */ + {0, 1, 3}, /* map_reset[3] = QRESET_QSFP_N_P(X+3) */ + {0, 1, 4}, /* map_reset[4] = QRESET_QSFP_N_P(X+4) */ + {0, 1, 5}, /* map_reset[5] = QRESET_QSFP_N_P(X+5) */ + }, + .map_lpmod = { {1, 0, 0}, /* map_lpmod[0] = LPMODE_QSFP_P(X) */ + {1, 0, 1}, /* map_lpmod[1] = LPMODE_QSFP_P(X+1) */ + {1, 0, 2}, /* map_lpmod[2] = LPMODE_QSFP_P(X+2) */ + {1, 0, 3}, /* map_lpmod[3] = LPMODE_QSFP_P(X+3) */ + {1, 0, 4}, /* map_lpmod[4] = LPMODE_QSFP_P(X+4) */ + {1, 0, 5}, /* map_lpmod[5] = LPMODE_QSFP_P(X+5) */ + }, + .map_modsel = { {0, 0, 0}, /* map_modsel[0] = MODSEL_QSFP_N_P(X) */ + {0, 0, 1}, /* map_modsel[1] = MODSEL_QSFP_N_P(X+1) */ + {0, 0, 2}, /* map_modsel[2] = MODSEL_QSFP_N_P(X+2) */ + {0, 0, 3}, /* map_modsel[3] = MODSEL_QSFP_N_P(X+3) */ + {0, 0, 4}, /* map_modsel[4] = MODSEL_QSFP_N_P(X+4) */ + {0, 0, 5}, /* map_modsel[5] = MODSEL_QSFP_N_P(X+5) */ + }, +}; + + +/* ========== Private functions ========== + */ +int check_channel_tier_1(void); + +struct i2c_client * +_get_i2c_client(struct ioexp_obj_s *self, + int chip_id){ + + struct ioexp_i2c_s *i2c_curr_p = self->i2c_head_p; + + if (!(i2c_curr_p)){ + SWPS_ERR("%s: i2c_curr_p is NULL\n", __func__); + return NULL; + } + while (i2c_curr_p){ + if ((i2c_curr_p->chip_id) == chip_id){ + return i2c_curr_p->i2c_client_p; + } + i2c_curr_p = i2c_curr_p->next; + } + SWPS_ERR("%s: not exist! :%d\n", __func__, chip_id); + return NULL; +} + + +static int +_common_ioexp_update_one(struct ioexp_obj_s *self, + struct ioexp_addr_s *ioexp_addr, + int chip_id, + int data_width, + int show_err, + char *caller_name) { + int buf = 0; + int err = 0; + int data_id = 0; + int r_offset = 0; + + for(data_id=0; data_idread_offset[data_id]; + if (r_offset < 0) { + SWPS_DEBUG("skip a read_offset <%d>\n", r_offset); + continue; + } + buf = i2c_smbus_read_byte_data(_get_i2c_client(self, chip_id), r_offset); + /* Check error */ + if (buf < 0) { + err = 1; + if (show_err) { + SWPS_INFO("IOEXP-%d read fail! :%d \n", self->ioexp_id, buf); + SWPS_INFO("Dump: :%d :0x%02x :%d, :%s\n", + ioexp_addr->chan_id, ioexp_addr->chip_addr, + ioexp_addr->read_offset[data_id], caller_name); + } + continue; + } + /* Update IOEXP object */ + self->chip_data[chip_id].data[data_id] = (uint8_t)buf; + } + if (err) { + return ERR_IOEXP_UNEXCPT; + } + return 0; +} + + +static int +common_ioexp_update_all(struct ioexp_obj_s *self, + int show_err, + char *caller_name){ + + int err = 0; + int chip_id = 0; + int chip_amount = self->ioexp_map_p->chip_amount; + + for (chip_id=0; chip_idioexp_map_p->map_addr[chip_id]), + chip_id, + self->ioexp_map_p->data_width, + show_err, + caller_name) < 0) { + err = 1; + } + } + if (err) { + return ERR_IOEXP_UNEXCPT; + } + return 0; +} + + +static int +_common_check_by_mode(struct ioexp_obj_s *self){ + + switch (self->mode){ + case IOEXP_MODE_DIRECT: + return self->fsm_4_direct(self); + + case IOEXP_MODE_POLLING: + if (self->state >= 0){ + return 0; + } + switch (self->state){ + case STATE_IOEXP_INIT: + return ERR_IOEXP_UNINIT; + case STATE_IOEXP_ABNORMAL: + return ERR_IOEXP_ABNORMAL; + default: + return ERR_IOEXP_NOSTATE; + } + break; + + default: + break; + } + SWPS_ERR("%s: Exception occurs. :%d \n", __func__, self->mode); + return ERR_IOEXP_UNEXCPT; +} + + +static int +_common_get_bit(struct ioexp_obj_s *self, + struct ioexp_bitmap_s *bitmap_obj_p, + char *func_mane){ + uint8_t buf; + int err_code; + + /* Check and get address */ + err_code = _common_check_by_mode(self); + if (err_code < 0){ + return err_code; + } + if (!bitmap_obj_p){ + SWPS_ERR("Layout config incorrect! :%d :%s\n", + self->ioexp_id, func_mane); + return ERR_IOEXP_BADCONF; + } + /* Get data form cache */ + buf = self->chip_data[bitmap_obj_p->chip_id].data[bitmap_obj_p->ioexp_voffset]; + return (int)(buf >> bitmap_obj_p->bit_shift & 0x01); +} + + +static int +_common_set_bit(struct ioexp_obj_s *self, + struct ioexp_bitmap_s *bitmap_obj_p, + int input_val, + char *func_mane){ + int err_code, target_offset; + uint8_t origin_byte; + uint8_t modify_byte; + + /* Check and get address */ + err_code = _common_check_by_mode(self); + if (err_code < 0){ + return err_code; + } + if (!bitmap_obj_p){ + SWPS_ERR("Layout config incorrect! :%d :%s\n", + self->ioexp_id, func_mane); + return ERR_IOEXP_BADCONF; + } + /* Prepare write date */ + origin_byte = self->chip_data[bitmap_obj_p->chip_id].data[bitmap_obj_p->ioexp_voffset]; + switch (input_val) { + case 0: + modify_byte = origin_byte; + SWP_BIT_CLEAR(modify_byte, bitmap_obj_p->bit_shift); + break; + case 1: + modify_byte = origin_byte; + SWP_BIT_SET(modify_byte, bitmap_obj_p->bit_shift); + break; + default: + SWPS_ERR("Input value incorrect! :%d :%d :%s\n", + input_val, self->ioexp_id, func_mane); + return ERR_IOEXP_BADINPUT; + } + /* Setup i2c client */ + target_offset = self->ioexp_map_p->map_addr[bitmap_obj_p->chip_id].write_offset[bitmap_obj_p->ioexp_voffset]; + /* Write byte to chip via I2C */ + err_code = i2c_smbus_write_byte_data(_get_i2c_client(self, bitmap_obj_p->chip_id), + target_offset, + modify_byte); + /* Update or bollback object */ + if (err_code < 0){ + self->chip_data[bitmap_obj_p->chip_id].data[bitmap_obj_p->ioexp_voffset] = origin_byte; + SWPS_ERR("I2C write fail! :%d :%d :%s :%d\n", + input_val, self->ioexp_id, func_mane, err_code); + return err_code; + } + self->chip_data[bitmap_obj_p->chip_id].data[bitmap_obj_p->ioexp_voffset] = modify_byte; + return 0; +} + + +/* ========== Object public functions ========== + */ +int +common_get_present(struct ioexp_obj_s *self, + int virt_offset){ + + int UNPLUG = 1; + int retval = ERR_IOEXP_UNEXCPT; + + retval = _common_get_bit(self, + &(self->ioexp_map_p->map_present[virt_offset]), + "common_get_present"); + if (retval < 0) { + /* [Note] + * => Transceiver object does not need to handle IOEXP layer issues. + */ + return UNPLUG; + } + return retval; +} + + +int +common_get_tx_fault(struct ioexp_obj_s *self, + int virt_offset){ + /* [Transmit Fault (Tx_Fault)] + * A catastrophic laser fault will activate the transmitter signal, + * TX_FAULT, and disable the laser. This signal is an open collector + * output (pull-up required on the host board). A low signal indicates + * normal laser operation and a high signal indicates a fault. The + * TX_FAULT will be latched high when a laser fault occurs and is + * cleared by toggling the TX_DISABLE input or power cycling the + * transceiver. The transmitter fault condition can also be monitored + * via the two-wire serial interface. + * (address A2, byte 110, bit 2). + * + * 0: Normal + * 1: Abnormal + */ + return _common_get_bit(self, + &(self->ioexp_map_p->map_tx_fault[virt_offset]), + "common_get_tx_fault"); +} + + +int +common_get_rxlos(struct ioexp_obj_s *self, + int virt_offset){ + /* [Receiver Loss of Signal (Rx_LOS)] + * The post-amplification IC also includes transition detection circuitry + * which monitors the ac level of incoming optical signals and provides a + * TTL/CMOS compatible status signal to the host (pin 8). An adequate optical + * input results in a low Rx_LOS output while a high Rx_LOS output indicates + * an unusable optical input. The Rx_LOS thresholds are factory set so that + * a high output indicates a definite optical fault has occurred. Rx_LOS can + * also be monitored via the two-wire serial interface + * (address A2h, byte 110, bit 1). + * + * 0: Normal + * 1: Abnormal + */ + return _common_get_bit(self, + &(self->ioexp_map_p->map_rxlos[virt_offset]), + "common_get_rxlos"); +} + + +int +common_get_tx_disable(struct ioexp_obj_s *self, + int virt_offset){ + + return _common_get_bit(self, + &(self->ioexp_map_p->map_tx_disable[virt_offset]), + "common_get_tx_disable"); +} + + +int +common_get_reset(struct ioexp_obj_s *self, + int virt_offset){ + + return _common_get_bit(self, + &(self->ioexp_map_p->map_reset[virt_offset]), + "common_get_reset"); +} + + +int +common_get_lpmod(struct ioexp_obj_s *self, + int virt_offset){ + + return _common_get_bit(self, + &(self->ioexp_map_p->map_lpmod[virt_offset]), + "common_get_lpmod"); +} + + +int +common_get_modsel(struct ioexp_obj_s *self, + int virt_offset){ + + return _common_get_bit(self, + &(self->ioexp_map_p->map_modsel[virt_offset]), + "common_get_modsel"); +} + + +int +common_get_hard_rs0(struct ioexp_obj_s *self, + int virt_offset){ + + return _common_get_bit(self, + &(self->ioexp_map_p->map_hard_rs0[virt_offset]), + "common_get_hard_rs0"); +} + + +int +common_get_hard_rs1(struct ioexp_obj_s *self, + int virt_offset){ + + return _common_get_bit(self, + &(self->ioexp_map_p->map_hard_rs1[virt_offset]), + "common_get_hard_rs1"); +} + + +int +common_set_tx_disable(struct ioexp_obj_s *self, + int virt_offset, + int input_val){ + + return _common_set_bit(self, + &(self->ioexp_map_p->map_tx_disable[virt_offset]), + input_val, + "common_set_tx_disable"); +} + + +int +common_set_reset(struct ioexp_obj_s *self, + int virt_offset, + int input_val){ + + return _common_set_bit(self, + &(self->ioexp_map_p->map_reset[virt_offset]), + input_val, + "common_set_reset"); +} + + +int +common_set_lpmod(struct ioexp_obj_s *self, + int virt_offset, + int input_val){ + + return _common_set_bit(self, + &(self->ioexp_map_p->map_lpmod[virt_offset]), + input_val, + "common_set_lpmod"); +} + + +int +common_set_modsel(struct ioexp_obj_s *self, + int virt_offset, + int input_val){ + + return _common_set_bit(self, + &(self->ioexp_map_p->map_modsel[virt_offset]), + input_val, + "common_set_modsel"); +} + + +int +common_set_hard_rs0(struct ioexp_obj_s *self, + int virt_offset, + int input_val){ + + return _common_set_bit(self, + &(self->ioexp_map_p->map_hard_rs0[virt_offset]), + input_val, + "common_set_hard_rs0"); +} + + +int +common_set_hard_rs1(struct ioexp_obj_s *self, + int virt_offset, + int input_val){ + + return _common_set_bit(self, + &(self->ioexp_map_p->map_hard_rs1[virt_offset]), + input_val, + "common_set_hard_rs1"); +} + + +int +ioexp_get_not_support(struct ioexp_obj_s *self, + int virt_offset){ + return ERR_IOEXP_NOTSUPPORT; +} + + +int +ioexp_set_not_support(struct ioexp_obj_s *self, + int virt_offset, + int input_val){ + return ERR_IOEXP_NOTSUPPORT; +} + + +int +fake_ioexp_init(struct ioexp_obj_s *self){ + return 1; +} + +int +fake_ioexp_update(struct ioexp_obj_s *self){ + return 1; +} + + +int +fake_update_func(struct ioexp_obj_s *self){ + return 1; +} + +int +fake_get_func(struct ioexp_obj_s *self, + int virt_offset){ + SWPS_WARN("Someone called fake_get_func\n"); + return -1; +} + +int +fake_set_func(struct ioexp_obj_s *self, + int virt_offset, + int input_val){ + SWPS_WARN("Someone called fake_set_func\n"); + return -1; +} + + +/* ========== Initial functions for IO Expander ========== + */ +int +common_ioexp_init(struct ioexp_obj_s *self) { + + int chip_id, offset, err_code; + struct ioexp_addr_s *addr_p; + + if (self->mode == IOEXP_MODE_DIRECT) { + goto update_common_ioexp_init; + } + if (!io_no_init) { /*normal init*/ + + /* Setup default value to each physical IO Expander */ + for (chip_id=0; chip_id<(self->ioexp_map_p->chip_amount); chip_id++){ + /* Get address mapping */ + addr_p = &(self->ioexp_map_p->map_addr[chip_id]); + if (!addr_p){ + SWPS_ERR("%s: IOEXP config incorrect! :%d \n", + __func__, chip_id); + return -1; + } + /* Setup default value */ + for (offset=0; offset<(self->ioexp_map_p->data_width); offset++){ + + /* [Desc] Skip the setup default value behavior + [Note] Setup default value = -1 if you don't want to write the value to IOEXP or CPLD + */ + if(addr_p->write_offset[offset] < 0){ + SWPS_DEBUG("skip a write_offset <%d>\n", addr_p->conf_offset[offset]); + continue; + } + err_code = i2c_smbus_write_byte_data(_get_i2c_client(self, chip_id), + addr_p->write_offset[offset], + addr_p->data_default[offset]); + if (err_code < 0){ + SWPS_ERR("%s: set default fail! :%d \n", + __func__, err_code); + return ERR_IOEXP_UNEXCPT; + } + } + } + } +update_common_ioexp_init: + /* Check and update info to object */ + err_code = self->update_all(self, 1, "common_ioexp_init"); + if (err_code < 0) { + SWPS_ERR("%s: update_all() fail! :%d \n", + __func__, err_code); + return ERR_IOEXP_UNEXCPT; + } + return 0; +} + + +/* ========== Object functions for Final State Machine ========== + */ +int +_is_channel_ready(struct ioexp_obj_s *self){ + + int chip_id = 0; + int byte_id = 0; + int getval = ERR_IOEXP_UNEXCPT; + int chkval = ERR_IOEXP_UNEXCPT; + char *emsg = "ERR"; + struct ioexp_addr_s *addr_p = NULL; + + for (chip_id=0; chip_id<(self->ioexp_map_p->chip_amount); chip_id++) { + addr_p = &(self->ioexp_map_p->map_addr[chip_id]); + if (!addr_p){ + emsg = "IOEXP config incorrect"; + goto err_is_channel_ready; + } + for (byte_id=0; byte_id<(self->ioexp_map_p->data_width); byte_id++) { + if (addr_p->conf_offset[byte_id] < 0) { + continue; + } + if ((addr_p->conf_default[byte_id]) != 0) { + goto go_is_channel_ready; + } + } + if (chip_id == ((self->ioexp_map_p->chip_amount) - 1)) { + SWPS_DEBUG("%s: no non-zero config", __func__); + break; + } + } + chip_id = 0; + byte_id = 0; + +go_is_channel_ready: + addr_p = &(self->ioexp_map_p->map_addr[chip_id]); + chkval = addr_p->conf_default[byte_id]; + getval = i2c_smbus_read_byte_data(_get_i2c_client(self, chip_id), + addr_p->conf_offset[byte_id]); + + SWPS_DEBUG("%s: target info :%d :%d :%d :%d :%d\n", + __func__, self->ioexp_id, chip_id, byte_id, chkval, getval); + + if ((getval >= 0) && (getval == chkval)) { + return 1; + } + return 0; + +err_is_channel_ready: + SWPS_ERR("%s: %s :%d :%d :%d :%d :%d\n", + __func__, emsg, self->ioexp_id, chip_id, byte_id, chkval, getval); + return ERR_IOEXP_UNEXCPT; +} + + +int +_ioexp_init_handler(struct ioexp_obj_s *self){ + + int return_val; + + switch (self->mode) { + case IOEXP_MODE_DIRECT: + return_val = self->init(self); + if (return_val < 0){ + self->state = STATE_IOEXP_ABNORMAL; + } else { + self->state = STATE_IOEXP_NORMAL; + } + return return_val; + + case IOEXP_MODE_POLLING: + /* Check system and channel is ready */ + if (self->state == STATE_IOEXP_INIT){ + if (!_is_channel_ready(self)){ + self->state = STATE_IOEXP_INIT; + SWPS_WARN("%s: IOEXP:%d channel not ready.\n", + __func__, self->ioexp_id); + return 0; + } + } + /* Execute initial callback */ + return_val = self->init(self); + if (return_val < 0){ + self->state = STATE_IOEXP_ABNORMAL; + } else { + self->state = STATE_IOEXP_NORMAL; + } + return return_val; + + default: + break; + } + SWPS_ERR("%s: exception occur :%d\n", __func__, self->mode); + return ERR_IOEXP_UNEXCPT; +} + + +int +common_ioexp_fsm_4_direct(struct ioexp_obj_s *self){ + + int result_val; + int show_err = 1; + char *func_mane = "common_ioexp_fsm_4_direct"; + + switch (self->state){ + case STATE_IOEXP_INIT: + result_val = _ioexp_init_handler(self); + /* Exception case: terminate initial procedure */ + if(result_val < 0){ + /* Initial fail */ + return result_val; + } + if(self->state == STATE_IOEXP_INIT){ + /* Keep in INIT state, and return error */ + return ERR_IOEXP_UNINIT; + } + /* Case: Initial done */ + return 0; + + case STATE_IOEXP_NORMAL: + result_val = self->update_all(self, show_err, func_mane); + if (result_val < 0){ + SWPS_INFO("%s: NORMAL -> ABNORMAL :%d\n", + __func__, result_val); + self->state = STATE_IOEXP_ABNORMAL; + return result_val; + } + self->state = STATE_IOEXP_NORMAL; + return 0; + + case STATE_IOEXP_ABNORMAL: + result_val = self->update_all(self, show_err, func_mane); + if (result_val < 0){ + self->state = STATE_IOEXP_ABNORMAL; + return result_val; + } + SWPS_DEBUG("%s: ABNORMAL -> NORMAL :%d\n", + __func__, result_val); + self->state = STATE_IOEXP_NORMAL; + return 0; + + default: + break; + } + SWPS_ERR("%s: Exception occurs :%d\n", + __func__, self->state); + return ERR_IOEXP_UNEXCPT; +} + + +int +common_ioexp_fsm_4_polling(struct ioexp_obj_s *self){ + + int result_val, i, show_e; + int fail_retry = 3; + char *func_name = "common_ioexp_fsm_4_polling"; + +#ifdef DEBUG_SWPS + show_e = 1; +#else + show_e = 0; +#endif + + switch (self->state){ + case STATE_IOEXP_INIT: + result_val = _ioexp_init_handler(self); + /* Exception case: terminate initial procedure */ + if(result_val < 0){ + /* Initial fail */ + return result_val; + } + /* Case: System (Channel) not ready */ + if(self->state == STATE_IOEXP_INIT){ + /* Keep in INIT state, wait and retry */ + return 0; + } + /* Case: Initial done */ + SWPS_INFO("IOEXP-%d: initial done. :%d\n", + self->ioexp_id, self->ioexp_type); + return result_val; + + case STATE_IOEXP_NORMAL: + /* Retry mechanism for case of i2c topology not stable */ + for (i=0; iupdate_all(self, show_e, func_name); + if (result_val >= 0) { + self->state = STATE_IOEXP_NORMAL; + return 0; + } + if (check_channel_tier_1() < 0) { + SWPS_INFO("%s: detect I2C crash :%d\n", + __func__, self->ioexp_id); + break; + } + SWPS_DEBUG("IOEXP-%d: unstable :%d\n", + self->ioexp_id, result_val); + } + SWPS_INFO("IOEXP-%d: NORMAL -> ABNORMAL :%d\n", + self->ioexp_id, result_val); + self->state = STATE_IOEXP_ABNORMAL; + return result_val; + + case STATE_IOEXP_ABNORMAL: + result_val = self->update_all(self, show_e, func_name); + if (result_val < 0){ + self->state = STATE_IOEXP_ABNORMAL; + return result_val; + } + SWPS_INFO("IOEXP-%d: ABNORMAL -> NORMAL :%d\n", + self->ioexp_id, result_val); + self->state = STATE_IOEXP_NORMAL; + return 0; + + default: + break; + } + SWPS_ERR("IOEXP-%d: Exception occurs :%d\n", + self->ioexp_id, self->state); + return ERR_IOEXP_UNEXCPT; +} + + +/* ========== Object private functions for check & update ========== + */ +int +common_ioexp_check(struct ioexp_obj_s *self){ + + int result; + + if (self->mode != IOEXP_MODE_POLLING){ + SWPS_ERR("%s: not polling mode :%d\n", + __func__, self->mode); + return ERR_IOEXP_NOTSUPPORT; + } + mutex_lock(&self->lock); + result = self->fsm_4_polling(self); + mutex_unlock(&self->lock); + return result; +} + + +/* ========== Functions for Factory pattern ========== + */ +static struct ioexp_map_s * +get_ioexp_map(int ioexp_type){ + switch (ioexp_type){ + case IOEXP_TYPE_MAGINOLIA_NAB: + return &ioexp_map_magnolia_nab; + case IOEXP_TYPE_MAGINOLIA_4AB: + return &ioexp_map_magnolia_4ab; + case IOEXP_TYPE_MAGINOLIA_7AB: + case IOEXP_TYPE_SPRUCE_7AB: + return &ioexp_map_magnolia_7ab; + case IOEXP_TYPE_REDWOOD_P01P08: + return &ioexp_map_redwood_p01p08_p17p24; + case IOEXP_TYPE_REDWOOD_P09P16: + return &ioexp_map_redwood_p09p16_p25p32; + case IOEXP_TYPE_HUDSON32IGA_P01P08: + return &ioexp_map_hudson32iga_p01p08_p17p24; + case IOEXP_TYPE_HUDSON32IGA_P09P16: + return &ioexp_map_hudson32iga_p09p16_p25p32; + case IOEXP_TYPE_CYPRESS_7ABC: + return &ioexp_map_cypress_7abc; + case IOEXP_TYPE_TAHOE_5A: + return &ioexp_map_tahoe_5a; + case IOEXP_TYPE_TAHOE_6ABC: + return &ioexp_map_tahoe_6abc; + case IOEXP_TYPE_SEQUOIA_NABC: + return &ioexp_map_sequoia_nabc; + case IOEXP_TYPE_LAVENDER_P65: + return &ioexp_map_lavender_p65; + case CPLD_TYPE_COTTONWOOD: + return &cpld_map_cottonwood; + case IOEXP_TYPE_MAPLE_0ABC: + case IOEXP_TYPE_CEDAR_0ABC: + return &ioexp_map_maple_0abc; + case IOEXP_TYPE_MAPLE_NABC: + return &ioexp_map_maple_nabc; + case IOEXP_TYPE_GULMOHAR_NABC: + return &ioexp_map_gulmohar_nabc; + case IOEXP_TYPE_GULMOHAR_7ABC: + return &ioexp_map_gulmohar_7abc; + case IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC: + return &ioexp_map_gulmohar_2t_evt1_nabc; + case IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC: + return &ioexp_map_gulmohar_2t_evt1_1abc; + case IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC: + return &ioexp_map_gulmohar_2t_evt1_3abc; + case IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC: + return &ioexp_map_gulmohar_2t_evt1_7abc; + case IOEXP_TYPE_SFP_8P_LAYOUT_1: + return &ioexp_map_sfp_8p_layout_1; + case IOEXP_TYPE_QSFP_6P_LAYOUT_1: + return &ioexp_map_6p_qsfp_type_1; + default: + return NULL; + } +} + + +int +setup_ioexp_ssize_attr(struct ioexp_obj_s *self, + struct ioexp_map_s *ioexp_map_p, + int ioexp_id, + int ioexp_type, + int run_mode){ + switch (run_mode){ + case IOEXP_MODE_POLLING: /* Direct access device mode */ + case IOEXP_MODE_DIRECT: /* Polling mode, read from cache */ + self->mode = run_mode; + break; + default: + SWPS_ERR("%s: non-defined run_mode:%d\n", + __func__, run_mode); + self->mode = ERR_IOEXP_UNEXCPT; + return ERR_IOEXP_UNEXCPT; + } + /* Setup mapping structure */ + self->ioexp_map_p = kzalloc(sizeof(*ioexp_map_p), GFP_KERNEL); + if (!(self->ioexp_map_p)) { + SWPS_ERR("%s: kzalloc ioexp_map_p fail\n", __func__); + return -1; + } + memcpy(self->ioexp_map_p, ioexp_map_p, sizeof(*ioexp_map_p)); + /* Setup attributes */ + self->ioexp_id = ioexp_id; + self->ioexp_type = ioexp_type; + self->state = STATE_IOEXP_INIT; + mutex_init(&self->lock); + return 0; +} + + +static int +setup_addr_mapping(struct ioexp_obj_s *self, + struct ioexp_addr_s *addr_map_p, + int chip_amount){ + struct ioexp_addr_s *tmp_p; + if (!addr_map_p){ + SWPS_ERR("%s: map is null\n", __func__); + return -1; + } + tmp_p = kzalloc((sizeof(*addr_map_p) * chip_amount), GFP_KERNEL); + if (!tmp_p){ + SWPS_ERR("%s: kzalloc fail.\n", __func__); + return -1; + } + memcpy(tmp_p, addr_map_p, (sizeof(*addr_map_p) * chip_amount)); + self->ioexp_map_p->map_addr = tmp_p; + + return 0; +} + + +static int +setup_ioexp_public_cb(struct ioexp_obj_s *self, + int ioexp_type){ + + switch (ioexp_type){ + case IOEXP_TYPE_MAGINOLIA_NAB: + case IOEXP_TYPE_MAGINOLIA_4AB: + case CPLD_TYPE_COTTONWOOD: + self->get_present = common_get_present; + self->get_tx_fault = common_get_tx_fault; + self->get_rxlos = common_get_rxlos; + self->get_tx_disable = common_get_tx_disable; + self->get_reset = ioexp_get_not_support; + self->get_lpmod = ioexp_get_not_support; + self->get_modsel = ioexp_get_not_support; + self->get_hard_rs0 = ioexp_get_not_support; + self->get_hard_rs1 = ioexp_get_not_support; + self->set_tx_disable = common_set_tx_disable; + self->set_reset = ioexp_set_not_support; + self->set_lpmod = ioexp_set_not_support; + self->set_modsel = ioexp_set_not_support; + self->set_hard_rs0 = ioexp_set_not_support; + self->set_hard_rs1 = ioexp_set_not_support; + return 0; + + case IOEXP_TYPE_MAPLE_NABC: + case IOEXP_TYPE_GULMOHAR_NABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC: + case IOEXP_TYPE_SFP_8P_LAYOUT_1: + self->get_present = common_get_present; + self->get_tx_fault = common_get_tx_fault; + self->get_rxlos = common_get_rxlos; + self->get_tx_disable = common_get_tx_disable; + self->get_reset = ioexp_get_not_support; + self->get_lpmod = ioexp_get_not_support; + self->get_modsel = ioexp_get_not_support; + self->get_hard_rs0 = common_get_hard_rs0; + self->get_hard_rs1 = common_get_hard_rs1; + self->set_tx_disable = common_set_tx_disable; + self->set_reset = ioexp_set_not_support; + self->set_lpmod = ioexp_set_not_support; + self->set_modsel = ioexp_set_not_support; + self->set_hard_rs0 = common_set_hard_rs0; + self->set_hard_rs1 = common_set_hard_rs1; + return 0; + + case IOEXP_TYPE_MAGINOLIA_7AB: + case IOEXP_TYPE_SPRUCE_7AB: + case IOEXP_TYPE_REDWOOD_P01P08: + case IOEXP_TYPE_REDWOOD_P09P16: + case IOEXP_TYPE_HUDSON32IGA_P01P08: + case IOEXP_TYPE_HUDSON32IGA_P09P16: + case IOEXP_TYPE_CYPRESS_7ABC: + case IOEXP_TYPE_TAHOE_5A: + case IOEXP_TYPE_TAHOE_6ABC: + case IOEXP_TYPE_SEQUOIA_NABC: + case IOEXP_TYPE_LAVENDER_P65: + case IOEXP_TYPE_MAPLE_0ABC: + case IOEXP_TYPE_GULMOHAR_7ABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC: + case IOEXP_TYPE_QSFP_6P_LAYOUT_1: + case IOEXP_TYPE_CEDAR_0ABC: + self->get_present = common_get_present; + self->get_tx_fault = ioexp_get_not_support; + self->get_rxlos = ioexp_get_not_support; + self->get_tx_disable = ioexp_get_not_support; + self->get_reset = common_get_reset; + self->get_lpmod = common_get_lpmod; + self->get_modsel = common_get_modsel; + self->get_hard_rs0 = ioexp_get_not_support; + self->get_hard_rs1 = ioexp_get_not_support; + self->set_tx_disable = ioexp_set_not_support; + self->set_reset = common_set_reset; + self->set_lpmod = common_set_lpmod; + self->set_modsel = common_set_modsel; + self->set_hard_rs0 = ioexp_set_not_support; + self->set_hard_rs1 = ioexp_set_not_support; + return 0; + + default: + SWPS_ERR("%s: type:%d incorrect!\n", __func__, ioexp_type); + break; + } + return ERR_IOEXP_UNEXCPT; +} + + +static int +setup_ioexp_private_cb(struct ioexp_obj_s *self, + int ioexp_type){ + + switch (ioexp_type){ + case IOEXP_TYPE_MAGINOLIA_NAB: + case IOEXP_TYPE_MAGINOLIA_4AB: + case IOEXP_TYPE_MAGINOLIA_7AB: + case IOEXP_TYPE_SPRUCE_7AB: + case IOEXP_TYPE_REDWOOD_P01P08: + case IOEXP_TYPE_REDWOOD_P09P16: + case IOEXP_TYPE_HUDSON32IGA_P01P08: + case IOEXP_TYPE_HUDSON32IGA_P09P16: + case IOEXP_TYPE_CYPRESS_7ABC: + case IOEXP_TYPE_TAHOE_5A: + case IOEXP_TYPE_TAHOE_6ABC: + case IOEXP_TYPE_SEQUOIA_NABC: + case IOEXP_TYPE_LAVENDER_P65: + case CPLD_TYPE_COTTONWOOD: + case IOEXP_TYPE_MAPLE_NABC: + case IOEXP_TYPE_MAPLE_0ABC: + case IOEXP_TYPE_GULMOHAR_NABC: + case IOEXP_TYPE_GULMOHAR_7ABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC: + case IOEXP_TYPE_SFP_8P_LAYOUT_1: + case IOEXP_TYPE_QSFP_6P_LAYOUT_1: + case IOEXP_TYPE_CEDAR_0ABC: + self->init = common_ioexp_init; + self->check = common_ioexp_check; + self->update_all = common_ioexp_update_all; + self->fsm_4_direct = common_ioexp_fsm_4_direct; + self->fsm_4_polling = common_ioexp_fsm_4_polling; + return 0; + + default: + SWPS_ERR("%s: type:%d incorrect!\n", __func__, ioexp_type); + break; + } + return ERR_IOEXP_UNEXCPT; +} + + +static int +setup_i2c_client_one(struct ioexp_obj_s *self, + int chip_id){ + + char *err_msg = "ERROR"; + struct i2c_adapter *adap = NULL; + struct i2c_client *client = NULL; + struct ioexp_i2c_s *i2c_obj_p = NULL; + struct ioexp_i2c_s *i2c_curr_p = NULL; + + int chan_id = self->ioexp_map_p->map_addr[chip_id].chan_id; + client = kzalloc(sizeof(*client), GFP_KERNEL); + if (!client){ + err_msg = "Can not kzalloc client!"; + goto err_ioexp_setup_i2c_1; + } + i2c_obj_p = kzalloc(sizeof(*i2c_obj_p), GFP_KERNEL); + if (!i2c_obj_p){ + err_msg = "Can not kzalloc i2c_obj_p!"; + goto err_ioexp_setup_i2c_2; + } + adap = i2c_get_adapter(chan_id); + if(!adap){ + err_msg = "Can not get adap!"; + goto err_ioexp_setup_i2c_3; + } + client->adapter = adap; + client->addr = self->ioexp_map_p->map_addr[chip_id].chip_addr; + i2c_obj_p->i2c_client_p = client; + i2c_obj_p->chip_id = chip_id; + i2c_obj_p->next = NULL; + if (!self->i2c_head_p){ + self->i2c_head_p = i2c_obj_p; + } else { + i2c_curr_p = self->i2c_head_p; + while (i2c_curr_p->next){ + i2c_curr_p = i2c_curr_p->next; + } + i2c_curr_p->next = i2c_obj_p; + } + return 0; + +err_ioexp_setup_i2c_3: + kfree(i2c_obj_p); +err_ioexp_setup_i2c_2: + kfree(client); +err_ioexp_setup_i2c_1: + SWPS_ERR("%s: %s :%d\n", __func__, err_msg, chan_id); + return -1; +} + + +static int +setup_i2c_client(struct ioexp_obj_s* self){ + + int result; + int chip_id = 0; + + for (chip_id=0; chip_id<(self->ioexp_map_p->chip_amount); chip_id++){ + result = setup_i2c_client_one(self, chip_id); + if (result < 0){ + SWPS_ERR("%s fail! :%d\n", __func__, chip_id); + return -1; + } + } + return 0; +} + + +static int +setup_ioexp_config(struct ioexp_obj_s *self) { + + int chip_id, offset, err_code; + struct ioexp_addr_s *addr_p; + if (io_no_init) { + + SWPS_INFO("io_no_init:%d \n", io_no_init); + return 0; + } + + for (chip_id=0; chip_id<(self->ioexp_map_p->chip_amount); chip_id++){ + addr_p = &(self->ioexp_map_p->map_addr[chip_id]); + if (!addr_p){ + SWPS_ERR("IOEXP config incorrect! :%d \n",chip_id); + return -1; + } + for (offset=0; offset<(self->ioexp_map_p->data_width); offset++){ + + /* [Desc] Skip the setup config value behavior + [Note] Setup config value = -1 if you don't want to write the value to IOEXP or CPLD + */ + if(addr_p->conf_offset[offset] < 0){ + SWPS_DEBUG("skip a config_offset <%d>\n", addr_p->conf_offset[offset]); + continue; + } + err_code = i2c_smbus_write_byte_data(_get_i2c_client(self, chip_id), + addr_p->conf_offset[offset], + addr_p->conf_default[offset]); + + if (err_code < 0){ + SWPS_INFO("%s: set conf fail! :%d \n", __func__, err_code); + return -2; + } + } + } + return 0; +} + + +struct ioexp_obj_s * +_create_ioexp_obj(int ioexp_id, + int ioexp_type, + struct ioexp_addr_s *addr_map_p, + int run_mode){ + + struct ioexp_map_s* ioexp_map_p; + struct ioexp_obj_s* result_p; + struct ioexp_i2c_s *i2c_curr_p; + struct ioexp_i2c_s *i2c_next_p; + + /* Get layout */ + ioexp_map_p = get_ioexp_map(ioexp_type); + if (!ioexp_map_p){ + SWPS_ERR("%s: Invalid ioexp_type\n", __func__); + goto err_create_ioexp_fail; + } + /* Prepare IOEXP object */ + result_p = kzalloc(sizeof(*result_p), GFP_KERNEL); + if (!result_p){ + SWPS_ERR("%s: kzalloc failure!\n", __func__); + goto err_create_ioexp_fail; + } + /* Prepare static size attributes */ + if (setup_ioexp_ssize_attr(result_p, + ioexp_map_p, + ioexp_id, + ioexp_type, + run_mode) < 0){ + goto err_create_ioexp_setup_attr_fail; + } + /* Prepare address mapping */ + if (setup_addr_mapping(result_p, addr_map_p, ioexp_map_p->chip_amount) < 0){ + goto err_create_ioexp_setup_attr_fail; + } + if (setup_i2c_client(result_p) < 0){ + goto err_create_ioexp_setup_i2c_fail; + } + /* Prepare call back functions of object */ + if (setup_ioexp_public_cb(result_p, ioexp_type) < 0){ + goto err_create_ioexp_setup_i2c_fail; + } + if (setup_ioexp_private_cb(result_p, ioexp_type) < 0){ + goto err_create_ioexp_setup_i2c_fail; + } + return result_p; + +err_create_ioexp_setup_i2c_fail: + i2c_curr_p = result_p->i2c_head_p; + i2c_next_p = result_p->i2c_head_p; + while (i2c_curr_p){ + i2c_next_p = i2c_curr_p->next; + if (i2c_curr_p->i2c_client_p) { + i2c_put_adapter(i2c_curr_p->i2c_client_p->adapter); + kfree(i2c_curr_p->i2c_client_p); + } + kfree(i2c_curr_p); + i2c_curr_p = i2c_next_p; + } +err_create_ioexp_setup_attr_fail: + kfree(result_p); +err_create_ioexp_fail: + SWPS_ERR("%s: fail! :%d :%d \n", + __func__, ioexp_id, ioexp_type); + return NULL; +} + + +int +create_ioexp_obj(int ioexp_id, + int ioexp_type, + struct ioexp_addr_s *addr_map_p, + int run_mode){ + + struct ioexp_obj_s *ioexp_p = NULL; + + ioexp_p = _create_ioexp_obj(ioexp_id, ioexp_type, + addr_map_p, run_mode); + if (!ioexp_p){ + return -1; + } + if (ioexp_head_p == NULL){ + ioexp_head_p = ioexp_p; + ioexp_tail_p = ioexp_p; + return 0; + } + ioexp_tail_p->next = ioexp_p; + ioexp_tail_p = ioexp_p; + return 0; +} +EXPORT_SYMBOL(create_ioexp_obj); + + +static int +_init_ioexp_obj(struct ioexp_obj_s* self) { + + char *err_msg = "ERR"; + char *func_name = "_init_ioexp_obj"; + + /* Setup IOEXP configure byte */ + if (setup_ioexp_config(self) < 0){ + err_msg = "setup_ioexp_config fail"; + goto err_init_ioexp_obj; + } + /* Setup default data */ + if (_ioexp_init_handler(self) < 0){ + err_msg = "_ioexp_init_handler fail"; + goto err_init_ioexp_obj; + } + /* Update all */ + if (self->state == STATE_IOEXP_NORMAL){ + if (self->update_all(self, 1, func_name) < 0){ + err_msg = "update_all() fail"; + goto err_init_ioexp_obj; + } + } + return 0; + +err_init_ioexp_obj: + SWPS_DEBUG("%s: %s\n", __func__, err_msg); + return -1; +} + + +int +init_ioexp_objs(void){ + /* Return value: + * 0: Success + * -1: Detect topology error + * -2: SWPS internal error + */ + struct ioexp_obj_s *curr_p = ioexp_head_p; + + if (!curr_p) { + SWPS_ERR("%s: ioexp_head_p is NULL\n", __func__); + return -2; + } + while (curr_p) { + if (_init_ioexp_obj(curr_p) < 0) { + SWPS_DEBUG("%s: _init_ioexp_obj() fail\n", __func__); + return -1; + } + curr_p = curr_p->next; + } + SWPS_DEBUG("%s: done.\n", __func__); + return 0; +} +EXPORT_SYMBOL(init_ioexp_objs); + + +void +clean_ioexp_objs(void){ + + struct ioexp_i2c_s *i2c_curr_p = NULL; + struct ioexp_i2c_s *i2c_next_p = NULL; + struct ioexp_obj_s *ioexp_next_p = NULL; + struct ioexp_obj_s *ioexp_curr_p = ioexp_head_p; + + if (ioexp_head_p == NULL){ + ioexp_tail_p = NULL; + return; + } + while(ioexp_curr_p){ + ioexp_next_p = ioexp_curr_p->next; + if (ioexp_curr_p->ioexp_map_p) { + if (ioexp_curr_p->ioexp_map_p->map_addr) { + kfree(ioexp_curr_p->ioexp_map_p->map_addr); + } + kfree(ioexp_curr_p->ioexp_map_p); + } + + i2c_curr_p = ioexp_curr_p->i2c_head_p; + while (i2c_curr_p) { + i2c_next_p = i2c_curr_p->next; + if (i2c_curr_p->i2c_client_p) { + i2c_put_adapter(i2c_curr_p->i2c_client_p->adapter); + kfree(i2c_curr_p->i2c_client_p); + } + kfree(i2c_curr_p); + i2c_curr_p = i2c_next_p; + } + kfree(ioexp_curr_p); + ioexp_curr_p = ioexp_next_p; + } + ioexp_tail_p = NULL; + SWPS_DEBUG("%s: done.\n", __func__); +} +EXPORT_SYMBOL(clean_ioexp_objs); + + +int +check_ioexp_objs(void){ + + struct ioexp_obj_s *ioexp_curr_p = ioexp_head_p; + + while (ioexp_curr_p){ + if ( (ioexp_curr_p->check(ioexp_curr_p)) < 0){ + SWPS_INFO("check IOEXP-%d fail! :%d\n", + ioexp_curr_p->ioexp_id, ioexp_curr_p->ioexp_type); + return -1; + } + ioexp_curr_p = ioexp_curr_p->next; + } + return 0; +} +EXPORT_SYMBOL(check_ioexp_objs); + + +struct ioexp_obj_s * +get_ioexp_obj(int ioexp_id){ + + struct ioexp_obj_s *result_p = NULL; + struct ioexp_obj_s *ioexp_curr_p = ioexp_head_p; + + while(ioexp_curr_p){ + if (ioexp_curr_p->ioexp_id == ioexp_id){ + result_p = ioexp_curr_p; + break; + } + ioexp_curr_p = ioexp_curr_p->next; + } + return result_p; +} +EXPORT_SYMBOL(get_ioexp_obj); + + +void +unlock_ioexp_all(void) { + + struct ioexp_obj_s *ioexp_curr_p = ioexp_head_p; + + while(ioexp_curr_p){ + mutex_unlock(&ioexp_curr_p->lock); + ioexp_curr_p = ioexp_curr_p->next; + } +} +EXPORT_SYMBOL(unlock_ioexp_all); + +int +lock_ioexp_all(void) { + + struct ioexp_obj_s *ioexp_curr_p = ioexp_head_p; + + while(ioexp_curr_p){ + mutex_lock(&ioexp_curr_p->lock); + ioexp_curr_p = ioexp_curr_p->next; + } + return 0; +} +EXPORT_SYMBOL(lock_ioexp_all); + + +int +check_channel_tier_1(void) { + + if ( (!_is_channel_ready(ioexp_head_p)) && + (!_is_channel_ready(ioexp_tail_p)) ){ + return -1; + } + return 0; +} +EXPORT_SYMBOL(check_channel_tier_1); + + +static int +_scan_channel_tier_1(int force, + int show_err) { + + struct ioexp_obj_s *ioexp_curr_p = ioexp_head_p; + int ready = 0; + + if (!ioexp_curr_p) { + goto err_scan_tier_1_channel; + } + while(ioexp_curr_p) { + ready = _is_channel_ready(ioexp_curr_p); + if ((!ready) && (!force)) { + goto err_scan_tier_1_channel; + } + ioexp_curr_p = ioexp_curr_p->next; + } + return 0; + +err_scan_tier_1_channel: + if (show_err) { + if (ioexp_curr_p) { + SWPS_INFO("%s: IOEXP-%d fail\n", __func__, ioexp_curr_p->ioexp_id); + } else { + SWPS_INFO("%s: IOEXP is null.\n", __func__); + } + } + return -1; +} + + +static int +_scan_channel_tier_1_single(void) { + + int ret = 0; + int chan_id = 0; + int fake_cid = 0; + int fake_offs = 0; + int fake_addr = 0; + struct i2c_adapter *adap = NULL; + struct i2c_client *client = NULL; + + if (ioexp_head_p->ioexp_id != ioexp_tail_p->ioexp_id) { + return 0; + } + /* Setup i2c_client */ + chan_id = ioexp_head_p->ioexp_map_p->map_addr[fake_cid].chan_id; + fake_addr = ioexp_head_p->ioexp_map_p->map_addr[fake_cid].chip_addr; + adap = i2c_get_adapter((chan_id + 1)); + if(!adap){ + SWPS_INFO("%s: Can not get adap!\n", __func__); + return 0; + } + client = kzalloc(sizeof(*client), GFP_KERNEL); + if (!client){ + SWPS_INFO("%s: Can not kzalloc client!\n", __func__); + return 0; + } + client->adapter = adap; + client->addr = fake_addr; + /* Fouce move ioexp ptr to next */ + ret = i2c_smbus_read_byte_data(client, fake_offs); + SWPS_DEBUG("%s: move ioexp_ptr done. :%d\n", __func__, ret); + kfree(client); + return 1; +} + + +int +resync_channel_tier_1(void) { + + char *emsg = "ERR"; + + if (!ioexp_head_p) { + emsg = "ioexp_head_p is NULL"; + goto err_resync_ioexp_status_1; + } + /* Run all */ + if (ioexp_head_p->ioexp_id == ioexp_tail_p->ioexp_id) { + _scan_channel_tier_1_single(); + } else { + _scan_channel_tier_1(1, 0); + } + /* Check all */ + if (_scan_channel_tier_1(0, 1) < 0) { + emsg = "resync tier-1 channel fail"; + goto err_resync_ioexp_status_1; + } + return 0; + +err_resync_ioexp_status_1: + SWPS_ERR("%s: %s\n", __func__, emsg); + return -1; +} +EXPORT_SYMBOL(resync_channel_tier_1); + + +/* For build single module using (Ex: ONL platform) */ +MODULE_LICENSE("GPL"); + + + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/io_expander.h b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/io_expander.h new file mode 100644 index 000000000000..43a8c290f5da --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/io_expander.h @@ -0,0 +1,189 @@ +#ifndef IO_EXPANDER_H +#define IO_EXPANDER_H + +#include + + +/* IOEXP type define (SFP series) */ +#define IOEXP_TYPE_MAGINOLIA_NAB (10101) +#define IOEXP_TYPE_MAGINOLIA_4AB (10102) +#define IOEXP_TYPE_MAPLE_NABC (10104) +#define IOEXP_TYPE_GULMOHAR_NABC (10105) +#define IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC (10106) +#define IOEXP_TYPE_SFP_8P_LAYOUT_1 (10107) +#define IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC (10108) +#define IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC (10109) + +/* IOEXP type define (QSFP series) */ +#define IOEXP_TYPE_MAGINOLIA_7AB (10201) +#define IOEXP_TYPE_REDWOOD_P01P08 (10202) +#define IOEXP_TYPE_REDWOOD_P09P16 (10203) +#define IOEXP_TYPE_HUDSON32IGA_P01P08 (10204) +#define IOEXP_TYPE_HUDSON32IGA_P09P16 (10205) +#define IOEXP_TYPE_SPRUCE_7AB (10206) +#define IOEXP_TYPE_CYPRESS_7ABC (10207) +#define IOEXP_TYPE_TAHOE_5A (10208) +#define IOEXP_TYPE_TAHOE_6ABC (10209) +#define IOEXP_TYPE_SEQUOIA_NABC (10210) +#define IOEXP_TYPE_LAVENDER_P65 (10211) +#define IOEXP_TYPE_MAPLE_0ABC (10212) +#define IOEXP_TYPE_GULMOHAR_7ABC (10213) +#define IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC (10214) +#define IOEXP_TYPE_QSFP_6P_LAYOUT_1 (10215) +#define IOEXP_TYPE_CEDAR_0ABC (10216) + +/* CPLD type define */ +#define CPLD_TYPE_COTTONWOOD (10301) + +/* IOEXP mode define */ +#define IOEXP_MODE_POLLING (19000) +#define IOEXP_MODE_DIRECT (19001) + +/* IOEXP state define */ +#define STATE_IOEXP_NORMAL (0) +#define STATE_IOEXP_INIT (-1) +#define STATE_IOEXP_ABNORMAL (-2) + +/* IOEXP error code define */ +#define ERR_IOEXP_NOTSUPPORT (-100) +#define ERR_IOEXP_UNINIT (-101) +#define ERR_IOEXP_BADCONF (-102) +#define ERR_IOEXP_ABNORMAL (-103) +#define ERR_IOEXP_NOSTATE (-104) +#define ERR_IOEXP_BADINPUT (-105) +#define ERR_IOEXP_UNEXCPT (-199) + +#define SWPS_INFO(fmt, args...) printk( KERN_INFO "[SWPS] " fmt, ##args) +#define SWPS_WARN(fmt, args...) printk( KERN_WARNING "[SWPS] " fmt, ##args) +#define SWPS_ERR(fmt, args...) printk( KERN_ERR "[SWPS] " fmt, ##args) + +#ifdef DEBUG_SWPS +# define SWPS_DEBUG(fmt, args...) printk( KERN_DEBUG "[SWPS] " fmt, ##args) +#else +# define SWPS_DEBUG(fmt, args...) +#endif + +struct ioexp_addr_s { + int chan_id; + int chip_addr; + int read_offset[8]; + int write_offset[8]; + int conf_offset[8]; + uint8_t data_default[8]; + uint8_t conf_default[8]; +}; + +struct ioexp_i2c_s { + int chip_id; + struct i2c_client *i2c_client_p; + struct ioexp_i2c_s *next; +}; + + +struct ioexp_bitmap_s { + int chip_id; /* IOEXP chip id */ + int ioexp_voffset; /* IOEXP virtual offset */ + int bit_shift; +}; + +struct ioexp_map_s { + int chip_amount; /* Number of chips that IOEXP object content */ + int data_width; /* Number of (Read/Write/Config) bytes */ + struct ioexp_addr_s *map_addr; /* Chip address info */ + struct ioexp_bitmap_s map_present[10]; /* IOEXP for SFP / QSFP */ + struct ioexp_bitmap_s map_tx_disable[10]; /* IOEXP for SFP */ + struct ioexp_bitmap_s map_tx_fault[10]; /* IOEXP for SFP */ + struct ioexp_bitmap_s map_rxlos[10]; /* IOEXP for SFP */ + struct ioexp_bitmap_s map_reset[10]; /* IOEXP for QSFP */ + struct ioexp_bitmap_s map_lpmod[10]; /* IOEXP for QSFP */ + struct ioexp_bitmap_s map_modsel[10]; /* IOEXP for QSFP */ + struct ioexp_bitmap_s map_hard_rs0[10]; /* IOEXP for QSFP */ + struct ioexp_bitmap_s map_hard_rs1[10]; /* IOEXP for QSFP */ +}; + +struct ioexp_data_s { + uint8_t data[8]; +}; + +struct ioexp_obj_s { + + /* ============================ + * Object public property + * ============================ + */ + int ioexp_id; + int ioexp_type; + + /* ============================ + * Object private property + * ============================ + */ + struct ioexp_data_s chip_data[16]; /* Max: 8-ioexp in one virt-ioexp(ioexp_obj) */ + struct ioexp_map_s *ioexp_map_p; + struct ioexp_obj_s *next; + struct ioexp_i2c_s *i2c_head_p; + struct mutex lock; + int mode; + int state; + + /* =========================================== + * Object public functions + * =========================================== + */ + int (*get_present)(struct ioexp_obj_s *self, int virt_offset); + int (*get_tx_fault)(struct ioexp_obj_s *self, int virt_offset); + int (*get_rxlos)(struct ioexp_obj_s *self, int virt_offset); + int (*get_tx_disable)(struct ioexp_obj_s *self, int virt_offset); + int (*get_reset)(struct ioexp_obj_s *self, int virt_offset); + int (*get_lpmod)(struct ioexp_obj_s *self, int virt_offset); + int (*get_modsel)(struct ioexp_obj_s *self, int virt_offset); + int (*get_hard_rs0)(struct ioexp_obj_s *self, int virt_offset); + int (*get_hard_rs1)(struct ioexp_obj_s *self, int virt_offset); + int (*set_tx_disable)(struct ioexp_obj_s *self, int virt_offset, int input_val); + int (*set_reset)(struct ioexp_obj_s *self, int virt_offset, int input_val); + int (*set_lpmod)(struct ioexp_obj_s *self, int virt_offset, int input_val); + int (*set_modsel)(struct ioexp_obj_s *self, int virt_offset, int input_val); + int (*set_hard_rs0)(struct ioexp_obj_s *self, int virt_offset, int input_val); + int (*set_hard_rs1)(struct ioexp_obj_s *self, int virt_offset, int input_val); + + /* =========================================== + * Object private functions + * =========================================== + */ + int (*init)(struct ioexp_obj_s *self); + int (*check)(struct ioexp_obj_s *self); + int (*update_all)(struct ioexp_obj_s *self, int show_err, char *caller_name); + int (*fsm_4_direct)(struct ioexp_obj_s* self); + int (*fsm_4_polling)(struct ioexp_obj_s* self); +}; + + +struct ioexp_obj_s* get_ioexp_obj(int ioexp_id); +int create_ioexp_obj(int ioexp_id, + int ioexp_type, + struct ioexp_addr_s *addr_map_p, + int run_mode); +int init_ioexp_objs(void); +int check_ioexp_objs(void); +void clean_ioexp_objs(void); + +void unlock_ioexp_all(void); +int lock_ioexp_all(void); + +int check_channel_tier_1(void); +int resync_channel_tier_1(void); + +/* Macro for bit control */ +#define SWP_BIT_SET(byte_val,bit_shift) ((byte_val) |= (1<<(bit_shift))) +#define SWP_BIT_CLEAR(byte_val,bit_shift) ((byte_val) &= ~(1<<(bit_shift))) + + +#endif /* IO_EXPANDER_H */ + + + + + + + + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/lpc_ich.c b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/lpc_ich.c new file mode 100644 index 000000000000..21e4824d6e33 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/lpc_ich.c @@ -0,0 +1,1149 @@ +/* + * lpc_ich.c - LPC interface for Intel ICH + * + * LPC bridge function of the Intel ICH contains many other + * functional units, such as Interrupt controllers, Timers, + * Power Management, System Management, GPIO, RTC, and LPC + * Configuration Registers. + * + * This driver is derived from lpc_sch. + + * Copyright (c) 2011 Extreme Engineering Solution, Inc. + * Author: Aaron Sierra + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License 2 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; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + * This driver supports the following I/O Controller hubs: + * (See the intel documentation on http://developer.intel.com.) + * document number 290655-003, 290677-014: 82801AA (ICH), 82801AB (ICHO) + * document number 290687-002, 298242-027: 82801BA (ICH2) + * document number 290733-003, 290739-013: 82801CA (ICH3-S) + * document number 290716-001, 290718-007: 82801CAM (ICH3-M) + * document number 290744-001, 290745-025: 82801DB (ICH4) + * document number 252337-001, 252663-008: 82801DBM (ICH4-M) + * document number 273599-001, 273645-002: 82801E (C-ICH) + * document number 252516-001, 252517-028: 82801EB (ICH5), 82801ER (ICH5R) + * document number 300641-004, 300884-013: 6300ESB + * document number 301473-002, 301474-026: 82801F (ICH6) + * document number 313082-001, 313075-006: 631xESB, 632xESB + * document number 307013-003, 307014-024: 82801G (ICH7) + * document number 322896-001, 322897-001: NM10 + * document number 313056-003, 313057-017: 82801H (ICH8) + * document number 316972-004, 316973-012: 82801I (ICH9) + * document number 319973-002, 319974-002: 82801J (ICH10) + * document number 322169-001, 322170-003: 5 Series, 3400 Series (PCH) + * document number 320066-003, 320257-008: EP80597 (IICH) + * document number 324645-001, 324646-001: Cougar Point (CPT) + * document number TBD : Patsburg (PBG) + * document number TBD : DH89xxCC + * document number TBD : Panther Point + * document number TBD : Lynx Point + * document number TBD : Lynx Point-LP + * document number TBD : Wellsburg + * document number TBD : Avoton SoC + * document number TBD : Coleto Creek + * document number TBD : Wildcat Point-LP + * document number TBD : 9 Series + * document number TBD : Lewisburg + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include + +#define ACPIBASE 0x40 +#define ACPIBASE_GPE_OFF 0x28 +#define ACPIBASE_GPE_END 0x2f +#define ACPIBASE_SMI_OFF 0x30 +#define ACPIBASE_SMI_END 0x33 +#define ACPIBASE_PMC_OFF 0x08 +#define ACPIBASE_PMC_END 0x0c +#define ACPIBASE_TCO_OFF 0x60 +#define ACPIBASE_TCO_END 0x7f +#define ACPICTRL_PMCBASE 0x44 + +#define ACPIBASE_GCS_OFF 0x3410 +#define ACPIBASE_GCS_END 0x3414 + +#define GPIOBASE_ICH0 0x58 +#define GPIOCTRL_ICH0 0x5C +#define GPIOBASE_ICH6 0x48 +#define GPIOCTRL_ICH6 0x4C + +#define RCBABASE 0xf0 + +#define wdt_io_res(i) wdt_res(0, i) +#define wdt_mem_res(i) wdt_res(ICH_RES_MEM_OFF, i) +#define wdt_res(b, i) (&wdt_ich_res[(b) + (i)]) + +struct lpc_ich_priv { + int chipset; + + int abase; /* ACPI base */ + int actrl_pbase; /* ACPI control or PMC base */ + int gbase; /* GPIO base */ + int gctrl; /* GPIO control */ + + int abase_save; /* Cached ACPI base value */ + int actrl_pbase_save; /* Cached ACPI control or PMC base value */ + int gctrl_save; /* Cached GPIO control value */ +}; + +static struct resource wdt_ich_res[] = { + /* ACPI - TCO */ + { + .flags = IORESOURCE_IO, + }, + /* ACPI - SMI */ + { + .flags = IORESOURCE_IO, + }, + /* GCS or PMC */ + { + .flags = IORESOURCE_MEM, + }, +}; + +static struct resource gpio_ich_res[] = { + /* GPIO */ + { + .flags = IORESOURCE_IO, + }, + /* ACPI - GPE0 */ + { + .flags = IORESOURCE_IO, + }, +}; + +static struct mfd_cell lpc_ich_wdt_cell = { + .name = "iTCO_wdt", + .num_resources = ARRAY_SIZE(wdt_ich_res), + .resources = wdt_ich_res, + .ignore_resource_conflicts = true, +}; + +static struct mfd_cell lpc_ich_gpio_cell = { + .name = "gpio_ich", + .num_resources = ARRAY_SIZE(gpio_ich_res), + .resources = gpio_ich_res, + .ignore_resource_conflicts = true, +}; + +/* chipset related info */ +enum lpc_chipsets { + LPC_ICH = 0, /* ICH */ + LPC_ICH0, /* ICH0 */ + LPC_ICH2, /* ICH2 */ + LPC_ICH2M, /* ICH2-M */ + LPC_ICH3, /* ICH3-S */ + LPC_ICH3M, /* ICH3-M */ + LPC_ICH4, /* ICH4 */ + LPC_ICH4M, /* ICH4-M */ + LPC_CICH, /* C-ICH */ + LPC_ICH5, /* ICH5 & ICH5R */ + LPC_6300ESB, /* 6300ESB */ + LPC_ICH6, /* ICH6 & ICH6R */ + LPC_ICH6M, /* ICH6-M */ + LPC_ICH6W, /* ICH6W & ICH6RW */ + LPC_631XESB, /* 631xESB/632xESB */ + LPC_ICH7, /* ICH7 & ICH7R */ + LPC_ICH7DH, /* ICH7DH */ + LPC_ICH7M, /* ICH7-M & ICH7-U */ + LPC_ICH7MDH, /* ICH7-M DH */ + LPC_NM10, /* NM10 */ + LPC_ICH8, /* ICH8 & ICH8R */ + LPC_ICH8DH, /* ICH8DH */ + LPC_ICH8DO, /* ICH8DO */ + LPC_ICH8M, /* ICH8M */ + LPC_ICH8ME, /* ICH8M-E */ + LPC_ICH9, /* ICH9 */ + LPC_ICH9R, /* ICH9R */ + LPC_ICH9DH, /* ICH9DH */ + LPC_ICH9DO, /* ICH9DO */ + LPC_ICH9M, /* ICH9M */ + LPC_ICH9ME, /* ICH9M-E */ + LPC_ICH10, /* ICH10 */ + LPC_ICH10R, /* ICH10R */ + LPC_ICH10D, /* ICH10D */ + LPC_ICH10DO, /* ICH10DO */ + LPC_PCH, /* PCH Desktop Full Featured */ + LPC_PCHM, /* PCH Mobile Full Featured */ + LPC_P55, /* P55 */ + LPC_PM55, /* PM55 */ + LPC_H55, /* H55 */ + LPC_QM57, /* QM57 */ + LPC_H57, /* H57 */ + LPC_HM55, /* HM55 */ + LPC_Q57, /* Q57 */ + LPC_HM57, /* HM57 */ + LPC_PCHMSFF, /* PCH Mobile SFF Full Featured */ + LPC_QS57, /* QS57 */ + LPC_3400, /* 3400 */ + LPC_3420, /* 3420 */ + LPC_3450, /* 3450 */ + LPC_EP80579, /* EP80579 */ + LPC_CPT, /* Cougar Point */ + LPC_CPTD, /* Cougar Point Desktop */ + LPC_CPTM, /* Cougar Point Mobile */ + LPC_PBG, /* Patsburg */ + LPC_DH89XXCC, /* DH89xxCC */ + LPC_PPT, /* Panther Point */ + LPC_LPT, /* Lynx Point */ + LPC_LPT_LP, /* Lynx Point-LP */ + LPC_WBG, /* Wellsburg */ + LPC_AVN, /* Avoton SoC */ + LPC_BAYTRAIL, /* Bay Trail SoC */ + LPC_COLETO, /* Coleto Creek */ + LPC_WPT_LP, /* Wildcat Point-LP */ + LPC_BRASWELL, /* Braswell SoC */ + LPC_LEWISBURG, /* Lewisburg */ + LPC_9S, /* 9 Series */ + LPC_APL, /* Apollo Lake SoC */ + LPC_GLK, /* Gemini Lake SoC */ + LPC_COUGARMOUNTAIN,/* Cougar Mountain SoC*/ +}; + +static struct lpc_ich_info lpc_chipset_info[] = { + [LPC_ICH] = { + .name = "ICH", + .iTCO_version = 1, + }, + [LPC_ICH0] = { + .name = "ICH0", + .iTCO_version = 1, + }, + [LPC_ICH2] = { + .name = "ICH2", + .iTCO_version = 1, + }, + [LPC_ICH2M] = { + .name = "ICH2-M", + .iTCO_version = 1, + }, + [LPC_ICH3] = { + .name = "ICH3-S", + .iTCO_version = 1, + }, + [LPC_ICH3M] = { + .name = "ICH3-M", + .iTCO_version = 1, + }, + [LPC_ICH4] = { + .name = "ICH4", + .iTCO_version = 1, + }, + [LPC_ICH4M] = { + .name = "ICH4-M", + .iTCO_version = 1, + }, + [LPC_CICH] = { + .name = "C-ICH", + .iTCO_version = 1, + }, + [LPC_ICH5] = { + .name = "ICH5 or ICH5R", + .iTCO_version = 1, + }, + [LPC_6300ESB] = { + .name = "6300ESB", + .iTCO_version = 1, + }, + [LPC_ICH6] = { + .name = "ICH6 or ICH6R", + .iTCO_version = 2, + .gpio_version = ICH_V6_GPIO, + }, + [LPC_ICH6M] = { + .name = "ICH6-M", + .iTCO_version = 2, + .gpio_version = ICH_V6_GPIO, + }, + [LPC_ICH6W] = { + .name = "ICH6W or ICH6RW", + .iTCO_version = 2, + .gpio_version = ICH_V6_GPIO, + }, + [LPC_631XESB] = { + .name = "631xESB/632xESB", + .iTCO_version = 2, + .gpio_version = ICH_V6_GPIO, + }, + [LPC_ICH7] = { + .name = "ICH7 or ICH7R", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH7DH] = { + .name = "ICH7DH", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH7M] = { + .name = "ICH7-M or ICH7-U", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH7MDH] = { + .name = "ICH7-M DH", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_NM10] = { + .name = "NM10", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH8] = { + .name = "ICH8 or ICH8R", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH8DH] = { + .name = "ICH8DH", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH8DO] = { + .name = "ICH8DO", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH8M] = { + .name = "ICH8M", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH8ME] = { + .name = "ICH8M-E", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH9] = { + .name = "ICH9", + .iTCO_version = 2, + .gpio_version = ICH_V9_GPIO, + }, + [LPC_ICH9R] = { + .name = "ICH9R", + .iTCO_version = 2, + .gpio_version = ICH_V9_GPIO, + }, + [LPC_ICH9DH] = { + .name = "ICH9DH", + .iTCO_version = 2, + .gpio_version = ICH_V9_GPIO, + }, + [LPC_ICH9DO] = { + .name = "ICH9DO", + .iTCO_version = 2, + .gpio_version = ICH_V9_GPIO, + }, + [LPC_ICH9M] = { + .name = "ICH9M", + .iTCO_version = 2, + .gpio_version = ICH_V9_GPIO, + }, + [LPC_ICH9ME] = { + .name = "ICH9M-E", + .iTCO_version = 2, + .gpio_version = ICH_V9_GPIO, + }, + [LPC_ICH10] = { + .name = "ICH10", + .iTCO_version = 2, + .gpio_version = ICH_V10CONS_GPIO, + }, + [LPC_ICH10R] = { + .name = "ICH10R", + .iTCO_version = 2, + .gpio_version = ICH_V10CONS_GPIO, + }, + [LPC_ICH10D] = { + .name = "ICH10D", + .iTCO_version = 2, + .gpio_version = ICH_V10CORP_GPIO, + }, + [LPC_ICH10DO] = { + .name = "ICH10DO", + .iTCO_version = 2, + .gpio_version = ICH_V10CORP_GPIO, + }, + [LPC_PCH] = { + .name = "PCH Desktop Full Featured", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_PCHM] = { + .name = "PCH Mobile Full Featured", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_P55] = { + .name = "P55", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_PM55] = { + .name = "PM55", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_H55] = { + .name = "H55", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_QM57] = { + .name = "QM57", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_H57] = { + .name = "H57", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_HM55] = { + .name = "HM55", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_Q57] = { + .name = "Q57", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_HM57] = { + .name = "HM57", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_PCHMSFF] = { + .name = "PCH Mobile SFF Full Featured", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_QS57] = { + .name = "QS57", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_3400] = { + .name = "3400", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_3420] = { + .name = "3420", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_3450] = { + .name = "3450", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_EP80579] = { + .name = "EP80579", + .iTCO_version = 2, + }, + [LPC_CPT] = { + .name = "Cougar Point", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_CPTD] = { + .name = "Cougar Point Desktop", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_CPTM] = { + .name = "Cougar Point Mobile", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_PBG] = { + .name = "Patsburg", + .iTCO_version = 2, + }, + [LPC_DH89XXCC] = { + .name = "DH89xxCC", + .iTCO_version = 2, + }, + [LPC_PPT] = { + .name = "Panther Point", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_LPT] = { + .name = "Lynx Point", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_LPT_LP] = { + .name = "Lynx Point_LP", + .iTCO_version = 2, + }, + [LPC_WBG] = { + .name = "Wellsburg", + .iTCO_version = 2, + }, + [LPC_AVN] = { + .name = "Avoton SoC", + .iTCO_version = 3, + .gpio_version = AVOTON_GPIO, + }, + [LPC_BAYTRAIL] = { + .name = "Bay Trail SoC", + .iTCO_version = 3, + }, + [LPC_COLETO] = { + .name = "Coleto Creek", + .iTCO_version = 2, + }, + [LPC_WPT_LP] = { + .name = "Wildcat Point_LP", + .iTCO_version = 2, + }, + [LPC_BRASWELL] = { + .name = "Braswell SoC", + .iTCO_version = 3, + }, + [LPC_LEWISBURG] = { + .name = "Lewisburg", + .iTCO_version = 2, + }, + [LPC_9S] = { + .name = "9 Series", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_APL] = { + .name = "Apollo Lake SoC", + .iTCO_version = 5, + }, + [LPC_GLK] = { + .name = "Gemini Lake SoC", + }, + [LPC_COUGARMOUNTAIN] = { + .name = "Cougar Mountain SoC", + .iTCO_version = 3, + }, +}; + +/* + * This data only exists for exporting the supported PCI ids + * via MODULE_DEVICE_TABLE. We do not actually register a + * pci_driver, because the I/O Controller Hub has also other + * functions that probably will be registered by other drivers. + */ +static const struct pci_device_id lpc_ich_ids[] = { + { PCI_VDEVICE(INTEL, 0x0f1c), LPC_BAYTRAIL}, + { PCI_VDEVICE(INTEL, 0x1c41), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c42), LPC_CPTD}, + { PCI_VDEVICE(INTEL, 0x1c43), LPC_CPTM}, + { PCI_VDEVICE(INTEL, 0x1c44), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c45), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c46), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c47), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c48), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c49), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c4a), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c4b), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c4c), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c4d), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c4e), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c4f), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c50), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c51), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c52), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c53), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c54), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c55), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c56), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c57), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c58), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c59), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c5a), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c5b), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c5c), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c5d), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c5e), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c5f), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1d40), LPC_PBG}, + { PCI_VDEVICE(INTEL, 0x1d41), LPC_PBG}, + { PCI_VDEVICE(INTEL, 0x1e40), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e41), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e42), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e43), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e44), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e45), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e46), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e47), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e48), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e49), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e4a), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e4b), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e4c), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e4d), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e4e), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e4f), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e50), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e51), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e52), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e53), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e54), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e55), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e56), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e57), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e58), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e59), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e5a), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e5b), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e5c), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e5d), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e5e), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e5f), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1f38), LPC_AVN}, + { PCI_VDEVICE(INTEL, 0x1f39), LPC_AVN}, + { PCI_VDEVICE(INTEL, 0x1f3a), LPC_AVN}, + { PCI_VDEVICE(INTEL, 0x1f3b), LPC_AVN}, + { PCI_VDEVICE(INTEL, 0x229c), LPC_BRASWELL}, + { PCI_VDEVICE(INTEL, 0x2310), LPC_DH89XXCC}, + { PCI_VDEVICE(INTEL, 0x2390), LPC_COLETO}, + { PCI_VDEVICE(INTEL, 0x2410), LPC_ICH}, + { PCI_VDEVICE(INTEL, 0x2420), LPC_ICH0}, + { PCI_VDEVICE(INTEL, 0x2440), LPC_ICH2}, + { PCI_VDEVICE(INTEL, 0x244c), LPC_ICH2M}, + { PCI_VDEVICE(INTEL, 0x2450), LPC_CICH}, + { PCI_VDEVICE(INTEL, 0x2480), LPC_ICH3}, + { PCI_VDEVICE(INTEL, 0x248c), LPC_ICH3M}, + { PCI_VDEVICE(INTEL, 0x24c0), LPC_ICH4}, + { PCI_VDEVICE(INTEL, 0x24cc), LPC_ICH4M}, + { PCI_VDEVICE(INTEL, 0x24d0), LPC_ICH5}, + { PCI_VDEVICE(INTEL, 0x25a1), LPC_6300ESB}, + { PCI_VDEVICE(INTEL, 0x2640), LPC_ICH6}, + { PCI_VDEVICE(INTEL, 0x2641), LPC_ICH6M}, + { PCI_VDEVICE(INTEL, 0x2642), LPC_ICH6W}, + { PCI_VDEVICE(INTEL, 0x2670), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2671), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2672), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2673), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2674), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2675), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2676), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2677), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2678), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2679), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x267a), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x267b), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x267c), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x267d), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x267e), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x267f), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x27b0), LPC_ICH7DH}, + { PCI_VDEVICE(INTEL, 0x27b8), LPC_ICH7}, + { PCI_VDEVICE(INTEL, 0x27b9), LPC_ICH7M}, + { PCI_VDEVICE(INTEL, 0x27bc), LPC_NM10}, + { PCI_VDEVICE(INTEL, 0x27bd), LPC_ICH7MDH}, + { PCI_VDEVICE(INTEL, 0x2810), LPC_ICH8}, + { PCI_VDEVICE(INTEL, 0x2811), LPC_ICH8ME}, + { PCI_VDEVICE(INTEL, 0x2812), LPC_ICH8DH}, + { PCI_VDEVICE(INTEL, 0x2814), LPC_ICH8DO}, + { PCI_VDEVICE(INTEL, 0x2815), LPC_ICH8M}, + { PCI_VDEVICE(INTEL, 0x2912), LPC_ICH9DH}, + { PCI_VDEVICE(INTEL, 0x2914), LPC_ICH9DO}, + { PCI_VDEVICE(INTEL, 0x2916), LPC_ICH9R}, + { PCI_VDEVICE(INTEL, 0x2917), LPC_ICH9ME}, + { PCI_VDEVICE(INTEL, 0x2918), LPC_ICH9}, + { PCI_VDEVICE(INTEL, 0x2919), LPC_ICH9M}, + { PCI_VDEVICE(INTEL, 0x3197), LPC_GLK}, + { PCI_VDEVICE(INTEL, 0x2b9c), LPC_COUGARMOUNTAIN}, + { PCI_VDEVICE(INTEL, 0x3a14), LPC_ICH10DO}, + { PCI_VDEVICE(INTEL, 0x3a16), LPC_ICH10R}, + { PCI_VDEVICE(INTEL, 0x3a18), LPC_ICH10}, + { PCI_VDEVICE(INTEL, 0x3a1a), LPC_ICH10D}, + { PCI_VDEVICE(INTEL, 0x3b00), LPC_PCH}, + { PCI_VDEVICE(INTEL, 0x3b01), LPC_PCHM}, + { PCI_VDEVICE(INTEL, 0x3b02), LPC_P55}, + { PCI_VDEVICE(INTEL, 0x3b03), LPC_PM55}, + { PCI_VDEVICE(INTEL, 0x3b06), LPC_H55}, + { PCI_VDEVICE(INTEL, 0x3b07), LPC_QM57}, + { PCI_VDEVICE(INTEL, 0x3b08), LPC_H57}, + { PCI_VDEVICE(INTEL, 0x3b09), LPC_HM55}, + { PCI_VDEVICE(INTEL, 0x3b0a), LPC_Q57}, + { PCI_VDEVICE(INTEL, 0x3b0b), LPC_HM57}, + { PCI_VDEVICE(INTEL, 0x3b0d), LPC_PCHMSFF}, + { PCI_VDEVICE(INTEL, 0x3b0f), LPC_QS57}, + { PCI_VDEVICE(INTEL, 0x3b12), LPC_3400}, + { PCI_VDEVICE(INTEL, 0x3b14), LPC_3420}, + { PCI_VDEVICE(INTEL, 0x3b16), LPC_3450}, + { PCI_VDEVICE(INTEL, 0x5031), LPC_EP80579}, + { PCI_VDEVICE(INTEL, 0x5ae8), LPC_APL}, + { PCI_VDEVICE(INTEL, 0x8c40), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c41), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c42), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c43), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c44), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c45), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c46), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c47), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c48), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c49), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c4a), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c4b), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c4c), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c4d), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c4e), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c4f), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c50), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c51), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c52), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c53), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c54), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c55), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c56), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c57), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c58), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c59), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c5a), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c5b), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c5c), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c5d), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c5e), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c5f), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8cc1), LPC_9S}, + { PCI_VDEVICE(INTEL, 0x8cc2), LPC_9S}, + { PCI_VDEVICE(INTEL, 0x8cc3), LPC_9S}, + { PCI_VDEVICE(INTEL, 0x8cc4), LPC_9S}, + { PCI_VDEVICE(INTEL, 0x8cc6), LPC_9S}, + { PCI_VDEVICE(INTEL, 0x8d40), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d41), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d42), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d43), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d44), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d45), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d46), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d47), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d48), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d49), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d4a), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d4b), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d4c), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d4d), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d4e), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d4f), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d50), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d51), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d52), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d53), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d54), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d55), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d56), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d57), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d58), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d59), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d5a), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d5b), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d5c), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d5d), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d5e), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d5f), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x9c40), LPC_LPT_LP}, + { PCI_VDEVICE(INTEL, 0x9c41), LPC_LPT_LP}, + { PCI_VDEVICE(INTEL, 0x9c42), LPC_LPT_LP}, + { PCI_VDEVICE(INTEL, 0x9c43), LPC_LPT_LP}, + { PCI_VDEVICE(INTEL, 0x9c44), LPC_LPT_LP}, + { PCI_VDEVICE(INTEL, 0x9c45), LPC_LPT_LP}, + { PCI_VDEVICE(INTEL, 0x9c46), LPC_LPT_LP}, + { PCI_VDEVICE(INTEL, 0x9c47), LPC_LPT_LP}, + { PCI_VDEVICE(INTEL, 0x9cc1), LPC_WPT_LP}, + { PCI_VDEVICE(INTEL, 0x9cc2), LPC_WPT_LP}, + { PCI_VDEVICE(INTEL, 0x9cc3), LPC_WPT_LP}, + { PCI_VDEVICE(INTEL, 0x9cc5), LPC_WPT_LP}, + { PCI_VDEVICE(INTEL, 0x9cc6), LPC_WPT_LP}, + { PCI_VDEVICE(INTEL, 0x9cc7), LPC_WPT_LP}, + { PCI_VDEVICE(INTEL, 0x9cc9), LPC_WPT_LP}, + { PCI_VDEVICE(INTEL, 0xa1c1), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa1c2), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa1c3), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa1c4), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa1c5), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa1c6), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa1c7), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa242), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa243), LPC_LEWISBURG}, + { 0, }, /* End of list */ +}; +MODULE_DEVICE_TABLE(pci, lpc_ich_ids); + +static void lpc_ich_restore_config_space(struct pci_dev *dev) +{ + struct lpc_ich_priv *priv = pci_get_drvdata(dev); + + if (priv->abase_save >= 0) { + pci_write_config_byte(dev, priv->abase, priv->abase_save); + priv->abase_save = -1; + } + + if (priv->actrl_pbase_save >= 0) { + pci_write_config_byte(dev, priv->actrl_pbase, + priv->actrl_pbase_save); + priv->actrl_pbase_save = -1; + } + + if (priv->gctrl_save >= 0) { + pci_write_config_byte(dev, priv->gctrl, priv->gctrl_save); + priv->gctrl_save = -1; + } +} + +static void lpc_ich_enable_acpi_space(struct pci_dev *dev) +{ + struct lpc_ich_priv *priv = pci_get_drvdata(dev); + u8 reg_save; + + switch (lpc_chipset_info[priv->chipset].iTCO_version) { + case 3: + /* + * Some chipsets (eg Avoton) enable the ACPI space in the + * ACPI BASE register. + */ + pci_read_config_byte(dev, priv->abase, ®_save); + pci_write_config_byte(dev, priv->abase, reg_save | 0x2); + priv->abase_save = reg_save; + break; + default: + /* + * Most chipsets enable the ACPI space in the ACPI control + * register. + */ + pci_read_config_byte(dev, priv->actrl_pbase, ®_save); + pci_write_config_byte(dev, priv->actrl_pbase, reg_save | 0x80); + priv->actrl_pbase_save = reg_save; + break; + } +} + +static void lpc_ich_enable_gpio_space(struct pci_dev *dev) +{ + struct lpc_ich_priv *priv = pci_get_drvdata(dev); + u8 reg_save; + + pci_read_config_byte(dev, priv->gctrl, ®_save); + pci_write_config_byte(dev, priv->gctrl, reg_save | 0x10); + priv->gctrl_save = reg_save; +} + +static void lpc_ich_enable_pmc_space(struct pci_dev *dev) +{ + struct lpc_ich_priv *priv = pci_get_drvdata(dev); + u8 reg_save; + + pci_read_config_byte(dev, priv->actrl_pbase, ®_save); + pci_write_config_byte(dev, priv->actrl_pbase, reg_save | 0x2); + + priv->actrl_pbase_save = reg_save; +} + +static int lpc_ich_finalize_wdt_cell(struct pci_dev *dev) +{ + struct itco_wdt_platform_data *pdata; + struct lpc_ich_priv *priv = pci_get_drvdata(dev); + struct lpc_ich_info *info; + struct mfd_cell *cell = &lpc_ich_wdt_cell; + + pdata = devm_kzalloc(&dev->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + info = &lpc_chipset_info[priv->chipset]; + + pdata->version = info->iTCO_version; + strlcpy(pdata->name, info->name, sizeof(pdata->name)); + + cell->platform_data = pdata; + cell->pdata_size = sizeof(*pdata); + return 0; +} + +static void lpc_ich_finalize_gpio_cell(struct pci_dev *dev) +{ + struct lpc_ich_priv *priv = pci_get_drvdata(dev); + struct mfd_cell *cell = &lpc_ich_gpio_cell; + + cell->platform_data = &lpc_chipset_info[priv->chipset]; + cell->pdata_size = sizeof(struct lpc_ich_info); +} + +/* + * We don't check for resource conflict globally. There are 2 or 3 independent + * GPIO groups and it's enough to have access to one of these to instantiate + * the device. + */ +static int lpc_ich_check_conflict_gpio(struct resource *res) +{ + int ret; + u8 use_gpio = 0; + + if (resource_size(res) >= 0x50 && + !acpi_check_region(res->start + 0x40, 0x10, "LPC ICH GPIO3")) + use_gpio |= 1 << 2; + + if (!acpi_check_region(res->start + 0x30, 0x10, "LPC ICH GPIO2")) + use_gpio |= 1 << 1; + + ret = acpi_check_region(res->start + 0x00, 0x30, "LPC ICH GPIO1"); + if (!ret) + use_gpio |= 1 << 0; + + return use_gpio ? use_gpio : ret; +} + +static int lpc_ich_init_gpio(struct pci_dev *dev) +{ + struct lpc_ich_priv *priv = pci_get_drvdata(dev); + u32 base_addr_cfg; + u32 base_addr; + int ret; + bool acpi_conflict = false; + struct resource *res; + + /* Setup power management base register */ + pci_read_config_dword(dev, priv->abase, &base_addr_cfg); + base_addr = base_addr_cfg & 0x0000ff80; + if (!base_addr) { + dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n"); + lpc_ich_gpio_cell.num_resources--; + goto gpe0_done; + } + + res = &gpio_ich_res[ICH_RES_GPE0]; + res->start = base_addr + ACPIBASE_GPE_OFF; + res->end = base_addr + ACPIBASE_GPE_END; + ret = acpi_check_resource_conflict(res); + if (ret) { + /* + * This isn't fatal for the GPIO, but we have to make sure that + * the platform_device subsystem doesn't see this resource + * or it will register an invalid region. + */ + lpc_ich_gpio_cell.num_resources--; + acpi_conflict = true; + } else { + lpc_ich_enable_acpi_space(dev); + } + +gpe0_done: + /* Setup GPIO base register */ + pci_read_config_dword(dev, priv->gbase, &base_addr_cfg); + base_addr = base_addr_cfg & 0x0000ff80; + if (!base_addr) { + dev_notice(&dev->dev, "I/O space for GPIO uninitialized\n"); + ret = -ENODEV; + goto gpio_done; + } + + /* Older devices provide fewer GPIO and have a smaller resource size. */ + res = &gpio_ich_res[ICH_RES_GPIO]; + res->start = base_addr; + switch (lpc_chipset_info[priv->chipset].gpio_version) { + case ICH_V5_GPIO: + case ICH_V10CORP_GPIO: + res->end = res->start + 128 - 1; + break; + default: + res->end = res->start + 64 - 1; + break; + } + + ret = lpc_ich_check_conflict_gpio(res); + if (ret < 0) { + /* this isn't necessarily fatal for the GPIO */ + acpi_conflict = true; + goto gpio_done; + } + lpc_chipset_info[priv->chipset].use_gpio = ret; + lpc_ich_enable_gpio_space(dev); + + lpc_ich_finalize_gpio_cell(dev); + ret = mfd_add_devices(&dev->dev, PLATFORM_DEVID_AUTO, + &lpc_ich_gpio_cell, 1, NULL, 0, NULL); + +gpio_done: + if (acpi_conflict) + pr_warn("Resource conflict(s) found affecting %s\n", + lpc_ich_gpio_cell.name); + return ret; +} + +static int lpc_ich_init_wdt(struct pci_dev *dev) +{ + struct lpc_ich_priv *priv = pci_get_drvdata(dev); + u32 base_addr_cfg; + u32 base_addr; + int ret; + struct resource *res; + + /* If we have ACPI based watchdog use that instead */ + if (acpi_has_watchdog()) + return -ENODEV; + + /* Setup power management base register */ + pci_read_config_dword(dev, priv->abase, &base_addr_cfg); + base_addr = base_addr_cfg & 0x0000ff80; + if (!base_addr) { + dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n"); + ret = -ENODEV; + goto wdt_done; + } + + res = wdt_io_res(ICH_RES_IO_TCO); + res->start = base_addr + ACPIBASE_TCO_OFF; + res->end = base_addr + ACPIBASE_TCO_END; + + res = wdt_io_res(ICH_RES_IO_SMI); + res->start = base_addr + ACPIBASE_SMI_OFF; + res->end = base_addr + ACPIBASE_SMI_END; + + lpc_ich_enable_acpi_space(dev); + + /* + * iTCO v2: + * Get the Memory-Mapped GCS register. To get access to it + * we have to read RCBA from PCI Config space 0xf0 and use + * it as base. GCS = RCBA + ICH6_GCS(0x3410). + * + * iTCO v3: + * Get the Power Management Configuration register. To get access + * to it we have to read the PMC BASE from config space and address + * the register at offset 0x8. + */ + if (lpc_chipset_info[priv->chipset].iTCO_version == 1) { + /* Don't register iomem for TCO ver 1 */ + lpc_ich_wdt_cell.num_resources--; + } else if (lpc_chipset_info[priv->chipset].iTCO_version == 2) { + pci_read_config_dword(dev, RCBABASE, &base_addr_cfg); + base_addr = base_addr_cfg & 0xffffc000; + if (!(base_addr_cfg & 1)) { + dev_notice(&dev->dev, "RCBA is disabled by " + "hardware/BIOS, device disabled\n"); + ret = -ENODEV; + goto wdt_done; + } + res = wdt_mem_res(ICH_RES_MEM_GCS_PMC); + res->start = base_addr + ACPIBASE_GCS_OFF; + res->end = base_addr + ACPIBASE_GCS_END; + } else if (lpc_chipset_info[priv->chipset].iTCO_version == 3) { + lpc_ich_enable_pmc_space(dev); + pci_read_config_dword(dev, ACPICTRL_PMCBASE, &base_addr_cfg); + base_addr = base_addr_cfg & 0xfffffe00; + + res = wdt_mem_res(ICH_RES_MEM_GCS_PMC); + res->start = base_addr + ACPIBASE_PMC_OFF; + res->end = base_addr + ACPIBASE_PMC_END; + } + + ret = lpc_ich_finalize_wdt_cell(dev); + if (ret) + goto wdt_done; + + ret = mfd_add_devices(&dev->dev, PLATFORM_DEVID_AUTO, + &lpc_ich_wdt_cell, 1, NULL, 0, NULL); + +wdt_done: + return ret; +} + +static int lpc_ich_probe(struct pci_dev *dev, + const struct pci_device_id *id) +{ + struct lpc_ich_priv *priv; + int ret; + bool cell_added = false; + + priv = devm_kzalloc(&dev->dev, + sizeof(struct lpc_ich_priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->chipset = id->driver_data; + + priv->actrl_pbase_save = -1; + priv->abase_save = -1; + + priv->abase = ACPIBASE; + priv->actrl_pbase = ACPICTRL_PMCBASE; + + priv->gctrl_save = -1; + if (priv->chipset <= LPC_ICH5) { + priv->gbase = GPIOBASE_ICH0; + priv->gctrl = GPIOCTRL_ICH0; + } else { + priv->gbase = GPIOBASE_ICH6; + priv->gctrl = GPIOCTRL_ICH6; + } + + pci_set_drvdata(dev, priv); + + if (lpc_chipset_info[priv->chipset].iTCO_version) { + ret = lpc_ich_init_wdt(dev); + if (!ret) + cell_added = true; + } + + if (lpc_chipset_info[priv->chipset].gpio_version) { + ret = lpc_ich_init_gpio(dev); + if (!ret) + cell_added = true; + } + + /* + * We only care if at least one or none of the cells registered + * successfully. + */ + if (!cell_added) { + dev_warn(&dev->dev, "No MFD cells added\n"); + lpc_ich_restore_config_space(dev); + return -ENODEV; + } + + return 0; +} + +static void lpc_ich_remove(struct pci_dev *dev) +{ + mfd_remove_devices(&dev->dev); + lpc_ich_restore_config_space(dev); +} + +static struct pci_driver lpc_ich_driver = { + .name = "lpc_ich", + .id_table = lpc_ich_ids, + .probe = lpc_ich_probe, + .remove = lpc_ich_remove, +}; + +module_pci_driver(lpc_ich_driver); + +MODULE_AUTHOR("Aaron Sierra "); +MODULE_DESCRIPTION("LPC interface for Intel ICH"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/transceiver.c b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/transceiver.c new file mode 100644 index 000000000000..251ada569ed6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/transceiver.c @@ -0,0 +1,8409 @@ +#include +#include +#include +#include +#include "io_expander.h" +#include "transceiver.h" + +/* For build single module using (Ex: ONL platform) */ +#include +//#include +//#include + +extern int io_no_init; +/* ========== Register EEPROM address mapping ========== + */ +struct eeprom_map_s eeprom_map_sfp = { + .addr_br =0x50, .page_br =-1, .offset_br =12, .length_br =1, + .addr_cdr =-1, .page_cdr =-1, .offset_cdr =-1, .length_cdr =-1, + .addr_comp_rev =0x50, .page_comp_rev =-1, .offset_comp_rev =94, .length_comp_rev =1, + .addr_connector =0x50, .page_connector =-1, .offset_connector =2, .length_connector =1, + .addr_diag_type =0x50, .page_diag_type =-1, .offset_diag_type =92 , .length_diag_type =1, + .addr_extbr =-1, .page_extbr =-1, .offset_extbr =-1, .length_extbr =-1, + .addr_ext_id =0x50, .page_ext_id =-1, .offset_ext_id =1, .length_ext_id =1, + .addr_id =0x50, .page_id =-1, .offset_id =0, .length_id =1, + .addr_len_sm =0x50, .page_len_sm =-1, .offset_len_sm =15, .length_len_sm =1, + .addr_len_smf =0x50, .page_len_smf =-1, .offset_len_smf =14, .length_len_smf =1, + .addr_len_om1 =0x50, .page_len_om1 =-1, .offset_len_om1 =17, .length_len_om1 =1, + .addr_len_om2 =0x50, .page_len_om2 =-1, .offset_len_om2 =16, .length_len_om2 =1, + .addr_len_om3 =0x50, .page_len_om3 =-1, .offset_len_om3 =19, .length_len_om3 =1, + .addr_len_om4 =0x50, .page_len_om4 =-1, .offset_len_om4 =18, .length_len_om4 =1, + .addr_option =0x50, .page_option =-1, .offset_option =64, .length_option =2, + .addr_rate_id =0x50, .page_rate_id =-1, .offset_rate_id =13, .length_rate_id =1, + .addr_rx_am =-1, .page_rx_am =-1, .offset_rx_am =-1, .length_rx_am =-1, + .addr_rx_em =0x51, .page_rx_em =-1, .offset_rx_em =115, .length_rx_em =1, + .addr_rx_los =-1, .page_rx_los =-1, .offset_rx_los =-1, .length_rx_los =-1, + .addr_rx_power =0x51, .page_rx_power =-1, .offset_rx_power =104, .length_rx_power =2, + .addr_soft_rs0 =0x51, .page_soft_rs0 =-1, .offset_soft_rs0 =110, .length_soft_rs0 =1, + .addr_soft_rs1 =0x51, .page_soft_rs1 =-1, .offset_soft_rs1 =118, .length_soft_rs0 =1, + .addr_temp =0x51, .page_temp =-1, .offset_temp =96, .length_temp =2, + .addr_trancomp =0x50, .page_trancomp =-1, .offset_trancomp =3, .length_trancomp =8, + .addr_trancomp_ext =0x50, .page_trancomp_ext =-1, .offset_trancomp_ext =36, .length_trancomp_ext =1, + .addr_tx_bias =0x51, .page_tx_bias =-1, .offset_tx_bias =100, .length_tx_bias =2, + .addr_tx_disable =-1, .page_tx_disable =-1, .offset_tx_disable =-1, .length_tx_disable =-1, + .addr_tx_eq =0x51, .page_tx_eq =-1, .offset_tx_eq =114, .length_tx_eq =1, + .addr_tx_fault =-1, .page_tx_fault =-1, .offset_tx_fault =-1, .length_tx_fault =-1, + .addr_tx_power =0x51, .page_tx_power =-1, .offset_tx_power =102, .length_tx_power =2, + .addr_vendor_name =0x50, .page_vendor_name =-1, .offset_vendor_name =20, .length_vendor_name =16, + .addr_vendor_pn =0x50, .page_vendor_pn =-1, .offset_vendor_pn =40, .length_vendor_pn =16, + .addr_vendor_rev =0x50, .page_vendor_rev =-1, .offset_vendor_rev =56, .length_vendor_rev =4, + .addr_vendor_sn =0x50, .page_vendor_sn =-1, .offset_vendor_sn =68, .length_vendor_sn =16, + .addr_voltage =0x51, .page_voltage =-1, .offset_voltage =98, .length_voltage =2, + .addr_wavelength =0x50, .page_wavelength =-1, .offset_wavelength =60, .length_wavelength =2, +}; + +struct eeprom_map_s eeprom_map_qsfp = { + .addr_br =0x50, .page_br =0, .offset_br =140, .length_br =1, + .addr_cdr =-1, .page_cdr =-1, .offset_cdr =-1, .length_cdr =-1, + .addr_comp_rev =0x50, .page_comp_rev =-1, .offset_comp_rev =1, .length_comp_rev =1, + .addr_connector =0x50, .page_connector =0, .offset_connector =130, .length_connector =1, + .addr_diag_type =0x50, .page_diag_type =0, .offset_diag_type =220, .length_diag_type =1, + .addr_extbr =0x50, .page_extbr =0, .offset_extbr =222, .length_extbr =1, + .addr_ext_id =0x50, .page_ext_id =0, .offset_ext_id =129, .length_ext_id =1, + .addr_id =0x50, .page_id =0, .offset_id =128, .length_id =1, + .addr_len_sm =-1, .page_len_sm =-1, .offset_len_sm =-1, .length_len_sm =-1, + .addr_len_smf =0x50, .page_len_smf =0, .offset_len_smf =142, .length_len_smf =1, + .addr_len_om1 =0x50, .page_len_om1 =0, .offset_len_om1 =145, .length_len_om1 =1, + .addr_len_om2 =0x50, .page_len_om2 =0, .offset_len_om2 =144, .length_len_om2 =1, + .addr_len_om3 =0x50, .page_len_om3 =0, .offset_len_om3 =143, .length_len_om3 =1, + .addr_len_om4 =0x50, .page_len_om4 =0, .offset_len_om4 =146, .length_len_om4 =1, + .addr_option =0x50, .page_option =0, .offset_option =193, .length_option =3, + .addr_rate_id =-1, .page_rate_id =-1, .offset_rate_id =-1, .length_rate_id =-1, + .addr_rx_am =-1, .page_rx_am =-1, .offset_rx_am =-1, .length_rx_am =-1, + .addr_rx_em =-1, .page_rx_em =-1, .offset_rx_em =-1, .length_rx_em =-1, + .addr_rx_los =0x50, .page_rx_los =-1, .offset_rx_los =3, .length_rx_los =1, + .addr_rx_power =0x50, .page_rx_power =-1, .offset_rx_power =34, .length_rx_power =8, + .addr_soft_rs0 =-1, .page_soft_rs0 =-1, .offset_soft_rs0 =-1, .length_soft_rs0 =-1, + .addr_soft_rs1 =-1, .page_soft_rs1 =-1, .offset_soft_rs1 =-1, .length_soft_rs0 =-1, + .addr_temp =0x50, .page_temp =-1, .offset_temp =22, .length_temp =2, + .addr_trancomp =0x50, .page_trancomp =0, .offset_trancomp =131, .length_trancomp =8, + .addr_trancomp_ext =0x50, .page_trancomp_ext =0, .offset_trancomp_ext =192, .length_trancomp_ext =1, + .addr_tx_bias =0x50, .page_tx_bias =-1, .offset_tx_bias =42, .length_tx_bias =8, + .addr_tx_disable =0x50, .page_tx_disable =-1, .offset_tx_disable =86, .length_tx_disable =1, + .addr_tx_eq =-1, .page_tx_eq =-1, .offset_tx_eq =-1, .length_tx_eq =-1, + .addr_tx_fault =0x50, .page_tx_fault =-1, .offset_tx_fault =4, .length_tx_fault =1, + .addr_tx_power =0x50, .page_tx_power =-1, .offset_tx_power =50, .length_tx_power =8, + .addr_vendor_name =0x50, .page_vendor_name =0, .offset_vendor_name =148, .length_vendor_name =16, + .addr_vendor_pn =0x50, .page_vendor_pn =0, .offset_vendor_pn =168, .length_vendor_pn =16, + .addr_vendor_rev =0x50, .page_vendor_rev =0, .offset_vendor_rev =184, .length_vendor_rev =2, + .addr_vendor_sn =0x50, .page_vendor_sn =0, .offset_vendor_sn =196, .length_vendor_sn =16, + .addr_voltage =0x50, .page_voltage =-1, .offset_voltage =26, .length_voltage =2, + .addr_wavelength =0x50, .page_wavelength =0, .offset_wavelength =186, .length_wavelength =2, +}; + +struct eeprom_map_s eeprom_map_qsfp28 = { + .addr_br =0x50, .page_br =0, .offset_br =140, .length_br =1, + .addr_cdr =0x50, .page_cdr =-1, .offset_cdr =98, .length_cdr =1, + .addr_comp_rev =0x50, .page_comp_rev =-1, .offset_comp_rev =1, .length_comp_rev =1, + .addr_connector =0x50, .page_connector =0, .offset_connector =130, .length_connector =1, + .addr_diag_type =0x50, .page_diag_type =0, .offset_diag_type =220, .length_diag_type =1, + .addr_extbr =0x50, .page_extbr =0, .offset_extbr =222, .length_extbr =1, + .addr_ext_id =0x50, .page_ext_id =0, .offset_ext_id =129, .length_ext_id =1, + .addr_id =0x50, .page_id =0, .offset_id =128, .length_id =1, + .addr_len_sm =-1, .page_len_sm =-1, .offset_len_sm =-1, .length_len_sm =-1, + .addr_len_smf =0x50, .page_len_smf =0, .offset_len_smf =142, .length_len_smf =1, + .addr_len_om1 =0x50, .page_len_om1 =0, .offset_len_om1 =145, .length_len_om1 =1, + .addr_len_om2 =0x50, .page_len_om2 =0, .offset_len_om2 =144, .length_len_om2 =1, + .addr_len_om3 =0x50, .page_len_om3 =0, .offset_len_om3 =143, .length_len_om3 =1, + .addr_len_om4 =0x50, .page_len_om4 =0, .offset_len_om4 =146, .length_len_om4 =1, + .addr_option =0x50, .page_option =0, .offset_option =193, .length_option =3, + .addr_rate_id =-1, .page_rate_id =-1, .offset_rate_id =-1, .length_rate_id =-1, + .addr_rx_am =0x50, .page_rx_am =3, .offset_rx_am =238, .length_rx_am =2, + .addr_rx_em =0x50, .page_rx_em =3, .offset_rx_em =236, .length_rx_em =2, + .addr_rx_los =0x50, .page_rx_los =-1, .offset_rx_los =3, .length_rx_los =1, + .addr_rx_power =0x50, .page_rx_power =-1, .offset_rx_power =34, .length_rx_power =8, + .addr_soft_rs0 =-1, .page_soft_rs0 =-1, .offset_soft_rs0 =-1, .length_soft_rs0 =-1, + .addr_soft_rs1 =-1, .page_soft_rs1 =-1, .offset_soft_rs1 =-1, .length_soft_rs0 =-1, + .addr_temp =0x50, .page_temp =-1, .offset_temp =22, .length_temp =2, + .addr_trancomp =0x50, .page_trancomp =0, .offset_trancomp =131, .length_trancomp =8, + .addr_trancomp_ext =0x50, .page_trancomp_ext =0, .offset_trancomp_ext =192, .length_trancomp_ext =1, + .addr_tx_bias =0x50, .page_tx_bias =-1, .offset_tx_bias =42, .length_tx_bias =8, + .addr_tx_disable =0x50, .page_tx_disable =-1, .offset_tx_disable =86, .length_tx_disable =1, + .addr_tx_eq =0x50, .page_tx_eq =3, .offset_tx_eq =234, .length_tx_eq =2, + .addr_tx_fault =0x50, .page_tx_fault =-1, .offset_tx_fault =4, .length_tx_fault =1, + .addr_tx_power =0x50, .page_tx_power =-1, .offset_tx_power =50, .length_tx_power =8, + .addr_vendor_name =0x50, .page_vendor_name =0, .offset_vendor_name =148, .length_vendor_name =16, + .addr_vendor_pn =0x50, .page_vendor_pn =0, .offset_vendor_pn =168, .length_vendor_pn =16, + .addr_vendor_rev =0x50, .page_vendor_rev =0, .offset_vendor_rev =184, .length_vendor_rev =2, + .addr_vendor_sn =0x50, .page_vendor_sn =0, .offset_vendor_sn =196, .length_vendor_sn =16, + .addr_voltage =0x50, .page_voltage =-1, .offset_voltage =26, .length_voltage =2, + .addr_wavelength =0x50, .page_wavelength =0, .offset_wavelength =186, .length_wavelength =2, +}; + + +/* ========== Utility Functions ========== + */ +static int +get_bit(uint8_t origin_byte, int bit_shift) { + return (int)((origin_byte >> bit_shift) & 0x1); +} + +static int +transform_word_to_int(uint8_t hight_byte, + uint8_t low_byte) { + return ((((int)hight_byte) << 8) + (int)low_byte); +} + +void +alarm_msg_2_user(struct transvr_obj_s *self, + char *emsg) { + + SWPS_ERR("%s on %s.\n", emsg, self->swp_name); +} +EXPORT_SYMBOL(alarm_msg_2_user); + +/* ========== Private functions ========== + */ +static int +_reload_transvr_obj(struct transvr_obj_s *self,int new_type); + +static int +reload_transvr_obj(struct transvr_obj_s *self,int new_type); + +static int +_is_transvr_support_ctle(struct transvr_obj_s *self); + +static int +_transvr_init_handler(struct transvr_obj_s *self); + +int +_transvr_clean_handler(struct transvr_obj_s *self); + +int +_sfp_detect_class_by_1g_ethernet(struct transvr_obj_s* self); + + +void +lock_transvr_obj(struct transvr_obj_s *self) { + + mutex_lock(&self->lock); + self->curr_page = VAL_TRANSVR_PAGE_FREE; +} +EXPORT_SYMBOL(lock_transvr_obj); + + +void +unlock_transvr_obj(struct transvr_obj_s *self) { + + self->curr_page = VAL_TRANSVR_PAGE_FREE; + mutex_unlock(&self->lock); +} +EXPORT_SYMBOL(unlock_transvr_obj); + + +static int +_check_by_mode(struct transvr_obj_s *self, + int (*attr_update_func)(struct transvr_obj_s *self, int show_err), + char *caller_name){ + + int return_val = ERR_TRANSVR_UNEXCPT; + + switch (self->mode){ + case TRANSVR_MODE_POLLING: + switch (self->state){ + case STATE_TRANSVR_CONNECTED: + goto ok_check_by_mode_1; + case STATE_TRANSVR_NEW: + case STATE_TRANSVR_INIT: + return ERR_TRANSVR_UNINIT; + case STATE_TRANSVR_DISCONNECTED: + return ERR_TRANSVR_UNPLUGGED; + case STATE_TRANSVR_UNEXCEPTED: + return ERR_TRANSVR_ABNORMAL; + case STATE_TRANSVR_ISOLATED: + return ERR_TRNASVR_BE_ISOLATED; + default: + goto err_check_by_mode_1; + } + goto ok_check_by_mode_1; + + case TRANSVR_MODE_DIRECT: + return_val = self->fsm_4_direct(self, caller_name); + if (return_val < 0){ + return return_val; + } + goto ok_check_by_mode_1; + + default: + goto err_check_by_mode_1; + } + goto ok_check_by_mode_1; + +ok_check_by_mode_1: + return attr_update_func(self, 0); + +err_check_by_mode_1: + SWPS_INFO("_check_by_mode: mode:%d state:%d\n", self->mode, self->state); + return ERR_TRANSVR_UNEXCPT; +} + + +static void +_transvr_clean_retry(struct transvr_obj_s *self) { + self->retry = 0; +} + + +static int +_transvr_handle_retry(struct transvr_obj_s *self, int retry) { + /* Return: 0: keep retry + * -1: stop retry + */ + if (self->retry == 0) { + self->retry = retry; + } + self->retry -= 1; + if (self->retry <= 0) { + _transvr_clean_retry(self); + return -1; + } + return 0; +} + + +static int +_common_setup_page(struct transvr_obj_s *self, + int addr, + int page, + int offset, + int len, + int show_e) { + /* return: + * 0 : OK + * -1 : EEPROM settings incorrect + * -2 : I2C R/W failure + * -3 : Undefined case + */ + int retval = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + + /* Check */ + if ((addr < 0) || (offset < 0) || (len < 0)) { + emsg = "EEPROM settings incorrect"; + retval = -1; + goto err_common_setup_page; + } + /* Case1: continue access */ + if ((self->i2c_client_p->addr == addr) && + (self->curr_page == page)) { + return 0; + } + self->i2c_client_p->addr = addr; + /* Case2: select lower page */ + if (page == -1) { + self->curr_page = page; + return 0; + } + /* Case3: select upper page */ + if (page >= 0) { + goto upper_common_setup_page; + } + /* Unexpected case */ + show_e = 1; + emsg = "Unexpected case"; + retval = -3; + goto err_common_setup_page; + +upper_common_setup_page: + if (i2c_smbus_write_byte_data(self->i2c_client_p, + VAL_TRANSVR_PAGE_SELECT_OFFSET, + page) < 0) { + emsg = "I2C R/W failure"; + retval = -2; + goto err_common_setup_page; + } + self->curr_page = page; + mdelay(VAL_TRANSVR_PAGE_SELECT_DELAY); + return 0; + +err_common_setup_page: + if (show_e) { + SWPS_INFO("%s: %s", __func__, emsg); + SWPS_INFO("%s: :0x%02x :%d :%d :%d\n", + __func__, addr, page, offset, len); + } + return retval; +} + +/* +static int +_common_setup_password(struct transvr_obj_s *self, + int addr, + int page, + int offs, + uint8_t pwd[4], + int show_e) { + int i = 0; + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + + err = _common_setup_page(self, addr, page, offs, 4, show_e); + if (err < 0){ + emsg = "setup EEPROM page fail"; + goto err_common_setup_password; + } + for (i=0; i<4; i++) { + err = i2c_smbus_write_byte_data(self->i2c_client_p, + (offs + i), + pwd[i]); + if (err < 0){ + emsg = "I2C R/W fail!"; + goto err_common_setup_password; + } + } + return 0; + +err_common_setup_password: + if (show_e) { + SWPS_INFO("%s: %s :%d\n", __func__, emsg, err); + } + return ERR_TRANSVR_UPDATE_FAIL; +} +*/ + +static int +_common_update_uint8_attr(struct transvr_obj_s *self, + int addr, + int page, + int offset, + int len, + uint8_t *buf, + char *caller, + int show_e){ + + int i; + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + + err = _common_setup_page(self, addr, page, offset, len, show_e); + if (err < 0){ + emsg = "setup EEPROM page fail"; + goto err_common_update_uint8_attr; + } + for (i=0; ii2c_client_p, (offset + i)); + if (err < 0){ + emsg = "I2C R/W fail!"; + goto err_common_update_uint8_attr; + } + buf[i] = err; + } + return 0; + +err_common_update_uint8_attr: + if (show_e) { + SWPS_INFO("%s: %s :%s :%d\n", + __func__, emsg, caller, err); + } + buf[0] = DEBUG_TRANSVR_HEX_VAL; + return ERR_TRANSVR_UPDATE_FAIL; +} + + +static int +_common_update_int_attr(struct transvr_obj_s *self, + int addr, + int page, + int offset, + int len, + int *buf, + char *caller, + int show_e){ + + int i; + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + + err = _common_setup_page(self, addr, page, offset, len, show_e); + if (err < 0){ + emsg = "setup EEPROM page fail"; + goto err_common_update_int_attr; + } + for (i=0; ii2c_client_p, (offset + i)); + if (err < 0){ + emsg = "I2C R/W fail!"; + goto err_common_update_int_attr; + } + buf[i] = (int)err; + } + return 0; + +err_common_update_int_attr: + if (show_e) { + SWPS_INFO("%s: %s :%s :%d\n", + __func__, emsg, caller, err); + } + buf[0] = DEBUG_TRANSVR_INT_VAL; + return ERR_TRANSVR_UPDATE_FAIL; +} + + +static int +_common_update_string_attr(struct transvr_obj_s *self, + int addr, + int page, + int offset, + int len, + char buf[], + char *caller, + int show_e){ + + int i; + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + + err = _common_setup_page(self, addr, page, offset, len, show_e); + if (err < 0){ + emsg = "setup EEPROM page fail"; + goto err_common_update_string_attr; + } + for (i=0; ii2c_client_p, (offset + i)); + if (err < 0){ + emsg = "I2C R/W fail!"; + goto err_common_update_string_attr; + } + buf[i] = (char)err; + } + return 0; + +err_common_update_string_attr: + if (show_e) { + SWPS_INFO("%s: %s :%s :%d\n", + __func__, emsg, caller, err); + } + buf[0] = 'e'; + return ERR_TRANSVR_UPDATE_FAIL; +} + + +static int +_common_set_uint8_attr(struct transvr_obj_s *self, + int addr, + int page, + int offset, + uint8_t update, + uint8_t *buf, + char *caller, + int show_e){ + int len = 1; + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + + if ((*buf) == update){ + return 0; + } + err = _common_setup_page(self, addr, page, offset, len, show_e); + if (err < 0){ + emsg = "setup EEPROM page fail"; + goto err_common_set_uint8_attr_1; + } + err = i2c_smbus_write_byte_data(self->i2c_client_p, + offset, + update); + if (err < 0){ + emsg = "I2C R/W fail!"; + goto err_common_set_uint8_attr_1; + } + (*buf) = update; + return 0; + +err_common_set_uint8_attr_1: + if (show_e) { + SWPS_INFO("%s: %s :%s :%d\n", + __func__, emsg, caller, err); + } + return ERR_TRANSVR_UPDATE_FAIL; +} + + +static int +_common_set_uint8_array(struct transvr_obj_s *self, + int addr, + int page, + int offs, + int len, + uint8_t update[], + uint8_t buf[], + char *caller, + int show_e){ + int i = 0; + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + + err = _common_setup_page(self, addr, page, offs, len, show_e); + if (err < 0){ + emsg = "setup EEPROM page fail"; + goto err_common_set_uint8_attr_1; + } + for (i=0; ii2c_client_p, + (offs + i), + update[i]); + if (err < 0){ + emsg = "I2C R/W fail!"; + goto err_common_set_uint8_attr_1; + } + buf[i] = update[i]; + } + return 0; + +err_common_set_uint8_attr_1: + if (show_e) { + SWPS_INFO("%s: %s :%s :%d :%d\n", + __func__, emsg, caller, err, i); + } + return ERR_TRANSVR_UPDATE_FAIL; +} + + +static int +_common_update_attr_id(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_id, + self->eeprom_map_p->page_id, + self->eeprom_map_p->offset_id, + self->eeprom_map_p->length_id, + &(self->id), + "_common_update_attr_id", + show_err); +} + + +static int +_common_update_attr_extended_id(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_ext_id, + self->eeprom_map_p->page_ext_id, + self->eeprom_map_p->offset_ext_id, + self->eeprom_map_p->length_ext_id, + &(self->ext_id), + "_common_update_attr_extended_id", + show_err); +} + + +static int +_common_update_attr_connector(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_connector, + self->eeprom_map_p->page_connector, + self->eeprom_map_p->offset_connector, + self->eeprom_map_p->length_connector, + &(self->connector), + "_common_update_attr_connector", + show_err); +} + + +static int +_common_update_attr_transvr_comp(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_trancomp, + self->eeprom_map_p->page_trancomp, + self->eeprom_map_p->offset_trancomp, + self->eeprom_map_p->length_trancomp, + self->transvr_comp, + "_common_update_attr_transvr_comp", + show_err); +} + + +static int +_common_update_attr_transvr_comp_ext(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_trancomp_ext, + self->eeprom_map_p->page_trancomp_ext, + self->eeprom_map_p->offset_trancomp_ext, + self->eeprom_map_p->length_trancomp_ext, + &(self->transvr_comp_ext), + "_common_update_attr_transvr_comp_ext", + show_err); +} + + +static int +_common_update_attr_vendor_name(struct transvr_obj_s *self, + int show_err){ + return _common_update_string_attr(self, + self->eeprom_map_p->addr_vendor_name, + self->eeprom_map_p->page_vendor_name, + self->eeprom_map_p->offset_vendor_name, + self->eeprom_map_p->length_vendor_name, + self->vendor_name, + "_common_update_attr_vendor_name", + show_err); +} + + +static int +_common_update_attr_vendor_pn(struct transvr_obj_s *self, + int show_err){ + return _common_update_string_attr(self, + self->eeprom_map_p->addr_vendor_pn, + self->eeprom_map_p->page_vendor_pn, + self->eeprom_map_p->offset_vendor_pn, + self->eeprom_map_p->length_vendor_pn, + self->vendor_pn, + "_common_update_attr_vendor_pn", + show_err); +} + + +static int +_common_update_attr_vendor_rev(struct transvr_obj_s *self, + int show_err){ + return _common_update_string_attr(self, + self->eeprom_map_p->addr_vendor_rev, + self->eeprom_map_p->page_vendor_rev, + self->eeprom_map_p->offset_vendor_rev, + self->eeprom_map_p->length_vendor_rev, + self->vendor_rev, + "_common_update_attr_vendor_rev", + show_err); +} + + +static int +_common_update_attr_vendor_sn(struct transvr_obj_s *self, + int show_err){ + return _common_update_string_attr(self, + self->eeprom_map_p->addr_vendor_sn, + self->eeprom_map_p->page_vendor_sn, + self->eeprom_map_p->offset_vendor_sn, + self->eeprom_map_p->length_vendor_sn, + self->vendor_sn, + "_common_update_attr_vendor_sn", + show_err); +} + + +static int +_common_update_attr_br(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_br, + self->eeprom_map_p->page_br, + self->eeprom_map_p->offset_br, + self->eeprom_map_p->length_br, + &(self->br), + "_common_update_attr_br", + show_err); +} + + +static int +_common_update_attr_len_smf(struct transvr_obj_s *self, + int show_err){ + return _common_update_int_attr(self, + self->eeprom_map_p->addr_len_smf, + self->eeprom_map_p->page_len_smf, + self->eeprom_map_p->offset_len_smf, + self->eeprom_map_p->length_len_smf, + &(self->len_smf), + "_common_update_attr_len_smf", + show_err); +} + + +static int +_common_update_attr_len_om1(struct transvr_obj_s *self, + int show_err){ + return _common_update_int_attr(self, + self->eeprom_map_p->addr_len_om1, + self->eeprom_map_p->page_len_om1, + self->eeprom_map_p->offset_len_om1, + self->eeprom_map_p->length_len_om1, + &(self->len_om1), + "_common_update_attr_len_om1", + show_err); +} + +static int +_common_update_attr_len_om2(struct transvr_obj_s *self, + int show_err){ + return _common_update_int_attr(self, + self->eeprom_map_p->addr_len_om2, + self->eeprom_map_p->page_len_om2, + self->eeprom_map_p->offset_len_om2, + self->eeprom_map_p->length_len_om2, + &(self->len_om2), + "_common_update_attr_len_om2", + show_err); +} + +static int +_common_update_attr_len_om3(struct transvr_obj_s *self, + int show_err){ + return _common_update_int_attr(self, + self->eeprom_map_p->addr_len_om3, + self->eeprom_map_p->page_len_om3, + self->eeprom_map_p->offset_len_om3, + self->eeprom_map_p->length_len_om3, + &(self->len_om3), + "_common_update_attr_len_om3", + show_err); +} + + +static int +_common_update_attr_len_om4(struct transvr_obj_s *self, + int show_err){ + return _common_update_int_attr(self, + self->eeprom_map_p->addr_len_om4, + self->eeprom_map_p->page_len_om4, + self->eeprom_map_p->offset_len_om4, + self->eeprom_map_p->length_len_om4, + &(self->len_om4), + "_common_update_attr_len_om4", + show_err); +} + + +static int +_common_update_attr_option(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_option, + self->eeprom_map_p->page_option, + self->eeprom_map_p->offset_option, + self->eeprom_map_p->length_option, + self->option, + "_common_update_attr_option", + show_err); +} + + +static int +_common_update_attr_comp_rev(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_comp_rev, + self->eeprom_map_p->page_comp_rev, + self->eeprom_map_p->offset_comp_rev, + self->eeprom_map_p->length_comp_rev, + &(self->comp_rev), + "_common_update_attr_comp_rev", + show_err); +} + + +static int +_common_update_attr_diag_type(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_diag_type, + self->eeprom_map_p->page_diag_type, + self->eeprom_map_p->offset_diag_type, + self->eeprom_map_p->length_diag_type, + &(self->diag_type), + "_common_update_attr_diag_type", + show_err); +} + + +static int +_common_update_attr_wavelength(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_wavelength, + self->eeprom_map_p->page_wavelength, + self->eeprom_map_p->offset_wavelength, + self->eeprom_map_p->length_wavelength, + self->wavelength, + "_common_update_attr_wavelength", + show_err); +} + + +int +_common_get_option_value(struct transvr_obj_s *self, + int offset, + int bit_shift) { + /* SFP: + * - option[0] = A0h / 64 + * - option[1] = A0h / 65 + * QSFP: + * - option[0] = 00h / 193 + * - option[1] = 00h / 194 + * - option[2] = 00h / 195 + */ + return (self->option[offset] & (1 << bit_shift)); +} + + +static int +_sfp_update_attr_len_sm(struct transvr_obj_s *self, + int show_err){ + return _common_update_int_attr(self, + self->eeprom_map_p->addr_len_sm, + self->eeprom_map_p->page_len_sm, + self->eeprom_map_p->offset_len_sm, + self->eeprom_map_p->length_len_sm, + &(self->len_sm), + "_common_update_attr_len_sm", + show_err); +} + + +static int +_sfp_update_attr_rate_id(struct transvr_obj_s *self, + int show_err){ + return _common_update_int_attr(self, + self->eeprom_map_p->addr_rate_id, + self->eeprom_map_p->page_rate_id, + self->eeprom_map_p->offset_rate_id, + self->eeprom_map_p->length_rate_id, + &(self->rate_id), + "_sfp_update_attr_rate_id", + show_err); +} + + +static int +_sfp_update_attr_soft_rs0(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_soft_rs0, + self->eeprom_map_p->page_soft_rs0, + self->eeprom_map_p->offset_soft_rs0, + self->eeprom_map_p->length_soft_rs0, + &(self->soft_rs0), + "_sfp_update_attr_soft_rs0", + show_err); +} + + +static int +_sfp_update_attr_soft_rs1(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_soft_rs1, + self->eeprom_map_p->page_soft_rs1, + self->eeprom_map_p->offset_soft_rs1, + self->eeprom_map_p->length_soft_rs1, + &(self->soft_rs1), + "_sfp_update_attr_soft_rs1", + show_err); +} + + +int +_sfp_is_diag_support(struct transvr_obj_s *self){ + + uint8_t bit_mask = 0xC0; /* 1100 0000 */ + uint8_t en_val = 0x40; /* 0100 0000 */ + uint8_t checkval = (self->diag_type & bit_mask); + + if (checkval == en_val) { + return 1; + } + return 0; +} + + +static int +_sfp_update_attr_curr_temp(struct transvr_obj_s *self, + int show_err){ + + if (!(_sfp_is_diag_support(self))) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_temp, + self->eeprom_map_p->page_temp, + self->eeprom_map_p->offset_temp, + self->eeprom_map_p->length_temp, + self->curr_temp, + "_sfp_update_attr_curr_temp", + show_err); +} + + +static int +_sfp_update_attr_curr_voltage(struct transvr_obj_s *self, + int show_err){ + + if (!(_sfp_is_diag_support(self))) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_voltage, + self->eeprom_map_p->page_voltage, + self->eeprom_map_p->offset_voltage, + self->eeprom_map_p->length_voltage, + self->curr_voltage, + "_sfp_update_attr_curr_voltage", + show_err); +} + + +static int +_sfp_update_attr_curr_tx_bias(struct transvr_obj_s *self, + int show_err){ + + if (!(_sfp_is_diag_support(self))) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_tx_bias, + self->eeprom_map_p->page_tx_bias, + self->eeprom_map_p->offset_tx_bias, + self->eeprom_map_p->length_tx_bias, + self->curr_tx_bias, + "_sfp_update_attr_curr_tx_bias", + show_err); +} + + +static int +_sfp_update_attr_curr_tx_power(struct transvr_obj_s *self, + int show_err){ + + if (!(_sfp_is_diag_support(self))) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_tx_power, + self->eeprom_map_p->page_tx_power, + self->eeprom_map_p->offset_tx_power, + self->eeprom_map_p->length_tx_power, + self->curr_tx_power, + "_sfp_update_attr_curr_tx_power", + show_err); +} + + +static int +_sfp_update_attr_curr_rx_power(struct transvr_obj_s *self, + int show_err){ + + if (!(_sfp_is_diag_support(self))) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_rx_power, + self->eeprom_map_p->page_rx_power, + self->eeprom_map_p->offset_rx_power, + self->eeprom_map_p->length_rx_power, + self->curr_rx_power, + "_sfp_update_attr_curr_rx_power", + show_err); +} + + +static int +_sfp_update_attr_rx_em(struct transvr_obj_s *self, + int show_err){ + + if (!_is_transvr_support_ctle(self)) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_rx_em, + self->eeprom_map_p->page_rx_em, + self->eeprom_map_p->offset_rx_em, + self->eeprom_map_p->length_rx_em, + self->rx_em, + "_sfp_update_attr_rx_em", + show_err); +} + + +static int +_sfp_update_attr_tx_eq(struct transvr_obj_s *self, + int show_err){ + + if (!_is_transvr_support_ctle(self)) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_tx_eq, + self->eeprom_map_p->page_tx_eq, + self->eeprom_map_p->offset_tx_eq, + self->eeprom_map_p->length_tx_eq, + self->tx_eq, + "_sfp_update_attr_tx_eq", + show_err); +} + + +static int +_qsfp_update_attr_cdr(struct transvr_obj_s *self, + int show_err){ + if (self->type != TRANSVR_TYPE_QSFP_28){ + self->cdr = DEBUG_TRANSVR_HEX_VAL; + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_cdr, + self->eeprom_map_p->page_cdr, + self->eeprom_map_p->offset_cdr, + self->eeprom_map_p->length_cdr, + &(self->cdr), + "_common_update_attr_cdr", + show_err); +} + + +static int +_qsfg_update_attr_extbr(struct transvr_obj_s *self, + int show_err) { + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_extbr, + self->eeprom_map_p->page_extbr, + self->eeprom_map_p->offset_extbr, + self->eeprom_map_p->length_extbr, + &(self->extbr), + "_common_update_attr_extbr", + show_err); +} + + +static int +_qsfp_is_diag_support(struct transvr_obj_s *self, + int diag_type) { + /* Input Parm: diag_type + * => 1 : temperature + * => 2 : voltage + * => 3 : tx relate + * => 4 : rx relate + */ + uint8_t mask_b2 = 0x04; /* 0000 0100 */ + uint8_t mask_b3 = 0x08; /* 0000 1000 */ + + switch (diag_type) { + case 1: /* temperature */ + case 2: /* voltage */ + /* Direct access target, because of spec not defined */ + return 1; + case 3: + case 4: + /* [Note] + * Due to lot of transceiver vendor defined it not rigorously and + * consider of general support, we seem it as supported if there + * are bit-2 OR bit-3 defined by transceiver vendor. + */ + if ( ((self->diag_type & mask_b2) == mask_b2 ) || + ((self->diag_type & mask_b3) == mask_b3 ) ){ + return 1; + } + return 0; + default: + SWPS_INFO("%s: undefined diag_type:%d\n", + __func__, diag_type); + break; + } + return 0; +} + + +int +_qsfp_is_implement_tx_disable(struct transvr_obj_s *self) { + /* + * 00h / Byte-195 / Bit-4 + */ + int byte = 2; + int bit = 4; + return _common_get_option_value(self, byte, bit); +} + + +int +_qsfp_is_implement_tx_fault(struct transvr_obj_s *self) { + /* + * 00h / Byte-195 / Bit-3 + */ + int byte = 2; + int bit = 3; + return _common_get_option_value(self, byte, bit); +} + + +static int +_qsfp_update_attr_curr_temp(struct transvr_obj_s *self, + int show_err){ + int diag_type = 1; + + if (!(_qsfp_is_diag_support(self, diag_type))) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_temp, + self->eeprom_map_p->page_temp, + self->eeprom_map_p->offset_temp, + self->eeprom_map_p->length_temp, + self->curr_temp, + "_qsfp_update_attr_curr_temp", + show_err); +} + + +static int +_qsfp_update_attr_curr_voltage(struct transvr_obj_s *self, + int show_err){ + int diag_type = 2; + + if (!(_qsfp_is_diag_support(self, diag_type))) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_voltage, + self->eeprom_map_p->page_voltage, + self->eeprom_map_p->offset_voltage, + self->eeprom_map_p->length_voltage, + self->curr_voltage, + "_qsfp_update_attr_curr_voltage", + show_err); +} + + +static int +_qsfp_update_attr_curr_tx_bias(struct transvr_obj_s *self, + int show_err){ + int diag_type = 3; + + if (!(_qsfp_is_diag_support(self, diag_type))) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_tx_bias, + self->eeprom_map_p->page_tx_bias, + self->eeprom_map_p->offset_tx_bias, + self->eeprom_map_p->length_tx_bias, + self->curr_tx_bias, + "_qsfp_update_attr_curr_tx_bias", + show_err); +} + + +static int +_qsfp_update_attr_curr_tx_power(struct transvr_obj_s *self, + int show_err){ + int diag_type = 3; + + if (!(_qsfp_is_diag_support(self, diag_type))) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_tx_power, + self->eeprom_map_p->page_tx_power, + self->eeprom_map_p->offset_tx_power, + self->eeprom_map_p->length_tx_power, + self->curr_tx_power, + "_qsfp_update_attr_curr_tx_power", + show_err); +} + + +static int +_qsfp_update_attr_curr_rx_power(struct transvr_obj_s *self, + int show_err){ + int diag_type = 4; + + if (!(_qsfp_is_diag_support(self, diag_type))) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_rx_power, + self->eeprom_map_p->page_rx_power, + self->eeprom_map_p->offset_rx_power, + self->eeprom_map_p->length_rx_power, + self->curr_rx_power, + "_qsfp_update_attr_curr_rx_power", + show_err); +} + + +static int +_qsfp_update_attr_soft_rx_los(struct transvr_obj_s *self, + int show_err){ + + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_rx_los, + self->eeprom_map_p->page_rx_los, + self->eeprom_map_p->offset_rx_los, + self->eeprom_map_p->length_rx_los, + &(self->rx_los), + "_qsfp_update_attr_soft_rx_los", + show_err); +} + + +static int +_qsfp_update_attr_soft_tx_disable(struct transvr_obj_s *self, + int show_err){ + + if (!_qsfp_is_implement_tx_disable(self)) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_tx_disable, + self->eeprom_map_p->page_tx_disable, + self->eeprom_map_p->offset_tx_disable, + self->eeprom_map_p->length_tx_disable, + &(self->tx_disable), + "_qsfp_update_attr_soft_tx_disable", + show_err); +} + + +static int +_qsfp_update_attr_soft_tx_fault(struct transvr_obj_s *self, + int show_err){ + + if (!_qsfp_is_implement_tx_fault(self)) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_tx_fault, + self->eeprom_map_p->page_tx_fault, + self->eeprom_map_p->offset_tx_fault, + self->eeprom_map_p->length_tx_fault, + &(self->tx_fault), + "_qsfp_update_attr_soft_tx_fault", + show_err); +} + + +static int +_qsfp_update_attr_tx_eq(struct transvr_obj_s *self, + int show_err){ + + if (!_is_transvr_support_ctle(self)) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_tx_eq, + self->eeprom_map_p->page_tx_eq, + self->eeprom_map_p->offset_tx_eq, + self->eeprom_map_p->length_tx_eq, + self->tx_eq, + "_qsfp_update_attr_tx_eq", + show_err); +} + + +static int +_qsfp_update_attr_rx_am(struct transvr_obj_s *self, + int show_err){ + + if (!_is_transvr_support_ctle(self)) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_rx_am, + self->eeprom_map_p->page_rx_am, + self->eeprom_map_p->offset_rx_am, + self->eeprom_map_p->length_rx_am, + self->rx_am, + "_qsfp_update_attr_rx_am", + show_err); +} + + +static int +_qsfp_update_attr_rx_em(struct transvr_obj_s *self, + int show_err){ + + if (!_is_transvr_support_ctle(self)) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_rx_em, + self->eeprom_map_p->page_rx_em, + self->eeprom_map_p->offset_rx_em, + self->eeprom_map_p->length_rx_em, + self->rx_em, + "_qsfp_update_attr_rx_em", + show_err); +} + + +int +_common_update_attr_all(struct transvr_obj_s *self, + int show_err){ + + char *err_str = "err"; + + if (_common_update_attr_id(self, show_err) < 0) { + err_str = "_common_update_attr_id"; + goto err_common_update_attr_all; + } + if (_common_update_attr_extended_id(self, show_err) < 0) { + err_str = "_common_update_attr_extended_id"; + goto err_common_update_attr_all; + } + if (_common_update_attr_connector(self, show_err) < 0) { + err_str = "_common_update_attr_connector"; + goto err_common_update_attr_all; + } + if (_common_update_attr_transvr_comp(self, show_err) < 0) { + err_str = "_common_update_attr_transvr_comp"; + goto err_common_update_attr_all; + } + if (_common_update_attr_transvr_comp_ext(self, show_err) < 0) { + err_str = "_common_update_attr_transvr_comp_ext"; + goto err_common_update_attr_all; + } + if (_common_update_attr_vendor_name(self, show_err) < 0) { + err_str = "_common_update_attr_vendor_name"; + goto err_common_update_attr_all; + } + if (_common_update_attr_vendor_pn(self, show_err) < 0) { + err_str = "_common_update_attr_vendor_pn"; + goto err_common_update_attr_all; + } + if (_common_update_attr_vendor_rev(self, show_err) < 0) { + err_str = "_common_update_attr_vendor_rev"; + goto err_common_update_attr_all; + } + if (_common_update_attr_vendor_sn(self, show_err) < 0) { + err_str = "_common_update_attr_vendor_sn"; + goto err_common_update_attr_all; + } + if (_common_update_attr_br(self, show_err) < 0) { + err_str = "_common_update_attr_br"; + goto err_common_update_attr_all; + } + if (_common_update_attr_len_smf(self, show_err) < 0) { + err_str = "_common_update_attr_len_smf"; + goto err_common_update_attr_all; + } + if (_common_update_attr_len_om1(self, show_err) < 0) { + err_str = "_common_update_attr_len_om1"; + goto err_common_update_attr_all; + } + if (_common_update_attr_len_om2(self, show_err) < 0) { + err_str = "_common_update_attr_len_om2"; + goto err_common_update_attr_all; + } + if (_common_update_attr_len_om3(self, show_err) < 0) { + err_str = "_common_update_attr_len_om3"; + goto err_common_update_attr_all; + } + if (_common_update_attr_len_om4(self, show_err) < 0) { + err_str = "_common_update_attr_len_om4"; + goto err_common_update_attr_all; + } + if (_common_update_attr_option(self, show_err) < 0) { + err_str = "_common_update_attr_option"; + goto err_common_update_attr_all; + } + if (_common_update_attr_comp_rev(self, show_err) < 0) { + err_str = "_common_update_attr_comp_rev"; + goto err_common_update_attr_all; + } + if (_common_update_attr_diag_type(self, show_err) < 0) { + err_str = "_common_update_attr_diag_type"; + goto err_common_update_attr_all; + } + if (_common_update_attr_wavelength(self, show_err) < 0) { + err_str = "_common_update_attr_wavelength"; + goto err_common_update_attr_all; + } + return 0; + +err_common_update_attr_all: + if (show_err){ + SWPS_INFO("%s: fail at:%s :%s\n", __func__, err_str, self->swp_name); + } + return -1; +} + + +int +_sfp_update_attr_all(struct transvr_obj_s *self, + int show_err){ + + char *err_str = DEBUG_TRANSVR_STR_VAL; + + if (_common_update_attr_all(self, show_err) < 0){ + err_str = "_common_update_attr_all"; + goto err_sfp_update_attr_all; + } + if (_sfp_update_attr_len_sm(self, show_err) < 0) { + err_str = "_sfp_update_attr_len_sm"; + goto err_sfp_update_attr_all; + } + if (_sfp_update_attr_rate_id(self, show_err) < 0) { + err_str = "_sfp_update_attr_rate_id"; + goto err_sfp_update_attr_all; + } + if ((self->rate_id) > 0) { + if (_sfp_update_attr_soft_rs0(self, show_err) < 0) { + err_str = "_sfp_update_attr_soft_rs0"; + goto err_sfp_update_attr_all; + } + if (_sfp_update_attr_soft_rs1(self, show_err) < 0) { + err_str = "_sfp_update_attr_soft_rs1"; + goto err_sfp_update_attr_all; + } + } + return 0; + +err_sfp_update_attr_all: + if (show_err){ + SWPS_INFO("%s: fail at:%s :%s\n", __func__, err_str, self->swp_name); + } + return -1; +} + + +int +_qsfp_update_attr_all(struct transvr_obj_s *self, + int show_err){ + + char *err_str = DEBUG_TRANSVR_STR_VAL; + + if (_common_update_attr_all(self, show_err) < 0){ + err_str = "_common_update_attr_all"; + goto err_qsfp_update_attr_all; + } + if (_qsfg_update_attr_extbr(self, show_err) < 0) { + err_str = "_qsfg_update_attr_extbr"; + goto err_qsfp_update_attr_all; + } + if (self->type == TRANSVR_TYPE_QSFP_28) { + if (_qsfp_update_attr_cdr(self, 1) < 0) { + err_str = "_qsfp_update_attr_cdr"; + goto err_qsfp_update_attr_all; + } + } + return 0; + +err_qsfp_update_attr_all: + if (show_err){ + SWPS_INFO("%s: fail at:%s :%s\n", __func__, err_str, self->swp_name); + } + return -1; +} + + +/* ========== Object functions for common type ========== + */ +int +_common_count_temp(uint8_t high_byte, + uint8_t low_byte, + char *buf_p) { + int sign = 0; + int high = 0; + int low = 0; + int lmax = 8; + + /* Count high */ + sign = get_bit(high_byte,7); + SWP_BIT_CLEAR(high_byte, 7); + high = (int)high_byte; + if (sign == 1) { + high = 0 - high; + } + /* Count low */ + low = (get_bit(low_byte, 7) * 500); + low += (get_bit(low_byte, 6) * 250); + low += (get_bit(low_byte, 5) * 125); + low += (get_bit(low_byte, 4) * 62); + low = (low / 100); + /* Integrate High and Low */ + return snprintf(buf_p, lmax, "%d.%d\n", high, low); +} + + +int +_common_count_voltage(uint8_t high_byte, + uint8_t low_byte, + char *buf_p) { + /* [Note]: + * Internally measured transceiver supply voltage. Represented + * as a 16 bit unsigned integer with the voltage defined as the + * full 16 bit value (0-65535) with LSB equal to 100 uVolt, + * yielding a total range of 0 to +6.55 Volts. Practical + * considerations to be defined by transceiver manufacturer will + * tend to limit the actual bounds of the supply voltage measurement. + * Accuracy is vendor specific but must be better than 3% of the + * manufacturer's nominal value over specified operating temperature + * and voltage. Note that in some transceivers, transmitter supply + * voltage and receiver supply voltage are isolated. In that case, + * only one supply is monitored. Refer to the device specification + * for more detail. + */ + int total = 0; + int lmax = 8; + int val_i = 0; + int val_f = 0; + /* unit: 100 uV (1mV=1000uV) */ + total = transform_word_to_int(high_byte, low_byte); + val_i = ((total/10) / 1000); + val_f = ((total/10) - (val_i*1000)); + /* Return Unit: 1 Volt */ + return snprintf(buf_p, lmax, "%d.%03d\n", val_i, val_f); +} + + +int +_common_count_tx_bias(uint8_t high_byte, + uint8_t low_byte, + char *buf_p) { + /* [Note] + * Measured TX bias current in uA. Represented as a 16 bit unsigned + * integer with the current defined as the full 16 bit value (0-65535) + * with LSB equal to 2 uA, yielding a total range of 0 to 131 mA. + * Accuracy is vendor specific but must be better than 10% of the + * manufacturer's nominal value over specified operating temperature + * and voltage. + */ + int total = 0; + int lmax = 8; + int val_i = 0; + int val_f = 0; + /* unit: 2 uA (1mA=1000uA) */ + total = transform_word_to_int(high_byte, low_byte); + val_i = ((total*2) / 1000); + val_f = (((total*2) - (val_i*1000)) / 100); + /* Return Unit: 1 mA */ + return snprintf(buf_p, lmax, "%d.%01d\n", val_i, val_f); +} + + +int +_common_count_tx_power(uint8_t high_byte, + uint8_t low_byte, + char *buf_p) { + /* [Note] + * Measured TX output power in mW. Represented as a 16 bit unsigned + * integer with the power defined as the full 16 bit value (0-65535) + * with LSB equal to 0.1 uW, yielding a total range of 0 to 6.5535 mW + * (~ -40 to +8.2 dBm). Data is assumed to be based on measurement of + * laser monitor photodiode current. It is factory calibrated to absolute + * units using the most representative fiber output type. Accuracy is + * vendor specific but must be better than 3dB over specified temperature + * and voltage. Data is not valid when the transmitter is disabled. + */ + int total = 0; + int lmax = 8; + int val_i = 0; + int val_f = 0; + /* unit: 0.1 uW (1mW=1000uW) */ + total = transform_word_to_int(high_byte, low_byte); + val_i = ((total/10) / 1000); + val_f = ((total/10) - (val_i*1000)); + /* Return Unit: 1 mW */ + return snprintf(buf_p, lmax, "%d.%03d\n", val_i, val_f); +} + + +int +_common_count_rx_power(uint8_t high_byte, + uint8_t low_byte, + char *buf_p) { + /* [Note] + * Measured RX received optical power in mW. Value can represent either + * average received power or OMA depending upon how bit 3 of byte 92 (A0h) + * is set. Represented as a 16 bit unsigned integer with the power defined + * as the full 16 bit value (0-65535) with LSB equal to 0.1 uW, yielding a + * total range of 0 to 6.5535 mW (~ -40 to +8.2 dBm). Absolute accuracy is + * dependent upon the exact optical wavelength. For the vendor specified + * wavelength, accuracy shall be better than 3dB over specified temperature + * and voltage. + */ + int total = 0; + int lmax = 8; + int val_i = 0; + int val_f = 0; + /* unit: 0.1 uW (1mW=1000uW) */ + total = transform_word_to_int(high_byte, low_byte); + val_i = ((total/10) / 1000); + val_f = ((total/10) - (val_i*1000)); + /* Return Unit: 1 mW */ + return snprintf(buf_p, lmax, "%d.%03d\n", val_i, val_f); +} + + +int +_common_count_wavelength(struct transvr_obj_s *self, + uint8_t high_byte, + uint8_t low_byte) { + /* [Note] + * SFP : uint 1 um. + * QSFP: unit 0.05 um. + */ + int total = 0; + + total = transform_word_to_int(high_byte, low_byte); + switch (self->type) { + case TRANSVR_TYPE_SFP: + return total; + + case TRANSVR_TYPE_QSFP: + case TRANSVR_TYPE_QSFP_PLUS: + case TRANSVR_TYPE_QSFP_28: + return (total/20); + + default: + break; + } + return ERR_TRANSVR_UNDEFINED; +} + + +int +common_get_id(struct transvr_obj_s *self){ + + int err_code = _check_by_mode(self, + &_common_update_attr_id, + "common_get_id"); + if (err_code < 0){ + return err_code; + } + /* Transform to INT to show error case */ + return (int)self->id; +} + + +int +common_get_ext_id(struct transvr_obj_s *self){ + + int err_code = _check_by_mode(self, + &_common_update_attr_extended_id, + "common_get_ext_id"); + if (err_code < 0){ + return err_code; + } + /* Transform to INT to show error case */ + return (int)self->ext_id; +} + + +int +common_get_connector(struct transvr_obj_s *self){ + + int err_code = _check_by_mode(self, + &_common_update_attr_connector, + "common_get_connector"); + if (err_code < 0){ + return err_code; + } + /* Transform to INT to show error case */ + return (int)self->connector; +} + + +int +common_get_vendor_name(struct transvr_obj_s *self, char *buf){ + + int err = DEBUG_TRANSVR_INT_VAL; + + if (self->state == STATE_TRANSVR_CONNECTED && + self->mode == TRANSVR_MODE_POLLING && + TRANSVR_INFO_CACHE_ENABLE) { + return snprintf(buf, LEN_TRANSVR_M_STR, "%s\n", self->vendor_name); + } + err = _check_by_mode(self, + &_common_update_attr_vendor_name, + "common_get_vendor_name"); + memset(buf, 0, LEN_TRANSVR_M_STR); + if (err < 0){ + return snprintf(buf, LEN_TRANSVR_M_STR, "%d\n", err); + } + return snprintf(buf, LEN_TRANSVR_M_STR, "%s\n", self->vendor_name); +} + + +int +common_get_vendor_pn(struct transvr_obj_s *self, char *buf) { + + int err = DEBUG_TRANSVR_INT_VAL; + + if (self->state == STATE_TRANSVR_CONNECTED && + self->mode == TRANSVR_MODE_POLLING && + TRANSVR_INFO_CACHE_ENABLE) { + return snprintf(buf, LEN_TRANSVR_M_STR, "%s\n", self->vendor_pn); + } + err = _check_by_mode(self, + &_common_update_attr_vendor_pn, + "common_get_vendor_pn"); + memset(buf, 0, LEN_TRANSVR_M_STR); + if (err < 0){ + return snprintf(buf, LEN_TRANSVR_M_STR, "%d\n", err); + } + return snprintf(buf, LEN_TRANSVR_M_STR, "%s\n", self->vendor_pn); +} + + +int +common_get_vendor_rev(struct transvr_obj_s *self, char *buf) { + + int err = DEBUG_TRANSVR_INT_VAL; + + if (self->state == STATE_TRANSVR_CONNECTED && + self->mode == TRANSVR_MODE_POLLING && + TRANSVR_INFO_CACHE_ENABLE) { + return snprintf(buf, LEN_TRANSVR_M_STR, "%s\n", self->vendor_rev); + } + err = _check_by_mode(self, + &_common_update_attr_vendor_rev, + "common_get_vendor_rev"); + memset(buf, 0, LEN_TRANSVR_M_STR); + if (err < 0){ + return snprintf(buf, LEN_TRANSVR_M_STR, "%d\n", err); + } + return snprintf(buf, LEN_TRANSVR_M_STR, "%s\n", self->vendor_rev); +} + + +int +common_get_vendor_sn(struct transvr_obj_s *self, char *buf) { + + int err = DEBUG_TRANSVR_INT_VAL; + + if (self->state == STATE_TRANSVR_CONNECTED && + self->mode == TRANSVR_MODE_POLLING && + TRANSVR_INFO_CACHE_ENABLE) { + return snprintf(buf, LEN_TRANSVR_M_STR, "%s\n", self->vendor_sn); + } + err = _check_by_mode(self, + &_common_update_attr_vendor_sn, + "common_get_vendor_sn"); + memset(buf, 0, LEN_TRANSVR_M_STR); + if (err < 0){ + return snprintf(buf, LEN_TRANSVR_M_STR, "%d\n", err); + } + return snprintf(buf, LEN_TRANSVR_M_STR, "%s\n", self->vendor_sn); +} + + +int +common_get_br(struct transvr_obj_s *self){ + + int err = DEBUG_TRANSVR_INT_VAL; + + if (self->state == STATE_TRANSVR_CONNECTED && + self->mode == TRANSVR_MODE_POLLING && + TRANSVR_INFO_CACHE_ENABLE) { + return (int)self->br; + } + err = _check_by_mode(self, + &_common_update_attr_br, + "common_get_br"); + if (err < 0){ + return err; + } + /* Transform to INT to show error case */ + return (int)self->br; +} + + +int +common_get_len_smf(struct transvr_obj_s *self){ + + int err = DEBUG_TRANSVR_INT_VAL; + + if (self->state == STATE_TRANSVR_CONNECTED && + self->mode == TRANSVR_MODE_POLLING && + TRANSVR_INFO_CACHE_ENABLE) { + return self->len_smf; + } + err = _check_by_mode(self, + &_common_update_attr_len_smf, + "common_get_len_smf"); + if (err < 0){ + return err; + } + return self->len_smf; +} + + +int +common_get_len_om1(struct transvr_obj_s *self){ + + int err = DEBUG_TRANSVR_INT_VAL; + + if (self->state == STATE_TRANSVR_CONNECTED && + self->mode == TRANSVR_MODE_POLLING && + TRANSVR_INFO_CACHE_ENABLE) { + return self->len_om1; + } + err = _check_by_mode(self, + &_common_update_attr_len_om1, + "common_get_len_om1"); + if (err < 0){ + return err; + } + return self->len_om1; +} + + +int +common_get_len_om2(struct transvr_obj_s *self){ + + int err = DEBUG_TRANSVR_INT_VAL; + + if (self->state == STATE_TRANSVR_CONNECTED && + self->mode == TRANSVR_MODE_POLLING && + TRANSVR_INFO_CACHE_ENABLE) { + return self->len_om2; + } + + err = _check_by_mode(self, + &_common_update_attr_len_om2, + "common_get_len_om2"); + if (err < 0){ + return err; + } + return self->len_om2; +} + + +int +common_get_len_om3(struct transvr_obj_s *self){ + + int err = DEBUG_TRANSVR_INT_VAL; + + if (self->state == STATE_TRANSVR_CONNECTED && + self->mode == TRANSVR_MODE_POLLING && + TRANSVR_INFO_CACHE_ENABLE) { + return self->len_om3; + } + + err = _check_by_mode(self, + &_common_update_attr_len_om3, + "common_get_len_om3"); + if (err < 0){ + return err; + } + return self->len_om3; +} + + +int +common_get_len_om4(struct transvr_obj_s *self){ + + int err = DEBUG_TRANSVR_INT_VAL; + + if (self->state == STATE_TRANSVR_CONNECTED && + self->mode == TRANSVR_MODE_POLLING && + TRANSVR_INFO_CACHE_ENABLE) { + return self->len_om4; + } + err = _check_by_mode(self, + &_common_update_attr_len_om4, + "common_get_len_om4"); + if (err < 0){ + return err; + } + return self->len_om4; +} + + +int +common_get_comp_extended(struct transvr_obj_s *self){ + + int err_code = _check_by_mode(self, + &_common_update_attr_transvr_comp_ext, + "common_get_comp_extended"); + if (err_code < 0){ + return err_code; + } + return self->transvr_comp_ext; +} + + +int +common_get_comp_rev(struct transvr_obj_s *self){ + + int err_code = _check_by_mode(self, + &_common_update_attr_comp_rev, + "common_get_comp_rev"); + if (err_code < 0){ + return err_code; + } + return self->comp_rev; +} + + +int +common_get_info(struct transvr_obj_s *self){ + + if (self->state != STATE_TRANSVR_CONNECTED) { + return self->state; + } + return self->info; +} + + +int +_common_get_if_lane(struct transvr_obj_s *self, + char *result){ + int i = 0; + int tmp_val = 0; + char tmp_str[LEN_TRANSVR_M_STR] = DEBUG_TRANSVR_STR_VAL; + + memset(result, 0, LEN_TRANSVR_M_STR); + + for (i=0; ilane_id); i++) { + tmp_val = self->lane_id[i]; + if (tmp_val < 1) { + break; + } + memset(tmp_str, 0, LEN_TRANSVR_M_STR); + if (i == 0) { + snprintf(tmp_str, LEN_TRANSVR_M_STR, "%d", tmp_val); + } else { + snprintf(tmp_str, LEN_TRANSVR_M_STR, ",%d", tmp_val); + } + strncat(result, tmp_str, LEN_TRANSVR_M_STR); + } + if (i == 0) { + return EVENT_TRANSVR_TASK_FAIL; + } + return 0; +} + + +int +common_get_if_lane(struct transvr_obj_s *self, + char *buf_p){ + + char tmp_str[LEN_TRANSVR_M_STR] = DEBUG_TRANSVR_STR_VAL; + + if (self->ioexp_obj_p->state != STATE_IOEXP_NORMAL) { + return snprintf(buf_p, LEN_TRANSVR_M_STR, "%d\n", ERR_TRANSVR_ABNORMAL); + } + if (_common_get_if_lane(self, tmp_str) < 0) { + return snprintf(buf_p, LEN_TRANSVR_M_STR, "%d\n" ,ERR_TRANSVR_ABNORMAL); + } + return snprintf(buf_p, LEN_TRANSVR_M_STR, "%s\n" ,tmp_str); +} + + +int +sfp_get_len_sm(struct transvr_obj_s *self){ + + int err_code = _check_by_mode(self, + &_sfp_update_attr_len_sm, + "sfp_get_len_sm"); + if (err_code < 0){ + return err_code; + } + return self->len_sm; +} + + +int +sfp_get_rate_id(struct transvr_obj_s *self){ + + int err_code = _check_by_mode(self, + &_sfp_update_attr_rate_id, + "sfp_get_rate_id"); + if (err_code < 0){ + return err_code; + } + return self->rate_id; +} + + +int +sfp_get_soft_rs0(struct transvr_obj_s *self){ + /* Note: + * SFP Soft Rate_Select Select [aka. "RS(0)"] address + * A2h, offset: 110, bit 3 (begin form 0) + */ + int err_code = DEBUG_TRANSVR_INT_VAL; + int bit_shift = 3; + uint8_t result = 0x00; + uint8_t bitmask = (1 << bit_shift); + + /* Check rate identifier is supported */ + err_code = self->get_rate_id(self); + if (err_code <= 0) { + return ERR_TRANSVR_NOTSUPPORT; + } + /* Update and check */ + err_code = _check_by_mode(self, + &_sfp_update_attr_soft_rs0, + "sfp_get_soft_rs0"); + if (err_code <0){ + return err_code; + } + result = (self->soft_rs0 & bitmask); + if (result == bitmask) { + return 1; + } + if (result == 0) { + return 0; + } + return ERR_TRANSVR_UNEXCPT; +} + + +int +sfp_get_soft_rs1(struct transvr_obj_s *self){ + /* Note: + * SFP Soft RS(1) Select address + * A2h, offset: 118, bit 3 (begin form 0) + */ + int err_code = DEBUG_TRANSVR_INT_VAL; + int bit_shift = 3; + uint8_t result = 0x00; + uint8_t bitmask = (1 << bit_shift); + + /* Check rate identifier is supported */ + err_code = self->get_rate_id(self); + if (err_code <= 0) { + return ERR_TRANSVR_NOTSUPPORT; + } + /* Update and check */ + err_code = _check_by_mode(self, + &_sfp_update_attr_soft_rs1, + "sfp_get_soft_rs1"); + if (err_code <0){ + return err_code; + } + result = (self->soft_rs1 & bitmask); + if (result == bitmask) { + return 1; + } + if (result == 0) { + return 0; + } + return ERR_TRANSVR_UNEXCPT; +} + + +int +sfp_get_transvr_temp(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_sfp_update_attr_curr_temp, + "sfp_get_transvr_temp"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->curr_temp[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + return _common_count_temp(self->curr_temp[0], + self->curr_temp[1], + buf_p); +} + + +int +sfp_get_transvr_voltage(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_sfp_update_attr_curr_voltage, + "sfp_get_transvr_voltage"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->curr_voltage[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + /* Return Unit: 1 Volt */ + return _common_count_voltage(self->curr_voltage[0], + self->curr_voltage[1], + buf_p); +} + + +int +sfp_get_transvr_tx_bias(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_sfp_update_attr_curr_tx_bias, + "sfp_get_transvr_tx_bias"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->curr_tx_bias[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + /* Return Unit: 1 mA */ + return _common_count_tx_bias(self->curr_tx_bias[0], + self->curr_tx_bias[1], + buf_p); +} + + +int +sfp_get_transvr_tx_power(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_sfp_update_attr_curr_tx_power, + "sfp_get_transvr_tx_power"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->curr_tx_bias[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + /* Return Unit: 1 mW */ + return _common_count_tx_power(self->curr_tx_power[0], + self->curr_tx_power[1], + buf_p); +} + + +int +sfp_get_transvr_rx_power(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_sfp_update_attr_curr_rx_power, + "sfp_get_transvr_rx_power"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->curr_tx_bias[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + /* Return Unit: 1 mW */ + return _common_count_rx_power(self->curr_rx_power[0], + self->curr_rx_power[1], + buf_p); +} + + +int +sfp_get_transvr_rx_em(struct transvr_obj_s *self, + char *buf_p) { + + int limt = 8; + int err = DEBUG_TRANSVR_INT_VAL; + + err = _check_by_mode(self, + &_sfp_update_attr_rx_em, + "sfp_get_transvr_rx_em"); + if (err < 0) { + return snprintf(buf_p, limt, "%d\n", err); + } + if ((self->tx_eq[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, limt, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + return snprintf(buf_p, limt, "0x%02x\n", self->rx_em[0]); +} + + +int +sfp_get_transvr_tx_eq(struct transvr_obj_s *self, + char *buf_p) { + + int limt = 8; + int err = DEBUG_TRANSVR_INT_VAL; + + err = _check_by_mode(self, + &_sfp_update_attr_tx_eq, + "sfp_get_transvr_tx_eq"); + if (err < 0) { + return snprintf(buf_p, limt, "%d\n", err); + } + if ((self->tx_eq[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, limt, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + return snprintf(buf_p, limt, "0x%02x\n", self->tx_eq[0]); +} + + +int +_sfp_get_comp_extended(struct transvr_obj_s *self) { + /* Address: A0h / 36 + * Reference: SFF-8024 TABLE 4-4 + */ + if ((self->state == STATE_TRANSVR_CONNECTED) || + (self->state == STATE_TRANSVR_INIT) ) { + return (int)(self->transvr_comp_ext); + } + return ERR_TRANSVR_ABNORMAL; +} + + +int +__sfp_get_comp_attr(struct transvr_obj_s *self, + int array_offset) { + /* SFP Specification Compliance: A0h / 3-10 + * transvr_comp[0-7] = 3 - 10 + */ + if ((self->state == STATE_TRANSVR_CONNECTED) || + (self->state == STATE_TRANSVR_INIT) ) { + return (int)(self->transvr_comp[array_offset]); + } + return ERR_TRANSVR_ABNORMAL; +} + + +int +_sfp_get_comp_10g_eth_comp(struct transvr_obj_s *self) { + /* transvr_comp[0] = address A0h / 3 + * + * 3 7: 10G Base-ER + * 3 6: 10GBASE-LRM + * 3 5: 10GBASE-LR + * 3 4: 10GBASE-SR + */ + int bitmask = 0xf0; /* 11110000 */ + return (__sfp_get_comp_attr(self, 0) & bitmask); +} + + +int +_sfp_get_comp_1g_eth_comp(struct transvr_obj_s *self) { + /* transvr_comp[3] = address A0h / 6 + * + * 6 7: BASE-PX *3 + * 6 6: BASE-BX10 *3 + * 6 5: 100BASE-FX + * 6 4: 100BASE-LX/LX10 + * 6 3: 1000BASE-T + * 6 2: 1000BASE-CX + * 6 1: 1000BASE-LX *3 + * 6 0: 1000BASE-SX + */ + return __sfp_get_comp_attr(self, 3); +} + + +int +_sfp_get_cable_tech(struct transvr_obj_s *self) { + /* transvr_comp[5] = address A0h / 8 + * + * 8 3: Active Cable *8 + * 8 2: Passive Cable *8 + */ + int bitmask = 0x0c; /* 00001100 */ + return (__sfp_get_comp_attr(self, 5) & bitmask); +} + + +int +sfp_get_comp_eth_1(struct transvr_obj_s *self){ + + int err_code = _check_by_mode(self, + &_common_update_attr_transvr_comp, + "sfp_get_comp_eth_1"); + if (err_code < 0){ + return err_code; + } + return _sfp_get_comp_1g_eth_comp(self); +} + + +int +sfp_get_comp_eth_10(struct transvr_obj_s *self){ + + int err_code = _check_by_mode(self, + &_common_update_attr_transvr_comp, + "sfp_get_comp_eth_10"); + if (err_code < 0){ + return err_code; + } + return _sfp_get_comp_10g_eth_comp(self); +} + + +int +_sfp_get_connector_type(struct transvr_obj_s *self) { + /* Address: A0h / 2 + * Reference: SFF-8024 TABLE 4-3 + */ + if ((self->state == STATE_TRANSVR_CONNECTED) || + (self->state == STATE_TRANSVR_INIT) ) { + return (int)(self->connector); + } + return ERR_TRANSVR_ABNORMAL; +} + + +int +sfp_get_wavelength(struct transvr_obj_s *self, + char *buf_p) { + /* [Note] Optical and Cable Variants Specification Compliance (SFF-8472) + * [Addr] A0h, Bytes 60-61 + * [Note] For optical variants, as defined by having zero's in A0h Byte 8 + * bits 2 and 3, Bytes 60 and 61 denote nominal transmitter output + * wavelength at room temperature. 16 bit value with byte 60 as high + * order byte and byte 61 as low order byte. The laser wavelength is + * equal to the 16 bit integer value in nm. This field allows the user + * to read the laser wavelength directly, so it is not necessary to + * infer it from the Transceiver Codes A0h Bytes 3 to 10 (see Table + * 5-3). This also allows specification of wavelengths not covered + * in the Transceiver Codes, such as those used in coarse WDM systems. + * + * For passive and active cable variants, a value of 00h for both A0h + * Byte 60 and Byte 61 denotes laser wavelength or cable specification + * compliance is unspecified. + */ + + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_common_update_attr_wavelength, + "common_get_wavelength"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->wavelength[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + /* unit: 1 um */ + return snprintf(buf_p, lmax, "%d\n", + _common_count_wavelength(self, + self->wavelength[0], + self->wavelength[1])); +} + + +int +sfp_get_1g_rj45_extphy_offset(struct transvr_obj_s *self, char *buf) { + + if (self->state != STATE_TRANSVR_CONNECTED) { + return ERR_TRANSVR_UNPLUGGED; + } + if ((self->info != TRANSVR_CLASS_BASE_T_1000) && + (self->info != TRANSVR_CLASS_BASE_T_1000_up) ){ + return ERR_TRANSVR_NOTSUPPORT; + } + return snprintf(buf, LEN_TRANSVR_S_STR, "0x%02x\n", self->extphy_offset); +} + + +int +sfp_get_1g_rj45_extphy_reg(struct transvr_obj_s *self, char *buf) { + + int i = 0; + int ret = 0; + int retry = 3; + int delay = 200; + + if (self->state != STATE_TRANSVR_CONNECTED) { + return ERR_TRANSVR_UNPLUGGED; + } + if ((self->info != TRANSVR_CLASS_BASE_T_1000) && + (self->info != TRANSVR_CLASS_BASE_T_1000_up) ){ + return ERR_TRANSVR_NOTSUPPORT; + } + if (_common_setup_page(self, VAL_TRANSVR_EXTPHY_ADDR_56, + -1, self->extphy_offset, 1, 0) < 0) { + return -EIO; + } + for (i=0; ii2c_client_p, self->extphy_offset); + if (ret >=0) { + goto ok_sfp_get_1g_rj45_extphy_reg; + } + msleep(delay); + } + SWPS_INFO("%s: retry:%d fail :%s :0x%02x\n", + __func__, retry, self->swp_name, self->extphy_offset); + return -EIO; + +ok_sfp_get_1g_rj45_extphy_reg: + ret = ((ret & 0x00ff) << 8) | ((ret & 0xff00) >> 8); + return snprintf(buf, LEN_TRANSVR_S_STR, "0x%04x\n", ret); +} + + +int +__qsfp_get_power_cls(struct transvr_obj_s *self, + int direct_access){ + + int err_code; + uint8_t detect_val; + + /* Detect and Update power class attribute */ + if (direct_access){ + err_code = _check_by_mode(self, + &_common_update_attr_extended_id, + "__qsfp_get_power_cls"); + } else { + err_code = self->ext_id; + } + if (err_code <0){ + return err_code; + } + if (err_code == DEBUG_TRANSVR_HEX_VAL){ + return ERR_TRANSVR_UPDATE_FAIL; + } + /* Clean data */ + detect_val = self->ext_id; + SWP_BIT_CLEAR(detect_val, 2); /* Bit2: CDR RX present */ + SWP_BIT_CLEAR(detect_val, 3); /* Bit3: CDR TX present */ + SWP_BIT_CLEAR(detect_val, 4); /* Bit4: CLEI present */ + SWP_BIT_CLEAR(detect_val, 5); /* Bit5: reserved */ + /* Identify power class */ + switch (detect_val) { + case 0: /* Class_1: 00000000 */ + return 1; + case 64: /* Class_2: 01000000 */ + return 2; + case 128: /* Class_3: 10000000 */ + return 3; + case 192: /* Class_4: 11000000 */ + return 4; + case 1: /* Class_5: 00000001 */ + case 193: /* Class_5: 11000001 */ + return 5; + case 2: /* Class_6: 00000010 */ + case 194: /* Class_6: 11000010 */ + return 6; + case 3: /* Class_7: 00000011 */ + case 195: /* Class_7: 11000011 */ + return 7; + default: + break; + } + SWPS_INFO("%s: Detect undefined power class:%d\n", __func__, detect_val); + return ERR_TRANSVR_UNDEFINED; +} + + +int +qsfp_get_power_cls(struct transvr_obj_s *self) { + return __qsfp_get_power_cls(self, 1); +} + + +int +__qsfp_get_cdr_present(struct transvr_obj_s *self, + int direct_access){ + + int retval; + int BIT_SHIFT = 2; + int BIT_MASK = 0x3; + + /* Detect and Update power class attribute */ + if (direct_access) { + retval = _check_by_mode(self, + &_common_update_attr_extended_id, + "__qsfp_get_cdr_present"); + if (retval < 0){ + return retval; + } + } + retval = self->ext_id; + if (retval == DEBUG_TRANSVR_HEX_VAL){ + return ERR_TRANSVR_UPDATE_FAIL; + } + /* Clean data and return */ + return (int)(retval >> BIT_SHIFT & BIT_MASK); +} + + +int +qsfp_get_cdr_present(struct transvr_obj_s *self) { + return __qsfp_get_cdr_present(self, 1); +} + + +int +qsfp_get_cdr(struct transvr_obj_s *self){ + + int err_code = _check_by_mode(self, + &_qsfp_update_attr_cdr, + "qsfp_get_cdr"); + if (err_code <0){ + return err_code; + } + + return self->cdr; +} + + +int +__qsfp_get_comp_attr(struct transvr_obj_s *self, + int array_offset) { + /* QSFP Specification Compliance: 00h / 131-138 + * transvr_comp[0-7] = 131 - 138 + */ + if ((self->state == STATE_TRANSVR_CONNECTED) || + (self->state == STATE_TRANSVR_INIT) ) { + return (int)(self->transvr_comp[array_offset]); + } + return ERR_TRANSVR_ABNORMAL; +} + + +int +_qsfp_get_comp_10_40_100_ethernet(struct transvr_obj_s *self) { + /* transvr_comp[0] = address 00h / 131 + * + * 131 7: Extended: See section 6.3.23. The Extended Specification Compliance + * Codes are maintained in the Transceiver Management section of SFF- + * 8024. + * 131 6: 10GBASE-LRM + * 131 5: 10GBASE-LR + * 131 4: 10GBASE-SR + * 131 3: 40GBASE-CR4 + * 131 2: 40GBASE-SR4 + * 131 1: 40GBASE-LR4 + * 131 0: 40G Active Cable (XLPPI) + */ + return __qsfp_get_comp_attr(self, 0); +} + + +int +_qsfp_get_comp_sonet(struct transvr_obj_s *self) { + /* transvr_comp[1] = address 00h / 132 + * + * 132 7-3: Reserved + * 132 2: OC 48, long reach + * 132 1: OC 48, intermediate reach + * 132 0: OC 48 short reach + */ + return __qsfp_get_comp_attr(self, 1); +} + + +int +_qsfp_get_comp_sas_sata(struct transvr_obj_s *self) { + /* transvr_comp[1] = address 00h / 132 + * + * 133 7: SAS 24.0 Gb/s + * 133 6: SAS 12.0 Gb/s + * 133 5: SAS 6.0 Gb/s + * 133 4: SAS 3.0 Gb/s + * 133 3-0: Reserved + */ + return __qsfp_get_comp_attr(self, 2); +} + + +int +_qsfp_get_comp_ethernet(struct transvr_obj_s *self) { + /* transvr_comp[1] = address 00h / 132 + * + * 134 7-4: Reserved + * 134 3: 1000BASE-T + * 134 2: 1000BASE-CX + * 134 1: 1000BASE-LX + * 134 0: 1000BASE-SX + */ + return __qsfp_get_comp_attr(self, 3); +} + + +int +_qsfp_get_comp_fc_link_length(struct transvr_obj_s *self) { + /* transvr_comp[1] = address 00h / 132 + * + * 135 7: Very long distance (V) + * 135 6: Short distance (S) + * 135 5: Intermediate distance (I) + * 135 4: Long distance (L) + * 135 3: Medium (M) + */ + int mask = 0xFC; /* 11111100 */ + return (__qsfp_get_comp_attr(self, 4) & mask); +} + + +int +_qsfp_get_comp_fc_trans_tech(struct transvr_obj_s *self) { + /* transvr_comp[1] = address 00h / 132 + * + * 135 2: Reserved + * 135 1: Longwave laser (LC) + * 135 0: Electrical inter-enclosure (EL) + * + * 136 7: Electrical intra-enclosure + * 136 6: Shortwave laser w/o OFC (SN) + * 136 5: Shortwave laser w OFC (SL) + * 136 4: Longwave Laser (LL) + * 136 3-0: Reserved + * + * return value = [bit 8-15:addr 135][bit 0-7:addr 136] + */ + int mask_135 = 7; /* 00000111 */ + int val_135 = (__qsfp_get_comp_attr(self, 4) & mask_135); + int val_136 = __qsfp_get_comp_attr(self, 5); + return ((val_135 << 7) + val_136); +} + + +int +_qsfp_get_comp_fc_trans_media(struct transvr_obj_s *self) { + /* transvr_comp[1] = address 00h / 132 + * + * 137 7: Twin Axial Pair (TW) + * 137 6: Shielded Twisted Pair (TP) + * 137 5: Miniature Coax (MI) + * 137 4: Video Coax (TV) + * 137 3: Multi-mode 62.5 m (M6) + * 137 2: Multi-mode 50 m (M5) + * 137 1: Multi-mode 50 um (OM3) + * 137 0: Single Mode (SM) + */ + return __qsfp_get_comp_attr(self, 6); +} + + +int +_qsfp_get_comp_fc_speed(struct transvr_obj_s *self) { + /* transvr_comp[1] = address 00h / 132 + * + * 138 7: 1200 MBps (per channel) + * 138 6: 800 MBps + * 138 5: 1600 MBps (per channel) + * 138 4: 400 MBps + * 138 3: 3200 MBps (per channel) + * 138 2: 200 MBps + * 138 1: Extended: See section 6.3.23. The Extended Specification + * Compliance Codes are maintained in the Transceiver Management + * section of SFF-8024. + * 138 0: 100 MBps + */ + return __qsfp_get_comp_attr(self, 7); +} + + +int +_qsfp_get_comp_extended(struct transvr_obj_s *self) { + /* Address: 00h / 192 + * Reference: SFF-8024 TABLE 4-4 + */ + if ((self->state == STATE_TRANSVR_CONNECTED) || + (self->state == STATE_TRANSVR_INIT) ) { + return (int)(self->transvr_comp_ext); + } + return ERR_TRANSVR_ABNORMAL; +} + + +int +qsfp_get_comp_eth(struct transvr_obj_s *self){ + + int err_code = _check_by_mode(self, + &_common_update_attr_transvr_comp, + "qsfp_get_comp_eth"); + if (err_code < 0){ + return err_code; + } + return _qsfp_get_comp_ethernet(self); +} + + +int +qsfp_get_comp_10_40(struct transvr_obj_s *self) { + + int err_code = _check_by_mode(self, + &_common_update_attr_transvr_comp, + "qsfp_get_comp_10_40"); + if (err_code < 0){ + return err_code; + } + return _qsfp_get_comp_10_40_100_ethernet(self); +} + + +int +_qsfp_get_connector_type(struct transvr_obj_s *self) { + /* Address: 00h / 130 + * Reference: SFF-8024 TABLE 4-3 + */ + if ((self->state == STATE_TRANSVR_CONNECTED) || + (self->state == STATE_TRANSVR_INIT) ) { + return (int)(self->connector); + } + return ERR_TRANSVR_ABNORMAL; +} + + +int +qsfp_get_transvr_temp(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_qsfp_update_attr_curr_temp, + "qsfp_get_transvr_temp"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->curr_temp[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + return _common_count_temp(self->curr_temp[0], + self->curr_temp[1], + buf_p); +} + + +int +qsfp_get_transvr_voltage(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_qsfp_update_attr_curr_voltage, + "qsfp_get_transvr_voltage"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->curr_voltage[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + /* Return Unit: 1 Volt */ + return _common_count_voltage(self->curr_voltage[0], + self->curr_voltage[1], + buf_p); +} + + +int +qsfp_get_transvr_tx_eq(struct transvr_obj_s *self, + char *buf_p) { + + int limt = 8; + int err = DEBUG_TRANSVR_INT_VAL; + + err = _check_by_mode(self, + &_qsfp_update_attr_tx_eq, + "qsfp_get_transvr_tx_eq"); + if (err < 0) { + return snprintf(buf_p, limt, "%d\n", err); + } + if ((self->tx_eq[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, limt, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + return snprintf(buf_p, limt, "0x%02x%02x\n", + self->tx_eq[0], self->tx_eq[1]); +} + + +int +qsfp_get_transvr_rx_am(struct transvr_obj_s *self, + char *buf_p) { + + int limt = 8; + int err = DEBUG_TRANSVR_INT_VAL; + + err = _check_by_mode(self, + &_qsfp_update_attr_rx_am, + "qsfp_get_transvr_rx_am"); + if (err < 0) { + return snprintf(buf_p, limt, "%d\n", err); + } + if ((self->rx_am[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, limt, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + return snprintf(buf_p, limt, "0x%02x%02x\n", + self->rx_am[0], self->rx_am[1]); +} + + +int +qsfp_get_transvr_rx_em(struct transvr_obj_s *self, + char *buf_p) { + + int limt = 8; + int err = DEBUG_TRANSVR_INT_VAL; + + err = _check_by_mode(self, + &_qsfp_update_attr_rx_em, + "qsfp_get_transvr_rx_em"); + if (err < 0) { + return snprintf(buf_p, limt, "%d\n", err); + } + if ((self->rx_em[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, limt, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + return snprintf(buf_p, limt, "0x%02x%02x\n", + self->rx_em[0], self->rx_em[1]); +} + + +int +_qsfp_get_channel_diag(uint8_t *data_array, + int (*count_func)(uint8_t high_byte, uint8_t low_byte, char *buf_p), + char *ch_name, + char *result_p) { + int i, high, low; + int len_max = 128; + char ch_buf[4][16] = { DEBUG_TRANSVR_STR_VAL, + DEBUG_TRANSVR_STR_VAL, + DEBUG_TRANSVR_STR_VAL, + DEBUG_TRANSVR_STR_VAL }; + + for (i=0; i<4; i++) { + high = (i*2); + low = ((i*2) + 1); + count_func(data_array[high], data_array[low], ch_buf[i]); + } + return snprintf(result_p, len_max, + "%s-%d:%s%s-%d:%s%s-%d:%s%s-%d:%s", + ch_name, 1, ch_buf[0], + ch_name, 2, ch_buf[1], + ch_name, 3, ch_buf[2], + ch_name, 4, ch_buf[3]); +} + + +int +qsfp_get_soft_rx_los(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int mask = 0x0f; /* Bit 0 ~ Bit 3 */ + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_qsfp_update_attr_soft_rx_los, + "qsfp_get_soft_rx_los"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + return snprintf(buf_p, lmax, "0x%02x\n", (self->rx_los & mask)); +} + + +int +qsfp_get_soft_tx_disable(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int mask = 0x0f; /* Bit 0 ~ Bit 3 */ + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_qsfp_update_attr_soft_tx_disable, + "qsfp_get_soft_tx_disable"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + return snprintf(buf_p, lmax, "0x%02x\n", (self->tx_disable & mask)); +} + + +int +qsfp_get_soft_tx_fault(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int mask = 0x0f; /* Bit 0 ~ Bit 3 */ + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_qsfp_update_attr_soft_tx_fault, + "qsfp_get_soft_tx_fault"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + return snprintf(buf_p, lmax, "0x%02x\n", (self->tx_fault & mask)); +} + + +int +qsfp_get_auto_tx_disable(struct transvr_obj_s *self, + char *buf_p) { + + if (self->auto_tx_disable == VAL_TRANSVR_FUNCTION_DISABLE) { + return snprintf(buf_p, LEN_TRANSVR_S_STR, + "%d\n", ERR_TRANSVR_FUNC_DISABLE); + } + return snprintf(buf_p, LEN_TRANSVR_S_STR, + "0x%02x\n", self->auto_tx_disable); +} + + +int +qsfp_get_transvr_tx_bias(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + char *ch_name = "TX"; + + err_code = _check_by_mode(self, + &_qsfp_update_attr_curr_tx_bias, + "qsfp_get_transvr_tx_bias"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->curr_tx_bias[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + /* Return Unit: 1 mA */ + return _qsfp_get_channel_diag(self->curr_tx_bias, + _common_count_tx_bias, + ch_name, + buf_p); +} + + +int +qsfp_get_transvr_tx_power(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + char *ch_name = "TX"; + + err_code = _check_by_mode(self, + &_qsfp_update_attr_curr_tx_power, + "qsfp_get_transvr_tx_power"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->curr_tx_power[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + /* Return Unit: 1 mW */ + return _qsfp_get_channel_diag(self->curr_tx_power, + _common_count_tx_power, + ch_name, + buf_p); +} + + +int +qsfp_get_transvr_rx_power(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + char *ch_name = "RX"; + + err_code = _check_by_mode(self, + &_qsfp_update_attr_curr_rx_power, + "qsfp_get_transvr_rx_power"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->curr_tx_power[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + /* Return Unit: 1 mW */ + return _qsfp_get_channel_diag(self->curr_rx_power, + _common_count_rx_power, + ch_name, + buf_p); +} + + +int +qsfp_get_wavelength(struct transvr_obj_s *self, + char *buf_p) { + /* [Desc] Wavelength or Copper Cable Attenuation (SFF-8636) + * [Addr] 00h 186-187 + * [Note] + * For optical free side devices, this parameter identifies the nominal + * transmitter output wavelength at room temperature. This parameter is + * a 16-bit hex value with Byte 186 as high order byte and Byte 187 as + * low order byte. The laser wavelength is equal to the 16-bit integer value + * divided by 20 in nm (units of 0.05 nm). This resolution should be adequate + * to cover all relevant wavelengths yet provide enough resolution for all + * expected DWDM applications. For accurate representation of controlled + * wavelength applications, this value should represent the center of the + * guaranteed wavelength range. + * If the free side device is identified as copper cable these registers will + * be used to define the cable attenuation. An indication of 0 dB attenuation + * refers to the case where the attenuation is not known or is unavailable. + * Byte 186 (00-FFh) is the copper cable attenuation at 2.5 GHz in units of 1 dB. + * Byte 187 (00-FFh) is the copper cable attenuation at 5.0 GHz in units of 1 dB. + */ + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_common_update_attr_wavelength, + "common_get_wavelength"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->wavelength[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + /* unit: 1 um */ + return snprintf(buf_p, lmax, "%d\n", + _common_count_wavelength(self, + self->wavelength[0], + self->wavelength[1])); +} + + +/* Public Function for Setup Features + */ +static int +__sfp_set_soft_rs(struct transvr_obj_s *self, + int input_val, + int address, + int page, + int offset, + int bit_shift, + uint8_t *attr_p, + char *caller, + int show_err) { + + int retval = ERR_TRANSVR_UNEXCPT; + int err_code = ERR_TRANSVR_UNEXCPT; + char *err_msg = DEBUG_TRANSVR_STR_VAL; + uint8_t update_val = (*attr_p); + + switch (input_val) { + case 0: + SWP_BIT_CLEAR(update_val, bit_shift); + break; + case 1: + SWP_BIT_SET(update_val, bit_shift); + break; + default: + retval = ERR_TRANSVR_UNEXCPT; + err_code = ERR_TRANSVR_UNEXCPT; + err_msg = "Exception occurs"; + goto err_private_sfp_set_soft_rs_1; + } + err_code = _common_set_uint8_attr(self, + address, + page, + offset, + update_val, + attr_p, + caller, + show_err); + if (err_code < 0) { + retval = err_code; + err_msg = "Write data via i2c fail!"; + goto err_private_sfp_set_soft_rs_1; + } + (*attr_p) = update_val; + return 0; + +err_private_sfp_set_soft_rs_1: + if (show_err) { + SWPS_INFO("%s: %s :%d :%s\n :%d\n", + __func__, err_msg, err_code, self->swp_name, input_val); + } + return retval; +} + + +static int +_sfp_set_soft_rs(struct transvr_obj_s *self, + int input_val, + int address, + int page, + int offset, + int bit_shift, + int (*attr_update_func)(struct transvr_obj_s *self, int show_err), + uint8_t *attr_p, + char *caller, + int show_err) { + + int retval = ERR_TRANSVR_UNEXCPT; + int err_code = ERR_TRANSVR_UNEXCPT; + char *err_msg = DEBUG_TRANSVR_STR_VAL; + + /* Check input value */ + if ((input_val != 0) && (input_val != 1)){ + retval = ERR_TRANSVR_BADINPUT; + err_code = ERR_TRANSVR_BADINPUT; + err_msg = "Input range incorrect!"; + goto err_common_sfp_set_soft_rs_1; + } + /* Check rate identifier is supported */ + err_code = self->get_rate_id(self); + if (err_code <= 0) { + switch (err_code) { + case 0: + retval = ERR_TRANSVR_NOTSUPPORT; + err_msg = "Not support this feature"; + break; + case ERR_TRANSVR_UNINIT: + retval = ERR_TRANSVR_UNINIT; + err_msg = "Check CDR present fail!"; + break; + case ERR_TRANSVR_UNPLUGGED: + retval = ERR_TRANSVR_UNPLUGGED; + err_msg = "Transceiver unplugged!"; + break; + default: + retval = err_code; + err_msg = "Check Rate_ID fail!"; + break; + } + goto err_common_sfp_set_soft_rs_1; + } + /* Check and update */ + err_code = _check_by_mode(self, + attr_update_func, + caller); + if ( (err_code < 0) || + ((*attr_p) == DEBUG_TRANSVR_HEX_VAL) ){ + retval = err_code; + err_msg = "Get current value fail!"; + goto err_common_sfp_set_soft_rs_1; + } + /* Generate and update value */ + return __sfp_set_soft_rs(self, + input_val, + address, + page, + offset, + bit_shift, + attr_p, + caller, + show_err); + +err_common_sfp_set_soft_rs_1: + if (show_err) { + SWPS_INFO("%s: %s :%d :%s\n :%d\n", + __func__, err_msg, err_code, self->swp_name, input_val); + } + return retval; +} + + +int +sfp_set_soft_rs0(struct transvr_obj_s *self, + int input_val) { + /* Note: + * SFP Soft Rate_Select Select RX ["RS(0)"] address + * A2h, offset: 110, bit 3 + */ + int bit_shift = 3; + int show_err = 1; + return _sfp_set_soft_rs(self, + input_val, + self->eeprom_map_p->addr_soft_rs0, + self->eeprom_map_p->page_soft_rs0, + self->eeprom_map_p->offset_soft_rs0, + bit_shift, + &_sfp_update_attr_soft_rs0, + &(self->soft_rs0), + "sfp_set_soft_rs0", + show_err); +} + + +int +sfp_set_soft_rs1(struct transvr_obj_s *self, + int input_val) { + /* Note: + * SFP Soft Rate_Select Select RX ["RS(1)"] address + * A2h, offset: 118, bit 3 + */ + int bit_shift = 3; + int show_err = 1; + return _sfp_set_soft_rs(self, + input_val, + self->eeprom_map_p->addr_soft_rs1, + self->eeprom_map_p->page_soft_rs1, + self->eeprom_map_p->offset_soft_rs1, + bit_shift, + &_sfp_update_attr_soft_rs1, + &(self->soft_rs1), + "sfp_set_soft_rs1", + show_err); +} + + +int +__sfp_set_tx_eq(struct transvr_obj_s *self, + int input, + int show_e) { + + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + uint8_t setv = DEBUG_TRANSVR_HEX_VAL; + + if ((input < 0) || (input > 0xFF)) { + emsg = "input incorrect"; + err = ERR_TRANSVR_BADINPUT; + goto err_sfp_set_tx_eq; + } + setv = (uint8_t)input; + if (self->tx_eq[0] == setv) { + return 0; + } + err = _common_set_uint8_attr(self, + self->eeprom_map_p->addr_tx_eq, + self->eeprom_map_p->page_tx_eq, + self->eeprom_map_p->offset_tx_eq, + setv, + &(self->tx_eq[0]), + "_sfp_set_tx_eq", + show_e); + if (err < 0) { + emsg = "set_uint8_attr fail"; + goto err_sfp_set_tx_eq; + } + return 0; + +err_sfp_set_tx_eq: + if (show_e) { + SWPS_INFO("%s: %s :%d\n", __func__, emsg, input); + } + return err; +} + + +int +_sfp_set_tx_eq(struct transvr_obj_s *self, + int input, + int show_e) { + + uint8_t tmp; + int i = 0; + int retry = 3; + + for (i=0; itx_eq[0]; + if (_sfp_update_attr_tx_eq(self, show_e) < 0){ + continue; + } + if (self->tx_eq[0] == tmp){ + return 0; + } + } + return ERR_TRANSVR_UPDATE_FAIL; +} + + +int +sfp_set_tx_eq(struct transvr_obj_s *self, + int input) { + + int err = _check_by_mode(self, + &_sfp_update_attr_tx_eq, + "sfp_set_tx_eq"); + if (err < 0) { + SWPS_DEBUG("%s: check fail :%d\n", __func__, err); + return err; + } + return _sfp_set_tx_eq(self, input, 1); +} + + +int +__sfp_set_rx_em(struct transvr_obj_s *self, + int input, + int show_e) { + + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + uint8_t setv = DEBUG_TRANSVR_HEX_VAL; + + if ((input < 0) || (input > 0xFF)) { + emsg = "input incorrect"; + err = ERR_TRANSVR_BADINPUT; + goto err_sfp_set_rx_em; + } + setv = (uint8_t)input; + if (self->rx_em[0] == setv) { + return 0; + } + err = _common_set_uint8_attr(self, + self->eeprom_map_p->addr_rx_em, + self->eeprom_map_p->page_rx_em, + self->eeprom_map_p->offset_rx_em, + setv, + &(self->rx_em[0]), + "_sfp_set_rx_em", + show_e); + if (err < 0) { + emsg = "set_uint8_attr fail"; + goto err_sfp_set_rx_em; + } + return 0; + +err_sfp_set_rx_em: + if (show_e) { + SWPS_INFO("%s: %s :%d\n", __func__, emsg, input); + } + return err; +} + + +int +_sfp_set_rx_em(struct transvr_obj_s *self, + int input, + int show_e) { + + uint8_t tmp; + int i = 0; + int retry = 3; + + for (i=0; irx_em[0]; + if (_sfp_update_attr_rx_em(self, show_e) < 0){ + continue; + } + if (self->rx_em[0] == tmp){ + return 0; + } + } + return -1; +} + + +int +sfp_set_rx_em(struct transvr_obj_s *self, + int input) { + + int err = _check_by_mode(self, + &_sfp_update_attr_rx_em, + "sfp_set_rx_em"); + if (err < 0) { + SWPS_DEBUG("%s: check fail :%d\n", __func__, err); + return err; + } + return _sfp_set_rx_em(self, input, 1); +} + + +int +sfp_set_1g_rj45_extphy_offset(struct transvr_obj_s *self, + int input) { + + if (self->state != STATE_TRANSVR_CONNECTED) { + return ERR_TRANSVR_UNPLUGGED; + } + if ((self->info != TRANSVR_CLASS_BASE_T_1000) && + (self->info != TRANSVR_CLASS_BASE_T_1000_up) ){ + return ERR_TRANSVR_NOTSUPPORT; + } + if ((input < 0) || (input > 0xff)) { + return ERR_TRANSVR_BADINPUT; + } + self->extphy_offset = (uint8_t)input; + return 0; +} + + +int +sfp_set_1g_rj45_extphy_reg(struct transvr_obj_s *self, + int input) { + + int i = 0; + int retry = 3; + int delay = 200; + uint16_t tmp = 0; + + if (self->state != STATE_TRANSVR_CONNECTED) { + return ERR_TRANSVR_UNPLUGGED; + } + if ((self->info != TRANSVR_CLASS_BASE_T_1000) && + (self->info != TRANSVR_CLASS_BASE_T_1000_up) ){ + return ERR_TRANSVR_NOTSUPPORT; + } + if ((input < 0) || (input > 0xffff)) { + return ERR_TRANSVR_BADINPUT; + } + tmp = ((input & 0x00ff) << 8) | ((input & 0xff00) >> 8); + if (_common_setup_page(self, VAL_TRANSVR_EXTPHY_ADDR_56, + -1, self->extphy_offset, 1, 0) < 0) { + return -EIO; + } + for (i=0; i<=retry; i++) { + if (i2c_smbus_write_word_data(self->i2c_client_p, + self->extphy_offset, + tmp) >= 0) { + return 0; + } + msleep(delay); + } + SWPS_INFO("%s: retry:%d fail :%s :0x%02x\n", + __func__, retry, self->swp_name, self->extphy_offset); + return -EIO; +} + + +static int +__qsfp_set_cdr(struct transvr_obj_s *self, + int input_val, + int show_err) { + + uint8_t update_val; + int CDR_FEATURE_SUPPORTED = 0x3; + int retval = ERR_TRANSVR_UNEXCPT; + int err_code = ERR_TRANSVR_UNEXCPT; + char *err_msg = DEBUG_TRANSVR_STR_VAL; + char *func_name = "__qsfp_set_cdr"; + + /* Check input value */ + if ((input_val < 0) || (input_val > 0xff)){ + retval = ERR_TRANSVR_BADINPUT; + err_code = ERR_TRANSVR_BADINPUT; + err_msg = "Input range incorrect!"; + goto err_qsfp_set_cdr_1; + } + update_val = (uint8_t)input_val; + /* Check CDR supported by transceiver */ + err_code = qsfp_get_cdr_present(self); + if (err_code < 0) { + retval = err_code; + switch (err_code) { + case ERR_TRANSVR_UNINIT: + err_msg = "Check CDR present fail!"; + break; + case ERR_TRANSVR_UNPLUGGED: + err_msg = "Transceiver unplugged!"; + break; + default: + err_msg = "Check CDR present fail!"; + break; + } + goto err_qsfp_set_cdr_1; + } + if (err_code != CDR_FEATURE_SUPPORTED) { + retval = ERR_TRANSVR_NOTSUPPORT; + err_msg = "This transceiver not support CDR!"; + goto err_qsfp_set_cdr_1; + } + /* Check and update */ + err_code = _check_by_mode(self, + &_qsfp_update_attr_cdr, + func_name); + if ( (err_code < 0) || + (self->cdr == DEBUG_TRANSVR_HEX_VAL) ){ + retval = err_code; + err_msg = "Get current value fail!"; + goto err_qsfp_set_cdr_1; + } + /* Write input value to transceiver */ + return _common_set_uint8_attr(self, + self->eeprom_map_p->addr_cdr, + self->eeprom_map_p->page_cdr, + self->eeprom_map_p->offset_cdr, + update_val, + &(self->cdr), + func_name, + show_err); + +err_qsfp_set_cdr_1: + if (show_err) { + SWPS_INFO("%s: %s :%d :%s\n :%d\n", + __func__, err_msg, err_code, self->swp_name, input_val); + } + return retval; +} + + +int +qsfp_set_cdr(struct transvr_obj_s *self, + int input_val) { + return __qsfp_set_cdr(self, input_val, 1); +} + + +int +qsfp_set_soft_tx_disable(struct transvr_obj_s *self, + int input_val) { + + int show_err = 1; + int in_max = 0xf; /* 1111 */ + int in_min = 0x0; /* 0000 */ + int retval = DEBUG_TRANSVR_INT_VAL; + int update_val = DEBUG_TRANSVR_INT_VAL; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + retval = _check_by_mode(self, + &_qsfp_update_attr_soft_tx_disable, + "qsfp_set_soft_tx_disable"); + if (retval < 0) { + snprintf(err_msg, 63, "Not ready. err:%d", retval); + goto err_qsfp_set_soft_tx_disable; + } + if ((input_val > in_max) || + (input_val < in_min) ){ + retval = ERR_TRANSVR_BADINPUT; + snprintf(err_msg, 63, "Input value:%d incorrect!", input_val); + goto err_qsfp_set_soft_tx_disable; + } + if ((self->tx_disable & 0x0f) == input_val) { + return 0; + } + update_val = ((self->tx_disable & 0xf0) & input_val); + retval = _common_set_uint8_attr(self, + self->eeprom_map_p->addr_tx_disable, + self->eeprom_map_p->page_tx_disable, + self->eeprom_map_p->offset_tx_disable, + input_val, + &(self->tx_disable), + "qsfp_set_tx_disable", + show_err); + if (retval < 0) { + snprintf(err_msg, 63, "_common_set_uint8_attr:%d fail!", retval); + goto err_qsfp_set_soft_tx_disable; + } + return 0; + +err_qsfp_set_soft_tx_disable: + SWPS_INFO("%s: %s :%s\n", __func__, err_msg, self->swp_name); + return retval; +} + + +int +_qsfp_set_auto_tx_disable(struct transvr_obj_s *self, + uint8_t update) { + + uint8_t tx_enable = 0x0; + int show_e = 1; + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + + /* Handle timing issues */ + if (update != tx_enable) { + /* Note: + * Because there are some txvr has timing issues, + * therefore we need to execute reset cycle first. + * (enable -> other settings) + */ + err = _common_set_uint8_attr(self, + self->eeprom_map_p->addr_tx_disable, + self->eeprom_map_p->page_tx_disable, + self->eeprom_map_p->offset_tx_disable, + tx_enable, + &(self->tx_disable), + "_qsfp_set_auto_tx_disable", + show_e); + if (err < 0) { + emsg = "I2C set reset value fail"; + goto err_qsfp_set_auto_tx_disable; + } + mdelay(10); + } + /* Setup target value */ + err = _common_set_uint8_attr(self, + self->eeprom_map_p->addr_tx_disable, + self->eeprom_map_p->page_tx_disable, + self->eeprom_map_p->offset_tx_disable, + self->auto_tx_disable, + &(self->tx_disable), + "_qsfp_set_auto_tx_disable", + show_e); + if (err < 0) { + emsg = "I2C set target value fail"; + goto err_qsfp_set_auto_tx_disable; + } + /* Check and update */ + err = _common_update_uint8_attr(self, + self->eeprom_map_p->addr_tx_disable, + self->eeprom_map_p->page_tx_disable, + self->eeprom_map_p->offset_tx_disable, + self->eeprom_map_p->length_tx_disable, + &(self->tx_disable), + "_qsfp_set_auto_tx_disable", + show_e); + if (err < 0) { + emsg = "I2C get value fail"; + goto err_qsfp_set_auto_tx_disable; + } + if (self->tx_disable != update) { + emsg = "data not become effective"; + goto err_qsfp_set_auto_tx_disable; + } + return 0; + +err_qsfp_set_auto_tx_disable: + SWPS_DEBUG("%s: %s :%s\n", + __func__, emsg, self->swp_name); + return ERR_TRANSVR_UPDATE_FAIL; +} + + +int +qsfp_set_auto_tx_disable(struct transvr_obj_s *self, + int input_val) { + + int in_max = 0xf; /* 1111 */ + int in_min = 0x0; /* 0000 */ + int retval = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + + /* Update settings*/ + if (input_val == VAL_TRANSVR_FUNCTION_DISABLE) { + emsg = "User disable auto tx_disable"; + self->auto_tx_disable = VAL_TRANSVR_FUNCTION_DISABLE; + goto out_qsfp_set_auto_tx_disable; + } + if ((input_val > in_max) || (input_val < in_min) ){ + SWPS_INFO("%s: Input value:%d incorrect! :%s\n", + __func__, input_val, self->swp_name); + return ERR_TRANSVR_BADINPUT; + } + self->auto_tx_disable = input_val; + /* Check current soft tx_disable */ + retval = _check_by_mode(self, + &_qsfp_update_attr_soft_tx_disable, + "qsfp_set_auto_tx_disable"); + switch (retval) { + case 0: + break; + case ERR_TRANSVR_UNPLUGGED: + emsg = "Doesn't need to update"; + goto out_qsfp_set_auto_tx_disable; + default: + SWPS_INFO("%s: setup fail :%d :%s\n", + __func__, retval, self->swp_name); + return retval; + } + return _qsfp_set_auto_tx_disable(self, input_val); + +out_qsfp_set_auto_tx_disable: + SWPS_DEBUG("%s: %s :%s :%d\n :%d", + __func__, emsg, self->swp_name, input_val, retval); + return 0; +} + + +int +__qsfp_set_tx_eq(struct transvr_obj_s *self, + int input, + int show_e) { + /* [Note] + * 0x + */ + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + uint8_t setv[2] = {0x00, 0x00}; + + if ((input < 0) || (input > 0xFFFF)) { + emsg = "input incorrect"; + err = ERR_TRANSVR_BADINPUT; + goto err_qsfp_set_tx_eq; + } + setv[0] = (uint8_t)((input & 0xFF00) >> 8); + setv[1] = (uint8_t)(input & 0xFF); + if ((self->tx_eq[0] == setv[0]) && + (self->tx_eq[1] == setv[1]) ) { + return 0; + } + err = _common_set_uint8_array(self, + self->eeprom_map_p->addr_tx_eq, + self->eeprom_map_p->page_tx_eq, + self->eeprom_map_p->offset_tx_eq, + self->eeprom_map_p->length_tx_eq, + setv, + self->tx_eq, + "_qsfp_set_tx_eq", + show_e); + if (err < 0) { + emsg = "set_uint8_array fail"; + goto err_qsfp_set_tx_eq; + } + return 0; + +err_qsfp_set_tx_eq: + if (show_e) { + SWPS_INFO("%s: %s :%d\n", __func__, emsg, input); + } + return err; +} + + +int +_qsfp_set_tx_eq(struct transvr_obj_s *self, + int input, + int show_e) { + + int i = 0; + int retry = 3; + uint8_t tmp[2]; + + for (i=0; itx_eq[0]; + tmp[1] = self->tx_eq[1]; + if (_qsfp_update_attr_tx_eq(self, show_e) < 0){ + continue; + } + if ((self->tx_eq[0] == tmp[0]) && + (self->tx_eq[1] == tmp[1]) ){ + return 0; + } + } + return -1; +} + + +int +qsfp_set_tx_eq(struct transvr_obj_s *self, + int input) { + + int err = _check_by_mode(self, + &_qsfp_update_attr_tx_eq, + "qsfp_set_tx_eq"); + if (err < 0) { + SWPS_DEBUG("%s: check fail :%d\n", __func__, err); + return err; + } + return _qsfp_set_tx_eq(self, input, 1); +} + + +int +__qsfp_set_rx_am(struct transvr_obj_s *self, + int input, + int show_e) { + /* [Note] + * 0x + */ + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + uint8_t setv[2] = {0x00, 0x00}; + + if ((input < 0) || (input > 0xFFFF)) { + emsg = "input incorrect"; + err = ERR_TRANSVR_BADINPUT; + goto err_qsfp_set_rx_am; + } + setv[0] = (uint8_t)((input & 0xFF00) >> 8); + setv[1] = (uint8_t)(input & 0xFF); + if ((self->rx_am[0] == setv[0]) && + (self->rx_am[1] == setv[1]) ) { + return 0; + } + err = _common_set_uint8_array(self, + self->eeprom_map_p->addr_rx_am, + self->eeprom_map_p->page_rx_am, + self->eeprom_map_p->offset_rx_am, + self->eeprom_map_p->length_rx_am, + setv, + self->rx_am, + "_qsfp_set_rx_am", + show_e); + if (err < 0) { + emsg = "set_uint8_array fail"; + goto err_qsfp_set_rx_am; + } + return 0; + +err_qsfp_set_rx_am: + if (show_e) { + SWPS_INFO("%s: %s :%d\n", __func__, emsg, input); + } + return err; +} + + +int +_qsfp_set_rx_am(struct transvr_obj_s *self, + int input, + int show_e) { + + int i = 0; + int retry = 3; + uint8_t tmp[2]; + + for (i=0; irx_am[0]; + tmp[1] = self->rx_am[1]; + if (_qsfp_update_attr_rx_am(self, show_e) < 0){ + continue; + } + if ((self->rx_am[0] == tmp[0]) && + (self->rx_am[1] == tmp[1]) ){ + return 0; + } + } + return -1; +} + + +int +qsfp_set_rx_am(struct transvr_obj_s *self, + int input) { + + int err = _check_by_mode(self, + &_qsfp_update_attr_rx_am, + "qsfp_set_rx_am"); + if (err < 0) { + SWPS_DEBUG("%s: check fail :%d\n", __func__, err); + return err; + } + return _qsfp_set_rx_am(self, input, 1); +} + + +int +__qsfp_set_rx_em(struct transvr_obj_s *self, + int input, + int show_e) { + /* [Note] + * 0x + */ + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + uint8_t setv[2] = {0x00, 0x00}; + + if ((input < 0) || (input > 0xFFFF)) { + emsg = "input incorrect"; + err = ERR_TRANSVR_BADINPUT; + goto err_qsfp_set_rx_em; + } + setv[0] = (uint8_t)((input & 0xFF00) >> 8); + setv[1] = (uint8_t)(input & 0xFF); + if ((self->rx_em[0] == setv[0]) && + (self->rx_em[1] == setv[1]) ) { + return 0; + } + err = _common_set_uint8_array(self, + self->eeprom_map_p->addr_rx_em, + self->eeprom_map_p->page_rx_em, + self->eeprom_map_p->offset_rx_em, + self->eeprom_map_p->length_rx_em, + setv, + self->rx_em, + "_qsfp_set_rx_em", + show_e); + if (err < 0) { + emsg = "set_uint8_array fail"; + goto err_qsfp_set_rx_em; + } + return 0; + +err_qsfp_set_rx_em: + if (show_e) { + SWPS_INFO("%s: %s :%d\n", __func__, emsg, input); + } + return err; +} + + +int +_qsfp_set_rx_em(struct transvr_obj_s *self, + int input, + int show_e) { + + int i = 0; + int retry = 3; + uint8_t tmp[2]; + + for (i=0; irx_em[0]; + tmp[1] = self->rx_em[1]; + if (_qsfp_update_attr_rx_em(self, show_e) < 0){ + continue; + } + if ((self->rx_em[0] == tmp[0]) && + (self->rx_em[1] == tmp[1]) ){ + return 0; + } + } + return -1; +} + + +int +qsfp_set_rx_em(struct transvr_obj_s *self, + int input) { + + int err = _check_by_mode(self, + &_qsfp_update_attr_rx_em, + "qsfp_set_rx_em"); + if (err < 0) { + SWPS_DEBUG("%s: check fail :%d\n", __func__, err); + return err; + } + return _qsfp_set_rx_em(self, input, 1); +} + + +int +common_transvr_dump(struct transvr_obj_s* self){ + + char *type_name = "Undefined"; + + if (TRANSVR_INFO_DUMP_ENABLE != 1) { + return 0; + } + switch (self->type) { + case TRANSVR_TYPE_SFP: + type_name = STR_TRANSVR_SFP; + break; + case TRANSVR_TYPE_QSFP: + type_name = STR_TRANSVR_QSFP; + break; + case TRANSVR_TYPE_QSFP_PLUS: + type_name = STR_TRANSVR_QSFP_PLUS; + break; + case TRANSVR_TYPE_QSFP_28: + type_name = STR_TRANSVR_QSFP28; + break; + case TRANSVR_TYPE_FAKE: + type_name = "FAKE"; + goto ok_common_transvr_dump; + case TRANSVR_TYPE_UNPLUGGED: + type_name = "UNPLUGGED"; + goto err_common_transvr_dump; + case TRANSVR_TYPE_INCONSISTENT: + type_name = "INCONSISTENT"; + goto err_common_transvr_dump; + case TRANSVR_TYPE_ERROR: + type_name = "ERROR"; + goto err_common_transvr_dump; + + default: + type_name = "UNEXPECTED"; + goto err_common_transvr_dump; + } + printk(KERN_INFO "[SWPS] Dump %s information:\n", self->swp_name); + printk(KERN_INFO " |- :%s\n", type_name); + printk(KERN_INFO " |- :%s\n", self->vendor_name); + printk(KERN_INFO " |- :%s\n", self->vendor_pn); + printk(KERN_INFO " |- :%s\n", self->vendor_rev); + printk(KERN_INFO " |- :%s\n", self->vendor_sn); + printk(KERN_INFO " |- :0x%02x\n", self->br); + printk(KERN_INFO " |- :0x%02x\n", self->comp_rev); + printk(KERN_INFO " |- :%d\n", self->len_om1); + printk(KERN_INFO " |- :%d\n", self->len_om2); + printk(KERN_INFO " |- :%d\n", self->len_om3); + printk(KERN_INFO " |- :%d\n", self->len_om4); + return 0; + +ok_common_transvr_dump: + SWPS_INFO("%s: %s is %s\n", __func__, self->swp_name, type_name); + return 0; + +err_common_transvr_dump: + SWPS_INFO("%s: %s is %s\n", __func__, self->swp_name, type_name); + return -1; +} + + +int +sfp_transvr_dump(struct transvr_obj_s* self) { + + if (TRANSVR_INFO_DUMP_ENABLE != 1) { + return 0; + } + if (common_transvr_dump(self) < 0) { + return -1; + } + printk(KERN_INFO " |- :%d\n", self->len_sm); + printk(KERN_INFO " |- :%d\n", self->len_smf); + printk(KERN_INFO " '- :0x%02x\n", self->rate_id); + return 0; +} + + +int +qsfp_transvr_dump(struct transvr_obj_s* self) { + + if (TRANSVR_INFO_DUMP_ENABLE != 1) { + return 0; + } + if (common_transvr_dump(self) < 0) { + return -1; + } + printk(KERN_INFO " |- :%d\n", self->len_smf); + printk(KERN_INFO " '- :Class_%d\n", __qsfp_get_power_cls(self, 0)); + return 0; +} + + +int +fake_transvr_dump(struct transvr_obj_s* self) { + + printk(KERN_INFO "[SWPS] Dump transceiver information: %s\n", self->swp_name); + printk(KERN_INFO " |- :FAKE\n"); + printk(KERN_INFO " |- :FAKE_VENDER_NAME\n"); + printk(KERN_INFO " |- :FAKE_VENDER_PN\n"); + printk(KERN_INFO " |- :FAKE_VENDER_REV\n"); + printk(KERN_INFO " |- :FAKE_VENDER_SN\n"); + printk(KERN_INFO " |- :0x99\n"); + printk(KERN_INFO " |- :99\n"); + printk(KERN_INFO " |- :99\n"); + printk(KERN_INFO " |- :99\n"); + printk(KERN_INFO " |- :99\n"); + printk(KERN_INFO " |- :99\n"); + printk(KERN_INFO " |- :99\n"); + printk(KERN_INFO " '- :0x99\n"); + return 0; +} + + +/* ========== Object functions for fake type ========== + */ +int +fake_transvr_update(struct transvr_obj_s *self, + int show_err){ + self->state = STATE_TRANSVR_CONNECTED; + return 0; +} + + +int +fake_get_binary(struct transvr_obj_s *self){ + return 1; +} + +int +fake_get_int(struct transvr_obj_s *self){ + return 99; +} + + +int +fake_get_hex(struct transvr_obj_s *self){ + return 0x0f; +} + + +int +fake_get_str(struct transvr_obj_s *self, char *buf) { + return snprintf(buf, 16, "fake_get_str\n"); +} + + +int +fake_set_int(struct transvr_obj_s *self, int input){ + SWPS_INFO("%s: %d\n", __func__, input); + return 0; +} + + +int +fake_set_hex(struct transvr_obj_s *self, int input){ + SWPS_INFO("%s: 0x%02x\n", __func__, input); + return 0; +} + + +/* ========== Object functions for unsupported ========== + */ +int +unsupported_get_func(struct transvr_obj_s *self){ + return ERR_TRANSVR_NOTSUPPORT; +} + + +int +unsupported_get_func2(struct transvr_obj_s *self, + char *buf_p) { + int len = snprintf(buf_p, 8, "%d\n", ERR_TRANSVR_NOTSUPPORT); + return len; +} + + +int +unsupported_set_func(struct transvr_obj_s *self, + int input_val){ + return ERR_TRANSVR_NOTSUPPORT; +} + + + +/* ========== Object functions for long term task ========== + * + * [Note] + * SWPS transceiver worker is likely the green-thread (coroutine). + * Due to resource and performance considerations. SWPS run all + * features in one kthread at the same time, and handle by it self. + */ + +/* For Transceiver Task Handling + */ +static struct transvr_worker_s * +transvr_task_get(struct transvr_obj_s *self, + char *func_name) { + + struct transvr_worker_s *curr_p = self->worker_p; + + while(curr_p != NULL){ + if (strcmp((curr_p->func_name), func_name) == 0 ) { + return curr_p; + } + curr_p = curr_p->next_p; + } + return NULL; +} + + +static struct transvr_worker_s* +transvr_task_creat(struct transvr_obj_s *self, + int (*main_task)(struct transvr_worker_s *task), + int (*post_task)(struct transvr_worker_s *task), + char *caller) { + + struct transvr_worker_s *task_p = NULL; + struct transvr_worker_s *curr_p = NULL; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + /* Check task not exist */ + task_p = transvr_task_get(self, caller); + if (task_p) { + snprintf(err_msg, sizeof(err_msg), "Task already created!"); + goto err_transvr_task_creat; + } + /* Create task worker */ + task_p = kzalloc(sizeof(struct transvr_worker_s), GFP_KERNEL); + if (!task_p){ + snprintf(err_msg, sizeof(err_msg), "kzalloc fail"); + goto err_transvr_task_creat; + } + /* Setup task data */ + task_p->transvr_p = self; + task_p->next_p = NULL; + task_p->trigger_time = 0; + task_p->retry = 1; + task_p->state = STATE_T_TASK_INIT; + task_p->main_task = main_task; + task_p->post_task = post_task; + task_p->p_data = NULL; + snprintf(task_p->func_name, sizeof(task_p->func_name), "%s", caller); + /* Setup Link List */ + if (self->worker_p) { + curr_p = self->worker_p; + while(curr_p->next_p != NULL) { + curr_p = curr_p->next_p; + } + curr_p->next_p = task_p; + task_p->pre_p = curr_p; + } else { + self->worker_p = task_p; + task_p->pre_p = NULL; + } + return task_p; + +err_transvr_task_creat: + SWPS_ERR("%s: %s :%s :%s\n", + __func__, err_msg, caller, self->swp_name); + return NULL; +} + + +static void +transvr_task_free_one(struct transvr_worker_s *task_p){ + + struct transvr_worker_s *pre_p = NULL; + struct transvr_worker_s *next_p = NULL; + + if (task_p) { + pre_p = task_p->pre_p; + next_p = task_p->next_p; + + if ((pre_p) && (next_p)) { + pre_p->next_p = next_p; + next_p->pre_p = pre_p; + + } else if ((!pre_p) && (next_p)) { + next_p->pre_p = NULL; + + } else if ((pre_p) && (!next_p)) { + pre_p->next_p = NULL; + + } else if ((!pre_p) && (!next_p)) { + task_p->transvr_p->worker_p = NULL; + } else { + SWPS_ERR("%s: Unexcept case!\n :%s", + __func__, task_p->transvr_p->swp_name); + } + kfree(task_p->p_data); + kfree(task_p); + } +} + + +static void +transvr_task_free_all(struct transvr_obj_s *self) { + + struct transvr_worker_s *curr_p = NULL; + struct transvr_worker_s *next_p = NULL; + + if (self->worker_p) { + curr_p = self->worker_p; + while(curr_p) { + next_p = curr_p->next_p; + transvr_task_free_one(curr_p); + curr_p = next_p; + } + self->worker_p = NULL; + } +} + + +static void +transvr_cache_free_all(struct transvr_obj_s *self) { + + memset(self->vendor_name, 0, (LEN_TRANSVR_M_STR * sizeof(char)) ); + memset(self->vendor_rev, 0, (LEN_TRANSVR_M_STR * sizeof(char)) ); + memset(self->vendor_pn, 0, (LEN_TRANSVR_M_STR * sizeof(char)) ); + memset(self->vendor_sn, 0, (LEN_TRANSVR_M_STR * sizeof(char)) ); + self->extphy_offset = 0; +} + +static int +_transvr_task_run_main(struct transvr_worker_s *task_p) { + + int retval = DEBUG_TRANSVR_INT_VAL; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + if (!task_p){ + snprintf(err_msg, sizeof(err_msg), "main_task is NULL!"); + goto main_transvr_task_err; + } + if ((task_p->trigger_time) == 0){ + goto main_transvr_task_run; + } + if (time_before(jiffies, task_p->trigger_time)){ + goto main_transvr_task_wait; + } + goto main_transvr_task_run; + +main_transvr_task_run: + if (task_p->retry != VAL_TRANSVR_TASK_RETRY_FOREVER) { + task_p->retry -= 1; + } + retval = task_p->main_task(task_p); + if (retval < 0) { + if (task_p->retry > 0) { + task_p->state = STATE_T_TASK_WAIT; + return EVENT_TRANSVR_TASK_WAIT; + } + snprintf(err_msg, sizeof(err_msg), "Run main_task fail!"); + goto main_transvr_task_err; + } + goto main_transvr_task_identify; + +main_transvr_task_identify: + switch (retval) { + case EVENT_TRANSVR_TASK_WAIT: + task_p->state = STATE_T_TASK_WAIT; + return EVENT_TRANSVR_TASK_WAIT; + + case EVENT_TRANSVR_TASK_DONE: + task_p->state = STATE_T_TASK_DONE; + return EVENT_TRANSVR_TASK_DONE; + + default: + break; + } + snprintf(err_msg, sizeof(err_msg), "Run main_task fail!"); + goto main_transvr_task_err; + +main_transvr_task_wait: + task_p->state = STATE_T_TASK_WAIT; + return EVENT_TRANSVR_TASK_WAIT; + +main_transvr_task_err: + task_p->state = STATE_T_TASK_FAIL; + SWPS_INFO("%s: %s :%d :%s\n", + __func__, err_msg, retval, task_p->transvr_p->swp_name); + return EVENT_TRANSVR_INIT_FAIL; +} + + +static int +_transvr_task_run_post(struct transvr_worker_s *task_p) { + + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + if ((task_p->post_task) == NULL) { + return EVENT_TRANSVR_TASK_DONE; + } + switch (task_p->state) { + case STATE_T_TASK_WAIT: + case STATE_T_TASK_INIT: + goto post_transvr_task_wait; + + case STATE_T_TASK_DONE: + case STATE_T_TASK_FAIL: + goto post_transvr_task_run; + + default: + break; + } + snprintf(err_msg, sizeof(err_msg), "Unexcept task state"); + goto post_transvr_task_err; + +post_transvr_task_run: + task_p->post_task(task_p); + return EVENT_TRANSVR_TASK_DONE; + +post_transvr_task_wait: + return EVENT_TRANSVR_TASK_WAIT; + +post_transvr_task_err: + SWPS_INFO("%s: %s :%d :%s\n", + __func__, err_msg, task_p->state, task_p->transvr_p->swp_name); + return EVENT_TRANSVR_TASK_FAIL; +} + + +static int +transvr_task_run_one(struct transvr_worker_s *task_p) { + + int retval_main = DEBUG_TRANSVR_INT_VAL; + int retval_post = DEBUG_TRANSVR_INT_VAL; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + retval_main = _transvr_task_run_main(task_p); + if (retval_main < 0) { + snprintf(err_msg, sizeof(err_msg), "Execute main_task fail!"); + goto err_transvr_task_run_one; + } + retval_post = _transvr_task_run_post(task_p); + if (retval_post < 0) { + snprintf(err_msg, sizeof(err_msg), "Execute post_task fail!"); + goto err_transvr_task_run_one; + } + return retval_main; + +err_transvr_task_run_one: + SWPS_INFO("%s: %s
:%d :%d :%s :%s\n", + __func__, err_msg, retval_main, retval_post, + task_p->func_name, task_p->transvr_p->swp_name); + return EVENT_TRANSVR_TASK_FAIL; +} + + +static int +transvr_task_run_all(struct transvr_obj_s *self) { + + int haserr = 0; + int retval = DEBUG_TRANSVR_INT_VAL; + struct transvr_worker_s *curr_p = NULL; + struct transvr_worker_s *next_p = NULL; + + if ((self->worker_p) == NULL) { + return EVENT_TRANSVR_TASK_DONE; + } + curr_p = self->worker_p; + while (curr_p != NULL) { + next_p = curr_p->next_p; + retval = transvr_task_run_one(curr_p); + if (curr_p->retry == VAL_TRANSVR_TASK_RETRY_FOREVER) { + curr_p = next_p; + continue; + } + switch (retval) { + case EVENT_TRANSVR_TASK_WAIT: + break; + case EVENT_TRANSVR_TASK_DONE: + transvr_task_free_one(curr_p); + break; + case EVENT_TRANSVR_TASK_FAIL: + + default: + haserr = 1; + transvr_task_free_one(curr_p); + break; + } + curr_p = next_p; + } + if (haserr) { + return EVENT_TRANSVR_TASK_FAIL; + } + return EVENT_TRANSVR_TASK_DONE; +} + + +static void +transvr_task_set_delay(struct transvr_worker_s *task_p, + unsigned long delay_msec) { + + task_p->trigger_time = (jiffies + (delay_msec * (HZ/1000))); +} + + +static void +transvr_task_set_retry(struct transvr_worker_s *task_p, + unsigned long retry_times) { + + task_p->retry = retry_times; +} + + +/* For Transceiver Post Task + */ +int +taskfunc_post_do_nothing(struct transvr_worker_s *task_p) { + + return EVENT_TRANSVR_TASK_DONE; +} + + +int +taskfunc_post_handle_task_state(struct transvr_worker_s *task_p) { + + struct transvr_obj_s* tp = task_p->transvr_p; + + switch (task_p->state) { + case STATE_T_TASK_INIT: + case STATE_T_TASK_WAIT: + return EVENT_TRANSVR_TASK_WAIT; + + case STATE_T_TASK_DONE: + tp->state = STATE_TRANSVR_CONNECTED; + tp->send_uevent(tp, KOBJ_ADD); + return EVENT_TRANSVR_TASK_DONE; + + case STATE_T_TASK_FAIL: + tp->state = STATE_TRANSVR_UNEXCEPTED; + return EVENT_TRANSVR_TASK_FAIL; + + default: + break; + } + return EVENT_TRANSVR_TASK_FAIL; +} + + +/* For Transceiver Main Task + */ +int +_taskfunc_sfp_setup_soft_rs(struct transvr_worker_s *task_p, + int input_val, + int address, + int page, + int offset, + int bit_shift, + uint8_t *attr_p, + char *caller) { + + int show_err = 0; + int err_code = DEBUG_TRANSVR_INT_VAL; + char *err_str = DEBUG_TRANSVR_STR_VAL; + char *func_str = "_taskfunc_sfp_setup_soft_rs"; + + err_code = _sfp_update_attr_soft_rs0(task_p->transvr_p, 0); + if (err_code < 0) { + err_str = "Get current soft_rs0 fail!"; + goto err_taskfunc_sfp_setup_soft_rs_1; + } + err_code = __sfp_set_soft_rs(task_p->transvr_p, + input_val, + address, + page, + offset, + bit_shift, + attr_p, + caller, + show_err); + if (err_code < 0) { + err_str = "Get current soft_rs0 fail!"; + goto err_taskfunc_sfp_setup_soft_rs_1; + } + return EVENT_TRANSVR_TASK_DONE; + +err_taskfunc_sfp_setup_soft_rs_1: + if ((task_p->retry) == 0) { + SWPS_INFO("%s: %s :%s :%d :%d\n", + func_str, err_str, task_p->transvr_p->swp_name, input_val, err_code); + } + return EVENT_TRANSVR_TASK_FAIL; +} + + +int +__taskfunc_sfp_setup_hard_rs(struct transvr_worker_s *task_p, + int input_val, + int (*get_func)(struct ioexp_obj_s *self, int virt_offset), + int (*set_func)(struct ioexp_obj_s *self, int virt_offset, int input_val)) { + + int err_val = EVENT_TRANSVR_EXCEP_EXCEP; + char *err_str = DEBUG_TRANSVR_STR_VAL; + + err_val = get_func(task_p->transvr_p->ioexp_obj_p, + task_p->transvr_p->ioexp_virt_offset); + + if (err_val < 0) { + if (err_val == ERR_IOEXP_NOTSUPPORT) { + return EVENT_TRANSVR_TASK_DONE; + } + err_str = "Get current hard_rs fail!"; + goto err_p_taskfunc_sfp_setup_hard_rs_1; + } + if (err_val == input_val) { + return EVENT_TRANSVR_TASK_DONE; + } + err_val = set_func(task_p->transvr_p->ioexp_obj_p, + task_p->transvr_p->ioexp_virt_offset, + input_val); + if (err_val < 0) { + err_str = "Setup hard_rs fail!"; + goto err_p_taskfunc_sfp_setup_hard_rs_1; + } + return EVENT_TRANSVR_TASK_DONE; + +err_p_taskfunc_sfp_setup_hard_rs_1: + if ((task_p->retry) == 0) { + SWPS_INFO("%s: %s :%s :%d :%d\n", + __func__, err_str, task_p->transvr_p->swp_name, input_val, err_val); + } + return EVENT_TRANSVR_TASK_FAIL; +} + + +int +_taskfunc_sfp_setup_hard_rs0(struct transvr_worker_s *task_p, + int input_val) { + + return __taskfunc_sfp_setup_hard_rs(task_p, + input_val, + task_p->transvr_p->ioexp_obj_p->get_hard_rs0, + task_p->transvr_p->ioexp_obj_p->set_hard_rs0); +} + + +int +_taskfunc_sfp_setup_hard_rs1(struct transvr_worker_s *task_p, + int input_val) { + + return __taskfunc_sfp_setup_hard_rs(task_p, + input_val, + task_p->transvr_p->ioexp_obj_p->get_hard_rs1, + task_p->transvr_p->ioexp_obj_p->set_hard_rs1); +} + + +int +_taskfunc_sfp_setup_rs0(struct transvr_worker_s *task_p, + int input_val) { + + int bit_shift = 3; + int old_val = DEBUG_TRANSVR_INT_VAL; + int err_val = EVENT_TRANSVR_EXCEP_EXCEP; + char *err_str = DEBUG_TRANSVR_STR_VAL; + char *func_str = "_taskfunc_sfp_setup_rs0"; + + err_val = _taskfunc_sfp_setup_hard_rs0(task_p, + input_val); + if (err_val < 0) { + err_str = "Setup hard_rs0 fail!"; + goto err_private_taskfunc_sfp_setup_rs0_1; + } + old_val = err_val; + err_val = _taskfunc_sfp_setup_soft_rs(task_p, + input_val, + task_p->transvr_p->eeprom_map_p->addr_soft_rs0, + task_p->transvr_p->eeprom_map_p->page_soft_rs0, + task_p->transvr_p->eeprom_map_p->offset_soft_rs0, + bit_shift, + &(task_p->transvr_p->soft_rs0), + func_str); + if (err_val < 0) { + err_str = "Setup soft_rs0 fail!"; + goto err_private_taskfunc_sfp_setup_rs0_1; + } + return EVENT_TRANSVR_TASK_DONE; + +err_private_taskfunc_sfp_setup_rs0_1: + if ((task_p->retry) == 0) { + SWPS_INFO("%s: %s :%s :%d :%d\n", + func_str, err_str, task_p->transvr_p->swp_name, input_val, err_val); + } + _taskfunc_sfp_setup_hard_rs0(task_p, old_val); + return EVENT_TRANSVR_TASK_FAIL; +} + + +int +_taskfunc_sfp_setup_rs1(struct transvr_worker_s *task_p, + int input_val) { + + int bit_shift = 3; + int old_val = DEBUG_TRANSVR_INT_VAL; + int err_val = EVENT_TRANSVR_EXCEP_EXCEP; + char *err_str = DEBUG_TRANSVR_STR_VAL; + char *func_str = "_taskfunc_sfp_setup_rs1"; + + err_val = _taskfunc_sfp_setup_hard_rs1(task_p, + input_val); + if (err_val < 0) { + err_str = "Setup hard_rs1 fail!"; + goto err_private_taskfunc_sfp_setup_rs1_1; + } + old_val = err_val; + err_val = _taskfunc_sfp_setup_soft_rs(task_p, + input_val, + task_p->transvr_p->eeprom_map_p->addr_soft_rs1, + task_p->transvr_p->eeprom_map_p->page_soft_rs1, + task_p->transvr_p->eeprom_map_p->offset_soft_rs1, + bit_shift, + &(task_p->transvr_p->soft_rs1), + func_str); + if (err_val < 0) { + err_str = "Setup soft_rs1 fail!"; + goto err_private_taskfunc_sfp_setup_rs1_1; + } + return EVENT_TRANSVR_TASK_DONE; + +err_private_taskfunc_sfp_setup_rs1_1: + if ((task_p->retry) == 0) { + SWPS_INFO("%s: %s :%s :%d :%d\n", + func_str, err_str, task_p->transvr_p->swp_name, input_val, err_val); + } + _taskfunc_sfp_setup_hard_rs1(task_p, old_val); + return EVENT_TRANSVR_TASK_FAIL; +} + + +int +taskfunc_sfp_setup_SFF8431_case1(struct transvr_worker_s *task_p) { + /* SFF-8431 (8/4/2G Rx Rate_Select only) */ + int update_val = 1; + + return _taskfunc_sfp_setup_rs0(task_p, update_val); +} + + + +int +taskfunc_sfp_setup_SFF8431_case2(struct transvr_worker_s *task_p) { + /* SFF-8431 (8/4/2G Tx Rate_Select only) */ + int update_val = 1; + + return _taskfunc_sfp_setup_rs1(task_p, update_val); +} + + +int +taskfunc_sfp_setup_SFF8431_case3(struct transvr_worker_s *task_p) { + /* SFF-8431 (8/4/2G Independent Rx & Tx Rate_select) */ + int update_rs0 = 1; + int update_rs1 = 1; + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _taskfunc_sfp_setup_rs0(task_p, update_rs0); + if (err_code < 0) { + return err_code; + } + return _taskfunc_sfp_setup_rs1(task_p, update_rs1); +} + + +int +taskfunc_sfp_handle_1g_rj45(struct transvr_worker_s *task_p) { + + /* Not all of platform support 0x56 for transceiver + * external PHY, Support list as below: + * => 1. Magnolia-PVT (PS: EVT & DVT not ready) + */ + int ext_phy_addr = 0x56; + int ext_phy_page = -1; + int ext_phy_offs = 0x11; + int ext_phy_len = 1; + int lstate_mask = 0x04; /* 00000100 */ + int show_err = 0; + int fail_retry = 5; + int fail_delay = 1000; /* msec */ + int err_code = DEBUG_TRANSVR_INT_VAL; + uint8_t detect_val = DEBUG_TRANSVR_HEX_VAL; + char err_str[64] = DEBUG_TRANSVR_STR_VAL; + int *tmp_p = NULL; + char *func_name = "taskfunc_sfp_handle_1g_rj45"; + + if (task_p->transvr_p->state != STATE_TRANSVR_CONNECTED) { + return EVENT_TRANSVR_TASK_DONE; + } + if ( (task_p->transvr_p->info != TRANSVR_CLASS_BASE_T_1000) && + (task_p->transvr_p->info != TRANSVR_CLASS_BASE_T_1000_up) ) { + goto err_taskfunc_sfp_handle_1g_rj45_1; + } + err_code = _common_update_uint8_attr(task_p->transvr_p, + ext_phy_addr, + ext_phy_page, + ext_phy_offs, + ext_phy_len, + &detect_val, + func_name, + show_err); + if ( (err_code < 0) || + (detect_val == DEBUG_TRANSVR_HEX_VAL) ) { + snprintf(err_str, sizeof(err_str), "Detect external link status fail"); + goto err_taskfunc_sfp_handle_1g_rj45_2; + } + if ((detect_val & lstate_mask) == lstate_mask) { + goto ok_taskfunc_sfp_handle_1g_rj45_link_up; + } + goto ok_taskfunc_sfp_handle_1g_rj45_link_down; + +ok_taskfunc_sfp_handle_1g_rj45_link_up: + /* Filter out noise */ + if (!(task_p->p_data)) { + tmp_p = kzalloc(sizeof(int), GFP_KERNEL); + if (!tmp_p) { + snprintf(err_str, sizeof(err_str), "kzalloc p_data fail"); + goto err_taskfunc_sfp_handle_1g_rj45_2; + } + *tmp_p = TRANSVR_CLASS_BASE_T_1000_up; + task_p->p_data = tmp_p; + goto ok_taskfunc_sfp_handle_1g_rj45_done; + } + if ((*(int *)(task_p->p_data)) != TRANSVR_CLASS_BASE_T_1000_up) { + kfree(task_p->p_data); + task_p->p_data = NULL; + snprintf(err_str, sizeof(err_str), "Internal error"); + goto err_taskfunc_sfp_handle_1g_rj45_2; + } + task_p->transvr_p->info = TRANSVR_CLASS_BASE_T_1000_up; + kfree(task_p->p_data); + task_p->p_data = NULL; + goto ok_taskfunc_sfp_handle_1g_rj45_done; + +ok_taskfunc_sfp_handle_1g_rj45_link_down: + if (task_p->p_data) { + kfree(task_p->p_data); + task_p->p_data = NULL; + } + task_p->transvr_p->info = TRANSVR_CLASS_BASE_T_1000; + goto ok_taskfunc_sfp_handle_1g_rj45_done; + +ok_taskfunc_sfp_handle_1g_rj45_done: + if (task_p->retry != VAL_TRANSVR_TASK_RETRY_FOREVER) { + transvr_task_set_retry(task_p, VAL_TRANSVR_TASK_RETRY_FOREVER); + } + return EVENT_TRANSVR_TASK_DONE; + +err_taskfunc_sfp_handle_1g_rj45_1: + snprintf(err_str, sizeof(err_str), "Detect transceiver:%d not Base-T, remove task.", + task_p->transvr_p->info); + SWPS_INFO("%s: %s :%s\n", __func__, err_str, task_p->transvr_p->swp_name); + transvr_task_set_retry(task_p, 0); + return EVENT_TRANSVR_TASK_DONE; + +err_taskfunc_sfp_handle_1g_rj45_2: + if (task_p->retry == VAL_TRANSVR_TASK_RETRY_FOREVER) { + transvr_task_set_retry(task_p, fail_retry); + } + if ((task_p->retry) == 0) { + /* Error case: + * => In this case, SWPS will stop external Link state monitor features + * and keeps transvr_p->info on TRANSVR_CLASS_BASE_T_1000_up. + * Upper layer will see it always Linkup that because of these type of + * transceiver has external phy, switch chip see it as Loopback transceiver. + */ + SWPS_WARN("%s can not access external PHY of Base-T SFP transceiver\n", + task_p->transvr_p->swp_name); + task_p->transvr_p->info = TRANSVR_CLASS_BASE_T_1000_up; + return EVENT_TRANSVR_TASK_DONE; + } else { + transvr_task_set_delay(task_p, fail_delay); + } + return EVENT_TRANSVR_TASK_FAIL; +} + + +int +_taskfunc_qsfp_setup_power_mod(struct transvr_obj_s *self, + int setup_val) { + + int curr_val = DEBUG_TRANSVR_INT_VAL; + int err_val = DEBUG_TRANSVR_INT_VAL; + char *err_msg = DEBUG_TRANSVR_STR_VAL; + if (io_no_init) { + + SWPS_INFO("%s no_io_init\n",__func__); + return EVENT_TRANSVR_TASK_DONE; + } + + curr_val = self->ioexp_obj_p->get_lpmod(self->ioexp_obj_p, + self->ioexp_virt_offset); + if (curr_val < 0){ + err_msg = "Get current value fail!"; + goto err_private_taskfunc_qsfp_setup_power_mod_1; + } + if (curr_val == setup_val){ + return EVENT_TRANSVR_TASK_DONE; + } + err_val = self->ioexp_obj_p->set_lpmod(self->ioexp_obj_p, + self->ioexp_virt_offset, + setup_val); + if (err_val < 0){ + err_msg = "Setup power mode fail!"; + goto err_private_taskfunc_qsfp_setup_power_mod_1; + } + return EVENT_TRANSVR_TASK_DONE; + +err_private_taskfunc_qsfp_setup_power_mod_1: + SWPS_INFO("%s: %s :%d :%d :%d\n", + __func__, err_msg, err_val, curr_val, setup_val); + return EVENT_TRANSVR_TASK_FAIL; +} + + +int +taskfunc_qsfp_handle_tx_disable(struct transvr_worker_s *task_p) { + + int i = 0; + int retry = 5; + int delay_ms = 100; + + if (task_p->transvr_p->auto_tx_disable == VAL_TRANSVR_FUNCTION_DISABLE) { + return EVENT_TRANSVR_TASK_DONE; + } + if (!_qsfp_is_implement_tx_disable(task_p->transvr_p)) { + return EVENT_TRANSVR_TASK_DONE; + } + for (i=0; itransvr_p, + task_p->transvr_p->auto_tx_disable) + == EVENT_TRANSVR_TASK_DONE) { + goto ok_taskfunc_qsfp_handle_tx_disable; + } + mdelay(delay_ms); + } + SWPS_INFO("%s auto setup tx_disable:0x%02x fail.\n", + task_p->transvr_p->swp_name, + task_p->transvr_p->auto_tx_disable); + return EVENT_TRANSVR_INIT_FAIL; + +ok_taskfunc_qsfp_handle_tx_disable: + SWPS_INFO("%s auto setup tx_disable:0x%02x ok.\n", + task_p->transvr_p->swp_name, + task_p->transvr_p->auto_tx_disable); + return EVENT_TRANSVR_TASK_DONE; +} + + +int +taskfunc_qsfp_set_hpmod(struct transvr_worker_s *task_p) { + + int err = DEBUG_TRANSVR_INT_VAL; + int HIGH_POWER_MODE = 0; + + /* Handle power mode */ + err = _taskfunc_qsfp_setup_power_mod(task_p->transvr_p, + HIGH_POWER_MODE); + if (err < 0) { + SWPS_INFO("%s: setup hpmod fail :%d :%s\n", + __func__, err, task_p->transvr_p->swp_name); + return err; + } + /* Handle auto tx_disable + * [Note] + * => Because there are some transceiver have timing issues or + * setup sequence issues, therefore we handle auto tx_disable + * after handle power mode. + */ + mdelay(100); + return taskfunc_qsfp_handle_tx_disable(task_p); +} + + +int +taskfunc_qsfp_set_lpmod(struct transvr_worker_s *task_p) { + + int LOW_POWER_MODE = 1; + return _taskfunc_qsfp_setup_power_mod(task_p->transvr_p, + LOW_POWER_MODE); +} + + +static int +initfunc_sfp_handle_multi_rate_mode(struct transvr_obj_s *self) { + + int task_retry = 3; + int err_code = DEBUG_TRANSVR_INT_VAL; + char *err_str = DEBUG_TRANSVR_STR_VAL; + char *func_str = "sfp_handle_multi_rate_mode"; + struct transvr_worker_s *task_p = NULL; + + switch (self->rate_id) { + case 0x00: /* Unspecified */ + case 0x03: /* Unspecified */ + case 0x05: /* Unspecified */ + case 0x07: /* Unspecified */ + case 0x09: /* Unspecified */ + case 0x0B: /* Unspecified */ + case 0x0D: /* Unspecified */ + case 0x0F: /* Unspecified */ + goto sfp_handle_multi_rate_mode_4_unspecified; + + case 0x02: /* SFF-8431 (8/4/2G Rx Rate_Select only) */ + task_p = transvr_task_creat(self, + taskfunc_sfp_setup_SFF8431_case1, + taskfunc_post_handle_task_state, + func_str); + goto sfp_handle_multi_rate_mode_4_sff8431; + + case 0x04: /* SFF-8431 (8/4/2G Tx Rate_Select only) */ + task_p = transvr_task_creat(self, + taskfunc_sfp_setup_SFF8431_case2, + taskfunc_post_handle_task_state, + func_str); + goto sfp_handle_multi_rate_mode_4_sff8431; + + case 0x06: /* SFF-8431 (8/4/2G Independent Rx & Tx Rate_select) */ + task_p = transvr_task_creat(self, + taskfunc_sfp_setup_SFF8431_case3, + taskfunc_post_handle_task_state, + func_str); + goto sfp_handle_multi_rate_mode_4_sff8431; + + case 0x01: /* SFF-8079 (4/2/1G Rate_Select & AS0/AS1) */ + err_str = "SFF-8079 (4/2/1G Rate_Select & AS0/AS1)"; + goto sfp_handle_multi_rate_mode_4_not_support; + + case 0x08: /* FC-PI-5 (16/8/4G Rx Rate_select only) + * High=16G only, Low=8G/4G + */ + err_str = "FC-PI-5 (16/8/4G Rx Rate_select only)"; + goto sfp_handle_multi_rate_mode_4_not_support; + + case 0x0A: /* FC-PI-5 (16/8/4G Independent Rx, Tx Rate_select) + * High=16G only, Low=8G/4G + */ + err_str = "FC-PI-5 (16/8/4G Independent Rx, Tx Rate_select)"; + goto sfp_handle_multi_rate_mode_4_not_support; + + case 0x0C: /* FC-PI-6 (32/16/8G Independent Rx, Tx Rate_Select) + * High=32G only, Low = 16G/8G + */ + err_str = "FC-PI-6 (32/16/8G Independent Rx, Tx Rate_Select)"; + goto sfp_handle_multi_rate_mode_4_not_support; + + case 0x0E: /* 10/8G Rx and Tx Rate_Select controlling the operation or + * locking modes of the internal signal conditioner, retimer + * or CDR, according to the logic table defined in Table 10-2, + * High Bit Rate (10G) =9.95-11.3 Gb/s; Low Bit Rate (8G) = + * 8.5 Gb/s. In this mode, the default value of bit 110.3 (Soft + * Rate Select RS(0), Table 9-11) and of bit 118.3 (Soft Rate + * Select RS(1), Table 10-1) is 1. + */ + err_str = "cable type: 0x0E"; + goto sfp_handle_multi_rate_mode_4_not_support; + + default: + err_str = "cable type: UNKNOW"; + goto sfp_handle_multi_rate_mode_4_not_support; + } + +sfp_handle_multi_rate_mode_4_sff8431: + if (!task_p) { + err_str = "Create task fail!"; + goto sfp_handle_multi_rate_mode_4_fail_1; + } + transvr_task_set_retry(task_p, task_retry); + return EVENT_TRANSVR_TASK_WAIT; + +sfp_handle_multi_rate_mode_4_unspecified: + return EVENT_TRANSVR_TASK_DONE; + +sfp_handle_multi_rate_mode_4_not_support: + SWPS_INFO("%s: Does not support %s :%s :0x%02x\n", + func_str, err_str, self->swp_name, self->rate_id); + return EVENT_TRANSVR_TASK_DONE; + +sfp_handle_multi_rate_mode_4_fail_1: + SWPS_INFO("%s: %s :%s :0x%02x, :%d\n", + func_str, err_str, self->swp_name, self->rate_id, err_code); + return EVENT_TRANSVR_INIT_FAIL; +} + + +static int +initfunc_sfp_handle_1g_rj45(struct transvr_obj_s *self) { + + struct transvr_worker_s *task_p = NULL; + int detect_cls = DEBUG_TRANSVR_INT_VAL; + char err_str[64] = DEBUG_TRANSVR_STR_VAL; + char *func_str = "initfunc_sfp_handle_1g_rj45"; + + + if (self->info == TRANSVR_CLASS_BASE_T_1000) { + task_p = transvr_task_creat(self, + taskfunc_sfp_handle_1g_rj45, + taskfunc_post_do_nothing, + func_str); + if (!task_p) { + snprintf(err_str, sizeof(err_str), "Create task fail"); + goto err_initfunc_sfp_handle_1g_rj45; + } + transvr_task_set_retry(task_p, VAL_TRANSVR_TASK_RETRY_FOREVER); + } + return EVENT_TRANSVR_TASK_DONE; + +err_initfunc_sfp_handle_1g_rj45: + SWPS_INFO("%s: %s :%s :%d\n", + __func__, err_str, self->swp_name, detect_cls); + return EVENT_TRANSVR_TASK_FAIL; +} + + +static int +initfunc_qsfp_handle_power_mode(struct transvr_obj_s *self) { + + int err_code = EVENT_TRANSVR_EXCEP_INIT; + int power_class = DEBUG_TRANSVR_INT_VAL; + int hpmod_retry = 3; + int lpower_config = 1; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + unsigned long hpmod_delay = 500; /* msec */ + struct transvr_worker_s *task_p = NULL; + + /* Handle power mode for IOEXP */ + power_class = __qsfp_get_power_cls(self, 0); + switch (power_class) { + case 1: /* Case: Low power mode (Class = 1) */ + err_code = _taskfunc_qsfp_setup_power_mod(self, lpower_config); + if (err_code < 0){ + snprintf(err_msg, sizeof(err_msg), "Setup lpmod fail :%d", err_code); + goto err_initfunc_qsfp_handle_power_mode; + } + return EVENT_TRANSVR_TASK_DONE; + + case 2: /* Case: High power mode (Class > 1) */ + case 3: + case 4: + case 5: + case 6: + case 7: + task_p = transvr_task_creat(self, + taskfunc_qsfp_set_hpmod, + taskfunc_post_handle_task_state, + "transvr_init_qsfp"); + if (!task_p) { + snprintf(err_msg, sizeof(err_msg), "Setup lpmod fail :%d", err_code); + goto err_initfunc_qsfp_handle_power_mode; + } + transvr_task_set_retry(task_p, hpmod_retry); + transvr_task_set_delay(task_p, hpmod_delay); + return EVENT_TRANSVR_TASK_WAIT; + + default: + break; + } + snprintf(err_msg, sizeof(err_msg), "Exception case"); + goto err_initfunc_qsfp_handle_power_mode; + +err_initfunc_qsfp_handle_power_mode: + SWPS_INFO("%s: %s :%s \n", __func__, err_msg, self->swp_name); + return EVENT_TRANSVR_INIT_FAIL; +} + + +int +initfunc_qsfp28_handle_cdr(struct transvr_obj_s *self) { + + uint8_t DEFAULT_VAL_CDR = 0xff; + int CDR_FUNC_EXISTED = 0x3; + int show_err = 1; + int err_val = EVENT_TRANSVR_TASK_FAIL; + char *err_msg = DEBUG_TRANSVR_STR_VAL; + char *func_str = "initfunc_qsfp28_handle_cdr"; + + err_val = __qsfp_get_cdr_present(self, 0); + if ( (err_val < 0) || + (err_val == DEBUG_TRANSVR_HEX_VAL) ) { + err_msg = "detect cdr_present fail!"; + goto err_taskfunc_qsfp_handle_cdr_1; + } + if (err_val == CDR_FUNC_EXISTED) { + err_val = _common_set_uint8_attr(self, + self->eeprom_map_p->addr_cdr, + self->eeprom_map_p->addr_cdr, + self->eeprom_map_p->offset_cdr, + DEFAULT_VAL_CDR, + &(self->cdr), + func_str, + show_err); + if (err_val < 0) { + err_msg = "set CDR fail!"; + goto err_taskfunc_qsfp_handle_cdr_1; + } + } + return EVENT_TRANSVR_TASK_DONE; + +err_taskfunc_qsfp_handle_cdr_1: + SWPS_INFO("%s: %s :%d :%s\n", + func_str, err_msg, err_val, self->swp_name); + return EVENT_TRANSVR_INIT_FAIL; +} + +/* ========== Object functions for Final State Machine ========== + */ +int +is_plugged(struct transvr_obj_s *self){ + + int limit = 63; + int present = DEBUG_TRANSVR_INT_VAL; + char emsg[64] = DEBUG_TRANSVR_STR_VAL; + struct ioexp_obj_s *ioexp_p = self->ioexp_obj_p; + + if (!ioexp_p) { + snprintf(emsg, limit, "ioexp_p is null!"); + goto err_is_plugged_1; + } + present = ioexp_p->get_present(ioexp_p, self->ioexp_virt_offset); + switch (present){ + case 0: + return 1; + case 1: + return 0; + case ERR_IOEXP_UNINIT: + snprintf(emsg, limit, "ioexp_p not ready!"); + goto err_is_plugged_1; + default: + if (ioexp_p->state == STATE_IOEXP_INIT){ + snprintf(emsg, limit, "ioexp_p not ready!"); + goto err_is_plugged_1; + } + break; + } + SWPS_INFO("%s: Exception case! :%d :%d\n", + __func__, present, ioexp_p->state); + return 0; + +err_is_plugged_1: + SWPS_DEBUG("%s: %s\n", __func__, emsg); + return 0; +} + + +static int +detect_transvr_type(struct transvr_obj_s* self){ + + int type = TRANSVR_TYPE_ERROR; + + self->i2c_client_p->addr = VAL_TRANSVR_COMID_ARREESS; + type = i2c_smbus_read_byte_data(self->i2c_client_p, + VAL_TRANSVR_COMID_OFFSET); + + /* Case: 1. Wait transceiver I2C module. + * 2. Transceiver I2C module failure. + * Note: 1. SFF allow maximum transceiver initial time is 2 second. So, there + * are exist some case that we need to wait transceiver. + * For these case, we keeps status on "TRANSVR_TYPE_UNPLUGGED", than + * state machine will keep trace with it. + * 2. There exist some I2C failure case we need to handle. Such as user + * insert the failure transceiver, or any reason cause it abnormal. + */ + if (type < 0){ + switch (type) { + case -EIO: + SWPS_DEBUG("%s: %s smbus return:-5 (I/O error)\n", + __func__, self->swp_name); + return TRANSVR_TYPE_UNPLUGGED; + case -ENXIO: + SWPS_DEBUG("%s: %s smbus return:-6 (No such device or address)\n", + __func__, self->swp_name); + return TRANSVR_TYPE_UNPLUGGED; + default: + break; + } + SWPS_INFO("%s: %s unexpected smbus return:%d \n", + __func__, self->swp_name, type); + return TRANSVR_TYPE_ERROR; + } + /* Identify valid transceiver type */ + switch (type){ + case TRANSVR_TYPE_SFP: + case TRANSVR_TYPE_QSFP: + case TRANSVR_TYPE_QSFP_PLUS: + case TRANSVR_TYPE_QSFP_28: + break; + case TRANSVR_TYPE_UNKNOW_1: + case TRANSVR_TYPE_UNKNOW_2: + type = TRANSVR_TYPE_UNKNOW_2; + break; + default: + SWPS_DEBUG("%s: unknow type:0x%02x \n", __func__, type); + type = TRANSVR_TYPE_ERROR; + break; + } + return type; +} + + +static int +detect_transvr_state(struct transvr_obj_s *self, + int result[2]){ + /* [return] [result-0] [result-1] + * 0 STATE_TRANSVR_CONNECTED TRANSVR_TYPE_FAKE + * 0 STATE_TRANSVR_DISCONNECTED TRANSVR_TYPE_UNPLUGGED + * 0 STATE_TRANSVR_ISOLATED TRANSVR_TYPE_ERROR + * 0 STATE_TRANSVR_INIT / + * 0 STATE_TRANSVR_SWAPPED + * 0 STATE_TRANSVR_CONNECTED + * ERR_TRNASVR_BE_ISOLATED STATE_TRANSVR_ISOLATED TRANSVR_TYPE_ERROR + * ERR_TRANSVR_I2C_CRASH STATE_TRANSVR_UNEXCEPTED TRANSVR_TYPE_ERROR + * ERR_TRANSVR_UNEXCPT STATE_TRANSVR_UNEXCEPTED TRANSVR_TYPE_UNKNOW_1/2 + */ + result[0] = STATE_TRANSVR_UNEXCEPTED; /* For return state */ + result[1] = TRANSVR_TYPE_ERROR; /* For return type */ + + /* Case1: Fake type */ + if (self->type == TRANSVR_TYPE_FAKE){ + result[0] = STATE_TRANSVR_CONNECTED; + result[1] = TRANSVR_TYPE_FAKE; + return 0; + } + /* Case2: Transceiver unplugged */ + if (!is_plugged(self)){ + result[0] = STATE_TRANSVR_DISCONNECTED; + result[1] = TRANSVR_TYPE_UNPLUGGED; + return 0; + } + /* Case3: Transceiver be isolated */ + if (self->state == STATE_TRANSVR_ISOLATED){ + result[0] = STATE_TRANSVR_ISOLATED; + result[1] = TRANSVR_TYPE_ERROR; + return ERR_TRNASVR_BE_ISOLATED; + } + /* Case4: Transceiver plugged */ + result[1] = detect_transvr_type(self); + /* Case4.1: I2C topology crash + * Note : There are some I2C issues cause by transceiver/cables. + * We need to check topology status when user insert it. + * But in this step, we can't not ensure this is the issues + * port. So, it return the ERR_TRANSVR_I2C_CRASH, then upper + * layer will diagnostic I2C topology. + */ + if (check_channel_tier_1() < 0) { + SWPS_INFO("%s: %s detect I2C crash :%d\n", + __func__, self->swp_name, self->state); + result[0] = STATE_TRANSVR_UNEXCEPTED; + result[1] = TRANSVR_TYPE_ERROR; + return ERR_TRANSVR_I2C_CRASH; + } + /* Case4.2: System initial not ready, + * Note : Sometime i2c channel or transceiver EEPROM will delay that will + * cause system in inconsistent state between EEPROM and IOEXP. + * In this case, SWP transceiver object keep state at LINK_DOWN + * to wait system ready. + * By the way, State Machine will handle these case. + */ + if (result[1] == TRANSVR_TYPE_UNPLUGGED){ + result[0] = STATE_TRANSVR_DISCONNECTED; + return 0; + } + /* Case4.3: Error transceiver type */ + if (result[1] == TRANSVR_TYPE_ERROR){ + result[0] = STATE_TRANSVR_ISOLATED; + SWPS_INFO("%s: %s detect error type\n", __func__, self->swp_name); + alarm_msg_2_user(self, "detected transceiver/cables not meet SFF standard!"); + return ERR_TRNASVR_BE_ISOLATED; + } + /* Case3.3: Unknow transceiver type */ + if ((result[1] == TRANSVR_TYPE_UNKNOW_1) || + (result[1] == TRANSVR_TYPE_UNKNOW_2) ){ + result[0] = STATE_TRANSVR_UNEXCEPTED; + return ERR_TRANSVR_UNEXCPT; + } + /* Case3.4: During initial process */ + if (self->state == STATE_TRANSVR_INIT){ + result[0] = STATE_TRANSVR_INIT; + return 0; + } + /* Case3.5: Transceiver be swapped */ + if (self->type != result[1]){ + result[0] = STATE_TRANSVR_SWAPPED; + return 0; + } + /* Case3.6: Link up state */ + result[0] = STATE_TRANSVR_CONNECTED; + return 0; +} + + +int +_sfp_detect_class_by_extend_comp(struct transvr_obj_s* self) { + /* Reference: SFF-8024 (v3.8) + */ + int detect_val = _sfp_get_comp_extended(self); + + switch(detect_val) { + case 0x00: /* Unspecified */ + return TRANSVR_CLASS_UNSPECIFIED; + + case 0x01: /* 100G AOC (Active Optical Cable) or 25GAUI C2M */ + case 0x18: /* 100G AOC or 25GAUI C2M AOC. */ + return TRANSVR_CLASS_OPTICAL_25G_AOC; + + case 0x02: /* 100GBASE-SR4 or 25GBASE-SR */ + return TRANSVR_CLASS_OPTICAL_25G_SR; + + case 0x03: /* 100GBASE-LR4 or 25GBASE-LR */ + return TRANSVR_CLASS_OPTICAL_25G_LR; + + case 0x04: /* 100GBASE-ER4 or 25GBASE-ER */ + return TRANSVR_CLASS_OPTICAL_25G_ER; + + case 0x08: /* 100G ACC (Active Copper Cable) or 25GAUI C2M ACC. */ + case 0x0b: /* 100GBASE-CR4 or 25GBASE-CR CA-L */ + case 0x0c: /* 25GBASE-CR CA-S */ + case 0x0d: /* 25GBASE-CR CA-N */ + case 0x19: /* 100G ACC or 25GAUI C2M ACC. */ + return TRANSVR_CLASS_COPPER_L1_25G; + + default: + break; + } + SWPS_INFO("%s: Unexcept value:0x%02x\n :%s", + __func__, detect_val, self->swp_name); + return TRANSVR_CLASS_ERROR; +} + + +int +_sfp_detect_class_by_10_ethernet(struct transvr_obj_s* self) { + /* Reference: SFF-8472 (v12.2) + */ + int detect_val = DEBUG_TRANSVR_INT_VAL; + + detect_val = _sfp_get_comp_10g_eth_comp(self); + /* Case: Unspecified */ + if (detect_val == 0x00) { + return TRANSVR_CLASS_UNSPECIFIED; + } + /* Case: 10G Optical (x1) */ + if ((detect_val & 0x10) == 0x10) { /* 00010000 : 10GBASE-SR */ + return TRANSVR_CLASS_OPTICAL_10G_S_SR; + } + if ( ((detect_val & 0x20) == 0x20) || /* 00100000 : 10GBASE-LR */ + ((detect_val & 0x40) == 0x40) ){ /* 01000000 : 10GBASE-LRM */ + return TRANSVR_CLASS_OPTICAL_10G_S_LR; + } + if ((detect_val & 0x80) == 0x80) { /* 10000000 : 10GBASE-ER */ + return TRANSVR_CLASS_OPTICAL_10G_S_ER; + } + /* Case: ERROR */ + SWPS_INFO("%s: Unexcept value:0x%02x\n :%s", + __func__, detect_val, self->swp_name); + return TRANSVR_CLASS_ERROR; +} + + +int +_sfp_detect_if_sp_by_br(struct transvr_obj_s* self) { + + int lower_bound_1g = 0x0b; + int upper_bound_1g = 0x1A; + int lower_bound_10g = 0x60; + int upper_bound_10g = 0x75; + int lower_bound_25g = 0xf0; + int upper_bound_25g = 0xff; + int notmal_br = DEBUG_TRANSVR_INT_VAL; + + notmal_br = (int)(self->br); /* updated by update_all() */ + /* Check 25G */ + if ((notmal_br >= lower_bound_25g) && + (notmal_br <= upper_bound_25g) ) { + return TRANSVR_CLASS_25G; + } + /* Check 10G */ + if ((notmal_br >= lower_bound_10g) && + (notmal_br <= upper_bound_10g) ) { + return TRANSVR_CLASS_10G; + } + /* Check 1G */ + if ((notmal_br >= lower_bound_1g) && + (notmal_br <= upper_bound_1g) ) { + return TRANSVR_CLASS_1G; + } + return TRANSVR_CLASS_UNSPECIFIED; +} + + +int +_sfp_detect_class_by_1g_ethernet(struct transvr_obj_s* self) { + /* Reference: SFF-8472 (v12.2) + */ + int detect_val = DEBUG_TRANSVR_INT_VAL; + int speed_br = DEBUG_TRANSVR_INT_VAL; + int speed_tmp = DEBUG_TRANSVR_INT_VAL; + char err_str[64] = DEBUG_TRANSVR_STR_VAL; + + speed_br = _sfp_detect_if_sp_by_br(self); + detect_val = _sfp_get_comp_1g_eth_comp(self); + + if (detect_val < 0) { + snprintf(err_str, sizeof(err_str), "Detect abnormal value:%d", detect_val); + goto err_p_sfp_detect_class_by_1g_ethernet; + } + /* Case: Unspecified */ + if (detect_val == 0x00) { + return TRANSVR_CLASS_UNSPECIFIED; + } + /* Case: 1G (x1) */ + if ((detect_val & 0x01) == 0x01) { /* 00000001 : 1000BASE-SX */ + speed_tmp = TRANSVR_CLASS_OPTICAL_1G_SX; + goto ok_sfp_detect_class_by_1g_ethernet_4_check_br_10g; + } + if ((detect_val & 0x02) == 0x02) { /* 00000010 : 1000BASE-LX *3 */ + speed_tmp = TRANSVR_CLASS_OPTICAL_1G_LX; + goto ok_sfp_detect_class_by_1g_ethernet_4_check_br_10g; + } + if ((detect_val & 0x04) == 0x04) { /* 00000100 : 1000BASE-CX */ + speed_tmp = TRANSVR_CLASS_COPPER_L1_1G; + goto ok_sfp_detect_class_by_1g_ethernet_4_check_br_10g; + } + /* Case: 1000 Base-T (x1) */ + if ((detect_val & 0x08) == 0x08) { /* 00001000 : 1000BASE-T */ + return TRANSVR_CLASS_BASE_T_1000; + } + /* Case: 100 Base */ + if ( ((detect_val & 0x10) == 0x10) || /* 00010000 : 100BASE-LX/LX10 */ + ((detect_val & 0x20) == 0x20) || /* 00100000 : 100BASE-FX */ + ((detect_val & 0x40) == 0x40) || /* 01000000 : BASE-BX10 *3 */ + ((detect_val & 0x80) == 0x80) ){ /* 10000000 : BASE-PX *3 */ + return TRANSVR_CLASS_OPTICAL_100; + } + /* Case: ERROR */ + snprintf(err_str, sizeof(err_str), "Case:ERROR, value:%d", detect_val); + goto err_p_sfp_detect_class_by_1g_ethernet; + +ok_sfp_detect_class_by_1g_ethernet_4_check_br_10g: + switch (speed_br) { + case TRANSVR_CLASS_UNSPECIFIED: + case TRANSVR_CLASS_1G: + return speed_tmp; + case TRANSVR_CLASS_10G: + goto ok_sfp_detect_class_by_1g_ethernet_4_transfer_10G; + } + +ok_sfp_detect_class_by_1g_ethernet_4_transfer_10G: + switch (speed_tmp) { + case TRANSVR_CLASS_OPTICAL_1G_SX: + return TRANSVR_CLASS_OPTICAL_10G_S_SR; + case TRANSVR_CLASS_OPTICAL_1G_LX: + return TRANSVR_CLASS_OPTICAL_10G_S_LR; + case TRANSVR_CLASS_COPPER_L1_1G: + return TRANSVR_CLASS_COPPER_L1_10G; + default: + break; + } + snprintf(err_str, sizeof(err_str), "transfer_1to10 fail, speed:%d", speed_tmp); + goto err_p_sfp_detect_class_by_1g_ethernet; + +err_p_sfp_detect_class_by_1g_ethernet: + SWPS_INFO("%s: %s :%s", __func__, err_str, self->swp_name); + return TRANSVR_CLASS_ERROR; +} + + +int +_sfp_detect_class_by_feature(struct transvr_obj_s* self) { + /* Reference: SFF-8024 (v3.8) + */ + int is_active = 0; + int conn_val = DEBUG_TRANSVR_INT_VAL; + int check_val = DEBUG_TRANSVR_INT_VAL; + int wave_len = DEBUG_TRANSVR_INT_VAL; + int speed_val = DEBUG_TRANSVR_INT_VAL; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + speed_val = _sfp_detect_if_sp_by_br(self); + conn_val = _sfp_get_connector_type(self); + + switch(conn_val) { + case 0x00: /* Unspecified */ + goto ok_sfp_detect_class_by_feature_4_check_active_passive; + case 0x07: /* LC (Lucent Connector) */ + case 0x0b: /* Optical Pigtail */ + case 0x0c: /* MPO 1x12 */ + case 0x0d: /* MPO 2x16 */ + /* + * ToDo: Need verify Optical Pigtail + */ + goto ok_sfp_detect_class_by_feature_4_optiocal; + case 0x21: /* Copper pigtail */ + /* + * ToDo: Need check ACC use case + */ + goto ok_sfp_detect_class_by_feature_4_check_active_passive; + case 0x23: /* No separable connector */ + /* + * ToDo: Standard not clear, not all transceiver vendor + * have the same defined + */ + goto ok_sfp_detect_class_by_feature_4_check_active_passive; + default: + break; + } + goto ok_sfp_detect_class_by_feature_4_unknow; + +ok_sfp_detect_class_by_feature_4_check_active_passive: + check_val = _sfp_get_cable_tech(self); + switch(check_val) { + case 0x00: /* Unspecified */ + goto ok_sfp_detect_class_by_feature_4_unknow; + case 0x04: /* Passive */ + goto ok_sfp_detect_class_by_feature_4_copper; + case 0x08: /* Active */ + is_active = 1; + goto ok_sfp_detect_class_by_feature_4_aoc; + default: + snprintf(err_msg, sizeof(err_msg), + "_sfp_get_cable_tech return Non define value:%d", + check_val); + break; + } + goto err_sfp_detect_class_by_feature_1; + +ok_sfp_detect_class_by_feature_4_optiocal: + wave_len = _common_count_wavelength(self, + self->wavelength[0], + self->wavelength[1]); + switch(speed_val) { + case TRANSVR_CLASS_25G: + switch (wave_len) { + case VAL_OPTICAL_WAVELENGTH_SR: + return TRANSVR_CLASS_OPTICAL_25G_SR; + case VAL_OPTICAL_WAVELENGTH_LR: + return TRANSVR_CLASS_OPTICAL_25G_LR; + case VAL_OPTICAL_WAVELENGTH_ER: + return TRANSVR_CLASS_OPTICAL_25G_ER; + default: + break; + } + return TRANSVR_CLASS_OPTICAL_25G; + + case TRANSVR_CLASS_10G: + switch (wave_len) { + case VAL_OPTICAL_WAVELENGTH_SR: + return TRANSVR_CLASS_OPTICAL_10G_S_SR; + case VAL_OPTICAL_WAVELENGTH_LR: + return TRANSVR_CLASS_OPTICAL_10G_S_LR; + case VAL_OPTICAL_WAVELENGTH_ER: + return TRANSVR_CLASS_OPTICAL_10G_S_ER; + default: + break; + } + return TRANSVR_CLASS_OPTICAL_10G; + + case TRANSVR_CLASS_1G: + switch (wave_len) { + case VAL_OPTICAL_WAVELENGTH_SR: + return TRANSVR_CLASS_OPTICAL_1G_SX; + case VAL_OPTICAL_WAVELENGTH_LR: + return TRANSVR_CLASS_OPTICAL_1G_LX; + case VAL_OPTICAL_WAVELENGTH_ER: + return TRANSVR_CLASS_OPTICAL_1G_EX; + default: + break; + } + return TRANSVR_CLASS_OPTICAL_1G; + + default: + return TRANSVR_CLASS_OPTICAL; + } + +ok_sfp_detect_class_by_feature_4_aoc: + switch(speed_val) { + case TRANSVR_CLASS_25G: + return TRANSVR_CLASS_OPTICAL_25G_AOC; + case TRANSVR_CLASS_10G: + return TRANSVR_CLASS_OPTICAL_10G_S_AOC; + case TRANSVR_CLASS_1G: + return TRANSVR_CLASS_OPTICAL_1G_AOC; + default: + break; + } + goto ok_sfp_detect_class_by_feature_4_unknow; + +ok_sfp_detect_class_by_feature_4_copper: + switch(speed_val) { + case TRANSVR_CLASS_25G: + return TRANSVR_CLASS_COPPER_L1_25G; + case TRANSVR_CLASS_10G: + return TRANSVR_CLASS_COPPER_L1_10G; + case TRANSVR_CLASS_1G: + return TRANSVR_CLASS_COPPER_L1_1G; + default: + return TRANSVR_CLASS_COPPER; + } + +ok_sfp_detect_class_by_feature_4_unknow: + return TRANSVR_CLASS_UNSPECIFIED; + +err_sfp_detect_class_by_feature_1: + SWPS_INFO("%s: %s\n :%s", __func__, err_msg, self->swp_name); + return TRANSVR_CLASS_ERROR; +} + + +int +sft_detect_transvr_class(struct transvr_obj_s* self) { + + int detect_val = DEBUG_TRANSVR_INT_VAL; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + /* Check Extended Compliance */ + detect_val = _sfp_detect_class_by_extend_comp(self); + switch(detect_val) { + case TRANSVR_CLASS_UNSPECIFIED: + break; + case TRANSVR_CLASS_OPTICAL_25G_AOC: + case TRANSVR_CLASS_OPTICAL_25G_SR: + case TRANSVR_CLASS_OPTICAL_25G_LR: + case TRANSVR_CLASS_OPTICAL_25G_ER: + case TRANSVR_CLASS_COPPER_L1_25G: + return detect_val; + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined extend_comp:%d", + detect_val); + goto err_sft_detect_transceiver_class_1; + } + /* Check 10G Compliance */ + detect_val = _sfp_detect_class_by_10_ethernet(self); + switch(detect_val) { + case TRANSVR_CLASS_UNSPECIFIED: + break; + case TRANSVR_CLASS_OPTICAL_10G_S_SR: + case TRANSVR_CLASS_OPTICAL_10G_S_LR: + case TRANSVR_CLASS_OPTICAL_10G_S_ER: + return detect_val; + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined 10G_eth:%d", + detect_val); + goto err_sft_detect_transceiver_class_1; + } + /* Check 1G Compliance */ + detect_val = _sfp_detect_class_by_1g_ethernet(self); + switch(detect_val) { + case TRANSVR_CLASS_UNSPECIFIED: + break; + case TRANSVR_CLASS_OPTICAL_1G_SX: + case TRANSVR_CLASS_OPTICAL_1G_LX: + case TRANSVR_CLASS_COPPER_L1_1G: + case TRANSVR_CLASS_BASE_T_1000: + case TRANSVR_CLASS_OPTICAL_100: + /* + * ToDo: Need Check 0.1G + */ + case TRANSVR_CLASS_OPTICAL_10G_S_SR: + case TRANSVR_CLASS_OPTICAL_10G_S_LR: + case TRANSVR_CLASS_COPPER_L1_10G: + /* Transfer speed case + * => Example: Raycom 10G DAC + */ + return detect_val; + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined 1G_eth:%d", + detect_val); + goto err_sft_detect_transceiver_class_1; + } + /* Check by connector, br, wavelength */ + detect_val = _sfp_detect_class_by_feature(self); + switch(detect_val) { + case TRANSVR_CLASS_UNSPECIFIED: + break; + case TRANSVR_CLASS_OPTICAL: + case TRANSVR_CLASS_OPTICAL_1G: + case TRANSVR_CLASS_OPTICAL_1G_SX: + case TRANSVR_CLASS_OPTICAL_1G_LX: + case TRANSVR_CLASS_OPTICAL_1G_EX: + case TRANSVR_CLASS_OPTICAL_1G_AOC: + case TRANSVR_CLASS_OPTICAL_10G: + case TRANSVR_CLASS_OPTICAL_10G_S_SR: + case TRANSVR_CLASS_OPTICAL_10G_S_LR: + case TRANSVR_CLASS_OPTICAL_10G_S_ER: + case TRANSVR_CLASS_OPTICAL_10G_S_AOC: + case TRANSVR_CLASS_OPTICAL_25G: + case TRANSVR_CLASS_OPTICAL_25G_SR: + case TRANSVR_CLASS_OPTICAL_25G_LR: + case TRANSVR_CLASS_OPTICAL_25G_ER: + case TRANSVR_CLASS_OPTICAL_25G_AOC: + case TRANSVR_CLASS_COPPER: + case TRANSVR_CLASS_COPPER_L1_1G: + case TRANSVR_CLASS_COPPER_L1_10G: + case TRANSVR_CLASS_COPPER_L1_25G: + return detect_val; + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined get_connector:%d", + detect_val); + goto err_sft_detect_transceiver_class_1; + } + /* Exception case: Can't verify */ + snprintf(err_msg, sizeof(err_msg), "Can not identify!"); + goto err_sft_detect_transceiver_class_1; + +err_sft_detect_transceiver_class_1: + SWPS_INFO("%s: %s :%s\n", __func__, err_msg, self->swp_name); + return TRANSVR_CLASS_ERROR; +} + + +int +_sfp_set_magnolia_if_type(struct transvr_obj_s* self, + int transvr_cls, + char *result){ + + int lmax = 8; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + switch(transvr_cls) { + case TRANSVR_CLASS_ERROR: + case TRANSVR_CLASS_UNSPECIFIED: + break; + /* 25G OPTICAL */ + case TRANSVR_CLASS_OPTICAL_25G_AOC: + case TRANSVR_CLASS_OPTICAL_25G_SR: + case TRANSVR_CLASS_OPTICAL_25G_LR: + case TRANSVR_CLASS_OPTICAL_25G_ER: + case TRANSVR_CLASS_OPTICAL_25G: + return snprintf(result, lmax, TRANSVR_IF_SFI); + /* 25G COPPER */ + case TRANSVR_CLASS_COPPER_L1_25G: + return snprintf(result, lmax, TRANSVR_IF_SFI); + /* 10G OPTICAL */ + case TRANSVR_CLASS_OPTICAL_10G_S_AOC: + case TRANSVR_CLASS_OPTICAL_10G_S_SR: + case TRANSVR_CLASS_OPTICAL_10G_S_LR: + case TRANSVR_CLASS_OPTICAL_10G_S_ER: + case TRANSVR_CLASS_OPTICAL_10G: + return snprintf(result, lmax, TRANSVR_IF_SFI); + /* 10G COPPER */ + case TRANSVR_CLASS_COPPER_L1_10G: + return snprintf(result, lmax, TRANSVR_IF_SFI); + /* 1G OPTICAL */ + case TRANSVR_CLASS_OPTICAL_1G_AOC: + case TRANSVR_CLASS_OPTICAL_1G_SX: + case TRANSVR_CLASS_OPTICAL_1G_LX: + case TRANSVR_CLASS_OPTICAL_1G_EX: + case TRANSVR_CLASS_OPTICAL_1G: + return snprintf(result, lmax, TRANSVR_IF_IF_GMII); + /* 1G COPPER */ + case TRANSVR_CLASS_COPPER_L1_1G: + return snprintf(result, lmax, TRANSVR_IF_IF_GMII); + /* 1G BASE_T */ + case TRANSVR_CLASS_BASE_T_1000: + return snprintf(result, lmax, TRANSVR_IF_IF_GMII); + /* 100 Base */ + case TRANSVR_CLASS_OPTICAL_100: + return snprintf(result, lmax, TRANSVR_IF_IF_GMII); + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined value:%d", + transvr_cls); + goto err_sfp_set_magnolia_if_type_1; + } + /* Exception case: Can't verify */ + snprintf(err_msg, sizeof(err_msg), "Can not identify!"); + goto err_sfp_set_magnolia_if_type_1; + +err_sfp_set_magnolia_if_type_1: + snprintf(result, lmax, TRANSVR_UEVENT_UNKNOW); + SWPS_INFO("%s: %s :%s\n", __func__, err_msg, self->swp_name); + return ERR_TRANSVR_ABNORMAL; +} + + +int +_sfp_set_redwood_if_type(struct transvr_obj_s* self, + int transvr_cls, + char *result) { + + int lmax = 8; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + switch(transvr_cls) { + case TRANSVR_CLASS_ERROR: + case TRANSVR_CLASS_UNSPECIFIED: + break; + /* 25G OPTICAL */ + case TRANSVR_CLASS_OPTICAL_25G_AOC: + case TRANSVR_CLASS_OPTICAL_25G_SR: + case TRANSVR_CLASS_OPTICAL_25G_LR: + case TRANSVR_CLASS_OPTICAL_25G_ER: + case TRANSVR_CLASS_OPTICAL_25G: + return snprintf(result, lmax, TRANSVR_IF_SR); + /* 25G COPPER */ + case TRANSVR_CLASS_COPPER_L1_25G: + return snprintf(result, lmax, TRANSVR_IF_KR); + /* 10G OPTICAL */ + case TRANSVR_CLASS_OPTICAL_10G_S_AOC: + case TRANSVR_CLASS_OPTICAL_10G_S_SR: + case TRANSVR_CLASS_OPTICAL_10G_S_LR: + case TRANSVR_CLASS_OPTICAL_10G_S_ER: + case TRANSVR_CLASS_OPTICAL_10G: + return snprintf(result, lmax, TRANSVR_IF_SFI); + /* 10G COPPER */ + case TRANSVR_CLASS_COPPER_L1_10G: + return snprintf(result, lmax, TRANSVR_IF_SFI); + /* 1G OPTICAL */ + case TRANSVR_CLASS_OPTICAL_1G_AOC: + case TRANSVR_CLASS_OPTICAL_1G_SX: + case TRANSVR_CLASS_OPTICAL_1G_LX: + case TRANSVR_CLASS_OPTICAL_1G_EX: + case TRANSVR_CLASS_OPTICAL_1G: + return snprintf(result, lmax, TRANSVR_IF_IF_GMII); + /* 1G COPPER */ + case TRANSVR_CLASS_COPPER_L1_1G: + return snprintf(result, lmax, TRANSVR_IF_IF_GMII); + /* 1G BASE_T */ + case TRANSVR_CLASS_BASE_T_1000: + return snprintf(result, lmax, TRANSVR_IF_IF_GMII); + /* 100 Base */ + case TRANSVR_CLASS_OPTICAL_100: + return snprintf(result, lmax, TRANSVR_IF_IF_GMII); + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined value:%d", + transvr_cls); + goto err_sfp_set_redwood_if_type_1; + } + /* Exception case: Can't verify */ + snprintf(err_msg, sizeof(err_msg), "Can not identify!"); + goto err_sfp_set_redwood_if_type_1; + +err_sfp_set_redwood_if_type_1: + snprintf(result, lmax, TRANSVR_UEVENT_UNKNOW); + SWPS_INFO("%s: %s\n :%s", __func__, err_msg, self->swp_name); + return ERR_TRANSVR_ABNORMAL; +} + + +int +_sfp_set_lavender_if_type(struct transvr_obj_s* self, + int transvr_cls, + char *result) { + /* (TBD) + * Due to 'LAV' looks like doesn't have interface type. + * We bypass it currently. + */ + int lmax = 8; + return snprintf(result, lmax, TRANSVR_UEVENT_UNKNOW); +} + + +int +_sfp_detect_if_type(struct transvr_obj_s* self, + char *result){ + + int lmax = 8; + int detect_cls = DEBUG_TRANSVR_INT_VAL; + + detect_cls = sft_detect_transvr_class(self); + switch (self->chipset_type) { + case CHIP_TYPE_MAGNOLIA: + return _sfp_set_magnolia_if_type(self, detect_cls, result); + + case CHIP_TYPE_MAPLE: + case CHIP_TYPE_REDWOOD: + return _sfp_set_redwood_if_type(self, detect_cls, result); + + case CHIP_TYPE_LAVENDER: + return _sfp_set_lavender_if_type(self, detect_cls, result); + + default: + SWPS_INFO("%s: non-defined chipset_type:%d :%s\n", + __func__, self->chipset_type, self->swp_name); + break; + } + snprintf(result, lmax, TRANSVR_UEVENT_UNKNOW); + return ERR_TRANSVR_ABNORMAL; +} + + +int +sfp_get_if_type(struct transvr_obj_s *self, + char *buf_p){ + + int lmax = 16; + char tmp_result[16] = DEBUG_TRANSVR_STR_VAL; + + if (self->state != STATE_TRANSVR_CONNECTED) { + return snprintf(buf_p, lmax, "%d\n", self->state); + } + if (_sfp_detect_if_type(self, tmp_result) < 0) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_ABNORMAL); + } + return snprintf(buf_p, lmax, "%s\n", tmp_result); +} + + +int +_sfp_detect_if_speed(struct transvr_obj_s* self, + char *result){ + + int lmax = 16; + int detect_val = DEBUG_TRANSVR_INT_VAL; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + detect_val = sft_detect_transvr_class(self); + switch(detect_val) { + case TRANSVR_CLASS_ERROR: + case TRANSVR_CLASS_UNSPECIFIED: + break; + /* 25G OPTICAL */ + case TRANSVR_CLASS_OPTICAL_25G_AOC: + case TRANSVR_CLASS_OPTICAL_25G_SR: + case TRANSVR_CLASS_OPTICAL_25G_LR: + case TRANSVR_CLASS_OPTICAL_25G_ER: + case TRANSVR_CLASS_OPTICAL_25G: + return snprintf(result, lmax, TRANSVR_IF_SP_25G); + /* 25G COPPER */ + case TRANSVR_CLASS_COPPER_L1_25G: + return snprintf(result, lmax, TRANSVR_IF_SP_25G); + /* 10G OPTICAL */ + case TRANSVR_CLASS_OPTICAL_10G_S_AOC: + case TRANSVR_CLASS_OPTICAL_10G_S_SR: + case TRANSVR_CLASS_OPTICAL_10G_S_LR: + case TRANSVR_CLASS_OPTICAL_10G_S_ER: + case TRANSVR_CLASS_OPTICAL_10G: + return snprintf(result, lmax, TRANSVR_IF_SP_10G); + /* 10G COPPER */ + case TRANSVR_CLASS_COPPER_L1_10G: + return snprintf(result, lmax, TRANSVR_IF_SP_10G); + /* 1G OPTICAL */ + case TRANSVR_CLASS_OPTICAL_1G_AOC: + case TRANSVR_CLASS_OPTICAL_1G_SX: + case TRANSVR_CLASS_OPTICAL_1G_LX: + case TRANSVR_CLASS_OPTICAL_1G_EX: + case TRANSVR_CLASS_OPTICAL_1G: + return snprintf(result, lmax, TRANSVR_IF_SP_1G); + /* 1G COPPER */ + case TRANSVR_CLASS_COPPER_L1_1G: + return snprintf(result, lmax, TRANSVR_IF_SP_1G); + /* 1G BASE_T */ + case TRANSVR_CLASS_BASE_T_1000: + return snprintf(result, lmax, TRANSVR_IF_SP_1G); + /* 100 Base */ + case TRANSVR_CLASS_OPTICAL_100: + return snprintf(result, lmax, TRANSVR_IF_SP_100); + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined value:%d", + detect_val); + goto err_sfp_detect_if_speed_1; + } + /* Check by BR */ + detect_val = _sfp_detect_if_sp_by_br(self); + switch (detect_val) { + case TRANSVR_CLASS_25G: + return snprintf(result, lmax, TRANSVR_IF_SP_25G); + case TRANSVR_CLASS_10G: + return snprintf(result, lmax, TRANSVR_IF_SP_10G); + case TRANSVR_CLASS_1G: + return snprintf(result, lmax, TRANSVR_IF_SP_1G); + default: + break; + } + /* Exception case: Can't verify */ + snprintf(err_msg, sizeof(err_msg), "Can not identify!"); + goto err_sfp_detect_if_speed_1; + +err_sfp_detect_if_speed_1: + snprintf(result, lmax, TRANSVR_UEVENT_UNKNOW); + SWPS_INFO("%s %s\n :%s", __func__, err_msg, self->swp_name); + return ERR_TRANSVR_ABNORMAL; +} + + +int +sfp_get_if_speed(struct transvr_obj_s *self, + char *buf_p){ + + int lmax = 16; + char tmp_result[16] = DEBUG_TRANSVR_STR_VAL; + + if (self->state != STATE_TRANSVR_CONNECTED) { + return snprintf(buf_p, lmax, "%d\n", self->state); + } + if (_sfp_detect_if_speed(self, tmp_result) < 0) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_ABNORMAL); + } + return snprintf(buf_p, lmax, "%s\n", tmp_result); +} + + +int +_qsfp_detect_class_by_extend_comp(struct transvr_obj_s* self) { + /* Reference: SFF-8024 (v3.8) + */ + int detect_val = DEBUG_TRANSVR_INT_VAL; + + detect_val = _qsfp_get_comp_extended(self); + switch(detect_val) { + case 0x00: /* Unspecified */ + return TRANSVR_CLASS_UNSPECIFIED; + + case 0x01: /* 100G AOC (Active Optical Cable) or 25GAUI C2M */ + case 0x18: /* 100G AOC or 25GAUI C2M AOC. */ + return TRANSVR_CLASS_OPTICAL_100G_AOC; + + case 0x06: /* 100G CWDM4 */ + case 0x09: /* Obsolete (assigned before 100G CWDM4 MSA required FEC) */ + case 0x17: /* 100G CLR4 */ + case 0x1A: /* 100GE-DWDM2 */ + return TRANSVR_CLASS_OPTICAL_100G; + + case 0x02: /* 100GBASE-SR4 or 25GBASE-SR */ + return TRANSVR_CLASS_OPTICAL_100G_SR4; + + case 0x03: /* 100GBASE-LR4 or 25GBASE-LR */ + return TRANSVR_CLASS_OPTICAL_100G_LR4; + + case 0x04: /* 100GBASE-ER4 or 25GBASE-ER */ + return TRANSVR_CLASS_OPTICAL_100G_ER4; + + case 0x07: /* 100G PSM4 Parallel SMF */ + return TRANSVR_CLASS_OPTICAL_100G_PSM4; + + case 0x12: /* 40G PSM4 Parallel SMF */ + return TRANSVR_CLASS_OPTICAL_40G; + + case 0x11: /* 4 x 10GBASE-SR */ + return TRANSVR_CLASS_OPTICAL_40G_SR4; + + case 0x10: /* 40GBASE-ER4 */ + return TRANSVR_CLASS_OPTICAL_40G_ER4; + + case 0x08: /* 100G ACC (Active Copper Cable) or 25GAUI C2M ACC. */ + case 0x0b: /* 100GBASE-CR4 or 25GBASE-CR CA-L */ + case 0x19: /* 100G ACC or 25GAUI C2M ACC. */ + return TRANSVR_CLASS_COPPER_L4_100G; + + default: + break; + } + SWPS_INFO("%s: Unexcept value:0x%02x\n :%s", + __func__, detect_val, self->swp_name); + return TRANSVR_CLASS_ERROR; +} + + +int +_qsfp_detect_class_by_10_40_100_ethernet(struct transvr_obj_s* self) { + /* Reference: SFF-8472 (v12.2) + */ + int detect_val = DEBUG_TRANSVR_INT_VAL; + + detect_val = _qsfp_get_comp_10_40_100_ethernet(self); + /* Case: Unspecified */ + if (detect_val == 0x00) { + return TRANSVR_CLASS_UNSPECIFIED; + } + /* Case: 40G Optical */ + if ((detect_val & 0x01) == 0x01) { /* 00000001 : 40G Active Cable (XLPPI) */ + return TRANSVR_CLASS_OPTICAL_40G_AOC; + } + if ((detect_val & 0x04) == 0x04) { /* 00000100 : 40GBASE-SR4 */ + return TRANSVR_CLASS_OPTICAL_40G_SR4; + } + if ( (detect_val & 0x02) == 0x02) { /* 00000010 : 40GBASE-LR4 */ + return TRANSVR_CLASS_OPTICAL_40G_LR4; + } + if ( (detect_val & 0x08) == 0x08) { /* 00001000 : 40GBASE-CR4 */ + return TRANSVR_CLASS_COPPER_L4_40G; + } + /* Case: 10G Optical */ + if ( (detect_val & 0x10) == 0x10) { /* 00010000 : 10GBASE-SR */ + return TRANSVR_CLASS_OPTICAL_10G_Q_SR; + } + if ( ((detect_val & 0x20) == 0x20) || /* 00100000 : 10GBASE-LR */ + ((detect_val & 0x40) == 0x40) ){ /* 01000000 : 10GBASE-LRM */ + return TRANSVR_CLASS_OPTICAL_10G_Q_LR; + } + /* Case: Extend Compliance */ + if ( ((detect_val & 0x80) == 0x80) ){ /* 10000000 : Use Extend Compliance */ + return TRANSVR_CLASS_EXTEND_COMP; + } + /* Case: ERROR */ + SWPS_INFO("%s: Unexcept value:0x%02x\n :%s", + __func__, detect_val, self->swp_name); + return TRANSVR_CLASS_ERROR; +} + + +int +_qsfp_detect_if_sp_by_br(struct transvr_obj_s* self) { + + int lower_bound_10g = 0x10; + int upper_bound_10g = 0x25; + int lower_bound_40g = 0x60; + int upper_bound_40g = 0x75; + int lower_bound_100g = 0x60; + int upper_bound_100g = 0x75; + int used_extend_br = 0xff; + int notmal_br = DEBUG_TRANSVR_INT_VAL; + int extend_br = DEBUG_TRANSVR_INT_VAL; + + notmal_br = (int)(self->br); /* updated by update_all() */ + /* Check 40G */ + if ((notmal_br >= lower_bound_40g) && + (notmal_br <= upper_bound_40g) ) { + return TRANSVR_CLASS_40G; + } + /* Check 100G */ + if (notmal_br == used_extend_br) { + extend_br = (int)(self->extbr); /* updated by update_all() */ + if ((extend_br >= lower_bound_100g) && + (extend_br <= upper_bound_100g) ) { + return TRANSVR_CLASS_100G; + } + } + /* Check 10G */ + if ((notmal_br >= lower_bound_10g) && + (notmal_br <= upper_bound_10g) ) { + return TRANSVR_CLASS_10G; + } + return TRANSVR_CLASS_UNSPECIFIED; +} + + +int +_qsfp_detect_class_by_feature(struct transvr_obj_s* self) { + /* Reference: SFF-8024 (v3.8) + */ + int conn_val = DEBUG_TRANSVR_INT_VAL; + int wave_len = DEBUG_TRANSVR_INT_VAL; + int speed_val = DEBUG_TRANSVR_INT_VAL; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + speed_val = _qsfp_detect_if_sp_by_br(self); + conn_val = _qsfp_get_connector_type(self); + + switch(conn_val) { + case 0x00: /* Unspecified */ + return TRANSVR_CLASS_UNSPECIFIED; + case 0x07: /* LC (Lucent Connector) */ + case 0x0b: /* Optical Pigtail */ + case 0x0c: /* MPO 1x12 (Multifiber Parallel Optic) */ + case 0x0d: /* MPO 2x16 */ + goto ok_qsfp_detect_class_by_feature_4_optiocal; + case 0x21: /* Copper pigtail */ + goto ok_qsfp_detect_class_by_feature_4_copper; + case 0x23: /* No separable connector */ + if ((_qsfp_get_comp_fc_link_length(self) > 0) || + (_qsfp_get_comp_fc_trans_tech(self) > 0) || + (_qsfp_get_comp_fc_trans_media(self) > 0) || + (_qsfp_get_comp_fc_speed(self) > 0) ) { + goto ok_qsfp_detect_class_by_feature_4_aoc; + } + goto ok_qsfp_detect_class_by_feature_4_copper; + default: + snprintf(err_msg, sizeof(err_msg), + "_qsfp_get_connector_type return Non define value:%d", + conn_val); + goto err_qsfp_detect_class_by_feature_1; + } + return TRANSVR_CLASS_UNSPECIFIED; + +ok_qsfp_detect_class_by_feature_4_optiocal: + wave_len = _common_count_wavelength(self, + self->wavelength[0], + self->wavelength[1]); + switch(speed_val) { + case TRANSVR_CLASS_100G: + switch (wave_len) { + case VAL_OPTICAL_WAVELENGTH_SR: + return TRANSVR_CLASS_OPTICAL_100G_SR4; + case VAL_OPTICAL_WAVELENGTH_LR: + return TRANSVR_CLASS_OPTICAL_100G_LR4; + case VAL_OPTICAL_WAVELENGTH_ER: + return TRANSVR_CLASS_OPTICAL_100G_ER4; + default: + break; + } + return TRANSVR_CLASS_OPTICAL_100G; + + case TRANSVR_CLASS_40G: + switch (wave_len) { + case VAL_OPTICAL_WAVELENGTH_SR: + return TRANSVR_CLASS_OPTICAL_40G_SR4; + case VAL_OPTICAL_WAVELENGTH_LR: + return TRANSVR_CLASS_OPTICAL_40G_LR4; + case VAL_OPTICAL_WAVELENGTH_ER: + return TRANSVR_CLASS_OPTICAL_40G_ER4; + default: + break; + } + return TRANSVR_CLASS_OPTICAL_40G; + + case TRANSVR_CLASS_10G: + switch (wave_len) { + case VAL_OPTICAL_WAVELENGTH_SR: + return TRANSVR_CLASS_OPTICAL_10G_Q_SR; + case VAL_OPTICAL_WAVELENGTH_LR: + return TRANSVR_CLASS_OPTICAL_10G_Q_LR; + case VAL_OPTICAL_WAVELENGTH_ER: + return TRANSVR_CLASS_OPTICAL_10G_Q_ER; + default: + break; + } + return TRANSVR_CLASS_OPTICAL_10G; + + default: + return TRANSVR_CLASS_OPTICAL; + } + +ok_qsfp_detect_class_by_feature_4_aoc: + switch(speed_val) { + case TRANSVR_CLASS_100G: + return TRANSVR_CLASS_OPTICAL_100G_AOC; + case TRANSVR_CLASS_40G: + return TRANSVR_CLASS_OPTICAL_40G_AOC; + case TRANSVR_CLASS_10G: + return TRANSVR_CLASS_OPTICAL_10G_Q_AOC; + default: + return TRANSVR_CLASS_OPTICAL; + } + +ok_qsfp_detect_class_by_feature_4_copper: + switch(speed_val) { + case TRANSVR_CLASS_100G: + return TRANSVR_CLASS_COPPER_L4_100G; + case TRANSVR_CLASS_40G: + return TRANSVR_CLASS_COPPER_L4_40G; + case TRANSVR_CLASS_10G: + return TRANSVR_CLASS_COPPER_L4_10G; + default: + return TRANSVR_CLASS_COPPER; + } + +err_qsfp_detect_class_by_feature_1: + SWPS_INFO("%s: %s\n :%s", + __func__, err_msg, self->swp_name); + return TRANSVR_CLASS_ERROR; +} + + +int +qsft_detect_transvr_class(struct transvr_obj_s* self) { + + int detect_val = DEBUG_TRANSVR_INT_VAL; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + /* Check Extended Compliance */ + detect_val = _qsfp_detect_class_by_extend_comp(self); + switch (detect_val) { + case TRANSVR_CLASS_UNSPECIFIED: + break; + case TRANSVR_CLASS_OPTICAL_100G: + case TRANSVR_CLASS_OPTICAL_100G_AOC: + case TRANSVR_CLASS_OPTICAL_100G_SR4: + case TRANSVR_CLASS_OPTICAL_100G_LR4: + case TRANSVR_CLASS_OPTICAL_100G_ER4: + case TRANSVR_CLASS_OPTICAL_100G_PSM4: + case TRANSVR_CLASS_OPTICAL_40G: + case TRANSVR_CLASS_OPTICAL_40G_AOC: + case TRANSVR_CLASS_OPTICAL_40G_SR4: + case TRANSVR_CLASS_OPTICAL_40G_LR4: + case TRANSVR_CLASS_OPTICAL_40G_ER4: + case TRANSVR_CLASS_COPPER_L4_100G: + return detect_val; + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined extend_comp:%d", + detect_val); + goto err_qsft_detect_transvr_class_1; + } + /* Check 10/40G/100G Ethernet Compliance */ + detect_val = _qsfp_detect_class_by_10_40_100_ethernet(self); + switch(detect_val) { + case TRANSVR_CLASS_UNSPECIFIED: + break; + case TRANSVR_CLASS_OPTICAL_40G_AOC: + case TRANSVR_CLASS_OPTICAL_40G_SR4: + case TRANSVR_CLASS_OPTICAL_40G_LR4: + case TRANSVR_CLASS_OPTICAL_10G_Q_SR: /* Need Check: SR4 or SR */ + case TRANSVR_CLASS_OPTICAL_10G_Q_LR: /* Need Check: SR4 or SR */ + case TRANSVR_CLASS_COPPER_L4_40G: + return detect_val; + case TRANSVR_CLASS_EXTEND_COMP: + /* Format incorrect case (We already checked the Extend + * Compliance is 0 + */ + snprintf(err_msg, sizeof(err_msg), + "Transceiver format incorrect"); + goto err_qsft_detect_transvr_class_1; + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined 10/40/100:%d", + detect_val); + goto err_qsft_detect_transvr_class_1; + } + /* Check by Connector type, BR and wavelength */ + detect_val = _qsfp_detect_class_by_feature(self); + switch (detect_val) { + case TRANSVR_CLASS_UNSPECIFIED: + break; + case TRANSVR_CLASS_OPTICAL_100G_ER4: + case TRANSVR_CLASS_OPTICAL_100G_LR4: + case TRANSVR_CLASS_OPTICAL_100G_SR4: + case TRANSVR_CLASS_OPTICAL_100G_AOC: + case TRANSVR_CLASS_OPTICAL_100G: + case TRANSVR_CLASS_OPTICAL_40G_ER4: + case TRANSVR_CLASS_OPTICAL_40G_LR4: + case TRANSVR_CLASS_OPTICAL_40G_SR4: + case TRANSVR_CLASS_OPTICAL_40G_AOC: + case TRANSVR_CLASS_OPTICAL_40G: + case TRANSVR_CLASS_OPTICAL_10G_Q_ER: + case TRANSVR_CLASS_OPTICAL_10G_Q_LR: + case TRANSVR_CLASS_OPTICAL_10G_Q_SR: + case TRANSVR_CLASS_OPTICAL_10G_Q_AOC: + case TRANSVR_CLASS_OPTICAL_10G: + case TRANSVR_CLASS_OPTICAL: + case TRANSVR_CLASS_COPPER_L4_100G: + case TRANSVR_CLASS_COPPER_L4_40G: + case TRANSVR_CLASS_COPPER_L4_10G: + case TRANSVR_CLASS_COPPER: + return detect_val; + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined connector:%d", + detect_val); + goto err_qsft_detect_transvr_class_1; + } + /* Exception case: Can't verify */ + snprintf(err_msg, sizeof(err_msg), + "Can not identify!"); + goto err_qsft_detect_transvr_class_1; + +err_qsft_detect_transvr_class_1: + SWPS_INFO("%s: %s\n :%s", __func__, err_msg, self->swp_name); + return TRANSVR_CLASS_ERROR; +} + + +int +_qsfp_set_magnolia_if_type(struct transvr_obj_s* self, + int transvr_cls, + char *result){ + + int lmax = 8; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + switch (transvr_cls) { + case TRANSVR_CLASS_UNSPECIFIED: + case TRANSVR_CLASS_ERROR: + break; + /* 100G Optical */ + case TRANSVR_CLASS_OPTICAL_100G: + case TRANSVR_CLASS_OPTICAL_100G_AOC: + case TRANSVR_CLASS_OPTICAL_100G_SR4: + case TRANSVR_CLASS_OPTICAL_100G_LR4: + case TRANSVR_CLASS_OPTICAL_100G_ER4: + case TRANSVR_CLASS_OPTICAL_100G_PSM4: + return snprintf(result, lmax, TRANSVR_IF_SR4); + /* 100G Copper */ + case TRANSVR_CLASS_COPPER_L4_100G: + return snprintf(result, lmax, TRANSVR_IF_KR4); + /* 40G Optical */ + case TRANSVR_CLASS_OPTICAL_40G: + case TRANSVR_CLASS_OPTICAL_40G_AOC: + case TRANSVR_CLASS_OPTICAL_40G_SR4: + case TRANSVR_CLASS_OPTICAL_40G_LR4: + case TRANSVR_CLASS_OPTICAL_40G_ER4: + return snprintf(result, lmax, TRANSVR_IF_IF_XGMII); + /* 40G Copper */ + case TRANSVR_CLASS_COPPER_L4_40G: + return snprintf(result, lmax, TRANSVR_IF_IF_XGMII); + /* 10G Optical */ + case TRANSVR_CLASS_OPTICAL_10G: + case TRANSVR_CLASS_OPTICAL_10G_Q_AOC: + case TRANSVR_CLASS_OPTICAL_10G_Q_SR: /* Need Check: SR4 or SR */ + case TRANSVR_CLASS_OPTICAL_10G_Q_LR: /* Need Check: LR4 or LR */ + case TRANSVR_CLASS_OPTICAL_10G_Q_ER: /* Need Check: ER4 or ER */ + return snprintf(result, lmax, TRANSVR_IF_IF_XGMII); + /* Optical */ + case TRANSVR_CLASS_OPTICAL: + return snprintf(result, lmax, TRANSVR_IF_IF_XGMII); + /* Copper */ + case TRANSVR_CLASS_COPPER: + return snprintf(result, lmax, TRANSVR_IF_IF_XGMII); + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined value:%d", + transvr_cls); + goto err_qsfp_set_magnolia_if_type_1; + } + /* Exception case: Can't verify */ + snprintf(err_msg, sizeof(err_msg), "Can not identify!"); + goto err_qsfp_set_magnolia_if_type_1; + +err_qsfp_set_magnolia_if_type_1: + snprintf(result, lmax, TRANSVR_UEVENT_UNKNOW); + SWPS_INFO("%s: %s\n :%s", __func__, err_msg, self->swp_name); + return ERR_TRANSVR_ABNORMAL; +} + + +int +_qsfp_set_redwood_if_type(struct transvr_obj_s* self, + int transvr_cls, + char *result){ + + int lmax = 8; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + switch (transvr_cls) { + case TRANSVR_CLASS_UNSPECIFIED: + case TRANSVR_CLASS_ERROR: + break; + /* 100G Optical */ + case TRANSVR_CLASS_OPTICAL_100G: + case TRANSVR_CLASS_OPTICAL_100G_AOC: + case TRANSVR_CLASS_OPTICAL_100G_SR4: + case TRANSVR_CLASS_OPTICAL_100G_LR4: + case TRANSVR_CLASS_OPTICAL_100G_ER4: + case TRANSVR_CLASS_OPTICAL_100G_PSM4: + return snprintf(result, lmax, TRANSVR_IF_SR4); + /* 100G Copper */ + case TRANSVR_CLASS_COPPER_L4_100G: + return snprintf(result, lmax, TRANSVR_IF_KR4); + /* 40G Optical */ + case TRANSVR_CLASS_OPTICAL_40G: + case TRANSVR_CLASS_OPTICAL_40G_AOC: + case TRANSVR_CLASS_OPTICAL_40G_SR4: + case TRANSVR_CLASS_OPTICAL_40G_LR4: + case TRANSVR_CLASS_OPTICAL_40G_ER4: + return snprintf(result, lmax, TRANSVR_IF_SR4); + /* 40G Copper */ + case TRANSVR_CLASS_COPPER_L4_40G: + return snprintf(result, lmax, TRANSVR_IF_KR4); + /* 10G Optical */ + case TRANSVR_CLASS_OPTICAL_10G: + case TRANSVR_CLASS_OPTICAL_10G_Q_AOC: + case TRANSVR_CLASS_OPTICAL_10G_Q_SR: /* Need Check: SR4 or SR */ + case TRANSVR_CLASS_OPTICAL_10G_Q_LR: /* Need Check: SR4 or SR */ + case TRANSVR_CLASS_OPTICAL_10G_Q_ER: + return snprintf(result, lmax, TRANSVR_IF_SR4); + /* Optical */ + case TRANSVR_CLASS_OPTICAL: + return snprintf(result, lmax, TRANSVR_IF_SR4); + /* Copper */ + case TRANSVR_CLASS_COPPER: + return snprintf(result, lmax, TRANSVR_IF_KR4); + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined value:%d", + transvr_cls); + goto err_qsfp_set_magnolia_if_type_1; + } + /* Exception case: Can't verify */ + snprintf(err_msg, sizeof(err_msg), "Can not identify!"); + goto err_qsfp_set_magnolia_if_type_1; + +err_qsfp_set_magnolia_if_type_1: + snprintf(result, lmax, TRANSVR_UEVENT_UNKNOW); + SWPS_INFO("%s: %s\n :%s", __func__, err_msg, self->swp_name); + return ERR_TRANSVR_ABNORMAL; +} + + +int +_qsfp_set_lavender_if_type(struct transvr_obj_s* self, + int transvr_cls, + char *result) { + /* (TBD) + * Due to 'LAV' looks like doesn't have interface type. + * We bypass it currently. + */ + int lmax = 8; + return snprintf(result, lmax, TRANSVR_UEVENT_UNKNOW); +} + + +int +_qsfp_detect_if_type(struct transvr_obj_s* self, + char *result){ + + int lmax = 8; + int detect_cls = DEBUG_TRANSVR_INT_VAL; + + detect_cls = qsft_detect_transvr_class(self); + switch (self->chipset_type) { + case CHIP_TYPE_MAGNOLIA: + return _qsfp_set_magnolia_if_type(self, detect_cls, result); + + case CHIP_TYPE_MAPLE: + case CHIP_TYPE_REDWOOD: + return _qsfp_set_redwood_if_type(self, detect_cls, result); + + case CHIP_TYPE_LAVENDER: + return _qsfp_set_lavender_if_type(self, detect_cls, result); + + default: + SWPS_INFO("%s: non-defined chipset_type:%d :%s\n", + __func__, self->chipset_type, self->swp_name); + break; + } + snprintf(result, lmax, TRANSVR_UEVENT_UNKNOW); + return ERR_TRANSVR_ABNORMAL; +} + + +int +qsfp_get_if_type(struct transvr_obj_s *self, + char *buf_p){ + + int lmax = 8; + char tmp_result[8] = DEBUG_TRANSVR_STR_VAL; + + if (self->state != STATE_TRANSVR_CONNECTED) { + return snprintf(buf_p, lmax, "%d\n", self->state); + } + if (_qsfp_detect_if_type(self, tmp_result) < 0) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_ABNORMAL); + } + return snprintf(buf_p, lmax, "%s\n", tmp_result); +} + + +int +_qsfp_detect_if_speed(struct transvr_obj_s* self, + char *result){ + int lmax = 16; + int detect_val = DEBUG_TRANSVR_INT_VAL; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + detect_val = qsft_detect_transvr_class(self); + switch (detect_val) { + case TRANSVR_CLASS_UNSPECIFIED: + case TRANSVR_CLASS_ERROR: + break; + /* 100G Optical */ + case TRANSVR_CLASS_OPTICAL_100G: + case TRANSVR_CLASS_OPTICAL_100G_AOC: + case TRANSVR_CLASS_OPTICAL_100G_SR4: + case TRANSVR_CLASS_OPTICAL_100G_LR4: + case TRANSVR_CLASS_OPTICAL_100G_ER4: + case TRANSVR_CLASS_OPTICAL_100G_PSM4: + return snprintf(result, lmax, TRANSVR_IF_SP_100G); + /* 100G Copper */ + case TRANSVR_CLASS_COPPER_L4_100G: + return snprintf(result, lmax, TRANSVR_IF_SP_100G); + /* 40G Optical */ + case TRANSVR_CLASS_OPTICAL_40G: + case TRANSVR_CLASS_OPTICAL_40G_AOC: + case TRANSVR_CLASS_OPTICAL_40G_SR4: + case TRANSVR_CLASS_OPTICAL_40G_LR4: + case TRANSVR_CLASS_OPTICAL_40G_ER4: + return snprintf(result, lmax, TRANSVR_IF_SP_40G); + /* 40G Copper */ + case TRANSVR_CLASS_COPPER_L4_40G: + return snprintf(result, lmax, TRANSVR_IF_SP_40G); + /* 10G Optical */ + case TRANSVR_CLASS_OPTICAL_10G: + case TRANSVR_CLASS_OPTICAL_10G_Q_AOC: + case TRANSVR_CLASS_OPTICAL_10G_Q_SR: /* Need Check: SR4 or SR */ + case TRANSVR_CLASS_OPTICAL_10G_Q_LR: /* Need Check: SR4 or SR */ + case TRANSVR_CLASS_OPTICAL_10G_Q_ER: + return snprintf(result, lmax, TRANSVR_IF_SP_10G); + /* 10G Copper */ + case TRANSVR_CLASS_COPPER_L4_10G: + return snprintf(result, lmax, TRANSVR_IF_SP_10G); + /* Optical */ + case TRANSVR_CLASS_OPTICAL: + break; + /* Copper */ + case TRANSVR_CLASS_COPPER: + break; + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined class case:%d", + detect_val); + goto err_qsfp_detect_if_speed_1; + } + /* Check br and extbr */ + detect_val = _qsfp_detect_if_sp_by_br(self); + switch(detect_val) { + case TRANSVR_CLASS_UNSPECIFIED: + break; + case TRANSVR_CLASS_10G: + return snprintf(result, lmax, TRANSVR_IF_SP_10G); + case TRANSVR_CLASS_40G: + return snprintf(result, lmax, TRANSVR_IF_SP_40G); + case TRANSVR_CLASS_100G: + return snprintf(result, lmax, TRANSVR_IF_SP_100G); + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined BR case:%d", + detect_val); + goto err_qsfp_detect_if_speed_1; + } + /* Exception case: Can't verify */ + snprintf(err_msg, sizeof(err_msg), "Can not identify!"); + goto err_qsfp_detect_if_speed_1; + +err_qsfp_detect_if_speed_1: + snprintf(result, lmax, TRANSVR_UEVENT_UNKNOW); + SWPS_INFO("%s: %s :%s\n", __func__, err_msg, self->swp_name); + return ERR_TRANSVR_ABNORMAL; +} + + +int +qsfp_get_if_speed(struct transvr_obj_s *self, + char *buf_p){ + + int lmax = 16; + char tmp_result[16] = DEBUG_TRANSVR_STR_VAL; + + if (self->state != STATE_TRANSVR_CONNECTED) { + return snprintf(buf_p, lmax, "%d\n", self->state); + } + if (_qsfp_detect_if_speed(self, tmp_result) < 0) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_ABNORMAL); + } + return snprintf(buf_p, lmax, "%s\n", tmp_result); +} + + +int +_common_set_lane_map_str(struct transvr_obj_s* self, + char *result) { + int i = 0; + int tmp_val = 0; + char tmp_str[LEN_TRANSVR_L_STR] = DEBUG_TRANSVR_STR_VAL; + char err_msg[LEN_TRANSVR_L_STR] = DEBUG_TRANSVR_STR_VAL; + + memset(result, 0, LEN_TRANSVR_L_STR); + snprintf(result, LEN_TRANSVR_L_STR, "%s=", TRANSVR_UEVENT_KEY_LANE); + + for (i=0; ilane_id); i++) { + tmp_val = self->lane_id[i]; + if (tmp_val < 1) { + break; + } + if (tmp_val > 256) { + snprintf(err_msg, sizeof(err_msg), + "detect abnormal value:%d", tmp_val); + goto err_common_set_lane_map_str_1; + } + memset(tmp_str, 0, sizeof(tmp_str)); + if (i == 0) { + snprintf(tmp_str, LEN_TRANSVR_L_STR, "%d", tmp_val); + } else { + snprintf(tmp_str, LEN_TRANSVR_L_STR, ",%d", tmp_val); + } + strncat(result, tmp_str, LEN_TRANSVR_L_STR); + } + if (i == 0) { + goto err_common_set_lane_map_str_2; + } + return 0; + +err_common_set_lane_map_str_1: + SWPS_INFO("%s: %s", __func__, err_msg); +err_common_set_lane_map_str_2: + snprintf(result, LEN_TRANSVR_L_STR, "%s=%s", TRANSVR_UEVENT_KEY_LANE, TRANSVR_UEVENT_UNKNOW); + return EVENT_TRANSVR_TASK_FAIL; +} + + +int +_common_send_uevent(struct transvr_obj_s* self, + enum kobject_action u_action, + int (*detect_if_type)(struct transvr_obj_s *self, char *result), + int (*detect_if_speed)(struct transvr_obj_s *self, char *result), + int send_anyway) { + + char *uevent_envp[4]; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + char tmp_str[32] = DEBUG_TRANSVR_STR_VAL; + char tmp_str_1[32] = DEBUG_TRANSVR_STR_VAL; + char tmp_str_2[32] = DEBUG_TRANSVR_STR_VAL; + char tmp_str_3[64] = DEBUG_TRANSVR_STR_VAL; + + if (TRANSVR_UEVENT_ENABLE != 1) { + return ERR_TRANSVR_NOTSUPPORT; + } + if (_common_get_if_lane(self, tmp_str) < 0) { + snprintf(tmp_str_3, sizeof(tmp_str_3), + "%s=%s", TRANSVR_UEVENT_KEY_LANE, TRANSVR_UEVENT_UNKNOW); + } else { + snprintf(tmp_str_3, sizeof(tmp_str_3), + "%s=%s", TRANSVR_UEVENT_KEY_LANE, tmp_str); + } + switch (u_action) { + case KOBJ_ADD: + /* Detect type */ + if (detect_if_type(self, tmp_str) < 0) { + snprintf(err_msg, sizeof(err_msg), "%s", "Detect interface type fail!"); + snprintf(tmp_str_1, sizeof(tmp_str_1), "%s=%s", TRANSVR_UEVENT_KEY_IF, TRANSVR_UEVENT_UNKNOW); + snprintf(tmp_str_2, sizeof(tmp_str_2), "%s=%s", TRANSVR_UEVENT_KEY_SP, TRANSVR_UEVENT_UNKNOW); + uevent_envp[0] = tmp_str_1; + uevent_envp[1] = tmp_str_2; + uevent_envp[2] = tmp_str_3; + uevent_envp[3] = NULL; + goto private_common_send_uevent_4_fail; + } + snprintf(tmp_str_1, sizeof(tmp_str_1), "%s=%s", TRANSVR_UEVENT_KEY_IF, tmp_str); + uevent_envp[0] = tmp_str_1; + /* Detect speed */ + if (detect_if_speed(self, tmp_str) < 0) { + snprintf(err_msg, sizeof(err_msg), "%s", "Detect interface speed fail!"); + snprintf(tmp_str_2, sizeof(tmp_str_2), "%s=%s", TRANSVR_UEVENT_KEY_SP, TRANSVR_UEVENT_UNKNOW); + uevent_envp[1] = tmp_str_2; + uevent_envp[2] = tmp_str_3; + uevent_envp[3] = NULL; + goto private_common_send_uevent_4_fail; + } + snprintf(tmp_str_2, sizeof(tmp_str_2), "%s=%s", TRANSVR_UEVENT_KEY_SP, tmp_str); + uevent_envp[1] = tmp_str_2; + uevent_envp[2] = tmp_str_3; + uevent_envp[3] = NULL; + goto private_common_send_uevent_4_send; + + case KOBJ_REMOVE: + snprintf(tmp_str_1, sizeof(tmp_str_1), "%s=%s", TRANSVR_UEVENT_KEY_IF, TRANSVR_UEVENT_UNKNOW); + snprintf(tmp_str_2, sizeof(tmp_str_2), "%s=%s", TRANSVR_UEVENT_KEY_SP, TRANSVR_UEVENT_UNKNOW); + uevent_envp[0] = tmp_str_1; + uevent_envp[1] = tmp_str_2; + uevent_envp[2] = tmp_str_3; + uevent_envp[3] = NULL; + goto private_common_send_uevent_4_send; + + default: + snprintf(err_msg, sizeof(err_msg), "kobject_action:%d not support", u_action); + goto private_common_send_uevent_4_fail; + } + snprintf(err_msg, sizeof(err_msg), "%s", "Exception case"); + goto private_common_send_uevent_4_fail; + +private_common_send_uevent_4_fail: + SWPS_INFO("%s: %s :%s\n", __func__, err_msg, self->swp_name); + if (send_anyway) { + goto private_common_send_uevent_4_send; + } + return ERR_TRANSVR_UEVENT_FAIL; + +private_common_send_uevent_4_send: + return kobject_uevent_env(&(self->transvr_dev_p->kobj), + u_action, + uevent_envp); +} + +int +sfp_send_uevent(struct transvr_obj_s* self, + enum kobject_action u_action) { + int send_anyway = 1; + return _common_send_uevent(self, + u_action, + &_sfp_detect_if_type, + &_sfp_detect_if_speed, + send_anyway); +} + + +int +qsfp_send_uevent(struct transvr_obj_s* self, + enum kobject_action u_action) { + int send_anyway = 1; + return _common_send_uevent(self, + u_action, + &_qsfp_detect_if_type, + &_qsfp_detect_if_speed, + send_anyway); +} + + +int +fake_send_uevent(struct transvr_obj_s* self, + enum kobject_action u_action) { + return EVENT_TRANSVR_TASK_DONE; +} + + +int +common_fsm_4_direct_mode(struct transvr_obj_s* self, + char *caller_name){ + + int err; + int detect_result[2]; + int current_state = STATE_TRANSVR_UNEXCEPTED; + int current_type = TRANSVR_TYPE_ERROR; + + if (self->state == STATE_TRANSVR_NEW) { + if (_transvr_init_handler(self) < 0){ + return ERR_TRANSVR_INIT_FAIL; + } + } + err = detect_transvr_state(self, detect_result); + if (err < 0) { + return err; + } + /* In Direct mode, driver only detect transceiver when user call driver interface + * which on sysfs. So it only need consider the state of Transceiver. + */ + current_state = detect_result[0]; + current_type = detect_result[1]; + + switch (current_state){ + + case STATE_TRANSVR_DISCONNECTED: /* Transceiver is not plugged */ + self->state = current_state; + self->type = current_type; + return ERR_TRANSVR_UNPLUGGED; + + case STATE_TRANSVR_INIT: /* Transceiver is plugged, system not ready */ + return ERR_TRANSVR_UNINIT; + + case STATE_TRANSVR_ISOLATED: /* Transceiver is plugged, but has some issues */ + return ERR_TRNASVR_BE_ISOLATED; + + case STATE_TRANSVR_CONNECTED: /* Transceiver is plugged, system is ready */ + self->state = current_state; + self->type = current_type; + return 0; + + case STATE_TRANSVR_SWAPPED: /* Transceiver is plugged, system detect user changed */ + self->type = current_type; + if (reload_transvr_obj(self, current_type) < 0){ + self->state = STATE_TRANSVR_UNEXCEPTED; + return ERR_TRANSVR_UNEXCPT; + } + self->state = current_state; + return 0; + + case STATE_TRANSVR_UNEXCEPTED: /* Transceiver type or state is unexpected case */ + self->state = STATE_TRANSVR_UNEXCEPTED; + self->type = TRANSVR_TYPE_ERROR; + return ERR_TRANSVR_UNEXCPT; + + default: + SWPS_INFO("%s: state:%d not in define.\n", __func__, current_state); + break; + } + return ERR_TRANSVR_UNEXCPT; +} + + +static int +_is_except_happened_4_pmode(struct transvr_obj_s* self, + int new_state) { + + int event_chk = 0; + + if (self->temp == 0){ + return 0; + } + switch (new_state) { + case STATE_TRANSVR_INIT: + event_chk = EVENT_TRANSVR_EXCEP_INIT; + goto check_event_happened_4_pmode; + + case STATE_TRANSVR_CONNECTED: + event_chk = EVENT_TRANSVR_EXCEP_UP; + goto check_event_happened_4_pmode; + + case STATE_TRANSVR_DISCONNECTED: + event_chk = EVENT_TRANSVR_EXCEP_DOWN; + goto check_event_happened_4_pmode; + + case STATE_TRANSVR_SWAPPED: + event_chk = EVENT_TRANSVR_EXCEP_SWAP; + goto check_event_happened_4_pmode; + + case STATE_TRANSVR_UNEXCEPTED: + event_chk = EVENT_TRANSVR_EXCEP_EXCEP; + goto check_event_happened_4_pmode; + + case STATE_TRANSVR_ISOLATED: + event_chk = EVENT_TRANSVR_EXCEP_ISOLATED; + goto check_event_happened_4_pmode; + + default: + SWPS_INFO("%s: unexcepted case:%d\n", __func__, new_state); + break; + } + return 0; + +check_event_happened_4_pmode: + if (self->temp == event_chk){ + return 1; + } + return 0; +} + + +int +common_fsm_4_polling_mode(struct transvr_obj_s* self, + char *caller_name){ + /* [Return Value]: + * ERR_TRANSVR_UNINIT : (1) Initial not ready + * ERR_TRANSVR_UNPLUGGED : (1) Any -> Down + * ERR_TRANSVR_TASK_BUSY : (1) Wait Initial task + * ERR_TRANSVR_UNEXCPT : (1) Initial fail + * (2) Task fail + * (3) Reload fail + * ERR_TRNASVR_BE_ISOLATED : (1) Already be isolated + * OK Case (return 0) : (1) action_4_connected + * (2) action_4_nothing (initial retry) + */ + int curr_state[2]; + int old_state = self->state; + int old_type = self->type; + int new_state = STATE_TRANSVR_UNEXCEPTED; + int new_type = TRANSVR_TYPE_ERROR; + int return_val = ERR_TRANSVR_UNEXCPT; + + /* Never initial */ + if (self->state == STATE_TRANSVR_NEW) { + goto comfsm_action_4_reinit_obj; + } + /* Detect current state */ + switch (detect_transvr_state(self, curr_state)) { + case 0: + new_state = curr_state[0]; + new_type = curr_state[1]; + break; + + case ERR_TRNASVR_BE_ISOLATED: + new_state = STATE_TRANSVR_ISOLATED; + new_type = old_type; + break; + + case ERR_TRANSVR_I2C_CRASH: + goto comfsm_action_4_report_i2c_crash; + + case ERR_TRANSVR_UNEXCPT: + default: + new_state = STATE_TRANSVR_UNEXCEPTED; + new_type = old_type; + } + /* State handling */ + switch (old_state) { + case STATE_TRANSVR_INIT: /* INIT -> */ + return_val = ERR_TRANSVR_UNINIT; + goto comfsm_action_4_keep_state; + + case STATE_TRANSVR_CONNECTED: + switch (new_state) { + case STATE_TRANSVR_INIT: /* Case 1-1: UP -> INIT */ + SWPS_INFO("Detect %s is present. :1-1\n",self->swp_name); + return_val = ERR_TRANSVR_UNINIT; + goto comfsm_action_4_keep_state; + + case STATE_TRANSVR_CONNECTED: /* Case 1-2: UP -> UP */ + return_val = 0; + goto comfsm_action_4_keep_state; + + case STATE_TRANSVR_DISCONNECTED: /* Case 1-3: UP -> DOWN */ + SWPS_INFO("Detect %s is removed. :1-3\n",self->swp_name); + goto comfsm_action_4_disconnected; + + case STATE_TRANSVR_SWAPPED: /* Case 1-4: UP -> SWAP */ + SWPS_INFO("Detect %s is swapped. :1-4\n",self->swp_name); + goto comfsm_action_4_reload_obj; + + case STATE_TRANSVR_UNEXCEPTED: /* Case 1-5: UP -> UNEXPET */ + SWPS_INFO("Detect %s has error. :1-5\n",self->swp_name); + goto comfsm_action_4_unexpected; + + case STATE_TRANSVR_ISOLATED: /* Case 1-6: UP -> ISOLATE */ + SWPS_INFO("Detect %s be isolated. :1-6\n",self->swp_name); + goto comfsm_action_4_isolate_obj; + + default: + break; + } + goto comfsm_action_4_unexpected; + + case STATE_TRANSVR_DISCONNECTED: + switch (new_state) { + case STATE_TRANSVR_INIT: /* Case 2-1: DOWN -> INIT */ + SWPS_INFO("Detect %s is present. :2-1\n",self->swp_name); + return_val = ERR_TRANSVR_UNINIT; + goto comfsm_action_4_keep_state; + + case STATE_TRANSVR_CONNECTED: /* Case 2-2: DOWN -> UP */ + SWPS_INFO("Detect %s is present. :2-2\n",self->swp_name); + goto comfsm_action_4_reinit_obj; + + case STATE_TRANSVR_DISCONNECTED: /* Case 2-3: DOWN -> DOWN */ + return_val = ERR_TRANSVR_UNPLUGGED; + goto comfsm_action_4_keep_state; + + case STATE_TRANSVR_SWAPPED: /* Case 2-4: DOWN -> SWAP */ + SWPS_INFO("Detect %s is swapped. :2-4\n",self->swp_name); + goto comfsm_action_4_reload_obj; + + case STATE_TRANSVR_UNEXCEPTED: /* Case 2-5: DOWN -> UNEXPET */ + SWPS_INFO("Detect %s has error. :2-5\n",self->swp_name); + goto comfsm_action_4_unexpected; + + case STATE_TRANSVR_ISOLATED: /* Case 2-6: DOWN -> ISOLATE */ + SWPS_INFO("Detect %s be isolated. :2-6\n",self->swp_name); + goto comfsm_action_4_isolate_obj; + + default: + break; + } + goto comfsm_action_4_unexpected; + + case STATE_TRANSVR_UNEXCEPTED: + /* Filter out re-action */ + if (_is_except_happened_4_pmode(self, new_state)) { + goto comfsm_action_4_keep_state; + } + /* First action */ + switch (new_state) { + case STATE_TRANSVR_INIT: /* Case 3-1: UNEXPET -> INIT */ + SWPS_INFO("Detect %s is present. :3-1\n",self->swp_name); + self->temp = EVENT_TRANSVR_EXCEP_INIT; + return_val = ERR_TRANSVR_UNINIT; + goto comfsm_action_4_keep_state; + + case STATE_TRANSVR_CONNECTED: /* Case 3-2: UNEXPET -> UP */ + SWPS_INFO("Detect %s is present. :3-2\n",self->swp_name); + self->temp = EVENT_TRANSVR_EXCEP_UP; + goto comfsm_action_4_reload_obj; + + case STATE_TRANSVR_DISCONNECTED: /* Case 3-3: UNEXPET -> DOWN */ + SWPS_INFO("Detect %s is removed. :3-3\n",self->swp_name); + goto comfsm_action_4_disconnected; + + case STATE_TRANSVR_SWAPPED: /* Case 3-4: UNEXPET -> SWAP */ + SWPS_INFO("Detect %s is swapped. :3-4\n",self->swp_name); + self->temp = EVENT_TRANSVR_EXCEP_SWAP; + goto comfsm_action_4_reload_obj; + + case STATE_TRANSVR_UNEXCEPTED: /* Case 3-5: UNEXPET -> UNEXPET */ + self->temp = EVENT_TRANSVR_EXCEP_EXCEP; + return_val = ERR_TRANSVR_UNEXCPT; + goto comfsm_action_4_keep_state; + + case STATE_TRANSVR_ISOLATED: /* Case 3-6: UNEXPET -> ISOLATE */ + SWPS_INFO("Detect %s be isolated. :3-6\n",self->swp_name); + goto comfsm_action_4_isolate_obj; + + default: + break; + } + goto comfsm_action_4_unexpected; + + case STATE_TRANSVR_ISOLATED: + /* Filter out re-action */ + if (_is_except_happened_4_pmode(self, new_state)) { + goto comfsm_action_4_keep_state; + } + /* First action */ + switch (new_state) { + case STATE_TRANSVR_INIT: /* Case 4-1: ISOLATE -> INIT */ + SWPS_INFO("Detect %s internal error. :4-1\n",self->swp_name); + self->temp = EVENT_TRANSVR_EXCEP_INIT; + return_val = ERR_TRNASVR_BE_ISOLATED; + goto comfsm_action_4_keep_state; + + case STATE_TRANSVR_CONNECTED: /* Case 4-2: ISOLATE -> UP */ + SWPS_INFO("Detect %s internal error. :4-2\n",self->swp_name); + self->temp = EVENT_TRANSVR_EXCEP_UP; + return_val = ERR_TRNASVR_BE_ISOLATED; + goto comfsm_action_4_keep_state; + + case STATE_TRANSVR_DISCONNECTED: /* Case 4-3: ISOLATE -> DOWN */ + SWPS_INFO("Detect %s is removed. :4-3\n",self->swp_name); + goto comfsm_action_4_disconnected; + + case STATE_TRANSVR_SWAPPED: /* Case 4-4: ISOLATE -> SWAP */ + SWPS_INFO("Detect %s internal error. :4-4\n",self->swp_name); + self->temp = EVENT_TRANSVR_EXCEP_SWAP; + return_val = ERR_TRNASVR_BE_ISOLATED; + goto comfsm_action_4_keep_state; + + case STATE_TRANSVR_UNEXCEPTED: /* Case 4-5: ISOLATE -> UNEXPET */ + SWPS_INFO("Detect %s internal error. :4-5\n",self->swp_name); + self->temp = EVENT_TRANSVR_EXCEP_EXCEP; + return_val = ERR_TRNASVR_BE_ISOLATED; + goto comfsm_action_4_keep_state; + + case STATE_TRANSVR_ISOLATED: /* Case 4-6: ISOLATE -> ISOLATE */ + return_val = ERR_TRNASVR_BE_ISOLATED; + goto comfsm_action_4_keep_state; + + default: + break; + } + goto comfsm_action_4_unexpected; + + default: + break; + } + goto comfsm_action_4_unexpected; + + +comfsm_action_4_keep_state: + return return_val; + +comfsm_action_4_reinit_obj: + SWPS_DEBUG("FSM action: %s re-initial.\n", self->swp_name); + return_val = _transvr_init_handler(self); + goto comfsm_action_4_identify_event; + +comfsm_action_4_reload_obj: + SWPS_DEBUG("FSM action: %s reload.\n", self->swp_name); + self->type = new_type; + return_val = reload_transvr_obj(self, new_type); + goto comfsm_action_4_identify_event; + +comfsm_action_4_identify_event: + switch (return_val) { + case EVENT_TRANSVR_INIT_UP: + case EVENT_TRANSVR_TASK_DONE: + goto comfsm_action_4_connected; + + case EVENT_TRANSVR_INIT_DOWN: + goto comfsm_action_4_disconnected; + + case EVENT_TRANSVR_INIT_REINIT: + goto comfsm_action_4_nothing; + + case EVENT_TRANSVR_TASK_WAIT: + self->state = STATE_TRANSVR_INIT; + return ERR_TRANSVR_TASK_BUSY; + + case EVENT_TRANSVR_TASK_FAIL: + SWPS_INFO("%s detect EVENT_TRANSVR_TASK_FAIL.\n", self->swp_name); + goto comfsm_action_4_unexpected; + + case EVENT_TRANSVR_INIT_FAIL: + SWPS_INFO("%s detect EVENT_TRANSVR_INIT_FAIL.\n", self->swp_name); + goto comfsm_action_4_unexpected; + + case EVENT_TRANSVR_RELOAD_FAIL: + SWPS_INFO("%s detect EVENT_TRANSVR_RELOAD_FAIL.\n", self->swp_name); + goto comfsm_action_4_unexpected; + + case EVENT_TRANSVR_I2C_CRASH: + goto comfsm_action_4_report_i2c_crash; + + case EVENT_TRANSVR_EXCEP_ISOLATED: + goto comfsm_action_4_isolate_obj; + + default: + SWPS_INFO("%s detect undefined event:%d.\n", self->swp_name, return_val); + goto comfsm_action_4_unexpected; + } + +comfsm_action_4_nothing: + SWPS_DEBUG("FSM action: %s do nothing.\n", self->swp_name); + return 0; + +comfsm_action_4_connected: + SWPS_DEBUG("FSM action: %s Connected.\n", self->swp_name); + self->state = STATE_TRANSVR_CONNECTED; + self->type = new_type; + self->send_uevent(self, KOBJ_ADD); + _transvr_clean_retry(self); + return 0; + +comfsm_action_4_disconnected: + SWPS_DEBUG("FSM action: %s Disconnected. \n", self->swp_name); + self->state = STATE_TRANSVR_DISCONNECTED; + self->temp = EVENT_TRANSVR_TASK_DONE; + self->send_uevent(self, KOBJ_REMOVE); + _transvr_clean_retry(self); + _transvr_clean_handler(self); + return ERR_TRANSVR_UNPLUGGED; + +comfsm_action_4_report_i2c_crash: + SWPS_DEBUG("FSM action: %s report I2C crash.\n", self->swp_name); + self->state = STATE_TRANSVR_UNEXCEPTED; + return ERR_TRANSVR_I2C_CRASH; + +comfsm_action_4_isolate_obj: + SWPS_DEBUG("FSM action: %s isolate.\n", self->swp_name); + self->state = STATE_TRANSVR_ISOLATED; + return ERR_TRNASVR_BE_ISOLATED; + +comfsm_action_4_unexpected: + SWPS_INFO("FSM action: %s unexpected.\n", self->swp_name); + SWPS_INFO("Dump: :%d :0x%02x :%d :0x%02x\n", + old_state, old_type, new_state, new_type); + self->state = STATE_TRANSVR_UNEXCEPTED; + self->send_uevent(self, KOBJ_REMOVE); + _transvr_clean_handler(self); + return ERR_TRANSVR_UNEXCPT; +} + + +int +fake_fsm_4_direct_mode(struct transvr_obj_s* self, + char *caller_name){ + self->state = STATE_TRANSVR_CONNECTED; + self->type = TRANSVR_TYPE_FAKE; + return 0; +} + + +int +fake_fsm_4_polling_mode(struct transvr_obj_s* self, + char *caller_name){ + self->state = STATE_TRANSVR_CONNECTED; + self->type = TRANSVR_TYPE_FAKE; + return 0; +} + + +/* ========== Object functions for Initial procedure ========== + */ +int +transvr_init_common(struct transvr_obj_s *self){ + /* Nothing to update */ + return EVENT_TRANSVR_TASK_DONE; +} + + +int +transvr_init_fake(struct transvr_obj_s *self){ + return EVENT_TRANSVR_TASK_DONE; +} + + +int +transvr_init_sfp(struct transvr_obj_s *self){ + + int tmp_val = DEBUG_TRANSVR_INT_VAL; + int err_code = DEBUG_TRANSVR_INT_VAL; + char *err_msg = "ERR"; + + self->info = sft_detect_transvr_class(self); + /* Disable auto_config */ + if (!self->auto_config) { + return EVENT_TRANSVR_TASK_DONE; + } + /* Handle multi-rate */ + err_code = initfunc_sfp_handle_multi_rate_mode(self); + if (err_code < 0) { + err_msg = "initfunc_sfp_handle_multi_rate_mode fail!"; + goto err_transvr_init_sfp_1; + } + /* Handle 1G- RJ45 */ + tmp_val = err_code; + err_code = initfunc_sfp_handle_1g_rj45(self); + if (err_code < 0) { + err_msg = "initfunc_sfp_handle_1g_rj45 fail!"; + goto err_transvr_init_sfp_1; + } + tmp_val = (tmp_val > err_code ? tmp_val : err_code); + if (tmp_val > EVENT_TRANSVR_TASK_DONE) { + return tmp_val; + } + return EVENT_TRANSVR_TASK_DONE; + +err_transvr_init_sfp_1: + SWPS_INFO("%s: %s :%d :%s\n", + __func__, err_msg, err_code, self->swp_name); + return EVENT_TRANSVR_INIT_FAIL; +} + + +int +transvr_init_qsfp(struct transvr_obj_s *self){ + + int err = EVENT_TRANSVR_EXCEP_EXCEP; + char *emsg = "ERR"; + + self->info = qsft_detect_transvr_class(self); + if (!self->auto_config) { + return EVENT_TRANSVR_TASK_DONE; + } + err = initfunc_qsfp_handle_power_mode(self); + if (err < 0){ + emsg = "initfunc_qsfp_handle_tx_disable fail!"; + goto err_transvr_init_qsfp; + } + return EVENT_TRANSVR_TASK_DONE; + +err_transvr_init_qsfp: + SWPS_INFO("%s: %s :%d :%s\n", + __func__, emsg, err, self->swp_name); + return EVENT_TRANSVR_INIT_FAIL; +} + + +int +transvr_init_qsfp28(struct transvr_obj_s *self){ + + int tmp_val = EVENT_TRANSVR_EXCEP_EXCEP; + int err_val = EVENT_TRANSVR_EXCEP_EXCEP; + char *err_msg = "ERR"; + + /* Handle QSFP common */ + err_val = transvr_init_qsfp(self); + if (err_val < 0){ + err_msg = "transvr_init_qsfp fail!"; + goto err_transvr_init_qsfp28_1; + } + /* Disable auto_config */ + if (!self->auto_config) { + return err_val; + } + /* Handle CDR */ + tmp_val = err_val; + err_val = initfunc_qsfp28_handle_cdr(self); + if (err_val < 0){ + err_msg = "Handle CDR fail!"; + goto err_transvr_init_qsfp28_1; + } + tmp_val = (tmp_val > err_val ? tmp_val : err_val); + if (tmp_val > EVENT_TRANSVR_TASK_DONE) { + return tmp_val; + } + return EVENT_TRANSVR_TASK_DONE; + +err_transvr_init_qsfp28_1: + SWPS_INFO("%s: %s :%d :%s\n", + __func__, err_msg, err_val, self->swp_name); + return EVENT_TRANSVR_INIT_FAIL; +} + + +/* ========== Object Initial handler ========== + */ +static int +_is_transvr_valid(struct transvr_obj_s *self, + int type, + int state) { + /* [Return] + * 0 : OK, inserted + * EVENT_TRANSVR_INIT_DOWN : OK, removed + * EVENT_TRANSVR_INIT_FAIL : Outside error, type doesn't supported + * EVENT_TRANSVR_EXCEP_INIT : Internal error, state undefined + */ + switch (type) { + case TRANSVR_TYPE_SFP: + case TRANSVR_TYPE_QSFP: + case TRANSVR_TYPE_QSFP_PLUS: + case TRANSVR_TYPE_QSFP_28: + case TRANSVR_TYPE_UNPLUGGED: + case TRANSVR_TYPE_FAKE: + break; + default: + SWPS_INFO("detect undefined type:0x%02x on %s\n", + type, self->swp_name); + return EVENT_TRANSVR_INIT_FAIL; + } + switch (state) { + case STATE_TRANSVR_DISCONNECTED: + return EVENT_TRANSVR_INIT_DOWN; + case STATE_TRANSVR_INIT: + case STATE_TRANSVR_CONNECTED: + case STATE_TRANSVR_SWAPPED: + break; + default: + SWPS_INFO("detect undefined state:%d on %s\n", + state, self->swp_name); + return EVENT_TRANSVR_EXCEP_INIT; + } + return 0; +} + + +static int +_is_transvr_hw_ready(struct transvr_obj_s *self, + int type){ + /* [Return] + * EVENT_TRANSVR_TASK_DONE : Ready + * EVENT_TRANSVR_TASK_WAIT : Not ready + * EVENT_TRANSVR_INIT_FAIL : Error + */ + int addr = DEBUG_TRANSVR_INT_VAL; + int page = DEBUG_TRANSVR_INT_VAL; + int offs = DEBUG_TRANSVR_INT_VAL; + int bit = DEBUG_TRANSVR_INT_VAL; + int ready = DEBUG_TRANSVR_INT_VAL; + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + uint8_t ab_val = DEBUG_TRANSVR_HEX_VAL; + + switch (type) { + case TRANSVR_TYPE_SFP: + addr = VAL_TRANSVR_8472_READY_ADDR; + page = VAL_TRANSVR_8472_READY_PAGE; + offs = VAL_TRANSVR_8472_READY_OFFSET; + bit = VAL_TRANSVR_8472_READY_BIT; + ready = VAL_TRANSVR_8472_READY_VALUE; + ab_val = VAL_TRANSVR_8472_READY_ABNORMAL; + break; + + case TRANSVR_TYPE_QSFP: + case TRANSVR_TYPE_QSFP_PLUS: + case TRANSVR_TYPE_QSFP_28: + addr = VAL_TRANSVR_8436_READY_ADDR; + page = VAL_TRANSVR_8436_READY_PAGE; + offs = VAL_TRANSVR_8436_READY_OFFSET; + bit = VAL_TRANSVR_8436_READY_BIT; + ready = VAL_TRANSVR_8436_READY_VALUE; + ab_val = VAL_TRANSVR_8436_READY_ABNORMAL; + break; + + case TRANSVR_TYPE_UNPLUGGED: + case TRANSVR_TYPE_FAKE: + return EVENT_TRANSVR_TASK_DONE; + + default: + emsg = "unexpected case"; + goto err_is_transvr_hw_ready; + } + /* Select target page */ + err = _common_setup_page(self, addr, page, offs, 1, 0); + if (err < 0) { + emsg = "setup page fail"; + goto err_is_transvr_hw_ready; + } + /* Check feature supported + * [Note] + * Some of transceiver/cables doesn't support "Status Indicators" + * (ex:DAC, RJ45 copper SFP ...etc). In these case, we bypass the + * step of checking Status Indicators, then state machine will take + * the following handle procedure. + */ + err = i2c_smbus_read_byte_data(self->i2c_client_p, + VAL_TRANSVR_COMID_OFFSET); + if (err < 0) { + emsg = "doesn't support Status Indicators"; + goto bypass_is_transvr_hw_ready; + } + /* Filter abnormal case */ + if (err == ab_val) { + emsg = "detect using unusual definition."; + goto bypass_is_transvr_hw_ready; + } + /* Get Status Indicators */ + err = i2c_smbus_read_byte_data(self->i2c_client_p, offs); + if (err < 0) { + emsg = "detect current value fail"; + goto err_is_transvr_hw_ready; + } + + if ((err & (1<:%d\n", __func__, emsg, type); + return EVENT_TRANSVR_TASK_DONE; + +err_is_transvr_hw_ready: + SWPS_DEBUG("%s: %s :%d\n", __func__, emsg, type); + return EVENT_TRANSVR_INIT_FAIL; +} + + +static int +_is_transvr_support_ctle(struct transvr_obj_s *self) { + + switch (self->info) { + case TRANSVR_CLASS_OPTICAL_25G: + case TRANSVR_CLASS_OPTICAL_25G_AOC: + case TRANSVR_CLASS_OPTICAL_25G_SR: + case TRANSVR_CLASS_OPTICAL_25G_LR: + case TRANSVR_CLASS_OPTICAL_25G_ER: + case TRANSVR_CLASS_OPTICAL_100G: + case TRANSVR_CLASS_OPTICAL_100G_AOC: + case TRANSVR_CLASS_OPTICAL_100G_SR4: + case TRANSVR_CLASS_OPTICAL_100G_LR4: + case TRANSVR_CLASS_OPTICAL_100G_ER4: + case TRANSVR_CLASS_OPTICAL_100G_PSM4: + return 1; + default: + break; + } + return 0; +} + + +static int +_transvr_init_handler(struct transvr_obj_s *self){ + + int detect[2]; + int d_state = STATE_TRANSVR_UNEXCEPTED; + int d_type = TRANSVR_TYPE_ERROR; + int result = ERR_TRANSVR_UNINIT; + int retry = 6; /* (6+1) x 0.3 = 2.1s > spec:2.0s */ + int elimit = 63; + char emsg[64] = DEBUG_TRANSVR_STR_VAL; + + /* Clean and check callback */ + self->state = STATE_TRANSVR_INIT; + if (self->init == NULL) { + snprintf(emsg, elimit, "init() is null"); + goto initer_err_case_unexcept_0; + } + if (self->clean == NULL) { + snprintf(emsg, elimit, "clean() is null"); + goto initer_err_case_unexcept_0; + } + self->clean(self); + + /* Detect transceiver information */ + result = detect_transvr_state(self, detect); + if (result < 0) { + snprintf(emsg, elimit, "detect_transvr_state() fail"); + switch (result) { + case ERR_TRANSVR_I2C_CRASH: + goto initer_err_case_i2c_ceash; + case ERR_TRNASVR_BE_ISOLATED: + goto initer_err_case_be_isolated; + + case ERR_TRANSVR_UNEXCPT: + default: + break; + } + goto initer_err_case_retry_1; + } + d_state = detect[0]; + d_type = detect[1]; + + /* Verify transceiver type and state */ + switch (_is_transvr_valid(self, d_type, d_state)) { + case 0: + break; + case EVENT_TRANSVR_INIT_DOWN: + goto initer_ok_case_down;; + case EVENT_TRANSVR_INIT_FAIL: + snprintf(emsg, elimit, "transceiver type doesn't support"); + goto initer_err_case_alarm_to_user; + case EVENT_TRANSVR_EXCEP_INIT: + default: + goto initer_err_case_unexcept_1; + } + + /* Handle reload case */ + if (self->type != d_type){ + /* This is the protect mechanism. Normally, This case will not happen. + * When State machine detect swap event during initial, It will trigger + * reload function to ensure type correct. */ + if (_reload_transvr_obj(self, d_type) < 0){ + snprintf(emsg, elimit, "reload object fail"); + goto initer_err_case_unexcept_1; + } + } + + /* Check transceiver HW initial ready */ + switch (_is_transvr_hw_ready(self, d_type)) { + case EVENT_TRANSVR_TASK_DONE: + break; + case EVENT_TRANSVR_TASK_WAIT: + goto initer_err_case_retry_1; + case EVENT_TRANSVR_INIT_FAIL: + default: + goto initer_err_case_unexcept_1; + } + + /* Try to update all and check */ + if (self->update_all(self, 1) < 0){ + /* For some transceiver, EEPROME has lag issues during initial stage. + * In this case, we set status back to STATE_TRANSVR_NEW, than it will + * be checked in next polling cycle. */ + goto initer_err_case_retry_1; + } + + /* Execute init() call back */ + result = self->init(self); + switch (result) { + case EVENT_TRANSVR_TASK_DONE: + break; + case EVENT_TRANSVR_TASK_WAIT: + goto initer_ok_case_wait; + + default: + snprintf(emsg, elimit, "undefined init() return:%d\n", result); + goto initer_err_case_unexcept_1; + } + goto initer_ok_case_up; + + +initer_ok_case_wait: + self->dump_all(self); + return EVENT_TRANSVR_TASK_WAIT; + +initer_ok_case_up: + self->state = STATE_TRANSVR_CONNECTED; + self->temp = 0; + self->dump_all(self); + return EVENT_TRANSVR_INIT_UP; + +initer_ok_case_down: + self->temp = 0; + self->state = STATE_TRANSVR_DISCONNECTED; + return EVENT_TRANSVR_INIT_DOWN; + +initer_err_case_i2c_ceash: + SWPS_DEBUG("%s: %s :%s :I2C crash\n", + __func__, emsg, self->swp_name); + self->state = STATE_TRANSVR_UNEXCEPTED; + return EVENT_TRANSVR_I2C_CRASH; + +initer_err_case_be_isolated: + SWPS_DEBUG("%s: %s :%s :isolated\n", + __func__, emsg, self->swp_name); + self->state = STATE_TRANSVR_ISOLATED; + return EVENT_TRANSVR_EXCEP_ISOLATED; + +initer_err_case_retry_1: + SWPS_DEBUG("%s: %s :%s :retry\n", + __func__, emsg, self->swp_name); + if (_transvr_handle_retry(self, retry) == 0) { + self->state = STATE_TRANSVR_NEW; + return EVENT_TRANSVR_INIT_REINIT; + } + goto initer_err_case_alarm_to_user; + +initer_err_case_unexcept_1: + self->clean(self); +initer_err_case_unexcept_0: + self->state = STATE_TRANSVR_UNEXCEPTED; + if (_is_except_happened_4_pmode(self, d_state) && + (self->mode == TRANSVR_MODE_POLLING) ){ + SWPS_INFO("%s: %s :%s\n", __func__, emsg, self->swp_name); + SWPS_INFO("Dump: :%d :%d :%d :%d\n", + self->state, self->type, d_state, d_type); + } + return EVENT_TRANSVR_INIT_FAIL; + +initer_err_case_alarm_to_user: + SWPS_DEBUG("%s: %s :%s :alarm_to_user\n", + __func__, emsg, self->swp_name); + self->state = STATE_TRANSVR_UNEXCEPTED; + alarm_msg_2_user(self, "detected transceiver/cables not meet SFF standard"); + return EVENT_TRANSVR_INIT_FAIL; +} + + +/* ========== Object functions for Clean procedure ========== + */ +int +_transvr_clean_handler(struct transvr_obj_s *self){ + + int retval = DEBUG_TRANSVR_INT_VAL; + + if (!self->clean) { + SWPS_ERR("%s: %s clean() is NULL.\n", + __func__, self->swp_name); + return EVENT_TRANSVR_TASK_FAIL; + } + retval = self->clean(self); + if (retval != EVENT_TRANSVR_TASK_DONE){ + SWPS_ERR("%s: %s clean() fail. [ERR]:%d\n", + __func__, self->swp_name, retval); + return retval; + } + return EVENT_TRANSVR_TASK_DONE; +} + + +int +common_transvr_clean(struct transvr_obj_s *self){ + + transvr_task_free_all(self); + transvr_cache_free_all(self); + return EVENT_TRANSVR_TASK_DONE; +} + + +int +qsfp_transvr_clean(struct transvr_obj_s *self){ + + int retval; + int lpower_config = 1; + + retval = _taskfunc_qsfp_setup_power_mod(self, lpower_config); + if (retval < 0){ + SWPS_ERR("%s: Set lpmod fail! :%d\n", + __func__, retval); + return retval; + } + retval = common_transvr_clean(self); + if (retval < 0){ + SWPS_ERR("%s: common_transvr_clean fail! :%d\n", + __func__, retval); + return retval; + } + return EVENT_TRANSVR_TASK_DONE; +} + + +int +fake_transvr_clean(struct transvr_obj_s *self){ + + return EVENT_TRANSVR_TASK_DONE; +} + + +/* ========== Object functions for check and update ========== + */ +int +common_transvr_check(struct transvr_obj_s *self){ + + char fun_str[32] = "common_transvr_check"; + + if (self->mode != TRANSVR_MODE_POLLING) { + SWPS_ERR("%s: mode:%d is not TRANSVR_MODE_POLLING\n", + fun_str, self->mode); + return ERR_TRANSVR_UNEXCPT; + } + /* Trigger delay task */ + transvr_task_run_all(self); + /* Trigger state machine to check and update */ + return self->fsm_4_polling(self, fun_str); +} + + +int +fake_transvr_check(struct transvr_obj_s *self){ + return 0; +} + + +/* ========== Functions for Factory pattern ========== + */ +static int +setup_transvr_public_cb(struct transvr_obj_s *self, + int transvr_type){ + switch (transvr_type){ + case TRANSVR_TYPE_SFP: + self->get_id = common_get_id; + self->get_ext_id = common_get_ext_id; + self->get_connector = common_get_connector; + self->get_vendor_name = common_get_vendor_name; + self->get_vendor_pn = common_get_vendor_pn; + self->get_vendor_rev = common_get_vendor_rev; + self->get_vendor_sn = common_get_vendor_sn; + self->get_power_cls = unsupported_get_func; + self->get_br = common_get_br; + self->get_len_sm = sfp_get_len_sm; + self->get_len_smf = common_get_len_smf; + self->get_len_om1 = common_get_len_om1; + self->get_len_om2 = common_get_len_om2; + self->get_len_om3 = common_get_len_om3; + self->get_len_om4 = common_get_len_om4; + self->get_comp_rev = common_get_comp_rev; + self->get_comp_eth_1 = sfp_get_comp_eth_1; + self->get_comp_eth_10 = sfp_get_comp_eth_10; + self->get_comp_eth_10_40 = unsupported_get_func; + self->get_comp_extend = common_get_comp_extended; + self->get_cdr = unsupported_get_func; + self->get_rate_id = sfp_get_rate_id; + self->get_soft_rs0 = sfp_get_soft_rs0; + self->get_soft_rs1 = sfp_get_soft_rs1; + self->get_info = common_get_info; + self->get_if_type = sfp_get_if_type; + self->get_if_speed = sfp_get_if_speed; + self->get_if_lane = common_get_if_lane; + self->get_curr_temp = sfp_get_transvr_temp; + self->get_curr_vol = sfp_get_transvr_voltage; + self->get_soft_rx_los = unsupported_get_func2; + self->get_soft_tx_disable = unsupported_get_func2; + self->get_soft_tx_fault = unsupported_get_func2; + self->get_auto_tx_disable = unsupported_get_func2; + self->get_tx_bias = sfp_get_transvr_tx_bias; + self->get_tx_power = sfp_get_transvr_tx_power; + self->get_rx_power = sfp_get_transvr_rx_power; + self->get_tx_eq = sfp_get_transvr_tx_eq; + self->get_rx_am = unsupported_get_func2; + self->get_rx_em = sfp_get_transvr_rx_em; + self->get_wavelength = sfp_get_wavelength; + self->get_extphy_offset = sfp_get_1g_rj45_extphy_offset; + self->get_extphy_reg = sfp_get_1g_rj45_extphy_reg; + self->set_cdr = unsupported_set_func; + self->set_soft_rs0 = sfp_set_soft_rs0; + self->set_soft_rs1 = sfp_set_soft_rs1; + self->set_soft_tx_disable = unsupported_set_func; + self->set_auto_tx_disable = unsupported_set_func; + self->set_tx_eq = sfp_set_tx_eq; + self->set_rx_am = unsupported_set_func; + self->set_rx_em = sfp_set_rx_em; + self->set_extphy_offset = sfp_set_1g_rj45_extphy_offset; + self->set_extphy_reg = sfp_set_1g_rj45_extphy_reg; + return 0; + + case TRANSVR_TYPE_QSFP: + case TRANSVR_TYPE_QSFP_PLUS: + self->get_id = common_get_id; + self->get_ext_id = common_get_ext_id; + self->get_connector = common_get_connector; + self->get_vendor_name = common_get_vendor_name; + self->get_vendor_pn = common_get_vendor_pn; + self->get_vendor_rev = common_get_vendor_rev; + self->get_vendor_sn = common_get_vendor_sn; + self->get_power_cls = qsfp_get_power_cls; + self->get_br = common_get_br; + self->get_len_sm = unsupported_get_func; + self->get_len_smf = common_get_len_smf; + self->get_len_om1 = common_get_len_om1; + self->get_len_om2 = common_get_len_om2; + self->get_len_om3 = common_get_len_om3; + self->get_len_om4 = common_get_len_om4; + self->get_comp_rev = common_get_comp_rev; + self->get_comp_eth_1 = qsfp_get_comp_eth; + self->get_comp_eth_10 = unsupported_get_func; + self->get_comp_eth_10_40 = qsfp_get_comp_10_40; + self->get_comp_extend = common_get_comp_extended; + self->get_cdr = unsupported_get_func; + self->get_rate_id = unsupported_get_func; + self->get_soft_rs0 = unsupported_get_func; /* TBD */ + self->get_soft_rs1 = unsupported_get_func; /* TBD */ + self->get_info = common_get_info; + self->get_if_type = qsfp_get_if_type; + self->get_if_speed = qsfp_get_if_speed; + self->get_if_lane = common_get_if_lane; + self->get_curr_temp = qsfp_get_transvr_temp; + self->get_curr_vol = qsfp_get_transvr_voltage; + self->get_soft_rx_los = qsfp_get_soft_rx_los; + self->get_soft_tx_disable = qsfp_get_soft_tx_disable; + self->get_soft_tx_fault = qsfp_get_soft_tx_fault; + self->get_auto_tx_disable = qsfp_get_auto_tx_disable; + self->get_tx_bias = qsfp_get_transvr_tx_bias; + self->get_tx_power = qsfp_get_transvr_tx_power; + self->get_rx_power = qsfp_get_transvr_rx_power; + self->get_tx_eq = unsupported_get_func2; + self->get_rx_am = unsupported_get_func2; + self->get_rx_em = unsupported_get_func2; + self->get_wavelength = qsfp_get_wavelength; + self->get_extphy_offset = unsupported_get_func2; + self->get_extphy_reg = unsupported_get_func2; + self->set_cdr = unsupported_set_func; + self->set_soft_rs0 = unsupported_set_func; /* TBD */ + self->set_soft_rs1 = unsupported_set_func; /* TBD */ + self->set_soft_tx_disable = qsfp_set_soft_tx_disable; + self->set_auto_tx_disable = qsfp_set_auto_tx_disable; + self->set_tx_eq = unsupported_set_func; + self->set_rx_am = unsupported_set_func; + self->set_rx_em = unsupported_set_func; + self->set_extphy_offset = unsupported_set_func; + self->set_extphy_reg = unsupported_set_func; + return 0; + + case TRANSVR_TYPE_QSFP_28: + self->get_id = common_get_id; + self->get_ext_id = common_get_ext_id; + self->get_connector = common_get_connector; + self->get_vendor_name = common_get_vendor_name; + self->get_vendor_pn = common_get_vendor_pn; + self->get_vendor_rev = common_get_vendor_rev; + self->get_vendor_sn = common_get_vendor_sn; + self->get_power_cls = qsfp_get_power_cls; + self->get_br = common_get_br; + self->get_len_sm = unsupported_get_func; + self->get_len_smf = common_get_len_smf; + self->get_len_om1 = common_get_len_om1; + self->get_len_om2 = common_get_len_om2; + self->get_len_om3 = common_get_len_om3; + self->get_len_om4 = common_get_len_om4; + self->get_comp_rev = common_get_comp_rev; + self->get_comp_eth_1 = qsfp_get_comp_eth; + self->get_comp_eth_10 = unsupported_get_func; + self->get_comp_eth_10_40 = qsfp_get_comp_10_40; + self->get_comp_extend = common_get_comp_extended; + self->get_cdr = qsfp_get_cdr; + self->get_rate_id = unsupported_get_func; + self->get_soft_rs0 = unsupported_get_func; /* TBD */ + self->get_soft_rs1 = unsupported_get_func; /* TBD */ + self->get_info = common_get_info; + self->get_if_type = qsfp_get_if_type; + self->get_if_speed = qsfp_get_if_speed; + self->get_if_lane = common_get_if_lane; + self->get_curr_temp = qsfp_get_transvr_temp; + self->get_curr_vol = qsfp_get_transvr_voltage; + self->get_soft_rx_los = qsfp_get_soft_rx_los; + self->get_soft_tx_disable = qsfp_get_soft_tx_disable; + self->get_soft_tx_fault = qsfp_get_soft_tx_fault; + self->get_auto_tx_disable = qsfp_get_auto_tx_disable; + self->get_tx_bias = qsfp_get_transvr_tx_bias; + self->get_tx_power = qsfp_get_transvr_tx_power; + self->get_rx_power = qsfp_get_transvr_rx_power; + self->get_tx_eq = qsfp_get_transvr_tx_eq; + self->get_rx_am = qsfp_get_transvr_rx_am; + self->get_rx_em = qsfp_get_transvr_rx_em; + self->get_wavelength = qsfp_get_wavelength; + self->get_extphy_offset = unsupported_get_func2; + self->get_extphy_reg = unsupported_get_func2; + self->set_cdr = qsfp_set_cdr; + self->set_soft_rs0 = unsupported_set_func; /* TBD */ + self->set_soft_rs1 = unsupported_set_func; /* TBD */ + self->set_soft_tx_disable = qsfp_set_soft_tx_disable; + self->set_auto_tx_disable = qsfp_set_auto_tx_disable; + self->set_tx_eq = qsfp_set_tx_eq; + self->set_rx_am = qsfp_set_rx_am; + self->set_rx_em = qsfp_set_rx_em; + self->set_extphy_offset = unsupported_set_func; + self->set_extphy_reg = unsupported_set_func; + return 0; + + case TRANSVR_TYPE_FAKE: + self->get_id = fake_get_hex; + self->get_ext_id = fake_get_hex; + self->get_connector = fake_get_hex; + self->get_vendor_name = fake_get_str; + self->get_vendor_pn = fake_get_str; + self->get_vendor_rev = fake_get_str; + self->get_vendor_sn = fake_get_str; + self->get_power_cls = fake_get_int; + self->get_br = fake_get_hex; + self->get_len_sm = fake_get_int; + self->get_len_smf = fake_get_int; + self->get_len_om1 = fake_get_int; + self->get_len_om2 = fake_get_int; + self->get_len_om3 = fake_get_int; + self->get_len_om4 = fake_get_int; + self->get_comp_rev = fake_get_hex; + self->get_comp_eth_1 = fake_get_hex; + self->get_comp_eth_10 = fake_get_hex; + self->get_comp_eth_10_40 = fake_get_hex; + self->get_comp_extend = fake_get_hex; + self->get_cdr = fake_get_hex; + self->get_rate_id = fake_get_hex; + self->get_soft_rs0 = fake_get_binary; + self->get_soft_rs1 = fake_get_binary; + self->get_info = fake_get_int; + self->get_if_type = fake_get_str; + self->get_if_speed = fake_get_str; + self->get_if_lane = fake_get_str; + self->get_curr_temp = fake_get_str; + self->get_curr_vol = fake_get_str; + self->get_soft_rx_los = fake_get_str; + self->get_soft_tx_disable = fake_get_str; + self->get_soft_tx_fault = fake_get_str; + self->get_auto_tx_disable = fake_get_str; + self->get_tx_bias = fake_get_str; + self->get_tx_power = fake_get_str; + self->get_rx_power = fake_get_str; + self->get_tx_eq = fake_get_str; + self->get_rx_am = fake_get_str; + self->get_rx_em = fake_get_str; + self->get_wavelength = fake_get_str; + self->get_extphy_offset = fake_get_str; + self->get_extphy_reg = fake_get_str; + self->set_cdr = fake_set_hex; + self->set_soft_rs0 = fake_set_int; + self->set_soft_rs1 = fake_set_int; + self->set_soft_tx_disable = fake_set_int; + self->set_auto_tx_disable = fake_set_int; + self->set_tx_eq = fake_set_int; + self->set_rx_am = fake_set_int; + self->set_rx_em = fake_set_int; + self->set_extphy_offset = fake_set_hex; + self->set_extphy_reg = fake_set_hex; + return 0; + + default: + break; + } + SWPS_WARN("%s: Detect non-defined type:%d\n", __func__, transvr_type); + return ERR_TRANSVR_UNEXCPT; +} + + +static int +setup_transvr_private_cb(struct transvr_obj_s *self, + int transvr_type){ + switch (transvr_type){ + case TRANSVR_TYPE_SFP: + self->init = transvr_init_sfp; + self->clean = common_transvr_clean; + self->check = common_transvr_check; + self->update_all = _sfp_update_attr_all; + self->fsm_4_direct = common_fsm_4_direct_mode; + self->fsm_4_polling = common_fsm_4_polling_mode; + self->send_uevent = sfp_send_uevent; + self->dump_all = sfp_transvr_dump; + return 0; + + case TRANSVR_TYPE_QSFP: + case TRANSVR_TYPE_QSFP_PLUS: + self->init = transvr_init_qsfp; + self->clean = qsfp_transvr_clean; + self->check = common_transvr_check; + self->update_all = _qsfp_update_attr_all; + self->fsm_4_direct = common_fsm_4_direct_mode; + self->fsm_4_polling = common_fsm_4_polling_mode; + self->send_uevent = qsfp_send_uevent; + self->dump_all = qsfp_transvr_dump; + return 0; + + case TRANSVR_TYPE_QSFP_28: + self->init = transvr_init_qsfp28; + self->clean = qsfp_transvr_clean; + self->check = common_transvr_check; + self->update_all = _qsfp_update_attr_all; + self->fsm_4_direct = common_fsm_4_direct_mode; + self->fsm_4_polling = common_fsm_4_polling_mode; + self->send_uevent = qsfp_send_uevent; + self->dump_all = qsfp_transvr_dump; + return 0; + + case TRANSVR_TYPE_FAKE: + self->init = transvr_init_fake; + self->clean = fake_transvr_clean; + self->check = fake_transvr_check; + self->update_all = fake_transvr_update; + self->fsm_4_direct = fake_fsm_4_direct_mode; + self->fsm_4_polling = fake_fsm_4_polling_mode; + self->send_uevent = fake_send_uevent; + self->dump_all = fake_transvr_dump; + return 0; + + default: + break; + } + SWPS_WARN("%s: Detect non-defined type:%d\n", __func__, transvr_type); + return ERR_TRANSVR_UNEXCPT; +} + + +static struct eeprom_map_s * +get_eeprom_map(int transvr_type){ + + switch (transvr_type){ + case TRANSVR_TYPE_SFP: + return &eeprom_map_sfp; + case TRANSVR_TYPE_QSFP: + case TRANSVR_TYPE_QSFP_PLUS: + return &eeprom_map_qsfp; + case TRANSVR_TYPE_QSFP_28: + return &eeprom_map_qsfp28; + + default: + break; + } + SWPS_WARN("%s: Detect non-defined type:%d\n", __func__, transvr_type); + return NULL; +} + + +static int +setup_transvr_ssize_attr(char *swp_name, + struct transvr_obj_s *self, + struct eeprom_map_s *map_p, + struct ioexp_obj_s *ioexp_obj_p, + int ioexp_virt_offset, + int transvr_type, + int chipset_type, + int chan_id, + int run_mode){ + switch (run_mode){ + case TRANSVR_MODE_DIRECT: /* Direct access device mode */ + case TRANSVR_MODE_POLLING: /* Polling mode, read from cache */ + self->mode = run_mode; + break; + default: + SWPS_ERR("%s: non-defined run_mode:%d\n", + __func__, run_mode); + self->mode = DEBUG_TRANSVR_INT_VAL; + return -1; + } + self->eeprom_map_p = map_p; + self->ioexp_obj_p = ioexp_obj_p; + self->ioexp_virt_offset = ioexp_virt_offset; + self->chan_id = chan_id; + self->layout = transvr_type; + self->type = transvr_type; + self->chipset_type = chipset_type; + self->state = STATE_TRANSVR_NEW; + self->info = STATE_TRANSVR_NEW; + self->auto_tx_disable = VAL_TRANSVR_FUNCTION_DISABLE; + strncpy(self->swp_name, swp_name, 32); + mutex_init(&self->lock); + return 0; +} + + +static int +setup_transvr_dsize_attr(struct transvr_obj_s *self){ + + char *emsg = DEBUG_TRANSVR_STR_VAL; + + self->vendor_name = kzalloc((LEN_TRANSVR_M_STR * sizeof(char)), GFP_KERNEL); + if (!self->vendor_name){ + emsg = "vendor_name"; + goto err_setup_d_attr; + } + self->vendor_pn = kzalloc((LEN_TRANSVR_M_STR * sizeof(char)), GFP_KERNEL); + if (!self->vendor_pn){ + emsg = "vendor_pn"; + goto err_setup_d_attr; + } + self->vendor_rev = kzalloc((LEN_TRANSVR_M_STR * sizeof(char)), GFP_KERNEL); + if (!self->vendor_rev){ + emsg = "vendor_rev"; + goto err_setup_d_attr; + } + self->vendor_sn = kzalloc((LEN_TRANSVR_M_STR * sizeof(char)), GFP_KERNEL); + if (!self->vendor_sn){ + emsg = "vendor_sn"; + goto err_setup_d_attr; + } + self->worker_p = NULL; + return 0; + +err_setup_d_attr: + SWPS_ERR("%s: %s kzalloc fail!", __func__, emsg); + return ERR_TRANSVR_UNEXCPT; +} + + +static int +setup_i2c_client(struct transvr_obj_s *self){ + + struct i2c_adapter *adap = NULL; + struct i2c_client *client = NULL; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + adap = i2c_get_adapter(self->chan_id); + if(!adap){ + snprintf(err_msg, sizeof(err_msg), + "can not get adap:%d", self->chan_id); + goto err_setup_i2c_client; + } + client = kzalloc(sizeof(*client), GFP_KERNEL); + if (!client){ + snprintf(err_msg, sizeof(err_msg), + "can not kzalloc client:%d", self->chan_id); + goto err_setup_i2c_client; + } + client->adapter = adap; + self->i2c_client_p = client; + self->i2c_client_p->addr = VAL_TRANSVR_COMID_ARREESS; + return 0; + +err_setup_i2c_client: + SWPS_ERR("%s: %s\n", __func__, err_msg); + return ERR_TRANSVR_UNEXCPT; +} + + +struct transvr_obj_s * +create_transvr_obj(char *swp_name, + int chan_id, + struct ioexp_obj_s *ioexp_obj_p, + int ioexp_virt_offset, + int transvr_type, + int chipset_type, + int run_mode){ + + struct transvr_obj_s *result_p; + struct eeprom_map_s *map_p; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + /* Allocate transceiver object */ + map_p = get_eeprom_map(transvr_type); + if (!map_p){ + snprintf(err_msg, sizeof(err_msg), + "Invalid transvr_type:%d", transvr_type); + goto err_create_transvr_fail; + } + result_p = kzalloc(sizeof(*result_p), GFP_KERNEL); + if (!result_p){ + snprintf(err_msg, sizeof(err_msg), "kzalloc fail"); + goto err_create_transvr_fail; + } + /* Prepare static size attributes */ + if (setup_transvr_ssize_attr(swp_name, + result_p, + map_p, + ioexp_obj_p, + ioexp_virt_offset, + transvr_type, + chipset_type, + chan_id, + run_mode) < 0){ + goto err_create_transvr_sattr_fail; + } + /* Prepare dynamic size attributes */ + if (setup_transvr_dsize_attr(result_p) < 0){ + goto err_create_transvr_dattr_fail; + } + /* Prepare call back functions of object */ + if (setup_transvr_public_cb(result_p, transvr_type) < 0){ + goto err_create_transvr_dattr_fail; + } + /* Prepare call back functions of object */ + if (setup_transvr_private_cb(result_p, transvr_type) < 0){ + goto err_create_transvr_dattr_fail; + } + /* Prepare i2c client object */ + if (setup_i2c_client(result_p) < 0){ + goto err_create_transvr_dattr_fail; + } + return result_p; + +err_create_transvr_dattr_fail: + kfree(result_p->vendor_sn); + kfree(result_p->vendor_rev); + kfree(result_p->vendor_pn); + kfree(result_p->vendor_name); +err_create_transvr_sattr_fail: + kfree(result_p); +err_create_transvr_fail: + SWPS_ERR("%s: %s :%d :%d :%d\n", + __func__, err_msg, chan_id, ioexp_virt_offset, transvr_type); + return NULL; +} +EXPORT_SYMBOL(create_transvr_obj); + + +static int +_reload_transvr_obj(struct transvr_obj_s *self, + int new_type){ + + struct eeprom_map_s *new_map_p; + struct eeprom_map_s *old_map_p = self->eeprom_map_p; + struct i2c_client *old_i2c_p = self->i2c_client_p; + int old_type = self->type; + + /* Change state to STATE_TRANSVR_INIT */ + self->state = STATE_TRANSVR_INIT; + self->type = new_type; + /* Replace EEPROME map */ + new_map_p = get_eeprom_map(new_type); + if (!new_map_p){ + goto err_private_reload_func_1; + } + self->eeprom_map_p = new_map_p; + /* Reload i2c client */ + if (setup_i2c_client(self) < 0){ + goto err_private_reload_func_2; + } + /* Replace call back functions */ + if (setup_transvr_public_cb(self, new_type) < 0){ + goto err_private_reload_func_3; + } + if (setup_transvr_private_cb(self, new_type) < 0){ + goto err_private_reload_func_3; + } + if(old_i2c_p){ + i2c_put_adapter(old_i2c_p->adapter); + } + kfree(old_i2c_p); + return 0; + +err_private_reload_func_3: + SWPS_INFO("%s: init() fail!\n", __func__); + if(old_i2c_p){ + i2c_put_adapter(old_i2c_p->adapter); + } + kfree(old_i2c_p); + self->state = STATE_TRANSVR_UNEXCEPTED; + self->type = TRANSVR_TYPE_ERROR; + return -2; + +err_private_reload_func_2: + self->eeprom_map_p = old_map_p; + self->i2c_client_p = old_i2c_p; +err_private_reload_func_1: + self->state = STATE_TRANSVR_UNEXCEPTED; + self->type = old_type; + SWPS_INFO("%s fail! :0x%02x\n", __func__, new_type); + return -1; +} + + +static int +reload_transvr_obj(struct transvr_obj_s *self, + int new_type){ + + int result_val = ERR_TRANSVR_UNEXCPT; + + /* Reload phase */ + result_val = _reload_transvr_obj(self, new_type); + if (result_val < 0){ + SWPS_INFO("%s: reload phase fail! :%d\n", + __func__, result_val); + return EVENT_TRANSVR_RELOAD_FAIL; + } + /* Initial phase */ + result_val = _transvr_init_handler(self); + if (result_val < 0){ + SWPS_INFO("%s: initial phase fail! :%d\n", + __func__, result_val); + } + return result_val; +} + + +int +isolate_transvr_obj(struct transvr_obj_s *self) { + + self->state = STATE_TRANSVR_ISOLATED; + SWPS_INFO("%s: %s be isolated\n", __func__, self->swp_name); + return 0; +} +EXPORT_SYMBOL(isolate_transvr_obj); + + +int +resync_channel_tier_2(struct transvr_obj_s *self) { + + int val = TRANSVR_TYPE_ERROR; + + if (self->state == STATE_TRANSVR_ISOLATED) { + return 0; + } + self->i2c_client_p->addr = VAL_TRANSVR_COMID_ARREESS; + val = i2c_smbus_read_byte_data(self->i2c_client_p, + VAL_TRANSVR_COMID_OFFSET); + if (val < 0) { + return -1; + } + return 0; +} +EXPORT_SYMBOL(resync_channel_tier_2); + +/* For build single module using (Ex: ONL platform) */ +MODULE_LICENSE("GPL"); + + +/* ----------------------------------------- + * ToDo List + * ----------------------------------------- + * 1. _sfp_detect_class_by_feature() + * => Need check ACC use case. + * 2. _sfp_detect_class_by_1g_ethernet() + * => Need check 0.1G use case. + * 3. Loopback transceiver use case. + * => Less much data + * 4. _qsfp_detect_class_by_extend_comp() + * => Verify 100G CWDM4 + * => Verify Obsolete (assigned before 100G CWDM4 MSA required FEC) + * => Verify 100G CLR4 + * => Verify 100GE-DWDM2 + * => Verify 40G PSM4 Parallel SMF + * => Verify 100G ACC (Active Copper Cable) or 25GAUI C2M ACC. + * => Verify 100G ACC or 25GAUI C2M ACC. + * => Verify 25GBASE-LR + * => Verify 40G Active Cable (XLPPI) + */ + + + + + + + + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/transceiver.h b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/transceiver.h new file mode 100644 index 000000000000..a2a503402142 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/modules/transceiver.h @@ -0,0 +1,804 @@ +#ifndef TRANSCEIVER_H +#define TRANSCEIVER_H + +#include + +/* advanced features control */ +#define TRANSVR_INFO_DUMP_ENABLE (1) +#define TRANSVR_INFO_CACHE_ENABLE (1) +#define TRANSVR_UEVENT_ENABLE (1) + +/* Transceiver type define */ +#define TRANSVR_TYPE_UNKNOW_1 (0x00) +#define TRANSVR_TYPE_UNKNOW_2 (0xff) +#define TRANSVR_TYPE_SFP (0x03) /* Define for SFP, SFP+, SFP28 */ +#define TRANSVR_TYPE_QSFP (0x0c) +#define TRANSVR_TYPE_QSFP_PLUS (0x0d) +#define TRANSVR_TYPE_QSFP_28 (0x11) +#define TRANSVR_TYPE_UNPLUGGED (0xfa) /* Define for ERROR handle */ +#define TRANSVR_TYPE_FAKE (0xfc) /* Define for ERROR handle */ +#define TRANSVR_TYPE_INCONSISTENT (0xfd) /* Define for ERROR handle */ +#define TRANSVR_TYPE_ERROR (0xfe) /* Define for ERROR handle */ + +/* Transceiver class for base info */ +#define TRANSVR_CLASS_UNSPECIFIED (0) +#define TRANSVR_CLASS_ERROR (-26001) +#define TRANSVR_CLASS_1G (26001) +#define TRANSVR_CLASS_10G (26011) +#define TRANSVR_CLASS_25G (26021) +#define TRANSVR_CLASS_40G (26041) +#define TRANSVR_CLASS_100G (26101) +#define TRANSVR_CLASS_NO_SPERARABLE (26901) +#define TRANSVR_CLASS_EXTEND_COMP (26902) +/* Transceiver class for Optical 1G */ +#define TRANSVR_CLASS_OPTICAL (27000) +#define TRANSVR_CLASS_OPTICAL_100 (27001) +#define TRANSVR_CLASS_OPTICAL_1G (27002) +#define TRANSVR_CLASS_OPTICAL_1G_AOC (27003) +#define TRANSVR_CLASS_OPTICAL_1G_SX (27004) +#define TRANSVR_CLASS_OPTICAL_1G_LX (27005) +#define TRANSVR_CLASS_OPTICAL_1G_EX (27006) +/* Transceiver class for Optical 10G */ +#define TRANSVR_CLASS_OPTICAL_10G (27010) +#define TRANSVR_CLASS_OPTICAL_10G_S_AOC (27011) +#define TRANSVR_CLASS_OPTICAL_10G_S_SR (27012) +#define TRANSVR_CLASS_OPTICAL_10G_S_LR (27013) +#define TRANSVR_CLASS_OPTICAL_10G_S_ER (27014) +#define TRANSVR_CLASS_OPTICAL_10G_Q_AOC (27015) +#define TRANSVR_CLASS_OPTICAL_10G_Q_SR (27016) +#define TRANSVR_CLASS_OPTICAL_10G_Q_LR (27017) +#define TRANSVR_CLASS_OPTICAL_10G_Q_ER (27018) +/* Transceiver class for Optical 25G */ +#define TRANSVR_CLASS_OPTICAL_25G (27020) +#define TRANSVR_CLASS_OPTICAL_25G_AOC (27021) +#define TRANSVR_CLASS_OPTICAL_25G_SR (27022) +#define TRANSVR_CLASS_OPTICAL_25G_LR (27023) +#define TRANSVR_CLASS_OPTICAL_25G_ER (27024) +/* Transceiver class for Optical 40G */ +#define TRANSVR_CLASS_OPTICAL_40G (27040) +#define TRANSVR_CLASS_OPTICAL_40G_AOC (27041) +#define TRANSVR_CLASS_OPTICAL_40G_SR4 (27042) +#define TRANSVR_CLASS_OPTICAL_40G_LR4 (27043) +#define TRANSVR_CLASS_OPTICAL_40G_ER4 (27044) +/* Transceiver class for Optical 100G */ +#define TRANSVR_CLASS_OPTICAL_100G (27100) +#define TRANSVR_CLASS_OPTICAL_100G_AOC (27101) +#define TRANSVR_CLASS_OPTICAL_100G_SR4 (27102) +#define TRANSVR_CLASS_OPTICAL_100G_LR4 (27103) +#define TRANSVR_CLASS_OPTICAL_100G_ER4 (27104) +#define TRANSVR_CLASS_OPTICAL_100G_PSM4 (27105) +/* Transceiver class for Copper */ +#define TRANSVR_CLASS_COPPER (28000) +#define TRANSVR_CLASS_COPPER_L1_1G (28001) +#define TRANSVR_CLASS_COPPER_L1_10G (28011) +#define TRANSVR_CLASS_COPPER_L4_10G (28012) +#define TRANSVR_CLASS_COPPER_L1_25G (28021) +#define TRANSVR_CLASS_COPPER_L4_40G (28041) +#define TRANSVR_CLASS_COPPER_L4_100G (28101) +/* Transceiver class for Base-T */ +#define TRANSVR_CLASS_BASE_T_1000 (29001) +#define TRANSVR_CLASS_BASE_T_1000_up (29002) +/* For uevent message */ +#define TRANSVR_UEVENT_KEY_IF "IF_TYPE" +#define TRANSVR_UEVENT_KEY_SP "IF_SPEED" +#define TRANSVR_UEVENT_KEY_LANE "IF_LANE" +#define TRANSVR_UEVENT_UNKNOW "UNKNOW" +#define TRANSVR_IF_KR "KR" +#define TRANSVR_IF_KR4 "KR4" +#define TRANSVR_IF_SR "SR" +#define TRANSVR_IF_SR4 "SR4" +#define TRANSVR_IF_SFI "SFI" +#define TRANSVR_IF_IF_GMII "GMII" +#define TRANSVR_IF_IF_XGMII "XGMII" +#define TRANSVR_IF_SP_100 "100" +#define TRANSVR_IF_SP_1G "1000" +#define TRANSVR_IF_SP_10G "10000" +#define TRANSVR_IF_SP_25G "25000" +#define TRANSVR_IF_SP_40G "40000" +#define TRANSVR_IF_SP_100G "100000" + +/* Transceiver mode define */ +#define TRANSVR_MODE_DIRECT (21000) +#define TRANSVR_MODE_POLLING (21001) + +/* Transceiver state define + * [Note] + * 1. State is used to represent the state of "Transceiver" and "Object". + * 2. State for different target has different means. The description as following: + */ +#define STATE_TRANSVR_CONNECTED (0) /* [Transvr]:Be plugged in. [Obj]:Link up, and work normally. */ +#define STATE_TRANSVR_NEW (-100) /* [Transvr]:(Not used) [Obj]:Create */ +#define STATE_TRANSVR_INIT (-101) /* [Transvr]:Be plugged in. [Obj]:Link up, and in initial process. */ +#define STATE_TRANSVR_ISOLATED (-102) /* [Transvr]:Be plugged in. [Obj]:Isolate, and not provide service. */ +#define STATE_TRANSVR_SWAPPED (-200) /* [Transvr]:Be plugged in. [Obj]:(Not used) */ +#define STATE_TRANSVR_DISCONNECTED (-300) /* [Transvr]:Un-plugged. [Obj]:Link down, and not provide service. */ +#define STATE_TRANSVR_UNEXCEPTED (-901) /* [Transvr]:Any [Obj]:Any, and not in expect case. */ + +/* Task state define */ +#define STATE_T_TASK_WAIT (110) +#define STATE_T_TASK_DONE (0) +#define STATE_T_TASK_INIT (-110) +#define STATE_T_TASK_FAIL (-410) + + +/* Event for task handling */ +#define EVENT_TRANSVR_TASK_WAIT (2101) +#define EVENT_TRANSVR_TASK_DONE (0) +#define EVENT_TRANSVR_TASK_FAIL (-2101) +/* Event for initial handling */ +#define EVENT_TRANSVR_INIT_UP (2201) +#define EVENT_TRANSVR_INIT_DOWN (1) +#define EVENT_TRANSVR_INIT_REINIT (-2201) +#define EVENT_TRANSVR_INIT_FAIL (-2202) +/* Event for others */ +#define EVENT_TRANSVR_RELOAD_FAIL (-2301) +#define EVENT_TRANSVR_EXCEP_INIT (-2401) +#define EVENT_TRANSVR_EXCEP_UP (-2402) +#define EVENT_TRANSVR_EXCEP_DOWN (-2403) +#define EVENT_TRANSVR_EXCEP_SWAP (-2404) +#define EVENT_TRANSVR_EXCEP_EXCEP (-2405) +#define EVENT_TRANSVR_EXCEP_ISOLATED (-2406) +#define EVENT_TRANSVR_I2C_CRASH (-2501) + +/* Transceiver error code define */ +#define ERR_TRANSVR_UNINIT (-201) +#define ERR_TRANSVR_UNPLUGGED (-202) +#define ERR_TRANSVR_ABNORMAL (-203) +#define ERR_TRANSVR_NOSTATE (-204) +#define ERR_TRANSVR_NOTSUPPORT (-205) +#define ERR_TRANSVR_BADINPUT (-206) +#define ERR_TRANSVR_UPDATE_FAIL (-207) +#define ERR_TRANSVR_RELOAD_FAIL (-208) +#define ERR_TRANSVR_INIT_FAIL (-209) +#define ERR_TRANSVR_UNDEFINED (-210) +#define ERR_TRANSVR_TASK_FAIL (-211) +#define ERR_TRANSVR_TASK_BUSY (-212) +#define ERR_TRANSVR_UEVENT_FAIL (-213) +#define ERR_TRANSVR_FUNC_DISABLE (-214) +#define ERR_TRANSVR_I2C_CRASH (-297) +#define ERR_TRNASVR_BE_ISOLATED (-298) +#define ERR_TRANSVR_UNEXCPT (-299) + +/* For debug */ +#define DEBUG_TRANSVR_INT_VAL (-99) +#define DEBUG_TRANSVR_HEX_VAL (0xfe) +#define DEBUG_TRANSVR_STR_VAL "ERROR" + +/* For system internal */ +#define VAL_TRANSVR_COMID_ARREESS (0x50) +#define VAL_TRANSVR_COMID_OFFSET (0x00) +#define VAL_TRANSVR_EXTPHY_ADDR_56 (0x56) +#define VAL_TRANSVR_8472_READY_ADDR (0x51) +#define VAL_TRANSVR_8472_READY_PAGE (-1) +#define VAL_TRANSVR_8472_READY_OFFSET (110) +#define VAL_TRANSVR_8472_READY_BIT (0) +#define VAL_TRANSVR_8472_READY_VALUE (0) +#define VAL_TRANSVR_8472_READY_ABNORMAL (0xff) +#define VAL_TRANSVR_8436_READY_ADDR (0x50) +#define VAL_TRANSVR_8436_READY_PAGE (-1) +#define VAL_TRANSVR_8436_READY_OFFSET (2) +#define VAL_TRANSVR_8436_READY_BIT (0) +#define VAL_TRANSVR_8436_READY_VALUE (0) +#define VAL_TRANSVR_8436_READY_ABNORMAL (0xff) +#define VAL_TRANSVR_8436_PWD_ADDR (0x50) +#define VAL_TRANSVR_8436_PWD_PAGE (-1) +#define VAL_TRANSVR_8436_PWD_OFFSET (123) +#define VAL_TRANSVR_PAGE_FREE (-99) +#define VAL_TRANSVR_PAGE_SELECT_OFFSET (127) +#define VAL_TRANSVR_PAGE_SELECT_DELAY (5) +#define VAL_TRANSVR_TASK_RETRY_FOREVER (-999) +#define VAL_TRANSVR_FUNCTION_DISABLE (-1) +#define STR_TRANSVR_SFP "SFP" +#define STR_TRANSVR_QSFP "QSFP" +#define STR_TRANSVR_QSFP_PLUS "QSFP+" +#define STR_TRANSVR_QSFP28 "QSFP28" + +/* For transvr buf len */ +#define LEN_TRANSVR_S_STR (16) +#define LEN_TRANSVR_M_STR (32) +#define LEN_TRANSVR_L_STR (64) + +/* Optical wavelength */ +#define VAL_OPTICAL_WAVELENGTH_SR (850) +#define VAL_OPTICAL_WAVELENGTH_LR (1310) +#define VAL_OPTICAL_WAVELENGTH_ER (1550) + +/* Switch chip type define */ +#define CHIP_TYPE_MAGNOLIA (31001) /* Magnolia, Hudson32i, Spruce */ +#define CHIP_TYPE_REDWOOD (31002) /* Redwood, Cypress, Sequoia */ +#define CHIP_TYPE_MAPLE (31003) /* Maple */ + +#define CHIP_TYPE_LAVENDER (31011) /* Lavender */ + +/* Info from transceiver EEPROM */ +struct eeprom_map_s { + int addr_br; int page_br; int offset_br; int length_br; + int addr_cdr; int page_cdr; int offset_cdr; int length_cdr; + int addr_comp_rev; int page_comp_rev; int offset_comp_rev; int length_comp_rev; + int addr_connector; int page_connector; int offset_connector; int length_connector; + int addr_diag_type; int page_diag_type; int offset_diag_type; int length_diag_type; + int addr_extbr; int page_extbr; int offset_extbr; int length_extbr; + int addr_ext_id; int page_ext_id; int offset_ext_id; int length_ext_id; + int addr_id; int page_id; int offset_id; int length_id; + int addr_len_sm; int page_len_sm; int offset_len_sm; int length_len_sm; + int addr_len_smf; int page_len_smf; int offset_len_smf; int length_len_smf; + int addr_len_om1; int page_len_om1; int offset_len_om1; int length_len_om1; + int addr_len_om2; int page_len_om2; int offset_len_om2; int length_len_om2; + int addr_len_om3; int page_len_om3; int offset_len_om3; int length_len_om3; + int addr_len_om4; int page_len_om4; int offset_len_om4; int length_len_om4; + int addr_option; int page_option; int offset_option; int length_option; + int addr_rate_id; int page_rate_id; int offset_rate_id; int length_rate_id; + int addr_rx_am; int page_rx_am; int offset_rx_am; int length_rx_am; + int addr_rx_em; int page_rx_em; int offset_rx_em; int length_rx_em; + int addr_rx_los; int page_rx_los; int offset_rx_los; int length_rx_los; + int addr_rx_power; int page_rx_power; int offset_rx_power; int length_rx_power; + int addr_soft_rs0; int page_soft_rs0; int offset_soft_rs0; int length_soft_rs0; + int addr_soft_rs1; int page_soft_rs1; int offset_soft_rs1; int length_soft_rs1; + int addr_temp; int page_temp; int offset_temp; int length_temp; + int addr_trancomp; int page_trancomp; int offset_trancomp; int length_trancomp; + int addr_trancomp_ext; int page_trancomp_ext; int offset_trancomp_ext; int length_trancomp_ext; + int addr_tx_bias; int page_tx_bias; int offset_tx_bias; int length_tx_bias; + int addr_tx_disable; int page_tx_disable; int offset_tx_disable; int length_tx_disable; + int addr_tx_eq; int page_tx_eq; int offset_tx_eq; int length_tx_eq; + int addr_tx_fault; int page_tx_fault; int offset_tx_fault; int length_tx_fault; + int addr_tx_power; int page_tx_power; int offset_tx_power; int length_tx_power; + int addr_vendor_name; int page_vendor_name; int offset_vendor_name; int length_vendor_name; + int addr_vendor_pn; int page_vendor_pn; int offset_vendor_pn; int length_vendor_pn; + int addr_vendor_rev; int page_vendor_rev; int offset_vendor_rev; int length_vendor_rev; + int addr_vendor_sn; int page_vendor_sn; int offset_vendor_sn; int length_vendor_sn; + int addr_voltage; int page_voltage; int offset_voltage; int length_voltage; + int addr_wavelength; int page_wavelength; int offset_wavelength; int length_wavelength; +}; + + +struct transvr_worker_s; + +/* Class of transceiver object */ +struct transvr_obj_s { + + /* ========== Object private property ========== + * [Prop]: id + * [Desc]: Type of serial transceiver. + * [Note]: SFP:03h / QSFP:0Ch / QSPF+:0Dh /QSFP28:11h + */ + uint8_t id; + + /* [Prop]: connector + * [Desc]: Connector type. + * [Note]: SFP : A0h / 2 + * QSFP: 00h / 130 + */ + uint8_t connector; + + /* [Prop]: transvr_comp + * [Desc]: Transceiver compliance code. + * [Note]: SFP: SFF-8472 + * - Normal : A0h / offset 3-10 + * - Extended: A0h / offset 36 + * QSFP: SFF-8436 & SFF-8636 + * - Normal : 00h / offset 131-138 + * - Extended: 00h / offset 192 + */ + uint8_t transvr_comp[8]; + uint8_t transvr_comp_ext; + + /* [Prop]: vendor_name + * [Desc]: SFP vendor name (ASCII 16 byte char). + * [Note]: ex:FINISAR CORP. + */ + char *vendor_name; + + /* [Prop]: vendor_pn + * [Desc]: Part number provided by SFP vendor (ASCII 16 byte char). + * [Note]: + */ + char *vendor_pn; + + /* [Prop]: vendor_rev + * [Desc]: Revision level for part number provided by vendor (ASCII 4 byte char). + * [Note]: + */ + char *vendor_rev; + + /* [Prop]: vendor_sn + * [Desc]: Serial number provided by vendor (ASCII 16 byte char). + * [Note]: + */ + char *vendor_sn; + + /* [Prop]: Extended identifier + * [Desc]: SFP: + * => None + * + * QSFP: + * => This byte contained two information: + * (1) Power consumption class + * (2) CDR function present + * [Note]: Bit description as below: + * [SFP] + * None + * + * [QSFP] + * (1) Power consumption class: + * Class 1: 1.5W (Bit6-7 = 00:) + * Class 2: 2.0W (Bit6-7 = 01:) + * Class 3: 2.5W (Bit6-7 = 10:) + * Class 4: 3.5W (Bit6-7 = 11:) + * Class 5: 4.0W (Bit0-1 = 01:) + * Class 6: 4.5W (Bit0-1 = 10:) + * Class 7: 5.0W (Bit0-1 = 11:) + * (2) CDR function present: + * Bit2: 0 = No CDR in RX + * 1 = CDR present in RX + * Bit3: 0 = No CDR in TX + * 1 = CDR present in TX + */ + uint8_t ext_id; + + /* [Prop]: br + * [Desc]: Nominal bit rate, units of 100 MBits/sec. + * [Note]: SFP:03h / QSFP:0Ch / QSPF+:0Dh + * has val: 0x67 + * no val : + */ + uint8_t br; + + /* [Prop]: extbr + * [Desc]: Extended br (00h/222) + * [Desc]: Nominal bit rate per channel, units of 250 Mbps. + * Complements. Byte 140. See Table 32A. + */ + uint8_t extbr; + + /* [Prop]: len_sm + * [Desc]: Length (single mode)-(100's)m + * [Note]: This value specifies the link length that is supported by the transceiver + * while operating in compliance with the applicable standards using single mode + * fiber. The value is in units of 100 meters. A value of 255 means that the + * transceiver supports a link length greater than 25.4 km. A value of zero means + * that the transceiver does not support single mode fiber or that the length + * information must be determined from the transceiver technology. + */ + int len_sm; + + /* [Prop]: len_smf + * [Desc]: Length (single mode)-km + * [Note]: Addition to EEPROM data from original GBIC definition. This value specifies + * the link length that is supported by the transceiver while operating in + * compliance with the applicable standards using single mode fiber. The value + * is in units of kilometers. A value of 255 means that the transceiver supports + * a link length greater than 254 km. A value of zero means that the transceiver + * does not support single mode fiber or that the length information must be + * determined from the transceiver technology. + */ + int len_smf; + + /* [Prop]: len_om1 + * [Desc]: Link length supported for 62.5 um OM1 fiber, units of 10 m + * [Note]: The value is in units of 10 meters. A value of 255 means that the + * transceiver supports a link length greater than 2.54 km. A value of + * zero means that the transceiver does not support 50 micron multi-mode + * fiber or that the length information must be determined from the transceiver + * technology. + */ + int len_om1; + + /* [Prop]: len_om2 + * [Desc]: Link length supported for 50 um OM2 fiber, units of 10 m + * [Note]: The value is in units of 10 meters. A value of 255 means that the + * transceiver supports a link length greater than 2.54 km. A value of + * zero means that the transceiver does not support 50 micron multi-mode + * fiber or that the length information must be determined from the transceiver + * technology. + */ + int len_om2; + + /* [Prop]: len_om3 + * [Desc]: Length (50um, OM3) + * [Note]: This value specifies link length that is supported by the transceiver while + * operating in compliance with applicable standards using 50 micron multimode + * OM3 [2000 MHz*km] fiber. The value is in units of 10 meters. A value of 255 + * means that the transceiver supports a link length greater than 2.54 km. A value + * of zero means that the transceiver does not support 50 micron multimode fiber + * or that the length information must be determined from the transceiver technology. + */ + int len_om3; + + /* [Prop]: len_om4 + * [Desc]: Length (50um, OM4) and Length (Active Cable or Copper) + * [Note]: For optical links, this value specifies link length that is supported by the + * transceiver while operating in compliance with applicable standards using 50 micron + * multimode OM4 [4700 MHz*km] fiber. The value is in units of 10 meters. A value of + * 255 means that the transceiver supports a link length greater than 2.54 km. A value + * of zero means that the transceiver does not support 50 micron multimode fiber or that + * the length information must be determined from the transceiver codes specified in Table 5-3. + * + * For copper links, this value specifies minimum link length supported by the transceiver + * while operating in compliance with applicable standards using copper cable. For active + * cable, this value represents actual length. The value is in units of 1 meter. A value of 255 + * means the transceiver supports a link length greater than 254 meters. A value of zero means + * the transceiver does not support copper or active cables or the length information must be + * determined from transceiver technology. Further information about cable design, equalization, + * and connectors is usually required to guarantee meeting a particular length requirement. + */ + int len_om4; + + /* [Prop]: comp_rev + * [Desc]: SFF spec revision compliance + * [Note]: Indicates which revision of SFF SFF-8472 (SFP) / SFF-8636 (QSFP) the transceiver + * complies with. (unsigned integer) + */ + uint8_t comp_rev; + + /* [Prop]: CDR + * [Desc]: For transceivers with CDR capability, setting the CDR to ON engages the internal + * retiming function. Setting the CDR to OFF enables an internal bypassing mode ,which + * directs traffic around the internal CDR. (Reference: SFF-8636) + * [Note]: value=0xff: ON. + * value=0x00: OFF. + */ + uint8_t cdr; + + /* [Prop]: rate_id + * [Desc]: Soft Rate Select 0(RX). + * [Note]: 1. Addr: A0h / Offset: 13 + * 2. Value description: + * 00h Unspecified + * 01h SFF-8079 (4/2/1G Rate_Select & AS0/AS1) + * 02h SFF-8431 (8/4/2G Rx Rate_Select only) + * 03h Unspecified * + * 04h SFF-8431 (8/4/2G Tx Rate_Select only) + * 05h Unspecified * + * 06h SFF-8431 (8/4/2G Independent Rx & Tx Rate_select) + * 07h Unspecified * + * 08h FC-PI-5 (16/8/4G Rx Rate_select only) High=16G only, Low=8G/4G + * 09h Unspecified * + * 0Ah FC-PI-5 (16/8/4G Independent Rx, Tx Rate_select) High=16G only, + * Low=8G/4G + * 0Bh Unspecified * + * 0Ch FC-PI-6 (32/16/8G Independent Rx, Tx Rate_Select) + * High=32G only, Low = 16G/8G + * 0Dh Unspecified * + * 0Eh 10/8G Rx and Tx Rate_Select controlling the operation or locking + * modes of the internal signal conditioner, retimer or CDR, according + * to the logic table defined in Table 10-2, High Bit Rate + * (10G) =9.95-11.3 Gb/s; Low Bit Rate (8G) = 8.5 Gb/s. In this mode, + * the default value of bit 110.3 (Soft Rate Select RS(0), Table 9-11) + * and of bit 118.3 (Soft Rate Select RS(1), Table 10-1) is 1. + * 0Fh Unspecified * + * 10h-FFh Unallocated + */ + int rate_id; + + /* [Prop]: soft_rs0 + * [Desc]: Soft Rate Select 0(RX). + * [Note]: 1. Writing '1' selects full bandwidth operation. + * 2. This bit is "OR'd with the hard Rate_Select, AS(0) or RS(0) pin value. + * 3. Default at power up is logic zero/low + * 4. Addr: A2h / Offset: 110 / Bit: 3 + */ + uint8_t soft_rs0; + + /* [Prop]: soft_rs1 + * [Desc]: Soft Rate Select 1(TX). + * [Note]: 1. Writing '1' selects full bandwidth TX operation. + * 2. This bit is "OR'd with the hard Rate_Select, AS(1) or RS(1) pin value. + * 3. Default at power up is logic zero/low + * 4. Addr: A2h / Offset: 118 / Bit: 3 + */ + uint8_t soft_rs1; + + /* [Prop]: diag_type + * [Desc]: DIAGNOSTIC MONITORING TYPE (A0h/92) + * [Note]: Description in SFF-8472 as below: + * Bit7: Reserved for legacy diagnostic implementations. Must be '0' for compliance + * with this document. + * Bit6: Digital diagnostic monitoring implemented (described in this document). + * Must be '1' for compliance with this document. + * Bit5 Internally calibrated + * Bit4 Externally calibrated + * Bit3 Received power measurement type.0 = OMA, 1 = average power + * Bit2 Address change required see section above, "addressing modes" + * Bit1-0 Unallocated + */ + uint8_t diag_type; + + /* [Prop]: curr_temp + * [Desc]: Transceiver Current Temperature (A2h/96-97) + * [Note]: 1. Dependent on diag_type. + * 2. 96: High byte + * 3. 97: Low byte + * 4. This feature only for SFP + */ + uint8_t curr_temp[2]; + + /* [Prop]: curr_vol + * [Desc]: Transceiver Current Voltage (SFP:A2h/108-109; QSFP:00h/22-23) + * [Note]: 1. Dependent on diag_type. + * 2. 98: High byte + * 3. 99: Low byte + * 4. This feature only for SFP + * 5. Internally measured transceiver supply voltage. Represented + * as a 16 bit unsigned integer with the voltage defined as the + * full 16 bit value (0-65535) with LSB equal to 100 uVolt, + * yielding a total range of 0 to +6.55 Volts + */ + uint8_t curr_voltage[2]; + + /* [Prop]: curr_tx_bias + * [Desc]: Transceiver TX Bias Current (SFP:A2h/100-101; QSFP:00h/26-27) + * [Note]: 1. Dependent on diag_type. + * 2. 100: High byte + * 3. 101: Low byte + * 4. This feature only for SFP + * 5. Measured TX bias current in uA. Represented as a 16 bit unsigned + * integer with the current defined as the full 16 bit value (0-65535) + * with LSB equal to 2 uA, yielding a total range of 0 to 131 mA. + * Accuracy is vendor specific but must be better than 10% of the + * manufacturer's nominal value over specified operating temperature + * and voltage. + */ + uint8_t curr_tx_bias[8]; + + /* [Prop]: curr_tx_power + * [Desc]: Transceiver TX Output Power (A2h/102-103) + * [Note]: 1. Dependent on diag_type. + * 2. 102: High byte + * 3. 103: Low byte + * 4. This feature only for SFP + * 5. Measured TX output power in mW. Represented as a 16 bit unsigned + * integer with the power defined as the full 16 bit value (0-65535) + * with LSB equal to 0.1 uW, yielding a total range of 0 to 6.5535 mW + * (~ -40 to +8.2 dBm). Data is assumed to be based on measurement of + * laser monitor photodiode current. It is factory calibrated to absolute + * units using the most representative fiber output type. Accuracy is + * vendor specific but must be better than 3dB over specified temperature + * and voltage. Data is not valid when the transmitter is disabled. + */ + uint8_t curr_tx_power[8]; + + /* [Prop]: curr_tx_power + * [Desc]: Transceiver TX Output Power (A2h/102-103) + * [Note]: 1. Dependent on diag_type. + * 2. 102: High byte + * 3. 103: Low byte + * 4. This feature only for SFP + * 5. Measured RX received optical power in mW. Value can represent either + * average received power or OMA depending upon how bit 3 of byte 92 (A0h) + * is set. Represented as a 16 bit unsigned integer with the power defined + * as the full 16 bit value (0-65535) with LSB equal to 0.1 uW, yielding a + * total range of 0 to 6.5535 mW (~ -40 to +8.2 dBm). Absolute accuracy is + * dependent upon the exact optical wavelength. For the vendor specified + * wavelength, accuracy shall be better than 3dB over specified temperature + * and voltage. + */ + uint8_t curr_rx_power[8]; + + /* [Prop]: wavelength + * [Desc]: Wavelength or Copper Cable Attenuation + * [Note]: (Following is info from SFF-8636) + * For optical free side devices, this parameter identifies the nominal + * transmitter output wavelength at room temperature. This parameter is a + * 16-bit hex value with Byte 186 as high order byte and Byte 187 as low + * order byte. The laser wavelength is equal to the 16-bit integer value + * divided by 20 in nm (units of 0.05 nm). This resolution should be adequate + * to cover all relevant wavelengths yet provide enough resolution for all + * expected DWDM applications. For accurate representation of controlled + * wavelength applications, this value should represent the center of the + * guaranteed wavelength range. If the free side device is identified as + * copper cable these registers will be used to define the cable attenuation. + * An indication of 0 dB attenuation refers to the case where the attenuation + * is not known or is unavailable. + * Byte 186 (00-FFh) is the copper cable attenuation at 2.5 GHz in units of 1 dB. + * Byte 187 (00-FFh) is the copper cable attenuation at 5.0 GHz in units of 1 dB. + */ + uint8_t wavelength[2]; + + /* [Prop]: Amplitude control + * [Desc]: Amplitude control + * [Note]: QSFP28 => SFF-8636 03H Byte-238/239 + */ + uint8_t rx_am[2]; + + /* [Prop]: Emphasis control + * [Desc]: Emphasis control + * [Note]: SFP+/28 => SFF-8472 A2H Byte-115 + * QSFP28 => SFF-8636 03H Byte-236/237 + */ + uint8_t rx_em[2]; + + /* [Prop]: Soft Rx LOS + * [Desc]: Soft Rx LOS which provide by transceiver + * [Note]: (Following is info from SFF-8636) + * Byte 3: + * - Bit 0: L-Rx1 LOS + * - Bit 1: L-Rx2 LOS + * - Bit 2: L-Rx3 LOS + * - Bit 3: L-Rx4 LOS + */ + uint8_t rx_los; + + /* [Prop]: Soft Tx Disable + * [Desc]: Soft Tx Disable which provide by transceiver + * [Note]: (Following is info from SFF-8636) + * Byte 86: + * - Bit 0: Tx1 Disable + * - Bit 1: Tx2 Disable + * - Bit 2: Tx3 Disable + * - Bit 3: Tx4 Disable + */ + uint8_t tx_disable; + + /* [Prop]: Soft Tx Fault + * [Desc]: Soft Tx Fault which provide by transceiver + * [Note]: (Following is info from SFF-8636) + * Byte 86: + * - Bit 0: Tx1 Fault + * - Bit 1: Tx2 Fault + * - Bit 2: Tx3 Fault + * - Bit 3: Tx4 Fault + */ + uint8_t tx_fault; + + /* [Prop]: Transceiver EQUALIZATION + * [Desc]: Transceiver EQUALIZATION + * [Note]: SFP+/28 => SFF-8472 A2H Byte-114 + * QSFP28 => SFF-8636 03H Byte-234/235 + */ + uint8_t tx_eq[2]; + + /* [Prop]: OPTION VALUES + * [Desc]: The bits in the option field shall specify the options implemented in the transceiver. + * [Note]: SFP+/28 => SFF-8472 A0H Byte-64/65 + * QSFP+/28 => SFF-8636 00H Byte-193/195 + */ + uint8_t option[3]; + + /* [Prop]: External PHY offset + * [Desc]: It needs to be setup first if you want to access transceiver external phy. + * [Note]: This feature dependent on transceiver. + * Currently, only 1G-RJ45 transceiver supported it. + */ + uint8_t extphy_offset; + + /* ========== Object private property ========== + */ + struct device *transvr_dev_p; + struct eeprom_map_s *eeprom_map_p; + struct i2c_client *i2c_client_p; + struct ioexp_obj_s *ioexp_obj_p; + struct transvr_worker_s *worker_p; + struct mutex lock; + char swp_name[32]; + int auto_config; + int auto_tx_disable; + int chan_id; + int chipset_type; + int curr_page; + int info; + int ioexp_virt_offset; + int lane_id[8]; + int layout; + int mode; + int retry; + int state; + int temp; + int type; + + /* ========== Object public functions ========== + */ + int (*get_id)(struct transvr_obj_s *self); + int (*get_ext_id)(struct transvr_obj_s *self); + int (*get_connector)(struct transvr_obj_s *self); + int (*get_vendor_name)(struct transvr_obj_s *self, char *buf_p); + int (*get_vendor_pn)(struct transvr_obj_s *self, char *buf_p); + int (*get_vendor_rev)(struct transvr_obj_s *self, char *buf_p); + int (*get_vendor_sn)(struct transvr_obj_s *self, char *buf_p); + int (*get_power_cls)(struct transvr_obj_s *self); + int (*get_br)(struct transvr_obj_s *self); + int (*get_len_sm)(struct transvr_obj_s *self); + int (*get_len_smf)(struct transvr_obj_s *self); + int (*get_len_om1)(struct transvr_obj_s *self); + int (*get_len_om2)(struct transvr_obj_s *self); + int (*get_len_om3)(struct transvr_obj_s *self); + int (*get_len_om4)(struct transvr_obj_s *self); + int (*get_comp_rev)(struct transvr_obj_s *self); + int (*get_comp_eth_1)(struct transvr_obj_s *self); + int (*get_comp_eth_10)(struct transvr_obj_s *self); + int (*get_comp_eth_10_40)(struct transvr_obj_s *self); + int (*get_comp_extend)(struct transvr_obj_s *self); + int (*get_cdr)(struct transvr_obj_s *self); + int (*get_rate_id)(struct transvr_obj_s *self); + int (*get_soft_rs0)(struct transvr_obj_s *self); + int (*get_soft_rs1)(struct transvr_obj_s *self); + int (*get_info)(struct transvr_obj_s *self); + int (*get_if_type)(struct transvr_obj_s *self, char *buf_p); + int (*get_if_speed)(struct transvr_obj_s *self, char *buf_p); + int (*get_if_lane)(struct transvr_obj_s *self, char *buf_p); + int (*get_curr_temp)(struct transvr_obj_s *self, char *buf_p); + int (*get_curr_vol)(struct transvr_obj_s *self, char *buf_p); + int (*get_soft_rx_los)(struct transvr_obj_s *self, char *buf_p); + int (*get_soft_tx_disable)(struct transvr_obj_s *self, char *buf_p); + int (*get_soft_tx_fault)(struct transvr_obj_s *self, char *buf_p); + int (*get_auto_tx_disable)(struct transvr_obj_s *self, char *buf_p); + int (*get_tx_bias)(struct transvr_obj_s *self, char *buf_p); + int (*get_tx_power)(struct transvr_obj_s *self, char *buf_p); + int (*get_rx_power)(struct transvr_obj_s *self, char *buf_p); + int (*get_tx_eq)(struct transvr_obj_s *self, char *buf_p); + int (*get_rx_am)(struct transvr_obj_s *self, char *buf_p); + int (*get_rx_em)(struct transvr_obj_s *self, char *buf_p); + int (*get_wavelength)(struct transvr_obj_s *self, char *buf_p); + int (*get_extphy_offset)(struct transvr_obj_s *self, char *buf_p); + int (*get_extphy_reg)(struct transvr_obj_s *self, char *buf_p); + int (*set_cdr)(struct transvr_obj_s *self, int input_val); + int (*set_soft_rs0)(struct transvr_obj_s *self, int input_val); + int (*set_soft_rs1)(struct transvr_obj_s *self, int input_val); + int (*set_soft_tx_disable)(struct transvr_obj_s *self, int input_val); + int (*set_auto_tx_disable)(struct transvr_obj_s *self, int input_val); + int (*set_tx_eq)(struct transvr_obj_s *self, int input_val); + int (*set_rx_am)(struct transvr_obj_s *self, int input_val); + int (*set_rx_em)(struct transvr_obj_s *self, int input_val); + int (*set_extphy_offset)(struct transvr_obj_s *self, int input_val); + int (*set_extphy_reg)(struct transvr_obj_s *self, int input_val); + + /* ========== Object private functions ========== + */ + int (*init)(struct transvr_obj_s *self); + int (*clean)(struct transvr_obj_s *self); + int (*check)(struct transvr_obj_s *self); + int (*update_all)(struct transvr_obj_s *self, int show_err); + int (*fsm_4_direct)(struct transvr_obj_s* self, char *caller_name); + int (*fsm_4_polling)(struct transvr_obj_s* self, char *caller_name); + int (*send_uevent)(struct transvr_obj_s* self, enum kobject_action u_action); + int (*dump_all)(struct transvr_obj_s* self); +}; + + +/* For AVL Mapping */ +struct transvr_avl_s { + char vendor_name[32]; + char vendor_pn[32]; + int (*init)(struct transvr_obj_s *self); +}; + + +/* Worker for long term task of transceiver */ +struct transvr_worker_s { + /* Task Parameter */ + struct transvr_obj_s *transvr_p; + struct transvr_worker_s *next_p; + struct transvr_worker_s *pre_p; + unsigned long trigger_time; + char func_name[64]; + int retry; + int state; + + /* Task private data */ + void *p_data; + + /* Call back function */ + int (*main_task)(struct transvr_worker_s *task); + int (*post_task)(struct transvr_worker_s *task); +}; + + +struct transvr_obj_s * +create_transvr_obj(char *swp_name, + int chan_id, + struct ioexp_obj_s *ioexp_obj_p, + int ioexp_virt_offset, + int transvr_type, + int chipset_type, + int run_mode); + +void lock_transvr_obj(struct transvr_obj_s *self); +void unlock_transvr_obj(struct transvr_obj_s *self); +int isolate_transvr_obj(struct transvr_obj_s *self); + +int resync_channel_tier_2(struct transvr_obj_s *self); + +void alarm_msg_2_user(struct transvr_obj_s *self, char *emsg); + +#endif /* TRANSCEIVER_H */ + + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/setup.py b/platform/broadcom/sonic-platform-modules-inventec/d6332/setup.py new file mode 100644 index 000000000000..c48f6ef8da07 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/setup.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python + +import os +from setuptools import setup +os.listdir + +setup( + name='sonic_platform', + version='1.0', + description='Module to initialize Ivnetec D6332 platforms', + + packages=['sonic_platform'], +) + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/__init__.py new file mode 100644 index 000000000000..4bfefa0fb636 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/__init__.py @@ -0,0 +1,3 @@ +__all__ = ["platform", "chassis"] +from sonic_platform import * + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/chassis.py new file mode 100644 index 000000000000..b9e0afd8501f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/chassis.py @@ -0,0 +1,242 @@ +#!/usr/bin/env python +# +# Name: chassis.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + import re + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform.eeprom import Eeprom + from sonic_platform.fan import Fan + from sonic_platform.psu import Psu + from sonic_platform.qsfp import QSfp + from sonic_platform.event_monitor import EventMonitor + from sonic_platform.thermal import Thermal + from sonic_platform.component import Component + from sonic_platform.watchdog import Watchdog +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +PMON_REBOOT_CAUSE_PATH = "/usr/share/sonic/platform/reboot-cause/" +REBOOT_CAUSE_FILE = "reboot-cause.txt" +PREV_REBOOT_CAUSE_FILE = "previous-reboot-cause.txt" +monitor = None + +class Chassis(ChassisBase): + + __num_of_fans = 5 + __num_of_psus = 2 + __num_of_sfps = 32 + __start_of_qsfp = 1 + __num_of_thermals = 15 + __num_of_components= 4 + + def __init__(self): + ChassisBase.__init__(self) + + # Initialize EEPROM + self._eeprom = Eeprom() + self._eeprom_data = self._eeprom.get_eeprom_data() + + # Initialize FAN + for index in range(self.__num_of_fans): + fan = Fan(index) + self._fan_list.append(fan) + + # Initialize PSU + for index in range(self.__num_of_psus): + psu = Psu(index) + self._psu_list.append(psu) + + # Initialize SFP + for index in range(self.__num_of_sfps): + sfp = QSfp(index) #only qsfp on platform D6332 + self._sfp_list.append(sfp) + + # Initialize THERMAL + for index in range(self.__num_of_thermals): + thermal = Thermal(index) + self._thermal_list.append(thermal) + + # Initialize COMPONENT + for index in range(self.__num_of_components): + component = Component(index) + self._component_list.append(component) + + # Initialize WATCHDOG + self._watchdog = Watchdog() + + + def __read_txt_file(self, file_path): + try: + with open(file_path, 'r') as fd: + data = fd.read() + return data.strip() + except IOError: + pass + return None + + +############################################## +# Device methods +############################################## + + def get_name(self): + """ + Retrieves the name of the chassis + Returns: + string: The name of the chassis + """ + return self._eeprom.modelstr(self._eeprom_data) + + def get_presence(self): + """ + Retrieves the presence of the chassis + Returns: + bool: True if chassis is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the chassis + Returns: + string: Model/part number of chassis + """ + return self._eeprom.part_number_str() + + def get_serial(self): + """ + Retrieves the serial number of the chassis + Returns: + string: Serial number of chassis + """ + return self._eeprom.serial_number_str(self._eeprom_data) + + def get_status(self): + """ + Retrieves the operational status of the chassis + Returns: + bool: A boolean value, True if chassis is operating properly + False if not + """ + return True + +############################################## +# Chassis methods +############################################## + + def get_base_mac(self): + """ + Retrieves the base MAC address for the chassis + + Returns: + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' + """ + return self._eeprom.base_mac_addr(self._eeprom_data) + + def get_serial_number(self): + """ + Retrieves the hardware serial number for the chassis + + Returns: + A string containing the hardware serial number for this chassis. + """ + return self._eeprom.serial_number_str(self._eeprom_data) + + def get_system_eeprom_info(self): + """ + Retrieves the full content of system EEPROM information for the chassis + + Returns: + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their corresponding + values. + Ex. { '0x21':'AG9064', '0x22':'V1.0', '0x23':'AG9064-0109867821', + '0x24':'001c0f000fcd0a', '0x25':'02/03/2018 16:22:00', + '0x26':'01', '0x27':'REV01', '0x28':'AG9064-C2358-16G'} + """ + return self._eeprom.system_eeprom_info() + + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + Returns: + A tuple (string, string) where the first element is a string + containing the cause of the previous reboot. This string must be + one of the predefined strings in this class. If the first string + is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used + to pass a description of the reboot cause. + """ + description = 'None' + reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER + + reboot_cause_path = PMON_REBOOT_CAUSE_PATH + REBOOT_CAUSE_FILE + prev_reboot_cause_path = PMON_REBOOT_CAUSE_PATH + PREV_REBOOT_CAUSE_FILE + + sw_reboot_cause = self.__read_txt_file(reboot_cause_path) or "Unknown" + prev_sw_reboot_cause = self.__read_txt_file(prev_reboot_cause_path) or "Unknown" + + if sw_reboot_cause == "Unknown" and (prev_sw_reboot_cause == "Unknown" or prev_sw_reboot_cause == self.REBOOT_CAUSE_POWER_LOSS): + reboot_cause = self.REBOOT_CAUSE_POWER_LOSS + description = prev_sw_reboot_cause + elif sw_reboot_cause != "Unknown": + reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE + description = sw_reboot_cause + elif prev_reboot_cause_path != "Unknown": + reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE + description = prev_sw_reboot_cause + + return (reboot_cause, description) + + def get_change_event(self, timeout=0): + """ + Returns a nested dictionary containing all devices which have + experienced a change at chassis level + + Args: + timeout: Timeout in milliseconds (optional). If timeout == 0, + this method will block until a change is detected. + + Returns: + (bool, dict): + - True if call successful, False if not; + - A nested dictionary where key is a device type, + value is a dictionary with key:value pairs in the format of + {'device_id':'device_event'}, + where device_id is the device ID for this device and + device_event, + status='1' represents device inserted, + status='0' represents device removed. + Ex. {'fan':{'0':'0', '2':'1'}, 'sfp':{'11':'0'}} + indicates that fan 0 has been removed, fan 2 + has been inserted and sfp 11 has been removed. + """ + global monitor + port_dict = {} + while True: + with EventMonitor(timeout) as monitor: + while True: + event = monitor.get_events() + + if not bool(event): + return True, {'sfp':port_dict} + else: + if event['SUBSYSTEM'] == 'swps': + portname = event['DEVPATH'].split("/")[-1] + rc = re.match(r"port(?P\d+)",portname) + if rc is not None: + if event['ACTION'] == "remove": + remove_num = int(rc.group("num")) + port_dict[remove_num] = "0" + elif event['ACTION'] == "add": + add_num = int(rc.group("num")) + port_dict[add_num] = "1" + return True, {'sfp':port_dict} + else: + return False, {'sfp':port_dict} + else: + pass diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/component.py new file mode 100644 index 000000000000..116daa8d30f8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/component.py @@ -0,0 +1,196 @@ +#!/usr/bin/env python + +try: + import os + import logging + from sonic_platform_base.component_base import ComponentBase + from sonic_platform.inv_const import Common + +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +OS_SYSTEM_SUCCESS = 0 + +CPLD1_INFO_PATH = Common.I2C_PREFIX+"/0-0077/info" +CPLD2_INFO_PATH = Common.I2C_PREFIX+"/0-0077/info" #info of 2 cpld are combined by inv_cpld under this path +BIOS_VER_PATH = "/sys/class/dmi/id/bios_version" +BIOS_CS_PATH = Common.I2C_PREFIX+"/0-0077/bios_cs" + +CPLD1_INDEX = 0 +CPLD2_INDEX = 1 +MAIN_BIOS_INDEX = 2 +BACKUP_BIOS_INDEX = 3 + + +COMPONENT_NAME_LIST = [ + "CPLD1", + "CPLD2", + "Main BIOS", + "Backup BIOS", +] + +COMPONENT_DESC_LIST = [ + "platform management and control LED", + "platform management and control LED", + "Main Basic Input/Output System", + "Backup Basic Input/Output System", +] + + +BIOS_ID_MAPPING_TABLE = { + 0: MAIN_BIOS_INDEX, + 1: BACKUP_BIOS_INDEX +} + +class Component(ComponentBase): + + def __get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip(' \t\n\r') + return retval + + def __set_attr_value(self, attr_path, value): + try: + with open(attr_path, 'r+') as reg_file: + reg_file.write(value) + except IOError as e: + logging.error("Error: unable to open file: %s" % str(e)) + return False + + return True + + def __get_current_bios(self): + current_bios=self.__get_attr_value(BIOS_CS_PATH) + if current_bios != 'ERR': + ''' + Get first char to convert to bios ID + ''' + current_bios = int(current_bios[:1]) + else: + current_bios = None + + return current_bios + + def __get_cpld_version(self): + ''' + The info output would be like: + The CPLD release date is 06/13/2019. + The PCB version is 5 + The CPLD version is 1.1 + ''' + cpld_version = None + ret_str = None + path = None + target="" + + if self.index == CPLD1_INDEX: + path = CPLD1_INFO_PATH + target="The CPLD version is " + elif self.index == CPLD2_INDEX: + path = CPLD2_INFO_PATH + target="The CPLD2 version is " + else: + logging.error("Unable support index %d", self.index) + + if path !=None: + try: + with open(path, 'r') as file: + ret_str = file.read() + except Exception as error: + logging.error("Unable to open file %s", path) + + if ret_str!=None: + start_idx=ret_str.find(target) + if start_idx > 0: + start_idx = start_idx+len(target) + offset = ret_str[start_idx:].find('\n') + if offset > 0: + end_idx=start_idx+offset + cpld_version=ret_str[start_idx:end_idx].strip('\n') + + if cpld_version is None: + logging.error("Unable to parse cpld info %d", self.index) + + return cpld_version + + + def __get_bios_version(self): + bios_version = None + current_bios_id=self.__get_current_bios() + + if current_bios_id != None : + if self.index == BIOS_ID_MAPPING_TABLE[current_bios_id]: + try: + with open(BIOS_VER_PATH, 'r') as file: + bios_version = file.read().strip('\n') + except Exception as error: + logging.error("Unable to open file %s", BIOS_VER_PATH) + else: + logging.error("Only support bios version of current running BIOS") + bios_version = "N/A" + + return bios_version + + def __install_cpld_firmware(self,image_path): + logging.error("[Component][__install_cpld_firmware] Currently not support FW update on platform D6332") + raise NotImplementedError + + def __install_bios_firmware(self,image_path): + logging.error("[Component][__install_bios_firmware] Currently not support FW update on platform D6332") + raise NotImplementedError + + __get_version_callback_list = { + CPLD1_INDEX:__get_cpld_version, + CPLD2_INDEX:__get_cpld_version, + MAIN_BIOS_INDEX:__get_bios_version, + BACKUP_BIOS_INDEX:__get_bios_version, + } + + def __init__(self, component_index): + self.index = component_index + + def get_name(self): + """ + Retrieves the name of the component + Returns: + A string containing the name of the component + """ + return COMPONENT_NAME_LIST[self.index] + + def get_description(self): + """ + Retrieves the description of the component + Returns: + A string containing the description of the component + """ + return COMPONENT_DESC_LIST[self.index] + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + Returns: + A string containing the firmware version of the component + """ + return self.__get_version_callback_list[self.index](self) + + 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 + """ + logging.error("[Component][install_firmware] Currently not support FW update on platform D6332") + raise NotImplementedError \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/eeprom.py new file mode 100644 index 000000000000..0d210b47beb2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/eeprom.py @@ -0,0 +1,77 @@ +# +# Name: eeprom.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + from sonic_eeprom import eeprom_tlvinfo +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +EEPROM_TOTAL_LEN_HIGH_OFFSET = 9 +EEPROM_TOTAL_LEN_LOW_OFFSET = 10 +EEPROM_TLV_TYPE_OFFSET = 0 +EEPROM_TLV_LEN_OFFSET = 1 +EEPROM_TLV_VALUE_OFFSET = 2 + +class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self): + self.__eeprom_path = "/sys/class/i2c-adapter/i2c-0/0-0055/eeprom" + super(Eeprom, self).__init__(self.__eeprom_path, 0, '', True) + self.__eeprom_tlv_dict = dict() + try: + self.__eeprom_data = self.read_eeprom() + except: + self.__eeprom_data = "N/A" + raise RuntimeError("Eeprom is not Programmed") + else: + eeprom = self.__eeprom_data + + if not self.is_valid_tlvinfo_header(eeprom): + return + + total_length = (ord(eeprom[EEPROM_TOTAL_LEN_HIGH_OFFSET]) << 8) | ord(eeprom[EEPROM_TOTAL_LEN_LOW_OFFSET]) + tlv_index = self._TLV_INFO_HDR_LEN + tlv_end = self._TLV_INFO_HDR_LEN + total_length + + while (tlv_index + EEPROM_TLV_VALUE_OFFSET) < len(eeprom) and tlv_index < tlv_end: + if not self.is_valid_tlv(eeprom[tlv_index:]): + break + + tlv = eeprom[tlv_index:tlv_index + EEPROM_TLV_VALUE_OFFSET + + ord(eeprom[tlv_index + EEPROM_TLV_LEN_OFFSET])] + code = "0x%02X" % (ord(tlv[EEPROM_TLV_TYPE_OFFSET])) + + if ord(tlv[EEPROM_TLV_TYPE_OFFSET]) == self._TLV_CODE_VENDOR_EXT: + value = str((ord(tlv[EEPROM_TLV_VALUE_OFFSET]) << 24) | (ord(tlv[EEPROM_TLV_VALUE_OFFSET+1]) << 16) | + (ord(tlv[EEPROM_TLV_VALUE_OFFSET+2]) << 8) | ord(tlv[EEPROM_TLV_VALUE_OFFSET+3])) + value += str(tlv[6:6 + ord(tlv[EEPROM_TLV_LEN_OFFSET])]) + else: + name, value = self.decoder(None, tlv) + + self.__eeprom_tlv_dict[code] = value + if ord(eeprom[tlv_index]) == self._TLV_CODE_CRC_32: + break + + tlv_index += ord(eeprom[tlv_index+EEPROM_TLV_LEN_OFFSET]) + EEPROM_TLV_VALUE_OFFSET + + def part_number_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_PART_NUMBER) + if not is_valid: + return "N/A" + + return results[2] + + def system_eeprom_info(self): + """ + Returns a dictionary, where keys are the type code defined in + ONIE EEPROM format and values are their corresponding values + found in the system EEPROM. + """ + return self.__eeprom_tlv_dict + + def get_eeprom_data(self): + return self.__eeprom_data diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/event_monitor.py b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/event_monitor.py new file mode 100644 index 000000000000..247943075934 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/event_monitor.py @@ -0,0 +1,94 @@ +# +# event_monitor.py +# Description: module to minitor events +# + +try: + import socket + from collections import OrderedDict + import os +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + + +NETLINK_KOBJECT_UEVENT = 15 + +class EventMonitor(object): + + def __init__(self, timeout): + self.recieved_events = OrderedDict() + self.socket = socket.socket(socket.AF_NETLINK, socket.SOCK_DGRAM, NETLINK_KOBJECT_UEVENT) + self.timeout = timeout + + def start(self): + self.socket.bind((os.getpid(), -1)) + + if 0 == self.timeout: + self.socket.settimeout(None) + else: + self.socket.settimeout(self.timeout/1000.0) + + def stop(self): + self.socket.close() + + def __enter__(self): + self.start() + return self + + def __exit__(self, exc_type, exc_value, traceback): + self.stop() + + def __iter__(self): + while True: + for item in self.next_events(): + yield item + + def next_events(self): + try: + data = self.socket.recv(16384) + event = {} + for item in data.split(b'\x00'): + if not item: + # check if we have an event and if we already received it + if event and event['SEQNUM'] not in self.recieved_events: + self.recieved_events[event['SEQNUM']] = None + if (len(self.recieved_events) > 100): + self.recieved_events.popitem(last=False) + yield event + event = {} + else: + try: + k, v = item.split(b'=', 1) + event[k.decode('ascii')] = v.decode('ascii') + except ValueError: + pass + except socket.timeout: + yield event + + def get_events(self): + event = {} + while True: + try: + data = self.socket.recv(16384) + + for item in data.split(b'\x00'): + if not item: + # check if we have an event and if we already received it + # if no item and event empty, means received garbled + if bool(event): + if event['SEQNUM'] not in self.recieved_events: + self.recieved_events[event['SEQNUM']] = None + if (len(self.recieved_events) > 100): + self.recieved_events.popitem(last=False) + return event + else: + event = {} + else: + try: + k, v = item.split(b'=', 1) + event[k] = v + except ValueError: + pass + except socket.timeout: + return event + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/fan.py new file mode 100644 index 000000000000..4f62ccaafd56 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/fan.py @@ -0,0 +1,330 @@ +#!/usr/bin/env python +# +# Name: fan.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + import math + import os + import logging + from sonic_platform_base.fan_base import FanBase + from sonic_platform.inv_const import FanConst , PsuConst, Common +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +MAX_SPEED_OF_FAN_FRONT = 23500 +MAX_SPEED_OF_FAN_BACK = 19900 +MAX_SPEED_OF_FAN_PSU = 26000 +MAX_PWM_OF_FAN = 255 + +class Fan(FanBase): + + __name_of_fans = ['FAN1','FAN2','FAN3','FAN4','FAN5','PSU1_FAN1','PSU2_FAN1'] + __start_of_psu_fans = FanConst().PSU_FAN_START_INDEX + + def __init__(self, index): + self.__index = index + + if self.__index >= self.__start_of_psu_fans: + psu_id=self.__index- self.__start_of_psu_fans + self.__presence_attr = "{}/i2c-inv_cpld/psu{}".format(Common.I2C_PREFIX,psu_id+1) + self.__rpm1_attr = "{}/psu{}/fan1_input".format(Common.INFO_PREFIX, psu_id+1) + else: + self.__fan_type = "{}/i2c-inv_cpld/fanmodule{}_type".format(Common.I2C_PREFIX, self.__index + 1) + self.__rpm1_attr = "{}/i2c-inv_cpld/fan{}_input".format(Common.I2C_PREFIX, 2*self.__index + 1) + self.__rpm2_attr = "{}/i2c-inv_cpld/fan{}_input".format(Common.I2C_PREFIX, 2*self.__index + 2) + self.__pwm_attr = "{}/i2c-inv_cpld/pwm{}".format(Common.I2C_PREFIX, self.__index + 1) + + def __get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip(' \t\n\r') + return retval + + def read_fru(self, attr_type): + fan_addr=FanConst.FAN_VPD_ADDR_BASE+self.__index + path="/sys/bus/i2c/devices/{}-00{}/eeprom".format(FanConst.FAN_VPD_CHANNEL, hex(fan_addr)[2:] ) + content=[] + attr_idx=0 + attr_length=0 + + if(os.path.exists(path)): + with open(path,'rw') as f: + content=f.read() + target_offset=ord(content[FanConst.TLV_PRODUCT_INFO_OFFSET_IDX-1]) + target_offset*=8 #spec defined: offset are in multiples of 8 bytes + + attr_idx=target_offset+FanConst.TLV_PRODUCT_INFO_AREA_START + for i in range(1,attr_type): + if attr_idx > len(content): + raise SyntaxError + attr_length=(ord(content[attr_idx]))&(0x3f) + attr_idx+=(attr_length+1); + + attr_length=(ord(content[attr_idx]))&(0x3f) + attr_idx+=1 + else: + logging.error("[FAN] Can't find path to eeprom : %s" % path) + return SyntaxError + + return content[attr_idx:attr_idx+attr_length] + + +############################################## +# Device methods +############################################## + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + return self.__name_of_fans[self.__index] + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + presence = False + + if self.__index >= self.__start_of_psu_fans: + #check fan of psu presence if psu presence + attr_path = self.__presence_attr + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (attr_rv == PsuConst.PSU_TYPE_LIST[0] or attr_rv == PsuConst.PSU_TYPE_LIST[1]): + presence = True + else: + raise SyntaxError + else: + attr_path = self.__fan_type + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if(attr_rv==FanConst.FAN_TYPE_LIST[0] or attr_rv==FanConst.FAN_TYPE_LIST[1]): + presence = True + else: + raise SyntaxError + + return presence + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + + Returns: + string: Model/part number of device + """ + if self.__index >= self.__start_of_psu_fans: + return NotImplementedError + else: + model=self.read_fru(FanConst.TLV_ATTR_TYPE_MODEL) + if not model: + return NotImplementedError + + return model + + def get_serial(self): + """ + Retrieves the serial number of the device + + Returns: + string: Serial number of device + """ + if self.__index >= self.__start_of_psu_fans: + return NotImplementedError + else: + serial=self.read_fru(FanConst.TLV_ATTR_TYPE_SERIAL) + if not serial: + return NotImplementedError + + return serial + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + status = False + + if self.__index >= self.__start_of_psu_fans: + #check fan of psu presence if psu presence + attr_path = self.__presence_attr + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (attr_rv == PsuConst.PSU_TYPE_LIST[1]): + status = True + else: + raise SyntaxError + else: + status = self.get_presence() + + return status + +############################################## +# FAN methods +############################################## + + def get_direction(self): + """ + Retrieves the direction of fan + + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + """ + direction = 'N/A' + + if self.__index >= self.__start_of_psu_fans: + raise NotImplementedError + else: + attr_path = self.__fan_type + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + + #"Normal Type", //00 + #"REVERSAL Type", //01 + #"UNPLUGGED", //10 + #"UNPLUGGED", //11 + + if(attr_rv==FanConst.FAN_TYPE_LIST[0]): + direction = 'FAN_DIRECTION_EXHAUST' + elif(attr_rv==FanConst.FAN_TYPE_LIST[1]): + direction = 'FAN_DIRECTION_INTAKE' + else: + raise SyntaxError + + return direction + + def get_speed(self): + """ + Retrieves the speed of fan as a percentage of full speed + + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + """ + speed = 0 + + if self.__index >= self.__start_of_psu_fans: + attr_rv1 = self.__get_attr_value(self.__presence_attr) + if( attr_rv1 == PsuConst.PSU_TYPE_LIST[0] or attr_rv1 == PsuConst.PSU_TYPE_LIST[1] ): + attr_path1 = self.__rpm1_attr + attr_rv1 = self.__get_attr_value(attr_path1) + if (attr_rv1 != 'ERR' ): + speed = int(attr_rv1) * 100 / MAX_SPEED_OF_FAN_PSU + elif(attr_rv1 == 'ERR' ): + raise SyntaxError + else: + attr_path1 = self.__rpm1_attr + attr_path2 = self.__rpm2_attr + + if self.get_presence() and None != attr_path1: + attr_rv1 = self.__get_attr_value(attr_path1) + attr_rv2 = self.__get_attr_value(attr_path2) + if (attr_rv1 != 'ERR' and attr_rv2 != 'ERR'): + fan1_input = int(attr_rv1) + speed = math.ceil(float(fan1_input * 100 / MAX_SPEED_OF_FAN_FRONT)) + fan2_input = int(attr_rv2) + speed += math.ceil(float(fan2_input * 100 / MAX_SPEED_OF_FAN_BACK)) + speed /= 2 + elif (attr_rv1 != 'ERR'): + fan1_input = int(attr_rv1) + if self.__index >= self.__start_of_psu_fans: + speed = speed = math.ceil(float(fan1_input * 100 / MAX_SPEED_OF_FAN_PSU)) + else: + speed = math.ceil(float(fan1_input * 100 / MAX_SPEED_OF_FAN_FRONT)) + elif (attr_rv2 != 'ERR'): + fan2_input = int(attr_rv2) + speed += math.ceil(float(fan2_input * 100 / MAX_SPEED_OF_FAN_BACK)) + else: + raise SyntaxError + + return speed + + def get_target_speed(self): + """ + Retrieves the target (expected) speed of the fan + + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + """ + speed = 0 + + if self.__index >= self.__start_of_psu_fans: + return NotImplementedError + else: + attr_path = self.__pwm_attr + + if self.get_presence() and None != attr_path: + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + pwm = int(attr_rv) + speed = math.ceil(float(pwm * 100 / MAX_PWM_OF_FAN)) + else: + raise SyntaxError + + return speed + + def get_speed_tolerance(self): + """ + Retrieves the speed tolerance of the fan + + Returns: + An integer, the percentage of variance from target speed which is + considered tolerable + """ + raise NotImplementedError + + def set_speed(self, speed): + """ + Sets the fan speed + + Args: + speed: An integer, the percentage of full fan speed to set fan to, + in the range 0 (off) to 100 (full speed) + + Returns: + A boolean, True if speed is set successfully, False if not + """ + raise NotImplementedError + + def set_status_led(self, color): + """ + Sets the state of the fan module status LED + + Args: + color: A string representing the color with which to set the + fan module status LED + + Returns: + bool: True if status LED state is set successfully, False if not + """ + raise NotImplementedError + + def get_status_led(self): + """ + Gets the state of the fan status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + raise NotImplementedError diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/inv_const.py b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/inv_const.py new file mode 100644 index 000000000000..ace488f551da --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/inv_const.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python + +class Common(): + INFO_PREFIX = "/usr/share/sonic/platform" + I2C_PREFIX = "/sys/bus/i2c/devices" + +class FanConst(): + #fan vpd info + FAN_VPD_CHANNEL= 1 + FAN_VPD_ADDR_BASE=0x52 + #fru status + TLV_PRODUCT_INFO_OFFSET_IDX=5 + TLV_PRODUCT_INFO_AREA_START=3 + TLV_ATTR_TYPE_SERIAL=5 + TLV_ATTR_TYPE_MODEL=2 + + PSU_FAN_START_INDEX = 5 + FAN_TYPE_LIST=["0:Normal Type","1:REVERSAL Type","2:UNPLUGGED","3:UNPLUGGED"] #defined in inv_cpld + +class PsuConst(): + PSU_TYPE_LIST=["0:unpowered","1:normal","2:not installed","3:not installed"] #defined in inv_cpld + PSU_I2C_ADDR=["2-005a","2-005b"] \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/platform.py new file mode 100644 index 000000000000..7d6bda4502de --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/platform.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python +# +# Name: platform.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PlatformBase): + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/psu.py new file mode 100644 index 000000000000..93352636078d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/psu.py @@ -0,0 +1,254 @@ +#!/usr/bin/env python +# +# Name: psu.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + import os + import logging + from sonic_platform_base.psu_base import PsuBase + from sonic_platform.fan import Fan + from sonic_platform.inv_const import FanConst , PsuConst, Common +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +VOLTAGE_UPPER_LIMIT = 14 +VOLTAGE_LOWER_LIMIT = 10 + +class Psu(PsuBase): + + __num_of_fans = 1 + __name_of_psus = ['PSU1','PSU2'] + + def __init__(self, index): + self.__index = index + psu_id = self.__index + 1 + + self.__psu_presence_attr = "{}/i2c-inv_cpld/psu{}".format(Common.I2C_PREFIX,psu_id) + self.__psu_voltage_out_attr = "{}/psu{}/in2_input".format(Common.INFO_PREFIX, psu_id) + self.__psu_current_out_attr = "{}/psu{}/curr2_input".format(Common.INFO_PREFIX, psu_id) + self.__psu_power_out_attr = "{}/psu{}/power2_input".format(Common.INFO_PREFIX, psu_id) + + # Get the start index of fan list + self.__fan_psu_start_index = self.__index + FanConst().PSU_FAN_START_INDEX + + # Overriding _fan_list class variable defined in PsuBase, to make it unique per Psu object + self._fan_list = [] + + # Initialize FAN + for x in range(self.__fan_psu_start_index, self.__fan_psu_start_index + self.__num_of_fans): + fan = Fan(x) + self._fan_list.append(fan) + + def __get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip(' \t\n\r') + return retval + + +############################################## +# Device methods +############################################## + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + return self.__name_of_psus[self.__index] + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + presence = False + attr_path = self.__psu_presence_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (attr_rv == PsuConst.PSU_TYPE_LIST[0] or attr_rv == PsuConst.PSU_TYPE_LIST[1]): + presence = True + else: + raise SyntaxError + + return presence + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + + Returns: + string: Model/part number of device + """ + #model = 'Unknow' + #attr_path = self.__psu_model_attr + + #attr_rv = self.__get_attr_value(attr_path) + #if (attr_rv != 'ERR'): + # if (attr_rv != ''): + # model = attr_rv + #else: + # raise SyntaxError + + #return model + raise NotImplementedError + + def get_serial(self): + """ + Retrieves the serial number of the device + + Returns: + string: Serial number of device + """ + """ + serial = 'Unknow' + attr_path = self.__psu_serial_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (attr_rv != ''): + serial = attr_rv + else: + raise SyntaxError + + return serial + """ + raise NotImplementedError + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + status = False + attr_path = self.__psu_presence_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (attr_rv == PsuConst.PSU_TYPE_LIST[1]): + status = True + else: + raise SyntaxError + + return status + + +############################################## +# PSU methods +############################################## + + def get_voltage(self): + """ + Retrieves current PSU voltage output + + Returns: + A float number, the output voltage in volts, + e.g. 12.1 + """ + voltage_out = 0.0 + attr_path = self.__psu_voltage_out_attr + + if(self.get_presence()): + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + voltage_out = float(attr_rv) / 1000 + else: + raise SyntaxError + + return voltage_out + + def get_current(self): + """ + Retrieves present electric current supplied by PSU + + Returns: + A float number, the electric current in amperes, e.g 15.4 + """ + current_out = 0.0 + attr_path = self.__psu_current_out_attr + + if(self.get_presence()): + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + current_out = float(attr_rv) / 1000 + else: + raise SyntaxError + + return current_out + + def get_power(self): + """ + Retrieves current energy supplied by PSU + + Returns: + A float number, the power in watts, e.g. 302.6 + """ + power_out = 0.0 + attr_path = self.__psu_power_out_attr + + if(self.get_presence()): + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + power_out = float(attr_rv) / 1000 + else: + raise SyntaxError + + return power_out + + def get_powergood_status(self): + """ + Retrieves the powergood status of PSU + + Returns: + A boolean, True if PSU has stablized its output voltages and passed all + its internal self-tests, False if not. + """ + powergood_status = False + voltage_out = self.get_voltage() + + #Check the voltage out with 12V, plus or minus 20 percentage. + if (VOLTAGE_LOWER_LIMIT <= voltage_out and voltage_out <= VOLTAGE_UPPER_LIMIT ): + powergood_status = True + + return powergood_status + + def set_status_led(self, color): + """ + Sets the state of the PSU status LED + + Args: + color: A string representing the color with which to set the + PSU status LED + + Returns: + bool: True if status LED state is set successfully, False if not + """ + raise NotImplementedError + + def get_status_led(self): + """ + Gets the state of the PSU status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + raise NotImplementedError diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/qsfp.py b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/qsfp.py new file mode 100644 index 000000000000..17763cd1264f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/qsfp.py @@ -0,0 +1,1023 @@ +#!/usr/bin/env python +# +# Name: qsfp.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + import os + import logging + from ctypes import create_string_buffer + from sonic_platform_base.sfp_base import SfpBase + from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom + from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper + from sonic_platform.inv_const import Common +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +INFO_OFFSET = 128 +THRE_OFFSET = 384 #128*3 +DOM_OFFSET = 0 + +XCVR_INTFACE_BULK_OFFSET = 0 +XCVR_INTFACE_BULK_WIDTH_QSFP = 20 +XCVR_HW_REV_WIDTH_QSFP = 2 +XCVR_CABLE_LENGTH_WIDTH_QSFP = 5 +XCVR_VENDOR_NAME_OFFSET = 20 +XCVR_VENDOR_NAME_WIDTH = 16 +XCVR_VENDOR_OUI_OFFSET = 37 +XCVR_VENDOR_OUI_WIDTH = 3 +XCVR_VENDOR_PN_OFFSET = 40 +XCVR_VENDOR_PN_WIDTH = 16 +XCVR_HW_REV_OFFSET = 56 +XCVR_HW_REV_WIDTH_OSFP = 2 +XCVR_VENDOR_SN_OFFSET = 68 +XCVR_VENDOR_SN_WIDTH = 16 +XCVR_VENDOR_DATE_OFFSET = 84 +XCVR_VENDOR_DATE_WIDTH = 8 +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 1 + +# Offset for values in QSFP eeprom +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_CONTROL_OFFSET = 86 +QSFP_CONTROL_WIDTH = 8 +QSFP_CHANNL_RX_LOS_STATUS_OFFSET = 3 +QSFP_CHANNL_RX_LOS_STATUS_WIDTH = 1 +QSFP_CHANNL_TX_FAULT_STATUS_OFFSET = 4 +QSFP_CHANNL_TX_FAULT_STATUS_WIDTH = 1 +QSFP_POWEROVERRIDE_OFFSET = 93 +QSFP_POWEROVERRIDE_WIDTH = 1 +QSFP_MODULE_THRESHOLD_OFFSET = 128 +QSFP_MODULE_THRESHOLD_WIDTH = 24 +QSFP_CHANNEL_THRESHOLD_OFFSET = 176 +QSFP_CHANNEL_THRESHOLD_WIDTH = 16 + +QSFP_REG_VALUE_ENABLE = "0x1" +QSFP_REG_VALUE_DISABLE = "0x0" + +class QSfp(SfpBase): + + __platform = "x86_64-inventec_d6332-r0" + __hwsku = "INVENTEC-D6332" + __port_to_i2c_mapping = { + 0:12, 1:13, 2:14, 3:15, 4:16, 5:17, 6:18, 7:19, + 8:20, 9:21, 10:22, 11:23, 12:24, 13:25, 14:26, 15:27, + 16:28, 17:29, 18:30, 19:31, 20:32, 21:33, 22:34, 23:35, + 24:36, 25:37, 26:38, 27:39, 28:40, 29:41, 30:42, 31:43, + } + + + def __init__(self, index): + self.__index = index + + self.__port_end = len(self.__port_to_i2c_mapping) - 1 + + self.__presence_attr = None + self.__eeprom_path = None + if self.__index in range(0, self.__port_end + 1): + self.__presence_attr = "/sys/class/swps/port{}/present".format(self.__index) + self.__lpmode_attr = "/sys/class/swps/port{}/lpmod".format(self.__index) + self.__reset_attr = "/sys/class/swps/port{}/reset".format(self.__index) + self.__eeprom_path = "{}/{}-0050/eeprom".format(Common.I2C_PREFIX, self.__port_to_i2c_mapping[self.__index]) + + SfpBase.__init__(self) + + def __get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip(' \t\n\r') + return retval + + def __set_attr_value(self, attr_path, value): + + try: + with open(attr_path, 'r+') as reg_file: + reg_file.write(value) + except IOError as e: + logging.error("Error: unable to open file: '%s'" % str(e)) + return False + + return True + + def __is_host(self): + return os.system("docker > /dev/null 2>&1") == 0 + + def __get_path_to_port_config_file(self): + host_platform_root_path = '/usr/share/sonic/device' + docker_hwsku_path = '/usr/share/sonic/hwsku' + + host_platform_path = "/".join([host_platform_root_path, self.__platform]) + hwsku_path = "/".join([host_platform_path, self.__hwsku]) if self.__is_host() else docker_hwsku_path + + return "/".join([hwsku_path, "port_config.ini"]) + + + def __read_eeprom_specific_bytes(self, offset, num_bytes): + eeprom_raw = [] + + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + sysfs_eeprom_path = self.__eeprom_path + try: + with open(sysfs_eeprom_path, mode="rb", buffering=0) as sysfsfile_eeprom: + sysfsfile_eeprom.seek(offset) + raw = sysfsfile_eeprom.read(num_bytes) + raw_len = len(raw) + for n in range(0, raw_len): + eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + except (OSError, IOError): + logging.error("File error: %s", sysfs_eeprom_path) + return None + + return eeprom_raw + + def __write_eeprom_specific_bytes(self, offset, buffer): + sysfs_eeprom_path = self.__eeprom_path + + try: + with open(sysfs_eeprom_path, "r+b") as sysfsfile_eeprom: + sysfsfile_eeprom.seek(offset) + sysfsfile_eeprom.write(buffer[0]) + except IOError as e: + logging.error("Error: unable to open file: '%s'" % str(e)) + return False + + return True + + def __convert_string_to_num(self, value_str): + if "-inf" in value_str: + return 'N/A' + elif "Unknown" in value_str: + return 'N/A' + elif 'dBm' in value_str: + t_str = value_str.rstrip('dBm') + return float(t_str) + elif 'mA' in value_str: + t_str = value_str.rstrip('mA') + return float(t_str) + elif 'C' in value_str: + t_str = value_str.rstrip('C') + return float(t_str) + elif 'Volts' in value_str: + t_str = value_str.rstrip('Volts') + return float(t_str) + else: + return 'N/A' + +############################################## +# Device methods +############################################## + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + name = None + + sfputil_helper = SfpUtilHelper() + sfputil_helper.read_porttab_mappings(self.__get_path_to_port_config_file()) + name = sfputil_helper.logical[self.__index] or "Unknown" + return name + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + presence = False + attr_path = self.__presence_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (int(attr_rv) == 0): + presence = True + else: + raise SyntaxError + + return presence + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + + Returns: + string: Model/part number of device + """ + model = "N/A" + offset = INFO_OFFSET + sfpi_obj = sff8436InterfaceId() + if not self.get_presence() or not sfpi_obj: + return model + + sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0) + model = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' + + return model + + def get_serial(self): + """ + Retrieves the serial number of the device + + Returns: + string: Serial number of device + """ + serial = "N/A" + offset = INFO_OFFSET + sfpi_obj = sff8436InterfaceId() + if not self.get_presence() or not sfpi_obj: + return serial + + sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_vendor_sn_raw, 0) + serial = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' + + return serial + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + status = False + tx_fault = self.get_tx_fault() + + if self.get_presence() and tx_fault and not any(tx_fault): + status = True + + return status + +############################################## +# SFP methods +############################################## + + def get_transceiver_info(self): + """ + Retrieves transceiver info of this SFP + + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + type |1*255VCHAR |type of SFP + hardwarerev |1*255VCHAR |hardware version of SFP + serialnum |1*255VCHAR |serial number of the SFP + manufacturename |1*255VCHAR |SFP vendor name + modelname |1*255VCHAR |SFP model name + Connector |1*255VCHAR |connector information + encoding |1*255VCHAR |encoding information + ext_identifier |1*255VCHAR |extend identifier + ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance + cable_length |INT |cable length in m + mominal_bit_rate |INT |nominal bit rate by 100Mbs + specification_compliance |1*255VCHAR |specification compliance + vendor_date |1*255VCHAR |vendor date + vendor_oui |1*255VCHAR |vendor OUI + ======================================================================== + """ + transceiver_info_dict_keys = ['type', 'hardwarerev', + 'serialnum', 'manufacturename', + 'modelname', 'Connector', + 'encoding', 'ext_identifier', + 'ext_rateselect_compliance', 'cable_type', + 'cable_length', 'nominal_bit_rate', + 'specification_compliance', 'vendor_date', + 'vendor_oui'] + + qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', + 'Length OM2(m)', 'Length OM1(m)', 'Length Cable Assembly(m)') + + qsfp_compliance_code_tup = ('10/40G Ethernet Compliance Code', 'SONET Compliance codes', + 'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes', + 'Fibre Channel link length/Transmitter Technology', 'Fibre Channel transmission media', + 'Fibre Channel Speed') + + sfpi_obj = sff8436InterfaceId() + if not self.get_presence() or not sfpi_obj: + return {} + + offset = INFO_OFFSET + + sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes((offset + XCVR_INTFACE_BULK_OFFSET), XCVR_INTFACE_BULK_WIDTH_QSFP) + sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(sfp_interface_bulk_raw, 0) + + sfp_vendor_name_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) + sfp_vendor_name_data = sfpi_obj.parse_vendor_name(sfp_vendor_name_raw, 0) + + sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0) + + sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes((offset + XCVR_HW_REV_OFFSET), XCVR_HW_REV_WIDTH_QSFP) + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_vendor_rev_raw, 0) + + sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_vendor_sn_raw, 0) + + sfp_vendor_oui_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH) + if sfp_vendor_oui_raw is not None: + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(sfp_vendor_oui_raw, 0) + + sfp_vendor_date_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH) + sfp_vendor_date_data = sfpi_obj.parse_vendor_date(sfp_vendor_date_raw, 0) + + transceiver_info_dict = dict.fromkeys(transceiver_info_dict_keys, 'N/A') + + if sfp_interface_bulk_data: + transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] + transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] + transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] + transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] + transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value']) + + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A' + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' + transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A' + transceiver_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A' + + transceiver_info_dict['cable_type'] = "Unknown" + transceiver_info_dict['cable_length'] = "Unknown" + for key in qsfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str(sfp_interface_bulk_data['data'][key]['value']) + + compliance_code_dict = dict() + for key in qsfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + + transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) + + return transceiver_info_dict + + def get_transceiver_bulk_status(self): + """ + Retrieves transceiver bulk status of this SFP + + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + rx_los |BOOLEAN |RX loss-of-signal status, True if has RX los, False if not. + tx_fault |BOOLEAN |TX fault status, True if has TX fault, False if not. + reset_status |BOOLEAN |reset status, True if SFP in reset, False if not. + lp_mode |BOOLEAN |low power mode status, True in lp mode, False if not. + tx_disable |BOOLEAN |TX disable status, True TX disabled, False if not. + tx_disabled_channel |HEX |disabled TX channels in hex, bits 0 to 3 represent channel 0 + | |to channel 3. + temperature |INT |module temperature in Celsius + voltage |INT |supply voltage in mV + txbias |INT |TX Bias Current in mA, n is the channel number, + | |for example, tx2bias stands for tx bias of channel 2. + rxpower |INT |received optical power in mW, n is the channel number, + | |for example, rx2power stands for rx power of channel 2. + txpower |INT |TX output power in mW, n is the channel number, + | |for example, tx2power stands for tx power of channel 2. + ======================================================================== + """ + transceiver_dom_info_dict_keys = ['rx_los', 'tx_fault', + 'reset_status', 'power_lpmode', + 'tx_disable', 'tx_disable_channel', + 'temperature', 'voltage', + 'rx1power', 'rx2power', + 'rx3power', 'rx4power', + 'tx1bias', 'tx2bias', + 'tx3bias', 'tx4bias', + 'tx1power', 'tx2power', + 'tx3power', 'tx4power'] + + sfpd_obj = sff8436Dom() + sfpi_obj = sff8436InterfaceId() + + if not self.get_presence() or not sfpi_obj or not sfpd_obj: + return {} + + transceiver_dom_info_dict = dict.fromkeys(transceiver_dom_info_dict_keys, 'N/A') + offset = DOM_OFFSET + offset_xcvr = INFO_OFFSET + + # 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((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_dom_capability(qsfp_dom_capability_raw, 0) + else: + return None + + dom_temperature_raw = self.__read_eeprom_specific_bytes((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) + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + + dom_voltage_raw = self.__read_eeprom_specific_bytes((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) + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + + qsfp_dom_rev_raw = self.__read_eeprom_specific_bytes((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) + qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['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 = {} + dom_channel_monitor_raw = None + 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((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: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes((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) + 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'] + + if dom_channel_monitor_raw: + 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'] + + for key in transceiver_dom_info_dict: + transceiver_dom_info_dict[key] = self.__convert_string_to_num(transceiver_dom_info_dict[key]) + + transceiver_dom_info_dict['rx_los'] = self.get_rx_los() + transceiver_dom_info_dict['tx_fault'] = self.get_tx_fault() + transceiver_dom_info_dict['reset_status'] = self.get_reset_status() + transceiver_dom_info_dict['tx_disable'] = self.get_tx_disable() + transceiver_dom_info_dict['tx_disable_channel'] = self.get_tx_disable_channel() + transceiver_dom_info_dict['lp_mode'] = self.get_lpmode() + + + return transceiver_dom_info_dict + + def get_transceiver_threshold_info(self): + """ + Retrieves transceiver threshold info of this SFP + + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius. + templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius. + temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius. + templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius. + vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV. + vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV. + vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV. + vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV. + rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm. + rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm. + rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm. + rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm. + txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm. + txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm. + txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm. + txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm. + txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA. + txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA. + txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA. + txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA. + ======================================================================== + """ + transceiver_dom_threshold_info_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning', + 'vcchighalarm', 'vcchighwarning', 'vcclowalarm', 'vcclowwarning', + 'rxpowerhighalarm', 'rxpowerhighwarning', 'rxpowerlowalarm', 'rxpowerlowwarning', + 'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', 'txpowerlowwarning', + 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning'] + + sfpd_obj = sff8436Dom() + if not self.get_presence() or not sfpd_obj: + return {} + + transceiver_dom_threshold_dict = dict.fromkeys(transceiver_dom_threshold_info_dict_keys, 'N/A') + offset = THRE_OFFSET + + dom_module_threshold_raw = self.__read_eeprom_specific_bytes((offset + QSFP_MODULE_THRESHOLD_OFFSET), QSFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw: + module_threshold_values = sfpd_obj.parse_module_threshold_values(dom_module_threshold_raw, 0) + module_threshold_data = module_threshold_values.get('data') + if module_threshold_data: + transceiver_dom_threshold_dict['temphighalarm'] = module_threshold_data['TempHighAlarm']['value'] + transceiver_dom_threshold_dict['templowalarm'] = module_threshold_data['TempLowAlarm']['value'] + transceiver_dom_threshold_dict['temphighwarning'] = module_threshold_data['TempHighWarning']['value'] + transceiver_dom_threshold_dict['templowwarning'] = module_threshold_data['TempLowWarning']['value'] + transceiver_dom_threshold_dict['vcchighalarm'] = module_threshold_data['VccHighAlarm']['value'] + transceiver_dom_threshold_dict['vcclowalarm'] = module_threshold_data['VccLowAlarm']['value'] + transceiver_dom_threshold_dict['vcchighwarning'] = module_threshold_data['VccHighWarning']['value'] + transceiver_dom_threshold_dict['vcclowwarning'] = module_threshold_data['VccLowWarning']['value'] + + dom_channel_thres_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNEL_THRESHOLD_OFFSET), QSFP_CHANNEL_THRESHOLD_WIDTH) + channel_threshold_values = sfpd_obj.parse_channel_threshold_values(dom_channel_thres_raw, 0) + channel_threshold_data = channel_threshold_values.get('data') + if channel_threshold_data: + transceiver_dom_threshold_dict['rxpowerhighalarm'] = channel_threshold_data['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerlowalarm'] = channel_threshold_data['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerhighwarning'] = channel_threshold_data['RxPowerHighWarning']['value'] + transceiver_dom_threshold_dict['rxpowerlowwarning'] = channel_threshold_data['RxPowerLowWarning']['value'] + transceiver_dom_threshold_dict['txpowerhighalarm'] = "0.0dBm" + transceiver_dom_threshold_dict['txpowerlowalarm'] = "0.0dBm" + transceiver_dom_threshold_dict['txpowerhighwarning'] = "0.0dBm" + transceiver_dom_threshold_dict['txpowerlowwarning'] = "0.0dBm" + transceiver_dom_threshold_dict['txbiashighalarm'] = channel_threshold_data['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_dict['txbiaslowalarm'] = channel_threshold_data['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_dict['txbiashighwarning'] = channel_threshold_data['TxBiasHighWarning']['value'] + transceiver_dom_threshold_dict['txbiaslowwarning'] = channel_threshold_data['TxBiasLowWarning']['value'] + + for key in transceiver_dom_threshold_dict: + transceiver_dom_threshold_dict[key] = self.__convert_string_to_num(transceiver_dom_threshold_dict[key]) + + return transceiver_dom_threshold_dict + + def get_reset_status(self): + """ + Retrieves the reset status of SFP + + Returns: + A Boolean, True if reset enabled, False if disabled + """ + reset_status = False + attr_path = self.__reset_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (int(attr_rv) == 0): + reset_status = True + else: + raise SyntaxError + + return reset_status + + def get_rx_los(self): + """ + Retrieves the RX LOS (lost-of-signal) status of SFP + + Returns: + A Boolean, True if SFP has RX LOS, False if not. + Note : RX LOS status is latched until a call to get_rx_los or a reset. + """ + rx_los_list = [] + + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(QSFP_CHANNL_RX_LOS_STATUS_OFFSET, QSFP_CHANNL_RX_LOS_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 16) + rx_los_list.append(rx_los_data & 0x01 != 0) + rx_los_list.append(rx_los_data & 0x02 != 0) + rx_los_list.append(rx_los_data & 0x04 != 0) + rx_los_list.append(rx_los_data & 0x08 != 0) + + return rx_los_list + + def get_tx_fault(self): + """ + Retrieves the TX fault status of SFP + + Returns: + A Boolean, True if SFP has TX fault, False if not + Note : TX fault status is lached until a call to get_tx_fault or a reset. + """ + tx_fault_list = [] + + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(QSFP_CHANNL_TX_FAULT_STATUS_OFFSET, QSFP_CHANNL_TX_FAULT_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 16) + tx_fault_list.append(tx_fault_data & 0x01 != 0) + tx_fault_list.append(tx_fault_data & 0x02 != 0) + tx_fault_list.append(tx_fault_data & 0x04 != 0) + tx_fault_list.append(tx_fault_data & 0x08 != 0) + + return tx_fault_list + + def get_tx_disable(self): + """ + Retrieves the tx_disable status of this SFP + + Returns: + A Boolean, True if tx_disable is enabled, False if disabled + """ + tx_disable = False + tx_disable_list = [] + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return tx_disable + + dom_control_raw = self.__read_eeprom_specific_bytes(QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH) + if dom_control_raw is not None: + dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0) + tx_disable_list.append('On' == dom_control_data['data']['TX1Disable']['value']) + tx_disable_list.append('On' == dom_control_data['data']['TX2Disable']['value']) + tx_disable_list.append('On' == dom_control_data['data']['TX3Disable']['value']) + tx_disable_list.append('On' == dom_control_data['data']['TX4Disable']['value']) + tx_disable = tx_disable_list[0] or tx_disable_list[1] or tx_disable_list[2] or tx_disable_list[3] + + return tx_disable + + def get_tx_disable_channel(self): + """ + Retrieves the TX disabled channels in this SFP + + Returns: + A hex of 4 bits (bit 0 to bit 3 as channel 0 to channel 3) to represent + TX channels which have been disabled in this SFP. + As an example, a returned value of 0x5 indicates that channel 0 + and channel 2 have been disabled. + """ + tx_disable_channel = 0 + tx_disable_list = [] + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return tx_disable_channel + + dom_control_raw = self.__read_eeprom_specific_bytes(QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH) + if dom_control_raw is not None: + dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0) + tx_disable_list.append('On' == dom_control_data['data']['TX1Disable']['value']) + tx_disable_list.append('On' == dom_control_data['data']['TX2Disable']['value']) + tx_disable_list.append('On' == dom_control_data['data']['TX3Disable']['value']) + tx_disable_list.append('On' == dom_control_data['data']['TX4Disable']['value']) + + for i in range(len(tx_disable_list)): + if tx_disable_list[i]: + tx_disable_channel |= 1 << i + + return tx_disable_channel + + def get_lpmode(self): + """ + Retrieves the lpmode (low power mode) status of this SFP + + Returns: + A Boolean, True if lpmode is enabled, False if disabled + """ + lpmode = False + attr_path = self.__lpmode_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (int(attr_rv) == 1): + lpmode = True + else: + raise SyntaxError + + return lpmode + + def get_power_override(self): + """ + Retrieves the power-override status of this SFP + + Returns: + A Boolean, True if power-override is enabled, False if disabled + """ + power_override = False + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return power_override + + dom_control_raw = self.__read_eeprom_specific_bytes(QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH) + if dom_control_raw is not None: + dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0) + power_override = ('On' == dom_control_data['data']['PowerOverride']['value']) + + return power_override + + def get_temperature(self): + """ + Retrieves the temperature of this SFP + + Returns: + An integer number of current temperature in Celsius + """ + temp = "N/A" + sfpd_obj = sff8436Dom() + offset = DOM_OFFSET + + if not self.get_presence() or not sfpd_obj: + return temp + + dom_temperature_raw = self.__read_eeprom_specific_bytes((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) + temp = self.__convert_string_to_num(dom_temperature_data['data']['Temperature']['value']) + + return temp + + def get_voltage(self): + """ + Retrieves the supply voltage of this SFP + + Returns: + An integer number of supply voltage in mV + """ + voltage = "N/A" + sfpd_obj = sff8436Dom() + offset = DOM_OFFSET + + if not self.get_presence() or not sfpd_obj: + return voltage + + dom_voltage_raw = self.__read_eeprom_specific_bytes((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) + voltage = self.__convert_string_to_num(dom_voltage_data['data']['Vcc']['value']) + + return voltage + + def get_tx_bias(self): + """ + Retrieves the TX bias current of this SFP + + Returns: + A list of four integer numbers, representing TX bias in mA + for channel 0 to channel 4. + Ex. ['110.09', '111.12', '108.21', '112.09'] + """ + tx_bias_list = [] + sfpd_obj = sff8436Dom() + sfpi_obj = sff8436InterfaceId() + offset = DOM_OFFSET + offset_xcvr = INFO_OFFSET + + if not self.get_presence() or not sfpd_obj: + return [] + + qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes((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_dom_capability(qsfp_dom_capability_raw, 0) + else: + return None + + qsfp_dom_rev_raw = self.__read_eeprom_specific_bytes((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) + qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value'] + + dom_channel_monitor_data = {} + dom_channel_monitor_raw = None + 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((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: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes((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) + + + if dom_channel_monitor_raw is not None: + tx_bias_list.append(self.__convert_string_to_num(dom_channel_monitor_data['data']['TX1Bias']['value'])) + tx_bias_list.append(self.__convert_string_to_num(dom_channel_monitor_data['data']['TX2Bias']['value'])) + tx_bias_list.append(self.__convert_string_to_num(dom_channel_monitor_data['data']['TX3Bias']['value'])) + tx_bias_list.append(self.__convert_string_to_num(dom_channel_monitor_data['data']['TX4Bias']['value'])) + + return tx_bias_list + + def get_rx_power(self): + """ + Retrieves the received optical power for this SFP + + Returns: + A list of four integer numbers, representing received optical + power in mW for channel 0 to channel 4. + Ex. ['1.77', '1.71', '1.68', '1.70'] + """ + rx_power_list = [] + sfpd_obj = sff8436Dom() + sfpi_obj = sff8436InterfaceId() + offset = DOM_OFFSET + offset_xcvr = INFO_OFFSET + + if not self.get_presence() or not sfpd_obj: + return [] + + qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes((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_dom_capability(qsfp_dom_capability_raw, 0) + else: + return None + + qsfp_dom_rev_raw = self.__read_eeprom_specific_bytes((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) + qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value'] + + dom_channel_monitor_data = {} + dom_channel_monitor_raw = None + 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((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: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes((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) + + + if dom_channel_monitor_raw is not None: + rx_power_list.append(self.__convert_string_to_num(dom_channel_monitor_data['data']['RX1Power']['value'])) + rx_power_list.append(self.__convert_string_to_num(dom_channel_monitor_data['data']['RX2Power']['value'])) + rx_power_list.append(self.__convert_string_to_num(dom_channel_monitor_data['data']['RX3Power']['value'])) + rx_power_list.append(self.__convert_string_to_num(dom_channel_monitor_data['data']['RX4Power']['value'])) + + return rx_power_list + + def get_tx_power(self): + """ + Retrieves the TX power of this SFP + + Returns: + A list of four integer numbers, representing TX power in mW + for channel 0 to channel 4. + Ex. ['1.86', '1.86', '1.86', '1.86'] + """ + tx_power_list = [] + sfpd_obj = sff8436Dom() + sfpi_obj = sff8436InterfaceId() + offset = DOM_OFFSET + offset_xcvr = INFO_OFFSET + + if not self.get_presence() or not sfpd_obj: + return [] + + qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes((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_dom_capability(qsfp_dom_capability_raw, 0) + else: + return None + + qsfp_dom_rev_raw = self.__read_eeprom_specific_bytes((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) + qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value'] + + dom_channel_monitor_data = {} + dom_channel_monitor_raw = None + 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')): + pass + + else: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes((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) + tx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX1Power']['value'])) + tx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX2Power']['value'])) + tx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX3Power']['value'])) + tx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX4Power']['value'])) + + return tx_power_list + + def reset(self): + """ + Reset SFP and return all user module settings to their default srate. + + Returns: + A boolean, True if successful, False if not + """ + + return self.__set_attr_value(self.__reset_attr, QSFP_REG_VALUE_ENABLE) + + def tx_disable(self, tx_disable): + """ + Disable SFP TX for all channels + + Args: + tx_disable : A Boolean, True to enable tx_disable mode, False to disable + tx_disable mode. + + Returns: + A boolean, True if tx_disable is set successfully, False if not + """ + tx_disable_ctl = 0xf if tx_disable else 0x0 + buffer = create_string_buffer(1) + buffer[0] = chr(tx_disable_ctl) + + return self.__write_eeprom_specific_bytes(QSFP_CONTROL_OFFSET, buffer) + + def tx_disable_channel(self, channel, disable): + """ + Sets the tx_disable for specified SFP channels + + Args: + channel : A hex of 4 bits (bit 0 to bit 3) which represent channel 0 to 3, + e.g. 0x5 for channel 0 and channel 2. + disable : A boolean, True to disable TX channels specified in channel, + False to enable + + Returns: + A boolean, True if successful, False if not + """ + channel_state = self.get_tx_disable_channel() + if disable: + tx_disable_ctl = channel_state | channel + else: + tx_disable_ctl = channel_state & (~channel & 0xf) + + buffer = create_string_buffer(1) + buffer[0] = chr(tx_disable_ctl) + + return self.__write_eeprom_specific_bytes(QSFP_CONTROL_OFFSET, buffer) + + def set_lpmode(self, lpmode): + """ + Sets the lpmode (low power mode) of SFP + + Args: + lpmode: A Boolean, True to enable lpmode, False to disable it + Note : lpmode can be overridden by set_power_override + + Returns: + A boolean, True if lpmode is set successfully, False if not + """ + if lpmode is True: + reg_value = QSFP_REG_VALUE_ENABLE + else: + reg_value = QSFP_REG_VALUE_DISABLE + + return self.__set_attr_value(self.__lpmode_attr, reg_value) + + def set_power_override(self, power_override, power_set): + """ + Sets SFP power level using power_override and power_set + + Args: + power_override : + A Boolean, True to override set_lpmode and use power_set + to control SFP power, False to disable SFP power control + through power_override/power_set and use set_lpmode + to control SFP power. + power_set : + Only valid when power_override is True. + A Boolean, True to set SFP to low power mode, False to set + SFP to high power mode. + + Returns: + A boolean, True if power-override and power_set are set successfully, + False if not + """ + power_override_bit = 0 + if power_override: + power_override_bit |= 1 << 0 + + power_set_bit = 0 + if power_set: + power_set_bit |= 1 << 1 + + buffer = create_string_buffer(1) + buffer[0] = chr(power_override_bit | power_set_bit) + + return self.__write_eeprom_specific_bytes(QSFP_POWEROVERRIDE_OFFSET, buffer) diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/thermal.py new file mode 100644 index 000000000000..ee1220a6c9fa --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/thermal.py @@ -0,0 +1,253 @@ +#!/usr/bin/env python +# +# Name: thermal.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + import os + import logging + from sonic_platform_base.thermal_base import ThermalBase + from sonic_platform.inv_const import PsuConst, Common +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +PSU1_THERMAL_START=9 +PSU2_THERMAL_START=12 + +class Thermal(ThermalBase): + + __core_temp_path = Common.INFO_PREFIX+"/coretemp/temp{}_input" + __switch_thermal_path = Common.INFO_PREFIX+"/board_thermal_{}/temp1_input" + __psu_thermal_path = Common.INFO_PREFIX+"/psu{}/temp{}_input" + __max_temp_path = Common.INFO_PREFIX+"/coretemp/temp{}_max" + __name_of_thermal = [ + "Core 0 Temperature", + "Core 1 Temperature", + "Core 2 Temperature", + "Core 3 Temperature", + "Core 4 Temperature", + "CPU Board Temperature", + "FrontSide Temperature", + "RearSide Temperature", + "NearASIC Temperature", + "PSU1 Temperature1", + "PSU1 Temperature2", + "PSU1 Temperature3", + "PSU2 Temperature1", + "PSU2 Temperature2", + "PSU2 Temperature3" + ] + __thermal_path_list = [ + __core_temp_path.format(1), + __core_temp_path.format(2), + __core_temp_path.format(3), + __core_temp_path.format(4), + __core_temp_path.format(5), + __switch_thermal_path.format(1), + __switch_thermal_path.format(2), + __switch_thermal_path.format(3), + __switch_thermal_path.format(4), + __psu_thermal_path.format(1,1), + __psu_thermal_path.format(1,2), + __psu_thermal_path.format(1,3), + __psu_thermal_path.format(2,1), + __psu_thermal_path.format(2,2), + __psu_thermal_path.format(2,3) + ] + __max_temp_path_list = [ + __max_temp_path.format(1), + __max_temp_path.format(2), + __max_temp_path.format(3), + __max_temp_path.format(4), + __max_temp_path.format(5), + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "" + ] + + + def __init__(self, index): + self.__index = index + + self.__thermal_temp_attr = self.__thermal_path_list[self.__index] + self.__max_temp_attr = self.__max_temp_path_list[self.__index] + + + def __get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip(' \t\n\r') + return retval + + +############################################## +# Device methods +############################################## + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + return self.__name_of_thermal[self.__index] + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + presence=False + + if (self.__index < PSU1_THERMAL_START): + attr_path = self.__thermal_temp_attr + presence=os.path.isfile(attr_path) + elif(self.__index < PSU2_THERMAL_START): + path="{}/i2c-inv_cpld/psu1".format(Common.I2C_PREFIX) + psu_state=self.__get_attr_value(path) + if (psu_state != 'ERR'): + if (psu_state == PsuConst.PSU_TYPE_LIST[0] or psu_state == PsuConst.PSU_TYPE_LIST[1]): + presence = True + else: + path="{}/i2c-inv_cpld/psu2".format(Common.I2C_PREFIX) + psu_state=self.__get_attr_value(path) + if (psu_state != 'ERR'): + if (psu_state == PsuConst.PSU_TYPE_LIST[0] or psu_state == PsuConst.PSU_TYPE_LIST[1]): + presence = True + + return presence + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + + Returns: + string: Model/part number of device + """ + raise NotImplementedError + + def get_serial(self): + """ + Retrieves the serial number of the device + + Returns: + string: Serial number of device + """ + raise NotImplementedError + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + status = False + if self.get_presence(): + status = True + + return status + +############################################## +# THERMAL methods +############################################## + + def get_temperature(self): + """ + Retrieves current temperature reading from thermal + + Returns: + A float number of current temperature in Celsius up to nearest thousandth + of one degree Celsius, e.g. 30.125 + """ + temperature = 0.0 + attr_path = self.__thermal_temp_attr + + if(self.get_presence()): + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + temperature = float(attr_rv) / 1000 + else: + raise SyntaxError + + return temperature + + def get_high_threshold(self): + """ + Retrieves the high threshold temperature of thermal + + Returns: + A float number, the high threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + attr_path = self.__max_temp_attr + + if attr_path == '': + raise NotImplementedError + else: + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + high_threshold = float(attr_rv) / 1000 + else: + raise SyntaxError + + return high_threshold + + def get_low_threshold(self): + """ + Retrieves the low threshold temperature of thermal + + Returns: + A float number, the low threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + raise NotImplementedError + + def set_high_threshold(self, temperature): + """ + Sets the high threshold temperature of thermal + + Args : + temperature: A float number up to nearest thousandth of one degree Celsius, + e.g. 30.125 + + Returns: + A boolean, True if threshold is set successfully, False if not + """ + raise NotImplementedError + + def set_low_threshold(self, temperature): + """ + Sets the low threshold temperature of thermal + + Args : + temperature: A float number up to nearest thousandth of one degree Celsius, + e.g. 30.125 + + Returns: + A boolean, True if threshold is set successfully, False if not + """ + raise NotImplementedError diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/watchdog.py b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/watchdog.py new file mode 100644 index 000000000000..42718541f5c2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/sonic_platform/watchdog.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python + +try: + from sonic_platform_base.watchdog_base import WatchdogBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +class Watchdog(WatchdogBase): + def __init__(self): + print('init Watchdog()') + + def arm(self, seconds): + """ + Arm the hardware watchdog with a timeout of seconds. + If the watchdog is currently armed, calling this function will + simply reset the timer to the provided value. If the underlying + hardware does not support the value provided in , this + method should arm the watchdog with the *next greater* available + value. + Returns: + An integer specifying the *actual* number of seconds the watchdog + was armed with. On failure returns -1. + """ + raise NotImplementedError + + def disarm(self): + """ + Disarm the hardware watchdog + Returns: + A boolean, True if watchdog is disarmed successfully, False if not + """ + raise NotImplementedError + + def is_armed(self): + """ + Retrieves the armed state of the hardware watchdog. + Returns: + A boolean, True if watchdog is armed, False if not + """ + raise NotImplementedError + + def get_remaining_time(self): + """ + If the watchdog is armed, retrieve the number of seconds remaining on + the watchdog timer + Returns: + An integer specifying the number of seconds remaining on thei + watchdog timer. If the watchdog is not armed, returns -1. + """ + raise NotImplementedError + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6332/utils/inventec_d6332_util.py b/platform/broadcom/sonic-platform-modules-inventec/d6332/utils/inventec_d6332_util.py new file mode 100755 index 000000000000..a468a323d6fc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6332/utils/inventec_d6332_util.py @@ -0,0 +1,325 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 Inventec, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +""" +Usage: %(scriptName)s [options] command object + +options: + -h | --help : this help message + -d | --debug : run with debug mode + -f | --force : ignore error during installation or clean +command: + install : install drivers and generate related sysfs nodes + clean : uninstall drivers and remove related sysfs nodes +""" + +import os +import commands +import sys, getopt +import logging +import syslog +import time + +DEBUG = False +args = [] +FORCE = 0 +FAN_VPD_CHANNEL= 1 +FAN_VPD_ADDR_BASE=0x52 +FAN_NUM=5 +RETRY_LIMIT = 5 +i2c_prefix = '/sys/bus/i2c/devices/' + + +if DEBUG == True: + print sys.argv[0] + print 'ARGV: ', sys.argv[1:] + + +def main(): + global DEBUG + global args + global FORCE + + + if len(sys.argv)<2: + show_help() + + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', + 'debug', + 'force', + ]) + if DEBUG == True: + print options + print args + print len(sys.argv) + + for opt, arg in options: + if opt in ('-h', '--help'): + show_help() + elif opt in ('-d', '--debug'): + DEBUG = True + logging.basicConfig(level=logging.INFO) + elif opt in ('-f', '--force'): + FORCE = 1 + else: + logging.info('no option') + for arg in args: + if arg == 'install': + install() + elif arg == 'clean': + uninstall() + else: + show_help() + + + return 0 + +def show_help(): + print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} + sys.exit(0) + +def show_log(txt): + if DEBUG == True: + print "[D6332]"+txt + return + +def exec_cmd(cmd, show): + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) + show_log (cmd +" with result:" + str(status)) + show_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + +def link_dir(prefix,dst): + retry=0 + ret=False + while(ret==False and retry /sys/bus/i2c/devices/i2c-0/new_device' +#'echo inv_cpld 0x33 > /sys/bus/i2c/devices/i2c-0/i2c-2/new_device', +#'echo inv_cpld 0x77 > /sys/bus/i2c/devices/i2c-0/i2c-2/new_device' +] + + +drivers =[ +#kernel-dirvers +'gpio_ich', +'lpc_ich', +'i2c-i801', +'i2c-mux', +'i2c-mux-pca954x', +'i2c-mux-pca9541', +'i2c-dev', +'ucd9000', +#inv-modules +'inv_eeprom', +'inv_cpld', +'lm75', +'inv_platform', +#'monitor', +'swps'] + + +# Modify for fast-reboot +def system_install(boot_option): + global FORCE + + #remove default drivers to avoid modprobe order conflicts + status, output = exec_cmd("rmmod i2c_ismt ", 1) + if status: + print output + if FORCE == 0: + return status + + status, output = exec_cmd("rmmod i2c-i801 ", 1) + if status: + print output + if FORCE == 0: + return status + + status, output = exec_cmd("rmmod gpio_ich ", 1) + if status: + print output + if FORCE == 0: + return status + + status, output = exec_cmd("rmmod lpc_ich ", 1) + if status: + print output + if FORCE == 0: + return status + + #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) + + #install drivers + ''' boot_option: 0 - normal, 1 - fast-reboot''' + for i in range(0,len(drivers)): + if drivers[i] == "swps": + if boot_option == 1: + status, output = exec_cmd("modprobe swps io_no_init=1", 1) + else: + status, output = exec_cmd("modprobe "+drivers[i], 1) + else: + status, output = exec_cmd("modprobe "+drivers[i], 1) + + if status: + print output + if FORCE == 0: + return status + + #instantiate devices + for i in range(0,len(instantiate)): + #time.sleep(1) + status, output = exec_cmd(instantiate[i], 1) + if status: + print output + if FORCE == 0: + return status + for addr_offset in range (0,FAN_NUM): + addr=FAN_VPD_ADDR_BASE+addr_offset + cmd = "i2cdetect -y "+str(FAN_VPD_CHANNEL)+" "+str(addr)+" "+str(addr)+" | grep "+str(hex(addr)).replace('0x','') + result=os.system(cmd) + if( result==0 ): + cmd="echo inv_eeprom "+str(addr)+" > /sys/bus/i2c/devices/i2c-"+FAN_VPD_CHANNEL + status, output = exec_cmd(cmd,1) + if status: + print output + if FORCE == 0: + return status +# +# INV_FIX-4037 +# It replaces the original sff8436 driver with the optoe driver +# + #optoe map to i2c-bus\ + for i in range(12,20): + cmd="echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-0/i2c-4/i2c-"+str(i)+"/new_device" + status, output =exec_cmd(cmd,1) + if status: + print output + if FORCE == 0: + return status + for i in range(20,28): + status, output =exec_cmd("echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-0/i2c-5/i2c-"+str(i)+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + for i in range(28,36): + status, output =exec_cmd("echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-0/i2c-6/i2c-"+str(i)+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + for i in range(36,44): + status, output =exec_cmd("echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-0/i2c-7/i2c-"+str(i)+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + + #make softlink for device info + for i in range(0,len(_path_prefix_list)): + if( os.path.islink(_path_dst_list[i]) ): + os.unlink(_path_dst_list[i]) + syslog.syslog(syslog.LOG_WARNING, "Path %s exists, remove before link again" % _path_dst_list[i] ) + link_dir(_path_prefix_list[i],_path_dst_list[i]) + + return + + +def system_ready(): + if not device_found(): + return False + return True + +def install(boot_option=0): + ''' boot_option: 0 - normal, 1 - fast-reboot ''' + if not device_found(): + print "No device, installing...." + status = system_install(boot_option) + if status: + if FORCE == 0: + return status + else: + print "D6332 devices detected...." + return + +def uninstall(): + global FORCE + #uninstall drivers + for i in range(len(drivers)-1,-1,-1): + status, output = exec_cmd("rmmod "+drivers[i], 1) + if status: + print output + if FORCE == 0: + return status + return + +def device_found(): + ret1, log = exec_cmd("ls "+i2c_prefix+"*0072", 0) + ret2, log = exec_cmd("ls "+i2c_prefix+"i2c-5", 0) + return not(ret1 or ret2) + +if __name__ == "__main__": + main() + + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/i2c-mux-pca9541.c b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/i2c-mux-pca9541.c index 68c44dbc533f..fa78379858e3 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/i2c-mux-pca9541.c +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/i2c-mux-pca9541.c @@ -24,7 +24,7 @@ #include #include -#include +#include /* * The PCA9541 is a bus master selector. It supports two I2C masters connected diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_platform.c b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_platform.c index 212388c8e98d..811ed5e18e58 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_platform.c +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_platform.c @@ -1,11 +1,11 @@ #include -#include +#include #include #include #include #include #include -#include +#include struct inv_i2c_board_info { int ch; diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/ucd9000.c b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/ucd9000.c index 3e3aa950277f..5beba343b327 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/ucd9000.c +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/ucd9000.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include "pmbus.h" enum chips { ucd9000, ucd90120, ucd90124, ucd90160, ucd9090, ucd90910 }; diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/chassis.py index f961cb8cde21..8f3520259038 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/chassis.py @@ -116,15 +116,6 @@ def get_base_mac(self): """ return self._eeprom.base_mac_address() - def get_serial_number(self): - """ - Retrieves the hardware serial number for the chassis - - Returns: - A string containing the hardware serial number for this chassis. - """ - return self._eeprom.serial_number_str() - def get_system_eeprom_info(self): """ Retrieves the full content of system EEPROM information for the chassis diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/eeprom.py index 5840246fddc2..ef0d6385534e 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/eeprom.py +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/eeprom.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python # # Name: eeprom.py, version: 1.0 # @@ -8,7 +7,7 @@ try: from sonic_eeprom import eeprom_tlvinfo import binascii -except ImportError, e: +except ImportError as e: raise ImportError(str(e) + "- required module not found") class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/qsfp.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/qsfp.py index f3f873be08ce..2cc4b6ca593a 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/qsfp.py +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/qsfp.py @@ -205,7 +205,7 @@ def get_model(self): string: Model/part number of device """ transceiver_info_dict = self.get_transceiver_info() - return transceiver_info_dict.get("modelname", "N/A") + return transceiver_info_dict.get("model", "N/A") def get_serial(self): """ @@ -215,7 +215,7 @@ def get_serial(self): string: Serial number of device """ transceiver_info_dict = self.get_transceiver_info() - return transceiver_info_dict.get("serialnum", "N/A") + return transceiver_info_dict.get("serial", "N/A") def get_status(self): """ @@ -240,11 +240,11 @@ def get_transceiver_info(self): keys |Value Format |Information ---------------------------|---------------|---------------------------- type |1*255VCHAR |type of SFP - hardwarerev |1*255VCHAR |hardware version of SFP - serialnum |1*255VCHAR |serial number of the SFP - manufacturename |1*255VCHAR |SFP vendor name - modelname |1*255VCHAR |SFP model name - Connector |1*255VCHAR |connector information + hardware_rev |1*255VCHAR |hardware version of SFP + serial |1*255VCHAR |serial number of the SFP + manufacturer |1*255VCHAR |SFP vendor name + model |1*255VCHAR |SFP model name + connector |1*255VCHAR |connector information encoding |1*255VCHAR |encoding information ext_identifier |1*255VCHAR |extend identifier ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance @@ -256,9 +256,9 @@ def get_transceiver_info(self): ======================================================================== """ - transceiver_info_dict_keys = ['type', 'hardwarerev', - 'serialnum', 'manufacturename', - 'modelname', 'Connector', + transceiver_info_dict_keys = ['type', 'hardware_rev', + 'serial', 'manufacturer', + 'model', 'connector', 'encoding', 'ext_identifier', 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', @@ -305,22 +305,22 @@ def get_transceiver_info(self): if sfp_interface_bulk_data: transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] - transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value']) - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A' - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' - transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A' - transceiver_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A' + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A' + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' + transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A' + transceiver_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A' - transceiver_info_dict['cable_type'] = "Unknown" - transceiver_info_dict['cable_length'] = "Unknown" + transceiver_info_dict['cable_type'] = "Unknown" + transceiver_info_dict['cable_length'] = "Unknown" for key in qsfp_cable_length_tup: if key in sfp_interface_bulk_data['data']: transceiver_info_dict['cable_type'] = key @@ -388,7 +388,7 @@ def get_transceiver_bulk_status(self): # in SFF-8636 dom capability definitions evolving with the versions. qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes((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) + qspf_dom_capability_data = sfpi_obj.parse_dom_capability(qsfp_dom_capability_raw, 0) else: return None diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/sfp.py index d8d88a2df2b0..8c432dc19764 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/sfp.py +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/sfp.py @@ -192,7 +192,7 @@ def get_model(self): string: Model/part number of device """ transceiver_info_dict = self.get_transceiver_info() - return transceiver_info_dict.get("modelname", "N/A") + return transceiver_info_dict.get("model", "N/A") def get_serial(self): """ @@ -202,7 +202,7 @@ def get_serial(self): string: Serial number of device """ transceiver_info_dict = self.get_transceiver_info() - return transceiver_info_dict.get("serialnum", "N/A") + return transceiver_info_dict.get("serial", "N/A") def get_status(self): """ @@ -227,11 +227,11 @@ def get_transceiver_info(self): keys |Value Format |Information ---------------------------|---------------|---------------------------- type |1*255VCHAR |type of SFP - hardwarerev |1*255VCHAR |hardware version of SFP - serialnum |1*255VCHAR |serial number of the SFP - manufacturename |1*255VCHAR |SFP vendor name - modelname |1*255VCHAR |SFP model name - Connector |1*255VCHAR |connector information + hardware_rev |1*255VCHAR |hardware version of SFP + serial |1*255VCHAR |serial number of the SFP + manufacturer |1*255VCHAR |SFP vendor name + model |1*255VCHAR |SFP model name + connector |1*255VCHAR |connector information encoding |1*255VCHAR |encoding information ext_identifier |1*255VCHAR |extend identifier ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance @@ -243,9 +243,9 @@ def get_transceiver_info(self): ======================================================================== """ - transceiver_info_dict_keys = ['type', 'hardwarerev', - 'serialnum', 'manufacturename', - 'modelname', 'Connector', + transceiver_info_dict_keys = ['type', 'hardware_rev', + 'serial', 'manufacturer', + 'model', 'connector', 'encoding', 'ext_identifier', 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', @@ -294,22 +294,22 @@ def get_transceiver_info(self): if sfp_interface_bulk_data: transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] - transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A' - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' - transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A' - transceiver_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A' + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A' + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' + transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A' + transceiver_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A' - transceiver_info_dict['cable_type'] = "Unknown" - transceiver_info_dict['cable_length'] = "Unknown" + transceiver_info_dict['cable_type'] = "Unknown" + transceiver_info_dict['cable_length'] = "Unknown" for key in sfp_cable_length_tup: if key in sfp_interface_bulk_data['data']: transceiver_info_dict['cable_type'] = key diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6556/modules/inv_platform.c b/platform/broadcom/sonic-platform-modules-inventec/d6556/modules/inv_platform.c index 26bd47300dab..ba11c275ce81 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d6556/modules/inv_platform.c +++ b/platform/broadcom/sonic-platform-modules-inventec/d6556/modules/inv_platform.c @@ -5,13 +5,13 @@ * (at your option) any later version. */ #include -#include +#include #include #include #include #include #include -#include +#include struct inv_i2c_board_info { int ch; diff --git a/platform/broadcom/sonic-platform-modules-inventec/d7032q28b/modules/inv_platform.c b/platform/broadcom/sonic-platform-modules-inventec/d7032q28b/modules/inv_platform.c index 52f6a5691d3e..6a2c7353228d 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d7032q28b/modules/inv_platform.c +++ b/platform/broadcom/sonic-platform-modules-inventec/d7032q28b/modules/inv_platform.c @@ -1,12 +1,12 @@ #include //#include -#include +#include #include #include #include #include -#include +#include #include #include diff --git a/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/modules/inv_platform.c b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/modules/inv_platform.c index ea26970075b0..5988bb55a434 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/modules/inv_platform.c +++ b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/modules/inv_platform.c @@ -1,12 +1,12 @@ #include //#include -#include +#include #include #include #include #include -#include +#include //#include //#include diff --git a/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/chassis.py index b5053cf4e2b4..0c83a22cd251 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/chassis.py @@ -119,15 +119,6 @@ def get_base_mac(self): """ return self._eeprom.base_mac_addr() - def get_serial_number(self): - """ - Retrieves the hardware serial number for the chassis - - Returns: - A string containing the hardware serial number for this chassis. - """ - return self._eeprom.serial_number_str() - def get_system_eeprom_info(self): """ Retrieves the full content of system EEPROM information for the chassis diff --git a/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/eeprom.py index b0ebee54ee24..70a4b0ecb437 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/eeprom.py +++ b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/eeprom.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python # # Name: eeprom.py, version: 1.0 # @@ -8,7 +7,7 @@ try: from sonic_eeprom import eeprom_tlvinfo import binascii -except ImportError, e: +except ImportError as e: raise ImportError(str(e) + "- required module not found") class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): diff --git a/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/sfp.py index 47d88afa13a4..a18d98d502f5 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/sfp.py +++ b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/sfp.py @@ -11,7 +11,6 @@ import os import time import subprocess -import sonic_device_util from ctypes import create_string_buffer try: @@ -232,7 +231,7 @@ def __init__(self, sfp_index, sfp_type): port_eeprom_path = eeprom_path.format(self.port_to_i2c_mapping[x]) self.port_to_eeprom_mapping[x] = port_eeprom_path - self.info_dict_keys = ['type', 'hardwarerev', 'serialnum', 'manufacturename', 'modelname', 'Connector', 'encoding', 'ext_identifier', + self.info_dict_keys = ['type', 'hardware_rev', 'serial', 'manufacturer', 'model', 'connector', 'encoding', 'ext_identifier', 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance', 'vendor_date', 'vendor_oui'] self.dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', 'temperature', 'voltage', @@ -426,11 +425,11 @@ def get_transceiver_info(self): keys |Value Format |Information ---------------------------|---------------|---------------------------- type |1*255VCHAR |type of SFP - hardwarerev |1*255VCHAR |hardware version of SFP - serialnum |1*255VCHAR |serial number of the SFP - manufacturename |1*255VCHAR |SFP vendor name - modelname |1*255VCHAR |SFP model name - Connector |1*255VCHAR |connector information + hardware_rev |1*255VCHAR |hardware version of SFP + serial |1*255VCHAR |serial number of the SFP + manufacturer |1*255VCHAR |SFP vendor name + model |1*255VCHAR |SFP model name + connector |1*255VCHAR |connector information encoding |1*255VCHAR |encoding information ext_identifier |1*255VCHAR |extend identifier ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance @@ -486,13 +485,13 @@ def get_transceiver_info(self): return None transceiver_info_dict['type'] = sfp_type_data['data']['type']['value'] - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] transceiver_info_dict['vendor_oui'] = 'N/A' transceiver_info_dict['vendor_date'] = 'N/A' - transceiver_info_dict['Connector'] = 'N/A' + transceiver_info_dict['connector'] = 'N/A' transceiver_info_dict['encoding'] = 'N/A' transceiver_info_dict['ext_identifier'] = 'N/A' transceiver_info_dict['ext_rateselect_compliance'] = 'N/A' @@ -557,13 +556,13 @@ def get_transceiver_info(self): end = start + XCVR_VENDOR_DATE_WIDTH sfp_vendor_date_data = sfpi_obj.parse_vendor_date(sfp_interface_bulk_raw[start : end], 0) transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] transceiver_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] - transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] @@ -637,7 +636,7 @@ def get_transceiver_bulk_status(self): qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes( (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( + qspf_dom_capability_data = sfpi_obj.parse_dom_capability( qsfp_dom_capability_raw, 0) else: return None diff --git a/platform/broadcom/sonic-platform-modules-inventec/d7264q28b/modules/inv_platform.c b/platform/broadcom/sonic-platform-modules-inventec/d7264q28b/modules/inv_platform.c index 720a4cd2257b..753f8cd3407d 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d7264q28b/modules/inv_platform.c +++ b/platform/broadcom/sonic-platform-modules-inventec/d7264q28b/modules/inv_platform.c @@ -1,12 +1,12 @@ #include //#include -#include +#include #include #include #include #include #include -#include +#include //#include //#include diff --git a/platform/broadcom/sonic-platform-modules-inventec/debian/control b/platform/broadcom/sonic-platform-modules-inventec/debian/control index 86f7e7b20f65..7a435d9b6e60 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/debian/control +++ b/platform/broadcom/sonic-platform-modules-inventec/debian/control @@ -2,35 +2,40 @@ Source: sonic-inventec-platform-modules Section: main Priority: extra Maintainer: Inventec -Build-Depends: debhelper (>= 8.0.0), bzip2 +Build-Depends: debhelper (>= 8.0.0), bzip2, dh-python Standards-Version: 3.9.3 Package: platform-modules-d7032q28b Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led Package: platform-modules-d7054q28b Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led Package: platform-modules-d6254qs Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led Package: platform-modules-d6556 Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led Package: platform-modules-d6356 Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led Package: platform-modules-d7264q28b Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned +Description: kernel modules for platform devices such as fan, led + +Package: platform-modules-d6332 +Architecture: amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led diff --git a/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6332.init b/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6332.init new file mode 100644 index 000000000000..9b14421a1324 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6332.init @@ -0,0 +1,74 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: setup-board +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Setup Inventec d6356j board. +### END INIT INFO + +PLATFORM_DIR=/usr/share/sonic/device/x86_64-inventec_d6332-r0/plugins +PLUGIN_DIR=/usr/lib/python2.7/dist-packages/inventec_plugin + +PLATFORM_DAEMON=$PLATFORM_DIR/platfmgr.py +PLATFORM_DAEMON_NAME=platfmgr +INVSYNCD_DAEMON=$PLUGIN_DIR/invSyncd.py +INVSYNCD_DAEMON_NAME=invSyncd + +# The process ID of the script when it runs is stored here: +PLATFORM_PIDFILE=/var/run/$PLATFORM_DAEMON_NAME.pid + +do_monitor_start() { + /sbin/start-stop-daemon --quiet --oknodo --pidfile $PLATFORM_PIDFILE --make-pidfile --startas $PLATFORM_DAEMON --start --background -- $DAEMON_OPTS + /sbin/start-stop-daemon --quiet --oknodo --pidfile $INVSYNCD_PIDFILE --make-pidfile --startas $INVSYNCD_DAEMON --start --background -- $DAEMON_OPTS +} + +do_monitor_stop() { + /sbin/start-stop-daemon --quiet --oknodo --stop --pidfile $PLATFORM_PIDFILE --retry 10 + /sbin/start-stop-daemon --quiet --oknodo --stop --pidfile $INVSYNCD_PIDFILE --retry 10 +} + +# Check Fast-Reboot cause +FAST_REBOOT='no' +case "$(cat /proc/cmdline)" in + *fast-reboot*|*warm*) + FAST_REBOOT='yes' + ;; + *) + FAST_REBOOT='no' + ;; +esac + +case "$1" in +start) + echo -n "Setting up board... " + if [ "$FAST_REBOOT" = "yes" ] ; then + /usr/local/bin/inventec_d6332_util.py -f fast-reboot-install + else + /usr/local/bin/inventec_d6332_util.py -f install + fi + do_monitor_${1} + echo "done." + ;; + +stop) + /usr/local/bin/inventec_d6332_util.py -f clean + do_monitor_${1} + echo "done." + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/platform-modules-d6332.init {start|stop}" + exit 1 + ;; +esac + +exit 0 diff --git a/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6332.install b/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6332.install new file mode 100644 index 000000000000..d21e85a86e1e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6332.install @@ -0,0 +1,4 @@ +d6332/utils/inventec_d6332_util.py /usr/local/bin +systemd/platform-modules-d6332.service /lib/systemd/system +d6332/utils/sonic_platform-1.0-py2-none-any.whl /usr/share/sonic/device/x86_64-inventec_d6332-r0 +d6332/utils/sonic_platform-1.0-py3-none-any.whl /usr/share/sonic/device/x86_64-inventec_d6332-r0 \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6332.postinst b/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6332.postinst new file mode 100644 index 000000000000..dff0ecc8522e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6332.postinst @@ -0,0 +1,25 @@ +#!/bin/sh +# Automatically added by dh_systemd_enable +# This will only remove masks created by d-s-h on package removal. +deb-systemd-helper unmask platform-modules-d6356j.service >/dev/null || true + +# was-enabled defaults to true, so new installations run enable. +if deb-systemd-helper --quiet was-enabled platform-modules-d6332.service; then + # Enables the unit on first installation, creates new + # symlinks on upgrades if the unit file has changed. + deb-systemd-helper enable platform-modules-d6332.service >/dev/null || true +else + # Update the statefile to add new symlinks (if any), which need to be + # cleaned up on purge. Also remove old symlinks. + deb-systemd-helper update-state platform-modules-d6332.service >/dev/null || true +fi +# End automatically added section +depmod -a +# Automatically added by dh_installinit +if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ]; then + if [ -x "/etc/init.d/platform-modules-d6332" ]; then + update-rc.d platform-modules-d6332 defaults >/dev/null + invoke-rc.d platform-modules-d6332 start || exit $? + fi +fi +# End automatically added section diff --git a/platform/broadcom/sonic-platform-modules-inventec/debian/rules b/platform/broadcom/sonic-platform-modules-inventec/debian/rules index f6c1aa1b2e70..0044efbba491 100755 --- a/platform/broadcom/sonic-platform-modules-inventec/debian/rules +++ b/platform/broadcom/sonic-platform-modules-inventec/debian/rules @@ -14,7 +14,7 @@ export INSTALL_MOD_DIR:=extra KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= d7032q28b d7054q28b d6254qs d6556 d6356 d7264q28b +MODULE_DIRS:= d7032q28b d7054q28b d6254qs d6556 d6356 d7264q28b d6332 %: dh $@ --with python2,systemd @@ -22,11 +22,17 @@ MODULE_DIRS:= d7032q28b d7054q28b d6254qs d6556 d6356 d7264q28b override_dh_auto_build: (for mod in $(MODULE_DIRS); do \ make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ - if [ $$mod = "d7054q28b" ] || [ $$mod = "d6356" ]; then \ + if [ $$mod = "d7054q28b" ] || [ $$mod = "d6356" ] || [ $$mod = "d6332" ]; then \ cd $(MOD_SRC_DIR)/$${mod}; \ python2 setup.py build; \ python2 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/utils; \ cd $(MOD_SRC_DIR); \ + fi; \ + if [ $$mod = "d6332" ]; then \ + cd $(MOD_SRC_DIR)/$${mod}; \ + python3 setup.py build; \ + python3 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/utils; \ + cd $(MOD_SRC_DIR); \ fi \ done) @@ -36,10 +42,15 @@ override_dh_auto_install: $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ cp $(MOD_SRC_DIR)/$${mod}/modules/*.ko \ debian/platform-modules-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ - if [ $$mod = "d7054q28b" ] || [ $$mod = "d6356" ]; then \ + if [ $$mod = "d7054q28b" ] || [ $$mod = "d6356" ] || [ $$mod = "d6332" ]; then \ cd $(MOD_SRC_DIR)/$${mod}; \ python2 setup.py install --root=$(MOD_SRC_DIR)/debian/platform-modules-$${mod} --install-layout=deb; \ cd $(MOD_SRC_DIR); \ + fi; \ + if [ $$mod = "d6332" ]; then \ + cd $(MOD_SRC_DIR)/$${mod}; \ + python3 setup.py install --root=$(MOD_SRC_DIR)/debian/platform-modules-$${mod} --install-layout=deb; \ + cd $(MOD_SRC_DIR); \ fi \ done) diff --git a/platform/broadcom/sonic-platform-modules-inventec/systemd/platform-modules-d6332.service b/platform/broadcom/sonic-platform-modules-inventec/systemd/platform-modules-d6332.service new file mode 100644 index 000000000000..1cbe712da280 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/systemd/platform-modules-d6332.service @@ -0,0 +1,13 @@ +[Unit] +Description=Inventec d6332 Platform modules +After=local-fs.target +Before=pmon.service + +[Service] +Type=oneshot +ExecStart=-/etc/init.d/platform-modules-d6332 start +ExecStop=-/etc/init.d/platform-modules-d6332 stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-juniper/README.md b/platform/broadcom/sonic-platform-modules-juniper/README.md index 8d2820a74b2e..3a661cef8eeb 100644 --- a/platform/broadcom/sonic-platform-modules-juniper/README.md +++ b/platform/broadcom/sonic-platform-modules-juniper/README.md @@ -1 +1,290 @@ -platform drivers for Juniper QFX5210 for the SONiC project +Juniper Networks Platform Support for SONiC +=========================================== + +This readme provides information on how to install and upgrade ONIE and SONiC images on the Juniper Networks switches. + +Note: Switches ship with ONIE and SONiC images preinstalled. + +## Supported platforms + +The following Juniper Networks platforms are supported for the SONiC operating system: + + - QFX5210-64C-S + - QFX5200-32C-S + + +## Building and Installing ONIE + +ONIE is the bootloader used and it's a prerequisite to install ONIE on the switches before installing SONiC. + +1. Cross compile ONIE + +To compile ONIE, you need to change the directories to "build-config" and then based on the platform issue the following commands + +a) For QFX5210-64C-S platform, invoke "make MACHINEROOT=../machine/juniper MACHINE=juniper_qfx5210 all". + +For example: + +``` + $ cd build-config + $ make -j4 MACHINEROOT=../machine/juniper MACHINE=juniper_qfx5210 all +``` + +b) For QFX5200-32C-S platform, invoke "make MACHINEROOT=../machine/juniper MACHINE=juniper_qfx5200 all". + +ONIE binaries are located at the directory /build/images. The following command shows how to navigate the directory to view the ONIE binaries: + +``` +stack@controller:~/ONIE_J/onie/build/images$ ls -rlt + +total 40740 + +-rw-rw-r-- 1 stack stack 3710240 Aug 3 12:32 juniper_x86-r0.vmlinuz -- ONIE kernel image +-rw-rw-r-- 1 stack stack 6038416 Aug 3 12:32 juniper_x86-r0.initrd -- ONIE initramfs (filesystem) +-rw-rw-r-- 1 stack stack 9811831 Aug 3 12:32 onie-updater-x86_64-juniper_x86-r0 -- ONIE self-update image for installing ONIE. +-rw-rw-r-- 1 stack stack 22151168 Aug 3 12:33 onie-recovery-x86_64-juniper_x86-r0.iso -- Recovery ISO image to create a bootable USB memory device for installing/recovery ONIE. +-rw-rw-r-- 1 stack stack 31465984 Aug 3 12:33 onie-recovery-x86_64-juniper_qfx5210-r0.efi64.pxe -- Recovery PXE image used for installing ONIE using PXE Network install. +``` + + +Note: Use the following command to build a demo target: + +For example: + +``` + $ make -j4 MACHINEROOT=../machine/juniper MACHINE=juniper_qfx5210 all demo +``` + +In addition to the above list of binary files, the following two binary files are also created: + +``` +-rw-rw---- 1 build build 12576008 Aug 19 16:30 demo-installer-x86_64-juniper_qfx5210-r0.bin +-rw-rw---- 1 build build 12576008 Aug 19 16:30 demo-diag-installer-x86_64-juniper_qfx5210-r0.bin +``` + +You can install these binary files by using the 'onie-nos-install' command to test the install / boot workflow. + +Use the following command for make clean: + +For example: + +``` + $ make machine-clean MACHINEROOT=../machine/juniper MACHINE=juniper_qfx5210 +``` + + +## Installing ONIE + +To install ONIE on a new switch, you can use one of the following ONIE recovery images: + +1) ..iso -- Hybrid ISO image. +2) ..efi64.pxe -- PXE image for UEFI64 machines. + +Note: Second method is not applicable for QFX5200-32C-S + + +## Creating an ISO Recovery Image + +You can use the recovery ISO (.iso) image to create a bootable USB memory device. + +To create a bootable USB memory device, use the "dd" command on a Linux workstation as follows: + +``` + $ dd if=.iso of=/dev/sdX bs=10M +``` + +For example: + +``` + $ dd if=onie-recovery-x86_64-juniper_qfx5210-r0.iso of=/dev/sdb bs=10M +``` + +You can find the correct "/dev/sdX" by validating the "dmesg" output after inserting an USB device into the Linux workstation. + + +1) Booting from a USB Memory Device + +To boot from an external USB memory device connected to the switch, you need to: + +a. Insert the USB memory device to the USB port of the switch. + +b. Power on the switch and enter the BIOS configuration by pressing the Esc key, as displayed in the console screen. + +c. Set the hard drive boot order as follows: + + When you see the "Boot Option #1" displayed on the console screen, select the USB memory device: + + Boot-->Boot Option Priorities-->Boot Option #1 + + If the USB memory device name is not listed in "Boot Option #1", check the priorities in the hard drive boot order: + + Boot-->Hard Drive BBS Priorities-->Boot Option #1 + + + For example, consider "JetFlashTranscend 8GB 8.07" as the USB memory device, the boot order will display as follows: + +``` + Boot Option Priorities + + Boot Option #1 [JetFlashTranscend 8...] + + Boot Option #2 [ATP ATP IG eUSB 1100] + + Boot Option #3 [IBA GE Slot 00A0 v1543] + + Boot Option #4 [UEFI: Built-in EFI ...] +``` + +d. Go to "Save & Exit" in the BIOS screen and from the Boot Override option select the USB memory device (For example, JetFlashTranscend 8GB 8.07). + +e. After a few seconds, the switch would restart and boot from the USB memory device and then you will see the following on the console screen: + +``` + GNU GRUB version 2.02~beta2+e4a1fe391 + + +----------------------------------------------------------------------------+ + |*ONIE: Rescue | + | ONIE: Embed ONIE | + | | + | | + | | + | | + | | + | | + | | + | | + | | + | | + +----------------------------------------------------------------------------+ + + Use the ^ and v keys to select which entry is highlighted. + Press enter to boot the selected OS, `e' to edit the commands before booting or `c' for a command-line. +``` + +f. Select "ONIE: Embed ONIE" to create a fresh partition to install ONIE automatically. + + Warning: All the data on the hard disk drive will be erased. + +g. Select "ONIE: Rescue" to enter the ONIE recovery command-line shell (Optional). + + + +2) Recovering ONIE using PXE-UEFI64 Recovery Image + +Note: This section is only applicable for QFX5210-64C-S platform. + +You can use the onie-recovery-x86_64-juniper_qfx5210-r0.efi64.pxe image to recover the ONIE image through UEFI PXE. + + The onie-recovery-x86_64-juniper_qfx5210-r0.efi64.pxe is made for the QFX5210-64C-S switch that has a PXE client which is based on UEFI64. + The onie-recovery-x86_64-juniper_qfx5210-r0.efi64.pxe is a combination of grub-efi-64 and the .iso recovery image, that looks like an UEFI application. The UEFI PXE client on the QFX5210-64C-S can then boot it. + + For more information on UEFI PXE Netboot, see https://wiki.ubuntu.com/UEFI/PXE-netboot-install. + + Note: To install the PXE-UEFI64 recovery image over the network, you need to configure your DHCP server so that DHCP clients receives the onie-recovery-x86_64-juniper_qfx5210-r0.efi64.pxe image as the bootfile. + + To enable IPv4 PXE boot on the QFX5210-64C-S switch: + + 1) Enter the BIOS configuration. + 2) Click "Save & Exit" menu on the "Boot Override" option. + 3) Select "UEFI: IP4 Broadcom NetXtreme Gigabit Ethernet" + +## Related Documentation for ONIE: + +The following links provide more information about ONIE: + + 1. ONIE documentation: https://opencomputeproject.github.io/onie/. + 2. How to build and install ONIE on QFX5210-64C-S switch, see https://github.com/opencomputeproject/onie/blob/master/machine/juniper/juniper_qfx5210/INSTALL. + +## SONiC Build Process: + +The instruction on how to build an ONIE compatible network operating system (NOS) installer image for Juniper Networks switches, and how to build docker images running inside the NOS is available at https://github.com/Azure/sonic-buildimage#usage. + + +## Install SONiC on the Juniper Networks switch:es + +You need to copy the SONiC image 'sonic-broadcom.bin' to the switch. You can copy the sonic-broadcom.bin to an USB memory device and insert it to the USB port of the switch. You can also use the 'scp' command to copy the sonic-broadcom.bin image to the switch over the network. + +Note: Unmount the USB memory device after copying the sonic-broadcom.bin. For example, umount /dev/sdX, where X is the name of the drive of the USB memory device. + +Run the following command to install SONIC: + +``` +For example, +ONIE:/var/tmp # onie-nos-install /var/tmp/sonic-broadcom.bin +``` + +## Booting SONiC + +The switch restarts automatically after the SONiC image has been successfully installed. + +1) Select SONiC from the GRUB boot manager. + +``` + GNU GRUB version 2.02 + + +----------------------------------------------------------------------------+ + |*SONiC-OS-master.0-dirty-20190913.060138 | + | ONIE | + | | + | | + | | + | | + | | + | | + | | + | | + | | + | | + +----------------------------------------------------------------------------+ + + Use the ^ and v keys to select which entry is highlighted. + Press enter to boot the selected OS, `e' to edit the commands + before booting or `c' for a command-line. +``` + +2. At the SONiC login prompt, enter the username as admin and password as YourPaSsWoRd. + +You can now start configuring the Juniper Networks switch running SONiC as its operating system. + + +## Upgrading SONiC image + +To upgrade the SONiC operating system to a latest version, you need to: + + 1. Copy the latest image of the SONiC image to the switch. + 2. Run the following command from the directory where the latest SONiC image has been copied. + +``` +$ sudo ./sonic-braodcom.bin +``` + +or + +``` +$ sudo sonic-installer ./sonic-broadcom.bin -y +``` + + +## Uninstalling SONiC image + +To unintall SONiC operating system from the switch, you need to: + + 1. Reboot the switch. + 2. Go to the ONIE GRUB menu and then select ONIE: Uninstall OS option to uninstall SONiC. + +For more details on drivers and platform scripts see the following links: + +1) QFX5210-64C-S: https://github.com/Azure/sonic-buildimage/blob/master/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/README + +2) QFX5200-32C-S: https://github.com/Azure/sonic-buildimage/blob/master/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/README + +## Related Documentation for SONiC: + +The following links provide more information about SONiC: + 1. SONiC documentation: https://github.com/azure/sonic/wiki. + +## Viewing the Device Revision of the FRU Model from IDEEPROM + +You can view the device revisions of the FRU model from IDEEPROM by using the show platform syseeprom CLI command. + +Note: The Device version shown is the HEX ASCII equivalent of the FRU model. For example, if the device version shows 41, then the HEX ASCII equivalent is character A. diff --git a/platform/broadcom/sonic-platform-modules-juniper/common/modules/gpio-tmc.c b/platform/broadcom/sonic-platform-modules-juniper/common/modules/gpio-tmc.c new file mode 100644 index 000000000000..7b02e8a5bc74 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/common/modules/gpio-tmc.c @@ -0,0 +1,661 @@ +/* + * Juniper Networks TMC GPIO driver + * + * Copyright (C) 2020 Juniper Networks + * Author: Ashish Bhensdadia + * + * This driver implement the GPIO set/get functionality + * + * This program is free software; 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. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "jnx-tmc.h" + +#define TMC_GPIO_MAX_BITS_PER_REG 16 +#define TMC_GPIO_SFP_MAX_BITS_PER_REG 2 +#define TMC_GPIO_PTPCFG_MAX_BITS_PER_REG 8 + +#define TMC_GPIO_FIND_GROUP(gpio) \ + ((gpio) / TMC_GPIO_MAX_BITS_PER_REG) +#define TMC_GPIO_FIND_GPIO(gpio) \ + ((gpio) % TMC_GPIO_MAX_BITS_PER_REG) + +#define TMC_GPIO_SFP_FIND_GROUP(gpio) \ + ((gpio) / TMC_GPIO_SFP_MAX_BITS_PER_REG) +#define TMC_GPIO_SFP_FIND_GPIO(gpio) \ + ((gpio) % TMC_GPIO_SFP_MAX_BITS_PER_REG) + +#define TMC_GPIO_PTPCFG_FIND_GPIO(gpio) \ + ((gpio) % TMC_GPIO_PTPCFG_MAX_BITS_PER_REG) + +#define TMC_GPIO_MAX_NGPIO_PER_GROUP 320 + +#define TMC_PFE_QSFP_RESET_OFFSET 0x4 +#define TMC_PFE_QSFP_PRESENT_OFFSET 0x8 +#define TMC_PFE_QSFP_PHY_RESET_OFFSET 0x10 +#define TMC_PFE_QSFP_LPMOD_OFFSET 0x78 +#define TMC_PFE_QSFP_LED_CTRL_OFFSET 0x20 + +#define TMC_PFE_LANES_GREEN_LED_VALUE 0x3 +#define TMC_PFE_LANE0_GREEN_LED_BIT_POSITION 0 +#define TMC_PFE_LANE1_GREEN_LED_BIT_POSITION 2 +#define TMC_PFE_LANE2_GREEN_LED_BIT_POSITION 4 +#define TMC_PFE_LANE3_GREEN_LED_BIT_POSITION 6 + +#define TMC_PFE_LANES_BEACON_LED_VALUE 0x2 +#define TMC_PFE_LANE0_BEACON_LED_BIT_POSITION 0 +#define TMC_PFE_LANE1_BEACON_LED_BIT_POSITION 2 +#define TMC_PFE_LANE2_BEACON_LED_BIT_POSITION 4 +#define TMC_PFE_LANE3_BEACON_LED_BIT_POSITION 6 + +#define TMC_PFE_LANES_FAULT_LED_VALUE 0x1 +#define TMC_PFE_LANE0_FAULT_LED_BIT_POSITION 0 +#define TMC_PFE_LANE1_FAULT_LED_BIT_POSITION 2 +#define TMC_PFE_LANE2_FAULT_LED_BIT_POSITION 4 +#define TMC_PFE_LANE3_FAULT_LED_BIT_POSITION 6 + +#define TMC_PFE_SFPSB0_TX_DISABLE_OFFSET 0x0 +#define TMC_PFE_SFPSB0_LED_CTRL_OFFSET 0xC +#define TMC_PFE_SFPSB0_LED_ACTIVITY_OFFSET 0x14 +#define TMC_PFE_SFPSB0_PRESENT_OFFSET 0x18 +#define TMC_PFE_SFPSB0_LOSS_OFFSET 0x1C +#define TMC_PFE_SFPSB0_TX_FAULT_OFFSET 0x20 + +#define TMC_PFE_SFPSB1_TX_DISABLE_OFFSET 0x0 +#define TMC_PFE_SFPSB1_LED_CTRL_OFFSET 0x8 +#define TMC_PFE_SFPSB1_LED_ACTIVITY_OFFSET 0x10 +#define TMC_PFE_SFPSB1_PRESENT_OFFSET 0x14 +#define TMC_PFE_SFPSB1_LOSS_OFFSET 0x18 +#define TMC_PFE_SFPSB1_TX_FAULT_OFFSET 0x1C + +/* + * Index 4 to 15 is used for QSFP starting with + * QSFP_LED_LANE0_GREEN. To keep multibit set/get common + * starting SFP_LED_LANE0_GREEN with 16 which will avoid + * conflict with QSFP enums. + */ +#define SFP_LED_OP_START_INDEX 16 + +/* + * Used for off-setting SFP led op index + */ +#define SFP_LED_OP_OFFSET 0xB + +/* + * SFP slave blocks + */ +#define SFP_SLAVE0_BLOCK 0x1 +#define SFP_SLAVE1_BLOCK 0x2 + +/* + * each group represent the 16 gpios. + * QSFP_RST - QSFP_LPMODE + * each bit represent the one gpio + * exemple: bits[0:15] - bit0 - gpio0 + * QSFP_LED_LANE0_GREEN - QSFP_LED_LANE3_FAULT + * here, number represent the one gpio + * exemple: bits[0:1] + * 00 - gpio off, 01 - gpio on [ gpio0] + * 00 - gpio off, 10 - gpio on [ gpio1] + * 00 - gpio off, 11 - gpio on [ gpio2] + * + */ +enum { + QSFP_RST, + QSFP_PRESENT, + QSFP_PHY_RST, + QSFP_LPMOD, + QSFP_LED_LANE0_GREEN, + QSFP_LED_LANE1_GREEN, + QSFP_LED_LANE2_GREEN, + QSFP_LED_LANE3_GREEN, + QSFP_LED_LANE0_BEACON, + QSFP_LED_LANE1_BEACON, + QSFP_LED_LANE2_BEACON, + QSFP_LED_LANE3_BEACON, + QSFP_LED_LANE0_FAULT, + QSFP_LED_LANE1_FAULT, + QSFP_LED_LANE2_FAULT, + QSFP_LED_LANE3_FAULT, + TMC_PFE_GPIO_GROUP_MAX +}; + +enum sfp_op { + SFP_TX_DISABLE, + SFP_LED_ACTIVITY, + SFP_PRESENT, + SFP_SFP_LOS, + SFP_TX_FAULT, + SFP_LED_LANE0_GREEN = SFP_LED_OP_START_INDEX, + SFP_LED_LANE1_GREEN, + SFP_LED_LANE2_GREEN, + SFP_LED_LANE3_GREEN, + SFP_LED_LANE0_BEACON, + SFP_LED_LANE1_BEACON, + SFP_LED_LANE2_BEACON, + SFP_LED_LANE3_BEACON, + SFP_LED_LANE0_FAULT, + SFP_LED_LANE1_FAULT, + SFP_LED_LANE2_FAULT, + SFP_LED_LANE3_FAULT, + TMC_PFE_SFP_GPIO_GROUP_MAX +}; + +static const u32 group_offset[TMC_PFE_GPIO_GROUP_MAX] = { + TMC_PFE_QSFP_RESET_OFFSET, + TMC_PFE_QSFP_PRESENT_OFFSET, + TMC_PFE_QSFP_PHY_RESET_OFFSET, + TMC_PFE_QSFP_LPMOD_OFFSET, + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE0 GREEN */ + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE1 GREEN */ + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE2 GREEN */ + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE3 GREEN */ + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE0 BEACON */ + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE1 BEACON */ + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE2 BEACON */ + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE3 BEACON */ + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE0 FAULT */ + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE1 FAULT */ + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE2 FAULT */ + TMC_PFE_QSFP_LED_CTRL_OFFSET, /* LANE3 FAULT */ +}; + +static const u32 sfp_slaveb0_group_offset[TMC_PFE_SFP_GPIO_GROUP_MAX] = { + TMC_PFE_SFPSB0_TX_DISABLE_OFFSET, + TMC_PFE_SFPSB0_LED_ACTIVITY_OFFSET, + TMC_PFE_SFPSB0_PRESENT_OFFSET, + TMC_PFE_SFPSB0_LOSS_OFFSET, + TMC_PFE_SFPSB0_TX_FAULT_OFFSET, + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE0 GREEN */ + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE1 GREEN */ + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE2 GREEN */ + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE3 GREEN */ + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE0 BEACON */ + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE1 BEACON */ + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE2 BEACON */ + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE3 BEACON */ + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE0 FAULT */ + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE1 FAULT */ + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE2 FAULT */ + TMC_PFE_SFPSB0_LED_CTRL_OFFSET, /* LANE3 FAULT */ +}; + +static const u32 sfp_slaveb1_group_offset[TMC_PFE_SFP_GPIO_GROUP_MAX] = { + TMC_PFE_SFPSB1_TX_DISABLE_OFFSET, + TMC_PFE_SFPSB1_LED_ACTIVITY_OFFSET, + TMC_PFE_SFPSB1_PRESENT_OFFSET, + TMC_PFE_SFPSB1_LOSS_OFFSET, + TMC_PFE_SFPSB1_TX_FAULT_OFFSET, + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE0 GREEN */ + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE1 GREEN */ + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE2 GREEN */ + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE3 GREEN */ + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE0 BEACON */ + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE1 BEACON */ + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE2 BEACON */ + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE3 BEACON */ + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE0 FAULT */ + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE1 FAULT */ + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE2 FAULT */ + TMC_PFE_SFPSB1_LED_CTRL_OFFSET, /* LANE3 FAULT */ +}; + +struct tmc_gpio_info { + int (*get)(struct gpio_chip *, unsigned int); + void (*set)(struct gpio_chip *, unsigned int, int); + int (*dirin)(struct gpio_chip *, unsigned int); + int (*dirout)(struct gpio_chip *, unsigned int, int); +}; + +struct tmc_gpio_chip { + const struct tmc_gpio_info *info; + void __iomem *base; + struct device *dev; + struct gpio_chip gpio; + int ngpio; + spinlock_t gpio_lock; /* gpio lock */ + int sfp_slave_block; +}; + +/* slave gpio max */ +static int gpio_max = 320; +module_param(gpio_max, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(gpio_max, "Maximum number of gpio for SLAVE TMC GPIO"); + +/* + * generic bit operation functions + */ +static u32 tmc_gpio_reset_bits(u32 state, u32 val, u32 shift) +{ + state &= ~(val << shift); + return state; +}; + +static u32 tmc_gpio_set_bits(u32 state, u32 val, u32 shift) +{ + state |= (val << shift); + return state; +}; + +static u32 tmc_gpio_find_bits_val(u32 state, u32 shift, u32 mask) +{ + return ((state >> shift)) & mask; +}; + +#define to_tmc_chip(chip) \ + container_of((chip), struct tmc_gpio_chip, gpio) + +/* + * tmc_gpio_multiple_bitsop - Generic TMC GPIO multiple bits operation + */ +static void tmc_gpio_multiple_bitsop(struct tmc_gpio_chip *chip, + unsigned int gpiono, u32 group, u32 offset, bool set) +{ + u32 gpio_state, led_val, bit_shift; + unsigned long flags; + void __iomem *iobase; + + iobase = chip->base + offset; + + dev_dbg(chip->dev, "TMC GPIO multiple bitop group=%u, " + "gpiono=%u, offet:=%u, set=%u\n", group, gpiono, offset, set); + + spin_lock_irqsave(&chip->gpio_lock, flags); + + switch (group) { + case QSFP_LED_LANE0_GREEN: + case SFP_LED_LANE0_GREEN: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_GREEN_LED_VALUE; + bit_shift = TMC_PFE_LANE0_GREEN_LED_BIT_POSITION; + break; + case QSFP_LED_LANE1_GREEN: + case SFP_LED_LANE1_GREEN: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_GREEN_LED_VALUE; + bit_shift = TMC_PFE_LANE1_GREEN_LED_BIT_POSITION; + break; + case QSFP_LED_LANE2_GREEN: + case SFP_LED_LANE2_GREEN: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_GREEN_LED_VALUE; + bit_shift = TMC_PFE_LANE2_GREEN_LED_BIT_POSITION; + break; + case QSFP_LED_LANE3_GREEN: + case SFP_LED_LANE3_GREEN: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_GREEN_LED_VALUE; + bit_shift = TMC_PFE_LANE3_GREEN_LED_BIT_POSITION; + break; + case QSFP_LED_LANE0_BEACON: + case SFP_LED_LANE0_BEACON: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_BEACON_LED_VALUE; + bit_shift = TMC_PFE_LANE0_BEACON_LED_BIT_POSITION; + break; + case QSFP_LED_LANE1_BEACON: + case SFP_LED_LANE1_BEACON: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_BEACON_LED_VALUE; + bit_shift = TMC_PFE_LANE1_BEACON_LED_BIT_POSITION; + break; + case QSFP_LED_LANE2_BEACON: + case SFP_LED_LANE2_BEACON: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_BEACON_LED_VALUE; + bit_shift = TMC_PFE_LANE2_BEACON_LED_BIT_POSITION; + break; + case QSFP_LED_LANE3_BEACON: + case SFP_LED_LANE3_BEACON: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_BEACON_LED_VALUE; + bit_shift = TMC_PFE_LANE3_BEACON_LED_BIT_POSITION; + break; + case QSFP_LED_LANE0_FAULT: + case SFP_LED_LANE0_FAULT: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_FAULT_LED_VALUE; + bit_shift = TMC_PFE_LANE0_FAULT_LED_BIT_POSITION; + break; + case QSFP_LED_LANE1_FAULT: + case SFP_LED_LANE1_FAULT: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_FAULT_LED_VALUE; + bit_shift = TMC_PFE_LANE1_FAULT_LED_BIT_POSITION; + break; + case QSFP_LED_LANE2_FAULT: + case SFP_LED_LANE2_FAULT: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_FAULT_LED_VALUE; + bit_shift = TMC_PFE_LANE2_FAULT_LED_BIT_POSITION; + break; + case QSFP_LED_LANE3_FAULT: + case SFP_LED_LANE3_FAULT: + gpio_state = ioread32(iobase+(0x004*gpiono)); + led_val = TMC_PFE_LANES_FAULT_LED_VALUE; + bit_shift = TMC_PFE_LANE3_FAULT_LED_BIT_POSITION; + break; + + default: + spin_unlock_irqrestore(&chip->gpio_lock, flags); + return; + } + + if (set) { + gpio_state = tmc_gpio_reset_bits(gpio_state, 0x3, bit_shift); + gpio_state = tmc_gpio_set_bits(gpio_state, led_val, bit_shift); + } else { + gpio_state = tmc_gpio_reset_bits(gpio_state, 0x3, bit_shift); + } + + iowrite32(gpio_state, (iobase+(0x004*gpiono))); + + spin_unlock_irqrestore(&chip->gpio_lock, flags); + + return; +}; + +/* + * tmc_gpio_one_bitop - Generic TMC GPIO single bit operation + */ +static void tmc_gpio_one_bitop(struct tmc_gpio_chip *chip, + unsigned int bit, u32 offset, bool set) +{ + u32 gpio_state; + unsigned long flags; + void __iomem *iobase; + + iobase = chip->base + offset; + + dev_dbg(chip->dev, "TMC GPIO one bitop bit=%u, offset=%x, " + "set=%u\n", bit, offset, set); + + spin_lock_irqsave(&chip->gpio_lock, flags); + + gpio_state = ioread32(iobase); + if (set) + gpio_state |= BIT(bit); + else + gpio_state &= ~BIT(bit); + + iowrite32(gpio_state, iobase); + + spin_unlock_irqrestore(&chip->gpio_lock, flags); + + return; +} + +/* + * tmc_gpio_get_multiple_bitsop - Generic TMC get GPIO multiple bits operation + */ +static int tmc_gpio_get_multiple_bitsop(struct tmc_gpio_chip *chip, + unsigned int gpiono, u32 group, u32 offset) +{ + u32 gpio_state; + void __iomem *iobase; + + iobase = chip->base + offset; + + dev_dbg(chip->dev, "TMC GPIO get multiple bitsop group=%u, " + "gpiono=%u, offset=%u\n", group, gpiono, offset); + + switch (group) { + case QSFP_LED_LANE0_GREEN: + case SFP_LED_LANE0_GREEN: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_GREEN_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE0_GREEN_LED_BIT_POSITION, 0x3)); + case QSFP_LED_LANE1_GREEN: + case SFP_LED_LANE1_GREEN: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_GREEN_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE1_GREEN_LED_BIT_POSITION, 0x3)); + case QSFP_LED_LANE2_GREEN: + case SFP_LED_LANE2_GREEN: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_GREEN_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE2_GREEN_LED_BIT_POSITION, 0x3)); + case QSFP_LED_LANE3_GREEN: + case SFP_LED_LANE3_GREEN: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_GREEN_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE3_GREEN_LED_BIT_POSITION, 0x3)); + case QSFP_LED_LANE0_BEACON: + case SFP_LED_LANE0_BEACON: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_BEACON_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE0_BEACON_LED_BIT_POSITION, 0x3)); + case QSFP_LED_LANE1_BEACON: + case SFP_LED_LANE1_BEACON: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_BEACON_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE1_BEACON_LED_BIT_POSITION, 0x3)); + case QSFP_LED_LANE2_BEACON: + case SFP_LED_LANE2_BEACON: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_BEACON_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE2_BEACON_LED_BIT_POSITION, 0x3)); + case QSFP_LED_LANE3_BEACON: + case SFP_LED_LANE3_BEACON: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_BEACON_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE3_BEACON_LED_BIT_POSITION, 0x3)); + case QSFP_LED_LANE0_FAULT: + case SFP_LED_LANE0_FAULT: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_FAULT_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE0_FAULT_LED_BIT_POSITION, 0x3)); + case QSFP_LED_LANE1_FAULT: + case SFP_LED_LANE1_FAULT: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_FAULT_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE1_FAULT_LED_BIT_POSITION, 0x3)); + case QSFP_LED_LANE2_FAULT: + case SFP_LED_LANE2_FAULT: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_FAULT_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE2_FAULT_LED_BIT_POSITION, 0x3)); + case QSFP_LED_LANE3_FAULT: + case SFP_LED_LANE3_FAULT: + gpio_state = ioread32(iobase+(0x004*gpiono)); + return (TMC_PFE_LANES_FAULT_LED_VALUE == + tmc_gpio_find_bits_val(gpio_state, + TMC_PFE_LANE3_FAULT_LED_BIT_POSITION, 0x3)); + default: + return 0; + } +}; + +/* + * tmc_gpio_get - Read the specified signal of the GPIO device. + */ +static int tmc_gpio_get(struct gpio_chip *gc, unsigned int gpio) +{ + struct tmc_gpio_chip *chip = to_tmc_chip(gc); + unsigned int group = TMC_GPIO_FIND_GROUP(gpio); + unsigned int bit = TMC_GPIO_FIND_GPIO(gpio); + + if (group >= TMC_PFE_GPIO_GROUP_MAX) + return 0; + + switch (group) { + case QSFP_RST: + case QSFP_PRESENT: + case QSFP_PHY_RST: + case QSFP_LPMOD: + dev_dbg(chip->dev, "TMC GPIO get one bitop group=%u, gpio=%u, " + "bit=%u\n", group, gpio, bit); + return !!(ioread32(chip->base + group_offset[group]) + & BIT(bit)); + default: + return tmc_gpio_get_multiple_bitsop(chip, bit, group, group_offset[group]); + } +} + +/* + * tmc_gpio_set - Write the specified signal of the GPIO device. + */ +static void tmc_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) +{ + struct tmc_gpio_chip *chip = to_tmc_chip(gc); + unsigned int group = TMC_GPIO_FIND_GROUP(gpio); + unsigned int bit = TMC_GPIO_FIND_GPIO(gpio); + + if (group >= TMC_PFE_GPIO_GROUP_MAX) + return; + + switch (group) { + case QSFP_RST: + case QSFP_PRESENT: + case QSFP_PHY_RST: + case QSFP_LPMOD: + dev_dbg(chip->dev, "TMC GPIO one bitop group=%d\n", group); + tmc_gpio_one_bitop(chip, bit, group_offset[group], val); + break; + default: + tmc_gpio_multiple_bitsop(chip, bit, group, group_offset[group], val); + break; + } +} + +static struct tmc_gpio_info tmc_gpios[] = { + { + .get = tmc_gpio_get, + .set = tmc_gpio_set, + }, +}; + +static void tmc_gpio_setup(struct tmc_gpio_chip *sgc, int id) +{ + struct gpio_chip *chip = &sgc->gpio; + const struct tmc_gpio_info *info = sgc->info; + + chip->get = info->get; + chip->set = info->set; + chip->direction_input = info->dirin; + chip->direction_output = info->dirout; + chip->dbg_show = NULL; + chip->can_sleep = 0; + + if (id == 0) { + chip->base = 0; + } else if (id == 1) { + chip->base = (gpio_max * id); + } else { + chip->base = -1; + } + + chip->ngpio = sgc->ngpio; + chip->label = dev_name(sgc->dev); + chip->parent = sgc->dev; + chip->owner = THIS_MODULE; +} + +static int tmc_gpio_of_init(struct device *dev, + struct tmc_gpio_chip *chip) +{ + chip->info = &tmc_gpios[0]; + chip->ngpio = gpio_max; + + return 0; +} + +static int tmc_gpio_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct tmc_gpio_chip *chip; + struct resource *res; + int ret; + + const struct mfd_cell *cell = mfd_get_cell(pdev); + + dev_dbg(dev, "TMC GPIO probe\n"); + + chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + dev_info(dev, "TMC GPIO resource 0x%llx, %llu\n", + res->start, resource_size(res)); + + chip->base = devm_ioremap_nocache(dev, res->start, resource_size(res)); + if (!chip->base) + return -ENOMEM; + + ret = tmc_gpio_of_init(dev, chip); + if (ret) + return ret; + + chip->dev = dev; + spin_lock_init(&chip->gpio_lock); + + tmc_gpio_setup(chip, cell->id); + + ret = gpiochip_add(&chip->gpio); + if (ret) { + dev_err(dev, + "Failed to register TMC gpiochip : %d\n", ret); + return ret; + } + + platform_set_drvdata(pdev, chip); + dev_info(dev, "TMC GPIO registered at 0x%lx, gpiobase: %d\n", + (long unsigned)chip->base, chip->gpio.base); + + return 0; +} + +static int tmc_gpio_remove(struct platform_device *pdev) +{ + struct tmc_gpio_chip *chip = platform_get_drvdata(pdev); + + gpiochip_remove(&chip->gpio); + + return 0; +} + +static struct platform_driver tmc_gpio_driver = { + .driver = { + .name = "gpioslave-tmc", + .owner = THIS_MODULE, + }, + .probe = tmc_gpio_probe, + .remove = tmc_gpio_remove, +}; + +module_platform_driver(tmc_gpio_driver); + +MODULE_DESCRIPTION("Juniper Networks TMC FPGA GPIO driver"); +MODULE_AUTHOR("Ashish Bhensdadia "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-juniper/common/modules/i2c-tmc.c b/platform/broadcom/sonic-platform-modules-juniper/common/modules/i2c-tmc.c new file mode 100644 index 000000000000..afd0311dc130 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/common/modules/i2c-tmc.c @@ -0,0 +1,1107 @@ +/* + * Juniper Networks TMC I2C Accelerator driver + * + * Copyright (C) 2020 Juniper Networks + * Author: Ashish Bhensdadia + * + * This driver implement the I2C functionality + * + * This program is free software; 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "jnx-tmc.h" + + +#define TMC_I2C_MASTER_I2C_SCAN_RESET_BIT BIT(31) + +#define TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET 0x0 +#define TMC_I2C_MSTR_AUTOMATION_I2C_DPMEM_OFFSET 0x10 + +#define TMC_I2C_MSTR_AUTOMATION_I2C(adap, offset) \ + ((adap)->membase + offset) + +#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_0 0x0 +#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_8 0x8 +#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_4 0x4 +#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_C 0xC +#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_10 0x10 +#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_14 0x14 +#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_18 0x18 +#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_1C 0x1C +#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_20 0x20 +#define TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_24 0x24 + +#define TMC_I2C_MSTR_I2C_DPMEM(adap, offset) \ + ((adap)->dpmbase + offset) + +#define TMC_I2C_TRANS_LEN 2 +#define tmc_iowrite(val, addr) iowrite32((val), (addr)) + +#define TMC_I2C_CTRL_GROUP(g) (((g) & 0xFF) << 8) +#define TMC_I2C_CTRL_WRCNT(w) (((w) & 0x3F) << 16) +#define TMC_I2C_CTRL_RDCNT(r) (((r) & 0x3F) << 16) +#define TMC_I2C_CTRL_DEVADDR(d) (((d) & 0xFF) << 8) +#define TMC_I2C_CTRL_OFFSET(o) ((o) & 0xFF) + + +#define TMC_I2C_MEM_CTRL_VLD BIT(31) + +#define TMC_I2C_CTRL_ERR(s) ((s) & 0x0F000000) +#define TMC_I2C_CTRL_DONE_BIT(s) ((s) & BIT(31)) +#define TMC_I2C_CTRL_STATUS_OK(s) (TMC_I2C_CTRL_DONE_BIT(s) & \ + TMC_I2C_CTRL_ERR(s)) +#define TMC_I2C_CTRL_DONE(s) (TMC_I2C_CTRL_DONE_BIT(s) == BIT(31)) + +#define TMC_I2C_STAT_INC(adap, s) (((adap)->stat.s)++) +#define TMC_I2C_STAT_INCN(adap, s, n) (((adap)->stat.s) += (n)) +#define TMC_I2C_GET_MASTER(tadap) ((tadap)->tctrl) + +#define TMC_I2C_READ 0x1 +#define TMC_I2C_WRITE 0x2 + +#define TMC_I2C_MASTER_LOCK(s, flags) \ +do { \ + spin_lock_irqsave(&(s)->lock, flags); \ +} while (0) + +#define TMC_I2C_MASTER_UNLOCK(s, flags) \ +do { \ + spin_unlock_irqrestore(&(s)->lock, flags); \ +} while (0) + +#define tmc_i2c_dbg(dev, fmt, args...) \ +do { \ + if (tmc_i2c_debug >= 1) \ + dev_err(dev, fmt, ## args); \ +} while (0) + + +/* pfe TMC i2c channel */ +static int pfe_channel = 32; +module_param(pfe_channel, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(pfe_channel, "Maximum number of channel for PFE TMC"); + +/* chassid TMC i2c channel */ +static int chd_channel = 11; +module_param(chd_channel, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(chd_channel, "Maximum number of channel for CHASSID TMC"); + +static u32 wr_index_to_oper[] = {0x01000000, 0x02000000, + 0x84000000, 0x85000000, 0x83000000}; +static u32 rd_index_to_oper[] = {0x08000000, 0x09000000, 0x0A000000, + 0x8B000000, 0x8C000000, 0x8D000000, 0x83000000}; + +struct tmc_i2c_adapter_stats { + u32 abort; + u32 go; + u32 mstr_rdy; + u32 mstr_busy; + u32 trans_compl; + u32 msg_cnt; + u32 rd_cnt; + u32 wr_cnt; + u32 byte_cnt; + u32 slave_timeo; + u32 scl_bus_loss; + u32 sda_bus_loss; + u32 ack_ptimeo; + u32 rd_cnt_0; + u32 rd_cnt_gt32; + u32 rst_tgt; + u32 rst_mstr; +}; + +struct tmc_i2c_adapter { + void __iomem *membase; + void __iomem *dpmbase; + struct i2c_adapter adap; + struct i2c_mux_core *muxc; + struct tmc_i2c_ctrl *tctrl; + int mux_channels; + int mux_select; + u32 i2c_delay; + int entries; + int master; + u32 control; + u32 speed; + bool done; + bool polling; + bool use_block; + wait_queue_head_t wait; + struct tmc_i2c_adapter_stats stat; +}; + +struct tmc_i2c_ctrl { + void __iomem *membase; + void __iomem *dpmbase; + struct i2c_adapter **adap; + struct device *dev; + int num_masters; + int mux_channels; + u32 i2c_delay; + u32 master_mask; + spinlock_t lock; /* master lock */ +}; + +/* + * Reset the Tmc I2C master + */ +static void tmc_i2c_reset_master(struct i2c_adapter *adap) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + struct tmc_i2c_ctrl *tmc = TMC_I2C_GET_MASTER(tadap); + u32 val, master = tadap->master; + unsigned long flags; + void __iomem *addr; + + dev_warn(&adap->dev, "Re-setting i2c master: %d\n", master); + + TMC_I2C_MASTER_LOCK(tmc, flags); + + addr = tmc->membase + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET; + val = ioread32(addr); + tmc_iowrite(val | (TMC_I2C_MASTER_I2C_SCAN_RESET_BIT), addr); + tmc_iowrite(val & ~(TMC_I2C_MASTER_I2C_SCAN_RESET_BIT), addr); + TMC_I2C_STAT_INC(tadap, rst_mstr); + + TMC_I2C_MASTER_UNLOCK(tmc, flags); +} + +/* + * check if the Tmc I2C master is ready + */ +static int tmc_i2c_mstr_wait_rdy(struct i2c_adapter *adap, u8 rw, u32 delay) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + unsigned long timeout; + u32 val; + + val = ioread32(TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + if (val) { + tmc_iowrite(0x80000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + mdelay(5); + tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + val = ioread32(TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + } else { + tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + } + + if ((rw == TMC_I2C_READ) && (delay)) { + tmc_iowrite(0x80000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + return 0; + } + + timeout = jiffies + adap->timeout; + do { + val = ioread32(TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + if (!val) + return 0; + + if (tadap->polling) { + usleep_range(50, 100); + } else { + tadap->done = false; + wait_event_timeout(tadap->wait, tadap->done, + adap->timeout); + } + } while (time_before(jiffies, timeout)); + + TMC_I2C_STAT_INC(tadap, mstr_busy); + + return -EBUSY; +} + +/* + * Wait for master completion + */ +static u32 tmc_i2c_mstr_wait_completion(struct i2c_adapter *adap, + u32 dp_entry_offset) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + u32 val; + + if (tadap->polling) { + /* Poll for the results */ + unsigned long timeout = jiffies + adap->timeout; + + do { + usleep_range(1000, 1200); + val = ioread32(TMC_I2C_MSTR_I2C_DPMEM(tadap, + dp_entry_offset)); + if (TMC_I2C_CTRL_DONE(val)) + break; + } while (time_before(jiffies, timeout)); + } else { + wait_event_timeout(tadap->wait, tadap->done, adap->timeout); + val = ioread32(TMC_I2C_MSTR_I2C_DPMEM(tadap, + dp_entry_offset)); + } + + return TMC_I2C_CTRL_STATUS_OK(val); +} + +/* + * TMC I2C delay read/write operation + */ +static int tmc_i2c_delay_rw_op(struct i2c_adapter *adap, u8 rw, u32 mux, + u32 addr, u32 offset, u32 len, u32 delay, u8 *buf) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + struct device *dev = &adap->dev; + int err, n; + u32 control = 0, data = 0; + u32 val; + + err = tmc_i2c_mstr_wait_rdy(adap, rw, 0); + if (err < 0) { + tmc_i2c_reset_master(adap); + return err; + } + + TMC_I2C_STAT_INC(tadap, mstr_rdy); + + /* initialize the start address and mux */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_DPMEM_OFFSET)); + + tmc_iowrite(mux, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_0)); + tmc_iowrite(0x84400000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_4)); + + /* populate delay */ + if (delay) { + if (delay > 1000) { + delay = delay/1000; + delay |= (1 << 16); + } + } + tmc_iowrite(delay, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_8)); + tmc_iowrite(0x86000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_C)); + + /* prepare control command */ + control |= TMC_I2C_CTRL_DEVADDR(addr); + control |= TMC_I2C_CTRL_OFFSET(offset); + + if (rw == TMC_I2C_WRITE) { + for (n = 0; n < len; n++) + data |= (buf[n] << ((len - 1 - n) * 8)); + tmc_iowrite(data, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_10)); + control |= TMC_I2C_CTRL_WRCNT(len); + control |= wr_index_to_oper[len-1]; + dev_dbg(dev, "WR Data: [%#04x, %#04x, %#04x, %#04x]\n", + ((data >> 24) & 0xff), ((data >> 16) & 0xff), + ((data >> 8) & 0xff), (data & 0xff)); + + } else { + /* read */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_10)); + control |= TMC_I2C_CTRL_RDCNT(len); + control |= rd_index_to_oper[len-1]; + } + + /* + * valid this transaction as well + */ + control |= TMC_I2C_MEM_CTRL_VLD; + + tadap->control = control; + + /* + * operation control command + */ + tmc_iowrite(control, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_14)); + + /* + * End commands + */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_18)); + tmc_iowrite(0x8E000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_1C)); + tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_20)); + tmc_iowrite(0x8F000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_24)); + + dev_dbg(dev, "Control (%#x): RD_WR_TYPE:%#02x, RD_WR_LEN:%d," + "Addr:%#01x, Offset:%#02x\n", control, + ((control >> 24) & 0x3F), ((control >> 16) & 0x3F), + ((control >> 8) & 0xff), ((control) & 0xff)); + + tadap->done = false; + + /* fire the transaction */ + tmc_iowrite(0x00000001, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + + TMC_I2C_STAT_INC(tadap, go); + + val = tmc_i2c_mstr_wait_completion(adap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_10); + if (val) { + dev_err(&adap->dev, + "i2c transaction error (0x%08x)\n", val); + + /* stop the transaction */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + return -EIO; + } + + /* + * read a word of data + */ + if (rw == TMC_I2C_READ) { + data = ioread32(TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_10)); + for (n = 0; n < len; n++) + buf[n] = (data >> (n * 8)) & 0xff; + + dev_dbg(dev, "RD Data: [%#04x, %#04x, %#04x, %#04x]\n", + ((data >> 24) & 0xff), ((data >> 16) & 0xff), + ((data >> 8) & 0xff), (data & 0xff)); + + TMC_I2C_STAT_INC(tadap, rd_cnt); + } else { + /* write */ + TMC_I2C_STAT_INC(tadap, wr_cnt); + } + + /* stop the transaction */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + + return 0; + +} + +/* + *TMC I2C none delay Read/write opertion + */ +static int tmc_i2c_none_delay_rw_op(struct i2c_adapter *adap, u8 rw, u32 mux, + u32 addr, u32 offset, u32 len, u8 *buf) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + struct device *dev = &adap->dev; + int err, n; + u32 control = 0, data = 0; + u32 val; + + err = tmc_i2c_mstr_wait_rdy(adap, rw, 0); + if (err < 0) { + tmc_i2c_reset_master(adap); + return err; + } + + TMC_I2C_STAT_INC(tadap, mstr_rdy); + + /* initialize the start address and mux */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_DPMEM_OFFSET)); + + tmc_iowrite(mux, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_0)); + tmc_iowrite(0x84400000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_4)); + + + /* prepare control command */ + control |= TMC_I2C_CTRL_DEVADDR(addr); + control |= TMC_I2C_CTRL_OFFSET(offset); + + if (rw == TMC_I2C_WRITE) { + for (n = 0; n < len; n++) + data |= (buf[n] << (n * 8)); + tmc_iowrite(data, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_8)); + control |= wr_index_to_oper[len-1]; + dev_dbg(dev, "WR Data: [%#04x, %#04x, %#04x, %#04x]\n", + ((data >> 24) & 0xff), ((data >> 16) & 0xff), + ((data >> 8) & 0xff), (data & 0xff)); + + } else { + /* read */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_8)); + control |= rd_index_to_oper[len-1]; + } + + /* + * valid this transaction as well + */ + control |= TMC_I2C_MEM_CTRL_VLD; + + tadap->control = control; + + /* + * operation control command + */ + tmc_iowrite(control, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_C)); + + /* + * End commands + */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_10)); + tmc_iowrite(0x8E000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_14)); + tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_18)); + tmc_iowrite(0x8F000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_1C)); + + dev_dbg(dev, "Control (%#x): RD_WR_TYPE:%#02x, RD_WR_LEN:%d," + "Addr:%#01x, Offset:%#02x\n", control, + ((control >> 24) & 0x3F), ((control >> 16) & 0x3F), + ((control >> 8) & 0xff), ((control) & 0xff)); + + tadap->done = false; + + /* fire the transaction */ + tmc_iowrite(0x00000001, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + + TMC_I2C_STAT_INC(tadap, go); + + /* wait till transaction complete */ + val = tmc_i2c_mstr_wait_completion(adap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_8); + if (val) { + dev_err(&adap->dev, + "i2c transaction error (0x%08x)\n", val); + + /* stop the transaction */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + return -EIO; + } + + /* + * read a word of data + */ + if (rw == TMC_I2C_READ) { + data = ioread32(TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_8)); + for (n = 0; n < len; n++) + buf[n] = (data >> (n * 8)) & 0xff; + + dev_dbg(dev, "RD Data: [%#04x, %#04x, %#04x, %#04x]\n", + ((data >> 24) & 0xff), ((data >> 16) & 0xff), + ((data >> 8) & 0xff), (data & 0xff)); + TMC_I2C_STAT_INC(tadap, rd_cnt); + } else { + /* write */ + TMC_I2C_STAT_INC(tadap, wr_cnt); + } + + /* stop the transaction */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + + return 0; +} + +/* + * TMC I2C read/write operation + */ +static int tmc_i2c_rw_op(struct i2c_adapter *adap, u8 rw, u32 mux, + u32 addr, u32 offset, u32 len, u8 *buf) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + u32 i2c_delay = tadap->i2c_delay; + + if (i2c_delay) { + return tmc_i2c_delay_rw_op(adap, rw, mux, addr, offset, + len, i2c_delay, buf); + } else { + return tmc_i2c_none_delay_rw_op(adap, rw, mux, addr, offset, + len, buf); + } +} + +static int tmc_i2c_calc_entries(int msglen) +{ + int entries = msglen / TMC_I2C_TRANS_LEN; + + return (entries += (msglen % TMC_I2C_TRANS_LEN) ? 1 : 0); +} + +static int tmc_i2c_block_read(struct i2c_adapter *adap, + struct i2c_msg *msgs, int num) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + struct device *dev = &adap->dev; + int curmsg, entries, len; + int offset = 0; + struct i2c_msg *msg; + int err, n = 0; + u8 rwbuf[4] = {0}; + + dev_dbg(dev, "Read i2c Block\n"); + + for (curmsg = 0, offset = 0; curmsg < num; curmsg++) { + msg = &msgs[curmsg]; + len = msg->len; + + if (msg->flags & I2C_M_RECV_LEN) + len = (I2C_SMBUS_BLOCK_MAX + 1); + + entries = tmc_i2c_calc_entries(len); + + if (msg->flags & I2C_M_RD) { + if (curmsg == 1 && ((msg->flags & I2C_M_RECV_LEN && + !(msgs[0].flags & I2C_M_RD)) || + (msg->len > TMC_I2C_TRANS_LEN))) { + offset = msgs[0].buf[0]; + } + + while (entries) { + err = tmc_i2c_rw_op(adap, TMC_I2C_READ, + tadap->mux_select, + msgs[0].addr, offset, + TMC_I2C_TRANS_LEN, rwbuf); + if (err < 0) + return err; + msg = &msgs[num - 1]; + msg->buf[n] = rwbuf[0]; + msg->buf[n+1] = rwbuf[1]; + n = n + TMC_I2C_TRANS_LEN; + offset = offset + TMC_I2C_TRANS_LEN; + entries--; + } + } + } + + return 0; +} + +/* + *TMC I2C SMB Read opertion + */ +static int tmc_i2c_smb_block_read_op(struct i2c_adapter *adap, u8 rw, u32 mux, + u32 addr, u32 offset, u32 len, u8 *buf) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + int err, i = 0; + u32 control = 0, data = 0; + u32 start_add; + + err = tmc_i2c_mstr_wait_rdy(adap, rw, 0); + if (err < 0) { + tmc_i2c_reset_master(adap); + return err; + } + + TMC_I2C_STAT_INC(tadap, mstr_rdy); + + /* initialize the start address and mux */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_DPMEM_OFFSET)); + + tmc_iowrite(mux, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_0)); + tmc_iowrite(0x84400000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_4)); + + + /* prepare control command */ + control |= TMC_I2C_CTRL_DEVADDR(addr); + control |= TMC_I2C_CTRL_OFFSET(offset); + + /* read */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_8)); + control |= TMC_I2C_CTRL_RDCNT(len);; + control |= rd_index_to_oper[6]; + + tadap->control = control; + + /* + * operation control command + */ + tmc_iowrite(control, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_C)); + + /* + * End commands + */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_10)); + tmc_iowrite(0x8E000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_14)); + tmc_iowrite(0x00000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_18)); + tmc_iowrite(0x8F000000, TMC_I2C_MSTR_I2C_DPMEM(tadap, + TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_1C)); + + tadap->done = false; + + /* fire the transaction */ + tmc_iowrite(0x00000001, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + + TMC_I2C_STAT_INC(tadap, go); + + /* + * read a block of data + */ + start_add = TMC_I2C_MSTR_I2C_DPMEM_ENTRY_OFFSET_8; + while (len > 0) { + usleep_range(10000, 12000); + data = ioread32(TMC_I2C_MSTR_I2C_DPMEM(tadap, start_add)); + buf[i] = data & 0xff; + buf[i + 1] = (data >> 8) & 0xff; + start_add = start_add + 8; + i = i + 2; + len = len - 2; + + TMC_I2C_STAT_INC(tadap, rd_cnt); + } + + /* stop the transaction */ + tmc_iowrite(0x00000000, TMC_I2C_MSTR_AUTOMATION_I2C(tadap, + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET)); + + return 0; +} + +static int tmc_i2c_smb_block_read(struct i2c_adapter *adap, + struct i2c_msg *msgs, int num) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + int curmsg, len; + int offset = 0; + struct i2c_msg *msg; + int err, i = 0; + u8 rwbuf[32] = {0}; + + for (curmsg = 0, offset = 0; curmsg < num; curmsg++) { + msg = &msgs[curmsg]; + len = msg->len; + + if (msg->flags & I2C_M_RECV_LEN) + len = (I2C_SMBUS_BLOCK_MAX + 1); + + if (msg->flags & I2C_M_RD) { + if ((curmsg == 1) && (msg->flags & I2C_M_RECV_LEN) && + !(msgs[0].flags & I2C_M_RD)) { + offset = msgs[0].buf[0]; + } + + err = tmc_i2c_smb_block_read_op(adap, TMC_I2C_READ, + tadap->mux_select, + msgs[0].addr, offset, + 32, rwbuf); + if (err < 0) { + return err; + } + msg = &msgs[num - 1]; + for (i = 0; i < len - 1; i++) { + msg->buf[i] = rwbuf[i]; + } + } + } + + return 0; +} + +static int tmc_i2c_mstr_xfer(struct i2c_adapter *adap, + struct i2c_msg *msgs, int num) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + struct device *dev = &adap->dev; + int n, curmsg, len = 0; + int err = 0; + struct i2c_msg *msg; + bool read; + u8 rwbuf[4] = {0}; + + dev_dbg(dev, "Num messages -> %d\n", num); + + /* + * Initialize all vars + */ + tadap->entries = 0; + tadap->use_block = false; + + for (curmsg = 0; curmsg < num; curmsg++) { + msg = &msgs[curmsg]; + dev_dbg(dev, "[%02d] %d bytes, flag %#02x buf %#02x\n", + curmsg, msg->len, msg->flags, msg->buf[0]); + if ((msg->len > TMC_I2C_TRANS_LEN) || + ((msg->flags & I2C_M_RD) && + (msg->flags & I2C_M_RECV_LEN))) { + /* If PEC is enabled len will come as 3 for a word read. + * We don't want to use block read for this case. + */ + if ((msg->flags & I2C_CLIENT_PEC) && + (msg->len == TMC_I2C_TRANS_LEN+1)) { + tadap->use_block = false; + } else { + tadap->use_block = true; + } + break; + } + } + + if (tadap->use_block) { + /* Read Block */ + if ((msg->flags & I2C_M_RD) && (msg->flags & I2C_M_RECV_LEN)) { + err = tmc_i2c_smb_block_read(adap, msgs, num); + } else { + err = tmc_i2c_block_read(adap, msgs, num); + } + if (err < 0) + return err; + } else { + read = msgs[num - 1].flags & I2C_M_RD; + for (curmsg = 0; curmsg < num; curmsg++) { + msg = &msgs[curmsg]; + len = msg->len; + + dev_dbg(dev, " [%02d] %s %d bytes addr %#02x, " + "flag %#02x, buf[0] %#02x\n", curmsg, + read ? "RD" : "WR", len, msg->addr, + msg->flags, msg->buf[0]); + + /* SMBus quick read/write command */ + if (len == 0 && curmsg == 0 && num == 1) { + if (read) { + len = 1; + } + break; + } + + if (curmsg == 0) { + if (!read) { + for (n = 1; n < len; n++) + rwbuf[n-1] = (msg->buf[n]); + len--; + } else { + /* read operation */ + continue; + } + } + } + + if (!read) { + /* write */ + err = tmc_i2c_rw_op(adap, TMC_I2C_WRITE, + tadap->mux_select, msgs[0].addr, + msgs[0].buf[0], len, rwbuf); + } else { + /* read */ + /* + * If PEC is enabled read only 2 bytes as expected in + * case of a word read instead of 3 to make it compatible + * with word write implementation. + */ + if (msg->flags & I2C_CLIENT_PEC && (len == TMC_I2C_TRANS_LEN + 1)) { + len--; + } + + err = tmc_i2c_rw_op(adap, TMC_I2C_READ, + tadap->mux_select, + msgs[0].addr, msgs[0].buf[0], + len, rwbuf); + msg = &msgs[num - 1]; + len = msg->len; + /* + * To avoid failure in PEC enabled case clear flag. + */ + if (len == TMC_I2C_TRANS_LEN + 1) { + msgs[num - 1].flags &= ~I2C_M_RD; + } + for (n = 0; n < len; n++) + msg->buf[n] = rwbuf[n]; + } + if (err < 0) + return err; + } + + TMC_I2C_STAT_INCN(tadap, msg_cnt, num); + + return num; +} + +static u32 tmc_i2c_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL + | I2C_FUNC_SMBUS_READ_BLOCK_DATA; +} + +static const struct i2c_algorithm tmc_i2c_algo = { + .master_xfer = tmc_i2c_mstr_xfer, + .functionality = tmc_i2c_func, +}; + +static int tmc_i2c_mux_group_sel(struct i2c_mux_core *muxc, u32 chan) +{ + struct tmc_i2c_adapter *tadap = i2c_mux_priv(muxc); + + dev_dbg(muxc->dev, "chan = %d\n", chan); + + if (!tadap || chan > TMC_I2C_MSTR_MAX_GROUPS) + return -ENODEV; + tadap->mux_select = chan; + + return 0; +} + +static int tmc_i2c_mux_init(struct i2c_adapter *adap) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + int chan, ret; + + tadap->muxc = i2c_mux_alloc(adap, &adap->dev, tadap->mux_channels, + 0, 0, tmc_i2c_mux_group_sel, NULL); + + if (!tadap->muxc) + return -ENOMEM; + + tadap->muxc->priv = tadap; + for (chan = 0; chan < tadap->mux_channels; chan++) { + ret = i2c_mux_add_adapter(tadap->muxc, 0, chan, 0); + if (ret) { + dev_err(&adap->dev, "Failed to add adapter %d\n", chan); + i2c_mux_del_adapters(tadap->muxc); + return ret; + } + } + + return 0; +} + +static struct i2c_adapter * +tmc_i2c_init_one(struct tmc_i2c_ctrl *tmc, + int master, int id) +{ + struct tmc_i2c_adapter *adapter; + struct device *dev = tmc->dev; + int err; + + adapter = devm_kzalloc(dev, sizeof(*adapter), GFP_KERNEL); + if (!adapter) + return ERR_PTR(-ENOMEM); + + init_waitqueue_head(&adapter->wait); + adapter->adap.owner = THIS_MODULE; + adapter->adap.algo = &tmc_i2c_algo; + adapter->adap.nr = -1; + adapter->adap.timeout = HZ / 5; + adapter->master = master; + adapter->mux_channels = tmc->mux_channels; + adapter->i2c_delay = tmc->i2c_delay; + adapter->membase = tmc->membase; + adapter->dpmbase = tmc->dpmbase; + adapter->polling = 1; + adapter->tctrl = tmc; + + i2c_set_adapdata(&adapter->adap, adapter); + snprintf(adapter->adap.name, sizeof(adapter->adap.name), + "%s:%d", dev_name(dev), master); + + adapter->adap.dev.parent = dev; + err = i2c_add_numbered_adapter(&adapter->adap); + if (err) + goto error; + + err = tmc_i2c_mux_init(&adapter->adap); + if (err) + goto err_remove; + + dev_dbg(dev, "Adapter[%02d-%02d]: " + "dpmbase: 0x%lx\n", id, master, + (unsigned long)adapter->dpmbase); + return &adapter->adap; + +err_remove: + i2c_del_adapter(&adapter->adap); +error: + return ERR_PTR(err); +} + +static void tmc_i2c_cleanup_one(struct i2c_adapter *adap) +{ + struct tmc_i2c_adapter *tadap = i2c_get_adapdata(adap); + + i2c_mux_del_adapters(tadap->muxc); + i2c_del_adapter(adap); + +} + + +static int tmc_i2c_of_init(struct device *dev, + struct tmc_i2c_ctrl *tmc, int id) +{ + u32 mux_channels, master, num_masters = 0, master_mask = 0; + u32 i2c_delay = 0; + + if (!(master_mask & BIT(master))) + num_masters++; + master_mask |= BIT(master); + + if (id == 0) { + /* chassisd */ + mux_channels = chd_channel; + num_masters = 1; + i2c_delay = 0; + } else if (id == 1) { + /* pfe */ + mux_channels = pfe_channel; + num_masters = 1; + i2c_delay = 20; + } else { + return -EINVAL; + } + + tmc->adap = devm_kcalloc(dev, num_masters, + sizeof(struct i2c_adapter *), + GFP_KERNEL); + if (!tmc->adap) + return -ENOMEM; + + tmc->num_masters = num_masters; + tmc->master_mask = master_mask; + tmc->mux_channels = mux_channels; + tmc->i2c_delay = i2c_delay; + + return 0; +} + +static int tmc_i2c_probe(struct platform_device *pdev) +{ + int i, n, err; + struct resource *res; + struct i2c_adapter *adap; + struct device *dev = &pdev->dev; + struct tmc_i2c_ctrl *tmc; + + const struct mfd_cell *cell = mfd_get_cell(pdev); + + /* + * Allocate memory for the Tmc FPGA + */ + tmc = devm_kzalloc(dev, sizeof(*tmc), GFP_KERNEL); + if (!tmc) + return -ENOMEM; + + platform_set_drvdata(pdev, tmc); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + dev_info(dev, "Tmc I2C Accel resource 0x%llx, %llu\n", + res->start, resource_size(res)); + + tmc->membase = devm_ioremap_nocache(dev, res->start, + resource_size(res)); + if (!tmc->membase) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res) + return -ENODEV; + + dev_info(dev, "Tmc I2C Mem resource 0x%llx, %llu\n", + res->start, resource_size(res)); + + tmc->dpmbase = devm_ioremap_nocache(dev, res->start, + resource_size(res)); + if (!tmc->dpmbase) + return -ENOMEM; + + tmc->dev = dev; + spin_lock_init(&tmc->lock); + + err = tmc_i2c_of_init(dev, tmc, cell->id); + if (err) + return err; + + dev_info(dev, "Tmc I2C Masters: %d\n", tmc->num_masters); + dev_info(dev, "Tmc I2C Delay: %d\n", tmc->i2c_delay); + + for (n = 0, i = 0; i < TMC_I2C_MASTER_NR_MSTRS; i++) { + if (tmc->master_mask & BIT(i)) { + adap = tmc_i2c_init_one(tmc, i, n); + if (IS_ERR(adap)) { + err = PTR_ERR(adap); + dev_err(dev, "Failed to initialize master " + "adapter %d: %d\n", i, err); + goto err_remove; + } + tmc->adap[n++] = adap; + } + } + + return 0; + +err_remove: + for (n--; n >= 0; n--) + tmc_i2c_cleanup_one(tmc->adap[n]); + return err; +} + +static int tmc_i2c_remove(struct platform_device *pdev) +{ + struct tmc_i2c_ctrl *tmc = platform_get_drvdata(pdev); + int i; + + /* Disable all masters */ + tmc_iowrite(0, tmc->membase + TMC_I2C_MSTR_AUTOMATION_I2C_SCAN_OFFSET); + + for (i = 0; i < tmc->num_masters; i++) + tmc_i2c_cleanup_one(tmc->adap[i]); + + return 0; +} + +static struct platform_driver tmc_i2c_driver = { + .driver = { + .name = "i2c-tmc", + .owner = THIS_MODULE, + }, + .probe = tmc_i2c_probe, + .remove = tmc_i2c_remove, +}; + +module_platform_driver(tmc_i2c_driver); + +MODULE_DESCRIPTION("Juniper Networks TMC FPGA I2C Accelerator driver"); +MODULE_AUTHOR("Ashish Bhensdadia "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-juniper/common/modules/jnx-refpga-tmc.c b/platform/broadcom/sonic-platform-modules-juniper/common/modules/jnx-refpga-tmc.c new file mode 100644 index 000000000000..ef36bca72e9d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/common/modules/jnx-refpga-tmc.c @@ -0,0 +1,603 @@ +/* + * Juniper Networks RE-FPGA qfx platform specific driver + * + * Copyright (C) 2020 Juniper Networks + * Author: Ciju Rajan K + * + * This driver implements various features such as + * - ALARM led driver + * - Fan full speed reset control + * - FAN precense detection + * - FAN type detection + * - Any new QFX specific features which uses RE-FPGA + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define NUM_LEDS 7 /* Max number of Alarm + FAN LEDs */ + +#define ALARM_MINOR_LED 0 +#define ALARM_MAJOR_LED 1 + +#define REFPGA_PCIE_RESET_CTRL 0x13 +#define REFPGA_PCIE_ALARM 0x33 +#define REFPGA_FAN0_CTRL_STAT 0x28 + +#define REFPGA_RESET_FAN_SPEED BIT(3) +#define REFPGA_OPER_TYPE BIT(0) +#define REFPGA_OPER_START BIT(1) +#define REFPGA_OPER_DONE BIT(2) + +#define TMC_REFPGA_ADDR_REG 0x0 /* TMC offset: 0x228 */ +#define TMC_REFPGA_DATA_REG 0x4 /* TMC offset: 0x22C */ +#define TMC_REFPGA_CTRL_REG 0x8 /* TMC offset: 0x230 */ + +#define TMC_REFPGA_READ_CMD 0x3 +#define TMC_REFPGA_WRITE_CMD 0x2 + +#define REFPGA_INTR_NR_GROUPS 1 +#define REFPGA_INTR_MAX_IRQS_PG 32 + +#define MAX_FANS 5 + +#define REFPGA_IRQ_MAX_BITS_PER_REG 32 + +#define POLL_INTERVAL 5000 + +#define AFI_MASK (0x01) +#define AFO_MASK (0x02) +#define AFI_AFO_MASK (0x03) +/* + * LED specific data structures + */ +struct refpga_led { + struct led_classdev lc; + struct work_struct work; + int blink; + int on; + int bit; + void __iomem *addr; +}; + +struct refpga_led_data { + int num_leds; + struct refpga_led *leds; +}; + +static DEFINE_MUTEX(alarm_led_lock); + +/* + * Common routines + */ +struct refpga_chip { + struct refpga_led_data *led; +}; + +static struct refpga_chip *refpga; + +static DEFINE_MUTEX(refpga_lock); + +static void __iomem *tmc_membase; + +static void wait_for_refpga_oper(void __iomem *base_addr) +{ + volatile u32 done = ~(-1); + unsigned long int timeout; + void __iomem *addr; + + addr = base_addr + (TMC_REFPGA_CTRL_REG); + /* + * Wait till the transaction is complete + */ + timeout = jiffies + msecs_to_jiffies(100); + + do { + usleep_range(50, 100); + done = ioread32(addr); + if (done & (REFPGA_OPER_DONE)) + break; + } while(time_before(jiffies, timeout)); +} +static u32 refpga_read(void __iomem *base_addr, u32 refpga_offset) +{ + u32 value; + + mutex_lock(&refpga_lock); + iowrite32(refpga_offset, base_addr + (TMC_REFPGA_ADDR_REG)); + iowrite32(TMC_REFPGA_READ_CMD, base_addr + (TMC_REFPGA_CTRL_REG)); + wait_for_refpga_oper(base_addr); + value = ioread32(base_addr + (TMC_REFPGA_DATA_REG)); + mutex_unlock(&refpga_lock); + + return value; +} + +static void refpga_write(void __iomem *base_addr, u32 refpga_offset, u32 val) +{ + mutex_lock(&refpga_lock); + iowrite32(refpga_offset, base_addr + (TMC_REFPGA_ADDR_REG)); + iowrite32(val, base_addr + (TMC_REFPGA_DATA_REG)); + iowrite32(TMC_REFPGA_WRITE_CMD, base_addr + (TMC_REFPGA_CTRL_REG)); + wait_for_refpga_oper(base_addr); + mutex_unlock(&refpga_lock); +} + +static bool get_fan_presense(u8 idx) +{ + u8 value = 0x00; + u8 offset = REFPGA_FAN0_CTRL_STAT; + bool ret = 0; + + value = refpga_read(tmc_membase, (offset + (idx * 2))); + /* + * Get the last two bits of REFPGA_FANx_CTRL_STAT. + * REFPGA_FANx_CTRL_STAT register of REFPGA gives the fan airflow + * status. There are 5 fans in QFX5200. Last two bits give the AFI + * & AFO status. If any of these bits are set, fan is present. + */ + value = (value & BIT(0)) | (value & BIT(1)); + if (value) + ret = 1; + + return ret; +} + +static int get_fan_type(u8 idx) +{ + u8 value = 0x00; + u8 offset = REFPGA_FAN0_CTRL_STAT; + int ret = -1; + + value = refpga_read(tmc_membase, (offset + (idx * 2))); + /* + * Get the last two bits of REFPGA_FANx_CTRL_STAT. + * REFPGA_FANx_CTRL_STAT register of REFPGA gives the fan airflow + * status. There are 5 fans in QFX5200. Last two bits give the AFI + * & AFO status. If bit1 is set, it's AFO and if bit 0 is set, + * it's AFI. + * + * This function will return '1' for AFO, '0' for AFI, and '-1' + * if there is no fan or if both AFI & AFO bits are set. + */ + value &= AFI_AFO_MASK; + + switch(value) { + case AFI_MASK: + ret = 0; + break; + case AFO_MASK: + ret = 1; + break; + default: + ret = -1; + break; + }; + + return ret; +} + +enum sysfs_fan_attributes { + FAN0_PRESENT, + FAN1_PRESENT, + FAN2_PRESENT, + FAN3_PRESENT, + FAN4_PRESENT, +}; + +enum sysfs_fan_type_attributes { + FAN0_TYPE, + FAN1_TYPE, + FAN2_TYPE, + FAN3_TYPE, + FAN4_TYPE, +}; + +/* + * The sysfs files will be present in this path + * /sys/devices/pci0000:00/0000:00:1c.0/0000:0f:00.0/refpga-tmc.15/fan*_present + * /sys/devices/pci0000:00/0000:00:1c.0/0000:0f:00.0/refpga-tmc.15/fan*_type + */ + +#define DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_present, S_IRUGO, refpga_fan_presense_show, NULL, FAN##index##_PRESENT) +#define DECLARE_FAN_PRESENT_ATTR(index) &sensor_dev_attr_fan##index##_present.dev_attr.attr + +#define DECLARE_FAN_TYPE_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_type, S_IRUGO, refpga_fan_type_show, NULL, FAN##index##_TYPE) +#define DECLARE_FAN_TYPE_ATTR(index) &sensor_dev_attr_fan##index##_type.dev_attr.attr + +static ssize_t refpga_fan_presense_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct sensor_device_attribute *s_attr = to_sensor_dev_attr(attr); + + return sprintf(buf, "%d\n", get_fan_presense(s_attr->index)); + +} + +static ssize_t refpga_fan_type_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct sensor_device_attribute *s_attr = to_sensor_dev_attr(attr); + + return sprintf(buf, "%d\n", get_fan_type(s_attr->index)); + +} + +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(0); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(1); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(2); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(3); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(4); + +DECLARE_FAN_TYPE_SENSOR_DEV_ATTR(0); +DECLARE_FAN_TYPE_SENSOR_DEV_ATTR(1); +DECLARE_FAN_TYPE_SENSOR_DEV_ATTR(2); +DECLARE_FAN_TYPE_SENSOR_DEV_ATTR(3); +DECLARE_FAN_TYPE_SENSOR_DEV_ATTR(4); + +static struct attribute *refpga_fan_attrs[] = { + DECLARE_FAN_PRESENT_ATTR(0), + DECLARE_FAN_PRESENT_ATTR(1), + DECLARE_FAN_PRESENT_ATTR(2), + DECLARE_FAN_PRESENT_ATTR(3), + DECLARE_FAN_PRESENT_ATTR(4), + DECLARE_FAN_TYPE_ATTR(0), + DECLARE_FAN_TYPE_ATTR(1), + DECLARE_FAN_TYPE_ATTR(2), + DECLARE_FAN_TYPE_ATTR(3), + DECLARE_FAN_TYPE_ATTR(4), + NULL +}; + +static struct attribute_group refpga_fan_attr_group = { + .attrs = refpga_fan_attrs, +}; + +/* + * There is only a single ALARM led in QFX5200 and that + * is used for both Major & Minor alarm indicator. + * These are represented by two different bits in RE-FPGA + * PCIE_ALARM register. Only one of the bit (either Red or + * Yellow) should be set a time. If both the bits are set, + * it's an undefined behaviour. + * + * The following table describes how the conditions are + * handled in the driver as there can be both Major & Minor + * alarms can be triggered from userspace. + * + * Major Minor Colour + * + * 0 0 Nil + * 0 1 Yellow + * 1 1 Red + * 1 0 Red + * + */ +static void manage_alarm_led(void __iomem *addr, int led_type, int value) +{ + static int alarm_major = 0, alarm_minor = 0; + u32 reg = 0x0; + + mutex_lock(&alarm_led_lock); + reg = refpga_read(addr, REFPGA_PCIE_ALARM); + + (led_type == ALARM_MAJOR_LED) ? + ((value == 1) ? (alarm_major = 1) : (alarm_major = 0)) : + ((value == 1) ? (alarm_minor = 1) : (alarm_minor = 0)); + if (alarm_major) { + reg &= ~BIT(ALARM_MINOR_LED); + reg |= BIT(ALARM_MAJOR_LED); + } else { + if (alarm_minor) { + reg &= ~BIT(ALARM_MAJOR_LED); + reg |= BIT(ALARM_MINOR_LED); + } else { + reg &= ~BIT(ALARM_MINOR_LED); + reg &= ~BIT(ALARM_MAJOR_LED); + } + } + refpga_write(addr, REFPGA_PCIE_ALARM, reg); + mutex_unlock(&alarm_led_lock); +} + +static void manage_fan_led(void __iomem *addr, int fan_slot, int value) +{ + u8 offset = REFPGA_FAN0_CTRL_STAT + (fan_slot * 2); + u32 reg = 0x0; + + reg = refpga_read(addr, offset); + if(value) { + /* Turn on s/w control */ + reg = reg | BIT(4); + /* Turn off green led */ + reg &= ~BIT(5); + /* Turn on yellow led & make it blink */ + reg |= (BIT(6) | BIT(7)); + } else { + /* Clear yellow led & stop blink */ + reg &= ~(BIT(6) | BIT(7)); + /* Stop s/w control */ + reg &= ~BIT(4); + } + refpga_write(addr, offset, reg); +} + +static void refpga_led_work(struct work_struct *work) +{ + struct refpga_led *led = container_of(work, struct refpga_led, work); + void __iomem *addr; + + addr = led->addr; + + if(strstr(led->lc.name, "fan")) + manage_fan_led(addr, led->bit, led->on); + else + manage_alarm_led(addr, led->bit, led->on); +} + +static void refpga_led_brightness_set(struct led_classdev *lc, + enum led_brightness brightness) +{ + struct refpga_led *led = container_of(lc, struct refpga_led, lc); + + led->on = (brightness != LED_OFF); + led->blink = 0; /* always turn off hw blink on brightness_set() */ + schedule_work(&led->work); +} + +struct led_table +{ + const char *name; + int reg; +}; + +static struct led_table qfx5200_led_data[] = { + { + .name = "alarm-minor", + .reg = 0, + }, + { + .name = "alarm-major", + .reg = 1, + }, + { + .name = "fan0-fault", + .reg = 0, + }, + { + .name = "fan1-fault", + .reg = 1, + }, + { + .name = "fan2-fault", + .reg = 2, + }, + { + .name = "fan3-fault", + .reg = 3, + }, + { + .name = "fan4-fault", + .reg = 4, + } +}; + +static int refpga_led_init_one(struct device *dev, + struct refpga_led_data *ild, + int num) +{ + struct refpga_led *led; + int ret = 0; + + led = &ild->leds[num]; + led->addr = tmc_membase; + + led->lc.name = qfx5200_led_data[num].name; + led->bit = qfx5200_led_data[num].reg; + led->lc.brightness = LED_OFF; + led->lc.brightness_set = refpga_led_brightness_set; + + ret = devm_led_classdev_register(dev, &led->lc); + if (ret) { + dev_err(dev, "devm_led_classdev_register failed\n"); + return ret; + } + + INIT_WORK(&led->work, refpga_led_work); + + return 0; +} + +static int refpga_led_qfx5200_init(struct device *dev, struct refpga_led_data *ild) +{ + int ret = 0, idx = 0; + + + if (!dev->parent) { + dev_err(dev, "dev->parent is null\n"); + return -ENODEV; + } + + ild->num_leds = NUM_LEDS; + ild->leds = devm_kzalloc(dev, sizeof(struct refpga_led) * NUM_LEDS, + GFP_KERNEL); + if (!ild->leds) { + dev_err(dev, "LED allocation failed\n"); + return -ENOMEM; + } + + for(idx=0; idxdev; + struct refpga_led_data *ild; + int ret; + + ild = devm_kzalloc(dev, sizeof(*ild), GFP_KERNEL); + if (!ild) { + dev_err(dev, "ild allocation failed\n"); + return -ENOMEM; + } + + ret = refpga_led_qfx5200_init(dev, ild); + if (ret < 0) + return ret; + + refpga->led = ild; + + return 0; +} + +static int jnx_refpga_led_remove(struct platform_device *pdev) +{ + struct refpga_chip *drv_data = platform_get_drvdata(pdev); + struct refpga_led_data *ild = drv_data->led; + int i; + + for (i = 0; i < ild->num_leds; i++) { + devm_led_classdev_unregister(&pdev->dev, &ild->leds[i].lc); + cancel_work_sync(&ild->leds[i].work); + } + if (ild) { + if (ild->leds) + devm_kfree(&pdev->dev, ild->leds); + devm_kfree(&pdev->dev, ild); + } + return 0; +} + +static void reset_fan_full_speed(struct device *dev) +{ + u32 val = ~(-1), tmp = ~(-1); + + /* + * Reading the REFPGA_PCIE_RESET_CTRL register + */ + val = refpga_read(tmc_membase, REFPGA_PCIE_RESET_CTRL); + /* + * Clearing the fan full_speed bit + */ + val &= ~(REFPGA_RESET_FAN_SPEED); + /* + * Writing the REFPGA_PCIE_RESET_CTRL register + */ + refpga_write(tmc_membase, REFPGA_PCIE_RESET_CTRL, val); + /* + * Reading the REFPGA_PCIE_RESET_CTRL register + */ + tmp = refpga_read(tmc_membase, REFPGA_PCIE_RESET_CTRL); + dev_info(dev, "After resetting fan full speed control: %X\n", tmp); +} + +static int jnx_refpga_tmc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct resource *res; + int ret = 0; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "resource allocation failed\n"); + return -ENODEV; + } + + tmc_membase = devm_ioremap_nocache(dev, res->start, resource_size(res)); + if (!tmc_membase) { + dev_err(dev, "ioremap failed\n"); + return -ENOMEM; + } + + refpga = devm_kzalloc(dev, sizeof(*refpga), GFP_KERNEL); + if (!refpga) { + dev_err(dev, "refpga memory allocation failed\n"); + return -ENOMEM; + } + + reset_fan_full_speed(dev); + + ret = jnx_refpga_led_probe(pdev); + if (ret != 0) { + dev_err(dev, "Refpga LED probe failed\n"); + return ret; + } + + dev_info(dev, "Refpga LED probe successful: TMC memoy base: %p\n", + tmc_membase); + + ret = sysfs_create_group(&dev->kobj, &refpga_fan_attr_group); + if (ret != 0) { + dev_err(dev, "sysfs_create_group failed: %d\n", ret); + return ret; + } + + platform_set_drvdata(pdev, refpga); + + return 0; +} + +static int jnx_refpga_tmc_remove(struct platform_device *pdev) +{ + jnx_refpga_led_remove(pdev); + sysfs_remove_group(&pdev->dev.kobj, &refpga_fan_attr_group); + + return 0; +} + +static struct platform_driver jnx_refpga_tmc_driver = { + .driver = { + .name = "refpga-tmc", + .owner = THIS_MODULE, + }, + .probe = jnx_refpga_tmc_probe, + .remove = jnx_refpga_tmc_remove, +}; + +static int __init jnx_refpga_tmc_driver_init(void) +{ + int ret = -1; + + ret = platform_driver_register(&jnx_refpga_tmc_driver); + + return ret; + +} + +static void __exit jnx_refpga_tmc_driver_exit(void) +{ + platform_driver_unregister(&jnx_refpga_tmc_driver); +} + +module_init(jnx_refpga_tmc_driver_init); +module_exit(jnx_refpga_tmc_driver_exit); + +MODULE_DESCRIPTION("Juniper Networks REFPGA / TMC driver"); +MODULE_AUTHOR("Ciju Rajan K "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-juniper/common/modules/jnx-tmc-core.c b/platform/broadcom/sonic-platform-modules-juniper/common/modules/jnx-tmc-core.c new file mode 100644 index 000000000000..833164bfed63 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/common/modules/jnx-tmc-core.c @@ -0,0 +1,477 @@ +/* + * Juniper Networks TMC-FPGA MFD Core driver for qfx platform + * + * Copyright (c) 2020, Juniper Networks + * Author: Ashish Bhensdadia + * + * This driver implement the resource publish for below devices + * - I2C + * - GPIO + * - RE FPGA + * - PSU + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "jnx-tmc.h" + +#define TMC_DO_SCRATCH_TEST 1 + +/* + * TMC FPGA Device IDs + */ +#define PCI_VENDOR_ID_JUNIPER 0x1304 + +#define PCI_DEVICE_ID_JNX_TMC_CHD 0x007B +#define PCI_DEVICE_ID_JNX_TMC_PFE 0x007C + +/* + * TMC resources + */ +static struct resource tmc_resource_i2c[] = { + /* I2C AUTOMATION Block */ + { + .name = "i2c-tmc", + .start = TMC_I2C_AUTOMATION_I2C_CONTROL_START, + .end = TMC_I2C_AUTOMATION_I2C_CONTROL_END, + .flags = IORESOURCE_MEM, + }, + + /* I2C DPMEM */ + { + .name = "i2c-tmc-mem", + .start = TMC_I2C_DPMEM_ENTRY_START, + .end = TMC_I2C_DPMEM_ENTRY_END, + .flags = IORESOURCE_MEM, + }, +}; + +#define TMC_RES_I2C_NR ARRAY_SIZE(tmc_resource_i2c) + +/* + * LED resources + */ +static struct resource tmc_resource_leds[] = { + { + .name = "leds-tmc", + .start = TMC_LED_CONTROL_START, + .end = TMC_LED_CONTROL_END, + .flags = IORESOURCE_MEM, + }, +}; + +#define TMC_RES_LEDS_NR ARRAY_SIZE(tmc_resource_leds) + +/* + * TMC RE-FPGA devices + */ +static struct resource tmc_resource_refpga[] = { + { + .name = "refpga-tmc", + .start = TMC_REFPGA_ACCESS_START, + .end = TMC_REFPGA_ACCESS_END, + .flags = IORESOURCE_MEM, + }, +}; + +#define TMC_RES_REFPGA_NR ARRAY_SIZE(tmc_resource_refpga) + +static struct resource tmc_resource_gpioslave0[] = { + /* SLAVE0 Block */ + { + .name = "gpioslave-tmc", + .start = TMC_GPIO_SLAVE0_START, + .end = TMC_GPIO_SLAVE0_END, + .flags = IORESOURCE_MEM, + } +}; + +#define TMC_RES_GPIOSLAVE0_NR ARRAY_SIZE(tmc_resource_gpioslave0) + +static struct resource tmc_resource_gpioslave1[] = { + /* SLAVE1 Block */ + { + .name = "gpioslave-tmc", + .start = TMC_GPIO_SLAVE1_START, + .end = TMC_GPIO_SLAVE1_END, + .flags = IORESOURCE_MEM, + } +}; + +#define TMC_RES_GPIOSLAVE1_NR ARRAY_SIZE(tmc_resource_gpioslave1) + +static struct resource tmc_resource_psu[] = { + /* PSU Block */ + { + .name = "psu-tmc", + .start = TMC_PSU_START, + .end = TMC_PSU_END, + .flags = IORESOURCE_MEM, + } +}; + +#define TMC_RES_PSU_NR ARRAY_SIZE(tmc_resource_psu) + +/* + * CHASSISD TMC MFD devices + */ +static struct mfd_cell chassisd_tmc_mfd_devs[] = { + { + .name = "i2c-tmc", + .num_resources = ARRAY_SIZE(tmc_resource_i2c), + .resources = &tmc_resource_i2c[0], + .of_compatible = "jnx,i2c-tmc", + .id = 0, + }, + { + .name = "leds-tmc", + .num_resources = ARRAY_SIZE(tmc_resource_leds), + .resources = &tmc_resource_leds[0], + .of_compatible = "jnx,leds-tmc", + .id = 0, + }, + { + .name = "refpga-tmc", + .num_resources = ARRAY_SIZE(tmc_resource_refpga), + .resources = &tmc_resource_refpga[0], + .of_compatible = "jnx,refpga-tmc", + .id = 0, + }, + { + .name = "psu-tmc", + .num_resources = ARRAY_SIZE(tmc_resource_psu), + .resources = &tmc_resource_psu[0], + .of_compatible = "jnx,psu-tmc", + .id = 0, + }, +}; + +/* + * PFE TMC MFD devices + */ +static struct mfd_cell pfe_tmc_mfd_devs[] = { + { + .name = "i2c-tmc", + .num_resources = ARRAY_SIZE(tmc_resource_i2c), + .resources = &tmc_resource_i2c[0], + .of_compatible = "jnx,i2c-tmc", + .id = 1, + }, + { + .name = "gpioslave-tmc", + .num_resources = ARRAY_SIZE(tmc_resource_gpioslave0), + .resources = &tmc_resource_gpioslave0[0], + .of_compatible = "jnx,gpioslave-tmc", + .id = 0, + }, + { + .name = "gpioslave-tmc", + .num_resources = ARRAY_SIZE(tmc_resource_gpioslave1), + .resources = &tmc_resource_gpioslave1[0], + .of_compatible = "jnx,gpioslave-tmc", + .id = 1, + }, +}; + + +struct tmc_fpga_data { + void __iomem *membase; + struct pci_dev *pdev; + + u32 major; /* Device id & Major version*/ + u32 minor; /* Minor version */ + + u32 optic_cpld_major; /* optic cpld major version */ + u32 optic_cpld_minor; /* optic cpld minor version */ + u32 optic_cpld_devid; /* optic cpld device id */ +}; + +/* sysfs entries */ +static ssize_t major_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct tmc_fpga_data *tmc = dev_get_drvdata(dev); + + return sprintf(buf, "0x%02X_%06X\n", + (tmc->major >> 24) & 0xff, + tmc->major & 0xffffff); +} + +static ssize_t minor_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct tmc_fpga_data *tmc = dev_get_drvdata(dev); + + return sprintf(buf, "%02X\n", (tmc->minor) & 0xff); +} + +static ssize_t optic_cpld_major_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tmc_fpga_data *tmc = dev_get_drvdata(dev); + + return sprintf(buf, "%01X\n", tmc->optic_cpld_major & 0xf); +} + +static ssize_t optic_cpld_devid_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tmc_fpga_data *tmc = dev_get_drvdata(dev); + + return sprintf(buf, "%01X\n", + (tmc->optic_cpld_major >> 4) & 0xf); +} + +static ssize_t optic_cpld_minor_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tmc_fpga_data *tmc = dev_get_drvdata(dev); + + return sprintf(buf, "%02X\n", tmc->optic_cpld_minor & 0xff); +} + +static ssize_t set_sys_shutdown(struct device *dev, + struct device_attribute *devattr, + const char *buf, + size_t len) +{ + + struct tmc_fpga_data *tmc = dev_get_drvdata(dev); + unsigned long val; + int ret; + + ret = kstrtoul(buf, 0, &val); + if (ret < 0) + return ret; + + if (val != 1) + return -EINVAL; + + /* Unlock the shutdown register */ + iowrite32(0x12345678, tmc->membase + TMC_SYS_SHUTDOWN_LOCK); + iowrite32(0x1, tmc->membase + TMC_SYS_SHUTDOWN); + + return len; +} + + +static DEVICE_ATTR(major, S_IRUGO, major_show, NULL); +static DEVICE_ATTR(minor, S_IRUGO, minor_show, NULL); +static DEVICE_ATTR(optic_cpld_major, S_IRUGO, optic_cpld_major_show, NULL); +static DEVICE_ATTR(optic_cpld_devid, S_IRUGO, optic_cpld_devid_show, NULL); +static DEVICE_ATTR(optic_cpld_minor, S_IRUGO, optic_cpld_minor_show, NULL); +static DEVICE_ATTR(shutdown, S_IWUSR, NULL, set_sys_shutdown); + +static struct attribute *tmc_attrs[] = { + &dev_attr_major.attr, + &dev_attr_minor.attr, + &dev_attr_optic_cpld_major.attr, + &dev_attr_optic_cpld_devid.attr, + &dev_attr_optic_cpld_minor.attr, + &dev_attr_shutdown.attr, + NULL, +}; + +static struct attribute_group tmc_attr_group = { + .attrs = tmc_attrs, +}; + +#if defined TMC_DO_SCRATCH_TEST +/* Do a quick scratch access test */ +static int tmc_do_test_scratch(struct tmc_fpga_data *tmc) +{ + struct pci_dev *pdev = tmc->pdev; + struct device *dev = &pdev->dev; + int offset = TMC_SCRATCH; + u32 acc, val = 0xdeadbeaf; + + /* + * Check rw register access -> use the scratch reg. + */ + iowrite32(val, tmc->membase + offset); + acc = ioread32(tmc->membase + offset); + if (acc != val) { + dev_err(dev, "Tmc scratch(0x%x) failed: %08x.%08x!\n", + offset, val, acc); + return -EIO; + } + + for (val = 0; val < 0xf0000000; val += 0x01010101) { + iowrite32(val, tmc->membase + offset); + acc = ioread32(tmc->membase + offset); + if (acc != val) { + dev_err(dev, "Tmc scratch(0x%x) failed: %08x.%08x!\n", + offset, val, acc); + return -EIO; + } + } + + /* + * Write a sig before leaving.. + */ + val = 0xcafebabe; + iowrite32(val, tmc->membase + offset); + dev_dbg(dev, "Tmc scratch result: 0x%08x\n", + ioread32(tmc->membase + offset)); + + return 0; +} +#endif /* TMC_DO_SCRATCH_TEST */ + +static int tmc_fpga_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + int err; + struct tmc_fpga_data *tmc; + struct device *dev = &pdev->dev; + + dev_dbg(dev, "Tmc FPGA Probe called\n"); + + tmc = devm_kzalloc(dev, sizeof(*tmc), GFP_KERNEL); + if (!tmc) + return -ENOMEM; + + err = pcim_enable_device(pdev); + if (err) { + dev_err(&pdev->dev, "Failed to enable device %d\n", err); + return err; + } + + err = pcim_iomap_regions(pdev, 1 << 0, "tmc-core"); + if (err) { + dev_err(&pdev->dev, "Failed to iomap regions %d\n", err); + goto err_disable; + } + + tmc->membase = pcim_iomap_table(pdev)[0]; + if (IS_ERR(tmc->membase)) { + dev_err(dev, "pci_ioremap_bar() failed\n"); + err = -ENOMEM; + goto err_release; + } + + tmc->pdev = pdev; + pci_set_drvdata(pdev, tmc); + + /* All Tmc uses MSI interrupts - enable bus mastering */ + pci_set_master(pdev); + +#if defined TMC_DO_SCRATCH_TEST + /* Check IO before proceeding */ + dev_dbg(dev, "Tmc FPGA starting scratch test\n"); + err = tmc_do_test_scratch(tmc); + if (err) + goto err_unmap; + + dev_dbg(dev, "Tmc FPGA scratch test passed !!!\n"); +#endif /* TMC_DO_SCRATCH_TEST */ + + switch (id->device) { + case PCI_DEVICE_ID_JNX_TMC_CHD: + err = mfd_add_devices(dev, pdev->bus->number, + &chassisd_tmc_mfd_devs[0], + ARRAY_SIZE(chassisd_tmc_mfd_devs), + &pdev->resource[0], + 0, NULL /* tmc->irq_domain */); + break; + case PCI_DEVICE_ID_JNX_TMC_PFE: + err = mfd_add_devices(dev, pdev->bus->number, + &pfe_tmc_mfd_devs[0], + ARRAY_SIZE(pfe_tmc_mfd_devs), + &pdev->resource[0], + 0, NULL /* tmc->irq_domain */); + break; + default: + dev_err(&pdev->dev, "Invalid PCI Device ID id:%d\n", + id->device); + goto err_unmap; + } + + if (err < 0) { + dev_err(&pdev->dev, "Failed to add mfd devices %d\n", err); + goto err_unmap; + } + + err = sysfs_create_group(&pdev->dev.kobj, &tmc_attr_group); + if (err) { + sysfs_remove_group(&pdev->dev.kobj, &tmc_attr_group); + dev_err(&pdev->dev, "Failed to create attr group\n"); + goto err_remove_mfd; + } + + tmc->major = ioread32(tmc->membase + TMC_REVISION); + tmc->minor = ioread32(tmc->membase + TMC_MINOR); + + tmc->optic_cpld_major = ioread32(tmc->membase + TMC_OPTIC_CPLD_MAJOR); + tmc->optic_cpld_minor = ioread32(tmc->membase + TMC_OPTIC_CPLD_MINOR); + + dev_info(dev, "Tmc FPGA Revision: 0x%02X_%06X, Minor: %02X\n", + (tmc->major >> 24) & 0xff, + tmc->major & 0xffffff, + (tmc->minor) & 0xff); + dev_info(dev, "Tmc FPGA optic cpld Major: 0x%01X, Minor: 0x%02X " + "Devid: 0x%01X\n", (tmc->optic_cpld_major) & 0xf, + (tmc->optic_cpld_minor) & 0xff, + (tmc->optic_cpld_major >> 4) & 0xf); + dev_info(dev, "Tmc FPGA mem:0x%lx\n", + (unsigned long)tmc->membase); + + return 0; + +err_remove_mfd: + mfd_remove_devices(dev); +err_unmap: + pci_iounmap(pdev, tmc->membase); +err_release: + pci_release_regions(pdev); +err_disable: + pci_disable_device(pdev); + + return err; +} + +static void tmc_fpga_remove(struct pci_dev *pdev) +{ + struct tmc_fpga_data *tmc = dev_get_drvdata(&pdev->dev); + + sysfs_remove_group(&pdev->dev.kobj, &tmc_attr_group); + mfd_remove_devices(&pdev->dev); +} + +static const struct pci_device_id tmc_fpga_id_tbl[] = { + { PCI_DEVICE(PCI_VENDOR_ID_JUNIPER, PCI_DEVICE_ID_JNX_TMC_CHD) }, + { PCI_DEVICE(PCI_VENDOR_ID_JUNIPER, PCI_DEVICE_ID_JNX_TMC_PFE) }, + { } +}; +MODULE_DEVICE_TABLE(pci, tmc_fpga_id_tbl); + +static struct pci_driver tmc_fpga_driver = { + .name = "tmc-core", + .id_table = tmc_fpga_id_tbl, + .probe = tmc_fpga_probe, + .remove = tmc_fpga_remove, +}; + +module_pci_driver(tmc_fpga_driver); + +MODULE_DESCRIPTION("Juniper Networks TMC FPGA MFD core driver"); +MODULE_AUTHOR("Ashish Bhensdadia "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-juniper/common/modules/jnx-tmc.h b/platform/broadcom/sonic-platform-modules-juniper/common/modules/jnx-tmc.h new file mode 100644 index 000000000000..dce7d7be3311 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/common/modules/jnx-tmc.h @@ -0,0 +1,93 @@ +/* + * Juniper Tmc FPGA register definitions + * + * Copyright (C) 2018 Juniper Networks + * Author: Ashish Bhensdadia + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __JNX_TMC_H__ +#define __JNX_TMC_H__ + + +#define TMC_REVISION 0x00064 +#define TMC_MINOR 0x00068 +#define TMC_SCRATCH 0x00098 + +#define TMC_OPTIC_CPLD_MAJOR 0x00104 +#define TMC_OPTIC_CPLD_MINOR 0x00108 + +/* + * I2C Master Block + */ +#define TMC_I2C_AUTOMATION_I2C_CONTROL_START 0x07000 +#define TMC_I2C_AUTOMATION_I2C_CONTROL_END 0x07500 + +#define TMC_I2C_DPMEM_ENTRY_START 0x10000 +#define TMC_I2C_DPMEM_ENTRY_END 0x13FFC + +#define TMC_LED_CONTROL_START 0x58 +#define TMC_LED_CONTROL_END 0x5B + +/* + * RE-FPGA block + */ +#define TMC_REFPGA_ACCESS_START 0x228 +#define TMC_REFPGA_ACCESS_END 0x233 + +#define TMC_I2C_MASTER_NR_MSTRS 16 +#define TMC_I2C_MSTR_MAX_GROUPS 66 + + +/* + * TMC GPIO SLAVE Block + */ +#define TMC_GPIO_PTP_RESET_START 0x94 +#define TMC_GPIO_PTP_RESET_END 0x97 + +#define TMC_GPIO_PTP_CFG_START 0xa4 +#define TMC_GPIO_PTP_CFG_END 0xa7 + +#define TMC_GPIO_PTP_DATA_START 0xa8 +#define TMC_GPIO_PTP_DATA_END 0xab + +#define TMC_GPIO_SLAVE0_START 0xf0 +#define TMC_GPIO_SLAVE0_END 0x16b + +#define TMC_GPIO_SLAVE1_START 0x170 +#define TMC_GPIO_SLAVE1_END 0x1eb + +#define TMC_GPIO_SLAVE2_START 0x1f0 +#define TMC_GPIO_SLAVE2_END 0x213 + +#define TMC_GPIO_SLAVE3_START 0x280 +#define TMC_GPIO_SLAVE3_END 0x2eb + +#define TMC_GPIO_SFP_SLAVE0_START 0x308 +#define TMC_GPIO_SFP_SLAVE0_END 0x32b + +#define TMC_GPIO_SFP_SLAVE1_START 0x32c +#define TMC_GPIO_SFP_SLAVE1_END 0x34b + +/* + * TMC PSU Block + */ +#define TMC_PSU_START 0x240 +#define TMC_PSU_END 0x243 + +/* + * TMC SHUTDOWN REG + */ +#define TMC_SYS_SHUTDOWN_LOCK 0x254 +#define TMC_SYS_SHUTDOWN 0x250 + +/* + * TMC DS100 MUX Block + */ +#define TMC_GPIO_MUX_SLAVE_START 0x26c +#define TMC_GPIO_MUX_SLAVE_END 0x26f + +#endif /* __JNX_TMC_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-juniper/common/modules/juniper_i2c_cpld.c b/platform/broadcom/sonic-platform-modules-juniper/common/modules/juniper_i2c_cpld.c deleted file mode 100644 index 25860a6ac1f9..000000000000 --- a/platform/broadcom/sonic-platform-modules-juniper/common/modules/juniper_i2c_cpld.c +++ /dev/null @@ -1,892 +0,0 @@ -/* - * A hwmon driver for the juniper_i2c_cpld - * - * Tested and validated on Juniper QFX5210 - * Ciju Rajan K - * - * Copyright (C) 2013 Accton Technology Corporation. - * Brandon Chuang - * - * Based on ad7414.c - * Copyright 2006 Stefan Roese , DENX Software Engineering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define MAX_PORT_NUM 64 -#define I2C_RW_RETRY_COUNT 10 -#define I2C_RW_RETRY_INTERVAL 60 /* ms */ - -#define I2C_ADDR_CPLD1 0x60 -#define I2C_ADDR_CPLD2 0x62 -#define I2C_ADDR_CPLD3 0x64 -#define CPLD_ADDRS {I2C_ADDR_CPLD1, I2C_ADDR_CPLD2, I2C_ADDR_CPLD3} - - -/* - * Number of additional attribute pointers to allocate - * with each call to krealloc - */ -#define ATTR_ALLOC_SIZE 1 /*For last attribute which is NUll.*/ - -#define NAME_SIZE 24 -#define MAX_RESP_LENGTH 48 - -typedef ssize_t (*show_func)( struct device *dev, - struct device_attribute *attr, - char *buf); -typedef ssize_t (*store_func)(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count); - -enum models { - AS7712_32X, - AS7716_32X, - qfx5210_64X, - AS7312_54X, - PLAIN_CPLD, /*No attribute but add i2c addr to the list.*/ - NUM_MODEL -}; - -enum sfp_func { - HAS_SFP = 1<<0 , - HAS_QSFP = 1<<1 , -}; - -enum common_attrs { - CMN_VERSION, - CMN_ACCESS, - CMN_PRESENT_ALL, - NUM_COMMON_ATTR -}; - -enum sfp_attrs { - SFP_PRESENT, - SFP_RESET, - SFP_LP_MODE, - NUM_SFP_ATTR -}; - -struct cpld_sensor { - struct cpld_sensor *next; - char name[NAME_SIZE+1]; /* sysfs sensor name */ - struct device_attribute attribute; - bool update; /* runtime sensor update needed */ - int data; /* Sensor data. Negative if there was a read error */ - - u8 reg; /* register */ - u8 mask; /* bit mask */ - bool invert; /* inverted value*/ - -}; - -#define to_cpld_sensor(_attr) \ - container_of(_attr, struct cpld_sensor, attribute) - -struct cpld_data { - struct device *dev; - struct device *hwmon_dev; - - int num_attributes; - struct attribute_group group; - - enum models model; - struct cpld_sensor *sensors; - struct mutex update_lock; - bool valid; - unsigned long last_updated; /* in jiffies */ - - int attr_index; - u16 sfp_num; - u8 sfp_types; - struct model_attrs *cmn_attr; -}; - -struct cpld_client_node { - struct i2c_client *client; - struct list_head list; -}; - - -struct base_attrs { - const char *name; - umode_t mode; - show_func get; - store_func set; -}; - -struct attrs { - int reg; - bool invert; - struct base_attrs *base; -}; - -struct model_attrs { - struct attrs **cmn; - struct attrs **portly; -}; - - -static ssize_t show_bit(struct device *dev, - struct device_attribute *devattr, char *buf); -static ssize_t show_presnet_all(struct device *dev, - struct device_attribute *devattr, char *buf); -static ssize_t set_1bit(struct device *dev, struct device_attribute *da, - const char *buf, size_t count); -static ssize_t set_byte(struct device *dev, struct device_attribute *da, - const char *buf, size_t count); -static ssize_t access(struct device *dev, struct device_attribute *da, - const char *buf, size_t count); - -int juniper_i2c_cpld_read(u8 cpld_addr, u8 reg); -int juniper_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); - - -struct base_attrs common_attrs[NUM_COMMON_ATTR] = -{ - [CMN_VERSION] = {"version", S_IRUGO, show_bit, NULL}, - [CMN_ACCESS] = {"access", S_IWUSR, NULL, set_byte}, - [CMN_PRESENT_ALL] = {"module_present_all", S_IRUGO, show_presnet_all, NULL}, -}; - -struct attrs as7712_common[] = { - [CMN_VERSION] = {0x01, false, &common_attrs[CMN_VERSION]}, - [CMN_ACCESS] = {0x00, false, &common_attrs[CMN_ACCESS]}, - [CMN_PRESENT_ALL] = {0x30, false, &common_attrs[CMN_PRESENT_ALL]}, -}; -struct attrs qfx5210_common[] = { - [CMN_VERSION] = {0x01, false, &common_attrs[CMN_VERSION]}, - [CMN_ACCESS] = {0x00, false, &common_attrs[CMN_ACCESS]}, - [CMN_PRESENT_ALL] = {0x30, false, &common_attrs[CMN_PRESENT_ALL]}, -}; -struct attrs as7312_common[] = { - [CMN_VERSION] = {0x01, false, &common_attrs[CMN_VERSION]}, - [CMN_ACCESS] = {0x00, false, &common_attrs[CMN_ACCESS]}, - [CMN_PRESENT_ALL] = {-1, false, &common_attrs[CMN_PRESENT_ALL]}, -}; -struct attrs plain_common[] = { - [CMN_VERSION] = {0x01, false, &common_attrs[CMN_VERSION]}, -}; - -struct base_attrs portly_attrs[] = -{ - [SFP_PRESENT] = {"module_present", S_IRUGO, show_bit, NULL}, - // Only root user will have the privilege to write to sysfs - // [SFP_RESET] = {"module_reset", S_IRUGO|S_IWUGO, show_bit, set_1bit}, - [SFP_RESET] = {"module_reset", S_IRUGO|S_IWUSR, show_bit, set_1bit}, -}; - -struct attrs as7712_port[] = { - {0x30, true, &portly_attrs[SFP_PRESENT]}, - {0x04, true, &portly_attrs[SFP_RESET]}, -}; - -struct attrs qfx5210_port[] = { - {0x70, true, &portly_attrs[SFP_PRESENT]}, - {0x40, true, &portly_attrs[SFP_RESET]}, -}; - -struct attrs *as7712_cmn_list[] = { - &as7712_common[CMN_VERSION], - &as7712_common[CMN_ACCESS], - &as7712_common[CMN_PRESENT_ALL], - NULL -}; - -struct attrs *qfx5210_cmn_list[] = { - &qfx5210_common[CMN_VERSION], - &qfx5210_common[CMN_ACCESS], - &qfx5210_common[CMN_PRESENT_ALL], - NULL -}; - -struct attrs *as7312_cmn_list[] = { - &as7312_common[CMN_VERSION], - &as7312_common[CMN_ACCESS], - &as7312_common[CMN_PRESENT_ALL], - NULL -}; - -struct attrs *plain_cmn_list[] = { - &plain_common[CMN_VERSION], - NULL -}; - -struct attrs *as7712_port_list[] = { - &as7712_port[SFP_PRESENT], - &as7712_port[SFP_RESET], - NULL -}; -struct attrs *qfx5210_port_list[] = { - &qfx5210_port[SFP_PRESENT], - &qfx5210_port[SFP_RESET], - NULL -}; - -struct model_attrs models_attr[NUM_MODEL] = { - {.cmn = as7712_cmn_list, .portly=as7712_port_list}, - {.cmn = as7712_cmn_list, .portly=as7712_port_list}, /*7716's as 7712*/ - {.cmn = qfx5210_cmn_list, .portly=qfx5210_port_list}, - {.cmn = as7312_cmn_list, .portly=qfx5210_port_list}, - {.cmn = plain_cmn_list, .portly=NULL}, -}; - -static LIST_HEAD(cpld_client_list); -static struct mutex list_lock; -/* Addresses scanned for juniper_i2c_cpld - */ -static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -static int get_sfp_spec(int model, u16 *num, u8 *types) -{ - switch (model) { - case AS7712_32X: - case AS7716_32X: - *num = 32; - *types = HAS_QSFP; - break; - case qfx5210_64X: - *num = 64; - *types = HAS_QSFP; - break; - case AS7312_54X: - *num = 54; - *types = HAS_QSFP|HAS_SFP; - default: - *types = 0; - *num = 0; - break; - } - - return 0; -} - -static int get_present_reg(int model, u8 port, u8 *cpld_addr, u8 *reg, u8 *num) -{ - u8 cpld_address[] = CPLD_ADDRS; - - switch (model) { - case AS7312_54X: - if (port < 48) { - *cpld_addr = cpld_address[1 + port/24]; - *reg = 0x09 + (port%24)/8; - *num = 8; - } - else - { - *reg = 0x18; - *num = 4; - *cpld_addr = ( port < 52)? cpld_address[1]: cpld_address[2]; - } - break; - default: - return -EINVAL; - } -} - - -/*Assume the bits for ports are listed in-a-row.*/ -static int get_reg_bit(u8 reg_start, int port, - u8 *reg ,u8 *mask) -{ - *reg = reg_start + ((port)/8); - *mask = 1 << ((port)%8); - - return 0; -} - -static int cpld_write_internal( - struct i2c_client *client, u8 reg, u8 value) -{ - int status = 0, retry = I2C_RW_RETRY_COUNT; - - while (retry) { - status = i2c_smbus_write_byte_data(client, reg, value); - if (unlikely(status < 0)) { - msleep(I2C_RW_RETRY_INTERVAL); - retry--; - continue; - } - - break; - } - - return status; -} - -static int cpld_read_internal(struct i2c_client *client, u8 reg) -{ - int status = 0, retry = I2C_RW_RETRY_COUNT; - - while (retry) { - status = i2c_smbus_read_byte_data(client, reg); - if (unlikely(status < 0)) { - msleep(I2C_RW_RETRY_INTERVAL); - retry--; - continue; - } - - break; - } - - return status; -} - - -/*Turn a numberic array into string with " " between each element. - * e.g., {0x11, 0x33, 0xff, 0xf1} => "11 33 ff f1" - */ -static ssize_t array_stringify(char *buf, u8 *input, size_t size) { - - int i; - char t[MAX_RESP_LENGTH+1]; - - buf[0] = '\0'; - for (i = 0; i < size; i++) { - snprintf(t, MAX_RESP_LENGTH, "%x ", input[i]); - strncat(buf, t, MAX_RESP_LENGTH); - } - - if (strlen(buf) > 0) - buf[strlen(buf)-1] = '\0'; /*Remove tailing blank*/ - - return snprintf(buf, MAX_RESP_LENGTH, "%s\n", buf); -} - -static ssize_t show_presnet_all_distinct(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct cpld_data *data = i2c_get_clientdata(client); - u8 i, value, reg; - u8 cpld_addr, num; - u8 _value[8]; - u64 *values = (u64 *)_value; - - values = 0; - mutex_lock(&data->update_lock); - while(i < data->sfp_num) - { - get_present_reg(data->model, i, &cpld_addr, ®, &num); - if(cpld_addr == client->addr) - value = cpld_read_internal(client, reg); - else - value = juniper_i2c_cpld_read(cpld_addr, reg); - - if (unlikely(value < 0)) { - goto exit; - } - - *values |= (value&((1<<(num))-1)) << i; - i += num; - } - mutex_unlock(&data->update_lock); - - *values = cpu_to_le64(*values); - return array_stringify(buf, _value, i); -exit: - mutex_unlock(&data->update_lock); - return value; -} - -static ssize_t show_presnet_all(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct cpld_data *data = i2c_get_clientdata(client); - struct cpld_sensor *sensor = to_cpld_sensor(devattr); - u8 i, values[MAX_RESP_LENGTH/8]; - - if (sensor->reg < 0) { - return show_presnet_all_distinct(dev, devattr, buf); - } - - mutex_lock(&data->update_lock); - for (i = 0; i < ((data->sfp_num+7)/8); i++) { - values[i] = cpld_read_internal(client, sensor->reg + i); - if (unlikely(values[i] < 0)) { - goto exit; - } - } - mutex_unlock(&data->update_lock); - return array_stringify(buf, values, i); - -exit: - mutex_unlock(&data->update_lock); - return values[i]; -} - -static ssize_t show_bit(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - int value; - struct i2c_client *client = to_i2c_client(dev); - struct cpld_data *data = i2c_get_clientdata(client); - struct cpld_sensor *sensor = to_cpld_sensor(devattr); - - mutex_lock(&data->update_lock); - value = cpld_read_internal(client, sensor->reg); - value = value & sensor->mask; - if (sensor->invert) - value = !value; - mutex_unlock(&data->update_lock); - - return snprintf(buf, PAGE_SIZE, "%x\n", value); -} - -static ssize_t set_1bit(struct device *dev, struct device_attribute *devattr, - const char *buf, size_t count) -{ - long is_reset; - int value, status; - struct i2c_client *client = to_i2c_client(dev); - struct cpld_data *data = i2c_get_clientdata(client); - struct cpld_sensor *sensor = to_cpld_sensor(devattr); - u8 cpld_bit, reg; - - status = kstrtol(buf, 10, &is_reset); - if (status) { - return status; - } - reg = sensor->reg; - cpld_bit = sensor->mask; - mutex_lock(&data->update_lock); - value = cpld_read_internal(client, reg); - if (unlikely(status < 0)) { - goto exit; - } - - if (sensor->invert) - is_reset = !is_reset; - - if (is_reset) { - value |= cpld_bit; - } - else { - value &= ~cpld_bit; - } - - status = cpld_write_internal(client, reg, value); - if (unlikely(status < 0)) { - goto exit; - } - mutex_unlock(&data->update_lock); - return count; - -exit: - mutex_unlock(&data->update_lock); - return status; -} - -static ssize_t set_byte(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) -{ - return access(dev, da, buf, count); -} - -static ssize_t access(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) -{ - int status; - u32 addr, val; - struct i2c_client *client = to_i2c_client(dev); - struct cpld_data *data = i2c_get_clientdata(client); - - if (sscanf(buf, "0x%x 0x%x", &addr, &val) != 2) { - return -EINVAL; - } - - if (addr > 0xFF || val > 0xFF) { - return -EINVAL; - } - - mutex_lock(&data->update_lock); - status = cpld_write_internal(client, addr, val); - if (unlikely(status < 0)) { - goto exit; - } - mutex_unlock(&data->update_lock); - return count; - -exit: - mutex_unlock(&data->update_lock); - return status; -} - -static void juniper_i2c_cpld_add_client(struct i2c_client *client) -{ - struct cpld_client_node *node = - kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL); - - if (!node) { - dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", - client->addr); - return; - } - node->client = client; - - mutex_lock(&list_lock); - list_add(&node->list, &cpld_client_list); - mutex_unlock(&list_lock); -} - -static void juniper_i2c_cpld_remove_client(struct i2c_client *client) -{ - struct list_head *list_node = NULL; - struct cpld_client_node *cpld_node = NULL; - int found = 0; - - mutex_lock(&list_lock); - - list_for_each(list_node, &cpld_client_list) - { - cpld_node = list_entry(list_node, struct cpld_client_node, list); - - if (cpld_node->client == client) { - found = 1; - break; - } - } - - if (found) { - list_del(list_node); - kfree(cpld_node); - } - - mutex_unlock(&list_lock); -} - -static int cpld_add_attribute(struct cpld_data *data, struct attribute *attr) -{ - int new_max_attrs = ++data->num_attributes + ATTR_ALLOC_SIZE; - void *new_attrs = krealloc(data->group.attrs, - new_max_attrs * sizeof(void *), - GFP_KERNEL); - if (!new_attrs) - return -ENOMEM; - data->group.attrs = new_attrs; - - - data->group.attrs[data->num_attributes-1] = attr; - data->group.attrs[data->num_attributes] = NULL; - - return 0; -} - -static void cpld_dev_attr_init(struct device_attribute *dev_attr, - const char *name, umode_t mode, - show_func show, store_func store) -{ - sysfs_attr_init(&dev_attr->attr); - dev_attr->attr.name = name; - dev_attr->attr.mode = mode; - dev_attr->show = show; - dev_attr->store = store; -} - -static struct cpld_sensor * add_sensor(struct cpld_data *data, - const char *name, - u8 reg, u8 mask, bool invert, - bool update, umode_t mode, - show_func get, store_func set) -{ - struct cpld_sensor *sensor; - struct device_attribute *a; - - sensor = devm_kzalloc(data->dev, sizeof(*sensor), GFP_KERNEL); - if (!sensor) - return NULL; - a = &sensor->attribute; - - snprintf(sensor->name, sizeof(sensor->name), name); - sensor->reg = reg; - sensor->mask = mask; - sensor->update = update; - sensor->invert = invert; - cpld_dev_attr_init(a, sensor->name, - mode, - get, set); - - if (cpld_add_attribute(data, &a->attr)) - return NULL; - - sensor->next = data->sensors; - data->sensors = sensor; - - return sensor; -} - -static int add_attributes_cmn(struct cpld_data *data, struct attrs **cmn) -{ - u8 reg, i ; - bool invert; - struct attrs *a; - struct base_attrs *b; - - if (NULL == cmn) - return -1; - - for (i = 0; cmn[i]; i++) - { - a = cmn[i]; - - reg = a->reg; - invert = a->invert; - - b = a->base; - if (NULL == b) - break; - - if (add_sensor(data, b->name, - reg, 0xff, invert, - true, b->mode, - b->get, b->set) == NULL) - { - return -ENOMEM; - } - } - return 0; -} - -static int add_attributes_portly(struct cpld_data *data, struct attrs **pa) -{ - char name[NAME_SIZE+1]; - int i, j; - u8 reg, mask, invert; - struct attrs *a; - struct base_attrs *b; - - if (NULL == pa) - return -1; - - - for (i = 0; pa[i]; i++) { - a = pa[i]; - - invert = a->invert; - b = a->base; - if (b == NULL) - break; - - for (j = 0; j < data->sfp_num; j++) - { - snprintf(name, NAME_SIZE, "%s_%d", b->name, j+1); - get_reg_bit(a->reg, j, ®, &mask); - - if (add_sensor(data, name, reg, mask, invert, - true, b->mode, b->get, b->set) == NULL) - { - return -ENOMEM; - } - } - } - return 0; -} - -static int add_attributes(struct i2c_client *client, - struct cpld_data *data) -{ - struct model_attrs *m = data->cmn_attr; - - if (m == NULL) - return -EINVAL; - - /* Common attributes.*/ - add_attributes_cmn(data, m->cmn); - - /* Port-wise attributes.*/ - add_attributes_portly(data, m->portly); - - return 0; -} - -static int juniper_i2c_cpld_probe(struct i2c_client *client, - const struct i2c_device_id *dev_id) -{ - int status; - struct cpld_data *data = NULL; - struct device *dev = &client->dev; - - if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { - dev_dbg(dev, "i2c_check_functionality failed (0x%x)\n", client->addr); - return -EIO; - } - - data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); - if (!data) { - return -ENOMEM; - } - - data->model = dev_id->driver_data; - data->cmn_attr = &models_attr[data->model]; - get_sfp_spec(data->model, &data->sfp_num, &data->sfp_types); - - i2c_set_clientdata(client, data); - mutex_init(&data->update_lock); - data->dev = dev; - dev_info(dev, "chip found\n"); - - status = add_attributes(client, data); - if (status) - goto out_kfree; - - /* - * If there are no attributes, something is wrong. - * Bail out instead of trying to register nothing. - */ - if (!data->num_attributes) { - dev_err(dev, "No attributes found\n"); - status = -ENODEV; - goto out_kfree; - } - - /* Register sysfs hooks */ - status = sysfs_create_group(&client->dev.kobj, &data->group); - if (status) { - goto out_kfree; - } - - data->hwmon_dev = hwmon_device_register(&client->dev); - if (IS_ERR(data->hwmon_dev)) { - status = PTR_ERR(data->hwmon_dev); - goto exit_remove; - } - - juniper_i2c_cpld_add_client(client); - dev_info(dev, "%s: cpld '%s'\n", - dev_name(data->hwmon_dev), client->name); - - return 0; -exit_remove: - sysfs_remove_group(&client->dev.kobj, &data->group); -out_kfree: - kfree(data->group.attrs); - return status; - -} - -static int juniper_i2c_cpld_remove(struct i2c_client *client) -{ - struct cpld_data *data = i2c_get_clientdata(client); - - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &data->group); - kfree(data->group.attrs); - juniper_i2c_cpld_remove_client(client); - return 0; -} - -int juniper_i2c_cpld_read(u8 cpld_addr, u8 reg) -{ - struct list_head *list_node = NULL; - struct cpld_client_node *cpld_node = NULL; - int ret = -EPERM; - - mutex_lock(&list_lock); - - list_for_each(list_node, &cpld_client_list) - { - cpld_node = list_entry(list_node, struct cpld_client_node, list); - - if (cpld_node->client->addr == cpld_addr) { - ret = i2c_smbus_read_byte_data(cpld_node->client, reg); - break; - } - } - - mutex_unlock(&list_lock); - - return ret; -} -EXPORT_SYMBOL(juniper_i2c_cpld_read); - -int juniper_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value) -{ - struct list_head *list_node = NULL; - struct cpld_client_node *cpld_node = NULL; - int ret = -EIO; - - mutex_lock(&list_lock); - - list_for_each(list_node, &cpld_client_list) - { - cpld_node = list_entry(list_node, struct cpld_client_node, list); - - if (cpld_node->client->addr == cpld_addr) { - ret = i2c_smbus_write_byte_data(cpld_node->client, reg, value); - break; - } - } - - mutex_unlock(&list_lock); - - return ret; -} -EXPORT_SYMBOL(juniper_i2c_cpld_write); - - -static const struct i2c_device_id juniper_i2c_cpld_id[] = { - { "cpld_as7712", AS7712_32X}, - { "cpld_as7716", AS7716_32X}, - { "cpld_qfx5210", qfx5210_64X}, - { "cpld_as7312", AS7312_54X}, - { "cpld_plain", PLAIN_CPLD}, - { }, -}; -MODULE_DEVICE_TABLE(i2c, juniper_i2c_cpld_id); - -static struct i2c_driver juniper_i2c_cpld_driver = { - .class = I2C_CLASS_HWMON, - .driver = { - .name = "juniper_i2c_cpld", - }, - .probe = juniper_i2c_cpld_probe, - .remove = juniper_i2c_cpld_remove, - .id_table = juniper_i2c_cpld_id, - .address_list = normal_i2c, -}; - - -static int __init juniper_i2c_cpld_init(void) -{ - mutex_init(&list_lock); - return i2c_add_driver(&juniper_i2c_cpld_driver); -} - -static void __exit juniper_i2c_cpld_exit(void) -{ - i2c_del_driver(&juniper_i2c_cpld_driver); -} - -module_init(juniper_i2c_cpld_init); -module_exit(juniper_i2c_cpld_exit); - -MODULE_AUTHOR("Brandon Chuang "); -MODULE_DESCRIPTION("juniper_i2c_cpld driver"); -MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-juniper/common/modules/ym2651y.c b/platform/broadcom/sonic-platform-modules-juniper/common/modules/ym2651y.c deleted file mode 100644 index 3ade5684107a..000000000000 --- a/platform/broadcom/sonic-platform-modules-juniper/common/modules/ym2651y.c +++ /dev/null @@ -1,622 +0,0 @@ -/* - * An hwmon driver for the 3Y Power YM-2651Y Power Module - * - * Tested and validated on Juniper QFX5210 - * Ciju Rajan K - * - * Copyright (C) 2014 Accton Technology Corporation. - * Brandon Chuang - * - * Based on ad7414.c - * Copyright 2006 Stefan Roese , DENX Software Engineering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MAX_FAN_DUTY_CYCLE 100 - -/* Addresses scanned - */ -static const unsigned short normal_i2c[] = { 0x58, 0x5b, I2C_CLIENT_END }; - -enum chips { - YM2651, - YM2401, - YM2851, -}; - -/* Each client has this additional data - */ -struct ym2651y_data { - struct device *hwmon_dev; - struct mutex update_lock; - char valid; /* !=0 if registers are valid */ - unsigned long last_updated; /* In jiffies */ - u8 capability; /* Register value */ - u16 status_word; /* Register value */ - u8 fan_fault; /* Register value */ - u8 over_temp; /* Register value */ - u16 v_out; /* Register value */ - u16 i_out; /* Register value */ - u16 p_out; /* Register value */ - u16 temp; /* Register value */ - u16 fan_speed; /* Register value */ - u16 fan_duty_cycle[2]; /* Register value */ - u8 fan_dir[4]; /* Register value */ - u8 pmbus_revision; /* Register value */ - u8 mfr_id[10]; /* Register value */ - u8 mfr_model[10]; /* Register value */ - u8 mfr_revsion[3]; /* Register value */ - u16 mfr_vin_min; /* Register value */ - u16 mfr_vin_max; /* Register value */ - u16 mfr_iin_max; /* Register value */ - u16 mfr_iout_max; /* Register value */ - u16 mfr_pin_max; /* Register value */ - u16 mfr_pout_max; /* Register value */ - u16 mfr_vout_min; /* Register value */ - u16 mfr_vout_max; /* Register value */ -}; - -static ssize_t show_byte(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t show_word(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t show_linear(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t show_over_temp(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t show_ascii(struct device *dev, struct device_attribute *da, - char *buf); -static struct ym2651y_data *ym2651y_update_device(struct device *dev); -static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, - const char *buf, size_t count); -static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value); - -enum ym2651y_sysfs_attributes { - PSU_POWER_ON = 0, - PSU_TEMP_FAULT, - PSU_POWER_GOOD, - PSU_FAN1_FAULT, - PSU_FAN_DIRECTION, - PSU_OVER_TEMP, - PSU_V_OUT, - PSU_I_OUT, - PSU_P_OUT, - PSU_P_OUT_UV, /*In Unit of microVolt, instead of mini.*/ - PSU_TEMP1_INPUT, - PSU_FAN1_SPEED, - PSU_FAN1_DUTY_CYCLE, - PSU_PMBUS_REVISION, - PSU_MFR_ID, - PSU_MFR_MODEL, - PSU_MFR_REVISION, - PSU_MFR_VIN_MIN, - PSU_MFR_VIN_MAX, - PSU_MFR_VOUT_MIN, - PSU_MFR_VOUT_MAX, - PSU_MFR_IIN_MAX, - PSU_MFR_IOUT_MAX, - PSU_MFR_PIN_MAX, - PSU_MFR_POUT_MAX -}; - -/* sysfs attributes for hwmon - */ -static SENSOR_DEVICE_ATTR(psu_power_on, S_IRUGO, show_word, NULL, PSU_POWER_ON); -static SENSOR_DEVICE_ATTR(psu_temp_fault, S_IRUGO, show_word, NULL, PSU_TEMP_FAULT); -static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_word, NULL, PSU_POWER_GOOD); -static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, show_fan_fault, NULL, PSU_FAN1_FAULT); -static SENSOR_DEVICE_ATTR(psu_over_temp, S_IRUGO, show_over_temp, NULL, PSU_OVER_TEMP); -static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, show_linear, NULL, PSU_V_OUT); -static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, show_linear, NULL, PSU_I_OUT); -static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, show_linear, NULL, PSU_P_OUT); -static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, show_linear, NULL, PSU_TEMP1_INPUT); -static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED); -static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, show_linear, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE); -static SENSOR_DEVICE_ATTR(psu_fan_dir, S_IRUGO, show_ascii, NULL, PSU_FAN_DIRECTION); -static SENSOR_DEVICE_ATTR(psu_pmbus_revision, S_IRUGO, show_byte, NULL, PSU_PMBUS_REVISION); -static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, show_ascii, NULL, PSU_MFR_ID); -static SENSOR_DEVICE_ATTR(psu_mfr_model, S_IRUGO, show_ascii, NULL, PSU_MFR_MODEL); -static SENSOR_DEVICE_ATTR(psu_mfr_revision, S_IRUGO, show_ascii, NULL, PSU_MFR_REVISION); -static SENSOR_DEVICE_ATTR(psu_mfr_vin_min, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MIN); -static SENSOR_DEVICE_ATTR(psu_mfr_vin_max, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MAX); -static SENSOR_DEVICE_ATTR(psu_mfr_vout_min, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MIN); -static SENSOR_DEVICE_ATTR(psu_mfr_vout_max, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MAX); -static SENSOR_DEVICE_ATTR(psu_mfr_iin_max, S_IRUGO, show_linear, NULL, PSU_MFR_IIN_MAX); -static SENSOR_DEVICE_ATTR(psu_mfr_iout_max, S_IRUGO, show_linear, NULL, PSU_MFR_IOUT_MAX); -static SENSOR_DEVICE_ATTR(psu_mfr_pin_max, S_IRUGO, show_linear, NULL, PSU_MFR_PIN_MAX); -static SENSOR_DEVICE_ATTR(psu_mfr_pout_max, S_IRUGO, show_linear, NULL, PSU_MFR_POUT_MAX); - -/*Duplicate nodes for lm-sensors.*/ -static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_linear, NULL, PSU_V_OUT); -static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, show_linear, NULL, PSU_I_OUT); -static SENSOR_DEVICE_ATTR(power2_input, S_IRUGO, show_linear, NULL, PSU_P_OUT_UV); -static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_linear, NULL, PSU_TEMP1_INPUT); -static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED); -static SENSOR_DEVICE_ATTR(temp1_fault, S_IRUGO, show_word, NULL, PSU_TEMP_FAULT); - -static struct attribute *ym2651y_attributes[] = { - &sensor_dev_attr_psu_power_on.dev_attr.attr, - &sensor_dev_attr_psu_temp_fault.dev_attr.attr, - &sensor_dev_attr_psu_power_good.dev_attr.attr, - &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, - &sensor_dev_attr_psu_over_temp.dev_attr.attr, - &sensor_dev_attr_psu_v_out.dev_attr.attr, - &sensor_dev_attr_psu_i_out.dev_attr.attr, - &sensor_dev_attr_psu_p_out.dev_attr.attr, - &sensor_dev_attr_psu_temp1_input.dev_attr.attr, - &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, - &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, - &sensor_dev_attr_psu_fan_dir.dev_attr.attr, - &sensor_dev_attr_psu_pmbus_revision.dev_attr.attr, - &sensor_dev_attr_psu_mfr_id.dev_attr.attr, - &sensor_dev_attr_psu_mfr_model.dev_attr.attr, - &sensor_dev_attr_psu_mfr_revision.dev_attr.attr, - &sensor_dev_attr_psu_mfr_vin_min.dev_attr.attr, - &sensor_dev_attr_psu_mfr_vin_max.dev_attr.attr, - &sensor_dev_attr_psu_mfr_pout_max.dev_attr.attr, - &sensor_dev_attr_psu_mfr_iin_max.dev_attr.attr, - &sensor_dev_attr_psu_mfr_pin_max.dev_attr.attr, - &sensor_dev_attr_psu_mfr_vout_min.dev_attr.attr, - &sensor_dev_attr_psu_mfr_vout_max.dev_attr.attr, - &sensor_dev_attr_psu_mfr_iout_max.dev_attr.attr, - /*Duplicate nodes for lm-sensors.*/ - &sensor_dev_attr_curr2_input.dev_attr.attr, - &sensor_dev_attr_in3_input.dev_attr.attr, - &sensor_dev_attr_power2_input.dev_attr.attr, - &sensor_dev_attr_temp1_input.dev_attr.attr, - &sensor_dev_attr_fan1_input.dev_attr.attr, - &sensor_dev_attr_temp1_fault.dev_attr.attr, - NULL -}; - -static ssize_t show_byte(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); - - return (attr->index == PSU_PMBUS_REVISION) ? sprintf(buf, "%d\n", data->pmbus_revision) : - sprintf(buf, "0\n"); -} - -static ssize_t show_word(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); - u16 status = 0; - - switch (attr->index) { - case PSU_POWER_ON: /* psu_power_on, low byte bit 6 of status_word, 0=>ON, 1=>OFF */ - status = (data->status_word & 0x40) ? 0 : 1; - break; - case PSU_TEMP_FAULT: /* psu_temp_fault, low byte bit 2 of status_word, 0=>Normal, 1=>temp fault */ - status = (data->status_word & 0x4) >> 2; - break; - case PSU_POWER_GOOD: /* psu_power_good, high byte bit 3 of status_word, 0=>OK, 1=>FAIL */ - status = (data->status_word & 0x800) ? 0 : 1; - break; - } - - return sprintf(buf, "%d\n", status); -} - -static int two_complement_to_int(u16 data, u8 valid_bit, int mask) -{ - u16 valid_data = data & mask; - bool is_negative = valid_data >> (valid_bit - 1); - - return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; -} - -static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct i2c_client *client = to_i2c_client(dev); - struct ym2651y_data *data = i2c_get_clientdata(client); - int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1; - long speed; - int error; - - error = kstrtol(buf, 10, &speed); - if (error) - return error; - - if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE) - return -EINVAL; - - mutex_lock(&data->update_lock); - data->fan_duty_cycle[nr] = speed; - ym2651y_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]); - mutex_unlock(&data->update_lock); - - return count; -} - -static ssize_t show_linear(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); - - u16 value = 0; - int exponent, mantissa; - int multiplier = 1000; - - switch (attr->index) { - case PSU_V_OUT: - value = data->v_out; - break; - case PSU_I_OUT: - value = data->i_out; - break; - case PSU_P_OUT_UV: - multiplier = 1000000; /*For lm-sensors, unit is micro-Volt.*/ - /*Passing through*/ - case PSU_P_OUT: - value = data->p_out; - break; - case PSU_TEMP1_INPUT: - value = data->temp; - break; - case PSU_FAN1_SPEED: - value = data->fan_speed; - multiplier = 1; - break; - case PSU_FAN1_DUTY_CYCLE: - value = data->fan_duty_cycle[0]; - multiplier = 1; - break; - case PSU_MFR_VIN_MIN: - value = data->mfr_vin_min; - break; - case PSU_MFR_VIN_MAX: - value = data->mfr_vin_max; - break; - case PSU_MFR_VOUT_MIN: - value = data->mfr_vout_min; - break; - case PSU_MFR_VOUT_MAX: - value = data->mfr_vout_max; - break; - case PSU_MFR_PIN_MAX: - value = data->mfr_pin_max; - break; - case PSU_MFR_POUT_MAX: - value = data->mfr_pout_max; - break; - case PSU_MFR_IOUT_MAX: - value = data->mfr_iout_max; - break; - case PSU_MFR_IIN_MAX: - value = data->mfr_iin_max; - break; - } - - exponent = two_complement_to_int(value >> 11, 5, 0x1f); - mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); - return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : - sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); -} - -static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); - - u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; - - return sprintf(buf, "%d\n", data->fan_fault >> shift); -} - -static ssize_t show_over_temp(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct ym2651y_data *data = ym2651y_update_device(dev); - - return sprintf(buf, "%d\n", data->over_temp >> 7); -} - -static ssize_t show_ascii(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); - u8 *ptr = NULL; - - switch (attr->index) { - case PSU_FAN_DIRECTION: /* psu_fan_dir */ - ptr = data->fan_dir; - break; - case PSU_MFR_ID: /* psu_mfr_id */ - ptr = data->mfr_id; - break; - case PSU_MFR_MODEL: /* psu_mfr_model */ - ptr = data->mfr_model; - break; - case PSU_MFR_REVISION: /* psu_mfr_revision */ - ptr = data->mfr_revsion; - break; - default: - return 0; - } - - return sprintf(buf, "%s\n", ptr); -} - -static const struct attribute_group ym2651y_group = { - .attrs = ym2651y_attributes, -}; - -static int ym2651y_probe(struct i2c_client *client, - const struct i2c_device_id *dev_id) -{ - struct ym2651y_data *data; - int status; - - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_BYTE_DATA | - I2C_FUNC_SMBUS_WORD_DATA | - I2C_FUNC_SMBUS_I2C_BLOCK)) { - status = -EIO; - goto exit; - } - - data = kzalloc(sizeof(struct ym2651y_data), GFP_KERNEL); - if (!data) { - status = -ENOMEM; - goto exit; - } - - i2c_set_clientdata(client, data); - mutex_init(&data->update_lock); - - dev_info(&client->dev, "chip found\n"); - - /* Register sysfs hooks */ - status = sysfs_create_group(&client->dev.kobj, &ym2651y_group); - if (status) { - goto exit_free; - } - - data->hwmon_dev = hwmon_device_register(&client->dev); - if (IS_ERR(data->hwmon_dev)) { - status = PTR_ERR(data->hwmon_dev); - goto exit_remove; - } - - dev_info(&client->dev, "%s: psu '%s'\n", - dev_name(data->hwmon_dev), client->name); - - return 0; - -exit_remove: - sysfs_remove_group(&client->dev.kobj, &ym2651y_group); -exit_free: - kfree(data); -exit: - - return status; -} - -static int ym2651y_remove(struct i2c_client *client) -{ - struct ym2651y_data *data = i2c_get_clientdata(client); - - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &ym2651y_group); - kfree(data); - - return 0; -} - -static const struct i2c_device_id ym2651y_id[] = { - { "ym2651", YM2651 }, - { "ym2401", YM2401 }, - { "ym2851", YM2851 }, - {} -}; -MODULE_DEVICE_TABLE(i2c, ym2651y_id); - -static struct i2c_driver ym2651y_driver = { - .class = I2C_CLASS_HWMON, - .driver = { - .name = "ym2651", - }, - .probe = ym2651y_probe, - .remove = ym2651y_remove, - .id_table = ym2651y_id, - .address_list = normal_i2c, -}; - -static int ym2651y_read_byte(struct i2c_client *client, u8 reg) -{ - return i2c_smbus_read_byte_data(client, reg); -} - -static int ym2651y_read_word(struct i2c_client *client, u8 reg) -{ - return i2c_smbus_read_word_data(client, reg); -} - -static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value) -{ - return i2c_smbus_write_word_data(client, reg, value); -} - -static int ym2651y_read_block(struct i2c_client *client, u8 command, u8 *data, - int data_len) -{ - int result = i2c_smbus_read_i2c_block_data(client, command, data_len, data); - - if (unlikely(result < 0)) - goto abort; - if (unlikely(result != data_len)) { - result = -EIO; - goto abort; - } - - result = 0; - -abort: - return result; -} - -struct reg_data_byte { - u8 reg; - u8 *value; -}; - -struct reg_data_word { - u8 reg; - u16 *value; -}; - -static struct ym2651y_data *ym2651y_update_device(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct ym2651y_data *data = i2c_get_clientdata(client); - - mutex_lock(&data->update_lock); - - if (time_after(jiffies, data->last_updated + HZ + HZ / 2) - || !data->valid) { - int i, status; - u8 command; - u8 fan_dir[5] = {0}; - struct reg_data_byte regs_byte[] = { {0x19, &data->capability}, - {0x7d, &data->over_temp}, - {0x81, &data->fan_fault}, - {0x98, &data->pmbus_revision} - }; - struct reg_data_word regs_word[] = { {0x79, &data->status_word}, - {0x8b, &data->v_out}, - {0x8c, &data->i_out}, - {0x96, &data->p_out}, - {0x8d, &data->temp}, - {0x3b, &(data->fan_duty_cycle[0])}, - {0x3c, &(data->fan_duty_cycle[1])}, - {0x90, &data->fan_speed}, - {0xa0, &data->mfr_vin_min}, - {0xa1, &data->mfr_vin_max}, - {0xa2, &data->mfr_iin_max}, - {0xa3, &data->mfr_pin_max}, - {0xa4, &data->mfr_vout_min}, - {0xa5, &data->mfr_vout_max}, - {0xa6, &data->mfr_iout_max}, - {0xa7, &data->mfr_pout_max} - }; - - dev_dbg(&client->dev, "Starting ym2651 update\n"); - - /* Read byte data */ - for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { - status = ym2651y_read_byte(client, regs_byte[i].reg); - - if (status < 0) - { - dev_dbg(&client->dev, "reg %d, err %d\n", - regs_byte[i].reg, status); - *(regs_byte[i].value) = 0; - } - else { - *(regs_byte[i].value) = status; - } - } - - /* Read word data */ - for (i = 0; i < ARRAY_SIZE(regs_word); i++) { - status = ym2651y_read_word(client, regs_word[i].reg); - - if (status < 0) - { - dev_dbg(&client->dev, "reg %d, err %d\n", - regs_word[i].reg, status); - *(regs_word[i].value) = 0; - } - else { - *(regs_word[i].value) = status; - } - } - - /* Read fan_direction */ - command = 0xC3; - status = ym2651y_read_block(client, command, fan_dir, ARRAY_SIZE(fan_dir)-1); - - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - } - - strncpy(data->fan_dir, fan_dir+1, ARRAY_SIZE(data->fan_dir)-1); - data->fan_dir[ARRAY_SIZE(data->fan_dir)-1] = '\0'; - - /* Read mfr_id */ - command = 0x99; - status = ym2651y_read_block(client, command, data->mfr_id, - ARRAY_SIZE(data->mfr_id)-1); - data->mfr_id[ARRAY_SIZE(data->mfr_id)-1] = '\0'; - - if (status < 0) - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - - /* Read mfr_model */ - command = 0x9a; - status = ym2651y_read_block(client, command, data->mfr_model, - ARRAY_SIZE(data->mfr_model)-1); - data->mfr_model[ARRAY_SIZE(data->mfr_model)-1] = '\0'; - - if (status < 0) - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - - /* Read mfr_revsion */ - command = 0x9b; - status = ym2651y_read_block(client, command, data->mfr_revsion, - ARRAY_SIZE(data->mfr_revsion)-1); - data->mfr_revsion[ARRAY_SIZE(data->mfr_revsion)-1] = '\0'; - - if (status < 0) - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - - data->last_updated = jiffies; - data->valid = 1; - } - - mutex_unlock(&data->update_lock); - - return data; -} - -module_i2c_driver(ym2651y_driver); - -MODULE_AUTHOR("Brandon Chuang "); -MODULE_DESCRIPTION("3Y Power YM-2651Y driver"); -MODULE_LICENSE("GPL"); - - diff --git a/platform/broadcom/sonic-platform-modules-juniper/debian/control b/platform/broadcom/sonic-platform-modules-juniper/debian/control index c9310069f9f9..9c3d12685a47 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/debian/control +++ b/platform/broadcom/sonic-platform-modules-juniper/debian/control @@ -9,3 +9,6 @@ Package: sonic-platform-juniper-qfx5210 Architecture: amd64 Description: kernel modules for platform devices such as fan, led, sfp +Package: sonic-platform-juniper-qfx5200 +Architecture: amd64 +Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-juniper/debian/rules b/platform/broadcom/sonic-platform-modules-juniper/debian/rules index 2be5594acd3d..1a781912a544 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/debian/rules +++ b/platform/broadcom/sonic-platform-modules-juniper/debian/rules @@ -19,11 +19,10 @@ PACKAGE_PRE_NAME := sonic-platform-juniper KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= qfx5210 +MODULE_DIRS:= qfx5210 qfx5200 MODULE_DIR := modules UTILS_DIR := utils SERVICE_DIR := service -PLATFORM_DIR := sonic_platform CONF_DIR := conf %: @@ -38,7 +37,7 @@ build: #make modules -C $(KERNEL_SRC)/build M=$(MODULE_SRC) (for mod in $(MODULE_DIRS); do \ make modules -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules || exit 1; \ - $(PYTHON) $${mod}/setup.py build; \ + $(PYTHON) setup.py build; \ done) binary: binary-arch binary-indep @@ -65,7 +64,7 @@ binary-indep: cp $(MOD_SRC_DIR)/$${mod}/$(MODULE_DIR)/*.ko debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/* debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin/; \ cp $(MOD_SRC_DIR)/$${mod}/$(SERVICE_DIR)/*.service debian/$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system/; \ - $(PYTHON) $${mod}/setup.py install --root=$(MOD_SRC_DIR)/debian/$(PACKAGE_PRE_NAME)-$${mod} --install-layout=deb; \ + $(PYTHON) setup.py install --root=$(MOD_SRC_DIR)/debian/$(PACKAGE_PRE_NAME)-$${mod} --install-layout=deb; \ done) # Resuming debhelper scripts dh_testroot diff --git a/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5200.install b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5200.install new file mode 100644 index 000000000000..a726447549d9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5200.install @@ -0,0 +1,8 @@ +qfx5200/utils/juniper_qfx5200_util.py usr/local/bin +qfx5200/utils/juniper_qfx5200_monitor.py usr/local/bin +qfx5200/utils/show_thresholds usr/local/bin +qfx5200/utils/temperature_thresholds_AFI.txt usr/local/bin +qfx5200/utils/temperature_thresholds_AFO.txt usr/local/bin +qfx5200/service/qfx5200-platform-init.service etc/systemd/system +qfx5200/utils/wrapper-warm-reboot usr/local/bin +qfx5200/utils/wrapper-fast-reboot usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5200.postinst b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5200.postinst new file mode 100644 index 000000000000..bdcf70e2beaf --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5200.postinst @@ -0,0 +1,37 @@ +#!/bin/bash + +systemctl enable qfx5200-platform-init.service +systemctl start qfx5200-platform-init.service + +# There are primary and secondary bios in qfx5200 platform. +# There is a problem with bios which prevents the OS booting from the +# secondary bios when the OS was installed using primary bios. +# Secondary bios fails to detect the UEFI partition. Right now +# the workaround is to have a folder structure /EFI/BOOT/BOOT64x.efi + +SONIC_VERSION=$(sonic-cfggen -y /etc/sonic/sonic_version.yml -v build_version) +FIRST_BOOT_FILE="/host/image-${SONIC_VERSION}/platform/firsttime" + +if [ -f $FIRST_BOOT_FILE ]; then + mkdir /tmp/sda1 + mount /dev/sda1 /tmp/sda1 + cd /tmp/sda1/EFI + mkdir BOOT > /dev/null 2>&1 + cp SONiC-OS/grubx64.efi BOOT/BOOTX64.EFI + cd /tmp + umount sda1 + # This code block ensures that no additional entries + # are added. This is applicable during SONiC image + # upgrades. + entries=`efibootmgr -v | grep "BOOTX64"` + if [ -z "$entries" ]; then + # Creating the UEFI entry for the first time. + efibootmgr -c -L "SONiC" -l "\EFI\BOOT\BOOTX64.EFI" > /var/tmp/efi_log 2>&1 + fi + mkdir /usr/bin/qfx5200-warm-reboot + mkdir /usr/bin/qfx5200-fast-reboot + cp /usr/bin/warm-reboot /usr/bin/qfx5200-warm-reboot + cp /usr/bin/fast-reboot /usr/bin/qfx5200-fast-reboot + cp /usr/local/bin/wrapper-warm-reboot /usr/bin/warm-reboot + cp /usr/local/bin/wrapper-fast-reboot /usr/bin/fast-reboot +fi diff --git a/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.install b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.install index db8c036fdd0d..9444aae8b7c2 100644 --- a/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.install +++ b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.install @@ -2,3 +2,5 @@ qfx5210/utils/juniper_qfx5210_util.py usr/local/bin qfx5210/utils/juniper_qfx5210_monitor.py usr/local/bin qfx5210/utils/platform_poweroff usr/local/bin qfx5210/service/qfx5210-platform-init.service etc/systemd/system +qfx5210/utils/wrapper-warm-reboot usr/local/bin +qfx5210/utils/wrapper-fast-reboot usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.postinst b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.postinst index 97b66fb44e4c..e4a9d353ef5d 100644 --- a/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.postinst +++ b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.postinst @@ -28,4 +28,10 @@ if [ -f $FIRST_BOOT_FILE ]; then # Creating the UEFI entry for the first time. efibootmgr -c -L "SONiC" -l "\EFI\BOOT\BOOTX64.EFI" > /var/tmp/efi_log 2>&1 fi + mkdir /usr/bin/qfx5210-warm-reboot + mkdir /usr/bin/qfx5210-fast-reboot + cp /usr/bin/warm-reboot /usr/bin/qfx5210-warm-reboot + cp /usr/bin/fast-reboot /usr/bin/qfx5210-fast-reboot + cp /usr/local/bin/wrapper-warm-reboot /usr/bin/warm-reboot + cp /usr/local/bin/wrapper-fast-reboot /usr/bin/fast-reboot fi diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/Makefile b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/Makefile new file mode 100644 index 000000000000..2b9cc2c22f71 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/Makefile @@ -0,0 +1 @@ +obj-m:=jnx-tmc-core.o i2c-tmc.o jnx-refpga-tmc.o leds-jnx-tmc.o gpio-tmc.o jnx-tmc-psu.o jnx-psu-monitor.o jnx-refpga-lpcm.o diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/gpio-tmc.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/gpio-tmc.c new file mode 120000 index 000000000000..257a13181ee9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/gpio-tmc.c @@ -0,0 +1 @@ +../../common/modules/gpio-tmc.c \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/i2c-tmc.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/i2c-tmc.c new file mode 120000 index 000000000000..6fc8e5f3b47b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/i2c-tmc.c @@ -0,0 +1 @@ +../../common/modules/i2c-tmc.c \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-psu-monitor.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-psu-monitor.c new file mode 100644 index 000000000000..e1604d3d0d51 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-psu-monitor.c @@ -0,0 +1,325 @@ +/* + * A hwmon PSU monitoring driver for Juniper QFX5200 platform + * + * Copyright (C) 2020 Juniper Networks. + * Ciju Rajan K + * + * Based on ym2651.c by Brandon Chuang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TEMP_INT_MASK (0xFFC0) +#define V_IN_INT_MASK (0xFFE0) +#define V_OUT_INT_MASK (0xFF00) +#define INVALID_READING (0xFFFF) +#define TEMP_FR_LEN 6 +#define V_IN_FR_LEN 5 +#define V_OUT_FR_LEN 8 + +static const unsigned short normal_i2c[] = { 0x58, 0x58, I2C_CLIENT_END }; + +struct psu_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u16 v_out; + u16 i_out; + u16 v_in; + u16 i_in; + u16 temp1_input; + u16 temp2_input; + u16 temp3_input; + u16 temp4_input; + u16 fan1_input; + u16 fan2_input; +}; + +static ssize_t show_word(struct device *dev, struct device_attribute *da, + char *buf); + +static struct psu_data *psu_update_device(struct device *dev); + +enum psu_sysfs_attributes { + PSU_V_OUT, + PSU_I_OUT, + PSU_V_IN, + PSU_I_IN, + PSU_TEMP1_INPUT, + PSU_TEMP2_INPUT, + PSU_TEMP3_INPUT, + PSU_TEMP4_INPUT, + PSU_FAN1_RPM, + PSU_FAN2_RPM, +}; + +/* + * sysfs attributes for hwmon + */ +static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_word, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, show_word, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(psu_v_in, S_IRUGO, show_word, NULL, PSU_V_IN); +static SENSOR_DEVICE_ATTR(psu_i_in, S_IRUGO, show_word, NULL, PSU_I_IN); +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_word, NULL, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_word, NULL, PSU_TEMP2_INPUT); +static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_word, NULL, PSU_TEMP3_INPUT); +static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_word, NULL, PSU_TEMP4_INPUT); +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_word, NULL, PSU_FAN1_RPM); +static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_word, NULL, PSU_FAN2_RPM); + +static struct attribute *psu_attributes[] = { + &sensor_dev_attr_in3_input.dev_attr.attr, + &sensor_dev_attr_curr2_input.dev_attr.attr, + &sensor_dev_attr_psu_v_in.dev_attr.attr, + &sensor_dev_attr_psu_i_in.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp4_input.dev_attr.attr, + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan2_input.dev_attr.attr, + NULL +}; + +static short convert_to_decimal(u16 value, + u16 data_mask, + u8 fr_len) +{ + return (((short)value >= 0) ? ((value & data_mask) >> fr_len) : + (-((((~(value & data_mask)) >> fr_len) + 1)))); +} + +static ssize_t show_word(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct psu_data *data = psu_update_device(dev); + u32 value = 0x0000; + + switch (attr->index) { + case PSU_V_OUT: + value = 1000 * convert_to_decimal(data->v_out, + V_OUT_INT_MASK, + V_OUT_FR_LEN); + break; + case PSU_V_IN: + value = convert_to_decimal(data->v_in, + V_IN_INT_MASK, + V_IN_FR_LEN); + break; + case PSU_I_IN: + value = data->i_in; + break; + case PSU_I_OUT: + value = 1000 * data->i_out / 64; + break; + case PSU_FAN1_RPM: + value = data->fan1_input; + break; + case PSU_FAN2_RPM: + value = data->fan2_input; + break; + case PSU_TEMP1_INPUT: + value = 1000 * convert_to_decimal(data->temp1_input, + TEMP_INT_MASK, + TEMP_FR_LEN); + break; + case PSU_TEMP2_INPUT: + value = 1000 * convert_to_decimal(data->temp2_input, + TEMP_INT_MASK, + TEMP_FR_LEN); + break; + case PSU_TEMP3_INPUT: + value = 1000 * convert_to_decimal(data->temp3_input, + TEMP_INT_MASK, + TEMP_FR_LEN); + break; + case PSU_TEMP4_INPUT: + value = 1000 * convert_to_decimal(data->temp4_input, + TEMP_INT_MASK, + TEMP_FR_LEN); + break; + } + + return sprintf(buf, "%d\n", (int)value); +} + +static const struct attribute_group jnx_psu_group = { + .attrs = psu_attributes, +}; + +static int jnx_psu_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct psu_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA | + I2C_FUNC_SMBUS_I2C_BLOCK)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct psu_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + dev_dbg(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &jnx_psu_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &jnx_psu_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int jnx_psu_remove(struct i2c_client *client) +{ + struct psu_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &jnx_psu_group); + kfree(data); + + return 0; +} + +enum { + JPSU, +}; + +static const struct i2c_device_id psu_id[] = { + { "jpsu", JPSU }, + {} +}; +MODULE_DEVICE_TABLE(i2c, psu_id); + + +static struct i2c_driver jnx_psu_monitor_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "jnx-psu-monitor", + }, + .probe = jnx_psu_probe, + .remove = jnx_psu_remove, + .id_table = psu_id, + .address_list = normal_i2c, +}; + + +static int psu_read_word(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_word_data(client, reg); +} + +struct reg_data_word { + u8 reg; + u16 *value; +}; + +static struct psu_data *psu_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct psu_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int i, status; + struct reg_data_word regs_word[] = { + {0x00, &data->temp1_input}, + {0x01, &data->temp2_input}, + {0x02, &data->temp3_input}, + {0x03, &data->temp4_input}, + {0x28, &data->v_out}, + {0x32, &data->v_in}, + {0x33, &data->i_out}, + {0x3D, &data->i_in}, + {0x20, &data->fan1_input}, + {0x21, &data->fan2_input} + }; + + dev_dbg(dev, "Starting psu monitoring update\n"); + + /* Read word data */ + for (i = 0; i < ARRAY_SIZE(regs_word); i++) { + status = 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; + } + else { + u16 value = (u16)status; + (INVALID_READING != value) ? (*(regs_word[i].value) = status) : + (*(regs_word[i].value) = 0); + } + } + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +module_i2c_driver(jnx_psu_monitor_driver); + +MODULE_AUTHOR("Ciju Rajan K "); +MODULE_DESCRIPTION("Juniper PSU monitoring driver for QFX5200"); +MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-refpga-lpcm.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-refpga-lpcm.c new file mode 100644 index 000000000000..e305b1c3219c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-refpga-lpcm.c @@ -0,0 +1,118 @@ +/* + * Juniper Networks Re-Fpga lpc module + * + * Copyright (C) 2020 Juniper Networks + * Author: Ciju Rajan K + * + * This module implements: + * - Registering Reboot handler to reset cpu + * - Reset management port + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define REFPGA_LPC_BASE_ADDRESS 0xFED50000 +#define REFPGA_LPC_WINDOW_SIZE 0x00000400 + +#define REFPGA_MRE_LPCM_RST_CTL_REG (0x3) +#define REFPGA_MAJOR_VERSION (0x0) +#define REFPGA_MINOR_VERSION (0x1) + +#define REFPGA_CPU_RESET BIT(0) +#define REFPGA_MGMT1_PHY_RESET BIT(1) + +static void __iomem *fpga = NULL; + +static int qfx5200_cpu_reset(struct notifier_block *nb, + unsigned long action, + void *data) +{ + int ret = 0; + + switch (action) { + case SYS_POWER_OFF: + case SYS_HALT: + printk(KERN_CRIT "System halt/power_off\n"); + break; + case SYS_RESTART: + printk(KERN_CRIT "System restart: qfx5200_cpu_reset\n"); + iowrite8(REFPGA_CPU_RESET, (u8 *)fpga + REFPGA_MRE_LPCM_RST_CTL_REG); + msleep(100); + break; + default: + /* Do Nothing */ + break; + } + return NOTIFY_DONE; +} + +static struct notifier_block qfx5200_nb = { + .notifier_call = qfx5200_cpu_reset, +}; + +static int __init refpga_lpcm_init(void) +{ + u8 major_version = 0x00; + u8 minor_version = 0x00; + + if (!request_mem_region(REFPGA_LPC_BASE_ADDRESS, REFPGA_LPC_WINDOW_SIZE, "refpga-lpc")) { + printk(KERN_ERR "Cannot allocate Re-fpga memory region\n"); + return -ENODEV; + } + + if ((fpga = ioremap(REFPGA_LPC_BASE_ADDRESS, REFPGA_LPC_WINDOW_SIZE)) == NULL) { + release_mem_region(REFPGA_LPC_BASE_ADDRESS, REFPGA_LPC_WINDOW_SIZE); + printk(KERN_ERR "Re-Fpga address mapping failed\n"); + return -1; + } + + major_version = ioread8((u8 *)fpga + REFPGA_MAJOR_VERSION); + minor_version = ioread8((u8 *)fpga + REFPGA_MINOR_VERSION); + printk(KERN_INFO "Re-Fpga major version: %x minor version: %x\n", major_version, minor_version); + + /* + * Register the cpld soft reset handler + */ + if(register_reboot_notifier(&qfx5200_nb)) { + printk(KERN_ALERT "Restart handler registration failed\n"); + } + + iowrite8(REFPGA_MGMT1_PHY_RESET, (u8 *)fpga + REFPGA_MRE_LPCM_RST_CTL_REG); + + return 0; + +} + +static void __exit refpga_lpcm_exit(void) +{ + /* + * Unregister the fpga soft reset handler + */ + if (unregister_reboot_notifier(&qfx5200_nb)) { + printk(KERN_CRIT "Failed to uregister reboot notifier\n"); + return; + } + iounmap(fpga); + release_mem_region(REFPGA_LPC_BASE_ADDRESS, REFPGA_LPC_WINDOW_SIZE); + printk(KERN_INFO "Re-Fpga lpcm module removed\n"); +} + +module_init(refpga_lpcm_init); +module_exit(refpga_lpcm_exit); + +MODULE_DESCRIPTION("Juniper Networks RE-FPGA lpc module"); +MODULE_AUTHOR("Ciju Rajan K "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-refpga-tmc.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-refpga-tmc.c new file mode 120000 index 000000000000..355eda2afdf7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-refpga-tmc.c @@ -0,0 +1 @@ +../../common/modules/jnx-refpga-tmc.c \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc-core.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc-core.c new file mode 120000 index 000000000000..623e7a0188c6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc-core.c @@ -0,0 +1 @@ +../../common/modules/jnx-tmc-core.c \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc-psu.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc-psu.c new file mode 100644 index 000000000000..86eeb6f88e45 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc-psu.c @@ -0,0 +1,173 @@ +/* + * Juniper Networks TMC fpga PSU driver + * + * This driver is for detecting if the PSU is present or not + * + * Copyright (C) 2020 Juniper Networks + * Author: Ciju Rajan K + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Max PSUs supported by this driver */ +#define NUM_PSU 2 + +struct tmc_psu_data { + int num_psu; + void __iomem *tmc_membase; +}; + +enum sysfs_psu_attributes { + PSU0_PRESENT, + PSU1_PRESENT, +}; + +static bool get_psu_presense(void *addr, u8 idx) +{ + bool ret = 0; + u32 value = ~(-1); + + value = ioread32(addr); + /* + * BIT(6) is for PSU 0 + * BIT(7) is for PSU 1 + * idx will be either 0 (PSU0) or 1 (PSU1) + */ + value &= BIT(idx+6); + + if (value) + ret = 1; + + return ret; +} + +/* + * Sysfs files are present in this path + * /sys/devices/pci0000:00/0000:00:1c.0/0000:0f:00.0/psu-tmc.15/psu*_present + */ + +#define DECLARE_PSU_PRESENT_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(psu##index##_present, S_IRUGO, tmc_psu_presense_show, NULL, PSU##index##_PRESENT) +#define DECLARE_PSU_PRESENT_ATTR(index) &sensor_dev_attr_psu##index##_present.dev_attr.attr + +static ssize_t tmc_psu_presense_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct sensor_device_attribute *s_attr = to_sensor_dev_attr(attr); + struct platform_device *pdev = to_platform_device(dev); + struct tmc_psu_data *psu = platform_get_drvdata(pdev); + + return sprintf(buf, "%d\n", get_psu_presense(psu->tmc_membase, s_attr->index)); + +} + +DECLARE_PSU_PRESENT_SENSOR_DEV_ATTR(0); +DECLARE_PSU_PRESENT_SENSOR_DEV_ATTR(1); + +static struct attribute *tmc_psu_attrs[] = { + DECLARE_PSU_PRESENT_ATTR(0), + DECLARE_PSU_PRESENT_ATTR(1), + NULL +}; + +static struct attribute_group tmc_psu_attr_group = { + .attrs = tmc_psu_attrs, +}; + +static int tmc_psu_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct tmc_psu_data *psu; + int ret; + struct resource *res; + void __iomem *addr; + + psu = devm_kzalloc(dev, sizeof(*psu), GFP_KERNEL); + if (!psu) { + dev_err(dev, "psu structure allocation failed\n"); + return -ENOMEM; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "res allocation failed\n"); + return -ENODEV; + } + + addr = devm_ioremap_nocache(dev, res->start, resource_size(res)); + if (!addr) { + dev_err(dev, "ioremap failed\n"); + return -ENOMEM; + } + + psu->tmc_membase = addr; + psu->num_psu = NUM_PSU; + + platform_set_drvdata(pdev, psu); + + ret = sysfs_create_group(&dev->kobj, &tmc_psu_attr_group); + if (ret != 0) { + dev_err(dev, "jnx-tmc-psu: sysfs_create_group failed: %d\n", ret); + return ret; + } + + return 0; +} + +static int tmc_psu_remove(struct platform_device *pdev) +{ + struct tmc_psu_data *psu = platform_get_drvdata(pdev); + + if (psu) { + devm_kfree(&pdev->dev, psu); + } + sysfs_remove_group(&pdev->dev.kobj, &tmc_psu_attr_group); + + return 0; +} + +static struct platform_driver jnx_tmc_psu_driver = { + .driver = { + .name = "psu-tmc", + .owner = THIS_MODULE, + }, + .probe = tmc_psu_probe, + .remove = tmc_psu_remove, +}; + +static int __init jnx_tmc_psu_driver_init(void) +{ + int ret = -1; + + ret = platform_driver_register(&jnx_tmc_psu_driver); + + return ret; + +} + +static void __exit jnx_tmc_psu_driver_exit(void) +{ + platform_driver_unregister(&jnx_tmc_psu_driver); +} + +module_init(jnx_tmc_psu_driver_init); +module_exit(jnx_tmc_psu_driver_exit); + +MODULE_DESCRIPTION("Juniper Networks TMC PSU driver"); +MODULE_AUTHOR("Ciju Rajan K "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc.h b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc.h new file mode 120000 index 000000000000..bfacb7ae018d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-tmc.h @@ -0,0 +1 @@ +../../common/modules/jnx-tmc.h \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/leds-jnx-tmc.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/leds-jnx-tmc.c new file mode 100644 index 000000000000..134faefd70a3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/leds-jnx-tmc.c @@ -0,0 +1,223 @@ +/* + * Juniper Networks TMC fpga LEDs driver + * + * Copyright (C) 2018 Juniper Networks + * Author: Ciju Rajan K + * + * This driver is based on I2CS fpga LEDs driver by Georgi Vlaev + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include + +/* Max LEDs supported by this driver (2bits of control per LED in 32bit reg) */ +#define NUM_LEDS 3 + +struct tmc_led { + struct led_classdev lc; + struct work_struct work; + int on; + int bit; + void __iomem *addr; +}; + +struct tmc_led_data { + int num_leds; + struct tmc_led *leds; +}; + +struct led_table +{ + const char *name; + int reg; +}; + +static struct led_table qfx5200_tmc_led_data[] = { + { + .name = "system", + .reg = 0, + }, + { + .name = "beacon", + .reg = 3, + }, + { + .name = "master", + .reg = 5, + } +}; + +static void jnx_tmc_leds_work(struct work_struct *work) +{ + struct tmc_led *led = container_of(work, struct tmc_led, work); + u32 value = ~(-1); + + value = ioread32(led->addr); + + if (led->on) { + if (!strncmp(led->lc.name, "beacon", 6)) { + value &= ~BIT(led->bit + 1); + value |= BIT(led->bit); + } else { + value |= BIT(led->bit) | BIT(led->bit + 1); + } + } else { + value &= ~(BIT(led->bit) | BIT(led->bit + 1)); + } + + iowrite32(value, led->addr); +} + +static void jnx_tmc_leds_brightness_set(struct led_classdev *lc, + enum led_brightness brightness) +{ + struct tmc_led *led = container_of(lc, struct tmc_led, lc); + + led->on = (brightness != LED_OFF); + schedule_work(&led->work); +} + +static int jnx_tmc_leds_init_one(struct device *dev, + struct tmc_led_data *ild, + int num, void __iomem *addr) +{ + struct tmc_led *led; + int ret; + + led = &ild->leds[num]; + + led->addr = addr; + + led->lc.name = qfx5200_tmc_led_data[num].name; + led->bit = qfx5200_tmc_led_data[num].reg; + led->lc.brightness_set = jnx_tmc_leds_brightness_set; + + + ret = devm_led_classdev_register(dev, &led->lc); + if (ret) + return ret; + + INIT_WORK(&led->work, jnx_tmc_leds_work); + + return 0; +} + +static int jnx_tmc_leds_init(struct device *dev, struct tmc_led_data *ild, + struct resource *res) +{ + int ret, idx = 0; + void __iomem *addr; + + if (!dev->parent) { + dev_err(dev, "dev->parent is null\n"); + return -ENODEV; + } + + addr = devm_ioremap_nocache(dev, res->start, resource_size(res)); + if (!addr) { + dev_err(dev, "ioremap failed\n"); + return -ENOMEM; + } + + ild->num_leds = NUM_LEDS; + ild->leds = devm_kzalloc(dev, sizeof(struct tmc_led) * NUM_LEDS, + GFP_KERNEL); + if (!ild->leds) { + dev_err(dev, "LED allocation failed\n"); + return -ENOMEM; + } + + for (idx=0; idxdev; + struct tmc_led_data *ild; + int ret; + struct resource *res; + + ild = devm_kzalloc(dev, sizeof(*ild), GFP_KERNEL); + if (!ild) { + dev_err(dev, "ild allocation failed\n"); + return -ENOMEM; + } + + platform_set_drvdata(pdev, ild); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "res allocation failed\n"); + return -ENODEV; + } + + ret = jnx_tmc_leds_init(dev, ild, res); + if (ret < 0) + return ret; + + return 0; +} + +static int tmc_leds_remove(struct platform_device *pdev) +{ + struct tmc_led_data *ild = platform_get_drvdata(pdev); + int i; + + for (i = 0; i < ild->num_leds; i++) { + devm_led_classdev_unregister(&pdev->dev, &ild->leds[i].lc); + cancel_work_sync(&ild->leds[i].work); + } + + if (ild) { + if (ild->leds) + devm_kfree(&pdev->dev, ild->leds); + devm_kfree(&pdev->dev, ild); + } + + return 0; +} + +static struct platform_driver jnx_tmc_leds_driver = { + .driver = { + .name = "leds-tmc", + .owner = THIS_MODULE, + }, + .probe = tmc_leds_probe, + .remove = tmc_leds_remove, +}; + +static int __init jnx_tmc_leds_driver_init(void) +{ + int ret = -1; + + ret = platform_driver_register(&jnx_tmc_leds_driver); + + return ret; + +} + +static void __exit jnx_tmc_leds_driver_exit(void) +{ + platform_driver_unregister(&jnx_tmc_leds_driver); +} + +module_init(jnx_tmc_leds_driver_init); +module_exit(jnx_tmc_leds_driver_exit); + +MODULE_DESCRIPTION("Juniper Networks TMC leds driver"); +MODULE_AUTHOR("Ciju Rajan K "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/service/qfx5200-platform-init.service b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/service/qfx5200-platform-init.service new file mode 100644 index 000000000000..550a9eda3464 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/service/qfx5200-platform-init.service @@ -0,0 +1,15 @@ +[Unit] +Description=Juniper QFX5200 initialization service +Before=pmon.service +After=sysinit.target +DefaultDependencies=no + +[Service] +ExecStartPre=/usr/local/bin/juniper_qfx5200_util.py install +ExecStart=/usr/local/bin/juniper_qfx5200_monitor.py +RemainAfterExit=yes +StandardOutput=syslog+console +StandardError=syslog+console + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/README b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/README new file mode 100755 index 000000000000..558410def831 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/README @@ -0,0 +1,152 @@ + +Copyright (c) 2020, Juniper Networks, Inc. +All rights reserved. + +Front panel LEDs +================ +There are 4 system LEDs in the front panel. Master, System, Alarm, & Beacon. +LED controls can be found under /sys/class/leds. The sysfs interface & +colour mappings are as follows: + +For master LED: /sys/class/leds/master/brightness + 0 => off + 1 => green + +For system LED: /sys/class/leds/system/brightness + 0 => off + 1 => green + +For alarm LED: /sys/class/leds/alarm/brightness + 0 => off + 1 => amber + 2 => red + +For beacon LED: /sys/class/leds/beacon/brightness + 0 => off + 1 => blue + +For any of the above LEDs, max_brightness file can tell the maximum value +accepted. + +System FANs +=========== +There are 5 fans and each of the fan has 2 fan modules. Overall there are +10 fans in the system. These fans are controlled by ADT7470 driver. + +Fan controls can be found in + /sys/bus/i2c/devices/7-002c + /sys/bus/i2c/devices/7-002e + /sys/bus/i2c/devices/7-002f + +For example, the complete path to driver control files will be + /sys/bus/i2c/devices/7-002c/hwmon/hwmon12 + +Fan duty cycle can be controlled through 'pwm1', 'pwm2', 'pwm3', 'pwm4' sysfs files. + +For example, these are the absolute paths to the control files + + /sys/bus/i2c/devices/7-002c/hwmon/hwmon*/pwm1 7-002c controls 2 fan modules + /sys/bus/i2c/devices/7-002c/hwmon/hwmon*/pwm2 + /sys/bus/i2c/devices/7-002c/hwmon/hwmon*/pwm3 + /sys/bus/i2c/devices/7-002c/hwmon/hwmon*/pwm4 + + /sys/bus/i2c/devices/7-002e/hwmon/hwmon*/pwm1 7-002e controls 2 fan modules + /sys/bus/i2c/devices/7-002e/hwmon/hwmon*/pwm2 + /sys/bus/i2c/devices/7-002e/hwmon/hwmon*/pwm3 + /sys/bus/i2c/devices/7-002e/hwmon/hwmon*/pwm4 + + /sys/bus/i2c/devices/7-002f/hwmon/hwmon*/pwm1 7-002c controls only 1 fan module + /sys/bus/i2c/devices/7-002f/hwmon/hwmon*/pwm2 + +For convenience, it will be represented as +/sys/bus/i2c/devices/7-002[c/e/f]/hwmon/hwmon*/pwm[1-4] + +Fan speed is given by +/sys/bus/i2c/devices/7-002[c/e/f]/hwmon/hwmon*/fan[1-4]_input + +Fan module presence is given by +/sys/devices/pci0000:00/0000:00:1c.0/0000:0f:00.0/refpga-tmc.15/fan[0-4]_present +file. A value of '1' indicate that fan is present & a value of '0' otherwise. + +Fan rotation direction is given by +/sys/devices/pci0000:00/0000:00:1c.0/0000:0f:00.0/refpga-tmc.15/fan[0-4]_type +A value of '1' indicate the direction is AFO (Front to back airflow) or Airflow +out. A value of '0' indicate that direction is AFI (Back to front airflow) or +Airflow in. + + +Temperature sensors +=================== +There are 10 temperature sensors. Kernel driver tmp401 is used for +reading temeperature sensors. + +The readings are available in + +/sys/bus/i2c/devices/5-0048/hwmon/hwmon*/temp1_input +/sys/bus/i2c/devices/5-0049/hwmon/hwmon*/temp1_input +/sys/bus/i2c/devices/5-004a/hwmon/hwmon*/temp1_input +/sys/bus/i2c/devices/5-004b/hwmon/hwmon*/temp1_input + +/sys/bus/i2c/devices/6-0048/hwmon/hwmon*/temp1_input +/sys/bus/i2c/devices/6-0049/hwmon/hwmon*/temp1_input +/sys/bus/i2c/devices/6-004a/hwmon/hwmon*/temp1_input +/sys/bus/i2c/devices/6-004b/hwmon/hwmon*/temp1_input + +/sys/bus/i2c/devices/7-0048/hwmon/hwmon*/temp1_input +/sys/bus/i2c/devices/7-0049/hwmon/hwmon*/temp1_input + +System PSUs +=========== +There are two independent PSUs. These are controlled by TMC fpga. + +PSU presence is given by jnx-tmc-psu dirver and is available at +/sys/devices/pci0000:00/0000:00:1c.0/0000:0f:00.0/psu-tmc.15/psu*_present +A value of '1' indicate PSU is present and a value of '0' otherwise. + +PSU monitoring data is provided by jnx-psu-monitor driver and is available at +/sys/bus/i2c/devices/3-0058 +/sys/bus/i2c/devices/4-0058 + +SFPs +==== +There are 32 QSFP+ modules supported in qfx5200 platform. EEPORMs will be +mapped under /sys/bus/i2c/devices/[14-45]-0050/ sysfs directory. + +FEC should be turned on for 100G SR4 & PSM4 optics and should +be turned off for 100G LR4 optics. If the FEC mode is not set +as per the optic type the port may not link up or work properly. +In some cases while interoperating between other NOSs & traffic +generators, FEC need to be enabled even for 100G DAC cables. + +As an example, see this configuration for FEC for 100G SR4 optics in +/etc/sonic/config_db.json + +"Ethernet4": { + "admin_status": "up", + "alias": "Ethernet4", + "fec": "rs", + "index": "1", + "lanes": "65,66,67,68", + "mtu": "9100", + "speed": "100000" + } + +Sensor details +============== +LM75 supported sensor modules will be available under 'sensors' command. + +Platform reboot +================= +Platform reboot sequences are in place for system reboot. The following +messages are displayed in the console when the system is rebooted: + + [ 6053.163363] System restart: qfx5200_cpu_reset + +Platform monitoring daemon +========================== +“juniper_qfx5200_monitor.py†is the platform monitoring script. +It implements the qfx5200 EM policy. This script will run as system service +and monitor the temperature sensors in every 20 seconds. Based on the EM +policy thresholds, it controls the fan rpm, manage alarm leds, and +shutdown the box in case of any over heating. + diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/juniper_qfx5200_monitor.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/juniper_qfx5200_monitor.py new file mode 100755 index 000000000000..dc47f1049322 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/juniper_qfx5200_monitor.py @@ -0,0 +1,913 @@ +#!/usr/bin/env python +# +# Name: juniper_qfx5200_monitor.py version: 1.0 +# +# Description: This file contains the EM implementation for QFX5200 platform +# +# Copyright (c) 2020, Juniper Networks, Inc. +# All rights reserved. +# +# Notice and Disclaimer: This code is licensed to you under the GNU General +# Public License as published by the Free Software Foundation, version 3 or +# any later version. This code is not an official Juniper product. You can +# obtain a copy of the License at +# +# OSS License: +# +# This program is free software: you can 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 . +# +# Third-Party Code: This code may depend on other components under separate +# copyright notice and license terms. Your use of the source code for those +# components is subject to the terms and conditions of the respective license +# as noted in the Third-Party source code file. + +try: + import os + import commands + import subprocess + import logging + import logging.config + import logging.handlers + import time + import glob + import re +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + +# Deafults +VERSION = '1.0' +FUNCTION_NAME = '/var/log/juniper_qfx5200_monitor' +verbose = False +DEBUG = False + +log_file = '%s.log' % FUNCTION_NAME +log_level = logging.DEBUG + + +isPlatformAFI = False +PrevASICValue = 0 + +temp_policy_AFI = { + 0: [[35, 0, 30000], [35, 30000, 39000], [55, 39000, 0], [55, 39000, 48000], [75, 48000, 0], [75, 48000, 56000], [90, 56000, 0], [90, 56000, 66000],[100, 66000, 0], + ['Yellow Alarm', 64000, 70000], ['Red Alarm', 70000, 73000], ['Fire Shut Alarm', 73000, 0]], + + 1: [[35, 0, 30000], [35, 30000, 39000], [55, 39000, 0], [55, 39000, 48000], [75, 48000, 0], [75, 48000, 56000], [90, 56000, 0], [90, 56000, 66000],[100, 66000, 0], + ['Yellow Alarm', 64000, 70000], ['Red Alarm', 70000, 73000], ['Fire Shut Alarm', 73000, 0]], + + 2: [[35, 0, 40000], [35, 40000, 47000], [55, 47000, 0], [55, 47000, 55000], [75, 55000, 0], [75, 55000, 62000], [90, 62000, 0], [90, 62000, 70000],[100, 70000, 0], + ['Yellow Alarm', 68000, 74000], ['Red Alarm', 74000, 77000], ['Fire Shut Alarm', 77000, 0]], + + 3: [[35, 0, 36000], [35, 36000, 44000], [55, 44000, 0], [55, 44000, 52000], [75, 52000, 0], [75, 52000, 60000], [90, 60000, 0], [90, 60000, 69000],[100, 69000, 0], + ['Yellow Alarm', 67000, 73000], ['Red Alarm', 73000, 76000], ['Fire Shut Alarm', 76000, 0]], + + 4: [[35, 0, 52000], [35, 52000, 57000], [55, 57000, 0], [55, 57000, 63000], [75, 63000, 0], [75, 63000, 68000], [90, 68000, 0], [90, 68000, 74000],[100, 74000, 0], + ['Yellow Alarm', 72000, 78000], ['Red Alarm', 78000, 81000], ['Fire Shut Alarm', 81000, 0]], + + 5: [[35, 0, 37000], [35, 37000, 45000], [55, 45000, 0], [55, 45000, 53000], [75, 53000, 0], [75, 53000, 61000], [90, 61000, 0], [90, 61000, 70000],[100, 70000, 0], + ['Yellow Alarm', 68000, 74000], ['Red Alarm', 74000, 77000], ['Fire Shut Alarm', 77000, 0]], + + 6: [[35, 0, 37000], [35, 37000, 45000], [55, 45000, 0], [55, 45000, 53000], [75, 53000, 0], [75, 53000, 60000], [90, 60000, 0], [90, 60000, 69000],[100, 69000, 0], + ['Yellow Alarm', 67000, 73000], ['Red Alarm', 73000, 76000], ['Fire Shut Alarm', 76000, 0]], + + 7: [[35, 0, 52000], [35, 52000, 57000], [55, 57000, 0], [55, 57000, 63000], [75, 63000, 0], [75, 63000, 68000], [90, 68000, 0], [90, 68000, 74000],[100, 74000, 0], + ['Yellow Alarm', 72000, 78000], ['Red Alarm', 78000, 81000], ['Fire Shut Alarm', 81000, 0]], + + 8: [[35, 0, 41000], [35, 41000, 48000], [55, 48000, 0], [55, 48000, 55000], [75, 55000, 0], [75, 55000, 62000], [90, 62000, 0], [90, 62000, 70000],[100, 70000, 0], + ['Yellow Alarm', 68000, 74000], ['Red Alarm', 74000, 77000], ['Fire Shut Alarm', 77000, 0]], + + 9: [[35, 0, 42000], [35, 42000, 49000], [55, 49000, 0], [55, 49000, 57000], [75, 57000, 0], [75, 57000, 64000], [90, 64000, 0], [90, 64000, 72000],[100, 72000, 0], + ['Yellow Alarm', 70000, 76000], ['Red Alarm', 76000, 79000], ['Fire Shut Alarm', 79000, 0]], + + 10: [[35, 0, 42000], [35, 42000, 50000], [55, 50000, 0], [55, 50000, 58000], [75, 58000, 0], [75, 58000, 66000], [90, 66000, 0], [90, 66000, 75000],[100, 75000, 0], + ['Yellow Alarm', 86000, 92000], ['Red Alarm', 92000, 95000], ['Fire Shut Alarm', 95000, 0]], + + 11: [[35, 0, 68000], [35, 68000, 74000], [55, 74000, 0], [55, 74000, 80000], [75, 80000, 0], [75, 80000, 85000], [90, 85000, 0], [90, 85000, 92000],[100, 92000, 0], + ['Yellow Alarm', 99000, 102000], ['Red Alarm', 102000, 105000], ['Fire Shut Alarm', 105000, 0]], + } + +temp_policy_AFO = { + 0: [[35, 0, 42000], [35, 42000, 49000], [55, 49000, 0], [55, 49000, 55000], [75, 55000, 0], [75, 55000, 62000], [90, 62000, 0], [90, 62000, 69000],[100, 69000, 0], + ['Yellow Alarm', 67000, 73000], ['Red Alarm', 73000, 76000], ['Fire Shut Alarm', 76000, 0]], + + 1: [[35, 0, 41000], [35, 41000, 48000], [55, 48000, 0], [55, 48000, 55000], [75, 55000, 0], [75, 55000, 61000], [90, 61000, 0], [90, 61000, 69000],[100, 69000, 0], + ['Yellow Alarm', 67000, 73000], ['Red Alarm', 73000, 76000], ['Fire Shut Alarm', 76000, 0]], + + 2: [[35, 0, 44000], [35, 44000, 50000], [55, 50000, 0], [55, 50000, 56000], [75, 56000, 0], [75, 56000, 63000], [90, 63000, 0], [90, 63000, 70000],[100, 70000, 0], + ['Yellow Alarm', 68000, 74000], ['Red Alarm', 74000, 77000], ['Fire Shut Alarm', 77000, 0]], + + 3: [[35, 0, 36000], [35, 36000, 43000], [55, 43000, 0], [55, 43000, 50000], [75, 50000, 0], [75, 50000, 57000], [90, 57000, 0], [90, 57000, 65000],[100, 65000, 0], + ['Yellow Alarm', 63000, 69000], ['Red Alarm', 69000, 72000], ['Fire Shut Alarm', 72000, 0]], + + 4: [[35, 0, 49000], [35, 49000, 54000], [55, 54000, 0], [55, 54000, 60000], [75, 60000, 0], [75, 60000, 65000], [90, 65000, 0], [90, 65000, 71000],[100, 71000, 0], + ['Yellow Alarm', 68000, 74000], ['Red Alarm', 74000, 77000], ['Fire Shut Alarm', 77000, 0]], + + 5: [[35, 0, 46000], [35, 46000, 52000], [55, 52000, 0], [55, 52000, 58000], [75, 58000, 0], [75, 58000, 63000], [90, 63000, 0], [90, 63000, 70000],[100, 70000, 0], + ['Yellow Alarm', 68000, 74000], ['Red Alarm', 74000, 77000], ['Fire Shut Alarm', 77000, 0]], + + 6: [[35, 0, 50000], [35, 50000, 55000], [55, 55000, 0], [55, 55000, 60000], [75, 60000, 0], [75, 60000, 65000], [90, 65000, 0], [90, 65000, 71000],[100, 71000, 0], + ['Yellow Alarm', 65000, 71000], ['Red Alarm', 71000, 78000], ['Fire Shut Alarm', 78000, 0]], + + 7: [[35, 0, 49000], [35, 49000, 55000], [55, 55000, 0], [55, 55000, 60000], [75, 60000, 0], [75, 60000, 66000], [90, 66000, 0], [90, 66000, 72000],[100, 72000, 0], + ['Yellow Alarm', 70000, 76000], ['Red Alarm', 76000, 79000], ['Fire Shut Alarm', 79000, 0]], + + 8: [[35, 0, 41000], [35, 41000, 47000], [55, 47000, 0], [55, 47000, 54000], [75, 54000, 0], [75, 54000, 60000], [90, 60000, 0], [90, 60000, 67000],[100, 67000, 0], + ['Yellow Alarm', 65000, 71000], ['Red Alarm', 71000, 74000], ['Fire Shut Alarm', 74000, 0]], + + 9: [[35, 0, 57000], [35, 57000, 61000], [55, 61000, 0], [55, 61000, 66000], [75, 66000, 0], [75, 66000, 70000], [90, 70000, 0], [90, 70000, 75000],[100, 75000, 0], + ['Yellow Alarm', 73000, 79000], ['Red Alarm', 79000, 82000], ['Fire Shut Alarm', 82000, 0]], + + 10: [[35, 0, 51000], [35, 51000, 58000], [55, 58000, 0], [55, 58000, 64000], [75, 64000, 0], [75, 64000, 70000], [90, 70000, 0], [90, 70000, 78000],[100, 78000, 0], + ['Yellow Alarm', 86000, 92000], ['Red Alarm', 92000, 95000], ['Fire Shut Alarm', 95000, 0]], + + 11: [[35, 0, 76000], [35, 76000, 79000], [55, 79000, 0], [55, 79000, 83000], [75, 83000, 0], [75, 83000, 86000], [90, 86000, 0], [90, 86000, 90000],[100, 90000, 0], + ['Yellow Alarm', 99000, 102000], ['Red Alarm', 102000, 105000], ['Fire Shut Alarm', 105000, 0]], + } + +class QFX5200_FanUtil(object): + """QFX5200 Platform FanUtil class""" + + PWMINPUT_PATH = '/sys/bus/i2c/devices/7-00{0}/hwmon/{1}/pwm{2}' + HWMONINPUT_PATH = '/sys/bus/i2c/devices/7-00{0}/hwmon/' + PWMINPUT_NUM_IDX = 0 + PWMINPUT_NUM = 10 + _pwm_input_path_mapping = {} + _hwmon_input_path_mapping = {} + + # PWM NUMBERS + _pwm_input_node_mapping = ['1','2','3','4','1','2','3','4','1','2'] + + # I2C NUMBERS + _hwmon_input_node_mapping = ['2c','2c','2c','2c','2e','2e','2e','2e','2f','2f'] + def __init__(self): + hwmoninput_path = self.HWMONINPUT_PATH + pwminput_path = self.PWMINPUT_PATH + for x in range(self.PWMINPUT_NUM): + self._hwmon_input_path_mapping[x] = hwmoninput_path.format( + self._hwmon_input_node_mapping[x]) + + hwmon_path = os.listdir(self._hwmon_input_path_mapping[x]) + hwmon_dir = '' + for hwmon_name in hwmon_path: + hwmon_dir = hwmon_name + + self._pwm_input_path_mapping[x] = pwminput_path.format( + self._hwmon_input_node_mapping[x], + hwmon_dir, + self._pwm_input_node_mapping[x]) + def get_fan_dutycycle(self): + fan_speed = {86: 35, 139: 55, 192: 75, 230: 90,255: 100} + ret_value = 0 + for x in range(self.PWMINPUT_NUM): + pwm_value = 0 + pwm_value1 = 0 + device_path = self._pwm_input_path_mapping[x] + cmd = ("sudo cat %s" %(device_path)) + status, pwm_value = commands.getstatusoutput(cmd) + pwm_value1 = int(pwm_value) + time.sleep(0.25) + if int(pwm_value1) > 0: + ret_value = fan_speed.get(int(pwm_value)) + break + + return int(ret_value) + + def set_fan_dutycycle(self, val): + fan_speed = {35: 86, 55: 139, 75: 192, 90: 230,100: 255} + for x in range(self.PWMINPUT_NUM): + device_path = self._pwm_input_path_mapping[x] + pwm_value = fan_speed.get(val) + pwm_value1 = str(pwm_value) + cmd = ("sudo echo %s > %s" %(pwm_value1,device_path)) + os.system(cmd) + time.sleep(0.25) + logging.debug('Setting PWM value: %s to all fans', pwm_value1) + return True + + def get_check_fan_dutycycle(self): + pwm_str = '' + for x in range(self.PWMINPUT_NUM): + device_path = self._pwm_input_path_mapping[x] + cmd = ("sudo cat %s" %(device_path)) + status, pwm_value = commands.getstatusoutput(cmd) + pwm_str += pwm_value + if (x != self.PWMINPUT_NUM -1): + pwm_str += ', ' + time.sleep(0.25) + logging.debug('Current PWM values set in all fans: %s', pwm_str) + + +class QFX5200_ThermalUtil(object): + """QFX5200 Platform ThermalUtil class""" + + SENSOR_NUM_ON_MAIN_BOARD = 10 + CORETEMP_INDEX_ON_MAIN_BOARD = 10 + SENSOR_CORETEMP_NUM_ON_MAIN_BOARD = 12 + CORETEMP_NUM_ON_MAIN_BOARD = 5 + THERMAL_NUM_RANGE = 10 + SENSOR_NUM_0_IDX = 0 + SENSORS_PATH = '/sys/bus/i2c/devices/{0}-00{1}/hwmon/hwmon*/temp1_input' + CORETEMP_PATH = '/sys/bus/platform/devices/coretemp.0/hwmon/hwmon*/temp{0}_input' + MAJORALARM_LED_PATH = '/sys/class/leds/alarm-major/brightness' + MINORALARM_LED_PATH = '/sys/class/leds/alarm-minor/brightness' + MONITORLOG_PATH = '/var/log/juniper_qfx5200_monitor.log' + + """ Dictionary where + key1 = thermal id index (integer) starting from 1 + value = path to fan device file (string) """ + _sensor_to_device_path_mapping = {} + + _sensor_to_device_node_mapping = [ + ['7', '48'], + ['7', '49'], + ['5', '48'], + ['5', '49'], + ['5', '4a'], + ['5', '4b'], + ['6', '48'], + ['6', '49'], + ['6', '4a'], + ['6', '4b'], + ] + + _coretemp_to_device_path_mapping = {} + + _coretemp_to_device_node_mapping = [1, 2, 3, 4, 5] + + def __init__(self): + sensor_path = self.SENSORS_PATH + coretemp_path = self.CORETEMP_PATH + for x in range(self.SENSOR_NUM_ON_MAIN_BOARD): + self._sensor_to_device_path_mapping[x] = sensor_path.format( + self._sensor_to_device_node_mapping[x][0], + self._sensor_to_device_node_mapping[x][1]) + + for x in range(self.CORETEMP_NUM_ON_MAIN_BOARD): + self._coretemp_to_device_path_mapping[x] = coretemp_path.format( + self._coretemp_to_device_node_mapping[x]) + + + """ Function reads the 5 temp inputs in CORETEMP_PATH + and returns the average of these 5 temp readings """ + def get_coretempValue(self): + sum = 0 + for x in range(self.CORETEMP_NUM_ON_MAIN_BOARD): + sum += self._get_coretemp_node_val(x) + avg = sum/self.CORETEMP_NUM_ON_MAIN_BOARD + return int(avg) + + + """ Function takes the Sensor number as input, constructs the device path, + opens sensor file, reads the temp content from the file and returns the value """ + def _get_sensor_node_val(self, thermal_num): + if thermal_num < self.SENSOR_NUM_0_IDX or thermal_num >= self.SENSOR_NUM_ON_MAIN_BOARD: + logging.debug('GET. Parameter error. thermal_num, %d', thermal_num) + return None + + device_path = self.get_thermal_to_device_path(thermal_num) + for filename in glob.glob(device_path): + try: + val_file = open(filename, 'r') + except IOError as e: + logging.error('get_sensor_node_val: unable to open file: %s', str(e)) + return None + + content = val_file.readline().rstrip() + + if content == '': + logging.debug('get_sensor_node_val: content is NULL. device_path:%s', device_path) + return None + + try: + val_file.close() + except IOError as e: + logging.error('get_sensor_node_val: unable to close file. device_path:%s', str(e)) + return None + + return int(content) + + + """ Function takes the coretemp number as input, constructs the device path, + opens sensor file, reads the temp content from the file and returns the value """ + def _get_coretemp_node_val(self, thermal_num): + + device_path = self.get_coretemp_to_device_path(thermal_num) + for filename in glob.glob(device_path): + try: + val_file = open(filename, 'r') + except IOError as e: + logging.error('get_coretemp_node_val: unable to open file: %s', str(e)) + return None + + content = val_file.readline().rstrip() + + if content == '': + logging.debug('get_coretemp_node_val: content is NULL. device_path:%s', device_path) + return None + + try: + val_file.close() + except IOError as e: + logging.error('_get_coretemp_node_val: unable to close file. device_path:%s', str(e)) + return None + + return int(content) + + + def get_thermal_to_device_path(self, thermal_num): + return self._sensor_to_device_path_mapping[thermal_num] + + + def get_coretemp_to_device_path(self, thermal_num): + return self._coretemp_to_device_path_mapping[thermal_num] + + + def get_alarm_led_brightness(self): + try: + val_file = open(self.MAJORALARM_LED_PATH) + except IOError as e: + logging.error('get_alarm_led_brightness: unable to open file: %s', str(e)) + return False + majoralarm_value = val_file.readline().rstrip() + val_file.close() + + try: + val_file = open(self.MINORALARM_LED_PATH) + except IOError as e: + logging.error('get_alarm_led_brightness: unable to open file: %s', str(e)) + return False + minoralarm_value = val_file.readline().rstrip() + val_file.close() + + if (majoralarm_value == str(1)) and (minoralarm_value == str(0)): + content = 2 + elif (majoralarm_value == str(0)) and (minoralarm_value == str(1)): + content = 1 + elif (majoralarm_value == str(0)) and (minoralarm_value == str(0)): + content = 0 + else: + pass + + return int(content) + + def set_alarm_led_brightness(self, val): + + """ Major Alarm set""" + if val == 2: + major_alarm_val = 1 + minor_alarm_val = 0 + + try: + val_file = open(self.MAJORALARM_LED_PATH, 'r+') + except IOError as e: + logging.error('set_alarm_led_brightness: unable to open file: %s', str(e)) + return False + + val_file.write(str(major_alarm_val)) + val_file.close() + + try: + val_file = open(self.MINORALARM_LED_PATH, 'r+') + except IOError as e: + logging.error('set_alarm_led_brightness: unable to open file: %s', str(e)) + return False + + val_file.write(str(minor_alarm_val)) + val_file.close() + + elif val == 1: + major_alarm_val = 0 + minor_alarm_val = 1 + + try: + val_file = open(self.MAJORALARM_LED_PATH, 'r+') + except IOError as e: + logging.error('set_alarm_led_brightness: unable to open file: %s', str(e)) + return False + + val_file.write(str(major_alarm_val)) + val_file.close() + + try: + val_file = open(self.MINORALARM_LED_PATH, 'r+') + except IOError as e: + logging.error('set_alarm_led_brightness: unable to open file: %s', str(e)) + return False + val_file.write(str(minor_alarm_val)) + val_file.close() + + else: + major_alarm_val = 0 + minor_alarm_val = 0 + + try: + val_file = open(self.MAJORALARM_LED_PATH, 'r+') + except IOError as e: + logging.error('set_alarm_led_brightness: unable to open file: %s', str(e)) + return False + + val_file.write(str(major_alarm_val)) + val_file.close() + + try: + val_file = open(self.MINORALARM_LED_PATH, 'r+') + except IOError as e: + logging.error('set_alarm_led_brightness: unable to open file: %s', str(e)) + return False + val_file.write(str(minor_alarm_val)) + val_file.close() + + """ Function is called periodically every 20 secs. It reads the 10 Temp sensors, 1 core Temp sensor and ASIC temp sets + Sensor flags accordingly. Also reads the Fan duty cycle and depending on the FAN duty cycle reading and temp sensor reading, + set the different parameters + + Below is the Sensor Mapping(Refer AFI/AFO EM Policy Specification) to the I2C devices + + /sys/bus/i2c/devices/7-0048/hwmon/hwmon* --> Sensor# 2 + /sys/bus/i2c/devices/7-0049/hwmon/hwmon* --> Sensor# 3 + /sys/bus/i2c/devices/5-0048/hwmon/hwmon* --> Sensor# 5 + /sys/bus/i2c/devices/5-0049/hwmon/hwmon* --> Sensor# 6 + /sys/bus/i2c/devices/5-004a/hwmon/hwmon* --> Sensor# 7 + /sys/bus/i2c/devices/5-004b/hwmon/hwmon* --> Sensor# 8 + /sys/bus/i2c/devices/6-0048/hwmon/hwmon* --> Sensor# 9 + /sys/bus/i2c/devices/6-0049/hwmon/hwmon* --> Sensor# 10 + /sys/bus/i2c/devices/6-004a/hwmon/hwmon* --> Sensor# 11 + /sys/bus/i2c/devices/6-004b/hwmon/hwmon* --> Sensor# 12 + """ + + def getSensorTemp(self): + global isPlatformAFI + global PrevASICValue + + sensor_str = '' + + #AFI + if (isPlatformAFI == True): + temp_policy = temp_policy_AFI + else: + #AFO + temp_policy = temp_policy_AFO + + """ Dictionary where + key = thermal id index starting from 0. 0 is the sensor 1 ... + value = Different temp ranges """ + SensorFlag = { + 0: [0,0,0,0,0,0,0,0,0,0,0,0], + 1: [0,0,0,0,0,0,0,0,0,0,0,0], + 2: [0,0,0,0,0,0,0,0,0,0,0,0], + 3: [0,0,0,0,0,0,0,0,0,0,0,0], + 4: [0,0,0,0,0,0,0,0,0,0,0,0], + 5: [0,0,0,0,0,0,0,0,0,0,0,0], + 6: [0,0,0,0,0,0,0,0,0,0,0,0], + 7: [0,0,0,0,0,0,0,0,0,0,0,0], + 8: [0,0,0,0,0,0,0,0,0,0,0,0], + 9: [0,0,0,0,0,0,0,0,0,0,0,0], + 10: [0,0,0,0,0,0,0,0,0,0,0,0], + 11: [0,0,0,0,0,0,0,0,0,0,0,0], + } + + for x in range(self.SENSOR_CORETEMP_NUM_ON_MAIN_BOARD): + SEN_str = 'SEN' + + if x < self.SENSOR_NUM_ON_MAIN_BOARD: + value = self._get_sensor_node_val(x) + if ( x < 2): + SEN_str += `x + 2` + else: + SEN_str += `x + 3` + + sensor_str += SEN_str + ':' + str(value) + ', ' + + elif x == self.CORETEMP_INDEX_ON_MAIN_BOARD: + value = self.get_coretempValue() + sensor_str += 'CPU:' + str(value) + ', ' + + else: + proc = subprocess.Popen("bcmcmd \"show temp\" | grep \"maximum peak temperature\" | awk '{ print $5 }' > /var/log/asic_value 2>&1 & ",shell=True) + time.sleep(2) + cmd = "kill -9 %s"%(proc.pid) + commands.getstatusoutput(cmd) + + if os.stat("/var/log/asic_value").st_size == 0: + value = PrevASICValue + else: + with open('/var/log/asic_value', 'r') as f: + value1 = f.readline() + value2 = float(value1) + value1 = value2 * 1000 + value = int(value1) + PrevASICValue = value + + sensor_str += 'BRCM TH:' + str(value) + + # 35% Duty Cycle + if value > temp_policy[x][0][1] and value <= temp_policy[x][0][2]: + SensorFlag[x][0] = True + + # 35% Prev Duty Cycle + elif value > temp_policy[x][1][1] and value < temp_policy[x][1][2]: + SensorFlag[x][1] = True + + # 55% Duty Cycle + elif value == temp_policy[x][2][1]: + SensorFlag[x][2] = True + + # 55% Prev Duty Cycle + elif value > temp_policy[x][3][1] and value < temp_policy[x][3][2]: + SensorFlag[x][3] = True + + # 75% Duty Cycle + elif value == temp_policy[x][4][1]: + SensorFlag[x][4] = True + + # 75% Prev Duty Cycle + elif value > temp_policy[x][5][1] and value < temp_policy[x][5][2]: + SensorFlag[x][5] = True + + # 90% Duty Cycle + elif value == temp_policy[x][6][1]: + SensorFlag[x][6] = True + + # 90% Prev Duty Cycle + elif value > temp_policy[x][7][1] and value < temp_policy[x][7][2]: + SensorFlag[x][7] = True + + #100% Duty Cycle + elif value >= temp_policy[x][8][1]: + SensorFlag[x][8] = True + + else: + pass + + # Yellow Alarm + if value >= temp_policy[x][9][1] and value < temp_policy[x][9][2]: + SensorFlag[x][9] = True + + # Red Alarm + elif value >= temp_policy[x][10][1] and value < temp_policy[x][10][2]: + SensorFlag[x][10] = True + + # Fire Shut down + elif value >= temp_policy[x][11][1]: + SensorFlag[x][11] = True + + logging.debug('Sensor values : %s', sensor_str) + fan = QFX5200_FanUtil() + # CHECK IF ANY TEMPERATURE SENSORS is running at Soft shutdown temperature + if (SensorFlag[0][11] or SensorFlag[1][11] or SensorFlag[2][11] or SensorFlag[3][11] or SensorFlag[4][11] or SensorFlag[5][11] or SensorFlag[6][11] or SensorFlag[7][11] + or SensorFlag[8][11] or SensorFlag[9][11] or SensorFlag[10][11] or SensorFlag[11][11]): + + logging.debug('Fire Threshold reached: System is going to shutdown now') + os.system("echo 'CRITICAL: Fire Threshold reached: System is going to shutdown now' > /dev/console") + + + logging.debug('Executing poweroff command') + + time.sleep(1) + + try: + monitorlog_file = open(self.MONITORLOG_PATH) + except IOError as e: + logging.error('get_Sensor_temp: unable to open file: %s', str(e)) + return False + + monitorlog_file.close() + + cmd = "poweroff" + os.system(cmd) + + # CHECK IF ANY TEMPERATURE SENSORS is running at RED warning , IF YES, SET THE ALARM LED TO 'RED' + elif (SensorFlag[0][10] or SensorFlag[1][10] or SensorFlag[2][10] or SensorFlag[3][10] or SensorFlag[4][10] or SensorFlag[5][10] or SensorFlag[6][10] or SensorFlag[7][10] + or SensorFlag[8][10] or SensorFlag[9][10] or SensorFlag[10][10] or SensorFlag[11][10]): + + self.set_alarm_led_brightness(2) + + logging.debug('Setting Red Alarm') + + # CHECK IF ANY TEMPERATURE SENSORS is running at Yellow warning, IF YES, SET THE ALARM LED TO 'YELLOW' + elif (SensorFlag[0][9] or SensorFlag[1][9] or SensorFlag[2][9] or SensorFlag[3][9] or SensorFlag[4][9] or SensorFlag[5][9] or SensorFlag[6][9] or SensorFlag[7][9] + or SensorFlag[8][9] or SensorFlag[9][9] or SensorFlag[10][9] or SensorFlag[11][9]): + + self.set_alarm_led_brightness(1) + + logging.debug('Setting Yellow Alarm') + + else: + value = self.get_alarm_led_brightness() + if ( value == 2): + logging.debug('Clearing Red Alarm') + elif ( value == 1): + logging.debug('Clearing Yellow Alarm') + + self.set_alarm_led_brightness(0) + + #CHECK IF ANY TEMPERATURE SENSORS HAS SET 100% DUTY CYCLE FLAG + if (SensorFlag[0][8] or SensorFlag[1][8] or SensorFlag[2][8] or SensorFlag[3][8] or SensorFlag[4][8] or SensorFlag[5][8] or SensorFlag[6][8] or SensorFlag[7][8] + or SensorFlag[8][8] or SensorFlag[9][8] or SensorFlag[10][8] or SensorFlag[11][8]): + + fan.get_check_fan_dutycycle() + if (fan.get_fan_dutycycle() < 100): + time.sleep(0.50) + fan.set_fan_dutycycle(100) + + logging.debug('Fan set to 100% dutycycle') + # CHECK IF ANY TEMPERATURE SENSORS HAS SET 90% PREV DUTY CYCLE FLAG + elif (SensorFlag[0][7] or SensorFlag[1][7] or SensorFlag[2][7] or SensorFlag[3][7] or SensorFlag[4][7] or SensorFlag[5][7] or SensorFlag[6][7] or SensorFlag[7][7] + or SensorFlag[8][7] or SensorFlag[9][7] or SensorFlag[10][7] or SensorFlag[11][7]): + + fan.get_check_fan_dutycycle() + + if (fan.get_fan_dutycycle() == 100): + logging.debug('Fan set to 100% dutycycle') + elif (fan.get_fan_dutycycle() != 90): + time.sleep(0.25) + fan.set_fan_dutycycle(90) + logging.debug('Fan set to 90% dutycycle') + else: + logging.debug('Fan set to 90% dutycycle') + + # CHECK IF ANY TEMPERATURE SENSORS HAS SET 90% DUTY CYCLE FLAG + elif (SensorFlag[0][6] or SensorFlag[1][6] or SensorFlag[2][6] or SensorFlag[3][6] or SensorFlag[4][6] or SensorFlag[5][6] or SensorFlag[6][6] or SensorFlag[7][6] + or SensorFlag[8][6] or SensorFlag[9][6] or SensorFlag[10][6] or SensorFlag[11][6]): + + fan.get_check_fan_dutycycle() + + if (fan.get_fan_dutycycle() < 90): + time.sleep(0.25) + fan.set_fan_dutycycle(90) + logging.debug('Fan set to 90% dutycycle') + elif (fan.get_fan_dutycycle() == 90): + logging.debug('Fan set to 90% dutycycle') + else: + time.sleep(0.25) + fan.set_fan_dutycycle(90) + logging.debug('Fan set to 90% dutycycle') + + # CHECK IF ANY TEMPERATURE SENSORS HAS SET 75% PREV DUTY CYCLE FLAG + elif (SensorFlag[0][5] or SensorFlag[1][5] or SensorFlag[2][5] or SensorFlag[3][5] or SensorFlag[4][5] or SensorFlag[5][5] or SensorFlag[6][5] or SensorFlag[7][5] + or SensorFlag[8][5] or SensorFlag[9][5] or SensorFlag[10][5] or SensorFlag[11][5]): + + fan.get_check_fan_dutycycle() + + if (fan.get_fan_dutycycle() > 75): + if (fan.get_fan_dutycycle() == 100): + time.sleep(0.25) + fan.set_fan_dutycycle(90) + logging.debug('Fan set to 90% dutycycle') + else: + logging.debug('Fan set to 90% dutycycle') + elif (fan.get_fan_dutycycle() != 75): + time.sleep(0.25) + fan.set_fan_dutycycle(75) + logging.debug('Fan set to 75% dutycycle') + else: + logging.debug('Fan set to 75% dutycycle') + + # CHECK IF ANY TEMPERATURE SENSORS HAS SET 75% DUTY CYCLE FLAG + elif (SensorFlag[0][4] or SensorFlag[1][4] or SensorFlag[2][4] or SensorFlag[3][4] or SensorFlag[4][4] or SensorFlag[5][4] or SensorFlag[6][4] or SensorFlag[7][4] + or SensorFlag[8][4] or SensorFlag[9][4] or SensorFlag[10][4] or SensorFlag[11][4]): + + fan.get_check_fan_dutycycle() + if (fan.get_fan_dutycycle() < 75): + time.sleep(0.25) + fan.set_fan_dutycycle(75) + logging.debug('Fan set to 75% dutycycle') + + elif (fan.get_fan_dutycycle() == 75): + logging.debug('Fan set to 75% dutycycle') + + else: + time.sleep(0.25) + fan.set_fan_dutycycle(75) + logging.debug('Fan set to 75% dutycycle') + + + # CHECK IF ANY TEMPERATURE SENSORS HAS SET 55% DUTY CYCLE PREV FLAG + elif (SensorFlag[0][3] or SensorFlag[1][3] or SensorFlag[2][3] or SensorFlag[3][3] or SensorFlag[4][3] or SensorFlag[5][3] or SensorFlag[6][3] or SensorFlag[7][3] + or SensorFlag[8][3] or SensorFlag[9][3] or SensorFlag[10][3] or SensorFlag[11][3]): + + fan.get_check_fan_dutycycle() + + if (fan.get_fan_dutycycle() > 55): + if (fan.get_fan_dutycycle() == 100): + time.sleep(0.25) + fan.set_fan_dutycycle(90) + logging.debug('Fan set to 90% dutycycle') + elif (fan.get_fan_dutycycle() == 90): + time.sleep(0.25) + fan.set_fan_dutycycle(75) + logging.debug('Fan set to 75% dutycycle') + else: + logging.debug('Fan set to 75% dutycycle') + elif (fan.get_fan_dutycycle() != 55): + time.sleep(0.25) + fan.set_fan_dutycycle(55) + logging.debug('Fan set to 55% dutycycle') + else: + logging.debug('Fan set to 55% dutycycle') + + + # CHECK IF ANY TEMPERATURE SENSORS HAS SET 55% DUTY CYCLE FLAG + elif (SensorFlag[0][2] or SensorFlag[1][2] or SensorFlag[2][2] or SensorFlag[3][2] or SensorFlag[4][2] or SensorFlag[5][2] or SensorFlag[6][2] or SensorFlag[7][2] + or SensorFlag[8][2] or SensorFlag[9][2] or SensorFlag[10][2] or SensorFlag[11][2]): + + fan.get_check_fan_dutycycle() + + if (fan.get_fan_dutycycle() < 55): + time.sleep(0.25) + fan.set_fan_dutycycle(55) + logging.debug('Fan set to 55% dutycycle') + elif (fan.get_fan_dutycycle() == 55): + logging.debug('Fan set to 55% dutycycle') + else: + time.sleep(0.25) + fan.set_fan_dutycycle(55) + logging.debug('Fan set to 55% dutycycle') + + # CHECK IF ANY TEMPERATURE SENSORS HAS SET 35% PREV DUTY CYCLE FLAG + elif (SensorFlag[0][1] or SensorFlag[1][1] or SensorFlag[2][1] or SensorFlag[3][1] or SensorFlag[4][1] or SensorFlag[5][1] or SensorFlag[6][1] or SensorFlag[7][1] + or SensorFlag[8][1] or SensorFlag[9][1] or SensorFlag[10][1] or SensorFlag[11][1]): + + fan.get_check_fan_dutycycle() + + if (fan.get_fan_dutycycle() > 35): + if (fan.get_fan_dutycycle() == 100): + time.sleep(0.25) + fan.set_fan_dutycycle(90) + logging.debug('Fan set to 90% dutycycle') + elif (fan.get_fan_dutycycle() == 90): + time.sleep(0.25) + fan.set_fan_dutycycle(75) + logging.debug('Fan set to 75% dutycycle') + elif (fan.get_fan_dutycycle() == 75): + time.sleep(0.25) + fan.set_fan_dutycycle(55) + logging.debug('Fan set to 55% dutycycle') + else: + logging.debug('Fan set to 55% dutycycle') + elif (fan.get_fan_dutycycle() == 35): + logging.debug('Fan set to 35% dutycycle') + + # CHECK IF ANY TEMPERATURE SENSORS HAS SET 35% DUTY CYCLE FLAG + elif (SensorFlag[0][0] or SensorFlag[1][0] or SensorFlag[2][0] or SensorFlag[3][0] or SensorFlag[4][0] or SensorFlag[5][0] or SensorFlag[6][0] or SensorFlag[7][0] + or SensorFlag[8][0] or SensorFlag[9][0] or SensorFlag[10][0] or SensorFlag[11][0]): + + fan.get_check_fan_dutycycle() + + if (fan.get_fan_dutycycle() > 35): + time.sleep(0.25) + fan.set_fan_dutycycle(35) + + logging.debug('Fan set to 35% dutycycle') + + else: + pass + + + # RESET ALL THE SENSOR FLAGS + for x in range(self.SENSOR_CORETEMP_NUM_ON_MAIN_BOARD): + for y in range(self.SENSOR_CORETEMP_NUM_ON_MAIN_BOARD): + SensorFlag[x][y] = 0 + +class device_monitor(object): + + MASTER_LED_PATH = '/sys/class/leds/master/brightness' + SYSTEM_LED_PATH = '/sys/class/leds/system/brightness' + + PWMINPUT_PATH = '/sys/bus/i2c/devices/7-00{0}/hwmon/{1}/pwm{2}' + HWMONINPUT_PATH = '/sys/bus/i2c/devices/7-00{0}/hwmon/' + + PWMINPUT_NUM = 10 + _pwm_input_path_mapping = {} + _hwmon_input_path_mapping = {} + + # PWM NUMBERS + _pwm_input_node_mapping = ['1','2','3','4','1','2','3','4','1','2'] + + # I2C NUMBERS + _hwmon_input_node_mapping = ['2c','2c','2c','2c','2e','2e','2e','2e','2f','2f'] + + def __init__(self, log_file, log_level): + global DEBUG + global isPlatformAFI + + hwmoninput_path = self.HWMONINPUT_PATH + pwminput_path = self.PWMINPUT_PATH + for x in range(self.PWMINPUT_NUM): + self._hwmon_input_path_mapping[x] = hwmoninput_path.format( + self._hwmon_input_node_mapping[x]) + + hwmon_path = os.listdir(self._hwmon_input_path_mapping[x]) + hwmon_dir = '' + for hwmon_name in hwmon_path: + hwmon_dir = hwmon_name + + self._pwm_input_path_mapping[x] = pwminput_path.format( + self._hwmon_input_node_mapping[x], + hwmon_dir, + self._pwm_input_node_mapping[x]) + + """Needs a logger and a logger level.""" + # set up logging to file + logging.basicConfig( + filename=log_file, + level=log_level, + format= '[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s' + ) + + if DEBUG == True: + # set up logging to console + if log_level == logging.DEBUG: + console = logging.StreamHandler() + console.setLevel(log_level) + formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') + console.setFormatter(formatter) + logging.getLogger('').addHandler(console) + + filename = "/var/run/eeprom" + AFO_str = "AFO" + pattern = re.compile(r"Fan Type", re.IGNORECASE) + with open(filename, "rt") as myfile: + for line in myfile: + if pattern.search(line) != None: + fan_type = str(line) + if "=" in fan_type: + user=fan_type[fan_type.find("=")+1:].split()[0] + if user == AFO_str: + isPlatformAFI = False + else: + isPlatformAFI = True + + master_led_value = 1 + + try: + masterLED_file = open(self.MASTER_LED_PATH, 'r+') + except IOError as e: + logging.error('device_monitor: unable to open Master LED file: %s', str(e)) + + masterLED_file.write(str(master_led_value)) + masterLED_file.close() + + system_led_value = 1 + + try: + systemLED_file = open(self.SYSTEM_LED_PATH, 'r+') + except IOError as e: + logging.error('device_monitor: unable to open System LED file: %s', str(e)) + + systemLED_file.write(str(system_led_value)) + systemLED_file.close() + self.get_Initial_fan_dutycycle() + self.set_Default_fan_dutycycle(35) + + + def set_Default_fan_dutycycle(self, val): + fan_speed = {35: 86, 55: 139, 75: 192, 90: 230,100: 255} + for x in range(self.PWMINPUT_NUM): + device_path = self._pwm_input_path_mapping[x] + pwm_value = fan_speed.get(val) + pwm_value1 = str(pwm_value) + time.sleep(0.25) + cmd = ("sudo echo %s > %s" %(pwm_value1,device_path)) + os.system(cmd) + + logging.debug('Setting Default PWM value: 86 to all fans') + return True + + def get_Initial_fan_dutycycle(self): + pwm_str = '' + for x in range(self.PWMINPUT_NUM): + device_path = self._pwm_input_path_mapping[x] + cmd = ("sudo cat %s" %(device_path)) + status, pwm_value = commands.getstatusoutput(cmd) + pwm_str += pwm_value + if (x != self.PWMINPUT_NUM -1): + pwm_str += ', ' + time.sleep(0.25) + logging.debug('Initial PWM values read: %s', pwm_str) + return True + + def manage_device(self): + thermal = QFX5200_ThermalUtil() + thermal.getSensorTemp() + +def main(): + #Introducing sleep of 150 seconds to wait for all the docker containers to start before starting the EM policy. + time.sleep(150) + monitor = device_monitor(log_file, log_level) + while True: + monitor.manage_device() + time.sleep(20) + +if __name__ == '__main__': + main() diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/juniper_qfx5200_util.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/juniper_qfx5200_util.py new file mode 100755 index 000000000000..2e6171d99180 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/juniper_qfx5200_util.py @@ -0,0 +1,235 @@ +#!/usr/bin/env python +# +# Description: This file contains the Juniper QFX5200 Platform Initialization routines +# +# Copyright (c) 2020, Juniper Networks, Inc. +# All rights reserved. +# +# This program is free software: you can 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 +import logging +import time + +PROJECT_NAME = 'QFX5200-32C' +verbose = False +DEBUG = False +FORCE = 0 + +if DEBUG == True: + print sys.argv[0] + print 'ARGV :', sys.argv[1:] + +i2c_prefix = '/sys/bus/i2c/devices/' + +kos = [ +'modprobe i2c-mux', +'modprobe mfd-core', +'modprobe tmp401', +'modprobe jnx-tmc-core', +'modprobe leds-jnx-tmc', +'modprobe jnx-refpga-tmc', +'modprobe i2c-tmc', +'modprobe gpio-tmc', +'modprobe jnx-tmc-psu', +'modprobe jnx-psu-monitor', +'modprobe jnx-refpga-lpcm', +'modprobe adt7470' +] + +mknod =[ +'echo tmp435 0x48 > /sys/bus/i2c/devices/i2c-5/new_device', +'echo tmp435 0x49 > /sys/bus/i2c/devices/i2c-5/new_device', +'echo tmp435 0x4A > /sys/bus/i2c/devices/i2c-5/new_device', +'echo tmp435 0x4B > /sys/bus/i2c/devices/i2c-5/new_device', +'echo tmp435 0x48 > /sys/bus/i2c/devices/i2c-6/new_device', +'echo tmp435 0x49 > /sys/bus/i2c/devices/i2c-6/new_device', +'echo tmp435 0x4A > /sys/bus/i2c/devices/i2c-6/new_device', +'echo tmp435 0x4B > /sys/bus/i2c/devices/i2c-6/new_device', +'echo tmp435 0x48 > /sys/bus/i2c/devices/i2c-7/new_device', +'echo tmp435 0x49 > /sys/bus/i2c/devices/i2c-7/new_device', +'echo adt7470 0x2C > /sys/bus/i2c/devices/i2c-7/new_device', +'echo adt7470 0x2E > /sys/bus/i2c/devices/i2c-7/new_device', +'echo adt7470 0x2F > /sys/bus/i2c/devices/i2c-7/new_device', +'echo jpsu 0x58 > /sys/bus/i2c/devices/i2c-3/new_device', +'echo jpsu 0x58 > /sys/bus/i2c/devices/i2c-4/new_device', +] + +def my_log(txt): + if DEBUG == True: + print 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_install(): + global FORCE + log_os_system("depmod", 1) + for i in range(0,len(kos)): + status, output = log_os_system(kos[i], 1) + time.sleep(2) + if status: + if FORCE == 0: + return status + return 0 + +def device_exist(): + ret1, log = log_os_system("ls "+i2c_prefix+"5-0049", 0) + ret2, log = log_os_system("ls "+i2c_prefix+"7-002c", 0) + + return not(ret1 or ret2) + +def device_install(): + global FORCE + for i in range(0,len(mknod)): + status, output = log_os_system(mknod[i], 1) + if status: + print output + if FORCE == 0: + return status + +def do_install(): + status = driver_install() + if status: + if FORCE == 0: + return status + + if not device_exist(): + logging.info('No device, installing....') + status = device_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" devices detected...." + return + +def main(): + + hwmon_input_node_mapping = ['2c','2e','2f'] + PWM1FREQ_PATH = '/sys/bus/i2c/devices/7-00{0}/hwmon/{1}/pwm1_freq' + NUMSENSORS_PATH = '/sys/bus/i2c/devices/7-00{0}/hwmon/{1}/num_temp_sensors' + HWMONINPUT_PATH = '/sys/bus/i2c/devices/7-00{0}/hwmon/' + PWMINPUT_NUM = 3 + hwmon_input_path_mapping = {} + pwm_input_path_mapping = {} + numsensors_input_path_mapping = {} + + + # Enabling REFPGA + EnableREFFGACmd = 'busybox devmem 0xFED50011 8 0x53' + try: + os.system(EnableREFFGACmd) + except OSError: + print 'Error: Execution of "%s" failed', EnableREFFGACmd + return False + + time.sleep(2) + + # Create CPU Board EEPROM device + CreateEEPROMdeviceCmd = 'sudo echo 24c02 0x51 > /sys/bus/i2c/devices/i2c-0/new_device' + try: + os.system(CreateEEPROMdeviceCmd) + except OSError: + print 'Error: Execution of "%s" failed', CreateEEPROMdeviceCmd + return False + + time.sleep(1) + + #Retrieve the Base MAC Address from EEPROM + status, macAddress = commands.getstatusoutput("decode-syseeprom -m 0x24") + if status: + print 'Error: Could not retrieve BASE MAC Address from EEPROM' + return False + + #Make eth0 interface down + status, eth0Down = commands.getstatusoutput("ifconfig eth0 down") + if status: + print 'Error: Could not make eth0 interface down' + return False + + #Assign BASE MAC ADDRESS retieved from CPU board EEPROM to eth0 interface + mac_address_prog = "ifconfig eth0 hw ether " + str(macAddress) + + status, MACAddressProg = commands.getstatusoutput(mac_address_prog) + if status: + print 'Error: Could not set up "macAddress" for eth0 interface' + return False + + #Make eth0 interface up + status, eth0UP = commands.getstatusoutput("ifconfig eth0 up") + if status: + print 'Error: Could not make eth0 interface up' + return False + + # Juniper QFX5200 platform drivers install + do_install() + time.sleep(2) + + # Juniper SFP Intialization + JuniperSFPInitCmd = 'python /usr/share/sonic/device/x86_64-juniper_qfx5200-r0/plugins/qfx5200_sfp_init.py' + try: + os.system(JuniperSFPInitCmd) + except OSError: + print 'Error: Execution of "%s" failed', JuniperSFPInitCmd + return False + + time.sleep(1) + # Invoking the script which retrieves the data from CPU Board and Main Board EEPROM and storing in file + EEPROMDataCmd = 'python /usr/share/sonic/device/x86_64-juniper_qfx5200-r0/plugins/qfx5200_eeprom_data.py' + try: + os.system(EEPROMDataCmd) + except OSError: + print 'Error: Execution of "%s" failed', EEPROMDataCmd + return False + + for x in range(PWMINPUT_NUM): + hwmon_input_path_mapping[x] = HWMONINPUT_PATH.format(hwmon_input_node_mapping[x]) + + hwmon_path = os.listdir(hwmon_input_path_mapping[x]) + hwmon_dir = '' + for hwmon_name in hwmon_path: + hwmon_dir = hwmon_name + + pwm_input_path_mapping[x] = PWM1FREQ_PATH.format( + hwmon_input_node_mapping[x], + hwmon_dir) + device_path = pwm_input_path_mapping[x] + time.sleep(1) + cmd = ("sudo echo 22500 > %s" %device_path) + os.system(cmd) + + numsensors_input_path_mapping[x] = NUMSENSORS_PATH.format( + hwmon_input_node_mapping[x], + hwmon_dir) + numsensors_path = numsensors_input_path_mapping[x] + time.sleep(1) + cmd = ("sudo echo 0 > %s" %numsensors_path) + os.system(cmd) + + return True + +if __name__ == "__main__": + main() diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/show_thresholds b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/show_thresholds new file mode 100755 index 000000000000..29d584e7f328 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/show_thresholds @@ -0,0 +1,43 @@ +#!/usr/bin/env python +import os +import commands + +def fantype_detect(): + + refpgaTMC_path = "/sys/devices/pci0000:00/0000:00:1c.0/0000:0f:00.0/refpga-tmc.15" + + AFO = "1" + AFI = "0" + + #default fan type is AFI + default_fantype = 0 + + for filename in os.listdir(refpgaTMC_path): + if filename.endswith('_type'): + fantype_path = os.path.join(refpgaTMC_path, filename) + cat_string = "cat " + fantype_string = cat_string + fantype_path + status,fan_type=commands.getstatusoutput(fantype_string) + if ((fan_type == AFO) or (fan_type == AFI)): + return fan_type + else: + pass + + return default_fantype + +def main(): + AFO_value = "1" + + fan_type = fantype_detect() + + if fan_type == AFO_value: + temp_thres_file = open("/usr/local/bin/temperature_thresholds_AFO.txt", "r+") + print temp_thres_file.read() + else: + temp_thres_file = open("/usr/local/bin/temperature_thresholds_AFI.txt", "r+") + print temp_thres_file.read() + + temp_thres_file.close() + +if __name__ == "__main__": + main() diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/temperature_thresholds_AFI.txt b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/temperature_thresholds_AFI.txt new file mode 100755 index 000000000000..055bd850906a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/temperature_thresholds_AFI.txt @@ -0,0 +1,27 @@ +Sensor # 35% 55% 75% 90% 100% Yellow Red Fire + Duty cycle Duty cycle Duty cycle Duty cycle Duty cycle Alarm Alarm Shutdown +================== ================================================================================================== +1 CPU <50 >=50 & <58 >=58 & 66 >=66 & <75 >=75 >86 >92 >95 + +2 (tmp435-i2c-7-48) <39 >=39 & <48 >=48 & <56 >=56 & <66 >=66 >64 >70 >73 + +3 (tmp435-i2c-7-49) <39 >=39 & <48 >=48 & <56 >=56 & <66 >=66 >64 >70 >73 + +4 BRCM TH1 ASIC <74 >=74 & <80 >=80 & <85 >=85 & <92 >=92 >99 >102 >105 + +5 (tmp435-i2c-5-48) <47 >=47 & <55 >=55 & <62 >=62 & <70 >=70 >68 >74 >77 + +6 (tmp435-i2c-5-49) <44 >=44 & <52 >=52 & <60 >=60 & <69 >=69 >67 >73 >76 + +7 (tmp435-i2c-5-4a) <57 >=57 & <63 >=63 & <68 >=68 & <74 >=74 >72 >78 >81 + +8 (tmp435-i2c-5-4b) <45 >=45 & <53 >=53 & <61 >=61 & <70 >=70 >68 >74 >77 + +9 (tmp435-i2c-6-48) <45 >=45 & <53 >=53 & <60 >=60 & <69 >=69 >67 >73 >76 + +10 (tmp435-i2c-6-49) <57 >=57 & <63 >=63 & <68 >=68 & <74 >=74 >72 >78 >81 + +11 (tmp435-i2c-6-4A) <48 >=48 & <55 >=55 & <62 >=62 & <70 >=70 >68 >74 >77 + +12 (tmp435-i2c-6-4B) <49 >=49 & <57 >=57 & <64 >=64 & <72 >=72 >70 >76 >79 + diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/temperature_thresholds_AFO.txt b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/temperature_thresholds_AFO.txt new file mode 100755 index 000000000000..b7f489b5565a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/temperature_thresholds_AFO.txt @@ -0,0 +1,27 @@ +Sensor # 35% 55% 75% 90% 100% Yellow Red Fire + Duty cycle Duty cycle Duty cycle Duty cycle Duty cycle Alarm Alarm Shutdown +================== ================================================================================================== +1 CPU <58 >=58 & <64 >=64 & <70 >=70 & <78 >=78 >86 >92 >95 + +2 (tmp435-i2c-7-48) <49 >=49 & <55 >=55 & <62 >=62 & <69 >=69 >67 >73 >76 + +3 (tmp435-i2c-7-49) <48 >=48 & <55 >=55 & <61 >=61 & <69 >=69 >67 >73 >76 + +4 BRCM TH1 ASIC <79 >=79 & <83 >=83 & <86 >=86 & <90 >=90 >99 >102 >105 + +5 (tmp435-i2c-5-48) <50 >=50 & <56 >=56 & <63 >=63 & <70 >=70 >68 >74 >77 + +6 (tmp435-i2c-5-49) <43 >=43 & <50 >=50 & <57 >=57 & <65 >=65 >63 >69 >72 + +7 (tmp435-i2c-5-4a) <54 >=54 & <60 >=60 & <65 >=65 & <71 >=71 >68 >74 >77 + +8 (tmp435-i2c-5-4b) <52 >=52 & <58 >=58 & <63 >=63 & <70 >=70 >68 >74 >77 + +9 (tmp435-i2c-6-48) <55 >=55 & <60 >=60 & <65 >=65 & <71 >=71 >65 >71 >78 + +10 (tmp435-i2c-6-49) <55 >=55 & <60 >=60 & <66 >=66 & <72 >=72 >70 >76 >79 + +11 (tmp435-i2c-6-4A) <47 >=47 & <54 >=54 & <60 >=60 & <67 >=67 >65 >71 >74 + +12 (tmp435-i2c-6-4B) <61 >=61 & <66 >=66 & <70 >=70 & <75 >=75 >73 >79 >82 + diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/wrapper-fast-reboot b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/wrapper-fast-reboot new file mode 100755 index 000000000000..08ac3be0d688 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/wrapper-fast-reboot @@ -0,0 +1,17 @@ +#!/bin/bash + +# Disable exit on non zero +set +e + +# Unloading this module as it contains the reboot +# notifier hook. When the kexec is invoked with platform +# reset handlers, it results in a cold reboot. Removing +# the reset handlers ensures that kernel does a kexec +# based fast reboot +rmmod jnx-refpga-lpcm > /dev/null 2>&1 + +/usr/bin/qfx5200-fast-reboot/fast-reboot $@ + +# Re-load the module if the fast-reboot script returns +# here. +modprobe jnx-refpga-lpcm > /dev/null 2>&1 diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/wrapper-warm-reboot b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/wrapper-warm-reboot new file mode 100755 index 000000000000..e34db6629588 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/wrapper-warm-reboot @@ -0,0 +1,17 @@ +#!/bin/bash + +# Disable exit on non zero +set +e + +# Unloading this module as it contains the reboot +# notifier hook. When the kexec is invoked with platform +# reset handlers, it results in a cold reboot. Removing +# the reset handlers ensures that kernel does a kexec +# based fast reboot +rmmod jnx-refpga-lpcm > /dev/null 2>&1 + +/usr/bin/qfx5200-warm-reboot/warm-reboot $@ + +# Re-load the module if the warm-reboot script returns +# here. +modprobe jnx-refpga-lpcm > /dev/null 2>&1 diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/juniper_i2c_cpld.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/juniper_i2c_cpld.c deleted file mode 120000 index 843ce05a4313..000000000000 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/juniper_i2c_cpld.c +++ /dev/null @@ -1 +0,0 @@ -../../common/modules/juniper_i2c_cpld.c \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/juniper_i2c_cpld.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/juniper_i2c_cpld.c new file mode 100644 index 000000000000..25860a6ac1f9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/juniper_i2c_cpld.c @@ -0,0 +1,892 @@ +/* + * A hwmon driver for the juniper_i2c_cpld + * + * Tested and validated on Juniper QFX5210 + * Ciju Rajan K + * + * Copyright (C) 2013 Accton Technology Corporation. + * Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define MAX_PORT_NUM 64 +#define I2C_RW_RETRY_COUNT 10 +#define I2C_RW_RETRY_INTERVAL 60 /* ms */ + +#define I2C_ADDR_CPLD1 0x60 +#define I2C_ADDR_CPLD2 0x62 +#define I2C_ADDR_CPLD3 0x64 +#define CPLD_ADDRS {I2C_ADDR_CPLD1, I2C_ADDR_CPLD2, I2C_ADDR_CPLD3} + + +/* + * Number of additional attribute pointers to allocate + * with each call to krealloc + */ +#define ATTR_ALLOC_SIZE 1 /*For last attribute which is NUll.*/ + +#define NAME_SIZE 24 +#define MAX_RESP_LENGTH 48 + +typedef ssize_t (*show_func)( struct device *dev, + struct device_attribute *attr, + char *buf); +typedef ssize_t (*store_func)(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count); + +enum models { + AS7712_32X, + AS7716_32X, + qfx5210_64X, + AS7312_54X, + PLAIN_CPLD, /*No attribute but add i2c addr to the list.*/ + NUM_MODEL +}; + +enum sfp_func { + HAS_SFP = 1<<0 , + HAS_QSFP = 1<<1 , +}; + +enum common_attrs { + CMN_VERSION, + CMN_ACCESS, + CMN_PRESENT_ALL, + NUM_COMMON_ATTR +}; + +enum sfp_attrs { + SFP_PRESENT, + SFP_RESET, + SFP_LP_MODE, + NUM_SFP_ATTR +}; + +struct cpld_sensor { + struct cpld_sensor *next; + char name[NAME_SIZE+1]; /* sysfs sensor name */ + struct device_attribute attribute; + bool update; /* runtime sensor update needed */ + int data; /* Sensor data. Negative if there was a read error */ + + u8 reg; /* register */ + u8 mask; /* bit mask */ + bool invert; /* inverted value*/ + +}; + +#define to_cpld_sensor(_attr) \ + container_of(_attr, struct cpld_sensor, attribute) + +struct cpld_data { + struct device *dev; + struct device *hwmon_dev; + + int num_attributes; + struct attribute_group group; + + enum models model; + struct cpld_sensor *sensors; + struct mutex update_lock; + bool valid; + unsigned long last_updated; /* in jiffies */ + + int attr_index; + u16 sfp_num; + u8 sfp_types; + struct model_attrs *cmn_attr; +}; + +struct cpld_client_node { + struct i2c_client *client; + struct list_head list; +}; + + +struct base_attrs { + const char *name; + umode_t mode; + show_func get; + store_func set; +}; + +struct attrs { + int reg; + bool invert; + struct base_attrs *base; +}; + +struct model_attrs { + struct attrs **cmn; + struct attrs **portly; +}; + + +static ssize_t show_bit(struct device *dev, + struct device_attribute *devattr, char *buf); +static ssize_t show_presnet_all(struct device *dev, + struct device_attribute *devattr, char *buf); +static ssize_t set_1bit(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t set_byte(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t access(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); + +int juniper_i2c_cpld_read(u8 cpld_addr, u8 reg); +int juniper_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + + +struct base_attrs common_attrs[NUM_COMMON_ATTR] = +{ + [CMN_VERSION] = {"version", S_IRUGO, show_bit, NULL}, + [CMN_ACCESS] = {"access", S_IWUSR, NULL, set_byte}, + [CMN_PRESENT_ALL] = {"module_present_all", S_IRUGO, show_presnet_all, NULL}, +}; + +struct attrs as7712_common[] = { + [CMN_VERSION] = {0x01, false, &common_attrs[CMN_VERSION]}, + [CMN_ACCESS] = {0x00, false, &common_attrs[CMN_ACCESS]}, + [CMN_PRESENT_ALL] = {0x30, false, &common_attrs[CMN_PRESENT_ALL]}, +}; +struct attrs qfx5210_common[] = { + [CMN_VERSION] = {0x01, false, &common_attrs[CMN_VERSION]}, + [CMN_ACCESS] = {0x00, false, &common_attrs[CMN_ACCESS]}, + [CMN_PRESENT_ALL] = {0x30, false, &common_attrs[CMN_PRESENT_ALL]}, +}; +struct attrs as7312_common[] = { + [CMN_VERSION] = {0x01, false, &common_attrs[CMN_VERSION]}, + [CMN_ACCESS] = {0x00, false, &common_attrs[CMN_ACCESS]}, + [CMN_PRESENT_ALL] = {-1, false, &common_attrs[CMN_PRESENT_ALL]}, +}; +struct attrs plain_common[] = { + [CMN_VERSION] = {0x01, false, &common_attrs[CMN_VERSION]}, +}; + +struct base_attrs portly_attrs[] = +{ + [SFP_PRESENT] = {"module_present", S_IRUGO, show_bit, NULL}, + // Only root user will have the privilege to write to sysfs + // [SFP_RESET] = {"module_reset", S_IRUGO|S_IWUGO, show_bit, set_1bit}, + [SFP_RESET] = {"module_reset", S_IRUGO|S_IWUSR, show_bit, set_1bit}, +}; + +struct attrs as7712_port[] = { + {0x30, true, &portly_attrs[SFP_PRESENT]}, + {0x04, true, &portly_attrs[SFP_RESET]}, +}; + +struct attrs qfx5210_port[] = { + {0x70, true, &portly_attrs[SFP_PRESENT]}, + {0x40, true, &portly_attrs[SFP_RESET]}, +}; + +struct attrs *as7712_cmn_list[] = { + &as7712_common[CMN_VERSION], + &as7712_common[CMN_ACCESS], + &as7712_common[CMN_PRESENT_ALL], + NULL +}; + +struct attrs *qfx5210_cmn_list[] = { + &qfx5210_common[CMN_VERSION], + &qfx5210_common[CMN_ACCESS], + &qfx5210_common[CMN_PRESENT_ALL], + NULL +}; + +struct attrs *as7312_cmn_list[] = { + &as7312_common[CMN_VERSION], + &as7312_common[CMN_ACCESS], + &as7312_common[CMN_PRESENT_ALL], + NULL +}; + +struct attrs *plain_cmn_list[] = { + &plain_common[CMN_VERSION], + NULL +}; + +struct attrs *as7712_port_list[] = { + &as7712_port[SFP_PRESENT], + &as7712_port[SFP_RESET], + NULL +}; +struct attrs *qfx5210_port_list[] = { + &qfx5210_port[SFP_PRESENT], + &qfx5210_port[SFP_RESET], + NULL +}; + +struct model_attrs models_attr[NUM_MODEL] = { + {.cmn = as7712_cmn_list, .portly=as7712_port_list}, + {.cmn = as7712_cmn_list, .portly=as7712_port_list}, /*7716's as 7712*/ + {.cmn = qfx5210_cmn_list, .portly=qfx5210_port_list}, + {.cmn = as7312_cmn_list, .portly=qfx5210_port_list}, + {.cmn = plain_cmn_list, .portly=NULL}, +}; + +static LIST_HEAD(cpld_client_list); +static struct mutex list_lock; +/* Addresses scanned for juniper_i2c_cpld + */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +static int get_sfp_spec(int model, u16 *num, u8 *types) +{ + switch (model) { + case AS7712_32X: + case AS7716_32X: + *num = 32; + *types = HAS_QSFP; + break; + case qfx5210_64X: + *num = 64; + *types = HAS_QSFP; + break; + case AS7312_54X: + *num = 54; + *types = HAS_QSFP|HAS_SFP; + default: + *types = 0; + *num = 0; + break; + } + + return 0; +} + +static int get_present_reg(int model, u8 port, u8 *cpld_addr, u8 *reg, u8 *num) +{ + u8 cpld_address[] = CPLD_ADDRS; + + switch (model) { + case AS7312_54X: + if (port < 48) { + *cpld_addr = cpld_address[1 + port/24]; + *reg = 0x09 + (port%24)/8; + *num = 8; + } + else + { + *reg = 0x18; + *num = 4; + *cpld_addr = ( port < 52)? cpld_address[1]: cpld_address[2]; + } + break; + default: + return -EINVAL; + } +} + + +/*Assume the bits for ports are listed in-a-row.*/ +static int get_reg_bit(u8 reg_start, int port, + u8 *reg ,u8 *mask) +{ + *reg = reg_start + ((port)/8); + *mask = 1 << ((port)%8); + + return 0; +} + +static int cpld_write_internal( + struct i2c_client *client, u8 reg, u8 value) +{ + int status = 0, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_write_byte_data(client, reg, value); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + return status; +} + +static int cpld_read_internal(struct i2c_client *client, u8 reg) +{ + int status = 0, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_read_byte_data(client, reg); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + return status; +} + + +/*Turn a numberic array into string with " " between each element. + * e.g., {0x11, 0x33, 0xff, 0xf1} => "11 33 ff f1" + */ +static ssize_t array_stringify(char *buf, u8 *input, size_t size) { + + int i; + char t[MAX_RESP_LENGTH+1]; + + buf[0] = '\0'; + for (i = 0; i < size; i++) { + snprintf(t, MAX_RESP_LENGTH, "%x ", input[i]); + strncat(buf, t, MAX_RESP_LENGTH); + } + + if (strlen(buf) > 0) + buf[strlen(buf)-1] = '\0'; /*Remove tailing blank*/ + + return snprintf(buf, MAX_RESP_LENGTH, "%s\n", buf); +} + +static ssize_t show_presnet_all_distinct(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 i, value, reg; + u8 cpld_addr, num; + u8 _value[8]; + u64 *values = (u64 *)_value; + + values = 0; + mutex_lock(&data->update_lock); + while(i < data->sfp_num) + { + get_present_reg(data->model, i, &cpld_addr, ®, &num); + if(cpld_addr == client->addr) + value = cpld_read_internal(client, reg); + else + value = juniper_i2c_cpld_read(cpld_addr, reg); + + if (unlikely(value < 0)) { + goto exit; + } + + *values |= (value&((1<<(num))-1)) << i; + i += num; + } + mutex_unlock(&data->update_lock); + + *values = cpu_to_le64(*values); + return array_stringify(buf, _value, i); +exit: + mutex_unlock(&data->update_lock); + return value; +} + +static ssize_t show_presnet_all(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + struct cpld_sensor *sensor = to_cpld_sensor(devattr); + u8 i, values[MAX_RESP_LENGTH/8]; + + if (sensor->reg < 0) { + return show_presnet_all_distinct(dev, devattr, buf); + } + + mutex_lock(&data->update_lock); + for (i = 0; i < ((data->sfp_num+7)/8); i++) { + values[i] = cpld_read_internal(client, sensor->reg + i); + if (unlikely(values[i] < 0)) { + goto exit; + } + } + mutex_unlock(&data->update_lock); + return array_stringify(buf, values, i); + +exit: + mutex_unlock(&data->update_lock); + return values[i]; +} + +static ssize_t show_bit(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int value; + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + struct cpld_sensor *sensor = to_cpld_sensor(devattr); + + mutex_lock(&data->update_lock); + value = cpld_read_internal(client, sensor->reg); + value = value & sensor->mask; + if (sensor->invert) + value = !value; + mutex_unlock(&data->update_lock); + + return snprintf(buf, PAGE_SIZE, "%x\n", value); +} + +static ssize_t set_1bit(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + long is_reset; + int value, status; + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + struct cpld_sensor *sensor = to_cpld_sensor(devattr); + u8 cpld_bit, reg; + + status = kstrtol(buf, 10, &is_reset); + if (status) { + return status; + } + reg = sensor->reg; + cpld_bit = sensor->mask; + mutex_lock(&data->update_lock); + value = cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + + if (sensor->invert) + is_reset = !is_reset; + + if (is_reset) { + value |= cpld_bit; + } + else { + value &= ~cpld_bit; + } + + status = cpld_write_internal(client, reg, value); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t set_byte(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + return access(dev, da, buf, count); +} + +static ssize_t access(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int status; + u32 addr, val; + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + + if (sscanf(buf, "0x%x 0x%x", &addr, &val) != 2) { + return -EINVAL; + } + + if (addr > 0xFF || val > 0xFF) { + return -EINVAL; + } + + mutex_lock(&data->update_lock); + status = cpld_write_internal(client, addr, val); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static void juniper_i2c_cpld_add_client(struct i2c_client *client) +{ + struct cpld_client_node *node = + kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL); + + if (!node) { + dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", + client->addr); + return; + } + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &cpld_client_list); + mutex_unlock(&list_lock); +} + +static void juniper_i2c_cpld_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client == client) { + found = 1; + break; + } + } + + if (found) { + list_del(list_node); + kfree(cpld_node); + } + + mutex_unlock(&list_lock); +} + +static int cpld_add_attribute(struct cpld_data *data, struct attribute *attr) +{ + int new_max_attrs = ++data->num_attributes + ATTR_ALLOC_SIZE; + void *new_attrs = krealloc(data->group.attrs, + new_max_attrs * sizeof(void *), + GFP_KERNEL); + if (!new_attrs) + return -ENOMEM; + data->group.attrs = new_attrs; + + + data->group.attrs[data->num_attributes-1] = attr; + data->group.attrs[data->num_attributes] = NULL; + + return 0; +} + +static void cpld_dev_attr_init(struct device_attribute *dev_attr, + const char *name, umode_t mode, + show_func show, store_func store) +{ + sysfs_attr_init(&dev_attr->attr); + dev_attr->attr.name = name; + dev_attr->attr.mode = mode; + dev_attr->show = show; + dev_attr->store = store; +} + +static struct cpld_sensor * add_sensor(struct cpld_data *data, + const char *name, + u8 reg, u8 mask, bool invert, + bool update, umode_t mode, + show_func get, store_func set) +{ + struct cpld_sensor *sensor; + struct device_attribute *a; + + sensor = devm_kzalloc(data->dev, sizeof(*sensor), GFP_KERNEL); + if (!sensor) + return NULL; + a = &sensor->attribute; + + snprintf(sensor->name, sizeof(sensor->name), name); + sensor->reg = reg; + sensor->mask = mask; + sensor->update = update; + sensor->invert = invert; + cpld_dev_attr_init(a, sensor->name, + mode, + get, set); + + if (cpld_add_attribute(data, &a->attr)) + return NULL; + + sensor->next = data->sensors; + data->sensors = sensor; + + return sensor; +} + +static int add_attributes_cmn(struct cpld_data *data, struct attrs **cmn) +{ + u8 reg, i ; + bool invert; + struct attrs *a; + struct base_attrs *b; + + if (NULL == cmn) + return -1; + + for (i = 0; cmn[i]; i++) + { + a = cmn[i]; + + reg = a->reg; + invert = a->invert; + + b = a->base; + if (NULL == b) + break; + + if (add_sensor(data, b->name, + reg, 0xff, invert, + true, b->mode, + b->get, b->set) == NULL) + { + return -ENOMEM; + } + } + return 0; +} + +static int add_attributes_portly(struct cpld_data *data, struct attrs **pa) +{ + char name[NAME_SIZE+1]; + int i, j; + u8 reg, mask, invert; + struct attrs *a; + struct base_attrs *b; + + if (NULL == pa) + return -1; + + + for (i = 0; pa[i]; i++) { + a = pa[i]; + + invert = a->invert; + b = a->base; + if (b == NULL) + break; + + for (j = 0; j < data->sfp_num; j++) + { + snprintf(name, NAME_SIZE, "%s_%d", b->name, j+1); + get_reg_bit(a->reg, j, ®, &mask); + + if (add_sensor(data, name, reg, mask, invert, + true, b->mode, b->get, b->set) == NULL) + { + return -ENOMEM; + } + } + } + return 0; +} + +static int add_attributes(struct i2c_client *client, + struct cpld_data *data) +{ + struct model_attrs *m = data->cmn_attr; + + if (m == NULL) + return -EINVAL; + + /* Common attributes.*/ + add_attributes_cmn(data, m->cmn); + + /* Port-wise attributes.*/ + add_attributes_portly(data, m->portly); + + return 0; +} + +static int juniper_i2c_cpld_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + int status; + struct cpld_data *data = NULL; + struct device *dev = &client->dev; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_dbg(dev, "i2c_check_functionality failed (0x%x)\n", client->addr); + return -EIO; + } + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) { + return -ENOMEM; + } + + data->model = dev_id->driver_data; + data->cmn_attr = &models_attr[data->model]; + get_sfp_spec(data->model, &data->sfp_num, &data->sfp_types); + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + data->dev = dev; + dev_info(dev, "chip found\n"); + + status = add_attributes(client, data); + if (status) + goto out_kfree; + + /* + * If there are no attributes, something is wrong. + * Bail out instead of trying to register nothing. + */ + if (!data->num_attributes) { + dev_err(dev, "No attributes found\n"); + status = -ENODEV; + goto out_kfree; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &data->group); + if (status) { + goto out_kfree; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + juniper_i2c_cpld_add_client(client); + dev_info(dev, "%s: cpld '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; +exit_remove: + sysfs_remove_group(&client->dev.kobj, &data->group); +out_kfree: + kfree(data->group.attrs); + return status; + +} + +static int juniper_i2c_cpld_remove(struct i2c_client *client) +{ + struct cpld_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &data->group); + kfree(data->group.attrs); + juniper_i2c_cpld_remove_client(client); + return 0; +} + +int juniper_i2c_cpld_read(u8 cpld_addr, u8 reg) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EPERM; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = i2c_smbus_read_byte_data(cpld_node->client, reg); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(juniper_i2c_cpld_read); + +int juniper_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EIO; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = i2c_smbus_write_byte_data(cpld_node->client, reg, value); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(juniper_i2c_cpld_write); + + +static const struct i2c_device_id juniper_i2c_cpld_id[] = { + { "cpld_as7712", AS7712_32X}, + { "cpld_as7716", AS7716_32X}, + { "cpld_qfx5210", qfx5210_64X}, + { "cpld_as7312", AS7312_54X}, + { "cpld_plain", PLAIN_CPLD}, + { }, +}; +MODULE_DEVICE_TABLE(i2c, juniper_i2c_cpld_id); + +static struct i2c_driver juniper_i2c_cpld_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "juniper_i2c_cpld", + }, + .probe = juniper_i2c_cpld_probe, + .remove = juniper_i2c_cpld_remove, + .id_table = juniper_i2c_cpld_id, + .address_list = normal_i2c, +}; + + +static int __init juniper_i2c_cpld_init(void) +{ + mutex_init(&list_lock); + return i2c_add_driver(&juniper_i2c_cpld_driver); +} + +static void __exit juniper_i2c_cpld_exit(void) +{ + i2c_del_driver(&juniper_i2c_cpld_driver); +} + +module_init(juniper_i2c_cpld_init); +module_exit(juniper_i2c_cpld_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("juniper_i2c_cpld driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/x86-64-juniper-qfx5210-64x-leds.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/x86-64-juniper-qfx5210-64x-leds.c index 66d097734392..51ce772c5e80 100644 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/x86-64-juniper-qfx5210-64x-leds.c +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/x86-64-juniper-qfx5210-64x-leds.c @@ -37,7 +37,6 @@ extern int juniper_i2c_cpld_read (u8 cpld_addr, u8 reg); extern int juniper_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); extern void led_classdev_unregister(struct led_classdev *led_cdev); -extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); extern void led_classdev_resume(struct led_classdev *led_cdev); extern void led_classdev_suspend(struct led_classdev *led_cdev); diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/x86-64-juniper-qfx5210-64x-psu.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/x86-64-juniper-qfx5210-64x-psu.c index cb283d2d4a1c..49a0cbbcebdd 100644 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/x86-64-juniper-qfx5210-64x-psu.c +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/x86-64-juniper-qfx5210-64x-psu.c @@ -306,7 +306,7 @@ static void __exit qfx5210_64x_psu_exit(void) /* * Unregister the cpld soft reset handler */ - if (!unregister_restart_handler(&qfx5210_nb)) { + if (unregister_reboot_notifier(&qfx5210_nb)) { printk(KERN_CRIT "Failed to uregister restart handler\n"); } diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/ym2651y.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/ym2651y.c deleted file mode 120000 index f4d67640ccc3..000000000000 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/ym2651y.c +++ /dev/null @@ -1 +0,0 @@ -../../common/modules/ym2651y.c \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/ym2651y.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/ym2651y.c new file mode 100644 index 000000000000..3ade5684107a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/ym2651y.c @@ -0,0 +1,622 @@ +/* + * An hwmon driver for the 3Y Power YM-2651Y Power Module + * + * Tested and validated on Juniper QFX5210 + * Ciju Rajan K + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_FAN_DUTY_CYCLE 100 + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { 0x58, 0x5b, I2C_CLIENT_END }; + +enum chips { + YM2651, + YM2401, + YM2851, +}; + +/* Each client has this additional data + */ +struct ym2651y_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 capability; /* Register value */ + u16 status_word; /* Register value */ + u8 fan_fault; /* Register value */ + u8 over_temp; /* Register value */ + u16 v_out; /* Register value */ + u16 i_out; /* Register value */ + u16 p_out; /* Register value */ + u16 temp; /* Register value */ + u16 fan_speed; /* Register value */ + u16 fan_duty_cycle[2]; /* Register value */ + u8 fan_dir[4]; /* Register value */ + u8 pmbus_revision; /* Register value */ + u8 mfr_id[10]; /* Register value */ + u8 mfr_model[10]; /* Register value */ + u8 mfr_revsion[3]; /* Register value */ + u16 mfr_vin_min; /* Register value */ + u16 mfr_vin_max; /* Register value */ + u16 mfr_iin_max; /* Register value */ + u16 mfr_iout_max; /* Register value */ + u16 mfr_pin_max; /* Register value */ + u16 mfr_pout_max; /* Register value */ + u16 mfr_vout_min; /* Register value */ + u16 mfr_vout_max; /* Register value */ +}; + +static ssize_t show_byte(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_word(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_linear(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_over_temp(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_ascii(struct device *dev, struct device_attribute *da, + char *buf); +static struct ym2651y_data *ym2651y_update_device(struct device *dev); +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value); + +enum ym2651y_sysfs_attributes { + PSU_POWER_ON = 0, + PSU_TEMP_FAULT, + PSU_POWER_GOOD, + PSU_FAN1_FAULT, + PSU_FAN_DIRECTION, + PSU_OVER_TEMP, + PSU_V_OUT, + PSU_I_OUT, + PSU_P_OUT, + PSU_P_OUT_UV, /*In Unit of microVolt, instead of mini.*/ + PSU_TEMP1_INPUT, + PSU_FAN1_SPEED, + PSU_FAN1_DUTY_CYCLE, + PSU_PMBUS_REVISION, + PSU_MFR_ID, + PSU_MFR_MODEL, + PSU_MFR_REVISION, + PSU_MFR_VIN_MIN, + PSU_MFR_VIN_MAX, + PSU_MFR_VOUT_MIN, + PSU_MFR_VOUT_MAX, + PSU_MFR_IIN_MAX, + PSU_MFR_IOUT_MAX, + PSU_MFR_PIN_MAX, + PSU_MFR_POUT_MAX +}; + +/* sysfs attributes for hwmon + */ +static SENSOR_DEVICE_ATTR(psu_power_on, S_IRUGO, show_word, NULL, PSU_POWER_ON); +static SENSOR_DEVICE_ATTR(psu_temp_fault, S_IRUGO, show_word, NULL, PSU_TEMP_FAULT); +static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_word, NULL, PSU_POWER_GOOD); +static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, show_fan_fault, NULL, PSU_FAN1_FAULT); +static SENSOR_DEVICE_ATTR(psu_over_temp, S_IRUGO, show_over_temp, NULL, PSU_OVER_TEMP); +static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, show_linear, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, show_linear, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, show_linear, NULL, PSU_P_OUT); +static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, show_linear, NULL, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED); +static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, show_linear, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE); +static SENSOR_DEVICE_ATTR(psu_fan_dir, S_IRUGO, show_ascii, NULL, PSU_FAN_DIRECTION); +static SENSOR_DEVICE_ATTR(psu_pmbus_revision, S_IRUGO, show_byte, NULL, PSU_PMBUS_REVISION); +static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, show_ascii, NULL, PSU_MFR_ID); +static SENSOR_DEVICE_ATTR(psu_mfr_model, S_IRUGO, show_ascii, NULL, PSU_MFR_MODEL); +static SENSOR_DEVICE_ATTR(psu_mfr_revision, S_IRUGO, show_ascii, NULL, PSU_MFR_REVISION); +static SENSOR_DEVICE_ATTR(psu_mfr_vin_min, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MIN); +static SENSOR_DEVICE_ATTR(psu_mfr_vin_max, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_vout_min, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MIN); +static SENSOR_DEVICE_ATTR(psu_mfr_vout_max, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_iin_max, S_IRUGO, show_linear, NULL, PSU_MFR_IIN_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_iout_max, S_IRUGO, show_linear, NULL, PSU_MFR_IOUT_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_pin_max, S_IRUGO, show_linear, NULL, PSU_MFR_PIN_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_pout_max, S_IRUGO, show_linear, NULL, PSU_MFR_POUT_MAX); + +/*Duplicate nodes for lm-sensors.*/ +static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_linear, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, show_linear, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(power2_input, S_IRUGO, show_linear, NULL, PSU_P_OUT_UV); +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_linear, NULL, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED); +static SENSOR_DEVICE_ATTR(temp1_fault, S_IRUGO, show_word, NULL, PSU_TEMP_FAULT); + +static struct attribute *ym2651y_attributes[] = { + &sensor_dev_attr_psu_power_on.dev_attr.attr, + &sensor_dev_attr_psu_temp_fault.dev_attr.attr, + &sensor_dev_attr_psu_power_good.dev_attr.attr, + &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, + &sensor_dev_attr_psu_over_temp.dev_attr.attr, + &sensor_dev_attr_psu_v_out.dev_attr.attr, + &sensor_dev_attr_psu_i_out.dev_attr.attr, + &sensor_dev_attr_psu_p_out.dev_attr.attr, + &sensor_dev_attr_psu_temp1_input.dev_attr.attr, + &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, + &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, + &sensor_dev_attr_psu_fan_dir.dev_attr.attr, + &sensor_dev_attr_psu_pmbus_revision.dev_attr.attr, + &sensor_dev_attr_psu_mfr_id.dev_attr.attr, + &sensor_dev_attr_psu_mfr_model.dev_attr.attr, + &sensor_dev_attr_psu_mfr_revision.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vin_min.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vin_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_pout_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_iin_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_pin_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vout_min.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vout_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_iout_max.dev_attr.attr, + /*Duplicate nodes for lm-sensors.*/ + &sensor_dev_attr_curr2_input.dev_attr.attr, + &sensor_dev_attr_in3_input.dev_attr.attr, + &sensor_dev_attr_power2_input.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_temp1_fault.dev_attr.attr, + NULL +}; + +static ssize_t show_byte(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + + return (attr->index == PSU_PMBUS_REVISION) ? sprintf(buf, "%d\n", data->pmbus_revision) : + sprintf(buf, "0\n"); +} + +static ssize_t show_word(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + u16 status = 0; + + switch (attr->index) { + case PSU_POWER_ON: /* psu_power_on, low byte bit 6 of status_word, 0=>ON, 1=>OFF */ + status = (data->status_word & 0x40) ? 0 : 1; + break; + case PSU_TEMP_FAULT: /* psu_temp_fault, low byte bit 2 of status_word, 0=>Normal, 1=>temp fault */ + status = (data->status_word & 0x4) >> 2; + break; + case PSU_POWER_GOOD: /* psu_power_good, high byte bit 3 of status_word, 0=>OK, 1=>FAIL */ + status = (data->status_word & 0x800) ? 0 : 1; + break; + } + + return sprintf(buf, "%d\n", status); +} + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask) +{ + u16 valid_data = data & mask; + bool is_negative = valid_data >> (valid_bit - 1); + + return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; +} + +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct ym2651y_data *data = i2c_get_clientdata(client); + int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1; + long speed; + int error; + + error = kstrtol(buf, 10, &speed); + if (error) + return error; + + if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE) + return -EINVAL; + + mutex_lock(&data->update_lock); + data->fan_duty_cycle[nr] = speed; + ym2651y_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t show_linear(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + + u16 value = 0; + int exponent, mantissa; + int multiplier = 1000; + + switch (attr->index) { + case PSU_V_OUT: + value = data->v_out; + break; + case PSU_I_OUT: + value = data->i_out; + break; + case PSU_P_OUT_UV: + multiplier = 1000000; /*For lm-sensors, unit is micro-Volt.*/ + /*Passing through*/ + case PSU_P_OUT: + value = data->p_out; + break; + case PSU_TEMP1_INPUT: + value = data->temp; + break; + case PSU_FAN1_SPEED: + value = data->fan_speed; + multiplier = 1; + break; + case PSU_FAN1_DUTY_CYCLE: + value = data->fan_duty_cycle[0]; + multiplier = 1; + break; + case PSU_MFR_VIN_MIN: + value = data->mfr_vin_min; + break; + case PSU_MFR_VIN_MAX: + value = data->mfr_vin_max; + break; + case PSU_MFR_VOUT_MIN: + value = data->mfr_vout_min; + break; + case PSU_MFR_VOUT_MAX: + value = data->mfr_vout_max; + break; + case PSU_MFR_PIN_MAX: + value = data->mfr_pin_max; + break; + case PSU_MFR_POUT_MAX: + value = data->mfr_pout_max; + break; + case PSU_MFR_IOUT_MAX: + value = data->mfr_iout_max; + break; + case PSU_MFR_IIN_MAX: + value = data->mfr_iin_max; + break; + } + + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + + u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; + + return sprintf(buf, "%d\n", data->fan_fault >> shift); +} + +static ssize_t show_over_temp(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct ym2651y_data *data = ym2651y_update_device(dev); + + return sprintf(buf, "%d\n", data->over_temp >> 7); +} + +static ssize_t show_ascii(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + u8 *ptr = NULL; + + switch (attr->index) { + case PSU_FAN_DIRECTION: /* psu_fan_dir */ + ptr = data->fan_dir; + break; + case PSU_MFR_ID: /* psu_mfr_id */ + ptr = data->mfr_id; + break; + case PSU_MFR_MODEL: /* psu_mfr_model */ + ptr = data->mfr_model; + break; + case PSU_MFR_REVISION: /* psu_mfr_revision */ + ptr = data->mfr_revsion; + break; + default: + return 0; + } + + return sprintf(buf, "%s\n", ptr); +} + +static const struct attribute_group ym2651y_group = { + .attrs = ym2651y_attributes, +}; + +static int ym2651y_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct ym2651y_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA | + I2C_FUNC_SMBUS_I2C_BLOCK)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct ym2651y_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &ym2651y_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &ym2651y_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int ym2651y_remove(struct i2c_client *client) +{ + struct ym2651y_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &ym2651y_group); + kfree(data); + + return 0; +} + +static const struct i2c_device_id ym2651y_id[] = { + { "ym2651", YM2651 }, + { "ym2401", YM2401 }, + { "ym2851", YM2851 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, ym2651y_id); + +static struct i2c_driver ym2651y_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "ym2651", + }, + .probe = ym2651y_probe, + .remove = ym2651y_remove, + .id_table = ym2651y_id, + .address_list = normal_i2c, +}; + +static int ym2651y_read_byte(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int ym2651y_read_word(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_word_data(client, reg); +} + +static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value) +{ + return i2c_smbus_write_word_data(client, reg, value); +} + +static int ym2651y_read_block(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ + int result = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + + if (unlikely(result < 0)) + goto abort; + if (unlikely(result != data_len)) { + result = -EIO; + goto abort; + } + + result = 0; + +abort: + return result; +} + +struct reg_data_byte { + u8 reg; + u8 *value; +}; + +struct reg_data_word { + u8 reg; + u16 *value; +}; + +static struct ym2651y_data *ym2651y_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct ym2651y_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int i, status; + u8 command; + u8 fan_dir[5] = {0}; + struct reg_data_byte regs_byte[] = { {0x19, &data->capability}, + {0x7d, &data->over_temp}, + {0x81, &data->fan_fault}, + {0x98, &data->pmbus_revision} + }; + struct reg_data_word regs_word[] = { {0x79, &data->status_word}, + {0x8b, &data->v_out}, + {0x8c, &data->i_out}, + {0x96, &data->p_out}, + {0x8d, &data->temp}, + {0x3b, &(data->fan_duty_cycle[0])}, + {0x3c, &(data->fan_duty_cycle[1])}, + {0x90, &data->fan_speed}, + {0xa0, &data->mfr_vin_min}, + {0xa1, &data->mfr_vin_max}, + {0xa2, &data->mfr_iin_max}, + {0xa3, &data->mfr_pin_max}, + {0xa4, &data->mfr_vout_min}, + {0xa5, &data->mfr_vout_max}, + {0xa6, &data->mfr_iout_max}, + {0xa7, &data->mfr_pout_max} + }; + + dev_dbg(&client->dev, "Starting ym2651 update\n"); + + /* Read byte data */ + for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { + status = ym2651y_read_byte(client, regs_byte[i].reg); + + if (status < 0) + { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_byte[i].reg, status); + *(regs_byte[i].value) = 0; + } + else { + *(regs_byte[i].value) = status; + } + } + + /* Read word data */ + for (i = 0; i < ARRAY_SIZE(regs_word); i++) { + status = ym2651y_read_word(client, regs_word[i].reg); + + if (status < 0) + { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_word[i].reg, status); + *(regs_word[i].value) = 0; + } + else { + *(regs_word[i].value) = status; + } + } + + /* Read fan_direction */ + command = 0xC3; + status = ym2651y_read_block(client, command, fan_dir, ARRAY_SIZE(fan_dir)-1); + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + } + + strncpy(data->fan_dir, fan_dir+1, ARRAY_SIZE(data->fan_dir)-1); + data->fan_dir[ARRAY_SIZE(data->fan_dir)-1] = '\0'; + + /* Read mfr_id */ + command = 0x99; + status = ym2651y_read_block(client, command, data->mfr_id, + ARRAY_SIZE(data->mfr_id)-1); + data->mfr_id[ARRAY_SIZE(data->mfr_id)-1] = '\0'; + + if (status < 0) + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + + /* Read mfr_model */ + command = 0x9a; + status = ym2651y_read_block(client, command, data->mfr_model, + ARRAY_SIZE(data->mfr_model)-1); + data->mfr_model[ARRAY_SIZE(data->mfr_model)-1] = '\0'; + + if (status < 0) + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + + /* Read mfr_revsion */ + command = 0x9b; + status = ym2651y_read_block(client, command, data->mfr_revsion, + ARRAY_SIZE(data->mfr_revsion)-1); + data->mfr_revsion[ARRAY_SIZE(data->mfr_revsion)-1] = '\0'; + + if (status < 0) + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +module_i2c_driver(ym2651y_driver); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("3Y Power YM-2651Y driver"); +MODULE_LICENSE("GPL"); + + diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/service/qfx5210-platform-init.service b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/service/qfx5210-platform-init.service old mode 100755 new mode 100644 diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/setup.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/setup.py deleted file mode 100755 index 536f814a3509..000000000000 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/setup.py +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env python - -import os -import sys -from setuptools import setup -os.listdir - -setup( - name='sonic_platform', - version='1.0', - description='Module to initialize Juniper QFX5210-64X platforms', - - packages=['sonic_platform'], - package_dir={'sonic_platform': 'qfx5210/sonic_platform'}, -) - diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/chassis.py deleted file mode 100755 index 674d9184df3c..000000000000 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/chassis.py +++ /dev/null @@ -1,277 +0,0 @@ -#!/usr/bin/env python -# -# Name: chassis.py, version: 1.0 -# -# Description: Module contains the definitions of SONiC platform APIs -# which provide the chassis specific details -# -# Copyright (c) 2019, Juniper Networks, Inc. -# All rights reserved. -# -# Notice and Disclaimer: This code is licensed to you under the GNU General -# Public License as published by the Free Software Foundation, version 3 or -# any later version. This code is not an official Juniper product. You can -# obtain a copy of the License at -# -# OSS License: -# -# This program is free software: you can 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 . -# -# Third-Party Code: This code may depend on other components under separate -# copyright notice and license terms. Your use of the source code for those -# components is subject to the terms and conditions of the respective license -# as noted in the Third-Party source code file. -# - -try: - import os - import commands - import sys - import time - from sonic_platform_base.chassis_base import ChassisBase -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - - -class Chassis(ChassisBase): - """ - JUNIPER QFX5210 Platform-specific Chassis class - """ - - # Find the last reboot reason out of following - # CPLD_WATCHDOG_RESET 0x08 - # POWER_ON_RESET 0x20 - # CPU_WATCHDOG_RESET 0x40 - # SOFTWARE_RESET 0x80 - - def __init__(self): - ChassisBase.__init__(self) - - def get_qfx5210_parameter_value(self,parameter_name): - try: - with open("/var/run/eeprom", "r") as file: - for item in file: - content = item.split('=') - if content[0] == parameter_name: - return content[1:] - return "False" - except IOError: - print "Error: File not found" - return "False" - - def get_product_name(self): - product_name_list = self.get_qfx5210_parameter_value('Product Name') - if product_name_list: - product_name = ''.join(product_name_list) - return product_name - else: - return False - - - def get_part_number(self): - part_number_list = self.get_qfx5210_parameter_value('Part Number') - if part_number_list: - part_number = ''.join(part_number_list) - return part_number - else: - return False - - - def get_serial_number(self): - serial_number_list = self.get_qfx5210_parameter_value('Serial Number') - if serial_number_list: - serial_number = ''.join(serial_number_list) - return serial_number - else: - return False - - - def get_base_mac(self): - mac_list = self.get_qfx5210_parameter_value('MAC') - if mac_list: - mac = ''.join(mac_list) - return mac - else: - return False - - - def get_mfg_date(self): - mfgdate_list = self.get_qfx5210_parameter_value('Manufacture Date') - if mfgdate_list: - mfgdate = ''.join(mfgdate_list) - return mfgdate - else: - return False - - def get_deviceversion_name(self): - device_version_list = self.get_qfx5210_parameter_value('Device Version') - if device_version_list: - deviceversion_name = ''.join(device_version_list) - return deviceversion_name - else: - return False - - def get_platform_name(self): - platform_name_list = self.get_qfx5210_parameter_value('Platform Name') - if platform_name_list: - platform_name = ''.join(platform_name_list) - return platform_name - else: - return False - - def get_MACnumber_name(self): - MACnumber_name_list = self.get_qfx5210_parameter_value('Number of MAC Addresses') - if MACnumber_name_list: - MACnumber_name = ''.join(MACnumber_name_list) - return MACnumber_name - else: - return False - - def get_vendor_name(self): - vendor_name_list = self.get_qfx5210_parameter_value('Vendor Name') - if vendor_name_list: - vendor_name = ''.join(vendor_name_list) - return vendor_name - else: - return False - - def get_mfg_name(self): - mfg_name_list = self.get_qfx5210_parameter_value('Manufacture Name') - if mfg_name_list: - mfg_name = ''.join(mfg_name_list) - return mfg_name - else: - return False - - def get_vendorext_name(self): - vendorext_list = self.get_qfx5210_parameter_value('Vendor Extension') - if vendorext_list: - vendorext = ''.join(vendorext_list) - return vendorext - else: - return False - - def get_vendorextIANA_name(self): - vendorext_list = self.get_qfx5210_parameter_value('IANA') - if vendorext_list: - vendorext = ''.join(vendorext_list) - return vendorext - else: - return False - - def get_vendorextASMREV_name(self): - vendorext_list = self.get_qfx5210_parameter_value('Assembly Part Number Rev') - if vendorext_list: - vendorext = ''.join(vendorext_list) - return vendorext - else: - return False - - def get_vendorextASMPartNum_name(self): - vendorext_list = self.get_qfx5210_parameter_value('Assembly Part Number') - if vendorext_list: - vendorext = ''.join(vendorext_list) - return vendorext - else: - return False - - def get_vendorextASMID_name(self): - vendorext_list = self.get_qfx5210_parameter_value('Assembly ID') - if vendorext_list: - vendorext = ''.join(vendorext_list) - return vendorext - else: - return False - - def get_vendorextASMMajNum_name(self): - vendorext_list = self.get_qfx5210_parameter_value('Assembly Major Revision') - if vendorext_list: - vendorext = ''.join(vendorext_list) - return vendorext - else: - return False - - def get_vendorextASMMinNum_name(self): - vendorext_list = self.get_qfx5210_parameter_value('Assembly Minor Revision') - if vendorext_list: - vendorext = ''.join(vendorext_list) - return vendorext - else: - return False - - def get_vendorextCLEI_name(self): - vendorext_list = self.get_qfx5210_parameter_value('CLEI code') - if vendorext_list: - vendorext = ''.join(vendorext_list) - return vendorext - else: - return False - - def get_onieversion_name(self): - onieversion_name_list = self.get_qfx5210_parameter_value('ONIE Version') - if onieversion_name_list: - onieversion_name = ''.join(onieversion_name_list) - return onieversion_name - else: - return False - - def get_crc_name(self): - crc_list = self.get_qfx5210_parameter_value('CRC') - if crc_list: - crc_name = ''.join(crc_list) - return crc_name - else: - return False - - def get_fan_type(self, fantype_path): - try: - fan_type_file = open(fantype_path) - except IOError as e: - print "Error: unable to open file: %s" % str(e) - return "-1" - else: - fan_type = fan_type_file.read() - fan_type_file.close() - return str(fan_type) - - - def get_reboot_cause(self): - """ - Retrieves the cause of the previous reboot - """ - status, last_reboot_reason = commands.getstatusoutput("i2cget -y 0 0x65 0x24") - if (status == 0): - if last_reboot_reason == "0x80": - return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) - elif last_reboot_reason == "0x40" or last_reboot_reason == "0x08": - return (ChassisBase.REBOOT_CAUSE_WATCHDOG, None) - elif last_reboot_reason == "0x20": - return (ChassisBase.REBOOT_CAUSE_POWER_LOSS, None) - elif last_reboot_reason == "0x10": - return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Swizzle Reset") - else: - return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Unknown reason") - else: - time.sleep(3) - status, last_reboot_reason = commands.getstatusoutput("i2cget -y 0 0x65 0x24") - if last_reboot_reason == "0x80": - return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) - elif last_reboot_reason == "0x40" or last_reboot_reason == "0x08": - return (ChassisBase.REBOOT_CAUSE_WATCHDOG, None) - elif last_reboot_reason == "0x20": - return (ChassisBase.REBOOT_CAUSE_POWER_LOSS, None) - elif last_reboot_reason == "0x10": - return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Swizzle Reset") - else: - return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Unknown reason") diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/platform.py deleted file mode 100755 index 5620fec54f65..000000000000 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/platform.py +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env python -# -# Name: platform.py, version: 1.0 -# -# Description: Module contains the definitions of SONiC platform APIs -# which provide the platform specific details -# -# Copyright (c) 2019, Juniper Networks, Inc. -# All rights reserved. -# -# Notice and Disclaimer: This code is licensed to you under the GNU General -# Public License as published by the Free Software Foundation, version 3 or -# any later version. This code is not an official Juniper product. You can -# obtain a copy of the License at -# -# OSS License: -# -# This program is free software: you can 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 . -# -# Third-Party Code: This code may depend on other components under separate -# copyright notice and license terms. Your use of the source code for those -# components is subject to the terms and conditions of the respective license -# as noted in the Third-Party source code file. -# - - -import sys - -try: - from sonic_platform_base.platform_base import PlatformBase -except ImportError as e: - raise ImportError("%s - required module not found" % e) - -platformDict = {'platform':'QFX5210-64C'} - -class Platform(PlatformBase): - def __init__(self): - self.platform = self.getPlatform() - - def getPlatformDict(self): - global platformDict - if platformDict: - return platformDict - - def readPlatformName(self): - return self.getPlatformDict().get('platform') - - def getPlatform(self): - platformCls = self.readPlatformName() - return platformCls - - def get_chassis(self): - from chassis import Chassis - chassis = Chassis() - return chassis - 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 97adf9588f9f..77eac5234257 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 @@ -35,20 +35,12 @@ try: import os import commands - import sys, getopt import subprocess - import click - import imp import logging import logging.config import logging.handlers - import types import time - import traceback import glob - import collections - import StringIO - from tabulate import tabulate except ImportError as e: raise ImportError('%s - required module not found' % str(e)) @@ -58,17 +50,16 @@ verbose = False DEBUG = False -global log_file -global log_level +log_file = '%s.log' % FUNCTION_NAME +log_level = logging.DEBUG - -global isPlatformAFI -global is80PerFlag -global is60PerFlag -global isFireThresholdReached -global isFireThresholdPrint -global PrevASICValue -global FireThresholdSecsRemaining +isPlatformAFI = False +is80PerFlag = True +is60PerFlag = True +isFireThresholdReached = False +isFireThresholdPrint = True +PrevASICValue = 0 +FireThresholdSecsRemaining = 120 temp_policy_AFI = { 0: [[70, 0, 48000], [70, 48000, 53000], [80, 53000, 0], [80, 53000, 58000], [100, 58000, 0], ['Yellow Alarm', 64000, 70000], ['Red Alarm', 70000, 75000], ['Fire Shut Alarm', 75000, 0]], @@ -201,7 +192,7 @@ def _get_sensor_node_val(self, thermal_num): try: val_file.close() - except: + except IOError as e: logging.debug('get_sensor_node_val: unable to close file. device_path:%s', device_path) return None @@ -227,8 +218,8 @@ def _get_coretemp_node_val(self, thermal_num): return None try: - val_file.close() - except: + val_file.close() + except IOError as e: logging.debug('get_coretemp_node_val: unable to close file. device_path:%s', device_path) return None @@ -326,7 +317,7 @@ def getSensorTemp(self): isFireThresholdReached == False time.sleep(20) cmd = "poweroff" - returned_value = os.system(cmd) + os.system(cmd) for x in range(self.SENSOR_CORETEMP_NUM_ON_MAIN_BOARD): if x < self.SENSOR_NUM_ON_MAIN_BOARD: @@ -340,7 +331,7 @@ def getSensorTemp(self): proc = subprocess.Popen("bcmcmd \"show temp\" | grep \"maximum peak temperature\" | awk '{ print $5 }' > /var/log/asic_value 2>&1 & ",shell=True) time.sleep(2) cmd = "kill -9 %s"%(proc.pid) - status, cmd_out = commands.getstatusoutput(cmd) + commands.getstatusoutput(cmd) if os.stat("/var/log/asic_value").st_size == 0: value = PrevASICValue @@ -531,13 +522,6 @@ class device_monitor(object): def __init__(self, log_file, log_level): global DEBUG - global isPlatformAFI - global isFireThresholdReached - global is80PerFlag - global is60PerFlag - global isFireThresholdPrint - global PrevASICValue - global FireThresholdSecsRemaining MASTER_LED_PATH = '/sys/class/leds/master/brightness' SYSTEM_LED_PATH = '/sys/class/leds/system/brightness' FANTYPE_PATH = '/sys/bus/i2c/devices/17-0068/fan1_direction' @@ -561,33 +545,32 @@ def __init__(self, log_file, log_level): console.setFormatter(formatter) logging.getLogger('').addHandler(console) - import sonic_platform - platform = sonic_platform.platform.Platform() - chassis = platform.get_chassis() - fan_type = chassis.get_fan_type(FANTYPE_PATH) + try: + fan_type_file = open(FANTYPE_PATH) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + fan_type = -1 + else: + fan_type = fan_type_file.read() + fan_type_file.close() + # the return value of get_fan_type is AFO = 0, AFI = 1 and for error condition it is -1 # In the error condition also, we are making default platform as AFO, to continue with Energy Monitoring if (int(fan_type) == -1 or int(fan_type) == 0): + logging.debug('FANTYPE_PATH. fan_type %d', int(fan_type)) if (int(fan_type) == -1): logging.error('device_monitor: unable to open sys file for fan handling, defaulting it to AFO') isPlatformAFI = False else: isPlatformAFI = True - isFireThresholdReached = False - is80PerFlag = True - is60PerFlag = True - isFireThresholdPrint = True - FireThresholdSecsRemaining = 120 - PrevASICValue = 0 - master_led_value = 1 try: masterLED_file = open(MASTER_LED_PATH, 'r+') except IOError as e: logging.error('device_monitor: unable to open Master LED file: %s', str(e)) - return False + return masterLED_file.write(str(master_led_value)) masterLED_file.close() @@ -596,19 +579,16 @@ def __init__(self, log_file, log_level): systemLED_file = open(SYSTEM_LED_PATH, 'r+') except IOError as e: logging.error('device_monitor: unable to open System LED 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() thermal.getSensorTemp() def main(): - log_file = '%s.log' % FUNCTION_NAME - log_level = logging.DEBUG - + #Introducing sleep of 150 seconds to wait for all the docker containers to start before starting the EM policy. time.sleep(150) monitor = device_monitor(log_file, log_level) diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_util.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_util.py index b3f130af41c0..5479c0e04126 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_util.py +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_util.py @@ -39,11 +39,7 @@ import sys, getopt import binascii import logging -import re import time -import random -import optparse -from collections import namedtuple @@ -138,145 +134,16 @@ def main(): except OSError: print 'Error: Execution of "%s" failed', DisableWatchDogCmd return False - - - CPUeepromFileCmd = 'cat /sys/devices/pci0000:00/0000:00:1f.3/i2c-0/0-0056/eeprom > /etc/init.d/eeprom_qfx5210_ascii' - # Write the contents of CPU EEPROM to file + + time.sleep(1) + # Invoking the script which retrieves the data from Board EEPROM and storing in file + EEPROMDataCmd = 'python /usr/share/sonic/device/x86_64-juniper_qfx5210-r0/plugins/qfx5210_eeprom_data.py' try: - os.system(CPUeepromFileCmd) + os.system(EEPROMDataCmd) except OSError: - print 'Error: Execution of "%s" failed', CPUeepromFileCmd + print 'Error: Execution of "%s" failed', EEPROMDataCmd return False - eeprom_ascii = '/etc/init.d/eeprom_qfx5210_ascii' - # Read file contents in Hex format - with open(eeprom_ascii, 'rb') as Hexformat: - content = Hexformat.read() - Hexformatoutput = binascii.hexlify(content) - - eeprom_hex = '/etc/init.d/eeprom_qfx5210_hex' - #Write contents of CPU EEPROM to new file in hexa format - with open(eeprom_hex, 'wb+') as Hexfile: - Hexfile.write(Hexformatoutput) - - # Read from EEPROM Hex file and extract the different fields like Product name, - # Part Number, Serial Number MAC Address, Mfg Date ... etc and store in /var/run/eeprom file - with open(eeprom_hex, 'rb') as eeprom_hexfile: - # moving the file pointer to required position where product name is stored in EEPROM file and reading the required bytes from this position - - product_position = eeprom_hexfile.seek(26, 0) - product_read = eeprom_hexfile.read(36) - product_name = binascii.unhexlify(product_read) - - # creating the "/var/run/eeprom" file and storing all the values of different fields in this file. - eeprom_file = open ("/var/run/eeprom", "a+") - eeprom_file.write("Product Name=%s\r\n" % str(product_name)) - - # like wise we are moving the file pointer to respective position where other fields are stored and extract these fields and store in /var/run/eeprom file - partnumber_position = eeprom_hexfile.seek(66, 0) - partnumber_read = eeprom_hexfile.read(20) - partnumber_name = binascii.unhexlify(partnumber_read) - eeprom_file.write("Part Number=%s\r\n" % str(partnumber_name)) - - serialnumber_position = eeprom_hexfile.seek(90, 0) - serialnumber_read = eeprom_hexfile.read(24) - serialnumber_name = binascii.unhexlify(serialnumber_read) - eeprom_file.write("Serial Number=%s\r\n" % str(serialnumber_name)) - - macaddress_position = eeprom_hexfile.seek(118, 0) - macaddress_read = eeprom_hexfile.read(12) - macaddress_name="" - for i in range(0,12,2): - macaddress_name += macaddress_read[i:i+2] + ":" - macaddress_name=macaddress_name[:-1] - eeprom_file.write("MAC Address=%s\r\n" % str(macaddress_name)) - - mfgdate_position = eeprom_hexfile.seek(132, 0) - mfgdate_read = eeprom_hexfile.read(40) - mfgdate_name = binascii.unhexlify(mfgdate_read) - eeprom_file.write("Manufacture Date=%s\r\n" % str(mfgdate_name)) - - devversion_position = eeprom_hexfile.seek(176, 0) - devversion_read = eeprom_hexfile.read(2) - eeprom_file.write("Device Version=%s\r\n" % str(devversion_read)) - - platform_position = eeprom_hexfile.seek(182, 0) - platform_read = eeprom_hexfile.read(68) - platform_name = binascii.unhexlify(platform_read) - eeprom_file.write("Platform Name=%s\r\n" % str(platform_name)) - - MACnumber_position = eeprom_hexfile.seek(254, 0) - MACnumber_read = eeprom_hexfile.read(4) - MACnumber = int(MACnumber_read, 16) - eeprom_file.write("Number of MAC Addresses=%s\r\n" % str(MACnumber)) - - vendorName_position = eeprom_hexfile.seek(262, 0) - vendorName_read = eeprom_hexfile.read(40) - vendorName = binascii.unhexlify(vendorName_read) - eeprom_file.write("Vendor Name=%s\r\n" % str(vendorName)) - - mfgname_position = eeprom_hexfile.seek(306, 0) - mfgname_read = eeprom_hexfile.read(40) - mfgname = binascii.unhexlify(mfgname_read) - eeprom_file.write("Manufacture Name=%s\r\n" % str(mfgname)) - - vendorext_position = eeprom_hexfile.seek(350, 0) - vendorext_read = eeprom_hexfile.read(124) - vendorext="" - vendorext += "0x" + vendorext_read[0:2] - for i in range(2,124,2): - vendorext += " 0x" + vendorext_read[i:i+2] - eeprom_file.write("Vendor Extension=%s\r\n" % str(vendorext)) - - IANA_position = eeprom_hexfile.seek(350, 0) - IANA_read = eeprom_hexfile.read(8) - IANAName = binascii.unhexlify(IANA_read) - eeprom_file.write("IANA=%s\r\n" % str(IANAName)) - - ASMpartrev_position = eeprom_hexfile.seek(358, 0) - ASMpartrev_read = eeprom_hexfile.read(4) - ASMpartrev = binascii.unhexlify(ASMpartrev_read) - eeprom_file.write("Assembly Part Number Rev=%s\r\n" % str(ASMpartrev)) - - ASMpartnum_position = eeprom_hexfile.seek(374, 0) - ASMpartnum_read = eeprom_hexfile.read(20) - ASMpartnum_read = binascii.unhexlify(ASMpartnum_read) - eeprom_file.write("Assembly Part Number=%s\r\n" % str(ASMpartnum_read)) - - ASMID_position = eeprom_hexfile.seek(402, 0) - ASMID_read = eeprom_hexfile.read(4) - ASMID_read_upper = ASMID_read.upper() - eeprom_file.write("Assembly ID=0x%s\r\n" % str(ASMID_read_upper)) - - ASMHWMajRev_position = eeprom_hexfile.seek(410, 0) - ASMHWMajRev_read = eeprom_hexfile.read(2) - eeprom_file.write("Assembly Major Revision=0x%s\r\n" % str(ASMHWMajRev_read)) - - ASMHWMinRev_position = eeprom_hexfile.seek(416, 0) - ASMHWMinRev_read = eeprom_hexfile.read(2) - eeprom_file.write("Assembly Minor Revision=0x%s\r\n" % str(ASMHWMinRev_read)) - - Deviation_position = eeprom_hexfile.seek(422, 0) - Deviation_read = eeprom_hexfile.read(28) - Deviation_read_upper = Deviation_read.upper() - eeprom_file.write("Deviation=0x%s\r\n" % str(Deviation_read_upper)) - - CLEI_position = eeprom_hexfile.seek(450, 0) - CLEI_read = eeprom_hexfile.read(20) - CLEI_name = binascii.unhexlify(CLEI_read) - eeprom_file.write("CLEI code=%s\r\n" % str(CLEI_name)) - - ONIEversion_position = eeprom_hexfile.seek(478, 0) - ONIEversion_read = eeprom_hexfile.read(22) - ONIEversion = binascii.unhexlify(ONIEversion_read) - eeprom_file.write("ONIE Version=%s\r\n" % str(ONIEversion)) - - CRC_position = eeprom_hexfile.seek(504, 0) - CRC = eeprom_hexfile.read(8) - eeprom_file.write("CRC=%s\r\n" % str(CRC)) - - eeprom_file.close() - return True def show_help(): @@ -471,14 +338,12 @@ def system_ready(): def do_install(): logging.info('Checking system....') - if driver_check() == False: - logging.info('No driver, installing....') - status = driver_install() - if status: - if FORCE == 0: - return status - else: - print PROJECT_NAME.upper()+" drivers detected...." + + status = driver_install() + if status: + if FORCE == 0: + return status + if not device_exist(): logging.info('No device, installing....') status = device_install() @@ -486,7 +351,8 @@ def do_install(): if FORCE == 0: return status else: - print PROJECT_NAME.upper()+" devices detected...." + print PROJECT_NAME.upper()+" devices detected...." + return def do_uninstall(): @@ -618,7 +484,6 @@ def set_device(args): 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') diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/wrapper-fast-reboot b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/wrapper-fast-reboot new file mode 100755 index 000000000000..e1a32a52472f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/wrapper-fast-reboot @@ -0,0 +1,17 @@ +#!/bin/bash + +# Disable exit on non zero +set +e + +# Unloading this module as it contains the reboot +# notifier hook. When the kexec is invoked with platform +# reset handlers, it results in a cold reboot. Removing +# the reset handlers ensures that kernel does a kexec +# based fast reboot +rmmod x86-64-juniper-qfx5210-64x-psu > /dev/null 2>&1 + +/usr/bin/qfx5210-fast-reboot/fast-reboot $@ + +# Re-load the module if the fast-reboot script returns +# here +modprobe x86-64-juniper-qfx5210-64x-psu > /dev/null 2>&1 diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/wrapper-warm-reboot b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/wrapper-warm-reboot new file mode 100755 index 000000000000..8815efe0acae --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/wrapper-warm-reboot @@ -0,0 +1,17 @@ +#!/bin/bash + +# Disable exit on non zero +set +e + +# Unloading this module as it contains the reboot +# notifier hook. When the kexec is invoked with platform +# reset handlers, it results in a cold reboot. Removing +# the reset handlers ensures that kernel does a kexec +# based fast reboot +rmmod x86-64-juniper-qfx5210-64x-psu > /dev/null 2>&1 + +/usr/bin/qfx5210-warm-reboot/warm-reboot $@ + +# Re-load the module if the warm-reboot script returns +# here +modprobe x86-64-juniper-qfx5210-64x-psu > /dev/null 2>&1 diff --git a/platform/broadcom/sonic-platform-modules-juniper/setup.py b/platform/broadcom/sonic-platform-modules-juniper/setup.py new file mode 100755 index 000000000000..283c00d3860f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/setup.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python + +import os +import sys +from setuptools import setup +os.listdir + +setup( + name='sonic_platform', + version='1.0', + description='Module to initialize Juniper platforms', + + packages=['sonic_platform'], + package_dir={'sonic_platform': 'sonic_platform'}, +) + diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-juniper/sonic_platform/__init__.py similarity index 100% rename from platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/__init__.py rename to platform/broadcom/sonic-platform-modules-juniper/sonic_platform/__init__.py diff --git a/platform/broadcom/sonic-platform-modules-juniper/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-juniper/sonic_platform/chassis.py new file mode 100755 index 000000000000..4f673ab086ba --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/sonic_platform/chassis.py @@ -0,0 +1,310 @@ +#!/usr/bin/env python +# +# Name: chassis.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# which provide the chassis specific details +# +# Copyright (c) 2020, Juniper Networks, Inc. +# All rights reserved. +# +# Notice and Disclaimer: This code is licensed to you under the GNU General +# Public License as published by the Free Software Foundation, version 3 or +# any later version. This code is not an official Juniper product. You can +# obtain a copy of the License at +# +# OSS License: +# +# This program is free software: you can 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 . +# +# Third-Party Code: This code may depend on other components under separate +# copyright notice and license terms. Your use of the source code for those +# components is subject to the terms and conditions of the respective license +# as noted in the Third-Party source code file. +# + +try: + import os + import commands + import sys + import time + import syslog + from sonic_platform_base.chassis_base import ChassisBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +SYSLOG_IDENTIFIER = "Juniper-Chassis" + +def log_info(msg): + syslog.openlog(SYSLOG_IDENTIFIER) + syslog.syslog(syslog.LOG_INFO, msg) + syslog.closelog() + +class Chassis(ChassisBase): + + def __init__(self): + ChassisBase.__init__(self) + + def get_parameter_value(self,parameter_name): + try: + with open("/var/run/eeprom", "r") as file: + for item in file: + content = item.split('=') + if content[0] == parameter_name: + return content[1:] + return "False" + except IOError: + print "Error: File not found" + return "False" + + def get_product_name(self): + product_name_list = self.get_parameter_value('Product Name') + if product_name_list: + product_name = ''.join(product_name_list) + return product_name + else: + return False + + + def get_part_number(self): + part_number_list = self.get_parameter_value('Part Number') + if part_number_list: + part_number = ''.join(part_number_list) + return part_number + else: + return False + + + def get_serial(self): + serial_number_list = self.get_parameter_value('Serial Number') + if serial_number_list: + serial_number = ''.join(serial_number_list) + return serial_number + else: + return False + + + def get_base_mac(self): + mac_list = self.get_parameter_value('MAC') + if mac_list: + mac = ''.join(mac_list) + return mac + else: + return False + + + def get_mfg_date(self): + mfgdate_list = self.get_parameter_value('Manufacture Date') + if mfgdate_list: + mfgdate = ''.join(mfgdate_list) + return mfgdate + else: + return False + + def get_deviceversion_name(self): + device_version_list = self.get_parameter_value('Device Version') + if device_version_list: + deviceversion_name = ''.join(device_version_list) + return deviceversion_name + else: + return False + + def get_platform_name(self): + platform_name_list = self.get_parameter_value('Platform Name') + if platform_name_list: + platform_name = ''.join(platform_name_list) + return platform_name + else: + return False + + def get_MACnumber_name(self): + MACnumber_name_list = self.get_parameter_value('Number of MAC Addresses') + if MACnumber_name_list: + MACnumber_name = ''.join(MACnumber_name_list) + return MACnumber_name + else: + return False + + def get_vendor_name(self): + vendor_name_list = self.get_parameter_value('Vendor Name') + if vendor_name_list: + vendor_name = ''.join(vendor_name_list) + return vendor_name + else: + return False + + def get_mfg_name(self): + mfg_name_list = self.get_parameter_value('Manufacture Name') + if mfg_name_list: + mfg_name = ''.join(mfg_name_list) + return mfg_name + else: + return False + + def get_vendorext_name(self): + vendorext_list = self.get_parameter_value('Vendor Extension') + if vendorext_list: + vendorext = ''.join(vendorext_list) + return vendorext + else: + return False + + def get_vendorextIANA_name(self): + vendorext_list = self.get_parameter_value('IANA') + if vendorext_list: + vendorext = ''.join(vendorext_list) + return vendorext + else: + return False + + def get_vendorextASMREV_name(self): + vendorext_list = self.get_parameter_value('Assembly Part Number Rev') + if vendorext_list: + vendorext = ''.join(vendorext_list) + return vendorext + else: + return False + + def get_vendorextASMPartNum_name(self): + vendorext_list = self.get_parameter_value('Assembly Part Number') + if vendorext_list: + vendorext = ''.join(vendorext_list) + return vendorext + else: + return False + + def get_vendorextASMID_name(self): + vendorext_list = self.get_parameter_value('Assembly ID') + if vendorext_list: + vendorext = ''.join(vendorext_list) + return vendorext + else: + return False + + def get_vendorextASMMajNum_name(self): + vendorext_list = self.get_parameter_value('Assembly Major Revision') + if vendorext_list: + vendorext = ''.join(vendorext_list) + return vendorext + else: + return False + + def get_vendorextASMMinNum_name(self): + vendorext_list = self.get_parameter_value('Assembly Minor Revision') + if vendorext_list: + vendorext = ''.join(vendorext_list) + return vendorext + else: + return False + + def get_vendorextCLEI_name(self): + vendorext_list = self.get_parameter_value('CLEI code') + if vendorext_list: + vendorext = ''.join(vendorext_list) + return vendorext + else: + return False + + def get_onieversion_name(self): + onieversion_name_list = self.get_parameter_value('ONIE Version') + if onieversion_name_list: + onieversion_name = ''.join(onieversion_name_list) + return onieversion_name + else: + return False + + def get_crc_name(self): + crc_list = self.get_parameter_value('CRC') + if crc_list: + crc_name = ''.join(crc_list) + return crc_name + else: + return False + + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + """ + platform_name = self.get_platform_name() + platform_name = platform_name.replace("\r","") + platform_name = platform_name.replace("\n","") + log_info("Juniper Platform name: {} and {}".format(self.get_platform_name(), platform_name)) + if str(platform_name) == "x86_64-juniper_networks_qfx5210-r0": + log_info("Juniper Platform QFX5210 ") + status, last_reboot_reason = commands.getstatusoutput("i2cget -f -y 0 0x65 0x24") + if (status == 0): + if last_reboot_reason == "0x80": + return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) + elif last_reboot_reason == "0x40" or last_reboot_reason == "0x08": + return (ChassisBase.REBOOT_CAUSE_WATCHDOG, None) + elif last_reboot_reason == "0x20": + return (ChassisBase.REBOOT_CAUSE_POWER_LOSS, None) + elif last_reboot_reason == "0x10": + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Swizzle Reset") + else: + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Unknown reason") + else: + time.sleep(3) + status, last_reboot_reason = commands.getstatusoutput("i2cget -f -y 0 0x65 0x24") + if last_reboot_reason == "0x80": + return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) + elif last_reboot_reason == "0x40" or last_reboot_reason == "0x08": + return (ChassisBase.REBOOT_CAUSE_WATCHDOG, None) + elif last_reboot_reason == "0x20": + return (ChassisBase.REBOOT_CAUSE_POWER_LOSS, None) + elif last_reboot_reason == "0x10": + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Swizzle Reset") + else: + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Unknown reason") + + elif str(platform_name) == "x86_64-juniper_networks_qfx5200-r0" : + log_info("Juniper Platform QFX5200 ") + status, major_version = commands.getstatusoutput("busybox devmem 0xFED50000 8") + status, minor_version = commands.getstatusoutput("busybox devmem 0xFED50001 8") + status, last_reboot_reason = commands.getstatusoutput("busybox devmem 0xFED50004 8") + if (status == 0): + if (major_version == "0x31") and (minor_version == "0x03") and (last_reboot_reason == "0x80"): + return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) + elif (major_version == "0x31") and (minor_version == "0x05") and (last_reboot_reason == "0x02"): + return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) + elif last_reboot_reason == "0x40" or last_reboot_reason == "0x08": + return (ChassisBase.REBOOT_CAUSE_WATCHDOG, None) + elif last_reboot_reason == "0x20": + return (ChassisBase.REBOOT_CAUSE_POWER_LOSS, None) + elif last_reboot_reason == "0x10": + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Swizzle Reset") + else: + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Unknown reason") + else: + time.sleep(3) + status, major_version = commands.getstatusoutput("busybox devmem 0xFED50000 8") + status, minor_version = commands.getstatusoutput("busybox devmem 0xFED50001 8") + status, last_reboot_reason = commands.getstatusoutput("busybox devmem 0xFED50004 8") + if (status == 0): + if (major_version == "0x31") and (minor_version == "0x03") and (last_reboot_reason == "0x80"): + return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) + elif (major_version == "0x31") and (minor_version == "0x05") and (last_reboot_reason == "0x02"): + return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) + elif last_reboot_reason == "0x40" or last_reboot_reason == "0x08": + return (ChassisBase.REBOOT_CAUSE_WATCHDOG, None) + elif last_reboot_reason == "0x20": + return (ChassisBase.REBOOT_CAUSE_POWER_LOSS, None) + elif last_reboot_reason == "0x10": + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Swizzle Reset") + else: + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Unknown reason") + else: + log_info("Error while reading Re-Fpga") + else: + log_info("Unsupported platform") diff --git a/platform/broadcom/sonic-platform-modules-juniper/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-juniper/sonic_platform/platform.py new file mode 100755 index 000000000000..c3a596111d38 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/sonic_platform/platform.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python +# +# Name: platform.py, version: 1.0 +# +# Description: Module contains the definition of SONiC platform API +# which provide the platform specific details +# +# Copyright (c) 2020, Juniper Networks, Inc. +# All rights reserved. +# +# Notice and Disclaimer: This code is licensed to you under the GNU General +# Public License as published by the Free Software Foundation, version 3 or +# any later version. This code is not an official Juniper product. You can +# obtain a copy of the License at +# +# OSS License: +# +# This program is free software: you can 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 . +# +# Third-Party Code: This code may depend on other components under separate +# copyright notice and license terms. Your use of the source code for those +# components is subject to the terms and conditions of the respective license +# as noted in the Third-Party source code file. +# + + +import sys + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError("%s - required module not found" % e) + +class Platform(PlatformBase): + """ + Juniper Platform-specific class + """ + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() diff --git a/platform/broadcom/sonic-platform-modules-mitac/debian/control b/platform/broadcom/sonic-platform-modules-mitac/debian/control index 8e20f8524d74..f909c6af9489 100644 --- a/platform/broadcom/sonic-platform-modules-mitac/debian/control +++ b/platform/broadcom/sonic-platform-modules-mitac/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-mitac-ly1200-32x Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_fse000.c b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_fse000.c index 362821706857..69d8c53cd0a9 100644 --- a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_fse000.c +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_fse000.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include "pmbus.h" #include diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_sb_i2c.c b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_sb_i2c.c index e2a9718863ff..6389229581bc 100644 --- a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_sb_i2c.c +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_sb_i2c.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include #include #include "bms_i2c.h" diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/qci_platform_ix1b.c b/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/qci_platform_ix1b.c index 925b46256cea..b3e955217a01 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/qci_platform_ix1b.c +++ b/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/qci_platform_ix1b.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include #if LINUX_VERSION_CODE > KERNEL_VERSION(3,12,0) #include #else diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/modules/quanta_platform_ix7.c b/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/modules/quanta_platform_ix7.c index a2a0af63af7d..a6e5733199ac 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/modules/quanta_platform_ix7.c +++ b/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/modules/quanta_platform_ix7.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0)) #include #else diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/modules/qci_platform_ix8.c b/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/modules/qci_platform_ix8.c index 26151b0ab24f..d35a56641e38 100755 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/modules/qci_platform_ix8.c +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/modules/qci_platform_ix8.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0)) #include #else diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/modules/qci_platform_ix8c.c b/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/modules/qci_platform_ix8c.c index f69d3879efb5..f389304a2fbd 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/modules/qci_platform_ix8c.c +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/modules/qci_platform_ix8c.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0)) #include #else diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/modules/qci_platform_ix9.c b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/modules/qci_platform_ix9.c index a927e850791f..1b98c4a2f31f 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/modules/qci_platform_ix9.c +++ b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/modules/qci_platform_ix9.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include #if LINUX_VERSION_CODE > KERNEL_VERSION(3,12,0) #include #else diff --git a/platform/cavium/cavm-platform-modules.mk b/platform/cavium/cavm-platform-modules.mk index 248486313505..4ac72a4c4aab 100644 --- a/platform/cavium/cavm-platform-modules.mk +++ b/platform/cavium/cavm-platform-modules.mk @@ -1,4 +1,3 @@ CAVM_PLATFORM_DEB = cavm_platform_modules.deb $(CAVM_PLATFORM_DEB)_SRC_PATH = $(PLATFORM_PATH)/cavm_platform_modules SONIC_MAKE_DEBS += $(CAVM_PLATFORM_DEB) -SONIC_STRETCH_DEBS += $(CAVM_PLATFORM_DEB) diff --git a/platform/cavium/cavm-xpnet.mk b/platform/cavium/cavm-xpnet.mk index 714a929fb2c1..ed86558a36ae 100644 --- a/platform/cavium/cavm-xpnet.mk +++ b/platform/cavium/cavm-xpnet.mk @@ -4,4 +4,3 @@ CAVM_XPNET_DEB = xp80-Pcie-Endpoint.deb $(CAVM_XPNET_DEB)_URL = $(CAVM_SAI_URL)/netdev/$(CAVM_XPNET_DEB) SONIC_ONLINE_DEBS += $(CAVM_XPNET_DEB) -SONIC_STRETCH_DEBS += $(CAVM_XPNET_DEB) diff --git a/platform/cavium/cavm_platform_modules/DEBIAN/control b/platform/cavium/cavm_platform_modules/DEBIAN/control index 75f8adc0cbd2..6a665e88c718 100755 --- a/platform/cavium/cavm_platform_modules/DEBIAN/control +++ b/platform/cavium/cavm_platform_modules/DEBIAN/control @@ -1,6 +1,6 @@ Package: cavm-platform-modules Version: 1.0 Architecture: amd64 -Depends: linux-image-3.16.0-4-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Maintainer: Nadiya.Stetskovych@cavium.com Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/cavium/docker-ptf-cavm.mk b/platform/cavium/docker-ptf-cavm.mk deleted file mode 100644 index 4665345586a8..000000000000 --- a/platform/cavium/docker-ptf-cavm.mk +++ /dev/null @@ -1,7 +0,0 @@ -# docker image for docker-ptf-cavm - -DOCKER_PTF_CAVM = docker-ptf-cavm.gz -$(DOCKER_PTF_CAVM)_PATH = $(DOCKERS_PATH)/docker-ptf-saithrift -$(DOCKER_PTF_CAVM)_DEPENDS += $(PYTHON_SAITHRIFT_CAVM) -$(DOCKER_PTF_CAVM)_LOAD_DOCKERS += $(DOCKER_PTF) -SONIC_DOCKER_IMAGES += $(DOCKER_PTF_CAVM) diff --git a/platform/cavium/docker-saiserver-cavm/Dockerfile b/platform/cavium/docker-saiserver-cavm/Dockerfile index 2f667c8038ed..d15b16cbfd43 100644 --- a/platform/cavium/docker-saiserver-cavm/Dockerfile +++ b/platform/cavium/docker-saiserver-cavm/Dockerfile @@ -27,4 +27,4 @@ COPY ["portmap.ini", "profile.ini", "/etc/sai/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf deps -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/cavium/docker-syncd-cavm-rpc.mk b/platform/cavium/docker-syncd-cavm-rpc.mk index e57370fce5ca..a19124609bb0 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) $(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/cavium/docker-syncd-cavm-rpc/Dockerfile.j2 b/platform/cavium/docker-syncd-cavm-rpc/Dockerfile.j2 index 984855434807..e9e9facef5ee 100644 --- a/platform/cavium/docker-syncd-cavm-rpc/Dockerfile.j2 +++ b/platform/cavium/docker-syncd-cavm-rpc/Dockerfile.j2 @@ -11,11 +11,6 @@ debs/ RUN apt-get purge -y syncd -RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; } ; \ -{% for deb in docker_syncd_cavm_rpc_debs.split(' ') -%} -dpkg_apt debs/{{ deb }}{{'; '}} -{%- endfor %} - ## Pre-install the fundamental packages RUN apt-get update \ && apt-get -y install \ @@ -27,7 +22,16 @@ RUN apt-get update \ python-dev \ wget \ cmake \ - && wget https://github.com/nanomsg/nanomsg/archive/1.0.0.tar.gz \ + libqt5core5a \ + libqt5network5 \ + libboost-atomic1.71.0 + +RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; } ; \ +{% for deb in docker_syncd_cavm_rpc_debs.split(' ') -%} +dpkg_apt debs/{{ deb }}{{'; '}} +{%- endfor %} + +RUN wget https://github.com/nanomsg/nanomsg/archive/1.0.0.tar.gz \ && tar xvfz 1.0.0.tar.gz \ && cd nanomsg-1.0.0 \ && mkdir -p build \ @@ -48,4 +52,4 @@ RUN apt-get update \ COPY ["ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/cavium/docker-syncd-cavm.mk b/platform/cavium/docker-syncd-cavm.mk index ad43d6f1196f..059d2c71ebb4 100644 --- a/platform/cavium/docker-syncd-cavm.mk +++ b/platform/cavium/docker-syncd-cavm.mk @@ -2,7 +2,7 @@ DOCKER_SYNCD_CAVM = docker-syncd-cavm.gz $(DOCKER_SYNCD_CAVM)_PATH = $(PLATFORM_PATH)/docker-syncd-cavm -$(DOCKER_SYNCD_CAVM)_DEPENDS += $(SYNCD) $(CAVM_LIBSAI) $(XP_TOOLS) $(REDIS_TOOLS) +$(DOCKER_SYNCD_CAVM)_DEPENDS += $(SYNCD) $(CAVM_LIBSAI) $(XP_TOOLS) $(DOCKER_SYNCD_CAVM)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_CAVM)_DEPENDS += $(SYNCD_DBG) \ diff --git a/platform/cavium/docker-syncd-cavm/Dockerfile.j2 b/platform/cavium/docker-syncd-cavm/Dockerfile.j2 index 0e2bc4b6bbc7..fcf82276ad1a 100755 --- a/platform/cavium/docker-syncd-cavm/Dockerfile.j2 +++ b/platform/cavium/docker-syncd-cavm/Dockerfile.j2 @@ -32,4 +32,4 @@ COPY ["profile.ini", "/etc/ssw/AS7512/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] 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 3079618990ed..61e290e3189e 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" - if does not exist for 5 times within 5 cycles then alert +check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/platform/cavium/docker-syncd-cavm/critical_processes b/platform/cavium/docker-syncd-cavm/critical_processes index 6082f242b872..bdd6903c5690 100644 --- a/platform/cavium/docker-syncd-cavm/critical_processes +++ b/platform/cavium/docker-syncd-cavm/critical_processes @@ -1 +1 @@ -syncd +program:syncd diff --git a/platform/cavium/docker-syncd-cavm/supervisord.conf b/platform/cavium/docker-syncd-cavm/supervisord.conf index 0c6285d46ae0..91b94a258033 100644 --- a/platform/cavium/docker-syncd-cavm/supervisord.conf +++ b/platform/cavium/docker-syncd-cavm/supervisord.conf @@ -5,7 +5,7 @@ nodaemon=true [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name syncd -events=PROCESS_STATE_EXITED +events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING autostart=true autorestart=unexpected diff --git a/platform/cavium/rules.mk b/platform/cavium/rules.mk index 2da9f5cca9f6..a526774d2951 100644 --- a/platform/cavium/rules.mk +++ b/platform/cavium/rules.mk @@ -5,17 +5,18 @@ include $(PLATFORM_PATH)/cavm-platform-modules.mk include $(PLATFORM_PATH)/cavm-xpnet.mk include $(PLATFORM_PATH)/one-image.mk include $(PLATFORM_PATH)/libsaithrift-dev.mk -include $(PLATFORM_PATH)/docker-ptf-cavm.mk SONIC_ALL += $(SONIC_ONE_IMAGE) \ $(DOCKER_FPM) \ $(DOCKER_PTF_CAVM) \ $(DOCKER_SYNCD_CAVM_RPC) -# Inject cavium sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(CAVM_SAI) $(CAVM_LIBSAI) +# Inject cavium sai into syncd +$(SYNCD)_DEPENDS += $(CAVM_SAI) $(CAVM_LIBSAI) +$(SYNCD)_UNINSTALLS += $(CAVM_LIBSAI) + ifeq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV_CAVM) +$(SYNCD)_DEPENDS += $(LIBSAITHRIFT_DEV_CAVM) endif # Runtime dependency on cavium sai is set only for syncd diff --git a/platform/centec-arm64/docker-saiserver-centec.mk b/platform/centec-arm64/docker-saiserver-centec.mk new file mode 100755 index 000000000000..8d1b11bf005e --- /dev/null +++ b/platform/centec-arm64/docker-saiserver-centec.mk @@ -0,0 +1,15 @@ +# docker image for centec saiserver + +DOCKER_SAISERVER_CENTEC = docker-saiserver-centec.gz +$(DOCKER_SAISERVER_CENTEC)_PATH = $(PLATFORM_PATH)/docker-saiserver-centec +$(DOCKER_SAISERVER_CENTEC)_DEPENDS += $(SAISERVER) +$(DOCKER_SAISERVER_CENTEC)_FILES += $(DSSERVE) $(BCMCMD) +$(DOCKER_SAISERVER_CENTEC)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) +SONIC_DOCKER_IMAGES += $(DOCKER_SAISERVER_CENTEC) + +$(DOCKER_SAISERVER_CENTEC)_CONTAINER_NAME = saiserver +$(DOCKER_SAISERVER_CENTEC)_RUN_OPT += --privileged -t +$(DOCKER_SAISERVER_CENTEC)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf +$(DOCKER_SAISERVER_CENTEC)_RUN_OPT += -v /var/run/docker-saiserver:/var/run/sswsyncd +$(DOCKER_SAISERVER_CENTEC)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_SAISERVER_CENTEC)_RUN_OPT += -v /host/warmboot:/var/warmboot diff --git a/platform/centec-arm64/docker-syncd-centec-rpc.mk b/platform/centec-arm64/docker-syncd-centec-rpc.mk new file mode 100755 index 000000000000..2c441e4fc410 --- /dev/null +++ b/platform/centec-arm64/docker-syncd-centec-rpc.mk @@ -0,0 +1,23 @@ +# docker image for centec syncd with rpc + +DOCKER_SYNCD_CENTEC_RPC = docker-syncd-centec-rpc.gz +$(DOCKER_SYNCD_CENTEC_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-centec-rpc +$(DOCKER_SYNCD_CENTEC_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_CENTEC_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) +ifeq ($(INSTALL_DEBUG_TOOLS), y) +$(DOCKER_SYNCD_CENTEC_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ + $(LIBSWSSCOMMON_DBG) \ + $(LIBSAIMETADATA_DBG) \ + $(LIBSAIREDIS_DBG) +endif +$(DOCKER_SYNCD_CENTEC_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_BASE) +SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_CENTEC_RPC) +ifeq ($(ENABLE_SYNCD_RPC),y) +SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_CENTEC_RPC) +endif + +$(DOCKER_SYNCD_CENTEC_RPC)_CONTAINER_NAME = syncd +$(DOCKER_SYNCD_CENTEC_RPC)_RUN_OPT += --privileged -t +$(DOCKER_SYNCD_CENTEC_RPC)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf +$(DOCKER_SYNCD_CENTEC_RPC)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_SYNCD_CENTEC_RPC)_RUN_OPT += -v /host/warmboot:/var/warmboot diff --git a/platform/centec-arm64/docker-syncd-centec-rpc/Dockerfile.j2 b/platform/centec-arm64/docker-syncd-centec-rpc/Dockerfile.j2 new file mode 100755 index 000000000000..bec9c7f4426b --- /dev/null +++ b/platform/centec-arm64/docker-syncd-centec-rpc/Dockerfile.j2 @@ -0,0 +1,57 @@ +FROM docker-syncd-centec + +## Make apt-get non-interactive +ENV DEBIAN_FRONTEND=noninteractive + +COPY \ +{% for deb in docker_syncd_centec_rpc_debs.split(' ') -%} +debs/{{ deb }}{{' '}} +{%- endfor -%} +debs/ + +RUN apt-get purge -y syncd + +## Pre-install the fundamental packages +RUN apt-get update \ + && apt-get -y install \ + net-tools \ + python-pip \ + python-setuptools \ + build-essential \ + libssl-dev \ + libffi-dev \ + python-dev \ + wget \ + cmake \ + libqt5core5a \ + libqt5network5 \ + libboost-atomic1.71.0 + +RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; } ; \ +{% for deb in docker_syncd_centec_rpc_debs.split(' ') -%} +dpkg_apt debs/{{ deb }}{{'; '}} +{%- endfor %} + +RUN wget https://github.com/nanomsg/nanomsg/archive/1.0.0.tar.gz \ + && tar xvfz 1.0.0.tar.gz \ + && cd nanomsg-1.0.0 \ + && mkdir -p build \ + && cmake . \ + && make install \ + && ldconfig \ + && cd .. \ + && rm -fr nanomsg-1.0.0 \ + && rm -f 1.0.0.tar.gz \ + && pip2 install cffi==1.7.0 \ + && pip2 install --upgrade cffi==1.7.0 \ + && pip2 install wheel \ + && pip2 install nnpy \ + && mkdir -p /opt \ + && cd /opt \ + && wget https://raw.githubusercontent.com/p4lang/ptf/master/ptf_nn/ptf_nn_agent.py \ + && apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y \ + && rm -rf /root/deps + +COPY ["ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] + +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/centec-arm64/docker-syncd-centec-rpc/ptf_nn_agent.conf b/platform/centec-arm64/docker-syncd-centec-rpc/ptf_nn_agent.conf new file mode 100755 index 000000000000..fa1ed0eb1622 --- /dev/null +++ b/platform/centec-arm64/docker-syncd-centec-rpc/ptf_nn_agent.conf @@ -0,0 +1,10 @@ +[program:ptf_nn_agent] +command=/usr/bin/python /opt/ptf_nn_agent.py --device-socket 1@tcp://0.0.0.0:10900 -i 1-3@Ethernet12 --set-iface-rcv-buffer=109430400 +process_name=ptf_nn_agent +stdout_logfile=/tmp/ptf_nn_agent.out.log +stderr_logfile=/tmp/ptf_nn_agent.err.log +redirect_stderr=false +autostart=true +autorestart=true +startsecs=1 +numprocs=1 diff --git a/platform/centec-arm64/docker-syncd-centec.mk b/platform/centec-arm64/docker-syncd-centec.mk new file mode 100755 index 000000000000..9c3d1b1aff75 --- /dev/null +++ b/platform/centec-arm64/docker-syncd-centec.mk @@ -0,0 +1,17 @@ +# docker image for centec syncd + +DOCKER_SYNCD_PLATFORM_CODE = centec +include $(PLATFORM_PATH)/../template/docker-syncd-base.mk + +$(DOCKER_SYNCD_BASE)_DEPENDS += $(SYNCD) $(PYTHON_SDK_API) +$(DOCKER_SYNCD_CENTEC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) +$(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ + $(LIBSWSSCOMMON_DBG) \ + $(LIBSAIMETADATA_DBG) \ + $(LIBSAIREDIS_DBG) + +$(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot +$(DOCKER_SYNCD_CENTEC)_RUN_OPT += --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 diff --git a/platform/centec-arm64/docker-syncd-centec/Dockerfile.j2 b/platform/centec-arm64/docker-syncd-centec/Dockerfile.j2 new file mode 100755 index 000000000000..b97bfe3d3e18 --- /dev/null +++ b/platform/centec-arm64/docker-syncd-centec/Dockerfile.j2 @@ -0,0 +1,37 @@ +FROM docker-config-engine-buster + +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 + +COPY \ +{% for deb in docker_syncd_centec_debs.split(' ') -%} +debs/{{ deb }}{{' '}} +{%- endfor -%} +debs/ + +RUN apt-get update \ + && apt-get -y install \ + net-tools \ + iputils-ping + +RUN apt-get -y install libpcap-dev libxml2-dev python-dev swig libsensors4-dev nfs-common + +RUN dpkg -i \ +{% for deb in docker_syncd_centec_debs.split(' ') -%} +debs/{{ deb }}{{' '}} +{%- endfor %} + +COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin/"] +COPY ["critical_processes", "/etc/supervisor/"] + +## Clean up +RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y +RUN rm -rf /debs + +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/centec-arm64/docker-syncd-centec/critical_processes b/platform/centec-arm64/docker-syncd-centec/critical_processes new file mode 100644 index 000000000000..bdd6903c5690 --- /dev/null +++ b/platform/centec-arm64/docker-syncd-centec/critical_processes @@ -0,0 +1 @@ +program:syncd diff --git a/platform/centec-arm64/docker-syncd-centec/supervisord.conf b/platform/centec-arm64/docker-syncd-centec/supervisord.conf new file mode 100755 index 000000000000..10f406129d9c --- /dev/null +++ b/platform/centec-arm64/docker-syncd-centec/supervisord.conf @@ -0,0 +1,38 @@ +[supervisord] +logfile_maxbytes=1MB +logfile_backups=2 +nodaemon=true + +[eventlistener:dependent-startup] +command=python2 -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE +buffer_size=25 + +[eventlistener:supervisor-proc-exit-listener] +command=python2 /usr/bin/supervisor-proc-exit-listener --container-name syncd +events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING +autostart=true +autorestart=unexpected + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true + +[program:syncd] +command=/usr/bin/syncd_start.sh +priority=3 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running diff --git a/platform/centec-arm64/docker-syncd-centec/syncd.sh b/platform/centec-arm64/docker-syncd-centec/syncd.sh new file mode 100755 index 000000000000..993cf100f2f0 --- /dev/null +++ b/platform/centec-arm64/docker-syncd-centec/syncd.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +function clean_up { + service syncd stop + exit +} + +trap clean_up SIGTERM SIGKILL + +service syncd start + +read diff --git a/platform/centec-arm64/libsaithrift-dev.mk b/platform/centec-arm64/libsaithrift-dev.mk new file mode 100755 index 000000000000..5b63dbbf7a29 --- /dev/null +++ b/platform/centec-arm64/libsaithrift-dev.mk @@ -0,0 +1,20 @@ +# libsaithrift-dev package + +SAI_VER = 0.9.4 + +LIBSAITHRIFT_DEV = libsaithrift-dev_$(SAI_VER)_$(CONFIGURED_ARCH).deb +$(LIBSAITHRIFT_DEV)_SRC_PATH = $(SRC_PATH)/sonic-sairedis/SAI +$(LIBSAITHRIFT_DEV)_DEPENDS += $(LIBTHRIFT) $(LIBTHRIFT_DEV) $(PYTHON_THRIFT) $(THRIFT_COMPILER) $(CENTEC_SAI) +$(LIBSAITHRIFT_DEV)_RDEPENDS += $(LIBTHRIFT) $(CENTEC_SAI) +SONIC_DPKG_DEBS += $(LIBSAITHRIFT_DEV) + +PYTHON_SAITHRIFT = python-saithrift_$(SAI_VER)_$(CONFIGURED_ARCH).deb +$(eval $(call add_extra_package,$(LIBSAITHRIFT_DEV),$(PYTHON_SAITHRIFT))) + +SAISERVER = saiserver_$(SAI_VER)_$(CONFIGURED_ARCH).deb +$(SAISERVER)_RDEPENDS += $(LIBTHRIFT) $(CENTEC_SAI) +$(eval $(call add_extra_package,$(LIBSAITHRIFT_DEV),$(SAISERVER))) + +SAISERVER_DBG = saiserver-dbg_$(SAI_VER)_$(CONFIGURED_ARCH).deb +$(SAISERVER_DBG)_RDEPENDS += $(SAISERVER) +$(eval $(call add_extra_package,$(LIBSAITHRIFT_DEV),$(SAISERVER_DBG))) diff --git a/platform/centec-arm64/modules b/platform/centec-arm64/modules new file mode 100644 index 000000000000..30cdc339d8de --- /dev/null +++ b/platform/centec-arm64/modules @@ -0,0 +1,22 @@ +pinctrl-ctc +mtdblock +ofpart +spi-ctc-qspi +spi-nor +m25p80 +i2c-ctc +i2c-dev +rtc-sd2405 +ctc5236_switch +ctc5236_mdio +ctcmac +ctcmac_test +ctc5236-mc +ctc_wdt +ehci-ctc +sdhci-ctc5236 +gpio-ctc +pwm-ctc +ext4 +overlay +squashfs diff --git a/platform/centec-arm64/one-image.mk b/platform/centec-arm64/one-image.mk new file mode 100755 index 000000000000..e8f0cf3690e5 --- /dev/null +++ b/platform/centec-arm64/one-image.mk @@ -0,0 +1,18 @@ +# sonic centec one image installer + +SONIC_ONE_IMAGE = sonic-centec-arm64.bin +$(SONIC_ONE_IMAGE)_MACHINE = centec-arm64 +$(SONIC_ONE_IMAGE)_IMAGE_TYPE = onie + +$(SONIC_ONE_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) +$(SONIC_ONE_IMAGE)_INSTALLS += $(TSINGMA_BSP_MODULE) +$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(CENTEC_E530_48T4X_P_PLATFORM_MODULE) +$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(CENTEC_E530_24X2C_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)) +else +$(SONIC_ONE_IMAGE)_DOCKERS = $(SONIC_INSTALL_DOCKER_IMAGES) +endif +SONIC_INSTALLERS += $(SONIC_ONE_IMAGE) diff --git a/platform/centec-arm64/platform-modules-centec-e530.mk b/platform/centec-arm64/platform-modules-centec-e530.mk new file mode 100644 index 000000000000..3058e77a57e3 --- /dev/null +++ b/platform/centec-arm64/platform-modules-centec-e530.mk @@ -0,0 +1,18 @@ +# Centec E530-48T4X-P Platform modules + + +CENTEC_E530_48T4X_P_PLATFORM_MODULE_VERSION =1.1 +CENTEC_E530_24X2C_PLATFORM_MODULE_VERSION =1.1 + +export CENTEC_E530_48T4X_P_PLATFORM_MODULE_VERSION + +CENTEC_E530_48T4X_P_PLATFORM_MODULE = platform-modules-e530-48t4x-p_$(CENTEC_E530_48T4X_P_PLATFORM_MODULE_VERSION)_arm64.deb + +$(CENTEC_E530_48T4X_P_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-e530 +$(CENTEC_E530_48T4X_P_PLATFORM_MODULE)_PLATFORM = arm64-centec_e530_48t4x_p-r0 +$(CENTEC_E530_48T4X_P_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +SONIC_DPKG_DEBS += $(CENTEC_E530_48T4X_P_PLATFORM_MODULE) + +CENTEC_E530_24X2C_PLATFORM_MODULE = platform-modules-e530-24x2c_$(CENTEC_E530_24X2C_PLATFORM_MODULE_VERSION)_arm64.deb +$(CENTEC_E530_24X2C_PLATFORM_MODULE)_PLATFORM = arm64-centec_e530_24x2c-r0 +$(eval $(call add_extra_package,$(CENTEC_E530_48T4X_P_PLATFORM_MODULE),$(CENTEC_E530_24X2C_PLATFORM_MODULE))) diff --git a/platform/centec-arm64/platform.conf b/platform/centec-arm64/platform.conf new file mode 100755 index 000000000000..8b29d0ded3a9 --- /dev/null +++ b/platform/centec-arm64/platform.conf @@ -0,0 +1,46 @@ +# Copyright (C) Centec Inc + +# over ride default behaviour + +echo "Preparing for installation ... " + +demo_mnt=/mnt + +hw_load() { + echo "ext4load mmc 0:2 \$loadaddr onie_uimage" +} + +create_partition() { + echo y | mkfs.ext4 -L CTC-SYSTEM /dev/mmcblk0p1 +} + +mount_partition() { + echo "mount flash" + mount -t ext4 /dev/mmcblk0p1 $demo_mnt +} + +bootloader_menu_config() { + mkdir -p $demo_mnt/boot + mount -t ext4 /dev/mmcblk0p2 $demo_mnt/boot + + rm $demo_mnt/boot/centec-e530.itb -rf + cp $demo_mnt/$image_dir/boot/sonic_arm64.fit $demo_mnt/boot/centec-e530.itb + cd $demo_mnt/boot + rm onie_uimage -rf + ln -s centec-e530.itb onie_uimage + cd - + sync + umount -l $demo_mnt/boot + + hw_load_str="$(hw_load)" + + (cat < /tmp/env.txt + + fw_setenv -f -s /tmp/env.txt + fw_setenv -f image_dir $image_dir +} diff --git a/platform/centec-arm64/rules.mk b/platform/centec-arm64/rules.mk new file mode 100755 index 000000000000..1982f86b757c --- /dev/null +++ b/platform/centec-arm64/rules.mk @@ -0,0 +1,22 @@ +include $(PLATFORM_PATH)/sai.mk +include $(PLATFORM_PATH)/docker-syncd-centec.mk +include $(PLATFORM_PATH)/docker-syncd-centec-rpc.mk +include $(PLATFORM_PATH)/one-image.mk +include $(PLATFORM_PATH)/libsaithrift-dev.mk +include $(PLATFORM_PATH)/tsingma-bsp.mk +include $(PLATFORM_PATH)/platform-modules-centec-e530.mk + +SONIC_ALL += $(SONIC_ONE_IMAGE) \ + $(DOCKER_FPM) +# $(DOCKER_SYNCD_CENTEC_RPC) + +# Inject centec sai into syncd +$(SYNCD)_DEPENDS += $(CENTEC_SAI) +$(SYNCD)_UNINSTALLS += $(CENTEC_SAI) + +ifeq ($(ENABLE_SYNCD_RPC),y) +$(SYNCD)_DEPENDS += $(LIBSAITHRIFT_DEV) +endif + +# Runtime dependency on centec sai is set only for syncd +$(SYNCD)_RDEPENDS += $(CENTEC_SAI) diff --git a/platform/centec-arm64/sai.mk b/platform/centec-arm64/sai.mk new file mode 100755 index 000000000000..2b902b49403a --- /dev/null +++ b/platform/centec-arm64/sai.mk @@ -0,0 +1,9 @@ +# Centec SAI + +export CENTEC_SAI_VERSION = 1.6.3-1 +export CENTEC_SAI = libsai_$(CENTEC_SAI_VERSION)_$(PLATFORM_ARCH).deb + +$(CENTEC_SAI)_URL = https://github.com/CentecNetworks/sonic-binaries/raw/master/$(PLATFORM_ARCH)/sai/$(CENTEC_SAI) +$(eval $(call add_conflict_package,$(CENTEC_SAI),$(LIBSAIVS_DEV))) +SONIC_ONLINE_DEBS += $(CENTEC_SAI) + diff --git a/platform/centec-arm64/sonic-platform-modules-e530/24x2c/classes/__init__.py b/platform/centec-arm64/sonic-platform-modules-e530/24x2c/classes/__init__.py new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/platform/centec-arm64/sonic-platform-modules-e530/24x2c/modules/Makefile b/platform/centec-arm64/sonic-platform-modules-e530/24x2c/modules/Makefile new file mode 100644 index 000000000000..c1beeaa15c68 --- /dev/null +++ b/platform/centec-arm64/sonic-platform-modules-e530/24x2c/modules/Makefile @@ -0,0 +1 @@ +obj-m := centec_e530_24x2c_platform.o diff --git a/platform/centec-arm64/sonic-platform-modules-e530/24x2c/modules/centec_e530_24x2c_platform.c b/platform/centec-arm64/sonic-platform-modules-e530/24x2c/modules/centec_e530_24x2c_platform.c new file mode 100644 index 000000000000..8c2437a2d071 --- /dev/null +++ b/platform/centec-arm64/sonic-platform-modules-e530/24x2c/modules/centec_e530_24x2c_platform.c @@ -0,0 +1,1111 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SEP(XXX) 1 +#define IS_INVALID_PTR(_PTR_) ((_PTR_ == NULL) || IS_ERR(_PTR_)) +#define IS_VALID_PTR(_PTR_) (!IS_INVALID_PTR(_PTR_)) + +#if SEP("defines") +#define SFP_NUM 24 +#define QSFP_NUM 2 +#define PORT_NUM (SFP_NUM + QSFP_NUM) +#endif + +#if SEP("i2c:smbus") +static int e530_24x2c_smbus_read_reg(struct i2c_client *client, unsigned char reg, unsigned char* value) +{ + int ret = 0; + + if (IS_INVALID_PTR(client)) + { + printk(KERN_CRIT "invalid i2c client"); + return -1; + } + + ret = i2c_smbus_read_byte_data(client, reg); + if (ret >= 0) { + *value = (unsigned char)ret; + } + else + { + *value = 0; + printk(KERN_CRIT "i2c_smbus op failed: ret=%d reg=%d\n",ret ,reg); + return ret; + } + + return 0; +} + +static int e530_24x2c_smbus_write_reg(struct i2c_client *client, unsigned char reg, unsigned char value) +{ + int ret = 0; + + if (IS_INVALID_PTR(client)) + { + printk(KERN_CRIT "invalid i2c client"); + return -1; + } + + ret = i2c_smbus_write_byte_data(client, reg, value); + if (ret != 0) + { + printk(KERN_CRIT "i2c_smbus op failed: ret=%d reg=%d\n",ret ,reg); + return ret; + } + + return 0; +} +#endif + +#if SEP("i2c:master") +static struct i2c_adapter *i2c_adp_master = NULL; /* i2c-1-cpu */ + +static int e530_24x2c_init_i2c_master(void) +{ + /* find i2c-core master */ + i2c_adp_master = i2c_get_adapter(0); + if(IS_INVALID_PTR(i2c_adp_master)) + { + i2c_adp_master = NULL; + printk(KERN_CRIT "e530_24x2c_init_i2c_master can't find i2c-core bus\n"); + return -1; + } + + return 0; +} + +static int e530_24x2c_exit_i2c_master(void) +{ + /* uninstall i2c-core master */ + if(IS_VALID_PTR(i2c_adp_master)) { + i2c_put_adapter(i2c_adp_master); + i2c_adp_master = NULL; + } + + return 0; +} +#endif + +#if SEP("i2c:gpio") +static struct i2c_adapter *i2c_adp_gpio0 = NULL; /* gpio0 */ +static struct i2c_adapter *i2c_adp_gpio1 = NULL; /* gpio1 */ +static struct i2c_adapter *i2c_adp_gpio2 = NULL; /* gpio2 */ +static struct i2c_board_info i2c_dev_gpio0 = { + I2C_BOARD_INFO("i2c-gpio0", 0x21), +}; +static struct i2c_board_info i2c_dev_gpio1 = { + I2C_BOARD_INFO("i2c-gpio1", 0x22), +}; +static struct i2c_board_info i2c_dev_gpio2 = { + I2C_BOARD_INFO("i2c-gpio2", 0x23), +}; +static struct i2c_client *i2c_client_gpio0 = NULL; +static struct i2c_client *i2c_client_gpio1 = NULL; +static struct i2c_client *i2c_client_gpio2 = NULL; + +static int e530_24x2c_init_i2c_gpio(void) +{ + int ret = 0; + + if (IS_INVALID_PTR(i2c_adp_master)) + { + printk(KERN_CRIT "e530_24x2c_init_i2c_gpio can't find i2c-core bus\n"); + return -1; + } + + i2c_adp_gpio0 = i2c_get_adapter(0); + if(IS_INVALID_PTR(i2c_adp_gpio0)) + { + i2c_adp_gpio0 = NULL; + printk(KERN_CRIT "get e530_24x2c gpio0 i2c-adp failed\n"); + return -1; + } + + i2c_client_gpio0 = i2c_new_device(i2c_adp_gpio0, &i2c_dev_gpio0); + if(IS_INVALID_PTR(i2c_client_gpio0)) + { + i2c_client_gpio0 = NULL; + printk(KERN_CRIT "create e530_24x2c board i2c client gpio0 failed\n"); + return -1; + } + + i2c_adp_gpio1 = i2c_get_adapter(0); + if(IS_INVALID_PTR(i2c_adp_gpio1)) + { + i2c_adp_gpio1 = NULL; + printk(KERN_CRIT "get e530_24x2c gpio1 i2c-adp failed\n"); + return -1; + } + + i2c_client_gpio1 = i2c_new_device(i2c_adp_gpio1, &i2c_dev_gpio1); + if(IS_INVALID_PTR(i2c_client_gpio1)) + { + i2c_client_gpio1 = NULL; + printk(KERN_CRIT "create e530_24x2c board i2c client gpio1 failed\n"); + return -1; + } + + i2c_adp_gpio2 = i2c_get_adapter(0); + if(IS_INVALID_PTR(i2c_adp_gpio2)) + { + i2c_adp_gpio2 = NULL; + printk(KERN_CRIT "get e530_24x2c gpio2 i2c-adp failed\n"); + return -1; + } + + i2c_client_gpio2 = i2c_new_device(i2c_adp_gpio2, &i2c_dev_gpio2); + if(IS_INVALID_PTR(i2c_client_gpio2)) + { + i2c_client_gpio2 = NULL; + printk(KERN_CRIT "create e530_24x2c board i2c client gpio2 failed\n"); + return -1; + } + + /* gpio0 */ + ret = e530_24x2c_smbus_write_reg(i2c_client_gpio0, 0x02, 0x00); + ret += e530_24x2c_smbus_write_reg(i2c_client_gpio0, 0x03, 0x00); + ret += e530_24x2c_smbus_write_reg(i2c_client_gpio0, 0x06, 0x00); + ret += e530_24x2c_smbus_write_reg(i2c_client_gpio0, 0x07, 0x00); + /* gpio1 */ + ret += e530_24x2c_smbus_write_reg(i2c_client_gpio1, 0x02, 0xbf); + ret += e530_24x2c_smbus_write_reg(i2c_client_gpio1, 0x03, 0xff); + ret += e530_24x2c_smbus_write_reg(i2c_client_gpio1, 0x06, 0x0c); + ret += e530_24x2c_smbus_write_reg(i2c_client_gpio1, 0x07, 0xff); + /* gpio2 */ + ret += e530_24x2c_smbus_write_reg(i2c_client_gpio2, 0x02, 0x00); + ret += e530_24x2c_smbus_write_reg(i2c_client_gpio2, 0x03, 0xff); + ret += e530_24x2c_smbus_write_reg(i2c_client_gpio2, 0x06, 0x00); + ret += e530_24x2c_smbus_write_reg(i2c_client_gpio2, 0x07, 0xff); + + if (ret) + { + printk(KERN_CRIT "init e530_24x2c board i2c gpio config failed\n"); + return -1; + } + + return 0; +} + +static int e530_24x2c_exit_i2c_gpio(void) +{ + if(IS_VALID_PTR(i2c_client_gpio0)) { + i2c_unregister_device(i2c_client_gpio0); + i2c_client_gpio0 = NULL; + } + + if(IS_VALID_PTR(i2c_adp_gpio0)) + { + i2c_put_adapter(i2c_adp_gpio0); + i2c_adp_gpio0 = NULL; + } + + if(IS_VALID_PTR(i2c_client_gpio1)) { + i2c_unregister_device(i2c_client_gpio1); + i2c_client_gpio1 = NULL; + } + + if(IS_VALID_PTR(i2c_adp_gpio1)) + { + i2c_put_adapter(i2c_adp_gpio1); + i2c_adp_gpio1 = NULL; + } + + if(IS_VALID_PTR(i2c_client_gpio2)) { + i2c_unregister_device(i2c_client_gpio2); + i2c_client_gpio2 = NULL; + } + + if(IS_VALID_PTR(i2c_adp_gpio2)) + { + i2c_put_adapter(i2c_adp_gpio2); + i2c_adp_gpio2 = NULL; + } + + return 0; +} +#endif + + +#if SEP("drivers:psu") +static struct class* psu_class = NULL; +static struct device* psu_dev_psu1 = NULL; +static struct device* psu_dev_psu2 = NULL; + +static ssize_t e530_24x2c_psu_read_presence(struct device *dev, struct device_attribute *attr, char *buf) +{ + int ret = 0; + unsigned char present_no = 0; + unsigned char present = 0; + unsigned char value = 0; + struct i2c_client *i2c_psu_client = NULL; + + if (psu_dev_psu1 == dev) + { + i2c_psu_client = i2c_client_gpio1; + present_no = 9; + } + else if (psu_dev_psu2 == dev) + { + i2c_psu_client = i2c_client_gpio1; + present_no = 13; + } + else + { + return sprintf(buf, "Error: unknown psu device\n"); + } + + if (IS_INVALID_PTR(i2c_psu_client)) + { + return sprintf(buf, "Error: psu i2c-adapter invalid\n"); + } + + ret = e530_24x2c_smbus_read_reg(i2c_psu_client, present_no/8, &present); + if (ret != 0) + { + return sprintf(buf, "Error: read psu data:%s failed\n", attr->attr.name); + } + + value = ((present & (1<<(present_no%8))) ? 1 : 0 ); + + return sprintf(buf, "%d\n", value); +} + +static ssize_t e530_24x2c_psu_read_status(struct device *dev, struct device_attribute *attr, char *buf) +{ + int ret = 0; + unsigned char workstate_no = 0; + unsigned char workstate = 0; + unsigned char value = 0; + struct i2c_client *i2c_psu_client = NULL; + + if (psu_dev_psu1 == dev) + { + i2c_psu_client = i2c_client_gpio1; + workstate_no = 11; + } + else if (psu_dev_psu2 == dev) + { + i2c_psu_client = i2c_client_gpio1; + workstate_no = 15; + } + else + { + return sprintf(buf, "Error: unknown psu device\n"); + } + + if (IS_INVALID_PTR(i2c_psu_client)) + { + return sprintf(buf, "Error: psu i2c-adapter invalid\n"); + } + + ret = e530_24x2c_smbus_read_reg(i2c_psu_client, workstate_no/8, &workstate); + if (ret != 0) + { + return sprintf(buf, "Error: read psu data:%s failed\n", attr->attr.name); + } + + value = ((workstate & (1<<(workstate_no%8))) ? 0 : 1 ); + + return sprintf(buf, "%d\n", value); +} + +static DEVICE_ATTR(psu_presence, S_IRUGO, e530_24x2c_psu_read_presence, NULL); +static DEVICE_ATTR(psu_status, S_IRUGO, e530_24x2c_psu_read_status, NULL); + +static int e530_24x2c_init_psu(void) +{ + int ret = 0; + + psu_class = class_create(THIS_MODULE, "psu"); + if (IS_INVALID_PTR(psu_class)) + { + psu_class = NULL; + printk(KERN_CRIT "create e530_24x2c class psu failed\n"); + return -1; + } + + psu_dev_psu1 = device_create(psu_class, NULL, MKDEV(222,0), NULL, "psu1"); + if (IS_INVALID_PTR(psu_dev_psu1)) + { + psu_dev_psu1 = NULL; + printk(KERN_CRIT "create e530_24x2c psu1 device failed\n"); + return -1; + } + + psu_dev_psu2 = device_create(psu_class, NULL, MKDEV(222,1), NULL, "psu2"); + if (IS_INVALID_PTR(psu_dev_psu2)) + { + psu_dev_psu2 = NULL; + printk(KERN_CRIT "create e530_24x2c psu2 device failed\n"); + return -1; + } + + ret = device_create_file(psu_dev_psu1, &dev_attr_psu_presence); + if (ret != 0) + { + printk(KERN_CRIT "create e530_24x2c psu1 device attr:presence failed\n"); + return -1; + } + + ret = device_create_file(psu_dev_psu1, &dev_attr_psu_status); + if (ret != 0) + { + printk(KERN_CRIT "create e530_24x2c psu1 device attr:status failed\n"); + return -1; + } + + ret = device_create_file(psu_dev_psu2, &dev_attr_psu_presence); + if (ret != 0) + { + printk(KERN_CRIT "create e530_24x2c psu2 device attr:presence failed\n"); + return -1; + } + + ret = device_create_file(psu_dev_psu2, &dev_attr_psu_status); + if (ret != 0) + { + printk(KERN_CRIT "create e530_24x2c psu2 device attr:status failed\n"); + return -1; + } + + return 0; +} + +static int e530_24x2c_exit_psu(void) +{ + if (IS_VALID_PTR(psu_dev_psu1)) + { + device_remove_file(psu_dev_psu1, &dev_attr_psu_presence); + device_remove_file(psu_dev_psu1, &dev_attr_psu_status); + device_destroy(psu_class, MKDEV(222,0)); + } + + if (IS_VALID_PTR(psu_dev_psu2)) + { + device_remove_file(psu_dev_psu2, &dev_attr_psu_presence); + device_remove_file(psu_dev_psu2, &dev_attr_psu_status); + device_destroy(psu_class, MKDEV(222,1)); + } + + if (IS_VALID_PTR(psu_class)) + { + class_destroy(psu_class); + psu_class = NULL; + } + + return 0; +} +#endif + +#if SEP("drivers:leds") +extern void e530_24x2c_led_set(struct led_classdev *led_cdev, enum led_brightness set_value); +extern enum led_brightness e530_24x2c_led_get(struct led_classdev *led_cdev); +extern void e530_24x2c_led_port_set(struct led_classdev *led_cdev, enum led_brightness set_value); +extern enum led_brightness e530_24x2c_led_port_get(struct led_classdev *led_cdev); + +static struct led_classdev led_dev_system = { + .name = "system", + .brightness_set = e530_24x2c_led_set, + .brightness_get = e530_24x2c_led_get, +}; +static struct led_classdev led_dev_idn = { + .name = "idn", + .brightness_set = e530_24x2c_led_set, + .brightness_get = e530_24x2c_led_get, +}; +static struct led_classdev led_dev_fan1 = { + .name = "fan1", + .brightness_set = e530_24x2c_led_set, + .brightness_get = e530_24x2c_led_get, +}; +static struct led_classdev led_dev_fan2 = { + .name = "fan2", + .brightness_set = e530_24x2c_led_set, + .brightness_get = e530_24x2c_led_get, +}; +static struct led_classdev led_dev_fan3 = { + .name = "fan3", + .brightness_set = e530_24x2c_led_set, + .brightness_get = e530_24x2c_led_get, +}; +static struct led_classdev led_dev_fan4 = { + .name = "fan4", + .brightness_set = e530_24x2c_led_set, + .brightness_get = e530_24x2c_led_get, +}; +static struct led_classdev led_dev_psu1 = { + .name = "psu1", + .brightness_set = e530_24x2c_led_set, + .brightness_get = e530_24x2c_led_get, +}; +static struct led_classdev led_dev_psu2 = { + .name = "psu2", + .brightness_set = e530_24x2c_led_set, + .brightness_get = e530_24x2c_led_get, +}; +static struct led_classdev led_dev_port[PORT_NUM] = { +{ .name = "port1", .brightness_set = e530_24x2c_led_port_set, .brightness_get = e530_24x2c_led_port_get,}, +{ .name = "port2", .brightness_set = e530_24x2c_led_port_set, .brightness_get = e530_24x2c_led_port_get,}, +{ .name = "port3", .brightness_set = e530_24x2c_led_port_set, .brightness_get = e530_24x2c_led_port_get,}, +{ .name = "port4", .brightness_set = e530_24x2c_led_port_set, .brightness_get = e530_24x2c_led_port_get,}, +{ .name = "port5", .brightness_set = e530_24x2c_led_port_set, .brightness_get = e530_24x2c_led_port_get,}, +{ .name = "port6", .brightness_set = e530_24x2c_led_port_set, .brightness_get = e530_24x2c_led_port_get,}, +{ .name = "port7", .brightness_set = e530_24x2c_led_port_set, .brightness_get = e530_24x2c_led_port_get,}, +{ .name = "port8", .brightness_set = e530_24x2c_led_port_set, .brightness_get = e530_24x2c_led_port_get,}, +{ .name = "port9", .brightness_set = e530_24x2c_led_port_set, .brightness_get = e530_24x2c_led_port_get,}, +{ .name = "port10", .brightness_set = e530_24x2c_led_port_set, .brightness_get = e530_24x2c_led_port_get,}, +{ .name = "port11", .brightness_set = e530_24x2c_led_port_set, .brightness_get = e530_24x2c_led_port_get,}, +{ .name = "port12", .brightness_set = e530_24x2c_led_port_set, .brightness_get = e530_24x2c_led_port_get,}, +{ .name = "port13", .brightness_set = e530_24x2c_led_port_set, .brightness_get = e530_24x2c_led_port_get,}, +{ .name = "port14", .brightness_set = e530_24x2c_led_port_set, .brightness_get = e530_24x2c_led_port_get,}, +{ .name = "port15", .brightness_set = e530_24x2c_led_port_set, .brightness_get = e530_24x2c_led_port_get,}, +{ .name = "port16", .brightness_set = e530_24x2c_led_port_set, .brightness_get = e530_24x2c_led_port_get,}, +{ .name = "port17", .brightness_set = e530_24x2c_led_port_set, .brightness_get = e530_24x2c_led_port_get,}, +{ .name = "port18", .brightness_set = e530_24x2c_led_port_set, .brightness_get = e530_24x2c_led_port_get,}, +{ .name = "port19", .brightness_set = e530_24x2c_led_port_set, .brightness_get = e530_24x2c_led_port_get,}, +{ .name = "port20", .brightness_set = e530_24x2c_led_port_set, .brightness_get = e530_24x2c_led_port_get,}, +{ .name = "port21", .brightness_set = e530_24x2c_led_port_set, .brightness_get = e530_24x2c_led_port_get,}, +{ .name = "port22", .brightness_set = e530_24x2c_led_port_set, .brightness_get = e530_24x2c_led_port_get,}, +{ .name = "port23", .brightness_set = e530_24x2c_led_port_set, .brightness_get = e530_24x2c_led_port_get,}, +{ .name = "port24", .brightness_set = e530_24x2c_led_port_set, .brightness_get = e530_24x2c_led_port_get,}, +{ .name = "port25", .brightness_set = e530_24x2c_led_port_set, .brightness_get = e530_24x2c_led_port_get,}, +{ .name = "port26", .brightness_set = e530_24x2c_led_port_set, .brightness_get = e530_24x2c_led_port_get,}, +}; +static unsigned char port_led_mode[PORT_NUM] = {0}; + +void e530_24x2c_led_set(struct led_classdev *led_cdev, enum led_brightness set_value) +{ + int ret = 0; + unsigned char reg = 0; + unsigned char mask = 0; + unsigned char shift = 0; + unsigned char led_value = 0; + struct i2c_client *i2c_led_client = i2c_client_gpio1; + + if (0 == strcmp(led_dev_system.name, led_cdev->name)) + { + reg = 0x2; + mask = 0x60; + shift = 5; + } + else if (0 == strcmp(led_dev_idn.name, led_cdev->name)) + { + reg = 0x2; + mask = 0x10; + shift = 4; + } + else if (0 == strcmp(led_dev_fan1.name, led_cdev->name)) + { + goto not_support; + } + else if (0 == strcmp(led_dev_fan2.name, led_cdev->name)) + { + goto not_support; + } + else if (0 == strcmp(led_dev_fan3.name, led_cdev->name)) + { + goto not_support; + } + else if (0 == strcmp(led_dev_fan4.name, led_cdev->name)) + { + goto not_support; + } + else if (0 == strcmp(led_dev_psu1.name, led_cdev->name)) + { + goto not_support; + } + else if (0 == strcmp(led_dev_psu2.name, led_cdev->name)) + { + goto not_support; + } + else + { + goto not_support; + } + + ret = e530_24x2c_smbus_read_reg(i2c_led_client, reg, &led_value); + if (ret != 0) + { + printk(KERN_CRIT "Error: read %s led attr failed\n", led_cdev->name); + return; + } + + led_value = ((led_value & (~mask)) | ((set_value << shift) & (mask))); + + ret = e530_24x2c_smbus_write_reg(i2c_led_client, reg, led_value); + if (ret != 0) + { + printk(KERN_CRIT "Error: write %s led attr failed\n", led_cdev->name); + return; + } + + return; + +not_support: + + printk(KERN_INFO "Error: led not support device:%s\n", led_cdev->name); + return; +} + +enum led_brightness e530_24x2c_led_get(struct led_classdev *led_cdev) +{ + int ret = 0; + unsigned char reg = 0; + unsigned char mask = 0; + unsigned char shift = 0; + unsigned char led_value = 0; + struct i2c_client *i2c_led_client = i2c_client_gpio0; + + if (0 == strcmp(led_dev_system.name, led_cdev->name)) + { + reg = 0x2; + mask = 0x60; + shift = 5; + } + else if (0 == strcmp(led_dev_idn.name, led_cdev->name)) + { + reg = 0x2; + mask = 0x10; + shift = 4; + } + else if (0 == strcmp(led_dev_fan1.name, led_cdev->name)) + { + goto not_support; + } + else if (0 == strcmp(led_dev_fan2.name, led_cdev->name)) + { + goto not_support; + } + else if (0 == strcmp(led_dev_fan3.name, led_cdev->name)) + { + goto not_support; + } + else if (0 == strcmp(led_dev_fan4.name, led_cdev->name)) + { + goto not_support; + } + else if (0 == strcmp(led_dev_psu1.name, led_cdev->name)) + { + goto not_support; + } + else if (0 == strcmp(led_dev_psu2.name, led_cdev->name)) + { + goto not_support; + } + else + { + goto not_support; + } + + ret = e530_24x2c_smbus_read_reg(i2c_led_client, reg, &led_value); + if (ret != 0) + { + printk(KERN_CRIT "Error: read %s led attr failed\n", led_cdev->name); + return 0; + } + + led_value = ((led_value & mask) >> shift); + + return led_value; + +not_support: + + printk(KERN_INFO "Error: not support device:%s\n", led_cdev->name); + return 0; +} + +void e530_24x2c_led_port_set(struct led_classdev *led_cdev, enum led_brightness set_value) +{ + int portNum = 0; + + sscanf(led_cdev->name, "port%d", &portNum); + + port_led_mode[portNum-1] = set_value; + + return; +} + +enum led_brightness e530_24x2c_led_port_get(struct led_classdev *led_cdev) +{ + int portNum = 0; + + sscanf(led_cdev->name, "port%d", &portNum); + + return port_led_mode[portNum-1]; +} + +static int e530_24x2c_init_led(void) +{ + int ret = 0; + int i = 0; + + ret = led_classdev_register(NULL, &led_dev_system); + if (ret != 0) + { + printk(KERN_CRIT "create e530_24x2c led_dev_system device failed\n"); + return -1; + } + + ret = led_classdev_register(NULL, &led_dev_idn); + if (ret != 0) + { + printk(KERN_CRIT "create e530_24x2c led_dev_idn device failed\n"); + return -1; + } + + ret = led_classdev_register(NULL, &led_dev_fan1); + if (ret != 0) + { + printk(KERN_CRIT "create e530_24x2c led_dev_fan1 device failed\n"); + return -1; + } + + ret = led_classdev_register(NULL, &led_dev_fan2); + if (ret != 0) + { + printk(KERN_CRIT "create e530_24x2c led_dev_fan2 device failed\n"); + return -1; + } + + ret = led_classdev_register(NULL, &led_dev_fan3); + if (ret != 0) + { + printk(KERN_CRIT "create e530_24x2c led_dev_fan3 device failed\n"); + return -1; + } + + ret = led_classdev_register(NULL, &led_dev_fan4); + if (ret != 0) + { + printk(KERN_CRIT "create e530_24x2c led_dev_fan4 device failed\n"); + return -1; + } + + ret = led_classdev_register(NULL, &led_dev_psu1); + if (ret != 0) + { + printk(KERN_CRIT "create e530_24x2c led_dev_psu1 device failed\n"); + return -1; + } + + ret = led_classdev_register(NULL, &led_dev_psu2); + if (ret != 0) + { + printk(KERN_CRIT "create e530_24x2c led_dev_psu2 device failed\n"); + return -1; + } + + for (i=0; i SFP_NUM+QSFP_NUM)) + { + printk(KERN_CRIT "sfp read presence, invalid port number!\n"); + buf[0] = '\0'; + return 0; + } + + spin_lock_irqsave(&(sfp_info[portNum].lock), flags); + presence = sfp_info[portNum].presence; + spin_unlock_irqrestore(&(sfp_info[portNum].lock), flags); + return sprintf(buf, "%d\n", presence); +} + +static ssize_t e530_24x2c_sfp_write_presence(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + int portNum = 0; + const char *name = dev_name(dev); + unsigned long flags = 0; + int presence = simple_strtol(buf, NULL, 10); + + sscanf(name, "sfp%d", &portNum); + + if ((portNum < 1) || (portNum > SFP_NUM+QSFP_NUM)) + { + printk(KERN_CRIT "sfp read presence, invalid port number!\n"); + return size; + } + + spin_lock_irqsave(&(sfp_info[portNum].lock), flags); + sfp_info[portNum].presence = presence; + spin_unlock_irqrestore(&(sfp_info[portNum].lock), flags); + + return size; +} + +static ssize_t e530_24x2c_sfp_read_enable(struct device *dev, struct device_attribute *attr, char *buf) +{ + int ret = 0; + unsigned char value = 0; + unsigned char reg_no = 0; + unsigned char input_bank = 0; + int portNum = 0; + const char *name = dev_name(dev); + struct i2c_client *i2c_sfp_client = NULL; + unsigned long flags = 0; + + sscanf(name, "sfp%d", &portNum); + + if ((portNum < 1) || (portNum > SFP_NUM+QSFP_NUM)) + { + printk(KERN_CRIT "sfp read enable, invalid port number!\n"); + value = 0; + } + + if (portNum <= SFP_NUM) + { + if (portNum >= 1 && portNum <= 16) + { + reg_no = portNum - 1; + i2c_sfp_client = i2c_client_gpio0; + } + else if (portNum > 16 && portNum <= 24) + { + reg_no = portNum - 17; + i2c_sfp_client = i2c_client_gpio2; + } + + input_bank = (reg_no/8) + 0x2; + ret = e530_24x2c_smbus_read_reg(i2c_sfp_client, input_bank, &value); + if (ret != 0) + { + return sprintf(buf, "Error: read sfp enable: %s failed\n", attr->attr.name); + } + + value = ((value & (1<<(reg_no%8))) ? 0 : 1 ); + } + else + { + spin_lock_irqsave(&(sfp_info[portNum].lock), flags); + value = sfp_info[portNum].enable; + spin_unlock_irqrestore(&(sfp_info[portNum].lock), flags); + } + + return sprintf(buf, "%d\n", value); +} + +static ssize_t e530_24x2c_sfp_write_enable(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + int ret = 0; + unsigned char value = 0; + unsigned char set_value = simple_strtol(buf, NULL, 10); + unsigned char reg_no = 0; + unsigned char input_bank = 0; + unsigned char output_bank = 0; + int portNum = 0; + const char *name = dev_name(dev); + struct i2c_client *i2c_sfp_client = NULL; + unsigned long flags = 0; + + sscanf(name, "sfp%d", &portNum); + + if ((portNum < 1) || (portNum > SFP_NUM+QSFP_NUM)) + { + printk(KERN_CRIT "sfp read enable, invalid port number!\n"); + return size; + } + + if (portNum <= SFP_NUM) + { + if (portNum >= 1 && portNum <= 16) + { + reg_no = portNum - 1; + i2c_sfp_client = i2c_client_gpio0; + } + else if (portNum > 16 && portNum <= 24) + { + reg_no = portNum - 17; + i2c_sfp_client = i2c_client_gpio2; + } + + set_value = ((set_value > 0) ? 0 : 1); + + input_bank = (reg_no/8) + 0x2; + ret = e530_24x2c_smbus_read_reg(i2c_sfp_client, input_bank, &value); + if (ret != 0) + { + printk(KERN_CRIT "Error: read %s enable failed\n", name); + return size; + } + + if (set_value) + { + value = (value | (1<<(reg_no % 8))); + } + else + { + value = (value & (~(1<<(reg_no % 8)))); + } + + output_bank = (reg_no/8) + 0x2; + ret = e530_24x2c_smbus_write_reg(i2c_sfp_client, output_bank, value); + if (ret != 0) + { + printk(KERN_CRIT "Error: write %s enable failed\n", name); + return size; + } + } + else + { + set_value = ((set_value > 0) ? 1 : 0); + + spin_lock_irqsave(&(sfp_info[portNum].lock), flags); + sfp_info[portNum].enable = set_value; + spin_unlock_irqrestore(&(sfp_info[portNum].lock), flags); + } + + return size; +} + +static ssize_t e530_24x2c_sfp_read_eeprom(struct device *dev, struct device_attribute *attr, char *buf) +{ + int portNum = 0; + const char *name = dev_name(dev); + unsigned long flags = 0; + size_t size = 0; + + sscanf(name, "sfp%d", &portNum); + + if ((portNum < 1) || (portNum > SFP_NUM+QSFP_NUM)) + { + printk(KERN_CRIT "sfp read eeprom, invalid port number!\n"); + buf[0] = '\0'; + return 0; + } + + spin_lock_irqsave(&(sfp_info[portNum].lock), flags); + memcpy(buf, sfp_info[portNum].eeprom[0], sfp_info[portNum].data_len[0]); + size = sfp_info[portNum].data_len[0]; + spin_unlock_irqrestore(&(sfp_info[portNum].lock), flags); + + return size; +} + +static ssize_t e530_24x2c_sfp_write_eeprom(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + int portNum = 0; + const char *name = dev_name(dev); + unsigned long flags = 0; + + sscanf(name, "sfp%d", &portNum); + + if ((portNum < 1) || (portNum > SFP_NUM+QSFP_NUM)) + { + printk(KERN_CRIT "sfp write eeprom, invalid port number!\n"); + return size; + } + + spin_lock_irqsave(&(sfp_info[portNum].lock), flags); + memcpy(sfp_info[portNum].eeprom[0], buf, size); + sfp_info[portNum].data_len[0] = size; + spin_unlock_irqrestore(&(sfp_info[portNum].lock), flags); + + return size; +} + +static DEVICE_ATTR(sfp_presence, S_IRUGO|S_IWUSR, e530_24x2c_sfp_read_presence, e530_24x2c_sfp_write_presence); +static DEVICE_ATTR(sfp_enable, S_IRUGO|S_IWUSR, e530_24x2c_sfp_read_enable, e530_24x2c_sfp_write_enable); +static DEVICE_ATTR(sfp_eeprom, S_IRUGO|S_IWUSR, e530_24x2c_sfp_read_eeprom, e530_24x2c_sfp_write_eeprom); + +static int e530_24x2c_init_sfp(void) +{ + int ret = 0; + int i = 0; + + sfp_class = class_create(THIS_MODULE, "sfp"); + if (IS_INVALID_PTR(sfp_class)) + { + sfp_class = NULL; + printk(KERN_CRIT "create e530_24x2c class sfp failed\n"); + return -1; + } + + for (i=1; i<=SFP_NUM+QSFP_NUM; i++) + { + memset(&(sfp_info[i].eeprom), 0, sizeof(sfp_info[i].eeprom)); + memset(&(sfp_info[i].data_len), 0, sizeof(sfp_info[i].data_len)); + spin_lock_init(&(sfp_info[i].lock)); + + sfp_dev[i] = device_create(sfp_class, NULL, MKDEV(223,i), NULL, "sfp%d", i); + if (IS_INVALID_PTR(sfp_dev[i])) + { + sfp_dev[i] = NULL; + printk(KERN_CRIT "create e530_24x2c sfp[%d] device failed\n", i); + continue; + } + + ret = device_create_file(sfp_dev[i], &dev_attr_sfp_presence); + if (ret != 0) + { + printk(KERN_CRIT "create e530_24x2c sfp[%d] device attr:presence failed\n", i); + continue; + } + + ret = device_create_file(sfp_dev[i], &dev_attr_sfp_enable); + if (ret != 0) + { + printk(KERN_CRIT "create e530_24x2c sfp[%d] device attr:enable failed\n", i); + continue; + } + + ret = device_create_file(sfp_dev[i], &dev_attr_sfp_eeprom); + if (ret != 0) + { + printk(KERN_CRIT "create e530_24x2c sfp[%d] device attr:eeprom failed\n", i); + continue; + } + } + + return ret; +} + +static int e530_24x2c_exit_sfp(void) +{ + int i = 0; + + for (i=1; i<=SFP_NUM+QSFP_NUM; i++) + { + if (IS_VALID_PTR(sfp_dev[i])) + { + device_remove_file(sfp_dev[i], &dev_attr_sfp_presence); + device_remove_file(sfp_dev[i], &dev_attr_sfp_enable); + device_remove_file(sfp_dev[i], &dev_attr_sfp_eeprom); + device_destroy(sfp_class, MKDEV(223,i)); + sfp_dev[i] = NULL; + } + } + + if (IS_VALID_PTR(sfp_class)) + { + class_destroy(sfp_class); + sfp_class = NULL; + } + + return 0; +} +#endif + +static int e530_24x2c_init(void) +{ + int ret = 0; + int failed = 0; + + printk(KERN_ALERT "install e530_24x2c board dirver...\n"); + + ret = e530_24x2c_init_i2c_master(); + if (ret != 0) + { + failed = 1; + } + + ret = e530_24x2c_init_i2c_gpio(); + if (ret != 0) + { + failed = 1; + } + + ret = e530_24x2c_init_psu(); + if (ret != 0) + { + failed = 1; + } + + ret = e530_24x2c_init_led(); + if (ret != 0) + { + failed = 1; + } + + ret = e530_24x2c_init_sfp(); + if (ret != 0) + { + failed = 1; + } + + if (failed) + printk(KERN_INFO "install e530_24x2c board driver failed\n"); + else + printk(KERN_ALERT "install e530_24x2c board dirver...ok\n"); + + return 0; +} + +static void e530_24x2c_exit(void) +{ + printk(KERN_INFO "uninstall e530_24x2c board dirver...\n"); + + e530_24x2c_exit_sfp(); + e530_24x2c_exit_led(); + e530_24x2c_exit_psu(); + e530_24x2c_exit_i2c_gpio(); + e530_24x2c_exit_i2c_master(); +} + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_AUTHOR("shil centecNetworks, Inc"); +MODULE_DESCRIPTION("e530-24x2c board driver"); +module_init(e530_24x2c_init); +module_exit(e530_24x2c_exit); diff --git a/platform/centec-arm64/sonic-platform-modules-e530/24x2c/service/24x2c_platform.service b/platform/centec-arm64/sonic-platform-modules-e530/24x2c/service/24x2c_platform.service new file mode 100644 index 000000000000..50e35ad601cb --- /dev/null +++ b/platform/centec-arm64/sonic-platform-modules-e530/24x2c/service/24x2c_platform.service @@ -0,0 +1,13 @@ +[Unit] +Description=Centec modules init +After=local-fs.target +Before=syncd.service + +[Service] +Type=oneshot +ExecStart=-/etc/init.d/platform-modules-e530-24x2c start +ExecStop=-/etc/init.d/platform-modules-e530-24x2c stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/centec-arm64/sonic-platform-modules-e530/24x2c/setup.py b/platform/centec-arm64/sonic-platform-modules-e530/24x2c/setup.py new file mode 100755 index 000000000000..17f8b8f01b55 --- /dev/null +++ b/platform/centec-arm64/sonic-platform-modules-e530/24x2c/setup.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +import os +from setuptools import setup +os.listdir + +setup( + name='24x2c', + version='1.1', + description='Module to initialize centec e530-24x2c platforms', + + packages=['24x2c'], + package_dir={'24x2c': '24x2c/classes'}, +) + diff --git a/platform/centec-arm64/sonic-platform-modules-e530/48t4x_p/classes/__init__.py b/platform/centec-arm64/sonic-platform-modules-e530/48t4x_p/classes/__init__.py new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/platform/centec-arm64/sonic-platform-modules-e530/48t4x_p/modules/Makefile b/platform/centec-arm64/sonic-platform-modules-e530/48t4x_p/modules/Makefile new file mode 100644 index 000000000000..47327a1a0037 --- /dev/null +++ b/platform/centec-arm64/sonic-platform-modules-e530/48t4x_p/modules/Makefile @@ -0,0 +1 @@ +obj-m := centec_e530_48t4x_p_platform.o diff --git a/platform/centec-arm64/sonic-platform-modules-e530/48t4x_p/modules/centec_e530_48t4x_p_platform.c b/platform/centec-arm64/sonic-platform-modules-e530/48t4x_p/modules/centec_e530_48t4x_p_platform.c new file mode 100644 index 000000000000..aedbe6601a07 --- /dev/null +++ b/platform/centec-arm64/sonic-platform-modules-e530/48t4x_p/modules/centec_e530_48t4x_p_platform.c @@ -0,0 +1,1023 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SEP(XXX) 1 +#define IS_INVALID_PTR(_PTR_) ((_PTR_ == NULL) || IS_ERR(_PTR_)) +#define IS_VALID_PTR(_PTR_) (!IS_INVALID_PTR(_PTR_)) + +#if SEP("defines") +#define SFP_NUM 4 +#define PORT_NUM (48+SFP_NUM) +#endif + +#if SEP("i2c:smbus") +static int e530_48t4x_p_smbus_read_reg(struct i2c_client *client, unsigned char reg, unsigned char* value) +{ + int ret = 0; + + if (IS_INVALID_PTR(client)) + { + printk(KERN_CRIT "invalid i2c client"); + return -1; + } + + ret = i2c_smbus_read_byte_data(client, reg); + if (ret >= 0) { + *value = (unsigned char)ret; + } + else + { + *value = 0; + printk(KERN_CRIT "i2c_smbus op failed: ret=%d reg=%d\n",ret ,reg); + return ret; + } + + return 0; +} + +static int e530_48t4x_p_smbus_write_reg(struct i2c_client *client, unsigned char reg, unsigned char value) +{ + int ret = 0; + + if (IS_INVALID_PTR(client)) + { + printk(KERN_CRIT "invalid i2c client"); + return -1; + } + + ret = i2c_smbus_write_byte_data(client, reg, value); + if (ret != 0) + { + printk(KERN_CRIT "i2c_smbus op failed: ret=%d reg=%d\n",ret ,reg); + return ret; + } + + return 0; +} +#endif + +#if SEP("i2c:master") +static struct i2c_adapter *i2c_adp_master = NULL; /* i2c-1-cpu */ + +static int e530_48t4x_p_init_i2c_master(void) +{ + /* find i2c-core master */ + i2c_adp_master = i2c_get_adapter(0); + if(IS_INVALID_PTR(i2c_adp_master)) + { + i2c_adp_master = NULL; + printk(KERN_CRIT "e530_48t4x_p_init_i2c_master can't find i2c-core bus\n"); + return -1; + } + + return 0; +} + +static int e530_48t4x_p_exit_i2c_master(void) +{ + /* uninstall i2c-core master */ + if(IS_VALID_PTR(i2c_adp_master)) { + i2c_put_adapter(i2c_adp_master); + i2c_adp_master = NULL; + } + + return 0; +} +#endif + +//TODO!!! +#if SEP("i2c:gpio") +static struct i2c_adapter *i2c_adp_gpio0 = NULL; /* gpio0 */ +static struct i2c_board_info i2c_dev_gpio0 = { + I2C_BOARD_INFO("i2c-gpio0", 0x22), +}; +static struct i2c_client *i2c_client_gpio0 = NULL; + +static int e530_48t4x_p_init_i2c_gpio(void) +{ + int ret = 0; + + if (IS_INVALID_PTR(i2c_adp_master)) + { + printk(KERN_CRIT "e530_48t4x_p_init_i2c_gpio can't find i2c-core bus\n"); + return -1; + } + + i2c_adp_gpio0 = i2c_get_adapter(0); + if(IS_INVALID_PTR(i2c_adp_gpio0)) + { + i2c_adp_gpio0 = NULL; + printk(KERN_CRIT "get e530_48t4x_p gpio0 i2c-adp failed\n"); + return -1; + } + + i2c_client_gpio0 = i2c_new_device(i2c_adp_gpio0, &i2c_dev_gpio0); + if(IS_INVALID_PTR(i2c_client_gpio0)) + { + i2c_client_gpio0 = NULL; + printk(KERN_CRIT "create e530_48t4x_p board i2c client gpio0 failed\n"); + return -1; + } + + /* gpio0 */ + /* tx enable and release mac led and close indicate led */ + ret = e530_48t4x_p_smbus_write_reg(i2c_client_gpio0, 0x02, 0xf0); + /* bank 0 : output bank 1 : input */ + ret += e530_48t4x_p_smbus_write_reg(i2c_client_gpio0, 0x06, 0x00); + ret += e530_48t4x_p_smbus_write_reg(i2c_client_gpio0, 0x07, 0xff); + + if (ret) + { + printk(KERN_CRIT "init e530_48t4x_p board i2c gpio config failed\n"); + return -1; + } + + return 0; +} + +static int e530_48t4x_p_exit_i2c_gpio(void) +{ + if(IS_VALID_PTR(i2c_client_gpio0)) { + i2c_unregister_device(i2c_client_gpio0); + i2c_client_gpio0 = NULL; + } + + if(IS_VALID_PTR(i2c_adp_gpio0)) + { + i2c_put_adapter(i2c_adp_gpio0); + i2c_adp_gpio0 = NULL; + } + + return 0; +} +#endif + + +#if SEP("drivers:psu") +static struct class* psu_class = NULL; +static struct device* psu_dev_psu1 = NULL; +static struct device* psu_dev_psu2 = NULL; + +static ssize_t e530_48t4x_p_psu_read_presence(struct device *dev, struct device_attribute *attr, char *buf) +{ + int ret = 0; + unsigned char present_no = 0; + unsigned char present = 0; + unsigned char value = 0; + struct i2c_client *i2c_psu_client = NULL; + + if (psu_dev_psu1 == dev) + { + i2c_psu_client = i2c_client_gpio0; + present_no = 9; + } + else if (psu_dev_psu2 == dev) + { + i2c_psu_client = i2c_client_gpio0; + present_no = 13; + } + else + { + return sprintf(buf, "Error: unknown psu device\n"); + } + + if (IS_INVALID_PTR(i2c_psu_client)) + { + return sprintf(buf, "Error: psu i2c-adapter invalid\n"); + } + + ret = e530_48t4x_p_smbus_read_reg(i2c_psu_client, present_no/8, &present); + if (ret != 0) + { + return sprintf(buf, "Error: read psu data:%s failed\n", attr->attr.name); + } + + value = ((present & (1<<(present_no%8))) ? 1 : 0 ); + + return sprintf(buf, "%d\n", value); +} + +static ssize_t e530_48t4x_p_psu_read_status(struct device *dev, struct device_attribute *attr, char *buf) +{ + int ret = 0; + unsigned char workstate_no = 0; + unsigned char workstate = 0; + unsigned char value = 0; + struct i2c_client *i2c_psu_client = NULL; + + if (psu_dev_psu1 == dev) + { + i2c_psu_client = i2c_client_gpio0; + workstate_no = 11; + } + else if (psu_dev_psu2 == dev) + { + i2c_psu_client = i2c_client_gpio0; + workstate_no = 15; + } + else + { + return sprintf(buf, "Error: unknown psu device\n"); + } + + if (IS_INVALID_PTR(i2c_psu_client)) + { + return sprintf(buf, "Error: psu i2c-adapter invalid\n"); + } + + ret = e530_48t4x_p_smbus_read_reg(i2c_psu_client, workstate_no/8, &workstate); + if (ret != 0) + { + return sprintf(buf, "Error: read psu data:%s failed\n", attr->attr.name); + } + + value = ((workstate & (1<<(workstate_no%8))) ? 0 : 1 ); + + return sprintf(buf, "%d\n", value); +} + +static DEVICE_ATTR(psu_presence, S_IRUGO, e530_48t4x_p_psu_read_presence, NULL); +static DEVICE_ATTR(psu_status, S_IRUGO, e530_48t4x_p_psu_read_status, NULL); + +static int e530_48t4x_p_init_psu(void) +{ + int ret = 0; + + psu_class = class_create(THIS_MODULE, "psu"); + if (IS_INVALID_PTR(psu_class)) + { + psu_class = NULL; + printk(KERN_CRIT "create e530_48t4x_p class psu failed\n"); + return -1; + } + + psu_dev_psu1 = device_create(psu_class, NULL, MKDEV(222,0), NULL, "psu1"); + if (IS_INVALID_PTR(psu_dev_psu1)) + { + psu_dev_psu1 = NULL; + printk(KERN_CRIT "create e530_48t4x_p psu1 device failed\n"); + return -1; + } + + psu_dev_psu2 = device_create(psu_class, NULL, MKDEV(222,1), NULL, "psu2"); + if (IS_INVALID_PTR(psu_dev_psu2)) + { + psu_dev_psu2 = NULL; + printk(KERN_CRIT "create e530_48t4x_p psu2 device failed\n"); + return -1; + } + + ret = device_create_file(psu_dev_psu1, &dev_attr_psu_presence); + if (ret != 0) + { + printk(KERN_CRIT "create e530_48t4x_p psu1 device attr:presence failed\n"); + return -1; + } + + ret = device_create_file(psu_dev_psu1, &dev_attr_psu_status); + if (ret != 0) + { + printk(KERN_CRIT "create e530_48t4x_p psu1 device attr:status failed\n"); + return -1; + } + + ret = device_create_file(psu_dev_psu2, &dev_attr_psu_presence); + if (ret != 0) + { + printk(KERN_CRIT "create e530_48t4x_p psu2 device attr:presence failed\n"); + return -1; + } + + ret = device_create_file(psu_dev_psu2, &dev_attr_psu_status); + if (ret != 0) + { + printk(KERN_CRIT "create e530_48t4x_p psu2 device attr:status failed\n"); + return -1; + } + + return 0; +} + +static int e530_48t4x_p_exit_psu(void) +{ + if (IS_VALID_PTR(psu_dev_psu1)) + { + device_remove_file(psu_dev_psu1, &dev_attr_psu_presence); + device_remove_file(psu_dev_psu1, &dev_attr_psu_status); + device_destroy(psu_class, MKDEV(222,0)); + } + + if (IS_VALID_PTR(psu_dev_psu2)) + { + device_remove_file(psu_dev_psu2, &dev_attr_psu_presence); + device_remove_file(psu_dev_psu2, &dev_attr_psu_status); + device_destroy(psu_class, MKDEV(222,1)); + } + + if (IS_VALID_PTR(psu_class)) + { + class_destroy(psu_class); + psu_class = NULL; + } + + return 0; +} +#endif + +#if SEP("drivers:leds") +extern void e530_48t4x_p_led_set(struct led_classdev *led_cdev, enum led_brightness set_value); +extern enum led_brightness e530_48t4x_p_led_get(struct led_classdev *led_cdev); +extern void e530_48t4x_p_led_port_set(struct led_classdev *led_cdev, enum led_brightness set_value); +extern enum led_brightness e530_48t4x_p_led_port_get(struct led_classdev *led_cdev); + +static struct led_classdev led_dev_system = { + .name = "system", + .brightness_set = e530_48t4x_p_led_set, + .brightness_get = e530_48t4x_p_led_get, +}; +static struct led_classdev led_dev_idn = { + .name = "idn", + .brightness_set = e530_48t4x_p_led_set, + .brightness_get = e530_48t4x_p_led_get, +}; +static struct led_classdev led_dev_fan1 = { + .name = "fan1", + .brightness_set = e530_48t4x_p_led_set, + .brightness_get = e530_48t4x_p_led_get, +}; +static struct led_classdev led_dev_fan2 = { + .name = "fan2", + .brightness_set = e530_48t4x_p_led_set, + .brightness_get = e530_48t4x_p_led_get, +}; +static struct led_classdev led_dev_fan3 = { + .name = "fan3", + .brightness_set = e530_48t4x_p_led_set, + .brightness_get = e530_48t4x_p_led_get, +}; +static struct led_classdev led_dev_fan4 = { + .name = "fan4", + .brightness_set = e530_48t4x_p_led_set, + .brightness_get = e530_48t4x_p_led_get, +}; +static struct led_classdev led_dev_psu1 = { + .name = "psu1", + .brightness_set = e530_48t4x_p_led_set, + .brightness_get = e530_48t4x_p_led_get, +}; +static struct led_classdev led_dev_psu2 = { + .name = "psu2", + .brightness_set = e530_48t4x_p_led_set, + .brightness_get = e530_48t4x_p_led_get, +}; +static struct led_classdev led_dev_port[PORT_NUM] = { +{ .name = "port1", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port2", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port3", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port4", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port5", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port6", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port7", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port8", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port9", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port10", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port11", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port12", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port13", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port14", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port15", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port16", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port17", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port18", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port19", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port20", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port21", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port22", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port23", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port24", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port25", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port26", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port27", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port28", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port29", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port30", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port31", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port32", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port33", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port34", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port35", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port36", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port37", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port38", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port39", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port40", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port41", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port42", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port43", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port44", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port45", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port46", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port47", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port48", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port49", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port50", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port51", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +{ .name = "port52", .brightness_set = e530_48t4x_p_led_port_set, .brightness_get = e530_48t4x_p_led_port_get,}, +}; +static unsigned char port_led_mode[PORT_NUM] = {0}; + +void e530_48t4x_p_led_set(struct led_classdev *led_cdev, enum led_brightness set_value) +{ + int ret = 0; + unsigned char reg = 0; + unsigned char mask = 0; + unsigned char shift = 0; + unsigned char led_value = 0; + struct i2c_client *i2c_led_client = i2c_client_gpio0; + + if (0 == strcmp(led_dev_system.name, led_cdev->name)) + { + reg = 0x2; + mask = 0x60; + shift = 5; + } + else if (0 == strcmp(led_dev_idn.name, led_cdev->name)) + { + reg = 0x2; + mask = 0x10; + shift = 4; + } + else if (0 == strcmp(led_dev_fan1.name, led_cdev->name)) + { + goto not_support; + } + else if (0 == strcmp(led_dev_fan2.name, led_cdev->name)) + { + goto not_support; + } + else if (0 == strcmp(led_dev_fan3.name, led_cdev->name)) + { + goto not_support; + } + else if (0 == strcmp(led_dev_fan4.name, led_cdev->name)) + { + goto not_support; + } + else if (0 == strcmp(led_dev_psu1.name, led_cdev->name)) + { + goto not_support; + } + else if (0 == strcmp(led_dev_psu2.name, led_cdev->name)) + { + goto not_support; + } + else + { + goto not_support; + } + + ret = e530_48t4x_p_smbus_read_reg(i2c_led_client, reg, &led_value); + if (ret != 0) + { + printk(KERN_CRIT "Error: read %s led attr failed\n", led_cdev->name); + return; + } + + led_value = ((led_value & (~mask)) | ((set_value << shift) & (mask))); + + ret = e530_48t4x_p_smbus_write_reg(i2c_led_client, reg, led_value); + if (ret != 0) + { + printk(KERN_CRIT "Error: write %s led attr failed\n", led_cdev->name); + return; + } + + return; + +not_support: + + printk(KERN_INFO "Error: led not support device:%s\n", led_cdev->name); + return; +} + +enum led_brightness e530_48t4x_p_led_get(struct led_classdev *led_cdev) +{ + int ret = 0; + unsigned char reg = 0; + unsigned char mask = 0; + unsigned char shift = 0; + unsigned char led_value = 0; + struct i2c_client *i2c_led_client = i2c_client_gpio0; + + if (0 == strcmp(led_dev_system.name, led_cdev->name)) + { + reg = 0x2; + mask = 0x60; + shift = 5; + } + else if (0 == strcmp(led_dev_idn.name, led_cdev->name)) + { + reg = 0x2; + mask = 0x10; + shift = 4; + } + else if (0 == strcmp(led_dev_fan1.name, led_cdev->name)) + { + goto not_support; + } + else if (0 == strcmp(led_dev_fan2.name, led_cdev->name)) + { + goto not_support; + } + else if (0 == strcmp(led_dev_fan3.name, led_cdev->name)) + { + goto not_support; + } + else if (0 == strcmp(led_dev_fan4.name, led_cdev->name)) + { + goto not_support; + } + else if (0 == strcmp(led_dev_psu1.name, led_cdev->name)) + { + goto not_support; + } + else if (0 == strcmp(led_dev_psu2.name, led_cdev->name)) + { + goto not_support; + } + else + { + goto not_support; + } + + ret = e530_48t4x_p_smbus_read_reg(i2c_led_client, reg, &led_value); + if (ret != 0) + { + printk(KERN_CRIT "Error: read %s led attr failed\n", led_cdev->name); + return 0; + } + + led_value = ((led_value & mask) >> shift); + + return led_value; + +not_support: + + printk(KERN_INFO "Error: not support device:%s\n", led_cdev->name); + return 0; +} + +void e530_48t4x_p_led_port_set(struct led_classdev *led_cdev, enum led_brightness set_value) +{ + int portNum = 0; + + sscanf(led_cdev->name, "port%d", &portNum); + + port_led_mode[portNum-1] = set_value; + + return; +} + +enum led_brightness e530_48t4x_p_led_port_get(struct led_classdev *led_cdev) +{ + int portNum = 0; + + sscanf(led_cdev->name, "port%d", &portNum); + + return port_led_mode[portNum-1]; +} + +static int e530_48t4x_p_init_led(void) +{ + int ret = 0; + int i = 0; + + ret = led_classdev_register(NULL, &led_dev_system); + if (ret != 0) + { + printk(KERN_CRIT "create e530_48t4x_p led_dev_system device failed\n"); + return -1; + } + + ret = led_classdev_register(NULL, &led_dev_idn); + if (ret != 0) + { + printk(KERN_CRIT "create e530_48t4x_p led_dev_idn device failed\n"); + return -1; + } + + ret = led_classdev_register(NULL, &led_dev_fan1); + if (ret != 0) + { + printk(KERN_CRIT "create e530_48t4x_p led_dev_fan1 device failed\n"); + return -1; + } + + ret = led_classdev_register(NULL, &led_dev_fan2); + if (ret != 0) + { + printk(KERN_CRIT "create e530_48t4x_p led_dev_fan2 device failed\n"); + return -1; + } + + ret = led_classdev_register(NULL, &led_dev_fan3); + if (ret != 0) + { + printk(KERN_CRIT "create e530_48t4x_p led_dev_fan3 device failed\n"); + return -1; + } + + ret = led_classdev_register(NULL, &led_dev_fan4); + if (ret != 0) + { + printk(KERN_CRIT "create e530_48t4x_p led_dev_fan4 device failed\n"); + return -1; + } + + ret = led_classdev_register(NULL, &led_dev_psu1); + if (ret != 0) + { + printk(KERN_CRIT "create e530_48t4x_p led_dev_psu1 device failed\n"); + return -1; + } + + ret = led_classdev_register(NULL, &led_dev_psu2); + if (ret != 0) + { + printk(KERN_CRIT "create e530_48t4x_p led_dev_psu2 device failed\n"); + return -1; + } + + for (i=0; i SFP_NUM)) + { + printk(KERN_CRIT "sfp read presence, invalid port number!\n"); + buf[0] = '\0'; + return 0; + } + + spin_lock_irqsave(&(sfp_info[portNum].lock), flags); + presence = sfp_info[portNum].presence; + spin_unlock_irqrestore(&(sfp_info[portNum].lock), flags); + return sprintf(buf, "%d\n", presence); +} + +static ssize_t e530_48t4x_p_sfp_write_presence(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + int portNum = 0; + const char *name = dev_name(dev); + unsigned long flags = 0; + int presence = simple_strtol(buf, NULL, 10); + + sscanf(name, "sfp%d", &portNum); + + if ((portNum < 1) || (portNum > SFP_NUM)) + { + printk(KERN_CRIT "sfp read presence, invalid port number!\n"); + return size; + } + + spin_lock_irqsave(&(sfp_info[portNum].lock), flags); + sfp_info[portNum].presence = presence; + spin_unlock_irqrestore(&(sfp_info[portNum].lock), flags); + + return size; +} + +static ssize_t e530_48t4x_p_sfp_read_enable(struct device *dev, struct device_attribute *attr, char *buf) +{ + int ret = 0; + unsigned char value = 0; + unsigned char reg_no = 0; + unsigned char input_bank = 0; + int portNum = 0; + const char *name = dev_name(dev); + struct i2c_client *i2c_sfp_client = NULL; + + sscanf(name, "sfp%d", &portNum); + + if ((portNum < 1) || (portNum > SFP_NUM)) + { + printk(KERN_CRIT "sfp read enable, invalid port number!\n"); + value = 0; + } + + reg_no = portNum - 1; + i2c_sfp_client = i2c_client_gpio0; + + input_bank = (reg_no/8) + 0x2; + ret = e530_48t4x_p_smbus_read_reg(i2c_sfp_client, input_bank, &value); + if (ret != 0) + { + return sprintf(buf, "Error: read sfp enable: %s failed\n", attr->attr.name); + } + + value = ((value & (1<<(reg_no%8))) ? 0 : 1 ); + + return sprintf(buf, "%d\n", value); +} + +static ssize_t e530_48t4x_p_sfp_write_enable(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + int ret = 0; + unsigned char value = 0; + unsigned char set_value = simple_strtol(buf, NULL, 10); + unsigned char reg_no = 0; + unsigned char input_bank = 0; + unsigned char output_bank = 0; + int portNum = 0; + const char *name = dev_name(dev); + struct i2c_client *i2c_sfp_client = NULL; + + sscanf(name, "sfp%d", &portNum); + + if ((portNum < 1) || (portNum > SFP_NUM)) + { + printk(KERN_CRIT "sfp read enable, invalid port number!\n"); + return size; + } + + reg_no = portNum - 1; + i2c_sfp_client = i2c_client_gpio0; + + set_value = ((set_value > 0) ? 0 : 1); + + input_bank = (reg_no/8) + 0x2; + ret = e530_48t4x_p_smbus_read_reg(i2c_sfp_client, input_bank, &value); + if (ret != 0) + { + printk(KERN_CRIT "Error: read %s enable failed\n", name); + return size; + } + + if (set_value) + { + value = (value | (1<<(reg_no % 8))); + } + else + { + value = (value & (~(1<<(reg_no % 8)))); + } + + output_bank = (reg_no/8) + 0x2; + ret = e530_48t4x_p_smbus_write_reg(i2c_sfp_client, output_bank, value); + if (ret != 0) + { + printk(KERN_CRIT "Error: write %s enable failed\n", name); + return size; + } + + return size; +} + +static ssize_t e530_48t4x_p_sfp_read_eeprom(struct device *dev, struct device_attribute *attr, char *buf) +{ + int portNum = 0; + const char *name = dev_name(dev); + unsigned long flags = 0; + size_t size = 0; + + sscanf(name, "sfp%d", &portNum); + + if ((portNum < 1) || (portNum > SFP_NUM)) + { + printk(KERN_CRIT "sfp read eeprom, invalid port number!\n"); + buf[0] = '\0'; + return 0; + } + + spin_lock_irqsave(&(sfp_info[portNum].lock), flags); + memcpy(buf, sfp_info[portNum].data, sfp_info[portNum].data_len); + size = sfp_info[portNum].data_len; + spin_unlock_irqrestore(&(sfp_info[portNum].lock), flags); + + return size; +} + +static ssize_t e530_48t4x_p_sfp_write_eeprom(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + int portNum = 0; + const char *name = dev_name(dev); + unsigned long flags = 0; + + sscanf(name, "sfp%d", &portNum); + + if ((portNum < 1) || (portNum > SFP_NUM)) + { + printk(KERN_CRIT "sfp write eeprom, invalid port number!\n"); + return size; + } + + spin_lock_irqsave(&(sfp_info[portNum].lock), flags); + memcpy(sfp_info[portNum].data, buf, size); + sfp_info[portNum].data_len = size; + spin_unlock_irqrestore(&(sfp_info[portNum].lock), flags); + + return size; +} + +static DEVICE_ATTR(sfp_presence, S_IRUGO|S_IWUSR, e530_48t4x_p_sfp_read_presence, e530_48t4x_p_sfp_write_presence); +static DEVICE_ATTR(sfp_enable, S_IRUGO|S_IWUSR, e530_48t4x_p_sfp_read_enable, e530_48t4x_p_sfp_write_enable); +static DEVICE_ATTR(sfp_eeprom, S_IRUGO|S_IWUSR, e530_48t4x_p_sfp_read_eeprom, e530_48t4x_p_sfp_write_eeprom); +static int e530_48t4x_p_init_sfp(void) +{ + int ret = 0; + int i = 0; + + sfp_class = class_create(THIS_MODULE, "sfp"); + if (IS_INVALID_PTR(sfp_class)) + { + sfp_class = NULL; + printk(KERN_CRIT "create e530_48t4x_p class sfp failed\n"); + return -1; + } + + for (i=1; i<=SFP_NUM; i++) + { + memset(&(sfp_info[i].data), 0, MAX_SFP_EEPROM_DATA_LEN+1); + sfp_info[i].data_len = 0; + spin_lock_init(&(sfp_info[i].lock)); + + sfp_dev[i] = device_create(sfp_class, NULL, MKDEV(223,i), NULL, "sfp%d", i); + if (IS_INVALID_PTR(sfp_dev[i])) + { + sfp_dev[i] = NULL; + printk(KERN_CRIT "create e530_48t4x_p sfp[%d] device failed\n", i); + continue; + } + + ret = device_create_file(sfp_dev[i], &dev_attr_sfp_presence); + if (ret != 0) + { + printk(KERN_CRIT "create e530_48t4x_p sfp[%d] device attr:presence failed\n", i); + continue; + } + + ret = device_create_file(sfp_dev[i], &dev_attr_sfp_enable); + if (ret != 0) + { + printk(KERN_CRIT "create e530_48t4x_p sfp[%d] device attr:enable failed\n", i); + continue; + } + + ret = device_create_file(sfp_dev[i], &dev_attr_sfp_eeprom); + if (ret != 0) + { + printk(KERN_CRIT "create e530_48t4x_p sfp[%d] device attr:eeprom failed\n", i); + continue; + } + } + + return ret; +} + +static int e530_48t4x_p_exit_sfp(void) +{ + int i = 0; + + for (i=1; i<=SFP_NUM; i++) + { + if (IS_VALID_PTR(sfp_dev[i])) + { + device_remove_file(sfp_dev[i], &dev_attr_sfp_presence); + device_remove_file(sfp_dev[i], &dev_attr_sfp_enable); + device_remove_file(sfp_dev[i], &dev_attr_sfp_eeprom); + device_destroy(sfp_class, MKDEV(223,i)); + sfp_dev[i] = NULL; + } + } + + if (IS_VALID_PTR(sfp_class)) + { + class_destroy(sfp_class); + sfp_class = NULL; + } + + return 0; +} +#endif + +static int e530_48t4x_p_init(void) +{ + int ret = 0; + int failed = 0; + + printk(KERN_ALERT "install e530_48t4x_p board dirver...\n"); + + ret = e530_48t4x_p_init_i2c_master(); + if (ret != 0) + { + failed = 1; + } + + ret = e530_48t4x_p_init_i2c_gpio(); + if (ret != 0) + { + failed = 1; + } + + ret = e530_48t4x_p_init_psu(); + if (ret != 0) + { + failed = 1; + } + + ret = e530_48t4x_p_init_led(); + if (ret != 0) + { + failed = 1; + } + + ret = e530_48t4x_p_init_sfp(); + if (ret != 0) + { + failed = 1; + } + + if (failed) + printk(KERN_INFO "install e530_48t4x_p board driver failed\n"); + else + printk(KERN_ALERT "install e530_48t4x_p board dirver...ok\n"); + + return 0; +} + +static void e530_48t4x_p_exit(void) +{ + printk(KERN_INFO "uninstall e530_48t4x_p board dirver...\n"); + + e530_48t4x_p_exit_sfp(); + e530_48t4x_p_exit_led(); + e530_48t4x_p_exit_psu(); + e530_48t4x_p_exit_i2c_gpio(); + e530_48t4x_p_exit_i2c_master(); +} + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_AUTHOR("shil centecNetworks, Inc"); +MODULE_DESCRIPTION("e530-48t4x-p board driver"); +module_init(e530_48t4x_p_init); +module_exit(e530_48t4x_p_exit); diff --git a/platform/centec-arm64/sonic-platform-modules-e530/48t4x_p/service/48t4x_p_platform.service b/platform/centec-arm64/sonic-platform-modules-e530/48t4x_p/service/48t4x_p_platform.service new file mode 100644 index 000000000000..957f232259ad --- /dev/null +++ b/platform/centec-arm64/sonic-platform-modules-e530/48t4x_p/service/48t4x_p_platform.service @@ -0,0 +1,13 @@ +[Unit] +Description=Centec modules init +After=local-fs.target +Before=syncd.service + +[Service] +Type=oneshot +ExecStart=-/etc/init.d/platform-modules-e530-48t4x-p start +ExecStop=-/etc/init.d/platform-modules-e530-48t4x-p stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/centec-arm64/sonic-platform-modules-e530/48t4x_p/setup.py b/platform/centec-arm64/sonic-platform-modules-e530/48t4x_p/setup.py new file mode 100755 index 000000000000..eee1cd2a841c --- /dev/null +++ b/platform/centec-arm64/sonic-platform-modules-e530/48t4x_p/setup.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +import os +from setuptools import setup +os.listdir + +setup( + name='48t4x_p', + version='1.1', + description='Module to initialize centec e530-48t4x-p platforms', + + packages=['48t4x_p'], + package_dir={'48t4x_p': '48t4x_p/classes'}, +) + diff --git a/platform/centec-arm64/sonic-platform-modules-e530/LICENSE b/platform/centec-arm64/sonic-platform-modules-e530/LICENSE new file mode 100644 index 000000000000..2d14d2b7785f --- /dev/null +++ b/platform/centec-arm64/sonic-platform-modules-e530/LICENSE @@ -0,0 +1,15 @@ +Copyright (C) 2019 Centec, Inc + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. diff --git a/platform/centec-arm64/sonic-platform-modules-e530/README.md b/platform/centec-arm64/sonic-platform-modules-e530/README.md new file mode 100644 index 000000000000..6b907de17378 --- /dev/null +++ b/platform/centec-arm64/sonic-platform-modules-e530/README.md @@ -0,0 +1 @@ +platform drivers for Centec E530 for the SONiC project diff --git a/platform/centec-arm64/sonic-platform-modules-e530/debian/changelog b/platform/centec-arm64/sonic-platform-modules-e530/debian/changelog new file mode 100644 index 000000000000..6ac3ca4827b9 --- /dev/null +++ b/platform/centec-arm64/sonic-platform-modules-e530/debian/changelog @@ -0,0 +1,11 @@ +sonic-centec-platform-modules (1.1) unstable; urgency=low + + * Add support for centec e530-48t4x-p and e530-24x2c + + -- shil Fri, 15 Nov 2019 13:36:54 +0800 + +sonic-centec-platform-modules (1.0) unstable; urgency=low + + * Initial release + + -- shil Fri, 15 Nov 2019 13:35:06 +0800 diff --git a/platform/centec-arm64/sonic-platform-modules-e530/debian/compat b/platform/centec-arm64/sonic-platform-modules-e530/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/platform/centec-arm64/sonic-platform-modules-e530/debian/compat @@ -0,0 +1 @@ +9 diff --git a/platform/centec-arm64/sonic-platform-modules-e530/debian/control b/platform/centec-arm64/sonic-platform-modules-e530/debian/control new file mode 100644 index 000000000000..2a1bc972a8b2 --- /dev/null +++ b/platform/centec-arm64/sonic-platform-modules-e530/debian/control @@ -0,0 +1,16 @@ +Source: sonic-centec-platform-modules +Section: main +Priority: extra +Maintainer: shil +Build-Depends: debhelper (>= 8.0.0), bzip2 +Standards-Version: 3.9.3 + +Package: platform-modules-e530-48t4x-p +Architecture: arm64 +Depends: linux-image-4.19.0-12-2-arm64-unsigned +Description: kernel modules for platform devices such as fan, led, sfp + +Package: platform-modules-e530-24x2c +Architecture: arm64 +Depends: linux-image-4.19.0-12-2-arm64-unsigned +Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/centec-arm64/sonic-platform-modules-e530/debian/platform-modules-e530-24x2c.init b/platform/centec-arm64/sonic-platform-modules-e530/debian/platform-modules-e530-24x2c.init new file mode 100755 index 000000000000..e0349914b58d --- /dev/null +++ b/platform/centec-arm64/sonic-platform-modules-e530/debian/platform-modules-e530-24x2c.init @@ -0,0 +1,61 @@ +#!/bin/bash +# This script load/unload centec kernel modules + +### BEGIN INIT INFO +# Provides: platform-modules-e530-24x2c +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Load Centec kernel modules +### END INIT INFO + + +function load_kernel_modules() +{ + depmod -a + modprobe centec_e530_24x2c_platform + modprobe dal + modprobe tun + modprobe tap +} + +function remove_kernel_modules() +{ + modprobe -r tap + modprobe -r tun + modprobe -r dal + modprobe -r centec_e530_24x2c_platform +} + +case "$1" in +start) + echo -n "Load Centec kernel modules... " + + load_kernel_modules + + echo "done." + ;; + +stop) + echo -n "Unload Centec kernel modules... " + + remove_kernel_modules + + echo "done." + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/platform-modules-e530-24x2c {start|stop}" + exit 1 + ;; +esac + +exit 0 + diff --git a/platform/centec-arm64/sonic-platform-modules-e530/debian/platform-modules-e530-24x2c.install b/platform/centec-arm64/sonic-platform-modules-e530/debian/platform-modules-e530-24x2c.install new file mode 100644 index 000000000000..b74a968fe976 --- /dev/null +++ b/platform/centec-arm64/sonic-platform-modules-e530/debian/platform-modules-e530-24x2c.install @@ -0,0 +1,3 @@ +../../centec/centec-dal/dal.ko /lib/modules/4.19.0-12-2-arm64/kernel/extra +24x2c/modules/centec_e530_24x2c_platform.ko /lib/modules/4.19.0-12-2-arm64/kernel/extra +24x2c/service/24x2c_platform.service /lib/systemd/system diff --git a/platform/centec-arm64/sonic-platform-modules-e530/debian/platform-modules-e530-24x2c.postinst b/platform/centec-arm64/sonic-platform-modules-e530/debian/platform-modules-e530-24x2c.postinst new file mode 100644 index 000000000000..8bc216369078 --- /dev/null +++ b/platform/centec-arm64/sonic-platform-modules-e530/debian/platform-modules-e530-24x2c.postinst @@ -0,0 +1,2 @@ +systemctl enable 24x2c_platform.service +systemctl start 24x2c_platform.service diff --git a/platform/centec-arm64/sonic-platform-modules-e530/debian/platform-modules-e530-48t4x-p.init b/platform/centec-arm64/sonic-platform-modules-e530/debian/platform-modules-e530-48t4x-p.init new file mode 100755 index 000000000000..b9a6d555b024 --- /dev/null +++ b/platform/centec-arm64/sonic-platform-modules-e530/debian/platform-modules-e530-48t4x-p.init @@ -0,0 +1,61 @@ +#!/bin/bash +# This script load/unload centec kernel modules + +### BEGIN INIT INFO +# Provides: platform-modules-e530-48t4x-p +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Load Centec kernel modules +### END INIT INFO + + +function load_kernel_modules() +{ + depmod -a + modprobe centec_e530_48t4x_p_platform + modprobe dal + modprobe tun + modprobe tap +} + +function remove_kernel_modules() +{ + modprobe -r tap + modprobe -r tun + modprobe -r dal + modprobe -r centec_e530_48t4x_p_platform +} + +case "$1" in +start) + echo -n "Load Centec kernel modules... " + + load_kernel_modules + + echo "done." + ;; + +stop) + echo -n "Unload Centec kernel modules... " + + remove_kernel_modules + + echo "done." + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/platform-modules-e530-48t4x-p {start|stop}" + exit 1 + ;; +esac + +exit 0 + diff --git a/platform/centec-arm64/sonic-platform-modules-e530/debian/platform-modules-e530-48t4x-p.install b/platform/centec-arm64/sonic-platform-modules-e530/debian/platform-modules-e530-48t4x-p.install new file mode 100644 index 000000000000..7d1c00eebeae --- /dev/null +++ b/platform/centec-arm64/sonic-platform-modules-e530/debian/platform-modules-e530-48t4x-p.install @@ -0,0 +1,3 @@ +../../centec/centec-dal/dal.ko /lib/modules/4.19.0-12-2-arm64/kernel/extra +48t4x_p/modules/centec_e530_48t4x_p_platform.ko /lib/modules/4.19.0-12-2-arm64/kernel/extra +48t4x_p/service/48t4x_p_platform.service /lib/systemd/system diff --git a/platform/centec-arm64/sonic-platform-modules-e530/debian/platform-modules-e530-48t4x-p.postinst b/platform/centec-arm64/sonic-platform-modules-e530/debian/platform-modules-e530-48t4x-p.postinst new file mode 100644 index 000000000000..12ef719aad8f --- /dev/null +++ b/platform/centec-arm64/sonic-platform-modules-e530/debian/platform-modules-e530-48t4x-p.postinst @@ -0,0 +1,2 @@ +systemctl enable 48t4x_p_platform.service +systemctl start 48t4x_p_platform.service diff --git a/platform/centec-arm64/sonic-platform-modules-e530/debian/rules b/platform/centec-arm64/sonic-platform-modules-e530/debian/rules new file mode 100755 index 000000000000..69ab667c063d --- /dev/null +++ b/platform/centec-arm64/sonic-platform-modules-e530/debian/rules @@ -0,0 +1,91 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# This file was originally written by Joey Hess and Craig Small. +# As a special exception, when this file is copied by dh-make into a +# dh-make output file, you may use that output file without restriction. +# This special exception was added by Craig Small in version 0.37 of dh-make. + +include /usr/share/dpkg/pkg-info.mk + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +export INSTALL_MOD_DIR:=extra + +PYTHON ?= python2 + +PACKAGE_PRE_NAME := sonic-platform-modules-e530 +KVERSION ?= $(shell uname -r) +KERNEL_SRC := /lib/modules/$(KVERSION) +MOD_SRC_DIR:= $(shell pwd) +MODULE_DIRS:= 48t4x_p 24x2c +MODULE_DIR := modules +UTILS_DIR := utils +SERVICE_DIR := service +CLASSES_DIR := classes +CONF_DIR := conf +KDAL_DIR := ../../centec/centec-dal/ + +%: + dh $@ --with systemd,python2,python3 --buildsystem=pybuild + +clean: + dh_testdir + dh_testroot + dh_clean + +build: + #make modules -C $(KERNEL_SRC)/build M=$(MODULE_SRC) + (for mod in $(KDAL_DIR); do \ + make modules -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/; \ + done) + (for mod in $(MODULE_DIRS); do \ + make modules -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ + $(PYTHON) $${mod}/setup.py build; \ + done) + +binary: binary-arch binary-indep + # Nothing to do + +binary-arch: + # Nothing to do + +#install: build + #dh_testdir + #dh_testroot + #dh_clean -k + #dh_installdirs + +binary-indep: + dh_testdir + dh_installdirs + + # Custom package commands + (for mod in $(MODULE_DIRS); do \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} usr/local/bin; \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} lib/systemd/system; \ + cp $(MOD_SRC_DIR)/$${mod}/$(MODULE_DIR)/*.ko debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + cp $(MOD_SRC_DIR)/$(KDAL_DIR)/*.ko debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/* debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin/; \ + cp $(MOD_SRC_DIR)/$${mod}/$(SERVICE_DIR)/*.service debian/$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system/; \ + $(PYTHON) $${mod}/setup.py install --root=$(MOD_SRC_DIR)/debian/$(PACKAGE_PRE_NAME)-$${mod} --install-layout=deb; \ + done) + # Resuming debhelper scripts + dh_testroot + dh_install + dh_installchangelogs + dh_installdocs + dh_systemd_enable + dh_installinit + dh_systemd_start + dh_link + dh_fixperms + dh_compress + dh_strip + dh_installdeb + dh_gencontrol + dh_md5sums + dh_builddeb +.PHONY: build binary binary-arch binary-indep clean diff --git a/platform/centec-arm64/sonic_fit.its b/platform/centec-arm64/sonic_fit.its new file mode 100644 index 000000000000..7ee89e6c812f --- /dev/null +++ b/platform/centec-arm64/sonic_fit.its @@ -0,0 +1,62 @@ +/* + *Copyright 2018 CENTEC + * + */ + +/dts-v1/; + +/ { + description = "arm64 kernel, initramfs and FDT blob"; + #address-cells = <1>; + + images { + kernel_ctc { + description = "ARM64 Kernel"; + data = /incbin/("./vmlinuz-4.19.0-12-2-arm64"); + type = "kernel"; + arch = "arm64"; + os = "linux"; + compression = "none"; + load = <0x80080000>; + entry = <0x80080000>; + hash { + algo = "crc32"; + }; + }; + initramfs { + description = "initramfs"; + data = /incbin/("./initrd.img-4.19.0-12-2-arm64"); + type = "ramdisk"; + arch = "arm64"; + os = "linux"; + compression = "gzip"; + load = <0x85000000>; + entry = <0x85000000>; + hash { + algo = "crc32"; + }; + }; + ctc_fdt { + description = "dtb for tm_ctc5236"; + data = /incbin/("./e530-ctc5236.dtb"); + type = "flat_dt"; + arch = "arm64"; + os = "linux"; + compression = "none"; + load = <0x88000000>; + hash { + algo = "crc32"; + }; + }; + }; + configurations { + default = "e530-ctc5236"; + + e530-ctc5236 { + description = "config for tm_ctc5236"; + kernel = "kernel_ctc"; + ramdisk = "initramfs"; + fdt = "ctc_fdt"; + }; + }; +}; diff --git a/platform/centec-arm64/tsingma-bsp.mk b/platform/centec-arm64/tsingma-bsp.mk new file mode 100644 index 000000000000..3b2095ef1d79 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp.mk @@ -0,0 +1,12 @@ +# Centec TsingMa BSP Platform modules + + +TSINGMA_BSP_MODULE_VERSION = 1.0 + +export TSINGMA_BSP_MODULE_VERSION + +TSINGMA_BSP_MODULE = tsingma-bsp_$(TSINGMA_BSP_MODULE_VERSION)_$(PLATFORM_ARCH).deb + +$(TSINGMA_BSP_MODULE)_SRC_PATH = $(PLATFORM_PATH)/tsingma-bsp +$(TSINGMA_BSP_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +SONIC_DPKG_DEBS += $(TSINGMA_BSP_MODULE) diff --git a/platform/centec-arm64/tsingma-bsp/LICENSE b/platform/centec-arm64/tsingma-bsp/LICENSE new file mode 100644 index 000000000000..2d14d2b7785f --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/LICENSE @@ -0,0 +1,15 @@ +Copyright (C) 2019 Centec, Inc + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. diff --git a/platform/centec-arm64/tsingma-bsp/README.md b/platform/centec-arm64/tsingma-bsp/README.md new file mode 100644 index 000000000000..41684740dc9b --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/README.md @@ -0,0 +1 @@ +platform drivers for Centec TsingMa soc diff --git a/platform/centec-arm64/tsingma-bsp/debian/changelog b/platform/centec-arm64/tsingma-bsp/debian/changelog new file mode 100644 index 000000000000..df95b50b9117 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/debian/changelog @@ -0,0 +1,5 @@ +tsingma-bsp (1.0) unstable; urgency=low + + * Initial release + + -- shil Wed, 24 Jun 2020 14:20:58 +0800 diff --git a/platform/centec-arm64/tsingma-bsp/debian/compat b/platform/centec-arm64/tsingma-bsp/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/debian/compat @@ -0,0 +1 @@ +9 diff --git a/platform/centec-arm64/tsingma-bsp/debian/control b/platform/centec-arm64/tsingma-bsp/debian/control new file mode 100644 index 000000000000..fc6d0b8def4f --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/debian/control @@ -0,0 +1,11 @@ +Source: tsingma-bsp +Section: main +Priority: extra +Maintainer: shil +Build-Depends: debhelper (>= 8.0.0), bzip2 +Standards-Version: 3.9.3 + +Package: tsingma-bsp +Architecture: arm64 +Depends: linux-image-4.19.0-12-2-arm64-unsigned +Description: kernel modules for tsingma bsp diff --git a/platform/centec-arm64/tsingma-bsp/debian/rules b/platform/centec-arm64/tsingma-bsp/debian/rules new file mode 100644 index 000000000000..17788b62411a --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/debian/rules @@ -0,0 +1,66 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# This file was originally written by Joey Hess and Craig Small. +# As a special exception, when this file is copied by dh-make into a +# dh-make output file, you may use that output file without restriction. +# This special exception was added by Craig Small in version 0.37 of dh-make. + +include /usr/share/dpkg/pkg-info.mk + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +PACKAGE_PRE_NAME := tsingma-bsp +KVERSION ?= $(shell uname -r) +KERNEL_SRC := /lib/modules/$(KVERSION) +MOD_SRC_DIR:= $(shell pwd) +MODULE_DIRS:= ctc5236-mc ctc5236_switch ctcmac ctc_wdt ehci-ctc gpio-ctc i2c-ctc pinctrl-ctc pwm-ctc rtc-sd2405 sdhci-ctc5236 spi-ctc-qspi +DTS_DIR := ctc-dts +MODULE_DIR := src +UTILS_DIR := utils +SERVICE_DIR := service +CLASSES_DIR := classes +CONF_DIR := conf + +%: + dh $@ --with systemd,python2,python3 --buildsystem=pybuild + +clean: + dh_testdir + dh_testroot + dh_clean + +build: + (for mod in $(MODULE_DIRS); do \ + make modules -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$(MODULE_DIR)/$${mod}; \ + done) + make -C $(MOD_SRC_DIR)/$(MODULE_DIR)/$(DTS_DIR) + +binary: binary-arch binary-indep + # Nothing to do + +binary-arch: + # Nothing to do + +binary-indep: + dh_testdir + dh_installdirs + + # Resuming debhelper scripts + dh_testroot + dh_install + dh_installchangelogs + dh_installdocs + dh_systemd_enable + dh_installinit + dh_systemd_start + dh_link + dh_fixperms + dh_compress + dh_strip + dh_installdeb + dh_gencontrol + dh_md5sums + dh_builddeb +.PHONY: build binary binary-arch binary-indep clean diff --git a/platform/centec-arm64/tsingma-bsp/debian/tsingma-bsp.init b/platform/centec-arm64/tsingma-bsp/debian/tsingma-bsp.init new file mode 100644 index 000000000000..dedbebb3be08 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/debian/tsingma-bsp.init @@ -0,0 +1,49 @@ +#!/bin/bash +# This script config centec tsingma soc + +### BEGIN INIT INFO +# Provides: tsingma-bsp +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Config Centec TsingMa SOC +### END INIT INFO + + +function config_tsingma_soc() +{ + hwaddr=`fw_printenv ethaddr | awk -F = '{print $2}'` + if [ "$hwaddr" != "" ]; then + ifconfig eth0 hw ether $hwaddr + fi + modprobe tun + modprobe tap +} + +case "$1" in +start) + echo -n "Config Centec TsingMa SOC... " + + config_tsingma_soc + + echo "done." + ;; + +stop) + echo "done." + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/tsingma-bsp {start|stop}" + exit 1 + ;; +esac + +exit 0 diff --git a/platform/centec-arm64/tsingma-bsp/debian/tsingma-bsp.install b/platform/centec-arm64/tsingma-bsp/debian/tsingma-bsp.install new file mode 100644 index 000000000000..e2fb35af1b6c --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/debian/tsingma-bsp.install @@ -0,0 +1,17 @@ +src/ctc5236-mc/ctc5236-mc.ko /lib/modules/4.19.0-12-2-arm64/kernel/extra +src/pwm-ctc/pwm-ctc.ko /lib/modules/4.19.0-12-2-arm64/kernel/extra +src/ctc5236_switch/ctc5236_switch.ko /lib/modules/4.19.0-12-2-arm64/kernel/extra +src/pinctrl-ctc/pinctrl-ctc.ko /lib/modules/4.19.0-12-2-arm64/kernel/extra +src/ctc_wdt/ctc_wdt.ko /lib/modules/4.19.0-12-2-arm64/kernel/extra +src/ctcmac/ctcmac.ko /lib/modules/4.19.0-12-2-arm64/kernel/extra +src/ctcmac/ctcmac_test.ko /lib/modules/4.19.0-12-2-arm64/kernel/extra +src/ctcmac/ctc5236_mdio.ko /lib/modules/4.19.0-12-2-arm64/kernel/extra +src/i2c-ctc/i2c-ctc.ko /lib/modules/4.19.0-12-2-arm64/kernel/extra +src/gpio-ctc/gpio-ctc.ko /lib/modules/4.19.0-12-2-arm64/kernel/extra +src/ehci-ctc/ehci-ctc.ko /lib/modules/4.19.0-12-2-arm64/kernel/extra +src/rtc-sd2405/rtc-sd2405.ko /lib/modules/4.19.0-12-2-arm64/kernel/extra +src/sdhci-ctc5236/sdhci-ctc5236.ko /lib/modules/4.19.0-12-2-arm64/kernel/extra +src/spi-ctc-qspi/spi-ctc-qspi.ko /lib/modules/4.19.0-12-2-arm64/kernel/extra +src/ctc-dts/e530-ctc5236.dtb /boot/ +src/config/fw_env.config /etc/ +src/config/tsingma-bsp.service /lib/systemd/system diff --git a/platform/centec-arm64/tsingma-bsp/debian/tsingma-bsp.postinst b/platform/centec-arm64/tsingma-bsp/debian/tsingma-bsp.postinst new file mode 100644 index 000000000000..2aaf59573a74 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/debian/tsingma-bsp.postinst @@ -0,0 +1,2 @@ +systemctl enable tsingma-bsp.service +systemctl start tsingma-bsp.service diff --git a/platform/centec-arm64/tsingma-bsp/src/config/fw_env.config b/platform/centec-arm64/tsingma-bsp/src/config/fw_env.config new file mode 100644 index 000000000000..6ef503c1cdb3 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/config/fw_env.config @@ -0,0 +1,2 @@ +# MTD device name Device offset Env. size Flash sector size +/dev/mtd1 0x00000000 0x00010000 0x00001000 diff --git a/platform/centec-arm64/tsingma-bsp/src/config/tsingma-bsp.service b/platform/centec-arm64/tsingma-bsp/src/config/tsingma-bsp.service new file mode 100644 index 000000000000..b384b4896e8b --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/config/tsingma-bsp.service @@ -0,0 +1,13 @@ +[Unit] +Description=Centec tsingma bsp init +After=local-fs.target +Before=syncd.service + +[Service] +Type=oneshot +ExecStart=-/etc/init.d/tsingma-bsp start +ExecStop=-/etc/init.d/tsingma-bsp stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/centec-arm64/tsingma-bsp/src/ctc-dts/Makefile b/platform/centec-arm64/tsingma-bsp/src/ctc-dts/Makefile new file mode 100644 index 000000000000..146a62ce37a7 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/ctc-dts/Makefile @@ -0,0 +1,4 @@ +e530-ctc5236.dtb: e530-ctc5236.dts ctc5236.dtsi ctc5236-clock.dtsi + cpp -nostdinc -I. -undef -x assembler-with-cpp e530-ctc5236.dts > tmp.dts + dtc -O dtb -o e530-ctc5236.dtb tmp.dts + rm tmp.dts -rf diff --git a/platform/centec-arm64/tsingma-bsp/src/ctc-dts/arm-gic.h b/platform/centec-arm64/tsingma-bsp/src/ctc-dts/arm-gic.h new file mode 100644 index 000000000000..8c75d237d4b7 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/ctc-dts/arm-gic.h @@ -0,0 +1,22 @@ +/* + * This header provides constants for the ARM GIC. + */ + +#ifndef _DT_BINDINGS_INTERRUPT_CONTROLLER_ARM_GIC_H +#define _DT_BINDINGS_INTERRUPT_CONTROLLER_ARM_GIC_H + +#include "irq.h" + +/* interrupt specifier cell 0 */ + +#define GIC_SPI 0 +#define GIC_PPI 1 + +/* + * Interrupt specifier cell 2. + * The flags in irq.h are valid, plus those below. + */ +#define GIC_CPU_MASK_RAW(x) ((x) << 8) +#define GIC_CPU_MASK_SIMPLE(num) GIC_CPU_MASK_RAW((1 << (num)) - 1) + +#endif diff --git a/platform/centec-arm64/tsingma-bsp/src/ctc-dts/ctc5236-clks.h b/platform/centec-arm64/tsingma-bsp/src/ctc-dts/ctc5236-clks.h new file mode 100644 index 000000000000..56d91da3130a --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/ctc-dts/ctc5236-clks.h @@ -0,0 +1,25 @@ +/* + * ctc5236 clock tree IDs + * + * (C) Copyright 2004-2017 Centec Networks (suzhou) Co., LTD. + * + * Jay Cao + * + * This program is free software; 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. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __CTC5236_CLKS_H +#define __CTC5236_CLKs_H + +#define CLKID_UNUSED 0 +#define CLKID_PLL_FIXED 1 +#define CLKID_UART0 2 + +#endif /* __CTC5236_CLKS_H */ diff --git a/platform/centec-arm64/tsingma-bsp/src/ctc-dts/ctc5236-clock.dtsi b/platform/centec-arm64/tsingma-bsp/src/ctc-dts/ctc5236-clock.dtsi new file mode 100644 index 000000000000..ae6b00c00ba2 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/ctc-dts/ctc5236-clock.dtsi @@ -0,0 +1,63 @@ +/* + * dts file for Centec CTC5236(TsingMa) SoC + * + * (C) Copyright 2004-2017 Centec Networks (suzhou) Co., LTD. + * + * Jay Cao + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + + osc: oscillator { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <50000000>; + }; + + sup_clk: sup_clk_12m { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <1200000000>; + clock-output-names = "sup_clk"; + }; + + uart_clk: uart_clk_20m { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <20000000>; + clock-output-names = "uart_clk"; + }; + + i2c_clk: clkm { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <50000000>; + clock-output-names = "i2c_clk"; + }; + wdog_clk:wdog_clk{ + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <1000000>; + clock-output-names = "wdog_clk"; + }; + timer_clk:timer_clk{ + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <500000000>; + clock-output-names = "timer_clk"; + }; + mmc_clk:mmc_clk{ + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <100000000>; + clock-output-names = "mmc_clk"; + }; + spi_clk:spi_clk{ + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <100000000>; + clock-output-names = "spi_clk"; + }; diff --git a/platform/centec-arm64/tsingma-bsp/src/ctc-dts/ctc5236.dtsi b/platform/centec-arm64/tsingma-bsp/src/ctc-dts/ctc5236.dtsi new file mode 100644 index 000000000000..d92000612c29 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/ctc-dts/ctc5236.dtsi @@ -0,0 +1,376 @@ +/* + * dts file for Centec CTC5236(TsingMa) SoC + * + * (C) Copyright 2004-2017 Centec Networks (suzhou) Co., LTD. + * + * Jay Cao + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + +#include "arm-gic.h" +#include "ctc5236-clks.h" +#include "../pinctrl-ctc/pinctrl-ctc.h" + +/ { + compatible = "centec,ctc5236"; + #address-cells = <2>; + #size-cells = <2>; + interrupt-parent = <&gic>; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu-map { + cluster0 { + core0 { + cpu = <&cpu0>; + }; + core1 { + cpu = <&cpu1>; + }; + }; + }; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0 0x000>; + enable-method = "spin-table"; + cpu-release-addr = <0 0x0010fff0>; + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0 0x001>; + enable-method = "spin-table"; + cpu-release-addr = <0 0x0010fff0>; + }; + }; + + gic: interrupt-controller@31201000 { + compatible = "arm,gic-400"; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0x0 0x31201000 0 0x1000>, + <0x0 0x31202000 0 0x2000>, + <0x0 0x31204000 0 0x2000>, + <0x0 0x31206000 0 0x2000>; + interrupts = ; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupt-parent = <&gic>; + interrupts = , + , + , + ; + }; + + soc: soc { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + #include "ctc5236-clock.dtsi" + ocram: sram@00100000 { + compatible = "mmio-sram"; + reg = <0x0 0x00100000 0x0 0x10000>; + }; + + memory-controller@30600000 { + compatible = "ctc,ctc5236-ddr-ctrl"; + reg = <0x0 0x30600000 0x0 0x100000>; + interrupts = ; + }; + + sysctrl: sysctrl@33200000 { + compatible = "ctc,ctc5236-sysctrl", "syscon"; + reg = <0x0 0x33200000 0x0 0x100000>; + little-endian; + }; + + serial0: serial@33000000 { + compatible = "arm,pl011","arm,primecell"; + reg = <0x0 0x33000000 0x0 0x1000>; + interrupts = ; + clocks = <&uart_clk>, <&sup_clk>; + clock-names = "uart_clk", "apb_pclk"; + status="disabled"; + }; + serial1: serial@33001000 { + compatible = "arm,pl011","arm,primecell"; + reg = <0x0 0x33001000 0x0 0x1000>; + interrupts = ; + clocks = <&uart_clk>, <&sup_clk>; + clock-names = "uart_clk", "apb_pclk"; + status="disabled"; + }; + serial2: serial@33002000 { + compatible = "arm,pl011","arm,primecell"; + reg = <0x0 0x33002000 0x0 0x1000>; + interrupts = ; + clocks = <&uart_clk>, <&sup_clk>; + clock-names = "uart_clk", "apb_pclk"; + status="disabled"; + }; + mdio: mdio@33620000 { + compatible = "ctc,mdio"; + reg = <0x0 0x33620000 0x0 0x10000>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + enet0: ethernet@33410000 { + compatible = "ctc,mac"; + device_type = "network"; + #address-cells = <2>; + #size-cells = <2>; + interrupt-parent = <&gic>; + status = "disabled"; + index = <0x00>; + reg = <0x0 0x33410000 0x0 0x10000>, + <0x0 0x33400000 0x0 0x10000>; + interrupts = , + , + ; + ctc,sysctrl = <&sysctrl>; + }; + + enet1: ethernet@33420000 { + compatible = "ctc,mac"; + device_type = "network"; + #address-cells = <2>; + #size-cells = <2>; + interrupt-parent = <&gic>; + status = "disabled"; + index = <0x01>; + reg = <0x0 0x33420000 0x0 0x10000>, + <0x0 0x33400000 0x0 0x10000>; + interrupts = , + , + ; + ctc,sysctrl = <&sysctrl>; + }; + + ehci0: usb@30500000 { + compatible = "ctc-ehci"; + reg = <0x0 0x30500000 0x0 0x1000>; + interrupts = ; + status = "disabled"; + }; + + ohci0: usb@30580000 { + compatible = "generic-ohci"; + reg = <0x0 0x30580000 0x0 0x1000>; + interrupts = ; + status = "disabled"; + }; + + spi: spi@33100000 { + compatible = "arm,pl022","arm,primecell"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x0 0x33100000 0x0 0x100000>; + clocks = <&spi_clk>, <&sup_clk>; + clock-names = "spi_clk", "apb_pclk"; + num-cs = <4>; + interrupts = ; + ctc,sysctrl = <&sysctrl>; + status ="disabled"; + }; + + qspi: qspi@10000000 { + compatible = "ctc, igdaxi001a-qspi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x0 0x10000000 0x0 0x10000>; + pclk = <500000000>; + num-cs = <2>; + idle-cycle = <2>; + post-cycle = <1>; + pre-cycle = <2>; + interrupts = ; + status = "disabled"; + }; + switch: switch@31100000 { + compatible = "centec,dal-localbus"; + reg = <0x0 0x31100000 0x0 0x1000>, + <0x0 0x33290000 0x0 0x10000>; + interrupts = , + , + , + , + , + , + , + ; + status ="disabled"; + }; + switch1: switch1@31101000 { + compatible = "centec,switch"; + reg = <0x0 0x31101000 0x0 0x1000>; + status ="disabled"; + }; + + i2c0: i2c0@33700000{ + compatible = "ctc,i2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x0 0x33700000 0x0 0x1000>; + interrupts = ; + clocks = <&i2c_clk>; + status ="disabled"; + }; + + i2c1: i2c1@33701000{ + compatible = "ctc,i2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x0 0x33701000 0x0 0x1000>; + interrupts = ; + clocks = <&i2c_clk>; + status ="disabled"; + }; + + pcie: pcie@20000000 { + compatible = "centec,ctc5236-pcie"; + reg = <0x0 0x20000000 0x0 0x10000000 + 0x0 0x30000000 0x0 0x1000>; + reg-names = "cfg", "ctrl"; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + device_type = "pci"; + interrupt-parent = <&gic>; + interrupts = , + , + ; + interrupt-names = "msi","aer","pme"; + msi-parent = <&pcie>; + bus-range = <0 0xff>; + ranges = <0x43000000 0 0x00000000 0 0x40000000 0 0x40000000>; + num-lanes = <1>; + ctc,sysctrl = <&sysctrl>; + status ="disabled"; + }; + + wtd0: wtd0@33500000{ + compatible = "arm,sp805-wdt", "arm,primecell"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x0 0x33500000 0x0 0x1000>; + clocks = <&wdog_clk>, <&sup_clk>; + clock-names = "wdog_clk", "apb_pclk"; + ctc,sysctrl = <&sysctrl>; + interrupts = ; + status="disabled"; + }; + wtd1: wtd1@33501000{ + compatible = "arm,sp805-wdt", "arm,primecell"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x0 0x33501000 0x0 0x1000>; + clocks = <&wdog_clk>, <&sup_clk>; + clock-names = "wdog_clk", "apb_pclk"; + ctc,sysctrl = <&sysctrl>; + interrupts = ; + status="disabled"; + }; + + sdhci: sdhci@30400000 { + compatible = "centec,ctc5236-sdhci"; + status = "disabled"; + interrupt-parent = <&gic>; + interrupts = ; + clocks = <&mmc_clk>; + clock-names = "mmc_clk"; + ctc,sysctrl = <&sysctrl>; + reg = <0x0 0x30400000 0x0 0x1000>; + }; + + timer0: timer0@33600000{ + compatible = "snps,dw-apb-timer"; + reg = <0x0 0x33600000 0x0 0x20>; + clocks = <&timer_clk>; + clock-names = "timer"; + interrupts = ; + DivNum = <0x3c>; + status="disabled"; + }; + timer1: timer1@33600020{ + compatible = "snps,dw-apb-timer"; + reg = <0x0 0x33600020 0x0 0x20>; + clocks = <&timer_clk>; + clock-names = "timer"; + interrupts = ; + DivNum = <0x3c>; + status="disabled"; + }; + + pwm: pwm@33200240{ + compatible = "centec-pwm"; + ctc,sysctrl = <&sysctrl>; + #pwm-cells = <2>; + + status="disabled"; + }; + + fan: fan-ctc5236 { + compatible = "fan-ctc5236"; + pwms = <&pwm 0 1000000>, + <&pwm 1 1000000>, + <&pwm 2 1000000>, + <&pwm 3 1000000>; + pwm-names = "pwm1","pwm2","pwm3","pwm4"; + }; + + gpio0: gpio@33610000 { + compatible = "ctc,apb-gpio"; + reg = <0x0 0x33610000 0x0 0x10000>; + #address-cells = <1>; + #size-cells = <0>; + + porta: gpio-port@0 { + compatible = "ctc,apb-gpio-porta"; + gpio-controller; + #gpio-cells = <2>; + ctc,nr-gpios = <16>; + reg = <0>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = ; + }; + portb: gpio-port@1 { + compatible = "ctc,apb-gpio-portb"; + gpio-controller; + #gpio-cells = <2>; + ctc,nr-gpios = <18>; + reg = <1>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = ; + }; + }; + + pinctrl: pinctrl { + compatible = "ctc,ctc5236-pinctrl"; + #address-cells = <0x2>; + #size-cells = <0x2>; + ctc,pinctrl-bank0 = <16>; + ctc,pinctrl-bank1 = <8>; + ctc,sysctrl = <&sysctrl>; + status = "okay"; + }; + }; + +}; + diff --git a/platform/centec-arm64/tsingma-bsp/src/ctc-dts/e530-ctc5236.dts b/platform/centec-arm64/tsingma-bsp/src/ctc-dts/e530-ctc5236.dts new file mode 100644 index 000000000000..d8544666e2ce --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/ctc-dts/e530-ctc5236.dts @@ -0,0 +1,212 @@ +/* + * dts file for Centec CTC5236(TsingMa) SoC E530-24X2C Board + * + * (C) Copyright 2004-2018 Centec Networks (suzhou) Co., LTD. + * + * liuht + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + +/dts-v1/; +#include "ctc5236.dtsi" + + +/ { + model = " CTC5236(TsingMa) E530 Board"; + compatible = "ctc5236,e530-ctc5236"; + + memory { + device_type = "memory"; + reg = <0 0x80000000 0x0 0x40000000>; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + aliases { + serial0 = &serial0; + serial1 = &serial1; + ethernet0 = &enet0; + ethernet1 = &enet1; + }; + +}; + +&serial0 { + status = "okay"; +}; + +&serial1 { + status = "okay"; +}; + +&mdio { + status = "okay"; + phy0: ethernet-phy@0 { + index = <0x00>; + reg = <0x00>; + }; +}; + +&enet0 { + status = "okay"; + phy-handle = <&phy0>; + auto-nego-mode= "sgmii-mac"; +}; + +&qspi { + status = "okay"; + + qspiflash: mx25u3235f@0 { + compatible = "jedec,spi-nor"; + reg = <0x0>; + spi-cpha; + spi-cpol; + spi-max-frequency = <25000000>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "u-boot"; + reg = <0x0 0x300000>; + }; + partition@300000 { + label = "uboot-env"; + reg = <0x300000 0x10000>; + }; + partition@310000 { + label = "system"; + reg = <0x310000 0x10000>; + }; + partition@320000 { + label = "hw-info"; + reg = <0x320000 0x10000>; + }; + }; + }; +}; + +&spi { + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&spi_pin>; + + clock0: ad9559@1 { + compatible = "analog,ad9559"; + reg = <1>; + spi-max-frequency = <25000000>; + }; +}; + +&switch { + status = "okay"; +}; + +&switch1 { + status = "okay"; +}; + +&i2c0{ + status = "okay"; + clock-frequency = <400000>; + + eeprom_0:eeprom_0@57 { + compatible = "atmel,24c64"; + reg = <0x57>; + pagesize = <32>; + }; + + rtc_0:rtc_0@32{ + compatible = "sd2405"; + reg = <0x32>; + }; +}; + +&i2c1{ + status = "okay"; + clock-frequency = <400000>; +}; + +&ehci0 { + status = "okay"; +}; + +&ohci0 { + status = "okay"; +}; + +&wtd0{ + status = "okay"; +}; + +&wtd1{ + status = "disabled"; +}; + +&sdhci { + bus-width = <8>; + max-frequency = <100000000>; + non-removable; + no-sd; + no-sdio; + voltage-ranges = <3300 3300>; + status = "okay"; +}; + +&timer0 { + status = "okay"; +}; + +&soc { + ctc-irq@0 { + compatible = "centec,ctc-irq"; + device_type = "ctc-irq"; + interrupt-parent=<&porta>; + interrupts = < 0 IRQ_TYPE_LEVEL_LOW>, + < 1 IRQ_TYPE_LEVEL_LOW>, + <15 IRQ_TYPE_LEVEL_LOW>, + < 6 IRQ_TYPE_LEVEL_HIGH>, + < 7 IRQ_TYPE_LEVEL_HIGH>; + + }; +}; + +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&pwm0_pin>; + status = "okay"; +}; + + +&pinctrl { + spi { + spi_pin: spi_pin { + status = "disabled"; + ctc,pins = <0 0 PIN_FUNC_SPI>, + <0 2 PIN_FUNC_SPI>, + <0 3 PIN_FUNC_SPI>, + <0 5 PIN_FUNC_SPI>; + }; + }; + + pwm0 { + pwm0_pin: pwm0_pin { + ctc,pins = <0 8 PIN_FUNC_PWM>, + <0 9 PIN_FUNC_PWM>, + <0 10 PIN_FUNC_PWM>, + <0 11 PIN_FUNC_PWM>, + <0 12 PIN_FUNC_PWM>, + <0 13 PIN_FUNC_PWM>, + <0 14 PIN_FUNC_PWM>, + <0 15 PIN_FUNC_PWM>; + }; + }; +}; diff --git a/platform/centec-arm64/tsingma-bsp/src/ctc-dts/irq.h b/platform/centec-arm64/tsingma-bsp/src/ctc-dts/irq.h new file mode 100644 index 000000000000..33a1003c55aa --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/ctc-dts/irq.h @@ -0,0 +1,19 @@ +/* + * This header provides constants for most IRQ bindings. + * + * Most IRQ bindings include a flags cell as part of the IRQ specifier. + * In most cases, the format of the flags cell uses the standard values + * defined in this header. + */ + +#ifndef _DT_BINDINGS_INTERRUPT_CONTROLLER_IRQ_H +#define _DT_BINDINGS_INTERRUPT_CONTROLLER_IRQ_H + +#define IRQ_TYPE_NONE 0 +#define IRQ_TYPE_EDGE_RISING 1 +#define IRQ_TYPE_EDGE_FALLING 2 +#define IRQ_TYPE_EDGE_BOTH (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING) +#define IRQ_TYPE_LEVEL_HIGH 4 +#define IRQ_TYPE_LEVEL_LOW 8 + +#endif diff --git a/platform/centec-arm64/tsingma-bsp/src/ctc5236-mc/Makefile b/platform/centec-arm64/tsingma-bsp/src/ctc5236-mc/Makefile new file mode 100644 index 000000000000..b31896d1ef26 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/ctc5236-mc/Makefile @@ -0,0 +1 @@ +obj-m = ctc5236-mc.o diff --git a/platform/centec-arm64/tsingma-bsp/src/ctc5236-mc/ctc5236-mc.c b/platform/centec-arm64/tsingma-bsp/src/ctc5236-mc/ctc5236-mc.c new file mode 100644 index 000000000000..55c86b3a5626 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/ctc5236-mc/ctc5236-mc.c @@ -0,0 +1,279 @@ +/* Centec TsingMa Memory Controller Driver + * + * Author: lius + * + * Copyright 2002-2019, Centec Networks (Suzhou) Co., Ltd. + * + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct ctc5236_mc { + struct device *dev; + void __iomem *base; + int irq; + +}; + +/* DDR interrupt enable register */ +#define DDR_ERR_INT_EN 0xF0 + +/* DDR interrupt status register */ +#define DDR_ERR_INT_STATUS 0xF4 + +/* over top-bound info register*/ +#define DDR_ERR_INT_OVER_TOPBOUND_L 0xF8 +#define DDR_ERR_INT_OVER_TOPBOUND_H 0xFC + +#define DDR_PORT0_ERR_INT_STATUS 0x1 +#define DDR_PORT1_ERR_INT_STATUS 0x2 +#define DDR_PORT2_ERR_INT_STATUS 0x3 +#define DDR_PORT3_ERR_INT_STATUS 0x4 +#define DDR_ERR_ECC_INT_STATUS 0x10000 +#define DDR_ERR_WR_PORT_REC_UNDERFLOW 0x20000 +#define DDR_ERR_WR_PORT_REC_OVERFLOW 0x40000 +#define DDR_ERR_RD_PORT_REC_UNDERFLOW 0x80000 +#define DDR_ERR_RD_PORT_REC_OVERFLOW 0x100000 + +#define DDR_PORT0_STATUS 0xB0 +#define DDR_PORT1_STATUS 0xB4 +#define DDR_PORT2_STATUS 0xB8 +#define DDR_PORT3_STATUS 0xBC + +#define DDR_ERR_OVER_TOPBOUND 0x20000 +#define DDR_ERR_WCMDQ_OVER 0x40000 +#define DDR_ERR_WCMDQ_UNDER 0x80000 +#define DDR_ERR_WDATAQ_OVER 0x100000 +#define DDR_ERR_WDATAQ_UNDER 0x200000 +#define DDR_ERR_WESPQ_OVER 0x400000 +#define DDR_ERR_WESPQ_UNDER 0x800000 +#define DDR_ERR_WINFOQ_OVER 0x1000000 +#define DDR_ERR_WINFOQ_UNDER 0x2000000 +#define DDR_ERR_RCMDQ_OVER 0x4000000 +#define DDR_ERR_RCMDQ_UNDER 0x8000000 +#define DDR_ERR_RDATAQ_OVER 0x10000000 +#define DDR_ERR_RDATAQ_UNDER 0x20000000 +#define DDR_ERR_RESPQ_OVER 0x40000000 +#define DDR_ERR_RESPQ_UNDER 0x80000000 + +#define DDR_PORT0_BASE 0xB0 +#define DDR_PORT1_BASE 0xB4 +#define DDR_PORT2_BASE 0xB8 +#define DDR_PORT3_BASE 0xBc + +#define DDR_PORT0 0 +#define DDR_PORT1 1 +#define DDR_PORT2 2 +#define DDR_PORT3 3 + +static int port_err_status(int status, int port, void *dev_id) +{ + int id = port; + unsigned long temp = 0; + unsigned int addr_h = 0; + unsigned int addr_l = 0; + struct ctc5236_mc *mci = dev_id; + + /*the reason of port interrupt */ + if (status & DDR_ERR_OVER_TOPBOUND) { + /* get low 32-bit address */ + addr_l = readl(mci->base + DDR_ERR_INT_OVER_TOPBOUND_L); + /* get high 2-bit address */ + addr_h = readl(mci->base + DDR_ERR_INT_OVER_TOPBOUND_H); + temp = (addr_l | (((unsigned long)((addr_h >> 12) & 0x3)) << 32) + ); + + pr_emerg("ERROR:port%d is out of top-bound range!\n" + "The error address is 0x%p\n", + id, (void *)temp); + } + + if (status & DDR_ERR_WCMDQ_OVER) + pr_err("ERROR:port%d write command queue is overflow!\n", id); + + if (status & DDR_ERR_WCMDQ_UNDER) + pr_err("ERROR:port%d write command queue is underflow!\n", id); + + if (status & DDR_ERR_WDATAQ_OVER) + pr_err("ERROR:port%d write data queue is overflow!\n", id); + + if (status & DDR_ERR_WDATAQ_UNDER) + pr_err("ERROR:port%d write data queue is underflow!\n", id); + + if (status & DDR_ERR_WESPQ_OVER) + pr_err("ERROR:port%d write response queue is overflow!\n", id); + + if (status & DDR_ERR_WESPQ_UNDER) + pr_err("ERROR:port%d write response queue is underflow!\n", id); + + if (status & DDR_ERR_WINFOQ_OVER) + pr_err("ERROR:port%d write info queue is overflow!\n", id); + + if (status & DDR_ERR_WINFOQ_UNDER) + pr_err("ERROR:port%d write info queue is underflow!\n", id); + + if (status & DDR_ERR_RCMDQ_OVER) + pr_err("ERROR:port%d read command queue is overflow!\n", id); + + if (status & DDR_ERR_RCMDQ_UNDER) + pr_err("ERROR:port%d read command queue is underflow!\n", id); + + if (status & DDR_ERR_RDATAQ_OVER) + pr_err("ERROR:port%d read data queue is overflow!\n", id); + + if (status & DDR_ERR_RDATAQ_UNDER) + pr_err("ERROR:port%d read data queue is underflow!\n", id); + + if (status & DDR_ERR_RESPQ_OVER) + pr_err("ERROR:port%d read response queue is overflow!\n", id); + + if (status & DDR_ERR_RESPQ_UNDER) + pr_err("ERROR:port%d read response queue is underflow!\n", id); + + return 1; +} + +static irqreturn_t ctc_mc_err_handler(int irq, void *dev_id) +{ + struct ctc5236_mc *mci = dev_id; + unsigned int status; + unsigned int ret = 0; + + /* get interrupt status */ + status = readl(mci->base + DDR_ERR_INT_STATUS); + + if (status & DDR_PORT0_ERR_INT_STATUS) { + ret = readl(mci->base + DDR_PORT0_BASE); + port_err_status(ret, DDR_PORT0, mci); + } + + if (status & DDR_PORT1_ERR_INT_STATUS) { + ret = readl(mci->base + DDR_PORT1_BASE); + port_err_status(ret, DDR_PORT1, mci); + } + + if (status & DDR_PORT2_ERR_INT_STATUS) { + ret = readl(mci->base + DDR_PORT2_BASE); + port_err_status(ret, DDR_PORT2, mci); + } + + if (status & DDR_PORT3_ERR_INT_STATUS) { + ret = readl(mci->base + DDR_PORT3_BASE); + port_err_status(ret, DDR_PORT3, mci); + } + + if (status & DDR_ERR_ECC_INT_STATUS) + pr_err("ERROR:The ecc more than 1-bit error !\n"); + + if (status & DDR_ERR_WR_PORT_REC_UNDERFLOW) + pr_err("ERROR:MPARB wr_port_rec FIFO is underflow!\n"); + + if (status & DDR_ERR_WR_PORT_REC_OVERFLOW) + pr_err("ERROR:MPARB wr_port_rec FIFO is overflow!\n"); + + if (status & DDR_ERR_RD_PORT_REC_UNDERFLOW) + pr_err("ERROR:MPARB rd_port_rec FIFO is underflow!\n"); + + if (status & DDR_ERR_RD_PORT_REC_OVERFLOW) + pr_err("ERROR:MPARB rd_port_rec FIFO is underflow!\n"); + + /* disable DDR interrupt */ + writel(0x0, mci->base + DDR_ERR_INT_EN); + + return IRQ_HANDLED; +} + +static const struct of_device_id ctc5236_ddr_ctrl_of_match[] = { + { + .compatible = "ctc,ctc5236-ddr-ctrl", + }, + {}, +}; + +MODULE_DEVICE_TABLE(of, ctc5236_ddr_ctrl_of_match); + +static int ctc5236_mc_probe(struct platform_device *pdev) +{ + const struct of_device_id *id; + struct ctc5236_mc *mci; + int ret; + + id = of_match_device(ctc5236_ddr_ctrl_of_match, &pdev->dev); + if (!id) + return -ENODEV; + + mci = kzalloc(sizeof(*mci), GFP_KERNEL); + if (!mci) + return -ENODEV; + + mci->base = devm_ioremap_resource(&pdev->dev, pdev->resource); + if (IS_ERR(mci->base)) + return PTR_ERR(mci->base); + + mci->irq = platform_get_irq(pdev, 0); + ret = + devm_request_irq(&pdev->dev, mci->irq, ctc_mc_err_handler, 0, + dev_name(&pdev->dev), mci); + if (ret < 0) { + dev_err(&pdev->dev, "Unable to request irq %d\n", mci->irq); + goto err; + } + + return 0; + +err: + dev_err(&pdev->dev, "Probe Failed!\n"); + return ret; +} + +static int ctc5236_mc_remove(struct platform_device *pdev) +{ + struct ctc5236_mc *mci = platform_get_drvdata(pdev); + + devm_iounmap(&pdev->dev, mci->base); + devm_free_irq(&pdev->dev, mci->irq, mci); + + kfree(mci); + return 0; +} + +static struct platform_driver ctc5236_mc_driver = { + .probe = ctc5236_mc_probe, + .remove = ctc5236_mc_remove, + .driver = { + .name = "ctc5236_mc", + .of_match_table = ctc5236_ddr_ctrl_of_match, + }, +}; + +static int __init ctc5236_mc_init(void) +{ + return platform_driver_register(&ctc5236_mc_driver); +} + +static void __exit ctc5236_mc_exit(void) +{ + platform_driver_unregister(&ctc5236_mc_driver); +} + +module_init(ctc5236_mc_init); +module_exit(ctc5236_mc_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Centec Network"); +MODULE_DESCRIPTION("Centec TsingMa memory controller driver"); diff --git a/platform/centec-arm64/tsingma-bsp/src/ctc5236_switch/Makefile b/platform/centec-arm64/tsingma-bsp/src/ctc5236_switch/Makefile new file mode 100644 index 000000000000..cb2b8a5e2381 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/ctc5236_switch/Makefile @@ -0,0 +1 @@ +obj-m = ctc5236_switch.o diff --git a/platform/centec-arm64/tsingma-bsp/src/ctc5236_switch/ctc5236_switch.c b/platform/centec-arm64/tsingma-bsp/src/ctc5236_switch/ctc5236_switch.c new file mode 100644 index 000000000000..1cc86667d9b9 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/ctc5236_switch/ctc5236_switch.c @@ -0,0 +1,324 @@ +/* (C) Copyright 2004-2017 Centec Networks (suzhou) Co., LTD. + * Wangyb + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include +#include +#include +#include +#include +#include +#include <../include/ctc5236_switch.h> + +struct ctc_access_t *access; + +#define SWITCH_DTS_OFFSET 0x1000 + +int ctc5236_switch_read(u32 offset, u32 len, u32 *p_value) +{ + union ctc_switch_cmd_status_u_t cmd_status_u; + u32 timeout = 0x6400; + u32 cmd_len = 0; + u8 index = 0; + + if (!p_value) { + pr_err("switch read:value buffer is NULL!\n"); + return -1; + } + + /* switch only have 16 databuf, len must not exceed 16 */ + if (len > 16 || len == 0) { + pr_err("switch read: length error! len = %d\n", len); + return -1; + } + /* cmdDataLen must be power of 2 */ + if ((len & (len - 1)) == 0) { + cmd_len = len; + } else { + cmd_len = len; + do { + cmd_len++; + } while ((cmd_len <= 16) && (cmd_len & (cmd_len - 1))); + } + + /* 1. write CmdStatusReg */ + memset(&cmd_status_u, 0, sizeof(union ctc_switch_cmd_status_u_t)); + cmd_status_u.cmd_status.cmdReadType = 1; + /* normal operate only support 1 entry */ + cmd_status_u.cmd_status.cmdEntryWords = (len == 16) ? 0 : len; + cmd_status_u.cmd_status.cmdDataLen = len; + writel(cmd_status_u.val, &access->cmd_status); + /* 2. write AddrReg */ + writel(offset, &access->addr); + /* 3. polling status and check */ + cmd_status_u.val = readl(&access->cmd_status); + while (!(cmd_status_u.cmd_status.reqProcDone) && (--timeout)) + cmd_status_u.val = readl(&access->cmd_status); + /* 4. check cmd done */ + if (!(cmd_status_u.cmd_status.reqProcDone)) { + pr_err("switch read error! cmd_status = %x\n", + cmd_status_u.val); + return -1; + } + /* 5. check pcie read status */ + if (cmd_status_u.cmd_status.reqProcError != 0) { + pr_err("pci read error! cmd_status = %x, offset = 0x%x\n", + cmd_status_u.val, offset); + return -1; + } + + /* 6. read data from buffer */ + for (index = 0; index < len; index++) + p_value[index] = readl(&access->data[index]); + + return 0; +} + +int ctc5236_switch_write(u32 offset, u32 len, u32 *p_value) +{ + union ctc_switch_cmd_status_u_t cmd_status_u; + u32 timeout = 0x6400; /* need to be confirmed */ + u32 cmd_len = 0; + u8 index = 0; + + if (!p_value) { + pr_err("switch write:value buffer is NULL!\n"); + return -1; + } + + /* switch only have 16 databuf, len must not exceed 16 */ + if (len > 16 || len == 0) { + pr_err("switch write length error! len = %d\n", len); + return -1; + } + + /* cmdDataLen must be power of 2 */ + if ((len & (len - 1)) == 0) { + cmd_len = len; + } else { + cmd_len = len; + do { + cmd_len++; + } while ((cmd_len <= 16) && (cmd_len & (cmd_len - 1))); + } + + /* 1. write CmdStatusReg */ + memset(&cmd_status_u, 0, sizeof(struct ctc_switch_cmd_status_t)); + cmd_status_u.cmd_status.cmdReadType = 0; + cmd_status_u.cmd_status.cmdEntryWords = (len == 16) ? 0 : len; + /* Notice: for 1 entry op, cmdDatalen eq cmdEntryWords, + * but for mutil entry, len = cmd_len + */ + cmd_status_u.cmd_status.cmdDataLen = len; + writel(cmd_status_u.val, &access->cmd_status); + /* 2. write AddrReg */ + writel(offset, &access->addr); + /* 3. write data into databuffer */ + for (index = 0; index < len; index++) + writel(p_value[index], &access->data[index]); + + /* 4. polling status and check */ + cmd_status_u.val = readl(&access->cmd_status); + while (!(cmd_status_u.cmd_status.reqProcDone) && (--timeout)) + cmd_status_u.val = readl(&access->cmd_status); + + /* 5. check cmd done */ + if (!(cmd_status_u.cmd_status.reqProcDone)) { + pr_err("switch write error! cmd_status = %x\n", + cmd_status_u.val); + return -1; + } + + /* 6. check switch read status */ + if (cmd_status_u.cmd_status.reqProcError != 0) { + pr_err("switch write error! cmd_status = %x, offset=0x%x\n", + cmd_status_u.val, offset); + return -1; + } + + return 0; +} + +static int +_sys_tsingma_peri_get_temp_with_code(u8 lchip, u32 temp_code, u32 *p_temp_val) +{ + u16 temp_mapping_tbl[SYS_TSINGMA_TEMP_TABLE_NUM + 1] = { + 804, 801, 798, 795, 792, 790, 787, 784, 781, 778, + 775, 772, 769, 766, 763, 761, 758, 755, 752, 749, + 746, 743, 740, 737, 734, 731, 728, 725, 722, 719, + 717, 714, 711, 708, 705, 702, 699, 696, 693, 690, + 687, 684, 681, 678, 675, 672, 669, 666, 663, 660, + 658, 655, 652, 649, 646, 643, 640, 637, 634, 631, + 628, 625, 622, 619, 616, 613, 610, 607, 604, 601, + 599, 596, 593, 590, 587, 584, 581, 578, 575, 572, + 569, 566, 563, 560, 557, 554, 551, 548, 545, 542, + 540, 537, 534, 531, 528, 525, 522, 519, 516, 513, + 510, 507, 504, 501, 498, 495, 492, 489, 486, 483, + 481, 478, 475, 472, 469, 466, 463, 460, 457, 454, + 451, 448, 445, 442, 439, 436, 433, 430, 427, 424, + 421, 418, 415, 412, 409, 406, 403, 400, 397, 394, + 391, 388, 385, 382, 379, 376, 373, 370, 367, 364, + 361, 358, 355, 352, 349, 346, 343, 340, 337, 334, + 331, 328, 325, 322, 319, 316, 0 + }; + u8 index = 0; + + for (index = 0; index < SYS_TSINGMA_TEMP_TABLE_NUM; index++) { + if ((temp_code <= temp_mapping_tbl[index]) + && (temp_code > temp_mapping_tbl[index + 1])) { + break; + } + } + + if (index < 39) + *p_temp_val = 40 - index + (1 << 31); + else + *p_temp_val = index - 40; + + return 0; +} + +int get_switch_temperature(void) +{ + int temperature; + u32 value, offset, p_value = 0; + u32 timeout = SYS_TSINGMA_SENSOR_TIMEOUT; + + value = 0x310c7; + offset = 0xf * 4; + ctc5236_switch_write(OMCMEM_BASE + offset, 1, &value); + + /*config RTHMC_RST=1 */ + /*mask_write tbl-reg OmcMem 0x10 offset 0x0 0x00000010 0x00000010 */ + offset = 0x10 * 4; + ctc5236_switch_read(OMCMEM_BASE + offset, 1, &value); + value |= BIT(4); + ctc5236_switch_write(OMCMEM_BASE + offset, 1, &value); + + /*wait RTHMC_RST=1 */ + /*read tbl-reg OmcMem 0x10 offset 0x0 */ + timeout = SYS_TSINGMA_SENSOR_TIMEOUT; + offset = 0x10 * 4; + while (timeout) { + timeout--; + ctc5236_switch_read(OMCMEM_BASE + offset, 1, &value); + if ((BIT(4) & value) == 0) + break; + msleep(1); + } + if (timeout == 0) + return 0xffff; + + /*config ENBIAS=1£¬ENVR=1£¬ENAD=1 */ + /*mask_write tbl-reg OmcMem 0x11 offset 0x0 0x02000007 0x03000007 */ + offset = 0x11 * 4; + ctc5236_switch_read(OMCMEM_BASE + offset, 1, &value); + value |= BIT(0) | BIT(1) | BIT(2) | BIT(25); + value &= ~BIT(24); + ctc5236_switch_write(OMCMEM_BASE + offset, 1, &value); + + msleep(1); + + /*set RTHM_MODE=1,RSAMPLE_DONE_INTEN=1,RDUMMY_THMRD=1,RV_SAMPLE_EN=1 */ + /*mask_write tbl-reg OmcMem 0x10 offset 0x0 0x00000203 0x00000003 */ + /*mask_write tbl-reg OmcMem 0x8 offset 0x0 0x00000004 0x00000004 */ + /*mask_write tbl-reg OmcMem 0x12 offset 0x0 0x00000001 0x00000001 */ + offset = 0x10 * 4; + ctc5236_switch_read(OMCMEM_BASE + offset, 1, &value); + value |= BIT(0) | BIT(1) | BIT(9); + ctc5236_switch_write(OMCMEM_BASE + offset, 1, &value); + offset = 0x8 * 4; + ctc5236_switch_read(OMCMEM_BASE + offset, 1, &value); + value |= BIT(2); + ctc5236_switch_write(OMCMEM_BASE + offset, 1, &value); + offset = 0x12 * 4; + ctc5236_switch_read(OMCMEM_BASE + offset, 1, &value); + value |= BIT(0); + ctc5236_switch_write(OMCMEM_BASE + offset, 1, &value); + + /*mask_write tbl-reg OmcMem 0x10 offset 0x0 0x00000001 0x00000001 */ + offset = 0x10 * 4; + ctc5236_switch_read(OMCMEM_BASE + offset, 1, &value); + value |= BIT(0); + ctc5236_switch_write(OMCMEM_BASE + offset, 1, &value); + + msleep(1); + + /*mask_write tbl-reg OmcMem 0x12 offset 0x0 0x00000001 0x00000001 */ + offset = 0x12 * 4; + ctc5236_switch_read(OMCMEM_BASE + offset, 1, &value); + value |= BIT(0); + ctc5236_switch_write(OMCMEM_BASE + offset, 1, &value); + + /*Wait((mask_read tbl-reg OmcMem 0xa offset 0x0 0x00000004) =1) */ + timeout = SYS_TSINGMA_SENSOR_TIMEOUT; + offset = 0xa * 4; + while (timeout) { + timeout--; + ctc5236_switch_read(OMCMEM_BASE + offset, 1, &value); + if (value & BIT(2)) + break; + + msleep(1); + } + if (timeout == 0) + return 0xffff; + + /*mask_write tbl-reg OmcMem 0x11 offset 0x0 0x00000006 0x00000006 */ + offset = 0x11 * 4; + ctc5236_switch_read(OMCMEM_BASE + offset, 1, &value); + value |= BIT(1) | BIT(2); + ctc5236_switch_write(OMCMEM_BASE + offset, 1, &value); + + msleep(10); + + /*read-reg OmcMem 0xd offset 0x0 */ + offset = 0xd * 4; + ctc5236_switch_read(OMCMEM_BASE + offset, 1, &value); + _sys_tsingma_peri_get_temp_with_code(0, value, &p_value); + temperature = p_value & ~BIT(31); + if ((p_value & BIT(31)) == 0) + return temperature; + else + return -temperature; + +} +EXPORT_SYMBOL_GPL(get_switch_temperature); + +static int ctc_switch_probe(struct platform_device *pdev) +{ + struct resource *iomem; + void __iomem *ioaddr; + resource_size_t start; + + iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + start = iomem->start - 0x1000; + ioaddr = devm_ioremap(&pdev->dev, start, resource_size(iomem)); + if (IS_ERR(ioaddr)) + return -1; + access = (struct ctc_access_t *) ioaddr; + + return 0; +} + +static const struct of_device_id ctc_switch_of_match[] = { + {.compatible = "centec,switch"}, + {} +}; + +MODULE_DEVICE_TABLE(of, ctc_switch_of_match); + +static struct platform_driver ctc_switch_driver = { + .driver = { + .name = "ctc-switch", + .of_match_table = ctc_switch_of_match, + }, + .probe = ctc_switch_probe, +}; + +module_platform_driver(ctc_switch_driver); + +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:switch"); diff --git a/platform/centec-arm64/tsingma-bsp/src/ctc_wdt/Makefile b/platform/centec-arm64/tsingma-bsp/src/ctc_wdt/Makefile new file mode 100644 index 000000000000..f13d35509ba4 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/ctc_wdt/Makefile @@ -0,0 +1 @@ +obj-m = ctc_wdt.o diff --git a/platform/centec-arm64/tsingma-bsp/src/ctc_wdt/ctc_wdt.c b/platform/centec-arm64/tsingma-bsp/src/ctc_wdt/ctc_wdt.c new file mode 100644 index 000000000000..2beecbb99e70 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/ctc_wdt/ctc_wdt.c @@ -0,0 +1,398 @@ +/* drivers/char/watchdog/ctc-wdt.c + * + * Watchdog driver for CTC TSINGMA, based on ARM SP805 watchdog module + * + * Copyright (C) 2010 ST Microelectronics + * Viresh Kumar + * + * This file is licensed under the terms of the GNU General Public + * License version 2 or later. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../include/sysctl.h" +#include +#include + +/* default timeout in seconds */ +#define DEFAULT_TIMEOUT 60 + +#define MODULE_NAME "ctc-wdt" + +/* watchdog register offsets and masks */ +#define WDTLOAD 0x000 +#define LOAD_MIN 0x00000001 +#define LOAD_MAX 0xFFFFFFFF +#define WDTVALUE 0x004 +#define WDTCONTROL 0x008 + /* control register masks */ +#define INT_ENABLE (1 << 0) +#define RESET_ENABLE (1 << 1) +#define WDTINTCLR 0x00C +#define WDTRIS 0x010 +#define WDTMIS 0x014 +#define INT_MASK (1 << 0) +#define WDTLOCK 0xC00 +#define UNLOCK 0x1ACCE551 +#define LOCK 0x00000001 + +/* TsingMa SoC */ +#define WDTCLK_MAX 500000000UL + +/** + * struct ctc_wdt: ctc wdt device structure + * @wdd: instance of struct watchdog_device + * @lock: spin lock protecting dev structure and io access + * @base: base address of wdt + * @clk: clock structure of wdt + * @adev: amba device structure of wdt + * @status: current status of wdt + * @load_val: load value to be set for current timeout + */ +struct ctc_wdt { + struct watchdog_device wdd; + spinlock_t lock; + void __iomem *base; + struct clk *clk; + struct amba_device *adev; + unsigned int load_val; + struct regmap *regmap_base; +}; + +static bool nowayout = WATCHDOG_NOWAYOUT; +module_param(nowayout, bool, 0); +MODULE_PARM_DESC(nowayout, + "Set to 1 to keep watchdog running after device release"); + +/* This routine finds load value that will reset system in required timeout */ +static int wdt_setload(struct watchdog_device *wdd, unsigned int timeout) +{ + struct ctc_wdt *wdt = watchdog_get_drvdata(wdd); + u64 load, rate; + + rate = clk_get_rate(wdt->clk); + + /* + * ctc wdt runs counter with given value twice, after the end of first + * counter it gives an interrupt and then starts counter again. If + * interrupt already occurred then it resets the system. This is why + * load is half of what should be required. + */ + load = div_u64(rate, 2) * timeout - 1; + + load = (load > LOAD_MAX) ? LOAD_MAX : load; + load = (load < LOAD_MIN) ? LOAD_MIN : load; + + spin_lock(&wdt->lock); + wdt->load_val = load; + /* roundup timeout to closest positive integer value */ + wdd->timeout = div_u64((load + 1) * 2 + (rate / 2), rate); + spin_unlock(&wdt->lock); + + return 0; +} + +/* returns number of seconds left for reset to occur */ +static unsigned int wdt_timeleft(struct watchdog_device *wdd) +{ + struct ctc_wdt *wdt = watchdog_get_drvdata(wdd); + u64 load, rate; + + rate = clk_get_rate(wdt->clk); + + spin_lock(&wdt->lock); + load = readl_relaxed(wdt->base + WDTVALUE); + + /*If the interrupt is inactive then time left is WDTValue + WDTLoad. */ + if (!(readl_relaxed(wdt->base + WDTRIS) & INT_MASK)) + load += wdt->load_val + 1; + spin_unlock(&wdt->lock); + + return div_u64(load, rate); +} + +static int wdt_config(struct watchdog_device *wdd, bool ping) +{ + struct ctc_wdt *wdt = watchdog_get_drvdata(wdd); + int ret; + + if (!ping) { + + ret = clk_prepare_enable(wdt->clk); + if (ret) { + dev_err(&wdt->adev->dev, "clock enable fail"); + return ret; + } + } + + spin_lock(&wdt->lock); + + writel_relaxed(UNLOCK, wdt->base + WDTLOCK); + writel_relaxed(wdt->load_val, wdt->base + WDTLOAD); + writel_relaxed(INT_MASK, wdt->base + WDTINTCLR); + + if (!ping) + writel_relaxed(INT_ENABLE | RESET_ENABLE, wdt->base + + WDTCONTROL); + + writel_relaxed(LOCK, wdt->base + WDTLOCK); + + /* Flush posted writes. */ + readl_relaxed(wdt->base + WDTLOCK); + spin_unlock(&wdt->lock); + + return 0; +} + +static int wdt_ping(struct watchdog_device *wdd) +{ + return wdt_config(wdd, true); +} + +/* enables watchdog timers reset */ +static int wdt_enable(struct watchdog_device *wdd) +{ + return wdt_config(wdd, false); +} + +/* disables watchdog timers reset */ +static int wdt_disable(struct watchdog_device *wdd) +{ + struct ctc_wdt *wdt = watchdog_get_drvdata(wdd); + + spin_lock(&wdt->lock); + + writel_relaxed(UNLOCK, wdt->base + WDTLOCK); + writel_relaxed(0, wdt->base + WDTCONTROL); + writel_relaxed(LOCK, wdt->base + WDTLOCK); + + /* Flush posted writes. */ + readl_relaxed(wdt->base + WDTLOCK); + spin_unlock(&wdt->lock); + + clk_disable_unprepare(wdt->clk); + + return 0; +} + +static int wdt_restart(struct watchdog_device *wdd, unsigned long action, + void *cmd) +{ + struct ctc_wdt *wdt = watchdog_get_drvdata(wdd); + + spin_lock(&wdt->lock); + + writel_relaxed(UNLOCK, wdt->base + WDTLOCK); + writel_relaxed(0, wdt->base + WDTCONTROL); + writel_relaxed(1, wdt->base + WDTLOAD); + writel_relaxed(INT_ENABLE | RESET_ENABLE, wdt->base + WDTCONTROL); + writel_relaxed(LOCK, wdt->base + WDTLOCK); + + spin_unlock(&wdt->lock); + + mdelay(100); + + return 0; +} + +static int wdt_set_pretimeout(struct watchdog_device *wdd, + unsigned int new_pretimeout) +{ + struct ctc_wdt *wdt = watchdog_get_drvdata(wdd); + u64 load, rate; + + rate = clk_get_rate(wdt->clk); + + load = rate * new_pretimeout - 1; + load = (load > LOAD_MAX) ? LOAD_MAX : load; + load = (load < LOAD_MIN) ? LOAD_MIN : load; + + spin_lock(&wdt->lock); + wdt->load_val = load; + /* roundup timeout to closest positive integer value */ + wdd->pretimeout = div_u64((load + 1) + (rate / 2), rate); + + spin_unlock(&wdt->lock); + + return 0; +} + +static irqreturn_t ctc_wdt_irq(int irq, void *dev_id) +{ + struct ctc_wdt *wdt = dev_id; + + watchdog_notify_pretimeout(&wdt->wdd); + + return IRQ_HANDLED; +} + +static const struct watchdog_info wdt_info = { + .options = + WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | + WDIOF_PRETIMEOUT, + .identity = MODULE_NAME, +}; + +static const struct watchdog_ops wdt_ops = { + .owner = THIS_MODULE, + .start = wdt_enable, + .stop = wdt_disable, + .ping = wdt_ping, + .set_timeout = wdt_setload, + .get_timeleft = wdt_timeleft, + .restart = wdt_restart, + .set_pretimeout = wdt_set_pretimeout, +}; + +static int ctc_wdt_probe(struct amba_device *adev, const struct amba_id *id) +{ + struct ctc_wdt *wdt; + int ret = 0; + u64 rate; + unsigned int fdc; + + wdt = devm_kzalloc(&adev->dev, sizeof(*wdt), GFP_KERNEL); + if (!wdt) { + ret = -ENOMEM; + goto err; + } + + wdt->base = devm_ioremap_resource(&adev->dev, &adev->res); + if (IS_ERR(wdt->base)) + return PTR_ERR(wdt->base); + + wdt->clk = devm_clk_get(&adev->dev, NULL); + if (IS_ERR(wdt->clk)) { + dev_warn(&adev->dev, "Clock not found\n"); + ret = PTR_ERR(wdt->clk); + goto err; + } + wdt->regmap_base = syscon_regmap_lookup_by_phandle(adev->dev.of_node, + "ctc,sysctrl"); + if (IS_ERR(wdt->regmap_base)) + return PTR_ERR(wdt->regmap_base); + + /* + * TsingMa SoC wdt reference clock is obtained by clockSub frequency + * division,which is 500Mhz.So we need to set the frequency division + * register according to the configured clock. + */ + + rate = clk_get_rate(wdt->clk); + if (rate < 0 || rate > WDTCLK_MAX) { + dev_err(&adev->dev, "Clock out of range\n"); + goto err; + } + + fdc = div_u64(WDTCLK_MAX, rate); + regmap_write(wdt->regmap_base, offsetof(struct SysCtl_regs, SysWdt0Cnt), + fdc); + regmap_write(wdt->regmap_base, offsetof(struct SysCtl_regs, SysWdt1Cnt), + fdc); + wdt->adev = adev; + wdt->wdd.info = &wdt_info; + wdt->wdd.ops = &wdt_ops; + wdt->wdd.parent = &adev->dev; + + spin_lock_init(&wdt->lock); + watchdog_set_nowayout(&wdt->wdd, nowayout); + watchdog_set_drvdata(&wdt->wdd, wdt); + wdt_setload(&wdt->wdd, DEFAULT_TIMEOUT); + ret = devm_request_irq(&adev->dev, adev->irq[0], ctc_wdt_irq, + 0, "ctc-wdt", wdt); + if (ret < 0) { + dev_err(&adev->dev, "devm_request_irq() failed: %d\n", ret); + goto err; + } + ret = watchdog_register_device(&wdt->wdd); + if (ret) { + dev_err(&adev->dev, "watchdog_register_device() failed: %d\n", + ret); + goto err; + } + amba_set_drvdata(adev, wdt); + + dev_info(&adev->dev, "registration successful\n"); + return 0; + +err: + dev_err(&adev->dev, "Probe Failed!!!\n"); + return ret; +} + +static int ctc_wdt_remove(struct amba_device *adev) +{ + struct ctc_wdt *wdt = amba_get_drvdata(adev); + + watchdog_unregister_device(&wdt->wdd); + watchdog_set_drvdata(&wdt->wdd, NULL); + + return 0; +} + +static int __maybe_unused ctc_wdt_suspend(struct device *dev) +{ + struct ctc_wdt *wdt = dev_get_drvdata(dev); + + if (watchdog_active(&wdt->wdd)) + return wdt_disable(&wdt->wdd); + + return 0; +} + +static int __maybe_unused ctc_wdt_resume(struct device *dev) +{ + struct ctc_wdt *wdt = dev_get_drvdata(dev); + + if (watchdog_active(&wdt->wdd)) + return wdt_enable(&wdt->wdd); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(ctc_wdt_dev_pm_ops, ctc_wdt_suspend, ctc_wdt_resume); + +static struct amba_id ctc_wdt_ids[] = { + /* Centec TsingMa SoC WDT ID */ + { + .id = 0x001bb824, + .mask = 0x00ffffff, + }, + {0, 0}, +}; + +MODULE_DEVICE_TABLE(amba, ctc_wdt_ids); + +static struct amba_driver ctc_wdt_driver = { + .drv = { + .name = MODULE_NAME, + .pm = &ctc_wdt_dev_pm_ops, + }, + .id_table = ctc_wdt_ids, + .probe = ctc_wdt_probe, + .remove = ctc_wdt_remove, +}; + +module_amba_driver(ctc_wdt_driver); + +MODULE_AUTHOR("lius "); +MODULE_DESCRIPTION("ARM CTC Watchdog Driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/centec-arm64/tsingma-bsp/src/ctcmac/Makefile b/platform/centec-arm64/tsingma-bsp/src/ctcmac/Makefile new file mode 100644 index 000000000000..f29ac076955d --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/ctcmac/Makefile @@ -0,0 +1,3 @@ +KBUILD_EXTRA_SYMBOLS = /sonic/platform/centec-arm64/tsingma-bsp/src/ctc5236_switch/Module.symvers + +obj-m = ctcmac.o ctcmac_test.o ctc5236_mdio.o diff --git a/platform/centec-arm64/tsingma-bsp/src/ctcmac/ctc5236_mdio.c b/platform/centec-arm64/tsingma-bsp/src/ctcmac/ctc5236_mdio.c new file mode 100644 index 000000000000..c176e0cfbc86 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/ctcmac/ctc5236_mdio.c @@ -0,0 +1,195 @@ +/* Centec cpu_mac Ethernet Driver -- cpu_mac controller implementation + * Provides Bus interface for MIIM regs + * + * Author: liuht + * + * Copyright 2002-2018, Centec Networks (Suzhou) Co., Ltd. + * + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "ctcmac.h" +#include "ctcmac_reg.h" + +struct ctc_mdio_priv { + void __iomem *map; + struct mdio_soc_regs *mdio_reg; +}; + +static int ctc_mdio_write(struct mii_bus *bus, int mii_id, int reg, u16 value) +{ + int ret = 0; + u32 cmd = 0; + u32 tmp = 0; + struct ctc_mdio_priv *priv = (struct ctc_mdio_priv *)bus->priv; + + cmd = CTCMAC_MDIO_CMD_REGAD(reg) | CTCMAC_MDIO_CMD_PHYAD(mii_id) + | CTCMAC_MDIO_CMD_OPCODE(1) | CTCMAC_MDIO_CMD_DATA(value); + + writel(cmd, &priv->mdio_reg->mdio_soc_cmd_0[0]); + writel(1, &priv->mdio_reg->mdio_soc_cmd_0[1]); + + ret = readl_poll_timeout(&priv->mdio_reg->mdio_soc_status_0, + tmp, tmp & CTCMAC_MDIO_STAT(1), 1000, 10000); + + if (ret < 0) + return -1; + + return 0; +} + +static int ctc_mdio_read(struct mii_bus *bus, int mii_id, int reg) +{ + int ret = 0; + u32 cmd = 0; + u32 status; + int value = 0; + struct ctc_mdio_priv *priv = (struct ctc_mdio_priv *)bus->priv; + + cmd = CTCMAC_MDIO_CMD_REGAD(reg) | CTCMAC_MDIO_CMD_PHYAD(mii_id) + | CTCMAC_MDIO_CMD_OPCODE(2); + + writel(cmd, &priv->mdio_reg->mdio_soc_cmd_0[0]); + writel(1, &priv->mdio_reg->mdio_soc_cmd_0[1]); + + ret = readl_poll_timeout(&priv->mdio_reg->mdio_soc_status_0, + status, status & CTCMAC_MDIO_STAT(1), 1000, + 10000); + if (ret < 0) { + pr_err("ctc_mdio_read1\n"); + return -1; + } + + value = (readl(&priv->mdio_reg->mdio_soc_status_0) & 0xffff); + + return value; +} + +static int ctc_mdio_reset(struct mii_bus *bus) +{ + struct ctc_mdio_priv *priv = (struct ctc_mdio_priv *)bus->priv; + + writel(0x91f, &priv->mdio_reg->mdio_soc_cfg_0); + + return 0; +} + +static const struct of_device_id ctc_mdio_match[] = { + { + .compatible = "ctc,mdio", + }, + {}, +}; + +MODULE_DEVICE_TABLE(of, ctc_mdio_match); + +static int ctc_mdio_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct resource res; + struct ctc_mdio_priv *priv; + struct mii_bus *new_bus; + int err; + + new_bus = mdiobus_alloc_size(sizeof(*priv)); + if (!new_bus) + return -ENOMEM; + + priv = new_bus->priv; + new_bus->name = "CTC MII Bus", new_bus->read = &ctc_mdio_read; + new_bus->write = &ctc_mdio_write; + new_bus->reset = &ctc_mdio_reset; + + err = of_address_to_resource(np, 0, &res); + if (err < 0) { + pr_err("Of address to resource fail %d!\n", err); + goto error; + } + + snprintf(new_bus->id, MII_BUS_ID_SIZE, "%s@%llx", np->name, + (unsigned long long)res.start); + + priv->map = of_iomap(np, 0); + if (!priv->map) { + err = -ENOMEM; + pr_err("of iomap fail %d!\n", err); + goto error; + } + priv->mdio_reg = (struct mdio_soc_regs *)priv->map; + new_bus->parent = &pdev->dev; + platform_set_drvdata(pdev, new_bus); + + err = of_mdiobus_register(new_bus, np); + if (err) { + pr_err("register mdio bus fail %d!\n", err); + goto error; + } + + return 0; + +error: + if (priv->map) + iounmap(priv->map); + + kfree(new_bus); + + return err; +} + +static int ctc_mdio_remove(struct platform_device *pdev) +{ + struct device *device = &pdev->dev; + struct mii_bus *bus = dev_get_drvdata(device); + struct ctc_mdio_priv *priv = bus->priv; + + mdiobus_unregister(bus); + + iounmap(priv->map); + mdiobus_free(bus); + + return 0; +} + +static struct platform_driver ctc_mdio_driver = { + .driver = { + .name = "ctc_mdio", + .of_match_table = ctc_mdio_match, + }, + .probe = ctc_mdio_probe, + .remove = ctc_mdio_remove, +}; + +module_platform_driver(ctc_mdio_driver); + +MODULE_LICENSE("GPL"); diff --git a/platform/centec-arm64/tsingma-bsp/src/ctcmac/ctcmac.c b/platform/centec-arm64/tsingma-bsp/src/ctcmac/ctcmac.c new file mode 100644 index 000000000000..6e267ed8fb42 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/ctcmac/ctcmac.c @@ -0,0 +1,2697 @@ +/* Centec cpu_mac Ethernet Driver -- cpu_mac controller implementation + * Provides Bus interface for MIIM regs + * + * Author: liuht + * + * Copyright 2002-2018, Centec Networks (Suzhou) Co., Ltd. + * + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "../pinctrl-ctc/pinctrl-ctc.h" +#include "../include/sysctl.h" +#include +#include +#include +#include "../include/ctc5236_switch.h" +#include +#include "ctcmac.h" +#include "ctcmac_reg.h" + +static int ctcmac_alloc_skb_resources(struct net_device *ndev); +static int ctcmac_free_skb_resources(struct ctcmac_private *priv); +static void cpumac_start(struct ctcmac_private *priv); +static void cpumac_halt(struct ctcmac_private *priv); +static void ctcmac_hw_init(struct ctcmac_private *priv); +static spinlock_t global_reglock __aligned(SMP_CACHE_BYTES); +static int g_reglock_init_done; +static int g_mac_unit_init_done; +static struct regmap *regmap_base; +static struct ctcmac_pkt_stats g_pkt_stats[2]; + +static const char ctc_stat_gstrings[][ETH_GSTRING_LEN] = { + "RX-bytes-good-ucast", + "RX-frame-good-ucast", + "RX-bytes-good-mcast", + "RX-frame-good-mcast", + "RX-bytes-good-bcast", + "RX-frame-good-bcast", + "RX-bytes-good-pause", + "RX-frame-good-pause", + "RX-bytes-good-pfc", + "RX-frame-good-pfc", + "RX-bytes-good-control", + "RX-frame-good-control", + "RX-bytes-fcs-error", + "RX-frame-fcs-error", + "RX-bytes-mac-overrun", + "RX-frame-mac-overrun", + "RX-bytes-good-63B", + "RX-frame-good-63B", + "RX-bytes-bad-63B", + "RX-frame-bad-63B", + "RX-bytes", + "RX-frame", + "RX-bytes-bad", + "RX-frame-bad", + "RX-bytes-good-jumbo", + "RX-frame-good-jumbo", + "RX-bytes-bad-jumbo", + "RX-frame-bad-jumbo", + "RX-bytes-64B", + "RX-frame-64B", + "RX-bytes-127B", + "RX-frame-127B", + "RX-bytes-255B", + "RX-frame-255B", + "RX-bytes-511B", + "RX-frame-511B", + "RX-bytes-1023B", + "RX-frame-1023B", + "RX-bytes", + "RX-frame", + "TX-bytes-ucast", + "TX-frame-ucast", + "TX-bytes-mcast", + "TX-frame-mcast", + "TX-bytes-bcast", + "TX-frame-bcast", + "TX-bytes-pause", + "TX-frame-pause", + "TX-bytes-control", + "TX-frame-control", + "TX-bytes-fcs-error", + "TX-frame-fcs-error", + "TX-bytes-underrun", + "TX-frame-underrun", + "TX-bytes-63B", + "TX-frame-63B", + "TX-bytes-64B", + "TX-frame-64B", + "TX-bytes-127B", + "TX-frame-127B", + "TX-bytes-255B", + "TX-frame-255B", + "TX-bytes-511B", + "TX-frame-511B", + "TX-bytes-1023B", + "TX-frame-1023B", + "TX-bytes-mtu1", + "TX-frame-mtu1", + "TX-bytes-mtu2", + "TX-frame-mtu2", + "TX-bytes-jumbo", + "TX-frame-jumbo", + "mtu1", + "mtu2", +}; + +static void clrsetbits(unsigned __iomem *addr, u32 clr, u32 set) +{ + writel((readl(addr) & ~(clr)) | (set), addr); +} + +static inline u32 ctcmac_regr(unsigned __iomem *addr) +{ + u32 val; + + val = readl(addr); + return val; +} + +static inline void ctcmac_regw(unsigned __iomem *addr, u32 val) +{ + writel(val, addr); +} + +static inline int ctcmac_rxbd_unused(struct ctcmac_priv_rx_q *rxq) +{ + /* left one rx desc unused */ + if (rxq->next_to_clean > rxq->next_to_use) + return rxq->next_to_clean - rxq->next_to_use - 1; + + return rxq->rx_ring_size + rxq->next_to_clean - rxq->next_to_use - 1; +} + +static int ctcmac_alloc_tx_queues(struct ctcmac_private *priv) +{ + int i; + + for (i = 0; i < priv->num_tx_queues; i++) { + priv->tx_queue[i] = kzalloc(sizeof(*priv->tx_queue[i]), + GFP_KERNEL); + if (!priv->tx_queue[i]) + return -ENOMEM; + + priv->tx_queue[i]->tx_skbuff = NULL; + priv->tx_queue[i]->qindex = i; + priv->tx_queue[i]->dev = priv->ndev; + spin_lock_init(&priv->tx_queue[i]->txlock); + } + return 0; +} + +static int ctcmac_alloc_rx_queues(struct ctcmac_private *priv) +{ + int i; + + for (i = 0; i < priv->num_rx_queues; i++) { + priv->rx_queue[i] = kzalloc(sizeof(*priv->rx_queue[i]), + GFP_KERNEL); + if (!priv->rx_queue[i]) + return -ENOMEM; + + priv->rx_queue[i]->qindex = i; + priv->rx_queue[i]->ndev = priv->ndev; + } + return 0; +} + +static void ctcmac_unmap_io_space(struct ctcmac_private *priv) +{ + if (priv->iobase) + iounmap(priv->iobase); +} + +static void ctcmac_free_tx_queues(struct ctcmac_private *priv) +{ + int i; + + for (i = 0; i < priv->num_tx_queues; i++) + kfree(priv->tx_queue[i]); +} + +static void ctcmac_free_rx_queues(struct ctcmac_private *priv) +{ + int i; + + for (i = 0; i < priv->num_rx_queues; i++) + kfree(priv->rx_queue[i]); +} + +static void ctcmac_free_dev(struct ctcmac_private *priv) +{ + if (priv->ndev) + free_netdev(priv->ndev); +} + +static int ctcmac_fixed_phy_link_update(struct net_device *dev, + struct fixed_phy_status *status) +{ + u32 mon = 0; + struct ctcmac_private *priv; + + if (!dev) + return 0; + + priv = netdev_priv(dev); + + if (priv->interface != PHY_INTERFACE_MODE_SGMII) + return 0; + + mon = readl(&priv->cpumac_reg->cpu_mac_sgmii_mon[0]); + if (priv->autoneg_mode == CTCMAC_AUTONEG_DISABLE) { + if ((mon & 0x100) == 0x100) + status->link = 1; + else + status->link = 0; + + } else { + if ((mon & CSM_ANST_MASK) == 6) + status->link = 1; + else + status->link = 0; + } + + return 0; +} + +static int ctcmac_of_init(struct platform_device *ofdev, + struct net_device **pdev) +{ + int err = 0, index; + const char *ctype, *automode, *dfe; + struct net_device *dev = NULL; + struct ctcmac_private *priv = NULL; + unsigned int num_tx_qs, num_rx_qs; + struct device_node *np = ofdev->dev.of_node; + + num_tx_qs = CTCMAC_TX_QUEUE_MAX; + num_rx_qs = CTCMAC_RX_QUEUE_MAX; + + *pdev = alloc_etherdev_mq(sizeof(*priv), num_tx_qs); + dev = *pdev; + if (!dev) + return -ENOMEM; + + priv = netdev_priv(dev); + priv->ndev = dev; + priv->ofdev = ofdev; + priv->dev = &ofdev->dev; + priv->dev->coherent_dma_mask = DMA_BIT_MASK(64); + priv->num_tx_queues = num_tx_qs; + netif_set_real_num_rx_queues(dev, num_rx_qs); + priv->num_rx_queues = num_rx_qs; + + if (ctcmac_alloc_tx_queues(priv)) + goto fail; + + if (ctcmac_alloc_rx_queues(priv)) + goto fail; + + /* init cpumac_reg/cpumac_mem/cpumac_unit address */ + priv->iobase = of_iomap(np, 0); + priv->cpumac_reg = priv->iobase + CPUMAC_REG_BASE; + priv->cpumac_mem = priv->iobase + CPUMAC_MEM_BASE; + priv->cpumacu_reg = of_iomap(np, 1) + CPUMACUNIT_REG_BASE; + + /* Get cpu_mac index */ + err = of_property_read_u32(np, "index", &index); + if (err == 0) + priv->index = index; + else + priv->index = 0; + + /* Get interface type, CTC5236 only support PHY_INTERFACE_MODE_SGMII */ + err = of_property_read_string(np, "phy-connection-type", &ctype); + if (err == 0 && !strncmp(ctype, "mii", 3)) { + priv->interface = PHY_INTERFACE_MODE_MII; + priv->supported = SUPPORTED_10baseT_Full; + } else { + priv->interface = PHY_INTERFACE_MODE_SGMII; + priv->supported = CTCMAC_SUPPORTED; + } + + err = of_property_read_string(np, "auto-nego-mode", &automode); + if (err == 0 && !strncmp(automode, "disable", 7)) + priv->autoneg_mode = CTCMAC_AUTONEG_DISABLE; + else if (err == 0 && !strncmp(automode, "sgmii-mac", 9)) + priv->autoneg_mode = CTCMAC_AUTONEG_MAC_M; + else if (err == 0 && !strncmp(automode, "sgmii-phy", 9)) + priv->autoneg_mode = CTCMAC_AUTONEG_PHY_M; + else if (err == 0 && !strncmp(automode, "1000base-x", 10)) + priv->autoneg_mode = CTCMAC_AUTONEG_1000BASEX_M; + else + priv->autoneg_mode = CTCMAC_AUTONEG_MAC_M; + + err = of_property_read_string(np, "dfe", &dfe); + if (err == 0 && !strncmp(dfe, "enable", 6)) + priv->dfe_enable = 1; + else + priv->dfe_enable = 0; + + priv->phy_node = of_parse_phandle(np, "phy-handle", 0); + /* In the case of a fixed PHY, the DT node associated + * to the PHY is the Ethernet MAC DT node. + */ + if (!priv->phy_node && of_phy_is_fixed_link(np)) { + err = of_phy_register_fixed_link(np); + if (err) + return -1; + + priv->phy_node = of_node_get(np); + } + /* mapping from hw irq to sw irq */ + priv->irqinfo[CTCMAC_NORMAL].irq = irq_of_parse_and_map(np, 0); + priv->irqinfo[CTCMAC_FUNC].irq = irq_of_parse_and_map(np, 1); + + return 0; + +fail: + ctcmac_unmap_io_space(priv); + ctcmac_free_tx_queues(priv); + ctcmac_free_rx_queues(priv); + ctcmac_free_dev(priv); + + return -1; +} + +int startup_ctcmac(struct net_device *ndev) +{ + struct ctcmac_private *priv = netdev_priv(ndev); + int err; + + ctcmac_hw_init(priv); + + err = ctcmac_alloc_skb_resources(ndev); + if (err) + return err; + + /* barrier */ + smp_mb__before_atomic(); + clear_bit(CTCMAC_DOWN, &priv->state); + /* barrier */ + smp_mb__after_atomic(); + + cpumac_start(priv); + /* force link state update after mac reset */ + priv->oldlink = 0; + priv->oldspeed = 0; + priv->oldduplex = -1; + + phy_start(ndev->phydev); + + napi_enable(&priv->napi_rx); + napi_enable(&priv->napi_tx); + + netif_tx_wake_all_queues(ndev); + + return 0; +} + +void stop_ctcmac(struct net_device *ndev) +{ + struct ctcmac_private *priv = netdev_priv(ndev); + + /* disable ints and gracefully shut down Rx/Tx DMA */ + cpumac_halt(priv); + + netif_tx_stop_all_queues(ndev); + + /* barrier */ + smp_mb__before_atomic(); + set_bit(CTCMAC_DOWN, &priv->state); + /* barrier */ + smp_mb__after_atomic(); + napi_disable(&priv->napi_rx); + napi_disable(&priv->napi_tx); + phy_stop(ndev->phydev); + ctcmac_free_skb_resources(priv); +} + +static void ctcmac_reset(struct net_device *ndev) +{ + struct ctcmac_private *priv = netdev_priv(ndev); + + while (test_and_set_bit_lock(CTCMAC_RESETTING, &priv->state)) + cpu_relax(); + + stop_ctcmac(ndev); + startup_ctcmac(ndev); + clear_bit_unlock(CTCMAC_RESETTING, &priv->state); +} + +/* ctcmac_reset_task gets scheduled when a packet has not been + * transmitted after a set amount of time. + * For now, assume that clearing out all the structures, and + * starting over will fix the problem. + */ +static void ctcmac_reset_task(struct work_struct *work) +{ + struct ctcmac_private *priv = container_of(work, struct ctcmac_private, + reset_task); + ctcmac_reset(priv->ndev); +} + +/* get the rxdesc number that was used by cpu_mac but has not been + * handled by CPU + */ +static int ctcmac_rxbd_recycle(struct ctcmac_private *priv, int qidx) +{ + u32 count; + + if (qidx) { + count = readl(&priv->cpumac_reg->cpu_mac_desc_mon[2]); + return count & 0xffff; + } + + count = readl(&priv->cpumac_reg->cpu_mac_desc_mon[1]); + + return (count >> 16) & 0xffff; +} + +static int ctcmac_rxbd_usable(struct ctcmac_private *priv, int qidx) +{ + return (readl(&priv->cpumac_reg->cpu_mac_desc_mon[0]) >> (qidx * 16)) & + 0xffff; +} + +/* get the txdesc number that was used by cpu_mac + * but has not been handled by CPU + */ +static int ctcmac_txbd_used_untreated(struct ctcmac_private *priv) +{ + u32 count; + + count = readl(&priv->cpumac_reg->cpu_mac_desc_mon[2]); + + return (count >> 16) & 0xffff; +} + +/* Add rx buffer data to skb fragment */ +static bool ctcmac_add_rx_frag(struct ctcmac_rx_buff *rxb, u32 lstatus, + struct sk_buff *skb, bool first) +{ + struct page *page = rxb->page; + unsigned int size = + (lstatus & CPU_MAC_DESC_INTF_W1_DESC_SIZE_MASK) >> 8; + int data_size; + + /* Remove the CRC from the packet length */ + if (lstatus & CPU_MAC_DESC_INTF_W1_DESC_EOP) + data_size = size - 4; + else + data_size = size; + + if (likely(first)) { + skb_put(skb, data_size); + } else { + if (data_size > 0) + skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, + rxb->page_offset, data_size, + CTCMAC_RXB_TRUESIZE); + + if (data_size < 0) + pskb_trim(skb, skb->len + data_size); + } + + /* try reuse page */ + if (unlikely(page_count(page) != 1)) + return false; + + /* change offset to the other half */ + rxb->page_offset ^= CTCMAC_RXB_TRUESIZE; + + if (data_size > 0) + page_ref_inc(page); + + return true; +} + +/* Reused page that has been release by CPU */ +static void ctcmac_reuse_rx_page(struct ctcmac_priv_rx_q *rxq, + struct ctcmac_rx_buff *old_rxb) +{ + struct ctcmac_rx_buff *new_rxb; + u16 nta = rxq->next_to_alloc; + + new_rxb = &rxq->rx_buff[nta]; + + /* find next buf that can reuse a page */ + nta++; + rxq->next_to_alloc = (nta < rxq->rx_ring_size) ? nta : 0; + + /* copy page reference */ + *new_rxb = *old_rxb; + + /* sync for use by the device */ + dma_sync_single_range_for_device(rxq->dev, old_rxb->dma, + old_rxb->page_offset, + CTCMAC_RXB_TRUESIZE, DMA_FROM_DEVICE); +} + +/* Handle the rx buffer that has been used by cpu_mac */ +static struct sk_buff *ctcmac_get_next_rxbuff(struct ctcmac_priv_rx_q *rx_queue, + u32 lstatus, struct sk_buff *skb) +{ + struct ctcmac_rx_buff *rxb = + &rx_queue->rx_buff[rx_queue->next_to_clean]; + struct page *page = rxb->page; + bool first = false; + + if (likely(!skb)) { + void *buff_addr = page_address(page) + rxb->page_offset; + + skb = build_skb(buff_addr, CTCMAC_SKBFRAG_SIZE); + if (unlikely(!skb)) + return NULL; + first = true; + } + + dma_sync_single_range_for_cpu(rx_queue->dev, rxb->dma, rxb->page_offset, + CTCMAC_RXB_TRUESIZE, DMA_FROM_DEVICE); + + if (ctcmac_add_rx_frag(rxb, lstatus, skb, first)) { + /* reuse the free half of the page */ + ctcmac_reuse_rx_page(rx_queue, rxb); + } else { + /* page cannot be reused, unmap it */ + dma_unmap_page(rx_queue->dev, rxb->dma, + PAGE_SIZE, DMA_FROM_DEVICE); + } + + /* clear rxb content */ + rxb->page = NULL; + + return skb; +} + +static void ctcmac_process_frame(struct net_device *ndev, struct sk_buff *skb) +{ + skb->protocol = eth_type_trans(skb, ndev); +} + +int ctc_mac_hss_write(struct ctcmac_private *priv, u8 addr, u8 data, + u8 serdes_id) +{ + u8 accid; + int timeout = 2000; + u32 val = 0, mon = 0; + + if (serdes_id == 0) + accid = 3; + else if (serdes_id == 1) + accid = 4; + else + accid = 0; + val = addr | (data << 8) | (accid << 24) | (1 << 31); + writel(val, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + + while (timeout--) { + mon = + readl(&priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_result); + if (mon & CPU_MAC_UNIT_HSS_REG_ACC_RESULT_W0_HSS_ACC_ACK_MASK) + break; + mdelay(1); + } + if (!(mon & CPU_MAC_UNIT_HSS_REG_ACC_RESULT_W0_HSS_ACC_ACK_MASK)) { + dev_err(&priv->ndev->dev, + "wait for write ack cpu_mac_unit_hss_reg_acc_result:0x%x addr 0x%x data 0x%x serdes %d fail!\n", + readl(&priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_result), + addr, data, serdes_id); + return -1; + } + + return 0; +} + +int ctc_mac_hss_read(struct ctcmac_private *priv, u8 addr, u8 *data, + u8 serdes_id) +{ + u8 accid; + u32 val = 0; + u32 mon = 0; + int timeout = 2000; + + if (serdes_id == 0) + accid = 3; + else if (serdes_id == 1) + accid = 4; + else + accid = 0; + val = addr | (1 << 16) | (accid << 24) | (1 << 31); + + writel(val, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + + while (timeout--) { + mon = + readl(&priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_result); + if (mon & CPU_MAC_UNIT_HSS_REG_ACC_RESULT_W0_HSS_ACC_ACK_MASK) + break; + mdelay(1); + } + if (!(mon & CPU_MAC_UNIT_HSS_REG_ACC_RESULT_W0_HSS_ACC_ACK_MASK)) { + dev_err(&priv->ndev->dev, + "wait for read ack cpu_mac_unit_hss_reg_acc_result:0x%x fail!\n", + readl(&priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_result)); + *data = 0x0; + return -1; + } + + val = readl(&priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_result); + *data = val & 0xff; + + return 0; +} + +static int ctcmac_maximize_margin_of_cmu_tempearture_ramp(struct ctcmac_private + *priv) +{ + u8 val, ctune, delta, ctune_cal; + int tmpr = 0; + + tmpr = get_switch_temperature(); + if (tmpr == 0xffff) { + pr_err("get temperature fail!\n"); + return -1; + } + + ctc_mac_hss_read(priv, 0x1c, &val, 2); + val &= 0xf8; + val |= 0x4; + ctc_mac_hss_write(priv, 0x1c, val, 2); + + /*r_pll_dlol_en 0x30[0] write 1 enable pll lol status output */ + ctc_mac_hss_read(priv, 0x30, &val, 2); + val |= BIT(0); + ctc_mac_hss_write(priv, 0x30, val, 2); + + if (tmpr <= -20) + delta = 2; + else if (tmpr <= 60) + delta = 1; + else + delta = 0; + + /*read_vco_ctune 0xe0[3:0] read ctune raw value */ + ctc_mac_hss_read(priv, 0xe0, &val, 2); + ctune = val & 0xf; + ctune_cal = ctune - delta; + /*cfg_vco_byp_ctune 0x07[3:0] write (ctune - delta) */ + ctc_mac_hss_read(priv, 0x7, &val, 2); + val &= 0xf0; + val |= ctune_cal; + ctc_mac_hss_write(priv, 0x7, val, 2); + + /*cfg_vco_cal_byp 0x06[7] write 1 */ + ctc_mac_hss_read(priv, 0x6, &val, 2); + val |= BIT(7); + ctc_mac_hss_write(priv, 0x6, val, 2); + + /*for temperature -40~-20C, try (ctune-1) if (ctune-2) causes lol */ + mdelay(10); + /*pll_lol_udl 0xe0[4] read 0 */ + val = ctc_mac_hss_read(priv, 0xe0, &val, 2); + if ((0 != (val & BIT(4))) && delta == 2) { + /*cfg_vco_byp_ctune 0x07[3:0] write (ctune - 1) */ + ctune_cal = ctune - 1; + ctc_mac_hss_read(priv, 0x7, &val, 2); + val &= 0xf0; + val |= ctune_cal; + ctc_mac_hss_write(priv, 0x7, val, 2); + } + /*check pll lol */ + mdelay(10); + /*pll_lol_udl 0xe0[4] read 0 */ + val = ctc_mac_hss_read(priv, 0xe0, &val, 2); + if (0 != (val & BIT(4))) { + pr_err("maximize margin of cmu tempearture ramp fail!\n"); + return -1; + } + + return 0; +} + +/* serdes init flow */ +static int ctc_mac_serdes_init(struct ctcmac_private *priv) +{ + int ret = 0; + u32 status; + int delay_ms = 10; + + if (priv->dfe_enable) { + /* reset serdes */ + writel(0x4610b003, &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[5]); + writel(0x4610b003, + &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[11]); + writel(0x83806000, &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[0]); + writel(0x28061800, &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[2]); + writel(0x0066c03a, &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[6]); + writel(0x28061810, &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[8]); + writel(0x0066c03a, + &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[12]); + } else { + /* reset serdes */ + writel(0x4610a805, &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[5]); + writel(0x4610a805, + &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[11]); + writel(0x83806000, &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[0]); + writel(0x28061800, &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[2]); + writel(0x0026c02a, &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[6]); + writel(0x28061810, &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[8]); + writel(0x0026c02a, + &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[12]); + } + + /* offset0 bit1 BlkRstN */ + writel(0x83806002, &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[0]); + mdelay(delay_ms); + + writel(0x80002309, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x80000842, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x8000ea45, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + + /* serdes 0 init */ + writel(0x83000a05, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x83002008, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x8300640f, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x83000214, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x83008015, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x83000116, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x83001817, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x83003018, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x83000e24, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x83008226, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x83001f27, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x83002028, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x83002829, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x8300302a, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x83002038, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x8300223a, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x8300523b, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x83002040, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x8300f141, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x8300014a, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x8300e693, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + + /* serdes 1 init */ + writel(0x84000a05, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x84002008, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x8400640f, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x84000214, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x84008015, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x84000116, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x84001817, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x84003018, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x84000e24, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x84008226, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x84001f27, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x84002028, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x84002829, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x8400302a, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x84002038, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x8400223a, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x8400523b, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x84002040, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x8400f141, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x8400014a, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x8400e693, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + + ctc_mac_hss_write(priv, 0x0c, 0x21, 0); + ctc_mac_hss_write(priv, 0x0f, 0x64, 0); + ctc_mac_hss_write(priv, 0x1a, 0x06, 0); + ctc_mac_hss_write(priv, 0x91, 0x30, 0); + ctc_mac_hss_write(priv, 0x48, 0x20, 0); + ctc_mac_hss_write(priv, 0x90, 0x30, 0); + //ctc_mac_hss_write(priv, 0x9e, 0x36, 0); + //ctc_mac_hss_write(priv, 0x93, 0x76, 0); + ctc_mac_hss_write(priv, 0x14, 0x01, 0); + ctc_mac_hss_write(priv, 0x26, 0x81, 0); + + ctc_mac_hss_write(priv, 0x0c, 0x21, 1); + ctc_mac_hss_write(priv, 0x0f, 0x64, 1); + ctc_mac_hss_write(priv, 0x1a, 0x06, 1); + ctc_mac_hss_write(priv, 0x91, 0x30, 1); + ctc_mac_hss_write(priv, 0x48, 0x20, 1); + ctc_mac_hss_write(priv, 0x90, 0x30, 1); + //ctc_mac_hss_write(priv, 0x9e, 0x36, 1); + //ctc_mac_hss_write(priv, 0x93, 0x76, 1); + ctc_mac_hss_write(priv, 0x14, 0x01, 1); + ctc_mac_hss_write(priv, 0x26, 0x81, 1); + + /* serdes post release */ + writel(0x83806003, &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[0]); + writel(0x83826003, &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[0]); + + writel(0x28061801, &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[2]); + writel(0x28061c01, &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[2]); + writel(0x28071c01, &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[2]); + + writel(0x28061811, &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[8]); + writel(0x28061c11, &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[8]); + writel(0x28071c11, &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[8]); + + ret = + readl_poll_timeout(&priv->cpumacu_reg->cpu_mac_unit_hss_mon[1], + status, + status & + CPU_MAC_UNIT_HSS_MON_W1_MON_HSS_L0_DFE_RST_DONE, + 1000, 2000000); + if (ret) { + netdev_dbg(priv->ndev, + "%s:wait for hss reset done fail with cpu_mac_unit_hss_mon[1]:0x%x\n", + priv->ndev->name, + readl(&priv->cpumacu_reg->cpu_mac_unit_hss_mon[1])); + } + mdelay(delay_ms); + + ctcmac_maximize_margin_of_cmu_tempearture_ramp(priv); + + return 0; +} + +/* Hardware init flow */ +static void ctcmac_hw_init(struct ctcmac_private *priv) +{ + int i; + u32 val; + int use_extram = 0; + + /* two cpumac access the same cpumac unit register */ + spin_lock_irq(&global_reglock); + if (priv->index == 0) { + /* release cpu_mac_0 */ + clrsetbits(&priv->cpumacu_reg->cpu_mac_unit_reset_ctl, + CPU_MAC_UNIT_RESET_CTL_W0_RESET_CORE_BASE, + CPU_MAC_UNIT_RESET_CTL_W0_RESET_CORE_CPU_MAC0); + clrsetbits(&priv->cpumacu_reg->cpu_mac_unit_reset_ctl, + CPU_MAC_UNIT_RESET_CTL_W0_RESET_CORE_CPU_MAC0, 0); + } else { + /* release cpu_mac_0 */ + clrsetbits(&priv->cpumacu_reg->cpu_mac_unit_reset_ctl, + CPU_MAC_UNIT_RESET_CTL_W0_RESET_CORE_BASE, + CPU_MAC_UNIT_RESET_CTL_W0_RESET_CORE_CPU_MAC1); + clrsetbits(&priv->cpumacu_reg->cpu_mac_unit_reset_ctl, + CPU_MAC_UNIT_RESET_CTL_W0_RESET_CORE_CPU_MAC1, 0); + } + + clrsetbits(&priv->cpumacu_reg->cpu_mac_unit_ts_cfg, + 0, CPU_MAC_UNIT_TS_CFG_W0_CFG_FORCE_S_AND_NS_EN); + + spin_unlock_irq(&global_reglock); + mdelay(10); + + /* init cpu_mac */ + clrsetbits(&priv->cpumac_reg->cpu_mac_init, 0, + CPU_MAC_INIT_DONE_W0_INIT_DONE); + udelay(1); + + if (priv->interface == PHY_INTERFACE_MODE_SGMII) { + /* switch to sgmii and enable auto nego */ + val = readl(&priv->cpumac_reg->cpu_mac_sgmii_auto_neg_cfg); + val &= ~(CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_AN_ENABLE_MASK + | CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_AN_MODE_MASK); + val |= (CSA_SGMII_MD_MASK | CSA_EN); + writel(val, &priv->cpumac_reg->cpu_mac_sgmii_auto_neg_cfg); + } + + if (priv->autoneg_mode == CTCMAC_AUTONEG_DISABLE) { + clrsetbits(&priv->cpumac_reg->cpu_mac_sgmii_auto_neg_cfg, + CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_AN_ENABLE, 0); + + } else { + val = readl(&priv->cpumac_reg->cpu_mac_sgmii_auto_neg_cfg); + val &= ~CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_AN_MODE_MASK; + val |= + (priv->autoneg_mode << 2 | + CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_AN_ENABLE); + writel(val, &priv->cpumac_reg->cpu_mac_sgmii_auto_neg_cfg); + } + /* disable rx link filter */ + clrsetbits(&priv->cpumac_reg->cpu_mac_sgmii_cfg[0], + CPU_MAC_SGMII_CFG_W0_CFG_MII_RX_LINK_FILTER_EN, 0); + /* ignore tx event */ + clrsetbits(&priv->cpumac_reg->cpu_mac_sgmii_cfg[0], + 0, CPU_MAC_SGMII_CFG_W0_CFG_TX_EVEN_IGNORE); + + clrsetbits(&priv->cpumac_reg->cpu_mac_axi_cfg, + 0, CPU_MAC_AXI_CFG_W0_CFG_AXI_RD_D_WORD_SWAP_EN); + clrsetbits(&priv->cpumac_reg->cpu_mac_axi_cfg, + 0, CPU_MAC_AXI_CFG_W0_CFG_AXI_WR_D_WORD_SWAP_EN); + + /* drop over size packet */ + clrsetbits(&priv->cpumac_reg->cpu_mac_gmac_cfg[0], + 0, CPU_MAC_GMAC_CFG_W0_CFG_RX_OVERRUN_DROP_EN + | CPU_MAC_GMAC_CFG_W0_CFG_RX_OVERSIZE_DROP_EN); + + /* not strip 4B crc when send packet */ + clrsetbits(&priv->cpumac_reg->cpu_mac_gmac_cfg[2], + CPU_MAC_GMAC_CFG_W2_CFG_TX_STRIP_CRC_EN, 0); + + /* enable cut-through mode */ + clrsetbits(&priv->cpumac_reg->cpu_mac_gmac_cfg[2], + 0, CPU_MAC_GMAC_CFG_W2_CFG_TX_CUT_THROUGH_EN); + + for (i = 0; i < priv->num_tx_queues; i++) { + if (priv->tx_queue[i]->tx_ring_size > + CTCMAC_INTERNAL_RING_SIZE) { + use_extram = 1; + break; + } + } + + for (i = 0; i < priv->num_rx_queues; i++) { + if (priv->rx_queue[i]->rx_ring_size > + CTCMAC_INTERNAL_RING_SIZE) { + use_extram = 1; + break; + } + } + + if (use_extram) { + spin_lock_irq(&global_reglock); + /* enable external SRAM to store rx/tx desc, + * support max 1023*3 desc + */ + regmap_read(regmap_base, + offsetof(struct SysCtl_regs, SysMemCtl), &val); + val |= SYS_MEM_CTL_W0_CFG_RAM_MUX_EN; + regmap_write(regmap_base, + offsetof(struct SysCtl_regs, SysMemCtl), val); + spin_unlock_irq(&global_reglock); + + if (priv->index == 0) { + ctcmac_regw(&priv->cpumac_reg->cpu_mac_ext_ram_cfg[1], + CTCMAC0_EXSRAM_BASE); + } else { + ctcmac_regw(&priv->cpumac_reg->cpu_mac_ext_ram_cfg[1], + CTCMAC1_EXSRAM_BASE); + } + ctcmac_regw(&priv->cpumac_reg->cpu_mac_ext_ram_cfg[0], + CTCMAC_TX_RING_SIZE); + clrsetbits(&priv->cpumac_reg->cpu_mac_ext_ram_cfg[0], 0, + CPU_MAC_EXT_RAM_CFG_W0_CFG_EXT_RAM_EN); + } else { + /* disable external SRAM to store rx/tx desc, + * support max 64*3 desc + */ + clrsetbits(&priv->cpumac_reg->cpu_mac_ext_ram_cfg[0], + CPU_MAC_EXT_RAM_CFG_W0_CFG_EXT_RAM_EN, 0); + spin_lock_irq(&global_reglock); + + regmap_read(regmap_base, + offsetof(struct SysCtl_regs, SysMemCtl), &val); + val &= ~SYS_MEM_CTL_W0_CFG_RAM_MUX_EN; + regmap_write(regmap_base, + offsetof(struct SysCtl_regs, SysMemCtl), val); + spin_unlock_irq(&global_reglock); + } + + if (priv->int_type == CTCMAC_INT_DESC) { + val = CPU_MAC_DESC_CFG_W0_CFG_TX_DESC_ACK_EN + | (CTCMAC_DESC_INT_NUM << 16) + | (CTCMAC_DESC_INT_NUM << 8) + | (CTCMAC_DESC_INT_NUM << 0); + ctcmac_regw(&priv->cpumac_reg->cpu_mac_desc_cfg[0], val); + } else { + val = CPU_MAC_DESC_CFG_W0_CFG_TX_DESC_DONE_INTR_EOP_EN + | CPU_MAC_DESC_CFG_W0_CFG_RX_DESC_DONE_INTR_EOP_EN + | CPU_MAC_DESC_CFG_W0_CFG_TX_DESC_ACK_EN; + ctcmac_regw(&priv->cpumac_reg->cpu_mac_desc_cfg[0], val); + } + + /* clear all interrupt */ + ctcmac_regw(&priv->cpumac_reg->cpu_mac_interrupt_func[1], 0xffffffff); + ctcmac_regw(&priv->cpumac_reg->cpu_mac_interrupt_normal[1], 0xffffffff); + /* mask all interrupt */ + ctcmac_regw(&priv->cpumac_reg->cpu_mac_interrupt_func[2], 0xffffffff); + ctcmac_regw(&priv->cpumac_reg->cpu_mac_interrupt_normal[2], 0xffffffff); +} + +static int ctcmac_wait_for_linkup(struct ctcmac_private *priv) +{ + int timeout = 3000; + u32 mon = 0; + + if (priv->autoneg_mode == CTCMAC_AUTONEG_DISABLE) { + /* wait for linkup */ + while (timeout--) { + mon = readl(&priv->cpumac_reg->cpu_mac_sgmii_mon[0]); + if ((mon & 0x100) == 0x100) + break; + + mdelay(1); + } + if ((mon & 0x100) != 0x100) { + pr_err("Error! when phy link up, link status %d is not right.\n", + mon); + return -1; + } + + } else { + /* wait for sgmii auto nego complete */ + while (timeout--) { + mon = readl(&priv->cpumac_reg->cpu_mac_sgmii_mon[0]); + if ((mon & CSM_ANST_MASK) == 6) + break; + + mdelay(1); + } + + if ((mon & CSM_ANST_MASK) != 6) { + pr_err("Error! when phy link up, auto-neg status %d is not right.\n", + mon); + return -1; + } + } + + return 0; +} + +/* update cpumac speed when phy linkup speed changed */ +static noinline void ctcmac_update_link_state(struct ctcmac_private *priv, + struct phy_device *phydev) +{ + u32 cfg_rep, cfg_smp; + int speed = phydev->speed; + + if (priv->interface != PHY_INTERFACE_MODE_SGMII) + return; + + if (netif_msg_link(priv)) + netdev_dbg(priv->ndev, "link up speed is %d\n", speed); + + if (phydev->link) { + cfg_rep = readl(&priv->cpumac_reg->cpu_mac_sgmii_cfg[0]); + cfg_smp = readl(&priv->cpumac_reg->cpu_mac_sgmii_cfg[1]); + cfg_rep &= ~CSC_REP_MASK; + cfg_smp &= ~CSC_SMP_MASK; + if (speed == 1000) { + cfg_rep |= CSC_1000M; + cfg_smp |= CSC_1000M; + } else if (speed == 100) { + cfg_rep |= CSC_100M; + cfg_smp |= CSC_100M; + } else if (speed == 10) { + cfg_rep |= CSC_10M; + cfg_smp |= CSC_10M; + } else { + return; + } + writel(cfg_rep, &priv->cpumac_reg->cpu_mac_sgmii_cfg[0]); + writel(cfg_smp, &priv->cpumac_reg->cpu_mac_sgmii_cfg[1]); + + ctcmac_wait_for_linkup(priv); + + if (!priv->oldlink) + priv->oldlink = 1; + + } else { + priv->oldlink = 0; + priv->oldspeed = 0; + priv->oldduplex = -1; + } +} + +static void adjust_link(struct net_device *dev) +{ + struct ctcmac_private *priv = netdev_priv(dev); + struct phy_device *phydev = dev->phydev; + + if (unlikely(phydev->link != priv->oldlink || + (phydev->link && (phydev->duplex != priv->oldduplex || + phydev->speed != priv->oldspeed)))) + ctcmac_update_link_state(priv, phydev); +} + +/* Initializes driver's PHY state, and attaches to the PHY. + * Returns 0 on success. + */ +static int ctcmac_init_phy(struct net_device *dev) +{ + int err; + struct ctcmac_private *priv = netdev_priv(dev); + phy_interface_t interface; + struct phy_device *phydev; + + priv->oldlink = 0; + priv->oldspeed = 0; + priv->oldduplex = -1; + + interface = priv->interface; + + phydev = of_phy_connect(dev, priv->phy_node, &adjust_link, 0, + interface); + if (!phydev) { + dev_err(&dev->dev, "could not attach to PHY\n"); + return -ENODEV; + } + if (of_phy_is_fixed_link(priv->phy_node)) { + err = fixed_phy_set_link_update(dev->phydev, + ctcmac_fixed_phy_link_update); + if (err) + dev_err(&priv->ndev->dev, "Set link update fail!\n"); + } + + /* Remove any features not supported by the controller */ + phydev->supported &= priv->supported; + phydev->advertising = phydev->supported; + + return 0; +} + +static irqreturn_t ctcmac_receive(int irq, struct ctcmac_private *priv) +{ + unsigned long flags; + + if (likely(napi_schedule_prep(&priv->napi_rx))) { + /* disable interrupt */ + spin_lock_irqsave(&priv->reglock, flags); + writel(CTCMAC_NOR_RX0_D | CTCMAC_NOR_RX1_D, + &priv->cpumac_reg->cpu_mac_interrupt_func[2]); + spin_unlock_irqrestore(&priv->reglock, flags); + __napi_schedule(&priv->napi_rx); + } else { + /* clear interrupt */ + writel(CTCMAC_NOR_RX0_D | CTCMAC_NOR_RX1_D, + &priv->cpumac_reg->cpu_mac_interrupt_func[1]); + } + + return IRQ_HANDLED; +} + +static irqreturn_t ctcmac_transmit(int irq, struct ctcmac_private *priv) +{ + unsigned long flags; + + if (likely(napi_schedule_prep(&priv->napi_tx))) { + /* disable interrupt */ + spin_lock_irqsave(&priv->reglock, flags); + writel(CTCMAC_NOR_TX_D, + &priv->cpumac_reg->cpu_mac_interrupt_func[2]); + spin_unlock_irqrestore(&priv->reglock, flags); + __napi_schedule(&priv->napi_tx); + + } else { + /* clear interrupt */ + writel(CTCMAC_NOR_TX_D, + &priv->cpumac_reg->cpu_mac_interrupt_func[1]); + } + + return IRQ_HANDLED; +} + +static irqreturn_t ctcmac_func(int irq, void *data) +{ + u32 event, stat, mask; + struct ctcmac_private *priv = (struct ctcmac_private *)data; + + stat = ctcmac_regr(&priv->cpumac_reg->cpu_mac_interrupt_func[0]); + mask = ctcmac_regr(&priv->cpumac_reg->cpu_mac_interrupt_func[2]); + event = stat & ~mask; + + if (netif_msg_intr(priv)) { + netdev_dbg(priv->ndev, + "function interrupt stat 0x%x mask 0x%x\n", stat, + mask); + } + if ((event & CTCMAC_NOR_RX0_D) || (event & CTCMAC_NOR_RX1_D)) + ctcmac_receive(irq, priv); + + if (event & CTCMAC_NOR_TX_D) + ctcmac_transmit(irq, priv); + + return IRQ_HANDLED; +} + +/* not used */ +static irqreturn_t ctcmac_normal(int irq, void *data) //TODO by liuht +{ + u32 stat, mask; + struct ctcmac_private *priv = (struct ctcmac_private *)data; + + stat = ctcmac_regr(&priv->cpumac_reg->cpu_mac_interrupt_func[0]); + mask = ctcmac_regr(&priv->cpumac_reg->cpu_mac_interrupt_func[2]); + + if (netif_msg_intr(priv)) { + netdev_dbg(priv->ndev, "normal interrupt stat 0x%x mask 0x%x\n", + stat, mask); + } + + return IRQ_HANDLED; +} + +static int ctcmac_request_irq(struct ctcmac_private *priv) +{ + int err = 0; + + err = request_irq(priv->irqinfo[CTCMAC_NORMAL].irq, ctcmac_normal, 0, + priv->irqinfo[CTCMAC_NORMAL].name, priv); + if (err < 0) + free_irq(priv->irqinfo[CTCMAC_NORMAL].irq, priv); + enable_irq_wake(priv->irqinfo[CTCMAC_NORMAL].irq); + + err = request_irq(priv->irqinfo[CTCMAC_FUNC].irq, ctcmac_func, 0, + priv->irqinfo[CTCMAC_FUNC].name, priv); + if (err < 0) + free_irq(priv->irqinfo[CTCMAC_FUNC].irq, priv); + enable_irq_wake(priv->irqinfo[CTCMAC_FUNC].irq); + + return err; +} + +static void ctcmac_free_irq(struct ctcmac_private *priv) +{ + free_irq(priv->irqinfo[CTCMAC_NORMAL].irq, priv); + free_irq(priv->irqinfo[CTCMAC_FUNC].irq, priv); +} + +static bool ctcmac_new_page(struct ctcmac_priv_rx_q *rxq, + struct ctcmac_rx_buff *rxb) +{ + struct page *page; + dma_addr_t addr; + + page = dev_alloc_page(); + if (unlikely(!page)) + return false; + + addr = dma_map_page(rxq->dev, page, 0, PAGE_SIZE, DMA_FROM_DEVICE); + if (unlikely(dma_mapping_error(rxq->dev, addr))) { + __free_page(page); + + return false; + } + + rxb->dma = addr; + rxb->page = page; + rxb->page_offset = 0; + + return true; +} + +static void ctcmac_fill_rxbd(struct ctcmac_private *priv, + struct ctcmac_rx_buff *rxb, int qidx) +{ + u32 desc_cfg_low, desc_cfg_high; + dma_addr_t bufaddr = rxb->dma + rxb->page_offset; + + /* DDR base address is 0 for cpu_mac, but is 0x80000000 for CPU */ + desc_cfg_low = + (bufaddr - CTC_DDR_BASE) & CPU_MAC_DESC_INTF_W0_DESC_ADDR_31_0_MASK; + /* CPU_MAC_DESC_INTF_W1_DESC_SIZE:bit(8) */ + desc_cfg_high = (CTCMAC_RXB_SIZE << 8) | + (((bufaddr - + CTC_DDR_BASE) >> 32) & + CPU_MAC_DESC_INTF_W1_DESC_ADDR_39_32_MASK); + + spin_lock_irq(&priv->reglock); + if (qidx) { + ctcmac_regw(&priv->cpumac_mem->cpu_mac_desc_intf_1[0], + desc_cfg_low); + /* barrier */ + smp_mb__before_atomic(); + ctcmac_regw(&priv->cpumac_mem->cpu_mac_desc_intf_1[1], + desc_cfg_high); + + } else { + ctcmac_regw(&priv->cpumac_mem->cpu_mac_desc_intf_0[0], + desc_cfg_low); + /* barrier */ + smp_mb__before_atomic(); + ctcmac_regw(&priv->cpumac_mem->cpu_mac_desc_intf_0[1], + desc_cfg_high); + } + + spin_unlock_irq(&priv->reglock); +} + +static void ctcmac_fill_txbd(struct ctcmac_private *priv, + struct ctcmac_desc_cfg *txdesc) +{ + u32 desc_cfg_low, desc_cfg_high; + + desc_cfg_low = txdesc->addr_low; + /* CPU_MAC_DESC_INTF_W1_DESC_SIZE:bit(8) */ + /* CPU_MAC_DESC_INTF_W1_DESC_SOP:bit(22) */ + /* CPU_MAC_DESC_INTF_W1_DESC_EOP:bit(23) */ + desc_cfg_high = txdesc->addr_high | + (txdesc->size << 8) | (txdesc->sop << 22) | (txdesc->eop << 23); + + spin_lock_irq(&priv->reglock); + ctcmac_regw(&priv->cpumac_mem->cpu_mac_desc_intf_2[0], desc_cfg_low); + /* barrier */ + smp_mb__before_atomic(); + ctcmac_regw(&priv->cpumac_mem->cpu_mac_desc_intf_2[1], desc_cfg_high); + + spin_unlock_irq(&priv->reglock); +} + +/* reclaim tx desc */ +static void ctcmac_get_txbd(struct ctcmac_private *priv) +{ + u32 lstatus; + + spin_lock_irq(&priv->reglock); + lstatus = ctcmac_regr(&priv->cpumac_mem->cpu_mac_desc_intf_2[0]); + /* barrier */ + smp_mb__before_atomic(); + lstatus = ctcmac_regr(&priv->cpumac_mem->cpu_mac_desc_intf_2[1]); + spin_unlock_irq(&priv->reglock); +} + +/* reclaim rx desc */ +static void ctcmac_get_rxbd(struct ctcmac_private *priv, u32 *lstatus, + int qidx) +{ + spin_lock_irq(&priv->reglock); + if (qidx) { + ctcmac_regr(&priv->cpumac_mem->cpu_mac_desc_intf_1[0]); + *lstatus = + ctcmac_regr(&priv->cpumac_mem->cpu_mac_desc_intf_1[1]); + } else { + ctcmac_regr(&priv->cpumac_mem->cpu_mac_desc_intf_0[0]); + *lstatus = + ctcmac_regr(&priv->cpumac_mem->cpu_mac_desc_intf_0[1]); + } + /* barrier */ + smp_mb__before_atomic(); + + spin_unlock_irq(&priv->reglock); +} + +/* alloc rx buffer for rx desc */ +static void ctcmac_alloc_rx_buffs(struct ctcmac_priv_rx_q *rx_queue, + int alloc_cnt) +{ + int i, j; + int qidx = rx_queue->qindex; + struct ctcmac_rx_buff *rxb; + struct net_device *ndev = rx_queue->ndev; + struct ctcmac_private *priv = netdev_priv(ndev); + + i = rx_queue->next_to_use; + j = rx_queue->next_to_alloc; + rxb = &rx_queue->rx_buff[i]; + + while (alloc_cnt--) { + /* if rx buffer is unmapped, alloc new pages */ + if (unlikely(!rxb->page)) { + if (unlikely(!ctcmac_new_page(rx_queue, rxb))) + break; + if (unlikely(++j == rx_queue->rx_ring_size)) + j = 0; + } + + /* fill rx desc */ + ctcmac_fill_rxbd(priv, rxb, qidx); + rxb++; + + if (unlikely(++i == rx_queue->rx_ring_size)) { + i = 0; + rxb = rx_queue->rx_buff; + } + } + + rx_queue->next_to_use = i; + rx_queue->next_to_alloc = j; +} + +static void ctcmac_alloc_one_rx_buffs(struct ctcmac_priv_rx_q *rx_queue) +{ + int i, j; + int qidx = rx_queue->qindex; + struct ctcmac_rx_buff *rxb; + struct net_device *ndev = rx_queue->ndev; + struct ctcmac_private *priv = netdev_priv(ndev); + + i = rx_queue->next_to_use; + j = rx_queue->next_to_alloc; + rxb = &rx_queue->rx_buff[i]; + + if (unlikely(!rxb->page)) { + if (unlikely(!ctcmac_new_page(rx_queue, rxb))) + return; + if (unlikely(++j == rx_queue->rx_ring_size)) + j = 0; + } + + if (unlikely(++i == rx_queue->rx_ring_size)) + i = 0; + + rx_queue->next_to_use = i; + rx_queue->next_to_alloc = j; + + /* fill rx desc */ + ctcmac_fill_rxbd(priv, rxb, qidx); +} + +static noinline int ctcmac_clean_rx_ring(struct ctcmac_priv_rx_q *rx_queue, + int rx_work_limit) +{ + struct net_device *ndev = rx_queue->ndev; + struct ctcmac_private *priv = netdev_priv(ndev); + int i, howmany = 0; + struct sk_buff *skb = rx_queue->skb; + int cleaned_cnt = ctcmac_rxbd_unused(rx_queue); + unsigned int total_bytes = 0, total_pkts = 0; + int qidx = rx_queue->qindex; + u32 alloc_new; + int budget = rx_work_limit; + + /* Get the first full descriptor */ + i = rx_queue->next_to_clean; + + while (rx_work_limit--) { + u32 lstatus; + + if (!rx_queue->pps_limit) { + if (cleaned_cnt >= CTCMAC_RX_BUFF_ALLOC) { + ctcmac_alloc_rx_buffs(rx_queue, cleaned_cnt); + cleaned_cnt = 0; + } + } else { + alloc_new = rx_queue->token / CTCMAC_TOKEN_PER_PKT; + if (cleaned_cnt >= CTCMAC_RX_BUFF_ALLOC && alloc_new) { + alloc_new = min_t(int, cleaned_cnt, + (int)alloc_new); + ctcmac_alloc_rx_buffs(rx_queue, alloc_new); + rx_queue->token -= + CTCMAC_TOKEN_PER_PKT * alloc_new; + cleaned_cnt -= alloc_new; + } + } + + if (ctcmac_rxbd_recycle(priv, qidx) <= 0) + break; + + ctcmac_get_rxbd(priv, &lstatus, qidx); + + /* fetch next to clean buffer from the ring */ + skb = ctcmac_get_next_rxbuff(rx_queue, lstatus, skb); + if (unlikely(!skb)) + break; + + cleaned_cnt++; + howmany++; + + if (unlikely(++i == rx_queue->rx_ring_size)) + i = 0; + + rx_queue->next_to_clean = i; + + if (netif_msg_rx_status(priv)) { + netdev_dbg(priv->ndev, + "%s rxbuf allocted %d used %d clean %d\n", + ndev->name, rx_queue->next_to_alloc, + rx_queue->next_to_use, + rx_queue->next_to_clean); + } + + /* fetch next buffer if not the last in frame */ + if (!(lstatus & CPU_MAC_DESC_INTF_W1_DESC_EOP)) { + if (rx_queue->pps_limit) + rx_queue->token += CTCMAC_TOKEN_PER_PKT; + continue; + } + + if (unlikely(lstatus & CPU_MAC_DESC_INTF_W1_DESC_ERR)) { + /* discard faulty buffer */ + dev_kfree_skb(skb); + skb = NULL; + rx_queue->stats.rx_dropped++; + if (netif_msg_rx_err(priv)) { + netdev_dbg(priv->ndev, + "%s: Error with rx desc status 0x%x\n", + ndev->name, lstatus); + } + continue; + } + + skb_record_rx_queue(skb, rx_queue->qindex); + ctcmac_process_frame(ndev, skb); + if (!(ndev->flags & IFF_PROMISC) && + skb->pkt_type == PACKET_OTHERHOST) { + /* discard */ + dev_kfree_skb(skb); + skb = NULL; + rx_queue->stats.rx_dropped++; + continue; + } + /* Increment the number of packets */ + total_pkts++; + total_bytes += skb->len + ETH_HLEN; + /* Send the packet up the stack */ + napi_gro_receive(&priv->napi_rx, skb); + + skb = NULL; + } + + /* Store incomplete frames for completion */ + rx_queue->skb = skb; + + rx_queue->stats.rx_packets += total_pkts; + rx_queue->stats.rx_bytes += total_bytes; + + if (!rx_queue->pps_limit && cleaned_cnt) + ctcmac_alloc_rx_buffs(rx_queue, cleaned_cnt); + + if (rx_queue->pps_limit && rx_queue->skb) + return budget; + + return howmany; +} + +static void ctcmac_clean_tx_ring(struct ctcmac_priv_tx_q *tx_queue) +{ + u16 next_to_clean; + int tqi = tx_queue->qindex; + struct sk_buff *skb; + struct netdev_queue *txq; + struct ctcmac_tx_buff *tx_buff; + struct net_device *dev = tx_queue->dev; + struct ctcmac_private *priv = netdev_priv(dev); + + txq = netdev_get_tx_queue(dev, tqi); + next_to_clean = tx_queue->next_to_clean; + while (ctcmac_txbd_used_untreated(priv)) { + ctcmac_get_txbd(priv); + skb = tx_queue->tx_skbuff[next_to_clean]; + dev_kfree_skb_any(skb); + tx_queue->tx_skbuff[next_to_clean] = NULL; + tx_buff = &tx_queue->tx_buff[next_to_clean]; + dma_unmap_single(priv->dev, tx_buff->dma, + tx_buff->len, DMA_TO_DEVICE); + if (tx_buff->alloc) + kfree(tx_buff->vaddr); + if (netif_msg_tx_queued(priv)) { + netdev_dbg(priv->ndev, "%s: clean skbuff id %d\n", + priv->ndev->name, tx_queue->next_to_clean); + } + if ((next_to_clean + 1) >= tx_queue->tx_ring_size) + next_to_clean = 0; + else + next_to_clean++; + + spin_lock(&tx_queue->txlock); + tx_queue->num_txbdfree++; + spin_unlock(&tx_queue->txlock); + } + + /* If we freed a buffer, we can restart transmission, if necessary */ + if (tx_queue->num_txbdfree && + netif_tx_queue_stopped(txq) && + !(test_bit(CTCMAC_DOWN, &priv->state))) { + netif_wake_subqueue(priv->ndev, tqi); + } + + tx_queue->next_to_clean = next_to_clean; +} + +static int ctcmac_poll_rx_sq(struct napi_struct *napi, int budget) +{ + int work_done = 0; + int rx_work_limit; + struct ctcmac_private *priv = + container_of(napi, struct ctcmac_private, napi_rx); + struct ctcmac_priv_rx_q *rxq0 = NULL, *rxq1 = NULL; + + /* clear interrupt */ + writel(CTCMAC_NOR_RX0_D | CTCMAC_NOR_RX1_D, + &priv->cpumac_reg->cpu_mac_interrupt_func[1]); + + rx_work_limit = budget; + rxq0 = priv->rx_queue[0]; + rxq1 = priv->rx_queue[1]; + + work_done += ctcmac_clean_rx_ring(rxq1, rx_work_limit); + rx_work_limit -= work_done; + work_done += ctcmac_clean_rx_ring(rxq0, rx_work_limit); + rx_work_limit -= work_done; + + rxq0->rx_trigger = 0; + rxq1->rx_trigger = 0; + if (work_done < budget) { + napi_complete(napi); + if (!ctcmac_rxbd_usable(priv, 0) && + !ctcmac_rxbd_recycle(priv, 0)) + rxq0->rx_trigger = 1; + + if (!ctcmac_rxbd_usable(priv, 1) && + !ctcmac_rxbd_recycle(priv, 1)) + rxq1->rx_trigger = 1; + + spin_lock_irq(&priv->reglock); + /* enable interrupt */ + writel(CTCMAC_NOR_RX0_D | CTCMAC_NOR_RX1_D, + &priv->cpumac_reg->cpu_mac_interrupt_func[3]); + spin_unlock_irq(&priv->reglock); + } + + return work_done; +} + +static int ctcmac_poll_tx_sq(struct napi_struct *napi, int budget) +{ + struct ctcmac_private *priv = + container_of(napi, struct ctcmac_private, napi_tx); + struct ctcmac_priv_tx_q *tx_queue = priv->tx_queue[0]; + + /* clear interrupt */ + writel(CTCMAC_NOR_TX_D, &priv->cpumac_reg->cpu_mac_interrupt_func[1]); + + ctcmac_clean_tx_ring(tx_queue); + + napi_complete(napi); + /* enable interrupt */ + spin_lock_irq(&priv->reglock); + writel(CTCMAC_NOR_TX_D, &priv->cpumac_reg->cpu_mac_interrupt_func[3]); + spin_unlock_irq(&priv->reglock); + + return 0; +} + +static void ctcmac_free_rx_resources(struct ctcmac_private *priv) +{ + int i, j; + struct ctcmac_priv_rx_q *rx_queue = NULL; + + for (i = 0; i < priv->num_rx_queues; i++) { + rx_queue = priv->rx_queue[i]; + if (rx_queue->skb) + dev_kfree_skb(rx_queue->skb); + + for (j = 0; j < rx_queue->rx_ring_size; j++) { + struct ctcmac_rx_buff *rxb = &rx_queue->rx_buff[j]; + + if (!rxb->page) + continue; + dma_unmap_single(rx_queue->dev, rxb->dma, + PAGE_SIZE, DMA_TO_DEVICE); + __free_page(rxb->page); + } + kfree(rx_queue->rx_buff); + rx_queue->rx_buff = NULL; + } +} + +static int ctcmac_init_rx_resources(struct net_device *ndev) +{ + int i; + struct ctcmac_private *priv = netdev_priv(ndev); + struct device *dev = priv->dev; + struct ctcmac_priv_rx_q *rx_queue = NULL; + + for (i = 0; i < priv->num_rx_queues; i++) { + rx_queue = priv->rx_queue[i]; + rx_queue->ndev = ndev; + rx_queue->dev = dev; + rx_queue->next_to_clean = 0; + rx_queue->next_to_use = 0; + rx_queue->next_to_alloc = 0; + rx_queue->skb = NULL; + rx_queue->rx_trigger = 0; + rx_queue->rx_buff = kcalloc(rx_queue->rx_ring_size, + sizeof(*rx_queue->rx_buff), + GFP_KERNEL); + if (!rx_queue->rx_buff) + goto cleanup; + + ctcmac_alloc_rx_buffs(rx_queue, ctcmac_rxbd_unused(rx_queue)); + } + + return 0; + +cleanup: + ctcmac_free_rx_resources(priv); + + return -1; +} + +static void ctcmac_free_tx_resources(struct ctcmac_private *priv) +{ + int i; + struct ctcmac_priv_tx_q *tx_queue = NULL; + + for (i = 0; i < priv->num_tx_queues; i++) { + struct netdev_queue *txq; + + tx_queue = priv->tx_queue[i]; + txq = netdev_get_tx_queue(tx_queue->dev, tx_queue->qindex); + + kfree(tx_queue->tx_skbuff); + tx_queue->tx_skbuff = NULL; + } +} + +static int ctcmac_init_tx_resources(struct net_device *ndev) +{ + int i; + struct ctcmac_private *priv = netdev_priv(ndev); + struct ctcmac_priv_tx_q *tx_queue = NULL; + + for (i = 0; i < priv->num_tx_queues; i++) { + tx_queue = priv->tx_queue[i]; + tx_queue->num_txbdfree = tx_queue->tx_ring_size; + tx_queue->next_to_clean = 0; + tx_queue->next_to_alloc = 0; + tx_queue->dev = ndev; + tx_queue->tx_skbuff = + kmalloc_array(tx_queue->tx_ring_size, + sizeof(*tx_queue->tx_skbuff), GFP_KERNEL); + + if (!tx_queue->tx_skbuff) + goto cleanup; + } + + return 0; + +cleanup: + ctcmac_free_tx_resources(priv); + + return -1; +} + +static int ctcmac_alloc_skb_resources(struct net_device *ndev) +{ + if (ctcmac_init_rx_resources(ndev)) + return -1; + if (ctcmac_init_tx_resources(ndev)) + return -1; + + return 0; +} + +static int ctcmac_free_skb_resources(struct ctcmac_private *priv) +{ + ctcmac_free_rx_resources(priv); + ctcmac_free_tx_resources(priv); + + return 0; +} + +static void cpumac_start(struct ctcmac_private *priv) +{ + /* 1. enable rx/tx interrupt */ + writel(CTCMAC_NOR_TX_D | CTCMAC_NOR_RX0_D | CTCMAC_NOR_RX1_D, + &priv->cpumac_reg->cpu_mac_interrupt_func[3]); + /* 2. enable rx/tx */ + clrsetbits(&priv->cpumac_reg->cpu_mac_reset, + CPU_MAC_RESET_W0_SOFT_RST_TX, + 0); + clrsetbits(&priv->cpumac_reg->cpu_mac_reset, + CPU_MAC_RESET_W0_SOFT_RST_RX, + 0); + + netif_trans_update(priv->ndev); /* prevent tx timeout */ +} + +static void cpumac_halt(struct ctcmac_private *priv) +{ + /* 1. disable rx/tx interrupt */ + ctcmac_regw(&priv->cpumac_reg->cpu_mac_interrupt_func[2], 0xffffffff); + ctcmac_regw(&priv->cpumac_reg->cpu_mac_interrupt_normal[2], 0xffffffff); + /* 2. disable rx/tx */ + clrsetbits(&priv->cpumac_reg->cpu_mac_reset, 0, + CPU_MAC_RESET_W0_SOFT_RST_TX); + clrsetbits(&priv->cpumac_reg->cpu_mac_reset, 0, + CPU_MAC_RESET_W0_SOFT_RST_RX); +} + +static void ctcmac_token_timer(struct timer_list *t) +{ + struct ctcmac_private *priv = from_timer(priv, t, token_timer); + struct ctcmac_priv_rx_q *rxq0, *rxq1; + + mod_timer(&priv->token_timer, jiffies + HZ / 10 - 1); + rxq0 = priv->rx_queue[0]; + rxq1 = priv->rx_queue[1]; + rxq0->token = min(rxq0->token + rxq0->pps_limit, rxq0->token_max); + rxq1->token = min(rxq1->token + rxq1->pps_limit, rxq1->token_max); + + if (rxq0->rx_trigger == 1 && (rxq0->token / CTCMAC_TOKEN_PER_PKT)) { + rxq0->rx_trigger = 0; + rxq0->token -= CTCMAC_TOKEN_PER_PKT; + ctcmac_alloc_one_rx_buffs(rxq0); + } + + if (rxq1->rx_trigger == 1 && (rxq1->token / CTCMAC_TOKEN_PER_PKT)) { + rxq1->rx_trigger = 0; + rxq1->token -= CTCMAC_TOKEN_PER_PKT; + ctcmac_alloc_one_rx_buffs(rxq1); + } +} + +static ssize_t rxq0_pps_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ctcmac_private *priv = + (struct ctcmac_private *)dev_get_drvdata(dev); + + return sprintf(buf, "%d\n", priv->rx_queue[0]->pps_limit); +} + +static ssize_t rxq0_pps_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + u32 rq0_pps; + struct ctcmac_private *priv = + (struct ctcmac_private *)dev_get_drvdata(dev); + + if (kstrtou32(buf, 0, &rq0_pps)) { + dev_err(&priv->ndev->dev, "Invalid rx queue0 pps!\n"); + return -1; + } + priv->rx_queue[0]->pps_limit = rq0_pps; + + return count; +} + +static ssize_t rxq1_pps_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ctcmac_private *priv = + (struct ctcmac_private *)dev_get_drvdata(dev); + + return sprintf(buf, "%d\n", priv->rx_queue[1]->pps_limit); +} + +static ssize_t rxq1_pps_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + u32 rq1_pps; + struct ctcmac_private *priv = + (struct ctcmac_private *)dev_get_drvdata(dev); + + if (kstrtou32(buf, 0, &rq1_pps)) { + dev_err(&priv->ndev->dev, "Invalid rx queue0 pps!\n"); + return -1; + } + priv->rx_queue[1]->pps_limit = rq1_pps; + + return count; +} + +static DEVICE_ATTR(rxq0_pps, S_IRUGO | S_IWUSR, rxq0_pps_show, rxq0_pps_store); +static DEVICE_ATTR(rxq1_pps, S_IRUGO | S_IWUSR, rxq1_pps_show, rxq1_pps_store); + +static void ctcmac_pps_init(struct ctcmac_private *priv) +{ + struct ctcmac_priv_rx_q *rxq0, *rxq1; + + rxq0 = priv->rx_queue[0]; + rxq1 = priv->rx_queue[1]; + + if (device_create_file(&priv->ndev->dev, &dev_attr_rxq0_pps) < 0) { + dev_err(&priv->ndev->dev, "create pps limit node fail\n"); + return; + } + if (device_create_file(&priv->ndev->dev, &dev_attr_rxq1_pps) < 0) { + dev_err(&priv->ndev->dev, "create pps limit node fail\n"); + return; + } + + rxq0->pps_limit = 0; + rxq1->pps_limit = 0; +} + +static void ctcmac_pps_disable(struct ctcmac_private *priv) +{ + priv->rx_queue[0]->pps_limit = 0; + priv->rx_queue[1]->pps_limit = 0; + del_timer(&priv->token_timer); +} + +static void ctcmac_pps_cfg(struct ctcmac_private *priv) +{ + struct ctcmac_priv_rx_q *rxq0, *rxq1; + + rxq0 = priv->rx_queue[0]; + rxq1 = priv->rx_queue[1]; + + rxq0->token = 0; + rxq0->token_max = rxq0->pps_limit * CTCMAC_TOKEN_PER_PKT; + rxq0->rx_trigger = 0; + rxq1->token = 0; + rxq1->token_max = rxq1->pps_limit * CTCMAC_TOKEN_PER_PKT; + rxq1->rx_trigger = 0; + if (rxq0->pps_limit || rxq1->pps_limit) { + timer_setup(&priv->token_timer, ctcmac_token_timer, 0); + priv->token_timer.expires = jiffies + HZ / 10; + add_timer(&priv->token_timer); + /* when enable pps ratelimit, must use desc done interrupt */ + priv->int_type = CTCMAC_INT_DESC; + } else { + priv->int_type = CTCMAC_INT_PACKET; + } +} + +static int ctcmac_enet_open(struct net_device *dev) +{ + struct ctcmac_private *priv = netdev_priv(dev); + int err; + + ctcmac_pps_cfg(priv); + + err = ctcmac_init_phy(dev); + if (err) + return err; + + err = ctcmac_request_irq(priv); + if (err) + return err; + + err = startup_ctcmac(dev); + if (err) + return err; + + return 0; +} + +static struct ctcmac_tx_buff *skb_to_txbuff(struct ctcmac_private *priv, + struct sk_buff *skb) +{ + u64 addr, offset; + int frag_index, nr_frags, rq; + skb_frag_t *frag; + struct ctcmac_tx_buff *tx_buff; + struct ctcmac_priv_tx_q *tx_queue = NULL; + + nr_frags = skb_shinfo(skb)->nr_frags; + rq = skb->queue_mapping; + tx_queue = priv->tx_queue[rq]; + + tx_buff = &tx_queue->tx_buff[tx_queue->next_to_alloc]; + addr = (u64)skb->data; + if (!nr_frags && + ((addr & PAGE_MASK) == ((addr + skb_headlen(skb)) & PAGE_MASK))) { + tx_buff->alloc = 0; + tx_buff->vaddr = skb->data; + tx_buff->len = skb_headlen(skb); + tx_buff->dma = + dma_map_single(priv->dev, skb->data, skb_headlen(skb), + DMA_TO_DEVICE); + tx_buff->offset = 0; + + } else { + int alloc_size; + + alloc_size = ALIGN(skb->len, BUF_ALIGNMENT); + tx_buff->alloc = 1; + tx_buff->len = skb->len; + tx_buff->vaddr = kmalloc(alloc_size, GFP_KERNEL); + offset = + (BUF_ALIGNMENT - + (((u64)tx_buff->vaddr) & (BUF_ALIGNMENT - 1))); + if (offset == BUF_ALIGNMENT) + offset = 0; + tx_buff->offset = offset; + memcpy(tx_buff->vaddr + offset, skb->data, skb_headlen(skb)); + offset += skb_headlen(skb); + for (frag_index = 0; frag_index < nr_frags; frag_index++) { + frag = &skb_shinfo(skb)->frags[frag_index]; + memcpy(tx_buff->vaddr + offset, frag, + skb_frag_size(frag)); + offset += skb_frag_size(frag); + } + + tx_buff->dma = + dma_map_single(priv->dev, tx_buff->vaddr, tx_buff->len, + DMA_TO_DEVICE); + } + return tx_buff; +} + +static int ctcmac_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + int rq = 0; + unsigned int bytes_sent; + struct netdev_queue *txq; + struct ctcmac_desc_cfg tx_desc; + struct ctcmac_tx_buff *tx_buff; + struct ctcmac_priv_tx_q *tx_queue = NULL; + struct ctcmac_private *priv = netdev_priv(dev); + + rq = skb->queue_mapping; + tx_queue = priv->tx_queue[rq]; + txq = netdev_get_tx_queue(dev, rq); + + /* check if there is space to queue this packet */ + if (tx_queue->num_txbdfree <= 0) { + if (netif_msg_tx_err(priv)) { + netdev_dbg(priv->ndev, + "%s: no space left before send pkt!\n", + priv->ndev->name); + } + /* no space, stop the queue */ + netif_tx_stop_queue(txq); + dev->stats.tx_fifo_errors++; + return NETDEV_TX_BUSY; + } + + /* Update transmit stats */ + bytes_sent = skb->len; + tx_queue->stats.tx_bytes += bytes_sent; + tx_queue->stats.tx_packets++; + + tx_buff = skb_to_txbuff(priv, skb); + tx_queue->tx_skbuff[tx_queue->next_to_alloc] = skb; + tx_desc.sop = 1; + tx_desc.eop = 1; + tx_desc.size = tx_buff->len; + tx_desc.addr_low = (tx_buff->dma + tx_buff->offset - CTC_DDR_BASE) + & CPU_MAC_DESC_INTF_W0_DESC_ADDR_31_0_MASK; + tx_desc.addr_high = + ((tx_buff->dma + tx_buff->offset - CTC_DDR_BASE) >> 32) + & CPU_MAC_DESC_INTF_W1_DESC_ADDR_39_32_MASK; + ctcmac_fill_txbd(priv, &tx_desc); + + if (netif_msg_tx_queued(priv)) { + netdev_dbg(priv->ndev, "%s: alloc skbuff id %d\n", + priv->ndev->name, tx_queue->next_to_alloc); + } + + if (tx_queue->next_to_alloc >= tx_queue->tx_ring_size - 1) + tx_queue->next_to_alloc = 0; + else + tx_queue->next_to_alloc++; + + /* We can work in parallel with 872(), except + * when modifying num_txbdfree. Note that we didn't grab the lock + * when we were reading the num_txbdfree and checking for available + * space, that's because outside of this function it can only grow. + */ + spin_lock_bh(&tx_queue->txlock); + /* reduce TxBD free count */ + tx_queue->num_txbdfree--; + spin_unlock_bh(&tx_queue->txlock); + + /* If the next BD still needs to be cleaned up, then the bds + * are full. We need to tell the kernel to stop sending us stuff. + */ + if (!tx_queue->num_txbdfree) { + netif_tx_stop_queue(txq); + if (netif_msg_tx_err(priv)) { + netdev_dbg(dev, "%s: no space left before send pkt!\n", + priv->ndev->name); + } + dev->stats.tx_fifo_errors++; + } + + return NETDEV_TX_OK; +} + +static int ctcmac_change_mtu(struct net_device *dev, int new_mtu) +{ + struct ctcmac_private *priv = netdev_priv(dev); + int frame_size = new_mtu + ETH_HLEN; + + if (frame_size < 64 || frame_size > CTCMAC_JUMBO_FRAME_SIZE) + return -EINVAL; + + while (test_and_set_bit_lock(CTCMAC_RESETTING, &priv->state)) + cpu_relax(); + + if (dev->flags & IFF_UP) + stop_ctcmac(dev); + + dev->mtu = new_mtu; + + if (dev->flags & IFF_UP) + startup_ctcmac(dev); + + clear_bit_unlock(CTCMAC_RESETTING, &priv->state); + + return 0; +} + +static int ctcmac_set_features(struct net_device *dev, + netdev_features_t features) +{ + return 0; +} + +/* Stops the kernel queue, and halts the controller */ +static int ctcmac_close(struct net_device *dev) +{ + struct ctcmac_private *priv = netdev_priv(dev); + + ctcmac_pps_disable(priv); + cancel_work_sync(&priv->reset_task); + stop_ctcmac(dev); + + /* Disconnect from the PHY */ + phy_disconnect(dev->phydev); + + ctcmac_free_irq(priv); + + return 0; +} + +static void ctcmac_set_multi(struct net_device *dev) +{ +} + +static void ctcmac_timeout(struct net_device *dev) +{ + struct ctcmac_private *priv = netdev_priv(dev); + + dev->stats.tx_errors++; + schedule_work(&priv->reset_task); +} + +static int ctcmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + struct phy_device *phydev = dev->phydev; + + if (!netif_running(dev)) + return -EINVAL; + + if (!phydev) + return -ENODEV; + + return phy_mii_ioctl(phydev, rq, cmd); +} + +static struct net_device_stats *ctcmac_get_stats(struct net_device *dev) +{ + int qidx; + unsigned long rx_packets = 0, rx_bytes = 0, rx_dropped = 0; + unsigned long tx_packets = 0, tx_bytes = 0; + struct ctcmac_private *priv = netdev_priv(dev); + + for (qidx = 0; qidx < priv->num_rx_queues; qidx++) { + if (!priv->rx_queue[qidx]) + return &dev->stats; + rx_packets += priv->rx_queue[qidx]->stats.rx_packets; + rx_bytes += priv->rx_queue[qidx]->stats.rx_bytes; + rx_dropped += priv->rx_queue[qidx]->stats.rx_dropped; + } + + if (!priv->tx_queue[0]) + return &dev->stats; + + tx_packets = priv->tx_queue[0]->stats.tx_packets; + tx_bytes = priv->tx_queue[0]->stats.tx_bytes; + + dev->stats.rx_packets = rx_packets; + dev->stats.rx_bytes = rx_bytes; + dev->stats.rx_dropped = rx_dropped; + dev->stats.tx_bytes = tx_bytes; + dev->stats.tx_packets = tx_packets; + + return &dev->stats; +} + +static int ctcmac_set_mac_addr(struct net_device *dev, void *p) +{ + eth_mac_addr(dev, p); + return 0; +} + +static void ctcmac_gdrvinfo(struct net_device *dev, + struct ethtool_drvinfo *drvinfo) +{ + strlcpy(drvinfo->driver, "ctcmac", sizeof(drvinfo->driver)); + strlcpy(drvinfo->version, "v1.0", sizeof(drvinfo->version)); + strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version)); + strlcpy(drvinfo->bus_info, "N/A", sizeof(drvinfo->bus_info)); +} + +/* Return the length of the register structure */ +static int ctcmac_reglen(struct net_device *dev) +{ + return sizeof(struct cpu_mac_regs); +} + +/* Return a dump of the GFAR register space */ +static void ctcmac_get_regs(struct net_device *dev, struct ethtool_regs *regs, + void *regbuf) +{ + int i; + struct ctcmac_private *priv = netdev_priv(dev); + u32 __iomem *theregs = (u32 __iomem *)priv->cpumac_reg; + u32 *buf = (u32 *)regbuf; + + for (i = 0; i < sizeof(struct cpu_mac_regs) / sizeof(u32); i++) + buf[i] = ctcmac_regr(&theregs[i]); +} + +/* Fills in rvals with the current ring parameters. Currently, + * rx, rx_mini, and rx_jumbo rings are the same size, as mini and + * jumbo are ignored by the driver + */ +static void ctcmac_gringparam(struct net_device *dev, + struct ethtool_ringparam *rvals) +{ + struct ctcmac_private *priv = netdev_priv(dev); + struct ctcmac_priv_tx_q *tx_queue = NULL; + struct ctcmac_priv_rx_q *rx_queue = NULL; + + tx_queue = priv->tx_queue[0]; + rx_queue = priv->rx_queue[0]; + + rvals->rx_max_pending = CTCMAC_MAX_RING_SIZE; + rvals->rx_mini_max_pending = CTCMAC_MAX_RING_SIZE; + rvals->rx_jumbo_max_pending = CTCMAC_MAX_RING_SIZE; + rvals->tx_max_pending = CTCMAC_MAX_RING_SIZE; + + /* Values changeable by the user. The valid values are + * in the range 1 to the "*_max_pending" counterpart above. + */ + rvals->rx_pending = rx_queue->rx_ring_size; + rvals->rx_mini_pending = rx_queue->rx_ring_size; + rvals->rx_jumbo_pending = rx_queue->rx_ring_size; + rvals->tx_pending = tx_queue->tx_ring_size; +} + +/* Change the current ring parameters, stopping the controller if + * necessary so that we don't mess things up while we're in motion. + */ +static int ctcmac_sringparam(struct net_device *dev, + struct ethtool_ringparam *rvals) +{ + struct ctcmac_private *priv = netdev_priv(dev); + int err = 0, i; + + if (rvals->rx_pending > CTCMAC_MAX_RING_SIZE) + return -EINVAL; + + if (rvals->tx_pending > CTCMAC_MAX_RING_SIZE) + return -EINVAL; + + while (test_and_set_bit_lock(CTCMAC_RESETTING, &priv->state)) + cpu_relax(); + + if (dev->flags & IFF_UP) + stop_ctcmac(dev); + + /* Change the sizes */ + for (i = 0; i < priv->num_rx_queues; i++) + priv->rx_queue[i]->rx_ring_size = rvals->rx_pending; + + for (i = 0; i < priv->num_tx_queues; i++) + priv->tx_queue[i]->tx_ring_size = rvals->tx_pending; + + /* Rebuild the rings with the new size */ + if (dev->flags & IFF_UP) + err = startup_ctcmac(dev); + + clear_bit_unlock(CTCMAC_RESETTING, &priv->state); + + return err; +} + +static void ctcmac_gpauseparam(struct net_device *dev, + struct ethtool_pauseparam *epause) +{ +} + +static int ctcmac_spauseparam(struct net_device *dev, + struct ethtool_pauseparam *epause) +{ + return 0; +} + +static void ctcmac_gstrings(struct net_device *dev, u32 stringset, u8 *buf) +{ + memcpy(buf, ctc_stat_gstrings, CTCMAC_STATS_LEN * ETH_GSTRING_LEN); +} + +static int ctcmac_sset_count(struct net_device *dev, int sset) +{ + return CTCMAC_STATS_LEN; +} + +static void ctcmac_fill_stats(struct net_device *netdev, + struct ethtool_stats *dummy, u64 *buf) +{ + u32 mtu; + unsigned long flags; + struct ctcmac_pkt_stats *stats; + struct ctcmac_private *priv = netdev_priv(netdev); + + spin_lock_irqsave(&priv->reglock, flags); + stats = &g_pkt_stats[priv->index]; + stats->rx_good_ucast_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_0[0]); + stats->rx_good_ucast_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_0[2]); + stats->rx_good_mcast_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_1[0]); + stats->rx_good_mcast_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_1[2]); + stats->rx_good_bcast_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_2[0]); + stats->rx_good_bcast_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_2[2]); + stats->rx_good_pause_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_3[0]); + stats->rx_good_pause_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_3[2]); + stats->rx_good_pfc_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_4[0]); + stats->rx_good_pfc_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_4[2]); + stats->rx_good_control_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_5[0]); + stats->rx_good_control_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_5[2]); + stats->rx_fcs_error_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_6[0]); + stats->rx_fcs_error_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_6[2]); + stats->rx_mac_overrun_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_7[0]); + stats->rx_mac_overrun_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_7[2]); + stats->rx_good_63B_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_8[0]); + stats->rx_good_63B_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_8[2]); + stats->rx_bad_63B_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_9[0]); + stats->rx_bad_63B_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_9[2]); + stats->rx_good_mtu2B_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_10[0]); + stats->rx_good_mtu2B_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_10[2]); + stats->rx_bad_mtu2B_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_11[0]); + stats->rx_bad_mtu2B_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_11[2]); + stats->rx_good_jumbo_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_12[0]); + stats->rx_good_jumbo_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_12[2]); + stats->rx_bad_jumbo_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_13[0]); + stats->rx_bad_jumbo_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_13[2]); + stats->rx_64B_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_14[0]); + stats->rx_64B_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_14[2]); + stats->rx_127B_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_15[0]); + stats->rx_127B_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_15[2]); + stats->rx_255B_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_16[0]); + stats->rx_255B_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_16[2]); + stats->rx_511B_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_17[0]); + stats->rx_511B_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_17[2]); + stats->rx_1023B_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_18[0]); + stats->rx_1023B_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_18[2]); + stats->rx_mtu1B_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_19[0]); + stats->rx_mtu1B_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_19[2]); + stats->tx_ucast_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_20[0]); + stats->tx_ucast_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_20[2]); + stats->tx_mcast_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_21[0]); + stats->tx_mcast_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_21[2]); + stats->tx_bcast_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_22[0]); + stats->tx_bcast_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_22[2]); + stats->tx_pause_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_23[0]); + stats->tx_pause_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_23[2]); + stats->tx_control_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_24[0]); + stats->tx_control_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_24[2]); + stats->tx_fcs_error_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_25[0]); + stats->tx_fcs_error_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_25[2]); + stats->tx_underrun_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_26[0]); + stats->tx_underrun_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_26[2]); + stats->tx_63B_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_27[0]); + stats->tx_63B_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_27[2]); + stats->tx_64B_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_28[0]); + stats->tx_64B_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_28[2]); + stats->tx_127B_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_29[0]); + stats->tx_127B_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_29[2]); + stats->tx_255B_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_30[0]); + stats->tx_255B_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_30[2]); + stats->tx_511B_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_31[0]); + stats->tx_511B_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_31[2]); + stats->tx_1023B_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_32[0]); + stats->tx_1023B_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_32[2]); + stats->tx_mtu1_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_33[0]); + stats->tx_mtu1_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_33[2]); + stats->tx_mtu2_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_34[0]); + stats->tx_mtu2_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_34[2]); + stats->tx_jumbo_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_35[0]); + stats->tx_jumbo_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_35[2]); + mtu = readl(&priv->cpumac_reg->cpu_mac_stats_cfg[1]); + stats->mtu1 = mtu & 0x3fff; + stats->mtu2 = (mtu >> 16) & 0x3fff; + spin_unlock_irqrestore(&priv->reglock, flags); + + memcpy(buf, (void *)stats, sizeof(struct ctcmac_pkt_stats)); +} + +static uint32_t ctcmac_get_msglevel(struct net_device *dev) +{ + struct ctcmac_private *priv = netdev_priv(dev); + + return priv->msg_enable; +} + +static void ctcmac_set_msglevel(struct net_device *dev, uint32_t data) +{ + struct ctcmac_private *priv = netdev_priv(dev); + + priv->msg_enable = data; +} + +static int ctcmac_get_ts_info(struct net_device *dev, + struct ethtool_ts_info *info) +{ + return 0; +} + +const struct ethtool_ops ctcmac_ethtool_ops = { + .get_drvinfo = ctcmac_gdrvinfo, + .get_regs_len = ctcmac_reglen, + .get_regs = ctcmac_get_regs, + .get_link = ethtool_op_get_link, + .get_ringparam = ctcmac_gringparam, + .set_ringparam = ctcmac_sringparam, + .get_pauseparam = ctcmac_gpauseparam, + .set_pauseparam = ctcmac_spauseparam, + .get_strings = ctcmac_gstrings, + .get_sset_count = ctcmac_sset_count, + .get_ethtool_stats = ctcmac_fill_stats, + .get_msglevel = ctcmac_get_msglevel, + .set_msglevel = ctcmac_set_msglevel, + .get_link_ksettings = phy_ethtool_get_link_ksettings, + .set_link_ksettings = phy_ethtool_set_link_ksettings, + .get_ts_info = ctcmac_get_ts_info, +}; + +static const struct net_device_ops ctcmac_netdev_ops = { + .ndo_open = ctcmac_enet_open, + .ndo_start_xmit = ctcmac_start_xmit, + .ndo_stop = ctcmac_close, + .ndo_change_mtu = ctcmac_change_mtu, + .ndo_set_features = ctcmac_set_features, + .ndo_set_rx_mode = ctcmac_set_multi, + .ndo_tx_timeout = ctcmac_timeout, + .ndo_do_ioctl = ctcmac_ioctl, + .ndo_get_stats = ctcmac_get_stats, + .ndo_set_mac_address = ctcmac_set_mac_addr, + .ndo_validate_addr = eth_validate_addr, +}; + +static int ctcmac_probe(struct platform_device *ofdev) +{ + struct net_device *dev = NULL; + struct ctcmac_private *priv = NULL; + int err = 0, i; + + regmap_base = + syscon_regmap_lookup_by_phandle(ofdev->dev.of_node, "ctc,sysctrl"); + if (IS_ERR(regmap_base)) + return PTR_ERR(regmap_base); + + err = ctcmac_of_init(ofdev, &dev); + if (err) + return err; + + priv = netdev_priv(dev); + SET_NETDEV_DEV(dev, &ofdev->dev); + INIT_WORK(&priv->reset_task, ctcmac_reset_task); + platform_set_drvdata(ofdev, priv); + dev_set_drvdata(&dev->dev, priv); + + dev->base_addr = (unsigned long)priv->iobase; + dev->watchdog_timeo = TX_TIMEOUT; + dev->mtu = CTCMAC_DEFAULT_MTU; + dev->netdev_ops = &ctcmac_netdev_ops; + dev->ethtool_ops = &ctcmac_ethtool_ops; + + netif_napi_add(dev, &priv->napi_rx, ctcmac_poll_rx_sq, + CTCMAC_NAIP_RX_WEIGHT); + netif_napi_add(dev, &priv->napi_tx, ctcmac_poll_tx_sq, + CTCMAC_NAIP_TX_WEIGHT); + + /* Initializing some of the rx/tx queue level parameters */ + for (i = 0; i < priv->num_tx_queues; i++) { + priv->tx_queue[i]->tx_ring_size = CTCMAC_TX_RING_SIZE; + priv->tx_queue[i]->num_txbdfree = CTCMAC_TX_RING_SIZE; + } + + for (i = 0; i < priv->num_rx_queues; i++) + priv->rx_queue[i]->rx_ring_size = CTCMAC_RX_RING_SIZE; + + set_bit(CTCMAC_DOWN, &priv->state); + + if (!g_reglock_init_done) + spin_lock_init(&global_reglock); + + g_reglock_init_done = 1; + + spin_lock_init(&priv->reglock); + /* Carrier starts down, phylib will bring it up */ + netif_carrier_off(dev); + err = register_netdev(dev); + if (err) + goto register_fail; + + if (!g_mac_unit_init_done) { + writel(0x07, &priv->cpumacu_reg->cpu_mac_unit_reset_ctl); + writel(0x00, &priv->cpumacu_reg->cpu_mac_unit_reset_ctl); + + clrsetbits(&priv->cpumacu_reg->cpu_mac_unit_ts_cfg, + 0, CPU_MAC_UNIT_TS_CFG_W0_CFG_FORCE_S_AND_NS_EN); + if (priv->interface == PHY_INTERFACE_MODE_SGMII) { + clrsetbits(&priv->cpumacu_reg->cpu_mac_unit_ref_pulse_cfg[1], + CPU_MAC_UNIT_REF_PULSE_CFG_W1_REF_LINK_PULSE_RST, + 0); + + ctc_mac_serdes_init(priv); + } + g_mac_unit_init_done = 1; + } + + ctcmac_pps_init(priv); + + mdelay(10); + + sprintf(priv->irqinfo[CTCMAC_NORMAL].name, "%s%s", + dev->name, "_normal"); + sprintf(priv->irqinfo[CTCMAC_FUNC].name, "%s%s", dev->name, "_func"); + + return 0; + +register_fail: + ctcmac_unmap_io_space(priv); + ctcmac_free_rx_queues(priv); + ctcmac_free_tx_queues(priv); + of_node_put(priv->phy_node); + ctcmac_free_dev(priv); + + return err; +} + +static int ctcmac_remove(struct platform_device *ofdev) +{ + struct ctcmac_private *priv = platform_get_drvdata(ofdev); + + device_remove_file(&priv->ndev->dev, &dev_attr_rxq0_pps); + device_remove_file(&priv->ndev->dev, &dev_attr_rxq1_pps); + + of_node_put(priv->phy_node); + + unregister_netdev(priv->ndev); + + ctcmac_unmap_io_space(priv); + ctcmac_free_rx_queues(priv); + ctcmac_free_tx_queues(priv); + ctcmac_free_dev(priv); + + return 0; +} + +static const struct of_device_id ctcmac_match[] = { + { + .type = "network", + .compatible = "ctc,mac", + }, + {}, +}; + +MODULE_DEVICE_TABLE(of, ctcmac_match); + +/* Structure for a device driver */ +static struct platform_driver ctcmac_driver = { + .driver = { + .name = "ctc-cpumac", + .of_match_table = ctcmac_match, + }, + .probe = ctcmac_probe, + .remove = ctcmac_remove, +}; + +module_platform_driver(ctcmac_driver); +MODULE_LICENSE("GPL"); diff --git a/platform/centec-arm64/tsingma-bsp/src/ctcmac/ctcmac.h b/platform/centec-arm64/tsingma-bsp/src/ctcmac/ctcmac.h new file mode 100644 index 000000000000..4378c2c802e9 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/ctcmac/ctcmac.h @@ -0,0 +1,307 @@ +/* + * Centec cpu_mac Ethernet Driver -- cpu_mac controller implementation + * Provides Bus interface for MIIM regs + * + * Author: liuht + * + * Copyright 2002-2017, Centec Networks (Suzhou) Co., Ltd. + * + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#ifndef __CTCMAC_H +#define __CTCMAC_H + +#define TX_TIMEOUT (5 * HZ) + +#define CTCMAC_DEFAULT_MTU 1500 +#define CTCMAC_MIN_PKT_LEN 64 + +#define CTCMAC_TX_QUEUE_MAX 1 +#define CTCMAC_RX_QUEUE_MAX 2 + +#define CTCMAC0_EXSRAM_BASE 0x0 +#define CTCMAC1_EXSRAM_BASE 0x1800 +#define CTCMAC_MAX_RING_SIZE 1023 +#define CTCMAC_TX_RING_SIZE 1023 +#define CTCMAC_RX_RING_SIZE 1023 +#define CTCMAC_RX_BUFF_ALLOC 16 +#define CTCMAC_INTERNAL_RING_SIZE 64 + +/* The maximum number of packets to be handled in one call of gfar_poll */ +#define CTCMAC_NAIP_RX_WEIGHT 16 +#define CTCMAC_NAIP_TX_WEIGHT 16 + +#define CTCMAC_RXB_SIZE 1024 +#define CTCMAC_SKBFRAG_SIZE (CTCMAC_RXB_SIZE \ + + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) +#define CTCMAC_RXB_TRUESIZE 2048 +#define BUF_ALIGNMENT 256 +#define CTCMAC_JUMBO_FRAME_SIZE 9600 + +#define CTCMAC_TOKEN_PER_PKT 10 +#define CTCMAC_TIMER_COMPENSATE 1 + +#define CTCMAC_NOR_RX1_R BIT(7) +#define CTCMAC_NOR_RX0_R BIT(6) +#define CTCMAC_NOR_RX1_D BIT(5) +#define CTCMAC_NOR_RX0_D BIT(4) +#define CTCMAC_NOR_TX_D BIT(3) +#define CTCMAC_NOR_AN_D BIT(2) +#define CTCMAC_NOR_LINK_DOWN BIT(1) +#define CTCMAC_NOR_LINK_UP BIT(0) + +#define CTC_DDR_BASE 0x80000000 + +#define CSA_SGMII_MD_MASK 0x00000008 +#define CSA_EN 0x00000001 + +/*Mask*/ +/*CTCMAC_SGMII_CFG*/ +#define CSC_REP_MASK 0x1fc00000 +#define CSC_SMP_MASK 0x1fc00000 +/*CTCMAC_SGMII_MON*/ +#define CSM_ANST_MASK 0x00000007 + +#define CSC_1000M 0x00000000 +#define CSC_100M 0x02400000 +#define CSC_10M 0x18c00000 + +#define CTCMAC_DESC_INT_NUM 1 + +#define CTCMAC_SUPPORTED (SUPPORTED_10baseT_Full \ + | SUPPORTED_100baseT_Full \ + | SUPPORTED_1000baseT_Full \ + | SUPPORTED_Autoneg) + +#define CTCMAC_STATS_LEN (sizeof(struct ctcmac_pkt_stats) / sizeof(u64)) + +struct ctcmac_skb_cb { + unsigned int bytes_sent; /* bytes-on-wire (i.e. no FCB) */ +}; + +#define CTCMAC_CB(skb) ((struct ctcmac_skb_cb *)((skb)->cb)) + +enum ctcmac_irqinfo_id { + CTCMAC_NORMAL = 0, + CTCMAC_FUNC, + CTCMAC_UNIT, + CTCMAC_NUM_IRQS +}; + +enum ctcmac_dev_state { + CTCMAC_DOWN = 1, + CTCMAC_RESETTING +}; + +enum ctcmac_int_type { + CTCMAC_INT_PACKET = 1, + CTCMAC_INT_DESC, + CTCMAC_INT_MAX +}; + +enum ctcmac_autoneg { + CTCMAC_AUTONEG_1000BASEX_M, + CTCMAC_AUTONEG_PHY_M, + CTCMAC_AUTONEG_MAC_M, + CTCMAC_AUTONEG_DISABLE, + CTCMAC_AUTONEG_MAX +}; + +/* Per TX queue stats */ +struct txq_stats { + unsigned long tx_packets; + unsigned long tx_bytes; +}; + +struct ctcmac_tx_buff { + void *vaddr; + dma_addr_t dma; + u32 len; + u32 offset; + u8 alloc; +}; + +struct ctcmac_priv_tx_q { + spinlock_t txlock __aligned(SMP_CACHE_BYTES); + struct ctcmac_tx_buff tx_buff[CTCMAC_MAX_RING_SIZE + 1]; + unsigned int num_txbdfree; + u16 tx_ring_size; + u16 qindex; + u16 next_to_alloc; + u16 next_to_clean; + struct txq_stats stats; + struct net_device *dev; + struct sk_buff **tx_skbuff; +}; + +/*Per RX queue stats */ +struct rxq_stats { + unsigned long rx_packets; + unsigned long rx_bytes; + unsigned long rx_dropped; +}; + +struct ctcmac_rx_buff { + dma_addr_t dma; + struct page *page; + unsigned int page_offset; +}; + +struct ctcmac_priv_rx_q { + struct ctcmac_rx_buff *rx_buff __aligned(SMP_CACHE_BYTES); + struct net_device *ndev; + struct device *dev; + u16 rx_ring_size; + u16 qindex; + u16 next_to_clean; + u16 next_to_use; + u16 next_to_alloc; + struct sk_buff *skb; + struct rxq_stats stats; + u32 pps_limit; + u32 token, token_max; + u32 rx_trigger; +}; + +struct ctcmac_irqinfo { + unsigned int irq; + char name[32]; +}; + +struct ctcmac_desc_cfg { + u8 err_type; /*used when err == 1 */ + u8 err; + u8 eop; + u8 sop; + u32 size; + u32 addr_high; + u32 addr_low; +}; + +struct ctcmac_private { + spinlock_t reglock __aligned(SMP_CACHE_BYTES); + struct device *dev; + struct net_device *ndev; + void __iomem *iobase; + struct cpu_mac_regs __iomem *cpumac_reg; + struct cpu_mac_mems __iomem *cpumac_mem; + struct cpu_mac_unit_regs *cpumacu_reg; + u32 device_flags; + int irq_num; + int index; + + struct ctcmac_priv_tx_q *tx_queue[CTCMAC_TX_QUEUE_MAX]; + struct ctcmac_priv_rx_q *rx_queue[CTCMAC_RX_QUEUE_MAX]; + + unsigned long state; + unsigned int num_tx_queues; + unsigned int num_rx_queues; + + /* PHY stuff */ + phy_interface_t interface; + struct device_node *phy_node; + struct mii_bus *mii_bus; + int oldspeed; + int oldlink; + int oldduplex; + + struct work_struct reset_task; + struct platform_device *ofdev; + struct napi_struct napi_rx; + struct napi_struct napi_tx; + struct ctcmac_irqinfo irqinfo[CTCMAC_NUM_IRQS]; + + int hwts_rx_en; + int hwts_tx_en; + u32 autoneg_mode; + u32 supported; + u32 msg_enable; + u32 int_type; + u8 dfe_enable; + struct timer_list token_timer; +}; + +struct ctcmac_pkt_stats { + u64 rx_good_ucast_bytes; + u64 rx_good_ucast_pkt; + u64 rx_good_mcast_bytes; + u64 rx_good_mcast_pkt; + u64 rx_good_bcast_bytes; + u64 rx_good_bcast_pkt; + u64 rx_good_pause_bytes; + u64 rx_good_pause_pkt; + u64 rx_good_pfc_bytes; + u64 rx_good_pfc_pkt; + u64 rx_good_control_bytes; + u64 rx_good_control_pkt; + u64 rx_fcs_error_bytes; + u64 rx_fcs_error_pkt; + u64 rx_mac_overrun_bytes; + u64 rx_mac_overrun_pkt; + u64 rx_good_63B_bytes; + u64 rx_good_63B_pkt; + u64 rx_bad_63B_bytes; + u64 rx_bad_63B_pkt; + u64 rx_good_mtu2B_bytes; + u64 rx_good_mtu2B_pkt; + u64 rx_bad_mtu2B_bytes; + u64 rx_bad_mtu2B_pkt; + u64 rx_good_jumbo_bytes; + u64 rx_good_jumbo_pkt; + u64 rx_bad_jumbo_bytes; + u64 rx_bad_jumbo_pkt; + u64 rx_64B_bytes; + u64 rx_64B_pkt; + u64 rx_127B_bytes; + u64 rx_127B_pkt; + u64 rx_255B_bytes; + u64 rx_255B_pkt; + u64 rx_511B_bytes; + u64 rx_511B_pkt; + u64 rx_1023B_bytes; + u64 rx_1023B_pkt; + u64 rx_mtu1B_bytes; + u64 rx_mtu1B_pkt; + u64 tx_ucast_bytes; + u64 tx_ucast_pkt; + u64 tx_mcast_bytes; + u64 tx_mcast_pkt; + u64 tx_bcast_bytes; + u64 tx_bcast_pkt; + u64 tx_pause_bytes; + u64 tx_pause_pkt; + u64 tx_control_bytes; + u64 tx_control_pkt; + u64 tx_fcs_error_bytes; + u64 tx_fcs_error_pkt; + u64 tx_underrun_bytes; + u64 tx_underrun_pkt; + u64 tx_63B_bytes; + u64 tx_63B_pkt; + u64 tx_64B_bytes; + u64 tx_64B_pkt; + u64 tx_127B_bytes; + u64 tx_127B_pkt; + u64 tx_255B_bytes; + u64 tx_255B_pkt; + u64 tx_511B_bytes; + u64 tx_511B_pkt; + u64 tx_1023B_bytes; + u64 tx_1023B_pkt; + u64 tx_mtu1_bytes; + u64 tx_mtu1_pkt; + u64 tx_mtu2_bytes; + u64 tx_mtu2_pkt; + u64 tx_jumbo_bytes; + u64 tx_jumbo_pkt; + u64 mtu1; + u64 mtu2; +}; + +#endif diff --git a/platform/centec-arm64/tsingma-bsp/src/ctcmac/ctcmac_reg.h b/platform/centec-arm64/tsingma-bsp/src/ctcmac/ctcmac_reg.h new file mode 100644 index 000000000000..2778f0bb4553 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/ctcmac/ctcmac_reg.h @@ -0,0 +1,5288 @@ +#ifndef __CTCMAC_H__ +#define __CTCMAC_H__ + +#define CPUMAC_MEM_BASE 0x00004000 +#define CPUMAC_REG_BASE 0x00000000 + +struct cpu_mac_regs { + u32 cpu_mac_axi_cfg; /* 0x00000000 */ + u32 cpu_mac_axi_mon; /* 0x00000004 */ + u32 cpu_mac_desc_cfg[2]; /* 0x00000008 */ + u32 cpu_mac_buffer_cfg[3]; /* 0x00000010 */ + u32 rsv7; + u32 cpu_mac_debug_stats[3]; /* 0x00000020 */ + u32 rsv11; + u32 cpu_mac_desc_mon[3]; /* 0x00000030 */ + u32 rsv15; + u32 cpu_mac_dma_weight_cfg; /* 0x00000040 */ + u32 cpu_mac_init; /* 0x00000044 */ + u32 cpu_mac_init_done; /* 0x00000048 */ + u32 cpu_mac_parity_ctl; /* 0x0000004c */ + u32 cpu_mac_ext_ram_cfg[2]; /* 0x00000050 */ + u32 rsv22; + u32 rsv23; + u32 cpu_mac_fifo_ctl[4]; /* 0x00000060 */ + u32 cpu_mac_gmac_cfg[4]; /* 0x00000070 */ + u32 cpu_mac_ram_chk_rec; /* 0x00000080 */ + u32 cpu_mac_reset; /* 0x00000084 */ + u32 cpu_mac_sgmii_auto_neg_cfg; /* 0x00000088 */ + u32 cpu_mac_reserved; /* 0x0000008c */ + u32 cpu_mac_gmac_mon[2]; /* 0x00000090 */ + u32 cpu_mac_credit_ctl; /* 0x00000098 */ + u32 cpu_mac_credit_status; /* 0x0000009c */ + u32 cpu_mac_pause_cfg[4]; /* 0x000000a0 */ + u32 cpu_mac_pause_mon[3]; /* 0x000000b0 */ + u32 rsv47; + u32 cpu_mac_sgmii_cfg[2]; /* 0x000000c0 */ + u32 cpu_mac_sgmii_mon[2]; /* 0x000000c8 */ + u32 cpu_mac_stats_cfg[2]; /* 0x000000d0 */ + u32 rsv54; + u32 rsv55; + u32 cpu_mac_interrupt_func[4]; /* 0x000000e0 */ + u32 cpu_mac_interrupt_normal[4]; /* 0x000000f0 */ + u32 cpu_mac_fifo_status[3]; /* 0x00000100 */ +}; + +/* cpu_mac_axi_cfg Definition */ +#define CPU_MAC_AXI_CFG_W0_CFG_AXI_WR_BURST_LEN BIT(0) +#define CPU_MAC_AXI_CFG_W0_CFG_AXI_WR_WORD_SWAP_EN BIT(18) +#define CPU_MAC_AXI_CFG_W0_CFG_AXI_WR_D_WORD_SWAP_EN BIT(19) +#define CPU_MAC_AXI_CFG_W0_CFG_AXI_RD_D_WORD_SWAP_EN BIT(17) +#define CPU_MAC_AXI_CFG_W0_CFG_AXI_RD_ADDR_ALIGN_EN BIT(20) +#define CPU_MAC_AXI_CFG_W0_CFG_AXI_RD_BURST_LEN BIT(8) +#define CPU_MAC_AXI_CFG_W0_CFG_AXI_RD_WORD_SWAP_EN BIT(16) + +#define CPU_MAC_AXI_CFG_W0_CFG_AXI_WR_BURST_LEN_MASK 0x000000ff +#define CPU_MAC_AXI_CFG_W0_CFG_AXI_WR_WORD_SWAP_EN_MASK 0x00040000 +#define CPU_MAC_AXI_CFG_W0_CFG_AXI_WR_D_WORD_SWAP_EN_MASK 0x00080000 +#define CPU_MAC_AXI_CFG_W0_CFG_AXI_RD_D_WORD_SWAP_EN_MASK 0x00020000 +#define CPU_MAC_AXI_CFG_W0_CFG_AXI_RD_ADDR_ALIGN_EN_MASK 0x00100000 +#define CPU_MAC_AXI_CFG_W0_CFG_AXI_RD_BURST_LEN_MASK 0x0000ff00 +#define CPU_MAC_AXI_CFG_W0_CFG_AXI_RD_WORD_SWAP_EN_MASK 0x00010000 + +/* cpu_mac_axi_mon Definition */ +#define CPU_MAC_AXI_MON_W0_MON_AXI_WR_RESP BIT(4) +#define CPU_MAC_AXI_MON_W0_MON_AXI_RD_RESP BIT(0) + +#define CPU_MAC_AXI_MON_W0_MON_AXI_WR_RESP_MASK 0x00000070 +#define CPU_MAC_AXI_MON_W0_MON_AXI_RD_RESP_MASK 0x00000007 + +/* cpu_mac_desc_cfg Definition */ +#define CPU_MAC_DESC_CFG_W0_CFG_TX_DESC_DONE_INTR_EOP_EN BIT(30) +#define CPU_MAC_DESC_CFG_W0_CFG_RX_DESC_DONE_INTR_EOP_EN BIT(29) +#define CPU_MAC_DESC_CFG_W0_CFG_RX_DESC0_DONE_INTR_THRD BIT(8) +#define CPU_MAC_DESC_CFG_W0_CFG_TX_DESC_DONE_INTR_THRD BIT(0) +#define CPU_MAC_DESC_CFG_W0_CFG_RX_DESC1_DONE_INTR_THRD BIT(16) +#define CPU_MAC_DESC_CFG_W0_CFG_TX_DESC_ACK_EN BIT(31) +#define CPU_MAC_DESC_CFG_W1_CFG_RX_DESC0_REQ_INTR_THRD BIT(0) +#define CPU_MAC_DESC_CFG_W1_CFG_RX_DESC1_REQ_INTR_THRD BIT(8) + +#define CPU_MAC_DESC_CFG_W0_CFG_TX_DESC_DONE_INTR_EOP_EN_MASK 0x40000000 +#define CPU_MAC_DESC_CFG_W0_CFG_RX_DESC_DONE_INTR_EOP_EN_MASK 0x20000000 +#define CPU_MAC_DESC_CFG_W0_CFG_RX_DESC0_DONE_INTR_THRD_MASK 0x0000ff00 +#define CPU_MAC_DESC_CFG_W0_CFG_TX_DESC_DONE_INTR_THRD_MASK 0x000000ff +#define CPU_MAC_DESC_CFG_W0_CFG_RX_DESC1_DONE_INTR_THRD_MASK 0x00ff0000 +#define CPU_MAC_DESC_CFG_W0_CFG_TX_DESC_ACK_EN_MASK 0x80000000 +#define CPU_MAC_DESC_CFG_W1_CFG_RX_DESC0_REQ_INTR_THRD_MASK 0x000000ff +#define CPU_MAC_DESC_CFG_W1_CFG_RX_DESC1_REQ_INTR_THRD_MASK 0x0000ff00 + +/* cpu_mac_buffer_cfg Definition */ +#define CPU_MAC_BUFFER_CFG_W0_CFG_RX_X_OFF_THRD BIT(16) +#define CPU_MAC_BUFFER_CFG_W0_CFG_RX_X_ON_THRD BIT(0) +#define CPU_MAC_BUFFER_CFG_W1_CFG_RX_RSV_THRD BIT(0) +#define CPU_MAC_BUFFER_CFG_W1_CFG_RX_FLUSH_THRD BIT(16) +#define CPU_MAC_BUFFER_CFG_W2_CFG_RX_FLUSH_EN BIT(0) + +#define CPU_MAC_BUFFER_CFG_W0_CFG_RX_X_OFF_THRD_MASK 0x3fff0000 +#define CPU_MAC_BUFFER_CFG_W0_CFG_RX_X_ON_THRD_MASK 0x00003fff +#define CPU_MAC_BUFFER_CFG_W1_CFG_RX_RSV_THRD_MASK 0x00003fff +#define CPU_MAC_BUFFER_CFG_W1_CFG_RX_FLUSH_THRD_MASK 0x3fff0000 +#define CPU_MAC_BUFFER_CFG_W2_CFG_RX_FLUSH_EN_MASK 0x00000001 + +/* cpu_mac_debug_stats Definition */ +#define CPU_MAC_DEBUG_STATS_W0_DMA_RX_ERROR_CNT BIT(20) +#define CPU_MAC_DEBUG_STATS_W0_GMAC_TX_SOP_CNT BIT(24) +#define CPU_MAC_DEBUG_STATS_W0_GMAC_RX_SOP_CNT BIT(0) +#define CPU_MAC_DEBUG_STATS_W0_GMAC_RX_EOP_CNT BIT(4) +#define CPU_MAC_DEBUG_STATS_W0_GMAC_TX_EOP_CNT BIT(28) +#define CPU_MAC_DEBUG_STATS_W0_DMA_RX_EOP_CNT BIT(16) +#define CPU_MAC_DEBUG_STATS_W0_GMAC_RX_ERROR_CNT BIT(8) +#define CPU_MAC_DEBUG_STATS_W0_DMA_RX_SOP_CNT BIT(12) +#define CPU_MAC_DEBUG_STATS_W1_DMA_TX_EOP_CNT BIT(8) +#define CPU_MAC_DEBUG_STATS_W1_GMAC_TX_PTP_ERR_CNT BIT(16) +#define CPU_MAC_DEBUG_STATS_W1_DMA_TX_SOP_CNT BIT(4) +#define CPU_MAC_DEBUG_STATS_W1_DMA_TX_ERROR_CNT BIT(12) +#define CPU_MAC_DEBUG_STATS_W1_GMAC_TX_ERROR_CNT BIT(0) +#define CPU_MAC_DEBUG_STATS_W2_AXI_RD_BURST_CNT BIT(8) +#define CPU_MAC_DEBUG_STATS_W2_EXT_RAM_SBE_CNT BIT(16) +#define CPU_MAC_DEBUG_STATS_W2_AXI_RD_BURST_ERR_CNT BIT(12) +#define CPU_MAC_DEBUG_STATS_W2_AXI_WR_BURST_CNT BIT(0) +#define CPU_MAC_DEBUG_STATS_W2_AXI_WR_BURST_ERR_CNT BIT(4) + +#define CPU_MAC_DEBUG_STATS_W0_DMA_RX_ERROR_CNT_MASK 0x00f00000 +#define CPU_MAC_DEBUG_STATS_W0_GMAC_TX_SOP_CNT_MASK 0x0f000000 +#define CPU_MAC_DEBUG_STATS_W0_GMAC_RX_SOP_CNT_MASK 0x0000000f +#define CPU_MAC_DEBUG_STATS_W0_GMAC_RX_EOP_CNT_MASK 0x000000f0 +#define CPU_MAC_DEBUG_STATS_W0_GMAC_TX_EOP_CNT_MASK 0xf0000000 +#define CPU_MAC_DEBUG_STATS_W0_DMA_RX_EOP_CNT_MASK 0x000f0000 +#define CPU_MAC_DEBUG_STATS_W0_GMAC_RX_ERROR_CNT_MASK 0x00000f00 +#define CPU_MAC_DEBUG_STATS_W0_DMA_RX_SOP_CNT_MASK 0x0000f000 +#define CPU_MAC_DEBUG_STATS_W1_DMA_TX_EOP_CNT_MASK 0x00000f00 +#define CPU_MAC_DEBUG_STATS_W1_GMAC_TX_PTP_ERR_CNT_MASK 0x000f0000 +#define CPU_MAC_DEBUG_STATS_W1_DMA_TX_SOP_CNT_MASK 0x000000f0 +#define CPU_MAC_DEBUG_STATS_W1_DMA_TX_ERROR_CNT_MASK 0x0000f000 +#define CPU_MAC_DEBUG_STATS_W1_GMAC_TX_ERROR_CNT_MASK 0x0000000f +#define CPU_MAC_DEBUG_STATS_W2_AXI_RD_BURST_CNT_MASK 0x00000f00 +#define CPU_MAC_DEBUG_STATS_W2_EXT_RAM_SBE_CNT_MASK 0x000f0000 +#define CPU_MAC_DEBUG_STATS_W2_AXI_RD_BURST_ERR_CNT_MASK 0x0000f000 +#define CPU_MAC_DEBUG_STATS_W2_AXI_WR_BURST_CNT_MASK 0x0000000f +#define CPU_MAC_DEBUG_STATS_W2_AXI_WR_BURST_ERR_CNT_MASK 0x000000f0 + +/* cpu_mac_desc_mon Definition */ +#define CPU_MAC_DESC_MON_W0_MON_DESC_AVAIL_NUM0 BIT(0) +#define CPU_MAC_DESC_MON_W0_MON_DESC_AVAIL_NUM1 BIT(16) +#define CPU_MAC_DESC_MON_W1_MON_DESC_AVAIL_NUM2 BIT(0) +#define CPU_MAC_DESC_MON_W1_MON_DESC_DONE_NUM0 BIT(16) +#define CPU_MAC_DESC_MON_W2_MON_DESC_DONE_NUM1 BIT(0) +#define CPU_MAC_DESC_MON_W2_MON_DESC_DONE_NUM2 BIT(16) + +#define CPU_MAC_DESC_MON_W0_MON_DESC_AVAIL_NUM0_MASK 0x0000ffff +#define CPU_MAC_DESC_MON_W0_MON_DESC_AVAIL_NUM1_MASK 0xffff0000 +#define CPU_MAC_DESC_MON_W1_MON_DESC_AVAIL_NUM2_MASK 0x0000ffff +#define CPU_MAC_DESC_MON_W1_MON_DESC_DONE_NUM0_MASK 0xffff0000 +#define CPU_MAC_DESC_MON_W2_MON_DESC_DONE_NUM1_MASK 0x0000ffff +#define CPU_MAC_DESC_MON_W2_MON_DESC_DONE_NUM2_MASK 0xffff0000 + +/* cpu_mac_dma_weight_cfg Definition */ +#define CPU_MAC_DMA_WEIGHT_CFG_W0_CFG_DMA_RX_WEIGHT1 BIT(8) +#define CPU_MAC_DMA_WEIGHT_CFG_W0_CFG_DMA_RX_WEIGHT0 BIT(0) + +#define CPU_MAC_DMA_WEIGHT_CFG_W0_CFG_DMA_RX_WEIGHT1_MASK 0x00000f00 +#define CPU_MAC_DMA_WEIGHT_CFG_W0_CFG_DMA_RX_WEIGHT0_MASK 0x0000000f + +/* cpu_mac_init Definition */ +#define CPU_MAC_INIT_W0_INIT BIT(0) + +#define CPU_MAC_INIT_W0_INIT_MASK 0x00000001 + +/* cpu_mac_init_done Definition */ +#define CPU_MAC_INIT_DONE_W0_INIT_DONE BIT(0) + +#define CPU_MAC_INIT_DONE_W0_INIT_DONE_MASK 0x00000001 + +/* cpu_mac_parity_ctl Definition */ +#define CPU_MAC_PARITY_CTL_W0_RX_PKT_MSG_FIFO_PARITY_EN BIT(2) +#define CPU_MAC_PARITY_CTL_W0_TX_PKT_FIFO_PARITY_EN BIT(4) +#define CPU_MAC_PARITY_CTL_W0_EXT_RAM_ECC_DETECT_DIS BIT(8) +#define CPU_MAC_PARITY_CTL_W0_CPU_MAC_STATS_RAM_PARITY_EN BIT(0) +#define CPU_MAC_PARITY_CTL_W0_RX_DESC0_CFG_FIFO_PARITY_EN BIT(5) +#define CPU_MAC_PARITY_CTL_W0_RX_PKT_DATA_FIFO_PARITY_EN BIT(1) +#define CPU_MAC_PARITY_CTL_W0_TX_DESC_CFG_FIFO_PARITY_EN BIT(7) +#define CPU_MAC_PARITY_CTL_W0_RX_DESC1_CFG_FIFO_PARITY_EN BIT(6) +#define CPU_MAC_PARITY_CTL_W0_EXT_RAM_ECC_CORRECT_DIS BIT(9) + +#define CPU_MAC_PARITY_CTL_W0_RX_PKT_MSG_FIFO_PARITY_EN_MASK 0x00000004 +#define CPU_MAC_PARITY_CTL_W0_TX_PKT_FIFO_PARITY_EN_MASK 0x00000010 +#define CPU_MAC_PARITY_CTL_W0_EXT_RAM_ECC_DETECT_DIS_MASK 0x00000100 +#define CPU_MAC_PARITY_CTL_W0_CPU_MAC_STATS_RAM_PARITY_EN_MASK 0x00000001 +#define CPU_MAC_PARITY_CTL_W0_RX_DESC0_CFG_FIFO_PARITY_EN_MASK 0x00000020 +#define CPU_MAC_PARITY_CTL_W0_RX_PKT_DATA_FIFO_PARITY_EN_MASK 0x00000002 +#define CPU_MAC_PARITY_CTL_W0_TX_DESC_CFG_FIFO_PARITY_EN_MASK 0x00000080 +#define CPU_MAC_PARITY_CTL_W0_RX_DESC1_CFG_FIFO_PARITY_EN_MASK 0x00000040 +#define CPU_MAC_PARITY_CTL_W0_EXT_RAM_ECC_CORRECT_DIS_MASK 0x00000200 + +/* cpu_mac_ext_ram_cfg Definition */ +#define CPU_MAC_EXT_RAM_CFG_W0_CFG_EXT_RAM_EN BIT(31) +#define CPU_MAC_EXT_RAM_CFG_W0_CFG_EXT_RAM_BASE_SIZE BIT(0) +#define CPU_MAC_EXT_RAM_CFG_W1_CFG_EXT_RAM_BASE_ADDR BIT(0) + +#define CPU_MAC_EXT_RAM_CFG_W0_CFG_EXT_RAM_EN_MASK 0x80000000 +#define CPU_MAC_EXT_RAM_CFG_W0_CFG_EXT_RAM_BASE_SIZE_MASK 0x000003ff +#define CPU_MAC_EXT_RAM_CFG_W1_CFG_EXT_RAM_BASE_ADDR_MASK 0x000fffff + +/* cpu_mac_fifo_ctl Definition */ +#define CPU_MAC_FIFO_CTL_W0_RX_PKT_DATA_FIFO_A_FULL_THRD BIT(0) +#define CPU_MAC_FIFO_CTL_W1_RX_PKT_MSG_FIFO_A_FULL_THRD BIT(0) +#define CPU_MAC_FIFO_CTL_W2_TX_PKT_FIFO_A_FULL_THRD BIT(0) +#define CPU_MAC_FIFO_CTL_W3_RX_PKT_FIFO_A_FULL_THRD BIT(0) + +#define CPU_MAC_FIFO_CTL_W0_RX_PKT_DATA_FIFO_A_FULL_THRD_MASK 0x00001fff +#define CPU_MAC_FIFO_CTL_W1_RX_PKT_MSG_FIFO_A_FULL_THRD_MASK 0x000003ff +#define CPU_MAC_FIFO_CTL_W2_TX_PKT_FIFO_A_FULL_THRD_MASK 0x000007ff +#define CPU_MAC_FIFO_CTL_W3_RX_PKT_FIFO_A_FULL_THRD_MASK 0x000003ff + +/* cpu_mac_gmac_cfg Definition */ +#define CPU_MAC_GMAC_CFG_W0_CFG_RX_CUT_THROUGH_EN BIT(4) +#define CPU_MAC_GMAC_CFG_W0_CFG_RX_UNDERSIZE_DROP_EN BIT(3) +#define CPU_MAC_GMAC_CFG_W0_CFG_RX_ERROR_DROP_EN BIT(5) +#define CPU_MAC_GMAC_CFG_W0_CFG_RX_TS_EN BIT(0) +#define CPU_MAC_GMAC_CFG_W0_CFG_RX_OVERSIZE_DROP_EN BIT(2) +#define CPU_MAC_GMAC_CFG_W0_CFG_RX_PAUSE_DROP_EN BIT(6) +#define CPU_MAC_GMAC_CFG_W0_CFG_RX_OVERRUN_DROP_EN BIT(1) +#define CPU_MAC_GMAC_CFG_W1_CFG_RX_MAX_PKT_LEN_CHK_EN BIT(0) +#define CPU_MAC_GMAC_CFG_W1_CFG_RX_MIN_PKT_LEN BIT(17) +#define CPU_MAC_GMAC_CFG_W1_CFG_RX_MIN_PKT_LEN_CHK_EN BIT(16) +#define CPU_MAC_GMAC_CFG_W1_CFG_RX_MAX_PKT_LEN BIT(1) +#define CPU_MAC_GMAC_CFG_W2_CFG_TX_START_THRD BIT(16) +#define CPU_MAC_GMAC_CFG_W2_CFG_TX_ERR_MASK_OFF BIT(1) +#define CPU_MAC_GMAC_CFG_W2_CFG_TX_PTP_ERR_EN BIT(6) +#define CPU_MAC_GMAC_CFG_W2_CFG_TX_KEEP_TS_EN BIT(12) +#define CPU_MAC_GMAC_CFG_W2_CFG_TX_PAUSE_STALL_EN BIT(4) +#define CPU_MAC_GMAC_CFG_W2_CFG_TX_CUT_THROUGH_EN BIT(10) +#define CPU_MAC_GMAC_CFG_W2_CFG_TX_STRIP_CRC_EN BIT(8) +#define CPU_MAC_GMAC_CFG_W2_CFG_TX_PKT_EN BIT(5) +#define CPU_MAC_GMAC_CFG_W2_CFG_TX_PAD_EN BIT(3) +#define CPU_MAC_GMAC_CFG_W2_CFG_TX_WAIT_CAPTURE_TS BIT(9) +#define CPU_MAC_GMAC_CFG_W2_CFG_TX_HDR_INFO_EN BIT(11) +#define CPU_MAC_GMAC_CFG_W2_CFG_TX_LPI_EN BIT(2) +#define CPU_MAC_GMAC_CFG_W2_CFG_TX_APPEND_CRC_EN BIT(0) +#define CPU_MAC_GMAC_CFG_W3_CFG_TX_SLEEP_TIMER BIT(0) +#define CPU_MAC_GMAC_CFG_W3_CFG_TX_WAKEUP_TIMER BIT(16) + +#define CPU_MAC_GMAC_CFG_W0_CFG_RX_CUT_THROUGH_EN_MASK 0x00000010 +#define CPU_MAC_GMAC_CFG_W0_CFG_RX_UNDERSIZE_DROP_EN_MASK 0x00000008 +#define CPU_MAC_GMAC_CFG_W0_CFG_RX_ERROR_DROP_EN_MASK 0x00000020 +#define CPU_MAC_GMAC_CFG_W0_CFG_RX_TS_EN_MASK 0x00000001 +#define CPU_MAC_GMAC_CFG_W0_CFG_RX_OVERSIZE_DROP_EN_MASK 0x00000004 +#define CPU_MAC_GMAC_CFG_W0_CFG_RX_PAUSE_DROP_EN_MASK 0x00000040 +#define CPU_MAC_GMAC_CFG_W0_CFG_RX_OVERRUN_DROP_EN_MASK 0x00000002 +#define CPU_MAC_GMAC_CFG_W1_CFG_RX_MAX_PKT_LEN_CHK_EN_MASK 0x00000001 +#define CPU_MAC_GMAC_CFG_W1_CFG_RX_MIN_PKT_LEN_MASK 0x00fe0000 +#define CPU_MAC_GMAC_CFG_W1_CFG_RX_MIN_PKT_LEN_CHK_EN_MASK 0x00010000 +#define CPU_MAC_GMAC_CFG_W1_CFG_RX_MAX_PKT_LEN_MASK 0x0000fffe +#define CPU_MAC_GMAC_CFG_W2_CFG_TX_START_THRD_MASK 0x07ff0000 +#define CPU_MAC_GMAC_CFG_W2_CFG_TX_ERR_MASK_OFF_MASK 0x00000002 +#define CPU_MAC_GMAC_CFG_W2_CFG_TX_PTP_ERR_EN_MASK 0x00000040 +#define CPU_MAC_GMAC_CFG_W2_CFG_TX_KEEP_TS_EN_MASK 0x00001000 +#define CPU_MAC_GMAC_CFG_W2_CFG_TX_PAUSE_STALL_EN_MASK 0x00000010 +#define CPU_MAC_GMAC_CFG_W2_CFG_TX_CUT_THROUGH_EN_MASK 0x00000400 +#define CPU_MAC_GMAC_CFG_W2_CFG_TX_STRIP_CRC_EN_MASK 0x00000100 +#define CPU_MAC_GMAC_CFG_W2_CFG_TX_PKT_EN_MASK 0x00000020 +#define CPU_MAC_GMAC_CFG_W2_CFG_TX_PAD_EN_MASK 0x00000008 +#define CPU_MAC_GMAC_CFG_W2_CFG_TX_WAIT_CAPTURE_TS_MASK 0x00000200 +#define CPU_MAC_GMAC_CFG_W2_CFG_TX_HDR_INFO_EN_MASK 0x00000800 +#define CPU_MAC_GMAC_CFG_W2_CFG_TX_LPI_EN_MASK 0x00000004 +#define CPU_MAC_GMAC_CFG_W2_CFG_TX_APPEND_CRC_EN_MASK 0x00000001 +#define CPU_MAC_GMAC_CFG_W3_CFG_TX_SLEEP_TIMER_MASK 0x0000ffff +#define CPU_MAC_GMAC_CFG_W3_CFG_TX_WAKEUP_TIMER_MASK 0xffff0000 + +/* cpu_mac_ram_chk_rec Definition */ +#define CPU_MAC_RAM_CHK_REC_W0_CPU_MAC_STATS_RAM_PARITY_FAIL BIT(31) +#define CPU_MAC_RAM_CHK_REC_W0_CPU_MAC_STATS_RAM_PARITY_FAIL_ADDR BIT(0) + +#define CPU_MAC_RAM_CHK_REC_W0_CPU_MAC_STATS_RAM_PARITY_FAIL_MASK 0x80000000 +#define CPU_MAC_RAM_CHK_REC_W0_CPU_MAC_STATS_RAM_PARITY_FAIL_ADDR_MASK 0x0000003f + +/* cpu_mac_reset Definition */ +#define CPU_MAC_RESET_W0_SOFT_RST_TX BIT(1) +#define CPU_MAC_RESET_W0_SOFT_RST_RX BIT(0) + +#define CPU_MAC_RESET_W0_SOFT_RST_TX_MASK 0x00000002 +#define CPU_MAC_RESET_W0_SOFT_RST_RX_MASK 0x00000001 + +/* cpu_mac_sgmii_auto_neg_cfg Definition */ +#define CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_AN_RESTART BIT(1) +#define CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_LOCAL_SPEED_MODE BIT(7) +#define CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_LINK_TIMER_CNT BIT(16) +#define CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_AN_MODE BIT(2) +#define CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_AN_REMOTE_LINKUP_EN BIT(25) +#define CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_IGNORE_LINK_FAILURE BIT(5) +#define CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_AN_PARALLEL_DETECT_EN BIT(24) +#define CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_TX_XMIT_LOAD_USE_ASYNC_FIFO BIT(14) +#define CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_LOCAL_EEE_ABILITY BIT(9) +#define CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_AN_ENABLE BIT(0) +#define CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_LOCAL_OFFLINE BIT(6) +#define CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_IGNORE_ANEG_ERR BIT(4) +#define CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_TX_CONFIG_REG_BIT14 BIT(13) +#define CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_LOCAL_EEE_CLK_STOP BIT(10) +#define CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_LOCAL_PAUSE_ABILITY BIT(11) + +#define CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_AN_RESTART_MASK 0x00000002 +#define CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_LOCAL_SPEED_MODE_MASK 0x00000180 +#define CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_LINK_TIMER_CNT_MASK 0x00ff0000 +#define CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_AN_MODE_MASK 0x0000000c +#define CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_AN_REMOTE_LINKUP_EN_MASK 0x02000000 +#define CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_IGNORE_LINK_FAILURE_MASK 0x00000020 +#define CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_AN_PARALLEL_DETECT_EN_MASK 0x01000000 +#define CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_TX_XMIT_LOAD_USE_ASYNC_FIFO_MASK 0x00004000 +#define CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_LOCAL_EEE_ABILITY_MASK 0x00000200 +#define CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_AN_ENABLE_MASK 0x00000001 +#define CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_LOCAL_OFFLINE_MASK 0x00000040 +#define CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_IGNORE_ANEG_ERR_MASK 0x00000010 +#define CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_TX_CONFIG_REG_BIT14_MASK 0x00002000 +#define CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_LOCAL_EEE_CLK_STOP_MASK 0x00000400 +#define CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_LOCAL_PAUSE_ABILITY_MASK 0x00001800 + +/* cpu_mac_reserved Definition */ +#define CPU_MAC_RESERVED_W0_RESERVED BIT(0) + +#define CPU_MAC_RESERVED_W0_RESERVED_MASK 0xffffffff + +/* cpu_mac_gmac_mon Definition */ +#define CPU_MAC_GMAC_MON_W0_MON_TX_LPI_STATE BIT(6) +#define CPU_MAC_GMAC_MON_W0_MON_RX_METER_TOKEN BIT(8) +#define CPU_MAC_GMAC_MON_W0_MON_RX_PKT_STATE BIT(0) +#define CPU_MAC_GMAC_MON_W1_GMAC_RX_BUF_FULL_DROP_CNT BIT(20) +#define CPU_MAC_GMAC_MON_W1_GMAC_RX_FILTER_DROP_CNT BIT(24) +#define CPU_MAC_GMAC_MON_W1_MON_TX_LPI_STATUS BIT(0) +#define CPU_MAC_GMAC_MON_W1_MON_RX_BUF_RD_STATE BIT(2) +#define CPU_MAC_GMAC_MON_W1_MON_TX_POP_STATE BIT(5) +#define CPU_MAC_GMAC_MON_W1_GMAC_RX_RUNT_DROP_CNT BIT(16) +#define CPU_MAC_GMAC_MON_W1_MON_TX_STATS_UNDERRUN BIT(1) +#define CPU_MAC_GMAC_MON_W1_MON_RX_PKT_LEN BIT(8) +#define CPU_MAC_GMAC_MON_W1_GMAC_RX_PAUSE_DROP_CNT BIT(28) + +#define CPU_MAC_GMAC_MON_W0_MON_TX_LPI_STATE_MASK 0x000000c0 +#define CPU_MAC_GMAC_MON_W0_MON_RX_METER_TOKEN_MASK 0xffffff00 +#define CPU_MAC_GMAC_MON_W0_MON_RX_PKT_STATE_MASK 0x0000000f +#define CPU_MAC_GMAC_MON_W1_GMAC_RX_BUF_FULL_DROP_CNT_MASK 0x00f00000 +#define CPU_MAC_GMAC_MON_W1_GMAC_RX_FILTER_DROP_CNT_MASK 0x0f000000 +#define CPU_MAC_GMAC_MON_W1_MON_TX_LPI_STATUS_MASK 0x00000001 +#define CPU_MAC_GMAC_MON_W1_MON_RX_BUF_RD_STATE_MASK 0x0000001c +#define CPU_MAC_GMAC_MON_W1_MON_TX_POP_STATE_MASK 0x000000e0 +#define CPU_MAC_GMAC_MON_W1_GMAC_RX_RUNT_DROP_CNT_MASK 0x000f0000 +#define CPU_MAC_GMAC_MON_W1_MON_TX_STATS_UNDERRUN_MASK 0x00000002 +#define CPU_MAC_GMAC_MON_W1_MON_RX_PKT_LEN_MASK 0x0000ff00 +#define CPU_MAC_GMAC_MON_W1_GMAC_RX_PAUSE_DROP_CNT_MASK 0xf0000000 + +/* cpu_mac_credit_ctl Definition */ +#define CPU_MAC_CREDIT_CTL_W0_CPU_MAC_CPU_RAM_CREDIT_THRD BIT(0) + +#define CPU_MAC_CREDIT_CTL_W0_CPU_MAC_CPU_RAM_CREDIT_THRD_MASK 0x000000ff + +/* cpu_mac_credit_status Definition */ +#define CPU_MAC_CREDIT_STATUS_W0_CPU_MAC_CPU_RAM_CREDIT_USED BIT(0) + +#define CPU_MAC_CREDIT_STATUS_W0_CPU_MAC_CPU_RAM_CREDIT_USED_MASK 0x000000ff + +/* cpu_mac_pause_cfg Definition */ +#define CPU_MAC_PAUSE_CFG_W0_CFG_RX_PAUSE_TIMER_ADJ_VALUE BIT(1) +#define CPU_MAC_PAUSE_CFG_W0_CFG_RX_NORM_PAUSE_EN BIT(0) +#define CPU_MAC_PAUSE_CFG_W0_CFG_RX_PAUSE_TIMER_DEC_VALUE BIT(11) +#define CPU_MAC_PAUSE_CFG_W1_CFG_TX_PAUSE_TIMER_ADJ_VALUE BIT(1) +#define CPU_MAC_PAUSE_CFG_W1_CFG_TX_PAUSE_TIMER_DEC_VALUE BIT(18) +#define CPU_MAC_PAUSE_CFG_W1_CFG_TX_PAUSE_EN BIT(0) +#define CPU_MAC_PAUSE_CFG_W2_CFG_TX_PAUSE_MAC_SA_31_0 BIT(0) +#define CPU_MAC_PAUSE_CFG_W3_CFG_TX_PAUSE_MAC_SA_47_32 BIT(0) +#define CPU_MAC_PAUSE_CFG_W3_CFG_TX_PAUSE_QUANTA BIT(16) + +#define CPU_MAC_PAUSE_CFG_W0_CFG_RX_PAUSE_TIMER_ADJ_VALUE_MASK 0x000007fe +#define CPU_MAC_PAUSE_CFG_W0_CFG_RX_NORM_PAUSE_EN_MASK 0x00000001 +#define CPU_MAC_PAUSE_CFG_W0_CFG_RX_PAUSE_TIMER_DEC_VALUE_MASK 0x0007f800 +#define CPU_MAC_PAUSE_CFG_W1_CFG_TX_PAUSE_TIMER_ADJ_VALUE_MASK 0x0003fffe +#define CPU_MAC_PAUSE_CFG_W1_CFG_TX_PAUSE_TIMER_DEC_VALUE_MASK 0x03fc0000 +#define CPU_MAC_PAUSE_CFG_W1_CFG_TX_PAUSE_EN_MASK 0x00000001 +#define CPU_MAC_PAUSE_CFG_W2_CFG_TX_PAUSE_MAC_SA_31_0_MASK 0x00000001 +#define CPU_MAC_PAUSE_CFG_W3_CFG_TX_PAUSE_MAC_SA_47_32_MASK 0x00000001 +#define CPU_MAC_PAUSE_CFG_W3_CFG_TX_PAUSE_QUANTA_MASK 0xffff0000 + +/* cpu_mac_pause_mon Definition */ +#define CPU_MAC_PAUSE_MON_W0_MON_TX_PAUSE_TIMER BIT(0) +#define CPU_MAC_PAUSE_MON_W1_MON_RX_PAUSE_TIMER BIT(0) +#define CPU_MAC_PAUSE_MON_W2_MON_TX_PAUSE_CUR_STATUS BIT(0) +#define CPU_MAC_PAUSE_MON_W2_MON_TX_PAUSE_LOG_STATUS BIT(1) + +#define CPU_MAC_PAUSE_MON_W0_MON_TX_PAUSE_TIMER_MASK 0x0001ffff +#define CPU_MAC_PAUSE_MON_W1_MON_RX_PAUSE_TIMER_MASK 0x0000ffff +#define CPU_MAC_PAUSE_MON_W2_MON_TX_PAUSE_CUR_STATUS_MASK 0x00000001 +#define CPU_MAC_PAUSE_MON_W2_MON_TX_PAUSE_LOG_STATUS_MASK 0x00000002 + +/* cpu_mac_sgmii_cfg Definition */ +#define CPU_MAC_SGMII_CFG_W0_CFG_TX_EVEN_IGNORE BIT(3) +#define CPU_MAC_SGMII_CFG_W0_CFG_TX_IPG_LEN BIT(14) +#define CPU_MAC_SGMII_CFG_W0_CFG_TX_PREAMBLE_LEN BIT(18) +#define CPU_MAC_SGMII_CFG_W0_CFG_UNIDIRECTION_EN BIT(4) +#define CPU_MAC_SGMII_CFG_W0_CFG_MII_RX_CHK_LINK_FOR_SOP BIT(31) +#define CPU_MAC_SGMII_CFG_W0_CFG_FORCE_RELOCK BIT(0) +#define CPU_MAC_SGMII_CFG_W0_CFG_FORCE_SIGNAL_DETECT BIT(1) +#define CPU_MAC_SGMII_CFG_W0_CFG_TX_REPLICATE_CNT BIT(22) +#define CPU_MAC_SGMII_CFG_W0_CFG_MII_RX_LINK_FILTER_TIMER BIT(6) +#define CPU_MAC_SGMII_CFG_W0_CFG_SIG_DET_ACTIVE_VALUE BIT(2) +#define CPU_MAC_SGMII_CFG_W0_CFG_MII_RX_LINK_FILTER_EN BIT(5) +#define CPU_MAC_SGMII_CFG_W1_CFG_MII_RX_SAMPLE_CNT BIT(22) +#define CPU_MAC_SGMII_CFG_W1_CFG_TX_THRESHOLD BIT(0) +#define CPU_MAC_SGMII_CFG_W1_CFG_MII_TX_A_FULL_THRD BIT(5) + +#define CPU_MAC_SGMII_CFG_W0_CFG_TX_EVEN_IGNORE_MASK 0x00000008 +#define CPU_MAC_SGMII_CFG_W0_CFG_TX_IPG_LEN_MASK 0x0003c000 +#define CPU_MAC_SGMII_CFG_W0_CFG_TX_PREAMBLE_LEN_MASK 0x003c0000 +#define CPU_MAC_SGMII_CFG_W0_CFG_UNIDIRECTION_EN_MASK 0x00000010 +#define CPU_MAC_SGMII_CFG_W0_CFG_MII_RX_CHK_LINK_FOR_SOP_MASK 0x80000000 +#define CPU_MAC_SGMII_CFG_W0_CFG_FORCE_RELOCK_MASK 0x00000001 +#define CPU_MAC_SGMII_CFG_W0_CFG_FORCE_SIGNAL_DETECT_MASK 0x00000002 +#define CPU_MAC_SGMII_CFG_W0_CFG_TX_REPLICATE_CNT_MASK 0x1fc00000 +#define CPU_MAC_SGMII_CFG_W0_CFG_MII_RX_LINK_FILTER_TIMER_MASK 0x00003fc0 +#define CPU_MAC_SGMII_CFG_W0_CFG_SIG_DET_ACTIVE_VALUE_MASK 0x00000004 +#define CPU_MAC_SGMII_CFG_W0_CFG_MII_RX_LINK_FILTER_EN_MASK 0x00000020 +#define CPU_MAC_SGMII_CFG_W1_CFG_MII_RX_SAMPLE_CNT_MASK 0x1fc00000 +#define CPU_MAC_SGMII_CFG_W1_CFG_TX_THRESHOLD_MASK 0x0000001f +#define CPU_MAC_SGMII_CFG_W1_CFG_MII_TX_A_FULL_THRD_MASK 0x000003e0 + +/* cpu_mac_sgmii_mon Definition */ +#define CPU_MAC_SGMII_MON_W0_MON_SGMII_TX_CODE_STATE BIT(23) +#define CPU_MAC_SGMII_MON_W0_MON_SGMII_TX_SOP_FLAG BIT(18) +#define CPU_MAC_SGMII_MON_W0_MON_SGMII_TX_EOP_FLAG BIT(19) +#define CPU_MAC_SGMII_MON_W0_MON_SGMII_RX_EOP_FLAG BIT(9) +#define CPU_MAC_SGMII_MON_W0_MON_SGMII_RX_SFD_FLAG BIT(11) +#define CPU_MAC_SGMII_MON_W0_MON_SGMII_TX_LPI_STATE BIT(20) +#define CPU_MAC_SGMII_MON_W0_MON_SGMII_RX_LPI_STATE BIT(12) +#define CPU_MAC_SGMII_MON_W0_MON_SGMII_RX_PKT_STATE BIT(15) +#define CPU_MAC_SGMII_MON_W0_MON_ANEG_STATE BIT(0) +#define CPU_MAC_SGMII_MON_W0_MON_CODE_ERR_CNT BIT(4) +#define CPU_MAC_SGMII_MON_W0_MON_LINK_STATUS BIT(8) +#define CPU_MAC_SGMII_MON_W0_MON_SGMII_RX_SOP_FLAG BIT(10) +#define CPU_MAC_SGMII_MON_W1_MON_AN_RX_REMOTE_CFG BIT(0) + +#define CPU_MAC_SGMII_MON_W0_MON_SGMII_TX_CODE_STATE_MASK 0x03800000 +#define CPU_MAC_SGMII_MON_W0_MON_SGMII_TX_SOP_FLAG_MASK 0x00040000 +#define CPU_MAC_SGMII_MON_W0_MON_SGMII_TX_EOP_FLAG_MASK 0x00080000 +#define CPU_MAC_SGMII_MON_W0_MON_SGMII_RX_EOP_FLAG_MASK 0x00000200 +#define CPU_MAC_SGMII_MON_W0_MON_SGMII_RX_SFD_FLAG_MASK 0x00000800 +#define CPU_MAC_SGMII_MON_W0_MON_SGMII_TX_LPI_STATE_MASK 0x00700000 +#define CPU_MAC_SGMII_MON_W0_MON_SGMII_RX_LPI_STATE_MASK 0x00007000 +#define CPU_MAC_SGMII_MON_W0_MON_SGMII_RX_PKT_STATE_MASK 0x00038000 +#define CPU_MAC_SGMII_MON_W0_MON_ANEG_STATE_MASK 0x00000007 +#define CPU_MAC_SGMII_MON_W0_MON_CODE_ERR_CNT_MASK 0x000000f0 +#define CPU_MAC_SGMII_MON_W0_MON_LINK_STATUS_MASK 0x00000100 +#define CPU_MAC_SGMII_MON_W0_MON_SGMII_RX_SOP_FLAG_MASK 0x00000400 +#define CPU_MAC_SGMII_MON_W1_MON_AN_RX_REMOTE_CFG_MASK 0x0000ffff + +/* cpu_mac_stats_cfg Definition */ +#define CPU_MAC_STATS_CFG_W0_CFG_GMAC_STATS64_B_PKT_HI_PRI BIT(4) +#define CPU_MAC_STATS_CFG_W0_CFG_GMAC_STATS_INCR_SATURATE BIT(1) +#define CPU_MAC_STATS_CFG_W0_CFG_GMAC_STATS_INCR_HOLD BIT(2) +#define CPU_MAC_STATS_CFG_W0_CFG_GMAC_STATS_CLEAR_ON_READ BIT(0) +#define CPU_MAC_STATS_CFG_W0_CFG_GMAC_STATS_OVER_WRITE_EN BIT(3) +#define CPU_MAC_STATS_CFG_W1_CFG_GMAC_STATS_MTU1 BIT(0) +#define CPU_MAC_STATS_CFG_W1_CFG_GMAC_STATS_MTU2 BIT(16) + +#define CPU_MAC_STATS_CFG_W0_CFG_GMAC_STATS64_B_PKT_HI_PRI_MASK 0x00000010 +#define CPU_MAC_STATS_CFG_W0_CFG_GMAC_STATS_INCR_SATURATE_MASK 0x00000002 +#define CPU_MAC_STATS_CFG_W0_CFG_GMAC_STATS_INCR_HOLD_MASK 0x00000004 +#define CPU_MAC_STATS_CFG_W0_CFG_GMAC_STATS_CLEAR_ON_READ_MASK 0x00000001 +#define CPU_MAC_STATS_CFG_W0_CFG_GMAC_STATS_OVER_WRITE_EN_MASK 0x00000008 +#define CPU_MAC_STATS_CFG_W1_CFG_GMAC_STATS_MTU1_MASK 0x00003fff +#define CPU_MAC_STATS_CFG_W1_CFG_GMAC_STATS_MTU2_MASK 0x3fff0000 + +/* cpu_mac_interrupt_func Definition */ +#define CPU_MAC_INTERRUPT_FUNC_W0_VALUE_SET0_CPU_MAC_INTERRUPT_FUNC BIT(0) +#define CPU_MAC_INTERRUPT_FUNC_W1_VALUE_RESET0_CPU_MAC_INTERRUPT_FUNC BIT(0) +#define CPU_MAC_INTERRUPT_FUNC_W2_MASK_SET0_CPU_MAC_INTERRUPT_FUNC BIT(0) +#define CPU_MAC_INTERRUPT_FUNC_W3_MASK_RESET0_CPU_MAC_INTERRUPT_FUNC BIT(0) + +#define CPU_MAC_INTERRUPT_FUNC_W0_VALUE_SET0_CPU_MAC_INTERRUPT_FUNC_MASK 0x000000ff +#define CPU_MAC_INTERRUPT_FUNC_W1_VALUE_RESET0_CPU_MAC_INTERRUPT_FUNC_MASK 0x000000ff +#define CPU_MAC_INTERRUPT_FUNC_W2_MASK_SET0_CPU_MAC_INTERRUPT_FUNC_MASK 0x000000ff +#define CPU_MAC_INTERRUPT_FUNC_W3_MASK_RESET0_CPU_MAC_INTERRUPT_FUNC_MASK 0x000000ff + +/* cpu_mac_interrupt_normal Definition */ +#define CPU_MAC_INTERRUPT_NORMAL_W0_VALUE_SET0_CPU_MAC_INTERRUPT_NORMAL BIT(0) +#define CPU_MAC_INTERRUPT_NORMAL_W1_VALUE_RESET0_CPU_MAC_INTERRUPT_NORMAL BIT(0) +#define CPU_MAC_INTERRUPT_NORMAL_W2_MASK_SET0_CPU_MAC_INTERRUPT_NORMAL BIT(0) +#define CPU_MAC_INTERRUPT_NORMAL_W3_MASK_RESET0_CPU_MAC_INTERRUPT_NORMAL BIT(0) + +#define CPU_MAC_INTERRUPT_NORMAL_W0_VALUE_SET0_CPU_MAC_INTERRUPT_NORMAL_MASK 0xffffffff +#define CPU_MAC_INTERRUPT_NORMAL_W1_VALUE_RESET0_CPU_MAC_INTERRUPT_NORMAL_MASK 0xffffffff +#define CPU_MAC_INTERRUPT_NORMAL_W2_MASK_SET0_CPU_MAC_INTERRUPT_NORMAL_MASK 0xffffffff +#define CPU_MAC_INTERRUPT_NORMAL_W3_MASK_RESET0_CPU_MAC_INTERRUPT_NORMAL_MASK 0xffffffff + +/* cpu_mac_fifo_status Definition */ +#define CPU_MAC_FIFO_STATUS_W0_RX_PKT_MSG_FIFO_FIFO_DEPTH BIT(0) +#define CPU_MAC_FIFO_STATUS_W0_RX_PKT_DATA_FIFO_FIFO_DEPTH BIT(20) +#define CPU_MAC_FIFO_STATUS_W0_TX_DESC_ACK_FIFO_FIFO_DEPTH BIT(10) +#define CPU_MAC_FIFO_STATUS_W0_EXT_RAM_RD_TRACK_FIFO_FIFO_DEPTH BIT(16) +#define CPU_MAC_FIFO_STATUS_W1_RX_DESC0_ACK_FIFO_FIFO_DEPTH BIT(12) +#define CPU_MAC_FIFO_STATUS_W1_RX_DESC1_CFG_FIFO_FIFO_DEPTH BIT(18) +#define CPU_MAC_FIFO_STATUS_W1_RX_DESC0_CFG_FIFO_FIFO_DEPTH BIT(6) +#define CPU_MAC_FIFO_STATUS_W1_RX_DESC1_ACK_FIFO_FIFO_DEPTH BIT(24) +#define CPU_MAC_FIFO_STATUS_W1_TX_DESC_CFG_FIFO_FIFO_DEPTH BIT(0) +#define CPU_MAC_FIFO_STATUS_W2_TX_PKT_FIFO_FIFO_DEPTH BIT(16) +#define CPU_MAC_FIFO_STATUS_W2_RX_PKT_FIFO_FIFO_DEPTH BIT(0) + +#define CPU_MAC_FIFO_STATUS_W0_RX_PKT_MSG_FIFO_FIFO_DEPTH_MASK 0x000003ff +#define CPU_MAC_FIFO_STATUS_W0_RX_PKT_DATA_FIFO_FIFO_DEPTH_MASK 0xfff00000 +#define CPU_MAC_FIFO_STATUS_W0_TX_DESC_ACK_FIFO_FIFO_DEPTH_MASK 0x0000fc00 +#define CPU_MAC_FIFO_STATUS_W0_EXT_RAM_RD_TRACK_FIFO_FIFO_DEPTH_MASK 0x000f0000 +#define CPU_MAC_FIFO_STATUS_W1_RX_DESC0_ACK_FIFO_FIFO_DEPTH_MASK 0x0003f000 +#define CPU_MAC_FIFO_STATUS_W1_RX_DESC1_CFG_FIFO_FIFO_DEPTH_MASK 0x00fc0000 +#define CPU_MAC_FIFO_STATUS_W1_RX_DESC0_CFG_FIFO_FIFO_DEPTH_MASK 0x00000fc0 +#define CPU_MAC_FIFO_STATUS_W1_RX_DESC1_ACK_FIFO_FIFO_DEPTH_MASK 0x3f000000 +#define CPU_MAC_FIFO_STATUS_W1_TX_DESC_CFG_FIFO_FIFO_DEPTH_MASK 0x0000003f +#define CPU_MAC_FIFO_STATUS_W2_TX_PKT_FIFO_FIFO_DEPTH_MASK 0x03ff0000 +#define CPU_MAC_FIFO_STATUS_W2_RX_PKT_FIFO_FIFO_DEPTH_MASK 0x000003ff + +struct cpu_mac_mems { + u32 tx_pkt_fifo_0[3]; /* 0x00004000 */ + u32 tx_pkt_fifo_0_rsv3; + u32 tx_pkt_fifo_1[3]; /* 0x00004010 */ + u32 tx_pkt_fifo_1_rsv3; + u32 tx_pkt_fifo_2[3]; /* 0x00004020 */ + u32 tx_pkt_fifo_2_rsv3; + u32 tx_pkt_fifo_3[3]; /* 0x00004030 */ + u32 tx_pkt_fifo_3_rsv3; + u32 tx_pkt_fifo_4[3]; /* 0x00004040 */ + u32 tx_pkt_fifo_4_rsv3; + u32 tx_pkt_fifo_5[3]; /* 0x00004050 */ + u32 tx_pkt_fifo_5_rsv3; + u32 tx_pkt_fifo_6[3]; /* 0x00004060 */ + u32 tx_pkt_fifo_6_rsv3; + u32 tx_pkt_fifo_7[3]; /* 0x00004070 */ + u32 tx_pkt_fifo_7_rsv3; + u32 tx_pkt_fifo_8[3]; /* 0x00004080 */ + u32 tx_pkt_fifo_8_rsv3; + u32 tx_pkt_fifo_9[3]; /* 0x00004090 */ + u32 tx_pkt_fifo_9_rsv3; + u32 tx_pkt_fifo_10[3]; /* 0x000040a0 */ + u32 tx_pkt_fifo_10_rsv3; + u32 tx_pkt_fifo_11[3]; /* 0x000040b0 */ + u32 tx_pkt_fifo_11_rsv3; + u32 tx_pkt_fifo_12[3]; /* 0x000040c0 */ + u32 tx_pkt_fifo_12_rsv3; + u32 tx_pkt_fifo_13[3]; /* 0x000040d0 */ + u32 tx_pkt_fifo_13_rsv3; + u32 tx_pkt_fifo_14[3]; /* 0x000040e0 */ + u32 tx_pkt_fifo_14_rsv3; + u32 tx_pkt_fifo_15[3]; /* 0x000040f0 */ + u32 tx_pkt_fifo_15_rsv3; + u32 tx_pkt_fifo_16[3]; /* 0x00004100 */ + u32 tx_pkt_fifo_16_rsv3; + u32 tx_pkt_fifo_17[3]; /* 0x00004110 */ + u32 tx_pkt_fifo_17_rsv3; + u32 tx_pkt_fifo_18[3]; /* 0x00004120 */ + u32 tx_pkt_fifo_18_rsv3; + u32 tx_pkt_fifo_19[3]; /* 0x00004130 */ + u32 tx_pkt_fifo_19_rsv3; + u32 tx_pkt_fifo_20[3]; /* 0x00004140 */ + u32 tx_pkt_fifo_20_rsv3; + u32 tx_pkt_fifo_21[3]; /* 0x00004150 */ + u32 tx_pkt_fifo_21_rsv3; + u32 tx_pkt_fifo_22[3]; /* 0x00004160 */ + u32 tx_pkt_fifo_22_rsv3; + u32 tx_pkt_fifo_23[3]; /* 0x00004170 */ + u32 tx_pkt_fifo_23_rsv3; + u32 tx_pkt_fifo_24[3]; /* 0x00004180 */ + u32 tx_pkt_fifo_24_rsv3; + u32 tx_pkt_fifo_25[3]; /* 0x00004190 */ + u32 tx_pkt_fifo_25_rsv3; + u32 tx_pkt_fifo_26[3]; /* 0x000041a0 */ + u32 tx_pkt_fifo_26_rsv3; + u32 tx_pkt_fifo_27[3]; /* 0x000041b0 */ + u32 tx_pkt_fifo_27_rsv3; + u32 tx_pkt_fifo_28[3]; /* 0x000041c0 */ + u32 tx_pkt_fifo_28_rsv3; + u32 tx_pkt_fifo_29[3]; /* 0x000041d0 */ + u32 tx_pkt_fifo_29_rsv3; + u32 tx_pkt_fifo_30[3]; /* 0x000041e0 */ + u32 tx_pkt_fifo_30_rsv3; + u32 tx_pkt_fifo_31[3]; /* 0x000041f0 */ + u32 tx_pkt_fifo_31_rsv3; + u32 tx_pkt_fifo_32[3]; /* 0x00004200 */ + u32 tx_pkt_fifo_32_rsv3; + u32 tx_pkt_fifo_33[3]; /* 0x00004210 */ + u32 tx_pkt_fifo_33_rsv3; + u32 tx_pkt_fifo_34[3]; /* 0x00004220 */ + u32 tx_pkt_fifo_34_rsv3; + u32 tx_pkt_fifo_35[3]; /* 0x00004230 */ + u32 tx_pkt_fifo_35_rsv3; + u32 tx_pkt_fifo_36[3]; /* 0x00004240 */ + u32 tx_pkt_fifo_36_rsv3; + u32 tx_pkt_fifo_37[3]; /* 0x00004250 */ + u32 tx_pkt_fifo_37_rsv3; + u32 tx_pkt_fifo_38[3]; /* 0x00004260 */ + u32 tx_pkt_fifo_38_rsv3; + u32 tx_pkt_fifo_39[3]; /* 0x00004270 */ + u32 tx_pkt_fifo_39_rsv3; + u32 tx_pkt_fifo_40[3]; /* 0x00004280 */ + u32 tx_pkt_fifo_40_rsv3; + u32 tx_pkt_fifo_41[3]; /* 0x00004290 */ + u32 tx_pkt_fifo_41_rsv3; + u32 tx_pkt_fifo_42[3]; /* 0x000042a0 */ + u32 tx_pkt_fifo_42_rsv3; + u32 tx_pkt_fifo_43[3]; /* 0x000042b0 */ + u32 tx_pkt_fifo_43_rsv3; + u32 tx_pkt_fifo_44[3]; /* 0x000042c0 */ + u32 tx_pkt_fifo_44_rsv3; + u32 tx_pkt_fifo_45[3]; /* 0x000042d0 */ + u32 tx_pkt_fifo_45_rsv3; + u32 tx_pkt_fifo_46[3]; /* 0x000042e0 */ + u32 tx_pkt_fifo_46_rsv3; + u32 tx_pkt_fifo_47[3]; /* 0x000042f0 */ + u32 tx_pkt_fifo_47_rsv3; + u32 tx_pkt_fifo_48[3]; /* 0x00004300 */ + u32 tx_pkt_fifo_48_rsv3; + u32 tx_pkt_fifo_49[3]; /* 0x00004310 */ + u32 tx_pkt_fifo_49_rsv3; + u32 tx_pkt_fifo_50[3]; /* 0x00004320 */ + u32 tx_pkt_fifo_50_rsv3; + u32 tx_pkt_fifo_51[3]; /* 0x00004330 */ + u32 tx_pkt_fifo_51_rsv3; + u32 tx_pkt_fifo_52[3]; /* 0x00004340 */ + u32 tx_pkt_fifo_52_rsv3; + u32 tx_pkt_fifo_53[3]; /* 0x00004350 */ + u32 tx_pkt_fifo_53_rsv3; + u32 tx_pkt_fifo_54[3]; /* 0x00004360 */ + u32 tx_pkt_fifo_54_rsv3; + u32 tx_pkt_fifo_55[3]; /* 0x00004370 */ + u32 tx_pkt_fifo_55_rsv3; + u32 tx_pkt_fifo_56[3]; /* 0x00004380 */ + u32 tx_pkt_fifo_56_rsv3; + u32 tx_pkt_fifo_57[3]; /* 0x00004390 */ + u32 tx_pkt_fifo_57_rsv3; + u32 tx_pkt_fifo_58[3]; /* 0x000043a0 */ + u32 tx_pkt_fifo_58_rsv3; + u32 tx_pkt_fifo_59[3]; /* 0x000043b0 */ + u32 tx_pkt_fifo_59_rsv3; + u32 tx_pkt_fifo_60[3]; /* 0x000043c0 */ + u32 tx_pkt_fifo_60_rsv3; + u32 tx_pkt_fifo_61[3]; /* 0x000043d0 */ + u32 tx_pkt_fifo_61_rsv3; + u32 tx_pkt_fifo_62[3]; /* 0x000043e0 */ + u32 tx_pkt_fifo_62_rsv3; + u32 tx_pkt_fifo_63[3]; /* 0x000043f0 */ + u32 tx_pkt_fifo_63_rsv3; + u32 tx_pkt_fifo_64[3]; /* 0x00004400 */ + u32 tx_pkt_fifo_64_rsv3; + u32 tx_pkt_fifo_65[3]; /* 0x00004410 */ + u32 tx_pkt_fifo_65_rsv3; + u32 tx_pkt_fifo_66[3]; /* 0x00004420 */ + u32 tx_pkt_fifo_66_rsv3; + u32 tx_pkt_fifo_67[3]; /* 0x00004430 */ + u32 tx_pkt_fifo_67_rsv3; + u32 tx_pkt_fifo_68[3]; /* 0x00004440 */ + u32 tx_pkt_fifo_68_rsv3; + u32 tx_pkt_fifo_69[3]; /* 0x00004450 */ + u32 tx_pkt_fifo_69_rsv3; + u32 tx_pkt_fifo_70[3]; /* 0x00004460 */ + u32 tx_pkt_fifo_70_rsv3; + u32 tx_pkt_fifo_71[3]; /* 0x00004470 */ + u32 tx_pkt_fifo_71_rsv3; + u32 tx_pkt_fifo_72[3]; /* 0x00004480 */ + u32 tx_pkt_fifo_72_rsv3; + u32 tx_pkt_fifo_73[3]; /* 0x00004490 */ + u32 tx_pkt_fifo_73_rsv3; + u32 tx_pkt_fifo_74[3]; /* 0x000044a0 */ + u32 tx_pkt_fifo_74_rsv3; + u32 tx_pkt_fifo_75[3]; /* 0x000044b0 */ + u32 tx_pkt_fifo_75_rsv3; + u32 tx_pkt_fifo_76[3]; /* 0x000044c0 */ + u32 tx_pkt_fifo_76_rsv3; + u32 tx_pkt_fifo_77[3]; /* 0x000044d0 */ + u32 tx_pkt_fifo_77_rsv3; + u32 tx_pkt_fifo_78[3]; /* 0x000044e0 */ + u32 tx_pkt_fifo_78_rsv3; + u32 tx_pkt_fifo_79[3]; /* 0x000044f0 */ + u32 tx_pkt_fifo_79_rsv3; + u32 tx_pkt_fifo_80[3]; /* 0x00004500 */ + u32 tx_pkt_fifo_80_rsv3; + u32 tx_pkt_fifo_81[3]; /* 0x00004510 */ + u32 tx_pkt_fifo_81_rsv3; + u32 tx_pkt_fifo_82[3]; /* 0x00004520 */ + u32 tx_pkt_fifo_82_rsv3; + u32 tx_pkt_fifo_83[3]; /* 0x00004530 */ + u32 tx_pkt_fifo_83_rsv3; + u32 tx_pkt_fifo_84[3]; /* 0x00004540 */ + u32 tx_pkt_fifo_84_rsv3; + u32 tx_pkt_fifo_85[3]; /* 0x00004550 */ + u32 tx_pkt_fifo_85_rsv3; + u32 tx_pkt_fifo_86[3]; /* 0x00004560 */ + u32 tx_pkt_fifo_86_rsv3; + u32 tx_pkt_fifo_87[3]; /* 0x00004570 */ + u32 tx_pkt_fifo_87_rsv3; + u32 tx_pkt_fifo_88[3]; /* 0x00004580 */ + u32 tx_pkt_fifo_88_rsv3; + u32 tx_pkt_fifo_89[3]; /* 0x00004590 */ + u32 tx_pkt_fifo_89_rsv3; + u32 tx_pkt_fifo_90[3]; /* 0x000045a0 */ + u32 tx_pkt_fifo_90_rsv3; + u32 tx_pkt_fifo_91[3]; /* 0x000045b0 */ + u32 tx_pkt_fifo_91_rsv3; + u32 tx_pkt_fifo_92[3]; /* 0x000045c0 */ + u32 tx_pkt_fifo_92_rsv3; + u32 tx_pkt_fifo_93[3]; /* 0x000045d0 */ + u32 tx_pkt_fifo_93_rsv3; + u32 tx_pkt_fifo_94[3]; /* 0x000045e0 */ + u32 tx_pkt_fifo_94_rsv3; + u32 tx_pkt_fifo_95[3]; /* 0x000045f0 */ + u32 tx_pkt_fifo_95_rsv3; + u32 tx_pkt_fifo_96[3]; /* 0x00004600 */ + u32 tx_pkt_fifo_96_rsv3; + u32 tx_pkt_fifo_97[3]; /* 0x00004610 */ + u32 tx_pkt_fifo_97_rsv3; + u32 tx_pkt_fifo_98[3]; /* 0x00004620 */ + u32 tx_pkt_fifo_98_rsv3; + u32 tx_pkt_fifo_99[3]; /* 0x00004630 */ + u32 tx_pkt_fifo_99_rsv3; + u32 tx_pkt_fifo_100[3]; /* 0x00004640 */ + u32 tx_pkt_fifo_100_rsv3; + u32 tx_pkt_fifo_101[3]; /* 0x00004650 */ + u32 tx_pkt_fifo_101_rsv3; + u32 tx_pkt_fifo_102[3]; /* 0x00004660 */ + u32 tx_pkt_fifo_102_rsv3; + u32 tx_pkt_fifo_103[3]; /* 0x00004670 */ + u32 tx_pkt_fifo_103_rsv3; + u32 tx_pkt_fifo_104[3]; /* 0x00004680 */ + u32 tx_pkt_fifo_104_rsv3; + u32 tx_pkt_fifo_105[3]; /* 0x00004690 */ + u32 tx_pkt_fifo_105_rsv3; + u32 tx_pkt_fifo_106[3]; /* 0x000046a0 */ + u32 tx_pkt_fifo_106_rsv3; + u32 tx_pkt_fifo_107[3]; /* 0x000046b0 */ + u32 tx_pkt_fifo_107_rsv3; + u32 tx_pkt_fifo_108[3]; /* 0x000046c0 */ + u32 tx_pkt_fifo_108_rsv3; + u32 tx_pkt_fifo_109[3]; /* 0x000046d0 */ + u32 tx_pkt_fifo_109_rsv3; + u32 tx_pkt_fifo_110[3]; /* 0x000046e0 */ + u32 tx_pkt_fifo_110_rsv3; + u32 tx_pkt_fifo_111[3]; /* 0x000046f0 */ + u32 tx_pkt_fifo_111_rsv3; + u32 tx_pkt_fifo_112[3]; /* 0x00004700 */ + u32 tx_pkt_fifo_112_rsv3; + u32 tx_pkt_fifo_113[3]; /* 0x00004710 */ + u32 tx_pkt_fifo_113_rsv3; + u32 tx_pkt_fifo_114[3]; /* 0x00004720 */ + u32 tx_pkt_fifo_114_rsv3; + u32 tx_pkt_fifo_115[3]; /* 0x00004730 */ + u32 tx_pkt_fifo_115_rsv3; + u32 tx_pkt_fifo_116[3]; /* 0x00004740 */ + u32 tx_pkt_fifo_116_rsv3; + u32 tx_pkt_fifo_117[3]; /* 0x00004750 */ + u32 tx_pkt_fifo_117_rsv3; + u32 tx_pkt_fifo_118[3]; /* 0x00004760 */ + u32 tx_pkt_fifo_118_rsv3; + u32 tx_pkt_fifo_119[3]; /* 0x00004770 */ + u32 tx_pkt_fifo_119_rsv3; + u32 tx_pkt_fifo_120[3]; /* 0x00004780 */ + u32 tx_pkt_fifo_120_rsv3; + u32 tx_pkt_fifo_121[3]; /* 0x00004790 */ + u32 tx_pkt_fifo_121_rsv3; + u32 tx_pkt_fifo_122[3]; /* 0x000047a0 */ + u32 tx_pkt_fifo_122_rsv3; + u32 tx_pkt_fifo_123[3]; /* 0x000047b0 */ + u32 tx_pkt_fifo_123_rsv3; + u32 tx_pkt_fifo_124[3]; /* 0x000047c0 */ + u32 tx_pkt_fifo_124_rsv3; + u32 tx_pkt_fifo_125[3]; /* 0x000047d0 */ + u32 tx_pkt_fifo_125_rsv3; + u32 tx_pkt_fifo_126[3]; /* 0x000047e0 */ + u32 tx_pkt_fifo_126_rsv3; + u32 tx_pkt_fifo_127[3]; /* 0x000047f0 */ + u32 tx_pkt_fifo_127_rsv3; + u32 tx_pkt_fifo_128[3]; /* 0x00004800 */ + u32 tx_pkt_fifo_128_rsv3; + u32 tx_pkt_fifo_129[3]; /* 0x00004810 */ + u32 tx_pkt_fifo_129_rsv3; + u32 tx_pkt_fifo_130[3]; /* 0x00004820 */ + u32 tx_pkt_fifo_130_rsv3; + u32 tx_pkt_fifo_131[3]; /* 0x00004830 */ + u32 tx_pkt_fifo_131_rsv3; + u32 tx_pkt_fifo_132[3]; /* 0x00004840 */ + u32 tx_pkt_fifo_132_rsv3; + u32 tx_pkt_fifo_133[3]; /* 0x00004850 */ + u32 tx_pkt_fifo_133_rsv3; + u32 tx_pkt_fifo_134[3]; /* 0x00004860 */ + u32 tx_pkt_fifo_134_rsv3; + u32 tx_pkt_fifo_135[3]; /* 0x00004870 */ + u32 tx_pkt_fifo_135_rsv3; + u32 tx_pkt_fifo_136[3]; /* 0x00004880 */ + u32 tx_pkt_fifo_136_rsv3; + u32 tx_pkt_fifo_137[3]; /* 0x00004890 */ + u32 tx_pkt_fifo_137_rsv3; + u32 tx_pkt_fifo_138[3]; /* 0x000048a0 */ + u32 tx_pkt_fifo_138_rsv3; + u32 tx_pkt_fifo_139[3]; /* 0x000048b0 */ + u32 tx_pkt_fifo_139_rsv3; + u32 tx_pkt_fifo_140[3]; /* 0x000048c0 */ + u32 tx_pkt_fifo_140_rsv3; + u32 tx_pkt_fifo_141[3]; /* 0x000048d0 */ + u32 tx_pkt_fifo_141_rsv3; + u32 tx_pkt_fifo_142[3]; /* 0x000048e0 */ + u32 tx_pkt_fifo_142_rsv3; + u32 tx_pkt_fifo_143[3]; /* 0x000048f0 */ + u32 tx_pkt_fifo_143_rsv3; + u32 tx_pkt_fifo_144[3]; /* 0x00004900 */ + u32 tx_pkt_fifo_144_rsv3; + u32 tx_pkt_fifo_145[3]; /* 0x00004910 */ + u32 tx_pkt_fifo_145_rsv3; + u32 tx_pkt_fifo_146[3]; /* 0x00004920 */ + u32 tx_pkt_fifo_146_rsv3; + u32 tx_pkt_fifo_147[3]; /* 0x00004930 */ + u32 tx_pkt_fifo_147_rsv3; + u32 tx_pkt_fifo_148[3]; /* 0x00004940 */ + u32 tx_pkt_fifo_148_rsv3; + u32 tx_pkt_fifo_149[3]; /* 0x00004950 */ + u32 tx_pkt_fifo_149_rsv3; + u32 tx_pkt_fifo_150[3]; /* 0x00004960 */ + u32 tx_pkt_fifo_150_rsv3; + u32 tx_pkt_fifo_151[3]; /* 0x00004970 */ + u32 tx_pkt_fifo_151_rsv3; + u32 tx_pkt_fifo_152[3]; /* 0x00004980 */ + u32 tx_pkt_fifo_152_rsv3; + u32 tx_pkt_fifo_153[3]; /* 0x00004990 */ + u32 tx_pkt_fifo_153_rsv3; + u32 tx_pkt_fifo_154[3]; /* 0x000049a0 */ + u32 tx_pkt_fifo_154_rsv3; + u32 tx_pkt_fifo_155[3]; /* 0x000049b0 */ + u32 tx_pkt_fifo_155_rsv3; + u32 tx_pkt_fifo_156[3]; /* 0x000049c0 */ + u32 tx_pkt_fifo_156_rsv3; + u32 tx_pkt_fifo_157[3]; /* 0x000049d0 */ + u32 tx_pkt_fifo_157_rsv3; + u32 tx_pkt_fifo_158[3]; /* 0x000049e0 */ + u32 tx_pkt_fifo_158_rsv3; + u32 tx_pkt_fifo_159[3]; /* 0x000049f0 */ + u32 tx_pkt_fifo_159_rsv3; + u32 tx_pkt_fifo_160[3]; /* 0x00004a00 */ + u32 tx_pkt_fifo_160_rsv3; + u32 tx_pkt_fifo_161[3]; /* 0x00004a10 */ + u32 tx_pkt_fifo_161_rsv3; + u32 tx_pkt_fifo_162[3]; /* 0x00004a20 */ + u32 tx_pkt_fifo_162_rsv3; + u32 tx_pkt_fifo_163[3]; /* 0x00004a30 */ + u32 tx_pkt_fifo_163_rsv3; + u32 tx_pkt_fifo_164[3]; /* 0x00004a40 */ + u32 tx_pkt_fifo_164_rsv3; + u32 tx_pkt_fifo_165[3]; /* 0x00004a50 */ + u32 tx_pkt_fifo_165_rsv3; + u32 tx_pkt_fifo_166[3]; /* 0x00004a60 */ + u32 tx_pkt_fifo_166_rsv3; + u32 tx_pkt_fifo_167[3]; /* 0x00004a70 */ + u32 tx_pkt_fifo_167_rsv3; + u32 tx_pkt_fifo_168[3]; /* 0x00004a80 */ + u32 tx_pkt_fifo_168_rsv3; + u32 tx_pkt_fifo_169[3]; /* 0x00004a90 */ + u32 tx_pkt_fifo_169_rsv3; + u32 tx_pkt_fifo_170[3]; /* 0x00004aa0 */ + u32 tx_pkt_fifo_170_rsv3; + u32 tx_pkt_fifo_171[3]; /* 0x00004ab0 */ + u32 tx_pkt_fifo_171_rsv3; + u32 tx_pkt_fifo_172[3]; /* 0x00004ac0 */ + u32 tx_pkt_fifo_172_rsv3; + u32 tx_pkt_fifo_173[3]; /* 0x00004ad0 */ + u32 tx_pkt_fifo_173_rsv3; + u32 tx_pkt_fifo_174[3]; /* 0x00004ae0 */ + u32 tx_pkt_fifo_174_rsv3; + u32 tx_pkt_fifo_175[3]; /* 0x00004af0 */ + u32 tx_pkt_fifo_175_rsv3; + u32 tx_pkt_fifo_176[3]; /* 0x00004b00 */ + u32 tx_pkt_fifo_176_rsv3; + u32 tx_pkt_fifo_177[3]; /* 0x00004b10 */ + u32 tx_pkt_fifo_177_rsv3; + u32 tx_pkt_fifo_178[3]; /* 0x00004b20 */ + u32 tx_pkt_fifo_178_rsv3; + u32 tx_pkt_fifo_179[3]; /* 0x00004b30 */ + u32 tx_pkt_fifo_179_rsv3; + u32 tx_pkt_fifo_180[3]; /* 0x00004b40 */ + u32 tx_pkt_fifo_180_rsv3; + u32 tx_pkt_fifo_181[3]; /* 0x00004b50 */ + u32 tx_pkt_fifo_181_rsv3; + u32 tx_pkt_fifo_182[3]; /* 0x00004b60 */ + u32 tx_pkt_fifo_182_rsv3; + u32 tx_pkt_fifo_183[3]; /* 0x00004b70 */ + u32 tx_pkt_fifo_183_rsv3; + u32 tx_pkt_fifo_184[3]; /* 0x00004b80 */ + u32 tx_pkt_fifo_184_rsv3; + u32 tx_pkt_fifo_185[3]; /* 0x00004b90 */ + u32 tx_pkt_fifo_185_rsv3; + u32 tx_pkt_fifo_186[3]; /* 0x00004ba0 */ + u32 tx_pkt_fifo_186_rsv3; + u32 tx_pkt_fifo_187[3]; /* 0x00004bb0 */ + u32 tx_pkt_fifo_187_rsv3; + u32 tx_pkt_fifo_188[3]; /* 0x00004bc0 */ + u32 tx_pkt_fifo_188_rsv3; + u32 tx_pkt_fifo_189[3]; /* 0x00004bd0 */ + u32 tx_pkt_fifo_189_rsv3; + u32 tx_pkt_fifo_190[3]; /* 0x00004be0 */ + u32 tx_pkt_fifo_190_rsv3; + u32 tx_pkt_fifo_191[3]; /* 0x00004bf0 */ + u32 tx_pkt_fifo_191_rsv3; + u32 tx_pkt_fifo_192[3]; /* 0x00004c00 */ + u32 tx_pkt_fifo_192_rsv3; + u32 tx_pkt_fifo_193[3]; /* 0x00004c10 */ + u32 tx_pkt_fifo_193_rsv3; + u32 tx_pkt_fifo_194[3]; /* 0x00004c20 */ + u32 tx_pkt_fifo_194_rsv3; + u32 tx_pkt_fifo_195[3]; /* 0x00004c30 */ + u32 tx_pkt_fifo_195_rsv3; + u32 tx_pkt_fifo_196[3]; /* 0x00004c40 */ + u32 tx_pkt_fifo_196_rsv3; + u32 tx_pkt_fifo_197[3]; /* 0x00004c50 */ + u32 tx_pkt_fifo_197_rsv3; + u32 tx_pkt_fifo_198[3]; /* 0x00004c60 */ + u32 tx_pkt_fifo_198_rsv3; + u32 tx_pkt_fifo_199[3]; /* 0x00004c70 */ + u32 tx_pkt_fifo_199_rsv3; + u32 tx_pkt_fifo_200[3]; /* 0x00004c80 */ + u32 tx_pkt_fifo_200_rsv3; + u32 tx_pkt_fifo_201[3]; /* 0x00004c90 */ + u32 tx_pkt_fifo_201_rsv3; + u32 tx_pkt_fifo_202[3]; /* 0x00004ca0 */ + u32 tx_pkt_fifo_202_rsv3; + u32 tx_pkt_fifo_203[3]; /* 0x00004cb0 */ + u32 tx_pkt_fifo_203_rsv3; + u32 tx_pkt_fifo_204[3]; /* 0x00004cc0 */ + u32 tx_pkt_fifo_204_rsv3; + u32 tx_pkt_fifo_205[3]; /* 0x00004cd0 */ + u32 tx_pkt_fifo_205_rsv3; + u32 tx_pkt_fifo_206[3]; /* 0x00004ce0 */ + u32 tx_pkt_fifo_206_rsv3; + u32 tx_pkt_fifo_207[3]; /* 0x00004cf0 */ + u32 tx_pkt_fifo_207_rsv3; + u32 tx_pkt_fifo_208[3]; /* 0x00004d00 */ + u32 tx_pkt_fifo_208_rsv3; + u32 tx_pkt_fifo_209[3]; /* 0x00004d10 */ + u32 tx_pkt_fifo_209_rsv3; + u32 tx_pkt_fifo_210[3]; /* 0x00004d20 */ + u32 tx_pkt_fifo_210_rsv3; + u32 tx_pkt_fifo_211[3]; /* 0x00004d30 */ + u32 tx_pkt_fifo_211_rsv3; + u32 tx_pkt_fifo_212[3]; /* 0x00004d40 */ + u32 tx_pkt_fifo_212_rsv3; + u32 tx_pkt_fifo_213[3]; /* 0x00004d50 */ + u32 tx_pkt_fifo_213_rsv3; + u32 tx_pkt_fifo_214[3]; /* 0x00004d60 */ + u32 tx_pkt_fifo_214_rsv3; + u32 tx_pkt_fifo_215[3]; /* 0x00004d70 */ + u32 tx_pkt_fifo_215_rsv3; + u32 tx_pkt_fifo_216[3]; /* 0x00004d80 */ + u32 tx_pkt_fifo_216_rsv3; + u32 tx_pkt_fifo_217[3]; /* 0x00004d90 */ + u32 tx_pkt_fifo_217_rsv3; + u32 tx_pkt_fifo_218[3]; /* 0x00004da0 */ + u32 tx_pkt_fifo_218_rsv3; + u32 tx_pkt_fifo_219[3]; /* 0x00004db0 */ + u32 tx_pkt_fifo_219_rsv3; + u32 tx_pkt_fifo_220[3]; /* 0x00004dc0 */ + u32 tx_pkt_fifo_220_rsv3; + u32 tx_pkt_fifo_221[3]; /* 0x00004dd0 */ + u32 tx_pkt_fifo_221_rsv3; + u32 tx_pkt_fifo_222[3]; /* 0x00004de0 */ + u32 tx_pkt_fifo_222_rsv3; + u32 tx_pkt_fifo_223[3]; /* 0x00004df0 */ + u32 tx_pkt_fifo_223_rsv3; + u32 tx_pkt_fifo_224[3]; /* 0x00004e00 */ + u32 tx_pkt_fifo_224_rsv3; + u32 tx_pkt_fifo_225[3]; /* 0x00004e10 */ + u32 tx_pkt_fifo_225_rsv3; + u32 tx_pkt_fifo_226[3]; /* 0x00004e20 */ + u32 tx_pkt_fifo_226_rsv3; + u32 tx_pkt_fifo_227[3]; /* 0x00004e30 */ + u32 tx_pkt_fifo_227_rsv3; + u32 tx_pkt_fifo_228[3]; /* 0x00004e40 */ + u32 tx_pkt_fifo_228_rsv3; + u32 tx_pkt_fifo_229[3]; /* 0x00004e50 */ + u32 tx_pkt_fifo_229_rsv3; + u32 tx_pkt_fifo_230[3]; /* 0x00004e60 */ + u32 tx_pkt_fifo_230_rsv3; + u32 tx_pkt_fifo_231[3]; /* 0x00004e70 */ + u32 tx_pkt_fifo_231_rsv3; + u32 tx_pkt_fifo_232[3]; /* 0x00004e80 */ + u32 tx_pkt_fifo_232_rsv3; + u32 tx_pkt_fifo_233[3]; /* 0x00004e90 */ + u32 tx_pkt_fifo_233_rsv3; + u32 tx_pkt_fifo_234[3]; /* 0x00004ea0 */ + u32 tx_pkt_fifo_234_rsv3; + u32 tx_pkt_fifo_235[3]; /* 0x00004eb0 */ + u32 tx_pkt_fifo_235_rsv3; + u32 tx_pkt_fifo_236[3]; /* 0x00004ec0 */ + u32 tx_pkt_fifo_236_rsv3; + u32 tx_pkt_fifo_237[3]; /* 0x00004ed0 */ + u32 tx_pkt_fifo_237_rsv3; + u32 tx_pkt_fifo_238[3]; /* 0x00004ee0 */ + u32 tx_pkt_fifo_238_rsv3; + u32 tx_pkt_fifo_239[3]; /* 0x00004ef0 */ + u32 tx_pkt_fifo_239_rsv3; + u32 tx_pkt_fifo_240[3]; /* 0x00004f00 */ + u32 tx_pkt_fifo_240_rsv3; + u32 tx_pkt_fifo_241[3]; /* 0x00004f10 */ + u32 tx_pkt_fifo_241_rsv3; + u32 tx_pkt_fifo_242[3]; /* 0x00004f20 */ + u32 tx_pkt_fifo_242_rsv3; + u32 tx_pkt_fifo_243[3]; /* 0x00004f30 */ + u32 tx_pkt_fifo_243_rsv3; + u32 tx_pkt_fifo_244[3]; /* 0x00004f40 */ + u32 tx_pkt_fifo_244_rsv3; + u32 tx_pkt_fifo_245[3]; /* 0x00004f50 */ + u32 tx_pkt_fifo_245_rsv3; + u32 tx_pkt_fifo_246[3]; /* 0x00004f60 */ + u32 tx_pkt_fifo_246_rsv3; + u32 tx_pkt_fifo_247[3]; /* 0x00004f70 */ + u32 tx_pkt_fifo_247_rsv3; + u32 tx_pkt_fifo_248[3]; /* 0x00004f80 */ + u32 tx_pkt_fifo_248_rsv3; + u32 tx_pkt_fifo_249[3]; /* 0x00004f90 */ + u32 tx_pkt_fifo_249_rsv3; + u32 tx_pkt_fifo_250[3]; /* 0x00004fa0 */ + u32 tx_pkt_fifo_250_rsv3; + u32 tx_pkt_fifo_251[3]; /* 0x00004fb0 */ + u32 tx_pkt_fifo_251_rsv3; + u32 tx_pkt_fifo_252[3]; /* 0x00004fc0 */ + u32 tx_pkt_fifo_252_rsv3; + u32 tx_pkt_fifo_253[3]; /* 0x00004fd0 */ + u32 tx_pkt_fifo_253_rsv3; + u32 tx_pkt_fifo_254[3]; /* 0x00004fe0 */ + u32 tx_pkt_fifo_254_rsv3; + u32 tx_pkt_fifo_255[3]; /* 0x00004ff0 */ + u32 tx_pkt_fifo_255_rsv3; + u32 tx_pkt_fifo_256[3]; /* 0x00005000 */ + u32 tx_pkt_fifo_256_rsv3; + u32 tx_pkt_fifo_257[3]; /* 0x00005010 */ + u32 tx_pkt_fifo_257_rsv3; + u32 tx_pkt_fifo_258[3]; /* 0x00005020 */ + u32 tx_pkt_fifo_258_rsv3; + u32 tx_pkt_fifo_259[3]; /* 0x00005030 */ + u32 tx_pkt_fifo_259_rsv3; + u32 tx_pkt_fifo_260[3]; /* 0x00005040 */ + u32 tx_pkt_fifo_260_rsv3; + u32 tx_pkt_fifo_261[3]; /* 0x00005050 */ + u32 tx_pkt_fifo_261_rsv3; + u32 tx_pkt_fifo_262[3]; /* 0x00005060 */ + u32 tx_pkt_fifo_262_rsv3; + u32 tx_pkt_fifo_263[3]; /* 0x00005070 */ + u32 tx_pkt_fifo_263_rsv3; + u32 tx_pkt_fifo_264[3]; /* 0x00005080 */ + u32 tx_pkt_fifo_264_rsv3; + u32 tx_pkt_fifo_265[3]; /* 0x00005090 */ + u32 tx_pkt_fifo_265_rsv3; + u32 tx_pkt_fifo_266[3]; /* 0x000050a0 */ + u32 tx_pkt_fifo_266_rsv3; + u32 tx_pkt_fifo_267[3]; /* 0x000050b0 */ + u32 tx_pkt_fifo_267_rsv3; + u32 tx_pkt_fifo_268[3]; /* 0x000050c0 */ + u32 tx_pkt_fifo_268_rsv3; + u32 tx_pkt_fifo_269[3]; /* 0x000050d0 */ + u32 tx_pkt_fifo_269_rsv3; + u32 tx_pkt_fifo_270[3]; /* 0x000050e0 */ + u32 tx_pkt_fifo_270_rsv3; + u32 tx_pkt_fifo_271[3]; /* 0x000050f0 */ + u32 tx_pkt_fifo_271_rsv3; + u32 tx_pkt_fifo_272[3]; /* 0x00005100 */ + u32 tx_pkt_fifo_272_rsv3; + u32 tx_pkt_fifo_273[3]; /* 0x00005110 */ + u32 tx_pkt_fifo_273_rsv3; + u32 tx_pkt_fifo_274[3]; /* 0x00005120 */ + u32 tx_pkt_fifo_274_rsv3; + u32 tx_pkt_fifo_275[3]; /* 0x00005130 */ + u32 tx_pkt_fifo_275_rsv3; + u32 tx_pkt_fifo_276[3]; /* 0x00005140 */ + u32 tx_pkt_fifo_276_rsv3; + u32 tx_pkt_fifo_277[3]; /* 0x00005150 */ + u32 tx_pkt_fifo_277_rsv3; + u32 tx_pkt_fifo_278[3]; /* 0x00005160 */ + u32 tx_pkt_fifo_278_rsv3; + u32 tx_pkt_fifo_279[3]; /* 0x00005170 */ + u32 tx_pkt_fifo_279_rsv3; + u32 tx_pkt_fifo_280[3]; /* 0x00005180 */ + u32 tx_pkt_fifo_280_rsv3; + u32 tx_pkt_fifo_281[3]; /* 0x00005190 */ + u32 tx_pkt_fifo_281_rsv3; + u32 tx_pkt_fifo_282[3]; /* 0x000051a0 */ + u32 tx_pkt_fifo_282_rsv3; + u32 tx_pkt_fifo_283[3]; /* 0x000051b0 */ + u32 tx_pkt_fifo_283_rsv3; + u32 tx_pkt_fifo_284[3]; /* 0x000051c0 */ + u32 tx_pkt_fifo_284_rsv3; + u32 tx_pkt_fifo_285[3]; /* 0x000051d0 */ + u32 tx_pkt_fifo_285_rsv3; + u32 tx_pkt_fifo_286[3]; /* 0x000051e0 */ + u32 tx_pkt_fifo_286_rsv3; + u32 tx_pkt_fifo_287[3]; /* 0x000051f0 */ + u32 tx_pkt_fifo_287_rsv3; + u32 tx_pkt_fifo_288[3]; /* 0x00005200 */ + u32 tx_pkt_fifo_288_rsv3; + u32 tx_pkt_fifo_289[3]; /* 0x00005210 */ + u32 tx_pkt_fifo_289_rsv3; + u32 tx_pkt_fifo_290[3]; /* 0x00005220 */ + u32 tx_pkt_fifo_290_rsv3; + u32 tx_pkt_fifo_291[3]; /* 0x00005230 */ + u32 tx_pkt_fifo_291_rsv3; + u32 tx_pkt_fifo_292[3]; /* 0x00005240 */ + u32 tx_pkt_fifo_292_rsv3; + u32 tx_pkt_fifo_293[3]; /* 0x00005250 */ + u32 tx_pkt_fifo_293_rsv3; + u32 tx_pkt_fifo_294[3]; /* 0x00005260 */ + u32 tx_pkt_fifo_294_rsv3; + u32 tx_pkt_fifo_295[3]; /* 0x00005270 */ + u32 tx_pkt_fifo_295_rsv3; + u32 tx_pkt_fifo_296[3]; /* 0x00005280 */ + u32 tx_pkt_fifo_296_rsv3; + u32 tx_pkt_fifo_297[3]; /* 0x00005290 */ + u32 tx_pkt_fifo_297_rsv3; + u32 tx_pkt_fifo_298[3]; /* 0x000052a0 */ + u32 tx_pkt_fifo_298_rsv3; + u32 tx_pkt_fifo_299[3]; /* 0x000052b0 */ + u32 tx_pkt_fifo_299_rsv3; + u32 tx_pkt_fifo_300[3]; /* 0x000052c0 */ + u32 tx_pkt_fifo_300_rsv3; + u32 tx_pkt_fifo_301[3]; /* 0x000052d0 */ + u32 tx_pkt_fifo_301_rsv3; + u32 tx_pkt_fifo_302[3]; /* 0x000052e0 */ + u32 tx_pkt_fifo_302_rsv3; + u32 tx_pkt_fifo_303[3]; /* 0x000052f0 */ + u32 tx_pkt_fifo_303_rsv3; + u32 tx_pkt_fifo_304[3]; /* 0x00005300 */ + u32 tx_pkt_fifo_304_rsv3; + u32 tx_pkt_fifo_305[3]; /* 0x00005310 */ + u32 tx_pkt_fifo_305_rsv3; + u32 tx_pkt_fifo_306[3]; /* 0x00005320 */ + u32 tx_pkt_fifo_306_rsv3; + u32 tx_pkt_fifo_307[3]; /* 0x00005330 */ + u32 tx_pkt_fifo_307_rsv3; + u32 tx_pkt_fifo_308[3]; /* 0x00005340 */ + u32 tx_pkt_fifo_308_rsv3; + u32 tx_pkt_fifo_309[3]; /* 0x00005350 */ + u32 tx_pkt_fifo_309_rsv3; + u32 tx_pkt_fifo_310[3]; /* 0x00005360 */ + u32 tx_pkt_fifo_310_rsv3; + u32 tx_pkt_fifo_311[3]; /* 0x00005370 */ + u32 tx_pkt_fifo_311_rsv3; + u32 tx_pkt_fifo_312[3]; /* 0x00005380 */ + u32 tx_pkt_fifo_312_rsv3; + u32 tx_pkt_fifo_313[3]; /* 0x00005390 */ + u32 tx_pkt_fifo_313_rsv3; + u32 tx_pkt_fifo_314[3]; /* 0x000053a0 */ + u32 tx_pkt_fifo_314_rsv3; + u32 tx_pkt_fifo_315[3]; /* 0x000053b0 */ + u32 tx_pkt_fifo_315_rsv3; + u32 tx_pkt_fifo_316[3]; /* 0x000053c0 */ + u32 tx_pkt_fifo_316_rsv3; + u32 tx_pkt_fifo_317[3]; /* 0x000053d0 */ + u32 tx_pkt_fifo_317_rsv3; + u32 tx_pkt_fifo_318[3]; /* 0x000053e0 */ + u32 tx_pkt_fifo_318_rsv3; + u32 tx_pkt_fifo_319[3]; /* 0x000053f0 */ + u32 tx_pkt_fifo_319_rsv3; + u32 tx_pkt_fifo_320[3]; /* 0x00005400 */ + u32 tx_pkt_fifo_320_rsv3; + u32 tx_pkt_fifo_321[3]; /* 0x00005410 */ + u32 tx_pkt_fifo_321_rsv3; + u32 tx_pkt_fifo_322[3]; /* 0x00005420 */ + u32 tx_pkt_fifo_322_rsv3; + u32 tx_pkt_fifo_323[3]; /* 0x00005430 */ + u32 tx_pkt_fifo_323_rsv3; + u32 tx_pkt_fifo_324[3]; /* 0x00005440 */ + u32 tx_pkt_fifo_324_rsv3; + u32 tx_pkt_fifo_325[3]; /* 0x00005450 */ + u32 tx_pkt_fifo_325_rsv3; + u32 tx_pkt_fifo_326[3]; /* 0x00005460 */ + u32 tx_pkt_fifo_326_rsv3; + u32 tx_pkt_fifo_327[3]; /* 0x00005470 */ + u32 tx_pkt_fifo_327_rsv3; + u32 tx_pkt_fifo_328[3]; /* 0x00005480 */ + u32 tx_pkt_fifo_328_rsv3; + u32 tx_pkt_fifo_329[3]; /* 0x00005490 */ + u32 tx_pkt_fifo_329_rsv3; + u32 tx_pkt_fifo_330[3]; /* 0x000054a0 */ + u32 tx_pkt_fifo_330_rsv3; + u32 tx_pkt_fifo_331[3]; /* 0x000054b0 */ + u32 tx_pkt_fifo_331_rsv3; + u32 tx_pkt_fifo_332[3]; /* 0x000054c0 */ + u32 tx_pkt_fifo_332_rsv3; + u32 tx_pkt_fifo_333[3]; /* 0x000054d0 */ + u32 tx_pkt_fifo_333_rsv3; + u32 tx_pkt_fifo_334[3]; /* 0x000054e0 */ + u32 tx_pkt_fifo_334_rsv3; + u32 tx_pkt_fifo_335[3]; /* 0x000054f0 */ + u32 tx_pkt_fifo_335_rsv3; + u32 tx_pkt_fifo_336[3]; /* 0x00005500 */ + u32 tx_pkt_fifo_336_rsv3; + u32 tx_pkt_fifo_337[3]; /* 0x00005510 */ + u32 tx_pkt_fifo_337_rsv3; + u32 tx_pkt_fifo_338[3]; /* 0x00005520 */ + u32 tx_pkt_fifo_338_rsv3; + u32 tx_pkt_fifo_339[3]; /* 0x00005530 */ + u32 tx_pkt_fifo_339_rsv3; + u32 tx_pkt_fifo_340[3]; /* 0x00005540 */ + u32 tx_pkt_fifo_340_rsv3; + u32 tx_pkt_fifo_341[3]; /* 0x00005550 */ + u32 tx_pkt_fifo_341_rsv3; + u32 tx_pkt_fifo_342[3]; /* 0x00005560 */ + u32 tx_pkt_fifo_342_rsv3; + u32 tx_pkt_fifo_343[3]; /* 0x00005570 */ + u32 tx_pkt_fifo_343_rsv3; + u32 tx_pkt_fifo_344[3]; /* 0x00005580 */ + u32 tx_pkt_fifo_344_rsv3; + u32 tx_pkt_fifo_345[3]; /* 0x00005590 */ + u32 tx_pkt_fifo_345_rsv3; + u32 tx_pkt_fifo_346[3]; /* 0x000055a0 */ + u32 tx_pkt_fifo_346_rsv3; + u32 tx_pkt_fifo_347[3]; /* 0x000055b0 */ + u32 tx_pkt_fifo_347_rsv3; + u32 tx_pkt_fifo_348[3]; /* 0x000055c0 */ + u32 tx_pkt_fifo_348_rsv3; + u32 tx_pkt_fifo_349[3]; /* 0x000055d0 */ + u32 tx_pkt_fifo_349_rsv3; + u32 tx_pkt_fifo_350[3]; /* 0x000055e0 */ + u32 tx_pkt_fifo_350_rsv3; + u32 tx_pkt_fifo_351[3]; /* 0x000055f0 */ + u32 tx_pkt_fifo_351_rsv3; + u32 tx_pkt_fifo_352[3]; /* 0x00005600 */ + u32 tx_pkt_fifo_352_rsv3; + u32 tx_pkt_fifo_353[3]; /* 0x00005610 */ + u32 tx_pkt_fifo_353_rsv3; + u32 tx_pkt_fifo_354[3]; /* 0x00005620 */ + u32 tx_pkt_fifo_354_rsv3; + u32 tx_pkt_fifo_355[3]; /* 0x00005630 */ + u32 tx_pkt_fifo_355_rsv3; + u32 tx_pkt_fifo_356[3]; /* 0x00005640 */ + u32 tx_pkt_fifo_356_rsv3; + u32 tx_pkt_fifo_357[3]; /* 0x00005650 */ + u32 tx_pkt_fifo_357_rsv3; + u32 tx_pkt_fifo_358[3]; /* 0x00005660 */ + u32 tx_pkt_fifo_358_rsv3; + u32 tx_pkt_fifo_359[3]; /* 0x00005670 */ + u32 tx_pkt_fifo_359_rsv3; + u32 tx_pkt_fifo_360[3]; /* 0x00005680 */ + u32 tx_pkt_fifo_360_rsv3; + u32 tx_pkt_fifo_361[3]; /* 0x00005690 */ + u32 tx_pkt_fifo_361_rsv3; + u32 tx_pkt_fifo_362[3]; /* 0x000056a0 */ + u32 tx_pkt_fifo_362_rsv3; + u32 tx_pkt_fifo_363[3]; /* 0x000056b0 */ + u32 tx_pkt_fifo_363_rsv3; + u32 tx_pkt_fifo_364[3]; /* 0x000056c0 */ + u32 tx_pkt_fifo_364_rsv3; + u32 tx_pkt_fifo_365[3]; /* 0x000056d0 */ + u32 tx_pkt_fifo_365_rsv3; + u32 tx_pkt_fifo_366[3]; /* 0x000056e0 */ + u32 tx_pkt_fifo_366_rsv3; + u32 tx_pkt_fifo_367[3]; /* 0x000056f0 */ + u32 tx_pkt_fifo_367_rsv3; + u32 tx_pkt_fifo_368[3]; /* 0x00005700 */ + u32 tx_pkt_fifo_368_rsv3; + u32 tx_pkt_fifo_369[3]; /* 0x00005710 */ + u32 tx_pkt_fifo_369_rsv3; + u32 tx_pkt_fifo_370[3]; /* 0x00005720 */ + u32 tx_pkt_fifo_370_rsv3; + u32 tx_pkt_fifo_371[3]; /* 0x00005730 */ + u32 tx_pkt_fifo_371_rsv3; + u32 tx_pkt_fifo_372[3]; /* 0x00005740 */ + u32 tx_pkt_fifo_372_rsv3; + u32 tx_pkt_fifo_373[3]; /* 0x00005750 */ + u32 tx_pkt_fifo_373_rsv3; + u32 tx_pkt_fifo_374[3]; /* 0x00005760 */ + u32 tx_pkt_fifo_374_rsv3; + u32 tx_pkt_fifo_375[3]; /* 0x00005770 */ + u32 tx_pkt_fifo_375_rsv3; + u32 tx_pkt_fifo_376[3]; /* 0x00005780 */ + u32 tx_pkt_fifo_376_rsv3; + u32 tx_pkt_fifo_377[3]; /* 0x00005790 */ + u32 tx_pkt_fifo_377_rsv3; + u32 tx_pkt_fifo_378[3]; /* 0x000057a0 */ + u32 tx_pkt_fifo_378_rsv3; + u32 tx_pkt_fifo_379[3]; /* 0x000057b0 */ + u32 tx_pkt_fifo_379_rsv3; + u32 tx_pkt_fifo_380[3]; /* 0x000057c0 */ + u32 tx_pkt_fifo_380_rsv3; + u32 tx_pkt_fifo_381[3]; /* 0x000057d0 */ + u32 tx_pkt_fifo_381_rsv3; + u32 tx_pkt_fifo_382[3]; /* 0x000057e0 */ + u32 tx_pkt_fifo_382_rsv3; + u32 tx_pkt_fifo_383[3]; /* 0x000057f0 */ + u32 tx_pkt_fifo_383_rsv3; + u32 tx_pkt_fifo_384[3]; /* 0x00005800 */ + u32 tx_pkt_fifo_384_rsv3; + u32 tx_pkt_fifo_385[3]; /* 0x00005810 */ + u32 tx_pkt_fifo_385_rsv3; + u32 tx_pkt_fifo_386[3]; /* 0x00005820 */ + u32 tx_pkt_fifo_386_rsv3; + u32 tx_pkt_fifo_387[3]; /* 0x00005830 */ + u32 tx_pkt_fifo_387_rsv3; + u32 tx_pkt_fifo_388[3]; /* 0x00005840 */ + u32 tx_pkt_fifo_388_rsv3; + u32 tx_pkt_fifo_389[3]; /* 0x00005850 */ + u32 tx_pkt_fifo_389_rsv3; + u32 tx_pkt_fifo_390[3]; /* 0x00005860 */ + u32 tx_pkt_fifo_390_rsv3; + u32 tx_pkt_fifo_391[3]; /* 0x00005870 */ + u32 tx_pkt_fifo_391_rsv3; + u32 tx_pkt_fifo_392[3]; /* 0x00005880 */ + u32 tx_pkt_fifo_392_rsv3; + u32 tx_pkt_fifo_393[3]; /* 0x00005890 */ + u32 tx_pkt_fifo_393_rsv3; + u32 tx_pkt_fifo_394[3]; /* 0x000058a0 */ + u32 tx_pkt_fifo_394_rsv3; + u32 tx_pkt_fifo_395[3]; /* 0x000058b0 */ + u32 tx_pkt_fifo_395_rsv3; + u32 tx_pkt_fifo_396[3]; /* 0x000058c0 */ + u32 tx_pkt_fifo_396_rsv3; + u32 tx_pkt_fifo_397[3]; /* 0x000058d0 */ + u32 tx_pkt_fifo_397_rsv3; + u32 tx_pkt_fifo_398[3]; /* 0x000058e0 */ + u32 tx_pkt_fifo_398_rsv3; + u32 tx_pkt_fifo_399[3]; /* 0x000058f0 */ + u32 tx_pkt_fifo_399_rsv3; + u32 tx_pkt_fifo_400[3]; /* 0x00005900 */ + u32 tx_pkt_fifo_400_rsv3; + u32 tx_pkt_fifo_401[3]; /* 0x00005910 */ + u32 tx_pkt_fifo_401_rsv3; + u32 tx_pkt_fifo_402[3]; /* 0x00005920 */ + u32 tx_pkt_fifo_402_rsv3; + u32 tx_pkt_fifo_403[3]; /* 0x00005930 */ + u32 tx_pkt_fifo_403_rsv3; + u32 tx_pkt_fifo_404[3]; /* 0x00005940 */ + u32 tx_pkt_fifo_404_rsv3; + u32 tx_pkt_fifo_405[3]; /* 0x00005950 */ + u32 tx_pkt_fifo_405_rsv3; + u32 tx_pkt_fifo_406[3]; /* 0x00005960 */ + u32 tx_pkt_fifo_406_rsv3; + u32 tx_pkt_fifo_407[3]; /* 0x00005970 */ + u32 tx_pkt_fifo_407_rsv3; + u32 tx_pkt_fifo_408[3]; /* 0x00005980 */ + u32 tx_pkt_fifo_408_rsv3; + u32 tx_pkt_fifo_409[3]; /* 0x00005990 */ + u32 tx_pkt_fifo_409_rsv3; + u32 tx_pkt_fifo_410[3]; /* 0x000059a0 */ + u32 tx_pkt_fifo_410_rsv3; + u32 tx_pkt_fifo_411[3]; /* 0x000059b0 */ + u32 tx_pkt_fifo_411_rsv3; + u32 tx_pkt_fifo_412[3]; /* 0x000059c0 */ + u32 tx_pkt_fifo_412_rsv3; + u32 tx_pkt_fifo_413[3]; /* 0x000059d0 */ + u32 tx_pkt_fifo_413_rsv3; + u32 tx_pkt_fifo_414[3]; /* 0x000059e0 */ + u32 tx_pkt_fifo_414_rsv3; + u32 tx_pkt_fifo_415[3]; /* 0x000059f0 */ + u32 tx_pkt_fifo_415_rsv3; + u32 tx_pkt_fifo_416[3]; /* 0x00005a00 */ + u32 tx_pkt_fifo_416_rsv3; + u32 tx_pkt_fifo_417[3]; /* 0x00005a10 */ + u32 tx_pkt_fifo_417_rsv3; + u32 tx_pkt_fifo_418[3]; /* 0x00005a20 */ + u32 tx_pkt_fifo_418_rsv3; + u32 tx_pkt_fifo_419[3]; /* 0x00005a30 */ + u32 tx_pkt_fifo_419_rsv3; + u32 tx_pkt_fifo_420[3]; /* 0x00005a40 */ + u32 tx_pkt_fifo_420_rsv3; + u32 tx_pkt_fifo_421[3]; /* 0x00005a50 */ + u32 tx_pkt_fifo_421_rsv3; + u32 tx_pkt_fifo_422[3]; /* 0x00005a60 */ + u32 tx_pkt_fifo_422_rsv3; + u32 tx_pkt_fifo_423[3]; /* 0x00005a70 */ + u32 tx_pkt_fifo_423_rsv3; + u32 tx_pkt_fifo_424[3]; /* 0x00005a80 */ + u32 tx_pkt_fifo_424_rsv3; + u32 tx_pkt_fifo_425[3]; /* 0x00005a90 */ + u32 tx_pkt_fifo_425_rsv3; + u32 tx_pkt_fifo_426[3]; /* 0x00005aa0 */ + u32 tx_pkt_fifo_426_rsv3; + u32 tx_pkt_fifo_427[3]; /* 0x00005ab0 */ + u32 tx_pkt_fifo_427_rsv3; + u32 tx_pkt_fifo_428[3]; /* 0x00005ac0 */ + u32 tx_pkt_fifo_428_rsv3; + u32 tx_pkt_fifo_429[3]; /* 0x00005ad0 */ + u32 tx_pkt_fifo_429_rsv3; + u32 tx_pkt_fifo_430[3]; /* 0x00005ae0 */ + u32 tx_pkt_fifo_430_rsv3; + u32 tx_pkt_fifo_431[3]; /* 0x00005af0 */ + u32 tx_pkt_fifo_431_rsv3; + u32 tx_pkt_fifo_432[3]; /* 0x00005b00 */ + u32 tx_pkt_fifo_432_rsv3; + u32 tx_pkt_fifo_433[3]; /* 0x00005b10 */ + u32 tx_pkt_fifo_433_rsv3; + u32 tx_pkt_fifo_434[3]; /* 0x00005b20 */ + u32 tx_pkt_fifo_434_rsv3; + u32 tx_pkt_fifo_435[3]; /* 0x00005b30 */ + u32 tx_pkt_fifo_435_rsv3; + u32 tx_pkt_fifo_436[3]; /* 0x00005b40 */ + u32 tx_pkt_fifo_436_rsv3; + u32 tx_pkt_fifo_437[3]; /* 0x00005b50 */ + u32 tx_pkt_fifo_437_rsv3; + u32 tx_pkt_fifo_438[3]; /* 0x00005b60 */ + u32 tx_pkt_fifo_438_rsv3; + u32 tx_pkt_fifo_439[3]; /* 0x00005b70 */ + u32 tx_pkt_fifo_439_rsv3; + u32 tx_pkt_fifo_440[3]; /* 0x00005b80 */ + u32 tx_pkt_fifo_440_rsv3; + u32 tx_pkt_fifo_441[3]; /* 0x00005b90 */ + u32 tx_pkt_fifo_441_rsv3; + u32 tx_pkt_fifo_442[3]; /* 0x00005ba0 */ + u32 tx_pkt_fifo_442_rsv3; + u32 tx_pkt_fifo_443[3]; /* 0x00005bb0 */ + u32 tx_pkt_fifo_443_rsv3; + u32 tx_pkt_fifo_444[3]; /* 0x00005bc0 */ + u32 tx_pkt_fifo_444_rsv3; + u32 tx_pkt_fifo_445[3]; /* 0x00005bd0 */ + u32 tx_pkt_fifo_445_rsv3; + u32 tx_pkt_fifo_446[3]; /* 0x00005be0 */ + u32 tx_pkt_fifo_446_rsv3; + u32 tx_pkt_fifo_447[3]; /* 0x00005bf0 */ + u32 tx_pkt_fifo_447_rsv3; + u32 tx_pkt_fifo_448[3]; /* 0x00005c00 */ + u32 tx_pkt_fifo_448_rsv3; + u32 tx_pkt_fifo_449[3]; /* 0x00005c10 */ + u32 tx_pkt_fifo_449_rsv3; + u32 tx_pkt_fifo_450[3]; /* 0x00005c20 */ + u32 tx_pkt_fifo_450_rsv3; + u32 tx_pkt_fifo_451[3]; /* 0x00005c30 */ + u32 tx_pkt_fifo_451_rsv3; + u32 tx_pkt_fifo_452[3]; /* 0x00005c40 */ + u32 tx_pkt_fifo_452_rsv3; + u32 tx_pkt_fifo_453[3]; /* 0x00005c50 */ + u32 tx_pkt_fifo_453_rsv3; + u32 tx_pkt_fifo_454[3]; /* 0x00005c60 */ + u32 tx_pkt_fifo_454_rsv3; + u32 tx_pkt_fifo_455[3]; /* 0x00005c70 */ + u32 tx_pkt_fifo_455_rsv3; + u32 tx_pkt_fifo_456[3]; /* 0x00005c80 */ + u32 tx_pkt_fifo_456_rsv3; + u32 tx_pkt_fifo_457[3]; /* 0x00005c90 */ + u32 tx_pkt_fifo_457_rsv3; + u32 tx_pkt_fifo_458[3]; /* 0x00005ca0 */ + u32 tx_pkt_fifo_458_rsv3; + u32 tx_pkt_fifo_459[3]; /* 0x00005cb0 */ + u32 tx_pkt_fifo_459_rsv3; + u32 tx_pkt_fifo_460[3]; /* 0x00005cc0 */ + u32 tx_pkt_fifo_460_rsv3; + u32 tx_pkt_fifo_461[3]; /* 0x00005cd0 */ + u32 tx_pkt_fifo_461_rsv3; + u32 tx_pkt_fifo_462[3]; /* 0x00005ce0 */ + u32 tx_pkt_fifo_462_rsv3; + u32 tx_pkt_fifo_463[3]; /* 0x00005cf0 */ + u32 tx_pkt_fifo_463_rsv3; + u32 tx_pkt_fifo_464[3]; /* 0x00005d00 */ + u32 tx_pkt_fifo_464_rsv3; + u32 tx_pkt_fifo_465[3]; /* 0x00005d10 */ + u32 tx_pkt_fifo_465_rsv3; + u32 tx_pkt_fifo_466[3]; /* 0x00005d20 */ + u32 tx_pkt_fifo_466_rsv3; + u32 tx_pkt_fifo_467[3]; /* 0x00005d30 */ + u32 tx_pkt_fifo_467_rsv3; + u32 tx_pkt_fifo_468[3]; /* 0x00005d40 */ + u32 tx_pkt_fifo_468_rsv3; + u32 tx_pkt_fifo_469[3]; /* 0x00005d50 */ + u32 tx_pkt_fifo_469_rsv3; + u32 tx_pkt_fifo_470[3]; /* 0x00005d60 */ + u32 tx_pkt_fifo_470_rsv3; + u32 tx_pkt_fifo_471[3]; /* 0x00005d70 */ + u32 tx_pkt_fifo_471_rsv3; + u32 tx_pkt_fifo_472[3]; /* 0x00005d80 */ + u32 tx_pkt_fifo_472_rsv3; + u32 tx_pkt_fifo_473[3]; /* 0x00005d90 */ + u32 tx_pkt_fifo_473_rsv3; + u32 tx_pkt_fifo_474[3]; /* 0x00005da0 */ + u32 tx_pkt_fifo_474_rsv3; + u32 tx_pkt_fifo_475[3]; /* 0x00005db0 */ + u32 tx_pkt_fifo_475_rsv3; + u32 tx_pkt_fifo_476[3]; /* 0x00005dc0 */ + u32 tx_pkt_fifo_476_rsv3; + u32 tx_pkt_fifo_477[3]; /* 0x00005dd0 */ + u32 tx_pkt_fifo_477_rsv3; + u32 tx_pkt_fifo_478[3]; /* 0x00005de0 */ + u32 tx_pkt_fifo_478_rsv3; + u32 tx_pkt_fifo_479[3]; /* 0x00005df0 */ + u32 tx_pkt_fifo_479_rsv3; + u32 tx_pkt_fifo_480[3]; /* 0x00005e00 */ + u32 tx_pkt_fifo_480_rsv3; + u32 tx_pkt_fifo_481[3]; /* 0x00005e10 */ + u32 tx_pkt_fifo_481_rsv3; + u32 tx_pkt_fifo_482[3]; /* 0x00005e20 */ + u32 tx_pkt_fifo_482_rsv3; + u32 tx_pkt_fifo_483[3]; /* 0x00005e30 */ + u32 tx_pkt_fifo_483_rsv3; + u32 tx_pkt_fifo_484[3]; /* 0x00005e40 */ + u32 tx_pkt_fifo_484_rsv3; + u32 tx_pkt_fifo_485[3]; /* 0x00005e50 */ + u32 tx_pkt_fifo_485_rsv3; + u32 tx_pkt_fifo_486[3]; /* 0x00005e60 */ + u32 tx_pkt_fifo_486_rsv3; + u32 tx_pkt_fifo_487[3]; /* 0x00005e70 */ + u32 tx_pkt_fifo_487_rsv3; + u32 tx_pkt_fifo_488[3]; /* 0x00005e80 */ + u32 tx_pkt_fifo_488_rsv3; + u32 tx_pkt_fifo_489[3]; /* 0x00005e90 */ + u32 tx_pkt_fifo_489_rsv3; + u32 tx_pkt_fifo_490[3]; /* 0x00005ea0 */ + u32 tx_pkt_fifo_490_rsv3; + u32 tx_pkt_fifo_491[3]; /* 0x00005eb0 */ + u32 tx_pkt_fifo_491_rsv3; + u32 tx_pkt_fifo_492[3]; /* 0x00005ec0 */ + u32 tx_pkt_fifo_492_rsv3; + u32 tx_pkt_fifo_493[3]; /* 0x00005ed0 */ + u32 tx_pkt_fifo_493_rsv3; + u32 tx_pkt_fifo_494[3]; /* 0x00005ee0 */ + u32 tx_pkt_fifo_494_rsv3; + u32 tx_pkt_fifo_495[3]; /* 0x00005ef0 */ + u32 tx_pkt_fifo_495_rsv3; + u32 tx_pkt_fifo_496[3]; /* 0x00005f00 */ + u32 tx_pkt_fifo_496_rsv3; + u32 tx_pkt_fifo_497[3]; /* 0x00005f10 */ + u32 tx_pkt_fifo_497_rsv3; + u32 tx_pkt_fifo_498[3]; /* 0x00005f20 */ + u32 tx_pkt_fifo_498_rsv3; + u32 tx_pkt_fifo_499[3]; /* 0x00005f30 */ + u32 tx_pkt_fifo_499_rsv3; + u32 tx_pkt_fifo_500[3]; /* 0x00005f40 */ + u32 tx_pkt_fifo_500_rsv3; + u32 tx_pkt_fifo_501[3]; /* 0x00005f50 */ + u32 tx_pkt_fifo_501_rsv3; + u32 tx_pkt_fifo_502[3]; /* 0x00005f60 */ + u32 tx_pkt_fifo_502_rsv3; + u32 tx_pkt_fifo_503[3]; /* 0x00005f70 */ + u32 tx_pkt_fifo_503_rsv3; + u32 tx_pkt_fifo_504[3]; /* 0x00005f80 */ + u32 tx_pkt_fifo_504_rsv3; + u32 tx_pkt_fifo_505[3]; /* 0x00005f90 */ + u32 tx_pkt_fifo_505_rsv3; + u32 tx_pkt_fifo_506[3]; /* 0x00005fa0 */ + u32 tx_pkt_fifo_506_rsv3; + u32 tx_pkt_fifo_507[3]; /* 0x00005fb0 */ + u32 tx_pkt_fifo_507_rsv3; + u32 tx_pkt_fifo_508[3]; /* 0x00005fc0 */ + u32 tx_pkt_fifo_508_rsv3; + u32 tx_pkt_fifo_509[3]; /* 0x00005fd0 */ + u32 tx_pkt_fifo_509_rsv3; + u32 tx_pkt_fifo_510[3]; /* 0x00005fe0 */ + u32 tx_pkt_fifo_510_rsv3; + u32 tx_pkt_fifo_511[3]; /* 0x00005ff0 */ + u32 tx_pkt_fifo_511_rsv3; + u32 tx_pkt_fifo_512[3]; /* 0x00006000 */ + u32 tx_pkt_fifo_512_rsv3; + u32 tx_pkt_fifo_513[3]; /* 0x00006010 */ + u32 tx_pkt_fifo_513_rsv3; + u32 tx_pkt_fifo_514[3]; /* 0x00006020 */ + u32 tx_pkt_fifo_514_rsv3; + u32 tx_pkt_fifo_515[3]; /* 0x00006030 */ + u32 tx_pkt_fifo_515_rsv3; + u32 tx_pkt_fifo_516[3]; /* 0x00006040 */ + u32 tx_pkt_fifo_516_rsv3; + u32 tx_pkt_fifo_517[3]; /* 0x00006050 */ + u32 tx_pkt_fifo_517_rsv3; + u32 tx_pkt_fifo_518[3]; /* 0x00006060 */ + u32 tx_pkt_fifo_518_rsv3; + u32 tx_pkt_fifo_519[3]; /* 0x00006070 */ + u32 tx_pkt_fifo_519_rsv3; + u32 tx_pkt_fifo_520[3]; /* 0x00006080 */ + u32 tx_pkt_fifo_520_rsv3; + u32 tx_pkt_fifo_521[3]; /* 0x00006090 */ + u32 tx_pkt_fifo_521_rsv3; + u32 tx_pkt_fifo_522[3]; /* 0x000060a0 */ + u32 tx_pkt_fifo_522_rsv3; + u32 tx_pkt_fifo_523[3]; /* 0x000060b0 */ + u32 tx_pkt_fifo_523_rsv3; + u32 tx_pkt_fifo_524[3]; /* 0x000060c0 */ + u32 tx_pkt_fifo_524_rsv3; + u32 tx_pkt_fifo_525[3]; /* 0x000060d0 */ + u32 tx_pkt_fifo_525_rsv3; + u32 tx_pkt_fifo_526[3]; /* 0x000060e0 */ + u32 tx_pkt_fifo_526_rsv3; + u32 tx_pkt_fifo_527[3]; /* 0x000060f0 */ + u32 tx_pkt_fifo_527_rsv3; + u32 tx_pkt_fifo_528[3]; /* 0x00006100 */ + u32 tx_pkt_fifo_528_rsv3; + u32 tx_pkt_fifo_529[3]; /* 0x00006110 */ + u32 tx_pkt_fifo_529_rsv3; + u32 tx_pkt_fifo_530[3]; /* 0x00006120 */ + u32 tx_pkt_fifo_530_rsv3; + u32 tx_pkt_fifo_531[3]; /* 0x00006130 */ + u32 tx_pkt_fifo_531_rsv3; + u32 tx_pkt_fifo_532[3]; /* 0x00006140 */ + u32 tx_pkt_fifo_532_rsv3; + u32 tx_pkt_fifo_533[3]; /* 0x00006150 */ + u32 tx_pkt_fifo_533_rsv3; + u32 tx_pkt_fifo_534[3]; /* 0x00006160 */ + u32 tx_pkt_fifo_534_rsv3; + u32 tx_pkt_fifo_535[3]; /* 0x00006170 */ + u32 tx_pkt_fifo_535_rsv3; + u32 tx_pkt_fifo_536[3]; /* 0x00006180 */ + u32 tx_pkt_fifo_536_rsv3; + u32 tx_pkt_fifo_537[3]; /* 0x00006190 */ + u32 tx_pkt_fifo_537_rsv3; + u32 tx_pkt_fifo_538[3]; /* 0x000061a0 */ + u32 tx_pkt_fifo_538_rsv3; + u32 tx_pkt_fifo_539[3]; /* 0x000061b0 */ + u32 tx_pkt_fifo_539_rsv3; + u32 tx_pkt_fifo_540[3]; /* 0x000061c0 */ + u32 tx_pkt_fifo_540_rsv3; + u32 tx_pkt_fifo_541[3]; /* 0x000061d0 */ + u32 tx_pkt_fifo_541_rsv3; + u32 tx_pkt_fifo_542[3]; /* 0x000061e0 */ + u32 tx_pkt_fifo_542_rsv3; + u32 tx_pkt_fifo_543[3]; /* 0x000061f0 */ + u32 tx_pkt_fifo_543_rsv3; + u32 tx_pkt_fifo_544[3]; /* 0x00006200 */ + u32 tx_pkt_fifo_544_rsv3; + u32 tx_pkt_fifo_545[3]; /* 0x00006210 */ + u32 tx_pkt_fifo_545_rsv3; + u32 tx_pkt_fifo_546[3]; /* 0x00006220 */ + u32 tx_pkt_fifo_546_rsv3; + u32 tx_pkt_fifo_547[3]; /* 0x00006230 */ + u32 tx_pkt_fifo_547_rsv3; + u32 tx_pkt_fifo_548[3]; /* 0x00006240 */ + u32 tx_pkt_fifo_548_rsv3; + u32 tx_pkt_fifo_549[3]; /* 0x00006250 */ + u32 tx_pkt_fifo_549_rsv3; + u32 tx_pkt_fifo_550[3]; /* 0x00006260 */ + u32 tx_pkt_fifo_550_rsv3; + u32 tx_pkt_fifo_551[3]; /* 0x00006270 */ + u32 tx_pkt_fifo_551_rsv3; + u32 tx_pkt_fifo_552[3]; /* 0x00006280 */ + u32 tx_pkt_fifo_552_rsv3; + u32 tx_pkt_fifo_553[3]; /* 0x00006290 */ + u32 tx_pkt_fifo_553_rsv3; + u32 tx_pkt_fifo_554[3]; /* 0x000062a0 */ + u32 tx_pkt_fifo_554_rsv3; + u32 tx_pkt_fifo_555[3]; /* 0x000062b0 */ + u32 tx_pkt_fifo_555_rsv3; + u32 tx_pkt_fifo_556[3]; /* 0x000062c0 */ + u32 tx_pkt_fifo_556_rsv3; + u32 tx_pkt_fifo_557[3]; /* 0x000062d0 */ + u32 tx_pkt_fifo_557_rsv3; + u32 tx_pkt_fifo_558[3]; /* 0x000062e0 */ + u32 tx_pkt_fifo_558_rsv3; + u32 tx_pkt_fifo_559[3]; /* 0x000062f0 */ + u32 tx_pkt_fifo_559_rsv3; + u32 tx_pkt_fifo_560[3]; /* 0x00006300 */ + u32 tx_pkt_fifo_560_rsv3; + u32 tx_pkt_fifo_561[3]; /* 0x00006310 */ + u32 tx_pkt_fifo_561_rsv3; + u32 tx_pkt_fifo_562[3]; /* 0x00006320 */ + u32 tx_pkt_fifo_562_rsv3; + u32 tx_pkt_fifo_563[3]; /* 0x00006330 */ + u32 tx_pkt_fifo_563_rsv3; + u32 tx_pkt_fifo_564[3]; /* 0x00006340 */ + u32 tx_pkt_fifo_564_rsv3; + u32 tx_pkt_fifo_565[3]; /* 0x00006350 */ + u32 tx_pkt_fifo_565_rsv3; + u32 tx_pkt_fifo_566[3]; /* 0x00006360 */ + u32 tx_pkt_fifo_566_rsv3; + u32 tx_pkt_fifo_567[3]; /* 0x00006370 */ + u32 tx_pkt_fifo_567_rsv3; + u32 tx_pkt_fifo_568[3]; /* 0x00006380 */ + u32 tx_pkt_fifo_568_rsv3; + u32 tx_pkt_fifo_569[3]; /* 0x00006390 */ + u32 tx_pkt_fifo_569_rsv3; + u32 tx_pkt_fifo_570[3]; /* 0x000063a0 */ + u32 tx_pkt_fifo_570_rsv3; + u32 tx_pkt_fifo_571[3]; /* 0x000063b0 */ + u32 tx_pkt_fifo_571_rsv3; + u32 tx_pkt_fifo_572[3]; /* 0x000063c0 */ + u32 tx_pkt_fifo_572_rsv3; + u32 tx_pkt_fifo_573[3]; /* 0x000063d0 */ + u32 tx_pkt_fifo_573_rsv3; + u32 tx_pkt_fifo_574[3]; /* 0x000063e0 */ + u32 tx_pkt_fifo_574_rsv3; + u32 tx_pkt_fifo_575[3]; /* 0x000063f0 */ + u32 tx_pkt_fifo_575_rsv3; + u32 tx_pkt_fifo_576[3]; /* 0x00006400 */ + u32 tx_pkt_fifo_576_rsv3; + u32 tx_pkt_fifo_577[3]; /* 0x00006410 */ + u32 tx_pkt_fifo_577_rsv3; + u32 tx_pkt_fifo_578[3]; /* 0x00006420 */ + u32 tx_pkt_fifo_578_rsv3; + u32 tx_pkt_fifo_579[3]; /* 0x00006430 */ + u32 tx_pkt_fifo_579_rsv3; + u32 tx_pkt_fifo_580[3]; /* 0x00006440 */ + u32 tx_pkt_fifo_580_rsv3; + u32 tx_pkt_fifo_581[3]; /* 0x00006450 */ + u32 tx_pkt_fifo_581_rsv3; + u32 tx_pkt_fifo_582[3]; /* 0x00006460 */ + u32 tx_pkt_fifo_582_rsv3; + u32 tx_pkt_fifo_583[3]; /* 0x00006470 */ + u32 tx_pkt_fifo_583_rsv3; + u32 tx_pkt_fifo_584[3]; /* 0x00006480 */ + u32 tx_pkt_fifo_584_rsv3; + u32 tx_pkt_fifo_585[3]; /* 0x00006490 */ + u32 tx_pkt_fifo_585_rsv3; + u32 tx_pkt_fifo_586[3]; /* 0x000064a0 */ + u32 tx_pkt_fifo_586_rsv3; + u32 tx_pkt_fifo_587[3]; /* 0x000064b0 */ + u32 tx_pkt_fifo_587_rsv3; + u32 tx_pkt_fifo_588[3]; /* 0x000064c0 */ + u32 tx_pkt_fifo_588_rsv3; + u32 tx_pkt_fifo_589[3]; /* 0x000064d0 */ + u32 tx_pkt_fifo_589_rsv3; + u32 tx_pkt_fifo_590[3]; /* 0x000064e0 */ + u32 tx_pkt_fifo_590_rsv3; + u32 tx_pkt_fifo_591[3]; /* 0x000064f0 */ + u32 tx_pkt_fifo_591_rsv3; + u32 tx_pkt_fifo_592[3]; /* 0x00006500 */ + u32 tx_pkt_fifo_592_rsv3; + u32 tx_pkt_fifo_593[3]; /* 0x00006510 */ + u32 tx_pkt_fifo_593_rsv3; + u32 tx_pkt_fifo_594[3]; /* 0x00006520 */ + u32 tx_pkt_fifo_594_rsv3; + u32 tx_pkt_fifo_595[3]; /* 0x00006530 */ + u32 tx_pkt_fifo_595_rsv3; + u32 tx_pkt_fifo_596[3]; /* 0x00006540 */ + u32 tx_pkt_fifo_596_rsv3; + u32 tx_pkt_fifo_597[3]; /* 0x00006550 */ + u32 tx_pkt_fifo_597_rsv3; + u32 tx_pkt_fifo_598[3]; /* 0x00006560 */ + u32 tx_pkt_fifo_598_rsv3; + u32 tx_pkt_fifo_599[3]; /* 0x00006570 */ + u32 tx_pkt_fifo_599_rsv3; + u32 tx_pkt_fifo_600[3]; /* 0x00006580 */ + u32 tx_pkt_fifo_600_rsv3; + u32 tx_pkt_fifo_601[3]; /* 0x00006590 */ + u32 tx_pkt_fifo_601_rsv3; + u32 tx_pkt_fifo_602[3]; /* 0x000065a0 */ + u32 tx_pkt_fifo_602_rsv3; + u32 tx_pkt_fifo_603[3]; /* 0x000065b0 */ + u32 tx_pkt_fifo_603_rsv3; + u32 tx_pkt_fifo_604[3]; /* 0x000065c0 */ + u32 tx_pkt_fifo_604_rsv3; + u32 tx_pkt_fifo_605[3]; /* 0x000065d0 */ + u32 tx_pkt_fifo_605_rsv3; + u32 tx_pkt_fifo_606[3]; /* 0x000065e0 */ + u32 tx_pkt_fifo_606_rsv3; + u32 tx_pkt_fifo_607[3]; /* 0x000065f0 */ + u32 tx_pkt_fifo_607_rsv3; + u32 tx_pkt_fifo_608[3]; /* 0x00006600 */ + u32 tx_pkt_fifo_608_rsv3; + u32 tx_pkt_fifo_609[3]; /* 0x00006610 */ + u32 tx_pkt_fifo_609_rsv3; + u32 tx_pkt_fifo_610[3]; /* 0x00006620 */ + u32 tx_pkt_fifo_610_rsv3; + u32 tx_pkt_fifo_611[3]; /* 0x00006630 */ + u32 tx_pkt_fifo_611_rsv3; + u32 tx_pkt_fifo_612[3]; /* 0x00006640 */ + u32 tx_pkt_fifo_612_rsv3; + u32 tx_pkt_fifo_613[3]; /* 0x00006650 */ + u32 tx_pkt_fifo_613_rsv3; + u32 tx_pkt_fifo_614[3]; /* 0x00006660 */ + u32 tx_pkt_fifo_614_rsv3; + u32 tx_pkt_fifo_615[3]; /* 0x00006670 */ + u32 tx_pkt_fifo_615_rsv3; + u32 tx_pkt_fifo_616[3]; /* 0x00006680 */ + u32 tx_pkt_fifo_616_rsv3; + u32 tx_pkt_fifo_617[3]; /* 0x00006690 */ + u32 tx_pkt_fifo_617_rsv3; + u32 tx_pkt_fifo_618[3]; /* 0x000066a0 */ + u32 tx_pkt_fifo_618_rsv3; + u32 tx_pkt_fifo_619[3]; /* 0x000066b0 */ + u32 tx_pkt_fifo_619_rsv3; + u32 tx_pkt_fifo_620[3]; /* 0x000066c0 */ + u32 tx_pkt_fifo_620_rsv3; + u32 tx_pkt_fifo_621[3]; /* 0x000066d0 */ + u32 tx_pkt_fifo_621_rsv3; + u32 tx_pkt_fifo_622[3]; /* 0x000066e0 */ + u32 tx_pkt_fifo_622_rsv3; + u32 tx_pkt_fifo_623[3]; /* 0x000066f0 */ + u32 tx_pkt_fifo_623_rsv3; + u32 tx_pkt_fifo_624[3]; /* 0x00006700 */ + u32 tx_pkt_fifo_624_rsv3; + u32 tx_pkt_fifo_625[3]; /* 0x00006710 */ + u32 tx_pkt_fifo_625_rsv3; + u32 tx_pkt_fifo_626[3]; /* 0x00006720 */ + u32 tx_pkt_fifo_626_rsv3; + u32 tx_pkt_fifo_627[3]; /* 0x00006730 */ + u32 tx_pkt_fifo_627_rsv3; + u32 tx_pkt_fifo_628[3]; /* 0x00006740 */ + u32 tx_pkt_fifo_628_rsv3; + u32 tx_pkt_fifo_629[3]; /* 0x00006750 */ + u32 tx_pkt_fifo_629_rsv3; + u32 tx_pkt_fifo_630[3]; /* 0x00006760 */ + u32 tx_pkt_fifo_630_rsv3; + u32 tx_pkt_fifo_631[3]; /* 0x00006770 */ + u32 tx_pkt_fifo_631_rsv3; + u32 tx_pkt_fifo_632[3]; /* 0x00006780 */ + u32 tx_pkt_fifo_632_rsv3; + u32 tx_pkt_fifo_633[3]; /* 0x00006790 */ + u32 tx_pkt_fifo_633_rsv3; + u32 tx_pkt_fifo_634[3]; /* 0x000067a0 */ + u32 tx_pkt_fifo_634_rsv3; + u32 tx_pkt_fifo_635[3]; /* 0x000067b0 */ + u32 tx_pkt_fifo_635_rsv3; + u32 tx_pkt_fifo_636[3]; /* 0x000067c0 */ + u32 tx_pkt_fifo_636_rsv3; + u32 tx_pkt_fifo_637[3]; /* 0x000067d0 */ + u32 tx_pkt_fifo_637_rsv3; + u32 tx_pkt_fifo_638[3]; /* 0x000067e0 */ + u32 tx_pkt_fifo_638_rsv3; + u32 tx_pkt_fifo_639[3]; /* 0x000067f0 */ + u32 tx_pkt_fifo_639_rsv3; + u32 rsv6656; + u32 rsv6657; + u32 rsv6658; + u32 rsv6659; + u32 rsv6660; + u32 rsv6661; + u32 rsv6662; + u32 rsv6663; + u32 rsv6664; + u32 rsv6665; + u32 rsv6666; + u32 rsv6667; + u32 rsv6668; + u32 rsv6669; + u32 rsv6670; + u32 rsv6671; + u32 rsv6672; + u32 rsv6673; + u32 rsv6674; + u32 rsv6675; + u32 rsv6676; + u32 rsv6677; + u32 rsv6678; + u32 rsv6679; + u32 rsv6680; + u32 rsv6681; + u32 rsv6682; + u32 rsv6683; + u32 rsv6684; + u32 rsv6685; + u32 rsv6686; + u32 rsv6687; + u32 rsv6688; + u32 rsv6689; + u32 rsv6690; + u32 rsv6691; + u32 rsv6692; + u32 rsv6693; + u32 rsv6694; + u32 rsv6695; + u32 rsv6696; + u32 rsv6697; + u32 rsv6698; + u32 rsv6699; + u32 rsv6700; + u32 rsv6701; + u32 rsv6702; + u32 rsv6703; + u32 rsv6704; + u32 rsv6705; + u32 rsv6706; + u32 rsv6707; + u32 rsv6708; + u32 rsv6709; + u32 rsv6710; + u32 rsv6711; + u32 rsv6712; + u32 rsv6713; + u32 rsv6714; + u32 rsv6715; + u32 rsv6716; + u32 rsv6717; + u32 rsv6718; + u32 rsv6719; + u32 rsv6720; + u32 rsv6721; + u32 rsv6722; + u32 rsv6723; + u32 rsv6724; + u32 rsv6725; + u32 rsv6726; + u32 rsv6727; + u32 rsv6728; + u32 rsv6729; + u32 rsv6730; + u32 rsv6731; + u32 rsv6732; + u32 rsv6733; + u32 rsv6734; + u32 rsv6735; + u32 rsv6736; + u32 rsv6737; + u32 rsv6738; + u32 rsv6739; + u32 rsv6740; + u32 rsv6741; + u32 rsv6742; + u32 rsv6743; + u32 rsv6744; + u32 rsv6745; + u32 rsv6746; + u32 rsv6747; + u32 rsv6748; + u32 rsv6749; + u32 rsv6750; + u32 rsv6751; + u32 rsv6752; + u32 rsv6753; + u32 rsv6754; + u32 rsv6755; + u32 rsv6756; + u32 rsv6757; + u32 rsv6758; + u32 rsv6759; + u32 rsv6760; + u32 rsv6761; + u32 rsv6762; + u32 rsv6763; + u32 rsv6764; + u32 rsv6765; + u32 rsv6766; + u32 rsv6767; + u32 rsv6768; + u32 rsv6769; + u32 rsv6770; + u32 rsv6771; + u32 rsv6772; + u32 rsv6773; + u32 rsv6774; + u32 rsv6775; + u32 rsv6776; + u32 rsv6777; + u32 rsv6778; + u32 rsv6779; + u32 rsv6780; + u32 rsv6781; + u32 rsv6782; + u32 rsv6783; + u32 rsv6784; + u32 rsv6785; + u32 rsv6786; + u32 rsv6787; + u32 rsv6788; + u32 rsv6789; + u32 rsv6790; + u32 rsv6791; + u32 rsv6792; + u32 rsv6793; + u32 rsv6794; + u32 rsv6795; + u32 rsv6796; + u32 rsv6797; + u32 rsv6798; + u32 rsv6799; + u32 rsv6800; + u32 rsv6801; + u32 rsv6802; + u32 rsv6803; + u32 rsv6804; + u32 rsv6805; + u32 rsv6806; + u32 rsv6807; + u32 rsv6808; + u32 rsv6809; + u32 rsv6810; + u32 rsv6811; + u32 rsv6812; + u32 rsv6813; + u32 rsv6814; + u32 rsv6815; + u32 rsv6816; + u32 rsv6817; + u32 rsv6818; + u32 rsv6819; + u32 rsv6820; + u32 rsv6821; + u32 rsv6822; + u32 rsv6823; + u32 rsv6824; + u32 rsv6825; + u32 rsv6826; + u32 rsv6827; + u32 rsv6828; + u32 rsv6829; + u32 rsv6830; + u32 rsv6831; + u32 rsv6832; + u32 rsv6833; + u32 rsv6834; + u32 rsv6835; + u32 rsv6836; + u32 rsv6837; + u32 rsv6838; + u32 rsv6839; + u32 rsv6840; + u32 rsv6841; + u32 rsv6842; + u32 rsv6843; + u32 rsv6844; + u32 rsv6845; + u32 rsv6846; + u32 rsv6847; + u32 rsv6848; + u32 rsv6849; + u32 rsv6850; + u32 rsv6851; + u32 rsv6852; + u32 rsv6853; + u32 rsv6854; + u32 rsv6855; + u32 rsv6856; + u32 rsv6857; + u32 rsv6858; + u32 rsv6859; + u32 rsv6860; + u32 rsv6861; + u32 rsv6862; + u32 rsv6863; + u32 rsv6864; + u32 rsv6865; + u32 rsv6866; + u32 rsv6867; + u32 rsv6868; + u32 rsv6869; + u32 rsv6870; + u32 rsv6871; + u32 rsv6872; + u32 rsv6873; + u32 rsv6874; + u32 rsv6875; + u32 rsv6876; + u32 rsv6877; + u32 rsv6878; + u32 rsv6879; + u32 rsv6880; + u32 rsv6881; + u32 rsv6882; + u32 rsv6883; + u32 rsv6884; + u32 rsv6885; + u32 rsv6886; + u32 rsv6887; + u32 rsv6888; + u32 rsv6889; + u32 rsv6890; + u32 rsv6891; + u32 rsv6892; + u32 rsv6893; + u32 rsv6894; + u32 rsv6895; + u32 rsv6896; + u32 rsv6897; + u32 rsv6898; + u32 rsv6899; + u32 rsv6900; + u32 rsv6901; + u32 rsv6902; + u32 rsv6903; + u32 rsv6904; + u32 rsv6905; + u32 rsv6906; + u32 rsv6907; + u32 rsv6908; + u32 rsv6909; + u32 rsv6910; + u32 rsv6911; + u32 rsv6912; + u32 rsv6913; + u32 rsv6914; + u32 rsv6915; + u32 rsv6916; + u32 rsv6917; + u32 rsv6918; + u32 rsv6919; + u32 rsv6920; + u32 rsv6921; + u32 rsv6922; + u32 rsv6923; + u32 rsv6924; + u32 rsv6925; + u32 rsv6926; + u32 rsv6927; + u32 rsv6928; + u32 rsv6929; + u32 rsv6930; + u32 rsv6931; + u32 rsv6932; + u32 rsv6933; + u32 rsv6934; + u32 rsv6935; + u32 rsv6936; + u32 rsv6937; + u32 rsv6938; + u32 rsv6939; + u32 rsv6940; + u32 rsv6941; + u32 rsv6942; + u32 rsv6943; + u32 rsv6944; + u32 rsv6945; + u32 rsv6946; + u32 rsv6947; + u32 rsv6948; + u32 rsv6949; + u32 rsv6950; + u32 rsv6951; + u32 rsv6952; + u32 rsv6953; + u32 rsv6954; + u32 rsv6955; + u32 rsv6956; + u32 rsv6957; + u32 rsv6958; + u32 rsv6959; + u32 rsv6960; + u32 rsv6961; + u32 rsv6962; + u32 rsv6963; + u32 rsv6964; + u32 rsv6965; + u32 rsv6966; + u32 rsv6967; + u32 rsv6968; + u32 rsv6969; + u32 rsv6970; + u32 rsv6971; + u32 rsv6972; + u32 rsv6973; + u32 rsv6974; + u32 rsv6975; + u32 rsv6976; + u32 rsv6977; + u32 rsv6978; + u32 rsv6979; + u32 rsv6980; + u32 rsv6981; + u32 rsv6982; + u32 rsv6983; + u32 rsv6984; + u32 rsv6985; + u32 rsv6986; + u32 rsv6987; + u32 rsv6988; + u32 rsv6989; + u32 rsv6990; + u32 rsv6991; + u32 rsv6992; + u32 rsv6993; + u32 rsv6994; + u32 rsv6995; + u32 rsv6996; + u32 rsv6997; + u32 rsv6998; + u32 rsv6999; + u32 rsv7000; + u32 rsv7001; + u32 rsv7002; + u32 rsv7003; + u32 rsv7004; + u32 rsv7005; + u32 rsv7006; + u32 rsv7007; + u32 rsv7008; + u32 rsv7009; + u32 rsv7010; + u32 rsv7011; + u32 rsv7012; + u32 rsv7013; + u32 rsv7014; + u32 rsv7015; + u32 rsv7016; + u32 rsv7017; + u32 rsv7018; + u32 rsv7019; + u32 rsv7020; + u32 rsv7021; + u32 rsv7022; + u32 rsv7023; + u32 rsv7024; + u32 rsv7025; + u32 rsv7026; + u32 rsv7027; + u32 rsv7028; + u32 rsv7029; + u32 rsv7030; + u32 rsv7031; + u32 rsv7032; + u32 rsv7033; + u32 rsv7034; + u32 rsv7035; + u32 rsv7036; + u32 rsv7037; + u32 rsv7038; + u32 rsv7039; + u32 rsv7040; + u32 rsv7041; + u32 rsv7042; + u32 rsv7043; + u32 rsv7044; + u32 rsv7045; + u32 rsv7046; + u32 rsv7047; + u32 rsv7048; + u32 rsv7049; + u32 rsv7050; + u32 rsv7051; + u32 rsv7052; + u32 rsv7053; + u32 rsv7054; + u32 rsv7055; + u32 rsv7056; + u32 rsv7057; + u32 rsv7058; + u32 rsv7059; + u32 rsv7060; + u32 rsv7061; + u32 rsv7062; + u32 rsv7063; + u32 rsv7064; + u32 rsv7065; + u32 rsv7066; + u32 rsv7067; + u32 rsv7068; + u32 rsv7069; + u32 rsv7070; + u32 rsv7071; + u32 rsv7072; + u32 rsv7073; + u32 rsv7074; + u32 rsv7075; + u32 rsv7076; + u32 rsv7077; + u32 rsv7078; + u32 rsv7079; + u32 rsv7080; + u32 rsv7081; + u32 rsv7082; + u32 rsv7083; + u32 rsv7084; + u32 rsv7085; + u32 rsv7086; + u32 rsv7087; + u32 rsv7088; + u32 rsv7089; + u32 rsv7090; + u32 rsv7091; + u32 rsv7092; + u32 rsv7093; + u32 rsv7094; + u32 rsv7095; + u32 rsv7096; + u32 rsv7097; + u32 rsv7098; + u32 rsv7099; + u32 rsv7100; + u32 rsv7101; + u32 rsv7102; + u32 rsv7103; + u32 rsv7104; + u32 rsv7105; + u32 rsv7106; + u32 rsv7107; + u32 rsv7108; + u32 rsv7109; + u32 rsv7110; + u32 rsv7111; + u32 rsv7112; + u32 rsv7113; + u32 rsv7114; + u32 rsv7115; + u32 rsv7116; + u32 rsv7117; + u32 rsv7118; + u32 rsv7119; + u32 rsv7120; + u32 rsv7121; + u32 rsv7122; + u32 rsv7123; + u32 rsv7124; + u32 rsv7125; + u32 rsv7126; + u32 rsv7127; + u32 rsv7128; + u32 rsv7129; + u32 rsv7130; + u32 rsv7131; + u32 rsv7132; + u32 rsv7133; + u32 rsv7134; + u32 rsv7135; + u32 rsv7136; + u32 rsv7137; + u32 rsv7138; + u32 rsv7139; + u32 rsv7140; + u32 rsv7141; + u32 rsv7142; + u32 rsv7143; + u32 rsv7144; + u32 rsv7145; + u32 rsv7146; + u32 rsv7147; + u32 rsv7148; + u32 rsv7149; + u32 rsv7150; + u32 rsv7151; + u32 rsv7152; + u32 rsv7153; + u32 rsv7154; + u32 rsv7155; + u32 rsv7156; + u32 rsv7157; + u32 rsv7158; + u32 rsv7159; + u32 rsv7160; + u32 rsv7161; + u32 rsv7162; + u32 rsv7163; + u32 rsv7164; + u32 rsv7165; + u32 rsv7166; + u32 rsv7167; + u32 rsv7168; + u32 rsv7169; + u32 rsv7170; + u32 rsv7171; + u32 rsv7172; + u32 rsv7173; + u32 rsv7174; + u32 rsv7175; + u32 rsv7176; + u32 rsv7177; + u32 rsv7178; + u32 rsv7179; + u32 rsv7180; + u32 rsv7181; + u32 rsv7182; + u32 rsv7183; + u32 rsv7184; + u32 rsv7185; + u32 rsv7186; + u32 rsv7187; + u32 rsv7188; + u32 rsv7189; + u32 rsv7190; + u32 rsv7191; + u32 rsv7192; + u32 rsv7193; + u32 rsv7194; + u32 rsv7195; + u32 rsv7196; + u32 rsv7197; + u32 rsv7198; + u32 rsv7199; + u32 rsv7200; + u32 rsv7201; + u32 rsv7202; + u32 rsv7203; + u32 rsv7204; + u32 rsv7205; + u32 rsv7206; + u32 rsv7207; + u32 rsv7208; + u32 rsv7209; + u32 rsv7210; + u32 rsv7211; + u32 rsv7212; + u32 rsv7213; + u32 rsv7214; + u32 rsv7215; + u32 rsv7216; + u32 rsv7217; + u32 rsv7218; + u32 rsv7219; + u32 rsv7220; + u32 rsv7221; + u32 rsv7222; + u32 rsv7223; + u32 rsv7224; + u32 rsv7225; + u32 rsv7226; + u32 rsv7227; + u32 rsv7228; + u32 rsv7229; + u32 rsv7230; + u32 rsv7231; + u32 rsv7232; + u32 rsv7233; + u32 rsv7234; + u32 rsv7235; + u32 rsv7236; + u32 rsv7237; + u32 rsv7238; + u32 rsv7239; + u32 rsv7240; + u32 rsv7241; + u32 rsv7242; + u32 rsv7243; + u32 rsv7244; + u32 rsv7245; + u32 rsv7246; + u32 rsv7247; + u32 rsv7248; + u32 rsv7249; + u32 rsv7250; + u32 rsv7251; + u32 rsv7252; + u32 rsv7253; + u32 rsv7254; + u32 rsv7255; + u32 rsv7256; + u32 rsv7257; + u32 rsv7258; + u32 rsv7259; + u32 rsv7260; + u32 rsv7261; + u32 rsv7262; + u32 rsv7263; + u32 rsv7264; + u32 rsv7265; + u32 rsv7266; + u32 rsv7267; + u32 rsv7268; + u32 rsv7269; + u32 rsv7270; + u32 rsv7271; + u32 rsv7272; + u32 rsv7273; + u32 rsv7274; + u32 rsv7275; + u32 rsv7276; + u32 rsv7277; + u32 rsv7278; + u32 rsv7279; + u32 rsv7280; + u32 rsv7281; + u32 rsv7282; + u32 rsv7283; + u32 rsv7284; + u32 rsv7285; + u32 rsv7286; + u32 rsv7287; + u32 rsv7288; + u32 rsv7289; + u32 rsv7290; + u32 rsv7291; + u32 rsv7292; + u32 rsv7293; + u32 rsv7294; + u32 rsv7295; + u32 rsv7296; + u32 rsv7297; + u32 rsv7298; + u32 rsv7299; + u32 rsv7300; + u32 rsv7301; + u32 rsv7302; + u32 rsv7303; + u32 rsv7304; + u32 rsv7305; + u32 rsv7306; + u32 rsv7307; + u32 rsv7308; + u32 rsv7309; + u32 rsv7310; + u32 rsv7311; + u32 rsv7312; + u32 rsv7313; + u32 rsv7314; + u32 rsv7315; + u32 rsv7316; + u32 rsv7317; + u32 rsv7318; + u32 rsv7319; + u32 rsv7320; + u32 rsv7321; + u32 rsv7322; + u32 rsv7323; + u32 rsv7324; + u32 rsv7325; + u32 rsv7326; + u32 rsv7327; + u32 rsv7328; + u32 rsv7329; + u32 rsv7330; + u32 rsv7331; + u32 rsv7332; + u32 rsv7333; + u32 rsv7334; + u32 rsv7335; + u32 rsv7336; + u32 rsv7337; + u32 rsv7338; + u32 rsv7339; + u32 rsv7340; + u32 rsv7341; + u32 rsv7342; + u32 rsv7343; + u32 rsv7344; + u32 rsv7345; + u32 rsv7346; + u32 rsv7347; + u32 rsv7348; + u32 rsv7349; + u32 rsv7350; + u32 rsv7351; + u32 rsv7352; + u32 rsv7353; + u32 rsv7354; + u32 rsv7355; + u32 rsv7356; + u32 rsv7357; + u32 rsv7358; + u32 rsv7359; + u32 rsv7360; + u32 rsv7361; + u32 rsv7362; + u32 rsv7363; + u32 rsv7364; + u32 rsv7365; + u32 rsv7366; + u32 rsv7367; + u32 rsv7368; + u32 rsv7369; + u32 rsv7370; + u32 rsv7371; + u32 rsv7372; + u32 rsv7373; + u32 rsv7374; + u32 rsv7375; + u32 rsv7376; + u32 rsv7377; + u32 rsv7378; + u32 rsv7379; + u32 rsv7380; + u32 rsv7381; + u32 rsv7382; + u32 rsv7383; + u32 rsv7384; + u32 rsv7385; + u32 rsv7386; + u32 rsv7387; + u32 rsv7388; + u32 rsv7389; + u32 rsv7390; + u32 rsv7391; + u32 rsv7392; + u32 rsv7393; + u32 rsv7394; + u32 rsv7395; + u32 rsv7396; + u32 rsv7397; + u32 rsv7398; + u32 rsv7399; + u32 rsv7400; + u32 rsv7401; + u32 rsv7402; + u32 rsv7403; + u32 rsv7404; + u32 rsv7405; + u32 rsv7406; + u32 rsv7407; + u32 rsv7408; + u32 rsv7409; + u32 rsv7410; + u32 rsv7411; + u32 rsv7412; + u32 rsv7413; + u32 rsv7414; + u32 rsv7415; + u32 rsv7416; + u32 rsv7417; + u32 rsv7418; + u32 rsv7419; + u32 rsv7420; + u32 rsv7421; + u32 rsv7422; + u32 rsv7423; + u32 rsv7424; + u32 rsv7425; + u32 rsv7426; + u32 rsv7427; + u32 rsv7428; + u32 rsv7429; + u32 rsv7430; + u32 rsv7431; + u32 rsv7432; + u32 rsv7433; + u32 rsv7434; + u32 rsv7435; + u32 rsv7436; + u32 rsv7437; + u32 rsv7438; + u32 rsv7439; + u32 rsv7440; + u32 rsv7441; + u32 rsv7442; + u32 rsv7443; + u32 rsv7444; + u32 rsv7445; + u32 rsv7446; + u32 rsv7447; + u32 rsv7448; + u32 rsv7449; + u32 rsv7450; + u32 rsv7451; + u32 rsv7452; + u32 rsv7453; + u32 rsv7454; + u32 rsv7455; + u32 rsv7456; + u32 rsv7457; + u32 rsv7458; + u32 rsv7459; + u32 rsv7460; + u32 rsv7461; + u32 rsv7462; + u32 rsv7463; + u32 rsv7464; + u32 rsv7465; + u32 rsv7466; + u32 rsv7467; + u32 rsv7468; + u32 rsv7469; + u32 rsv7470; + u32 rsv7471; + u32 rsv7472; + u32 rsv7473; + u32 rsv7474; + u32 rsv7475; + u32 rsv7476; + u32 rsv7477; + u32 rsv7478; + u32 rsv7479; + u32 rsv7480; + u32 rsv7481; + u32 rsv7482; + u32 rsv7483; + u32 rsv7484; + u32 rsv7485; + u32 rsv7486; + u32 rsv7487; + u32 rsv7488; + u32 rsv7489; + u32 rsv7490; + u32 rsv7491; + u32 rsv7492; + u32 rsv7493; + u32 rsv7494; + u32 rsv7495; + u32 rsv7496; + u32 rsv7497; + u32 rsv7498; + u32 rsv7499; + u32 rsv7500; + u32 rsv7501; + u32 rsv7502; + u32 rsv7503; + u32 rsv7504; + u32 rsv7505; + u32 rsv7506; + u32 rsv7507; + u32 rsv7508; + u32 rsv7509; + u32 rsv7510; + u32 rsv7511; + u32 rsv7512; + u32 rsv7513; + u32 rsv7514; + u32 rsv7515; + u32 rsv7516; + u32 rsv7517; + u32 rsv7518; + u32 rsv7519; + u32 rsv7520; + u32 rsv7521; + u32 rsv7522; + u32 rsv7523; + u32 rsv7524; + u32 rsv7525; + u32 rsv7526; + u32 rsv7527; + u32 rsv7528; + u32 rsv7529; + u32 rsv7530; + u32 rsv7531; + u32 rsv7532; + u32 rsv7533; + u32 rsv7534; + u32 rsv7535; + u32 rsv7536; + u32 rsv7537; + u32 rsv7538; + u32 rsv7539; + u32 rsv7540; + u32 rsv7541; + u32 rsv7542; + u32 rsv7543; + u32 rsv7544; + u32 rsv7545; + u32 rsv7546; + u32 rsv7547; + u32 rsv7548; + u32 rsv7549; + u32 rsv7550; + u32 rsv7551; + u32 rsv7552; + u32 rsv7553; + u32 rsv7554; + u32 rsv7555; + u32 rsv7556; + u32 rsv7557; + u32 rsv7558; + u32 rsv7559; + u32 rsv7560; + u32 rsv7561; + u32 rsv7562; + u32 rsv7563; + u32 rsv7564; + u32 rsv7565; + u32 rsv7566; + u32 rsv7567; + u32 rsv7568; + u32 rsv7569; + u32 rsv7570; + u32 rsv7571; + u32 rsv7572; + u32 rsv7573; + u32 rsv7574; + u32 rsv7575; + u32 rsv7576; + u32 rsv7577; + u32 rsv7578; + u32 rsv7579; + u32 rsv7580; + u32 rsv7581; + u32 rsv7582; + u32 rsv7583; + u32 rsv7584; + u32 rsv7585; + u32 rsv7586; + u32 rsv7587; + u32 rsv7588; + u32 rsv7589; + u32 rsv7590; + u32 rsv7591; + u32 rsv7592; + u32 rsv7593; + u32 rsv7594; + u32 rsv7595; + u32 rsv7596; + u32 rsv7597; + u32 rsv7598; + u32 rsv7599; + u32 rsv7600; + u32 rsv7601; + u32 rsv7602; + u32 rsv7603; + u32 rsv7604; + u32 rsv7605; + u32 rsv7606; + u32 rsv7607; + u32 rsv7608; + u32 rsv7609; + u32 rsv7610; + u32 rsv7611; + u32 rsv7612; + u32 rsv7613; + u32 rsv7614; + u32 rsv7615; + u32 rsv7616; + u32 rsv7617; + u32 rsv7618; + u32 rsv7619; + u32 rsv7620; + u32 rsv7621; + u32 rsv7622; + u32 rsv7623; + u32 rsv7624; + u32 rsv7625; + u32 rsv7626; + u32 rsv7627; + u32 rsv7628; + u32 rsv7629; + u32 rsv7630; + u32 rsv7631; + u32 rsv7632; + u32 rsv7633; + u32 rsv7634; + u32 rsv7635; + u32 rsv7636; + u32 rsv7637; + u32 rsv7638; + u32 rsv7639; + u32 rsv7640; + u32 rsv7641; + u32 rsv7642; + u32 rsv7643; + u32 rsv7644; + u32 rsv7645; + u32 rsv7646; + u32 rsv7647; + u32 rsv7648; + u32 rsv7649; + u32 rsv7650; + u32 rsv7651; + u32 rsv7652; + u32 rsv7653; + u32 rsv7654; + u32 rsv7655; + u32 rsv7656; + u32 rsv7657; + u32 rsv7658; + u32 rsv7659; + u32 rsv7660; + u32 rsv7661; + u32 rsv7662; + u32 rsv7663; + u32 rsv7664; + u32 rsv7665; + u32 rsv7666; + u32 rsv7667; + u32 rsv7668; + u32 rsv7669; + u32 rsv7670; + u32 rsv7671; + u32 rsv7672; + u32 rsv7673; + u32 rsv7674; + u32 rsv7675; + u32 rsv7676; + u32 rsv7677; + u32 rsv7678; + u32 rsv7679; + u32 rsv7680; + u32 rsv7681; + u32 rsv7682; + u32 rsv7683; + u32 rsv7684; + u32 rsv7685; + u32 rsv7686; + u32 rsv7687; + u32 rsv7688; + u32 rsv7689; + u32 rsv7690; + u32 rsv7691; + u32 rsv7692; + u32 rsv7693; + u32 rsv7694; + u32 rsv7695; + u32 rsv7696; + u32 rsv7697; + u32 rsv7698; + u32 rsv7699; + u32 rsv7700; + u32 rsv7701; + u32 rsv7702; + u32 rsv7703; + u32 rsv7704; + u32 rsv7705; + u32 rsv7706; + u32 rsv7707; + u32 rsv7708; + u32 rsv7709; + u32 rsv7710; + u32 rsv7711; + u32 rsv7712; + u32 rsv7713; + u32 rsv7714; + u32 rsv7715; + u32 rsv7716; + u32 rsv7717; + u32 rsv7718; + u32 rsv7719; + u32 rsv7720; + u32 rsv7721; + u32 rsv7722; + u32 rsv7723; + u32 rsv7724; + u32 rsv7725; + u32 rsv7726; + u32 rsv7727; + u32 rsv7728; + u32 rsv7729; + u32 rsv7730; + u32 rsv7731; + u32 rsv7732; + u32 rsv7733; + u32 rsv7734; + u32 rsv7735; + u32 rsv7736; + u32 rsv7737; + u32 rsv7738; + u32 rsv7739; + u32 rsv7740; + u32 rsv7741; + u32 rsv7742; + u32 rsv7743; + u32 rsv7744; + u32 rsv7745; + u32 rsv7746; + u32 rsv7747; + u32 rsv7748; + u32 rsv7749; + u32 rsv7750; + u32 rsv7751; + u32 rsv7752; + u32 rsv7753; + u32 rsv7754; + u32 rsv7755; + u32 rsv7756; + u32 rsv7757; + u32 rsv7758; + u32 rsv7759; + u32 rsv7760; + u32 rsv7761; + u32 rsv7762; + u32 rsv7763; + u32 rsv7764; + u32 rsv7765; + u32 rsv7766; + u32 rsv7767; + u32 rsv7768; + u32 rsv7769; + u32 rsv7770; + u32 rsv7771; + u32 rsv7772; + u32 rsv7773; + u32 rsv7774; + u32 rsv7775; + u32 rsv7776; + u32 rsv7777; + u32 rsv7778; + u32 rsv7779; + u32 rsv7780; + u32 rsv7781; + u32 rsv7782; + u32 rsv7783; + u32 rsv7784; + u32 rsv7785; + u32 rsv7786; + u32 rsv7787; + u32 rsv7788; + u32 rsv7789; + u32 rsv7790; + u32 rsv7791; + u32 rsv7792; + u32 rsv7793; + u32 rsv7794; + u32 rsv7795; + u32 rsv7796; + u32 rsv7797; + u32 rsv7798; + u32 rsv7799; + u32 rsv7800; + u32 rsv7801; + u32 rsv7802; + u32 rsv7803; + u32 rsv7804; + u32 rsv7805; + u32 rsv7806; + u32 rsv7807; + u32 rsv7808; + u32 rsv7809; + u32 rsv7810; + u32 rsv7811; + u32 rsv7812; + u32 rsv7813; + u32 rsv7814; + u32 rsv7815; + u32 rsv7816; + u32 rsv7817; + u32 rsv7818; + u32 rsv7819; + u32 rsv7820; + u32 rsv7821; + u32 rsv7822; + u32 rsv7823; + u32 rsv7824; + u32 rsv7825; + u32 rsv7826; + u32 rsv7827; + u32 rsv7828; + u32 rsv7829; + u32 rsv7830; + u32 rsv7831; + u32 rsv7832; + u32 rsv7833; + u32 rsv7834; + u32 rsv7835; + u32 rsv7836; + u32 rsv7837; + u32 rsv7838; + u32 rsv7839; + u32 rsv7840; + u32 rsv7841; + u32 rsv7842; + u32 rsv7843; + u32 rsv7844; + u32 rsv7845; + u32 rsv7846; + u32 rsv7847; + u32 rsv7848; + u32 rsv7849; + u32 rsv7850; + u32 rsv7851; + u32 rsv7852; + u32 rsv7853; + u32 rsv7854; + u32 rsv7855; + u32 rsv7856; + u32 rsv7857; + u32 rsv7858; + u32 rsv7859; + u32 rsv7860; + u32 rsv7861; + u32 rsv7862; + u32 rsv7863; + u32 rsv7864; + u32 rsv7865; + u32 rsv7866; + u32 rsv7867; + u32 rsv7868; + u32 rsv7869; + u32 rsv7870; + u32 rsv7871; + u32 rsv7872; + u32 rsv7873; + u32 rsv7874; + u32 rsv7875; + u32 rsv7876; + u32 rsv7877; + u32 rsv7878; + u32 rsv7879; + u32 rsv7880; + u32 rsv7881; + u32 rsv7882; + u32 rsv7883; + u32 rsv7884; + u32 rsv7885; + u32 rsv7886; + u32 rsv7887; + u32 rsv7888; + u32 rsv7889; + u32 rsv7890; + u32 rsv7891; + u32 rsv7892; + u32 rsv7893; + u32 rsv7894; + u32 rsv7895; + u32 rsv7896; + u32 rsv7897; + u32 rsv7898; + u32 rsv7899; + u32 rsv7900; + u32 rsv7901; + u32 rsv7902; + u32 rsv7903; + u32 rsv7904; + u32 rsv7905; + u32 rsv7906; + u32 rsv7907; + u32 rsv7908; + u32 rsv7909; + u32 rsv7910; + u32 rsv7911; + u32 rsv7912; + u32 rsv7913; + u32 rsv7914; + u32 rsv7915; + u32 rsv7916; + u32 rsv7917; + u32 rsv7918; + u32 rsv7919; + u32 rsv7920; + u32 rsv7921; + u32 rsv7922; + u32 rsv7923; + u32 rsv7924; + u32 rsv7925; + u32 rsv7926; + u32 rsv7927; + u32 rsv7928; + u32 rsv7929; + u32 rsv7930; + u32 rsv7931; + u32 rsv7932; + u32 rsv7933; + u32 rsv7934; + u32 rsv7935; + u32 rsv7936; + u32 rsv7937; + u32 rsv7938; + u32 rsv7939; + u32 rsv7940; + u32 rsv7941; + u32 rsv7942; + u32 rsv7943; + u32 rsv7944; + u32 rsv7945; + u32 rsv7946; + u32 rsv7947; + u32 rsv7948; + u32 rsv7949; + u32 rsv7950; + u32 rsv7951; + u32 rsv7952; + u32 rsv7953; + u32 rsv7954; + u32 rsv7955; + u32 rsv7956; + u32 rsv7957; + u32 rsv7958; + u32 rsv7959; + u32 rsv7960; + u32 rsv7961; + u32 rsv7962; + u32 rsv7963; + u32 rsv7964; + u32 rsv7965; + u32 rsv7966; + u32 rsv7967; + u32 rsv7968; + u32 rsv7969; + u32 rsv7970; + u32 rsv7971; + u32 rsv7972; + u32 rsv7973; + u32 rsv7974; + u32 rsv7975; + u32 rsv7976; + u32 rsv7977; + u32 rsv7978; + u32 rsv7979; + u32 rsv7980; + u32 rsv7981; + u32 rsv7982; + u32 rsv7983; + u32 rsv7984; + u32 rsv7985; + u32 rsv7986; + u32 rsv7987; + u32 rsv7988; + u32 rsv7989; + u32 rsv7990; + u32 rsv7991; + u32 rsv7992; + u32 rsv7993; + u32 rsv7994; + u32 rsv7995; + u32 rsv7996; + u32 rsv7997; + u32 rsv7998; + u32 rsv7999; + u32 rsv8000; + u32 rsv8001; + u32 rsv8002; + u32 rsv8003; + u32 rsv8004; + u32 rsv8005; + u32 rsv8006; + u32 rsv8007; + u32 rsv8008; + u32 rsv8009; + u32 rsv8010; + u32 rsv8011; + u32 rsv8012; + u32 rsv8013; + u32 rsv8014; + u32 rsv8015; + u32 rsv8016; + u32 rsv8017; + u32 rsv8018; + u32 rsv8019; + u32 rsv8020; + u32 rsv8021; + u32 rsv8022; + u32 rsv8023; + u32 rsv8024; + u32 rsv8025; + u32 rsv8026; + u32 rsv8027; + u32 rsv8028; + u32 rsv8029; + u32 rsv8030; + u32 rsv8031; + u32 rsv8032; + u32 rsv8033; + u32 rsv8034; + u32 rsv8035; + u32 rsv8036; + u32 rsv8037; + u32 rsv8038; + u32 rsv8039; + u32 rsv8040; + u32 rsv8041; + u32 rsv8042; + u32 rsv8043; + u32 rsv8044; + u32 rsv8045; + u32 rsv8046; + u32 rsv8047; + u32 rsv8048; + u32 rsv8049; + u32 rsv8050; + u32 rsv8051; + u32 rsv8052; + u32 rsv8053; + u32 rsv8054; + u32 rsv8055; + u32 rsv8056; + u32 rsv8057; + u32 rsv8058; + u32 rsv8059; + u32 rsv8060; + u32 rsv8061; + u32 rsv8062; + u32 rsv8063; + u32 rsv8064; + u32 rsv8065; + u32 rsv8066; + u32 rsv8067; + u32 rsv8068; + u32 rsv8069; + u32 rsv8070; + u32 rsv8071; + u32 rsv8072; + u32 rsv8073; + u32 rsv8074; + u32 rsv8075; + u32 rsv8076; + u32 rsv8077; + u32 rsv8078; + u32 rsv8079; + u32 rsv8080; + u32 rsv8081; + u32 rsv8082; + u32 rsv8083; + u32 rsv8084; + u32 rsv8085; + u32 rsv8086; + u32 rsv8087; + u32 rsv8088; + u32 rsv8089; + u32 rsv8090; + u32 rsv8091; + u32 rsv8092; + u32 rsv8093; + u32 rsv8094; + u32 rsv8095; + u32 rsv8096; + u32 rsv8097; + u32 rsv8098; + u32 rsv8099; + u32 rsv8100; + u32 rsv8101; + u32 rsv8102; + u32 rsv8103; + u32 rsv8104; + u32 rsv8105; + u32 rsv8106; + u32 rsv8107; + u32 rsv8108; + u32 rsv8109; + u32 rsv8110; + u32 rsv8111; + u32 rsv8112; + u32 rsv8113; + u32 rsv8114; + u32 rsv8115; + u32 rsv8116; + u32 rsv8117; + u32 rsv8118; + u32 rsv8119; + u32 rsv8120; + u32 rsv8121; + u32 rsv8122; + u32 rsv8123; + u32 rsv8124; + u32 rsv8125; + u32 rsv8126; + u32 rsv8127; + u32 rsv8128; + u32 rsv8129; + u32 rsv8130; + u32 rsv8131; + u32 rsv8132; + u32 rsv8133; + u32 rsv8134; + u32 rsv8135; + u32 rsv8136; + u32 rsv8137; + u32 rsv8138; + u32 rsv8139; + u32 rsv8140; + u32 rsv8141; + u32 rsv8142; + u32 rsv8143; + u32 rsv8144; + u32 rsv8145; + u32 rsv8146; + u32 rsv8147; + u32 rsv8148; + u32 rsv8149; + u32 rsv8150; + u32 rsv8151; + u32 rsv8152; + u32 rsv8153; + u32 rsv8154; + u32 rsv8155; + u32 rsv8156; + u32 rsv8157; + u32 rsv8158; + u32 rsv8159; + u32 rsv8160; + u32 rsv8161; + u32 rsv8162; + u32 rsv8163; + u32 rsv8164; + u32 rsv8165; + u32 rsv8166; + u32 rsv8167; + u32 rsv8168; + u32 rsv8169; + u32 rsv8170; + u32 rsv8171; + u32 rsv8172; + u32 rsv8173; + u32 rsv8174; + u32 rsv8175; + u32 rsv8176; + u32 rsv8177; + u32 rsv8178; + u32 rsv8179; + u32 rsv8180; + u32 rsv8181; + u32 rsv8182; + u32 rsv8183; + u32 rsv8184; + u32 rsv8185; + u32 rsv8186; + u32 rsv8187; + u32 rsv8188; + u32 rsv8189; + u32 rsv8190; + u32 rsv8191; + u32 rx_pkt_msg_fifo_0[1]; /* 0x00008000 */ + u32 rx_pkt_msg_fifo_1[1]; /* 0x00008004 */ + u32 rx_pkt_msg_fifo_2[1]; /* 0x00008008 */ + u32 rx_pkt_msg_fifo_3[1]; /* 0x0000800c */ + u32 rx_pkt_msg_fifo_4[1]; /* 0x00008010 */ + u32 rx_pkt_msg_fifo_5[1]; /* 0x00008014 */ + u32 rx_pkt_msg_fifo_6[1]; /* 0x00008018 */ + u32 rx_pkt_msg_fifo_7[1]; /* 0x0000801c */ + u32 rx_pkt_msg_fifo_8[1]; /* 0x00008020 */ + u32 rx_pkt_msg_fifo_9[1]; /* 0x00008024 */ + u32 rx_pkt_msg_fifo_10[1]; /* 0x00008028 */ + u32 rx_pkt_msg_fifo_11[1]; /* 0x0000802c */ + u32 rx_pkt_msg_fifo_12[1]; /* 0x00008030 */ + u32 rx_pkt_msg_fifo_13[1]; /* 0x00008034 */ + u32 rx_pkt_msg_fifo_14[1]; /* 0x00008038 */ + u32 rx_pkt_msg_fifo_15[1]; /* 0x0000803c */ + u32 rx_pkt_msg_fifo_16[1]; /* 0x00008040 */ + u32 rx_pkt_msg_fifo_17[1]; /* 0x00008044 */ + u32 rx_pkt_msg_fifo_18[1]; /* 0x00008048 */ + u32 rx_pkt_msg_fifo_19[1]; /* 0x0000804c */ + u32 rx_pkt_msg_fifo_20[1]; /* 0x00008050 */ + u32 rx_pkt_msg_fifo_21[1]; /* 0x00008054 */ + u32 rx_pkt_msg_fifo_22[1]; /* 0x00008058 */ + u32 rx_pkt_msg_fifo_23[1]; /* 0x0000805c */ + u32 rx_pkt_msg_fifo_24[1]; /* 0x00008060 */ + u32 rx_pkt_msg_fifo_25[1]; /* 0x00008064 */ + u32 rx_pkt_msg_fifo_26[1]; /* 0x00008068 */ + u32 rx_pkt_msg_fifo_27[1]; /* 0x0000806c */ + u32 rx_pkt_msg_fifo_28[1]; /* 0x00008070 */ + u32 rx_pkt_msg_fifo_29[1]; /* 0x00008074 */ + u32 rx_pkt_msg_fifo_30[1]; /* 0x00008078 */ + u32 rx_pkt_msg_fifo_31[1]; /* 0x0000807c */ + u32 rx_pkt_msg_fifo_32[1]; /* 0x00008080 */ + u32 rx_pkt_msg_fifo_33[1]; /* 0x00008084 */ + u32 rx_pkt_msg_fifo_34[1]; /* 0x00008088 */ + u32 rx_pkt_msg_fifo_35[1]; /* 0x0000808c */ + u32 rx_pkt_msg_fifo_36[1]; /* 0x00008090 */ + u32 rx_pkt_msg_fifo_37[1]; /* 0x00008094 */ + u32 rx_pkt_msg_fifo_38[1]; /* 0x00008098 */ + u32 rx_pkt_msg_fifo_39[1]; /* 0x0000809c */ + u32 rx_pkt_msg_fifo_40[1]; /* 0x000080a0 */ + u32 rx_pkt_msg_fifo_41[1]; /* 0x000080a4 */ + u32 rx_pkt_msg_fifo_42[1]; /* 0x000080a8 */ + u32 rx_pkt_msg_fifo_43[1]; /* 0x000080ac */ + u32 rx_pkt_msg_fifo_44[1]; /* 0x000080b0 */ + u32 rx_pkt_msg_fifo_45[1]; /* 0x000080b4 */ + u32 rx_pkt_msg_fifo_46[1]; /* 0x000080b8 */ + u32 rx_pkt_msg_fifo_47[1]; /* 0x000080bc */ + u32 rx_pkt_msg_fifo_48[1]; /* 0x000080c0 */ + u32 rx_pkt_msg_fifo_49[1]; /* 0x000080c4 */ + u32 rx_pkt_msg_fifo_50[1]; /* 0x000080c8 */ + u32 rx_pkt_msg_fifo_51[1]; /* 0x000080cc */ + u32 rx_pkt_msg_fifo_52[1]; /* 0x000080d0 */ + u32 rx_pkt_msg_fifo_53[1]; /* 0x000080d4 */ + u32 rx_pkt_msg_fifo_54[1]; /* 0x000080d8 */ + u32 rx_pkt_msg_fifo_55[1]; /* 0x000080dc */ + u32 rx_pkt_msg_fifo_56[1]; /* 0x000080e0 */ + u32 rx_pkt_msg_fifo_57[1]; /* 0x000080e4 */ + u32 rx_pkt_msg_fifo_58[1]; /* 0x000080e8 */ + u32 rx_pkt_msg_fifo_59[1]; /* 0x000080ec */ + u32 rx_pkt_msg_fifo_60[1]; /* 0x000080f0 */ + u32 rx_pkt_msg_fifo_61[1]; /* 0x000080f4 */ + u32 rx_pkt_msg_fifo_62[1]; /* 0x000080f8 */ + u32 rx_pkt_msg_fifo_63[1]; /* 0x000080fc */ + u32 rx_pkt_msg_fifo_64[1]; /* 0x00008100 */ + u32 rx_pkt_msg_fifo_65[1]; /* 0x00008104 */ + u32 rx_pkt_msg_fifo_66[1]; /* 0x00008108 */ + u32 rx_pkt_msg_fifo_67[1]; /* 0x0000810c */ + u32 rx_pkt_msg_fifo_68[1]; /* 0x00008110 */ + u32 rx_pkt_msg_fifo_69[1]; /* 0x00008114 */ + u32 rx_pkt_msg_fifo_70[1]; /* 0x00008118 */ + u32 rx_pkt_msg_fifo_71[1]; /* 0x0000811c */ + u32 rx_pkt_msg_fifo_72[1]; /* 0x00008120 */ + u32 rx_pkt_msg_fifo_73[1]; /* 0x00008124 */ + u32 rx_pkt_msg_fifo_74[1]; /* 0x00008128 */ + u32 rx_pkt_msg_fifo_75[1]; /* 0x0000812c */ + u32 rx_pkt_msg_fifo_76[1]; /* 0x00008130 */ + u32 rx_pkt_msg_fifo_77[1]; /* 0x00008134 */ + u32 rx_pkt_msg_fifo_78[1]; /* 0x00008138 */ + u32 rx_pkt_msg_fifo_79[1]; /* 0x0000813c */ + u32 rx_pkt_msg_fifo_80[1]; /* 0x00008140 */ + u32 rx_pkt_msg_fifo_81[1]; /* 0x00008144 */ + u32 rx_pkt_msg_fifo_82[1]; /* 0x00008148 */ + u32 rx_pkt_msg_fifo_83[1]; /* 0x0000814c */ + u32 rx_pkt_msg_fifo_84[1]; /* 0x00008150 */ + u32 rx_pkt_msg_fifo_85[1]; /* 0x00008154 */ + u32 rx_pkt_msg_fifo_86[1]; /* 0x00008158 */ + u32 rx_pkt_msg_fifo_87[1]; /* 0x0000815c */ + u32 rx_pkt_msg_fifo_88[1]; /* 0x00008160 */ + u32 rx_pkt_msg_fifo_89[1]; /* 0x00008164 */ + u32 rx_pkt_msg_fifo_90[1]; /* 0x00008168 */ + u32 rx_pkt_msg_fifo_91[1]; /* 0x0000816c */ + u32 rx_pkt_msg_fifo_92[1]; /* 0x00008170 */ + u32 rx_pkt_msg_fifo_93[1]; /* 0x00008174 */ + u32 rx_pkt_msg_fifo_94[1]; /* 0x00008178 */ + u32 rx_pkt_msg_fifo_95[1]; /* 0x0000817c */ + u32 rx_pkt_msg_fifo_96[1]; /* 0x00008180 */ + u32 rx_pkt_msg_fifo_97[1]; /* 0x00008184 */ + u32 rx_pkt_msg_fifo_98[1]; /* 0x00008188 */ + u32 rx_pkt_msg_fifo_99[1]; /* 0x0000818c */ + u32 rx_pkt_msg_fifo_100[1]; /* 0x00008190 */ + u32 rx_pkt_msg_fifo_101[1]; /* 0x00008194 */ + u32 rx_pkt_msg_fifo_102[1]; /* 0x00008198 */ + u32 rx_pkt_msg_fifo_103[1]; /* 0x0000819c */ + u32 rx_pkt_msg_fifo_104[1]; /* 0x000081a0 */ + u32 rx_pkt_msg_fifo_105[1]; /* 0x000081a4 */ + u32 rx_pkt_msg_fifo_106[1]; /* 0x000081a8 */ + u32 rx_pkt_msg_fifo_107[1]; /* 0x000081ac */ + u32 rx_pkt_msg_fifo_108[1]; /* 0x000081b0 */ + u32 rx_pkt_msg_fifo_109[1]; /* 0x000081b4 */ + u32 rx_pkt_msg_fifo_110[1]; /* 0x000081b8 */ + u32 rx_pkt_msg_fifo_111[1]; /* 0x000081bc */ + u32 rx_pkt_msg_fifo_112[1]; /* 0x000081c0 */ + u32 rx_pkt_msg_fifo_113[1]; /* 0x000081c4 */ + u32 rx_pkt_msg_fifo_114[1]; /* 0x000081c8 */ + u32 rx_pkt_msg_fifo_115[1]; /* 0x000081cc */ + u32 rx_pkt_msg_fifo_116[1]; /* 0x000081d0 */ + u32 rx_pkt_msg_fifo_117[1]; /* 0x000081d4 */ + u32 rx_pkt_msg_fifo_118[1]; /* 0x000081d8 */ + u32 rx_pkt_msg_fifo_119[1]; /* 0x000081dc */ + u32 rx_pkt_msg_fifo_120[1]; /* 0x000081e0 */ + u32 rx_pkt_msg_fifo_121[1]; /* 0x000081e4 */ + u32 rx_pkt_msg_fifo_122[1]; /* 0x000081e8 */ + u32 rx_pkt_msg_fifo_123[1]; /* 0x000081ec */ + u32 rx_pkt_msg_fifo_124[1]; /* 0x000081f0 */ + u32 rx_pkt_msg_fifo_125[1]; /* 0x000081f4 */ + u32 rx_pkt_msg_fifo_126[1]; /* 0x000081f8 */ + u32 rx_pkt_msg_fifo_127[1]; /* 0x000081fc */ + u32 rx_pkt_msg_fifo_128[1]; /* 0x00008200 */ + u32 rx_pkt_msg_fifo_129[1]; /* 0x00008204 */ + u32 rx_pkt_msg_fifo_130[1]; /* 0x00008208 */ + u32 rx_pkt_msg_fifo_131[1]; /* 0x0000820c */ + u32 rx_pkt_msg_fifo_132[1]; /* 0x00008210 */ + u32 rx_pkt_msg_fifo_133[1]; /* 0x00008214 */ + u32 rx_pkt_msg_fifo_134[1]; /* 0x00008218 */ + u32 rx_pkt_msg_fifo_135[1]; /* 0x0000821c */ + u32 rx_pkt_msg_fifo_136[1]; /* 0x00008220 */ + u32 rx_pkt_msg_fifo_137[1]; /* 0x00008224 */ + u32 rx_pkt_msg_fifo_138[1]; /* 0x00008228 */ + u32 rx_pkt_msg_fifo_139[1]; /* 0x0000822c */ + u32 rx_pkt_msg_fifo_140[1]; /* 0x00008230 */ + u32 rx_pkt_msg_fifo_141[1]; /* 0x00008234 */ + u32 rx_pkt_msg_fifo_142[1]; /* 0x00008238 */ + u32 rx_pkt_msg_fifo_143[1]; /* 0x0000823c */ + u32 rx_pkt_msg_fifo_144[1]; /* 0x00008240 */ + u32 rx_pkt_msg_fifo_145[1]; /* 0x00008244 */ + u32 rx_pkt_msg_fifo_146[1]; /* 0x00008248 */ + u32 rx_pkt_msg_fifo_147[1]; /* 0x0000824c */ + u32 rx_pkt_msg_fifo_148[1]; /* 0x00008250 */ + u32 rx_pkt_msg_fifo_149[1]; /* 0x00008254 */ + u32 rx_pkt_msg_fifo_150[1]; /* 0x00008258 */ + u32 rx_pkt_msg_fifo_151[1]; /* 0x0000825c */ + u32 rx_pkt_msg_fifo_152[1]; /* 0x00008260 */ + u32 rx_pkt_msg_fifo_153[1]; /* 0x00008264 */ + u32 rx_pkt_msg_fifo_154[1]; /* 0x00008268 */ + u32 rx_pkt_msg_fifo_155[1]; /* 0x0000826c */ + u32 rx_pkt_msg_fifo_156[1]; /* 0x00008270 */ + u32 rx_pkt_msg_fifo_157[1]; /* 0x00008274 */ + u32 rx_pkt_msg_fifo_158[1]; /* 0x00008278 */ + u32 rx_pkt_msg_fifo_159[1]; /* 0x0000827c */ + u32 rx_pkt_msg_fifo_160[1]; /* 0x00008280 */ + u32 rx_pkt_msg_fifo_161[1]; /* 0x00008284 */ + u32 rx_pkt_msg_fifo_162[1]; /* 0x00008288 */ + u32 rx_pkt_msg_fifo_163[1]; /* 0x0000828c */ + u32 rx_pkt_msg_fifo_164[1]; /* 0x00008290 */ + u32 rx_pkt_msg_fifo_165[1]; /* 0x00008294 */ + u32 rx_pkt_msg_fifo_166[1]; /* 0x00008298 */ + u32 rx_pkt_msg_fifo_167[1]; /* 0x0000829c */ + u32 rx_pkt_msg_fifo_168[1]; /* 0x000082a0 */ + u32 rx_pkt_msg_fifo_169[1]; /* 0x000082a4 */ + u32 rx_pkt_msg_fifo_170[1]; /* 0x000082a8 */ + u32 rx_pkt_msg_fifo_171[1]; /* 0x000082ac */ + u32 rx_pkt_msg_fifo_172[1]; /* 0x000082b0 */ + u32 rx_pkt_msg_fifo_173[1]; /* 0x000082b4 */ + u32 rx_pkt_msg_fifo_174[1]; /* 0x000082b8 */ + u32 rx_pkt_msg_fifo_175[1]; /* 0x000082bc */ + u32 rx_pkt_msg_fifo_176[1]; /* 0x000082c0 */ + u32 rx_pkt_msg_fifo_177[1]; /* 0x000082c4 */ + u32 rx_pkt_msg_fifo_178[1]; /* 0x000082c8 */ + u32 rx_pkt_msg_fifo_179[1]; /* 0x000082cc */ + u32 rx_pkt_msg_fifo_180[1]; /* 0x000082d0 */ + u32 rx_pkt_msg_fifo_181[1]; /* 0x000082d4 */ + u32 rx_pkt_msg_fifo_182[1]; /* 0x000082d8 */ + u32 rx_pkt_msg_fifo_183[1]; /* 0x000082dc */ + u32 rx_pkt_msg_fifo_184[1]; /* 0x000082e0 */ + u32 rx_pkt_msg_fifo_185[1]; /* 0x000082e4 */ + u32 rx_pkt_msg_fifo_186[1]; /* 0x000082e8 */ + u32 rx_pkt_msg_fifo_187[1]; /* 0x000082ec */ + u32 rx_pkt_msg_fifo_188[1]; /* 0x000082f0 */ + u32 rx_pkt_msg_fifo_189[1]; /* 0x000082f4 */ + u32 rx_pkt_msg_fifo_190[1]; /* 0x000082f8 */ + u32 rx_pkt_msg_fifo_191[1]; /* 0x000082fc */ + u32 rx_pkt_msg_fifo_192[1]; /* 0x00008300 */ + u32 rx_pkt_msg_fifo_193[1]; /* 0x00008304 */ + u32 rx_pkt_msg_fifo_194[1]; /* 0x00008308 */ + u32 rx_pkt_msg_fifo_195[1]; /* 0x0000830c */ + u32 rx_pkt_msg_fifo_196[1]; /* 0x00008310 */ + u32 rx_pkt_msg_fifo_197[1]; /* 0x00008314 */ + u32 rx_pkt_msg_fifo_198[1]; /* 0x00008318 */ + u32 rx_pkt_msg_fifo_199[1]; /* 0x0000831c */ + u32 rx_pkt_msg_fifo_200[1]; /* 0x00008320 */ + u32 rx_pkt_msg_fifo_201[1]; /* 0x00008324 */ + u32 rx_pkt_msg_fifo_202[1]; /* 0x00008328 */ + u32 rx_pkt_msg_fifo_203[1]; /* 0x0000832c */ + u32 rx_pkt_msg_fifo_204[1]; /* 0x00008330 */ + u32 rx_pkt_msg_fifo_205[1]; /* 0x00008334 */ + u32 rx_pkt_msg_fifo_206[1]; /* 0x00008338 */ + u32 rx_pkt_msg_fifo_207[1]; /* 0x0000833c */ + u32 rx_pkt_msg_fifo_208[1]; /* 0x00008340 */ + u32 rx_pkt_msg_fifo_209[1]; /* 0x00008344 */ + u32 rx_pkt_msg_fifo_210[1]; /* 0x00008348 */ + u32 rx_pkt_msg_fifo_211[1]; /* 0x0000834c */ + u32 rx_pkt_msg_fifo_212[1]; /* 0x00008350 */ + u32 rx_pkt_msg_fifo_213[1]; /* 0x00008354 */ + u32 rx_pkt_msg_fifo_214[1]; /* 0x00008358 */ + u32 rx_pkt_msg_fifo_215[1]; /* 0x0000835c */ + u32 rx_pkt_msg_fifo_216[1]; /* 0x00008360 */ + u32 rx_pkt_msg_fifo_217[1]; /* 0x00008364 */ + u32 rx_pkt_msg_fifo_218[1]; /* 0x00008368 */ + u32 rx_pkt_msg_fifo_219[1]; /* 0x0000836c */ + u32 rx_pkt_msg_fifo_220[1]; /* 0x00008370 */ + u32 rx_pkt_msg_fifo_221[1]; /* 0x00008374 */ + u32 rx_pkt_msg_fifo_222[1]; /* 0x00008378 */ + u32 rx_pkt_msg_fifo_223[1]; /* 0x0000837c */ + u32 rx_pkt_msg_fifo_224[1]; /* 0x00008380 */ + u32 rx_pkt_msg_fifo_225[1]; /* 0x00008384 */ + u32 rx_pkt_msg_fifo_226[1]; /* 0x00008388 */ + u32 rx_pkt_msg_fifo_227[1]; /* 0x0000838c */ + u32 rx_pkt_msg_fifo_228[1]; /* 0x00008390 */ + u32 rx_pkt_msg_fifo_229[1]; /* 0x00008394 */ + u32 rx_pkt_msg_fifo_230[1]; /* 0x00008398 */ + u32 rx_pkt_msg_fifo_231[1]; /* 0x0000839c */ + u32 rx_pkt_msg_fifo_232[1]; /* 0x000083a0 */ + u32 rx_pkt_msg_fifo_233[1]; /* 0x000083a4 */ + u32 rx_pkt_msg_fifo_234[1]; /* 0x000083a8 */ + u32 rx_pkt_msg_fifo_235[1]; /* 0x000083ac */ + u32 rx_pkt_msg_fifo_236[1]; /* 0x000083b0 */ + u32 rx_pkt_msg_fifo_237[1]; /* 0x000083b4 */ + u32 rx_pkt_msg_fifo_238[1]; /* 0x000083b8 */ + u32 rx_pkt_msg_fifo_239[1]; /* 0x000083bc */ + u32 rx_pkt_msg_fifo_240[1]; /* 0x000083c0 */ + u32 rx_pkt_msg_fifo_241[1]; /* 0x000083c4 */ + u32 rx_pkt_msg_fifo_242[1]; /* 0x000083c8 */ + u32 rx_pkt_msg_fifo_243[1]; /* 0x000083cc */ + u32 rx_pkt_msg_fifo_244[1]; /* 0x000083d0 */ + u32 rx_pkt_msg_fifo_245[1]; /* 0x000083d4 */ + u32 rx_pkt_msg_fifo_246[1]; /* 0x000083d8 */ + u32 rx_pkt_msg_fifo_247[1]; /* 0x000083dc */ + u32 rx_pkt_msg_fifo_248[1]; /* 0x000083e0 */ + u32 rx_pkt_msg_fifo_249[1]; /* 0x000083e4 */ + u32 rx_pkt_msg_fifo_250[1]; /* 0x000083e8 */ + u32 rx_pkt_msg_fifo_251[1]; /* 0x000083ec */ + u32 rx_pkt_msg_fifo_252[1]; /* 0x000083f0 */ + u32 rx_pkt_msg_fifo_253[1]; /* 0x000083f4 */ + u32 rx_pkt_msg_fifo_254[1]; /* 0x000083f8 */ + u32 rx_pkt_msg_fifo_255[1]; /* 0x000083fc */ + u32 rx_pkt_msg_fifo_256[1]; /* 0x00008400 */ + u32 rx_pkt_msg_fifo_257[1]; /* 0x00008404 */ + u32 rx_pkt_msg_fifo_258[1]; /* 0x00008408 */ + u32 rx_pkt_msg_fifo_259[1]; /* 0x0000840c */ + u32 rx_pkt_msg_fifo_260[1]; /* 0x00008410 */ + u32 rx_pkt_msg_fifo_261[1]; /* 0x00008414 */ + u32 rx_pkt_msg_fifo_262[1]; /* 0x00008418 */ + u32 rx_pkt_msg_fifo_263[1]; /* 0x0000841c */ + u32 rx_pkt_msg_fifo_264[1]; /* 0x00008420 */ + u32 rx_pkt_msg_fifo_265[1]; /* 0x00008424 */ + u32 rx_pkt_msg_fifo_266[1]; /* 0x00008428 */ + u32 rx_pkt_msg_fifo_267[1]; /* 0x0000842c */ + u32 rx_pkt_msg_fifo_268[1]; /* 0x00008430 */ + u32 rx_pkt_msg_fifo_269[1]; /* 0x00008434 */ + u32 rx_pkt_msg_fifo_270[1]; /* 0x00008438 */ + u32 rx_pkt_msg_fifo_271[1]; /* 0x0000843c */ + u32 rx_pkt_msg_fifo_272[1]; /* 0x00008440 */ + u32 rx_pkt_msg_fifo_273[1]; /* 0x00008444 */ + u32 rx_pkt_msg_fifo_274[1]; /* 0x00008448 */ + u32 rx_pkt_msg_fifo_275[1]; /* 0x0000844c */ + u32 rx_pkt_msg_fifo_276[1]; /* 0x00008450 */ + u32 rx_pkt_msg_fifo_277[1]; /* 0x00008454 */ + u32 rx_pkt_msg_fifo_278[1]; /* 0x00008458 */ + u32 rx_pkt_msg_fifo_279[1]; /* 0x0000845c */ + u32 rx_pkt_msg_fifo_280[1]; /* 0x00008460 */ + u32 rx_pkt_msg_fifo_281[1]; /* 0x00008464 */ + u32 rx_pkt_msg_fifo_282[1]; /* 0x00008468 */ + u32 rx_pkt_msg_fifo_283[1]; /* 0x0000846c */ + u32 rx_pkt_msg_fifo_284[1]; /* 0x00008470 */ + u32 rx_pkt_msg_fifo_285[1]; /* 0x00008474 */ + u32 rx_pkt_msg_fifo_286[1]; /* 0x00008478 */ + u32 rx_pkt_msg_fifo_287[1]; /* 0x0000847c */ + u32 rx_pkt_msg_fifo_288[1]; /* 0x00008480 */ + u32 rx_pkt_msg_fifo_289[1]; /* 0x00008484 */ + u32 rx_pkt_msg_fifo_290[1]; /* 0x00008488 */ + u32 rx_pkt_msg_fifo_291[1]; /* 0x0000848c */ + u32 rx_pkt_msg_fifo_292[1]; /* 0x00008490 */ + u32 rx_pkt_msg_fifo_293[1]; /* 0x00008494 */ + u32 rx_pkt_msg_fifo_294[1]; /* 0x00008498 */ + u32 rx_pkt_msg_fifo_295[1]; /* 0x0000849c */ + u32 rx_pkt_msg_fifo_296[1]; /* 0x000084a0 */ + u32 rx_pkt_msg_fifo_297[1]; /* 0x000084a4 */ + u32 rx_pkt_msg_fifo_298[1]; /* 0x000084a8 */ + u32 rx_pkt_msg_fifo_299[1]; /* 0x000084ac */ + u32 rx_pkt_msg_fifo_300[1]; /* 0x000084b0 */ + u32 rx_pkt_msg_fifo_301[1]; /* 0x000084b4 */ + u32 rx_pkt_msg_fifo_302[1]; /* 0x000084b8 */ + u32 rx_pkt_msg_fifo_303[1]; /* 0x000084bc */ + u32 rx_pkt_msg_fifo_304[1]; /* 0x000084c0 */ + u32 rx_pkt_msg_fifo_305[1]; /* 0x000084c4 */ + u32 rx_pkt_msg_fifo_306[1]; /* 0x000084c8 */ + u32 rx_pkt_msg_fifo_307[1]; /* 0x000084cc */ + u32 rx_pkt_msg_fifo_308[1]; /* 0x000084d0 */ + u32 rx_pkt_msg_fifo_309[1]; /* 0x000084d4 */ + u32 rx_pkt_msg_fifo_310[1]; /* 0x000084d8 */ + u32 rx_pkt_msg_fifo_311[1]; /* 0x000084dc */ + u32 rx_pkt_msg_fifo_312[1]; /* 0x000084e0 */ + u32 rx_pkt_msg_fifo_313[1]; /* 0x000084e4 */ + u32 rx_pkt_msg_fifo_314[1]; /* 0x000084e8 */ + u32 rx_pkt_msg_fifo_315[1]; /* 0x000084ec */ + u32 rx_pkt_msg_fifo_316[1]; /* 0x000084f0 */ + u32 rx_pkt_msg_fifo_317[1]; /* 0x000084f4 */ + u32 rx_pkt_msg_fifo_318[1]; /* 0x000084f8 */ + u32 rx_pkt_msg_fifo_319[1]; /* 0x000084fc */ + u32 rx_pkt_msg_fifo_320[1]; /* 0x00008500 */ + u32 rx_pkt_msg_fifo_321[1]; /* 0x00008504 */ + u32 rx_pkt_msg_fifo_322[1]; /* 0x00008508 */ + u32 rx_pkt_msg_fifo_323[1]; /* 0x0000850c */ + u32 rx_pkt_msg_fifo_324[1]; /* 0x00008510 */ + u32 rsv8517; + u32 rsv8518; + u32 rsv8519; + u32 rsv8520; + u32 rsv8521; + u32 rsv8522; + u32 rsv8523; + u32 rsv8524; + u32 rsv8525; + u32 rsv8526; + u32 rsv8527; + u32 rsv8528; + u32 rsv8529; + u32 rsv8530; + u32 rsv8531; + u32 rsv8532; + u32 rsv8533; + u32 rsv8534; + u32 rsv8535; + u32 rsv8536; + u32 rsv8537; + u32 rsv8538; + u32 rsv8539; + u32 rsv8540; + u32 rsv8541; + u32 rsv8542; + u32 rsv8543; + u32 rsv8544; + u32 rsv8545; + u32 rsv8546; + u32 rsv8547; + u32 rsv8548; + u32 rsv8549; + u32 rsv8550; + u32 rsv8551; + u32 rsv8552; + u32 rsv8553; + u32 rsv8554; + u32 rsv8555; + u32 rsv8556; + u32 rsv8557; + u32 rsv8558; + u32 rsv8559; + u32 rsv8560; + u32 rsv8561; + u32 rsv8562; + u32 rsv8563; + u32 rsv8564; + u32 rsv8565; + u32 rsv8566; + u32 rsv8567; + u32 rsv8568; + u32 rsv8569; + u32 rsv8570; + u32 rsv8571; + u32 rsv8572; + u32 rsv8573; + u32 rsv8574; + u32 rsv8575; + u32 rsv8576; + u32 rsv8577; + u32 rsv8578; + u32 rsv8579; + u32 rsv8580; + u32 rsv8581; + u32 rsv8582; + u32 rsv8583; + u32 rsv8584; + u32 rsv8585; + u32 rsv8586; + u32 rsv8587; + u32 rsv8588; + u32 rsv8589; + u32 rsv8590; + u32 rsv8591; + u32 rsv8592; + u32 rsv8593; + u32 rsv8594; + u32 rsv8595; + u32 rsv8596; + u32 rsv8597; + u32 rsv8598; + u32 rsv8599; + u32 rsv8600; + u32 rsv8601; + u32 rsv8602; + u32 rsv8603; + u32 rsv8604; + u32 rsv8605; + u32 rsv8606; + u32 rsv8607; + u32 rsv8608; + u32 rsv8609; + u32 rsv8610; + u32 rsv8611; + u32 rsv8612; + u32 rsv8613; + u32 rsv8614; + u32 rsv8615; + u32 rsv8616; + u32 rsv8617; + u32 rsv8618; + u32 rsv8619; + u32 rsv8620; + u32 rsv8621; + u32 rsv8622; + u32 rsv8623; + u32 rsv8624; + u32 rsv8625; + u32 rsv8626; + u32 rsv8627; + u32 rsv8628; + u32 rsv8629; + u32 rsv8630; + u32 rsv8631; + u32 rsv8632; + u32 rsv8633; + u32 rsv8634; + u32 rsv8635; + u32 rsv8636; + u32 rsv8637; + u32 rsv8638; + u32 rsv8639; + u32 rsv8640; + u32 rsv8641; + u32 rsv8642; + u32 rsv8643; + u32 rsv8644; + u32 rsv8645; + u32 rsv8646; + u32 rsv8647; + u32 rsv8648; + u32 rsv8649; + u32 rsv8650; + u32 rsv8651; + u32 rsv8652; + u32 rsv8653; + u32 rsv8654; + u32 rsv8655; + u32 rsv8656; + u32 rsv8657; + u32 rsv8658; + u32 rsv8659; + u32 rsv8660; + u32 rsv8661; + u32 rsv8662; + u32 rsv8663; + u32 rsv8664; + u32 rsv8665; + u32 rsv8666; + u32 rsv8667; + u32 rsv8668; + u32 rsv8669; + u32 rsv8670; + u32 rsv8671; + u32 rsv8672; + u32 rsv8673; + u32 rsv8674; + u32 rsv8675; + u32 rsv8676; + u32 rsv8677; + u32 rsv8678; + u32 rsv8679; + u32 rsv8680; + u32 rsv8681; + u32 rsv8682; + u32 rsv8683; + u32 rsv8684; + u32 rsv8685; + u32 rsv8686; + u32 rsv8687; + u32 rsv8688; + u32 rsv8689; + u32 rsv8690; + u32 rsv8691; + u32 rsv8692; + u32 rsv8693; + u32 rsv8694; + u32 rsv8695; + u32 rsv8696; + u32 rsv8697; + u32 rsv8698; + u32 rsv8699; + u32 rsv8700; + u32 rsv8701; + u32 rsv8702; + u32 rsv8703; + u32 cpu_mac_stats_ram_0[4]; /* 0x00008800 */ + u32 cpu_mac_stats_ram_1[4]; /* 0x00008810 */ + u32 cpu_mac_stats_ram_2[4]; /* 0x00008820 */ + u32 cpu_mac_stats_ram_3[4]; /* 0x00008830 */ + u32 cpu_mac_stats_ram_4[4]; /* 0x00008840 */ + u32 cpu_mac_stats_ram_5[4]; /* 0x00008850 */ + u32 cpu_mac_stats_ram_6[4]; /* 0x00008860 */ + u32 cpu_mac_stats_ram_7[4]; /* 0x00008870 */ + u32 cpu_mac_stats_ram_8[4]; /* 0x00008880 */ + u32 cpu_mac_stats_ram_9[4]; /* 0x00008890 */ + u32 cpu_mac_stats_ram_10[4]; /* 0x000088a0 */ + u32 cpu_mac_stats_ram_11[4]; /* 0x000088b0 */ + u32 cpu_mac_stats_ram_12[4]; /* 0x000088c0 */ + u32 cpu_mac_stats_ram_13[4]; /* 0x000088d0 */ + u32 cpu_mac_stats_ram_14[4]; /* 0x000088e0 */ + u32 cpu_mac_stats_ram_15[4]; /* 0x000088f0 */ + u32 cpu_mac_stats_ram_16[4]; /* 0x00008900 */ + u32 cpu_mac_stats_ram_17[4]; /* 0x00008910 */ + u32 cpu_mac_stats_ram_18[4]; /* 0x00008920 */ + u32 cpu_mac_stats_ram_19[4]; /* 0x00008930 */ + u32 cpu_mac_stats_ram_20[4]; /* 0x00008940 */ + u32 cpu_mac_stats_ram_21[4]; /* 0x00008950 */ + u32 cpu_mac_stats_ram_22[4]; /* 0x00008960 */ + u32 cpu_mac_stats_ram_23[4]; /* 0x00008970 */ + u32 cpu_mac_stats_ram_24[4]; /* 0x00008980 */ + u32 cpu_mac_stats_ram_25[4]; /* 0x00008990 */ + u32 cpu_mac_stats_ram_26[4]; /* 0x000089a0 */ + u32 cpu_mac_stats_ram_27[4]; /* 0x000089b0 */ + u32 cpu_mac_stats_ram_28[4]; /* 0x000089c0 */ + u32 cpu_mac_stats_ram_29[4]; /* 0x000089d0 */ + u32 cpu_mac_stats_ram_30[4]; /* 0x000089e0 */ + u32 cpu_mac_stats_ram_31[4]; /* 0x000089f0 */ + u32 cpu_mac_stats_ram_32[4]; /* 0x00008a00 */ + u32 cpu_mac_stats_ram_33[4]; /* 0x00008a10 */ + u32 cpu_mac_stats_ram_34[4]; /* 0x00008a20 */ + u32 cpu_mac_stats_ram_35[4]; /* 0x00008a30 */ + u32 cpu_mac_stats_ram_36[4]; /* 0x00008a40 */ + u32 cpu_mac_stats_ram_37[4]; /* 0x00008a50 */ + u32 cpu_mac_stats_ram_38[4]; /* 0x00008a60 */ + u32 cpu_mac_stats_ram_39[4]; /* 0x00008a70 */ + u32 rsv8864; + u32 rsv8865; + u32 rsv8866; + u32 rsv8867; + u32 rsv8868; + u32 rsv8869; + u32 rsv8870; + u32 rsv8871; + u32 rsv8872; + u32 rsv8873; + u32 rsv8874; + u32 rsv8875; + u32 rsv8876; + u32 rsv8877; + u32 rsv8878; + u32 rsv8879; + u32 rsv8880; + u32 rsv8881; + u32 rsv8882; + u32 rsv8883; + u32 rsv8884; + u32 rsv8885; + u32 rsv8886; + u32 rsv8887; + u32 rsv8888; + u32 rsv8889; + u32 rsv8890; + u32 rsv8891; + u32 rsv8892; + u32 rsv8893; + u32 rsv8894; + u32 rsv8895; + u32 rsv8896; + u32 rsv8897; + u32 rsv8898; + u32 rsv8899; + u32 rsv8900; + u32 rsv8901; + u32 rsv8902; + u32 rsv8903; + u32 rsv8904; + u32 rsv8905; + u32 rsv8906; + u32 rsv8907; + u32 rsv8908; + u32 rsv8909; + u32 rsv8910; + u32 rsv8911; + u32 rsv8912; + u32 rsv8913; + u32 rsv8914; + u32 rsv8915; + u32 rsv8916; + u32 rsv8917; + u32 rsv8918; + u32 rsv8919; + u32 rsv8920; + u32 rsv8921; + u32 rsv8922; + u32 rsv8923; + u32 rsv8924; + u32 rsv8925; + u32 rsv8926; + u32 rsv8927; + u32 rsv8928; + u32 rsv8929; + u32 rsv8930; + u32 rsv8931; + u32 rsv8932; + u32 rsv8933; + u32 rsv8934; + u32 rsv8935; + u32 rsv8936; + u32 rsv8937; + u32 rsv8938; + u32 rsv8939; + u32 rsv8940; + u32 rsv8941; + u32 rsv8942; + u32 rsv8943; + u32 rsv8944; + u32 rsv8945; + u32 rsv8946; + u32 rsv8947; + u32 rsv8948; + u32 rsv8949; + u32 rsv8950; + u32 rsv8951; + u32 rsv8952; + u32 rsv8953; + u32 rsv8954; + u32 rsv8955; + u32 rsv8956; + u32 rsv8957; + u32 rsv8958; + u32 rsv8959; + u32 tx_desc_cfg_fifo_0[2]; /* 0x00008c00 */ + u32 tx_desc_cfg_fifo_1[2]; /* 0x00008c08 */ + u32 tx_desc_cfg_fifo_2[2]; /* 0x00008c10 */ + u32 tx_desc_cfg_fifo_3[2]; /* 0x00008c18 */ + u32 tx_desc_cfg_fifo_4[2]; /* 0x00008c20 */ + u32 tx_desc_cfg_fifo_5[2]; /* 0x00008c28 */ + u32 tx_desc_cfg_fifo_6[2]; /* 0x00008c30 */ + u32 tx_desc_cfg_fifo_7[2]; /* 0x00008c38 */ + u32 tx_desc_cfg_fifo_8[2]; /* 0x00008c40 */ + u32 tx_desc_cfg_fifo_9[2]; /* 0x00008c48 */ + u32 tx_desc_cfg_fifo_10[2]; /* 0x00008c50 */ + u32 tx_desc_cfg_fifo_11[2]; /* 0x00008c58 */ + u32 tx_desc_cfg_fifo_12[2]; /* 0x00008c60 */ + u32 tx_desc_cfg_fifo_13[2]; /* 0x00008c68 */ + u32 tx_desc_cfg_fifo_14[2]; /* 0x00008c70 */ + u32 tx_desc_cfg_fifo_15[2]; /* 0x00008c78 */ + u32 tx_desc_cfg_fifo_16[2]; /* 0x00008c80 */ + u32 tx_desc_cfg_fifo_17[2]; /* 0x00008c88 */ + u32 tx_desc_cfg_fifo_18[2]; /* 0x00008c90 */ + u32 tx_desc_cfg_fifo_19[2]; /* 0x00008c98 */ + u32 tx_desc_cfg_fifo_20[2]; /* 0x00008ca0 */ + u32 tx_desc_cfg_fifo_21[2]; /* 0x00008ca8 */ + u32 tx_desc_cfg_fifo_22[2]; /* 0x00008cb0 */ + u32 tx_desc_cfg_fifo_23[2]; /* 0x00008cb8 */ + u32 tx_desc_cfg_fifo_24[2]; /* 0x00008cc0 */ + u32 tx_desc_cfg_fifo_25[2]; /* 0x00008cc8 */ + u32 tx_desc_cfg_fifo_26[2]; /* 0x00008cd0 */ + u32 tx_desc_cfg_fifo_27[2]; /* 0x00008cd8 */ + u32 tx_desc_cfg_fifo_28[2]; /* 0x00008ce0 */ + u32 tx_desc_cfg_fifo_29[2]; /* 0x00008ce8 */ + u32 tx_desc_cfg_fifo_30[2]; /* 0x00008cf0 */ + u32 tx_desc_cfg_fifo_31[2]; /* 0x00008cf8 */ + u32 tx_desc_cfg_fifo_32[2]; /* 0x00008d00 */ + u32 tx_desc_cfg_fifo_33[2]; /* 0x00008d08 */ + u32 tx_desc_cfg_fifo_34[2]; /* 0x00008d10 */ + u32 tx_desc_cfg_fifo_35[2]; /* 0x00008d18 */ + u32 tx_desc_cfg_fifo_36[2]; /* 0x00008d20 */ + u32 tx_desc_cfg_fifo_37[2]; /* 0x00008d28 */ + u32 tx_desc_cfg_fifo_38[2]; /* 0x00008d30 */ + u32 tx_desc_cfg_fifo_39[2]; /* 0x00008d38 */ + u32 tx_desc_cfg_fifo_40[2]; /* 0x00008d40 */ + u32 tx_desc_cfg_fifo_41[2]; /* 0x00008d48 */ + u32 tx_desc_cfg_fifo_42[2]; /* 0x00008d50 */ + u32 tx_desc_cfg_fifo_43[2]; /* 0x00008d58 */ + u32 tx_desc_cfg_fifo_44[2]; /* 0x00008d60 */ + u32 tx_desc_cfg_fifo_45[2]; /* 0x00008d68 */ + u32 tx_desc_cfg_fifo_46[2]; /* 0x00008d70 */ + u32 tx_desc_cfg_fifo_47[2]; /* 0x00008d78 */ + u32 tx_desc_cfg_fifo_48[2]; /* 0x00008d80 */ + u32 tx_desc_cfg_fifo_49[2]; /* 0x00008d88 */ + u32 tx_desc_cfg_fifo_50[2]; /* 0x00008d90 */ + u32 tx_desc_cfg_fifo_51[2]; /* 0x00008d98 */ + u32 tx_desc_cfg_fifo_52[2]; /* 0x00008da0 */ + u32 tx_desc_cfg_fifo_53[2]; /* 0x00008da8 */ + u32 tx_desc_cfg_fifo_54[2]; /* 0x00008db0 */ + u32 tx_desc_cfg_fifo_55[2]; /* 0x00008db8 */ + u32 tx_desc_cfg_fifo_56[2]; /* 0x00008dc0 */ + u32 tx_desc_cfg_fifo_57[2]; /* 0x00008dc8 */ + u32 tx_desc_cfg_fifo_58[2]; /* 0x00008dd0 */ + u32 tx_desc_cfg_fifo_59[2]; /* 0x00008dd8 */ + u32 tx_desc_cfg_fifo_60[2]; /* 0x00008de0 */ + u32 tx_desc_cfg_fifo_61[2]; /* 0x00008de8 */ + u32 tx_desc_cfg_fifo_62[2]; /* 0x00008df0 */ + u32 tx_desc_cfg_fifo_63[2]; /* 0x00008df8 */ + u32 rx_desc_0_cfg_fifo_0[2]; /* 0x00008e00 */ + u32 rx_desc_0_cfg_fifo_1[2]; /* 0x00008e08 */ + u32 rx_desc_0_cfg_fifo_2[2]; /* 0x00008e10 */ + u32 rx_desc_0_cfg_fifo_3[2]; /* 0x00008e18 */ + u32 rx_desc_0_cfg_fifo_4[2]; /* 0x00008e20 */ + u32 rx_desc_0_cfg_fifo_5[2]; /* 0x00008e28 */ + u32 rx_desc_0_cfg_fifo_6[2]; /* 0x00008e30 */ + u32 rx_desc_0_cfg_fifo_7[2]; /* 0x00008e38 */ + u32 rx_desc_0_cfg_fifo_8[2]; /* 0x00008e40 */ + u32 rx_desc_0_cfg_fifo_9[2]; /* 0x00008e48 */ + u32 rx_desc_0_cfg_fifo_10[2]; /* 0x00008e50 */ + u32 rx_desc_0_cfg_fifo_11[2]; /* 0x00008e58 */ + u32 rx_desc_0_cfg_fifo_12[2]; /* 0x00008e60 */ + u32 rx_desc_0_cfg_fifo_13[2]; /* 0x00008e68 */ + u32 rx_desc_0_cfg_fifo_14[2]; /* 0x00008e70 */ + u32 rx_desc_0_cfg_fifo_15[2]; /* 0x00008e78 */ + u32 rx_desc_0_cfg_fifo_16[2]; /* 0x00008e80 */ + u32 rx_desc_0_cfg_fifo_17[2]; /* 0x00008e88 */ + u32 rx_desc_0_cfg_fifo_18[2]; /* 0x00008e90 */ + u32 rx_desc_0_cfg_fifo_19[2]; /* 0x00008e98 */ + u32 rx_desc_0_cfg_fifo_20[2]; /* 0x00008ea0 */ + u32 rx_desc_0_cfg_fifo_21[2]; /* 0x00008ea8 */ + u32 rx_desc_0_cfg_fifo_22[2]; /* 0x00008eb0 */ + u32 rx_desc_0_cfg_fifo_23[2]; /* 0x00008eb8 */ + u32 rx_desc_0_cfg_fifo_24[2]; /* 0x00008ec0 */ + u32 rx_desc_0_cfg_fifo_25[2]; /* 0x00008ec8 */ + u32 rx_desc_0_cfg_fifo_26[2]; /* 0x00008ed0 */ + u32 rx_desc_0_cfg_fifo_27[2]; /* 0x00008ed8 */ + u32 rx_desc_0_cfg_fifo_28[2]; /* 0x00008ee0 */ + u32 rx_desc_0_cfg_fifo_29[2]; /* 0x00008ee8 */ + u32 rx_desc_0_cfg_fifo_30[2]; /* 0x00008ef0 */ + u32 rx_desc_0_cfg_fifo_31[2]; /* 0x00008ef8 */ + u32 rx_desc_0_cfg_fifo_32[2]; /* 0x00008f00 */ + u32 rx_desc_0_cfg_fifo_33[2]; /* 0x00008f08 */ + u32 rx_desc_0_cfg_fifo_34[2]; /* 0x00008f10 */ + u32 rx_desc_0_cfg_fifo_35[2]; /* 0x00008f18 */ + u32 rx_desc_0_cfg_fifo_36[2]; /* 0x00008f20 */ + u32 rx_desc_0_cfg_fifo_37[2]; /* 0x00008f28 */ + u32 rx_desc_0_cfg_fifo_38[2]; /* 0x00008f30 */ + u32 rx_desc_0_cfg_fifo_39[2]; /* 0x00008f38 */ + u32 rx_desc_0_cfg_fifo_40[2]; /* 0x00008f40 */ + u32 rx_desc_0_cfg_fifo_41[2]; /* 0x00008f48 */ + u32 rx_desc_0_cfg_fifo_42[2]; /* 0x00008f50 */ + u32 rx_desc_0_cfg_fifo_43[2]; /* 0x00008f58 */ + u32 rx_desc_0_cfg_fifo_44[2]; /* 0x00008f60 */ + u32 rx_desc_0_cfg_fifo_45[2]; /* 0x00008f68 */ + u32 rx_desc_0_cfg_fifo_46[2]; /* 0x00008f70 */ + u32 rx_desc_0_cfg_fifo_47[2]; /* 0x00008f78 */ + u32 rx_desc_0_cfg_fifo_48[2]; /* 0x00008f80 */ + u32 rx_desc_0_cfg_fifo_49[2]; /* 0x00008f88 */ + u32 rx_desc_0_cfg_fifo_50[2]; /* 0x00008f90 */ + u32 rx_desc_0_cfg_fifo_51[2]; /* 0x00008f98 */ + u32 rx_desc_0_cfg_fifo_52[2]; /* 0x00008fa0 */ + u32 rx_desc_0_cfg_fifo_53[2]; /* 0x00008fa8 */ + u32 rx_desc_0_cfg_fifo_54[2]; /* 0x00008fb0 */ + u32 rx_desc_0_cfg_fifo_55[2]; /* 0x00008fb8 */ + u32 rx_desc_0_cfg_fifo_56[2]; /* 0x00008fc0 */ + u32 rx_desc_0_cfg_fifo_57[2]; /* 0x00008fc8 */ + u32 rx_desc_0_cfg_fifo_58[2]; /* 0x00008fd0 */ + u32 rx_desc_0_cfg_fifo_59[2]; /* 0x00008fd8 */ + u32 rx_desc_0_cfg_fifo_60[2]; /* 0x00008fe0 */ + u32 rx_desc_0_cfg_fifo_61[2]; /* 0x00008fe8 */ + u32 rx_desc_0_cfg_fifo_62[2]; /* 0x00008ff0 */ + u32 rx_desc_0_cfg_fifo_63[2]; /* 0x00008ff8 */ + u32 rx_desc_1_cfg_fifo_0[2]; /* 0x00009000 */ + u32 rx_desc_1_cfg_fifo_1[2]; /* 0x00009008 */ + u32 rx_desc_1_cfg_fifo_2[2]; /* 0x00009010 */ + u32 rx_desc_1_cfg_fifo_3[2]; /* 0x00009018 */ + u32 rx_desc_1_cfg_fifo_4[2]; /* 0x00009020 */ + u32 rx_desc_1_cfg_fifo_5[2]; /* 0x00009028 */ + u32 rx_desc_1_cfg_fifo_6[2]; /* 0x00009030 */ + u32 rx_desc_1_cfg_fifo_7[2]; /* 0x00009038 */ + u32 rx_desc_1_cfg_fifo_8[2]; /* 0x00009040 */ + u32 rx_desc_1_cfg_fifo_9[2]; /* 0x00009048 */ + u32 rx_desc_1_cfg_fifo_10[2]; /* 0x00009050 */ + u32 rx_desc_1_cfg_fifo_11[2]; /* 0x00009058 */ + u32 rx_desc_1_cfg_fifo_12[2]; /* 0x00009060 */ + u32 rx_desc_1_cfg_fifo_13[2]; /* 0x00009068 */ + u32 rx_desc_1_cfg_fifo_14[2]; /* 0x00009070 */ + u32 rx_desc_1_cfg_fifo_15[2]; /* 0x00009078 */ + u32 rx_desc_1_cfg_fifo_16[2]; /* 0x00009080 */ + u32 rx_desc_1_cfg_fifo_17[2]; /* 0x00009088 */ + u32 rx_desc_1_cfg_fifo_18[2]; /* 0x00009090 */ + u32 rx_desc_1_cfg_fifo_19[2]; /* 0x00009098 */ + u32 rx_desc_1_cfg_fifo_20[2]; /* 0x000090a0 */ + u32 rx_desc_1_cfg_fifo_21[2]; /* 0x000090a8 */ + u32 rx_desc_1_cfg_fifo_22[2]; /* 0x000090b0 */ + u32 rx_desc_1_cfg_fifo_23[2]; /* 0x000090b8 */ + u32 rx_desc_1_cfg_fifo_24[2]; /* 0x000090c0 */ + u32 rx_desc_1_cfg_fifo_25[2]; /* 0x000090c8 */ + u32 rx_desc_1_cfg_fifo_26[2]; /* 0x000090d0 */ + u32 rx_desc_1_cfg_fifo_27[2]; /* 0x000090d8 */ + u32 rx_desc_1_cfg_fifo_28[2]; /* 0x000090e0 */ + u32 rx_desc_1_cfg_fifo_29[2]; /* 0x000090e8 */ + u32 rx_desc_1_cfg_fifo_30[2]; /* 0x000090f0 */ + u32 rx_desc_1_cfg_fifo_31[2]; /* 0x000090f8 */ + u32 rx_desc_1_cfg_fifo_32[2]; /* 0x00009100 */ + u32 rx_desc_1_cfg_fifo_33[2]; /* 0x00009108 */ + u32 rx_desc_1_cfg_fifo_34[2]; /* 0x00009110 */ + u32 rx_desc_1_cfg_fifo_35[2]; /* 0x00009118 */ + u32 rx_desc_1_cfg_fifo_36[2]; /* 0x00009120 */ + u32 rx_desc_1_cfg_fifo_37[2]; /* 0x00009128 */ + u32 rx_desc_1_cfg_fifo_38[2]; /* 0x00009130 */ + u32 rx_desc_1_cfg_fifo_39[2]; /* 0x00009138 */ + u32 rx_desc_1_cfg_fifo_40[2]; /* 0x00009140 */ + u32 rx_desc_1_cfg_fifo_41[2]; /* 0x00009148 */ + u32 rx_desc_1_cfg_fifo_42[2]; /* 0x00009150 */ + u32 rx_desc_1_cfg_fifo_43[2]; /* 0x00009158 */ + u32 rx_desc_1_cfg_fifo_44[2]; /* 0x00009160 */ + u32 rx_desc_1_cfg_fifo_45[2]; /* 0x00009168 */ + u32 rx_desc_1_cfg_fifo_46[2]; /* 0x00009170 */ + u32 rx_desc_1_cfg_fifo_47[2]; /* 0x00009178 */ + u32 rx_desc_1_cfg_fifo_48[2]; /* 0x00009180 */ + u32 rx_desc_1_cfg_fifo_49[2]; /* 0x00009188 */ + u32 rx_desc_1_cfg_fifo_50[2]; /* 0x00009190 */ + u32 rx_desc_1_cfg_fifo_51[2]; /* 0x00009198 */ + u32 rx_desc_1_cfg_fifo_52[2]; /* 0x000091a0 */ + u32 rx_desc_1_cfg_fifo_53[2]; /* 0x000091a8 */ + u32 rx_desc_1_cfg_fifo_54[2]; /* 0x000091b0 */ + u32 rx_desc_1_cfg_fifo_55[2]; /* 0x000091b8 */ + u32 rx_desc_1_cfg_fifo_56[2]; /* 0x000091c0 */ + u32 rx_desc_1_cfg_fifo_57[2]; /* 0x000091c8 */ + u32 rx_desc_1_cfg_fifo_58[2]; /* 0x000091d0 */ + u32 rx_desc_1_cfg_fifo_59[2]; /* 0x000091d8 */ + u32 rx_desc_1_cfg_fifo_60[2]; /* 0x000091e0 */ + u32 rx_desc_1_cfg_fifo_61[2]; /* 0x000091e8 */ + u32 rx_desc_1_cfg_fifo_62[2]; /* 0x000091f0 */ + u32 rx_desc_1_cfg_fifo_63[2]; /* 0x000091f8 */ + u32 rx_desc_0_ack_fifo_0[1]; /* 0x00009200 */ + u32 rx_desc_0_ack_fifo_1[1]; /* 0x00009204 */ + u32 rx_desc_0_ack_fifo_2[1]; /* 0x00009208 */ + u32 rx_desc_0_ack_fifo_3[1]; /* 0x0000920c */ + u32 rx_desc_0_ack_fifo_4[1]; /* 0x00009210 */ + u32 rx_desc_0_ack_fifo_5[1]; /* 0x00009214 */ + u32 rx_desc_0_ack_fifo_6[1]; /* 0x00009218 */ + u32 rx_desc_0_ack_fifo_7[1]; /* 0x0000921c */ + u32 rx_desc_0_ack_fifo_8[1]; /* 0x00009220 */ + u32 rx_desc_0_ack_fifo_9[1]; /* 0x00009224 */ + u32 rx_desc_0_ack_fifo_10[1]; /* 0x00009228 */ + u32 rx_desc_0_ack_fifo_11[1]; /* 0x0000922c */ + u32 rx_desc_0_ack_fifo_12[1]; /* 0x00009230 */ + u32 rx_desc_0_ack_fifo_13[1]; /* 0x00009234 */ + u32 rx_desc_0_ack_fifo_14[1]; /* 0x00009238 */ + u32 rx_desc_0_ack_fifo_15[1]; /* 0x0000923c */ + u32 rx_desc_0_ack_fifo_16[1]; /* 0x00009240 */ + u32 rx_desc_0_ack_fifo_17[1]; /* 0x00009244 */ + u32 rx_desc_0_ack_fifo_18[1]; /* 0x00009248 */ + u32 rx_desc_0_ack_fifo_19[1]; /* 0x0000924c */ + u32 rx_desc_0_ack_fifo_20[1]; /* 0x00009250 */ + u32 rx_desc_0_ack_fifo_21[1]; /* 0x00009254 */ + u32 rx_desc_0_ack_fifo_22[1]; /* 0x00009258 */ + u32 rx_desc_0_ack_fifo_23[1]; /* 0x0000925c */ + u32 rx_desc_0_ack_fifo_24[1]; /* 0x00009260 */ + u32 rx_desc_0_ack_fifo_25[1]; /* 0x00009264 */ + u32 rx_desc_0_ack_fifo_26[1]; /* 0x00009268 */ + u32 rx_desc_0_ack_fifo_27[1]; /* 0x0000926c */ + u32 rx_desc_0_ack_fifo_28[1]; /* 0x00009270 */ + u32 rx_desc_0_ack_fifo_29[1]; /* 0x00009274 */ + u32 rx_desc_0_ack_fifo_30[1]; /* 0x00009278 */ + u32 rx_desc_0_ack_fifo_31[1]; /* 0x0000927c */ + u32 rx_desc_0_ack_fifo_32[1]; /* 0x00009280 */ + u32 rx_desc_0_ack_fifo_33[1]; /* 0x00009284 */ + u32 rx_desc_0_ack_fifo_34[1]; /* 0x00009288 */ + u32 rx_desc_0_ack_fifo_35[1]; /* 0x0000928c */ + u32 rx_desc_0_ack_fifo_36[1]; /* 0x00009290 */ + u32 rx_desc_0_ack_fifo_37[1]; /* 0x00009294 */ + u32 rx_desc_0_ack_fifo_38[1]; /* 0x00009298 */ + u32 rx_desc_0_ack_fifo_39[1]; /* 0x0000929c */ + u32 rx_desc_0_ack_fifo_40[1]; /* 0x000092a0 */ + u32 rx_desc_0_ack_fifo_41[1]; /* 0x000092a4 */ + u32 rx_desc_0_ack_fifo_42[1]; /* 0x000092a8 */ + u32 rx_desc_0_ack_fifo_43[1]; /* 0x000092ac */ + u32 rx_desc_0_ack_fifo_44[1]; /* 0x000092b0 */ + u32 rx_desc_0_ack_fifo_45[1]; /* 0x000092b4 */ + u32 rx_desc_0_ack_fifo_46[1]; /* 0x000092b8 */ + u32 rx_desc_0_ack_fifo_47[1]; /* 0x000092bc */ + u32 rx_desc_0_ack_fifo_48[1]; /* 0x000092c0 */ + u32 rx_desc_0_ack_fifo_49[1]; /* 0x000092c4 */ + u32 rx_desc_0_ack_fifo_50[1]; /* 0x000092c8 */ + u32 rx_desc_0_ack_fifo_51[1]; /* 0x000092cc */ + u32 rx_desc_0_ack_fifo_52[1]; /* 0x000092d0 */ + u32 rx_desc_0_ack_fifo_53[1]; /* 0x000092d4 */ + u32 rx_desc_0_ack_fifo_54[1]; /* 0x000092d8 */ + u32 rx_desc_0_ack_fifo_55[1]; /* 0x000092dc */ + u32 rx_desc_0_ack_fifo_56[1]; /* 0x000092e0 */ + u32 rx_desc_0_ack_fifo_57[1]; /* 0x000092e4 */ + u32 rx_desc_0_ack_fifo_58[1]; /* 0x000092e8 */ + u32 rx_desc_0_ack_fifo_59[1]; /* 0x000092ec */ + u32 rx_desc_0_ack_fifo_60[1]; /* 0x000092f0 */ + u32 rx_desc_0_ack_fifo_61[1]; /* 0x000092f4 */ + u32 rx_desc_0_ack_fifo_62[1]; /* 0x000092f8 */ + u32 rx_desc_0_ack_fifo_63[1]; /* 0x000092fc */ + u32 rx_desc_1_ack_fifo_0[1]; /* 0x00009300 */ + u32 rx_desc_1_ack_fifo_1[1]; /* 0x00009304 */ + u32 rx_desc_1_ack_fifo_2[1]; /* 0x00009308 */ + u32 rx_desc_1_ack_fifo_3[1]; /* 0x0000930c */ + u32 rx_desc_1_ack_fifo_4[1]; /* 0x00009310 */ + u32 rx_desc_1_ack_fifo_5[1]; /* 0x00009314 */ + u32 rx_desc_1_ack_fifo_6[1]; /* 0x00009318 */ + u32 rx_desc_1_ack_fifo_7[1]; /* 0x0000931c */ + u32 rx_desc_1_ack_fifo_8[1]; /* 0x00009320 */ + u32 rx_desc_1_ack_fifo_9[1]; /* 0x00009324 */ + u32 rx_desc_1_ack_fifo_10[1]; /* 0x00009328 */ + u32 rx_desc_1_ack_fifo_11[1]; /* 0x0000932c */ + u32 rx_desc_1_ack_fifo_12[1]; /* 0x00009330 */ + u32 rx_desc_1_ack_fifo_13[1]; /* 0x00009334 */ + u32 rx_desc_1_ack_fifo_14[1]; /* 0x00009338 */ + u32 rx_desc_1_ack_fifo_15[1]; /* 0x0000933c */ + u32 rx_desc_1_ack_fifo_16[1]; /* 0x00009340 */ + u32 rx_desc_1_ack_fifo_17[1]; /* 0x00009344 */ + u32 rx_desc_1_ack_fifo_18[1]; /* 0x00009348 */ + u32 rx_desc_1_ack_fifo_19[1]; /* 0x0000934c */ + u32 rx_desc_1_ack_fifo_20[1]; /* 0x00009350 */ + u32 rx_desc_1_ack_fifo_21[1]; /* 0x00009354 */ + u32 rx_desc_1_ack_fifo_22[1]; /* 0x00009358 */ + u32 rx_desc_1_ack_fifo_23[1]; /* 0x0000935c */ + u32 rx_desc_1_ack_fifo_24[1]; /* 0x00009360 */ + u32 rx_desc_1_ack_fifo_25[1]; /* 0x00009364 */ + u32 rx_desc_1_ack_fifo_26[1]; /* 0x00009368 */ + u32 rx_desc_1_ack_fifo_27[1]; /* 0x0000936c */ + u32 rx_desc_1_ack_fifo_28[1]; /* 0x00009370 */ + u32 rx_desc_1_ack_fifo_29[1]; /* 0x00009374 */ + u32 rx_desc_1_ack_fifo_30[1]; /* 0x00009378 */ + u32 rx_desc_1_ack_fifo_31[1]; /* 0x0000937c */ + u32 rx_desc_1_ack_fifo_32[1]; /* 0x00009380 */ + u32 rx_desc_1_ack_fifo_33[1]; /* 0x00009384 */ + u32 rx_desc_1_ack_fifo_34[1]; /* 0x00009388 */ + u32 rx_desc_1_ack_fifo_35[1]; /* 0x0000938c */ + u32 rx_desc_1_ack_fifo_36[1]; /* 0x00009390 */ + u32 rx_desc_1_ack_fifo_37[1]; /* 0x00009394 */ + u32 rx_desc_1_ack_fifo_38[1]; /* 0x00009398 */ + u32 rx_desc_1_ack_fifo_39[1]; /* 0x0000939c */ + u32 rx_desc_1_ack_fifo_40[1]; /* 0x000093a0 */ + u32 rx_desc_1_ack_fifo_41[1]; /* 0x000093a4 */ + u32 rx_desc_1_ack_fifo_42[1]; /* 0x000093a8 */ + u32 rx_desc_1_ack_fifo_43[1]; /* 0x000093ac */ + u32 rx_desc_1_ack_fifo_44[1]; /* 0x000093b0 */ + u32 rx_desc_1_ack_fifo_45[1]; /* 0x000093b4 */ + u32 rx_desc_1_ack_fifo_46[1]; /* 0x000093b8 */ + u32 rx_desc_1_ack_fifo_47[1]; /* 0x000093bc */ + u32 rx_desc_1_ack_fifo_48[1]; /* 0x000093c0 */ + u32 rx_desc_1_ack_fifo_49[1]; /* 0x000093c4 */ + u32 rx_desc_1_ack_fifo_50[1]; /* 0x000093c8 */ + u32 rx_desc_1_ack_fifo_51[1]; /* 0x000093cc */ + u32 rx_desc_1_ack_fifo_52[1]; /* 0x000093d0 */ + u32 rx_desc_1_ack_fifo_53[1]; /* 0x000093d4 */ + u32 rx_desc_1_ack_fifo_54[1]; /* 0x000093d8 */ + u32 rx_desc_1_ack_fifo_55[1]; /* 0x000093dc */ + u32 rx_desc_1_ack_fifo_56[1]; /* 0x000093e0 */ + u32 rx_desc_1_ack_fifo_57[1]; /* 0x000093e4 */ + u32 rx_desc_1_ack_fifo_58[1]; /* 0x000093e8 */ + u32 rx_desc_1_ack_fifo_59[1]; /* 0x000093ec */ + u32 rx_desc_1_ack_fifo_60[1]; /* 0x000093f0 */ + u32 rx_desc_1_ack_fifo_61[1]; /* 0x000093f4 */ + u32 rx_desc_1_ack_fifo_62[1]; /* 0x000093f8 */ + u32 rx_desc_1_ack_fifo_63[1]; /* 0x000093fc */ + u32 tx_desc_ack_fifo_0[1]; /* 0x00009400 */ + u32 tx_desc_ack_fifo_1[1]; /* 0x00009404 */ + u32 tx_desc_ack_fifo_2[1]; /* 0x00009408 */ + u32 tx_desc_ack_fifo_3[1]; /* 0x0000940c */ + u32 tx_desc_ack_fifo_4[1]; /* 0x00009410 */ + u32 tx_desc_ack_fifo_5[1]; /* 0x00009414 */ + u32 tx_desc_ack_fifo_6[1]; /* 0x00009418 */ + u32 tx_desc_ack_fifo_7[1]; /* 0x0000941c */ + u32 tx_desc_ack_fifo_8[1]; /* 0x00009420 */ + u32 tx_desc_ack_fifo_9[1]; /* 0x00009424 */ + u32 tx_desc_ack_fifo_10[1]; /* 0x00009428 */ + u32 tx_desc_ack_fifo_11[1]; /* 0x0000942c */ + u32 tx_desc_ack_fifo_12[1]; /* 0x00009430 */ + u32 tx_desc_ack_fifo_13[1]; /* 0x00009434 */ + u32 tx_desc_ack_fifo_14[1]; /* 0x00009438 */ + u32 tx_desc_ack_fifo_15[1]; /* 0x0000943c */ + u32 tx_desc_ack_fifo_16[1]; /* 0x00009440 */ + u32 tx_desc_ack_fifo_17[1]; /* 0x00009444 */ + u32 tx_desc_ack_fifo_18[1]; /* 0x00009448 */ + u32 tx_desc_ack_fifo_19[1]; /* 0x0000944c */ + u32 tx_desc_ack_fifo_20[1]; /* 0x00009450 */ + u32 tx_desc_ack_fifo_21[1]; /* 0x00009454 */ + u32 tx_desc_ack_fifo_22[1]; /* 0x00009458 */ + u32 tx_desc_ack_fifo_23[1]; /* 0x0000945c */ + u32 tx_desc_ack_fifo_24[1]; /* 0x00009460 */ + u32 tx_desc_ack_fifo_25[1]; /* 0x00009464 */ + u32 tx_desc_ack_fifo_26[1]; /* 0x00009468 */ + u32 tx_desc_ack_fifo_27[1]; /* 0x0000946c */ + u32 tx_desc_ack_fifo_28[1]; /* 0x00009470 */ + u32 tx_desc_ack_fifo_29[1]; /* 0x00009474 */ + u32 tx_desc_ack_fifo_30[1]; /* 0x00009478 */ + u32 tx_desc_ack_fifo_31[1]; /* 0x0000947c */ + u32 tx_desc_ack_fifo_32[1]; /* 0x00009480 */ + u32 tx_desc_ack_fifo_33[1]; /* 0x00009484 */ + u32 tx_desc_ack_fifo_34[1]; /* 0x00009488 */ + u32 tx_desc_ack_fifo_35[1]; /* 0x0000948c */ + u32 tx_desc_ack_fifo_36[1]; /* 0x00009490 */ + u32 tx_desc_ack_fifo_37[1]; /* 0x00009494 */ + u32 tx_desc_ack_fifo_38[1]; /* 0x00009498 */ + u32 tx_desc_ack_fifo_39[1]; /* 0x0000949c */ + u32 tx_desc_ack_fifo_40[1]; /* 0x000094a0 */ + u32 tx_desc_ack_fifo_41[1]; /* 0x000094a4 */ + u32 tx_desc_ack_fifo_42[1]; /* 0x000094a8 */ + u32 tx_desc_ack_fifo_43[1]; /* 0x000094ac */ + u32 tx_desc_ack_fifo_44[1]; /* 0x000094b0 */ + u32 tx_desc_ack_fifo_45[1]; /* 0x000094b4 */ + u32 tx_desc_ack_fifo_46[1]; /* 0x000094b8 */ + u32 tx_desc_ack_fifo_47[1]; /* 0x000094bc */ + u32 tx_desc_ack_fifo_48[1]; /* 0x000094c0 */ + u32 tx_desc_ack_fifo_49[1]; /* 0x000094c4 */ + u32 tx_desc_ack_fifo_50[1]; /* 0x000094c8 */ + u32 tx_desc_ack_fifo_51[1]; /* 0x000094cc */ + u32 tx_desc_ack_fifo_52[1]; /* 0x000094d0 */ + u32 tx_desc_ack_fifo_53[1]; /* 0x000094d4 */ + u32 tx_desc_ack_fifo_54[1]; /* 0x000094d8 */ + u32 tx_desc_ack_fifo_55[1]; /* 0x000094dc */ + u32 tx_desc_ack_fifo_56[1]; /* 0x000094e0 */ + u32 tx_desc_ack_fifo_57[1]; /* 0x000094e4 */ + u32 tx_desc_ack_fifo_58[1]; /* 0x000094e8 */ + u32 tx_desc_ack_fifo_59[1]; /* 0x000094ec */ + u32 tx_desc_ack_fifo_60[1]; /* 0x000094f0 */ + u32 tx_desc_ack_fifo_61[1]; /* 0x000094f4 */ + u32 tx_desc_ack_fifo_62[1]; /* 0x000094f8 */ + u32 tx_desc_ack_fifo_63[1]; /* 0x000094fc */ + u32 cpu_mac_desc_intf_0[2]; /* 0x00009500 */ + u32 cpu_mac_desc_intf_1[2]; /* 0x00009508 */ + u32 cpu_mac_desc_intf_2[2]; /* 0x00009510 */ +}; + +/* tx_pkt_fifo Definition */ +#define TX_PKT_FIFO_W0_TX_PKT_FIFO_FIELD0 BIT(0) +#define TX_PKT_FIFO_W1_TX_PKT_FIFO_FIELD1 BIT(0) +#define TX_PKT_FIFO_W2_TX_PKT_FIFO_FIELD2 BIT(0) + +#define TX_PKT_FIFO_W0_TX_PKT_FIFO_FIELD0_MASK 0xffffffff +#define TX_PKT_FIFO_W1_TX_PKT_FIFO_FIELD1_MASK 0xffffffff +#define TX_PKT_FIFO_W2_TX_PKT_FIFO_FIELD2_MASK 0x0000000f + +/* rx_pkt_msg_fifo Definition */ +#define RX_PKT_MSG_FIFO_W0_RX_PKT_MSG_FIFO_FIELD BIT(0) + +#define RX_PKT_MSG_FIFO_W0_RX_PKT_MSG_FIFO_FIELD_MASK 0x0000ffff + +/* cpu_mac_stats_ram Definition */ +#define CPU_MAC_STATS_RAM_W0_BYTE_CNT_31_0 BIT(0) +#define CPU_MAC_STATS_RAM_W1_BYTE_CNT_39_32 BIT(0) +#define CPU_MAC_STATS_RAM_W2_FRAME_CNT_31_0 BIT(0) +#define CPU_MAC_STATS_RAM_W3_FRAME_CNT_33_32 BIT(0) + +#define CPU_MAC_STATS_RAM_W0_BYTE_CNT_31_0_MASK 0xffffffff +#define CPU_MAC_STATS_RAM_W1_BYTE_CNT_39_32_MASK 0x000000ff +#define CPU_MAC_STATS_RAM_W2_FRAME_CNT_31_0_MASK 0xffffffff +#define CPU_MAC_STATS_RAM_W3_FRAME_CNT_33_32_MASK 0x00000003 + +/* tx_desc_cfg_fifo Definition */ +#define TX_DESC_CFG_FIFO_W0_TX_DESC_CFG_FIFO_FIELD0 BIT(0) +#define TX_DESC_CFG_FIFO_W1_TX_DESC_CFG_FIFO_FIELD1 BIT(0) + +#define TX_DESC_CFG_FIFO_W0_TX_DESC_CFG_FIFO_FIELD0_MASK 0xffffffff +#define TX_DESC_CFG_FIFO_W1_TX_DESC_CFG_FIFO_FIELD1_MASK 0x01ffffff + +/* rx_desc_0_cfg_fifo Definition */ +#define RX_DESC0_CFG_FIFO_W0_RX_DESC0_CFG_FIFO_FIELD0 BIT(0) +#define RX_DESC0_CFG_FIFO_W1_RX_DESC0_CFG_FIFO_FIELD1 BIT(0) + +#define RX_DESC0_CFG_FIFO_W0_RX_DESC0_CFG_FIFO_FIELD0_MASK 0xffffffff +#define RX_DESC0_CFG_FIFO_W1_RX_DESC0_CFG_FIFO_FIELD1_MASK 0x01ffffff + +/* rx_desc_1_cfg_fifo Definition */ +#define RX_DESC1_CFG_FIFO_W0_RX_DESC1_CFG_FIFO_FIELD0 BIT(0) +#define RX_DESC1_CFG_FIFO_W1_RX_DESC1_CFG_FIFO_FIELD1 BIT(0) + +#define RX_DESC1_CFG_FIFO_W0_RX_DESC1_CFG_FIFO_FIELD0_MASK 0xffffffff +#define RX_DESC1_CFG_FIFO_W1_RX_DESC1_CFG_FIFO_FIELD1_MASK 0x01ffffff + +/* rx_desc_0_ack_fifo Definition */ +#define RX_DESC0_ACK_FIFO_W0_RX_DESC0_ACK_FIFO_FIELD BIT(0) + +#define RX_DESC0_ACK_FIFO_W0_RX_DESC0_ACK_FIFO_FIELD_MASK 0x0007ffff + +/* rx_desc_1_ack_fifo Definition */ +#define RX_DESC1_ACK_FIFO_W0_RX_DESC1_ACK_FIFO_FIELD BIT(0) + +#define RX_DESC1_ACK_FIFO_W0_RX_DESC1_ACK_FIFO_FIELD_MASK 0x0007ffff + +/* tx_desc_ack_fifo Definition */ +#define TX_DESC_ACK_FIFO_W0_TX_DESC_ACK_FIFO_FIELD BIT(0) + +#define TX_DESC_ACK_FIFO_W0_TX_DESC_ACK_FIFO_FIELD_MASK 0x00000001 + +/* cpu_mac_desc_intf Definition */ +#define CPU_MAC_DESC_INTF_W0_DESC_ADDR_31_0 BIT(0) +#define CPU_MAC_DESC_INTF_W1_DESC_ADDR_39_32 BIT(0) +#define CPU_MAC_DESC_INTF_W1_DESC_SIZE BIT(8) +#define CPU_MAC_DESC_INTF_W1_DESC_SOP BIT(22) +#define CPU_MAC_DESC_INTF_W1_DESC_ERR_TYPE BIT(25) +#define CPU_MAC_DESC_INTF_W1_DESC_EOP BIT(23) +#define CPU_MAC_DESC_INTF_W1_DESC_ERR BIT(24) + +#define CPU_MAC_DESC_INTF_W0_DESC_ADDR_31_0_MASK 0xffffffff +#define CPU_MAC_DESC_INTF_W1_DESC_ADDR_39_32_MASK 0x000000ff +#define CPU_MAC_DESC_INTF_W1_DESC_SIZE_MASK 0x003fff00 +#define CPU_MAC_DESC_INTF_W1_DESC_SOP_MASK 0x00400000 +#define CPU_MAC_DESC_INTF_W1_DESC_ERR_TYPE_MASK 0x0e000000 +#define CPU_MAC_DESC_INTF_W1_DESC_EOP_MASK 0x00800000 +#define CPU_MAC_DESC_INTF_W1_DESC_ERR_MASK 0x01000000 + +/* defing MDIOSOC_REG_BASE 0x00000000 */ + +struct mdio_soc_regs { + u32 mdio_soc_cmd_0[2]; /* 0x00000000 */ + u32 mdio_soc_cmd_1[2]; /* 0x00000008 */ + u32 mdio_soc_status_1; /* 0x00000010 */ + u32 mdio_soc_status_0; /* 0x00000014 */ + u32 mdio_soc_reserved; /* 0x00000018 */ + u32 mdio_soc_cfg_0; /* 0x0000001c */ + u32 mdio_soc_cfg_1; /* 0x00000020 */ +}; + +/* mdio_soc_cmd_0 Definition */ +#define MDIO_SOC_CMD0_W0_OP_CODE_CMD_LANE0 BIT(26) +#define MDIO_SOC_CMD0_W0_REG_ADD_CMD_LANE0 BIT(16) +#define MDIO_SOC_CMD0_W0_DATA_CMD_LANE0 BIT(0) +#define MDIO_SOC_CMD0_W0_PHY_ADD_CMD_LANE0 BIT(21) +#define MDIO_SOC_CMD0_W1_START_CMD_LANE0 BIT(0) + +#define MDIO_SOC_CMD0_W0_OP_CODE_CMD_LANE0_MASK 0x0c000000 +#define MDIO_SOC_CMD0_W0_REG_ADD_CMD_LANE0_MASK 0x001f0000 +#define MDIO_SOC_CMD0_W0_DATA_CMD_LANE0_MASK 0x0000ffff +#define MDIO_SOC_CMD0_W0_PHY_ADD_CMD_LANE0_MASK 0x03e00000 +#define MDIO_SOC_CMD0_W1_START_CMD_LANE0_MASK 0x00000003 + +/* mdio_soc_cmd_1 Definition */ +#define MDIO_SOC_CMD1_W0_PHY_ADD_CMD_LANE1 BIT(21) +#define MDIO_SOC_CMD1_W0_OP_CODE_CMD_LANE1 BIT(26) +#define MDIO_SOC_CMD1_W0_DATA_CMD_LANE1 BIT(0) +#define MDIO_SOC_CMD1_W0_REG_ADD_CMD_LANE1 BIT(16) +#define MDIO_SOC_CMD1_W1_START_CMD_LANE1 BIT(0) + +#define MDIO_SOC_CMD1_W0_PHY_ADD_CMD_LANE1_MASK 0x03e00000 +#define MDIO_SOC_CMD1_W0_OP_CODE_CMD_LANE1_MASK 0x0c000000 +#define MDIO_SOC_CMD1_W0_DATA_CMD_LANE1_MASK 0x0000ffff +#define MDIO_SOC_CMD1_W0_REG_ADD_CMD_LANE1_MASK 0x001f0000 +#define MDIO_SOC_CMD1_W1_START_CMD_LANE1_MASK 0x00000003 + +/* mdio_soc_status_1 Definition */ +#define MDIO_SOC_STATUS1_W0_MDIO_CMD_DONE_LANE1 BIT(16) +#define MDIO_SOC_STATUS1_W0_MDIO_READ_DATA_LANE1 BIT(0) + +#define MDIO_SOC_STATUS1_W0_MDIO_CMD_DONE_LANE1_MASK 0x00010000 +#define MDIO_SOC_STATUS1_W0_MDIO_READ_DATA_LANE1_MASK 0x0000ffff + +/* mdio_soc_status_0 Definition */ +#define MDIO_SOC_STATUS0_W0_MDIO_CMD_DONE_LANE0 BIT(16) +#define MDIO_SOC_STATUS0_W0_MDIO_READ_DATA_LANE0 BIT(0) + +#define MDIO_SOC_STATUS0_W0_MDIO_CMD_DONE_LANE0_MASK 0x00010000 +#define MDIO_SOC_STATUS0_W0_MDIO_READ_DATA_LANE0_MASK 0x0000ffff + +/* mdio_soc_reserved Definition */ +#define MDIO_SOC_RESERVED_W0_RESERVED BIT(0) + +#define MDIO_SOC_RESERVED_W0_RESERVED_MASK 0x0000ffff + +/* mdio_soc_cfg_0 Definition */ +#define MDIO_SOC_CFG0_W0_MDIO_MAC_PRE_LANE0 BIT(0) +#define MDIO_SOC_CFG0_W0_MDIO_IN_DLY_LANE0 BIT(8) + +#define MDIO_SOC_CFG0_W0_MDIO_MAC_PRE_LANE0_MASK 0x0000003f +#define MDIO_SOC_CFG0_W0_MDIO_IN_DLY_LANE0_MASK 0x00000f00 + +/* mdio_soc_cfg_1 Definition */ +#define MDIO_SOC_CFG1_W0_MDIO_IN_DLY_LANE1 BIT(8) +#define MDIO_SOC_CFG1_W0_MDIO_MAC_PRE_LANE1 BIT(0) + +#define MDIO_SOC_CFG1_W0_MDIO_IN_DLY_LANE1_MASK 0x00000f00 +#define MDIO_SOC_CFG1_W0_MDIO_MAC_PRE_LANE1_MASK 0x0000003f + +#define CPUMACUNIT_MEM_BASE 0x00000400 +#define CPUMACUNIT_REG_BASE 0x00000040 + +struct cpu_mac_unit_regs { + u32 cpu_mac_unit_hss_mon[7]; /* 0x00000040 */ + u32 rsv23; + u32 cpu_mac_hss_reg_acc_timing_cfg[2]; /* 0x00000060 */ + u32 cpu_mac_unit_reset_ctl; /* 0x00000068 */ + u32 cpu_mac_unit_hss_reg_acc_ctl; /* 0x0000006c */ + u32 cpu_mac_unit_hss_reg_acc_result; /* 0x00000070 */ + u32 cpu_mac_unit_axi_cfg; /* 0x00000074 */ + u32 cpu_mac_unit_ts_cfg; /* 0x00000078 */ + u32 cpu_mac_unit_fifo_status; /* 0x0000007c */ + u32 cpu_mac_unit_ts_mon[3]; /* 0x00000080 */ + u32 rsv35; + u32 cpu_mac_unit_ref_pulse_cfg[4]; /* 0x00000090 */ + u32 cpu_mac_unit_interrupt_func[4]; /* 0x000000a0 */ + u32 rsv44; + u32 rsv45; + u32 rsv46; + u32 rsv47; + u32 cpu_mac_unit_hss_cfg[12]; /* 0x000000c0 */ + u32 rsv60; + u32 rsv61; + u32 rsv62; + u32 rsv63; + u32 cpu_mac_unit_ip_cam_cfg[32]; /* 0x00000100 */ + u32 cpu_mac_unit_mac_cam_cfg[32]; /* 0x00000180 */ + u32 cpu_mac_unit_filter_cfg[6]; /* 0x00000200 */ +}; + +/* cpu_mac_unit_hss_mon Definition */ +#define CPU_MAC_UNIT_HSS_MON_W0_MON_HSS_CMU0_DBG_OBS BIT(0) +#define CPU_MAC_UNIT_HSS_MON_W0_MON_HSS_CMU0_LOL BIT(16) +#define CPU_MAC_UNIT_HSS_MON_W1_MON_HSS_L0_PMA2_PCS_TX_DET_RX_N BIT(22) +#define CPU_MAC_UNIT_HSS_MON_W1_MON_HSS_L0_PMA2_PCS_TX_DET_RX_P BIT(23) +#define CPU_MAC_UNIT_HSS_MON_W1_MON_HSS_L0_LOL_UDL BIT(20) +#define CPU_MAC_UNIT_HSS_MON_W1_MON_HSS_L0_RX_EI BIT(18) +#define CPU_MAC_UNIT_HSS_MON_W1_MON_HSS_L0_DBG_OBS BIT(0) +#define CPU_MAC_UNIT_HSS_MON_W1_MON_HSS_L0_PMA_RST_DONE BIT(17) +#define CPU_MAC_UNIT_HSS_MON_W1_MON_HSS_L0_I_SCAN_DONE BIT(21) +#define CPU_MAC_UNIT_HSS_MON_W1_MON_HSS_L0_RX_EI_FILTERED BIT(24) +#define CPU_MAC_UNIT_HSS_MON_W1_MON_HSS_L0_LOL BIT(19) +#define CPU_MAC_UNIT_HSS_MON_W1_MON_HSS_L0_DFE_RST_DONE BIT(16) +#define CPU_MAC_UNIT_HSS_MON_W2_MON_HSS_L0_I_SCAN_RESULTS_31_0 BIT(0) +#define CPU_MAC_UNIT_HSS_MON_W3_MON_HSS_L0_I_SCAN_RESULTS_63_32 BIT(0) +#define CPU_MAC_UNIT_HSS_MON_W4_MON_HSS_L1_PMA2_PCS_TX_DET_RX_P BIT(23) +#define CPU_MAC_UNIT_HSS_MON_W4_MON_HSS_L1_RX_EI_FILTERED BIT(24) +#define CPU_MAC_UNIT_HSS_MON_W4_MON_HSS_L1_I_SCAN_DONE BIT(21) +#define CPU_MAC_UNIT_HSS_MON_W4_MON_HSS_L1_PMA2_PCS_TX_DET_RX_N BIT(22) +#define CPU_MAC_UNIT_HSS_MON_W4_MON_HSS_L1_LOL BIT(19) +#define CPU_MAC_UNIT_HSS_MON_W4_MON_HSS_L1_DFE_RST_DONE BIT(16) +#define CPU_MAC_UNIT_HSS_MON_W4_MON_HSS_L1_LOL_UDL BIT(20) +#define CPU_MAC_UNIT_HSS_MON_W4_MON_HSS_L1_PMA_RST_DONE BIT(17) +#define CPU_MAC_UNIT_HSS_MON_W4_MON_HSS_L1_RX_EI BIT(18) +#define CPU_MAC_UNIT_HSS_MON_W4_MON_HSS_L1_DBG_OBS BIT(0) +#define CPU_MAC_UNIT_HSS_MON_W5_MON_HSS_L1_I_SCAN_RESULTS_31_0 BIT(0) +#define CPU_MAC_UNIT_HSS_MON_W6_MON_HSS_L1_I_SCAN_RESULTS_63_32 BIT(0) + +#define CPU_MAC_UNIT_HSS_MON_W0_MON_HSS_CMU0_DBG_OBS_MASK 0x0000ffff +#define CPU_MAC_UNIT_HSS_MON_W0_MON_HSS_CMU0_LOL_MASK 0x00010000 +#define CPU_MAC_UNIT_HSS_MON_W1_MON_HSS_L0_PMA2_PCS_TX_DET_RX_N_MASK 0x00400000 +#define CPU_MAC_UNIT_HSS_MON_W1_MON_HSS_L0_PMA2_PCS_TX_DET_RX_P_MASK 0x00800000 +#define CPU_MAC_UNIT_HSS_MON_W1_MON_HSS_L0_LOL_UDL_MASK 0x00100000 +#define CPU_MAC_UNIT_HSS_MON_W1_MON_HSS_L0_RX_EI_MASK 0x00040000 +#define CPU_MAC_UNIT_HSS_MON_W1_MON_HSS_L0_DBG_OBS_MASK 0x0000ffff +#define CPU_MAC_UNIT_HSS_MON_W1_MON_HSS_L0_PMA_RST_DONE_MASK 0x00020000 +#define CPU_MAC_UNIT_HSS_MON_W1_MON_HSS_L0_I_SCAN_DONE_MASK 0x00200000 +#define CPU_MAC_UNIT_HSS_MON_W1_MON_HSS_L0_RX_EI_FILTERED_MASK 0x01000000 +#define CPU_MAC_UNIT_HSS_MON_W1_MON_HSS_L0_LOL_MASK 0x00080000 +#define CPU_MAC_UNIT_HSS_MON_W1_MON_HSS_L0_DFE_RST_DONE_MASK 0x00010000 +#define CPU_MAC_UNIT_HSS_MON_W2_MON_HSS_L0_I_SCAN_RESULTS_31_0_MASK 0x00000001 +#define CPU_MAC_UNIT_HSS_MON_W3_MON_HSS_L0_I_SCAN_RESULTS_63_32_MASK 0x00000001 +#define CPU_MAC_UNIT_HSS_MON_W4_MON_HSS_L1_PMA2_PCS_TX_DET_RX_P_MASK 0x00800000 +#define CPU_MAC_UNIT_HSS_MON_W4_MON_HSS_L1_RX_EI_FILTERED_MASK 0x01000000 +#define CPU_MAC_UNIT_HSS_MON_W4_MON_HSS_L1_I_SCAN_DONE_MASK 0x00200000 +#define CPU_MAC_UNIT_HSS_MON_W4_MON_HSS_L1_PMA2_PCS_TX_DET_RX_N_MASK 0x00400000 +#define CPU_MAC_UNIT_HSS_MON_W4_MON_HSS_L1_LOL_MASK 0x00080000 +#define CPU_MAC_UNIT_HSS_MON_W4_MON_HSS_L1_DFE_RST_DONE_MASK 0x00010000 +#define CPU_MAC_UNIT_HSS_MON_W4_MON_HSS_L1_LOL_UDL_MASK 0x00100000 +#define CPU_MAC_UNIT_HSS_MON_W4_MON_HSS_L1_PMA_RST_DONE_MASK 0x00020000 +#define CPU_MAC_UNIT_HSS_MON_W4_MON_HSS_L1_RX_EI_MASK 0x00040000 +#define CPU_MAC_UNIT_HSS_MON_W4_MON_HSS_L1_DBG_OBS_MASK 0x0000ffff +#define CPU_MAC_UNIT_HSS_MON_W5_MON_HSS_L1_I_SCAN_RESULTS_31_0_MASK 0x00000001 +#define CPU_MAC_UNIT_HSS_MON_W6_MON_HSS_L1_I_SCAN_RESULTS_63_32_MASK 0x00000001 + +/* cpu_mac_hss_reg_acc_timing_cfg Definition */ +#define CPU_MAC_HSS_REG_ACC_TIMING_CFG_W0_CFG_ACTIVE_CYCLES BIT(0) +#define CPU_MAC_HSS_REG_ACC_TIMING_CFG_W0_CFG_HOLD_CYCLES BIT(8) +#define CPU_MAC_HSS_REG_ACC_TIMING_CFG_W1_CFG_RD_OUT_VALID_CYCLES BIT(8) +#define CPU_MAC_HSS_REG_ACC_TIMING_CFG_W1_CFG_SETUP_CYCLES BIT(0) + +#define CPU_MAC_HSS_REG_ACC_TIMING_CFG_W0_CFG_ACTIVE_CYCLES_MASK 0x000000ff +#define CPU_MAC_HSS_REG_ACC_TIMING_CFG_W0_CFG_HOLD_CYCLES_MASK 0x0000ff00 +#define CPU_MAC_HSS_REG_ACC_TIMING_CFG_W1_CFG_RD_OUT_VALID_CYCLES_MASK 0x0000ff00 +#define CPU_MAC_HSS_REG_ACC_TIMING_CFG_W1_CFG_SETUP_CYCLES_MASK 0x000000ff + +/* cpu_mac_unit_reset_ctl Definition */ +#define CPU_MAC_UNIT_RESET_CTL_W0_RESET_CORE_CPU_MAC1 BIT(1) +#define CPU_MAC_UNIT_RESET_CTL_W0_RESET_CORE_CPU_MAC0 BIT(2) +#define CPU_MAC_UNIT_RESET_CTL_W0_RESET_CORE_BASE BIT(0) + +#define CPU_MAC_UNIT_RESET_CTL_W0_RESET_CORE_CPU_MAC1_MASK 0x00000002 +#define CPU_MAC_UNIT_RESET_CTL_W0_RESET_CORE_CPU_MAC0_MASK 0x00000004 +#define CPU_MAC_UNIT_RESET_CTL_W0_RESET_CORE_BASE_MASK 0x00000001 + +/* cpu_mac_unit_hss_reg_acc_ctl Definition */ +#define CPU_MAC_UNIT_HSS_REG_ACC_CTL_W0_HSS_ACC_WDATA BIT(8) +#define CPU_MAC_UNIT_HSS_REG_ACC_CTL_W0_HSS_ACC_VALID BIT(31) +#define CPU_MAC_UNIT_HSS_REG_ACC_CTL_W0_HSS_ACC_ADDR BIT(0) +#define CPU_MAC_UNIT_HSS_REG_ACC_CTL_W0_HSS_ACC_IS_READ BIT(16) +#define CPU_MAC_UNIT_HSS_REG_ACC_CTL_W0_HSS_ACC_ID BIT(24) + +#define CPU_MAC_UNIT_HSS_REG_ACC_CTL_W0_HSS_ACC_WDATA_MASK 0x0000ff00 +#define CPU_MAC_UNIT_HSS_REG_ACC_CTL_W0_HSS_ACC_VALID_MASK 0x80000000 +#define CPU_MAC_UNIT_HSS_REG_ACC_CTL_W0_HSS_ACC_ADDR_MASK 0x000000ff +#define CPU_MAC_UNIT_HSS_REG_ACC_CTL_W0_HSS_ACC_IS_READ_MASK 0x00010000 +#define CPU_MAC_UNIT_HSS_REG_ACC_CTL_W0_HSS_ACC_ID_MASK 0x0f000000 + +/* cpu_mac_unit_hss_reg_acc_result Definition */ +#define CPU_MAC_UNIT_HSS_REG_ACC_RESULT_W0_HSS_ACC_ACK BIT(31) +#define CPU_MAC_UNIT_HSS_REG_ACC_RESULT_W0_HSS_ACC_ACK_DATA BIT(0) + +#define CPU_MAC_UNIT_HSS_REG_ACC_RESULT_W0_HSS_ACC_ACK_MASK 0x80000000 +#define CPU_MAC_UNIT_HSS_REG_ACC_RESULT_W0_HSS_ACC_ACK_DATA_MASK 0x000000ff + +/* cpu_mac_unit_axi_cfg Definition */ +#define CPU_MAC_UNIT_AXI_CFG_W0_CFG_AXI0_ID BIT(0) +#define CPU_MAC_UNIT_AXI_CFG_W0_CFG_AXI1_ID BIT(4) + +#define CPU_MAC_UNIT_AXI_CFG_W0_CFG_AXI0_ID_MASK 0x0000000f +#define CPU_MAC_UNIT_AXI_CFG_W0_CFG_AXI1_ID_MASK 0x000000f0 + +/* cpu_mac_unit_ts_cfg Definition */ +#define CPU_MAC_UNIT_TS_CFG_W0_CFG_TX_CAPTURE_FIFO_INTR_THRD BIT(0) +#define CPU_MAC_UNIT_TS_CFG_W0_CFG_FORCE_S_AND_NS_EN BIT(31) + +#define CPU_MAC_UNIT_TS_CFG_W0_CFG_TX_CAPTURE_FIFO_INTR_THRD_MASK 0x0000000f +#define CPU_MAC_UNIT_TS_CFG_W0_CFG_FORCE_S_AND_NS_EN_MASK 0x80000000 + +/* cpu_mac_unit_fifo_status Definition */ +#define CPU_MAC_UNIT_FIFO_STATUS_W0_CPU_MAC_UNIT_TX_TS_CAPTURE_FIFO_FIFO_DEPTH BIT(0) + +#define CPU_MAC_UNIT_FIFO_STATUS_W0_CPU_MAC_UNIT_TX_TS_CAPTURE_FIFO_FIFO_DEPTH_MASK 0x0000000f + +/* cpu_mac_unit_ts_mon Definition */ +#define CPU_MAC_UNIT_TS_MON_W0_MON_ADJ_NS BIT(0) +#define CPU_MAC_UNIT_TS_MON_W1_MON_ADJ_SECOND BIT(0) +#define CPU_MAC_UNIT_TS_MON_W2_MON_TX_CAPTURE_FIFO_DROP_CNT BIT(0) + +#define CPU_MAC_UNIT_TS_MON_W0_MON_ADJ_NS_MASK 0x3fffffff +#define CPU_MAC_UNIT_TS_MON_W1_MON_ADJ_SECOND_MASK 0xffffffff +#define CPU_MAC_UNIT_TS_MON_W2_MON_TX_CAPTURE_FIFO_DROP_CNT_MASK 0x0000000f + +/* cpu_mac_unit_ref_pulse_cfg Definition */ +#define CPU_MAC_UNIT_REF_PULSE_CFG_W0_REF_PAUSE_TIMER_PULSE_DIV BIT(0) +#define CPU_MAC_UNIT_REF_PULSE_CFG_W0_REF_PAUSE_TIMER_PULSE_RST BIT(31) +#define CPU_MAC_UNIT_REF_PULSE_CFG_W1_REF_LINK_PULSE_DIV BIT(0) +#define CPU_MAC_UNIT_REF_PULSE_CFG_W1_REF_LINK_PULSE_RST BIT(31) +#define CPU_MAC_UNIT_REF_PULSE_CFG_W2_REF_LINK_FILTER_PULSE_RST BIT(31) +#define CPU_MAC_UNIT_REF_PULSE_CFG_W2_REF_LINK_FILTER_PULSE_DIV BIT(0) +#define CPU_MAC_UNIT_REF_PULSE_CFG_W3_REF_EEE_PULSE_DIV BIT(0) +#define CPU_MAC_UNIT_REF_PULSE_CFG_W3_REF_EEE_PULSE_RST BIT(31) + +#define CPU_MAC_UNIT_REF_PULSE_CFG_W0_REF_PAUSE_TIMER_PULSE_DIV_MASK 0x7fffffff +#define CPU_MAC_UNIT_REF_PULSE_CFG_W0_REF_PAUSE_TIMER_PULSE_RST_MASK 0x80000000 +#define CPU_MAC_UNIT_REF_PULSE_CFG_W1_REF_LINK_PULSE_DIV_MASK 0x7fffffff +#define CPU_MAC_UNIT_REF_PULSE_CFG_W1_REF_LINK_PULSE_RST_MASK 0x80000000 +#define CPU_MAC_UNIT_REF_PULSE_CFG_W2_REF_LINK_FILTER_PULSE_RST_MASK 0x80000000 +#define CPU_MAC_UNIT_REF_PULSE_CFG_W2_REF_LINK_FILTER_PULSE_DIV_MASK 0x7fffffff +#define CPU_MAC_UNIT_REF_PULSE_CFG_W3_REF_EEE_PULSE_DIV_MASK 0x7fffffff +#define CPU_MAC_UNIT_REF_PULSE_CFG_W3_REF_EEE_PULSE_RST_MASK 0x80000000 + +/* cpu_mac_unit_interrupt_func Definition */ +#define CPU_MAC_UNIT_INTERRUPT_FUNC_W0_VALUE_SET0_CPU_MAC_UNIT_INTERRUPT_FUNC BIT(0) +#define CPU_MAC_UNIT_INTERRUPT_FUNC_W1_VALUE_RESET0_CPU_MAC_UNIT_INTERRUPT_FUNC BIT(0) +#define CPU_MAC_UNIT_INTERRUPT_FUNC_W2_MASK_SET0_CPU_MAC_UNIT_INTERRUPT_FUNC BIT(0) +#define CPU_MAC_UNIT_INTERRUPT_FUNC_W3_MASK_RESET0_CPU_MAC_UNIT_INTERRUPT_FUNC BIT(0) + +#define CPU_MAC_UNIT_INTERRUPT_FUNC_W0_VALUE_SET0_CPU_MAC_UNIT_INTERRUPT_FUNC_MASK 0x00000001 +#define CPU_MAC_UNIT_INTERRUPT_FUNC_W1_VALUE_RESET0_CPU_MAC_UNIT_INTERRUPT_FUNC_MASK 0x00000001 +#define CPU_MAC_UNIT_INTERRUPT_FUNC_W2_MASK_SET0_CPU_MAC_UNIT_INTERRUPT_FUNC_MASK 0x00000001 +#define CPU_MAC_UNIT_INTERRUPT_FUNC_W3_MASK_RESET0_CPU_MAC_UNIT_INTERRUPT_FUNC_MASK 0x00000001 + +/* cpu_mac_unit_hss_cfg Definition */ +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_BCLK_RST_N_BIT 1 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_HWT_BIAS_DN_EN_BIT 13 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_HWT_BIAS_UP_EN_BIT 14 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_HWT_CFG_DIV_SEL_BIT 5 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_HWT_CK_TREE_PD_BIT 29 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_HWT_EN_TX_CK_DN_BIT 24 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_HWT_EN_TX_CK_UP_BIT 23 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_HWT_IBIAS_PD_BIT 26 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_HWT_LINK_BUF_EN_BIT 16 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_HWT_MULTI_LANE_MODE_BIT 12 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_HWT_PMA_TX_CK_PD_BIT 31 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_HWT_REFCK_PD_BIT 30 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_HWT_REFCK_TERM_EN_BIT 25 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_HWT_RST_TREE_PD_MA_BIT 27 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_HWT_VCO_DIV_SEL_BIT 2 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_HWT_VCO_PD_BIT 28 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_PCLK_GATING_BIT 15 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_PCS2_PMA_PHY_MODE_BIT 18 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_REXT10_K_BIT 11 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_RST_N_BIT 17 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_GLB_RST_N_BIT 0 +#define CPU_MAC_UNIT_HSS_CFG_W1_CFG_HSS_CMU0_HWT_CTRL_LOGIC_PD_BIT 28 +#define CPU_MAC_UNIT_HSS_CFG_W1_CFG_HSS_CMU0_HWT_EN_DUMMY_BIT 29 +#define CPU_MAC_UNIT_HSS_CFG_W1_CFG_HSS_CMU0_HWT_PD_DIV64_BIT 26 +#define CPU_MAC_UNIT_HSS_CFG_W1_CFG_HSS_CMU0_HWT_PD_DIV66_BIT 27 +#define CPU_MAC_UNIT_HSS_CFG_W1_CFG_HSS_CMU0_HWT_REF_CK_CENTER_SPREAD_BIT 25 +#define CPU_MAC_UNIT_HSS_CFG_W1_CFG_HSS_CMU0_HWT_REF_CK_MCNT_MAX_VAL_BIT 9 +#define CPU_MAC_UNIT_HSS_CFG_W1_CFG_HSS_CMU0_HWT_REF_CK_NCN_MAX_VAL_BIT 14 +#define CPU_MAC_UNIT_HSS_CFG_W1_CFG_HSS_CMU0_HWT_REF_CK_RES_EN_BIT 2 +#define CPU_MAC_UNIT_HSS_CFG_W1_CFG_HSS_CMU0_HWT_REF_CK_SRC_SEL_BIT 3 +#define CPU_MAC_UNIT_HSS_CFG_W1_CFG_HSS_CMU0_HWT_REF_CK_SSC_PI_BW_BIT 6 +#define CPU_MAC_UNIT_HSS_CFG_W1_CFG_HSS_CMU0_HWT_REF_CK_SSC_PI_STEP_BIT 4 +#define CPU_MAC_UNIT_HSS_CFG_W1_CFG_HSS_CMU0_HWT_REF_CK_SSC_RESET_N_BIT 1 +#define CPU_MAC_UNIT_HSS_CFG_W1_CFG_HSS_CMU0_HWT_REF_CK_SSC_RTL_CLK_SEL_BIT 0 +#define CPU_MAC_UNIT_HSS_CFG_W2_CFG_HSS_L0_AUX_RX_CK_SEL_BIT 2 +#define CPU_MAC_UNIT_HSS_CFG_W2_CFG_HSS_L0_AUX_TX_CK_SEL_BIT 1 +#define CPU_MAC_UNIT_HSS_CFG_W2_CFG_HSS_L0_DATA_WIDTH_SEL_BIT 7 +#define CPU_MAC_UNIT_HSS_CFG_W2_CFG_HSS_L0_HWT_MULTI_LANE_MODE_BIT 3 +#define CPU_MAC_UNIT_HSS_CFG_W2_CFG_HSS_L0_LANE_ID_BIT 4 +#define CPU_MAC_UNIT_HSS_CFG_W2_CFG_HSS_L0_PCS2_PMA_PHY_MODE_BIT 22 +#define CPU_MAC_UNIT_HSS_CFG_W2_CFG_HSS_L0_PCS2_PMA_TX_SWING_BIT 31 +#define CPU_MAC_UNIT_HSS_CFG_W2_CFG_HSS_L0_PCS2_PMA_VGA_CTRL_BIT 27 +#define CPU_MAC_UNIT_HSS_CFG_W2_CFG_HSS_L0_PMA_RX_DIV_SEL_BIT 19 +#define CPU_MAC_UNIT_HSS_CFG_W2_CFG_HSS_L0_PMA_TX_CK_SEL_BIT 13 +#define CPU_MAC_UNIT_HSS_CFG_W2_CFG_HSS_L0_RST_N_BIT 0 +#define CPU_MAC_UNIT_HSS_CFG_W2_CFG_HSS_L0_RX_RATE_SEL_BIT 17 +#define CPU_MAC_UNIT_HSS_CFG_W2_CFG_HSS_L0_RX_RST_N_BIT 16 +#define CPU_MAC_UNIT_HSS_CFG_W2_CFG_HSS_L0_TX_RATE_SEL_BIT 11 +#define CPU_MAC_UNIT_HSS_CFG_W2_CFG_HSS_L0_TX_RST_N_BIT 10 +#define CPU_MAC_UNIT_HSS_CFG_W3_CFG_HSS_L0_HWT_FOM_SEL_BIT 19 +#define CPU_MAC_UNIT_HSS_CFG_W3_CFG_HSS_L0_PCS2_PMA_PI_EXT_DAC_BIT20_TO14_BIT 20 +#define CPU_MAC_UNIT_HSS_CFG_W3_CFG_HSS_L0_PCS2_PMA_PI_EXT_DAC_BIT23_TO21_BIT 27 +#define CPU_MAC_UNIT_HSS_CFG_W3_CFG_HSS_L0_PCS2_PMA_TX_EI_BIT 18 +#define CPU_MAC_UNIT_HSS_CFG_W3_CFG_HSS_L0_PCS_EN_ADV_BIT 9 +#define CPU_MAC_UNIT_HSS_CFG_W3_CFG_HSS_L0_PCS_EN_DLY_BIT 8 +#define CPU_MAC_UNIT_HSS_CFG_W3_CFG_HSS_L0_PCS_EN_MAIN_BIT 7 +#define CPU_MAC_UNIT_HSS_CFG_W3_CFG_HSS_L0_PCS_I_SCAN_EN_BIT 6 +#define CPU_MAC_UNIT_HSS_CFG_W3_CFG_HSS_L0_PCS_TAP_ADV_BIT 1 +#define CPU_MAC_UNIT_HSS_CFG_W3_CFG_HSS_L0_PCS_TAP_DLY_BIT 10 +#define CPU_MAC_UNIT_HSS_CFG_W3_CFG_HSS_L0_PCS_TAP_MAIN_BIT 0 +#define CPU_MAC_UNIT_HSS_CFG_W4_CFG_HSS_L0_PCS2_PMA_ITX_PREEMP_BASE_BIT 30 +#define CPU_MAC_UNIT_HSS_CFG_W4_CFG_HSS_L0_PCS2_PMA_MCNT_MAX_VAL_BIT 25 +#define CPU_MAC_UNIT_HSS_CFG_W4_CFG_HSS_L0_PCS2_PMA_PI_FLOOP_STEPS_BIT 23 +#define CPU_MAC_UNIT_HSS_CFG_W4_CFG_HSS_L0_PCS2_PMA_RX_SSC_LH_BIT 22 +#define CPU_MAC_UNIT_HSS_CFG_W4_CFG_HSS_L0_PCS2_PMA_SSC_EN_BIT 21 +#define CPU_MAC_UNIT_HSS_CFG_W4_CFG_HSS_L0_PCS2_PMA_SSC_PI_BW_BIT 17 +#define CPU_MAC_UNIT_HSS_CFG_W4_CFG_HSS_L0_PCS2_PMA_SSC_PI_STEP_BIT 15 +#define CPU_MAC_UNIT_HSS_CFG_W4_CFG_HSS_L0_PCS2_PMA_SSC_RESETB_BIT 14 +#define CPU_MAC_UNIT_HSS_CFG_W4_CFG_HSS_L0_PCS2_PMA_SSC_RTL_CLK_SEL_BIT 13 +#define CPU_MAC_UNIT_HSS_CFG_W4_CFG_HSS_L0_PCS2_PMA_TX_DET_RX_EN_BIT 12 +#define CPU_MAC_UNIT_HSS_CFG_W4_CFG_HSS_L0_PCS2_PMA_TX_DET_RX_STR_BIT 11 +#define CPU_MAC_UNIT_HSS_CFG_W4_CFG_HSS_L0_PCS2_PMANCNT_MAX_VAL_BIT 0 +#define CPU_MAC_UNIT_HSS_CFG_W5_CFG_HSS_L0_PCS2_PMA_EN_PRE_EMPH_BIT 31 +#define CPU_MAC_UNIT_HSS_CFG_W5_CFG_HSS_L0_PCS2_PMA_EQC_FORCE_BIT 27 +#define CPU_MAC_UNIT_HSS_CFG_W5_CFG_HSS_L0_PCS2_PMA_EQR_BYP_BIT 26 +#define CPU_MAC_UNIT_HSS_CFG_W5_CFG_HSS_L0_PCS2_PMA_ISCAN_EXT_DAC_BIT7_BIT 25 +#define CPU_MAC_UNIT_HSS_CFG_W5_CFG_HSS_L0_PCS2_PMA_POWER_CTRL_BIT 0 +#define CPU_MAC_UNIT_HSS_CFG_W6_CFG_HSS_L0_FORCE_SIGNAL_DETECT_BIT 31 +#define CPU_MAC_UNIT_HSS_CFG_W6_CFG_HSS_L0_PCLK_GATING_BIT 7 +#define CPU_MAC_UNIT_HSS_CFG_W6_CFG_HSS_L0_PCS2_PMA_CENTER_SPREADING_BIT 6 +#define CPU_MAC_UNIT_HSS_CFG_W6_CFG_HSS_L0_PCS2_PMA_CTLE_RSTN_BIT 17 +#define CPU_MAC_UNIT_HSS_CFG_W6_CFG_HSS_L0_PCS2_PMA_DIS2ND_ORDER_BIT 5 +#define CPU_MAC_UNIT_HSS_CFG_W6_CFG_HSS_L0_PCS2_PMA_EID_LP_BIT 18 +#define CPU_MAC_UNIT_HSS_CFG_W6_CFG_HSS_L0_PCS2_PMA_EN_DFE_DIG_BIT 4 +#define CPU_MAC_UNIT_HSS_CFG_W6_CFG_HSS_L0_PCS2_PMA_EQ_RES_BIT 0 +#define CPU_MAC_UNIT_HSS_CFG_W6_CFG_HSS_L0_PCS2_PMA_HOLD_DFE_BIT 22 +#define CPU_MAC_UNIT_HSS_CFG_W6_CFG_HSS_L0_PCS2_PMA_ISCAN_SEL_BIT 19 +#define CPU_MAC_UNIT_HSS_CFG_W6_CFG_HSS_L0_PCS2_PMA_PI_HOLD_BIT 20 +#define CPU_MAC_UNIT_HSS_CFG_W6_CFG_HSS_L0_PCS2_PMA_R50_EN_BIT 21 +#define CPU_MAC_UNIT_HSS_CFG_W6_CFG_HSS_L0_PCS2_PMA_TX_MARGIN_BIT 8 +#define CPU_MAC_UNIT_HSS_CFG_W7_CFG_HSS_L0_PCS2_PMA_DLEV_BIT 23 +#define CPU_MAC_UNIT_HSS_CFG_W7_CFG_HSS_L0_PCS2_PMA_DLEV_BYP_BIT 31 +#define CPU_MAC_UNIT_HSS_CFG_W7_CFG_HSS_L0_PCS2_PMA_H1_BIT 0 +#define CPU_MAC_UNIT_HSS_CFG_W7_CFG_HSS_L0_PCS2_PMA_H2_BIT 6 +#define CPU_MAC_UNIT_HSS_CFG_W7_CFG_HSS_L0_PCS2_PMA_H3_BIT 11 +#define CPU_MAC_UNIT_HSS_CFG_W7_CFG_HSS_L0_PCS2_PMA_H4_BIT 15 +#define CPU_MAC_UNIT_HSS_CFG_W7_CFG_HSS_L0_PCS2_PMA_H5_BIT 19 +#define CPU_MAC_UNIT_HSS_CFG_W7_CFG_HSS_L0_PCS2_PMA_H_BYP_BIT 30 +#define CPU_MAC_UNIT_HSS_CFG_W8_CFG_HSS_L1_AUX_RX_CK_SEL_BIT 2 +#define CPU_MAC_UNIT_HSS_CFG_W8_CFG_HSS_L1_AUX_TX_CK_SEL_BIT 1 +#define CPU_MAC_UNIT_HSS_CFG_W8_CFG_HSS_L1_DATA_WIDTH_SEL_BIT 7 +#define CPU_MAC_UNIT_HSS_CFG_W8_CFG_HSS_L1_HWT_MULTI_LANE_MODE_BIT 3 +#define CPU_MAC_UNIT_HSS_CFG_W8_CFG_HSS_L1_LANE_ID_BIT 4 +#define CPU_MAC_UNIT_HSS_CFG_W8_CFG_HSS_L1_PCS2_PMA_PHY_MODE_BIT 22 +#define CPU_MAC_UNIT_HSS_CFG_W8_CFG_HSS_L1_PCS2_PMA_TX_SWING_BIT 31 +#define CPU_MAC_UNIT_HSS_CFG_W8_CFG_HSS_L1_PCS2_PMA_VGA_CTRL_BIT 27 +#define CPU_MAC_UNIT_HSS_CFG_W8_CFG_HSS_L1_PMA_RX_DIV_SEL_BIT 19 +#define CPU_MAC_UNIT_HSS_CFG_W8_CFG_HSS_L1_PMA_TX_CK_SEL_BIT 13 +#define CPU_MAC_UNIT_HSS_CFG_W8_CFG_HSS_L1_RST_N_BIT 0 +#define CPU_MAC_UNIT_HSS_CFG_W8_CFG_HSS_L1_RX_RATE_SEL_BIT 17 +#define CPU_MAC_UNIT_HSS_CFG_W8_CFG_HSS_L1_RX_RST_N_BIT 16 +#define CPU_MAC_UNIT_HSS_CFG_W8_CFG_HSS_L1_TX_RATE_SEL_BIT 11 +#define CPU_MAC_UNIT_HSS_CFG_W8_CFG_HSS_L1_TX_RST_N_BIT 10 +#define CPU_MAC_UNIT_HSS_CFG_W9_CFG_HSS_L1_HWT_FOM_SEL_BIT 19 +#define CPU_MAC_UNIT_HSS_CFG_W9_CFG_HSS_L1_PCS2_PMA_PI_EXT_DAC_BIT20_TO14_BIT 20 +#define CPU_MAC_UNIT_HSS_CFG_W9_CFG_HSS_L1_PCS2_PMA_PI_EXT_DAC_BIT23_TO21_BIT 27 +#define CPU_MAC_UNIT_HSS_CFG_W9_CFG_HSS_L1_PCS2_PMA_TX_EI_BIT 18 +#define CPU_MAC_UNIT_HSS_CFG_W9_CFG_HSS_L1_PCS_EN_ADV_BIT 9 +#define CPU_MAC_UNIT_HSS_CFG_W9_CFG_HSS_L1_PCS_EN_DLY_BIT 8 +#define CPU_MAC_UNIT_HSS_CFG_W9_CFG_HSS_L1_PCS_EN_MAIN_BIT 7 +#define CPU_MAC_UNIT_HSS_CFG_W9_CFG_HSS_L1_PCS_I_SCAN_EN_BIT 6 +#define CPU_MAC_UNIT_HSS_CFG_W9_CFG_HSS_L1_PCS_TAP_ADV_BIT 1 +#define CPU_MAC_UNIT_HSS_CFG_W9_CFG_HSS_L1_PCS_TAP_DLY_BIT 10 +#define CPU_MAC_UNIT_HSS_CFG_W9_CFG_HSS_L1_PCS_TAP_MAIN_BIT 0 +#define CPU_MAC_UNIT_HSS_CFG_W10_CFG_HSS_L1_PCS2_PMA_ITX_PREEMP_BASE_BIT 30 +#define CPU_MAC_UNIT_HSS_CFG_W10_CFG_HSS_L1_PCS2_PMA_MCNT_MAX_VAL_BIT 25 +#define CPU_MAC_UNIT_HSS_CFG_W10_CFG_HSS_L1_PCS2_PMA_PI_FLOOP_STEPS_BIT 23 +#define CPU_MAC_UNIT_HSS_CFG_W10_CFG_HSS_L1_PCS2_PMA_RX_SSC_LH_BIT 22 +#define CPU_MAC_UNIT_HSS_CFG_W10_CFG_HSS_L1_PCS2_PMA_SSC_EN_BIT 21 +#define CPU_MAC_UNIT_HSS_CFG_W10_CFG_HSS_L1_PCS2_PMA_SSC_PI_BW_BIT 17 +#define CPU_MAC_UNIT_HSS_CFG_W10_CFG_HSS_L1_PCS2_PMA_SSC_PI_STEP_BIT 15 +#define CPU_MAC_UNIT_HSS_CFG_W10_CFG_HSS_L1_PCS2_PMA_SSC_RESETB_BIT 14 +#define CPU_MAC_UNIT_HSS_CFG_W10_CFG_HSS_L1_PCS2_PMA_SSC_RTL_CLK_SEL_BIT 13 +#define CPU_MAC_UNIT_HSS_CFG_W10_CFG_HSS_L1_PCS2_PMA_TX_DET_RX_EN_BIT 12 +#define CPU_MAC_UNIT_HSS_CFG_W10_CFG_HSS_L1_PCS2_PMA_TX_DET_RX_STR_BIT 11 +#define CPU_MAC_UNIT_HSS_CFG_W10_CFG_HSS_L1_PCS2_PMANCNT_MAX_VAL_BIT 0 +#define CPU_MAC_UNIT_HSS_CFG_W11_CFG_HSS_L1_PCS2_PMA_EN_PRE_EMPH_BIT 31 +#define CPU_MAC_UNIT_HSS_CFG_W11_CFG_HSS_L1_PCS2_PMA_EQC_FORCE_BIT 27 +#define CPU_MAC_UNIT_HSS_CFG_W11_CFG_HSS_L1_PCS2_PMA_EQR_BYP_BIT 26 +#define CPU_MAC_UNIT_HSS_CFG_W11_CFG_HSS_L1_PCS2_PMA_ISCAN_EXT_DAC_BIT7_BIT 25 +#define CPU_MAC_UNIT_HSS_CFG_W11_CFG_HSS_L1_PCS2_PMA_POWER_CTRL_BIT 0 +#define CPU_MAC_UNIT_HSS_CFG_W12_CFG_HSS_L1_FORCE_SIGNAL_DETECT_BIT 31 +#define CPU_MAC_UNIT_HSS_CFG_W12_CFG_HSS_L1_PCLK_GATING_BIT 7 +#define CPU_MAC_UNIT_HSS_CFG_W12_CFG_HSS_L1_PCS2_PMA_CENTER_SPREADING_BIT 6 +#define CPU_MAC_UNIT_HSS_CFG_W12_CFG_HSS_L1_PCS2_PMA_CTLE_RSTN_BIT 17 +#define CPU_MAC_UNIT_HSS_CFG_W12_CFG_HSS_L1_PCS2_PMA_DIS2ND_ORDER_BIT 5 +#define CPU_MAC_UNIT_HSS_CFG_W12_CFG_HSS_L1_PCS2_PMA_EID_LP_BIT 18 +#define CPU_MAC_UNIT_HSS_CFG_W12_CFG_HSS_L1_PCS2_PMA_EN_DFE_DIG_BIT 4 +#define CPU_MAC_UNIT_HSS_CFG_W12_CFG_HSS_L1_PCS2_PMA_EQ_RES_BIT 0 +#define CPU_MAC_UNIT_HSS_CFG_W12_CFG_HSS_L1_PCS2_PMA_HOLD_DFE_BIT 22 +#define CPU_MAC_UNIT_HSS_CFG_W12_CFG_HSS_L1_PCS2_PMA_ISCAN_SEL_BIT 19 +#define CPU_MAC_UNIT_HSS_CFG_W12_CFG_HSS_L1_PCS2_PMA_PI_HOLD_BIT 20 +#define CPU_MAC_UNIT_HSS_CFG_W12_CFG_HSS_L1_PCS2_PMA_R50_EN_BIT 21 +#define CPU_MAC_UNIT_HSS_CFG_W12_CFG_HSS_L1_PCS2_PMA_TX_MARGIN_BIT 8 +#define CPU_MAC_UNIT_HSS_CFG_W13_CFG_HSS_L1_PCS2_PMA_DLEV_BIT 23 +#define CPU_MAC_UNIT_HSS_CFG_W13_CFG_HSS_L1_PCS2_PMA_DLEV_BYP_BIT 31 +#define CPU_MAC_UNIT_HSS_CFG_W13_CFG_HSS_L1_PCS2_PMA_H1_BIT 0 +#define CPU_MAC_UNIT_HSS_CFG_W13_CFG_HSS_L1_PCS2_PMA_H2_BIT 6 +#define CPU_MAC_UNIT_HSS_CFG_W13_CFG_HSS_L1_PCS2_PMA_H3_BIT 11 +#define CPU_MAC_UNIT_HSS_CFG_W13_CFG_HSS_L1_PCS2_PMA_H4_BIT 15 +#define CPU_MAC_UNIT_HSS_CFG_W13_CFG_HSS_L1_PCS2_PMA_H5_BIT 19 +#define CPU_MAC_UNIT_HSS_CFG_W13_CFG_HSS_L1_PCS2_PMA_H_BYP_BIT 30 + +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_BCLK_RST_N_MASK 0x00000002 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_HWT_BIAS_DN_EN_MASK 0x00002000 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_HWT_BIAS_UP_EN_MASK 0x00004000 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_HWT_CFG_DIV_SEL_MASK 0x000007e0 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_HWT_CK_TREE_PD_MASK 0x20000000 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_HWT_EN_TX_CK_DN_MASK 0x01000000 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_HWT_EN_TX_CK_UP_MASK 0x00800000 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_HWT_IBIAS_PD_MASK 0x04000000 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_HWT_LINK_BUF_EN_MASK 0x00010000 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_HWT_MULTI_LANE_MODE_MASK 0x00001000 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_HWT_PMA_TX_CK_PD_MASK 0x80000000 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_HWT_REFCK_PD_MASK 0x40000000 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_HWT_REFCK_TERM_EN_MASK 0x02000000 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_HWT_RST_TREE_PD_MA_MASK 0x08000000 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_HWT_VCO_DIV_SEL_MASK 0x0000001c +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_HWT_VCO_PD_MASK 0x10000000 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_PCLK_GATING_MASK 0x00008000 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_PCS2_PMA_PHY_MODE_MASK 0x007c0000 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_REXT10_K_MASK 0x00000800 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_CMU0_RST_N_MASK 0x00020000 +#define CPU_MAC_UNIT_HSS_CFG_W0_CFG_HSS_GLB_RST_N_MASK 0x00000001 +#define CPU_MAC_UNIT_HSS_CFG_W1_CFG_HSS_CMU0_HWT_CTRL_LOGIC_PD_MASK 0x10000000 +#define CPU_MAC_UNIT_HSS_CFG_W1_CFG_HSS_CMU0_HWT_EN_DUMMY_MASK 0x20000000 +#define CPU_MAC_UNIT_HSS_CFG_W1_CFG_HSS_CMU0_HWT_PD_DIV64_MASK 0x04000000 +#define CPU_MAC_UNIT_HSS_CFG_W1_CFG_HSS_CMU0_HWT_PD_DIV66_MASK 0x08000000 +#define CPU_MAC_UNIT_HSS_CFG_W1_CFG_HSS_CMU0_HWT_REF_CK_CENTER_SPREAD_MASK 0x02000000 +#define CPU_MAC_UNIT_HSS_CFG_W1_CFG_HSS_CMU0_HWT_REF_CK_MCNT_MAX_VAL_MASK 0x00003e00 +#define CPU_MAC_UNIT_HSS_CFG_W1_CFG_HSS_CMU0_HWT_REF_CK_NCN_MAX_VAL_MASK 0x01ffc000 +#define CPU_MAC_UNIT_HSS_CFG_W1_CFG_HSS_CMU0_HWT_REF_CK_RES_EN_MASK 0x00000004 +#define CPU_MAC_UNIT_HSS_CFG_W1_CFG_HSS_CMU0_HWT_REF_CK_SRC_SEL_MASK 0x00000008 +#define CPU_MAC_UNIT_HSS_CFG_W1_CFG_HSS_CMU0_HWT_REF_CK_SSC_PI_BW_MASK 0x000001c0 +#define CPU_MAC_UNIT_HSS_CFG_W1_CFG_HSS_CMU0_HWT_REF_CK_SSC_PI_STEP_MASK 0x00000030 +#define CPU_MAC_UNIT_HSS_CFG_W1_CFG_HSS_CMU0_HWT_REF_CK_SSC_RESET_N_MASK 0x00000002 +#define CPU_MAC_UNIT_HSS_CFG_W1_CFG_HSS_CMU0_HWT_REF_CK_SSC_RTL_CLK_SEL_MASK 0x00000001 +#define CPU_MAC_UNIT_HSS_CFG_W2_CFG_HSS_L0_AUX_RX_CK_SEL_MASK 0x00000004 +#define CPU_MAC_UNIT_HSS_CFG_W2_CFG_HSS_L0_AUX_TX_CK_SEL_MASK 0x00000002 +#define CPU_MAC_UNIT_HSS_CFG_W2_CFG_HSS_L0_DATA_WIDTH_SEL_MASK 0x00000380 +#define CPU_MAC_UNIT_HSS_CFG_W2_CFG_HSS_L0_HWT_MULTI_LANE_MODE_MASK 0x00000008 +#define CPU_MAC_UNIT_HSS_CFG_W2_CFG_HSS_L0_LANE_ID_MASK 0x00000070 +#define CPU_MAC_UNIT_HSS_CFG_W2_CFG_HSS_L0_PCS2_PMA_PHY_MODE_MASK 0x07c00000 +#define CPU_MAC_UNIT_HSS_CFG_W2_CFG_HSS_L0_PCS2_PMA_TX_SWING_MASK 0x80000000 +#define CPU_MAC_UNIT_HSS_CFG_W2_CFG_HSS_L0_PCS2_PMA_VGA_CTRL_MASK 0x78000000 +#define CPU_MAC_UNIT_HSS_CFG_W2_CFG_HSS_L0_PMA_RX_DIV_SEL_MASK 0x00380000 +#define CPU_MAC_UNIT_HSS_CFG_W2_CFG_HSS_L0_PMA_TX_CK_SEL_MASK 0x0000e000 +#define CPU_MAC_UNIT_HSS_CFG_W2_CFG_HSS_L0_RST_N_MASK 0x00000001 +#define CPU_MAC_UNIT_HSS_CFG_W2_CFG_HSS_L0_RX_RATE_SEL_MASK 0x00060000 +#define CPU_MAC_UNIT_HSS_CFG_W2_CFG_HSS_L0_RX_RST_N_MASK 0x00010000 +#define CPU_MAC_UNIT_HSS_CFG_W2_CFG_HSS_L0_TX_RATE_SEL_MASK 0x00001800 +#define CPU_MAC_UNIT_HSS_CFG_W2_CFG_HSS_L0_TX_RST_N_MASK 0x00000400 +#define CPU_MAC_UNIT_HSS_CFG_W3_CFG_HSS_L0_HWT_FOM_SEL_MASK 0x00080000 +#define CPU_MAC_UNIT_HSS_CFG_W3_CFG_HSS_L0_PCS2_PMA_PI_EXT_DAC_BIT20_TO14_MASK 0x07f00000 +#define CPU_MAC_UNIT_HSS_CFG_W3_CFG_HSS_L0_PCS2_PMA_PI_EXT_DAC_BIT23_TO21_MASK 0x38000000 +#define CPU_MAC_UNIT_HSS_CFG_W3_CFG_HSS_L0_PCS2_PMA_TX_EI_MASK 0x00040000 +#define CPU_MAC_UNIT_HSS_CFG_W3_CFG_HSS_L0_PCS_EN_ADV_MASK 0x00000200 +#define CPU_MAC_UNIT_HSS_CFG_W3_CFG_HSS_L0_PCS_EN_DLY_MASK 0x00000100 +#define CPU_MAC_UNIT_HSS_CFG_W3_CFG_HSS_L0_PCS_EN_MAIN_MASK 0x00000080 +#define CPU_MAC_UNIT_HSS_CFG_W3_CFG_HSS_L0_PCS_I_SCAN_EN_MASK 0x00000040 +#define CPU_MAC_UNIT_HSS_CFG_W3_CFG_HSS_L0_PCS_TAP_ADV_MASK 0x0000003e +#define CPU_MAC_UNIT_HSS_CFG_W3_CFG_HSS_L0_PCS_TAP_DLY_MASK 0x00007c00 +#define CPU_MAC_UNIT_HSS_CFG_W3_CFG_HSS_L0_PCS_TAP_MAIN_MASK 0x00000001 +#define CPU_MAC_UNIT_HSS_CFG_W4_CFG_HSS_L0_PCS2_PMA_ITX_PREEMP_BASE_MASK 0xc0000000 +#define CPU_MAC_UNIT_HSS_CFG_W4_CFG_HSS_L0_PCS2_PMA_MCNT_MAX_VAL_MASK 0x3e000000 +#define CPU_MAC_UNIT_HSS_CFG_W4_CFG_HSS_L0_PCS2_PMA_PI_FLOOP_STEPS_MASK 0x01800000 +#define CPU_MAC_UNIT_HSS_CFG_W4_CFG_HSS_L0_PCS2_PMA_RX_SSC_LH_MASK 0x00400000 +#define CPU_MAC_UNIT_HSS_CFG_W4_CFG_HSS_L0_PCS2_PMA_SSC_EN_MASK 0x00200000 +#define CPU_MAC_UNIT_HSS_CFG_W4_CFG_HSS_L0_PCS2_PMA_SSC_PI_BW_MASK 0x001e0000 +#define CPU_MAC_UNIT_HSS_CFG_W4_CFG_HSS_L0_PCS2_PMA_SSC_PI_STEP_MASK 0x00018000 +#define CPU_MAC_UNIT_HSS_CFG_W4_CFG_HSS_L0_PCS2_PMA_SSC_RESETB_MASK 0x00004000 +#define CPU_MAC_UNIT_HSS_CFG_W4_CFG_HSS_L0_PCS2_PMA_SSC_RTL_CLK_SEL_MASK 0x00002000 +#define CPU_MAC_UNIT_HSS_CFG_W4_CFG_HSS_L0_PCS2_PMA_TX_DET_RX_EN_MASK 0x00001000 +#define CPU_MAC_UNIT_HSS_CFG_W4_CFG_HSS_L0_PCS2_PMA_TX_DET_RX_STR_MASK 0x00000800 +#define CPU_MAC_UNIT_HSS_CFG_W4_CFG_HSS_L0_PCS2_PMANCNT_MAX_VAL_MASK 0x000007ff +#define CPU_MAC_UNIT_HSS_CFG_W5_CFG_HSS_L0_PCS2_PMA_EN_PRE_EMPH_MASK 0x80000000 +#define CPU_MAC_UNIT_HSS_CFG_W5_CFG_HSS_L0_PCS2_PMA_EQC_FORCE_MASK 0x78000000 +#define CPU_MAC_UNIT_HSS_CFG_W5_CFG_HSS_L0_PCS2_PMA_EQR_BYP_MASK 0x04000000 +#define CPU_MAC_UNIT_HSS_CFG_W5_CFG_HSS_L0_PCS2_PMA_ISCAN_EXT_DAC_BIT7_MASK 0x02000000 +#define CPU_MAC_UNIT_HSS_CFG_W5_CFG_HSS_L0_PCS2_PMA_POWER_CTRL_MASK 0x01ffffff +#define CPU_MAC_UNIT_HSS_CFG_W6_CFG_HSS_L0_FORCE_SIGNAL_DETECT_MASK 0x80000000 +#define CPU_MAC_UNIT_HSS_CFG_W6_CFG_HSS_L0_PCLK_GATING_MASK 0x00000080 +#define CPU_MAC_UNIT_HSS_CFG_W6_CFG_HSS_L0_PCS2_PMA_CENTER_SPREADING_MASK 0x00000040 +#define CPU_MAC_UNIT_HSS_CFG_W6_CFG_HSS_L0_PCS2_PMA_CTLE_RSTN_MASK 0x00020000 +#define CPU_MAC_UNIT_HSS_CFG_W6_CFG_HSS_L0_PCS2_PMA_DIS2ND_ORDER_MASK 0x00000020 +#define CPU_MAC_UNIT_HSS_CFG_W6_CFG_HSS_L0_PCS2_PMA_EID_LP_MASK 0x00040000 +#define CPU_MAC_UNIT_HSS_CFG_W6_CFG_HSS_L0_PCS2_PMA_EN_DFE_DIG_MASK 0x00000010 +#define CPU_MAC_UNIT_HSS_CFG_W6_CFG_HSS_L0_PCS2_PMA_EQ_RES_MASK 0x0000000f +#define CPU_MAC_UNIT_HSS_CFG_W6_CFG_HSS_L0_PCS2_PMA_HOLD_DFE_MASK 0x00400000 +#define CPU_MAC_UNIT_HSS_CFG_W6_CFG_HSS_L0_PCS2_PMA_ISCAN_SEL_MASK 0x00080000 +#define CPU_MAC_UNIT_HSS_CFG_W6_CFG_HSS_L0_PCS2_PMA_PI_HOLD_MASK 0x00100000 +#define CPU_MAC_UNIT_HSS_CFG_W6_CFG_HSS_L0_PCS2_PMA_R50_EN_MASK 0x00200000 +#define CPU_MAC_UNIT_HSS_CFG_W6_CFG_HSS_L0_PCS2_PMA_TX_MARGIN_MASK 0x0001ff00 +#define CPU_MAC_UNIT_HSS_CFG_W7_CFG_HSS_L0_PCS2_PMA_DLEV_MASK 0x3f800000 +#define CPU_MAC_UNIT_HSS_CFG_W7_CFG_HSS_L0_PCS2_PMA_DLEV_BYP_MASK 0x80000000 +#define CPU_MAC_UNIT_HSS_CFG_W7_CFG_HSS_L0_PCS2_PMA_H1_MASK 0x0000003f +#define CPU_MAC_UNIT_HSS_CFG_W7_CFG_HSS_L0_PCS2_PMA_H2_MASK 0x000007c0 +#define CPU_MAC_UNIT_HSS_CFG_W7_CFG_HSS_L0_PCS2_PMA_H3_MASK 0x00007800 +#define CPU_MAC_UNIT_HSS_CFG_W7_CFG_HSS_L0_PCS2_PMA_H4_MASK 0x00078000 +#define CPU_MAC_UNIT_HSS_CFG_W7_CFG_HSS_L0_PCS2_PMA_H5_MASK 0x00780000 +#define CPU_MAC_UNIT_HSS_CFG_W7_CFG_HSS_L0_PCS2_PMA_H_BYP_MASK 0x40000000 +#define CPU_MAC_UNIT_HSS_CFG_W8_CFG_HSS_L1_AUX_RX_CK_SEL_MASK 0x00000004 +#define CPU_MAC_UNIT_HSS_CFG_W8_CFG_HSS_L1_AUX_TX_CK_SEL_MASK 0x00000002 +#define CPU_MAC_UNIT_HSS_CFG_W8_CFG_HSS_L1_DATA_WIDTH_SEL_MASK 0x00000380 +#define CPU_MAC_UNIT_HSS_CFG_W8_CFG_HSS_L1_HWT_MULTI_LANE_MODE_MASK 0x00000008 +#define CPU_MAC_UNIT_HSS_CFG_W8_CFG_HSS_L1_LANE_ID_MASK 0x00000070 +#define CPU_MAC_UNIT_HSS_CFG_W8_CFG_HSS_L1_PCS2_PMA_PHY_MODE_MASK 0x07c00000 +#define CPU_MAC_UNIT_HSS_CFG_W8_CFG_HSS_L1_PCS2_PMA_TX_SWING_MASK 0x80000000 +#define CPU_MAC_UNIT_HSS_CFG_W8_CFG_HSS_L1_PCS2_PMA_VGA_CTRL_MASK 0x78000000 +#define CPU_MAC_UNIT_HSS_CFG_W8_CFG_HSS_L1_PMA_RX_DIV_SEL_MASK 0x00380000 +#define CPU_MAC_UNIT_HSS_CFG_W8_CFG_HSS_L1_PMA_TX_CK_SEL_MASK 0x0000e000 +#define CPU_MAC_UNIT_HSS_CFG_W8_CFG_HSS_L1_RST_N_MASK 0x00000001 +#define CPU_MAC_UNIT_HSS_CFG_W8_CFG_HSS_L1_RX_RATE_SEL_MASK 0x00060000 +#define CPU_MAC_UNIT_HSS_CFG_W8_CFG_HSS_L1_RX_RST_N_MASK 0x00010000 +#define CPU_MAC_UNIT_HSS_CFG_W8_CFG_HSS_L1_TX_RATE_SEL_MASK 0x00001800 +#define CPU_MAC_UNIT_HSS_CFG_W8_CFG_HSS_L1_TX_RST_N_MASK 0x00000400 +#define CPU_MAC_UNIT_HSS_CFG_W9_CFG_HSS_L1_HWT_FOM_SEL_MASK 0x00080000 +#define CPU_MAC_UNIT_HSS_CFG_W9_CFG_HSS_L1_PCS2_PMA_PI_EXT_DAC_BIT20_TO14_MASK 0x07f00000 +#define CPU_MAC_UNIT_HSS_CFG_W9_CFG_HSS_L1_PCS2_PMA_PI_EXT_DAC_BIT23_TO21_MASK 0x38000000 +#define CPU_MAC_UNIT_HSS_CFG_W9_CFG_HSS_L1_PCS2_PMA_TX_EI_MASK 0x00040000 +#define CPU_MAC_UNIT_HSS_CFG_W9_CFG_HSS_L1_PCS_EN_ADV_MASK 0x00000200 +#define CPU_MAC_UNIT_HSS_CFG_W9_CFG_HSS_L1_PCS_EN_DLY_MASK 0x00000100 +#define CPU_MAC_UNIT_HSS_CFG_W9_CFG_HSS_L1_PCS_EN_MAIN_MASK 0x00000080 +#define CPU_MAC_UNIT_HSS_CFG_W9_CFG_HSS_L1_PCS_I_SCAN_EN_MASK 0x00000040 +#define CPU_MAC_UNIT_HSS_CFG_W9_CFG_HSS_L1_PCS_TAP_ADV_MASK 0x0000003e +#define CPU_MAC_UNIT_HSS_CFG_W9_CFG_HSS_L1_PCS_TAP_DLY_MASK 0x00007c00 +#define CPU_MAC_UNIT_HSS_CFG_W9_CFG_HSS_L1_PCS_TAP_MAIN_MASK 0x00000001 +#define CPU_MAC_UNIT_HSS_CFG_W10_CFG_HSS_L1_PCS2_PMA_ITX_PREEMP_BASE_MASK 0xc0000000 +#define CPU_MAC_UNIT_HSS_CFG_W10_CFG_HSS_L1_PCS2_PMA_MCNT_MAX_VAL_MASK 0x3e000000 +#define CPU_MAC_UNIT_HSS_CFG_W10_CFG_HSS_L1_PCS2_PMA_PI_FLOOP_STEPS_MASK 0x01800000 +#define CPU_MAC_UNIT_HSS_CFG_W10_CFG_HSS_L1_PCS2_PMA_RX_SSC_LH_MASK 0x00400000 +#define CPU_MAC_UNIT_HSS_CFG_W10_CFG_HSS_L1_PCS2_PMA_SSC_EN_MASK 0x00200000 +#define CPU_MAC_UNIT_HSS_CFG_W10_CFG_HSS_L1_PCS2_PMA_SSC_PI_BW_MASK 0x001e0000 +#define CPU_MAC_UNIT_HSS_CFG_W10_CFG_HSS_L1_PCS2_PMA_SSC_PI_STEP_MASK 0x00018000 +#define CPU_MAC_UNIT_HSS_CFG_W10_CFG_HSS_L1_PCS2_PMA_SSC_RESETB_MASK 0x00004000 +#define CPU_MAC_UNIT_HSS_CFG_W10_CFG_HSS_L1_PCS2_PMA_SSC_RTL_CLK_SEL_MASK 0x00002000 +#define CPU_MAC_UNIT_HSS_CFG_W10_CFG_HSS_L1_PCS2_PMA_TX_DET_RX_EN_MASK 0x00001000 +#define CPU_MAC_UNIT_HSS_CFG_W10_CFG_HSS_L1_PCS2_PMA_TX_DET_RX_STR_MASK 0x00000800 +#define CPU_MAC_UNIT_HSS_CFG_W10_CFG_HSS_L1_PCS2_PMANCNT_MAX_VAL_MASK 0x000007ff +#define CPU_MAC_UNIT_HSS_CFG_W11_CFG_HSS_L1_PCS2_PMA_EN_PRE_EMPH_MASK 0x80000000 +#define CPU_MAC_UNIT_HSS_CFG_W11_CFG_HSS_L1_PCS2_PMA_EQC_FORCE_MASK 0x78000000 +#define CPU_MAC_UNIT_HSS_CFG_W11_CFG_HSS_L1_PCS2_PMA_EQR_BYP_MASK 0x04000000 +#define CPU_MAC_UNIT_HSS_CFG_W11_CFG_HSS_L1_PCS2_PMA_ISCAN_EXT_DAC_BIT7_MASK 0x02000000 +#define CPU_MAC_UNIT_HSS_CFG_W11_CFG_HSS_L1_PCS2_PMA_POWER_CTRL_MASK 0x01ffffff +#define CPU_MAC_UNIT_HSS_CFG_W12_CFG_HSS_L1_FORCE_SIGNAL_DETECT_MASK 0x80000000 +#define CPU_MAC_UNIT_HSS_CFG_W12_CFG_HSS_L1_PCLK_GATING_MASK 0x00000080 +#define CPU_MAC_UNIT_HSS_CFG_W12_CFG_HSS_L1_PCS2_PMA_CENTER_SPREADING_MASK 0x00000040 +#define CPU_MAC_UNIT_HSS_CFG_W12_CFG_HSS_L1_PCS2_PMA_CTLE_RSTN_MASK 0x00020000 +#define CPU_MAC_UNIT_HSS_CFG_W12_CFG_HSS_L1_PCS2_PMA_DIS2ND_ORDER_MASK 0x00000020 +#define CPU_MAC_UNIT_HSS_CFG_W12_CFG_HSS_L1_PCS2_PMA_EID_LP_MASK 0x00040000 +#define CPU_MAC_UNIT_HSS_CFG_W12_CFG_HSS_L1_PCS2_PMA_EN_DFE_DIG_MASK 0x00000010 +#define CPU_MAC_UNIT_HSS_CFG_W12_CFG_HSS_L1_PCS2_PMA_EQ_RES_MASK 0x0000000f +#define CPU_MAC_UNIT_HSS_CFG_W12_CFG_HSS_L1_PCS2_PMA_HOLD_DFE_MASK 0x00400000 +#define CPU_MAC_UNIT_HSS_CFG_W12_CFG_HSS_L1_PCS2_PMA_ISCAN_SEL_MASK 0x00080000 +#define CPU_MAC_UNIT_HSS_CFG_W12_CFG_HSS_L1_PCS2_PMA_PI_HOLD_MASK 0x00100000 +#define CPU_MAC_UNIT_HSS_CFG_W12_CFG_HSS_L1_PCS2_PMA_R50_EN_MASK 0x00200000 +#define CPU_MAC_UNIT_HSS_CFG_W12_CFG_HSS_L1_PCS2_PMA_TX_MARGIN_MASK 0x0001ff00 +#define CPU_MAC_UNIT_HSS_CFG_W13_CFG_HSS_L1_PCS2_PMA_DLEV_MASK 0x3f800000 +#define CPU_MAC_UNIT_HSS_CFG_W13_CFG_HSS_L1_PCS2_PMA_DLEV_BYP_MASK 0x80000000 +#define CPU_MAC_UNIT_HSS_CFG_W13_CFG_HSS_L1_PCS2_PMA_H1_MASK 0x0000003f +#define CPU_MAC_UNIT_HSS_CFG_W13_CFG_HSS_L1_PCS2_PMA_H2_MASK 0x000007c0 +#define CPU_MAC_UNIT_HSS_CFG_W13_CFG_HSS_L1_PCS2_PMA_H3_MASK 0x00007800 +#define CPU_MAC_UNIT_HSS_CFG_W13_CFG_HSS_L1_PCS2_PMA_H4_MASK 0x00078000 +#define CPU_MAC_UNIT_HSS_CFG_W13_CFG_HSS_L1_PCS2_PMA_H5_MASK 0x00780000 +#define CPU_MAC_UNIT_HSS_CFG_W13_CFG_HSS_L1_PCS2_PMA_H_BYP_MASK 0x40000000 +/* cpu_mac_unit_ip_cam_cfg Definition */ +#define CPU_MAC_UNIT_IP_CAM_CFG_W0_CFG_IP_CAM_VALUE0_31_0 BIT(0) +#define CPU_MAC_UNIT_IP_CAM_CFG_W1_CFG_IP_CAM_VALUE0_63_32 BIT(0) +#define CPU_MAC_UNIT_IP_CAM_CFG_W2_CFG_IP_CAM_VALUE0_95_64 BIT(0) +#define CPU_MAC_UNIT_IP_CAM_CFG_W3_CFG_IP_CAM_VALUE0_127_96 BIT(0) +#define CPU_MAC_UNIT_IP_CAM_CFG_W4_CFG_IP_CAM_VALUE1_31_0 BIT(0) +#define CPU_MAC_UNIT_IP_CAM_CFG_W5_CFG_IP_CAM_VALUE1_63_32 BIT(0) +#define CPU_MAC_UNIT_IP_CAM_CFG_W6_CFG_IP_CAM_VALUE1_95_64 BIT(0) +#define CPU_MAC_UNIT_IP_CAM_CFG_W7_CFG_IP_CAM_VALUE1_127_96 BIT(0) +#define CPU_MAC_UNIT_IP_CAM_CFG_W8_CFG_IP_CAM_VALUE2_31_0 BIT(0) +#define CPU_MAC_UNIT_IP_CAM_CFG_W9_CFG_IP_CAM_VALUE2_63_32 BIT(0) +#define CPU_MAC_UNIT_IP_CAM_CFG_W10_CFG_IP_CAM_VALUE2_95_64 BIT(0) +#define CPU_MAC_UNIT_IP_CAM_CFG_W11_CFG_IP_CAM_VALUE2_127_96 BIT(0) +#define CPU_MAC_UNIT_IP_CAM_CFG_W12_CFG_IP_CAM_VALUE3_31_0 BIT(0) +#define CPU_MAC_UNIT_IP_CAM_CFG_W13_CFG_IP_CAM_VALUE3_63_32 BIT(0) +#define CPU_MAC_UNIT_IP_CAM_CFG_W14_CFG_IP_CAM_VALUE3_95_64 BIT(0) +#define CPU_MAC_UNIT_IP_CAM_CFG_W15_CFG_IP_CAM_VALUE3_127_96 BIT(0) +#define CPU_MAC_UNIT_IP_CAM_CFG_W16_CFG_IP_CAM_MASK0_31_0 BIT(0) +#define CPU_MAC_UNIT_IP_CAM_CFG_W17_CFG_IP_CAM_MASK0_63_32 BIT(0) +#define CPU_MAC_UNIT_IP_CAM_CFG_W18_CFG_IP_CAM_MASK0_95_64 BIT(0) +#define CPU_MAC_UNIT_IP_CAM_CFG_W19_CFG_IP_CAM_MASK0_127_96 BIT(0) +#define CPU_MAC_UNIT_IP_CAM_CFG_W20_CFG_IP_CAM_MASK1_31_0 BIT(0) +#define CPU_MAC_UNIT_IP_CAM_CFG_W21_CFG_IP_CAM_MASK1_63_32 BIT(0) +#define CPU_MAC_UNIT_IP_CAM_CFG_W22_CFG_IP_CAM_MASK1_95_64 BIT(0) +#define CPU_MAC_UNIT_IP_CAM_CFG_W23_CFG_IP_CAM_MASK1_127_96 BIT(0) +#define CPU_MAC_UNIT_IP_CAM_CFG_W24_CFG_IP_CAM_MASK2_31_0 BIT(0) +#define CPU_MAC_UNIT_IP_CAM_CFG_W25_CFG_IP_CAM_MASK2_63_32 BIT(0) +#define CPU_MAC_UNIT_IP_CAM_CFG_W26_CFG_IP_CAM_MASK2_95_64 BIT(0) +#define CPU_MAC_UNIT_IP_CAM_CFG_W27_CFG_IP_CAM_MASK2_127_96 BIT(0) +#define CPU_MAC_UNIT_IP_CAM_CFG_W28_CFG_IP_CAM_MASK3_31_0 BIT(0) +#define CPU_MAC_UNIT_IP_CAM_CFG_W29_CFG_IP_CAM_MASK3_63_32 BIT(0) +#define CPU_MAC_UNIT_IP_CAM_CFG_W30_CFG_IP_CAM_MASK3_95_64 BIT(0) +#define CPU_MAC_UNIT_IP_CAM_CFG_W31_CFG_IP_CAM_MASK3_127_96 BIT(0) + +#define CPU_MAC_UNIT_IP_CAM_CFG_W0_CFG_IP_CAM_VALUE0_31_0_MASK 0x00000001 +#define CPU_MAC_UNIT_IP_CAM_CFG_W1_CFG_IP_CAM_VALUE0_63_32_MASK 0x00000001 +#define CPU_MAC_UNIT_IP_CAM_CFG_W2_CFG_IP_CAM_VALUE0_95_64_MASK 0x00000001 +#define CPU_MAC_UNIT_IP_CAM_CFG_W3_CFG_IP_CAM_VALUE0_127_96_MASK 0x00000001 +#define CPU_MAC_UNIT_IP_CAM_CFG_W4_CFG_IP_CAM_VALUE1_31_0_MASK 0x00000001 +#define CPU_MAC_UNIT_IP_CAM_CFG_W5_CFG_IP_CAM_VALUE1_63_32_MASK 0x00000001 +#define CPU_MAC_UNIT_IP_CAM_CFG_W6_CFG_IP_CAM_VALUE1_95_64_MASK 0x00000001 +#define CPU_MAC_UNIT_IP_CAM_CFG_W7_CFG_IP_CAM_VALUE1_127_96_MASK 0x00000001 +#define CPU_MAC_UNIT_IP_CAM_CFG_W8_CFG_IP_CAM_VALUE2_31_0_MASK 0x00000001 +#define CPU_MAC_UNIT_IP_CAM_CFG_W9_CFG_IP_CAM_VALUE2_63_32_MASK 0x00000001 +#define CPU_MAC_UNIT_IP_CAM_CFG_W10_CFG_IP_CAM_VALUE2_95_64_MASK 0x00000001 +#define CPU_MAC_UNIT_IP_CAM_CFG_W11_CFG_IP_CAM_VALUE2_127_96_MASK 0x00000001 +#define CPU_MAC_UNIT_IP_CAM_CFG_W12_CFG_IP_CAM_VALUE3_31_0_MASK 0x00000001 +#define CPU_MAC_UNIT_IP_CAM_CFG_W13_CFG_IP_CAM_VALUE3_63_32_MASK 0x00000001 +#define CPU_MAC_UNIT_IP_CAM_CFG_W14_CFG_IP_CAM_VALUE3_95_64_MASK 0x00000001 +#define CPU_MAC_UNIT_IP_CAM_CFG_W15_CFG_IP_CAM_VALUE3_127_96_MASK 0x00000001 +#define CPU_MAC_UNIT_IP_CAM_CFG_W16_CFG_IP_CAM_MASK0_31_0_MASK 0x00000001 +#define CPU_MAC_UNIT_IP_CAM_CFG_W17_CFG_IP_CAM_MASK0_63_32_MASK 0x00000001 +#define CPU_MAC_UNIT_IP_CAM_CFG_W18_CFG_IP_CAM_MASK0_95_64_MASK 0x00000001 +#define CPU_MAC_UNIT_IP_CAM_CFG_W19_CFG_IP_CAM_MASK0_127_96_MASK 0x00000001 +#define CPU_MAC_UNIT_IP_CAM_CFG_W20_CFG_IP_CAM_MASK1_31_0_MASK 0x00000001 +#define CPU_MAC_UNIT_IP_CAM_CFG_W21_CFG_IP_CAM_MASK1_63_32_MASK 0x00000001 +#define CPU_MAC_UNIT_IP_CAM_CFG_W22_CFG_IP_CAM_MASK1_95_64_MASK 0x00000001 +#define CPU_MAC_UNIT_IP_CAM_CFG_W23_CFG_IP_CAM_MASK1_127_96_MASK 0x00000001 +#define CPU_MAC_UNIT_IP_CAM_CFG_W24_CFG_IP_CAM_MASK2_31_0_MASK 0x00000001 +#define CPU_MAC_UNIT_IP_CAM_CFG_W25_CFG_IP_CAM_MASK2_63_32_MASK 0x00000001 +#define CPU_MAC_UNIT_IP_CAM_CFG_W26_CFG_IP_CAM_MASK2_95_64_MASK 0x00000001 +#define CPU_MAC_UNIT_IP_CAM_CFG_W27_CFG_IP_CAM_MASK2_127_96_MASK 0x00000001 +#define CPU_MAC_UNIT_IP_CAM_CFG_W28_CFG_IP_CAM_MASK3_31_0_MASK 0x00000001 +#define CPU_MAC_UNIT_IP_CAM_CFG_W29_CFG_IP_CAM_MASK3_63_32_MASK 0x00000001 +#define CPU_MAC_UNIT_IP_CAM_CFG_W30_CFG_IP_CAM_MASK3_95_64_MASK 0x00000001 +#define CPU_MAC_UNIT_IP_CAM_CFG_W31_CFG_IP_CAM_MASK3_127_96_MASK 0x00000001 + +/* cpu_mac_unit_mac_cam_cfg Definition */ +#define CPU_MAC_UNIT_MAC_CAM_CFG_W0_CFG_MAC_CAM_VALUE0_31_0 BIT(0) +#define CPU_MAC_UNIT_MAC_CAM_CFG_W1_CFG_MAC_CAM_VALUE0_47_32 BIT(0) +#define CPU_MAC_UNIT_MAC_CAM_CFG_W2_CFG_MAC_CAM_VALUE1_31_0 BIT(0) +#define CPU_MAC_UNIT_MAC_CAM_CFG_W3_CFG_MAC_CAM_VALUE1_47_32 BIT(0) +#define CPU_MAC_UNIT_MAC_CAM_CFG_W4_CFG_MAC_CAM_VALUE2_31_0 BIT(0) +#define CPU_MAC_UNIT_MAC_CAM_CFG_W5_CFG_MAC_CAM_VALUE2_47_32 BIT(0) +#define CPU_MAC_UNIT_MAC_CAM_CFG_W6_CFG_MAC_CAM_VALUE3_31_0 BIT(0) +#define CPU_MAC_UNIT_MAC_CAM_CFG_W7_CFG_MAC_CAM_VALUE3_47_32 BIT(0) +#define CPU_MAC_UNIT_MAC_CAM_CFG_W8_CFG_MAC_CAM_VALUE4_31_0 BIT(0) +#define CPU_MAC_UNIT_MAC_CAM_CFG_W9_CFG_MAC_CAM_VALUE4_47_32 BIT(0) +#define CPU_MAC_UNIT_MAC_CAM_CFG_W10_CFG_MAC_CAM_VALUE5_31_0 BIT(0) +#define CPU_MAC_UNIT_MAC_CAM_CFG_W11_CFG_MAC_CAM_VALUE5_47_32 BIT(0) +#define CPU_MAC_UNIT_MAC_CAM_CFG_W12_CFG_MAC_CAM_VALUE6_31_0 BIT(0) +#define CPU_MAC_UNIT_MAC_CAM_CFG_W13_CFG_MAC_CAM_VALUE6_47_32 BIT(0) +#define CPU_MAC_UNIT_MAC_CAM_CFG_W14_CFG_MAC_CAM_VALUE7_31_0 BIT(0) +#define CPU_MAC_UNIT_MAC_CAM_CFG_W15_CFG_MAC_CAM_VALUE7_47_32 BIT(0) +#define CPU_MAC_UNIT_MAC_CAM_CFG_W16_CFG_MAC_CAM_MASK0_31_0 BIT(0) +#define CPU_MAC_UNIT_MAC_CAM_CFG_W17_CFG_MAC_CAM_MASK0_47_32 BIT(0) +#define CPU_MAC_UNIT_MAC_CAM_CFG_W18_CFG_MAC_CAM_MASK1_31_0 BIT(0) +#define CPU_MAC_UNIT_MAC_CAM_CFG_W19_CFG_MAC_CAM_MASK1_47_32 BIT(0) +#define CPU_MAC_UNIT_MAC_CAM_CFG_W20_CFG_MAC_CAM_MASK2_31_0 BIT(0) +#define CPU_MAC_UNIT_MAC_CAM_CFG_W21_CFG_MAC_CAM_MASK2_47_32 BIT(0) +#define CPU_MAC_UNIT_MAC_CAM_CFG_W22_CFG_MAC_CAM_MASK3_31_0 BIT(0) +#define CPU_MAC_UNIT_MAC_CAM_CFG_W23_CFG_MAC_CAM_MASK3_47_32 BIT(0) +#define CPU_MAC_UNIT_MAC_CAM_CFG_W24_CFG_MAC_CAM_MASK4_31_0 BIT(0) +#define CPU_MAC_UNIT_MAC_CAM_CFG_W25_CFG_MAC_CAM_MASK4_47_32 BIT(0) +#define CPU_MAC_UNIT_MAC_CAM_CFG_W26_CFG_MAC_CAM_MASK5_31_0 BIT(0) +#define CPU_MAC_UNIT_MAC_CAM_CFG_W27_CFG_MAC_CAM_MASK5_47_32 BIT(0) +#define CPU_MAC_UNIT_MAC_CAM_CFG_W28_CFG_MAC_CAM_MASK6_31_0 BIT(0) +#define CPU_MAC_UNIT_MAC_CAM_CFG_W29_CFG_MAC_CAM_MASK6_47_32 BIT(0) +#define CPU_MAC_UNIT_MAC_CAM_CFG_W30_CFG_MAC_CAM_MASK7_31_0 BIT(0) +#define CPU_MAC_UNIT_MAC_CAM_CFG_W31_CFG_MAC_CAM_MASK7_47_32 BIT(0) + +#define CPU_MAC_UNIT_MAC_CAM_CFG_W0_CFG_MAC_CAM_VALUE0_31_0_MASK 0x00000001 +#define CPU_MAC_UNIT_MAC_CAM_CFG_W1_CFG_MAC_CAM_VALUE0_47_32_MASK 0x00000001 +#define CPU_MAC_UNIT_MAC_CAM_CFG_W2_CFG_MAC_CAM_VALUE1_31_0_MASK 0x00000001 +#define CPU_MAC_UNIT_MAC_CAM_CFG_W3_CFG_MAC_CAM_VALUE1_47_32_MASK 0x00000001 +#define CPU_MAC_UNIT_MAC_CAM_CFG_W4_CFG_MAC_CAM_VALUE2_31_0_MASK 0x00000001 +#define CPU_MAC_UNIT_MAC_CAM_CFG_W5_CFG_MAC_CAM_VALUE2_47_32_MASK 0x00000001 +#define CPU_MAC_UNIT_MAC_CAM_CFG_W6_CFG_MAC_CAM_VALUE3_31_0_MASK 0x00000001 +#define CPU_MAC_UNIT_MAC_CAM_CFG_W7_CFG_MAC_CAM_VALUE3_47_32_MASK 0x00000001 +#define CPU_MAC_UNIT_MAC_CAM_CFG_W8_CFG_MAC_CAM_VALUE4_31_0_MASK 0x00000001 +#define CPU_MAC_UNIT_MAC_CAM_CFG_W9_CFG_MAC_CAM_VALUE4_47_32_MASK 0x00000001 +#define CPU_MAC_UNIT_MAC_CAM_CFG_W10_CFG_MAC_CAM_VALUE5_31_0_MASK 0x00000001 +#define CPU_MAC_UNIT_MAC_CAM_CFG_W11_CFG_MAC_CAM_VALUE5_47_32_MASK 0x00000001 +#define CPU_MAC_UNIT_MAC_CAM_CFG_W12_CFG_MAC_CAM_VALUE6_31_0_MASK 0x00000001 +#define CPU_MAC_UNIT_MAC_CAM_CFG_W13_CFG_MAC_CAM_VALUE6_47_32_MASK 0x00000001 +#define CPU_MAC_UNIT_MAC_CAM_CFG_W14_CFG_MAC_CAM_VALUE7_31_0_MASK 0x00000001 +#define CPU_MAC_UNIT_MAC_CAM_CFG_W15_CFG_MAC_CAM_VALUE7_47_32_MASK 0x00000001 +#define CPU_MAC_UNIT_MAC_CAM_CFG_W16_CFG_MAC_CAM_MASK0_31_0_MASK 0x00000001 +#define CPU_MAC_UNIT_MAC_CAM_CFG_W17_CFG_MAC_CAM_MASK0_47_32_MASK 0x00000001 +#define CPU_MAC_UNIT_MAC_CAM_CFG_W18_CFG_MAC_CAM_MASK1_31_0_MASK 0x00000001 +#define CPU_MAC_UNIT_MAC_CAM_CFG_W19_CFG_MAC_CAM_MASK1_47_32_MASK 0x00000001 +#define CPU_MAC_UNIT_MAC_CAM_CFG_W20_CFG_MAC_CAM_MASK2_31_0_MASK 0x00000001 +#define CPU_MAC_UNIT_MAC_CAM_CFG_W21_CFG_MAC_CAM_MASK2_47_32_MASK 0x00000001 +#define CPU_MAC_UNIT_MAC_CAM_CFG_W22_CFG_MAC_CAM_MASK3_31_0_MASK 0x00000001 +#define CPU_MAC_UNIT_MAC_CAM_CFG_W23_CFG_MAC_CAM_MASK3_47_32_MASK 0x00000001 +#define CPU_MAC_UNIT_MAC_CAM_CFG_W24_CFG_MAC_CAM_MASK4_31_0_MASK 0x00000001 +#define CPU_MAC_UNIT_MAC_CAM_CFG_W25_CFG_MAC_CAM_MASK4_47_32_MASK 0x00000001 +#define CPU_MAC_UNIT_MAC_CAM_CFG_W26_CFG_MAC_CAM_MASK5_31_0_MASK 0x00000001 +#define CPU_MAC_UNIT_MAC_CAM_CFG_W27_CFG_MAC_CAM_MASK5_47_32_MASK 0x00000001 +#define CPU_MAC_UNIT_MAC_CAM_CFG_W28_CFG_MAC_CAM_MASK6_31_0_MASK 0x00000001 +#define CPU_MAC_UNIT_MAC_CAM_CFG_W29_CFG_MAC_CAM_MASK6_47_32_MASK 0x00000001 +#define CPU_MAC_UNIT_MAC_CAM_CFG_W30_CFG_MAC_CAM_MASK7_31_0_MASK 0x00000001 +#define CPU_MAC_UNIT_MAC_CAM_CFG_W31_CFG_MAC_CAM_MASK7_47_32_MASK 0x00000001 + +/* cpu_mac_unit_filter_cfg Definition */ +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_IP_ADDR_IS_SA0 BIT(17) +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_MAC_ADDR_IS_SA0 BIT(9) +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_IP_ADDR_IS_SA3 BIT(20) +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_MAC_ADDR_IS_SA6 BIT(15) +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_IP_ADDR_IS_SA1 BIT(18) +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_FILTER_IS_LOOSE BIT(5) +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_MAC_ADDR_IS_SA7 BIT(16) +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_IP_ADDR_FILTER_EN BIT(2) +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_BLOCK_SUPPRESSION_TRAFFIC BIT(6) +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_IP_ADDR_IS_SA2 BIT(19) +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_IP_CAM3_IS_V6 BIT(24) +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_MAC_ADDR_IS_SA5 BIT(14) +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_MAC_ADDR_IS_SA2 BIT(11) +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_MAC_ADDR_IS_SA4 BIT(13) +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_IP_CAM_IS_BLACK_LIST BIT(4) +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_MAC_CAM_IS_BLACK_LIST BIT(3) +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_MAC_FILTER_EN BIT(0) +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_IP_CAM2_IS_V6 BIT(23) +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_IP_CAM1_IS_V6 BIT(22) +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_ETHER_TYPE_FILTER_EN BIT(1) +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_MAC_ADDR_IS_SA1 BIT(10) +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_MAC_ADDR_IS_SA3 BIT(12) +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_IP_CAM0_IS_V6 BIT(21) +#define CPU_MAC_UNIT_FILTER_CFG_W1_CFG_SUPPRESSION_ETHER_TYPE0 BIT(16) +#define CPU_MAC_UNIT_FILTER_CFG_W1_CFG_VLAN_TPID BIT(0) +#define CPU_MAC_UNIT_FILTER_CFG_W2_CFG_SUPPRESSION_ETHER_TYPE1 BIT(0) +#define CPU_MAC_UNIT_FILTER_CFG_W2_CFG_SUPPRESSION_ETHER_TYPE2 BIT(16) +#define CPU_MAC_UNIT_FILTER_CFG_W3_CFG_CONFIRM_ETHER_TYPE0 BIT(0) +#define CPU_MAC_UNIT_FILTER_CFG_W3_CFG_CONFIRM_ETHER_TYPE1 BIT(16) +#define CPU_MAC_UNIT_FILTER_CFG_W4_CFG_CONFIRM_ETHER_TYPE2 BIT(0) +#define CPU_MAC_UNIT_FILTER_CFG_W5_CFG_METER_TOKEN_UPD_INTERVAL BIT(0) +#define CPU_MAC_UNIT_FILTER_CFG_W5_CFG_METER_TOKEN_UPD_VALUE BIT(16) + +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_IP_ADDR_IS_SA0_MASK 0x00020000 +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_MAC_ADDR_IS_SA0_MASK 0x00000200 +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_IP_ADDR_IS_SA3_MASK 0x00100000 +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_MAC_ADDR_IS_SA6_MASK 0x00008000 +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_IP_ADDR_IS_SA1_MASK 0x00040000 +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_FILTER_IS_LOOSE_MASK 0x00000020 +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_MAC_ADDR_IS_SA7_MASK 0x00010000 +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_IP_ADDR_FILTER_EN_MASK 0x00000004 +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_BLOCK_SUPPRESSION_TRAFFIC_MASK 0x000001c0 +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_IP_ADDR_IS_SA2_MASK 0x00080000 +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_IP_CAM3_IS_V6_MASK 0x01000000 +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_MAC_ADDR_IS_SA5_MASK 0x00004000 +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_MAC_ADDR_IS_SA2_MASK 0x00000800 +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_MAC_ADDR_IS_SA4_MASK 0x00002000 +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_IP_CAM_IS_BLACK_LIST_MASK 0x00000010 +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_MAC_CAM_IS_BLACK_LIST_MASK 0x00000008 +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_MAC_FILTER_EN_MASK 0x00000001 +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_IP_CAM2_IS_V6_MASK 0x00800000 +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_IP_CAM1_IS_V6_MASK 0x00400000 +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_ETHER_TYPE_FILTER_EN_MASK 0x00000002 +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_MAC_ADDR_IS_SA1_MASK 0x00000400 +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_MAC_ADDR_IS_SA3_MASK 0x00001000 +#define CPU_MAC_UNIT_FILTER_CFG_W0_CFG_IP_CAM0_IS_V6_MASK 0x00200000 +#define CPU_MAC_UNIT_FILTER_CFG_W1_CFG_SUPPRESSION_ETHER_TYPE0_MASK 0xffff0000 +#define CPU_MAC_UNIT_FILTER_CFG_W1_CFG_VLAN_TPID_MASK 0x0000ffff +#define CPU_MAC_UNIT_FILTER_CFG_W2_CFG_SUPPRESSION_ETHER_TYPE1_MASK 0x0000ffff +#define CPU_MAC_UNIT_FILTER_CFG_W2_CFG_SUPPRESSION_ETHER_TYPE2_MASK 0xffff0000 +#define CPU_MAC_UNIT_FILTER_CFG_W3_CFG_CONFIRM_ETHER_TYPE0_MASK 0x0000ffff +#define CPU_MAC_UNIT_FILTER_CFG_W3_CFG_CONFIRM_ETHER_TYPE1_MASK 0xffff0000 +#define CPU_MAC_UNIT_FILTER_CFG_W4_CFG_CONFIRM_ETHER_TYPE2_MASK 0x0000ffff +#define CPU_MAC_UNIT_FILTER_CFG_W5_CFG_METER_TOKEN_UPD_INTERVAL_MASK 0x0000ffff +#define CPU_MAC_UNIT_FILTER_CFG_W5_CFG_METER_TOKEN_UPD_VALUE_MASK 0xffff0000 + +struct cpu_mac_unit_mems { + u32 cpu_mac_unit_tx_ts_capture_fifo_0[3]; /* 0x00000400 */ + u32 cpu_mac_unit_tx_ts_capture_fifo_0_rsv3; + u32 cpu_mac_unit_tx_ts_capture_fifo_1[3]; /* 0x00000410 */ + u32 cpu_mac_unit_tx_ts_capture_fifo_1_rsv3; + u32 cpu_mac_unit_tx_ts_capture_fifo_2[3]; /* 0x00000420 */ + u32 cpu_mac_unit_tx_ts_capture_fifo_2_rsv3; + u32 cpu_mac_unit_tx_ts_capture_fifo_3[3]; /* 0x00000430 */ + u32 cpu_mac_unit_tx_ts_capture_fifo_3_rsv3; + u32 cpu_mac_unit_tx_ts_capture_fifo_4[3]; /* 0x00000440 */ + u32 cpu_mac_unit_tx_ts_capture_fifo_4_rsv3; + u32 cpu_mac_unit_tx_ts_capture_fifo_5[3]; /* 0x00000450 */ + u32 cpu_mac_unit_tx_ts_capture_fifo_5_rsv3; + u32 cpu_mac_unit_tx_ts_capture_fifo_6[3]; /* 0x00000460 */ + u32 cpu_mac_unit_tx_ts_capture_fifo_6_rsv3; + u32 cpu_mac_unit_tx_ts_capture_fifo_7[3]; /* 0x00000470 */ + u32 cpu_mac_unit_tx_ts_capture_fifo_7_rsv3; + u32 cpu_mac_unit_tx_capture_ts_0[3]; /* 0x00000480 */ + u32 cpu_mac_unit_tx_capture_ts_0_rsv3; +}; + +/* cpu_mac_unit_tx_ts_capture_fifo Definition */ +#define CPU_MAC_UNIT_TX_TS_CAPTURE_FIFO_W0_CPU_MAC_UNIT_TX_TS_CAPTURE_FIFO_FIELD0 BIT(0) +#define CPU_MAC_UNIT_TX_TS_CAPTURE_FIFO_W1_CPU_MAC_UNIT_TX_TS_CAPTURE_FIFO_FIELD1 BIT(0) +#define CPU_MAC_UNIT_TX_TS_CAPTURE_FIFO_W2_CPU_MAC_UNIT_TX_TS_CAPTURE_FIFO_FIELD2 BIT(0) + +#define CPU_MAC_UNIT_TX_TS_CAPTURE_FIFO_W0_CPU_MAC_UNIT_TX_TS_CAPTURE_FIFO_FIELD0_MASK 0xffffffff +#define CPU_MAC_UNIT_TX_TS_CAPTURE_FIFO_W1_CPU_MAC_UNIT_TX_TS_CAPTURE_FIFO_FIELD1_MASK 0xffffffff +#define CPU_MAC_UNIT_TX_TS_CAPTURE_FIFO_W2_CPU_MAC_UNIT_TX_TS_CAPTURE_FIFO_FIELD2_MASK 0x0000000f + +/* cpu_mac_unit_tx_capture_ts Definition */ +#define CPU_MAC_UNIT_TX_CAPTURE_TS_W0_CPU_MAC1_TX_SEQ_ID BIT(5) +#define CPU_MAC_UNIT_TX_CAPTURE_TS_W0_CPU_MAC1_TX_SFD BIT(4) +#define CPU_MAC_UNIT_TX_CAPTURE_TS_W0_CPU_MAC0_TX_SEQ_ID BIT(1) +#define CPU_MAC_UNIT_TX_CAPTURE_TS_W0_CPU_MAC0_TX_SFD BIT(0) +#define CPU_MAC_UNIT_TX_CAPTURE_TS_W1_ADJ_RC_SECOND BIT(0) +#define CPU_MAC_UNIT_TX_CAPTURE_TS_W2_ADJ_RC_NS BIT(0) + +#define CPU_MAC_UNIT_TX_CAPTURE_TS_W0_CPU_MAC1_TX_SEQ_ID_MASK 0x00000060 +#define CPU_MAC_UNIT_TX_CAPTURE_TS_W0_CPU_MAC1_TX_SFD_MASK 0x00000010 +#define CPU_MAC_UNIT_TX_CAPTURE_TS_W0_CPU_MAC0_TX_SEQ_ID_MASK 0x00000006 +#define CPU_MAC_UNIT_TX_CAPTURE_TS_W0_CPU_MAC0_TX_SFD_MASK 0x00000001 +#define CPU_MAC_UNIT_TX_CAPTURE_TS_W1_ADJ_RC_SECOND_MASK 0xffffffff +#define CPU_MAC_UNIT_TX_CAPTURE_TS_W2_ADJ_RC_NS_MASK 0x3fffffff + +#define CTCMAC_NUM 2 +#define TX_BUF_CNT 2 + +#define CTCMAC_MDIO_BASE 0x33620000 +#define CTCMAC_0_BASE 0x33410000 +#define CTCMAC_1_BASE 0x33420000 + +#define CTCMAC_MDIO_CMD_STCODE(V) (V << 0) +#define CTCMAC_MDIO_CMD_OPCODE(V) (V << 26) +#define CTCMAC_MDIO_CMD_PHYAD(V) (V << 21) +#define CTCMAC_MDIO_CMD_REGAD(V) (V << 16) +#define CTCMAC_MDIO_CMD_DATA(V) (V << 0) + +#define CTCMAC_MDIO_STAT(V) (V << 16) + +#endif diff --git a/platform/centec-arm64/tsingma-bsp/src/ctcmac/ctcmac_test.c b/platform/centec-arm64/tsingma-bsp/src/ctcmac/ctcmac_test.c new file mode 100644 index 000000000000..72bbf7599ebb --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/ctcmac/ctcmac_test.c @@ -0,0 +1,2116 @@ +/* + * Centec cpu_mac Ethernet Driver For Test -- cpu_mac controller implementation + * Provides Bus interface for MIIM regs + * + * Author: liuht + * + * Copyright 2002-2018, Centec Networks (Suzhou) Co., Ltd. + * + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "../pinctrl-ctc/pinctrl-ctc.h" +#include "../include/sysctl.h" +#include +#include +#include + +#include "ctcmac.h" +#include "ctcmac_reg.h" + +enum ctcmac_test_field { + CTCMAC_RING_SIZE = 0, + CTCMAC_PAYLOAD_SIZE = 1, + CTCMAC_RXTS_EN = 2, + CTCMAC_RXTS_DUMP = 3, + CTCMAC_TXTS_EN = 4, + CTCMAC_TXTS_DUMP = 5, + CTCMAC_TXINFO_VAL1 = 6, + CTCMAC_TXINFO_VAL2 = 7, + CTCMAC_TXINFO_VAL3 = 8, + CTCMAC_TXINFO_VAL4 = 9, +}; + +struct ctcmac_ptp_info { + u32 val1; + u32 val2; + u32 val3; + u32 val4; +}; + +struct ctcmac_test_param { + u32 ring_size; + u32 payload_size; + u32 rxts_en; + u32 rxts_dump; + u32 txts_en; + u32 txts_dump; + struct ctcmac_ptp_info ptp_info; +}; + +static int ctcmac_alloc_skb_resources(struct net_device *ndev); +static int ctcmac_free_skb_resources(struct ctcmac_private *priv); +static void cpumac_start(struct ctcmac_private *priv); +static void cpumac_halt(struct ctcmac_private *priv); +static void ctcmac_hw_init(struct ctcmac_private *priv); +static spinlock_t global_reglock __aligned(SMP_CACHE_BYTES); +static int g_reglock_init_done; +static int g_mac_unit_init_done; +static struct ctcmac_test_param test_param[2]; +static struct ctcmac_pkt_stats pkt_stats[2]; +static int cpumac_unit_irq_installed; +static struct regmap *regmap_base; +struct cpu_mac_unit_regs *g_cpumacu_reg; +/* get cpumac register : just for test */ +static int ctcmac_ethtool_get_eeprom(struct net_device *netdev, + struct ethtool_eeprom *ee, u8 *data) +{ + u8 *iobase; + u32 val; + unsigned long flags; + struct ctcmac_private *priv = netdev_priv(netdev); + + if (ee->offset >= 0x00010000) { + iobase = (u8 *)priv->cpumacu_reg; + ee->offset -= (0x00010000 + CPUMACUNIT_REG_BASE); + } else if (ee->offset >= 0x00004000) { + iobase = (u8 *)priv->cpumac_mem; + ee->offset -= 0x00004000; + } else { + iobase = (u8 *)priv->cpumac_reg; + } + + spin_lock_irqsave(&priv->reglock, flags); + val = readl((unsigned __iomem *)(iobase + ee->offset)); + pr_err("0x%llx : 0x%x\n", (u64)(iobase + ee->offset), val); + memcpy(data, (u8 *)&val, 4); + + spin_unlock_irqrestore(&priv->reglock, flags); + + return 0; +} + +static int ctcmac_fill_test_param(u32 index, u32 field, u32 val) +{ + if (field == CTCMAC_RING_SIZE) + test_param[index].ring_size = val; + else if (field == CTCMAC_PAYLOAD_SIZE) + test_param[index].payload_size = val; + else if (field == CTCMAC_RXTS_EN) + test_param[index].rxts_en = val; + else if (field == CTCMAC_RXTS_DUMP) + test_param[index].rxts_dump = val; + else if (field == CTCMAC_TXTS_EN) + test_param[index].txts_en = val; + else if (field == CTCMAC_TXTS_DUMP) + test_param[index].txts_dump = val; + else if (field == CTCMAC_TXINFO_VAL1) + test_param[index].ptp_info.val1 = val; + else if (field == CTCMAC_TXINFO_VAL2) + test_param[index].ptp_info.val2 = val; + else if (field == CTCMAC_TXINFO_VAL3) + test_param[index].ptp_info.val3 = val; + else if (field == CTCMAC_TXINFO_VAL4) + test_param[index].ptp_info.val4 = val; + + pr_err("test param:\n"); + pr_err("ring size : %d\n", test_param[index].ring_size); + pr_err("payload size : %d\n", test_param[index].payload_size); + pr_err("rxts en : %d\n", test_param[index].rxts_en); + pr_err("rxts dump : %d\n", test_param[index].rxts_dump); + pr_err("txts en : %d\n", test_param[index].txts_en); + pr_err("txts dump : %d\n", test_param[index].txts_dump); + pr_err("ptp info : 0x%x 0x%x 0x%x 0x%x\n", + test_param[index].ptp_info.val1, + test_param[index].ptp_info.val2, + test_param[index].ptp_info.val3, + test_param[index].ptp_info.val4); + + return 0; +} + +/* set cpumac register : just for test */ +static int ctcmac_ethtool_set_eeprom(struct net_device *netdev, + struct ethtool_eeprom *ee, u8 *data) +{ + u8 *iobase; + u32 val = 0; + unsigned long flags; + struct ctcmac_private *priv = netdev_priv(netdev); + + if (ee->offset >= 0x00030000) { + memset(&pkt_stats[priv->index], 0, + sizeof(struct ctcmac_pkt_stats)); + return 0; + } else if (ee->offset >= 0x00020000) { + val = + data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << + 24); + ctcmac_fill_test_param(priv->index, ee->offset - 0x00020000, + val); + return 0; + } else if (ee->offset >= 0x00010000) { + iobase = (u8 *)priv->cpumacu_reg; + ee->offset -= (0x00010000 + CPUMACUNIT_REG_BASE); + } else if (ee->offset >= 0x00004000) { + iobase = (u8 *)priv->cpumac_mem; + ee->offset -= 0x00004000; + } else { + iobase = (u8 *)priv->cpumac_reg; + } + + val = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); + pr_err("0x%llx : 0x%x\n", (u64)(iobase + ee->offset), val); + spin_lock_irqsave(&priv->reglock, flags); + writel(val, (unsigned __iomem *)(iobase + ee->offset)); + spin_unlock_irqrestore(&priv->reglock, flags); + + return 0; +} + +static void ctcmac_ethtool_get_stats(struct net_device *netdev, + struct ethtool_regs *regs, void *regbuf) +{ + u32 mtu; + unsigned long flags; + struct ctcmac_pkt_stats *stats; + struct ctcmac_private *priv = netdev_priv(netdev); + + spin_lock_irqsave(&priv->reglock, flags); + stats = &pkt_stats[priv->index]; + stats->rx_good_ucast_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_0[0]); + stats->rx_good_ucast_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_0[2]); + stats->rx_good_mcast_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_1[0]); + stats->rx_good_mcast_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_1[2]); + stats->rx_good_bcast_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_2[0]); + stats->rx_good_bcast_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_2[2]); + stats->rx_good_pause_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_3[0]); + stats->rx_good_pause_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_3[2]); + stats->rx_good_pfc_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_4[0]); + stats->rx_good_pfc_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_4[2]); + stats->rx_good_control_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_5[0]); + stats->rx_good_control_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_5[2]); + stats->rx_fcs_error_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_6[0]); + stats->rx_fcs_error_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_6[2]); + stats->rx_mac_overrun_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_7[0]); + stats->rx_mac_overrun_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_7[2]); + stats->rx_good_63B_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_8[0]); + stats->rx_good_63B_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_8[2]); + stats->rx_bad_63B_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_9[0]); + stats->rx_bad_63B_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_9[2]); + stats->rx_good_mtu2B_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_10[0]); + stats->rx_good_mtu2B_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_10[2]); + stats->rx_bad_mtu2B_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_11[0]); + stats->rx_bad_mtu2B_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_11[2]); + stats->rx_good_jumbo_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_12[0]); + stats->rx_good_jumbo_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_12[2]); + stats->rx_bad_jumbo_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_13[0]); + stats->rx_bad_jumbo_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_13[2]); + stats->rx_64B_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_14[0]); + stats->rx_64B_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_14[2]); + stats->rx_127B_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_15[0]); + stats->rx_127B_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_15[2]); + stats->rx_255B_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_16[0]); + stats->rx_255B_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_16[2]); + stats->rx_511B_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_17[0]); + stats->rx_511B_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_17[2]); + stats->rx_1023B_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_18[0]); + stats->rx_1023B_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_18[2]); + stats->rx_mtu1B_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_19[0]); + stats->rx_mtu1B_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_19[2]); + stats->tx_ucast_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_20[0]); + stats->tx_ucast_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_20[2]); + stats->tx_mcast_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_21[0]); + stats->tx_mcast_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_21[2]); + stats->tx_bcast_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_22[0]); + stats->tx_bcast_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_22[2]); + stats->tx_pause_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_23[0]); + stats->tx_pause_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_23[2]); + stats->tx_control_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_24[0]); + stats->tx_control_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_24[2]); + stats->tx_fcs_error_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_25[0]); + stats->tx_fcs_error_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_25[2]); + stats->tx_underrun_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_26[0]); + stats->tx_underrun_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_26[2]); + stats->tx_63B_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_27[0]); + stats->tx_63B_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_27[2]); + stats->tx_64B_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_28[0]); + stats->tx_64B_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_28[2]); + stats->tx_127B_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_29[0]); + stats->tx_127B_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_29[2]); + stats->tx_255B_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_30[0]); + stats->tx_255B_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_30[2]); + stats->tx_511B_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_31[0]); + stats->tx_511B_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_31[2]); + stats->tx_1023B_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_32[0]); + stats->tx_1023B_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_32[2]); + stats->tx_mtu1_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_33[0]); + stats->tx_mtu1_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_33[2]); + stats->tx_mtu2_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_34[0]); + stats->tx_mtu2_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_34[2]); + stats->tx_jumbo_bytes += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_35[0]); + stats->tx_jumbo_pkt += + readq(&priv->cpumac_mem->cpu_mac_stats_ram_35[2]); + mtu = readl(&priv->cpumac_reg->cpu_mac_stats_cfg[1]); + stats->mtu1 = mtu & 0x3fff; + stats->mtu2 = (mtu >> 16) & 0x3fff; + spin_unlock_irqrestore(&priv->reglock, flags); + + memcpy(regbuf, (void *)stats, sizeof(struct ctcmac_pkt_stats)); +} + +static int ctcmac_ethtool_get_eeprom_len(struct net_device *netdev) +{ + return 0x40000; +} + +static int ctcmac_ethtool_get_regs_len(struct net_device *netdev) +{ + return sizeof(struct ctcmac_pkt_stats); +} + +const struct ethtool_ops ctcmac_ethtool_test_ops = { + .get_eeprom = ctcmac_ethtool_get_eeprom, + .set_eeprom = ctcmac_ethtool_set_eeprom, + .get_eeprom_len = ctcmac_ethtool_get_eeprom_len, + .get_regs = ctcmac_ethtool_get_stats, + .get_regs_len = ctcmac_ethtool_get_regs_len, +}; + +static void clrsetbits(unsigned __iomem *addr, u32 clr, u32 set) +{ + writel((readl(addr) & ~(clr)) | (set), addr); +} + +static u32 ctcmac_regr(unsigned __iomem *addr) +{ + u32 val; + + val = readl(addr); + return val; +} + +static void ctcmac_regw(unsigned __iomem *addr, u32 val) +{ + writel(val, addr); +} + +static inline int ctcmac_rxbd_unused(struct ctcmac_priv_rx_q *rxq) +{ + if (rxq->next_to_clean > rxq->next_to_use) + return rxq->next_to_clean - rxq->next_to_use - 1; + + return rxq->rx_ring_size + rxq->next_to_clean - rxq->next_to_use - 1; +} + +static int ctcmac_alloc_tx_queues(struct ctcmac_private *priv) +{ + int i; + + for (i = 0; i < priv->num_tx_queues; i++) { + priv->tx_queue[i] = kzalloc(sizeof(*priv->tx_queue[i]), + GFP_KERNEL); + if (!priv->tx_queue[i]) + return -ENOMEM; + + priv->tx_queue[i]->tx_skbuff = NULL; + priv->tx_queue[i]->qindex = i; + priv->tx_queue[i]->dev = priv->ndev; + spin_lock_init(&priv->tx_queue[i]->txlock); + } + return 0; +} + +static int ctcmac_alloc_rx_queues(struct ctcmac_private *priv) +{ + int i; + + for (i = 0; i < priv->num_rx_queues; i++) { + priv->rx_queue[i] = kzalloc(sizeof(*priv->rx_queue[i]), + GFP_KERNEL); + if (!priv->rx_queue[i]) + return -ENOMEM; + + priv->rx_queue[i]->qindex = i; + priv->rx_queue[i]->ndev = priv->ndev; + } + return 0; +} + +static void ctcmac_unmap_io_space(struct ctcmac_private *priv) +{ + if (priv->iobase) + iounmap(priv->iobase); +} + +static void ctcmac_free_tx_queues(struct ctcmac_private *priv) +{ + int i; + + for (i = 0; i < priv->num_tx_queues; i++) + kfree(priv->tx_queue[i]); +} + +static void ctcmac_free_rx_queues(struct ctcmac_private *priv) +{ + int i; + + for (i = 0; i < priv->num_rx_queues; i++) + kfree(priv->rx_queue[i]); +} + +static void ctcmac_free_dev(struct ctcmac_private *priv) +{ + if (priv->ndev) + free_netdev(priv->ndev); +} + +static int ctcmac_of_init(struct platform_device *ofdev, + struct net_device **pdev) +{ + int err = 0, index; + const char *ctype; + struct net_device *dev = NULL; + struct ctcmac_private *priv = NULL; + unsigned int num_tx_qs, num_rx_qs; + struct device_node *np = ofdev->dev.of_node; + + num_tx_qs = CTCMAC_TX_QUEUE_MAX; + num_rx_qs = CTCMAC_RX_QUEUE_MAX; + + *pdev = alloc_etherdev_mq(sizeof(*priv), num_tx_qs); + dev = *pdev; + if (!dev) + return -ENOMEM; + + priv = netdev_priv(dev); + priv->ndev = dev; + priv->ofdev = ofdev; + priv->dev = &ofdev->dev; + priv->dev->coherent_dma_mask = DMA_BIT_MASK(64); + priv->num_tx_queues = num_tx_qs; + netif_set_real_num_rx_queues(dev, num_rx_qs); + priv->num_rx_queues = num_rx_qs; + + priv->iobase = of_iomap(np, 0); + priv->cpumac_reg = priv->iobase + CPUMAC_REG_BASE; + priv->cpumac_mem = priv->iobase + CPUMAC_MEM_BASE; + priv->cpumacu_reg = of_iomap(np, 1) + CPUMACUNIT_REG_BASE; + g_cpumacu_reg = priv->cpumacu_reg; + + err = of_property_read_u32(np, "index", &index); + if (err == 0) + priv->index = index; + else + priv->index = 0; + + err = of_property_read_string(np, "phy-connection-type", &ctype); + if (err == 0 && !strncmp(ctype, "sgmii", 5)) + priv->interface = PHY_INTERFACE_MODE_SGMII; + else + priv->interface = PHY_INTERFACE_MODE_MII; + + priv->supported = SUPPORTED_10baseT_Full | SUPPORTED_10baseT_Half; + err = of_property_read_string(np, "capability-100M", &ctype); + if (err == 0 && !strncmp(ctype, "support", 7)) + priv->supported |= + SUPPORTED_100baseT_Full | SUPPORTED_100baseT_Half; + + err = of_property_read_string(np, "capability-1000M", &ctype); + if (err == 0 && !strncmp(ctype, "support", 7)) + priv->supported |= SUPPORTED_1000baseT_Full; + + priv->phy_node = of_parse_phandle(np, "phy-handle", 0); + + priv->irqinfo[CTCMAC_NORMAL].irq = irq_of_parse_and_map(np, 0); + priv->irqinfo[CTCMAC_FUNC].irq = irq_of_parse_and_map(np, 1); + priv->irqinfo[CTCMAC_UNIT].irq = irq_of_parse_and_map(np, 2); + + return 0; +} + +static int startup_ctcmac(struct net_device *ndev) +{ + int i; + int err; + struct ctcmac_private *priv = netdev_priv(ndev); + + if (ctcmac_alloc_tx_queues(priv)) + return -1; + + if (ctcmac_alloc_rx_queues(priv)) + return -1; + + /* Initializing some of the rx/tx queue level parameters */ + for (i = 0; i < priv->num_tx_queues; i++) { + priv->tx_queue[i]->tx_ring_size = + test_param[priv->index].ring_size; + priv->tx_queue[i]->num_txbdfree = + test_param[priv->index].ring_size; + } + + for (i = 0; i < priv->num_rx_queues; i++) { + priv->rx_queue[i]->rx_ring_size = + test_param[priv->index].ring_size; + } + + ctcmac_hw_init(priv); + + err = ctcmac_alloc_skb_resources(ndev); + if (err) + return err; + + /* barrier */ + smp_mb__before_atomic(); + clear_bit(CTCMAC_DOWN, &priv->state); + /* barrier */ + smp_mb__after_atomic(); + + cpumac_start(priv); + /* force link state update after mac reset */ + priv->oldlink = 0; + priv->oldspeed = 0; + priv->oldduplex = -1; + + phy_start(ndev->phydev); + + napi_enable(&priv->napi_rx); + napi_enable(&priv->napi_tx); + + netif_tx_wake_all_queues(ndev); + + return 0; +} + +static void stop_ctcmac(struct net_device *ndev) +{ + struct ctcmac_private *priv = netdev_priv(ndev); + + /* disable ints and gracefully shut down Rx/Tx DMA */ + cpumac_halt(priv); + + netif_tx_stop_all_queues(ndev); + + /* barrier */ + smp_mb__before_atomic(); + set_bit(CTCMAC_DOWN, &priv->state); + /* barrier */ + smp_mb__after_atomic(); + napi_disable(&priv->napi_rx); + napi_disable(&priv->napi_tx); + phy_stop(ndev->phydev); + ctcmac_free_skb_resources(priv); +} + +static void ctcmac_reset(struct net_device *ndev) +{ + struct ctcmac_private *priv = netdev_priv(ndev); + + while (test_and_set_bit_lock(CTCMAC_RESETTING, &priv->state)) + cpu_relax(); + + stop_ctcmac(ndev); + startup_ctcmac(ndev); + clear_bit_unlock(CTCMAC_RESETTING, &priv->state); +} + +/* ctcmac_reset_task gets scheduled when a packet has not been + * transmitted after a set amount of time. + * For now, assume that clearing out all the structures, and + * starting over will fix the problem. + */ +static void ctcmac_reset_task(struct work_struct *work) +{ + struct ctcmac_private *priv = container_of(work, struct ctcmac_private, + reset_task); + + ctcmac_reset(priv->ndev); +} + +static int ctcmac_rxbd_used_untreated(struct ctcmac_private *priv, int qidx) +{ + u32 count; + + if (qidx) { + count = readl(&priv->cpumac_reg->cpu_mac_desc_mon[2]); + return count & 0xffff; + } + + count = readl(&priv->cpumac_reg->cpu_mac_desc_mon[1]); + + return (count >> 16) & 0xffff; +} + +static int ctcmac_txbd_used_untreated(struct ctcmac_private *priv) +{ + u32 count; + + count = readl(&priv->cpumac_reg->cpu_mac_desc_mon[2]); + + return (count >> 16) & 0xffff; +} + +static bool ctcmac_add_rx_frag(struct ctcmac_rx_buff *rxb, u32 lstatus, + struct sk_buff *skb, bool first) +{ + struct page *page = rxb->page; + unsigned int size = + (lstatus & CPU_MAC_DESC_INTF_W1_DESC_SIZE_MASK) >> 8; + + if (likely(first)) { + skb_put(skb, size); + } else { + skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, + rxb->page_offset, size, CTCMAC_RXB_TRUESIZE); + } + + /* try reuse page */ + if (unlikely(page_count(page) != 1)) + return false; + + /* change offset to the other half */ + rxb->page_offset ^= CTCMAC_RXB_TRUESIZE; + + page_ref_inc(page); + + return true; +} + +static void ctcmac_reuse_rx_page(struct ctcmac_priv_rx_q *rxq, + struct ctcmac_rx_buff *old_rxb) +{ + struct ctcmac_rx_buff *new_rxb; + u16 nta = rxq->next_to_alloc; + + new_rxb = &rxq->rx_buff[nta]; + + /* find next buf that can reuse a page */ + nta++; + rxq->next_to_alloc = (nta < rxq->rx_ring_size) ? nta : 0; + + /* copy page reference */ + *new_rxb = *old_rxb; + + /* sync for use by the device */ + dma_sync_single_range_for_device(rxq->dev, old_rxb->dma, + old_rxb->page_offset, + CTCMAC_RXB_TRUESIZE, DMA_FROM_DEVICE); +} + +static struct sk_buff *ctcmac_get_next_rxbuff(struct ctcmac_priv_rx_q *rx_queue, + u32 lstatus, struct sk_buff *skb) +{ + struct ctcmac_rx_buff *rxb = + &rx_queue->rx_buff[rx_queue->next_to_clean]; + struct page *page = rxb->page; + bool first = false; + + if (likely(!skb)) { + void *buff_addr = page_address(page) + rxb->page_offset; + + skb = build_skb(buff_addr, CTCMAC_SKBFRAG_SIZE); + if (unlikely(!skb)) + return NULL; + first = true; + } + + dma_sync_single_range_for_cpu(rx_queue->dev, rxb->dma, rxb->page_offset, + CTCMAC_RXB_TRUESIZE, DMA_FROM_DEVICE); + + if (ctcmac_add_rx_frag(rxb, lstatus, skb, first)) { + /* reuse the free half of the page */ + ctcmac_reuse_rx_page(rx_queue, rxb); + } else { + /* page cannot be reused, unmap it */ + dma_unmap_page(rx_queue->dev, rxb->dma, + PAGE_SIZE, DMA_FROM_DEVICE); + } + + /* clear rxb content */ + rxb->page = NULL; + + return skb; +} + +static void ctcmac_process_frame(struct net_device *ndev, struct sk_buff *skb) +{ + struct ctcmac_private *priv = netdev_priv(ndev); + + if (test_param[priv->index].rxts_en) { + struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb); + u64 *ns = (u64 *)(skb->data + skb->len - 8); + + if (test_param[priv->index].rxts_dump) + pr_err("receive frame time stamp 0x%llx\n", *ns); + + memset(shhwtstamps, 0, sizeof(*shhwtstamps)); + shhwtstamps->hwtstamp = ns_to_ktime(be64_to_cpu(*ns)); + skb_pull(skb, 8); + if (test_param[priv->index].rxts_dump) { + pr_err("receive frame time stamp %lld\n", + shhwtstamps->hwtstamp); + } + } + + skb->protocol = eth_type_trans(skb, ndev); +} + +static int ctc_mac_serdes_init(struct ctcmac_private *priv) +{ + int ret = 0; + u32 status; + int delay_ms = 10; + + /* reset serdes */ + writel(0x83806000, &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[0]); + writel(0x28061800, &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[2]); + writel(0x0026c03a, &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[6]); + writel(0x28061810, &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[8]); + writel(0x0026c03a, &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[12]); + + /* offset0 bit1 BlkRstN */ + writel(0x83806002, &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[0]); + mdelay(delay_ms); + + writel(0x80002309, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x80000842, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x8000ea45, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + + /* serdes 0 init */ + writel(0x83000a05, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x83002008, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x8300640f, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x83000214, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x83008015, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x83000116, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x83001817, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x83003018, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x83000e24, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x83008226, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x83001f27, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x83002028, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x83002829, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x8300302a, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x83002038, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x8300223a, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x8300523b, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x83002040, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x8300f141, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x8300014a, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x8300e693, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + + /* serdes 1 init */ + writel(0x84000a05, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x84002008, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x8400640f, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x84000214, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x84008015, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x84000116, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x84001817, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x84003018, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x84000e24, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x84008226, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x84001f27, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x84002028, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x84002829, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x8400302a, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x84002038, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x8400223a, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x8400523b, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x84002040, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x8400f141, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x8400014a, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + mdelay(delay_ms); + writel(0x8400e693, &priv->cpumacu_reg->cpu_mac_unit_hss_reg_acc_ctl); + + /* serdes post release */ + writel(0x83806003, &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[0]); + writel(0x83826003, &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[0]); + + writel(0x28061801, &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[2]); + writel(0x28061c01, &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[2]); + writel(0x28071c01, &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[2]); + + writel(0x28061811, &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[8]); + writel(0x28061c11, &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[8]); + writel(0x28071c11, &priv->cpumacu_reg->cpu_mac_unit_hss_cfg[8]); + + ret = + readl_poll_timeout(&priv->cpumacu_reg->cpu_mac_unit_hss_mon[1], + status, + status & + CPU_MAC_UNIT_HSS_MON_W1_MON_HSS_L0_DFE_RST_DONE, + 1000, 2000000); + if (ret) { + netdev_dbg(priv->ndev, + "%s:wait for hss reset done fail with cpu_mac_unit_hss_mon[1]:0x%x\n", + priv->ndev->name, + readl(&priv->cpumacu_reg->cpu_mac_unit_hss_mon[1])); + } + mdelay(delay_ms); + + return 0; +} + +static void ctcmac_hw_init(struct ctcmac_private *priv) +{ + int i; + u32 val; + int use_extram = 0; + + /* two cpumac access the same cpumac unit register */ + spin_lock_irq(&global_reglock); + if (priv->index == 0) { + clrsetbits(&priv->cpumacu_reg->cpu_mac_unit_reset_ctl, + CPU_MAC_UNIT_RESET_CTL_W0_RESET_CORE_BASE, + CPU_MAC_UNIT_RESET_CTL_W0_RESET_CORE_CPU_MAC0); + clrsetbits(&priv->cpumacu_reg->cpu_mac_unit_reset_ctl, + CPU_MAC_UNIT_RESET_CTL_W0_RESET_CORE_CPU_MAC0, 0); + } else { + clrsetbits(&priv->cpumacu_reg->cpu_mac_unit_reset_ctl, + CPU_MAC_UNIT_RESET_CTL_W0_RESET_CORE_BASE, + CPU_MAC_UNIT_RESET_CTL_W0_RESET_CORE_CPU_MAC1); + clrsetbits(&priv->cpumacu_reg->cpu_mac_unit_reset_ctl, + CPU_MAC_UNIT_RESET_CTL_W0_RESET_CORE_CPU_MAC1, 0); + } + + clrsetbits(&priv->cpumacu_reg->cpu_mac_unit_ts_cfg, + 0, CPU_MAC_UNIT_TS_CFG_W0_CFG_FORCE_S_AND_NS_EN); + + spin_unlock_irq(&global_reglock); + mdelay(10); + + clrsetbits(&priv->cpumac_reg->cpu_mac_init, 0, + CPU_MAC_INIT_DONE_W0_INIT_DONE); + udelay(1); + + if (priv->interface == PHY_INTERFACE_MODE_SGMII) { + /* switch to sgmii and enable auto nego */ + val = readl(&priv->cpumac_reg->cpu_mac_sgmii_auto_neg_cfg); + val &= ~(CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_AN_ENABLE_MASK + | CPU_MAC_SGMII_AUTO_NEG_CFG_W0_CFG_AN_MODE_MASK); + val |= (CSA_SGMII_MD_MASK | CSA_EN); + writel(val, &priv->cpumac_reg->cpu_mac_sgmii_auto_neg_cfg); + } + + clrsetbits(&priv->cpumac_reg->cpu_mac_sgmii_cfg[0], + CPU_MAC_SGMII_CFG_W0_CFG_MII_RX_LINK_FILTER_EN, 0); + clrsetbits(&priv->cpumac_reg->cpu_mac_sgmii_cfg[0], + 0, CPU_MAC_SGMII_CFG_W0_CFG_TX_EVEN_IGNORE); + + clrsetbits(&priv->cpumac_reg->cpu_mac_axi_cfg, + 0, CPU_MAC_AXI_CFG_W0_CFG_AXI_RD_D_WORD_SWAP_EN); + clrsetbits(&priv->cpumac_reg->cpu_mac_axi_cfg, + 0, CPU_MAC_AXI_CFG_W0_CFG_AXI_WR_D_WORD_SWAP_EN); + + clrsetbits(&priv->cpumac_reg->cpu_mac_gmac_cfg[0], + 0, CPU_MAC_GMAC_CFG_W0_CFG_RX_OVERRUN_DROP_EN + | CPU_MAC_GMAC_CFG_W0_CFG_RX_OVERSIZE_DROP_EN); + + clrsetbits(&priv->cpumac_reg->cpu_mac_gmac_cfg[2], + CPU_MAC_GMAC_CFG_W2_CFG_TX_STRIP_CRC_EN, 0); + + clrsetbits(&priv->cpumac_reg->cpu_mac_gmac_cfg[2], + 0, CPU_MAC_GMAC_CFG_W2_CFG_TX_CUT_THROUGH_EN); + + for (i = 0; i < priv->num_tx_queues; i++) { + if (priv->tx_queue[i]->tx_ring_size > + CTCMAC_INTERNAL_RING_SIZE) { + use_extram = 1; + break; + } + } + + for (i = 0; i < priv->num_rx_queues; i++) { + if (priv->rx_queue[i]->rx_ring_size > + CTCMAC_INTERNAL_RING_SIZE) { + use_extram = 1; + break; + } + } + + if (use_extram) { + spin_lock_irq(&global_reglock); + regmap_read(regmap_base, + offsetof(struct SysCtl_regs, SysMemCtl), &val); + val |= SYS_MEM_CTL_W0_CFG_RAM_MUX_EN; + regmap_write(regmap_base, + offsetof(struct SysCtl_regs, SysMemCtl), val); + spin_unlock_irq(&global_reglock); + if (priv->index == 0) { + ctcmac_regw(&priv->cpumac_reg->cpu_mac_ext_ram_cfg[1], + CTCMAC0_EXSRAM_BASE); + } else { + ctcmac_regw(&priv->cpumac_reg->cpu_mac_ext_ram_cfg[1], + CTCMAC1_EXSRAM_BASE); + } + ctcmac_regw(&priv->cpumac_reg->cpu_mac_ext_ram_cfg[0], + test_param[priv->index].ring_size); + clrsetbits(&priv->cpumac_reg->cpu_mac_ext_ram_cfg[0], 0, + CPU_MAC_EXT_RAM_CFG_W0_CFG_EXT_RAM_EN); + + } else { + clrsetbits(&priv->cpumac_reg->cpu_mac_ext_ram_cfg[0], + CPU_MAC_EXT_RAM_CFG_W0_CFG_EXT_RAM_EN, 0); + spin_lock_irq(&global_reglock); + regmap_read(regmap_base, + offsetof(struct SysCtl_regs, SysMemCtl), &val); + val &= ~SYS_MEM_CTL_W0_CFG_RAM_MUX_EN; + regmap_write(regmap_base, + offsetof(struct SysCtl_regs, SysMemCtl), val); + spin_unlock_irq(&global_reglock); + } + + if (test_param[priv->index].rxts_en) { + clrsetbits(&priv->cpumac_reg->cpu_mac_gmac_cfg[0], + 0, CPU_MAC_GMAC_CFG_W0_CFG_RX_TS_EN); + } + + if (test_param[priv->index].txts_en) { + clrsetbits(&priv->cpumac_reg->cpu_mac_gmac_cfg[2], + CPU_MAC_GMAC_CFG_W2_CFG_TX_WAIT_CAPTURE_TS, + CPU_MAC_GMAC_CFG_W2_CFG_TX_HDR_INFO_EN); + } + + /* clear all interrupt */ + ctcmac_regw(&priv->cpumac_reg->cpu_mac_interrupt_func[1], 0xffffffff); + ctcmac_regw(&priv->cpumac_reg->cpu_mac_interrupt_normal[1], 0xffffffff); + /* mask all interrupt */ + ctcmac_regw(&priv->cpumac_reg->cpu_mac_interrupt_func[2], 0xffffffff); + ctcmac_regw(&priv->cpumac_reg->cpu_mac_interrupt_normal[2], 0xffffffff); + + pr_err("%s ctcmac_hw_init 0x%x\n", __func__, priv->ndev->flags); +} + +/* update cpumac speed when phy linkup speed changed */ +static noinline void ctcmac_update_link_state(struct ctcmac_private *priv, + struct phy_device *phydev) +{ + int timeout = 2000; + u32 mon, cfg_rep, cfg_smp; + int speed = phydev->speed; + + if (priv->interface != PHY_INTERFACE_MODE_SGMII) + return; + + if (netif_msg_link(priv)) + netdev_dbg(priv->ndev, "link up speed is %d\n", speed); + + if (phydev->link) { + cfg_rep = readl(&priv->cpumac_reg->cpu_mac_sgmii_cfg[0]); + cfg_smp = readl(&priv->cpumac_reg->cpu_mac_sgmii_cfg[1]); + cfg_rep &= ~CSC_REP_MASK; + cfg_smp &= ~CSC_SMP_MASK; + if (speed == 1000) { + cfg_rep |= CSC_1000M; + cfg_smp |= CSC_1000M; + } else if (speed == 100) { + cfg_rep |= CSC_100M; + cfg_smp |= CSC_100M; + } else if (speed == 10) { + cfg_rep |= CSC_10M; + cfg_smp |= CSC_10M; + } else { + return; + } + writel(cfg_rep, &priv->cpumac_reg->cpu_mac_sgmii_cfg[0]); + writel(cfg_smp, &priv->cpumac_reg->cpu_mac_sgmii_cfg[1]); + + while (timeout--) { + mon = readl(&priv->cpumac_reg->cpu_mac_sgmii_mon[0]); + if ((mon & CSM_ANST_MASK) == 6) + break; + + mdelay(1); + } + + if ((mon & CSM_ANST_MASK) != 6) { + pr_err("Error! when phy link up, auto-neg status %d is not right.\n", + mon); + } + if (!priv->oldlink) + priv->oldlink = 1; + + } else { + priv->oldlink = 0; + priv->oldspeed = 0; + priv->oldduplex = -1; + } +} + +static void adjust_link(struct net_device *dev) +{ + struct ctcmac_private *priv = netdev_priv(dev); + struct phy_device *phydev = dev->phydev; + + if (unlikely(phydev->link != priv->oldlink || + (phydev->link && (phydev->duplex != priv->oldduplex || + phydev->speed != priv->oldspeed)))) + ctcmac_update_link_state(priv, phydev); +} + +/* Initializes driver's PHY state, and attaches to the PHY. + * Returns 0 on success. + */ +static int ctcmac_init_phy(struct net_device *dev) +{ + struct ctcmac_private *priv = netdev_priv(dev); + phy_interface_t interface; + struct phy_device *phydev; + + priv->oldlink = 0; + priv->oldspeed = 0; + priv->oldduplex = -1; + + interface = priv->interface; + + phydev = of_phy_connect(dev, priv->phy_node, &adjust_link, 0, + interface); + if (!phydev) { + dev_err(&dev->dev, "could not attach to PHY\n"); + return -ENODEV; + } + + /* Remove any features not supported by the controller */ + phydev->supported = priv->supported; + phydev->advertising = phydev->supported; + + return 0; +} + +static irqreturn_t ctcmac_receive(int irq, struct ctcmac_private *priv) +{ + unsigned long flags; + + if (likely(napi_schedule_prep(&priv->napi_rx))) { + /* disable interrupt */ + spin_lock_irqsave(&priv->reglock, flags); + writel(CTCMAC_NOR_RX0_D | CTCMAC_NOR_RX1_D, + &priv->cpumac_reg->cpu_mac_interrupt_func[2]); + spin_unlock_irqrestore(&priv->reglock, flags); + __napi_schedule(&priv->napi_rx); + } else { + /* clear interrupt */ + writel(CTCMAC_NOR_RX0_D | CTCMAC_NOR_RX1_D, + &priv->cpumac_reg->cpu_mac_interrupt_func[1]); + } + + return IRQ_HANDLED; +} + +static irqreturn_t ctcmac_transmit(int irq, struct ctcmac_private *priv) +{ + unsigned long flags; + + if (likely(napi_schedule_prep(&priv->napi_tx))) { + /* disable interrupt */ + spin_lock_irqsave(&priv->reglock, flags); + writel(CTCMAC_NOR_TX_D, + &priv->cpumac_reg->cpu_mac_interrupt_func[2]); + spin_unlock_irqrestore(&priv->reglock, flags); + __napi_schedule(&priv->napi_tx); + + } else { + /* clear interrupt */ + writel(CTCMAC_NOR_TX_D, + &priv->cpumac_reg->cpu_mac_interrupt_func[1]); + } + + return IRQ_HANDLED; +} + +static irqreturn_t ctcmac_func(int irq, void *data) +{ + u32 event, stat, mask; + struct ctcmac_private *priv = (struct ctcmac_private *)data; + + stat = ctcmac_regr(&priv->cpumac_reg->cpu_mac_interrupt_func[0]); + mask = ctcmac_regr(&priv->cpumac_reg->cpu_mac_interrupt_func[2]); + event = stat & ~mask; + + if ((event & CTCMAC_NOR_RX0_D) || (event & CTCMAC_NOR_RX1_D)) + ctcmac_receive(irq, priv); + + if (event & CTCMAC_NOR_TX_D) + ctcmac_transmit(irq, priv); + + return IRQ_HANDLED; +} + +static irqreturn_t ctcmac_unit(int irq, void *data) +{ + struct cpu_mac_unit_mems *mems = + (struct cpu_mac_unit_mems *)(g_cpumacu_reg + 0x400 - + CPUMACUNIT_REG_BASE); + + ctcmac_regw(&g_cpumacu_reg->cpu_mac_unit_interrupt_func[2], 1); + ctcmac_regw(&g_cpumacu_reg->cpu_mac_unit_interrupt_func[1], 1); + + while (ctcmac_regr(&g_cpumacu_reg->cpu_mac_unit_fifo_status)) { + pr_err("Tx Capture time stamp in fifo 0x%x 0x%x 0x%x\n", + ctcmac_regr(&mems->cpu_mac_unit_tx_capture_ts_0[0]), + ctcmac_regr(&mems->cpu_mac_unit_tx_capture_ts_0[1]), + ctcmac_regr(&mems->cpu_mac_unit_tx_capture_ts_0[2])); + } + ctcmac_regw(&g_cpumacu_reg->cpu_mac_unit_interrupt_func[3], 1); + + return IRQ_HANDLED; +} + +static irqreturn_t ctcmac_normal(int irq, void *grp_id) //TODO by liuht +{ + return IRQ_HANDLED; +} + +static int ctcmac_request_irq(struct ctcmac_private *priv) +{ + int err = 0; + + err = request_irq(priv->irqinfo[CTCMAC_NORMAL].irq, ctcmac_normal, 0, + priv->irqinfo[CTCMAC_NORMAL].name, priv); + if (err < 0) + free_irq(priv->irqinfo[CTCMAC_NORMAL].irq, priv); + enable_irq_wake(priv->irqinfo[CTCMAC_NORMAL].irq); + + err = request_irq(priv->irqinfo[CTCMAC_FUNC].irq, ctcmac_func, 0, + priv->irqinfo[CTCMAC_FUNC].name, priv); + if (err < 0) + free_irq(priv->irqinfo[CTCMAC_FUNC].irq, priv); + enable_irq_wake(priv->irqinfo[CTCMAC_FUNC].irq); + + spin_lock_irq(&global_reglock); + if (priv->irqinfo[CTCMAC_UNIT].irq && !cpumac_unit_irq_installed) { + err = + request_irq(priv->irqinfo[CTCMAC_UNIT].irq, ctcmac_unit, 0, + "cpumac_unit", NULL); + if (err < 0) { + free_irq(priv->irqinfo[CTCMAC_UNIT].irq, NULL); + return err; + } + enable_irq_wake(priv->irqinfo[CTCMAC_UNIT].irq); + cpumac_unit_irq_installed = 1; + } + spin_unlock_irq(&global_reglock); + + return err; +} + +static void ctcmac_free_irq(struct ctcmac_private *priv) +{ + free_irq(priv->irqinfo[CTCMAC_NORMAL].irq, priv); + free_irq(priv->irqinfo[CTCMAC_FUNC].irq, priv); + + spin_lock_irq(&global_reglock); + if (cpumac_unit_irq_installed == 1) { + free_irq(priv->irqinfo[CTCMAC_UNIT].irq, NULL); + cpumac_unit_irq_installed = 0; + } + spin_unlock_irq(&global_reglock); +} + +static bool ctcmac_new_page(struct ctcmac_priv_rx_q *rxq, + struct ctcmac_rx_buff *rxb) +{ + struct page *page; + dma_addr_t addr; + + page = dev_alloc_page(); + if (unlikely(!page)) + return false; + + addr = dma_map_page(rxq->dev, page, 0, PAGE_SIZE, DMA_FROM_DEVICE); + if (unlikely(dma_mapping_error(rxq->dev, addr))) { + __free_page(page); + + return false; + } + + rxb->dma = addr; + rxb->page = page; + rxb->page_offset = 0; + + return true; +} + +static void ctcmac_fill_rxbd(struct ctcmac_private *priv, + struct ctcmac_rx_buff *rxb, int qidx) +{ + u32 desc_cfg_low, desc_cfg_high; + dma_addr_t bufaddr = rxb->dma + rxb->page_offset; + + desc_cfg_low = + (bufaddr - CTC_DDR_BASE) & CPU_MAC_DESC_INTF_W0_DESC_ADDR_31_0_MASK; + /* CPU_MAC_DESC_INTF_W1_DESC_SIZE:bit(8) */ + desc_cfg_high = (test_param[priv->index].payload_size << 8) | + (((bufaddr - + CTC_DDR_BASE) >> 32) & + CPU_MAC_DESC_INTF_W1_DESC_ADDR_39_32_MASK); + + spin_lock_irq(&priv->reglock); + if (qidx) { + ctcmac_regw(&priv->cpumac_mem->cpu_mac_desc_intf_1[0], + desc_cfg_low); + /* barrier */ + smp_mb__before_atomic(); + ctcmac_regw(&priv->cpumac_mem->cpu_mac_desc_intf_1[1], + desc_cfg_high); + + } else { + ctcmac_regw(&priv->cpumac_mem->cpu_mac_desc_intf_0[0], + desc_cfg_low); + /* barrier */ + smp_mb__before_atomic(); + ctcmac_regw(&priv->cpumac_mem->cpu_mac_desc_intf_0[1], + desc_cfg_high); + } + + spin_unlock_irq(&priv->reglock); +} + +static void ctcmac_fill_txbd(struct ctcmac_private *priv, + struct ctcmac_desc_cfg *txdesc) +{ + u32 desc_cfg_low, desc_cfg_high; + + desc_cfg_low = txdesc->addr_low; + /* CPU_MAC_DESC_INTF_W1_DESC_SIZE:bit(8) */ + /* CPU_MAC_DESC_INTF_W1_DESC_SOP:bit(22) */ + /* CPU_MAC_DESC_INTF_W1_DESC_EOP:bit(23) */ + desc_cfg_high = txdesc->addr_high | + (txdesc->size << 8) | (txdesc->sop << 22) | (txdesc->eop << 23); + + spin_lock_irq(&priv->reglock); + ctcmac_regw(&priv->cpumac_mem->cpu_mac_desc_intf_2[0], desc_cfg_low); + /* barrier */ + smp_mb__before_atomic(); + ctcmac_regw(&priv->cpumac_mem->cpu_mac_desc_intf_2[1], desc_cfg_high); + spin_unlock_irq(&priv->reglock); +} + +static void ctcmac_get_txbd(struct ctcmac_private *priv) +{ + u32 lstatus; + + spin_lock_irq(&priv->reglock); + lstatus = ctcmac_regr(&priv->cpumac_mem->cpu_mac_desc_intf_2[0]); + /* barrier */ + smp_mb__before_atomic(); + lstatus = ctcmac_regr(&priv->cpumac_mem->cpu_mac_desc_intf_2[1]); + + spin_unlock_irq(&priv->reglock); +} + +static void ctcmac_get_rxbd(struct ctcmac_private *priv, u32 *lstatus, + int qidx) +{ + spin_lock_irq(&priv->reglock); + if (qidx) { + ctcmac_regr(&priv->cpumac_mem->cpu_mac_desc_intf_1[0]); + *lstatus = + ctcmac_regr(&priv->cpumac_mem->cpu_mac_desc_intf_1[1]); + } else { + ctcmac_regr(&priv->cpumac_mem->cpu_mac_desc_intf_0[0]); + *lstatus = + ctcmac_regr(&priv->cpumac_mem->cpu_mac_desc_intf_0[1]); + } + /* barrier */ + smp_mb__before_atomic(); + + spin_unlock_irq(&priv->reglock); +} + +static void ctcmac_alloc_rx_buffs(struct ctcmac_priv_rx_q *rx_queue, + int alloc_cnt) +{ + int i; + int qidx = rx_queue->qindex; + struct ctcmac_rx_buff *rxb; + struct net_device *ndev = rx_queue->ndev; + struct ctcmac_private *priv = netdev_priv(ndev); + + i = rx_queue->next_to_use; + rxb = &rx_queue->rx_buff[i]; + + while (alloc_cnt--) { + /* try reuse page */ + if (unlikely(!rxb->page)) { + if (unlikely(!ctcmac_new_page(rx_queue, rxb))) + break; + } + + ctcmac_fill_rxbd(priv, rxb, qidx); + rxb++; + + if (unlikely(++i == rx_queue->rx_ring_size)) { + i = 0; + rxb = rx_queue->rx_buff; + } + } + + rx_queue->next_to_use = i; + rx_queue->next_to_alloc = i; +} + +static int ctcmac_clean_rx_ring(struct ctcmac_priv_rx_q *rx_queue, + int rx_work_limit) +{ + struct net_device *ndev = rx_queue->ndev; + struct ctcmac_private *priv = netdev_priv(ndev); + int i, howmany = 0; + struct sk_buff *skb = rx_queue->skb; + int cleaned_cnt = ctcmac_rxbd_unused(rx_queue); + unsigned int total_bytes = 0, total_pkts = 0; + int qidx = rx_queue->qindex; + + /* Get the first full descriptor */ + i = rx_queue->next_to_clean; + + while (rx_work_limit--) { + u32 lstatus; + + if (cleaned_cnt >= test_param[priv->index].ring_size / 2) { + ctcmac_alloc_rx_buffs(rx_queue, cleaned_cnt); + cleaned_cnt = 0; + } + + if (ctcmac_rxbd_used_untreated(priv, qidx) <= 0) + break; + + if (qidx != 0) + pr_err("rx queue %d rx packet!\n", qidx); + ctcmac_get_rxbd(priv, &lstatus, qidx); + + /* fetch next to clean buffer from the ring */ + skb = ctcmac_get_next_rxbuff(rx_queue, lstatus, skb); + if (unlikely(!skb)) + break; + + cleaned_cnt++; + howmany++; + + if (unlikely(++i == rx_queue->rx_ring_size)) + i = 0; + + rx_queue->next_to_clean = i; + + /* fetch next buffer if not the last in frame */ + if (!(lstatus & CPU_MAC_DESC_INTF_W1_DESC_EOP)) + continue; + + if (unlikely(lstatus & CPU_MAC_DESC_INTF_W1_DESC_ERR)) { + if (!test_param[priv->index].rxts_en) { + /* discard faulty buffer */ + dev_kfree_skb(skb); + skb = NULL; + rx_queue->stats.rx_dropped++; + pr_err("%s: Error with rx desc status 0x%x\n", + ndev->name, lstatus); + continue; + } else { + pr_err("%s: Error with rx desc status 0x%x\n", + ndev->name, lstatus); + } + } + + /* Increment the number of packets */ + total_pkts++; + total_bytes += skb->len; + + skb_record_rx_queue(skb, rx_queue->qindex); + ctcmac_process_frame(ndev, skb); + /* Send the packet up the stack */ + napi_gro_receive(&priv->napi_rx, skb); + + skb = NULL; + } + + /* Store incomplete frames for completion */ + rx_queue->skb = skb; + + rx_queue->stats.rx_packets += total_pkts; + rx_queue->stats.rx_bytes += total_bytes; + + if (cleaned_cnt) + ctcmac_alloc_rx_buffs(rx_queue, cleaned_cnt); + + return howmany; +} + +static void ctcmac_clean_tx_ring(struct ctcmac_priv_tx_q *tx_queue) +{ + u16 next_to_clean; + int tqi = tx_queue->qindex; + struct sk_buff *skb; + struct netdev_queue *txq; + struct ctcmac_tx_buff *tx_buff; + struct net_device *dev = tx_queue->dev; + struct ctcmac_private *priv = netdev_priv(dev); + + txq = netdev_get_tx_queue(dev, tqi); + next_to_clean = tx_queue->next_to_clean; + while (ctcmac_txbd_used_untreated(priv)) { + ctcmac_get_txbd(priv); + + tx_buff = &tx_queue->tx_buff[next_to_clean]; + skb = tx_queue->tx_skbuff[next_to_clean]; + dev_kfree_skb_any(skb); + tx_queue->tx_skbuff[next_to_clean] = NULL; + + dma_unmap_single(priv->dev, tx_buff->dma, + tx_buff->len, DMA_TO_DEVICE); + if (tx_buff->alloc) + kfree(tx_buff->vaddr); + + if ((next_to_clean + 1) >= tx_queue->tx_ring_size) + next_to_clean = 0; + else + next_to_clean++; + + spin_lock(&tx_queue->txlock); + tx_queue->num_txbdfree++; + spin_unlock(&tx_queue->txlock); + } + + /* If we freed a buffer, we can restart transmission, if necessary */ + if (tx_queue->num_txbdfree && + netif_tx_queue_stopped(txq) && + !(test_bit(CTCMAC_DOWN, &priv->state))) { + netif_wake_subqueue(priv->ndev, tqi); + } + + tx_queue->next_to_clean = next_to_clean; +} + +static int ctcmac_poll_rx_sq(struct napi_struct *napi, int budget) +{ + int qidx; + int work_done = 0; + int rx_work_limit; + struct ctcmac_private *priv = + container_of(napi, struct ctcmac_private, napi_rx); + struct ctcmac_priv_rx_q *rx_queue = NULL; + + /* clear interrupt */ + writel(CTCMAC_NOR_RX0_D | CTCMAC_NOR_RX1_D, + &priv->cpumac_reg->cpu_mac_interrupt_func[1]); + + rx_work_limit = budget; + for (qidx = priv->num_rx_queues - 1; qidx >= 0; qidx--) { + rx_queue = priv->rx_queue[qidx]; + work_done += ctcmac_clean_rx_ring(rx_queue, rx_work_limit); + rx_work_limit -= work_done; + } + + if (work_done < budget) { + napi_complete(napi); + /* enable interrupt */ + spin_lock_irq(&priv->reglock); + writel(CTCMAC_NOR_RX0_D | CTCMAC_NOR_RX1_D, + &priv->cpumac_reg->cpu_mac_interrupt_func[3]); + spin_unlock_irq(&priv->reglock); + } + + return work_done; +} + +static int ctcmac_poll_tx_sq(struct napi_struct *napi, int budget) +{ + struct ctcmac_private *priv = + container_of(napi, struct ctcmac_private, napi_tx); + struct ctcmac_priv_tx_q *tx_queue = priv->tx_queue[0]; + + /* clear interrupt */ + writel(CTCMAC_NOR_TX_D, &priv->cpumac_reg->cpu_mac_interrupt_func[1]); + + ctcmac_clean_tx_ring(tx_queue); + + napi_complete(napi); + /* enable interrupt */ + spin_lock_irq(&priv->reglock); + writel(CTCMAC_NOR_TX_D, &priv->cpumac_reg->cpu_mac_interrupt_func[3]); + spin_unlock_irq(&priv->reglock); + + return 0; +} + +static void ctcmac_free_rx_resources(struct ctcmac_private *priv) +{ + int i, j; + struct ctcmac_priv_rx_q *rx_queue = NULL; + + for (i = 0; i < priv->num_rx_queues; i++) { + rx_queue = priv->rx_queue[i]; + if (rx_queue->skb) + dev_kfree_skb(rx_queue->skb); + + for (j = 0; j < rx_queue->rx_ring_size; j++) { + struct ctcmac_rx_buff *rxb = &rx_queue->rx_buff[j]; + + if (!rxb->page) + continue; + dma_unmap_single(rx_queue->dev, rxb->dma, + PAGE_SIZE, DMA_TO_DEVICE); + __free_page(rxb->page); + } + kfree(rx_queue->rx_buff); + rx_queue->rx_buff = NULL; + } +} + +static int ctcmac_init_rx_resources(struct net_device *ndev) +{ + int i; + struct ctcmac_private *priv = netdev_priv(ndev); + struct device *dev = priv->dev; + struct ctcmac_priv_rx_q *rx_queue = NULL; + + for (i = 0; i < priv->num_rx_queues; i++) { + rx_queue = priv->rx_queue[i]; + rx_queue->ndev = ndev; + rx_queue->dev = dev; + rx_queue->next_to_clean = 0; + rx_queue->next_to_use = 0; + rx_queue->next_to_alloc = 0; + rx_queue->skb = NULL; + rx_queue->rx_buff = kcalloc(rx_queue->rx_ring_size, + sizeof(*rx_queue->rx_buff), + GFP_KERNEL); + if (!rx_queue->rx_buff) + goto cleanup; + + ctcmac_alloc_rx_buffs(rx_queue, ctcmac_rxbd_unused(rx_queue)); + } + + return 0; + +cleanup: + ctcmac_free_rx_resources(priv); + + return -1; +} + +static void ctcmac_free_tx_resources(struct ctcmac_private *priv) +{ + int i; + struct ctcmac_priv_tx_q *tx_queue = NULL; + + for (i = 0; i < priv->num_tx_queues; i++) { + struct netdev_queue *txq; + + tx_queue = priv->tx_queue[i]; + txq = netdev_get_tx_queue(tx_queue->dev, tx_queue->qindex); + + kfree(tx_queue->tx_skbuff); + tx_queue->tx_skbuff = NULL; + } +} + +static int ctcmac_init_tx_resources(struct net_device *ndev) +{ + int i; + struct ctcmac_private *priv = netdev_priv(ndev); + struct ctcmac_priv_tx_q *tx_queue = NULL; + + for (i = 0; i < priv->num_tx_queues; i++) { + tx_queue = priv->tx_queue[i]; + tx_queue->num_txbdfree = tx_queue->tx_ring_size; + tx_queue->next_to_clean = 0; + tx_queue->next_to_alloc = 0; + tx_queue->dev = ndev; + tx_queue->tx_skbuff = + kmalloc_array(tx_queue->tx_ring_size, + sizeof(*tx_queue->tx_skbuff), GFP_KERNEL); + + if (!tx_queue->tx_skbuff) + goto cleanup; + } + + return 0; + +cleanup: + ctcmac_free_tx_resources(priv); + + return -1; +} + +static int ctcmac_alloc_skb_resources(struct net_device *ndev) +{ + if (ctcmac_init_rx_resources(ndev)) + return -1; + if (ctcmac_init_tx_resources(ndev)) + return -1; + + return 0; +} + +static int ctcmac_free_skb_resources(struct ctcmac_private *priv) +{ + ctcmac_free_rx_resources(priv); + ctcmac_free_tx_resources(priv); + ctcmac_free_tx_queues(priv); + ctcmac_free_rx_queues(priv); + + return 0; +} + +static void cpumac_start(struct ctcmac_private *priv) +{ + /* 1. enable rx/tx interrupt */ + writel(CTCMAC_NOR_TX_D | CTCMAC_NOR_RX0_D | CTCMAC_NOR_RX1_D, + &priv->cpumac_reg->cpu_mac_interrupt_func[3]); + /* 2. enable rx/tx */ + clrsetbits(&priv->cpumac_reg->cpu_mac_reset, + CPU_MAC_RESET_W0_SOFT_RST_TX, + 0); + clrsetbits(&priv->cpumac_reg->cpu_mac_reset, + CPU_MAC_RESET_W0_SOFT_RST_RX, + 0); + + netif_trans_update(priv->ndev); /* prevent tx timeout */ +} + +static void cpumac_halt(struct ctcmac_private *priv) +{ + /* 1. disable rx/tx interrupt */ + ctcmac_regw(&priv->cpumac_reg->cpu_mac_interrupt_func[2], 0xffffffff); + ctcmac_regw(&priv->cpumac_reg->cpu_mac_interrupt_normal[2], 0xffffffff); + /* 2. disable rx/tx */ + clrsetbits(&priv->cpumac_reg->cpu_mac_reset, 0, + CPU_MAC_RESET_W0_SOFT_RST_TX); + clrsetbits(&priv->cpumac_reg->cpu_mac_reset, 0, + CPU_MAC_RESET_W0_SOFT_RST_RX); +} + +static int ctcmac_enet_open(struct net_device *dev) +{ + struct ctcmac_private *priv = netdev_priv(dev); + int err; + + err = ctcmac_init_phy(dev); + if (err) + return err; + err = ctcmac_request_irq(priv); + if (err) + return err; + err = startup_ctcmac(dev); + if (err) + return err; + return 0; +} + +static struct ctcmac_tx_buff *skb_to_txbuff(struct ctcmac_private *priv, + struct sk_buff *skb) +{ + u64 addr, offset; + int frag_index, nr_frags, rq; + skb_frag_t *frag; + struct ctcmac_tx_buff *tx_buff; + struct ctcmac_priv_tx_q *tx_queue = NULL; + + nr_frags = skb_shinfo(skb)->nr_frags; + rq = skb->queue_mapping; + tx_queue = priv->tx_queue[rq]; + + tx_buff = &tx_queue->tx_buff[tx_queue->next_to_alloc]; + addr = (u64)skb->data; + if (!test_param[priv->index].txts_en && !nr_frags && + ((addr & PAGE_MASK) == ((addr + skb_headlen(skb)) & PAGE_MASK))) { + tx_buff->alloc = 0; + tx_buff->vaddr = skb->data; + tx_buff->len = skb_headlen(skb); + tx_buff->dma = + dma_map_single(priv->dev, skb->data, skb_headlen(skb), + DMA_TO_DEVICE); + tx_buff->offset = 0; + + } else { + int alloc_size; + + if (test_param[priv->index].txts_en) { + alloc_size = ALIGN(skb->len + 16, BUF_ALIGNMENT); + tx_buff->len = skb->len + 16; + } else { + alloc_size = ALIGN(skb->len, BUF_ALIGNMENT); + tx_buff->len = skb->len; + } + tx_buff->alloc = 1; + tx_buff->vaddr = kmalloc(alloc_size, GFP_KERNEL); + offset = + (BUF_ALIGNMENT - + (((u64)tx_buff->vaddr) & (BUF_ALIGNMENT - 1))); + if (offset == BUF_ALIGNMENT) + offset = 0; + + tx_buff->offset = offset; + if (test_param[priv->index].txts_en) { + memcpy(tx_buff->vaddr + offset, + &test_param[priv->index].ptp_info, 16); + } + + offset += 16; + memcpy(tx_buff->vaddr + offset, skb->data, skb_headlen(skb)); + offset += skb_headlen(skb); + for (frag_index = 0; frag_index < nr_frags; frag_index++) { + frag = &skb_shinfo(skb)->frags[frag_index]; + memcpy(tx_buff->vaddr + offset, frag, + skb_frag_size(frag)); + offset += skb_frag_size(frag); + } + + tx_buff->dma = + dma_map_single(priv->dev, tx_buff->vaddr, tx_buff->len, + DMA_TO_DEVICE); + } + return tx_buff; +} + +static int ctcmac_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + int rq = 0; + unsigned int bytes_sent; + struct netdev_queue *txq; + struct ctcmac_desc_cfg tx_desc; + struct ctcmac_tx_buff *tx_buff; + struct ctcmac_priv_tx_q *tx_queue = NULL; + struct ctcmac_private *priv = netdev_priv(dev); + + rq = skb->queue_mapping; + tx_queue = priv->tx_queue[rq]; + txq = netdev_get_tx_queue(dev, rq); + + /* check if there is space to queue this packet */ + if (tx_queue->num_txbdfree <= 0) { + pr_err("%s: no space left before send pkt!\n", + priv->ndev->name); + /* no space, stop the queue */ + netif_tx_stop_queue(txq); + dev->stats.tx_fifo_errors++; + return NETDEV_TX_BUSY; + } + + /* Update transmit stats */ + bytes_sent = skb->len; + tx_queue->stats.tx_bytes += bytes_sent; + tx_queue->stats.tx_packets++; + + tx_buff = skb_to_txbuff(priv, skb); + tx_desc.sop = 1; + tx_desc.eop = 1; + tx_desc.size = tx_buff->len; + tx_desc.addr_low = (tx_buff->dma + tx_buff->offset - CTC_DDR_BASE) + & CPU_MAC_DESC_INTF_W0_DESC_ADDR_31_0_MASK; + tx_desc.addr_high = + ((tx_buff->dma + tx_buff->offset - CTC_DDR_BASE) >> 32) + & CPU_MAC_DESC_INTF_W1_DESC_ADDR_39_32_MASK; + ctcmac_fill_txbd(priv, &tx_desc); + tx_queue->tx_skbuff[tx_queue->next_to_alloc] = skb; + + if (tx_queue->next_to_alloc >= tx_queue->tx_ring_size - 1) + tx_queue->next_to_alloc = 0; + else + tx_queue->next_to_alloc++; + + /* We can work in parallel with 872(), except + * when modifying num_txbdfree. Note that we didn't grab the lock + * when we were reading the num_txbdfree and checking for available + * space, that's because outside of this function it can only grow. + */ + spin_lock_bh(&tx_queue->txlock); + /* reduce TxBD free count */ + tx_queue->num_txbdfree--; + spin_unlock_bh(&tx_queue->txlock); + + /* If the next BD still needs to be cleaned up, then the bds + * are full. We need to tell the kernel to stop sending us stuff. + */ + if (!tx_queue->num_txbdfree) { + netif_tx_stop_queue(txq); + pr_err("%s: no space left after send pkt!\n", priv->ndev->name); + dev->stats.tx_fifo_errors++; + } + + return NETDEV_TX_OK; +} + +static int ctcmac_change_mtu(struct net_device *dev, int new_mtu) +{ + struct ctcmac_private *priv = netdev_priv(dev); + int frame_size = new_mtu + ETH_HLEN; + + if (frame_size < 64 || frame_size > CTCMAC_JUMBO_FRAME_SIZE) + return -EINVAL; + + while (test_and_set_bit_lock(CTCMAC_RESETTING, &priv->state)) + cpu_relax(); + + if (dev->flags & IFF_UP) + stop_ctcmac(dev); + + dev->mtu = new_mtu; + + if (dev->flags & IFF_UP) + startup_ctcmac(dev); + + clear_bit_unlock(CTCMAC_RESETTING, &priv->state); + + return 0; +} + +static int ctcmac_set_features(struct net_device *dev, + netdev_features_t features) +{ + return 0; +} + +/* Stops the kernel queue, and halts the controller */ +static int ctcmac_close(struct net_device *dev) +{ + struct ctcmac_private *priv = netdev_priv(dev); + + cancel_work_sync(&priv->reset_task); + stop_ctcmac(dev); + + /* Disconnect from the PHY */ + phy_disconnect(dev->phydev); + ctcmac_free_irq(priv); + return 0; +} + +static void ctcmac_set_multi(struct net_device *dev) +{ +} + +static void ctcmac_timeout(struct net_device *dev) +{ + struct ctcmac_private *priv = netdev_priv(dev); + + dev->stats.tx_errors++; + schedule_work(&priv->reset_task); +} + +static int ctcmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + struct phy_device *phydev = dev->phydev; + + if (!netif_running(dev)) + return -EINVAL; + + if (!phydev) + return -ENODEV; + + return phy_mii_ioctl(phydev, rq, cmd); +} + +static struct net_device_stats *ctcmac_get_stats(struct net_device *dev) +{ + int qidx; + unsigned long rx_packets = 0, rx_bytes = 0, rx_dropped = 0; + unsigned long tx_packets = 0, tx_bytes = 0; + struct ctcmac_private *priv = netdev_priv(dev); + + for (qidx = 0; qidx < priv->num_rx_queues; qidx++) { + if (!priv->rx_queue[qidx]) + return &dev->stats; + rx_packets += priv->rx_queue[qidx]->stats.rx_packets; + rx_bytes += priv->rx_queue[qidx]->stats.rx_bytes; + rx_dropped += priv->rx_queue[qidx]->stats.rx_dropped; + } + + if (!priv->tx_queue[0]) + return &dev->stats; + + tx_packets = priv->tx_queue[0]->stats.tx_packets; + tx_bytes = priv->tx_queue[0]->stats.tx_bytes; + + dev->stats.rx_packets = rx_packets; + dev->stats.rx_bytes = rx_bytes; + dev->stats.rx_dropped = rx_dropped; + dev->stats.tx_bytes = tx_bytes; + dev->stats.tx_packets = tx_packets; + + return &dev->stats; +} + +static int ctcmac_set_mac_addr(struct net_device *dev, void *p) +{ + eth_mac_addr(dev, p); + + return 0; +} + +static const struct net_device_ops ctcmac_netdev_ops = { + .ndo_open = ctcmac_enet_open, + .ndo_start_xmit = ctcmac_start_xmit, + .ndo_stop = ctcmac_close, + .ndo_change_mtu = ctcmac_change_mtu, + .ndo_set_features = ctcmac_set_features, + .ndo_set_rx_mode = ctcmac_set_multi, + .ndo_tx_timeout = ctcmac_timeout, + .ndo_do_ioctl = ctcmac_ioctl, + .ndo_get_stats = ctcmac_get_stats, + .ndo_set_mac_address = ctcmac_set_mac_addr, + .ndo_validate_addr = eth_validate_addr, +}; + +static int ctcmac_probe(struct platform_device *ofdev) +{ + struct net_device *dev = NULL; + struct ctcmac_private *priv = NULL; + int err = 0; + + regmap_base = + syscon_regmap_lookup_by_phandle(ofdev->dev.of_node, "ctc,sysctrl"); + if (IS_ERR(regmap_base)) + return PTR_ERR(regmap_base); + + err = ctcmac_of_init(ofdev, &dev); + if (err) + return err; + + priv = netdev_priv(dev); + SET_NETDEV_DEV(dev, &ofdev->dev); + INIT_WORK(&priv->reset_task, ctcmac_reset_task); + platform_set_drvdata(ofdev, priv); + + dev->base_addr = (unsigned long)priv->iobase; + dev->watchdog_timeo = TX_TIMEOUT; + dev->mtu = CTCMAC_DEFAULT_MTU; + dev->netdev_ops = &ctcmac_netdev_ops; + dev->ethtool_ops = &ctcmac_ethtool_test_ops; + + netif_napi_add(dev, &priv->napi_rx, ctcmac_poll_rx_sq, + CTCMAC_NAIP_RX_WEIGHT); + netif_napi_add(dev, &priv->napi_tx, ctcmac_poll_tx_sq, + CTCMAC_NAIP_TX_WEIGHT); + + set_bit(CTCMAC_DOWN, &priv->state); + + if (!g_reglock_init_done) + spin_lock_init(&global_reglock); + + g_reglock_init_done = 1; + + spin_lock_init(&priv->reglock); + /* Carrier starts down, phylib will bring it up */ + netif_carrier_off(dev); + err = register_netdev(dev); + if (err) + goto register_fail; + + if (!g_mac_unit_init_done) { + writel(0x07, &priv->cpumacu_reg->cpu_mac_unit_reset_ctl); + writel(0x00, &priv->cpumacu_reg->cpu_mac_unit_reset_ctl); + + clrsetbits(&priv->cpumacu_reg->cpu_mac_unit_ts_cfg, + 0, CPU_MAC_UNIT_TS_CFG_W0_CFG_FORCE_S_AND_NS_EN); + if (priv->interface == PHY_INTERFACE_MODE_SGMII) { + clrsetbits(&priv->cpumacu_reg->cpu_mac_unit_ref_pulse_cfg[1], + CPU_MAC_UNIT_REF_PULSE_CFG_W1_REF_LINK_PULSE_RST, + 0); + + ctc_mac_serdes_init(priv); + } + g_mac_unit_init_done = 1; + } + + mdelay(10); + + sprintf(priv->irqinfo[CTCMAC_NORMAL].name, "%s%s", + dev->name, "_normal"); + sprintf(priv->irqinfo[CTCMAC_FUNC].name, "%s%s", dev->name, "_func"); + sprintf(priv->irqinfo[CTCMAC_UNIT].name, "%s%s", dev->name, "_unit"); + test_param[priv->index].ring_size = 64; + test_param[priv->index].payload_size = 256; + + return 0; + +register_fail: + ctcmac_unmap_io_space(priv); + ctcmac_free_rx_queues(priv); + ctcmac_free_tx_queues(priv); + of_node_put(priv->phy_node); + ctcmac_free_dev(priv); + + return err; +} + +static int ctcmac_remove(struct platform_device *ofdev) +{ + struct ctcmac_private *priv = platform_get_drvdata(ofdev); + + of_node_put(priv->phy_node); + + unregister_netdev(priv->ndev); + + ctcmac_unmap_io_space(priv); + ctcmac_free_rx_queues(priv); + ctcmac_free_tx_queues(priv); + ctcmac_free_dev(priv); + + return 0; +} + +static const struct of_device_id ctcmac_match[] = { + { + .type = "network", + .compatible = "ctc,mac-test", + }, + {}, +}; + +MODULE_DEVICE_TABLE(of, ctcmac_match); + +/* Structure for a device driver */ +static struct platform_driver ctcmac_driver = { + .driver = { + .name = "ctc-cpumac-test", + .of_match_table = ctcmac_match, + }, + .probe = ctcmac_probe, + .remove = ctcmac_remove, +}; + +module_platform_driver(ctcmac_driver); +MODULE_LICENSE("GPL"); diff --git a/platform/centec-arm64/tsingma-bsp/src/ehci-ctc/Makefile b/platform/centec-arm64/tsingma-bsp/src/ehci-ctc/Makefile new file mode 100644 index 000000000000..121d3a0eada7 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/ehci-ctc/Makefile @@ -0,0 +1 @@ +obj-m = ehci-ctc.o diff --git a/platform/centec-arm64/tsingma-bsp/src/ehci-ctc/ehci-ctc.c b/platform/centec-arm64/tsingma-bsp/src/ehci-ctc/ehci-ctc.c new file mode 100644 index 000000000000..458ef18dc3ff --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/ehci-ctc/ehci-ctc.c @@ -0,0 +1,423 @@ +/* + * Centec platform ehci driver + * + * Copyright 2018 Liuht + * + * Licensed under the GNU/GPL. See COPYING for details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ehci.h" + +#define DRIVER_DESC "Centec EHCI platform driver" +#define EHCI_MAX_CLKS 4 +#define EHCI_MAX_RSTS 4 +#define hcd_to_ehci_priv(h) ((struct ehci_ctc_priv *)hcd_to_ehci(h)->priv) + +struct ehci_ctc_priv { + struct clk *clks[EHCI_MAX_CLKS]; + struct reset_control *rsts[EHCI_MAX_RSTS]; + struct phy **phys; + int num_phys; + bool reset_on_resume; +}; + +static const char hcd_name[] = "ehci-ctc"; + +static int ehci_ctc_reset(struct usb_hcd *hcd) +{ + struct platform_device *pdev = to_platform_device(hcd->self.controller); + struct usb_ehci_pdata *pdata = dev_get_platdata(&pdev->dev); + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + int retval; + + ehci->has_synopsys_hc_bug = pdata->has_synopsys_hc_bug; + + if (pdata->pre_setup) { + retval = pdata->pre_setup(hcd); + if (retval < 0) + return retval; + } + + ehci->caps = hcd->regs + pdata->caps_offset; + retval = ehci_setup(hcd); + if (retval) + return retval; + + if (pdata->no_io_watchdog) + ehci->need_io_watchdog = 0; + return 0; +} + +static int ehci_ctc_power_on(struct platform_device *dev) +{ + struct usb_hcd *hcd = platform_get_drvdata(dev); + struct ehci_ctc_priv *priv = hcd_to_ehci_priv(hcd); + int clk, ret, phy_num; + + for (clk = 0; clk < EHCI_MAX_CLKS && priv->clks[clk]; clk++) { + ret = clk_prepare_enable(priv->clks[clk]); + if (ret) + goto err_disable_clks; + } + + for (phy_num = 0; phy_num < priv->num_phys; phy_num++) { + ret = phy_init(priv->phys[phy_num]); + if (ret) + goto err_exit_phy; + ret = phy_power_on(priv->phys[phy_num]); + if (ret) { + phy_exit(priv->phys[phy_num]); + goto err_exit_phy; + } + } + + return 0; + +err_exit_phy: + while (--phy_num >= 0) { + phy_power_off(priv->phys[phy_num]); + phy_exit(priv->phys[phy_num]); + } +err_disable_clks: + while (--clk >= 0) + clk_disable_unprepare(priv->clks[clk]); + + return ret; +} + +static void ehci_ctc_power_off(struct platform_device *dev) +{ + struct usb_hcd *hcd = platform_get_drvdata(dev); + struct ehci_ctc_priv *priv = hcd_to_ehci_priv(hcd); + int clk, phy_num; + + for (phy_num = 0; phy_num < priv->num_phys; phy_num++) { + phy_power_off(priv->phys[phy_num]); + phy_exit(priv->phys[phy_num]); + } + + for (clk = EHCI_MAX_CLKS - 1; clk >= 0; clk--) + if (priv->clks[clk]) + clk_disable_unprepare(priv->clks[clk]); +} + +static struct hc_driver __read_mostly ehci_ctc_hc_driver; + +static const struct ehci_driver_overrides platform_overrides __initconst = { + .reset = ehci_ctc_reset, + .extra_priv_size = sizeof(struct ehci_ctc_priv), +}; + +static struct usb_ehci_pdata ehci_ctc_defaults = { + .caps_offset = 0x100, + .dma_mask_64 = 1, + .power_on = ehci_ctc_power_on, + .power_suspend = ehci_ctc_power_off, + .power_off = ehci_ctc_power_off, +}; + +#define KERN_CTC KERN_ERR +static int ehci_ctc_probe(struct platform_device *dev) +{ + struct usb_hcd *hcd; + struct resource *res_mem; + struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev); + struct ehci_ctc_priv *priv; + struct ehci_hcd *ehci; + int err, irq, phy_num, clk = 0, rst; + + if (usb_disabled()) + return -ENODEV; + + /* + * Use reasonable defaults so platforms don't have to provide these + * with DT probing on ARM. + */ + if (!pdata) + pdata = &ehci_ctc_defaults; + + err = dma_coerce_mask_and_coherent(&dev->dev, + pdata->dma_mask_64 ? + DMA_BIT_MASK(64) : DMA_BIT_MASK(32)); + if (err) { + dev_err(&dev->dev, "Error: DMA mask configuration failed\n"); + return err; + } + + irq = platform_get_irq(dev, 0); + if (irq < 0) { + dev_err(&dev->dev, "no irq provided"); + return irq; + } + + hcd = usb_create_hcd(&ehci_ctc_hc_driver, &dev->dev, + dev_name(&dev->dev)); + if (!hcd) + return -ENOMEM; + + platform_set_drvdata(dev, hcd); + dev->dev.platform_data = pdata; + priv = hcd_to_ehci_priv(hcd); + ehci = hcd_to_ehci(hcd); + if (pdata == &ehci_ctc_defaults && dev->dev.of_node) { + if (of_property_read_bool(dev->dev.of_node, "big-endian-regs")) + ehci->big_endian_mmio = 1; + + if (of_property_read_bool(dev->dev.of_node, "big-endian-desc")) + ehci->big_endian_desc = 1; + + if (of_property_read_bool(dev->dev.of_node, "big-endian")) + ehci->big_endian_mmio = ehci->big_endian_desc = 1; + + if (of_property_read_bool(dev->dev.of_node, + "needs-reset-on-resume")) + priv->reset_on_resume = true; + + if (of_property_read_bool(dev->dev.of_node, + "has-transaction-translator")) + hcd->has_tt = 1; + + priv->num_phys = of_count_phandle_with_args(dev->dev.of_node, + "phys", + "#phy-cells"); + + if (priv->num_phys > 0) { + priv->phys = devm_kcalloc(&dev->dev, priv->num_phys, + sizeof(struct phy *), + GFP_KERNEL); + if (!priv->phys) + return -ENOMEM; + } else + priv->num_phys = 0; + + for (phy_num = 0; phy_num < priv->num_phys; phy_num++) { + priv->phys[phy_num] = + devm_of_phy_get_by_index(&dev->dev, + dev->dev.of_node, phy_num); + if (IS_ERR(priv->phys[phy_num])) { + err = PTR_ERR(priv->phys[phy_num]); + goto err_put_hcd; + } + } + + for (clk = 0; clk < EHCI_MAX_CLKS; clk++) { + priv->clks[clk] = of_clk_get(dev->dev.of_node, clk); + if (IS_ERR(priv->clks[clk])) { + err = PTR_ERR(priv->clks[clk]); + if (err == -EPROBE_DEFER) + goto err_put_clks; + priv->clks[clk] = NULL; + break; + } + } + } + for (rst = 0; rst < EHCI_MAX_RSTS; rst++) { + priv->rsts[rst] = + devm_reset_control_get_shared_by_index(&dev->dev, rst); + if (IS_ERR(priv->rsts[rst])) { + err = PTR_ERR(priv->rsts[rst]); + if (err == -EPROBE_DEFER) + goto err_reset; + priv->rsts[rst] = NULL; + break; + } + + err = reset_control_deassert(priv->rsts[rst]); + if (err) + goto err_reset; + } + if (pdata->big_endian_desc) + ehci->big_endian_desc = 1; + if (pdata->big_endian_mmio) + ehci->big_endian_mmio = 1; + if (pdata->has_tt) + hcd->has_tt = 1; + if (pdata->reset_on_resume) + priv->reset_on_resume = true; + +#ifndef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO + if (ehci->big_endian_mmio) { + dev_err(&dev->dev, + "Error: CONFIG_USB_EHCI_BIG_ENDIAN_MMIO not set\n"); + err = -EINVAL; + goto err_reset; + } +#endif +#ifndef CONFIG_USB_EHCI_BIG_ENDIAN_DESC + if (ehci->big_endian_desc) { + dev_err(&dev->dev, + "Error: CONFIG_USB_EHCI_BIG_ENDIAN_DESC not set\n"); + err = -EINVAL; + goto err_reset; + } +#endif + + if (pdata->power_on) { + err = pdata->power_on(dev); + if (err < 0) + goto err_reset; + } + res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0); + hcd->regs = devm_ioremap_resource(&dev->dev, res_mem); + if (IS_ERR(hcd->regs)) { + err = PTR_ERR(hcd->regs); + goto err_power; + } + hcd->rsrc_start = res_mem->start; + hcd->rsrc_len = resource_size(res_mem); + err = usb_add_hcd(hcd, irq, IRQF_SHARED); + if (err) + goto err_power; + device_wakeup_enable(hcd->self.controller); + platform_set_drvdata(dev, hcd); + return err; + +err_power: + if (pdata->power_off) + pdata->power_off(dev); +err_reset: + while (--rst >= 0) + reset_control_assert(priv->rsts[rst]); +err_put_clks: + while (--clk >= 0) + clk_put(priv->clks[clk]); +err_put_hcd: + if (pdata == &ehci_ctc_defaults) + dev->dev.platform_data = NULL; + + usb_put_hcd(hcd); + + return err; +} + +static int ehci_ctc_remove(struct platform_device *dev) +{ + struct usb_hcd *hcd = platform_get_drvdata(dev); + struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev); + struct ehci_ctc_priv *priv = hcd_to_ehci_priv(hcd); + int clk, rst; + + usb_remove_hcd(hcd); + + if (pdata->power_off) + pdata->power_off(dev); + + for (rst = 0; rst < EHCI_MAX_RSTS && priv->rsts[rst]; rst++) + reset_control_assert(priv->rsts[rst]); + + for (clk = 0; clk < EHCI_MAX_CLKS && priv->clks[clk]; clk++) + clk_put(priv->clks[clk]); + + usb_put_hcd(hcd); + + if (pdata == &ehci_ctc_defaults) + dev->dev.platform_data = NULL; + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int ehci_ctc_suspend(struct device *dev) +{ + struct usb_hcd *hcd = dev_get_drvdata(dev); + struct usb_ehci_pdata *pdata = dev_get_platdata(dev); + struct platform_device *pdev = to_platform_device(dev); + bool do_wakeup = device_may_wakeup(dev); + int ret; + + ret = ehci_suspend(hcd, do_wakeup); + if (ret) + return ret; + + if (pdata->power_suspend) + pdata->power_suspend(pdev); + + return ret; +} + +static int ehci_ctc_resume(struct device *dev) +{ + struct usb_hcd *hcd = dev_get_drvdata(dev); + struct usb_ehci_pdata *pdata = dev_get_platdata(dev); + struct platform_device *pdev = to_platform_device(dev); + struct ehci_ctc_priv *priv = hcd_to_ehci_priv(hcd); + + if (pdata->power_on) { + int err = pdata->power_on(pdev); + + if (err < 0) + return err; + } + + ehci_resume(hcd, priv->reset_on_resume); + return 0; +} +#endif /* CONFIG_PM_SLEEP */ + +static const struct of_device_id ctc_ehci_ids[] = { + {.compatible = "ctc-ehci",}, + {} +}; + +MODULE_DEVICE_TABLE(of, ctc_ehci_ids); + +static const struct platform_device_id ehci_ctc_table[] = { + {"ehci-ctc", 0}, + {} +}; + +MODULE_DEVICE_TABLE(platform, ehci_ctc_table); + +static SIMPLE_DEV_PM_OPS(ehci_ctc_pm_ops, ehci_ctc_suspend, ehci_ctc_resume); + +static struct platform_driver ehci_ctc_driver = { + .id_table = ehci_ctc_table, + .probe = ehci_ctc_probe, + .remove = ehci_ctc_remove, + .shutdown = usb_hcd_platform_shutdown, + .driver = { + .name = "ehci-ctc", + .pm = &ehci_ctc_pm_ops, + .of_match_table = ctc_ehci_ids, + } +}; + +static int __init ehci_ctc_init(void) +{ + if (usb_disabled()) + return -ENODEV; + + pr_info("%s: " DRIVER_DESC "\n", hcd_name); + + ehci_init_driver(&ehci_ctc_hc_driver, &platform_overrides); + return platform_driver_register(&ehci_ctc_driver); +} + +module_init(ehci_ctc_init); + +static void __exit ehci_ctc_cleanup(void) +{ + platform_driver_unregister(&ehci_ctc_driver); +} + +module_exit(ehci_ctc_cleanup); + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR("Hauke Mehrtens"); +MODULE_AUTHOR("Alan Stern"); +MODULE_LICENSE("GPL"); diff --git a/platform/centec-arm64/tsingma-bsp/src/ehci-ctc/ehci.h b/platform/centec-arm64/tsingma-bsp/src/ehci-ctc/ehci.h new file mode 100644 index 000000000000..c8e9a48e1d51 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/ehci-ctc/ehci.h @@ -0,0 +1,894 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2001-2002 by David Brownell + */ + +#ifndef __LINUX_EHCI_HCD_H +#define __LINUX_EHCI_HCD_H + +/* definitions used for the EHCI driver */ + +/* + * __hc32 and __hc16 are "Host Controller" types, they may be equivalent to + * __leXX (normally) or __beXX (given EHCI_BIG_ENDIAN_DESC), depending on + * the host controller implementation. + * + * To facilitate the strongest possible byte-order checking from "sparse" + * and so on, we use __leXX unless that's not practical. + */ +#ifdef CONFIG_USB_EHCI_BIG_ENDIAN_DESC +typedef __u32 __bitwise __hc32; +typedef __u16 __bitwise __hc16; +#else +#define __hc32 __le32 +#define __hc16 __le16 +#endif + +/* statistics can be kept for tuning/monitoring */ +#ifdef CONFIG_DYNAMIC_DEBUG +#define EHCI_STATS +#endif + +struct ehci_stats { + /* irq usage */ + unsigned long normal; + unsigned long error; + unsigned long iaa; + unsigned long lost_iaa; + + /* termination of urbs from core */ + unsigned long complete; + unsigned long unlink; +}; + +/* + * Scheduling and budgeting information for periodic transfers, for both + * high-speed devices and full/low-speed devices lying behind a TT. + */ +struct ehci_per_sched { + struct usb_device *udev; /* access to the TT */ + struct usb_host_endpoint *ep; + struct list_head ps_list; /* node on ehci_tt's ps_list */ + u16 tt_usecs; /* time on the FS/LS bus */ + u16 cs_mask; /* C-mask and S-mask bytes */ + u16 period; /* actual period in frames */ + u16 phase; /* actual phase, frame part */ + u8 bw_phase; /* same, for bandwidth + reservation */ + u8 phase_uf; /* uframe part of the phase */ + u8 usecs, c_usecs; /* times on the HS bus */ + u8 bw_uperiod; /* period in microframes, for + bandwidth reservation */ + u8 bw_period; /* same, in frames */ +}; +#define NO_FRAME 29999 /* frame not assigned yet */ + +/* ehci_hcd->lock guards shared data against other CPUs: + * ehci_hcd: async, unlink, periodic (and shadow), ... + * usb_host_endpoint: hcpriv + * ehci_qh: qh_next, qtd_list + * ehci_qtd: qtd_list + * + * Also, hold this lock when talking to HC registers or + * when updating hw_* fields in shared qh/qtd/... structures. + */ + +#define EHCI_MAX_ROOT_PORTS 15 /* see HCS_N_PORTS */ + +/* + * ehci_rh_state values of EHCI_RH_RUNNING or above mean that the + * controller may be doing DMA. Lower values mean there's no DMA. + */ +enum ehci_rh_state { + EHCI_RH_HALTED, + EHCI_RH_SUSPENDED, + EHCI_RH_RUNNING, + EHCI_RH_STOPPING +}; + +/* + * Timer events, ordered by increasing delay length. + * Always update event_delays_ns[] and event_handlers[] (defined in + * ehci-timer.c) in parallel with this list. + */ +enum ehci_hrtimer_event { + EHCI_HRTIMER_POLL_ASS, /* Poll for async schedule off */ + EHCI_HRTIMER_POLL_PSS, /* Poll for periodic schedule off */ + EHCI_HRTIMER_POLL_DEAD, /* Wait for dead controller to stop */ + EHCI_HRTIMER_UNLINK_INTR, /* Wait for interrupt QH unlink */ + EHCI_HRTIMER_FREE_ITDS, /* Wait for unused iTDs and siTDs */ + EHCI_HRTIMER_ACTIVE_UNLINK, /* Wait while unlinking an active QH */ + EHCI_HRTIMER_START_UNLINK_INTR, /* Unlink empty interrupt QHs */ + EHCI_HRTIMER_ASYNC_UNLINKS, /* Unlink empty async QHs */ + EHCI_HRTIMER_IAA_WATCHDOG, /* Handle lost IAA interrupts */ + EHCI_HRTIMER_DISABLE_PERIODIC, /* Wait to disable periodic sched */ + EHCI_HRTIMER_DISABLE_ASYNC, /* Wait to disable async sched */ + EHCI_HRTIMER_IO_WATCHDOG, /* Check for missing IRQs */ + EHCI_HRTIMER_NUM_EVENTS /* Must come last */ +}; +#define EHCI_HRTIMER_NO_EVENT 99 + +struct ehci_hcd { /* one per controller */ + /* timing support */ + enum ehci_hrtimer_event next_hrtimer_event; + unsigned enabled_hrtimer_events; + ktime_t hr_timeouts[EHCI_HRTIMER_NUM_EVENTS]; + struct hrtimer hrtimer; + + int PSS_poll_count; + int ASS_poll_count; + int died_poll_count; + + /* glue to PCI and HCD framework */ + struct ehci_caps __iomem *caps; + struct ehci_regs __iomem *regs; + struct ehci_dbg_port __iomem *debug; + + __u32 hcs_params; /* cached register copy */ + spinlock_t lock; + enum ehci_rh_state rh_state; + + /* general schedule support */ + bool scanning:1; + bool need_rescan:1; + bool intr_unlinking:1; + bool iaa_in_progress:1; + bool async_unlinking:1; + bool shutdown:1; + struct ehci_qh *qh_scan_next; + + /* async schedule support */ + struct ehci_qh *async; + struct ehci_qh *dummy; /* For AMD quirk use */ + struct list_head async_unlink; + struct list_head async_idle; + unsigned async_unlink_cycle; + unsigned async_count; /* async activity count */ + __hc32 old_current; /* Test for QH becoming */ + __hc32 old_token; /* inactive during unlink */ + + /* periodic schedule support */ +#define DEFAULT_I_TDPS 1024 /* some HCs can do less */ + unsigned periodic_size; + __hc32 *periodic; /* hw periodic table */ + dma_addr_t periodic_dma; + struct list_head intr_qh_list; + unsigned i_thresh; /* uframes HC might cache */ + + union ehci_shadow *pshadow; /* mirror hw periodic table */ + struct list_head intr_unlink_wait; + struct list_head intr_unlink; + unsigned intr_unlink_wait_cycle; + unsigned intr_unlink_cycle; + unsigned now_frame; /* frame from HC hardware */ + unsigned last_iso_frame; /* last frame scanned for iso */ + unsigned intr_count; /* intr activity count */ + unsigned isoc_count; /* isoc activity count */ + unsigned periodic_count; /* periodic activity count */ + unsigned uframe_periodic_max; /* max periodic time per uframe */ + + + /* list of itds & sitds completed while now_frame was still active */ + struct list_head cached_itd_list; + struct ehci_itd *last_itd_to_free; + struct list_head cached_sitd_list; + struct ehci_sitd *last_sitd_to_free; + + /* per root hub port */ + unsigned long reset_done[EHCI_MAX_ROOT_PORTS]; + + /* bit vectors (one bit per port) */ + unsigned long bus_suspended; /* which ports were + already suspended at the start of a bus suspend */ + unsigned long companion_ports; /* which ports are + dedicated to the companion controller */ + unsigned long owned_ports; /* which ports are + owned by the companion during a bus suspend */ + unsigned long port_c_suspend; /* which ports have + the change-suspend feature turned on */ + unsigned long suspended_ports; /* which ports are + suspended */ + unsigned long resuming_ports; /* which ports have + started to resume */ + + /* per-HC memory pools (could be per-bus, but ...) */ + struct dma_pool *qh_pool; /* qh per active urb */ + struct dma_pool *qtd_pool; /* one or more per qh */ + struct dma_pool *itd_pool; /* itd per iso urb */ + struct dma_pool *sitd_pool; /* sitd per split iso urb */ + + unsigned random_frame; + unsigned long next_statechange; + ktime_t last_periodic_enable; + u32 command; + + /* SILICON QUIRKS */ + unsigned no_selective_suspend:1; + unsigned has_fsl_port_bug:1; /* FreeScale */ + unsigned has_fsl_hs_errata:1; /* Freescale HS quirk */ + unsigned has_fsl_susp_errata:1; /* NXP SUSP quirk */ + unsigned big_endian_mmio:1; + unsigned big_endian_desc:1; + unsigned big_endian_capbase:1; + unsigned has_amcc_usb23:1; + unsigned need_io_watchdog:1; + unsigned amd_pll_fix:1; + unsigned use_dummy_qh:1; /* AMD Frame List table quirk*/ + unsigned has_synopsys_hc_bug:1; /* Synopsys HC */ + unsigned frame_index_bug:1; /* MosChip (AKA NetMos) */ + unsigned need_oc_pp_cycle:1; /* MPC834X port power */ + unsigned imx28_write_fix:1; /* For Freescale i.MX28 */ + + /* required for usb32 quirk */ + #define OHCI_CTRL_HCFS (3 << 6) + #define OHCI_USB_OPER (2 << 6) + #define OHCI_USB_SUSPEND (3 << 6) + + #define OHCI_HCCTRL_OFFSET 0x4 + #define OHCI_HCCTRL_LEN 0x4 + __hc32 *ohci_hcctrl_reg; + unsigned has_hostpc:1; + unsigned has_tdi_phy_lpm:1; + unsigned has_ppcd:1; /* support per-port change bits */ + u8 sbrn; /* packed release number */ + + /* irq statistics */ +#ifdef EHCI_STATS + struct ehci_stats stats; +# define COUNT(x) ((x)++) +#else +# define COUNT(x) +#endif + + /* debug files */ +#ifdef CONFIG_DYNAMIC_DEBUG + struct dentry *debug_dir; +#endif + + /* bandwidth usage */ +#define EHCI_BANDWIDTH_SIZE 64 +#define EHCI_BANDWIDTH_FRAMES (EHCI_BANDWIDTH_SIZE >> 3) + u8 bandwidth[EHCI_BANDWIDTH_SIZE]; + /* us allocated per uframe */ + u8 tt_budget[EHCI_BANDWIDTH_SIZE]; + /* us budgeted per uframe */ + struct list_head tt_list; + + /* platform-specific data -- must come last */ + unsigned long priv[0] __aligned(sizeof(s64)); +}; + +/* convert between an HCD pointer and the corresponding EHCI_HCD */ +static inline struct ehci_hcd *hcd_to_ehci(struct usb_hcd *hcd) +{ + return (struct ehci_hcd *) (hcd->hcd_priv); +} +static inline struct usb_hcd *ehci_to_hcd(struct ehci_hcd *ehci) +{ + return container_of((void *) ehci, struct usb_hcd, hcd_priv); +} + +/*-------------------------------------------------------------------------*/ + +#include + +/*-------------------------------------------------------------------------*/ + +#define QTD_NEXT(ehci, dma) cpu_to_hc32(ehci, (u32)dma) + +/* + * EHCI Specification 0.95 Section 3.5 + * QTD: describe data transfer components (buffer, direction, ...) + * See Fig 3-6 "Queue Element Transfer Descriptor Block Diagram". + * + * These are associated only with "QH" (Queue Head) structures, + * used with control, bulk, and interrupt transfers. + */ +struct ehci_qtd { + /* first part defined by EHCI spec */ + __hc32 hw_next; /* see EHCI 3.5.1 */ + __hc32 hw_alt_next; /* see EHCI 3.5.2 */ + __hc32 hw_token; /* see EHCI 3.5.3 */ +#define QTD_TOGGLE (1 << 31) /* data toggle */ +#define QTD_LENGTH(tok) (((tok)>>16) & 0x7fff) +#define QTD_IOC (1 << 15) /* interrupt on complete */ +#define QTD_CERR(tok) (((tok)>>10) & 0x3) +#define QTD_PID(tok) (((tok)>>8) & 0x3) +#define QTD_STS_ACTIVE (1 << 7) /* HC may execute this */ +#define QTD_STS_HALT (1 << 6) /* halted on error */ +#define QTD_STS_DBE (1 << 5) /* data buffer error (in HC) */ +#define QTD_STS_BABBLE (1 << 4) /* device was babbling (qtd halted) */ +#define QTD_STS_XACT (1 << 3) /* device gave illegal response */ +#define QTD_STS_MMF (1 << 2) /* incomplete split transaction */ +#define QTD_STS_STS (1 << 1) /* split transaction state */ +#define QTD_STS_PING (1 << 0) /* issue PING? */ + +#define ACTIVE_BIT(ehci) cpu_to_hc32(ehci, QTD_STS_ACTIVE) +#define HALT_BIT(ehci) cpu_to_hc32(ehci, QTD_STS_HALT) +#define STATUS_BIT(ehci) cpu_to_hc32(ehci, QTD_STS_STS) + + __hc32 hw_buf[5]; /* see EHCI 3.5.4 */ + __hc32 hw_buf_hi[5]; /* Appendix B */ + + /* the rest is HCD-private */ + dma_addr_t qtd_dma; /* qtd address */ + struct list_head qtd_list; /* sw qtd list */ + struct urb *urb; /* qtd's urb */ + size_t length; /* length of buffer */ +} __aligned(32); + +/* mask NakCnt+T in qh->hw_alt_next */ +#define QTD_MASK(ehci) cpu_to_hc32(ehci, ~0x1f) + +#define IS_SHORT_READ(token) (QTD_LENGTH(token) != 0 && QTD_PID(token) == 1) + +/*-------------------------------------------------------------------------*/ + +/* type tag from {qh,itd,sitd,fstn}->hw_next */ +#define Q_NEXT_TYPE(ehci, dma) ((dma) & cpu_to_hc32(ehci, 3 << 1)) + +/* + * Now the following defines are not converted using the + * cpu_to_le32() macro anymore, since we have to support + * "dynamic" switching between be and le support, so that the driver + * can be used on one system with SoC EHCI controller using big-endian + * descriptors as well as a normal little-endian PCI EHCI controller. + */ +/* values for that type tag */ +#define Q_TYPE_ITD (0 << 1) +#define Q_TYPE_QH (1 << 1) +#define Q_TYPE_SITD (2 << 1) +#define Q_TYPE_FSTN (3 << 1) + +/* next async queue entry, or pointer to interrupt/periodic QH */ +#define QH_NEXT(ehci, dma) \ + (cpu_to_hc32(ehci, (((u32) dma) & ~0x01f) | Q_TYPE_QH)) + +/* for periodic/async schedules and qtd lists, mark end of list */ +#define EHCI_LIST_END(ehci) cpu_to_hc32(ehci, 1) /* "null pointer" to hw */ + +/* + * Entries in periodic shadow table are pointers to one of four kinds + * of data structure. That's dictated by the hardware; a type tag is + * encoded in the low bits of the hardware's periodic schedule. Use + * Q_NEXT_TYPE to get the tag. + * + * For entries in the async schedule, the type tag always says "qh". + */ +union ehci_shadow { + struct ehci_qh *qh; /* Q_TYPE_QH */ + struct ehci_itd *itd; /* Q_TYPE_ITD */ + struct ehci_sitd *sitd; /* Q_TYPE_SITD */ + struct ehci_fstn *fstn; /* Q_TYPE_FSTN */ + __hc32 *hw_next; /* (all types) */ + void *ptr; +}; + +/*-------------------------------------------------------------------------*/ + +/* + * EHCI Specification 0.95 Section 3.6 + * QH: describes control/bulk/interrupt endpoints + * See Fig 3-7 "Queue Head Structure Layout". + * + * These appear in both the async and (for interrupt) periodic schedules. + */ + +/* first part defined by EHCI spec */ +struct ehci_qh_hw { + __hc32 hw_next; /* see EHCI 3.6.1 */ + __hc32 hw_info1; /* see EHCI 3.6.2 */ +#define QH_CONTROL_EP (1 << 27) /* FS/LS control endpoint */ +#define QH_HEAD (1 << 15) /* Head of async reclamation list */ +#define QH_TOGGLE_CTL (1 << 14) /* Data toggle control */ +#define QH_HIGH_SPEED (2 << 12) /* Endpoint speed */ +#define QH_LOW_SPEED (1 << 12) +#define QH_FULL_SPEED (0 << 12) +#define QH_INACTIVATE (1 << 7) /* Inactivate on next transaction */ + __hc32 hw_info2; /* see EHCI 3.6.2 */ +#define QH_SMASK 0x000000ff +#define QH_CMASK 0x0000ff00 +#define QH_HUBADDR 0x007f0000 +#define QH_HUBPORT 0x3f800000 +#define QH_MULT 0xc0000000 + __hc32 hw_current; /* qtd list - see EHCI 3.6.4 */ + + /* qtd overlay (hardware parts of a struct ehci_qtd) */ + __hc32 hw_qtd_next; + __hc32 hw_alt_next; + __hc32 hw_token; + __hc32 hw_buf[5]; + __hc32 hw_buf_hi[5]; +} __aligned(32); + +struct ehci_qh { + struct ehci_qh_hw *hw; /* Must come first */ + /* the rest is HCD-private */ + dma_addr_t qh_dma; /* address of qh */ + union ehci_shadow qh_next; /* ptr to qh; or periodic */ + struct list_head qtd_list; /* sw qtd list */ + struct list_head intr_node; /* list of intr QHs */ + struct ehci_qtd *dummy; + struct list_head unlink_node; + struct ehci_per_sched ps; /* scheduling info */ + + unsigned unlink_cycle; + + u8 qh_state; +#define QH_STATE_LINKED 1 /* HC sees this */ +#define QH_STATE_UNLINK 2 /* HC may still see this */ +#define QH_STATE_IDLE 3 /* HC doesn't see this */ +#define QH_STATE_UNLINK_WAIT 4 /* LINKED and on unlink q */ +#define QH_STATE_COMPLETING 5 /* don't touch token.HALT */ + + u8 xacterrs; /* XactErr retry counter */ +#define QH_XACTERR_MAX 32 /* XactErr retry limit */ + + u8 unlink_reason; +#define QH_UNLINK_HALTED 0x01 /* Halt flag is set */ +#define QH_UNLINK_SHORT_READ 0x02 /* Recover from a short read */ +#define QH_UNLINK_DUMMY_OVERLAY 0x04 /* QH overlayed the dummy TD */ +#define QH_UNLINK_SHUTDOWN 0x08 /* The HC isn't running */ +#define QH_UNLINK_QUEUE_EMPTY 0x10 /* Reached end of the queue */ +#define QH_UNLINK_REQUESTED 0x20 /* Disable, reset, or dequeue */ + + u8 gap_uf; /* uframes split/csplit gap */ + + unsigned is_out:1; /* bulk or intr OUT */ + unsigned clearing_tt:1; /* Clear-TT-Buf in progress */ + unsigned dequeue_during_giveback:1; + unsigned should_be_inactive:1; +}; + +/*-------------------------------------------------------------------------*/ + +/* description of one iso transaction (up to 3 KB data if highspeed) */ +struct ehci_iso_packet { + /* These will be copied to iTD when scheduling */ + u64 bufp; /* itd->hw_bufp{,_hi}[pg] |= */ + __hc32 transaction; /* itd->hw_transaction[i] |= */ + u8 cross; /* buf crosses pages */ + /* for full speed OUT splits */ + u32 buf1; +}; + +/* temporary schedule data for packets from iso urbs (both speeds) + * each packet is one logical usb transaction to the device (not TT), + * beginning at stream->next_uframe + */ +struct ehci_iso_sched { + struct list_head td_list; + unsigned span; + unsigned first_packet; + struct ehci_iso_packet packet[0]; +}; + +/* + * ehci_iso_stream - groups all (s)itds for this endpoint. + * acts like a qh would, if EHCI had them for ISO. + */ +struct ehci_iso_stream { + /* first field matches ehci_hq, but is NULL */ + struct ehci_qh_hw *hw; + + u8 bEndpointAddress; + u8 highspeed; + struct list_head td_list; /* queued itds/sitds */ + struct list_head free_list; /* list of unused itds/sitds */ + + /* output of (re)scheduling */ + struct ehci_per_sched ps; /* scheduling info */ + unsigned next_uframe; + __hc32 splits; + + /* the rest is derived from the endpoint descriptor, + * including the extra info for hw_bufp[0..2] + */ + u16 uperiod; /* period in uframes */ + u16 maxp; + unsigned bandwidth; + + /* This is used to initialize iTD's hw_bufp fields */ + __hc32 buf0; + __hc32 buf1; + __hc32 buf2; + + /* this is used to initialize sITD's tt info */ + __hc32 address; +}; + +/*-------------------------------------------------------------------------*/ + +/* + * EHCI Specification 0.95 Section 3.3 + * Fig 3-4 "Isochronous Transaction Descriptor (iTD)" + * + * Schedule records for high speed iso xfers + */ +struct ehci_itd { + /* first part defined by EHCI spec */ + __hc32 hw_next; /* see EHCI 3.3.1 */ + __hc32 hw_transaction[8]; /* see EHCI 3.3.2 */ +#define EHCI_ISOC_ACTIVE (1<<31) /* activate transfer this slot */ +#define EHCI_ISOC_BUF_ERR (1<<30) /* Data buffer error */ +#define EHCI_ISOC_BABBLE (1<<29) /* babble detected */ +#define EHCI_ISOC_XACTERR (1<<28) /* XactErr - transaction error */ +#define EHCI_ITD_LENGTH(tok) (((tok)>>16) & 0x0fff) +#define EHCI_ITD_IOC (1 << 15) /* interrupt on complete */ + +#define ITD_ACTIVE(ehci) cpu_to_hc32(ehci, EHCI_ISOC_ACTIVE) + + __hc32 hw_bufp[7]; /* see EHCI 3.3.3 */ + __hc32 hw_bufp_hi[7]; /* Appendix B */ + + /* the rest is HCD-private */ + dma_addr_t itd_dma; /* for this itd */ + union ehci_shadow itd_next; /* ptr to periodic q entry */ + + struct urb *urb; + struct ehci_iso_stream *stream; /* endpoint's queue */ + struct list_head itd_list; /* list of stream's itds */ + + /* any/all hw_transactions here may be used by that urb */ + unsigned frame; /* where scheduled */ + unsigned pg; + unsigned index[8]; /* in urb->iso_frame_desc */ +} __aligned(32); + +/*-------------------------------------------------------------------------*/ + +/* + * EHCI Specification 0.95 Section 3.4 + * siTD, aka split-transaction isochronous Transfer Descriptor + * ... describe full speed iso xfers through TT in hubs + * see Figure 3-5 "Split-transaction Isochronous Transaction Descriptor (siTD) + */ +struct ehci_sitd { + /* first part defined by EHCI spec */ + __hc32 hw_next; +/* uses bit field macros above - see EHCI 0.95 Table 3-8 */ + __hc32 hw_fullspeed_ep; /* EHCI table 3-9 */ + __hc32 hw_uframe; /* EHCI table 3-10 */ + __hc32 hw_results; /* EHCI table 3-11 */ +#define SITD_IOC (1 << 31) /* interrupt on completion */ +#define SITD_PAGE (1 << 30) /* buffer 0/1 */ +#define SITD_LENGTH(x) (((x) >> 16) & 0x3ff) +#define SITD_STS_ACTIVE (1 << 7) /* HC may execute this */ +#define SITD_STS_ERR (1 << 6) /* error from TT */ +#define SITD_STS_DBE (1 << 5) /* data buffer error (in HC) */ +#define SITD_STS_BABBLE (1 << 4) /* device was babbling */ +#define SITD_STS_XACT (1 << 3) /* illegal IN response */ +#define SITD_STS_MMF (1 << 2) /* incomplete split transaction */ +#define SITD_STS_STS (1 << 1) /* split transaction state */ + +#define SITD_ACTIVE(ehci) cpu_to_hc32(ehci, SITD_STS_ACTIVE) + + __hc32 hw_buf[2]; /* EHCI table 3-12 */ + __hc32 hw_backpointer; /* EHCI table 3-13 */ + __hc32 hw_buf_hi[2]; /* Appendix B */ + + /* the rest is HCD-private */ + dma_addr_t sitd_dma; + union ehci_shadow sitd_next; /* ptr to periodic q entry */ + + struct urb *urb; + struct ehci_iso_stream *stream; /* endpoint's queue */ + struct list_head sitd_list; /* list of stream's sitds */ + unsigned frame; + unsigned index; +} __aligned(32); + +/*-------------------------------------------------------------------------*/ + +/* + * EHCI Specification 0.96 Section 3.7 + * Periodic Frame Span Traversal Node (FSTN) + * + * Manages split interrupt transactions (using TT) that span frame boundaries + * into uframes 0/1; see 4.12.2.2. In those uframes, a "save place" FSTN + * makes the HC jump (back) to a QH to scan for fs/ls QH completions until + * it hits a "restore" FSTN; then it returns to finish other uframe 0/1 work. + */ +struct ehci_fstn { + __hc32 hw_next; /* any periodic q entry */ + __hc32 hw_prev; /* qh or EHCI_LIST_END */ + + /* the rest is HCD-private */ + dma_addr_t fstn_dma; + union ehci_shadow fstn_next; /* ptr to periodic q entry */ +} __aligned(32); + +/*-------------------------------------------------------------------------*/ + +/* + * USB-2.0 Specification Sections 11.14 and 11.18 + * Scheduling and budgeting split transactions using TTs + * + * A hub can have a single TT for all its ports, or multiple TTs (one for each + * port). The bandwidth and budgeting information for the full/low-speed bus + * below each TT is self-contained and independent of the other TTs or the + * high-speed bus. + * + * "Bandwidth" refers to the number of microseconds on the FS/LS bus allocated + * to an interrupt or isochronous endpoint for each frame. "Budget" refers to + * the best-case estimate of the number of full-speed bytes allocated to an + * endpoint for each microframe within an allocated frame. + * + * Removal of an endpoint invalidates a TT's budget. Instead of trying to + * keep an up-to-date record, we recompute the budget when it is needed. + */ + +struct ehci_tt { + u16 bandwidth[EHCI_BANDWIDTH_FRAMES]; + + struct list_head tt_list; /* List of all ehci_tt's */ + struct list_head ps_list; /* Items using this TT */ + struct usb_tt *usb_tt; + int tt_port; /* TT port number */ +}; + +/*-------------------------------------------------------------------------*/ + +/* Prepare the PORTSC wakeup flags during controller suspend/resume */ + +#define ehci_prepare_ports_for_controller_suspend(ehci, do_wakeup) \ + ehci_adjust_port_wakeup_flags(ehci, true, do_wakeup) + +#define ehci_prepare_ports_for_controller_resume(ehci) \ + ehci_adjust_port_wakeup_flags(ehci, false, false) + +/*-------------------------------------------------------------------------*/ + +#ifdef CONFIG_USB_EHCI_ROOT_HUB_TT + +/* + * Some EHCI controllers have a Transaction Translator built into the + * root hub. This is a non-standard feature. Each controller will need + * to add code to the following inline functions, and call them as + * needed (mostly in root hub code). + */ + +#define ehci_is_TDI(e) (ehci_to_hcd(e)->has_tt) + +/* Returns the speed of a device attached to a port on the root hub. */ +static inline unsigned int +ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc) +{ + if (ehci_is_TDI(ehci)) { + switch ((portsc >> (ehci->has_hostpc ? 25 : 26)) & 3) { + case 0: + return 0; + case 1: + return USB_PORT_STAT_LOW_SPEED; + case 2: + default: + return USB_PORT_STAT_HIGH_SPEED; + } + } + return USB_PORT_STAT_HIGH_SPEED; +} + +#else + +#define ehci_is_TDI(e) (0) + +#define ehci_port_speed(ehci, portsc) USB_PORT_STAT_HIGH_SPEED +#endif + +/*-------------------------------------------------------------------------*/ + +#ifdef CONFIG_PPC_83xx +/* Some Freescale processors have an erratum in which the TT + * port number in the queue head was 0..N-1 instead of 1..N. + */ +#define ehci_has_fsl_portno_bug(e) ((e)->has_fsl_port_bug) +#else +#define ehci_has_fsl_portno_bug(e) (0) +#endif + +#define PORTSC_FSL_PFSC 24 /* Port Force Full-Speed Connect */ + +#if defined(CONFIG_PPC_85xx) +/* Some Freescale processors have an erratum (USB A-005275) in which + * incoming packets get corrupted in HS mode + */ +#define ehci_has_fsl_hs_errata(e) ((e)->has_fsl_hs_errata) +#else +#define ehci_has_fsl_hs_errata(e) (0) +#endif + +/* + * Some Freescale/NXP processors have an erratum (USB A-005697) + * in which we need to wait for 10ms for bus to enter suspend mode + * after setting SUSP bit. + */ +#define ehci_has_fsl_susp_errata(e) ((e)->has_fsl_susp_errata) + +/* + * While most USB host controllers implement their registers in + * little-endian format, a minority (celleb companion chip) implement + * them in big endian format. + * + * This attempts to support either format at compile time without a + * runtime penalty, or both formats with the additional overhead + * of checking a flag bit. + * + * ehci_big_endian_capbase is a special quirk for controllers that + * implement the HC capability registers as separate registers and not + * as fields of a 32-bit register. + */ + +#ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO +#define ehci_big_endian_mmio(e) ((e)->big_endian_mmio) +#define ehci_big_endian_capbase(e) ((e)->big_endian_capbase) +#else +#define ehci_big_endian_mmio(e) 0 +#define ehci_big_endian_capbase(e) 0 +#endif + +/* + * Big-endian read/write functions are arch-specific. + * Other arches can be added if/when they're needed. + */ +#if defined(CONFIG_ARM) && defined(CONFIG_ARCH_IXP4XX) +#define readl_be(addr) __raw_readl((__force unsigned *)addr) +#define writel_be(val, addr) __raw_writel(val, (__force unsigned *)addr) +#endif + +static inline unsigned int ehci_readl(const struct ehci_hcd *ehci, + __u32 __iomem *regs) +{ +#ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO + return ehci_big_endian_mmio(ehci) ? + readl_be(regs) : + readl(regs); +#else + return readl(regs); +#endif +} + +#ifdef CONFIG_SOC_IMX28 +static inline void imx28_ehci_writel(const unsigned int val, + volatile __u32 __iomem *addr) +{ + __asm__ ("swp %0, %0, [%1]" : : "r"(val), "r"(addr)); +} +#else +static inline void imx28_ehci_writel(const unsigned int val, + volatile __u32 __iomem *addr) +{ +} +#endif +static inline void ehci_writel(const struct ehci_hcd *ehci, + const unsigned int val, __u32 __iomem *regs) +{ +#ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO + ehci_big_endian_mmio(ehci) ? + writel_be(val, regs) : + writel(val, regs); +#else + if (ehci->imx28_write_fix) + imx28_ehci_writel(val, regs); + else + writel(val, regs); +#endif +} + +/* + * On certain ppc-44x SoC there is a HW issue, that could only worked around with + * explicit suspend/operate of OHCI. This function hereby makes sense only on that arch. + * Other common bits are dependent on has_amcc_usb23 quirk flag. + */ +#ifdef CONFIG_44x +static inline void set_ohci_hcfs(struct ehci_hcd *ehci, int operational) +{ + u32 hc_control; + + hc_control = (readl_be(ehci->ohci_hcctrl_reg) & ~OHCI_CTRL_HCFS); + if (operational) + hc_control |= OHCI_USB_OPER; + else + hc_control |= OHCI_USB_SUSPEND; + + writel_be(hc_control, ehci->ohci_hcctrl_reg); + (void) readl_be(ehci->ohci_hcctrl_reg); +} +#else +static inline void set_ohci_hcfs(struct ehci_hcd *ehci, int operational) +{ } +#endif + +/*-------------------------------------------------------------------------*/ + +/* + * The AMCC 440EPx not only implements its EHCI registers in big-endian + * format, but also its DMA data structures (descriptors). + * + * EHCI controllers accessed through PCI work normally (little-endian + * everywhere), so we won't bother supporting a BE-only mode for now. + */ +#ifdef CONFIG_USB_EHCI_BIG_ENDIAN_DESC +#define ehci_big_endian_desc(e) ((e)->big_endian_desc) + +/* cpu to ehci */ +static inline __hc32 cpu_to_hc32(const struct ehci_hcd *ehci, const u32 x) +{ + return ehci_big_endian_desc(ehci) + ? (__force __hc32)cpu_to_be32(x) + : (__force __hc32)cpu_to_le32(x); +} + +/* ehci to cpu */ +static inline u32 hc32_to_cpu(const struct ehci_hcd *ehci, const __hc32 x) +{ + return ehci_big_endian_desc(ehci) + ? be32_to_cpu((__force __be32)x) + : le32_to_cpu((__force __le32)x); +} + +static inline u32 hc32_to_cpup(const struct ehci_hcd *ehci, const __hc32 *x) +{ + return ehci_big_endian_desc(ehci) + ? be32_to_cpup((__force __be32 *)x) + : le32_to_cpup((__force __le32 *)x); +} + +#else + +/* cpu to ehci */ +static inline __hc32 cpu_to_hc32(const struct ehci_hcd *ehci, const u32 x) +{ + return cpu_to_le32(x); +} + +/* ehci to cpu */ +static inline u32 hc32_to_cpu(const struct ehci_hcd *ehci, const __hc32 x) +{ + return le32_to_cpu(x); +} + +static inline u32 hc32_to_cpup(const struct ehci_hcd *ehci, const __hc32 *x) +{ + return le32_to_cpup(x); +} + +#endif + +/*-------------------------------------------------------------------------*/ + +#define ehci_dbg(ehci, fmt, args...) \ + dev_dbg(ehci_to_hcd(ehci)->self.controller, fmt, ## args) +#define ehci_err(ehci, fmt, args...) \ + dev_err(ehci_to_hcd(ehci)->self.controller, fmt, ## args) +#define ehci_info(ehci, fmt, args...) \ + dev_info(ehci_to_hcd(ehci)->self.controller, fmt, ## args) +#define ehci_warn(ehci, fmt, args...) \ + dev_warn(ehci_to_hcd(ehci)->self.controller, fmt, ## args) + +/*-------------------------------------------------------------------------*/ + +/* Declarations of things exported for use by ehci platform drivers */ + +struct ehci_driver_overrides { + size_t extra_priv_size; + int (*reset)(struct usb_hcd *hcd); + int (*port_power)(struct usb_hcd *hcd, + int portnum, bool enable); +}; + +extern void ehci_init_driver(struct hc_driver *drv, + const struct ehci_driver_overrides *over); +extern int ehci_setup(struct usb_hcd *hcd); +extern int ehci_handshake(struct ehci_hcd *ehci, void __iomem *ptr, + u32 mask, u32 done, int usec); +extern int ehci_reset(struct ehci_hcd *ehci); + +extern int ehci_suspend(struct usb_hcd *hcd, bool do_wakeup); +extern int ehci_resume(struct usb_hcd *hcd, bool force_reset); +extern void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci, + bool suspending, bool do_wakeup); + +extern int ehci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, + u16 wIndex, char *buf, u16 wLength); + +#endif /* __LINUX_EHCI_HCD_H */ diff --git a/platform/centec-arm64/tsingma-bsp/src/gpio-ctc/Makefile b/platform/centec-arm64/tsingma-bsp/src/gpio-ctc/Makefile new file mode 100644 index 000000000000..52d73b89e5a6 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/gpio-ctc/Makefile @@ -0,0 +1 @@ +obj-m = gpio-ctc.o diff --git a/platform/centec-arm64/tsingma-bsp/src/gpio-ctc/gpio-ctc.c b/platform/centec-arm64/tsingma-bsp/src/gpio-ctc/gpio-ctc.c new file mode 100644 index 000000000000..de310e02d210 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/gpio-ctc/gpio-ctc.c @@ -0,0 +1,558 @@ +/* + * Copyright (c) 2018 Liuht + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "gpio-ctcapb.h" +#include +#include "gpiolib.h" + +#define DWAPB_MAX_PORTS 2 + +struct ctcapb_gpio; + +struct ctcapb_gpio_port { + bool is_registered; + unsigned int idx; + struct gpio_chip gc; + struct ctcapb_gpio *gpio; + struct GpioSoc_port_regs *regs; + struct irq_domain *domain; +}; + +struct ctcapb_gpio { + struct device *dev; + unsigned int nr_ports; + struct GpioSoc_regs *regs; + struct ctcapb_gpio_port *ports; +}; + +static void clrsetbits(unsigned __iomem *addr, u32 clr, u32 set) +{ + writel((readl(addr) & ~(clr)) | (set), addr); +} + +static int ctcapb_gpio_to_irq(struct gpio_chip *gc, unsigned int offset) +{ + struct ctcapb_gpio_port *port = gpiochip_get_data(gc); + + return irq_find_mapping(port->domain, offset); +} + +static void ctcapb_toggle_trigger(struct ctcapb_gpio_port *port, + unsigned int offs) +{ + u32 v = readl(&port->regs->GpioIntrPolarity); + + if (gpio_get_value(port->gc.base + offs)) + v &= ~BIT(offs); + else + v |= BIT(offs); + + writel(v, &port->regs->GpioIntrPolarity); +} + +static u32 ctcapb_do_irq(struct ctcapb_gpio_port *port) +{ + u32 irq_status = readl_relaxed(&port->regs->GpioIntrStatus); + u32 ret = irq_status; + + while (irq_status) { + int hwirq = fls(irq_status) - 1; + int gpio_irq = irq_find_mapping(port->domain, hwirq); + + generic_handle_irq(gpio_irq); + irq_status &= ~BIT(hwirq); + + if ((irq_get_trigger_type(gpio_irq) & IRQ_TYPE_SENSE_MASK) + == IRQ_TYPE_EDGE_BOTH) + ctcapb_toggle_trigger(port, hwirq); + } + + return ret; +} + +static void ctcapb_irq_handler(struct irq_desc *desc) +{ + struct ctcapb_gpio_port *port = irq_desc_get_handler_data(desc); + struct irq_chip *chip = irq_desc_get_chip(desc); + + ctcapb_do_irq(port); + + if (chip->irq_eoi) + chip->irq_eoi(irq_desc_get_irq_data(desc)); +} + +static void ctcapb_irq_enable(struct irq_data *d) +{ + struct irq_chip_generic *igc = irq_data_get_irq_chip_data(d); + struct ctcapb_gpio_port *port = igc->private; + struct gpio_chip *gc = &port->gc; + unsigned long flags; + + spin_lock_irqsave(&gc->bgpio_lock, flags); + clrsetbits(&port->regs->GpioIntrEn, 0, BIT(d->hwirq)); + spin_unlock_irqrestore(&gc->bgpio_lock, flags); +} + +extern void irq_gc_mask_clr_bit(struct irq_data *d); + +static void ctcapb_irq_unmask(struct irq_data *d) +{ + irq_gc_mask_clr_bit(d); + ctcapb_irq_enable(d); +} + +static int ctcapb_irq_reqres(struct irq_data *d) +{ + struct irq_chip_generic *igc = irq_data_get_irq_chip_data(d); + struct ctcapb_gpio_port *port = igc->private; + struct gpio_chip *gc = &port->gc; + + if (gpiochip_lock_as_irq(gc, irqd_to_hwirq(d))) { + dev_err(port->gpio->dev, "unable to lock HW IRQ %lu for IRQ\n", + irqd_to_hwirq(d)); + return -EINVAL; + } + return 0; +} + +static void ctcapb_irq_relres(struct irq_data *d) +{ + struct irq_chip_generic *igc = irq_data_get_irq_chip_data(d); + struct ctcapb_gpio_port *port = igc->private; + struct gpio_chip *gc = &port->gc; + + gpiochip_unlock_as_irq(gc, irqd_to_hwirq(d)); +} + +static int ctcapb_irq_set_type(struct irq_data *d, u32 type) +{ + struct irq_chip_generic *igc = irq_data_get_irq_chip_data(d); + struct ctcapb_gpio_port *port = igc->private; + struct gpio_chip *gc = &port->gc; + int bit = d->hwirq; + unsigned long level, polarity, flags; + + if (type & ~(IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | + IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) + return -EINVAL; + + spin_lock_irqsave(&gc->bgpio_lock, flags); + level = readl(&port->regs->GpioIntrLevel); + polarity = readl(&port->regs->GpioIntrPolarity); + + switch (type) { + case IRQ_TYPE_EDGE_BOTH: + level &= ~BIT(bit); + ctcapb_toggle_trigger(port, bit); + break; + case IRQ_TYPE_EDGE_RISING: + level &= ~BIT(bit); + polarity |= BIT(bit); + break; + case IRQ_TYPE_EDGE_FALLING: + level &= ~BIT(bit); + polarity &= ~BIT(bit); + break; + case IRQ_TYPE_LEVEL_HIGH: + level |= BIT(bit); + polarity |= BIT(bit); + break; + case IRQ_TYPE_LEVEL_LOW: + level |= BIT(bit); + polarity &= ~BIT(bit); + break; + } + + irq_setup_alt_chip(d, type); + + writel(level, &port->regs->GpioIntrLevel); + writel(polarity, &port->regs->GpioIntrPolarity); + spin_unlock_irqrestore(&gc->bgpio_lock, flags); + + return 0; +} + +static int ctcapb_gpio_set_debounce(struct gpio_chip *gc, + unsigned int offset, unsigned int debounce) +{ + struct ctcapb_gpio_port *port = gpiochip_get_data(gc); + unsigned long flags, val_deb; + unsigned long mask = BIT(offset); + + spin_lock_irqsave(&gc->bgpio_lock, flags); + + val_deb = readl(&port->regs->GpioDebCtl); + if (debounce) + writel(val_deb | mask, &port->regs->GpioDebCtl); + else + writel(val_deb & ~mask, &port->regs->GpioDebCtl); + + spin_unlock_irqrestore(&gc->bgpio_lock, flags); + + return 0; +} + +static int ctc_gpio_set_config(struct gpio_chip *gc, unsigned int offset, + unsigned long config) +{ + u32 debounce; + + if (pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE) + return -ENOTSUPP; + + debounce = pinconf_to_config_argument(config); + return ctcapb_gpio_set_debounce(gc, offset, debounce); +} + +static irqreturn_t ctcapb_irq_handler_mfd(int irq, void *dev_id) +{ + u32 worked; + struct ctcapb_gpio_port *port = dev_id; + + worked = ctcapb_do_irq(port); + + return worked ? IRQ_HANDLED : IRQ_NONE; +} + +static void ctcapb_configure_irqs(struct ctcapb_gpio_port *port, + struct ctcapb_port_property *pp) +{ + struct gpio_chip *gc = &port->gc; + struct fwnode_handle *fwnode = pp->fwnode; + struct irq_chip_generic *irq_gc = NULL; + unsigned int hwirq, ngpio = gc->ngpio; + struct irq_chip_type *ct; + int err, i; + + port->domain = irq_domain_create_linear(fwnode, ngpio, + &irq_generic_chip_ops, port); + if (!port->domain) + return; + + err = irq_alloc_domain_generic_chips(port->domain, ngpio, 2, + "gpio-ctcapb", handle_level_irq, + IRQ_NOREQUEST, 0, + IRQ_GC_INIT_NESTED_LOCK); + if (err) { + dev_info(port->gpio->dev, + "irq_alloc_domain_generic_chips failed\n"); + irq_domain_remove(port->domain); + port->domain = NULL; + return; + } + + irq_gc = irq_get_domain_generic_chip(port->domain, 0); + if (!irq_gc) { + irq_domain_remove(port->domain); + port->domain = NULL; + return; + } + + irq_gc->reg_base = port->regs; + irq_gc->private = port; + + for (i = 0; i < 2; i++) { + ct = &irq_gc->chip_types[i]; + ct->chip.irq_ack = irq_gc_ack_set_bit; + ct->chip.irq_mask = irq_gc_mask_set_bit; + ct->chip.irq_unmask = ctcapb_irq_unmask; + ct->chip.irq_set_type = ctcapb_irq_set_type; + //ct->chip.irq_enable = ctcapb_irq_enable; + //ct->chip.irq_disable = ctcapb_irq_disable; + ct->chip.irq_request_resources = ctcapb_irq_reqres; + ct->chip.irq_release_resources = ctcapb_irq_relres; + ct->regs.ack = + (&port->regs->GpioEoiCtl - &port->regs->GpioDataCtl) * 4; + ct->regs.mask = + (&port->regs->GpioIntrMask - &port->regs->GpioDataCtl) * 4; + ct->type = IRQ_TYPE_LEVEL_MASK; + } + + irq_gc->chip_types[0].type = IRQ_TYPE_LEVEL_MASK; + irq_gc->chip_types[1].type = IRQ_TYPE_EDGE_BOTH; + irq_gc->chip_types[1].handler = handle_edge_irq; + + if (!pp->irq_shared) { + irq_set_chained_handler_and_data(pp->irq, ctcapb_irq_handler, + port); + } else { + /* + * Request a shared IRQ since where MFD would have devices + * using the same irq pin + */ + err = devm_request_irq(port->gpio->dev, pp->irq, + ctcapb_irq_handler_mfd, + IRQF_SHARED, "gpio-ctcapb-mfd", port); + if (err) { + dev_err(port->gpio->dev, "error requesting IRQ\n"); + irq_domain_remove(port->domain); + port->domain = NULL; + return; + } + } + + for (hwirq = 0; hwirq < ngpio; hwirq++) + irq_create_mapping(port->domain, hwirq); + + port->gc.to_irq = ctcapb_gpio_to_irq; +} + +static void ctcapb_irq_teardown(struct ctcapb_gpio_port *port) +{ + struct gpio_chip *gc = &port->gc; + unsigned int ngpio = gc->ngpio; + irq_hw_number_t hwirq; + + if (!port->domain) + return; + + for (hwirq = 0; hwirq < ngpio; hwirq++) + irq_dispose_mapping(irq_find_mapping(port->domain, hwirq)); + + irq_domain_remove(port->domain); + port->domain = NULL; +} + +static int ctcapb_gpio_add_port(struct ctcapb_gpio *gpio, + struct ctcapb_port_property *pp, + unsigned int offs) +{ + struct ctcapb_gpio_port *port; + void __iomem *dat, *set, *dirout; + int err; + + port = &gpio->ports[offs]; + port->gpio = gpio; + port->idx = pp->idx; + + if (port->idx == 0) { + dat = &gpio->regs->GpioReadData; + set = &gpio->regs->GpioDataCtl; + dirout = &gpio->regs->GpioOutCtl; + port->regs = + (struct GpioSoc_port_regs *)&gpio->regs->GpioDataCtl; + } else { + dat = &gpio->regs->GpioHsReadData; + set = &gpio->regs->GpioHsDataCtl; + dirout = &gpio->regs->GpioHsOutCtl; + port->regs = + (struct GpioSoc_port_regs *)&gpio->regs->GpioHsDataCtl; + } + + err = bgpio_init(&port->gc, gpio->dev, 4, dat, set, NULL, dirout, + NULL, false); + if (err) { + dev_err(gpio->dev, "failed to init gpio chip for port%d\n", + port->idx); + return err; + } +#ifdef CONFIG_OF_GPIO + port->gc.of_node = to_of_node(pp->fwnode); +#endif + port->gc.ngpio = pp->ngpio; + port->gc.base = pp->gpio_base; + port->gc.set_config = ctc_gpio_set_config; + + if (pp->irq) + ctcapb_configure_irqs(port, pp); + + err = gpiochip_add_data(&port->gc, port); + if (err) + dev_err(gpio->dev, "failed to register gpiochip for port%d\n", + port->idx); + else + port->is_registered = true; + + /* Add GPIO-signaled ACPI event support */ + if (pp->irq) + acpi_gpiochip_request_interrupts(&port->gc); + + return err; +} + +static void ctcapb_gpio_unregister(struct ctcapb_gpio *gpio) +{ + unsigned int m; + + for (m = 0; m < gpio->nr_ports; ++m) + if (gpio->ports[m].is_registered) + gpiochip_remove(&gpio->ports[m].gc); +} + +static struct ctcapb_platform_data *ctcapb_gpio_get_pdata(struct device *dev) +{ + struct fwnode_handle *fwnode; + struct ctcapb_platform_data *pdata; + struct ctcapb_port_property *pp; + int nports; + int i; + + nports = device_get_child_node_count(dev); + if (nports == 0) + return ERR_PTR(-ENODEV); + + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return ERR_PTR(-ENOMEM); + + pdata->properties = devm_kcalloc(dev, nports, sizeof(*pp), GFP_KERNEL); + if (!pdata->properties) + return ERR_PTR(-ENOMEM); + + pdata->nports = nports; + + i = 0; + device_for_each_child_node(dev, fwnode) { + pp = &pdata->properties[i++]; + pp->fwnode = fwnode; + + if (fwnode_property_read_u32(fwnode, "reg", &pp->idx) || + pp->idx >= DWAPB_MAX_PORTS) { + dev_err(dev, + "missing/invalid port index for port%d\n", i); + fwnode_handle_put(fwnode); + return ERR_PTR(-EINVAL); + } + + if (fwnode_property_read_u32(fwnode, "ctc,nr-gpios", + &pp->ngpio)) { + dev_info(dev, + "failed to get number of gpios for port%d\n", + i); + pp->ngpio = 32; + } + + if (dev->of_node && fwnode_property_read_bool(fwnode, + "interrupt-controller")) { + pp->irq = irq_of_parse_and_map(to_of_node(fwnode), 0); + if (!pp->irq) + dev_warn(dev, "no irq for port%d\n", pp->idx); + } + + if (has_acpi_companion(dev) && pp->idx == 0) + pp->irq = platform_get_irq(to_platform_device(dev), 0); + + pp->irq_shared = false; + pp->gpio_base = -1; + } + + return pdata; +} + +static int ctcapb_gpio_probe(struct platform_device *pdev) +{ + unsigned int i; + struct resource *res; + struct ctcapb_gpio *gpio; + int err; + struct device *dev = &pdev->dev; + struct ctcapb_platform_data *pdata = dev_get_platdata(dev); + + if (!pdata) { + pdata = ctcapb_gpio_get_pdata(dev); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); + } + + if (!pdata->nports) + return -ENODEV; + + gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); + if (!gpio) + return -ENOMEM; + + gpio->dev = &pdev->dev; + gpio->nr_ports = pdata->nports; + + gpio->ports = devm_kcalloc(&pdev->dev, gpio->nr_ports, + sizeof(*gpio->ports), GFP_KERNEL); + if (!gpio->ports) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + gpio->regs = + (struct GpioSoc_regs *)devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(gpio->regs)) + return PTR_ERR(gpio->regs); + + for (i = 0; i < gpio->nr_ports; i++) { + err = ctcapb_gpio_add_port(gpio, &pdata->properties[i], i); + if (err) + goto out_unregister; + } + platform_set_drvdata(pdev, gpio); + + return 0; + +out_unregister: + ctcapb_gpio_unregister(gpio); + for (i = 0; i < gpio->nr_ports; i++) + ctcapb_irq_teardown(&gpio->ports[i]); + + return err; +} + +static int ctcapb_gpio_remove(struct platform_device *pdev) +{ + int i; + struct ctcapb_gpio *gpio = platform_get_drvdata(pdev); + + ctcapb_gpio_unregister(gpio); + for (i = 0; i < gpio->nr_ports; i++) + ctcapb_irq_teardown(&gpio->ports[i]); + + return 0; +} + +static const struct of_device_id ctcapb_of_match[] = { + {.compatible = "ctc,apb-gpio"}, + { /* Sentinel */ } +}; + +MODULE_DEVICE_TABLE(of, ctcapb_of_match); + +static const struct acpi_device_id ctcapb_acpi_match[] = { + {"HISI0181", 0}, + {"APMC0D07", 0}, + {} +}; + +MODULE_DEVICE_TABLE(acpi, ctcapb_acpi_match); + +static struct platform_driver ctcapb_gpio_driver = { + .driver = { + .name = "gpio-ctcapb", + .of_match_table = of_match_ptr(ctcapb_of_match), + .acpi_match_table = ACPI_PTR(ctcapb_acpi_match), + }, + .probe = ctcapb_gpio_probe, + .remove = ctcapb_gpio_remove, +}; + +module_platform_driver(ctcapb_gpio_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Liuht"); +MODULE_DESCRIPTION("Centec APB GPIO driver"); diff --git a/platform/centec-arm64/tsingma-bsp/src/gpio-ctc/gpio-ctcapb.h b/platform/centec-arm64/tsingma-bsp/src/gpio-ctc/gpio-ctcapb.h new file mode 100644 index 000000000000..7be811afa48c --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/gpio-ctc/gpio-ctcapb.h @@ -0,0 +1,75 @@ +/* + * Copyright(c) 2014 Intel Corporation. + * + * 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. + */ + +#ifndef GPIO_CTC_APB_H +#define GPIO_CTC_APB_H + +struct ctcapb_port_property { + struct fwnode_handle *fwnode; + unsigned int idx; + unsigned int ngpio; + unsigned int gpio_base; + unsigned int irq; + bool irq_shared; +}; + +struct ctcapb_platform_data { + struct ctcapb_port_property *properties; + unsigned int nports; +}; + +struct GpioSoc_regs { + u32 GpioDataCtl; /* 0x00000000 */ + u32 GpioOutCtl; /* 0x00000004 */ + u32 GpioDebCtl; /* 0x00000008 */ + u32 GpioReadData; /* 0x0000000c */ + u32 GpioIntrEn; /* 0x00000010 */ + u32 GpioIntrMask; /* 0x00000014 */ + u32 GpioIntrLevel; /* 0x00000018 */ + u32 GpioIntrPolarity; /* 0x0000001c */ + u32 GpioIntrStatus; /* 0x00000020 */ + u32 GpioIntrRaw; /* 0x00000024 */ + u32 GpioEoiCtl; /* 0x00000028 */ + u32 rsv11; + u32 GpioDebCnt; /* 0x00000030 */ + u32 GpioVerId; /* 0x00000034 */ + u32 rsv14; + u32 rsv15; + u32 GpioHsDataCtl; /* 0x00000040 */ + u32 GpioHsOutCtl; /* 0x00000044 */ + u32 GpioHsDebCtl; /* 0x00000048 */ + u32 GpioHsReadData; /* 0x0000004c */ + u32 GpioHsIntrEn; /* 0x00000050 */ + u32 GpioHsIntrMask; /* 0x00000054 */ + u32 GpioHsIntrLevel; /* 0x00000058 */ + u32 GpioHsIntrPolarity; /* 0x0000005c */ + u32 GpioHsIntrStatus; /* 0x00000060 */ + u32 GpioHsIntrRaw; /* 0x00000064 */ + u32 GpioHsEoiCtl; /* 0x00000068 */ +}; + +struct GpioSoc_port_regs { + u32 GpioDataCtl; + u32 GpioOutCtl; + u32 GpioDebCtl; + u32 GpioReadData; + u32 GpioIntrEn; + u32 GpioIntrMask; + u32 GpioIntrLevel; + u32 GpioIntrPolarity; + u32 GpioIntrStatus; + u32 GpioIntrRaw; + u32 GpioEoiCtl; +}; + +#endif diff --git a/platform/centec-arm64/tsingma-bsp/src/gpio-ctc/gpiolib.h b/platform/centec-arm64/tsingma-bsp/src/gpio-ctc/gpiolib.h new file mode 100644 index 000000000000..a7e49fef73d4 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/gpio-ctc/gpiolib.h @@ -0,0 +1,298 @@ +/* + * Internal GPIO functions. + * + * Copyright (C) 2013, Intel Corporation + * Author: Mika Westerberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef GPIOLIB_H +#define GPIOLIB_H + +#include +#include /* for enum gpiod_flags */ +#include +#include +#include +#include + +enum of_gpio_flags; +enum gpio_lookup_flags; +struct acpi_device; + +/** + * struct gpio_device - internal state container for GPIO devices + * @id: numerical ID number for the GPIO chip + * @dev: the GPIO device struct + * @chrdev: character device for the GPIO device + * @mockdev: class device used by the deprecated sysfs interface (may be + * NULL) + * @owner: helps prevent removal of modules exporting active GPIOs + * @chip: pointer to the corresponding gpiochip, holding static + * data for this device + * @descs: array of ngpio descriptors. + * @ngpio: the number of GPIO lines on this GPIO device, equal to the size + * of the @descs array. + * @base: GPIO base in the DEPRECATED global Linux GPIO numberspace, assigned + * at device creation time. + * @label: a descriptive name for the GPIO device, such as the part number + * or name of the IP component in a System on Chip. + * @data: per-instance data assigned by the driver + * @list: links gpio_device:s together for traversal + * + * This state container holds most of the runtime variable data + * for a GPIO device and can hold references and live on after the + * GPIO chip has been removed, if it is still being used from + * userspace. + */ +struct gpio_device { + int id; + struct device dev; + struct cdev chrdev; + struct device *mockdev; + struct module *owner; + struct gpio_chip *chip; + struct gpio_desc *descs; + int base; + u16 ngpio; + const char *label; + void *data; + struct list_head list; + +#ifdef CONFIG_PINCTRL + /* + * If CONFIG_PINCTRL is enabled, then gpio controllers can optionally + * describe the actual pin range which they serve in an SoC. This + * information would be used by pinctrl subsystem to configure + * corresponding pins for gpio usage. + */ + struct list_head pin_ranges; +#endif +}; + +/** + * struct acpi_gpio_info - ACPI GPIO specific information + * @adev: reference to ACPI device which consumes GPIO resource + * @flags: GPIO initialization flags + * @gpioint: if %true this GPIO is of type GpioInt otherwise type is GpioIo + * @polarity: interrupt polarity as provided by ACPI + * @triggering: triggering type as provided by ACPI + * @quirks: Linux specific quirks as provided by struct acpi_gpio_mapping + */ +struct acpi_gpio_info { + struct acpi_device *adev; + enum gpiod_flags flags; + bool gpioint; + int polarity; + int triggering; + unsigned int quirks; +}; + +/* gpio suffixes used for ACPI and device tree lookup */ +static __maybe_unused const char * const gpio_suffixes[] = { "gpios", "gpio" }; + +#ifdef CONFIG_OF_GPIO +struct gpio_desc *of_find_gpio(struct device *dev, + const char *con_id, + unsigned int idx, + enum gpio_lookup_flags *flags); +struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np, + const char *list_name, int index, enum of_gpio_flags *flags); +int of_gpiochip_add(struct gpio_chip *gc); +void of_gpiochip_remove(struct gpio_chip *gc); +#else +static inline struct gpio_desc *of_find_gpio(struct device *dev, + const char *con_id, + unsigned int idx, + enum gpio_lookup_flags *flags) +{ + return ERR_PTR(-ENOENT); +} +static inline struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np, + const char *list_name, int index, enum of_gpio_flags *flags) +{ + return ERR_PTR(-ENOENT); +} +static inline int of_gpiochip_add(struct gpio_chip *gc) { return 0; } +static inline void of_gpiochip_remove(struct gpio_chip *gc) { } +#endif /* CONFIG_OF_GPIO */ + +#ifdef CONFIG_ACPI +void acpi_gpiochip_add(struct gpio_chip *chip); +void acpi_gpiochip_remove(struct gpio_chip *chip); + +void acpi_gpiochip_request_interrupts(struct gpio_chip *chip); +void acpi_gpiochip_free_interrupts(struct gpio_chip *chip); + +int acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, + struct acpi_gpio_info *info); + +struct gpio_desc *acpi_find_gpio(struct device *dev, + const char *con_id, + unsigned int idx, + enum gpiod_flags *dflags, + enum gpio_lookup_flags *lookupflags); +struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode, + const char *propname, int index, + struct acpi_gpio_info *info); + +int acpi_gpio_count(struct device *dev, const char *con_id); + +bool acpi_can_fallback_to_crs(struct acpi_device *adev, const char *con_id); +#else +static inline void acpi_gpiochip_add(struct gpio_chip *chip) { } +static inline void acpi_gpiochip_remove(struct gpio_chip *chip) { } + +static inline void +acpi_gpiochip_request_interrupts(struct gpio_chip *chip) { } + +static inline void +acpi_gpiochip_free_interrupts(struct gpio_chip *chip) { } + +static inline int +acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, struct acpi_gpio_info *info) +{ + return 0; +} + +static inline struct gpio_desc * +acpi_find_gpio(struct device *dev, const char *con_id, + unsigned int idx, enum gpiod_flags *dflags, + enum gpio_lookup_flags *lookupflags) +{ + return ERR_PTR(-ENOENT); +} +static inline struct gpio_desc * +acpi_node_get_gpiod(struct fwnode_handle *fwnode, const char *propname, + int index, struct acpi_gpio_info *info) +{ + return ERR_PTR(-ENXIO); +} +static inline int acpi_gpio_count(struct device *dev, const char *con_id) +{ + return -ENODEV; +} + +static inline bool acpi_can_fallback_to_crs(struct acpi_device *adev, + const char *con_id) +{ + return false; +} +#endif + +struct gpio_desc *gpiochip_get_desc(struct gpio_chip *chip, u16 hwnum); +int gpiod_get_array_value_complex(bool raw, bool can_sleep, + unsigned int array_size, + struct gpio_desc **desc_array, + int *value_array); +int gpiod_set_array_value_complex(bool raw, bool can_sleep, + unsigned int array_size, + struct gpio_desc **desc_array, + int *value_array); + +/* This is just passed between gpiolib and devres */ +struct gpio_desc *gpiod_get_from_of_node(struct device_node *node, + const char *propname, int index, + enum gpiod_flags dflags, + const char *label); + +extern struct spinlock gpio_lock; +extern struct list_head gpio_devices; + +struct gpio_desc { + struct gpio_device *gdev; + unsigned long flags; +/* flag symbols are bit numbers */ +#define FLAG_REQUESTED 0 +#define FLAG_IS_OUT 1 +#define FLAG_EXPORT 2 /* protected by sysfs_lock */ +#define FLAG_SYSFS 3 /* exported via /sys/class/gpio/control */ +#define FLAG_ACTIVE_LOW 6 /* value has active low */ +#define FLAG_OPEN_DRAIN 7 /* Gpio is open drain type */ +#define FLAG_OPEN_SOURCE 8 /* Gpio is open source type */ +#define FLAG_USED_AS_IRQ 9 /* GPIO is connected to an IRQ */ +#define FLAG_IS_HOGGED 11 /* GPIO is hogged */ +#define FLAG_TRANSITORY 12 /* GPIO may lose value in sleep or reset */ + + /* Connection label */ + const char *label; + /* Name of the GPIO */ + const char *name; +}; + +int gpiod_request(struct gpio_desc *desc, const char *label); +void gpiod_free(struct gpio_desc *desc); +int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id, + unsigned long lflags, enum gpiod_flags dflags); +int gpiod_hog(struct gpio_desc *desc, const char *name, + unsigned long lflags, enum gpiod_flags dflags); + +/* + * Return the GPIO number of the passed descriptor relative to its chip + */ +static inline int gpio_chip_hwgpio(const struct gpio_desc *desc) +{ + return desc - &desc->gdev->descs[0]; +} + +void devprop_gpiochip_set_names(struct gpio_chip *chip, + const struct fwnode_handle *fwnode); + +/* With descriptor prefix */ + +#define gpiod_emerg(desc, fmt, ...) \ + pr_emerg("gpio-%d (%s): " fmt, desc_to_gpio(desc), desc->label ? : "?",\ + ##__VA_ARGS__) +#define gpiod_crit(desc, fmt, ...) \ + pr_crit("gpio-%d (%s): " fmt, desc_to_gpio(desc), desc->label ? : "?", \ + ##__VA_ARGS__) +#define gpiod_err(desc, fmt, ...) \ + pr_err("gpio-%d (%s): " fmt, desc_to_gpio(desc), desc->label ? : "?", \ + ##__VA_ARGS__) +#define gpiod_warn(desc, fmt, ...) \ + pr_warn("gpio-%d (%s): " fmt, desc_to_gpio(desc), desc->label ? : "?", \ + ##__VA_ARGS__) +#define gpiod_info(desc, fmt, ...) \ + pr_info("gpio-%d (%s): " fmt, desc_to_gpio(desc), desc->label ? : "?", \ + ##__VA_ARGS__) +#define gpiod_dbg(desc, fmt, ...) \ + pr_debug("gpio-%d (%s): " fmt, desc_to_gpio(desc), desc->label ? : "?",\ + ##__VA_ARGS__) + +/* With chip prefix */ + +#define chip_emerg(chip, fmt, ...) \ + dev_emerg(&chip->gpiodev->dev, "(%s): " fmt, chip->label, ##__VA_ARGS__) +#define chip_crit(chip, fmt, ...) \ + dev_crit(&chip->gpiodev->dev, "(%s): " fmt, chip->label, ##__VA_ARGS__) +#define chip_err(chip, fmt, ...) \ + dev_err(&chip->gpiodev->dev, "(%s): " fmt, chip->label, ##__VA_ARGS__) +#define chip_warn(chip, fmt, ...) \ + dev_warn(&chip->gpiodev->dev, "(%s): " fmt, chip->label, ##__VA_ARGS__) +#define chip_info(chip, fmt, ...) \ + dev_info(&chip->gpiodev->dev, "(%s): " fmt, chip->label, ##__VA_ARGS__) +#define chip_dbg(chip, fmt, ...) \ + dev_dbg(&chip->gpiodev->dev, "(%s): " fmt, chip->label, ##__VA_ARGS__) + +#ifdef CONFIG_GPIO_SYSFS + +int gpiochip_sysfs_register(struct gpio_device *gdev); +void gpiochip_sysfs_unregister(struct gpio_device *gdev); + +#else + +static inline int gpiochip_sysfs_register(struct gpio_device *gdev) +{ + return 0; +} + +static inline void gpiochip_sysfs_unregister(struct gpio_device *gdev) +{ +} + +#endif /* CONFIG_GPIO_SYSFS */ + +#endif /* GPIOLIB_H */ diff --git a/platform/centec-arm64/tsingma-bsp/src/i2c-ctc/Makefile b/platform/centec-arm64/tsingma-bsp/src/i2c-ctc/Makefile new file mode 100644 index 000000000000..3821209dfe92 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/i2c-ctc/Makefile @@ -0,0 +1 @@ +obj-m = i2c-ctc.o diff --git a/platform/centec-arm64/tsingma-bsp/src/i2c-ctc/i2c-ctc.c b/platform/centec-arm64/tsingma-bsp/src/i2c-ctc/i2c-ctc.c new file mode 100644 index 000000000000..bcae26040d06 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/i2c-ctc/i2c-ctc.c @@ -0,0 +1,822 @@ +/* Centec I2C controller driver + * + * Author: Wangyb + * + * Copyright 2005-2018, Centec Networks (Suzhou) Co., Ltd. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "i2c-ctc.h" + +#define IC_ICK_NS(f) (1000000000 / f) + +static char *abort_sources[] = { + [ABRT_7B_ADDR_NOACK] = "slave address not acknowledged (7bit mode)", + [ABRT_10ADDR1_NOACK] = + "first address byte not acknowledged (10bit mode)", + [ABRT_10ADDR2_NOACK] = + "second address byte not acknowledged (10bit mode)", + [ABRT_TXDATA_NOACK] = "data not acknowledged", + [ABRT_GCALL_NOACK] = "no acknowledgment for a general call", + [ABRT_GCALL_READ] = "read after general call", + [ABRT_SBYTE_ACKDET] = "start byte acknowledged", + [ABRT_SBYTE_NORSTRT] = + "trying to send start byte when restart is disabled", + [ABRT_10B_RD_NORSTRT] = + "trying to read when restart is disabled (10bit mode)", + [ABRT_MASTER_DIS] = "trying to use disabled adapter", + [ARB_LOST] = "lost arbitration", +}; + +static u32 ctc_readl(struct ctc_i2c_dev *dev, int offset) +{ + u32 value; + + value = readl_relaxed(dev->base + offset); + return value; +} + +static void ctc_writel(struct ctc_i2c_dev *dev, u32 b, int offset) +{ + writel_relaxed(b, dev->base + offset); +} + +static void __i2c_ctc_enable(struct ctc_i2c_dev *dev, bool enable) +{ + int timeout = 100; + + do { + ctc_writel(dev, enable, CTC_IC_ENABLE); + if ((ctc_readl(dev, CTC_IC_ENABLE_STATUS) & 1) == enable) + return; + usleep_range(25, 250); + } while (timeout--); + + dev_warn(dev->dev, "timeout in %sabling adapter\n", + enable ? "en" : "dis"); +} + +/* Conditional expression: + * SCL high level time = (high level cnt + (14 + 4)cnt) * 20ns + * SCL low level time = (low level cnt + (1 + 2)cnt) * 20ns + */ +static u32 __ctc_calc_ss_cnt(u32 clk_freq) +{ + return CTC_SCL_Timing(clk_freq) / 2 / 20; +} + +static u32 __ctc_calc_fs_cnt(u32 clk_freq) +{ + return CTC_SCL_Timing(clk_freq) / 2 / 20 + 1; +} + +int i2c_ctc_init(struct ctc_i2c_dev *dev) +{ + u32 hcnt, lcnt; + u32 reg, comp_param1; + + reg = ctc_readl(dev, CTC_IC_COMP_TYPE); + if (reg != CTC_IC_COMP_TYPE_VALUE) { + dev_err(dev->dev, "Unknown Centec component type: 0x%08x\n", + reg); + return -ENODEV; + } + + /* Disable the adapter */ + __i2c_ctc_enable(dev, false); + + /* Set SCL timing parameters */ + if ((dev->master_cfg & CTC_IC_CON_SPEED_MASK) + == CTC_IC_CON_SPEED_FAST) { + hcnt = __ctc_calc_fs_cnt(dev->clk_freq) - 14 - 4; + lcnt = __ctc_calc_fs_cnt(dev->clk_freq) - 1 - 2; + + ctc_writel(dev, hcnt, CTC_IC_FS_SCL_HCNT); + ctc_writel(dev, lcnt, CTC_IC_FS_SCL_LCNT); + dev_info(dev->dev, + "Fast-mode HCNT:LCNT = %d:%d, clk_freq = %d\n", hcnt, + lcnt, dev->clk_freq); + + } else { + hcnt = __ctc_calc_ss_cnt(dev->clk_freq) - 14 - 2; + lcnt = __ctc_calc_ss_cnt(dev->clk_freq) - 1; + + ctc_writel(dev, hcnt, CTC_IC_SS_SCL_HCNT); + ctc_writel(dev, lcnt, CTC_IC_SS_SCL_LCNT); + dev_info(dev->dev, + "Standard-mode HCNT:LCNT = %d:%d, clk_freq = %d\n", + hcnt, lcnt, dev->clk_freq); + } + + /* Configure SDA Hold Time if required */ + if (dev->sda_hold_time) + ctc_writel(dev, dev->sda_hold_time, CTC_IC_SDA_HOLD); + + /* Configure Tx/Rx FIFO threshold levels */ + comp_param1 = ctc_readl(dev, CTC_IC_COMP_PARAM_1); + dev->tx_fifo_depth = ((comp_param1 >> 16) & 0xff) + 1; + dev->rx_fifo_depth = ((comp_param1 >> 8) & 0xff) + 1; + + ctc_writel(dev, dev->tx_fifo_depth / 2, CTC_IC_TX_TL); + ctc_writel(dev, 0, CTC_IC_RX_TL); + + /* Configure the i2c master */ + ctc_writel(dev, dev->master_cfg, CTC_IC_CON); + + return 0; +} + +static int i2c_ctc_wait_bus_not_busy(struct ctc_i2c_dev *dev) +{ + int timeout = 20; + + while (ctc_readl(dev, CTC_IC_STATUS) & CTC_IC_STATUS_ACTIVITY) { + if (timeout <= 0) { + dev_warn(dev->dev, "timeout waiting for bus ready\n"); + return -ETIMEDOUT; + } + timeout--; + usleep_range(1000, 1100); + } + return 0; +} + +void i2c_ctc_disable_intr(struct ctc_i2c_dev *dev) +{ + ctc_writel(dev, 0, CTC_IC_INTR_MASK); +} + +static void i2c_ctc_xfer_init(struct ctc_i2c_dev *dev) +{ + struct i2c_msg *msgs = dev->msgs; + u32 ic_con, ic_tar = 0; + + /* Disable the adapter */ + __i2c_ctc_enable(dev, false); + + /* if the slave address is ten bit address, enable 10BITADDR */ + ic_con = ctc_readl(dev, CTC_IC_CON); + if (msgs[dev->msg_write_idx].flags & I2C_M_TEN) { + ic_con |= CTC_IC_CON_10BITADDR_MASTER; + ic_tar = CTC_IC_TAR_10BITADDR_MASTER; + } else { + ic_con &= ~CTC_IC_CON_10BITADDR_MASTER; + } + + ctc_writel(dev, ic_con, CTC_IC_CON); + + /* Set the slave (target) address */ + ctc_writel(dev, msgs[dev->msg_write_idx].addr | ic_tar, CTC_IC_TAR); + + /* Enforce disabled interrupts (due to HW issues) */ + i2c_ctc_disable_intr(dev); + + /* Enable the adapter */ + __i2c_ctc_enable(dev, true); + + /* Clear and enable interrupts */ + ctc_readl(dev, CTC_IC_CLR_INTR); + ctc_writel(dev, CTC_IC_INTR_DEFAULT_MASK, CTC_IC_INTR_MASK); +} + +static int i2c_ctc_handle_tx_abort(struct ctc_i2c_dev *dev) +{ + unsigned long abort_source = dev->abort_source; + int i; + + if (abort_source & CTC_IC_TX_ABRT_NOACK) { + for_each_set_bit(i, &abort_source, ARRAY_SIZE(abort_sources)) + dev_dbg(dev->dev, "%s: %s\n", __func__, + abort_sources[i]); + return -EREMOTEIO; + } + + for_each_set_bit(i, &abort_source, ARRAY_SIZE(abort_sources)) + dev_err(dev->dev, "%s: %s\n", __func__, abort_sources[i]); + + if (abort_source & CTC_IC_TX_ARB_LOST) + return -EAGAIN; + else if (abort_source & CTC_IC_TX_ABRT_GCALL_READ) + return -EINVAL; + else + return -EIO; +} + +static int i2c_ctc_interrupt_transfer(struct ctc_i2c_dev *dev) +{ + int ret; + + mutex_lock(&dev->lock); + + reinit_completion(&dev->cmd_complete); + + dev->cmd_err = 0; + dev->msg_write_idx = 0; + dev->msg_read_idx = 0; + dev->msg_err = 0; + dev->status = STATUS_IDLE; + dev->abort_source = 0; + dev->rx_outstanding = 0; + + ret = i2c_ctc_wait_bus_not_busy(dev); + if (ret < 0) + goto done; + + /* start the transfers */ + i2c_ctc_xfer_init(dev); + + /* wait for tx to complete */ + if (!wait_for_completion_timeout(&dev->cmd_complete, HZ)) { + dev_err(dev->dev, "controller timed out\n"); + i2c_ctc_init(dev); + ret = -ETIMEDOUT; + goto done; + } + + __i2c_ctc_enable(dev, false); + + if (dev->msg_err) { + ret = dev->msg_err; + goto done; + } + + /* no error */ + if (likely(!dev->cmd_err)) { + ret = dev->msgs_num; + goto done; + } + + /* We have an error */ + if (dev->cmd_err == CTC_IC_ERR_TX_ABRT) { + ret = i2c_ctc_handle_tx_abort(dev); + goto done; + } + ret = -EIO; + +done: + mutex_unlock(&dev->lock); + return ret; +} + +static void ctc_i2c_flush_rxfifo(struct ctc_i2c_dev *dev) +{ + while (ctc_readl(dev, CTC_IC_STATUS) & CTC_IC_STATUS_RFNE) + ctc_readl(dev, CTC_IC_DATA_CMD); +} + +static int ctc_i2c_xfer_finish(struct ctc_i2c_dev *dev) +{ + int ret; + ulong start_stop_det = jiffies; + + while (1) { + if ((ctc_readl(dev, CTC_IC_RAW_INTR_STAT) & + CTC_IC_INTR_STOP_DET)) { + ctc_readl(dev, CTC_IC_CLR_STOP_DET); + break; + } else if (time_after(jiffies, start_stop_det + + I2C_STOPDET_TO)) { + break; + } + } + + ret = i2c_ctc_wait_bus_not_busy(dev); + if (ret < 0) + return -1; + + ctc_i2c_flush_rxfifo(dev); + + return 0; +} + +static int __ctc_i2c_read(struct ctc_i2c_dev *dev, __u16 chip_addr, u8 *offset, + __u16 olen, u8 *data, __u16 dlen) +{ + unsigned int active = 0; + unsigned int flag = 0; + int ret; + unsigned long start_time_rx; + + ret = i2c_ctc_wait_bus_not_busy(dev); + if (ret < 0) + return -1; + + /* Disable the adapter */ + __i2c_ctc_enable(dev, false); + + /* Set the slave (target) address */ + ctc_writel(dev, chip_addr, CTC_IC_TAR); + + /* Enable the adapter */ + __i2c_ctc_enable(dev, true); + + if (olen > 0) { + ctc_writel(dev, *offset | CTC_RESTART, CTC_IC_DATA_CMD); + olen--; + while (olen) { + offset++; + olen--; + ctc_writel(dev, *offset, CTC_IC_DATA_CMD); + } + } + + start_time_rx = jiffies; + while (dlen) { + if (!active) { + if (flag == 0) { + if (dlen == 1) { + ctc_writel(dev, + CTC_CMD_READ | CTC_STOP | + CTC_RESTART, + CTC_IC_DATA_CMD); + } else { + ctc_writel(dev, + CTC_CMD_READ | CTC_RESTART, + CTC_IC_DATA_CMD); + } + flag = 1; + } else if (dlen != 1) { + ctc_writel(dev, CTC_CMD_READ, CTC_IC_DATA_CMD); + } else { + ctc_writel(dev, CTC_CMD_READ | CTC_STOP, + CTC_IC_DATA_CMD); + } + active = 1; + } + if (ctc_readl(dev, CTC_IC_STATUS) & CTC_IC_STATUS_RFNE) { + *data++ = + (unsigned char)ctc_readl(dev, CTC_IC_DATA_CMD); + dlen--; + start_time_rx = jiffies; + active = 0; + } else if (time_after(jiffies, start_time_rx + I2C_BYTE_TO)) { + return -ETIMEDOUT; + } + } + + return ctc_i2c_xfer_finish(dev); +} + +static int __ctc_i2c_write(struct ctc_i2c_dev *dev, __u16 chip_addr, + u8 *offset, __u16 olen, u8 *data, __u16 dlen) +{ + int ret; + unsigned long start_time_tx; + int nb = dlen; + + ret = i2c_ctc_wait_bus_not_busy(dev); + if (ret < 0) + return -1; + + /* Disable the adapter */ + __i2c_ctc_enable(dev, false); + + /* Set the slave (target) address */ + ctc_writel(dev, chip_addr, CTC_IC_TAR); + + /* Enable the adapter */ + __i2c_ctc_enable(dev, true); + + start_time_tx = jiffies; + while (dlen) { + if (ctc_readl(dev, CTC_IC_STATUS) & CTC_IC_STATUS_TFNF) { + if (--dlen == 0) { + ctc_writel(dev, *data | CTC_STOP, + CTC_IC_DATA_CMD); + } else { + ctc_writel(dev, *data, CTC_IC_DATA_CMD); + } + data++; + start_time_tx = jiffies; + } else if (time_after(jiffies, start_time_tx + + (nb * I2C_BYTE_TO))) { + dev_err(dev->dev, "Timed out. i2c write Failed\n"); + return -ETIMEDOUT; + } + } + return ctc_i2c_xfer_finish(dev); +} + +static int i2c_ctc_polling_transfer(struct ctc_i2c_dev *dev) +{ + struct i2c_msg *dmsg, *omsg, dummy; + int ret; + + memset(&dummy, 0, sizeof(struct i2c_msg)); + + /* We expect either two messages (one with an offset and one with the + * actucal data) or one message (just data) + */ + if (dev->msgs_num > 2 || dev->msgs_num == 0) { + dev_err(dev->dev, "%s: Only one or two messages are supported.", + __func__); + return -1; + } + + omsg = dev->msgs_num == 1 ? &dummy : dev->msgs; + dmsg = dev->msgs_num == 1 ? dev->msgs : (dev->msgs + 1); + + if (dmsg->flags & I2C_M_RD) { + ret = __ctc_i2c_read(dev, dmsg->addr, omsg->buf, omsg->len, + dmsg->buf, dmsg->len); + } else + ret = __ctc_i2c_write(dev, dmsg->addr, omsg->buf, omsg->len, + dmsg->buf, dmsg->len); + if (!ret) + return dev->msgs_num; + else + return -EIO; +} + +static int i2c_ctc_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], + int num) +{ + struct ctc_i2c_dev *dev = i2c_get_adapdata(adap); + int ret; + + dev_dbg(dev->dev, "%s: msgs: %d\n", __func__, num); + dev->msgs = msgs; + dev->msgs_num = num; + + if (dev->xfer_type == CTC_IC_INTERRUPT_TRANSFER) + ret = i2c_ctc_interrupt_transfer(dev); + else + ret = i2c_ctc_polling_transfer(dev); + + return ret; +} + +static void i2c_ctc_xfer_msg(struct ctc_i2c_dev *dev) +{ + struct i2c_msg *msgs = dev->msgs; + u32 intr_mask; + int tx_limit, rx_limit; + u32 addr = msgs[dev->msg_write_idx].addr; + u32 buf_len = dev->tx_buf_len; + u8 *buf = dev->tx_buf; + bool need_restart = false; + + intr_mask = CTC_IC_INTR_DEFAULT_MASK; + + /* msg_write_idx */ + for (; dev->msg_write_idx < dev->msgs_num; dev->msg_write_idx++) { + + if (msgs[dev->msg_write_idx].addr != addr) { + dev_err(dev->dev, "%s: invalid target address\n", + __func__); + dev->msg_err = -EINVAL; + break; + } + + if (msgs[dev->msg_write_idx].len == 0) { + dev_err(dev->dev, "%s: invalid message length\n", + __func__); + dev->msg_err = -EINVAL; + break; + } + + if (!(dev->status & STATUS_WRITE_IN_PROGRESS)) { + /* new i2c_msg */ + buf = msgs[dev->msg_write_idx].buf; + buf_len = msgs[dev->msg_write_idx].len; + + if ((dev->master_cfg & CTC_IC_CON_RESTART_EN) + && (dev->msg_write_idx > 0)) + need_restart = true; + } + + tx_limit = dev->tx_fifo_depth - ctc_readl(dev, CTC_IC_TXFLR); + rx_limit = dev->rx_fifo_depth - ctc_readl(dev, CTC_IC_RXFLR); + + while (buf_len > 0 && tx_limit > 0 && rx_limit > 0) { + u32 cmd = 0; + + /* set the stop bit */ + if (dev->msg_write_idx == dev->msgs_num - 1 + && buf_len == 1) + cmd |= BIT(9); + + /* set the restart bit */ + if (need_restart) { + cmd |= BIT(10); + need_restart = false; + } + + if (msgs[dev->msg_write_idx].flags & I2C_M_RD) { + if (rx_limit - dev->rx_outstanding <= 0) + break; + + /* 1 = Read */ + ctc_writel(dev, cmd | CTC_CMD_READ, + CTC_IC_DATA_CMD); + rx_limit--; + dev->rx_outstanding++; + } else + /* 0 = Write */ + ctc_writel(dev, cmd | *buf++, CTC_IC_DATA_CMD); + tx_limit--; + buf_len--; + } + + dev->tx_buf = buf; + dev->tx_buf_len = buf_len; + + if (buf_len > 0) { + /* more bytes to be written */ + dev->status |= STATUS_WRITE_IN_PROGRESS; + break; + } + dev->status &= ~STATUS_WRITE_IN_PROGRESS; + } + + if (dev->msg_write_idx == dev->msgs_num) + intr_mask &= ~CTC_IC_INTR_TX_EMPTY; + + if (dev->msg_err) + intr_mask = 0; + + ctc_writel(dev, intr_mask, CTC_IC_INTR_MASK); +} + +static void i2c_ctc_read(struct ctc_i2c_dev *dev) +{ + struct i2c_msg *msgs = dev->msgs; + int rx_valid; + u32 len; + u8 *buf; + + /* msg_read_idx */ + for (; dev->msg_read_idx < dev->msgs_num; dev->msg_read_idx++) { + + if (!(msgs[dev->msg_read_idx].flags & I2C_M_RD)) + continue; + + if (!(dev->status & STATUS_READ_IN_PROGRESS)) { + len = msgs[dev->msg_read_idx].len; + buf = msgs[dev->msg_read_idx].buf; + } else { + len = dev->rx_buf_len; + buf = dev->rx_buf; + } + + rx_valid = ctc_readl(dev, CTC_IC_RXFLR); + + for (; len > 0 && rx_valid > 0; len--, rx_valid--) { + *buf++ = ctc_readl(dev, CTC_IC_DATA_CMD); + dev->rx_outstanding--; + } + + if (len > 0) { + dev->status |= STATUS_READ_IN_PROGRESS; + dev->rx_buf_len = len; + dev->rx_buf = buf; + return; + } + dev->status &= ~STATUS_READ_IN_PROGRESS; + } +} + +static u32 i2c_ctc_read_clear_intrbits(struct ctc_i2c_dev *dev) +{ + u32 stat; + + stat = ctc_readl(dev, CTC_IC_INTR_STAT); + if (stat & CTC_IC_INTR_RX_UNDER) + ctc_readl(dev, CTC_IC_CLR_RX_UNDER); + if (stat & CTC_IC_INTR_RX_OVER) + ctc_readl(dev, CTC_IC_CLR_RX_OVER); + if (stat & CTC_IC_INTR_TX_OVER) + ctc_readl(dev, CTC_IC_CLR_TX_OVER); + if (stat & CTC_IC_INTR_RD_REQ) + ctc_readl(dev, CTC_IC_CLR_RD_REQ); + if (stat & CTC_IC_INTR_TX_ABRT) { + dev->abort_source = ctc_readl(dev, CTC_IC_TX_ABRT_SOURCE); + ctc_readl(dev, CTC_IC_CLR_TX_ABRT); + } + if (stat & CTC_IC_INTR_RX_DONE) + ctc_readl(dev, CTC_IC_CLR_RX_DONE); + if (stat & CTC_IC_INTR_ACTIVITY) + ctc_readl(dev, CTC_IC_CLR_ACTIVITY); + if (stat & CTC_IC_INTR_STOP_DET) + ctc_readl(dev, CTC_IC_CLR_STOP_DET); + if (stat & CTC_IC_INTR_START_DET) + ctc_readl(dev, CTC_IC_CLR_START_DET); + if (stat & CTC_IC_INTR_GEN_CALL) + ctc_readl(dev, CTC_IC_CLR_GEN_CALL); + + return stat; +} + +static irqreturn_t i2c_ctc_isr(int this_irq, void *dev_id) +{ + struct ctc_i2c_dev *dev = dev_id; + u32 stat, enabled; + + enabled = ctc_readl(dev, CTC_IC_ENABLE); + stat = ctc_readl(dev, CTC_IC_RAW_INTR_STAT); + dev_dbg(dev->dev, "%s: enabled=%#x stat=%#x\n", __func__, enabled, + stat); + if (!enabled || !(stat & ~CTC_IC_INTR_ACTIVITY)) + return IRQ_NONE; + + stat = i2c_ctc_read_clear_intrbits(dev); + + if (stat & CTC_IC_INTR_TX_ABRT) { + dev->cmd_err |= CTC_IC_ERR_TX_ABRT; + dev->status = STATUS_IDLE; + + ctc_writel(dev, 0, CTC_IC_INTR_MASK); + goto tx_aborted; + } + + if (stat & CTC_IC_INTR_RX_FULL) + i2c_ctc_read(dev); + + if (stat & CTC_IC_INTR_TX_EMPTY) + i2c_ctc_xfer_msg(dev); + +tx_aborted: + if ((stat & (CTC_IC_INTR_TX_ABRT | CTC_IC_INTR_STOP_DET)) + || dev->msg_err) + complete(&dev->cmd_complete); + return IRQ_HANDLED; +} + +static u32 i2c_ctc_func(struct i2c_adapter *adap) +{ + struct ctc_i2c_dev *dev = i2c_get_adapdata(adap); + + return dev->functionality; +} + +static struct i2c_algorithm i2c_ctc_algo = { + .master_xfer = i2c_ctc_xfer, + .functionality = i2c_ctc_func, +}; + +int i2c_ctc_probe(struct ctc_i2c_dev *dev) +{ + struct i2c_adapter *adap = &dev->adapter; + int ret; + + init_completion(&dev->cmd_complete); + mutex_init(&dev->lock); + + i2c_ctc_init(dev); + + snprintf(adap->name, sizeof(adap->name), + "Centec TsingMa SoC's I2C adapter"); + adap->algo = &i2c_ctc_algo; + adap->dev.parent = dev->dev; + i2c_set_adapdata(adap, dev); + + i2c_ctc_disable_intr(dev); + if (dev->xfer_type == CTC_IC_INTERRUPT_TRANSFER) { + ret = devm_request_irq(dev->dev, dev->irq, i2c_ctc_isr, + IRQF_SHARED | IRQF_COND_SUSPEND, + dev_name(dev->dev), dev); + if (ret) { + dev_err(dev->dev, "failure requesting irq %i: %d\n", + dev->irq, ret); + return ret; + } + } + ret = i2c_add_numbered_adapter(adap); + if (ret) + dev_err(dev->dev, "failure adding adapter: %d\n", ret); + + return ret; +} + +static int ctc_i2c_plat_probe(struct platform_device *pdev) +{ + struct ctc_i2c_dev *dev; + struct i2c_adapter *adap; + struct resource *mem; + int irq, ret; + u32 clk_freq, ht; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + dev = devm_kzalloc(&pdev->dev, sizeof(struct ctc_i2c_dev), GFP_KERNEL); + if (!dev) + return -ENOMEM; + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + dev->base = devm_ioremap_resource(&pdev->dev, mem); + if (IS_ERR(dev->base)) + return PTR_ERR(dev->base); + + dev->dev = &pdev->dev; + dev->irq = irq; + platform_set_drvdata(pdev, dev); + + of_property_read_u32(pdev->dev.of_node, "clock-frequency", &clk_freq); + + dev->clk_freq = clk_freq; + if (dev->clk_freq <= 100000) + dev->master_cfg |= CTC_IC_CON_SPEED_STD; + else if (dev->clk_freq <= 400000) + dev->master_cfg |= CTC_IC_CON_SPEED_FAST; + else { + dev_err(&pdev->dev, "Unsupported this frequency\n"); + return -EINVAL; + } + + dev->master_cfg |= + CTC_IC_CON_MASTER | CTC_IC_CON_SLAVE_DISABLE | + CTC_IC_CON_RESTART_EN; + + dev->functionality = + I2C_FUNC_I2C | + I2C_FUNC_10BIT_ADDR | + I2C_FUNC_SMBUS_BYTE | + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_I2C_BLOCK; + + dev->clk = devm_clk_get(&pdev->dev, NULL); + clk_prepare_enable(dev->clk); + + if (!of_property_read_u32 + (pdev->dev.of_node, "i2c-sda-hold-time-ns", &ht)) { + dev->sda_hold_time = ht / IC_ICK_NS(clk_get_rate(dev->clk)); + } + + if (of_property_read_bool(pdev->dev.of_node, "i2c-polling-xfer")) + dev->xfer_type = CTC_IC_POLLING_TRANSFER; + else + dev->xfer_type = CTC_IC_INTERRUPT_TRANSFER; + + dev->adapter.nr = pdev->id; + adap = &dev->adapter; + adap->owner = THIS_MODULE; + adap->class = I2C_CLASS_DEPRECATED; + adap->dev.of_node = pdev->dev.of_node; + + ret = i2c_ctc_probe(dev); + return ret; +} + +static int ctc_i2c_plat_remove(struct platform_device *pdev) +{ + struct ctc_i2c_dev *dev = platform_get_drvdata(pdev); + + i2c_del_adapter(&dev->adapter); + + /* Disable controller */ + __i2c_ctc_enable(dev, false); + + /* Disable all interupts */ + ctc_writel(dev, 0, CTC_IC_INTR_MASK); + ctc_readl(dev, CTC_IC_CLR_INTR); + + return 0; +} + +static const struct of_device_id ctc_i2c_of_match[] = { + {.compatible = "ctc,i2c",}, + {}, +}; + +MODULE_DEVICE_TABLE(of, ctc_i2c_of_match); + +static struct platform_driver ctc_i2c_driver = { + .probe = ctc_i2c_plat_probe, + .remove = ctc_i2c_plat_remove, + .driver = { + .name = "i2c_centec", + .of_match_table = of_match_ptr(ctc_i2c_of_match), + }, +}; + +static int __init ctc_i2c_init_driver(void) +{ + return platform_driver_register(&ctc_i2c_driver); +} + +subsys_initcall(ctc_i2c_init_driver); + +static void __exit ctc_i2c_exit_driver(void) +{ + platform_driver_unregister(&ctc_i2c_driver); +} + +module_exit(ctc_i2c_exit_driver); + +MODULE_AUTHOR("Centec, Inc."); +MODULE_LICENSE("GPL"); diff --git a/platform/centec-arm64/tsingma-bsp/src/i2c-ctc/i2c-ctc.h b/platform/centec-arm64/tsingma-bsp/src/i2c-ctc/i2c-ctc.h new file mode 100644 index 000000000000..c27079646a30 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/i2c-ctc/i2c-ctc.h @@ -0,0 +1,162 @@ +/* Author: Wangyb + * + * Copyright 2005-2018, Centec Networks (Suzhou) Co., Ltd. + * + */ + +#define CTC_IC_CON_MASTER 0x1 +#define CTC_IC_CON_SPEED_STD 0x2 +#define CTC_IC_CON_SPEED_FAST 0x4 +#define CTC_IC_CON_SPEED_MASK 0x6 +#define CTC_IC_CON_10BITADDR_MASTER 0x10 +#define CTC_IC_CON_RESTART_EN 0x20 +#define CTC_IC_CON_SLAVE_DISABLE 0x40 + +#define CTC_SCL_Timing(T) (1000000000 / T) /* in nanoseconds */ + +/* + * Registers offset + */ +#define CTC_IC_CON 0x0 +#define CTC_IC_TAR 0x4 +#define CTC_IC_DATA_CMD 0x10 +#define CTC_IC_SS_SCL_HCNT 0x14 +#define CTC_IC_SS_SCL_LCNT 0x18 +#define CTC_IC_FS_SCL_HCNT 0x1c +#define CTC_IC_FS_SCL_LCNT 0x20 +#define CTC_IC_INTR_STAT 0x2c +#define CTC_IC_INTR_MASK 0x30 +#define CTC_IC_RAW_INTR_STAT 0x34 +#define CTC_IC_RX_TL 0x38 +#define CTC_IC_TX_TL 0x3c +#define CTC_IC_CLR_INTR 0x40 +#define CTC_IC_CLR_RX_UNDER 0x44 +#define CTC_IC_CLR_RX_OVER 0x48 +#define CTC_IC_CLR_TX_OVER 0x4c +#define CTC_IC_CLR_RD_REQ 0x50 +#define CTC_IC_CLR_TX_ABRT 0x54 +#define CTC_IC_CLR_RX_DONE 0x58 +#define CTC_IC_CLR_ACTIVITY 0x5c +#define CTC_IC_CLR_STOP_DET 0x60 +#define CTC_IC_CLR_START_DET 0x64 +#define CTC_IC_CLR_GEN_CALL 0x68 +#define CTC_IC_ENABLE 0x6c +#define CTC_IC_STATUS 0x70 +#define CTC_IC_TXFLR 0x74 +#define CTC_IC_RXFLR 0x78 +#define CTC_IC_SDA_HOLD 0x7c +#define CTC_IC_TX_ABRT_SOURCE 0x80 +#define CTC_IC_ENABLE_STATUS 0x9c +#define CTC_IC_COMP_PARAM_1 0xf4 +#define CTC_IC_COMP_VERSION 0xf8 +#define CTC_IC_SDA_HOLD_MIN_VERS 0x3131312A +#define CTC_IC_COMP_TYPE 0xfc +#define CTC_IC_COMP_TYPE_VALUE 0x44570140 + +#define CTC_IC_STATUS_ACTIVITY 0x1 +#define CTC_IC_TAR_10BITADDR_MASTER BIT(12) +#define CTC_IC_ERR_TX_ABRT 0x1 + +#define CTC_IC_INTR_RX_UNDER 0x001 +#define CTC_IC_INTR_RX_OVER 0x002 +#define CTC_IC_INTR_RX_FULL 0x004 +#define CTC_IC_INTR_TX_OVER 0x008 +#define CTC_IC_INTR_TX_EMPTY 0x010 +#define CTC_IC_INTR_RD_REQ 0x020 +#define CTC_IC_INTR_TX_ABRT 0x040 +#define CTC_IC_INTR_RX_DONE 0x080 +#define CTC_IC_INTR_ACTIVITY 0x100 +#define CTC_IC_INTR_STOP_DET 0x200 +#define CTC_IC_INTR_START_DET 0x400 +#define CTC_IC_INTR_GEN_CALL 0x800 + +#define CTC_IC_INTR_DEFAULT_MASK (CTC_IC_INTR_RX_FULL | \ + CTC_IC_INTR_TX_EMPTY | \ + CTC_IC_INTR_TX_ABRT | \ + CTC_IC_INTR_STOP_DET) + +/* + * status codes + */ +#define STATUS_IDLE 0x0 +#define STATUS_WRITE_IN_PROGRESS 0x1 +#define STATUS_READ_IN_PROGRESS 0x2 + +#define ABRT_7B_ADDR_NOACK 0 +#define ABRT_10ADDR1_NOACK 1 +#define ABRT_10ADDR2_NOACK 2 +#define ABRT_TXDATA_NOACK 3 +#define ABRT_GCALL_NOACK 4 +#define ABRT_GCALL_READ 5 +#define ABRT_SBYTE_ACKDET 7 +#define ABRT_SBYTE_NORSTRT 9 +#define ABRT_10B_RD_NORSTRT 10 +#define ABRT_MASTER_DIS 11 +#define ARB_LOST 12 + +#define CTC_IC_TX_ABRT_7B_ADDR_NOACK (1UL << ABRT_7B_ADDR_NOACK) +#define CTC_IC_TX_ABRT_10ADDR1_NOACK (1UL << ABRT_10ADDR1_NOACK) +#define CTC_IC_TX_ABRT_10ADDR2_NOACK (1UL << ABRT_10ADDR2_NOACK) +#define CTC_IC_TX_ABRT_TXDATA_NOACK (1UL << ABRT_TXDATA_NOACK) +#define CTC_IC_TX_ABRT_GCALL_NOACK (1UL << ABRT_GCALL_NOACK) +#define CTC_IC_TX_ABRT_GCALL_READ (1UL << ABRT_GCALL_READ) +#define CTC_IC_TX_ABRT_SBYTE_ACKDET (1UL << ABRT_SBYTE_ACKDET) +#define CTC_IC_TX_ABRT_SBYTE_NORSTRT (1UL << ABRT_SBYTE_NORSTRT) +#define CTC_IC_TX_ABRT_10B_RD_NORSTRT (1UL << ABRT_10B_RD_NORSTRT) +#define CTC_IC_TX_ABRT_MASTER_DIS (1UL << ABRT_MASTER_DIS) +#define CTC_IC_TX_ARB_LOST (1UL << ARB_LOST) + +#define CTC_IC_TX_ABRT_NOACK (CTC_IC_TX_ABRT_7B_ADDR_NOACK | \ + CTC_IC_TX_ABRT_10ADDR1_NOACK | \ + CTC_IC_TX_ABRT_10ADDR2_NOACK | \ + CTC_IC_TX_ABRT_TXDATA_NOACK | \ + CTC_IC_TX_ABRT_GCALL_NOACK) + +#define CTC_CMD_READ 0x0100 +#define CTC_STOP 0x0200 +#define CTC_RESTART 0x0400 + +#define CTC_IC_STATUS_RFNE 0x0008 +#define CTC_IC_STATUS_TFNF 0x0002 + +#define I2C_BYTE_TO 1 /* means 1 jiffies = 4ms */ +#define I2C_STOPDET_TO 1 /* means 1 jiffies = 4ms */ + +#define CTC_IC_STATUS_MA 0x0020 +#define CTC_IC_STATUS_TFE 0x0004 + +enum xfer_type_e { + CTC_IC_INTERRUPT_TRANSFER, + CTC_IC_POLLING_TRANSFER +}; + +struct ctc_i2c_dev { + struct device *dev; + void __iomem *base; + struct completion cmd_complete; + struct clk *clk; + struct mutex lock; + u32 master_cfg; + int irq; + unsigned int rx_fifo_depth; + unsigned int tx_fifo_depth; + struct i2c_adapter adapter; + struct i2c_msg *msgs; + int msgs_num; + int msg_err; + int cmd_err; + unsigned int status; + u32 abort_source; + int msg_read_idx; + int rx_outstanding; + int msg_write_idx; + u32 tx_buf_len; + u8 *tx_buf; + u32 rx_buf_len; + u8 *rx_buf; + u32 accessor_flags; + u32 functionality; + u32 clk_freq; + u32 sda_hold_time; + u32 xfer_type; +}; diff --git a/platform/centec-arm64/tsingma-bsp/src/include/ctc5236_switch.h b/platform/centec-arm64/tsingma-bsp/src/include/ctc5236_switch.h new file mode 100644 index 000000000000..aba77b10be32 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/include/ctc5236_switch.h @@ -0,0 +1,43 @@ +#ifndef __CTC5236_SWITCH_H +#define __CTC5236_SWITCH_H + +#define OMCMEM_BASE 0x00041000 +#define SYS_TSINGMA_MDIO_CTLR_NUM 2 +#define SYS_TSINGMA_TEMP_TABLE_NUM 166 +#define SYS_TSINGMA_SENSOR_TIMEOUT 1000 + +struct ctc_switch_cmd_status_t { + u32 cmdReadType:1; + u32 pcieReqCmdChk:3; + u32 cmdEntryWords:4; + u32 cmdDataLen:5; + u32 reserved:1; + u32 pcieReqError:1; + u32 pcieDataError:1; + u32 reqProcDone:1; + u32 reqProcError:1; + u32 reqProcTimeout:1; + u32 reqProcAckError:1; + u32 reqProcAckCnt:5; + u32 regProcBusy:1; + u32 cmdStatusWaitReq:1; + u32 pciePoisoned:1; + u32 regProcState:3; + u32 pcieReqOverlap:1; +}; + +union ctc_switch_cmd_status_u_t { + struct ctc_switch_cmd_status_t cmd_status; + u32 val; +}; + +struct ctc_access_t { + u32 cmd_status; + u32 addr; + u32 data[16]; +}; + +extern int ctc5236_switch_read(u32 offset, u32 len, u32 *p_value); +extern int ctc5236_switch_write(u32 offset, u32 len, u32 *p_value); +extern int get_switch_temperature(void); +#endif diff --git a/platform/centec-arm64/tsingma-bsp/src/include/sysctl.h b/platform/centec-arm64/tsingma-bsp/src/include/sysctl.h new file mode 100644 index 000000000000..2201db88558f --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/include/sysctl.h @@ -0,0 +1,2714 @@ +/* + * (C) Copyright 2004-2017 Centec Networks (suzhou) Co., LTD. + * Jay Cao + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef __CTC5236_SYSCTL_H__ +#define __CTC5236_SYSCTL_H__ + +#ifndef __ASSEMBLY__ + +/* define SYSCTL_MEM_BASE 0x0000fe00 */ +/* defing SYSCTL_REG_BASE 0x00000000 */ + +struct SysCtl_regs { + u32 SysResetCtl; /* 0x00000000 */ + u32 SysResetAutoEn; /* 0x00000004 */ + u32 SysGicResetCtl; /* 0x00000008 */ + u32 rsv3; + u32 SysWdtResetCtl; /* 0x00000010 */ + u32 SysDmaResetCtl; /* 0x00000014 */ + u32 SysDdrResetCtl; /* 0x00000018 */ + u32 SysPcieResetCtl; /* 0x0000001c */ + u32 SysMacResetCtl; /* 0x00000020 */ + u32 SysMshResetCtl; /* 0x00000024 */ + u32 SysUsbResetCtl; /* 0x00000028 */ + u32 SysSpiResetCtl; /* 0x0000002c */ + u32 SysQspiResetCtl; /* 0x00000030 */ + u32 SysAxiSupResetCtl; /* 0x00000034 */ + u32 SysGpioResetCtl; /* 0x00000038 */ + u32 SysI2CResetCtl; /* 0x0000003c */ + u32 SysMdioSocResetCtl; /* 0x00000040 */ + u32 SysTimerResetCtl; /* 0x00000044 */ + u32 SysUartResetCtl; /* 0x00000048 */ + u32 SysTraceResetCtl; /* 0x0000004c */ + u32 SysDbg0ResetEnCtl; /* 0x00000050 */ + u32 SysDbg1ResetEnCtl; /* 0x00000054 */ + u32 SysWarm0ResetEnCtl; /* 0x00000058 */ + u32 SysWarm1ResetEnCtl; /* 0x0000005c */ + u32 SysWdt0ResetEnCtl; /* 0x00000060 */ + u32 SysWdt1ResetEnCtl; /* 0x00000064 */ + u32 SysCtlReserved; /* 0x00000068 */ + u32 SysEnClkCfg; /* 0x0000006c */ + u32 SysPllSocCfg0; /* 0x00000070 */ + u32 SysPllSocCfg1; /* 0x00000074 */ + u32 SysPllDdrCfg0; /* 0x00000078 */ + u32 SysPllDdrCfg1; /* 0x0000007c */ + u32 SysClkSelCfg; /* 0x00000080 */ + u32 SysClkDivCfg; /* 0x00000084 */ + u32 SysClkPeriCfg[2]; /* 0x00000088 */ + u32 SysDbgCreditCtl; /* 0x00000090 */ + u32 rsv37; + u32 SysI2CMultiCtl; /* 0x00000098 */ + u32 BootStrapPin; /* 0x0000009c */ + u32 SysCntValue[2]; /* 0x000000a0 */ + u32 SysCntLog; /* 0x000000a8 */ + u32 rsv43; + u32 rsv44; + u32 rsv45; + u32 SysCoreGicAddrBase; /* 0x000000b8 */ + u32 rsv47; + u32 SysCorePmCfg; /* 0x000000c0 */ + u32 SysCoreStatus; /* 0x000000c4 */ + u32 SysCorePmuEvent0; /* 0x000000c8 */ + u32 SysCorePmuEvent1; /* 0x000000cc */ + u32 SysRstVecBar0[2]; /* 0x000000d0 */ + u32 SysRstVecBar1[2]; /* 0x000000d8 */ + u32 SysGicCfg; /* 0x000000e0 */ + u32 SysGicStatus; /* 0x000000e4 */ + u32 rsv58; + u32 SysMemCtl; /* 0x000000ec */ + u32 SysDmaMapCfg; /* 0x000000f0 */ + u32 SysDmaAbortCfg; /* 0x000000f4 */ + u32 rsv62; + u32 rsv63; + u32 SysCstCfg; /* 0x00000100 */ + u32 SysCstTargetIdCfg; /* 0x00000104 */ + u32 SysCstMemMapIdCfg; /* 0x00000108 */ + u32 rsv67; + u32 SysQspiBootCfg0; /* 0x00000110 */ + u32 SysQspiBootCfg1; /* 0x00000114 */ + u32 SysQspiBootCfg2; /* 0x00000118 */ + u32 SysQspiBootCfg3; /* 0x0000011c */ + u32 SysDdrCfg; /* 0x00000120 */ + u32 rsv73; + u32 SysSpiSelCfg; /* 0x00000128 */ + u32 SysMdioSocCfg; /* 0x0000012c */ + u32 SysWdt0Cnt; /* 0x00000130 */ + u32 SysWdt0Rev; /* 0x00000134 */ + u32 SysWdt1Cnt; /* 0x00000138 */ + u32 SysWdt1Rev; /* 0x0000013c */ + u32 SysMshCfg; /* 0x00000140 */ + u32 SysMshStatus; /* 0x00000144 */ + u32 SysUsbCfg0; /* 0x00000148 */ + u32 SysUsbCfg1; /* 0x0000014c */ + u32 SysUsbCfg2; /* 0x00000150 */ + u32 SysUsbStatus; /* 0x00000154 */ + u32 rsv86; + u32 rsv87; + u32 rsv88; + u32 rsv89; + u32 rsv90; + u32 rsv91; + u32 rsv92; + u32 rsv93; + u32 SysPcieBaseCfg; /* 0x00000178 */ + u32 SysRegCfg; /* 0x0000017c */ + u32 SysInitCtl[2]; /* 0x00000180 */ + u32 SysPllSupCfg0; /* 0x00000188 */ + u32 SysPllSupCfg1; /* 0x0000018c */ + u32 SysApbProcTimer; /* 0x00000190 */ + u32 rsv101; + u32 SysUsbTest[2]; /* 0x00000198 */ + u32 SysGpioMultiCtl; /* 0x000001a0 */ + u32 rsv105; + u32 SysGpioHsMultiCtl[2]; /* 0x000001a8 */ + u32 rsv108; + u32 rsv109; + u32 SysPcieStatus[2]; /* 0x000001b8 */ + u32 SysMsixStatus[8]; /* 0x000001c0 */ + u32 SysMsixMask[8]; /* 0x000001e0 */ + u32 SysMsixAddr; /* 0x00000200 */ + u32 SysMsixVecCtl; /* 0x00000204 */ + u32 SysMsixAddrEn; /* 0x00000208 */ + u32 SysMsixIntrLog; /* 0x0000020c */ + u32 SysDebugCtl; /* 0x00000210 */ + u32 rsv133; + u32 rsv134; + u32 rsv135; + u32 SysMsixPending[8]; /* 0x00000220 */ + u32 SysPwmCtl[8]; /* 0x00000240 */ + u32 SysTachLog[8]; /* 0x00000260 */ + u32 MonAxiCpuCurInfo[14]; /* 0x00000280 */ + u32 rsv174; + u32 rsv175; + u32 MonAxiCpuLogInfo[14]; /* 0x000002c0 */ + u32 rsv190; + u32 rsv191; + u32 MonAxiDdr0CurInfo[14]; /* 0x00000300 */ + u32 rsv206; + u32 rsv207; + u32 MonAxiDdr0LogInfo[14]; /* 0x00000340 */ + u32 rsv222; + u32 rsv223; + u32 MonAxiDdr1CurInfo[10]; /* 0x00000380 */ + u32 rsv234; + u32 rsv235; + u32 rsv236; + u32 rsv237; + u32 rsv238; + u32 rsv239; + u32 MonAxiDdr1LogInfo[10]; /* 0x000003c0 */ + u32 rsv250; + u32 rsv251; + u32 rsv252; + u32 rsv253; + u32 rsv254; + u32 rsv255; + u32 MonAxiMemCurInfo[10]; /* 0x00000400 */ + u32 rsv266; + u32 rsv267; + u32 rsv268; + u32 rsv269; + u32 rsv270; + u32 rsv271; + u32 MonAxiMemLogInfo[10]; /* 0x00000440 */ + u32 rsv282; + u32 rsv283; + u32 rsv284; + u32 rsv285; + u32 rsv286; + u32 rsv287; + u32 MonAxiMshCurInfo[9]; /* 0x00000480 */ + u32 rsv297; + u32 rsv298; + u32 rsv299; + u32 rsv300; + u32 rsv301; + u32 rsv302; + u32 rsv303; + u32 MonAxiMshLogInfo[9]; /* 0x000004c0 */ + u32 rsv313; + u32 rsv314; + u32 rsv315; + u32 rsv316; + u32 rsv317; + u32 rsv318; + u32 rsv319; + u32 MonAxiPcieCurInfo[10]; /* 0x00000500 */ + u32 rsv330; + u32 rsv331; + u32 rsv332; + u32 rsv333; + u32 rsv334; + u32 rsv335; + u32 MonAxiPcieLogInfo[10]; /* 0x00000540 */ + u32 rsv346; + u32 rsv347; + u32 rsv348; + u32 rsv349; + u32 rsv350; + u32 rsv351; + u32 MonAxiQspiCurInfo[7]; /* 0x00000580 */ + u32 rsv359; + u32 MonAxiQspiLogInfo[8]; /* 0x000005a0 */ + u32 MonAxiSupCurInfo[8]; /* 0x000005c0 */ + u32 MonAxiSupLogInfo[8]; /* 0x000005e0 */ + u32 MonSysApbCurInfo[4]; /* 0x00000600 */ + u32 MonSysApbLogInfo[4]; /* 0x00000610 */ + u32 MonSecApbCurInfo[4]; /* 0x00000620 */ + u32 MonSecApbLogInfo[4]; /* 0x00000630 */ + u32 DebugCpuCnt[2]; /* 0x00000640 */ + u32 DebugMemCnt[2]; /* 0x00000648 */ + u32 DebugDdrCnt[4]; /* 0x00000650 */ + u32 DebugMshCnt[2]; /* 0x00000660 */ + u32 DebugPcieCnt[2]; /* 0x00000668 */ + u32 DebugQspiCnt[2]; /* 0x00000670 */ + u32 DebugSupCnt[2]; /* 0x00000678 */ + u32 SysSpiVecLog[5]; /* 0x00000680 */ + u32 rsv421; + u32 rsv422; + u32 rsv423; + u32 DebugAhbRespCnt; /* 0x000006a0 */ + u32 DebugGicRespCnt; /* 0x000006a4 */ + u32 DebugMemPtrCfg; /* 0x000006a8 */ + u32 rsv427; + u32 rsv428; + u32 rsv429; + u32 rsv430; + u32 rsv431; + u32 rsv432; + u32 rsv433; + u32 rsv434; + u32 rsv435; + u32 rsv436; + u32 rsv437; + u32 rsv438; + u32 rsv439; + u32 rsv440; + u32 rsv441; + u32 rsv442; + u32 rsv443; + u32 rsv444; + u32 rsv445; + u32 rsv446; + u32 rsv447; + u32 Grant0IntMask; /* 0x00000700 */ + u32 Grant0IntCtl; /* 0x00000704 */ + u32 Grant1IntMask; /* 0x00000708 */ + u32 Grant1IntCtl; /* 0x0000070c */ + u32 Grant2IntMask; /* 0x00000710 */ + u32 Grant2IntCtl; /* 0x00000714 */ + u32 Grant3IntMask; /* 0x00000718 */ + u32 Grant3IntCtl; /* 0x0000071c */ + u32 SysIntrIntCtl[2]; /* 0x00000720 */ + u32 SupIntrIntCtl[2]; /* 0x00000728 */ + u32 SysMiscInfo0; /* 0x00000730 */ + u32 SysMiscInfo1; /* 0x00000734 */ + u32 SysMiscInfo2; /* 0x00000738 */ + u32 SysMiscInfo3; /* 0x0000073c */ + u32 CommonInfo0; /* 0x00000740 */ + u32 CommonInfo1; /* 0x00000744 */ + u32 CommonInfo2; /* 0x00000748 */ + u32 CommonInfo3; /* 0x0000074c */ + u32 rsv468; + u32 rsv469; + u32 rsv470; + u32 rsv471; + u32 rsv472; + u32 rsv473; + u32 rsv474; + u32 rsv475; + u32 rsv476; + u32 rsv477; + u32 rsv478; + u32 rsv479; + u32 Grant0ExtMask; /* 0x00000780 */ + u32 Grant0ExtCtl; /* 0x00000784 */ + u32 Grant1ExtMask; /* 0x00000788 */ + u32 Grant1ExtCtl; /* 0x0000078c */ + u32 Grant2ExtMask; /* 0x00000790 */ + u32 Grant2ExtCtl; /* 0x00000794 */ + u32 Grant3ExtMask; /* 0x00000798 */ + u32 Grant3ExtCtl; /* 0x0000079c */ + u32 SysIntrExtCtl[2]; /* 0x000007a0 */ + u32 SupIntrExtCtl[2]; /* 0x000007a8 */ + u32 SupMiscInfo0; /* 0x000007b0 */ + u32 SupMiscInfo1; /* 0x000007b4 */ + u32 SupMiscInfo2; /* 0x000007b8 */ + u32 SupMiscInfo3; /* 0x000007bc */ +}; + +/* ############################################################################ + * # SysResetCtl Definition + */ +#define SYS_RESET_CTL_W0_CFG_NIC_RESET BIT(9) +#define SYS_RESET_CTL_W0_LOG_CST_RESET BIT(23) +#define SYS_RESET_CTL_W0_CFG_SYS_APB_RESET BIT(12) +#define SYS_RESET_CTL_W0_LOG_NIC_RESET BIT(25) +#define SYS_RESET_CTL_W0_LOG_CPU0_COLD_RESET BIT(16) +#define SYS_RESET_CTL_W0_CFG_CPU_APB_RESET BIT(5) +#define SYS_RESET_CTL_W0_CFG_CPU1_COLD_RESET BIT(1) +#define SYS_RESET_CTL_W0_CFG_CPU1_CORE_RESET BIT(3) +#define SYS_RESET_CTL_W0_LOG_CPU_APB_RESET BIT(21) +#define SYS_RESET_CTL_W0_CFG_SEC_APB_RESET BIT(11) +#define SYS_RESET_CTL_W0_CFG_CPU0_CORE_RESET BIT(2) +#define SYS_RESET_CTL_W0_LOG_SEC_APB_RESET BIT(27) +#define SYS_RESET_CTL_W0_CFG_CPU0_COLD_RESET BIT(0) +#define SYS_RESET_CTL_W0_CFG_CST_RESET BIT(7) +#define SYS_RESET_CTL_W0_LOG_JTAG_POT_RESET BIT(22) +#define SYS_RESET_CTL_W0_LOG_CPU1_CORE_RESET BIT(19) +#define SYS_RESET_CTL_W0_LOG_SYS_APB_RESET BIT(28) +#define SYS_RESET_CTL_W0_LOG_CPU0_CORE_RESET BIT(18) +#define SYS_RESET_CTL_W0_LOG_CPU1_COLD_RESET BIT(17) +#define SYS_RESET_CTL_W0_LOG_CPU_L2_RESET BIT(20) +#define SYS_RESET_CTL_W0_LOG_GPV_RESET BIT(26) +#define SYS_RESET_CTL_W0_CFG_CPU_L2_RESET BIT(4) +#define SYS_RESET_CTL_W0_CFG_GPV_RESET BIT(10) +#define SYS_RESET_CTL_W0_CFG_JTAG_POT_RESET BIT(6) +#define SYS_RESET_CTL_W0_CFG_CPU_MEM_RESET BIT(8) +#define SYS_RESET_CTL_W0_LOG_CPU_MEM_RESET BIT(24) + +#define SYS_RESET_CTL_W0_CFG_NIC_RESET_MASK 0x00000200 +#define SYS_RESET_CTL_W0_LOG_CST_RESET_MASK 0x00800000 +#define SYS_RESET_CTL_W0_CFG_SYS_APB_RESET_MASK 0x00001000 +#define SYS_RESET_CTL_W0_LOG_NIC_RESET_MASK 0x02000000 +#define SYS_RESET_CTL_W0_LOG_CPU0_COLD_RESET_MASK 0x00010000 +#define SYS_RESET_CTL_W0_CFG_CPU_APB_RESET_MASK 0x00000020 +#define SYS_RESET_CTL_W0_CFG_CPU1_COLD_RESET_MASK 0x00000002 +#define SYS_RESET_CTL_W0_CFG_CPU1_CORE_RESET_MASK 0x00000008 +#define SYS_RESET_CTL_W0_LOG_CPU_APB_RESET_MASK 0x00200000 +#define SYS_RESET_CTL_W0_CFG_SEC_APB_RESET_MASK 0x00000800 +#define SYS_RESET_CTL_W0_CFG_CPU0_CORE_RESET_MASK 0x00000004 +#define SYS_RESET_CTL_W0_LOG_SEC_APB_RESET_MASK 0x08000000 +#define SYS_RESET_CTL_W0_CFG_CPU0_COLD_RESET_MASK 0x00000001 +#define SYS_RESET_CTL_W0_CFG_CST_RESET_MASK 0x00000080 +#define SYS_RESET_CTL_W0_LOG_JTAG_POT_RESET_MASK 0x00400000 +#define SYS_RESET_CTL_W0_LOG_CPU1_CORE_RESET_MASK 0x00080000 +#define SYS_RESET_CTL_W0_LOG_SYS_APB_RESET_MASK 0x10000000 +#define SYS_RESET_CTL_W0_LOG_CPU0_CORE_RESET_MASK 0x00040000 +#define SYS_RESET_CTL_W0_LOG_CPU1_COLD_RESET_MASK 0x00020000 +#define SYS_RESET_CTL_W0_LOG_CPU_L2_RESET_MASK 0x00100000 +#define SYS_RESET_CTL_W0_LOG_GPV_RESET_MASK 0x04000000 +#define SYS_RESET_CTL_W0_CFG_CPU_L2_RESET_MASK 0x00000010 +#define SYS_RESET_CTL_W0_CFG_GPV_RESET_MASK 0x00000400 +#define SYS_RESET_CTL_W0_CFG_JTAG_POT_RESET_MASK 0x00000040 +#define SYS_RESET_CTL_W0_CFG_CPU_MEM_RESET_MASK 0x00000100 +#define SYS_RESET_CTL_W0_LOG_CPU_MEM_RESET_MASK 0x01000000 + +/* ############################################################################ + * # SysResetAutoEn Definition + */ +#define SYS_RESET_AUTO_EN_W0_CFG_CPU1_CORE_RESET_AUTO_EN BIT(3) +#define SYS_RESET_AUTO_EN_W0_CFG_NIC_RESET_AUTO_EN BIT(9) +#define SYS_RESET_AUTO_EN_W0_CFG_CST_RESET_AUTO_EN BIT(7) +#define SYS_RESET_AUTO_EN_W0_CFG_WDT1_RESET_AUTO_EN BIT(14) +#define SYS_RESET_AUTO_EN_W0_CFG_CPU0_COLD_RESET_AUTO_EN BIT(0) +#define SYS_RESET_AUTO_EN_W0_CFG_GPV_RESET_AUTO_EN BIT(10) +#define SYS_RESET_AUTO_EN_W0_CFG_WDT0_RESET_AUTO_EN BIT(13) +#define SYS_RESET_AUTO_EN_W0_CFG_JTAG_POT_RESET_AUTO_EN BIT(6) +#define SYS_RESET_AUTO_EN_W0_CFG_SEC_APB_RESET_AUTO_EN BIT(11) +#define SYS_RESET_AUTO_EN_W0_CFG_CPU_MEM_RESET_AUTO_EN BIT(8) +#define SYS_RESET_AUTO_EN_W0_CFG_SYS_APB_RESET_AUTO_EN BIT(12) +#define SYS_RESET_AUTO_EN_W0_CFG_CPU_L2_RESET_AUTO_EN BIT(4) +#define SYS_RESET_AUTO_EN_W0_CFG_CPU_APB_RESET_AUTO_EN BIT(5) +#define SYS_RESET_AUTO_EN_W0_CFG_CPU1_COLD_RESET_AUTO_EN BIT(1) +#define SYS_RESET_AUTO_EN_W0_CFG_CPU0_CORE_RESET_AUTO_EN BIT(2) + +#define SYS_RESET_AUTO_EN_W0_CFG_CPU1_CORE_RESET_AUTO_EN_MASK 0x00000008 +#define SYS_RESET_AUTO_EN_W0_CFG_NIC_RESET_AUTO_EN_MASK 0x00000200 +#define SYS_RESET_AUTO_EN_W0_CFG_CST_RESET_AUTO_EN_MASK 0x00000080 +#define SYS_RESET_AUTO_EN_W0_CFG_WDT1_RESET_AUTO_EN_MASK 0x00004000 +#define SYS_RESET_AUTO_EN_W0_CFG_CPU0_COLD_RESET_AUTO_EN_MASK 0x00000001 +#define SYS_RESET_AUTO_EN_W0_CFG_GPV_RESET_AUTO_EN_MASK 0x00000400 +#define SYS_RESET_AUTO_EN_W0_CFG_WDT0_RESET_AUTO_EN_MASK 0x00002000 +#define SYS_RESET_AUTO_EN_W0_CFG_JTAG_POT_RESET_AUTO_EN_MASK 0x00000040 +#define SYS_RESET_AUTO_EN_W0_CFG_SEC_APB_RESET_AUTO_EN_MASK 0x00000800 +#define SYS_RESET_AUTO_EN_W0_CFG_CPU_MEM_RESET_AUTO_EN_MASK 0x00000100 +#define SYS_RESET_AUTO_EN_W0_CFG_SYS_APB_RESET_AUTO_EN_MASK 0x00001000 +#define SYS_RESET_AUTO_EN_W0_CFG_CPU_L2_RESET_AUTO_EN_MASK 0x00000010 +#define SYS_RESET_AUTO_EN_W0_CFG_CPU_APB_RESET_AUTO_EN_MASK 0x00000020 +#define SYS_RESET_AUTO_EN_W0_CFG_CPU1_COLD_RESET_AUTO_EN_MASK 0x00000002 +#define SYS_RESET_AUTO_EN_W0_CFG_CPU0_CORE_RESET_AUTO_EN_MASK 0x00000004 + +/* ############################################################################ + * # SysGicResetCtl Definition + */ +#define SYS_GIC_RESET_CTL_W0_CFG_GIC_RESET BIT(0) + +#define SYS_GIC_RESET_CTL_W0_CFG_GIC_RESET_MASK 0x00000001 + +/* ############################################################################ + * # SysWdtResetCtl Definition + */ +#define SYS_WDT_RESET_CTL_W0_LOG_WDT1_RESET BIT(5) +#define SYS_WDT_RESET_CTL_W0_CFG_WDT0_RESET BIT(0) +#define SYS_WDT_RESET_CTL_W0_LOG_WDT0_RESET BIT(4) +#define SYS_WDT_RESET_CTL_W0_CFG_WDT1_RESET BIT(1) + +#define SYS_WDT_RESET_CTL_W0_LOG_WDT1_RESET_MASK 0x00000020 +#define SYS_WDT_RESET_CTL_W0_CFG_WDT0_RESET_MASK 0x00000001 +#define SYS_WDT_RESET_CTL_W0_LOG_WDT0_RESET_MASK 0x00000010 +#define SYS_WDT_RESET_CTL_W0_CFG_WDT1_RESET_MASK 0x00000002 + +/* ############################################################################ + * # SysDmaResetCtl Definition + */ +#define SYS_DMA_RESET_CTL_W0_CFG_CPU_DMA_RESET BIT(0) + +#define SYS_DMA_RESET_CTL_W0_CFG_CPU_DMA_RESET_MASK 0x00000001 + +/* ############################################################################ + * # SysDdrResetCtl Definition + */ +#define SYS_DDR_RESET_CTL_W0_CFG_DDR_MC_RESET BIT(2) +#define SYS_DDR_RESET_CTL_W0_CFG_DDR_CFG_RESET BIT(0) +#define SYS_DDR_RESET_CTL_W0_CFG_DDR_AXI_RESET BIT(1) + +#define SYS_DDR_RESET_CTL_W0_CFG_DDR_MC_RESET_MASK 0x00000004 +#define SYS_DDR_RESET_CTL_W0_CFG_DDR_CFG_RESET_MASK 0x00000001 +#define SYS_DDR_RESET_CTL_W0_CFG_DDR_AXI_RESET_MASK 0x00000002 + +/* ############################################################################ + * # SysPcieResetCtl Definition + */ +#define SYS_PCIE_RESET_CTL_W0_CFG_PIPE_RESET BIT(1) +#define SYS_PCIE_RESET_CTL_W0_CFG_PHY_REG_RESET BIT(3) +#define SYS_PCIE_RESET_CTL_W0_CFG_PCIE_RESET BIT(0) +#define SYS_PCIE_RESET_CTL_W0_CFG_PCIE_POR BIT(2) + +#define SYS_PCIE_RESET_CTL_W0_CFG_PIPE_RESET_MASK 0x00000002 +#define SYS_PCIE_RESET_CTL_W0_CFG_PHY_REG_RESET_MASK 0x00000008 +#define SYS_PCIE_RESET_CTL_W0_CFG_PCIE_RESET_MASK 0x00000001 +#define SYS_PCIE_RESET_CTL_W0_CFG_PCIE_POR_MASK 0x00000004 + +/* ############################################################################ + * # SysMacResetCtl Definition + */ +#define SYS_MAC_RESET_CTL_W0_CFG_CPU_MAC_RESET BIT(0) + +#define SYS_MAC_RESET_CTL_W0_CFG_CPU_MAC_RESET_MASK 0x00000001 + +/* ############################################################################ + * # SysMshResetCtl Definition + */ +#define SYS_MSH_RESET_CTL_W0_CFG_MSH_C_TX_RESET BIT(3) +#define SYS_MSH_RESET_CTL_W0_CFG_MSH_C_RX_DLL_RESET BIT(6) +#define SYS_MSH_RESET_CTL_W0_CFG_MSH_CFG_RESET BIT(1) +#define SYS_MSH_RESET_CTL_W0_CFG_MSH_REF_C_RESET BIT(4) +#define SYS_MSH_RESET_CTL_W0_CFG_MSH_C_RX_RESET BIT(2) +#define SYS_MSH_RESET_CTL_W0_CFG_MSH_AXI_RESET BIT(0) +#define SYS_MSH_RESET_CTL_W0_CFG_MSH_TM_RESET BIT(5) + +#define SYS_MSH_RESET_CTL_W0_CFG_MSH_C_TX_RESET_MASK 0x00000008 +#define SYS_MSH_RESET_CTL_W0_CFG_MSH_C_RX_DLL_RESET_MASK 0x00000040 +#define SYS_MSH_RESET_CTL_W0_CFG_MSH_CFG_RESET_MASK 0x00000002 +#define SYS_MSH_RESET_CTL_W0_CFG_MSH_REF_C_RESET_MASK 0x00000010 +#define SYS_MSH_RESET_CTL_W0_CFG_MSH_C_RX_RESET_MASK 0x00000004 +#define SYS_MSH_RESET_CTL_W0_CFG_MSH_AXI_RESET_MASK 0x00000001 +#define SYS_MSH_RESET_CTL_W0_CFG_MSH_TM_RESET_MASK 0x00000020 + +/* ############################################################################ + * # SysUsbResetCtl Definition + */ +#define SYS_USB_RESET_CTL_W0_CFG_USB_INTF_RESET BIT(0) +#define SYS_USB_RESET_CTL_W0_CFG_USB_PHY_RESET BIT(2) +#define SYS_USB_RESET_CTL_W0_CFG_USB_PHY_ATE_RESET BIT(6) +#define SYS_USB_RESET_CTL_W0_CFG_USB_PHY_PORT_RESET BIT(5) +#define SYS_USB_RESET_CTL_W0_CFG_USB_UTMI_RESET BIT(3) +#define SYS_USB_RESET_CTL_W0_CFG_USB_AUX_RESET BIT(1) +#define SYS_USB_RESET_CTL_W0_CFG_USB_PHY_PWR_ON_RESET BIT(4) + +#define SYS_USB_RESET_CTL_W0_CFG_USB_INTF_RESET_MASK 0x00000001 +#define SYS_USB_RESET_CTL_W0_CFG_USB_PHY_RESET_MASK 0x00000004 +#define SYS_USB_RESET_CTL_W0_CFG_USB_PHY_ATE_RESET_MASK 0x00000040 +#define SYS_USB_RESET_CTL_W0_CFG_USB_PHY_PORT_RESET_MASK 0x00000020 +#define SYS_USB_RESET_CTL_W0_CFG_USB_UTMI_RESET_MASK 0x00000008 +#define SYS_USB_RESET_CTL_W0_CFG_USB_AUX_RESET_MASK 0x00000002 +#define SYS_USB_RESET_CTL_W0_CFG_USB_PHY_PWR_ON_RESET_MASK 0x00000010 + +/* ############################################################################ + * # SysSpiResetCtl Definition + */ +#define SYS_SPI_RESET_CTL_W0_CFG_SPI_RESET BIT(0) + +#define SYS_SPI_RESET_CTL_W0_CFG_SPI_RESET_MASK 0x00000001 + +/* ############################################################################ + * # SysQspiResetCtl Definition + */ +#define SYS_QSPI_RESET_CTL_W0_CFG_QSPI_RESET BIT(0) + +#define SYS_QSPI_RESET_CTL_W0_CFG_QSPI_RESET_MASK 0x00000001 + +/* ############################################################################ + * # SysAxiSupResetCtl Definition + */ +#define SYS_AXI_SUP_RESET_CTL_W0_CFG_SWITCH_CORE_RESET BIT(1) +#define SYS_AXI_SUP_RESET_CTL_W0_CFG_SWITCH_SUP_RESET BIT(2) +#define SYS_AXI_SUP_RESET_CTL_W0_CFG_AXI_SUP_RESET BIT(0) + +#define SYS_AXI_SUP_RESET_CTL_W0_CFG_SWITCH_CORE_RESET_MASK 0x00000002 +#define SYS_AXI_SUP_RESET_CTL_W0_CFG_SWITCH_SUP_RESET_MASK 0x00000004 +#define SYS_AXI_SUP_RESET_CTL_W0_CFG_AXI_SUP_RESET_MASK 0x00000001 + +/* ############################################################################ + * # SysGpioResetCtl Definition + */ +#define SYS_GPIO_RESET_CTL_W0_CFG_GPIO_RESET BIT(0) + +#define SYS_GPIO_RESET_CTL_W0_CFG_GPIO_RESET_MASK 0x00000001 + +/* ############################################################################ + * # SysI2CResetCtl Definition + */ +#define SYS_I2_C_RESET_CTL_W0_CFG_I2_C0_RESET BIT(0) +#define SYS_I2_C_RESET_CTL_W0_CFG_I2_C1_RESET BIT(1) + +#define SYS_I2_C_RESET_CTL_W0_CFG_I2_C0_RESET_MASK 0x00000001 +#define SYS_I2_C_RESET_CTL_W0_CFG_I2_C1_RESET_MASK 0x00000002 + +/* ############################################################################ + * # SysMdioSocResetCtl Definition + */ +#define SYS_MDIO_SOC_RESET_CTL_W0_CFG_MDIO_SOC_RESET BIT(0) + +#define SYS_MDIO_SOC_RESET_CTL_W0_CFG_MDIO_SOC_RESET_MASK 0x00000001 + +/* ############################################################################ + * # SysTimerResetCtl Definition + */ +#define SYS_TIMER_RESET_CTL_W0_CFG_TIMER_RESET BIT(0) + +#define SYS_TIMER_RESET_CTL_W0_CFG_TIMER_RESET_MASK 0x00000001 + +/* ############################################################################ + * # SysUartResetCtl Definition + */ +#define SYS_UART_RESET_CTL_W0_CFG_UART1_RESET BIT(1) +#define SYS_UART_RESET_CTL_W0_CFG_UART2_RESET BIT(2) +#define SYS_UART_RESET_CTL_W0_CFG_UART0_RESET BIT(0) + +#define SYS_UART_RESET_CTL_W0_CFG_UART1_RESET_MASK 0x00000002 +#define SYS_UART_RESET_CTL_W0_CFG_UART2_RESET_MASK 0x00000004 +#define SYS_UART_RESET_CTL_W0_CFG_UART0_RESET_MASK 0x00000001 + +/* ############################################################################ + * # SysTraceResetCtl Definition + */ +#define SYS_TRACE_RESET_CTL_W0_CFG_TRACE_RESET BIT(0) + +#define SYS_TRACE_RESET_CTL_W0_CFG_TRACE_RESET_MASK 0x00000001 + +/* ############################################################################ + * # SysDbg0ResetEnCtl Definition + */ +#define SYS_DBG0_RESET_EN_CTL_W0_DBG0_RST_EN_CPU_L2 BIT(4) +#define SYS_DBG0_RESET_EN_CTL_W0_DBG0_RST_EN_CPU1_CORE BIT(3) +#define SYS_DBG0_RESET_EN_CTL_W0_DBG0_RST_EN_CST BIT(7) +#define SYS_DBG0_RESET_EN_CTL_W0_DBG0_RST_EN_CPU0_COLD BIT(0) +#define SYS_DBG0_RESET_EN_CTL_W0_DBG0_RST_EN_WDT0 BIT(9) +#define SYS_DBG0_RESET_EN_CTL_W0_DBG0_RST_EN_WDT1 BIT(10) +#define SYS_DBG0_RESET_EN_CTL_W0_DBG0_RST_EN_CPU1_COLD BIT(1) +#define SYS_DBG0_RESET_EN_CTL_W0_DBG0_RST_EN_CPU0_CORE BIT(2) +#define SYS_DBG0_RESET_EN_CTL_W0_DBG0_RST_EN_CPU_MEM BIT(8) +#define SYS_DBG0_RESET_EN_CTL_W0_DBG0_RST_EN_NIC BIT(11) +#define SYS_DBG0_RESET_EN_CTL_W0_DBG0_RST_EN_JTAG_POT BIT(6) +#define SYS_DBG0_RESET_EN_CTL_W0_DBG0_RST_EN_CPU_APB BIT(5) + +#define SYS_DBG0_RESET_EN_CTL_W0_DBG0_RST_EN_CPU_L2_MASK 0x00000010 +#define SYS_DBG0_RESET_EN_CTL_W0_DBG0_RST_EN_CPU1_CORE_MASK 0x00000008 +#define SYS_DBG0_RESET_EN_CTL_W0_DBG0_RST_EN_CST_MASK 0x00000080 +#define SYS_DBG0_RESET_EN_CTL_W0_DBG0_RST_EN_CPU0_COLD_MASK 0x00000001 +#define SYS_DBG0_RESET_EN_CTL_W0_DBG0_RST_EN_WDT0_MASK 0x00000200 +#define SYS_DBG0_RESET_EN_CTL_W0_DBG0_RST_EN_WDT1_MASK 0x00000400 +#define SYS_DBG0_RESET_EN_CTL_W0_DBG0_RST_EN_CPU1_COLD_MASK 0x00000002 +#define SYS_DBG0_RESET_EN_CTL_W0_DBG0_RST_EN_CPU0_CORE_MASK 0x00000004 +#define SYS_DBG0_RESET_EN_CTL_W0_DBG0_RST_EN_CPU_MEM_MASK 0x00000100 +#define SYS_DBG0_RESET_EN_CTL_W0_DBG0_RST_EN_NIC_MASK 0x00000800 +#define SYS_DBG0_RESET_EN_CTL_W0_DBG0_RST_EN_JTAG_POT_MASK 0x00000040 +#define SYS_DBG0_RESET_EN_CTL_W0_DBG0_RST_EN_CPU_APB_MASK 0x00000020 + +/* ############################################################################ + * # SysDbg1ResetEnCtl Definition + */ +#define SYS_DBG1_RESET_EN_CTL_W0_DBG1_RST_EN_CPU1_CORE BIT(3) +#define SYS_DBG1_RESET_EN_CTL_W0_DBG1_RST_EN_CPU_APB BIT(5) +#define SYS_DBG1_RESET_EN_CTL_W0_DBG1_RST_EN_JTAG_POT BIT(6) +#define SYS_DBG1_RESET_EN_CTL_W0_DBG1_RST_EN_CPU0_COLD BIT(0) +#define SYS_DBG1_RESET_EN_CTL_W0_DBG1_RST_EN_CPU_MEM BIT(8) +#define SYS_DBG1_RESET_EN_CTL_W0_DBG1_RST_EN_CPU1_COLD BIT(1) +#define SYS_DBG1_RESET_EN_CTL_W0_DBG1_RST_EN_CPU0_CORE BIT(2) +#define SYS_DBG1_RESET_EN_CTL_W0_DBG1_RST_EN_CST BIT(7) +#define SYS_DBG1_RESET_EN_CTL_W0_DBG1_RST_EN_WDT0 BIT(9) +#define SYS_DBG1_RESET_EN_CTL_W0_DBG1_RST_EN_CPU_L2 BIT(4) +#define SYS_DBG1_RESET_EN_CTL_W0_DBG1_RST_EN_WDT1 BIT(10) +#define SYS_DBG1_RESET_EN_CTL_W0_DBG1_RST_EN_NIC BIT(11) + +#define SYS_DBG1_RESET_EN_CTL_W0_DBG1_RST_EN_CPU1_CORE_MASK 0x00000008 +#define SYS_DBG1_RESET_EN_CTL_W0_DBG1_RST_EN_CPU_APB_MASK 0x00000020 +#define SYS_DBG1_RESET_EN_CTL_W0_DBG1_RST_EN_JTAG_POT_MASK 0x00000040 +#define SYS_DBG1_RESET_EN_CTL_W0_DBG1_RST_EN_CPU0_COLD_MASK 0x00000001 +#define SYS_DBG1_RESET_EN_CTL_W0_DBG1_RST_EN_CPU_MEM_MASK 0x00000100 +#define SYS_DBG1_RESET_EN_CTL_W0_DBG1_RST_EN_CPU1_COLD_MASK 0x00000002 +#define SYS_DBG1_RESET_EN_CTL_W0_DBG1_RST_EN_CPU0_CORE_MASK 0x00000004 +#define SYS_DBG1_RESET_EN_CTL_W0_DBG1_RST_EN_CST_MASK 0x00000080 +#define SYS_DBG1_RESET_EN_CTL_W0_DBG1_RST_EN_WDT0_MASK 0x00000200 +#define SYS_DBG1_RESET_EN_CTL_W0_DBG1_RST_EN_CPU_L2_MASK 0x00000010 +#define SYS_DBG1_RESET_EN_CTL_W0_DBG1_RST_EN_WDT1_MASK 0x00000400 +#define SYS_DBG1_RESET_EN_CTL_W0_DBG1_RST_EN_NIC_MASK 0x00000800 + +/* ############################################################################ + * # SysWarm0ResetEnCtl Definition + */ +#define SYS_WARM0_RESET_EN_CTL_W0_WARM0_RST_EN_CPU1_COLD BIT(1) +#define SYS_WARM0_RESET_EN_CTL_W0_WARM0_RST_EN_WDT0 BIT(9) +#define SYS_WARM0_RESET_EN_CTL_W0_WARM0_RST_EN_CPU0_COLD BIT(0) +#define SYS_WARM0_RESET_EN_CTL_W0_WARM0_RST_EN_CPU_L2 BIT(4) +#define SYS_WARM0_RESET_EN_CTL_W0_WARM0_RST_EN_JTAG_POT BIT(6) +#define SYS_WARM0_RESET_EN_CTL_W0_WARM0_RST_EN_CST BIT(7) +#define SYS_WARM0_RESET_EN_CTL_W0_WARM0_RST_EN_CPU_APB BIT(5) +#define SYS_WARM0_RESET_EN_CTL_W0_WARM0_RST_EN_CPU0_CORE BIT(2) +#define SYS_WARM0_RESET_EN_CTL_W0_WARM0_RST_EN_CPU_MEM BIT(8) +#define SYS_WARM0_RESET_EN_CTL_W0_WARM0_RST_EN_WDT1 BIT(10) +#define SYS_WARM0_RESET_EN_CTL_W0_WARM0_RST_EN_NIC BIT(11) +#define SYS_WARM0_RESET_EN_CTL_W0_WARM0_RST_EN_CPU1_CORE BIT(3) + +#define SYS_WARM0_RESET_EN_CTL_W0_WARM0_RST_EN_CPU1_COLD_MASK 0x00000002 +#define SYS_WARM0_RESET_EN_CTL_W0_WARM0_RST_EN_WDT0_MASK 0x00000200 +#define SYS_WARM0_RESET_EN_CTL_W0_WARM0_RST_EN_CPU0_COLD_MASK 0x00000001 +#define SYS_WARM0_RESET_EN_CTL_W0_WARM0_RST_EN_CPU_L2_MASK 0x00000010 +#define SYS_WARM0_RESET_EN_CTL_W0_WARM0_RST_EN_JTAG_POT_MASK 0x00000040 +#define SYS_WARM0_RESET_EN_CTL_W0_WARM0_RST_EN_CST_MASK 0x00000080 +#define SYS_WARM0_RESET_EN_CTL_W0_WARM0_RST_EN_CPU_APB_MASK 0x00000020 +#define SYS_WARM0_RESET_EN_CTL_W0_WARM0_RST_EN_CPU0_CORE_MASK 0x00000004 +#define SYS_WARM0_RESET_EN_CTL_W0_WARM0_RST_EN_CPU_MEM_MASK 0x00000100 +#define SYS_WARM0_RESET_EN_CTL_W0_WARM0_RST_EN_WDT1_MASK 0x00000400 +#define SYS_WARM0_RESET_EN_CTL_W0_WARM0_RST_EN_NIC_MASK 0x00000800 +#define SYS_WARM0_RESET_EN_CTL_W0_WARM0_RST_EN_CPU1_CORE_MASK 0x00000008 + +/* ############################################################################ + * # SysWarm1ResetEnCtl Definition + */ +#define SYS_WARM1_RESET_EN_CTL_W0_WARM1_RST_EN_CPU_MEM BIT(8) +#define SYS_WARM1_RESET_EN_CTL_W0_WARM1_RST_EN_CPU1_COLD BIT(1) +#define SYS_WARM1_RESET_EN_CTL_W0_WARM1_RST_EN_WDT1 BIT(10) +#define SYS_WARM1_RESET_EN_CTL_W0_WARM1_RST_EN_CPU_APB BIT(5) +#define SYS_WARM1_RESET_EN_CTL_W0_WARM1_RST_EN_CST BIT(7) +#define SYS_WARM1_RESET_EN_CTL_W0_WARM1_RST_EN_NIC BIT(11) +#define SYS_WARM1_RESET_EN_CTL_W0_WARM1_RST_EN_CPU0_COLD BIT(0) +#define SYS_WARM1_RESET_EN_CTL_W0_WARM1_RST_EN_CPU1_CORE BIT(3) +#define SYS_WARM1_RESET_EN_CTL_W0_WARM1_RST_EN_CPU_L2 BIT(4) +#define SYS_WARM1_RESET_EN_CTL_W0_WARM1_RST_EN_WDT0 BIT(9) +#define SYS_WARM1_RESET_EN_CTL_W0_WARM1_RST_EN_JTAG_POT BIT(6) +#define SYS_WARM1_RESET_EN_CTL_W0_WARM1_RST_EN_CPU0_CORE BIT(2) + +#define SYS_WARM1_RESET_EN_CTL_W0_WARM1_RST_EN_CPU_MEM_MASK 0x00000100 +#define SYS_WARM1_RESET_EN_CTL_W0_WARM1_RST_EN_CPU1_COLD_MASK 0x00000002 +#define SYS_WARM1_RESET_EN_CTL_W0_WARM1_RST_EN_WDT1_MASK 0x00000400 +#define SYS_WARM1_RESET_EN_CTL_W0_WARM1_RST_EN_CPU_APB_MASK 0x00000020 +#define SYS_WARM1_RESET_EN_CTL_W0_WARM1_RST_EN_CST_MASK 0x00000080 +#define SYS_WARM1_RESET_EN_CTL_W0_WARM1_RST_EN_NIC_MASK 0x00000800 +#define SYS_WARM1_RESET_EN_CTL_W0_WARM1_RST_EN_CPU0_COLD_MASK 0x00000001 +#define SYS_WARM1_RESET_EN_CTL_W0_WARM1_RST_EN_CPU1_CORE_MASK 0x00000008 +#define SYS_WARM1_RESET_EN_CTL_W0_WARM1_RST_EN_CPU_L2_MASK 0x00000010 +#define SYS_WARM1_RESET_EN_CTL_W0_WARM1_RST_EN_WDT0_MASK 0x00000200 +#define SYS_WARM1_RESET_EN_CTL_W0_WARM1_RST_EN_JTAG_POT_MASK 0x00000040 +#define SYS_WARM1_RESET_EN_CTL_W0_WARM1_RST_EN_CPU0_CORE_MASK 0x00000004 + +/* ############################################################################ + * # SysWdt0ResetEnCtl Definition + */ +#define SYS_WDT0_RESET_EN_CTL_W0_WDT0_RST_EN_CPU_L2 BIT(4) +#define SYS_WDT0_RESET_EN_CTL_W0_WDT0_RST_EN_CPU1_COLD BIT(1) +#define SYS_WDT0_RESET_EN_CTL_W0_WDT0_RST_EN_CPU_APB BIT(5) +#define SYS_WDT0_RESET_EN_CTL_W0_WDT0_RST_EN_WDT1 BIT(10) +#define SYS_WDT0_RESET_EN_CTL_W0_WDT0_RST_EN_CST BIT(7) +#define SYS_WDT0_RESET_EN_CTL_W0_WDT0_RST_EN_CPU0_CORE BIT(2) +#define SYS_WDT0_RESET_EN_CTL_W0_WDT0_RST_EN_WDT0 BIT(9) +#define SYS_WDT0_RESET_EN_CTL_W0_WDT0_RST_EN_CPU_MEM BIT(8) +#define SYS_WDT0_RESET_EN_CTL_W0_WDT0_RST_EN_JTAG_POT BIT(6) +#define SYS_WDT0_RESET_EN_CTL_W0_WDT0_RST_EN_CPU1_CORE BIT(3) +#define SYS_WDT0_RESET_EN_CTL_W0_WDT0_RST_EN_CPU0_COLD BIT(0) +#define SYS_WDT0_RESET_EN_CTL_W0_WDT0_RST_EN_NIC BIT(11) + +#define SYS_WDT0_RESET_EN_CTL_W0_WDT0_RST_EN_CPU_L2_MASK 0x00000010 +#define SYS_WDT0_RESET_EN_CTL_W0_WDT0_RST_EN_CPU1_COLD_MASK 0x00000002 +#define SYS_WDT0_RESET_EN_CTL_W0_WDT0_RST_EN_CPU_APB_MASK 0x00000020 +#define SYS_WDT0_RESET_EN_CTL_W0_WDT0_RST_EN_WDT1_MASK 0x00000400 +#define SYS_WDT0_RESET_EN_CTL_W0_WDT0_RST_EN_CST_MASK 0x00000080 +#define SYS_WDT0_RESET_EN_CTL_W0_WDT0_RST_EN_CPU0_CORE_MASK 0x00000004 +#define SYS_WDT0_RESET_EN_CTL_W0_WDT0_RST_EN_WDT0_MASK 0x00000200 +#define SYS_WDT0_RESET_EN_CTL_W0_WDT0_RST_EN_CPU_MEM_MASK 0x00000100 +#define SYS_WDT0_RESET_EN_CTL_W0_WDT0_RST_EN_JTAG_POT_MASK 0x00000040 +#define SYS_WDT0_RESET_EN_CTL_W0_WDT0_RST_EN_CPU1_CORE_MASK 0x00000008 +#define SYS_WDT0_RESET_EN_CTL_W0_WDT0_RST_EN_CPU0_COLD_MASK 0x00000001 +#define SYS_WDT0_RESET_EN_CTL_W0_WDT0_RST_EN_NIC_MASK 0x00000800 + +/* ############################################################################ + * # SysWdt1ResetEnCtl Definition + */ +#define SYS_WDT1_RESET_EN_CTL_W0_WDT1_RST_EN_CPU_L2 BIT(4) +#define SYS_WDT1_RESET_EN_CTL_W0_WDT1_RST_EN_WDT0 BIT(9) +#define SYS_WDT1_RESET_EN_CTL_W0_WDT1_RST_EN_WDT1 BIT(10) +#define SYS_WDT1_RESET_EN_CTL_W0_WDT1_RST_EN_CPU1_CORE BIT(3) +#define SYS_WDT1_RESET_EN_CTL_W0_WDT1_RST_EN_CPU_APB BIT(5) +#define SYS_WDT1_RESET_EN_CTL_W0_WDT1_RST_EN_CST BIT(7) +#define SYS_WDT1_RESET_EN_CTL_W0_WDT1_RST_EN_CPU0_COLD BIT(0) +#define SYS_WDT1_RESET_EN_CTL_W0_WDT1_RST_EN_CPU_MEM BIT(8) +#define SYS_WDT1_RESET_EN_CTL_W0_WDT1_RST_EN_CPU1_COLD BIT(1) +#define SYS_WDT1_RESET_EN_CTL_W0_WDT1_RST_EN_JTAG_POT BIT(6) +#define SYS_WDT1_RESET_EN_CTL_W0_WDT1_RST_EN_CPU0_CORE BIT(2) +#define SYS_WDT1_RESET_EN_CTL_W0_WDT1_RST_EN_NIC BIT(11) + +#define SYS_WDT1_RESET_EN_CTL_W0_WDT1_RST_EN_CPU_L2_MASK 0x00000010 +#define SYS_WDT1_RESET_EN_CTL_W0_WDT1_RST_EN_WDT0_MASK 0x00000200 +#define SYS_WDT1_RESET_EN_CTL_W0_WDT1_RST_EN_WDT1_MASK 0x00000400 +#define SYS_WDT1_RESET_EN_CTL_W0_WDT1_RST_EN_CPU1_CORE_MASK 0x00000008 +#define SYS_WDT1_RESET_EN_CTL_W0_WDT1_RST_EN_CPU_APB_MASK 0x00000020 +#define SYS_WDT1_RESET_EN_CTL_W0_WDT1_RST_EN_CST_MASK 0x00000080 +#define SYS_WDT1_RESET_EN_CTL_W0_WDT1_RST_EN_CPU0_COLD_MASK 0x00000001 +#define SYS_WDT1_RESET_EN_CTL_W0_WDT1_RST_EN_CPU_MEM_MASK 0x00000100 +#define SYS_WDT1_RESET_EN_CTL_W0_WDT1_RST_EN_CPU1_COLD_MASK 0x00000002 +#define SYS_WDT1_RESET_EN_CTL_W0_WDT1_RST_EN_JTAG_POT_MASK 0x00000040 +#define SYS_WDT1_RESET_EN_CTL_W0_WDT1_RST_EN_CPU0_CORE_MASK 0x00000004 +#define SYS_WDT1_RESET_EN_CTL_W0_WDT1_RST_EN_NIC_MASK 0x00000800 + +/* ############################################################################ + * # SysCtlReserved Definition + */ +#define SYS_CTL_RESERVED_W0_RESERVED BIT(0) + +#define SYS_CTL_RESERVED_W0_RESERVED_MASK 0xffffffff + +/* ############################################################################ + * # SysEnClkCfg Definition + */ +#define SYS_EN_CLK_CFG_W0_CFG_EN_CLK_MSH BIT(2) +#define SYS_EN_CLK_CFG_W0_CFG_EN_CLK_CPU_DMA BIT(5) +#define SYS_EN_CLK_CFG_W0_CFG_EN_CLK_CPU_MEM BIT(8) +#define SYS_EN_CLK_CFG_W0_CFG_EN_CLK_CPU_MAC BIT(7) +#define SYS_EN_CLK_CFG_W0_CFG_EN_CLK_CST BIT(4) +#define SYS_EN_CLK_CFG_W0_CFG_EN_CLK_TZC BIT(3) +#define SYS_EN_CLK_CFG_W0_CFG_EN_CLK_MISC BIT(12) +#define SYS_EN_CLK_CFG_W0_CFG_EN_CLK_DDR BIT(0) +#define SYS_EN_CLK_CFG_W0_CFG_EN_CLK_SSP BIT(10) +#define SYS_EN_CLK_CFG_W0_CFG_EN_CLK_GIC BIT(6) +#define SYS_EN_CLK_CFG_W0_CFG_EN_CLK_USB BIT(1) +#define SYS_EN_CLK_CFG_W0_CFG_EN_CLK_AXI_SUP BIT(9) +#define SYS_EN_CLK_CFG_W0_CFG_EN_CLK_QSPI BIT(11) + +#define SYS_EN_CLK_CFG_W0_CFG_EN_CLK_MSH_MASK 0x00000004 +#define SYS_EN_CLK_CFG_W0_CFG_EN_CLK_CPU_DMA_MASK 0x00000020 +#define SYS_EN_CLK_CFG_W0_CFG_EN_CLK_CPU_MEM_MASK 0x00000100 +#define SYS_EN_CLK_CFG_W0_CFG_EN_CLK_CPU_MAC_MASK 0x00000080 +#define SYS_EN_CLK_CFG_W0_CFG_EN_CLK_CST_MASK 0x00000010 +#define SYS_EN_CLK_CFG_W0_CFG_EN_CLK_TZC_MASK 0x00000008 +#define SYS_EN_CLK_CFG_W0_CFG_EN_CLK_MISC_MASK 0x00001000 +#define SYS_EN_CLK_CFG_W0_CFG_EN_CLK_DDR_MASK 0x00000001 +#define SYS_EN_CLK_CFG_W0_CFG_EN_CLK_SSP_MASK 0x00000400 +#define SYS_EN_CLK_CFG_W0_CFG_EN_CLK_GIC_MASK 0x00000040 +#define SYS_EN_CLK_CFG_W0_CFG_EN_CLK_USB_MASK 0x00000002 +#define SYS_EN_CLK_CFG_W0_CFG_EN_CLK_AXI_SUP_MASK 0x00000200 +#define SYS_EN_CLK_CFG_W0_CFG_EN_CLK_QSPI_MASK 0x00000800 + +/* ############################################################################ + * # SysPllSocCfg0 Definition + */ +#define SYS_PLL_SOC_CFG0_W0_PLL_SOC_POST_DIV BIT(12) +#define SYS_PLL_SOC_CFG0_W0_PLL_SOC_MULT_INT BIT(20) +#define SYS_PLL_SOC_CFG0_W0_PLL_SOC_INT_FBK BIT(2) +#define SYS_PLL_SOC_CFG0_W0_PLL_SOC_DCO_BYPASS BIT(1) +#define SYS_PLL_SOC_CFG0_W0_PLL_SOC_PRE_DIV BIT(4) +#define SYS_PLL_SOC_CFG0_W0_PLL_SOC_RESET BIT(0) +#define SYS_PLL_SOC_CFG0_W0_PLL_SOC_PLL_PWD BIT(3) + +#define SYS_PLL_SOC_CFG0_W0_PLL_SOC_POST_DIV_MASK 0x0003f000 +#define SYS_PLL_SOC_CFG0_W0_PLL_SOC_MULT_INT_MASK 0x0ff00000 +#define SYS_PLL_SOC_CFG0_W0_PLL_SOC_INT_FBK_MASK 0x00000004 +#define SYS_PLL_SOC_CFG0_W0_PLL_SOC_DCO_BYPASS_MASK 0x00000002 +#define SYS_PLL_SOC_CFG0_W0_PLL_SOC_PRE_DIV_MASK 0x000001f0 +#define SYS_PLL_SOC_CFG0_W0_PLL_SOC_RESET_MASK 0x00000001 +#define SYS_PLL_SOC_CFG0_W0_PLL_SOC_PLL_PWD_MASK 0x00000008 + +/* ############################################################################ + * # SysPllSocCfg1 Definition + */ +#define SYS_PLL_SOC_CFG1_W0_PLL_SOC_BYPASS BIT(24) +#define SYS_PLL_SOC_CFG1_W0_PLL_SOC_SLOCK BIT(16) +#define SYS_PLL_SOC_CFG1_W0_PLL_SOC_SGAIN BIT(20) +#define SYS_PLL_SOC_CFG1_W0_PLL_SOC_SIP BIT(0) +#define SYS_PLL_SOC_CFG1_W0_MON_PLL_SOC_LOCK BIT(28) +#define SYS_PLL_SOC_CFG1_W0_PLL_SOC_SIC BIT(8) + +#define SYS_PLL_SOC_CFG1_W0_PLL_SOC_BYPASS_MASK 0x01000000 +#define SYS_PLL_SOC_CFG1_W0_PLL_SOC_SLOCK_MASK 0x00010000 +#define SYS_PLL_SOC_CFG1_W0_PLL_SOC_SGAIN_MASK 0x00700000 +#define SYS_PLL_SOC_CFG1_W0_PLL_SOC_SIP_MASK 0x0000001f +#define SYS_PLL_SOC_CFG1_W0_MON_PLL_SOC_LOCK_MASK 0x10000000 +#define SYS_PLL_SOC_CFG1_W0_PLL_SOC_SIC_MASK 0x00001f00 + +/* ############################################################################ + * # SysPllDdrCfg0 Definition + */ +#define SYS_PLL_DDR_CFG0_W0_PLL_DDR_DCO_BYPASS BIT(1) +#define SYS_PLL_DDR_CFG0_W0_PLL_DDR_PRE_DIV BIT(4) +#define SYS_PLL_DDR_CFG0_W0_PLL_DDR_RESET BIT(0) +#define SYS_PLL_DDR_CFG0_W0_PLL_DDR_INT_FBK BIT(2) +#define SYS_PLL_DDR_CFG0_W0_PLL_DDR_PLL_PWD BIT(3) +#define SYS_PLL_DDR_CFG0_W0_PLL_DDR_MULT_INT BIT(20) +#define SYS_PLL_DDR_CFG0_W0_PLL_DDR_POST_DIV BIT(12) + +#define SYS_PLL_DDR_CFG0_W0_PLL_DDR_DCO_BYPASS_MASK 0x00000002 +#define SYS_PLL_DDR_CFG0_W0_PLL_DDR_PRE_DIV_MASK 0x000001f0 +#define SYS_PLL_DDR_CFG0_W0_PLL_DDR_RESET_MASK 0x00000001 +#define SYS_PLL_DDR_CFG0_W0_PLL_DDR_INT_FBK_MASK 0x00000004 +#define SYS_PLL_DDR_CFG0_W0_PLL_DDR_PLL_PWD_MASK 0x00000008 +#define SYS_PLL_DDR_CFG0_W0_PLL_DDR_MULT_INT_MASK 0x0ff00000 +#define SYS_PLL_DDR_CFG0_W0_PLL_DDR_POST_DIV_MASK 0x0003f000 + +/* ############################################################################ + * # SysPllDdrCfg1 Definition + */ +#define SYS_PLL_DDR_CFG1_W0_PLL_DDR_SLOCK BIT(16) +#define SYS_PLL_DDR_CFG1_W0_PLL_DDR_BYPASS BIT(24) +#define SYS_PLL_DDR_CFG1_W0_MON_PLL_DDR_LOCK BIT(28) +#define SYS_PLL_DDR_CFG1_W0_PLL_DDR_SIC BIT(8) +#define SYS_PLL_DDR_CFG1_W0_PLL_DDR_SIP BIT(0) +#define SYS_PLL_DDR_CFG1_W0_PLL_DDR_SGAIN BIT(20) + +#define SYS_PLL_DDR_CFG1_W0_PLL_DDR_SLOCK_MASK 0x00010000 +#define SYS_PLL_DDR_CFG1_W0_PLL_DDR_BYPASS_MASK 0x01000000 +#define SYS_PLL_DDR_CFG1_W0_MON_PLL_DDR_LOCK_MASK 0x10000000 +#define SYS_PLL_DDR_CFG1_W0_PLL_DDR_SIC_MASK 0x00001f00 +#define SYS_PLL_DDR_CFG1_W0_PLL_DDR_SIP_MASK 0x0000001f +#define SYS_PLL_DDR_CFG1_W0_PLL_DDR_SGAIN_MASK 0x00700000 + +/* ############################################################################ + * # SysClkSelCfg Definition + */ +#define SYS_CLK_SEL_CFG_W0_RELEASE_DIV_CLK BIT(1) +#define SYS_CLK_SEL_CFG_W0_SUP_CLOCK_SEL BIT(0) + +#define SYS_CLK_SEL_CFG_W0_RELEASE_DIV_CLK_MASK 0x00000002 +#define SYS_CLK_SEL_CFG_W0_SUP_CLOCK_SEL_MASK 0x00000001 + +/* ############################################################################ + * # SysClkDivCfg Definition + */ +#define SYS_CLK_DIV_CFG_W0_CFG_DIV_AHB_CNT BIT(8) +#define SYS_CLK_DIV_CFG_W0_CFG_DIV_TRACE_CNT BIT(16) +#define SYS_CLK_DIV_CFG_W0_CFG_DIV_CST_CNT BIT(0) +#define SYS_CLK_DIV_CFG_W0_CFG_DIV_MSH_CNT BIT(24) + +#define SYS_CLK_DIV_CFG_W0_CFG_DIV_AHB_CNT_MASK 0x0000ff00 +#define SYS_CLK_DIV_CFG_W0_CFG_DIV_TRACE_CNT_MASK 0x00ff0000 +#define SYS_CLK_DIV_CFG_W0_CFG_DIV_CST_CNT_MASK 0x000000ff +#define SYS_CLK_DIV_CFG_W0_CFG_DIV_MSH_CNT_MASK 0xff000000 + +/* ############################################################################ + * # SysClkPeriCfg Definition + */ +#define SYS_CLK_PERI_CFG_W0_CFG_DIV_USB_PHY_CNT BIT(16) +#define SYS_CLK_PERI_CFG_W0_CFG_DIV_SSP_CNT BIT(8) +#define SYS_CLK_PERI_CFG_W0_CFG_DIV_MSH_REF_CNT BIT(0) +#define SYS_CLK_PERI_CFG_W0_CFG_DIV_UART_CNT BIT(24) +#define SYS_CLK_PERI_CFG_W1_CFG_DIV_UART_CHG_EN BIT(15) +#define SYS_CLK_PERI_CFG_W1_CFG_DIV_MSH_TM_CNT BIT(0) +#define SYS_CLK_PERI_CFG_W1_CFG_DIV_MDIO_SOC_CNT BIT(16) + +#define SYS_CLK_PERI_CFG_W0_CFG_DIV_USB_PHY_CNT_MASK 0x00ff0000 +#define SYS_CLK_PERI_CFG_W0_CFG_DIV_SSP_CNT_MASK 0x0000ff00 +#define SYS_CLK_PERI_CFG_W0_CFG_DIV_MSH_REF_CNT_MASK 0x000000ff +#define SYS_CLK_PERI_CFG_W0_CFG_DIV_UART_CNT_MASK 0xff000000 +#define SYS_CLK_PERI_CFG_W1_CFG_DIV_UART_CHG_EN_MASK 0x00008000 +#define SYS_CLK_PERI_CFG_W1_CFG_DIV_MSH_TM_CNT_MASK 0x000007ff +#define SYS_CLK_PERI_CFG_W1_CFG_DIV_MDIO_SOC_CNT_MASK 0x07ff0000 + +/* ############################################################################ + * # SysDbgCreditCtl Definition + */ +#define SYS_DBG_CREDIT_CTL_W0_DBG_CREDIT_CNT BIT(8) +#define SYS_DBG_CREDIT_CTL_W0_CFG_DBG_CREDIT_CNT BIT(0) +#define SYS_DBG_CREDIT_CTL_W0_DBG_CREDIT_OK BIT(12) +#define SYS_DBG_CREDIT_CTL_W0_CFG_DBG_CREDIT_THRD BIT(4) + +#define SYS_DBG_CREDIT_CTL_W0_DBG_CREDIT_CNT_MASK 0x00000700 +#define SYS_DBG_CREDIT_CTL_W0_CFG_DBG_CREDIT_CNT_MASK 0x00000007 +#define SYS_DBG_CREDIT_CTL_W0_DBG_CREDIT_OK_MASK 0x00001000 +#define SYS_DBG_CREDIT_CTL_W0_CFG_DBG_CREDIT_THRD_MASK 0x00000070 + +/* ############################################################################ + * # SysI2CMultiCtl Definition + */ +#define SYS_I2_C_MULTI_CTL_W0_CFG_I2_C_SLAVE_EN BIT(0) + +#define SYS_I2_C_MULTI_CTL_W0_CFG_I2_C_SLAVE_EN_MASK 0x00000001 + +/* ############################################################################ + * # BootStrapPin Definition + */ +#define BOOT_STRAP_PIN_W0_BOOT_STRAP_LOG BIT(0) +#define BOOT_STRAP_PIN_W0_CPU_SPEED_LOG BIT(4) + +#define BOOT_STRAP_PIN_W0_BOOT_STRAP_LOG_MASK 0x00000007 +#define BOOT_STRAP_PIN_W0_CPU_SPEED_LOG_MASK 0x00000010 + +/* ############################################################################ + * # SysCntValue Definition + */ +#define SYS_CNT_VALUE_W0_SYS_CNT_VALUE_READ_31_0 BIT(0) +#define SYS_CNT_VALUE_W1_SYS_CNT_VALUE_READ_63_32 BIT(0) + +#define SYS_CNT_VALUE_W0_SYS_CNT_VALUE_READ_31_0_MASK 0x00000001 +#define SYS_CNT_VALUE_W1_SYS_CNT_VALUE_READ_63_32_MASK 0x00000001 + +/* ############################################################################ + * # SysCntLog Definition + */ +#define SYS_CNT_LOG_W0_SYS_CNT_HALT_READ BIT(1) +#define SYS_CNT_LOG_W0_SYS_CNT_OVER_READ BIT(2) +#define SYS_CNT_LOG_W0_SYS_CNT_DIV_READ BIT(16) +#define SYS_CNT_LOG_W0_SYS_CNT_EN_READ BIT(0) + +#define SYS_CNT_LOG_W0_SYS_CNT_HALT_READ_MASK 0x00000002 +#define SYS_CNT_LOG_W0_SYS_CNT_OVER_READ_MASK 0x00000004 +#define SYS_CNT_LOG_W0_SYS_CNT_DIV_READ_MASK 0x03ff0000 +#define SYS_CNT_LOG_W0_SYS_CNT_EN_READ_MASK 0x00000001 + +/* ############################################################################ + * # SysCoreGicAddrBase Definition + */ +#define SYS_CORE_GIC_ADDR_BASE_W0_CFG_GIC_REG_BASE BIT(0) + +#define SYS_CORE_GIC_ADDR_BASE_W0_CFG_GIC_REG_BASE_MASK 0x00ffffff + +/* ############################################################################ + * # SysCorePmCfg Definition + */ +#define SYS_CORE_PM_CFG_W0_LOG_L2_Q_ACCEPTN BIT(1) +#define SYS_CORE_PM_CFG_W0_LOG_DBG_NO_PWR_DWN BIT(4) +#define SYS_CORE_PM_CFG_W0_LOG_L2_Q_DENY BIT(2) +#define SYS_CORE_PM_CFG_W0_CFG_L2_Q_REQN BIT(8) +#define SYS_CORE_PM_CFG_W0_LOG_L2_Q_ACTIVE BIT(0) + +#define SYS_CORE_PM_CFG_W0_LOG_L2_Q_ACCEPTN_MASK 0x00000002 +#define SYS_CORE_PM_CFG_W0_LOG_DBG_NO_PWR_DWN_MASK 0x00000030 +#define SYS_CORE_PM_CFG_W0_LOG_L2_Q_DENY_MASK 0x00000004 +#define SYS_CORE_PM_CFG_W0_CFG_L2_Q_REQN_MASK 0x00000100 +#define SYS_CORE_PM_CFG_W0_LOG_L2_Q_ACTIVE_MASK 0x00000001 + +/* ############################################################################ + * # SysCoreStatus Definition + */ +#define SYS_CORE_STATUS_W0_CORE_STANDBY_WFI_L2 BIT(7) +#define SYS_CORE_STATUS_W0_JTAG_NSW_LOG BIT(8) +#define SYS_CORE_STATUS_W0_CFG_CORE1_EVENT_CLR BIT(17) +#define SYS_CORE_STATUS_W0_CORE_SMP_EN BIT(4) +#define SYS_CORE_STATUS_W0_JTAG_TOP_LOG BIT(9) +#define SYS_CORE_STATUS_W0_CORE_STANDBY_WFE BIT(2) +#define SYS_CORE_STATUS_W0_CORE_L2_FLUSH_DONE BIT(6) +#define SYS_CORE_STATUS_W0_CORE_STANDBY_WFI BIT(0) +#define SYS_CORE_STATUS_W0_CFG_CORE0_EVENT_CLR BIT(16) +#define SYS_CORE_STATUS_W0_CFG_CORE0_EVENT_RAW BIT(18) +#define SYS_CORE_STATUS_W0_CFG_CORE1_EVENT_RAW BIT(19) + +#define SYS_CORE_STATUS_W0_CORE_STANDBY_WFI_L2_MASK 0x00000080 +#define SYS_CORE_STATUS_W0_JTAG_NSW_LOG_MASK 0x00000100 +#define SYS_CORE_STATUS_W0_CFG_CORE1_EVENT_CLR_MASK 0x00020000 +#define SYS_CORE_STATUS_W0_CORE_SMP_EN_MASK 0x00000030 +#define SYS_CORE_STATUS_W0_JTAG_TOP_LOG_MASK 0x00000200 +#define SYS_CORE_STATUS_W0_CORE_STANDBY_WFE_MASK 0x0000000c +#define SYS_CORE_STATUS_W0_CORE_L2_FLUSH_DONE_MASK 0x00000040 +#define SYS_CORE_STATUS_W0_CORE_STANDBY_WFI_MASK 0x00000003 +#define SYS_CORE_STATUS_W0_CFG_CORE0_EVENT_CLR_MASK 0x00010000 +#define SYS_CORE_STATUS_W0_CFG_CORE0_EVENT_RAW_MASK 0x00040000 +#define SYS_CORE_STATUS_W0_CFG_CORE1_EVENT_RAW_MASK 0x00080000 + +/* ############################################################################ + * # SysCorePmuEvent0 Definition + */ +#define SYS_CORE_PMU_EVENT0_W0_CORE0_PMU_EVENT BIT(0) + +#define SYS_CORE_PMU_EVENT0_W0_CORE0_PMU_EVENT_MASK 0x3fffffff + +/* ############################################################################ + * # SysCorePmuEvent1 Definition + */ +#define SYS_CORE_PMU_EVENT1_W0_CORE1_PMU_EVENT BIT(0) + +#define SYS_CORE_PMU_EVENT1_W0_CORE1_PMU_EVENT_MASK 0x3fffffff + +/* ############################################################################ + * # SysRstVecBar0 Definition + */ +#define SYS_RST_VEC_BAR0_W0_CFG_RV_BAR_ADDR0_31_0 BIT(0) +#define SYS_RST_VEC_BAR0_W1_CFG_RV_BAR_ADDR0_39_32 BIT(0) + +#define SYS_RST_VEC_BAR0_W0_CFG_RV_BAR_ADDR0_31_0_MASK 0x00000001 +#define SYS_RST_VEC_BAR0_W1_CFG_RV_BAR_ADDR0_39_32_MASK 0x00000001 + +/* ############################################################################ + * # SysRstVecBar1 Definition + */ +#define SYS_RST_VEC_BAR1_W0_CFG_RV_BAR_ADDR1_31_0 BIT(0) +#define SYS_RST_VEC_BAR1_W1_CFG_RV_BAR_ADDR1_39_32 BIT(0) + +#define SYS_RST_VEC_BAR1_W0_CFG_RV_BAR_ADDR1_31_0_MASK 0x00000001 +#define SYS_RST_VEC_BAR1_W1_CFG_RV_BAR_ADDR1_39_32_MASK 0x00000001 + +/* ############################################################################ + * # SysGicCfg Definition + */ +#define SYS_GIC_CFG_W0_CFG_GIC_LEGACY_IRQ_BAR BIT(4) +#define SYS_GIC_CFG_W0_CFG_GIC_WA_USER BIT(9) +#define SYS_GIC_CFG_W0_CFG_GIC_LEGACY_FIQ_BAR BIT(0) +#define SYS_GIC_CFG_W0_CFG_GIC_RA_USER BIT(8) + +#define SYS_GIC_CFG_W0_CFG_GIC_LEGACY_IRQ_BAR_MASK 0x00000030 +#define SYS_GIC_CFG_W0_CFG_GIC_WA_USER_MASK 0x00000200 +#define SYS_GIC_CFG_W0_CFG_GIC_LEGACY_FIQ_BAR_MASK 0x00000003 +#define SYS_GIC_CFG_W0_CFG_GIC_RA_USER_MASK 0x00000100 + +/* ############################################################################ + * # SysGicStatus Definition + */ +#define SYS_GIC_STATUS_W0_GIC_FIQ_OUT_LOG BIT(0) +#define SYS_GIC_STATUS_W0_GIC_IRQ_OUT_LOG BIT(2) + +#define SYS_GIC_STATUS_W0_GIC_FIQ_OUT_LOG_MASK 0x00000003 +#define SYS_GIC_STATUS_W0_GIC_IRQ_OUT_LOG_MASK 0x0000000c + +/* ############################################################################ + * # SysMemCtl Definition + */ +#define SYS_MEM_CTL_W0_CFG_RAM_MUX_EN BIT(0) +#define SYS_MEM_CTL_W0_CFG_SYS_REMAP_EN BIT(2) +#define SYS_MEM_CTL_W0_CFG_SYS_DBG_EN BIT(4) +#define SYS_MEM_CTL_W0_CFG_RAM_REMAP BIT(1) + +#define SYS_MEM_CTL_W0_CFG_RAM_MUX_EN_MASK 0x00000001 +#define SYS_MEM_CTL_W0_CFG_SYS_REMAP_EN_MASK 0x00000004 +#define SYS_MEM_CTL_W0_CFG_SYS_DBG_EN_MASK 0x00000010 +#define SYS_MEM_CTL_W0_CFG_RAM_REMAP_MASK 0x00000002 + +/* ############################################################################ + * # SysDmaMapCfg Definition + */ +#define SYS_DMA_MAP_CFG_W0_CFG_CPU_DMA_WR_MAP_LOW BIT(0) +#define SYS_DMA_MAP_CFG_W0_CFG_CPU_DMA_WR_MAP_HIGH BIT(16) +#define SYS_DMA_MAP_CFG_W0_CFG_CPU_DMA_RD_MAP_HIGH BIT(24) +#define SYS_DMA_MAP_CFG_W0_CFG_CPU_DMA_RD_MAP_LOW BIT(8) + +#define SYS_DMA_MAP_CFG_W0_CFG_CPU_DMA_WR_MAP_LOW_MASK 0x0000000f +#define SYS_DMA_MAP_CFG_W0_CFG_CPU_DMA_WR_MAP_HIGH_MASK 0x000f0000 +#define SYS_DMA_MAP_CFG_W0_CFG_CPU_DMA_RD_MAP_HIGH_MASK 0x0f000000 +#define SYS_DMA_MAP_CFG_W0_CFG_CPU_DMA_RD_MAP_LOW_MASK 0x00000f00 + +/* ############################################################################ + * # SysDmaAbortCfg Definition + */ +#define SYS_DMA_ABORT_CFG_W0_DMA_ABORT_LEVEL_EN BIT(4) +#define SYS_DMA_ABORT_CFG_W0_DMA_ABORT_STATUS BIT(0) + +#define SYS_DMA_ABORT_CFG_W0_DMA_ABORT_LEVEL_EN_MASK 0x00000010 +#define SYS_DMA_ABORT_CFG_W0_DMA_ABORT_STATUS_MASK 0x00000001 + +/* ############################################################################ + * # SysCstCfg Definition + */ +#define SYS_CST_CFG_W0_CFG_CST_PIU_TP_CTL BIT(4) +#define SYS_CST_CFG_W0_CFG_CST_PIU_TP_MAX_DATA_SIZE BIT(8) +#define SYS_CST_CFG_W0_CFG_CST_INSTANCE_ID BIT(0) +#define SYS_CST_CFG_W0_CFG_CST_DEVICE_EN BIT(5) + +#define SYS_CST_CFG_W0_CFG_CST_PIU_TP_CTL_MASK 0x00000010 +#define SYS_CST_CFG_W0_CFG_CST_PIU_TP_MAX_DATA_SIZE_MASK 0x00001f00 +#define SYS_CST_CFG_W0_CFG_CST_INSTANCE_ID_MASK 0x0000000f +#define SYS_CST_CFG_W0_CFG_CST_DEVICE_EN_MASK 0x00000020 + +/* ############################################################################ + * # SysCstTargetIdCfg Definition + */ +#define SYS_CST_TARGET_ID_CFG_W0_CFG_CST_TARGET_ID BIT(0) + +#define SYS_CST_TARGET_ID_CFG_W0_CFG_CST_TARGET_ID_MASK 0xffffffff + +/* ############################################################################ + * # SysCstMemMapIdCfg Definition + */ +#define SYS_CST_MEM_MAP_ID_CFG_W0_CFG_CST_MEM_MAP_TARGET_ID BIT(0) + +#define SYS_CST_MEM_MAP_ID_CFG_W0_CFG_CST_MEM_MAP_TARGET_ID_MASK 0xffffffff + +/* ############################################################################ + * # SysQspiBootCfg0 Definition + */ +#define SYS_QSPI_BOOT_CFG0_W0_QSPI_BOOT_EN_CPHA BIT(4) +#define SYS_QSPI_BOOT_CFG0_W0_QSPI_BOOT_HOLD BIT(6) +#define SYS_QSPI_BOOT_CFG0_W0_QSPI_BOOT_WP BIT(7) +#define SYS_QSPI_BOOT_CFG0_W0_QSPI_BOOT_CHIP_SEL BIT(8) +#define SYS_QSPI_BOOT_CFG0_W0_QSPI_BOOT_RX_CODE BIT(12) +#define SYS_QSPI_BOOT_CFG0_W0_QSPI_BOOT_EN BIT(0) +#define SYS_QSPI_BOOT_CFG0_W0_QSPI_XIP_EN BIT(1) +#define SYS_QSPI_BOOT_CFG0_W0_QSPI_BOOT_EN_CPOL BIT(5) +#define SYS_QSPI_BOOT_CFG0_W0_QSPI_BOOT_CLK_DIV BIT(16) + +#define SYS_QSPI_BOOT_CFG0_W0_QSPI_BOOT_EN_CPHA_MASK 0x00000010 +#define SYS_QSPI_BOOT_CFG0_W0_QSPI_BOOT_HOLD_MASK 0x00000040 +#define SYS_QSPI_BOOT_CFG0_W0_QSPI_BOOT_WP_MASK 0x00000080 +#define SYS_QSPI_BOOT_CFG0_W0_QSPI_BOOT_CHIP_SEL_MASK 0x00000700 +#define SYS_QSPI_BOOT_CFG0_W0_QSPI_BOOT_RX_CODE_MASK 0x00007000 +#define SYS_QSPI_BOOT_CFG0_W0_QSPI_BOOT_EN_MASK 0x00000001 +#define SYS_QSPI_BOOT_CFG0_W0_QSPI_XIP_EN_MASK 0x00000002 +#define SYS_QSPI_BOOT_CFG0_W0_QSPI_BOOT_EN_CPOL_MASK 0x00000020 +#define SYS_QSPI_BOOT_CFG0_W0_QSPI_BOOT_CLK_DIV_MASK 0x00ff0000 + +/* ############################################################################ + * # SysQspiBootCfg1 Definition + */ +#define SYS_QSPI_BOOT_CFG1_W0_QSPI_BOOT_CMD_CODE BIT(24) +#define SYS_QSPI_BOOT_CFG1_W0_QSPI_BOOT_CMD_MODE BIT(12) +#define SYS_QSPI_BOOT_CFG1_W0_QSPI_BOOT_CMD_CYCLE BIT(16) +#define SYS_QSPI_BOOT_CFG1_W0_QSPI_BOOT_ADDR_MODE BIT(8) +#define SYS_QSPI_BOOT_CFG1_W0_QSPI_BOOT_ADDR_CYCLE BIT(0) + +#define SYS_QSPI_BOOT_CFG1_W0_QSPI_BOOT_CMD_CODE_MASK 0xff000000 +#define SYS_QSPI_BOOT_CFG1_W0_QSPI_BOOT_CMD_MODE_MASK 0x00007000 +#define SYS_QSPI_BOOT_CFG1_W0_QSPI_BOOT_CMD_CYCLE_MASK 0x001f0000 +#define SYS_QSPI_BOOT_CFG1_W0_QSPI_BOOT_ADDR_MODE_MASK 0x00000700 +#define SYS_QSPI_BOOT_CFG1_W0_QSPI_BOOT_ADDR_CYCLE_MASK 0x0000003f + +/* ############################################################################ + * # SysQspiBootCfg2 Definition + */ +#define SYS_QSPI_BOOT_CFG2_W0_QSPI_BOOT_DUMMY_MODE BIT(8) +#define SYS_QSPI_BOOT_CFG2_W0_QSPI_BOOT_DUMMY_CYCLE BIT(0) + +#define SYS_QSPI_BOOT_CFG2_W0_QSPI_BOOT_DUMMY_MODE_MASK 0x00000700 +#define SYS_QSPI_BOOT_CFG2_W0_QSPI_BOOT_DUMMY_CYCLE_MASK 0x0000003f + +/* ############################################################################ + * # SysQspiBootCfg3 Definition + */ +#define SYS_QSPI_BOOT_CFG3_W0_QSPI_BOOT_DUMMY_CODE BIT(0) + +#define SYS_QSPI_BOOT_CFG3_W0_QSPI_BOOT_DUMMY_CODE_MASK 0xffffffff + +/* ############################################################################ + * # SysDdrCfg Definition + */ +#define SYS_DDR_CFG_W0_DDR_RESET_CK_E_LATCH_BAR BIT(0) +#define SYS_DDR_CFG_W0_DDR_FORCE_STA_CK_STP1 BIT(3) +#define SYS_DDR_CFG_W0_DDR_PHY_IDDQ BIT(4) +#define SYS_DDR_CFG_W0_DDR_VDD_ON BIT(2) +#define SYS_DDR_CFG_W0_DDR_PWR_OFF_PHY BIT(1) + +#define SYS_DDR_CFG_W0_DDR_RESET_CK_E_LATCH_BAR_MASK 0x00000001 +#define SYS_DDR_CFG_W0_DDR_FORCE_STA_CK_STP1_MASK 0x00000008 +#define SYS_DDR_CFG_W0_DDR_PHY_IDDQ_MASK 0x00000010 +#define SYS_DDR_CFG_W0_DDR_VDD_ON_MASK 0x00000004 +#define SYS_DDR_CFG_W0_DDR_PWR_OFF_PHY_MASK 0x00000002 + +/* ############################################################################ + * # SysSpiSelCfg Definition + */ +#define SYS_SPI_SEL_CFG_W0_SSP_SLAVE_SEL BIT(0) +#define SYS_SPI_SEL_CFG_W0_SSP_CS_CFG_CTL BIT(4) + +#define SYS_SPI_SEL_CFG_W0_SSP_SLAVE_SEL_MASK 0x00000003 +#define SYS_SPI_SEL_CFG_W0_SSP_CS_CFG_CTL_MASK 0x000000f0 + +/* ############################################################################ + * # SysMdioSocCfg Definition + */ +#define SYS_MDIO_SOC_CFG_W0_CFG_EN_CLK_MDIO_SOC BIT(4) +#define SYS_MDIO_SOC_CFG_W0_CFG_INV_MDIO_SOC BIT(0) +#define SYS_MDIO_SOC_CFG_W0_CFG_EN_CLK_MDIO_SOC_REG BIT(5) + +#define SYS_MDIO_SOC_CFG_W0_CFG_EN_CLK_MDIO_SOC_MASK 0x00000010 +#define SYS_MDIO_SOC_CFG_W0_CFG_INV_MDIO_SOC_MASK 0x00000001 +#define SYS_MDIO_SOC_CFG_W0_CFG_EN_CLK_MDIO_SOC_REG_MASK 0x00000020 + +/* ############################################################################ + * # SysWdt0Cnt Definition + */ +#define SYS_WDT0_CNT_W0_CFG_WDT0_DIV_CNT BIT(0) + +#define SYS_WDT0_CNT_W0_CFG_WDT0_DIV_CNT_MASK 0xffffffff + +/* ############################################################################ + * # SysWdt0Rev Definition + */ +#define SYS_WDT0_REV_W0_CFG_WDT0_ECO_REV BIT(0) + +#define SYS_WDT0_REV_W0_CFG_WDT0_ECO_REV_MASK 0x0000000f + +/* ############################################################################ + * # SysWdt1Cnt Definition + */ +#define SYS_WDT1_CNT_W0_CFG_WDT1_DIV_CNT BIT(0) + +#define SYS_WDT1_CNT_W0_CFG_WDT1_DIV_CNT_MASK 0xffffffff + +/* ############################################################################ + * # SysWdt1Rev Definition + */ +#define SYS_WDT1_REV_W0_CFG_WDT1_ECO_REV BIT(0) + +#define SYS_WDT1_REV_W0_CFG_WDT1_ECO_REV_MASK 0x0000000f + +/* ############################################################################ + * # SysMshCfg Definition + */ +#define SYS_MSH_CFG_W0_CFG_MSH_CARD_DETECT_IN_EN BIT(4) +#define SYS_MSH_CFG_W0_CFG_MSH_CARD_DETECT BIT(5) +#define SYS_MSH_CFG_W0_MSH_INTF_C_CLK_TX_DELAY BIT(16) +#define SYS_MSH_CFG_W0_MSH_INTF_C_CLK_TX_PHASE_SEL BIT(24) +#define SYS_MSH_CFG_W0_CFG_MSH_CARD_WRITE_PROT BIT(7) +#define SYS_MSH_CFG_W0_CFG_RESET_BAR_MSH_SEL BIT(12) +#define SYS_MSH_CFG_W0_MSH_INTF_TX_DLL_MASTER_BYPASS BIT(2) +#define SYS_MSH_CFG_W0_MSH_INTF_RX_DLL_MASTER_BYPASS BIT(1) +#define SYS_MSH_CFG_W0_MSH_INTF_C_CLK_TX_SEL BIT(25) +#define SYS_MSH_CFG_W0_MSH_INTF_AT_DLL_MASTER_BYPASS BIT(0) +#define SYS_MSH_CFG_W0_CFG_MSH_CARD_WRITE_PROT_IN_EN BIT(6) + +#define SYS_MSH_CFG_W0_CFG_MSH_CARD_DETECT_IN_EN_MASK 0x00000010 +#define SYS_MSH_CFG_W0_CFG_MSH_CARD_DETECT_MASK 0x00000020 +#define SYS_MSH_CFG_W0_MSH_INTF_C_CLK_TX_DELAY_MASK 0x00ff0000 +#define SYS_MSH_CFG_W0_MSH_INTF_C_CLK_TX_PHASE_SEL_MASK 0x01000000 +#define SYS_MSH_CFG_W0_CFG_MSH_CARD_WRITE_PROT_MASK 0x00000080 +#define SYS_MSH_CFG_W0_CFG_RESET_BAR_MSH_SEL_MASK 0x00001000 +#define SYS_MSH_CFG_W0_MSH_INTF_TX_DLL_MASTER_BYPASS_MASK 0x00000004 +#define SYS_MSH_CFG_W0_MSH_INTF_RX_DLL_MASTER_BYPASS_MASK 0x00000002 +#define SYS_MSH_CFG_W0_MSH_INTF_C_CLK_TX_SEL_MASK 0x02000000 +#define SYS_MSH_CFG_W0_MSH_INTF_AT_DLL_MASTER_BYPASS_MASK 0x00000001 +#define SYS_MSH_CFG_W0_CFG_MSH_CARD_WRITE_PROT_IN_EN_MASK 0x00000040 + +/* ############################################################################ + * # SysMshStatus Definition + */ +#define SYS_MSH_STATUS_W0_MON_MSH_C_RESET_DONE BIT(2) +#define SYS_MSH_STATUS_W0_MON_MSH_SD_CLK_LOCK BIT(6) +#define SYS_MSH_STATUS_W0_MON_MSH_SD_DATXFER_WIDTH BIT(0) +#define SYS_MSH_STATUS_W0_MON_MSH_AT_DLL_LOCK BIT(4) +#define SYS_MSH_STATUS_W0_MON_MSH_RX_DLL_LOCK BIT(5) + +#define SYS_MSH_STATUS_W0_MON_MSH_C_RESET_DONE_MASK 0x00000004 +#define SYS_MSH_STATUS_W0_MON_MSH_SD_CLK_LOCK_MASK 0x00000040 +#define SYS_MSH_STATUS_W0_MON_MSH_SD_DATXFER_WIDTH_MASK 0x00000003 +#define SYS_MSH_STATUS_W0_MON_MSH_AT_DLL_LOCK_MASK 0x00000010 +#define SYS_MSH_STATUS_W0_MON_MSH_RX_DLL_LOCK_MASK 0x00000020 + +/* ############################################################################ + * # SysUsbCfg0 Definition + */ +#define SYS_USB_CFG0_W0_USB_PHY_TX_PRE_EMP_AMP_TUNE BIT(2) +#define SYS_USB_CFG0_W0_USB_PHY_FSEL BIT(8) +#define SYS_USB_CFG0_W0_USB_PHY_COMMON_ONN BIT(0) +#define SYS_USB_CFG0_W0_USB_PHY_PLL_B_TUNE BIT(1) +#define SYS_USB_CFG0_W0_USB_PHY_COMP_DIS_TUNE BIT(4) +#define SYS_USB_CFG0_W0_USB_PHY_TX_RISE_TUNE BIT(20) +#define SYS_USB_CFG0_W0_USB_PHY_TX_HSXV_TUNE BIT(28) +#define SYS_USB_CFG0_W0_USB_PHY_VA_TEST_EN_B BIT(22) +#define SYS_USB_CFG0_W0_USB_PHY_TX_VREF_TUNE BIT(24) +#define SYS_USB_CFG0_W0_USB_PHY_TX_RES_TUNE BIT(30) +#define SYS_USB_CFG0_W0_USB_PHY_TX_FS_LS_TUNE BIT(16) +#define SYS_USB_CFG0_W0_USB_PHY_VREG_BYPASS BIT(11) +#define SYS_USB_CFG0_W0_USB_PHY_TX_PRE_EMP_PULSE_TUNE BIT(7) +#define SYS_USB_CFG0_W0_USB_PHY_SQ_RX_TUNE BIT(12) + +#define SYS_USB_CFG0_W0_USB_PHY_TX_PRE_EMP_AMP_TUNE_MASK 0x0000000c +#define SYS_USB_CFG0_W0_USB_PHY_FSEL_MASK 0x00000700 +#define SYS_USB_CFG0_W0_USB_PHY_COMMON_ONN_MASK 0x00000001 +#define SYS_USB_CFG0_W0_USB_PHY_PLL_B_TUNE_MASK 0x00000002 +#define SYS_USB_CFG0_W0_USB_PHY_COMP_DIS_TUNE_MASK 0x00000070 +#define SYS_USB_CFG0_W0_USB_PHY_TX_RISE_TUNE_MASK 0x00300000 +#define SYS_USB_CFG0_W0_USB_PHY_TX_HSXV_TUNE_MASK 0x30000000 +#define SYS_USB_CFG0_W0_USB_PHY_VA_TEST_EN_B_MASK 0x00c00000 +#define SYS_USB_CFG0_W0_USB_PHY_TX_VREF_TUNE_MASK 0x0f000000 +#define SYS_USB_CFG0_W0_USB_PHY_TX_RES_TUNE_MASK 0xc0000000 +#define SYS_USB_CFG0_W0_USB_PHY_TX_FS_LS_TUNE_MASK 0x000f0000 +#define SYS_USB_CFG0_W0_USB_PHY_VREG_BYPASS_MASK 0x00000800 +#define SYS_USB_CFG0_W0_USB_PHY_TX_PRE_EMP_PULSE_TUNE_MASK 0x00000080 +#define SYS_USB_CFG0_W0_USB_PHY_SQ_RX_TUNE_MASK 0x00007000 + +/* ############################################################################ + * # SysUsbCfg1 Definition + */ +#define SYS_USB_CFG1_W0_USB_INTF_AUTOPPD_ON_OVERCUR_EN BIT(1) +#define SYS_USB_CFG1_W0_USB_INTF_FL_ADJ_VAL_HOST BIT(4) +#define SYS_USB_CFG1_W0_USB_INTF_WORD_IF BIT(16) +#define SYS_USB_CFG1_W0_USB_INTF_OHCI_CNT_SEL BIT(13) +#define SYS_USB_CFG1_W0_USB_INTF_OHCI_SUSP_LGCY BIT(14) +#define SYS_USB_CFG1_W0_USB_INTF_OHCI_CLKCKTRST_BAR BIT(12) +#define SYS_USB_CFG1_W0_USB_INTF_APP_START_CLK BIT(0) +#define SYS_USB_CFG1_W0_USB_PHY_LOOPBACK_EN BIT(17) +#define SYS_USB_CFG1_W0_USB_INTF_SIM_MODE BIT(15) +#define SYS_USB_CFG1_W0_USB_INTF_HUBSETUP_MIN BIT(2) + +#define SYS_USB_CFG1_W0_USB_INTF_AUTOPPD_ON_OVERCUR_EN_MASK 0x00000002 +#define SYS_USB_CFG1_W0_USB_INTF_FL_ADJ_VAL_HOST_MASK 0x000003f0 +#define SYS_USB_CFG1_W0_USB_INTF_WORD_IF_MASK 0x00010000 +#define SYS_USB_CFG1_W0_USB_INTF_OHCI_CNT_SEL_MASK 0x00002000 +#define SYS_USB_CFG1_W0_USB_INTF_OHCI_SUSP_LGCY_MASK 0x00004000 +#define SYS_USB_CFG1_W0_USB_INTF_OHCI_CLKCKTRST_BAR_MASK 0x00001000 +#define SYS_USB_CFG1_W0_USB_INTF_APP_START_CLK_MASK 0x00000001 +#define SYS_USB_CFG1_W0_USB_PHY_LOOPBACK_EN_MASK 0x00020000 +#define SYS_USB_CFG1_W0_USB_INTF_SIM_MODE_MASK 0x00008000 +#define SYS_USB_CFG1_W0_USB_INTF_HUBSETUP_MIN_MASK 0x00000004 + +/* ############################################################################ + * # SysUsbCfg2 Definition + */ +#define SYS_USB_CFG2_W0_USB_PHY_PLL_P_TUNE BIT(8) +#define SYS_USB_CFG2_W0_USB_PHY_PLL_I_TUNE BIT(4) +#define SYS_USB_CFG2_W0_USB_PHY_TX_BIT_STUFF_EN0 BIT(16) +#define SYS_USB_CFG2_W0_USB_PHY_TX_BIT_STUFF_EN_H0 BIT(17) +#define SYS_USB_CFG2_W0_USB_PHY_OTG_TUNE BIT(0) +#define SYS_USB_CFG2_W0_USB_PHY_VDAT_REF_TUNE BIT(12) + +#define SYS_USB_CFG2_W0_USB_PHY_PLL_P_TUNE_MASK 0x00000f00 +#define SYS_USB_CFG2_W0_USB_PHY_PLL_I_TUNE_MASK 0x00000030 +#define SYS_USB_CFG2_W0_USB_PHY_TX_BIT_STUFF_EN0_MASK 0x00010000 +#define SYS_USB_CFG2_W0_USB_PHY_TX_BIT_STUFF_EN_H0_MASK 0x00020000 +#define SYS_USB_CFG2_W0_USB_PHY_OTG_TUNE_MASK 0x00000007 +#define SYS_USB_CFG2_W0_USB_PHY_VDAT_REF_TUNE_MASK 0x00003000 + +/* ############################################################################ + * # SysUsbStatus Definition + */ +#define SYS_USB_STATUS_W0_USB_INTF_EHCI_LPSMC_STATE BIT(0) +#define SYS_USB_STATUS_W0_USB_INTF_EHCI_XFER_CNT BIT(4) +#define SYS_USB_STATUS_W0_USB_INTF_OHCI_ISOC_OUT_MEM_READ BIT(18) +#define SYS_USB_STATUS_W0_USB_INTF_OHCI_CCS BIT(16) +#define SYS_USB_STATUS_W0_USB_INTF_EHCI_XFER_PRDC BIT(15) +#define SYS_USB_STATUS_W0_USB_INTF_OHCI_GLOBALSUSPEND BIT(17) +#define SYS_USB_STATUS_W0_USB_INTF_OHCI_RMTWKP BIT(19) + +#define SYS_USB_STATUS_W0_USB_INTF_EHCI_LPSMC_STATE_MASK 0x0000000f +#define SYS_USB_STATUS_W0_USB_INTF_EHCI_XFER_CNT_MASK 0x00007ff0 +#define SYS_USB_STATUS_W0_USB_INTF_OHCI_ISOC_OUT_MEM_READ_MASK 0x00040000 +#define SYS_USB_STATUS_W0_USB_INTF_OHCI_CCS_MASK 0x00010000 +#define SYS_USB_STATUS_W0_USB_INTF_EHCI_XFER_PRDC_MASK 0x00008000 +#define SYS_USB_STATUS_W0_USB_INTF_OHCI_GLOBALSUSPEND_MASK 0x00020000 +#define SYS_USB_STATUS_W0_USB_INTF_OHCI_RMTWKP_MASK 0x00080000 + +/* ############################################################################ + * # SysPcieBaseCfg Definition + */ +#define SYS_PCIE_BASE_CFG_W0_PCIE_BASE_CFG BIT(0) + +#define SYS_PCIE_BASE_CFG_W0_PCIE_BASE_CFG_MASK 0x000fffff + +/* ############################################################################ + * # SysRegCfg Definition + */ +#define SYS_REG_CFG_W0_EN_CLK_GLOBAL_SYS BIT(0) +#define SYS_REG_CFG_W0_CFG_SOC_ACC_DIR_EN BIT(1) + +#define SYS_REG_CFG_W0_EN_CLK_GLOBAL_SYS_MASK 0x00000001 +#define SYS_REG_CFG_W0_CFG_SOC_ACC_DIR_EN_MASK 0x00000002 + +/* ############################################################################ + * # SysInitCtl Definition + */ +#define SYS_INIT_CTL_W0_CPU_MEM_INIT_DONE BIT(1) +#define SYS_INIT_CTL_W0_CFG_INIT_EN BIT(0) +#define SYS_INIT_CTL_W1_CFG_INIT_START_PTR BIT(0) +#define SYS_INIT_CTL_W1_CFG_INIT_END_PTR BIT(16) + +#define SYS_INIT_CTL_W0_CPU_MEM_INIT_DONE_MASK 0x00000002 +#define SYS_INIT_CTL_W0_CFG_INIT_EN_MASK 0x00000001 +#define SYS_INIT_CTL_W1_CFG_INIT_START_PTR_MASK 0x00007fff +#define SYS_INIT_CTL_W1_CFG_INIT_END_PTR_MASK 0x7fff0000 + +/* ############################################################################ + * # SysPllSupCfg0 Definition + */ +#define SYS_PLL_SUP_CFG0_W0_PLL_SUP_PLL_PWD BIT(3) +#define SYS_PLL_SUP_CFG0_W0_PLL_SUP_MULT_INT BIT(20) +#define SYS_PLL_SUP_CFG0_W0_PLL_SUP_RESET BIT(0) +#define SYS_PLL_SUP_CFG0_W0_PLL_SUP_INT_FBK BIT(2) +#define SYS_PLL_SUP_CFG0_W0_PLL_SUP_PRE_DIV BIT(4) +#define SYS_PLL_SUP_CFG0_W0_PLL_SUP_DCO_BYPASS BIT(1) +#define SYS_PLL_SUP_CFG0_W0_PLL_SUP_POST_DIV BIT(12) + +#define SYS_PLL_SUP_CFG0_W0_PLL_SUP_PLL_PWD_MASK 0x00000008 +#define SYS_PLL_SUP_CFG0_W0_PLL_SUP_MULT_INT_MASK 0x0ff00000 +#define SYS_PLL_SUP_CFG0_W0_PLL_SUP_RESET_MASK 0x00000001 +#define SYS_PLL_SUP_CFG0_W0_PLL_SUP_INT_FBK_MASK 0x00000004 +#define SYS_PLL_SUP_CFG0_W0_PLL_SUP_PRE_DIV_MASK 0x000001f0 +#define SYS_PLL_SUP_CFG0_W0_PLL_SUP_DCO_BYPASS_MASK 0x00000002 +#define SYS_PLL_SUP_CFG0_W0_PLL_SUP_POST_DIV_MASK 0x0003f000 + +/* ############################################################################ + * # SysPllSupCfg1 Definition + */ +#define SYS_PLL_SUP_CFG1_W0_MON_PLL_SUP_LOCK BIT(28) +#define SYS_PLL_SUP_CFG1_W0_PLL_SUP_SGAIN BIT(20) +#define SYS_PLL_SUP_CFG1_W0_PLL_SUP_SIP BIT(0) +#define SYS_PLL_SUP_CFG1_W0_PLL_SUP_SIC BIT(8) +#define SYS_PLL_SUP_CFG1_W0_PLL_SUP_SLOCK BIT(16) +#define SYS_PLL_SUP_CFG1_W0_PLL_SUP_BYPASS BIT(24) + +#define SYS_PLL_SUP_CFG1_W0_MON_PLL_SUP_LOCK_MASK 0x10000000 +#define SYS_PLL_SUP_CFG1_W0_PLL_SUP_SGAIN_MASK 0x00700000 +#define SYS_PLL_SUP_CFG1_W0_PLL_SUP_SIP_MASK 0x0000001f +#define SYS_PLL_SUP_CFG1_W0_PLL_SUP_SIC_MASK 0x00001f00 +#define SYS_PLL_SUP_CFG1_W0_PLL_SUP_SLOCK_MASK 0x00010000 +#define SYS_PLL_SUP_CFG1_W0_PLL_SUP_BYPASS_MASK 0x01000000 + +/* ############################################################################ + * # SysApbProcTimer Definition + */ +#define SYS_APB_PROC_TIMER_W0_CFG_APB_PROC_TIMER BIT(0) + +#define SYS_APB_PROC_TIMER_W0_CFG_APB_PROC_TIMER_MASK 0x0000ffff + +/* ############################################################################ + * # SysUsbTest Definition + */ +#define SYS_USB_TEST_W0_USB_PHY_TEST_DATA_IN BIT(8) +#define SYS_USB_TEST_W0_USB_PHY_TEST_DATA_OUT_SEL BIT(16) +#define SYS_USB_TEST_W0_USB_PHY_TEST_ADDR BIT(0) +#define SYS_USB_TEST_W1_USB_PHY_TEST_CLK BIT(16) +#define SYS_USB_TEST_W1_USB_PHY_TEST_DATA_OUT BIT(0) + +#define SYS_USB_TEST_W0_USB_PHY_TEST_DATA_IN_MASK 0x0000ff00 +#define SYS_USB_TEST_W0_USB_PHY_TEST_DATA_OUT_SEL_MASK 0x00010000 +#define SYS_USB_TEST_W0_USB_PHY_TEST_ADDR_MASK 0x0000000f +#define SYS_USB_TEST_W1_USB_PHY_TEST_CLK_MASK 0x00010000 +#define SYS_USB_TEST_W1_USB_PHY_TEST_DATA_OUT_MASK 0x0000000f + +/* ############################################################################ + * # SysGpioMultiCtl Definition + */ +#define SYS_GPIO_MULTI_CTL_W0_CFG_GPIO14_SEL BIT(28) +#define SYS_GPIO_MULTI_CTL_W0_CFG_GPIO5_SEL BIT(10) +#define SYS_GPIO_MULTI_CTL_W0_CFG_GPIO15_SEL BIT(30) +#define SYS_GPIO_MULTI_CTL_W0_CFG_GPIO7_SEL BIT(14) +#define SYS_GPIO_MULTI_CTL_W0_CFG_GPIO9_SEL BIT(18) +#define SYS_GPIO_MULTI_CTL_W0_CFG_GPIO13_SEL BIT(26) +#define SYS_GPIO_MULTI_CTL_W0_CFG_GPIO0_SEL BIT(0) +#define SYS_GPIO_MULTI_CTL_W0_CFG_GPIO1_SEL BIT(2) +#define SYS_GPIO_MULTI_CTL_W0_CFG_GPIO6_SEL BIT(12) +#define SYS_GPIO_MULTI_CTL_W0_CFG_GPIO11_SEL BIT(22) +#define SYS_GPIO_MULTI_CTL_W0_CFG_GPIO3_SEL BIT(6) +#define SYS_GPIO_MULTI_CTL_W0_CFG_GPIO10_SEL BIT(20) +#define SYS_GPIO_MULTI_CTL_W0_CFG_GPIO2_SEL BIT(4) +#define SYS_GPIO_MULTI_CTL_W0_CFG_GPIO8_SEL BIT(16) +#define SYS_GPIO_MULTI_CTL_W0_CFG_GPIO12_SEL BIT(24) +#define SYS_GPIO_MULTI_CTL_W0_CFG_GPIO4_SEL BIT(8) + +#define SYS_GPIO_MULTI_CTL_W0_CFG_GPIO14_SEL_MASK 0x30000000 +#define SYS_GPIO_MULTI_CTL_W0_CFG_GPIO5_SEL_MASK 0x00000c00 +#define SYS_GPIO_MULTI_CTL_W0_CFG_GPIO15_SEL_MASK 0xc0000000 +#define SYS_GPIO_MULTI_CTL_W0_CFG_GPIO7_SEL_MASK 0x0000c000 +#define SYS_GPIO_MULTI_CTL_W0_CFG_GPIO9_SEL_MASK 0x000c0000 +#define SYS_GPIO_MULTI_CTL_W0_CFG_GPIO13_SEL_MASK 0x0c000000 +#define SYS_GPIO_MULTI_CTL_W0_CFG_GPIO0_SEL_MASK 0x00000003 +#define SYS_GPIO_MULTI_CTL_W0_CFG_GPIO1_SEL_MASK 0x0000000c +#define SYS_GPIO_MULTI_CTL_W0_CFG_GPIO6_SEL_MASK 0x00003000 +#define SYS_GPIO_MULTI_CTL_W0_CFG_GPIO11_SEL_MASK 0x00c00000 +#define SYS_GPIO_MULTI_CTL_W0_CFG_GPIO3_SEL_MASK 0x000000c0 +#define SYS_GPIO_MULTI_CTL_W0_CFG_GPIO10_SEL_MASK 0x00300000 +#define SYS_GPIO_MULTI_CTL_W0_CFG_GPIO2_SEL_MASK 0x00000030 +#define SYS_GPIO_MULTI_CTL_W0_CFG_GPIO8_SEL_MASK 0x00030000 +#define SYS_GPIO_MULTI_CTL_W0_CFG_GPIO12_SEL_MASK 0x03000000 +#define SYS_GPIO_MULTI_CTL_W0_CFG_GPIO4_SEL_MASK 0x00000300 + +/* ############################################################################ + * # SysGpioHsMultiCtl Definition + */ +#define SYS_GPIO_HS_MULTI_CTL_W0_CFG_GPIO_HS13_SEL BIT(26) +#define SYS_GPIO_HS_MULTI_CTL_W0_CFG_GPIO_HS7_SEL BIT(14) +#define SYS_GPIO_HS_MULTI_CTL_W0_CFG_GPIO_HS9_SEL BIT(18) +#define SYS_GPIO_HS_MULTI_CTL_W0_CFG_GPIO_HS14_SEL BIT(28) +#define SYS_GPIO_HS_MULTI_CTL_W0_CFG_GPIO_HS11_SEL BIT(22) +#define SYS_GPIO_HS_MULTI_CTL_W0_CFG_GPIO_HS15_SEL BIT(30) +#define SYS_GPIO_HS_MULTI_CTL_W0_CFG_GPIO_HS5_SEL BIT(10) +#define SYS_GPIO_HS_MULTI_CTL_W0_CFG_GPIO_HS4_SEL BIT(8) +#define SYS_GPIO_HS_MULTI_CTL_W0_CFG_GPIO_HS10_SEL BIT(20) +#define SYS_GPIO_HS_MULTI_CTL_W0_CFG_GPIO_HS8_SEL BIT(16) +#define SYS_GPIO_HS_MULTI_CTL_W0_CFG_GPIO_HS12_SEL BIT(24) +#define SYS_GPIO_HS_MULTI_CTL_W0_CFG_GPIO_HS6_SEL BIT(12) +#define SYS_GPIO_HS_MULTI_CTL_W0_CFG_GPIO_HS3_SEL BIT(6) +#define SYS_GPIO_HS_MULTI_CTL_W0_CFG_GPIO_HS2_SEL BIT(4) +#define SYS_GPIO_HS_MULTI_CTL_W0_CFG_GPIO_HS0_SEL BIT(0) +#define SYS_GPIO_HS_MULTI_CTL_W0_CFG_GPIO_HS1_SEL BIT(2) +#define SYS_GPIO_HS_MULTI_CTL_W1_CFG_GPIO_HS17_SEL BIT(2) +#define SYS_GPIO_HS_MULTI_CTL_W1_CFG_GPIO_HS16_SEL BIT(0) + +#define SYS_GPIO_HS_MULTI_CTL_W0_CFG_GPIO_HS13_SEL_MASK 0x0c000000 +#define SYS_GPIO_HS_MULTI_CTL_W0_CFG_GPIO_HS7_SEL_MASK 0x0000c000 +#define SYS_GPIO_HS_MULTI_CTL_W0_CFG_GPIO_HS9_SEL_MASK 0x000c0000 +#define SYS_GPIO_HS_MULTI_CTL_W0_CFG_GPIO_HS14_SEL_MASK 0x30000000 +#define SYS_GPIO_HS_MULTI_CTL_W0_CFG_GPIO_HS11_SEL_MASK 0x00c00000 +#define SYS_GPIO_HS_MULTI_CTL_W0_CFG_GPIO_HS15_SEL_MASK 0xc0000000 +#define SYS_GPIO_HS_MULTI_CTL_W0_CFG_GPIO_HS5_SEL_MASK 0x00000c00 +#define SYS_GPIO_HS_MULTI_CTL_W0_CFG_GPIO_HS4_SEL_MASK 0x00000300 +#define SYS_GPIO_HS_MULTI_CTL_W0_CFG_GPIO_HS10_SEL_MASK 0x00300000 +#define SYS_GPIO_HS_MULTI_CTL_W0_CFG_GPIO_HS8_SEL_MASK 0x00030000 +#define SYS_GPIO_HS_MULTI_CTL_W0_CFG_GPIO_HS12_SEL_MASK 0x03000000 +#define SYS_GPIO_HS_MULTI_CTL_W0_CFG_GPIO_HS6_SEL_MASK 0x00003000 +#define SYS_GPIO_HS_MULTI_CTL_W0_CFG_GPIO_HS3_SEL_MASK 0x000000c0 +#define SYS_GPIO_HS_MULTI_CTL_W0_CFG_GPIO_HS2_SEL_MASK 0x00000030 +#define SYS_GPIO_HS_MULTI_CTL_W0_CFG_GPIO_HS0_SEL_MASK 0x00000003 +#define SYS_GPIO_HS_MULTI_CTL_W0_CFG_GPIO_HS1_SEL_MASK 0x0000000c +#define SYS_GPIO_HS_MULTI_CTL_W1_CFG_GPIO_HS17_SEL_MASK 0x0000000c +#define SYS_GPIO_HS_MULTI_CTL_W1_CFG_GPIO_HS16_SEL_MASK 0x00000003 + +/* ############################################################################ + * # SysPcieStatus Definition + */ +#define SYS_PCIE_STATUS_W0_PCIE_LTSSM_LOG_31_0 BIT(0) +#define SYS_PCIE_STATUS_W1_PCIE_LTSSM_LOG_63_32 BIT(0) + +#define SYS_PCIE_STATUS_W0_PCIE_LTSSM_LOG_31_0_MASK 0x00000001 +#define SYS_PCIE_STATUS_W1_PCIE_LTSSM_LOG_63_32_MASK 0x00000001 + +/* ############################################################################ + * # SysMsixStatus Definition + */ +#define SYS_MSIX_STATUS_W0_MSIX_STATUS0 BIT(0) +#define SYS_MSIX_STATUS_W1_MSIX_STATUS1 BIT(0) +#define SYS_MSIX_STATUS_W2_MSIX_STATUS2 BIT(0) +#define SYS_MSIX_STATUS_W3_MSIX_STATUS3 BIT(0) +#define SYS_MSIX_STATUS_W4_MSIX_STATUS4 BIT(0) +#define SYS_MSIX_STATUS_W5_MSIX_STATUS5 BIT(0) +#define SYS_MSIX_STATUS_W6_MSIX_STATUS6 BIT(0) +#define SYS_MSIX_STATUS_W7_MSIX_STATUS7 BIT(0) + +#define SYS_MSIX_STATUS_W0_MSIX_STATUS0_MASK 0xffffffff +#define SYS_MSIX_STATUS_W1_MSIX_STATUS1_MASK 0xffffffff +#define SYS_MSIX_STATUS_W2_MSIX_STATUS2_MASK 0xffffffff +#define SYS_MSIX_STATUS_W3_MSIX_STATUS3_MASK 0xffffffff +#define SYS_MSIX_STATUS_W4_MSIX_STATUS4_MASK 0xffffffff +#define SYS_MSIX_STATUS_W5_MSIX_STATUS5_MASK 0xffffffff +#define SYS_MSIX_STATUS_W6_MSIX_STATUS6_MASK 0xffffffff +#define SYS_MSIX_STATUS_W7_MSIX_STATUS7_MASK 0xffffffff + +/* ############################################################################ + * # SysMsixMask Definition + */ +#define SYS_MSIX_MASK_W0_MSIX_MASK0 BIT(0) +#define SYS_MSIX_MASK_W1_MSIX_MASK1 BIT(0) +#define SYS_MSIX_MASK_W2_MSIX_MASK2 BIT(0) +#define SYS_MSIX_MASK_W3_MSIX_MASK3 BIT(0) +#define SYS_MSIX_MASK_W4_MSIX_MASK4 BIT(0) +#define SYS_MSIX_MASK_W5_MSIX_MASK5 BIT(0) +#define SYS_MSIX_MASK_W6_MSIX_MASK6 BIT(0) +#define SYS_MSIX_MASK_W7_MSIX_MASK7 BIT(0) + +#define SYS_MSIX_MASK_W0_MSIX_MASK0_MASK 0xffffffff +#define SYS_MSIX_MASK_W1_MSIX_MASK1_MASK 0xffffffff +#define SYS_MSIX_MASK_W2_MSIX_MASK2_MASK 0xffffffff +#define SYS_MSIX_MASK_W3_MSIX_MASK3_MASK 0xffffffff +#define SYS_MSIX_MASK_W4_MSIX_MASK4_MASK 0xffffffff +#define SYS_MSIX_MASK_W5_MSIX_MASK5_MASK 0xffffffff +#define SYS_MSIX_MASK_W6_MSIX_MASK6_MASK 0xffffffff +#define SYS_MSIX_MASK_W7_MSIX_MASK7_MASK 0xffffffff + +/* ############################################################################ + * # SysMsixAddr Definition + */ +#define SYS_MSIX_ADDR_W0_MSIX_ADDR BIT(0) + +#define SYS_MSIX_ADDR_W0_MSIX_ADDR_MASK 0xffffffff + +/* ############################################################################ + * # SysMsixVecCtl Definition + */ +#define SYS_MSIX_VEC_CTL_W0_MSIX_VEC_EN BIT(0) + +#define SYS_MSIX_VEC_CTL_W0_MSIX_VEC_EN_MASK 0x000000ff + +/* ############################################################################ + * # SysMsixAddrEn Definition + */ +#define SYS_MSIX_ADDR_EN_W0_MSIX_ADDR_EN BIT(0) + +#define SYS_MSIX_ADDR_EN_W0_MSIX_ADDR_EN_MASK 0x00000001 + +/* ############################################################################ + * # SysMsixIntrLog Definition + */ +#define SYS_MSIX_INTR_LOG_W0_MSIX_INTR_LOG BIT(0) + +#define SYS_MSIX_INTR_LOG_W0_MSIX_INTR_LOG_MASK 0x000000ff + +/* ############################################################################ + * # SysDebugCtl Definition + */ +#define SYS_DEBUG_CTL_W0_DEBUG_INIT_PCIE BIT(4) +#define SYS_DEBUG_CTL_W0_DEBUG_INIT_SYS_APB BIT(8) +#define SYS_DEBUG_CTL_W0_DEBUG_EN_SYS_APB BIT(9) +#define SYS_DEBUG_CTL_W0_DEBUG_EN_SEC_APB BIT(13) +#define SYS_DEBUG_CTL_W0_DEBUG_INIT_MSH BIT(7) +#define SYS_DEBUG_CTL_W0_DEBUG_INIT_DDR1 BIT(3) +#define SYS_DEBUG_CTL_W0_DEBUG_INIT_CPU BIT(0) +#define SYS_DEBUG_CTL_W0_DEBUG_INIT_DDR0 BIT(2) +#define SYS_DEBUG_CTL_W0_DEBUG_INIT_SEC_APB BIT(12) +#define SYS_DEBUG_CTL_W0_DEBUG_INIT_MEM BIT(1) +#define SYS_DEBUG_CTL_W0_DEBUG_ONCE_SEC_APB BIT(14) +#define SYS_DEBUG_CTL_W0_DEBUG_ONCE_SYS_APB BIT(10) +#define SYS_DEBUG_CTL_W0_DEBUG_INIT_SUP BIT(6) +#define SYS_DEBUG_CTL_W0_DEBUG_INIT_QSPI BIT(5) + +#define SYS_DEBUG_CTL_W0_DEBUG_INIT_PCIE_MASK 0x00000010 +#define SYS_DEBUG_CTL_W0_DEBUG_INIT_SYS_APB_MASK 0x00000100 +#define SYS_DEBUG_CTL_W0_DEBUG_EN_SYS_APB_MASK 0x00000200 +#define SYS_DEBUG_CTL_W0_DEBUG_EN_SEC_APB_MASK 0x00002000 +#define SYS_DEBUG_CTL_W0_DEBUG_INIT_MSH_MASK 0x00000080 +#define SYS_DEBUG_CTL_W0_DEBUG_INIT_DDR1_MASK 0x00000008 +#define SYS_DEBUG_CTL_W0_DEBUG_INIT_CPU_MASK 0x00000001 +#define SYS_DEBUG_CTL_W0_DEBUG_INIT_DDR0_MASK 0x00000004 +#define SYS_DEBUG_CTL_W0_DEBUG_INIT_SEC_APB_MASK 0x00001000 +#define SYS_DEBUG_CTL_W0_DEBUG_INIT_MEM_MASK 0x00000002 +#define SYS_DEBUG_CTL_W0_DEBUG_ONCE_SEC_APB_MASK 0x00004000 +#define SYS_DEBUG_CTL_W0_DEBUG_ONCE_SYS_APB_MASK 0x00000400 +#define SYS_DEBUG_CTL_W0_DEBUG_INIT_SUP_MASK 0x00000040 +#define SYS_DEBUG_CTL_W0_DEBUG_INIT_QSPI_MASK 0x00000020 + +/* ############################################################################ + * # SysMsixPending Definition + */ +#define SYS_MSIX_PENDING_W0_MSIX_PENDING0 BIT(0) +#define SYS_MSIX_PENDING_W1_MSIX_PENDING1 BIT(0) +#define SYS_MSIX_PENDING_W2_MSIX_PENDING2 BIT(0) +#define SYS_MSIX_PENDING_W3_MSIX_PENDING3 BIT(0) +#define SYS_MSIX_PENDING_W4_MSIX_PENDING4 BIT(0) +#define SYS_MSIX_PENDING_W5_MSIX_PENDING5 BIT(0) +#define SYS_MSIX_PENDING_W6_MSIX_PENDING6 BIT(0) +#define SYS_MSIX_PENDING_W7_MSIX_PENDING7 BIT(0) + +#define SYS_MSIX_PENDING_W0_MSIX_PENDING0_MASK 0xffffffff +#define SYS_MSIX_PENDING_W1_MSIX_PENDING1_MASK 0xffffffff +#define SYS_MSIX_PENDING_W2_MSIX_PENDING2_MASK 0xffffffff +#define SYS_MSIX_PENDING_W3_MSIX_PENDING3_MASK 0xffffffff +#define SYS_MSIX_PENDING_W4_MSIX_PENDING4_MASK 0xffffffff +#define SYS_MSIX_PENDING_W5_MSIX_PENDING5_MASK 0xffffffff +#define SYS_MSIX_PENDING_W6_MSIX_PENDING6_MASK 0xffffffff +#define SYS_MSIX_PENDING_W7_MSIX_PENDING7_MASK 0xffffffff + +/* ############################################################################ + * # SysPwmCtl Definition + */ +#define SYS_PWM_CTL_W0_CFG_PWM0_EN BIT(31) +#define SYS_PWM_CTL_W0_CFG_PWM0_PERIOD_CYCLE BIT(0) +#define SYS_PWM_CTL_W1_CFG_PWM0_DUTY_CYCLE BIT(0) +#define SYS_PWM_CTL_W2_CFG_PWM1_EN BIT(31) +#define SYS_PWM_CTL_W2_CFG_PWM1_PERIOD_CYCLE BIT(0) +#define SYS_PWM_CTL_W3_CFG_PWM1_DUTY_CYCLE BIT(0) +#define SYS_PWM_CTL_W4_CFG_PWM2_EN BIT(31) +#define SYS_PWM_CTL_W4_CFG_PWM2_PERIOD_CYCLE BIT(0) +#define SYS_PWM_CTL_W5_CFG_PWM2_DUTY_CYCLE BIT(0) +#define SYS_PWM_CTL_W6_CFG_PWM3_EN BIT(31) +#define SYS_PWM_CTL_W6_CFG_PWM3_PERIOD_CYCLE BIT(0) +#define SYS_PWM_CTL_W7_CFG_PWM3_DUTY_CYCLE BIT(0) + +#define SYS_PWM_CTL_W0_CFG_PWM0_EN_MASK 0x80000000 +#define SYS_PWM_CTL_W0_CFG_PWM0_PERIOD_CYCLE_MASK 0x00ffffff +#define SYS_PWM_CTL_W1_CFG_PWM0_DUTY_CYCLE_MASK 0x00ffffff +#define SYS_PWM_CTL_W2_CFG_PWM1_EN_MASK 0x80000000 +#define SYS_PWM_CTL_W2_CFG_PWM1_PERIOD_CYCLE_MASK 0x00ffffff +#define SYS_PWM_CTL_W3_CFG_PWM1_DUTY_CYCLE_MASK 0x00ffffff +#define SYS_PWM_CTL_W4_CFG_PWM2_EN_MASK 0x80000000 +#define SYS_PWM_CTL_W4_CFG_PWM2_PERIOD_CYCLE_MASK 0x00ffffff +#define SYS_PWM_CTL_W5_CFG_PWM2_DUTY_CYCLE_MASK 0x00ffffff +#define SYS_PWM_CTL_W6_CFG_PWM3_EN_MASK 0x80000000 +#define SYS_PWM_CTL_W6_CFG_PWM3_PERIOD_CYCLE_MASK 0x00ffffff +#define SYS_PWM_CTL_W7_CFG_PWM3_DUTY_CYCLE_MASK 0x00ffffff + +/* ############################################################################ + * # SysTachLog Definition + */ +#define SYS_TACH_LOG_W0_TACH0_PERIOD_CYCLE BIT(0) +#define SYS_TACH_LOG_W1_TACH0_DUTY_CYCLE BIT(0) +#define SYS_TACH_LOG_W2_TACH1_PERIOD_CYCLE BIT(0) +#define SYS_TACH_LOG_W3_TACH1_DUTY_CYCLE BIT(0) +#define SYS_TACH_LOG_W4_TACH2_PERIOD_CYCLE BIT(0) +#define SYS_TACH_LOG_W5_TACH2_DUTY_CYCLE BIT(0) +#define SYS_TACH_LOG_W6_TACH3_PERIOD_CYCLE BIT(0) +#define SYS_TACH_LOG_W7_TACH3_DUTY_CYCLE BIT(0) + +#define SYS_TACH_LOG_W0_TACH0_PERIOD_CYCLE_MASK 0x00ffffff +#define SYS_TACH_LOG_W1_TACH0_DUTY_CYCLE_MASK 0x00ffffff +#define SYS_TACH_LOG_W2_TACH1_PERIOD_CYCLE_MASK 0x00ffffff +#define SYS_TACH_LOG_W3_TACH1_DUTY_CYCLE_MASK 0x00ffffff +#define SYS_TACH_LOG_W4_TACH2_PERIOD_CYCLE_MASK 0x00ffffff +#define SYS_TACH_LOG_W5_TACH2_DUTY_CYCLE_MASK 0x00ffffff +#define SYS_TACH_LOG_W6_TACH3_PERIOD_CYCLE_MASK 0x00ffffff +#define SYS_TACH_LOG_W7_TACH3_DUTY_CYCLE_MASK 0x00ffffff + +/* ############################################################################ + * # MonAxiCpuCurInfo Definition + */ +#define MON_AXI_CPU_CUR_INFO_W0_MON_AXI_CPU_CUR_INFO_31_0 BIT(0) +#define MON_AXI_CPU_CUR_INFO_W1_MON_AXI_CPU_CUR_INFO_63_32 BIT(0) +#define MON_AXI_CPU_CUR_INFO_W2_MON_AXI_CPU_CUR_INFO_95_64 BIT(0) +#define MON_AXI_CPU_CUR_INFO_W3_MON_AXI_CPU_CUR_INFO_127_96 BIT(0) +#define MON_AXI_CPU_CUR_INFO_W4_MON_AXI_CPU_CUR_INFO_159_128 BIT(0) +#define MON_AXI_CPU_CUR_INFO_W5_MON_AXI_CPU_CUR_INFO_191_160 BIT(0) +#define MON_AXI_CPU_CUR_INFO_W6_MON_AXI_CPU_CUR_INFO_223_192 BIT(0) +#define MON_AXI_CPU_CUR_INFO_W7_MON_AXI_CPU_CUR_INFO_255_224 BIT(0) +#define MON_AXI_CPU_CUR_INFO_W8_MON_AXI_CPU_CUR_INFO_287_256 BIT(0) +#define MON_AXI_CPU_CUR_INFO_W9_MON_AXI_CPU_CUR_INFO_319_288 BIT(0) +#define MON_AXI_CPU_CUR_INFO_W10_MON_AXI_CPU_CUR_INFO_351_320 BIT(0) +#define MON_AXI_CPU_CUR_INFO_W11_MON_AXI_CPU_CUR_INFO_383_352 BIT(0) +#define MON_AXI_CPU_CUR_INFO_W12_MON_AXI_CPU_CUR_INFO_415_384 BIT(0) +#define MON_AXI_CPU_CUR_INFO_W13_MON_AXI_CPU_CUR_INFO_427_416 BIT(0) + +#define MON_AXI_CPU_CUR_INFO_W0_MON_AXI_CPU_CUR_INFO_31_0_MASK 0x00000001 +#define MON_AXI_CPU_CUR_INFO_W1_MON_AXI_CPU_CUR_INFO_63_32_MASK 0x00000001 +#define MON_AXI_CPU_CUR_INFO_W2_MON_AXI_CPU_CUR_INFO_95_64_MASK 0x00000001 +#define MON_AXI_CPU_CUR_INFO_W3_MON_AXI_CPU_CUR_INFO_127_96_MASK 0x00000001 +#define MON_AXI_CPU_CUR_INFO_W4_MON_AXI_CPU_CUR_INFO_159_128_MASK 0x00000001 +#define MON_AXI_CPU_CUR_INFO_W5_MON_AXI_CPU_CUR_INFO_191_160_MASK 0x00000001 +#define MON_AXI_CPU_CUR_INFO_W6_MON_AXI_CPU_CUR_INFO_223_192_MASK 0x00000001 +#define MON_AXI_CPU_CUR_INFO_W7_MON_AXI_CPU_CUR_INFO_255_224_MASK 0x00000001 +#define MON_AXI_CPU_CUR_INFO_W8_MON_AXI_CPU_CUR_INFO_287_256_MASK 0x00000001 +#define MON_AXI_CPU_CUR_INFO_W9_MON_AXI_CPU_CUR_INFO_319_288_MASK 0x00000001 +#define MON_AXI_CPU_CUR_INFO_W10_MON_AXI_CPU_CUR_INFO_351_320_MASK 0x00000001 +#define MON_AXI_CPU_CUR_INFO_W11_MON_AXI_CPU_CUR_INFO_383_352_MASK 0x00000001 +#define MON_AXI_CPU_CUR_INFO_W12_MON_AXI_CPU_CUR_INFO_415_384_MASK 0x00000001 +#define MON_AXI_CPU_CUR_INFO_W13_MON_AXI_CPU_CUR_INFO_427_416_MASK 0x00000001 + +/* ############################################################################ + * # MonAxiCpuLogInfo Definition + */ +#define MON_AXI_CPU_LOG_INFO_W0_MON_AXI_CPU_LOG_INFO_31_0 BIT(0) +#define MON_AXI_CPU_LOG_INFO_W1_MON_AXI_CPU_LOG_INFO_63_32 BIT(0) +#define MON_AXI_CPU_LOG_INFO_W2_MON_AXI_CPU_LOG_INFO_95_64 BIT(0) +#define MON_AXI_CPU_LOG_INFO_W3_MON_AXI_CPU_LOG_INFO_127_96 BIT(0) +#define MON_AXI_CPU_LOG_INFO_W4_MON_AXI_CPU_LOG_INFO_159_128 BIT(0) +#define MON_AXI_CPU_LOG_INFO_W5_MON_AXI_CPU_LOG_INFO_191_160 BIT(0) +#define MON_AXI_CPU_LOG_INFO_W6_MON_AXI_CPU_LOG_INFO_223_192 BIT(0) +#define MON_AXI_CPU_LOG_INFO_W7_MON_AXI_CPU_LOG_INFO_255_224 BIT(0) +#define MON_AXI_CPU_LOG_INFO_W8_MON_AXI_CPU_LOG_INFO_287_256 BIT(0) +#define MON_AXI_CPU_LOG_INFO_W9_MON_AXI_CPU_LOG_INFO_319_288 BIT(0) +#define MON_AXI_CPU_LOG_INFO_W10_MON_AXI_CPU_LOG_INFO_351_320 BIT(0) +#define MON_AXI_CPU_LOG_INFO_W11_MON_AXI_CPU_LOG_INFO_383_352 BIT(0) +#define MON_AXI_CPU_LOG_INFO_W12_MON_AXI_CPU_LOG_INFO_415_384 BIT(0) +#define MON_AXI_CPU_LOG_INFO_W13_MON_AXI_CPU_LOG_INFO_427_416 BIT(0) + +#define MON_AXI_CPU_LOG_INFO_W0_MON_AXI_CPU_LOG_INFO_31_0_MASK 0x00000001 +#define MON_AXI_CPU_LOG_INFO_W1_MON_AXI_CPU_LOG_INFO_63_32_MASK 0x00000001 +#define MON_AXI_CPU_LOG_INFO_W2_MON_AXI_CPU_LOG_INFO_95_64_MASK 0x00000001 +#define MON_AXI_CPU_LOG_INFO_W3_MON_AXI_CPU_LOG_INFO_127_96_MASK 0x00000001 +#define MON_AXI_CPU_LOG_INFO_W4_MON_AXI_CPU_LOG_INFO_159_128_MASK 0x00000001 +#define MON_AXI_CPU_LOG_INFO_W5_MON_AXI_CPU_LOG_INFO_191_160_MASK 0x00000001 +#define MON_AXI_CPU_LOG_INFO_W6_MON_AXI_CPU_LOG_INFO_223_192_MASK 0x00000001 +#define MON_AXI_CPU_LOG_INFO_W7_MON_AXI_CPU_LOG_INFO_255_224_MASK 0x00000001 +#define MON_AXI_CPU_LOG_INFO_W8_MON_AXI_CPU_LOG_INFO_287_256_MASK 0x00000001 +#define MON_AXI_CPU_LOG_INFO_W9_MON_AXI_CPU_LOG_INFO_319_288_MASK 0x00000001 +#define MON_AXI_CPU_LOG_INFO_W10_MON_AXI_CPU_LOG_INFO_351_320_MASK 0x00000001 +#define MON_AXI_CPU_LOG_INFO_W11_MON_AXI_CPU_LOG_INFO_383_352_MASK 0x00000001 +#define MON_AXI_CPU_LOG_INFO_W12_MON_AXI_CPU_LOG_INFO_415_384_MASK 0x00000001 +#define MON_AXI_CPU_LOG_INFO_W13_MON_AXI_CPU_LOG_INFO_427_416_MASK 0x00000001 + +/* ############################################################################ + * # MonAxiDdr0CurInfo Definition + */ +#define MON_AXI_DDR0_CUR_INFO_W0_MON_AXI_DDR0_CUR_INFO_31_0 BIT(0) +#define MON_AXI_DDR0_CUR_INFO_W1_MON_AXI_DDR0_CUR_INFO_63_32 BIT(0) +#define MON_AXI_DDR0_CUR_INFO_W2_MON_AXI_DDR0_CUR_INFO_95_64 BIT(0) +#define MON_AXI_DDR0_CUR_INFO_W3_MON_AXI_DDR0_CUR_INFO_127_96 BIT(0) +#define MON_AXI_DDR0_CUR_INFO_W4_MON_AXI_DDR0_CUR_INFO_159_128 BIT(0) +#define MON_AXI_DDR0_CUR_INFO_W5_MON_AXI_DDR0_CUR_INFO_191_160 BIT(0) +#define MON_AXI_DDR0_CUR_INFO_W6_MON_AXI_DDR0_CUR_INFO_223_192 BIT(0) +#define MON_AXI_DDR0_CUR_INFO_W7_MON_AXI_DDR0_CUR_INFO_255_224 BIT(0) +#define MON_AXI_DDR0_CUR_INFO_W8_MON_AXI_DDR0_CUR_INFO_287_256 BIT(0) +#define MON_AXI_DDR0_CUR_INFO_W9_MON_AXI_DDR0_CUR_INFO_319_288 BIT(0) +#define MON_AXI_DDR0_CUR_INFO_W10_MON_AXI_DDR0_CUR_INFO_351_320 BIT(0) +#define MON_AXI_DDR0_CUR_INFO_W11_MON_AXI_DDR0_CUR_INFO_383_352 BIT(0) +#define MON_AXI_DDR0_CUR_INFO_W12_MON_AXI_DDR0_CUR_INFO_415_384 BIT(0) +#define MON_AXI_DDR0_CUR_INFO_W13_MON_AXI_DDR0_CUR_INFO_427_416 BIT(0) + +#define MON_AXI_DDR0_CUR_INFO_W0_MON_AXI_DDR0_CUR_INFO_31_0_MASK 0x00000001 +#define MON_AXI_DDR0_CUR_INFO_W1_MON_AXI_DDR0_CUR_INFO_63_32_MASK 0x00000001 +#define MON_AXI_DDR0_CUR_INFO_W2_MON_AXI_DDR0_CUR_INFO_95_64_MASK 0x00000001 +#define MON_AXI_DDR0_CUR_INFO_W3_MON_AXI_DDR0_CUR_INFO_127_96_MASK 0x00000001 +#define MON_AXI_DDR0_CUR_INFO_W4_MON_AXI_DDR0_CUR_INFO_159_128_MASK 0x00000001 +#define MON_AXI_DDR0_CUR_INFO_W5_MON_AXI_DDR0_CUR_INFO_191_160_MASK 0x00000001 +#define MON_AXI_DDR0_CUR_INFO_W6_MON_AXI_DDR0_CUR_INFO_223_192_MASK 0x00000001 +#define MON_AXI_DDR0_CUR_INFO_W7_MON_AXI_DDR0_CUR_INFO_255_224_MASK 0x00000001 +#define MON_AXI_DDR0_CUR_INFO_W8_MON_AXI_DDR0_CUR_INFO_287_256_MASK 0x00000001 +#define MON_AXI_DDR0_CUR_INFO_W9_MON_AXI_DDR0_CUR_INFO_319_288_MASK 0x00000001 +#define MON_AXI_DDR0_CUR_INFO_W10_MON_AXI_DDR0_CUR_INFO_351_320_MASK 0x00000001 +#define MON_AXI_DDR0_CUR_INFO_W11_MON_AXI_DDR0_CUR_INFO_383_352_MASK 0x00000001 +#define MON_AXI_DDR0_CUR_INFO_W12_MON_AXI_DDR0_CUR_INFO_415_384_MASK 0x00000001 +#define MON_AXI_DDR0_CUR_INFO_W13_MON_AXI_DDR0_CUR_INFO_427_416_MASK 0x00000001 + +/* ############################################################################ + * # MonAxiDdr0LogInfo Definition + */ +#define MON_AXI_DDR0_LOG_INFO_W0_MON_AXI_DDR0_LOG_INFO_31_0 BIT(0) +#define MON_AXI_DDR0_LOG_INFO_W1_MON_AXI_DDR0_LOG_INFO_63_32 BIT(0) +#define MON_AXI_DDR0_LOG_INFO_W2_MON_AXI_DDR0_LOG_INFO_95_64 BIT(0) +#define MON_AXI_DDR0_LOG_INFO_W3_MON_AXI_DDR0_LOG_INFO_127_96 BIT(0) +#define MON_AXI_DDR0_LOG_INFO_W4_MON_AXI_DDR0_LOG_INFO_159_128 BIT(0) +#define MON_AXI_DDR0_LOG_INFO_W5_MON_AXI_DDR0_LOG_INFO_191_160 BIT(0) +#define MON_AXI_DDR0_LOG_INFO_W6_MON_AXI_DDR0_LOG_INFO_223_192 BIT(0) +#define MON_AXI_DDR0_LOG_INFO_W7_MON_AXI_DDR0_LOG_INFO_255_224 BIT(0) +#define MON_AXI_DDR0_LOG_INFO_W8_MON_AXI_DDR0_LOG_INFO_287_256 BIT(0) +#define MON_AXI_DDR0_LOG_INFO_W9_MON_AXI_DDR0_LOG_INFO_319_288 BIT(0) +#define MON_AXI_DDR0_LOG_INFO_W10_MON_AXI_DDR0_LOG_INFO_351_320 BIT(0) +#define MON_AXI_DDR0_LOG_INFO_W11_MON_AXI_DDR0_LOG_INFO_383_352 BIT(0) +#define MON_AXI_DDR0_LOG_INFO_W12_MON_AXI_DDR0_LOG_INFO_415_384 BIT(0) +#define MON_AXI_DDR0_LOG_INFO_W13_MON_AXI_DDR0_LOG_INFO_427_416 BIT(0) + +#define MON_AXI_DDR0_LOG_INFO_W0_MON_AXI_DDR0_LOG_INFO_31_0_MASK 0x00000001 +#define MON_AXI_DDR0_LOG_INFO_W1_MON_AXI_DDR0_LOG_INFO_63_32_MASK 0x00000001 +#define MON_AXI_DDR0_LOG_INFO_W2_MON_AXI_DDR0_LOG_INFO_95_64_MASK 0x00000001 +#define MON_AXI_DDR0_LOG_INFO_W3_MON_AXI_DDR0_LOG_INFO_127_96_MASK 0x00000001 +#define MON_AXI_DDR0_LOG_INFO_W4_MON_AXI_DDR0_LOG_INFO_159_128_MASK 0x00000001 +#define MON_AXI_DDR0_LOG_INFO_W5_MON_AXI_DDR0_LOG_INFO_191_160_MASK 0x00000001 +#define MON_AXI_DDR0_LOG_INFO_W6_MON_AXI_DDR0_LOG_INFO_223_192_MASK 0x00000001 +#define MON_AXI_DDR0_LOG_INFO_W7_MON_AXI_DDR0_LOG_INFO_255_224_MASK 0x00000001 +#define MON_AXI_DDR0_LOG_INFO_W8_MON_AXI_DDR0_LOG_INFO_287_256_MASK 0x00000001 +#define MON_AXI_DDR0_LOG_INFO_W9_MON_AXI_DDR0_LOG_INFO_319_288_MASK 0x00000001 +#define MON_AXI_DDR0_LOG_INFO_W10_MON_AXI_DDR0_LOG_INFO_351_320_MASK 0x00000001 +#define MON_AXI_DDR0_LOG_INFO_W11_MON_AXI_DDR0_LOG_INFO_383_352_MASK 0x00000001 +#define MON_AXI_DDR0_LOG_INFO_W12_MON_AXI_DDR0_LOG_INFO_415_384_MASK 0x00000001 +#define MON_AXI_DDR0_LOG_INFO_W13_MON_AXI_DDR0_LOG_INFO_427_416_MASK 0x00000001 + +/* ############################################################################ + * # MonAxiDdr1CurInfo Definition + */ +#define MON_AXI_DDR1_CUR_INFO_W0_MON_AXI_DDR1_CUR_INFO_31_0 BIT(0) +#define MON_AXI_DDR1_CUR_INFO_W1_MON_AXI_DDR1_CUR_INFO_63_32 BIT(0) +#define MON_AXI_DDR1_CUR_INFO_W2_MON_AXI_DDR1_CUR_INFO_95_64 BIT(0) +#define MON_AXI_DDR1_CUR_INFO_W3_MON_AXI_DDR1_CUR_INFO_127_96 BIT(0) +#define MON_AXI_DDR1_CUR_INFO_W4_MON_AXI_DDR1_CUR_INFO_159_128 BIT(0) +#define MON_AXI_DDR1_CUR_INFO_W5_MON_AXI_DDR1_CUR_INFO_191_160 BIT(0) +#define MON_AXI_DDR1_CUR_INFO_W6_MON_AXI_DDR1_CUR_INFO_223_192 BIT(0) +#define MON_AXI_DDR1_CUR_INFO_W7_MON_AXI_DDR1_CUR_INFO_255_224 BIT(0) +#define MON_AXI_DDR1_CUR_INFO_W8_MON_AXI_DDR1_CUR_INFO_287_256 BIT(0) +#define MON_AXI_DDR1_CUR_INFO_W9_MON_AXI_DDR1_CUR_INFO_299_288 BIT(0) + +#define MON_AXI_DDR1_CUR_INFO_W0_MON_AXI_DDR1_CUR_INFO_31_0_MASK 0x00000001 +#define MON_AXI_DDR1_CUR_INFO_W1_MON_AXI_DDR1_CUR_INFO_63_32_MASK 0x00000001 +#define MON_AXI_DDR1_CUR_INFO_W2_MON_AXI_DDR1_CUR_INFO_95_64_MASK 0x00000001 +#define MON_AXI_DDR1_CUR_INFO_W3_MON_AXI_DDR1_CUR_INFO_127_96_MASK 0x00000001 +#define MON_AXI_DDR1_CUR_INFO_W4_MON_AXI_DDR1_CUR_INFO_159_128_MASK 0x00000001 +#define MON_AXI_DDR1_CUR_INFO_W5_MON_AXI_DDR1_CUR_INFO_191_160_MASK 0x00000001 +#define MON_AXI_DDR1_CUR_INFO_W6_MON_AXI_DDR1_CUR_INFO_223_192_MASK 0x00000001 +#define MON_AXI_DDR1_CUR_INFO_W7_MON_AXI_DDR1_CUR_INFO_255_224_MASK 0x00000001 +#define MON_AXI_DDR1_CUR_INFO_W8_MON_AXI_DDR1_CUR_INFO_287_256_MASK 0x00000001 +#define MON_AXI_DDR1_CUR_INFO_W9_MON_AXI_DDR1_CUR_INFO_299_288_MASK 0x00000001 + +/* ############################################################################ + * # MonAxiDdr1LogInfo Definition + */ +#define MON_AXI_DDR1_LOG_INFO_W0_MON_AXI_DDR1_LOG_INFO_31_0 BIT(0) +#define MON_AXI_DDR1_LOG_INFO_W1_MON_AXI_DDR1_LOG_INFO_63_32 BIT(0) +#define MON_AXI_DDR1_LOG_INFO_W2_MON_AXI_DDR1_LOG_INFO_95_64 BIT(0) +#define MON_AXI_DDR1_LOG_INFO_W3_MON_AXI_DDR1_LOG_INFO_127_96 BIT(0) +#define MON_AXI_DDR1_LOG_INFO_W4_MON_AXI_DDR1_LOG_INFO_159_128 BIT(0) +#define MON_AXI_DDR1_LOG_INFO_W5_MON_AXI_DDR1_LOG_INFO_191_160 BIT(0) +#define MON_AXI_DDR1_LOG_INFO_W6_MON_AXI_DDR1_LOG_INFO_223_192 BIT(0) +#define MON_AXI_DDR1_LOG_INFO_W7_MON_AXI_DDR1_LOG_INFO_255_224 BIT(0) +#define MON_AXI_DDR1_LOG_INFO_W8_MON_AXI_DDR1_LOG_INFO_287_256 BIT(0) +#define MON_AXI_DDR1_LOG_INFO_W9_MON_AXI_DDR1_LOG_INFO_299_288 BIT(0) + +#define MON_AXI_DDR1_LOG_INFO_W0_MON_AXI_DDR1_LOG_INFO_31_0_MASK 0x00000001 +#define MON_AXI_DDR1_LOG_INFO_W1_MON_AXI_DDR1_LOG_INFO_63_32_MASK 0x00000001 +#define MON_AXI_DDR1_LOG_INFO_W2_MON_AXI_DDR1_LOG_INFO_95_64_MASK 0x00000001 +#define MON_AXI_DDR1_LOG_INFO_W3_MON_AXI_DDR1_LOG_INFO_127_96_MASK 0x00000001 +#define MON_AXI_DDR1_LOG_INFO_W4_MON_AXI_DDR1_LOG_INFO_159_128_MASK 0x00000001 +#define MON_AXI_DDR1_LOG_INFO_W5_MON_AXI_DDR1_LOG_INFO_191_160_MASK 0x00000001 +#define MON_AXI_DDR1_LOG_INFO_W6_MON_AXI_DDR1_LOG_INFO_223_192_MASK 0x00000001 +#define MON_AXI_DDR1_LOG_INFO_W7_MON_AXI_DDR1_LOG_INFO_255_224_MASK 0x00000001 +#define MON_AXI_DDR1_LOG_INFO_W8_MON_AXI_DDR1_LOG_INFO_287_256_MASK 0x00000001 +#define MON_AXI_DDR1_LOG_INFO_W9_MON_AXI_DDR1_LOG_INFO_299_288_MASK 0x00000001 + +/* ############################################################################ + * # MonAxiMemCurInfo Definition + */ +#define MON_AXI_MEM_CUR_INFO_W0_MON_AXI_MEM_CUR_INFO_31_0 BIT(0) +#define MON_AXI_MEM_CUR_INFO_W1_MON_AXI_MEM_CUR_INFO_63_32 BIT(0) +#define MON_AXI_MEM_CUR_INFO_W2_MON_AXI_MEM_CUR_INFO_95_64 BIT(0) +#define MON_AXI_MEM_CUR_INFO_W3_MON_AXI_MEM_CUR_INFO_127_96 BIT(0) +#define MON_AXI_MEM_CUR_INFO_W4_MON_AXI_MEM_CUR_INFO_159_128 BIT(0) +#define MON_AXI_MEM_CUR_INFO_W5_MON_AXI_MEM_CUR_INFO_191_160 BIT(0) +#define MON_AXI_MEM_CUR_INFO_W6_MON_AXI_MEM_CUR_INFO_223_192 BIT(0) +#define MON_AXI_MEM_CUR_INFO_W7_MON_AXI_MEM_CUR_INFO_255_224 BIT(0) +#define MON_AXI_MEM_CUR_INFO_W8_MON_AXI_MEM_CUR_INFO_287_256 BIT(0) +#define MON_AXI_MEM_CUR_INFO_W9_MON_AXI_MEM_CUR_INFO_303_288 BIT(0) + +#define MON_AXI_MEM_CUR_INFO_W0_MON_AXI_MEM_CUR_INFO_31_0_MASK 0x00000001 +#define MON_AXI_MEM_CUR_INFO_W1_MON_AXI_MEM_CUR_INFO_63_32_MASK 0x00000001 +#define MON_AXI_MEM_CUR_INFO_W2_MON_AXI_MEM_CUR_INFO_95_64_MASK 0x00000001 +#define MON_AXI_MEM_CUR_INFO_W3_MON_AXI_MEM_CUR_INFO_127_96_MASK 0x00000001 +#define MON_AXI_MEM_CUR_INFO_W4_MON_AXI_MEM_CUR_INFO_159_128_MASK 0x00000001 +#define MON_AXI_MEM_CUR_INFO_W5_MON_AXI_MEM_CUR_INFO_191_160_MASK 0x00000001 +#define MON_AXI_MEM_CUR_INFO_W6_MON_AXI_MEM_CUR_INFO_223_192_MASK 0x00000001 +#define MON_AXI_MEM_CUR_INFO_W7_MON_AXI_MEM_CUR_INFO_255_224_MASK 0x00000001 +#define MON_AXI_MEM_CUR_INFO_W8_MON_AXI_MEM_CUR_INFO_287_256_MASK 0x00000001 +#define MON_AXI_MEM_CUR_INFO_W9_MON_AXI_MEM_CUR_INFO_303_288_MASK 0x00000001 + +/* ############################################################################ + * # MonAxiMemLogInfo Definition + */ +#define MON_AXI_MEM_LOG_INFO_W0_MON_AXI_MEM_LOG_INFO_31_0 BIT(0) +#define MON_AXI_MEM_LOG_INFO_W1_MON_AXI_MEM_LOG_INFO_63_32 BIT(0) +#define MON_AXI_MEM_LOG_INFO_W2_MON_AXI_MEM_LOG_INFO_95_64 BIT(0) +#define MON_AXI_MEM_LOG_INFO_W3_MON_AXI_MEM_LOG_INFO_127_96 BIT(0) +#define MON_AXI_MEM_LOG_INFO_W4_MON_AXI_MEM_LOG_INFO_159_128 BIT(0) +#define MON_AXI_MEM_LOG_INFO_W5_MON_AXI_MEM_LOG_INFO_191_160 BIT(0) +#define MON_AXI_MEM_LOG_INFO_W6_MON_AXI_MEM_LOG_INFO_223_192 BIT(0) +#define MON_AXI_MEM_LOG_INFO_W7_MON_AXI_MEM_LOG_INFO_255_224 BIT(0) +#define MON_AXI_MEM_LOG_INFO_W8_MON_AXI_MEM_LOG_INFO_287_256 BIT(0) +#define MON_AXI_MEM_LOG_INFO_W9_MON_AXI_MEM_LOG_INFO_303_288 BIT(0) + +#define MON_AXI_MEM_LOG_INFO_W0_MON_AXI_MEM_LOG_INFO_31_0_MASK 0x00000001 +#define MON_AXI_MEM_LOG_INFO_W1_MON_AXI_MEM_LOG_INFO_63_32_MASK 0x00000001 +#define MON_AXI_MEM_LOG_INFO_W2_MON_AXI_MEM_LOG_INFO_95_64_MASK 0x00000001 +#define MON_AXI_MEM_LOG_INFO_W3_MON_AXI_MEM_LOG_INFO_127_96_MASK 0x00000001 +#define MON_AXI_MEM_LOG_INFO_W4_MON_AXI_MEM_LOG_INFO_159_128_MASK 0x00000001 +#define MON_AXI_MEM_LOG_INFO_W5_MON_AXI_MEM_LOG_INFO_191_160_MASK 0x00000001 +#define MON_AXI_MEM_LOG_INFO_W6_MON_AXI_MEM_LOG_INFO_223_192_MASK 0x00000001 +#define MON_AXI_MEM_LOG_INFO_W7_MON_AXI_MEM_LOG_INFO_255_224_MASK 0x00000001 +#define MON_AXI_MEM_LOG_INFO_W8_MON_AXI_MEM_LOG_INFO_287_256_MASK 0x00000001 +#define MON_AXI_MEM_LOG_INFO_W9_MON_AXI_MEM_LOG_INFO_303_288_MASK 0x00000001 + +/* ############################################################################ + * # MonAxiMshCurInfo Definition + */ +#define MON_AXI_MSH_CUR_INFO_W0_MON_AXI_MSH_CUR_INFO_31_0 BIT(0) +#define MON_AXI_MSH_CUR_INFO_W1_MON_AXI_MSH_CUR_INFO_63_32 BIT(0) +#define MON_AXI_MSH_CUR_INFO_W2_MON_AXI_MSH_CUR_INFO_95_64 BIT(0) +#define MON_AXI_MSH_CUR_INFO_W3_MON_AXI_MSH_CUR_INFO_127_96 BIT(0) +#define MON_AXI_MSH_CUR_INFO_W4_MON_AXI_MSH_CUR_INFO_159_128 BIT(0) +#define MON_AXI_MSH_CUR_INFO_W5_MON_AXI_MSH_CUR_INFO_191_160 BIT(0) +#define MON_AXI_MSH_CUR_INFO_W6_MON_AXI_MSH_CUR_INFO_223_192 BIT(0) +#define MON_AXI_MSH_CUR_INFO_W7_MON_AXI_MSH_CUR_INFO_255_224 BIT(0) +#define MON_AXI_MSH_CUR_INFO_W8_MON_AXI_MSH_CUR_INFO_275_256 BIT(0) + +#define MON_AXI_MSH_CUR_INFO_W0_MON_AXI_MSH_CUR_INFO_31_0_MASK 0x00000001 +#define MON_AXI_MSH_CUR_INFO_W1_MON_AXI_MSH_CUR_INFO_63_32_MASK 0x00000001 +#define MON_AXI_MSH_CUR_INFO_W2_MON_AXI_MSH_CUR_INFO_95_64_MASK 0x00000001 +#define MON_AXI_MSH_CUR_INFO_W3_MON_AXI_MSH_CUR_INFO_127_96_MASK 0x00000001 +#define MON_AXI_MSH_CUR_INFO_W4_MON_AXI_MSH_CUR_INFO_159_128_MASK 0x00000001 +#define MON_AXI_MSH_CUR_INFO_W5_MON_AXI_MSH_CUR_INFO_191_160_MASK 0x00000001 +#define MON_AXI_MSH_CUR_INFO_W6_MON_AXI_MSH_CUR_INFO_223_192_MASK 0x00000001 +#define MON_AXI_MSH_CUR_INFO_W7_MON_AXI_MSH_CUR_INFO_255_224_MASK 0x00000001 +#define MON_AXI_MSH_CUR_INFO_W8_MON_AXI_MSH_CUR_INFO_275_256_MASK 0x00000001 + +/* ############################################################################ + * # MonAxiMshLogInfo Definition + */ +#define MON_AXI_MSH_LOG_INFO_W0_MON_AXI_MSH_LOG_INFO_31_0 BIT(0) +#define MON_AXI_MSH_LOG_INFO_W1_MON_AXI_MSH_LOG_INFO_63_32 BIT(0) +#define MON_AXI_MSH_LOG_INFO_W2_MON_AXI_MSH_LOG_INFO_95_64 BIT(0) +#define MON_AXI_MSH_LOG_INFO_W3_MON_AXI_MSH_LOG_INFO_127_96 BIT(0) +#define MON_AXI_MSH_LOG_INFO_W4_MON_AXI_MSH_LOG_INFO_159_128 BIT(0) +#define MON_AXI_MSH_LOG_INFO_W5_MON_AXI_MSH_LOG_INFO_191_160 BIT(0) +#define MON_AXI_MSH_LOG_INFO_W6_MON_AXI_MSH_LOG_INFO_223_192 BIT(0) +#define MON_AXI_MSH_LOG_INFO_W7_MON_AXI_MSH_LOG_INFO_255_224 BIT(0) +#define MON_AXI_MSH_LOG_INFO_W8_MON_AXI_MSH_LOG_INFO_275_256 BIT(0) +#define MON_AXI_MSH_LOG_INFO_W8_MON_AXI_MSH_LOG_WD_ID BIT(24) + +#define MON_AXI_MSH_LOG_INFO_W0_MON_AXI_MSH_LOG_INFO_31_0_MASK 0x00000001 +#define MON_AXI_MSH_LOG_INFO_W1_MON_AXI_MSH_LOG_INFO_63_32_MASK 0x00000001 +#define MON_AXI_MSH_LOG_INFO_W2_MON_AXI_MSH_LOG_INFO_95_64_MASK 0x00000001 +#define MON_AXI_MSH_LOG_INFO_W3_MON_AXI_MSH_LOG_INFO_127_96_MASK 0x00000001 +#define MON_AXI_MSH_LOG_INFO_W4_MON_AXI_MSH_LOG_INFO_159_128_MASK 0x00000001 +#define MON_AXI_MSH_LOG_INFO_W5_MON_AXI_MSH_LOG_INFO_191_160_MASK 0x00000001 +#define MON_AXI_MSH_LOG_INFO_W6_MON_AXI_MSH_LOG_INFO_223_192_MASK 0x00000001 +#define MON_AXI_MSH_LOG_INFO_W7_MON_AXI_MSH_LOG_INFO_255_224_MASK 0x00000001 +#define MON_AXI_MSH_LOG_INFO_W8_MON_AXI_MSH_LOG_INFO_275_256_MASK 0x00000001 +#define MON_AXI_MSH_LOG_INFO_W8_MON_AXI_MSH_LOG_WD_ID_MASK 0x0f000000 + +/* ############################################################################ + * # MonAxiPcieCurInfo Definition + */ +#define MON_AXI_PCIE_CUR_INFO_W0_MON_AXI_PCIE_CUR_INFO_31_0 BIT(0) +#define MON_AXI_PCIE_CUR_INFO_W1_MON_AXI_PCIE_CUR_INFO_63_32 BIT(0) +#define MON_AXI_PCIE_CUR_INFO_W2_MON_AXI_PCIE_CUR_INFO_95_64 BIT(0) +#define MON_AXI_PCIE_CUR_INFO_W3_MON_AXI_PCIE_CUR_INFO_127_96 BIT(0) +#define MON_AXI_PCIE_CUR_INFO_W4_MON_AXI_PCIE_CUR_INFO_159_128 BIT(0) +#define MON_AXI_PCIE_CUR_INFO_W5_MON_AXI_PCIE_CUR_INFO_191_160 BIT(0) +#define MON_AXI_PCIE_CUR_INFO_W6_MON_AXI_PCIE_CUR_INFO_223_192 BIT(0) +#define MON_AXI_PCIE_CUR_INFO_W7_MON_AXI_PCIE_CUR_INFO_255_224 BIT(0) +#define MON_AXI_PCIE_CUR_INFO_W8_MON_AXI_PCIE_CUR_INFO_287_256 BIT(0) +#define MON_AXI_PCIE_CUR_INFO_W9_MON_AXI_PCIE_CUR_INFO_291_288 BIT(0) + +#define MON_AXI_PCIE_CUR_INFO_W0_MON_AXI_PCIE_CUR_INFO_31_0_MASK 0x00000001 +#define MON_AXI_PCIE_CUR_INFO_W1_MON_AXI_PCIE_CUR_INFO_63_32_MASK 0x00000001 +#define MON_AXI_PCIE_CUR_INFO_W2_MON_AXI_PCIE_CUR_INFO_95_64_MASK 0x00000001 +#define MON_AXI_PCIE_CUR_INFO_W3_MON_AXI_PCIE_CUR_INFO_127_96_MASK 0x00000001 +#define MON_AXI_PCIE_CUR_INFO_W4_MON_AXI_PCIE_CUR_INFO_159_128_MASK 0x00000001 +#define MON_AXI_PCIE_CUR_INFO_W5_MON_AXI_PCIE_CUR_INFO_191_160_MASK 0x00000001 +#define MON_AXI_PCIE_CUR_INFO_W6_MON_AXI_PCIE_CUR_INFO_223_192_MASK 0x00000001 +#define MON_AXI_PCIE_CUR_INFO_W7_MON_AXI_PCIE_CUR_INFO_255_224_MASK 0x00000001 +#define MON_AXI_PCIE_CUR_INFO_W8_MON_AXI_PCIE_CUR_INFO_287_256_MASK 0x00000001 +#define MON_AXI_PCIE_CUR_INFO_W9_MON_AXI_PCIE_CUR_INFO_291_288_MASK 0x00000001 + +/* ############################################################################ + * # MonAxiPcieLogInfo Definition + */ +#define MON_AXI_PCIE_LOG_INFO_W0_MON_AXI_PCIE_LOG_INFO_31_0 BIT(0) +#define MON_AXI_PCIE_LOG_INFO_W1_MON_AXI_PCIE_LOG_INFO_63_32 BIT(0) +#define MON_AXI_PCIE_LOG_INFO_W2_MON_AXI_PCIE_LOG_INFO_95_64 BIT(0) +#define MON_AXI_PCIE_LOG_INFO_W3_MON_AXI_PCIE_LOG_INFO_127_96 BIT(0) +#define MON_AXI_PCIE_LOG_INFO_W4_MON_AXI_PCIE_LOG_INFO_159_128 BIT(0) +#define MON_AXI_PCIE_LOG_INFO_W5_MON_AXI_PCIE_LOG_INFO_191_160 BIT(0) +#define MON_AXI_PCIE_LOG_INFO_W6_MON_AXI_PCIE_LOG_INFO_223_192 BIT(0) +#define MON_AXI_PCIE_LOG_INFO_W7_MON_AXI_PCIE_LOG_INFO_255_224 BIT(0) +#define MON_AXI_PCIE_LOG_INFO_W8_MON_AXI_PCIE_LOG_INFO_287_256 BIT(0) +#define MON_AXI_PCIE_LOG_INFO_W9_MON_AXI_PCIE_LOG_INFO_291_288 BIT(0) + +#define MON_AXI_PCIE_LOG_INFO_W0_MON_AXI_PCIE_LOG_INFO_31_0_MASK 0x00000001 +#define MON_AXI_PCIE_LOG_INFO_W1_MON_AXI_PCIE_LOG_INFO_63_32_MASK 0x00000001 +#define MON_AXI_PCIE_LOG_INFO_W2_MON_AXI_PCIE_LOG_INFO_95_64_MASK 0x00000001 +#define MON_AXI_PCIE_LOG_INFO_W3_MON_AXI_PCIE_LOG_INFO_127_96_MASK 0x00000001 +#define MON_AXI_PCIE_LOG_INFO_W4_MON_AXI_PCIE_LOG_INFO_159_128_MASK 0x00000001 +#define MON_AXI_PCIE_LOG_INFO_W5_MON_AXI_PCIE_LOG_INFO_191_160_MASK 0x00000001 +#define MON_AXI_PCIE_LOG_INFO_W6_MON_AXI_PCIE_LOG_INFO_223_192_MASK 0x00000001 +#define MON_AXI_PCIE_LOG_INFO_W7_MON_AXI_PCIE_LOG_INFO_255_224_MASK 0x00000001 +#define MON_AXI_PCIE_LOG_INFO_W8_MON_AXI_PCIE_LOG_INFO_287_256_MASK 0x00000001 +#define MON_AXI_PCIE_LOG_INFO_W9_MON_AXI_PCIE_LOG_INFO_291_288_MASK 0x00000001 + +/* ############################################################################ + * # MonAxiQspiCurInfo Definition + */ +#define MON_AXI_QSPI_CUR_INFO_W0_MON_AXI_QSPI_CUR_INFO_31_0 BIT(0) +#define MON_AXI_QSPI_CUR_INFO_W1_MON_AXI_QSPI_CUR_INFO_63_32 BIT(0) +#define MON_AXI_QSPI_CUR_INFO_W2_MON_AXI_QSPI_CUR_INFO_95_64 BIT(0) +#define MON_AXI_QSPI_CUR_INFO_W3_MON_AXI_QSPI_CUR_INFO_127_96 BIT(0) +#define MON_AXI_QSPI_CUR_INFO_W4_MON_AXI_QSPI_CUR_INFO_159_128 BIT(0) +#define MON_AXI_QSPI_CUR_INFO_W5_MON_AXI_QSPI_CUR_INFO_191_160 BIT(0) +#define MON_AXI_QSPI_CUR_INFO_W6_MON_AXI_QSPI_CUR_INFO_223_192 BIT(0) + +#define MON_AXI_QSPI_CUR_INFO_W0_MON_AXI_QSPI_CUR_INFO_31_0_MASK 0x00000001 +#define MON_AXI_QSPI_CUR_INFO_W1_MON_AXI_QSPI_CUR_INFO_63_32_MASK 0x00000001 +#define MON_AXI_QSPI_CUR_INFO_W2_MON_AXI_QSPI_CUR_INFO_95_64_MASK 0x00000001 +#define MON_AXI_QSPI_CUR_INFO_W3_MON_AXI_QSPI_CUR_INFO_127_96_MASK 0x00000001 +#define MON_AXI_QSPI_CUR_INFO_W4_MON_AXI_QSPI_CUR_INFO_159_128_MASK 0x00000001 +#define MON_AXI_QSPI_CUR_INFO_W5_MON_AXI_QSPI_CUR_INFO_191_160_MASK 0x00000001 +#define MON_AXI_QSPI_CUR_INFO_W6_MON_AXI_QSPI_CUR_INFO_223_192_MASK 0x00000001 + +/* ############################################################################ + * # MonAxiQspiLogInfo Definition + */ +#define MON_AXI_QSPI_LOG_INFO_W0_MON_AXI_QSPI_LOG_INFO_31_0 BIT(0) +#define MON_AXI_QSPI_LOG_INFO_W1_MON_AXI_QSPI_LOG_INFO_63_32 BIT(0) +#define MON_AXI_QSPI_LOG_INFO_W2_MON_AXI_QSPI_LOG_INFO_95_64 BIT(0) +#define MON_AXI_QSPI_LOG_INFO_W3_MON_AXI_QSPI_LOG_INFO_127_96 BIT(0) +#define MON_AXI_QSPI_LOG_INFO_W4_MON_AXI_QSPI_LOG_INFO_159_128 BIT(0) +#define MON_AXI_QSPI_LOG_INFO_W5_MON_AXI_QSPI_LOG_INFO_191_160 BIT(0) +#define MON_AXI_QSPI_LOG_INFO_W6_MON_AXI_QSPI_LOG_INFO_223_192 BIT(0) +#define MON_AXI_QSPI_LOG_INFO_W7_MON_AXI_QSPI_LOG_WD_ID BIT(0) + +#define MON_AXI_QSPI_LOG_INFO_W0_MON_AXI_QSPI_LOG_INFO_31_0_MASK 0x00000001 +#define MON_AXI_QSPI_LOG_INFO_W1_MON_AXI_QSPI_LOG_INFO_63_32_MASK 0x00000001 +#define MON_AXI_QSPI_LOG_INFO_W2_MON_AXI_QSPI_LOG_INFO_95_64_MASK 0x00000001 +#define MON_AXI_QSPI_LOG_INFO_W3_MON_AXI_QSPI_LOG_INFO_127_96_MASK 0x00000001 +#define MON_AXI_QSPI_LOG_INFO_W4_MON_AXI_QSPI_LOG_INFO_159_128_MASK 0x00000001 +#define MON_AXI_QSPI_LOG_INFO_W5_MON_AXI_QSPI_LOG_INFO_191_160_MASK 0x00000001 +#define MON_AXI_QSPI_LOG_INFO_W6_MON_AXI_QSPI_LOG_INFO_223_192_MASK 0x00000001 +#define MON_AXI_QSPI_LOG_INFO_W7_MON_AXI_QSPI_LOG_WD_ID_MASK 0x000003ff + +/* ############################################################################ + * # MonAxiSupCurInfo Definition + */ +#define MON_AXI_SUP_CUR_INFO_W0_MON_AXI_SUP_CUR_INFO_31_0 BIT(0) +#define MON_AXI_SUP_CUR_INFO_W1_MON_AXI_SUP_CUR_INFO_63_32 BIT(0) +#define MON_AXI_SUP_CUR_INFO_W2_MON_AXI_SUP_CUR_INFO_95_64 BIT(0) +#define MON_AXI_SUP_CUR_INFO_W3_MON_AXI_SUP_CUR_INFO_127_96 BIT(0) +#define MON_AXI_SUP_CUR_INFO_W4_MON_AXI_SUP_CUR_INFO_159_128 BIT(0) +#define MON_AXI_SUP_CUR_INFO_W5_MON_AXI_SUP_CUR_INFO_191_160 BIT(0) +#define MON_AXI_SUP_CUR_INFO_W6_MON_AXI_SUP_CUR_INFO_223_192 BIT(0) +#define MON_AXI_SUP_CUR_INFO_W7_MON_AXI_SUP_CUR_INFO_231_224 BIT(0) + +#define MON_AXI_SUP_CUR_INFO_W0_MON_AXI_SUP_CUR_INFO_31_0_MASK 0x00000001 +#define MON_AXI_SUP_CUR_INFO_W1_MON_AXI_SUP_CUR_INFO_63_32_MASK 0x00000001 +#define MON_AXI_SUP_CUR_INFO_W2_MON_AXI_SUP_CUR_INFO_95_64_MASK 0x00000001 +#define MON_AXI_SUP_CUR_INFO_W3_MON_AXI_SUP_CUR_INFO_127_96_MASK 0x00000001 +#define MON_AXI_SUP_CUR_INFO_W4_MON_AXI_SUP_CUR_INFO_159_128_MASK 0x00000001 +#define MON_AXI_SUP_CUR_INFO_W5_MON_AXI_SUP_CUR_INFO_191_160_MASK 0x00000001 +#define MON_AXI_SUP_CUR_INFO_W6_MON_AXI_SUP_CUR_INFO_223_192_MASK 0x00000001 +#define MON_AXI_SUP_CUR_INFO_W7_MON_AXI_SUP_CUR_INFO_231_224_MASK 0x00000001 + +/* ############################################################################ + * # MonAxiSupLogInfo Definition + */ +#define MON_AXI_SUP_LOG_INFO_W0_MON_AXI_SUP_LOG_INFO_31_0 BIT(0) +#define MON_AXI_SUP_LOG_INFO_W1_MON_AXI_SUP_LOG_INFO_63_32 BIT(0) +#define MON_AXI_SUP_LOG_INFO_W2_MON_AXI_SUP_LOG_INFO_95_64 BIT(0) +#define MON_AXI_SUP_LOG_INFO_W3_MON_AXI_SUP_LOG_INFO_127_96 BIT(0) +#define MON_AXI_SUP_LOG_INFO_W4_MON_AXI_SUP_LOG_INFO_159_128 BIT(0) +#define MON_AXI_SUP_LOG_INFO_W5_MON_AXI_SUP_LOG_INFO_191_160 BIT(0) +#define MON_AXI_SUP_LOG_INFO_W6_MON_AXI_SUP_LOG_INFO_223_192 BIT(0) +#define MON_AXI_SUP_LOG_INFO_W7_MON_AXI_SUP_LOG_INFO_231_224 BIT(0) + +#define MON_AXI_SUP_LOG_INFO_W0_MON_AXI_SUP_LOG_INFO_31_0_MASK 0x00000001 +#define MON_AXI_SUP_LOG_INFO_W1_MON_AXI_SUP_LOG_INFO_63_32_MASK 0x00000001 +#define MON_AXI_SUP_LOG_INFO_W2_MON_AXI_SUP_LOG_INFO_95_64_MASK 0x00000001 +#define MON_AXI_SUP_LOG_INFO_W3_MON_AXI_SUP_LOG_INFO_127_96_MASK 0x00000001 +#define MON_AXI_SUP_LOG_INFO_W4_MON_AXI_SUP_LOG_INFO_159_128_MASK 0x00000001 +#define MON_AXI_SUP_LOG_INFO_W5_MON_AXI_SUP_LOG_INFO_191_160_MASK 0x00000001 +#define MON_AXI_SUP_LOG_INFO_W6_MON_AXI_SUP_LOG_INFO_223_192_MASK 0x00000001 +#define MON_AXI_SUP_LOG_INFO_W7_MON_AXI_SUP_LOG_INFO_231_224_MASK 0x00000001 + +/* ############################################################################ + * # MonSysApbCurInfo Definition + */ +#define MON_SYS_APB_CUR_INFO_W0_MON_SYS_APB_CUR_ADDR BIT(0) +#define MON_SYS_APB_CUR_INFO_W1_MON_SYS_APB_CUR_WR_DATA BIT(0) +#define MON_SYS_APB_CUR_INFO_W2_MON_SYS_APB_CUR_RD_DATA BIT(0) +#define MON_SYS_APB_CUR_INFO_W3_MON_SYS_APB_CUR_ENABLE BIT(3) +#define MON_SYS_APB_CUR_INFO_W3_MON_SYS_APB_CUR_WRITE BIT(2) +#define MON_SYS_APB_CUR_INFO_W3_MON_SYS_APB_CUR_READY BIT(1) +#define MON_SYS_APB_CUR_INFO_W3_MON_SYS_APB_CUR_SEL BIT(4) +#define MON_SYS_APB_CUR_INFO_W3_MON_SYS_APB_CUR_SLV_ERR BIT(0) + +#define MON_SYS_APB_CUR_INFO_W0_MON_SYS_APB_CUR_ADDR_MASK 0xffffffff +#define MON_SYS_APB_CUR_INFO_W1_MON_SYS_APB_CUR_WR_DATA_MASK 0xffffffff +#define MON_SYS_APB_CUR_INFO_W2_MON_SYS_APB_CUR_RD_DATA_MASK 0xffffffff +#define MON_SYS_APB_CUR_INFO_W3_MON_SYS_APB_CUR_ENABLE_MASK 0x00000008 +#define MON_SYS_APB_CUR_INFO_W3_MON_SYS_APB_CUR_WRITE_MASK 0x00000004 +#define MON_SYS_APB_CUR_INFO_W3_MON_SYS_APB_CUR_READY_MASK 0x00000002 +#define MON_SYS_APB_CUR_INFO_W3_MON_SYS_APB_CUR_SEL_MASK 0x00000010 +#define MON_SYS_APB_CUR_INFO_W3_MON_SYS_APB_CUR_SLV_ERR_MASK 0x00000001 + +/* ############################################################################ + * # MonSysApbLogInfo Definition + */ +#define MON_SYS_APB_LOG_INFO_W0_MON_SYS_APB_LOG_ADDR BIT(0) +#define MON_SYS_APB_LOG_INFO_W1_MON_SYS_APB_LOG_WR_DATA BIT(0) +#define MON_SYS_APB_LOG_INFO_W2_MON_SYS_APB_LOG_RD_DATA BIT(0) +#define MON_SYS_APB_LOG_INFO_W3_MON_SYS_APB_LOG_SEL BIT(4) +#define MON_SYS_APB_LOG_INFO_W3_MON_SYS_APB_LOG_ENABLE BIT(3) +#define MON_SYS_APB_LOG_INFO_W3_MON_SYS_APB_LOG_READY BIT(1) +#define MON_SYS_APB_LOG_INFO_W3_MON_SYS_APB_ERR_CNT BIT(8) +#define MON_SYS_APB_LOG_INFO_W3_MON_SYS_APB_LOG_SLV_ERR BIT(0) +#define MON_SYS_APB_LOG_INFO_W3_MON_SYS_APB_LOG_WRITE BIT(2) + +#define MON_SYS_APB_LOG_INFO_W0_MON_SYS_APB_LOG_ADDR_MASK 0xffffffff +#define MON_SYS_APB_LOG_INFO_W1_MON_SYS_APB_LOG_WR_DATA_MASK 0xffffffff +#define MON_SYS_APB_LOG_INFO_W2_MON_SYS_APB_LOG_RD_DATA_MASK 0xffffffff +#define MON_SYS_APB_LOG_INFO_W3_MON_SYS_APB_LOG_SEL_MASK 0x00000010 +#define MON_SYS_APB_LOG_INFO_W3_MON_SYS_APB_LOG_ENABLE_MASK 0x00000008 +#define MON_SYS_APB_LOG_INFO_W3_MON_SYS_APB_LOG_READY_MASK 0x00000002 +#define MON_SYS_APB_LOG_INFO_W3_MON_SYS_APB_ERR_CNT_MASK 0x0000ff00 +#define MON_SYS_APB_LOG_INFO_W3_MON_SYS_APB_LOG_SLV_ERR_MASK 0x00000001 +#define MON_SYS_APB_LOG_INFO_W3_MON_SYS_APB_LOG_WRITE_MASK 0x00000004 + +/* ############################################################################ + * # MonSecApbCurInfo Definition + */ +#define MON_SEC_APB_CUR_INFO_W0_MON_SEC_APB_CUR_ADDR BIT(0) +#define MON_SEC_APB_CUR_INFO_W1_MON_SEC_APB_CUR_WR_DATA BIT(0) +#define MON_SEC_APB_CUR_INFO_W2_MON_SEC_APB_CUR_RD_DATA BIT(0) +#define MON_SEC_APB_CUR_INFO_W3_MON_SEC_APB_CUR_WRITE BIT(2) +#define MON_SEC_APB_CUR_INFO_W3_MON_SEC_APB_CUR_READY BIT(1) +#define MON_SEC_APB_CUR_INFO_W3_MON_SEC_APB_CUR_SLV_ERR BIT(0) +#define MON_SEC_APB_CUR_INFO_W3_MON_SEC_APB_CUR_ENABLE BIT(3) +#define MON_SEC_APB_CUR_INFO_W3_MON_SEC_APB_CUR_SEL BIT(4) + +#define MON_SEC_APB_CUR_INFO_W0_MON_SEC_APB_CUR_ADDR_MASK 0xffffffff +#define MON_SEC_APB_CUR_INFO_W1_MON_SEC_APB_CUR_WR_DATA_MASK 0xffffffff +#define MON_SEC_APB_CUR_INFO_W2_MON_SEC_APB_CUR_RD_DATA_MASK 0xffffffff +#define MON_SEC_APB_CUR_INFO_W3_MON_SEC_APB_CUR_WRITE_MASK 0x00000004 +#define MON_SEC_APB_CUR_INFO_W3_MON_SEC_APB_CUR_READY_MASK 0x00000002 +#define MON_SEC_APB_CUR_INFO_W3_MON_SEC_APB_CUR_SLV_ERR_MASK 0x00000001 +#define MON_SEC_APB_CUR_INFO_W3_MON_SEC_APB_CUR_ENABLE_MASK 0x00000008 +#define MON_SEC_APB_CUR_INFO_W3_MON_SEC_APB_CUR_SEL_MASK 0x00000010 + +/* ############################################################################ + * # MonSecApbLogInfo Definition + */ +#define MON_SEC_APB_LOG_INFO_W0_MON_SEC_APB_LOG_ADDR BIT(0) +#define MON_SEC_APB_LOG_INFO_W1_MON_SEC_APB_LOG_WR_DATA BIT(0) +#define MON_SEC_APB_LOG_INFO_W2_MON_SEC_APB_LOG_RD_DATA BIT(0) +#define MON_SEC_APB_LOG_INFO_W3_MON_SEC_APB_LOG_SLV_ERR BIT(0) +#define MON_SEC_APB_LOG_INFO_W3_MON_SEC_APB_LOG_WRITE BIT(2) +#define MON_SEC_APB_LOG_INFO_W3_MON_SEC_APB_LOG_READY BIT(1) +#define MON_SEC_APB_LOG_INFO_W3_MON_SEC_APB_LOG_ENABLE BIT(3) +#define MON_SEC_APB_LOG_INFO_W3_MON_SEC_APB_LOG_SEL BIT(4) +#define MON_SEC_APB_LOG_INFO_W3_MON_SEC_APB_ERR_CNT BIT(8) + +#define MON_SEC_APB_LOG_INFO_W0_MON_SEC_APB_LOG_ADDR_MASK 0xffffffff +#define MON_SEC_APB_LOG_INFO_W1_MON_SEC_APB_LOG_WR_DATA_MASK 0xffffffff +#define MON_SEC_APB_LOG_INFO_W2_MON_SEC_APB_LOG_RD_DATA_MASK 0xffffffff +#define MON_SEC_APB_LOG_INFO_W3_MON_SEC_APB_LOG_SLV_ERR_MASK 0x00000001 +#define MON_SEC_APB_LOG_INFO_W3_MON_SEC_APB_LOG_WRITE_MASK 0x00000004 +#define MON_SEC_APB_LOG_INFO_W3_MON_SEC_APB_LOG_READY_MASK 0x00000002 +#define MON_SEC_APB_LOG_INFO_W3_MON_SEC_APB_LOG_ENABLE_MASK 0x00000008 +#define MON_SEC_APB_LOG_INFO_W3_MON_SEC_APB_LOG_SEL_MASK 0x00000010 +#define MON_SEC_APB_LOG_INFO_W3_MON_SEC_APB_ERR_CNT_MASK 0x0000ff00 + +/* ############################################################################ + * # DebugCpuCnt Definition + */ +#define DEBUG_CPU_CNT_W0_MON_CPU_WA_LOG_CNT BIT(8) +#define DEBUG_CPU_CNT_W0_MON_CPU_RA_LOG_CNT BIT(0) +#define DEBUG_CPU_CNT_W0_MON_CPU_WD_LOG_CNT BIT(16) +#define DEBUG_CPU_CNT_W1_MON_CPU_WR_OUT_CNT BIT(8) +#define DEBUG_CPU_CNT_W1_MON_CPU_RD_OUT_CNT BIT(0) +#define DEBUG_CPU_CNT_W1_MON_CPU_WR_RESP_ERROR_CNT BIT(24) +#define DEBUG_CPU_CNT_W1_MON_CPU_RD_RESP_ERROR_CNT BIT(16) + +#define DEBUG_CPU_CNT_W0_MON_CPU_WA_LOG_CNT_MASK 0x0000ff00 +#define DEBUG_CPU_CNT_W0_MON_CPU_RA_LOG_CNT_MASK 0x000000ff +#define DEBUG_CPU_CNT_W0_MON_CPU_WD_LOG_CNT_MASK 0x00ff0000 +#define DEBUG_CPU_CNT_W1_MON_CPU_WR_OUT_CNT_MASK 0x00001f00 +#define DEBUG_CPU_CNT_W1_MON_CPU_RD_OUT_CNT_MASK 0x0000001f +#define DEBUG_CPU_CNT_W1_MON_CPU_WR_RESP_ERROR_CNT_MASK 0xff000000 +#define DEBUG_CPU_CNT_W1_MON_CPU_RD_RESP_ERROR_CNT_MASK 0x00ff0000 + +/* ############################################################################ + * # DebugMemCnt Definition + */ +#define DEBUG_MEM_CNT_W0_MON_MEM_WA_LOG_CNT BIT(8) +#define DEBUG_MEM_CNT_W0_MON_MEM_RA_LOG_CNT BIT(0) +#define DEBUG_MEM_CNT_W0_MON_MEM_WD_LOG_CNT BIT(16) +#define DEBUG_MEM_CNT_W1_MON_MEM_WR_OUT_CNT BIT(8) +#define DEBUG_MEM_CNT_W1_MON_MEM_RD_OUT_CNT BIT(0) + +#define DEBUG_MEM_CNT_W0_MON_MEM_WA_LOG_CNT_MASK 0x0000ff00 +#define DEBUG_MEM_CNT_W0_MON_MEM_RA_LOG_CNT_MASK 0x000000ff +#define DEBUG_MEM_CNT_W0_MON_MEM_WD_LOG_CNT_MASK 0x00ff0000 +#define DEBUG_MEM_CNT_W1_MON_MEM_WR_OUT_CNT_MASK 0x00001f00 +#define DEBUG_MEM_CNT_W1_MON_MEM_RD_OUT_CNT_MASK 0x0000001f + +/* ############################################################################ + * # DebugDdrCnt Definition + */ +#define DEBUG_DDR_CNT_W0_MON_DDR0_WA_LOG_CNT BIT(8) +#define DEBUG_DDR_CNT_W0_MON_DDR0_RA_LOG_CNT BIT(0) +#define DEBUG_DDR_CNT_W0_MON_DDR0_WD_LOG_CNT BIT(16) +#define DEBUG_DDR_CNT_W1_MON_DDR0_RD_OUT_CNT BIT(0) +#define DEBUG_DDR_CNT_W1_MON_DDR0_WR_RESP_ERROR_CNT BIT(24) +#define DEBUG_DDR_CNT_W1_MON_DDR0_RD_RESP_ERROR_CNT BIT(16) +#define DEBUG_DDR_CNT_W1_MON_DDR0_WR_OUT_CNT BIT(8) +#define DEBUG_DDR_CNT_W2_MON_DDR1_RA_LOG_CNT BIT(0) +#define DEBUG_DDR_CNT_W2_MON_DDR1_WD_LOG_CNT BIT(16) +#define DEBUG_DDR_CNT_W2_MON_DDR1_WA_LOG_CNT BIT(8) +#define DEBUG_DDR_CNT_W3_MON_DDR1_WR_OUT_CNT BIT(8) +#define DEBUG_DDR_CNT_W3_MON_DDR1_RD_RESP_ERROR_CNT BIT(16) +#define DEBUG_DDR_CNT_W3_MON_DDR1_RD_OUT_CNT BIT(0) +#define DEBUG_DDR_CNT_W3_MON_DDR1_WR_RESP_ERROR_CNT BIT(24) + +#define DEBUG_DDR_CNT_W0_MON_DDR0_WA_LOG_CNT_MASK 0x0000ff00 +#define DEBUG_DDR_CNT_W0_MON_DDR0_RA_LOG_CNT_MASK 0x000000ff +#define DEBUG_DDR_CNT_W0_MON_DDR0_WD_LOG_CNT_MASK 0x00ff0000 +#define DEBUG_DDR_CNT_W1_MON_DDR0_RD_OUT_CNT_MASK 0x0000001f +#define DEBUG_DDR_CNT_W1_MON_DDR0_WR_RESP_ERROR_CNT_MASK 0xff000000 +#define DEBUG_DDR_CNT_W1_MON_DDR0_RD_RESP_ERROR_CNT_MASK 0x00ff0000 +#define DEBUG_DDR_CNT_W1_MON_DDR0_WR_OUT_CNT_MASK 0x00001f00 +#define DEBUG_DDR_CNT_W2_MON_DDR1_RA_LOG_CNT_MASK 0x000000ff +#define DEBUG_DDR_CNT_W2_MON_DDR1_WD_LOG_CNT_MASK 0x00ff0000 +#define DEBUG_DDR_CNT_W2_MON_DDR1_WA_LOG_CNT_MASK 0x0000ff00 +#define DEBUG_DDR_CNT_W3_MON_DDR1_WR_OUT_CNT_MASK 0x00001f00 +#define DEBUG_DDR_CNT_W3_MON_DDR1_RD_RESP_ERROR_CNT_MASK 0x00ff0000 +#define DEBUG_DDR_CNT_W3_MON_DDR1_RD_OUT_CNT_MASK 0x0000001f +#define DEBUG_DDR_CNT_W3_MON_DDR1_WR_RESP_ERROR_CNT_MASK 0xff000000 + +/* ############################################################################ + * # DebugMshCnt Definition + */ +#define DEBUG_MSH_CNT_W0_MON_MSH_WD_LOG_CNT BIT(16) +#define DEBUG_MSH_CNT_W0_MON_MSH_RA_LOG_CNT BIT(0) +#define DEBUG_MSH_CNT_W0_MON_MSH_WA_LOG_CNT BIT(8) +#define DEBUG_MSH_CNT_W1_MON_MSH_RD_OUT_CNT BIT(0) +#define DEBUG_MSH_CNT_W1_MON_MSH_WR_OUT_CNT BIT(8) + +#define DEBUG_MSH_CNT_W0_MON_MSH_WD_LOG_CNT_MASK 0x00ff0000 +#define DEBUG_MSH_CNT_W0_MON_MSH_RA_LOG_CNT_MASK 0x000000ff +#define DEBUG_MSH_CNT_W0_MON_MSH_WA_LOG_CNT_MASK 0x0000ff00 +#define DEBUG_MSH_CNT_W1_MON_MSH_RD_OUT_CNT_MASK 0x0000001f +#define DEBUG_MSH_CNT_W1_MON_MSH_WR_OUT_CNT_MASK 0x00001f00 + +/* ############################################################################ + * # DebugPcieCnt Definition + */ +#define DEBUG_PCIE_CNT_W0_MON_PCIE_WD_LOG_CNT BIT(16) +#define DEBUG_PCIE_CNT_W0_MON_PCIE_RA_LOG_CNT BIT(0) +#define DEBUG_PCIE_CNT_W0_MON_PCIE_WA_LOG_CNT BIT(8) +#define DEBUG_PCIE_CNT_W1_MON_PCIE_WR_OUT_CNT BIT(8) +#define DEBUG_PCIE_CNT_W1_MON_PCIE_RD_OUT_CNT BIT(0) +#define DEBUG_PCIE_CNT_W1_MON_PCIE_WR_RESP_ERROR_CNT BIT(24) +#define DEBUG_PCIE_CNT_W1_MON_PCIE_RD_RESP_ERROR_CNT BIT(16) + +#define DEBUG_PCIE_CNT_W0_MON_PCIE_WD_LOG_CNT_MASK 0x00ff0000 +#define DEBUG_PCIE_CNT_W0_MON_PCIE_RA_LOG_CNT_MASK 0x000000ff +#define DEBUG_PCIE_CNT_W0_MON_PCIE_WA_LOG_CNT_MASK 0x0000ff00 +#define DEBUG_PCIE_CNT_W1_MON_PCIE_WR_OUT_CNT_MASK 0x00001f00 +#define DEBUG_PCIE_CNT_W1_MON_PCIE_RD_OUT_CNT_MASK 0x0000001f +#define DEBUG_PCIE_CNT_W1_MON_PCIE_WR_RESP_ERROR_CNT_MASK 0xff000000 +#define DEBUG_PCIE_CNT_W1_MON_PCIE_RD_RESP_ERROR_CNT_MASK 0x00ff0000 + +/* ############################################################################ + * # DebugQspiCnt Definition + */ +#define DEBUG_QSPI_CNT_W0_MON_QSPI_WD_LOG_CNT BIT(16) +#define DEBUG_QSPI_CNT_W0_MON_QSPI_RA_LOG_CNT BIT(0) +#define DEBUG_QSPI_CNT_W0_MON_QSPI_WA_LOG_CNT BIT(8) +#define DEBUG_QSPI_CNT_W1_MON_QSPI_RD_OUT_CNT BIT(0) +#define DEBUG_QSPI_CNT_W1_MON_QSPI_WR_OUT_CNT BIT(8) + +#define DEBUG_QSPI_CNT_W0_MON_QSPI_WD_LOG_CNT_MASK 0x00ff0000 +#define DEBUG_QSPI_CNT_W0_MON_QSPI_RA_LOG_CNT_MASK 0x000000ff +#define DEBUG_QSPI_CNT_W0_MON_QSPI_WA_LOG_CNT_MASK 0x0000ff00 +#define DEBUG_QSPI_CNT_W1_MON_QSPI_RD_OUT_CNT_MASK 0x0000001f +#define DEBUG_QSPI_CNT_W1_MON_QSPI_WR_OUT_CNT_MASK 0x00001f00 + +/* ############################################################################ + * # DebugSupCnt Definition + */ +#define DEBUG_SUP_CNT_W0_MON_SUP_WD_LOG_CNT BIT(16) +#define DEBUG_SUP_CNT_W0_MON_SUP_RA_LOG_CNT BIT(0) +#define DEBUG_SUP_CNT_W0_MON_SUP_WA_LOG_CNT BIT(8) +#define DEBUG_SUP_CNT_W1_MON_SUP_WR_OUT_CNT BIT(8) +#define DEBUG_SUP_CNT_W1_MON_SUP_RD_RESP_ERROR_CNT BIT(16) +#define DEBUG_SUP_CNT_W1_MON_SUP_WR_RESP_ERROR_CNT BIT(24) +#define DEBUG_SUP_CNT_W1_MON_SUP_RD_OUT_CNT BIT(0) + +#define DEBUG_SUP_CNT_W0_MON_SUP_WD_LOG_CNT_MASK 0x00ff0000 +#define DEBUG_SUP_CNT_W0_MON_SUP_RA_LOG_CNT_MASK 0x000000ff +#define DEBUG_SUP_CNT_W0_MON_SUP_WA_LOG_CNT_MASK 0x0000ff00 +#define DEBUG_SUP_CNT_W1_MON_SUP_WR_OUT_CNT_MASK 0x00001f00 +#define DEBUG_SUP_CNT_W1_MON_SUP_RD_RESP_ERROR_CNT_MASK 0x00ff0000 +#define DEBUG_SUP_CNT_W1_MON_SUP_WR_RESP_ERROR_CNT_MASK 0xff000000 +#define DEBUG_SUP_CNT_W1_MON_SUP_RD_OUT_CNT_MASK 0x0000001f + +/* ############################################################################ + * # SysSpiVecLog Definition + */ +#define SYS_SPI_VEC_LOG_W0_SPI_VEC_LOG_31_0 BIT(0) +#define SYS_SPI_VEC_LOG_W1_SPI_VEC_LOG_63_32 BIT(0) +#define SYS_SPI_VEC_LOG_W2_SPI_VEC_LOG_95_64 BIT(0) +#define SYS_SPI_VEC_LOG_W3_SPI_VEC_LOG_127_96 BIT(0) +#define SYS_SPI_VEC_LOG_W4_SPI_VEC_LOG_159_128 BIT(0) + +#define SYS_SPI_VEC_LOG_W0_SPI_VEC_LOG_31_0_MASK 0x00000001 +#define SYS_SPI_VEC_LOG_W1_SPI_VEC_LOG_63_32_MASK 0x00000001 +#define SYS_SPI_VEC_LOG_W2_SPI_VEC_LOG_95_64_MASK 0x00000001 +#define SYS_SPI_VEC_LOG_W3_SPI_VEC_LOG_127_96_MASK 0x00000001 +#define SYS_SPI_VEC_LOG_W4_SPI_VEC_LOG_159_128_MASK 0x00000001 + +/* ############################################################################ + * # DebugAhbRespCnt Definition + */ +#define DEBUG_AHB_RESP_CNT_W0_MON_MSH_CFG_RESP_ERROR_CNT BIT(8) +#define DEBUG_AHB_RESP_CNT_W0_MON_DDR_CFG_RESP_ERROR_CNT BIT(0) +#define DEBUG_AHB_RESP_CNT_W0_MON_USB_CFG_RESP_ERROR_CNT BIT(16) + +#define DEBUG_AHB_RESP_CNT_W0_MON_MSH_CFG_RESP_ERROR_CNT_MASK 0x0000ff00 +#define DEBUG_AHB_RESP_CNT_W0_MON_DDR_CFG_RESP_ERROR_CNT_MASK 0x000000ff +#define DEBUG_AHB_RESP_CNT_W0_MON_USB_CFG_RESP_ERROR_CNT_MASK 0x00ff0000 + +/* ############################################################################ + * # DebugGicRespCnt Definition + */ +#define DEBUG_GIC_RESP_CNT_W0_MON_GIC_RD_RESP_ERROR_CNT BIT(0) +#define DEBUG_GIC_RESP_CNT_W0_MON_GIC_WR_RESP_ERROR_CNT BIT(8) + +#define DEBUG_GIC_RESP_CNT_W0_MON_GIC_RD_RESP_ERROR_CNT_MASK 0x000000ff +#define DEBUG_GIC_RESP_CNT_W0_MON_GIC_WR_RESP_ERROR_CNT_MASK 0x0000ff00 + +/* ############################################################################ + * # DebugMemPtrCfg Definition + */ +#define DEBUG_MEM_PTR_CFG_W0_CFG_DBG_START_PTR BIT(0) +#define DEBUG_MEM_PTR_CFG_W0_CFG_DBG_END_PTR BIT(16) + +#define DEBUG_MEM_PTR_CFG_W0_CFG_DBG_START_PTR_MASK 0x00003fff +#define DEBUG_MEM_PTR_CFG_W0_CFG_DBG_END_PTR_MASK 0x3fff0000 + +/* ############################################################################ + * # Grant0IntMask Definition + */ +#define GRANT0_INT_MASK_W0_GRANT0_INT_MASK BIT(0) + +#define GRANT0_INT_MASK_W0_GRANT0_INT_MASK_MASK 0xffffffff + +/* ############################################################################ + * # Grant0IntCtl Definition + */ +#define GRANT0_INT_CTL_W0_GRANT0_INT_CTL BIT(0) + +#define GRANT0_INT_CTL_W0_GRANT0_INT_CTL_MASK 0xffffffff + +/* ############################################################################ + * # Grant1IntMask Definition + */ +#define GRANT1_INT_MASK_W0_GRANT1_INT_MASK BIT(0) + +#define GRANT1_INT_MASK_W0_GRANT1_INT_MASK_MASK 0xffffffff + +/* ############################################################################ + * # Grant1IntCtl Definition + */ +#define GRANT1_INT_CTL_W0_GRANT1_INT_CTL BIT(0) + +#define GRANT1_INT_CTL_W0_GRANT1_INT_CTL_MASK 0xffffffff + +/* ############################################################################ + * # Grant2IntMask Definition + */ +#define GRANT2_INT_MASK_W0_GRANT2_INT_MASK BIT(0) + +#define GRANT2_INT_MASK_W0_GRANT2_INT_MASK_MASK 0xffffffff + +/* ############################################################################ + * # Grant2IntCtl Definition + */ +#define GRANT2_INT_CTL_W0_GRANT2_INT_CTL BIT(0) + +#define GRANT2_INT_CTL_W0_GRANT2_INT_CTL_MASK 0xffffffff + +/* ############################################################################ + * # Grant3IntMask Definition + */ +#define GRANT3_INT_MASK_W0_GRANT3_INT_MASK BIT(0) + +#define GRANT3_INT_MASK_W0_GRANT3_INT_MASK_MASK 0xffffffff + +/* ############################################################################ + * # Grant3IntCtl Definition + */ +#define GRANT3_INT_CTL_W0_GRANT3_INT_CTL BIT(0) + +#define GRANT3_INT_CTL_W0_GRANT3_INT_CTL_MASK 0xffffffff + +/* ############################################################################ + * # SysIntrIntCtl Definition + */ +#define SYS_INTR_INT_CTL_W0_SYS_INTR_INT_CTL_31_0 BIT(0) +#define SYS_INTR_INT_CTL_W1_SYS_INTR_INT_CTL_63_32 BIT(0) + +#define SYS_INTR_INT_CTL_W0_SYS_INTR_INT_CTL_31_0_MASK 0x00000001 +#define SYS_INTR_INT_CTL_W1_SYS_INTR_INT_CTL_63_32_MASK 0x00000001 + +/* ############################################################################ + * # SupIntrIntCtl Definition + */ +#define SUP_INTR_INT_CTL_W0_SUP_INTR_INT_CTL_31_0 BIT(0) +#define SUP_INTR_INT_CTL_W1_SUP_INTR_INT_CTL_63_32 BIT(0) + +#define SUP_INTR_INT_CTL_W0_SUP_INTR_INT_CTL_31_0_MASK 0x00000001 +#define SUP_INTR_INT_CTL_W1_SUP_INTR_INT_CTL_63_32_MASK 0x00000001 + +/* ############################################################################ + * # SysMiscInfo0 Definition + */ +#define SYS_MISC_INFO0_W0_SYS_MISC_INFO0 BIT(0) + +#define SYS_MISC_INFO0_W0_SYS_MISC_INFO0_MASK 0xffffffff + +/* ############################################################################ + * # SysMiscInfo1 Definition + */ +#define SYS_MISC_INFO1_W0_SYS_MISC_INFO1 BIT(0) + +#define SYS_MISC_INFO1_W0_SYS_MISC_INFO1_MASK 0xffffffff + +/* ############################################################################ + * # SysMiscInfo2 Definition + */ +#define SYS_MISC_INFO2_W0_SYS_MISC_INFO2 BIT(0) + +#define SYS_MISC_INFO2_W0_SYS_MISC_INFO2_MASK 0xffffffff + +/* ############################################################################ + * # SysMiscInfo3 Definition + */ +#define SYS_MISC_INFO3_W0_SYS_MISC_INFO3 BIT(0) + +#define SYS_MISC_INFO3_W0_SYS_MISC_INFO3_MASK 0xffffffff + +/* ############################################################################ + * # CommonInfo0 Definition + */ +#define COMMON_INFO0_W0_COMMON_INFO0 BIT(0) + +#define COMMON_INFO0_W0_COMMON_INFO0_MASK 0xffffffff + +/* ############################################################################ + * # CommonInfo1 Definition + */ +#define COMMON_INFO1_W0_COMMON_INFO1 BIT(0) + +#define COMMON_INFO1_W0_COMMON_INFO1_MASK 0xffffffff + +/* ############################################################################ + * # CommonInfo2 Definition + */ +#define COMMON_INFO2_W0_COMMON_INFO2 BIT(0) + +#define COMMON_INFO2_W0_COMMON_INFO2_MASK 0xffffffff + +/* ############################################################################ + * # CommonInfo3 Definition + */ +#define COMMON_INFO3_W0_COMMON_INFO3 BIT(0) + +#define COMMON_INFO3_W0_COMMON_INFO3_MASK 0xffffffff + +/* ############################################################################ + * # Grant0ExtMask Definition + */ +#define GRANT0_EXT_MASK_W0_GRANT0_EXT_MASK BIT(0) + +#define GRANT0_EXT_MASK_W0_GRANT0_EXT_MASK_MASK 0xffffffff + +/* ############################################################################ + * # Grant0ExtCtl Definition + */ +#define GRANT0_EXT_CTL_W0_GRANT0_EXT_CTL BIT(0) + +#define GRANT0_EXT_CTL_W0_GRANT0_EXT_CTL_MASK 0xffffffff + +/* ############################################################################ + * # Grant1ExtMask Definition + */ +#define GRANT1_EXT_MASK_W0_GRANT1_EXT_MASK BIT(0) + +#define GRANT1_EXT_MASK_W0_GRANT1_EXT_MASK_MASK 0xffffffff + +/* ############################################################################ + * # Grant1ExtCtl Definition + */ +#define GRANT1_EXT_CTL_W0_GRANT1_EXT_CTL BIT(0) + +#define GRANT1_EXT_CTL_W0_GRANT1_EXT_CTL_MASK 0xffffffff + +/* ############################################################################ + * # Grant2ExtMask Definition + */ +#define GRANT2_EXT_MASK_W0_GRANT2_EXT_MASK BIT(0) + +#define GRANT2_EXT_MASK_W0_GRANT2_EXT_MASK_MASK 0xffffffff + +/* ############################################################################ + * # Grant2ExtCtl Definition + */ +#define GRANT2_EXT_CTL_W0_GRANT2_EXT_CTL BIT(0) + +#define GRANT2_EXT_CTL_W0_GRANT2_EXT_CTL_MASK 0xffffffff + +/* ############################################################################ + * # Grant3ExtMask Definition + */ +#define GRANT3_EXT_MASK_W0_GRANT3_EXT_MASK BIT(0) + +#define GRANT3_EXT_MASK_W0_GRANT3_EXT_MASK_MASK 0xffffffff + +/* ############################################################################ + * # Grant3ExtCtl Definition + */ +#define GRANT3_EXT_CTL_W0_GRANT3_EXT_CTL BIT(0) + +#define GRANT3_EXT_CTL_W0_GRANT3_EXT_CTL_MASK 0xffffffff + +/* ############################################################################ + * # SysIntrExtCtl Definition + */ +#define SYS_INTR_EXT_CTL_W0_SYS_INTR_EXT_CTL_31_0 BIT(0) +#define SYS_INTR_EXT_CTL_W1_SYS_INTR_EXT_CTL_63_32 BIT(0) + +#define SYS_INTR_EXT_CTL_W0_SYS_INTR_EXT_CTL_31_0_MASK 0x00000001 +#define SYS_INTR_EXT_CTL_W1_SYS_INTR_EXT_CTL_63_32_MASK 0x00000001 + +/* ############################################################################ + * # SupIntrExtCtl Definition + */ +#define SUP_INTR_EXT_CTL_W0_SUP_INTR_EXT_CTL_31_0 BIT(0) +#define SUP_INTR_EXT_CTL_W1_SUP_INTR_EXT_CTL_63_32 BIT(0) + +#define SUP_INTR_EXT_CTL_W0_SUP_INTR_EXT_CTL_31_0_MASK 0x00000001 +#define SUP_INTR_EXT_CTL_W1_SUP_INTR_EXT_CTL_63_32_MASK 0x00000001 + +/* ############################################################################ + * # SupMiscInfo0 Definition + */ +#define SUP_MISC_INFO0_W0_SUP_MISC_INFO0 BIT(0) + +#define SUP_MISC_INFO0_W0_SUP_MISC_INFO0_MASK 0xffffffff + +/* ############################################################################ + * # SupMiscInfo1 Definition + */ +#define SUP_MISC_INFO1_W0_SUP_MISC_INFO1 BIT(0) + +#define SUP_MISC_INFO1_W0_SUP_MISC_INFO1_MASK 0xffffffff + +/* ############################################################################ + * # SupMiscInfo2 Definition + */ +#define SUP_MISC_INFO2_W0_SUP_MISC_INFO2 BIT(0) + +#define SUP_MISC_INFO2_W0_SUP_MISC_INFO2_MASK 0xffffffff + +/* ############################################################################ + * # SupMiscInfo3 Definition + */ +#define SUP_MISC_INFO3_W0_SUP_MISC_INFO3 BIT(0) + +#define SUP_MISC_INFO3_W0_SUP_MISC_INFO3_MASK 0xffffffff + +struct SysCtl_mems { + u32 SysApbMem0[3]; /* 0x0000fe00 */ + u32 SysApbMem0_rsv3; + u32 SysApbMem1[3]; /* 0x0000fe10 */ + u32 SysApbMem1_rsv3; + u32 SysApbMem2[3]; /* 0x0000fe20 */ + u32 SysApbMem2_rsv3; + u32 SysApbMem3[3]; /* 0x0000fe30 */ + u32 SysApbMem3_rsv3; + u32 SysApbMem4[3]; /* 0x0000fe40 */ + u32 SysApbMem4_rsv3; + u32 SysApbMem5[3]; /* 0x0000fe50 */ + u32 SysApbMem5_rsv3; + u32 SysApbMem6[3]; /* 0x0000fe60 */ + u32 SysApbMem6_rsv3; + u32 SysApbMem7[3]; /* 0x0000fe70 */ + u32 SysApbMem7_rsv3; + u32 SysApbMem8[3]; /* 0x0000fe80 */ + u32 SysApbMem8_rsv3; + u32 SysApbMem9[3]; /* 0x0000fe90 */ + u32 SysApbMem9_rsv3; + u32 SysApbMem10[3]; /* 0x0000fea0 */ + u32 SysApbMem10_rsv3; + u32 SysApbMem11[3]; /* 0x0000feb0 */ + u32 SysApbMem11_rsv3; + u32 SysApbMem12[3]; /* 0x0000fec0 */ + u32 SysApbMem12_rsv3; + u32 SysApbMem13[3]; /* 0x0000fed0 */ + u32 SysApbMem13_rsv3; + u32 SysApbMem14[3]; /* 0x0000fee0 */ + u32 SysApbMem14_rsv3; + u32 SysApbMem15[3]; /* 0x0000fef0 */ + u32 SysApbMem15_rsv3; + u32 SecApbMem0[3]; /* 0x0000ff00 */ + u32 SecApbMem0_rsv3; + u32 SecApbMem1[3]; /* 0x0000ff10 */ + u32 SecApbMem1_rsv3; + u32 SecApbMem2[3]; /* 0x0000ff20 */ + u32 SecApbMem2_rsv3; + u32 SecApbMem3[3]; /* 0x0000ff30 */ + u32 SecApbMem3_rsv3; + u32 SecApbMem4[3]; /* 0x0000ff40 */ + u32 SecApbMem4_rsv3; + u32 SecApbMem5[3]; /* 0x0000ff50 */ + u32 SecApbMem5_rsv3; + u32 SecApbMem6[3]; /* 0x0000ff60 */ + u32 SecApbMem6_rsv3; + u32 SecApbMem7[3]; /* 0x0000ff70 */ + u32 SecApbMem7_rsv3; + u32 SecApbMem8[3]; /* 0x0000ff80 */ + u32 SecApbMem8_rsv3; + u32 SecApbMem9[3]; /* 0x0000ff90 */ + u32 SecApbMem9_rsv3; + u32 SecApbMem10[3]; /* 0x0000ffa0 */ + u32 SecApbMem10_rsv3; + u32 SecApbMem11[3]; /* 0x0000ffb0 */ + u32 SecApbMem11_rsv3; + u32 SecApbMem12[3]; /* 0x0000ffc0 */ + u32 SecApbMem12_rsv3; + u32 SecApbMem13[3]; /* 0x0000ffd0 */ + u32 SecApbMem13_rsv3; + u32 SecApbMem14[3]; /* 0x0000ffe0 */ + u32 SecApbMem14_rsv3; + u32 SecApbMem15[3]; /* 0x0000fff0 */ + u32 SecApbMem15_rsv3; +}; + +/* ############################################################################ + * # SysApbMem Definition + */ +#define SYS_APB_MEM_W0_ADDR BIT(0) +#define SYS_APB_MEM_W1_DATA BIT(0) +#define SYS_APB_MEM_W2_WR_EN BIT(0) +#define SYS_APB_MEM_W2_SLV_ERR BIT(1) + +#define SYS_APB_MEM_W0_ADDR_MASK 0xffffffff +#define SYS_APB_MEM_W1_DATA_MASK 0xffffffff +#define SYS_APB_MEM_W2_WR_EN_MASK 0x00000001 +#define SYS_APB_MEM_W2_SLV_ERR_MASK 0x00000002 + +/* ############################################################################ + * # SecApbMem Definition + */ +#define SEC_APB_MEM_W0_ADDR BIT(0) +#define SEC_APB_MEM_W1_DATA BIT(0) +#define SEC_APB_MEM_W2_WR_EN BIT(0) +#define SEC_APB_MEM_W2_SLV_ERR BIT(1) + +#define SEC_APB_MEM_W0_ADDR_MASK 0xffffffff +#define SEC_APB_MEM_W1_DATA_MASK 0xffffffff +#define SEC_APB_MEM_W2_WR_EN_MASK 0x00000001 +#define SEC_APB_MEM_W2_SLV_ERR_MASK 0x00000002 + +/* Bootmode setting values */ +#define ROM_QSPI_MODE 0x00000000 +#define ROM_EMMC_MODE 0x00000001 +#define ROM_SD_MODE 0x00000002 +#define ROM_UART_MODE 0x00000003 +#define NON_ROM_MODE 0x00000004 +#define JTAG_MODE 0x00000005 +#define ROM_QSPI_DEBUG_MODE 0x00000007 + +#define BOOT_MODES_MASK 0x00000007 + +#define sysctl_base ((struct SysCtl_regs *)CONFIG_SYS_CTC5236_SYSCTL_BASE) +#endif + +#endif /*__CTC5236_SYSCTL_H__*/ diff --git a/platform/centec-arm64/tsingma-bsp/src/pinctrl-ctc/Makefile b/platform/centec-arm64/tsingma-bsp/src/pinctrl-ctc/Makefile new file mode 100644 index 000000000000..b6d77c0e6cac --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/pinctrl-ctc/Makefile @@ -0,0 +1 @@ +obj-m = pinctrl-ctc.o diff --git a/platform/centec-arm64/tsingma-bsp/src/pinctrl-ctc/core.h b/platform/centec-arm64/tsingma-bsp/src/pinctrl-ctc/core.h new file mode 100644 index 000000000000..4a0526e567df --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/pinctrl-ctc/core.h @@ -0,0 +1,254 @@ +/* + * Core private header for the pin control subsystem + * + * Copyright (C) 2011 ST-Ericsson SA + * Written on behalf of Linaro for ST-Ericsson + * + * Author: Linus Walleij + * + * License terms: GNU General Public License (GPL) version 2 + */ + +#include +#include +#include +#include +#include + +struct pinctrl_gpio_range; + +/** + * struct pinctrl_dev - pin control class device + * @node: node to include this pin controller in the global pin controller list + * @desc: the pin controller descriptor supplied when initializing this pin + * controller + * @pin_desc_tree: each pin descriptor for this pin controller is stored in + * this radix tree + * @pin_group_tree: optionally each pin group can be stored in this radix tree + * @num_groups: optionally number of groups can be kept here + * @pin_function_tree: optionally each function can be stored in this radix tree + * @num_functions: optionally number of functions can be kept here + * @gpio_ranges: a list of GPIO ranges that is handled by this pin controller, + * ranges are added to this list at runtime + * @dev: the device entry for this pin controller + * @owner: module providing the pin controller, used for refcounting + * @driver_data: driver data for drivers registering to the pin controller + * subsystem + * @p: result of pinctrl_get() for this device + * @hog_default: default state for pins hogged by this device + * @hog_sleep: sleep state for pins hogged by this device + * @mutex: mutex taken on each pin controller specific action + * @device_root: debugfs root for this device + */ +struct pinctrl_dev { + struct list_head node; + struct pinctrl_desc *desc; + struct radix_tree_root pin_desc_tree; +#ifdef CONFIG_GENERIC_PINCTRL_GROUPS + struct radix_tree_root pin_group_tree; + unsigned int num_groups; +#endif +#ifdef CONFIG_GENERIC_PINMUX_FUNCTIONS + struct radix_tree_root pin_function_tree; + unsigned int num_functions; +#endif + struct list_head gpio_ranges; + struct device *dev; + struct module *owner; + void *driver_data; + struct pinctrl *p; + struct pinctrl_state *hog_default; + struct pinctrl_state *hog_sleep; + struct mutex mutex; +#ifdef CONFIG_DEBUG_FS + struct dentry *device_root; +#endif +}; + +/** + * struct pinctrl - per-device pin control state holder + * @node: global list node + * @dev: the device using this pin control handle + * @states: a list of states for this device + * @state: the current state + * @dt_maps: the mapping table chunks dynamically parsed from device tree for + * this device, if any + * @users: reference count + */ +struct pinctrl { + struct list_head node; + struct device *dev; + struct list_head states; + struct pinctrl_state *state; + struct list_head dt_maps; + struct kref users; +}; + +/** + * struct pinctrl_state - a pinctrl state for a device + * @node: list node for struct pinctrl's @states field + * @name: the name of this state + * @settings: a list of settings for this state + */ +struct pinctrl_state { + struct list_head node; + const char *name; + struct list_head settings; +}; + +/** + * struct pinctrl_setting_mux - setting data for MAP_TYPE_MUX_GROUP + * @group: the group selector to program + * @func: the function selector to program + */ +struct pinctrl_setting_mux { + unsigned group; + unsigned func; +}; + +/** + * struct pinctrl_setting_configs - setting data for MAP_TYPE_CONFIGS_* + * @group_or_pin: the group selector or pin ID to program + * @configs: a pointer to an array of config parameters/values to program into + * hardware. Each individual pin controller defines the format and meaning + * of config parameters. + * @num_configs: the number of entries in array @configs + */ +struct pinctrl_setting_configs { + unsigned group_or_pin; + unsigned long *configs; + unsigned num_configs; +}; + +/** + * struct pinctrl_setting - an individual mux or config setting + * @node: list node for struct pinctrl_settings's @settings field + * @type: the type of setting + * @pctldev: pin control device handling to be programmed. Not used for + * PIN_MAP_TYPE_DUMMY_STATE. + * @dev_name: the name of the device using this state + * @data: Data specific to the setting type + */ +struct pinctrl_setting { + struct list_head node; + enum pinctrl_map_type type; + struct pinctrl_dev *pctldev; + const char *dev_name; + union { + struct pinctrl_setting_mux mux; + struct pinctrl_setting_configs configs; + } data; +}; + +/** + * struct pin_desc - pin descriptor for each physical pin in the arch + * @pctldev: corresponding pin control device + * @name: a name for the pin, e.g. the name of the pin/pad/finger on a + * datasheet or such + * @dynamic_name: if the name of this pin was dynamically allocated + * @drv_data: driver-defined per-pin data. pinctrl core does not touch this + * @mux_usecount: If zero, the pin is not claimed, and @owner should be NULL. + * If non-zero, this pin is claimed by @owner. This field is an integer + * rather than a boolean, since pinctrl_get() might process multiple + * mapping table entries that refer to, and hence claim, the same group + * or pin, and each of these will increment the @usecount. + * @mux_owner: The name of device that called pinctrl_get(). + * @mux_setting: The most recent selected mux setting for this pin, if any. + * @gpio_owner: If pinctrl_gpio_request() was called for this pin, this is + * the name of the GPIO that "owns" this pin. + */ +struct pin_desc { + struct pinctrl_dev *pctldev; + const char *name; + bool dynamic_name; + void *drv_data; + /* These fields only added when supporting pinmux drivers */ +#ifdef CONFIG_PINMUX + unsigned mux_usecount; + const char *mux_owner; + const struct pinctrl_setting_mux *mux_setting; + const char *gpio_owner; +#endif +}; + +/** + * struct pinctrl_maps - a list item containing part of the mapping table + * @node: mapping table list node + * @maps: array of mapping table entries + * @num_maps: the number of entries in @maps + */ +struct pinctrl_maps { + struct list_head node; + const struct pinctrl_map *maps; + unsigned num_maps; +}; + +#ifdef CONFIG_GENERIC_PINCTRL_GROUPS + +/** + * struct group_desc - generic pin group descriptor + * @name: name of the pin group + * @pins: array of pins that belong to the group + * @num_pins: number of pins in the group + * @data: pin controller driver specific data + */ +struct group_desc { + const char *name; + int *pins; + int num_pins; + void *data; +}; + +int pinctrl_generic_get_group_count(struct pinctrl_dev *pctldev); + +const char *pinctrl_generic_get_group_name(struct pinctrl_dev *pctldev, + unsigned int group_selector); + +int pinctrl_generic_get_group_pins(struct pinctrl_dev *pctldev, + unsigned int group_selector, + const unsigned int **pins, + unsigned int *npins); + +struct group_desc *pinctrl_generic_get_group(struct pinctrl_dev *pctldev, + unsigned int group_selector); + +int pinctrl_generic_add_group(struct pinctrl_dev *pctldev, const char *name, + int *gpins, int ngpins, void *data); + +int pinctrl_generic_remove_group(struct pinctrl_dev *pctldev, + unsigned int group_selector); + +#endif /* CONFIG_GENERIC_PINCTRL_GROUPS */ + +struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *dev_name); +struct pinctrl_dev *get_pinctrl_dev_from_of_node(struct device_node *np); +int pin_get_from_name(struct pinctrl_dev *pctldev, const char *name); +const char *pin_get_name(struct pinctrl_dev *pctldev, const unsigned pin); +int pinctrl_get_group_selector(struct pinctrl_dev *pctldev, + const char *pin_group); + +static inline struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, + unsigned int pin) +{ + return radix_tree_lookup(&pctldev->pin_desc_tree, pin); +} + +extern struct pinctrl_gpio_range * +pinctrl_find_gpio_range_from_pin_nolock(struct pinctrl_dev *pctldev, + unsigned int pin); + +int pinctrl_register_map(const struct pinctrl_map *maps, unsigned num_maps, + bool dup); +void pinctrl_unregister_map(const struct pinctrl_map *map); + +extern int pinctrl_force_sleep(struct pinctrl_dev *pctldev); +extern int pinctrl_force_default(struct pinctrl_dev *pctldev); + +extern struct mutex pinctrl_maps_mutex; +extern struct list_head pinctrl_maps; + +#define for_each_maps(_maps_node_, _i_, _map_) \ + list_for_each_entry(_maps_node_, &pinctrl_maps, node) \ + for (_i_ = 0, _map_ = &_maps_node_->maps[_i_]; \ + _i_ < _maps_node_->num_maps; \ + _i_++, _map_ = &_maps_node_->maps[_i_]) diff --git a/platform/centec-arm64/tsingma-bsp/src/pinctrl-ctc/pinconf.h b/platform/centec-arm64/tsingma-bsp/src/pinctrl-ctc/pinconf.h new file mode 100644 index 000000000000..6c722505f893 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/pinctrl-ctc/pinconf.h @@ -0,0 +1,132 @@ +/* + * Internal interface between the core pin control system and the + * pin config portions + * + * Copyright (C) 2011 ST-Ericsson SA + * Written on behalf of Linaro for ST-Ericsson + * Based on bits of regulator core, gpio core and clk core + * + * Author: Linus Walleij + * + * License terms: GNU General Public License (GPL) version 2 + */ + +#ifdef CONFIG_PINCONF + +int pinconf_check_ops(struct pinctrl_dev *pctldev); +int pinconf_validate_map(const struct pinctrl_map *map, int i); +int pinconf_map_to_setting(const struct pinctrl_map *map, + struct pinctrl_setting *setting); +void pinconf_free_setting(const struct pinctrl_setting *setting); +int pinconf_apply_setting(const struct pinctrl_setting *setting); + +int pinconf_set_config(struct pinctrl_dev *pctldev, unsigned pin, + unsigned long *configs, size_t nconfigs); + +/* + * You will only be interested in these if you're using PINCONF + * so don't supply any stubs for these. + */ +int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin, + unsigned long *config); +int pin_config_group_get(const char *dev_name, const char *pin_group, + unsigned long *config); + +#else + +static inline int pinconf_check_ops(struct pinctrl_dev *pctldev) +{ + return 0; +} + +static inline int pinconf_validate_map(const struct pinctrl_map *map, int i) +{ + return 0; +} + +static inline int pinconf_map_to_setting(const struct pinctrl_map *map, + struct pinctrl_setting *setting) +{ + return 0; +} + +static inline void pinconf_free_setting(const struct pinctrl_setting *setting) +{ +} + +static inline int pinconf_apply_setting(const struct pinctrl_setting *setting) +{ + return 0; +} + +static inline int pinconf_set_config(struct pinctrl_dev *pctldev, unsigned pin, + unsigned long *configs, size_t nconfigs) +{ + return -ENOTSUPP; +} + +#endif + +#if defined(CONFIG_PINCONF) && defined(CONFIG_DEBUG_FS) + +void pinconf_show_map(struct seq_file *s, const struct pinctrl_map *map); +void pinconf_show_setting(struct seq_file *s, + const struct pinctrl_setting *setting); +void pinconf_init_device_debugfs(struct dentry *devroot, + struct pinctrl_dev *pctldev); + +#else + +static inline void pinconf_show_map(struct seq_file *s, + const struct pinctrl_map *map) +{ +} + +static inline void pinconf_show_setting(struct seq_file *s, + const struct pinctrl_setting *setting) +{ +} + +static inline void pinconf_init_device_debugfs(struct dentry *devroot, + struct pinctrl_dev *pctldev) +{ +} + +#endif + +/* + * The following functions are available if the driver uses the generic + * pin config. + */ + +#if defined(CONFIG_GENERIC_PINCONF) && defined(CONFIG_DEBUG_FS) + +void pinconf_generic_dump_pins(struct pinctrl_dev *pctldev, + struct seq_file *s, const char *gname, + unsigned pin); + +void pinconf_generic_dump_config(struct pinctrl_dev *pctldev, + struct seq_file *s, unsigned long config); +#else + +static inline void pinconf_generic_dump_pins(struct pinctrl_dev *pctldev, + struct seq_file *s, + const char *gname, unsigned pin) +{ + return; +} + +static inline void pinconf_generic_dump_config(struct pinctrl_dev *pctldev, + struct seq_file *s, + unsigned long config) +{ + return; +} +#endif + +#if defined(CONFIG_GENERIC_PINCONF) && defined(CONFIG_OF) +int pinconf_generic_parse_dt_config(struct device_node *np, + struct pinctrl_dev *pctldev, + unsigned long **configs, + unsigned int *nconfigs); +#endif diff --git a/platform/centec-arm64/tsingma-bsp/src/pinctrl-ctc/pinctrl-ctc.c b/platform/centec-arm64/tsingma-bsp/src/pinctrl-ctc/pinctrl-ctc.c new file mode 100644 index 000000000000..50c65dbfd786 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/pinctrl-ctc/pinctrl-ctc.c @@ -0,0 +1,537 @@ +/* + * Copyright (c) 2018 Liuht + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../include/sysctl.h" +#include "pinctrl-ctc.h" +#include "core.h" +#include "pinconf.h" + +#define CTC_PIN_BANK_NUM 2 + +struct ctc_pin_bank { + u32 pin_base; + u8 nr_pins; + char *name; +}; + +struct ctc_pin_ctrl { + struct ctc_pin_bank *pin_banks; + u32 nr_banks; + u32 nr_pins; + char *label; +}; + +struct ctc_pin_config { + unsigned int func; + unsigned long *configs; + unsigned int nconfigs; +}; + +struct ctc_pin_group { + const char *name; + unsigned int npins; + unsigned int *pins; + struct ctc_pin_config *data; +}; + +struct ctc_pmx_func { + const char *name; + const char **groups; + u8 ngroups; +}; + +struct ctc_pinctrl { + struct regmap *regmap_base; + struct device *dev; + struct pinctrl_desc pctl; + struct pinctrl_dev *pctl_dev; + struct ctc_pin_ctrl *ctrl; + struct ctc_pin_group *groups; + unsigned int ngroups; + struct ctc_pmx_func *functions; + unsigned int nfunctions; +}; + +static void ctc_pinctrl_child_count(struct ctc_pinctrl *info, + struct device_node *np) +{ + struct device_node *child; + + for_each_child_of_node(np, child) { + info->nfunctions++; + info->ngroups += of_get_child_count(child); + } +} + +static struct ctc_pin_bank *ctc_bank_num_to_bank(struct ctc_pinctrl *info, + unsigned int num) +{ + struct ctc_pin_bank *b = info->ctrl->pin_banks; + + if (num < info->ctrl->nr_banks) + return &b[num]; + + return ERR_PTR(-EINVAL); +} + +static int ctc_pinctrl_parse_groups(struct device_node *np, + struct ctc_pin_group *grp, + struct ctc_pinctrl *info, u32 index) +{ + struct ctc_pin_bank *bank; + int size; + const __be32 *list; + int num; + int i, j; + + dev_dbg(info->dev, "group(%d): %s\n", index, np->name); + + /* Initialise group */ + grp->name = np->name; + + /* + * the binding format is ctc,pins = , + * do sanity check and calculate pins number + */ + list = of_get_property(np, "ctc,pins", &size); + /* we do not check return since it's safe node passed down */ + size /= sizeof(*list); + if (!size || size % 3) { + dev_err(info->dev, + "wrong pins number or pins and configs should be by 4\n"); + return -EINVAL; + } + + grp->npins = size / 3; + + grp->pins = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int), + GFP_KERNEL); + grp->data = devm_kzalloc(info->dev, grp->npins * + sizeof(struct ctc_pin_config), GFP_KERNEL); + if (!grp->pins || !grp->data) + return -ENOMEM; + + for (i = 0, j = 0; i < size; i += 3, j++) { + num = be32_to_cpu(*list++); + bank = ctc_bank_num_to_bank(info, num); + if (IS_ERR(bank)) + return PTR_ERR(bank); + + grp->pins[j] = bank->pin_base + be32_to_cpu(*list++); + grp->data[j].func = be32_to_cpu(*list++); + } + + return 0; +} + +static int ctc_pinctrl_parse_functions(struct device_node *np, + struct ctc_pinctrl *info, u32 index) +{ + struct device_node *child; + struct ctc_pmx_func *func; + struct ctc_pin_group *grp; + int ret; + static u32 grp_index; + u32 i = 0; + + dev_dbg(info->dev, "parse function(%d): %s\n", index, np->name); + + func = &info->functions[index]; + + /* Initialise function */ + func->name = np->name; + func->ngroups = of_get_child_count(np); + if (func->ngroups <= 0) + return 0; + + func->groups = devm_kzalloc(info->dev, + func->ngroups * sizeof(char *), GFP_KERNEL); + if (!func->groups) + return -ENOMEM; + + for_each_child_of_node(np, child) { + func->groups[i] = child->name; + grp = &info->groups[grp_index++]; + ret = ctc_pinctrl_parse_groups(child, grp, info, i++); + if (ret) { + of_node_put(child); + return ret; + } + } + + return 0; +} + +static int ctc_pinctrl_parse_dt(struct platform_device *pdev, + struct ctc_pinctrl *info) +{ + int ret, i; + u32 bank0_pins, bank1_pins; + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct device_node *child; + + info->ctrl = devm_kzalloc(dev, sizeof(struct ctc_pin_ctrl), GFP_KERNEL); + if (!info->ctrl) + return -EINVAL; + + ret = of_property_read_u32(np, "ctc,pinctrl-bank0", &bank0_pins); + if (ret < 0) { + dev_err(dev, "failed to get bank0 pin information\n"); + return -EINVAL; + } + ret = of_property_read_u32(np, "ctc,pinctrl-bank1", &bank1_pins); + if (ret < 0) { + dev_err(dev, "failed to get bank1 pin information\n"); + return -EINVAL; + } + info->ctrl->pin_banks = + devm_kzalloc(dev, sizeof(struct ctc_pin_bank) * CTC_PIN_BANK_NUM, + GFP_KERNEL); + if (!info->ctrl->pin_banks) { + dev_err(dev, "failed to allocate memory for pin banks\n"); + return -EINVAL; + } + info->ctrl->nr_banks = CTC_PIN_BANK_NUM; + info->ctrl->nr_pins = bank0_pins + bank1_pins; + info->ctrl->pin_banks[0].pin_base = 0; + info->ctrl->pin_banks[0].nr_pins = bank0_pins; + info->ctrl->pin_banks[1].pin_base = bank0_pins + 1; + info->ctrl->pin_banks[1].nr_pins = bank1_pins; + + ctc_pinctrl_child_count(info, np); + + dev_dbg(&pdev->dev, "nfunctions = %d\n", info->nfunctions); + dev_dbg(&pdev->dev, "ngroups = %d\n", info->ngroups); + + info->functions = devm_kzalloc(dev, info->nfunctions * + sizeof(struct ctc_pmx_func), GFP_KERNEL); + if (!info->functions) + return -EINVAL; + + info->groups = devm_kzalloc(dev, info->ngroups * + sizeof(struct ctc_pin_group), GFP_KERNEL); + if (!info->groups) + return -EINVAL; + + i = 0; + for_each_child_of_node(np, child) { + ret = ctc_pinctrl_parse_functions(child, info, i++); + if (ret) { + dev_err(&pdev->dev, "failed to parse function\n"); + of_node_put(child); + return ret; + } + } + + return 0; +} + +static int ctc_get_groups_count(struct pinctrl_dev *pctldev) +{ + struct ctc_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + + return info->ngroups; +} + +static const char *ctc_get_group_name(struct pinctrl_dev *pctldev, + unsigned int selector) +{ + struct ctc_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + + return info->groups[selector].name; +} + +static int ctc_get_group_pins(struct pinctrl_dev *pctldev, + unsigned int selector, const unsigned int **pins, + unsigned int *npins) +{ + struct ctc_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + + if (selector >= info->ngroups) + return -EINVAL; + + *pins = info->groups[selector].pins; + *npins = info->groups[selector].npins; + + return 0; +} + +static inline const struct ctc_pin_group *ctc_pinctrl_name_to_group(const struct + ctc_pinctrl + *info, + const char + *name) +{ + int i; + + for (i = 0; i < info->ngroups; i++) { + if (!strcmp(info->groups[i].name, name)) + return &info->groups[i]; + } + + return NULL; +} + +static int ctc_dt_node_to_map(struct pinctrl_dev *pctldev, + struct device_node *np, + struct pinctrl_map **map, unsigned int *num_maps) +{ + struct ctc_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + const struct ctc_pin_group *grp; + struct pinctrl_map *new_map; + struct device_node *parent; + int map_num; + + /* + * first find the group of this node and check if we need to create + * config maps for pins + */ + grp = ctc_pinctrl_name_to_group(info, np->name); + if (!grp) { + dev_err(info->dev, "unable to find group for node %s\n", + np->name); + return -EINVAL; + } + + map_num = 1; + new_map = devm_kzalloc(pctldev->dev, sizeof(*new_map) * map_num, + GFP_KERNEL); + if (!new_map) + return -ENOMEM; + + *map = new_map; + *num_maps = map_num; + + /* create mux map */ + parent = of_get_parent(np); + if (!parent) { + devm_kfree(pctldev->dev, new_map); + return -EINVAL; + } + new_map[0].type = PIN_MAP_TYPE_MUX_GROUP; + new_map[0].data.mux.function = parent->name; + new_map[0].data.mux.group = np->name; + of_node_put(parent); + + return 0; +} + +static int ctc_pmx_get_funcs_count(struct pinctrl_dev *pctldev) +{ + struct ctc_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + + return info->nfunctions; +} + +static const char *ctc_pmx_get_func_name(struct pinctrl_dev *pctldev, + unsigned int selector) +{ + struct ctc_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + + return info->functions[selector].name; +} + +static int ctc_pmx_get_groups(struct pinctrl_dev *pctldev, + unsigned int selector, const char *const **groups, + unsigned int *const num_groups) +{ + struct ctc_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + + *groups = info->functions[selector].groups; + *num_groups = info->functions[selector].ngroups; + + return 0; +} + +static struct ctc_pin_bank *ctc_pin_to_bank(struct ctc_pinctrl *info, + unsigned int pin) +{ + struct ctc_pin_bank *b = info->ctrl->pin_banks; + + while (pin >= (b->pin_base + b->nr_pins)) + b++; + + return b; +} + +static int ctc_set_pin_mux(struct ctc_pinctrl *info, struct ctc_pin_bank *bank, + int pin, int mux) +{ + + if (!bank->pin_base) { + regmap_update_bits(info->regmap_base, + offsetof(struct SysCtl_regs, + SysGpioMultiCtl), 3 << pin * 2, + mux << pin * 2); + } else { + regmap_update_bits(info->regmap_base, + offsetof(struct SysCtl_regs, + SysGpioHsMultiCtl), 3 << pin * 2, + mux << pin * 2); + } + return 0; +} + +static int ctc_pmx_set(struct pinctrl_dev *pctldev, unsigned int selector, + unsigned int group) +{ + struct ctc_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + const unsigned int *pins = info->groups[group].pins; + const struct ctc_pin_config *data = info->groups[group].data; + struct ctc_pin_bank *bank; + int cnt, ret = 0; + + dev_dbg(info->dev, "enable function %s group %s\n", + info->functions[selector].name, info->groups[group].name); + + /* for each pin in the pin group selected, program the corresponding pin + * pin function number in the config register. + */ + for (cnt = 0; cnt < info->groups[group].npins; cnt++) { + bank = ctc_pin_to_bank(info, pins[cnt]); + ret = ctc_set_pin_mux(info, bank, pins[cnt] - bank->pin_base, + data[cnt].func); + if (ret) + break; + } + + return 0; +} + +static void ctc_dt_free_map(struct pinctrl_dev *pctldev, + struct pinctrl_map *map, unsigned int num_maps) +{ +} + +static const struct pinctrl_ops ctc_pctrl_ops = { + .get_groups_count = ctc_get_groups_count, + .get_group_name = ctc_get_group_name, + .get_group_pins = ctc_get_group_pins, + .dt_node_to_map = ctc_dt_node_to_map, + .dt_free_map = ctc_dt_free_map, +}; + +static const struct pinmux_ops ctc_pmx_ops = { + .get_functions_count = ctc_pmx_get_funcs_count, + .get_function_name = ctc_pmx_get_func_name, + .get_function_groups = ctc_pmx_get_groups, + .set_mux = ctc_pmx_set, +}; + +static int ctc_pinctrl_register(struct platform_device *pdev, + struct ctc_pinctrl *info) +{ + struct pinctrl_desc *ctrldesc = &info->pctl; + struct pinctrl_pin_desc *pindesc, *pdesc; + struct ctc_pin_bank *pin_bank; + int pin, bank, ret; + int k; + + ret = ctc_pinctrl_parse_dt(pdev, info); + if (ret) + return ret; + + ctrldesc->name = "ctc-pinctrl"; + ctrldesc->owner = THIS_MODULE; + ctrldesc->pctlops = &ctc_pctrl_ops; + ctrldesc->pmxops = &ctc_pmx_ops; + ctrldesc->confops = NULL; + + pindesc = + devm_kzalloc(&pdev->dev, sizeof(*pindesc) * info->ctrl->nr_pins, + GFP_KERNEL); + if (!pindesc) { + dev_err(&pdev->dev, "mem alloc for pin descriptors failed\n"); + return -ENOMEM; + } + ctrldesc->pins = pindesc; + ctrldesc->npins = info->ctrl->nr_pins; + + pdesc = pindesc; + for (bank = 0, k = 0; bank < info->ctrl->nr_banks; bank++) { + pin_bank = &info->ctrl->pin_banks[bank]; + for (pin = 0; pin < pin_bank->nr_pins; pin++, k++) { + pdesc->number = k; + pdesc->name = kasprintf(GFP_KERNEL, "gpio%d-%d", + bank, pin); + pdesc++; + } + } + + info->pctl_dev = devm_pinctrl_register(&pdev->dev, ctrldesc, info); + if (IS_ERR(info->pctl_dev)) { + dev_err(&pdev->dev, "could not register pinctrl driver\n"); + return PTR_ERR(info->pctl_dev); + } + + return 0; +} + +static int ctc_pinctrl_probe(struct platform_device *pdev) +{ + struct ctc_pinctrl *info; + struct device *dev = &pdev->dev; + + info = devm_kzalloc(dev, sizeof(struct ctc_pinctrl), GFP_KERNEL); + if (!info) + return -ENOMEM; + + info->dev = dev; + info->regmap_base = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, + "ctc,sysctrl"); + if (IS_ERR(info->regmap_base)) + return PTR_ERR(info->regmap_base); + + ctc_pinctrl_register(pdev, info); + + platform_set_drvdata(pdev, info); + + return 0; +} + +static const struct of_device_id ctc_pinctrl_dt_match[] = { + {.compatible = "ctc,ctc5236-pinctrl"}, + {}, +}; + +static struct platform_driver ctc_pinctrl_driver = { + .probe = ctc_pinctrl_probe, + .driver = { + .name = "ctc-pinctrl", + .of_match_table = ctc_pinctrl_dt_match, + }, +}; + +//static int __init ctc_pinctrl_drv_register(void) +//{ +// return platform_driver_register(&ctc_pinctrl_driver); +//} +// +//postcore_initcall(ctc_pinctrl_drv_register); + +module_platform_driver(ctc_pinctrl_driver); +MODULE_LICENSE("GPL"); diff --git a/platform/centec-arm64/tsingma-bsp/src/pinctrl-ctc/pinctrl-ctc.h b/platform/centec-arm64/tsingma-bsp/src/pinctrl-ctc/pinctrl-ctc.h new file mode 100644 index 000000000000..91188a84d9df --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/pinctrl-ctc/pinctrl-ctc.h @@ -0,0 +1,24 @@ +/* + * Header providing constants for centec pinctrl. + * + * Copyright (c) 2018 Liuht + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __PINCTRL_CTC_H__ +#define __PINCTRL_CTC_H__ + +#define PIN_FUNC_SPI 1 +#define PIN_FUNC_PWM 2 +#define PIN_FUNC_UART 1 +#define PIN_FUNC_FC 1 +#endif diff --git a/platform/centec-arm64/tsingma-bsp/src/pwm-ctc/Makefile b/platform/centec-arm64/tsingma-bsp/src/pwm-ctc/Makefile new file mode 100644 index 000000000000..4d187265224f --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/pwm-ctc/Makefile @@ -0,0 +1 @@ +obj-m = pwm-ctc.o diff --git a/platform/centec-arm64/tsingma-bsp/src/pwm-ctc/pwm-ctc.c b/platform/centec-arm64/tsingma-bsp/src/pwm-ctc/pwm-ctc.c new file mode 100644 index 000000000000..8b2a031a46fa --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/pwm-ctc/pwm-ctc.c @@ -0,0 +1,247 @@ +/* Centec PWM driver + * + * Author: wangyb + * + * Copyright 2005-2018, Centec Networks (Suzhou) Co., Ltd. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../pinctrl-ctc/pinctrl-ctc.h" +#include "../pinctrl-ctc/core.h" +#include "../include/sysctl.h" +#include +#include +#include + +#define CTC_NUM_PWM 4 +#define CTC_CR_PWM 0x0 +#define CTC_DUTY_PWM 0x4 + +#define CTC_MAX_PERIOD_PWM 0xFFFFFF +#define CTC_MAX_DUTY_PWM 0xFFFFFF + +#define CTC_PWM_ENABLE 0x80000000 + +#define CTC_PERIOD_TACH 0x0 +#define CTC_DUTY_TACH 0x4 + +struct ctc_pwm_chip { + void __iomem *base; + struct regmap *regmap_base; + struct pwm_chip chip; +}; + +static inline struct ctc_pwm_chip *to_ctc_pwm_chip(struct pwm_chip *chip) +{ + return container_of(chip, struct ctc_pwm_chip, chip); +} + +static inline void ctc_pwm_writel(struct ctc_pwm_chip *chip, unsigned int num, + unsigned long offset, unsigned long val) +{ + regmap_write(chip->regmap_base, + offsetof(struct SysCtl_regs, + SysPwmCtl) + offset + num * 0x8, val); +} + +static inline u32 ctc_pwm_readl(struct ctc_pwm_chip *chip, unsigned int num, + unsigned long offset) +{ + u32 val; + + regmap_read(chip->regmap_base, + offsetof(struct SysCtl_regs, + SysPwmCtl) + offset + num * 0x8, &val); + return val; +} + +static inline u32 ctc_tach_readl(struct ctc_pwm_chip *chip, unsigned int num, + unsigned long offset) +{ + u32 val; + + regmap_read(chip->regmap_base, + offsetof(struct SysCtl_regs, + SysTachLog) + offset + num * 0x8, &val); + return val; +} + +static int ctc_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, + int duty_ns, int period_ns) +{ + struct ctc_pwm_chip *pc = to_ctc_pwm_chip(chip); + u32 cur_value; + + duty_ns = duty_ns / 1000; + period_ns = period_ns / 1000; + + /* duty cycle */ + duty_ns = duty_ns & CTC_MAX_DUTY_PWM; + ctc_pwm_writel(pc, pwm->hwpwm, CTC_DUTY_PWM, duty_ns); + + /* period cycle */ + period_ns = period_ns & CTC_MAX_PERIOD_PWM; + cur_value = ctc_pwm_readl(pc, pwm->hwpwm, CTC_CR_PWM); + cur_value &= ~(CTC_MAX_PERIOD_PWM); + cur_value |= period_ns << 0; + ctc_pwm_writel(pc, pwm->hwpwm, CTC_CR_PWM, cur_value); + + return 0; +} + +static int ctc_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) +{ + struct ctc_pwm_chip *pc = to_ctc_pwm_chip(chip); + u32 cur_value; + + cur_value = ctc_pwm_readl(pc, pwm->hwpwm, CTC_CR_PWM); + cur_value |= 1 << 31; + ctc_pwm_writel(pc, pwm->hwpwm, CTC_CR_PWM, cur_value); + return 0; +} + +static void ctc_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) +{ + struct ctc_pwm_chip *pc = to_ctc_pwm_chip(chip); + u32 cur_value; + + cur_value = ctc_pwm_readl(pc, pwm->hwpwm, CTC_CR_PWM); + cur_value &= ~(1 << 31); + + ctc_pwm_writel(pc, pwm->hwpwm, CTC_CR_PWM, cur_value); +} + +static void ctc_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, + struct pwm_state *state) +{ + struct ctc_pwm_chip *pc = to_ctc_pwm_chip(chip); + u32 cur_value; + u32 cur_value_2; + + cur_value = ctc_pwm_readl(pc, pwm->hwpwm, CTC_CR_PWM); + + if (cur_value & CTC_PWM_ENABLE) + state->enabled = true; + else + state->enabled = false; + + state->polarity = PWM_POLARITY_NORMAL; + + state->period = (cur_value & (~CTC_PWM_ENABLE)) * 1000; + + cur_value_2 = ctc_pwm_readl(pc, pwm->hwpwm, CTC_DUTY_PWM); + + state->duty_cycle = cur_value_2 * 1000; +} + +static int ctc_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm, + struct pwm_capture *result, unsigned long timeout) +{ + struct ctc_pwm_chip *pc = to_ctc_pwm_chip(chip); + u32 period_tach; + u32 duty_tach; + + period_tach = ctc_tach_readl(pc, pwm->hwpwm, CTC_PERIOD_TACH) / 4; + result->period = period_tach * 1000; + + duty_tach = ctc_tach_readl(pc, pwm->hwpwm, CTC_DUTY_TACH) / 4; + result->duty_cycle = duty_tach * 1000; + + return 0; +} + +static const struct pwm_ops ctc_pwm_ops = { + .config = ctc_pwm_config, + .enable = ctc_pwm_enable, + .disable = ctc_pwm_disable, + .get_state = ctc_pwm_get_state, + .capture = ctc_pwm_capture, + .owner = THIS_MODULE, +}; + +static int ctc_pwm_probe(struct platform_device *pdev) +{ + struct pinctrl_dev *pctldev; + struct ctc_pwm_chip *pc; + struct pinctrl_state *state; + + int ret; + int i; + u32 cur_value; + + pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); + if (!pc) + return -ENOMEM; + + pc->regmap_base = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, + "ctc,sysctrl"); + pctldev = devm_kzalloc(&pdev->dev, sizeof(*pctldev), GFP_KERNEL); + if (!pctldev) + return -1; + pctldev->p = pinctrl_get(&pdev->dev); + state = pinctrl_lookup_state(pctldev->p, PINCTRL_STATE_DEFAULT); + pinctrl_select_state(pctldev->p, state); + pr_info("Select PWM Function\n"); + + for (i = 0; i < CTC_NUM_PWM; i++) { + cur_value = ctc_pwm_readl(pc, i, CTC_CR_PWM); + cur_value |= 1 << 31; + ctc_pwm_writel(pc, i, CTC_CR_PWM, cur_value); + } + + platform_set_drvdata(pdev, pc); + pc->chip.dev = &pdev->dev; + pc->chip.ops = &ctc_pwm_ops; + pc->chip.base = -1; + pc->chip.npwm = CTC_NUM_PWM; + + ret = pwmchip_add(&pc->chip); + if (ret < 0) + return -1; + + return 0; +} + +static int ctc_pwm_remove(struct platform_device *pdev) +{ + struct ctc_pwm_chip *pc = platform_get_drvdata(pdev); + int i; + + for (i = 0; i < CTC_NUM_PWM; i++) + pwm_disable(&pc->chip.pwms[i]); + + return pwmchip_remove(&pc->chip); +} + +static const struct of_device_id ctc_pwm_of_match[] = { + {.compatible = "centec-pwm"}, + {} +}; + +MODULE_DEVICE_TABLE(of, ctc_pwm_of_match); + +static struct platform_driver ctc_pwm_driver = { + .driver = { + .name = "ctc-pwm", + .of_match_table = ctc_pwm_of_match, + }, + .probe = ctc_pwm_probe, + .remove = ctc_pwm_remove, +}; + +module_platform_driver(ctc_pwm_driver); + +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:centec-pwm"); diff --git a/platform/centec-arm64/tsingma-bsp/src/rtc-sd2405/Makefile b/platform/centec-arm64/tsingma-bsp/src/rtc-sd2405/Makefile new file mode 100644 index 000000000000..7e34f8c9367f --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/rtc-sd2405/Makefile @@ -0,0 +1 @@ +obj-m = rtc-sd2405.o diff --git a/platform/centec-arm64/tsingma-bsp/src/rtc-sd2405/rtc-sd2405.c b/platform/centec-arm64/tsingma-bsp/src/rtc-sd2405/rtc-sd2405.c new file mode 100644 index 000000000000..77c76353cd60 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/rtc-sd2405/rtc-sd2405.c @@ -0,0 +1,249 @@ +/* rtc class driver for the SD2405 chip + * + * Author: Dale Farnsworth + * + * based on previously existing rtc class drivers + * + * 2007 (c) MontaVista, Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ + +#include +#include +#include +#include +#include + +#define DRV_VERSION "0.1" + +/* + * register indices + */ +#define SD2405_REG_SC 0x0 /* seconds 00-59 */ +#define SD2405_REG_MN 0x1 /* minutes 00-59 */ +#define SD2405_REG_HR 0x2 /* hours 00-23 */ +#define SD2405_REG_DW 0x3 /* day of week 1-7 */ +#define SD2405_REG_DT 0x4 /* day of month 00-31 */ +#define SD2405_REG_MO 0x5 /* month 01-12 */ +#define SD2405_REG_YR 0x6 /* year 00-99 */ + +#define SD2405_REG_CTRL1 0xf /* control 1 */ +#define SD2405_REG_CTRL2 0x10 /* control 2 */ +#define SD2405_REG_CTRL3 0x11 /* control 3 ARST */ + +#define SD2405_REG_LEN 7 + +/* + * register write protect + */ +#define SD2405_REG_CONTROL1_WRITE 0x80 +#define SD2405_REG_CONTROL2_WRITE 0x84 + +#define SD2405_IDLE_TIME_AFTER_WRITE 3 /* specification says 2.5 mS */ + +static struct i2c_driver sd2405_driver; + +static int sd2405_i2c_read_regs(struct i2c_client *client, u8 *buf) +{ + struct i2c_msg msgs[1] = { + { + .addr = client->addr, + .flags = I2C_M_RD, /* read */ + .len = SD2405_REG_LEN, + .buf = buf} + }; + int rc; + + rc = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); + if (rc != ARRAY_SIZE(msgs)) { + dev_err(&client->dev, "%s: register read failed\n", __func__); + return -EIO; + } + return 0; +} + +static int sd2405_i2c_write_regs(struct i2c_client *client, u8 const *buf) +{ + int rc; + u8 temp_reg[SD2405_REG_LEN + 1] = { 0 }; + + struct i2c_msg msgs[1] = { + { + .addr = client->addr, + .flags = 0, /* write */ + .len = SD2405_REG_LEN + 1, + .buf = temp_reg} + }; + + memcpy(&temp_reg[1], buf, SD2405_REG_LEN); + + rc = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); + if (rc != ARRAY_SIZE(msgs)) + goto write_failed; + msleep(SD2405_IDLE_TIME_AFTER_WRITE); + + return 0; + +write_failed: + dev_err(&client->dev, "%s: register write failed\n", __func__); + return -EIO; +} + +static int sd2405_i2c_read_time(struct i2c_client *client, struct rtc_time *tm) +{ + int rc; + u8 regs[SD2405_REG_LEN]; + + rc = sd2405_i2c_read_regs(client, regs); + if (rc < 0) + return rc; + + tm->tm_sec = bcd2bin(regs[SD2405_REG_SC]); + tm->tm_min = bcd2bin(regs[SD2405_REG_MN]); + tm->tm_hour = bcd2bin(regs[SD2405_REG_HR] & 0x3f); + tm->tm_wday = bcd2bin(regs[SD2405_REG_DW]); + tm->tm_mday = bcd2bin(regs[SD2405_REG_DT]); + tm->tm_mon = bcd2bin(regs[SD2405_REG_MO]) - 1; + tm->tm_year = bcd2bin(regs[SD2405_REG_YR]) + 100; + + return 0; +} + +static int sd2405_i2c_set_write_protect(struct i2c_client *client) +{ + int rc; + + rc = i2c_smbus_write_byte_data(client, SD2405_REG_CTRL1, 0); + rc += i2c_smbus_write_byte_data(client, SD2405_REG_CTRL2, 0); + if (rc < 0) { + dev_err(&client->dev, "%s: control register write failed\n", + __func__); + return -EIO; + } + return 0; +} + +static int sd2405_i2c_clear_write_protect(struct i2c_client *client) +{ + int rc; + + rc = i2c_smbus_write_byte_data(client, SD2405_REG_CTRL2, + SD2405_REG_CONTROL1_WRITE); + rc += + i2c_smbus_write_byte_data(client, SD2405_REG_CTRL1, + SD2405_REG_CONTROL2_WRITE); + if (rc < 0) { + dev_err(&client->dev, "%s: control register write failed\n", + __func__); + return -EIO; + } + return 0; +} + +static int +sd2405_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm) +{ + u8 regs[SD2405_REG_LEN]; + int rc; + + rc = sd2405_i2c_clear_write_protect(client); + if (rc < 0) + return rc; + + regs[SD2405_REG_SC] = bin2bcd(tm->tm_sec); + regs[SD2405_REG_MN] = bin2bcd(tm->tm_min); + regs[SD2405_REG_HR] = bin2bcd(tm->tm_hour) | 0x80; + regs[SD2405_REG_DW] = bin2bcd(tm->tm_wday); + regs[SD2405_REG_DT] = bin2bcd(tm->tm_mday); + regs[SD2405_REG_MO] = bin2bcd(tm->tm_mon + 1); + regs[SD2405_REG_YR] = bin2bcd(tm->tm_year - 100); + + rc = sd2405_i2c_write_regs(client, regs); + if (rc < 0) + return rc; + + rc = sd2405_i2c_set_write_protect(client); + if (rc < 0) + return rc; + + return 0; +} + +static int sd2405_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + return sd2405_i2c_read_time(to_i2c_client(dev), tm); +} + +static int sd2405_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + return sd2405_i2c_set_time(to_i2c_client(dev), tm); +} + +static int sd2405_remove(struct i2c_client *client) +{ + struct rtc_device *rtc = i2c_get_clientdata(client); + + if (rtc) + rtc_device_unregister(rtc); + + return 0; +} + +static const struct rtc_class_ops sd2405_rtc_ops = { + .read_time = sd2405_rtc_read_time, + .set_time = sd2405_rtc_set_time, +}; + +static int +sd2405_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct rtc_device *rtc; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) + return -ENODEV; + + dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); + + rtc = rtc_device_register(sd2405_driver.driver.name, + &client->dev, &sd2405_rtc_ops, THIS_MODULE); + if (IS_ERR(rtc)) + return PTR_ERR(rtc); + + i2c_set_clientdata(client, rtc); + + return 0; +} + +static struct i2c_device_id sd2405_id[] = { + {"sd2405", 0}, + {} +}; + +static struct i2c_driver sd2405_driver = { + .driver = { + .name = "rtc-sd2405", + }, + .probe = sd2405_probe, + .remove = sd2405_remove, + .id_table = sd2405_id, +}; + +static int __init sd2405_init(void) +{ + return i2c_add_driver(&sd2405_driver); +} + +static void __exit sd2405_exit(void) +{ + i2c_del_driver(&sd2405_driver); +} + +MODULE_DESCRIPTION("Maxim SD2405 RTC driver"); +MODULE_AUTHOR("Dale Farnsworth "); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_VERSION); + +module_init(sd2405_init); +module_exit(sd2405_exit); diff --git a/platform/centec-arm64/tsingma-bsp/src/sdhci-ctc5236/Makefile b/platform/centec-arm64/tsingma-bsp/src/sdhci-ctc5236/Makefile new file mode 100644 index 000000000000..82c8485d0ee9 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/sdhci-ctc5236/Makefile @@ -0,0 +1 @@ +obj-m = sdhci-ctc5236.o diff --git a/platform/centec-arm64/tsingma-bsp/src/sdhci-ctc5236/sdhci-ctc5236.c b/platform/centec-arm64/tsingma-bsp/src/sdhci-ctc5236/sdhci-ctc5236.c new file mode 100644 index 000000000000..b9981e8b0c54 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/sdhci-ctc5236/sdhci-ctc5236.c @@ -0,0 +1,307 @@ +/* sdhci-ctc5236.c Support for SDHCI on Centec TsingMa SoC's + * + * Copyright (C) 2004-2017 Centec Networks (suzhou) Co., LTD. + * + * Author: Jay Cao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include "sdhci-pltfm.h" +#include "../pinctrl-ctc/pinctrl-ctc.h" +#include "../include/sysctl.h" +#include +#include +#include +#include +#include + +#define REG_OFFSET_ADDR 0x500 +#define MSHC_CTRL_R 0x8 +#define AT_CTRL_R 0x40 +#define SW_TUNE_EN 0x10 +#define SD_CLK_EN_MASK 0x00000001 +#define AT_STAT_R 0x44 +#define MAX_TUNING_LOOP 0x80 +#define MIN_TUNING_LOOP 0x0 +#define TUNE_CTRL_STEP 1 + +struct regmap *regmap_base; +#define SDHCI_REFCLK_150M 150000000 + +static u16 sdhci_ctc5236_readw(struct sdhci_host *host, int reg) +{ + if (unlikely(reg == SDHCI_HOST_VERSION)) + return SDHCI_SPEC_300; + + return readw(host->ioaddr + reg); +} + +static u32 sdhci_ctc5236_readl(struct sdhci_host *host, int reg) +{ + u32 ret = readl(host->ioaddr + reg); + + if (reg == SDHCI_CAPABILITIES_1) + ret &= + ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_SDR104 | + SDHCI_SUPPORT_DDR50); + if (reg == SDHCI_CAPABILITIES) + ret &= ~(SDHCI_CAN_64BIT); + + return ret; +} + +static void ctc5236_mmc_init_card(struct sdhci_host *host) +{ + int CLK_CTRL_R_value = 0x0; + int AT_CTRL_R_value = 0x0; + int MSHC_CTRL_R_value = 0x0; + + /* Disable command conflict check for 150M */ + sdhci_writel(host, MSHC_CTRL_R_value, REG_OFFSET_ADDR + MSHC_CTRL_R); + dev_dbg(mmc_dev(host->mmc), "MSHC_CTRL_R is %x\n", + sdhci_readl(host, REG_OFFSET_ADDR + MSHC_CTRL_R)); + + /* Disable auto-tuning function */ + CLK_CTRL_R_value = sdhci_readw(host, SDHCI_CLOCK_CONTROL); + CLK_CTRL_R_value &= (~SDHCI_CLOCK_CARD_EN); + sdhci_writew(host, CLK_CTRL_R_value, SDHCI_CLOCK_CONTROL); + AT_CTRL_R_value = sdhci_readl(host, REG_OFFSET_ADDR + AT_CTRL_R); + AT_CTRL_R_value &= (~SD_CLK_EN_MASK); + sdhci_writel(host, AT_CTRL_R_value, REG_OFFSET_ADDR + AT_CTRL_R); + dev_dbg(mmc_dev(host->mmc), "AT_CTRL_R is %x\n", + sdhci_readl(host, REG_OFFSET_ADDR + AT_CTRL_R)); +} + +void sdhci_ctc5236_reset(struct sdhci_host *host, u8 mask) +{ + unsigned long timeout; + + sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET); + + /* Wait max 100 ms */ + timeout = 100; + + /* hw clears the bit when it's done */ + while (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask) { + if (timeout == 0) { + pr_err("%s: Reset 0x%x never completed.\n", + mmc_hostname(host->mmc), (int)mask); + return; + } + timeout--; + mdelay(1); + } + + if (mask & SDHCI_RESET_ALL) { + host->clock = 0; + ctc5236_mmc_init_card(host); + } + +} + +void ctc_sdhci_set_clock(struct sdhci_host *host, unsigned int clock) +{ + int val = 0; + + if (clock == SDHCI_REFCLK_150M) { + /* SDHCI reference clock change 150M */ + regmap_read(regmap_base, + offsetof(struct SysCtl_regs, SysClkPeriCfg), &val); + val = val & (~SYS_CLK_PERI_CFG_W0_CFG_DIV_MSH_REF_CNT_MASK); + val |= + ((0x8 & SYS_CLK_PERI_CFG_W0_CFG_DIV_MSH_REF_CNT_MASK)) << 0; + regmap_write(regmap_base, + offsetof(struct SysCtl_regs, SysClkPeriCfg), val); + } + + sdhci_set_clock(host, clock); +} + +static int sdhci_ctc5236_prepare_tuning(struct sdhci_host *host, + int CENTER_PH_CODE) +{ + int CLK_CTRL_R_value = 0x0; + int HOST_CTRL2_R_value = 0x0; + int AT_CTRL_R_value = 0x0; + + /* Turn-off Sampling Clock */ + CLK_CTRL_R_value = sdhci_readw(host, SDHCI_CLOCK_CONTROL); + CLK_CTRL_R_value &= (~SDHCI_CLOCK_CARD_EN); + sdhci_writew(host, CLK_CTRL_R_value, SDHCI_CLOCK_CONTROL); + + /* Reset Tuning Engine */ + HOST_CTRL2_R_value = sdhci_readw(host, SDHCI_HOST_CONTROL2); + HOST_CTRL2_R_value &= (~SDHCI_CTRL_TUNED_CLK); + sdhci_writew(host, HOST_CTRL2_R_value, SDHCI_HOST_CONTROL2); + + /* Set up registers for CMD21 operation */ + if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8) + sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 128), SDHCI_BLOCK_SIZE); + else if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4) + sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 64), SDHCI_BLOCK_SIZE); + + sdhci_writew(host, SDHCI_TRNS_READ, SDHCI_TRANSFER_MODE); + + /* Enable Software tuning */ + AT_CTRL_R_value = sdhci_readl(host, REG_OFFSET_ADDR + AT_CTRL_R); + AT_CTRL_R_value |= SW_TUNE_EN; + sdhci_writel(host, AT_CTRL_R_value, REG_OFFSET_ADDR + AT_CTRL_R); + + /* Set tuning_cclk_sel to 0 */ + sdhci_writel(host, CENTER_PH_CODE, REG_OFFSET_ADDR + AT_STAT_R); + + /* Turn-on Sampling Clock */ + CLK_CTRL_R_value |= SDHCI_CLOCK_CARD_EN; + sdhci_writew(host, CLK_CTRL_R_value, SDHCI_CLOCK_CONTROL); + + return 0; +} + +static int sdhci_ctc5236_execute_tuning(struct sdhci_host *host, u32 opcode) +{ + int min, max, avg, ret; + int val = 0; + + /* Disable Rx bypass when tuning */ + regmap_read(regmap_base, offsetof(struct SysCtl_regs, SysMshCfg), &val); + val &= (~SYS_MSH_CFG_W0_MSH_INTF_RX_DLL_MASTER_BYPASS_MASK); + regmap_write(regmap_base, offsetof(struct SysCtl_regs, SysMshCfg), val); + + /* find the mininum delay first which can pass tuning */ + min = MIN_TUNING_LOOP; + sdhci_ctc5236_prepare_tuning(host, min); + while (min < MAX_TUNING_LOOP) { + dev_dbg(mmc_dev(host->mmc), "#1# AT_STAT_R is %x\n", + sdhci_readl(host, REG_OFFSET_ADDR + AT_STAT_R)); + if (!mmc_send_tuning(host->mmc, opcode, NULL)) + break; + + host->ops->reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); + + min += TUNE_CTRL_STEP; + sdhci_writel(host, min, REG_OFFSET_ADDR + AT_STAT_R); + } + + /* find the maxinum delay which can not pass tuning */ + max = min + TUNE_CTRL_STEP; + sdhci_ctc5236_prepare_tuning(host, max); + while (max < MAX_TUNING_LOOP) { + dev_dbg(mmc_dev(host->mmc), "#2# AT_STAT_R is %x\n", + sdhci_readl(host, REG_OFFSET_ADDR + AT_STAT_R)); + if (mmc_send_tuning(host->mmc, opcode, NULL)) { + max -= TUNE_CTRL_STEP; + break; + } + + host->ops->reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); + + max += TUNE_CTRL_STEP; + sdhci_writel(host, max, REG_OFFSET_ADDR + AT_STAT_R); + } + + /* use average delay to get the best timing */ + avg = (min + max) / 2; + sdhci_ctc5236_prepare_tuning(host, avg); + ret = mmc_send_tuning(host->mmc, opcode, NULL); + host->ops->reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); + sdhci_writel(host, avg, REG_OFFSET_ADDR + AT_STAT_R); + + dev_info(mmc_dev(host->mmc), "Tuning %s at 0x%x ret %d\n", + ret ? "failed" : "passed", avg, ret); + + return ret; +} + +static const struct sdhci_ops sdhci_ctc5236_ops = { + .read_w = sdhci_ctc5236_readw, + .read_l = sdhci_ctc5236_readl, + .set_clock = ctc_sdhci_set_clock, + .set_bus_width = sdhci_set_bus_width, + .reset = sdhci_ctc5236_reset, + .set_uhs_signaling = sdhci_set_uhs_signaling, + .get_max_clock = sdhci_pltfm_clk_get_max_clock, + .platform_execute_tuning = sdhci_ctc5236_execute_tuning, +}; + +static struct sdhci_pltfm_data sdhci_ctc5236_pdata = { + .ops = &sdhci_ctc5236_ops, + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | SDHCI_QUIRK2_BROKEN_HS200, + .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | SDHCI_QUIRK_BROKEN_ADMA, +}; + +static int sdhci_ctc5236_probe(struct platform_device *pdev) +{ + struct sdhci_host *host; + struct sdhci_pltfm_host *pltfm_host; + struct clk *clk; + int ret; + + host = sdhci_pltfm_init(pdev, &sdhci_ctc5236_pdata, 0); + if (IS_ERR(host)) + return PTR_ERR(host); + + clk = devm_clk_get(&pdev->dev, "mmc_clk"); + if (IS_ERR(clk)) { + dev_err(&pdev->dev, "Peripheral clk not found\n"); + return PTR_ERR(clk); + } + pltfm_host = sdhci_priv(host); + pltfm_host->clk = clk; + clk_prepare_enable(clk); + + regmap_base = + syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "ctc,sysctrl"); + if (IS_ERR(regmap_base)) + return PTR_ERR(regmap_base); + + mmc_of_parse_voltage(pdev->dev.of_node, &host->ocr_mask); + + ret = mmc_of_parse(host->mmc); + if (ret) + goto err_sdhci_add; + + ret = sdhci_add_host(host); + if (ret) + goto err_sdhci_add; + return 0; + +err_sdhci_add: + sdhci_pltfm_free(pdev); + return ret; +} + +static const struct of_device_id sdhci_ctc5236_of_match[] = { + {.compatible = "centec,ctc5236-sdhci"}, + {}, +}; + +MODULE_DEVICE_TABLE(of, sdhci_ctc5236_of_match); + +static struct platform_driver sdhci_ctc5236_driver = { + .driver = { + .name = "sdhci-ctc5236", + .pm = &sdhci_pltfm_pmops, + .of_match_table = of_match_ptr(sdhci_ctc5236_of_match), + }, + .probe = sdhci_ctc5236_probe, + .remove = sdhci_pltfm_unregister, +}; + +module_platform_driver(sdhci_ctc5236_driver); + +MODULE_DESCRIPTION("SDHCI driver for Centec TsingMa SoCs"); +MODULE_AUTHOR("Jay Cao "); +MODULE_LICENSE("GPL v2"); diff --git a/platform/centec-arm64/tsingma-bsp/src/sdhci-ctc5236/sdhci-pltfm.h b/platform/centec-arm64/tsingma-bsp/src/sdhci-ctc5236/sdhci-pltfm.h new file mode 100644 index 000000000000..1e91fb1c020e --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/sdhci-ctc5236/sdhci-pltfm.h @@ -0,0 +1,116 @@ +/* + * Copyright 2010 MontaVista Software, LLC. + * + * Author: Anton Vorontsov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _DRIVERS_MMC_SDHCI_PLTFM_H +#define _DRIVERS_MMC_SDHCI_PLTFM_H + +#include +#include +#include "sdhci.h" + +struct sdhci_pltfm_data { + const struct sdhci_ops *ops; + unsigned int quirks; + unsigned int quirks2; +}; + +struct sdhci_pltfm_host { + struct clk *clk; + + /* migrate from sdhci_of_host */ + unsigned int clock; + u16 xfer_mode_shadow; + + unsigned long private[0] ____cacheline_aligned; +}; + +#ifdef CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER +/* + * These accessors are designed for big endian hosts doing I/O to + * little endian controllers incorporating a 32-bit hardware byte swapper. + */ +static inline u32 sdhci_be32bs_readl(struct sdhci_host *host, int reg) +{ + return in_be32(host->ioaddr + reg); +} + +static inline u16 sdhci_be32bs_readw(struct sdhci_host *host, int reg) +{ + return in_be16(host->ioaddr + (reg ^ 0x2)); +} + +static inline u8 sdhci_be32bs_readb(struct sdhci_host *host, int reg) +{ + return in_8(host->ioaddr + (reg ^ 0x3)); +} + +static inline void sdhci_be32bs_writel(struct sdhci_host *host, + u32 val, int reg) +{ + out_be32(host->ioaddr + reg, val); +} + +static inline void sdhci_be32bs_writew(struct sdhci_host *host, + u16 val, int reg) +{ + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + int base = reg & ~0x3; + int shift = (reg & 0x2) * 8; + + switch (reg) { + case SDHCI_TRANSFER_MODE: + /* + * Postpone this write, we must do it together with a + * command write that is down below. + */ + pltfm_host->xfer_mode_shadow = val; + return; + case SDHCI_COMMAND: + sdhci_be32bs_writel(host, + val << 16 | pltfm_host->xfer_mode_shadow, + SDHCI_TRANSFER_MODE); + return; + } + clrsetbits_be32(host->ioaddr + base, 0xffff << shift, val << shift); +} + +static inline void sdhci_be32bs_writeb(struct sdhci_host *host, u8 val, int reg) +{ + int base = reg & ~0x3; + int shift = (reg & 0x3) * 8; + + clrsetbits_be32(host->ioaddr + base , 0xff << shift, val << shift); +} +#endif /* CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER */ + +extern void sdhci_get_of_property(struct platform_device *pdev); + +extern struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev, + const struct sdhci_pltfm_data *pdata, + size_t priv_size); +extern void sdhci_pltfm_free(struct platform_device *pdev); + +extern int sdhci_pltfm_register(struct platform_device *pdev, + const struct sdhci_pltfm_data *pdata, + size_t priv_size); +extern int sdhci_pltfm_unregister(struct platform_device *pdev); + +extern unsigned int sdhci_pltfm_clk_get_max_clock(struct sdhci_host *host); + +static inline void *sdhci_pltfm_priv(struct sdhci_pltfm_host *host) +{ + return host->private; +} + +int sdhci_pltfm_suspend(struct device *dev); +int sdhci_pltfm_resume(struct device *dev); +extern const struct dev_pm_ops sdhci_pltfm_pmops; + +#endif /* _DRIVERS_MMC_SDHCI_PLTFM_H */ diff --git a/platform/centec-arm64/tsingma-bsp/src/sdhci-ctc5236/sdhci.h b/platform/centec-arm64/tsingma-bsp/src/sdhci-ctc5236/sdhci.h new file mode 100644 index 000000000000..0f8c4f3ccafc --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/sdhci-ctc5236/sdhci.h @@ -0,0 +1,761 @@ +/* + * linux/drivers/mmc/host/sdhci.h - Secure Digital Host Controller Interface driver + * + * Header file for Host Controller registers and I/O accessors. + * + * Copyright (C) 2005-2008 Pierre Ossman, All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + */ +#ifndef __SDHCI_HW_H +#define __SDHCI_HW_H + +#include +#include +#include +#include +#include +#include + +#include + +/* + * Controller registers + */ + +#define SDHCI_DMA_ADDRESS 0x00 +#define SDHCI_ARGUMENT2 SDHCI_DMA_ADDRESS + +#define SDHCI_BLOCK_SIZE 0x04 +#define SDHCI_MAKE_BLKSZ(dma, blksz) (((dma & 0x7) << 12) | (blksz & 0xFFF)) + +#define SDHCI_BLOCK_COUNT 0x06 + +#define SDHCI_ARGUMENT 0x08 + +#define SDHCI_TRANSFER_MODE 0x0C +#define SDHCI_TRNS_DMA 0x01 +#define SDHCI_TRNS_BLK_CNT_EN 0x02 +#define SDHCI_TRNS_AUTO_CMD12 0x04 +#define SDHCI_TRNS_AUTO_CMD23 0x08 +#define SDHCI_TRNS_READ 0x10 +#define SDHCI_TRNS_MULTI 0x20 + +#define SDHCI_COMMAND 0x0E +#define SDHCI_CMD_RESP_MASK 0x03 +#define SDHCI_CMD_CRC 0x08 +#define SDHCI_CMD_INDEX 0x10 +#define SDHCI_CMD_DATA 0x20 +#define SDHCI_CMD_ABORTCMD 0xC0 + +#define SDHCI_CMD_RESP_NONE 0x00 +#define SDHCI_CMD_RESP_LONG 0x01 +#define SDHCI_CMD_RESP_SHORT 0x02 +#define SDHCI_CMD_RESP_SHORT_BUSY 0x03 + +#define SDHCI_MAKE_CMD(c, f) (((c & 0xff) << 8) | (f & 0xff)) +#define SDHCI_GET_CMD(c) ((c>>8) & 0x3f) + +#define SDHCI_RESPONSE 0x10 + +#define SDHCI_BUFFER 0x20 + +#define SDHCI_PRESENT_STATE 0x24 +#define SDHCI_CMD_INHIBIT 0x00000001 +#define SDHCI_DATA_INHIBIT 0x00000002 +#define SDHCI_DOING_WRITE 0x00000100 +#define SDHCI_DOING_READ 0x00000200 +#define SDHCI_SPACE_AVAILABLE 0x00000400 +#define SDHCI_DATA_AVAILABLE 0x00000800 +#define SDHCI_CARD_PRESENT 0x00010000 +#define SDHCI_WRITE_PROTECT 0x00080000 +#define SDHCI_DATA_LVL_MASK 0x00F00000 +#define SDHCI_DATA_LVL_SHIFT 20 +#define SDHCI_DATA_0_LVL_MASK 0x00100000 +#define SDHCI_CMD_LVL 0x01000000 + +#define SDHCI_HOST_CONTROL 0x28 +#define SDHCI_CTRL_LED 0x01 +#define SDHCI_CTRL_4BITBUS 0x02 +#define SDHCI_CTRL_HISPD 0x04 +#define SDHCI_CTRL_DMA_MASK 0x18 +#define SDHCI_CTRL_SDMA 0x00 +#define SDHCI_CTRL_ADMA1 0x08 +#define SDHCI_CTRL_ADMA32 0x10 +#define SDHCI_CTRL_ADMA64 0x18 +#define SDHCI_CTRL_8BITBUS 0x20 +#define SDHCI_CTRL_CDTEST_INS 0x40 +#define SDHCI_CTRL_CDTEST_EN 0x80 + +#define SDHCI_POWER_CONTROL 0x29 +#define SDHCI_POWER_ON 0x01 +#define SDHCI_POWER_180 0x0A +#define SDHCI_POWER_300 0x0C +#define SDHCI_POWER_330 0x0E + +#define SDHCI_BLOCK_GAP_CONTROL 0x2A + +#define SDHCI_WAKE_UP_CONTROL 0x2B +#define SDHCI_WAKE_ON_INT 0x01 +#define SDHCI_WAKE_ON_INSERT 0x02 +#define SDHCI_WAKE_ON_REMOVE 0x04 + +#define SDHCI_CLOCK_CONTROL 0x2C +#define SDHCI_DIVIDER_SHIFT 8 +#define SDHCI_DIVIDER_HI_SHIFT 6 +#define SDHCI_DIV_MASK 0xFF +#define SDHCI_DIV_MASK_LEN 8 +#define SDHCI_DIV_HI_MASK 0x300 +#define SDHCI_PROG_CLOCK_MODE 0x0020 +#define SDHCI_CLOCK_CARD_EN 0x0004 +#define SDHCI_CLOCK_INT_STABLE 0x0002 +#define SDHCI_CLOCK_INT_EN 0x0001 + +#define SDHCI_TIMEOUT_CONTROL 0x2E + +#define SDHCI_SOFTWARE_RESET 0x2F +#define SDHCI_RESET_ALL 0x01 +#define SDHCI_RESET_CMD 0x02 +#define SDHCI_RESET_DATA 0x04 + +#define SDHCI_INT_STATUS 0x30 +#define SDHCI_INT_ENABLE 0x34 +#define SDHCI_SIGNAL_ENABLE 0x38 +#define SDHCI_INT_RESPONSE 0x00000001 +#define SDHCI_INT_DATA_END 0x00000002 +#define SDHCI_INT_BLK_GAP 0x00000004 +#define SDHCI_INT_DMA_END 0x00000008 +#define SDHCI_INT_SPACE_AVAIL 0x00000010 +#define SDHCI_INT_DATA_AVAIL 0x00000020 +#define SDHCI_INT_CARD_INSERT 0x00000040 +#define SDHCI_INT_CARD_REMOVE 0x00000080 +#define SDHCI_INT_CARD_INT 0x00000100 +#define SDHCI_INT_RETUNE 0x00001000 +#define SDHCI_INT_CQE 0x00004000 +#define SDHCI_INT_ERROR 0x00008000 +#define SDHCI_INT_TIMEOUT 0x00010000 +#define SDHCI_INT_CRC 0x00020000 +#define SDHCI_INT_END_BIT 0x00040000 +#define SDHCI_INT_INDEX 0x00080000 +#define SDHCI_INT_DATA_TIMEOUT 0x00100000 +#define SDHCI_INT_DATA_CRC 0x00200000 +#define SDHCI_INT_DATA_END_BIT 0x00400000 +#define SDHCI_INT_BUS_POWER 0x00800000 +#define SDHCI_INT_AUTO_CMD_ERR 0x01000000 +#define SDHCI_INT_ADMA_ERROR 0x02000000 + +#define SDHCI_INT_NORMAL_MASK 0x00007FFF +#define SDHCI_INT_ERROR_MASK 0xFFFF8000 + +#define SDHCI_INT_CMD_MASK (SDHCI_INT_RESPONSE | SDHCI_INT_TIMEOUT | \ + SDHCI_INT_CRC | SDHCI_INT_END_BIT | SDHCI_INT_INDEX | \ + SDHCI_INT_AUTO_CMD_ERR) +#define SDHCI_INT_DATA_MASK (SDHCI_INT_DATA_END | SDHCI_INT_DMA_END | \ + SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | \ + SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \ + SDHCI_INT_DATA_END_BIT | SDHCI_INT_ADMA_ERROR | \ + SDHCI_INT_BLK_GAP) +#define SDHCI_INT_ALL_MASK ((unsigned int)-1) + +#define SDHCI_CQE_INT_ERR_MASK ( \ + SDHCI_INT_ADMA_ERROR | SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT | \ + SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX | \ + SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT) + +#define SDHCI_CQE_INT_MASK (SDHCI_CQE_INT_ERR_MASK | SDHCI_INT_CQE) + +#define SDHCI_AUTO_CMD_STATUS 0x3C +#define SDHCI_AUTO_CMD_TIMEOUT 0x00000002 +#define SDHCI_AUTO_CMD_CRC 0x00000004 +#define SDHCI_AUTO_CMD_END_BIT 0x00000008 +#define SDHCI_AUTO_CMD_INDEX 0x00000010 + +#define SDHCI_HOST_CONTROL2 0x3E +#define SDHCI_CTRL_UHS_MASK 0x0007 +#define SDHCI_CTRL_UHS_SDR12 0x0000 +#define SDHCI_CTRL_UHS_SDR25 0x0001 +#define SDHCI_CTRL_UHS_SDR50 0x0002 +#define SDHCI_CTRL_UHS_SDR104 0x0003 +#define SDHCI_CTRL_UHS_DDR50 0x0004 +#define SDHCI_CTRL_HS400 0x0005 /* Non-standard */ +#define SDHCI_CTRL_VDD_180 0x0008 +#define SDHCI_CTRL_DRV_TYPE_MASK 0x0030 +#define SDHCI_CTRL_DRV_TYPE_B 0x0000 +#define SDHCI_CTRL_DRV_TYPE_A 0x0010 +#define SDHCI_CTRL_DRV_TYPE_C 0x0020 +#define SDHCI_CTRL_DRV_TYPE_D 0x0030 +#define SDHCI_CTRL_EXEC_TUNING 0x0040 +#define SDHCI_CTRL_TUNED_CLK 0x0080 +#define SDHCI_CTRL_PRESET_VAL_ENABLE 0x8000 + +#define SDHCI_CAPABILITIES 0x40 +#define SDHCI_TIMEOUT_CLK_MASK 0x0000003F +#define SDHCI_TIMEOUT_CLK_SHIFT 0 +#define SDHCI_TIMEOUT_CLK_UNIT 0x00000080 +#define SDHCI_CLOCK_BASE_MASK 0x00003F00 +#define SDHCI_CLOCK_V3_BASE_MASK 0x0000FF00 +#define SDHCI_CLOCK_BASE_SHIFT 8 +#define SDHCI_MAX_BLOCK_MASK 0x00030000 +#define SDHCI_MAX_BLOCK_SHIFT 16 +#define SDHCI_CAN_DO_8BIT 0x00040000 +#define SDHCI_CAN_DO_ADMA2 0x00080000 +#define SDHCI_CAN_DO_ADMA1 0x00100000 +#define SDHCI_CAN_DO_HISPD 0x00200000 +#define SDHCI_CAN_DO_SDMA 0x00400000 +#define SDHCI_CAN_DO_SUSPEND 0x00800000 +#define SDHCI_CAN_VDD_330 0x01000000 +#define SDHCI_CAN_VDD_300 0x02000000 +#define SDHCI_CAN_VDD_180 0x04000000 +#define SDHCI_CAN_64BIT 0x10000000 + +#define SDHCI_SUPPORT_SDR50 0x00000001 +#define SDHCI_SUPPORT_SDR104 0x00000002 +#define SDHCI_SUPPORT_DDR50 0x00000004 +#define SDHCI_DRIVER_TYPE_A 0x00000010 +#define SDHCI_DRIVER_TYPE_C 0x00000020 +#define SDHCI_DRIVER_TYPE_D 0x00000040 +#define SDHCI_RETUNING_TIMER_COUNT_MASK 0x00000F00 +#define SDHCI_RETUNING_TIMER_COUNT_SHIFT 8 +#define SDHCI_USE_SDR50_TUNING 0x00002000 +#define SDHCI_RETUNING_MODE_MASK 0x0000C000 +#define SDHCI_RETUNING_MODE_SHIFT 14 +#define SDHCI_CLOCK_MUL_MASK 0x00FF0000 +#define SDHCI_CLOCK_MUL_SHIFT 16 +#define SDHCI_SUPPORT_HS400 0x80000000 /* Non-standard */ + +#define SDHCI_CAPABILITIES_1 0x44 + +#define SDHCI_MAX_CURRENT 0x48 +#define SDHCI_MAX_CURRENT_LIMIT 0xFF +#define SDHCI_MAX_CURRENT_330_MASK 0x0000FF +#define SDHCI_MAX_CURRENT_330_SHIFT 0 +#define SDHCI_MAX_CURRENT_300_MASK 0x00FF00 +#define SDHCI_MAX_CURRENT_300_SHIFT 8 +#define SDHCI_MAX_CURRENT_180_MASK 0xFF0000 +#define SDHCI_MAX_CURRENT_180_SHIFT 16 +#define SDHCI_MAX_CURRENT_MULTIPLIER 4 + +/* 4C-4F reserved for more max current */ + +#define SDHCI_SET_ACMD12_ERROR 0x50 +#define SDHCI_SET_INT_ERROR 0x52 + +#define SDHCI_ADMA_ERROR 0x54 + +/* 55-57 reserved */ + +#define SDHCI_ADMA_ADDRESS 0x58 +#define SDHCI_ADMA_ADDRESS_HI 0x5C + +/* 60-FB reserved */ + +#define SDHCI_PRESET_FOR_SDR12 0x66 +#define SDHCI_PRESET_FOR_SDR25 0x68 +#define SDHCI_PRESET_FOR_SDR50 0x6A +#define SDHCI_PRESET_FOR_SDR104 0x6C +#define SDHCI_PRESET_FOR_DDR50 0x6E +#define SDHCI_PRESET_FOR_HS400 0x74 /* Non-standard */ +#define SDHCI_PRESET_DRV_MASK 0xC000 +#define SDHCI_PRESET_DRV_SHIFT 14 +#define SDHCI_PRESET_CLKGEN_SEL_MASK 0x400 +#define SDHCI_PRESET_CLKGEN_SEL_SHIFT 10 +#define SDHCI_PRESET_SDCLK_FREQ_MASK 0x3FF +#define SDHCI_PRESET_SDCLK_FREQ_SHIFT 0 + +#define SDHCI_SLOT_INT_STATUS 0xFC + +#define SDHCI_HOST_VERSION 0xFE +#define SDHCI_VENDOR_VER_MASK 0xFF00 +#define SDHCI_VENDOR_VER_SHIFT 8 +#define SDHCI_SPEC_VER_MASK 0x00FF +#define SDHCI_SPEC_VER_SHIFT 0 +#define SDHCI_SPEC_100 0 +#define SDHCI_SPEC_200 1 +#define SDHCI_SPEC_300 2 + +/* + * End of controller registers. + */ + +#define SDHCI_MAX_DIV_SPEC_200 256 +#define SDHCI_MAX_DIV_SPEC_300 2046 + +/* + * Host SDMA buffer boundary. Valid values from 4K to 512K in powers of 2. + */ +#define SDHCI_DEFAULT_BOUNDARY_SIZE (512 * 1024) +#define SDHCI_DEFAULT_BOUNDARY_ARG (ilog2(SDHCI_DEFAULT_BOUNDARY_SIZE) - 12) + +/* ADMA2 32-bit DMA descriptor size */ +#define SDHCI_ADMA2_32_DESC_SZ 8 + +/* ADMA2 32-bit descriptor */ +struct sdhci_adma2_32_desc { + __le16 cmd; + __le16 len; + __le32 addr; +} __packed __aligned(4); + +/* ADMA2 data alignment */ +#define SDHCI_ADMA2_ALIGN 4 +#define SDHCI_ADMA2_MASK (SDHCI_ADMA2_ALIGN - 1) + +/* + * ADMA2 descriptor alignment. Some controllers (e.g. Intel) require 8 byte + * alignment for the descriptor table even in 32-bit DMA mode. Memory + * allocation is at least 8 byte aligned anyway, so just stipulate 8 always. + */ +#define SDHCI_ADMA2_DESC_ALIGN 8 + +/* ADMA2 64-bit DMA descriptor size */ +#define SDHCI_ADMA2_64_DESC_SZ 12 + +/* + * ADMA2 64-bit descriptor. Note 12-byte descriptor can't always be 8-byte + * aligned. + */ +struct sdhci_adma2_64_desc { + __le16 cmd; + __le16 len; + __le32 addr_lo; + __le32 addr_hi; +} __packed __aligned(4); + +#define ADMA2_TRAN_VALID 0x21 +#define ADMA2_NOP_END_VALID 0x3 +#define ADMA2_END 0x2 + +/* + * Maximum segments assuming a 512KiB maximum requisition size and a minimum + * 4KiB page size. + */ +#define SDHCI_MAX_SEGS 128 + +/* Allow for a a command request and a data request at the same time */ +#define SDHCI_MAX_MRQS 2 + +/* + * 48bit command and 136 bit response in 100KHz clock could take upto 2.48ms. + * However since the start time of the command, the time between + * command and response, and the time between response and start of data is + * not known, set the command transfer time to 10ms. + */ +#define MMC_CMD_TRANSFER_TIME (10 * NSEC_PER_MSEC) /* max 10 ms */ + +enum sdhci_cookie { + COOKIE_UNMAPPED, + COOKIE_PRE_MAPPED, /* mapped by sdhci_pre_req() */ + COOKIE_MAPPED, /* mapped by sdhci_prepare_data() */ +}; + +struct sdhci_host { + /* Data set by hardware interface driver */ + const char *hw_name; /* Hardware bus name */ + + unsigned int quirks; /* Deviations from spec. */ + +/* Controller doesn't honor resets unless we touch the clock register */ +#define SDHCI_QUIRK_CLOCK_BEFORE_RESET (1<<0) +/* Controller has bad caps bits, but really supports DMA */ +#define SDHCI_QUIRK_FORCE_DMA (1<<1) +/* Controller doesn't like to be reset when there is no card inserted. */ +#define SDHCI_QUIRK_NO_CARD_NO_RESET (1<<2) +/* Controller doesn't like clearing the power reg before a change */ +#define SDHCI_QUIRK_SINGLE_POWER_WRITE (1<<3) +/* Controller has flaky internal state so reset it on each ios change */ +#define SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS (1<<4) +/* Controller has an unusable DMA engine */ +#define SDHCI_QUIRK_BROKEN_DMA (1<<5) +/* Controller has an unusable ADMA engine */ +#define SDHCI_QUIRK_BROKEN_ADMA (1<<6) +/* Controller can only DMA from 32-bit aligned addresses */ +#define SDHCI_QUIRK_32BIT_DMA_ADDR (1<<7) +/* Controller can only DMA chunk sizes that are a multiple of 32 bits */ +#define SDHCI_QUIRK_32BIT_DMA_SIZE (1<<8) +/* Controller can only ADMA chunks that are a multiple of 32 bits */ +#define SDHCI_QUIRK_32BIT_ADMA_SIZE (1<<9) +/* Controller needs to be reset after each request to stay stable */ +#define SDHCI_QUIRK_RESET_AFTER_REQUEST (1<<10) +/* Controller needs voltage and power writes to happen separately */ +#define SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER (1<<11) +/* Controller provides an incorrect timeout value for transfers */ +#define SDHCI_QUIRK_BROKEN_TIMEOUT_VAL (1<<12) +/* Controller has an issue with buffer bits for small transfers */ +#define SDHCI_QUIRK_BROKEN_SMALL_PIO (1<<13) +/* Controller does not provide transfer-complete interrupt when not busy */ +#define SDHCI_QUIRK_NO_BUSY_IRQ (1<<14) +/* Controller has unreliable card detection */ +#define SDHCI_QUIRK_BROKEN_CARD_DETECTION (1<<15) +/* Controller reports inverted write-protect state */ +#define SDHCI_QUIRK_INVERTED_WRITE_PROTECT (1<<16) +/* Controller does not like fast PIO transfers */ +#define SDHCI_QUIRK_PIO_NEEDS_DELAY (1<<18) +/* Controller has to be forced to use block size of 2048 bytes */ +#define SDHCI_QUIRK_FORCE_BLK_SZ_2048 (1<<20) +/* Controller cannot do multi-block transfers */ +#define SDHCI_QUIRK_NO_MULTIBLOCK (1<<21) +/* Controller can only handle 1-bit data transfers */ +#define SDHCI_QUIRK_FORCE_1_BIT_DATA (1<<22) +/* Controller needs 10ms delay between applying power and clock */ +#define SDHCI_QUIRK_DELAY_AFTER_POWER (1<<23) +/* Controller uses SDCLK instead of TMCLK for data timeouts */ +#define SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK (1<<24) +/* Controller reports wrong base clock capability */ +#define SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN (1<<25) +/* Controller cannot support End Attribute in NOP ADMA descriptor */ +#define SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC (1<<26) +/* Controller is missing device caps. Use caps provided by host */ +#define SDHCI_QUIRK_MISSING_CAPS (1<<27) +/* Controller uses Auto CMD12 command to stop the transfer */ +#define SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12 (1<<28) +/* Controller doesn't have HISPD bit field in HI-SPEED SD card */ +#define SDHCI_QUIRK_NO_HISPD_BIT (1<<29) +/* Controller treats ADMA descriptors with length 0000h incorrectly */ +#define SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC (1<<30) +/* The read-only detection via SDHCI_PRESENT_STATE register is unstable */ +#define SDHCI_QUIRK_UNSTABLE_RO_DETECT (1<<31) + + unsigned int quirks2; /* More deviations from spec. */ + +#define SDHCI_QUIRK2_HOST_OFF_CARD_ON (1<<0) +#define SDHCI_QUIRK2_HOST_NO_CMD23 (1<<1) +/* The system physically doesn't support 1.8v, even if the host does */ +#define SDHCI_QUIRK2_NO_1_8_V (1<<2) +#define SDHCI_QUIRK2_PRESET_VALUE_BROKEN (1<<3) +#define SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON (1<<4) +/* Controller has a non-standard host control register */ +#define SDHCI_QUIRK2_BROKEN_HOST_CONTROL (1<<5) +/* Controller does not support HS200 */ +#define SDHCI_QUIRK2_BROKEN_HS200 (1<<6) +/* Controller does not support DDR50 */ +#define SDHCI_QUIRK2_BROKEN_DDR50 (1<<7) +/* Stop command (CMD12) can set Transfer Complete when not using MMC_RSP_BUSY */ +#define SDHCI_QUIRK2_STOP_WITH_TC (1<<8) +/* Controller does not support 64-bit DMA */ +#define SDHCI_QUIRK2_BROKEN_64_BIT_DMA (1<<9) +/* need clear transfer mode register before send cmd */ +#define SDHCI_QUIRK2_CLEAR_TRANSFERMODE_REG_BEFORE_CMD (1<<10) +/* Capability register bit-63 indicates HS400 support */ +#define SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400 (1<<11) +/* forced tuned clock */ +#define SDHCI_QUIRK2_TUNING_WORK_AROUND (1<<12) +/* disable the block count for single block transactions */ +#define SDHCI_QUIRK2_SUPPORT_SINGLE (1<<13) +/* Controller broken with using ACMD23 */ +#define SDHCI_QUIRK2_ACMD23_BROKEN (1<<14) +/* Broken Clock divider zero in controller */ +#define SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN (1<<15) +/* Controller has CRC in 136 bit Command Response */ +#define SDHCI_QUIRK2_RSP_136_HAS_CRC (1<<16) +/* + * Disable HW timeout if the requested timeout is more than the maximum + * obtainable timeout. + */ +#define SDHCI_QUIRK2_DISABLE_HW_TIMEOUT (1<<17) + + int irq; /* Device IRQ */ + void __iomem *ioaddr; /* Mapped address */ + char *bounce_buffer; /* For packing SDMA reads/writes */ + dma_addr_t bounce_addr; + unsigned int bounce_buffer_size; + + const struct sdhci_ops *ops; /* Low level hw interface */ + + /* Internal data */ + struct mmc_host *mmc; /* MMC structure */ + struct mmc_host_ops mmc_host_ops; /* MMC host ops */ + u64 dma_mask; /* custom DMA mask */ + +#if IS_ENABLED(CONFIG_LEDS_CLASS) + struct led_classdev led; /* LED control */ + char led_name[32]; +#endif + + spinlock_t lock; /* Mutex */ + + int flags; /* Host attributes */ +#define SDHCI_USE_SDMA (1<<0) /* Host is SDMA capable */ +#define SDHCI_USE_ADMA (1<<1) /* Host is ADMA capable */ +#define SDHCI_REQ_USE_DMA (1<<2) /* Use DMA for this req. */ +#define SDHCI_DEVICE_DEAD (1<<3) /* Device unresponsive */ +#define SDHCI_SDR50_NEEDS_TUNING (1<<4) /* SDR50 needs tuning */ +#define SDHCI_AUTO_CMD12 (1<<6) /* Auto CMD12 support */ +#define SDHCI_AUTO_CMD23 (1<<7) /* Auto CMD23 support */ +#define SDHCI_PV_ENABLED (1<<8) /* Preset value enabled */ +#define SDHCI_SDIO_IRQ_ENABLED (1<<9) /* SDIO irq enabled */ +#define SDHCI_USE_64_BIT_DMA (1<<12) /* Use 64-bit DMA */ +#define SDHCI_HS400_TUNING (1<<13) /* Tuning for HS400 */ +#define SDHCI_SIGNALING_330 (1<<14) /* Host is capable of 3.3V signaling */ +#define SDHCI_SIGNALING_180 (1<<15) /* Host is capable of 1.8V signaling */ +#define SDHCI_SIGNALING_120 (1<<16) /* Host is capable of 1.2V signaling */ + + unsigned int version; /* SDHCI spec. version */ + + unsigned int max_clk; /* Max possible freq (MHz) */ + unsigned int timeout_clk; /* Timeout freq (KHz) */ + unsigned int clk_mul; /* Clock Muliplier value */ + + unsigned int clock; /* Current clock (MHz) */ + u8 pwr; /* Current voltage */ + + bool runtime_suspended; /* Host is runtime suspended */ + bool bus_on; /* Bus power prevents runtime suspend */ + bool preset_enabled; /* Preset is enabled */ + bool pending_reset; /* Cmd/data reset is pending */ + bool irq_wake_enabled; /* IRQ wakeup is enabled */ + + struct mmc_request *mrqs_done[SDHCI_MAX_MRQS]; /* Requests done */ + struct mmc_command *cmd; /* Current command */ + struct mmc_command *data_cmd; /* Current data command */ + struct mmc_data *data; /* Current data request */ + unsigned int data_early:1; /* Data finished before cmd */ + + struct sg_mapping_iter sg_miter; /* SG state for PIO */ + unsigned int blocks; /* remaining PIO blocks */ + + int sg_count; /* Mapped sg entries */ + + void *adma_table; /* ADMA descriptor table */ + void *align_buffer; /* Bounce buffer */ + + size_t adma_table_sz; /* ADMA descriptor table size */ + size_t align_buffer_sz; /* Bounce buffer size */ + + dma_addr_t adma_addr; /* Mapped ADMA descr. table */ + dma_addr_t align_addr; /* Mapped bounce buffer */ + + unsigned int desc_sz; /* ADMA descriptor size */ + + struct tasklet_struct finish_tasklet; /* Tasklet structures */ + + struct timer_list timer; /* Timer for timeouts */ + struct timer_list data_timer; /* Timer for data timeouts */ + + u32 caps; /* CAPABILITY_0 */ + u32 caps1; /* CAPABILITY_1 */ + bool read_caps; /* Capability flags have been read */ + + unsigned int ocr_avail_sdio; /* OCR bit masks */ + unsigned int ocr_avail_sd; + unsigned int ocr_avail_mmc; + u32 ocr_mask; /* available voltages */ + + unsigned timing; /* Current timing */ + + u32 thread_isr; + + /* cached registers */ + u32 ier; + + bool cqe_on; /* CQE is operating */ + u32 cqe_ier; /* CQE interrupt mask */ + u32 cqe_err_ier; /* CQE error interrupt mask */ + + wait_queue_head_t buf_ready_int; /* Waitqueue for Buffer Read Ready interrupt */ + unsigned int tuning_done; /* Condition flag set when CMD19 succeeds */ + + unsigned int tuning_count; /* Timer count for re-tuning */ + unsigned int tuning_mode; /* Re-tuning mode supported by host */ +#define SDHCI_TUNING_MODE_1 0 +#define SDHCI_TUNING_MODE_2 1 +#define SDHCI_TUNING_MODE_3 2 + /* Delay (ms) between tuning commands */ + int tuning_delay; + + /* Host SDMA buffer boundary. */ + u32 sdma_boundary; + + u64 data_timeout; + + unsigned long private[0] ____cacheline_aligned; +}; + +struct sdhci_ops { +#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS + u32 (*read_l)(struct sdhci_host *host, int reg); + u16 (*read_w)(struct sdhci_host *host, int reg); + u8 (*read_b)(struct sdhci_host *host, int reg); + void (*write_l)(struct sdhci_host *host, u32 val, int reg); + void (*write_w)(struct sdhci_host *host, u16 val, int reg); + void (*write_b)(struct sdhci_host *host, u8 val, int reg); +#endif + + void (*set_clock)(struct sdhci_host *host, unsigned int clock); + void (*set_power)(struct sdhci_host *host, unsigned char mode, + unsigned short vdd); + + u32 (*irq)(struct sdhci_host *host, u32 intmask); + + int (*enable_dma)(struct sdhci_host *host); + unsigned int (*get_max_clock)(struct sdhci_host *host); + unsigned int (*get_min_clock)(struct sdhci_host *host); + /* get_timeout_clock should return clk rate in unit of Hz */ + unsigned int (*get_timeout_clock)(struct sdhci_host *host); + unsigned int (*get_max_timeout_count)(struct sdhci_host *host); + void (*set_timeout)(struct sdhci_host *host, + struct mmc_command *cmd); + void (*set_bus_width)(struct sdhci_host *host, int width); + void (*platform_send_init_74_clocks)(struct sdhci_host *host, + u8 power_mode); + unsigned int (*get_ro)(struct sdhci_host *host); + void (*reset)(struct sdhci_host *host, u8 mask); + int (*platform_execute_tuning)(struct sdhci_host *host, u32 opcode); + void (*set_uhs_signaling)(struct sdhci_host *host, unsigned int uhs); + void (*hw_reset)(struct sdhci_host *host); + void (*adma_workaround)(struct sdhci_host *host, u32 intmask); + void (*card_event)(struct sdhci_host *host); + void (*voltage_switch)(struct sdhci_host *host); +}; + +#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS + +static inline void sdhci_writel(struct sdhci_host *host, u32 val, int reg) +{ + if (unlikely(host->ops->write_l)) + host->ops->write_l(host, val, reg); + else + writel(val, host->ioaddr + reg); +} + +static inline void sdhci_writew(struct sdhci_host *host, u16 val, int reg) +{ + if (unlikely(host->ops->write_w)) + host->ops->write_w(host, val, reg); + else + writew(val, host->ioaddr + reg); +} + +static inline void sdhci_writeb(struct sdhci_host *host, u8 val, int reg) +{ + if (unlikely(host->ops->write_b)) + host->ops->write_b(host, val, reg); + else + writeb(val, host->ioaddr + reg); +} + +static inline u32 sdhci_readl(struct sdhci_host *host, int reg) +{ + if (unlikely(host->ops->read_l)) + return host->ops->read_l(host, reg); + else + return readl(host->ioaddr + reg); +} + +static inline u16 sdhci_readw(struct sdhci_host *host, int reg) +{ + if (unlikely(host->ops->read_w)) + return host->ops->read_w(host, reg); + else + return readw(host->ioaddr + reg); +} + +static inline u8 sdhci_readb(struct sdhci_host *host, int reg) +{ + if (unlikely(host->ops->read_b)) + return host->ops->read_b(host, reg); + else + return readb(host->ioaddr + reg); +} + +#else + +static inline void sdhci_writel(struct sdhci_host *host, u32 val, int reg) +{ + writel(val, host->ioaddr + reg); +} + +static inline void sdhci_writew(struct sdhci_host *host, u16 val, int reg) +{ + writew(val, host->ioaddr + reg); +} + +static inline void sdhci_writeb(struct sdhci_host *host, u8 val, int reg) +{ + writeb(val, host->ioaddr + reg); +} + +static inline u32 sdhci_readl(struct sdhci_host *host, int reg) +{ + return readl(host->ioaddr + reg); +} + +static inline u16 sdhci_readw(struct sdhci_host *host, int reg) +{ + return readw(host->ioaddr + reg); +} + +static inline u8 sdhci_readb(struct sdhci_host *host, int reg) +{ + return readb(host->ioaddr + reg); +} + +#endif /* CONFIG_MMC_SDHCI_IO_ACCESSORS */ + +struct sdhci_host *sdhci_alloc_host(struct device *dev, size_t priv_size); +void sdhci_free_host(struct sdhci_host *host); + +static inline void *sdhci_priv(struct sdhci_host *host) +{ + return host->private; +} + +void sdhci_card_detect(struct sdhci_host *host); +void __sdhci_read_caps(struct sdhci_host *host, u16 *ver, u32 *caps, + u32 *caps1); +int sdhci_setup_host(struct sdhci_host *host); +void sdhci_cleanup_host(struct sdhci_host *host); +int __sdhci_add_host(struct sdhci_host *host); +int sdhci_add_host(struct sdhci_host *host); +void sdhci_remove_host(struct sdhci_host *host, int dead); +void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd); + +static inline void sdhci_read_caps(struct sdhci_host *host) +{ + __sdhci_read_caps(host, NULL, NULL, NULL); +} + +static inline bool sdhci_sdio_irq_enabled(struct sdhci_host *host) +{ + return !!(host->flags & SDHCI_SDIO_IRQ_ENABLED); +} + +u16 sdhci_calc_clk(struct sdhci_host *host, unsigned int clock, + unsigned int *actual_clock); +void sdhci_set_clock(struct sdhci_host *host, unsigned int clock); +void sdhci_enable_clk(struct sdhci_host *host, u16 clk); +void sdhci_set_power(struct sdhci_host *host, unsigned char mode, + unsigned short vdd); +void sdhci_set_power_noreg(struct sdhci_host *host, unsigned char mode, + unsigned short vdd); +void sdhci_set_bus_width(struct sdhci_host *host, int width); +void sdhci_reset(struct sdhci_host *host, u8 mask); +void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing); +int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode); +void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); +int sdhci_start_signal_voltage_switch(struct mmc_host *mmc, + struct mmc_ios *ios); +void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable); + +#ifdef CONFIG_PM +int sdhci_suspend_host(struct sdhci_host *host); +int sdhci_resume_host(struct sdhci_host *host); +int sdhci_runtime_suspend_host(struct sdhci_host *host); +int sdhci_runtime_resume_host(struct sdhci_host *host); +#endif + +void sdhci_cqe_enable(struct mmc_host *mmc); +void sdhci_cqe_disable(struct mmc_host *mmc, bool recovery); +bool sdhci_cqe_irq(struct sdhci_host *host, u32 intmask, int *cmd_error, + int *data_error); + +void sdhci_dumpregs(struct sdhci_host *host); + +void sdhci_start_tuning(struct sdhci_host *host); +void sdhci_end_tuning(struct sdhci_host *host); +void sdhci_reset_tuning(struct sdhci_host *host); +void sdhci_send_tuning(struct sdhci_host *host, u32 opcode); + +#endif /* __SDHCI_HW_H */ diff --git a/platform/centec-arm64/tsingma-bsp/src/spi-ctc-qspi/Makefile b/platform/centec-arm64/tsingma-bsp/src/spi-ctc-qspi/Makefile new file mode 100644 index 000000000000..f42732b694cb --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/spi-ctc-qspi/Makefile @@ -0,0 +1 @@ +obj-m = spi-ctc-qspi.o diff --git a/platform/centec-arm64/tsingma-bsp/src/spi-ctc-qspi/spi-ctc-qspi.c b/platform/centec-arm64/tsingma-bsp/src/spi-ctc-qspi/spi-ctc-qspi.c new file mode 100644 index 000000000000..936459bd3e73 --- /dev/null +++ b/platform/centec-arm64/tsingma-bsp/src/spi-ctc-qspi/spi-ctc-qspi.c @@ -0,0 +1,639 @@ +/* + * Centec QSPI controller driver + * + * Author: wangyb + * + * Copyright 2005-2018, Centec Networks (Suzhou) Co., Ltd. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SPI_MODE 0x00 + +#define PIO_MODE_1 0x01 +#define PIO_MODE_2 0x02 + +#define PIO_BASE(NR) (0x20*(NR-1)) +#define PIO_GO(NR) (0x10 + PIO_BASE(NR)) +#define PIO_CTRL(NR) (0x14 + PIO_BASE(NR)) +#define PIO_STEP0_CONF(NR) (0x20 + PIO_BASE(NR)) +#define PIO_STEP1_CONF(NR) (0x24 + PIO_BASE(NR)) +#define PIO_STEP2_CONF(NR) (0x28 + PIO_BASE(NR)) +#define PIO_STEP3_CONF(NR) (0x2c + PIO_BASE(NR)) + +#define PP_GO 0x80 +#define PP_CTRL 0x84 +#define PP_CMD_CODE 0x90 +#define PP_CMD_CONF 0x94 +#define PP_ADDR_CODE 0x98 +#define PP_ADDR_CONF 0X9c +#define PP_DUMMY_CODE 0xa0 +#define PP_DUMMY_CONF 0xa4 +#define PP_DATA_CONF 0xa8 + +#define CTRL_IDLE_CYCLE(V) (((V)&3)<<24) +#define CTRL_PRE_CYCLE(V) (((V)&3)<<22) +#define CTRL_POST_CYCLE(V) (((V)&3)<<20) +#define CTRL_SCLK_DEFAULT(V) (((V)&1)<<19) +#define CTRL_SOUT3_DEFAULT(V) (((V)&1)<<18) +#define CTRL_SOUT2_DEFAULT(V) (((V)&1)<<17) +#define CTRL_SOUT1_DEFAULT(V) (((V)&1)<<16) +#define CTRL_CS(V) (((V)&0xff)<<8) +#define CTRL_DIV_SCLK(V) (((V)&0xff)<<0) + +#define CTC_QSPI_TX_BUFF 0x100 +#define CTC_QSPI_RX_BUFF 0x180 + +#define CTC_QSPI_RX_BUFFER_SIZE 128 +#define CTC_QSPI_TX_BUFFER_SIZE 256 + +#define SPINOR_OP_PP 0x02 /* Page program (up to 256 bytes) */ + +#define TIMEOUT_COUNT 65535 + +#define SPI_INT_EN 0x04 +#define SPI_INT_STATUS 0x0c + +struct ctc_qspi { + void __iomem *regs; + u32 speed_hz; + u32 bus_clk; + u32 num_chipselect; + u32 idlecycle; + u32 precycle; + u32 postcycle; + u32 sout1def; + u32 sout2def; + u32 sout3def; + u32 qspi_mode; + u32 clkdiv; + u32 sclkdef; + u32 cs_select; + u32 bytes_to_transfer; + u8 step; + u32 tx_entry; +}; + +enum ctc_qspi_mode { + PIO_MODE1 = 1, + PIO_MODE2, + PP_MODE, + BOOT_MODE, + XIP_MODE, + MODE_MAX +}; + +enum type_mode { + TYPE_PP = 1, + TYPE_PIO, + TYPE_MAX +}; + +static int ctc_reg_read(struct ctc_qspi *ctc_qspi, u32 reg, u32 *value) +{ + *value = readl(ctc_qspi->regs + reg); + return *value; +} + +static int ctc_reg_write(struct ctc_qspi *ctc_qspi, u32 reg, u32 value) +{ + writel(value, ctc_qspi->regs + reg); + + return 0; +} + +static int ctc_reg_write_mask(struct ctc_qspi *ctc_qspi, u32 reg, u32 value, + u32 mask) +{ + u32 temp; + + ctc_reg_read(ctc_qspi, reg, &temp); + temp &= ~mask; + temp |= value; + ctc_reg_write(ctc_qspi, reg, temp); + + return 0; +} + +static int ctc_qspi_setup(struct spi_device *spi) +{ + struct ctc_qspi *ctc_qspi = spi_master_get_devdata(spi->master); + + if (spi->master->busy) + return -EBUSY; + + ctc_qspi->sout1def = 1; + ctc_qspi->sout2def = 1; + ctc_qspi->sout3def = 1; + + ctc_qspi->speed_hz = spi->max_speed_hz; + + ctc_qspi->clkdiv = (ctc_qspi->bus_clk / (ctc_qspi->speed_hz * 2)); + + if ((spi->mode & 0x3) == SPI_MODE_0) + ctc_qspi->sclkdef = 0; + else if ((spi->mode & 0x3) == SPI_MODE_3) + ctc_qspi->sclkdef = 1; + else + ctc_qspi->sclkdef = 1; + return 0; +} + +static noinline int ctc_write_tx_buf(struct ctc_qspi *ctc_qspi, u8 offset, + u32 value) +{ + writel(value, ctc_qspi->regs + CTC_QSPI_TX_BUFF + offset); + + return 0; +} + +static noinline int check_buf_ok(u8 *buf, int i) +{ + return buf && (buf + i); +} + +static noinline int fill_tx_entry(struct ctc_qspi *ctc_qspi, u8 *buf, int i, + u8 off) +{ + ctc_qspi->tx_entry |= buf[i] << (off % 4) * 8; + + return 0; +} + +static noinline void update_offset(u8 *offset, u8 off) +{ + *offset = off; +} + +static void ctc_fill_tx_buf(struct ctc_qspi *ctc_qspi, u8 *offset, u8 *buf, + u32 len) +{ + + int i = 0; + u8 off = *offset; + + while (i < len) { + if (check_buf_ok(buf, i)) + fill_tx_entry(ctc_qspi, buf, i, off); + + if (off % 4 == 0) { + ctc_write_tx_buf(ctc_qspi, off, ctc_qspi->tx_entry); + ctc_qspi->tx_entry = 0; + } + i++; + off--; + } + + update_offset(offset, off); + +} + +static void ctc_fill_pp_buf(struct ctc_qspi *ctc_qspi, u32 *offset, u8 *buf, + u32 len) +{ + u32 i = 0, j = 0; + u32 off = *offset; + + while (i < len) { + for (j = 0; j < 4; j++) { + if (buf && (buf + i)) + ctc_qspi->tx_entry |= buf[i + j] << (j % 4) * 8; + } + ctc_write_tx_buf(ctc_qspi, off, ctc_qspi->tx_entry); + ctc_qspi->tx_entry = 0; + + i = i + 4; + off += 4; + } + *offset = off; +} + +static void ctc_stepx_conf_init(struct ctc_qspi *ctc_qspi) +{ + ctc_qspi->step = 0; + + ctc_reg_write_mask(ctc_qspi, PIO_STEP0_CONF(ctc_qspi->qspi_mode), 0, + 0xffffffff); + ctc_reg_write_mask(ctc_qspi, PIO_STEP1_CONF(ctc_qspi->qspi_mode), 0, + 0xffffffff); + ctc_reg_write_mask(ctc_qspi, PIO_STEP2_CONF(ctc_qspi->qspi_mode), 0, + 0xffffffff); + ctc_reg_write_mask(ctc_qspi, PIO_STEP3_CONF(ctc_qspi->qspi_mode), 0, + 0xffffffff); +} + +static void ctc_stepx_conf(struct ctc_qspi *ctc_qspi, u8 lanes, u32 bytes, + u32 output_en) +{ + u32 cycle = 0; + u32 stepx_conf = 0; + + if (bytes <= 0) + return; + + cycle = (bytes * 8) / lanes; + + if (lanes == 1) { + stepx_conf = (0xd << 20) | (lanes << 16) | (cycle); + } else if (lanes == 2) { + stepx_conf = output_en ? (0x3 << 20) | (lanes << 16) | (cycle) : + (0xc << 20) | (lanes << 16) | (cycle); + } else if (lanes == 4) { + stepx_conf = output_en ? (0xf << 20) | (lanes << 16) | (cycle) : + (0x0 << 20) | (lanes << 16) | (cycle); + } + + if (ctc_qspi->step == 0) { + ctc_reg_write_mask(ctc_qspi, + PIO_STEP0_CONF(ctc_qspi->qspi_mode), + stepx_conf, 0xffffffff); + ctc_qspi->step++; + } else if (ctc_qspi->step == 1) { + ctc_reg_write_mask(ctc_qspi, + PIO_STEP1_CONF(ctc_qspi->qspi_mode), + stepx_conf, 0xffffffff); + ctc_qspi->step++; + } else if (ctc_qspi->step == 2) { + ctc_reg_write_mask(ctc_qspi, + PIO_STEP2_CONF(ctc_qspi->qspi_mode), + stepx_conf, 0xffffffff); + ctc_qspi->step++; + } else if (ctc_qspi->step == 3) { + ctc_reg_write_mask(ctc_qspi, + PIO_STEP3_CONF(ctc_qspi->qspi_mode), + stepx_conf, 0xffffffff); + ctc_qspi->step++; + } + +} + +static void ctc_select_qspi_mode(struct ctc_qspi *ctc_qspi, u32 qspi_mode) +{ + if ((qspi_mode == PIO_MODE1) || (qspi_mode == PIO_MODE2)) { + ctc_reg_write_mask(ctc_qspi, SPI_MODE, ctc_qspi->qspi_mode, + 0xffffffff); + } else if (qspi_mode == PP_MODE) { + ctc_reg_write_mask(ctc_qspi, SPI_MODE, 0x100, 0xffffffff); + } +} + +static void ctc_qspi_pio_ctrl(struct ctc_qspi *ctc_qspi) +{ + u32 ctrl = 0; + + ctrl = CTRL_IDLE_CYCLE(ctc_qspi->idlecycle) | + CTRL_PRE_CYCLE(ctc_qspi->precycle) | + CTRL_POST_CYCLE(ctc_qspi->postcycle) | + CTRL_SCLK_DEFAULT(ctc_qspi->sclkdef) | + CTRL_SOUT3_DEFAULT(ctc_qspi->sout3def) | + CTRL_SOUT2_DEFAULT(ctc_qspi->sout2def) | + CTRL_SOUT1_DEFAULT(ctc_qspi->sout1def) | + CTRL_CS(ctc_qspi->cs_select) | + CTRL_DIV_SCLK(ctc_qspi->clkdiv); + + ctc_reg_write_mask(ctc_qspi, PIO_CTRL(ctc_qspi->qspi_mode), ctrl, + 0xffffffff); +} + +static void ctc_qspi_pp_ctrl(struct ctc_qspi *ctc_qspi) +{ + u32 ctrl = 0; + + ctrl = CTRL_IDLE_CYCLE(ctc_qspi->idlecycle) | + CTRL_PRE_CYCLE(ctc_qspi->precycle) | + CTRL_POST_CYCLE(ctc_qspi->postcycle) | + CTRL_SCLK_DEFAULT(ctc_qspi->sclkdef) | + CTRL_SOUT3_DEFAULT(ctc_qspi->sout3def) | + CTRL_SOUT2_DEFAULT(ctc_qspi->sout2def) | + CTRL_SOUT1_DEFAULT(ctc_qspi->sout1def) | + CTRL_CS(ctc_qspi->cs_select) | + CTRL_DIV_SCLK(ctc_qspi->clkdiv); + + ctc_reg_write_mask(ctc_qspi, PP_CTRL, ctrl, 0xffffffff); +} + +static u32 ctc_pp_conf(u8 lanes, u32 len) +{ + u32 cycle = 0; + + cycle = (len * 8) / lanes; + + return (lanes << 16) | (cycle); +} + +static int ctc_read_rx_buf(struct ctc_qspi *ctc_qspi, u8 offset, u8 *value) +{ + *value = readb(ctc_qspi->regs + CTC_QSPI_RX_BUFF + offset); + + return 0; +} + +static void ctc_extra_rx_buf(struct ctc_qspi *ctc_qspi, u8 offset, u8 *buf, + u8 len) +{ + int i = 0; + + while (i < len) { + ctc_read_rx_buf(ctc_qspi, offset, &buf[i++]); + offset--; + } +} + +static int ctc_transfer_for_PP_mode(struct ctc_qspi *ctc_qspi, + struct spi_transfer *p_xfers[], + u8 xfers_num, u32 msg_len) +{ + u8 i; + u32 pp_conf; + u32 timeout = 0; + u32 temp; + u32 offset; + struct spi_mem_op mem_ops; + + memset(&mem_ops, 0, sizeof(mem_ops)); + + mem_ops.cmd.opcode = ((u8 *) p_xfers[0]->tx_buf)[0]; + mem_ops.cmd.buswidth = p_xfers[0]->tx_nbits; + + mem_ops.addr.nbytes = p_xfers[1]->len; + mem_ops.addr.buswidth = p_xfers[1]->tx_nbits; + for (i = 0; i < mem_ops.addr.nbytes; i++) { + mem_ops.addr.val |= + ((u8 *) p_xfers[1]->tx_buf)[i] << (8 * + (mem_ops.addr.nbytes - + i - 1)); + } + + if (xfers_num >= 4) { + mem_ops.addr.nbytes = p_xfers[2]->len; + mem_ops.addr.buswidth = p_xfers[2]->tx_nbits; + } + + mem_ops.data.nbytes = p_xfers[xfers_num - 1]->len; + mem_ops.data.buswidth = p_xfers[xfers_num - 1]->tx_nbits; + mem_ops.data.buf.out = p_xfers[xfers_num - 1]->tx_buf; + + ctc_qspi->qspi_mode = PP_MODE; + ctc_select_qspi_mode(ctc_qspi, ctc_qspi->qspi_mode); + ctc_qspi_pp_ctrl(ctc_qspi); + + /* Fill buffer */ + offset = 0; + ctc_qspi->tx_entry = 0; + ctc_fill_pp_buf(ctc_qspi, &offset, (u8 *) mem_ops.data.buf.out, + mem_ops.data.nbytes); + + /* PP CMD */ + ctc_reg_write_mask(ctc_qspi, PP_CMD_CODE, mem_ops.cmd.opcode, + 0xffffffff); + pp_conf = ctc_pp_conf(mem_ops.cmd.buswidth, 1); + ctc_reg_write_mask(ctc_qspi, PP_CMD_CONF, pp_conf, 0xffffffff); + + /* PP ADDR */ + ctc_reg_write_mask(ctc_qspi, PP_ADDR_CODE, mem_ops.addr.val, + 0xffffffff); + pp_conf = ctc_pp_conf(mem_ops.addr.buswidth, mem_ops.addr.nbytes); + ctc_reg_write_mask(ctc_qspi, PP_ADDR_CONF, pp_conf, 0xffffffff); + + /* PP DUMMY */ + ctc_reg_write_mask(ctc_qspi, PP_DUMMY_CODE, 0x00000000, 0xffffffff); + pp_conf = ctc_pp_conf(mem_ops.dummy.buswidth, mem_ops.dummy.nbytes); + ctc_reg_write_mask(ctc_qspi, PP_DUMMY_CONF, pp_conf, 0xffffffff); + + /* PP DATA */ + pp_conf = ctc_pp_conf(mem_ops.data.buswidth, mem_ops.data.nbytes); + ctc_reg_write_mask(ctc_qspi, PP_DATA_CONF, pp_conf, 0xffffffff); + + /* PP GO */ + ctc_reg_write_mask(ctc_qspi, PP_GO, 0x01, 0xffffffff); + while (ctc_reg_read(ctc_qspi, PP_GO, &temp) & 0x1) { + if (timeout++ > TIMEOUT_COUNT) + break; + udelay(1); + } + + return msg_len; +} + +static int ctc_transfer_for_PIO(struct ctc_qspi *ctc_qspi, + struct spi_transfer *p_xfers[], u8 xfers_num, + u32 msg_len) +{ + u8 i; + u8 offset; + u32 timeout = 0; + u32 temp; + + ctc_qspi->qspi_mode = PIO_MODE1; + ctc_select_qspi_mode(ctc_qspi, ctc_qspi->qspi_mode); + ctc_qspi_pio_ctrl(ctc_qspi); + ctc_stepx_conf_init(ctc_qspi); + + offset = msg_len - 1; + ctc_qspi->tx_entry = 0; + for (i = 0; i < xfers_num; i++) { + if (p_xfers[i]->tx_buf) { + ctc_fill_tx_buf(ctc_qspi, &offset, + (u8 *) p_xfers[i]->tx_buf, + p_xfers[i]->len); + ctc_stepx_conf(ctc_qspi, p_xfers[i]->tx_nbits, + p_xfers[i]->len, 1); + } else { + ctc_fill_tx_buf(ctc_qspi, &offset, + (u8 *) p_xfers[i]->rx_buf, + p_xfers[i]->len); + ctc_stepx_conf(ctc_qspi, p_xfers[i]->rx_nbits, + p_xfers[i]->len, 0); + } + } + + /* PIO write start transfer */ + ctc_reg_write_mask(ctc_qspi, PIO_GO(ctc_qspi->qspi_mode), 0x01, + 0xffffffff); + while (ctc_reg_read(ctc_qspi, PIO_GO(ctc_qspi->qspi_mode), &temp) & 0x1) { + if (timeout++ > TIMEOUT_COUNT) + break; + udelay(1); + } + + if (p_xfers[xfers_num - 1]->rx_buf) { + ctc_extra_rx_buf(ctc_qspi, p_xfers[xfers_num - 1]->len - 1, + p_xfers[xfers_num - 1]->rx_buf, + p_xfers[xfers_num - 1]->len); + } + + return msg_len; +} + +static int ctc_qspi_start_transfer_one(struct spi_master *master, + struct spi_message *msg) +{ + struct ctc_qspi *ctc_qspi = spi_master_get_devdata(master); + struct spi_device *spi = msg->spi; + struct spi_transfer *t; + u8 xfer_num = 0; + struct spi_transfer *xfers[4]; + u32 msg_len = 0; + + ctc_qspi->cs_select = (0x1 << spi->chip_select); + list_for_each_entry(t, &msg->transfers, transfer_list) { + xfers[xfer_num] = t; + xfer_num++; + msg_len += t->len; + } + + if (xfers[xfer_num - 1]->tx_buf && xfer_num >= 3) { + msg->actual_length = + ctc_transfer_for_PP_mode(ctc_qspi, xfers, xfer_num, + msg_len); + } else { + msg->actual_length = + ctc_transfer_for_PIO(ctc_qspi, xfers, xfer_num, msg_len); + } + + msg->status = 0; + spi_finalize_current_message(master); + + return 0; +} + +int ctc_qspi_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op) +{ + //max data transfer size = tx buffer size - (cmd - addr -dummy ) + if (op->data.dir == SPI_MEM_DATA_IN) { + if (op->data.nbytes > CTC_QSPI_RX_BUFFER_SIZE - 6) + op->data.nbytes = CTC_QSPI_RX_BUFFER_SIZE - 6; + } else { + if (op->data.nbytes > CTC_QSPI_TX_BUFFER_SIZE) + op->data.nbytes = CTC_QSPI_TX_BUFFER_SIZE; + } + + return 0; +} + +static int ctc_qspi_exec_mem_op(struct spi_mem *mem, + const struct spi_mem_op *op) +{ + return -ENOTSUPP; +} + +static const struct spi_controller_mem_ops ctc_qspi_mem_ops = { + .adjust_op_size = ctc_qspi_adjust_op_size, + .exec_op = ctc_qspi_exec_mem_op, +}; + +static int ctc_qspi_probe(struct platform_device *pdev) +{ + int ret = 0, irq; + struct spi_master *master; + struct ctc_qspi *ctc_qspi; + struct resource *res; + struct device_node *np = pdev->dev.of_node; + u32 tmp; + + master = spi_alloc_master(&pdev->dev, sizeof(*ctc_qspi)); + if (!master) + return -ENOMEM; + + master->mode_bits = + SPI_MODE_3 | SPI_MODE_1 | SPI_TX_DUAL | SPI_RX_DUAL | SPI_TX_QUAD | + SPI_RX_QUAD; + master->setup = ctc_qspi_setup; + master->transfer_one_message = ctc_qspi_start_transfer_one; + master->bits_per_word_mask = + SPI_BPW_MASK(32) | SPI_BPW_MASK(16) | SPI_BPW_MASK(8); + master->mem_ops = &ctc_qspi_mem_ops; + if (!of_property_read_u32(np, "num-cs", &tmp)) + master->num_chipselect = tmp; + + ctc_qspi = spi_master_get_devdata(master); + master->dev.of_node = pdev->dev.of_node; + platform_set_drvdata(pdev, master); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + ctc_qspi->regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(ctc_qspi->regs)) { + ret = PTR_ERR(ctc_qspi->regs); + goto remove_master; + } + + if (!of_property_read_u32(np, "pclk", &tmp)) + ctc_qspi->bus_clk = tmp; + if (!of_property_read_u32(np, "idle-cycle", &tmp)) + ctc_qspi->idlecycle = tmp; + if (!of_property_read_u32(np, "pre-cycle", &tmp)) + ctc_qspi->precycle = tmp; + if (!of_property_read_u32(np, "post-cycle", &tmp)) + ctc_qspi->postcycle = tmp; + if (!of_property_read_u32(np, "qspi-mode", &tmp)) + ctc_qspi->qspi_mode = tmp; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "no irq resource?\n"); + return irq; + } + ret = devm_spi_register_master(&pdev->dev, master); + if (!ret) + return 0; + return 0; + +remove_master: + spi_master_put(master); + + return ret; +} + +static int ctc_qspi_remove(struct platform_device *pdev) +{ + struct spi_master *master = platform_get_drvdata(pdev); + + spi_unregister_master(master); + return 0; +} + +static const struct of_device_id ctc_qspi_match[] = { + { + .compatible = "ctc, igdaxi001a-qspi", + }, + {}, +}; + +MODULE_DEVICE_TABLE(of, ctc_qspi_match); + +/* Structure for a device driver */ +static struct platform_driver ctc_qspi_driver = { + .driver = { + .name = "ctc-qspi", + .of_match_table = ctc_qspi_match, + }, + .probe = ctc_qspi_probe, + .remove = ctc_qspi_remove, +}; + +module_platform_driver(ctc_qspi_driver); + +MODULE_AUTHOR("Centec, Inc."); +MODULE_LICENSE("GPL"); diff --git a/platform/centec/centec-dal/Makefile b/platform/centec/centec-dal/Makefile new file mode 100644 index 000000000000..a0837a80cd18 --- /dev/null +++ b/platform/centec/centec-dal/Makefile @@ -0,0 +1,7 @@ +ifeq ($(CONFIGURED_ARCH), arm64) +EXTRA_CFLAGS += -DSOC_ACTIVE +EXTRA_CFLAGS += -DDMA_MEM_MODE_PLATFORM +endif + +obj-m := dal.o +dal-y := dal_kernel.o dal_mpool.o diff --git a/platform/centec/centec-dal/dal_common.h b/platform/centec/centec-dal/dal_common.h new file mode 100644 index 000000000000..d8d4d6a67c0d --- /dev/null +++ b/platform/centec/centec-dal/dal_common.h @@ -0,0 +1,119 @@ +/** + @file dal.h + + @author Copyright (C) 2012 Centec Networks Inc. All rights reserved. + + @date 2012-4-9 + + @version v2.0 + +*/ +#ifndef _DAL_COMMON_H_ +#define _DAL_COMMON_H_ +#ifdef __cplusplus +extern "C" { +#endif + +#define DAL_MAX_CHIP_NUM 8 /* DAL support max chip num is 8 */ +#define DAL_MAX_INTR_NUM 8 + +#define DAL_NETIF_T_PORT 0 +#define DAL_NETIF_T_VLAN 1 + +#define DAL_MAX_KNET_NETIF 64 +#define DAL_MAX_KNET_NAME_LEN 32 + +enum dal_operate_code_e +{ + DAL_OP_CREATE, + DAL_OP_DESTORY, + DAL_OP_GET, + DAL_OP_MAX, +}; +typedef enum dal_operate_code_e dal_operate_code_t; + +struct dal_dma_info_s +{ + unsigned int lchip; + unsigned int phy_base; + unsigned int phy_base_hi; + unsigned int size; + unsigned int knet_tx_offset; + unsigned int knet_tx_size; + unsigned int* virt_base; +}; +typedef struct dal_dma_info_s dal_dma_info_t; + +struct dal_dma_chan_s +{ + unsigned char lchip; + unsigned char channel_id; + unsigned char dmasel; + unsigned char active; + unsigned short current_index; + unsigned short desc_num; + unsigned short desc_depth; + unsigned short data_size; + unsigned long long mem_base; + void* virt_base; /**< don't use when register chan*/ + unsigned char* p_desc_used; /**< don't use when register chan*/ +}; +typedef struct dal_dma_chan_s dal_dma_chan_t; + +struct dal_netif_s +{ + unsigned char op_type; + unsigned char netif_id; + unsigned char type; + unsigned char lchip; + unsigned short vlan; + unsigned int gport; + unsigned char mac[6]; + char name[DAL_MAX_KNET_NAME_LEN]; +}; +typedef struct dal_netif_s dal_netif_t; + +/** + @brief define dal error type +*/ +enum dal_err_e +{ + DAL_E_NONE = 0, /**< NO error */ + DAL_E_INVALID_PTR = -1000, /**< invalid pointer */ + DAL_E_INVALID_FD = -999, /**< invalid FD */ + DAL_E_TIME_OUT = -998, /**< time out */ + DAL_E_INVALID_ACCESS = -997, /**< invalid access type*/ + DAL_E_MPOOL_NOT_CREATE = -996, /**< mpool not create*/ + DAL_E_INVALID_IRQ = -995, + DAL_E_DEV_NOT_FOUND = -994, + DAL_E_EXCEED_MAX = -993, + DAL_E_NOT_INIT = -992, + DAL_E_ENVALID_MSI_PARA = -991, + + DAL_E_ERROR_CODE_END +}; + +enum dal_access_type_e +{ + DAL_PCI_IO, /* [HB]humber is access as pci device, using ioctrl */ + DAL_SUPER_IF, /* [HB]humber is controled by fpga device */ + DAL_PCIE_MM, /* [GB]Gb is access as pcie device, using mmap */ + DAL_SPECIAL_EMU, /* [GB]special for emulation */ + DAL_MAX_ACCESS_TYPE +}; +typedef enum dal_access_type_e dal_access_type_t; + +struct dal_pci_dev_s +{ + unsigned int busNo; + unsigned int devNo; + unsigned int funNo; +}; +typedef struct dal_pci_dev_s dal_pci_dev_t; + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/centec/centec-dal/dal_kernel.c b/platform/centec/centec-dal/dal_kernel.c new file mode 100644 index 000000000000..23fc6e736575 --- /dev/null +++ b/platform/centec/centec-dal/dal_kernel.c @@ -0,0 +1,2234 @@ +/** + @file dal_kernal.c + + @date 2012-10-18 + + @version v2.0 + + +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) +#include +#endif +#include "dal_kernel.h" +#include "dal_common.h" +#include "dal_mpool.h" +#include +#if defined(SOC_ACTIVE) +#include +#endif +MODULE_AUTHOR("Centec Networks Inc."); +MODULE_DESCRIPTION("DAL kernel module"); +MODULE_LICENSE("GPL"); + +/* DMA memory pool size */ +static char* dma_pool_size; +module_param(dma_pool_size, charp, 0); +MODULE_PARM_DESC(dma_pool_size, + "Specify DMA memory pool size (default 4MB)"); + +/***************************************************************************** + * defines + *****************************************************************************/ +#define MB_SIZE 0x100000 +#define CTC_MAX_INTR_NUM 8 + +#define MEM_MAP_RESERVE SetPageReserved +#define MEM_MAP_UNRESERVE ClearPageReserved + +#define CTC_VENDOR_VID 0xc001 +#define CTC_HUMBER_DEVICE_ID 0x6048 +#define CTC_GOLDENGATE_DEVICE_ID 0xc010 +#define CTC_PCIE_VENDOR_ID 0xcb10 +#define CTC_DUET2_DEVICE_ID 0x7148 +#define CTC_TSINGMA_DEVICE_ID 0x5236 + +#define MEM_MAP_RESERVE SetPageReserved +#define MEM_MAP_UNRESERVE ClearPageReserved + +#define CTC_GREATBELT_DEVICE_ID 0x03e8 /* TBD */ +#define DAL_MAX_CHIP_NUM 8 +#define VIRT_TO_PAGE(p) virt_to_page((p)) +#define DAL_UNTAG_BLOCK 0 +#define DAL_DISCARD_BLOCK 1 +#define DAL_MATCHED_BLOCK 2 +#define DAL_CUR_MATCH_BLOCk 3 +/***************************************************************************** + * typedef + *****************************************************************************/ +typedef enum dal_cpu_mode_type_e +{ + DAL_CPU_MODE_TYPE_NONE, + DAL_CPU_MODE_TYPE_PCIE, /*use pcie*/ + DAL_CPU_MODE_TYPE_LOCAL, /*use local bus*/ + DAL_CPU_MODE_MAX_TYPE, + +} dal_cpu_mode_type_t; +/* Control Data */ +typedef struct dal_isr_s +{ + int irq; + void (* isr)(void*); + void (* isr_knet)(void*); + void* isr_data; + void* isr_knet_data; + int trigger; + int count; + wait_queue_head_t wqh; +} dal_isr_t; + +#if defined(SOC_ACTIVE) +typedef struct dal_kernel_local_dev_s +{ + struct list_head list; + struct platform_device* pci_dev; + + /* PCI I/O mapped base address */ + void __iomem * logic_address; + + /* Physical address */ + uintptr phys_address; +} dal_kern_local_dev_t; +#endif + +typedef struct dal_kernel_pcie_dev_s +{ + struct list_head list; + struct pci_dev* pci_dev; + + /* PCI I/O mapped base address */ + uintptr logic_address; + + /* Physical address */ + unsigned long long phys_address; +} dal_kern_pcie_dev_t; + +typedef struct _dma_segment +{ + struct list_head list; + unsigned long req_size; /* Requested DMA segment size */ + unsigned long blk_size; /* DMA block size */ + unsigned long blk_order; /* DMA block size in alternate format */ + unsigned long seg_size; /* Current DMA segment size */ + unsigned long seg_begin; /* Logical address of segment */ + unsigned long seg_end; /* Logical end address of segment */ + unsigned long* blk_ptr; /* Array of logical DMA block addresses */ + int blk_cnt_max; /* Maximum number of block to allocate */ + int blk_cnt; /* Current number of blocks allocated */ +} dma_segment_t; + +typedef irqreturn_t (*p_func) (int irq, void* dev_id); + +/*************************************************************************** + *declared + ***************************************************************************/ +static unsigned int linux_dal_poll0(struct file* filp, struct poll_table_struct* p); +static unsigned int linux_dal_poll1(struct file* filp, struct poll_table_struct* p); +static unsigned int linux_dal_poll2(struct file* filp, struct poll_table_struct* p); +static unsigned int linux_dal_poll3(struct file* filp, struct poll_table_struct* p); +static unsigned int linux_dal_poll4(struct file* filp, struct poll_table_struct* p); +static unsigned int linux_dal_poll5(struct file* filp, struct poll_table_struct* p); +static unsigned int linux_dal_poll6(struct file* filp, struct poll_table_struct* p); +static unsigned int linux_dal_poll7(struct file* filp, struct poll_table_struct* p); + +/***************************************************************************** + * global variables + *****************************************************************************/ +static void* dal_dev[DAL_MAX_CHIP_NUM]={0}; +static dal_isr_t dal_isr[CTC_MAX_INTR_NUM]; +#if defined(SOC_ACTIVE) +static dal_isr_t dal_int[CTC_MAX_INTR_NUM] = {0}; +#endif +static int dal_chip_num = 0; +static int dal_version = 0; +static int dal_intr_num = 0; +static int use_high_memory = 0; +static unsigned int* dma_virt_base[DAL_MAX_CHIP_NUM]; +static unsigned long long dma_phy_base[DAL_MAX_CHIP_NUM]; +static unsigned int dma_mem_size = 0xc00000; +static unsigned int msi_irq_base[DAL_MAX_CHIP_NUM]; +static unsigned int msi_irq_num[DAL_MAX_CHIP_NUM]; +static unsigned int msi_used = 0; +static unsigned int active_type[DAL_MAX_CHIP_NUM] = {0}; +static struct class *dal_class; + +static LIST_HEAD(_dma_seg); +static int dal_debug = 0; +module_param(dal_debug, int, 0); +MODULE_PARM_DESC(dal_debug, "Set debug level (default 0)"); + +static struct pci_device_id dal_id_table[] = +{ + {PCI_DEVICE(CTC_VENDOR_VID, CTC_GREATBELT_DEVICE_ID)}, + {PCI_DEVICE(CTC_PCIE_VENDOR_ID, CTC_GOLDENGATE_DEVICE_ID)}, + {PCI_DEVICE((CTC_PCIE_VENDOR_ID+1), (CTC_GOLDENGATE_DEVICE_ID+1))}, + {PCI_DEVICE(CTC_PCIE_VENDOR_ID, CTC_DUET2_DEVICE_ID)}, + {PCI_DEVICE(CTC_PCIE_VENDOR_ID, CTC_TSINGMA_DEVICE_ID)}, + {0, }, +}; +#if defined(SOC_ACTIVE) +static const struct of_device_id linux_dal_of_match[] = { + { .compatible = "centec,dal-localbus",}, + {}, +}; +MODULE_DEVICE_TABLE(of, linux_dal_of_match); +#endif + +static wait_queue_head_t poll_intr[CTC_MAX_INTR_NUM]; + +p_func intr_handler_fun[CTC_MAX_INTR_NUM]; + +static int poll_intr_trigger[CTC_MAX_INTR_NUM]; + +static struct file_operations dal_intr_fops[CTC_MAX_INTR_NUM] = +{ + { + .owner = THIS_MODULE, + .poll = linux_dal_poll0, + }, + { + .owner = THIS_MODULE, + .poll = linux_dal_poll1, + }, + { + .owner = THIS_MODULE, + .poll = linux_dal_poll2, + }, + { + .owner = THIS_MODULE, + .poll = linux_dal_poll3, + }, + { + .owner = THIS_MODULE, + .poll = linux_dal_poll4, + }, + { + .owner = THIS_MODULE, + .poll = linux_dal_poll5, + }, + { + .owner = THIS_MODULE, + .poll = linux_dal_poll6, + }, + { + .owner = THIS_MODULE, + .poll = linux_dal_poll7, + }, +}; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)) +#include +#define virt_to_bus virt_to_phys +#define bus_to_virt phys_to_virt +#endif +/***************************************************************************** + * macros + *****************************************************************************/ +#define VERIFY_CHIP_INDEX(n) (n < dal_chip_num) + +#define _KERNEL_INTERUPT_PROCESS +static irqreturn_t +intr0_handler(int irq, void* dev_id) +{ + dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; + + if(poll_intr_trigger[0]) + { + return IRQ_HANDLED; + } + + disable_irq_nosync(irq); + + if (p_dal_isr) + { + if (p_dal_isr->isr) + { + /* kernel mode interrupt handler */ + p_dal_isr->isr(p_dal_isr->isr_data); + } + else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) + { + /* user mode interrupt handler */ + poll_intr_trigger[0] = 1; + wake_up(&poll_intr[0]); + } + + if (p_dal_isr->isr_knet) + { + /* kernel mode interrupt handler */ + p_dal_isr->isr_knet(p_dal_isr->isr_knet_data); + } + } + + return IRQ_HANDLED; +} + +static irqreturn_t +intr1_handler(int irq, void* dev_id) +{ + dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; + + if(poll_intr_trigger[1]) + { + return IRQ_HANDLED; + } + + disable_irq_nosync(irq); + + if (p_dal_isr) + { + if (p_dal_isr->isr) + { + /* kernel mode interrupt handler */ + p_dal_isr->isr(p_dal_isr->isr_data); + } + else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) + { + /* user mode interrupt handler */ + poll_intr_trigger[1] = 1; + wake_up(&poll_intr[1]); + } + } + + return IRQ_HANDLED; +} + +static irqreturn_t +intr2_handler(int irq, void* dev_id) +{ + dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; + if(poll_intr_trigger[2]) + { + return IRQ_HANDLED; + } + disable_irq_nosync(irq); + + if (p_dal_isr) + { + if (p_dal_isr->isr) + { + /* kernel mode interrupt handler */ + p_dal_isr->isr(p_dal_isr->isr_data); + } + else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) + { + /* user mode interrupt handler */ + poll_intr_trigger[2] = 1; + wake_up(&poll_intr[2]); + } + } + + return IRQ_HANDLED; +} + +static irqreturn_t +intr3_handler(int irq, void* dev_id) +{ + dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; + if(poll_intr_trigger[3]) + { + return IRQ_HANDLED; + } + disable_irq_nosync(irq); + + if (p_dal_isr) + { + if (p_dal_isr->isr) + { + /* kernel mode interrupt handler */ + p_dal_isr->isr(p_dal_isr->isr_data); + } + else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) + { + /* user mode interrupt handler */ + poll_intr_trigger[3] = 1; + wake_up(&poll_intr[3]); + } + } + + return IRQ_HANDLED; +} + +static irqreturn_t +intr4_handler(int irq, void* dev_id) +{ + dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; + if(poll_intr_trigger[4]) + { + return IRQ_HANDLED; + } + disable_irq_nosync(irq); + + if (p_dal_isr) + { + if (p_dal_isr->isr) + { + /* kernel mode interrupt handler */ + p_dal_isr->isr(p_dal_isr->isr_data); + } + else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) + { + /* user mode interrupt handler */ + poll_intr_trigger[4] = 1; + wake_up(&poll_intr[4]); + } + } + + return IRQ_HANDLED; +} + +static irqreturn_t +intr5_handler(int irq, void* dev_id) +{ + dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; + if(poll_intr_trigger[5]) + { + return IRQ_HANDLED; + } + disable_irq_nosync(irq); + + if (p_dal_isr) + { + if (p_dal_isr->isr) + { + /* kernel mode interrupt handler */ + p_dal_isr->isr(p_dal_isr->isr_data); + } + else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) + { + /* user mode interrupt handler */ + poll_intr_trigger[5] = 1; + wake_up(&poll_intr[5]); + } + } + + return IRQ_HANDLED; +} + +static irqreturn_t +intr6_handler(int irq, void* dev_id) +{ + dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; + if(poll_intr_trigger[6]) + { + return IRQ_HANDLED; + } + disable_irq_nosync(irq); + + if (p_dal_isr) + { + if (p_dal_isr->isr) + { + /* kernel mode interrupt handler */ + p_dal_isr->isr(p_dal_isr->isr_data); + } + else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) + { + /* user mode interrupt handler */ + poll_intr_trigger[6] = 1; + wake_up(&poll_intr[6]); + } + } + + return IRQ_HANDLED; +} + +static irqreturn_t +intr7_handler(int irq, void* dev_id) +{ + dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; + if(poll_intr_trigger[7]) + { + return IRQ_HANDLED; + } + disable_irq_nosync(irq); + + if (p_dal_isr) + { + if (p_dal_isr->isr) + { + /* kernel mode interrupt handler */ + p_dal_isr->isr(p_dal_isr->isr_data); + } + else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) + { + /* user mode interrupt handler */ + poll_intr_trigger[7] = 1; + wake_up(&poll_intr[7]); + } + } + + return IRQ_HANDLED; +} + +int +dal_interrupt_register(unsigned int irq, int prio, void (* isr)(void*), void* data) +{ + int ret; + unsigned char str[16]; + unsigned char* int_name = NULL; + unsigned int intr_num_tmp = 0; + unsigned int intr_num = CTC_MAX_INTR_NUM; + unsigned long irq_flags = 0; + + if (dal_intr_num >= CTC_MAX_INTR_NUM) + { + printk("Interrupt numbers exceeds max.\n"); + return -1; + } + + if (msi_used) + { + int_name = "dal_msi"; + } + else + { + int_name = "dal_intr"; + } + + + for (intr_num_tmp=0;intr_num_tmp < CTC_MAX_INTR_NUM; intr_num_tmp++) + { + if (irq == dal_isr[intr_num_tmp].irq) + { + if (0 == msi_used) + { + dal_isr[intr_num_tmp].count++; + printk("Interrupt irq %d register count %d.\n", irq, dal_isr[intr_num_tmp].count); + } + return 0; + } + if ((0 == dal_isr[intr_num_tmp].irq) && (CTC_MAX_INTR_NUM == intr_num)) + { + intr_num = intr_num_tmp; + dal_isr[intr_num].count = 0; + } + } + dal_isr[intr_num].irq = irq; + dal_isr[intr_num].isr = isr; + dal_isr[intr_num].isr_data = data; + dal_isr[intr_num].count++; + + init_waitqueue_head(&poll_intr[intr_num]); + + /* only user mode */ + if ((NULL == isr) && (NULL == data)) + { + snprintf(str, 16, "%s%d", "dal_intr", intr_num); + ret = register_chrdev(DAL_DEV_INTR_MAJOR_BASE + intr_num, + str, &dal_intr_fops[intr_num]); + if (ret < 0) + { + printk("Register character device for irq %d failed, ret= %d", irq, ret); + return ret; + } + } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) + irq_flags = 0; +#else + irq_flags = IRQF_DISABLED; +#endif + if ((ret = request_irq(irq, + intr_handler_fun[intr_num], + irq_flags, + int_name, + &dal_isr[intr_num])) < 0) + { + printk("Cannot request irq %d, ret %d.\n", irq, ret); + unregister_chrdev(DAL_DEV_INTR_MAJOR_BASE + intr_num, str); + } + + if (0 == ret) + { + dal_intr_num++; + } + + return ret; +} + +int +dal_interrupt_unregister(unsigned int irq) +{ + unsigned char str[16]; + int intr_idx = 0; + int find_flag = 0; + + /* get intr device index */ + for (intr_idx = 0; intr_idx < CTC_MAX_INTR_NUM; intr_idx++) + { + if (dal_isr[intr_idx].irq == irq) + { + find_flag = 1; + break; + } + } + + if (find_flag == 0) + { + printk ("irq%d is not registered! unregister failed \n", irq); + return -1; + } + + dal_isr[intr_idx].count--; + if (0 != dal_isr[intr_idx].count) + { + printk("Interrupt irq %d unregister count %d.\n", irq, dal_isr[intr_idx].count); + return -1; + } + snprintf(str, 16, "%s%d", "dal_intr", intr_idx); + + unregister_chrdev(DAL_DEV_INTR_MAJOR_BASE + intr_idx, str); + + free_irq(irq, &dal_isr[intr_idx]); + + dal_isr[intr_idx].irq = 0; + + dal_intr_num--; + + return 0; +} + +int +dal_interrupt_connect(unsigned int irq, int prio, void (* isr)(void*), void* data) +{ + int irq_idx = 0; + + for (irq_idx = 0; irq_idx < dal_intr_num; irq_idx++) + { + if (dal_isr[irq_idx].irq == irq) + { + dal_isr[irq_idx].isr_knet = isr; + dal_isr[irq_idx].isr_knet_data = data; + + return 0; + } + } + + return -1; +} + +int +dal_interrupt_disconnect(unsigned int irq) +{ + int irq_idx = 0; + + for (irq_idx = 0; irq_idx < dal_intr_num; irq_idx++) + { + if (dal_isr[irq_idx].irq == irq) + { + dal_isr[irq_idx].isr_knet = NULL; + dal_isr[irq_idx].isr_knet_data = NULL; + + return 0; + } + } + + return -1; +} + +static dal_ops_t g_dal_ops = +{ + interrupt_connect:dal_interrupt_connect, + interrupt_disconnect:dal_interrupt_disconnect, +}; + +int +dal_get_dal_ops(dal_ops_t **dal_ops) +{ + *dal_ops = &g_dal_ops; + + return 0; +} + +int +dal_interrupt_set_en(unsigned int irq, unsigned int enable) +{ + enable ? enable_irq(irq) : disable_irq_nosync(irq); + return 0; +} + +static int +_dal_set_msi_enabe(unsigned int lchip, unsigned int irq_num) +{ + int ret = 0; + dal_kern_pcie_dev_t* dev = NULL; + + if (DAL_CPU_MODE_TYPE_PCIE == active_type[lchip]) + { + dev = dal_dev[lchip]; + if (NULL == dev) + { + return -1; + } + if (irq_num == 1) + { + ret = pci_enable_msi(dev->pci_dev); + if (ret) + { + printk ("msi enable failed!!! lchip = %d, irq_num = %d\n", lchip, irq_num); + pci_disable_msi(dev->pci_dev); + msi_used = 0; + } + + msi_irq_base[lchip] = dev->pci_dev->irq; + msi_irq_num[lchip] = 1; + } + else + { +#if 0 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 79)) + ret = pci_enable_msi_exact(dev->pci_dev, irq_num); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 26, 32)) + ret = pci_enable_msi_block(dev->pci_dev, irq_num); +#else + ret = -1; +#endif + if (ret) + { + printk ("msi enable failed!!! lchip = %d, irq_num = %d\n", lchip, irq_num); + pci_disable_msi(dev->pci_dev); + msi_used = 0; + } + + msi_irq_base[lchip] = dev->pci_dev->irq; + msi_irq_num[lchip] = irq_num; +#endif + } + } + + return ret; +} + +static int +_dal_set_msi_disable(unsigned int lchip) +{ + dal_kern_pcie_dev_t* dev = NULL; + + if (DAL_CPU_MODE_TYPE_PCIE == active_type[lchip]) + { + dev = dal_dev[lchip]; + if (NULL == dev) + { + return -1; + } + pci_disable_msi(dev->pci_dev); + + msi_irq_base[lchip] = 0; + msi_irq_num[lchip] = 0; + } + + return 0; +} + +int +dal_set_msi_cap(unsigned long arg) +{ + int ret = 0; + int index = 0; + dal_msi_info_t msi_info; + + if (copy_from_user(&msi_info, (void*)arg, sizeof(dal_msi_info_t))) + { + return -EFAULT; + } + + printk("####dal_set_msi_cap lchip %d base %d num:%d\n", msi_info.lchip, msi_info.irq_base, msi_info.irq_num); + if (DAL_CPU_MODE_TYPE_PCIE == active_type[msi_info.lchip]) + { + if (msi_info.irq_num > 0) + { + if (0 == msi_used) + { + msi_used = 1; + ret = _dal_set_msi_enabe(msi_info.lchip, msi_info.irq_num); + } + else if ((1 == msi_used) && (msi_info.irq_num != msi_irq_num[msi_info.lchip])) + { + for (index = 0; index < msi_irq_num[msi_info.lchip]; index++) + { + dal_interrupt_unregister(msi_irq_base[msi_info.lchip]+index); + } + _dal_set_msi_disable(msi_info.lchip); + msi_used = 1; + ret = _dal_set_msi_enabe(msi_info.lchip, msi_info.irq_num); + } + } + else + { + msi_used = 0; + ret = _dal_set_msi_disable(msi_info.lchip); + } + } + + return ret; +} + +int +dal_user_interrupt_register(unsigned long arg) +{ + int irq = 0; + if (copy_from_user(&irq, (void*)arg, sizeof(int))) + { + return -EFAULT; + } + printk("####register interrupt irq:%d\n", irq); + return dal_interrupt_register(irq, 0, NULL, NULL); +} + +int +dal_user_interrupt_unregister(unsigned long arg) +{ + int irq = 0; + if (copy_from_user(&irq, (void*)arg, sizeof(int))) + { + return -EFAULT; + } + printk("####unregister interrupt irq:%d\n", irq); + return dal_interrupt_unregister(irq); +} + +int +dal_user_interrupt_set_en(unsigned long arg) +{ + dal_intr_parm_t dal_intr_parm; + + if (copy_from_user(&dal_intr_parm, (void*)arg, sizeof(dal_intr_parm_t))) + { + return -EFAULT; + } + + return dal_interrupt_set_en(dal_intr_parm.irq, dal_intr_parm.enable); +} + +/* + * Function: _dal_dma_segment_free + */ + +/* + * Function: _find_largest_segment + * + * Purpose: + * Find largest contiguous segment from a pool of DMA blocks. + * Parameters: + * dseg - DMA segment descriptor + * Returns: + * 0 on success, < 0 on error. + * Notes: + * Assembly stops if a segment of the requested segment size + * has been obtained. + * + * Lower address bits of the DMA blocks are used as follows: + * 0: Untagged + * 1: Discarded block + * 2: Part of largest contiguous segment + * 3: Part of current contiguous segment + */ +#ifndef DMA_MEM_MODE_PLATFORM +static int +_dal_find_largest_segment(dma_segment_t* dseg) +{ + int i, j, blks, found; + unsigned long seg_begin; + unsigned long seg_end; + unsigned long seg_tmp; + + blks = dseg->blk_cnt; + + /* Clear all block tags */ + for (i = 0; i < blks; i++) + { + dseg->blk_ptr[i] &= ~3; + } + + for (i = 0; i < blks && dseg->seg_size < dseg->req_size; i++) + { + /* First block must be an untagged block */ + if ((dseg->blk_ptr[i] & 3) == DAL_UNTAG_BLOCK) + { + /* Initial segment size is the block size */ + seg_begin = dseg->blk_ptr[i]; + seg_end = seg_begin + dseg->blk_size; + dseg->blk_ptr[i] |= DAL_CUR_MATCH_BLOCk; + + /* Loop looking for adjacent blocks */ + do + { + found = 0; + + for (j = i + 1; j < blks && (seg_end - seg_begin) < dseg->req_size; j++) + { + seg_tmp = dseg->blk_ptr[j]; + /* Check untagged blocks only */ + if ((seg_tmp & 3) == DAL_UNTAG_BLOCK) + { + if (seg_tmp == (seg_begin - dseg->blk_size)) + { + /* Found adjacent block below current segment */ + dseg->blk_ptr[j] |= DAL_CUR_MATCH_BLOCk; + seg_begin = seg_tmp; + found = 1; + } + else if (seg_tmp == seg_end) + { + /* Found adjacent block above current segment */ + dseg->blk_ptr[j] |= DAL_CUR_MATCH_BLOCk; + seg_end += dseg->blk_size; + found = 1; + } + } + } + } + while (found); + + if ((seg_end - seg_begin) > dseg->seg_size) + { + /* The current block is largest so far */ + dseg->seg_begin = seg_begin; + dseg->seg_end = seg_end; + dseg->seg_size = seg_end - seg_begin; + + /* Re-tag current and previous largest segment */ + for (j = 0; j < blks; j++) + { + if ((dseg->blk_ptr[j] & 3) == DAL_CUR_MATCH_BLOCk) + { + /* Tag current segment as the largest */ + dseg->blk_ptr[j] &= ~1; + } + else if ((dseg->blk_ptr[j] & 3) == DAL_MATCHED_BLOCK) + { + /* Discard previous largest segment */ + dseg->blk_ptr[j] ^= 3; + } + } + } + else + { + /* Discard all blocks in current segment */ + for (j = 0; j < blks; j++) + { + if ((dseg->blk_ptr[j] & 3) == DAL_CUR_MATCH_BLOCk) + { + dseg->blk_ptr[j] &= ~2; + } + } + } + } + } + + return 0; +} + +/* + * Function: _alloc_dma_blocks + */ +static int +_dal_alloc_dma_blocks(dma_segment_t* dseg, int blks) +{ + int i, start; + unsigned long addr; + + if (dseg->blk_cnt + blks > dseg->blk_cnt_max) + { + printk("No more DMA blocks\n"); + return -1; + } + + start = dseg->blk_cnt; + dseg->blk_cnt += blks; + + for (i = start; i < dseg->blk_cnt; i++) + { + addr = __get_free_pages(GFP_ATOMIC, dseg->blk_order); + if (addr) + { + dseg->blk_ptr[i] = addr; + } + else + { + printk("DMA allocation failed\n"); + return -1; + } + } + + return 0; +} + +/* + * Function: _dal_dma_segment_alloc + */ +static dma_segment_t* +_dal_dma_segment_alloc(unsigned int size, unsigned int blk_size) +{ + dma_segment_t* dseg; + int i, blk_ptr_size; + unsigned long page_addr; + struct sysinfo si; + + /* Sanity check */ + if (size == 0 || blk_size == 0) + { + return NULL; + } + + /* Allocate an initialize DMA segment descriptor */ + if ((dseg = kmalloc(sizeof(dma_segment_t), GFP_ATOMIC)) == NULL) + { + return NULL; + } + + memset(dseg, 0, sizeof(dma_segment_t)); + dseg->req_size = size; + dseg->blk_size = PAGE_ALIGN(blk_size); + + while ((PAGE_SIZE << dseg->blk_order) < dseg->blk_size) + { + dseg->blk_order++; + } + + si_meminfo(&si); + dseg->blk_cnt_max = (si.totalram << PAGE_SHIFT) / dseg->blk_size; + blk_ptr_size = dseg->blk_cnt_max * sizeof(unsigned long); + /* Allocate an initialize DMA block pool */ + dseg->blk_ptr = kmalloc(blk_ptr_size, GFP_KERNEL); + if (dseg->blk_ptr == NULL) + { + kfree(dseg); + return NULL; + } + + memset(dseg->blk_ptr, 0, blk_ptr_size); + /* Allocate minimum number of blocks */ + _dal_alloc_dma_blocks(dseg, dseg->req_size / dseg->blk_size); + + /* Allocate more blocks until we have a complete segment */ + do + { + _dal_find_largest_segment(dseg); + if (dseg->seg_size >= dseg->req_size) + { + break; + } + } + while (_dal_alloc_dma_blocks(dseg, 8) == 0); + + /* Reserve all pages in the DMA segment and free unused blocks */ + for (i = 0; i < dseg->blk_cnt; i++) + { + if ((dseg->blk_ptr[i] & 3) == 2) + { + dseg->blk_ptr[i] &= ~3; + + for (page_addr = dseg->blk_ptr[i]; + page_addr < dseg->blk_ptr[i] + dseg->blk_size; + page_addr += PAGE_SIZE) + { + MEM_MAP_RESERVE(VIRT_TO_PAGE((void*)page_addr)); + } + } + else if (dseg->blk_ptr[i]) + { + dseg->blk_ptr[i] &= ~3; + free_pages(dseg->blk_ptr[i], dseg->blk_order); + dseg->blk_ptr[i] = 0; + } + } + + return dseg; +} + +/* + * Function: _dal_dma_segment_free + */ +static void +_dal_dma_segment_free(dma_segment_t* dseg) +{ + int i; + unsigned long page_addr; + + if (dseg->blk_ptr) + { + for (i = 0; i < dseg->blk_cnt; i++) + { + if (dseg->blk_ptr[i]) + { + for (page_addr = dseg->blk_ptr[i]; + page_addr < dseg->blk_ptr[i] + dseg->blk_size; + page_addr += PAGE_SIZE) + { + MEM_MAP_UNRESERVE(VIRT_TO_PAGE(page_addr)); + } + + free_pages(dseg->blk_ptr[i], dseg->blk_order); + } + } + + kfree(dseg->blk_ptr); + kfree(dseg); + } +} + +/* + * Function: -dal_pgalloc + */ +static void* +_dal_pgalloc(unsigned int size) +{ + dma_segment_t* dseg; + unsigned int blk_size; + + blk_size = (size < DMA_BLOCK_SIZE) ? size : DMA_BLOCK_SIZE; + if ((dseg = _dal_dma_segment_alloc(size, blk_size)) == NULL) + { + return NULL; + } + + if (dseg->seg_size < size) + { + /* If we didn't get the full size then forget it */ + printk("Notice: Can not get enough memory for requset!!\n"); + printk("actual size:0x%lx, request size:0x%x\n", dseg->seg_size, size); + /*-_dal_dma_segment_free(dseg);*/ + /*-return NULL;*/ + } + + list_add(&dseg->list, &_dma_seg); + return (void*)dseg->seg_begin; +} + +/* + * Function: _dal_pgfree + */ +static int +_dal_pgfree(void* ptr) +{ + struct list_head* pos; + + list_for_each(pos, &_dma_seg) + { + dma_segment_t* dseg = list_entry(pos, dma_segment_t, list); + if (ptr == (void*)dseg->seg_begin) + { + list_del(&dseg->list); + _dal_dma_segment_free(dseg); + return 0; + } + } + return -1; +} +#endif + +static void +dal_alloc_dma_pool(int lchip, int size) +{ +#if defined(DMA_MEM_MODE_PLATFORM) || defined(SOC_ACTIVE) + struct device * dev = NULL; +#endif + + if (use_high_memory) + { + dma_phy_base[lchip] = virt_to_bus(high_memory); + dma_virt_base[lchip] = ioremap_nocache(dma_phy_base[lchip], size); + } + else + { +#if defined(DMA_MEM_MODE_PLATFORM) || defined(SOC_ACTIVE) + if ((DAL_CPU_MODE_TYPE_PCIE != active_type[lchip]) && (DAL_CPU_MODE_TYPE_LOCAL != active_type[lchip])) + { + printk("active type %d error, not cpu and soc!\n", active_type[lchip]); + return; + } + if (DAL_CPU_MODE_TYPE_PCIE == active_type[lchip]) + { + dev = &(((dal_kern_pcie_dev_t*)(dal_dev[lchip]))->pci_dev->dev); + } +#if defined (SOC_ACTIVE) + if (DAL_CPU_MODE_TYPE_LOCAL == active_type[lchip]) + { + dev = &(((dal_kern_local_dev_t*)(dal_dev[lchip]))->pci_dev->dev); + } +#endif + dma_virt_base[lchip] = dma_alloc_coherent(dev, dma_mem_size, + &dma_phy_base[lchip], GFP_KERNEL); + + printk("dma_phy_base[lchip] 0x%llx dma_virt_base[lchip] %p \n", dma_phy_base[lchip], dma_virt_base[lchip]); + printk(KERN_WARNING "########Using DMA_MEM_MODE_PLATFORM \n"); +#else + /* Get DMA memory from kernel */ + dma_virt_base[lchip] = _dal_pgalloc(size); + dma_phy_base[lchip] = virt_to_bus(dma_virt_base[lchip]); + //dma_virt_base [lchip]= ioremap_nocache(dma_phy_base[lchip], size); +#endif + } +} + +static void +dal_free_dma_pool(int lchip) +{ + int ret = 0; +#if defined(DMA_MEM_MODE_PLATFORM) || defined(SOC_ACTIVE) + struct device * dev = NULL; +#endif + + ret = ret; + if (use_high_memory) + { + iounmap(dma_virt_base[lchip]); + } + else + { +#if defined(DMA_MEM_MODE_PLATFORM) || defined(SOC_ACTIVE) + if ((DAL_CPU_MODE_TYPE_PCIE != active_type[lchip]) && (DAL_CPU_MODE_TYPE_LOCAL != active_type[lchip])) + { + return; + } + if (DAL_CPU_MODE_TYPE_PCIE == active_type[lchip]) + { + dev = &(((dal_kern_pcie_dev_t*)(dal_dev[lchip]))->pci_dev->dev); + } +#if defined(SOC_ACTIVE) + if (DAL_CPU_MODE_TYPE_LOCAL == active_type[lchip]) + { + dev = &(((dal_kern_local_dev_t*)(dal_dev[lchip]))->pci_dev->dev); + } +#endif + dma_free_coherent(dev, dma_mem_size, + dma_virt_base[lchip], dma_phy_base[lchip]); +#else + iounmap(dma_virt_base[lchip]); + ret = _dal_pgfree(dma_virt_base[lchip]); + if(ret<0) + { + printk("Dma free memory fail !!!!!! \n"); + } +#endif + } +} + +#define _KERNEL_DAL_IO +static int +_dal_pci_read(unsigned char lchip, unsigned int offset, unsigned int* value) +{ + if (!VERIFY_CHIP_INDEX(lchip)) + { + return -1; + } + + if ((DAL_CPU_MODE_TYPE_PCIE != active_type[lchip]) && (DAL_CPU_MODE_TYPE_LOCAL != active_type[lchip])) + { + return -1; + } + + if (DAL_CPU_MODE_TYPE_PCIE == active_type[lchip]) + { + *value = *(volatile unsigned int*)(((dal_kern_pcie_dev_t*)(dal_dev[lchip]))->logic_address + offset); + } +#if defined(SOC_ACTIVE) + if (DAL_CPU_MODE_TYPE_LOCAL == active_type[lchip]) + { + *value = *(volatile unsigned int*)(((dal_kern_local_dev_t*)(dal_dev[lchip]))->logic_address + offset); + } +#endif + return 0; +} + +int +dal_create_irq_mapping(unsigned long arg) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) + +#ifndef NO_IRQ +#define NO_IRQ (-1) +#endif + dal_irq_mapping_t irq_map; + + if (copy_from_user(&irq_map, (void*)arg, sizeof(dal_irq_mapping_t))) + { + return -EFAULT; + } + + irq_map.sw_irq = irq_create_mapping(NULL, irq_map.hw_irq); + if (irq_map.sw_irq == NO_IRQ) + { + printk("IRQ mapping fail !!!!!! \n"); + return -1; + } + + if (copy_to_user((dal_irq_mapping_t*)arg, (void*)&irq_map, sizeof(dal_irq_mapping_t))) + { + return -EFAULT; + } +#endif + return 0; +} + +int +dal_pci_read(unsigned long arg) +{ + dal_chip_parm_t cmdpara_chip; + + if (copy_from_user(&cmdpara_chip, (void*)arg, sizeof(dal_chip_parm_t))) + { + return -EFAULT; + } + + _dal_pci_read((unsigned char)cmdpara_chip.lchip, (unsigned int)cmdpara_chip.reg_addr, + (unsigned int*)(&(cmdpara_chip.value))); + + if (copy_to_user((dal_chip_parm_t*)arg, (void*)&cmdpara_chip, sizeof(dal_chip_parm_t))) + { + return -EFAULT; + } + + return 0; +} + +static int +_dal_pci_write(unsigned char lchip, unsigned int offset, unsigned int value) +{ + if (!VERIFY_CHIP_INDEX(lchip)) + { + return -1; + } + + if ((DAL_CPU_MODE_TYPE_PCIE != active_type[lchip]) && (DAL_CPU_MODE_TYPE_LOCAL != active_type[lchip])) + { + return -1; + } + + if (DAL_CPU_MODE_TYPE_PCIE == active_type[lchip]) + { + *(volatile unsigned int*)(((dal_kern_pcie_dev_t*)(dal_dev[lchip]))->logic_address + offset) = value; + } +#if defined(SOC_ACTIVE) + if (DAL_CPU_MODE_TYPE_LOCAL == active_type[lchip]) + { + *(volatile unsigned int*)(((dal_kern_local_dev_t*)(dal_dev[lchip]))->logic_address + offset) = value; + } +#endif + + return 0; +} + +int +dal_pci_write(unsigned long arg) +{ + dal_chip_parm_t cmdpara_chip; + + if (copy_from_user(&cmdpara_chip, (void*)arg, sizeof(dal_chip_parm_t))) + { + return -EFAULT; + } + + _dal_pci_write((unsigned char)cmdpara_chip.lchip, (unsigned int)cmdpara_chip.reg_addr, + (unsigned int)cmdpara_chip.value); + + return 0; +} + +int +dal_pci_conf_read(unsigned char lchip, unsigned int offset, unsigned int* value) +{ + if (!VERIFY_CHIP_INDEX(lchip)) + { + return -1; + } + + if (DAL_CPU_MODE_TYPE_PCIE == active_type[lchip]) + { + pci_read_config_dword(((dal_kern_pcie_dev_t*)(dal_dev[lchip]))->pci_dev, offset, value); + } + + return 0; +} + +int +dal_pci_conf_write(unsigned char lchip, unsigned int offset, unsigned int value) +{ + if (!VERIFY_CHIP_INDEX(lchip)) + { + return -1; + } + + if (DAL_CPU_MODE_TYPE_PCIE == active_type[lchip]) + { + pci_write_config_dword(((dal_kern_pcie_dev_t*)(dal_dev[lchip]))->pci_dev, offset, value); + } + + return 0; +} +int +dal_user_read_pci_conf(unsigned long arg) +{ + dal_pci_cfg_ioctl_t dal_cfg; + + if (copy_from_user(&dal_cfg, (void*)arg, sizeof(dal_pci_cfg_ioctl_t))) + { + return -EFAULT; + } + + if (dal_pci_conf_read(dal_cfg.lchip, dal_cfg.offset, &dal_cfg.value)) + { + printk("dal_pci_conf_read failed.\n"); + return -EFAULT; + } + + if (copy_to_user((dal_pci_cfg_ioctl_t*)arg, (void*)&dal_cfg, sizeof(dal_pci_cfg_ioctl_t))) + { + return -EFAULT; + } + + return 0; +} + +int +dal_user_write_pci_conf(unsigned long arg) +{ + dal_pci_cfg_ioctl_t dal_cfg; + + if (copy_from_user(&dal_cfg, (void*)arg, sizeof(dal_pci_cfg_ioctl_t))) + { + return -EFAULT; + } + + return dal_pci_conf_write(dal_cfg.lchip, dal_cfg.offset, dal_cfg.value); +} + +static int +linux_get_device(unsigned long arg) +{ + dal_user_dev_t user_dev; + int lchip = 0; + + if (copy_from_user(&user_dev, (void*)arg, sizeof(user_dev))) + { + return -EFAULT; + } + + user_dev.chip_num = dal_chip_num; + lchip = user_dev.lchip; + + if (lchip < dal_chip_num) + { + if (DAL_CPU_MODE_TYPE_PCIE == active_type[lchip]) + { + user_dev.phy_base0 = (unsigned int)((dal_kern_pcie_dev_t*)(dal_dev[lchip]))->phys_address; + user_dev.phy_base1 = (unsigned int)(((dal_kern_pcie_dev_t*)(dal_dev[lchip]))->phys_address >> 32); + user_dev.bus_no = ((dal_kern_pcie_dev_t*)(dal_dev[lchip]))->pci_dev->bus->number; + user_dev.dev_no = ((dal_kern_pcie_dev_t*)(dal_dev[lchip]))->pci_dev->device; + user_dev.fun_no = ((dal_kern_pcie_dev_t*)(dal_dev[lchip]))->pci_dev->devfn; + user_dev.soc_active = 0; + } +#if defined(SOC_ACTIVE) + if (DAL_CPU_MODE_TYPE_LOCAL == active_type[lchip]) + { + user_dev.phy_base0 = (unsigned int)((dal_kern_pcie_dev_t*)(dal_dev[lchip]))->phys_address; + user_dev.phy_base1 = (unsigned int)(((dal_kern_pcie_dev_t*)(dal_dev[lchip]))->phys_address >> 32); + user_dev.bus_no = 0; + user_dev.dev_no = CTC_TSINGMA_DEVICE_ID; + user_dev.fun_no = 0; + user_dev.soc_active = 1; + } +#endif + } + + if (copy_to_user((dal_user_dev_t*)arg, (void*)&user_dev, sizeof(user_dev))) + { + return -EFAULT; + } + + return 0; +} + +/* set dal version, copy to user */ +static int +linux_get_dal_version(unsigned long arg) +{ + int dal_ver = VERSION_1DOT2; /* set dal version */ + + if (copy_to_user((int*)arg, (void*)&dal_ver, sizeof(dal_ver))) + { + return -EFAULT; + } + + dal_version = dal_ver; /* up sw */ + + return 0; +} + +static int +linux_get_dma_info(unsigned long arg) +{ + dal_dma_info_t dma_para; + + if (copy_from_user(&dma_para, (void*)arg, sizeof(dal_dma_info_t))) + { + return -EFAULT; + } + + dma_para.phy_base = (unsigned int)dma_phy_base[dma_para.lchip]; + dma_para.phy_base_hi = dma_phy_base[dma_para.lchip] >> 32; + dma_para.virt_base = dma_virt_base[dma_para.lchip]; + dma_para.size = dma_mem_size; + + printk("dal dma phy addr: 0x%llx, virt addr: %p.\n", dma_phy_base[dma_para.lchip], dma_virt_base[dma_para.lchip]); + + if (copy_to_user((dal_dma_info_t*)arg, (void*)&dma_para, sizeof(dal_dma_info_t))) + { + return -EFAULT; + } + + return 0; +} + +static int +dal_get_msi_info(unsigned long arg) +{ + dal_msi_info_t msi_para; + unsigned int lchip = 0; + + /* get lchip form user mode */ + if (copy_from_user(&msi_para, (void*)arg, sizeof(dal_msi_info_t))) + { + return -EFAULT; + } + lchip = msi_para.lchip; + + if (DAL_CPU_MODE_TYPE_PCIE == active_type[lchip]) + { + msi_para.irq_base = msi_irq_base[lchip]; + msi_para.irq_num = msi_irq_num[lchip]; + } +#if defined(SOC_ACTIVE) + if (DAL_CPU_MODE_TYPE_LOCAL == active_type[lchip]) + { + msi_para.irq_base = dal_int[0].irq; + msi_para.irq_num = CTC_MAX_INTR_NUM; + } +#endif + + /* send msi info to user mode */ + if (copy_to_user((dal_msi_info_t*)arg, (void*)&msi_para, sizeof(dal_msi_info_t))) + { + return -EFAULT; + } + + return 0; +} + + +static int +dal_get_intr_info(unsigned long arg) +{ + dal_intr_info_t intr_para; + unsigned int intr_num = 0; + + /* get lchip form user mode */ + if (copy_from_user(&intr_para, (void*)arg, sizeof(dal_intr_info_t))) + { + return -EFAULT; + } + + intr_para.irq_idx = CTC_MAX_INTR_NUM; + for (intr_num=0; intr_num< CTC_MAX_INTR_NUM; intr_num++) + { + if (intr_para.irq == dal_isr[intr_num].irq) + { + intr_para.irq_idx = intr_num; + break; + } + } + + if (CTC_MAX_INTR_NUM == intr_para.irq_idx) + { + printk("Interrupt %d cann't find.\n", intr_para.irq); + } + /* send msi info to user mode */ + if (copy_to_user((dal_intr_info_t*)arg, (void*)&intr_para, sizeof(dal_intr_info_t))) + { + return -EFAULT; + } + + return 0; +} + +int +dal_cache_inval(unsigned long ptr, unsigned int length) +{ +#ifdef DMA_CACHE_COHERENCE_EN + /*dma_cache_wback_inv((unsigned long)intr_para.ptr, intr_para.length);*/ + + dma_sync_single_for_cpu(NULL, ptr, length, DMA_FROM_DEVICE); + + /*dma_cache_sync(NULL, (void*)bus_to_virt(intr_para.ptr), intr_para.length, DMA_FROM_DEVICE);*/ +#endif + return 0; +} + +int +dal_cache_flush(unsigned long ptr, unsigned int length) +{ +#ifdef DMA_CACHE_COHERENCE_EN + /*dma_cache_wback_inv(intr_para.ptr, intr_para.length);*/ + + dma_sync_single_for_device(NULL, ptr, length, DMA_TO_DEVICE); + + /*dma_cache_sync(NULL, (void*)bus_to_virt(intr_para.ptr), intr_para.length, DMA_TO_DEVICE);*/ +#endif + return 0; +} + +static int +dal_user_cache_inval(unsigned long arg) +{ +#ifndef DMA_MEM_MODE_PLATFORM + dal_dma_cache_info_t intr_para; + + if (copy_from_user(&intr_para, (void*)arg, sizeof(dal_dma_cache_info_t))) + { + return -EFAULT; + } + + dal_cache_inval(intr_para.ptr, intr_para.length); +#endif + return 0; +} + +static int +dal_user_cache_flush(unsigned long arg) +{ +#ifndef DMA_MEM_MODE_PLATFORM + dal_dma_cache_info_t intr_para; + + if (copy_from_user(&intr_para, (void*)arg, sizeof(dal_dma_cache_info_t))) + { + return -EFAULT; + } + + dal_cache_flush(intr_para.ptr, intr_para.length); +#endif + return 0; +} + +#if defined(SOC_ACTIVE) +static int linux_dal_local_probe(struct platform_device *pdev) +{ + dal_kern_local_dev_t* dev = NULL; + unsigned int temp = 0; + unsigned int lchip = 0; + int i = 0; + int irq = 0; + struct resource * res = NULL; + + printk(KERN_WARNING "********found soc dal device*****\n"); + + for (lchip = 0; lchip < DAL_MAX_CHIP_NUM; lchip ++) + { + if (NULL == dal_dev[lchip]) + { + break; + } + } + + if (lchip >= DAL_MAX_CHIP_NUM) + { + printk("Exceed max local chip num\n"); + return -1; + } + + if (NULL == dal_dev[lchip]) + { + dal_dev[lchip] = kmalloc(sizeof(dal_kern_local_dev_t), GFP_ATOMIC); + if (NULL == dal_dev[lchip]) + { + printk("no memory for dal soc dev, lchip %d\n", lchip); + return -1; + } + } + dev = dal_dev[lchip]; + if (NULL == dev) + { + printk("Cannot obtain PCI resources\n"); + } + + lchip = lchip; + dal_chip_num += 1; + + dev->pci_dev = pdev; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + dev->phys_address = res->start; + dev->logic_address = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(dev->logic_address)) + { + kfree(dev); + return PTR_ERR(dev->logic_address); + } + + for (i = 0; i < CTC_MAX_INTR_NUM; i++) + { + irq = platform_get_irq(pdev, i); + if (irq < 0) + { + printk( "can't get irq number\n"); + kfree(dev); + return irq; + } + dal_int[i].irq = irq; + printk( "irq %d vector %d\n", i, irq); + } + + active_type[lchip] = DAL_CPU_MODE_TYPE_LOCAL; + _dal_pci_read(lchip, 0x48, &temp); + if (((temp >> 8) & 0xffff) == 0x3412) + { + printk("Little endian Cpu detected!!! \n"); + _dal_pci_write(lchip, 0x48, 0xFFFFFFFF); + } + + /* alloc dma_mem_size for every chip */ + if (dma_mem_size) + { + dal_alloc_dma_pool(lchip, dma_mem_size); + + /*add check Dma memory pool cannot cross 4G space*/ + if ((0==(dma_phy_base[lchip]>>32)) && (0!=((dma_phy_base[lchip]+dma_mem_size)>>32))) + { + printk("Dma malloc memory cross 4G space!!!!!! \n"); + kfree(dev); + return -1; + } + } + + printk(KERN_WARNING "linux_dal_probe end*****\n"); + + return 0; +} +#endif + +int linux_dal_pcie_probe(struct pci_dev* pdev, const struct pci_device_id* id) +{ + dal_kern_pcie_dev_t* dev = NULL; + unsigned int temp = 0; + unsigned int lchip = 0; + int bar = 0; + int ret = 0; + /*unsigned int devid = 0;*/ + + printk(KERN_WARNING "********found cpu dal device*****\n"); + + for (lchip = 0; lchip < DAL_MAX_CHIP_NUM; lchip ++) + { + if (NULL == dal_dev[lchip]) + { + break; + } + } + + if (lchip >= DAL_MAX_CHIP_NUM) + { + printk("Exceed max local chip num\n"); + return -1; + } + + if (NULL == dal_dev[lchip]) + { + dal_dev[lchip] = kmalloc(sizeof(dal_kern_pcie_dev_t), GFP_ATOMIC); + if (NULL == dal_dev[lchip]) + { + printk("no memory for dal cpu dev, lchip %d\n", lchip); + return -1; + } + } + dev = dal_dev[lchip]; + if (NULL == dev) + { + printk("Cannot obtain PCI resources\n"); + } + + lchip = lchip; + dal_chip_num += 1; + + dev->pci_dev = pdev; + + if (pdev->device == 0x5236) + { + printk("use bar2 to config memory space\n"); + bar = 2; + } + + if (pci_enable_device(pdev) < 0) + { + printk("Cannot enable PCI device: vendor id = %x, device id = %x\n", + pdev->vendor, pdev->device); + } + + ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); + if (ret) + { + ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (ret) + { + printk("Could not set PCI DMA Mask\n"); + kfree(dev); + return ret; + } + } + + if (pci_request_regions(pdev, DAL_NAME) < 0) + { + printk("Cannot obtain PCI resources\n"); + } + + dev->phys_address = pci_resource_start(pdev, bar); + dev->logic_address = (uintptr)ioremap_nocache(dev->phys_address, + pci_resource_len(dev->pci_dev, bar)); + + active_type[lchip] = DAL_CPU_MODE_TYPE_PCIE; + + _dal_pci_read(lchip, 0x48, &temp); + if (((temp >> 8) & 0xffff) == 0x3412) + { + printk("Little endian Cpu detected!!! \n"); + _dal_pci_write(lchip, 0x48, 0xFFFFFFFF); + } + + pci_set_master(pdev); + + + /* alloc dma_mem_size for every chip */ + if (dma_mem_size) + { + dal_alloc_dma_pool(lchip, dma_mem_size); + + /*add check Dma memory pool cannot cross 4G space*/ + if ((0==(dma_phy_base[lchip]>>32)) && (0!=((dma_phy_base[lchip]+dma_mem_size)>>32))) + { + printk("Dma malloc memory cross 4G space!!!!!! \n"); + kfree(dev); + return -1; + } + } + + printk(KERN_WARNING "linux_dal_probe end*****\n"); + + return 0; +} + +#if defined(SOC_ACTIVE) +static int +linux_dal_local_remove(struct platform_device *pdev) +{ + unsigned int lchip = 0; + unsigned int flag = 0; + dal_kern_local_dev_t* dev = NULL; + + for (lchip = 0; lchip < DAL_MAX_CHIP_NUM; lchip ++) + { + dev = dal_dev[lchip]; + if ((NULL != dev )&& (pdev == dev->pci_dev)) + { + flag = 1; + break; + } + } + + if (1 == flag) + { + dal_free_dma_pool(lchip); + dev->pci_dev = NULL; + kfree(dev); + dal_chip_num--; + active_type[lchip] = DAL_CPU_MODE_TYPE_NONE; + } + + return 0; +} +#endif + +void +linux_dal_pcie_remove(struct pci_dev* pdev) +{ + unsigned int lchip = 0; + unsigned int flag = 0; + dal_kern_pcie_dev_t* dev = NULL; + + for (lchip = 0; lchip < DAL_MAX_CHIP_NUM; lchip ++) + { + dev = dal_dev[lchip]; + if ((NULL != dev )&& (pdev == dev->pci_dev)) + { + flag = 1; + break; + } + } + + if (1 == flag) + { + dal_free_dma_pool(lchip); + pci_release_regions(pdev); + pci_disable_device(pdev); + dev->pci_dev = NULL; + kfree(dev); + dal_chip_num--; + active_type[lchip] = DAL_CPU_MODE_TYPE_NONE; + } +} + +#ifdef CONFIG_COMPAT +static long +linux_dal_ioctl(struct file* file, + unsigned int cmd, unsigned long arg) +#else + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)) +static long +linux_dal_ioctl(struct file* file, + unsigned int cmd, unsigned long arg) +#else +static int +linux_dal_ioctl(struct inode* inode, struct file* file, + unsigned int cmd, unsigned long arg) +#endif + +#endif +{ + switch (cmd) + { + + case CMD_READ_CHIP: + return dal_pci_read(arg); + + case CMD_WRITE_CHIP: + return dal_pci_write(arg); + + case CMD_GET_DEVICES: + return linux_get_device(arg); + + case CMD_GET_DAL_VERSION: + return linux_get_dal_version(arg); + + case CMD_GET_DMA_INFO: + return linux_get_dma_info(arg); + + case CMD_PCI_CONFIG_READ: + return dal_user_read_pci_conf(arg); + + case CMD_PCI_CONFIG_WRITE: + return dal_user_write_pci_conf(arg); + + case CMD_REG_INTERRUPTS: + return dal_user_interrupt_register(arg); + + case CMD_UNREG_INTERRUPTS: + return dal_user_interrupt_unregister(arg); + + case CMD_EN_INTERRUPTS: + return dal_user_interrupt_set_en(arg); + + case CMD_SET_MSI_CAP: + return dal_set_msi_cap(arg); + + case CMD_GET_MSI_INFO: + return dal_get_msi_info(arg); + + case CMD_IRQ_MAPPING: + return dal_create_irq_mapping(arg); + + case CMD_GET_INTR_INFO: + return dal_get_intr_info(arg); + + case CMD_CACHE_INVAL: + return dal_user_cache_inval(arg); + + case CMD_CACHE_FLUSH: + return dal_user_cache_flush(arg); + + default: + break; + } + + return 0; +} + +static unsigned int +linux_dal_poll0(struct file* filp, struct poll_table_struct* p) +{ + unsigned int mask = 0; + unsigned long flags; + + poll_wait(filp, &poll_intr[0], p); + local_irq_save(flags); + if (poll_intr_trigger[0]) + { + poll_intr_trigger[0] = 0; + mask |= POLLIN | POLLRDNORM; + } + + local_irq_restore(flags); + + return mask; +} + +static unsigned int +linux_dal_poll1(struct file* filp, struct poll_table_struct* p) +{ + unsigned int mask = 0; + unsigned long flags; + + poll_wait(filp, &poll_intr[1], p); + local_irq_save(flags); + if (poll_intr_trigger[1]) + { + poll_intr_trigger[1] = 0; + mask |= POLLIN | POLLRDNORM; + } + + local_irq_restore(flags); + + return mask; +} + +static unsigned int +linux_dal_poll2(struct file* filp, struct poll_table_struct* p) +{ + unsigned int mask = 0; + unsigned long flags; + + poll_wait(filp, &poll_intr[2], p); + local_irq_save(flags); + if (poll_intr_trigger[2]) + { + poll_intr_trigger[2] = 0; + mask |= POLLIN | POLLRDNORM; + } + + local_irq_restore(flags); + + return mask; +} + +static unsigned int +linux_dal_poll3(struct file* filp, struct poll_table_struct* p) +{ + unsigned int mask = 0; + unsigned long flags; + + poll_wait(filp, &poll_intr[3], p); + local_irq_save(flags); + if (poll_intr_trigger[3]) + { + poll_intr_trigger[3] = 0; + mask |= POLLIN | POLLRDNORM; + } + + local_irq_restore(flags); + + return mask; +} + +static unsigned int +linux_dal_poll4(struct file* filp, struct poll_table_struct* p) +{ + unsigned int mask = 0; + unsigned long flags; + + poll_wait(filp, &poll_intr[4], p); + local_irq_save(flags); + if (poll_intr_trigger[4]) + { + poll_intr_trigger[4] = 0; + mask |= POLLIN | POLLRDNORM; + } + + local_irq_restore(flags); + + return mask; +} + +static unsigned int +linux_dal_poll5(struct file* filp, struct poll_table_struct* p) +{ + unsigned int mask = 0; + unsigned long flags; + + poll_wait(filp, &poll_intr[5], p); + local_irq_save(flags); + if (poll_intr_trigger[5]) + { + poll_intr_trigger[5] = 0; + mask |= POLLIN | POLLRDNORM; + } + + local_irq_restore(flags); + + return mask; +} + +static unsigned int +linux_dal_poll6(struct file* filp, struct poll_table_struct* p) +{ + unsigned int mask = 0; + unsigned long flags; + + poll_wait(filp, &poll_intr[6], p); + local_irq_save(flags); + if (poll_intr_trigger[6]) + { + poll_intr_trigger[6] = 0; + mask |= POLLIN | POLLRDNORM; + } + + local_irq_restore(flags); + + return mask; +} + +static unsigned int +linux_dal_poll7(struct file* filp, struct poll_table_struct* p) +{ + unsigned int mask = 0; + unsigned long flags; + + poll_wait(filp, &poll_intr[7], p); + local_irq_save(flags); + if (poll_intr_trigger[7]) + { + poll_intr_trigger[7] = 0; + mask |= POLLIN | POLLRDNORM; + } + + local_irq_restore(flags); + + return mask; +} + +static struct pci_driver linux_dal_pcie_driver = +{ + .name = DAL_NAME, + .id_table = dal_id_table, + .probe = linux_dal_pcie_probe, + .remove = linux_dal_pcie_remove, +}; +#if defined(SOC_ACTIVE) +static struct platform_driver linux_dal_local_driver = +{ + .probe = linux_dal_local_probe, + .remove = linux_dal_local_remove, + .driver = { + .name = DAL_NAME, + .of_match_table = of_match_ptr(linux_dal_of_match), + }, +}; +#endif + +static struct file_operations fops = +{ + .owner = THIS_MODULE, +#ifdef CONFIG_COMPAT + .compat_ioctl = linux_dal_ioctl, + .unlocked_ioctl = linux_dal_ioctl, +#else +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)) + .unlocked_ioctl = linux_dal_ioctl, +#else + .ioctl = linux_dal_ioctl, +#endif +#endif +}; + +static int __init +linux_dal_init(void) +{ + int ret = 0; + + /* Get DMA memory pool size form dal.ok input param, or use default dma_mem_size */ + if (dma_pool_size) + { + if ((dma_pool_size[strlen(dma_pool_size) - 1] & ~0x20) == 'M') + { + dma_mem_size = simple_strtoul(dma_pool_size, NULL, 0); + printk("dma_mem_size: 0x%x \n", dma_mem_size); + + dma_mem_size *= MB_SIZE; + } + else + { + printk("DMA memory pool size must be specified as e.g. dma_pool_size=8M\n"); + } + + if (dma_mem_size & (dma_mem_size - 1)) + { + printk("dma_mem_size must be a power of 2 (1M, 2M, 4M, 8M etc.)\n"); + dma_mem_size = 0; + } + } + + ret = register_chrdev(DAL_DEV_MAJOR, DAL_NAME, &fops); + if (ret < 0) + { + printk(KERN_WARNING "Register linux_dal device, ret %d\n", ret); + return ret; + } + + ret = pci_register_driver(&linux_dal_pcie_driver); + if (ret < 0) + { + printk(KERN_WARNING "Register ASIC PCI driver failed, ret %d\n", ret); + return ret; + } +#if defined(SOC_ACTIVE) + ret = platform_driver_register(&linux_dal_local_driver); + if (ret < 0) + { + printk(KERN_WARNING "Register ASIC LOCALBUS driver failed, ret %d\n", ret); + } +#endif + + /* alloc /dev/linux_dal node */ + dal_class = class_create(THIS_MODULE, DAL_NAME); + device_create(dal_class, NULL, MKDEV(DAL_DEV_MAJOR, 0), NULL, DAL_NAME); + + /* init interrupt function */ + intr_handler_fun[0] = intr0_handler; + intr_handler_fun[1] = intr1_handler; + intr_handler_fun[2] = intr2_handler; + intr_handler_fun[3] = intr3_handler; + intr_handler_fun[4] = intr4_handler; + intr_handler_fun[5] = intr5_handler; + intr_handler_fun[6] = intr6_handler; + intr_handler_fun[7] = intr7_handler; + + return ret; +} + +static void __exit +linux_dal_exit(void) +{ + device_destroy(dal_class, MKDEV(DAL_DEV_MAJOR, 0)); + class_destroy(dal_class); + unregister_chrdev(DAL_DEV_MAJOR, "linux_dal"); + pci_unregister_driver(&linux_dal_pcie_driver); +#if defined(SOC_ACTIVE) + platform_driver_unregister(&linux_dal_local_driver); +#endif +} + +module_init(linux_dal_init); +module_exit(linux_dal_exit); +EXPORT_SYMBOL(dal_get_dal_ops); +EXPORT_SYMBOL(dal_cache_inval); +EXPORT_SYMBOL(dal_cache_flush); + diff --git a/platform/centec/centec-dal/dal_kernel.h b/platform/centec/centec-dal/dal_kernel.h new file mode 100644 index 000000000000..1055dba26952 --- /dev/null +++ b/platform/centec/centec-dal/dal_kernel.h @@ -0,0 +1,180 @@ +/** + @file dal_kernel_io.h + + @author Copyright (C) 2012 Centec Networks Inc. All rights reserved. + + @date 2012-4-9 + + @version v2.0 + +*/ +#ifndef _DAL_KERNEL_H_ +#define _DAL_KERNEL_H_ +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(CONFIG_RESOURCES_64BIT) || defined(CONFIG_PHYS_ADDR_T_64BIT) +#define PHYS_ADDR_IS_64BIT +#endif + +#ifndef SDK_IN_USERMODE +#ifdef PHYS_ADDR_IS_64BIT +typedef long long intptr; +typedef unsigned long long uintptr; +#else +typedef int intptr; +typedef unsigned int uintptr; +#endif +#endif + +#ifndef STATIC +#define STATIC static +#endif +#define DAL_PCI_READ_ADDR 0x0 +#define DAL_PCI_READ_DATA 0xc +#define DAL_PCI_WRITE_ADDR 0x8 +#define DAL_PCI_WRITE_DATA 0x4 +#define DAL_PCI_STATUS 0x10 + +#define DAL_PCI_STATUS_IN_PROCESS 31 +#define DAL_PCI_STATUS_BAD_PARITY 5 +#define DAL_PCI_STATUS_CPU_ACCESS_ERR 4 +#define DAL_PCI_STATUS_READ_CMD 3 +#define DAL_PCI_STATUS_REGISTER_ERR 1 +#define DAL_PCI_STATUS_REGISTER_ACK 0 + +#define DAL_PCI_ACCESS_TIMEOUT 0x64 + +#define DAL_NAME "linux_dal" /* "linux_dal" */ + +#define DAL_DEV_MAJOR 198 + +#define DAL_DEV_INTR_MAJOR_BASE 200 + +#define DAL_DEV_NAME "/dev/" DAL_NAME +#define DAL_ONE_KB 1024 +#define DAL_ONE_MB (1024*1024) +struct dal_chip_parm_s +{ + unsigned int lchip; /*tmp should be uint8*/ + unsigned int fpga_id; /*tmp add*/ + unsigned int reg_addr; + unsigned int value; +}; +typedef struct dal_chip_parm_s dal_chip_parm_t; + +struct dal_intr_parm_s +{ + unsigned int irq; + unsigned int enable; +}; +typedef struct dal_intr_parm_s dal_intr_parm_t; + +struct dal_irq_mapping_s +{ + unsigned int hw_irq; + unsigned int sw_irq; +}; +typedef struct dal_irq_mapping_s dal_irq_mapping_t; + +struct dal_user_dev_s +{ + unsigned int chip_num; /*output: local chip number*/ + unsigned int lchip; /*input: local chip id*/ + unsigned int phy_base0; /* low 32bits physical base address */ + unsigned int phy_base1; /* high 32bits physical base address */ + unsigned int bus_no; + unsigned int dev_no; + unsigned int fun_no; + unsigned int soc_active; + void* virt_base[2]; /* !!!!warning!!!!Virtual base address; pointer void* must be last member */ +}; +typedef struct dal_user_dev_s dal_user_dev_t; + +struct dal_pci_cfg_ioctl_s +{ + unsigned int lchip; /* Device ID */ + unsigned int offset; + unsigned int value; +}; +typedef struct dal_pci_cfg_ioctl_s dal_pci_cfg_ioctl_t; + +struct dal_msi_info_s +{ + unsigned int lchip; + unsigned int irq_base; + unsigned int irq_num; +}; +typedef struct dal_msi_info_s dal_msi_info_t; + +struct dal_intr_info_s +{ + unsigned int irq; + unsigned int irq_idx; +}; +typedef struct dal_intr_info_s dal_intr_info_t; + +struct dal_dma_cache_info_s +{ + unsigned long ptr; + unsigned int length; +}; +typedef struct dal_dma_cache_info_s dal_dma_cache_info_t; + +#define CMD_MAGIC 'C' +#define CMD_WRITE_CHIP _IO(CMD_MAGIC, 0) /* for humber ioctrol*/ +#define CMD_READ_CHIP _IO(CMD_MAGIC, 1) /* for humber ioctrol*/ +#define CMD_GET_DEVICES _IO(CMD_MAGIC, 2) +#define CMD_GET_DAL_VERSION _IO(CMD_MAGIC, 3) +#define CMD_PCI_CONFIG_WRITE _IO(CMD_MAGIC, 4) +#define CMD_PCI_CONFIG_READ _IO(CMD_MAGIC, 5) +#define CMD_GET_DMA_INFO _IO(CMD_MAGIC, 6) +#define CMD_REG_INTERRUPTS _IO(CMD_MAGIC, 7) +#define CMD_UNREG_INTERRUPTS _IO(CMD_MAGIC, 8) +#define CMD_EN_INTERRUPTS _IO(CMD_MAGIC, 9) +#define CMD_I2C_READ _IO(CMD_MAGIC, 10) +#define CMD_I2C_WRITE _IO(CMD_MAGIC, 11) +#define CMD_GET_MSI_INFO _IO(CMD_MAGIC, 12) +#define CMD_SET_MSI_CAP _IO(CMD_MAGIC, 13) +#define CMD_IRQ_MAPPING _IO(CMD_MAGIC, 14) +#define CMD_GET_INTR_INFO _IO(CMD_MAGIC, 15) +#define CMD_CACHE_INVAL _IO(CMD_MAGIC, 16) +#define CMD_CACHE_FLUSH _IO(CMD_MAGIC, 17) +#define CMD_GET_KNET_VERSION _IO(CMD_MAGIC, 18) +#define CMD_CONNECT_INTERRUPTS _IO(CMD_MAGIC, 19) +#define CMD_DISCONNECT_INTERRUPTS _IO(CMD_MAGIC, 20) +#define CMD_SET_DMA_INFO _IO(CMD_MAGIC, 21) +#define CMD_REG_DMA_CHAN _IO(CMD_MAGIC, 22) +#define CMD_HANDLE_NETIF _IO(CMD_MAGIC, 23) + +enum dal_version_e +{ + VERSION_MIN, + VERSION_1DOT0, + VERSION_1DOT1, + VERSION_1DOT2, + + VERSION_MAX +}; +typedef enum dal_version_e dal_version_t; + +struct dal_ops_s { + int (*interrupt_connect)(unsigned int irq, int prio, void (*)(void*), void *data); + int (*interrupt_disconnect)(unsigned int irq); +}; +typedef struct dal_ops_s dal_ops_t; + +/* We try to assemble a contiguous segment from chunks of this size */ +#define DMA_BLOCK_SIZE (512 * DAL_ONE_KB) + +extern int dal_get_dal_ops(dal_ops_t **dal_ops); +extern int dal_cache_inval(unsigned long ptr, unsigned int length); +extern int dal_cache_flush(unsigned long ptr, unsigned int length); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/centec/centec-dal/dal_mpool.c b/platform/centec/centec-dal/dal_mpool.c new file mode 100644 index 000000000000..f3b5f85e5ecd --- /dev/null +++ b/platform/centec/centec-dal/dal_mpool.c @@ -0,0 +1,360 @@ + +/*SYSTEM MODIFIED, Added by weij for compile SDK, 2017-09-11*/ +//#include "sal.h" +#include "dal_mpool.h" +#define DAL_MAX_CHIP_NUM 32 +#ifdef __KERNEL__ +#include +#include + +#define DAL_MALLOC(x) kmalloc(x, GFP_ATOMIC) +#define DAL_FREE(x) kfree(x) + +static spinlock_t dal_mpool_lock[DAL_MAX_CHIP_NUM]; +#define MPOOL_LOCK_INIT() spin_lock_init(&dal_mpool_lock[lchip]) +#define MPOOL_LOCK_DEINIT() +#define MPOOL_LOCK() unsigned long flags; spin_lock_irqsave(&dal_mpool_lock[lchip], flags) +#define MPOOL_UNLOCK() spin_unlock_irqrestore(&dal_mpool_lock[lchip], flags) +#define DAL_PRINT(fmt,arg...) printk(fmt,##arg) +#else /* !__KERNEL__*/ + +#include +#include "sal.h" +#define DAL_MALLOC(x) sal_malloc(x) +#define DAL_FREE(x) sal_free(x) +static sal_mutex_t* dal_mpool_lock[DAL_MAX_CHIP_NUM]; +#define MPOOL_LOCK_INIT() sal_mutex_create(&dal_mpool_lock[lchip]) +#define MPOOL_LOCK_DEINIT() sal_mutex_destroy(dal_mpool_lock[lchip]) +#define MPOOL_LOCK() sal_mutex_lock(dal_mpool_lock[lchip]) +#define MPOOL_UNLOCK() sal_mutex_unlock(dal_mpool_lock[lchip]) +#define DAL_PRINT(fmt,arg...) sal_printf(fmt,##arg) + +#endif /* __KERNEL__ */ +dal_mpool_mem_t* g_free_block_ptr = NULL; + +/* System cache line size */ +#ifndef DAL_CACHE_LINE_BYTES +#define DAL_CACHE_LINE_BYTES 256 +#endif + +static dal_mpool_mem_t* p_desc_pool[DAL_MAX_CHIP_NUM] = {0}; +static dal_mpool_mem_t* p_data_pool[DAL_MAX_CHIP_NUM] = {0}; + +/*SYSTEM MODIFIED, Added by weij for compile SDK, 2017-09-11*/ +int +dal_mpool_init(uint8_t lchip) +{ + MPOOL_LOCK_INIT(); + return 0; +} +/*SYSTEM MODIFIED, Added by weij for compile SDK, 2017-09-11*/ +int +dal_mpool_deinit(uint8_t lchip) +{ + MPOOL_LOCK_DEINIT(); + return 0; +} + +dal_mpool_mem_t* +_dal_mpool_create(void* base, int size, int type) +{ + dal_mpool_mem_t* head = NULL; + dal_mpool_mem_t* tail = NULL; + + head = (dal_mpool_mem_t*)DAL_MALLOC(sizeof(dal_mpool_mem_t)); + if (head == NULL) + { + return NULL; + } + + tail = (dal_mpool_mem_t*)DAL_MALLOC(sizeof(dal_mpool_mem_t)); + if (tail == NULL) + { + DAL_FREE(head); + return NULL; + } + + head->size = tail->size = 0; + head->type = type; + head->address = base; + tail->address = head->address + size; + head->next = tail; + tail->next = NULL; + + return head; +} + +dal_mpool_mem_t* +dal_mpool_create(unsigned char lchip, void* base, int size) +{ + dal_mpool_mem_t* head = NULL; + int mod = (int)(((unsigned long)base) & (DAL_CACHE_LINE_BYTES - 1)); + + MPOOL_LOCK(); + + if (mod) + { + base = (char*)base + (DAL_CACHE_LINE_BYTES - mod); + size -= (DAL_CACHE_LINE_BYTES - mod); + } + + size &= ~(DAL_CACHE_LINE_BYTES - 1); + + /* init for common linkptr, only used for GB */ + head = _dal_mpool_create(base, size, DAL_MPOOL_TYPE_USELESS); + if (NULL == head) + { + MPOOL_UNLOCK(); + return NULL; + } + + /* init for desc linkptr */ + p_desc_pool[lchip] = _dal_mpool_create(base, DAL_MPOOL_MAX_DESX_SIZE, DAL_MPOOL_TYPE_DESC); + if (NULL == p_desc_pool[lchip]) + { + MPOOL_UNLOCK(); + DAL_FREE(head->next); + DAL_FREE(head); + return NULL; + } + + /* init for data linkptr */ + p_data_pool[lchip] = _dal_mpool_create(((char*)base+DAL_MPOOL_MAX_DESX_SIZE), (size - DAL_MPOOL_MAX_DESX_SIZE), DAL_MPOOL_TYPE_DATA); + if (NULL == p_data_pool[lchip]) + { + MPOOL_UNLOCK(); + DAL_FREE(head->next); + DAL_FREE(head); + DAL_FREE(p_desc_pool[lchip]->next); + DAL_FREE(p_desc_pool[lchip]); + return NULL; + } + + MPOOL_UNLOCK(); + + return head; +} + +dal_mpool_mem_t* +_dal_mpool_alloc_comon(dal_mpool_mem_t* ptr, int size, int type) +{ + dal_mpool_mem_t* new_ptr = NULL; + + while (ptr && ptr->next) + { + if (ptr->next->address - (ptr->address + ptr->size) >= size) + { + break; + } + + ptr = ptr->next; + } + + if (!(ptr && ptr->next)) + { + return NULL; + } + + new_ptr = DAL_MALLOC(sizeof(dal_mpool_mem_t)); + if (!new_ptr) + { + return NULL; + } + + new_ptr->type = type; + new_ptr->address = ptr->address + ptr->size; + new_ptr->size = size; + new_ptr->next = ptr->next; + ptr->next = new_ptr; + + return new_ptr; +} + +void* +dal_mpool_alloc(unsigned char lchip, dal_mpool_mem_t* pool, int size, int type) +{ + dal_mpool_mem_t* ptr = NULL; + dal_mpool_mem_t* new_ptr = NULL; + int mod; + + MPOOL_LOCK(); + + mod = size & (DAL_CACHE_LINE_BYTES - 1); + if (mod != 0) + { + size += (DAL_CACHE_LINE_BYTES - mod); + } + + switch(type) + { + case DAL_MPOOL_TYPE_USELESS: + ptr = pool; + new_ptr = _dal_mpool_alloc_comon(ptr, size, type); + if (NULL == new_ptr) + { + MPOOL_UNLOCK(); + return NULL; + } + break; + case DAL_MPOOL_TYPE_DESC: + ptr = p_desc_pool[lchip]; + new_ptr = _dal_mpool_alloc_comon(ptr, size, type); + if (NULL == new_ptr) + { + MPOOL_UNLOCK(); + return NULL; + } + break; + case DAL_MPOOL_TYPE_DATA: + ptr = p_data_pool[lchip]; + new_ptr = _dal_mpool_alloc_comon(ptr, size, type); + if (NULL == new_ptr) + { + MPOOL_UNLOCK(); + return NULL; + } + break; + default: + MPOOL_UNLOCK(); + return NULL; + break; + } + + MPOOL_UNLOCK(); + if( NULL == new_ptr ) + { + return NULL; + } + + return new_ptr->address; +} + +void +_dal_mpool_free(dal_mpool_mem_t* ptr, void* addr, int type) +{ + unsigned char* address = (unsigned char*)addr; + dal_mpool_mem_t* prev = NULL; + + while (ptr && ptr->next) + { + if (ptr->next->address == address) + { + break; + } + + ptr = ptr->next; + } + + if (ptr && ptr->next) + { + prev = ptr; + ptr = ptr->next; + prev->next = ptr->next; + DAL_FREE(ptr); + } + + return; +} + +void +dal_mpool_free(unsigned char lchip, dal_mpool_mem_t* pool, void* addr) +{ + dal_mpool_mem_t* ptr = pool; + + MPOOL_LOCK(); + + switch(pool->type) + { + case DAL_MPOOL_TYPE_USELESS: + ptr = pool; + _dal_mpool_free(ptr, addr, DAL_MPOOL_TYPE_USELESS); + break; + case DAL_MPOOL_TYPE_DESC: + ptr = p_desc_pool[lchip]; + _dal_mpool_free(ptr, addr, DAL_MPOOL_TYPE_DESC); + break; + case DAL_MPOOL_TYPE_DATA: + ptr = p_data_pool[lchip]; + _dal_mpool_free(ptr, addr, DAL_MPOOL_TYPE_DATA); + break; + default: + break; + } + + MPOOL_UNLOCK(); + return; +} + +int +dal_mpool_destroy(unsigned char lchip, dal_mpool_mem_t* pool) +{ + dal_mpool_mem_t* ptr, * next; + + MPOOL_LOCK(); + + for (ptr = pool; ptr; ptr = next) + { + next = ptr->next; + DAL_FREE(ptr); + } + + for (ptr = p_desc_pool[lchip]; ptr; ptr = next) + { + next = ptr->next; + DAL_FREE(ptr); + } + + for (ptr = p_data_pool[lchip]; ptr; ptr = next) + { + next = ptr->next; + DAL_FREE(ptr); + } + + MPOOL_UNLOCK(); + + return 0; +} + +int +dal_mpool_usage(dal_mpool_mem_t* pool, int type) +{ + int usage = 0; + dal_mpool_mem_t* ptr; + /*SYSTEM MODIFIED, Added by weij for compile SDK, 2017-09-11*/ + uint8_t lchip = 0; + MPOOL_LOCK(); + + for (ptr = pool; ptr; ptr = ptr->next) + { + if (ptr->type == type || ptr->type == -1) + { + usage += ptr->size; + } + } + + MPOOL_UNLOCK(); + + return usage; +} + +int +dal_mpool_debug(dal_mpool_mem_t* pool) +{ + dal_mpool_mem_t* ptr; + int index = 0; + /*SYSTEM MODIFIED, Added by weij for compile SDK, 2017-09-11*/ + uint8_t lchip = 0; + MPOOL_LOCK(); + + for (ptr = pool; ptr; ptr = ptr->next) + { + /* DAL_PRINT("%2dst mpool block: address=0x%8x, size=0x%x \n", index, (unsigned int)ptr->address, ptr->size);*/ + DAL_PRINT("%2dst mpool block: address=%p, size=0x%x \n", index, ptr->address, ptr->size); /* note*/ + index++; + } + + MPOOL_UNLOCK(); + + return 0; +} + diff --git a/platform/centec/centec-dal/dal_mpool.h b/platform/centec/centec-dal/dal_mpool.h new file mode 100644 index 000000000000..4c2e3487e394 --- /dev/null +++ b/platform/centec/centec-dal/dal_mpool.h @@ -0,0 +1,74 @@ +/** + @file dal_mpool.h + + @author Copyright (C) 2011 Centec Networks Inc. All rights reserved. + + @date 2012-5-10 + + @version v2.0 + + This file contains the dma memory init, allocation and free APIs +*/ + +#ifndef _DMA_MPOOL_H +#define _DMA_MPOOL_H +#ifdef __cplusplus +extern "C" { +#endif + +#define DAL_MPOOL_MAX_DESX_SIZE (1024*1024) + +enum dal_mpool_type_e +{ + DAL_MPOOL_TYPE_USELESS, /* just compatible with GB */ + DAL_MPOOL_TYPE_DESC, /* dma mpool op for desc */ + DAL_MPOOL_TYPE_DATA /* dma mpool op for data */ +}; +typedef enum dal_mpool_type_e dal_mpool_type_t; + +struct dal_mpool_mem_s +{ + unsigned char* address; + int size; + int type; + struct dal_mpool_mem_s* next; +}; +typedef struct dal_mpool_mem_s dal_mpool_mem_t; + +/** + @brief This function is to alloc dma memory + + @param[in] size size of memory + + @return NULL + +*/ +extern int +dal_mpool_init(unsigned char lchip); + +extern int +dal_mpool_deinit(unsigned char lchip); + +extern dal_mpool_mem_t* +dal_mpool_create(unsigned char lchip, void* base_ptr, int size); + +extern void* +dal_mpool_alloc(unsigned char lchip, dal_mpool_mem_t* pool, int size, int type); + +extern void +dal_mpool_free(unsigned char lchip, dal_mpool_mem_t* pool, void* addr); + +extern int +dal_mpool_destroy(unsigned char lchip, dal_mpool_mem_t* pool); + +extern int +dal_mpool_usage(dal_mpool_mem_t* pool, int type); + +extern int +dal_mpool_debug(dal_mpool_mem_t* pool); +#ifdef __cplusplus +} +#endif + +#endif /* !_DMA_MPOOL_H */ + diff --git a/platform/centec/docker-ptf-centec.mk b/platform/centec/docker-ptf-centec.mk deleted file mode 100644 index ff84ed0becb7..000000000000 --- a/platform/centec/docker-ptf-centec.mk +++ /dev/null @@ -1,7 +0,0 @@ -# docker image for docker-ptf-centec - -DOCKER_PTF_CENTEC = docker-ptf-centec.gz -$(DOCKER_PTF_CENTEC)_PATH = $(DOCKERS_PATH)/docker-ptf-saithrift -$(DOCKER_PTF_CENTEC)_DEPENDS += $(PYTHON_SAITHRIFT_CENTEC) -$(DOCKER_PTF_CENTEC)_LOAD_DOCKERS += $(DOCKER_PTF) -SONIC_DOCKER_IMAGES += $(DOCKER_PTF_CENTEC) diff --git a/platform/centec/docker-syncd-centec-rpc.mk b/platform/centec/docker-syncd-centec-rpc.mk index 71c8ef7753c1..6b912185b7da 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) \ @@ -10,14 +10,14 @@ $(DOCKER_SYNCD_CENTEC_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ $(LIBSAIMETADATA_DBG) \ $(LIBSAIREDIS_DBG) endif -$(DOCKER_SYNCD_CENTEC_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_CENTEC) +$(DOCKER_SYNCD_CENTEC_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_BASE) SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_CENTEC_RPC) ifeq ($(ENABLE_SYNCD_RPC),y) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_CENTEC_RPC) endif $(DOCKER_SYNCD_CENTEC_RPC)_CONTAINER_NAME = syncd -$(DOCKER_SYNCD_CENTEC_RPC)_RUN_OPT += --net=host --privileged -t +$(DOCKER_SYNCD_CENTEC_RPC)_RUN_OPT += --privileged -t $(DOCKER_SYNCD_CENTEC_RPC)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf $(DOCKER_SYNCD_CENTEC_RPC)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd $(DOCKER_SYNCD_CENTEC_RPC)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro diff --git a/platform/centec/docker-syncd-centec-rpc/Dockerfile.j2 b/platform/centec/docker-syncd-centec-rpc/Dockerfile.j2 index 2174fd91f919..bec9c7f4426b 100644 --- a/platform/centec/docker-syncd-centec-rpc/Dockerfile.j2 +++ b/platform/centec/docker-syncd-centec-rpc/Dockerfile.j2 @@ -11,23 +11,28 @@ debs/ RUN apt-get purge -y syncd -RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; } ; \ -{% for deb in docker_syncd_centec_rpc_debs.split(' ') -%} -dpkg_apt debs/{{ deb }}{{'; '}} -{%- endfor %} - ## Pre-install the fundamental packages RUN apt-get update \ && apt-get -y install \ net-tools \ python-pip \ + python-setuptools \ build-essential \ libssl-dev \ libffi-dev \ python-dev \ wget \ cmake \ - && wget https://github.com/nanomsg/nanomsg/archive/1.0.0.tar.gz \ + libqt5core5a \ + libqt5network5 \ + libboost-atomic1.71.0 + +RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; } ; \ +{% for deb in docker_syncd_centec_rpc_debs.split(' ') -%} +dpkg_apt debs/{{ deb }}{{'; '}} +{%- endfor %} + +RUN wget https://github.com/nanomsg/nanomsg/archive/1.0.0.tar.gz \ && tar xvfz 1.0.0.tar.gz \ && cd nanomsg-1.0.0 \ && mkdir -p build \ @@ -37,9 +42,10 @@ RUN apt-get update \ && cd .. \ && rm -fr nanomsg-1.0.0 \ && rm -f 1.0.0.tar.gz \ - && pip install cffi==1.7.0 \ - && pip install --upgrade cffi==1.7.0 \ - && pip install nnpy \ + && pip2 install cffi==1.7.0 \ + && pip2 install --upgrade cffi==1.7.0 \ + && pip2 install wheel \ + && pip2 install nnpy \ && mkdir -p /opt \ && cd /opt \ && wget https://raw.githubusercontent.com/p4lang/ptf/master/ptf_nn/ptf_nn_agent.py \ @@ -47,5 +53,5 @@ RUN apt-get update \ && rm -rf /root/deps COPY ["ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] - -ENTRYPOINT ["/usr/bin/supervisord"] + +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/centec/docker-syncd-centec.mk b/platform/centec/docker-syncd-centec.mk index a0dbcc629dee..75cc45c28559 100644 --- a/platform/centec/docker-syncd-centec.mk +++ b/platform/centec/docker-syncd-centec.mk @@ -1,23 +1,16 @@ # docker image for centec syncd -DOCKER_SYNCD_CENTEC = docker-syncd-centec.gz -$(DOCKER_SYNCD_CENTEC)_PATH = $(PLATFORM_PATH)/docker-syncd-centec -$(DOCKER_SYNCD_CENTEC)_DEPENDS += $(SYNCD) -$(DOCKER_SYNCD_CENTEC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) -ifeq ($(INSTALL_DEBUG_TOOLS), y) +DOCKER_SYNCD_PLATFORM_CODE = centec +include $(PLATFORM_PATH)/../template/docker-syncd-base.mk + +$(DOCKER_SYNCD_BASE)_DEPENDS += $(SYNCD) + $(DOCKER_SYNCD_CENTEC)_DEPENDS += $(SYNCD_DBG) \ $(LIBSWSSCOMMON_DBG) \ $(LIBSAIMETADATA_DBG) \ $(LIBSAIREDIS_DBG) -endif -$(DOCKER_SYNCD_CENTEC)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE) -SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_CENTEC) -ifneq ($(ENABLE_SYNCD_RPC),y) -SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_CENTEC) -endif -$(DOCKER_SYNCD_CENTEC)_CONTAINER_NAME = syncd -$(DOCKER_SYNCD_CENTEC)_RUN_OPT += --net=host --privileged -t +$(DOCKER_SYNCD_CENTEC)_RUN_OPT += --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 diff --git a/platform/centec/docker-syncd-centec/Dockerfile.j2 b/platform/centec/docker-syncd-centec/Dockerfile.j2 index b40103a24f28..ce3b47bcdd77 100755 --- a/platform/centec/docker-syncd-centec/Dockerfile.j2 +++ b/platform/centec/docker-syncd-centec/Dockerfile.j2 @@ -1,4 +1,4 @@ -FROM docker-config-engine +FROM docker-config-engine-buster ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf @@ -20,15 +20,14 @@ debs/{{ deb }}{{' '}} {%- endfor %} ## TODO: add kmod into Depends -RUN apt-get install -f kmod +RUN apt-get install -yf kmod -COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] -COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin/"] COPY ["critical_processes", "/etc/supervisor/"] ## Clean up RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] 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 3079618990ed..61e290e3189e 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" - if does not exist for 5 times within 5 cycles then alert +check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/platform/centec/docker-syncd-centec/critical_processes b/platform/centec/docker-syncd-centec/critical_processes index 6082f242b872..bdd6903c5690 100644 --- a/platform/centec/docker-syncd-centec/critical_processes +++ b/platform/centec/docker-syncd-centec/critical_processes @@ -1 +1 @@ -syncd +program:syncd diff --git a/platform/centec/docker-syncd-centec/start.sh b/platform/centec/docker-syncd-centec/start.sh deleted file mode 100755 index 623316050475..000000000000 --- a/platform/centec/docker-syncd-centec/start.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -rm -f /var/run/rsyslogd.pid - -supervisorctl start rsyslogd - -supervisorctl start syncd diff --git a/platform/centec/docker-syncd-centec/supervisord.conf b/platform/centec/docker-syncd-centec/supervisord.conf index 0c6285d46ae0..6df1893a0be0 100644 --- a/platform/centec/docker-syncd-centec/supervisord.conf +++ b/platform/centec/docker-syncd-centec/supervisord.conf @@ -3,32 +3,35 @@ 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 +[eventlistener:dependent-startup] +command=python2 -m supervisord_dependent_startup autostart=true autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE -[program:start.sh] -command=/usr/bin/start.sh -priority=1 +[eventlistener:supervisor-proc-exit-listener] +command=python2 /usr/bin/supervisor-proc-exit-listener --container-name syncd +events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING autostart=true -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog +autorestart=unexpected [program:rsyslogd] -command=/usr/sbin/rsyslogd -n -priority=2 +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 autostart=false autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true [program:syncd] command=/usr/bin/syncd_start.sh -priority=3 +priority=2 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running diff --git a/platform/centec/one-image.mk b/platform/centec/one-image.mk index 0e057b24df03..a92c97078846 100644 --- a/platform/centec/one-image.mk +++ b/platform/centec/one-image.mk @@ -5,7 +5,8 @@ $(SONIC_ONE_IMAGE)_MACHINE = centec $(SONIC_ONE_IMAGE)_IMAGE_TYPE = onie $(SONIC_ONE_IMAGE)_INSTALLS = $(SYSTEMD_SONIC_GENERATOR) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(CENTEC_E582_48X6Q_PLATFORM_MODULE) \ - $(CENTEC_E582_48X2Q4Z_PLATFORM_MODULE) + $(CENTEC_E582_48X2Q4Z_PLATFORM_MODULE) \ + $(EMBEDWAY_ES6220_PLATFORM_MODULE) ifeq ($(INSTALL_DEBUG_TOOLS),y) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES) $(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES)) diff --git a/platform/centec/platform-modules-centec-e582.mk b/platform/centec/platform-modules-centec-e582.mk index e22653075ecb..e86c428a7403 100644 --- a/platform/centec/platform-modules-centec-e582.mk +++ b/platform/centec/platform-modules-centec-e582.mk @@ -12,7 +12,6 @@ CENTEC_E582_48X6Q_PLATFORM_MODULE = platform-modules-e582-48x6q_$(CENTEC_E582_48 $(CENTEC_E582_48X6Q_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-e582 $(CENTEC_E582_48X6Q_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) $(CENTEC_E582_48X6Q_PLATFORM_MODULE)_PLATFORM = x86_64-centec_e582_48x6q-r0 -SONIC_STRETCH_DEBS += $(CENTEC_E582_48X6Q_PLATFORM_MODULE) SONIC_DPKG_DEBS += $(CENTEC_E582_48X6Q_PLATFORM_MODULE) CENTEC_E582_48X2Q4Z_PLATFORM_MODULE = platform-modules-e582-48x2q4z_$(CENTEC_E582_48X2Q4Z_PLATFORM_MODULE_VERSION)_amd64.deb diff --git a/platform/centec/platform-modules-embedway.mk b/platform/centec/platform-modules-embedway.mk new file mode 100644 index 000000000000..c2ddfc327542 --- /dev/null +++ b/platform/centec/platform-modules-embedway.mk @@ -0,0 +1,12 @@ +# embedway es6220 Platform modules + +EMBEDWAY_ES6220_PLATFORM_MODULE_VERSION =1.1 + +export EMBEDWAY_ES6220_PLATFORM_MODULE_VERSION + +EMBEDWAY_ES6220_PLATFORM_MODULE = platform-modules-embedway-es6220_$(EMBEDWAY_ES6220_PLATFORM_MODULE_VERSION)_amd64.deb + +$(EMBEDWAY_ES6220_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-embedway +$(EMBEDWAY_ES6220_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +$(EMBEDWAY_ES6220_PLATFORM_MODULE)_PLATFORM = x86_64-ew_es6220_x48q2h4-r0 +SONIC_DPKG_DEBS += $(EMBEDWAY_ES6220_PLATFORM_MODULE) diff --git a/platform/centec/rules.mk b/platform/centec/rules.mk index 53759cb67f40..182248ec1ac6 100644 --- a/platform/centec/rules.mk +++ b/platform/centec/rules.mk @@ -1,19 +1,19 @@ include $(PLATFORM_PATH)/platform-modules-centec-e582.mk +include $(PLATFORM_PATH)/platform-modules-embedway.mk include $(PLATFORM_PATH)/sdk.mk include $(PLATFORM_PATH)/docker-syncd-centec.mk include $(PLATFORM_PATH)/docker-syncd-centec-rpc.mk include $(PLATFORM_PATH)/one-image.mk include $(PLATFORM_PATH)/libsaithrift-dev.mk -include $(PLATFORM_PATH)/docker-ptf-centec.mk -SONIC_ALL += $(SONIC_ONE_IMAGE) \ - $(DOCKER_PTF_CENTEC) \ - $(DOCKER_SYNCD_CENTEC_RPC) +SONIC_ALL += $(SONIC_ONE_IMAGE) + +# Inject centec sai into syncd +$(SYNCD)_DEPENDS += $(CENTEC_SAI) +$(SYNCD)_UNINSTALLS += $(CENTEC_SAI) -# Inject centec sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(CENTEC_SAI) ifeq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV_CENTEC) +$(SYNCD)_DEPENDS += $(LIBSAITHRIFT_DEV) endif # Runtime dependency on centec sai is set only for syncd diff --git a/platform/centec/sdk.mk b/platform/centec/sdk.mk index c529762dafc8..588b2b244130 100644 --- a/platform/centec/sdk.mk +++ b/platform/centec/sdk.mk @@ -1,5 +1,6 @@ # Centec SAI -CENTEC_SAI = libsai_1.3.3_amd64.deb -$(CENTEC_SAI)_URL = https://github.com/CentecNetworks/goldengate-sai/raw/master/lib/SONiC_1.3.3/libsai_1.3.3-1.0_amd64.deb +CENTEC_SAI = libsai_1.6.3-1_amd64.deb +$(CENTEC_SAI)_URL = https://github.com/CentecNetworks/sonic-binaries/raw/master/amd64/$(CENTEC_SAI) +$(eval $(call add_conflict_package,$(CENTEC_SAI),$(LIBSAIVS_DEV))) SONIC_ONLINE_DEBS += $(CENTEC_SAI) diff --git a/platform/centec/sonic-platform-modules-e582/48x2q4z/cfg/config_db.json b/platform/centec/sonic-platform-modules-e582/48x2q4z/cfg/config_db.json deleted file mode 100644 index 3a5c8ba914b5..000000000000 --- a/platform/centec/sonic-platform-modules-e582/48x2q4z/cfg/config_db.json +++ /dev/null @@ -1,302 +0,0 @@ -{ - "DEVICE_METADATA": { - "localhost": { - "bgp_asn": 65100, - "deployment_id": null, - "hostname": "switch1", - "type": "LeafRouter", - "hwsku": "E582-48x6q" - - } - }, - "BGP_PEER_RANGE": {}, - "VLAN": {}, - "PORT": { - "Ethernet1": { - "alias": "eth-0-1", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet2": { - "alias": "eth-0-2", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet3": { - "alias": "eth-0-3", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet4": { - "alias": "eth-0-4", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet5": { - "alias": "eth-0-5", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet6": { - "alias": "eth-0-6", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet7": { - "alias": "eth-0-7", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet8": { - "alias": "eth-0-8", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet9": { - "alias": "eth-0-9", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet10": { - "alias": "eth-0-10", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet11": { - "alias": "eth-0-11", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet12": { - "alias": "eth-0-12", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet13": { - "alias": "eth-0-13", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet14": { - "alias": "eth-0-14", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet15": { - "alias": "eth-0-15", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet16": { - "alias": "eth-0-16", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet17": { - "alias": "eth-0-17", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet18": { - "alias": "eth-0-18", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet19": { - "alias": "eth-0-19", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet20": { - "alias": "eth-0-20", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet21": { - "alias": "eth-0-21", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet22": { - "alias": "eth-0-22", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet23": { - "alias": "eth-0-23", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet24": { - "alias": "eth-0-24", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet25": { - "alias": "eth-0-25", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet26": { - "alias": "eth-0-26", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet27": { - "alias": "eth-0-27", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet28": { - "alias": "eth-0-28", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet29": { - "alias": "eth-0-29", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet30": { - "alias": "eth-0-30", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet31": { - "alias": "eth-0-31", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet32": { - "alias": "eth-0-32", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet33": { - "alias": "eth-0-33", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet34": { - "alias": "eth-0-34", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet35": { - "alias": "eth-0-35", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet36": { - "alias": "eth-0-36", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet37": { - "alias": "eth-0-37", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet38": { - "alias": "eth-0-38", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet39": { - "alias": "eth-0-39", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet40": { - "alias": "eth-0-40", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet41": { - "alias": "eth-0-41", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet42": { - "alias": "eth-0-42", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet43": { - "alias": "eth-0-43", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet44": { - "alias": "eth-0-44", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet45": { - "alias": "eth-0-45", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet46": { - "alias": "eth-0-46", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet47": { - "alias": "eth-0-47", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet48": { - "alias": "eth-0-48", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet49": { - "alias": "eth-0-49", - "speed": "40000", - "mtu": "9100" - }, - "Ethernet50": { - "alias": "eth-0-50", - "speed": "40000", - "mtu": "9100" - }, - "Ethernet51": { - "alias": "eth-0-51", - "speed": "100000", - "mtu": "9100" - }, - "Ethernet52": { - "alias": "eth-0-52", - "speed": "100000", - "mtu": "9100" - }, - "Ethernet53": { - "alias": "eth-0-53", - "speed": "100000", - "mtu": "9100" - }, - "Ethernet54": { - "alias": "eth-0-54", - "speed": "100000", - "mtu": "9100" - } - }, - "SYSLOG_SERVER": {}, - "VLAN_INTERFACE": {}, - "PORTCHANNEL_INTERFACE": {}, - "PORTCHANNEL": {}, - "MGMT_INTERFACE": {}, - "DHCP_SERVER": {}, - "LOOPBACK_INTERFACE": { - "Loopback0|127.0.0.1/8": {} - }, - "ACL_TABLE": {}, - "INTERFACE": { - "Ethernet1|192.168.1.1/24": {}, - "Ethernet2|192.168.2.1/24": {}, - "Ethernet3|192.168.3.1/24": {}, - "Ethernet4|192.168.4.1/24": {} - } -} diff --git a/platform/centec/sonic-platform-modules-e582/48x2q4z/cfg/config_db_l2l3.json b/platform/centec/sonic-platform-modules-e582/48x2q4z/cfg/config_db_l2l3.json deleted file mode 100644 index dd40332f9049..000000000000 --- a/platform/centec/sonic-platform-modules-e582/48x2q4z/cfg/config_db_l2l3.json +++ /dev/null @@ -1,610 +0,0 @@ -{ - "QUEUE": { - "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|0-2": { - "wred_profile": "[WRED_PROFILE|AZURE_LOSSY]" - }, - "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|3-4": { - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]", - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|5-7": { - "wred_profile": "[WRED_PROFILE|AZURE_LOSSY]" - } - }, - "WRED_PROFILE": { - "AZURE_LOSSLESS": { - "red_max_threshold": "32760", - "yellow_max_threshold": "32760", - "green_min_threshold": "4095", - "red_min_threshold": "4095", - "yellow_min_threshold": "4095", - "green_max_threshold": "32760", - "wred_yellow_enable": "true", - "wred_green_enable": "true" - }, - "AZURE_LOSSY": { - "red_max_threshold": "32760", - "yellow_max_threshold": "32760", - "green_min_threshold": "4095", - "red_min_threshold": "4095", - "yellow_min_threshold": "4095", - "green_max_threshold": "32760", - "wred_yellow_enable": "true", - "wred_green_enable": "true" - } - }, - "DSCP_TO_TC_MAP": { - "AZURE": { - "56": "7", - "54": "6", - "28": "3", - "48": "6", - "29": "3", - "60": "7", - "61": "7", - "62": "7", - "63": "7", - "49": "6", - "34": "4", - "24": "3", - "25": "3", - "26": "3", - "27": "3", - "20": "2", - "21": "2", - "22": "2", - "23": "2", - "46": "5", - "47": "5", - "44": "5", - "45": "5", - "42": "5", - "43": "5", - "40": "5", - "41": "5", - "1": "0", - "0": "0", - "3": "0", - "2": "0", - "5": "0", - "4": "0", - "7": "0", - "6": "0", - "9": "1", - "8": "1", - "35": "4", - "13": "1", - "12": "1", - "15": "1", - "58": "7", - "11": "1", - "10": "1", - "39": "4", - "38": "4", - "59": "7", - "14": "1", - "17": "2", - "16": "2", - "19": "2", - "18": "2", - "31": "3", - "30": "3", - "51": "6", - "36": "4", - "53": "6", - "52": "6", - "33": "4", - "55": "6", - "37": "4", - "32": "4", - "57": "7", - "50": "6" - } - }, - "DEVICE_METADATA": { - "localhost": { - "hwsku": "E582-48x6q", - "hostname": "switch1", - "bgp_asn": "None", - "deployment_id": "None", - "type": "LeafRouter" - } - }, - "PORT": { - "Ethernet1": { - "alias": "eth-0-1", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet2": { - "alias": "eth-0-2", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet3": { - "alias": "eth-0-3", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet4": { - "alias": "eth-0-4", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet5": { - "alias": "eth-0-5", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet6": { - "alias": "eth-0-6", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet7": { - "alias": "eth-0-7", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet8": { - "alias": "eth-0-8", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet9": { - "alias": "eth-0-9", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet10": { - "alias": "eth-0-10", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet11": { - "alias": "eth-0-11", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet12": { - "alias": "eth-0-12", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet13": { - "alias": "eth-0-13", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet14": { - "alias": "eth-0-14", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet15": { - "alias": "eth-0-15", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet16": { - "alias": "eth-0-16", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet17": { - "alias": "eth-0-17", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet18": { - "alias": "eth-0-18", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet19": { - "alias": "eth-0-19", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet20": { - "alias": "eth-0-20", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet21": { - "alias": "eth-0-21", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet22": { - "alias": "eth-0-22", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet23": { - "alias": "eth-0-23", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet24": { - "alias": "eth-0-24", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet25": { - "alias": "eth-0-25", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet26": { - "alias": "eth-0-26", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet27": { - "alias": "eth-0-27", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet28": { - "alias": "eth-0-28", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet29": { - "alias": "eth-0-29", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet30": { - "alias": "eth-0-30", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet31": { - "alias": "eth-0-31", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet32": { - "alias": "eth-0-32", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet33": { - "alias": "eth-0-33", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet34": { - "alias": "eth-0-34", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet35": { - "alias": "eth-0-35", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet36": { - "alias": "eth-0-36", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet37": { - "alias": "eth-0-37", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet38": { - "alias": "eth-0-38", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet39": { - "alias": "eth-0-39", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet40": { - "alias": "eth-0-40", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet41": { - "alias": "eth-0-41", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet42": { - "alias": "eth-0-42", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet43": { - "alias": "eth-0-43", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet44": { - "alias": "eth-0-44", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet45": { - "alias": "eth-0-45", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet46": { - "alias": "eth-0-46", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet47": { - "alias": "eth-0-47", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet48": { - "alias": "eth-0-48", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet49": { - "alias": "eth-0-49", - "speed": "40000", - "mtu": "9100" - }, - "Ethernet50": { - "alias": "eth-0-50", - "speed": "40000", - "mtu": "9100" - }, - "Ethernet51": { - "alias": "eth-0-51", - "speed": "100000", - "mtu": "9100" - }, - "Ethernet52": { - "alias": "eth-0-52", - "speed": "100000", - "mtu": "9100" - }, - "Ethernet53": { - "alias": "eth-0-53", - "speed": "100000", - "mtu": "9100" - }, - "Ethernet54": { - "alias": "eth-0-54", - "speed": "100000", - "mtu": "9100" - } - }, - "PORT_QOS_MAP": { - "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54": { - "pfc_enable": "3,4", - "dscp_to_tc_map": "[DSCP_TO_TC_MAP|AZURE]" - } - }, - "SCHEDULER": { - "scheduler.0": { - "type": "DWRR", - "weight": "25" - }, - "scheduler.1": { - "type": "DWRR", - "weight": "30" - }, - "scheduler.2": { - "type": "DWRR", - "weight": "20" - } - }, - "VLAN": { - "Vlan500": { - "dhcp_servers": [ - "192.168.5.1", - "192.168.5.2", - "192.168.5.3", - "192.168.5.4" - ], - "members": [ - "Ethernet5", - "Ethernet6", - "Ethernet7", - "Ethernet8" - ], - "vlanid": "500" - }, - "Vlan600": { - "dhcp_servers": [ - "192.168.6.1", - "192.168.6.2", - "192.168.6.3", - "192.168.6.4" - ], - "members": [ - "Ethernet5", - "Ethernet6" - ], - "vlanid": "600" - }, - "Vlan700": { - "dhcp_servers": [ - "192.168.7.1", - "192.168.7.2", - "192.168.7.3", - "192.168.7.4" - ], - "members": [ - "Ethernet5", - "Ethernet7" - ], - "vlanid": "700" - }, - "Vlan800": { - "dhcp_servers": [ - "192.168.8.1", - "192.168.8.2", - "192.168.8.3", - "192.168.8.4" - ], - "members": [ - "Ethernet5", - "Ethernet8" - ], - "vlanid": "800" - } - }, - "VLAN_MEMBER": { - "Vlan500|Ethernet5": { - "tagging_mode": "tagged" - }, - "Vlan500|Ethernet6": { - "tagging_mode": "untagged" - }, - "Vlan500|Ethernet7": { - "tagging_mode": "untagged" - }, - "Vlan500|Ethernet8": { - "tagging_mode": "untagged" - }, - "Vlan600|Ethernet5": { - "tagging_mode": "tagged" - }, - "Vlan600|Ethernet6": { - "tagging_mode": "tagged" - }, - "Vlan700|Ethernet5": { - "tagging_mode": "tagged" - }, - "Vlan700|Ethernet7": { - "tagging_mode": "tagged" - }, - "Vlan800|Ethernet5": { - "tagging_mode": "tagged" - }, - "Vlan800|Ethernet8": { - "tagging_mode": "tagged" - } - }, - "INTERFACE": { - "Ethernet1|192.168.1.1/24": {}, - "Ethernet2|192.168.2.1/24": {}, - "Ethernet3|192.168.3.1/24": {}, - "Ethernet4|192.168.4.1/24": {} - }, - "VLAN_INTERFACE": { - "Vlan500|192.168.5.1/24": {}, - "Vlan600|192.168.6.1/24": {}, - "Vlan700|192.168.7.1/24": {}, - "Vlan800|192.168.8.1/24": {} - }, - "LOOPBACK_INTERFACE": { - "Loopback0|127.0.0.1/8": {} - }, - "CABLE_LENGTH": { - "AZURE": { - "Ethernet8": "40m", - "Ethernet9": "40m", - "Ethernet2": "40m", - "Ethernet3": "40m", - "Ethernet1": "40m", - "Ethernet6": "40m", - "Ethernet7": "40m", - "Ethernet4": "40m", - "Ethernet5": "40m", - "Ethernet22": "40m", - "Ethernet50": "40m", - "Ethernet51": "40m", - "Ethernet52": "40m", - "Ethernet53": "40m", - "Ethernet54": "40m", - "Ethernet38": "40m", - "Ethernet39": "40m", - "Ethernet18": "40m", - "Ethernet19": "40m", - "Ethernet14": "40m", - "Ethernet15": "40m", - "Ethernet16": "40m", - "Ethernet17": "40m", - "Ethernet10": "40m", - "Ethernet11": "40m", - "Ethernet12": "40m", - "Ethernet35": "40m", - "Ethernet37": "40m", - "Ethernet32": "40m", - "Ethernet33": "40m", - "Ethernet30": "40m", - "Ethernet31": "40m", - "Ethernet49": "40m", - "Ethernet48": "40m", - "Ethernet47": "40m", - "Ethernet36": "40m", - "Ethernet45": "40m", - "Ethernet44": "40m", - "Ethernet43": "40m", - "Ethernet42": "40m", - "Ethernet41": "40m", - "Ethernet40": "40m", - "Ethernet29": "40m", - "Ethernet28": "40m", - "Ethernet34": "40m", - "Ethernet46": "40m", - "Ethernet21": "40m", - "Ethernet20": "40m", - "Ethernet23": "40m", - "Ethernet13": "40m", - "Ethernet25": "40m", - "Ethernet24": "40m", - "Ethernet27": "40m", - "Ethernet26": "40m" - } - }, - "CRM": { - "Config": { - "acl_table_threshold_type": "percentage", - "nexthop_group_threshold_type": "percentage", - "fdb_entry_high_threshold": "85", - "acl_entry_threshold_type": "percentage", - "ipv6_neighbor_low_threshold": "70", - "nexthop_group_member_low_threshold": "70", - "acl_group_high_threshold": "85", - "ipv4_route_high_threshold": "85", - "acl_counter_high_threshold": "85", - "ipv4_route_low_threshold": "70", - "ipv4_route_threshold_type": "percentage", - "ipv4_neighbor_low_threshold": "70", - "acl_group_threshold_type": "percentage", - "ipv4_nexthop_high_threshold": "85", - "ipv6_route_threshold_type": "percentage", - "nexthop_group_low_threshold": "70", - "ipv4_neighbor_high_threshold": "85", - "ipv6_route_high_threshold": "85", - "ipv6_nexthop_threshold_type": "percentage", - "polling_interval": "300", - "ipv4_nexthop_threshold_type": "percentage", - "acl_group_low_threshold": "70", - "acl_entry_low_threshold": "70", - "nexthop_group_member_threshold_type": "percentage", - "ipv4_nexthop_low_threshold": "70", - "acl_counter_threshold_type": "percentage", - "ipv6_neighbor_high_threshold": "85", - "nexthop_group_member_high_threshold": "85", - "acl_table_low_threshold": "70", - "fdb_entry_threshold_type": "percentage", - "ipv6_neighbor_threshold_type": "percentage", - "acl_table_high_threshold": "85", - "ipv6_nexthop_low_threshold": "70", - "acl_counter_low_threshold": "70", - "ipv4_neighbor_threshold_type": "percentage", - "nexthop_group_high_threshold": "85", - "ipv6_route_low_threshold": "70", - "acl_entry_high_threshold": "85", - "fdb_entry_low_threshold": "70", - "ipv6_nexthop_high_threshold": "85" - } - } -} diff --git a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/Makefile b/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/Makefile index d1ca9824aa9e..645ca1c2e9e1 100644 --- a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/Makefile +++ b/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/Makefile @@ -1,2 +1 @@ -obj-m := centec_e582_48x2q4z_platform.o dal.o centec_at24c64.o -dal-y := dal_kernel.o dal_mpool.o +obj-m := centec_e582_48x2q4z_platform.o centec_at24c64.o diff --git a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/centec_e582_48x2q4z_platform.c b/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/centec_e582_48x2q4z_platform.c index 16bed86593b2..6e06a67f8dd2 100644 --- a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/centec_e582_48x2q4z_platform.c +++ b/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/centec_e582_48x2q4z_platform.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include #include #include @@ -1249,7 +1249,7 @@ static ssize_t e582_48x2q4z_sfp_write_enable(struct device *dev, struct device_a } else if ((portNum >= 41) && (portNum <= 48)) { - reg_no = portNum - 17;/*8-13*/ + reg_no = portNum - 33;/*8-13*/ i2c_sfp_client = i2c_client_gpio3; } else if ((portNum >= 49) && (portNum <= 54)) diff --git a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_kernel.c b/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_kernel.c deleted file mode 100644 index 32a38f842cfa..000000000000 --- a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_kernel.c +++ /dev/null @@ -1,1833 +0,0 @@ -/** - @file dal_kernal.c - - @date 2012-10-18 - - @version v2.0 - - -*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) -#include -#endif -#include "dal_kernel.h" -#include "dal_mpool.h" -#include -MODULE_AUTHOR("Centec Networks Inc."); -MODULE_DESCRIPTION("DAL kernel module"); -MODULE_LICENSE("GPL"); - -/* DMA memory pool size */ -static char* dma_pool_size; -module_param(dma_pool_size, charp, 0); -MODULE_PARM_DESC(dma_pool_size, - "Specify DMA memory pool size (default 4MB)"); - -/***************************************************************************** - * defines - *****************************************************************************/ -#define MB_SIZE 0x100000 -#define CTC_MAX_INTR_NUM 8 - -#define MEM_MAP_RESERVE SetPageReserved -#define MEM_MAP_UNRESERVE ClearPageReserved - -#define CTC_VENDOR_VID 0xc001 -#define CTC_HUMBER_DEVICE_ID 0x6048 -#define CTC_GOLDENGATE_DEVICE_ID 0xc010 -#define CTC_PCIE_VENDOR_ID 0xcb10 -#define CTC_DUET2_DEVICE_ID 0x7148 - -#define MEM_MAP_RESERVE SetPageReserved -#define MEM_MAP_UNRESERVE ClearPageReserved - -#define CTC_GREATBELT_DEVICE_ID 0x03e8 /* TBD */ -#define DAL_MAX_CHIP_NUM 8 /* [GB] used */ -#define VIRT_TO_PAGE(p) virt_to_page((p)) -#define DAL_UNTAG_BLOCK 0 -#define DAL_DISCARD_BLOCK 1 -#define DAL_MATCHED_BLOCK 2 -#define DAL_CUR_MATCH_BLOCk 3 -/***************************************************************************** - * typedef - *****************************************************************************/ -/* Control Data */ -typedef struct dal_isr_s -{ - int irq; - void (* isr)(void*); - void* isr_data; - int trigger; - int count; - wait_queue_head_t wqh; -} dal_isr_t; - -typedef struct dal_kernel_dev_s -{ - struct list_head list; - struct pci_dev* pci_dev; - - /* PCI I/O mapped base address */ - uintptr logic_address; - - /* Physical address */ - unsigned long long phys_address; -} dal_kern_dev_t; - -typedef struct _dma_segment -{ - struct list_head list; - unsigned long req_size; /* Requested DMA segment size */ - unsigned long blk_size; /* DMA block size */ - unsigned long blk_order; /* DMA block size in alternate format */ - unsigned long seg_size; /* Current DMA segment size */ - unsigned long seg_begin; /* Logical address of segment */ - unsigned long seg_end; /* Logical end address of segment */ - unsigned long* blk_ptr; /* Array of logical DMA block addresses */ - int blk_cnt_max; /* Maximum number of block to allocate */ - int blk_cnt; /* Current number of blocks allocated */ -} dma_segment_t; - -typedef irqreturn_t (*p_func) (int irq, void* dev_id); - -/*************************************************************************** - *declared - ***************************************************************************/ -static unsigned int linux_dal_poll0(struct file* filp, struct poll_table_struct* p); -static unsigned int linux_dal_poll1(struct file* filp, struct poll_table_struct* p); -static unsigned int linux_dal_poll2(struct file* filp, struct poll_table_struct* p); -static unsigned int linux_dal_poll3(struct file* filp, struct poll_table_struct* p); -static unsigned int linux_dal_poll4(struct file* filp, struct poll_table_struct* p); -static unsigned int linux_dal_poll5(struct file* filp, struct poll_table_struct* p); -static unsigned int linux_dal_poll6(struct file* filp, struct poll_table_struct* p); -static unsigned int linux_dal_poll7(struct file* filp, struct poll_table_struct* p); - -/***************************************************************************** - * global variables - *****************************************************************************/ -static dal_kern_dev_t dal_dev[DAL_MAX_CHIP_NUM]; -static dal_isr_t dal_isr[CTC_MAX_INTR_NUM]; -static int dal_chip_num = 0; -static int dal_version = 0; -static int dal_intr_num = 0; -static int use_high_memory = 0; -static unsigned int* dma_virt_base[DAL_MAX_CHIP_NUM]; -#ifndef DMA_MEM_MODE_PLATFORM -static unsigned int* dma_virt_base_tmp[DAL_MAX_CHIP_NUM]; -#endif -static unsigned long long dma_phy_base[DAL_MAX_CHIP_NUM]; -static unsigned int dma_mem_size = 0xc00000; -static unsigned int msi_irq_base[DAL_MAX_CHIP_NUM]; -static unsigned int msi_irq_num[DAL_MAX_CHIP_NUM]; -static unsigned int msi_used = 0; -static struct class *dal_class; - -static LIST_HEAD(_dma_seg); -static int dal_debug = 0; -module_param(dal_debug, int, 0); -MODULE_PARM_DESC(dal_debug, "Set debug level (default 0)"); - -static struct pci_device_id dal_id_table[] = -{ - {PCI_DEVICE(CTC_VENDOR_VID, CTC_GREATBELT_DEVICE_ID)}, - {PCI_DEVICE(CTC_PCIE_VENDOR_ID, CTC_GOLDENGATE_DEVICE_ID)}, - {PCI_DEVICE((CTC_PCIE_VENDOR_ID+1), (CTC_GOLDENGATE_DEVICE_ID+1))}, - {PCI_DEVICE(CTC_PCIE_VENDOR_ID, CTC_DUET2_DEVICE_ID)}, - {0, }, -}; - -static wait_queue_head_t poll_intr[CTC_MAX_INTR_NUM]; - -p_func intr_handler_fun[CTC_MAX_INTR_NUM]; - -static int poll_intr_trigger[CTC_MAX_INTR_NUM]; - -static struct file_operations dal_intr_fops[CTC_MAX_INTR_NUM] = -{ - { - .owner = THIS_MODULE, - .poll = linux_dal_poll0, - }, - { - .owner = THIS_MODULE, - .poll = linux_dal_poll1, - }, - { - .owner = THIS_MODULE, - .poll = linux_dal_poll2, - }, - { - .owner = THIS_MODULE, - .poll = linux_dal_poll3, - }, - { - .owner = THIS_MODULE, - .poll = linux_dal_poll4, - }, - { - .owner = THIS_MODULE, - .poll = linux_dal_poll5, - }, - { - .owner = THIS_MODULE, - .poll = linux_dal_poll6, - }, - { - .owner = THIS_MODULE, - .poll = linux_dal_poll7, - }, -}; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)) -#include -#define virt_to_bus virt_to_phys -#define bus_to_virt phys_to_virt -#endif -/***************************************************************************** - * macros - *****************************************************************************/ -#define VERIFY_CHIP_INDEX(n) (n < dal_chip_num) - -#define _KERNEL_INTERUPT_PROCESS -static irqreturn_t -intr0_handler(int irq, void* dev_id) -{ - dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; - - if(poll_intr_trigger[0]) - { - return IRQ_HANDLED; - } - - disable_irq_nosync(irq); - - if (p_dal_isr) - { - if (p_dal_isr->isr) - { - /* kernel mode interrupt handler */ - p_dal_isr->isr(p_dal_isr->isr_data); - } - else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) - { - /* user mode interrupt handler */ - poll_intr_trigger[0] = 1; - wake_up(&poll_intr[0]); - } - } - - return IRQ_HANDLED; -} - -static irqreturn_t -intr1_handler(int irq, void* dev_id) -{ - dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; - if(poll_intr_trigger[1]) - { - return IRQ_HANDLED; - } - - disable_irq_nosync(irq); - - if (p_dal_isr) - { - if (p_dal_isr->isr) - { - /* kernel mode interrupt handler */ - p_dal_isr->isr(p_dal_isr->isr_data); - } - else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) - { - /* user mode interrupt handler */ - poll_intr_trigger[1] = 1; - wake_up(&poll_intr[1]); - } - } - - return IRQ_HANDLED; -} - -static irqreturn_t -intr2_handler(int irq, void* dev_id) -{ - dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; - if(poll_intr_trigger[2]) - { - return IRQ_HANDLED; - } - disable_irq_nosync(irq); - - if (p_dal_isr) - { - if (p_dal_isr->isr) - { - /* kernel mode interrupt handler */ - p_dal_isr->isr(p_dal_isr->isr_data); - } - else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) - { - /* user mode interrupt handler */ - poll_intr_trigger[2] = 1; - wake_up(&poll_intr[2]); - } - } - - return IRQ_HANDLED; -} - -static irqreturn_t -intr3_handler(int irq, void* dev_id) -{ - dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; - if(poll_intr_trigger[3]) - { - return IRQ_HANDLED; - } - disable_irq_nosync(irq); - - if (p_dal_isr) - { - if (p_dal_isr->isr) - { - /* kernel mode interrupt handler */ - p_dal_isr->isr(p_dal_isr->isr_data); - } - else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) - { - /* user mode interrupt handler */ - poll_intr_trigger[3] = 1; - wake_up(&poll_intr[3]); - } - } - - return IRQ_HANDLED; -} - -static irqreturn_t -intr4_handler(int irq, void* dev_id) -{ - dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; - if(poll_intr_trigger[4]) - { - return IRQ_HANDLED; - } - disable_irq_nosync(irq); - - if (p_dal_isr) - { - if (p_dal_isr->isr) - { - /* kernel mode interrupt handler */ - p_dal_isr->isr(p_dal_isr->isr_data); - } - else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) - { - /* user mode interrupt handler */ - poll_intr_trigger[4] = 1; - wake_up(&poll_intr[4]); - } - } - - return IRQ_HANDLED; -} - -static irqreturn_t -intr5_handler(int irq, void* dev_id) -{ - dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; - if(poll_intr_trigger[5]) - { - return IRQ_HANDLED; - } - disable_irq_nosync(irq); - - if (p_dal_isr) - { - if (p_dal_isr->isr) - { - /* kernel mode interrupt handler */ - p_dal_isr->isr(p_dal_isr->isr_data); - } - else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) - { - /* user mode interrupt handler */ - poll_intr_trigger[5] = 1; - wake_up(&poll_intr[5]); - } - } - - return IRQ_HANDLED; -} - -static irqreturn_t -intr6_handler(int irq, void* dev_id) -{ - dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; - if(poll_intr_trigger[6]) - { - return IRQ_HANDLED; - } - disable_irq_nosync(irq); - - if (p_dal_isr) - { - if (p_dal_isr->isr) - { - /* kernel mode interrupt handler */ - p_dal_isr->isr(p_dal_isr->isr_data); - } - else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) - { - /* user mode interrupt handler */ - poll_intr_trigger[6] = 1; - wake_up(&poll_intr[6]); - } - } - - return IRQ_HANDLED; -} - -static irqreturn_t -intr7_handler(int irq, void* dev_id) -{ - dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; - if(poll_intr_trigger[7]) - { - return IRQ_HANDLED; - } - disable_irq_nosync(irq); - - if (p_dal_isr) - { - if (p_dal_isr->isr) - { - /* kernel mode interrupt handler */ - p_dal_isr->isr(p_dal_isr->isr_data); - } - else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) - { - /* user mode interrupt handler */ - poll_intr_trigger[7] = 1; - wake_up(&poll_intr[7]); - } - } - - return IRQ_HANDLED; -} - -int -dal_interrupt_register(unsigned int irq, int prio, void (* isr)(void*), void* data) -{ - int ret; - unsigned char str[16]; - unsigned char* int_name = NULL; - unsigned int intr_num_tmp = 0; - unsigned int intr_num = CTC_MAX_INTR_NUM; - unsigned long irq_flags = 0; - - if (dal_intr_num >= CTC_MAX_INTR_NUM) - { - printk("Interrupt numbers exceeds max.\n"); - return -1; - } - - if (msi_used) - { - int_name = "dal_msi"; - } - else - { - int_name = "dal_intr"; - } - - - for (intr_num_tmp=0;intr_num_tmp < CTC_MAX_INTR_NUM; intr_num_tmp++) - { - if (irq == dal_isr[intr_num_tmp].irq) - { - if (0 == msi_used) - { - dal_isr[intr_num_tmp].count++; - printk("Interrupt irq %d register count %d.\n", irq, dal_isr[intr_num_tmp].count); - } - return 0; - } - if ((0 == dal_isr[intr_num_tmp].irq) && (CTC_MAX_INTR_NUM == intr_num)) - { - intr_num = intr_num_tmp; - dal_isr[intr_num].count = 0; - } - } - dal_isr[intr_num].irq = irq; - dal_isr[intr_num].isr = isr; - dal_isr[intr_num].isr_data = data; - dal_isr[intr_num].count++; - - init_waitqueue_head(&poll_intr[intr_num]); - - /* only user mode */ - if ((NULL == isr) && (NULL == data)) - { - snprintf(str, 16, "%s%d", "dal_intr", intr_num); - ret = register_chrdev(DAL_DEV_INTR_MAJOR_BASE + intr_num, - str, &dal_intr_fops[intr_num]); - if (ret < 0) - { - printk("Register character device for irq %d failed, ret= %d", irq, ret); - return ret; - } - } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) - irq_flags = 0; -#else - irq_flags = IRQF_DISABLED; -#endif - if ((ret = request_irq(irq, - intr_handler_fun[intr_num], - irq_flags, - int_name, - &dal_isr[intr_num])) < 0) - { - printk("Cannot request irq %d, ret %d.\n", irq, ret); - unregister_chrdev(DAL_DEV_INTR_MAJOR_BASE + intr_num, str); - } - - if (0 == ret) - { - dal_intr_num++; - } - - return ret; -} - -int -dal_interrupt_unregister(unsigned int irq) -{ - unsigned char str[16]; - int intr_idx = 0; - int find_flag = 0; - - /* get intr device index */ - for (intr_idx = 0; intr_idx < CTC_MAX_INTR_NUM; intr_idx++) - { - if (dal_isr[intr_idx].irq == irq) - { - find_flag = 1; - break; - } - } - - if (find_flag == 0) - { - printk ("irq%d is not registered! unregister failed \n", irq); - return -1; - } - - dal_isr[intr_idx].count--; - if (0 != dal_isr[intr_idx].count) - { - printk("Interrupt irq %d unregister count %d.\n", irq, dal_isr[intr_idx].count); - return -1; - } - snprintf(str, 16, "%s%d", "dal_intr", intr_idx); - - unregister_chrdev(DAL_DEV_INTR_MAJOR_BASE + intr_idx, str); - - free_irq(irq, &dal_isr[intr_idx]); - - dal_isr[intr_idx].irq = 0; - - dal_intr_num--; - - return 0; -} - -int -dal_interrupt_set_en(unsigned int irq, unsigned int enable) -{ - enable ? enable_irq(irq) : disable_irq_nosync(irq); - return 0; -} - -static int -_dal_set_msi_enabe(unsigned int lchip, unsigned int irq_num) -{ - int ret = 0; - - if (irq_num == 1) - { - ret = pci_enable_msi(dal_dev[lchip].pci_dev); - if (ret) - { - printk ("msi enable failed!!! lchip = %d, irq_num = %d\n", lchip, irq_num); - pci_disable_msi(dal_dev[lchip].pci_dev); - msi_used = 0; - } - - msi_irq_base[lchip] = dal_dev[lchip].pci_dev->irq; - msi_irq_num[lchip] = 1; - } - else - { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 79)) - ret = pci_enable_msi_exact(dal_dev[lchip].pci_dev, irq_num); -#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 26, 32)) - ret = pci_enable_msi_block(dal_dev[lchip].pci_dev, irq_num); -#else - ret = -1; -#endif - if (ret) - { - printk ("msi enable failed!!! lchip = %d, irq_num = %d\n", lchip, irq_num); - pci_disable_msi(dal_dev[lchip].pci_dev); - msi_used = 0; - } - - msi_irq_base[lchip] = dal_dev[lchip].pci_dev->irq; - msi_irq_num[lchip] = irq_num; - } - - return ret; -} - -static int -_dal_set_msi_disable(unsigned int lchip) -{ - - pci_disable_msi(dal_dev[lchip].pci_dev); - - msi_irq_base[lchip] = 0; - msi_irq_num[lchip] = 0; - - return 0; -} - -int -dal_set_msi_cap(unsigned long arg) -{ - int ret = 0; - int index = 0; - dal_msi_info_t msi_info; - - if (copy_from_user(&msi_info, (void*)arg, sizeof(dal_msi_info_t))) - { - return -EFAULT; - } - - printk("####dal_set_msi_cap lchip %d base %d num:%d\n", msi_info.lchip, msi_info.irq_base, msi_info.irq_num); - if (msi_info.irq_num > 0) - { - if (0 == msi_used) - { - msi_used = 1; - ret = _dal_set_msi_enabe(msi_info.lchip, msi_info.irq_num); - } - else if ((1 == msi_used) && (msi_info.irq_num != msi_irq_num[msi_info.lchip])) - { - for (index = 0; index < msi_irq_num[msi_info.lchip]; index++) - { - dal_interrupt_unregister(msi_irq_base[msi_info.lchip]+index); - } - _dal_set_msi_disable(msi_info.lchip); - msi_used = 1; - ret = _dal_set_msi_enabe(msi_info.lchip, msi_info.irq_num); - } - } - else - { - msi_used = 0; - ret = _dal_set_msi_disable(msi_info.lchip); - } - - return ret; -} - -int -dal_user_interrupt_register(unsigned long arg) -{ - int irq = 0; - if (copy_from_user(&irq, (void*)arg, sizeof(int))) - { - return -EFAULT; - } - printk("####register interrupt irq:%d\n", irq); - return dal_interrupt_register(irq, 0, NULL, NULL); -} - -int -dal_user_interrupt_unregister(unsigned long arg) -{ - int irq = 0; - if (copy_from_user(&irq, (void*)arg, sizeof(int))) - { - return -EFAULT; - } - printk("####unregister interrupt irq:%d\n", irq); - return dal_interrupt_unregister(irq); -} - -int -dal_user_interrupt_set_en(unsigned long arg) -{ - dal_intr_parm_t dal_intr_parm; - - if (copy_from_user(&dal_intr_parm, (void*)arg, sizeof(dal_intr_parm_t))) - { - return -EFAULT; - } - - return dal_interrupt_set_en(dal_intr_parm.irq, dal_intr_parm.enable); -} - -/* - * Function: _dal_dma_segment_free - */ - -/* - * Function: _find_largest_segment - * - * Purpose: - * Find largest contiguous segment from a pool of DMA blocks. - * Parameters: - * dseg - DMA segment descriptor - * Returns: - * 0 on success, < 0 on error. - * Notes: - * Assembly stops if a segment of the requested segment size - * has been obtained. - * - * Lower address bits of the DMA blocks are used as follows: - * 0: Untagged - * 1: Discarded block - * 2: Part of largest contiguous segment - * 3: Part of current contiguous segment - */ -#ifndef DMA_MEM_MODE_PLATFORM -static int -_dal_find_largest_segment(dma_segment_t* dseg) -{ - int i, j, blks, found; - unsigned long seg_begin; - unsigned long seg_end; - unsigned long seg_tmp; - - blks = dseg->blk_cnt; - - /* Clear all block tags */ - for (i = 0; i < blks; i++) - { - dseg->blk_ptr[i] &= ~3; - } - - for (i = 0; i < blks && dseg->seg_size < dseg->req_size; i++) - { - /* First block must be an untagged block */ - if ((dseg->blk_ptr[i] & 3) == DAL_UNTAG_BLOCK) - { - /* Initial segment size is the block size */ - seg_begin = dseg->blk_ptr[i]; - seg_end = seg_begin + dseg->blk_size; - dseg->blk_ptr[i] |= DAL_CUR_MATCH_BLOCk; - - /* Loop looking for adjacent blocks */ - do - { - found = 0; - - for (j = i + 1; j < blks && (seg_end - seg_begin) < dseg->req_size; j++) - { - seg_tmp = dseg->blk_ptr[j]; - /* Check untagged blocks only */ - if ((seg_tmp & 3) == DAL_UNTAG_BLOCK) - { - if (seg_tmp == (seg_begin - dseg->blk_size)) - { - /* Found adjacent block below current segment */ - dseg->blk_ptr[j] |= DAL_CUR_MATCH_BLOCk; - seg_begin = seg_tmp; - found = 1; - } - else if (seg_tmp == seg_end) - { - /* Found adjacent block above current segment */ - dseg->blk_ptr[j] |= DAL_CUR_MATCH_BLOCk; - seg_end += dseg->blk_size; - found = 1; - } - } - } - } - while (found); - - if ((seg_end - seg_begin) > dseg->seg_size) - { - /* The current block is largest so far */ - dseg->seg_begin = seg_begin; - dseg->seg_end = seg_end; - dseg->seg_size = seg_end - seg_begin; - - /* Re-tag current and previous largest segment */ - for (j = 0; j < blks; j++) - { - if ((dseg->blk_ptr[j] & 3) == DAL_CUR_MATCH_BLOCk) - { - /* Tag current segment as the largest */ - dseg->blk_ptr[j] &= ~1; - } - else if ((dseg->blk_ptr[j] & 3) == DAL_MATCHED_BLOCK) - { - /* Discard previous largest segment */ - dseg->blk_ptr[j] ^= 3; - } - } - } - else - { - /* Discard all blocks in current segment */ - for (j = 0; j < blks; j++) - { - if ((dseg->blk_ptr[j] & 3) == DAL_CUR_MATCH_BLOCk) - { - dseg->blk_ptr[j] &= ~2; - } - } - } - } - } - - return 0; -} - -/* - * Function: _alloc_dma_blocks - */ -static int -_dal_alloc_dma_blocks(dma_segment_t* dseg, int blks) -{ - int i, start; - unsigned long addr; - - if (dseg->blk_cnt + blks > dseg->blk_cnt_max) - { - printk("No more DMA blocks\n"); - return -1; - } - - start = dseg->blk_cnt; - dseg->blk_cnt += blks; - - for (i = start; i < dseg->blk_cnt; i++) - { - addr = __get_free_pages(GFP_ATOMIC, dseg->blk_order); - if (addr) - { - dseg->blk_ptr[i] = addr; - } - else - { - printk("DMA allocation failed\n"); - return -1; - } - } - - return 0; -} - -/* - * Function: _dal_dma_segment_alloc - */ -static dma_segment_t* -_dal_dma_segment_alloc(unsigned int size, unsigned int blk_size) -{ - dma_segment_t* dseg; - int i, blk_ptr_size; - unsigned long page_addr; - struct sysinfo si; - - /* Sanity check */ - if (size == 0 || blk_size == 0) - { - return NULL; - } - - /* Allocate an initialize DMA segment descriptor */ - if ((dseg = kmalloc(sizeof(dma_segment_t), GFP_ATOMIC)) == NULL) - { - return NULL; - } - - memset(dseg, 0, sizeof(dma_segment_t)); - dseg->req_size = size; - dseg->blk_size = PAGE_ALIGN(blk_size); - - while ((PAGE_SIZE << dseg->blk_order) < dseg->blk_size) - { - dseg->blk_order++; - } - - si_meminfo(&si); - dseg->blk_cnt_max = (si.totalram << PAGE_SHIFT) / dseg->blk_size; - blk_ptr_size = dseg->blk_cnt_max * sizeof(unsigned long); - /* Allocate an initialize DMA block pool */ - dseg->blk_ptr = kmalloc(blk_ptr_size, GFP_KERNEL); - if (dseg->blk_ptr == NULL) - { - kfree(dseg); - return NULL; - } - - memset(dseg->blk_ptr, 0, blk_ptr_size); - /* Allocate minimum number of blocks */ - _dal_alloc_dma_blocks(dseg, dseg->req_size / dseg->blk_size); - - /* Allocate more blocks until we have a complete segment */ - do - { - _dal_find_largest_segment(dseg); - if (dseg->seg_size >= dseg->req_size) - { - break; - } - } - while (_dal_alloc_dma_blocks(dseg, 8) == 0); - - /* Reserve all pages in the DMA segment and free unused blocks */ - for (i = 0; i < dseg->blk_cnt; i++) - { - if ((dseg->blk_ptr[i] & 3) == 2) - { - dseg->blk_ptr[i] &= ~3; - - for (page_addr = dseg->blk_ptr[i]; - page_addr < dseg->blk_ptr[i] + dseg->blk_size; - page_addr += PAGE_SIZE) - { - MEM_MAP_RESERVE(VIRT_TO_PAGE((void*)page_addr)); - } - } - else if (dseg->blk_ptr[i]) - { - dseg->blk_ptr[i] &= ~3; - free_pages(dseg->blk_ptr[i], dseg->blk_order); - dseg->blk_ptr[i] = 0; - } - } - - return dseg; -} - -/* - * Function: _dal_dma_segment_free - */ -static void -_dal_dma_segment_free(dma_segment_t* dseg) -{ - int i; - unsigned long page_addr; - - if (dseg->blk_ptr) - { - for (i = 0; i < dseg->blk_cnt; i++) - { - if (dseg->blk_ptr[i]) - { - for (page_addr = dseg->blk_ptr[i]; - page_addr < dseg->blk_ptr[i] + dseg->blk_size; - page_addr += PAGE_SIZE) - { - MEM_MAP_UNRESERVE(VIRT_TO_PAGE(page_addr)); - } - - free_pages(dseg->blk_ptr[i], dseg->blk_order); - } - } - - kfree(dseg->blk_ptr); - kfree(dseg); - } -} - -/* - * Function: -dal_pgalloc - */ -static void* -_dal_pgalloc(unsigned int size) -{ - dma_segment_t* dseg; - unsigned int blk_size; - - blk_size = (size < DMA_BLOCK_SIZE) ? size : DMA_BLOCK_SIZE; - if ((dseg = _dal_dma_segment_alloc(size, blk_size)) == NULL) - { - return NULL; - } - - if (dseg->seg_size < size) - { - /* If we didn't get the full size then forget it */ - printk("Notice: Can not get enough memory for requset!!\n"); - printk("actual size:0x%lx, request size:0x%x\n", dseg->seg_size, size); - //-_dal_dma_segment_free(dseg); - //-return NULL; - } - - list_add(&dseg->list, &_dma_seg); - return (void*)dseg->seg_begin; -} - -/* - * Function: _dal_pgfree - */ -static int -_dal_pgfree(void* ptr) -{ - struct list_head* pos; - - list_for_each(pos, &_dma_seg) - { - dma_segment_t* dseg = list_entry(pos, dma_segment_t, list); - if (ptr == (void*)dseg->seg_begin) - { - list_del(&dseg->list); - _dal_dma_segment_free(dseg); - return 0; - } - } - return -1; -} -#endif -static void -dal_alloc_dma_pool(int lchip, int size) -{ - if (use_high_memory) - { - dma_phy_base[lchip] = virt_to_bus(high_memory); - dma_virt_base[lchip] = ioremap_nocache(dma_phy_base[lchip], size); - } - else - { -#ifdef DMA_MEM_MODE_PLATFORM - dma_virt_base[lchip] = dma_alloc_coherent(&(dal_dev[lchip].pci_dev->dev), dma_mem_size, - &dma_phy_base[lchip], GFP_KERNEL); - - printk(KERN_WARNING "########Using DMA_MEM_MODE_PLATFORM \n"); -#endif - -#ifndef DMA_MEM_MODE_PLATFORM - /* Get DMA memory from kernel */ - dma_virt_base_tmp[lchip] = _dal_pgalloc(size); - dma_phy_base[lchip] = virt_to_bus(dma_virt_base_tmp[lchip]); - dma_virt_base [lchip]= ioremap_nocache(dma_phy_base[lchip], size); -#endif - } -} - -static void -dal_free_dma_pool(int lchip) -{ - int ret = 0; - ret = ret; - if (use_high_memory) - { - iounmap(dma_virt_base[lchip]); - } - else - { -#ifdef DMA_MEM_MODE_PLATFORM - dma_free_coherent(&(dal_dev[lchip].pci_dev->dev), dma_mem_size, - dma_virt_base[lchip], dma_phy_base[lchip]); -#endif - -#ifndef DMA_MEM_MODE_PLATFORM - iounmap(dma_virt_base[lchip]); - ret = _dal_pgfree(dma_virt_base_tmp[lchip]); - if(ret<0) - { - printk("Dma free memory fail !!!!!! \n"); - } -#endif - } -} - -#define _KERNEL_DAL_IO -static int -_dal_pci_read(unsigned char lchip, unsigned int offset, unsigned int* value) -{ - if (!VERIFY_CHIP_INDEX(lchip)) - { - return -1; - } - - *value = *(volatile unsigned int*)(dal_dev[lchip].logic_address + offset); - return 0; -} - -int -dal_create_irq_mapping(unsigned long arg) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) - -#ifndef NO_IRQ -#define NO_IRQ (-1) -#endif - dal_irq_mapping_t irq_map; - - if (copy_from_user(&irq_map, (void*)arg, sizeof(dal_irq_mapping_t))) - { - return -EFAULT; - } - - irq_map.sw_irq = irq_create_mapping(NULL, irq_map.hw_irq); - if (irq_map.sw_irq == NO_IRQ) - { - printk("IRQ mapping fail !!!!!! \n"); - return -1; - } - - if (copy_to_user((dal_irq_mapping_t*)arg, (void*)&irq_map, sizeof(dal_irq_mapping_t))) - { - return -EFAULT; - } -#endif - return 0; -} - -int -dal_pci_read(unsigned long arg) -{ - dal_chip_parm_t cmdpara_chip; - - if (copy_from_user(&cmdpara_chip, (void*)arg, sizeof(dal_chip_parm_t))) - { - return -EFAULT; - } - - _dal_pci_read((unsigned char)cmdpara_chip.lchip, (unsigned int)cmdpara_chip.reg_addr, - (unsigned int*)(&(cmdpara_chip.value))); - - if (copy_to_user((dal_chip_parm_t*)arg, (void*)&cmdpara_chip, sizeof(dal_chip_parm_t))) - { - return -EFAULT; - } - - return 0; -} - -static int -_dal_pci_write(unsigned char lchip, unsigned int offset, unsigned int value) -{ - if (!VERIFY_CHIP_INDEX(lchip)) - { - return -1; - } - - *(volatile unsigned int*)(dal_dev[lchip].logic_address + offset) = value; - return 0; -} - -int -dal_pci_write(unsigned long arg) -{ - dal_chip_parm_t cmdpara_chip; - - if (copy_from_user(&cmdpara_chip, (void*)arg, sizeof(dal_chip_parm_t))) - { - return -EFAULT; - } - - _dal_pci_write((unsigned char)cmdpara_chip.lchip, (unsigned int)cmdpara_chip.reg_addr, - (unsigned int)cmdpara_chip.value); - - return 0; -} - -int -dal_pci_conf_read(unsigned char lchip, unsigned int offset, unsigned int* value) -{ - if (!VERIFY_CHIP_INDEX(lchip)) - { - return -1; - } - - pci_read_config_dword(dal_dev[lchip].pci_dev, offset, value); - return 0; -} - -int -dal_pci_conf_write(unsigned char lchip, unsigned int offset, unsigned int value) -{ - if (!VERIFY_CHIP_INDEX(lchip)) - { - return -1; - } - - pci_write_config_dword(dal_dev[lchip].pci_dev, offset, value); - return 0; -} -int -dal_user_read_pci_conf(unsigned long arg) -{ - dal_pci_cfg_ioctl_t dal_cfg; - - if (copy_from_user(&dal_cfg, (void*)arg, sizeof(dal_pci_cfg_ioctl_t))) - { - return -EFAULT; - } - - if (dal_pci_conf_read(dal_cfg.lchip, dal_cfg.offset, &dal_cfg.value)) - { - printk("dal_pci_conf_read failed.\n"); - return -EFAULT; - } - - if (copy_to_user((dal_pci_cfg_ioctl_t*)arg, (void*)&dal_cfg, sizeof(dal_pci_cfg_ioctl_t))) - { - return -EFAULT; - } - - return 0; -} - -int -dal_user_write_pci_conf(unsigned long arg) -{ - dal_pci_cfg_ioctl_t dal_cfg; - - if (copy_from_user(&dal_cfg, (void*)arg, sizeof(dal_pci_cfg_ioctl_t))) - { - return -EFAULT; - } - - return dal_pci_conf_write(dal_cfg.lchip, dal_cfg.offset, dal_cfg.value); -} - -static int -linux_get_device(unsigned long arg) -{ - dal_user_dev_t user_dev; - int lchip = 0; - - if (copy_from_user(&user_dev, (void*)arg, sizeof(user_dev))) - { - return -EFAULT; - } - - user_dev.chip_num = dal_chip_num; - lchip = user_dev.lchip; - - if (lchip < dal_chip_num) - { - user_dev.phy_base0 = (unsigned int)dal_dev[lchip].phys_address; - user_dev.phy_base1 = (unsigned int)(dal_dev[lchip].phys_address >> 32); - - user_dev.bus_no = dal_dev[lchip].pci_dev->bus->number; - user_dev.dev_no = dal_dev[lchip].pci_dev->device; - user_dev.fun_no = dal_dev[lchip].pci_dev->devfn; - } - - if (copy_to_user((dal_user_dev_t*)arg, (void*)&user_dev, sizeof(user_dev))) - { - return -EFAULT; - } - - return 0; -} - -/* set dal version, copy to user */ -static int -linux_get_dal_version(unsigned long arg) -{ - int dal_ver = VERSION_1DOT2; /* set dal version */ - - if (copy_to_user((int*)arg, (void*)&dal_ver, sizeof(dal_ver))) - { - return -EFAULT; - } - - dal_version = dal_ver; /* up sw */ - - return 0; -} - -static int -linux_get_dma_info(unsigned long arg) -{ - dma_info_t dma_para; - - if (copy_from_user(&dma_para, (void*)arg, sizeof(dma_info_t))) - { - return -EFAULT; - } - - dma_para.phy_base = (unsigned int)dma_phy_base[dma_para.lchip]; - dma_para.phy_base_hi = dma_phy_base[dma_para.lchip] >> 32; - dma_para.size = dma_mem_size; - - if (copy_to_user((dma_info_t*)arg, (void*)&dma_para, sizeof(dma_info_t))) - { - return -EFAULT; - } - - return 0; -} - -static int -dal_get_msi_info(unsigned long arg) -{ - dal_msi_info_t msi_para; - unsigned int lchip = 0; - - /* get lchip form user mode */ - if (copy_from_user(&msi_para, (void*)arg, sizeof(dal_msi_info_t))) - { - return -EFAULT; - } - lchip = msi_para.lchip; - - msi_para.irq_base = msi_irq_base[lchip]; - msi_para.irq_num = msi_irq_num[lchip]; - - /* send msi info to user mode */ - if (copy_to_user((dal_msi_info_t*)arg, (void*)&msi_para, sizeof(dal_msi_info_t))) - { - return -EFAULT; - } - - return 0; -} - - -static int -dal_get_intr_info(unsigned long arg) -{ - dal_intr_info_t intr_para; - unsigned int intr_num = 0; - - /* get lchip form user mode */ - if (copy_from_user(&intr_para, (void*)arg, sizeof(dal_intr_info_t))) - { - return -EFAULT; - } - - intr_para.irq_idx = CTC_MAX_INTR_NUM; - for (intr_num=0; intr_num< CTC_MAX_INTR_NUM; intr_num++) - { - if (intr_para.irq == dal_isr[intr_num].irq) - { - intr_para.irq_idx = intr_num; - break; - } - } - - if (CTC_MAX_INTR_NUM == intr_para.irq_idx) - { - printk("Interrupt %d cann't find.\n", intr_para.irq); - } - /* send msi info to user mode */ - if (copy_to_user((dal_intr_info_t*)arg, (void*)&intr_para, sizeof(dal_intr_info_t))) - { - return -EFAULT; - } - - return 0; -} - -static int -dal_cache_inval(unsigned long arg) -{ - dal_dma_cache_info_t intr_para; - - if (copy_from_user(&intr_para, (void*)arg, sizeof(dal_dma_cache_info_t))) - { - return -EFAULT; - } - -#if 0 - dma_cache_wback_inv((unsigned long)intr_para.ptr, intr_para.length); -#endif - -#if 0 - dma_sync_single_for_cpu(NULL, intr_para.ptr, intr_para.length, DMA_BIDIRECTIONAL); - - - dma_cache_sync(NULL, (void*)intr_para.ptr, intr_para.length, DMA_BIDIRECTIONAL); -#endif - return 0; -} - -static int -dal_cache_flush(unsigned long arg) -{ - dal_dma_cache_info_t intr_para; - - if (copy_from_user(&intr_para, (void*)arg, sizeof(dal_dma_cache_info_t))) - { - return -EFAULT; - } - -#if 0 - dma_cache_wback_inv(intr_para.ptr, intr_para.length); -#endif - -#if 0 - dma_sync_single_for_cpu(NULL, intr_para.ptr, intr_para.length, DMA_BIDIRECTIONAL); - - - dma_cache_sync(NULL, (void*)intr_para.ptr, intr_para.length, DMA_BIDIRECTIONAL); -#endif - return 0; -} - -int -linux_dal_probe(struct pci_dev* pdev, const struct pci_device_id* id) -{ - dal_kern_dev_t* dev = NULL; - int bar = 0; - int ret = 0; - unsigned int temp = 0; - unsigned int lchip = 0; - - printk(KERN_WARNING "********found dal device*****\n"); - - for (lchip = 0; lchip < DAL_MAX_CHIP_NUM; lchip ++) - { - if (NULL == dal_dev[lchip].pci_dev) - { - break; - } - } - - if (lchip >= DAL_MAX_CHIP_NUM) - { - printk("Exceed max local chip num\n"); - return -1; - } - - dev = &dal_dev[lchip]; - if (NULL == dev) - { - printk("Cannot obtain PCI resources\n"); - } - - lchip = lchip; - dal_chip_num += 1; - - dev->pci_dev = pdev; - - if (pci_enable_device(pdev) < 0) - { - printk("Cannot enable PCI device: vendor id = %x, device id = %x\n", - pdev->vendor, pdev->device); - } - - ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); - if (ret) - { - ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); - if (ret) - { - printk("Could not set PCI DMA Mask\n"); - return ret; - } - } - - if (pci_request_regions(pdev, DAL_NAME) < 0) - { - printk("Cannot obtain PCI resources\n"); - } - - dev->phys_address = pci_resource_start(pdev, bar); - dev->logic_address = (uintptr)ioremap_nocache(dev->phys_address, - pci_resource_len(dev->pci_dev, bar)); - - _dal_pci_read(lchip, 0x48, &temp); - if (((temp >> 8) & 0xffff) == 0x3412) - { - printk("Little endian Cpu detected!!! \n"); - _dal_pci_write(lchip, 0x48, 0xFFFFFFFF); - } - - pci_set_master(pdev); - - /* alloc dma_mem_size for every chip */ - if (dma_mem_size) - { - dal_alloc_dma_pool(lchip, dma_mem_size); - - /*add check Dma memory pool cannot cross 4G space*/ - if ((0==(dma_phy_base[lchip]>>32)) && (0!=((dma_phy_base[lchip]+dma_mem_size)>>32))) - { - printk("Dma malloc memory cross 4G space!!!!!! \n"); - return -1; - } - } - - printk(KERN_WARNING "linux_dal_probe end*****\n"); - - return 0; -} - -void -linux_dal_remove(struct pci_dev* pdev) -{ - unsigned int lchip = 0; - unsigned int flag = 0; - - for (lchip = 0; lchip < DAL_MAX_CHIP_NUM; lchip ++) - { - if (pdev == dal_dev[lchip].pci_dev) - { - flag = 1; - break; - } - } - - if (1 == flag) - { - dal_free_dma_pool(lchip); - pci_release_regions(pdev); - pci_disable_device(pdev); - - dal_dev[lchip].pci_dev = NULL; - dal_chip_num--; - } - - -} - -#ifdef CONFIG_COMPAT -static long -linux_dal_ioctl(struct file* file, - unsigned int cmd, unsigned long arg) -#else - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)) -static int -linux_dal_ioctl(struct file* file, - unsigned int cmd, unsigned long arg) -#else -static int -linux_dal_ioctl(struct inode* inode, struct file* file, - unsigned int cmd, unsigned long arg) -#endif - -#endif -{ - switch (cmd) - { - - case CMD_READ_CHIP: - return dal_pci_read(arg); - - case CMD_WRITE_CHIP: - return dal_pci_write(arg); - - case CMD_GET_DEVICES: - return linux_get_device(arg); - - case CMD_GET_DAL_VERSION: - return linux_get_dal_version(arg); - - case CMD_GET_DMA_INFO: - return linux_get_dma_info(arg); - - case CMD_PCI_CONFIG_READ: - return dal_user_read_pci_conf(arg); - - case CMD_PCI_CONFIG_WRITE: - return dal_user_write_pci_conf(arg); - - case CMD_REG_INTERRUPTS: - return dal_user_interrupt_register(arg); - - case CMD_UNREG_INTERRUPTS: - return dal_user_interrupt_unregister(arg); - - case CMD_EN_INTERRUPTS: - return dal_user_interrupt_set_en(arg); - - case CMD_SET_MSI_CAP: - return dal_set_msi_cap(arg); - - case CMD_GET_MSI_INFO: - return dal_get_msi_info(arg); - - case CMD_IRQ_MAPPING: - return dal_create_irq_mapping(arg); - - case CMD_GET_INTR_INFO: - return dal_get_intr_info(arg); - - case CMD_CACHE_INVAL: - return dal_cache_inval(arg); - - case CMD_CACHE_FLUSH: - return dal_cache_flush(arg); - - default: - break; - } - - return 0; -} - -static unsigned int -linux_dal_poll0(struct file* filp, struct poll_table_struct* p) -{ - unsigned int mask = 0; - unsigned long flags; - - poll_wait(filp, &poll_intr[0], p); - local_irq_save(flags); - if (poll_intr_trigger[0]) - { - poll_intr_trigger[0] = 0; - mask |= POLLIN | POLLRDNORM; - } - - local_irq_restore(flags); - - return mask; -} - -static unsigned int -linux_dal_poll1(struct file* filp, struct poll_table_struct* p) -{ - unsigned int mask = 0; - unsigned long flags; - - poll_wait(filp, &poll_intr[1], p); - local_irq_save(flags); - if (poll_intr_trigger[1]) - { - poll_intr_trigger[1] = 0; - mask |= POLLIN | POLLRDNORM; - } - - local_irq_restore(flags); - - return mask; -} - -static unsigned int -linux_dal_poll2(struct file* filp, struct poll_table_struct* p) -{ - unsigned int mask = 0; - unsigned long flags; - - poll_wait(filp, &poll_intr[2], p); - local_irq_save(flags); - if (poll_intr_trigger[2]) - { - poll_intr_trigger[2] = 0; - mask |= POLLIN | POLLRDNORM; - } - - local_irq_restore(flags); - - return mask; -} - -static unsigned int -linux_dal_poll3(struct file* filp, struct poll_table_struct* p) -{ - unsigned int mask = 0; - unsigned long flags; - - poll_wait(filp, &poll_intr[3], p); - local_irq_save(flags); - if (poll_intr_trigger[3]) - { - poll_intr_trigger[3] = 0; - mask |= POLLIN | POLLRDNORM; - } - - local_irq_restore(flags); - - return mask; -} - -static unsigned int -linux_dal_poll4(struct file* filp, struct poll_table_struct* p) -{ - unsigned int mask = 0; - unsigned long flags; - - poll_wait(filp, &poll_intr[4], p); - local_irq_save(flags); - if (poll_intr_trigger[4]) - { - poll_intr_trigger[4] = 0; - mask |= POLLIN | POLLRDNORM; - } - - local_irq_restore(flags); - - return mask; -} - -static unsigned int -linux_dal_poll5(struct file* filp, struct poll_table_struct* p) -{ - unsigned int mask = 0; - unsigned long flags; - - poll_wait(filp, &poll_intr[5], p); - local_irq_save(flags); - if (poll_intr_trigger[5]) - { - poll_intr_trigger[5] = 0; - mask |= POLLIN | POLLRDNORM; - } - - local_irq_restore(flags); - - return mask; -} - -static unsigned int -linux_dal_poll6(struct file* filp, struct poll_table_struct* p) -{ - unsigned int mask = 0; - unsigned long flags; - - poll_wait(filp, &poll_intr[6], p); - local_irq_save(flags); - if (poll_intr_trigger[6]) - { - poll_intr_trigger[6] = 0; - mask |= POLLIN | POLLRDNORM; - } - - local_irq_restore(flags); - - return mask; -} - -static unsigned int -linux_dal_poll7(struct file* filp, struct poll_table_struct* p) -{ - unsigned int mask = 0; - unsigned long flags; - - poll_wait(filp, &poll_intr[7], p); - local_irq_save(flags); - if (poll_intr_trigger[7]) - { - poll_intr_trigger[7] = 0; - mask |= POLLIN | POLLRDNORM; - } - - local_irq_restore(flags); - - return mask; -} - -static struct pci_driver linux_dal_driver = -{ - .name = DAL_NAME, - .id_table = dal_id_table, - .probe = linux_dal_probe, - .remove = linux_dal_remove, -}; - -static struct file_operations fops = -{ - .owner = THIS_MODULE, -#ifdef CONFIG_COMPAT - .compat_ioctl = linux_dal_ioctl, - .unlocked_ioctl = linux_dal_ioctl, -#else -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)) - .unlocked_ioctl = linux_dal_ioctl, -#else - .ioctl = linux_dal_ioctl, -#endif -#endif -}; - - -static int __init -linux_dal_init(void) -{ - int ret = 0; - - /* Get DMA memory pool size form dal.ok input param, or use default dma_mem_size */ - if (dma_pool_size) - { - if ((dma_pool_size[strlen(dma_pool_size) - 1] & ~0x20) == 'M') - { - dma_mem_size = simple_strtoul(dma_pool_size, NULL, 0); - printk("dma_mem_size: 0x%x \n", dma_mem_size); - - dma_mem_size *= MB_SIZE; - } - else - { - printk("DMA memory pool size must be specified as e.g. dma_pool_size=8M\n"); - } - - if (dma_mem_size & (dma_mem_size - 1)) - { - printk("dma_mem_size must be a power of 2 (1M, 2M, 4M, 8M etc.)\n"); - dma_mem_size = 0; - } - } - - ret = register_chrdev(DAL_DEV_MAJOR, DAL_NAME, &fops); - if (ret < 0) - { - printk(KERN_WARNING "Register linux_dal device, ret %d\n", ret); - return ret; - } - - ret = pci_register_driver(&linux_dal_driver); - if (ret < 0) - { - printk(KERN_WARNING "Register ASIC PCI driver failed, ret %d\n", ret); - return ret; - } - - /* alloc /dev/linux_dal node */ - dal_class = class_create(THIS_MODULE, DAL_NAME); - device_create(dal_class, NULL, MKDEV(DAL_DEV_MAJOR, 0), NULL, DAL_NAME); - - /* init interrupt function */ - intr_handler_fun[0] = intr0_handler; - intr_handler_fun[1] = intr1_handler; - intr_handler_fun[2] = intr2_handler; - intr_handler_fun[3] = intr3_handler; - intr_handler_fun[4] = intr4_handler; - intr_handler_fun[5] = intr5_handler; - intr_handler_fun[6] = intr6_handler; - intr_handler_fun[7] = intr7_handler; - - return ret; -} - -static void __exit -linux_dal_exit(void) -{ - device_destroy(dal_class, MKDEV(DAL_DEV_MAJOR, 0)); - class_destroy(dal_class); - unregister_chrdev(DAL_DEV_MAJOR, "linux_dal"); - pci_unregister_driver(&linux_dal_driver); -} - -module_init(linux_dal_init); -module_exit(linux_dal_exit); - - diff --git a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_kernel.h b/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_kernel.h deleted file mode 100644 index 850a4cffa731..000000000000 --- a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_kernel.h +++ /dev/null @@ -1,171 +0,0 @@ -/** - @file dal_kernel_io.h - - @author Copyright (C) 2012 Centec Networks Inc. All rights reserved. - - @date 2012-4-9 - - @version v2.0 - -*/ -#ifndef _DAL_KERNEL_H_ -#define _DAL_KERNEL_H_ -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(CONFIG_RESOURCES_64BIT) || defined(CONFIG_PHYS_ADDR_T_64BIT) -#define PHYS_ADDR_IS_64BIT -#endif - -#ifndef SDK_IN_USERMODE -#ifdef PHYS_ADDR_IS_64BIT -typedef long long intptr; -typedef unsigned long long uintptr; -#else -typedef int intptr; -typedef unsigned int uintptr; -#endif -#endif - -#define DAL_PCI_READ_ADDR 0x0 -#define DAL_PCI_READ_DATA 0xc -#define DAL_PCI_WRITE_ADDR 0x8 -#define DAL_PCI_WRITE_DATA 0x4 -#define DAL_PCI_STATUS 0x10 - -#define DAL_PCI_STATUS_IN_PROCESS 31 -#define DAL_PCI_STATUS_BAD_PARITY 5 -#define DAL_PCI_STATUS_CPU_ACCESS_ERR 4 -#define DAL_PCI_STATUS_READ_CMD 3 -#define DAL_PCI_STATUS_REGISTER_ERR 1 -#define DAL_PCI_STATUS_REGISTER_ACK 0 - -#define DAL_PCI_ACCESS_TIMEOUT 0x64 - -#define DAL_NAME "linux_dal" /* "linux_dal" */ - -#define DAL_DEV_MAJOR 198 - -#define DAL_DEV_INTR_MAJOR_BASE 200 - -#define DAL_DEV_NAME "/dev/" DAL_NAME -#define DAL_ONE_KB 1024 -#define DAL_ONE_MB (1024*1024) -struct dal_chip_parm_s -{ - unsigned int lchip; /*tmp should be uint8*/ - unsigned int fpga_id; /*tmp add*/ - unsigned int reg_addr; - unsigned int value; -}; -typedef struct dal_chip_parm_s dal_chip_parm_t; - -struct dal_intr_parm_s -{ - unsigned int irq; - unsigned int enable; -}; -typedef struct dal_intr_parm_s dal_intr_parm_t; - -struct dal_irq_mapping_s -{ - unsigned int hw_irq; - unsigned int sw_irq; -}; -typedef struct dal_irq_mapping_s dal_irq_mapping_t; - -struct dal_user_dev_s -{ - unsigned int chip_num; /*output: local chip number*/ - unsigned int lchip; /*input: local chip id*/ - unsigned int phy_base0; /* low 32bits physical base address */ - unsigned int phy_base1; /* high 32bits physical base address */ - unsigned int bus_no; - unsigned int dev_no; - unsigned int fun_no; - void* virt_base[2]; /* Virtual base address; this must be last member */ -}; -typedef struct dal_user_dev_s dal_user_dev_t; - -struct dma_info_s -{ - unsigned int lchip; - unsigned int phy_base; - unsigned int phy_base_hi; - unsigned int size; - unsigned int* virt_base; -}; -typedef struct dma_info_s dma_info_t; - -struct dal_pci_cfg_ioctl_s -{ - unsigned int lchip; /* Device ID */ - unsigned int offset; - unsigned int value; -}; -typedef struct dal_pci_cfg_ioctl_s dal_pci_cfg_ioctl_t; - -struct dal_msi_info_s -{ - unsigned int lchip; - unsigned int irq_base; - unsigned int irq_num; -}; -typedef struct dal_msi_info_s dal_msi_info_t; - -struct dal_intr_info_s -{ - unsigned int irq; - unsigned int irq_idx; -}; -typedef struct dal_intr_info_s dal_intr_info_t; - -struct dal_dma_cache_info_s -{ - unsigned long ptr; - unsigned int length; -}; -typedef struct dal_dma_cache_info_s dal_dma_cache_info_t; - -#define CMD_MAGIC 'C' -#define CMD_WRITE_CHIP _IO(CMD_MAGIC, 0) /* for humber ioctrol*/ -#define CMD_READ_CHIP _IO(CMD_MAGIC, 1) /* for humber ioctrol*/ -#define CMD_GET_DEVICES _IO(CMD_MAGIC, 2) -#define CMD_GET_DAL_VERSION _IO(CMD_MAGIC, 3) -#define CMD_PCI_CONFIG_WRITE _IO(CMD_MAGIC, 4) -#define CMD_PCI_CONFIG_READ _IO(CMD_MAGIC, 5) -#define CMD_GET_DMA_INFO _IO(CMD_MAGIC, 6) -#define CMD_REG_INTERRUPTS _IO(CMD_MAGIC, 7) -#define CMD_UNREG_INTERRUPTS _IO(CMD_MAGIC, 8) -#define CMD_EN_INTERRUPTS _IO(CMD_MAGIC, 9) -#define CMD_I2C_READ _IO(CMD_MAGIC, 10) -#define CMD_I2C_WRITE _IO(CMD_MAGIC, 11) -#define CMD_GET_MSI_INFO _IO(CMD_MAGIC, 12) -#define CMD_SET_MSI_CAP _IO(CMD_MAGIC, 13) -#define CMD_IRQ_MAPPING _IO(CMD_MAGIC, 14) -#define CMD_GET_INTR_INFO _IO(CMD_MAGIC, 15) -#define CMD_CACHE_INVAL _IO(CMD_MAGIC, 16) -#define CMD_CACHE_FLUSH _IO(CMD_MAGIC, 17) - -enum dal_version_e -{ - VERSION_MIN, - VERSION_1DOT0, - VERSION_1DOT1, - VERSION_1DOT2, - - VERSION_MAX -}; -typedef enum dal_version_e dal_version_t; - -/* We try to assemble a contiguous segment from chunks of this size */ -#define DMA_BLOCK_SIZE (512 * DAL_ONE_KB) - -#ifdef __cplusplus -} -#endif - -#endif - - diff --git a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_mpool.c b/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_mpool.c deleted file mode 100644 index 5aca222a138f..000000000000 --- a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_mpool.c +++ /dev/null @@ -1,350 +0,0 @@ -#include "dal_mpool.h" - -#ifdef __KERNEL__ -#include -#include - -#define DAL_MALLOC(x) kmalloc(x, GFP_ATOMIC) -#define DAL_FREE(x) kfree(x) - -static spinlock_t dal_mpool_lock; -#define MPOOL_LOCK_INIT() spin_lock_init(&dal_mpool_lock) -#define MPOOL_LOCK() unsigned long flags; spin_lock_irqsave(&dal_mpool_lock, flags) -#define MPOOL_UNLOCK() spin_unlock_irqrestore(&dal_mpool_lock, flags) -#define DAL_PRINT(fmt,arg...) printk(fmt,##arg) -#else /* !__KERNEL__*/ - -#include -#include "sal.h" -#define DAL_MALLOC(x) malloc(x) -#define DAL_FREE(x) free(x) -static sal_mutex_t* dal_mpool_lock; -#define MPOOL_LOCK_INIT() sal_mutex_create(&dal_mpool_lock) -#define MPOOL_LOCK() sal_mutex_lock(dal_mpool_lock) -#define MPOOL_UNLOCK() sal_mutex_unlock(dal_mpool_lock) -#define DAL_PRINT(fmt,arg...) sal_printf(fmt,##arg) - -#endif /* __KERNEL__ */ - - - -dal_mpool_mem_t* g_free_block_ptr = NULL; - -/* System cache line size */ -#ifndef DAL_CACHE_LINE_BYTES -#define DAL_CACHE_LINE_BYTES 256 -#endif - -#define DAL_MAX_CHIP_NUM 32 -static dal_mpool_mem_t* p_desc_pool[DAL_MAX_CHIP_NUM] = {0}; -static dal_mpool_mem_t* p_data_pool[DAL_MAX_CHIP_NUM] = {0}; - -int -dal_mpool_init(void) -{ - MPOOL_LOCK_INIT(); - return 0; -} - -dal_mpool_mem_t* -_dal_mpool_create(void* base, int size, int type) -{ - dal_mpool_mem_t* head = NULL; - dal_mpool_mem_t* tail = NULL; - - head = (dal_mpool_mem_t*)DAL_MALLOC(sizeof(dal_mpool_mem_t)); - if (head == NULL) - { - return NULL; - } - - tail = (dal_mpool_mem_t*)DAL_MALLOC(sizeof(dal_mpool_mem_t)); - if (tail == NULL) - { - DAL_FREE(head); - return NULL; - } - - head->size = tail->size = 0; - head->type = type; - head->address = base; - tail->address = head->address + size; - head->next = tail; - tail->next = NULL; - - return head; -} - -dal_mpool_mem_t* -dal_mpool_create(unsigned char lchip, void* base, int size) -{ - dal_mpool_mem_t* head = NULL; - int mod = (int)(((unsigned long)base) & (DAL_CACHE_LINE_BYTES - 1)); - - MPOOL_LOCK(); - - if (mod) - { - base = (char*)base + (DAL_CACHE_LINE_BYTES - mod); - size -= (DAL_CACHE_LINE_BYTES - mod); - } - - size &= ~(DAL_CACHE_LINE_BYTES - 1); - - /* init for common linkptr, only used for GB */ - head = _dal_mpool_create(base, size, DAL_MPOOL_TYPE_USELESS); - if (NULL == head) - { - MPOOL_UNLOCK(); - return NULL; - } - - /* init for desc linkptr */ - p_desc_pool[lchip] = _dal_mpool_create(base, DAL_MPOOL_MAX_DESX_SIZE, DAL_MPOOL_TYPE_DESC); - if (NULL == p_desc_pool[lchip]) - { - MPOOL_UNLOCK(); - DAL_FREE(head->next); - DAL_FREE(head); - return NULL; - } - - /* init for data linkptr */ - p_data_pool[lchip] = _dal_mpool_create(((char*)base+DAL_MPOOL_MAX_DESX_SIZE), (size - DAL_MPOOL_MAX_DESX_SIZE), DAL_MPOOL_TYPE_DATA); - if (NULL == p_data_pool[lchip]) - { - MPOOL_UNLOCK(); - DAL_FREE(head->next); - DAL_FREE(head); - DAL_FREE(p_desc_pool[lchip]->next); - DAL_FREE(p_desc_pool[lchip]); - return NULL; - } - - MPOOL_UNLOCK(); - - return head; -} - -dal_mpool_mem_t* -_dal_mpool_alloc_comon(dal_mpool_mem_t* ptr, int size, int type) -{ - dal_mpool_mem_t* new_ptr = NULL; - - while (ptr && ptr->next) - { - if (ptr->next->address - (ptr->address + ptr->size) >= size) - { - break; - } - - ptr = ptr->next; - } - - if (!(ptr && ptr->next)) - { - return NULL; - } - - new_ptr = DAL_MALLOC(sizeof(dal_mpool_mem_t)); - if (!new_ptr) - { - return NULL; - } - - new_ptr->type = type; - new_ptr->address = ptr->address + ptr->size; - new_ptr->size = size; - new_ptr->next = ptr->next; - ptr->next = new_ptr; - - return new_ptr; -} - -void* -dal_mpool_alloc(unsigned char lchip, dal_mpool_mem_t* pool, int size, int type) -{ - dal_mpool_mem_t* ptr = NULL; - dal_mpool_mem_t* new_ptr = NULL; - int mod; - - MPOOL_LOCK(); - - mod = size & (DAL_CACHE_LINE_BYTES - 1); - if (mod != 0) - { - size += (DAL_CACHE_LINE_BYTES - mod); - } - - switch(type) - { - case DAL_MPOOL_TYPE_USELESS: - ptr = pool; - new_ptr = _dal_mpool_alloc_comon(ptr, size, type); - if (NULL == new_ptr) - { - MPOOL_UNLOCK(); - return NULL; - } - break; - case DAL_MPOOL_TYPE_DESC: - ptr = p_desc_pool[lchip]; - new_ptr = _dal_mpool_alloc_comon(ptr, size, type); - if (NULL == new_ptr) - { - MPOOL_UNLOCK(); - return NULL; - } - break; - case DAL_MPOOL_TYPE_DATA: - ptr = p_data_pool[lchip]; - new_ptr = _dal_mpool_alloc_comon(ptr, size, type); - if (NULL == new_ptr) - { - MPOOL_UNLOCK(); - return NULL; - } - break; - default: - MPOOL_UNLOCK(); - return NULL; - break; - } - - MPOOL_UNLOCK(); - if( NULL == new_ptr ) - { - return NULL; - } - - return new_ptr->address; -} - -void -_dal_mpool_free(dal_mpool_mem_t* ptr, void* addr, int type) -{ - unsigned char* address = (unsigned char*)addr; - dal_mpool_mem_t* prev = NULL; - - while (ptr && ptr->next) - { - if (ptr->next->address == address) - { - break; - } - - ptr = ptr->next; - } - - if (ptr && ptr->next) - { - prev = ptr; - ptr = ptr->next; - prev->next = ptr->next; - DAL_FREE(ptr); - } - - return; -} - -void -dal_mpool_free(unsigned char lchip, dal_mpool_mem_t* pool, void* addr) -{ - dal_mpool_mem_t* ptr = pool; - - MPOOL_LOCK(); - - switch(pool->type) - { - case DAL_MPOOL_TYPE_USELESS: - ptr = pool; - _dal_mpool_free(ptr, addr, DAL_MPOOL_TYPE_USELESS); - break; - case DAL_MPOOL_TYPE_DESC: - ptr = p_desc_pool[lchip]; - _dal_mpool_free(ptr, addr, DAL_MPOOL_TYPE_DESC); - break; - case DAL_MPOOL_TYPE_DATA: - ptr = p_data_pool[lchip]; - _dal_mpool_free(ptr, addr, DAL_MPOOL_TYPE_DATA); - break; - default: - break; - } - - MPOOL_UNLOCK(); - return; -} - -int -dal_mpool_destroy(unsigned char lchip, dal_mpool_mem_t* pool) -{ - dal_mpool_mem_t* ptr, * next; - - MPOOL_LOCK(); - - for (ptr = pool; ptr; ptr = next) - { - next = ptr->next; - DAL_FREE(ptr); - } - - for (ptr = p_desc_pool[lchip]; ptr; ptr = next) - { - next = ptr->next; - DAL_FREE(ptr); - } - - for (ptr = p_data_pool[lchip]; ptr; ptr = next) - { - next = ptr->next; - DAL_FREE(ptr); - } - - MPOOL_UNLOCK(); - - return 0; -} - -int -dal_mpool_usage(dal_mpool_mem_t* pool, int type) -{ - int usage = 0; - dal_mpool_mem_t* ptr; - - MPOOL_LOCK(); - - for (ptr = pool; ptr; ptr = ptr->next) - { - if (ptr->type == type || ptr->type == -1) - { - usage += ptr->size; - } - } - - MPOOL_UNLOCK(); - - return usage; -} - -int -dal_mpool_debug(dal_mpool_mem_t* pool) -{ - dal_mpool_mem_t* ptr; - int index = 0; - - MPOOL_LOCK(); - - for (ptr = pool; ptr; ptr = ptr->next) - { -// DAL_PRINT("%2dst mpool block: address=0x%8x, size=0x%x \n", index, (unsigned int)ptr->address, ptr->size); - DAL_PRINT("%2dst mpool block: address=%p, size=0x%x \n", index, ptr->address, ptr->size); // note - index++; - } - - MPOOL_UNLOCK(); - - return 0; -} - - diff --git a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_mpool.h b/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_mpool.h deleted file mode 100644 index d93f88868136..000000000000 --- a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_mpool.h +++ /dev/null @@ -1,72 +0,0 @@ -/** - @file dal_mpool.h - - @author Copyright (C) 2011 Centec Networks Inc. All rights reserved. - - @date 2012-5-10 - - @version v2.0 - - This file contains the dma memory init, allocation and free APIs -*/ - -#ifndef _DMA_MPOOL_H -#define _DMA_MPOOL_H -#ifdef __cplusplus -extern "C" { -#endif - -#define DAL_MPOOL_MAX_DESX_SIZE (1024*1024) - -enum dal_mpool_type_e -{ - DAL_MPOOL_TYPE_USELESS, /* just compatible with GB */ - DAL_MPOOL_TYPE_DESC, /* dma mpool op for desc */ - DAL_MPOOL_TYPE_DATA /* dma mpool op for data */ -}; -typedef enum dal_mpool_type_e dal_mpool_type_t; - -struct dal_mpool_mem_s -{ - unsigned char* address; - int size; - int type; - struct dal_mpool_mem_s* next; -}; -typedef struct dal_mpool_mem_s dal_mpool_mem_t; - -/** - @brief This function is to alloc dma memory - - @param[in] size size of memory - - @return NULL - -*/ -extern int -dal_mpool_init(void); - -extern dal_mpool_mem_t* -dal_mpool_create(unsigned char lchip, void* base_ptr, int size); - -extern void* -dal_mpool_alloc(unsigned char lchip, dal_mpool_mem_t* pool, int size, int type); - -extern void -dal_mpool_free(unsigned char lchip, dal_mpool_mem_t* pool, void* addr); - -extern int -dal_mpool_destroy(unsigned char lchip, dal_mpool_mem_t* pool); - -extern int -dal_mpool_usage(dal_mpool_mem_t* pool, int type); - -extern int -dal_mpool_debug(dal_mpool_mem_t* pool); -#ifdef __cplusplus -} -#endif - -#endif /* !_DMA_MPOOL_H */ - - diff --git a/platform/centec/sonic-platform-modules-e582/48x2q4z/scripts/48x2q4z_platform.sh b/platform/centec/sonic-platform-modules-e582/48x2q4z/scripts/48x2q4z_platform.sh index 2f6583bc487b..0edb50901425 100755 --- a/platform/centec/sonic-platform-modules-e582/48x2q4z/scripts/48x2q4z_platform.sh +++ b/platform/centec/sonic-platform-modules-e582/48x2q4z/scripts/48x2q4z_platform.sh @@ -58,7 +58,7 @@ if [ "$1" == "init" ]; then i2cset -y 17 0x22 0x1a 0xff i2cset -y 17 0x22 0x1b 0x0 i2cset -y 17 0x22 0x1c 0xff - i2cset -y 17 0x22 0x9 0x0 + i2cset -y 17 0x22 0x9 0xf0 i2cset -y 17 0x22 0xb 0x0c #start platform monitor diff --git a/platform/centec/sonic-platform-modules-e582/48x6q/cfg/config_db.json b/platform/centec/sonic-platform-modules-e582/48x6q/cfg/config_db.json deleted file mode 100644 index 995ac0444b99..000000000000 --- a/platform/centec/sonic-platform-modules-e582/48x6q/cfg/config_db.json +++ /dev/null @@ -1,302 +0,0 @@ -{ - "DEVICE_METADATA": { - "localhost": { - "bgp_asn": 65100, - "deployment_id": null, - "hostname": "switch1", - "type": "LeafRouter", - "hwsku": "E582-48x6q" - - } - }, - "BGP_PEER_RANGE": {}, - "VLAN": {}, - "PORT": { - "Ethernet1": { - "alias": "eth-0-1", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet2": { - "alias": "eth-0-2", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet3": { - "alias": "eth-0-3", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet4": { - "alias": "eth-0-4", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet5": { - "alias": "eth-0-5", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet6": { - "alias": "eth-0-6", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet7": { - "alias": "eth-0-7", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet8": { - "alias": "eth-0-8", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet9": { - "alias": "eth-0-9", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet10": { - "alias": "eth-0-10", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet11": { - "alias": "eth-0-11", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet12": { - "alias": "eth-0-12", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet13": { - "alias": "eth-0-13", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet14": { - "alias": "eth-0-14", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet15": { - "alias": "eth-0-15", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet16": { - "alias": "eth-0-16", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet17": { - "alias": "eth-0-17", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet18": { - "alias": "eth-0-18", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet19": { - "alias": "eth-0-19", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet20": { - "alias": "eth-0-20", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet21": { - "alias": "eth-0-21", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet22": { - "alias": "eth-0-22", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet23": { - "alias": "eth-0-23", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet24": { - "alias": "eth-0-24", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet25": { - "alias": "eth-0-25", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet26": { - "alias": "eth-0-26", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet27": { - "alias": "eth-0-27", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet28": { - "alias": "eth-0-28", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet29": { - "alias": "eth-0-29", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet30": { - "alias": "eth-0-30", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet31": { - "alias": "eth-0-31", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet32": { - "alias": "eth-0-32", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet33": { - "alias": "eth-0-33", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet34": { - "alias": "eth-0-34", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet35": { - "alias": "eth-0-35", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet36": { - "alias": "eth-0-36", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet37": { - "alias": "eth-0-37", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet38": { - "alias": "eth-0-38", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet39": { - "alias": "eth-0-39", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet40": { - "alias": "eth-0-40", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet41": { - "alias": "eth-0-41", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet42": { - "alias": "eth-0-42", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet43": { - "alias": "eth-0-43", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet44": { - "alias": "eth-0-44", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet45": { - "alias": "eth-0-45", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet46": { - "alias": "eth-0-46", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet47": { - "alias": "eth-0-47", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet48": { - "alias": "eth-0-48", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet49": { - "alias": "eth-0-49", - "speed": "40000", - "mtu": "9100" - }, - "Ethernet50": { - "alias": "eth-0-50", - "speed": "40000", - "mtu": "9100" - }, - "Ethernet51": { - "alias": "eth-0-51", - "speed": "40000", - "mtu": "9100" - }, - "Ethernet52": { - "alias": "eth-0-52", - "speed": "40000", - "mtu": "9100" - }, - "Ethernet53": { - "alias": "eth-0-53", - "speed": "40000", - "mtu": "9100" - }, - "Ethernet54": { - "alias": "eth-0-54", - "speed": "40000", - "mtu": "9100" - } - }, - "SYSLOG_SERVER": {}, - "VLAN_INTERFACE": {}, - "PORTCHANNEL_INTERFACE": {}, - "PORTCHANNEL": {}, - "MGMT_INTERFACE": {}, - "DHCP_SERVER": {}, - "LOOPBACK_INTERFACE": { - "Loopback0|127.0.0.1/8": {} - }, - "ACL_TABLE": {}, - "INTERFACE": { - "Ethernet1|192.168.1.1/24": {}, - "Ethernet2|192.168.2.1/24": {}, - "Ethernet3|192.168.3.1/24": {}, - "Ethernet4|192.168.4.1/24": {} - } -} diff --git a/platform/centec/sonic-platform-modules-e582/48x6q/cfg/config_db_l2l3.json b/platform/centec/sonic-platform-modules-e582/48x6q/cfg/config_db_l2l3.json deleted file mode 100644 index ce6909f3a200..000000000000 --- a/platform/centec/sonic-platform-modules-e582/48x6q/cfg/config_db_l2l3.json +++ /dev/null @@ -1,610 +0,0 @@ -{ - "QUEUE": { - "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|0-2": { - "wred_profile": "[WRED_PROFILE|AZURE_LOSSY]" - }, - "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|3-4": { - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]", - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|5-7": { - "wred_profile": "[WRED_PROFILE|AZURE_LOSSY]" - } - }, - "WRED_PROFILE": { - "AZURE_LOSSLESS": { - "red_max_threshold": "32760", - "yellow_max_threshold": "32760", - "green_min_threshold": "4095", - "red_min_threshold": "4095", - "yellow_min_threshold": "4095", - "green_max_threshold": "32760", - "wred_yellow_enable": "true", - "wred_green_enable": "true" - }, - "AZURE_LOSSY": { - "red_max_threshold": "32760", - "yellow_max_threshold": "32760", - "green_min_threshold": "4095", - "red_min_threshold": "4095", - "yellow_min_threshold": "4095", - "green_max_threshold": "32760", - "wred_yellow_enable": "true", - "wred_green_enable": "true" - } - }, - "DSCP_TO_TC_MAP": { - "AZURE": { - "56": "7", - "54": "6", - "28": "3", - "48": "6", - "29": "3", - "60": "7", - "61": "7", - "62": "7", - "63": "7", - "49": "6", - "34": "4", - "24": "3", - "25": "3", - "26": "3", - "27": "3", - "20": "2", - "21": "2", - "22": "2", - "23": "2", - "46": "5", - "47": "5", - "44": "5", - "45": "5", - "42": "5", - "43": "5", - "40": "5", - "41": "5", - "1": "0", - "0": "0", - "3": "0", - "2": "0", - "5": "0", - "4": "0", - "7": "0", - "6": "0", - "9": "1", - "8": "1", - "35": "4", - "13": "1", - "12": "1", - "15": "1", - "58": "7", - "11": "1", - "10": "1", - "39": "4", - "38": "4", - "59": "7", - "14": "1", - "17": "2", - "16": "2", - "19": "2", - "18": "2", - "31": "3", - "30": "3", - "51": "6", - "36": "4", - "53": "6", - "52": "6", - "33": "4", - "55": "6", - "37": "4", - "32": "4", - "57": "7", - "50": "6" - } - }, - "DEVICE_METADATA": { - "localhost": { - "hwsku": "E582-48x6q", - "hostname": "switch1", - "bgp_asn": "None", - "deployment_id": "None", - "type": "LeafRouter" - } - }, - "PORT": { - "Ethernet1": { - "alias": "eth-0-1", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet2": { - "alias": "eth-0-2", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet3": { - "alias": "eth-0-3", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet4": { - "alias": "eth-0-4", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet5": { - "alias": "eth-0-5", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet6": { - "alias": "eth-0-6", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet7": { - "alias": "eth-0-7", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet8": { - "alias": "eth-0-8", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet9": { - "alias": "eth-0-9", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet10": { - "alias": "eth-0-10", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet11": { - "alias": "eth-0-11", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet12": { - "alias": "eth-0-12", - "speed": "1000", - "mtu": "9100" - }, - "Ethernet13": { - "alias": "eth-0-13", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet14": { - "alias": "eth-0-14", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet15": { - "alias": "eth-0-15", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet16": { - "alias": "eth-0-16", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet17": { - "alias": "eth-0-17", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet18": { - "alias": "eth-0-18", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet19": { - "alias": "eth-0-19", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet20": { - "alias": "eth-0-20", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet21": { - "alias": "eth-0-21", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet22": { - "alias": "eth-0-22", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet23": { - "alias": "eth-0-23", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet24": { - "alias": "eth-0-24", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet25": { - "alias": "eth-0-25", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet26": { - "alias": "eth-0-26", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet27": { - "alias": "eth-0-27", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet28": { - "alias": "eth-0-28", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet29": { - "alias": "eth-0-29", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet30": { - "alias": "eth-0-30", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet31": { - "alias": "eth-0-31", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet32": { - "alias": "eth-0-32", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet33": { - "alias": "eth-0-33", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet34": { - "alias": "eth-0-34", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet35": { - "alias": "eth-0-35", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet36": { - "alias": "eth-0-36", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet37": { - "alias": "eth-0-37", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet38": { - "alias": "eth-0-38", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet39": { - "alias": "eth-0-39", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet40": { - "alias": "eth-0-40", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet41": { - "alias": "eth-0-41", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet42": { - "alias": "eth-0-42", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet43": { - "alias": "eth-0-43", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet44": { - "alias": "eth-0-44", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet45": { - "alias": "eth-0-45", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet46": { - "alias": "eth-0-46", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet47": { - "alias": "eth-0-47", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet48": { - "alias": "eth-0-48", - "speed": "10000", - "mtu": "9100" - }, - "Ethernet49": { - "alias": "eth-0-49", - "speed": "40000", - "mtu": "9100" - }, - "Ethernet50": { - "alias": "eth-0-50", - "speed": "40000", - "mtu": "9100" - }, - "Ethernet51": { - "alias": "eth-0-51", - "speed": "40000", - "mtu": "9100" - }, - "Ethernet52": { - "alias": "eth-0-52", - "speed": "40000", - "mtu": "9100" - }, - "Ethernet53": { - "alias": "eth-0-53", - "speed": "40000", - "mtu": "9100" - }, - "Ethernet54": { - "alias": "eth-0-54", - "speed": "40000", - "mtu": "9100" - } - }, - "PORT_QOS_MAP": { - "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54": { - "pfc_enable": "3,4", - "dscp_to_tc_map": "[DSCP_TO_TC_MAP|AZURE]" - } - }, - "SCHEDULER": { - "scheduler.0": { - "type": "DWRR", - "weight": "25" - }, - "scheduler.1": { - "type": "DWRR", - "weight": "30" - }, - "scheduler.2": { - "type": "DWRR", - "weight": "20" - } - }, - "VLAN": { - "Vlan500": { - "dhcp_servers": [ - "192.168.5.1", - "192.168.5.2", - "192.168.5.3", - "192.168.5.4" - ], - "members": [ - "Ethernet5", - "Ethernet6", - "Ethernet7", - "Ethernet8" - ], - "vlanid": "500" - }, - "Vlan600": { - "dhcp_servers": [ - "192.168.6.1", - "192.168.6.2", - "192.168.6.3", - "192.168.6.4" - ], - "members": [ - "Ethernet5", - "Ethernet6" - ], - "vlanid": "600" - }, - "Vlan700": { - "dhcp_servers": [ - "192.168.7.1", - "192.168.7.2", - "192.168.7.3", - "192.168.7.4" - ], - "members": [ - "Ethernet5", - "Ethernet7" - ], - "vlanid": "700" - }, - "Vlan800": { - "dhcp_servers": [ - "192.168.8.1", - "192.168.8.2", - "192.168.8.3", - "192.168.8.4" - ], - "members": [ - "Ethernet5", - "Ethernet8" - ], - "vlanid": "800" - } - }, - "VLAN_MEMBER": { - "Vlan500|Ethernet5": { - "tagging_mode": "tagged" - }, - "Vlan500|Ethernet6": { - "tagging_mode": "untagged" - }, - "Vlan500|Ethernet7": { - "tagging_mode": "untagged" - }, - "Vlan500|Ethernet8": { - "tagging_mode": "untagged" - }, - "Vlan600|Ethernet5": { - "tagging_mode": "tagged" - }, - "Vlan600|Ethernet6": { - "tagging_mode": "tagged" - }, - "Vlan700|Ethernet5": { - "tagging_mode": "tagged" - }, - "Vlan700|Ethernet7": { - "tagging_mode": "tagged" - }, - "Vlan800|Ethernet5": { - "tagging_mode": "tagged" - }, - "Vlan800|Ethernet8": { - "tagging_mode": "tagged" - } - }, - "INTERFACE": { - "Ethernet1|192.168.1.1/24": {}, - "Ethernet2|192.168.2.1/24": {}, - "Ethernet3|192.168.3.1/24": {}, - "Ethernet4|192.168.4.1/24": {} - }, - "VLAN_INTERFACE": { - "Vlan500|192.168.5.1/24": {}, - "Vlan600|192.168.6.1/24": {}, - "Vlan700|192.168.7.1/24": {}, - "Vlan800|192.168.8.1/24": {} - }, - "LOOPBACK_INTERFACE": { - "Loopback0|127.0.0.1/8": {} - }, - "CABLE_LENGTH": { - "AZURE": { - "Ethernet8": "40m", - "Ethernet9": "40m", - "Ethernet2": "40m", - "Ethernet3": "40m", - "Ethernet1": "40m", - "Ethernet6": "40m", - "Ethernet7": "40m", - "Ethernet4": "40m", - "Ethernet5": "40m", - "Ethernet22": "40m", - "Ethernet50": "40m", - "Ethernet51": "40m", - "Ethernet52": "40m", - "Ethernet53": "40m", - "Ethernet54": "40m", - "Ethernet38": "40m", - "Ethernet39": "40m", - "Ethernet18": "40m", - "Ethernet19": "40m", - "Ethernet14": "40m", - "Ethernet15": "40m", - "Ethernet16": "40m", - "Ethernet17": "40m", - "Ethernet10": "40m", - "Ethernet11": "40m", - "Ethernet12": "40m", - "Ethernet35": "40m", - "Ethernet37": "40m", - "Ethernet32": "40m", - "Ethernet33": "40m", - "Ethernet30": "40m", - "Ethernet31": "40m", - "Ethernet49": "40m", - "Ethernet48": "40m", - "Ethernet47": "40m", - "Ethernet36": "40m", - "Ethernet45": "40m", - "Ethernet44": "40m", - "Ethernet43": "40m", - "Ethernet42": "40m", - "Ethernet41": "40m", - "Ethernet40": "40m", - "Ethernet29": "40m", - "Ethernet28": "40m", - "Ethernet34": "40m", - "Ethernet46": "40m", - "Ethernet21": "40m", - "Ethernet20": "40m", - "Ethernet23": "40m", - "Ethernet13": "40m", - "Ethernet25": "40m", - "Ethernet24": "40m", - "Ethernet27": "40m", - "Ethernet26": "40m" - } - }, - "CRM": { - "Config": { - "acl_table_threshold_type": "percentage", - "nexthop_group_threshold_type": "percentage", - "fdb_entry_high_threshold": "85", - "acl_entry_threshold_type": "percentage", - "ipv6_neighbor_low_threshold": "70", - "nexthop_group_member_low_threshold": "70", - "acl_group_high_threshold": "85", - "ipv4_route_high_threshold": "85", - "acl_counter_high_threshold": "85", - "ipv4_route_low_threshold": "70", - "ipv4_route_threshold_type": "percentage", - "ipv4_neighbor_low_threshold": "70", - "acl_group_threshold_type": "percentage", - "ipv4_nexthop_high_threshold": "85", - "ipv6_route_threshold_type": "percentage", - "nexthop_group_low_threshold": "70", - "ipv4_neighbor_high_threshold": "85", - "ipv6_route_high_threshold": "85", - "ipv6_nexthop_threshold_type": "percentage", - "polling_interval": "300", - "ipv4_nexthop_threshold_type": "percentage", - "acl_group_low_threshold": "70", - "acl_entry_low_threshold": "70", - "nexthop_group_member_threshold_type": "percentage", - "ipv4_nexthop_low_threshold": "70", - "acl_counter_threshold_type": "percentage", - "ipv6_neighbor_high_threshold": "85", - "nexthop_group_member_high_threshold": "85", - "acl_table_low_threshold": "70", - "fdb_entry_threshold_type": "percentage", - "ipv6_neighbor_threshold_type": "percentage", - "acl_table_high_threshold": "85", - "ipv6_nexthop_low_threshold": "70", - "acl_counter_low_threshold": "70", - "ipv4_neighbor_threshold_type": "percentage", - "nexthop_group_high_threshold": "85", - "ipv6_route_low_threshold": "70", - "acl_entry_high_threshold": "85", - "fdb_entry_low_threshold": "70", - "ipv6_nexthop_high_threshold": "85" - } - } -} diff --git a/platform/centec/sonic-platform-modules-e582/48x6q/modules/Makefile b/platform/centec/sonic-platform-modules-e582/48x6q/modules/Makefile index 25df81bba426..2462555c8714 100644 --- a/platform/centec/sonic-platform-modules-e582/48x6q/modules/Makefile +++ b/platform/centec/sonic-platform-modules-e582/48x6q/modules/Makefile @@ -1,2 +1 @@ -obj-m := centec_e582_48x6q_platform.o dal.o centec_at24c64.o -dal-y := dal_kernel.o dal_mpool.o +obj-m := centec_e582_48x6q_platform.o centec_at24c64.o diff --git a/platform/centec/sonic-platform-modules-e582/48x6q/modules/centec_e582_48x6q_platform.c b/platform/centec/sonic-platform-modules-e582/48x6q/modules/centec_e582_48x6q_platform.c index 6ef18ca62f41..f72efee2a0d6 100644 --- a/platform/centec/sonic-platform-modules-e582/48x6q/modules/centec_e582_48x6q_platform.c +++ b/platform/centec/sonic-platform-modules-e582/48x6q/modules/centec_e582_48x6q_platform.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_kernel.c b/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_kernel.c deleted file mode 100644 index 32a38f842cfa..000000000000 --- a/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_kernel.c +++ /dev/null @@ -1,1833 +0,0 @@ -/** - @file dal_kernal.c - - @date 2012-10-18 - - @version v2.0 - - -*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) -#include -#endif -#include "dal_kernel.h" -#include "dal_mpool.h" -#include -MODULE_AUTHOR("Centec Networks Inc."); -MODULE_DESCRIPTION("DAL kernel module"); -MODULE_LICENSE("GPL"); - -/* DMA memory pool size */ -static char* dma_pool_size; -module_param(dma_pool_size, charp, 0); -MODULE_PARM_DESC(dma_pool_size, - "Specify DMA memory pool size (default 4MB)"); - -/***************************************************************************** - * defines - *****************************************************************************/ -#define MB_SIZE 0x100000 -#define CTC_MAX_INTR_NUM 8 - -#define MEM_MAP_RESERVE SetPageReserved -#define MEM_MAP_UNRESERVE ClearPageReserved - -#define CTC_VENDOR_VID 0xc001 -#define CTC_HUMBER_DEVICE_ID 0x6048 -#define CTC_GOLDENGATE_DEVICE_ID 0xc010 -#define CTC_PCIE_VENDOR_ID 0xcb10 -#define CTC_DUET2_DEVICE_ID 0x7148 - -#define MEM_MAP_RESERVE SetPageReserved -#define MEM_MAP_UNRESERVE ClearPageReserved - -#define CTC_GREATBELT_DEVICE_ID 0x03e8 /* TBD */ -#define DAL_MAX_CHIP_NUM 8 /* [GB] used */ -#define VIRT_TO_PAGE(p) virt_to_page((p)) -#define DAL_UNTAG_BLOCK 0 -#define DAL_DISCARD_BLOCK 1 -#define DAL_MATCHED_BLOCK 2 -#define DAL_CUR_MATCH_BLOCk 3 -/***************************************************************************** - * typedef - *****************************************************************************/ -/* Control Data */ -typedef struct dal_isr_s -{ - int irq; - void (* isr)(void*); - void* isr_data; - int trigger; - int count; - wait_queue_head_t wqh; -} dal_isr_t; - -typedef struct dal_kernel_dev_s -{ - struct list_head list; - struct pci_dev* pci_dev; - - /* PCI I/O mapped base address */ - uintptr logic_address; - - /* Physical address */ - unsigned long long phys_address; -} dal_kern_dev_t; - -typedef struct _dma_segment -{ - struct list_head list; - unsigned long req_size; /* Requested DMA segment size */ - unsigned long blk_size; /* DMA block size */ - unsigned long blk_order; /* DMA block size in alternate format */ - unsigned long seg_size; /* Current DMA segment size */ - unsigned long seg_begin; /* Logical address of segment */ - unsigned long seg_end; /* Logical end address of segment */ - unsigned long* blk_ptr; /* Array of logical DMA block addresses */ - int blk_cnt_max; /* Maximum number of block to allocate */ - int blk_cnt; /* Current number of blocks allocated */ -} dma_segment_t; - -typedef irqreturn_t (*p_func) (int irq, void* dev_id); - -/*************************************************************************** - *declared - ***************************************************************************/ -static unsigned int linux_dal_poll0(struct file* filp, struct poll_table_struct* p); -static unsigned int linux_dal_poll1(struct file* filp, struct poll_table_struct* p); -static unsigned int linux_dal_poll2(struct file* filp, struct poll_table_struct* p); -static unsigned int linux_dal_poll3(struct file* filp, struct poll_table_struct* p); -static unsigned int linux_dal_poll4(struct file* filp, struct poll_table_struct* p); -static unsigned int linux_dal_poll5(struct file* filp, struct poll_table_struct* p); -static unsigned int linux_dal_poll6(struct file* filp, struct poll_table_struct* p); -static unsigned int linux_dal_poll7(struct file* filp, struct poll_table_struct* p); - -/***************************************************************************** - * global variables - *****************************************************************************/ -static dal_kern_dev_t dal_dev[DAL_MAX_CHIP_NUM]; -static dal_isr_t dal_isr[CTC_MAX_INTR_NUM]; -static int dal_chip_num = 0; -static int dal_version = 0; -static int dal_intr_num = 0; -static int use_high_memory = 0; -static unsigned int* dma_virt_base[DAL_MAX_CHIP_NUM]; -#ifndef DMA_MEM_MODE_PLATFORM -static unsigned int* dma_virt_base_tmp[DAL_MAX_CHIP_NUM]; -#endif -static unsigned long long dma_phy_base[DAL_MAX_CHIP_NUM]; -static unsigned int dma_mem_size = 0xc00000; -static unsigned int msi_irq_base[DAL_MAX_CHIP_NUM]; -static unsigned int msi_irq_num[DAL_MAX_CHIP_NUM]; -static unsigned int msi_used = 0; -static struct class *dal_class; - -static LIST_HEAD(_dma_seg); -static int dal_debug = 0; -module_param(dal_debug, int, 0); -MODULE_PARM_DESC(dal_debug, "Set debug level (default 0)"); - -static struct pci_device_id dal_id_table[] = -{ - {PCI_DEVICE(CTC_VENDOR_VID, CTC_GREATBELT_DEVICE_ID)}, - {PCI_DEVICE(CTC_PCIE_VENDOR_ID, CTC_GOLDENGATE_DEVICE_ID)}, - {PCI_DEVICE((CTC_PCIE_VENDOR_ID+1), (CTC_GOLDENGATE_DEVICE_ID+1))}, - {PCI_DEVICE(CTC_PCIE_VENDOR_ID, CTC_DUET2_DEVICE_ID)}, - {0, }, -}; - -static wait_queue_head_t poll_intr[CTC_MAX_INTR_NUM]; - -p_func intr_handler_fun[CTC_MAX_INTR_NUM]; - -static int poll_intr_trigger[CTC_MAX_INTR_NUM]; - -static struct file_operations dal_intr_fops[CTC_MAX_INTR_NUM] = -{ - { - .owner = THIS_MODULE, - .poll = linux_dal_poll0, - }, - { - .owner = THIS_MODULE, - .poll = linux_dal_poll1, - }, - { - .owner = THIS_MODULE, - .poll = linux_dal_poll2, - }, - { - .owner = THIS_MODULE, - .poll = linux_dal_poll3, - }, - { - .owner = THIS_MODULE, - .poll = linux_dal_poll4, - }, - { - .owner = THIS_MODULE, - .poll = linux_dal_poll5, - }, - { - .owner = THIS_MODULE, - .poll = linux_dal_poll6, - }, - { - .owner = THIS_MODULE, - .poll = linux_dal_poll7, - }, -}; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)) -#include -#define virt_to_bus virt_to_phys -#define bus_to_virt phys_to_virt -#endif -/***************************************************************************** - * macros - *****************************************************************************/ -#define VERIFY_CHIP_INDEX(n) (n < dal_chip_num) - -#define _KERNEL_INTERUPT_PROCESS -static irqreturn_t -intr0_handler(int irq, void* dev_id) -{ - dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; - - if(poll_intr_trigger[0]) - { - return IRQ_HANDLED; - } - - disable_irq_nosync(irq); - - if (p_dal_isr) - { - if (p_dal_isr->isr) - { - /* kernel mode interrupt handler */ - p_dal_isr->isr(p_dal_isr->isr_data); - } - else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) - { - /* user mode interrupt handler */ - poll_intr_trigger[0] = 1; - wake_up(&poll_intr[0]); - } - } - - return IRQ_HANDLED; -} - -static irqreturn_t -intr1_handler(int irq, void* dev_id) -{ - dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; - if(poll_intr_trigger[1]) - { - return IRQ_HANDLED; - } - - disable_irq_nosync(irq); - - if (p_dal_isr) - { - if (p_dal_isr->isr) - { - /* kernel mode interrupt handler */ - p_dal_isr->isr(p_dal_isr->isr_data); - } - else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) - { - /* user mode interrupt handler */ - poll_intr_trigger[1] = 1; - wake_up(&poll_intr[1]); - } - } - - return IRQ_HANDLED; -} - -static irqreturn_t -intr2_handler(int irq, void* dev_id) -{ - dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; - if(poll_intr_trigger[2]) - { - return IRQ_HANDLED; - } - disable_irq_nosync(irq); - - if (p_dal_isr) - { - if (p_dal_isr->isr) - { - /* kernel mode interrupt handler */ - p_dal_isr->isr(p_dal_isr->isr_data); - } - else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) - { - /* user mode interrupt handler */ - poll_intr_trigger[2] = 1; - wake_up(&poll_intr[2]); - } - } - - return IRQ_HANDLED; -} - -static irqreturn_t -intr3_handler(int irq, void* dev_id) -{ - dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; - if(poll_intr_trigger[3]) - { - return IRQ_HANDLED; - } - disable_irq_nosync(irq); - - if (p_dal_isr) - { - if (p_dal_isr->isr) - { - /* kernel mode interrupt handler */ - p_dal_isr->isr(p_dal_isr->isr_data); - } - else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) - { - /* user mode interrupt handler */ - poll_intr_trigger[3] = 1; - wake_up(&poll_intr[3]); - } - } - - return IRQ_HANDLED; -} - -static irqreturn_t -intr4_handler(int irq, void* dev_id) -{ - dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; - if(poll_intr_trigger[4]) - { - return IRQ_HANDLED; - } - disable_irq_nosync(irq); - - if (p_dal_isr) - { - if (p_dal_isr->isr) - { - /* kernel mode interrupt handler */ - p_dal_isr->isr(p_dal_isr->isr_data); - } - else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) - { - /* user mode interrupt handler */ - poll_intr_trigger[4] = 1; - wake_up(&poll_intr[4]); - } - } - - return IRQ_HANDLED; -} - -static irqreturn_t -intr5_handler(int irq, void* dev_id) -{ - dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; - if(poll_intr_trigger[5]) - { - return IRQ_HANDLED; - } - disable_irq_nosync(irq); - - if (p_dal_isr) - { - if (p_dal_isr->isr) - { - /* kernel mode interrupt handler */ - p_dal_isr->isr(p_dal_isr->isr_data); - } - else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) - { - /* user mode interrupt handler */ - poll_intr_trigger[5] = 1; - wake_up(&poll_intr[5]); - } - } - - return IRQ_HANDLED; -} - -static irqreturn_t -intr6_handler(int irq, void* dev_id) -{ - dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; - if(poll_intr_trigger[6]) - { - return IRQ_HANDLED; - } - disable_irq_nosync(irq); - - if (p_dal_isr) - { - if (p_dal_isr->isr) - { - /* kernel mode interrupt handler */ - p_dal_isr->isr(p_dal_isr->isr_data); - } - else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) - { - /* user mode interrupt handler */ - poll_intr_trigger[6] = 1; - wake_up(&poll_intr[6]); - } - } - - return IRQ_HANDLED; -} - -static irqreturn_t -intr7_handler(int irq, void* dev_id) -{ - dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; - if(poll_intr_trigger[7]) - { - return IRQ_HANDLED; - } - disable_irq_nosync(irq); - - if (p_dal_isr) - { - if (p_dal_isr->isr) - { - /* kernel mode interrupt handler */ - p_dal_isr->isr(p_dal_isr->isr_data); - } - else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) - { - /* user mode interrupt handler */ - poll_intr_trigger[7] = 1; - wake_up(&poll_intr[7]); - } - } - - return IRQ_HANDLED; -} - -int -dal_interrupt_register(unsigned int irq, int prio, void (* isr)(void*), void* data) -{ - int ret; - unsigned char str[16]; - unsigned char* int_name = NULL; - unsigned int intr_num_tmp = 0; - unsigned int intr_num = CTC_MAX_INTR_NUM; - unsigned long irq_flags = 0; - - if (dal_intr_num >= CTC_MAX_INTR_NUM) - { - printk("Interrupt numbers exceeds max.\n"); - return -1; - } - - if (msi_used) - { - int_name = "dal_msi"; - } - else - { - int_name = "dal_intr"; - } - - - for (intr_num_tmp=0;intr_num_tmp < CTC_MAX_INTR_NUM; intr_num_tmp++) - { - if (irq == dal_isr[intr_num_tmp].irq) - { - if (0 == msi_used) - { - dal_isr[intr_num_tmp].count++; - printk("Interrupt irq %d register count %d.\n", irq, dal_isr[intr_num_tmp].count); - } - return 0; - } - if ((0 == dal_isr[intr_num_tmp].irq) && (CTC_MAX_INTR_NUM == intr_num)) - { - intr_num = intr_num_tmp; - dal_isr[intr_num].count = 0; - } - } - dal_isr[intr_num].irq = irq; - dal_isr[intr_num].isr = isr; - dal_isr[intr_num].isr_data = data; - dal_isr[intr_num].count++; - - init_waitqueue_head(&poll_intr[intr_num]); - - /* only user mode */ - if ((NULL == isr) && (NULL == data)) - { - snprintf(str, 16, "%s%d", "dal_intr", intr_num); - ret = register_chrdev(DAL_DEV_INTR_MAJOR_BASE + intr_num, - str, &dal_intr_fops[intr_num]); - if (ret < 0) - { - printk("Register character device for irq %d failed, ret= %d", irq, ret); - return ret; - } - } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) - irq_flags = 0; -#else - irq_flags = IRQF_DISABLED; -#endif - if ((ret = request_irq(irq, - intr_handler_fun[intr_num], - irq_flags, - int_name, - &dal_isr[intr_num])) < 0) - { - printk("Cannot request irq %d, ret %d.\n", irq, ret); - unregister_chrdev(DAL_DEV_INTR_MAJOR_BASE + intr_num, str); - } - - if (0 == ret) - { - dal_intr_num++; - } - - return ret; -} - -int -dal_interrupt_unregister(unsigned int irq) -{ - unsigned char str[16]; - int intr_idx = 0; - int find_flag = 0; - - /* get intr device index */ - for (intr_idx = 0; intr_idx < CTC_MAX_INTR_NUM; intr_idx++) - { - if (dal_isr[intr_idx].irq == irq) - { - find_flag = 1; - break; - } - } - - if (find_flag == 0) - { - printk ("irq%d is not registered! unregister failed \n", irq); - return -1; - } - - dal_isr[intr_idx].count--; - if (0 != dal_isr[intr_idx].count) - { - printk("Interrupt irq %d unregister count %d.\n", irq, dal_isr[intr_idx].count); - return -1; - } - snprintf(str, 16, "%s%d", "dal_intr", intr_idx); - - unregister_chrdev(DAL_DEV_INTR_MAJOR_BASE + intr_idx, str); - - free_irq(irq, &dal_isr[intr_idx]); - - dal_isr[intr_idx].irq = 0; - - dal_intr_num--; - - return 0; -} - -int -dal_interrupt_set_en(unsigned int irq, unsigned int enable) -{ - enable ? enable_irq(irq) : disable_irq_nosync(irq); - return 0; -} - -static int -_dal_set_msi_enabe(unsigned int lchip, unsigned int irq_num) -{ - int ret = 0; - - if (irq_num == 1) - { - ret = pci_enable_msi(dal_dev[lchip].pci_dev); - if (ret) - { - printk ("msi enable failed!!! lchip = %d, irq_num = %d\n", lchip, irq_num); - pci_disable_msi(dal_dev[lchip].pci_dev); - msi_used = 0; - } - - msi_irq_base[lchip] = dal_dev[lchip].pci_dev->irq; - msi_irq_num[lchip] = 1; - } - else - { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 79)) - ret = pci_enable_msi_exact(dal_dev[lchip].pci_dev, irq_num); -#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 26, 32)) - ret = pci_enable_msi_block(dal_dev[lchip].pci_dev, irq_num); -#else - ret = -1; -#endif - if (ret) - { - printk ("msi enable failed!!! lchip = %d, irq_num = %d\n", lchip, irq_num); - pci_disable_msi(dal_dev[lchip].pci_dev); - msi_used = 0; - } - - msi_irq_base[lchip] = dal_dev[lchip].pci_dev->irq; - msi_irq_num[lchip] = irq_num; - } - - return ret; -} - -static int -_dal_set_msi_disable(unsigned int lchip) -{ - - pci_disable_msi(dal_dev[lchip].pci_dev); - - msi_irq_base[lchip] = 0; - msi_irq_num[lchip] = 0; - - return 0; -} - -int -dal_set_msi_cap(unsigned long arg) -{ - int ret = 0; - int index = 0; - dal_msi_info_t msi_info; - - if (copy_from_user(&msi_info, (void*)arg, sizeof(dal_msi_info_t))) - { - return -EFAULT; - } - - printk("####dal_set_msi_cap lchip %d base %d num:%d\n", msi_info.lchip, msi_info.irq_base, msi_info.irq_num); - if (msi_info.irq_num > 0) - { - if (0 == msi_used) - { - msi_used = 1; - ret = _dal_set_msi_enabe(msi_info.lchip, msi_info.irq_num); - } - else if ((1 == msi_used) && (msi_info.irq_num != msi_irq_num[msi_info.lchip])) - { - for (index = 0; index < msi_irq_num[msi_info.lchip]; index++) - { - dal_interrupt_unregister(msi_irq_base[msi_info.lchip]+index); - } - _dal_set_msi_disable(msi_info.lchip); - msi_used = 1; - ret = _dal_set_msi_enabe(msi_info.lchip, msi_info.irq_num); - } - } - else - { - msi_used = 0; - ret = _dal_set_msi_disable(msi_info.lchip); - } - - return ret; -} - -int -dal_user_interrupt_register(unsigned long arg) -{ - int irq = 0; - if (copy_from_user(&irq, (void*)arg, sizeof(int))) - { - return -EFAULT; - } - printk("####register interrupt irq:%d\n", irq); - return dal_interrupt_register(irq, 0, NULL, NULL); -} - -int -dal_user_interrupt_unregister(unsigned long arg) -{ - int irq = 0; - if (copy_from_user(&irq, (void*)arg, sizeof(int))) - { - return -EFAULT; - } - printk("####unregister interrupt irq:%d\n", irq); - return dal_interrupt_unregister(irq); -} - -int -dal_user_interrupt_set_en(unsigned long arg) -{ - dal_intr_parm_t dal_intr_parm; - - if (copy_from_user(&dal_intr_parm, (void*)arg, sizeof(dal_intr_parm_t))) - { - return -EFAULT; - } - - return dal_interrupt_set_en(dal_intr_parm.irq, dal_intr_parm.enable); -} - -/* - * Function: _dal_dma_segment_free - */ - -/* - * Function: _find_largest_segment - * - * Purpose: - * Find largest contiguous segment from a pool of DMA blocks. - * Parameters: - * dseg - DMA segment descriptor - * Returns: - * 0 on success, < 0 on error. - * Notes: - * Assembly stops if a segment of the requested segment size - * has been obtained. - * - * Lower address bits of the DMA blocks are used as follows: - * 0: Untagged - * 1: Discarded block - * 2: Part of largest contiguous segment - * 3: Part of current contiguous segment - */ -#ifndef DMA_MEM_MODE_PLATFORM -static int -_dal_find_largest_segment(dma_segment_t* dseg) -{ - int i, j, blks, found; - unsigned long seg_begin; - unsigned long seg_end; - unsigned long seg_tmp; - - blks = dseg->blk_cnt; - - /* Clear all block tags */ - for (i = 0; i < blks; i++) - { - dseg->blk_ptr[i] &= ~3; - } - - for (i = 0; i < blks && dseg->seg_size < dseg->req_size; i++) - { - /* First block must be an untagged block */ - if ((dseg->blk_ptr[i] & 3) == DAL_UNTAG_BLOCK) - { - /* Initial segment size is the block size */ - seg_begin = dseg->blk_ptr[i]; - seg_end = seg_begin + dseg->blk_size; - dseg->blk_ptr[i] |= DAL_CUR_MATCH_BLOCk; - - /* Loop looking for adjacent blocks */ - do - { - found = 0; - - for (j = i + 1; j < blks && (seg_end - seg_begin) < dseg->req_size; j++) - { - seg_tmp = dseg->blk_ptr[j]; - /* Check untagged blocks only */ - if ((seg_tmp & 3) == DAL_UNTAG_BLOCK) - { - if (seg_tmp == (seg_begin - dseg->blk_size)) - { - /* Found adjacent block below current segment */ - dseg->blk_ptr[j] |= DAL_CUR_MATCH_BLOCk; - seg_begin = seg_tmp; - found = 1; - } - else if (seg_tmp == seg_end) - { - /* Found adjacent block above current segment */ - dseg->blk_ptr[j] |= DAL_CUR_MATCH_BLOCk; - seg_end += dseg->blk_size; - found = 1; - } - } - } - } - while (found); - - if ((seg_end - seg_begin) > dseg->seg_size) - { - /* The current block is largest so far */ - dseg->seg_begin = seg_begin; - dseg->seg_end = seg_end; - dseg->seg_size = seg_end - seg_begin; - - /* Re-tag current and previous largest segment */ - for (j = 0; j < blks; j++) - { - if ((dseg->blk_ptr[j] & 3) == DAL_CUR_MATCH_BLOCk) - { - /* Tag current segment as the largest */ - dseg->blk_ptr[j] &= ~1; - } - else if ((dseg->blk_ptr[j] & 3) == DAL_MATCHED_BLOCK) - { - /* Discard previous largest segment */ - dseg->blk_ptr[j] ^= 3; - } - } - } - else - { - /* Discard all blocks in current segment */ - for (j = 0; j < blks; j++) - { - if ((dseg->blk_ptr[j] & 3) == DAL_CUR_MATCH_BLOCk) - { - dseg->blk_ptr[j] &= ~2; - } - } - } - } - } - - return 0; -} - -/* - * Function: _alloc_dma_blocks - */ -static int -_dal_alloc_dma_blocks(dma_segment_t* dseg, int blks) -{ - int i, start; - unsigned long addr; - - if (dseg->blk_cnt + blks > dseg->blk_cnt_max) - { - printk("No more DMA blocks\n"); - return -1; - } - - start = dseg->blk_cnt; - dseg->blk_cnt += blks; - - for (i = start; i < dseg->blk_cnt; i++) - { - addr = __get_free_pages(GFP_ATOMIC, dseg->blk_order); - if (addr) - { - dseg->blk_ptr[i] = addr; - } - else - { - printk("DMA allocation failed\n"); - return -1; - } - } - - return 0; -} - -/* - * Function: _dal_dma_segment_alloc - */ -static dma_segment_t* -_dal_dma_segment_alloc(unsigned int size, unsigned int blk_size) -{ - dma_segment_t* dseg; - int i, blk_ptr_size; - unsigned long page_addr; - struct sysinfo si; - - /* Sanity check */ - if (size == 0 || blk_size == 0) - { - return NULL; - } - - /* Allocate an initialize DMA segment descriptor */ - if ((dseg = kmalloc(sizeof(dma_segment_t), GFP_ATOMIC)) == NULL) - { - return NULL; - } - - memset(dseg, 0, sizeof(dma_segment_t)); - dseg->req_size = size; - dseg->blk_size = PAGE_ALIGN(blk_size); - - while ((PAGE_SIZE << dseg->blk_order) < dseg->blk_size) - { - dseg->blk_order++; - } - - si_meminfo(&si); - dseg->blk_cnt_max = (si.totalram << PAGE_SHIFT) / dseg->blk_size; - blk_ptr_size = dseg->blk_cnt_max * sizeof(unsigned long); - /* Allocate an initialize DMA block pool */ - dseg->blk_ptr = kmalloc(blk_ptr_size, GFP_KERNEL); - if (dseg->blk_ptr == NULL) - { - kfree(dseg); - return NULL; - } - - memset(dseg->blk_ptr, 0, blk_ptr_size); - /* Allocate minimum number of blocks */ - _dal_alloc_dma_blocks(dseg, dseg->req_size / dseg->blk_size); - - /* Allocate more blocks until we have a complete segment */ - do - { - _dal_find_largest_segment(dseg); - if (dseg->seg_size >= dseg->req_size) - { - break; - } - } - while (_dal_alloc_dma_blocks(dseg, 8) == 0); - - /* Reserve all pages in the DMA segment and free unused blocks */ - for (i = 0; i < dseg->blk_cnt; i++) - { - if ((dseg->blk_ptr[i] & 3) == 2) - { - dseg->blk_ptr[i] &= ~3; - - for (page_addr = dseg->blk_ptr[i]; - page_addr < dseg->blk_ptr[i] + dseg->blk_size; - page_addr += PAGE_SIZE) - { - MEM_MAP_RESERVE(VIRT_TO_PAGE((void*)page_addr)); - } - } - else if (dseg->blk_ptr[i]) - { - dseg->blk_ptr[i] &= ~3; - free_pages(dseg->blk_ptr[i], dseg->blk_order); - dseg->blk_ptr[i] = 0; - } - } - - return dseg; -} - -/* - * Function: _dal_dma_segment_free - */ -static void -_dal_dma_segment_free(dma_segment_t* dseg) -{ - int i; - unsigned long page_addr; - - if (dseg->blk_ptr) - { - for (i = 0; i < dseg->blk_cnt; i++) - { - if (dseg->blk_ptr[i]) - { - for (page_addr = dseg->blk_ptr[i]; - page_addr < dseg->blk_ptr[i] + dseg->blk_size; - page_addr += PAGE_SIZE) - { - MEM_MAP_UNRESERVE(VIRT_TO_PAGE(page_addr)); - } - - free_pages(dseg->blk_ptr[i], dseg->blk_order); - } - } - - kfree(dseg->blk_ptr); - kfree(dseg); - } -} - -/* - * Function: -dal_pgalloc - */ -static void* -_dal_pgalloc(unsigned int size) -{ - dma_segment_t* dseg; - unsigned int blk_size; - - blk_size = (size < DMA_BLOCK_SIZE) ? size : DMA_BLOCK_SIZE; - if ((dseg = _dal_dma_segment_alloc(size, blk_size)) == NULL) - { - return NULL; - } - - if (dseg->seg_size < size) - { - /* If we didn't get the full size then forget it */ - printk("Notice: Can not get enough memory for requset!!\n"); - printk("actual size:0x%lx, request size:0x%x\n", dseg->seg_size, size); - //-_dal_dma_segment_free(dseg); - //-return NULL; - } - - list_add(&dseg->list, &_dma_seg); - return (void*)dseg->seg_begin; -} - -/* - * Function: _dal_pgfree - */ -static int -_dal_pgfree(void* ptr) -{ - struct list_head* pos; - - list_for_each(pos, &_dma_seg) - { - dma_segment_t* dseg = list_entry(pos, dma_segment_t, list); - if (ptr == (void*)dseg->seg_begin) - { - list_del(&dseg->list); - _dal_dma_segment_free(dseg); - return 0; - } - } - return -1; -} -#endif -static void -dal_alloc_dma_pool(int lchip, int size) -{ - if (use_high_memory) - { - dma_phy_base[lchip] = virt_to_bus(high_memory); - dma_virt_base[lchip] = ioremap_nocache(dma_phy_base[lchip], size); - } - else - { -#ifdef DMA_MEM_MODE_PLATFORM - dma_virt_base[lchip] = dma_alloc_coherent(&(dal_dev[lchip].pci_dev->dev), dma_mem_size, - &dma_phy_base[lchip], GFP_KERNEL); - - printk(KERN_WARNING "########Using DMA_MEM_MODE_PLATFORM \n"); -#endif - -#ifndef DMA_MEM_MODE_PLATFORM - /* Get DMA memory from kernel */ - dma_virt_base_tmp[lchip] = _dal_pgalloc(size); - dma_phy_base[lchip] = virt_to_bus(dma_virt_base_tmp[lchip]); - dma_virt_base [lchip]= ioremap_nocache(dma_phy_base[lchip], size); -#endif - } -} - -static void -dal_free_dma_pool(int lchip) -{ - int ret = 0; - ret = ret; - if (use_high_memory) - { - iounmap(dma_virt_base[lchip]); - } - else - { -#ifdef DMA_MEM_MODE_PLATFORM - dma_free_coherent(&(dal_dev[lchip].pci_dev->dev), dma_mem_size, - dma_virt_base[lchip], dma_phy_base[lchip]); -#endif - -#ifndef DMA_MEM_MODE_PLATFORM - iounmap(dma_virt_base[lchip]); - ret = _dal_pgfree(dma_virt_base_tmp[lchip]); - if(ret<0) - { - printk("Dma free memory fail !!!!!! \n"); - } -#endif - } -} - -#define _KERNEL_DAL_IO -static int -_dal_pci_read(unsigned char lchip, unsigned int offset, unsigned int* value) -{ - if (!VERIFY_CHIP_INDEX(lchip)) - { - return -1; - } - - *value = *(volatile unsigned int*)(dal_dev[lchip].logic_address + offset); - return 0; -} - -int -dal_create_irq_mapping(unsigned long arg) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) - -#ifndef NO_IRQ -#define NO_IRQ (-1) -#endif - dal_irq_mapping_t irq_map; - - if (copy_from_user(&irq_map, (void*)arg, sizeof(dal_irq_mapping_t))) - { - return -EFAULT; - } - - irq_map.sw_irq = irq_create_mapping(NULL, irq_map.hw_irq); - if (irq_map.sw_irq == NO_IRQ) - { - printk("IRQ mapping fail !!!!!! \n"); - return -1; - } - - if (copy_to_user((dal_irq_mapping_t*)arg, (void*)&irq_map, sizeof(dal_irq_mapping_t))) - { - return -EFAULT; - } -#endif - return 0; -} - -int -dal_pci_read(unsigned long arg) -{ - dal_chip_parm_t cmdpara_chip; - - if (copy_from_user(&cmdpara_chip, (void*)arg, sizeof(dal_chip_parm_t))) - { - return -EFAULT; - } - - _dal_pci_read((unsigned char)cmdpara_chip.lchip, (unsigned int)cmdpara_chip.reg_addr, - (unsigned int*)(&(cmdpara_chip.value))); - - if (copy_to_user((dal_chip_parm_t*)arg, (void*)&cmdpara_chip, sizeof(dal_chip_parm_t))) - { - return -EFAULT; - } - - return 0; -} - -static int -_dal_pci_write(unsigned char lchip, unsigned int offset, unsigned int value) -{ - if (!VERIFY_CHIP_INDEX(lchip)) - { - return -1; - } - - *(volatile unsigned int*)(dal_dev[lchip].logic_address + offset) = value; - return 0; -} - -int -dal_pci_write(unsigned long arg) -{ - dal_chip_parm_t cmdpara_chip; - - if (copy_from_user(&cmdpara_chip, (void*)arg, sizeof(dal_chip_parm_t))) - { - return -EFAULT; - } - - _dal_pci_write((unsigned char)cmdpara_chip.lchip, (unsigned int)cmdpara_chip.reg_addr, - (unsigned int)cmdpara_chip.value); - - return 0; -} - -int -dal_pci_conf_read(unsigned char lchip, unsigned int offset, unsigned int* value) -{ - if (!VERIFY_CHIP_INDEX(lchip)) - { - return -1; - } - - pci_read_config_dword(dal_dev[lchip].pci_dev, offset, value); - return 0; -} - -int -dal_pci_conf_write(unsigned char lchip, unsigned int offset, unsigned int value) -{ - if (!VERIFY_CHIP_INDEX(lchip)) - { - return -1; - } - - pci_write_config_dword(dal_dev[lchip].pci_dev, offset, value); - return 0; -} -int -dal_user_read_pci_conf(unsigned long arg) -{ - dal_pci_cfg_ioctl_t dal_cfg; - - if (copy_from_user(&dal_cfg, (void*)arg, sizeof(dal_pci_cfg_ioctl_t))) - { - return -EFAULT; - } - - if (dal_pci_conf_read(dal_cfg.lchip, dal_cfg.offset, &dal_cfg.value)) - { - printk("dal_pci_conf_read failed.\n"); - return -EFAULT; - } - - if (copy_to_user((dal_pci_cfg_ioctl_t*)arg, (void*)&dal_cfg, sizeof(dal_pci_cfg_ioctl_t))) - { - return -EFAULT; - } - - return 0; -} - -int -dal_user_write_pci_conf(unsigned long arg) -{ - dal_pci_cfg_ioctl_t dal_cfg; - - if (copy_from_user(&dal_cfg, (void*)arg, sizeof(dal_pci_cfg_ioctl_t))) - { - return -EFAULT; - } - - return dal_pci_conf_write(dal_cfg.lchip, dal_cfg.offset, dal_cfg.value); -} - -static int -linux_get_device(unsigned long arg) -{ - dal_user_dev_t user_dev; - int lchip = 0; - - if (copy_from_user(&user_dev, (void*)arg, sizeof(user_dev))) - { - return -EFAULT; - } - - user_dev.chip_num = dal_chip_num; - lchip = user_dev.lchip; - - if (lchip < dal_chip_num) - { - user_dev.phy_base0 = (unsigned int)dal_dev[lchip].phys_address; - user_dev.phy_base1 = (unsigned int)(dal_dev[lchip].phys_address >> 32); - - user_dev.bus_no = dal_dev[lchip].pci_dev->bus->number; - user_dev.dev_no = dal_dev[lchip].pci_dev->device; - user_dev.fun_no = dal_dev[lchip].pci_dev->devfn; - } - - if (copy_to_user((dal_user_dev_t*)arg, (void*)&user_dev, sizeof(user_dev))) - { - return -EFAULT; - } - - return 0; -} - -/* set dal version, copy to user */ -static int -linux_get_dal_version(unsigned long arg) -{ - int dal_ver = VERSION_1DOT2; /* set dal version */ - - if (copy_to_user((int*)arg, (void*)&dal_ver, sizeof(dal_ver))) - { - return -EFAULT; - } - - dal_version = dal_ver; /* up sw */ - - return 0; -} - -static int -linux_get_dma_info(unsigned long arg) -{ - dma_info_t dma_para; - - if (copy_from_user(&dma_para, (void*)arg, sizeof(dma_info_t))) - { - return -EFAULT; - } - - dma_para.phy_base = (unsigned int)dma_phy_base[dma_para.lchip]; - dma_para.phy_base_hi = dma_phy_base[dma_para.lchip] >> 32; - dma_para.size = dma_mem_size; - - if (copy_to_user((dma_info_t*)arg, (void*)&dma_para, sizeof(dma_info_t))) - { - return -EFAULT; - } - - return 0; -} - -static int -dal_get_msi_info(unsigned long arg) -{ - dal_msi_info_t msi_para; - unsigned int lchip = 0; - - /* get lchip form user mode */ - if (copy_from_user(&msi_para, (void*)arg, sizeof(dal_msi_info_t))) - { - return -EFAULT; - } - lchip = msi_para.lchip; - - msi_para.irq_base = msi_irq_base[lchip]; - msi_para.irq_num = msi_irq_num[lchip]; - - /* send msi info to user mode */ - if (copy_to_user((dal_msi_info_t*)arg, (void*)&msi_para, sizeof(dal_msi_info_t))) - { - return -EFAULT; - } - - return 0; -} - - -static int -dal_get_intr_info(unsigned long arg) -{ - dal_intr_info_t intr_para; - unsigned int intr_num = 0; - - /* get lchip form user mode */ - if (copy_from_user(&intr_para, (void*)arg, sizeof(dal_intr_info_t))) - { - return -EFAULT; - } - - intr_para.irq_idx = CTC_MAX_INTR_NUM; - for (intr_num=0; intr_num< CTC_MAX_INTR_NUM; intr_num++) - { - if (intr_para.irq == dal_isr[intr_num].irq) - { - intr_para.irq_idx = intr_num; - break; - } - } - - if (CTC_MAX_INTR_NUM == intr_para.irq_idx) - { - printk("Interrupt %d cann't find.\n", intr_para.irq); - } - /* send msi info to user mode */ - if (copy_to_user((dal_intr_info_t*)arg, (void*)&intr_para, sizeof(dal_intr_info_t))) - { - return -EFAULT; - } - - return 0; -} - -static int -dal_cache_inval(unsigned long arg) -{ - dal_dma_cache_info_t intr_para; - - if (copy_from_user(&intr_para, (void*)arg, sizeof(dal_dma_cache_info_t))) - { - return -EFAULT; - } - -#if 0 - dma_cache_wback_inv((unsigned long)intr_para.ptr, intr_para.length); -#endif - -#if 0 - dma_sync_single_for_cpu(NULL, intr_para.ptr, intr_para.length, DMA_BIDIRECTIONAL); - - - dma_cache_sync(NULL, (void*)intr_para.ptr, intr_para.length, DMA_BIDIRECTIONAL); -#endif - return 0; -} - -static int -dal_cache_flush(unsigned long arg) -{ - dal_dma_cache_info_t intr_para; - - if (copy_from_user(&intr_para, (void*)arg, sizeof(dal_dma_cache_info_t))) - { - return -EFAULT; - } - -#if 0 - dma_cache_wback_inv(intr_para.ptr, intr_para.length); -#endif - -#if 0 - dma_sync_single_for_cpu(NULL, intr_para.ptr, intr_para.length, DMA_BIDIRECTIONAL); - - - dma_cache_sync(NULL, (void*)intr_para.ptr, intr_para.length, DMA_BIDIRECTIONAL); -#endif - return 0; -} - -int -linux_dal_probe(struct pci_dev* pdev, const struct pci_device_id* id) -{ - dal_kern_dev_t* dev = NULL; - int bar = 0; - int ret = 0; - unsigned int temp = 0; - unsigned int lchip = 0; - - printk(KERN_WARNING "********found dal device*****\n"); - - for (lchip = 0; lchip < DAL_MAX_CHIP_NUM; lchip ++) - { - if (NULL == dal_dev[lchip].pci_dev) - { - break; - } - } - - if (lchip >= DAL_MAX_CHIP_NUM) - { - printk("Exceed max local chip num\n"); - return -1; - } - - dev = &dal_dev[lchip]; - if (NULL == dev) - { - printk("Cannot obtain PCI resources\n"); - } - - lchip = lchip; - dal_chip_num += 1; - - dev->pci_dev = pdev; - - if (pci_enable_device(pdev) < 0) - { - printk("Cannot enable PCI device: vendor id = %x, device id = %x\n", - pdev->vendor, pdev->device); - } - - ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); - if (ret) - { - ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); - if (ret) - { - printk("Could not set PCI DMA Mask\n"); - return ret; - } - } - - if (pci_request_regions(pdev, DAL_NAME) < 0) - { - printk("Cannot obtain PCI resources\n"); - } - - dev->phys_address = pci_resource_start(pdev, bar); - dev->logic_address = (uintptr)ioremap_nocache(dev->phys_address, - pci_resource_len(dev->pci_dev, bar)); - - _dal_pci_read(lchip, 0x48, &temp); - if (((temp >> 8) & 0xffff) == 0x3412) - { - printk("Little endian Cpu detected!!! \n"); - _dal_pci_write(lchip, 0x48, 0xFFFFFFFF); - } - - pci_set_master(pdev); - - /* alloc dma_mem_size for every chip */ - if (dma_mem_size) - { - dal_alloc_dma_pool(lchip, dma_mem_size); - - /*add check Dma memory pool cannot cross 4G space*/ - if ((0==(dma_phy_base[lchip]>>32)) && (0!=((dma_phy_base[lchip]+dma_mem_size)>>32))) - { - printk("Dma malloc memory cross 4G space!!!!!! \n"); - return -1; - } - } - - printk(KERN_WARNING "linux_dal_probe end*****\n"); - - return 0; -} - -void -linux_dal_remove(struct pci_dev* pdev) -{ - unsigned int lchip = 0; - unsigned int flag = 0; - - for (lchip = 0; lchip < DAL_MAX_CHIP_NUM; lchip ++) - { - if (pdev == dal_dev[lchip].pci_dev) - { - flag = 1; - break; - } - } - - if (1 == flag) - { - dal_free_dma_pool(lchip); - pci_release_regions(pdev); - pci_disable_device(pdev); - - dal_dev[lchip].pci_dev = NULL; - dal_chip_num--; - } - - -} - -#ifdef CONFIG_COMPAT -static long -linux_dal_ioctl(struct file* file, - unsigned int cmd, unsigned long arg) -#else - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)) -static int -linux_dal_ioctl(struct file* file, - unsigned int cmd, unsigned long arg) -#else -static int -linux_dal_ioctl(struct inode* inode, struct file* file, - unsigned int cmd, unsigned long arg) -#endif - -#endif -{ - switch (cmd) - { - - case CMD_READ_CHIP: - return dal_pci_read(arg); - - case CMD_WRITE_CHIP: - return dal_pci_write(arg); - - case CMD_GET_DEVICES: - return linux_get_device(arg); - - case CMD_GET_DAL_VERSION: - return linux_get_dal_version(arg); - - case CMD_GET_DMA_INFO: - return linux_get_dma_info(arg); - - case CMD_PCI_CONFIG_READ: - return dal_user_read_pci_conf(arg); - - case CMD_PCI_CONFIG_WRITE: - return dal_user_write_pci_conf(arg); - - case CMD_REG_INTERRUPTS: - return dal_user_interrupt_register(arg); - - case CMD_UNREG_INTERRUPTS: - return dal_user_interrupt_unregister(arg); - - case CMD_EN_INTERRUPTS: - return dal_user_interrupt_set_en(arg); - - case CMD_SET_MSI_CAP: - return dal_set_msi_cap(arg); - - case CMD_GET_MSI_INFO: - return dal_get_msi_info(arg); - - case CMD_IRQ_MAPPING: - return dal_create_irq_mapping(arg); - - case CMD_GET_INTR_INFO: - return dal_get_intr_info(arg); - - case CMD_CACHE_INVAL: - return dal_cache_inval(arg); - - case CMD_CACHE_FLUSH: - return dal_cache_flush(arg); - - default: - break; - } - - return 0; -} - -static unsigned int -linux_dal_poll0(struct file* filp, struct poll_table_struct* p) -{ - unsigned int mask = 0; - unsigned long flags; - - poll_wait(filp, &poll_intr[0], p); - local_irq_save(flags); - if (poll_intr_trigger[0]) - { - poll_intr_trigger[0] = 0; - mask |= POLLIN | POLLRDNORM; - } - - local_irq_restore(flags); - - return mask; -} - -static unsigned int -linux_dal_poll1(struct file* filp, struct poll_table_struct* p) -{ - unsigned int mask = 0; - unsigned long flags; - - poll_wait(filp, &poll_intr[1], p); - local_irq_save(flags); - if (poll_intr_trigger[1]) - { - poll_intr_trigger[1] = 0; - mask |= POLLIN | POLLRDNORM; - } - - local_irq_restore(flags); - - return mask; -} - -static unsigned int -linux_dal_poll2(struct file* filp, struct poll_table_struct* p) -{ - unsigned int mask = 0; - unsigned long flags; - - poll_wait(filp, &poll_intr[2], p); - local_irq_save(flags); - if (poll_intr_trigger[2]) - { - poll_intr_trigger[2] = 0; - mask |= POLLIN | POLLRDNORM; - } - - local_irq_restore(flags); - - return mask; -} - -static unsigned int -linux_dal_poll3(struct file* filp, struct poll_table_struct* p) -{ - unsigned int mask = 0; - unsigned long flags; - - poll_wait(filp, &poll_intr[3], p); - local_irq_save(flags); - if (poll_intr_trigger[3]) - { - poll_intr_trigger[3] = 0; - mask |= POLLIN | POLLRDNORM; - } - - local_irq_restore(flags); - - return mask; -} - -static unsigned int -linux_dal_poll4(struct file* filp, struct poll_table_struct* p) -{ - unsigned int mask = 0; - unsigned long flags; - - poll_wait(filp, &poll_intr[4], p); - local_irq_save(flags); - if (poll_intr_trigger[4]) - { - poll_intr_trigger[4] = 0; - mask |= POLLIN | POLLRDNORM; - } - - local_irq_restore(flags); - - return mask; -} - -static unsigned int -linux_dal_poll5(struct file* filp, struct poll_table_struct* p) -{ - unsigned int mask = 0; - unsigned long flags; - - poll_wait(filp, &poll_intr[5], p); - local_irq_save(flags); - if (poll_intr_trigger[5]) - { - poll_intr_trigger[5] = 0; - mask |= POLLIN | POLLRDNORM; - } - - local_irq_restore(flags); - - return mask; -} - -static unsigned int -linux_dal_poll6(struct file* filp, struct poll_table_struct* p) -{ - unsigned int mask = 0; - unsigned long flags; - - poll_wait(filp, &poll_intr[6], p); - local_irq_save(flags); - if (poll_intr_trigger[6]) - { - poll_intr_trigger[6] = 0; - mask |= POLLIN | POLLRDNORM; - } - - local_irq_restore(flags); - - return mask; -} - -static unsigned int -linux_dal_poll7(struct file* filp, struct poll_table_struct* p) -{ - unsigned int mask = 0; - unsigned long flags; - - poll_wait(filp, &poll_intr[7], p); - local_irq_save(flags); - if (poll_intr_trigger[7]) - { - poll_intr_trigger[7] = 0; - mask |= POLLIN | POLLRDNORM; - } - - local_irq_restore(flags); - - return mask; -} - -static struct pci_driver linux_dal_driver = -{ - .name = DAL_NAME, - .id_table = dal_id_table, - .probe = linux_dal_probe, - .remove = linux_dal_remove, -}; - -static struct file_operations fops = -{ - .owner = THIS_MODULE, -#ifdef CONFIG_COMPAT - .compat_ioctl = linux_dal_ioctl, - .unlocked_ioctl = linux_dal_ioctl, -#else -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)) - .unlocked_ioctl = linux_dal_ioctl, -#else - .ioctl = linux_dal_ioctl, -#endif -#endif -}; - - -static int __init -linux_dal_init(void) -{ - int ret = 0; - - /* Get DMA memory pool size form dal.ok input param, or use default dma_mem_size */ - if (dma_pool_size) - { - if ((dma_pool_size[strlen(dma_pool_size) - 1] & ~0x20) == 'M') - { - dma_mem_size = simple_strtoul(dma_pool_size, NULL, 0); - printk("dma_mem_size: 0x%x \n", dma_mem_size); - - dma_mem_size *= MB_SIZE; - } - else - { - printk("DMA memory pool size must be specified as e.g. dma_pool_size=8M\n"); - } - - if (dma_mem_size & (dma_mem_size - 1)) - { - printk("dma_mem_size must be a power of 2 (1M, 2M, 4M, 8M etc.)\n"); - dma_mem_size = 0; - } - } - - ret = register_chrdev(DAL_DEV_MAJOR, DAL_NAME, &fops); - if (ret < 0) - { - printk(KERN_WARNING "Register linux_dal device, ret %d\n", ret); - return ret; - } - - ret = pci_register_driver(&linux_dal_driver); - if (ret < 0) - { - printk(KERN_WARNING "Register ASIC PCI driver failed, ret %d\n", ret); - return ret; - } - - /* alloc /dev/linux_dal node */ - dal_class = class_create(THIS_MODULE, DAL_NAME); - device_create(dal_class, NULL, MKDEV(DAL_DEV_MAJOR, 0), NULL, DAL_NAME); - - /* init interrupt function */ - intr_handler_fun[0] = intr0_handler; - intr_handler_fun[1] = intr1_handler; - intr_handler_fun[2] = intr2_handler; - intr_handler_fun[3] = intr3_handler; - intr_handler_fun[4] = intr4_handler; - intr_handler_fun[5] = intr5_handler; - intr_handler_fun[6] = intr6_handler; - intr_handler_fun[7] = intr7_handler; - - return ret; -} - -static void __exit -linux_dal_exit(void) -{ - device_destroy(dal_class, MKDEV(DAL_DEV_MAJOR, 0)); - class_destroy(dal_class); - unregister_chrdev(DAL_DEV_MAJOR, "linux_dal"); - pci_unregister_driver(&linux_dal_driver); -} - -module_init(linux_dal_init); -module_exit(linux_dal_exit); - - diff --git a/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_kernel.h b/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_kernel.h deleted file mode 100644 index 850a4cffa731..000000000000 --- a/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_kernel.h +++ /dev/null @@ -1,171 +0,0 @@ -/** - @file dal_kernel_io.h - - @author Copyright (C) 2012 Centec Networks Inc. All rights reserved. - - @date 2012-4-9 - - @version v2.0 - -*/ -#ifndef _DAL_KERNEL_H_ -#define _DAL_KERNEL_H_ -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(CONFIG_RESOURCES_64BIT) || defined(CONFIG_PHYS_ADDR_T_64BIT) -#define PHYS_ADDR_IS_64BIT -#endif - -#ifndef SDK_IN_USERMODE -#ifdef PHYS_ADDR_IS_64BIT -typedef long long intptr; -typedef unsigned long long uintptr; -#else -typedef int intptr; -typedef unsigned int uintptr; -#endif -#endif - -#define DAL_PCI_READ_ADDR 0x0 -#define DAL_PCI_READ_DATA 0xc -#define DAL_PCI_WRITE_ADDR 0x8 -#define DAL_PCI_WRITE_DATA 0x4 -#define DAL_PCI_STATUS 0x10 - -#define DAL_PCI_STATUS_IN_PROCESS 31 -#define DAL_PCI_STATUS_BAD_PARITY 5 -#define DAL_PCI_STATUS_CPU_ACCESS_ERR 4 -#define DAL_PCI_STATUS_READ_CMD 3 -#define DAL_PCI_STATUS_REGISTER_ERR 1 -#define DAL_PCI_STATUS_REGISTER_ACK 0 - -#define DAL_PCI_ACCESS_TIMEOUT 0x64 - -#define DAL_NAME "linux_dal" /* "linux_dal" */ - -#define DAL_DEV_MAJOR 198 - -#define DAL_DEV_INTR_MAJOR_BASE 200 - -#define DAL_DEV_NAME "/dev/" DAL_NAME -#define DAL_ONE_KB 1024 -#define DAL_ONE_MB (1024*1024) -struct dal_chip_parm_s -{ - unsigned int lchip; /*tmp should be uint8*/ - unsigned int fpga_id; /*tmp add*/ - unsigned int reg_addr; - unsigned int value; -}; -typedef struct dal_chip_parm_s dal_chip_parm_t; - -struct dal_intr_parm_s -{ - unsigned int irq; - unsigned int enable; -}; -typedef struct dal_intr_parm_s dal_intr_parm_t; - -struct dal_irq_mapping_s -{ - unsigned int hw_irq; - unsigned int sw_irq; -}; -typedef struct dal_irq_mapping_s dal_irq_mapping_t; - -struct dal_user_dev_s -{ - unsigned int chip_num; /*output: local chip number*/ - unsigned int lchip; /*input: local chip id*/ - unsigned int phy_base0; /* low 32bits physical base address */ - unsigned int phy_base1; /* high 32bits physical base address */ - unsigned int bus_no; - unsigned int dev_no; - unsigned int fun_no; - void* virt_base[2]; /* Virtual base address; this must be last member */ -}; -typedef struct dal_user_dev_s dal_user_dev_t; - -struct dma_info_s -{ - unsigned int lchip; - unsigned int phy_base; - unsigned int phy_base_hi; - unsigned int size; - unsigned int* virt_base; -}; -typedef struct dma_info_s dma_info_t; - -struct dal_pci_cfg_ioctl_s -{ - unsigned int lchip; /* Device ID */ - unsigned int offset; - unsigned int value; -}; -typedef struct dal_pci_cfg_ioctl_s dal_pci_cfg_ioctl_t; - -struct dal_msi_info_s -{ - unsigned int lchip; - unsigned int irq_base; - unsigned int irq_num; -}; -typedef struct dal_msi_info_s dal_msi_info_t; - -struct dal_intr_info_s -{ - unsigned int irq; - unsigned int irq_idx; -}; -typedef struct dal_intr_info_s dal_intr_info_t; - -struct dal_dma_cache_info_s -{ - unsigned long ptr; - unsigned int length; -}; -typedef struct dal_dma_cache_info_s dal_dma_cache_info_t; - -#define CMD_MAGIC 'C' -#define CMD_WRITE_CHIP _IO(CMD_MAGIC, 0) /* for humber ioctrol*/ -#define CMD_READ_CHIP _IO(CMD_MAGIC, 1) /* for humber ioctrol*/ -#define CMD_GET_DEVICES _IO(CMD_MAGIC, 2) -#define CMD_GET_DAL_VERSION _IO(CMD_MAGIC, 3) -#define CMD_PCI_CONFIG_WRITE _IO(CMD_MAGIC, 4) -#define CMD_PCI_CONFIG_READ _IO(CMD_MAGIC, 5) -#define CMD_GET_DMA_INFO _IO(CMD_MAGIC, 6) -#define CMD_REG_INTERRUPTS _IO(CMD_MAGIC, 7) -#define CMD_UNREG_INTERRUPTS _IO(CMD_MAGIC, 8) -#define CMD_EN_INTERRUPTS _IO(CMD_MAGIC, 9) -#define CMD_I2C_READ _IO(CMD_MAGIC, 10) -#define CMD_I2C_WRITE _IO(CMD_MAGIC, 11) -#define CMD_GET_MSI_INFO _IO(CMD_MAGIC, 12) -#define CMD_SET_MSI_CAP _IO(CMD_MAGIC, 13) -#define CMD_IRQ_MAPPING _IO(CMD_MAGIC, 14) -#define CMD_GET_INTR_INFO _IO(CMD_MAGIC, 15) -#define CMD_CACHE_INVAL _IO(CMD_MAGIC, 16) -#define CMD_CACHE_FLUSH _IO(CMD_MAGIC, 17) - -enum dal_version_e -{ - VERSION_MIN, - VERSION_1DOT0, - VERSION_1DOT1, - VERSION_1DOT2, - - VERSION_MAX -}; -typedef enum dal_version_e dal_version_t; - -/* We try to assemble a contiguous segment from chunks of this size */ -#define DMA_BLOCK_SIZE (512 * DAL_ONE_KB) - -#ifdef __cplusplus -} -#endif - -#endif - - diff --git a/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_mpool.c b/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_mpool.c deleted file mode 100644 index 5aca222a138f..000000000000 --- a/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_mpool.c +++ /dev/null @@ -1,350 +0,0 @@ -#include "dal_mpool.h" - -#ifdef __KERNEL__ -#include -#include - -#define DAL_MALLOC(x) kmalloc(x, GFP_ATOMIC) -#define DAL_FREE(x) kfree(x) - -static spinlock_t dal_mpool_lock; -#define MPOOL_LOCK_INIT() spin_lock_init(&dal_mpool_lock) -#define MPOOL_LOCK() unsigned long flags; spin_lock_irqsave(&dal_mpool_lock, flags) -#define MPOOL_UNLOCK() spin_unlock_irqrestore(&dal_mpool_lock, flags) -#define DAL_PRINT(fmt,arg...) printk(fmt,##arg) -#else /* !__KERNEL__*/ - -#include -#include "sal.h" -#define DAL_MALLOC(x) malloc(x) -#define DAL_FREE(x) free(x) -static sal_mutex_t* dal_mpool_lock; -#define MPOOL_LOCK_INIT() sal_mutex_create(&dal_mpool_lock) -#define MPOOL_LOCK() sal_mutex_lock(dal_mpool_lock) -#define MPOOL_UNLOCK() sal_mutex_unlock(dal_mpool_lock) -#define DAL_PRINT(fmt,arg...) sal_printf(fmt,##arg) - -#endif /* __KERNEL__ */ - - - -dal_mpool_mem_t* g_free_block_ptr = NULL; - -/* System cache line size */ -#ifndef DAL_CACHE_LINE_BYTES -#define DAL_CACHE_LINE_BYTES 256 -#endif - -#define DAL_MAX_CHIP_NUM 32 -static dal_mpool_mem_t* p_desc_pool[DAL_MAX_CHIP_NUM] = {0}; -static dal_mpool_mem_t* p_data_pool[DAL_MAX_CHIP_NUM] = {0}; - -int -dal_mpool_init(void) -{ - MPOOL_LOCK_INIT(); - return 0; -} - -dal_mpool_mem_t* -_dal_mpool_create(void* base, int size, int type) -{ - dal_mpool_mem_t* head = NULL; - dal_mpool_mem_t* tail = NULL; - - head = (dal_mpool_mem_t*)DAL_MALLOC(sizeof(dal_mpool_mem_t)); - if (head == NULL) - { - return NULL; - } - - tail = (dal_mpool_mem_t*)DAL_MALLOC(sizeof(dal_mpool_mem_t)); - if (tail == NULL) - { - DAL_FREE(head); - return NULL; - } - - head->size = tail->size = 0; - head->type = type; - head->address = base; - tail->address = head->address + size; - head->next = tail; - tail->next = NULL; - - return head; -} - -dal_mpool_mem_t* -dal_mpool_create(unsigned char lchip, void* base, int size) -{ - dal_mpool_mem_t* head = NULL; - int mod = (int)(((unsigned long)base) & (DAL_CACHE_LINE_BYTES - 1)); - - MPOOL_LOCK(); - - if (mod) - { - base = (char*)base + (DAL_CACHE_LINE_BYTES - mod); - size -= (DAL_CACHE_LINE_BYTES - mod); - } - - size &= ~(DAL_CACHE_LINE_BYTES - 1); - - /* init for common linkptr, only used for GB */ - head = _dal_mpool_create(base, size, DAL_MPOOL_TYPE_USELESS); - if (NULL == head) - { - MPOOL_UNLOCK(); - return NULL; - } - - /* init for desc linkptr */ - p_desc_pool[lchip] = _dal_mpool_create(base, DAL_MPOOL_MAX_DESX_SIZE, DAL_MPOOL_TYPE_DESC); - if (NULL == p_desc_pool[lchip]) - { - MPOOL_UNLOCK(); - DAL_FREE(head->next); - DAL_FREE(head); - return NULL; - } - - /* init for data linkptr */ - p_data_pool[lchip] = _dal_mpool_create(((char*)base+DAL_MPOOL_MAX_DESX_SIZE), (size - DAL_MPOOL_MAX_DESX_SIZE), DAL_MPOOL_TYPE_DATA); - if (NULL == p_data_pool[lchip]) - { - MPOOL_UNLOCK(); - DAL_FREE(head->next); - DAL_FREE(head); - DAL_FREE(p_desc_pool[lchip]->next); - DAL_FREE(p_desc_pool[lchip]); - return NULL; - } - - MPOOL_UNLOCK(); - - return head; -} - -dal_mpool_mem_t* -_dal_mpool_alloc_comon(dal_mpool_mem_t* ptr, int size, int type) -{ - dal_mpool_mem_t* new_ptr = NULL; - - while (ptr && ptr->next) - { - if (ptr->next->address - (ptr->address + ptr->size) >= size) - { - break; - } - - ptr = ptr->next; - } - - if (!(ptr && ptr->next)) - { - return NULL; - } - - new_ptr = DAL_MALLOC(sizeof(dal_mpool_mem_t)); - if (!new_ptr) - { - return NULL; - } - - new_ptr->type = type; - new_ptr->address = ptr->address + ptr->size; - new_ptr->size = size; - new_ptr->next = ptr->next; - ptr->next = new_ptr; - - return new_ptr; -} - -void* -dal_mpool_alloc(unsigned char lchip, dal_mpool_mem_t* pool, int size, int type) -{ - dal_mpool_mem_t* ptr = NULL; - dal_mpool_mem_t* new_ptr = NULL; - int mod; - - MPOOL_LOCK(); - - mod = size & (DAL_CACHE_LINE_BYTES - 1); - if (mod != 0) - { - size += (DAL_CACHE_LINE_BYTES - mod); - } - - switch(type) - { - case DAL_MPOOL_TYPE_USELESS: - ptr = pool; - new_ptr = _dal_mpool_alloc_comon(ptr, size, type); - if (NULL == new_ptr) - { - MPOOL_UNLOCK(); - return NULL; - } - break; - case DAL_MPOOL_TYPE_DESC: - ptr = p_desc_pool[lchip]; - new_ptr = _dal_mpool_alloc_comon(ptr, size, type); - if (NULL == new_ptr) - { - MPOOL_UNLOCK(); - return NULL; - } - break; - case DAL_MPOOL_TYPE_DATA: - ptr = p_data_pool[lchip]; - new_ptr = _dal_mpool_alloc_comon(ptr, size, type); - if (NULL == new_ptr) - { - MPOOL_UNLOCK(); - return NULL; - } - break; - default: - MPOOL_UNLOCK(); - return NULL; - break; - } - - MPOOL_UNLOCK(); - if( NULL == new_ptr ) - { - return NULL; - } - - return new_ptr->address; -} - -void -_dal_mpool_free(dal_mpool_mem_t* ptr, void* addr, int type) -{ - unsigned char* address = (unsigned char*)addr; - dal_mpool_mem_t* prev = NULL; - - while (ptr && ptr->next) - { - if (ptr->next->address == address) - { - break; - } - - ptr = ptr->next; - } - - if (ptr && ptr->next) - { - prev = ptr; - ptr = ptr->next; - prev->next = ptr->next; - DAL_FREE(ptr); - } - - return; -} - -void -dal_mpool_free(unsigned char lchip, dal_mpool_mem_t* pool, void* addr) -{ - dal_mpool_mem_t* ptr = pool; - - MPOOL_LOCK(); - - switch(pool->type) - { - case DAL_MPOOL_TYPE_USELESS: - ptr = pool; - _dal_mpool_free(ptr, addr, DAL_MPOOL_TYPE_USELESS); - break; - case DAL_MPOOL_TYPE_DESC: - ptr = p_desc_pool[lchip]; - _dal_mpool_free(ptr, addr, DAL_MPOOL_TYPE_DESC); - break; - case DAL_MPOOL_TYPE_DATA: - ptr = p_data_pool[lchip]; - _dal_mpool_free(ptr, addr, DAL_MPOOL_TYPE_DATA); - break; - default: - break; - } - - MPOOL_UNLOCK(); - return; -} - -int -dal_mpool_destroy(unsigned char lchip, dal_mpool_mem_t* pool) -{ - dal_mpool_mem_t* ptr, * next; - - MPOOL_LOCK(); - - for (ptr = pool; ptr; ptr = next) - { - next = ptr->next; - DAL_FREE(ptr); - } - - for (ptr = p_desc_pool[lchip]; ptr; ptr = next) - { - next = ptr->next; - DAL_FREE(ptr); - } - - for (ptr = p_data_pool[lchip]; ptr; ptr = next) - { - next = ptr->next; - DAL_FREE(ptr); - } - - MPOOL_UNLOCK(); - - return 0; -} - -int -dal_mpool_usage(dal_mpool_mem_t* pool, int type) -{ - int usage = 0; - dal_mpool_mem_t* ptr; - - MPOOL_LOCK(); - - for (ptr = pool; ptr; ptr = ptr->next) - { - if (ptr->type == type || ptr->type == -1) - { - usage += ptr->size; - } - } - - MPOOL_UNLOCK(); - - return usage; -} - -int -dal_mpool_debug(dal_mpool_mem_t* pool) -{ - dal_mpool_mem_t* ptr; - int index = 0; - - MPOOL_LOCK(); - - for (ptr = pool; ptr; ptr = ptr->next) - { -// DAL_PRINT("%2dst mpool block: address=0x%8x, size=0x%x \n", index, (unsigned int)ptr->address, ptr->size); - DAL_PRINT("%2dst mpool block: address=%p, size=0x%x \n", index, ptr->address, ptr->size); // note - index++; - } - - MPOOL_UNLOCK(); - - return 0; -} - - diff --git a/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_mpool.h b/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_mpool.h deleted file mode 100644 index d93f88868136..000000000000 --- a/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_mpool.h +++ /dev/null @@ -1,72 +0,0 @@ -/** - @file dal_mpool.h - - @author Copyright (C) 2011 Centec Networks Inc. All rights reserved. - - @date 2012-5-10 - - @version v2.0 - - This file contains the dma memory init, allocation and free APIs -*/ - -#ifndef _DMA_MPOOL_H -#define _DMA_MPOOL_H -#ifdef __cplusplus -extern "C" { -#endif - -#define DAL_MPOOL_MAX_DESX_SIZE (1024*1024) - -enum dal_mpool_type_e -{ - DAL_MPOOL_TYPE_USELESS, /* just compatible with GB */ - DAL_MPOOL_TYPE_DESC, /* dma mpool op for desc */ - DAL_MPOOL_TYPE_DATA /* dma mpool op for data */ -}; -typedef enum dal_mpool_type_e dal_mpool_type_t; - -struct dal_mpool_mem_s -{ - unsigned char* address; - int size; - int type; - struct dal_mpool_mem_s* next; -}; -typedef struct dal_mpool_mem_s dal_mpool_mem_t; - -/** - @brief This function is to alloc dma memory - - @param[in] size size of memory - - @return NULL - -*/ -extern int -dal_mpool_init(void); - -extern dal_mpool_mem_t* -dal_mpool_create(unsigned char lchip, void* base_ptr, int size); - -extern void* -dal_mpool_alloc(unsigned char lchip, dal_mpool_mem_t* pool, int size, int type); - -extern void -dal_mpool_free(unsigned char lchip, dal_mpool_mem_t* pool, void* addr); - -extern int -dal_mpool_destroy(unsigned char lchip, dal_mpool_mem_t* pool); - -extern int -dal_mpool_usage(dal_mpool_mem_t* pool, int type); - -extern int -dal_mpool_debug(dal_mpool_mem_t* pool); -#ifdef __cplusplus -} -#endif - -#endif /* !_DMA_MPOOL_H */ - - diff --git a/platform/centec/sonic-platform-modules-e582/debian/control b/platform/centec/sonic-platform-modules-e582/debian/control index c449246b2823..97f617d4836a 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-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-e582-48x6q Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/centec/sonic-platform-modules-e582/debian/platform-modules-e582-48x2q4z.install b/platform/centec/sonic-platform-modules-e582/debian/platform-modules-e582-48x2q4z.install index 9bd1181e860f..30a343ff53b1 100644 --- a/platform/centec/sonic-platform-modules-e582/debian/platform-modules-e582-48x2q4z.install +++ b/platform/centec/sonic-platform-modules-e582/debian/platform-modules-e582-48x2q4z.install @@ -1,6 +1,4 @@ 48x2q4z/cfg/48x2q4z-modules.conf etc/modules-load.d -48x2q4z/cfg/config_db.json etc/sonic -48x2q4z/cfg/config_db_l2l3.json etc/sonic 48x2q4z/scripts/48x2q4z_platform.sh usr/bin 48x2q4z/scripts/48x2q4z_platform_monitor.py usr/bin 48x2q4z/service/48x2q4z_platform.service lib/systemd/system diff --git a/platform/centec/sonic-platform-modules-e582/debian/platform-modules-e582-48x6q.install b/platform/centec/sonic-platform-modules-e582/debian/platform-modules-e582-48x6q.install index a6d26ce329bc..76254afb3a29 100644 --- a/platform/centec/sonic-platform-modules-e582/debian/platform-modules-e582-48x6q.install +++ b/platform/centec/sonic-platform-modules-e582/debian/platform-modules-e582-48x6q.install @@ -1,6 +1,4 @@ 48x6q/cfg/48x6q-modules.conf etc/modules-load.d -48x6q/cfg/config_db.json etc/sonic -48x6q/cfg/config_db_l2l3.json etc/sonic 48x6q/scripts/48x6q_platform.sh usr/bin 48x6q/scripts/48x6q_platform_monitor.py usr/bin 48x6q/service/48x6q_platform.service lib/systemd/system diff --git a/platform/centec/sonic-platform-modules-e582/debian/rules b/platform/centec/sonic-platform-modules-e582/debian/rules index 9f5d67b1af5c..b726f62c8c68 100755 --- a/platform/centec/sonic-platform-modules-e582/debian/rules +++ b/platform/centec/sonic-platform-modules-e582/debian/rules @@ -14,6 +14,7 @@ override_dh_auto_build: (for mod in $(MODULE_DIRS); do \ make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ done) + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/../centec-dal override_dh_auto_install: (for mod in $(MODULE_DIRS); do \ @@ -21,6 +22,7 @@ override_dh_auto_install: $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ cp -f $(MOD_SRC_DIR)/$${mod}/modules/*.ko \ debian/platform-modules-e582-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + cp -f $(MOD_SRC_DIR)/../centec-dal/*.ko debian/platform-modules-e582-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ done) override_dh_usrlocal: @@ -32,4 +34,6 @@ override_dh_clean: rm -rf $(MOD_SRC_DIR)/$${mod}/modules/*.ko; \ rm -rf debian/platform-modules-e582-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR)/*.ko; \ done) + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/../centec-dal clean; \ + rm -rf $(MOD_SRC_DIR)/../centec-dal/*.ko diff --git a/platform/centec/sonic-platform-modules-embedway/LICENSE b/platform/centec/sonic-platform-modules-embedway/LICENSE new file mode 100644 index 000000000000..99228517bae7 --- /dev/null +++ b/platform/centec/sonic-platform-modules-embedway/LICENSE @@ -0,0 +1,15 @@ +Copyright (C) 2017 Centec, Inc + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. diff --git a/platform/centec/sonic-platform-modules-embedway/README.md b/platform/centec/sonic-platform-modules-embedway/README.md new file mode 100644 index 000000000000..61b3ef6c87f4 --- /dev/null +++ b/platform/centec/sonic-platform-modules-embedway/README.md @@ -0,0 +1 @@ +platform drivers for Centec E582 for the SONiC project diff --git a/platform/centec/sonic-platform-modules-embedway/debian/changelog b/platform/centec/sonic-platform-modules-embedway/debian/changelog new file mode 100644 index 000000000000..2a2f05ab70c6 --- /dev/null +++ b/platform/centec/sonic-platform-modules-embedway/debian/changelog @@ -0,0 +1,5 @@ +sonic-platform-modules-embedway (1.1) unstable; urgency=low + + * Initial release + + -- yangbs Mon, 22 Jan 2018 13:43:40 +0800 diff --git a/platform/centec/sonic-platform-modules-embedway/debian/compat b/platform/centec/sonic-platform-modules-embedway/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/platform/centec/sonic-platform-modules-embedway/debian/compat @@ -0,0 +1 @@ +9 diff --git a/platform/centec/sonic-platform-modules-embedway/debian/control b/platform/centec/sonic-platform-modules-embedway/debian/control new file mode 100644 index 000000000000..6fb02a824826 --- /dev/null +++ b/platform/centec/sonic-platform-modules-embedway/debian/control @@ -0,0 +1,12 @@ +Source: sonic-platform-modules-embedway +Section: main +Priority: extra +Maintainer: yangbs +Build-Depends: debhelper (>= 8.0.0), bzip2 +Standards-Version: 3.9.3 + +Package: platform-modules-embedway-es6220 +Architecture: amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned +Description: kernel modules for platform devices such as fan, led, sfp + diff --git a/platform/centec/sonic-platform-modules-embedway/debian/platform-modules-embedway-es6220.init b/platform/centec/sonic-platform-modules-embedway/debian/platform-modules-embedway-es6220.init new file mode 100755 index 000000000000..76d758cf53c0 --- /dev/null +++ b/platform/centec/sonic-platform-modules-embedway/debian/platform-modules-embedway-es6220.init @@ -0,0 +1,41 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: setup-board +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Setup e582-48x2q4z board. +### END INIT INFO + +case "$1" in +start) + echo -n "Setting up board... " + /usr/bin/es6220_platform.sh init + /usr/bin/add_crontab_remove_syslog.sh + /usr/bin/remove_syslog.sh + /usr/bin/create_eeprom.sh + + echo "done." + ;; + +stop) + /usr/bin/es6220_platform.sh deinit + echo "done." + + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: service platform-modules-embedway-es6220 {start|stop}" + exit 1 + ;; +esac + +exit 0 diff --git a/platform/centec/sonic-platform-modules-embedway/debian/platform-modules-embedway-es6220.install b/platform/centec/sonic-platform-modules-embedway/debian/platform-modules-embedway-es6220.install new file mode 100644 index 000000000000..004148fe9932 --- /dev/null +++ b/platform/centec/sonic-platform-modules-embedway/debian/platform-modules-embedway-es6220.install @@ -0,0 +1,5 @@ +es6220/scripts/es6220_platform.sh usr/bin +es6220/scripts/create_eeprom.sh usr/bin +es6220/scripts/add_crontab_remove_syslog.sh usr/bin +es6220/scripts/remove_syslog.sh usr/bin +es6220/service/es6220_platform.service lib/systemd/system diff --git a/platform/centec/sonic-platform-modules-embedway/debian/platform-modules-embedway-es6220.postinst b/platform/centec/sonic-platform-modules-embedway/debian/platform-modules-embedway-es6220.postinst new file mode 100644 index 000000000000..35f3ee2308a6 --- /dev/null +++ b/platform/centec/sonic-platform-modules-embedway/debian/platform-modules-embedway-es6220.postinst @@ -0,0 +1,3 @@ +depmod -a +systemctl enable es6220_platform.service +systemctl start es6220_platform.service diff --git a/platform/centec/sonic-platform-modules-embedway/debian/rules b/platform/centec/sonic-platform-modules-embedway/debian/rules new file mode 100755 index 000000000000..250c0861e196 --- /dev/null +++ b/platform/centec/sonic-platform-modules-embedway/debian/rules @@ -0,0 +1,25 @@ +#!/usr/bin/make -f + +export INSTALL_MOD_DIR:=extra + +KVERSION ?= $(shell uname -r) +KERNEL_SRC := /lib/modules/$(KVERSION) +MOD_SRC_DIR:= $(shell pwd) + +%: + dh $@ + +override_dh_auto_build: + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/../centec-dal + +override_dh_auto_install: + dh_installdirs -pplatform-modules-embedway-es6220 \ + $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + cp -f $(MOD_SRC_DIR)/../centec-dal/*.ko debian/platform-modules-embedway-es6220/$(KERNEL_SRC)/$(INSTALL_MOD_DIR) + +override_dh_usrlocal: + +override_dh_clean: + dh_clean + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/../centec-dal clean; \ + rm -rf $(MOD_SRC_DIR)/../centec-dal/*.ko diff --git a/platform/centec/sonic-platform-modules-embedway/es6220/scripts/add_crontab_remove_syslog.sh b/platform/centec/sonic-platform-modules-embedway/es6220/scripts/add_crontab_remove_syslog.sh new file mode 100755 index 000000000000..f5db8f0fc68e --- /dev/null +++ b/platform/centec/sonic-platform-modules-embedway/es6220/scripts/add_crontab_remove_syslog.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +#sed -n '7p' /etc/rsyslog.d/99-default.conf +sudo sed -i '7c !user.debug;*.*;cron,auth,authpriv.none -/var/log/syslog' /etc/rsyslog.d/99-default.conf +sudo sed -i '10c user.debug /var/log/sdkdebug' /etc/rsyslog.d/99-default.conf +#sed -n '7p' /etc/rsyslog.d/99-default.conf +sudo service rsyslog restart + +sudo sed -i '9c */5 * * * * root /usr/bin/remove_syslog.sh' /etc/crontab +#echo "*/5 * * * * root /usr/bin/remove_syslog.sh" >> /etc/crontab + +exit 0 diff --git a/platform/centec/sonic-platform-modules-embedway/es6220/scripts/create_eeprom.sh b/platform/centec/sonic-platform-modules-embedway/es6220/scripts/create_eeprom.sh new file mode 100755 index 000000000000..052191a33803 --- /dev/null +++ b/platform/centec/sonic-platform-modules-embedway/es6220/scripts/create_eeprom.sh @@ -0,0 +1,18 @@ +#! /bin/bash + +#find cache of eeprom and delete, otherwise will dislay cache +cache_file="/var/cache/sonic/decode-syseeprom/syseeprom_cache" +if [ -f $cache_file ]; then + rm -f $cache_file +fi + +#create new device for eeprom +tmp=`i2cdetect -l | grep CP` +bus_num=${tmp:4:1} + +path="/sys/bus/i2c/devices/i2c-${bus_num}" + +cd $path +echo "24c512 0x56" > new_device + +sudo dd if=/sys/bus/i2c/devices/${bus_num}-0056/eeprom of=/home/admin/eeprom.bin bs=1 count=512 diff --git a/platform/centec/sonic-platform-modules-embedway/es6220/scripts/es6220_platform.sh b/platform/centec/sonic-platform-modules-embedway/es6220/scripts/es6220_platform.sh new file mode 100755 index 000000000000..3f6990dc46d9 --- /dev/null +++ b/platform/centec/sonic-platform-modules-embedway/es6220/scripts/es6220_platform.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +#platform init script for embedway es6220 + +init_devnum() { + found=0 + for devnum in 0 1; do + devname=`cat /sys/bus/i2c/devices/i2c-${devnum}/name` + # I801 adapter can be at either dffd0000 or dfff0000 + if [[ $devname == 'SMBus I801 adapter at '* ]]; then + found=1 + break + fi + done + + [ $found -eq 0 ] && echo "cannot find I801" && exit 1 +} + +init_devnum + +if [ "$1" == "init" ]; then + #install drivers and dependencies + depmod -a + modprobe dal + +elif [ "$1" == "deinit" ]; then + modprobe -r dal +else + echo "e582-48x2q4z_platform : Invalid option !" +fi diff --git a/platform/centec/sonic-platform-modules-embedway/es6220/scripts/remove_syslog.sh b/platform/centec/sonic-platform-modules-embedway/es6220/scripts/remove_syslog.sh new file mode 100755 index 000000000000..1366ffbdd819 --- /dev/null +++ b/platform/centec/sonic-platform-modules-embedway/es6220/scripts/remove_syslog.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +#remove syslog + +sudo find /var/log/ -mtime +7 -name "syslog.*" | sudo xargs rm -rf + +#echo "remove_syslog.sh crontab is running" >> /home/admin/shell.txt + +exit 0 diff --git a/platform/centec/sonic-platform-modules-embedway/es6220/service/es6220_platform.service b/platform/centec/sonic-platform-modules-embedway/es6220/service/es6220_platform.service new file mode 100644 index 000000000000..111ed4952649 --- /dev/null +++ b/platform/centec/sonic-platform-modules-embedway/es6220/service/es6220_platform.service @@ -0,0 +1,13 @@ +[Unit] +Description=embedway es6220 platform modules +After=local-fs.target +Before=pmon.service + +[Service] +Type=oneshot +ExecStart=-/etc/init.d/platform-modules-embedway-es6220 start +ExecStop=-/etc/init.d/platform-modules-embedway-es6220 stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/generic/rules.mk b/platform/generic/rules.mk index bc2507740277..c836c1faec1a 100644 --- a/platform/generic/rules.mk +++ b/platform/generic/rules.mk @@ -2,8 +2,8 @@ include $(PLATFORM_PATH)/aboot-image.mk include $(PLATFORM_PATH)/onie-image.mk SONIC_ALL += $(DOCKER_DATABASE) \ - $(DOCKER_LLDP_SV2) \ - $(DOCKER_SNMP_SV2) \ + $(DOCKER_SNMP) \ + $(DOCKER_LLDP) \ $(DOCKER_PLATFORM_MONITOR) \ $(DOCKER_DHCP_RELAY) \ $(DOCKER_PTF) \ diff --git a/platform/innovium/docker-ptf-invm.mk b/platform/innovium/docker-ptf-invm.mk deleted file mode 100755 index 6c81734676fd..000000000000 --- a/platform/innovium/docker-ptf-invm.mk +++ /dev/null @@ -1,7 +0,0 @@ -# docker image for docker-ptf-invm - -DOCKER_PTF_INVM = docker-ptf-invm.gz -$(DOCKER_PTF_INVM)_PATH = $(DOCKERS_PATH)/docker-ptf-saithrift -$(DOCKER_PTF_INVM)_DEPENDS += $(PYTHON_SAITHRIFT_INVM) -$(DOCKER_PTF_INVM)_LOAD_DOCKERS += $(DOCKER_PTF) -SONIC_DOCKER_IMAGES += $(DOCKER_PTF_INVM) 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/innovium/docker-syncd-invm-rpc/Dockerfile.j2 b/platform/innovium/docker-syncd-invm-rpc/Dockerfile.j2 index af31d587b90a..eea52e3398b8 100755 --- a/platform/innovium/docker-syncd-invm-rpc/Dockerfile.j2 +++ b/platform/innovium/docker-syncd-invm-rpc/Dockerfile.j2 @@ -11,11 +11,6 @@ debs/ RUN dpkg -P syncd -RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; } ; \ -{% for deb in docker_syncd_invm_rpc_debs.split(' ') -%} -dpkg_apt debs/{{ deb }}{{'; '}} -{%- endfor %} - ## Pre-install the fundamental packages RUN apt-get update \ && apt-get -y install \ @@ -29,7 +24,16 @@ RUN apt-get update \ libjansson4 \ wget \ cmake \ - && wget https://github.com/nanomsg/nanomsg/archive/1.0.0.tar.gz \ + libqt5core5a \ + libqt5network5 \ + libboost-atomic1.71.0 + +RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; } ; \ +{% for deb in docker_syncd_invm_rpc_debs.split(' ') -%} +dpkg_apt debs/{{ deb }}{{'; '}} +{%- endfor %} + +RUN wget https://github.com/nanomsg/nanomsg/archive/1.0.0.tar.gz \ && tar xvfz 1.0.0.tar.gz \ && cd nanomsg-1.0.0 \ && mkdir -p build \ @@ -50,4 +54,4 @@ RUN apt-get update \ COPY ["ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/innovium/docker-syncd-invm.mk b/platform/innovium/docker-syncd-invm.mk index 3ba35c5edb97..52c11b90911d 100755 --- a/platform/innovium/docker-syncd-invm.mk +++ b/platform/innovium/docker-syncd-invm.mk @@ -10,4 +10,7 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSAIMETADATA_DBG) \ $(LIBSAIREDIS_DBG) +SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_BASE) +SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_SYNCD_BASE_DBG) + $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot diff --git a/platform/innovium/docker-syncd-invm/Dockerfile.j2 b/platform/innovium/docker-syncd-invm/Dockerfile.j2 index 6f6f5eca9b60..ab4be823de66 100755 --- a/platform/innovium/docker-syncd-invm/Dockerfile.j2 +++ b/platform/innovium/docker-syncd-invm/Dockerfile.j2 @@ -24,11 +24,10 @@ RUN dpkg -i \ debs/{{ deb }}{{' '}} {%- endfor %} -COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] ## Clean up RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/innovium/docker-syncd-invm/start.sh b/platform/innovium/docker-syncd-invm/start.sh deleted file mode 100755 index 623316050475..000000000000 --- a/platform/innovium/docker-syncd-invm/start.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -rm -f /var/run/rsyslogd.pid - -supervisorctl start rsyslogd - -supervisorctl start syncd diff --git a/platform/innovium/docker-syncd-invm/supervisord.conf b/platform/innovium/docker-syncd-invm/supervisord.conf index 1af5d70a1d0c..ffdb5fd85c47 100755 --- a/platform/innovium/docker-syncd-invm/supervisord.conf +++ b/platform/innovium/docker-syncd-invm/supervisord.conf @@ -3,26 +3,30 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true -[program:start.sh] -command=/usr/bin/start.sh -priority=1 +[eventlistener:dependent-startup] +command=python2 -m supervisord_dependent_startup autostart=true -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE +buffer_size=25 [program:rsyslogd] -command=/usr/sbin/rsyslogd -n -priority=2 +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true [program:syncd] command=/usr/bin/syncd_start.sh -priority=3 +priority=2 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running diff --git a/platform/innovium/invm-sai.mk b/platform/innovium/invm-sai.mk index 8c236a8b68d2..25e490e44f83 100755 --- a/platform/innovium/invm-sai.mk +++ b/platform/innovium/invm-sai.mk @@ -10,5 +10,6 @@ $(INVM_LIBSAI)_URL = $(INVM_SAI_ONLINE)/$(INVM_LIBSAI) $(INVM_HSAI)_URL = $(INVM_SAI_ONLINE)/$(INVM_HSAI) $(INVM_DRV)_URL = $(INVM_SAI_ONLINE)/$(INVM_DRV) +$(eval $(call add_conflict_package,$(INVM_HSAI),$(LIBSAIVS_DEV))) + SONIC_ONLINE_DEBS += $(INVM_LIBSAI) $(INVM_HSAI) $(INVM_DRV) -SONIC_STRETCH_DEBS += $(INVM_DRV) diff --git a/platform/innovium/platform-modules-cel.mk b/platform/innovium/platform-modules-cel.mk index b93bea758d71..4b394c36ec88 100755 --- a/platform/innovium/platform-modules-cel.mk +++ b/platform/innovium/platform-modules-cel.mk @@ -9,4 +9,3 @@ $(CEL_MIDSTONE_200I_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform- $(CEL_MIDSTONE_200I_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) $(CEL_MIDSTONE_200I_PLATFORM_MODULE)_PLATFORM = x86_64-cel_midstone-r0 SONIC_DPKG_DEBS += $(CEL_MIDSTONE_200I_PLATFORM_MODULE) -SONIC_STRETCH_DEBS+= $(CEL_MIDSTONE_200I_PLATFORM_MODULE) diff --git a/platform/innovium/platform-modules-delta.mk b/platform/innovium/platform-modules-delta.mk index 68e13fb8a8a4..6a6dc45763eb 100644 --- a/platform/innovium/platform-modules-delta.mk +++ b/platform/innovium/platform-modules-delta.mk @@ -10,4 +10,3 @@ $(DELTA_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) $(DELTA_PLATFORM_MODULE)_PLATFORM = x86_64-delta_et-c032if-r0 SONIC_DPKG_DEBS += $(DELTA_PLATFORM_MODULE) -SONIC_STRETCH_DEBS += $(DELTA_PLATFORM_MODULE) diff --git a/platform/innovium/rules.mk b/platform/innovium/rules.mk index 68a9dbb41040..ea23466ad578 100755 --- a/platform/innovium/rules.mk +++ b/platform/innovium/rules.mk @@ -6,15 +6,15 @@ include $(PLATFORM_PATH)/docker-syncd-invm-rpc.mk include $(PLATFORM_PATH)/one-image.mk include $(PLATFORM_PATH)/libsaithrift-dev.mk include $(PLATFORM_PATH)/python-saithrift.mk -include $(PLATFORM_PATH)/docker-ptf-invm.mk SONIC_ALL += $(SONIC_INVM_ONE_IMAGE) \ $(DOCKER_FPM) \ $(DOCKER_PTF_INVM) \ $(DOCKER_SYNCD_INVM_RPC) -# Inject invm sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(INVM_HSAI) $(INVM_LIBSAI) $(LIBSAITHRIFT_DEV_INVM) +# Inject invm sai into syncd +$(SYNCD)_DEPENDS += $(INVM_HSAI) $(INVM_LIBSAI) $(LIBSAITHRIFT_DEV_INVM) +$(SYNCD)_UNINSTALLS += $(INVM_HSAI) # Runtime dependency on invm sai is set only for syncd $(SYNCD)_RDEPENDS += $(INVM_HSAI) diff --git a/platform/innovium/sonic-platform-modules-cel/debian/control b/platform/innovium/sonic-platform-modules-cel/debian/control index 543d381ab6f7..374f1f75d3aa 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-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned 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 3fe3ffc9f526..bcfea2d42f1f 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-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/innovium/sonic-platform-modules-delta/et-c032if/modules/delta_et-c032if_platform.c b/platform/innovium/sonic-platform-modules-delta/et-c032if/modules/delta_et-c032if_platform.c index d4e23a166e88..2e9db4278294 100644 --- a/platform/innovium/sonic-platform-modules-delta/et-c032if/modules/delta_et-c032if_platform.c +++ b/platform/innovium/sonic-platform-modules-delta/et-c032if/modules/delta_et-c032if_platform.c @@ -9,9 +9,9 @@ #include #include #include -#include +#include #include -#include +#include #include #include #include diff --git a/platform/marvell-arm64/docker-ptf-mrvl.mk b/platform/marvell-arm64/docker-ptf-mrvl.mk deleted file mode 100644 index 69dff4a90dd4..000000000000 --- a/platform/marvell-arm64/docker-ptf-mrvl.mk +++ /dev/null @@ -1,7 +0,0 @@ -# docker image for docker-ptf-mrvl - -DOCKER_PTF_MRVL = docker-ptf-mrvl.gz -$(DOCKER_PTF_MRVL)_PATH = $(DOCKERS_PATH)/docker-ptf-saithrift -$(DOCKER_PTF_MRVL)_DEPENDS += $(PYTHON_SAITHRIFT) -$(DOCKER_PTF_MRVL)_LOAD_DOCKERS += $(DOCKER_PTF) -SONIC_DOCKER_IMAGES += $(DOCKER_PTF_MRVL) diff --git a/platform/marvell-arm64/docker-saiserver-mrvl.mk b/platform/marvell-arm64/docker-saiserver-mrvl.mk index 07dac2a4610d..a449e3e83e45 100644 --- a/platform/marvell-arm64/docker-saiserver-mrvl.mk +++ b/platform/marvell-arm64/docker-saiserver-mrvl.mk @@ -5,6 +5,7 @@ $(DOCKER_SAISERVER_MRVL)_PATH = $(PLATFORM_PATH)/docker-saiserver-mrvl $(DOCKER_SAISERVER_MRVL)_DEPENDS += $(SAISERVER) $(DOCKER_SAISERVER_MRVL)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) SONIC_DOCKER_IMAGES += $(DOCKER_SAISERVER_MRVL) +SONIC_STRETCH_DOCKERS += $(DOCKER_SAISERVER_MRVL) $(DOCKER_SAISERVER_MRVL)_CONTAINER_NAME = saiserver $(DOCKER_SAISERVER_MRVL)_RUN_OPT += --net=host --privileged -t 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-arm64/docker-syncd-mrvl-rpc/Dockerfile.j2 b/platform/marvell-arm64/docker-syncd-mrvl-rpc/Dockerfile.j2 index cea067d2abf6..118be5e1c5f2 100644 --- a/platform/marvell-arm64/docker-syncd-mrvl-rpc/Dockerfile.j2 +++ b/platform/marvell-arm64/docker-syncd-mrvl-rpc/Dockerfile.j2 @@ -11,11 +11,6 @@ debs/ RUN apt-get purge -y syncd -RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; } ; \ -{% for deb in docker_syncd_mrvl_rpc_debs.split(' ') -%} -dpkg_apt debs/{{ deb }}{{'; '}} -{%- endfor %} - ## Pre-install the fundamental packages RUN apt-get update \ && apt-get -y install \ @@ -27,7 +22,16 @@ RUN apt-get update \ python-dev \ wget \ cmake \ - && wget https://github.com/nanomsg/nanomsg/archive/1.0.0.tar.gz \ + libqt5core5a \ + libqt5network5 \ + libboost-atomic1.71.0 + +RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; } ; \ +{% for deb in docker_syncd_mrvl_rpc_debs.split(' ') -%} +dpkg_apt debs/{{ deb }}{{'; '}} +{%- endfor %} + +RUN wget https://github.com/nanomsg/nanomsg/archive/1.0.0.tar.gz \ && tar xvfz 1.0.0.tar.gz \ && cd nanomsg-1.0.0 \ && mkdir -p build \ @@ -48,4 +52,4 @@ RUN apt-get update \ COPY ["ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/marvell-arm64/docker-syncd-mrvl.mk b/platform/marvell-arm64/docker-syncd-mrvl.mk index 841e3b4b165f..dd01caab687b 100644 --- a/platform/marvell-arm64/docker-syncd-mrvl.mk +++ b/platform/marvell-arm64/docker-syncd-mrvl.mk @@ -10,5 +10,8 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSAIMETADATA_DBG) \ $(LIBSAIREDIS_DBG) +SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_BASE) +SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_SYNCD_BASE_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/Dockerfile.j2 b/platform/marvell-arm64/docker-syncd-mrvl/Dockerfile.j2 index 410911e6a4f8..afaac3fd056c 100755 --- a/platform/marvell-arm64/docker-syncd-mrvl/Dockerfile.j2 +++ b/platform/marvell-arm64/docker-syncd-mrvl/Dockerfile.j2 @@ -26,13 +26,12 @@ RUN dpkg -i \ debs/{{ deb }}{{' '}} {%- endfor %} -COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] -COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin/"] COPY ["critical_processes", "/etc/supervisor/"] ## Clean up RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] 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 3079618990ed..61e290e3189e 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" - if does not exist for 5 times within 5 cycles then alert +check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/platform/marvell-arm64/docker-syncd-mrvl/critical_processes b/platform/marvell-arm64/docker-syncd-mrvl/critical_processes index 6082f242b872..bdd6903c5690 100644 --- a/platform/marvell-arm64/docker-syncd-mrvl/critical_processes +++ b/platform/marvell-arm64/docker-syncd-mrvl/critical_processes @@ -1 +1 @@ -syncd +program:syncd diff --git a/platform/marvell-arm64/docker-syncd-mrvl/start.sh b/platform/marvell-arm64/docker-syncd-mrvl/start.sh deleted file mode 100755 index 623316050475..000000000000 --- a/platform/marvell-arm64/docker-syncd-mrvl/start.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -rm -f /var/run/rsyslogd.pid - -supervisorctl start rsyslogd - -supervisorctl start syncd diff --git a/platform/marvell-arm64/docker-syncd-mrvl/supervisord.conf b/platform/marvell-arm64/docker-syncd-mrvl/supervisord.conf index b11e045fac7e..10f406129d9c 100644 --- a/platform/marvell-arm64/docker-syncd-mrvl/supervisord.conf +++ b/platform/marvell-arm64/docker-syncd-mrvl/supervisord.conf @@ -3,27 +3,29 @@ 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 +[eventlistener:dependent-startup] +command=python2 -m supervisord_dependent_startup autostart=true autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE +buffer_size=25 -[program:start.sh] -command=/usr/bin/start.sh -priority=1 +[eventlistener:supervisor-proc-exit-listener] +command=python2 /usr/bin/supervisor-proc-exit-listener --container-name syncd +events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING autostart=true -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog +autorestart=unexpected [program:rsyslogd] -command=/usr/sbin/rsyslogd -n -priority=2 +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true [program:syncd] command=/usr/bin/syncd_start.sh @@ -32,3 +34,5 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running diff --git a/platform/marvell-arm64/linux-kernel-arm64.mk b/platform/marvell-arm64/linux-kernel-arm64.mk index 2c5438db982d..a953c908234c 100644 --- a/platform/marvell-arm64/linux-kernel-arm64.mk +++ b/platform/marvell-arm64/linux-kernel-arm64.mk @@ -4,4 +4,3 @@ LINUX_KERNEL_DTB = linux-image-4.9.168-arm64.deb $(LINUX_KERNEL_DTB)_URL = https://github.com/Marvell-switching/sonic-marvell-binaries/raw/master/arm64/kernel/$(LINUX_KERNEL_DTB) SONIC_ONLINE_DEBS += $(LINUX_KERNEL_DTB) -SONIC_STRETCH_DEBS += $(LINUX_KERNEL_DTB) diff --git a/platform/marvell-arm64/rules.mk b/platform/marvell-arm64/rules.mk index bf4667a46d41..f8e4c12a49ff 100644 --- a/platform/marvell-arm64/rules.mk +++ b/platform/marvell-arm64/rules.mk @@ -4,10 +4,9 @@ include $(PLATFORM_PATH)/docker-syncd-mrvl.mk include $(PLATFORM_PATH)/docker-syncd-mrvl-rpc.mk include $(PLATFORM_PATH)/docker-saiserver-mrvl.mk include $(PLATFORM_PATH)/libsaithrift-dev.mk -include $(PLATFORM_PATH)/docker-ptf-mrvl.mk include $(PLATFORM_PATH)/one-image.mk include $(PLATFORM_PATH)/linux-kernel-arm64.mk -ENABLE_SYSTEM_TELEMETRY = "" +INCLUDE_SYSTEM_TELEMETRY = "" SONIC_ALL += $(SONIC_ONE_IMAGE) \ @@ -15,10 +14,12 @@ SONIC_ALL += $(SONIC_ONE_IMAGE) \ $(DOCKER_PTF_MRVL) \ $(DOCKER_SYNCD_MRVL_RPC) -# Inject mrvl sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(MRVL_SAI) +# Inject mrvl sai into syncd +$(SYNCD)_DEPENDS += $(MRVL_SAI) +$(SYNCD)_UNINSTALLS += $(MRVL_DEV) + ifeq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV) +$(SYNCD)_DEPENDS += $(LIBSAITHRIFT_DEV) endif # Runtime dependency on mrvl sai is set only for syncd diff --git a/platform/marvell-arm64/sai.mk b/platform/marvell-arm64/sai.mk index ebdd7030a3d4..6cf79472963f 100644 --- a/platform/marvell-arm64/sai.mk +++ b/platform/marvell-arm64/sai.mk @@ -4,4 +4,6 @@ export MRVL_SAI_VERSION = 1.5.1 export MRVL_SAI = mrvllibsai_$(PLATFORM_ARCH)_$(MRVL_SAI_VERSION).deb $(MRVL_SAI)_SRC_PATH = $(PLATFORM_PATH)/sai +$(eval $(call add_conflict_package,$(MRVL_SAI),$(LIBSAIVS_DEV))) + SONIC_MAKE_DEBS += $(MRVL_SAI) diff --git a/platform/marvell-arm64/sonic_fit.its b/platform/marvell-arm64/sonic_fit.its new file mode 100644 index 000000000000..9b09d4cd3d4c --- /dev/null +++ b/platform/marvell-arm64/sonic_fit.its @@ -0,0 +1,55 @@ +/dts-v1/; + +/ { + description = "U-Boot fitImage for SONIC Marvell Arm64"; + #address-cells = <1>; + + images { + kernel@0 { + description = "Linux Kernel"; + data = /incbin/("/boot/vmlinuz-4.9.0-9-2-arm64"); + type = "kernel"; + arch = "arm64"; + os = "linux"; + compression = "none"; + load = <0x6000000>; + entry = <0x6000000>; + hash@1 { + algo = "sha1"; + }; + }; + fdt@0 { + description = "Flattened Device Tree blob"; + data = /incbin/("/boot/armada-7020-comexpress.dtb"); + type = "flat_dt"; + arch = "arm64"; + compression = "none"; + hash@1 { + algo = "sha1"; + }; + }; + ramdisk@0 { + description = "ramdisk"; + data = /incbin/("/boot/initrd.img-4.9.0-9-2-arm64"); + type = "ramdisk"; + arch = "arm64"; + os = "linux"; + compression = "gzip"; + hash@1 { + algo = "sha1"; + }; + }; + }; + configurations { + default = "conf@1"; + conf@1 { + description = "Boot Linux kernel with FDT blob + ramdisk"; + kernel = "kernel@0"; + fdt = "fdt@0"; + ramdisk = "ramdisk@0"; + hash@1 { + algo = "sha1"; + }; + }; + }; +}; diff --git a/platform/marvell-armhf/docker-ptf-mrvl.mk b/platform/marvell-armhf/docker-ptf-mrvl.mk deleted file mode 100644 index 69dff4a90dd4..000000000000 --- a/platform/marvell-armhf/docker-ptf-mrvl.mk +++ /dev/null @@ -1,7 +0,0 @@ -# docker image for docker-ptf-mrvl - -DOCKER_PTF_MRVL = docker-ptf-mrvl.gz -$(DOCKER_PTF_MRVL)_PATH = $(DOCKERS_PATH)/docker-ptf-saithrift -$(DOCKER_PTF_MRVL)_DEPENDS += $(PYTHON_SAITHRIFT) -$(DOCKER_PTF_MRVL)_LOAD_DOCKERS += $(DOCKER_PTF) -SONIC_DOCKER_IMAGES += $(DOCKER_PTF_MRVL) diff --git a/platform/marvell-armhf/docker-saiserver-mrvl.mk b/platform/marvell-armhf/docker-saiserver-mrvl.mk index 398902961da8..8720e3364688 100644 --- a/platform/marvell-armhf/docker-saiserver-mrvl.mk +++ b/platform/marvell-armhf/docker-saiserver-mrvl.mk @@ -6,6 +6,7 @@ $(DOCKER_SAISERVER_MRVL)_DEPENDS += $(SAISERVER) $(DOCKER_SAISERVER_MRVL)_FILES += $(DSSERVE) $(BCMCMD) $(DOCKER_SAISERVER_MRVL)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) SONIC_DOCKER_IMAGES += $(DOCKER_SAISERVER_MRVL) +SONIC_STRETCH_DOCKERS += $(DOCKER_SAISERVER_MRVL) $(DOCKER_SAISERVER_MRVL)_CONTAINER_NAME = saiserver $(DOCKER_SAISERVER_MRVL)_RUN_OPT += --net=host --privileged -t 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-armhf/docker-syncd-mrvl-rpc/Dockerfile.j2 b/platform/marvell-armhf/docker-syncd-mrvl-rpc/Dockerfile.j2 index cea067d2abf6..118be5e1c5f2 100644 --- a/platform/marvell-armhf/docker-syncd-mrvl-rpc/Dockerfile.j2 +++ b/platform/marvell-armhf/docker-syncd-mrvl-rpc/Dockerfile.j2 @@ -11,11 +11,6 @@ debs/ RUN apt-get purge -y syncd -RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; } ; \ -{% for deb in docker_syncd_mrvl_rpc_debs.split(' ') -%} -dpkg_apt debs/{{ deb }}{{'; '}} -{%- endfor %} - ## Pre-install the fundamental packages RUN apt-get update \ && apt-get -y install \ @@ -27,7 +22,16 @@ RUN apt-get update \ python-dev \ wget \ cmake \ - && wget https://github.com/nanomsg/nanomsg/archive/1.0.0.tar.gz \ + libqt5core5a \ + libqt5network5 \ + libboost-atomic1.71.0 + +RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; } ; \ +{% for deb in docker_syncd_mrvl_rpc_debs.split(' ') -%} +dpkg_apt debs/{{ deb }}{{'; '}} +{%- endfor %} + +RUN wget https://github.com/nanomsg/nanomsg/archive/1.0.0.tar.gz \ && tar xvfz 1.0.0.tar.gz \ && cd nanomsg-1.0.0 \ && mkdir -p build \ @@ -48,4 +52,4 @@ RUN apt-get update \ COPY ["ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/marvell-armhf/docker-syncd-mrvl.mk b/platform/marvell-armhf/docker-syncd-mrvl.mk index 841e3b4b165f..dd01caab687b 100644 --- a/platform/marvell-armhf/docker-syncd-mrvl.mk +++ b/platform/marvell-armhf/docker-syncd-mrvl.mk @@ -10,5 +10,8 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSAIMETADATA_DBG) \ $(LIBSAIREDIS_DBG) +SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_BASE) +SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_SYNCD_BASE_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/Dockerfile.j2 b/platform/marvell-armhf/docker-syncd-mrvl/Dockerfile.j2 index 410911e6a4f8..afaac3fd056c 100755 --- a/platform/marvell-armhf/docker-syncd-mrvl/Dockerfile.j2 +++ b/platform/marvell-armhf/docker-syncd-mrvl/Dockerfile.j2 @@ -26,13 +26,12 @@ RUN dpkg -i \ debs/{{ deb }}{{' '}} {%- endfor %} -COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] -COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin/"] COPY ["critical_processes", "/etc/supervisor/"] ## Clean up RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] 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 3079618990ed..61e290e3189e 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" - if does not exist for 5 times within 5 cycles then alert +check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/platform/marvell-armhf/docker-syncd-mrvl/critical_processes b/platform/marvell-armhf/docker-syncd-mrvl/critical_processes index 6082f242b872..bdd6903c5690 100644 --- a/platform/marvell-armhf/docker-syncd-mrvl/critical_processes +++ b/platform/marvell-armhf/docker-syncd-mrvl/critical_processes @@ -1 +1 @@ -syncd +program:syncd diff --git a/platform/marvell-armhf/docker-syncd-mrvl/start.sh b/platform/marvell-armhf/docker-syncd-mrvl/start.sh deleted file mode 100755 index 623316050475..000000000000 --- a/platform/marvell-armhf/docker-syncd-mrvl/start.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -rm -f /var/run/rsyslogd.pid - -supervisorctl start rsyslogd - -supervisorctl start syncd diff --git a/platform/marvell-armhf/docker-syncd-mrvl/supervisord.conf b/platform/marvell-armhf/docker-syncd-mrvl/supervisord.conf index b11e045fac7e..e633b4fe115c 100644 --- a/platform/marvell-armhf/docker-syncd-mrvl/supervisord.conf +++ b/platform/marvell-armhf/docker-syncd-mrvl/supervisord.conf @@ -3,32 +3,36 @@ 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 +[eventlistener:dependent-startup] +command=python2 -m supervisord_dependent_startup autostart=true autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE +buffer_size=25 -[program:start.sh] -command=/usr/bin/start.sh -priority=1 +[eventlistener:supervisor-proc-exit-listener] +command=python2 /usr/bin/supervisor-proc-exit-listener --container-name syncd +events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING autostart=true -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog +autorestart=unexpected [program:rsyslogd] -command=/usr/sbin/rsyslogd -n -priority=2 +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true [program:syncd] command=/usr/bin/syncd_start.sh -priority=3 +priority=2 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running diff --git a/platform/marvell-armhf/linux-kernel-armhf.mk b/platform/marvell-armhf/linux-kernel-armhf.mk index 4d52beac49d9..ac7aa3faf19a 100644 --- a/platform/marvell-armhf/linux-kernel-armhf.mk +++ b/platform/marvell-armhf/linux-kernel-armhf.mk @@ -4,4 +4,3 @@ 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/marvell-armhf/one-image.mk b/platform/marvell-armhf/one-image.mk index 000ac9ea3e18..44bcd9595281 100644 --- a/platform/marvell-armhf/one-image.mk +++ b/platform/marvell-armhf/one-image.mk @@ -5,7 +5,8 @@ $(SONIC_ONE_IMAGE)_MACHINE = marvell-armhf $(SONIC_ONE_IMAGE)_IMAGE_TYPE = onie $(SONIC_ONE_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) $(SONIC_ONE_IMAGE)_INSTALLS += $(LINUX_KERNEL_DTB) -$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(ET6448M_PLATFORM) +$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(ET6448M_PLATFORM) \ + $(NOKIA_7215_PLATFORM) 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/marvell-armhf/platform-et6448m.mk b/platform/marvell-armhf/platform-et6448m.mk index eeef04a20ae7..1f0ee201cc76 100644 --- a/platform/marvell-armhf/platform-et6448m.mk +++ b/platform/marvell-armhf/platform-et6448m.mk @@ -6,4 +6,3 @@ $(ET6448M_PLATFORM)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-et6448m $(ET6448M_PLATFORM)_PLATFORM = armhf-marvell_et6448m_52x-r0 SONIC_DPKG_DEBS += $(ET6448M_PLATFORM) -SONIC_STRETCH_DEBS += $(ET6448M_PLATFORM) diff --git a/platform/marvell-armhf/platform-nokia.mk b/platform/marvell-armhf/platform-nokia.mk new file mode 100644 index 000000000000..7e7df9cb13cc --- /dev/null +++ b/platform/marvell-armhf/platform-nokia.mk @@ -0,0 +1,11 @@ +# Nokia Platform + +NOKIA_7215_PLATFORM_VERSION = 1.0 +export NOKIA_7215_PLATFORM_VERSION + +NOKIA_7215_PLATFORM = sonic-platform-nokia-7215_$(NOKIA_7215_PLATFORM_VERSION)_$(CONFIGURED_ARCH).deb +$(NOKIA_7215_PLATFORM)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-nokia +$(NOKIA_7215_PLATFORM)_PLATFORM = armhf-nokia_ixs7215_52x-r0 +SONIC_DPKG_DEBS += $(NOKIA_7215_PLATFORM) + +SONIC_STRETCH_DEBS += $(NOKIA_7215_PLATFORM) diff --git a/platform/marvell-armhf/platform.conf b/platform/marvell-armhf/platform.conf index 7799b33d57d9..78f64b6fbe18 100644 --- a/platform/marvell-armhf/platform.conf +++ b/platform/marvell-armhf/platform.conf @@ -10,28 +10,60 @@ fdt_addr=0x1000000 initrd_addr=0x2000000 VAR_LOG=512 -kernel_fname="/boot/vmlinuz-4.9.0-9-2-armmp" -initrd_fname="/boot/initrd.img-4.9.0-9-2-armmp" +kernel_fname="/boot/vmlinuz-4.19.0-12-2-armmp" +initrd_fname="/boot/initrd.img-4.19.0-12-2-armmp" fdt_fname="/boot/armada-385-ET6448M_4G_Nand.dtb" +if [ "$install_env" = "onie" ]; then + MACH_FILE="/etc/machine.conf" +else + MACH_FILE="/host/machine.conf" +fi +# armhf-marvell_et6448m_52x-r0 - Platform = Et6448M +# armhf-nokia_ixs7215_52x-r0 - Platform = Nokia IPD6448M +PLATFORM=`sed -n 's/^onie_platform=\(.*\)/\1/p' $MACH_FILE` +echo "Intalling SONiC from $install_env on Platform $PLATFORM" + # global mount defines -demo_dev=ubi0 -mtd_dev=/dev/$(cat /proc/mtd | grep "SONIC" | grep -o "mtd[0-9]") -mtd_num=$(echo $mtd_dev | grep -o "[0-9]") +if [ "$PLATFORM" = "armhf-marvell_et6448m_52x-r0" ]; then + demo_dev=ubi0 + mtd_dev=/dev/$(cat /proc/mtd | grep "SONIC" | grep -o "mtd[0-9]") + mtd_num=$(echo $mtd_dev | grep -o "[0-9]") + + fdt_fname="/boot/armada-385-ET6448M_4G_Nand.dtb" + + BOOTARGS='setenv bootargs root='$demo_dev' rw rootwait ubi.mtd='$mtd_num' rootfstype=ubifs panic=1 console=ttyS0,115200 ${othbootargs} ${mtdparts} ${linuxargs}' + UBI_LOAD='run ubi_sonic_boot_mount_ubi; ubifsload $kernel_addr $image_name;ubifsload $fdt_addr $fdt_name; ubifsload $initrd_addr $initrd_name' + BOOTARGS_OLD='setenv bootargs root='$demo_dev' rw rootwait ubi.mtd='$mtd_num' rootfstype=ubifs panic=1 console=ttyS0,115200 ${othbootargs} ${mtdparts} ${linuxargs_old}' + UBI_LOAD_OLD='run ubi_sonic_boot_mount_ubi; ubifsload $kernel_addr $image_name_old;ubifsload $fdt_addr $fdt_name_old; ubifsload $initrd_addr $initrd_name_old' + UBIBOOTCMD='run ubi_sonic_boot_bootargs; run ubi_sonic_boot_load; test -n "$boot_once" && setenv boot_once "" && saveenv; bootz $kernel_addr $initrd_addr $fdt_addr' + UBIBOOTCMD_OLD='run ubi_sonic_boot_bootargs_old; run ubi_sonic_boot_load_old; test -n "$boot_once" && setenv boot_once "" && saveenv; bootz $kernel_addr $initrd_addr $fdt_addr' + LINUX_MISC_CMD='apparmor=1 security=apparmor usbcore.autosuspend=-1' + +elif [ "$PLATFORM" = "armhf-nokia_ixs7215_52x-r0" ]; then + demo_dev=sda2 + + fdt_fname="/boot/armada-385-ipd6448m.dtb" + + BOOTARGS='setenv bootargs root=/dev/'$demo_dev' rw rootwait rootfstype=ext4 panic=1 console=ttyS0,115200 ${othbootargs} ${mtdparts} ${linuxargs}' + UBI_LOAD='scsi init; ext4load scsi 0:2 $kernel_addr $image_name; ext4load scsi 0:2 $fdt_addr $fdt_name; ext4load scsi 0:2 $initrd_addr $initrd_name' + BOOTARGS_OLD='setenv bootargs root=/dev/'$demo_dev' rw rootwait rootfstype=ext4 panic=1 console=ttyS0,115200 ${othbootargs} ${mtdparts} ${linuxargs_old}' + UBI_LOAD_OLD='scsi init; ext4load scsi 0:2 $kernel_addr $image_name_old; ext4load scsi 0:2 $fdt_addr $fdt_name_old; ext4load scsi 0:2 $initrd_addr $initrd_name_old' + UBIBOOTCMD='run ubi_sonic_boot_bootargs; run ubi_sonic_boot_load; test -n "$boot_once" && setenv boot_once "" && saveenv; bootz $kernel_addr $initrd_addr $fdt_addr' + UBIBOOTCMD_OLD='run ubi_sonic_boot_bootargs_old; run ubi_sonic_boot_load_old; test -n "$boot_once" && setenv boot_once "" && saveenv; bootz $kernel_addr $initrd_addr $fdt_addr' + LINUX_MISC_CMD='apparmor=1 security=apparmor usbcore.autosuspend=-1' + +else + echo "Unsupported Platform $PLAFORM" + exit 2 +fi demo_mnt=/tmp FW_ENV_DEFAULT='/dev/mtd0 0x00500000 0x80000 0x100000 8' UBOOT_FW_DEFAULT=1 -# Skip VID Header in UBIFS -BOOTARGS='setenv bootargs root='$demo_dev' rw rootwait ubi.mtd='$mtd_num',8192 rootfstype=ubifs panic=1 console=ttyS0,115200 ${othbootargs} ${mtdparts} ${linuxargs}' -UBI_LOAD='run ubi_sonic_boot_mount_ubi; ubifsload $kernel_addr $image_name;ubifsload $fdt_addr $fdt_name; ubifsload $initrd_addr $initrd_name' -BOOTARGS_OLD='setenv bootargs root='$demo_dev' rw rootwait ubi.mtd='$mtd_num',8192 rootfstype=ubifs panic=1 console=ttyS0,115200 ${othbootargs} ${mtdparts} ${linuxargs_old}' -UBI_LOAD_OLD='run ubi_sonic_boot_mount_ubi; ubifsload $kernel_addr $image_name_old;ubifsload $fdt_addr $fdt_name_old; ubifsload $initrd_addr $initrd_name_old' -UBIBOOTCMD='run ubi_sonic_boot_bootargs; run ubi_sonic_boot_load; test -n "$boot_once" && setenv boot_once "" && saveenv; bootz $kernel_addr $initrd_addr $fdt_addr' -UBIBOOTCMD_OLD='run ubi_sonic_boot_bootargs_old; run ubi_sonic_boot_load_old; test -n "$boot_once" && setenv boot_once "" && saveenv; bootz $kernel_addr $initrd_addr $fdt_addr' -LINUX_MISC_CMD='apparmor=1 security=apparmor usbcore.autosuspend=-1' - prepare_boot_menu() { + echo "Sync up cache ..." + sync echo "Setting up U-Boot environment..." DTB_HAS_ENV_BLK=$(grep uboot-env /proc/mtd | sed -e 's/:.*$//') @@ -68,6 +100,12 @@ prepare_boot_menu() { echo $FW_ENV_DEFAULT > /etc/fw_env.config echo "Using pre-configured uboot env" fi + if [ "$PLATFORM" = "armhf-nokia_ixs7215_52x-r0" ]; then + FW_ENV_DEFAULT='/dev/mtd0 0x00100000 0x10000 0x10000' + echo $FW_ENV_DEFAULT > /etc/fw_env.config + echo "Using pre-configured uboot env for armhf-nokia_ixs7215_52x-r0" + fi + image_name=${image_dir}${kernel_fname} initrd_name=${image_dir}${initrd_fname} fdt_name=${image_dir}${fdt_fname} @@ -100,12 +138,16 @@ prepare_boot_menu() { fw_setenv ${FW_ARG} sonic_version_2 $sonic_version_2 > /dev/null BOOT1='echo " > Boot1: $sonic_version_1 - run sonic_image_1";echo;' BOOT2='echo " > Boot2: $sonic_version_2 - run sonic_image_2";echo;' - BOOT3='echo " > Boot3: ONIE - run onie_nand_boot";echo;' + if [ "$PLATFORM" = "armhf-nokia_ixs7215_52x-r0" ]; then + BOOT3='echo " > Boot3: ONIE - run onie_bootcmd";echo;' + else + BOOT3='echo " > Boot3: ONIE - run onie_nand_boot";echo;' + fi BORDER='echo "---------------------------------------------------";echo;' fw_setenv ${FW_ARG} print_menu $BORDER $BOOT1 $BOOT2 $BOOT3 $BORDER > /dev/null - fw_setenv ${FW_ARG} linuxargs "net.ifnames=0 loopfstype=squashfs loop=$image_dir/$FILESYSTEM_SQUASHFS varlog_size=$VAR_LOG" > /dev/null - fw_setenv ${FW_ARG} linuxargs_old "net.ifnames=0 loopfstype=squashfs loop=$image_dir_old/$FILESYSTEM_SQUASHFS varlog_size=$VAR_LOG" > /dev/null + fw_setenv ${FW_ARG} linuxargs "net.ifnames=0 loopfstype=squashfs loop=$image_dir/$FILESYSTEM_SQUASHFS varlog_size=$VAR_LOG loglevel=4" > /dev/null + fw_setenv ${FW_ARG} linuxargs_old "net.ifnames=0 loopfstype=squashfs loop=$image_dir_old/$FILESYSTEM_SQUASHFS varlog_size=$VAR_LOG loglevel=4" > /dev/null # Set boot configs fw_setenv ${FW_ARG} kernel_addr $kernel_addr > /dev/null @@ -118,6 +160,9 @@ prepare_boot_menu() { else fw_setenv ${FW_ARG} mtdparts 'mtdparts=armada-nand:4m(uboot)ro,5m@5m(uboot-env),20m@10m(ONIE),-(SONIC)' > /dev/null fi + if [ "$PLATFORM" = "armhf-nokia_ixs7215_52x-r0" ]; then + fw_setenv ${FW_ARG} mtdparts 'mtdparts=spi0.0:4m(boot),-(spi-rootfs)' > /dev/null + fi fw_setenv ${FW_ARG} ubi_sonic_boot_mount_ubi 'ubi part SONIC; ubifsmount ubi0' > /dev/null fw_setenv ${FW_ARG} ubi_sonic_boot_bootargs $BOOTARGS > /dev/null fw_setenv ${FW_ARG} ubi_sonic_boot_load $UBI_LOAD > /dev/null @@ -149,9 +194,52 @@ create_ubi_partition() { ubimkvol /dev/$demo_dev -N $demo_dev -s 3900MiB } +create_gpt_partition() { + blk_dev="/dev/sda" + demo_part=$(sgdisk -p $blk_dev | grep -e "$demo_volume_label" -e "$legacy_volume_label" | awk '{print $1}') + # ONIE partition size 168MB + onie_part_size=168 + + if [ -z "$demo_part" ] ; then + # Partition Does NOT Exists + echo "SONIC label [$demo_volume_label] is NOT found in Partition" + echo "Proceeding to create partition" + + attr_bitmask="0x0" + + sgdisk --new=${demo_part}::+${onie_part_size}MB \ + --attributes=${demo_part}:=:$attr_bitmask \ + --change-name=${demo_part}:$demo_volume_label $blk_dev \ + || { + echo "Warning: The first trial of creating partition failed, trying the largest aligned available block of sectors on the disk" + begin=$(sgdisk -F $blk_dev) + end=$(sgdisk -E $blk_dev) + sgdisk --new=${demo_part}:$begin:$end \ + --attributes=${demo_part}:=:$attr_bitmask \ + --change-name=${demo_part}:$demo_volume_label $blk_dev + } || { + echo "Error: Unable to create partition $demo_part on $blk_dev" + exit 1 + } + partprobe || true + else + # Partition Exists + echo "Partition exists $demo_part on $blk_dev" + fi + + # Make filesystem + mkfs.ext4 -L $demo_volume_label /dev/$demo_dev +} + create_partition() { # Platform speicific partition - create_ubi_partition + if [ "$PLATFORM" = "armhf-marvell_et6448m_52x-r0" ]; then + echo "Doing UBI partition" + create_ubi_partition + else + echo "Doing GPT partition" + create_gpt_partition + fi } mount_partition() { @@ -162,14 +250,22 @@ mount_partition() { } echo "Mounting $demo_dev on $demo_mnt " - trap_push "${onie_bin} umount /dev/ubi0_0|| true" - mount -t ubifs /dev/ubi0_0 $demo_mnt || { - echo "Failed" - } + if [ "$PLATFORM" = "armhf-marvell_et6448m_52x-r0" ]; then + trap_push "${onie_bin} umount /dev/ubi0_0|| true" + mount -t ubifs /dev/ubi0_0 $demo_mnt || { + echo "mount -t ubifs /dev/ubi0_0 $demo_mnt Failed" + exit 1 + } + else + trap_push "${onie_bin} umount /dev/sda2|| true" + mount -t ext4 /dev/sda2 $demo_mnt || { + echo "mount -t ext4 /dev/sda2 $demo_mnt Failed" + exit 1 + } + fi } bootloader_menu_config() { # Update uboot Environment prepare_boot_menu } - diff --git a/platform/marvell-armhf/rules.mk b/platform/marvell-armhf/rules.mk index 05ca4788069e..58b9654956f3 100644 --- a/platform/marvell-armhf/rules.mk +++ b/platform/marvell-armhf/rules.mk @@ -4,22 +4,24 @@ include $(PLATFORM_PATH)/docker-syncd-mrvl.mk include $(PLATFORM_PATH)/docker-syncd-mrvl-rpc.mk include $(PLATFORM_PATH)/docker-saiserver-mrvl.mk include $(PLATFORM_PATH)/libsaithrift-dev.mk -include $(PLATFORM_PATH)/docker-ptf-mrvl.mk include $(PLATFORM_PATH)/one-image.mk include $(PLATFORM_PATH)/linux-kernel-armhf.mk include $(PLATFORM_PATH)/platform-et6448m.mk +include $(PLATFORM_PATH)/platform-nokia.mk -ENABLE_SYSTEM_TELEMETRY = "" ENABLE_SYNCD_RPC = "" +INCLUDE_MGMT_FRAMEWORK = "" SONIC_ALL += $(SONIC_ONE_IMAGE) \ $(DOCKER_FPM) #$(DOCKER_SYNCD_MRVL_RPC) -# Inject mrvl sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(MRVL_SAI) +# Inject mrvl sai into syncd +$(SYNCD)_DEPENDS += $(MRVL_SAI) +$(SYNCD)_UNINSTALLS += $(MRVL_SAI) + ifeq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV) +$(SYNCD)_DEPENDS += $(LIBSAITHRIFT_DEV) endif # Runtime dependency on mrvl sai is set only for syncd diff --git a/platform/marvell-armhf/sai.mk b/platform/marvell-armhf/sai.mk index ebdd7030a3d4..70aebfb514e3 100644 --- a/platform/marvell-armhf/sai.mk +++ b/platform/marvell-armhf/sai.mk @@ -1,7 +1,9 @@ # Marvell SAI -export MRVL_SAI_VERSION = 1.5.1 -export MRVL_SAI = mrvllibsai_$(PLATFORM_ARCH)_$(MRVL_SAI_VERSION).deb +export MRVL_SAI_VERSION = 1.7.1 +export MRVL_SAI = mrvllibsai_m0_MASTER_$(PLATFORM_ARCH)_$(MRVL_SAI_VERSION).deb $(MRVL_SAI)_SRC_PATH = $(PLATFORM_PATH)/sai +$(eval $(call add_conflict_package,$(MRVL_SAI),$(LIBSAIVS_DEV))) + SONIC_MAKE_DEBS += $(MRVL_SAI) diff --git a/platform/marvell-armhf/sonic-platform-et6448m/debian/install b/platform/marvell-armhf/sonic-platform-et6448m/debian/install index af8265fb38ce..ceb6090c4058 100644 --- a/platform/marvell-armhf/sonic-platform-et6448m/debian/install +++ b/platform/marvell-armhf/sonic-platform-et6448m/debian/install @@ -1 +1,3 @@ et6448m_plt_setup.sh usr/sbin +entropy.py etc/ +inband_mgmt.sh etc/ diff --git a/platform/marvell-armhf/sonic-platform-et6448m/entropy.py b/platform/marvell-armhf/sonic-platform-et6448m/entropy.py new file mode 100644 index 000000000000..338e2ad9bcea --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-et6448m/entropy.py @@ -0,0 +1,19 @@ +#!/usr/bin/python +import fcntl, struct +import time +from os import path + +RNDADDENTROPY=0x40085203 + +def avail(): + with open("/proc/sys/kernel/random/entropy_avail", mode='r') as avail: + return int(avail.read()) + +if path.exists("/proc/sys/kernel/random/entropy_avail"): + while 1: + while avail() < 2048: + with open('/dev/urandom', 'rb') as urnd, open("/dev/random", mode='wb') as rnd: + d = urnd.read(512) + t = struct.pack('ii', 4 * len(d), len(d)) + d + fcntl.ioctl(rnd, RNDADDENTROPY, t) + time.sleep(30) diff --git a/platform/marvell-armhf/sonic-platform-et6448m/et6448m_plt_setup.sh b/platform/marvell-armhf/sonic-platform-et6448m/et6448m_plt_setup.sh index 83a0add5f005..a587b3b17ca5 100755 --- a/platform/marvell-armhf/sonic-platform-et6448m/et6448m_plt_setup.sh +++ b/platform/marvell-armhf/sonic-platform-et6448m/et6448m_plt_setup.sh @@ -52,6 +52,9 @@ main() { fw_uboot_env_cfg et6448m_profile + + python /etc/entropy.py & + /bin/sh /etc/inband_mgmt.sh } main $@ diff --git a/platform/marvell-armhf/sonic-platform-et6448m/inband_mgmt.sh b/platform/marvell-armhf/sonic-platform-et6448m/inband_mgmt.sh new file mode 100644 index 000000000000..3d3d77abeb33 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-et6448m/inband_mgmt.sh @@ -0,0 +1,40 @@ +#!/bin/sh + +#inband_mgmt + +inband_mgmt(){ + +# The intent of this sequence is to ensure 12c bus enumeration order by +# controlling the order in which the various i2c device drivers are +# loaded. Hence the drivers are unloaded and then reloaded in the prescribed +# order. +# NOTE: In the nokia platform the following sequence is performed by the Nokia +# platform service init script and thus should not be performed here + if [ ! -f /host/machine.conf ]; then + exit 0 + fi + grep ^onie_platform /host/machine.conf 2>/dev/null | grep nokia >/dev/null + if [ $? != 0 ]; then + rmmod i2c-dev + rmmod i2c_mux_gpio + rmmod i2c_mv64xxx + modprobe i2c_mv64xxx + modprobe i2c-dev + modprobe i2c_mux_gpio + sleep 60 + fi + while :; do + ip -br link show eth0 2> /dev/null + if [ $? -eq 0 ]; then + ip address show eth0 | grep -qw "inet" 2>/dev/null + if [ $? -ne 0 ]; then + ifconfig eth0 down + systemctl restart networking + fi + sleep 120 + else + sleep 3 + fi + done +} +(inband_mgmt > /dev/null)& diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/scripts/nokia-7215init.sh b/platform/marvell-armhf/sonic-platform-nokia/7215/scripts/nokia-7215init.sh new file mode 100755 index 000000000000..4cad43348e06 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/scripts/nokia-7215init.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +# Platform init script for Nokia IXS 7215 + +# Load required kernel-mode drivers +load_kernel_drivers() { + # Remove modules loaded during Linux init + # FIX-ME: This will be removed in the future when Linux init no longer loads these + rmmod i2c_mux_gpio + rmmod i2c_dev + rmmod i2c_mv64xxx + + # Carefully control the load order here to ensure consistent i2c bus numbering + modprobe i2c_mv64xxx + modprobe i2c_dev + modprobe i2c_mux_gpio + modprobe eeprom +} + + +nokia_7215_profile() +{ + MAC_ADDR=$(sudo decode-syseeprom -m) + sed -i "s/switchMacAddress=.*/switchMacAddress=$MAC_ADDR/g" /usr/share/sonic/device/armhf-nokia_ixs7215_52x-r0/Nokia-7215/profile.ini + echo "Nokia-7215: Updating switch mac address ${MAC_ADDR}" +} + +# - Main entry + +# Install kernel drivers required for i2c bus access +load_kernel_drivers + +# LOGIC to enumerate SFP eeprom devices - send 0x50 to kernel i2c driver - initialize devices +# the mux may be enumerated at number 4 or 5 so we check for the mux and skip if needed + +# Get list of the mux channels +ismux_bus=$(i2cdetect -l|grep mux|cut -f1) + +# Enumerate the SFP eeprom device on each mux channel +for mux in ${ismux_bus} +do + echo optoe2 0x50 > /sys/class/i2c-adapter/${mux}/new_device +done + +# Enumerate system eeprom +echo 24c02 0x53 > /sys/class/i2c-adapter/i2c-0/new_device +sleep 2 +chmod 644 /sys/class/i2c-adapter/i2c-0/0-0053/eeprom + +# Enumerate fan eeprom devices +echo eeprom 0x55 > /sys/class/i2c-adapter/i2c-0/new_device +echo eeprom 0x56 > /sys/class/i2c-adapter/i2c-0/new_device + +# Enumerate psu eeprom devices +echo eeprom 0x51 > /sys/class/i2c-adapter/i2c-1/new_device +echo eeprom 0x52 > /sys/class/i2c-adapter/i2c-1/new_device + +# Enable optical SFP Tx +i2cset -y -m 0x0f 0 0x41 0x5 0x00 + +# Ensure switch is programmed with chassis base MAC addr +nokia_7215_profile + +echo "Nokia-7215 - completed platform init script" +exit 0 diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/service/nokia-7215init.service b/platform/marvell-armhf/sonic-platform-nokia/7215/service/nokia-7215init.service new file mode 100644 index 000000000000..8b17dbc8edc0 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/service/nokia-7215init.service @@ -0,0 +1,14 @@ +[Unit] +Description=Nokia-7215 Platform Service +Before=pmon.service +After=sysinit.target +DefaultDependencies=no + +[Service] +ExecStart=/usr/local/bin/nokia-7215init.sh +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL +#StandardOutput=tty + +[Install] +WantedBy=multi-user.target diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/setup.py b/platform/marvell-armhf/sonic-platform-nokia/7215/setup.py new file mode 100755 index 000000000000..65f4853bec83 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/setup.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +import os +from setuptools import setup +os.listdir + +setup( + name='sonic_platform', + version='1.0', + description='Module to initialize Nokia IXS 7215 platforms', + + packages=['sonic_platform','sonic_platform.test'], + package_dir={'sonic_platform': '7215/sonic_platform'}, +) + diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/__init__.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/__init__.py new file mode 100755 index 000000000000..139597f9cb07 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/__init__.py @@ -0,0 +1,2 @@ + + diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/chassis.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/chassis.py new file mode 100755 index 000000000000..b3ada4c71f9c --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/chassis.py @@ -0,0 +1,386 @@ +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + import os + import sys + import glob + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform.sfp import Sfp + from sonic_platform.eeprom import Eeprom + from sonic_platform.fan import Fan + from .fan_drawer import RealDrawer + from sonic_platform.psu import Psu + from sonic_platform.thermal import Thermal + from sonic_platform.component import Component + from sonic_py_common import logger +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +smbus_present = 1 +try: + import smbus +except ImportError as e: + smbus_present = 0 + +MAX_SELECT_DELAY = 3600 +COPPER_PORT_START = 1 +COPPER_PORT_END = 48 +SFP_PORT_START = 49 +SFP_PORT_END = 52 +PORT_END = 52 + +# Device counts +MAX_7215_FAN_DRAWERS = 2 +MAX_7215_FANS_PER_DRAWER = 1 +MAX_7215_PSU = 2 +MAX_7215_THERMAL = 6 + +# Temp - disable these to help with early debug +MAX_7215_COMPONENT = 2 + +SYSLOG_IDENTIFIER = "chassis" +sonic_logger = logger.Logger(SYSLOG_IDENTIFIER) + + +class Chassis(ChassisBase): + """ + Nokia platform-specific Chassis class + Derived from Dell S6000 platform. + customized for the 7215 platform. + """ + + def __init__(self): + ChassisBase.__init__(self) + self.system_led_supported_color = ['off', 'amber', 'green', 'amber_blink', 'green_blink'] + # Port numbers for SFP List Initialization + self.COPPER_PORT_START = COPPER_PORT_START + self.COPPER_PORT_END = COPPER_PORT_END + self.SFP_PORT_START = SFP_PORT_START + self.SFP_PORT_END = SFP_PORT_END + self.PORT_END = PORT_END + + # for non-sfp ports create dummy objects for copper / non-sfp ports + for index in range(self.COPPER_PORT_START, self.COPPER_PORT_END+1): + sfp_node = Sfp(index, 'COPPER', 'N/A', 'N/A') + self._sfp_list.append(sfp_node) + + # Verify optoe2 driver SFP eeprom devices were enumerated and exist + # then create the sfp nodes + eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" + mux_dev = sorted(glob.glob("/sys/class/i2c-adapter/i2c-0/i2c-[0-9]")) + y = 0 + for index in range(self.SFP_PORT_START, self.SFP_PORT_END+1): + mux_dev_num = mux_dev[y] + port_i2c_map = mux_dev_num[-1] + y = y + 1 + port_eeprom_path = eeprom_path.format(port_i2c_map) + if not os.path.exists(port_eeprom_path): + sonic_logger.log_info("path %s didnt exist" % port_eeprom_path) + sfp_node = Sfp(index, 'SFP', port_eeprom_path, port_i2c_map) + self._sfp_list.append(sfp_node) + self.sfp_event_initialized = False + + # Instantiate system eeprom object + self._eeprom = Eeprom() + + # Construct lists fans, power supplies, thermals & components + drawer_num = MAX_7215_FAN_DRAWERS + fan_num_per_drawer = MAX_7215_FANS_PER_DRAWER + drawer_ctor = RealDrawer + fan_index = 0 + for drawer_index in range(drawer_num): + drawer = drawer_ctor(drawer_index) + self._fan_drawer_list.append(drawer) + for index in range(fan_num_per_drawer): + fan = Fan(fan_index, drawer) + fan_index += 1 + drawer._fan_list.append(fan) + self._fan_list.append(fan) + + for i in range(MAX_7215_PSU): + psu = Psu(i) + self._psu_list.append(psu) + + for i in range(MAX_7215_THERMAL): + thermal = Thermal(i) + self._thermal_list.append(thermal) + + for i in range(MAX_7215_COMPONENT): + component = Component(i) + self._component_list.append(component) + + 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 physical SFP ports in a + chassis starting from 1. + + Returns: + An object dervied from SfpBase representing the specified sfp + """ + sfp = None + + try: + # The index will start from 1 + sfp = self._sfp_list[index-1] + except IndexError: + sys.stderr.write("SFP index {} out of range (1-{})\n".format( + index, len(self._sfp_list))) + return sfp + + def get_name(self): + """ + Retrieves the name of the chassis + Returns: + string: The name of the chassis + """ + return self._eeprom.modelstr() + + def get_presence(self): + """ + Retrieves the presence of the chassis + Returns: + bool: True if chassis is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the chassis + Returns: + string: Model/part number of chassis + """ + return self._eeprom.part_number_str() + + def get_status(self): + """ + Retrieves the operational status of the chassis + Returns: + bool: A boolean value, True if chassis is operating properly + False if not + """ + return True + + def get_base_mac(self): + """ + Retrieves the base MAC address for the chassis + + Returns: + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' + """ + return self._eeprom.base_mac_addr() + + def get_serial(self): + """ + Retrieves the hardware serial number for the chassis + + Returns: + A string containing the hardware serial number for this + chassis. + """ + return self._eeprom.serial_number_str() + + def get_system_eeprom_info(self): + """ + Retrieves the full content of system EEPROM information for the + chassis + + Returns: + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their + corresponding values. + """ + return self._eeprom.system_eeprom_info() + + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + Returns: + A tuple (string, string) where the first element is a string + containing the cause of the previous reboot. This string must be + one of the predefined strings in this class. If the first string + is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used + to pass a description of the reboot cause. + """ + # The ixs7215 CPLD does not have a hardware reboot cause register so + # the hardware portion of reboot cause can't be implemented + + return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) + + def get_change_event(self, timeout=0): + """ + Returns a nested dictionary containing all devices which have + experienced a change at chassis level + + Args: + timeout: Timeout in milliseconds (optional). If timeout == 0, + this method will block until a change is detected. + + Returns: + (bool, dict): + - True if call successful, False if not; + - A nested dictionary where key is a device type, + value is a dictionary with key:value pairs in the format of + {'device_id':'device_event'}, + where device_id is the device ID for this device and + device_event, + status='1' represents device inserted, + status='0' represents device removed. + Ex. {'fan':{'0':'0', '2':'1'}, 'sfp':{'11':'0'}} + indicates that fan 0 has been removed, fan 2 + has been inserted and sfp 11 has been removed. + """ + # Initialize SFP event first + if not self.sfp_event_initialized: + from sonic_platform.sfp_event import sfp_event + self.sfp_event = sfp_event() + self.sfp_event.initialize() + self.MAX_SELECT_EVENT_RETURNED = self.PORT_END + self.sfp_event_initialized = True + + wait_for_ever = (timeout == 0) + port_dict = {} + if wait_for_ever: + # xrcvd will call this monitor loop in the "SYSTEM_READY" state + timeout = MAX_SELECT_DELAY + while True: + status = self.sfp_event.check_sfp_status(port_dict, timeout) + if not port_dict == {}: + break + else: + # At boot up and in "INIT" state call from xrcvd will have timeout + # value return true without change after timeout and will + # transition to "SYSTEM_READY" + status = self.sfp_event.check_sfp_status(port_dict, timeout) + + if status: + return True, {'sfp': port_dict} + else: + return True, {'sfp': {}} + + def get_thermal_manager(self): + from .thermal_manager import ThermalManager + return ThermalManager + + def set_status_led(self, color): + """ + Sets the state of the system LED + + Args: + color: A string representing the color with which to set the + system LED + + Returns: + bool: True if system LED state is set successfully, False if not + """ + if color not in self.system_led_supported_color: + return False + + if (color == 'off'): + value = 0x00 + elif (color == 'amber'): + value = 0x01 + elif (color == 'green'): + value = 0x02 + elif (color == 'amber_blink'): + value = 0x03 + elif (color == 'green_blink'): + value = 0x04 + else: + return False + + # Write sys led + if smbus_present == 0: + sonic_logger.log_warning("PMON LED SET -> smbus present = 0") + else: + bus = smbus.SMBus(0) + DEVICE_ADDRESS = 0x41 + DEVICEREG = 0x7 + bus.write_byte_data(DEVICE_ADDRESS, DEVICEREG, value) + sonic_logger.log_info(" System LED set O.K. ") + return True + + return False + + def get_status_led(self): + """ + Gets the state of the system LED + + Returns: + A string, one of the valid LED color strings which could be vendor + specified. + """ + # Read sys led + if smbus_present == 0: + sonic_logger.log_warning("PMON LED GET -> smbus present = 0") + return False + else: + bus = smbus.SMBus(0) + DEVICE_ADDRESS = 0x41 + DEVICE_REG = 0x7 + value = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + + if value == 0x00: + color = 'off' + elif value == 0x01: + color = 'amber' + elif value == 0x02: + color = 'green' + elif value == 0x03: + color = 'amber_blink' + elif value == 0x04: + color = 'green_blink' + else: + return False + + return color + + def get_watchdog(self): + """ + Retrieves hardware watchdog device on this chassis + + Returns: + An object derived from WatchdogBase representing the hardware + watchdog device + + Note: + We overload this method to ensure that watchdog is only initialized + when it is referenced. Currently, only one daemon can open the + watchdog. To initialize watchdog in the constructor causes multiple + daemon try opening watchdog when loading and constructing a chassis + object and fail. By doing so we can eliminate that risk. + """ + try: + if self._watchdog is None: + from sonic_platform.watchdog import WatchdogImplBase + watchdog_device_path = "/dev/watchdog0" + self._watchdog = WatchdogImplBase(watchdog_device_path) + except Exception as e: + sonic_logger.log_warning(" Fail to load watchdog {}".format(repr(e))) + + return self._watchdog + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. If the agent cannot determine the parent-relative position + for some reason, or if the associated value of entPhysicalContainedIn is '0', then the value '-1' is returned + Returns: + integer: The 1-based relative physical position in parent device or -1 if cannot determine the position + """ + return -1 + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return False diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/component.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/component.py new file mode 100644 index 000000000000..6a5410458df7 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/component.py @@ -0,0 +1,119 @@ +######################################################################## +# NOKIA IXS7215 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Components' (e.g., BIOS, CPLD, FPGA, etc.) available in +# the platform +# +######################################################################## + +try: + import os + import sys + import subprocess + import ntpath + from sonic_platform_base.component_base import ComponentBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +try: + import smbus +except ImportError as e: + smbus_present = 0 + +if sys.version_info[0] < 3: + import commands as cmd +else: + import subprocess as cmd + + +class Component(ComponentBase): + """Nokia platform-specific Component class""" + + CHASSIS_COMPONENTS = [ + ["System-CPLD", "Used for managing SFPs, LEDs, PSUs and FANs "], + ["U-Boot", "Performs initialization during booting"], + ] + + def __init__(self, component_index): + self.index = component_index + self.name = self.CHASSIS_COMPONENTS[self.index][0] + self.description = self.CHASSIS_COMPONENTS[self.index][1] + + def _get_command_result(self, cmdline): + try: + proc = subprocess.Popen(cmdline.split(), stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + result = stdout.rstrip('\n') + except OSError: + result = None + + return result + + def _get_cpld_version(self, cpld_number): + + if smbus_present == 0: + cmdstatus, cpld_version = cmd.getstatusoutput('i2cget -y 0 0x41 0x2') + else: + bus = smbus.SMBus(0) + DEVICE_ADDRESS = 0x41 + DEVICE_REG = 0x2 + cpld_version = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + + return str(int(cpld_version, 16)) + + def get_name(self): + """ + Retrieves the name of the component + + Returns: + A string containing the name of the component + """ + return self.name + + def get_description(self): + """ + Retrieves the description of the component + + Returns: + A string containing the description of the component + """ + return self.description + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + if self.index == 0: + return self._get_cpld_version(self.index) + + if self.index == 1: + cmdstatus, uboot_version = cmd.getstatusoutput('grep --null-data U-Boot /dev/mtd0ro|head -1 | cut -c 1-30') + return uboot_version + + 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 + """ + image_name = ntpath.basename(image_path) + print(" ixs7215 - install cpld {}".format(image_name)) + + # check whether the image file exists + if not os.path.isfile(image_path): + print("ERROR: the cpld image {} doesn't exist ".format(image_path)) + return False + + success_flag = False + + return success_flag diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/eeprom.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/eeprom.py new file mode 100644 index 000000000000..cefcedaedf12 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/eeprom.py @@ -0,0 +1,233 @@ +######################################################################## +# Nokia IXR7220_D1 +# +# Module contains platform specific implementation of SONiC Platform +# Base API and provides the EEPROMs' information. +# +# The different EEPROMs available are as follows: +# - System EEPROM : Contains Serial number, Service tag, Base MA +# address, etc. in ONIE TlvInfo EEPROM format. +# - PSU EEPROM : Contains Serial number, Part number, Service Tag, +# PSU type, Revision. +# - Fan EEPROM : Contains Serial number, Part number, Service Tag, +# Fan type, Number of Fans in Fantray, Revision. +######################################################################## + + +try: + from sonic_platform_base.sonic_eeprom.eeprom_base import EepromDecoder + from sonic_platform_base.sonic_eeprom.eeprom_tlvinfo import TlvInfoDecoder +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +# PSU eeprom fields in format required by EepromDecoder +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), ('Redundant copy', 's', 83), ('PSU Type', 's', 1), + ('Fab Rev', 's', 2) + ] + +# Fan eeprom fields in format required by EepromDecoder +fan_eeprom_format = [ + ('Model', 's', 12), ('Serial Number', 's', 13) + ] + + +class Eeprom(TlvInfoDecoder): + """Nokia platform-specific EEPROM class""" + + I2C_DIR = "/sys/class/i2c-adapter/" + + def __init__(self, is_psu=False, psu_index=0, is_fan=False, fan_index=0): + self.is_psu_eeprom = is_psu + self.is_fan_eeprom = is_fan + self.is_sys_eeprom = not (is_psu | is_fan) + + if self.is_sys_eeprom: + self.start_offset = 0 + self.eeprom_path = self.I2C_DIR + "i2c-0/0-0053/eeprom" + # System EEPROM is in ONIE TlvInfo EEPROM format + super(Eeprom, self).__init__(self.eeprom_path, + self.start_offset, '', True) + self._load_system_eeprom() + else: + if self.is_psu_eeprom: + self.index = psu_index + self.start_offset = 6 + self.eeprom_path = self.I2C_DIR \ + + "i2c-1/1-005{}/eeprom".format(2 - self.index) + self.format = psu_eeprom_format + else: + self.index = fan_index + self.start_offset = 13 + self.eeprom_path = self.I2C_DIR \ + + "i2c-4{0}/4{0}-0050/eeprom".format(self.index - 1) + self.format = fan_eeprom_format + EepromDecoder.__init__(self, self.eeprom_path, self.format, + self.start_offset, '', True) + self._load_device_eeprom() + + def _load_system_eeprom(self): + """ + Reads the system EEPROM and retrieves the values corresponding + to the codes defined as per ONIE TlvInfo EEPROM format and fills + them in a dictionary. + """ + try: + # Read System EEPROM as per ONIE TlvInfo EEPROM format. + self.eeprom_data = self.read_eeprom() + except Exception as e: + self.base_mac = 'NA' + self.serial_number = 'NA' + self.part_number = 'NA' + self.model_str = 'NA' + self.serial = 'NA' + self.eeprom_tlv_dict = dict() + else: + eeprom = self.eeprom_data + self.eeprom_tlv_dict = dict() + + if not self.is_valid_tlvinfo_header(eeprom): + self.base_mac = 'NA' + self.serial_number = 'NA' + self.part_number = 'NA' + self.model_str = 'NA' + self.serial = 'NA' + return + + total_length = (eeprom[9] << 8) | eeprom[10] + tlv_index = self._TLV_INFO_HDR_LEN + tlv_end = self._TLV_INFO_HDR_LEN + total_length + + while (tlv_index + 2) < len(eeprom) and tlv_index < tlv_end: + if not self.is_valid_tlv(eeprom[tlv_index:]): + break + + tlv = eeprom[tlv_index:tlv_index + 2 + + eeprom[tlv_index + 1]] + code = "0x%02X" % (tlv[0]) + + name, value = self.decoder(None, tlv) + + self.eeprom_tlv_dict[code] = value + if eeprom[tlv_index] == self._TLV_CODE_CRC_32: + break + + tlv_index += eeprom[tlv_index+1] + 2 + + self.base_mac = self.eeprom_tlv_dict.get( + "0x%X" % (self._TLV_CODE_MAC_BASE), 'NA') + self.serial_number = self.eeprom_tlv_dict.get( + "0x%X" % (self._TLV_CODE_SERIAL_NUMBER), 'NA') + self.part_number = self.eeprom_tlv_dict.get( + "0x%X" % (self._TLV_CODE_PART_NUMBER), 'NA') + self.model_str = self.eeprom_tlv_dict.get( + "0x%X" % (self._TLV_CODE_PRODUCT_NAME), 'NA') + self.serial = self.eeprom_tlv_dict.get( + "0x%X" % (self._TLV_CODE_SERVICE_TAG), 'NA') + + def _load_device_eeprom(self): + """ + Reads the Fan/PSU EEPROM and retrieves the serial number and + model number of the device. + """ + try: + # Read Fan/PSU EEPROM as per the specified format. + self.eeprom_data = EepromDecoder.read_eeprom(self) + except Exception as e: + self.serial_number = 'NA' + self.part_number = 'NA' + self.model_str = 'NA' + self.serial = 'NA' + else: + (valid, data) = self._get_eeprom_field("Model") + if valid: + self.model_str = data + else: + self.model_str = 'NA' + + (valid, data) = self._get_eeprom_field("Serial Number") + if valid: + self.serial_number = data + else: + self.serial_number = 'NA' + + 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: + (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): + """ + For a field name specified in the EEPROM format, returns the + presence of the field and the value for the same. + """ + field_start = 0 + for field in self.format: + field_end = field_start + field[2] + if field[0] == field_name: + if decode: + return (True, self.eeprom_data[field_start:field_end].decode('ascii')) + else: + return (True, self.eeprom_data[field_start:field_end]) + field_start = field_end + + return (False, None) + + def serial_number_str(self): + """ + Returns the serial number. + """ + return self.serial_number + + def part_number_str(self): + """ + Returns the part number. + """ + return self.part_number + + def airflow_fan_type(self): + """ + Returns the airflow fan type. + """ + 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): + """ + Returns the base MAC address found in the system EEPROM. + """ + return self.base_mac + + def modelstr(self): + """ + Returns the Model name. + """ + return self.model_str + + def serial_str(self): + """ + Returns the servicetag number. + """ + return self.serial + + def system_eeprom_info(self): + """ + Returns a dictionary, where keys are the type code defined in + ONIE EEPROM format and values are their corresponding values + found in the system EEPROM. + """ + return self.eeprom_tlv_dict diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/fan.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/fan.py new file mode 100644 index 000000000000..67610a125fad --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/fan.py @@ -0,0 +1,361 @@ +######################################################################## +# Nokia 7215 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Fans' information which are available in the platform +# +######################################################################## + + +try: + import os + from sonic_platform_base.fan_base import FanBase + from sonic_py_common import logger +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +smbus_present = 1 +try: + import smbus +except ImportError as e: + smbus_present = 0 + +MAX_IXS7215_FAN_SPEED = 19000 +WORKING_IXS7215_FAN_SPEED = 960 + +sonic_logger = logger.Logger('fan') + + +class Fan(FanBase): + """Nokia platform-specific Fan class""" + + def __init__(self, fan_index, fan_drawer, psu_fan=False, dependency=None): + self.is_psu_fan = psu_fan + ADT7473_DIR = "/sys/bus/i2c/devices/0-002e/" + + if not self.is_psu_fan: + # Fan is 1-based in Nokia platforms + self.index = fan_index + 1 + self.fan_drawer = fan_drawer + self.set_fan_speed_reg = ADT7473_DIR+"pwm{}".format(self.index) + self.get_fan_speed_reg = ADT7473_DIR+"fan{}_input".format(self.index) + self.max_fan_speed = MAX_IXS7215_FAN_SPEED + self.supported_led_color = ['off', 'green', 'red'] + else: + # this is a PSU Fan + self.index = fan_index + self.dependency = dependency + + def _get_i2c_register(self, reg_file): + # On successful read, returns the value read from given + # reg_name and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(reg_file)): + return rv + + try: + with open(reg_file, 'r') as fd: + rv = fd.read() + except Exception as e: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + + def _set_i2c_register(self, reg_file, value): + # On successful write, the value read will be written on + # reg_name and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(reg_file)): + return rv + + try: + with open(reg_file, 'w') as fd: + rv = fd.write(str(value)) + except Exception as e: + rv = 'ERR' + + return rv + + def get_name(self): + """ + Retrieves the name of the Fan + + Returns: + string: The name of the Fan + """ + if not self.is_psu_fan: + return "Fan{}".format(self.index) + else: + return "PSU{} Fan".format(self.index) + + def get_presence(self): + """ + Retrieves the presence of the Fan Unit + + Returns: + bool: True if Fan is present, False if not + """ + if smbus_present == 0: + sonic_logger.log_info("PMON fan-smbus ERROR - presence ") + return False + else: + bus = smbus.SMBus(0) + DEVICE_ADDRESS = 0x41 + DEVICE_REG = 0xb + fanstatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + + if self.index == 1: + fanstatus = fanstatus & 1 + if fanstatus == 1: + return False + if self.index == 2: + fanstatus = fanstatus & 2 + if fanstatus == 2: + return False + return True + + def get_model(self): + """ + Retrieves the model number of the Fan + + Returns: + string: Part number of Fan + """ + + return 'NA' + + def get_serial(self): + """ + Retrieves the serial number of the Fan + + Returns: + string: Serial number of Fan + """ + + return 'NA' + + def get_status(self): + """ + Retrieves the operational status of the Fan + + Returns: + bool: True if Fan is operating properly, False if not + """ + status = False + + fan_speed = self._get_i2c_register(self.get_fan_speed_reg) + if (fan_speed != 'ERR'): + if (int(fan_speed) > WORKING_IXS7215_FAN_SPEED): + status = True + + return status + + def get_direction(self): + """ + Retrieves the fan airflow direction + Possible fan directions (relative to port-side of device) + Returns: + A string, either FAN_DIRECTION_INTAKE or + FAN_DIRECTION_EXHAUST depending on fan direction + """ + + return 'intake' + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device + Returns: + integer: The 1-based relative physical position in parent device + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True + + + def get_speed(self): + """ + Retrieves the speed of a Front FAN in the tray in revolutions per + minute defined by 1-based index + :param index: An integer, 1-based index of the FAN to query speed + :return: integer, denoting front FAN speed + """ + speed = 0 + + fan_speed = self._get_i2c_register(self.get_fan_speed_reg) + if (fan_speed != 'ERR'): + speed_in_rpm = int(fan_speed) + else: + speed_in_rpm = 0 + + speed = 100*speed_in_rpm//MAX_IXS7215_FAN_SPEED + if speed > 100: + speed = 100 + + return speed + + def get_speed_tolerance(self): + """ + Retrieves the speed tolerance of the fan + + Returns: + An integer, the percentage of variance from target speed + which is considered tolerable + """ + if self.get_presence(): + # The tolerance value is fixed as 25% for this platform + tolerance = 25 + else: + tolerance = 0 + + return tolerance + + def set_speed(self, speed): + """ + Set fan speed to expected value + Args: + speed: An integer, the percentage of full fan speed to set + fan to, in the range 0 (off) to 100 (full speed) + Returns: + bool: True if set success, False if fail. + """ + if self.is_psu_fan: + return False + + # Set current fan duty cycle + # - 0x00 : fan off + # - 0x40 : 25% duty cycle + # - 0x80 : 50% duty cycle (default) + # - 0xff : 100% duty cycle (full speed) + if speed in range(0, 6): + fandutycycle = 0x00 + elif speed in range(6, 41): + fandutycycle = 64 + elif speed in range(41, 76): + fandutycycle = 128 + elif speed in range(76, 101): + fandutycycle = 255 + else: + return False + + rv = self._set_i2c_register(self.set_fan_speed_reg, fandutycycle) + if (rv != 'ERR'): + return True + else: + return False + + def set_status_led(self, color): + """ + Set led to expected color + Args: + color: A string representing the color with which to set the + fan module status LED + Returns: + bool: True if set success, False if fail. + + off , red and green are the only settings 7215 fans + """ + + if self.is_psu_fan or (color not in self.supported_led_color): + return False + if (color == self.STATUS_LED_COLOR_AMBER): + return False + if (color == self.STATUS_LED_COLOR_RED): + value = 0x02 + elif (color == self.STATUS_LED_COLOR_GREEN): + value = 0x01 + elif (color == self.STATUS_LED_COLOR_OFF): + value = 0x00 + else: + return False + + if smbus_present == 0: + return False + else: + bus = smbus.SMBus(0) + DEVICE_ADDRESS = 0x41 + DEVICEREG = 0x8 + original = bus.read_byte_data(DEVICE_ADDRESS, DEVICEREG) + if (self.index == 1): + new = value << 4 + ledstatus = original & 0xcf + ledstatus = ledstatus | new + elif self.index == 2: + new = value << 6 + ledstatus = original & 0x3f + ledstatus = ledstatus | new + else: + return False + + bus.write_byte_data(DEVICE_ADDRESS, DEVICEREG, ledstatus) + + return True + + def get_status_led(self): + """ + Gets the state of the fan status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings. + """ + + if self.is_psu_fan: + return False + + if smbus_present == 0: + return False + else: + bus = smbus.SMBus(0) + DEVICE_ADDRESS = 0x41 + DEVICE_REG = 0x8 + ledstatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + + if self.index == 1: + ledstatus = (ledstatus & 0x30) + ledstatus = ledstatus >> 4 + elif self.index == 2: + ledstatus = (ledstatus & 0xC0) + ledstatus = ledstatus >> 6 + if ledstatus == 0x02: + return self.STATUS_LED_COLOR_RED + elif ledstatus == 0x1: + return self.STATUS_LED_COLOR_GREEN + else: + return self.STATUS_LED_COLOR_OFF + + def get_target_speed(self): + """ + Retrieves the target (expected) speed of the fan + + Returns: + An integer, the percentage of full fan speed, in the range 0 + (off) to 100 (full speed) + """ + speed = 0 + + fan_duty = self._get_i2c_register(self.set_fan_speed_reg) + if (fan_duty != 'ERR'): + dutyspeed = int(fan_duty) + if dutyspeed == 0: + speed = 0 + elif dutyspeed == 64: + speed = 25 + elif dutyspeed == 128: + speed = 50 + elif dutyspeed == 255: + speed = 100 + + return speed + + + + diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/fan_drawer.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/fan_drawer.py new file mode 100644 index 000000000000..cabb15d455d6 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/fan_drawer.py @@ -0,0 +1,91 @@ +############################################################################# +# Nokia +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Fan Drawer status which is available in the platform +# +############################################################################# + +try: + from sonic_platform_base.fan_drawer_base import FanDrawerBase + from sonic_py_common import logger +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +sonic_logger = logger.Logger('fan_drawer') + +class NokiaFanDrawer(FanDrawerBase): + def __init__(self, index): + super(NokiaFanDrawer, self).__init__() + self._index = index + 1 + self._led = None + + def get_index(self): + return self._index + + def get_presence(self): + return self._fan_list[0].get_presence() + + def get_model(self): + """ + Retrieves the model number of the Fan Drawer + Returns: + string: Part number of Fan Drawer + """ + return self._fan_list[0].get_model() + + def get_serial(self): + """ + Retrieves the serial number of the Fan Drawer + Returns: + string: Serial number of Fan + """ + return self._fan_list[0].get_serial() + + def get_status(self): + """ + Retrieves the operational status of the Fan Drawer + Returns: + bool: True if Fan is operating properly, False if not + """ + return self._fan_list[0].get_status() + + def get_direction(self): + return 'intake' + + def set_status_led(self, color): + return True + + def get_status_led(self, color): + return self._fan_list[0].get_status_led() + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device + Returns: + integer: The 1-based relative physical position in parent device + """ + return self._index + + +# For Nokia platforms with fan drawer(s) +class RealDrawer(NokiaFanDrawer): + def __init__(self, index): + super(RealDrawer, self).__init__(index) + self._name = 'drawer{}'.format(self._index) + + def get_name(self): + return self._name + + + + + diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/platform.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/platform.py new file mode 100755 index 000000000000..7a3046bc7391 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/platform.py @@ -0,0 +1,22 @@ +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PlatformBase): + """ + Nokia platform-specific class + """ + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/psu.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/psu.py new file mode 100644 index 000000000000..ab53abebf934 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/psu.py @@ -0,0 +1,248 @@ +######################################################################## +# Nokia 7215 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the PSUs' information which are available in the platform +# +######################################################################## + +try: + import sys + from sonic_platform_base.psu_base import PsuBase + from sonic_py_common import logger +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +if sys.version_info[0] < 3: + import commands as cmd +else: + import subprocess as cmd + +smbus_present = 1 +try: + import smbus +except ImportError as e: + smbus_present = 0 + +sonic_logger = logger.Logger('psu') + +class Psu(PsuBase): + """Nokia platform-specific PSU class for 7215 """ + + def __init__(self, psu_index): + # PSU is 1-based in Nokia platforms + self.index = psu_index + 1 + self._fan_list = [] + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + return "PSU{}".format(self.index) + + def get_presence(self): + """ + Retrieves the presence of the Power Supply Unit (PSU) + + Returns: + bool: True if PSU is present, False if not + """ + + if smbus_present == 0: # if called from psuutil outside of pmon + cmdstatus, psustatus = cmd.getstatusoutput('i2cget -y 0 0x41 0xa') + psustatus = int(psustatus, 16) + else: + bus = smbus.SMBus(0) + DEVICE_ADDRESS = 0x41 + DEVICE_REG = 0xa + psustatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + + if self.index == 1: + psustatus = psustatus & 1 + if psustatus == 1: + return False + if self.index == 2: + psustatus = psustatus & 2 + if psustatus == 2: + return False + + return True + + def get_model(self): + """ + Retrieves the part number of the PSU + + Returns: + string: Part number of PSU + """ + return "N/A" +# return self.eeprom.serial_number_str() + + + def get_serial(self): + """ + Retrieves the serial number of the PSU + + Returns: + string: Serial number of PSU + """ + return "N/A" +# return self.eeprom.serial_number_str() + + + def get_status(self): + """ + Retrieves the operational status of the PSU + + Returns: + bool: True if PSU is operating properly, False if not + """ + + if smbus_present == 0: + cmdstatus, psustatus = cmd.getstatusoutput('i2cget -y 0 0x41 0xa') + psustatus = int(psustatus, 16) + sonic_logger.log_warning("PMON psu-smbus - presence = 0 ") + else: + bus = smbus.SMBus(0) + DEVICE_ADDRESS = 0x41 + DEVICE_REG = 0xa + psustatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + + if self.index == 1: + psustatus = psustatus & 4 + if psustatus == 4: + return True + if self.index == 2: + psustatus = psustatus & 8 + if psustatus == 8: + return True + + return False + + def get_voltage(self): + """ + Retrieves current PSU voltage output + + Returns: + A float number, the output voltage in volts, + e.g. 12.1 + """ + if smbus_present == 0: + cmdstatus, psustatus = cmd.getstatusoutput('i2cget -y 0 0x41 0xa') + psustatus = int(psustatus, 16) + else: + bus = smbus.SMBus(0) + DEVICE_ADDRESS = 0x41 + DEVICE_REG = 0xa + psustatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + + if self.index == 1: + psustatus = psustatus & 4 + if psustatus == 4: + psu_voltage = 12.0 + return psu_voltage + if self.index == 2: + psustatus = psustatus & 8 + if psustatus == 8: + psu_voltage = 12.0 + return psu_voltage + + psu_voltage = 0.0 + return psu_voltage + +# def get_current(self): +# """ +# Retrieves present electric current supplied by PSU +# +# Returns: +# A float number, electric current in amperes, +# e.g. 15.4 +# """ +# psu_current = 0.0 +# +# return psu_current +# +# def get_power(self): +# """ +# Retrieves current energy supplied by PSU +# +# Returns: +# A float number, the power in watts, +# e.g. 302.6 +# """ +# psu_power = 0.0 +# +# return psu_power + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device + Returns: + integer: The 1-based relative physical position in parent device + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True + + def get_powergood_status(self): + """ + Retrieves the powergood status of PSU + Returns: + A boolean, True if PSU has stablized its output voltages and + passed all its internal self-tests, False if not. + """ + + if smbus_present == 0: + cmdstatus, psustatus = cmd.getstatusoutput('i2cget -y 0 0x41 0xa') + psustatus = int(psustatus, 16) + else: + bus = smbus.SMBus(0) + DEVICE_ADDRESS = 0x41 + DEVICE_REG = 0xa + psustatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + + if self.index == 1: + psustatus = psustatus & 4 + if psustatus == 4: + return True + if self.index == 2: + psustatus = psustatus & 8 + if psustatus == 8: + return True + + return False + + def get_status_led(self): + """ + Gets the state of the PSU status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings. + """ + if self.get_powergood_status(): + return self.STATUS_LED_COLOR_GREEN + else: + return self.STATUS_LED_COLOR_OFF + + def set_status_led(self, color): + """ + Sets the state of the PSU status LED + Args: + color: A string representing the color with which to set the + PSU status LED + Returns: + bool: True if status LED state is set successfully, False if + not + """ + # In ISX7215 , the firmware running in the PSU controls the LED + # and the PSU LED state cannot be changed from CPU. + return False diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/sfp.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/sfp.py new file mode 100644 index 000000000000..cb9c1b910561 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/sfp.py @@ -0,0 +1,948 @@ +############################################################################# +# Nokia +# +############################################################################# + +import os +import sys +import time + +try: + from sonic_platform_base.sfp_base import SfpBase + from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom + from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper + from sonic_py_common import logger +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +if sys.version_info[0] < 3: + import commands as cmd +else: + import subprocess as cmd + +smbus_present = 1 + +try: + import smbus +except ImportError as e: + smbus_present = 0 + + +INFO_OFFSET = 128 +DOM_OFFSET = 0 + +# definitions of the offset and width for values in XCVR info eeprom +XCVR_INTFACE_BULK_OFFSET = 0 + +XCVR_INTFACE_BULK_WIDTH_SFP = 21 +XCVR_TYPE_OFFSET = 0 +XCVR_TYPE_WIDTH = 1 +XCVR_EXT_TYPE_OFFSET = 1 +XCVR_EXT_TYPE_WIDTH = 1 +XCVR_CONNECTOR_OFFSET = 2 +XCVR_CONNECTOR_WIDTH = 1 +XCVR_COMPLIANCE_CODE_OFFSET = 3 +XCVR_COMPLIANCE_CODE_WIDTH = 8 +XCVR_ENCODING_OFFSET = 11 +XCVR_ENCODING_WIDTH = 1 +XCVR_NBR_OFFSET = 12 +XCVR_NBR_WIDTH = 1 +XCVR_EXT_RATE_SEL_OFFSET = 13 +XCVR_EXT_RATE_SEL_WIDTH = 1 +XCVR_CABLE_LENGTH_OFFSET = 14 + +XCVR_CABLE_LENGTH_WIDTH_SFP = 6 +XCVR_VENDOR_NAME_OFFSET = 20 +XCVR_VENDOR_NAME_WIDTH = 16 +XCVR_VENDOR_OUI_OFFSET = 37 +XCVR_VENDOR_OUI_WIDTH = 3 +XCVR_VENDOR_PN_OFFSET = 40 +XCVR_VENDOR_PN_WIDTH = 16 +XCVR_HW_REV_OFFSET = 56 + +XCVR_HW_REV_WIDTH_SFP = 4 +XCVR_VENDOR_SN_OFFSET = 68 +XCVR_VENDOR_SN_WIDTH = 16 +XCVR_VENDOR_DATE_OFFSET = 84 +XCVR_VENDOR_DATE_WIDTH = 8 +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 2 +XCVR_INTERFACE_DATA_START = 0 +XCVR_INTERFACE_DATA_SIZE = 92 + +SFP_DOM_BULK_DATA_START = 96 +SFP_DOM_BULK_DATA_SIZE = 10 + +SFP_MODULE_ADDRA2_OFFSET = 256 +SFP_MODULE_THRESHOLD_OFFSET = 0 +SFP_MODULE_THRESHOLD_WIDTH = 56 +SFP_CHANNL_THRESHOLD_OFFSET = 112 +SFP_CHANNL_THRESHOLD_WIDTH = 2 + +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VOLT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_CHANNL_MON_OFFSET = 100 +SFP_CHANNL_MON_WIDTH = 6 +SFP_CHANNL_STATUS_OFFSET = 110 +SFP_CHANNL_STATUS_WIDTH = 1 + +sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)', + 'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)', + 'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)') + +sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode', + 'ESCONComplianceCodes', 'SONETComplianceCodes', + 'EthernetComplianceCodes', 'FibreChannelLinkLength', + 'FibreChannelTechnology', 'SFP+CableTechnology', + 'FibreChannelTransmissionMedia', 'FibreChannelSpeed') + +COPPER_TYPE = "COPPER" +SFP_TYPE = "SFP" + +# SFP PORT numbers +SFP_PORT_START = 49 +SFP_PORT_END = 52 + +SYSLOG_IDENTIFIER = "xcvrd" +sonic_logger = logger.Logger(SYSLOG_IDENTIFIER) + + +class Sfp(SfpBase): + """Platform-specific Sfp class""" + """ + Nokia platform-specific Sfp class + """ + + # Paths + PLATFORM_ROOT_PATH = "/usr/share/sonic/device" + PMON_HWSKU_PATH = "/usr/share/sonic/hwsku" + HOST_CHK_CMD = "docker > /dev/null 2>&1" + + PLATFORM = "armhf-nokia_ixs7215_52x-r0" + HWSKU = "Nokia-7215" + + port_to_i2c_mapping = 0 + + def __init__(self, index, sfp_type, eeprom_path, port_i2c_map): + SfpBase.__init__(self) + + self.index = index + self.port_num = index + self.sfp_type = sfp_type + self.eeprom_path = eeprom_path + self.port_to_i2c_mapping = port_i2c_map + self.port_name = sfp_type + str(index) + self.port_to_eeprom_mapping = {} + + self.port_to_eeprom_mapping[index] = eeprom_path + + self.info_dict_keys = ['type', 'hardware_rev', 'serial', 'manufacturer', + 'model', 'connector', 'encoding', 'ext_identifier', + 'ext_rateselect_compliance', 'cable_type', 'cable_length', + 'nominal_bit_rate', 'specification_compliance', + 'vendor_date', 'vendor_oui'] + + self.dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', + 'tx_disable', 'tx_disable_channel', 'temperature', + 'voltage', 'rx1power', 'rx2power', 'rx3power', + 'rx4power', 'tx1bias', 'tx2bias', 'tx3bias', 'tx4bias', + 'tx1power', 'tx2power', 'tx3power', 'tx4power'] + + self.threshold_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', + 'templowwarning', 'vcchighalarm', 'vcchighwarning', + 'vcclowalarm', 'vcclowwarning', 'rxpowerhighalarm', + 'rxpowerhighwarning', 'rxpowerlowalarm', 'rxpowerlowwarning', + 'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', + 'txpowerlowwarning', 'txbiashighalarm', 'txbiashighwarning', + 'txbiaslowalarm', 'txbiaslowwarning'] + + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.calibration = 0 + + def __convert_string_to_num(self, value_str): + if "-inf" in value_str: + return 'N/A' + elif "Unknown" in value_str: + return 'N/A' + elif 'dBm' in value_str: + t_str = value_str.rstrip('dBm') + return float(t_str) + elif 'mA' in value_str: + t_str = value_str.rstrip('mA') + return float(t_str) + elif 'C' in value_str: + t_str = value_str.rstrip('C') + return float(t_str) + elif 'Volts' in value_str: + t_str = value_str.rstrip('Volts') + return float(t_str) + else: + return 'N/A' + + def __is_host(self): + return os.system(self.HOST_CHK_CMD) == 0 + + def __get_path_to_port_config_file(self): + platform_path = "/".join([self.PLATFORM_ROOT_PATH, self.PLATFORM]) + hwsku_path = "/".join([platform_path, self.HWSKU] + ) if self.__is_host() else self.PMON_HWSKU_PATH + return "/".join([hwsku_path, "port_config.ini"]) + + def __read_eeprom_specific_bytes(self, offset, num_bytes): + sysfsfile_eeprom = None + + eeprom_raw = [] + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[self.port_num] + + try: + sysfsfile_eeprom = open( + sysfs_sfp_i2c_client_eeprom_path, mode="rb", buffering=0) + sysfsfile_eeprom.seek(offset) + raw = sysfsfile_eeprom.read(num_bytes) + for n in range(0, num_bytes): + eeprom_raw[n] = hex(raw[n])[2:].zfill(2) + except Exception as e: + pass + finally: + if sysfsfile_eeprom: + sysfsfile_eeprom.close() + return eeprom_raw + + def _dom_capability_detect(self): + if self.sfp_type == "SFP": + sfpi_obj = sff8472InterfaceId() + if sfpi_obj is None: + return None + sfp_dom_capability_raw = self.__read_eeprom_specific_bytes( + XCVR_DOM_CAPABILITY_OFFSET, XCVR_DOM_CAPABILITY_WIDTH) + if sfp_dom_capability_raw is not None: + sfp_dom_capability = int(sfp_dom_capability_raw[0], 16) + self.dom_supported = (sfp_dom_capability & 0x40 != 0) + if self.dom_supported: + self.dom_temp_supported = True + self.dom_volt_supported = True + self.dom_rx_power_supported = True + self.dom_tx_power_supported = True + if sfp_dom_capability & 0x20 != 0: + self.calibration = 1 + elif sfp_dom_capability & 0x10 != 0: + self.calibration = 2 + else: + self.calibration = 0 + else: + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.calibration = 0 + self.dom_tx_disable_supported = ( + int(sfp_dom_capability_raw[1], 16) & 0x40 != 0) + else: + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + + def get_transceiver_info(self): + """ + Retrieves transceiver info of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + type |1*255VCHAR |type of SFP + hardware_rev |1*255VCHAR |hardware version of SFP + serial |1*255VCHAR |serial number of the SFP + manufacturer |1*255VCHAR |SFP vendor name + model |1*255VCHAR |SFP model name + connector |1*255VCHAR |connector information + encoding |1*255VCHAR |encoding information + ext_identifier |1*255VCHAR |extend identifier + ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance + cable_length |INT |cable length in m + nominal_bit_rate |INT |nominal bit rate by 100Mbs + specification_compliance |1*255VCHAR |specification compliance + vendor_date |1*255VCHAR |vendor date + vendor_oui |1*255VCHAR |vendor OUI + application_advertisement |1*255VCHAR |supported applications advertisement + ======================================================================== + """ + + if self.sfp_type == COPPER_TYPE: + return None + + compliance_code_dict = {} + transceiver_info_dict = dict.fromkeys(self.info_dict_keys, 'N/A') + + if not self.get_presence(): + return transceiver_info_dict + + if self.sfp_type == SFP_TYPE: + offset = 0 + vendor_rev_width = XCVR_HW_REV_WIDTH_SFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_SFP + + sfpi_obj = sff8472InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + + sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes( + offset + XCVR_INTERFACE_DATA_START, XCVR_INTERFACE_DATA_SIZE) + if sfp_interface_bulk_raw is None: + return None + + start = XCVR_INTFACE_BULK_OFFSET - XCVR_INTERFACE_DATA_START + end = start + interface_info_bulk_width + sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_NAME_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_NAME_WIDTH + sfp_vendor_name_data = sfpi_obj.parse_vendor_name( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_PN_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_PN_WIDTH + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_HW_REV_OFFSET - XCVR_INTERFACE_DATA_START + end = start + vendor_rev_width + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_SN_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_SN_WIDTH + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_OUI_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_OUI_WIDTH + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui( + sfp_interface_bulk_raw[start: end], 0) + + start = XCVR_VENDOR_DATE_OFFSET - XCVR_INTERFACE_DATA_START + end = start + XCVR_VENDOR_DATE_WIDTH + sfp_vendor_date_data = sfpi_obj.parse_vendor_date( + sfp_interface_bulk_raw[start: end], 0) + transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] + transceiver_info_dict['vendor_date'] = sfp_vendor_date_data[ + 'data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] + transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] + transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] + + for key in sfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str( + sfp_interface_bulk_data['data'][key]['value']) + + for key in sfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + transceiver_info_dict['specification_compliance'] = str( + compliance_code_dict) + + transceiver_info_dict['nominal_bit_rate'] = str( + sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) + transceiver_info_dict['application_advertisement'] = 'N/A' + + return transceiver_info_dict + + def get_transceiver_bulk_status(self): + """ + Retrieves transceiver bulk status of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + rx_los |BOOLEAN |RX loss-of-signal status, True if has RX los, False if not. + tx_fault |BOOLEAN |TX fault status, True if has TX fault, False if not. + reset_status |BOOLEAN |reset status, True if SFP in reset, False if not. + lp_mode |BOOLEAN |low power mode status, True in lp mode, False if not. + tx_disable |BOOLEAN |TX disable status, True TX disabled, False if not. + tx_disabled_channel |HEX |disabled TX channels in hex, bits 0 to 3 represent channel 0 + | |to channel 3. + temperature |INT |module temperature in Celsius + voltage |INT |supply voltage in mV + txbias |INT |TX Bias Current in mA, n is the channel number, + | |for example, tx2bias stands for tx bias of channel 2. + rxpower |INT |received optical power in mW, n is the channel number, + | |for example, rx2power stands for rx power of channel 2. + txpower |INT |TX output power in mW, n is the channel number, + | |for example, tx2power stands for tx power of channel 2. + ======================================================================== + """ + + transceiver_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A') + + if self.sfp_type == COPPER_TYPE: + return transceiver_dom_info_dict + + if self.sfp_type == SFP_TYPE: + + self._dom_capability_detect() + if not self.dom_supported: + return transceiver_dom_info_dict + + offset = 256 + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return transceiver_dom_info_dict + sfpd_obj._calibration_type = self.calibration + + dom_data_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_DOM_BULK_DATA_START), SFP_DOM_BULK_DATA_SIZE) + + start = SFP_TEMPE_OFFSET - SFP_DOM_BULK_DATA_START + end = start + SFP_TEMPE_WIDTH + dom_temperature_data = sfpd_obj.parse_temperature( + dom_data_raw[start: end], 0) + + start = SFP_VOLT_OFFSET - SFP_DOM_BULK_DATA_START + end = start + SFP_VOLT_WIDTH + dom_voltage_data = sfpd_obj.parse_voltage( + dom_data_raw[start: end], 0) + + start = SFP_CHANNL_MON_OFFSET - SFP_DOM_BULK_DATA_START + end = start + SFP_CHANNL_MON_WIDTH + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( + dom_data_raw[start: end], 0) + + transceiver_dom_info_dict['temperature'] = self.__convert_string_to_num( + dom_temperature_data['data']['Temperature']['value']) + transceiver_dom_info_dict['voltage'] = self.__convert_string_to_num( + dom_voltage_data['data']['Vcc']['value']) + transceiver_dom_info_dict['rx1power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['RXPower']['value']) + transceiver_dom_info_dict['tx1bias'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['TXBias']['value']) + transceiver_dom_info_dict['tx1power'] = self.__convert_string_to_num( + dom_channel_monitor_data['data']['TXPower']['value']) + + transceiver_dom_info_dict['rx_los'] = self.get_rx_los() + transceiver_dom_info_dict['tx_fault'] = self.get_tx_fault() + transceiver_dom_info_dict['reset_status'] = self.get_reset_status() + transceiver_dom_info_dict['lp_mode'] = self.get_lpmode() + + return transceiver_dom_info_dict + + def get_transceiver_threshold_info(self): + """ + Retrieves transceiver threshold info of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius. + templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius. + temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius. + templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius. + vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV. + vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV. + vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV. + vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV. + rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm. + rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm. + rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm. + rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm. + txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm. + txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm. + txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm. + txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm. + txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA. + txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA. + txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA. + txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA. + ======================================================================== + """ + transceiver_dom_threshold_info_dict = dict.fromkeys( + self.threshold_dict_keys, 'N/A') + + if self.sfp_type == COPPER_TYPE: + return transceiver_dom_threshold_info_dict + + if self.sfp_type == SFP_TYPE: + + offset = SFP_MODULE_ADDRA2_OFFSET + + self._dom_capability_detect() + if not self.dom_supported: + return transceiver_dom_threshold_info_dict + + sfpd_obj = sff8472Dom(None, self.calibration) + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_raw = self.__read_eeprom_specific_bytes((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 + + # 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 + + def get_reset_status(self): + """ + Retrieves the reset status of SFP + Returns: + A Boolean, True if reset enabled, False if disabled + """ + self._dom_capability_detect() + if not self.dom_supported: + return False + if self.sfp_type == COPPER_TYPE: + return False + + if self.sfp_type == SFP_TYPE: + offset = 0 + + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + + if dom_channel_monitor_raw is not None: + return False + else: + return True + + def get_rx_los(self): + """ + Retrieves the RX LOS (lost-of-signal) status of SFP + Returns: + A Boolean, True if SFP has RX LOS, False if not. + """ + if self.sfp_type == COPPER_TYPE: + return None + if not self.dom_supported: + return None + rx_los_list = [] + + offset = 256 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes((offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 16) + rx_los_list.append(rx_los_data & 0x02 != 0) + else: + return None + + return rx_los_list + + def get_tx_fault(self): + """ + Retrieves the TX fault status of SFP + Returns: + A Boolean, True if SFP has TX fault, False if not + Note : TX fault status is lached until a call to get_tx_fault or a reset. + """ + if self.sfp_type == COPPER_TYPE: + return None + if not self.dom_supported: + return None + tx_fault_list = [] + + offset = 256 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes((offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 16) + tx_fault_list.append(tx_fault_data & 0x04 != 0) + else: + return None + return tx_fault_list + + + def get_tx_disable(self): + """ + Retrieves the tx_disable status of this SFP + Returns: + A Boolean, True if tx_disable is enabled, False if disabled + """ + + if self.sfp_type == COPPER_TYPE: + return None + if not self.dom_supported: + return None + + tx_disable_list = [] + offset = 256 + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes((offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_disable_data = int(dom_channel_monitor_raw[0], 16) + tx_disable_list.append(tx_disable_data & 0xC0 != 0) + else: + return None + + return tx_disable_list + + def get_tx_disable_channel(self): + """ + Retrieves the TX disabled channels in this SFP + Returns: + A hex of 4 bits (bit 0 to bit 3 as channel 0 to channel 3) to represent + TX channels which have been disabled in this SFP. + As an example, a returned value of 0x5 indicates that channel 0 + and channel 2 have been disabled. + """ + tx_disable_list = self.get_tx_disable() + if tx_disable_list is None: + return 0 + tx_disabled = 0 + for i in range(len(tx_disable_list)): + if tx_disable_list[i]: + tx_disabled |= 1 << i + return tx_disabled + + def get_lpmode(self): + """ + Retrieves the lpmode (low power mode) status of this SFP + Returns: + A Boolean, True if lpmode is enabled, False if disabled + """ + if self.sfp_type == COPPER_TYPE: + return False + if self.sfp_type == SFP_TYPE: + return False + + def get_power_override(self): + """ + Retrieves the power-override status of this SFP + Returns: + A Boolean, True if power-override is enabled, False if disabled + """ + if self.sfp_type == COPPER_TYPE: + return False + if self.sfp_type == SFP_TYPE: + return False + + def get_temperature(self): + """ + Retrieves the temperature of this SFP + Returns: + An integer number of current temperature in Celsius + """ + if self.sfp_type == COPPER_TYPE: + return None + + transceiver_bulk_status = self.get_transceiver_bulk_status() + return transceiver_bulk_status.get("temperature", "N/A") + + def get_voltage(self): + """ + Retrieves the supply voltage of this SFP + Returns: + An integer number of supply voltage in mV + """ + if self.sfp_type == COPPER_TYPE: + return None + + transceiver_bulk_status = self.get_transceiver_bulk_status() + return transceiver_bulk_status.get("voltage", "N/A") + + def get_tx_bias(self): + """ + Retrieves the TX bias current of this SFP + Returns: + + """ + if self.sfp_type == COPPER_TYPE: + return None + + tx_bias_list = [] + transceiver_bulk_status = self.get_transceiver_bulk_status() + tx_bias_list.append(transceiver_bulk_status.get("tx1bias", "N/A")) + + return tx_bias_list + + + def get_rx_power(self): + """ + Retrieves the received optical power for this SFP + Returns: + A list of four integer numbers, representing received optical + power in mW for channel 0 to channel 4. + Ex. ['1.77', '1.71', '1.68', '1.70'] + """ + rx_power_list = [] + if self.sfp_type == COPPER_TYPE: + return None + + if self.sfp_type == SFP_TYPE: + + offset = 256 + + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + self._dom_capability_detect() + if self.dom_supported: + sfpd_obj._calibration_type = self.calibration + + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_CHANNL_MON_OFFSET), SFP_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) + rx_power_list.append(self.__convert_string_to_num( + dom_channel_monitor_data['data']['RXPower']['value'])) + else: + return None + else: + return None + + return rx_power_list + + def get_tx_power(self): + """ + Retrieves the TX power of this SFP + Returns: + A list of four integer numbers, representing TX power in mW + for channel 0 to channel 4. + Ex. ['1.86', '1.86', '1.86', '1.86'] + """ + tx_power_list = [] + + if self.sfp_type == COPPER_TYPE: + return None + + if self.sfp_type == SFP_TYPE: + + offset = 256 + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + self._dom_capability_detect() + if self.dom_supported: + sfpd_obj._calibration_type = self.calibration + + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_CHANNL_MON_OFFSET), SFP_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) + tx_power_list.append(self.__convert_string_to_num( + dom_channel_monitor_data['data']['TXPower']['value'])) + else: + return None + else: + return None + return tx_power_list + + def reset(self): + """ + Reset SFP and return all user module settings to their default srate. + Returns: + A boolean, True if successful, False if not + """ + if self.sfp_type == COPPER_TYPE: + return False + + path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/sfp_port_reset" + port_ps = path.format(self.port_to_i2c_mapping) + + 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 tx_disable(self, tx_disable): + """ + Disable SFP TX for all channels + Args: + tx_disable : A Boolean, True to enable tx_disable mode, False to disable + tx_disable mode. + Returns: + A boolean, True if tx_disable is set successfully, False if not + """ + + return NotImplementedError + + def tx_disable_channel(self, channel, disable): + """ + Sets the tx_disable for specified SFP channels + Args: + channel : A hex of 4 bits (bit 0 to bit 3) which represent channel 0 to 3, + e.g. 0x5 for channel 0 and channel 2. + disable : A boolean, True to disable TX channels specified in channel, + False to enable + Returns: + A boolean, True if successful, False if not + """ + + return NotImplementedError + + def set_lpmode(self, lpmode): + """ + Sets the lpmode (low power mode) of SFP + Args: + lpmode: A Boolean, True to enable lpmode, False to disable it + Note : lpmode can be overridden by set_power_override + Returns: + A boolean, True if lpmode is set successfully, False if not + """ + if self.sfp_type == COPPER_TYPE: + return False + if self.sfp_type == SFP_TYPE: + return False + + def set_power_override(self, power_override, power_set): + """ + Sets SFP power level using power_override and power_set + Args: + power_override : + A Boolean, True to override set_lpmode and use power_set + to control SFP power, False to disable SFP power control + through power_override/power_set and use set_lpmode + to control SFP power. + power_set : + Only valid when power_override is True. + A Boolean, True to set SFP to low power mode, False to set + SFP to high power mode. + Returns: + A boolean, True if power-override and power_set are set successfully, + False if not + """ + + return NotImplementedError + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + sfputil_helper = SfpUtilHelper() + sfputil_helper.read_porttab_mappings( + self.__get_path_to_port_config_file()) + name = sfputil_helper.logical[self.index] or "Unknown" + return name + + def get_presence(self): + """ + Retrieves the presence + Returns: + bool: True if is present, False if not + """ + if self.sfp_type == COPPER_TYPE: + return False + + if smbus_present == 0: # if called from sfputil outside of pmon + cmdstatus, sfpstatus = cmd.getstatusoutput('i2cget -y 0 0x41 0x3') + sfpstatus = int(sfpstatus, 16) + else: + bus = smbus.SMBus(0) + DEVICE_ADDRESS = 0x41 + DEVICE_REG = 0x3 + sfpstatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + + pos = [1, 2, 4, 8] + bit_pos = pos[self.index-SFP_PORT_START] + sfpstatus = sfpstatus & (bit_pos) + + if sfpstatus == 0: + return True + + return False + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + transceiver_dom_info_dict = self.get_transceiver_info() + return transceiver_dom_info_dict.get("model", "N/A") + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + transceiver_dom_info_dict = self.get_transceiver_info() + return transceiver_dom_info_dict.get("serial", "N/A") + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self.get_presence() + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + + if self.sfp_type == "SFP": + return True + else: + return False + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device + Returns: + integer: The 1-based relative physical position in parent device + """ + return self.index diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/sfp_event.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/sfp_event.py new file mode 100644 index 000000000000..ed2143886760 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/sfp_event.py @@ -0,0 +1,117 @@ +''' +listen for the SFP change event and return to chassis. +''' +import sys +import time +from sonic_py_common import logger + +smbus_present = 1 + +try: + import smbus +except ImportError as e: + smbus_present = 0 + +if sys.version_info[0] < 3: + import commands as cmd +else: + import subprocess as cmd + +# system level event/error +EVENT_ON_ALL_SFP = '-1' +SYSTEM_NOT_READY = 'system_not_ready' +SYSTEM_READY = 'system_become_ready' +SYSTEM_FAIL = 'system_fail' + +# SFP PORT numbers +SFP_PORT_START = 49 +SFP_PORT_END = 52 + +SYSLOG_IDENTIFIER = "sfp_event" +sonic_logger = logger.Logger(SYSLOG_IDENTIFIER) + + +class sfp_event: + ''' Listen to plugin/plugout cable events ''' + + def __init__(self): + self.handle = None + + def initialize(self): + self.modprs_register = 0 + # Get Transceiver status + time.sleep(5) + self.modprs_register = self._get_transceiver_status() + sonic_logger.log_info("Initial SFP presence=%d" % self.modprs_register) + + def deinitialize(self): + if self.handle is None: + return + + def _get_transceiver_status(self): + if smbus_present == 0: + sonic_logger.log_info(" PMON - smbus ERROR - DEBUG sfp_event ") + cmdstatus, sfpstatus = cmd.getstatusoutput('i2cget -y 0 0x41 0x3') + sfpstatus = int(sfpstatus, 16) + else: + bus = smbus.SMBus(0) + DEVICE_ADDRESS = 0x41 + DEVICE_REG = 0x3 + sfpstatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) + + sfpstatus = ~sfpstatus + sfpstatus = sfpstatus & 0xF + + return sfpstatus + + def check_sfp_status(self, port_change, timeout): + """ + check_sfp_status called from get_change_event, this will return correct + status of all 4 SFP ports if there is a change in any of them + """ + start_time = time.time() + port = SFP_PORT_START + forever = False + + if timeout == 0: + forever = True + elif timeout > 0: + timeout = timeout / float(1000) # Convert to secs + else: + return False, {} + end_time = start_time + timeout + + if (start_time > end_time): + return False, {} # Time wrap or possibly incorrect timeout + + while (timeout >= 0): + # Check for OIR events and return updated port_change + reg_value = self._get_transceiver_status() + if (reg_value != self.modprs_register): + changed_ports = (self.modprs_register ^ reg_value) + while (port >= SFP_PORT_START and port <= SFP_PORT_END): + # Mask off the bit corresponding to our port + mask = (1 << port-SFP_PORT_START) + if (changed_ports & mask): + # ModPrsL is active high + if reg_value & mask == 0: + port_change[port] = '0' + else: + port_change[port] = '1' + port += 1 + + # Update reg value + self.modprs_register = reg_value + return True, port_change + + if forever: + time.sleep(1) + else: + timeout = end_time - time.time() + if timeout >= 1: + time.sleep(1) # We poll at 1 second granularity + else: + if timeout > 0: + time.sleep(timeout) + return True, {} + return False, {} diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/README b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/README new file mode 100644 index 000000000000..3efc8fabce08 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/README @@ -0,0 +1 @@ +This directory contains unit tests of the Platform API 2.0 diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-chassis.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-chassis.py new file mode 100755 index 000000000000..775596159269 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-chassis.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python + +try: + import sonic_platform.platform + import sonic_platform.chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +def main(): + print("-----------------") + print("Chassis Unit Test") + print("-----------------") + + chassis = sonic_platform.platform.Platform().get_chassis() + print(" Chassis name: {}".format(chassis.get_name())) + + print(" Chassis presence: {}".format(chassis.get_presence())) + + print(" Chassis model: {}".format(chassis.get_model())) + + print(" Chassis serial: {}".format(chassis.get_serial())) + + print(" Chassis status: {}".format(chassis.get_status())) + + print(" Chassis base_mac: {}".format(chassis.get_base_mac())) + + print(" Chassis reboot cause: {}\n".format(chassis.get_reboot_cause())) + + print(" Chassis watchdog: {}".format(chassis.get_watchdog())) + + print(" Chassis num_components: {}".format(chassis.get_num_components())) + + print(" Chassis all_components: {}\n".format(chassis.get_all_components())) + + print(" Chassis num_modules: {}".format(chassis.get_num_modules())) + + print(" Chassis all_modules: {}\n".format(chassis.get_all_modules())) + + print(" Chassis num_fans: {}".format(chassis.get_num_fans())) + + print(" Chassis all_fans: {}\n".format(chassis.get_all_fans())) + + print(" Chassis num_thermals: {}".format(chassis.get_num_thermals())) + + print(" Chassis all_thermals: {}\n".format(chassis.get_all_thermals())) + + print(" Chassis num_sfps: {}".format(chassis.get_num_sfps())) + + print(" Chassis all_sfps: {}\n".format(chassis.get_all_sfps())) + + print(" Chassis eeprom: {}".format(chassis.get_eeprom())) + + print(" Chassis system_eeprom_info: {}\n".format(chassis.get_system_eeprom_info())) + + print(" Chassis get_status_led start : {}\n".format(chassis.get_status_led())) + chassis.set_status_led('amber') + print(" Chassis get_status_led amber: {}\n".format(chassis.get_status_led())) + chassis.set_status_led('green') + print(" Chassis get_status_led green: {}\n".format(chassis.get_status_led())) + + return + + +if __name__ == '__main__': + main() diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-component.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-component.py new file mode 100755 index 000000000000..edc9e03b3f66 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-component.py @@ -0,0 +1,17 @@ +#!/usr/bin/python + +from sonic_platform.chassis import Chassis + + +def main(): + print("---------------------------") + print("Chassis Component Unit Test") + print("---------------------------") + + chassis = Chassis() + + return + + +if __name__ == '__main__': + main() diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-eeprom.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-eeprom.py new file mode 100755 index 000000000000..76f3d8995e4a --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-eeprom.py @@ -0,0 +1,25 @@ +#!/usr/bin/python + +from sonic_platform.chassis import Chassis + + +def main(): + print("------------------------") + print("Chassis eeprom Unit Test") + print("------------------------") + + chassis = Chassis() + + eeprom = chassis.get_eeprom() + + print " Model: {}, Serial: {}".format(eeprom.modelstr(), + eeprom.serial_str()) + print " Part#: {}, Serial#: {}".format(eeprom.part_number_str(), + eeprom.serial_number_str()) + print " Base MAC: {}".format(eeprom.base_mac_addr()) + + return + + +if __name__ == '__main__': + main() diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-fan.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-fan.py new file mode 100755 index 000000000000..6f1ebd42adbe --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-fan.py @@ -0,0 +1,27 @@ +#!/usr/bin/python + +from sonic_platform.chassis import Chassis + + +def main(): + print("---------------------") + print("Chassis Fan Unit Test") + print("---------------------") + + chassis = Chassis() + + for fan in chassis.get_all_fans(): + print(" Name:", fan.get_name()) + print(" Presence: {}, Status: {}, LED: {}".format(fan.get_presence(), + fan.get_status(), + fan.get_status_led())) + print(" Model: {}, Serial: {}".format(fan.get_model(), + fan.get_serial())) + print(" Direction: {}, Speed: {}RPM, Target Speed: {}%\n".format(fan.get_direction(), + str(fan.get_speed()), + str(fan.get_target_speed()))) + return + + +if __name__ == '__main__': + main() diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-psu.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-psu.py new file mode 100755 index 000000000000..692430ff2991 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-psu.py @@ -0,0 +1,25 @@ +#!/usr/bin/python + +from sonic_platform.chassis import Chassis + + +def main(): + print("---------------------") + print("Chassis PSU Unit Test") + print("---------------------") + + chassis = Chassis() + + for psu in chassis.get_all_psus(): + print(" Name:", psu.get_name()) + print(" Presence: {}, Status: {}, LED: {}".format(psu.get_presence(), + psu.get_status(), + psu.get_status_led())) + print(" Model: {}, Serial: {}".format(psu.get_model(), + psu.get_serial())) + print(" Voltage: {}, Current: NO, Power: NO \n".format(psu.get_voltage())) + return + + +if __name__ == '__main__': + main() diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-sfp.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-sfp.py new file mode 100755 index 000000000000..f5437b18f82e --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-sfp.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python + +try: + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +def main(): + + PORT_START = 1 + PORT_END = 52 + + chassis = Chassis() + + for physical_port in range(PORT_START, PORT_END+1): + + + print(" ") + print(" SFP transceiver tests PORT = ", physical_port) + name = chassis.get_sfp(physical_port).get_name() + print(" SFP transceiver tests NAME = ", name) + + presence = chassis.get_sfp(physical_port).get_presence() + print("TEST 1 - sfp presence [ True ] ", physical_port, presence) + + status = chassis.get_sfp(physical_port).get_reset_status() + print("TEST 2 - sfp reset status [ False ] ", physical_port, status) + + txdisable = chassis.get_sfp(physical_port).get_tx_disable() + print("TEST 3 - sfp tx_disable [ False ] ", physical_port, txdisable) + + rxlos = chassis.get_sfp(physical_port).get_rx_los() + print("TEST 4 - sfp status rxlos [ False ] ", physical_port, rxlos) + + txfault = chassis.get_sfp(physical_port).get_tx_fault() + print("TEST 5 - sfp status txfault [ False ] ", physical_port, txfault) + + lpmode = chassis.get_sfp(physical_port).get_lpmode() + print("TEST 6 - sfp enable lpmode [ False ] ", physical_port, lpmode) + + trans_info = chassis.get_sfp(physical_port).get_transceiver_info() + print("TEST 7 - sfp transceiver info for port:", physical_port, trans_info) + + trans_status = chassis.get_sfp(physical_port).get_transceiver_bulk_status() + print("TEST 8 - sfp bulk status for port:", physical_port, trans_status) + + threshold = chassis.get_sfp(physical_port).get_transceiver_threshold_info() + print("TEST 9 - sfp bulk status for port:", physical_port, threshold) + + return + + +if __name__ == '__main__': + main() diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-thermal.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-thermal.py new file mode 100755 index 000000000000..9e99b0da3f41 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/test/test-thermal.py @@ -0,0 +1,25 @@ +#!/usr/bin/python + +from sonic_platform.chassis import Chassis + + +def main(): + print("-------------------------") + print("Chassis Thermal Unit Test") + print("-------------------------") + + chassis = Chassis() + + for thermal in chassis.get_all_thermals(): + print(" Name:", thermal.get_name()) + print(" Presence: {}, Status: {}".format(thermal.get_presence(), + thermal.get_status())) + print(" Model: {}, Serial: {}".format(thermal.get_model(), + thermal.get_serial())) + print(" Temperature: {}C, High Threshold: {}C\n".format(thermal.get_temperature(), + thermal.get_high_threshold())) + return + + +if __name__ == '__main__': + main() diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal.py new file mode 100644 index 000000000000..528a6e49d924 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal.py @@ -0,0 +1,243 @@ +######################################################################## +# Nokia IXS7215 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Thermals' information which are available in the platform +# +######################################################################## + + +try: + import os + from sonic_platform_base.thermal_base import ThermalBase + from sonic_py_common import logger +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +sonic_logger = logger.Logger('thermal') + +class Thermal(ThermalBase): + """Nokia platform-specific Thermal class""" + + I2C_CLASS_DIR = "/sys/class/i2c-adapter/" + I2C_DEV_MAPPING = (['i2c-0/0-004a/hwmon/', 1], + ['i2c-0/0-004b/hwmon/', 1], + ['i2c-0/0-002e/', 1], + ['i2c-0/0-002e/', 2], + ['i2c-0/0-002e/', 3]) + + HWMON_CLASS_DIR = "/sys/class/hwmon/" + + THERMAL_NAME = ("PCB PHY", "PCB MAC", + "ADT7473-CPU", "ADT7473-LOC", "ADT7473-MAC", + "CPU Core") + + def __init__(self, thermal_index): + self.index = thermal_index + 1 + self.is_psu_thermal = False + self.dependency = None + self.thermal_high_threshold_file = None + # PCB temperature sensors + if self.index < 3: + i2c_path = self.I2C_CLASS_DIR + self.I2C_DEV_MAPPING[self.index - 1][0] + sensor_index = self.I2C_DEV_MAPPING[self.index - 1][1] + sensor_max_suffix = "max" + sensor_crit_suffix = None + hwmon_node = os.listdir(i2c_path)[0] + self.SENSOR_DIR = i2c_path + hwmon_node + '/' + + # ADT7473 temperature sensors + elif self.index < 6: + i2c_path = self.I2C_CLASS_DIR + self.I2C_DEV_MAPPING[self.index - 1][0] + sensor_index = self.I2C_DEV_MAPPING[self.index - 1][1] + sensor_max_suffix = "max" + sensor_crit_suffix = "crit" + self.SENSOR_DIR = i2c_path + + # Armada 38x SOC temperature sensor + else: + dev_path = self.HWMON_CLASS_DIR + sensor_index = 1 + sensor_max_suffix = None + sensor_crit_suffix = None + hwmon_node = os.listdir(dev_path)[0] + self.SENSOR_DIR = dev_path + hwmon_node + '/' + + # sysfs file for current temperature value + self.thermal_temperature_file = self.SENSOR_DIR \ + + "temp{}_input".format(sensor_index) + + # sysfs file for high threshold value if supported for this sensor + if sensor_max_suffix: + self.thermal_high_threshold_file = self.SENSOR_DIR \ + + "temp{}_{}".format(sensor_index, sensor_max_suffix) + else: + self.thermal_high_threshold_file = None + + # sysfs file for crit high threshold value if supported for this sensor + if sensor_crit_suffix: + self.thermal_high_crit_threshold_file = self.SENSOR_DIR \ + + "temp{}_{}".format(sensor_index, sensor_crit_suffix) + else: + self.thermal_high_crit_threshold_file = None + + def _read_sysfs_file(self, sysfs_file): + # On successful read, returns the value read from given + # sysfs_file and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(sysfs_file)): + return rv + + try: + with open(sysfs_file, 'r') as fd: + rv = fd.read() + except Exception as e: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + + def get_name(self): + """ + Retrieves the name of the thermal + + Returns: + string: The name of the thermal + """ + return self.THERMAL_NAME[self.index - 1] + + def get_presence(self): + """ + Retrieves the presence of the thermal + + Returns: + bool: True if thermal is present, False if not + """ + if self.dependency: + return self.dependency.get_presence() + else: + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the Thermal + + Returns: + string: Model/part number of Thermal + """ + return 'NA' + + def get_serial(self): + """ + Retrieves the serial number of the Thermal + + Returns: + string: Serial number of Thermal + """ + return 'NA' + + def get_status(self): + """ + Retrieves the operational status of the thermal + + Returns: + A boolean value, True if thermal is operating properly, + False if not + """ + if self.dependency: + return self.dependency.get_status() + else: + return True + + def get_temperature(self): + """ + Retrieves current temperature reading from thermal + + Returns: + A float number of current temperature in Celsius up to + nearest thousandth of one degree Celsius, e.g. 30.125 + """ + thermal_temperature = self._read_sysfs_file( + self.thermal_temperature_file) + if (thermal_temperature != 'ERR'): + thermal_temperature = float(thermal_temperature) / 1000 + else: + thermal_temperature = 0 + + return float("{:.3f}".format(thermal_temperature)) + + def get_high_threshold(self): + """ + Retrieves the high threshold temperature of thermal + + Returns: + A float number, the high threshold temperature of thermal in + Celsius up to nearest thousandth of one degree Celsius, + e.g. 30.125 + """ + # Not implemented for this sensor + if not self.thermal_high_threshold_file: + raise NotImplementedError + + thermal_high_threshold = self._read_sysfs_file( + self.thermal_high_threshold_file) + if (thermal_high_threshold != 'ERR'): + thermal_high_threshold = float(thermal_high_threshold) / 1000 + else: + thermal_high_threshold = 0.0 + + return float("{:.3f}".format(thermal_high_threshold)) + + def set_high_threshold(self, temperature): + """ + Sets the high threshold temperature of thermal + + Args : + temperature: A float number up to nearest thousandth of one + degree Celsius, e.g. 30.125 + Returns: + A boolean, True if threshold is set successfully, False if + not + """ + # Thermal threshold values are pre-defined based on HW. + return False + + def get_high_critical_threshold(self): + """ + Retrieves the high critical threshold temperature of thermal + + Returns: + A float number, the high critical threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + + # Not implemented for this sensor + if not self.thermal_high_crit_threshold_file: + raise NotImplementedError + + thermal_high_crit_threshold = self._read_sysfs_file( + self.thermal_high_crit_threshold_file) + if (thermal_high_crit_threshold != 'ERR'): + thermal_high_crit_threshold = float(thermal_high_crit_threshold) / 1000 + else: + thermal_high_crit_threshold = 0.0 + + return float("{:.3f}".format(thermal_high_crit_threshold)) + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device + Returns: + integer: The 1-based relative physical position in parent device + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return False diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal_actions.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal_actions.py new file mode 100644 index 000000000000..a829fd80a5ba --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal_actions.py @@ -0,0 +1,192 @@ +from sonic_platform_base.sonic_thermal_control.thermal_action_base import ThermalPolicyActionBase +from sonic_platform_base.sonic_thermal_control.thermal_json_object import thermal_json_object + +from sonic_py_common import logger + +sonic_logger = logger.Logger('thermal_actions') + + +class SetFanSpeedAction(ThermalPolicyActionBase): + """ + Base thermal action class to set speed for fans + """ + # JSON field definition + JSON_FIELD_SPEED = 'speed' + JSON_FIELD_DEFAULT_SPEED = 'default_speed' + JSON_FIELD_HIGHTEMP_SPEED = 'hightemp_speed' + + def __init__(self): + """ + Constructor of SetFanSpeedAction + """ + self.default_speed = 50 + self.hightemp_speed = 100 + self.speed = self.default_speed + + def load_from_json(self, json_obj): + """ + Construct SetFanSpeedAction via JSON. JSON example: + { + "type": "fan.all.set_speed" + "speed": "100" + } + :param json_obj: A JSON object representing a SetFanSpeedAction action. + :return: + """ + if SetFanSpeedAction.JSON_FIELD_SPEED in json_obj: + speed = float(json_obj[SetFanSpeedAction.JSON_FIELD_SPEED]) + if speed < 0 or speed > 100: + raise ValueError('SetFanSpeedAction invalid speed value {} in JSON policy file, valid value should be [0, 100]'. + format(speed)) + self.speed = float(json_obj[SetFanSpeedAction.JSON_FIELD_SPEED]) + else: + raise ValueError('SetFanSpeedAction missing mandatory field {} in JSON policy file'. + format(SetFanSpeedAction.JSON_FIELD_SPEED)) + + @classmethod + def set_all_fan_speed(cls, thermal_info_dict, speed): + from .thermal_infos import FanInfo + if FanInfo.INFO_NAME in thermal_info_dict and isinstance(thermal_info_dict[FanInfo.INFO_NAME], FanInfo): + fan_info_obj = thermal_info_dict[FanInfo.INFO_NAME] + for fan in fan_info_obj.get_presence_fans(): + fan.set_speed(int(speed)) + + +@thermal_json_object('fan.all.set_speed') +class SetAllFanSpeedAction(SetFanSpeedAction): + """ + Action to set speed for all fans + """ + def execute(self, thermal_info_dict): + """ + Set speed for all fans + :param thermal_info_dict: A dictionary stores all thermal information. + :return: + """ + SetAllFanSpeedAction.set_all_fan_speed(thermal_info_dict, self.speed) + + +@thermal_json_object('thermal.temp_check_and_set_all_fan_speed') +class ThermalRecoverAction(SetFanSpeedAction): + """ + Action to check thermal sensor temperature change status and set speed for all fans + """ + + def load_from_json(self, json_obj): + """ + Construct ThermalRecoverAction via JSON. JSON example: + { + "type": "thermal.temp_check_and_set_all_fan_speed" + "default_speed": "50" + "hightemp_speed": "100" + } + :param json_obj: A JSON object representing a ThermalRecoverAction action. + :return: + """ + if SetFanSpeedAction.JSON_FIELD_DEFAULT_SPEED in json_obj: + default_speed = float(json_obj[SetFanSpeedAction.JSON_FIELD_DEFAULT_SPEED]) + if default_speed < 0 or default_speed > 100: + raise ValueError('SetFanSpeedAction invalid default speed value {} in JSON policy file, valid value should be [0, 100]'. + format(default_speed)) + self.default_speed = float(json_obj[SetFanSpeedAction.JSON_FIELD_DEFAULT_SPEED]) + else: + raise ValueError('SetFanSpeedAction missing mandatory field {} in JSON policy file'. + format(SetFanSpeedAction.JSON_FIELD_DEFAULT_SPEED)) + + if SetFanSpeedAction.JSON_FIELD_HIGHTEMP_SPEED in json_obj: + hightemp_speed = float(json_obj[SetFanSpeedAction.JSON_FIELD_HIGHTEMP_SPEED]) + if hightemp_speed < 0 or hightemp_speed > 100: + raise ValueError('SetFanSpeedAction invalid hightemp speed value {} in JSON policy file, valid value should be [0, 100]'. + format(hightemp_speed)) + self.hightemp_speed = float(json_obj[SetFanSpeedAction.JSON_FIELD_HIGHTEMP_SPEED]) + else: + raise ValueError('SetFanSpeedAction missing mandatory field {} in JSON policy file'. + format(SetFanSpeedAction.JSON_FIELD_HIGHTEMP_SPEED)) + + sonic_logger.log_warning("ThermalRecoverAction: default: {}, hightemp: {}".format(self.default_speed, self.hightemp_speed)) + + def execute(self, thermal_info_dict): + """ + Check check thermal sensor temperature change status and set speed for all fans + :param thermal_info_dict: A dictionary stores all thermal information. + :return: + """ + from .thermal_infos import ThermalInfo + if ThermalInfo.INFO_NAME in thermal_info_dict and \ + isinstance(thermal_info_dict[ThermalInfo.INFO_NAME], ThermalInfo): + + thermal_info_obj = thermal_info_dict[ThermalInfo.INFO_NAME] + if thermal_info_obj.is_warm_up_and_over_high_threshold(): + ThermalRecoverAction.set_all_fan_speed(thermal_info_dict, self.hightemp_speed) + elif thermal_info_obj.is_cool_down_and_below_low_threshold(): + ThermalRecoverAction.set_all_fan_speed(thermal_info_dict, self.default_speed) + + +@thermal_json_object('switch.shutdown') +class SwitchPolicyAction(ThermalPolicyActionBase): + """ + Base class for thermal action. Once all thermal conditions in a thermal policy are matched, + all predefined thermal action will be executed. + """ + def execute(self, thermal_info_dict): + """ + Take action when thermal condition matches. For example, adjust speed of fan or shut + down the switch. + :param thermal_info_dict: A dictionary stores all thermal information. + :return: + """ + sonic_logger.log_warning("Alarm for temperature critical is detected, reboot Device") + # import os + # os.system('reboot') + + +@thermal_json_object('thermal_control.control') +class ControlThermalAlgoAction(ThermalPolicyActionBase): + """ + Action to control the thermal control algorithm + """ + # JSON field definition + JSON_FIELD_STATUS = 'status' + + def __init__(self): + self.status = True + + def load_from_json(self, json_obj): + """ + Construct ControlThermalAlgoAction via JSON. JSON example: + { + "type": "thermal_control.control" + "status": "true" + } + :param json_obj: A JSON object representing a ControlThermalAlgoAction action. + :return: + """ + if ControlThermalAlgoAction.JSON_FIELD_STATUS in json_obj: + status_str = json_obj[ControlThermalAlgoAction.JSON_FIELD_STATUS].lower() + if status_str == 'true': + self.status = True + elif status_str == 'false': + self.status = False + else: + raise ValueError('Invalid {} field value, please specify true of false'. + format(ControlThermalAlgoAction.JSON_FIELD_STATUS)) + else: + raise ValueError('ControlThermalAlgoAction ' + 'missing mandatory field {} in JSON policy file'. + format(ControlThermalAlgoAction.JSON_FIELD_STATUS)) + + def execute(self, thermal_info_dict): + """ + Disable thermal control algorithm + :param thermal_info_dict: A dictionary stores all thermal information. + :return: + """ + from .thermal_infos import ChassisInfo + if ChassisInfo.INFO_NAME in thermal_info_dict: + chassis_info_obj = thermal_info_dict[ChassisInfo.INFO_NAME] + chassis = chassis_info_obj.get_chassis() + thermal_manager = chassis.get_thermal_manager() + if self.status: + thermal_manager.start_thermal_control_algorithm() + else: + thermal_manager.stop_thermal_control_algorithm() diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal_conditions.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal_conditions.py new file mode 100644 index 000000000000..4923d63d746b --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal_conditions.py @@ -0,0 +1,81 @@ +from sonic_platform_base.sonic_thermal_control.thermal_condition_base import ThermalPolicyConditionBase +from sonic_platform_base.sonic_thermal_control.thermal_json_object import thermal_json_object + + +class FanCondition(ThermalPolicyConditionBase): + def get_fan_info(self, thermal_info_dict): + from .thermal_infos import FanInfo + if FanInfo.INFO_NAME in thermal_info_dict and isinstance(thermal_info_dict[FanInfo.INFO_NAME], FanInfo): + return thermal_info_dict[FanInfo.INFO_NAME] + else: + return None + + +@thermal_json_object('fan.any.absence') +class AnyFanAbsenceCondition(FanCondition): + def is_match(self, thermal_info_dict): + fan_info_obj = self.get_fan_info(thermal_info_dict) + return len(fan_info_obj.get_absence_fans()) > 0 if fan_info_obj else False + + +@thermal_json_object('fan.all.absence') +class AllFanAbsenceCondition(FanCondition): + def is_match(self, thermal_info_dict): + fan_info_obj = self.get_fan_info(thermal_info_dict) + return len(fan_info_obj.get_presence_fans()) == 0 if fan_info_obj else False + + +@thermal_json_object('fan.all.presence') +class AllFanPresenceCondition(FanCondition): + def is_match(self, thermal_info_dict): + fan_info_obj = self.get_fan_info(thermal_info_dict) + return len(fan_info_obj.get_absence_fans()) == 0 if fan_info_obj else False + + +class ThermalCondition(ThermalPolicyConditionBase): + def get_thermal_info(self, thermal_info_dict): + from .thermal_infos import ThermalInfo + if ThermalInfo.INFO_NAME in thermal_info_dict and isinstance(thermal_info_dict[ThermalInfo.INFO_NAME], ThermalInfo): + return thermal_info_dict[ThermalInfo.INFO_NAME] + else: + return None + + +@thermal_json_object('thermal.over.high_critical_threshold') +class ThermalOverHighCriticalCondition(ThermalCondition): + def is_match(self, thermal_info_dict): + thermal_info_obj = self.get_thermal_info(thermal_info_dict) + if thermal_info_obj: + return thermal_info_obj.is_over_high_critical_threshold() + else: + return False + + +class PsuCondition(ThermalPolicyConditionBase): + def get_psu_info(self, thermal_info_dict): + from .thermal_infos import PsuInfo + if PsuInfo.INFO_NAME in thermal_info_dict and isinstance(thermal_info_dict[PsuInfo.INFO_NAME], PsuInfo): + return thermal_info_dict[PsuInfo.INFO_NAME] + else: + return None + + +@thermal_json_object('psu.any.absence') +class AnyPsuAbsenceCondition(PsuCondition): + def is_match(self, thermal_info_dict): + psu_info_obj = self.get_psu_info(thermal_info_dict) + return len(psu_info_obj.get_absence_psus()) > 0 if psu_info_obj else False + + +@thermal_json_object('psu.all.absence') +class AllPsuAbsenceCondition(PsuCondition): + def is_match(self, thermal_info_dict): + psu_info_obj = self.get_psu_info(thermal_info_dict) + return len(psu_info_obj.get_presence_psus()) == 0 if psu_info_obj else False + + +@thermal_json_object('psu.all.presence') +class AllPsuPresenceCondition(PsuCondition): + def is_match(self, thermal_info_dict): + psu_info_obj = self.get_psu_info(thermal_info_dict) + return len(psu_info_obj.get_absence_psus()) == 0 if psu_info_obj else False diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal_infos.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal_infos.py new file mode 100644 index 000000000000..cd0a0591cd2a --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal_infos.py @@ -0,0 +1,210 @@ +from sonic_platform_base.sonic_thermal_control.thermal_info_base import ThermalPolicyInfoBase +from sonic_platform_base.sonic_thermal_control.thermal_json_object import thermal_json_object + + +@thermal_json_object('fan_info') +class FanInfo(ThermalPolicyInfoBase): + """ + Fan information needed by thermal policy + """ + + # Fan information name + INFO_NAME = 'fan_info' + + def __init__(self): + self._absence_fans = set() + self._presence_fans = set() + self._status_changed = False + + def collect(self, chassis): + """ + Collect absence and presence fans. + :param chassis: The chassis object + :return: + """ + self._status_changed = False + for fan in chassis.get_all_fans(): + if fan.get_presence() and fan not in self._presence_fans: + self._presence_fans.add(fan) + self._status_changed = True + if fan in self._absence_fans: + self._absence_fans.remove(fan) + elif not fan.get_presence() and fan not in self._absence_fans: + self._absence_fans.add(fan) + self._status_changed = True + if fan in self._presence_fans: + self._presence_fans.remove(fan) + + def get_absence_fans(self): + """ + Retrieves absence fans + :return: A set of absence fans + """ + return self._absence_fans + + def get_presence_fans(self): + """ + Retrieves presence fans + :return: A set of presence fans + """ + return self._presence_fans + + def is_status_changed(self): + """ + Retrieves if the status of fan information changed + :return: True if status changed else False + """ + return self._status_changed + + +@thermal_json_object('thermal_info') +class ThermalInfo(ThermalPolicyInfoBase): + """ + Thermal information needed by thermal policy + """ + + # Fan information name + INFO_NAME = 'thermal_info' + + def __init__(self): + self.init = False + self._old_avg_temp = 0 + self._current_avg_temp = 0 + self._high_crital_threshold = 75 + self._high_threshold = 45 + self._low_threshold = 40 + + def collect(self, chassis): + """ + Collect thermal sensor temperature change status + :param chassis: The chassis object + :return: + """ + self._temps = [] + self._over_high_critical_threshold = False + self._warm_up_and_over_high_threshold = False + self._cool_down_and_below_low_threshold = False + + # Calculate average temp within the device + temp = 0 + num_of_thermals = chassis.get_num_thermals() + for index in range(num_of_thermals): + self._temps.insert(index, chassis.get_thermal(index).get_temperature()) + temp += self._temps[index] + + self._current_avg_temp = temp / num_of_thermals + + # Special case if first time + if self.init is False: + self._old_avg_temp = self._current_avg_temp + self.init = True + + # Check if new average temp exceeds high threshold value + if self._current_avg_temp >= self._old_avg_temp and self._current_avg_temp >= self._high_threshold: + self._warm_up_and_over_high_threshold = True + + # Check if new average temp exceeds low threshold value + if self._current_avg_temp <= self._old_avg_temp and self._current_avg_temp <= self._low_threshold: + self._cool_down_and_below_low_threshold = True + + self._old_avg_temp = self._current_avg_temp + + def is_warm_up_and_over_high_threshold(self): + """ + Retrieves if the temperature is warm up and over high threshold + :return: True if the temperature is warm up and over high threshold else False + """ + return self._warm_up_and_over_high_threshold + + def is_cool_down_and_below_low_threshold(self): + """ + Retrieves if the temperature is cold down and below low threshold + :return: True if the temperature is cold down and below low threshold else False + """ + return self._cool_down_and_below_low_threshold + + def is_over_high_critical_threshold(self): + """ + Retrieves if the temperature is over high critical threshold + :return: True if the temperature is over high critical threshold else False + """ + return self._over_high_critical_threshold + + +@thermal_json_object('psu_info') +class PsuInfo(ThermalPolicyInfoBase): + """ + PSU information needed by thermal policy + """ + INFO_NAME = 'psu_info' + + def __init__(self): + self._absence_psus = set() + self._presence_psus = set() + self._status_changed = False + + def collect(self, chassis): + """ + Collect absence and presence PSUs. + :param chassis: The chassis object + :return: + """ + self._status_changed = False + for psu in chassis.get_all_psus(): + if psu.get_presence() and psu.get_powergood_status() and psu not in self._presence_psus: + self._presence_psus.add(psu) + self._status_changed = True + if psu in self._absence_psus: + self._absence_psus.remove(psu) + elif (not psu.get_presence() or not psu.get_powergood_status()) and psu not in self._absence_psus: + self._absence_psus.add(psu) + self._status_changed = True + if psu in self._presence_psus: + self._presence_psus.remove(psu) + + def get_absence_psus(self): + """ + Retrieves presence PSUs + :return: A set of absence PSUs + """ + return self._absence_psus + + def get_presence_psus(self): + """ + Retrieves presence PSUs + :return: A set of presence fans + """ + return self._presence_psus + + def is_status_changed(self): + """ + Retrieves if the status of PSU information changed + :return: True if status changed else False + """ + return self._status_changed + + +@thermal_json_object('chassis_info') +class ChassisInfo(ThermalPolicyInfoBase): + """ + Chassis information needed by thermal policy + """ + INFO_NAME = 'chassis_info' + + def __init__(self): + self._chassis = None + + def collect(self, chassis): + """ + Collect platform chassis. + :param chassis: The chassis object + :return: + """ + self._chassis = chassis + + def get_chassis(self): + """ + Retrieves platform chassis object + :return: A platform chassis object. + """ + return self._chassis diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal_manager.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal_manager.py new file mode 100644 index 000000000000..967cf175934e --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/thermal_manager.py @@ -0,0 +1,49 @@ +from sonic_platform_base.sonic_thermal_control.thermal_manager_base import ThermalManagerBase +from .thermal_actions import * +from .thermal_conditions import * +from .thermal_infos import * + + +class ThermalManager(ThermalManagerBase): + THERMAL_ALGORITHM_CONTROL_PATH = '/var/run/hw-management/config/suspend' + + @classmethod + def start_thermal_control_algorithm(cls): + """ + Start thermal control algorithm + + Returns: + bool: True if set success, False if fail. + """ + cls._control_thermal_control_algorithm(False) + + @classmethod + def stop_thermal_control_algorithm(cls): + """ + Stop thermal control algorithm + + Returns: + bool: True if set success, False if fail. + """ + cls._control_thermal_control_algorithm(True) + + @classmethod + def _control_thermal_control_algorithm(cls, suspend): + """ + Control thermal control algorithm + + Args: + suspend: Bool, indicate suspend the algorithm or not + + Returns: + bool: True if set success, False if fail. + """ + status = True + write_value = 1 if suspend else 0 + try: + with open(cls.THERMAL_ALGORITHM_CONTROL_PATH, 'w') as control_file: + control_file.write(str(write_value)) + except (ValueError, IOError): + status = False + + return status diff --git a/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/watchdog.py b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/watchdog.py new file mode 100644 index 000000000000..75ec3ab177ae --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/7215/sonic_platform/watchdog.py @@ -0,0 +1,135 @@ +""" +ARMADA 38x Watchdog - one 32 bit cpu watchdog per cpu - 2 watchdogs ( page 662) + +Module contains an implementation of SONiC Platform Base API and +provides access to hardware watchdog +""" + +import os +import fcntl +import array + +from sonic_platform_base.watchdog_base import WatchdogBase +from sonic_py_common import logger + +""" ioctl constants """ +IO_READ = 0x80000000 +IO_SIZE_INT = 0x00040000 +IO_TYPE_WATCHDOG = ord('W') << 8 + +WDR_INT = IO_READ | IO_SIZE_INT | IO_TYPE_WATCHDOG + +""" Watchdog ioctl commands """ +WDIOC_SETOPTIONS = 4 | WDR_INT +WDIOC_KEEPALIVE = 5 | WDR_INT +WDIOC_GETTIMEOUT = 7 | WDR_INT + +""" Watchdog status constants """ +WDIOS_DISABLECARD = 0x0001 +WDIOS_ENABLECARD = 0x0002 + +""" watchdog sysfs """ +WD_SYSFS_PATH = "/sys/class/watchdog/" + +WD_COMMON_ERROR = -1 + +sonic_logger = logger.Logger() + + +class WatchdogImplBase(WatchdogBase): + """ + Base class that implements common logic for interacting + with watchdog using ioctl commands + """ + + def __init__(self, wd_device_path): + """ + Open a watchdog handle + @param wd_device_path Path to watchdog device + """ + + self.watchdog_path = wd_device_path + self.watchdog = os.open(self.watchdog_path, os.O_WRONLY) + + # Opening a watchdog descriptor starts + # watchdog timer; by default it should be stopped + self._disablewatchdog() + self.armed = False + self.timeout = self._gettimeout() + + def disarm(self): + """ + Disarm the hardware watchdog + + Returns: + A boolean, True if watchdog is disarmed successfully, False + if not + """ + sonic_logger.log_info(" Debug disarm watchdog ") + + try: + self._disablewatchdog() + self.armed = False + self.timeout = 0 + except IOError: + return False + + return True + + def _disablewatchdog(self): + """ + Turn off the watchdog timer + """ + + req = array.array('h', [WDIOS_DISABLECARD]) + fcntl.ioctl(self.watchdog, WDIOC_SETOPTIONS, req, False) + + def _gettimeout(self): + """ + Get watchdog timeout + @return watchdog timeout + """ + + req = array.array('I', [0]) + fcntl.ioctl(self.watchdog, WDIOC_GETTIMEOUT, req, True) + + return int(req[0]) + + def arm(self, seconds): + """ + Implements arm WatchdogBase API + """ + sonic_logger.log_info(" Debug arm watchdog4 ") + ret = WD_COMMON_ERROR + if seconds < 0: + return ret + + try: + if self.timeout != seconds: + self.timeout = self._settimeout(seconds) + if self.armed: + self._keepalive() + else: + sonic_logger.log_info(" Debug arm watchdog5 ") + self._enablewatchdog() + self.armed = True + ret = self.timeout + except IOError: + pass + + return ret + + def _enablewatchdog(self): + """ + Turn on the watchdog timer + """ + + req = array.array('h', [WDIOS_ENABLECARD]) + fcntl.ioctl(self.watchdog, WDIOC_SETOPTIONS, req, False) + + def _keepalive(self): + """ + Keep alive watchdog timer + """ + + fcntl.ioctl(self.watchdog, WDIOC_KEEPALIVE) diff --git a/platform/marvell-armhf/sonic-platform-nokia/debian/changelog b/platform/marvell-armhf/sonic-platform-nokia/debian/changelog new file mode 100755 index 000000000000..f4c860fab861 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/debian/changelog @@ -0,0 +1,5 @@ +sonic-platform-nokia-7215 (1.0) unstable; urgency=low + + * Add support for nokia-7215. + + -- Nokia Wed, 15 Apr 2020 09:35:58 +0800 diff --git a/platform/marvell-armhf/sonic-platform-nokia/debian/compat b/platform/marvell-armhf/sonic-platform-nokia/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/debian/compat @@ -0,0 +1 @@ +9 diff --git a/platform/marvell-armhf/sonic-platform-nokia/debian/control b/platform/marvell-armhf/sonic-platform-nokia/debian/control new file mode 100755 index 000000000000..0da04ac89842 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/debian/control @@ -0,0 +1,15 @@ +Source: sonic-platform-nokia-7215 +Section: unknown +Priority: optional +Maintainer: Nokia +Build-Depends: debhelper (>=9) +Standards-Version: 3.9.6 +Homepage: +#Vcs-Git: git://anonscm.debian.org/collab-maint/sonic-platform-et6448m.git +#Vcs-Browser: https://anonscm.debian.org/cgit/collab-maint/sonic-platform-et6448m.git + +Package: sonic-platform-nokia-7215 +Architecture: armhf +Depends: ${misc:Depends} +Description: + diff --git a/platform/marvell-armhf/sonic-platform-nokia/debian/rules b/platform/marvell-armhf/sonic-platform-nokia/debian/rules new file mode 100755 index 000000000000..b7592c2b51e9 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/debian/rules @@ -0,0 +1,64 @@ +#!/usr/bin/make -f +# See debhelper(7) (uncomment to enable) +# output every command that modifies files on the build system. +#export DH_VERBOSE = 1 + +include /usr/share/dpkg/pkg-info.mk +#-------------------------------------------------------- + +PACKAGE_PRE_NAME := sonic-platform-nokia +MOD_SRC_DIR:= $(shell pwd) +MODULE_DIRS:= 7215 +UTILS_DIR := utils +SERVICE_DIR := service +PLATFORM_DIR := sonic_platform + +%: + dh $@ --with systemd,python3 --buildsystem=pybuild + +clean: + dh_testdir + dh_testroot + dh_clean + +build: + (for mod in $(MODULE_DIRS); do \ + python3 $${mod}/setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}; \ + done) + +binary: binary-arch binary-indep + # Nothing to do + +binary-arch: + # Nothing to do + +binary-indep: + dh_testdir + dh_installdirs + + # Custom package commands + (for mod in $(MODULE_DIRS); do \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} /usr/local/bin; \ + cp $(MOD_SRC_DIR)/$${mod}/$(SERVICE_DIR)/*.service debian/$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system/; \ + cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/* debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin/; \ + python3 $${mod}/setup.py install --root=$(MOD_SRC_DIR)/debian/$(PACKAGE_PRE_NAME)-$${mod} --install-layout=deb; \ + done) + + # Resuming debhelper scripts + dh_testroot + dh_install + dh_installchangelogs + dh_installdocs + dh_systemd_enable + dh_installinit + dh_systemd_start + dh_link + dh_fixperms + dh_compress + dh_strip + dh_installdeb + dh_gencontrol + dh_md5sums + dh_builddeb + +.PHONY: build binary binary-arch binary-indep clean diff --git a/platform/marvell-armhf/sonic-platform-nokia/debian/sonic-platform-nokia-7215.install b/platform/marvell-armhf/sonic-platform-nokia/debian/sonic-platform-nokia-7215.install new file mode 100644 index 000000000000..ea347d79be3a --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/debian/sonic-platform-nokia-7215.install @@ -0,0 +1,6 @@ +nokia-7215_plt_setup.sh usr/sbin +7215/scripts/nokia-7215init.sh usr/local/bin +7215/service/nokia-7215init.service etc/systemd/system +7215/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/armhf-nokia_ixs7215_52x-r0 +entropy.py etc/ +inband_mgmt.sh etc/ diff --git a/platform/marvell-armhf/sonic-platform-nokia/debian/sonic-platform-nokia-7215.postinst b/platform/marvell-armhf/sonic-platform-nokia/debian/sonic-platform-nokia-7215.postinst new file mode 100644 index 000000000000..de91cedb4ec7 --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/debian/sonic-platform-nokia-7215.postinst @@ -0,0 +1,11 @@ +#!/bin/sh +# postinst script for sonic-platform-nokia-7215 +# +# see: dh_installdeb(1) + +sh /usr/sbin/nokia-7215_plt_setup.sh +systemctl enable nokia-7215init.service +systemctl start nokia-7215init.service + +exit 0 + diff --git a/platform/marvell-armhf/sonic-platform-nokia/entropy.py b/platform/marvell-armhf/sonic-platform-nokia/entropy.py new file mode 100644 index 000000000000..338e2ad9bcea --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/entropy.py @@ -0,0 +1,19 @@ +#!/usr/bin/python +import fcntl, struct +import time +from os import path + +RNDADDENTROPY=0x40085203 + +def avail(): + with open("/proc/sys/kernel/random/entropy_avail", mode='r') as avail: + return int(avail.read()) + +if path.exists("/proc/sys/kernel/random/entropy_avail"): + while 1: + while avail() < 2048: + with open('/dev/urandom', 'rb') as urnd, open("/dev/random", mode='wb') as rnd: + d = urnd.read(512) + t = struct.pack('ii', 4 * len(d), len(d)) + d + fcntl.ioctl(rnd, RNDADDENTROPY, t) + time.sleep(30) diff --git a/platform/marvell-armhf/sonic-platform-nokia/inband_mgmt.sh b/platform/marvell-armhf/sonic-platform-nokia/inband_mgmt.sh new file mode 100644 index 000000000000..25455d16ecbf --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/inband_mgmt.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +#inband_mgmt + +inband_mgmt(){ + # In this platform, one of the network ports is used as mgmt interface. + # This script periodically monitors inband management port eth0 and + # assigns IP address to eth0 if needed. + if [ ! -f /host/machine.conf ]; then + exit 0 + fi + #wait for n/w port init to complete + sleep 60 + while :; do + ip -br link show eth0 2> /dev/null + if [ $? -eq 0 ]; then + ip address show eth0 | grep -qw "inet" 2>/dev/null + if [ $? -ne 0 ]; then + ifconfig eth0 down + systemctl restart networking + fi + sleep 120 + else + sleep 3 + fi + done +} +(inband_mgmt > /dev/null)& diff --git a/platform/marvell-armhf/sonic-platform-nokia/nokia-7215_plt_setup.sh b/platform/marvell-armhf/sonic-platform-nokia/nokia-7215_plt_setup.sh new file mode 100755 index 000000000000..8301999d0d0a --- /dev/null +++ b/platform/marvell-armhf/sonic-platform-nokia/nokia-7215_plt_setup.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +fw_uboot_env_cfg() +{ + echo "Setting up U-Boot environment..." + + MACH_FILE="/host/machine.conf" + PLATFORM=`sed -n 's/onie_platform=\(.*\)/\1/p' $MACH_FILE` + + if [ "$PLATFORM" = "armhf-nokia_ixs7215_52x-r0" ]; then + # Ixs7215 / IPD6448M board Uboot ENV offset + FW_ENV_DEFAULT='/dev/mtd0 0x00100000 0x10000 0x10000' + + demo_part=$(sgdisk -p /dev/sda | grep -e "SONiC-OS") + if [ -z "$demo_part" ]; then + # ET6448M Board - For Backward compatibility + FW_ENV_DEFAULT='/dev/mtd0 0x00500000 0x80000 0x100000 8' + fi + else + FW_ENV_DEFAULT='/dev/mtd0 0x00500000 0x80000 0x100000 8' + fi + + echo "Using pre-configured uboot env" + echo $FW_ENV_DEFAULT > /etc/fw_env.config + +} + + +main() +{ + fw_uboot_env_cfg + echo "Nokia-IXS7215: /dev/mtd0 FW_ENV_DEFAULT" + + python /etc/entropy.py & + /bin/sh /etc/inband_mgmt.sh +} + +main $@ diff --git a/platform/marvell/docker-syncd-mrvl-rpc.mk b/platform/marvell/docker-syncd-mrvl-rpc.mk index 0e1b65f2fd5d..c3ce6c10119c 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/marvell/docker-syncd-mrvl-rpc/Dockerfile.j2 b/platform/marvell/docker-syncd-mrvl-rpc/Dockerfile.j2 index cea067d2abf6..118be5e1c5f2 100644 --- a/platform/marvell/docker-syncd-mrvl-rpc/Dockerfile.j2 +++ b/platform/marvell/docker-syncd-mrvl-rpc/Dockerfile.j2 @@ -11,11 +11,6 @@ debs/ RUN apt-get purge -y syncd -RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; } ; \ -{% for deb in docker_syncd_mrvl_rpc_debs.split(' ') -%} -dpkg_apt debs/{{ deb }}{{'; '}} -{%- endfor %} - ## Pre-install the fundamental packages RUN apt-get update \ && apt-get -y install \ @@ -27,7 +22,16 @@ RUN apt-get update \ python-dev \ wget \ cmake \ - && wget https://github.com/nanomsg/nanomsg/archive/1.0.0.tar.gz \ + libqt5core5a \ + libqt5network5 \ + libboost-atomic1.71.0 + +RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; } ; \ +{% for deb in docker_syncd_mrvl_rpc_debs.split(' ') -%} +dpkg_apt debs/{{ deb }}{{'; '}} +{%- endfor %} + +RUN wget https://github.com/nanomsg/nanomsg/archive/1.0.0.tar.gz \ && tar xvfz 1.0.0.tar.gz \ && cd nanomsg-1.0.0 \ && mkdir -p build \ @@ -48,4 +52,4 @@ RUN apt-get update \ COPY ["ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/marvell/docker-syncd-mrvl.mk b/platform/marvell/docker-syncd-mrvl.mk index 97b7eab19895..d6d7d032b8ac 100644 --- a/platform/marvell/docker-syncd-mrvl.mk +++ b/platform/marvell/docker-syncd-mrvl.mk @@ -10,6 +10,9 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSAIMETADATA_DBG) \ $(LIBSAIREDIS_DBG) +SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_BASE) +SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_SYNCD_BASE_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/Dockerfile.j2 b/platform/marvell/docker-syncd-mrvl/Dockerfile.j2 index 40973653e8d3..e91231e49791 100755 --- a/platform/marvell/docker-syncd-mrvl/Dockerfile.j2 +++ b/platform/marvell/docker-syncd-mrvl/Dockerfile.j2 @@ -21,7 +21,7 @@ RUN dpkg -i \ debs/{{ deb }}{{' '}} {%- endfor %} -COPY ["start.sh", "syncd.sh", "/usr/bin/"] +COPY ["syncd.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor/"] @@ -30,5 +30,4 @@ COPY ["critical_processes", "/etc/supervisor/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["/usr/bin/supervisord"] - +ENTRYPOINT ["/usr/local/bin/supervisord"] 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 3079618990ed..61e290e3189e 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" - if does not exist for 5 times within 5 cycles then alert +check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/platform/marvell/docker-syncd-mrvl/critical_processes b/platform/marvell/docker-syncd-mrvl/critical_processes index 6082f242b872..bdd6903c5690 100644 --- a/platform/marvell/docker-syncd-mrvl/critical_processes +++ b/platform/marvell/docker-syncd-mrvl/critical_processes @@ -1 +1 @@ -syncd +program:syncd diff --git a/platform/marvell/docker-syncd-mrvl/start.sh b/platform/marvell/docker-syncd-mrvl/start.sh deleted file mode 100755 index 96e2a9128081..000000000000 --- a/platform/marvell/docker-syncd-mrvl/start.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -rm -f /var/run/rsyslogd.pid - -supervisorctl start rsyslogd - -supervisorctl start syncd - diff --git a/platform/marvell/docker-syncd-mrvl/supervisord.conf b/platform/marvell/docker-syncd-mrvl/supervisord.conf index 43de2426f981..94be9dd268f6 100644 --- a/platform/marvell/docker-syncd-mrvl/supervisord.conf +++ b/platform/marvell/docker-syncd-mrvl/supervisord.conf @@ -3,27 +3,29 @@ 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 +[eventlistener:dependent-startup] +command=python2 -m supervisord_dependent_startup autostart=true autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE +buffer_size=25 -[program:start.sh] -command=/usr/bin/start.sh -priority=1 +[eventlistener:supervisor-proc-exit-listener] +command=python2 /usr/bin/supervisor-proc-exit-listener --container-name syncd +events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING autostart=true -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog +autorestart=unexpected [program:rsyslogd] -command=/usr/sbin/rsyslogd -n -priority=2 +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 autostart=false autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true [program:syncd] command=/usr/bin/syncd_start.sh @@ -32,4 +34,5 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog - +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running diff --git a/platform/marvell/rules.mk b/platform/marvell/rules.mk index c01e1e491803..da23e53f26bc 100644 --- a/platform/marvell/rules.mk +++ b/platform/marvell/rules.mk @@ -8,10 +8,12 @@ SONIC_ALL += $(SONIC_ONE_IMAGE) \ $(DOCKER_FPM) \ $(DOCKER_SYNCD_MRVL_RPC) -# Inject mrvl sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(MRVL_FPA) $(MRVL_SAI) +# Inject mrvl sai into syncd +$(SYNCD)_DEPENDS += $(MRVL_FPA) $(MRVL_SAI) +$(SYNCD)_UNINSTALLS += $(MRVL_SAI) + ifeq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV) +$(SYNCD)_DEPENDS += $(LIBSAITHRIFT_DEV) endif # Runtime dependency on mrvl sai is set only for syncd diff --git a/platform/marvell/sai.mk b/platform/marvell/sai.mk index 553188100045..ac05bc8f0470 100644 --- a/platform/marvell/sai.mk +++ b/platform/marvell/sai.mk @@ -4,4 +4,6 @@ export MRVL_SAI_VERSION = 1.5.1 export MRVL_SAI = mrvllibsai_amd64_$(MRVL_SAI_VERSION).deb $(MRVL_SAI)_SRC_PATH = $(PLATFORM_PATH)/sai +$(eval $(call add_conflict_package,$(MRVL_SAI),$(LIBSAIVS_DEV))) + SONIC_MAKE_DEBS += $(MRVL_SAI) diff --git a/platform/mellanox/asic_table.j2 b/platform/mellanox/asic_table.j2 new file mode 100644 index 000000000000..4afc780b0b06 --- /dev/null +++ b/platform/mellanox/asic_table.j2 @@ -0,0 +1,59 @@ +{%- if DEVICE_METADATA is defined and DEVICE_METADATA['localhost']['platform'] is defined %} +{%- set platform = DEVICE_METADATA['localhost']['platform'] %} +{%- else -%} +{%- set platform = "vs-platform" %} +{%- endif -%} + + +[ +{% set platform2asic = { + 'x86_64-mlnx_lssn2700-r0':'MELLANOX-SPECTRUM', + 'x86_64-mlnx_msn2010-r0':'MELLANOX-SPECTRUM', + 'x86_64-mlnx_msn2100-r0':'MELLANOX-SPECTRUM', + 'x86_64-mlnx_msn2410-r0':'MELLANOX-SPECTRUM', + 'x86_64-mlnx_msn2700-r0':'MELLANOX-SPECTRUM', + 'x86_64-mlnx_msn2700_simx-r0':'MELLANOX-SPECTRUM', + 'x86_64-mlnx_msn2740-r0':'MELLANOX-SPECTRUM', + 'x86_64-mlnx_msn3700c-r0':'MELLANOX-SPECTRUM-2', + 'x86_64-mlnx_msn3700-r0':'MELLANOX-SPECTRUM-2', + 'x86_64-mlnx_msn3700_simx-r0':'MELLANOX-SPECTRUM-2', + 'x86_64-mlnx_msn3800-r0':'MELLANOX-SPECTRUM-2', + 'x86_64-mlnx_msn4700_simx-r0':'MELLANOX-SPECTRUM-3', + 'x86_64-mlnx_msn4700-r0':'MELLANOX-SPECTRUM-3', + 'x86_64-mlnx_msn4600c-r0':'MELLANOX-SPECTRUM-3', + 'vs-platform':'vs' + } +%} +{% set asic_type = platform2asic[platform] %} +{% if asic_type == 'MELLANOX-SPECTRUM' %} + { + "ASIC_TABLE:MELLANOX-SPECTRUM": { + "cell_size": "96", + "pipeline_latency": "19", + "mac_phy_delay": "0.8", + "peer_response_time": "3.8" + }, + "OP": "SET" + } +{% elif asic_type == 'MELLANOX-SPECTRUM-2' %} + { + "ASIC_TABLE:MELLANOX-SPECTRUM-2": { + "cell_size": "144", + "pipeline_latency": "19", + "mac_phy_delay": "0.8", + "peer_response_time": "3.8" + }, + "OP": "SET" + } +{% elif asic_type == 'MELLANOX-SPECTRUM-3' %} + { + "ASIC_TABLE:MELLANOX-SPECTRUM-3": { + "cell_size": "144", + "pipeline_latency": "19", + "mac_phy_delay": "0.8", + "peer_response_time": "3.8" + }, + "OP": "SET" + } +{% endif %} +] diff --git a/platform/mellanox/docker-ptf-mlnx.mk b/platform/mellanox/docker-ptf-mlnx.mk deleted file mode 100644 index f6d17e72fcfe..000000000000 --- a/platform/mellanox/docker-ptf-mlnx.mk +++ /dev/null @@ -1,7 +0,0 @@ -# docker image for docker-ptf-mlnx - -DOCKER_PTF_MLNX = docker-ptf-mlnx.gz -$(DOCKER_PTF_MLNX)_PATH = $(DOCKERS_PATH)/docker-ptf-saithrift -$(DOCKER_PTF_MLNX)_DEPENDS += $(PYTHON_SAITHRIFT) -$(DOCKER_PTF_MLNX)_LOAD_DOCKERS += $(DOCKER_PTF) -SONIC_DOCKER_IMAGES += $(DOCKER_PTF_MLNX) diff --git a/platform/mellanox/docker-saiserver-mlnx.dep b/platform/mellanox/docker-saiserver-mlnx.dep new file mode 100644 index 000000000000..7a4e4fdcbb34 --- /dev/null +++ b/platform/mellanox/docker-saiserver-mlnx.dep @@ -0,0 +1,10 @@ +# DPKG FRK + +DPATH := $($(DOCKER_SAISERVER_MLNX)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/docker-saiserver-mlnx.mk $(PLATFORM_PATH)/docker-saiserver-mlnx.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(DPATH)) + +$(DOCKER_SAISERVER_MLNX)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_SAISERVER_MLNX)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_SAISERVER_MLNX)_DEP_FILES := $(DEP_FILES) diff --git a/platform/mellanox/docker-saiserver-mlnx.mk b/platform/mellanox/docker-saiserver-mlnx.mk index d91756a1f239..6515fa9846b1 100644 --- a/platform/mellanox/docker-saiserver-mlnx.mk +++ b/platform/mellanox/docker-saiserver-mlnx.mk @@ -6,6 +6,7 @@ $(DOCKER_SAISERVER_MLNX)_DEPENDS += $(SAISERVER) $(PYTHON_SDK_API) $(DOCKER_SAISERVER_MLNX)_PYTHON_DEBS += $(MLNX_SFPD) $(DOCKER_SAISERVER_MLNX)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) SONIC_DOCKER_IMAGES += $(DOCKER_SAISERVER_MLNX) +SONIC_STRETCH_DOCKERS += $(DOCKER_SAISERVER_MLNX) $(DOCKER_SAISERVER_MLNX)_CONTAINER_NAME = saiserver $(DOCKER_SAISERVER_MLNX)_RUN_OPT += --net=host --privileged -t diff --git a/platform/mellanox/docker-saiserver-mlnx/Dockerfile.j2 b/platform/mellanox/docker-saiserver-mlnx/Dockerfile.j2 index b202be5b3401..39223131ee43 100644 --- a/platform/mellanox/docker-saiserver-mlnx/Dockerfile.j2 +++ b/platform/mellanox/docker-saiserver-mlnx/Dockerfile.j2 @@ -44,4 +44,4 @@ COPY ["sai_2700.xml", "/usr/share/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/mellanox/docker-syncd-mlnx-rpc.dep b/platform/mellanox/docker-syncd-mlnx-rpc.dep new file mode 100644 index 000000000000..c79c94d2c03a --- /dev/null +++ b/platform/mellanox/docker-syncd-mlnx-rpc.dep @@ -0,0 +1,10 @@ +# DPKG FRK + +DPATH := $($(DOCKER_SYNCD_MLNX_RPC)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/docker-syncd-mlnx-rpc.mk $(PLATFORM_PATH)/docker-syncd-mlnx-rpc.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(DPATH)) + +$(DOCKER_SYNCD_MLNX_RPC)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_SYNCD_MLNX_RPC)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_SYNCD_MLNX_RPC)_DEP_FILES := $(DEP_FILES) diff --git a/platform/mellanox/docker-syncd-mlnx-rpc.mk b/platform/mellanox/docker-syncd-mlnx-rpc.mk index ed9eea9ae8f8..806b40035f23 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) \ @@ -14,7 +14,7 @@ endif $(DOCKER_SYNCD_MLNX_RPC)_PYTHON_DEBS += $(MLNX_SFPD) $(DOCKER_SYNCD_MLNX_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_BASE) SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_MLNX_RPC) -SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_MLNX_RPC) +SONIC_BUSTER_DOCKERS += $(DOCKER_SYNCD_MLNX_RPC) ifeq ($(ENABLE_SYNCD_RPC),y) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_MLNX_RPC) endif diff --git a/platform/mellanox/docker-syncd-mlnx-rpc/Dockerfile.j2 b/platform/mellanox/docker-syncd-mlnx-rpc/Dockerfile.j2 index 3f6225c96bd3..b48d4ac3c793 100644 --- a/platform/mellanox/docker-syncd-mlnx-rpc/Dockerfile.j2 +++ b/platform/mellanox/docker-syncd-mlnx-rpc/Dockerfile.j2 @@ -11,17 +11,11 @@ RUN apt-get purge -y syncd {% if docker_syncd_mlnx_rpc_debs.strip() -%} # Copy locally-built Debian package dependencies {{ copy_files("debs/", docker_syncd_mlnx_rpc_debs.split(' '), "/debs/") }} - -# Install locally-built Debian packages and implicitly install their dependencies -{{ install_debian_packages(docker_syncd_mlnx_rpc_debs.split(' ')) }} {% endif %} {% if docker_syncd_mlnx_rpc_pydebs.strip() -%} # Copy locally-built Debian package dependencies {{ copy_files("python-debs/", docker_syncd_mlnx_rpc_pydebs.split(' '), "/debs/") }} - -# Install locally-built Debian packages and implicitly install their dependencies -{{ install_debian_packages(docker_syncd_mlnx_rpc_pydebs.split(' ')) }} {% endif %} ## Pre-install the fundamental packages @@ -29,13 +23,29 @@ RUN apt-get update \ && apt-get -y install \ net-tools \ python-pip \ + python-setuptools \ build-essential \ libssl-dev \ libffi-dev \ python-dev \ wget \ cmake \ - && wget https://github.com/nanomsg/nanomsg/archive/1.0.0.tar.gz \ + libqt5core5a \ + libqt5network5 \ + libboost-atomic1.71.0 + +{% if docker_syncd_mlnx_rpc_debs.strip() -%} +# Install locally-built Debian packages and implicitly install their dependencies +{{ install_debian_packages(docker_syncd_mlnx_rpc_debs.split(' ')) }} +{% endif %} + +{% if docker_syncd_mlnx_rpc_pydebs.strip() -%} +# Install locally-built Debian packages and implicitly install their dependencies +{{ install_debian_packages(docker_syncd_mlnx_rpc_pydebs.split(' ')) }} +{% endif %} + + +RUN wget https://github.com/nanomsg/nanomsg/archive/1.0.0.tar.gz \ && tar xvfz 1.0.0.tar.gz \ && cd nanomsg-1.0.0 \ && mkdir -p build \ @@ -45,9 +55,10 @@ RUN apt-get update \ && cd .. \ && rm -fr nanomsg-1.0.0 \ && rm -f 1.0.0.tar.gz \ - && pip install cffi==1.7.0 \ - && pip install --upgrade cffi==1.7.0 \ - && pip install nnpy \ + && pip2 install cffi==1.7.0 \ + && pip2 install --upgrade cffi==1.7.0 \ + && pip2 install wheel \ + && pip2 install nnpy \ && mkdir -p /opt \ && cd /opt \ && wget https://raw.githubusercontent.com/p4lang/ptf/master/ptf_nn/ptf_nn_agent.py \ @@ -62,4 +73,4 @@ RUN apt-get clean -y && \ apt-get autoremove -y && \ rm -rf /debs -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/mellanox/docker-syncd-mlnx.dep b/platform/mellanox/docker-syncd-mlnx.dep new file mode 100644 index 000000000000..659b09cec8f4 --- /dev/null +++ b/platform/mellanox/docker-syncd-mlnx.dep @@ -0,0 +1,12 @@ +# DPKG FRK + +DPATH := $($(DOCKER_SYNCD_BASE)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/docker-syncd-mlnx.mk $(PLATFORM_PATH)/docker-syncd-mlnx.dep platform/mellanox/mlnx-sai.mk +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(DPATH)) + +$(DOCKER_SYNCD_BASE)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_SYNCD_BASE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_SYNCD_BASE)_DEP_FILES := $(DEP_FILES) + +$(eval $(call add_dbg_docker,$(DOCKER_SYNCD_BASE),$(DOCKER_SYNCD_BASE_DBG))) diff --git a/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 b/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 index 6953933735fa..5c9ac6c1c145 100755 --- a/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 +++ b/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 @@ -1,5 +1,5 @@ {% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} -FROM docker-config-engine-stretch +FROM docker-config-engine-buster ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf @@ -35,9 +35,8 @@ RUN apt-get clean -y && \ apt-get autoremove -y && \ rm -rf /debs -COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor/"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] 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 3079618990ed..61e290e3189e 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" - if does not exist for 5 times within 5 cycles then alert +check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/platform/mellanox/docker-syncd-mlnx/critical_processes b/platform/mellanox/docker-syncd-mlnx/critical_processes index 6082f242b872..bdd6903c5690 100644 --- a/platform/mellanox/docker-syncd-mlnx/critical_processes +++ b/platform/mellanox/docker-syncd-mlnx/critical_processes @@ -1 +1 @@ -syncd +program:syncd diff --git a/platform/mellanox/docker-syncd-mlnx/start.sh b/platform/mellanox/docker-syncd-mlnx/start.sh deleted file mode 100755 index 96e2a9128081..000000000000 --- a/platform/mellanox/docker-syncd-mlnx/start.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -rm -f /var/run/rsyslogd.pid - -supervisorctl start rsyslogd - -supervisorctl start syncd - diff --git a/platform/mellanox/docker-syncd-mlnx/supervisord.conf b/platform/mellanox/docker-syncd-mlnx/supervisord.conf index 0c6285d46ae0..8491d762bf51 100644 --- a/platform/mellanox/docker-syncd-mlnx/supervisord.conf +++ b/platform/mellanox/docker-syncd-mlnx/supervisord.conf @@ -3,32 +3,36 @@ 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 +[eventlistener:dependent-startup] +command=python3 -m supervisord_dependent_startup autostart=true autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE +buffer_size=25 -[program:start.sh] -command=/usr/bin/start.sh -priority=1 +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name syncd +events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING autostart=true -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog +autorestart=unexpected [program:rsyslogd] -command=/usr/sbin/rsyslogd -n -priority=2 +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 autostart=false autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true [program:syncd] command=/usr/bin/syncd_start.sh -priority=3 +priority=2 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running diff --git a/platform/mellanox/fw.dep b/platform/mellanox/fw.dep new file mode 100644 index 000000000000..228f6dc87e36 --- /dev/null +++ b/platform/mellanox/fw.dep @@ -0,0 +1,16 @@ +# DPKG FRK + +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/fw.mk $(PLATFORM_PATH)/fw.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) + +$(MLNX_SPC_FW_FILE)_CACHE_MODE := GIT_CONTENT_SHA +$(MLNX_SPC_FW_FILE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(MLNX_SPC_FW_FILE)_DEP_FILES := $(DEP_FILES) + +$(MLNX_SPC2_FW_FILE)_CACHE_MODE := GIT_CONTENT_SHA +$(MLNX_SPC2_FW_FILE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(MLNX_SPC2_FW_FILE)_DEP_FILES := $(DEP_FILES) + +$(MLNX_SPC3_FW_FILE)_CACHE_MODE := GIT_CONTENT_SHA +$(MLNX_SPC3_FW_FILE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(MLNX_SPC3_FW_FILE)_DEP_FILES := $(DEP_FILES) diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index dc8243be1e83..5b21692173c0 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) @@ -11,17 +11,17 @@ else FW_FROM_URL = n endif -MLNX_SPC_FW_VERSION = 13.2007.0322 +MLNX_SPC_FW_VERSION = 13.2008.2314 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.2008.2314 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.2008.2314 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) @@ -34,13 +34,8 @@ else SONIC_ONLINE_FILES += $(MLNX_FW_FILES) endif -export MLNX_SPC_FW_VERSION -export MLNX_SPC_FW_FILE +MLNX_FILES += $(MLNX_FW_FILES) -export MLNX_SPC2_FW_VERSION +export MLNX_SPC_FW_FILE export MLNX_SPC2_FW_FILE - -export MLNX_SPC3_FW_VERSION export MLNX_SPC3_FW_FILE - -export MLNX_FW_FILES diff --git a/platform/mellanox/hw-management.dep b/platform/mellanox/hw-management.dep new file mode 100644 index 000000000000..b69ca22b4c57 --- /dev/null +++ b/platform/mellanox/hw-management.dep @@ -0,0 +1,15 @@ +# DPKG FRK + +SPATH := $($(MLNX_HW_MANAGEMENT)_SRC_PATH) +SLINKS := $(shell find $(SPATH) -type l -exec echo {} \; | grep -Ev ' ') +SMDEP_PATHS := $(shell git submodule status --recursive -- $(SPATH) | awk '{print $$2}' | grep -Ev ' ') +SMDEP_FILES := $(foreach path,$(SMDEP_PATHS),$(filter-out $(SMDEP_PATHS),$(addprefix $(path)/,$(shell cd $(path) && git ls-files | grep -Ev ' ')))) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/hw-management.mk $(PLATFORM_PATH)/hw-management.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(filter-out $(SMDEP_PATHS),$(shell git ls-files -- $(SPATH) | grep -Ev ' ')) + +$(MLNX_HW_MANAGEMENT)_CACHE_MODE := GIT_CONTENT_SHA +$(MLNX_HW_MANAGEMENT)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(MLNX_HW_MANAGEMENT)_DEP_FILES := $(filter-out $(SLINKS),$(DEP_FILES)) +$(MLNX_HW_MANAGEMENT)_SMDEP_FILES := $(filter-out $(SLINKS),$(SMDEP_FILES)) +$(MLNX_HW_MANAGEMENT)_SMDEP_PATHS := $(SMDEP_PATHS) diff --git a/platform/mellanox/hw-management.mk b/platform/mellanox/hw-management.mk index 692a816a0f4f..521daa1c7c3b 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.3012 +MLNX_HW_MANAGEMENT_VERSION = 7.0010.1300 export MLNX_HW_MANAGEMENT_VERSION @@ -8,5 +8,3 @@ MLNX_HW_MANAGEMENT = hw-management_1.mlnx.$(MLNX_HW_MANAGEMENT_VERSION)_amd64.de $(MLNX_HW_MANAGEMENT)_SRC_PATH = $(PLATFORM_PATH)/hw-management $(MLNX_HW_MANAGEMENT)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) SONIC_MAKE_DEBS += $(MLNX_HW_MANAGEMENT) - -SONIC_STRETCH_DEBS += $(MLNX_HW_MANAGEMENT) diff --git a/platform/mellanox/hw-management/0001-Make-SONiC-determine-reboot-cause-service-start-afte.patch b/platform/mellanox/hw-management/0001-Make-SONiC-determine-reboot-cause-service-start-afte.patch new file mode 100644 index 000000000000..11539e606369 --- /dev/null +++ b/platform/mellanox/hw-management/0001-Make-SONiC-determine-reboot-cause-service-start-afte.patch @@ -0,0 +1,26 @@ +From 1a1011b6da491d35001df5a7204d4eecb2769767 Mon Sep 17 00:00:00 2001 +From: keboliu +Date: Fri, 15 Jan 2021 14:41:16 +0800 +Subject: [PATCH] Make SONiC determine-reboot-cause service start after hw-mgmt + service + +Signed-off-by: Kebo Liu +--- + debian/hw-management.hw-management.service | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/debian/hw-management.hw-management.service b/debian/hw-management.hw-management.service +index 39a2a54..2104b87 100755 +--- a/debian/hw-management.hw-management.service ++++ b/debian/hw-management.hw-management.service +@@ -1,6 +1,7 @@ + [Unit] + Description=Chassis HW management service of Mellanox systems + Documentation=man:hw-management.service(8) ++Before=determine-reboot-cause.service + + [Service] + Type=oneshot +-- +1.9.1 + 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 deleted file mode 100644 index ccbd6322d2e6..000000000000 --- a/platform/mellanox/hw-management/0001-Make-hw-mgmt-SimX-compatiable.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 6aecc8fed8cc78c1fb5c6b52bdfa3d07ca66e652 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 - -Signed-off-by: Mykola Faryma ---- - usr/usr/bin/hw-management.sh | 29 +++++++++++++++++++++++++++++ - 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 ---- a/usr/usr/bin/hw-management.sh -+++ b/usr/usr/bin/hw-management.sh -@@ -737,6 +737,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 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 -+} -+ -+if [[ "$(cat /sys/devices/virtual/dmi/id/sys_vendor)" = "QEMU" ]]; then -+ handle_simx -+ exit 0 -+fi -+ - case $ACTION in - start) - if [ -d /var/run/hw-management ]; then --- -1.9.1 - diff --git a/platform/mellanox/hw-management/0002-hw-management.sh-Disable-thermal-policy-running-in-h.patch b/platform/mellanox/hw-management/0002-hw-management.sh-Disable-thermal-policy-running-in-h.patch deleted file mode 100644 index d1c34fd16ec0..000000000000 --- a/platform/mellanox/hw-management/0002-hw-management.sh-Disable-thermal-policy-running-in-h.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 76b02916794be2e2558fcff1d11609a594f633d7 Mon Sep 17 00:00:00 2001 -From: Stephen Sun -Date: Fri, 14 Feb 2020 13:48:00 +0800 -Subject: [PATCH] Disable thermal policy running in hw-mgmt service SONiC - thermal control algorithm has been supported. - -Signed-off-by: Stephen Sun ---- - usr/usr/bin/hw-management.sh | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/usr/usr/bin/hw-management.sh b/usr/usr/bin/hw-management.sh -index 2cdbfb2..48b41d5 100755 ---- a/usr/usr/bin/hw-management.sh -+++ b/usr/usr/bin/hw-management.sh -@@ -799,7 +799,11 @@ do_start() - #disabled for leopard chipless bringup. - echo 1 > $config_path/suspend - -- $THERMAL_CONTROL $thermal_type $max_tachos $max_psus& -+# -+# Disable thermal control algorithm in hw-management service -+# because there has already been that in SONiC -+# -+# $THERMAL_CONTROL $thermal_type $max_tachos $max_psus& - } - - do_stop() --- -1.9.1 - diff --git a/platform/mellanox/hw-management/0002-hw-mgmt-events-Add-support-for-SDK-OFFLINE-event-for.patch b/platform/mellanox/hw-management/0002-hw-mgmt-events-Add-support-for-SDK-OFFLINE-event-for.patch new file mode 100644 index 000000000000..6c58f7299c2c --- /dev/null +++ b/platform/mellanox/hw-management/0002-hw-mgmt-events-Add-support-for-SDK-OFFLINE-event-for.patch @@ -0,0 +1,30 @@ +From 3e511778248403968e0a02857b7003f352669ba3 Mon Sep 17 00:00:00 2001 +From: Vadim Pasternak +Date: Wed, 13 Jan 2021 13:19:17 +0200 +Subject: [PATCH] hw-mgmt: events: Add support for SDK OFFLINE event for + handling flow with in service firmware upgrade + +In order to prevent "mlxsw_minimal" driver access to ASIC during in +service firmware upgrade flow, SDK will raise "OFFLINE" 'udev' event +at early beginning of such flow. When this event is received, +hw-managemnet will remove "mlxsw_minimal" driver. +There is no need to implement opposite "ONLINE" event, since this flow +is ended up with "kexec". + +Signed-off-by: Vadim Pasternak +--- + usr/lib/udev/rules.d/50-hw-management-events.rules | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/usr/lib/udev/rules.d/50-hw-management-events.rules b/usr/lib/udev/rules.d/50-hw-management-events.rules +index cf4219e..33ea1bc 100644 +--- a/usr/lib/udev/rules.d/50-hw-management-events.rules ++++ b/usr/lib/udev/rules.d/50-hw-management-events.rules +@@ -269,3 +269,4 @@ SUBSYSTEM=="i2c", DEVPATH=="/devices/platform/mlxplat/i2c_mlxcpld*/i2c-*/i2c-*/* + # SDK + SUBSYSTEM=="pci", DRIVERS=="sx_core", ACTION=="add", RUN+="/usr/bin/hw-management-thermal-events.sh add sxcore add" + SUBSYSTEM=="pci", DRIVERS=="sx_core", ACTION=="remove", RUN+="/usr/bin/hw-management-thermal-events.sh rm sxcore remove" ++SUBSYSTEM=="pci", DRIVERS=="sx_core", ACTION=="offline", RUN+="/usr/bin/hw-management-thermal-events.sh rm sxcore remove" +-- +1.9.1 + diff --git a/platform/mellanox/hw-management/Makefile b/platform/mellanox/hw-management/Makefile index 608c94e6b02a..eb087b47bfff 100644 --- a/platform/mellanox/hw-management/Makefile +++ b/platform/mellanox/hw-management/Makefile @@ -8,7 +8,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : pushd hw-mgmt git am ../*.patch chmod +x ./debian/rules - sudo ./debian/rules binary KVERSION=$(KVERSION) + KVERSION=$(KVERSION) dpkg-buildpackage -us -uc -b -rfakeroot -j$(SONIC_CONFIG_MAKE_JOBS) --admindir $(SONIC_DPKG_ADMINDIR) popd mv $* $(DEST)/ diff --git a/platform/mellanox/hw-management/hw-mgmt b/platform/mellanox/hw-management/hw-mgmt index 2f659142ab3b..dec7935777b5 160000 --- a/platform/mellanox/hw-management/hw-mgmt +++ b/platform/mellanox/hw-management/hw-mgmt @@ -1 +1 @@ -Subproject commit 2f659142ab3b4deb58989a2ca38b0b1671600509 +Subproject commit dec7935777b52d31a2220bad8b0cec4b71ec0961 diff --git a/platform/mellanox/issu-version.dep b/platform/mellanox/issu-version.dep new file mode 100644 index 000000000000..c4a178aef712 --- /dev/null +++ b/platform/mellanox/issu-version.dep @@ -0,0 +1,10 @@ +# DPKG FRK + +SPATH := $($(ISSU_VERSION_FILE)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/issu-version.mk $(PLATFORM_PATH)/issu-version.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(SPATH)) + +$(ISSU_VERSION_FILE)_CACHE_MODE := GIT_CONTENT_SHA +$(ISSU_VERSION_FILE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(ISSU_VERSION_FILE)_DEP_FILES := $(DEP_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/libsaithrift-dev.dep b/platform/mellanox/libsaithrift-dev.dep new file mode 100644 index 000000000000..a6fd20007c77 --- /dev/null +++ b/platform/mellanox/libsaithrift-dev.dep @@ -0,0 +1,32 @@ +# DPKG FRK + +SPATH := $($(LIBSAITHRIFT_DEV)_SRC_PATH) +SLINKS := $(shell find $(SPATH) -type l -exec echo {} \; | grep -Ev ' ') +SMDEP_PATHS := $(SPATH) $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git submodule status --recursive | awk '{print $$2}' | grep -Ev ' ')) +SMDEP_FILES := $(foreach path,$(SMDEP_PATHS),$(filter-out $(SMDEP_PATHS),$(addprefix $(path)/,$(shell cd $(path) && git ls-files | grep -Ev ' ')))) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/libsaithrift-dev.mk $(PLATFORM_PATH)/libsaithrift-dev.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) + +$(LIBSAITHRIFT_DEV)_CACHE_MODE := GIT_CONTENT_SHA +$(LIBSAITHRIFT_DEV)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(LIBSAITHRIFT_DEV)_DEP_FILES := $(DEP_FILES) +$(LIBSAITHRIFT_DEV)_SMDEP_FILES := $(filter-out $(SLINKS),$(SMDEP_FILES)) +$(LIBSAITHRIFT_DEV)_SMDEP_PATHS := $(SMDEP_PATHS) + +$(PYTHON_SAITHRIFT)_CACHE_MODE := GIT_CONTENT_SHA +$(PYTHON_SAITHRIFT)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(PYTHON_SAITHRIFT)_DEP_FILES := $(DEP_FILES) +$(PYTHON_SAITHRIFT)_SMDEP_FILES := $(filter-out $(SLINKS),$(SMDEP_FILES)) +$(PYTHON_SAITHRIFT)_SMDEP_PATHS := $(SMDEP_PATHS) + +$(SAISERVER)_CACHE_MODE := GIT_CONTENT_SHA +$(SAISERVER)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SAISERVER)_DEP_FILES := $(DEP_FILES) +$(SAISERVER)_SMDEP_FILES := $(filter-out $(SLINKS),$(SMDEP_FILES)) +$(SAISERVER)_SMDEP_PATHS := $(SMDEP_PATHS) + +$(SAISERVER_DBG)_CACHE_MODE := GIT_CONTENT_SHA +$(SAISERVER_DBG)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SAISERVER_DBG)_DEP_FILES := $(DEP_FILES) +$(SAISERVER_DBG)_SMDEP_FILES := $(filter-out $(SLINKS),$(SMDEP_FILES)) +$(SAISERVER_DBG)_SMDEP_PATHS := $(SMDEP_PATHS) diff --git a/platform/mellanox/mft.dep b/platform/mellanox/mft.dep new file mode 100644 index 000000000000..7dcdaf1d305d --- /dev/null +++ b/platform/mellanox/mft.dep @@ -0,0 +1,18 @@ +# DPKG FRK + +SPATH := $($(MFT)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/mft.mk $(PLATFORM_PATH)/mft.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(SPATH)) + +$(MFT)_CACHE_MODE := GIT_CONTENT_SHA +$(MFT)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(MFT)_DEP_FILES := $(DEP_FILES) + +$(KERNEL_MFT)_CACHE_MODE := GIT_CONTENT_SHA +$(KERNEL_MFT)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(KERNEL_MFT)_DEP_FILES := $(DEP_FILES) + +$(MFT_OEM)_CACHE_MODE := GIT_CONTENT_SHA +$(MFT_OEM)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(MFT_OEM)_DEP_FILES := $(DEP_FILES) diff --git a/platform/mellanox/mft.mk b/platform/mellanox/mft.mk index e6c9d9ba0ea6..4529343931e3 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.15.3 +MFT_REVISION = 3 export MFT_VERSION MFT_REVISION @@ -10,10 +10,8 @@ $(MFT)_SRC_PATH = $(PLATFORM_PATH)/mft $(MFT)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) SONIC_MAKE_DEBS += $(MFT) -KERNEL_MFT = kernel-mft-dkms_$(MFT_VERSION)-$(KVERSION)_all.deb +KERNEL_MFT = kernel-mft-dkms-modules-$(KVERSION)_$(MFT_VERSION)_amd64.deb $(eval $(call add_derived_package,$(MFT),$(KERNEL_MFT))) MFT_OEM = mft-oem_$(MFT_VERSION)-$(MFT_REVISION)_amd64.deb $(eval $(call add_derived_package,$(MFT),$(MFT_OEM))) - -SONIC_STRETCH_DEBS += $(KERNEL_MFT) diff --git a/platform/mellanox/mft/Makefile b/platform/mellanox/mft/Makefile index e18964dd4b91..84a587730386 100644 --- a/platform/mellanox/mft/Makefile +++ b/platform/mellanox/mft/Makefile @@ -4,15 +4,21 @@ SHELL = /bin/bash MFT_NAME = mft-$(MFT_VERSION)-$(MFT_REVISION)-x86_64-deb MFT_TGZ = $(MFT_NAME).tgz + SRC_DEB = kernel-mft-dkms_$(MFT_VERSION)-$(MFT_REVISION)_all.deb +MOD_DEB = kernel-mft-dkms-modules-$(KVERSION)_$(MFT_VERSION)_amd64.deb MAIN_TARGET = mft_$(MFT_VERSION)-$(MFT_REVISION)_amd64.deb -DERIVED_TARGETS = kernel-mft-dkms_$(MFT_VERSION)-$(KVERSION)_all.deb mft-oem_$(MFT_VERSION)-$(MFT_REVISION)_amd64.deb +DERIVED_TARGETS = $(MOD_DEB) mft-oem_$(MFT_VERSION)-$(MFT_REVISION)_amd64.deb + +DKMS_BMDEB = /var/lib/dkms/kernel-mft-dkms/$(MFT_VERSION)/bmdeb +DKMS_TMP := $(shell mktemp -u -d -t dkms.XXXXXXXXXX) $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : rm -rf $(MFT_NAME) wget -O $(MFT_TGZ) http://www.mellanox.com/downloads/MFT/$(MFT_TGZ) tar xzf $(MFT_TGZ) + pushd $(MFT_NAME)/SDEBS # put a lock here because dpkg does not allow installing packages in parallel @@ -22,11 +28,27 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : fi done - tar xvf `sudo dkms mkdriverdisk kernel-mft-dkms/$(MFT_VERSION) -a all -d ubuntu -k $(KVERSION) --media tar | grep "Disk image location" | cut -d':' -f2` popd + sudo dkms build kernel-mft-dkms/$(MFT_VERSION) -k $(KVERSION) -a amd64 + sudo dkms mkbmdeb kernel-mft-dkms/$(MFT_VERSION) -k $(KVERSION) -a amd64 + + # w/a: remove dependencies + mkdir -p $(DKMS_TMP)/DEBIAN + + dpkg -e $(DKMS_BMDEB)/$(MOD_DEB) $(DKMS_TMP)/DEBIAN + dpkg -x $(DKMS_BMDEB)/$(MOD_DEB) $(DKMS_TMP) + + sed -i '/^Depends:/c\Depends:' $(DKMS_TMP)/DEBIAN/control + + pushd $(MFT_NAME)/DEBS + dpkg -b $(DKMS_TMP) . + popd + + rm -rf $(DKMS_TMP) + # fix timestamp because we do not actually build tools, only kernel - touch $(MFT_NAME)/DEBS/* - mv $(MFT_NAME)/SDEBS/ubuntu-drivers/4.9.0/kernel-mft-dkms_$(MFT_VERSION)-$(KVERSION)_all.deb $(MFT_NAME)/DEBS/* $(DEST) + touch $(MFT_NAME)/DEBS/*.deb + mv $(MFT_NAME)/DEBS/*.deb $(DEST) $(addprefix $(DEST)/, $(DERIVED_TARGETS)): $(DEST)/% : $(DEST)/$(MAIN_TARGET) diff --git a/platform/mellanox/mlnx-ffb.dep b/platform/mellanox/mlnx-ffb.dep new file mode 100644 index 000000000000..efaadd2767ae --- /dev/null +++ b/platform/mellanox/mlnx-ffb.dep @@ -0,0 +1,10 @@ +# DPKG FRK + +DPATH := $($(MLNX_FFB_SCRIPT)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/mlnx-ffb.mk $(PLATFORM_PATH)/mlnx-ffb.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(addprefix $(DPATH),$(MLNX_FFB_SCRIPT)) + +$(MLNX_FFB_SCRIPT)_CACHE_MODE := GIT_CONTENT_SHA +$(MLNX_FFB_SCRIPT)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(MLNX_FFB_SCRIPT)_DEP_FILES := $(DEP_FILES) diff --git a/platform/mellanox/mlnx-ffb.mk b/platform/mellanox/mlnx-ffb.mk index dabb995a3658..6c3c925b5996 100755 --- a/platform/mellanox/mlnx-ffb.mk +++ b/platform/mellanox/mlnx-ffb.mk @@ -1,7 +1,9 @@ # mellanox fast fast boot script MLNX_FFB_SCRIPT = mlnx-ffb.sh -$(MLNX_FFB_SCRIPT)_PATH = platform/mellanox/ +$(MLNX_FFB_SCRIPT)_PATH = $(PLATFORM_PATH)/ SONIC_COPY_FILES += $(MLNX_FFB_SCRIPT) +MLNX_FILES += $(MLNX_FFB_SCRIPT) + export MLNX_FFB_SCRIPT diff --git a/platform/mellanox/mlnx-ffb.sh b/platform/mellanox/mlnx-ffb.sh index 1488bb2c6b97..d0bef9d57761 100755 --- a/platform/mellanox/mlnx-ffb.sh +++ b/platform/mellanox/mlnx-ffb.sh @@ -23,8 +23,8 @@ check_sdk_upgrade() { CHECK_RESULT="${FFB_FAILURE}" - NEXT_SONIC_IMAGE="$(sonic_installer list | grep "Next: " | cut -f2 -d' ')" - CURRENT_SONIC_IMAGE="$(sonic_installer list | grep "Current: " | cut -f2 -d' ')" + NEXT_SONIC_IMAGE="$(sonic-installer list | grep "Next: " | cut -f2 -d' ')" + CURRENT_SONIC_IMAGE="$(sonic-installer list | grep "Current: " | cut -f2 -d' ')" FS_PATH="/host/image-${NEXT_SONIC_IMAGE#SONiC-OS-}/fs.squashfs" FS_MOUNTPOINT="/tmp/image-${NEXT_SONIC_IMAGE#SONiC-OS-}-fs" diff --git a/platform/mellanox/mlnx-fw-upgrade.j2 b/platform/mellanox/mlnx-fw-upgrade.j2 index d0f69c35e0bc..245ce75d5f18 100755 --- a/platform/mellanox/mlnx-fw-upgrade.j2 +++ b/platform/mellanox/mlnx-fw-upgrade.j2 @@ -19,25 +19,23 @@ declare -r EXIT_SUCCESS="0" declare -r EXIT_FAILURE="1" declare -r QUERY_CMD="mlxfwmanager --query" +declare -r LIST_CONTENT_CMD="mlxfwmanager --list-content" declare -r BURN_CMD="mlxfwmanager -u -f -y" declare -r QUERY_FILE="/tmp/mlxfwmanager-query.log" +declare -r LIST_CONTENT_FILE="/tmp/mlxfwmanager-list-content.log" declare -r SPC1_ASIC="spc1" declare -r SPC2_ASIC="spc2" declare -r SPC3_ASIC="spc3" declare -r UNKN_ASIC="unknown" +declare -r UNKN_MST="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}" VERBOSE_LEVEL="${VERBOSE_MIN}" @@ -155,6 +153,18 @@ function GetAsicType() { exit "${EXIT_FAILURE}" } +function GetMstDevice() { + local _MST_DEVICE="$(ls /dev/mst/*_pci_cr0 2>&1)" + + if [[ ! -c "${_MST_DEVICE}" ]]; then + echo "${UNKN_MST}" + else + echo "${_MST_DEVICE}" + fi + + exit "${EXIT_SUCCESS}" +} + function RunCmd() { local ERROR_CODE="${EXIT_SUCCESS}" @@ -180,26 +190,24 @@ function UpgradeFW() { if [ ! -z "${_FS_MOUNTPOINT}" ]; then local -r _FW_FILE="${_FS_MOUNTPOINT}/${FW_FILE_MAP[$_ASIC_TYPE]}" - - if [ ! -f "${_FW_FILE}" ]; then - ExitFailure "no such file: ${_FW_FILE}" - fi - - RunCmd "${QUERY_CMD} -i ${_FW_FILE} -L ${QUERY_FILE}" &>/dev/null - - local -r _FW_INFO="$(grep FW ${QUERY_FILE})" - local -r _FW_CURRENT="$(echo ${_FW_INFO} | cut -f2 -d' ')" - local -r _FW_AVAILABLE="$(echo ${_FW_INFO} | cut -f3 -d' ')" else local -r _FW_FILE="${FW_FILE_MAP[$_ASIC_TYPE]}" + fi - RunCmd "${QUERY_CMD} -L ${QUERY_FILE}" &>/dev/null - - local -r _FW_INFO="$(grep FW ${QUERY_FILE})" - local -r _FW_CURRENT="$(echo ${_FW_INFO} | cut -f2 -d' ')" - local -r _FW_AVAILABLE="${FW_REQUIRED_MAP[$_ASIC_TYPE]}" + if [ ! -f "${_FW_FILE}" ]; then + ExitFailure "no such file: ${_FW_FILE}" fi + RunCmd "${QUERY_CMD} -o ${QUERY_FILE}" + local -r _FW_CURRENT_INFO="$(grep FW ${QUERY_FILE})" + local -r _FW_CURRENT="$(echo ${_FW_CURRENT_INFO} | cut -f2 -d' ')" + local -r _PSID_INFO="$(grep PSID ${QUERY_FILE})" + local -r _PSID="$(echo ${_PSID_INFO} | cut -f2 -d' ')" + + RunCmd "${LIST_CONTENT_CMD} -i ${_FW_FILE} -o ${LIST_CONTENT_FILE}" + local -r _FW_AVAILABLE_INFO="$(grep ${_PSID} ${LIST_CONTENT_FILE})" + local -r _FW_AVAILABLE="$(echo ${_FW_AVAILABLE_INFO} | cut -f4 -d' ')" + if [[ -z "${_FW_CURRENT}" ]]; then ExitFailure "could not retreive current FW version" fi @@ -212,13 +220,19 @@ function UpgradeFW() { ExitSuccess "firmware is up to date" else LogNotice "firmware upgrade is required. Installing compatible version..." - RunCmd "${BURN_CMD} -i ${_FW_FILE}" + local -r _MST_DEVICE="$(GetMstDevice)" + if [[ "${_MST_DEVICE}" = "${UNKN_MST}" ]]; then + LogWarning "could not find fastest mst device, using default device" + RunCmd "${BURN_CMD} -i ${_FW_FILE}" + else + RunCmd "${BURN_CMD} -d ${_MST_DEVICE} -i ${_FW_FILE}" + fi fi } function UpgradeFWFromImage() { - local -r _NEXT_SONIC_IMAGE="$(sonic_installer list | grep "Next: " | cut -f2 -d' ')" - local -r _CURRENT_SONIC_IMAGE="$(sonic_installer list | grep "Current: " | cut -f2 -d' ')" + local -r _NEXT_SONIC_IMAGE="$(sonic-installer list | grep "Next: " | cut -f2 -d' ')" + local -r _CURRENT_SONIC_IMAGE="$(sonic-installer list | grep "Current: " | cut -f2 -d' ')" local -r _FS_PATH="/host/image-${_NEXT_SONIC_IMAGE#SONiC-OS-}/fs.squashfs" local -r _FS_MOUNTPOINT="/tmp/image-${_NEXT_SONIC_IMAGE#SONiC-OS-}-fs" diff --git a/platform/mellanox/mlnx-onie-fw-update.dep b/platform/mellanox/mlnx-onie-fw-update.dep new file mode 100644 index 000000000000..f22352ed0cba --- /dev/null +++ b/platform/mellanox/mlnx-onie-fw-update.dep @@ -0,0 +1,10 @@ +# DPKG FRK + +DPATH := $($(MLNX_ONIE_FW_UPDATE)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/mlnx-onie-fw-update.mk $(PLATFORM_PATH)/mlnx-onie-fw-update.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(addprefix $(DPATH),$(MLNX_ONIE_FW_UPDATE)) + +$(MLNX_ONIE_FW_UPDATE)_CACHE_MODE := GIT_CONTENT_SHA +$(MLNX_ONIE_FW_UPDATE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(MLNX_ONIE_FW_UPDATE)_DEP_FILES := $(DEP_FILES) diff --git a/platform/mellanox/mlnx-onie-fw-update.mk b/platform/mellanox/mlnx-onie-fw-update.mk new file mode 100644 index 000000000000..13f68ce4671f --- /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_PATH)/ +SONIC_COPY_FILES += $(MLNX_ONIE_FW_UPDATE) + +MLNX_FILES += $(MLNX_ONIE_FW_UPDATE) + +export MLNX_ONIE_FW_UPDATE diff --git a/platform/mellanox/mlnx-onie-fw-update.sh b/platform/mellanox/mlnx-onie-fw-update.sh new file mode 100755 index 000000000000..0abc55ef76b4 --- /dev/null +++ b/platform/mellanox/mlnx-onie-fw-update.sh @@ -0,0 +1,205 @@ +#!/bin/bash + +# Copyright (C) 2019 Mellanox Technologies Ltd. +# Copyright (C) 2019 Michael Shych +# +# SPDX-License-Identifier: GPL-2.0 + +this_script="$(basename $(realpath ${0}))" +lock_file="/var/run/${this_script%.*}.lock" + +onie_mount=/mnt/onie-boot +onie_lib=/lib/onie +os_boot=/host + +print_help() { +cat <${lock_file} + /usr/bin/flock -x ${lock_fd} + register_unlock_handler ${lock_fd} +} + +# Multiprocessing synchronization +lock_script_state_change + +# Process command arguments +cmd="${1}" + +# Optional argument +arg="${2}" + +if [[ -z "${cmd}" ]]; then + # Default to 'show' if no command is specified. + cmd="show" +fi + +case "${cmd}" in + add|remove) + if [[ -z "${arg}" ]]; then + echo "ERROR: This command requires a firmware update file name" + echo "Run: '${this_script} help' for complete details" + exit 1 + fi + ;; + update) + enable_onie_access + show_pending + rc=$? + if [[ ${rc} -ne 0 ]]; then + enable_onie_fw_update_mode + rc=$? + disable_onie_access + if [[ ${rc} -eq 0 ]]; then + system_reboot + else + echo "ERROR: failed to enable ONIE firmware update mode" + exit ${rc} + fi + else + echo "ERROR: No firmware images for update" + echo "Run: '${this_script} add ' before update" + disable_onie_access + exit 1 + fi + ;; + purge|show-pending|show-results|show|show-log|help) + ;; + *) + echo "ERROR: Unknown command: ${cmd}" + exit 1 + ;; +esac + +enable_onie_access +${onie_mount}/onie/tools/bin/onie-fwpkg "$@" +rc=$? +if [[ "${cmd}" = "help" ]]; then + print_help +fi +disable_onie_access + +exit ${rc} diff --git a/platform/mellanox/mlnx-platform-api.dep b/platform/mellanox/mlnx-platform-api.dep new file mode 100644 index 000000000000..b66c0b9c3bdf --- /dev/null +++ b/platform/mellanox/mlnx-platform-api.dep @@ -0,0 +1,15 @@ +# DPKG FRK + +SPATH := $($(SONIC_PLATFORM_API_PY2)_SRC_PATH) +SLINKS := $(shell find $(SPATH) -type l -exec echo {} \; | grep -Ev ' ') +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/mlnx-platform-api.mk $(PLATFORM_PATH)/mlnx-platform-api.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(SPATH) | grep -Ev ' ') + +$(SONIC_PLATFORM_API_PY2)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_PLATFORM_API_PY2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_PLATFORM_API_PY2)_DEP_FILES := $(filter-out $(SLINKS),$(DEP_FILES)) + +$(SONIC_PLATFORM_API_PY3)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_PLATFORM_API_PY3)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_PLATFORM_API_PY3)_DEP_FILES := $(filter-out $(SLINKS),$(DEP_FILES)) diff --git a/platform/mellanox/mlnx-platform-api.mk b/platform/mellanox/mlnx-platform-api.mk index 7bbbc3c70b0e..e7e36c1f67b8 100644 --- a/platform/mellanox/mlnx-platform-api.mk +++ b/platform/mellanox/mlnx-platform-api.mk @@ -3,7 +3,17 @@ SONIC_PLATFORM_API_PY2 = mlnx_platform_api-1.0-py2-none-any.whl $(SONIC_PLATFORM_API_PY2)_SRC_PATH = $(PLATFORM_PATH)/mlnx-platform-api $(SONIC_PLATFORM_API_PY2)_PYTHON_VERSION = 2 -$(SONIC_PLATFORM_API_PY2)_DEPENDS = $(SONIC_PLATFORM_COMMON_PY2) $(SONIC_DAEMON_BASE_PY2) $(SONIC_CONFIG_ENGINE) +$(SONIC_PLATFORM_API_PY2)_DEPENDS = $(SONIC_PY_COMMON_PY2) $(SONIC_PLATFORM_COMMON_PY2) $(SONIC_CONFIG_ENGINE_PY2) SONIC_PYTHON_WHEELS += $(SONIC_PLATFORM_API_PY2) export mlnx_platform_api_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_API_PY2))" + +# SONIC_PLATFORM_API_PY3 package + +SONIC_PLATFORM_API_PY3 = mlnx_platform_api-1.0-py3-none-any.whl +$(SONIC_PLATFORM_API_PY3)_SRC_PATH = $(PLATFORM_PATH)/mlnx-platform-api +$(SONIC_PLATFORM_API_PY3)_PYTHON_VERSION = 3 +$(SONIC_PLATFORM_API_PY3)_DEPENDS = $(SONIC_PY_COMMON_PY3) $(SONIC_PLATFORM_COMMON_PY3) $(SONIC_CONFIG_ENGINE_PY3) $(SONIC_PLATFORM_API_PY2) +SONIC_PYTHON_WHEELS += $(SONIC_PLATFORM_API_PY3) + +export mlnx_platform_api_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_API_PY3))" diff --git a/platform/mellanox/mlnx-platform-api/setup.py b/platform/mellanox/mlnx-platform-api/setup.py index f10f84924d2c..df1a8cadbb09 100644 --- a/platform/mellanox/mlnx-platform-api/setup.py +++ b/platform/mellanox/mlnx-platform-api/setup.py @@ -31,6 +31,7 @@ 'Natural Language :: English', 'Operating System :: POSIX :: Linux', 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3.7', 'Topic :: Utilities', ], keywords='sonic SONiC platform PLATFORM', diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index fe8b31898387..b5ca79286d1f 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -11,15 +11,13 @@ 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 sonic_py_common import device_info + from sonic_py_common.logger import Logger from os import listdir from os.path import isfile, join - from glob import glob import sys import io import re - import subprocess import syslog except ImportError as e: raise ImportError (str(e) + "- required module not found") @@ -28,8 +26,6 @@ MLNX_NUM_PSU = 2 -GET_HWSKU_CMD = "sonic-cfggen -d -v DEVICE_METADATA.localhost.hwsku" - EEPROM_CACHE_ROOT = '/var/cache/sonic/decode-syseeprom' EEPROM_CACHE_FILE = 'syseeprom_cache' @@ -47,30 +43,32 @@ # Global logger class instance logger = Logger() -# magic code defnition for port number, qsfp port position of each hwsku +# magic code defnition for port number, qsfp port position of each Platform # 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} -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)] +platform_dict_port = {'x86_64-mlnx_msn2010-r0': 3, 'x86_64-mlnx_msn2100-r0': 1, 'x86_64-mlnx_msn2410-r0': 2, 'x86_64-mlnx_msn2700-r0': 0, 'x86_64-mlnx_lssn2700':0, 'x86_64-mlnx_msn2740-r0': 0, 'x86_64-mlnx_msn3420-r0':5, 'x86_64-mlnx_msn3700-r0': 0, 'x86_64-mlnx_msn3700c-r0': 0, 'x86_64-mlnx_msn3800-r0': 4, 'x86_64-mlnx_msn4600c-r0':4, 'x86_64-mlnx_msn4700-r0': 0, 'x86_64-mlnx_msn4410-r0': 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), (0, 48, 59, 60, 1)] class Chassis(ChassisBase): """Platform-specific Chassis class""" + # System status LED + _led = None + def __init__(self): super(Chassis, self).__init__() - # 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 + self.name = "Undefined" + self.model = "Undefined" + # Initialize Platform name + self.platform_name = device_info.get_platform() + # move the initialization of each components to their dedicated initializer # which will be called from platform self.sfp_module_initialized = False self.sfp_event_initialized = False self.reboot_cause_initialized = False + self.sdk_handle = None logger.log_info("Chassis loaded successfully") @@ -78,42 +76,39 @@ def __del__(self): if self.sfp_event_initialized: self.sfp_event.deinitialize() + if self.sdk_handle: + from sonic_platform.sfp import deinitialize_sdk_handle + deinitialize_sdk_handle(self.sdk_handle) + def initialize_psu(self): from sonic_platform.psu import Psu # Initialize PSU list self.psu_module = Psu for index in range(MLNX_NUM_PSU): - psu = Psu(index, self.sku_name) + psu = Psu(index, self.platform_name) self._psu_list.append(psu) def initialize_fan(self): + from .device_data import DEVICE_DATA from sonic_platform.fan import Fan - from sonic_platform.fan import FAN_PATH - self.fan_module = Fan - self.fan_path = FAN_PATH - # Initialize FAN list - multi_rotor_in_drawer = False - num_of_fan, num_of_drawer = self._extract_num_of_fans_and_fan_drawers() - multi_rotor_in_drawer = num_of_fan > num_of_drawer - - # Fan's direction isn't supported on spectrum 1 devices for now - mst_dev_list = glob(MST_DEVICE_NAME_PATTERN) - if not mst_dev_list: - raise RuntimeError("Can't get chip type due to {} not found".format(MST_DEVICE_NAME_PATTERN)) - m = re.search(MST_DEVICE_RE_PATTERN, mst_dev_list[0]) - if m.group(1) == SPECTRUM1_CHIP_ID: - has_fan_dir = False - else: - has_fan_dir = True - - for index in range(num_of_fan): - if multi_rotor_in_drawer: - fan = Fan(has_fan_dir, index, index/2) - else: - fan = Fan(has_fan_dir, index, index) - self._fan_list.append(fan) + from .fan_drawer import RealDrawer, VirtualDrawer + + fan_data = DEVICE_DATA[self.platform_name]['fans'] + drawer_num = fan_data['drawer_num'] + drawer_type = fan_data['drawer_type'] + fan_num_per_drawer = fan_data['fan_num_per_drawer'] + drawer_ctor = RealDrawer if drawer_type == 'real' else VirtualDrawer + fan_index = 0 + for drawer_index in range(drawer_num): + drawer = drawer_ctor(drawer_index, fan_data) + self._fan_drawer_list.append(drawer) + for index in range(fan_num_per_drawer): + fan = Fan(fan_index, drawer, index + 1) + fan_index += 1 + drawer._fan_list.append(fan) + self._fan_list.append(fan) def initialize_sfp(self): @@ -122,7 +117,7 @@ def initialize_sfp(self): self.sfp_module = SFP # Initialize SFP list - port_position_tuple = self._get_port_position_tuple_by_sku_name() + port_position_tuple = self._get_port_position_tuple_by_platform_name() self.PORT_START = port_position_tuple[0] self.QSFP_PORT_START = port_position_tuple[1] self.PORT_END = port_position_tuple[2] @@ -130,31 +125,50 @@ def initialize_sfp(self): for index in range(self.PORT_START, self.PORT_END + 1): if index in range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1): - sfp_module = SFP(index, 'QSFP') + sfp_module = SFP(index, 'QSFP', self.get_sdk_handle, self.platform_name) else: - sfp_module = SFP(index, 'SFP') + sfp_module = SFP(index, 'SFP', self.get_sdk_handle, self.platform_name) + self._sfp_list.append(sfp_module) self.sfp_module_initialized = True + def get_sdk_handle(self): + if not self.sdk_handle: + from sonic_platform.sfp import initialize_sdk_handle + self.sdk_handle = initialize_sdk_handle() + if self.sdk_handle is None: + logger.log_error('Failed to open SDK handle') + return self.sdk_handle + + def initialize_thermals(self): - from sonic_platform.thermal import initialize_thermals + from sonic_platform.thermal import initialize_chassis_thermals # Initialize thermals - initialize_thermals(self.sku_name, self._thermal_list, self._psu_list) + initialize_chassis_thermals(self.platform_name, self._thermal_list) def initialize_eeprom(self): - from eeprom import Eeprom + from .eeprom import Eeprom # Initialize EEPROM self._eeprom = Eeprom() + # Get chassis name and model from eeprom + self.name = self._eeprom.get_product_name() + self.model = self._eeprom.get_part_number() def initialize_components(self): # Initialize component list - from sonic_platform.component import ComponentBIOS, ComponentCPLD + from sonic_platform.component import ComponentONIE, ComponentSSD, ComponentBIOS, ComponentCPLD + self._component_list.append(ComponentONIE()) + self._component_list.append(ComponentSSD()) self._component_list.append(ComponentBIOS()) - self._component_list.append(ComponentCPLD()) + self._component_list.extend(ComponentCPLD.get_component_list()) + + def initizalize_system_led(self): + from .led import SystemLed + Chassis._led = SystemLed() def get_name(self): @@ -167,6 +181,15 @@ def get_name(self): return self.name + def get_model(self): + """ + Retrieves the model number (or part number) of the device + + Returns: + string: Model/part number of device + """ + return self.model + ############################################## # SFP methods ############################################## @@ -197,13 +220,13 @@ def get_all_sfps(self): def get_sfp(self, index): """ - Retrieves sfp represented by (0-based) index + Retrieves sfp represented by (1-based) index Args: - index: An integer, the index (0-based) of the sfp to retrieve. + 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 0. - For example, 0 for Ethernet0, 1 for Ethernet4 and so on. + starting from 1. + For example, 1 for Ethernet0, 2 for Ethernet4 and so on. Returns: An object dervied from SfpBase representing the specified sfp @@ -212,7 +235,7 @@ def get_sfp(self, index): self.initialize_sfp() sfp = None - + index -= 1 try: sfp = self._sfp_list[index] except IndexError: @@ -238,15 +261,8 @@ def _extract_num_of_fans_and_fan_drawers(self): return num_of_fan, num_of_drawer - - def _get_sku_name(self): - p = subprocess.Popen(GET_HWSKU_CMD, shell=True, stdout=subprocess.PIPE) - out, err = p.communicate() - return out.rstrip('\n') - - - def _get_port_position_tuple_by_sku_name(self): - position_tuple = port_position_tuple_list[hwsku_dict_port[self.sku_name]] + def _get_port_position_tuple_by_platform_name(self): + position_tuple = port_position_tuple_list[platform_dict_port[self.platform_name]] return position_tuple @@ -286,7 +302,7 @@ def get_base_mac(self): return self._eeprom.get_base_mac() - def get_serial_number(self): + def get_serial(self): """ Retrieves the hardware serial number for the chassis @@ -373,11 +389,11 @@ def get_reboot_cause(self): if not self.reboot_cause_initialized: self.initialize_reboot_cause() - for reset_file, reset_cause in self.reboot_major_cause_dict.iteritems(): + for reset_file, reset_cause in self.reboot_major_cause_dict.items(): if self._verify_reboot_cause(reset_file): return reset_cause, '' - for reset_file, reset_cause in self.reboot_minor_cause_dict.iteritems(): + for reset_file, reset_cause in self.reboot_minor_cause_dict.items(): if self._verify_reboot_cause(reset_file): return self.REBOOT_CAUSE_HARDWARE_OTHER, reset_cause @@ -398,7 +414,7 @@ def _show_capabilities(self): """ for s in self._sfp_list: try: - print "index {} tx disable {} dom {} calibration {} temp {} volt {} power (tx {} rx {})".format(s.index, + print("index {} tx disable {} dom {} calibration {} temp {} volt {} power (tx {} rx {})".format(s.index, s.dom_tx_disable_supported, s.dom_supported, s.calibration, @@ -406,9 +422,9 @@ def _show_capabilities(self): s.dom_volt_supported, s.dom_rx_power_supported, s.dom_tx_power_supported - ) + )) except: - print "fail to retrieve capabilities for module index {}".format(s.index) + print("fail to retrieve capabilities for module index {}".format(s.index)) def get_change_event(self, timeout=0): @@ -448,30 +464,75 @@ 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 + self.reinit_sfps(port_dict) return True, {'sfp':port_dict} else: return True, {'sfp':{}} + def reinit_sfps(self, port_dict): + """ + Re-initialize SFP if there is any newly inserted SFPs + :param port_dict: SFP event data + :return: + """ + # SFP not initialize yet, do nothing + if not self.sfp_module_initialized: + return + + from . import sfp + for index, status in port_dict.items(): + if status == sfp.SFP_STATUS_INSERTED: + try: + self.get_sfp(index).reinit() + except Exception as e: + logger.log_error("Fail to re-initialize SFP {} - {}".format(index, repr(e))) + def get_thermal_manager(self): from .thermal_manager import ThermalManager return ThermalManager + def set_status_led(self, color): + """ + Sets the state of the system LED + + Args: + color: A string representing the color with which to set the + system LED + + Returns: + bool: True if system LED state is set successfully, False if not + """ + return False if not Chassis._led else Chassis._led.set_status(color) + + def get_status_led(self): + """ + Gets the state of the system LED + + Returns: + A string, one of the valid LED color strings which could be vendor + specified. + """ + return None if not Chassis._led else Chassis._led.get_status() + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. If the agent cannot determine the parent-relative position + for some reason, or if the associated value of entPhysicalContainedIn is '0', then the value '-1' is returned + Returns: + integer: The 1-based relative physical position in parent device or -1 if cannot determine the position + """ + return -1 + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return False diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py index dc09ae4011fa..e70007e96562 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py @@ -5,55 +5,358 @@ # # 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 io import re import sys + import glob + import tempfile + import subprocess + if sys.version_info[0] > 2: + import configparser + else: + import ConfigParser as configparser + + from sonic_platform_base.component_base import ComponentBase except ImportError as e: raise ImportError(str(e) + "- required module not found") -#components definitions -COMPONENT_BIOS = "BIOS" -COMPONENT_CPLD = "CPLD" + +class MPFAManager(object): + MPFA_EXTENSION = '.mpfa' + + MPFA_EXTRACT_COMMAND = 'tar xzf {} -C {}' + MPFA_CLEANUP_COMMAND = 'rm -rf {}' + + def __init__(self, mpfa_path): + self.__mpfa_path = mpfa_path + self.__contents_path = None + self.__metadata = None + + def __enter__(self): + self.extract() + return self + + def __exit__(self, exc_type, exc_value, traceback): + self.cleanup() + + def __validate_path(self, mpfa_path): + if not os.path.isfile(mpfa_path): + raise RuntimeError("MPFA doesn't exist: path={}".format(mpfa_path)) + + name, ext = os.path.splitext(mpfa_path) + if ext != self.MPFA_EXTENSION: + raise RuntimeError("MPFA doesn't have valid extension: path={}".format(mpfa_path)) + + def __extract_contents(self, mpfa_path): + contents_path = tempfile.mkdtemp(prefix='mpfa-') + + cmd = self.MPFA_EXTRACT_COMMAND.format(mpfa_path, contents_path) + subprocess.check_call(cmd.split(), universal_newlines=True) + + self.__contents_path = contents_path + + def __parse_metadata(self, contents_path): + metadata_path = os.path.join(contents_path, 'metadata.ini') + + if not os.path.isfile(metadata_path): + raise RuntimeError("MPFA metadata doesn't exist: path={}".format(metadata_path)) + + cp = configparser.ConfigParser() + with io.open(metadata_path, 'r') as metadata_ini: + cp.readfp(metadata_ini) + + self.__metadata = cp + + def extract(self): + if self.is_extracted(): + return + + self.__validate_path(self.__mpfa_path) + self.__extract_contents(self.__mpfa_path) + self.__parse_metadata(self.__contents_path) + + def cleanup(self): + if os.path.exists(self.__contents_path): + cmd = self.MPFA_CLEANUP_COMMAND.format(self.__contents_path) + subprocess.check_call(cmd.split(), universal_newlines=True) + + self.__contents_path = None + self.__metadata = None + + def get_path(self): + return self.__contents_path + + def get_metadata(self): + return self.__metadata + + def is_extracted(self): + return self.__contents_path is not None and os.path.exists(self.__contents_path) + + +class ONIEUpdater(object): + 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_PENDING = '/usr/bin/mlnx-onie-fw-update.sh show-pending' + + ONIE_VERSION_PARSE_PATTERN = '([0-9]{4})\.([0-9]{2})-([0-9]+)\.([0-9]+)\.([0-9]+)-([0-9]+)' + ONIE_VERSION_BASE_PARSE_PATTERN = '([0-9]+)\.([0-9]+)\.([0-9]+)' + ONIE_VERSION_REQUIRED = '5.2.0016' + + ONIE_VERSION_ATTR = 'onie_version' + ONIE_NO_PENDING_UPDATES_ATTR = 'No pending firmware updates present' + + ONIE_IMAGE_INFO_COMMAND = '/bin/bash {} -q -i' + + def __mount_onie_fs(self): + fs_mountpoint = '/mnt/onie-fs' + onie_path = '/lib/onie' + + if os.path.lexists(onie_path) or os.path.exists(fs_mountpoint): + self.__umount_onie_fs() + + cmd = "fdisk -l | grep 'ONIE boot' | awk '{print $1}'" + fs_path = subprocess.check_output(cmd, + stderr=subprocess.STDOUT, + shell=True, + universal_newlines=True).rstrip('\n') + + os.mkdir(fs_mountpoint) + cmd = "mount -n -r -t ext4 {} {}".format(fs_path, fs_mountpoint) + subprocess.check_call(cmd, shell=True, universal_newlines=True) + + fs_onie_path = os.path.join(fs_mountpoint, 'onie/tools/lib/onie') + os.symlink(fs_onie_path, onie_path) + + return fs_mountpoint + + def __umount_onie_fs(self): + fs_mountpoint = '/mnt/onie-fs' + onie_path = '/lib/onie' + + if os.path.islink(onie_path): + os.unlink(onie_path) + + if os.path.ismount(fs_mountpoint): + cmd = "umount -rf {}".format(fs_mountpoint) + subprocess.check_call(cmd, shell=True, universal_newlines=True) + + if os.path.exists(fs_mountpoint): + os.rmdir(fs_mountpoint) + + def __stage_update(self, image_path): + cmd = self.ONIE_FW_UPDATE_CMD_ADD.format(image_path) + + try: + subprocess.check_call(cmd.split(), universal_newlines=True) + except subprocess.CalledProcessError as e: + raise RuntimeError("Failed to stage firmware update: {}".format(str(e))) + + def __unstage_update(self, image_path): + cmd = self.ONIE_FW_UPDATE_CMD_REMOVE.format(os.path.basename(image_path)) + + try: + subprocess.check_call(cmd.split(), universal_newlines=True) + except subprocess.CalledProcessError as e: + raise RuntimeError("Failed to unstage firmware update: {}".format(str(e))) + + def __trigger_update(self): + cmd = self.ONIE_FW_UPDATE_CMD_UPDATE + + try: + subprocess.check_call(cmd.split(), universal_newlines=True) + except subprocess.CalledProcessError as e: + raise RuntimeError("Failed to trigger firmware update: {}".format(str(e))) + + def __is_update_staged(self, image_path): + cmd = self.ONIE_FW_UPDATE_CMD_SHOW_PENDING + + try: + output = subprocess.check_output(cmd.split(), + stderr=subprocess.STDOUT, + universal_newlines=True).rstrip('\n') + except subprocess.CalledProcessError as e: + raise RuntimeError("Failed to get pending firmware updates: {}".format(str(e))) + + basename = os.path.basename(image_path) + + for line in output.splitlines(): + if line.startswith(basename): + return True + + return False + + def parse_onie_version(self, version, is_base=False): + onie_year = None + onie_month = None + onie_major = None + onie_minor = None + onie_release = None + onie_baudrate = None + + if is_base: + pattern = self.ONIE_VERSION_BASE_PARSE_PATTERN + + m = re.search(pattern, version) + if not m: + raise RuntimeError("Failed to parse ONIE version: pattern={}, version={}".format(pattern, version)) + + onie_major = m.group(1) + onie_minor = m.group(2) + onie_release = m.group(3) + + return onie_year, onie_month, onie_major, onie_minor, onie_release, onie_baudrate + + pattern = self.ONIE_VERSION_PARSE_PATTERN + + m = re.search(pattern, version) + if not m: + raise RuntimeError("Failed to parse ONIE version: pattern={}, version={}".format(pattern, version)) + + onie_year = m.group(1) + onie_month = m.group(2) + onie_major = m.group(3) + onie_minor = m.group(4) + onie_release = m.group(5) + onie_baudrate = m.group(6) + + return onie_year, onie_month, onie_major, onie_minor, onie_release, onie_baudrate + + def get_onie_required_version(self): + return self.ONIE_VERSION_REQUIRED + + def get_onie_version(self): + version = None + + try: + fs_mountpoint = self.__mount_onie_fs() + machine_conf_path = os.path.join(fs_mountpoint, 'onie/grub/grub-machine.cfg') + + with open(machine_conf_path, 'r') as machine_conf: + for line in machine_conf: + if line.startswith(self.ONIE_VERSION_ATTR): + items = line.rstrip('\n').split('=') + + if len(items) != 2: + raise RuntimeError("Failed to parse ONIE info: line={}".format(line)) + + version = items[1] + break + + if version is None: + raise RuntimeError("Failed to parse ONIE version") + finally: + self.__umount_onie_fs() + + return version + + def get_onie_firmware_info(self, image_path): + firmware_info = { } + + try: + self.__mount_onie_fs() + + cmd = self.ONIE_IMAGE_INFO_COMMAND.format(image_path) + + try: + output = subprocess.check_output(cmd.split(), + stderr=subprocess.STDOUT, + universal_newlines=True).rstrip('\n') + except subprocess.CalledProcessError as e: + raise RuntimeError("Failed to get ONIE firmware info: {}".format(str(e))) + + for line in output.splitlines(): + items = line.split('=') + + if len(items) != 2: + raise RuntimeError("Failed to parse ONIE firmware info: line={}".format(line)) + + firmware_info[items[0]] = items[1] + finally: + self.__umount_onie_fs() + + return firmware_info + + def update_firmware(self, image_path): + cmd = self.ONIE_FW_UPDATE_CMD_SHOW_PENDING + + try: + output = subprocess.check_output(cmd.split(), + stderr=subprocess.STDOUT, + universal_newlines=True).rstrip('\n') + except subprocess.CalledProcessError as e: + raise RuntimeError("Failed to get pending firmware updates: {}".format(str(e))) + + no_pending_updates = False + + for line in output.splitlines(): + if line.startswith(self.ONIE_NO_PENDING_UPDATES_ATTR): + no_pending_updates = True + break + + if not no_pending_updates: + raise RuntimeError("Failed to complete firmware update: pending updates are present") + + try: + self.__stage_update(image_path) + self.__trigger_update() + except: + if self.__is_update_staged(image_path): + self.__unstage_update(image_path) + raise + + def is_non_onie_firmware_update_supported(self): + current_version = self.get_onie_version() + _, _, major1, minor1, release1, _ = self.parse_onie_version(current_version) + version1 = int("{}{}{}".format(major1, minor1, release1)) + + required_version = self.get_onie_required_version() + _, _, major2, minor2, release2, _ = self.parse_onie_version(required_version, True) + version2 = int("{}{}{}".format(major2, minor2, release2)) + + return version1 >= version2 + class Component(ComponentBase): def __init__(self): self.name = None + self.description = None self.image_ext_name = None - def get_name(self): - """ - Retrieves the name of the component - - Returns: - A string containing the name of the component - """ return self.name + def get_description(self): + return self.description - def _read_generic_file(self, filename, len): + @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) + proc = subprocess.Popen(cmdline, + stdout=subprocess.PIPE, + shell=True, + stderr=subprocess.STDOUT, + universal_newlines=True) stdout = proc.communicate()[0] rc = proc.wait() result = stdout.rstrip('\n') @@ -65,274 +368,384 @@ 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 + name_list = os.path.splitext(image_path) 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 + else: + if name_list[1]: + print("ERROR: Extend name of file {} is wrong. Image for {} shouldn't have extension".format(image_path, self.name)) + return False return True +class ComponentONIE(Component): + COMPONENT_NAME = 'ONIE' + COMPONENT_DESCRIPTION = 'ONIE - Open Network Install Environment' -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" + ONIE_IMAGE_VERSION_ATTR = 'image_version' + + def __init__(self): + super(ComponentONIE, self).__init__() + + self.name = self.COMPONENT_NAME + self.description = self.COMPONENT_DESCRIPTION + self.onie_updater = ONIEUpdater() - 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' + def __install_firmware(self, image_path): + if not self._check_file_validity(image_path): + return False - 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" + try: + print("INFO: Staging {} firmware update with ONIE updater".format(self.name)) + self.onie_updater.update_firmware(image_path) + except Exception as e: + print("ERROR: Failed to update {} firmware: {}".format(self.name, str(e))) + return False - BIOS_QUERY_VERSION_COMMAND = 'dmidecode -t 11' + return True + + def get_firmware_version(self): + return self.onie_updater.get_onie_version() + + def get_available_firmware_version(self, image_path): + firmware_info = self.onie_updater.get_onie_firmware_info(image_path) + if self.ONIE_IMAGE_VERSION_ATTR not in firmware_info: + raise RuntimeError("Failed to get {} available firmware version".format(self.name)) + + return firmware_info[self.ONIE_IMAGE_VERSION_ATTR] + + def get_firmware_update_notification(self, image_path): + return "Immediate cold reboot is required to complete {} firmware update".format(self.name) + + def install_firmware(self, image_path): + return self.__install_firmware(image_path) + + def update_firmware(self, image_path): + self.__install_firmware(image_path) + + +class ComponentSSD(Component): + COMPONENT_NAME = 'SSD' + COMPONENT_DESCRIPTION = 'SSD - Solid-State Drive' + COMPONENT_FIRMWARE_EXTENSION = '.pkg' + + FIRMWARE_VERSION_ATTR = 'Firmware Version' + AVAILABLE_FIRMWARE_VERSION_ATTR = 'Available Firmware Version' + POWER_CYCLE_REQUIRED_ATTR = 'Power Cycle Required' + UPGRADE_REQUIRED_ATTR = 'Upgrade Required' + + SSD_INFO_COMMAND = "/usr/bin/mlnx-ssd-fw-update.sh -q" + SSD_FIRMWARE_INFO_COMMAND = "/usr/bin/mlnx-ssd-fw-update.sh -q -i {}" + SSD_FIRMWARE_UPDATE_COMMAND = "/usr/bin/mlnx-ssd-fw-update.sh -y -u -i {}" def __init__(self): - self.name = COMPONENT_BIOS - self.image_ext_name = ".rom" + super(ComponentSSD, self).__init__() + self.name = self.COMPONENT_NAME + self.description = self.COMPONENT_DESCRIPTION + self.image_ext_name = self.COMPONENT_FIRMWARE_EXTENSION - def get_description(self): - """ - Retrieves the description of the component + def __install_firmware(self, image_path): + if not self._check_file_validity(image_path): + return False - Returns: - A string containing the description of the component - """ - return "BIOS - Basic Input/Output System" + cmd = self.SSD_FIRMWARE_UPDATE_COMMAND.format(image_path) + try: + print("INFO: Installing {} firmware update".format(self.name)) + subprocess.check_call(cmd.split(), universal_newlines=True) + except subprocess.CalledProcessError as e: + print("ERROR: Failed to update {} firmware: {}".format(self.name, str(e))) + return False + + return True def get_firmware_version(self): - """ - Retrieves the firmware version of the component + cmd = self.SSD_INFO_COMMAND - Returns: - A string containing the firmware version of the component + try: + output = subprocess.check_output(cmd.split(), + stderr=subprocess.STDOUT, + universal_newlines=True).rstrip('\n') + except subprocess.CalledProcessError as e: + raise RuntimeError("Failed to get {} info: {}".format(self.name, str(e))) - BIOS version is retrieved via command 'dmidecode -t 11' - which should return result in the following convention - # dmidecode 3.0 - Getting SMBIOS data from sysfs. - SMBIOS 2.7 present. + for line in output.splitlines(): + if line.startswith(self.FIRMWARE_VERSION_ATTR): + return line.split(':')[1].lstrip(' \t') - Handle 0x0022, DMI type 11, 5 bytes - OEM Strings - String 1:*0ABZS017_02.02.002* - String 2: To Be Filled By O.E.M. + raise RuntimeError("Failed to parse {} version".format(self.name)) + + def get_available_firmware_version(self, image_path): + cmd = self.SSD_FIRMWARE_INFO_COMMAND.format(image_path) - 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 - """ 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, RuntimeError) as e: - raise RuntimeError("Failed to parse BIOS version due to {}".format(repr(e))) + output = subprocess.check_output(cmd.split(), + stderr=subprocess.STDOUT, + universal_newlines=True).rstrip('\n') + except subprocess.CalledProcessError as e: + raise RuntimeError("Failed to get {} firmware info: {}".format(self.name, str(e))) - return result + current_firmware_version = None + available_firmware_version = None + upgrade_required = None + + for line in output.splitlines(): + if line.startswith(self.FIRMWARE_VERSION_ATTR): + current_firmware_version = line.split(':')[1].lstrip(' \t') + if line.startswith(self.AVAILABLE_FIRMWARE_VERSION_ATTR): + available_firmware_version = line.split(':')[1].lstrip(' \t') + if line.startswith(self.UPGRADE_REQUIRED_ATTR): + upgrade_required = line.split(':')[1].lstrip(' \t') + if upgrade_required is None or upgrade_required not in ['yes', 'no']: + raise RuntimeError("Failed to parse {} firmware upgrade status".format(self.name)) + + if upgrade_required == 'no': + if current_firmware_version is None: + raise RuntimeError("Failed to parse {} current firmware version".format(self.name)) + return current_firmware_version + + if available_firmware_version is None: + raise RuntimeError("Failed to parse {} available firmware version".format(self.name)) + + return available_firmware_version + + def get_firmware_update_notification(self, image_path): + cmd = self.SSD_FIRMWARE_INFO_COMMAND.format(image_path) - 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 + output = subprocess.check_output(cmd.split(), + stderr=subprocess.STDOUT, + universal_newlines=True).rstrip('\n') + except subprocess.CalledProcessError as e: + raise RuntimeError("Failed to get {} firmware info: {}".format(self.name, str(e))) - 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 + power_cycle_required = None + upgrade_required = None - return True + for line in output.splitlines(): + if line.startswith(self.POWER_CYCLE_REQUIRED_ATTR): + power_cycle_required = line.split(':')[1].lstrip(' \t') + if line.startswith(self.UPGRADE_REQUIRED_ATTR): + upgrade_required = line.split(':')[1].lstrip(' \t') + + if upgrade_required is None or upgrade_required not in ['yes', 'no']: + raise RuntimeError("Failed to parse {} firmware upgrade status".format(self.name)) + + if upgrade_required == 'no': + return None + + if power_cycle_required is None or power_cycle_required not in ['yes', 'no']: + raise RuntimeError("Failed to parse {} firmware power policy".format(self.name)) + + notification = None + + if power_cycle_required == 'yes': + notification = "Immediate power cycle is required to complete {} firmware update".format(self.name) + return notification def install_firmware(self, image_path): - """ - Installs firmware to the component + return self.__install_firmware(image_path) - Args: - image_path: A string, path to firmware image + def update_firmware(self, image_path): + self.__install_firmware(image_path) - Returns: - A boolean, True if install was successful, False if not - """ - # check ONIE version requirement - if not self._check_onie_version(): + +class ComponentBIOS(Component): + COMPONENT_NAME = 'BIOS' + COMPONENT_DESCRIPTION = 'BIOS - Basic Input/Output System' + COMPONENT_FIRMWARE_EXTENSION = '.rom' + + BIOS_VERSION_COMMAND = 'dmidecode --oem-string 1' + + def __init__(self): + super(ComponentBIOS, self).__init__() + + self.name = self.COMPONENT_NAME + self.description = self.COMPONENT_DESCRIPTION + self.image_ext_name = self.COMPONENT_FIRMWARE_EXTENSION + self.onie_updater = ONIEUpdater() + + def __install_firmware(self, image_path): + if not self.onie_updater.is_non_onie_firmware_update_supported(): + print("ERROR: ONIE {} or later is required".format(self.onie_updater.get_onie_required_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 + print("INFO: Staging {} firmware update with ONIE updater".format(self.name)) + self.onie_updater.update_firmware(image_path) except Exception as e: - print("ERROR: Installing BIOS failed due to {}".format(repr(e))) + print("ERROR: Failed to update {} firmware: {}".format(self.name, str(e))) return False - print("INFO: Reboot is required to finish BIOS installation.") return True + def get_firmware_version(self): + cmd = self.BIOS_VERSION_COMMAND + try: + version = subprocess.check_output(cmd.split(), + stderr=subprocess.STDOUT, + universal_newlines=True).rstrip('\n') + except subprocess.CalledProcessError as e: + raise RuntimeError("Failed to get {} version: {}".format(self.name, str(e))) -class ComponentCPLD(Component): - CPLD_VERSION_FILE_PATTERN = '/var/run/hw-management/system/cpld[0-9]_version' - CPLD_VERSION_MAX_LENGTH = 4 + return version - CPLD_UPDATE_COMMAND = "cpldupdate --dev {} {}" - CPLD_INSTALL_SUCCESS_FLAG = "PASS!" + def get_available_firmware_version(self, image_path): + raise NotImplementedError("{} component doesn't support firmware version query".format(self.name)) - MST_DEVICE_PATTERN = "/dev/mst/mt[0-9]*_pciconf0" + def get_firmware_update_notification(self, image_path): + return "Immediate cold reboot is required to complete {} firmware update".format(self.name) - def __init__(self): - self.name = COMPONENT_CPLD - self.image_ext_name = ".vme" + def install_firmware(self, image_path): + return self.__install_firmware(image_path) + def update_firmware(self, image_path): + self.__install_firmware(image_path) - def get_description(self): - """ - Retrieves the description of the component - Returns: - A string containing the description of the component - """ - return "CPLD - includes all CPLDs in the switch" +class ComponentCPLD(Component): + COMPONENT_NAME = 'CPLD{}' + COMPONENT_DESCRIPTION = 'CPLD - Complex Programmable Logic Device' + COMPONENT_FIRMWARE_EXTENSION = '.vme' + MST_DEVICE_PATH = '/dev/mst' + MST_DEVICE_PATTERN = 'mt[0-9]*_pci_cr0' - def get_firmware_version(self): - """ - Retrieves the firmware version of the component + 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_min' - 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)) + CPLD_NUMBER_MAX_LENGTH = 1 + CPLD_PART_NUMBER_MAX_LENGTH = 6 + CPLD_VERSION_MAX_LENGTH = 2 + CPLD_VERSION_MINOR_MAX_LENGTH = 2 - return cpld_version + CPLD_PART_NUMBER_DEFAULT = '0' + CPLD_VERSION_MINOR_DEFAULT = '0' + CPLD_FIRMWARE_UPDATE_COMMAND = 'cpldupdate --dev {} --print-progress {}' - 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: + def __init__(self, idx): + super(ComponentCPLD, self).__init__() + + 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_mst_device(self): + if not os.path.exists(self.MST_DEVICE_PATH): + print("ERROR: mst driver is not loaded") return None - return mst_dev_list + pattern = os.path.join(self.MST_DEVICE_PATH, self.MST_DEVICE_PATTERN) - 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 + mst_dev_list = glob.glob(pattern) + if not mst_dev_list or len(mst_dev_list) != 1: + devices = str(os.listdir(self.MST_DEVICE_PATH)) + print("ERROR: Failed to get mst device: pattern={}, devices={}".format(pattern, devices)) + return None + + return mst_dev_list[0] + + def __install_firmware(self, image_path): 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") + mst_dev = self.__get_mst_device() + if mst_dev is None: return False - cmdline = self.CPLD_UPDATE_COMMAND.format(mst_dev_list[0], image_path) - outputline = "" - success_flag = False + cmd = self.CPLD_FIRMWARE_UPDATE_COMMAND.format(mst_dev, image_path) + try: - proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT) - while True: - out = proc.stdout.read(1) + print("INFO: Installing {} firmware update: path={}".format(self.name, image_path)) + subprocess.check_call(cmd.split(), universal_newlines=True) + except subprocess.CalledProcessError as e: + print("ERROR: Failed to update {} firmware: {}".format(self.name, str(e))) + return False - if out == '' and proc.poll() != None: - break + return True - if out != '': - sys.stdout.write(out) - sys.stdout.flush() - outputline += out + def get_firmware_version(self): + 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) - 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 + 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 proc.returncode: - print("ERROR: Upgrade CPLD failed, return code {}".format(proc.returncode)) - success_flag = False + if part_number is None: + part_number = self.CPLD_PART_NUMBER_DEFAULT - except OSError as e: - raise RuntimeError("Failed to execute command {} due to {}".format(cmdline, repr(e))) + if version_minor is None: + version_minor = self.CPLD_VERSION_MINOR_DEFAULT - if success_flag: - print("INFO: Success. Refresh or power cycle is required to finish CPLD installation.") - else: - print("ERROR: Failed to install CPLD") + part_number = part_number.rstrip('\n').zfill(self.CPLD_PART_NUMBER_MAX_LENGTH) + version = version.rstrip('\n').zfill(self.CPLD_VERSION_MAX_LENGTH) + version_minor = version_minor.rstrip('\n').zfill(self.CPLD_VERSION_MINOR_MAX_LENGTH) + + return "CPLD{}_REV{}{}".format(part_number, version, version_minor) + + def get_available_firmware_version(self, image_path): + with MPFAManager(image_path) as mpfa: + if not mpfa.get_metadata().has_option('version', self.name): + raise RuntimeError("Failed to get {} available firmware version".format(self.name)) + + return mpfa.get_metadata().get('version', self.name) + + def get_firmware_update_notification(self, image_path): + name, ext = os.path.splitext(os.path.basename(image_path)) + if ext == self.COMPONENT_FIRMWARE_EXTENSION: + return "Power cycle (with 30 sec delay) or refresh image is required to complete {} firmware update".format(self.name) + + return "Immediate power cycle is required to complete {} firmware update".format(self.name) + + def install_firmware(self, image_path): + return self.__install_firmware(image_path) + + def update_firmware(self, image_path): + with MPFAManager(image_path) as mpfa: + if not mpfa.get_metadata().has_option('firmware', 'burn'): + raise RuntimeError("Failed to get {} burn firmware".format(self.name)) + if not mpfa.get_metadata().has_option('firmware', 'refresh'): + raise RuntimeError("Failed to get {} refresh firmware".format(self.name)) + + burn_firmware = mpfa.get_metadata().get('firmware', 'burn') + refresh_firmware = mpfa.get_metadata().get('firmware', 'refresh') + + print("INFO: Processing {} burn file: firmware install".format(self.name)) + if not self.__install_firmware(os.path.join(mpfa.get_path(), burn_firmware)): + return + + print("INFO: Processing {} refresh file: firmware update".format(self.name)) + self.__install_firmware(os.path.join(mpfa.get_path(), refresh_firmware)) + + @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('\n') + + for cpld_idx in range(1, int(cpld_number) + 1): + component_list.append(cls(cpld_idx)) - return success_flag + return component_list diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/device_data.py b/platform/mellanox/mlnx-platform-api/sonic_platform/device_data.py new file mode 100644 index 000000000000..3853cac3f713 --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/device_data.py @@ -0,0 +1,254 @@ +DEVICE_DATA = { + 'x86_64-mlnx_msn2700-r0': { + 'thermal': { + 'minimum_table': { + "unk_trust": {"-127:30":13, "31:40":14 , "41:120":15}, + "unk_untrust": {"-127:25":13, "26:30":14 , "31:35":15, "36:120":16} + } + }, + 'fans': { + 'drawer_num': 4, + 'drawer_type': 'real', + 'fan_num_per_drawer': 2, + 'support_fan_direction': False, + 'hot_swappable': True + }, + 'psus': { + 'psu_num': 2, + 'fan_num_per_psu': 1, + 'hot_swappable': True, + 'led_num': 1 + } + }, + 'x86_64-mlnx_msn2740-r0': { + 'thermal': { + 'minimum_table': { + "unk_trust": {"-127:120":13}, + "unk_untrust": {"-127:15":13, "16:25":14 , "26:30":15, "31:120":17}, + } + }, + 'fans': { + 'drawer_num': 4, + 'drawer_type': 'real', + 'fan_num_per_drawer': 1, + 'support_fan_direction': False, + 'hot_swappable': True + }, + 'psus': { + 'psu_num': 2, + 'fan_num_per_psu': 1, + 'hot_swappable': True, + 'led_num': 1 + } + }, + 'x86_64-mlnx_msn2100-r0': { + 'thermal': { + 'minimum_table': { + "unk_trust": {"-127:40":12, "41:120":13}, + "unk_untrust": {"-127:15":12, "16:25":13, "26:30":14, "31:35":15, "36:120":16} + } + }, + 'fans': { + 'drawer_num': 1, + 'drawer_type': 'virtual', + 'fan_num_per_drawer': 4, + 'support_fan_direction': False, + 'hot_swappable': False + }, + 'psus': { + 'psu_num': 2, + 'fan_num_per_psu': 1, + 'hot_swappable': False, + 'led_num': 2 + } + }, + 'x86_64-mlnx_msn2410-r0': { + 'thermal': { + 'minimum_table': { + "unk_trust": {"-127:30":13, "31:40":14 , "41:120":15}, + "unk_untrust": {"-127:25":13, "26:30":14 , "31:35":15, "36:120":16} + } + }, + 'fans': { + 'drawer_num': 4, + 'drawer_type': 'real', + 'fan_num_per_drawer': 2, + 'support_fan_direction': False, + 'hot_swappable': True + }, + 'psus': { + 'psu_num': 2, + 'fan_num_per_psu': 1, + 'hot_swappable': True, + 'led_num': 1 + } + }, + 'x86_64-mlnx_msn2010-r0': { + 'thermal': { + 'minimum_table': { + "unk_trust": {"-127:120":12}, + "unk_untrust": {"-127:15":12, "16:20":13 , "21:30":14, "31:35":15, "36:120":16} + } + }, + 'fans': { + 'drawer_num': 1, + 'drawer_type': 'virtual', + 'fan_num_per_drawer': 4, + 'support_fan_direction': False, + 'hot_swappable': False + }, + 'psus': { + 'psu_num': 2, + 'fan_num_per_psu': 1, + 'hot_swappable': False, + 'led_num': 2 + } + }, + 'x86_64-mlnx_msn3700-r0': { + 'thermal': { + 'minimum_table': { + "unk_trust": {"-127:25":12, "26:40":13 , "41:120":14}, + "unk_untrust": {"-127:15":12, "16:30":13 , "31:35":14, "36:40":15, "41:120":16}, + } + }, + 'fans': { + 'drawer_num': 6, + 'drawer_type': 'real', + 'fan_num_per_drawer': 2, + 'support_fan_direction': True, + 'hot_swappable': True + }, + 'psus': { + 'psu_num': 2, + 'fan_num_per_psu': 1, + 'hot_swappable': True, + 'led_num': 1 + } + }, + 'x86_64-mlnx_msn3700c-r0': { + 'thermal': { + 'minimum_table': { + "unk_trust": {"-127:40":12, "41:120":13}, + "unk_untrust": {"-127:10":12, "11:20":13 , "21:30":14, "31:35":15, "36:120":16}, + } + }, + 'fans': { + 'drawer_num': 4, + 'drawer_type': 'real', + 'fan_num_per_drawer': 2, + 'support_fan_direction': True, + 'hot_swappable': True + }, + 'psus': { + 'psu_num': 2, + 'fan_num_per_psu': 1, + 'hot_swappable': True, + 'led_num': 1 + } + }, + 'x86_64-mlnx_msn3800-r0': { + 'thermal': { + 'minimum_table': { + "unk_trust": {"-127:30":12, "31:40":13 , "41:120":14}, + "unk_untrust": {"-127:0":12, "1:10":13 , "11:15":14, "16:20":15, "21:35":16, "36:120":17}, + } + }, + 'fans': { + 'drawer_num': 3, + 'drawer_type': 'real', + 'fan_num_per_drawer': 1, + 'support_fan_direction': True, + 'hot_swappable': True + }, + 'psus': { + 'psu_num': 2, + 'fan_num_per_psu': 1, + 'hot_swappable': True, + 'led_num': 1 + } + }, + 'x86_64-mlnx_msn4700-r0': { + 'thermal': { + 'minimum_table': { + "unk_trust": {"-127:35":14, "36:120":15}, + "unk_untrust": {"-127:35":14, "36:120":15}, + } + }, + 'fans': { + 'drawer_num': 6, + 'drawer_type': 'real', + 'fan_num_per_drawer': 2, + 'support_fan_direction': True, + 'hot_swappable': True + }, + 'psus': { + 'psu_num': 2, + 'fan_num_per_psu': 1, + 'hot_swappable': True, + 'led_num': 1 + } + }, + 'x86_64-mlnx_msn4410-r0': { + 'thermal': { + 'minimum_table': { + "unk_trust": {"-127:120":16}, + "unk_untrust": {"-127:120":16}, + } + }, + 'fans': { + 'drawer_num': 6, + 'drawer_type': 'real', + 'fan_num_per_drawer': 2, + 'support_fan_direction': True, + 'hot_swappable': True + }, + 'psus': { + 'psu_num': 2, + 'fan_num_per_psu': 1, + 'hot_swappable': True, + 'led_num': 1 + } + }, + 'x86_64-mlnx_msn3420-r0': { + 'thermal': { + 'minimum_table': { + "unk_trust": {"-127:120":12}, + "unk_untrust": {"-127:25":12, "26:35":13, "36:40":14, "41:120":16}, + } + }, + 'fans': { + 'drawer_num': 5, + 'drawer_type': 'real', + 'fan_num_per_drawer': 2, + 'support_fan_direction': True, + 'hot_swappable': True + }, + 'psus': { + 'psu_num': 2, + 'fan_num_per_psu': 1, + 'hot_swappable': True, + 'led_num': 1 + } + }, + 'x86_64-mlnx_msn4600c-r0': { + 'thermal': { + 'minimum_table': { + "unk_trust": {"-127:40":12, "41:120":13}, + "unk_untrust": {"-127:5":12, "6:20":13, "21:30":14, "31:35":15, "36:40":16, "41:120":17}, + } + }, + 'fans': { + 'drawer_num': 3, + 'drawer_type': 'real', + 'fan_num_per_drawer': 1, + 'support_fan_direction': True, + 'hot_swappable': True + }, + 'psus': { + 'psu_num': 2, + 'fan_num_per_psu': 1, + 'hot_swappable': True, + 'led_num': 1 + } + } +} \ No newline at end of file diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/eeprom.py b/platform/mellanox/mlnx-platform-api/sonic_platform/eeprom.py index 23f4b8b3444c..ef13bbd89e27 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/eeprom.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/eeprom.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ############################################################################# # Mellanox # @@ -7,17 +5,25 @@ # provides the eeprom information which are available in the platform # ############################################################################# -import exceptions import os import sys import re -from cStringIO import StringIO +import time + +if sys.version_info.major == 3: + from io import StringIO +else: + from cStringIO import StringIO + +from sonic_py_common.logger import Logger try: from sonic_platform_base.sonic_eeprom import eeprom_tlvinfo except ImportError as e: raise ImportError (str(e) + "- required module not found") +logger = Logger() + # # CACHE_XXX stuffs are supposted to be moved to the base classes # since they are common for all vendors @@ -59,14 +65,22 @@ def __init__(self): self._eeprom_loaded = True def _load_eeprom(self): + cache_file = os.path.join(CACHE_ROOT, CACHE_FILE) if not os.path.exists(CACHE_ROOT): try: os.makedirs(CACHE_ROOT) except: pass + else: + try: + # Make sure first time always read eeprom data from hardware + if os.path.exists(cache_file): + os.remove(cache_file) + except Exception as e: + logger.log_error('Failed to remove cache file {} - {}'.format(cache_file, repr(e))) try: - self.set_cache_name(os.path.join(CACHE_ROOT, CACHE_FILE)) + self.set_cache_name(cache_file) except: pass @@ -80,12 +94,28 @@ def _load_eeprom(self): pass self._base_mac = self.mgmtaddrstr(eeprom) - if self._base_mac == None: + if self._base_mac is None: self._base_mac = "Undefined." + else: + self._base_mac = self._base_mac.strip('\0') self._serial_str = self.serial_number_str(eeprom) - if self._serial_str == None: + if self._serial_str is None: self._serial_str = "Undefined." + else: + self._serial_str = self._serial_str.strip('\0') + + self._product_name = self.modelstr(eeprom) + if self._product_name is None: + self._product_name = "Undefined." + else: + self._product_name = self._product_name.strip('\0') + + self._part_number = self.part_number_str(eeprom) + if self._part_number is None: + self._part_number = "Undefined." + else: + self._part_number = self._part_number.strip('\0') original_stdout = sys.stdout sys.stdout = StringIO() @@ -101,7 +131,7 @@ def _load_eeprom(self): for line in lines: try: - match = re.search('(0x[0-9a-fA-F]{2})([\s]+[\S]+[\s]+)([\S]+)', line) + match = re.search('(0x[0-9a-fA-F]{2})([\s]+[\S]+[\s]+)([\S]+[\s]*[\S]*)', line) if match is not None: idx = match.group(1) value = match.group(3).rstrip('\0') @@ -135,6 +165,28 @@ def get_serial_number(self): self._load_eeprom() return self._serial_str + def get_product_name(self): + """ + Retrieves the hardware product name for the chassis + + Returns: + A string containing the hardware product name for this chassis. + """ + if not self._eeprom_loaded: + self._load_eeprom() + return self._product_name + + def get_part_number(self): + """ + Retrieves the hardware part number for the chassis + + Returns: + A string containing the hardware part number for this chassis. + """ + if not self._eeprom_loaded: + self._load_eeprom() + return self._part_number + def get_system_eeprom_info(self): """ Retrieves the full content of system EEPROM information for the chassis diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py b/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py index cc4f8e81d9b5..cad7d014e0f7 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py @@ -9,56 +9,70 @@ ############################################################################# import os.path +import subprocess try: from sonic_platform_base.fan_base import FanBase + from .led import FanLed, ComponentFaultyIndicator + from .utils import read_int_from_file, read_str_from_file, write_file except ImportError as e: raise ImportError (str(e) + "- required module not found") -LED_ON = '1' -LED_OFF = '0' - PWM_MAX = 255 FAN_PATH = "/var/run/hw-management/thermal/" -LED_PATH = "/var/run/hw-management/led/" +CONFIG_PATH = "/var/run/hw-management/config" # fan_dir isn't supported on Spectrum 1. It is supported on Spectrum 2 and later switches FAN_DIR = "/var/run/hw-management/system/fan_dir" +COOLING_STATE_PATH = "/var/run/hw-management/thermal/cooling_cur_state" class Fan(FanBase): """Platform-specific Fan class""" STATUS_LED_COLOR_ORANGE = "orange" - - def __init__(self, has_fan_dir, fan_index, drawer_index = 1, psu_fan = False): + min_cooling_level = 2 + MIN_VALID_COOLING_LEVEL = 1 + MAX_VALID_COOLING_LEVEL = 10 + # PSU fan speed vector + PSU_FAN_SPEED = ['0x3c', '0x3c', '0x3c', '0x3c', '0x3c', + '0x3c', '0x3c', '0x46', '0x50', '0x5a', '0x64'] + + def __init__(self, fan_index, fan_drawer, position, psu_fan = False, psu=None): + super(Fan, self).__init__() + # API index is starting from 0, Mellanox platform index is starting from 1 self.index = fan_index + 1 - self.drawer_index = drawer_index + 1 + self.fan_drawer = fan_drawer + self.position = position self.is_psu_fan = psu_fan + self.psu = psu + if self.fan_drawer: + self.led = ComponentFaultyIndicator(self.fan_drawer.get_led()) + elif self.is_psu_fan: + from .psu import Psu + self.led = ComponentFaultyIndicator(Psu.get_shared_led()) + else: + self.led = FanLed(self.index) - self.fan_min_speed_path = "fan{}_min".format(self.index) if not self.is_psu_fan: self.fan_speed_get_path = "fan{}_speed_get".format(self.index) self.fan_speed_set_path = "fan{}_speed_set".format(self.index) - self.fan_presence_path = "fan{}_status".format(self.drawer_index) - self.fan_max_speed_path = "fan{}_max".format(self.index) - self._name = "fan{}".format(fan_index + 1) + self.fan_max_speed_path = os.path.join(FAN_PATH, "fan{}_max".format(self.index)) + self.fan_min_speed_path = os.path.join(FAN_PATH, "fan{}_min".format(self.index)) + self._name = "fan{}".format(self.index) else: self.fan_speed_get_path = "psu{}_fan1_speed_get".format(self.index) self.fan_presence_path = "psu{}_fan1_speed_get".format(self.index) - self._name = 'psu_{}_fan_{}'.format(self.index, fan_index) - self.fan_max_speed_path = None + self._name = 'psu_{}_fan_{}'.format(self.index, 1) + self.fan_max_speed_path = os.path.join(CONFIG_PATH, "psu_fan_max") + self.fan_min_speed_path = os.path.join(CONFIG_PATH, "psu_fan_min") + self.psu_i2c_bus_path = os.path.join(CONFIG_PATH, 'psu{0}_i2c_bus'.format(self.index)) + self.psu_i2c_addr_path = os.path.join(CONFIG_PATH, 'psu{0}_i2c_addr'.format(self.index)) + self.psu_i2c_command_path = os.path.join(CONFIG_PATH, 'fan_command') + self.fan_status_path = "fan{}_fault".format(self.index) - self.fan_green_led_path = "led_fan{}_green".format(self.drawer_index) - self.fan_red_led_path = "led_fan{}_red".format(self.drawer_index) - self.fan_orange_led_path = "led_fan{}_orange".format(self.drawer_index) self.fan_pwm_path = "pwm1" - self.fan_led_cap_path = "led_fan{}_capability".format(self.drawer_index) - if has_fan_dir: - self.fan_dir = FAN_DIR - else: - self.fan_dir = None def get_direction(self): @@ -80,20 +94,10 @@ def get_direction(self): 1 stands for forward, in other words intake 0 stands for reverse, in other words exhaust """ - if not self.fan_dir or self.is_psu_fan: + if self.is_psu_fan: return self.FAN_DIRECTION_NOT_APPLICABLE - - try: - with open(os.path.join(self.fan_dir), 'r') as fan_dir: - fan_dir_bits = int(fan_dir.read()) - fan_mask = 1 << self.index - 1 - if fan_dir_bits & fan_mask: - return self.FAN_DIRECTION_INTAKE - else: - return self.FAN_DIRECTION_EXHAUST - except (ValueError, IOError) as e: - raise RuntimeError("Failed to read fan direction status to {}".format(repr(e))) - + else: + return self.fan_drawer.get_direction() def get_name(self): return self._name @@ -107,15 +111,11 @@ def get_status(self): """ status = 0 if self.is_psu_fan: - status = 1 + status = 0 else: - try: - with open(os.path.join(FAN_PATH, self.fan_status_path), 'r') as fault_status: - status = int(fault_status.read()) - except (ValueError, IOError): - status = 0 + status = read_int_from_file(os.path.join(FAN_PATH, self.fan_status_path), 1) - return status == 1 + return status == 0 def get_presence(self): @@ -125,43 +125,10 @@ def get_presence(self): Returns: bool: True if fan is present, False if not """ - status = 0 if self.is_psu_fan: - if os.path.exists(os.path.join(FAN_PATH, self.fan_presence_path)): - status = 1 - else: - status = 0 + return self.psu.get_presence() and self.psu.get_powergood_status() and os.path.exists(os.path.join(FAN_PATH, self.fan_presence_path)) else: - try: - with open(os.path.join(FAN_PATH, self.fan_presence_path), 'r') as presence_status: - status = int(presence_status.read()) - except (ValueError, IOError): - status = 0 - - return status == 1 - - - def _get_min_speed_in_rpm(self): - speed = 0 - try: - with open(os.path.join(FAN_PATH, self.fan_min_speed_path), 'r') as min_fan_speed: - speed = int(min_fan_speed.read()) - except (ValueError, IOError): - speed = 0 - - return speed - - - def _get_max_speed_in_rpm(self): - speed = 0 - try: - with open(os.path.join(FAN_PATH, self.fan_max_speed_path), 'r') as max_fan_speed: - speed = int(max_fan_speed.read()) - except (ValueError, IOError): - speed = 0 - - return speed - + return self.fan_drawer.get_presence() def get_speed(self): """ @@ -171,18 +138,15 @@ def get_speed(self): int: percentage of the max fan speed """ speed = 0 - try: - with open(os.path.join(FAN_PATH, self.fan_speed_get_path), 'r') as fan_curr_speed: - speed_in_rpm = int(fan_curr_speed.read()) - except (ValueError, IOError): - speed_in_rpm = 0 + speed_in_rpm = read_int_from_file(os.path.join(FAN_PATH, self.fan_speed_get_path)) - if self.fan_max_speed_path is None: - # in case of max speed unsupported, we just return speed in unit of RPM. + max_speed_in_rpm = read_int_from_file(self.fan_max_speed_path) + if max_speed_in_rpm == 0: return speed_in_rpm - max_speed_in_rpm = self._get_max_speed_in_rpm() - speed = 100*speed_in_rpm/max_speed_in_rpm + speed = 100*speed_in_rpm//max_speed_in_rpm + if speed > 100: + speed = 100 return speed @@ -195,18 +159,15 @@ def get_target_speed(self): int: percentage of the max fan speed """ if self.is_psu_fan: - # Not like system fan, psu fan speed can not be modified, so target speed is N/A - return self.get_speed() + try: + # Get PSU fan target speed according to current system cooling level + cooling_level = self.get_cooling_level() + return int(self.PSU_FAN_SPEED[cooling_level], 16) + except Exception: + return self.get_speed() - try: - with open(os.path.join(FAN_PATH, self.fan_speed_set_path), 'r') as fan_pwm: - pwm = int(fan_pwm.read()) - except (ValueError, IOError): - pwm = 0 - - speed = int(round(pwm*100.0/PWM_MAX)) - - return speed + pwm = read_int_from_file(os.path.join(FAN_PATH, self.fan_speed_set_path)) + return int(round(pwm*100.0/PWM_MAX)) def set_speed(self, speed): @@ -221,33 +182,40 @@ def set_speed(self, speed): bool: True if set success, False if fail. """ status = True - pwm = int(round(PWM_MAX*speed/100.0)) if self.is_psu_fan: - #PSU fan speed is not setable. - return False - + if not self.get_presence(): + return False + from .thermal import logger + try: + bus = read_str_from_file(self.psu_i2c_bus_path, raise_exception=True) + addr = read_str_from_file(self.psu_i2c_addr_path, raise_exception=True) + command = read_str_from_file(self.psu_i2c_command_path, raise_exception=True) + speed = Fan.PSU_FAN_SPEED[int(speed // 10)] + command = "i2cset -f -y {0} {1} {2} {3} wp".format(bus, addr, command, speed) + subprocess.check_call(command, shell = True, universal_newlines=True) + return True + except subprocess.CalledProcessError as ce: + logger.log_error('Failed to call command {}, return code={}, command output={}'.format(ce.cmd, ce.returncode, ce.output)) + return False + except Exception as e: + logger.log_error('Failed to set PSU FAN speed - {}'.format(e)) + return False + try: - with open(os.path.join(FAN_PATH, self.fan_speed_set_path), 'w') as fan_pwm: - fan_pwm.write(str(pwm)) + cooling_level = int(speed // 10) + if cooling_level < self.min_cooling_level: + cooling_level = self.min_cooling_level + speed = self.min_cooling_level * 10 + self.set_cooling_level(cooling_level, cooling_level) + pwm = int(round(PWM_MAX*speed/100.0)) + write_file(os.path.join(FAN_PATH, self.fan_speed_set_path), pwm, raise_exception=True) except (ValueError, IOError): status = False return status - def _get_led_capability(self): - cap_list = None - try: - with open(os.path.join(LED_PATH, self.fan_led_cap_path), 'r') as fan_led_cap: - caps = fan_led_cap.read() - cap_list = caps.split() - except (ValueError, IOError): - status = 0 - - return cap_list - - def set_status_led(self, color): """ Set led to expected color @@ -259,48 +227,7 @@ def set_status_led(self, color): Returns: bool: True if set success, False if fail. """ - led_cap_list = self._get_led_capability() - if led_cap_list is None: - return False - - if self.is_psu_fan: - # PSU fan led status is not able to set - return False - status = False - try: - if color == self.STATUS_LED_COLOR_GREEN: - with open(os.path.join(LED_PATH, self.fan_green_led_path), 'w') as fan_led: - fan_led.write(LED_ON) - status = True - elif color == self.STATUS_LED_COLOR_RED: - # Some fan don't support red led but support orange led, in this case we set led to orange - if self.STATUS_LED_COLOR_RED in led_cap_list: - led_path = os.path.join(LED_PATH, self.fan_red_led_path) - elif self.STATUS_LED_COLOR_ORANGE in led_cap_list: - led_path = os.path.join(LED_PATH, self.fan_orange_led_path) - else: - return False - with open(led_path, 'w') as fan_led: - fan_led.write(LED_ON) - status = True - elif color == self.STATUS_LED_COLOR_OFF: - if self.STATUS_LED_COLOR_GREEN in led_cap_list: - with open(os.path.join(LED_PATH, self.fan_green_led_path), 'w') as fan_led: - fan_led.write(str(LED_OFF)) - if self.STATUS_LED_COLOR_RED in led_cap_list: - with open(os.path.join(LED_PATH, self.fan_red_led_path), 'w') as fan_led: - fan_led.write(str(LED_OFF)) - if self.STATUS_LED_COLOR_ORANGE in led_cap_list: - with open(os.path.join(LED_PATH, self.fan_orange_led_path), 'w') as fan_led: - fan_led.write(str(LED_OFF)) - - status = True - else: - status = False - except (ValueError, IOError): - status = False - - return status + return self.led.set_status(color) def get_status_led(self): @@ -310,26 +237,7 @@ def get_status_led(self): Returns: A string, one of the predefined STATUS_LED_COLOR_* strings above """ - led_cap_list = self._get_led_capability() - if led_cap_list is None: - return self.STATUS_LED_COLOR_OFF - - try: - with open(os.path.join(LED_PATH, self.fan_green_led_path), 'r') as fan_led: - if LED_OFF != fan_led.read().rstrip('\n'): - return self.STATUS_LED_COLOR_GREEN - if self.STATUS_LED_COLOR_RED in led_cap_list: - with open(os.path.join(LED_PATH, self.fan_red_led_path), 'r') as fan_led: - if LED_OFF != fan_led.read().rstrip('\n'): - return self.STATUS_LED_COLOR_RED - if self.STATUS_LED_COLOR_ORANGE in led_cap_list: - with open(os.path.join(LED_PATH, self.fan_orange_led_path), 'r') as fan_led: - if LED_OFF != fan_led.read().rstrip('\n'): - return self.STATUS_LED_COLOR_RED - except (ValueError, IOError) as e: - raise RuntimeError("Failed to read led status for fan {} due to {}".format(self.index, repr(e))) - - return self.STATUS_LED_COLOR_OFF + return self.led.get_status() def get_speed_tolerance(self): @@ -340,5 +248,55 @@ def get_speed_tolerance(self): An integer, the percentage of variance from target speed which is considered tolerable """ - # The tolerance value is fixed as 20% for all the Mellanox platform - return 20 + # The tolerance value is fixed as 50% for all the Mellanox platform + return 50 + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device + Returns: + integer: The 1-based relative physical position in parent device + """ + return self.position + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return False + + @classmethod + def set_cooling_level(cls, level, cur_state): + """ + Change cooling level. The input level should be an integer value [1, 10]. + 1 means 10%, 2 means 20%, 10 means 100%. + """ + if not isinstance(level, int): + raise RuntimeError("Failed to set cooling level, input parameter must be integer") + + if level < cls.MIN_VALID_COOLING_LEVEL or level > cls.MAX_VALID_COOLING_LEVEL: + raise RuntimeError("Failed to set cooling level, level value must be in range [{}, {}], got {}".format( + cls.MIN_VALID_COOLING_LEVEL, + cls.MAX_VALID_COOLING_LEVEL, + level + )) + + try: + # Reset FAN cooling level vector. According to low level team, + # if we need set cooling level to X, we need first write a (10+X) + # to cooling_cur_state file to reset the cooling level vector. + write_file(COOLING_STATE_PATH, level + 10, raise_exception=True) + + # We need set cooling level after resetting the cooling level vector + write_file(COOLING_STATE_PATH, cur_state, raise_exception=True) + except (ValueError, IOError) as e: + raise RuntimeError("Failed to set cooling level - {}".format(e)) + + @classmethod + def get_cooling_level(cls): + try: + return read_int_from_file(COOLING_STATE_PATH, raise_exception=True) + except (ValueError, IOError) as e: + raise RuntimeError("Failed to get cooling level - {}".format(e)) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/fan_drawer.py b/platform/mellanox/mlnx-platform-api/sonic_platform/fan_drawer.py new file mode 100644 index 000000000000..66ee39491735 --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/fan_drawer.py @@ -0,0 +1,120 @@ +#!/usr/bin/env python + +############################################################################# +# Mellanox +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Fan Drawer status which are available in the platform +# +############################################################################# + +import os + +try: + from sonic_platform_base.fan_drawer_base import FanDrawerBase + from sonic_platform_base.fan_base import FanBase + from .led import FanLed, SharedLed +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + + +class MellanoxFanDrawer(FanDrawerBase): + def __init__(self, index, fan_data): + from .fan import FAN_PATH + super(MellanoxFanDrawer, self).__init__() + self._index = index + 1 + self._fan_data = fan_data + self._presence_path = os.path.join(FAN_PATH, 'fan{}_status'.format(self._index)) + self._led = None + + def get_index(self): + return self._index + + def get_led(self): + return self._led + + def get_presence(self): + if not self._fan_data['hot_swappable']: + return True + + status = 0 + try: + with open(self._presence_path, 'r') as presence_status: + status = int(presence_status.read()) + except (ValueError, IOError) as e: + status = 0 + + return status == 1 + + def get_direction(self): + if not self._fan_data['support_fan_direction'] or not self.get_presence(): + return FanBase.FAN_DIRECTION_NOT_APPLICABLE + + try: + from .fan import FAN_DIR + with open(FAN_DIR, 'r') as fan_dir: + fan_dir_bits = int(fan_dir.read()) + fan_mask = 1 << self._index - 1 + if fan_dir_bits & fan_mask: + return FanBase.FAN_DIRECTION_INTAKE + else: + return FanBase.FAN_DIRECTION_EXHAUST + except (ValueError, IOError) as e: + raise RuntimeError("Failed to read fan direction status to {}".format(repr(e))) + + def set_status_led(self, color): + """ + Sets the state of the fan drawer status LED + + Args: + color: A string representing the color with which to set the + fan drawer status LED + + Returns: + bool: True if status LED state is set successfully, False if not + """ + return True + + def get_status_led(self): + """ + Gets the state of the fan drawer LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + return self._led.get_status() + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device + Returns: + integer: The 1-based relative physical position in parent device + """ + return self._index + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return self._fan_data['hot_swappable'] + + +class RealDrawer(MellanoxFanDrawer): + def __init__(self, index, fan_data): + super(RealDrawer, self).__init__(index, fan_data) + self._name = 'drawer{}'.format(self._index) + self._led = SharedLed(FanLed(self._index)) + + def get_name(self): + return self._name + + +class VirtualDrawer(MellanoxFanDrawer): + def __init__(self, index, fan_data): + super(VirtualDrawer, self).__init__(index, fan_data) + self._led = SharedLed(FanLed(None)) + + def get_name(self): + return 'N/A' diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/led.py b/platform/mellanox/mlnx-platform-api/sonic_platform/led.py new file mode 100644 index 000000000000..2e6002b77e6f --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/led.py @@ -0,0 +1,319 @@ +import os + + +class Led(object): + STATUS_LED_COLOR_GREEN = 'green' + STATUS_LED_COLOR_GREEN_BLINK = 'green_blink' + STATUS_LED_COLOR_RED = 'red' + STATUS_LED_COLOR_RED_BLINK = 'red_blink' + STATUS_LED_COLOR_ORANGE = 'orange' + STATUS_LED_COLOR_ORANGE_BLINK = 'orange_blink' + STATUS_LED_COLOR_OFF = 'off' + + LED_ON = '1' + LED_OFF = '0' + LED_BLINK = '50' + + LED_PATH = "/var/run/hw-management/led/" + + def set_status(self, color): + led_cap_list = self.get_capability() + if led_cap_list is None: + return False + + status = False + try: + self._stop_blink(led_cap_list) + blink_pos = color.find('blink') + if blink_pos != -1: + return self._set_status_blink(color, blink_pos, led_cap_list) + + if color == Led.STATUS_LED_COLOR_GREEN: + with open(self.get_green_led_path(), 'w') as led: + led.write(Led.LED_ON) + status = True + elif color == Led.STATUS_LED_COLOR_RED: + # Some led don't support red led but support orange led, in this case we set led to orange + if Led.STATUS_LED_COLOR_RED in led_cap_list: + led_path = self.get_red_led_path() + elif Led.STATUS_LED_COLOR_ORANGE in led_cap_list: + led_path = self.get_orange_led_path() + else: + return False + + with open(led_path, 'w') as led: + led.write(Led.LED_ON) + status = True + elif color == Led.STATUS_LED_COLOR_OFF: + if Led.STATUS_LED_COLOR_GREEN in led_cap_list: + with open(self.get_green_led_path(), 'w') as led: + led.write(Led.LED_OFF) + if Led.STATUS_LED_COLOR_RED in led_cap_list: + with open(self.get_red_led_path(), 'w') as led: + led.write(Led.LED_OFF) + if Led.STATUS_LED_COLOR_ORANGE in led_cap_list: + with open(self.get_orange_led_path(), 'w') as led: + led.write(Led.LED_OFF) + + status = True + else: + status = False + except (ValueError, IOError): + status = False + + return status + + def _set_status_blink(self, color, blink_pos, led_cap_list): + if color not in led_cap_list: + if color == Led.STATUS_LED_COLOR_RED_BLINK and Led.STATUS_LED_COLOR_ORANGE_BLINK in led_cap_list: + color = Led.STATUS_LED_COLOR_ORANGE_BLINK + elif color == Led.STATUS_LED_COLOR_ORANGE_BLINK and Led.STATUS_LED_COLOR_RED_BLINK in led_cap_list: + color = Led.STATUS_LED_COLOR_RED_BLINK + else: + return False + + if Led.STATUS_LED_COLOR_GREEN_BLINK == color: + self._set_led_blink_status(self.get_green_led_delay_on_path(), self.get_green_led_delay_off_path(), Led.LED_BLINK) + elif Led.STATUS_LED_COLOR_RED_BLINK == color: + self._set_led_blink_status(self.get_red_led_delay_on_path(), self.get_red_led_delay_off_path(), Led.LED_BLINK) + elif Led.STATUS_LED_COLOR_ORANGE_BLINK == color: + self._set_led_blink_status(self.get_orange_led_delay_on_path(), self.get_orange_led_delay_off_path(), Led.LED_BLINK) + else: + return False + + return True + + def _stop_blink(self, led_cap_list): + try: + if Led.STATUS_LED_COLOR_GREEN_BLINK in led_cap_list: + self._set_led_blink_status(self.get_green_led_delay_on_path(), self.get_green_led_delay_off_path(), Led.LED_OFF) + if Led.STATUS_LED_COLOR_RED_BLINK in led_cap_list: + self._set_led_blink_status(self.get_red_led_delay_on_path(), self.get_red_led_delay_off_path(), Led.LED_OFF) + if Led.STATUS_LED_COLOR_ORANGE_BLINK in led_cap_list: + self._set_led_blink_status(self.get_orange_led_delay_on_path(), self.get_orange_led_delay_off_path(), Led.LED_OFF) + except Exception as e: + return + + def _set_led_blink_status(self, delay_on_file, delay_off_file, value): + with open(delay_on_file, 'w') as led: + led.write(value) + with open(delay_off_file, 'w') as led: + led.write(value) + + def get_status(self): + led_cap_list = self.get_capability() + if led_cap_list is None: + return Led.STATUS_LED_COLOR_OFF + + try: + blink_status = self._get_blink_status(led_cap_list) + if blink_status is not None: + return blink_status + + with open(self.get_green_led_path(), 'r') as led: + if Led.LED_OFF != led.read().rstrip('\n'): + return Led.STATUS_LED_COLOR_GREEN + + if Led.STATUS_LED_COLOR_RED in led_cap_list: + with open(self.get_red_led_path(), 'r') as led: + if Led.LED_OFF != led.read().rstrip('\n'): + return Led.STATUS_LED_COLOR_RED + if Led.STATUS_LED_COLOR_ORANGE in led_cap_list: + with open(self.get_orange_led_path(), 'r') as led: + if Led.LED_OFF != led.read().rstrip('\n'): + return Led.STATUS_LED_COLOR_RED + except (ValueError, IOError) as e: + raise RuntimeError("Failed to read led status due to {}".format(repr(e))) + + return Led.STATUS_LED_COLOR_OFF + + def _get_blink_status(self, led_cap_list): + try: + if Led.STATUS_LED_COLOR_GREEN_BLINK in led_cap_list: + if self._is_led_blinking(self.get_green_led_delay_on_path(), self.get_green_led_delay_off_path()): + return Led.STATUS_LED_COLOR_GREEN_BLINK + if Led.STATUS_LED_COLOR_RED_BLINK in led_cap_list: + if self._is_led_blinking(self.get_red_led_delay_on_path(), self.get_red_led_delay_off_path()): + return Led.STATUS_LED_COLOR_RED_BLINK + if Led.STATUS_LED_COLOR_ORANGE_BLINK in led_cap_list: + if self._is_led_blinking(self.get_orange_led_delay_on_path(), self.get_orange_led_delay_off_path()): + return Led.STATUS_LED_COLOR_ORANGE_BLINK + except Exception as e: + return None + + return None + + def _is_led_blinking(self, delay_on_file, delay_off_file): + with open(delay_on_file, 'r') as led: + delay_on = led.read().rstrip('\n') + with open(delay_off_file, 'r') as led: + delay_off = led.read().rstrip('\n') + return delay_on != Led.LED_OFF and delay_off != Led.LED_OFF + + def get_capability(self): + cap_list = None + try: + with open(self.get_led_cap_path(), 'r') as led_cap: + caps = led_cap.read() + cap_list = set(caps.split()) + except (ValueError, IOError): + pass + + return cap_list + + def get_green_led_path(self): + pass + + def get_green_led_delay_off_path(self): + return '{}_delay_off'.format(self.get_green_led_path()) + + def get_green_led_delay_on_path(self): + return '{}_delay_on'.format(self.get_green_led_path()) + + def get_red_led_path(self): + pass + + def get_red_led_delay_off_path(self): + return '{}_delay_off'.format(self.get_red_led_path()) + + def get_red_led_delay_on_path(self): + return '{}_delay_on'.format(self.get_red_led_path()) + + def get_orange_led_path(self): + pass + + def get_orange_led_delay_off_path(self): + return '{}_delay_off'.format(self.get_orange_led_path()) + + def get_orange_led_delay_on_path(self): + return '{}_delay_on'.format(self.get_orange_led_path()) + + def get_led_cap_path(self): + pass + + +class FanLed(Led): + LED_PATH = "/var/run/hw-management/led/" + + def __init__(self, index): + if index is not None: + self._green_led_path = os.path.join(Led.LED_PATH, "led_fan{}_green".format(index)) + self._red_led_path = os.path.join(Led.LED_PATH, "led_fan{}_red".format(index)) + self._orange_led_path = os.path.join(Led.LED_PATH, "led_fan{}_orange".format(index)) + self._led_cap_path = os.path.join(Led.LED_PATH, "led_fan{}_capability".format(index)) + else: + self._green_led_path = os.path.join(Led.LED_PATH, "led_fan_green") + self._red_led_path = os.path.join(Led.LED_PATH, "led_fan_red") + self._orange_led_path = os.path.join(Led.LED_PATH, "led_fan_orange") + self._led_cap_path = os.path.join(Led.LED_PATH, "led_fan_capability") + + self.set_status(Led.STATUS_LED_COLOR_GREEN) + + def get_green_led_path(self): + return self._green_led_path + + def get_red_led_path(self): + return self._red_led_path + + def get_orange_led_path(self): + return self._orange_led_path + + def get_led_cap_path(self): + return self._led_cap_path + + +class PsuLed(Led): + def __init__(self, index): + if index is not None: + self._green_led_path = os.path.join(Led.LED_PATH, "led_psu{}_green".format(index)) + self._red_led_path = os.path.join(Led.LED_PATH, "led_psu{}_red".format(index)) + self._orange_led_path = os.path.join(Led.LED_PATH, "led_psu{}_orange".format(index)) + self._led_cap_path = os.path.join(Led.LED_PATH, "led_psu{}_capability".format(index)) + else: + self._green_led_path = os.path.join(Led.LED_PATH, "led_psu_green") + self._red_led_path = os.path.join(Led.LED_PATH, "led_psu_red") + self._orange_led_path = os.path.join(Led.LED_PATH, "led_psu_orange") + self._led_cap_path = os.path.join(Led.LED_PATH, "led_psu_capability") + + self.set_status(Led.STATUS_LED_COLOR_GREEN) + + def get_green_led_path(self): + return self._green_led_path + + def get_red_led_path(self): + return self._red_led_path + + def get_orange_led_path(self): + return self._orange_led_path + + def get_led_cap_path(self): + return self._led_cap_path + + +class SystemLed(Led): + def __init__(self): + self._green_led_path = os.path.join(Led.LED_PATH, "led_status_green") + self._red_led_path = os.path.join(Led.LED_PATH, "led_status_red") + self._orange_led_path = os.path.join(Led.LED_PATH, "led_status_orange") + self._led_cap_path = os.path.join(Led.LED_PATH, "led_status_capability") + + def get_green_led_path(self): + return self._green_led_path + + def get_red_led_path(self): + return self._red_led_path + + def get_orange_led_path(self): + return self._orange_led_path + + def get_led_cap_path(self): + return self._led_cap_path + + +class SharedLed(object): + LED_PRIORITY = { + Led.STATUS_LED_COLOR_RED: 0, + Led.STATUS_LED_COLOR_GREEN: 1 + } + + def __init__(self, led): + self._led = led + self._virtual_leds = [] + + def add_virtual_leds(self, led): + self._virtual_leds.append(led) + + def update_status_led(self): + target_color = Led.STATUS_LED_COLOR_GREEN + for virtual_led in self._virtual_leds: + try: + if SharedLed.LED_PRIORITY[virtual_led.get_led_color()] < SharedLed.LED_PRIORITY[target_color]: + target_color = virtual_led.get_led_color() + except KeyError: + return False + return self._led.set_status(target_color) + + def get_status(self): + return self._led.get_status() + + +class ComponentFaultyIndicator(object): + def __init__(self, shared_led): + self._color = Led.STATUS_LED_COLOR_GREEN + self._shared_led = shared_led + self._shared_led.add_virtual_leds(self) + + def set_status(self, color): + current_color = self._color + self._color = color + if self._shared_led.update_status_led(): + return True + else: + self._color = current_color + return False + + def get_led_color(self): + return self._color + + def get_status(self): + return self._shared_led.get_status() diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py b/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py index 6d81ca3e7b51..f2a8af954790 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py @@ -19,6 +19,8 @@ def __init__(self): if self._is_host(): self._chassis = Chassis() self._chassis.initialize_components() + self._chassis.initizalize_system_led() + self._chassis.initialize_eeprom() else: self._chassis = Chassis() self._chassis.initialize_psu() @@ -33,14 +35,18 @@ def _is_host(self): """ is_host = False try: - proc = subprocess.Popen("docker --version 2>/dev/null", stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT) + proc = subprocess.Popen("docker --version 2>/dev/null", + stdout=subprocess.PIPE, + shell=True, + stderr=subprocess.STDOUT, + universal_newlines=True) stdout = proc.communicate()[0] proc.wait() result = stdout.rstrip('\n') if result != '': is_host = True - except OSError, e: + except OSError as e: pass return is_host diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py index 31887ddf4f25..7b73b7196ce2 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py @@ -11,13 +11,13 @@ try: import os.path from sonic_platform_base.psu_base import PsuBase - from sonic_daemon_base.daemon_base import Logger + from sonic_py_common.logger import Logger from sonic_platform.fan import Fan + from .led import PsuLed, SharedLed, ComponentFaultyIndicator + from .device_data import DEVICE_DATA except ImportError as e: raise ImportError (str(e) + "- required module not found") -LED_ON = '1' -LED_OFF = '0' # Global logger class instance logger = Logger() @@ -28,16 +28,11 @@ PSU_VOLTAGE = "voltage" PSU_POWER = "power" -LED_PATH = "/var/run/hw-management/led/" +# in most platforms 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 -# SKUs with unplugable PSUs: -# 1. don't have psuX_status and should be treated as always present -# 2. don't have voltage, current and power values -hwsku_dict_with_unplugable_psu = ['ACS-MSN2010', 'ACS-MSN2100'] +platform_dict_psu = {'x86_64-mlnx_msn3420-r0':1, 'x86_64-mlnx_msn3700-r0': 1, 'x86_64-mlnx_msn3700c-r0': 1, 'x86_64-mlnx_msn3800-r0': 1, 'x86_64-mlnx_msn4600c-r0':1, 'x86_64-mlnx_msn4700-r0': 1, 'x86_64-mlnx_msn4410-r0': 1} -# 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} psu_profile_list = [ # default filename convention { @@ -45,7 +40,7 @@ PSU_VOLTAGE : "power/psu{}_volt", PSU_POWER : "power/psu{}_power" }, - # for 3700, 3700c, 3800 + # for 3420, 3700, 3700c, 3800, 4600c, 4700 { PSU_CURRENT : "power/psu{}_curr", PSU_VOLTAGE : "power/psu{}_volt_out2", @@ -56,9 +51,9 @@ class Psu(PsuBase): """Platform-specific Psu class""" - STATUS_LED_COLOR_ORANGE = "orange" + shared_led = None - def __init__(self, psu_index, sku): + def __init__(self, psu_index, platform): global psu_list PsuBase.__init__(self) # PSU is 1-based on Mellanox platform @@ -66,23 +61,27 @@ def __init__(self, psu_index, sku): psu_list.append(self.index) self.psu_path = "/var/run/hw-management/" psu_oper_status = "thermal/psu{}_pwr_status".format(self.index) - #psu_oper_status should always be present for all SKUs + #psu_oper_status should always be present for all platforms self.psu_oper_status = os.path.join(self.psu_path, psu_oper_status) self._name = "PSU{}".format(psu_index + 1) - if sku in hwsku_dict_psu: - filemap = psu_profile_list[hwsku_dict_psu[sku]] + if platform in platform_dict_psu: + filemap = psu_profile_list[platform_dict_psu[platform]] else: filemap = psu_profile_list[0] - if sku in hwsku_dict_with_unplugable_psu: - self.always_presence = True + self.psu_data = DEVICE_DATA[platform]['psus'] + + if not self.psu_data['hot_swappable']: + self.always_present = True self.psu_voltage = None self.psu_current = None self.psu_power = None self.psu_presence = None + self.psu_temp = None + self.psu_temp_threshold = None else: - self.always_presence = False + self.always_present = False psu_voltage = filemap[PSU_VOLTAGE].format(self.index) psu_voltage = os.path.join(self.psu_path, psu_voltage) self.psu_voltage = psu_voltage @@ -99,18 +98,27 @@ def __init__(self, psu_index, sku): psu_presence = os.path.join(self.psu_path, psu_presence) self.psu_presence = psu_presence - fan = Fan(sku, psu_index, psu_index, True) - if fan.get_presence(): + self.psu_temp = os.path.join(self.psu_path, 'thermal/psu{}_temp'.format(self.index)) + self.psu_temp_threshold = os.path.join(self.psu_path, 'thermal/psu{}_temp_max'.format(self.index)) + + # unplugable PSU has no FAN + if self.psu_data['hot_swappable']: + fan = Fan(psu_index, None, 1, True, self) self._fan_list.append(fan) + if self.psu_data['led_num'] == 1: + self.led = ComponentFaultyIndicator(Psu.get_shared_led()) + else: # 2010/2100 + self.led = PsuLed(self.index) + + # initialize thermal for PSU + from .thermal import initialize_psu_thermals + initialize_psu_thermals(platform, self._thermal_list, self.index, self.get_power_available_status) + + def get_name(self): return self._name - self.psu_green_led_path = "led_psu_green" - self.psu_red_led_path = "led_psu_red" - self.psu_orange_led_path = "led_psu_orange" - self.psu_led_cap_path = "led_psu_capability" - def _read_generic_file(self, filename, len): """ @@ -118,8 +126,10 @@ def _read_generic_file(self, filename, len): """ result = 0 try: + if not os.path.exists(filename): + return result with open(filename, 'r') as fileobj: - result = int(fileobj.read()) + result = int(fileobj.read().strip()) except Exception as e: logger.log_info("Fail to read file {} due to {}".format(filename, repr(e))) return result @@ -144,8 +154,8 @@ def get_presence(self): Returns: bool: True if PSU is present, False if not """ - if self.always_presence: - return self.always_presence + if self.always_present: + return self.always_present else: status = self._read_generic_file(self.psu_presence, 0) return status == 1 @@ -192,19 +202,6 @@ def get_power(self): else: return None - - def _get_led_capability(self): - cap_list = None - try: - with open(os.path.join(LED_PATH, self.psu_led_cap_path), 'r') as psu_led_cap: - caps = psu_led_cap.read() - cap_list = caps.split() - except (ValueError, IOError): - status = 0 - - return cap_list - - def set_status_led(self, color): """ Sets the state of the PSU status LED @@ -219,45 +216,7 @@ def set_status_led(self, color): Notes: Only one led for all PSUs. """ - led_cap_list = self._get_led_capability() - if led_cap_list is None: - return False - - status = False - try: - if color == self.STATUS_LED_COLOR_GREEN: - with open(os.path.join(LED_PATH, self.psu_green_led_path), 'w') as psu_led: - psu_led.write(LED_ON) - status = True - elif color == self.STATUS_LED_COLOR_RED: - # Some fan don't support red led but support orange led, in this case we set led to orange - if self.STATUS_LED_COLOR_RED in led_cap_list: - led_path = os.path.join(LED_PATH, self.psu_red_led_path) - elif self.STATUS_LED_COLOR_ORANGE in led_cap_list: - led_path = os.path.join(LED_PATH, self.psu_orange_led_path) - else: - return False - with open(led_path, 'w') as psu_led: - psu_led.write(LED_ON) - status = True - elif color == self.STATUS_LED_COLOR_OFF: - if self.STATUS_LED_COLOR_GREEN in led_cap_list: - with open(os.path.join(LED_PATH, self.psu_green_led_path), 'w') as psu_led: - psu_led.write(str(LED_OFF)) - if self.STATUS_LED_COLOR_RED in led_cap_list: - with open(os.path.join(LED_PATH, self.psu_red_led_path), 'w') as psu_led: - psu_led.write(str(LED_OFF)) - if self.STATUS_LED_COLOR_ORANGE in led_cap_list: - with open(os.path.join(LED_PATH, self.psu_orange_led_path), 'w') as psu_led: - psu_led.write(str(LED_OFF)) - - status = True - else: - status = False - except (ValueError, IOError): - status = False - - return status + return self.led.set_status(color) def get_status_led(self): @@ -267,23 +226,102 @@ def get_status_led(self): Returns: A string, one of the predefined STATUS_LED_COLOR_* strings above """ - led_cap_list = self._get_led_capability() - if led_cap_list is None: - return self.STATUS_LED_COLOR_OFF + if self.psu_data['led_num'] == 1: + return Psu.get_shared_led().get_status() + else: + return self.led.get_status() - try: - with open(os.path.join(LED_PATH, self.psu_green_led_path), 'r') as psu_led: - if LED_OFF != psu_led.read().rstrip('\n'): - return self.STATUS_LED_COLOR_GREEN - if self.STATUS_LED_COLOR_RED in led_cap_list: - with open(os.path.join(LED_PATH, self.psu_red_led_path), 'r') as psu_led: - if LED_OFF != psu_led.read().rstrip('\n'): - return self.STATUS_LED_COLOR_RED - if self.STATUS_LED_COLOR_ORANGE in led_cap_list: - with open(os.path.join(LED_PATH, self.psu_orange_led_path), 'r') as psu_led: - if LED_OFF != psu_led.read().rstrip('\n'): - return self.STATUS_LED_COLOR_RED - except (ValueError, IOError) as e: - raise RuntimeError("Failed to read led status for psu due to {}".format(repr(e))) - - return self.STATUS_LED_COLOR_OFF + + def get_power_available_status(self): + """ + Gets the power available status + + Returns: + True if power is present and power on. + False and "absence of PSU" if power is not present. + False and "absence of power" if power is present but not power on. + """ + if not self.get_presence(): + return False, "absence of PSU" + elif not self.get_powergood_status(): + return False, "absence of power" + else: + return True, "" + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device + Returns: + integer: The 1-based relative physical position in parent device + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return self.psu_data['hot_swappable'] + + @classmethod + def get_shared_led(cls): + if not cls.shared_led: + cls.shared_led = SharedLed(PsuLed(None)) + return cls.shared_led + + def get_temperature(self): + """ + Retrieves current temperature reading from PSU + + Returns: + A float number of current temperature in Celsius up to nearest thousandth + of one degree Celsius, e.g. 30.125 + """ + if self.psu_temp is not None and self.get_powergood_status(): + try: + temp = self._read_generic_file(self.psu_temp, 0) + return float(temp) / 1000 + except Exception as e: + logger.log_info("Fail to get temperature for PSU {} due to - {}".format(self._name, repr(e))) + + return None + + def get_temperature_high_threshold(self): + """ + Retrieves the high threshold temperature of PSU + + Returns: + A float number, the high threshold temperature of PSU in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + if self.psu_temp_threshold is not None and self.get_powergood_status(): + try: + temp_threshold = self._read_generic_file(self.psu_temp_threshold, 0) + return float(temp_threshold) / 1000 + except Exception as e: + logger.log_info("Fail to get temperature threshold for PSU {} due to - {}".format(self._name, repr(e))) + + return None + + def get_voltage_high_threshold(self): + """ + Retrieves the high threshold PSU voltage output + + Returns: + A float number, the high threshold output voltage in volts, + e.g. 12.1 + """ + # hw-management doesn't expose those sysfs for now + raise NotImplementedError + + def get_voltage_low_threshold(self): + """ + Retrieves the low threshold PSU voltage output + + Returns: + A float number, the low threshold output voltage in volts, + e.g. 12.1 + """ + # hw-management doesn't expose those sysfs for now + raise NotImplementedError diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py index 254d9c2e3e58..39ced89fcd59 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py @@ -9,7 +9,6 @@ ############################################################################# try: - import os import subprocess import time from sonic_platform_base.sfp_base import SfpBase @@ -19,13 +18,23 @@ from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom from sonic_platform_base.sonic_sfp.inf8628 import inf8628InterfaceId - from sonic_daemon_base.daemon_base import Logger - from python_sdk_api.sxd_api import * - from python_sdk_api.sx_api import * + from sonic_platform_base.sonic_sfp.qsfp_dd import qsfp_dd_InterfaceId + from sonic_platform_base.sonic_sfp.qsfp_dd import qsfp_dd_Dom + from sonic_py_common.logger import Logger except ImportError as e: raise ImportError (str(e) + "- required module not found") +try: + # python_sdk_api does not support python3 for now. Daemons like thermalctld or psud + # also import this file without actually use the sdk lib. So we catch the ImportError + # and ignore it here. Meanwhile, we have to trigger xcvrd using python2 now because it + # uses the sdk lib. + from python_sdk_api.sxd_api import * + from python_sdk_api.sx_api import * +except ImportError as e: + pass + # definitions of the offset and width for values in XCVR info eeprom XCVR_INTFACE_BULK_OFFSET = 0 XCVR_INTFACE_BULK_WIDTH_QSFP = 20 @@ -57,18 +66,41 @@ XCVR_HW_REV_WIDTH_OSFP = 2 XCVR_HW_REV_WIDTH_QSFP = 2 XCVR_HW_REV_WIDTH_SFP = 4 +XCVR_EXT_SPECIFICATION_COMPLIANCE_OFFSET = 64 +XCVR_EXT_SPECIFICATION_COMPLIANCE_WIDTH = 1 XCVR_VENDOR_SN_OFFSET = 68 XCVR_VENDOR_SN_WIDTH = 16 XCVR_VENDOR_DATE_OFFSET = 84 XCVR_VENDOR_DATE_WIDTH = 8 XCVR_DOM_CAPABILITY_OFFSET = 92 XCVR_DOM_CAPABILITY_WIDTH = 2 + +# definitions of the offset and width for values in XCVR_QSFP_DD info eeprom +XCVR_EXT_TYPE_OFFSET_QSFP_DD = 72 +XCVR_EXT_TYPE_WIDTH_QSFP_DD = 2 +XCVR_CONNECTOR_OFFSET_QSFP_DD = 75 +XCVR_CONNECTOR_WIDTH_QSFP_DD = 1 +XCVR_CABLE_LENGTH_OFFSET_QSFP_DD = 74 +XCVR_CABLE_LENGTH_WIDTH_QSFP_DD = 1 +XCVR_HW_REV_OFFSET_QSFP_DD = 36 +XCVR_HW_REV_WIDTH_QSFP_DD = 2 +XCVR_VENDOR_DATE_OFFSET_QSFP_DD = 54 +XCVR_VENDOR_DATE_WIDTH_QSFP_DD = 8 +XCVR_DOM_CAPABILITY_OFFSET_QSFP_DD = 2 +XCVR_DOM_CAPABILITY_WIDTH_QSFP_DD = 1 +XCVR_MEDIA_TYPE_OFFSET_QSFP_DD = 85 +XCVR_MEDIA_TYPE_WIDTH_QSFP_DD = 1 +XCVR_FIRST_APPLICATION_LIST_OFFSET_QSFP_DD = 86 +XCVR_FIRST_APPLICATION_LIST_WIDTH_QSFP_DD = 32 +XCVR_SECOND_APPLICATION_LIST_OFFSET_QSFP_DD = 351 +XCVR_SECOND_APPLICATION_LIST_WIDTH_QSFP_DD = 28 + # to improve performance we retrieve all eeprom data via a single ethtool command # in function get_transceiver_info and get_transceiver_bulk_status # XCVR_INTERFACE_DATA_SIZE stands for the max size to be read # this variable is only used by get_transceiver_info. -# please be noted that each time some new value added to the function -# we should make sure that it falls into the area +# please be noted that each time some new value added to the function +# we should make sure that it falls into the area # [XCVR_INTERFACE_DATA_START, XCVR_INTERFACE_DATA_SIZE] or # adjust XCVR_INTERFACE_MAX_SIZE to contain the new data # It's same for [QSFP_DOM_BULK_DATA_START, QSFP_DOM_BULK_DATA_SIZE] and @@ -85,6 +117,9 @@ SFP_DOM_BULK_DATA_START = 96 SFP_DOM_BULK_DATA_SIZE = 10 +QSFP_DD_DOM_BULK_DATA_START = 14 +QSFP_DD_DOM_BULK_DATA_SIZE = 4 + # definitions of the offset for values in OSFP info eeprom OSFP_TYPE_OFFSET = 0 OSFP_VENDOR_NAME_OFFSET = 129 @@ -92,6 +127,13 @@ OSFP_HW_REV_OFFSET = 164 OSFP_VENDOR_SN_OFFSET = 166 +# definitions of the offset for values in QSFP_DD info eeprom +QSFP_DD_TYPE_OFFSET = 0 +QSFP_DD_VENDOR_NAME_OFFSET = 1 +QSFP_DD_VENDOR_PN_OFFSET = 20 +QSFP_DD_VENDOR_SN_OFFSET = 38 +QSFP_DD_VENDOR_OUI_OFFSET = 17 + #definitions of the offset and width for values in DOM info eeprom QSFP_DOM_REV_OFFSET = 1 QSFP_DOM_REV_WIDTH = 1 @@ -136,15 +178,38 @@ SFP_CHANNL_STATUS_OFFSET = 110 SFP_CHANNL_STATUS_WIDTH = 1 +QSFP_DD_TEMPE_OFFSET = 14 +QSFP_DD_TEMPE_WIDTH = 2 +QSFP_DD_VOLT_OFFSET = 16 +QSFP_DD_VOLT_WIDTH = 2 +QSFP_DD_TX_BIAS_OFFSET = 42 +QSFP_DD_TX_BIAS_WIDTH = 16 +QSFP_DD_RX_POWER_OFFSET = 58 +QSFP_DD_RX_POWER_WIDTH = 16 +QSFP_DD_TX_POWER_OFFSET = 26 +QSFP_DD_TX_POWER_WIDTH = 16 +QSFP_DD_CHANNL_MON_OFFSET = 26 +QSFP_DD_CHANNL_MON_WIDTH = 48 +QSFP_DD_CHANNL_DISABLE_STATUS_OFFSET = 86 +QSFP_DD_CHANNL_DISABLE_STATUS_WIDTH = 1 +QSFP_DD_CHANNL_RX_LOS_STATUS_OFFSET = 19 +QSFP_DD_CHANNL_RX_LOS_STATUS_WIDTH = 1 +QSFP_DD_CHANNL_TX_FAULT_STATUS_OFFSET = 7 +QSFP_DD_CHANNL_TX_FAULT_STATUS_WIDTH = 1 +QSFP_DD_MODULE_THRESHOLD_OFFSET = 0 +QSFP_DD_MODULE_THRESHOLD_WIDTH = 72 +QSFP_DD_CHANNL_STATUS_OFFSET = 26 +QSFP_DD_CHANNL_STATUS_WIDTH = 1 + # identifier value of xSFP module which is in the first byte of the EEPROM # if the identifier value falls into SFP_TYPE_CODE_LIST the module is treated as a SFP module and parsed according to 8472 # for QSFP_TYPE_CODE_LIST the module is treated as a QSFP module and parsed according to 8436/8636 -# Originally the type (SFP/QSFP) of each module is determined according to the SKU dictionary +# Originally the type (SFP/QSFP) of each module is determined according to the SKU dictionary # where the type of each FP port is defined. The content of EEPROM is parsed according to its type. # However, sometimes the SFP module can be fit in an adapter and then pluged into a QSFP port. # In this case the EEPROM content is in format of SFP but parsed as QSFP, causing failure. -# To resolve that issue the type field of the xSFP module is also fetched so that we can know exectly what type the -# module is. Currently only the following types are recognized as SFP/QSFP module. +# To resolve that issue the type field of the xSFP module is also fetched so that we can know exectly what type the +# module is. Currently only the following types are recognized as SFP/QSFP module. # Meanwhile, if the a module's identifier value can't be recognized, it will be parsed according to the SKU dictionary. # This is because in the future it's possible that some new identifier value which is not regonized but backward compatible # with the current format and by doing so it can be parsed as much as possible. @@ -155,8 +220,11 @@ '0d', # QSFP+ or later '11' # QSFP28 or later ] +QSFP_DD_TYPE_CODE_LIST = [ + '18' # QSFP-DD Double Density 8X Pluggable Transceiver +] -qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', +qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', 'Length OM2(m)', 'Length OM1(m)', 'Length Cable Assembly(m)') @@ -164,7 +232,7 @@ 'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)', 'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)') -sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode', +sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode', 'ESCONComplianceCodes', 'SONETComplianceCodes', 'EthernetComplianceCodes','FibreChannelLinkLength', 'FibreChannelTechnology', 'SFP+CableTechnology', @@ -179,6 +247,7 @@ SFP_TYPE = "SFP" QSFP_TYPE = "QSFP" OSFP_TYPE = "OSFP" +QSFP_DD_TYPE = "QSFP_DD" #variables for sdk REGISTER_NUM = 1 @@ -212,65 +281,69 @@ MCIA_ADDR_TX_DISABLE_BIT = 6 PORT_TYPE_NVE = 8 +PORT_TYPE_CPU = 4 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) + +# parameters for SFP presence +SFP_STATUS_INSERTED = '1' # Global logger class instance logger = Logger() + +# SDK initializing stuff, called from chassis +def initialize_sdk_handle(): + rc, sdk_handle = sx_api_open(None) + if (rc != SX_STATUS_SUCCESS): + logger.log_warning("Failed to open api handle, please check whether SDK is running.") + sdk_handle = None + + return sdk_handle + +def deinitialize_sdk_handle(sdk_handle): + if sdk_handle is not None: + rc = sx_api_close(sdk_handle) + if (rc != SX_STATUS_SUCCESS): + logger.log_warning("Failed to close api handle.") + + return rc == SXD_STATUS_SUCCESS + else: + logger.log_warning("Sdk handle is none") + return False + class SFP(SfpBase): """Platform-specific SFP class""" - def __init__(self, sfp_index, sfp_type): + def __init__(self, sfp_index, sfp_type, sdk_handle_getter, platform): + SfpBase.__init__(self) self.index = sfp_index + 1 self.sfp_eeprom_path = "qsfp{}".format(self.index) self.sfp_status_path = "qsfp{}_status".format(self.index) self._detect_sfp_type(sfp_type) self.dom_tx_disable_supported = False self._dom_capability_detect() - self.sdk_handle = None + self.sdk_handle_getter = sdk_handle_getter self.sdk_index = sfp_index + # initialize SFP thermal list + from .thermal import initialize_sfp_thermals + initialize_sfp_thermals(platform, self._thermal_list, self.index) - #SDK initializing stuff - def _initialize_sdk_handle(self): - """ - reference: device\mellanox\\pulgins\sfpreset.py - """ - rc, self.sdk_handle = sx_api_open(None) - if (rc != SX_STATUS_SUCCESS): - logger.log_warning("Failed to open api handle, please check whether SDK is running.") - self.sdk_handle = None - - self.mypid = os.getpid() - - - def _open_sdk(self): - if self.sdk_handle is None: - self._initialize_sdk_handle() + @property + def sdk_handle(self): + return self.sdk_handle_getter() - rc = sxd_access_reg_init(self.mypid, None, 0) - if rc != 0: - logger.log_warning("Failed to initializing register access, please check that SDK is running.") - return False - - return True - - - def _close_sdk(self): - rc = sxd_access_reg_deinit() - if rc != 0: - logger.log_warning("Failed to deinitializing register access.") - #no further actions here - - - def _init_sx_meta_data(self): - meta = sxd_reg_meta_t() - meta.dev_id = DEVICE_ID - meta.swid = SWITCH_ID - return meta + def reinit(self): + """ + Re-initialize this SFP object when a new SFP inserted + :return: + """ + self._detect_sfp_type(self.sfp_type) + self._dom_capability_detect() def get_presence(self): """ @@ -282,14 +355,18 @@ def get_presence(self): presence = False ethtool_cmd = "ethtool -m sfp{} hex on offset 0 length 1 2>/dev/null".format(self.index) try: - proc = subprocess.Popen(ethtool_cmd, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT) + proc = subprocess.Popen(ethtool_cmd, + stdout=subprocess.PIPE, + shell=True, + stderr=subprocess.STDOUT, + universal_newlines=True) stdout = proc.communicate()[0] proc.wait() result = stdout.rstrip('\n') if result != '': presence = True - except OSError, e: + except OSError as e: raise OSError("Cannot detect sfp") return presence @@ -300,7 +377,9 @@ def _read_eeprom_specific_bytes(self, offset, num_bytes): eeprom_raw = [] ethtool_cmd = "ethtool -m sfp{} hex on offset {} length {}".format(self.index, offset, num_bytes) try: - output = subprocess.check_output(ethtool_cmd, shell=True) + output = subprocess.check_output(ethtool_cmd, + shell=True, + universal_newlines=True) output_lines = output.splitlines() first_line_raw = output_lines[0] if "Offset" in first_line_raw: @@ -321,6 +400,8 @@ def _detect_sfp_type(self, sfp_type): self.sfp_type = SFP_TYPE elif eeprom_raw[0] in QSFP_TYPE_CODE_LIST: self.sfp_type = QSFP_TYPE + elif eeprom_raw[0] in QSFP_DD_TYPE_CODE_LIST: + self.sfp_type = QSFP_DD_TYPE else: # we don't regonize this identifier value, treat the xSFP module as the default type self.sfp_type = sfp_type @@ -339,6 +420,7 @@ def _dom_capability_detect(self): self.dom_temp_supported = False self.dom_volt_supported = False self.dom_rx_power_supported = False + self.dom_tx_bias_power_supported = False self.dom_tx_power_supported = False self.calibration = 0 return @@ -358,7 +440,7 @@ def _dom_capability_detect(self): if qsfp_dom_capability_raw is not None: qsfp_version_compliance_raw = self._read_eeprom_specific_bytes(QSFP_VERSION_COMPLIANCE_OFFSET, QSFP_VERSION_COMPLIANCE_WIDTH) qsfp_version_compliance = int(qsfp_version_compliance_raw[0], 16) - dom_capability = sfpi_obj.parse_qsfp_dom_capability(qsfp_dom_capability_raw, 0) + dom_capability = sfpi_obj.parse_dom_capability(qsfp_dom_capability_raw, 0) if qsfp_version_compliance >= 0x08: self.dom_temp_supported = dom_capability['data']['Temp_support']['value'] == 'On' self.dom_volt_supported = dom_capability['data']['Voltage_support']['value'] == 'On' @@ -388,6 +470,45 @@ def _dom_capability_detect(self): self.dom_tx_power_supported = False self.calibration = 0 self.qsfp_page3_available = False + + elif self.sfp_type == QSFP_DD_TYPE: + sfpi_obj = qsfp_dd_InterfaceId() + if sfpi_obj is None: + self.dom_supported = False + + offset = 0 + # two types of QSFP-DD cable types supported: Copper and Optical. + qsfp_dom_capability_raw = self._read_eeprom_specific_bytes((offset + XCVR_DOM_CAPABILITY_OFFSET_QSFP_DD), XCVR_DOM_CAPABILITY_WIDTH_QSFP_DD) + if qsfp_dom_capability_raw is not None: + self.dom_temp_supported = True + self.dom_volt_supported = True + dom_capability = sfpi_obj.parse_dom_capability(qsfp_dom_capability_raw, 0) + if dom_capability['data']['Flat_MEM']['value'] == 'Off': + self.dom_supported = True + self.second_application_list = True + self.dom_rx_power_supported = True + self.dom_tx_power_supported = True + self.dom_tx_bias_power_supported = True + self.dom_thresholds_supported = True + self.dom_rx_tx_power_bias_supported = True + else: + self.dom_supported = False + self.second_application_list = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.dom_tx_bias_power_supported = False + self.dom_thresholds_supported = False + self.dom_rx_tx_power_bias_supported = False + else: + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.dom_tx_bias_power_supported = False + self.dom_thresholds_supported = False + self.dom_rx_tx_power_bias_supported = False + elif self.sfp_type == SFP_TYPE: sfpi_obj = sff8472InterfaceId() if sfpi_obj is None: @@ -449,15 +570,15 @@ def get_transceiver_info(self): Returns: A dict which contains following keys/values : - ======================================================================== - keys |Value Format |Information + ================================================================================ + keys |Value Format |Information ---------------------------|---------------|---------------------------- type |1*255VCHAR |type of SFP - hardwarerev |1*255VCHAR |hardware version of SFP - serialnum |1*255VCHAR |serial number of the SFP - manufacturename |1*255VCHAR |SFP vendor name - modelname |1*255VCHAR |SFP model name - Connector |1*255VCHAR |connector information + hardware_rev |1*255VCHAR |hardware version of SFP + serial |1*255VCHAR |serial number of the SFP + manufacturer |1*255VCHAR |SFP vendor name + model |1*255VCHAR |SFP model name + connector |1*255VCHAR |connector information encoding |1*255VCHAR |encoding information ext_identifier |1*255VCHAR |extend identifier ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance @@ -466,7 +587,8 @@ def get_transceiver_info(self): specification_compliance |1*255VCHAR |specification compliance vendor_date |1*255VCHAR |vendor date vendor_oui |1*255VCHAR |vendor OUI - ======================================================================== + application_advertisement |1*255VCHAR |supported applications advertisement + ================================================================================ """ transceiver_info_dict = {} compliance_code_dict = {} @@ -513,13 +635,13 @@ def get_transceiver_info(self): return None transceiver_info_dict['type'] = sfp_type_data['data']['type']['value'] - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] transceiver_info_dict['vendor_oui'] = 'N/A' transceiver_info_dict['vendor_date'] = 'N/A' - transceiver_info_dict['Connector'] = 'N/A' + transceiver_info_dict['connector'] = 'N/A' transceiver_info_dict['encoding'] = 'N/A' transceiver_info_dict['ext_identifier'] = 'N/A' transceiver_info_dict['ext_rateselect_compliance'] = 'N/A' @@ -527,32 +649,148 @@ def get_transceiver_info(self): transceiver_info_dict['cable_length'] = 'N/A' transceiver_info_dict['specification_compliance'] = 'N/A' transceiver_info_dict['nominal_bit_rate'] = 'N/A' + transceiver_info_dict['application_advertisement'] = 'N/A' - else: - if self.sfp_type == QSFP_TYPE: - offset = 128 - vendor_rev_width = XCVR_HW_REV_WIDTH_QSFP - cable_length_width = XCVR_CABLE_LENGTH_WIDTH_QSFP - interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_QSFP - sfp_type = 'QSFP' - - sfpi_obj = sff8436InterfaceId() - if sfpi_obj is None: - print("Error: sfp_object open failed") - return None + elif self.sfp_type == QSFP_TYPE: + offset = 128 + vendor_rev_width = XCVR_HW_REV_WIDTH_QSFP + cable_length_width = XCVR_CABLE_LENGTH_WIDTH_QSFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_QSFP + sfp_type = 'QSFP' + + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + elif self.sfp_type == QSFP_DD_TYPE: + offset = 128 + + sfpi_obj = qsfp_dd_InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + + sfp_type_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_TYPE_OFFSET), XCVR_TYPE_WIDTH) + if sfp_type_raw is not None: + sfp_type_data = sfpi_obj.parse_sfp_type(sfp_type_raw, 0) else: - offset = 0 - vendor_rev_width = XCVR_HW_REV_WIDTH_SFP - cable_length_width = XCVR_CABLE_LENGTH_WIDTH_SFP - interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_SFP - sfp_type = 'SFP' - - sfpi_obj = sff8472InterfaceId() - if sfpi_obj is None: - print("Error: sfp_object open failed") + return None + + sfp_vendor_name_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) + if sfp_vendor_name_raw is not None: + sfp_vendor_name_data = sfpi_obj.parse_vendor_name(sfp_vendor_name_raw, 0) + else: + return None + + sfp_vendor_pn_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + if sfp_vendor_pn_raw is not None: + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0) + else: + return None + + sfp_vendor_rev_raw = self._read_eeprom_specific_bytes((offset + XCVR_HW_REV_OFFSET_QSFP_DD), XCVR_HW_REV_WIDTH_QSFP_DD) + if sfp_vendor_rev_raw is not None: + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_vendor_rev_raw, 0) + else: + return None + + sfp_vendor_sn_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + if sfp_vendor_sn_raw is not None: + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_vendor_sn_raw, 0) + else: + return None + + sfp_vendor_oui_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH) + if sfp_vendor_oui_raw is not None: + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(sfp_vendor_oui_raw, 0) + else: + return None + + sfp_vendor_date_raw = self._read_eeprom_specific_bytes((offset + XCVR_VENDOR_DATE_OFFSET_QSFP_DD), XCVR_VENDOR_DATE_WIDTH_QSFP_DD) + if sfp_vendor_date_raw is not None: + sfp_vendor_date_data = sfpi_obj.parse_vendor_date(sfp_vendor_date_raw, 0) + else: + return None + + sfp_connector_raw = self._read_eeprom_specific_bytes((offset + XCVR_CONNECTOR_OFFSET_QSFP_DD), XCVR_CONNECTOR_WIDTH_QSFP_DD) + if sfp_connector_raw is not None: + sfp_connector_data = sfpi_obj.parse_connector(sfp_connector_raw, 0) + else: + return None + + sfp_ext_identifier_raw = self._read_eeprom_specific_bytes((offset + XCVR_EXT_TYPE_OFFSET_QSFP_DD), XCVR_EXT_TYPE_WIDTH_QSFP_DD) + if sfp_ext_identifier_raw is not None: + sfp_ext_identifier_data = sfpi_obj.parse_ext_iden(sfp_ext_identifier_raw, 0) + else: + return None + + sfp_cable_len_raw = self._read_eeprom_specific_bytes((offset + XCVR_CABLE_LENGTH_OFFSET_QSFP_DD), XCVR_CABLE_LENGTH_WIDTH_QSFP_DD) + if sfp_cable_len_raw is not None: + sfp_cable_len_data = sfpi_obj.parse_cable_len(sfp_cable_len_raw, 0) + else: + return None + + sfp_media_type_raw = self._read_eeprom_specific_bytes(XCVR_MEDIA_TYPE_OFFSET_QSFP_DD, XCVR_MEDIA_TYPE_WIDTH_QSFP_DD) + if sfp_media_type_raw is not None: + sfp_media_type_dict = sfpi_obj.parse_media_type(sfp_media_type_raw, 0) + if sfp_media_type_dict is None: return None + host_media_list = "" + sfp_application_type_first_list = self._read_eeprom_specific_bytes((XCVR_FIRST_APPLICATION_LIST_OFFSET_QSFP_DD), XCVR_FIRST_APPLICATION_LIST_WIDTH_QSFP_DD) + if self.second_application_list: + possible_application_count = 15 + sfp_application_type_second_list = self._read_eeprom_specific_bytes((XCVR_SECOND_APPLICATION_LIST_OFFSET_QSFP_DD), XCVR_SECOND_APPLICATION_LIST_WIDTH_QSFP_DD) + if sfp_application_type_first_list is not None and sfp_application_type_second_list is not None: + sfp_application_type_list = sfp_application_type_first_list + sfp_application_type_second_list + else: + return None + else: + possible_application_count = 8 + if sfp_application_type_first_list is not None: + sfp_application_type_list = sfp_application_type_first_list + else: + return None + + for i in range(0, possible_application_count): + if sfp_application_type_list[i * 4] == 'ff': + break + host_electrical, media_interface = sfpi_obj.parse_application(sfp_media_type_dict, sfp_application_type_list[i * 4], sfp_application_type_list[i * 4 + 1]) + host_media_list = host_media_list + host_electrical + ' - ' + media_interface + '\n\t\t\t\t ' + else: + return None + + transceiver_info_dict['type'] = str(sfp_type_data['data']['type']['value']) + transceiver_info_dict['manufacturer'] = str(sfp_vendor_name_data['data']['Vendor Name']['value']) + transceiver_info_dict['model'] = str(sfp_vendor_pn_data['data']['Vendor PN']['value']) + transceiver_info_dict['hardware_rev'] = str(sfp_vendor_rev_data['data']['Vendor Rev']['value']) + transceiver_info_dict['serial'] = str(sfp_vendor_sn_data['data']['Vendor SN']['value']) + transceiver_info_dict['vendor_oui'] = str(sfp_vendor_oui_data['data']['Vendor OUI']['value']) + transceiver_info_dict['vendor_date'] = str(sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value']) + transceiver_info_dict['connector'] = str(sfp_connector_data['data']['Connector']['value']) + transceiver_info_dict['encoding'] = "Not supported for CMIS cables" + transceiver_info_dict['ext_identifier'] = str(sfp_ext_identifier_data['data']['Extended Identifier']['value']) + transceiver_info_dict['ext_rateselect_compliance'] = "Not supported for CMIS cables" + transceiver_info_dict['specification_compliance'] = "Not supported for CMIS cables" + transceiver_info_dict['cable_type'] = "Length Cable Assembly(m)" + transceiver_info_dict['cable_length'] = str(sfp_cable_len_data['data']['Length Cable Assembly(m)']['value']) + transceiver_info_dict['nominal_bit_rate'] = "Not supported for CMIS cables" + transceiver_info_dict['application_advertisement'] = host_media_list + + else: + offset = 0 + vendor_rev_width = XCVR_HW_REV_WIDTH_SFP + cable_length_width = XCVR_CABLE_LENGTH_WIDTH_SFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_SFP + sfp_type = 'SFP' + + sfpi_obj = sff8472InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + + if self.sfp_type != QSFP_DD_TYPE: sfp_interface_bulk_raw = self._read_eeprom_specific_bytes(offset + XCVR_INTERFACE_DATA_START, XCVR_INTERFACE_DATA_SIZE) if sfp_interface_bulk_raw is None: return None @@ -586,16 +824,17 @@ def get_transceiver_info(self): sfp_vendor_date_data = sfpi_obj.parse_vendor_date(sfp_interface_bulk_raw[start : end], 0) transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] - transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] - transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] - transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] - transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] transceiver_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] - transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] + transceiver_info_dict['application_advertisement'] = 'N/A' if self.sfp_type == QSFP_TYPE: for key in qsfp_cable_length_tup: @@ -606,8 +845,13 @@ def get_transceiver_info(self): for key in qsfp_compliance_code_tup: if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + sfp_ext_specification_compliance_raw = self._read_eeprom_specific_bytes(offset + XCVR_EXT_SPECIFICATION_COMPLIANCE_OFFSET, XCVR_EXT_SPECIFICATION_COMPLIANCE_WIDTH) + if sfp_ext_specification_compliance_raw is not None: + sfp_ext_specification_compliance_data = sfpi_obj.parse_ext_specification_compliance(sfp_ext_specification_compliance_raw[0 : 1], 0) + if sfp_ext_specification_compliance_data['data']['Extended Specification compliance']['value'] != "Unspecified": + compliance_code_dict['Extended Specification compliance'] = sfp_ext_specification_compliance_data['data']['Extended Specification compliance']['value'] transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) - + transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value']) else: for key in sfp_cable_length_tup: @@ -621,7 +865,7 @@ def get_transceiver_info(self): transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) - + return transceiver_info_dict @@ -632,7 +876,7 @@ def get_transceiver_bulk_status(self): Returns: A dict which contains following keys/values : ======================================================================== - keys |Value Format |Information + keys |Value Format |Information ---------------------------|---------------|---------------------------- RX LOS |BOOLEAN |RX lost-of-signal status, | |True if has RX los, False if not. @@ -659,10 +903,16 @@ def get_transceiver_bulk_status(self): dom_info_dict_keys = ['temperature', 'voltage', 'rx1power', 'rx2power', 'rx3power', 'rx4power', + 'rx5power', 'rx6power', + 'rx7power', 'rx8power', 'tx1bias', 'tx2bias', 'tx3bias', 'tx4bias', + 'tx5bias', 'tx6bias', + 'tx7bias', 'tx8bias', 'tx1power', 'tx2power', - 'tx3power', 'tx4power' + 'tx3power', 'tx4power', + 'tx5power', 'tx6power', + 'tx7power', 'tx8power' ] transceiver_dom_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') @@ -719,6 +969,73 @@ def get_transceiver_bulk_status(self): transceiver_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value'] transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] + elif self.sfp_type == QSFP_DD_TYPE: + + offset = 0 + sfpd_obj = qsfp_dd_Dom() + if sfpd_obj is None: + return transceiver_dom_info_dict + + dom_data_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_DOM_BULK_DATA_START), QSFP_DD_DOM_BULK_DATA_SIZE) + if dom_data_raw is None: + return transceiver_dom_info_dict + + if self.dom_temp_supported: + start = QSFP_DD_TEMPE_OFFSET - QSFP_DD_DOM_BULK_DATA_START + end = start + QSFP_DD_TEMPE_WIDTH + dom_temperature_data = sfpd_obj.parse_temperature(dom_data_raw[start : end], 0) + temp = self._convert_string_to_num(dom_temperature_data['data']['Temperature']['value']) + if temp is not None: + transceiver_dom_info_dict['temperature'] = temp + + if self.dom_volt_supported: + start = QSFP_DD_VOLT_OFFSET - QSFP_DD_DOM_BULK_DATA_START + end = start + QSFP_DD_VOLT_WIDTH + dom_voltage_data = sfpd_obj.parse_voltage(dom_data_raw[start : end], 0) + volt = self._convert_string_to_num(dom_voltage_data['data']['Vcc']['value']) + if volt is not None: + transceiver_dom_info_dict['voltage'] = volt + + if self.dom_rx_tx_power_bias_supported: + # page 11h + offset = 512 + dom_data_raw = self._read_eeprom_specific_bytes(offset + QSFP_DD_CHANNL_MON_OFFSET, QSFP_DD_CHANNL_MON_WIDTH) + if dom_data_raw is None: + return transceiver_dom_info_dict + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_data_raw, 0) + + if self.dom_tx_power_supported: + transceiver_dom_info_dict['tx1power'] = str(self._convert_string_to_num(dom_channel_monitor_data['data']['TX1Power']['value'])) + transceiver_dom_info_dict['tx2power'] = str(self._convert_string_to_num(dom_channel_monitor_data['data']['TX2Power']['value'])) + transceiver_dom_info_dict['tx3power'] = str(self._convert_string_to_num(dom_channel_monitor_data['data']['TX3Power']['value'])) + transceiver_dom_info_dict['tx4power'] = str(self._convert_string_to_num(dom_channel_monitor_data['data']['TX4Power']['value'])) + transceiver_dom_info_dict['tx5power'] = str(self._convert_string_to_num(dom_channel_monitor_data['data']['TX5Power']['value'])) + transceiver_dom_info_dict['tx6power'] = str(self._convert_string_to_num(dom_channel_monitor_data['data']['TX6Power']['value'])) + transceiver_dom_info_dict['tx7power'] = str(self._convert_string_to_num(dom_channel_monitor_data['data']['TX7Power']['value'])) + transceiver_dom_info_dict['tx8power'] = str(self._convert_string_to_num(dom_channel_monitor_data['data']['TX8Power']['value'])) + + if self.dom_rx_power_supported: + transceiver_dom_info_dict['rx1power'] = str(self._convert_string_to_num(dom_channel_monitor_data['data']['RX1Power']['value'])) + transceiver_dom_info_dict['rx2power'] = str(self._convert_string_to_num(dom_channel_monitor_data['data']['RX2Power']['value'])) + transceiver_dom_info_dict['rx3power'] = str(self._convert_string_to_num(dom_channel_monitor_data['data']['RX3Power']['value'])) + transceiver_dom_info_dict['rx4power'] = str(self._convert_string_to_num(dom_channel_monitor_data['data']['RX4Power']['value'])) + transceiver_dom_info_dict['rx5power'] = str(self._convert_string_to_num(dom_channel_monitor_data['data']['RX5Power']['value'])) + transceiver_dom_info_dict['rx6power'] = str(self._convert_string_to_num(dom_channel_monitor_data['data']['RX6Power']['value'])) + transceiver_dom_info_dict['rx7power'] = str(self._convert_string_to_num(dom_channel_monitor_data['data']['RX7Power']['value'])) + transceiver_dom_info_dict['rx8power'] = str(self._convert_string_to_num(dom_channel_monitor_data['data']['RX8Power']['value'])) + + if self.dom_tx_bias_power_supported: + transceiver_dom_info_dict['tx1bias'] = str(dom_channel_monitor_data['data']['TX1Bias']['value']) + transceiver_dom_info_dict['tx2bias'] = str(dom_channel_monitor_data['data']['TX2Bias']['value']) + transceiver_dom_info_dict['tx3bias'] = str(dom_channel_monitor_data['data']['TX3Bias']['value']) + transceiver_dom_info_dict['tx4bias'] = str(dom_channel_monitor_data['data']['TX4Bias']['value']) + transceiver_dom_info_dict['tx5bias'] = str(dom_channel_monitor_data['data']['TX5Bias']['value']) + transceiver_dom_info_dict['tx6bias'] = str(dom_channel_monitor_data['data']['TX6Bias']['value']) + transceiver_dom_info_dict['tx7bias'] = str(dom_channel_monitor_data['data']['TX7Bias']['value']) + transceiver_dom_info_dict['tx8bias'] = str(dom_channel_monitor_data['data']['TX8Bias']['value']) + + return transceiver_dom_info_dict + else: if not self.dom_supported: return transceiver_dom_info_dict @@ -846,6 +1163,47 @@ def get_transceiver_threshold_info(self): transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_channel_threshold_data['data']['TxPowerLowAlarm']['value'] transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_channel_threshold_data['data']['TxPowerLowWarning']['value'] + elif self.sfp_type == QSFP_DD_TYPE: + if not self.dom_supported: + return transceiver_dom_threshold_info_dict + + if not self.dom_thresholds_supported: + return transceiver_dom_threshold_info_dict + + sfpd_obj = qsfp_dd_Dom() + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + # page 02 + offset = 384 + dom_module_threshold_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_MODULE_THRESHOLD_OFFSET), QSFP_DD_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_data = sfpd_obj.parse_module_threshold_values(dom_module_threshold_raw, 0) + + # 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_module_threshold_data['data']['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RxPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['TxBiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['TxBiasLowWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TxPowerLowWarning']['value'] + else: offset = SFP_MODULE_ADDRA2_OFFSET @@ -896,12 +1254,12 @@ def get_reset_status(self): A Boolean, True if reset enabled, False if disabled for QSFP, originally I would like to make use of Initialization complete flag bit - which is at Page a0 offset 6 bit 0 to test whether reset is complete. + which is at Page a0 offset 6 bit 0 to test whether reset is complete. However as unit testing was carried out I find this approach may fail because: 1. we make use of ethtool to read data on I2C bus rather than to read directly 2. ethtool is unable to access I2C during QSFP module being reset In other words, whenever the flag is able to be retrived, the value is always be 1 - As a result, it doesn't make sense to retrieve that flag. Just treat successfully + As a result, it doesn't make sense to retrieve that flag. Just treat successfully retrieving data as "data ready". for SFP it seems that there is not flag indicating whether reset succeed. However, we can also do it in the way for QSFP. @@ -929,7 +1287,16 @@ def get_reset_status(self): return True else: return False + elif self.sfp_type == QSFP_DD_TYPE: + offset = 0 + sfpd_obj = qsfp_dd_Dom() + dom_channel_status_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_CHANNL_STATUS_OFFSET), QSFP_DD_CHANNL_STATUS_WIDTH) + if dom_channel_status_raw is None: + return False + + dom_channel_status_data = sfpd_obj.parse_dom_channel_status(dom_channel_status_raw, 0) + return dom_channel_status_data['data']['Status']['value'] == 'On' def get_rx_los(self): """ @@ -954,6 +1321,23 @@ def get_rx_los(self): rx_los_list.append(rx_los_data & 0x02 != 0) rx_los_list.append(rx_los_data & 0x04 != 0) rx_los_list.append(rx_los_data & 0x08 != 0) + + elif self.sfp_type == QSFP_DD_TYPE: + # page 11h + if self.dom_rx_tx_power_bias_supported: + offset = 512 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_CHANNL_RX_LOS_STATUS_OFFSET), QSFP_DD_CHANNL_RX_LOS_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 8) + rx_los_list.append(rx_los_data & 0x01 != 0) + rx_los_list.append(rx_los_data & 0x02 != 0) + rx_los_list.append(rx_los_data & 0x04 != 0) + rx_los_list.append(rx_los_data & 0x08 != 0) + rx_los_list.append(rx_los_data & 0x10 != 0) + rx_los_list.append(rx_los_data & 0x20 != 0) + rx_los_list.append(rx_los_data & 0x40 != 0) + rx_los_list.append(rx_los_data & 0x80 != 0) + else: offset = 256 dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) @@ -988,6 +1372,24 @@ def get_tx_fault(self): tx_fault_list.append(tx_fault_data & 0x02 != 0) tx_fault_list.append(tx_fault_data & 0x04 != 0) tx_fault_list.append(tx_fault_data & 0x08 != 0) + + elif self.sfp_type == QSFP_DD_TYPE: + return None + # page 11h + if self.dom_rx_tx_power_bias_supported: + offset = 512 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_CHANNL_TX_FAULT_STATUS_OFFSET), QSFP_DD_CHANNL_TX_FAULT_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 8) + tx_fault_list.append(tx_fault_data & 0x01 != 0) + tx_fault_list.append(tx_fault_data & 0x02 != 0) + tx_fault_list.append(tx_fault_data & 0x04 != 0) + tx_fault_list.append(tx_fault_data & 0x08 != 0) + tx_fault_list.append(tx_fault_data & 0x10 != 0) + tx_fault_list.append(tx_fault_data & 0x20 != 0) + tx_fault_list.append(tx_fault_data & 0x40 != 0) + tx_fault_list.append(tx_fault_data & 0x80 != 0) + else: offset = 256 dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) @@ -1025,6 +1427,22 @@ def get_tx_disable(self): tx_disable_list.append(tx_disable_data & 0x02 != 0) tx_disable_list.append(tx_disable_data & 0x04 != 0) tx_disable_list.append(tx_disable_data & 0x08 != 0) + + elif self.sfp_type == QSFP_DD_TYPE: + if self.dom_rx_tx_power_bias_supported: + offset = 128 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_CHANNL_DISABLE_STATUS_OFFSET), QSFP_DD_CHANNL_DISABLE_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_disable_data = int(dom_channel_monitor_raw[0], 16) + tx_disable_list.append(tx_disable_data & 0x01 != 0) + tx_disable_list.append(tx_disable_data & 0x02 != 0) + tx_disable_list.append(tx_disable_data & 0x04 != 0) + tx_disable_list.append(tx_disable_data & 0x08 != 0) + tx_disable_list.append(tx_disable_data & 0x10 != 0) + tx_disable_list.append(tx_disable_data & 0x20 != 0) + tx_disable_list.append(tx_disable_data & 0x40 != 0) + tx_disable_list.append(tx_disable_data & 0x80 != 0) + else: offset = 256 dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) @@ -1043,7 +1461,7 @@ def get_tx_disable_channel(self): Returns: A hex of 4 bits (bit 0 to bit 3 as channel 0 to channel 3) to represent TX channels which have been disabled in this SFP. - As an example, a returned value of 0x5 indicates that channel 0 + As an example, a returned value of 0x5 indicates that channel 0 and channel 2 have been disabled. """ tx_disable_list = self.get_tx_disable() @@ -1056,6 +1474,21 @@ def get_tx_disable_channel(self): return tx_disabled + def mgmt_phy_mod_pwr_attr_get(self, power_attr_type): + sx_mgmt_phy_mod_pwr_attr_p = new_sx_mgmt_phy_mod_pwr_attr_t_p() + sx_mgmt_phy_mod_pwr_attr = sx_mgmt_phy_mod_pwr_attr_t() + sx_mgmt_phy_mod_pwr_attr.power_attr_type = power_attr_type + sx_mgmt_phy_mod_pwr_attr_t_p_assign(sx_mgmt_phy_mod_pwr_attr_p, sx_mgmt_phy_mod_pwr_attr) + try: + rc = sx_mgmt_phy_mod_pwr_attr_get(self.sdk_handle, self.sdk_index, sx_mgmt_phy_mod_pwr_attr_p) + assert SX_STATUS_SUCCESS == rc, "sx_mgmt_phy_mod_pwr_attr_get failed" + sx_mgmt_phy_mod_pwr_attr = sx_mgmt_phy_mod_pwr_attr_t_p_value(sx_mgmt_phy_mod_pwr_attr_p) + pwr_mode_attr = sx_mgmt_phy_mod_pwr_attr.pwr_mode_attr + return pwr_mode_attr.admin_pwr_mode_e, pwr_mode_attr.oper_pwr_mode_e + finally: + delete_sx_mgmt_phy_mod_pwr_attr_t_p(sx_mgmt_phy_mod_pwr_attr_p) + + def get_lpmode(self): """ Retrieves the lpmode (low power mode) status of this SFP @@ -1063,28 +1496,9 @@ def get_lpmode(self): Returns: A Boolean, True if lpmode is enabled, False if disabled """ - if self.sfp_type == QSFP_TYPE: - if self._open_sdk(): - # Get MCION - mcion = ku_mcion_reg() - mcion.module = self.sdk_index - meta = self._init_sx_meta_data() - meta.access_cmd = SXD_ACCESS_CMD_GET - - rc = sxd_access_reg_mcion(mcion, meta, REGISTER_NUM, None, None) - self._close_sdk() - - if rc != SXD_STATUS_SUCCESS: - logger.log_warning("sxd_access_reg_mcion getting failed, rc = %d" % rc) - return None + admin_pwr_mode, oper_pwr_mode = self.mgmt_phy_mod_pwr_attr_get(SX_MGMT_PHY_MOD_PWR_ATTR_PWR_MODE_E) - # Get low power mode status - lpm_mask = 1 << 8 - lpm_status = (lpm_mask & mcion.module_status_bits) != 0 - - return lpm_status - else: - return NotImplementedError + return oper_pwr_mode == SX_MGMT_PHY_MOD_PWR_MODE_LOW_E def get_power_override(self): @@ -1135,6 +1549,22 @@ def get_temperature(self): return None else: return None + + elif self.sfp_type == QSFP_DD_TYPE: + offset = 0 + + sfpd_obj = qsfp_dd_Dom() + if sfpd_obj is None: + return None + + if self.dom_temp_supported: + dom_temperature_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_TEMPE_OFFSET), QSFP_DD_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + temp = self._convert_string_to_num(dom_temperature_data['data']['Temperature']['value']) + return temp + return None + else: offset = 256 sfpd_obj = sff8472Dom() @@ -1163,7 +1593,7 @@ def get_voltage(self): if self.sfp_type == QSFP_TYPE: offset = 0 offset_xcvr = 128 - + sfpd_obj = sff8436Dom() if sfpd_obj is None: return None @@ -1177,6 +1607,22 @@ def get_voltage(self): else: return None return None + + if self.sfp_type == QSFP_DD_TYPE: + offset = 128 + + sfpd_obj = qsfp_dd_Dom() + if sfpd_obj is None: + return None + + if self.dom_volt_supported: + dom_voltage_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_VOLT_OFFSET), QSFP_DD_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + voltage = self._convert_string_to_num(dom_voltage_data['data']['Vcc']['value']) + return voltage + return None + else: offset = 256 @@ -1208,7 +1654,7 @@ def get_tx_bias(self): if self.sfp_type == QSFP_TYPE: offset = 0 offset_xcvr = 128 - + sfpd_obj = sff8436Dom() if sfpd_obj is None: return None @@ -1220,6 +1666,28 @@ def get_tx_bias(self): tx_bias_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX2Bias']['value'])) tx_bias_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX3Bias']['value'])) tx_bias_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX4Bias']['value'])) + + elif self.sfp_type == QSFP_DD_TYPE: + # page 11h + if self.dom_rx_tx_power_bias_supported: + offset = 512 + sfpd_obj = qsfp_dd_Dom() + if sfpd_obj is None: + return None + + if dom_tx_bias_power_supported: + dom_tx_bias_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_TX_BIAS_OFFSET), QSFP_DD_TX_BIAS_WIDTH) + if dom_tx_bias_raw is not None: + dom_tx_bias_data = sfpd_obj.parse_dom_tx_bias(dom_tx_bias_raw, 0) + tx_bias_list.append(self._convert_string_to_num(dom_tx_bias_data['data']['TX1Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num(dom_tx_bias_data['data']['TX2Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num(dom_tx_bias_data['data']['TX3Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num(dom_tx_bias_data['data']['TX4Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num(dom_tx_bias_data['data']['TX5Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num(dom_tx_bias_data['data']['TX6Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num(dom_tx_bias_data['data']['TX7Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num(dom_tx_bias_data['data']['TX8Bias']['value'])) + else: offset = 256 @@ -1258,7 +1726,7 @@ def get_rx_power(self): elif self.sfp_type == QSFP_TYPE: offset = 0 offset_xcvr = 128 - + sfpd_obj = sff8436Dom() if sfpd_obj is None: return None @@ -1275,6 +1743,28 @@ def get_rx_power(self): return None else: return None + + elif self.sfp_type == QSFP_DD_TYPE: + # page 11 + if self.dom_rx_tx_power_bias_supported: + offset = 512 + sfpd_obj = qsfp_dd_Dom() + if sfpd_obj is None: + return None + + if self.dom_rx_power_supported: + dom_rx_power_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_RX_POWER_OFFSET), QSFP_DD_RX_POWER_WIDTH) + if dom_rx_power_raw is not None: + dom_rx_power_data = sfpd_obj.parse_dom_rx_power(dom_rx_power_raw, 0) + rx_power_list.append(self._convert_string_to_num(dom_rx_power_data['data']['RX1Power']['value'])) + rx_power_list.append(self._convert_string_to_num(dom_rx_power_data['data']['RX2Power']['value'])) + rx_power_list.append(self._convert_string_to_num(dom_rx_power_data['data']['RX3Power']['value'])) + rx_power_list.append(self._convert_string_to_num(dom_rx_power_data['data']['RX4Power']['value'])) + rx_power_list.append(self._convert_string_to_num(dom_rx_power_data['data']['RX5Power']['value'])) + rx_power_list.append(self._convert_string_to_num(dom_rx_power_data['data']['RX6Power']['value'])) + rx_power_list.append(self._convert_string_to_num(dom_rx_power_data['data']['RX7Power']['value'])) + rx_power_list.append(self._convert_string_to_num(dom_rx_power_data['data']['RX8Power']['value'])) + else: offset = 256 @@ -1330,6 +1820,29 @@ def get_tx_power(self): return None else: return None + + elif self.sfp_type == QSFP_DD_TYPE: + return None + # page 11 + if self.dom_rx_tx_power_bias_supported: + offset = 512 + sfpd_obj = qsfp_dd_Dom() + if sfpd_obj is None: + return None + + if self.dom_tx_power_supported: + dom_tx_power_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_TX_POWER_OFFSET), QSFP_DD_TX_POWER_WIDTH) + if dom_tx_power_raw is not None: + dom_tx_power_data = sfpd_obj.parse_dom_tx_power(dom_tx_power_raw, 0) + tx_power_list.append(self._convert_string_to_num(dom_tx_power_data['data']['TX1Power']['value'])) + tx_power_list.append(self._convert_string_to_num(dom_tx_power_data['data']['TX2Power']['value'])) + tx_power_list.append(self._convert_string_to_num(dom_tx_power_data['data']['TX3Power']['value'])) + tx_power_list.append(self._convert_string_to_num(dom_tx_power_data['data']['TX4Power']['value'])) + tx_power_list.append(self._convert_string_to_num(dom_tx_power_data['data']['TX5Power']['value'])) + tx_power_list.append(self._convert_string_to_num(dom_tx_power_data['data']['TX6Power']['value'])) + tx_power_list.append(self._convert_string_to_num(dom_tx_power_data['data']['TX7Power']['value'])) + tx_power_list.append(self._convert_string_to_num(dom_tx_power_data['data']['TX8Power']['value'])) + else: offset = 256 sfpd_obj = sff8472Dom() @@ -1359,66 +1872,11 @@ def reset(self): refer plugins/sfpreset.py """ - handle = self._open_sdk() - if handle is None: - return False - - # Get PMAOS - pmaos = ku_pmaos_reg() - pmaos.module = self.sdk_index - meta = self._init_sx_meta_data() - meta.access_cmd = SXD_ACCESS_CMD_GET - - rc = sxd_access_reg_pmaos(pmaos, meta, REGISTER_NUM, None, None) - if rc != SXD_STATUS_SUCCESS: - logger.log_warning("sxd_access_reg_pmaos getting failed, rc = %d" % rc) - self._close_sdk() - return None - - # Reset SFP - pmaos.rst = 1 - meta.access_cmd = SXD_ACCESS_CMD_SET - rc = sxd_access_reg_pmaos(pmaos, meta, REGISTER_NUM, None, None) - if rc != SXD_STATUS_SUCCESS: - logger.log_warning("sxd_access_reg_pmaos setting failed, rc = %d" % rc) - - self._close_sdk() - return rc == SXD_STATUS_SUCCESS - + rc = sx_mgmt_phy_mod_reset(self.sdk_handle, self.sdk_index) + if rc != SX_STATUS_SUCCESS: + logger.log_warning("sx_mgmt_phy_mod_reset failed, rc = %d" % rc) - def _write_i2c_via_mcia(self, page, i2caddr, address, data, mask): - handle = self._open_sdk() - if handle is None: - return False - - mcia = ku_mcia_reg() - - meta = self._init_sx_meta_data() - meta.access_cmd = SXD_ACCESS_CMD_GET - - mcia.module = self.sdk_index - mcia.page_number = page - mcia.i2c_device_address = i2caddr - mcia.device_address = address - mcia.size = 1 - rc = sxd_access_reg_mcia(mcia, meta, REGISTER_NUM, None, None) - if rc != SXD_STATUS_SUCCESS: - logger.log_warning("sxd_access_reg_mcia getting failed, rc = %d" % rc) - self._close_sdk() - return False - - original_data = (mcia.dword_0 >> 24) & 0x000000FF - updated_data = original_data & (~mask) - updated_data |= (data & mask) - - mcia.dword_0 = (updated_data << 24) & 0xFF000000 - meta.access_cmd = SXD_ACCESS_CMD_SET - rc = sxd_access_reg_mcia(mcia, meta, REGISTER_NUM, None, None) - if rc != SXD_STATUS_SUCCESS: - logger.log_warning("sxd_access_reg_mcia setting failed, rc = %d" % rc) - - self._close_sdk() - return rc == SXD_STATUS_SUCCESS + return rc == SX_STATUS_SUCCESS def tx_disable(self, tx_disable): @@ -1435,34 +1893,7 @@ def tx_disable(self, tx_disable): for SFP, make use of bit 6 of byte at (offset 110, a2h (i2c addr 0x51)) to disable/enable tx for QSFP, set all channels to disable/enable tx """ - if self.sfp_type == SFP_TYPE: - if self.dom_tx_disable_supported: - handle = self._open_sdk() - if handle is None: - return False - - tx_disable_mask = 1 << MCIA_ADDR_TX_DISABLE_BIT - if tx_disable: - tx_disable_bit = tx_disable_mask - else: - tx_disable_bit = 0 - - return self._write_i2c_via_mcia(2, 0x51, MCIA_ADDR_TX_DISABLE, tx_disable_bit, tx_disable_mask) - else: - return False - elif self.sfp_type == QSFP_TYPE: - if self.dom_tx_disable_supported: - channel_mask = 0x0f - if tx_disable: - disable_flag = channel_mask - else: - disable_flag = 0 - - return self._write_i2c_via_mcia(0, 0x50, MCIA_ADDR_TX_CHANNEL_DISABLE, disable_flag, channel_mask) - else: - return False - else: - return NotImplementedError + return NotImplementedError def tx_disable_channel(self, channel, disable): @@ -1480,25 +1911,17 @@ def tx_disable_channel(self, channel, disable): QSFP: page a0, address 86, lower 4 bits """ - if self.sfp_type == QSFP_TYPE: - if self.dom_tx_disable_supported: - channel_mask = 1 << channel - if disable: - disable_flag = channel_mask - else: - disable_flag = 0 - - return self._write_i2c_via_mcia(0, 0x50, MCIA_ADDR_TX_CHANNEL_DISABLE, disable_flag, channel_mask) - else: - return False - else: - return NotImplementedError + return NotImplementedError def is_nve(self, port): return (port & NVE_MASK) != 0 + def is_cpu(self, port): + return (port & CPU_MASK) != 0 + + def is_port_admin_status_up(self, log_port): oper_state_p = new_sx_port_oper_state_t_p() admin_state_p = new_sx_port_admin_state_t_p() @@ -1507,6 +1930,11 @@ def is_port_admin_status_up(self, log_port): assert rc == SXD_STATUS_SUCCESS, "sx_api_port_state_get failed, rc = %d" % rc admin_state = sx_port_admin_state_t_p_value(admin_state_p) + + delete_sx_port_oper_state_t_p(oper_state_p) + delete_sx_port_admin_state_t_p(admin_state_p) + delete_sx_port_module_state_t_p(module_state_p) + if admin_state == SX_PORT_ADMIN_STATUS_UP: return True else: @@ -1515,11 +1943,14 @@ def is_port_admin_status_up(self, log_port): def set_port_admin_status_by_log_port(self, log_port, admin_status): rc = sx_api_port_state_set(self.sdk_handle, log_port, admin_status) - assert rc == SX_STATUS_SUCCESS, "sx_api_port_state_set failed, rc = %d" % rc + if SX_STATUS_SUCCESS != rc: + logger.log_error("sx_api_port_state_set failed, rc = %d" % rc) + + return SX_STATUS_SUCCESS == rc - # Get all the ports related to the sfp, if port admin status is up, put it to list - def get_log_ports(self): + def get_logical_ports(self): + # Get all the ports related to the sfp, if port admin status is up, put it to list port_attributes_list = new_sx_port_attributes_t_arr(SX_PORT_ATTR_ARR_SIZE) port_cnt_p = new_uint32_t_p() uint32_t_p_assign(port_cnt_p, SX_PORT_ATTR_ARR_SIZE) @@ -1531,58 +1962,58 @@ def get_log_ports(self): log_port_list = [] for i in range(0, port_cnt): port_attributes = sx_port_attributes_t_arr_getitem(port_attributes_list, i) - if self.is_nve(int(port_attributes.log_port)) == False \ - and port_attributes.port_mapping.module_port == self.sdk_index \ - and self.is_port_admin_status_up(port_attributes.log_port): + if not self.is_nve(int(port_attributes.log_port)) \ + and not self.is_cpu(int(port_attributes.log_port)) \ + and port_attributes.port_mapping.module_port == self.sdk_index \ + and self.is_port_admin_status_up(port_attributes.log_port): log_port_list.append(port_attributes.log_port) + delete_sx_port_attributes_t_arr(port_attributes_list) + delete_uint32_t_p(port_cnt_p) return log_port_list - def _set_sfp_admin_status_raw(self, admin_status): - # Get PMAOS - pmaos = ku_pmaos_reg() - pmaos.module = self.sdk_index - meta = self._init_sx_meta_data() - meta.access_cmd = SXD_ACCESS_CMD_GET - rc = sxd_access_reg_pmaos(pmaos, meta, REGISTER_NUM, None, None) - assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmaos failed, rc = %d" % rc - - # Set admin status to PMAOS - pmaos.ase = PMAOS_ASE - pmaos.ee = PMAOS_EE - pmaos.e = PMAOS_E - pmaos.rst = PMAOS_RST - if admin_status == SX_PORT_ADMIN_STATUS_DOWN: - pmaos.admin_status = PMAOS_DISABLE - else: - pmaos.admin_status = PMAOS_ENABLE - - meta.access_cmd = SXD_ACCESS_CMD_SET - rc = sxd_access_reg_pmaos(pmaos, meta, REGISTER_NUM, None, None) - assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmaos failed, rc = %d" % rc - + def mgmt_phy_mod_pwr_attr_set(self, power_attr_type, admin_pwr_mode): + result = False + sx_mgmt_phy_mod_pwr_attr = sx_mgmt_phy_mod_pwr_attr_t() + sx_mgmt_phy_mod_pwr_mode_attr = sx_mgmt_phy_mod_pwr_mode_attr_t() + sx_mgmt_phy_mod_pwr_attr.power_attr_type = power_attr_type + sx_mgmt_phy_mod_pwr_mode_attr.admin_pwr_mode_e = admin_pwr_mode + sx_mgmt_phy_mod_pwr_attr.pwr_mode_attr = sx_mgmt_phy_mod_pwr_mode_attr + sx_mgmt_phy_mod_pwr_attr_p = new_sx_mgmt_phy_mod_pwr_attr_t_p() + sx_mgmt_phy_mod_pwr_attr_t_p_assign(sx_mgmt_phy_mod_pwr_attr_p, sx_mgmt_phy_mod_pwr_attr) + try: + rc = sx_mgmt_phy_mod_pwr_attr_set(self.sdk_handle, SX_ACCESS_CMD_SET, self.sdk_index, sx_mgmt_phy_mod_pwr_attr_p) + if SX_STATUS_SUCCESS != rc: + logger.log_error("sx_mgmt_phy_mod_pwr_attr_set failed, rc = %d" % rc) + result = False + else: + result = True + finally: + delete_sx_mgmt_phy_mod_pwr_attr_t_p(sx_mgmt_phy_mod_pwr_attr_p) - def _set_lpmode_raw(self, lpmode): - # Get PMMP - pmmp = ku_pmmp_reg() - pmmp.module = self.sdk_index - meta = self._init_sx_meta_data() - meta.access_cmd = SXD_ACCESS_CMD_GET - rc = sxd_access_reg_pmmp(pmmp, meta, REGISTER_NUM, None, None) - assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmmp failed, rc = %d" % rc + return result - # Set low power mode status - lpm_mask = 1 << PMMP_LPMODE_BIT - if lpmode: - pmmp.eeprom_override = pmmp.eeprom_override | lpm_mask - else: - pmmp.eeprom_override = pmmp.eeprom_override & (~lpm_mask) - meta.access_cmd = SXD_ACCESS_CMD_SET - rc = sxd_access_reg_pmmp(pmmp, meta, REGISTER_NUM, None, None) + def _set_lpmode_raw(self, ports, attr_type, power_mode): + result = False + # Check if the module already works in the same mode + admin_pwr_mode, oper_pwr_mode = self.mgmt_phy_mod_pwr_attr_get(attr_type) + if (power_mode == SX_MGMT_PHY_MOD_PWR_MODE_LOW_E and oper_pwr_mode == SX_MGMT_PHY_MOD_PWR_MODE_LOW_E) \ + or (power_mode == SX_MGMT_PHY_MOD_PWR_MODE_AUTO_E and admin_pwr_mode == SX_MGMT_PHY_MOD_PWR_MODE_AUTO_E): + return True + try: + # Bring the port down + for port in ports: + self.set_port_admin_status_by_log_port(port, SX_PORT_ADMIN_STATUS_DOWN) + # Set the desired power mode + result = self.mgmt_phy_mod_pwr_attr_set(attr_type, power_mode) + finally: + # Bring the port up + for port in ports: + self.set_port_admin_status_by_log_port(port, SX_PORT_ADMIN_STATUS_UP) - return rc + return result def set_lpmode(self, lpmode): @@ -1596,26 +2027,15 @@ def set_lpmode(self, lpmode): Returns: A boolean, True if lpmode is set successfully, False if not """ - handle = self._open_sdk() - if handle is None: - return False - try: - log_port_list = self.get_log_ports() - for log_port in log_port_list: - self.set_port_admin_status_by_log_port(log_port, SX_PORT_ADMIN_STATUS_DOWN) - self._set_sfp_admin_status_raw(SX_PORT_ADMIN_STATUS_DOWN) - - result = self._set_lpmode_raw(lpmode) - - self._set_sfp_admin_status_raw(SX_PORT_ADMIN_STATUS_UP) - for log_port in log_port_list: - self.set_port_admin_status_by_log_port(log_port, SX_PORT_ADMIN_STATUS_DOWN) - - return result == SXD_STATUS_SUCCESS - except: - logger.log_warning("set_lpmode failed due to some SDK failure") - self._close_sdk() - return False + log_port_list = self.get_logical_ports() + if lpmode: + self._set_lpmode_raw(log_port_list, SX_MGMT_PHY_MOD_PWR_ATTR_PWR_MODE_E, SX_MGMT_PHY_MOD_PWR_MODE_LOW_E) + logger.log_info("Enabled low power mode for module [%d]" % (self.sdk_index)) + else: + self._set_lpmode_raw(log_port_list, SX_MGMT_PHY_MOD_PWR_ATTR_PWR_MODE_E, SX_MGMT_PHY_MOD_PWR_MODE_AUTO_E) + logger.log_info( "Disabled low power mode for module [%d]" % (self.sdk_index)) + + return True def set_power_override(self, power_override, power_set): @@ -1623,7 +2043,7 @@ def set_power_override(self, power_override, power_set): Sets SFP power level using power_override and power_set Args: - power_override : + power_override : A Boolean, True to override set_lpmode and use power_set to control SFP power, False to disable SFP power control through power_override/power_set and use set_lpmode @@ -1637,15 +2057,12 @@ def set_power_override(self, power_override, power_set): A boolean, True if power-override and power_set are set successfully, False if not """ - if self.sfp_type == QSFP_TYPE: - power_override_bit = 0 - if power_override: - power_override_bit |= 1 << MCIA_ADDR_POWER_OVERRIDE_POR_BIT - power_set_bit = 0 - if power_set: - power_set_bit |= 1 << MCIA_ADDR_POWER_OVERRIDE_PS_BIT - power_override_mask = 1 << MCIA_ADDR_POWER_OVERRIDE_PS_BIT | 1 << MCIA_ADDR_POWER_OVERRIDE_POR_BIT - - return self._write_i2c_via_mcia(0, 0x50, MCIA_ADDR_POWER_OVERRIDE, power_set_bit|power_override_bit, power_override_mask) - else: - return NotImplementedError + return NotImplementedError + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True 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..ba3ab68a9576 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp_event.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp_event.py @@ -3,23 +3,77 @@ listen to the SDK for the SFP change event and return to chassis. ''' -from __future__ import print_function + import sys, errno import os import time import select from python_sdk_api.sx_api import * -from sonic_daemon_base.daemon_base import Logger - -SDK_SFP_STATE_IN = 0x1 +from sonic_py_common.logger import Logger + +# 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 + port_change[port+1] = 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 ''' @@ -216,6 +278,7 @@ def on_pmpe(self, fd_p): port_cnt_p = new_uint32_t_p() uint32_t_p_assign(port_cnt_p,64) label_port_list = [] + label_port = None module_state = 0 rc = sx_lib_host_ifc_recv(fd_p, pkt, pkt_size_p, recv_info_p) @@ -228,18 +291,30 @@ 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 - - for i in xrange(port_list_size): + 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 range(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) port_cnt = uint32_t_p_value(port_cnt_p) - for i in xrange(port_cnt): + for i in range(port_cnt): port_attributes = sx_port_attributes_t_arr_getitem(port_attributes_list,i) if port_attributes.log_port == logical_port: - lable_port = port_attributes.port_mapping.module_port + label_port = port_attributes.port_mapping.module_port break - label_port_list.append(lable_port) + + if label_port is not None: + label_port_list.append(label_port) delete_uint32_t_p(pkt_size_p) delete_uint8_t_arr(pkt) @@ -247,4 +322,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 diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py index 462267951130..c942b0d89d35 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py @@ -10,7 +10,7 @@ try: from sonic_platform_base.thermal_base import ThermalBase - from sonic_daemon_base.daemon_base import Logger + from sonic_py_common.logger import Logger from os import listdir from os.path import isfile, join import io @@ -42,6 +42,22 @@ HW_MGMT_THERMAL_ROOT = "/var/run/hw-management/thermal/" +THERMAL_ZONE_ASIC_PATH = "/var/run/hw-management/thermal/mlxsw/" +THERMAL_ZONE_MODULE_PATH = "/var/run/hw-management/thermal/mlxsw-module{}/" +THERMAL_ZONE_GEARBOX_PATH = "/var/run/hw-management/thermal/mlxsw-gearbox{}/" +THERMAL_ZONE_MODE = "thermal_zone_mode" +THERMAL_ZONE_POLICY = "thermal_zone_policy" +THERMAL_ZONE_TEMPERATURE = "thermal_zone_temp" +THERMAL_ZONE_NORMAL_TEMPERATURE = "temp_trip_norm" + +MODULE_TEMPERATURE_FAULT_PATH = "/var/run/hw-management/thermal/module{}_temp_fault" + +thermal_api_handler_asic = { + THERMAL_API_GET_TEMPERATURE: 'asic', + THERMAL_API_GET_HIGH_THRESHOLD: 'mlxsw/temp_trip_hot', + THERMAL_API_GET_HIGH_CRITICAL_THRESHOLD: 'mlxsw/temp_trip_crit' +} + thermal_api_handler_cpu_core = { THERMAL_API_GET_TEMPERATURE:"cpu_core{}", THERMAL_API_GET_HIGH_THRESHOLD:"cpu_core{}_max", @@ -64,17 +80,18 @@ } thermal_api_handler_gearbox = { THERMAL_API_GET_TEMPERATURE:"gearbox{}_temp_input", - THERMAL_API_GET_HIGH_THRESHOLD:None + THERMAL_API_GET_HIGH_THRESHOLD:"mlxsw-gearbox{}/temp_trip_hot", + THERMAL_API_GET_HIGH_CRITICAL_THRESHOLD:"mlxsw-gearbox{}/temp_trip_crit" } thermal_ambient_apis = { - THERMAL_DEV_ASIC_AMBIENT : "asic", + THERMAL_DEV_ASIC_AMBIENT : thermal_api_handler_asic, THERMAL_DEV_PORT_AMBIENT : "port_amb", THERMAL_DEV_FAN_AMBIENT : "fan_amb", THERMAL_DEV_COMEX_AMBIENT : "comex_amb", THERMAL_DEV_BOARD_AMBIENT : "board_amb" } thermal_ambient_name = { - THERMAL_DEV_ASIC_AMBIENT : "Ambient ASIC Temp", + THERMAL_DEV_ASIC_AMBIENT : 'ASIC', THERMAL_DEV_PORT_AMBIENT : "Ambient Port Side Temp", THERMAL_DEV_FAN_AMBIENT : "Ambient Fan Side Temp", THERMAL_DEV_COMEX_AMBIENT : "Ambient COMEX Temp", @@ -96,12 +113,10 @@ } thermal_device_categories_all = [ - THERMAL_DEV_CATEGORY_CPU_CORE, - THERMAL_DEV_CATEGORY_CPU_PACK, - THERMAL_DEV_CATEGORY_MODULE, - THERMAL_DEV_CATEGORY_PSU, THERMAL_DEV_CATEGORY_AMBIENT, - THERMAL_DEV_CATEGORY_GEARBOX + THERMAL_DEV_CATEGORY_CPU_PACK, + THERMAL_DEV_CATEGORY_CPU_CORE, + THERMAL_DEV_CATEGORY_GEARBOX, ] thermal_device_categories_singleton = [ @@ -113,7 +128,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} +platform_dict_thermal = {'x86_64-mlnx_msn2700-r0': 0, 'x86_64-mlnx_lssn2700-r0':0, 'x86_64-mlnx_msn2740-r0': 3, 'x86_64-mlnx_msn2100-r0': 1, 'x86_64-mlnx_msn2410-r0': 2, 'x86_64-mlnx_msn2010-r0': 4, 'x86_64-mlnx_msn3420-r0':9, 'x86_64-mlnx_msn3700-r0': 5, 'x86_64-mlnx_msn3700c-r0': 6, 'x86_64-mlnx_msn3800-r0': 7, 'x86_64-mlnx_msn4600c-r0':9, 'x86_64-mlnx_msn4700-r0': 8, 'x86_64-mlnx_msn4410-r0': 8} thermal_profile_list = [ # 2700 { @@ -238,19 +253,100 @@ ] ) }, + # 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 + ] + ) + }, + # 3420 + { + THERMAL_DEV_CATEGORY_CPU_CORE:(0, 2), + THERMAL_DEV_CATEGORY_MODULE:(1, 60), + 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 + ] + ) + }, + # 4600C + { + THERMAL_DEV_CATEGORY_CPU_CORE:(0, 4), + THERMAL_DEV_CATEGORY_MODULE:(1, 64), + 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 + ] + ) + }, + # 4410 + { + 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_psu_thermals(platform, thermal_list, psu_index, dependency): + tp_index = platform_dict_thermal[platform] + thermal_profile = thermal_profile_list[tp_index] + _, count = thermal_profile[THERMAL_DEV_CATEGORY_PSU] + if count == 0: + return + thermal = Thermal(THERMAL_DEV_CATEGORY_PSU, psu_index, True, 1, dependency) + thermal_list.append(thermal) + -def initialize_thermals(sku, thermal_list, psu_list): +def initialize_sfp_thermals(platform, thermal_list, sfp_index): + thermal = Thermal(THERMAL_DEV_CATEGORY_MODULE, sfp_index, True, 1) + thermal_list.append(thermal) + + +def initialize_chassis_thermals(platform, thermal_list): # create thermal objects for all categories of sensors - tp_index = hwsku_dict_thermal[sku] + tp_index = platform_dict_thermal[platform] thermal_profile = thermal_profile_list[tp_index] + Thermal.thermal_profile = thermal_profile + position = 1 for category in thermal_device_categories_all: if category == THERMAL_DEV_CATEGORY_AMBIENT: count, ambient_list = thermal_profile[category] for ambient in ambient_list: - thermal = Thermal(category, ambient, True) - thermal_list.append(thermal) + thermal = Thermal(category, ambient, True, position) + thermal_list.append(thermal), + position += 1 else: start, count = 0, 0 if category in thermal_profile: @@ -258,22 +354,22 @@ def initialize_thermals(sku, thermal_list, psu_list): if count == 0: continue if count == 1: - thermal = Thermal(category, 0, False) + thermal = Thermal(category, 0, False, position) thermal_list.append(thermal) + position += 1 else: - if category == THERMAL_DEV_CATEGORY_PSU: - for index in range(count): - thermal = Thermal(category, start + index, True, psu_list[index].get_powergood_status, "power off") - thermal_list.append(thermal) - else: - for index in range(count): - thermal = Thermal(category, start + index, True) - thermal_list.append(thermal) + for index in range(count): + thermal = Thermal(category, start + index, True, position) + thermal_list.append(thermal) + position += 1 class Thermal(ThermalBase): - def __init__(self, category, index, has_index, dependency = None, hint = None): + thermal_profile = None + thermal_algorithm_status = False + + def __init__(self, category, index, has_index, position, dependency = None): """ index should be a string for category ambient and int for other categories """ @@ -288,11 +384,11 @@ def __init__(self, category, index, has_index, dependency = None, hint = None): self.index = 0 self.category = category + self.position = position self.temperature = self._get_file_from_api(THERMAL_API_GET_TEMPERATURE) self.high_threshold = self._get_file_from_api(THERMAL_API_GET_HIGH_THRESHOLD) self.high_critical_threshold = self._get_file_from_api(THERMAL_API_GET_HIGH_CRITICAL_THRESHOLD) self.dependency = dependency - self.dependent_hint = hint def get_name(self): @@ -305,14 +401,15 @@ def get_name(self): return self.name - def _read_generic_file(self, filename, len): + @classmethod + def _read_generic_file(cls, filename, len): """ Read a generic file, returns the contents of the file """ result = None try: with open(filename, 'r') as fileobj: - result = fileobj.read() + result = fileobj.read().strip() except Exception as e: logger.log_info("Fail to read file {} due to {}".format(filename, repr(e))) return result @@ -320,8 +417,14 @@ def _read_generic_file(self, filename, len): def _get_file_from_api(self, api_name): if self.category == THERMAL_DEV_CATEGORY_AMBIENT: - if api_name == THERMAL_API_GET_TEMPERATURE: - filename = thermal_ambient_apis[self.index] + handler = thermal_ambient_apis[self.index] + if isinstance(handler, str): + if api_name == THERMAL_API_GET_TEMPERATURE: + filename = thermal_ambient_apis[self.index] + else: + return None + elif isinstance(handler, dict): + filename = handler[api_name] else: return None else: @@ -344,13 +447,11 @@ def get_temperature(self): A float number of current temperature in Celsius up to nearest thousandth of one degree Celsius, e.g. 30.125 """ - if self.dependency and not self.dependency(): - if self.dependent_hint: - hint = self.dependent_hint - else: - hint = "unknown reason" - logger.log_info("get_temperature for {} failed due to {}".format(self.name, hint)) - return None + if self.dependency: + status, hint = self.dependency() + if not status: + logger.log_debug("get_temperature for {} failed due to {}".format(self.name, hint)) + return None value_str = self._read_generic_file(self.temperature, 0) if value_str is None: return None @@ -370,6 +471,11 @@ def get_high_threshold(self): """ if self.high_threshold is None: return None + if self.dependency: + status, hint = self.dependency() + if not status: + logger.log_debug("get_high_threshold for {} failed due to {}".format(self.name, hint)) + return None value_str = self._read_generic_file(self.high_threshold, 0) if value_str is None: return None @@ -389,6 +495,11 @@ def get_high_critical_threshold(self): """ if self.high_critical_threshold is None: return None + if self.dependency: + status, hint = self.dependency() + if not status: + logger.log_debug("get_high_critical_threshold for {} failed due to {}".format(self.name, hint)) + return None value_str = self._read_generic_file(self.high_critical_threshold, 0) if value_str is None: return None @@ -396,3 +507,146 @@ def get_high_critical_threshold(self): if self.category == THERMAL_DEV_CATEGORY_MODULE and value_float == THERMAL_API_INVALID_HIGH_THRESHOLD: return None return value_float / 1000.0 + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device + Returns: + integer: The 1-based relative physical position in parent device + """ + return self.position + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return False + + @classmethod + def _write_generic_file(cls, filename, content): + """ + Generic functions to write content to a specified file path if + the content has changed. + """ + try: + with open(filename, 'w+') as file_obj: + origin_content = file_obj.read() + if origin_content != content: + file_obj.write(content) + except Exception as e: + logger.log_info("Fail to write file {} due to {}".format(filename, repr(e))) + + @classmethod + def set_thermal_algorithm_status(cls, status, force=True): + """ + Enable/disable kernel thermal algorithm. + When enable kernel thermal algorithm, kernel will adjust fan speed + according to thermal zones temperature. Please note that kernel will + only adjust fan speed when temperature across some "edge", e.g temperature + changes to exceed high threshold. + When disable kernel thermal algorithm, kernel no longer adjust fan speed. + We usually disable the algorithm when we want to set a fix speed. E.g, when + a fan unit is removed from system, we will set fan speed to 100% and disable + the algorithm to avoid it adjust the speed. + + Returns: + True if thermal algorithm status changed. + """ + if not cls.thermal_profile: + raise Exception("Fail to get thermal profile for this switch") + + if not force and cls.thermal_algorithm_status == status: + return False + + cls.thermal_algorithm_status = status + content = "enabled" if status else "disabled" + policy = "step_wise" if status else "user_space" + cls._write_generic_file(join(THERMAL_ZONE_ASIC_PATH, THERMAL_ZONE_MODE), content) + cls._write_generic_file(join(THERMAL_ZONE_ASIC_PATH, THERMAL_ZONE_POLICY), policy) + + if THERMAL_DEV_CATEGORY_MODULE in cls.thermal_profile: + start, count = cls.thermal_profile[THERMAL_DEV_CATEGORY_MODULE] + if count != 0: + for index in range(count): + cls._write_generic_file(join(THERMAL_ZONE_MODULE_PATH.format(start + index), THERMAL_ZONE_MODE), content) + cls._write_generic_file(join(THERMAL_ZONE_MODULE_PATH.format(start + index), THERMAL_ZONE_POLICY), policy) + + if THERMAL_DEV_CATEGORY_GEARBOX in cls.thermal_profile: + start, count = cls.thermal_profile[THERMAL_DEV_CATEGORY_GEARBOX] + if count != 0: + for index in range(count): + cls._write_generic_file(join(THERMAL_ZONE_GEARBOX_PATH.format(start + index), THERMAL_ZONE_MODE), content) + cls._write_generic_file(join(THERMAL_ZONE_GEARBOX_PATH.format(start + index), THERMAL_ZONE_POLICY), policy) + return True + + @classmethod + def check_thermal_zone_temperature(cls): + """ + Check thermal zone current temperature with normal temperature + + Returns: + True if all thermal zones current temperature less or equal than normal temperature + """ + if not cls.thermal_profile: + raise Exception("Fail to get thermal profile for this switch") + + if not cls._check_thermal_zone_temperature(THERMAL_ZONE_ASIC_PATH): + return False + + if THERMAL_DEV_CATEGORY_MODULE in cls.thermal_profile: + start, count = cls.thermal_profile[THERMAL_DEV_CATEGORY_MODULE] + if count != 0: + for index in range(count): + if not cls._check_thermal_zone_temperature(THERMAL_ZONE_MODULE_PATH.format(start + index)): + return False + + if THERMAL_DEV_CATEGORY_GEARBOX in cls.thermal_profile: + start, count = cls.thermal_profile[THERMAL_DEV_CATEGORY_GEARBOX] + if count != 0: + for index in range(count): + if not cls._check_thermal_zone_temperature(THERMAL_ZONE_GEARBOX_PATH.format(start + index)): + return False + + return True + + @classmethod + def _check_thermal_zone_temperature(cls, thermal_zone_path): + normal_temp_path = join(thermal_zone_path, THERMAL_ZONE_NORMAL_TEMPERATURE) + current_temp_path = join(thermal_zone_path, THERMAL_ZONE_TEMPERATURE) + normal = None + current = None + try: + with open(normal_temp_path, 'r') as file_obj: + normal = float(file_obj.read()) + + with open(current_temp_path, 'r') as file_obj: + current = float(file_obj.read()) + + return current <= normal + except Exception as e: + logger.log_info("Fail to check thermal zone temperature for file {} due to {}".format(thermal_zone_path, repr(e))) + + @classmethod + def check_module_temperature_trustable(cls): + if not cls.thermal_profile: + raise Exception("Fail to get thermal profile for this switch") + + start, count = cls.thermal_profile[THERMAL_DEV_CATEGORY_MODULE] + for index in range(count): + fault_file_path = MODULE_TEMPERATURE_FAULT_PATH.format(index + start) + fault = cls._read_generic_file(fault_file_path, 0) + if fault.strip() != '0': + return 'untrust' + return 'trust' + + @classmethod + def get_min_amb_temperature(cls): + fan_ambient_path = join(HW_MGMT_THERMAL_ROOT, THERMAL_DEV_FAN_AMBIENT) + port_ambient_path = join(HW_MGMT_THERMAL_ROOT, THERMAL_DEV_PORT_AMBIENT) + + # if there is any exception, let it raise + fan_ambient_temp = int(cls._read_generic_file(fan_ambient_path, 0)) + port_ambient_temp = int(cls._read_generic_file(port_ambient_path, 0)) + return fan_ambient_temp if fan_ambient_temp < port_ambient_temp else port_ambient_temp diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_actions.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_actions.py index 72729287d1c5..e7436bd0a5b7 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_actions.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_actions.py @@ -1,5 +1,6 @@ from sonic_platform_base.sonic_thermal_control.thermal_action_base import ThermalPolicyActionBase from sonic_platform_base.sonic_thermal_control.thermal_json_object import thermal_json_object +from .thermal import logger class SetFanSpeedAction(ThermalPolicyActionBase): @@ -52,7 +53,35 @@ def execute(self, thermal_info_dict): fan_info_obj = thermal_info_dict[FanInfo.INFO_NAME] for fan in fan_info_obj.get_presence_fans(): fan.set_speed(self.speed) + logger.log_info('Set all system FAN speed to {}'.format(self.speed)) + SetAllFanSpeedAction.set_psu_fan_speed(thermal_info_dict, self.speed) + + @classmethod + def set_psu_fan_speed(cls, thermal_info_dict, speed): + from .thermal_infos import ChassisInfo + if ChassisInfo.INFO_NAME in thermal_info_dict and isinstance(thermal_info_dict[ChassisInfo.INFO_NAME], ChassisInfo): + chassis = thermal_info_dict[ChassisInfo.INFO_NAME].get_chassis() + for psu in chassis.get_all_psus(): + for psu_fan in psu.get_all_fans(): + psu_fan.set_speed(speed) + + +@thermal_json_object('fan.all.check_and_set_speed') +class CheckAndSetAllFanSpeedAction(SetAllFanSpeedAction): + """ + Action to check thermal zone temperature and recover speed for all fans + """ + def execute(self, thermal_info_dict): + """ + Check thermal zone and set speed for all fans + :param thermal_info_dict: A dictionary stores all thermal information. + :return: + """ + from .thermal import Thermal + if Thermal.check_thermal_zone_temperature(): + SetAllFanSpeedAction.execute(self, thermal_info_dict) + @thermal_json_object('thermal_control.control') class ControlThermalAlgoAction(ThermalPolicyActionBase): @@ -95,14 +124,86 @@ def execute(self, thermal_info_dict): :param thermal_info_dict: A dictionary stores all thermal information. :return: """ - from .thermal_infos import ChassisInfo - if ChassisInfo.INFO_NAME in thermal_info_dict: - chassis_info_obj = thermal_info_dict[ChassisInfo.INFO_NAME] - chassis = chassis_info_obj.get_chassis() - thermal_manager = chassis.get_thermal_manager() + from .thermal_infos import FanInfo + from .thermal import Thermal + from .thermal_conditions import UpdateCoolingLevelToMinCondition + from .fan import Fan + status_changed = Thermal.set_thermal_algorithm_status(self.status, False) + + # Only update cooling level if thermal algorithm status changed + if status_changed: if self.status: - thermal_manager.start_thermal_control_algorithm() - else: - thermal_manager.stop_thermal_control_algorithm() + # Check thermal zone temperature, if all thermal zone temperature + # back to normal, set it to minimum allowed speed to + # save power + UpdateCoolingLevelToMinAction.update_cooling_level_to_minimum(thermal_info_dict) + + logger.log_info('Changed thermal algorithm status to {}'.format(self.status)) + + +@thermal_json_object('thermal.recover') +class ThermalRecoverAction(ThermalPolicyActionBase): + def execute(self, thermal_info_dict): + UpdateCoolingLevelToMinAction.update_cooling_level_to_minimum(thermal_info_dict) +class ChangeMinCoolingLevelAction(ThermalPolicyActionBase): + UNKNOWN_SKU_COOLING_LEVEL = 6 + def execute(self, thermal_info_dict): + from .device_data import DEVICE_DATA + from .fan import Fan + from .thermal_infos import ChassisInfo + from .thermal_conditions import MinCoolingLevelChangeCondition + from .thermal_conditions import UpdateCoolingLevelToMinCondition + + chassis = thermal_info_dict[ChassisInfo.INFO_NAME].get_chassis() + if chassis.platform_name not in DEVICE_DATA or 'thermal' not in DEVICE_DATA[chassis.platform_name] or 'minimum_table' not in DEVICE_DATA[chassis.platform_name]['thermal']: + Fan.min_cooling_level = ChangeMinCoolingLevelAction.UNKNOWN_SKU_COOLING_LEVEL + else: + trust_state = MinCoolingLevelChangeCondition.trust_state + temperature = MinCoolingLevelChangeCondition.temperature + minimum_table = DEVICE_DATA[chassis.platform_name]['thermal']['minimum_table']['unk_{}'.format(trust_state)] + + for key, cooling_level in minimum_table.items(): + temp_range = key.split(':') + temp_min = int(temp_range[0].strip()) + temp_max = int(temp_range[1].strip()) + if temp_min <= temperature <= temp_max: + Fan.min_cooling_level = cooling_level - 10 + break + + current_cooling_level = Fan.get_cooling_level() + if current_cooling_level < Fan.min_cooling_level: + Fan.set_cooling_level(Fan.min_cooling_level, Fan.min_cooling_level) + SetAllFanSpeedAction.set_psu_fan_speed(thermal_info_dict, Fan.min_cooling_level * 10) + else: + Fan.set_cooling_level(Fan.min_cooling_level, current_cooling_level) + UpdateCoolingLevelToMinAction.update_cooling_level_to_minimum(thermal_info_dict) + + +class UpdatePsuFanSpeedAction(ThermalPolicyActionBase): + def execute(self, thermal_info_dict): + from .thermal_conditions import CoolingLevelChangeCondition + SetAllFanSpeedAction.set_psu_fan_speed(thermal_info_dict, CoolingLevelChangeCondition.cooling_level * 10) + + +class UpdateCoolingLevelToMinAction(ThermalPolicyActionBase): + def execute(self, thermal_info_dict): + self.update_cooling_level_to_minimum(thermal_info_dict) + + @classmethod + def update_cooling_level_to_minimum(cls, thermal_info_dict): + from .fan import Fan + from .thermal import Thermal + from .thermal_conditions import UpdateCoolingLevelToMinCondition + from .thermal_infos import FanInfo + if Thermal.check_thermal_zone_temperature(): + fan_info_obj = thermal_info_dict[FanInfo.INFO_NAME] + speed = Fan.min_cooling_level * 10 + for fan in fan_info_obj.get_presence_fans(): + fan.set_speed(speed) + SetAllFanSpeedAction.set_psu_fan_speed(thermal_info_dict, speed) + UpdateCoolingLevelToMinCondition.enable = False + else: + UpdateCoolingLevelToMinCondition.enable = True + diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_conditions.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_conditions.py index 2df59acc9bf1..a682061d12a8 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_conditions.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_conditions.py @@ -32,6 +32,20 @@ def is_match(self, thermal_info_dict): return len(fan_info_obj.get_absence_fans()) == 0 if fan_info_obj else False +@thermal_json_object('fan.any.fault') +class AnyFanFaultCondition(FanCondition): + def is_match(self, thermal_info_dict): + fan_info_obj = self.get_fan_info(thermal_info_dict) + return len(fan_info_obj.get_fault_fans()) > 0 if fan_info_obj else False + + +@thermal_json_object('fan.all.good') +class AllFanGoodCondition(FanCondition): + def is_match(self, thermal_info_dict): + fan_info_obj = self.get_fan_info(thermal_info_dict) + return len(fan_info_obj.get_fault_fans()) == 0 if fan_info_obj else False + + class PsuCondition(ThermalPolicyConditionBase): def get_psu_info(self, thermal_info_dict): from .thermal_infos import PsuInfo @@ -61,3 +75,52 @@ def is_match(self, thermal_info_dict): psu_info_obj = self.get_psu_info(thermal_info_dict) return len(psu_info_obj.get_absence_psus()) == 0 if psu_info_obj else False + +class MinCoolingLevelChangeCondition(ThermalPolicyConditionBase): + trust_state = None + temperature = None + + def is_match(self, thermal_info_dict): + from .thermal import Thermal + + trust_state = Thermal.check_module_temperature_trustable() + temperature = Thermal.get_min_amb_temperature() + temperature = int(temperature / 1000) + + change_cooling_level = False + if trust_state != MinCoolingLevelChangeCondition.trust_state: + MinCoolingLevelChangeCondition.trust_state = trust_state + change_cooling_level = True + + if temperature != MinCoolingLevelChangeCondition.temperature: + MinCoolingLevelChangeCondition.temperature = temperature + change_cooling_level = True + + return change_cooling_level + + +class CoolingLevelChangeCondition(ThermalPolicyConditionBase): + cooling_level = None + + def is_match(self, thermal_info_dict): + from .fan import Fan + current_cooling_level = Fan.get_cooling_level() + if current_cooling_level != CoolingLevelChangeCondition.cooling_level: + CoolingLevelChangeCondition.cooling_level = current_cooling_level + return True + else: + return False + + +class UpdateCoolingLevelToMinCondition(ThermalPolicyConditionBase): + enable = False + def is_match(self, thermal_info_dict): + if not UpdateCoolingLevelToMinCondition.enable: + return False + + from .fan import Fan + current_cooling_level = Fan.get_cooling_level() + if current_cooling_level == Fan.min_cooling_level: + UpdateCoolingLevelToMinCondition.enable = False + return False + return True diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_infos.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_infos.py index 34d31e47d24c..e810a5646456 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_infos.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_infos.py @@ -14,6 +14,7 @@ class FanInfo(ThermalPolicyInfoBase): def __init__(self): self._absence_fans = set() self._presence_fans = set() + self._fault_fans = set() self._status_changed = False def collect(self, chassis): @@ -24,17 +25,27 @@ def collect(self, chassis): """ self._status_changed = False for fan in chassis.get_all_fans(): - if fan.get_presence() and fan not in self._presence_fans: + presence = fan.get_presence() + status = fan.get_status() + if presence and fan not in self._presence_fans: self._presence_fans.add(fan) self._status_changed = True if fan in self._absence_fans: self._absence_fans.remove(fan) - elif not fan.get_presence() and fan not in self._absence_fans: + elif not presence and fan not in self._absence_fans: self._absence_fans.add(fan) self._status_changed = True if fan in self._presence_fans: self._presence_fans.remove(fan) + if not status and fan not in self._fault_fans: + self._fault_fans.add(fan) + self._status_changed = True + elif status and fan in self._fault_fans: + self._fault_fans.remove(fan) + self._status_changed = True + + def get_absence_fans(self): """ Retrieves absence fans @@ -49,6 +60,13 @@ def get_presence_fans(self): """ return self._presence_fans + def get_fault_fans(self): + """ + Retrieves fault fans + :return: A set of fault fans + """ + return self._fault_fans + def is_status_changed(self): """ Retrieves if the status of fan information changed @@ -77,12 +95,12 @@ def collect(self, chassis): """ self._status_changed = False for psu in chassis.get_all_psus(): - if psu.get_presence() and psu not in self._presence_psus: + if psu.get_presence() and psu.get_powergood_status() and psu not in self._presence_psus: self._presence_psus.add(psu) self._status_changed = True if psu in self._absence_psus: self._absence_psus.remove(psu) - elif not psu.get_presence() and psu not in self._absence_psus: + elif (not psu.get_presence() or not psu.get_powergood_status()) and psu not in self._absence_psus: self._absence_psus.add(psu) self._status_changed = True if psu in self._presence_psus: diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_manager.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_manager.py index 133bb078ca20..914eec79816c 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_manager.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_manager.py @@ -1,12 +1,29 @@ import os from sonic_platform_base.sonic_thermal_control.thermal_manager_base import ThermalManagerBase +from sonic_platform_base.sonic_thermal_control.thermal_policy import ThermalPolicy from .thermal_actions import * from .thermal_conditions import * from .thermal_infos import * class ThermalManager(ThermalManagerBase): - THERMAL_ALGORITHM_CONTROL_PATH = '/var/run/hw-management/config/suspend' + @classmethod + def initialize(cls): + """ + Initialize thermal manager, including register thermal condition types and thermal action types + and any other vendor specific initialization. + :return: + """ + cls._add_private_thermal_policy() + + @classmethod + def deinitialize(cls): + """ + Destroy thermal manager, including any vendor specific cleanup. The default behavior of this function + is a no-op. + :return: + """ + cls.start_thermal_control_algorithm() @classmethod def start_thermal_control_algorithm(cls): @@ -16,7 +33,8 @@ def start_thermal_control_algorithm(cls): Returns: bool: True if set success, False if fail. """ - cls._control_thermal_control_algorithm(False) + from .thermal import Thermal + Thermal.set_thermal_algorithm_status(True) @classmethod def stop_thermal_control_algorithm(cls): @@ -26,25 +44,22 @@ def stop_thermal_control_algorithm(cls): Returns: bool: True if set success, False if fail. """ - cls._control_thermal_control_algorithm(True) + from .thermal import Thermal + Thermal.set_thermal_algorithm_status(False) @classmethod - def _control_thermal_control_algorithm(cls, suspend): - """ - Control thermal control algorithm - - Args: - suspend: Bool, indicate suspend the algorithm or not + def _add_private_thermal_policy(cls): + dynamic_min_speed_policy = ThermalPolicy() + dynamic_min_speed_policy.conditions[MinCoolingLevelChangeCondition] = MinCoolingLevelChangeCondition() + dynamic_min_speed_policy.actions[ChangeMinCoolingLevelAction] = ChangeMinCoolingLevelAction() + cls._policy_dict['DynamicMinCoolingLevelPolicy'] = dynamic_min_speed_policy - Returns: - bool: True if set success, False if fail. - """ - status = True - write_value = 1 if suspend else 0 - try: - with open(cls.THERMAL_ALGORITHM_CONTROL_PATH, 'w') as control_file: - control_file.write(str(write_value)) - except (ValueError, IOError): - status = False + update_psu_fan_speed_policy = ThermalPolicy() + update_psu_fan_speed_policy.conditions[CoolingLevelChangeCondition] = CoolingLevelChangeCondition() + update_psu_fan_speed_policy.actions[UpdatePsuFanSpeedAction] = UpdatePsuFanSpeedAction() + cls._policy_dict['UpdatePsuFanSpeedPolicy'] = update_psu_fan_speed_policy - return status + update_cooling_level_policy = ThermalPolicy() + update_cooling_level_policy.conditions[UpdateCoolingLevelToMinCondition] = UpdateCoolingLevelToMinCondition() + update_cooling_level_policy.actions[UpdateCoolingLevelToMinAction] = UpdateCoolingLevelToMinAction() + cls._policy_dict['UpdateCoolingLevelPolicy'] = update_cooling_level_policy diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/utils.py b/platform/mellanox/mlnx-platform-api/sonic_platform/utils.py new file mode 100644 index 000000000000..d5175acf8d0e --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/utils.py @@ -0,0 +1,57 @@ +def read_str_from_file(file_path, default='', raise_exception=False): + """ + Read string content from file + :param file_path: File path + :param default: Default return value if any exception occur + :param raise_exception: Raise exception to caller if True else just return default value + :return: String content of the file + """ + try: + with open(file_path, 'r') as f: + value = f.read().strip() + except (ValueError, IOError) as e: + if not raise_exception: + value = default + else: + raise e + + return value + + +def read_int_from_file(file_path, default=0, raise_exception=False): + """ + Read content from file and cast it to integer + :param file_path: File path + :param default: Default return value if any exception occur + :param raise_exception: Raise exception to caller if True else just return default value + :return: Integer value of the file content + """ + try: + with open(file_path, 'r') as f: + value = int(f.read().strip()) + except (ValueError, IOError) as e: + if not raise_exception: + value = default + else: + raise e + + return value + + +def write_file(file_path, content, raise_exception=False): + """ + Write the given value to a file + :param file_path: File path + :param content: Value to write to the file + :param raise_exception: Raise exception to caller if True + :return: True if write success else False + """ + try: + with open(file_path, 'w') as f: + f.write(str(content)) + except (ValueError, IOError) as e: + if not raise_exception: + return False + else: + raise e + return True diff --git a/platform/mellanox/mlnx-platform-api/tests/duplicate_action.json b/platform/mellanox/mlnx-platform-api/tests/duplicate_action.json new file mode 100644 index 000000000000..c19787aa26e0 --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/tests/duplicate_action.json @@ -0,0 +1,18 @@ +{ + "name": "any fan absence", + "conditions": [ + { + "type": "fan.any.absence" + } + ], + "actions": [ + { + "type": "fan.all.set_speed", + "speed": "100" + }, + { + "type": "fan.all.set_speed", + "speed": "100" + } + ] +} diff --git a/platform/mellanox/mlnx-platform-api/tests/duplicate_condition.json b/platform/mellanox/mlnx-platform-api/tests/duplicate_condition.json new file mode 100644 index 000000000000..c25d84762e2a --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/tests/duplicate_condition.json @@ -0,0 +1,17 @@ +{ + "name": "any fan absence", + "conditions": [ + { + "type": "fan.any.absence" + }, + { + "type": "fan.any.absence" + } + ], + "actions": [ + { + "type": "fan.all.set_speed", + "speed": "100" + } + ] +} diff --git a/platform/mellanox/mlnx-platform-api/tests/empty_action.json b/platform/mellanox/mlnx-platform-api/tests/empty_action.json new file mode 100644 index 000000000000..b1051b5a6f60 --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/tests/empty_action.json @@ -0,0 +1,10 @@ +{ + "name": "any fan absence", + "conditions": [ + { + "type": "fan.any.absence" + } + ], + "actions": [ + ] +} \ No newline at end of file diff --git a/platform/mellanox/mlnx-platform-api/tests/empty_condition.json b/platform/mellanox/mlnx-platform-api/tests/empty_condition.json new file mode 100644 index 000000000000..e7a588459246 --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/tests/empty_condition.json @@ -0,0 +1,11 @@ +{ + "name": "any fan absence", + "conditions": [ + ], + "actions": [ + { + "type": "fan.all.set_speed", + "speed": "100" + } + ] +} \ No newline at end of file diff --git a/platform/mellanox/mlnx-platform-api/tests/mock_platform.py b/platform/mellanox/mlnx-platform-api/tests/mock_platform.py index b8d070d44955..8edb9d4fb163 100644 --- a/platform/mellanox/mlnx-platform-api/tests/mock_platform.py +++ b/platform/mellanox/mlnx-platform-api/tests/mock_platform.py @@ -1,22 +1,40 @@ class MockFan: + speed = 60 def __init__(self): self.presence = True - self.speed = 60 + self.name = None + self.status = True def get_presence(self): return self.presence def set_speed(self, speed): - self.speed = speed + MockFan.speed = speed + + def get_status(self): + return self.status + + def get_target_speed(self): + return MockFan.speed + + def get_name(self): + return self.name class MockPsu: def __init__(self): self.presence = True + self.powergood = True def get_presence(self): return self.presence + def get_powergood_status(self): + return self.powergood + + def get_all_fans(self): + return [] + class MockChassis: def __init__(self): diff --git a/platform/mellanox/mlnx-platform-api/tests/policy_with_same_conditions.json b/platform/mellanox/mlnx-platform-api/tests/policy_with_same_conditions.json new file mode 100644 index 000000000000..ace291be1c55 --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/tests/policy_with_same_conditions.json @@ -0,0 +1,75 @@ +{ + "thermal_control_algorithm": { + "run_at_boot_up": "false", + "fan_speed_when_suspend": "60" + }, + "info_types": [ + { + "type": "fan_info" + }, + { + "type": "psu_info" + }, + { + "type": "chassis_info" + } + ], + "policies": [ + { + "name": "all fan and psu presence", + "conditions": [ + { + "type": "fan.all.presence" + }, + { + "type": "psu.all.presence" + } + ], + "actions": [ + { + "type": "thermal_control.control", + "status": "false" + }, + { + "type": "fan.all.set_speed", + "speed": "100" + } + ] + }, + { + "name": "any psu absence", + "conditions": [ + { + "type": "psu.any.absence" + } + ], + "actions": [ + { + "type": "thermal_control.control", + "status": "false" + }, + { + "type": "fan.all.set_speed", + "speed": "100" + } + ] + }, + { + "name": "all fan and psu presence 1", + "conditions": [ + { + "type": "fan.all.presence" + }, + { + "type": "psu.all.presence" + } + ], + "actions": [ + { + "type": "thermal_control.control", + "status": "true" + } + ] + } + ] +} \ No newline at end of file diff --git a/platform/mellanox/mlnx-platform-api/tests/test_fan_api.py b/platform/mellanox/mlnx-platform-api/tests/test_fan_api.py new file mode 100644 index 000000000000..bb9ee7e125a2 --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/tests/test_fan_api.py @@ -0,0 +1,57 @@ +import os +import sys +import pytest +from mock import MagicMock +from .mock_platform import MockFan + +test_path = os.path.dirname(os.path.abspath(__file__)) +modules_path = os.path.dirname(test_path) +sys.path.insert(0, modules_path) + +from sonic_platform.fan import Fan +from sonic_platform.led import FanLed +from sonic_platform.fan_drawer import RealDrawer +from sonic_platform.device_data import DEVICE_DATA + + +def test_get_absence_fan_direction(): + fan_drawer = RealDrawer(0, DEVICE_DATA['x86_64-mlnx_msn2700-r0']['fans']) + fan = Fan(0, fan_drawer, 1) + fan_drawer.get_presence = MagicMock(return_value=False) + + assert not fan.is_psu_fan + assert fan.get_direction() == Fan.FAN_DIRECTION_NOT_APPLICABLE + + +def test_fan_drawer_set_status_led(): + fan_drawer = RealDrawer(0, DEVICE_DATA['x86_64-mlnx_msn2700-r0']['fans']) + with pytest.raises(Exception): + fan_drawer.set_status_led(None, 'Invalid color') + + with pytest.raises(Exception): + fan_drawer.set_status_led(None, Fan.STATUS_LED_COLOR_RED) + + fan1 = Fan(0, fan_drawer, 1) + fan2 = Fan(1, fan_drawer, 2) + fan_list = fan_drawer.get_all_fans() + fan_list.append(fan1) + fan_list.append(fan2) + + FanLed.set_status = MagicMock() + + fan1.set_status_led(Fan.STATUS_LED_COLOR_RED) + fan_drawer.set_status_led(Fan.STATUS_LED_COLOR_RED) + FanLed.set_status.assert_called_with(Fan.STATUS_LED_COLOR_RED) + + fan2.set_status_led(Fan.STATUS_LED_COLOR_GREEN) + fan_drawer.set_status_led(Fan.STATUS_LED_COLOR_GREEN) + FanLed.set_status.assert_called_with(Fan.STATUS_LED_COLOR_RED) + + fan1.set_status_led(Fan.STATUS_LED_COLOR_GREEN) + fan_drawer.set_status_led(Fan.STATUS_LED_COLOR_GREEN) + FanLed.set_status.assert_called_with(Fan.STATUS_LED_COLOR_GREEN) + + fan1.set_status_led(Fan.STATUS_LED_COLOR_RED) + fan_drawer.set_status_led(Fan.STATUS_LED_COLOR_RED) + FanLed.set_status.assert_called_with(Fan.STATUS_LED_COLOR_RED) + diff --git a/platform/mellanox/mlnx-platform-api/tests/test_thermal_policy.py b/platform/mellanox/mlnx-platform-api/tests/test_thermal_policy.py index ba9e502d4f74..4d69a39c58a1 100644 --- a/platform/mellanox/mlnx-platform-api/tests/test_thermal_policy.py +++ b/platform/mellanox/mlnx-platform-api/tests/test_thermal_policy.py @@ -11,6 +11,11 @@ from sonic_platform.thermal_manager import ThermalManager from sonic_platform.thermal_infos import FanInfo, PsuInfo +from sonic_platform.fan import Fan +from sonic_platform.thermal import Thermal + +Thermal.check_thermal_zone_temperature = MagicMock() +Thermal.set_thermal_algorithm_status = MagicMock() @pytest.fixture(scope='session', autouse=True) @@ -27,6 +32,7 @@ def test_load_policy(thermal_manager): assert 'any fan absence' in thermal_manager._policy_dict assert 'any psu absence' in thermal_manager._policy_dict + assert 'any fan broken' in thermal_manager._policy_dict assert 'all fan and psu presence' in thermal_manager._policy_dict assert thermal_manager._fan_speed_when_suspend == 60 @@ -40,6 +46,7 @@ def test_fan_info(): fan_info.collect(chassis) assert len(fan_info.get_absence_fans()) == 1 assert len(fan_info.get_presence_fans()) == 0 + assert len(fan_info.get_fault_fans()) == 0 assert fan_info.is_status_changed() fan_list = chassis.get_all_fans() @@ -47,8 +54,15 @@ def test_fan_info(): fan_info.collect(chassis) assert len(fan_info.get_absence_fans()) == 0 assert len(fan_info.get_presence_fans()) == 1 + assert len(fan_info.get_fault_fans()) == 0 assert fan_info.is_status_changed() + fan_list[0].status = False + fan_info.collect(chassis) + assert len(fan_info.get_absence_fans()) == 0 + assert len(fan_info.get_presence_fans()) == 1 + assert len(fan_info.get_fault_fans()) == 1 + assert fan_info.is_status_changed() def test_psu_info(): chassis = MockChassis() @@ -66,40 +80,58 @@ def test_psu_info(): assert len(psu_info.get_presence_psus()) == 1 assert psu_info.is_status_changed() + psu_list[0].powergood = False + psu_info.collect(chassis) + assert len(psu_info.get_absence_psus()) == 1 + assert len(psu_info.get_presence_psus()) == 0 + assert psu_info.is_status_changed() + def test_fan_policy(thermal_manager): chassis = MockChassis() chassis.make_fan_absence() chassis.fan_list.append(MockFan()) - thermal_manager.start_thermal_control_algorithm = MagicMock() - thermal_manager.stop_thermal_control_algorithm = MagicMock() thermal_manager.run_policy(chassis) fan_list = chassis.get_all_fans() assert fan_list[1].speed == 100 - thermal_manager.stop_thermal_control_algorithm.assert_called_once() + Thermal.set_thermal_algorithm_status.assert_called_with(False, False) fan_list[0].presence = True + Thermal.check_thermal_zone_temperature = MagicMock(return_value=True) thermal_manager.run_policy(chassis) - thermal_manager.start_thermal_control_algorithm.assert_called_once() + Thermal.set_thermal_algorithm_status.assert_called_with(True, False) + assert Thermal.check_thermal_zone_temperature.call_count == 2 + assert fan_list[0].speed == 60 + assert fan_list[1].speed == 60 + + fan_list[0].status = False + thermal_manager.run_policy(chassis) + Thermal.set_thermal_algorithm_status.assert_called_with(False, False) + + fan_list[0].status = True + Thermal.check_thermal_zone_temperature = MagicMock(return_value=False) + thermal_manager.run_policy(chassis) + Thermal.set_thermal_algorithm_status.assert_called_with(True, False) + assert Thermal.check_thermal_zone_temperature.call_count == 2 + assert fan_list[0].speed == 100 + assert fan_list[1].speed == 100 def test_psu_policy(thermal_manager): chassis = MockChassis() chassis.make_psu_absence() chassis.fan_list.append(MockFan()) - thermal_manager.start_thermal_control_algorithm = MagicMock() - thermal_manager.stop_thermal_control_algorithm = MagicMock() thermal_manager.run_policy(chassis) fan_list = chassis.get_all_fans() assert fan_list[0].speed == 100 - thermal_manager.stop_thermal_control_algorithm.assert_called_once() + Thermal.set_thermal_algorithm_status.assert_called_with(False, False) psu_list = chassis.get_all_psus() psu_list[0].presence = True thermal_manager.run_policy(chassis) - thermal_manager.start_thermal_control_algorithm.assert_called_once() + Thermal.set_thermal_algorithm_status.assert_called_with(True, False) def test_any_fan_absence_condition(): @@ -153,6 +185,44 @@ def test_all_fan_presence_condition(): fan_info.collect(chassis) assert condition.is_match({'fan_info': fan_info}) +def test_any_fan_fault_condition(): + chassis = MockChassis() + fan = MockFan() + fan_list = chassis.get_all_fans() + fan_list.append(fan) + fault_fan = MockFan() + fault_fan.status = False + fan_list.append(fault_fan) + fan_info = FanInfo() + fan_info.collect(chassis) + + from sonic_platform.thermal_conditions import AnyFanFaultCondition + condition = AnyFanFaultCondition() + assert condition.is_match({'fan_info': fan_info}) + + fault_fan.status = True + fan_info.collect(chassis) + assert not condition.is_match({'fan_info': fan_info}) + +def test_all_fan_good_condition(): + chassis = MockChassis() + fan = MockFan() + fan_list = chassis.get_all_fans() + fan_list.append(fan) + fault_fan = MockFan() + fault_fan.status = False + fan_list.append(fault_fan) + fan_info = FanInfo() + fan_info.collect(chassis) + + from sonic_platform.thermal_conditions import AllFanGoodCondition + condition = AllFanGoodCondition() + assert not condition.is_match({'fan_info': fan_info}) + + fault_fan.status = True + fan_info.collect(chassis) + assert condition.is_match({'fan_info': fan_info}) + def test_any_psu_absence_condition(): chassis = MockChassis() @@ -269,4 +339,176 @@ def test_load_control_thermal_algo_action(): with pytest.raises(ValueError): action.load_from_json(json_obj) +def test_load_check_and_set_speed_action(): + from sonic_platform.thermal_actions import CheckAndSetAllFanSpeedAction + action = CheckAndSetAllFanSpeedAction() + json_str = '{\"speed\": \"40\"}' + json_obj = json.loads(json_str) + action.load_from_json(json_obj) + assert action.speed == 40 + + json_str = '{\"speed\": \"-1\"}' + json_obj = json.loads(json_str) + with pytest.raises(ValueError): + action.load_from_json(json_obj) + + json_str = '{\"speed\": \"101\"}' + json_obj = json.loads(json_str) + with pytest.raises(ValueError): + action.load_from_json(json_obj) + + json_str = '{\"invalid\": \"60\"}' + json_obj = json.loads(json_str) + with pytest.raises(ValueError): + action.load_from_json(json_obj) +def test_execute_check_and_set_fan_speed_action(): + chassis = MockChassis() + fan_list = chassis.get_all_fans() + fan_list.append(MockFan()) + fan_list.append(MockFan()) + fan_info = FanInfo() + fan_info.collect(chassis) + Thermal.check_thermal_zone_temperature = MagicMock(return_value=True) + + from sonic_platform.thermal_actions import CheckAndSetAllFanSpeedAction + action = CheckAndSetAllFanSpeedAction() + action.speed = 99 + action.execute({'fan_info': fan_info}) + assert fan_list[0].speed == 99 + assert fan_list[1].speed == 99 + + Thermal.check_thermal_zone_temperature = MagicMock(return_value=False) + fan_list[0].speed = 100 + fan_list[1].speed = 100 + action.speed = 60 + action.execute({'fan_info': fan_info}) + assert fan_list[0].speed == 100 + assert fan_list[1].speed == 100 + +def test_load_duplicate_condition(): + from sonic_platform_base.sonic_thermal_control.thermal_policy import ThermalPolicy + with open(os.path.join(test_path, 'duplicate_condition.json')) as f: + json_obj = json.load(f) + policy = ThermalPolicy() + with pytest.raises(Exception): + policy.load_from_json(json_obj) + +def test_load_duplicate_action(): + from sonic_platform_base.sonic_thermal_control.thermal_policy import ThermalPolicy + with open(os.path.join(test_path, 'duplicate_action.json')) as f: + json_obj = json.load(f) + policy = ThermalPolicy() + with pytest.raises(Exception): + policy.load_from_json(json_obj) + +def test_load_empty_condition(): + from sonic_platform_base.sonic_thermal_control.thermal_policy import ThermalPolicy + with open(os.path.join(test_path, 'empty_condition.json')) as f: + json_obj = json.load(f) + policy = ThermalPolicy() + with pytest.raises(Exception): + policy.load_from_json(json_obj) + +def test_load_empty_action(): + from sonic_platform_base.sonic_thermal_control.thermal_policy import ThermalPolicy + with open(os.path.join(test_path, 'empty_action.json')) as f: + json_obj = json.load(f) + policy = ThermalPolicy() + with pytest.raises(Exception): + policy.load_from_json(json_obj) + +def test_load_policy_with_same_conditions(): + from sonic_platform_base.sonic_thermal_control.thermal_manager_base import ThermalManagerBase + class MockThermalManager(ThermalManagerBase): + pass + + with pytest.raises(Exception): + MockThermalManager.load(os.path.join(test_path, 'policy_with_same_conditions.json')) + +def test_dynamic_minimum_table_data(): + from sonic_platform.device_data import DEVICE_DATA + for platform, platform_data in DEVICE_DATA.items(): + if 'thermal' in platform_data and 'minimum_table' in platform_data['thermal']: + minimum_table = platform_data['thermal']['minimum_table'] + check_minimum_table_data(platform, minimum_table) + +def check_minimum_table_data(platform, minimum_table): + valid_dir = ['p2c', 'c2p', 'unk'] + valid_trust_state = ['trust', 'untrust'] + + for category, data in minimum_table.items(): + key_data = category.split('_') + assert key_data[0] in valid_dir + assert key_data[1] in valid_trust_state + + data_list = [(value, key) for key, value in data.items()] + data_list.sort(key=lambda x : x[0]) + + previous_edge = None + previous_cooling_level = None + for item in data_list: + cooling_level = item[0] + range_str = item[1] + + ranges = range_str.split(':') + low = int(ranges[0]) + high = int(ranges[1]) + assert low < high + + if previous_edge is None: + assert low == -127 + else: + assert low - previous_edge == 1, '{}-{}-{} error, item={}'.format(platform, key_data[0], key_data[1], item) + previous_edge = high + + assert 10 <= cooling_level <= 20 + if previous_cooling_level is not None: + assert cooling_level > previous_cooling_level + previous_cooling_level = cooling_level + +def test_dynamic_minimum_policy(thermal_manager): + from sonic_platform.thermal_conditions import MinCoolingLevelChangeCondition + from sonic_platform.thermal_actions import ChangeMinCoolingLevelAction + from sonic_platform.thermal_infos import ChassisInfo + from sonic_platform.thermal import Thermal + from sonic_platform.fan import Fan + ThermalManager.initialize() + assert 'DynamicMinCoolingLevelPolicy' in thermal_manager._policy_dict + policy = thermal_manager._policy_dict['DynamicMinCoolingLevelPolicy'] + assert MinCoolingLevelChangeCondition in policy.conditions + assert ChangeMinCoolingLevelAction in policy.actions + + condition = policy.conditions[MinCoolingLevelChangeCondition] + action = policy.actions[ChangeMinCoolingLevelAction] + Thermal.check_module_temperature_trustable = MagicMock(return_value='trust') + Thermal.get_min_amb_temperature = MagicMock(return_value=35001) + assert condition.is_match(None) + assert MinCoolingLevelChangeCondition.trust_state == 'trust' + assert MinCoolingLevelChangeCondition.temperature == 35 + assert not condition.is_match(None) + + Thermal.check_module_temperature_trustable = MagicMock(return_value='untrust') + assert condition.is_match(None) + assert MinCoolingLevelChangeCondition.trust_state == 'untrust' + + Thermal.get_min_amb_temperature = MagicMock(return_value=25999) + assert condition.is_match(None) + assert MinCoolingLevelChangeCondition.temperature == 25 + + chassis = MockChassis() + chassis.platform_name = 'invalid' + info = ChassisInfo() + info._chassis = chassis + thermal_info_dict = {ChassisInfo.INFO_NAME: info} + Fan.get_cooling_level = MagicMock(return_value=5) + Fan.set_cooling_level = MagicMock() + action.execute(thermal_info_dict) + assert Fan.min_cooling_level == 6 + Fan.set_cooling_level.assert_called_with(6, 6) + Fan.set_cooling_level.call_count = 0 + + chassis.platform_name = 'x86_64-mlnx_msn2700-r0' + action.execute(thermal_info_dict) + assert Fan.min_cooling_level == 3 + Fan.set_cooling_level.assert_called_with(3, 5) diff --git a/platform/mellanox/mlnx-platform-api/tests/thermal_policy.json b/platform/mellanox/mlnx-platform-api/tests/thermal_policy.json index 5d31b2abd875..413211b21220 100644 --- a/platform/mellanox/mlnx-platform-api/tests/thermal_policy.json +++ b/platform/mellanox/mlnx-platform-api/tests/thermal_policy.json @@ -51,6 +51,24 @@ } ] }, + { + "name": "any fan broken", + "conditions": [ + { + "type": "fan.any.fault" + } + ], + "actions": [ + { + "type": "thermal_control.control", + "status": "false" + }, + { + "type": "fan.all.set_speed", + "speed": "100" + } + ] + }, { "name": "all fan and psu presence", "conditions": [ @@ -59,12 +77,19 @@ }, { "type": "psu.all.presence" + }, + { + "type": "fan.all.good" } ], "actions": [ { "type": "thermal_control.control", "status": "true" + }, + { + "type": "fan.all.check_and_set_speed", + "speed": "60" } ] } diff --git a/platform/mellanox/mlnx-sai.dep b/platform/mellanox/mlnx-sai.dep new file mode 100644 index 000000000000..2a3862caa8e8 --- /dev/null +++ b/platform/mellanox/mlnx-sai.dep @@ -0,0 +1,21 @@ +# DPKG FRK + +SPATH := $($(MLNX_SAI)_SRC_PATH) +SLINKS := $(shell find $(SPATH) -type l -exec echo {} \; | grep -Ev ' ') +SMDEP_PATHS := $(shell git submodule status --recursive -- $(SPATH) | awk '{print $$2}' | grep -Ev ' ') +SMDEP_FILES := $(foreach path,$(SMDEP_PATHS),$(filter-out $(SMDEP_PATHS),$(addprefix $(path)/,$(shell cd $(path) && git ls-files | grep -Ev ' ')))) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/mlnx-sai.mk $(PLATFORM_PATH)/mlnx-sai.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(filter-out $(SMDEP_PATHS),$(shell git ls-files -- $(SPATH) | grep -Ev ' ')) + +$(MLNX_SAI)_CACHE_MODE := GIT_CONTENT_SHA +$(MLNX_SAI)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(MLNX_SAI)_DEP_FILES := $(filter-out $(SLINKS),$(DEP_FILES)) +$(MLNX_SAI)_SMDEP_FILES := $(filter-out $(SLINKS),$(SMDEP_FILES)) +$(MLNX_SAI)_SMDEP_PATHS := $(SMDEP_PATHS) + +$(MLNX_SAI_DBGSYM)_CACHE_MODE := GIT_CONTENT_SHA +$(MLNX_SAI_DBGSYM)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(MLNX_SAI_DBGSYM)_DEP_FILES := $(filter-out $(SLINKS),$(DEP_FILES)) +$(MLNX_SAI_DBGSYM)_SMDEP_FILES := $(filter-out $(SLINKS),$(SMDEP_FILES)) +$(MLNX_SAI_DBGSYM)_SMDEP_PATHS := $(SMDEP_PATHS) diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk index 4f9e3b292465..7f16a72cc076 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.18.1.0 export MLNX_SAI_VERSION @@ -8,6 +8,7 @@ MLNX_SAI = mlnx-sai_1.mlnx.$(MLNX_SAI_VERSION)_amd64.deb $(MLNX_SAI)_SRC_PATH = $(PLATFORM_PATH)/mlnx-sai $(MLNX_SAI)_DEPENDS += $(MLNX_SDK_DEBS) $(MLNX_SAI)_RDEPENDS += $(MLNX_SDK_RDEBS) $(MLNX_SDK_DEBS) +$(eval $(call add_conflict_package,$(MLNX_SAI),$(LIBSAIVS_DEV))) MLNX_SAI_DBGSYM = mlnx-sai-dbgsym_1.mlnx.$(MLNX_SAI_VERSION)_amd64.deb $(eval $(call add_derived_package,$(MLNX_SAI),$(MLNX_SAI_DBGSYM))) SONIC_MAKE_DEBS += $(MLNX_SAI) diff --git a/platform/mellanox/mlnx-sai/Makefile b/platform/mellanox/mlnx-sai/Makefile index de6a7152d601..715f43ef0355 100644 --- a/platform/mellanox/mlnx-sai/Makefile +++ b/platform/mellanox/mlnx-sai/Makefile @@ -10,7 +10,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : pushd mlnx_sai chmod a+x autogen.sh - debuild -e 'make_extra_flags="DEFS=-DACS_OS"' -us -uc -d -b + debuild -e 'make_extra_flags="DEFS=-DACS_OS -DCONFIG_SYSLOG"' -us -uc -d -b popd mv $(DERIVED_TARGETS) $* $(DEST)/ diff --git a/platform/mellanox/mlnx-sai/SAI-Implementation b/platform/mellanox/mlnx-sai/SAI-Implementation index ef47a5592190..aa467f9462d0 160000 --- a/platform/mellanox/mlnx-sai/SAI-Implementation +++ b/platform/mellanox/mlnx-sai/SAI-Implementation @@ -1 +1 @@ -Subproject commit ef47a5592190c08d2f127d3fe8fa5a77ee4087ba +Subproject commit aa467f9462d063c79875b3a6ea699e9d0b1d8b57 diff --git a/platform/mellanox/mlnx-ssd-fw-update.dep b/platform/mellanox/mlnx-ssd-fw-update.dep new file mode 100644 index 000000000000..60e587a64f07 --- /dev/null +++ b/platform/mellanox/mlnx-ssd-fw-update.dep @@ -0,0 +1,10 @@ +# DPKG FRK + +DPATH := $($(MLNX_SSD_FW_UPDATE)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/mlnx-ssd-fw-update.mk $(PLATFORM_PATH)/mlnx-ssd-fw-update.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(addprefix $(DPATH),$(MLNX_SSD_FW_UPDATE)) + +$(MLNX_SSD_FW_UPDATE)_CACHE_MODE := GIT_CONTENT_SHA +$(MLNX_SSD_FW_UPDATE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(MLNX_SSD_FW_UPDATE)_DEP_FILES := $(DEP_FILES) diff --git a/platform/mellanox/mlnx-ssd-fw-update.mk b/platform/mellanox/mlnx-ssd-fw-update.mk new file mode 100644 index 000000000000..024710efbf9b --- /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_PATH)/ +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..4a2204adacf8 --- /dev/null +++ b/platform/mellanox/mlnx-ssd-fw-update.sh @@ -0,0 +1,729 @@ +#!/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.5" +#===== +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 + export LC_ALL= + export LANG="en_US.UTF-8" +} + +#==============================================================================# +#= 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 --ignore-time-conflict --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 [[ "yes" == "$power_policy" || $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 is not required, latest version based on given package is in use." + print_ssd_info "no" + fi + + echo -e "" + erase_extract_package "$extraction_path" + exit 0 +fi + +exit 0 diff --git a/platform/mellanox/one-image.dep b/platform/mellanox/one-image.dep new file mode 100644 index 000000000000..c29b43a7bba9 --- /dev/null +++ b/platform/mellanox/one-image.dep @@ -0,0 +1,3 @@ +# DPKG FRK + +$(SONIC_ONE_IMAGE)_CACHE_MODE := none 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 b/platform/mellanox/onie-fw-update deleted file mode 100755 index 314f4ed70268..000000000000 --- a/platform/mellanox/onie-fw-update +++ /dev/null @@ -1,120 +0,0 @@ -#!/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 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/peripheral_table.j2 b/platform/mellanox/peripheral_table.j2 new file mode 100644 index 000000000000..730fd681bc61 --- /dev/null +++ b/platform/mellanox/peripheral_table.j2 @@ -0,0 +1,17 @@ +{%- if DEVICE_METADATA is defined and DEVICE_METADATA['localhost']['platform'] is defined %} +{%- set platform = DEVICE_METADATA['localhost']['platform'] %} +{%- endif -%} + +{% set platform2gearbox = { + 'x86_64-mlnx_msn3800-r0':'MELLANOX-GEARBOX-3800' + } +%} +{% set gearbox_type = platform2gearbox[platform] %} +{% if gearbox_type == 'MELLANOX-GEARBOX-3800' %} +{ + "PERIPHERAL_TABLE:MELLANOX-GEARBOX-3800": { + "gearbox_delay": "400" + }, + "OP": "SET" +} +{% endif %} diff --git a/platform/mellanox/rules.dep b/platform/mellanox/rules.dep new file mode 100644 index 000000000000..409857592159 --- /dev/null +++ b/platform/mellanox/rules.dep @@ -0,0 +1,17 @@ +# DPKG FRK + +include $(PLATFORM_PATH)/sdk.dep +include $(PLATFORM_PATH)/fw.dep +include $(PLATFORM_PATH)/mft.dep +include $(PLATFORM_PATH)/mlnx-sai.dep +include $(PLATFORM_PATH)/hw-management.dep +include $(PLATFORM_PATH)/mlnx-platform-api.dep +include $(PLATFORM_PATH)/docker-syncd-mlnx.dep +include $(PLATFORM_PATH)/docker-syncd-mlnx-rpc.dep +include $(PLATFORM_PATH)/docker-saiserver-mlnx.dep +include $(PLATFORM_PATH)/one-image.dep +include $(PLATFORM_PATH)/libsaithrift-dev.dep +include $(PLATFORM_PATH)/mlnx-ffb.dep +include $(PLATFORM_PATH)/issu-version.dep +include $(PLATFORM_PATH)/mlnx-onie-fw-update.dep +include $(PLATFORM_PATH)/mlnx-ssd-fw-update.dep diff --git a/platform/mellanox/rules.mk b/platform/mellanox/rules.mk index efd0af2c8f4a..179e20f3fff5 100644 --- a/platform/mellanox/rules.mk +++ b/platform/mellanox/rules.mk @@ -9,18 +9,20 @@ include $(PLATFORM_PATH)/docker-syncd-mlnx-rpc.mk include $(PLATFORM_PATH)/docker-saiserver-mlnx.mk include $(PLATFORM_PATH)/one-image.mk 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) -# Inject mlnx sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(MLNX_SAI) +# Inject mlnx sai into syncd +$(SYNCD)_DEPENDS += $(MLNX_SAI) +$(SYNCD)_UNINSTALLS += $(MLNX_SAI) + ifeq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV) +$(SYNCD)_DEPENDS += $(LIBSAITHRIFT_DEV) endif # Runtime dependency on mlnx sai is set only for syncd @@ -29,5 +31,4 @@ $(SYNCD)_RDEPENDS += $(MLNX_SAI) # Inject mlnx sdk libs to platform monitor $(DOCKER_PLATFORM_MONITOR)_DEPENDS += $(APPLIBS) $(SX_COMPLIB) $(SXD_LIBS) $(SX_GEN_UTILS) $(PYTHON_SDK_API) $(APPLIBS_DEV) $(SX_COMPLIB_DEV) $(SXD_LIBS_DEV) $(SX_GEN_UTILS_DEV) -# Inject mlnx mlx libs to platform monitor -$(DOCKER_PLATFORM_MONITOR)_DEPENDS += $(MFT) +export SONIC_BUFFER_MODEL=dynamic diff --git a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers index 07425a0957d1..78d452b90836 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 78d452b90836005784cd6345bacf0a5df109f742 diff --git a/platform/mellanox/sdk.dep b/platform/mellanox/sdk.dep new file mode 100644 index 000000000000..bf3ecb95d8ae --- /dev/null +++ b/platform/mellanox/sdk.dep @@ -0,0 +1,229 @@ +# DPKG FRK + +# APPLIBS + +SPATH := $($(APPLIBS)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/sdk.mk $(PLATFORM_PATH)/sdk.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(SPATH)) + +$(APPLIBS)_CACHE_MODE := GIT_CONTENT_SHA +$(APPLIBS)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(APPLIBS)_DEP_FILES := $(DEP_FILES) + +$(APPLIBS_DEV)_CACHE_MODE := GIT_CONTENT_SHA +$(APPLIBS_DEV)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(APPLIBS_DEV)_DEP_FILES := $(DEP_FILES) + +ifeq ($(SDK_FROM_SRC),y) +$(APPLIBS_DBGSYM)_CACHE_MODE := GIT_CONTENT_SHA +$(APPLIBS_DBGSYM)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(APPLIBS_DBGSYM)_DEP_FILES := $(DEP_FILES) +endif + +# IPROUTE2_MLNX + +SPATH := $($(IPROUTE2_MLNX)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/sdk.mk $(PLATFORM_PATH)/sdk.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(SPATH)) + +$(IPROUTE2_MLNX)_CACHE_MODE := GIT_CONTENT_SHA +$(IPROUTE2_MLNX)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(IPROUTE2_MLNX)_DEP_FILES := $(DEP_FILES) + +$(IPROUTE2_MLNX_DEV)_CACHE_MODE := GIT_CONTENT_SHA +$(IPROUTE2_MLNX_DEV)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(IPROUTE2_MLNX_DEV)_DEP_FILES := $(DEP_FILES) + +ifeq ($(SDK_FROM_SRC),y) +$(IPROUTE2_MLNX_DBGSYM)_CACHE_MODE := GIT_CONTENT_SHA +$(IPROUTE2_MLNX_DBGSYM)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(IPROUTE2_MLNX_DBGSYM)_DEP_FILES := $(DEP_FILES) +endif + +# SX_COMPLIB + +SPATH := $($(SX_COMPLIB)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/sdk.mk $(PLATFORM_PATH)/sdk.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(SPATH)) + +$(SX_COMPLIB)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_COMPLIB)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_COMPLIB)_DEP_FILES := $(DEP_FILES) + +$(SX_COMPLIB_DEV)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_COMPLIB_DEV)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_COMPLIB_DEV)_DEP_FILES := $(DEP_FILES) + +ifeq ($(SDK_FROM_SRC),y) +$(SX_COMPLIB_DBGSYM)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_COMPLIB_DBGSYM)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_COMPLIB_DBGSYM)_DEP_FILES := $(DEP_FILES) +endif + +# SX_EXAMPLES + +SPATH := $($(SX_EXAMPLES)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/sdk.mk $(PLATFORM_PATH)/sdk.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(SPATH)) + +$(SX_EXAMPLES)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_EXAMPLES)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_EXAMPLES)_DEP_FILES := $(DEP_FILES) + +$(SX_EXAMPLES_DEV)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_EXAMPLES_DEV)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_EXAMPLES_DEV)_DEP_FILES := $(DEP_FILES) + +ifeq ($(SDK_FROM_SRC),y) +$(SX_EXAMPLES_DBGSYM)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_EXAMPLES_DBGSYM)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_EXAMPLES_DBGSYM)_DEP_FILES := $(DEP_FILES) +endif + +# SX_GEN_UTILS + +SPATH := $($(SX_GEN_UTILS)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/sdk.mk $(PLATFORM_PATH)/sdk.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(SPATH)) + +$(SX_GEN_UTILS)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_GEN_UTILS)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_GEN_UTILS)_DEP_FILES := $(DEP_FILES) + +$(SX_GEN_UTILS_DEV)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_GEN_UTILS_DEV)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_GEN_UTILS_DEV)_DEP_FILES := $(DEP_FILES) + +ifeq ($(SDK_FROM_SRC),y) +$(SX_GEN_UTILS_DBGSYM)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_GEN_UTILS_DBGSYM)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_GEN_UTILS_DBGSYM)_DEP_FILES := $(DEP_FILES) +endif + +# SX_SCEW + +SPATH := $($(SX_SCEW)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/sdk.mk $(PLATFORM_PATH)/sdk.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(SPATH)) + +$(SX_SCEW)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_SCEW)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_SCEW)_DEP_FILES := $(DEP_FILES) + +$(SX_SCEW_DEV)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_SCEW_DEV)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_SCEW_DEV)_DEP_FILES := $(DEP_FILES) + +ifeq ($(SDK_FROM_SRC),y) +$(SX_SCEW_DBGSYM)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_SCEW_DBGSYM)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_SCEW_DBGSYM)_DEP_FILES := $(DEP_FILES) +endif + +# SXD_LIBS + +SPATH := $($(SXD_LIBS)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/sdk.mk $(PLATFORM_PATH)/sdk.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(SPATH)) + +$(SXD_LIBS)_CACHE_MODE := GIT_CONTENT_SHA +$(SXD_LIBS)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SXD_LIBS)_DEP_FILES := $(DEP_FILES) + +$(SXD_LIBS_DEV)_CACHE_MODE := GIT_CONTENT_SHA +$(SXD_LIBS_DEV)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SXD_LIBS_DEV)_DEP_FILES := $(DEP_FILES) + +ifeq ($(SDK_FROM_SRC),y) +$(SXD_LIBS_DBGSYM)_CACHE_MODE := GIT_CONTENT_SHA +$(SXD_LIBS_DBGSYM)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SXD_LIBS_DBGSYM)_DEP_FILES := $(DEP_FILES) +endif + +# PYTHON_SDK_API + +SPATH := $($(PYTHON_SDK_API)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/sdk.mk $(PLATFORM_PATH)/sdk.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(SPATH)) + +$(PYTHON_SDK_API)_CACHE_MODE := GIT_CONTENT_SHA +$(PYTHON_SDK_API)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(PYTHON_SDK_API)_DEP_FILES := $(DEP_FILES) + +ifeq ($(SDK_FROM_SRC),y) +$(PYTHON_SDK_API_DBGSYM)_CACHE_MODE := GIT_CONTENT_SHA +$(PYTHON_SDK_API_DBGSYM)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(PYTHON_SDK_API_DBGSYM)_DEP_FILES := $(DEP_FILES) +endif + +# SX_ACL_HELPER + +SPATH := $($(SX_ACL_HELPER)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/sdk.mk $(PLATFORM_PATH)/sdk.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(SPATH)) + +$(SX_ACL_HELPER)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_ACL_HELPER)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_ACL_HELPER)_DEP_FILES := $(DEP_FILES) + +$(SX_ACL_HELPER_DEV)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_ACL_HELPER_DEV)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_ACL_HELPER_DEV)_DEP_FILES := $(DEP_FILES) + +ifeq ($(SDK_FROM_SRC),y) +$(SX_ACL_HELPER_DBGSYM)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_ACL_HELPER_DBGSYM)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_ACL_HELPER_DBGSYM)_DEP_FILES := $(DEP_FILES) +endif + +# WJH_LIBS + +SPATH := $($(WJH_LIBS)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/sdk.mk $(PLATFORM_PATH)/sdk.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(SPATH)) + +$(WJH_LIBS)_CACHE_MODE := GIT_CONTENT_SHA +$(WJH_LIBS)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(WJH_LIBS)_DEP_FILES := $(DEP_FILES) + +$(WJH_LIBS_DEV)_CACHE_MODE := GIT_CONTENT_SHA +$(WJH_LIBS_DEV)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(WJH_LIBS_DEV)_DEP_FILES := $(DEP_FILES) + +ifeq ($(SDK_FROM_SRC),y) +$(WJH_LIBS_DBGSYM)_CACHE_MODE := GIT_CONTENT_SHA +$(WJH_LIBS_DBGSYM)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(WJH_LIBS_DBGSYM)_DEP_FILES := $(DEP_FILES) +endif + +# SX_KERNEL + +SPATH := $($(SX_KERNEL)_SRC_PATH) +SLINKS := $(shell find $(SPATH) -type l -exec echo {} \; | grep -Ev ' ') +SMDEP_PATHS := $(shell git submodule status --recursive -- $(SPATH) | awk '{print $$2}' | grep -Ev ' ') +SMDEP_FILES := $(foreach path,$(SMDEP_PATHS),$(filter-out $(SMDEP_PATHS),$(addprefix $(path)/,$(shell cd $(path) && git ls-files | grep -Ev ' ')))) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/sdk.mk $(PLATFORM_PATH)/sdk.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(filter-out $(SMDEP_PATHS),$(shell git ls-files -- $(SPATH) | grep -Ev ' ')) + +$(SX_KERNEL)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_KERNEL)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_KERNEL)_DEP_FILES := $(filter-out $(SLINKS),$(DEP_FILES)) +$(SX_KERNEL)_SMDEP_FILES := $(filter-out $(SLINKS),$(SMDEP_FILES)) +$(SX_KERNEL)_SMDEP_PATHS := $(SMDEP_PATHS) + +$(SX_KERNEL_DEV)_CACHE_MODE := GIT_CONTENT_SHA +$(SX_KERNEL_DEV)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SX_KERNEL_DEV)_DEP_FILES := $(filter-out $(SLINKS),$(DEP_FILES)) +$(SX_KERNEL_DEV)_SMDEP_FILES := $(filter-out $(SLINKS),$(SMDEP_FILES)) +$(SX_KERNEL_DEV)_SMDEP_PATHS := $(SMDEP_PATHS) diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index f2af75cccf2b..d35eb67a1f11 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,8 +1,9 @@ MLNX_SDK_BASE_PATH = $(PLATFORM_PATH)/sdk-src/sx-kernel/Switch-SDK-drivers/bin/ -MLNX_SDK_VERSION = 4.4.0542 +MLNX_SDK_PKG_BASE_PATH = $(MLNX_SDK_BASE_PATH)/$(BLDENV)/ +MLNX_SDK_VERSION = 4.4.2318 MLNX_SDK_ISSU_VERSION = 101 -MLNX_SDK_DEB_VERSION = $(subst _,.,$(MLNX_SDK_VERSION)) +MLNX_SDK_DEB_VERSION = $(subst -,.,$(subst _,.,$(MLNX_SDK_VERSION))) # Place here URL where SDK sources exist MLNX_SDK_SOURCE_BASE_URL = @@ -136,7 +137,7 @@ SX_KERNEL_DEV = sx-kernel-dev_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb $(eval $(call add_derived_package,$(SX_KERNEL),$(SX_KERNEL_DEV))) define make_path - $(1)_PATH = $(MLNX_SDK_BASE_PATH) + $(1)_PATH = $(MLNX_SDK_PKG_BASE_PATH) endef @@ -152,8 +153,6 @@ else SONIC_COPY_DEBS += $(MLNX_SDK_RDEBS) $(PYTHON_SDK_API) endif -SONIC_STRETCH_DEBS += $(SX_KERNEL) - mlnx-sdk-packages: $(addprefix $(DEBS_PATH)/, $(MLNX_SDK_RDEBS) $(PYTHON_SDK_API) $(SX_KERNEL)) SONIC_PHONY_TARGETS += mlnx-sdk-packages diff --git a/platform/nephos/docker-ptf-nephos.mk b/platform/nephos/docker-ptf-nephos.mk deleted file mode 100644 index 7fbbd271cf65..000000000000 --- a/platform/nephos/docker-ptf-nephos.mk +++ /dev/null @@ -1,7 +0,0 @@ -# docker image for docker-ptf-nephos - -DOCKER_PTF_NEPHOS = docker-ptf-nephos.gz -$(DOCKER_PTF_NEPHOS)_PATH = $(DOCKERS_PATH)/docker-ptf-saithrift -$(DOCKER_PTF_NEPHOS)_DEPENDS += $(PYTHON_SAITHRIFT_NEPHOS) -$(DOCKER_PTF_NEPHOS)_LOAD_DOCKERS += $(DOCKER_PTF) -SONIC_DOCKER_IMAGES += $(DOCKER_PTF_NEPHOS) 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) \ diff --git a/platform/nephos/docker-syncd-nephos-rpc/Dockerfile.j2 b/platform/nephos/docker-syncd-nephos-rpc/Dockerfile.j2 index b4b4724e47ff..6c63efb69bb6 100644 --- a/platform/nephos/docker-syncd-nephos-rpc/Dockerfile.j2 +++ b/platform/nephos/docker-syncd-nephos-rpc/Dockerfile.j2 @@ -11,11 +11,6 @@ debs/ RUN apt-get purge -y syncd -RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; } ; \ -{% for deb in docker_syncd_nephos_rpc_debs.split(' ') -%} -dpkg_apt debs/{{ deb }}{{'; '}} -{%- endfor %} - ## Pre-install the fundamental packages RUN apt-get update \ && apt-get -y install \ @@ -27,7 +22,16 @@ RUN apt-get update \ python-dev \ wget \ cmake \ - && wget https://github.com/nanomsg/nanomsg/archive/1.0.0.tar.gz \ + libqt5core5a \ + libqt5network5 \ + libboost-atomic1.71.0 + +RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; } ; \ +{% for deb in docker_syncd_nephos_rpc_debs.split(' ') -%} +dpkg_apt debs/{{ deb }}{{'; '}} +{%- endfor %} + +RUN wget https://github.com/nanomsg/nanomsg/archive/1.0.0.tar.gz \ && tar xvfz 1.0.0.tar.gz \ && cd nanomsg-1.0.0 \ && mkdir -p build \ @@ -48,4 +52,4 @@ RUN apt-get update \ COPY ["ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/nephos/docker-syncd-nephos.mk b/platform/nephos/docker-syncd-nephos.mk index 67bad252870a..146523ec1c64 100644 --- a/platform/nephos/docker-syncd-nephos.mk +++ b/platform/nephos/docker-syncd-nephos.mk @@ -11,6 +11,9 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSAIMETADATA_DBG) \ $(LIBSAIREDIS_DBG) +SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_BASE) +SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_SYNCD_BASE_DBG) + $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd diff --git a/platform/nephos/docker-syncd-nephos/Dockerfile.j2 b/platform/nephos/docker-syncd-nephos/Dockerfile.j2 index f891ace1e8e4..e142fa04d57d 100755 --- a/platform/nephos/docker-syncd-nephos/Dockerfile.j2 +++ b/platform/nephos/docker-syncd-nephos/Dockerfile.j2 @@ -32,7 +32,7 @@ debs/{{ deb }}{{' '}} ##debs/{{ deb }}{{' '}} ##{%- endfor %} -COPY ["files/dsserve", "files/npx_diag", "start.sh", "/usr/bin/"] +COPY ["files/dsserve", "files/npx_diag", "/usr/bin/"] RUN chmod +x /usr/bin/npx_diag /usr/bin/dsserve COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] @@ -43,4 +43,4 @@ COPY ["critical_processes", "/etc/supervisor/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] 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 0b9ec741cd57..d63346d9ee20 100644 --- a/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd +++ b/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd @@ -4,8 +4,8 @@ ## syncd ## dsserve ############################################################################### -check process syncd matching "/usr/bin/syncd" - if does not exist for 5 times within 5 cycles then alert +check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles -check process dsserve matching "/usr/bin/dsserve /usr/bin/syncd" - if does not exist for 5 times within 5 cycles then alert +check program syncd|dsserve with path "/usr/bin/process_checker syncd /usr/bin/dsserve /usr/bin/syncd" + if status != 0 for 5 times within 5 cycles then alert repeat every 1 cycles diff --git a/platform/nephos/docker-syncd-nephos/critical_processes b/platform/nephos/docker-syncd-nephos/critical_processes index 489668a89e08..d1163a9c3046 100644 --- a/platform/nephos/docker-syncd-nephos/critical_processes +++ b/platform/nephos/docker-syncd-nephos/critical_processes @@ -1,2 +1,2 @@ -dsserve -syncd +program:dsserve +program:syncd diff --git a/platform/nephos/docker-syncd-nephos/start.sh b/platform/nephos/docker-syncd-nephos/start.sh deleted file mode 100755 index 623316050475..000000000000 --- a/platform/nephos/docker-syncd-nephos/start.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -rm -f /var/run/rsyslogd.pid - -supervisorctl start rsyslogd - -supervisorctl start syncd diff --git a/platform/nephos/docker-syncd-nephos/supervisord.conf b/platform/nephos/docker-syncd-nephos/supervisord.conf index 0c6285d46ae0..955021ad2d51 100644 --- a/platform/nephos/docker-syncd-nephos/supervisord.conf +++ b/platform/nephos/docker-syncd-nephos/supervisord.conf @@ -3,32 +3,36 @@ 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 +[eventlistener:dependent-startup] +command=python2 -m supervisord_dependent_startup autostart=true autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE +buffer_size=25 -[program:start.sh] -command=/usr/bin/start.sh -priority=1 +[eventlistener:supervisor-proc-exit-listener] +command=python2 /usr/bin/supervisor-proc-exit-listener --container-name syncd +events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING autostart=true -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog +autorestart=unexpected [program:rsyslogd] -command=/usr/sbin/rsyslogd -n -priority=2 +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 autostart=false autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true [program:syncd] command=/usr/bin/syncd_start.sh -priority=3 +priority=2 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running diff --git a/platform/nephos/nephos-modules.mk b/platform/nephos/nephos-modules.mk index ebd696217b8e..5e055537a428 100644 --- a/platform/nephos/nephos-modules.mk +++ b/platform/nephos/nephos-modules.mk @@ -1,26 +1,9 @@ # Nephos Platform modules -VERSION = 1.0.0 +NPS_PLATFORM_MODULE_VERSION = 1.0.1 -ifneq ($(NEPHOS_SAI_DEB_LOCAL_URL), ) -SDK_FROM_LOCAL = y -else -SDK_FROM_LOCAL = n -endif - -SDK_VERSION = 3.0.0 -LINUX_VER = 4.9.0-11-2 -SDK_COMMIT_ID = 529202 - -ifeq ($(SAI_FROM_LOCAL), y) -NEPHOS_MODULE = nps-modules-$(LINUX_VER)_$(SDK_VERSION)_$(SDK_COMMIT_ID)_amd64.deb -$(NEPHOS_MODULE)_PATH = $(NEPHOS_SAI_DEB_LOCAL_URL) -SONIC_COPY_DEBS += $(NEPHOS_MODULE) -else -NEPHOS_MODULE = nephos-modules_$(VERSION)_amd64.deb +NEPHOS_MODULE = nephos-modules_$(NPS_PLATFORM_MODULE_VERSION)_amd64.deb $(NEPHOS_MODULE)_SRC_PATH = $(PLATFORM_PATH)/nephos-modules $(NEPHOS_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) SONIC_DPKG_DEBS += $(NEPHOS_MODULE) -endif -SONIC_STRETCH_DEBS += $(NEPHOS_MODULE) 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..1b485d808f3e 100644 --- a/platform/nephos/nephos-modules/debian/control +++ b/platform/nephos/nephos-modules/debian/control @@ -1,12 +1,12 @@ Source: nephos-modules Section: main Priority: extra -Maintainer: support +Maintainer: support Build-Depends: debhelper (>= 8.0.0), bzip2 Standards-Version: 3.9.3 Package: nephos-modules Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for nephos asic diff --git a/platform/nephos/nephos-modules/modules/init.d/nps-modules b/platform/nephos/nephos-modules/modules/init.d/nps-modules new file mode 100755 index 000000000000..d6f841ee02e7 --- /dev/null +++ b/platform/nephos/nephos-modules/modules/init.d/nps-modules @@ -0,0 +1,54 @@ +#!/bin/bash +# This script load/unload nps kernel modules + +### BEGIN INIT INFO +# Provides: load-nps-modules +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Load nps kernel modules +### END INIT INFO + +case "$1" in +start) + echo -n "Load nps kernel modules... " + + RMEM_SIZE=`cat /proc/sys/net/core/rmem_max` + if [ $RMEM_SIZE -lt 8388608 ]; then + echo "8388608" > /proc/sys/net/core/rmem_max + fi + WMEM_SIZE=`cat /proc/sys/net/core/wmem_max` + if [ $WMEM_SIZE -lt 25165824 ]; then + echo "25165824" > /proc/sys/net/core/wmem_max + fi + + modprobe nps_dev + modprobe nps_netif + + echo "done." + ;; + +stop) + echo -n "Unload nps kernel modules... " + + rmmod nps_netif + rmmod nps_dev + + echo "done." + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/nps-modules {start|stop}" + exit 1 + ;; +esac + +exit 0 + 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 deleted file mode 100755 index a6deb4217a95..000000000000 --- a/platform/nephos/nephos-modules/modules/init.d/nps-modules-4.9.0-9-2-amd64 +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/bash -# This script load/unload nps kernel modules - -### BEGIN INIT INFO -# Provides: load-nps-modules -# Required-Start: -# Required-Stop: -# Should-Start: -# Should-Stop: -# Default-Start: S -# Default-Stop: 0 6 -# Short-Description: Load nps kernel modules -### END INIT INFO - -case "$1" in -start) - echo -n "Load nps kernel modules... " - - RMEM_SIZE=`cat /proc/sys/net/core/rmem_max` - if [ $RMEM_SIZE -lt 8388608 ]; then - echo "8388608" > /proc/sys/net/core/rmem_max - fi - WMEM_SIZE=`cat /proc/sys/net/core/wmem_max` - if [ $WMEM_SIZE -lt 25165824 ]; then - echo "25165824" > /proc/sys/net/core/wmem_max - fi - - modprobe nps_dev - modprobe nps_netif - - echo "done." - ;; - -stop) - echo -n "Unload nps kernel modules... " - - rmmod nps_netif - rmmod nps_dev - - echo "done." - ;; - -force-reload|restart) - echo "Not supported" - ;; - -*) - echo "Usage: /etc/init.d/nps-modules-4.9.0-11-2-amd64.init {start|stop}" - exit 1 - ;; -esac - -exit 0 - 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 deleted file mode 100644 index 9acdeb30a44c..000000000000 --- a/platform/nephos/nephos-modules/modules/service/nps-modules-4.9.0-9-2-amd64.service +++ /dev/null @@ -1,13 +0,0 @@ -[Unit] -Description=Nephos kernel modules init -After=local-fs.target -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 -RemainAfterExit=yes - -[Install] -WantedBy=multi-user.target diff --git a/platform/nephos/nephos-modules/modules/service/nps-modules.service b/platform/nephos/nephos-modules/modules/service/nps-modules.service new file mode 100644 index 000000000000..22aa9a7510c6 --- /dev/null +++ b/platform/nephos/nephos-modules/modules/service/nps-modules.service @@ -0,0 +1,13 @@ +[Unit] +Description=Nephos kernel modules init +After=local-fs.target +Before=syncd.service + +[Service] +Type=oneshot +ExecStart=-/etc/init.d/nps-modules start +ExecStop=-/etc/init.d/nps-modules stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target 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"); diff --git a/platform/nephos/platform-modules-accton.mk b/platform/nephos/platform-modules-accton.mk index ebfd77f30fc8..1ecb76a2fbb8 100644 --- a/platform/nephos/platform-modules-accton.mk +++ b/platform/nephos/platform-modules-accton.mk @@ -10,4 +10,3 @@ $(ACCTON_AS7116_54X_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS $(ACCTON_AS7116_54X_PLATFORM_MODULE)_PLATFORM = x86_64-accton_as7116_54x-r0 SONIC_DPKG_DEBS += $(ACCTON_AS7116_54X_PLATFORM_MODULE) -SONIC_STRETCH_DEBS += $(ACCTON_AS7116_54X_PLATFORM_MODULE) diff --git a/platform/nephos/platform-modules-cig.mk b/platform/nephos/platform-modules-cig.mk index 5cccf1692550..48e7072f6da3 100644 --- a/platform/nephos/platform-modules-cig.mk +++ b/platform/nephos/platform-modules-cig.mk @@ -9,18 +9,15 @@ $(CIG_CS6436_56P_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-mod $(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) 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/platform-modules-ingrasys.mk b/platform/nephos/platform-modules-ingrasys.mk index 94b8315cd70c..03818ca8465d 100644 --- a/platform/nephos/platform-modules-ingrasys.mk +++ b/platform/nephos/platform-modules-ingrasys.mk @@ -17,5 +17,3 @@ $(INGRASYS_S9230_64X_PLATFORM_MODULE)_PLATFORM = x86_64-ingrasys_s9230_64x-r0 $(eval $(call add_extra_package,$(INGRASYS_S9130_32X_PLATFORM_MODULE),$(INGRASYS_S9230_64X_PLATFORM_MODULE))) -SONIC_STRETCH_DEBS += $(INGRASYS_S9130_32X_PLATFORM_MODULE) -SONIC_STRETCH_DEBS += $(INGRASYS_S9230_64X_PLATFORM_MODULE) diff --git a/platform/nephos/rules.mk b/platform/nephos/rules.mk index 5c115eeaf8d0..4ee2443e7585 100644 --- a/platform/nephos/rules.mk +++ b/platform/nephos/rules.mk @@ -7,7 +7,6 @@ include $(PLATFORM_PATH)/docker-syncd-nephos.mk include $(PLATFORM_PATH)/docker-syncd-nephos-rpc.mk include $(PLATFORM_PATH)/one-image.mk include $(PLATFORM_PATH)/libsaithrift-dev.mk -include $(PLATFORM_PATH)/docker-ptf-nephos.mk NPX_DIAG = npx_diag $(NPX_DIAG)_URL = "https://github.com/NephosInc/SONiC/raw/master/sdk/npx_diag" @@ -22,10 +21,12 @@ SONIC_ONLINE_FILES += $(NPX_DIAG) $(WARM_VERIFIER) $(DSSERVE) SONIC_ALL += $(SONIC_ONE_IMAGE) $(DOCKER_FPM) -# Inject nephos sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(NEPHOS_SAI) $(NEPHOS_SAI_DEV) +# Inject nephos sai into syncd +$(SYNCD)_DEPENDS += $(NEPHOS_SAI) $(NEPHOS_SAI_DEV) +$(SYNCD)_UNINSTALLS += $(NEPHOS_SAI_DEV) + ifeq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV) +$(SYNCD)_DEPENDS += $(LIBSAITHRIFT_DEV) endif # Runtime dependency on nephos sai is set only for syncd diff --git a/platform/nephos/sai.mk b/platform/nephos/sai.mk index 5f7c4a23ae95..8bbeb9899b58 100644 --- a/platform/nephos/sai.mk +++ b/platform/nephos/sai.mk @@ -3,7 +3,7 @@ SAI_VERSION = 1.5.0 SAI_COMMIT_ID = 06a67d # Place here URL where SAI deb exist -NEPHOS_SAI_DEB_LOCAL_URL = +NEPHOS_SAI_DEB_LOCAL_URL = export NEPHOS_SAI_DEB_LOCAL_URL # ifneq ($(NEPHOS_SAI_DEB_LOCAL_URL), ) @@ -33,3 +33,4 @@ else SONIC_ONLINE_DEBS += $(NEPHOS_SAI) $(NEPHOS_SAI_DEV) endif $(NEPHOS_SAI_DEV)_DEPENDS += $(NEPHOS_SAI) +$(eval $(call add_conflict_package,$(NEPHOS_SAI_DEV),$(LIBSAIVS_DEV))) diff --git a/platform/nephos/sonic-platform-modules-accton/debian/control b/platform/nephos/sonic-platform-modules-accton/debian/control index 639534f3edcc..3020b86408d6 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-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/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 index 0a78085fd49b..0a1a887642d6 100755 --- 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 @@ -335,7 +335,7 @@ def system_get_lswtemp(): return 25 # chp = subprocess.Popen("docker ps --filter name=syncd", shell=True, stdout=subprocess.PIPE) -# if chp.poll() == None: +# if chp.poll() is None: # misclogger.info("No subp.") # chp.kill() # 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 index c186676cbf3f..b4627a081d78 100755 --- 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 @@ -335,7 +335,7 @@ def system_get_lswtemp(): return 25 # chp = subprocess.Popen("docker ps --filter name=syncd", shell=True, stdout=subprocess.PIPE) -# if chp.poll() == None: +# if chp.poll() is None: # misclogger.info("No subp.") # chp.kill() # 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 index 4c7c629f3e7b..2f442bac2603 100644 --- 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 @@ -35,7 +35,6 @@ 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); 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 3b685236a075..56add80221bb 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 @@ -335,7 +335,7 @@ def system_get_lswtemp(): return 25 # chp = subprocess.Popen("docker ps --filter name=syncd", shell=True, stdout=subprocess.PIPE) -# if chp.poll() == None: +# if chp.poll() is None: # misclogger.info("No subp.") # chp.kill() # diff --git a/platform/nephos/sonic-platform-modules-cig/debian/control b/platform/nephos/sonic-platform-modules-cig/debian/control index bf40791b24e0..fc0c6736ffa2 100644 --- a/platform/nephos/sonic-platform-modules-cig/debian/control +++ b/platform/nephos/sonic-platform-modules-cig/debian/control @@ -7,15 +7,15 @@ Standards-Version: 3.9.3 Package: sonic-platform-cig-cs6436-56p Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned 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 +Depends: linux-image-4.19.0-12-2-amd64-unsigned 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 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/nephos/sonic-platform-modules-pegatron/debian/control b/platform/nephos/sonic-platform-modules-pegatron/debian/control index 18e74be1455d..8fc19980fc12 100755 --- a/platform/nephos/sonic-platform-modules-pegatron/debian/control +++ b/platform/nephos/sonic-platform-modules-pegatron/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-pegatron-porsche Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/p4/docker-sonic-p4.mk b/platform/p4/docker-sonic-p4.mk index 534d161631f5..940b85ed5d2a 100644 --- a/platform/p4/docker-sonic-p4.mk +++ b/platform/p4/docker-sonic-p4.mk @@ -8,10 +8,11 @@ $(DOCKER_SONIC_P4)_DEPENDS += $(SWSS) \ $(REDIS_TOOLS) \ $(REDIS_SERVER) \ $(PYTHON_SWSSCOMMON) \ - $(LIBTEAMDCT) \ + $(PYTHON3_SWSSCOMMON) \ + $(LIBTEAMDCTL) \ $(LIBTEAM_UTILS) \ $(SONIC_DEVICE_DATA) \ - $(SONIC_UTILS) \ + $(SONIC_UTILITIES_PY3) \ $(IPROUTE2) # ifeq ($(ROUTING_STACK), quagga) @@ -23,7 +24,8 @@ $(DOCKER_SONIC_P4)_DEPENDS += $(QUAGGA) # endif $(DOCKER_SONIC_P4)_FILES += $(CONFIGDB_LOAD_SCRIPT) \ - $(ARP_UPDATE_SCRIPT) + $(ARP_UPDATE_SCRIPT) \ + $(ARP_UPDATE_VARS_TEMPLATE) $(DOCKER_SONIC_P4)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE) SONIC_DOCKER_IMAGES += $(DOCKER_SONIC_P4) diff --git a/platform/p4/docker-sonic-p4/Dockerfile.j2 b/platform/p4/docker-sonic-p4/Dockerfile.j2 index 0f918821dea2..90ff15472248 100644 --- a/platform/p4/docker-sonic-p4/Dockerfile.j2 +++ b/platform/p4/docker-sonic-p4/Dockerfile.j2 @@ -16,6 +16,7 @@ RUN apt-get install -y net-tools \ ethtool \ tcpdump \ ifupdown \ + jq \ bridge-utils \ python-ply \ libqt5core5a \ @@ -39,13 +40,18 @@ RUN apt-get install -y net-tools \ iproute \ libpython2.7 \ grub2-common \ - python-click-default-group \ - python-click \ - python-natsort \ - python-tabulate \ bash-completion \ libelf1 \ - libmnl0 + libmnl0 \ + # For installing Python m2crypto package + # (these can be uninstalled after installation) + build-essential \ + python-dev \ + python3-dev \ + libssl-dev \ + swig \ + # For using Python m2crypto package + openssl RUN pip install setuptools RUN pip install py2_ipaddress @@ -62,6 +68,8 @@ debs/{{ deb }}{{' '}} {%- endfor %} ## Clean up +RUN apt-get purge -y build-essential libssl-dev swig +RUN apt-get purge -y python-dev python3-dev RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs @@ -79,6 +87,7 @@ COPY ["start.sh", "orchagent.sh", "config_bm.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["files/configdb-load.sh", "/usr/bin/"] COPY ["files/arp_update", "/usr/bin"] +COPY ["files/arp_update_vars.j2", "/usr/share/sonic/templates/"] RUN echo "docker-sonic-p4" > /etc/hostname RUN touch /etc/quagga/zebra.conf diff --git a/platform/p4/docker-sonic-p4/orchagent.sh b/platform/p4/docker-sonic-p4/orchagent.sh index 9abfc22c967e..1975e44753f1 100755 --- a/platform/p4/docker-sonic-p4/orchagent.sh +++ b/platform/p4/docker-sonic-p4/orchagent.sh @@ -1,6 +1,11 @@ #!/usr/bin/env bash -MAC_ADDRESS=$(sonic-cfggen -d -v 'DEVICE_METADATA.localhost.mac') +SWSS_VARS_FILE=/usr/share/sonic/templates/swss_vars.j2 + +# Retrieve SWSS vars from sonic-cfggen +SWSS_VARS=$(sonic-cfggen -d -y /etc/sonic/sonic_version.yml -t $SWSS_VARS_FILE) || exit 1 + +MAC_ADDRESS=$(echo $SWSS_VARS | jq -r '.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" @@ -13,6 +18,12 @@ ORCHAGENT_ARGS="-d /var/log/swss " # Set orchagent pop batch size to 8192 ORCHAGENT_ARGS+="-b 8192 " +# Set synchronous mode if it is enabled in CONFIG_DB +SYNC_MODE=$(echo $SWSS_VARS | jq -r '.synchronous_mode') +if [ "$SYNC_MODE" == "enable" ]; then + ORCHAGENT_ARGS+="-s " +fi + # Set mac address ORCHAGENT_ARGS+="-m $MAC_ADDRESS" diff --git a/platform/p4/docker-sonic-p4/start.sh b/platform/p4/docker-sonic-p4/start.sh index e3251bb2f4e5..2da8fe2249fd 100755 --- a/platform/p4/docker-sonic-p4/start.sh +++ b/platform/p4/docker-sonic-p4/start.sh @@ -58,6 +58,9 @@ supervisorctl start portsyncd echo "Start neighsyncd" supervisorctl start neighsyncd +echo "Start fdbsyncd" +supervisorctl start fdbsyncd + echo "Start teamsyncd" supervisorctl start teamsyncd diff --git a/platform/p4/docker-sonic-p4/supervisord.conf b/platform/p4/docker-sonic-p4/supervisord.conf index 946e4cb36e3a..a4026f61c140 100644 --- a/platform/p4/docker-sonic-p4/supervisord.conf +++ b/platform/p4/docker-sonic-p4/supervisord.conf @@ -131,3 +131,11 @@ autostart=false autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog + +[program:fdbsyncd] +command=/usr/bin/fdbsyncd +priority=16 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog diff --git a/platform/p4/rules.mk b/platform/p4/rules.mk index 975dbb82ec8c..b33b04f43d41 100644 --- a/platform/p4/rules.mk +++ b/platform/p4/rules.mk @@ -10,8 +10,8 @@ include $(PLATFORM_PATH)/libsaithrift-dev.mk SONIC_ALL += $(DOCKER_SONIC_P4) -$(LIBSAIREDIS)_DEPENDS += $(P4_SWITCH) +$(SYNCD)_DEPENDS += $(P4_SWITCH) ifeq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV_P4) +$(SYNCD)_DEPENDS += $(LIBSAITHRIFT_DEV_P4) endif -$(LIBSAIREDIS)_RDEPENDS += $(P4_SWITCH) +$(SYNCD)_RDEPENDS += $(P4_SWITCH) diff --git a/platform/pddf/README.md b/platform/pddf/README.md new file mode 100644 index 000000000000..b46bb6780b1e --- /dev/null +++ b/platform/pddf/README.md @@ -0,0 +1,19 @@ + Platform Driver Development Framework (PDDF) is part of SONiC Platform Development Kit (PDK) which optimizes the platform developement. + + SONiC PDDF (Platform driver development framework) supports the following HW devices on a given platform: + + - Fan + - PSU + - System EEPROM + - CPLD + - CPLDMUX + - GPIO + - Optic Transceivers + - System LED control via CPLD + - System Status Registers in CPLD + - Temp Sensors + + This folder for the PDDF consists of the following: + + - PDDF python utility scripts + - Generic PDDF HW device drivers in kernel space diff --git a/platform/pddf/i2c/Makefile b/platform/pddf/i2c/Makefile new file mode 100644 index 000000000000..1486370b5005 --- /dev/null +++ b/platform/pddf/i2c/Makefile @@ -0,0 +1 @@ +subdir-m := modules diff --git a/platform/pddf/i2c/debian/changelog b/platform/pddf/i2c/debian/changelog new file mode 100755 index 000000000000..505184c1fd80 --- /dev/null +++ b/platform/pddf/i2c/debian/changelog @@ -0,0 +1,12 @@ +sonic-pddf-platform-modules (1.1) unstable; urgency=low + + * Enhancing PDDF: Added support for cpldmux, gpio and some extra attributes + + -- Broadcom Wed, 10 Jun 2020 10:10:10 -0800 + +sonic-pddf-platform-modules (1.0) unstable; urgency=low + + * Basic tempelate for PDDF + * Initial release + + -- Broadcom Wed, 26 Jun 2019 10:10:10 -0800 diff --git a/platform/pddf/i2c/debian/compat b/platform/pddf/i2c/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/platform/pddf/i2c/debian/compat @@ -0,0 +1 @@ +9 diff --git a/platform/pddf/i2c/debian/control b/platform/pddf/i2c/debian/control new file mode 100755 index 000000000000..afd96c3d260a --- /dev/null +++ b/platform/pddf/i2c/debian/control @@ -0,0 +1,12 @@ +Source: sonic-pddf-platform-modules +Section: main +Priority: extra +Maintainer: Broadcom +Build-Depends: debhelper (>= 9), bzip2 +Standards-Version: 3.9.3 + +Package: sonic-platform-pddf +Architecture: amd64 +Description: kernel modules for platform devices such as psu, fan, sfp, led + + diff --git a/platform/pddf/i2c/debian/rules b/platform/pddf/i2c/debian/rules new file mode 100755 index 000000000000..35fca9a784ad --- /dev/null +++ b/platform/pddf/i2c/debian/rules @@ -0,0 +1,75 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# This file was originally written by Joey Hess and Craig Small. +# As a special exception, when this file is copied by dh-make into a +# dh-make output file, you may use that output file without restriction. +# This special exception was added by Craig Small in version 0.37 of dh-make. +include /usr/share/dpkg/pkg-info.mk + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +export INSTALL_MOD_DIR:=extra + +PYTHON ?= python2 + +PACKAGE_PRE_NAME := sonic-platform-pddf +KVERSION ?= $(shell uname -r) +KERNEL_SRC := /lib/modules/$(KVERSION) +MOD_SRC_DIR:= $(shell pwd) +MODULE_DIRS:= client cpld cpld/driver cpldmux cpldmux/driver fan fan/driver fan/vendor_api mux gpio led psu psu/driver sysstatus xcvr xcvr/driver +MODULE_DIR:= modules +UTILS_DIR := utils +SERVICE_DIR := service + +%: + echo =================RUNNING $@============= + dh $@ --with systemd,python2,python3 --buildsystem=pybuild + +clean: + echo ============CLEANING================= + dh_testdir + dh_testroot + dh_clean + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR) clean + +build: + make modules -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR); \ + $(PYTHON) $(MOD_SRC_DIR)/setup.py build; \ + +binary: binary-arch binary-indep + # Nothing to do + +binary-arch: + # Nothing to do + +binary-indep: + dh_testdir + dh_installdirs + dh_installdirs -p$(PACKAGE_PRE_NAME) $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + dh_installdirs -p$(PACKAGE_PRE_NAME) usr/local/bin; \ + # Custom package commands + (for mod in $(MODULE_DIRS); do \ + cp $(MOD_SRC_DIR)/$(MODULE_DIR)/$${mod}/*.ko debian/$(PACKAGE_PRE_NAME)/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + done) ; \ + cp -r $(MOD_SRC_DIR)/$(UTILS_DIR)/* debian/$(PACKAGE_PRE_NAME)/usr/local/bin/; \ + $(PYTHON) $(MOD_SRC_DIR)/setup.py install --root=$(MOD_SRC_DIR)/debian/$(PACKAGE_PRE_NAME) --install-layout=deb; + + # Resuming debhelper scripts + dh_testroot + dh_install + dh_installchangelogs + dh_installdocs + dh_systemd_enable + dh_installinit + dh_systemd_start + dh_link + dh_fixperms + dh_compress + dh_strip + dh_installdeb + dh_gencontrol + dh_md5sums + dh_builddeb +.PHONY: build binary binary-arch binary-indep clean diff --git a/platform/pddf/i2c/modules/Makefile b/platform/pddf/i2c/modules/Makefile new file mode 100644 index 000000000000..67d3726c3202 --- /dev/null +++ b/platform/pddf/i2c/modules/Makefile @@ -0,0 +1 @@ +subdir-m := client cpld cpldmux xcvr mux gpio psu fan led sysstatus diff --git a/platform/pddf/i2c/modules/client/Makefile b/platform/pddf/i2c/modules/client/Makefile new file mode 100644 index 000000000000..c841a144f2db --- /dev/null +++ b/platform/pddf/i2c/modules/client/Makefile @@ -0,0 +1,3 @@ +obj-m:= pddf_client_module.o + +ccflags-y := -I$(M)/modules/include diff --git a/platform/pddf/i2c/modules/client/pddf_client_module.c b/platform/pddf/i2c/modules/client/pddf_client_module.c new file mode 100644 index 000000000000..f36596dbe970 --- /dev/null +++ b/platform/pddf/i2c/modules/client/pddf_client_module.c @@ -0,0 +1,330 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A pddf kernel module to create access-data attributes for client creation + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pddf_client_defs.h" + + + +NEW_DEV_ATTR pddf_data={0}; +EXPORT_SYMBOL(pddf_data); +int showall = 0; + + +/* CLIENT CREATION DATA ATTR LIST */ +PDDF_DATA_ATTR(i2c_type, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_CHAR, 32, (void*)&pddf_data.i2c_type, NULL); +PDDF_DATA_ATTR(i2c_name, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_CHAR, 32, (void*)&pddf_data.i2c_name, NULL); +PDDF_DATA_ATTR(parent_bus, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_HEX, sizeof(int), (void*)&pddf_data.parent_bus, NULL); +PDDF_DATA_ATTR(dev_type, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_CHAR, 32, (void*)&pddf_data.dev_type, NULL); +PDDF_DATA_ATTR(dev_id, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_DEC, sizeof(int), (void*)&pddf_data.dev_id, NULL); +PDDF_DATA_ATTR(dev_addr, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_HEX, sizeof(int), (void*)&pddf_data.dev_addr, NULL); +PDDF_DATA_ATTR(error, S_IRUGO, show_error_code, NULL, PDDF_INT_DEC, sizeof(int), (void*)&pddf_data.error, (void*)&pddf_data.errstr); + + + +static struct attribute *pddf_clients_data_attributes[] = { + &attr_i2c_type.dev_attr.attr, + &attr_i2c_name.dev_attr.attr, + &attr_parent_bus.dev_attr.attr, + &attr_dev_type.dev_attr.attr, + &attr_dev_id.dev_attr.attr, + &attr_dev_addr.dev_attr.attr, + &attr_error.dev_attr.attr, + NULL +}; + +struct attribute_group pddf_clients_data_group = { + .attrs = pddf_clients_data_attributes, +}; +EXPORT_SYMBOL(pddf_clients_data_group); + + + +PDDF_DATA_ATTR(showall, S_IRUGO, show_all_devices, NULL, PDDF_INT_DEC, sizeof(int), (void *)&showall, NULL); + +static struct attribute *pddf_allclients_data_attributes[] = { + &attr_showall.dev_attr.attr, + NULL +}; +struct attribute_group pddf_allclients_data_group = { + .attrs = pddf_allclients_data_attributes, +}; + + + + + +void set_attr_data(void * ptr) +{ + pddf_data.data=ptr; +} + +ssize_t show_all_devices(struct device *dev, struct device_attribute *da, char *buf) +{ + int ret = 0; + PDDF_ATTR *pptr = (PDDF_ATTR *)da; + int *ptr = (int *)pptr->addr; + + traverse_device_table(); + ret = sprintf(buf, "Total Devices: %d\n", *ptr); + + return ret; +} + +ssize_t show_error_code(struct device *dev, struct device_attribute *da, char *buf) +{ + int ret = 0; + PDDF_ATTR *pptr = (PDDF_ATTR *)da; + NEW_DEV_ATTR *ptr = ( NEW_DEV_ATTR *)pptr->addr; + + ret = sprintf(buf, "0x%x:%s\n", (ptr->error), ptr->errstr); + + return ret; +} + +void set_error_code(int ecode, char *estr) +{ + pddf_data.error = ecode; + strcpy(pddf_data.errstr, estr); + return; +} +EXPORT_SYMBOL(set_error_code); + +ssize_t show_pddf_data(struct device *dev, struct device_attribute *da, char *buf) +{ + int ret = 0; + PDDF_ATTR *ptr = (PDDF_ATTR *)da; + /*pddf_dbg(KERN_ERR "[ READ ] DATA ATTR PTR TYPE:%d, ADDR=%p\n", ptr->type, ptr->addr);*/ + switch(ptr->type) + { + case PDDF_CHAR: + ret = sprintf(buf, "%s\n", ptr->addr); + break; + case PDDF_UCHAR: + ret = sprintf(buf, "%d\n", *(unsigned char*)(ptr->addr)); + break; + case PDDF_INT_DEC: + ret = sprintf(buf, "%d\n", *(int*)(ptr->addr)); + break; + case PDDF_INT_HEX: + ret = sprintf(buf, "0x%x\n", *(int*)(ptr->addr)); + break; + case PDDF_USHORT: + ret = sprintf(buf, "0x%x\n", *(unsigned short *)(ptr->addr)); + break; + case PDDF_UINT32: + ret = sprintf(buf, "0x%x\n", *(uint32_t *)(ptr->addr)); + break; + default: + break; + } + + return ret; +} +EXPORT_SYMBOL(show_pddf_data); + +ssize_t store_pddf_data(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int ret = 0, num = 0; + + + PDDF_ATTR *ptr = (PDDF_ATTR *)da; + + switch(ptr->type) + { + case PDDF_CHAR: + strncpy(ptr->addr, buf, strlen(buf)-1); // to discard newline char form buf + ptr->addr[strlen(buf)-1] = '\0'; + break; + case PDDF_UCHAR: + ret = kstrtoint(buf,10,&num); + if (ret==0) + *(unsigned char *)(ptr->addr) = (unsigned char)num; + break; + case PDDF_INT_DEC: + ret = kstrtoint(buf,10,&num); + if (ret==0) + *(int *)(ptr->addr) = num; + break; + case PDDF_INT_HEX: + ret = kstrtoint(buf,16,&num); + if (ret==0) + *(int *)(ptr->addr) = num; + break; + case PDDF_USHORT: + ret = kstrtoint(buf,16,&num); + if (ret==0) + *(unsigned short *)(ptr->addr) = (unsigned short)num; + break; + case PDDF_UINT32: + ret = kstrtoint(buf,16,&num); + if (ret==0) + *(uint32_t *)(ptr->addr) = (uint32_t)num; + break; + default: + break; + } + + return count; +} +EXPORT_SYMBOL(store_pddf_data); + + + +DEFINE_HASHTABLE(htable, 8); + +int get_hash(char *name) +{ + int i=0; + int hash=0; + for(i=0; iname, name); + hdev->data = ptr; + pddf_dbg(CLIENT, KERN_ERR "%s: Adding ptr 0x%p to the hash table\n", __FUNCTION__, ptr); + hash_add(htable, &hdev->node, get_hash(hdev->name)); +} +EXPORT_SYMBOL(add_device_table); + +void* get_device_table(char *name) +{ + PDEVICE *dev=NULL; + int i=0; + + hash_for_each(htable, i, dev, node) { + if(strcmp(dev->name, name)==0) { + return (void *)dev->data; + } + } + + return NULL; +} +EXPORT_SYMBOL(get_device_table); + +void delete_device_table(char *name) +{ + PDEVICE *dev=NULL; + int i=0; + + hash_for_each(htable, i, dev, node) { + if(strcmp(dev->name, name)==0) { + pddf_dbg(CLIENT, KERN_ERR "found entry to delete: %s 0x%p\n", dev->name, dev->data); + hash_del(&(dev->node)); + } + } + return; +} +EXPORT_SYMBOL(delete_device_table); + +void traverse_device_table(void ) +{ + PDEVICE *dev=NULL; + int i=0; + hash_for_each(htable, i, dev, node) { + pddf_dbg(CLIENT, KERN_ERR "Entry[%d]: %s : 0x%p\n", i, dev->name, dev->data); + } + showall = i; +} +EXPORT_SYMBOL(traverse_device_table); + +struct kobject *device_kobj; +static struct kobject *pddf_kobj; + +struct kobject *get_device_i2c_kobj(void) +{ + return device_kobj; +} + +EXPORT_SYMBOL(get_device_i2c_kobj); + +int __init pddf_data_init(void) +{ + int ret = 0; + + + pddf_dbg(CLIENT, "PDDF_DATA MODULE.. init\n"); + + pddf_kobj = kobject_create_and_add("pddf", kernel_kobj); + if(!pddf_kobj) { + return -ENOMEM; + } + device_kobj = kobject_create_and_add("devices", pddf_kobj); + if(!device_kobj) { + return -ENOMEM; + } + + init_device_table(); + + ret = sysfs_create_group(device_kobj, &pddf_allclients_data_group); + if (ret) + { + kobject_put(device_kobj); + return ret; + } + pddf_dbg(CLIENT, "CREATED PDDF ALLCLIENTS CREATION SYSFS GROUP\n"); + + + + return ret; +} + +void __exit pddf_data_exit(void) +{ + + pddf_dbg(CLIENT, "PDDF_DATA MODULE.. exit\n"); + sysfs_remove_group(device_kobj, &pddf_allclients_data_group); + + kobject_put(device_kobj); + kobject_put(pddf_kobj); + pddf_dbg(CLIENT, KERN_ERR "%s: Removed the kernle object for 'pddf' and 'device' \n", __FUNCTION__); + return; +} + +module_init(pddf_data_init); +module_exit(pddf_data_exit); + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("pddf data"); +MODULE_LICENSE("GPL"); + diff --git a/platform/pddf/i2c/modules/cpld/Makefile b/platform/pddf/i2c/modules/cpld/Makefile new file mode 100644 index 000000000000..c6182ef4f93d --- /dev/null +++ b/platform/pddf/i2c/modules/cpld/Makefile @@ -0,0 +1,4 @@ +subdir-m := driver +obj-m := pddf_cpld_module.o + +CFLAGS_$(obj-m):= -I$(M)/modules/include diff --git a/platform/pddf/i2c/modules/cpld/driver/Makefile b/platform/pddf/i2c/modules/cpld/driver/Makefile new file mode 100644 index 000000000000..42704c2cfaec --- /dev/null +++ b/platform/pddf/i2c/modules/cpld/driver/Makefile @@ -0,0 +1,5 @@ +TARGET = pddf_cpld_driver +obj-m := $(TARGET).o + + +ccflags-y := -I$(M)/modules/include diff --git a/platform/pddf/i2c/modules/cpld/driver/pddf_cpld_driver.c b/platform/pddf/i2c/modules/cpld/driver/pddf_cpld_driver.c new file mode 100755 index 000000000000..a34c370b9af1 --- /dev/null +++ b/platform/pddf/i2c/modules/cpld/driver/pddf_cpld_driver.c @@ -0,0 +1,230 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A pddf kernel driver module for CPLD + */ + +#include +#include +#include +#include +#include +#include "pddf_cpld_defs.h" + +extern PDDF_CPLD_DATA pddf_cpld_data; + + +static LIST_HEAD(cpld_client_list); +static struct mutex list_lock; + +struct cpld_client_node { + struct i2c_client *client; + struct list_head list; +}; + +int board_i2c_cpld_read(unsigned short cpld_addr, u8 reg) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EPERM; + + //hw_preaccess_func_cpld_mux_default((uint32_t)cpld_addr, NULL); + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = i2c_smbus_read_byte_data(cpld_node->client, reg); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(board_i2c_cpld_read); + +int board_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EIO; + + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = i2c_smbus_write_byte_data(cpld_node->client, reg, value); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(board_i2c_cpld_write); + +ssize_t regval_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int len = 0; + struct i2c_client *client = to_i2c_client(dev); + + mutex_lock(&pddf_cpld_data.cpld_lock); + // Put code here to read the register value and print it + if (pddf_cpld_data.reg_addr!=0) + len = sprintf(buf, "0x%2.2x\n", board_i2c_cpld_read(client->addr, pddf_cpld_data.reg_addr)); + else + len = sprintf(buf, "xx\n"); + + mutex_unlock(&pddf_cpld_data.cpld_lock); + return len; +} + +static DEVICE_ATTR_RO(regval); + +static struct attribute *cpld_attrs[] = { + &dev_attr_regval.attr, + NULL, +}; + +static struct attribute_group cpld_attribute_group = { + .attrs = cpld_attrs, +}; + + + + +/* Addresses scanned for board_i2c_cpld + */ +static const unsigned short normal_i2c[] = { 0x31, 0x32, 0x33, 0x35, 0x60, 0x61, 0x62, 0x64, I2C_CLIENT_END }; + +static void board_i2c_cpld_add_client(struct i2c_client *client) +{ + struct cpld_client_node *node = kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL); + + if (!node) { + dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", client->addr); + return; + } + + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &cpld_client_list); + mutex_unlock(&list_lock); +} + +static void board_i2c_cpld_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client == client) { + found = 1; + break; + } + } + + if (found) { + list_del(list_node); + kfree(cpld_node); + } + + mutex_unlock(&list_lock); +} + +static int board_i2c_cpld_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_dbg(&client->dev, "i2c_check_functionality failed (0x%x)\n", client->addr); + status = -EIO; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &cpld_attribute_group); + if (status) { + goto exit; + } + + dev_dbg(&client->dev, "chip found\n"); + board_i2c_cpld_add_client(client); + + return 0; + +exit: + return status; +} + +static int board_i2c_cpld_remove(struct i2c_client *client) +{ + sysfs_remove_group(&client->dev.kobj, &cpld_attribute_group); + board_i2c_cpld_remove_client(client); + + return 0; +} + +static const struct i2c_device_id board_i2c_cpld_id[] = { + { "i2c_cpld", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, board_i2c_cpld_id); + +static struct i2c_driver board_i2c_cpld_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "i2c_cpld", + }, + .probe = board_i2c_cpld_probe, + .remove = board_i2c_cpld_remove, + .id_table = board_i2c_cpld_id, + .address_list = normal_i2c, +}; + +static int __init board_i2c_cpld_init(void) +{ + mutex_init(&list_lock); + return i2c_add_driver(&board_i2c_cpld_driver); +} + +static void __exit board_i2c_cpld_exit(void) +{ + i2c_del_driver(&board_i2c_cpld_driver); +} + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("board_i2c_cpld driver"); +MODULE_LICENSE("GPL"); + +module_init(board_i2c_cpld_init); +module_exit(board_i2c_cpld_exit); diff --git a/platform/pddf/i2c/modules/cpld/pddf_cpld_module.c b/platform/pddf/i2c/modules/cpld/pddf_cpld_module.c new file mode 100644 index 000000000000..af15e390265f --- /dev/null +++ b/platform/pddf/i2c/modules/cpld/pddf_cpld_module.c @@ -0,0 +1,219 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * A pddf kernel module to create I2C client for a CPLD + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pddf_client_defs.h" +#include "pddf_cpld_defs.h" + +PDDF_CPLD_DATA pddf_cpld_data={0}; +EXPORT_SYMBOL(pddf_cpld_data); + +static ssize_t do_device_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t store_pddf_cpld_data(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +ssize_t show_pddf_cpld_data(struct device *dev, struct device_attribute *da, char *buf); + +extern void *get_device_table(char *name); +extern void delete_device_table(char *name); + + +/* MUX CLIENT DATA */ +PDDF_DATA_ATTR(dev_ops, S_IWUSR, NULL, do_device_operation, PDDF_CHAR, 8, NULL, (void*)&pddf_data); +PDDF_DATA_ATTR(reg_addr, S_IWUSR|S_IRUGO, show_pddf_cpld_data, store_pddf_cpld_data, PDDF_USHORT, sizeof(unsigned short), (void*)&pddf_cpld_data.reg_addr, NULL); + + + +static struct attribute *cpld_attributes[] = { + &attr_dev_ops.dev_attr.attr, + &attr_reg_addr.dev_attr.attr, + NULL +}; + +static const struct attribute_group pddf_cpld_client_data_group = { + .attrs = cpld_attributes, +}; + + +static ssize_t store_pddf_cpld_data(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int ret = 0; + int num = 0; + PDDF_ATTR *ptr = (PDDF_ATTR *)da; + + ret = kstrtoint(buf,16,&num); + if (ret==0) + { + mutex_lock(&pddf_cpld_data.cpld_lock); + *(unsigned short *)(ptr->addr) = (unsigned short)num; + mutex_unlock(&pddf_cpld_data.cpld_lock); + pddf_dbg(CPLD, KERN_ERR "Stored value: 0x%x, num: 0x%x\n", *(int*)(ptr->addr), num); + } + + return count; +} +EXPORT_SYMBOL(store_pddf_cpld_data); + +ssize_t show_pddf_cpld_data(struct device *dev, struct device_attribute *da, char *buf) +{ + int ret = 0; + PDDF_ATTR *ptr = (PDDF_ATTR *)da; + pddf_dbg(CPLD, KERN_ERR "[ READ ] DATA ATTR PTR TYPE:%d, ADDR=%p\n", ptr->type, ptr->addr); + + mutex_lock(&pddf_cpld_data.cpld_lock); + ret = sprintf(buf, "0x%x\n", *(unsigned short *)(ptr->addr)); + mutex_unlock(&pddf_cpld_data.cpld_lock); + + return ret; +} +EXPORT_SYMBOL(show_pddf_cpld_data); + +static ssize_t do_device_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + PDDF_ATTR *ptr = (PDDF_ATTR *)da; + NEW_DEV_ATTR *device_ptr = (NEW_DEV_ATTR *)(ptr->data); + struct i2c_adapter *adapter; + static struct i2c_board_info board_info; + struct i2c_client *client_ptr; + + if (strncmp(buf, "add", strlen(buf)-1)==0) + { + adapter = i2c_get_adapter(device_ptr->parent_bus); + + if (strncmp(device_ptr->dev_type, "i2c_cpld", strlen("i2c_cpld"))==0) + { + board_info = (struct i2c_board_info) { + .platform_data = (void *)NULL, + }; + + board_info.addr = device_ptr->dev_addr; + strcpy(board_info.type, device_ptr->dev_type); + + /*pddf_dbg(KERN_ERR "Creating a client %s on 0x%x, platform_data 0x%x\n", board_info.type, board_info.addr, board_info.platform_data);*/ + client_ptr = i2c_new_device(adapter, &board_info); + + if (client_ptr != NULL) { + i2c_put_adapter(adapter); + pddf_dbg(CPLD, KERN_ERR "Created %s client: 0x%p\n", device_ptr->i2c_name, (void *)client_ptr); + add_device_table(device_ptr->i2c_name, (void*)client_ptr); + } + else { + i2c_put_adapter(adapter); + goto free_data; + } + + } + else + { + printk(KERN_ERR "%s: Unsupported type of cpld - unable to add i2c client\n", __FUNCTION__); + } + } + else if (strncmp(buf, "delete", strlen(buf)-1)==0) + { + /*Get the i2c_client handle for the created client*/ + client_ptr = (struct i2c_client *)get_device_table(device_ptr->i2c_name); + if (client_ptr) + { + pddf_dbg(CPLD, KERN_ERR "Removing %s client: 0x%p\n", device_ptr->i2c_name, (void *)client_ptr); + i2c_unregister_device(client_ptr); + delete_device_table(device_ptr->i2c_name); + } + else + { + printk(KERN_ERR "Unable to get the client handle for %s\n", device_ptr->i2c_name); + } + } + else + { + printk(KERN_ERR "PDDF_ERROR: %s: Invalid value for dev_ops %s", __FUNCTION__, buf); + } + +free_data: + /*TODO: free the device_ptr->data is dynamically allocated*/ + memset(device_ptr, 0 , sizeof(NEW_DEV_ATTR)); + + return count; +} + + +static struct kobject *cpld_kobj; + +int __init cpld_data_init(void) +{ + struct kobject *device_kobj; + int ret = 0; + + + pddf_dbg(CPLD, "CPLD_DATA MODULE.. init\n"); + + device_kobj = get_device_i2c_kobj(); + if(!device_kobj) + return -ENOMEM; + + cpld_kobj = kobject_create_and_add("cpld", device_kobj); + if(!cpld_kobj) + return -ENOMEM; + + + ret = sysfs_create_group(cpld_kobj, &pddf_clients_data_group); + if (ret) + { + kobject_put(cpld_kobj); + return ret; + } + pddf_dbg(CPLD, "CREATED PDDF I2C CLIENTS CREATION SYSFS GROUP\n"); + + mutex_init(&pddf_cpld_data.cpld_lock); + + ret = sysfs_create_group(cpld_kobj, &pddf_cpld_client_data_group); + if (ret) + { + sysfs_remove_group(cpld_kobj, &pddf_clients_data_group); + kobject_put(cpld_kobj); + return ret; + } + pddf_dbg(CPLD, "CREATED PDDF I2C CLIENTS CREATION SYSFS GROUP\n"); + return ret; +} + +void __exit cpld_data_exit(void) +{ + pddf_dbg(CPLD, "CPLD_DATA MODULE.. exit\n"); + sysfs_remove_group(cpld_kobj, &pddf_cpld_client_data_group); + sysfs_remove_group(cpld_kobj, &pddf_clients_data_group); + kobject_put(cpld_kobj); + pddf_dbg(CPLD, KERN_ERR "%s: Removed the kobjects for 'cpld'\n",__FUNCTION__); + return; +} + +module_init(cpld_data_init); +module_exit(cpld_data_exit); + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("cpld platform data"); +MODULE_LICENSE("GPL"); diff --git a/platform/pddf/i2c/modules/cpldmux/Makefile b/platform/pddf/i2c/modules/cpldmux/Makefile new file mode 100644 index 000000000000..53816b98f750 --- /dev/null +++ b/platform/pddf/i2c/modules/cpldmux/Makefile @@ -0,0 +1,4 @@ +subdir-m := driver +obj-m := pddf_cpldmux_module.o + +CFLAGS_$(obj-m):= -I$(M)/modules/include diff --git a/platform/pddf/i2c/modules/cpldmux/driver/Makefile b/platform/pddf/i2c/modules/cpldmux/driver/Makefile new file mode 100644 index 000000000000..2c6aa6e60eea --- /dev/null +++ b/platform/pddf/i2c/modules/cpldmux/driver/Makefile @@ -0,0 +1,4 @@ +TARGET = pddf_cpldmux_driver +obj-m := $(TARGET).o + +ccflags-y := -I$(M)/modules/include diff --git a/platform/pddf/i2c/modules/cpldmux/driver/pddf_cpldmux_driver.c b/platform/pddf/i2c/modules/cpldmux/driver/pddf_cpldmux_driver.c new file mode 100755 index 000000000000..c9df1a60c1af --- /dev/null +++ b/platform/pddf/i2c/modules/cpldmux/driver/pddf_cpldmux_driver.c @@ -0,0 +1,209 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A pddf kernel driver module for CPLDMUX + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "pddf_client_defs.h" +#include "pddf_cpldmux_defs.h" + +extern PDDF_CPLDMUX_DATA pddf_cpldmux_data; + +/* Users may overwrite these select and delsect functions as per their requirements + * by overwriting them in custom driver + */ +PDDF_CPLDMUX_OPS pddf_cpldmux_ops = { + .select = pddf_cpldmux_select_default, + .deselect = NULL, /* pddf_cpldmux_deselct_default */ +}; +EXPORT_SYMBOL(pddf_cpldmux_ops); + + +/* NOTE: Never use i2c_smbus_write_byte_data() or i2c_smbus_xfer() since these operations + * locks the parent bus which might lead to mutex deadlock. + */ +static int cpldmux_byte_write(struct i2c_client *client, u8 regaddr, u8 val) +{ + union i2c_smbus_data data; + + data.byte = val; + return client->adapter->algo->smbus_xfer(client->adapter, client->addr, + client->flags, + I2C_SMBUS_WRITE, + regaddr, I2C_SMBUS_BYTE_DATA, &data); +} + +int pddf_cpldmux_select_default(struct i2c_mux_core *muxc, uint32_t chan) +{ + PDDF_CPLDMUX_PRIV_DATA *private = i2c_mux_priv(muxc); + PDDF_CPLDMUX_PDATA *pdata = NULL; + PDDF_CPLDMUX_CHAN_DATA *sdata = NULL; + int ret = 0; + + /* Select the chan_data based upon the chan */ + pdata = &private->data; + if (chan>=pdata->num_chan) + { + printk(KERN_ERR "%s: wrong channel number %d, supported channels %d\n",__FUNCTION__, chan, pdata->num_chan); + return 0; + } + + if ( (pdata->chan_cache!=1) || (private->last_chan!=chan) ) + { + sdata = &pdata->chan_data[chan]; + pddf_dbg(CPLDMUX, KERN_ERR "%s: Writing 0x%x at 0x%x offset of cpld 0x%x to enable chan %d\n", __FUNCTION__, sdata->cpld_sel, sdata->cpld_offset, sdata->cpld_devaddr, chan); + ret = cpldmux_byte_write(pdata->cpld, sdata->cpld_offset, (uint8_t)(sdata->cpld_sel & 0xff)); + private->last_chan = chan; + } + + return ret; +} + +int pddf_cpldmux_deselect_default(struct i2c_mux_core *muxc, uint32_t chan) +{ + PDDF_CPLDMUX_PRIV_DATA *private = i2c_mux_priv(muxc); + PDDF_CPLDMUX_PDATA *pdata = NULL; + PDDF_CPLDMUX_CHAN_DATA *sdata = NULL; + int ret = 0; + + /* Select the chan_data based upon the chan */ + pdata = &private->data; + if (chan>=pdata->num_chan) + { + printk(KERN_ERR "%s: wrong channel number %d, supported channels %d\n",__FUNCTION__, chan, pdata->num_chan); + return 0; + } + sdata = &pdata->chan_data[chan]; + + pddf_dbg(CPLDMUX, KERN_ERR "%s: Writing 0x%x at 0x%x offset of cpld 0x%x to disable chan %d", __FUNCTION__, sdata->cpld_desel, sdata->cpld_offset, sdata->cpld_devaddr, chan); + ret = cpldmux_byte_write(pdata->cpld, sdata->cpld_offset, (uint8_t)(sdata->cpld_desel)); + return ret; +} + +static int cpld_mux_probe(struct platform_device *pdev) +{ + struct i2c_mux_core *muxc; + PDDF_CPLDMUX_PRIV_DATA *private; + PDDF_CPLDMUX_PDATA *pdata; + struct i2c_adapter *adap; + int i, ret, ndev; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "CPLDMUX platform data not found\n"); + return -ENODEV; + } + private = (PDDF_CPLDMUX_PRIV_DATA *)kzalloc(sizeof(PDDF_CPLDMUX_PRIV_DATA) , GFP_KERNEL); + if (!private) { + printk(KERN_ERR "Failed to allocate memory for priv data\n"); + return -ENOMEM; + } + + private->last_chan = 0xff; /*Giving imaginary high value so that proper channel is selected at first iteration*/ + memcpy(&private->data, pdata, sizeof(PDDF_CPLDMUX_PDATA)); + + adap = i2c_get_adapter(pdata->parent_bus); + if (!adap) { + kfree(private); + dev_err(&pdev->dev, "Parent adapter (%d) not found\n", pdata->parent_bus); + return -ENODEV; + } + ndev = pdata->num_chan; + + muxc = i2c_mux_alloc(adap, &pdev->dev, ndev, 0, 0, pddf_cpldmux_ops.select, pddf_cpldmux_ops.deselect); + if (!muxc) { + ret = -ENOMEM; + goto alloc_failed; + } + muxc->priv = private; + platform_set_drvdata(pdev, muxc); + + for (i = 0; i < ndev; i++) + { + int nr = pdata->base_chan + i; + unsigned int class = 0; + ret = i2c_mux_add_adapter(muxc, nr, i, class); + if (ret) { + dev_err(&pdev->dev, "Failed to add adapter %d\n", i); + goto add_adapter_failed; + } + } + dev_info(&pdev->dev, "%d port mux on %s adapter\n", ndev, adap->name); + return 0; + +add_adapter_failed: + i2c_mux_del_adapters(muxc); +alloc_failed: + kfree(private); + i2c_put_adapter(adap); + return ret; +} + +static int cpld_mux_remove(struct platform_device *pdev) +{ + struct i2c_mux_core *muxc = platform_get_drvdata(pdev); + struct i2c_adapter *adap = muxc->parent; + PDDF_CPLDMUX_PDATA *cpldmux_pdata = pdev->dev.platform_data; + + i2c_mux_del_adapters(muxc); + if (muxc->priv) + kfree(muxc->priv); + i2c_put_adapter(adap); + + if (cpldmux_pdata) { + pddf_dbg(CPLDMUX, KERN_DEBUG "%s: Freeing cpldmux platform data\n", __FUNCTION__); + kfree(cpldmux_pdata); + } + + return 0; +} + +static struct platform_driver cpld_mux_driver = { + .probe = cpld_mux_probe, + .remove = cpld_mux_remove, /* TODO */ + .driver = { + .owner = THIS_MODULE, + .name = "cpld_mux", + }, +}; + +static int __init board_i2c_cpldmux_init(void) +{ + int ret; + ret = platform_driver_register(&cpld_mux_driver); + if (ret) { + printk(KERN_WARNING "Fail to register swpld mux driver\n"); + } + return (ret); +} + +static void __exit board_i2c_cpldmux_exit(void) +{ + platform_driver_unregister(&cpld_mux_driver); +} + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("board_i2c_cpldmux driver"); +MODULE_LICENSE("GPL"); + +module_init(board_i2c_cpldmux_init); +module_exit(board_i2c_cpldmux_exit); diff --git a/platform/pddf/i2c/modules/cpldmux/pddf_cpldmux_module.c b/platform/pddf/i2c/modules/cpldmux/pddf_cpldmux_module.c new file mode 100644 index 000000000000..f99def315820 --- /dev/null +++ b/platform/pddf/i2c/modules/cpldmux/pddf_cpldmux_module.c @@ -0,0 +1,254 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * PDDF generic module for cpldmux device + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pddf_client_defs.h" +#include "pddf_cpldmux_defs.h" + +PDDF_CPLDMUX_DATA pddf_cpldmux_data={0}; +PDDF_CPLDMUX_CHAN_DATA pddf_cpldmux_chan_data={0}; +EXPORT_SYMBOL(pddf_cpldmux_data); + +static ssize_t do_device_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t do_chan_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count); + +extern void *get_device_table(char *name); +extern void delete_device_table(char *name); + + +/* CPLDMUX CLIENT DATA */ +PDDF_DATA_ATTR(dev_ops, S_IWUSR, NULL, do_device_operation, PDDF_CHAR, 8, (void*)&pddf_cpldmux_data, (void*)&pddf_data); +PDDF_DATA_ATTR(chan_ops, S_IWUSR, NULL, do_chan_operation, PDDF_CHAR, 8, (void*)&pddf_cpldmux_data, NULL); +PDDF_DATA_ATTR(base_chan, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_HEX, sizeof(int), (void*)&pddf_cpldmux_data.base_chan, NULL); +PDDF_DATA_ATTR(num_chan, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_DEC, sizeof(int), (void*)&pddf_cpldmux_data.num_chan, NULL); +PDDF_DATA_ATTR(chan_cache, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_DEC, sizeof(int), (void*)&pddf_cpldmux_data.chan_cache, NULL); +PDDF_DATA_ATTR(cpld_name, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_CHAR, 32, (void*)&pddf_cpldmux_data.cpld_name, NULL); +PDDF_DATA_ATTR(chan, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_DEC, sizeof(int), (void*)&pddf_cpldmux_chan_data.chan_num, NULL); +PDDF_DATA_ATTR(dev, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_CHAR, 128, (void*)&pddf_cpldmux_chan_data.chan_device, NULL); +PDDF_DATA_ATTR(cpld_devaddr, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_HEX, sizeof(int), (void*)&pddf_cpldmux_chan_data.cpld_devaddr, NULL); +PDDF_DATA_ATTR(cpld_offset, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_HEX, sizeof(int), (void*)&pddf_cpldmux_chan_data.cpld_offset, NULL); +PDDF_DATA_ATTR(cpld_sel, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_HEX, sizeof(int), (void*)&pddf_cpldmux_chan_data.cpld_sel, NULL); +PDDF_DATA_ATTR(cpld_desel, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_HEX, sizeof(int), (void*)&pddf_cpldmux_chan_data.cpld_desel, NULL); + + +static struct attribute *cpldmux_attributes[] = { + &attr_dev_ops.dev_attr.attr, + &attr_chan_ops.dev_attr.attr, + &attr_base_chan.dev_attr.attr, + &attr_num_chan.dev_attr.attr, + &attr_chan_cache.dev_attr.attr, + &attr_cpld_name.dev_attr.attr, + &attr_chan.dev_attr.attr, + &attr_dev.dev_attr.attr, + &attr_cpld_devaddr.dev_attr.attr, + &attr_cpld_offset.dev_attr.attr, + &attr_cpld_sel.dev_attr.attr, + &attr_cpld_desel.dev_attr.attr, + NULL +}; + +static const struct attribute_group pddf_cpldmux_client_data_group = { + .attrs = cpldmux_attributes, +}; + + + +static ssize_t do_chan_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + PDDF_ATTR *ptr = (PDDF_ATTR *)da; + PDDF_CPLDMUX_DATA *cpldmux_data = (PDDF_CPLDMUX_DATA *)(ptr->addr); + int index; + + pddf_dbg(CPLDMUX, KERN_ERR "%s: Adding channel %d\n", __FUNCTION__, pddf_cpldmux_chan_data.chan_num); + index = pddf_cpldmux_chan_data.chan_num; + cpldmux_data->chan_data[index] = pddf_cpldmux_chan_data; + + memset(&pddf_cpldmux_chan_data, 0, sizeof(pddf_cpldmux_chan_data)); + + + return count; +} + +static ssize_t do_device_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + PDDF_ATTR *ptr = (PDDF_ATTR *)da; + NEW_DEV_ATTR *device_ptr = (NEW_DEV_ATTR *)(ptr->data); + PDDF_CPLDMUX_DATA *cpldmux_data = (PDDF_CPLDMUX_DATA *)(ptr->addr); + PDDF_CPLDMUX_PDATA *cpldmux_platform_data = NULL; + struct platform_device *plat_dev = NULL; + struct i2c_client *client_ptr = NULL; + int ret=0, i=0; + + if (strncmp(buf, "add", strlen(buf)-1)==0) + { + if (strncmp(device_ptr->dev_type, "cpld_mux", strlen("cpld_mux"))==0) + { + /*Get the i2c_client handle for the CPLD which drives this cpldmux*/ + client_ptr = (struct i2c_client *)get_device_table(cpldmux_data->cpld_name); + if (client_ptr==NULL) + { + pddf_dbg(CPLDMUX, KERN_ERR "Unable to get the CPLD client %s for %s cpldmux\n", cpldmux_data->cpld_name, device_ptr->i2c_name); + printk(KERN_ERR "Unable to get the CPLD client %s for %s cpldmux\n", cpldmux_data->cpld_name, device_ptr->i2c_name); + goto clear_data; + } + + /* Allocate the cpldmux_platform_data */ + cpldmux_platform_data = (PDDF_CPLDMUX_PDATA *)kzalloc( sizeof(PDDF_CPLDMUX_PDATA) + cpldmux_data->num_chan*sizeof(PDDF_CPLDMUX_CHAN_DATA), GFP_KERNEL ); + cpldmux_platform_data->chan_data = (PDDF_CPLDMUX_CHAN_DATA *)(cpldmux_platform_data+1); + + cpldmux_platform_data->parent_bus = device_ptr->parent_bus; + cpldmux_platform_data->base_chan = cpldmux_data->base_chan; + cpldmux_platform_data->num_chan = cpldmux_data->num_chan; + cpldmux_platform_data->chan_cache = cpldmux_data->chan_cache; + cpldmux_platform_data->cpld = client_ptr; + for (i=0; inum_chan; i++) + { + cpldmux_platform_data->chan_data[i] = cpldmux_data->chan_data[i]; + } + + plat_dev = platform_device_alloc(device_ptr->dev_type, device_ptr->dev_id); + + plat_dev->dev.platform_data = cpldmux_platform_data; + + pddf_dbg(CPLDMUX, KERN_ERR "Creating a %s platform_device 0x%p, platform_data 0x%p\n", plat_dev->name, (void *)plat_dev, (void *)cpldmux_platform_data); + ret = platform_device_add(plat_dev); + if (ret) + { + pddf_dbg(CPLDMUX, KERN_ERR "Unable to create cpld_mux (%s) device: Error %d\n", device_ptr->i2c_name, ret); + goto free_data; + } + else + { + add_device_table(device_ptr->i2c_name, (void *)plat_dev); + } + + } + else + { + printk(KERN_ERR "%s: Unsupported type of cpldmux - unable to add i2c client\n", __FUNCTION__); + } + } + else if (strncmp(buf, "delete", strlen(buf)-1)==0) + { + /*Get the i2c_client handle for the created client*/ + plat_dev = (struct platform_device *)get_device_table(device_ptr->i2c_name); + if (plat_dev) + { + pddf_dbg(CPLDMUX, KERN_ERR "Removing %s device: 0x%p\n", device_ptr->i2c_name, (void *)plat_dev); + pddf_dbg(CPLDMUX, KERN_ERR "Freeing the memory held by device: 0x%p\n", (void *)plat_dev); + platform_device_del(plat_dev); + delete_device_table(device_ptr->i2c_name); + } + else + { + printk(KERN_ERR "Unable to get the client handle for %s\n", device_ptr->i2c_name); + } + } + else + { + printk(KERN_ERR "PDDF_ERROR: %s: Invalid value for dev_ops %s", __FUNCTION__, buf); + } + goto clear_data; + +free_data: + /* Free the allocated memory for platform and channel data */ + cpldmux_platform_data = plat_dev->dev.platform_data; + if (cpldmux_platform_data) + { + printk(KERN_ERR "%s: Unable to register a cpldmux device. Freeing the platform data\n", __FUNCTION__); + kfree(cpldmux_platform_data); + } + + /* Put the platform device structure */ + platform_device_put(plat_dev); +clear_data: + memset(cpldmux_data, 0, sizeof(PDDF_CPLDMUX_DATA)); + /*TODO: free the data device_ptr->data if data is dynamically allocated*/ + memset(device_ptr, 0, sizeof(NEW_DEV_ATTR)); + return count; +} + + +static struct kobject *cpldmux_kobj; + +int __init cpldmux_data_init(void) +{ + struct kobject *device_kobj; + int ret = 0; + + + pddf_dbg(CPLDMUX, "CPLDMUX_DATA MODULE.. init\n"); + + device_kobj = get_device_i2c_kobj(); + if(!device_kobj) + return -ENOMEM; + + cpldmux_kobj = kobject_create_and_add("cpldmux", device_kobj); + if(!cpldmux_kobj) + return -ENOMEM; + + + ret = sysfs_create_group(cpldmux_kobj, &pddf_clients_data_group); + if (ret) + { + kobject_put(cpldmux_kobj); + return ret; + } + pddf_dbg(CPLDMUX, "CREATED PDDF I2C CLIENTS CREATION SYSFS GROUP\n"); + + + ret = sysfs_create_group(cpldmux_kobj, &pddf_cpldmux_client_data_group); + if (ret) + { + sysfs_remove_group(cpldmux_kobj, &pddf_clients_data_group); + kobject_put(cpldmux_kobj); + return ret; + } + pddf_dbg(CPLDMUX, "CREATED PDDF I2C CLIENTS CREATION SYSFS GROUP\n"); + return ret; +} + +void __exit cpldmux_data_exit(void) +{ + pddf_dbg(CPLDMUX, "CPLDMUX_DATA MODULE.. exit\n"); + sysfs_remove_group(cpldmux_kobj, &pddf_cpldmux_client_data_group); + sysfs_remove_group(cpldmux_kobj, &pddf_clients_data_group); + kobject_put(cpldmux_kobj); + pddf_dbg(CPLDMUX, KERN_ERR "%s: Removed the kobjects for 'cpldmux'\n",__FUNCTION__); + return; +} + +module_init(cpldmux_data_init); +module_exit(cpldmux_data_exit); + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("cpldmux platform data"); +MODULE_LICENSE("GPL"); diff --git a/platform/pddf/i2c/modules/fan/Makefile b/platform/pddf/i2c/modules/fan/Makefile new file mode 100644 index 000000000000..94b6b146c51d --- /dev/null +++ b/platform/pddf/i2c/modules/fan/Makefile @@ -0,0 +1,4 @@ +subdir-m := driver +obj-m := pddf_fan_module.o + +CFLAGS_$(obj-m):= -I$(M)/modules/include diff --git a/platform/pddf/i2c/modules/fan/driver/Makefile b/platform/pddf/i2c/modules/fan/driver/Makefile new file mode 100644 index 000000000000..c94f217d3bab --- /dev/null +++ b/platform/pddf/i2c/modules/fan/driver/Makefile @@ -0,0 +1,6 @@ +TARGET := pddf_fan_driver_module +obj-m := $(TARGET).o + +$(TARGET)-objs := pddf_fan_api.o pddf_fan_driver.o + +ccflags-y := -I$(M)/modules/include diff --git a/platform/pddf/i2c/modules/fan/driver/pddf_fan_api.c b/platform/pddf/i2c/modules/fan/driver/pddf_fan_api.c new file mode 100644 index 000000000000..167b0e183315 --- /dev/null +++ b/platform/pddf/i2c/modules/fan/driver/pddf_fan_api.c @@ -0,0 +1,526 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description of various APIs related to FAN component + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pddf_fan_defs.h" +#include "pddf_fan_driver.h" + +/*#define FAN_DEBUG*/ +#ifdef FAN_DEBUG +#define fan_dbg(...) printk(__VA_ARGS__) +#else +#define fan_dbg(...) +#endif + +extern void *get_device_table(char *name); + +void get_fan_duplicate_sysfs(int idx, char *str) +{ + switch (idx) + { + default: + break; + } + + return; +} + + +int fan_update_hw(struct device *dev, struct fan_attr_info *info, FAN_DATA_ATTR *udata) +{ + int status = 0; + struct i2c_client *client = to_i2c_client(dev); + FAN_SYSFS_ATTR_DATA *sysfs_attr_data = NULL; + + + mutex_lock(&info->update_lock); + + sysfs_attr_data = udata->access_data; + if (sysfs_attr_data->pre_set != NULL) + { + status = (sysfs_attr_data->pre_set)(client, udata, info); + if (status!=0) + printk(KERN_ERR "%s: pre_set function fails for %s attribute\n", __FUNCTION__, udata->aname); + } + if (sysfs_attr_data->do_set != NULL) + { + status = (sysfs_attr_data->do_set)(client, udata, info); + if (status!=0) + printk(KERN_ERR "%s: do_set function fails for %s attribute\n", __FUNCTION__, udata->aname); + + } + if (sysfs_attr_data->post_set != NULL) + { + status = (sysfs_attr_data->post_set)(client, udata, info); + if (status!=0) + printk(KERN_ERR "%s: post_set function fails for %s attribute\n", __FUNCTION__, udata->aname); + } + + mutex_unlock(&info->update_lock); + + return 0; +} + +int fan_update_attr(struct device *dev, struct fan_attr_info *info, FAN_DATA_ATTR *udata) +{ + int status = 0; + struct i2c_client *client = to_i2c_client(dev); + FAN_SYSFS_ATTR_DATA *sysfs_attr_data = NULL; + + + mutex_lock(&info->update_lock); + + if (time_after(jiffies, info->last_updated + HZ + HZ / 2) || !info->valid) + { + dev_dbg(&client->dev, "Starting pddf_fan update\n"); + info->valid = 0; + + sysfs_attr_data = udata->access_data; + if (sysfs_attr_data->pre_get != NULL) + { + status = (sysfs_attr_data->pre_get)(client, udata, info); + if (status!=0) + printk(KERN_ERR "%s: pre_get function fails for %s attribute\n", __FUNCTION__, udata->aname); + } + if (sysfs_attr_data->do_get != NULL) + { + status = (sysfs_attr_data->do_get)(client, udata, info); + if (status!=0) + printk(KERN_ERR "%s: do_get function fails for %s attribute\n", __FUNCTION__, udata->aname); + + } + if (sysfs_attr_data->post_get != NULL) + { + status = (sysfs_attr_data->post_get)(client, udata, info); + if (status!=0) + printk(KERN_ERR "%s: post_get function fails for %s attribute\n", __FUNCTION__, udata->aname); + } + + + info->last_updated = jiffies; + info->valid = 1; + } + + mutex_unlock(&info->update_lock); + + return 0; +} + +ssize_t fan_show_default(struct device *dev, struct device_attribute *da, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct fan_data *data = i2c_get_clientdata(client); + FAN_PDATA *pdata = (FAN_PDATA *)(client->dev.platform_data); + FAN_DATA_ATTR *usr_data = NULL; + struct fan_attr_info *attr_info = NULL; + int i, status=0; + char new_str[ATTR_NAME_LEN] = ""; + FAN_SYSFS_ATTR_DATA *ptr = NULL; + + for (i=0;inum_attr;i++) + { + ptr = (FAN_SYSFS_ATTR_DATA *)pdata->fan_attrs[i].access_data; + get_fan_duplicate_sysfs(ptr->index , new_str); + if (strcmp(attr->dev_attr.attr.name, pdata->fan_attrs[i].aname) == 0 || strcmp(attr->dev_attr.attr.name, new_str) == 0) + { + attr_info = &data->attr_info[i]; + usr_data = &pdata->fan_attrs[i]; + strcpy(new_str, ""); + } + } + + if (attr_info==NULL || usr_data==NULL) + { + printk(KERN_ERR "%s is not supported attribute for this client\n", usr_data->aname); + goto exit; + } + + fan_update_attr(dev, attr_info, usr_data); + + /*Decide the o/p based on attribute type */ + switch(attr->index) + { + case FAN1_PRESENT: + case FAN2_PRESENT: + case FAN3_PRESENT: + case FAN4_PRESENT: + case FAN5_PRESENT: + case FAN6_PRESENT: + case FAN7_PRESENT: + case FAN8_PRESENT: + case FAN9_PRESENT: + case FAN10_PRESENT: + case FAN11_PRESENT: + case FAN12_PRESENT: + case FAN1_DIRECTION: + case FAN2_DIRECTION: + case FAN3_DIRECTION: + case FAN4_DIRECTION: + case FAN5_DIRECTION: + case FAN6_DIRECTION: + case FAN7_DIRECTION: + case FAN8_DIRECTION: + case FAN9_DIRECTION: + case FAN10_DIRECTION: + case FAN11_DIRECTION: + case FAN12_DIRECTION: + case FAN1_INPUT: + case FAN2_INPUT: + case FAN3_INPUT: + case FAN4_INPUT: + case FAN5_INPUT: + case FAN6_INPUT: + case FAN7_INPUT: + case FAN8_INPUT: + case FAN9_INPUT: + case FAN10_INPUT: + case FAN11_INPUT: + case FAN12_INPUT: + case FAN1_PWM: + case FAN2_PWM: + case FAN3_PWM: + case FAN4_PWM: + case FAN5_PWM: + case FAN6_PWM: + case FAN7_PWM: + case FAN8_PWM: + case FAN9_PWM: + case FAN10_PWM: + case FAN11_PWM: + case FAN12_PWM: + case FAN1_FAULT: + case FAN2_FAULT: + case FAN3_FAULT: + case FAN4_FAULT: + case FAN5_FAULT: + case FAN6_FAULT: + case FAN7_FAULT: + case FAN8_FAULT: + case FAN9_FAULT: + case FAN10_FAULT: + case FAN11_FAULT: + case FAN12_FAULT: + status = attr_info->val.intval; + break; + default: + fan_dbg(KERN_ERR "%s: Unable to find the attribute index for %s\n", __FUNCTION__, usr_data->aname); + status = 0; + } + +exit: + return sprintf(buf, "%d\n", status); +} + + +ssize_t fan_store_default(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct fan_data *data = i2c_get_clientdata(client); + FAN_PDATA *pdata = (FAN_PDATA *)(client->dev.platform_data); + FAN_DATA_ATTR *usr_data = NULL; + struct fan_attr_info *attr_info = NULL; + int i, ret ; + uint32_t val; + + for (i=0;inum_attr;i++) + { + if (strcmp(data->attr_info[i].name, attr->dev_attr.attr.name) == 0 && strcmp(pdata->fan_attrs[i].aname, attr->dev_attr.attr.name) == 0) + { + attr_info = &data->attr_info[i]; + usr_data = &pdata->fan_attrs[i]; + } + } + + if (attr_info==NULL || usr_data==NULL) { + printk(KERN_ERR "%s is not supported attribute for this client\n", attr->dev_attr.attr.name); + goto exit; + } + + switch(attr->index) + { + case FAN1_PWM: + case FAN2_PWM: + case FAN3_PWM: + case FAN4_PWM: + case FAN5_PWM: + case FAN6_PWM: + case FAN7_PWM: + case FAN8_PWM: + case FAN9_PWM: + case FAN10_PWM: + case FAN11_PWM: + case FAN12_PWM: + ret = kstrtoint(buf, 10, &val); + if (ret) + { + printk(KERN_ERR "%s: Unable to convert string into value for %s\n", __FUNCTION__, usr_data->aname); + return ret; + } + /*Update the value of attr_info here, and use it to update the HW values*/ + attr_info->val.intval = val; + break; + default: + printk(KERN_ERR "%s: Unable to find the attr index for %s\n", __FUNCTION__, usr_data->aname); + goto exit; + } + + fan_dbg(KERN_ERR "%s: pwm to be set is %d\n", __FUNCTION__, val); + fan_update_hw(dev, attr_info, usr_data); + +exit: + return count; +} + +int fan_cpld_client_read(FAN_DATA_ATTR *udata) +{ + int status = -1; + + if (udata!=NULL) + { + if (udata->len==1) + { + status = board_i2c_cpld_read(udata->devaddr , udata->offset); + } + else + { + /* Get the I2C client for the CPLD */ + struct i2c_client *client_ptr=NULL; + client_ptr = (struct i2c_client *)get_device_table(udata->devname); + if (client_ptr) + { + if (udata->len==2) + { + status = i2c_smbus_read_word_swapped(client_ptr, udata->offset); + } + else + printk(KERN_ERR "PDDF_FAN: Doesn't support block CPLD read yet"); + } + else + printk(KERN_ERR "Unable to get the client handle for %s\n", udata->devname); + } + + } + + return status; +} + + +int sonic_i2c_get_fan_present_default(void *client, FAN_DATA_ATTR *udata, void *info) +{ + int status = 0; + int val = 0; + struct fan_attr_info *painfo = (struct fan_attr_info *)info; + + if (strcmp(udata->devtype, "cpld") == 0) + { + val = fan_cpld_client_read(udata); + } + else + { + val = i2c_smbus_read_byte_data((struct i2c_client *)client, udata->offset); + } + + painfo->val.intval = ((val & udata->mask) == udata->cmpval); + + + return status; +} + +int sonic_i2c_get_fan_rpm_default(void *client, FAN_DATA_ATTR *udata, void *info) +{ + int status = 0; + uint32_t val = 0; + struct fan_attr_info *painfo = (struct fan_attr_info *)info; + + if (strcmp(udata->devtype, "cpld") == 0) + { + val = fan_cpld_client_read(udata); + } + else + { + if (udata->len == 1) + { + val = i2c_smbus_read_byte_data((struct i2c_client *)client, udata->offset); + } + else if (udata->len ==2) + { + val = i2c_smbus_read_word_swapped((struct i2c_client *)client, udata->offset); + + } + } + + if (udata->is_divisor) + painfo->val.intval = udata->mult / (val >> 3); + else + painfo->val.intval = udata->mult * val; + + return status; +} + + +int sonic_i2c_get_fan_direction_default(void *client, FAN_DATA_ATTR *udata, void *info) +{ + int status = 0; + uint32_t val = 0; + struct fan_attr_info *painfo = (struct fan_attr_info *)info; + + if (strcmp(udata->devtype, "cpld") == 0) + { + val = fan_cpld_client_read(udata); + } + else + { + val = i2c_smbus_read_byte_data((struct i2c_client *)client, udata->offset); + } + painfo->val.intval = ((val & udata->mask) == udata->cmpval); + + return status; +} + + +int sonic_i2c_set_fan_pwm_default(struct i2c_client *client, FAN_DATA_ATTR *udata, void *info) +{ + int status = 0; + uint32_t val = 0; + struct fan_attr_info *painfo = (struct fan_attr_info *)info; + + val = painfo->val.intval & udata->mask; + + if (val > 255) + { + return -EINVAL; + } + + if (strcmp(udata->devtype, "cpld") == 0) + { + if (udata->len==1) + { + status = board_i2c_cpld_write(udata->devaddr , udata->offset, val); + } + else + { + /* Get the I2C client for the CPLD */ + struct i2c_client *client_ptr=NULL; + client_ptr = (struct i2c_client *)get_device_table(udata->devname); + if (client_ptr) + { + if (udata->len==2) + { + uint8_t val_lsb = val & 0xFF; + uint8_t val_hsb = (val >> 8) & 0xFF; + /* TODO: Check this logic for LE and BE */ + i2c_smbus_write_byte_data(client, udata->offset, val_lsb); + i2c_smbus_write_byte_data(client, udata->offset+1, val_hsb); + } + else + printk(KERN_ERR "PDDF_FAN: Doesn't support block CPLD write yet"); + } + else + printk(KERN_ERR "Unable to get the client handle for %s\n", udata->devname); + } + + } + else + { + if (udata->len == 1) + i2c_smbus_write_byte_data(client, udata->offset, val); + else if (udata->len == 2) + { + uint8_t val_lsb = val & 0xFF; + uint8_t val_hsb = (val >> 8) & 0xFF; + /* TODO: Check this logic for LE and BE */ + i2c_smbus_write_byte_data(client, udata->offset, val_lsb); + i2c_smbus_write_byte_data(client, udata->offset+1, val_hsb); + } + else + { + printk(KERN_DEBUG "%s: pwm should be of len 1/2 bytes. Not setting the pwm as the length is %d\n", __FUNCTION__, udata->len); + } + } + + return status; +} + + +int sonic_i2c_get_fan_pwm_default(void *client, FAN_DATA_ATTR *udata, void *info) +{ + int status = 0; + uint32_t val = 0; + struct fan_attr_info *painfo = (struct fan_attr_info *)info; + + if (strcmp(udata->devtype, "cpld") == 0) + { + val = fan_cpld_client_read(udata); + } + else + { + if (udata->len == 1) + { + val = i2c_smbus_read_byte_data((struct i2c_client *)client, udata->offset); + } + else if (udata->len ==2) + { + val = i2c_smbus_read_word_swapped((struct i2c_client *)client, udata->offset); + + } + } + + val = val & udata->mask; + painfo->val.intval = val; + return status; +} + +int sonic_i2c_get_fan_fault_default(void *client, FAN_DATA_ATTR *udata, void *info) +{ + int status = 0; + uint32_t val = 0; + struct fan_attr_info *painfo = (struct fan_attr_info *)info; + + /*Assuming fan fault to be denoted by 1 byte only*/ + if (strcmp(udata->devtype, "cpld") == 0) + { + val = fan_cpld_client_read(udata); + } + else + { + val = i2c_smbus_read_byte_data((struct i2c_client *)client, udata->offset); + } + + val = val & udata->mask; + painfo->val.intval = val; + return status; +} + + +int pddf_fan_post_probe_default(struct i2c_client *client, const struct i2c_device_id *dev_id) +{ + + /*Dummy func for now - check the respective platform modules*/ + return 0; +} diff --git a/platform/pddf/i2c/modules/fan/driver/pddf_fan_driver.c b/platform/pddf/i2c/modules/fan/driver/pddf_fan_driver.c new file mode 100644 index 000000000000..da8275fccd64 --- /dev/null +++ b/platform/pddf/i2c/modules/fan/driver/pddf_fan_driver.c @@ -0,0 +1,496 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * A pddf kernel driver module for a FAN controller + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pddf_client_defs.h" +#include "pddf_fan_defs.h" +#include "pddf_fan_driver.h" +#include "pddf_fan_api.h" + +#define DRVNAME "pddf_fan" + +struct pddf_ops_t pddf_fan_ops = { + .pre_init = NULL, + .post_init = NULL, + + .pre_probe = NULL, + .post_probe = pddf_fan_post_probe_default, + + .pre_remove = NULL, + .post_remove = NULL, + + .pre_exit = NULL, + .post_exit = NULL, +}; +EXPORT_SYMBOL(pddf_fan_ops); + + + +FAN_SYSFS_ATTR_DATA data_fan1_present = {FAN1_PRESENT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_present_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan1_present); +FAN_SYSFS_ATTR_DATA data_fan2_present = {FAN2_PRESENT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_present_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan2_present); +FAN_SYSFS_ATTR_DATA data_fan3_present = {FAN3_PRESENT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_present_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan3_present); +FAN_SYSFS_ATTR_DATA data_fan4_present = {FAN4_PRESENT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_present_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan4_present); +FAN_SYSFS_ATTR_DATA data_fan5_present = {FAN5_PRESENT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_present_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan5_present); +FAN_SYSFS_ATTR_DATA data_fan6_present = {FAN6_PRESENT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_present_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan6_present); +FAN_SYSFS_ATTR_DATA data_fan7_present = {FAN7_PRESENT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_present_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan7_present); +FAN_SYSFS_ATTR_DATA data_fan8_present = {FAN8_PRESENT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_present_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan8_present); +FAN_SYSFS_ATTR_DATA data_fan9_present = {FAN9_PRESENT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_present_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan9_present); +FAN_SYSFS_ATTR_DATA data_fan10_present = {FAN10_PRESENT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_present_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan10_present); +FAN_SYSFS_ATTR_DATA data_fan11_present = {FAN11_PRESENT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_present_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan11_present); +FAN_SYSFS_ATTR_DATA data_fan12_present = {FAN12_PRESENT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_present_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan12_present); + + +FAN_SYSFS_ATTR_DATA data_fan1_direction = {FAN1_DIRECTION, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_direction_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan1_direction); +FAN_SYSFS_ATTR_DATA data_fan2_direction = {FAN2_DIRECTION, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_direction_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan2_direction); +FAN_SYSFS_ATTR_DATA data_fan3_direction = {FAN3_DIRECTION, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_direction_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan3_direction); +FAN_SYSFS_ATTR_DATA data_fan4_direction = {FAN4_DIRECTION, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_direction_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan4_direction); +FAN_SYSFS_ATTR_DATA data_fan5_direction = {FAN5_DIRECTION, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_direction_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan5_direction); +FAN_SYSFS_ATTR_DATA data_fan6_direction = {FAN6_DIRECTION, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_direction_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan6_direction); +FAN_SYSFS_ATTR_DATA data_fan7_direction = {FAN7_DIRECTION, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_direction_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan7_direction); +FAN_SYSFS_ATTR_DATA data_fan8_direction = {FAN8_DIRECTION, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_direction_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan8_direction); +FAN_SYSFS_ATTR_DATA data_fan9_direction = {FAN9_DIRECTION, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_direction_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan9_direction); +FAN_SYSFS_ATTR_DATA data_fan10_direction = {FAN10_DIRECTION, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_direction_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan10_direction); +FAN_SYSFS_ATTR_DATA data_fan11_direction = {FAN11_DIRECTION, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_direction_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan11_direction); +FAN_SYSFS_ATTR_DATA data_fan12_direction = {FAN12_DIRECTION, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_direction_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan12_direction); + + +FAN_SYSFS_ATTR_DATA data_fan1_input = {FAN1_INPUT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_rpm_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan1_input); +FAN_SYSFS_ATTR_DATA data_fan2_input = {FAN2_INPUT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_rpm_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan2_input); +FAN_SYSFS_ATTR_DATA data_fan3_input = {FAN3_INPUT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_rpm_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan3_input); +FAN_SYSFS_ATTR_DATA data_fan4_input = {FAN4_INPUT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_rpm_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan4_input); +FAN_SYSFS_ATTR_DATA data_fan5_input = {FAN5_INPUT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_rpm_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan5_input); +FAN_SYSFS_ATTR_DATA data_fan6_input = {FAN6_INPUT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_rpm_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan6_input); +FAN_SYSFS_ATTR_DATA data_fan7_input = {FAN7_INPUT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_rpm_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan7_input); +FAN_SYSFS_ATTR_DATA data_fan8_input = {FAN8_INPUT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_rpm_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan8_input); +FAN_SYSFS_ATTR_DATA data_fan9_input = {FAN9_INPUT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_rpm_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan9_input); +FAN_SYSFS_ATTR_DATA data_fan10_input = {FAN10_INPUT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_rpm_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan10_input); +FAN_SYSFS_ATTR_DATA data_fan11_input = {FAN11_INPUT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_rpm_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan11_input); +FAN_SYSFS_ATTR_DATA data_fan12_input = {FAN12_INPUT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_rpm_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan12_input); + + +FAN_SYSFS_ATTR_DATA data_fan1_pwm = {FAN1_PWM, S_IRUGO | S_IWUSR, fan_show_default, NULL, sonic_i2c_get_fan_pwm_default, NULL, fan_store_default, NULL, sonic_i2c_set_fan_pwm_default, NULL, NULL}; +EXPORT_SYMBOL(data_fan1_pwm); +FAN_SYSFS_ATTR_DATA data_fan2_pwm = {FAN2_PWM, S_IRUGO | S_IWUSR, fan_show_default, NULL, sonic_i2c_get_fan_pwm_default, NULL, fan_store_default, NULL, sonic_i2c_set_fan_pwm_default, NULL, NULL}; +EXPORT_SYMBOL(data_fan2_pwm); +FAN_SYSFS_ATTR_DATA data_fan3_pwm = {FAN3_PWM, S_IRUGO | S_IWUSR, fan_show_default, NULL, sonic_i2c_get_fan_pwm_default, NULL, fan_store_default, NULL, sonic_i2c_set_fan_pwm_default, NULL, NULL}; +EXPORT_SYMBOL(data_fan3_pwm); +FAN_SYSFS_ATTR_DATA data_fan4_pwm = {FAN4_PWM, S_IRUGO | S_IWUSR, fan_show_default, NULL, sonic_i2c_get_fan_pwm_default, NULL, fan_store_default, NULL, sonic_i2c_set_fan_pwm_default, NULL, NULL}; +EXPORT_SYMBOL(data_fan4_pwm); +FAN_SYSFS_ATTR_DATA data_fan5_pwm = {FAN5_PWM, S_IRUGO | S_IWUSR, fan_show_default, NULL, sonic_i2c_get_fan_pwm_default, NULL, fan_store_default, NULL, sonic_i2c_set_fan_pwm_default, NULL, NULL}; +EXPORT_SYMBOL(data_fan5_pwm); +FAN_SYSFS_ATTR_DATA data_fan6_pwm = {FAN6_PWM, S_IRUGO | S_IWUSR, fan_show_default, NULL, sonic_i2c_get_fan_pwm_default, NULL, fan_store_default, NULL, sonic_i2c_set_fan_pwm_default, NULL, NULL}; +EXPORT_SYMBOL(data_fan6_pwm); +FAN_SYSFS_ATTR_DATA data_fan7_pwm = {FAN7_PWM, S_IRUGO | S_IWUSR, fan_show_default, NULL, sonic_i2c_get_fan_pwm_default, NULL, fan_store_default, NULL, sonic_i2c_set_fan_pwm_default, NULL, NULL}; +EXPORT_SYMBOL(data_fan7_pwm); +FAN_SYSFS_ATTR_DATA data_fan8_pwm = {FAN8_PWM, S_IRUGO | S_IWUSR, fan_show_default, NULL, sonic_i2c_get_fan_pwm_default, NULL, fan_store_default, NULL, sonic_i2c_set_fan_pwm_default, NULL, NULL}; +EXPORT_SYMBOL(data_fan8_pwm); +FAN_SYSFS_ATTR_DATA data_fan9_pwm = {FAN9_PWM, S_IRUGO | S_IWUSR, fan_show_default, NULL, sonic_i2c_get_fan_pwm_default, NULL, fan_store_default, NULL, sonic_i2c_set_fan_pwm_default, NULL, NULL}; +EXPORT_SYMBOL(data_fan9_pwm); +FAN_SYSFS_ATTR_DATA data_fan10_pwm = {FAN10_PWM, S_IRUGO | S_IWUSR, fan_show_default, NULL, sonic_i2c_get_fan_pwm_default, NULL, fan_store_default, NULL, sonic_i2c_set_fan_pwm_default, NULL, NULL}; +EXPORT_SYMBOL(data_fan10_pwm); +FAN_SYSFS_ATTR_DATA data_fan11_pwm = {FAN11_PWM, S_IRUGO | S_IWUSR, fan_show_default, NULL, sonic_i2c_get_fan_pwm_default, NULL, fan_store_default, NULL, sonic_i2c_set_fan_pwm_default, NULL, NULL}; +EXPORT_SYMBOL(data_fan11_pwm); +FAN_SYSFS_ATTR_DATA data_fan12_pwm = {FAN12_PWM, S_IRUGO | S_IWUSR, fan_show_default, NULL, sonic_i2c_get_fan_pwm_default, NULL, fan_store_default, NULL, sonic_i2c_set_fan_pwm_default, NULL, NULL}; +EXPORT_SYMBOL(data_fan12_pwm); + + +FAN_SYSFS_ATTR_DATA data_fan1_fault = {FAN1_FAULT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_fault_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan1_fault); +FAN_SYSFS_ATTR_DATA data_fan2_fault = {FAN2_FAULT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_fault_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan2_fault); +FAN_SYSFS_ATTR_DATA data_fan3_fault = {FAN3_FAULT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_fault_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan3_fault); +FAN_SYSFS_ATTR_DATA data_fan4_fault = {FAN4_FAULT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_fault_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan4_fault); +FAN_SYSFS_ATTR_DATA data_fan5_fault = {FAN5_FAULT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_fault_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan5_fault); +FAN_SYSFS_ATTR_DATA data_fan6_fault = {FAN6_FAULT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_fault_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan6_fault); +FAN_SYSFS_ATTR_DATA data_fan7_fault = {FAN7_FAULT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_fault_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan7_fault); +FAN_SYSFS_ATTR_DATA data_fan8_fault = {FAN8_FAULT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_fault_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan8_fault); +FAN_SYSFS_ATTR_DATA data_fan9_fault = {FAN9_FAULT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_fault_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan9_fault); +FAN_SYSFS_ATTR_DATA data_fan10_fault = {FAN10_FAULT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_fault_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan10_fault); +FAN_SYSFS_ATTR_DATA data_fan11_fault = {FAN11_FAULT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_fault_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan11_fault); +FAN_SYSFS_ATTR_DATA data_fan12_fault = {FAN12_FAULT, S_IRUGO, fan_show_default, NULL, sonic_i2c_get_fan_fault_default, NULL, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(data_fan12_fault); + + +FAN_SYSFS_ATTR_DATA_ENTRY fan_sysfs_attr_data_tbl[]= +{ + { "fan1_present", &data_fan1_present}, + { "fan2_present", &data_fan2_present}, + { "fan3_present", &data_fan3_present}, + { "fan4_present", &data_fan4_present}, + { "fan5_present", &data_fan5_present}, + { "fan6_present", &data_fan6_present}, + { "fan7_present", &data_fan7_present}, + { "fan8_present", &data_fan8_present}, + { "fan9_present", &data_fan9_present}, + { "fan10_present", &data_fan10_present}, + { "fan11_present", &data_fan11_present}, + { "fan12_present", &data_fan12_present}, + { "fan1_direction", &data_fan1_direction}, + { "fan2_direction", &data_fan2_direction}, + { "fan3_direction", &data_fan3_direction}, + { "fan4_direction", &data_fan4_direction}, + { "fan5_direction", &data_fan5_direction}, + { "fan6_direction", &data_fan6_direction}, + { "fan7_direction", &data_fan7_direction}, + { "fan8_direction", &data_fan8_direction}, + { "fan9_direction", &data_fan9_direction}, + { "fan10_direction", &data_fan10_direction}, + { "fan11_direction", &data_fan11_direction}, + { "fan12_direction", &data_fan12_direction}, + { "fan1_input", &data_fan1_input}, + { "fan2_input", &data_fan2_input}, + { "fan3_input", &data_fan3_input}, + { "fan4_input", &data_fan4_input}, + { "fan5_input", &data_fan5_input}, + { "fan6_input", &data_fan6_input}, + { "fan7_input", &data_fan7_input}, + { "fan8_input", &data_fan8_input}, + { "fan9_input", &data_fan9_input}, + { "fan10_input", &data_fan10_input}, + { "fan11_input", &data_fan11_input}, + { "fan12_input", &data_fan12_input}, + { "fan1_pwm", &data_fan1_pwm}, + { "fan2_pwm", &data_fan2_pwm}, + { "fan3_pwm", &data_fan3_pwm}, + { "fan4_pwm", &data_fan4_pwm}, + { "fan5_pwm", &data_fan5_pwm}, + { "fan6_pwm", &data_fan6_pwm}, + { "fan7_pwm", &data_fan7_pwm}, + { "fan8_pwm", &data_fan8_pwm}, + { "fan9_pwm", &data_fan9_pwm}, + { "fan10_pwm", &data_fan10_pwm}, + { "fan11_pwm", &data_fan11_pwm}, + { "fan12_pwm", &data_fan12_pwm}, + { "fan1_fault", &data_fan1_fault}, + { "fan2_fault", &data_fan2_fault}, + { "fan3_fault", &data_fan3_fault}, + { "fan4_fault", &data_fan4_fault}, + { "fan5_fault", &data_fan5_fault}, + { "fan6_fault", &data_fan6_fault}, + { "fan7_fault", &data_fan7_fault}, + { "fan8_fault", &data_fan8_fault}, + { "fan9_fault", &data_fan9_fault}, + { "fan10_fault", &data_fan10_fault}, + { "fan11_fault", &data_fan11_fault}, + { "fan12_fault", &data_fan12_fault}, +}; + +void *get_fan_access_data(char *name) +{ + int i=0; + for(i=0; i<(sizeof(fan_sysfs_attr_data_tbl)/sizeof(fan_sysfs_attr_data_tbl[0])); i++) + { + if(strcmp(name, fan_sysfs_attr_data_tbl[i].name) ==0) + { + return &fan_sysfs_attr_data_tbl[i]; + } + } + return NULL; +} +EXPORT_SYMBOL(get_fan_access_data); + + + +static int pddf_fan_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct fan_data *data; + int status=0,i,num, j=0; + FAN_PDATA *fan_platform_data; + FAN_DATA_ATTR *data_attr; + FAN_SYSFS_ATTR_DATA_ENTRY *sysfs_data_entry; + char new_str[ATTR_NAME_LEN] = ""; + + if (client == NULL) { + printk("NULL Client.. \n"); + goto exit; + } + + if (pddf_fan_ops.pre_probe) + { + status = (pddf_fan_ops.pre_probe)(client, dev_id); + if (status != 0) + goto exit; + } + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + status = -EIO; + goto exit; + } + + /* Add support for a pre probe function */ + data = kzalloc(sizeof(struct fan_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + dev_info(&client->dev, "chip found\n"); + + + /*Take control of the platform data*/ + fan_platform_data = (FAN_PDATA *)(client->dev.platform_data); + num = fan_platform_data->len; + data->num_attr = num; + + for (i=0;ifan_attrs + i; + sysfs_data_entry = get_fan_access_data(data_attr->aname); + if (sysfs_data_entry == NULL) + { + printk(KERN_ERR "%s: Wrong attribute name provided by user '%s'\n", __FUNCTION__, data_attr->aname); + continue; + } + + dy_ptr = (struct sensor_device_attribute *)kzalloc(sizeof(struct sensor_device_attribute)+ATTR_NAME_LEN, GFP_KERNEL); + dy_ptr->dev_attr.attr.name = (char *)&dy_ptr[1]; + strcpy((char *)dy_ptr->dev_attr.attr.name, data_attr->aname); + dy_ptr->dev_attr.attr.mode = sysfs_data_entry->a_ptr->mode; + dy_ptr->dev_attr.show = sysfs_data_entry->a_ptr->show; + dy_ptr->dev_attr.store = sysfs_data_entry->a_ptr->store; + dy_ptr->index = sysfs_data_entry->a_ptr->index; + + data->fan_attribute_list[i] = &dy_ptr->dev_attr.attr; + strcpy(data->attr_info[i].name, data_attr->aname); + data->attr_info[i].valid = 0; + mutex_init(&data->attr_info[i].update_lock); + + /*Create a duplicate entry*/ + get_fan_duplicate_sysfs(dy_ptr->index, new_str); + if (strcmp(new_str,"")) + { + dy_ptr = (struct sensor_device_attribute *)kzalloc(sizeof(struct sensor_device_attribute)+ATTR_NAME_LEN, GFP_KERNEL); + dy_ptr->dev_attr.attr.name = (char *)&dy_ptr[1]; + strcpy((char *)dy_ptr->dev_attr.attr.name, new_str); + dy_ptr->dev_attr.attr.mode = sysfs_data_entry->a_ptr->mode; + dy_ptr->dev_attr.show = sysfs_data_entry->a_ptr->show; + dy_ptr->dev_attr.store = sysfs_data_entry->a_ptr->store; + dy_ptr->index = sysfs_data_entry->a_ptr->index; + + data->fan_attribute_list[num+j] = &dy_ptr->dev_attr.attr; + j++; + strcpy(new_str, ""); + } + } + data->fan_attribute_list[i+j] = NULL; + data->fan_attribute_group.attrs = data->fan_attribute_list; + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &data->fan_attribute_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: fan '%s'\n", + dev_name(data->hwmon_dev), client->name); + + /* Add a support for post probe function */ + if (pddf_fan_ops.post_probe) + { + status = (pddf_fan_ops.post_probe)(client, dev_id); + if (status != 0) + goto exit_remove; + } + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &data->fan_attribute_group); +exit_free: + /* Free all the allocated attributes */ + for (i=0; data->fan_attribute_list[i]!=NULL; i++) + { + struct sensor_device_attribute *ptr = (struct sensor_device_attribute *)data->fan_attribute_list[i]; + kfree(ptr); + } + pddf_dbg(FAN, KERN_ERR "%s: Freed all the memory allocated for attributes\n", __FUNCTION__); + kfree(data); +exit: + return status; +} + +static int pddf_fan_remove(struct i2c_client *client) +{ + int i = 0, ret = 0; + struct sensor_device_attribute *ptr = NULL; + struct fan_data *data = i2c_get_clientdata(client); + FAN_PDATA *platdata = (FAN_PDATA *)client->dev.platform_data; + FAN_DATA_ATTR *platdata_sub = platdata->fan_attrs; + + if (pddf_fan_ops.pre_remove) + { + ret = (pddf_fan_ops.pre_remove)(client); + if (ret!=0) + printk(KERN_ERR "FAN pre_remove function failed\n"); + } + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &data->fan_attribute_group); + for (i=0; data->fan_attribute_list[i]!=NULL; i++) + { + ptr = (struct sensor_device_attribute *)data->fan_attribute_list[i]; + kfree(ptr); + } + pddf_dbg(FAN, KERN_ERR "%s: Freed all the memory allocated for attributes\n", __FUNCTION__); + kfree(data); + + if (platdata_sub) { + printk(KERN_DEBUG "%s: Freeing platform subdata\n", __FUNCTION__); + kfree(platdata_sub); + } + if (platdata) { + printk(KERN_DEBUG "%s: Freeing platform data\n", __FUNCTION__); + kfree(platdata); + } + + if (pddf_fan_ops.post_remove) + { + ret = (pddf_fan_ops.post_remove)(client); + if (ret!=0) + printk(KERN_ERR "FAN post_remove function failed\n"); + } + + return 0; +} + +/* Addresses to scan */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +static const struct i2c_device_id pddf_fan_id[] = { + { "fan_ctrl", 0 }, + { "fan_cpld", 1 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, pddf_fan_id); + +static struct i2c_driver pddf_fan_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = DRVNAME, + }, + .probe = pddf_fan_probe, + .remove = pddf_fan_remove, + .id_table = pddf_fan_id, + .address_list = normal_i2c, +}; + +static int __init pddf_fan_init(void) +{ + int status = 0; + + if (pddf_fan_ops.pre_init) + { + status = (pddf_fan_ops.pre_init)(); + if (status!=0) + return status; + } + + status = i2c_add_driver(&pddf_fan_driver); + if (status!=0) + return status; + + if (pddf_fan_ops.post_init) + { + status = (pddf_fan_ops.post_init)(); + if (status!=0) + return status; + } + return status; + +} + +static void __exit pddf_fan_exit(void) +{ + if (pddf_fan_ops.pre_exit) (pddf_fan_ops.pre_exit)(); + i2c_del_driver(&pddf_fan_driver); + if (pddf_fan_ops.post_exit) (pddf_fan_ops.post_exit)(); +} + +module_init(pddf_fan_init); +module_exit(pddf_fan_exit); + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("pddf_fan driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/pddf/i2c/modules/fan/pddf_fan_module.c b/platform/pddf/i2c/modules/fan/pddf_fan_module.c new file mode 100644 index 000000000000..b910d6b4a351 --- /dev/null +++ b/platform/pddf/i2c/modules/fan/pddf_fan_module.c @@ -0,0 +1,280 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * A pddf kernel module to create I2C client for FAN controller + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pddf_client_defs.h" +#include "pddf_fan_defs.h" + + +static ssize_t do_attr_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t do_device_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +extern void *get_fan_access_data(char *); +extern void* get_device_table(char *name); +extern void delete_device_table(char *name); + +FAN_DATA fan_data = {0}; + + + +/* FAN CLIENT DATA */ +PDDF_DATA_ATTR(num_fantrays, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_DEC, sizeof(int), (void*)&fan_data.num_fantrays, NULL); + +PDDF_DATA_ATTR(attr_name, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_CHAR, 32, (void*)&fan_data.fan_attr.aname, NULL); +PDDF_DATA_ATTR(attr_devtype, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_CHAR, 8, (void*)&fan_data.fan_attr.devtype, NULL); +PDDF_DATA_ATTR(attr_devname, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_CHAR, 8, (void*)&fan_data.fan_attr.devname, NULL); +PDDF_DATA_ATTR(attr_devaddr, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UINT32, sizeof(uint32_t), (void*)&fan_data.fan_attr.devaddr, NULL); +PDDF_DATA_ATTR(attr_offset, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UINT32, sizeof(uint32_t), (void*)&fan_data.fan_attr.offset, NULL); +PDDF_DATA_ATTR(attr_mask, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UINT32, sizeof(uint32_t), (void*)&fan_data.fan_attr.mask, NULL); +PDDF_DATA_ATTR(attr_cmpval, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UINT32, sizeof(uint32_t), (void*)&fan_data.fan_attr.cmpval, NULL); +PDDF_DATA_ATTR(attr_len, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_DEC, sizeof(int), (void*)&fan_data.fan_attr.len, NULL); +PDDF_DATA_ATTR(attr_mult, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_DEC, sizeof(int), (void*)&fan_data.fan_attr.mult, NULL); +PDDF_DATA_ATTR(attr_is_divisor, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UCHAR, sizeof(unsigned char), (void*)&fan_data.fan_attr.is_divisor, NULL); +PDDF_DATA_ATTR(attr_ops, S_IWUSR, NULL, do_attr_operation, PDDF_CHAR, 8, (void*)&fan_data, NULL); +PDDF_DATA_ATTR(dev_ops, S_IWUSR, NULL, do_device_operation, PDDF_CHAR, 8, (void*)&fan_data, (void*)&pddf_data); + + + +static struct attribute *fan_attributes[] = { + &attr_num_fantrays.dev_attr.attr, + &attr_attr_name.dev_attr.attr, + &attr_attr_devtype.dev_attr.attr, + &attr_attr_devname.dev_attr.attr, + &attr_attr_devaddr.dev_attr.attr, + &attr_attr_offset.dev_attr.attr, + &attr_attr_mask.dev_attr.attr, + &attr_attr_cmpval.dev_attr.attr, + &attr_attr_len.dev_attr.attr, + &attr_attr_mult.dev_attr.attr, + &attr_attr_is_divisor.dev_attr.attr, + &attr_attr_ops.dev_attr.attr, + &attr_dev_ops.dev_attr.attr, + NULL +}; + +static const struct attribute_group pddf_fan_client_data_group = { + .attrs = fan_attributes, +}; + + +static ssize_t do_attr_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + PDDF_ATTR *ptr = (PDDF_ATTR *)da; + FAN_DATA *fdata = (FAN_DATA *)(ptr->addr); + FAN_SYSFS_ATTR_DATA_ENTRY *entry_ptr; + + + fdata->fan_attrs[fdata->len] = fdata->fan_attr; + entry_ptr = get_fan_access_data(fdata->fan_attrs[fdata->len].aname); + if (entry_ptr != NULL && entry_ptr->a_ptr != NULL) + { + fdata->fan_attrs[fdata->len].access_data = entry_ptr->a_ptr ; + } + + fdata->len++; + memset(&fdata->fan_attr, 0, sizeof(fdata->fan_attr)); + + + return count; +} + +struct i2c_board_info *i2c_get_fan_board_info(FAN_DATA *fdata, NEW_DEV_ATTR *cdata) +{ + int num = fdata->len; + int i = 0; + static struct i2c_board_info board_info; + FAN_PDATA *fan_platform_data; + + if (strcmp(cdata->dev_type, "fan_ctrl")==0 || + strcmp(cdata->dev_type, "fan_eeprom")==0 || + strcmp(cdata->dev_type, "fan_cpld")==0 ) + { + /* Allocate the fan_platform_data */ + fan_platform_data = (FAN_PDATA *)kzalloc(sizeof(FAN_PDATA), GFP_KERNEL); + fan_platform_data->fan_attrs = (FAN_DATA_ATTR *)kzalloc(num*sizeof(FAN_DATA_ATTR), GFP_KERNEL); + + + fan_platform_data->num_fantrays = fdata->num_fantrays; + fan_platform_data->len = fdata->len; + + for (i=0;ifan_attrs[i] = fdata->fan_attrs[i]; + } + + board_info = (struct i2c_board_info) { + .platform_data = fan_platform_data, + }; + + board_info.addr = cdata->dev_addr; + strcpy(board_info.type, cdata->dev_type); + } + else + { + printk(KERN_ERR "%s:Unknown type of device %s. Unable to create I2C client for it\n",__FUNCTION__, cdata->dev_type); + } + + return &board_info; +} + + +static ssize_t do_device_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + PDDF_ATTR *ptr = (PDDF_ATTR *)da; + FAN_DATA *fdata = (FAN_DATA *)(ptr->addr); + NEW_DEV_ATTR *cdata = (NEW_DEV_ATTR *)(ptr->data); + struct i2c_adapter *adapter; + struct i2c_board_info *board_info; + struct i2c_client *client_ptr; + + if (strncmp(buf, "add", strlen(buf)-1)==0) + { + adapter = i2c_get_adapter(cdata->parent_bus); + board_info = i2c_get_fan_board_info(fdata, cdata); + + /* Populate the platform data for fan */ + client_ptr = i2c_new_device(adapter, board_info); + + if(client_ptr != NULL) + { + i2c_put_adapter(adapter); + pddf_dbg(FAN, KERN_ERR "Created a %s client: 0x%p\n", cdata->i2c_name, (void *)client_ptr); + add_device_table(cdata->i2c_name, (void*)client_ptr); + } + else + { + i2c_put_adapter(adapter); + goto free_data; + } + } + else if (strncmp(buf, "delete", strlen(buf)-1)==0) + { + /*Get the i2c_client handle for the created client*/ + client_ptr = (struct i2c_client *)get_device_table(cdata->i2c_name); + if (client_ptr) + { + pddf_dbg(FAN, KERN_ERR "Removing %s client: 0x%p\n", cdata->i2c_name, (void *)client_ptr); + i2c_unregister_device(client_ptr); + delete_device_table(cdata->i2c_name); + } + else + { + printk(KERN_ERR "Unable to get the client handle for %s\n", cdata->i2c_name); + } + } + else + { + printk(KERN_ERR "PDDF_ERROR: %s: Invalid value for dev_ops %s", __FUNCTION__, buf); + } + + goto clear_data; + +free_data: + if (board_info->platform_data) + { + FAN_PDATA *fan_platform_data = board_info->platform_data; + if (fan_platform_data->fan_attrs) + { + printk(KERN_ERR "%s: Unable to create i2c client. Freeing the platform subdata\n", __FUNCTION__); + kfree(fan_platform_data->fan_attrs); + } + printk(KERN_ERR "%s: Unable to create i2c client. Freeing the platform data\n", __FUNCTION__); + kfree(fan_platform_data); + } +clear_data: + memset(fdata, 0, sizeof(FAN_DATA)); + /*TODO: free the data cdata->data if data is dynal=mically allocated*/ + memset(cdata, 0, sizeof(NEW_DEV_ATTR)); + return count; +} + + +static struct kobject *fan_kobj; +static struct kobject *i2c_kobj; + +int __init pddf_data_init(void) +{ + struct kobject *device_kobj; + int ret = 0; + + + pddf_dbg(FAN, "PDDF FAN MODULE.. init\n"); + + device_kobj = get_device_i2c_kobj(); + if(!device_kobj) + return -ENOMEM; + + fan_kobj = kobject_create_and_add("fan", device_kobj); + if(!fan_kobj) + return -ENOMEM; + i2c_kobj = kobject_create_and_add("i2c", fan_kobj); + if(!i2c_kobj) + return -ENOMEM; + + ret = sysfs_create_group(i2c_kobj, &pddf_clients_data_group); + if (ret) + { + kobject_put(i2c_kobj); + kobject_put(fan_kobj); + return ret; + } + pddf_dbg(FAN, "CREATED FAN I2C CLIENTS CREATION SYSFS GROUP\n"); + + ret = sysfs_create_group(i2c_kobj, &pddf_fan_client_data_group); + if (ret) + { + sysfs_remove_group(i2c_kobj, &pddf_clients_data_group); + kobject_put(i2c_kobj); + kobject_put(fan_kobj); + return ret; + } + pddf_dbg(FAN, "CREATED PDDF FAN DATA SYSFS GROUP\n"); + + + + return ret; +} + +void __exit pddf_data_exit(void) +{ + pddf_dbg(FAN, "PDDF FAN MODULE.. exit\n"); + sysfs_remove_group(i2c_kobj, &pddf_fan_client_data_group); + sysfs_remove_group(i2c_kobj, &pddf_clients_data_group); + kobject_put(i2c_kobj); + kobject_put(fan_kobj); + pddf_dbg(FAN, KERN_ERR "%s: Removed the kobjects for 'i2c' and 'fan'\n",__FUNCTION__); + return; +} + +module_init(pddf_data_init); +module_exit(pddf_data_exit); + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("fan platform data"); +MODULE_LICENSE("GPL"); diff --git a/platform/pddf/i2c/modules/gpio/Makefile b/platform/pddf/i2c/modules/gpio/Makefile new file mode 100644 index 000000000000..6d48c5884731 --- /dev/null +++ b/platform/pddf/i2c/modules/gpio/Makefile @@ -0,0 +1,4 @@ + +obj-m := pddf_gpio_module.o + +CFLAGS_$(obj-m):= -I$(M)/modules/include diff --git a/platform/pddf/i2c/modules/gpio/pddf_gpio_module.c b/platform/pddf/i2c/modules/gpio/pddf_gpio_module.c new file mode 100644 index 000000000000..afd37c3927df --- /dev/null +++ b/platform/pddf/i2c/modules/gpio/pddf_gpio_module.c @@ -0,0 +1,223 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * PDDF generic kernle module to create the I2C client for pca955x type of GPIO module + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pddf_client_defs.h" +#include "pddf_gpio_defs.h" + + +static ssize_t do_device_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +extern void* get_device_table(char *name); +extern void delete_device_table(char *name); + +static int base_gpio_num = 0xf0; +GPIO_DATA gpio_data = {0}; + +/* GPIO CLIENT DATA */ +PDDF_DATA_ATTR(gpio_base, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_HEX, sizeof(int), (void*)&gpio_data.gpio_base, NULL); +PDDF_DATA_ATTR(dev_ops, S_IWUSR, NULL, do_device_operation, PDDF_CHAR, 8, (void*)&gpio_data, (void*)&pddf_data); + + + +static struct attribute *gpio_attributes[] = { + &attr_gpio_base.dev_attr.attr, + &attr_dev_ops.dev_attr.attr, + NULL +}; + +static const struct attribute_group pddf_gpio_client_data_group = { + .attrs = gpio_attributes, +}; + + +struct i2c_board_info *i2c_get_gpio_board_info(GPIO_DATA* mdata, NEW_DEV_ATTR *device_data) +{ + static struct i2c_board_info board_info; + struct pca953x_platform_data *gpio_platform_data=NULL; + int def_num_gpios, base; + + gpio_platform_data = (struct pca953x_platform_data *)kzalloc(sizeof (struct pca953x_platform_data), GFP_KERNEL); + + if (strncmp(device_data->dev_type, "pca9554", strlen("pca9554")) == 0 || + strncmp(device_data->dev_type, "pca9534", strlen("pca9534")) == 0 || + strncmp(device_data->dev_type, "pca9538", strlen("pca9538")) == 0) + def_num_gpios = 0x8; + else if (strncmp(device_data->dev_type, "pca9555", strlen("pca9555")) == 0 || + strncmp(device_data->dev_type, "pca9535", strlen("pca9535")) == 0 || + strncmp(device_data->dev_type, "pca9539", strlen("pca9539")) == 0 || + strncmp(device_data->dev_type, "pca9575", strlen("pca9575")) == 0) + def_num_gpios = 0x10; + else if (strncmp(device_data->dev_type, "pca9698", strlen("pca9698")) == 0 || + strncmp(device_data->dev_type, "pca9505", strlen("pca9505")) == 0) + def_num_gpios = 0x28; + else + { + printk(KERN_ERR "%s: Unknown type of gpio device\n", __FUNCTION__); + return NULL; + } + + if(mdata->gpio_base == 0) { + base = base_gpio_num; + base_gpio_num += def_num_gpios; + } + else { + base = mdata->gpio_base; + } + + gpio_platform_data->gpio_base = base; + + board_info = (struct i2c_board_info) { + .platform_data = gpio_platform_data, + }; + + board_info.addr = device_data->dev_addr; + strcpy(board_info.type, device_data->dev_type); + + return &board_info; +} + + +static ssize_t do_device_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + PDDF_ATTR *ptr = (PDDF_ATTR *)da; + GPIO_DATA *gpio_ptr = (GPIO_DATA *)(ptr->addr); + NEW_DEV_ATTR *device_ptr = (NEW_DEV_ATTR *)(ptr->data); + struct i2c_adapter *adapter; + struct i2c_board_info *board_info; + struct i2c_client *client_ptr; + + if (strncmp(buf, "add", strlen(buf)-1)==0) + { + adapter = i2c_get_adapter(device_ptr->parent_bus); + board_info = i2c_get_gpio_board_info(gpio_ptr, device_ptr); + + /*pddf_dbg(KERN_ERR "Creating a client %s on 0x%x, platform_data 0x%x\n", board_info->type, board_info->addr, board_info->platform_data);*/ + client_ptr = i2c_new_device(adapter, board_info); + + i2c_put_adapter(adapter); + if (client_ptr != NULL) + { + pddf_dbg(GPIO, KERN_ERR "Created %s client: 0x%p\n", device_ptr->i2c_name, (void *)client_ptr); + add_device_table(device_ptr->i2c_name, (void*)client_ptr); + } + else + { + kfree(board_info); + goto free_data; + } + } + else if (strncmp(buf, "delete", strlen(buf)-1)==0) + { + /*Get the i2c_client handle for the created client*/ + client_ptr = (struct i2c_client *)get_device_table(device_ptr->i2c_name); + if (client_ptr) + { + struct pca953x_platform_data *gpio_platform_data = (struct pca953x_platform_data *)client_ptr->dev.platform_data; + pddf_dbg(GPIO, KERN_ERR "Removing %s client: 0x%p\n", device_ptr->i2c_name, (void *)client_ptr); + i2c_unregister_device(client_ptr); + /*TODO: Nullyfy the platform data*/ + if (gpio_platform_data) + kfree(gpio_platform_data); + delete_device_table(device_ptr->i2c_name); + } + else + { + printk(KERN_ERR "Unable to get the client handle for %s\n", device_ptr->i2c_name); + } + } + else + { + printk(KERN_ERR "PDDF_ERROR: %s: Invalid value for dev_ops %s", __FUNCTION__, buf); + } + +free_data: + memset(gpio_ptr, 0, sizeof(GPIO_DATA)); + /*TODO: free the device_ptr->data is dynamically allocated*/ + memset(device_ptr, 0 , sizeof(NEW_DEV_ATTR)); + + return count; +} + + +static struct kobject *gpio_kobj; + +int __init gpio_data_init(void) +{ + struct kobject *device_kobj; + int ret = 0; + + + pddf_dbg(GPIO, "GPIO_DATA MODULE.. init\n"); + + device_kobj = get_device_i2c_kobj(); + if(!device_kobj) + return -ENOMEM; + + gpio_kobj = kobject_create_and_add("gpio", device_kobj); + if(!gpio_kobj) + return -ENOMEM; + + + ret = sysfs_create_group(gpio_kobj, &pddf_clients_data_group); + if (ret) + { + kobject_put(gpio_kobj); + return ret; + } + pddf_dbg(GPIO, "CREATED PDDF I2C CLIENTS CREATION SYSFS GROUP\n"); + + ret = sysfs_create_group(gpio_kobj, &pddf_gpio_client_data_group); + if (ret) + { + sysfs_remove_group(gpio_kobj, &pddf_clients_data_group); + kobject_put(gpio_kobj); + return ret; + } + pddf_dbg(GPIO, "CREATED GPIO DATA SYSFS GROUP\n"); + + return ret; +} + +void __exit gpio_data_exit(void) +{ + pddf_dbg(GPIO, "GPIO_DATA MODULE.. exit\n"); + sysfs_remove_group(gpio_kobj, &pddf_gpio_client_data_group); + sysfs_remove_group(gpio_kobj, &pddf_clients_data_group); + kobject_put(gpio_kobj); + pddf_dbg(GPIO, KERN_ERR "%s: Removed the kobjects for 'gpio'\n",__FUNCTION__); + return; +} + +module_init(gpio_data_init); +module_exit(gpio_data_exit); + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("gpio platform data"); +MODULE_LICENSE("GPL"); diff --git a/platform/pddf/i2c/modules/include/pddf_client_defs.h b/platform/pddf/i2c/modules/include/pddf_client_defs.h new file mode 100644 index 000000000000..1c98a73e6eb6 --- /dev/null +++ b/platform/pddf/i2c/modules/include/pddf_client_defs.h @@ -0,0 +1,135 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description: + * Platform I2C client defines/structures header file + */ + +#ifndef __PDDF_CLIENT_DEFS_H__ +#define __PDDF_CLIENT_DEFS_H__ + +#include + +#define PSU "PDDF_PSU" +#define LED "PDDF_LED" +#define FAN "PDDF_FAN" +#define CLIENT "PDDF_CLIENT" +#define CPLD "PDDF_CPLD" +#define CPLDMUX "PDDF_CPLDMUX" +#define MUX "PDDF_MUX" +#define GPIO "PDDF_GPIO" +#define SYSSTATUS "PDDF_SYSSTATUS" +#define XCVR "PDDF_XCVR" + +#define PDDF_DEBUG +#ifdef PDDF_DEBUG +#define pddf_dbg(filter,...) printk("%s\t", filter); printk(KERN_CONT __VA_ARGS__) +#else +#define pddf_dbg(...) +#endif + + +#define GEN_NAME_SIZE 32 +#define ERR_STR_SIZE 128 + + +typedef struct pddf_data_attribute{ + struct device_attribute dev_attr; + int type; + int len; + char *addr; + char *data; +}PDDF_ATTR; + +#define PDDF_DATA_ATTR(_name, _mode, _show, _store, _type, _len, _addr, _data) \ + struct pddf_data_attribute attr_##_name = { .dev_attr = __ATTR(_name, _mode, _show, _store), \ + .type = _type , \ + .len = _len , \ + .addr = _addr, \ + .data = _data } + + +enum attribute_data_type { + PDDF_CHAR, + PDDF_UCHAR, + PDDF_INT_HEX, // integer represented in HEX + PDDF_INT_DEC, // integer represented in DECIMAL + PDDF_USHORT, // HEX + PDDF_UINT32 // HEX +}; + + + + + +// PSU Specific details + +typedef struct NEW_DEV_ATTR +{ + char i2c_type[GEN_NAME_SIZE]; + char i2c_name[GEN_NAME_SIZE]; + int parent_bus; + char dev_type[GEN_NAME_SIZE]; + int dev_id; + int dev_addr; + char *data; + int error; + char errstr[ERR_STR_SIZE]; + +}NEW_DEV_ATTR; +extern NEW_DEV_ATTR pddf_data; + +extern struct attribute_group pddf_clients_data_group; +extern ssize_t store_pddf_data(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +extern ssize_t show_pddf_data(struct device *dev, struct device_attribute *da, char *buf); +struct kobject* get_device_i2c_kobj(void); +void set_attr_data(void * ptr); +void set_error_code(int, char *); +ssize_t show_error_code(struct device *dev, struct device_attribute *da, char *buf); +ssize_t show_all_devices(struct device *dev, struct device_attribute *da, char *buf); +void traverse_device_table(void ); + + + +/*Various Ops hook which can be used by vendors to provide some deviation from usual pddf functionality*/ +struct pddf_ops_t +{ + /*Module init ops*/ + int (*pre_init)(void); + int (*post_init)(void); + /*probe ops*/ + int (*pre_probe)(struct i2c_client *, const struct i2c_device_id *); + int (*post_probe)(struct i2c_client *, const struct i2c_device_id *); + /*remove ops*/ + int (*pre_remove)(struct i2c_client *); + int (*post_remove)(struct i2c_client *); + /*Module exit ops*/ + void (*pre_exit)(void); + void (*post_exit)(void); +}; + + +typedef struct PDEVICE +{ + struct hlist_node node; + char name[GEN_NAME_SIZE]; + void *data; + +}PDEVICE; + +void add_device_table(char *name, void *ptr); + + +#endif diff --git a/platform/pddf/i2c/modules/include/pddf_cpld_defs.h b/platform/pddf/i2c/modules/include/pddf_cpld_defs.h new file mode 100644 index 000000000000..c312f3277f75 --- /dev/null +++ b/platform/pddf/i2c/modules/include/pddf_cpld_defs.h @@ -0,0 +1,31 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description: + * Platform CPLD defines/structures header file + */ + +#ifndef __PDDF_CPLD_DEFS_H__ +#define __PDDF_CPLD_DEFS_H__ + +/* CPLD DATA - DATA FOR CPLD CLIENT READ/WRITE*/ +typedef struct CPLD_DATA +{ + struct mutex cpld_lock; + uint16_t reg_addr; +}PDDF_CPLD_DATA; + + +#endif diff --git a/platform/pddf/i2c/modules/include/pddf_cpldmux_defs.h b/platform/pddf/i2c/modules/include/pddf_cpldmux_defs.h new file mode 100644 index 000000000000..ab2aa901c884 --- /dev/null +++ b/platform/pddf/i2c/modules/include/pddf_cpldmux_defs.h @@ -0,0 +1,76 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description: + * Platform CPLDMUX defines/structures header file + */ + +#ifndef __PDDF_CPLDMUX_DEFS_H__ +#define __PDDF_CPLDMUX_DEFS_H__ + +#include + +#define MAX_CPLDMUX_CHAN 64 + +typedef struct CPLDMUX_CHAN_DATA +{ + int chan_num; + char chan_device[128]; /* Could be multiple devices, mentioned as " " seperated array */ + int cpld_devaddr; + int cpld_offset; + int cpld_sel; + int cpld_desel; +}PDDF_CPLDMUX_CHAN_DATA; + +/* CPLDMUX DATA - DATA FOR CPLDMUX CLIENT*/ +typedef struct CPLDMUX_DATA +{ + int base_chan; + int num_chan; + int chan_cache; + uint32_t cpld_addr; + char cpld_name[32]; + PDDF_CPLDMUX_CHAN_DATA chan_data[MAX_CPLDMUX_CHAN]; +}PDDF_CPLDMUX_DATA; + +typedef struct CPLDMUX_PDATA +{ + int parent_bus; + int base_chan; + int num_chan; + int chan_cache; + struct i2c_client *cpld; + PDDF_CPLDMUX_CHAN_DATA *chan_data; +}PDDF_CPLDMUX_PDATA; + +typedef struct CPLDMUX_PRIV_DATA{ + struct i2c_adapter *parent; + uint32_t last_chan; /* Will be used in case channel caching is enabled */ + PDDF_CPLDMUX_PDATA data; +}PDDF_CPLDMUX_PRIV_DATA; + +typedef struct pldmux_ops_t +{ + int (*select)(struct i2c_mux_core *muxc, uint32_t chan); + int (*deselect)(struct i2c_mux_core *muxc, uint32_t chan); +}PDDF_CPLDMUX_OPS; + +int pddf_cpldmux_select_default(struct i2c_mux_core *muxc, uint32_t chan); +int pddf_cpldmux_deselect_default(struct i2c_mux_core *muxc, uint32_t chan); + +extern int board_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int board_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +#endif diff --git a/platform/pddf/i2c/modules/include/pddf_fan_api.h b/platform/pddf/i2c/modules/include/pddf_fan_api.h new file mode 100644 index 000000000000..45b7751ccd43 --- /dev/null +++ b/platform/pddf/i2c/modules/include/pddf_fan_api.h @@ -0,0 +1,37 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Description + * FAN driver api declarations + */ + +#ifndef __PDDF_FAN_API_H__ +#define __PDDF_FAN_API_H__ + +extern int pddf_fan_post_probe_default(struct i2c_client *client, const struct i2c_device_id *dev_id); + +extern void get_fan_duplicate_sysfs(int idx, char *str); +extern ssize_t fan_show_default(struct device *dev, struct device_attribute *da, char *buf); +extern ssize_t fan_store_default(struct device *dev, struct device_attribute *da, const char *buf, size_t count); + + +extern int sonic_i2c_get_fan_present_default(void *client, FAN_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_fan_rpm_default(void *client, FAN_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_fan_direction_default(void *client, FAN_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_fan_pwm_default(void *client, FAN_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_fan_fault_default(void *client, FAN_DATA_ATTR *adata, void *data); +extern int sonic_i2c_set_fan_pwm_default(void *client, FAN_DATA_ATTR *adata, void *data); + +#endif diff --git a/platform/pddf/i2c/modules/include/pddf_fan_defs.h b/platform/pddf/i2c/modules/include/pddf_fan_defs.h new file mode 100644 index 000000000000..7765e5446293 --- /dev/null +++ b/platform/pddf/i2c/modules/include/pddf_fan_defs.h @@ -0,0 +1,91 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description: + * Platform FAN defines/structures header file + */ + +#ifndef __PDDF_FAN_DEFS_H__ +#define __PDDF_FAN_DEFS_H__ + + +#define MAX_NUM_FAN 6 +#define MAX_FAN_ATTRS 128 +#define ATTR_NAME_LEN 32 +#define STR_ATTR_SIZE 32 +#define DEV_TYPE_LEN 32 + +/* Each client has this additional data + */ + +typedef struct FAN_DATA_ATTR +{ + char aname[ATTR_NAME_LEN]; // attr name, taken from enum fan_sysfs_attributes + char devtype[DEV_TYPE_LEN]; // Type of FAN controller, i.e EMC2305, EMC2302, or FAN-CPLD etc + char devname[DEV_TYPE_LEN]; // Name of the device from where this informatin is to be read + uint32_t devaddr; + uint32_t offset; + uint32_t mask; + uint32_t cmpval; + uint32_t len; + int mult; // Multiplication factor to get the actual data + uint8_t is_divisor; // Check if the value is a divisor and mult is dividend + void *access_data; + +}FAN_DATA_ATTR; + + +typedef struct FAN_SYSFS_ATTR_DATA +{ + int index; + unsigned short mode; + ssize_t (*show)(struct device *dev, struct device_attribute *da, char *buf); + int (*pre_get)(void *client, FAN_DATA_ATTR *adata, void *data); + int (*do_get)(void *client, FAN_DATA_ATTR *adata, void *data); + int (*post_get)(void *client, FAN_DATA_ATTR *adata, void *data); + ssize_t (*store)(struct device *dev, struct device_attribute *da, const char *buf, size_t count); + int (*pre_set)(void *client, FAN_DATA_ATTR *adata, void *data); + int (*do_set)(void *client, FAN_DATA_ATTR *adata, void *data); + int (*post_set)(void *client, FAN_DATA_ATTR *adata, void *data); + void *data; +} FAN_SYSFS_ATTR_DATA; + +typedef struct FAN_SYSFS_ATTR_DATA_ENTRY +{ + char name[ATTR_NAME_LEN]; + FAN_SYSFS_ATTR_DATA *a_ptr; +} FAN_SYSFS_ATTR_DATA_ENTRY; + + +/* FAN CLIENT DATA - PLATFORM DATA FOR FAN CLIENT */ +typedef struct FAN_DATA +{ + int num_fantrays; // num of fans controlled by this fan client + FAN_DATA_ATTR fan_attr; + int len; // no of valid attributes for this fan client + FAN_DATA_ATTR fan_attrs[MAX_FAN_ATTRS]; +}FAN_DATA; + +typedef struct FAN_PDATA +{ + int num_fantrays; // num of fans controlled by this fan client + int len; // no of valid attributes for this fan client + FAN_DATA_ATTR *fan_attrs; +}FAN_PDATA; + +extern int board_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int board_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +#endif diff --git a/platform/pddf/i2c/modules/include/pddf_fan_driver.h b/platform/pddf/i2c/modules/include/pddf_fan_driver.h new file mode 100644 index 000000000000..8404db20786a --- /dev/null +++ b/platform/pddf/i2c/modules/include/pddf_fan_driver.h @@ -0,0 +1,107 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description + * FAN driver related data structures + */ +#ifndef __PDDF_FAN_DRIVER_H__ +#define __PDDF_FAN_DRIVER_H__ + +enum fan_sysfs_attributes { + FAN1_PRESENT, + FAN2_PRESENT, + FAN3_PRESENT, + FAN4_PRESENT, + FAN5_PRESENT, + FAN6_PRESENT, + FAN7_PRESENT, + FAN8_PRESENT, + FAN9_PRESENT, + FAN10_PRESENT, + FAN11_PRESENT, + FAN12_PRESENT, + FAN1_DIRECTION, + FAN2_DIRECTION, + FAN3_DIRECTION, + FAN4_DIRECTION, + FAN5_DIRECTION, + FAN6_DIRECTION, + FAN7_DIRECTION, + FAN8_DIRECTION, + FAN9_DIRECTION, + FAN10_DIRECTION, + FAN11_DIRECTION, + FAN12_DIRECTION, + FAN1_INPUT, + FAN2_INPUT, + FAN3_INPUT, + FAN4_INPUT, + FAN5_INPUT, + FAN6_INPUT, + FAN7_INPUT, + FAN8_INPUT, + FAN9_INPUT, + FAN10_INPUT, + FAN11_INPUT, + FAN12_INPUT, + FAN1_PWM, + FAN2_PWM, + FAN3_PWM, + FAN4_PWM, + FAN5_PWM, + FAN6_PWM, + FAN7_PWM, + FAN8_PWM, + FAN9_PWM, + FAN10_PWM, + FAN11_PWM, + FAN12_PWM, + FAN1_FAULT, + FAN2_FAULT, + FAN3_FAULT, + FAN4_FAULT, + FAN5_FAULT, + FAN6_FAULT, + FAN7_FAULT, + FAN8_FAULT, + FAN9_FAULT, + FAN10_FAULT, + FAN11_FAULT, + FAN12_FAULT, + FAN_MAX_ATTR +}; +/* Each client has this additional data */ +struct fan_attr_info { + char name[ATTR_NAME_LEN]; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + union { + char strval[STR_ATTR_SIZE]; + int intval; + u16 shortval; + u8 charval; + }val; +}; + +struct fan_data { + struct device *hwmon_dev; + int num_attr; + struct attribute *fan_attribute_list[MAX_FAN_ATTRS]; + struct attribute_group fan_attribute_group; + struct fan_attr_info attr_info[MAX_FAN_ATTRS]; +}; + +#endif diff --git a/platform/pddf/i2c/modules/include/pddf_gpio_defs.h b/platform/pddf/i2c/modules/include/pddf_gpio_defs.h new file mode 100644 index 000000000000..a8ee00189bce --- /dev/null +++ b/platform/pddf/i2c/modules/include/pddf_gpio_defs.h @@ -0,0 +1,30 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description: + * Platform GPIO defines/structures header file + */ + +#ifndef __PAL_GPIO_DEFS_H__ +#define __PAL_GPIO_DEFS_H__ + +#include +/* GPIO CLIENT DATA*/ +typedef struct GPIO_DATA +{ + int gpio_base; // base bus number of the gpio pins +}GPIO_DATA; + +#endif diff --git a/platform/pddf/i2c/modules/include/pddf_led_defs.h b/platform/pddf/i2c/modules/include/pddf_led_defs.h new file mode 100644 index 000000000000..1603f8c5af8e --- /dev/null +++ b/platform/pddf/i2c/modules/include/pddf_led_defs.h @@ -0,0 +1,120 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description + * Platform LED related defines and structures + */ + + +/***************************************** + * kobj list + *****************************************/ + +struct kobject *platform_kobj=NULL; +struct kobject *led_kobj=NULL; + +struct kobject *state_attr_kobj=NULL; +struct kobject *cur_state_kobj=NULL; + +/***************************************** + * Static Data provided from user + * space JSON data file + *****************************************/ +#define NAME_SIZE 32 +typedef enum { + STATUS_LED_COLOR_GREEN, + STATUS_LED_COLOR_GREEN_BLINK, + STATUS_LED_COLOR_RED, + STATUS_LED_COLOR_RED_BLINK, + STATUS_LED_COLOR_AMBER, + STATUS_LED_COLOR_AMBER_BLINK, + STATUS_LED_COLOR_BLUE, + STATUS_LED_COLOR_BLUE_BLINK, + STATUS_LED_COLOR_OFF, + MAX_LED_STATUS +}LED_STATUS; + +char* LED_STATUS_STR[] = { + "STATUS_LED_COLOR_GREEN", + "STATUS_LED_COLOR_GREEN_BLINK", + "STATUS_LED_COLOR_RED", + "STATUS_LED_COLOR_RED_BLINK", + "STATUS_LED_COLOR_AMBER", + "STATUS_LED_COLOR_AMBER_BLINK", + "STATUS_LED_COLOR_BLUE", + "STATUS_LED_COLOR_BLUE_BLINK", + "STATUS_LED_COLOR_OFF" +}; + + +typedef struct +{ + char bits[NAME_SIZE]; + int pos; + int mask_bits; +}MASK_BITS; + +typedef struct +{ + int swpld_addr; + int swpld_addr_offset; + MASK_BITS bits; + unsigned short value; +} LED_DATA; + +typedef struct +{ + int state; + char color[NAME_SIZE]; +} CUR_STATE_DATA; + +typedef struct +{ + CUR_STATE_DATA cur_state; + char device_name[NAME_SIZE]; + int index; + LED_DATA data[MAX_LED_STATUS]; + int swpld_addr; + int swpld_addr_offset; +} LED_OPS_DATA; + +typedef enum{ + LED_SYS, + LED_PSU, + LED_FAN, + LED_FANTRAY, + LED_DIAG, + LED_LOC, + LED_TYPE_MAX +} LED_TYPE; +char* LED_TYPE_STR[LED_TYPE_MAX] = +{ + "LED_SYS", + "LED_PSU", + "LED_FAN", + "LED_FANTRAY", + "LED_DIAG", + "LED_LOC", +}; + +/***************************************** + * Data exported from kernel for + * user space plugin to get/set + *****************************************/ +#define PDDF_LED_DATA_ATTR( _prefix, _name, _mode, _show, _store, _type, _len, _addr) \ + struct pddf_data_attribute pddf_dev_##_prefix##_attr_##_name = { .dev_attr = __ATTR(_name, _mode, _show, _store), \ + .type = _type , \ + .len = _len , \ + .addr = _addr } diff --git a/platform/pddf/i2c/modules/include/pddf_mux_defs.h b/platform/pddf/i2c/modules/include/pddf_mux_defs.h new file mode 100644 index 000000000000..c58a00e972c6 --- /dev/null +++ b/platform/pddf/i2c/modules/include/pddf_mux_defs.h @@ -0,0 +1,31 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description: + * Platform MUX defines/structures header file + */ + +#ifndef __PAL_MUX_DEFS_H__ +#define __PAL_MUX_DEFS_H__ + +#include + +/* MUX CLIENT DATA - PLATFORM DATA FOR PSU CLIENT */ +typedef struct MUX_DATA +{ + int virt_bus; // Virtual base bus number of the mux channels +}MUX_DATA; + +#endif diff --git a/platform/pddf/i2c/modules/include/pddf_psu_api.h b/platform/pddf/i2c/modules/include/pddf_psu_api.h new file mode 100644 index 000000000000..762863f02845 --- /dev/null +++ b/platform/pddf/i2c/modules/include/pddf_psu_api.h @@ -0,0 +1,41 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description + * PSU driver related api declarations + */ + +#ifndef __PDDF_PSU_API_H__ +#define __PDDF_PSU_API_H__ + +extern void get_psu_duplicate_sysfs(int idx, char *str); +extern ssize_t psu_show_default(struct device *dev, struct device_attribute *da, char *buf); +extern ssize_t psu_store_default(struct device *dev, struct device_attribute *da, const char *buf, size_t count); + +extern int sonic_i2c_get_psu_present_default(void *client, PSU_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_psu_power_good_default(void *client, PSU_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_psu_model_name_default(void *client, PSU_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_psu_mfr_id_default(void *client, PSU_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_psu_serial_num_default(void *client, PSU_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_psu_fan_dir_default(void *client, PSU_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_psu_v_out_default(void *client, PSU_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_psu_i_out_default(void *client, PSU_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_psu_p_out_default(void *client, PSU_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_psu_fan1_speed_rpm_default(void *client, PSU_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_psu_temp1_input_default(void *client, PSU_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_psu_v_in_default(void *client, PSU_DATA_ATTR *adata, void *data); +extern int sonic_i2c_get_psu_i_in_default(void *client, PSU_DATA_ATTR *adata, void *data); + +#endif diff --git a/platform/pddf/i2c/modules/include/pddf_psu_defs.h b/platform/pddf/i2c/modules/include/pddf_psu_defs.h new file mode 100644 index 000000000000..60e81a9f5878 --- /dev/null +++ b/platform/pddf/i2c/modules/include/pddf_psu_defs.h @@ -0,0 +1,90 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description: + * Platform PSU defines/structures header file + */ + +#ifndef __PDDF_PSU_DEFS_H__ +#define __PDDF_PSU_DEFS_H__ + + +#define MAX_NUM_PSU 5 +#define MAX_PSU_ATTRS 32 +#define ATTR_NAME_LEN 32 +#define STR_ATTR_SIZE 32 +#define DEV_TYPE_LEN 32 + +/* Each client has this additional data + */ + +typedef struct PSU_DATA_ATTR +{ + char aname[ATTR_NAME_LEN]; // attr name, taken from enum psu_sysfs_attributes + char devtype[DEV_TYPE_LEN]; // either a 'eeprom' or 'cpld', or 'pmbus' attribute + char devname[DEV_TYPE_LEN]; // Name of the device from where this sysfs attr is read + uint32_t devaddr; + uint32_t offset; + uint32_t mask; + uint32_t cmpval; + uint32_t len; + void *access_data; + +}PSU_DATA_ATTR; + +typedef struct PSU_SYSFS_ATTR_DATA +{ + int index; + unsigned short mode; + ssize_t (*show)(struct device *dev, struct device_attribute *da, char *buf); + int (*pre_get)(void *client, PSU_DATA_ATTR *adata, void *data); + int (*do_get)(void *client, PSU_DATA_ATTR *adata, void *data); + int (*post_get)(void *client, PSU_DATA_ATTR *adata, void *data); + ssize_t (*store)(struct device *dev, struct device_attribute *da, const char *buf, size_t count); + int (*pre_set)(void *client, PSU_DATA_ATTR *adata, void *data); + int (*do_set)(void *client, PSU_DATA_ATTR *adata, void *data); + int (*post_set)(void *client, PSU_DATA_ATTR *adata, void *data); + void *data; +} PSU_SYSFS_ATTR_DATA; + +typedef struct PSU_SYSFS_ATTR_DATA_ENTRY +{ + char name[ATTR_NAME_LEN]; + PSU_SYSFS_ATTR_DATA *a_ptr; +} PSU_SYSFS_ATTR_DATA_ENTRY; + + +/* PSU CLIENT DATA - PLATFORM DATA FOR PSU CLIENT */ +typedef struct PSU_DATA +{ + int idx; // psu index + int num_psu_fans; + PSU_DATA_ATTR psu_attr; + int len; // no of valid attributes for this psu client + PSU_DATA_ATTR psu_attrs[MAX_PSU_ATTRS]; +}PSU_DATA; + +typedef struct PSU_PDATA +{ + int idx; // psu index + int num_psu_fans; // num of fans supported by the PSU + int len; // no of valid attributes for this psu client + PSU_DATA_ATTR *psu_attrs; +}PSU_PDATA; + +extern int board_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int board_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +#endif diff --git a/platform/pddf/i2c/modules/include/pddf_psu_driver.h b/platform/pddf/i2c/modules/include/pddf_psu_driver.h new file mode 100644 index 000000000000..a2aa3f41d397 --- /dev/null +++ b/platform/pddf/i2c/modules/include/pddf_psu_driver.h @@ -0,0 +1,65 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description + * PSU driver data structures + */ +#ifndef __PDDF_PSU_DRIVER_H__ +#define __PDDF_PSU_DRIVER_H__ + +enum psu_sysfs_attributes { + PSU_PRESENT, + PSU_MODEL_NAME, + PSU_POWER_GOOD, + PSU_MFR_ID, + PSU_SERIAL_NUM, + PSU_FAN_DIR, + PSU_V_OUT, + PSU_I_OUT, + PSU_P_OUT, /* This is in micro watts to comply with lm-sensors */ + PSU_FAN1_SPEED, + PSU_TEMP1_INPUT, + PSU_V_IN, + PSU_I_IN, + PSU_ATTR_MAX +}; + + +/* Every client has psu_data which is divided into per attribute data */ +struct psu_attr_info { + char name[ATTR_NAME_LEN]; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 status; + union { + char strval[STR_ATTR_SIZE]; + int intval; + u16 shortval; + u8 charval; + }val; +}; +struct psu_data { + struct device *hwmon_dev; + u8 index; + int num_psu_fans; + int num_attr; + struct attribute *psu_attribute_list[MAX_PSU_ATTRS]; + struct attribute_group psu_attribute_group; + struct psu_attr_info attr_info[MAX_PSU_ATTRS]; +}; + + +#endif diff --git a/platform/pddf/i2c/modules/include/pddf_sysstatus_defs.h b/platform/pddf/i2c/modules/include/pddf_sysstatus_defs.h new file mode 100644 index 000000000000..fd23f214d204 --- /dev/null +++ b/platform/pddf/i2c/modules/include/pddf_sysstatus_defs.h @@ -0,0 +1,51 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description + * Platform system status module structures + */ + +#ifndef __PDDF_SYSSTATUS_DEFS_H__ +#define __PDDF_SYSSTATUS_DEFS_H__ + + +#define ATTR_NAME_LEN 32 +#define MAX_ATTRS 32 + + +/* SYSSTATUS CLIENT DATA - PLATFORM DATA FOR SYSSTATUS CLIENT */ +typedef struct SYSSTATUS_ADDR_ATTR +{ + char aname[ATTR_NAME_LEN]; // attr name + uint32_t devaddr; + uint32_t offset; + uint32_t mask; + uint32_t len; + +}SYSSTATUS_ADDR_ATTR; + + +typedef struct SYSSTATUS_DATA +{ + int len; + SYSSTATUS_ADDR_ATTR sysstatus_addr_attr; + SYSSTATUS_ADDR_ATTR sysstatus_addr_attrs[MAX_ATTRS]; + +}SYSSTATUS_DATA; + + + + +#endif diff --git a/platform/pddf/i2c/modules/include/pddf_xcvr_api.h b/platform/pddf/i2c/modules/include/pddf_xcvr_api.h new file mode 100644 index 000000000000..4a1ce00d5581 --- /dev/null +++ b/platform/pddf/i2c/modules/include/pddf_xcvr_api.h @@ -0,0 +1,44 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description + * Optics driver related api declarations + */ +#ifndef __PDDF_XCVR_API_H__ +#define __PDDF_XCVR_API_H__ + +extern int sonic_i2c_get_mod_pres(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data); +extern int sonic_i2c_get_mod_reset(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data); +extern int sonic_i2c_get_mod_intr_status(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data); +extern int sonic_i2c_get_mod_lpmode(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data); +extern int sonic_i2c_get_mod_rxlos(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data); +extern int sonic_i2c_get_mod_txdisable(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data); +extern int sonic_i2c_get_mod_txfault(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data); +extern int sonic_i2c_set_mod_lpmode(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data); +extern int sonic_i2c_set_mod_reset(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data); +extern int sonic_i2c_set_mod_txdisable(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data); + +extern ssize_t get_module_presence(struct device *dev, struct device_attribute *da, char *buf); +extern ssize_t get_module_reset(struct device *dev, struct device_attribute *da, char *buf); +extern ssize_t set_module_reset(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +extern ssize_t get_module_intr_status(struct device *dev, struct device_attribute *da, char *buf); +extern ssize_t get_module_lpmode(struct device *dev, struct device_attribute *da, char *buf); +extern ssize_t set_module_lpmode(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +extern ssize_t get_module_rxlos(struct device *dev, struct device_attribute *da, char *buf); +extern ssize_t get_module_txdisable(struct device *dev, struct device_attribute *da, char *buf); +extern ssize_t set_module_txdisable(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +extern ssize_t get_module_txfault(struct device *dev, struct device_attribute *da, char *buf); + +#endif diff --git a/platform/pddf/i2c/modules/include/pddf_xcvr_defs.h b/platform/pddf/i2c/modules/include/pddf_xcvr_defs.h new file mode 100644 index 000000000000..63de2eeae0c2 --- /dev/null +++ b/platform/pddf/i2c/modules/include/pddf_xcvr_defs.h @@ -0,0 +1,121 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description: + * Platform SFP defines/structures header file + */ + +#ifndef __PDDF_XCVR_DEFS_H__ +#define __PDDF_XCVR_DEFS_H__ + + +#define MAX_NUM_XCVR 5 +#define MAX_XCVR_ATTRS 20 + + +typedef struct XCVR_ATTR +{ + char aname[32]; // attr name, taken from enum xcvr_sysfs_attributes + char devtype[32]; // either a 'eeprom' or 'cpld', or 'pmbus' attribute + char devname[32]; // name of the device from where this sysfs is to be read + uint32_t devaddr; + uint32_t offset; + uint32_t mask; + uint32_t cmpval; + uint32_t len; + + int (*pre_access)(void *client, void *data); + int (*do_access)(void *client, void *data); + int (*post_access)(void *client, void *data); + +}XCVR_ATTR; + +/* XCVR CLIENT DATA - PLATFORM DATA FOR XCVR CLIENT */ +typedef struct XCVR_DATA +{ + int idx; // xcvr index + XCVR_ATTR xcvr_attr; + int len; // no of valid attributes for this xcvr client + XCVR_ATTR xcvr_attrs[MAX_XCVR_ATTRS]; +}XCVR_DATA; + +typedef struct XCVR_PDATA +{ + int idx; // xcvr index + unsigned short addr; // i2c address of the device + int len; // no of valid attributes for this xcvr client + XCVR_ATTR *xcvr_attrs; +}XCVR_PDATA; + + +#define BIT_INDEX(i) (1ULL << (i)) + +/* List of valid port types */ +typedef enum xcvr_port_type_e { + PDDF_PORT_TYPE_INVALID, + PDDF_PORT_TYPE_NOT_PRESENT, + PDDF_PORT_TYPE_SFP, + PDDF_PORT_TYPE_SFP_PLUS, + PDDF_PORT_TYPE_QSFP, + PDDF_PORT_TYPE_QSFP_PLUS, + PDDF_PORT_TYPE_QSFP28 +} xcvr_port_type_t; + +/* Each client has this additional data + */ +struct xcvr_data { + struct device *xdev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + int index; /* port index */ + xcvr_port_type_t port_type; + uint32_t modpres; + uint32_t reset; + uint32_t intr_status; + uint32_t lpmode; + uint32_t rxlos; + uint32_t txdisable; + uint32_t txfault; +}; + +typedef struct XCVR_SYSFS_ATTR_OPS +{ + int index; + ssize_t (*show)(struct device *dev, struct device_attribute *da, char *buf); + int (*pre_get)(struct i2c_client *client, XCVR_ATTR *adata, struct xcvr_data *data); + int (*do_get)(struct i2c_client *client, XCVR_ATTR *adata, struct xcvr_data *data); + int (*post_get)(struct i2c_client *client, XCVR_ATTR *adata, struct xcvr_data *data); + ssize_t (*store)(struct device *dev, struct device_attribute *da, const char *buf, size_t count); + int (*pre_set)(struct i2c_client *client, XCVR_ATTR *adata, struct xcvr_data *data); + int (*do_set)(struct i2c_client *client, XCVR_ATTR *adata, struct xcvr_data *data); + int (*post_set)(struct i2c_client *client, XCVR_ATTR *adata, struct xcvr_data *data); +} XCVR_SYSFS_ATTR_OPS; + +enum xcvr_sysfs_attributes { + XCVR_PRESENT, + XCVR_RESET, + XCVR_INTR_STATUS, + XCVR_LPMODE, + XCVR_RXLOS, + XCVR_TXDISABLE, + XCVR_TXFAULT, + XCVR_ATTR_MAX +}; + +extern int board_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int board_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +#endif diff --git a/platform/pddf/i2c/modules/led/Makefile b/platform/pddf/i2c/modules/led/Makefile new file mode 100644 index 000000000000..0c450ec70b4c --- /dev/null +++ b/platform/pddf/i2c/modules/led/Makefile @@ -0,0 +1,4 @@ +TARGET := pddf_led_module +obj-m := $(TARGET).o + +CFLAGS_$(obj-m):= -I$(M)/modules/include diff --git a/platform/pddf/i2c/modules/led/pddf_led_module.c b/platform/pddf/i2c/modules/led/pddf_led_module.c new file mode 100644 index 000000000000..362467e5ab98 --- /dev/null +++ b/platform/pddf/i2c/modules/led/pddf_led_module.c @@ -0,0 +1,659 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * A pddf kernel module to manage various LEDs of a switch + */ + +#include +#include +#include +#include +#include +#include +#include "pddf_led_defs.h" +#include "pddf_client_defs.h" +#include +#include +#include + +#define DEBUG 0 +LED_OPS_DATA sys_led_ops_data[1]={0}; +LED_OPS_DATA* psu_led_ops_data=NULL; +LED_OPS_DATA diag_led_ops_data[1]= {0}; +LED_OPS_DATA fan_led_ops_data[1]= {0}; +LED_OPS_DATA loc_led_ops_data[1]= {0}; +LED_OPS_DATA* fantray_led_ops_data=NULL; +LED_OPS_DATA temp_data={0}; +LED_OPS_DATA* dev_list[LED_TYPE_MAX] = { + sys_led_ops_data, + NULL, + fan_led_ops_data, + NULL, + diag_led_ops_data, + loc_led_ops_data, +}; +int num_psus = 0; +int num_fantrays = 0; + +extern int board_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int board_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); +extern ssize_t show_pddf_data(struct device *dev, struct device_attribute *da, char *buf); +extern ssize_t store_pddf_data(struct device *dev, struct device_attribute *da, const char *buf, size_t count); + +static LED_STATUS find_state_index(const char* state_str) { + int index; + char *ptr = (char *)state_str; + while (*ptr && *ptr!= '\n' && *ptr !='\0') ptr++; + *ptr='\0'; + for ( index = 0; index < MAX_LED_STATUS; index++) { + /*int rc = strcmp(state_str, LED_STATUS_STR[index]) ;*/ + if (strcmp(state_str, LED_STATUS_STR[index]) == 0 ) { + return index; + } + } + return MAX_LED_STATUS; +} + +static LED_TYPE get_dev_type(char* name) +{ + LED_TYPE ret = LED_TYPE_MAX; + if(strcasecmp(name, "SYS_LED")==0) { + ret = LED_SYS; + } else if(strcasecmp(name, "FAN_LED")==0) { + ret = LED_FAN; + } else if(strstr(name, "PSU_LED")) { + ret = LED_PSU; + } else if(strcasecmp(name, "DIAG_LED")==0) { + ret = LED_DIAG; + } else if(strcasecmp(name, "LOC_LED")==0) { + ret = LED_LOC; + } else if(strstr(name, "FANTRAY_LED")) { + ret = LED_FANTRAY; + } +#if DEBUG > 1 + pddf_dbg(LED, KERN_INFO "LED get_dev_type: %s; %d\n", name, ret); +#endif + return (ret); +} +static int dev_index_check(LED_TYPE type, int index) +{ +#if DEBUG + pddf_dbg(LED, "dev_index_check: type:%s index:%d num_psus:%d num_fantrays:%d\n", + LED_TYPE_STR[type], index, num_psus, num_fantrays); +#endif + switch(type) + { + case LED_PSU: + if(index >= num_psus) return (-1); + break; + case LED_FANTRAY: + if(index >= num_fantrays) return (-1); + break; + default: + if(index >= 1) return (-1); + break; + } + return (0); +} + +static LED_OPS_DATA* find_led_ops_data(struct device_attribute *da) +{ + struct pddf_data_attribute *_ptr = (struct pddf_data_attribute *)da; + LED_OPS_DATA* ptr=(LED_OPS_DATA*)_ptr->addr; + LED_TYPE led_type; + if(!ptr || strlen(ptr->device_name)==0 ) return(NULL); + + + if((led_type=get_dev_type(ptr->device_name))==LED_TYPE_MAX) { + printk(KERN_ERR "PDDF_LED ERROR *%s Unsupported Led Type\n", __func__); + return(NULL); + } + if(dev_index_check(led_type, ptr->index)==-1) { + printk(KERN_ERR "PDDF_LED ERROR %s invalid index: %d for type:%s\n", __func__, ptr->index, ptr->device_name); + return(NULL); + } +#if DEBUG > 1 + pddf_dbg(LED, "find_led_ops_data: name:%s; index=%d tempAddr:%p actualAddr:%p\n", + ptr->device_name, ptr->index, ptr, dev_list[led_type]+ptr->index); +#endif + return (dev_list[led_type]+ptr->index); +} + +static void print_led_data(LED_OPS_DATA *ptr, LED_STATUS state) +{ + int i = 0; + if(!ptr) return ; + pddf_dbg(LED, KERN_INFO "Print %s index:%d num_psus:%d num_fantrays:%d ADDR=%p\n", + ptr->device_name, ptr->index, num_psus, num_fantrays, ptr); + pddf_dbg(LED, KERN_INFO "\tindex: %d\n", ptr->index); + pddf_dbg(LED, KERN_INFO "\tcur_state: %d; %s \n", ptr->cur_state.state, ptr->cur_state.color); + for (i = 0; i< MAX_LED_STATUS; i++) { + if(ptr->data[i].swpld_addr && (i == state || state == -1)) { + pddf_dbg(LED, KERN_INFO "\t\t[%s]: addr/offset:0x%x;0x%x color:%s; value:%x; mask_bits: 0x%x; pos:%d\n", + LED_STATUS_STR[i], + ptr->data[i].swpld_addr, ptr->data[i].swpld_addr_offset, + LED_STATUS_STR[i], ptr->data[i].value, ptr->data[i].bits.mask_bits, ptr->data[i].bits.pos); + } + } +} + +ssize_t get_status_led(struct device_attribute *da) +{ + int ret=0; + struct pddf_data_attribute *_ptr = (struct pddf_data_attribute *)da; + LED_OPS_DATA* temp_data_ptr=(LED_OPS_DATA*)_ptr->addr; + LED_OPS_DATA* ops_ptr=find_led_ops_data(da); + uint32_t color_val=0, sys_val=0; + int state=0; + if (!ops_ptr) { + pddf_dbg(LED, KERN_ERR "ERROR %s: Cannot find LED Ptr", __func__); + return (-1); + } + if (ops_ptr->swpld_addr == 0x0) { + pddf_dbg(LED, KERN_ERR "ERROR %s: device: %s %d not configured\n", __func__, + temp_data_ptr->device_name, temp_data_ptr->index); + return (-1); + } + sys_val = board_i2c_cpld_read(ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset); + if (sys_val < 0) + return sys_val; + + strcpy(temp_data.cur_state.color, "None"); + for (state=0; statedata[state].bits.mask_bits); + if ((color_val ^ (ops_ptr->data[state].value<data[state].bits.pos))==0) { + strcpy(temp_data.cur_state.color, LED_STATUS_STR[state]); + } + } +#if DEBUG > 1 + pddf_dbg(LED, KERN_ERR "Get : %s:%d addr/offset:0x%x; 0x%x value=0x%x [%s]\n", + ops_ptr->device_name, ops_ptr->index, + ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset, sys_val, + temp_data.cur_state.color); +#endif + + return(ret); +} + +ssize_t set_status_led(struct device_attribute *da) +{ + int ret=0; + uint32_t sys_val=0, new_val=0; + LED_STATUS cur_state = MAX_LED_STATUS; + struct pddf_data_attribute *_ptr = (struct pddf_data_attribute *)da; + LED_OPS_DATA* temp_data_ptr=(LED_OPS_DATA*)_ptr->addr; + LED_OPS_DATA* ops_ptr=find_led_ops_data(da); + char* _buf=temp_data_ptr->cur_state.color; + + if (!ops_ptr) { + pddf_dbg(LED, KERN_ERR "PDDF_LED ERROR %s: Cannot find LED Ptr", __func__); + return (-1); + } + if (ops_ptr->swpld_addr == 0x0) { + pddf_dbg(LED, KERN_ERR "PDDF_LED ERROR %s: device: %s %d not configured\n", + __func__, ops_ptr->device_name, ops_ptr->index); + return (-1); + } + pddf_dbg(LED, KERN_ERR "%s: Set [%s;%d] color[%s]\n", __func__, + temp_data_ptr->device_name, temp_data_ptr->index, + temp_data_ptr->cur_state.color); + cur_state = find_state_index(_buf); + + if (cur_state == MAX_LED_STATUS) { + pddf_dbg(LED, KERN_ERR "ERROR %s: not supported: %s\n", _buf, __func__); + return (-1); + } + + if(ops_ptr->data[cur_state].swpld_addr != 0x0) { + sys_val = board_i2c_cpld_read(ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset); + if (sys_val < 0) + return sys_val; + + new_val = (sys_val & ops_ptr->data[cur_state].bits.mask_bits) | + (ops_ptr->data[cur_state].value << ops_ptr->data[cur_state].bits.pos); + + } else { + pddf_dbg(LED, KERN_ERR "ERROR %s: %s %d state %d; %s not configured\n",__func__, + ops_ptr->device_name, ops_ptr->index, cur_state, _buf); + return (-1); + } + + board_i2c_cpld_write(ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset, new_val); + pddf_dbg(LED, KERN_INFO "Set color:%s; 0x%x:0x%x sys_val:0x%x new_val:0x%x read:0x%x\n", + LED_STATUS_STR[cur_state], + ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset, + sys_val, new_val, + ret = board_i2c_cpld_read(ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset)); + if (ret < 0) + { + pddf_dbg(LED, KERN_ERR "PDDF_LED ERROR %s: Error %d in reading from cpld(0x%x) offset 0x%x\n", __FUNCTION__, ret, ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset); + return ret; + } + return(ret); +} + + +ssize_t show_pddf_data(struct device *dev, struct device_attribute *da, + char *buf) +{ + int ret = 0; + struct pddf_data_attribute *ptr = (struct pddf_data_attribute *)da; + switch(ptr->type) + { + case PDDF_CHAR: + ret = sprintf(buf, "%s\n", ptr->addr); + break; + case PDDF_INT_DEC: + ret = sprintf(buf, "%d\n", *(int*)(ptr->addr)); + break; + case PDDF_INT_HEX: + ret = sprintf(buf, "0x%x\n", *(int*)(ptr->addr)); + break; + case PDDF_USHORT: + ret = sprintf(buf, "0x%x\n", *(unsigned short *)(ptr->addr)); + break; + case PDDF_UINT32: + ret = sprintf(buf, "0x%x\n", *(uint32_t *)(ptr->addr)); + break; + default: + break; + } +#if DEBUG > 1 + pddf_dbg(LED, "[ READ ] DATA ATTR PTR [%s] TYPE:%d, Value:[%s]\n", + ptr->dev_attr.attr.name, ptr->type, buf); +#endif + return ret; +} + +ssize_t store_pddf_data(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int ret = 0, num = 0; + struct pddf_data_attribute *ptr = (struct pddf_data_attribute *)da; + switch(ptr->type) + { + case PDDF_CHAR: + strncpy(ptr->addr, buf, strlen(buf)-1); // to discard newline char form buf + ptr->addr[strlen(buf)-1] = '\0'; +#if DEBUG + pddf_dbg(LED, KERN_ERR "[ WRITE ] ATTR PTR [%s] PDDF_CHAR VALUE:%s\n", + ptr->dev_attr.attr.name, ptr->addr); +#endif + break; + case PDDF_INT_DEC: + ret = kstrtoint(buf,10,&num); + if (ret==0) + *(int *)(ptr->addr) = num; +#if DEBUG + pddf_dbg(LED, KERN_ERR "[ WRITE ] ATTR PTR [%s] PDDF_DEC VALUE:%d\n", + ptr->dev_attr.attr.name, *(int *)(ptr->addr)); +#endif + break; + case PDDF_INT_HEX: + ret = kstrtoint(buf,16,&num); + if (ret==0) + *(int *)(ptr->addr) = num; +#if DEBUG + pddf_dbg(LED, KERN_ERR "[ WRITE ] ATTR PTR [%s] PDDF_HEX VALUE:0x%x\n", + ptr->dev_attr.attr.name, *(int *)(ptr->addr)); +#endif + break; + case PDDF_USHORT: + ret = kstrtoint(buf,16,&num); + if (ret==0) + *(unsigned short *)(ptr->addr) = (unsigned short)num; +#if DEBUG + pddf_dbg(LED, KERN_ERR "[ WRITE ] ATTR PTR [%s] PDDF_USHORT VALUE:%x\n", + ptr->dev_attr.attr.name, *(unsigned short *)(ptr->addr)); +#endif + break; + case PDDF_UINT32: + ret = kstrtoint(buf,16,&num); + if (ret==0) + *(uint32_t *)(ptr->addr) = (uint32_t)num; +#if DEBUG + pddf_dbg(LED, KERN_ERR "[ WRITE ] ATTR PTR [%s] PDDF_UINT32 VALUE:%d\n", + ptr->dev_attr.attr.name, *(uint32_t *)(ptr->addr)); +#endif + break; + default: + break; + } + return count; +} + +static int load_led_ops_data(struct device_attribute *da, LED_STATUS state) +{ + struct pddf_data_attribute *_ptr = (struct pddf_data_attribute *)da; + LED_OPS_DATA* ptr=(LED_OPS_DATA*)_ptr->addr; + LED_TYPE led_type; + LED_OPS_DATA* ops_ptr=NULL; + if(!ptr || strlen(ptr->device_name)==0 ) { + pddf_dbg(LED, KERN_INFO "SYSTEM_LED: load_led_ops_data return -1 device_name:%s\n", ptr? ptr->device_name:"NULL"); + return(-1); + } + if(ptr->device_name) + { + pddf_dbg(LED, KERN_INFO "[%s]: load_led_ops_data: index=%d addr=0x%x;0x%x valu=0x%x\n", + ptr->device_name, ptr->index, ptr->swpld_addr, ptr->swpld_addr_offset, ptr->data[0].value); + } + if((led_type=get_dev_type(ptr->device_name))==LED_TYPE_MAX) { + pddf_dbg(LED, KERN_ERR "PDDF_LED ERROR *%s Unsupported Led Type\n", __func__); + return(-1); + } + if(dev_index_check(led_type, ptr->index)==-1) { + pddf_dbg(LED, KERN_ERR "PDDF_LED ERROR %s invalid index: %d for type:%d\n", __func__, ptr->index, led_type); + return(-1); + } + ops_ptr = dev_list[led_type]+ptr->index; + + memcpy(ops_ptr->device_name, ptr->device_name, sizeof(ops_ptr->device_name)); + ops_ptr->index = ptr->index; + memcpy(&ops_ptr->data[state], &ptr->data[0], sizeof(LED_DATA)); + ops_ptr->data[state].swpld_addr = ptr->swpld_addr; + ops_ptr->data[state].swpld_addr_offset = ptr->swpld_addr_offset; + ops_ptr->swpld_addr = ptr->swpld_addr; + ops_ptr->swpld_addr_offset = ptr->swpld_addr_offset; + + print_led_data(dev_list[led_type]+ptr->index, state); + + memset(ptr, 0, sizeof(LED_OPS_DATA)); + return (0); +} + +static int show_led_ops_data(struct device_attribute *da) +{ + LED_OPS_DATA* ops_ptr=find_led_ops_data(da); + print_led_data(ops_ptr, -1); + return(0); +} + +static int verify_led_ops_data(struct device_attribute *da) +{ + struct pddf_data_attribute *_ptr = (struct pddf_data_attribute *)da; + LED_OPS_DATA* ptr=(LED_OPS_DATA*)_ptr->addr; + LED_OPS_DATA* ops_ptr=find_led_ops_data(da); + + if(ops_ptr) + memcpy(ptr, ops_ptr, sizeof(LED_OPS_DATA)); + else + { + pddf_dbg(LED, "SYSTEM_LED: verify_led_ops_data: Failed to find ops_ptr name:%s; index=%d\n", ptr->device_name, ptr->index); + } + return (0); +} + + +ssize_t dev_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ +#if DEBUG + pddf_dbg(LED, KERN_INFO "dev_operation [%s]\n", buf); +#endif + if(strstr(buf, "STATUS_LED_COLOR")!= NULL) { + LED_STATUS index = find_state_index(buf); + if (index < MAX_LED_STATUS ) { + load_led_ops_data(da, index); + } else { + printk(KERN_ERR "PDDF_ERROR %s: Invalid state for dev_ops %s", __FUNCTION__, buf); + } + } + else if(strncmp(buf, "show", strlen("show"))==0 ) { + show_led_ops_data(da); + } + else if(strncmp(buf, "verify", strlen("verify"))==0 ) { + verify_led_ops_data(da); + } + else if(strncmp(buf, "get_status", strlen("get_status"))==0 ) { + get_status_led(da); + } + else if(strncmp(buf, "set_status", strlen("set_status"))==0 ) { + set_status_led(da); + } + else { + printk(KERN_ERR "PDDF_ERROR %s: Invalid value for dev_ops %s", __FUNCTION__, buf); + } + return(count); +} + +ssize_t store_config_data(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int ret, num; + struct pddf_data_attribute *ptr = (struct pddf_data_attribute *)da; + if(strncmp(ptr->dev_attr.attr.name, "num_psus", strlen("num_psus"))==0 ) { + ret = kstrtoint(buf,10,&num); + if (ret==0) + *(int *)(ptr->addr) = num; + if(psu_led_ops_data == NULL) { + if ((psu_led_ops_data = kzalloc(num * sizeof(LED_OPS_DATA), GFP_KERNEL)) == NULL) { + printk(KERN_ERR "PDDF_LED ERROR failed to allocate memory for PSU LED\n"); + return (count); + } + pddf_dbg(LED, "Allocate PSU LED Memory ADDR=%p\n", psu_led_ops_data); + dev_list[LED_PSU]=psu_led_ops_data; + } +#if DEBUG + pddf_dbg(LED, "[ WRITE ] ATTR CONFIG [%s] VALUE:%d; %d\n", + ptr->dev_attr.attr.name, num, num_psus); +#endif + return(count); + } + if(strncmp(ptr->dev_attr.attr.name, "num_fantrays", strlen("num_fantrays"))==0 ) { + ret = kstrtoint(buf,10,&num); + if (ret==0) + *(int *)(ptr->addr) = num; + if (fantray_led_ops_data == NULL) { + if ((fantray_led_ops_data = kzalloc(num * sizeof(LED_OPS_DATA), GFP_KERNEL)) == NULL) { + printk(KERN_ERR "PDDF_LED ERROR failed to allocate memory for FANTRAY LED\n"); + return (count); + } + pddf_dbg(LED, "Allocate FanTray LED Memory ADDR=%p\n", fantray_led_ops_data); + dev_list[LED_FANTRAY]=fantray_led_ops_data; + } +#if DEBUG + pddf_dbg(LED, "[ WRITE ] ATTR CONFIG [%s] VALUE:%d; %d\n", + ptr->dev_attr.attr.name, num, num_fantrays); +#endif + return(count); + } + return (count); +} + +ssize_t store_bits_data(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int len = 0, num1 = 0, num2 = 0, i=0, rc1=0, rc2=0; + char mask=0xFF; + char *pptr=NULL; + char bits[NAME_SIZE]; + struct pddf_data_attribute *ptr = (struct pddf_data_attribute *)da; + MASK_BITS* bits_ptr=(MASK_BITS*)(ptr->addr); + strncpy(bits_ptr->bits, buf, strlen(buf)-1); // to discard newline char form buf + bits_ptr->bits[strlen(buf)-1] = '\0'; + if((pptr=strstr(buf,":")) != NULL) { + len=pptr-buf; + sprintf(bits, buf); + bits[len]='\0'; + rc1=kstrtoint(bits,16,&num1); + if (rc1==0) + { + sprintf(bits, ++pptr); + rc2=kstrtoint(bits,16,&num2); + if (rc2==0) + { + for (i=num2; i<=num1; i++) { + mask &= ~(1 << i); + } + bits_ptr->mask_bits = mask; + bits_ptr->pos = num2; + } + } + } else { + rc1=kstrtoint(buf,16,&num1); + if (rc1==0) + { + bits_ptr->mask_bits = mask & ~(1 << num1); + bits_ptr->pos = num1; + } + } +#if DEBUG + pddf_dbg(LED, KERN_ERR "[ WRITE ] ATTR PTR Bits [%s] VALUE:%s mask:0x%x; pos:0x%x\n", + ptr->dev_attr.attr.name, bits_ptr->bits, bits_ptr->mask_bits, bits_ptr->pos); +#endif + return (count); +} + +/************************************************************************** + * platform/ attributes + **************************************************************************/ +PDDF_LED_DATA_ATTR(platform, num_psus, S_IWUSR|S_IRUGO, show_pddf_data, + store_config_data, PDDF_INT_DEC, sizeof(int), (void*)&num_psus); +PDDF_LED_DATA_ATTR(platform, num_fantrays, S_IWUSR|S_IRUGO, show_pddf_data, + store_config_data, PDDF_INT_DEC, sizeof(int), (void*)&num_fantrays); + +struct attribute* attrs_platform[]={ + &pddf_dev_platform_attr_num_psus.dev_attr.attr, + &pddf_dev_platform_attr_num_fantrays.dev_attr.attr, + NULL, +}; +struct attribute_group attr_group_platform={ + .attrs = attrs_platform, +}; + +/************************************************************************** + * led/ attributes + **************************************************************************/ +PDDF_LED_DATA_ATTR(dev, device_name, S_IWUSR|S_IRUGO, show_pddf_data, + store_pddf_data, PDDF_CHAR, NAME_SIZE, (void*)&temp_data.device_name); +PDDF_LED_DATA_ATTR(dev, index, S_IWUSR|S_IRUGO, show_pddf_data, + store_pddf_data, PDDF_INT_DEC, sizeof(int), (void*)&temp_data.index); +PDDF_LED_DATA_ATTR(dev, swpld_addr, S_IWUSR|S_IRUGO, show_pddf_data, + store_pddf_data, PDDF_INT_HEX, sizeof(int), (void*)&temp_data.swpld_addr); +PDDF_LED_DATA_ATTR(dev, swpld_addr_offset, S_IWUSR|S_IRUGO, show_pddf_data, + store_pddf_data, PDDF_INT_HEX, sizeof(int), (void*)&temp_data.swpld_addr_offset); +PDDF_LED_DATA_ATTR(dev, dev_ops , S_IWUSR, NULL, + dev_operation, PDDF_CHAR, NAME_SIZE, (void*)&temp_data); + +struct attribute* attrs_dev[]={ + &pddf_dev_dev_attr_device_name.dev_attr.attr, + &pddf_dev_dev_attr_index.dev_attr.attr, + &pddf_dev_dev_attr_swpld_addr.dev_attr.attr, + &pddf_dev_dev_attr_swpld_addr_offset.dev_attr.attr, + &pddf_dev_dev_attr_dev_ops.dev_attr.attr, + NULL, +}; +struct attribute_group attr_group_dev={ + .attrs = attrs_dev, +}; + +/************************************************************************** + * state_attr/ attributes + **************************************************************************/ +#define LED_DEV_STATE_ATTR_GROUP(name, func) \ + PDDF_LED_DATA_ATTR(name, bits, S_IWUSR|S_IRUGO, show_pddf_data, \ + store_bits_data, PDDF_CHAR, NAME_SIZE, func.bits.bits); \ + PDDF_LED_DATA_ATTR(name, value, S_IWUSR|S_IRUGO, show_pddf_data, \ + store_pddf_data, PDDF_USHORT, sizeof(unsigned short), func.value); \ + struct attribute* attrs_##name[]={ \ + &pddf_dev_##name##_attr_bits.dev_attr.attr, \ + &pddf_dev_##name##_attr_value.dev_attr.attr, \ + NULL, \ + }; \ + struct attribute_group attr_group_##name={ \ + .attrs = attrs_##name, \ + }; \ + + +LED_DEV_STATE_ATTR_GROUP(state_attr, (void*)&temp_data.data[0]) + +/************************************************************************** + * cur_state/ attributes + **************************************************************************/ +PDDF_LED_DATA_ATTR(cur_state, color, S_IWUSR|S_IRUGO, show_pddf_data, + store_pddf_data, PDDF_CHAR, NAME_SIZE, (void*)&temp_data.cur_state.color); + +struct attribute* attrs_cur_state[]={ + &pddf_dev_cur_state_attr_color.dev_attr.attr, + NULL, +}; +struct attribute_group attr_group_cur_state={ + .attrs = attrs_cur_state, +}; + +/*************************************************************************/ +#define KOBJ_FREE(obj) \ + if(obj) kobject_put(obj); \ + +void free_kobjs(void) +{ + KOBJ_FREE(cur_state_kobj) + KOBJ_FREE(state_attr_kobj) + KOBJ_FREE(led_kobj) + KOBJ_FREE(platform_kobj) +} + +int KBOJ_CREATE(char* name, struct kobject* parent, struct kobject** child) +{ + if (parent) { + *child = kobject_create_and_add(name, parent); + } else { + printk(KERN_ERR "PDDF_LED ERROR to create %s kobj; null parent\n", name); + free_kobjs(); + return (-ENOMEM); + } + return (0); +} + +int LED_DEV_ATTR_CREATE(struct kobject *kobj, const struct attribute_group *attr, const char* name) +{ + int status = sysfs_create_group(kobj, attr); + if(status) { + pddf_dbg(LED, KERN_ERR "Driver ERROR: sysfs_create %s failed rc=%d\n", name, status); + } + return (status); +} + + +static int __init led_init(void) { + struct kobject *device_kobj; + pddf_dbg(LED, KERN_INFO "PDDF GENERIC LED MODULE init..\n"); + + device_kobj = get_device_i2c_kobj(); + if(!device_kobj) + return -ENOMEM; + + KBOJ_CREATE("platform", device_kobj, &platform_kobj); + KBOJ_CREATE("led", device_kobj, &led_kobj); + KBOJ_CREATE("state_attr", led_kobj, &state_attr_kobj); + KBOJ_CREATE("cur_state", led_kobj, &cur_state_kobj); + + LED_DEV_ATTR_CREATE(platform_kobj, &attr_group_platform, "attr_group_platform"); + LED_DEV_ATTR_CREATE(led_kobj, &attr_group_dev, "attr_group_dev"); + LED_DEV_ATTR_CREATE(state_attr_kobj, &attr_group_state_attr, "attr_group_state_attr"); + LED_DEV_ATTR_CREATE(cur_state_kobj, &attr_group_cur_state, "attr_group_cur_state"); + return (0); +} + + +static void __exit led_exit(void) { + pddf_dbg(LED, "PDDF GENERIC LED MODULE exit..\n"); + free_kobjs(); + if(psu_led_ops_data) kfree(psu_led_ops_data); + if(fantray_led_ops_data) kfree(fantray_led_ops_data); +} + +module_init(led_init); +module_exit(led_exit); + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("led driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/pddf/i2c/modules/mux/Makefile b/platform/pddf/i2c/modules/mux/Makefile new file mode 100644 index 000000000000..486e7033435f --- /dev/null +++ b/platform/pddf/i2c/modules/mux/Makefile @@ -0,0 +1,4 @@ + +obj-m := pddf_mux_module.o + +CFLAGS_$(obj-m):= -I$(M)/modules/include diff --git a/platform/pddf/i2c/modules/mux/pddf_mux_module.c b/platform/pddf/i2c/modules/mux/pddf_mux_module.c new file mode 100644 index 000000000000..b0cd9e761ca7 --- /dev/null +++ b/platform/pddf/i2c/modules/mux/pddf_mux_module.c @@ -0,0 +1,211 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * A pddf kernel module to create I2C client for pca954x type of multiplexer + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pddf_client_defs.h" +#include "pddf_mux_defs.h" + + +static ssize_t do_device_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +extern void* get_device_table(char *name); +extern void delete_device_table(char *name); + + +MUX_DATA mux_data = {0}; + +/* MUX CLIENT DATA */ +PDDF_DATA_ATTR(virt_bus, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_HEX, sizeof(int), (void*)&mux_data.virt_bus, NULL); +PDDF_DATA_ATTR(dev_ops, S_IWUSR, NULL, do_device_operation, PDDF_CHAR, 8, (void*)&mux_data, (void*)&pddf_data); + + + +static struct attribute *mux_attributes[] = { + &attr_virt_bus.dev_attr.attr, + &attr_dev_ops.dev_attr.attr, + NULL +}; + +static const struct attribute_group pddf_mux_client_data_group = { + .attrs = mux_attributes, +}; + +struct i2c_board_info *i2c_get_mux_board_info(MUX_DATA* mdata, NEW_DEV_ATTR *device_data) +{ + static struct i2c_board_info board_info; + static struct pca954x_platform_mode platform_modes[8]; + static struct pca954x_platform_data mux_platform_data; + int num_modes, i; + + if (strncmp(device_data->dev_type, "pca9548", strlen("pca9548")) == 0) + num_modes = 8; + else if (strncmp(device_data->dev_type, "pca9546", strlen("pca9546")) == 0) + num_modes = 6; + else + { + printk(KERN_ERR "%s: Unknown type of mux device\n", __FUNCTION__); + return NULL; + } + + for(i = 0; i < num_modes; i++) { + platform_modes[i] = (struct pca954x_platform_mode) { + .adap_id = (mdata->virt_bus + i), + .deselect_on_exit = 1, + }; + } + + mux_platform_data = (struct pca954x_platform_data) { + .modes = platform_modes, + .num_modes = num_modes, + }; + + board_info = (struct i2c_board_info) { + .platform_data = &mux_platform_data, + }; + + board_info.addr = device_data->dev_addr; + strcpy(board_info.type, device_data->dev_type); + + return &board_info; +} + + +static ssize_t do_device_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + PDDF_ATTR *ptr = (PDDF_ATTR *)da; + MUX_DATA *mux_ptr = (MUX_DATA *)(ptr->addr); + NEW_DEV_ATTR *device_ptr = (NEW_DEV_ATTR *)(ptr->data); + struct i2c_adapter *adapter; + struct i2c_board_info *board_info; + struct i2c_client *client_ptr; + + if (strncmp(buf, "add", strlen(buf)-1)==0) + { + adapter = i2c_get_adapter(device_ptr->parent_bus); + board_info = i2c_get_mux_board_info(mux_ptr, device_ptr); + + client_ptr = i2c_new_device(adapter, board_info); + + if (client_ptr != NULL) + { + i2c_put_adapter(adapter); + pddf_dbg(MUX, KERN_ERR "Created %s client: 0x%p\n", device_ptr->i2c_name, (void *)client_ptr); + add_device_table(device_ptr->i2c_name, (void*)client_ptr); + } + else + { + i2c_put_adapter(adapter); + goto free_data; + } + } + else if (strncmp(buf, "delete", strlen(buf)-1)==0) + { + /*Get the i2c_client handle for the created client*/ + client_ptr = (struct i2c_client *)get_device_table(device_ptr->i2c_name); + if (client_ptr) + { + pddf_dbg(MUX, KERN_ERR "Removing %s client: 0x%p\n", device_ptr->i2c_name, (void *)client_ptr); + i2c_unregister_device(client_ptr); + /*TODO: Nullyfy the platform data*/ + delete_device_table(device_ptr->i2c_name); + } + else + { + printk(KERN_ERR "Unable to get the client handle for %s\n", device_ptr->i2c_name); + } + } + else + { + printk(KERN_ERR "PDDF_ERROR: %s: Invalid value for dev_ops %s", __FUNCTION__, buf); + } + +free_data: + memset(mux_ptr, 0, sizeof(MUX_DATA)); + /*TODO: free the device_ptr->data is dynamically allocated*/ + memset(device_ptr, 0 , sizeof(NEW_DEV_ATTR)); + + return count; +} + + +static struct kobject *mux_kobj; + +int __init mux_data_init(void) +{ + struct kobject *device_kobj; + int ret = 0; + + + pddf_dbg(MUX, "MUX_DATA MODULE.. init\n"); + + device_kobj = get_device_i2c_kobj(); + if(!device_kobj) + return -ENOMEM; + + mux_kobj = kobject_create_and_add("mux", device_kobj); + if(!mux_kobj) + return -ENOMEM; + + + ret = sysfs_create_group(mux_kobj, &pddf_clients_data_group); + if (ret) + { + kobject_put(mux_kobj); + return ret; + } + pddf_dbg(MUX, "CREATED PDDF I2C CLIENTS CREATION SYSFS GROUP\n"); + + ret = sysfs_create_group(mux_kobj, &pddf_mux_client_data_group); + if (ret) + { + sysfs_remove_group(mux_kobj, &pddf_clients_data_group); + kobject_put(mux_kobj); + return ret; + } + pddf_dbg(MUX, "CREATED MUX DATA SYSFS GROUP\n"); + + return ret; +} + +void __exit mux_data_exit(void) +{ + pddf_dbg(MUX, "MUX_DATA MODULE.. exit\n"); + sysfs_remove_group(mux_kobj, &pddf_mux_client_data_group); + sysfs_remove_group(mux_kobj, &pddf_clients_data_group); + kobject_put(mux_kobj); + pddf_dbg(MUX, KERN_ERR "%s: Removed the kobjects for 'mux'\n",__FUNCTION__); + return; +} + +module_init(mux_data_init); +module_exit(mux_data_exit); + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("mux platform data"); +MODULE_LICENSE("GPL"); diff --git a/platform/pddf/i2c/modules/psu/Makefile b/platform/pddf/i2c/modules/psu/Makefile new file mode 100644 index 000000000000..04db30dfb48b --- /dev/null +++ b/platform/pddf/i2c/modules/psu/Makefile @@ -0,0 +1,4 @@ +subdir-m := driver +obj-m := pddf_psu_module.o + +CFLAGS_$(obj-m):= -I$(M)/modules/include diff --git a/platform/pddf/i2c/modules/psu/driver/Makefile b/platform/pddf/i2c/modules/psu/driver/Makefile new file mode 100644 index 000000000000..86d508051382 --- /dev/null +++ b/platform/pddf/i2c/modules/psu/driver/Makefile @@ -0,0 +1,6 @@ +TARGET = pddf_psu_driver_module +obj-m := $(TARGET).o + +$(TARGET)-objs := pddf_psu_api.o pddf_psu_driver.o + +ccflags-y := -I$(M)/modules/include diff --git a/platform/pddf/i2c/modules/psu/driver/pddf_psu_api.c b/platform/pddf/i2c/modules/psu/driver/pddf_psu_api.c new file mode 100644 index 000000000000..b6b5e306a000 --- /dev/null +++ b/platform/pddf/i2c/modules/psu/driver/pddf_psu_api.c @@ -0,0 +1,707 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description of various APIs related to PSU component + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pddf_psu_defs.h" +#include "pddf_psu_driver.h" + + +/*#define PSU_DEBUG*/ +#ifdef PSU_DEBUG +#define psu_dbg(...) printk(__VA_ARGS__) +#else +#define psu_dbg(...) +#endif + + +void get_psu_duplicate_sysfs(int idx, char *str) +{ + switch (idx) + { + case PSU_V_OUT: + strcpy(str, "in3_input"); + break; + case PSU_I_OUT: + strcpy(str, "curr2_input"); + break; + case PSU_P_OUT: + strcpy(str, "power2_input"); + break; + case PSU_FAN1_SPEED: + strcpy(str, "fan1_input"); + break; + case PSU_TEMP1_INPUT: + strcpy(str, "temp1_input"); + break; + default: + break; + } + + return; +} + +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; +} + +int psu_update_hw(struct device *dev, struct psu_attr_info *info, PSU_DATA_ATTR *udata) +{ + int status = 0; + struct i2c_client *client = to_i2c_client(dev); + PSU_SYSFS_ATTR_DATA *sysfs_attr_data = NULL; + + + mutex_lock(&info->update_lock); + + sysfs_attr_data = udata->access_data; + if (sysfs_attr_data->pre_set != NULL) + { + status = (sysfs_attr_data->pre_set)(client, udata, info); + if (status!=0) + printk(KERN_ERR "%s: pre_set function fails for %s attribute\n", __FUNCTION__, udata->aname); + } + if (sysfs_attr_data->do_set != NULL) + { + status = (sysfs_attr_data->do_set)(client, udata, info); + if (status!=0) + printk(KERN_ERR "%s: do_set function fails for %s attribute\n", __FUNCTION__, udata->aname); + + } + if (sysfs_attr_data->post_set != NULL) + { + status = (sysfs_attr_data->post_set)(client, udata, info); + if (status!=0) + printk(KERN_ERR "%s: post_set function fails for %s attribute\n", __FUNCTION__, udata->aname); + } + + mutex_unlock(&info->update_lock); + + return 0; +} + + +int psu_update_attr(struct device *dev, struct psu_attr_info *data, PSU_DATA_ATTR *udata) +{ + int status = 0; + struct i2c_client *client = to_i2c_client(dev); + PSU_SYSFS_ATTR_DATA *sysfs_attr_data=NULL; + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || !data->valid) + { + dev_dbg(&client->dev, "Starting update for %s\n", data->name); + + sysfs_attr_data = udata->access_data; + if (sysfs_attr_data->pre_get != NULL) + { + status = (sysfs_attr_data->pre_get)(client, udata, data); + if (status!=0) + printk(KERN_ERR "%s: pre_get function fails for %s attribute\n", __FUNCTION__, udata->aname); + } + if (sysfs_attr_data->do_get != NULL) + { + status = (sysfs_attr_data->do_get)(client, udata, data); + if (status!=0) + printk(KERN_ERR "%s: do_get function fails for %s attribute\n", __FUNCTION__, udata->aname); + + } + if (sysfs_attr_data->post_get != NULL) + { + status = (sysfs_attr_data->post_get)(client, udata, data); + if (status!=0) + printk(KERN_ERR "%s: post_get function fails for %s attribute\n", __FUNCTION__, udata->aname); + } + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + return 0; +} + +ssize_t psu_show_default(struct device *dev, struct device_attribute *da, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct psu_data *data = i2c_get_clientdata(client); + PSU_PDATA *pdata = (PSU_PDATA *)(client->dev.platform_data); + PSU_DATA_ATTR *usr_data = NULL; + struct psu_attr_info *sysfs_attr_info = NULL; + int i, status=0; + u16 value = 0; + int exponent, mantissa; + int multiplier = 1000; + char new_str[ATTR_NAME_LEN] = ""; + PSU_SYSFS_ATTR_DATA *ptr = NULL; + + for (i=0;inum_attr;i++) + { + ptr = (PSU_SYSFS_ATTR_DATA *)pdata->psu_attrs[i].access_data; + get_psu_duplicate_sysfs(ptr->index , new_str); + if ( strcmp(attr->dev_attr.attr.name, pdata->psu_attrs[i].aname) == 0 || strcmp(attr->dev_attr.attr.name, new_str) == 0 ) + { + sysfs_attr_info = &data->attr_info[i]; + usr_data = &pdata->psu_attrs[i]; + strcpy(new_str, ""); + } + } + + if (sysfs_attr_info==NULL || usr_data==NULL) + { + printk(KERN_ERR "%s is not supported attribute for this client\n", attr->dev_attr.attr.name); + goto exit; + } + + psu_update_attr(dev, sysfs_attr_info, usr_data); + + switch(attr->index) + { + case PSU_PRESENT: + case PSU_POWER_GOOD: + status = sysfs_attr_info->val.intval; + return sprintf(buf, "%d\n", status); + break; + case PSU_MODEL_NAME: + case PSU_MFR_ID: + case PSU_SERIAL_NUM: + case PSU_FAN_DIR: + return sprintf(buf, "%s\n", sysfs_attr_info->val.strval); + break; + case PSU_V_OUT: + case PSU_I_OUT: + case PSU_V_IN: + case PSU_I_IN: + multiplier = 1000; + value = sysfs_attr_info->val.shortval; + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + if (exponent >= 0) + return sprintf(buf, "%d\n", (mantissa << exponent) * multiplier); + else + return sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); + + break; + case PSU_P_OUT: + multiplier = 1000000; + value = sysfs_attr_info->val.shortval; + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + if (exponent >= 0) + return sprintf(buf, "%d\n", (mantissa << exponent) * multiplier); + else + return sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); + + break; + case PSU_FAN1_SPEED: + value = sysfs_attr_info->val.shortval; + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + if (exponent >= 0) + return sprintf(buf, "%d\n", (mantissa << exponent)); + else + return sprintf(buf, "%d\n", (mantissa) / (1 << -exponent)); + + break; + case PSU_TEMP1_INPUT: + multiplier = 1000; + value = sysfs_attr_info->val.shortval; + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + if (exponent >= 0) + return sprintf(buf, "%d\n", (mantissa << exponent) * multiplier); + else + return sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); + + break; + default: + printk(KERN_ERR "%s: Unable to find attribute index for %s\n", __FUNCTION__, usr_data->aname); + goto exit; + } + +exit: + return sprintf(buf, "%d\n", status); +} + + +ssize_t psu_store_default(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct psu_data *data = i2c_get_clientdata(client); + PSU_PDATA *pdata = (PSU_PDATA *)(client->dev.platform_data); + PSU_DATA_ATTR *usr_data = NULL; + struct psu_attr_info *sysfs_attr_info = NULL; + int i; + + for (i=0;inum_attr;i++) + { + if (strcmp(data->attr_info[i].name, attr->dev_attr.attr.name) == 0 && strcmp(pdata->psu_attrs[i].aname, attr->dev_attr.attr.name) == 0) + { + sysfs_attr_info = &data->attr_info[i]; + usr_data = &pdata->psu_attrs[i]; + } + } + + if (sysfs_attr_info==NULL || usr_data==NULL) { + printk(KERN_ERR "%s is not supported attribute for this client\n", attr->dev_attr.attr.name); + goto exit; + } + + switch(attr->index) + { + /*No write attributes for now in PSU*/ + default: + goto exit; + } + + psu_update_hw(dev, sysfs_attr_info, usr_data); + +exit: + return count; +} + +int sonic_i2c_get_psu_present_default(void *client, PSU_DATA_ATTR *adata, void *data) +{ + int status = 0; + int val = 0; + struct psu_attr_info *padata = (struct psu_attr_info *)data; + + + if (strncmp(adata->devtype, "cpld", strlen("cpld")) == 0) + { + val = board_i2c_cpld_read(adata->devaddr , adata->offset); + if (val < 0) + return val; + padata->val.intval = ((val & adata->mask) == adata->cmpval); + psu_dbg(KERN_ERR "%s: status_value = 0x%x\n", __FUNCTION__, padata->val.intval); + } + + return status; +} + +int sonic_i2c_get_psu_power_good_default(void *client, PSU_DATA_ATTR *adata, void *data) +{ + int status = 0; + int val = 0; + struct psu_attr_info *padata = (struct psu_attr_info *)data; + + if (strncmp(adata->devtype, "cpld", strlen("cpld")) == 0) + { + val = board_i2c_cpld_read(adata->devaddr , adata->offset); + if (val < 0) + return val; + padata->val.intval = ((val & adata->mask) == adata->cmpval); + psu_dbg(KERN_ERR "%s: status_value = 0x%x\n", __FUNCTION__, padata->val.intval); + } + + return status; +} + +int sonic_i2c_get_psu_model_name_default(void *client, PSU_DATA_ATTR *adata, void *data) +{ + int status = 0, retry = 10; + struct psu_attr_info *padata = (struct psu_attr_info *)data; + char model[32]=""; //temporary placeholder for model name + uint8_t offset = (uint8_t)adata->offset; + int data_len = adata->len; + + while (retry) + { + status = i2c_smbus_read_i2c_block_data((struct i2c_client *)client, offset, data_len-1, model); + if (unlikely(status<0)) + { + msleep(60); + retry--; + continue; + } + break; + } + + if (status < 0) + { + model[0] = '\0'; + dev_dbg(&((struct i2c_client *)client)->dev, "unable to read model name from (0x%x)\n", ((struct i2c_client *)client)->addr); + } + else + { + model[data_len-1] = '\0'; + } + + if (strncmp(adata->devtype, "pmbus", strlen("pmbus")) == 0) + strncpy(padata->val.strval, model+1, data_len-1); + else + strncpy(padata->val.strval, model, data_len); + + psu_dbg(KERN_ERR "%s: status = %d, model_name : %s\n", __FUNCTION__, status, padata->val.strval); + return 0; +} + +int sonic_i2c_get_psu_mfr_id_default(void *client, PSU_DATA_ATTR *adata, void *data) +{ + + int status = 0, retry = 10; + struct psu_attr_info *padata = (struct psu_attr_info *)data; + char mfr_id[16] = ""; // temporary place holder for mfr_id + uint8_t offset = (uint8_t)adata->offset; + int data_len = adata->len; + + while (retry) + { + status = i2c_smbus_read_i2c_block_data((struct i2c_client *)client, offset, data_len-1, mfr_id); + if (unlikely(status<0)) + { + msleep(60); + retry--; + continue; + } + break; + } + + if (status < 0) + { + mfr_id[0] = '\0'; + dev_dbg(&((struct i2c_client *)client)->dev, "unable to read mfr_id from (0x%x)\n", ((struct i2c_client *)client)->addr); + } + else + { + mfr_id[data_len-1] = '\0'; + } + + if (strncmp(adata->devtype, "pmbus", strlen("pmbus")) == 0) + strncpy(padata->val.strval, mfr_id+1, data_len-1); + else + strncpy(padata->val.strval, mfr_id, data_len); + + psu_dbg(KERN_ERR "%s: status = %d, mfr_id : %s\n", __FUNCTION__, status, padata->val.strval); + return 0; +} + +int sonic_i2c_get_psu_serial_num_default(void *client, PSU_DATA_ATTR *adata, void *data) +{ + + int status = 0, retry = 10; + struct psu_attr_info *padata = (struct psu_attr_info *)data; + char serial[32] = ""; // temporary string to store the serial num + uint8_t offset = (uint8_t)adata->offset; + int data_len = adata->len; + + while (retry) + { + status = i2c_smbus_read_i2c_block_data((struct i2c_client *)client, offset, data_len-1, serial); + if (unlikely(status<0)) + { + msleep(60); + retry--; + continue; + } + break; + } + + if (status < 0) + { + serial[0] = '\0'; + dev_dbg(&((struct i2c_client *)client)->dev, "unable to read serial num from (0x%x)\n", ((struct i2c_client *)client)->addr); + } + else + { + serial[data_len-1] = '\0'; + } + + if (strncmp(adata->devtype, "pmbus", strlen("pmbus")) == 0) + strncpy(padata->val.strval, serial+1, data_len-1); + else + strncpy(padata->val.strval, serial, data_len); + + psu_dbg(KERN_ERR "%s: status = %d, serial_num : %s\n", __FUNCTION__, status, padata->val.strval); + return 0; +} + +int sonic_i2c_get_psu_fan_dir_default(void *client, PSU_DATA_ATTR *adata, void *data) +{ + + int status = 0, retry = 10; + struct psu_attr_info *padata = (struct psu_attr_info *)data; + char fan_dir[5] = ""; + uint8_t offset = (uint8_t)adata->offset; + int data_len = adata->len; + + while (retry) + { + status = i2c_smbus_read_i2c_block_data((struct i2c_client *)client, offset, data_len-1, fan_dir); + if (unlikely(status<0)) + { + msleep(60); + retry--; + continue; + } + break; + } + + if (status < 0) + { + fan_dir[0] = '\0'; + dev_dbg(&((struct i2c_client *)client)->dev, "unable to read fan_dir from (0x%x)\n", ((struct i2c_client *)client)->addr); + } + else + { + fan_dir[data_len-1] = '\0'; + } + + if (strncmp(adata->devtype, "pmbus", strlen("pmbus")) == 0) + strncpy(padata->val.strval, fan_dir+1, data_len-1); + else + strncpy(padata->val.strval, fan_dir, data_len); + + psu_dbg(KERN_ERR "%s: status = %d, fan_dir : %s\n", __FUNCTION__, status, padata->val.strval); + return 0; +} + +int sonic_i2c_get_psu_v_out_default(void *client, PSU_DATA_ATTR *adata, void *data) +{ + + int status = 0, retry = 10; + struct psu_attr_info *padata = (struct psu_attr_info *)data; + uint8_t offset = (uint8_t)adata->offset; + + while (retry) { + status = i2c_smbus_read_word_data((struct i2c_client *)client, offset); + if (unlikely(status < 0)) { + msleep(60); + retry--; + continue; + } + break; + } + + if (status < 0) + { + padata->val.shortval = 0; + dev_dbg(&((struct i2c_client *)client)->dev, "unable to read v_out from (0x%x)\n", ((struct i2c_client *)client)->addr); + } + else + { + padata->val.shortval = status; + } + + psu_dbg(KERN_ERR "%s: v_out : %d\n", __FUNCTION__, padata->val.shortval); + return 0; +} + +int sonic_i2c_get_psu_i_out_default(void *client, PSU_DATA_ATTR *adata, void *data) +{ + + int status = 0, retry = 10; + struct psu_attr_info *padata = (struct psu_attr_info *)data; + uint8_t offset = (uint8_t)adata->offset; + + while (retry) { + status = i2c_smbus_read_word_data((struct i2c_client *)client, offset); + if (unlikely(status < 0)) { + msleep(60); + retry--; + continue; + } + break; + } + + if (status < 0) + { + padata->val.shortval = 0; + dev_dbg(&((struct i2c_client *)client)->dev, "unable to read i_out from (0x%x)\n", ((struct i2c_client *)client)->addr); + } + else + { + padata->val.shortval = status; + } + + psu_dbg(KERN_ERR "%s: i_out : %d\n", __FUNCTION__, padata->val.shortval); + return 0; +} + +int sonic_i2c_get_psu_p_out_default(void *client, PSU_DATA_ATTR *adata, void *data) +{ + + int status = 0, retry = 10; + struct psu_attr_info *padata = (struct psu_attr_info *)data; + uint8_t offset = (uint8_t)adata->offset; + + while (retry) { + status = i2c_smbus_read_word_data((struct i2c_client *)client, offset); + if (unlikely(status < 0)) { + msleep(60); + retry--; + continue; + } + break; + } + + if (status < 0) + { + padata->val.shortval = 0; + dev_dbg(&((struct i2c_client *)client)->dev, "unable to read p_out from (0x%x)\n", ((struct i2c_client *)client)->addr); + } + else + { + padata->val.shortval = status; + } + + psu_dbg(KERN_ERR "%s: p_out : %d\n", __FUNCTION__, padata->val.shortval); + return 0; +} + +int sonic_i2c_get_psu_v_in_default(void *client, PSU_DATA_ATTR *adata, void *data) +{ + + int status = 0, retry = 10; + struct psu_attr_info *padata = (struct psu_attr_info *)data; + uint8_t offset = (uint8_t)adata->offset; + + while (retry) { + status = i2c_smbus_read_word_data((struct i2c_client *)client, offset); + if (unlikely(status < 0)) { + msleep(60); + retry--; + continue; + } + break; + } + + if (status < 0) + { + padata->val.shortval = 0; + dev_dbg(&((struct i2c_client *)client)->dev, "unable to read v_in from (0x%x)\n", ((struct i2c_client *)client)->addr); + } + else + { + padata->val.shortval = status; + } + + psu_dbg(KERN_ERR "%s: v_in : %d\n", __FUNCTION__, padata->val.shortval); + return 0; +} + +int sonic_i2c_get_psu_i_in_default(void *client, PSU_DATA_ATTR *adata, void *data) +{ + + int status = 0, retry = 10; + struct psu_attr_info *padata = (struct psu_attr_info *)data; + uint8_t offset = (uint8_t)adata->offset; + + while (retry) { + status = i2c_smbus_read_word_data((struct i2c_client *)client, offset); + if (unlikely(status < 0)) { + msleep(60); + retry--; + continue; + } + break; + } + + if (status < 0) + { + padata->val.shortval = 0; + dev_dbg(&((struct i2c_client *)client)->dev, "unable to read i_in from (0x%x)\n", ((struct i2c_client *)client)->addr); + } + else + { + padata->val.shortval = status; + } + + psu_dbg(KERN_ERR "%s: i_in : %d\n", __FUNCTION__, padata->val.shortval); + return 0; +} + +int sonic_i2c_get_psu_fan1_speed_rpm_default(void *client, PSU_DATA_ATTR *adata, void *data) +{ + + int status = 0, retry = 10; + struct psu_attr_info *padata = (struct psu_attr_info *)data; + uint8_t offset = (uint8_t)adata->offset; + + while (retry) { + status = i2c_smbus_read_word_data((struct i2c_client *)client, offset); + if (unlikely(status < 0)) { + msleep(60); + retry--; + continue; + } + break; + } + + if (status < 0) + { + padata->val.shortval = 0; + dev_dbg(&((struct i2c_client *)client)->dev, "unable to read fan1_speed_rpm from (0x%x)\n", ((struct i2c_client *)client)->addr); + } + else + { + padata->val.shortval = status; + } + + psu_dbg(KERN_ERR "%s: fan1_speed_rpm : %d\n", __FUNCTION__, padata->val.shortval); + return 0; +} + +int sonic_i2c_get_psu_temp1_input_default(void *client, PSU_DATA_ATTR *adata, void *data) +{ + + int status = 0, retry = 10; + struct psu_attr_info *padata = (struct psu_attr_info *)data; + uint8_t offset = (uint8_t)adata->offset; + + while (retry) { + status = i2c_smbus_read_word_data((struct i2c_client *)client, offset); + if (unlikely(status < 0)) { + msleep(60); + retry--; + continue; + } + break; + } + + if (status < 0) + { + padata->val.shortval = 0; + dev_dbg(&((struct i2c_client *)client)->dev, "unable to read temp1_input from (0x%x)\n", ((struct i2c_client *)client)->addr); + } + else + { + padata->val.shortval = status; + } + + psu_dbg(KERN_ERR "%s: temp1_input : %d\n", __FUNCTION__, padata->val.shortval); + return 0; +} diff --git a/platform/pddf/i2c/modules/psu/driver/pddf_psu_driver.c b/platform/pddf/i2c/modules/psu/driver/pddf_psu_driver.c new file mode 100644 index 000000000000..ad71e45eca20 --- /dev/null +++ b/platform/pddf/i2c/modules/psu/driver/pddf_psu_driver.c @@ -0,0 +1,381 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * A pddf kernel module driver for PSU + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pddf_client_defs.h" +#include "pddf_psu_defs.h" +#include "pddf_psu_driver.h" +#include "pddf_psu_api.h" + + +static unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +struct pddf_ops_t pddf_psu_ops = { + .pre_init = NULL, + .post_init = NULL, + + .pre_probe = NULL, + .post_probe = NULL, + + .pre_remove = NULL, + .post_remove = NULL, + + .pre_exit = NULL, + .post_exit = NULL, +}; +EXPORT_SYMBOL(pddf_psu_ops); + + +PSU_SYSFS_ATTR_DATA access_psu_present = {PSU_PRESENT, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_present_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_present); + +PSU_SYSFS_ATTR_DATA access_psu_model_name = {PSU_MODEL_NAME, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_model_name_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_model_name); + +PSU_SYSFS_ATTR_DATA access_psu_power_good = {PSU_POWER_GOOD, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_power_good_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_power_good); + +PSU_SYSFS_ATTR_DATA access_psu_mfr_id = {PSU_MFR_ID, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_mfr_id_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_mfr_id); + +PSU_SYSFS_ATTR_DATA access_psu_serial_num = {PSU_SERIAL_NUM, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_serial_num_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_serial_num); + +PSU_SYSFS_ATTR_DATA access_psu_fan_dir = {PSU_FAN_DIR, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_fan_dir_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_fan_dir); + +PSU_SYSFS_ATTR_DATA access_psu_v_out = {PSU_V_OUT, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_v_out_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_v_out); + +PSU_SYSFS_ATTR_DATA access_psu_i_out = {PSU_I_OUT, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_i_out_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_i_out); + +PSU_SYSFS_ATTR_DATA access_psu_p_out = {PSU_P_OUT, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_p_out_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_p_out); + +PSU_SYSFS_ATTR_DATA access_psu_fan1_speed_rpm = {PSU_FAN1_SPEED, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_fan1_speed_rpm_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_fan1_speed_rpm); + +PSU_SYSFS_ATTR_DATA access_psu_temp1_input = {PSU_TEMP1_INPUT, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_temp1_input_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_temp1_input); + +PSU_SYSFS_ATTR_DATA access_psu_v_in = {PSU_V_IN, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_v_in_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_v_in); + +PSU_SYSFS_ATTR_DATA access_psu_i_in = {PSU_I_IN, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_i_in_default, NULL, NULL, NULL, NULL, NULL}; +EXPORT_SYMBOL(access_psu_i_in); + + +PSU_SYSFS_ATTR_DATA_ENTRY psu_sysfs_attr_data_tbl[]= +{ + { "psu_present", &access_psu_present}, + { "psu_model_name", &access_psu_model_name}, + { "psu_power_good" , &access_psu_power_good}, + { "psu_mfr_id" , &access_psu_mfr_id}, + { "psu_serial_num" , &access_psu_serial_num}, + { "psu_fan_dir" , &access_psu_fan_dir}, + { "psu_v_out" , &access_psu_v_out}, + { "psu_i_out" , &access_psu_i_out}, + { "psu_p_out" , &access_psu_p_out}, + { "psu_fan1_speed_rpm" , &access_psu_fan1_speed_rpm}, + { "psu_temp1_input" , &access_psu_temp1_input}, + { "psu_v_in" , &access_psu_v_in}, + { "psu_i_in" , &access_psu_i_in} +}; + +void *get_psu_access_data(char *name) +{ + int i=0; + for(i=0; i<(sizeof(psu_sysfs_attr_data_tbl)/sizeof(psu_sysfs_attr_data_tbl[0])); i++) + { + if(strcmp(name, psu_sysfs_attr_data_tbl[i].name) ==0) + { + return &psu_sysfs_attr_data_tbl[i]; + } + } + return NULL; +} +EXPORT_SYMBOL(get_psu_access_data); + + +static int psu_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct psu_data *data; + int status =0; + int i,num, j=0; + PSU_PDATA *psu_platform_data; + PSU_DATA_ATTR *data_attr; + PSU_SYSFS_ATTR_DATA_ENTRY *sysfs_data_entry; + char new_str[ATTR_NAME_LEN] = ""; + + + if (client == NULL) { + printk("NULL Client.. \n"); + goto exit; + } + + if (pddf_psu_ops.pre_probe) + { + status = (pddf_psu_ops.pre_probe)(client, dev_id); + if (status != 0) + goto exit; + } + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct psu_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + dev_info(&client->dev, "chip found\n"); + + /* Take control of the platform data */ + psu_platform_data = (PSU_PDATA *)(client->dev.platform_data); + num = psu_platform_data->len; + data->index = psu_platform_data->idx - 1; + data->num_psu_fans = psu_platform_data->num_psu_fans; + data->num_attr = num; + + + + /* Create and Add supported attr in the 'attributes' list */ + for (i=0; ipsu_attrs + i; + sysfs_data_entry = get_psu_access_data(data_attr->aname); + if (sysfs_data_entry == NULL) + { + printk(KERN_ERR "%s: Wrong attribute name provided by user '%s'\n", __FUNCTION__, data_attr->aname); + continue; + } + + dy_ptr = (struct sensor_device_attribute *)kzalloc(sizeof(struct sensor_device_attribute)+ATTR_NAME_LEN, GFP_KERNEL); + dy_ptr->dev_attr.attr.name = (char *)&dy_ptr[1]; + strcpy((char *)dy_ptr->dev_attr.attr.name, data_attr->aname); + dy_ptr->dev_attr.attr.mode = sysfs_data_entry->a_ptr->mode; + dy_ptr->dev_attr.show = sysfs_data_entry->a_ptr->show; + dy_ptr->dev_attr.store = sysfs_data_entry->a_ptr->store; + dy_ptr->index = sysfs_data_entry->a_ptr->index; + + data->psu_attribute_list[i] = &dy_ptr->dev_attr.attr; + strcpy(data->attr_info[i].name, data_attr->aname); + data->attr_info[i].valid = 0; + mutex_init(&data->attr_info[i].update_lock); + + /*Create a duplicate entry*/ + get_psu_duplicate_sysfs(dy_ptr->index, new_str); + if (strcmp(new_str,"")) + { + dy_ptr = (struct sensor_device_attribute *)kzalloc(sizeof(struct sensor_device_attribute)+ATTR_NAME_LEN, GFP_KERNEL); + dy_ptr->dev_attr.attr.name = (char *)&dy_ptr[1]; + strcpy((char *)dy_ptr->dev_attr.attr.name, new_str); + dy_ptr->dev_attr.attr.mode = sysfs_data_entry->a_ptr->mode; + dy_ptr->dev_attr.show = sysfs_data_entry->a_ptr->show; + dy_ptr->dev_attr.store = sysfs_data_entry->a_ptr->store; + dy_ptr->index = sysfs_data_entry->a_ptr->index; + + data->psu_attribute_list[num+j] = &dy_ptr->dev_attr.attr; + j++; + strcpy(new_str,""); + } + } + data->psu_attribute_list[i+j] = NULL; + data->psu_attribute_group.attrs = data->psu_attribute_list; + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &data->psu_attribute_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", + dev_name(data->hwmon_dev), client->name); + + /* Add a support for post probe function */ + if (pddf_psu_ops.post_probe) + { + status = (pddf_psu_ops.post_probe)(client, dev_id); + if (status != 0) + goto exit_remove; + } + + return 0; + + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &data->psu_attribute_group); +exit_free: + /* Free all the allocated attributes */ + for (i=0;data->psu_attribute_list[i]!=NULL;i++) + { + struct sensor_device_attribute *ptr = (struct sensor_device_attribute *)data->psu_attribute_list[i]; + kfree(ptr); + data->psu_attribute_list[i] = NULL; + pddf_dbg(PSU, KERN_ERR "%s: Freed all the memory allocated for attributes\n", __FUNCTION__); + } + kfree(data); +exit: + return status; +} + +static int psu_remove(struct i2c_client *client) +{ + int i=0, ret = 0; + struct psu_data *data = i2c_get_clientdata(client); + PSU_PDATA *platdata = (PSU_PDATA *)client->dev.platform_data; // use dev_get_platdata() + PSU_DATA_ATTR *platdata_sub = platdata->psu_attrs; + struct sensor_device_attribute *ptr = NULL; + + if (pddf_psu_ops.pre_remove) + { + ret = (pddf_psu_ops.pre_remove)(client); + if (ret!=0) + printk(KERN_ERR "FAN pre_remove function failed\n"); + } + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &data->psu_attribute_group); + for (i=0; data->psu_attribute_list[i]!=NULL; i++) + { + ptr = (struct sensor_device_attribute *)data->psu_attribute_list[i]; + kfree(ptr); + data->psu_attribute_list[i] = NULL; + } + pddf_dbg(PSU, KERN_ERR "%s: Freed all the memory allocated for attributes\n", __FUNCTION__); + kfree(data); + if (platdata_sub) { + printk(KERN_DEBUG "%s: Freeing platform subdata\n", __FUNCTION__); + kfree(platdata_sub); + } + if (platdata) { + printk(KERN_DEBUG "%s: Freeing platform data\n", __FUNCTION__); + kfree(platdata); + } + + if (pddf_psu_ops.post_remove) + { + ret = (pddf_psu_ops.post_remove)(client); + if (ret!=0) + printk(KERN_ERR "FAN post_remove function failed\n"); + } + + return ret; +} + +enum psu_intf +{ + eeprom_intf, + smbus_intf +}; + +static const struct i2c_device_id psu_id[] = { + {"psu_eeprom", eeprom_intf}, + {"psu_pmbus", smbus_intf}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, psu_id); + +static struct i2c_driver psu_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "psu", + }, + .probe = psu_probe, + .remove = psu_remove, + .id_table = psu_id, + .address_list = normal_i2c, +}; + +int example_fun(void) +{ + pddf_dbg(PSU, KERN_ERR "CALLING FUN...\n"); + return 0; +} +EXPORT_SYMBOL(example_fun); + + +int psu_init(void) +{ + int status = 0; + + if (pddf_psu_ops.pre_init) + { + status = (pddf_psu_ops.pre_init)(); + if (status!=0) + return status; + } + + pddf_dbg(PSU, KERN_ERR "GENERIC_PSU_DRIVER.. init Invoked..\n"); + status = i2c_add_driver(&psu_driver); + if (status!=0) + return status; + + if (pddf_psu_ops.post_init) + { + status = (pddf_psu_ops.post_init)(); + if (status!=0) + return status; + } + + return status; +} +EXPORT_SYMBOL(psu_init); + +void __exit psu_exit(void) +{ + pddf_dbg(PSU, "GENERIC_PSU_DRIVER.. exit\n"); + if (pddf_psu_ops.pre_exit) (pddf_psu_ops.pre_exit)(); + i2c_del_driver(&psu_driver); + if (pddf_psu_ops.post_exit) (pddf_psu_ops.post_exit)(); +} +EXPORT_SYMBOL(psu_exit); + +module_init(psu_init); +module_exit(psu_exit); + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("psu driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/pddf/i2c/modules/psu/pddf_psu_module.c b/platform/pddf/i2c/modules/psu/pddf_psu_module.c new file mode 100644 index 000000000000..cf9713b407cd --- /dev/null +++ b/platform/pddf/i2c/modules/psu/pddf_psu_module.c @@ -0,0 +1,283 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * A pddf kernel module to create I2C client for PSU + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pddf_client_defs.h" +#include "pddf_psu_defs.h" + + +static ssize_t do_attr_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t do_device_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +extern void *get_psu_access_data(char *); +extern void* get_device_table(char *name); +extern void delete_device_table(char *name); + +PSU_DATA psu_data = {0}; + + + +/* PSU CLIENT DATA */ +PDDF_DATA_ATTR(psu_idx, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_DEC, sizeof(int), (void*)&psu_data.idx, NULL); +PDDF_DATA_ATTR(psu_fans, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_DEC, sizeof(int), (void*)&psu_data.num_psu_fans, NULL); + +PDDF_DATA_ATTR(attr_name, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_CHAR, 32, (void*)&psu_data.psu_attr.aname, NULL); +PDDF_DATA_ATTR(attr_devtype, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_CHAR, 8, (void*)&psu_data.psu_attr.devtype, NULL); +PDDF_DATA_ATTR(attr_devname, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_CHAR, 8, (void*)&psu_data.psu_attr.devname, NULL); +PDDF_DATA_ATTR(attr_devaddr, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UINT32, sizeof(uint32_t), (void*)&psu_data.psu_attr.devaddr, NULL); +PDDF_DATA_ATTR(attr_offset, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UINT32, sizeof(uint32_t), (void*)&psu_data.psu_attr.offset, NULL); +PDDF_DATA_ATTR(attr_mask, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UINT32, sizeof(uint32_t), (void*)&psu_data.psu_attr.mask, NULL); +PDDF_DATA_ATTR(attr_cmpval, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UINT32, sizeof(uint32_t), (void*)&psu_data.psu_attr.cmpval, NULL); +PDDF_DATA_ATTR(attr_len, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_DEC, sizeof(int), (void*)&psu_data.psu_attr.len, NULL); +PDDF_DATA_ATTR(attr_ops, S_IWUSR, NULL, do_attr_operation, PDDF_CHAR, 8, (void*)&psu_data, NULL); +PDDF_DATA_ATTR(dev_ops, S_IWUSR, NULL, do_device_operation, PDDF_CHAR, 8, (void*)&psu_data, (void*)&pddf_data); + + + +static struct attribute *psu_attributes[] = { + &attr_psu_idx.dev_attr.attr, + &attr_psu_fans.dev_attr.attr, + + &attr_attr_name.dev_attr.attr, + &attr_attr_devtype.dev_attr.attr, + &attr_attr_devname.dev_attr.attr, + &attr_attr_devaddr.dev_attr.attr, + &attr_attr_offset.dev_attr.attr, + &attr_attr_mask.dev_attr.attr, + &attr_attr_cmpval.dev_attr.attr, + &attr_attr_len.dev_attr.attr, + &attr_attr_ops.dev_attr.attr, + &attr_dev_ops.dev_attr.attr, + NULL +}; + +static const struct attribute_group pddf_psu_client_data_group = { + .attrs = psu_attributes, +}; + + +static ssize_t do_attr_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + PDDF_ATTR *ptr = (PDDF_ATTR *)da; + PSU_DATA *pdata = (PSU_DATA *)(ptr->addr); + PSU_SYSFS_ATTR_DATA_ENTRY *access_ptr; + + + pdata->psu_attrs[pdata->len] = pdata->psu_attr; + access_ptr = get_psu_access_data(pdata->psu_attrs[pdata->len].aname); + if (access_ptr != NULL && access_ptr->a_ptr != NULL) + { + pdata->psu_attrs[pdata->len].access_data = access_ptr->a_ptr ; + } + + + pdata->len++; + memset(&pdata->psu_attr, 0, sizeof(pdata->psu_attr)); + + + return count; +} + +struct i2c_board_info *i2c_get_psu_board_info(PSU_DATA *pdata, NEW_DEV_ATTR *cdata) +{ + int num = pdata->len; + int i = 0; + static struct i2c_board_info board_info; + PSU_PDATA *psu_platform_data; + + + if (strcmp(cdata->dev_type, "psu_pmbus")==0 || strcmp(cdata->dev_type, "psu_eeprom")==0 ) + { + /* Allocate the psu_platform_data */ + psu_platform_data = (PSU_PDATA *)kzalloc(sizeof(PSU_PDATA), GFP_KERNEL); + psu_platform_data->psu_attrs = (PSU_DATA_ATTR *)kzalloc(num*sizeof(PSU_DATA_ATTR), GFP_KERNEL); + + + psu_platform_data->idx = pdata->idx; + psu_platform_data->num_psu_fans = pdata->num_psu_fans; + psu_platform_data->len = pdata->len; + + for (i=0;ipsu_attrs[i] = pdata->psu_attrs[i]; + } + + board_info = (struct i2c_board_info) { + .platform_data = psu_platform_data, + }; + + board_info.addr = cdata->dev_addr; + strcpy(board_info.type, cdata->dev_type); + } + else + { + printk(KERN_ERR "%s:Unknown type of device %s. Unable to clreate I2C client for it\n",__FUNCTION__, cdata->dev_type); + } + + return &board_info; +} + + +static ssize_t do_device_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + PDDF_ATTR *ptr = (PDDF_ATTR *)da; + PSU_DATA *pdata = (PSU_DATA *)(ptr->addr); + NEW_DEV_ATTR *cdata = (NEW_DEV_ATTR *)(ptr->data); + struct i2c_adapter *adapter; + struct i2c_board_info *board_info; + struct i2c_client *client_ptr; + + + if (strncmp(buf, "add", strlen(buf)-1)==0) + { + adapter = i2c_get_adapter(cdata->parent_bus); + board_info = i2c_get_psu_board_info(pdata, cdata); + + /* Populate the platform data for psu */ + client_ptr = i2c_new_device(adapter, board_info); + + if(client_ptr != NULL) + { + i2c_put_adapter(adapter); + pddf_dbg(PSU, KERN_ERR "Created a %s client: 0x%p\n", cdata->i2c_name , (void *)client_ptr); + add_device_table(cdata->i2c_name, (void*)client_ptr); + } + else + { + i2c_put_adapter(adapter); + goto free_data; + } + } + else if (strncmp(buf, "delete", strlen(buf)-1)==0) + { + /*Get the i2c_client handle for the created client*/ + client_ptr = (struct i2c_client *)get_device_table(cdata->i2c_name); + if (client_ptr) + { + pddf_dbg(PSU, KERN_ERR "Removing %s client: 0x%p\n", cdata->i2c_name, (void *)client_ptr); + i2c_unregister_device(client_ptr); + delete_device_table(cdata->i2c_name); + } + else + { + printk(KERN_ERR "Unable to get the client handle for %s\n", cdata->i2c_name); + } + + } + else + { + printk(KERN_ERR "PDDF_ERROR: %s: Invalid value for dev_ops %s", __FUNCTION__, buf); + } + + goto clear_data; + +free_data: + if (board_info->platform_data) + { + PSU_PDATA *psu_platform_data = board_info->platform_data; + if (psu_platform_data->psu_attrs) + { + printk(KERN_ERR "%s: Unable to create i2c client. Freeing the platform subdata\n", __FUNCTION__); + kfree(psu_platform_data->psu_attrs); + } + printk(KERN_ERR "%s: Unable to create i2c client. Freeing the platform data\n", __FUNCTION__); + kfree(psu_platform_data); + } + +clear_data: + memset(pdata, 0, sizeof(PSU_DATA)); + /*TODO: free the data cdata->data if data is dynal=mically allocated*/ + memset(cdata, 0, sizeof(NEW_DEV_ATTR)); + return count; +} + + +static struct kobject *psu_kobj; +static struct kobject *i2c_kobj; + +int __init pddf_data_init(void) +{ + struct kobject *device_kobj; + int ret = 0; + + + pddf_dbg(PSU, "PDDF_DATA MODULE.. init\n"); + + device_kobj = get_device_i2c_kobj(); + if(!device_kobj) + return -ENOMEM; + + psu_kobj = kobject_create_and_add("psu", device_kobj); + if(!psu_kobj) + return -ENOMEM; + i2c_kobj = kobject_create_and_add("i2c", psu_kobj); + if(!i2c_kobj) + return -ENOMEM; + + ret = sysfs_create_group(i2c_kobj, &pddf_clients_data_group); + if (ret) + { + kobject_put(i2c_kobj); + kobject_put(psu_kobj); + return ret; + } + pddf_dbg(PSU, "CREATED PSU I2C CLIENTS CREATION SYSFS GROUP\n"); + + ret = sysfs_create_group(i2c_kobj, &pddf_psu_client_data_group); + if (ret) + { + sysfs_remove_group(i2c_kobj, &pddf_clients_data_group); + kobject_put(i2c_kobj); + kobject_put(psu_kobj); + return ret; + } + pddf_dbg(PSU, "CREATED PDDF PSU DATA SYSFS GROUP\n"); + + return ret; +} + +void __exit pddf_data_exit(void) +{ + + pddf_dbg(PSU, "PDDF_DATA MODULE.. exit\n"); + sysfs_remove_group(i2c_kobj, &pddf_psu_client_data_group); + sysfs_remove_group(i2c_kobj, &pddf_clients_data_group); + kobject_put(i2c_kobj); + kobject_put(psu_kobj); + pddf_dbg(PSU, KERN_ERR "%s: Removed the kobjects for 'i2c' and 'psu'\n",__FUNCTION__); + + return; +} + +module_init(pddf_data_init); +module_exit(pddf_data_exit); + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("psu platform data"); +MODULE_LICENSE("GPL"); diff --git a/platform/pddf/i2c/modules/sysstatus/Makefile b/platform/pddf/i2c/modules/sysstatus/Makefile new file mode 100644 index 000000000000..150d160eae15 --- /dev/null +++ b/platform/pddf/i2c/modules/sysstatus/Makefile @@ -0,0 +1,4 @@ +TARGET := pddf_sysstatus_module +obj-m := $(TARGET).o + +CFLAGS_$(obj-m):= -I$(M)/modules/include diff --git a/platform/pddf/i2c/modules/sysstatus/pddf_sysstatus_module.c b/platform/pddf/i2c/modules/sysstatus/pddf_sysstatus_module.c new file mode 100644 index 000000000000..bd892d924265 --- /dev/null +++ b/platform/pddf/i2c/modules/sysstatus/pddf_sysstatus_module.c @@ -0,0 +1,235 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * A pddf kernel module for system status registers + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pddf_client_defs.h" +#include "pddf_sysstatus_defs.h" + + + +SYSSTATUS_DATA sysstatus_data = {0}; + +extern int board_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int board_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +static ssize_t do_attr_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +ssize_t show_sysstatus_data(struct device *dev, struct device_attribute *da, char *buf); + + +PDDF_DATA_ATTR(attr_name, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_CHAR, 32, + (void*)&sysstatus_data.sysstatus_addr_attr.aname, NULL); +PDDF_DATA_ATTR(attr_devaddr, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UINT32, + sizeof(uint32_t), (void*)&sysstatus_data.sysstatus_addr_attr.devaddr , NULL); +PDDF_DATA_ATTR(attr_offset, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UINT32, + sizeof(uint32_t), (void*)&sysstatus_data.sysstatus_addr_attr.offset, NULL); +PDDF_DATA_ATTR(attr_mask, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UINT32, + sizeof(uint32_t), (void*)&sysstatus_data.sysstatus_addr_attr.mask , NULL); +PDDF_DATA_ATTR(attr_len, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UINT32, + sizeof(uint32_t), (void*)&sysstatus_data.sysstatus_addr_attr.len , NULL); +PDDF_DATA_ATTR(attr_ops, S_IWUSR, NULL, do_attr_operation, PDDF_CHAR, 8, (void*)&sysstatus_data, NULL); + + + +static struct attribute *sysstatus_addr_attributes[] = { + &attr_attr_name.dev_attr.attr, + &attr_attr_devaddr.dev_attr.attr, + &attr_attr_offset.dev_attr.attr, + &attr_attr_mask.dev_attr.attr, + &attr_attr_len.dev_attr.attr, + &attr_attr_ops.dev_attr.attr, + NULL +}; + +PDDF_DATA_ATTR(board_info, S_IWUSR|S_IRUGO, show_sysstatus_data, NULL, PDDF_UINT32, 32, NULL, NULL); +PDDF_DATA_ATTR(cpld1_version, S_IWUSR|S_IRUGO, show_sysstatus_data, NULL, PDDF_UINT32, sizeof(uint32_t), NULL, NULL); +PDDF_DATA_ATTR(cpld2_version, S_IWUSR|S_IRUGO, show_sysstatus_data, NULL, PDDF_UINT32, sizeof(uint32_t), NULL, NULL); +PDDF_DATA_ATTR(cpld3_version, S_IWUSR|S_IRUGO, show_sysstatus_data, NULL, PDDF_UINT32, sizeof(uint32_t), NULL, NULL); +PDDF_DATA_ATTR(power_module_status, S_IWUSR|S_IRUGO, show_sysstatus_data, NULL, PDDF_UINT32, sizeof(uint32_t), NULL, NULL); +PDDF_DATA_ATTR(system_reset1, S_IWUSR|S_IRUGO, show_sysstatus_data, NULL, PDDF_UINT32, sizeof(uint32_t), NULL, NULL); +PDDF_DATA_ATTR(system_reset2, S_IWUSR|S_IRUGO, show_sysstatus_data, NULL, PDDF_UINT32, sizeof(uint32_t), NULL, NULL); +PDDF_DATA_ATTR(system_reset3, S_IWUSR|S_IRUGO, show_sysstatus_data, NULL, PDDF_UINT32, sizeof(uint32_t), NULL, NULL); +PDDF_DATA_ATTR(system_reset4, S_IWUSR|S_IRUGO, show_sysstatus_data, NULL, PDDF_UINT32, sizeof(uint32_t), NULL, NULL); +PDDF_DATA_ATTR(system_reset5, S_IWUSR|S_IRUGO, show_sysstatus_data, NULL, PDDF_UINT32, sizeof(uint32_t), NULL, NULL); +PDDF_DATA_ATTR(system_reset6, S_IWUSR|S_IRUGO, show_sysstatus_data, NULL, PDDF_UINT32, sizeof(uint32_t), NULL, NULL); +PDDF_DATA_ATTR(system_reset7, S_IWUSR|S_IRUGO, show_sysstatus_data, NULL, PDDF_UINT32, sizeof(uint32_t), NULL, NULL); +PDDF_DATA_ATTR(system_reset8, S_IWUSR|S_IRUGO, show_sysstatus_data, NULL, PDDF_UINT32, sizeof(uint32_t), NULL, NULL); +PDDF_DATA_ATTR(misc1, S_IWUSR|S_IRUGO, show_sysstatus_data, NULL, PDDF_UINT32, sizeof(uint32_t), NULL, NULL); +PDDF_DATA_ATTR(misc2, S_IWUSR|S_IRUGO, show_sysstatus_data, NULL, PDDF_UINT32, sizeof(uint32_t), NULL, NULL); +PDDF_DATA_ATTR(misc3, S_IWUSR|S_IRUGO, show_sysstatus_data, NULL, PDDF_UINT32, sizeof(uint32_t), NULL, NULL); + + + +static struct attribute *sysstatus_data_attributes[] = { + &attr_board_info.dev_attr.attr, + &attr_cpld1_version.dev_attr.attr, + &attr_cpld2_version.dev_attr.attr, + &attr_cpld3_version.dev_attr.attr, + &attr_power_module_status.dev_attr.attr, + &attr_system_reset1.dev_attr.attr, + &attr_system_reset2.dev_attr.attr, + &attr_system_reset3.dev_attr.attr, + &attr_system_reset4.dev_attr.attr, + &attr_system_reset5.dev_attr.attr, + &attr_system_reset6.dev_attr.attr, + &attr_system_reset7.dev_attr.attr, + &attr_system_reset8.dev_attr.attr, + &attr_misc1.dev_attr.attr, + &attr_misc2.dev_attr.attr, + &attr_misc3.dev_attr.attr, + NULL +}; + + + +static const struct attribute_group pddf_sysstatus_addr_group = { + .attrs = sysstatus_addr_attributes, +}; + + +static const struct attribute_group pddf_sysstatus_data_group = { + .attrs = sysstatus_data_attributes, +}; + + +static struct kobject *sysstatus_addr_kobj; +static struct kobject *sysstatus_data_kobj; + + + +ssize_t show_sysstatus_data(struct device *dev, struct device_attribute *da, char *buf) +{ + + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + SYSSTATUS_DATA *data = &sysstatus_data; + struct SYSSTATUS_ADDR_ATTR *sysstatus_addr_attrs = NULL; + int i, status ; + + + for (i=0;isysstatus_addr_attrs[i].aname, attr->dev_attr.attr.name) == 0 ) + { + sysstatus_addr_attrs = &data->sysstatus_addr_attrs[i]; + + } + } + + if (sysstatus_addr_attrs==NULL ) + { + printk(KERN_DEBUG "%s is not supported attribute for this client\n",data->sysstatus_addr_attrs[i].aname); + status = 0; + } + else + { + status = board_i2c_cpld_read( sysstatus_addr_attrs->devaddr, sysstatus_addr_attrs->offset); + } + + return sprintf(buf, "0x%x\n", (status&sysstatus_addr_attrs->mask)); + +} + + + +static ssize_t do_attr_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + PDDF_ATTR *ptr = (PDDF_ATTR *)da; + SYSSTATUS_DATA *pdata = (SYSSTATUS_DATA *)(ptr->addr); + + pdata->sysstatus_addr_attrs[pdata->len] = pdata->sysstatus_addr_attr; + pdata->len++; + pddf_dbg(SYSSTATUS, KERN_ERR "%s: Populating the data for %s\n", __FUNCTION__, pdata->sysstatus_addr_attr.aname); + memset(&pdata->sysstatus_addr_attr, 0, sizeof(pdata->sysstatus_addr_attr)); + + + return count; +} + + + + +int __init sysstatus_data_init(void) +{ + struct kobject *device_kobj; + int ret = 0; + + + pddf_dbg(SYSSTATUS, "PDDF SYSSTATUS MODULE.. init\n"); + + device_kobj = get_device_i2c_kobj(); + if(!device_kobj) + return -ENOMEM; + + sysstatus_addr_kobj = kobject_create_and_add("sysstatus", device_kobj); + if(!sysstatus_addr_kobj) + return -ENOMEM; + + sysstatus_data_kobj = kobject_create_and_add("sysstatus_data", sysstatus_addr_kobj); + if(!sysstatus_data_kobj) + return -ENOMEM; + + + ret = sysfs_create_group(sysstatus_addr_kobj, &pddf_sysstatus_addr_group); + if (ret) + { + kobject_put(sysstatus_addr_kobj); + return ret; + } + + ret = sysfs_create_group(sysstatus_data_kobj, &pddf_sysstatus_data_group); + if (ret) + { + sysfs_remove_group(sysstatus_addr_kobj, &pddf_sysstatus_addr_group); + kobject_put(sysstatus_data_kobj); + kobject_put(sysstatus_addr_kobj); + return ret; + } + + + return ret; +} + +void __exit sysstatus_data_exit(void) +{ + pddf_dbg(SYSSTATUS, "PDDF SYSSTATUS MODULE.. exit\n"); + sysfs_remove_group(sysstatus_data_kobj, &pddf_sysstatus_data_group); + sysfs_remove_group(sysstatus_addr_kobj, &pddf_sysstatus_addr_group); + kobject_put(sysstatus_data_kobj); + kobject_put(sysstatus_addr_kobj); + pddf_dbg(SYSSTATUS, KERN_ERR "%s: Removed the kobjects for 'SYSSTATUS'\n",__FUNCTION__); + return; +} + +module_init(sysstatus_data_init); +module_exit(sysstatus_data_exit); + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("SYSSTATUS platform data"); +MODULE_LICENSE("GPL"); diff --git a/platform/pddf/i2c/modules/xcvr/Makefile b/platform/pddf/i2c/modules/xcvr/Makefile new file mode 100644 index 000000000000..e72ad6b44233 --- /dev/null +++ b/platform/pddf/i2c/modules/xcvr/Makefile @@ -0,0 +1,4 @@ +subdir-m := driver +obj-m := pddf_xcvr_module.o + +CFLAGS_$(obj-m):= -I$(M)/modules/include diff --git a/platform/pddf/i2c/modules/xcvr/driver/Makefile b/platform/pddf/i2c/modules/xcvr/driver/Makefile new file mode 100644 index 000000000000..0b381d1fc2fe --- /dev/null +++ b/platform/pddf/i2c/modules/xcvr/driver/Makefile @@ -0,0 +1,7 @@ +TARGET = pddf_xcvr_driver_module + +obj-m := $(TARGET).o + +$(TARGET)-objs := pddf_xcvr_api.o pddf_xcvr_driver.o + +ccflags-y := -I$(M)/modules/include diff --git a/platform/pddf/i2c/modules/xcvr/driver/pddf_xcvr_api.c b/platform/pddf/i2c/modules/xcvr/driver/pddf_xcvr_api.c new file mode 100644 index 000000000000..ddb7a1b3a2b3 --- /dev/null +++ b/platform/pddf/i2c/modules/xcvr/driver/pddf_xcvr_api.c @@ -0,0 +1,909 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Description of various APIs related to transciever component + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pddf_xcvr_defs.h" + +/*#define SFP_DEBUG*/ +#ifdef SFP_DEBUG +#define sfp_dbg(...) printk(__VA_ARGS__) +#else +#define sfp_dbg(...) +#endif + +extern XCVR_SYSFS_ATTR_OPS xcvr_ops[]; +extern void *get_device_table(char *name); + +int get_xcvr_module_attr_data(struct i2c_client *client, struct device *dev, + struct device_attribute *da); + +int xcvr_i2c_cpld_read(XCVR_ATTR *info) +{ + int status = -1; + + if (info!=NULL) + { + if (info->len==1) + { + status = board_i2c_cpld_read(info->devaddr , info->offset); + } + else + { + /* Get the I2C client for the CPLD */ + struct i2c_client *client_ptr=NULL; + client_ptr = (struct i2c_client *)get_device_table(info->devname); + if (client_ptr) + { + if (info->len==2) + { + status = i2c_smbus_read_word_swapped(client_ptr, info->offset); + } + else + printk(KERN_ERR "PDDF_XCVR: Doesn't support block CPLD read yet"); + } + else + printk(KERN_ERR "Unable to get the client handle for %s\n", info->devname); + } + + } + + return status; +} + +int sonic_i2c_get_mod_pres(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data) +{ + int status = 0; + uint32_t modpres = 0; + + if ( strcmp(info->devtype, "cpld") == 0) + { + status = xcvr_i2c_cpld_read(info); + + if (status < 0) + return status; + else + { + modpres = ((status & BIT_INDEX(info->mask)) == info->cmpval) ? 1 : 0; + sfp_dbg(KERN_INFO "\nMod presence :0x%x, reg_value = 0x%x, devaddr=0x%x, mask=0x%x, offset=0x%x\n", modpres, status, info->devaddr, info->mask, info->offset); + } + } + else if(strcmp(info->devtype, "eeprom") == 0) + { + /* get client client for eeprom - Not Applicable */ + } + data->modpres = modpres; + + return 0; +} + +int sonic_i2c_get_mod_reset(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data) +{ + int status = 0; + uint32_t modreset=0; + + if (strcmp(info->devtype, "cpld") == 0) + { + status = xcvr_i2c_cpld_read(info); + if (status < 0) + return status; + else + { + modreset = ((status & BIT_INDEX(info->mask)) == info->cmpval) ? 1 : 0; + sfp_dbg(KERN_INFO "\nMod Reset :0x%x, reg_value = 0x%x\n", modreset, status); + } + } + else if(strcmp(info->devtype, "eeprom") == 0) + { + /* get client client for eeprom - Not Applicable */ + } + + data->reset = modreset; + return 0; +} + +int sonic_i2c_get_mod_intr_status(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data) +{ + int status = 0; + uint32_t mod_intr = 0; + + if (strcmp(info->devtype, "cpld") == 0) + { + status = xcvr_i2c_cpld_read(info); + if (status < 0) + return status; + else + { + mod_intr = ((status & BIT_INDEX(info->mask)) == info->cmpval) ? 1 : 0; + sfp_dbg(KERN_INFO "\nModule Interrupt :0x%x, reg_value = 0x%x\n", mod_intr, status); + } + } + else if(strcmp(info->devtype, "eeprom") == 0) + { + /* get client client for eeprom - Not Applicable */ + } + + data->intr_status = mod_intr; + return 0; +} + + +int sonic_i2c_get_mod_lpmode(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data) +{ + int status = 0; + uint32_t lpmode = 0; + + if (strcmp(info->devtype, "cpld") == 0) + { + status = xcvr_i2c_cpld_read(info); + if (status < 0) + return status; + else + { + lpmode = ((status & BIT_INDEX(info->mask)) == info->cmpval) ? 1 : 0; + sfp_dbg(KERN_INFO "\nModule LPmode :0x%x, reg_value = 0x%x\n", lpmode, status); + } + } + else if (strcmp(info->devtype, "eeprom") == 0) + { + /* get client client for eeprom - Not Applicable */ + } + + data->lpmode = lpmode; + return 0; +} + +int sonic_i2c_get_mod_rxlos(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data) +{ + int status = 0; + uint32_t rxlos = 0; + + + if (strcmp(info->devtype, "cpld") == 0) + { + status = xcvr_i2c_cpld_read(info); + if (status < 0) + return status; + else + { + rxlos = ((status & BIT_INDEX(info->mask)) == info->cmpval) ? 1 : 0; + sfp_dbg(KERN_INFO "\nModule RxLOS :0x%x, reg_value = 0x%x\n", rxlos, status); + } + } + data->rxlos = rxlos; + + return 0; +} + +int sonic_i2c_get_mod_txdisable(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data) +{ + int status = 0; + uint32_t txdis = 0; + + if (strcmp(info->devtype, "cpld") == 0) + { + status = xcvr_i2c_cpld_read(info); + if (status < 0) + return status; + else + { + txdis = ((status & BIT_INDEX(info->mask)) == info->cmpval) ? 1 : 0; + sfp_dbg(KERN_INFO "\nModule TxDisable :0x%x, reg_value = 0x%x\n", txdis, status); + } + } + data->txdisable = txdis; + + return 0; +} + +int sonic_i2c_get_mod_txfault(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data) +{ + int status = 0; + uint32_t txflt = 0; + + if (strcmp(info->devtype, "cpld") == 0) + { + status = xcvr_i2c_cpld_read(info); + if (status < 0) + return status; + else + { + txflt = ((status & BIT_INDEX(info->mask)) == info->cmpval) ? 1 : 0; + sfp_dbg(KERN_INFO "\nModule TxFault :0x%x, reg_value = 0x%x\n", txflt, status); + } + + } + data->txfault = txflt; + + return 0; +} + +int sonic_i2c_set_mod_reset(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data) +{ + int status = 0; + unsigned int val_mask = 0, dnd_value = 0; + uint32_t reg; + struct i2c_client *client_ptr=NULL; + + if (strcmp(info->devtype, "cpld") == 0) + { + val_mask = BIT_INDEX(info->mask); + /* Get the I2C client for the CPLD */ + client_ptr = (struct i2c_client *)get_device_table(info->devname); + + if (client_ptr) + { + if (info->len == 1) + status = board_i2c_cpld_read(info->devaddr , info->offset); + else if (info->len == 2) + status = i2c_smbus_read_word_data(client_ptr, info->offset); + else + { + printk(KERN_ERR "PDDF_XCVR: Doesn't support block CPLD read yet"); + status = -1; + } + } + else + { + printk(KERN_ERR "Unable to get the client handle for %s\n", info->devname); + status = -1; + } + /*printk(KERN_ERR "sonic_i2c_set_mod_reset:client_ptr=0x%x, status=0x%x, offset=0x%x, len=%d\n", client_ptr, status, info->offset, info->len);*/ + + if (status < 0) + return status; + else + { + dnd_value = status & ~val_mask; + if (((data->reset == 1) && (info->cmpval != 0)) || ((data->reset == 0) && (info->cmpval == 0))) + reg = dnd_value | val_mask; + else + reg = dnd_value; + if (info->len == 1) + status = board_i2c_cpld_write(info->devaddr, info->offset, (uint8_t)reg); + else if (info->len == 2) + status = i2c_smbus_write_word_swapped(client_ptr, info->offset, (uint16_t)reg); + else + { + printk(KERN_ERR "PDDF_XCVR: Doesn't support block CPLD write yet"); + status = -1; + } + } + } + + return status; +} + +int sonic_i2c_set_mod_lpmode(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data) +{ + int status = 0; + unsigned int val_mask = 0, dnd_value = 0; + uint32_t reg; + struct i2c_client *client_ptr=NULL; + + if (strcmp(info->devtype, "cpld") == 0) + { + val_mask = BIT_INDEX(info->mask); + /* Get the I2C client for the CPLD */ + client_ptr = (struct i2c_client *)get_device_table(info->devname); + + if (client_ptr) + { + if (info->len == 1) + status = board_i2c_cpld_read(info->devaddr , info->offset); + else if (info->len == 2) + status = i2c_smbus_read_word_data(client_ptr, info->offset); + else + { + printk(KERN_ERR "PDDF_XCVR: Doesn't support block CPLD read yet"); + status = -1; + } + } + else + { + printk(KERN_ERR "Unable to get the client handle for %s\n", info->devname); + status = -1; + } + + if (status < 0) + return status; + else + { + dnd_value = status & ~val_mask; + if (((data->lpmode == 1) && (info->cmpval != 0)) || ((data->lpmode == 0) && (info->cmpval == 0))) + reg = dnd_value | val_mask; + else + reg = dnd_value; + if (info->len == 1) + status = board_i2c_cpld_write(info->devaddr, info->offset, (uint8_t)reg); + else if (info->len == 2) + status = i2c_smbus_write_word_swapped(client_ptr, info->offset, (uint16_t)reg); + else + { + printk(KERN_ERR "PDDF_XCVR: Doesn't support block CPLD write yet"); + status = -1; + } + } + } + + return status; +} + +int sonic_i2c_set_mod_txdisable(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data) +{ + int status = 0; + unsigned int val_mask = 0, dnd_value = 0; + uint32_t reg; + struct i2c_client *client_ptr=NULL; + + if (strcmp(info->devtype, "cpld") == 0) + { + val_mask = BIT_INDEX(info->mask); + /* Get the I2C client for the CPLD */ + client_ptr = (struct i2c_client *)get_device_table(info->devname); + + if (client_ptr) + { + if (info->len == 1) + status = board_i2c_cpld_read(info->devaddr , info->offset); + else if (info->len == 2) + status = i2c_smbus_read_word_data(client_ptr, info->offset); + else + { + printk(KERN_ERR "PDDF_XCVR: Doesn't support block CPLD read yet"); + status = -1; + } + } + else + { + printk(KERN_ERR "Unable to get the client handle for %s\n", info->devname); + status = -1; + } + + if (status < 0) + return status; + else + { + dnd_value = status & ~val_mask; + if (((data->txdisable == 1) && (info->cmpval != 0)) || ((data->txdisable == 0) && (info->cmpval == 0))) + reg = dnd_value | val_mask; + else + reg = dnd_value; + if (info->len == 1) + status = board_i2c_cpld_write(info->devaddr, info->offset, (uint8_t)reg); + else if (info->len == 2) + status = i2c_smbus_write_word_swapped(client_ptr, info->offset, (uint16_t)reg); + else + { + printk(KERN_ERR "PDDF_XCVR: Doesn't support block CPLD write yet"); + status = -1; + } + } + } + + return status; +} + +ssize_t get_module_presence(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct xcvr_data *data = i2c_get_clientdata(client); + XCVR_PDATA *pdata = (XCVR_PDATA *)(client->dev.platform_data); + XCVR_ATTR *attr_data = NULL; + XCVR_SYSFS_ATTR_OPS *attr_ops = NULL; + int status = 0, i; + + for (i=0; ilen; i++) + { + attr_data = &pdata->xcvr_attrs[i]; + if (strcmp(attr_data->aname, attr->dev_attr.attr.name) == 0) + { + attr_ops = &xcvr_ops[attr->index]; + + mutex_lock(&data->update_lock); + if (attr_ops->pre_get != NULL) + { + status = (attr_ops->pre_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: pre_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + if (attr_ops->do_get != NULL) + { + status = (attr_ops->do_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: do_get function fails for %s attribute. ret %d\n", __FUNCTION__, attr_data->aname, status); + + } + if (attr_ops->post_get != NULL) + { + status = (attr_ops->post_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: post_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + mutex_unlock(&data->update_lock); + return sprintf(buf, "%d\n", data->modpres); + } + } + return sprintf(buf, "%s",""); +} + +ssize_t get_module_reset(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct xcvr_data *data = i2c_get_clientdata(client); + XCVR_PDATA *pdata = (XCVR_PDATA *)(client->dev.platform_data); + XCVR_ATTR *attr_data = NULL; + XCVR_SYSFS_ATTR_OPS *attr_ops = NULL; + int status = 0, i; + + for (i=0; ilen; i++) + { + attr_data = &pdata->xcvr_attrs[i]; + if (strcmp(attr_data->aname, attr->dev_attr.attr.name) == 0) + { + attr_ops = &xcvr_ops[attr->index]; + + mutex_lock(&data->update_lock); + if (attr_ops->pre_get != NULL) + { + status = (attr_ops->pre_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: pre_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + if (attr_ops->do_get != NULL) + { + status = (attr_ops->do_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: do_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + + } + if (attr_ops->post_get != NULL) + { + status = (attr_ops->post_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: post_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", data->reset); + } + } + return sprintf(buf, "%s",""); +} + +ssize_t set_module_reset(struct device *dev, struct device_attribute *da, const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct xcvr_data *data = i2c_get_clientdata(client); + XCVR_PDATA *pdata = (XCVR_PDATA *)(client->dev.platform_data); + XCVR_ATTR *attr_data = NULL; + XCVR_SYSFS_ATTR_OPS *attr_ops = NULL; + int status = 0, i; + unsigned int set_value; + + for (i=0; ilen; i++) + { + attr_data = &pdata->xcvr_attrs[i]; + if (strcmp(attr_data->aname, attr->dev_attr.attr.name) == 0) + { + attr_ops = &xcvr_ops[attr->index]; + if(kstrtoint(buf, 10, &set_value)) + return -EINVAL; + if ((set_value != 1) && (set_value != 0)) + return -EINVAL; + + data->reset = set_value; + + mutex_lock(&data->update_lock); + + if (attr_ops->pre_set != NULL) + { + status = (attr_ops->pre_set)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: pre_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + if (attr_ops->do_set != NULL) + { + status = (attr_ops->do_set)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: do_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + + } + if (attr_ops->post_set != NULL) + { + status = (attr_ops->post_set)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: post_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + mutex_unlock(&data->update_lock); + + return count; + } + } + return -EINVAL; +} + +ssize_t get_module_intr_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct xcvr_data *data = i2c_get_clientdata(client); + XCVR_PDATA *pdata = (XCVR_PDATA *)(client->dev.platform_data); + XCVR_ATTR *attr_data = NULL; + XCVR_SYSFS_ATTR_OPS *attr_ops = NULL; + int status = 0, i; + + for (i=0; ilen; i++) + { + attr_data = &pdata->xcvr_attrs[i]; + if (strcmp(attr_data->aname, attr->dev_attr.attr.name) == 0) + { + attr_ops = &xcvr_ops[attr->index]; + + mutex_lock(&data->update_lock); + if (attr_ops->pre_get != NULL) + { + status = (attr_ops->pre_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: pre_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + if (attr_ops->do_get != NULL) + { + status = (attr_ops->do_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: do_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + + } + if (attr_ops->post_get != NULL) + { + status = (attr_ops->post_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: post_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + + mutex_unlock(&data->update_lock); + return sprintf(buf, "%d\n", data->intr_status); + } + } + return sprintf(buf, "%s",""); +} + +int get_xcvr_module_attr_data(struct i2c_client *client, struct device *dev, + struct device_attribute *da) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + XCVR_PDATA *pdata = (XCVR_PDATA *)(client->dev.platform_data); + XCVR_ATTR *attr_data = NULL; + int i; + + for (i=0; i < pdata->len; i++) + { + attr_data = &pdata->xcvr_attrs[i]; + if (strcmp(attr_data->aname, attr->dev_attr.attr.name) == 0) + { + return i; + } + } + return -1; +} + +ssize_t get_module_lpmode(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); + XCVR_PDATA *pdata = (XCVR_PDATA *)(client->dev.platform_data); + struct xcvr_data *data = i2c_get_clientdata(client); + XCVR_ATTR *attr_data = NULL; + XCVR_SYSFS_ATTR_OPS *attr_ops = NULL; + int idx, status = 0; + + idx = get_xcvr_module_attr_data(client, dev, da); + + if (idx>=0) attr_data = &pdata->xcvr_attrs[idx]; + + if (attr_data!=NULL) + { + + attr_ops = &xcvr_ops[attr->index]; + + mutex_lock(&data->update_lock); + if (attr_ops->pre_get != NULL) + { + status = (attr_ops->pre_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: pre_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + if (attr_ops->do_get != NULL) + { + status = (attr_ops->do_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: do_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + + } + if (attr_ops->post_get != NULL) + { + status = (attr_ops->post_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: post_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + mutex_unlock(&data->update_lock); + return sprintf(buf, "%d\n", data->lpmode); + } + else + return sprintf(buf,"%s",""); +} + +ssize_t set_module_lpmode(struct device *dev, struct device_attribute *da, const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct xcvr_data *data = i2c_get_clientdata(client); + XCVR_PDATA *pdata = (XCVR_PDATA *)(client->dev.platform_data); + int idx, status = 0; + uint32_t set_value; + XCVR_ATTR *attr_data = NULL; + XCVR_SYSFS_ATTR_OPS *attr_ops = NULL; + + idx = get_xcvr_module_attr_data(client, dev, da); + + if (idx>=0) attr_data = &pdata->xcvr_attrs[idx]; + + if (attr_data!=NULL) + { + attr_ops = &xcvr_ops[attr->index]; + if(kstrtoint(buf, 10, &set_value)) + return -EINVAL; + if ((set_value != 1) && (set_value != 0)) + return -EINVAL; + + data->lpmode = set_value; + + mutex_lock(&data->update_lock); + + if (attr_ops->pre_set != NULL) + { + status = (attr_ops->pre_set)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: pre_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + if (attr_ops->do_set != NULL) + { + status = (attr_ops->do_set)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: do_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + + } + if (attr_ops->post_set != NULL) + { + status = (attr_ops->post_set)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: post_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + mutex_unlock(&data->update_lock); + } + return count; +} + +ssize_t get_module_rxlos(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct xcvr_data *data = i2c_get_clientdata(client); + XCVR_PDATA *pdata = (XCVR_PDATA *)(client->dev.platform_data); + int idx, status = 0; + XCVR_ATTR *attr_data = NULL; + XCVR_SYSFS_ATTR_OPS *attr_ops = NULL; + + idx = get_xcvr_module_attr_data(client, dev, da); + + if (idx>=0) attr_data = &pdata->xcvr_attrs[idx]; + + if (attr_data!=NULL) + { + attr_ops = &xcvr_ops[attr->index]; + + mutex_lock(&data->update_lock); + if (attr_ops->pre_get != NULL) + { + status = (attr_ops->pre_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: pre_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + if (attr_ops->do_get != NULL) + { + status = (attr_ops->do_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: do_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + + } + if (attr_ops->post_get != NULL) + { + status = (attr_ops->post_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: post_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + mutex_unlock(&data->update_lock); + return sprintf(buf, "%d\n", data->rxlos); + } + else + return sprintf(buf,"%s",""); +} + +ssize_t get_module_txdisable(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct xcvr_data *data = i2c_get_clientdata(client); + XCVR_PDATA *pdata = (XCVR_PDATA *)(client->dev.platform_data); + int idx, status = 0; + XCVR_ATTR *attr_data = NULL; + XCVR_SYSFS_ATTR_OPS *attr_ops = NULL; + + idx = get_xcvr_module_attr_data(client, dev, da); + + if (idx>=0) attr_data = &pdata->xcvr_attrs[idx]; + + if (attr_data!=NULL) + { + attr_ops = &xcvr_ops[attr->index]; + + mutex_lock(&data->update_lock); + if (attr_ops->pre_get != NULL) + { + status = (attr_ops->pre_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: pre_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + if (attr_ops->do_get != NULL) + { + status = (attr_ops->do_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: do_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + + } + if (attr_ops->post_get != NULL) + { + status = (attr_ops->post_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: post_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + mutex_unlock(&data->update_lock); + return sprintf(buf, "%d\n", data->txdisable); + } + else + return sprintf(buf,"%s",""); +} + +ssize_t set_module_txdisable(struct device *dev, struct device_attribute *da, const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct xcvr_data *data = i2c_get_clientdata(client); + XCVR_PDATA *pdata = (XCVR_PDATA *)(client->dev.platform_data); + int idx, status = 0; + uint32_t set_value; + XCVR_ATTR *attr_data = NULL; + XCVR_SYSFS_ATTR_OPS *attr_ops = NULL; + + idx = get_xcvr_module_attr_data(client, dev, da); + + if (idx>=0) attr_data = &pdata->xcvr_attrs[idx]; + + if (attr_data!=NULL) + { + attr_ops = &xcvr_ops[attr->index]; + if(kstrtoint(buf, 10, &set_value)) + return -EINVAL; + if ((set_value != 1) && (set_value != 0)) + return -EINVAL; + + data->txdisable = set_value; + + mutex_lock(&data->update_lock); + + if (attr_ops->pre_set != NULL) + { + status = (attr_ops->pre_set)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: pre_set function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + if (attr_ops->do_set != NULL) + { + status = (attr_ops->do_set)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: do_set function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + + } + if (attr_ops->post_set != NULL) + { + status = (attr_ops->post_set)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: post_set function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + mutex_unlock(&data->update_lock); + } + return count; +} + +ssize_t get_module_txfault(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); + XCVR_PDATA *pdata = (XCVR_PDATA *)(client->dev.platform_data); + struct xcvr_data *data = i2c_get_clientdata(client); + int idx, status = 0; + XCVR_ATTR *attr_data = NULL; + XCVR_SYSFS_ATTR_OPS *attr_ops = NULL; + + idx = get_xcvr_module_attr_data(client, dev, da); + + if (idx>=0) attr_data = &pdata->xcvr_attrs[idx]; + + if (attr_data!=NULL) + { + attr_ops = &xcvr_ops[attr->index]; + + mutex_lock(&data->update_lock); + if (attr_ops->pre_get != NULL) + { + status = (attr_ops->pre_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: pre_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + if (attr_ops->do_get != NULL) + { + status = (attr_ops->do_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: do_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + + } + if (attr_ops->post_get != NULL) + { + status = (attr_ops->post_get)(client, attr_data, data); + if (status!=0) + printk(KERN_ERR "%s: post_get function fails for %s attribute\n", __FUNCTION__, attr_data->aname); + } + mutex_unlock(&data->update_lock); + return sprintf(buf, "%d\n", data->txfault); + } + return sprintf(buf,"%s",""); +} diff --git a/platform/pddf/i2c/modules/xcvr/driver/pddf_xcvr_driver.c b/platform/pddf/i2c/modules/xcvr/driver/pddf_xcvr_driver.c new file mode 100644 index 000000000000..142d38a2ff2b --- /dev/null +++ b/platform/pddf/i2c/modules/xcvr/driver/pddf_xcvr_driver.c @@ -0,0 +1,296 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * A pddf kernel driver module for Optic component + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pddf_client_defs.h" +#include "pddf_xcvr_defs.h" +#include "pddf_xcvr_api.h" + + +struct pddf_ops_t pddf_xcvr_ops = { + .pre_init = NULL, + .post_init = NULL, + + .pre_probe = NULL, + .post_probe = NULL, + + .pre_remove = NULL, + .post_remove = NULL, + + .pre_exit = NULL, + .post_exit = NULL, +}; +EXPORT_SYMBOL(pddf_xcvr_ops); + +XCVR_SYSFS_ATTR_OPS xcvr_ops[XCVR_ATTR_MAX] = { + {XCVR_PRESENT, get_module_presence, NULL, sonic_i2c_get_mod_pres, NULL, NULL, NULL, NULL, NULL}, + {XCVR_RESET, get_module_reset, NULL, sonic_i2c_get_mod_reset, NULL, set_module_reset, NULL, sonic_i2c_set_mod_reset, NULL}, + {XCVR_INTR_STATUS, get_module_intr_status, NULL, sonic_i2c_get_mod_intr_status, NULL, NULL, NULL, NULL, NULL}, + {XCVR_LPMODE, get_module_lpmode, NULL, sonic_i2c_get_mod_lpmode, NULL, set_module_lpmode, NULL, sonic_i2c_set_mod_lpmode, NULL}, + {XCVR_RXLOS, get_module_rxlos, NULL, sonic_i2c_get_mod_rxlos, NULL, NULL, NULL, NULL, NULL}, + {XCVR_TXDISABLE, get_module_txdisable, NULL, sonic_i2c_get_mod_txdisable, NULL, set_module_txdisable, NULL, sonic_i2c_set_mod_txdisable, NULL}, + {XCVR_TXFAULT, get_module_txfault, NULL, sonic_i2c_get_mod_txfault, NULL, NULL, NULL, NULL, NULL}, +}; +EXPORT_SYMBOL(xcvr_ops); + + +/* sysfs attributes + */ +static SENSOR_DEVICE_ATTR(xcvr_present, S_IWUSR|S_IRUGO, get_module_presence, NULL, XCVR_PRESENT); +static SENSOR_DEVICE_ATTR(xcvr_reset, S_IWUSR|S_IRUGO, get_module_reset, set_module_reset, XCVR_RESET); +static SENSOR_DEVICE_ATTR(xcvr_intr_status, S_IWUSR|S_IRUGO, get_module_intr_status, NULL, XCVR_INTR_STATUS); +static SENSOR_DEVICE_ATTR(xcvr_lpmode, S_IWUSR|S_IRUGO, get_module_lpmode, set_module_lpmode, XCVR_LPMODE); +static SENSOR_DEVICE_ATTR(xcvr_rxlos, S_IWUSR|S_IRUGO, get_module_rxlos, NULL, XCVR_RXLOS); +static SENSOR_DEVICE_ATTR(xcvr_txdisable, S_IWUSR|S_IRUGO, get_module_txdisable, set_module_txdisable, XCVR_TXDISABLE); +static SENSOR_DEVICE_ATTR(xcvr_txfault, S_IWUSR|S_IRUGO, get_module_txfault, NULL, XCVR_TXFAULT); + +/* List of all the xcvr attribute structures + * to get name, use sensor_dev_attr_<>.dev_attr.attr.name + * to get the id, use sensor_dev_attr_<>.dev_attr.index + */ +static struct sensor_device_attribute *xcvr_attr_list[MAX_XCVR_ATTRS] = { + &sensor_dev_attr_xcvr_present, + &sensor_dev_attr_xcvr_reset, + &sensor_dev_attr_xcvr_intr_status, + &sensor_dev_attr_xcvr_lpmode, + &sensor_dev_attr_xcvr_rxlos, + &sensor_dev_attr_xcvr_txdisable, + &sensor_dev_attr_xcvr_txfault, +}; + +static struct attribute *xcvr_attributes[MAX_XCVR_ATTRS] = {NULL}; + +static const struct attribute_group xcvr_group = { + .attrs = xcvr_attributes, +}; + +static int xcvr_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct xcvr_data *data; + int status =0; + int i,j,num; + XCVR_PDATA *xcvr_platform_data; + XCVR_ATTR *attr_data; + + if (client == NULL) { + pddf_dbg(XCVR, "NULL Client.. \n"); + goto exit; + } + + if (pddf_xcvr_ops.pre_probe) + { + status = (pddf_xcvr_ops.pre_probe)(client, dev_id); + if (status != 0) + goto exit; + } + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct xcvr_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + + dev_info(&client->dev, "chip found\n"); + + /* Take control of the platform data */ + xcvr_platform_data = (XCVR_PDATA *)(client->dev.platform_data); + num = xcvr_platform_data->len; + data->index = xcvr_platform_data->idx - 1; + mutex_init(&data->update_lock); + + /* Add supported attr in the 'attributes' list */ + for (i=0; ixcvr_attrs + i; + for(j=0;jdev_attr.attr; + + if (strncmp(aptr->name, attr_data->aname, strlen(attr_data->aname))==0) + break; + } + + if (jdev_attr.attr; + + } + xcvr_attributes[i] = NULL; + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &xcvr_group); + if (status) { + goto exit_free; + } + + data->xdev = hwmon_device_register(&client->dev); + if (IS_ERR(data->xdev)) { + status = PTR_ERR(data->xdev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: xcvr '%s'\n", + dev_name(data->xdev), client->name); + + /* Add a support for post probe function */ + if (pddf_xcvr_ops.post_probe) + { + status = (pddf_xcvr_ops.post_probe)(client, dev_id); + if (status != 0) + goto exit_remove; + } + + + return 0; + + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &xcvr_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int xcvr_remove(struct i2c_client *client) +{ + int ret = 0; + struct xcvr_data *data = i2c_get_clientdata(client); + XCVR_PDATA *platdata = (XCVR_PDATA *)client->dev.platform_data; + XCVR_ATTR *platdata_sub = platdata->xcvr_attrs; + + if (pddf_xcvr_ops.pre_remove) + { + ret = (pddf_xcvr_ops.pre_remove)(client); + if (ret!=0) + printk(KERN_ERR "FAN pre_remove function failed\n"); + } + + hwmon_device_unregister(data->xdev); + sysfs_remove_group(&client->dev.kobj, &xcvr_group); + kfree(data); + + if (platdata_sub) { + pddf_dbg(XCVR, KERN_DEBUG "%s: Freeing platform subdata\n", __FUNCTION__); + kfree(platdata_sub); + } + if (platdata) { + pddf_dbg(XCVR, KERN_DEBUG "%s: Freeing platform data\n", __FUNCTION__); + kfree(platdata); + } + + if (pddf_xcvr_ops.post_remove) + { + ret = (pddf_xcvr_ops.post_remove)(client); + if (ret!=0) + printk(KERN_ERR "FAN post_remove function failed\n"); + } + + return 0; +} + +enum xcvr_intf +{ + XCVR_CTRL_INTF, +}; + +static const struct i2c_device_id xcvr_ids[] = { + { "pddf_xcvr", XCVR_CTRL_INTF }, + {} +}; + +MODULE_DEVICE_TABLE(i2c, xcvr_ids); + +static struct i2c_driver xcvr_driver = { + /*.class = I2C_CLASS_HWMON,*/ + .driver = { + .name = "xcvr", + .owner = THIS_MODULE, + }, + .probe = xcvr_probe, + .remove = xcvr_remove, + .id_table = xcvr_ids, +}; + + +/*int __init xcvr_init(void)*/ +int xcvr_init(void) +{ + int ret = 0; + + if (pddf_xcvr_ops.pre_init) + { + ret = (pddf_xcvr_ops.pre_init)(); + if (ret!=0) + return ret; + } + + pddf_dbg(XCVR, KERN_ERR "PDDF XCVR DRIVER.. init Invoked..\n"); + ret = i2c_add_driver(&xcvr_driver); + if (ret!=0) + return ret; + + if (pddf_xcvr_ops.post_init) + { + ret = (pddf_xcvr_ops.post_init)(); + if (ret!=0) + return ret; + } + + return ret; +} +EXPORT_SYMBOL(xcvr_init); + +void __exit xcvr_exit(void) +{ + pddf_dbg(XCVR, "PDDF XCVR DRIVER.. exit\n"); + if (pddf_xcvr_ops.pre_exit) (pddf_xcvr_ops.pre_exit)(); + i2c_del_driver(&xcvr_driver); + if (pddf_xcvr_ops.post_exit) (pddf_xcvr_ops.post_exit)(); + +} +EXPORT_SYMBOL(xcvr_exit); + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("Driver for transceiver operations"); +MODULE_LICENSE("GPL"); + +module_init(xcvr_init); +module_exit(xcvr_exit); diff --git a/platform/pddf/i2c/modules/xcvr/pddf_xcvr_module.c b/platform/pddf/i2c/modules/xcvr/pddf_xcvr_module.c new file mode 100644 index 000000000000..65c555b742a2 --- /dev/null +++ b/platform/pddf/i2c/modules/xcvr/pddf_xcvr_module.c @@ -0,0 +1,275 @@ +/* + * Copyright 2019 Broadcom. + * The term “Broadcom†refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * A pddf kernel module to create i2C client for optics + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pddf_client_defs.h" +#include "pddf_xcvr_defs.h" + +static ssize_t do_attr_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t do_device_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +extern void* get_device_table(char *name); +extern void delete_device_table(char *name); + +XCVR_DATA xcvr_data = {0}; + +/* XCVR CLIENT DATA */ +PDDF_DATA_ATTR(dev_idx, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_DEC, sizeof(int), (void*)&xcvr_data.idx, NULL); + +PDDF_DATA_ATTR(attr_name, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_CHAR, 32, (void*)&xcvr_data.xcvr_attr.aname, NULL); +PDDF_DATA_ATTR(attr_devtype, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_CHAR, 8, (void*)&xcvr_data.xcvr_attr.devtype, NULL); +PDDF_DATA_ATTR(attr_devname, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_CHAR, 8, (void*)&xcvr_data.xcvr_attr.devname, NULL); +PDDF_DATA_ATTR(attr_devaddr, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UINT32, sizeof(uint32_t), (void*)&xcvr_data.xcvr_attr.devaddr, NULL); +PDDF_DATA_ATTR(attr_offset, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UINT32, sizeof(uint32_t), (void*)&xcvr_data.xcvr_attr.offset, NULL); +PDDF_DATA_ATTR(attr_mask, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UINT32, sizeof(uint32_t), (void*)&xcvr_data.xcvr_attr.mask, NULL); +PDDF_DATA_ATTR(attr_cmpval, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_UINT32, sizeof(uint32_t), (void*)&xcvr_data.xcvr_attr.cmpval, NULL); +PDDF_DATA_ATTR(attr_len, S_IWUSR|S_IRUGO, show_pddf_data, store_pddf_data, PDDF_INT_DEC, sizeof(int), (void*)&xcvr_data.xcvr_attr.len, NULL); +PDDF_DATA_ATTR(attr_ops, S_IWUSR, NULL, do_attr_operation, PDDF_CHAR, 8, (void*)&xcvr_data, NULL); +PDDF_DATA_ATTR(dev_ops, S_IWUSR, NULL, do_device_operation, PDDF_CHAR, 8, (void*)&xcvr_data, (void*)&pddf_data); + + +static struct attribute *xcvr_attributes[] = { + &attr_dev_idx.dev_attr.attr, + + &attr_attr_name.dev_attr.attr, + &attr_attr_devtype.dev_attr.attr, + &attr_attr_devname.dev_attr.attr, + &attr_attr_devaddr.dev_attr.attr, + &attr_attr_offset.dev_attr.attr, + &attr_attr_mask.dev_attr.attr, + &attr_attr_cmpval.dev_attr.attr, + &attr_attr_len.dev_attr.attr, + &attr_attr_ops.dev_attr.attr, + &attr_dev_ops.dev_attr.attr, + NULL +}; + +static const struct attribute_group pddf_xcvr_client_data_group = { + .attrs = xcvr_attributes, +}; + + +static ssize_t do_attr_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + PDDF_ATTR *ptr = (PDDF_ATTR *)da; + XCVR_DATA *pdata = (XCVR_DATA *)(ptr->addr); + + pdata->xcvr_attrs[pdata->len] = pdata->xcvr_attr; + pdata->len++; + memset(&pdata->xcvr_attr, 0, sizeof(pdata->xcvr_attr)); + + + return count; +} + +/*PDDF_DATA_ATTR(dev_ops, S_IWUSR, NULL, do_device_operation, PDDF_CHAR, 8, (void*)&pddf_attr, (void*)NULL);*/ +static ssize_t do_device_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int i = 0; + PDDF_ATTR *ptr = (PDDF_ATTR *)da; + XCVR_DATA *pdata = (XCVR_DATA *)(ptr->addr); + NEW_DEV_ATTR *cdata = (NEW_DEV_ATTR *)(ptr->data); + + struct i2c_adapter *adapter; + struct i2c_board_info board_info; + struct i2c_client *client_ptr; + + /* Populate the platform data for xcvr */ + if (strncmp(buf, "add", strlen(buf)-1)==0) + { + if (strcmp(cdata->dev_type, "pddf_xcvr")==0) + { + int num = pdata->len; + XCVR_PDATA *xcvr_platform_data; + + adapter = i2c_get_adapter(cdata->parent_bus); + /* Allocate the xcvr_platform_data */ + xcvr_platform_data = (XCVR_PDATA *)kzalloc(sizeof(XCVR_PDATA), GFP_KERNEL); + xcvr_platform_data->xcvr_attrs = (XCVR_ATTR *)kzalloc(num*sizeof(XCVR_ATTR), GFP_KERNEL); + + + xcvr_platform_data->idx = pdata->idx; + xcvr_platform_data->len = pdata->len; + + for (i=0;ixcvr_attrs[i] = pdata->xcvr_attrs[i]; + } + + board_info = (struct i2c_board_info) { + .platform_data = xcvr_platform_data, + }; + + board_info.addr = cdata->dev_addr; + strcpy(board_info.type, cdata->dev_type); + + client_ptr = i2c_new_device(adapter, &board_info); + if (client_ptr != NULL) { + i2c_put_adapter(adapter); + pddf_dbg(XCVR, KERN_ERR "Created a %s client: 0x%p\n", cdata->i2c_name, (void *)client_ptr); + add_device_table(cdata->i2c_name, (void*)client_ptr); + } + else + { + i2c_put_adapter(adapter); + goto free_data; + } + } + else if((strcmp(cdata->dev_type, "optoe1")==0) || (strcmp(cdata->dev_type, "optoe2")==0)) + { + + adapter = i2c_get_adapter(cdata->parent_bus); + board_info = (struct i2c_board_info) { + .platform_data = (void *)NULL, + }; + + board_info.addr = cdata->dev_addr; + strcpy(board_info.type, cdata->dev_type); + + client_ptr = i2c_new_device(adapter, &board_info); + if(client_ptr != NULL) { + i2c_put_adapter(adapter); + pddf_dbg(XCVR, KERN_ERR "Created %s, type:%s client: 0x%p\n", cdata->i2c_name, cdata->dev_type, (void *)client_ptr); + add_device_table(cdata->i2c_name, (void*)client_ptr); + } + else + { + i2c_put_adapter(adapter); + printk(KERN_ERR "Error creating a client %s on 0x%x, client_ptr:0x%p\n", board_info.type, board_info.addr, (void *)client_ptr); + goto free_data; + } + } + else + { + printk(KERN_ERR "%s:Unknown type of device %s. Unable to create I2C client for it\n",__FUNCTION__, cdata->dev_type); + } + } + else if (strncmp(buf, "delete", strlen(buf)-1)==0) + { + /*Get the i2c_client handle for the created client*/ + client_ptr = (struct i2c_client *)get_device_table(cdata->i2c_name); + if (client_ptr) + { + pddf_dbg(XCVR, KERN_ERR "Removing %s client: 0x%p\n", cdata->i2c_name, (void *)client_ptr); + i2c_unregister_device(client_ptr); + delete_device_table(cdata->i2c_name); + } + else + { + pddf_dbg(XCVR, KERN_ERR "Unable to get the client handle for %s\n", cdata->i2c_name); + } + } + else + { + printk(KERN_ERR "PDDF_ERROR: %s: Invalid value for dev_ops %s", __FUNCTION__, buf); + } + + goto clear_data; + +free_data: + if (board_info.platform_data) + { + XCVR_PDATA *xcvr_platform_data = board_info.platform_data; + if (xcvr_platform_data->xcvr_attrs) + { + printk(KERN_ERR "%s: Unable to create i2c client. Freeing the platform subdata\n", __FUNCTION__); + kfree(xcvr_platform_data->xcvr_attrs); + } + printk(KERN_ERR "%s: Unable to create i2c client. Freeing the platform data\n", __FUNCTION__); + kfree(xcvr_platform_data); + } + +clear_data: + memset(pdata, 0, sizeof(XCVR_DATA)); + /*TODO: free the data cdata->data if data is dynal=mically allocated*/ + memset(cdata, 0, sizeof(NEW_DEV_ATTR)); + return count; +} + +struct kobject *xcvr_kobj; +struct kobject *i2c_kobj; +int __init pddf_data_init(void) +{ + struct kobject *device_kobj; + int ret = 0; + + pddf_dbg(XCVR, KERN_ERR "XCVR PDDF MODULE.. init\n"); + + device_kobj = get_device_i2c_kobj(); + if(!device_kobj) + return -ENOMEM; + + xcvr_kobj = kobject_create_and_add("xcvr", device_kobj); + if(!xcvr_kobj) + return -ENOMEM; + i2c_kobj = kobject_create_and_add("i2c", xcvr_kobj); + if(!i2c_kobj) + return -ENOMEM; + + ret = sysfs_create_group(i2c_kobj, &pddf_clients_data_group); + if (ret) + { + kobject_put(i2c_kobj); + kobject_put(xcvr_kobj); + return ret; + } + pddf_dbg(XCVR, "CREATED SFP I2C CLIENTS CREATION SYSFS GROUP\n"); + + ret = sysfs_create_group(i2c_kobj, &pddf_xcvr_client_data_group); + if (ret) + { + sysfs_remove_group(i2c_kobj, &pddf_clients_data_group); + kobject_put(i2c_kobj); + kobject_put(xcvr_kobj); + return ret; + } + pddf_dbg(XCVR, "CREATED PDDF SFP DATA SYSFS GROUP\n"); + + return ret; +} + +void __exit pddf_data_exit(void) +{ + + pddf_dbg(XCVR, "XCVR PDDF MODULE.. exit\n"); + sysfs_remove_group(i2c_kobj, &pddf_xcvr_client_data_group); + sysfs_remove_group(i2c_kobj, &pddf_clients_data_group); + kobject_put(i2c_kobj); + kobject_put(xcvr_kobj); + pddf_dbg(XCVR, KERN_ERR "%s: Removed the kobjects for 'i2c' and 'xcvr'\n",__FUNCTION__); + + return; +} + +module_init(pddf_data_init); +module_exit(pddf_data_exit); + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("sfp platform data"); +MODULE_LICENSE("GPL"); diff --git a/platform/pddf/i2c/service/pddf-platform-init.service b/platform/pddf/i2c/service/pddf-platform-init.service new file mode 100644 index 000000000000..ccb8d1110fb7 --- /dev/null +++ b/platform/pddf/i2c/service/pddf-platform-init.service @@ -0,0 +1,13 @@ +[Unit] +Description=PDDF module and device initialization service +Before=pmon.service +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/pddf_util.py install +ExecStop=/usr/local/bin/pddf_util.py clean +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/pddf/i2c/setup.py b/platform/pddf/i2c/setup.py new file mode 100755 index 000000000000..04da78cd5330 --- /dev/null +++ b/platform/pddf/i2c/setup.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python + +from setuptools import setup +import os + +setup( + name='pddf-platform', + version='%s' % os.environ.get('PLATFORM_MODULE_VERSION', '1.0'), + description='Module to initialize Platform', + packages=[ + 'modules', + ], +) + diff --git a/platform/pddf/i2c/utils/pddf_util.py b/platform/pddf/i2c/utils/pddf_util.py new file mode 100755 index 000000000000..127f37d6b2f0 --- /dev/null +++ b/platform/pddf/i2c/utils/pddf_util.py @@ -0,0 +1,605 @@ +#!/usr/bin/env python + + +""" +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 + switch-pddf : switch to pddf mode, installing pddf drivers and generating sysfs nodes + switch-nonpddf : switch to per platform, non-pddf mode +""" + +import commands +import logging +import getopt +import os +import shutil +import subprocess +import sys + +import pddfparse + +PLATFORM_ROOT_PATH = '/usr/share/sonic/device' +SONIC_CFGGEN_PATH = '/usr/local/bin/sonic-cfggen' +HWSKU_KEY = 'DEVICE_METADATA.localhost.hwsku' +PLATFORM_KEY = 'DEVICE_METADATA.localhost.platform' + +PROJECT_NAME = 'PDDF' +version = '1.1' +verbose = False +DEBUG = False +args = [] +ALL_DEVICE = {} +FORCE = 0 +kos = [] +perm_kos = [] +devs = [] + +# Instantiate the class pddf_obj +try: + pddf_obj = pddfparse.PddfParse() +except Exception as e: + print "%s" % str(e) + sys.exit() + + + +if DEBUG == True: + print sys.argv[0] + print 'ARGV :', sys.argv[1:] + +def main(): + global DEBUG + global args + global FORCE + global kos + + 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) + + # generate the KOS list from pddf device JSON file + if 'std_perm_kos' in pddf_obj.data['PLATFORM'].keys(): + kos.extend(pddf_obj.data['PLATFORM']['std_perm_kos']) + perm_kos.extend(pddf_obj.data['PLATFORM']['std_perm_kos']) + kos.extend(pddf_obj.data['PLATFORM']['std_kos']) + kos.extend(pddf_obj.data['PLATFORM']['pddf_kos']) + + kos = ['modprobe '+i for i in kos] + + if 'custom_kos' in pddf_obj.data['PLATFORM']: + custom_kos = pddf_obj.data['PLATFORM']['custom_kos'] + kos.extend(['modprobe -f '+i for i in custom_kos]) + + 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 == 'switch-pddf': + do_switch_pddf() + elif arg == 'switch-nonpddf': + do_switch_nonpddf() + else: + show_help() + + return 0 + +def show_help(): + print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} + sys.exit(0) + +def my_log(txt): + if DEBUG == True: + print "[PDDF]"+txt + return + +def log_os_system(cmd, show): + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) + my_log (cmd +"with result:" + str(status)) + my_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + +def driver_check(): + ret, lsmod = log_os_system("lsmod| grep pddf", 0) + if ret: + return False + logging.info('mods:'+lsmod) + if len(lsmod) ==0: + return False + return True + + +# Returns platform and HW SKU +def get_platform_and_hwsku(): + try: + proc = subprocess.Popen([SONIC_CFGGEN_PATH, '-H', '-v', PLATFORM_KEY], + stdout=subprocess.PIPE, + shell=False, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + platform = stdout.rstrip('\n') + + proc = subprocess.Popen([SONIC_CFGGEN_PATH, '-d', '-v', HWSKU_KEY], + stdout=subprocess.PIPE, + shell=False, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + hwsku = stdout.rstrip('\n') + except OSError, e: + raise OSError("Cannot detect platform") + + return (platform, hwsku) + +def get_path_to_device(): + # Get platform and hwsku + (platform, hwsku) = get_platform_and_hwsku() + + # Load platform module from source + platform_path = "/".join([PLATFORM_ROOT_PATH, platform]) + + return platform_path + +def get_path_to_pddf_plugin(): + pddf_path = "/".join([PLATFORM_ROOT_PATH, "pddf/plugins"]) + return pddf_path + +def config_pddf_utils(): + device_path = get_path_to_device() + pddf_path = get_path_to_pddf_plugin() + + # ########################################################################## + SONIC_PLATFORM_BSP_WHL_PKG = "/".join([device_path, 'sonic_platform-1.0-py2-none-any.whl']) + SONIC_PLATFORM_PDDF_WHL_PKG = "/".join([device_path, 'pddf', 'sonic_platform-1.0-py2-none-any.whl']) + SONIC_PLATFORM_BSP_WHL_PKG_BK = "/".join([device_path, 'sonic_platform-1.0-py2-none-any.whl.orig']) + status, output = log_os_system("pip show sonic-platform > /dev/null 2>&1", 1) + if status: + if os.path.exists(SONIC_PLATFORM_PDDF_WHL_PKG): + # Platform API 2.0 is supported + if os.path.exists(SONIC_PLATFORM_BSP_WHL_PKG): + # bsp whl pkg is present but not installed on host + if not os.path.exists(SONIC_PLATFORM_BSP_WHL_PKG_BK): + log_os_system('mv '+SONIC_PLATFORM_BSP_WHL_PKG+' '+SONIC_PLATFORM_BSP_WHL_PKG_BK, 1) + # PDDF whl package exist ... this must be the whl package created from + # PDDF 2.0 ref API classes and some changes on top of it ... install it + shutil.copy(SONIC_PLATFORM_PDDF_WHL_PKG, SONIC_PLATFORM_BSP_WHL_PKG) + print "Attemting to install the PDDF sonic_platform wheel package ..." + status, output = log_os_system("pip install "+ SONIC_PLATFORM_BSP_WHL_PKG, 1) + if status: + print "Error: Failed to install {}".format(SONIC_PLATFORM_BSP_WHL_PKG) + return status + else: + print "Successfully installed {} package".format(SONIC_PLATFORM_BSP_WHL_PKG) + else: + # PDDF with platform APIs 1.5 must be supported + device_plugin_path = "/".join([device_path, "plugins"]) + backup_path = "/".join([device_plugin_path, "orig"]) + print "Loading PDDF generic plugins (1.0)" + if os.path.exists(backup_path) is False: + os.mkdir(backup_path) + log_os_system("mv "+device_plugin_path+"/*.*"+" "+backup_path, 0) + + for item in os.listdir(pddf_path): + shutil.copy(pddf_path+"/"+item, device_plugin_path+"/"+item) + + shutil.copy('/usr/local/bin/pddfparse.py', device_plugin_path+"/pddfparse.py") + + else: + # sonic_platform whl pkg is installed 2 possibilities, 1) bsp 2.0 classes + # are installed, 2) system rebooted and either pddf/bsp 2.0 classes are already installed + if os.path.exists(SONIC_PLATFORM_PDDF_WHL_PKG): + if not os.path.exists(SONIC_PLATFORM_BSP_WHL_PKG_BK): + # bsp 2.0 classes are installed. Take a backup and copy pddf 2.0 whl pkg + log_os_system('mv '+SONIC_PLATFORM_BSP_WHL_PKG+' '+SONIC_PLATFORM_BSP_WHL_PKG_BK, 1) + shutil.copy(SONIC_PLATFORM_PDDF_WHL_PKG, SONIC_PLATFORM_BSP_WHL_PKG) + # uninstall the existing bsp whl pkg + status, output = log_os_system("pip uninstall sonic-platform -y &> /dev/null", 1) + if status: + print "Error: Unable to uninstall BSP sonic-platform whl package" + return status + print "Attemting to install the PDDF sonic_platform wheel package ..." + status, output = log_os_system("pip install "+ SONIC_PLATFORM_BSP_WHL_PKG, 1) + if status: + print "Error: Failed to install {}".format(SONIC_PLATFORM_BSP_WHL_PKG) + return status + else: + print "Successfully installed {} package".format(SONIC_PLATFORM_BSP_WHL_PKG) + else: + # system rebooted in pddf mode + print "System rebooted in PDDF mode, hence keeping the PDDF 2.0 classes" + else: + # pddf whl package doesnt exist + print "Error: PDDF 2.0 classes doesnt exist. PDDF mode can not be enabled" + sys.exit(1) + + # ########################################################################## + # Take a backup of orig fancontrol + if os.path.exists(device_path+"/fancontrol"): + log_os_system("mv "+device_path+"/fancontrol"+" "+device_path+"/fancontrol.bak", 0) + + # Create a link to fancontrol of PDDF + if os.path.exists(device_path+"/pddf/fancontrol") and not os.path.exists(device_path+"/fancontrol"): + shutil.copy(device_path+"/pddf/fancontrol",device_path+"/fancontrol") + + # BMC support + f_sensors="/usr/bin/sensors" + f_sensors_org="/usr/bin/sensors.org" + f_pddf_sensors="/usr/local/bin/pddf_sensors" + if os.path.exists(f_pddf_sensors) is True: + if os.path.exists(f_sensors_org) is False: + shutil.copy(f_sensors, f_sensors_org) + shutil.copy(f_pddf_sensors, f_sensors) + + + return 0 + +def cleanup_pddf_utils(): + device_path = get_path_to_device() + SONIC_PLATFORM_BSP_WHL_PKG = "/".join([device_path, 'sonic_platform-1.0-py2-none-any.whl']) + SONIC_PLATFORM_PDDF_WHL_PKG = "/".join([device_path, 'pddf', 'sonic_platform-1.0-py2-none-any.whl']) + SONIC_PLATFORM_BSP_WHL_PKG_BK = "/".join([device_path, 'sonic_platform-1.0-py2-none-any.whl.orig']) + # ########################################################################## + status, output = log_os_system("pip show sonic-platform > /dev/null 2>&1", 1) + if status: + # PDDF Platform API 2.0 is not supported but system is in PDDF mode, hence PDDF 1.0 plugins are present + device_plugin_path = "/".join([device_path, "plugins"]) + backup_path = "/".join([device_plugin_path, "orig"]) + if os.path.exists(backup_path) is True: + for item in os.listdir(device_plugin_path): + if os.path.isdir(device_plugin_path+"/"+item) is False: + os.remove(device_plugin_path+"/"+item) + + log_os_system("mv "+backup_path+"/*"+" "+device_plugin_path, 1) + os.rmdir(backup_path) + else: + print "\nERR: Unable to locate original device files...\n" + + else: + # PDDF 2.0 apis are supported and PDDF whl package is installed + if os.path.exists(SONIC_PLATFORM_PDDF_WHL_PKG): + if os.path.exists(SONIC_PLATFORM_BSP_WHL_PKG_BK): + # platform is 2.0 compliant and original bsp 2.0 whl package exist + log_os_system('mv '+SONIC_PLATFORM_BSP_WHL_PKG_BK+' '+SONIC_PLATFORM_BSP_WHL_PKG, 1) + status, output = log_os_system("pip uninstall sonic-platform -y &> /dev/null", 1) + if status: + print "Error: Unable to uninstall PDDF sonic-platform whl package" + return status + print "Attemting to install the BSP sonic_platform wheel package ..." + status, output = log_os_system("pip install "+ SONIC_PLATFORM_BSP_WHL_PKG, 1) + if status: + print "Error: Failed to install {}".format(SONIC_PLATFORM_BSP_WHL_PKG) + return status + else: + print "Successfully installed {} package".format(SONIC_PLATFORM_BSP_WHL_PKG) + else: + # platform doesnt support 2.0 APIs but PDDF is 2.0 based + # remove and uninstall the PDDF whl package + if os.path.exists(SONIC_PLATFORM_BSP_WHL_PKG): + os.remove(SONIC_PLATFORM_BSP_WHL_PKG) + status, output = log_os_system("pip uninstall sonic-platform -y &> /dev/null", 1) + if status: + print "Error: Unable to uninstall PDDF sonic-platform whl package" + return status + else: + # something seriously wrong. System is in PDDF mode but pddf whl pkg is not present + print "Error: Fatal error as the system is in PDDF mode but the pddf .whl original is not present" + # ################################################################################################################ + + if os.path.exists(device_path+"/fancontrol"): + os.remove(device_path+"/fancontrol") + + if os.path.exists(device_path+"/fancontrol.bak"): + log_os_system("mv "+device_path+"/fancontrol.bak"+" "+device_path+"/fancontrol", 0) + + # BMC support + f_sensors="/usr/bin/sensors" + f_sensors_org="/usr/bin/sensors.org" + if os.path.exists(f_sensors_org) is True: + shutil.copy(f_sensors_org, f_sensors) + + return 0 + +def create_pddf_log_files(): + if not os.path.exists('/var/log/pddf'): + log_os_system("sudo mkdir /var/log/pddf", 1) + + log_os_system("sudo touch /var/log/pddf/led.txt", 1) + log_os_system("sudo touch /var/log/pddf/psu.txt", 1) + log_os_system("sudo touch /var/log/pddf/fan.txt", 1) + log_os_system("sudo touch /var/log/pddf/xcvr.txt", 1) + log_os_system("sudo touch /var/log/pddf/sysstatus.txt", 1) + log_os_system("sudo touch /var/log/pddf/cpld.txt", 1) + log_os_system("sudo touch /var/log/pddf/cpldmux.txt", 1) + log_os_system("sudo touch /var/log/pddf/client.txt", 1) + log_os_system("sudo touch /var/log/pddf/mux.txt", 1) + +def driver_install(): + global FORCE + + # check for pre_driver_install script + if os.path.exists('/usr/local/bin/pddf_pre_driver_install.sh'): + status, output = log_os_system('/usr/local/bin/pddf_pre_driver_install.sh', 1) + if status: + print "Error: pddf_pre_driver_install script failed with error %d"%status + return status + + log_os_system("depmod", 1) + for i in range(0,len(kos)): + status, output = log_os_system(kos[i], 1) + if status: + print "driver_install() failed with error %d"%status + if FORCE == 0: + return status + + output = config_pddf_utils() + if output: + print "config_pddf_utils() failed with error %d"%output + # check for post_driver_install script + if os.path.exists('/usr/local/bin/pddf_post_driver_install.sh'): + status, output = log_os_system('/usr/local/bin/pddf_post_driver_install.sh', 1) + if status: + print "Error: pddf_post_driver_install script failed with error %d"%status + return status + + + return 0 + +def driver_uninstall(): + global FORCE + + status = cleanup_pddf_utils() + if status: + print "cleanup_pddf_utils() failed with error %d"%status + + for i in range(0,len(kos)): + # if it is in perm_kos, do not remove + if (kos[-(i+1)].split())[-1] in perm_kos or 'i2c-i801' in kos[-(i+1)]: + continue + + rm = kos[-(i+1)].replace("modprobe", "modprobe -rq") + rm = rm.replace("insmod", "rmmod") + status, output = log_os_system(rm, 1) + if status: + print "driver_uninstall() failed with error %d"%status + if FORCE == 0: + return status + return 0 + +def device_install(): + global FORCE + + # check for pre_device_creation script + if os.path.exists('/usr/local/bin/pddf_pre_device_create.sh'): + status, output = log_os_system('/usr/local/bin/pddf_pre_device_create.sh', 1) + if status: + print "Error: pddf_pre_device_create script failed with error %d"%status + return status + + # trigger the pddf_obj script for FAN, PSU, CPLD, MUX, etc + status = pddf_obj.create_pddf_devices() + if status: + print "Error: create_pddf_devices() failed with error %d"%status + if FORCE == 0: + return status + + # check for post_device_create script + if os.path.exists('/usr/local/bin/pddf_post_device_create.sh'): + status, output = log_os_system('/usr/local/bin/pddf_post_device_create.sh', 1) + if status: + print "Error: pddf_post_device_create script failed with error %d"%status + return status + + return + +def device_uninstall(): + global FORCE + # Trigger the paloparse script for deletion of FAN, PSU, OPTICS, CPLD clients + status = pddf_obj.delete_pddf_devices() + if status: + print "Error: delete_pddf_devices() failed with error %d"%status + if FORCE == 0: + return status + return + +def do_install(): + print "Checking system...." + if not os.path.exists('/usr/share/sonic/platform/pddf_support'): + print PROJECT_NAME.upper() +" mode is not enabled" + return + + if driver_check()== False : + print PROJECT_NAME.upper() +" has no PDDF driver installed...." + create_pddf_log_files() + print "Installing ..." + status = driver_install() + if status: + return status + else: + print PROJECT_NAME.upper() +" drivers detected...." + + print "Creating devices ..." + status = device_install() + if status: + return status + + return + +def do_uninstall(): + print "Checking system...." + if not os.path.exists('/usr/share/sonic/platform/pddf_support'): + print PROJECT_NAME.upper() +" mode is not enabled" + return + + + if os.path.exists('/var/log/pddf'): + print "Remove pddf log files....." + log_os_system("sudo rm -rf /var/log/pddf", 1) + + print "Remove all the devices..." + status = device_uninstall() + if status: + return status + + + if driver_check()== False : + print PROJECT_NAME.upper() +" has no PDDF driver installed...." + else: + print "Removing installed driver...." + status = driver_uninstall() + if status: + if FORCE == 0: + return status + return + +def do_switch_pddf(): + try: + import pddf_switch_svc + except ImportError: + print "Unable to find pddf_switch_svc.py. PDDF might not be supported on this platform" + sys.exit() + print "Check the pddf support..." + status = pddf_switch_svc.check_pddf_support() + if not status: + print "PDDF is not supported on this platform" + return status + + + print "Checking system...." + if os.path.exists('/usr/share/sonic/platform/pddf_support'): + print PROJECT_NAME.upper() +" system is already in pddf mode...." + else: + print "Check if the native sonic-platform whl package is installed in the pmon docker" + status, output = log_os_system("docker exec -it pmon pip show sonic-platform", 1) + if not status: + # Need to remove this whl module + status, output = log_os_system("docker exec -it pmon pip uninstall sonic-platform -y", 1) + if not status: + print "Successfully uninstalled the native sonic-platform whl pkg from pmon container" + else: + print "Error: Unable to uninstall the sonic-platform whl pkg from pmon container.\ + Do it manually before moving to nonpddf mode" + return status + print "Stopping the pmon service ..." + status, output = log_os_system("systemctl stop pmon.service", 1) + if status: + print "Pmon stop failed" + if FORCE==0: + return status + + print "Stopping the platform services.." + status = pddf_switch_svc.stop_platform_svc() + if not status: + if FORCE==0: + return status + + print "Creating the pddf_support file..." + if os.path.exists('/usr/share/sonic/platform'): + log_os_system("touch /usr/share/sonic/platform/pddf_support", 1) + else: + print "/usr/share/sonic/platform path doesn't exist. Unable to set pddf mode" + return -1 + + print "Starting the PDDF platform service..." + status = pddf_switch_svc.start_platform_pddf() + if not status: + if FORCE==0: + return status + + print "Restart the pmon service ..." + status, output = log_os_system("systemctl start pmon.service", 1) + if status: + print "Pmon restart failed" + if FORCE==0: + return status + + return + +def do_switch_nonpddf(): + try: + import pddf_switch_svc + except ImportError: + print "Unable to find pddf_switch_svc.py. PDDF might not be supported on this platform" + sys.exit() + print "Checking system...." + if not os.path.exists('/usr/share/sonic/platform/pddf_support'): + print PROJECT_NAME.upper() +" system is already in non-pddf mode...." + else: + print "Check if the sonic-platform whl package is installed in the pmon docker" + status, output = log_os_system("docker exec -it pmon pip show sonic-platform", 1) + if not status: + # Need to remove this whl module + status, output = log_os_system("docker exec -it pmon pip uninstall sonic-platform -y", 1) + if not status: + print "Successfully uninstalled the sonic-platform whl pkg from pmon container" + else: + print "Error: Unable to uninstall the sonic-platform whl pkg from pmon container.\ + Do it manually before moving to nonpddf mode" + return status + print "Stopping the pmon service ..." + status, output = log_os_system("systemctl stop pmon.service", 1) + if status: + print "Stopping pmon service failed" + if FORCE==0: + return status + + print "Stopping the PDDF platform service..." + status = pddf_switch_svc.stop_platform_pddf() + if not status: + if FORCE==0: + return status + + print "Removing the pddf_support file..." + if os.path.exists('/usr/share/sonic/platform'): + log_os_system("rm -f /usr/share/sonic/platform/pddf_support", 1) + else: + print "/usr/share/sonic/platform path doesnt exist. Unable to set non-pddf mode" + return -1 + + print "Starting the platform services..." + status = pddf_switch_svc.start_platform_svc() + if not status: + if FORCE==0: + return status + + print "Restart the pmon service ..." + status, output = log_os_system("systemctl start pmon.service", 1) + if status: + print "Restarting pmon service failed" + if FORCE==0: + return status + + return + +if __name__ == "__main__": + main() diff --git a/platform/pddf/i2c/utils/pddfparse.py b/platform/pddf/i2c/utils/pddfparse.py new file mode 100755 index 000000000000..f9ce8fca0b42 --- /dev/null +++ b/platform/pddf/i2c/utils/pddfparse.py @@ -0,0 +1,1949 @@ +#!/usr/bin/env python +import argparse +import glob +import json +from jsonschema import validate +import os +import re +import subprocess +import sys +import time +import unicodedata + +bmc_cache={} +cache={} +SONIC_CFGGEN_PATH = '/usr/local/bin/sonic-cfggen' +HWSKU_KEY = 'DEVICE_METADATA.localhost.hwsku' +PLATFORM_KEY = 'DEVICE_METADATA.localhost.platform' + +dirname=os.path.dirname(os.path.realpath(__file__)) + +color_map = { + "STATUS_LED_COLOR_GREEN" : "green", + "STATUS_LED_COLOR_RED" : "red", + "STATUS_LED_COLOR_AMBER" : "amber", + "STATUS_LED_COLOR_BLUE" : "blue", + "STATUS_LED_COLOR_GREEN_BLINK" : "blinking green", + "STATUS_LED_COLOR_RED_BLINK" : "blinking red", + "STATUS_LED_COLOR_AMBER_BLINK" : "blinking amber", + "STATUS_LED_COLOR_BLUE_BLINK" : "blinking blue", + "STATUS_LED_COLOR_OFF" : "off" +} + + + + +class PddfParse(): + def __init__(self): + if not os.path.exists("/usr/share/sonic/platform"): + platform, hwsku = self.get_platform_and_hwsku() + os.symlink("/usr/share/sonic/device/"+platform, "/usr/share/sonic/platform") + + try: + with open('/usr/share/sonic/platform/pddf/pddf-device.json') as f: + self.data = json.load(f) + except IOError: + if os.path.exists('/usr/share/sonic/platform'): + os.unlink("/usr/share/sonic/platform") + raise Exception('PDDF JSON file not found. PDDF is not supported on this platform') + + + self.data_sysfs_obj={} + self.sysfs_obj={} + + + # Returns platform and HW SKU + def get_platform_and_hwsku(self): + try: + proc = subprocess.Popen([SONIC_CFGGEN_PATH, '-H', '-v', PLATFORM_KEY], + stdout=subprocess.PIPE, + shell=False, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + platform = stdout.rstrip('\n') + + proc = subprocess.Popen([SONIC_CFGGEN_PATH, '-d', '-v', HWSKU_KEY], + stdout=subprocess.PIPE, + shell=False, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + hwsku = stdout.rstrip('\n') + except OSError, e: + raise OSError("Cannot detect platform") + + return (platform, hwsku) + + ################################################################################################################### + # GENERIC DEFS + ################################################################################################################### + def runcmd(self, cmd): + rc = os.system(cmd) + if rc!=0: + print "%s -- command failed"%cmd + return rc + + def get_dev_idx(self, dev, ops): + parent=dev['dev_info']['virt_parent'] + pdev=self.data[parent] + + return pdev['dev_attr']['dev_idx'] + + + def get_path(self, target, attr): + aa = target + attr + + if aa in cache: + return cache[aa] + + string = None + p = re.search(r'\d+$', target) + if p is None: + for bb in filter(re.compile(target).search,self.data.keys()): + path = self.dev_parse(self.data[bb], { "cmd": "show_attr", "target":bb, "attr":attr }) + if path != "": + string = path + else: + if target in self.data.keys(): + path = self.dev_parse(self.data[target], { "cmd": "show_attr", "target":target, "attr":attr }) + if path != "": + string = path + + + if string is not None: + string = string.rstrip() + + cache[aa]=string + return string + + + def get_device_type(self, key): + if not key in self.data.keys(): + return None + return self.data[key]['dev_info']['device_type'] + + def get_platform(self): + return self.data['PLATFORM'] + + def get_num_psu_fans(self, dev): + if not dev in self.data.keys(): + return 0 + + if not 'num_psu_fans' in self.data[dev]['dev_attr']: + return 0 + + return self.data[dev]['dev_attr']['num_psu_fans'] + + def get_led_path(self): + return ("pddf/devices/led") + + def get_led_cur_state_path(self): + return ("pddf/devices/led/cur_state") + + def get_led_color(self): + color_f="/sys/kernel/pddf/devices/led/cur_state/color" + try: + with open(color_f, 'r') as f: + color = f.read().strip("\r\n") + except IOError: + return ("Error") + + return (color_map[color]) + + ################################################################################################################### + # CREATE DEFS + ################################################################################################################### + def create_device(self, attr, path, ops): + ret = 0 + for key in attr.keys(): + if type(attr[key]) is list: + val = " ".join(attr[key]) + else: + val = attr[key] + + cmd="echo '%s' > /sys/kernel/%s/%s"%(val, path, key) + ret=self.runcmd(cmd) + if ret!=0: + return ret + return ret + + + def create_psu_i2c_device(self, dev, ops): + create_ret = 0 + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['PSU']: + create_ret = self.create_device(dev['i2c']['topo_info'], "pddf/devices/psu/i2c", ops) + if create_ret!=0: + return create_ret + cmd= "echo '%s' > /sys/kernel/pddf/devices/psu/i2c/i2c_name"%(dev['dev_info']['device_name']) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + cmd= "echo '%s' > /sys/kernel/pddf/devices/psu/i2c/psu_idx"%( self.get_dev_idx(dev, ops)) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + for attr in dev['i2c']['attr_list']: + create_ret = self.create_device(attr, "pddf/devices/psu/i2c", ops) + if create_ret!=0: + return create_ret + cmd= "echo 'add' > /sys/kernel/pddf/devices/psu/i2c/attr_ops" + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + + cmd = "echo 'add' > /sys/kernel/pddf/devices/psu/i2c/dev_ops" + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + else: + cmd = "echo %s 0x%x > /sys/bus/i2c/devices/i2c-%d/new_device" % (dev['i2c']['topo_info']['dev_type'], + int(dev['i2c']['topo_info']['dev_addr'], 0), int(dev['i2c']['topo_info']['parent_bus'], 0)) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + + + return create_ret + + + + def create_psu_bmc_device(self, dev, ops): + print "" + + + def create_psu_device(self, dev, ops): + return self.create_psu_i2c_device(dev, ops ) + + def create_fan_device(self, dev, ops): + create_ret = 0 + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['FAN']: + create_ret = self.create_device(dev['i2c']['topo_info'], "pddf/devices/fan/i2c", ops) + if create_ret!=0: + return create_ret + cmd= "echo '%s' > /sys/kernel/pddf/devices/fan/i2c/i2c_name"%(dev['dev_info']['device_name']) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + create_ret = self.create_device(dev['i2c']['dev_attr'], "pddf/devices/fan/i2c", ops) + if create_ret!=0: + return create_ret + for attr in dev['i2c']['attr_list']: + create_ret = self.create_device(attr, "pddf/devices/fan/i2c", ops) + if create_ret!=0: + return create_ret + cmd= "echo 'add' > /sys/kernel/pddf/devices/fan/i2c/attr_ops" + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + + cmd= "echo 'add' > /sys/kernel/pddf/devices/fan/i2c/dev_ops" + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + else: + cmd= "echo %s 0x%x > /sys/bus/i2c/devices/i2c-%d/new_device" % (dev['i2c']['topo_info']['dev_type'], + int(dev['i2c']['topo_info']['dev_addr'], 0), int(dev['i2c']['topo_info']['parent_bus'], 0)) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + + return create_ret + + def create_temp_sensor_device(self, dev, ops): + create_ret = 0 + # NO PDDF driver for temp_sensors device + cmd= "echo %s 0x%x > /sys/bus/i2c/devices/i2c-%d/new_device" % (dev['i2c']['topo_info']['dev_type'], + int(dev['i2c']['topo_info']['dev_addr'], 0), int(dev['i2c']['topo_info']['parent_bus'], 0)) + create_ret = self.runcmd(cmd) + return create_ret + + + + + def create_cpld_device(self, dev, ops): + create_ret = 0 + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['CPLD']: + create_ret = self.create_device(dev['i2c']['topo_info'], "pddf/devices/cpld", ops) + if create_ret!=0: + return create_ret + + cmd= "echo '%s' > /sys/kernel/pddf/devices/cpld/i2c_name"%(dev['dev_info']['device_name']) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + # TODO: If attributes are provided then, use 'self.create_device' for them too + cmd= "echo 'add' > /sys/kernel/pddf/devices/cpld/dev_ops" + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + else: + cmd= "echo %s 0x%x > /sys/bus/i2c/devices/i2c-%d/new_device" % (dev['i2c']['topo_info']['dev_type'], + int(dev['i2c']['topo_info']['dev_addr'], 0), int(dev['i2c']['topo_info']['parent_bus'], 0)) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + + return create_ret + + def create_cpldmux_device(self, dev, ops): + create_ret = 0 + create_ret = self.create_device(dev['i2c']['topo_info'], "pddf/devices/cpldmux", ops) + if create_ret!=0: + return create_ret + cmd= "echo '%s' > /sys/kernel/pddf/devices/mux/i2c_name"%(dev['dev_info']['device_name']) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + self.create_device(dev['i2c']['dev_attr'], "pddf/devices/cpldmux", ops) + # Parse channel info + for chan in dev['i2c']['channel']: + self.create_device(chan, "pddf/devices/cpldmux", ops) + cmd="echo 'add' > /sys/kernel/pddf/devices/cpldmux/chan_ops" + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + + cmd= "echo 'add' > /sys/kernel/pddf/devices/cpldmux/dev_ops" + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + + def create_gpio_device(self, dev, ops): + create_ret = 0 + create_ret = self.create_device(dev['i2c']['topo_info'], "pddf/devices/gpio", ops) + if create_ret!=0: + return create_ret + cmd= "echo '%s' > /sys/kernel/pddf/devices/gpio/i2c_name"%(dev['dev_info']['device_name']) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + create_ret = self.create_device(dev['i2c']['dev_attr'], "pddf/devices/gpio", ops) + if create_ret!=0: + return create_ret + cmd= "echo 'add' > /sys/kernel/pddf/devices/gpio/dev_ops" + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + + time.sleep(2) + base = dev['i2c']['dev_attr']['gpio_base'] + for inst in dev['i2c']['ports']: + if inst['port_num']!="": + port_no = int(base, 16) + int(inst['port_num']) + cmd= "echo %d > /sys/class/gpio/export"%port_no + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + if inst['direction']!="": + cmd= "echo %s >/sys/class/gpio/gpio%d/direction"%(inst['direction'], port_no) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + if inst['value']!="": + for i in inst['value'].split(','): + cmd= "echo %s >/sys/class/gpio/gpio%d/value"%(i.rstrip(), port_no) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + + return create_ret + + def create_mux_device(self, dev, ops): + create_ret = 0 + create_ret = self.create_device(dev['i2c']['topo_info'], "pddf/devices/mux", ops) + if create_ret!=0: + return create_ret + cmd= "echo '%s' > /sys/kernel/pddf/devices/mux/i2c_name"%(dev['dev_info']['device_name']) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + self.create_device(dev['i2c']['dev_attr'], "pddf/devices/mux", ops) + cmd= "echo 'add' > /sys/kernel/pddf/devices/mux/dev_ops" + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + + + def create_xcvr_i2c_device(self, dev, ops): + create_ret = 0 + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['PORT_MODULE']: + self.create_device(dev['i2c']['topo_info'], "pddf/devices/xcvr/i2c", ops) + cmd= "echo '%s' > /sys/kernel/pddf/devices/xcvr/i2c/i2c_name"%(dev['dev_info']['device_name']) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + cmd="echo '%s' > /sys/kernel/pddf/devices/xcvr/i2c/dev_idx"%( self.get_dev_idx(dev, ops)) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + for attr in dev['i2c']['attr_list']: + self.create_device(attr, "pddf/devices/xcvr/i2c", ops) + cmd="echo 'add' > /sys/kernel/pddf/devices/xcvr/i2c/attr_ops" + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + + cmd="echo 'add' > /sys/kernel/pddf/devices/xcvr/i2c/dev_ops" + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + else: + cmd="echo %s 0x%x > /sys/bus/i2c/devices/i2c-%d/new_device" % (dev['i2c']['topo_info']['dev_type'], + int(dev['i2c']['topo_info']['dev_addr'], 0), int(dev['i2c']['topo_info']['parent_bus'], 0)) + create_ret = self.runcmd(cmd) + #print "\n" + if create_ret!=0: + return create_ret + # Add port name + port_name_sysfs = '/sys/bus/i2c/devices/{}-00{:02x}/port_name'.format( + int(dev['i2c']['topo_info']['parent_bus'], 0),int(dev['i2c']['topo_info']['dev_addr'], 0)) + + if os.path.exists(port_name_sysfs): + cmd="echo {} > /sys/bus/i2c/devices/{}-00{:02x}/port_name".format( + dev['dev_info']['virt_parent'].lower(), int(dev['i2c']['topo_info']['parent_bus'], 0), + int(dev['i2c']['topo_info']['dev_addr'], 0)) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + + return create_ret + + def create_xcvr_bmc_device(self, dev, ops): + print "" + + def create_xcvr_device(self, dev, ops): + return self.create_xcvr_i2c_device(dev, ops ) + + def create_sysstatus_device(self, dev, ops): + create_ret = 0 + for attr in dev['attr_list']: + self.create_device(attr, "pddf/devices/sysstatus", ops) + cmd= "echo 'add' > /sys/kernel/pddf/devices/sysstatus/attr_ops" + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + + def create_eeprom_device(self, dev, ops): + create_ret = 0 + if "EEPROM" in self.data['PLATFORM']['pddf_dev_types'] and \ + dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['EEPROM']: + self.create_device(dev['i2c']['topo_info'], "pddf/devices/eeprom/i2c", ops) + cmd= "echo '%s' > /sys/kernel/pddf/devices/eeprom/i2c/i2c_name"%(dev['dev_info']['device_name']) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + self.create_device(dev['i2c']['dev_attr'], "pddf/devices/eeprom/i2c", ops) + cmd = "echo 'add' > /sys/kernel/pddf/devices/eeprom/i2c/dev_ops" + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + + else: + cmd= "echo %s 0x%x > /sys/bus/i2c/devices/i2c-%d/new_device" % (dev['i2c']['topo_info']['dev_type'], + int(dev['i2c']['topo_info']['dev_addr'], 0), int(dev['i2c']['topo_info']['parent_bus'], 0)) + create_ret = self.runcmd(cmd) + if create_ret!=0: + return create_ret + + return create_ret + + ################################################################################################################### + # DELETE DEFS + ################################################################################################################### + def delete_eeprom_device(self, dev, ops): + if "EEPROM" in self.data['PLATFORM']['pddf_dev_types'] and \ + dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['EEPROM']: + cmd= "echo '%s' > /sys/kernel/pddf/devices/eeprom/i2c/i2c_name"%(dev['dev_info']['device_name']) + self.runcmd(cmd) + cmd = "echo 'delete' > /sys/kernel/pddf/devices/eeprom/i2c/dev_ops" + self.runcmd(cmd) + else: + cmd= "echo 0x%x > /sys/bus/i2c/devices/i2c-%d/delete_device" % (int(dev['i2c']['topo_info']['dev_addr'], 0), + int(dev['i2c']['topo_info']['parent_bus'], 0)) + self.runcmd(cmd) + + def delete_sysstatus_device(self, dev, ops): + # NOT A PHYSICAL DEVICE.... rmmod on module would remove all the artifacts + pass + + + def delete_xcvr_i2c_device(self, dev, ops): + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['PORT_MODULE']: + cmd= "echo '%s' > /sys/kernel/pddf/devices/xcvr/i2c/i2c_name"%(dev['dev_info']['device_name']) + self.runcmd(cmd) + cmd="echo 'delete' > /sys/kernel/pddf/devices/xcvr/i2c/dev_ops" + self.runcmd(cmd) + else: + cmd="echo 0x%x > /sys/bus/i2c/devices/i2c-%d/delete_device" % (int(dev['i2c']['topo_info']['dev_addr'], 0), + int(dev['i2c']['topo_info']['parent_bus'], 0)) + self.runcmd(cmd) + + def delete_xcvr_device(self, dev, ops): + self.delete_xcvr_i2c_device(dev, ops) + return + + def delete_gpio_device(self, dev, ops): + cmd= "echo '%s' > /sys/kernel/pddf/devices/gpio/i2c_name"%(dev['dev_info']['device_name']) + self.runcmd(cmd) + cmd= "echo 'delete' > /sys/kernel/pddf/devices/gpio/dev_ops" + self.runcmd(cmd) + + def delete_mux_device(self, dev, ops): + cmd= "echo '%s' > /sys/kernel/pddf/devices/mux/i2c_name"%(dev['dev_info']['device_name']) + self.runcmd(cmd) + cmd= "echo 'delete' > /sys/kernel/pddf/devices/mux/dev_ops" + self.runcmd(cmd) + + def delete_cpld_device(self, dev, ops): + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['CPLD']: + cmd= "echo '%s' > /sys/kernel/pddf/devices/cpld/i2c_name"%(dev['dev_info']['device_name']) + self.runcmd(cmd) + cmd= "echo 'delete' > /sys/kernel/pddf/devices/cpld/dev_ops" + self.runcmd(cmd) + else: + cmd= "echo 0x%x > /sys/bus/i2c/devices/i2c-%d/delete_device" % (int(dev['i2c']['topo_info']['dev_addr'], 0), + int(dev['i2c']['topo_info']['parent_bus'], 0)) + self.runcmd(cmd) + + def delete_cpldmux_device(self, dev, ops): + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['CPLDMUX']: + cmd= "echo '%s' > /sys/kernel/pddf/devices/cpldmux/i2c_name"%(dev['dev_info']['device_name']) + self.runcmd(cmd) + cmd= "echo 'delete' > /sys/kernel/pddf/devices/cpldmux/dev_ops" + self.runcmd(cmd) + + def delete_temp_sensor_device(self, dev, ops): + # NO PDDF driver for temp_sensors device + cmd= "echo 0x%x > /sys/bus/i2c/devices/i2c-%d/delete_device" % (int(dev['i2c']['topo_info']['dev_addr'], 0), + int(dev['i2c']['topo_info']['parent_bus'], 0)) + self.runcmd(cmd) + + def delete_fan_device(self, dev, ops): + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['FAN']: + cmd= "echo '%s' > /sys/kernel/pddf/devices/fan/i2c/i2c_name"%(dev['dev_info']['device_name']) + self.runcmd(cmd) + cmd= "echo 'delete' > /sys/kernel/pddf/devices/fan/i2c/dev_ops" + self.runcmd(cmd) + else: + cmd= "echo 0x%x > /sys/bus/i2c/devices/i2c-%d/delete_device" % (int(dev['i2c']['topo_info']['dev_addr'], 0), + int(dev['i2c']['topo_info']['parent_bus'], 0)) + self.runcmd(cmd) + + + def delete_psu_i2c_device(self, dev, ops): + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['PSU']: + cmd= "echo '%s' > /sys/kernel/pddf/devices/psu/i2c/i2c_name"%(dev['dev_info']['device_name']) + self.runcmd(cmd) + cmd = "echo 'delete' > /sys/kernel/pddf/devices/psu/i2c/dev_ops" + self.runcmd(cmd) + else: + cmd = "echo 0x%x > /sys/bus/i2c/devices/i2c-%d/delete_device" %(int(dev['i2c']['topo_info']['dev_addr'], 0), + int(dev['i2c']['topo_info']['parent_bus'], 0)) + self.runcmd(cmd) + + def delete_psu_device(self, dev, ops): + self.delete_psu_i2c_device(dev, ops ) + return + + + ################################################################################################################### + # SHOW ATTRIBIUTES DEFS + ################################################################################################################### + def is_led_device_configured(self, device_name, attr_name): + if device_name in self.data.keys(): + attr_list=self.data[device_name]['i2c']['attr_list'] + for attr in attr_list: + if attr['attr_name'].strip() == attr_name.strip(): + return (True) + return (False) + + + def show_device_sysfs(self, dev, ops): + parent=dev['dev_info']['device_parent'] + pdev=self.data[parent] + if pdev['dev_info']['device_parent'] == 'SYSTEM': + return "/sys/bus/i2c/devices/"+"i2c-%d"%int(pdev['i2c']['topo_info']['dev_addr'], 0) + return self.show_device_sysfs(pdev, ops) + "/" + "i2c-%d" % int(dev['i2c']['topo_info']['parent_bus'], 0) + + + # This is alid for 'at24' type of EEPROM devices. Only one attribtue 'eeprom' + def show_attr_eeprom_device(self, dev, ops): + str = "" + attr_name=ops['attr'] + attr_list=dev['i2c']['attr_list'] + KEY="eeprom" + dsysfs_path="" + + if not KEY in self.data_sysfs_obj: + self.data_sysfs_obj[KEY]=[] + + for attr in attr_list: + if attr_name == attr['attr_name'] or attr_name == 'all': + if 'drv_attr_name' in attr.keys(): + real_name = attr['drv_attr_name'] + else: + real_name = attr['attr_name'] + + dsysfs_path = self.show_device_sysfs(dev, ops)+"/%d-00%x"%(int(dev['i2c']['topo_info']['parent_bus'],0), + int(dev['i2c']['topo_info']['dev_addr'], 0))+"/%s"%real_name + if not dsysfs_path in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(dsysfs_path) + str += dsysfs_path+"\n" + return str + + def show_attr_gpio_device(self, dev, ops): + ret = "" + KEY="gpio" + if not KEY in self.data_sysfs_obj: + self.data_sysfs_obj[KEY]=[] + + return ret + + + def show_attr_mux_device(self, dev, ops): + ret = "" + KEY="mux" + if not KEY in self.data_sysfs_obj: + self.data_sysfs_obj[KEY]=[] + + return ret + + def show_attr_psu_i2c_device(self, dev, ops): + target=ops['target'] + attr_name=ops['attr'] + ret = "" + KEY="psu" + dsysfs_path="" + + if not KEY in self.data_sysfs_obj: + self.data_sysfs_obj[KEY]=[] + + if target == 'all' or target == dev['dev_info']['virt_parent'] : + attr_list=dev['i2c']['attr_list'] + for attr in attr_list: + if attr_name == attr['attr_name'] or attr_name == 'all' : + if 'attr_devtype' in attr.keys() and attr['attr_devtype'] == "gpio": + # Check and enable the gpio from class + gpio_dev = self.data[attr['attr_devname']] + base = int(gpio_dev['i2c']['dev_attr']['gpio_base'], 16) + port_num = base + int(attr['attr_offset'], 16) + gpio_name = 'gpio'+str(port_num) + attr_path = '/sys/class/gpio/'+gpio_name+'/value' + if (os.path.exists(attr_path)): + if not attr_path in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(attr_path) + ret += attr_path + '\n' + else: + if 'drv_attr_name' in attr.keys(): + real_name = attr['drv_attr_name'] + else: + real_name = attr['attr_name'] + + dsysfs_path = self.show_device_sysfs(dev, ops) + \ + "/%d-00%x"%(int(dev['i2c']['topo_info']['parent_bus'], 0), + int(dev['i2c']['topo_info']['dev_addr'], 0)) + \ + "/%s"%real_name + if not dsysfs_path in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(dsysfs_path) + ret += dsysfs_path+"\n" + return ret + + + def show_attr_psu_device(self, dev, ops): + return self.show_attr_psu_i2c_device(dev, ops ) + + + def show_attr_fan_device(self, dev, ops): + ret_str = "" + attr_name=ops['attr'] + attr_list=dev['i2c']['attr_list'] + KEY="fan" + dsysfs_path="" + + if not KEY in self.data_sysfs_obj: + self.data_sysfs_obj[KEY]=[] + + + for attr in attr_list: + if attr_name == attr['attr_name'] or attr_name == 'all': + if 'drv_attr_name' in attr.keys(): + real_name = attr['drv_attr_name'] + else: + real_name = attr['attr_name'] + + dsysfs_path= self.show_device_sysfs(dev, ops) + \ + "/%d-00%x" %(int(dev['i2c']['topo_info']['parent_bus'], 0), + int(dev['i2c']['topo_info']['dev_addr'], 0)) + \ + "/%s"%real_name + if not dsysfs_path in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(dsysfs_path) + ret_str += dsysfs_path+"\n" + return ret_str + + # This is only valid for LM75 + def show_attr_temp_sensor_device(self, dev, ops): + ret_str = "" + attr_name=ops['attr'] + attr_list=dev['i2c']['attr_list'] + KEY="temp-sensors" + dsysfs_path="" + + if not KEY in self.data_sysfs_obj: + self.data_sysfs_obj[KEY]=[] + + + for attr in attr_list: + if attr_name == attr['attr_name'] or attr_name == 'all': + path = self.show_device_sysfs(dev, ops) + \ + "/%d-00%x/" %(int(dev['i2c']['topo_info']['parent_bus'], 0), + int(dev['i2c']['topo_info']['dev_addr'], 0)) + if 'drv_attr_name' in attr.keys(): + real_name = attr['drv_attr_name'] + else: + real_name = attr['attr_name'] + + if (os.path.exists(path)): + full_path = glob.glob(path + 'hwmon/hwmon*/' + real_name)[0] + dsysfs_path=full_path + if not dsysfs_path in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(dsysfs_path) + ret_str += full_path + "\n" + return ret_str + + def show_attr_sysstatus_device(self, dev, ops): + ret = "" + attr_name=ops['attr'] + attr_list=dev['attr_list'] + KEY="sys-status" + dsysfs_path="" + + if not KEY in self.data_sysfs_obj: + self.data_sysfs_obj[KEY]=[] + + + for attr in attr_list: + if attr_name == attr['attr_name'] or attr_name == 'all': + dsysfs_path = "/sys/kernel/pddf/devices/sysstatus/sysstatus_data/" + attr['attr_name'] + if not dsysfs_path in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(dsysfs_path) + ret += dsysfs_path+"\n" + return ret + + + def show_attr_xcvr_i2c_device(self, dev, ops): + target=ops['target'] + attr_name=ops['attr'] + ret = "" + dsysfs_path = "" + KEY="xcvr" + if not KEY in self.data_sysfs_obj: + self.data_sysfs_obj[KEY]=[] + + if target == 'all' or target == dev['dev_info']['virt_parent'] : + attr_list=dev['i2c']['attr_list'] + for attr in attr_list: + if attr_name == attr['attr_name'] or attr_name == 'all' : + if 'attr_devtype' in attr.keys() and attr['attr_devtype'] == "gpio": + # Check and enable the gpio from class + gpio_dev = self.data[attr['attr_devname']] + base = int(gpio_dev['i2c']['dev_attr']['gpio_base'], 16) + port_num = base + int(attr['attr_offset'], 16) + gpio_name = 'gpio'+str(port_num) + attr_path = '/sys/class/gpio/'+gpio_name+'/value' + if (os.path.exists(attr_path)): + if not attr_path in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(attr_path) + ret += attr_path + '\n' + else: + if 'drv_attr_name' in attr.keys(): + real_name = attr['drv_attr_name'] + else: + real_name = attr['attr_name'] + + dsysfs_path = self.show_device_sysfs(dev, ops) + \ + "/%d-00%x" %(int(dev['i2c']['topo_info']['parent_bus'], 0), + int(dev['i2c']['topo_info']['dev_addr'], 0)) + \ + "/%s"%real_name + if not dsysfs_path in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(dsysfs_path) + ret += dsysfs_path+"\n" + return ret + + + def show_attr_xcvr_device(self, dev, ops): + return self.show_attr_xcvr_i2c_device(dev, ops ) + + def show_attr_cpld_device(self, dev, ops): + ret = "" + KEY="cpld" + if not KEY in self.data_sysfs_obj: + self.data_sysfs_obj[KEY]=[] + + return ret + + def show_attr_cpldmux_device(self, dev, ops): + ret = "" + KEY="cpldmux" + if not KEY in self.data_sysfs_obj: + self.data_sysfs_obj[KEY]=[] + + return ret + + + ################################################################################################################### + # SHOW DEFS + ################################################################################################################### + def check_led_cmds(self, key, ops): + name = ops['target']+'_LED' + if (ops['target']=='config' or ops['attr']=='all') or \ + (name==self.data[key]['dev_info']['device_name'] and + ops['attr']==self.data[key]['dev_attr']['index']): + return (True) + else: + return (False) + + def dump_sysfs_obj(self, obj, key_type): + if (key_type == 'keys'): + for key in obj.keys(): + print key + return + + for key in obj: + if (key == key_type or key_type == 'all'): + print key+":" + for entry in obj[key]: + print "\t"+entry + + def add_list_sysfs_obj(self, obj, KEY, list): + for sysfs in list: + if not sysfs in obj[KEY]: + obj[KEY].append(sysfs) + + def sysfs_attr(self, key, value, path, obj, obj_key): + sysfs_path="/sys/kernel/%s/%s"%(path, key) + if not sysfs_path in obj[obj_key]: + obj[obj_key].append(sysfs_path) + + + def sysfs_device(self, attr, path, obj, obj_key): + for key in attr.keys(): + sysfs_path="/sys/kernel/%s/%s"%(path, key) + if not sysfs_path in obj[obj_key]: + obj[obj_key].append(sysfs_path) + + def show_eeprom_device(self, dev, ops): + return + + + def show_mux_device(self, dev, ops): + KEY ='mux' + if not KEY in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + self.sysfs_device(dev['i2c']['topo_info'], "pddf/devices/mux", self.sysfs_obj, KEY) + self.sysfs_device(dev['i2c']['dev_attr'], "pddf/devices/mux", self.sysfs_obj, KEY) + sysfs_path= "/sys/kernel/pddf/devices/mux/dev_ops" + if not sysfs_path in self.sysfs_obj[KEY]: + self.sysfs_obj[KEY].append(sysfs_path) + list=['/sys/kernel/pddf/devices/mux/i2c_type', + '/sys/kernel/pddf/devices/mux/i2c_name', + '/sys/kernel/pddf/devices/mux/error'] + self.add_list_sysfs_obj(self.sysfs_obj, KEY, list) + + def show_gpio_device(self, dev, ops): + KEY ='gpio' + if not KEY in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + self.sysfs_device(dev['i2c']['topo_info'], "pddf/devices/gpio", self.sysfs_obj, KEY) + self.sysfs_device(dev['i2c']['dev_attr'], "pddf/devices/gpio", self.sysfs_obj, KEY) + sysfs_path= "/sys/kernel/pddf/devices/gpio/dev_ops" + if not sysfs_path in self.sysfs_obj[KEY]: + self.sysfs_obj[KEY].append(sysfs_path) + list=['/sys/kernel/pddf/devices/gpio/i2c_type', + '/sys/kernel/pddf/devices/gpio/i2c_name', + '/sys/kernel/pddf/devices/gpio/error'] + self.add_list_sysfs_obj(self.sysfs_obj, KEY, list) + + + def show_psu_i2c_device(self, dev, ops): + KEY ='psu' + path='pddf/devices/psu/i2c' + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['PSU']: + if not KEY in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + self.sysfs_device(dev['i2c']['topo_info'], path, self.sysfs_obj, KEY) + sysfs_path = "/sys/kernel/pddf/devices/psu/i2c/psu_idx" + self.sysfs_obj[KEY].append(sysfs_path) + + for attr in dev['i2c']['attr_list']: + self.sysfs_device(attr, "pddf/devices/psu/i2c", self.sysfs_obj, KEY) + sysfs_path = "/sys/kernel/pddf/devices/psu/i2c/dev_ops" + if not sysfs_path in self.sysfs_obj[KEY]: + self.sysfs_obj[KEY].append(sysfs_path) + list=['/sys/kernel/pddf/devices/psu/i2c/i2c_type', + '/sys/kernel/pddf/devices/fan/i2c/i2c_name', + '/sys/kernel/pddf/devices/psu/i2c/error', + '/sys/kernel/pddf/devices/psu/i2c/attr_ops'] + self.add_list_sysfs_obj(self.sysfs_obj, KEY, list) + + + def show_psu_device(self, dev, ops): + self.show_psu_i2c_device(dev, ops ) + return + + def show_client_device(self): + KEY ='client' + if not KEY in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + list=['/sys/kernel/pddf/devices/showall'] + self.add_list_sysfs_obj(self.sysfs_obj, KEY, list) + + + def show_fan_device(self, dev, ops): + KEY ='fan' + path='pddf/devices/fan/i2c' + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['FAN']: + if not KEY in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + + self.sysfs_device(dev['i2c']['topo_info'], path, self.sysfs_obj, KEY) + self.sysfs_device(dev['i2c']['dev_attr'], path, self.sysfs_obj, KEY) + for attr in dev['i2c']['attr_list']: + self.sysfs_device(attr, path, self.sysfs_obj, KEY) + list=['/sys/kernel/pddf/devices/fan/i2c/i2c_type', + '/sys/kernel/pddf/devices/fan/i2c/i2c_name', + '/sys/kernel/pddf/devices/fan/i2c/error', + '/sys/kernel/pddf/devices/fan/i2c/attr_ops', + '/sys/kernel/pddf/devices/fan/i2c/dev_ops'] + self.add_list_sysfs_obj(self.sysfs_obj, KEY, list) + + + def show_temp_sensor_device(self, dev, ops): + return + + def show_sysstatus_device(self, dev, ops): + KEY ='sysstatus' + if not KEY in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + for attr in dev['attr_list']: + self.sysfs_device(attr, "pddf/devices/sysstatus", self.sysfs_obj, KEY) + sysfs_path= "/sys/kernel/pddf/devices/sysstatus/attr_ops" + if not sysfs_path in self.sysfs_obj[KEY]: + self.sysfs_obj[KEY].append(sysfs_path) + + + def show_xcvr_i2c_device(self, dev, ops): + KEY ='xcvr' + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['PORT_MODULE']: + if not KEY in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + self.sysfs_device(dev['i2c']['topo_info'], "pddf/devices/xcvr/i2c", self.sysfs_obj, KEY) + + for attr in dev['i2c']['attr_list']: + self.sysfs_device(attr, "pddf/devices/xcvr/i2c", self.sysfs_obj, KEY) + sysfs_path = "/sys/kernel/pddf/devices/xcvr/i2c/dev_ops" + if not sysfs_path in self.sysfs_obj[KEY]: + self.sysfs_obj[KEY].append(sysfs_path) + list=['/sys/kernel/pddf/devices/xcvr/i2c/i2c_type', + '/sys/kernel/pddf/devices/xcvr/i2c/i2c_name', + '/sys/kernel/pddf/devices/xcvr/i2c/error', + '/sys/kernel/pddf/devices/xcvr/i2c/attr_ops'] + self.add_list_sysfs_obj(self.sysfs_obj, KEY, list) + + + def show_xcvr_device(self, dev, ops): + self.show_xcvr_i2c_device(dev, ops ) + return + + def show_cpld_device(self, dev, ops): + KEY ='cpld' + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['CPLD']: + if not KEY in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + self.sysfs_device(dev['i2c']['topo_info'], "pddf/devices/cpld", self.sysfs_obj, KEY) + sysfs_path= "/sys/kernel/pddf/devices/cpld/dev_ops" + if not sysfs_path in self.sysfs_obj[KEY]: + self.sysfs_obj[KEY].append(sysfs_path) + list=['/sys/kernel/pddf/devices/cpld/i2c_type', + '/sys/kernel/pddf/devices/cpld/i2c_name', + '/sys/kernel/pddf/devices/cpld/error'] + self.add_list_sysfs_obj(self.sysfs_obj, KEY, list) + + def show_led_platform_device(self, key, ops): + if ops['attr']=='all' or ops['attr']=='PLATFORM': + KEY='platform' + if not KEY in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + path='pddf/devices/platform' + self.sysfs_attr('num_psus', self.data['PLATFORM']['num_psus'], path, self.sysfs_obj, KEY) + self.sysfs_attr('num_fantrays', self.data['PLATFORM']['num_fantrays'], path, self.sysfs_obj, KEY) + + def show_led_device(self, key, ops): + if self.check_led_cmds(key, ops): + KEY='led' + if not KEY in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + path="pddf/devices/led" + for attr in self.data[key]['i2c']['attr_list']: + self.sysfs_attr('device_name', self.data[key]['dev_info']['device_name'],path,self.sysfs_obj,KEY) + self.sysfs_attr('swpld_addr', self.data[key]['dev_info']['device_name'],path,self.sysfs_obj, KEY) + self.sysfs_attr('swpld_addr_offset',self.data[key]['dev_info']['device_name'], + path,self.sysfs_obj, KEY) + self.sysfs_device(self.data[key]['dev_attr'], path, self.sysfs_obj, KEY) + for attr_key in attr.keys(): + attr_path="pddf/devices/led/" + attr['attr_name'] + if (attr_key != 'attr_name' and attr_key != 'swpld_addr' and attr_key != 'swpld_addr_offset'): + self.sysfs_attr(attr_key, attr[attr_key], attr_path, self.sysfs_obj, KEY) + sysfs_path="/sys/kernel/pddf/devices/led/dev_ops" + if not sysfs_path in self.sysfs_obj[KEY]: + self.sysfs_obj[KEY].append(sysfs_path) + list=['/sys/kernel/pddf/devices/led/cur_state/color'] + self.add_list_sysfs_obj(self.sysfs_obj, KEY, list) + + + def validate_xcvr_device(self, dev, ops): + devtype_list = ['optoe1', 'optoe2'] + dev_attribs = ['xcvr_present', 'xcvr_reset', 'xcvr_intr_status', 'xcvr_lpmode'] + ret_val = "xcvr validation failed" + + if dev['i2c']['topo_info']['dev_type'] in devtype_list: + for attr in dev['i2c']['attr_list']: + if 'attr_name' in attr.keys() and 'eeprom' in attr.values(): + ret_val = "xcvr validation success" + else: + print "xcvr validation Failed" + return + + elif dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['PORT_MODULE']: + for attr in dev['i2c']['attr_list']: + if attr.get("attr_name") in dev_attribs: + ret_val = "Success" + else: + print "xcvr validation Failed" + return + print ret_val + + def validate_eeprom_device(self, dev, ops): + devtype_list = ['24c02'] + dev_access_mode = ['BLOCK', 'BYTE'] + dev_attribs = ['eeprom'] + ret_val = "eeprom failed" + + if dev['i2c']['topo_info']['dev_type'] in devtype_list: + if dev['i2c']['dev_attr']['access_mode'] in dev_access_mode: + for attr in dev['i2c']['attr_list']: + if attr.get("attr_name") in dev_attribs: + ret_val = "eeprom success" + print ret_val + + def validate_mux_device(self, dev, ops): + devtype_list = ['pca9548', 'pca954x'] + dev_channels = ["0", "1", "2", "3", "4", "5", "6", "7"] + ret_val = "mux failed" + + if dev['i2c']['topo_info']['dev_type'] in devtype_list: + for attr in dev['i2c']['channel']: + if attr.get("chn") in dev_channels: + ret_val = "Mux success" + print ret_val + + def validate_cpld_device(self, dev, ops): + devtype_list = ['i2c_cpld'] + ret_val = "cpld failed" + + if dev['i2c']['topo_info']['dev_type'] in devtype_list: + ret_val = "cpld success" + print ret_val + + + def validate_sysstatus_device(self, dev, ops): + dev_attribs = ['board_info', 'cpld1_version', 'power_module_status', 'system_reset5', + 'system_reset6', 'system_reset7', 'misc1', 'cpld2_version', 'cpld3_version' + ] + ret_val = "sysstatus failed" + + if dev['dev_info']['device_type'] == "SYSSTAT": + for attr in dev['attr_list']: + if attr.get("attr_name") in dev_attribs: + ret_val = "sysstatus success" + print ret_val + + def validate_temp_sensor_device(self, dev, ops): + devtype_list = ['lm75'] + dev_attribs = ['temp1_max', 'temp1_max_hyst', 'temp1_input'] + ret_val = "temp sensor failed" + + if dev['dev_info']['device_type'] == "TEMP_SENSOR": + if dev['i2c']['topo_info']['dev_type'] in devtype_list: + for attr in dev['i2c']['attr_list']: + if attr.get("attr_name") in dev_attribs: + ret_val = "tempsensor success" + print ret_val + + def validate_fan_device(self, dev, ops): + ret_val = "fan failed" + + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['FAN']: + if dev['i2c']['dev_attr']['num_fan'] is not None: + ret_val = "fan success" + + print ret_val + + def validate_psu_device(self, dev, ops): + dev_attribs = ['psu_present', 'psu_model_name', 'psu_power_good', 'psu_mfr_id', 'psu_serial_num', + 'psu_fan_dir', 'psu_v_out', 'psu_i_out', 'psu_p_out', 'psu_fan1_speed_rpm' + ] + ret_val = "psu failed" + + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['PSU']: + for attr in dev['i2c']['attr_list']: + if attr.get("attr_name") in dev_attribs: + if attr.get("attr_devaddr") is not None: + if attr.get("attr_offset") is not None: + if attr.get("attr_mask") is not None: + if attr.get("attr_len") is not None: + ret_val = "psu success" + else: + ret_val = "psu failed" + + print ret_val + + ################################################################################################################### + # SPYTEST + ################################################################################################################### + def verify_attr(self, key, attr, path): + node="/sys/kernel/%s/%s"%(path, key) + try: + with open(node, 'r') as f: + status = f.read() + except IOError: + print "PDDF_VERIFY_ERR: IOError: node:%s key:%s"%(node, key) + return + + status=status.rstrip("\n\r") + if attr[key]!=status: + print "PDDF_VERIFY_ERR: node: %s switch:%s"%(node, status) + + def verify_device(self, attr, path, ops): + for key in attr.keys(): + self.verify_attr(key, attr, path) + + + def get_led_device(self, device_name): + self.create_attr('device_name', self.data[device_name]['dev_info']['device_name'], "pddf/devices/led") + self.create_attr('index', self.data[device_name]['dev_attr']['index'], "pddf/devices/led") + cmd="echo 'verify' > /sys/kernel/pddf/devices/led/dev_ops" + self.runcmd(cmd) + + def validate_sysfs_creation(self, obj, validate_type): + dir = '/sys/kernel/pddf/devices/'+validate_type + if (os.path.exists(dir) or validate_type=='client'): + for sysfs in obj[validate_type]: + if(not os.path.exists(sysfs)): + print "[SYSFS FILE] " + sysfs + ": does not exist" + else: + print "[SYSFS DIR] " + dir + ": does not exist" + + def validate_dsysfs_creation(self, obj, validate_type): + if validate_type in obj.keys(): + # There is a possibility that some components dont have any device-self.data attr + if not obj[validate_type]: + print "[SYSFS ATTR] for " + validate_type + ": empty " + else: + for sysfs in obj[validate_type]: + if(not os.path.exists(sysfs)): + print "[SYSFS FILE] " + sysfs + ": does not exist" + else: + print "[SYSFS KEY] for " + validate_type + ": not configured" + + def verify_sysfs_data(self, verify_type): + if (verify_type=='LED'): + for key in self.data.keys(): + if key != 'PLATFORM': + attr=self.data[key]['dev_info'] + if attr['device_type'] == 'LED': + self.get_led_device(key) + self.verify_attr('device_name', self.data[key]['dev_info'], "pddf/devices/led") + self.verify_attr('index', self.data[key]['dev_attr'], "pddf/devices/led") + for attr in self.data[key]['i2c']['attr_list']: + path="pddf/devices/led/" + attr['attr_name'] + for entry in attr.keys(): + if (entry != 'attr_name' and entry != 'swpld_addr' and entry != 'swpld_addr_offset'): + self.verify_attr(entry, attr, path) + if ( entry == 'swpld_addr' or entry == 'swpld_addr_offset'): + self.verify_attr(entry, attr, 'pddf/devices/led') + + + + def schema_validation(self, validate_type): + process_validate_type = 0 + for key in self.data.keys(): + if (key != 'PLATFORM'): + temp_obj={} + schema_list=[] + try: + device_type=self.data[key]["dev_info"]["device_type"] + except Exception as e: + print "dev_info or device_type ERROR: " + key + print e + + if validate_type == 'mismatch': + process_validate_type = 1 + device_type="PSU" + schema_file="/usr/local/bin/schema/FAN.schema" + schema_list.append(schema_file) + elif validate_type == 'missing': + process_validate_type = 1 + schema_file="/usr/local/bin/schema/PLATFORM.schema" + schema_list.append(schema_file) + + elif validate_type == 'empty': + process_validate_type = 1 + if not device_type: + print "Empty device_type for " + key + continue + elif (validate_type=='all' or validate_type==device_type): + process_validate_type = 1 + if "bmc" in self.data[key].keys(): + schema_file="/usr/local/bin/schema/"+device_type + "_BMC.schema" + schema_list.append(schema_file) + + if "i2c" in self.data[key].keys(): + schema_file="/usr/local/bin/schema/"+device_type + ".schema" + schema_list.append(schema_file) + if device_type: + temp_obj[device_type]=self.data[key] + for schema_file in schema_list: + if (os.path.exists(schema_file)): + print "Validate " + schema_file + ";" + key + json_data=json.dumps(temp_obj) + with open(schema_file, 'r') as f: + schema=json.load(f) + try: + validate(temp_obj, schema) + except Exception as e: + print "Validation ERROR: " + schema_file + ";" + key + if validate_type == 'mismatch': + return + else: + print e + else: + print "ERROR Missing File: " + schema_file + if not process_validate_type: + print "device_type: " + validate_type + " not configured" + + def modules_validation(self, validate_type): + kos = [] + supported_type = False + module_validation_status=[] + + if validate_type == "bmc": + kos=['ipmi_devintf', 'ipmi_si', 'ipmi_msghandler'] + validate_type = 'ipmi' + else: + # generate the KOS list from pddf device JSON file + kos.extend(self.data['PLATFORM']['pddf_kos']) + + if 'custom_kos' in self.data['PLATFORM']: + kos.extend(self.data['PLATFORM']['custom_kos']) + + for mod in kos: + if validate_type in mod or validate_type == "pddf": + supported_type=True + cmd = "lsmod | grep " + mod + try: + subprocess.check_output(cmd, shell=True) + except Exception as e: + module_validation_status.append(mod) + if supported_type: + if module_validation_status: + module_validation_status.append(":ERROR not loaded") + print str(module_validation_status)[1:-1] + else: + print "Loaded" + else: + print validate_type + " not configured" + + + + + + ################################################################################################################### + # PARSE DEFS + ################################################################################################################### + def psu_parse(self, dev, ops): + parse_str="" + ret="" + for ifce in dev['i2c']['interface']: + ret=getattr(self, ops['cmd']+"_psu_device")(self.data[ifce['dev']], ops ) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + print "{}_psu_device failed".format(ops['cmd']) + return ret + else: + pass + else: + # in case of 'show_attr' functions + parse_str+=ret + return parse_str + + def fan_parse(self, dev, ops): + parse_str="" + ret=getattr(self, ops['cmd']+"_fan_device")(dev, ops ) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + print "{}_fan_device failed".format(ops['cmd']) + return ret + else: + pass + else: + # in case of 'show_attr' functions + parse_str+=ret + + return parse_str + + def temp_sensor_parse(self, dev, ops): + parse_str="" + ret=getattr(self, ops['cmd']+"_temp_sensor_device")(dev, ops ) + if not ret is None: + if str(ret).isdigit() : + if ret!=0: + # in case if 'create' functions + print "{}_temp_sensor_device failed".format(ops['cmd']) + return ret + else: + pass + else: + # in case of 'show_attr' functions + parse_str+=ret + + return parse_str + + def cpld_parse(self, dev, ops): + parse_str = "" + ret = getattr(self, ops['cmd']+"_cpld_device")(dev, ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + print "{}_cpld_device failed".format(ops['cmd']) + return ret + else: + pass + else: + # in case of 'show_attr' functions + parse_str+=ret + + return parse_str + + def cpldmux_parse(self, dev, ops): + parse_str = "" + ret = getattr(self, ops['cmd']+"_cpldmux_device")(dev, ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + print "{}_cpldmux_device() cmd failed".format(ops['cmd']) + return ret + else: + pass + else: + parse_str += ret + + for chan in dev['i2c']['channel']: + for device in chan['dev']: + ret = self.dev_parse(self.data[device], ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + return ret + else: + pass + else: + parse_str += ret + + return parse_str + + def cpldmux_parse_reverse(self, dev, ops): + parse_str = "" + for chan in reversed(dev['i2c']['channel']): + for device in reversed(chan['dev']): + ret = self.dev_parse(self.data[device], ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + return ret + else: + pass + else: + parse_str += ret + + ret = getattr(self, ops['cmd']+"_cpldmux_device")(dev, ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + print "{}_cpldmux_device() cmd failed".format(ops['cmd']) + return ret + else: + pass + else: + parse_str += ret + + return parse_str + + + def sysstatus_parse(self, dev,ops): + parse_str = "" + ret = getattr(self, ops['cmd']+"_sysstatus_device")(dev, ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + print "{}_sysstatus_device failed".format(ops['cmd']) + return ret + else: + pass + else: + # in case of 'show_attr' functions + parse_str+=ret + + return parse_str + + def gpio_parse(self, dev, ops): + parse_str = "" + ret = getattr(self, ops['cmd']+"_gpio_device")(dev, ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + print "{}_temp_sensor_device failed".format(ops['cmd']) + return ret + else: + pass + else: + # in case of 'show_attr' functions + parse_str += ret + + return parse_str + + + def mux_parse(self, dev, ops): + parse_str = "" + ret = getattr(self, ops['cmd']+"_mux_device")(dev, ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + print "{}_mux_device() cmd failed".format(ops['cmd']) + return ret + else: + pass + else: + parse_str += ret + + for ch in dev['i2c']['channel']: + ret = self.dev_parse(self.data[ch['dev']], ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + return ret + else: + pass + else: + parse_str += ret + return parse_str + + def mux_parse_reverse(self, dev, ops): + parse_str = "" + for ch in reversed(dev['i2c']['channel']): + ret = self.dev_parse(self.data[ch['dev']], ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + return ret + else: + pass + else: + parse_str += ret + + ret = getattr(self, ops['cmd']+"_mux_device")(dev, ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + print "{}_mux_device() cmd failed".format(ops['cmd']) + return ret + else: + pass + else: + parse_str += ret + + return parse_str + + + def eeprom_parse(self, dev, ops): + parse_str = "" + ret = getattr(self, ops['cmd']+"_eeprom_device")(dev, ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + print "{}_eeprom_device() cmd failed".format(ops['cmd']) + return ret + else: + pass + else: + parse_str += ret + + return parse_str + + def optic_parse(self, dev, ops): + parse_str="" + ret="" + for ifce in dev['i2c']['interface']: + ret=getattr(self, ops['cmd']+"_xcvr_device")(self.data[ifce['dev']], ops ) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + print "{}_eeprom_device() cmd failed".format(ops['cmd']) + return ret + else: + pass + else: + parse_str+=ret + return parse_str + + def cpu_parse(self, bus, ops): + parse_str = "" + for dev in bus['i2c']['CONTROLLERS']: + dev1 = self.data[dev['dev']] + for d in dev1['i2c']['DEVICES']: + ret=self.dev_parse(self.data[d['dev']], ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + return ret + else: + pass + else: + parse_str += ret + return parse_str + + def cpu_parse_reverse(self, bus, ops): + parse_str = "" + for dev in reversed(bus['i2c']['CONTROLLERS']): + dev1 = self.data[dev['dev']] + for d in reversed(dev1['i2c']['DEVICES']): + ret=self.dev_parse(self.data[d['dev']], ops) + if not ret is None: + if str(ret).isdigit(): + if ret!=0: + # in case if 'create' functions + return ret + else: + pass + else: + parse_str += ret + return parse_str + + + def dev_parse(self, dev, ops): + attr=dev['dev_info'] + if attr['device_type'] == 'CPU': + if ops['cmd']=='delete': + return self.cpu_parse_reverse(dev, ops) + else: + return self.cpu_parse(dev, ops) + + if attr['device_type'] == 'EEPROM': + return self.eeprom_parse(dev, ops) + + if attr['device_type'] == 'MUX': + if ops['cmd']=='delete': + return self.mux_parse_reverse(dev, ops) + else: + return self.mux_parse(dev, ops) + + if attr['device_type'] == 'GPIO': + return self.gpio_parse(dev, ops) + + if attr['device_type'] == 'PSU': + return self.psu_parse(dev, ops) + + if attr['device_type'] == 'FAN': + return self.fan_parse(dev, ops) + + if attr['device_type'] == 'TEMP_SENSOR': + return self.temp_sensor_parse(dev, ops) + + if attr['device_type'] == 'SFP' or attr['device_type'] == 'SFP28' or \ + attr['device_type'] == 'QSFP' or attr['device_type'] == 'QSFP28': + return self.optic_parse(dev, ops) + + if attr['device_type'] == 'CPLD': + return self.cpld_parse(dev, ops) + + if attr['device_type'] == 'CPLDMUX': + if ops['cmd']=='delete': + return self.cpldmux_parse_reverse(dev, ops) + else: + return self.cpldmux_parse(dev, ops) + + if attr['device_type'] == 'SYSSTAT': + return self.sysstatus_parse(dev,ops) + + def is_supported_sysled_state(self, sysled_name, sysled_state): + if not sysled_name in self.data.keys(): + return False, "[FAILED] " + sysled_name + " is not configured" + for attr in self.data[sysled_name]['i2c']['attr_list']: + if attr['attr_name'] == sysled_state: + return True, "[PASS] supported" + return False, "[FAILED]: Invalid color" + + + def create_attr(self, key, value, path): + cmd = "echo '%s' > /sys/kernel/%s/%s"%(value, path, key) + self.runcmd(cmd) + + def create_led_platform_device(self, key, ops): + if ops['attr']=='all' or ops['attr']=='PLATFORM': + path='pddf/devices/platform' + self.create_attr('num_psus', self.data['PLATFORM']['num_psus'], path) + self.create_attr('num_fantrays', self.data['PLATFORM']['num_fantrays'], path) + + def create_led_device(self, key, ops): + if ops['attr']=='all' or ops['attr']==self.data[key]['dev_info']['device_name']: + path="pddf/devices/led" + for attr in self.data[key]['i2c']['attr_list']: + self.create_attr('device_name', self.data[key]['dev_info']['device_name'], path) + self.create_device(self.data[key]['dev_attr'], path, ops) + for attr_key in attr.keys(): + if (attr_key == 'swpld_addr_offset' or attr_key == 'swpld_addr'): + self.create_attr(attr_key, attr[attr_key], path) + elif (attr_key != 'attr_name' and attr_key != 'descr' and + attr_key != 'attr_devtype' and attr_key != 'attr_devname'): + state_path=path+'/state_attr' + self.create_attr(attr_key, attr[attr_key],state_path) + cmd="echo '" + attr['attr_name']+"' > /sys/kernel/pddf/devices/led/dev_ops" + self.runcmd(cmd) + + + + def led_parse(self, ops): + getattr(self, ops['cmd']+"_led_platform_device")("PLATFORM", ops) + for key in self.data.keys(): + if key != 'PLATFORM' and 'dev_info' in self.data[key]: + attr=self.data[key]['dev_info'] + if attr['device_type'] == 'LED': + getattr(self, ops['cmd']+"_led_device")(key, ops) + + + def get_device_list(self, list, type): + for key in self.data.keys(): + if key != 'PLATFORM' and 'dev_info' in self.data[key]: + attr=self.data[key]['dev_info'] + if attr['device_type'] == type: + list.append(self.data[key]) + + + def create_pddf_devices(self): + self.led_parse({ "cmd": "create", "target":"all", "attr":"all" }) + create_ret = 0 + create_ret = self.dev_parse(self.data['SYSTEM'], { "cmd": "create", "target":"all", "attr":"all" } ) + if create_ret!=0: + return create_ret + if 'SYSSTATUS' in self.data: + create_ret = self.dev_parse(self.data['SYSSTATUS'], { "cmd": "create", "target":"all", "attr":"all" } ) + if create_ret!=0: + return create_ret + + def delete_pddf_devices(self): + self.dev_parse(self.data['SYSTEM'], { "cmd": "delete", "target":"all", "attr":"all" } ) + if 'SYSSTATUS' in self.data: + self.dev_parse(self.data['SYSSTATUS'], { "cmd": "delete", "target":"all", "attr":"all" } ) + + def populate_pddf_sysfsobj(self): + self.dev_parse(self.data['SYSTEM'], { "cmd": "show", "target":"all", "attr":"all" } ) + if 'SYSSTATUS' in self.data: + self.dev_parse(self.data['SYSSTATUS'], { "cmd": "show", "target":"all", "attr":"all" } ) + self.led_parse({ "cmd": "show", "target":"all", "attr":"all" }) + self.show_client_device() + + def cli_dump_dsysfs(self, component): + self.dev_parse(self.data['SYSTEM'], { "cmd": "show_attr", "target":"all", "attr":"all" } ) + if 'SYSSTATUS' in self.data: + self.dev_parse(self.data['SYSSTATUS'], { "cmd": "show_attr", "target":"all", "attr":"all" } ) + if component in self.data_sysfs_obj: + return self.data_sysfs_obj[component] + else: + return None + + + def validate_pddf_devices(self, *args): + self.populate_pddf_sysfsobj() + v_ops = { 'cmd': 'validate', 'target':'all', 'attr':'all' } + self.dev_parse(self.data['SYSTEM'], v_ops ) + + ################################################################################################################## + # BMC APIs + ################################################################################################################## + def populate_bmc_cache_db(self, bmc_attr): + bmc_cmd = str(bmc_attr['bmc_cmd']).strip() + + if 'delimiter' in bmc_attr.keys(): + delim = str(bmc_attr['delimiter']).strip() + else: + delim = None + + o_list = subprocess.check_output(bmc_cmd, shell=True).strip().split('\n') + bmc_cache[bmc_cmd]={} + bmc_cache[bmc_cmd]['time']=time.time() + for entry in o_list: + name = entry.split(delim)[0].strip() + bmc_cache[bmc_cmd][name]=entry + + def non_raw_ipmi_get_request(self, bmc_attr): + bmc_db_update_time=1 + value = 'N/A' + bmc_cmd = str(bmc_attr['bmc_cmd']).strip() + field_name = str(bmc_attr['field_name']).strip() + field_pos= int(bmc_attr['field_pos'])-1 + + if 'delimiter' in bmc_attr.keys(): + delim = str(bmc_attr['delimiter']).strip() + else: + delim = None + + if not bmc_cmd in bmc_cache: + self.populate_bmc_cache_db(bmc_attr) + else: + now = time.time() + if (int(now - bmc_cache[bmc_cmd]['time']) > bmc_db_update_time): + self.populate_bmc_cache_db(bmc_attr) + + try: + data=bmc_cache[bmc_cmd][field_name] + value = data.split(delim)[field_pos].strip() + except Exception as e: + pass + + if 'mult' in bmc_attr.keys() and not value.isalpha(): + if value.isalpha(): + value = 0.0 + value = float(value) * float(bmc_attr['mult']) + + return str(value) + + def raw_ipmi_get_request(self, bmc_attr): + value = 'N/A' + cmd = bmc_attr['bmc_cmd'] + " 2>/dev/null" + if bmc_attr['type'] == 'raw': + try: + value = subprocess.check_output(cmd, shell=True).strip() + except Exception as e: + pass + + if value != 'N/A': + value = str(int(value, 16)) + return value + + if bmc_attr['type'] == 'mask': + mask = int(bmc_attr['mask'].encode('utf-8'), 16) + try: + value = subprocess.check_output(cmd, shell=True).strip() + except Exception as e: + pass + + # value should either be '1' or '0' + if value != 'N/A': + value = '1' if bool(int(value, 16) & mask) else '0' + + return value + + if bmc_attr['type'] == 'ascii': + try: + value = subprocess.check_output(cmd, shell=True) + except Exception as e: + pass + + if value != 'N/A': + tmp = ''.join(chr(int(i, 16)) for i in value.split()) + tmp = "".join(i for i in unicode(tmp) if unicodedata.category(i)[0]!="C") + value = str(tmp) + + return (value) + + return value + + def bmc_get_cmd(self, bmc_attr): + if int(bmc_attr['raw']) == 1: + value = self.raw_ipmi_get_request(bmc_attr) + else: + value = self.non_raw_ipmi_get_request(bmc_attr) + return (value) + + def non_raw_ipmi_set_request(self, bmc_attr, val): + value = 'N/A' + # TODO: Implement it + return value + + def raw_ipmi_set_request(self, bmc_attr, val): + value = 'N/A' + # TODO: Implement this + return value + + def bmc_set_cmd(self, bmc_attr, val): + if int(bmc_attr['raw']) == 1: + value = self.raw_ipmi_set_request(bmc_attr, val) + else: + value = self.non_raw_ipmi_set_request(bmc_attr, val) + return (value) + + # bmc-based attr: return attr obj + # non-bmc-based attr: return empty obj + def check_bmc_based_attr(self, device_name, attr_name): + if device_name in self.data.keys(): + if "bmc" in self.data[device_name].keys() and 'ipmitool' in self.data[device_name]['bmc'].keys(): + attr_list = self.data[device_name]['bmc']['ipmitool']['attr_list'] + for attr in attr_list: + if attr['attr_name'].strip() == attr_name.strip(): + return attr + # Required attr_name is not supported in BMC object + return {} + return None + + def get_attr_name_output(self, device_name, attr_name): + bmc_attr = self.check_bmc_based_attr(device_name, attr_name) + output={"mode":"", "status":""} + + if bmc_attr is not None: + if bmc_attr=={}: + return {} + output['mode']="bmc" + output['status']=self.bmc_get_cmd(bmc_attr) + else: + output['mode']="i2c" + node = self.get_path(device_name, attr_name) + if node is None: + return {} + try: + with open(node, 'r') as f: + output['status'] = f.read() + except IOError: + return {} + return output + + def set_attr_name_output(self, device_name, attr_name, val): + bmc_attr = self.check_bmc_based_attr(device_name, attr_name) + output={"mode":"", "status":""} + + if bmc_attr is not None: + if bmc_attr=={}: + return {} + output['mode']="bmc" + output['status']=False # No set operation allowed for BMC attributes as they are handled by BMC itself + else: + output['mode']="i2c" + node = self.get_path(device_name, attr_name) + if node is None: + return {} + try: + with open(node, 'w') as f: + f.write(str(val)) + except IOError: + return {} + + output['status'] = True + + return output + + ################################################################################################################### + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("--create", action='store_true', help="create the I2C topology") + parser.add_argument("--sysfs", action='store', nargs="+", help="show access-attributes sysfs for the I2C topology") + parser.add_argument("--dsysfs", action='store', nargs="+", help="show data-attributes sysfs for the I2C topology") + parser.add_argument("--delete", action='store_true', help="Remove all the created I2C clients from topology") + parser.add_argument("--validate", action='store', help="Validate the device specific attribute data elements") + parser.add_argument("--schema", action='store', nargs="+", help="Schema Validation") + parser.add_argument("--modules", action='store', nargs="+", help="Loaded modules validation") + + args = parser.parse_args() + + # Create the object + try: + pddf_obj = PddfParse() + except Exception as e: + print "%s" % str(e) + sys.exit() + + if args.create: + pddf_obj.create_pddf_devices() + + if args.sysfs: + if args.sysfs[0] == 'all': + pddf_obj.populate_pddf_sysfsobj() + if args.sysfs[0] == 'print': + pddf_obj.populate_pddf_sysfsobj() + pddf_obj.dump_sysfs_obj(pddf_obj.sysfs_obj, args.sysfs[1]) + if args.sysfs[0] == 'validate': + pddf_obj.populate_pddf_sysfsobj() + pddf_obj.validate_sysfs_creation(pddf_obj.sysfs_obj, args.sysfs[1]) + if args.sysfs[0] == 'verify': + pddf_obj.verify_sysfs_data(args.sysfs[1]) + + + if args.dsysfs: + if args.dsysfs[0] == 'validate': + pddf_obj.dev_parse(pddf_obj.data['SYSTEM'], { "cmd": "show_attr", "target":"all", "attr":"all" } ) + if 'SYSSTATUS' in pddf_obj.data: + pddf_obj.dev_parse(pddf_obj.data['SYSSTATUS'], { "cmd": "show_attr", "target":"all", "attr":"all" } ) + pddf_obj.validate_dsysfs_creation(pddf_obj.data_sysfs_obj, args.dsysfs[1]) + + elif args.dsysfs[0] == 'print': + pddf_obj.dev_parse(pddf_obj.data['SYSTEM'], { "cmd": "show_attr", "target":"all", "attr":"all" } ) + if 'SYSSTATUS' in pddf_obj.data: + pddf_obj.dev_parse(pddf_obj.data['SYSSTATUS'], { "cmd": "show_attr", "target":"all", "attr":"all" } ) + pddf_obj.dump_sysfs_obj(pddf_obj.data_sysfs_obj, args.dsysfs[1]) + + elif args.dsysfs[0] == 'all': + ret = pddf_obj.dev_parse(pddf_obj.data['SYSTEM'], { "cmd": "show_attr", "target":"all", "attr":"all" } ) + if 'SYSSTATUS' in pddf_obj.data: + ret += pddf_obj.dev_parse(pddf_obj.data['SYSSTATUS'], { "cmd": "show_attr", "target":"all", + "attr":"all" } ) + pddf_obj.dump_sysfs_obj(pddf_obj.data_sysfs_obj, 'all') + else: + pddf_obj.dev_parse(pddf_obj.data[args.dsysfs[0]], { "cmd": "show_attr", "target":args.dsysfs[0], + "attr":args.dsysfs[1] }) + + if args.delete: + pddf_obj.delete_pddf_devices() + + if args.validate: + if args.validate[0] == 'all': + pddf_obj.validate_pddf_devices(args.validate[1:]) + else: + pass + + if args.schema: + pddf_obj.schema_validation(args.schema[0]) + + if args.modules: + pddf_obj.modules_validation(args.modules[0]) + + + +if __name__ == "__main__" : + main() diff --git a/platform/pddf/i2c/utils/schema/CPLD.schema b/platform/pddf/i2c/utils/schema/CPLD.schema new file mode 100644 index 000000000000..c2f8c0de842f --- /dev/null +++ b/platform/pddf/i2c/utils/schema/CPLD.schema @@ -0,0 +1,67 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "CPLD": { + "type": "object", + "properties": { + "dev_info": { + "type": "object", + "properties": { + "device_type": { + "type": "string" + }, + "device_name": { + "type": "string" + }, + "device_parent": { + "type": "string" + } + }, + "required": [ + "device_type", + "device_name", + "device_parent" + ] + }, + "i2c": { + "type": "object", + "properties": { + "topo_info": { + "type": "object", + "properties": { + "parent_bus": { + "type": "string" + }, + "dev_addr": { + "type": "string" + }, + "dev_type": { + "type": "string" + } + }, + "required": [ + "parent_bus", + "dev_addr", + "dev_type" + ] + }, + "dev_attr": { + "type": "object" + } + }, + "required": [ + "topo_info" + ] + } + }, + "required": [ + "dev_info", + "i2c" + ] + } + }, + "required": [ + "CPLD" + ] +} diff --git a/platform/pddf/i2c/utils/schema/CPU.schema b/platform/pddf/i2c/utils/schema/CPU.schema new file mode 100644 index 000000000000..9bb07ae0f6bb --- /dev/null +++ b/platform/pddf/i2c/utils/schema/CPU.schema @@ -0,0 +1,80 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "CPU": { + "type": "object", + "properties": { + "dev_info": { + "type": "object", + "properties": { + "device_type": { + "type": "string" + }, + "device_name": { + "type": "string" + }, + "device_parent": { + "type": "null" + } + }, + "required": [ + "device_type", + "device_name", + "device_parent" + ] + }, + "i2c": { + "type": "object", + "properties": { + "CONTROLLERS": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "dev_name": { + "type": "string" + }, + "dev": { + "type": "string" + } + }, + "required": [ + "dev_name", + "dev" + ] + }, + { + "type": "object", + "properties": { + "dev_name": { + "type": "string" + }, + "dev": { + "type": "string" + } + }, + "required": [ + "dev_name", + "dev" + ] + } + ] + } + }, + "required": [ + "CONTROLLERS" + ] + } + }, + "required": [ + "dev_info", + "i2c" + ] + } + }, + "required": [ + "CPU" + ] +} diff --git a/platform/pddf/i2c/utils/schema/EEPROM.schema b/platform/pddf/i2c/utils/schema/EEPROM.schema new file mode 100644 index 000000000000..a8e8885e3ad1 --- /dev/null +++ b/platform/pddf/i2c/utils/schema/EEPROM.schema @@ -0,0 +1,93 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "EEPROM": { + "type": "object", + "properties": { + "dev_info": { + "type": "object", + "properties": { + "device_type": { + "type": "string" + }, + "device_name": { + "type": "string" + }, + "device_parent": { + "type": "string" + } + }, + "required": [ + "device_type", + "device_name", + "device_parent" + ] + }, + "i2c": { + "type": "object", + "properties": { + "topo_info": { + "type": "object", + "properties": { + "parent_bus": { + "type": "string" + }, + "dev_addr": { + "type": "string" + }, + "dev_type": { + "type": "string" + } + }, + "required": [ + "parent_bus", + "dev_addr", + "dev_type" + ] + }, + "dev_attr": { + "type": "object", + "properties": { + "access_mode": { + "type": "string" + } + }, + "required": [ + "access_mode" + ] + }, + "attr_list": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + } + }, + "required": [ + "attr_name" + ] + } + ] + } + }, + "required": [ + "topo_info", + "dev_attr", + "attr_list" + ] + } + }, + "required": [ + "dev_info", + "i2c" + ] + } + }, + "required": [ + "EEPROM" + ] +} diff --git a/platform/pddf/i2c/utils/schema/FAN.schema b/platform/pddf/i2c/utils/schema/FAN.schema new file mode 100644 index 000000000000..069007533130 --- /dev/null +++ b/platform/pddf/i2c/utils/schema/FAN.schema @@ -0,0 +1,113 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "FAN": { + "type": "object", + "properties": { + "dev_info": { + "type": "object", + "properties": { + "device_type": { + "type": "string" + }, + "device_name": { + "type": "string" + }, + "device_parent": { + "type": "string" + } + }, + "required": [ + "device_type", + "device_name", + "device_parent" + ] + }, + "i2c": { + "type": "object", + "properties": { + "topo_info": { + "type": "object", + "properties": { + "parent_bus": { + "type": "string" + }, + "dev_addr": { + "type": "string" + }, + "dev_type": { + "type": "string" + } + }, + "required": [ + "parent_bus", + "dev_addr", + "dev_type" + ] + }, + "dev_attr": { + "type": "object", + "properties": { + "num_fantrays": { + "type": "string" + } + }, + "required": [ + "num_fantrays" + ] + }, + "attr_list": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "attr_devtype": { + "type": "string" + }, + "attr_offset": { + "type": "string" + }, + "attr_mask": { + "type": "string" + }, + "attr_cmpval": { + "type": "string" + }, + "attr_len": { + "type": "string" + } + }, + "required": [ + "attr_name", + "attr_devtype", + "attr_offset", + "attr_mask", + "attr_cmpval", + "attr_len" + ] + } + ] + } + }, + "required": [ + "topo_info", + "dev_attr", + "attr_list" + ] + } + }, + "required": [ + "dev_info", + "i2c" + ] + } + }, + "required": [ + "FAN" + ] +} diff --git a/platform/pddf/i2c/utils/schema/FAN_BMC.schema b/platform/pddf/i2c/utils/schema/FAN_BMC.schema new file mode 100644 index 000000000000..41d774dfa6bd --- /dev/null +++ b/platform/pddf/i2c/utils/schema/FAN_BMC.schema @@ -0,0 +1,69 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "FAN": { + "type": "object", + "properties": { + "dev_info": { + "type": "object", + "properties": { + "device_type": { + "type": "string" + } + }, + "required": [ + "device_type" + ] + }, + "bmc": { + "type": "object", + "properties": { + "ipmitool": { + "type": "object", + "properties": { + "attr_list": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "bmc_cmd": { + "type": "string" + }, + "raw": { + "type": "string" + } + }, + "required": [ + "attr_name", + "bmc_cmd", + "raw" + ] + } + ] + } + }, + "required": [ + "attr_list" + ] + } + }, + "required": [ + "ipmitool" + ] + } + }, + "required": [ + "dev_info", + "bmc" + ] + } + }, + "required": [ + "FAN" + ] +} diff --git a/platform/pddf/i2c/utils/schema/LED.schema b/platform/pddf/i2c/utils/schema/LED.schema new file mode 100644 index 000000000000..04583ee660aa --- /dev/null +++ b/platform/pddf/i2c/utils/schema/LED.schema @@ -0,0 +1,120 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "LED": { + "type": "object", + "properties": { + "dev_info": { + "type": "object", + "properties": { + "device_type": { + "type": "string" + }, + "device_name": { + "type": "string" + } + }, + "required": [ + "device_type", + "device_name" + ] + }, + "dev_attr": { + "type": "object", + "properties": { + "index": { + "type": "string" + } + }, + "required": [ + "index" + ] + }, + "i2c": { + "type": "object", + "properties": { + "attr_list": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "bits": { + "type": "string" + }, + "color": { + "type": "string" + }, + "value": { + "type": "string" + }, + "swpld_addr": { + "type": "string" + }, + "swpld_addr_offset": { + "type": "string" + } + }, + "required": [ + "attr_name", + "bits", + "color", + "value", + "swpld_addr", + "swpld_addr_offset" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "bits": { + "type": "string" + }, + "color": { + "type": "string" + }, + "value": { + "type": "string" + }, + "swpld_addr": { + "type": "string" + }, + "swpld_addr_offset": { + "type": "string" + } + }, + "required": [ + "attr_name", + "bits", + "color", + "value", + "swpld_addr", + "swpld_addr_offset" + ] + } + ] + } + }, + "required": [ + "attr_list" + ] + } + }, + "required": [ + "dev_info", + "dev_attr", + "i2c" + ] + } + }, + "required": [ + "LED" + ] +} diff --git a/platform/pddf/i2c/utils/schema/MUX.schema b/platform/pddf/i2c/utils/schema/MUX.schema new file mode 100644 index 000000000000..6ef46e8dd2a9 --- /dev/null +++ b/platform/pddf/i2c/utils/schema/MUX.schema @@ -0,0 +1,97 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "MUX": { + "type": "object", + "properties": { + "dev_info": { + "type": "object", + "properties": { + "device_type": { + "type": "string" + }, + "device_name": { + "type": "string" + }, + "device_parent": { + "type": "string" + } + }, + "required": [ + "device_type", + "device_name", + "device_parent" + ] + }, + "i2c": { + "type": "object", + "properties": { + "topo_info": { + "type": "object", + "properties": { + "parent_bus": { + "type": "string" + }, + "dev_addr": { + "type": "string" + }, + "dev_type": { + "type": "string" + } + }, + "required": [ + "parent_bus", + "dev_addr", + "dev_type" + ] + }, + "dev_attr": { + "type": "object", + "properties": { + "virt_bus": { + "type": "string" + } + }, + "required": [ + "virt_bus" + ] + }, + "channel": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "chn": { + "type": "string" + }, + "dev": { + "type": "string" + } + }, + "required": [ + "chn", + "dev" + ] + } + ] + } + }, + "required": [ + "topo_info", + "dev_attr", + "channel" + ] + } + }, + "required": [ + "dev_info", + "i2c" + ] + } + }, + "required": [ + "MUX" + ] +} diff --git a/platform/pddf/i2c/utils/schema/PSU-PMBUS.schema b/platform/pddf/i2c/utils/schema/PSU-PMBUS.schema new file mode 100644 index 000000000000..6516d2321371 --- /dev/null +++ b/platform/pddf/i2c/utils/schema/PSU-PMBUS.schema @@ -0,0 +1,109 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "PSU-PMBUS": { + "type": "object", + "properties": { + "dev_info": { + "type": "object", + "properties": { + "device_type": { + "type": "string" + }, + "device_name": { + "type": "string" + }, + "device_parent": { + "type": "string" + }, + "virt_parent": { + "type": "string" + } + }, + "required": [ + "device_type", + "device_name", + "device_parent", + "virt_parent" + ] + }, + "i2c": { + "type": "object", + "properties": { + "topo_info": { + "type": "object", + "properties": { + "parent_bus": { + "type": "string" + }, + "dev_addr": { + "type": "string" + }, + "dev_type": { + "type": "string" + } + }, + "required": [ + "parent_bus", + "dev_addr", + "dev_type" + ] + }, + "attr_list": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "attr_devaddr": { + "type": "string" + }, + "attr_devtype": { + "type": "string" + }, + "attr_offset": { + "type": "string" + }, + "attr_mask": { + "type": "string" + }, + "attr_cmpval": { + "type": "string" + }, + "attr_len": { + "type": "string" + } + }, + "required": [ + "attr_name", + "attr_devaddr", + "attr_devtype", + "attr_offset", + "attr_mask", + "attr_cmpval", + "attr_len" + ] + } + ] + } + }, + "required": [ + "topo_info", + "attr_list" + ] + } + }, + "required": [ + "dev_info", + "i2c" + ] + } + }, + "required": [ + "PSU-PMBUS" + ] +} diff --git a/platform/pddf/i2c/utils/schema/PSU.schema b/platform/pddf/i2c/utils/schema/PSU.schema new file mode 100644 index 000000000000..5ed53df4572f --- /dev/null +++ b/platform/pddf/i2c/utils/schema/PSU.schema @@ -0,0 +1,81 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "PSU": { + "type": "object", + "properties": { + "dev_info": { + "type": "object", + "properties": { + "device_type": { + "type": "string" + }, + "device_name": { + "type": "string" + }, + "device_parent": { + "type": "string" + } + }, + "required": [ + "device_type", + "device_name", + "device_parent" + ] + }, + "dev_attr": { + "type": "object", + "properties": { + "dev_idx": { + "type": "string" + }, + "num_psu_fans": { + "type": "string" + } + }, + "required": [ + "dev_idx", + "num_psu_fans" + ] + }, + "i2c": { + "type": "object", + "properties": { + "interface": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "itf": { + "type": "string" + }, + "dev": { + "type": "string" + } + }, + "required": [ + "itf", + "dev" + ] + } + ] + } + }, + "required": [ + "interface" + ] + } + }, + "required": [ + "dev_info", + "dev_attr", + "i2c" + ] + } + }, + "required": [ + "PSU" + ] +} diff --git a/platform/pddf/i2c/utils/schema/PSU_BMC.schema b/platform/pddf/i2c/utils/schema/PSU_BMC.schema new file mode 100644 index 000000000000..299e79dd7854 --- /dev/null +++ b/platform/pddf/i2c/utils/schema/PSU_BMC.schema @@ -0,0 +1,336 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "PSU": { + "type": "object", + "properties": { + "dev_info": { + "type": "object", + "properties": { + "device_type": { + "type": "string" + } + }, + "required": [ + "device_type" + ] + }, + "dev_attr": { + "type": "object", + "properties": { + "dev_idx": { + "type": "string" + }, + "num_psu_fans": { + "type": "string" + } + }, + "required": [ + "dev_idx", + "num_psu_fans" + ] + }, + "bmc": { + "type": "object", + "properties": { + "ipmitool": { + "type": "object", + "properties": { + "attr_list": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "bmc_cmd": { + "type": "string" + }, + "raw": { + "type": "string" + }, + "field_name": { + "type": "string" + }, + "field_pos": { + "type": "string" + } + }, + "required": [ + "attr_name", + "bmc_cmd", + "raw", + "field_name", + "field_pos" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "bmc_cmd": { + "type": "string" + }, + "raw": { + "type": "string" + }, + "type": { + "type": "string" + }, + "mask": { + "type": "string" + } + }, + "required": [ + "attr_name", + "bmc_cmd", + "raw", + "type", + "mask" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "bmc_cmd": { + "type": "string" + }, + "raw": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "attr_name", + "bmc_cmd", + "raw", + "type" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "bmc_cmd": { + "type": "string" + }, + "raw": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "attr_name", + "bmc_cmd", + "raw", + "type" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "bmc_cmd": { + "type": "string" + }, + "raw": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "attr_name", + "bmc_cmd", + "raw", + "type" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "bmc_cmd": { + "type": "string" + }, + "raw": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "attr_name", + "bmc_cmd", + "raw", + "type" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "bmc_cmd": { + "type": "string" + }, + "raw": { + "type": "string" + }, + "field_name": { + "type": "string" + }, + "field_pos": { + "type": "string" + }, + "mult": { + "type": "string" + } + }, + "required": [ + "attr_name", + "bmc_cmd", + "raw", + "field_name", + "field_pos", + "mult" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "bmc_cmd": { + "type": "string" + }, + "raw": { + "type": "string" + }, + "field_name": { + "type": "string" + }, + "field_pos": { + "type": "string" + }, + "mult": { + "type": "string" + } + }, + "required": [ + "attr_name", + "bmc_cmd", + "raw", + "field_name", + "field_pos", + "mult" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "bmc_cmd": { + "type": "string" + }, + "raw": { + "type": "string" + }, + "field_name": { + "type": "string" + }, + "field_pos": { + "type": "string" + }, + "mult": { + "type": "string" + } + }, + "required": [ + "attr_name", + "bmc_cmd", + "raw", + "field_name", + "field_pos", + "mult" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "bmc_cmd": { + "type": "string" + }, + "raw": { + "type": "string" + }, + "field_name": { + "type": "string" + }, + "field_pos": { + "type": "string" + }, + "mult": { + "type": "string" + } + }, + "required": [ + "attr_name", + "bmc_cmd", + "raw", + "field_name", + "field_pos", + "mult" + ] + } + ] + } + }, + "required": [ + "attr_list" + ] + } + }, + "required": [ + "ipmitool" + ] + } + }, + "required": [ + "dev_info", + "dev_attr", + "bmc" + ] + } + }, + "required": [ + "PSU" + ] +} diff --git a/platform/pddf/i2c/utils/schema/QSFP.schema b/platform/pddf/i2c/utils/schema/QSFP.schema new file mode 100644 index 000000000000..be8e75a9cd1f --- /dev/null +++ b/platform/pddf/i2c/utils/schema/QSFP.schema @@ -0,0 +1,92 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "QSFP": { + "type": "object", + "properties": { + "dev_info": { + "type": "object", + "properties": { + "device_type": { + "type": "string" + }, + "device_name": { + "type": "string" + }, + "device_parent": { + "type": "string" + } + }, + "required": [ + "device_type", + "device_name", + "device_parent" + ] + }, + "dev_attr": { + "type": "object", + "properties": { + "dev_idx": { + "type": "string" + } + }, + "required": [ + "dev_idx" + ] + }, + "i2c": { + "type": "object", + "properties": { + "interface": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "itf": { + "type": "string" + }, + "dev": { + "type": "string" + } + }, + "required": [ + "itf", + "dev" + ] + }, + { + "type": "object", + "properties": { + "itf": { + "type": "string" + }, + "dev": { + "type": "string" + } + }, + "required": [ + "itf", + "dev" + ] + } + ] + } + }, + "required": [ + "interface" + ] + } + }, + "required": [ + "dev_info", + "dev_attr", + "i2c" + ] + } + }, + "required": [ + "QSFP" + ] +} diff --git a/platform/pddf/i2c/utils/schema/SMBUS.schema b/platform/pddf/i2c/utils/schema/SMBUS.schema new file mode 100644 index 000000000000..91429a1d7ee8 --- /dev/null +++ b/platform/pddf/i2c/utils/schema/SMBUS.schema @@ -0,0 +1,128 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "SMBUS": { + "type": "object", + "properties": { + "dev_info": { + "type": "object", + "properties": { + "device_type": { + "type": "string" + }, + "device_name": { + "type": "string" + }, + "device_parent": { + "type": "string" + } + }, + "required": [ + "device_type", + "device_name", + "device_parent" + ] + }, + "i2c": { + "type": "object", + "properties": { + "topo_info": { + "type": "object", + "properties": { + "dev_addr": { + "type": "string" + } + }, + "required": [ + "dev_addr" + ] + }, + "DEVICES": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "dev": { + "type": "string" + } + }, + "required": [ + "dev" + ] + }, + { + "type": "object", + "properties": { + "dev": { + "type": "string" + } + }, + "required": [ + "dev" + ] + }, + { + "type": "object", + "properties": { + "dev": { + "type": "string" + } + }, + "required": [ + "dev" + ] + }, + { + "type": "object", + "properties": { + "dev": { + "type": "string" + } + }, + "required": [ + "dev" + ] + }, + { + "type": "object", + "properties": { + "dev": { + "type": "string" + } + }, + "required": [ + "dev" + ] + }, + { + "type": "object", + "properties": { + "dev": { + "type": "string" + } + }, + "required": [ + "dev" + ] + } + ] + } + }, + "required": [ + "topo_info", + "DEVICES" + ] + } + }, + "required": [ + "dev_info", + "i2c" + ] + } + }, + "required": [ + "SMBUS" + ] +} diff --git a/platform/pddf/i2c/utils/schema/SYSSTAT.schema b/platform/pddf/i2c/utils/schema/SYSSTAT.schema new file mode 100644 index 000000000000..d31e10c27222 --- /dev/null +++ b/platform/pddf/i2c/utils/schema/SYSSTAT.schema @@ -0,0 +1,285 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "SYSSTAT": { + "type": "object", + "properties": { + "dev_info": { + "type": "object", + "properties": { + "device_type": { + "type": "string" + }, + "device_name": { + "type": "string" + } + }, + "required": [ + "device_type", + "device_name" + ] + }, + "dev_attr": { + "type": "object" + }, + "attr_list": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "attr_devaddr": { + "type": "string" + }, + "attr_offset": { + "type": "string" + }, + "attr_mask": { + "type": "string" + }, + "attr_len": { + "type": "string" + } + }, + "required": [ + "attr_name", + "attr_devaddr", + "attr_offset", + "attr_mask", + "attr_len" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "attr_devaddr": { + "type": "string" + }, + "attr_offset": { + "type": "string" + }, + "attr_mask": { + "type": "string" + }, + "attr_len": { + "type": "string" + } + }, + "required": [ + "attr_name", + "attr_devaddr", + "attr_offset", + "attr_mask", + "attr_len" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "attr_devaddr": { + "type": "string" + }, + "attr_offset": { + "type": "string" + }, + "attr_mask": { + "type": "string" + }, + "attr_len": { + "type": "string" + } + }, + "required": [ + "attr_name", + "attr_devaddr", + "attr_offset", + "attr_mask", + "attr_len" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "attr_devaddr": { + "type": "string" + }, + "attr_offset": { + "type": "string" + }, + "attr_mask": { + "type": "string" + }, + "attr_len": { + "type": "string" + } + }, + "required": [ + "attr_name", + "attr_devaddr", + "attr_offset", + "attr_mask", + "attr_len" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "attr_devaddr": { + "type": "string" + }, + "attr_offset": { + "type": "string" + }, + "attr_mask": { + "type": "string" + }, + "attr_len": { + "type": "string" + } + }, + "required": [ + "attr_name", + "attr_devaddr", + "attr_offset", + "attr_mask", + "attr_len" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "attr_devaddr": { + "type": "string" + }, + "attr_offset": { + "type": "string" + }, + "attr_mask": { + "type": "string" + }, + "attr_len": { + "type": "string" + } + }, + "required": [ + "attr_name", + "attr_devaddr", + "attr_offset", + "attr_mask", + "attr_len" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "attr_devaddr": { + "type": "string" + }, + "attr_offset": { + "type": "string" + }, + "attr_mask": { + "type": "string" + }, + "attr_len": { + "type": "string" + } + }, + "required": [ + "attr_name", + "attr_devaddr", + "attr_offset", + "attr_mask", + "attr_len" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "attr_devaddr": { + "type": "string" + }, + "attr_offset": { + "type": "string" + }, + "attr_mask": { + "type": "string" + }, + "attr_len": { + "type": "string" + } + }, + "required": [ + "attr_name", + "attr_devaddr", + "attr_offset", + "attr_mask", + "attr_len" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "attr_devaddr": { + "type": "string" + }, + "attr_offset": { + "type": "string" + }, + "attr_mask": { + "type": "string" + }, + "attr_len": { + "type": "string" + } + }, + "required": [ + "attr_name", + "attr_devaddr", + "attr_offset", + "attr_mask", + "attr_len" + ] + } + ] + } + }, + "required": [ + "dev_info", + "dev_attr", + "attr_list" + ] + } + }, + "required": [ + "SYSSTAT" + ] +} diff --git a/platform/pddf/i2c/utils/schema/TEMP_SENSOR.schema b/platform/pddf/i2c/utils/schema/TEMP_SENSOR.schema new file mode 100644 index 000000000000..0bc2ce8b8303 --- /dev/null +++ b/platform/pddf/i2c/utils/schema/TEMP_SENSOR.schema @@ -0,0 +1,102 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "TEMP_SENSOR": { + "type": "object", + "properties": { + "dev_info": { + "type": "object", + "properties": { + "device_type": { + "type": "string" + }, + "device_name": { + "type": "string" + }, + "device_parent": { + "type": "string" + } + }, + "required": [ + "device_type", + "device_parent" + ] + }, + "i2c": { + "type": "object", + "properties": { + "topo_info": { + "type": "object", + "properties": { + "parent_bus": { + "type": "string" + }, + "dev_addr": { + "type": "string" + }, + "dev_type": { + "type": "string" + } + }, + "required": [ + "parent_bus", + "dev_addr", + "dev_type" + ] + }, + "attr_list": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + } + }, + "required": [ + "attr_name" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + } + }, + "required": [ + "attr_name" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + } + }, + "required": [ + "attr_name" + ] + } + ] + } + }, + "required": [ + "topo_info", + "attr_list" + ] + } + }, + "required": [ + "dev_info", + "i2c" + ] + } + }, + "required": [ + "TEMP_SENSOR" + ] +} diff --git a/platform/pddf/i2c/utils/schema/TEMP_SENSOR_BMC.schema b/platform/pddf/i2c/utils/schema/TEMP_SENSOR_BMC.schema new file mode 100644 index 000000000000..c8f7c447b718 --- /dev/null +++ b/platform/pddf/i2c/utils/schema/TEMP_SENSOR_BMC.schema @@ -0,0 +1,143 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "TEMP_SENSOR": { + "type": "object", + "properties": { + "dev_info": { + "type": "object", + "properties": { + "device_type": { + "type": "string" + } + }, + "required": [ + "device_type" + ] + }, + "dev_attr": { + "type": "object", + "properties": { + "display_name": { + "type": "string" + } + }, + "required": [ + "display_name" + ] + }, + "bmc": { + "type": "object", + "properties": { + "ipmitool": { + "type": "object", + "properties": { + "attr_list": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "bmc_cmd": { + "type": "string" + }, + "raw": { + "type": "string" + }, + "field_name": { + "type": "string" + }, + "field_pos": { + "type": "string" + } + }, + "required": [ + "attr_name", + "bmc_cmd", + "raw", + "field_name", + "field_pos" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "bmc_cmd": { + "type": "string" + }, + "raw": { + "type": "string" + }, + "field_name": { + "type": "string" + }, + "field_pos": { + "type": "string" + } + }, + "required": [ + "attr_name", + "bmc_cmd", + "raw", + "field_name", + "field_pos" + ] + }, + { + "type": "object", + "properties": { + "attr_name": { + "type": "string" + }, + "bmc_cmd": { + "type": "string" + }, + "raw": { + "type": "string" + }, + "field_name": { + "type": "string" + }, + "field_pos": { + "type": "string" + } + }, + "required": [ + "attr_name", + "bmc_cmd", + "raw", + "field_name", + "field_pos" + ] + } + ] + } + }, + "required": [ + "attr_list" + ] + } + }, + "required": [ + "ipmitool" + ] + } + }, + "required": [ + "dev_info", + "dev_attr", + "bmc" + ] + } + }, + "required": [ + "TEMP_SENSOR" + ] +} diff --git a/platform/pddf/platform-api-pddf-base.dep b/platform/pddf/platform-api-pddf-base.dep new file mode 100644 index 000000000000..aaaedb068384 --- /dev/null +++ b/platform/pddf/platform-api-pddf-base.dep @@ -0,0 +1,13 @@ + +MPATH := $($(PDDF_PLATFORM_API_BASE_PY2)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/pddf/platform-api-pddf-base.mk platform/pddf/platform-api-pddf-base.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(MPATH)) + +$(PDDF_PLATFORM_API_BASE_PY2)_CACHE_MODE := GIT_CONTENT_SHA +$(PDDF_PLATFORM_API_BASE_PY2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(PDDF_PLATFORM_API_BASE_PY2)_DEP_FILES := $(DEP_FILES) + +$(PDDF_PLATFORM_API_BASE_PY3)_CACHE_MODE := GIT_CONTENT_SHA +$(PDDF_PLATFORM_API_BASE_PY3)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(PDDF_PLATFORM_API_BASE_PY3)_DEP_FILES := $(DEP_FILES) diff --git a/platform/pddf/platform-api-pddf-base.mk b/platform/pddf/platform-api-pddf-base.mk new file mode 100644 index 000000000000..ce818707ba7e --- /dev/null +++ b/platform/pddf/platform-api-pddf-base.mk @@ -0,0 +1,28 @@ +#################################################### +# PDDF Generic 2.0 Platform API base classes +#################################################### +PDDF_PLATFORM_API_BASE_VERSION = 1.0 + +export PDDF_PLATFORM_API_BASE_VERSION + +PDDF_PLATFORM_API_BASE_PY2 = sonic_platform_pddf_common-$(PDDF_PLATFORM_API_BASE_VERSION)-py2-none-any.whl +$(PDDF_PLATFORM_API_BASE_PY2)_SRC_PATH = $(PLATFORM_PDDF_PATH)/platform-api-pddf-base +$(PDDF_PLATFORM_API_BASE_PY2)_PYTHON_VERSION = 2 +$(PDDF_PLATFORM_API_BASE_PY2)_DEPENDS = $(SONIC_CONFIG_ENGINE) +SONIC_PYTHON_WHEELS += $(PDDF_PLATFORM_API_BASE_PY2) + +export pddf_platform_api_base_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(PDDF_PLATFORM_API_BASE_PY2))" +export PDDF_PLATFORM_API_BASE_PY2 + +PDDF_PLATFORM_API_BASE_PY3 = sonic_platform_pddf_common-$(PDDF_PLATFORM_API_BASE_VERSION)-py3-none-any.whl +$(PDDF_PLATFORM_API_BASE_PY3)_SRC_PATH = $(PLATFORM_PDDF_PATH)/platform-api-pddf-base +$(PDDF_PLATFORM_API_BASE_PY3)_PYTHON_VERSION = 3 +$(PDDF_PLATFORM_API_BASE_PY3)_DEPENDS = $(SONIC_CONFIG_ENGINE) +# Synthetic dependency to avoid building the Python 2 and 3 packages +# simultaneously and any potential conflicts which may arise +$(PDDF_PLATFORM_API_BASE_PY3)_DEPENDS += $(PDDF_PLATFORM_API_BASE_PY2) +$(PDDF_PLATFORM_API_BASE_PY3)_TEST = n +SONIC_PYTHON_WHEELS += $(PDDF_PLATFORM_API_BASE_PY3) + +export pddf_platform_api_base_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(PDDF_PLATFORM_API_BASE_PY3))" +export PDDF_PLATFORM_API_BASE_PY3 diff --git a/platform/pddf/platform-api-pddf-base/setup.py b/platform/pddf/platform-api-pddf-base/setup.py new file mode 100755 index 000000000000..0d8b4a6b2df2 --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/setup.py @@ -0,0 +1,34 @@ + +from setuptools import setup + +setup( + name='sonic-platform-pddf-common', + version='1.0', + description='SONIC platform APIs base (2.0) implementation on PDDF supported platforms', + license='Apache 2.0', + author='SONiC Team', + author_email='linuxnetdev@microsoft.com', + url='https://github.com/Azure/sonic-buildimage', + maintainer='Fuzail Khan', + maintainer_email='fuzail.khan@broadcom.com', + packages=[ + 'sonic_platform_pddf_base', + ], + install_requires=[ + 'jsonschema==2.6.0' + ], + classifiers=[ + 'Development Status :: 3 - Alpha', + 'Environment :: Plugins', + 'Intended Audience :: Developers', + 'Intended Audience :: Information Technology', + 'Intended Audience :: System Administrators', + 'License :: OSI Approved :: Apache Software License', + 'Natural Language :: English', + 'Operating System :: POSIX :: Linux', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3.7', + 'Topic :: Utilities', + ], + keywords='sonic SONiC platform PLATFORM', +) diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/__init__.py b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_chassis.py b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_chassis.py new file mode 100755 index 000000000000..0e77a90dbab1 --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_chassis.py @@ -0,0 +1,512 @@ +#!/usr/bin/env python + +############################################################################# +# PDDF +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + import sys + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform.sfp import Sfp + from sonic_platform.psu import Psu + from sonic_platform.fan import Fan + from sonic_platform.thermal import Thermal + from sonic_platform.eeprom import Eeprom +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PddfChassis(ChassisBase): + """ + PDDF Generic Chassis class + """ + pddf_obj = {} + plugin_data = {} + + def __init__(self, pddf_data=None, pddf_plugin_data=None): + + ChassisBase.__init__(self) + + self.pddf_obj = pddf_data if pddf_data else None + self.plugin_data = pddf_plugin_data if pddf_plugin_data else None + if not self.pddf_obj or not self.plugin_data: + try: + from . import pddfparse + import json + self.pddf_obj = pddfparse.PddfParse() + with open('/usr/share/sonic/platform/pddf/pd-plugin.json') as pd: + self.plugin_data = json.load(pd) + except Exception as e: + raise Exception("Error: Unable to load PDDF JSON data - %s" % str(e)) + + self.platform_inventory = self.pddf_obj.get_platform() + + # Initialize EEPROM + self.sys_eeprom = Eeprom(self.pddf_obj, self.plugin_data) + + # FANs + for i in range(self.platform_inventory['num_fantrays']): + for j in range(self.platform_inventory['num_fans_pertray']): + fan = Fan(i, j, self.pddf_obj, self.plugin_data) + self._fan_list.append(fan) + + # PSUs + for i in range(self.platform_inventory['num_psus']): + psu = Psu(i, self.pddf_obj, self.plugin_data) + self._psu_list.append(psu) + + # OPTICs + for index in range(self.platform_inventory['num_ports']): + sfp = Sfp(index, self.pddf_obj, self.plugin_data) + self._sfp_list.append(sfp) + + # THERMALs + for i in range(self.platform_inventory['num_temps']): + thermal = Thermal(i, self.pddf_obj, self.plugin_data) + self._thermal_list.append(thermal) + + # SYSTEM LED Test Cases + """ + #comment out test cases + sys_led_list= { "LOC":0, + "DIAG":0, + "FAN":0, + "SYS":0, + "PSU1":0, + "PSU2":1 + } + + for led in sys_led_list: + color=self.get_system_led(led, sys_led_list[led]) + print color + + self.set_system_led("LOC_LED","STATUS_LED_COLOR_GREEN") + color=self.get_system_led("LOC_LED") + print "Set Green: " + color + self.set_system_led("LOC_LED", "STATUS_LED_COLOR_OFF") + color=self.get_system_led("LOC_LED") + print "Set off: " + color + """ + + def get_name(self): + """ + Retrieves the name of the chassis + Returns: + string: The name of the chassis + """ + return self.sys_eeprom.modelstr() + + def get_presence(self): + """ + Retrieves the presence of the chassis + Returns: + bool: True if chassis is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the chassis + Returns: + string: Model/part number of chassis + """ + return self.sys_eeprom.part_number_str() + + def get_serial(self): + """ + Retrieves the serial number of the chassis (Service tag) + Returns: + string: Serial number of chassis + """ + return self.sys_eeprom.serial_str() + + def get_status(self): + """ + Retrieves the operational status of the chassis + Returns: + bool: A boolean value, True if chassis is operating properly + False if not + """ + return True + + def get_base_mac(self): + """ + Retrieves the base MAC address for the chassis + + Returns: + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' + """ + return self.sys_eeprom.base_mac_addr() + + def get_serial_number(self): + """ + Retrieves the hardware serial number for the chassis + + Returns: + A string containing the hardware serial number for this + chassis. + """ + return self.sys_eeprom.serial_number_str() + + def get_system_eeprom_info(self): + """ + Retrieves the full content of system EEPROM information for the chassis + Returns: + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their corresponding + values. + """ + return self.sys_eeprom.system_eeprom_info() + + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + + Returns: + A tuple (string, string) where the first element is a string + containing the cause of the previous reboot. This string must be + one of the predefined strings in this class. If the first string + is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used + to pass a description of the reboot cause. + """ + raise NotImplementedError + + def get_component_name_list(self): + """ + Retrieves a list of the names of components available on the chassis (e.g., BIOS, CPLD, FPGA, etc.) + + Returns: + A list containing the names of components available on the chassis + """ + return self._component_name_list + + def get_firmware_version(self, component_name): + """ + Retrieves platform-specific hardware/firmware versions for chassis + componenets such as BIOS, CPLD, FPGA, etc. + Args: + component_name: A string, the component name. + + Returns: + A string containing platform-specific component versions + """ + raise NotImplementedError + + def install_component_firmware(self, component_name, image_path): + """ + Install firmware to component + Args: + component_name: A string, the component name. + image_path: A string, path to firmware image. + + Returns: + A boolean, True if install was successful, False if not + """ + raise NotImplementedError + + ############################################## + # Module methods + ############################################## + + def get_num_modules(self): + """ + Retrieves the number of modules available on this chassis + + Returns: + An integer, the number of modules available on this chassis + """ + return len(self._module_list) + + def get_all_modules(self): + """ + Retrieves all modules available on this chassis + + Returns: + A list of objects derived from ModuleBase representing all + modules available on this chassis + """ + return self._module_list + + def get_module(self, index): + """ + Retrieves module represented by (0-based) index + + Args: + index: An integer, the index (0-based) of the module to + retrieve + + Returns: + An object dervied from ModuleBase representing the specified + module + """ + module = None + + try: + module = self._module_list[index] + except IndexError: + sys.stderr.write("Module index {} out of range (0-{})\n".format( + index, len(self._module_list)-1)) + + return module + ############################################## + # Fan methods + ############################################## + + def get_num_fans(self): + """ + Retrieves the number of fans available on this chassis + + Returns: + An integer, the number of fan modules available on this chassis + """ + return len(self._fan_list) + + def get_all_fans(self): + """ + Retrieves all fan modules available on this chassis + + Returns: + A list of objects derived from FanBase representing all fan + modules available on this chassis + """ + return self._fan_list + + def get_fan(self, index): + """ + Retrieves fan module represented by (0-based) index + + Args: + index: An integer, the index (0-based) of the fan module to + retrieve + + Returns: + An object dervied from FanBase representing the specified fan + module + """ + fan = None + + try: + fan = self._fan_list[index] + except IndexError: + sys.stderr.write("Fan index {} out of range (0-{})\n".format( + index, len(self._fan_list)-1)) + + return fan + + ############################################## + # PSU methods + ############################################## + + def get_num_psus(self): + """ + Retrieves the number of power supply units available on this chassis + + Returns: + An integer, the number of power supply units available on this + chassis + """ + return len(self._psu_list) + + def get_all_psus(self): + """ + Retrieves all power supply units available on this chassis + + Returns: + A list of objects derived from PsuBase representing all power + supply units available on this chassis + """ + return self._psu_list + + def get_psu(self, index): + """ + Retrieves power supply unit represented by (0-based) index + + Args: + index: An integer, the index (0-based) of the power supply unit to + retrieve + + Returns: + An object dervied from PsuBase representing the specified power + supply unit + """ + psu = None + + try: + psu = self._psu_list[index] + except IndexError: + sys.stderr.write("PSU index {} out of range (0-{})\n".format( + index, len(self._psu_list)-1)) + + return psu + + ############################################## + # THERMAL methods + ############################################## + + def get_num_thermals(self): + """ + Retrieves the number of thermals available on this chassis + + Returns: + An integer, the number of thermals available on this chassis + """ + return len(self._thermal_list) + + def get_all_thermals(self): + """ + Retrieves all thermals available on this chassis + + Returns: + A list of objects derived from ThermalBase representing all thermals + available on this chassis + """ + return self._thermal_list + + def get_thermal(self, index): + """ + Retrieves thermal unit represented by (0-based) index + + Args: + index: An integer, the index (0-based) of the thermal to + retrieve + + Returns: + An object dervied from ThermalBase representing the specified thermal + """ + thermal = None + + try: + thermal = self._thermal_list[index] + except IndexError: + sys.stderr.write("THERMAL index {} out of range (0-{})\n".format( + index, len(self._thermal_list)-1)) + + return thermal + + ############################################## + # SFP methods + ############################################## + + def get_num_sfps(self): + """ + Retrieves the number of sfps available on this chassis + + Returns: + An integer, the number of sfps available on this chassis + """ + return len(self._sfp_list) + + def get_all_sfps(self): + """ + Retrieves all sfps available on this chassis + + Returns: + A list of objects derived from SfpBase representing all sfps + available on this chassis + """ + return self._sfp_list + + def get_sfp(self, index): + """ + Retrieves sfp represented by (0-based) index + + Args: + index: An integer, the index (0-based) of the sfp to retrieve. + The index should be the sequence of a physical port in a chassis, + starting from 0. + 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] + except IndexError: + sys.stderr.write("SFP index {} out of range (0-{})\n".format( + index, len(self._sfp_list)-1)) + + return sfp + + ############################################## + # System LED methods + ############################################## + def set_system_led(self, led_device_name, color): + result, msg = self.pddf_obj.is_supported_sysled_state(led_device_name, color) + if result == False: + print(msg) + return (False) + + index = self.pddf_obj.data[led_device_name]['dev_attr']['index'] + device_name = self.pddf_obj.data[led_device_name]['dev_info']['device_name'] + self.pddf_obj.create_attr('device_name', device_name, self.pddf_obj.get_led_path()) + self.pddf_obj.create_attr('index', index, self.pddf_obj.get_led_path()) + self.pddf_obj.create_attr('color', color, self.pddf_obj.get_led_cur_state_path()) + self.pddf_obj.create_attr('dev_ops', 'set_status', self.pddf_obj.get_led_path()) + return (True) + + def get_system_led(self, led_device_name): + if led_device_name not in self.pddf_obj.data.keys(): + status = "[FAILED] " + led_device_name + " is not configured" + return (status) + + index = self.pddf_obj.data[led_device_name]['dev_attr']['index'] + device_name = self.pddf_obj.data[led_device_name]['dev_info']['device_name'] + self.pddf_obj.create_attr('device_name', device_name, self.pddf_obj.get_led_path()) + self.pddf_obj.create_attr('index', index, self.pddf_obj.get_led_path()) + self.pddf_obj.create_attr('dev_ops', 'get_status', self.pddf_obj.get_led_path()) + color = self.pddf_obj.get_led_color() + return (color) + + ############################################## + # Other methods + ############################################## + + def get_watchdog(self): + """ + Retreives hardware watchdog device on this chassis + + Returns: + An object derived from WatchdogBase representing the hardware + watchdog device + """ + return self._watchdog + + def get_eeprom(self): + """ + Retreives eeprom device on this chassis + + Returns: + An object derived from WatchdogBase representing the hardware + eeprom device + """ + return self.sys_eeprom + + def get_change_event(self, timeout=0): + """ + Returns a nested dictionary containing all devices which have + experienced a change at chassis level + + Args: + timeout: Timeout in milliseconds (optional). If timeout == 0, + this method will block until a change is detected. + Returns: + (bool, dict): + - True if call successful, False if not; + - A nested dictionary where key is a device type, + value is a dictionary with key:value pairs in the format of + {'device_id':'device_event'}, + where device_id is the device ID for this device and + device_event, + status='1' represents device inserted, + status='0' represents device removed. + Ex. {'fan':{'0':'0', '2':'1'}, 'sfp':{'11':'0'}} + indicates that fan 0 has been removed, fan 2 + has been inserted and sfp 11 has been removed. + """ + raise NotImplementedError diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_eeprom.py b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_eeprom.py new file mode 100644 index 000000000000..592485d617e4 --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_eeprom.py @@ -0,0 +1,116 @@ +############################################################################# +# PDDF +# +# PDDF syseeprom base class inherited from the base class +############################################################################# + +try: + from sonic_eeprom import eeprom_tlvinfo + import binascii +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PddfEeprom(eeprom_tlvinfo.TlvInfoDecoder): + _TLV_INFO_MAX_LEN = 256 + pddf_obj = {} + plugin_data = {} + + def __init__(self, pddf_data=None, pddf_plugin_data=None): + if not pddf_data or not pddf_plugin_data: + raise ValueError('PDDF JSON data error') + + self.pddf_obj = pddf_data + self.plugin_data = pddf_plugin_data + + # system EEPROM always has device name EEPROM1 + self.eeprom_path = self.pddf_obj.get_path("EEPROM1", "eeprom") + if self.eeprom_path is None: + return + + super(PddfEeprom, self).__init__(self.eeprom_path, 0, '', True) + self.eeprom_tlv_dict = dict() + try: + self.eeprom_data = self.read_eeprom() + except: + self.eeprom_data = "N/A" + raise RuntimeError("PddfEeprom is not Programmed") + else: + eeprom = self.eeprom_data + + if not self.is_valid_tlvinfo_header(eeprom): + return + + total_length = (ord(eeprom[9]) << 8) | ord(eeprom[10]) + tlv_index = self._TLV_INFO_HDR_LEN + tlv_end = self._TLV_INFO_HDR_LEN + total_length + + while (tlv_index + 2) < len(eeprom) and tlv_index < tlv_end: + if not self.is_valid_tlv(eeprom[tlv_index:]): + break + + tlv = eeprom[tlv_index:tlv_index + 2 + + ord(eeprom[tlv_index + 1])] + code = "0x%02X" % (ord(tlv[0])) + + if ord(tlv[0]) == self._TLV_CODE_VENDOR_EXT: + value = str((ord(tlv[2]) << 24) | (ord(tlv[3]) << 16) | + (ord(tlv[4]) << 8) | ord(tlv[5])) + value += str(tlv[6:6 + ord(tlv[1])]) + else: + name, value = self.decoder(None, tlv) + + self.eeprom_tlv_dict[code] = value + if ord(eeprom[tlv_index]) == self._TLV_CODE_CRC_32: + break + + tlv_index += ord(eeprom[tlv_index+1]) + 2 + + def serial_number_str(self): + (is_valid, results) = self.get_tlv_field(self.eeprom_data, self._TLV_CODE_SERIAL_NUMBER) + if not is_valid: + return "N/A" + return results[2] + + def base_mac_addr(self): + (is_valid, t) = self.get_tlv_field(self.eeprom_data, self._TLV_CODE_MAC_BASE) + if not is_valid or t[1] != 6: + return super(TlvInfoDecoder, self).switchaddrstr(e) + + return ":".join([binascii.b2a_hex(T) for T in t[2]]) + + def modelstr(self): + (is_valid, results) = self.get_tlv_field(self.eeprom_data, self._TLV_CODE_PRODUCT_NAME) + if not is_valid: + return "N/A" + + return results[2] + + def part_number_str(self): + (is_valid, results) = self.get_tlv_field(self.eeprom_data, self._TLV_CODE_PART_NUMBER) + if not is_valid: + return "N/A" + + return results[2] + + def serial_str(self): + (is_valid, results) = self.get_tlv_field(self.eeprom_data, self._TLV_CODE_SERVICE_TAG) + if not is_valid: + return "N/A" + + return results[2] + + def revision_str(self): + (is_valid, results) = self.get_tlv_field(self.eeprom_data, self._TLV_CODE_DEVICE_VERSION) + if not is_valid: + return "N/A" + + return results[2] + + def system_eeprom_info(self): + """ + Returns a dictionary, where keys are the type code defined in + ONIE EEPROM format and values are their corresponding values + found in the system EEPROM. + """ + return self.eeprom_tlv_dict diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_fan.py b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_fan.py new file mode 100755 index 000000000000..5930345070b4 --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_fan.py @@ -0,0 +1,329 @@ +#!/usr/bin/env python + +# All the supported FAN SysFS aattributes are +#- fan_present +#- fan_direction +#- fan_input +#- fan_pwm +#- fan_fault +# where idx is in the range [1-32] +# + +try: + from sonic_platform_base.fan_base import FanBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PddfFan(FanBase): + """PDDF generic Fan class""" + + pddf_obj = {} + plugin_data = {} + + def __init__(self, tray_idx, fan_idx=0, pddf_data=None, pddf_plugin_data=None, is_psu_fan=False, psu_index=0): + # idx is 0-based + if not pddf_data or not pddf_plugin_data: + raise ValueError('PDDF JSON data error') + + self.pddf_obj = pddf_data + self.plugin_data = pddf_plugin_data + self.platform = self.pddf_obj.get_platform() + + if tray_idx < 0 or tray_idx >= self.platform['num_fantrays']: + print("Invalid fantray index %d\n" % tray_idx) + return + + if fan_idx < 0 or fan_idx >= self.platform['num_fans_pertray']: + print("Invalid fan index (within a tray) %d\n" % fan_idx) + return + + self.fantray_index = tray_idx+1 + self.fan_index = fan_idx+1 + self.is_psu_fan = is_psu_fan + if self.is_psu_fan: + self.fans_psu_index = psu_index + + def get_name(self): + """ + Retrieves the fan name + Returns: String containing fan-name + """ + if self.is_psu_fan: + return "PSU{}_FAN{}".format(self.fans_psu_index, self.fan_index) + else: + if 'name' in self.plugin_data['FAN']: + return self.plugin_data['FAN']['name'][str(self.fantray_index)] + else: + return "Fantray{}_{}".format(self.fantray_index, self.fan_index) + + def get_presence(self): + if self.is_psu_fan: + return True + else: + idx = (self.fantray_index-1)*self.platform['num_fans_pertray'] + self.fan_index + attr_name = "fan" + str(idx) + "_present" + output = self.pddf_obj.get_attr_name_output("FAN-CTRL", attr_name) + if not output: + return False + + mode = output['mode'] + presence = output['status'].rstrip() + + vmap = self.plugin_data['FAN']['present'][mode]['valmap'] + + if presence in vmap: + status = vmap[presence] + else: + status = False + + return status + + def get_status(self): + speed = self.get_speed() + status = True if (speed != 0) else False + return status + + def get_direction(self): + """ + Retrieves the direction of fan + + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + """ + if self.is_psu_fan: + device = "PSU{}".format(self.fans_psu_index) + output = self.pddf_obj.get_attr_name_output(device, "psu_fan_dir") + if not output: + return False + + mode = output['mode'] + val = output['status'] + + val = val.rstrip() + vmap = self.plugin_data['PSU']['psu_fan_dir'][mode]['valmap'] + + if val in vmap: + direction = vmap[val] + else: + direction = val + + else: + idx = (self.fantray_index-1)*self.platform['num_fans_pertray'] + self.fan_index + attr = "fan" + str(idx) + "_direction" + output = self.pddf_obj.get_attr_name_output("FAN-CTRL", attr) + if not output: + return False + + mode = output['mode'] + val = output['status'] + + val = val.rstrip() + vmap = self.plugin_data['FAN']['direction'][mode]['valmap'] + if val in vmap: + direction = vmap[val] + else: + direction = val + + return direction + + def get_speed(self): + """ + Retrieves the speed of fan as a percentage of full speed + + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + """ + if self.is_psu_fan: + attr = "psu_fan{}_speed_rpm".format(self.fan_index) + device = "PSU{}".format(self.fans_psu_index) + output = self.pddf_obj.get_attr_name_output(device, attr) + if not output: + return 0 + + output['status'] = output['status'].rstrip() + if output['status'].isalpha(): + return 0 + else: + speed = int(output['status']) + + max_speed = int(self.plugin_data['PSU']['PSU_FAN_MAX_SPEED']) + speed_percentage = (speed*100)/max_speed + return speed_percentage + else: + # TODO This calculation should change based on MAX FAN SPEED + idx = (self.fantray_index-1)*self.platform['num_fans_pertray'] + self.fan_index + attr = "fan" + str(idx) + "_pwm" + output = self.pddf_obj.get_attr_name_output("FAN-CTRL", attr) + + if not output: + return 0 + + output['status'] = output['status'].rstrip() + if output['status'].isalpha(): + return 0 + else: + fpwm = int(output['status']) + + pwm_to_dc = eval(self.plugin_data['FAN']['pwm_to_duty_cycle']) + speed_percentage = int(round(pwm_to_dc(fpwm))) + + return speed_percentage + + def get_speed_rpm(self): + """ + Retrieves the speed of fan in RPM + + Returns: + An integer, Speed of fan in RPM + """ + if self.is_psu_fan: + attr = "psu_fan{}_speed_rpm".format(self.fan_index) + device = "PSU{}".format(self.fans_psu_index) + output = self.pddf_obj.get_attr_name_output(device, attr) + if not output: + return 0 + + output['status'] = output['status'].rstrip() + if output['status'].isalpha(): + return 0 + else: + speed = int(float(output['status'])) + + rpm_speed = speed + return rpm_speed + else: + idx = (self.fantray_index-1)*self.platform['num_fans_pertray'] + self.fan_index + attr = "fan" + str(idx) + "_input" + output = self.pddf_obj.get_attr_name_output("FAN-CTRL", attr) + + if output is None: + return 0 + + output['status'] = output['status'].rstrip() + if output['status'].isalpha(): + return 0 + else: + rpm_speed = int(float(output['status'])) + + return rpm_speed + + def get_target_speed(self): + """ + Retrieves the target (expected) speed of the fan + + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + """ + target_speed = 0 + if self.is_psu_fan: + # Target speed not usually supported for PSU fans + target_speed = 0 + else: + idx = (self.fantray_index-1)*self.platform['num_fans_pertray'] + self.fan_index + attr = "fan" + str(idx) + "_pwm" + output = self.pddf_obj.get_attr_name_output("FAN-CTRL", attr) + + if not output: + return 0 + + output['status'] = output['status'].rstrip() + if output['status'].isalpha(): + return 0 + else: + fpwm = int(output['status']) + + pwm_to_dc = eval(self.plugin_data['FAN']['pwm_to_duty_cycle']) + speed_percentage = int(round(pwm_to_dc(fpwm))) + target_speed = speed_percentage + + return target_speed + + def get_speed_tolerance(self): + """ + Retrieves the speed tolerance of the fan + + Returns: + An integer, the percentage of variance from target speed which is + considered tolerable + """ + # Fix the speed vairance to 10 percent. If it changes based on platforms, overwrite + # this value in derived pddf fan class + return 10 + + def set_speed(self, speed): + """ + Sets the fan speed + + Args: + speed: An integer, the percentage of full fan speed to set fan to, + in the range 0 (off) to 100 (full speed) + + Returns: + A boolean, True if speed is set successfully, False if not + """ + if self.is_psu_fan: + print("Setting PSU fan speed is not allowed") + return False + else: + if speed < 0 or speed > 100: + print("Error: Invalid speed %d. Please provide a valid speed percentage" % speed) + return False + + if 'duty_cycle_to_pwm' not in self.plugin_data['FAN']: + print("Setting fan speed is not allowed !") + return False + else: + duty_cycle_to_pwm = eval(self.plugin_data['FAN']['duty_cycle_to_pwm']) + pwm = int(round(duty_cycle_to_pwm(speed))) + + status = False + idx = (self.fantray_index-1)*self.platform['num_fans_pertray'] + self.fan_index + attr = "fan" + str(idx) + "_pwm" + output = self.pddf_obj.set_attr_name_output("FAN-CTRL", attr, pwm) + if not output: + return False + + status = output['status'] + + return status + + def set_status_led(self, color): + index = str(self.fantray_index-1) + led_device_name = "FANTRAY{}".format(self.fantray_index) + "_LED" + + result, msg = self.pddf_obj.is_supported_sysled_state(led_device_name, color) + if result == False: + print(msg) + return (False) + + device_name = self.pddf_obj.data[led_device_name]['dev_info']['device_name'] + self.pddf_obj.create_attr('device_name', device_name, self.pddf_obj.get_led_path()) + self.pddf_obj.create_attr('index', index, self.pddf_obj.get_led_path()) + self.pddf_obj.create_attr('color', color, self.pddf_obj.get_led_cur_state_path()) + self.pddf_obj.create_attr('dev_ops', 'set_status', self.pddf_obj.get_led_path()) + return (True) + + def get_status_led(self): + index = str(self.fantray_index-1) + fan_led_device = "FANTRAY{}".format(self.fantray_index) + "_LED" + + if fan_led_device not in self.pddf_obj.data.keys(): + # Implement a generic status_led color scheme + if self.get_status(): + return self.STATUS_LED_COLOR_GREEN + else: + return self.STATUS_LED_COLOR_OFF + + device_name = self.pddf_obj.data[fan_led_device]['dev_info']['device_name'] + self.pddf_obj.create_attr('device_name', device_name, self.pddf_obj.get_led_path()) + self.pddf_obj.create_attr('index', index, self.pddf_obj.get_led_path()) + self.pddf_obj.create_attr('dev_ops', 'get_status', self.pddf_obj.get_led_path()) + color = self.pddf_obj.get_led_color() + return (color) + + def dump_sysfs(self): + return self.pddf_obj.cli_dump_dsysfs('fan') diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_platform.py b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_platform.py new file mode 100755 index 000000000000..00eefc9a815e --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_platform.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python + +############################################################################# +# PDDF +# Module contains an implementation of SONiC Platform API and +# provides the platform information +# +############################################################################# + + +try: + import json + from . import pddfparse + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PddfPlatform(PlatformBase): + """ + PDDF Generic Platform class + """ + pddf_data = {} + pddf_plugin_data = {} + + def __init__(self): + # Initialize the JSON data + self.pddf_data = pddfparse.PddfParse() + with open('/usr/share/sonic/platform/pddf/pd-plugin.json') as pd: + self.pddf_plugin_data = json.load(pd) + + if not self.pddf_data or not self.pddf_plugin_data: + print("Error: PDDF JSON data is not loaded properly ... Exiting") + raise ValueError + + PlatformBase.__init__(self) + self._chassis = Chassis(self.pddf_data, self.pddf_plugin_data) diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_psu.py b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_psu.py new file mode 100755 index 000000000000..58b69ce0aa73 --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_psu.py @@ -0,0 +1,297 @@ +#!/usr/bin/env python +# +# All the supported PSU SysFS aattributes are +#- psu_present +#- psu_model_name +#- psu_power_good +#- psu_mfr_id +#- psu_serial_num +#- psu_fan_dir +#- psu_v_out +#- psu_i_out +#- psu_p_out +#- psu_fan1_speed_rpm +# + + +try: + from sonic_platform_base.psu_base import PsuBase + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PddfPsu(PsuBase): + """PDDF generic PSU class""" + + pddf_obj = {} + plugin_data = {} + + def __init__(self, index, pddf_data=None, pddf_plugin_data=None): + PsuBase.__init__(self) + if not pddf_data or not pddf_plugin_data: + raise ValueError('PDDF JSON data error') + + self.pddf_obj = pddf_data + self.plugin_data = pddf_plugin_data + self.platform = self.pddf_obj.get_platform() + self.psu_index = index + 1 + + self._fan_list = [] # _fan_list under PsuBase class is a global variable, hence we need to use _fan_list per class instatiation + self.num_psu_fans = int(self.pddf_obj.get_num_psu_fans('PSU{}'.format(index+1))) + for psu_fan_idx in range(self.num_psu_fans): + psu_fan = Fan(0, psu_fan_idx, pddf_data, pddf_plugin_data, True, self.psu_index) + self._fan_list.append(psu_fan) + + def get_num_fans(self): + """ + Retrieves the number of fan modules available on this PSU + + Returns: + An integer, the number of fan modules available on this PSU + """ + return len(self._fan_list) + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + if 'name' in self.plugin_data['PSU']: + return self.plugin_data['PSU']['name'][str(self.psu_index)] + else: + return "PSU{}".format(self.psu_index) + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + status = 0 + device = "PSU{}".format(self.psu_index) + output = self.pddf_obj.get_attr_name_output(device, "psu_present") + if not output: + return False + + mode = output['mode'] + status = output['status'] + + vmap = self.plugin_data['PSU']['psu_present'][mode]['valmap'] + + if status.rstrip('\n') in vmap: + return vmap[status.rstrip('\n')] + else: + return False + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + + Returns: + string: Model/part number of device + """ + device = "PSU{}".format(self.psu_index) + output = self.pddf_obj.get_attr_name_output(device, "psu_model_name") + if not output: + return None + + model = output['status'] + + # strip_non_ascii + stripped = (c for c in model if 0 < ord(c) < 127) + model = ''.join(stripped) + + return model.rstrip('\n') + + def get_serial(self): + """ + Retrieves the serial number of the device + + Returns: + string: Serial number of device + """ + device = "PSU{}".format(self.psu_index) + output = self.pddf_obj.get_attr_name_output(device, "psu_serial_num") + if not output: + return None + + serial = output['status'] + + return serial.rstrip('\n') + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + device = "PSU{}".format(self.psu_index) + + output = self.pddf_obj.get_attr_name_output(device, "psu_power_good") + if not output: + return False + + mode = output['mode'] + status = output['status'] + + vmap = self.plugin_data['PSU']['psu_power_good'][mode]['valmap'] + + if status.rstrip('\n') in vmap: + return vmap[status.rstrip('\n')] + else: + return False + + def get_mfr_id(self): + """ + Retrieves the manufacturer id of the device + + Returns: + string: Manufacturer Id of device + """ + device = "PSU{}".format(self.psu_index) + output = self.pddf_obj.get_attr_name_output(device, "psu_mfr_id") + if not output: + return None + + mfr = output['status'] + + return mfr.rstrip('\n') + + def get_voltage(self): + """ + Retrieves current PSU voltage output + + Returns: + A float number, the output voltage in volts, + e.g. 12.1 + """ + device = "PSU{}".format(self.psu_index) + output = self.pddf_obj.get_attr_name_output(device, "psu_v_out") + if not output: + return 0.0 + + v_out = output['status'] + + return float(v_out)/1000 + + def get_current(self): + """ + Retrieves present electric current supplied by PSU + + Returns: + A float number, electric current in amperes, + e.g. 15.4 + """ + device = "PSU{}".format(self.psu_index) + output = self.pddf_obj.get_attr_name_output(device, "psu_i_out") + if not output: + return 0.0 + + i_out = output['status'] + + # current in mA + return float(i_out)/1000 + + def get_power(self): + """ + Retrieves current energy supplied by PSU + + Returns: + A float number, the power in watts, + e.g. 302.6 + """ + device = "PSU{}".format(self.psu_index) + output = self.pddf_obj.get_attr_name_output(device, "psu_p_out") + if not output: + return 0.0 + + p_out = output['status'] + + # power is returned in micro watts + return float(p_out)/1000000 + + def get_powergood_status(self): + """ + Retrieves the powergood status of PSU + + Returns: + A boolean, True if PSU has stablized its output voltages and + passed all its internal self-tests, False if not. + """ + return self.get_status() + + def set_status_led(self, color): + index = str(self.psu_index-1) + led_device_name = "PSU{}".format(self.psu_index) + "_LED" + + result, msg = self.pddf_obj.is_supported_sysled_state(led_device_name, color) + if result == False: + print(msg) + return (False) + + device_name = self.pddf_obj.data[led_device_name]['dev_info']['device_name'] + self.pddf_obj.create_attr('device_name', device_name, self.pddf_obj.get_led_path()) + self.pddf_obj.create_attr('index', index, self.pddf_obj.get_led_path()) + self.pddf_obj.create_attr('color', color, self.pddf_obj.get_led_cur_state_path()) + self.pddf_obj.create_attr('dev_ops', 'set_status', self.pddf_obj.get_led_path()) + return (True) + + def get_status_led(self): + index = str(self.psu_index-1) + psu_led_device = "PSU{}_LED".format(self.psu_index) + if psu_led_device not in self.pddf_obj.data.keys(): + # Implement a generic status_led color scheme + if self.get_powergood_status(): + return self.STATUS_LED_COLOR_GREEN + else: + return self.STATUS_LED_COLOR_OFF + + device_name = self.pddf_obj.data[psu_led_device]['dev_info']['device_name'] + self.pddf_obj.create_attr('device_name', device_name, self.pddf_obj.get_led_path()) + self.pddf_obj.create_attr('index', index, self.pddf_obj.get_led_path()) + self.pddf_obj.create_attr('dev_ops', 'get_status', self.pddf_obj.get_led_path()) + color = self.pddf_obj.get_led_color() + return (color) + + def get_input_voltage(self): + """ + Retrieves current PSU input voltage + + Returns: + A float number, the input voltage in volts, + e.g. 12.1 + """ + device = "PSU{}".format(self.psu_index) + output = self.pddf_obj.get_attr_name_output(device, "psu_v_in") + if not output: + return 0.0 + + v_in = output['status'] + + return float(v_in)/1000 + + def get_input_current(self): + """ + Retrieves present electric current supplied to the PSU + + Returns: + A float number, electric current in amperes, + e.g. 15.4 + """ + device = "PSU{}".format(self.psu_index) + output = self.pddf_obj.get_attr_name_output(device, "psu_i_in") + if not output: + return 0.0 + + i_in = output['status'] + + # current in mA + return float(i_in)/1000 + + def dump_sysfs(self): + return self.pddf_obj.cli_dump_dsysfs('psu') diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_sfp.py b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_sfp.py new file mode 100755 index 000000000000..dc37bba6e888 --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_sfp.py @@ -0,0 +1,1395 @@ +#!/usr/bin/env python + +try: + import time + from ctypes import create_string_buffer + from sonic_platform_base.sfp_base import SfpBase + from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom + from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom + from sonic_platform_base.sonic_sfp.sff8472 import sffbase + from sonic_platform_base.sonic_sfp.inf8628 import inf8628InterfaceId +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +# definitions of the offset and width for values in XCVR info eeprom +XCVR_INTFACE_BULK_OFFSET = 0 +XCVR_INTFACE_BULK_WIDTH_QSFP = 20 +XCVR_INTFACE_BULK_WIDTH_SFP = 21 +XCVR_TYPE_OFFSET = 0 +XCVR_TYPE_WIDTH = 1 +XCVR_EXT_TYPE_OFFSET = 1 +XCVR_EXT_TYPE_WIDTH = 1 +XCVR_CONNECTOR_OFFSET = 2 +XCVR_CONNECTOR_WIDTH = 1 +XCVR_COMPLIANCE_CODE_OFFSET = 3 +XCVR_COMPLIANCE_CODE_WIDTH = 8 +XCVR_ENCODING_OFFSET = 11 +XCVR_ENCODING_WIDTH = 1 +XCVR_NBR_OFFSET = 12 +XCVR_NBR_WIDTH = 1 +XCVR_EXT_RATE_SEL_OFFSET = 13 +XCVR_EXT_RATE_SEL_WIDTH = 1 +XCVR_CABLE_LENGTH_OFFSET = 14 +XCVR_CABLE_LENGTH_WIDTH_QSFP = 5 +XCVR_CABLE_LENGTH_WIDTH_SFP = 6 +XCVR_VENDOR_NAME_OFFSET = 20 +XCVR_VENDOR_NAME_WIDTH = 16 +XCVR_VENDOR_OUI_OFFSET = 37 +XCVR_VENDOR_OUI_WIDTH = 3 +XCVR_VENDOR_PN_OFFSET = 40 +XCVR_VENDOR_PN_WIDTH = 16 +XCVR_HW_REV_OFFSET = 56 +XCVR_HW_REV_WIDTH_OSFP = 2 +XCVR_HW_REV_WIDTH_QSFP = 2 +XCVR_HW_REV_WIDTH_SFP = 4 +XCVR_VENDOR_SN_OFFSET = 68 +XCVR_VENDOR_SN_WIDTH = 16 +XCVR_VENDOR_DATE_OFFSET = 84 +XCVR_VENDOR_DATE_WIDTH = 8 +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 1 + +# definitions of the offset for values in OSFP info eeprom +OSFP_TYPE_OFFSET = 0 +OSFP_VENDOR_NAME_OFFSET = 129 +OSFP_VENDOR_PN_OFFSET = 148 +OSFP_HW_REV_OFFSET = 164 +OSFP_VENDOR_SN_OFFSET = 166 + +# definitions of the offset and width for values in DOM info eeprom +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_CONTROL_OFFSET = 86 +QSFP_CONTROL_WIDTH = 8 +QSFP_CHANNL_RX_LOS_STATUS_OFFSET = 3 +QSFP_CHANNL_RX_LOS_STATUS_WIDTH = 1 +QSFP_CHANNL_TX_FAULT_STATUS_OFFSET = 4 +QSFP_CHANNL_TX_FAULT_STATUS_WIDTH = 1 +QSFP_POWEROVERRIDE_OFFSET = 93 +QSFP_POWEROVERRIDE_WIDTH = 1 +QSFP_MODULE_THRESHOLD_OFFSET = 128 +QSFP_MODULE_THRESHOLD_WIDTH = 24 +QSFP_CHANNEL_THRESHOLD_OFFSET = 176 +QSFP_CHANNEL_THRESHOLD_WIDTH = 16 + + +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VOLT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_CHANNL_MON_OFFSET = 100 +SFP_CHANNL_MON_WIDTH = 6 +SFP_MODULE_THRESHOLD_OFFSET = 0 +SFP_MODULE_THRESHOLD_WIDTH = 40 +SFP_CHANNL_THRESHOLD_OFFSET = 112 +SFP_CHANNL_THRESHOLD_WIDTH = 2 +SFP_STATUS_CONTROL_OFFSET = 110 +SFP_STATUS_CONTROL_WIDTH = 1 +SFP_TX_DISABLE_HARD_BIT = 7 +SFP_TX_DISABLE_SOFT_BIT = 6 + + +qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', + 'Length OM2(m)', 'Length OM1(m)', + 'Length Cable Assembly(m)') + +sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)', + 'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)', + 'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)') + +sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode', + 'ESCONComplianceCodes', 'SONETComplianceCodes', + 'EthernetComplianceCodes', 'FibreChannelLinkLength', + 'FibreChannelTechnology', 'SFP+CableTechnology', + 'FibreChannelTransmissionMedia', 'FibreChannelSpeed') + +qsfp_compliance_code_tup = ('10/40G Ethernet Compliance Code', 'SONET Compliance codes', + 'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes', + 'Fibre Channel link length/Transmitter Technology', + 'Fibre Channel transmission media', 'Fibre Channel Speed') + +PAGE_OFFSET = 0 +KEY_OFFSET = 1 +KEY_WIDTH = 2 +FUNC_NAME = 3 + +INFO_OFFSET = 128 +DOM_OFFSET = 0 +DOM_OFFSET1 = 384 + + +class PddfSfp(SfpBase): + """ + PDDF generic Sfp class + """ + + pddf_obj = {} + plugin_data = {} + _port_to_eeprom_mapping = {} + _port_start = 0 + _port_end = 0 + _port_to_type_mapping = {} + _qsfp_ports = [] + _sfp_ports = [] + + # Read out any bytes from any offset + def __read_eeprom_specific_bytes(self, offset, num_bytes): + sysfsfile_eeprom = None + eeprom_raw = [] + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + try: + sysfsfile_eeprom = open(self.eeprom_path, mode="rb", buffering=0) + sysfsfile_eeprom.seek(offset) + raw = sysfsfile_eeprom.read(num_bytes) + for n in range(0, num_bytes): + eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + except Exception as e: + print("Error: Unable to open eeprom_path: %s" % (str(e))) + finally: + if sysfsfile_eeprom: + sysfsfile_eeprom.close() + + return eeprom_raw + + def __init__(self, index, pddf_data=None, pddf_plugin_data=None): + if not pddf_data or not pddf_plugin_data: + raise ValueError('PDDF JSON data error') + + self.pddf_obj = pddf_data + self.plugin_data = pddf_plugin_data + + self.platform = self.pddf_obj.get_platform() + + # index is 0-based + self._port_start = 0 + self._port_end = int(self.platform['num_ports']) + if index < self._port_start or index >= self._port_end: + print("Invalid port index %d" % index) + return + + self.port_index = index+1 + self.device = 'PORT{}'.format(self.port_index) + self.sfp_type = self.pddf_obj.get_device_type(self.device) + self.is_qsfp_port = True if (self.sfp_type == 'QSFP' or self.sfp_type == 'QSFP28') else False + self.is_osfp_port = True if (self.sfp_type == 'OSFP' or self.sfp_type == 'QSFP-DD') else False + self.eeprom_path = self.pddf_obj.get_path(self.device, 'eeprom') + + self.info_dict_keys = ['type', 'hardware_rev', 'serial', 'manufacturer', 'model', 'connector', 'encoding', + 'ext_identifier', 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', + 'specification_compliance', 'vendor_date', 'vendor_oui', 'application_advertisement'] + + self.dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', + 'temperature', 'voltage', 'rx1power', 'rx2power', 'rx3power', 'rx4power', 'tx1bias', 'tx2bias', + 'tx3bias', 'tx4bias', 'tx1power', 'tx2power', 'tx3power', 'tx4power'] + + self.threshold_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning', + 'vcchighalarm', 'vcchighwarning', 'vcclowalarm', 'vcclowwarning', 'rxpowerhighalarm', + 'rxpowerhighwarning', 'rxpowerlowalarm', 'rxpowerlowwarning', 'txpowerhighalarm', 'txpowerhighwarning', + 'txpowerlowalarm', 'txpowerlowwarning', 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', + 'txbiaslowwarning'] + + SfpBase.__init__(self) + + def get_transceiver_info(self): + """ + Retrieves transceiver info of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + type |1*255VCHAR |type of SFP + hardware_rev |1*255VCHAR |hardware version of SFP + serial |1*255VCHAR |serial number of the SFP + manufacturer |1*255VCHAR |SFP vendor name + model |1*255VCHAR |SFP model name + connector |1*255VCHAR |connector information + encoding |1*255VCHAR |encoding information + ext_identifier |1*255VCHAR |extend identifier + ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance + cable_length |INT |cable length in m + nominal_bit_rate |INT |nominal bit rate by 100Mbs + specification_compliance |1*255VCHAR |specification compliance + vendor_date |1*255VCHAR |vendor date + vendor_oui |1*255VCHAR |vendor OUI + application_advertisement |1*255VCHAR |supported applications advertisement + ======================================================================== + """ + # check present status + if not self.get_presence(): + return None + + if self.is_osfp_port: + sfpi_obj = inf8628InterfaceId() + offset = 0 + type_offset = OSFP_TYPE_OFFSET + vendor_rev_width = XCVR_HW_REV_WIDTH_OSFP + hw_rev_offset = OSFP_HW_REV_OFFSET + vendor_name_offset = OSFP_VENDOR_NAME_OFFSET + vendor_pn_offset = OSFP_VENDOR_PN_OFFSET + vendor_sn_offset = OSFP_VENDOR_SN_OFFSET + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_QSFP + sfp_type = 'OSFP' + + elif self.is_qsfp_port: + sfpi_obj = sff8436InterfaceId() + offset = 128 + type_offset = XCVR_TYPE_OFFSET + vendor_rev_width = XCVR_HW_REV_WIDTH_QSFP + hw_rev_offset = XCVR_HW_REV_OFFSET + vendor_name_offset = XCVR_VENDOR_NAME_OFFSET + vendor_pn_offset = XCVR_VENDOR_PN_OFFSET + vendor_sn_offset = XCVR_VENDOR_SN_OFFSET + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_QSFP + sfp_type = 'QSFP' + else: + sfpi_obj = sff8472InterfaceId() + offset = 0 + type_offset = XCVR_TYPE_OFFSET + vendor_rev_width = XCVR_HW_REV_WIDTH_SFP + hw_rev_offset = XCVR_HW_REV_OFFSET + vendor_name_offset = XCVR_VENDOR_NAME_OFFSET + vendor_pn_offset = XCVR_VENDOR_PN_OFFSET + vendor_sn_offset = XCVR_VENDOR_SN_OFFSET + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_SFP + sfp_type = 'SFP' + + if sfpi_obj is None: + return None + + if self.is_osfp_port: + sfp_type_raw = self.__read_eeprom_specific_bytes((offset + type_offset), XCVR_TYPE_WIDTH) + if sfp_type_raw is not None: + sfp_type_data = sfpi_obj.parse_sfp_type(sfp_type_raw, 0) + sfp_type_abbrv_name = sfpi_obj.parse_sfp_type_abbrv_name(sfp_typ_raw, 0) + else: + sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_INTFACE_BULK_OFFSET), interface_info_bulk_width) + if sfp_interface_bulk_raw is not None: + sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(sfp_interface_bulk_raw, 0) + + sfp_vendor_oui_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH) + if sfp_vendor_oui_raw is not None: + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(sfp_vendor_oui_raw, 0) + + sfp_vendor_date_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH) + if sfp_vendor_date_raw is not None: + sfp_vendor_date_data = sfpi_obj.parse_vendor_date(sfp_vendor_date_raw, 0) + + sfp_vendor_name_raw = self.__read_eeprom_specific_bytes( + (offset + vendor_name_offset), XCVR_VENDOR_NAME_WIDTH) + sfp_vendor_name_data = sfpi_obj.parse_vendor_name( + sfp_vendor_name_raw, 0) + + sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes( + (offset + vendor_pn_offset), XCVR_VENDOR_PN_WIDTH) + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn( + sfp_vendor_pn_raw, 0) + + sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes( + (offset + hw_rev_offset), vendor_rev_width) + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev( + sfp_vendor_rev_raw, 0) + + sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes( + (offset + vendor_sn_offset), XCVR_VENDOR_SN_WIDTH) + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn( + sfp_vendor_sn_raw, 0) + + xcvr_info_dict = dict.fromkeys(self.info_dict_keys, 'N/A') + compliance_code_dict = dict() + + if sfp_interface_bulk_data: + xcvr_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] + xcvr_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + xcvr_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] + xcvr_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] + xcvr_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] + xcvr_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] + else: + xcvr_info_dict['type'] = sfp_type_data['data']['type']['value'] if sfp_type_data else 'N/A' + xcvr_info_dict['type_abbrv_name'] = sfp_type_abbrv_name['data']['type_abbrv_name']['value'] if sfp_type_abbrv_name else 'N/A' + + xcvr_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A' + xcvr_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' + xcvr_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' + xcvr_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' + xcvr_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A' + xcvr_info_dict['vendor_date'] = sfp_vendor_date_data['data'][ + 'VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A' + xcvr_info_dict['cable_type'] = "Unknown" + xcvr_info_dict['cable_length'] = "Unknown" + + if sfp_type == 'QSFP': + for key in qsfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + xcvr_info_dict['cable_type'] = key + xcvr_info_dict['cable_length'] = str(sfp_interface_bulk_data['data'][key]['value']) + + for key in qsfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + xcvr_info_dict['specification_compliance'] = str(compliance_code_dict) + + nkey = 'Nominal Bit Rate(100Mbs)' + if nkey in sfp_interface_bulk_data['data']: + xcvr_info_dict['nominal_bit_rate'] = str( + sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value']) + else: + xcvr_info_dict['nominal_bit_rate'] = 'N/A' + elif sfp_type == 'OSFP': + pass + else: + for key in sfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + xcvr_info_dict['cable_type'] = key + xcvr_info_dict['cable_length'] = str(sfp_interface_bulk_data['data'][key]['value']) + + for key in sfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + xcvr_info_dict['specification_compliance'] = str(compliance_code_dict) + + xcvr_info_dict['nominal_bit_rate'] = str( + sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) + + return xcvr_info_dict + + def get_transceiver_bulk_status(self): + """ + Retrieves transceiver bulk status of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + rx_los |BOOLEAN |RX loss-of-signal status, True if has RX los, False if not. + tx_fault |BOOLEAN |TX fault status, True if has TX fault, False if not. + reset_status |BOOLEAN |reset status, True if SFP in reset, False if not. + lp_mode |BOOLEAN |low power mode status, True in lp mode, False if not. + tx_disable |BOOLEAN |TX disable status, True TX disabled, False if not. + tx_disabled_channel |HEX |disabled TX channels in hex, bits 0 to 3 represent channel 0 + | |to channel 3. + temperature |INT |module temperature in Celsius + voltage |INT |supply voltage in mV + txbias |INT |TX Bias Current in mA, n is the channel number, + | |for example, tx2bias stands for tx bias of channel 2. + rxpower |INT |received optical power in mW, n is the channel number, + | |for example, rx2power stands for rx power of channel 2. + txpower |INT |TX output power in mW, n is the channel number, + | |for example, tx2power stands for tx power of channel 2. + ======================================================================== + """ + # check present status + if not self.get_presence(): + return None + + xcvr_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A') + + if self.is_osfp_port: + # Below part is added to avoid fail xcvrd, shall be implemented later + pass + elif self.is_qsfp_port: + # QSFPs + offset = 0 + offset_xcvr = 128 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + return None + + qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes( + (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_dom_capability( + qsfp_dom_capability_raw, 0) + else: + return None + + dom_temperature_raw = self.__read_eeprom_specific_bytes((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 None + + dom_voltage_raw = self.__read_eeprom_specific_bytes((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 None + + qsfp_dom_rev_raw = self.__read_eeprom_specific_bytes((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 None + + xcvr_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + xcvr_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( + (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 None + + xcvr_dom_info_dict['tx1power'] = 'N/A' + xcvr_dom_info_dict['tx2power'] = 'N/A' + xcvr_dom_info_dict['tx3power'] = 'N/A' + xcvr_dom_info_dict['tx4power'] = 'N/A' + else: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (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 + + xcvr_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TX1Power']['value'] + xcvr_dom_info_dict['tx2power'] = dom_channel_monitor_data['data']['TX2Power']['value'] + xcvr_dom_info_dict['tx3power'] = dom_channel_monitor_data['data']['TX3Power']['value'] + xcvr_dom_info_dict['tx4power'] = dom_channel_monitor_data['data']['TX4Power']['value'] + + if dom_channel_monitor_raw: + xcvr_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + xcvr_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + xcvr_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RX1Power']['value'] + xcvr_dom_info_dict['rx2power'] = dom_channel_monitor_data['data']['RX2Power']['value'] + xcvr_dom_info_dict['rx3power'] = dom_channel_monitor_data['data']['RX3Power']['value'] + xcvr_dom_info_dict['rx4power'] = dom_channel_monitor_data['data']['RX4Power']['value'] + xcvr_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value'] + xcvr_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value'] + xcvr_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value'] + xcvr_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] + + else: + # SFPs + offset = 256 + + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + dom_temperature_raw = self.__read_eeprom_specific_bytes((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 None + + dom_voltage_raw = self.__read_eeprom_specific_bytes((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 None + + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_CHANNL_MON_OFFSET), SFP_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 None + + xcvr_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + xcvr_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + xcvr_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RXPower']['value'] + xcvr_dom_info_dict['rx2power'] = 'N/A' + xcvr_dom_info_dict['rx3power'] = 'N/A' + xcvr_dom_info_dict['rx4power'] = 'N/A' + xcvr_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TXBias']['value'] + xcvr_dom_info_dict['tx2bias'] = 'N/A' + xcvr_dom_info_dict['tx3bias'] = 'N/A' + xcvr_dom_info_dict['tx4bias'] = 'N/A' + xcvr_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TXPower']['value'] + xcvr_dom_info_dict['tx2power'] = 'N/A' + xcvr_dom_info_dict['tx3power'] = 'N/A' + xcvr_dom_info_dict['tx4power'] = 'N/A' + + xcvr_dom_info_dict['rx_los'] = self.get_rx_los() + xcvr_dom_info_dict['tx_fault'] = self.get_tx_fault() + xcvr_dom_info_dict['reset_status'] = self.get_reset_status() + xcvr_dom_info_dict['lp_mode'] = self.get_lpmode() + + return xcvr_dom_info_dict + + def get_transceiver_threshold_info(self): + """ + Retrieves transceiver threshold info of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius. + templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius. + temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius. + templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius. + vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV. + vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV. + vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV. + vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV. + rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm. + rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm. + rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm. + rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm. + txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm. + txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm. + txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm. + txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm. + txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA. + txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA. + txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA. + txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA. + ======================================================================== + """ + # check present status + if not self.get_presence(): + return None + + xcvr_dom_threshold_info_dict = dict.fromkeys(self.threshold_dict_keys, 'N/A') + + if self.is_osfp_port: + # Below part is added to avoid fail xcvrd, shall be implemented later + pass + elif self.is_qsfp_port: + # QSFPs + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + dom_thres_raw = self.__read_eeprom_specific_bytes(QSFP_MODULE_THRESHOLD_OFFSET, QSFP_MODULE_THRESHOLD_WIDTH) + + if dom_thres_raw: + module_threshold_values = sfpd_obj.parse_module_threshold_values( + dom_thres_raw, 0) + module_threshold_data = module_threshold_values.get('data') + if module_threshold_data: + xcvr_dom_threshold_info_dict['temphighalarm'] = module_threshold_data['TempHighAlarm']['value'] + xcvr_dom_threshold_info_dict['templowalarm'] = module_threshold_data['TempLowAlarm']['value'] + xcvr_dom_threshold_info_dict['temphighwarning'] = module_threshold_data['TempHighWarning']['value'] + xcvr_dom_threshold_info_dict['templowwarning'] = module_threshold_data['TempLowWarning']['value'] + xcvr_dom_threshold_info_dict['vcchighalarm'] = module_threshold_data['VccHighAlarm']['value'] + xcvr_dom_threshold_info_dict['vcclowalarm'] = module_threshold_data['VccLowAlarm']['value'] + xcvr_dom_threshold_info_dict['vcchighwarning'] = module_threshold_data['VccHighWarning']['value'] + xcvr_dom_threshold_info_dict['vcclowwarning'] = module_threshold_data['VccLowWarning']['value'] + + dom_thres_raw = self.__read_eeprom_specific_bytes( + QSFP_CHANNEL_THRESHOLD_OFFSET, QSFP_CHANNEL_THRESHOLD_WIDTH) + if dom_thres_raw: + channel_threshold_values = sfpd_obj.parse_channel_threshold_values( + dom_thres_raw, 0) + channel_threshold_data = channel_threshold_values.get('data') + if channel_threshold_data: + xcvr_dom_threshold_info_dict['rxpowerhighalarm'] = channel_threshold_data['RxPowerHighAlarm']['value'] + xcvr_dom_threshold_info_dict['rxpowerlowalarm'] = channel_threshold_data['RxPowerLowAlarm']['value'] + xcvr_dom_threshold_info_dict['rxpowerhighwarning'] = channel_threshold_data['RxPowerHighWarning']['value'] + xcvr_dom_threshold_info_dict['rxpowerlowwarning'] = channel_threshold_data['RxPowerLowWarning']['value'] + xcvr_dom_threshold_info_dict['txpowerhighalarm'] = "0.0dBm" + xcvr_dom_threshold_info_dict['txpowerlowalarm'] = "0.0dBm" + xcvr_dom_threshold_info_dict['txpowerhighwarning'] = "0.0dBm" + xcvr_dom_threshold_info_dict['txpowerlowwarning'] = "0.0dBm" + xcvr_dom_threshold_info_dict['txbiashighalarm'] = channel_threshold_data['TxBiasHighAlarm']['value'] + xcvr_dom_threshold_info_dict['txbiaslowalarm'] = channel_threshold_data['TxBiasLowAlarm']['value'] + xcvr_dom_threshold_info_dict['txbiashighwarning'] = channel_threshold_data['TxBiasHighWarning']['value'] + xcvr_dom_threshold_info_dict['txbiaslowwarning'] = channel_threshold_data['TxBiasLowWarning']['value'] + + else: + # SFPs + sfpd_obj = sff8472Dom() + offset = 256 + eeprom_ifraw = self.__read_eeprom_specific_bytes(0, offset) + sfpi_obj = sff8472InterfaceId(eeprom_ifraw) + cal_type = sfpi_obj.get_calibration_type() + sfpd_obj._calibration_type = cal_type + + dom_module_threshold_raw = self.__read_eeprom_specific_bytes( + (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) + + xcvr_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + xcvr_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + xcvr_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + xcvr_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + xcvr_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VoltageHighAlarm']['value'] + xcvr_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VoltageLowAlarm']['value'] + xcvr_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data[ + 'data']['VoltageHighWarning']['value'] + xcvr_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VoltageLowWarning']['value'] + xcvr_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value'] + xcvr_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value'] + xcvr_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value'] + xcvr_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value'] + xcvr_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value'] + xcvr_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value'] + xcvr_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value'] + xcvr_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TXPowerLowWarning']['value'] + xcvr_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RXPowerHighAlarm']['value'] + xcvr_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RXPowerLowAlarm']['value'] + xcvr_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RXPowerHighWarning']['value'] + xcvr_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value'] + + return xcvr_dom_threshold_info_dict + + def get_reset_status(self): + """ + Retrieves the reset status of SFP + Returns: + A Boolean, True if reset enabled, False if disabled + """ + reset_status = None + if not self.get_presence(): + return reset_status + + device = 'PORT{}'.format(self.port_index) + output = self.pddf_obj.get_attr_name_output(device, 'xcvr_reset') + if not output: + return False + + status = int(output['status'].rstrip()) + + if status == 1: + reset_status = True + else: + reset_status = False + + return reset_status + + def get_rx_los(self): + """ + Retrieves the RX LOS (lost-of-signal) status of SFP + Returns: + A Boolean, True if SFP has RX LOS, False if not. + Note : RX LOS status is latched until a call to get_rx_los or a reset. + """ + rx_los = None + if not self.get_presence(): + return rx_los + + device = 'PORT{}'.format(self.port_index) + output = self.pddf_obj.get_attr_name_output(device, 'xcvr_rxlos') + + if not output: + # read the values from EEPROM + if self.is_osfp_port: + pass + elif self.is_qsfp_port: + rx_los_list = [] + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + QSFP_CHANNL_RX_LOS_STATUS_OFFSET, QSFP_CHANNL_RX_LOS_STATUS_WIDTH) if self.get_presence() else None + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 16) + rx_los_list.append(rx_los_data & 0x01 != 0) + rx_los_list.append(rx_los_data & 0x02 != 0) + rx_los_list.append(rx_los_data & 0x04 != 0) + rx_los_list.append(rx_los_data & 0x08 != 0) + rx_los = rx_los_list[0] and rx_los_list[1] and rx_los_list[2] and rx_los_list[3] + else: + # SFP ports + status_control_raw = self.__read_eeprom_specific_bytes( + SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if status_control_raw: + data = int(status_control_raw[0], 16) + rx_los = (sffbase().test_bit(data, 1) != 0) + + else: + status = int(output['status'].rstrip()) + + if status == 1: + rx_los = True + else: + rx_los = False + + return rx_los + + def get_tx_fault(self): + """ + Retrieves the TX fault status of SFP + Returns: + A Boolean, True if SFP has TX fault, False if not + Note : TX fault status is lached until a call to get_tx_fault or a reset. + """ + tx_fault = None + if not self.get_presence(): + return tx_fault + + device = 'PORT{}'.format(self.port_index) + output = self.pddf_obj.get_attr_name_output(device, 'xcvr_txfault') + + if not output: + # read the values from EEPROM + if self.is_osfp_port: + pass + elif self.is_qsfp_port: + tx_fault_list = [] + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + QSFP_CHANNL_TX_FAULT_STATUS_OFFSET, QSFP_CHANNL_TX_FAULT_STATUS_WIDTH) if self.get_presence() else None + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 16) + tx_fault_list.append(tx_fault_data & 0x01 != 0) + tx_fault_list.append(tx_fault_data & 0x02 != 0) + tx_fault_list.append(tx_fault_data & 0x04 != 0) + tx_fault_list.append(tx_fault_data & 0x08 != 0) + tx_fault = tx_fault_list[0] and tx_fault_list[1] and tx_fault_list[2] and tx_fault_list[3] + else: + # SFP + status_control_raw = self.__read_eeprom_specific_bytes( + SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if status_control_raw: + data = int(status_control_raw[0], 16) + tx_fault = (sffbase().test_bit(data, 2) != 0) + else: + status = int(output['status'].rstrip()) + + if status == 1: + tx_fault = True + else: + tx_fault = False + + return tx_fault + + def get_tx_disable(self): + """ + Retrieves the tx_disable status of this SFP + Returns: + A Boolean, True if tx_disable is enabled, False if disabled + """ + tx_disable = False + if not self.get_presence(): + return tx_disable + + device = 'PORT{}'.format(self.port_index) + output = self.pddf_obj.get_attr_name_output(device, 'xcvr_txdisable') + + if not output: + # read the values from EEPROM + if self.is_osfp_port: + return tx_disable + elif self.is_qsfp_port: + tx_disable_list = [] + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return False + + dom_control_raw = self.__read_eeprom_specific_bytes( + QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH) if self.get_presence() else None + if dom_control_raw is not None: + dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0) + tx_disable_list.append( + 'On' == dom_control_data['data']['TX1Disable']['value']) + tx_disable_list.append( + 'On' == dom_control_data['data']['TX2Disable']['value']) + tx_disable_list.append( + 'On' == dom_control_data['data']['TX3Disable']['value']) + tx_disable_list.append( + 'On' == dom_control_data['data']['TX4Disable']['value']) + + return tx_disable_list + else: + status_control_raw = self.__read_eeprom_specific_bytes( + SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if status_control_raw: + data = int(status_control_raw[0], 16) + tx_disable_hard = (sffbase().test_bit( + data, SFP_TX_DISABLE_HARD_BIT) != 0) + tx_disable_soft = (sffbase().test_bit( + data, SFP_TX_DISABLE_SOFT_BIT) != 0) + tx_disable = tx_disable_hard | tx_disable_soft + + return tx_disable + else: + status = int(output['status'].rstrip()) + + if status == 1: + tx_disable = True + else: + tx_disable = False + + return tx_disable + + def get_tx_disable_channel(self): + """ + Retrieves the TX disabled channels in this SFP + Returns: + A hex of 4 bits (bit 0 to bit 3 as channel 0 to channel 3) to represent + TX channels which have been disabled in this SFP. + As an example, a returned value of 0x5 indicates that channel 0 + and channel 2 have been disabled. + """ + if not self.get_presence(): + return 0 + + if self.is_osfp_port: + return 0 + elif self.is_qsfp_port: + tx_disable_list = self.get_tx_disable() + if tx_disable_list is None: + return 0 + tx_disabled = 0 + for i in range(len(tx_disable_list)): + if tx_disable_list[i]: + tx_disabled |= 1 << i + return tx_disabled + else: + # SFP doesnt support this + return 0 + + def get_lpmode(self): + """ + Retrieves the lpmode (low power mode) status of this SFP + Returns: + A Boolean, True if lpmode is enabled, False if disabled + """ + lpmode = False + if not self.get_presence(): + return lpmode + + device = 'PORT{}'.format(self.port_index) + output = self.pddf_obj.get_attr_name_output(device, 'xcvr_lpmode') + + if not output: + # Read from EEPROM + if self.is_osfp_port: + pass + elif self.is_qsfp_port: + try: + eeprom = None + ctype = self.get_connector_type() + if ctype in ['Copper pigtail', 'No separable connector']: + return False + + eeprom = open(self.eeprom_path, "rb") + eeprom.seek(93) + status = ord(eeprom.read(1)) + + if ((status & 0x3) == 0x3): + # Low Power Mode if "Power override" bit is 1 and "Power set" bit is 1 + lpmode = True + else: + # High Power Mode if one of the following conditions is matched: + # 1. "Power override" bit is 0 + # 2. "Power override" bit is 1 and "Power set" bit is 0 + lpmode = False + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) + else: + # SFP + pass + else: + status = int(output['status'].rstrip()) + + if status == 1: + lpmode = True + else: + lpmode = False + + return lpmode + + def get_power_override(self): + """ + Retrieves the power-override status of this SFP + Returns: + A Boolean, True if power-override is enabled, False if disabled + """ + power_override = False + if not self.get_presence(): + return power_override + + if self.is_osfp_port: + pass + elif self.is_qsfp_port: + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return False + + dom_control_raw = self.__read_eeprom_specific_bytes( + QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH) if self.get_presence() else None + if dom_control_raw is not None: + dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0) + power_override = ('On' == dom_control_data['data']['PowerOverride']['value']) + else: + # SFP doesnt suppor this + pass + + return power_override + + def get_temperature(self): + """ + Retrieves the temperature of this SFP + Returns: + An integer number of current temperature in Celsius + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + if transceiver_dom_info_dict is not None: + # returns None if temperature is not found in the dictionary + return transceiver_dom_info_dict.get("temperature") + else: + return None + + def get_voltage(self): + """ + Retrieves the supply voltage of this SFP + Returns: + An integer number of supply voltage in mV + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + # returns None if voltage is not found in the dictionary + if transceiver_dom_info_dict is not None: + return transceiver_dom_info_dict.get("voltage") + else: + return None + + def get_tx_bias(self): + """ + Retrieves the TX bias current of this SFP + Returns: + A list of four integer numbers, representing TX bias in mA + for channel 0 to channel 4. + Ex. ['110.09', '111.12', '108.21', '112.09'] + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + if transceiver_dom_info_dict is not None: + tx1_bs = transceiver_dom_info_dict.get("tx1bias", "N/A") + tx2_bs = transceiver_dom_info_dict.get("tx2bias", "N/A") + tx3_bs = transceiver_dom_info_dict.get("tx3bias", "N/A") + tx4_bs = transceiver_dom_info_dict.get("tx4bias", "N/A") + return [tx1_bs, tx2_bs, tx3_bs, tx4_bs] if transceiver_dom_info_dict else [] + else: + return None + + def get_rx_power(self): + """ + Retrieves the received optical power for this SFP + Returns: + A list of four integer numbers, representing received optical + power in mW for channel 0 to channel 4. + Ex. ['1.77', '1.71', '1.68', '1.70'] + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + if transceiver_dom_info_dict is not None: + rx1_pw = transceiver_dom_info_dict.get("rx1power", "N/A") + rx2_pw = transceiver_dom_info_dict.get("rx2power", "N/A") + rx3_pw = transceiver_dom_info_dict.get("rx3power", "N/A") + rx4_pw = transceiver_dom_info_dict.get("rx4power", "N/A") + return [rx1_pw, rx2_pw, rx3_pw, rx4_pw] if transceiver_dom_info_dict else [] + else: + return None + + def get_tx_power(self): + """ + Retrieves the TX power of this SFP + Returns: + A list of four integer numbers, representing TX power in mW + for channel 0 to channel 4. + Ex. ['1.86', '1.86', '1.86', '1.86'] + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + if transceiver_dom_info_dict is not None: + tx1_pw = transceiver_dom_info_dict.get("tx1power", "N/A") + tx2_pw = transceiver_dom_info_dict.get("tx2power", "N/A") + tx3_pw = transceiver_dom_info_dict.get("tx3power", "N/A") + tx4_pw = transceiver_dom_info_dict.get("tx4power", "N/A") + return [tx1_pw, tx2_pw, tx3_pw, tx4_pw] + else: + return None + + def reset(self): + """ + Reset SFP and return all user module settings to their default srate. + Returns: + A boolean, True if successful, False if not + """ + status = False + if not self.get_presence(): + return status + + device = 'PORT{}'.format(self.port_index) + # TODO: Implement a wrapper set function to write the sequence + path = self.pddf_obj.get_path(device, 'xcvr_reset') + + # TODO: put the optic based reset logic using EEPROM + if path is None: + pass + else: + try: + f = open(path, 'r+') + except IOError as e: + return False + + try: + f.seek(0) + f.write('1') + time.sleep(1) + f.seek(0) + f.write('0') + + f.close() + status = True + except IOError as e: + status = False + + return status + + def tx_disable(self, tx_disable): + """ + Disable SFP TX for all channels + Args: + tx_disable : A Boolean, True to enable tx_disable mode, False to disable + tx_disable mode. + Returns: + A boolean, True if tx_disable is set successfully, False if not + """ + # find out a generic implementation of tx_disable for SFP, QSFP and OSFP + status = False + if not self.get_presence(): + return tx_disable + + device = 'PORT{}'.format(self.port_index) + path = self.pddf_obj.get_path(device, 'xcvr_txdisable') + + # TODO: put the optic based reset logic using EEPROM + if path is None: + if self.is_osfp_port: + pass + elif self.is_qsfp_port: + eeprom_f = None + try: + txdisable_ctl = 0xf if tx_disable else 0x0 + buf = create_string_buffer(1) + buf[0] = chr(txdisable_ctl) + # Write to eeprom + eeprom_f = open(self.eeprom_path, "r+b") + eeprom_f.seek(QSFP_CONTROL_OFFSET) + eeprom_f.write(buf[0]) + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + finally: + if eeprom_f is not None: + eeprom_f.close() + time.sleep(0.01) + + status = True + else: + status_control_raw = self.__read_eeprom_specific_bytes( + SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if status_control_raw is not None: + # Set bit 6 for Soft TX Disable Select + # 01000000 = 64 and 10111111 = 191 + txdisable_bit = 64 if tx_disable else 191 + status_control = int(status_control_raw[0], 16) + txdisable_ctl = (status_control | txdisable_bit) if tx_disable else ( + status_control & txdisable_bit) + try: + eeprom_f = open(self.eeprom_path, mode="r+b", buffering=0) + buf = create_string_buffer(1) + buf[0] = chr(txdisable_ctl) + # Write to eeprom + eeprom_f.seek(SFP_STATUS_CONTROL_OFFSET) + eeprom_f.write(buf[0]) + except Exception as e: + print(("Error: unable to open file: %s" % str(e))) + return False + finally: + if eeprom_f: + eeprom_f.close() + time.sleep(0.01) + status = True + else: + try: + f = open(path, 'r+') + except IOError as e: + return False + + try: + if tx_disable: + f.write('1') + else: + f.write('0') + f.close() + status = True + except IOError as e: + status = False + + return status + + def tx_disable_channel(self, channel, disable): + """ + Sets the tx_disable for specified SFP channels + Args: + channel : A hex of 4 bits (bit 0 to bit 3) which represent channel 0 to 3, + e.g. 0x5 for channel 0 and channel 2. + disable : A boolean, True to disable TX channels specified in channel, + False to enable + Returns: + A boolean, True if successful, False if not + """ + # TODO: find a implementation + status = False + if not self.get_presence(): + return status + + if self.is_osfp_port: + pass + elif self.is_qsfp_port: + eeprom_f = None + try: + channel_state = self.get_tx_disable_channel() + txdisable_ctl = (channel_state | channel) if disable else (channel_state & ~channel) + buf = create_string_buffer(1) + buf[0] = chr(txdisable_ctl) + # Write to eeprom + eeprom_f = open(self.eeprom_path, "r+b") + eeprom_f.seek(QSFP_CONTROL_OFFSET) + eeprom_f.write(buf[0]) + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + finally: + if eeprom_f is not None: + eeprom_f.close() + time.sleep(0.01) + status = True + else: + pass + + return status + + def set_lpmode(self, lpmode): + """ + Sets the lpmode (low power mode) of SFP + Args: + lpmode: A Boolean, True to enable lpmode, False to disable it + Note : lpmode can be overridden by set_power_override + Returns: + A boolean, True if lpmode is set successfully, False if not + """ + status = False + if not self.get_presence(): + return status + + device = 'PORT{}'.format(self.port_index) + path = self.pddf_obj.get_path(device, 'xcvr_lpmode') + + # TODO: put the optic based reset logic using EEPROM + if path is None: + if self.is_osfp_port: + pass + elif self.is_qsfp_port: + try: + eeprom_f = None + ctype = self.get_connector_type() + if ctype in ['Copper pigtail', 'No separable connector']: + return False + + # Fill in write buffer + regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode + buffer = create_string_buffer(1) + buffer[0] = chr(regval) + + # Write to eeprom + eeprom_f = open(self.eeprom_path, "r+b") + eeprom_f.seek(93) + eeprom_f.write(buffer[0]) + return True + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + finally: + if eeprom_f is not None: + eeprom_f.close() + time.sleep(0.01) + else: + pass + + else: + try: + f = open(path, 'r+') + except IOError as e: + return False + + try: + if lpmode: + f.write('1') + else: + f.write('0') + + f.close() + status = True + except IOError as e: + status = False + + return status + + def set_power_override(self, power_override, power_set): + """ + Sets SFP power level using power_override and power_set + Args: + power_override : + A Boolean, True to override set_lpmode and use power_set + to control SFP power, False to disable SFP power control + through power_override/power_set and use set_lpmode + to control SFP power. + power_set : + Only valid when power_override is True. + A Boolean, True to set SFP to low power mode, False to set + SFP to high power mode. + Returns: + A boolean, True if power-override and power_set are set successfully, + False if not + """ + status = False + if not self.get_presence(): + return status + + if self.is_osfp_port: + pass + elif self.is_qsfp_port: + try: + power_override_bit = 0 + if power_override: + power_override_bit |= 1 << 0 + + power_set_bit = 0 + if power_set: + power_set_bit |= 1 << 1 + + buffer = create_string_buffer(1) + buffer[0] = chr(power_override_bit | power_set_bit) + # Write to eeprom + eeprom_f = open(self.eeprom_path, "r+b") + eeprom_f.seek(QSFP_POWEROVERRIDE_OFFSET) + eeprom_f.write(buffer[0]) + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + finally: + if eeprom_f is not None: + eeprom_f.close() + time.sleep(0.01) + return True + else: + pass + + return status + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + # Name of the port/sfp ? + return 'PORT{}'.format(self.port_index) + + def get_presence(self): + """ + Retrieves the presence of the PSU + Returns: + bool: True if PSU is present, False if not + """ + output = self.pddf_obj.get_attr_name_output(self.device, 'xcvr_present') + if not output: + return False + + mode = output['mode'] + modpres = output['status'].rstrip() + if 'XCVR' in self.plugin_data: + if 'xcvr_present' in self.plugin_data['XCVR']: + ptype = self.sfp_type + vtype = 'valmap-'+ptype + if vtype in self.plugin_data['XCVR']['xcvr_present'][mode]: + vmap = self.plugin_data['XCVR']['xcvr_present'][mode][vtype] + if modpres in vmap: + return vmap[modpres] + else: + return False + # if self.plugin_data doesn't specify anything regarding Transceivers + if modpres == '1': + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + transceiver_dom_info_dict = self.get_transceiver_info() + if transceiver_dom_info_dict is not None: + return transceiver_dom_info_dict.get("model", "N/A") + else: + return None + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + transceiver_dom_info_dict = self.get_transceiver_info() + if transceiver_dom_info_dict is not None: + return transceiver_dom_info_dict.get("serial", "N/A") + else: + return None + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self.get_presence() and self.get_transceiver_bulk_status() + + def get_connector_type(self): + """ + Retrieves the device connector type + Returns: + enum: connector_code + """ + transceiver_dom_info_dict = self.get_transceiver_info() + if transceiver_dom_info_dict is not None: + return transceiver_dom_info_dict.get("connector", "N/A") + else: + return None + + 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 + + def dump_sysfs(self): + return self.pddf_obj.cli_dump_dsysfs('xcvr') diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_thermal.py b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_thermal.py new file mode 100755 index 000000000000..cd09041e152f --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_thermal.py @@ -0,0 +1,167 @@ +#!/usr/bin/env python + +# All the supported Temperature Sensor SysFS aattributes are +#- temp1_high_crit_threshold +#- temp1_high_threshold +#- temp1_input +#- temp_low_threshold +#- temp1_low_crit_threshold + +try: + from sonic_platform_base.thermal_base import ThermalBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PddfThermal(ThermalBase): + """PDDF generic Thermal class""" + pddf_obj = {} + plugin_data = {} + + def __init__(self, index, pddf_data=None, pddf_plugin_data=None): + if not pddf_data or not pddf_plugin_data: + raise ValueError('PDDF JSON data error') + + self.pddf_obj = pddf_data + self.plugin_data = pddf_plugin_data + + self.platform = self.pddf_obj.get_platform() + + self.thermal_index = index + 1 + self.thermal_obj_name = "TEMP{}".format(self.thermal_index) + self.thermal_obj = self.pddf_obj.data[self.thermal_obj_name] + + def get_name(self): + if 'dev_attr' in self.thermal_obj.keys(): + if 'display_name' in self.thermal_obj['dev_attr']: + return str(self.thermal_obj['dev_attr']['display_name']) + # In case of errors + return (self.thermal_obj_name) + + def get_temperature(self): + output = self.pddf_obj.get_attr_name_output(self.thermal_obj_name, "temp1_input") + if not output: + return None + + if output['status'].isalpha(): + attr_value = None + else: + attr_value = float(output['status']) + + if output['mode'] == 'bmc': + return attr_value + else: + return (attr_value/float(1000)) + + def get_high_threshold(self): + output = self.pddf_obj.get_attr_name_output(self.thermal_obj_name, "temp1_high_threshold") + if not output: + return None + + if output['status'].isalpha(): + attr_value = None + else: + attr_value = float(output['status']) + + if output['mode'] == 'bmc': + return attr_value + else: + return (attr_value/float(1000)) + + def get_low_threshold(self): + output = self.pddf_obj.get_attr_name_output(self.thermal_obj_name, "temp1_low_threshold") + if not output: + return None + + if output['status'].isalpha(): + attr_value = None + else: + attr_value = float(output['status']) + + if output['mode'] == 'bmc': + return attr_value + else: + return (attr_value/float(1000)) + + def set_high_threshold(self, temperature): + node = self.pddf_obj.get_path(self.thermal_obj_name, "temp1_high_threshold") + if node is None: + print("ERROR %s does not exist" % node) + return None + + cmd = "echo '%d' > %s" % (temperature * 1000, node) + os.system(cmd) + + return (True) + + def set_low_threshold(self, temperature): + node = self.pddf_obj.get_path(self.thermal_obj_name, "temp1_low_threshold") + if node is None: + print("ERROR %s does not exist" % node) + return None + cmd = "echo '%d' > %s" % (temperature * 1000, node) + os.system(cmd) + + return (True) + + def get_high_critical_threshold(self): + """ + Retrieves the high critical threshold temperature of thermal + + Returns: + A float number, the high critical threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + output = self.pddf_obj.get_attr_name_output(self.thermal_obj_name, "temp1_high_crit_threshold") + if not output: + return None + + if output['status'].isalpha(): + attr_value = None + else: + attr_value = float(output['status']) + + if output['mode'] == 'bmc': + return attr_value + else: + return (attr_value/float(1000)) + + def get_low_critical_threshold(self): + """ + Retrieves the low critical threshold temperature of thermal + + Returns: + A float number, the low critical threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + output = self.pddf_obj.get_attr_name_output(self.thermal_obj_name, "temp1_low_crit_threshold") + if not output: + return None + + if output['status'].isalpha(): + attr_value = None + else: + attr_value = float(output['status']) + + if output['mode'] == 'bmc': + return attr_value + else: + return (attr_value/float(1000)) + + # Helper Functions + + def get_temp_label(self): + if 'bmc' in self.pddf_obj.data[self.thermal_obj_name].keys(): + return None + else: + if self.thermal_obj_name in self.pddf_obj.data.keys(): + dev = self.pddf_obj.data[self.thermal_obj_name] + topo_info = dev['i2c']['topo_info'] + label = "%s-i2c-%d-%x" % (topo_info['dev_type'], int(topo_info['parent_bus'], 0), + int(topo_info['dev_addr'], 0)) + return (label) + else: + return None + + def dump_sysfs(self): + return self.pddf_obj.cli_dump_dsysfs('temp-sensors') diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddfparse.py b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddfparse.py new file mode 100755 index 000000000000..6ca59206fd56 --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddfparse.py @@ -0,0 +1,1465 @@ +#!/usr/bin/env python +import glob +import json +from jsonschema import validate +import os +import re +import subprocess +import time +import unicodedata + +bmc_cache = {} +cache = {} +SONIC_CFGGEN_PATH = '/usr/local/bin/sonic-cfggen' +HWSKU_KEY = 'DEVICE_METADATA.localhost.hwsku' +PLATFORM_KEY = 'DEVICE_METADATA.localhost.platform' + +dirname = os.path.dirname(os.path.realpath(__file__)) + +color_map = { + "STATUS_LED_COLOR_GREEN": "green", + "STATUS_LED_COLOR_RED": "red", + "STATUS_LED_COLOR_AMBER": "amber", + "STATUS_LED_COLOR_BLUE": "blue", + "STATUS_LED_COLOR_GREEN_BLINK": "blinking green", + "STATUS_LED_COLOR_RED_BLINK": "blinking red", + "STATUS_LED_COLOR_AMBER_BLINK": "blinking amber", + "STATUS_LED_COLOR_BLUE_BLINK": "blinking blue", + "STATUS_LED_COLOR_OFF": "off" +} + + +class PddfParse(): + def __init__(self): + if not os.path.exists("/usr/share/sonic/platform"): + self.platform, self.hwsku = self.get_platform_and_hwsku() + os.symlink("/usr/share/sonic/device/"+self.platform, "/usr/share/sonic/platform") + + try: + with open('/usr/share/sonic/platform/pddf/pddf-device.json') as f: + self.data = json.load(f) + except IOError: + if os.path.exists('/usr/share/sonic/platform'): + os.unlink("/usr/share/sonic/platform") + + self.data_sysfs_obj = {} + self.sysfs_obj = {} + + # Returns platform and HW SKU + + def get_platform_and_hwsku(self): + try: + proc = subprocess.Popen([SONIC_CFGGEN_PATH, '-H', '-v', PLATFORM_KEY], + stdout=subprocess.PIPE, + shell=False, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + platform = stdout.rstrip('\n') + + proc = subprocess.Popen([SONIC_CFGGEN_PATH, '-d', '-v', HWSKU_KEY], + stdout=subprocess.PIPE, + shell=False, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + hwsku = stdout.rstrip('\n') + except OSError as e: + raise OSError("Cannot detect platform") + + return (platform, hwsku) + + ################################################################################################################# + # GENERIC DEFS + ################################################################################################################# + def runcmd(self, cmd): + rc = os.system(cmd) + if rc != 0: + print("%s -- command failed" % cmd) + return rc + + def get_dev_idx(self, dev, ops): + parent = dev['dev_info']['virt_parent'] + pdev = self.data[parent] + + return pdev['dev_attr']['dev_idx'] + + def get_path(self, target, attr): + aa = target + attr + + if aa in cache: + return cache[aa] + + string = None + p = re.search(r'\d+$', target) + if p is None: + for bb in filter(re.compile(target).search, self.data.keys()): + path = self.dev_parse(self.data[bb], {"cmd": "show_attr", "target": bb, "attr": attr}) + if path != "": + string = path + else: + if target in self.data.keys(): + path = self.dev_parse(self.data[target], {"cmd": "show_attr", "target": target, "attr": attr}) + if path != "": + string = path + + if string is not None: + string = string.rstrip() + + cache[aa] = string + return string + + def get_device_type(self, key): + if key not in self.data.keys(): + return None + return self.data[key]['dev_info']['device_type'] + + def get_platform(self): + return self.data['PLATFORM'] + + def get_num_psu_fans(self, dev): + if dev not in self.data.keys(): + return 0 + + if 'num_psu_fans' not in self.data[dev]['dev_attr']: + return 0 + + return self.data[dev]['dev_attr']['num_psu_fans'] + + def get_led_path(self): + return ("pddf/devices/led") + + def get_led_cur_state_path(self): + return ("pddf/devices/led/cur_state") + + def get_led_color(self): + color_f = "/sys/kernel/pddf/devices/led/cur_state/color" + try: + with open(color_f, 'r') as f: + color = f.read().strip("\r\n") + except IOError: + return ("Error") + + return (color_map[color]) + + def get_led_color_devtype(self, key): + attr_list = self.data[key]['i2c']['attr_list'] + for attr in attr_list: + if 'attr_devtype' in attr: + return attr['attr_devtype'].strip() + else: + return 'cpld' + + def get_led_color_from_gpio(self, led_device_name): + attr_list = self.data[led_device_name]['i2c']['attr_list'] + attr = attr_list[0] + if ':' in attr['bits']: + bits_list = attr['bits'].split(':') + bits_list.sort(reverse=True) + max_bit = int(bits_list[0]) + else: + max_bit = 0 + base_offset = int(attr['swpld_addr_offset'], 16) + value = 0 + bit = 0 + while bit <= max_bit: + offset = base_offset + bit + if 'attr_devname' in attr: + attr_path = self.get_gpio_attr_path(self.data[attr['attr_devname']], hex(offset)) + else: + status = "[FAILED] attr_devname is not configured" + return (status) + if not os.path.exists(attr_path): + status = "[FAILED] {} does not exist".format(attr_path) + return (status) + cmd = 'cat ' + attr_path + gpio_value = subprocess.check_output(cmd, shell=True) + value |= int(gpio_value) << bit + bit += 1 + + for attr in attr_list: + if int(attr['value'].strip(), 16) == value: + return(color_map[attr['attr_name']]) + return (color_map['STATUS_LED_COLOR_OFF']) + + def get_led_color_from_cpld(self, led_device_name): + index = self.data[led_device_name]['dev_attr']['index'] + device_name = self.data[led_device_name]['dev_info']['device_name'] + self.create_attr('device_name', device_name, self.get_led_path()) + self.create_attr('index', index, self.get_led_path()) + self.create_attr('dev_ops', 'get_status', self.get_led_path()) + return self.get_led_color() + + def set_led_color_from_gpio(self, led_device_name, color): + attr_list = self.data[led_device_name]['i2c']['attr_list'] + for attr in attr_list: + if attr['attr_name'].strip() == color.strip(): + base_offset = int(attr['swpld_addr_offset'], 16) + if ':' in attr['bits']: + bits_list = attr['bits'].split(':') + bits_list.sort(reverse=True) + max_bit = int(bits_list[0]) + else: + max_bit = 0 + value = int(attr['value'], 16) + i = 0 + while i <= max_bit: + _value = (value >> i) & 1 + base_offset += i + attr_path = self.get_gpio_attr_path(self.data[attr['attr_devname']], hex(base_offset)) + i += 1 + try: + cmd = "echo {} > {}".format(_value, attr_path) + self.runcmd(cmd) + except Exception as e: + print("Invalid gpio path : " + attr_path) + return (False) + return (True) + + def set_led_color_from_cpld(self, led_device_name, color): + index = self.data[led_device_name]['dev_attr']['index'] + device_name = self.data[led_device_name]['dev_info']['device_name'] + self.create_attr('device_name', device_name, self.get_led_path()) + self.create_attr('index', index, self.get_led_path()) + self.create_attr('color', color, self.get_led_cur_state_path()) + self.create_attr('dev_ops', 'set_status', self.get_led_path()) + return (True) + + def get_system_led_color(self, led_device_name): + if led_device_name not in self.data.keys(): + status = "[FAILED] " + led_device_name + " is not configured" + return (status) + + type = self.get_led_color_devtype(led_device_name) + + if type == 'gpio': + color = self.get_led_color_from_gpio(led_device_name) + elif type == 'cpld': + color = self.get_led_color_from_cpld(led_device_name) + return color + + def set_system_led_color(self, led_device_name, color): + result, msg = self.is_supported_sysled_state(led_device_name, color) + if result == False: + print(msg) + return (result) + + type = self.get_led_color_devtype(led_device_name) + + if type == 'gpio': + return (self.set_led_color_from_gpio(led_device_name, color)) + else: + return (self.set_led_color_from_cpld(led_device_name, color)) + + ################################################################################################################### + # SHOW ATTRIBIUTES DEFS + ################################################################################################################### + def is_led_device_configured(self, device_name, attr_name): + if device_name in self.data.keys(): + attr_list = self.data[device_name]['i2c']['attr_list'] + for attr in attr_list: + if attr['attr_name'].strip() == attr_name.strip(): + return (True) + return (False) + + def show_device_sysfs(self, dev, ops): + parent = dev['dev_info']['device_parent'] + pdev = self.data[parent] + if pdev['dev_info']['device_parent'] == 'SYSTEM': + return "/sys/bus/i2c/devices/"+"i2c-%d" % int(pdev['i2c']['topo_info']['dev_addr'], 0) + return self.show_device_sysfs(pdev, ops) + "/" + "i2c-%d" % int(dev['i2c']['topo_info']['parent_bus'], 0) + + # This is alid for 'at24' type of EEPROM devices. Only one attribtue 'eeprom' + + def show_attr_eeprom_device(self, dev, ops): + str = "" + attr_name = ops['attr'] + attr_list = dev['i2c']['attr_list'] + KEY = "eeprom" + dsysfs_path = "" + + if KEY not in self.data_sysfs_obj: + self.data_sysfs_obj[KEY] = [] + + for attr in attr_list: + if attr_name == attr['attr_name'] or attr_name == 'all': + if 'drv_attr_name' in attr.keys(): + real_name = attr['drv_attr_name'] + else: + real_name = attr['attr_name'] + + dsysfs_path = self.show_device_sysfs(dev, ops) + \ + "/%d-00%x" % (int(dev['i2c']['topo_info']['parent_bus'], 0), + int(dev['i2c']['topo_info']['dev_addr'], 0)) + \ + "/%s" % real_name + if dsysfs_path not in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(dsysfs_path) + str += dsysfs_path+"\n" + return str + + def show_attr_gpio_device(self, dev, ops): + ret = "" + KEY = "gpio" + if KEY not in self.data_sysfs_obj: + self.data_sysfs_obj[KEY] = [] + + return ret + + def show_attr_mux_device(self, dev, ops): + ret = "" + KEY = "mux" + if KEY not in self.data_sysfs_obj: + self.data_sysfs_obj[KEY] = [] + + return ret + + def get_gpio_attr_path(self, dev, offset): + base = int(dev['i2c']['dev_attr']['gpio_base'], 16) + port_num = base + int(offset, 16) + gpio_name = 'gpio'+str(port_num) + path = '/sys/class/gpio/'+gpio_name+'/value' + return path + + def show_attr_psu_i2c_device(self, dev, ops): + target = ops['target'] + attr_name = ops['attr'] + ret = "" + KEY = "psu" + dsysfs_path = "" + + if KEY not in self.data_sysfs_obj: + self.data_sysfs_obj[KEY] = [] + + if target == 'all' or target == dev['dev_info']['virt_parent']: + attr_list = dev['i2c']['attr_list'] + for attr in attr_list: + if attr_name == attr['attr_name'] or attr_name == 'all': + if 'attr_devtype' in attr.keys() and attr['attr_devtype'] == "gpio": + # Check and enable the gpio from class + attr_path = self.get_gpio_attr_path(self.data[attr['attr_devname']], attr['attr_offset']) + if (os.path.exists(attr_path)): + if attr_path not in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(attr_path) + ret += attr_path + '\n' + else: + if 'drv_attr_name' in attr.keys(): + real_name = attr['drv_attr_name'] + else: + real_name = attr['attr_name'] + + dsysfs_path = self.show_device_sysfs(dev, ops) + \ + "/%d-00%x" % (int(dev['i2c']['topo_info']['parent_bus'], 0), + int(dev['i2c']['topo_info']['dev_addr'], 0)) + \ + "/%s" % real_name + if dsysfs_path not in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(dsysfs_path) + ret += dsysfs_path+"\n" + return ret + + def show_attr_psu_device(self, dev, ops): + return self.show_attr_psu_i2c_device(dev, ops) + + def show_attr_fan_device(self, dev, ops): + ret = "" + attr_name = ops['attr'] + attr_list = dev['i2c']['attr_list'] + KEY = "fan" + dsysfs_path = "" + + if KEY not in self.data_sysfs_obj: + self.data_sysfs_obj[KEY] = [] + + for attr in attr_list: + if attr_name == attr['attr_name'] or attr_name == 'all': + if 'attr_devtype' in attr.keys() and attr['attr_devtype'] == "gpio": + # Check and enable the gpio from class + attr_path = self.get_gpio_attr_path(self.data[attr['attr_devname']], attr['attr_offset']) + if (os.path.exists(attr_path)): + if attr_path not in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(attr_path) + ret += attr_path + '\n' + else: + if 'drv_attr_name' in attr.keys(): + real_name = attr['drv_attr_name'] + else: + real_name = attr['attr_name'] + + dsysfs_path = self.show_device_sysfs(dev, ops) + \ + "/%d-00%x" % (int(dev['i2c']['topo_info']['parent_bus'], 0), + int(dev['i2c']['topo_info']['dev_addr'], 0)) + \ + "/%s" % real_name + if dsysfs_path not in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(dsysfs_path) + ret += dsysfs_path+"\n" + return ret + + # This is only valid for LM75 + def show_attr_temp_sensor_device(self, dev, ops): + str = "" + attr_name = ops['attr'] + attr_list = dev['i2c']['attr_list'] + KEY = "temp-sensors" + dsysfs_path = "" + + if KEY not in self.data_sysfs_obj: + self.data_sysfs_obj[KEY] = [] + + for attr in attr_list: + if attr_name == attr['attr_name'] or attr_name == 'all': + path = self.show_device_sysfs(dev, ops)+"/%d-00%x/" % (int(dev['i2c']['topo_info']['parent_bus'], 0), + int(dev['i2c']['topo_info']['dev_addr'], 0)) + if 'drv_attr_name' in attr.keys(): + real_name = attr['drv_attr_name'] + else: + real_name = attr['attr_name'] + + if (os.path.exists(path)): + full_path = glob.glob(path + 'hwmon/hwmon*/' + real_name)[0] + dsysfs_path = full_path + if dsysfs_path not in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(dsysfs_path) + str += full_path + "\n" + return str + + def show_attr_sysstatus_device(self, dev, ops): + ret = "" + attr_name = ops['attr'] + attr_list = dev['attr_list'] + KEY = "sys-status" + dsysfs_path = "" + + if KEY not in self.data_sysfs_obj: + self.data_sysfs_obj[KEY] = [] + + for attr in attr_list: + if attr_name == attr['attr_name'] or attr_name == 'all': + dsysfs_path = "/sys/kernel/pddf/devices/sysstatus/sysstatus_data/" + attr['attr_name'] + if dsysfs_path not in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(dsysfs_path) + ret += dsysfs_path+"\n" + return ret + + def show_attr_xcvr_i2c_device(self, dev, ops): + target = ops['target'] + attr_name = ops['attr'] + ret = "" + dsysfs_path = "" + KEY = "xcvr" + if KEY not in self.data_sysfs_obj: + self.data_sysfs_obj[KEY] = [] + + if target == 'all' or target == dev['dev_info']['virt_parent']: + attr_list = dev['i2c']['attr_list'] + for attr in attr_list: + if attr_name == attr['attr_name'] or attr_name == 'all': + if 'attr_devtype' in attr.keys() and attr['attr_devtype'] == "gpio": + # Check and enable the gpio from class + attr_path = self.get_gpio_attr_path(self.data[attr['attr_devname']], attr['attr_offset']) + if (os.path.exists(attr_path)): + if attr_path not in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(attr_path) + ret += attr_path + '\n' + else: + if 'drv_attr_name' in attr.keys(): + real_name = attr['drv_attr_name'] + else: + real_name = attr['attr_name'] + + dsysfs_path = self.show_device_sysfs(dev, ops) + \ + "/%d-00%x" % (int(dev['i2c']['topo_info']['parent_bus'], 0), + int(dev['i2c']['topo_info']['dev_addr'], 0)) + \ + "/%s" % real_name + if dsysfs_path not in self.data_sysfs_obj[KEY]: + self.data_sysfs_obj[KEY].append(dsysfs_path) + ret += dsysfs_path+"\n" + return ret + + def show_attr_xcvr_device(self, dev, ops): + return self.show_attr_xcvr_i2c_device(dev, ops) + + def show_attr_cpld_device(self, dev, ops): + ret = "" + KEY = "cpld" + if KEY not in self.data_sysfs_obj: + self.data_sysfs_obj[KEY] = [] + + return ret + + ################################################################################################################### + # SHOW DEFS + ################################################################################################################### + + def check_led_cmds(self, key, ops): + name = ops['target']+'_LED' + if (ops['target'] == 'config' or ops['attr'] == 'all') or \ + (name == self.data[key]['dev_info']['device_name'] and + ops['attr'] == self.data[key]['dev_attr']['index']): + return (True) + else: + return (False) + + def dump_sysfs_obj(self, obj, key_type): + if (key_type == 'keys'): + for key in obj.keys(): + print(key) + return + + for key in obj: + if (key == key_type or key_type == 'all'): + print(key+":") + for entry in obj[key]: + print("\t"+entry) + + def add_list_sysfs_obj(self, obj, KEY, list): + for sysfs in list: + if sysfs not in obj[KEY]: + obj[KEY].append(sysfs) + + def sysfs_attr(self, key, value, path, obj, obj_key): + sysfs_path = "/sys/kernel/%s/%s" % (path, key) + if sysfs_path not in obj[obj_key]: + obj[obj_key].append(sysfs_path) + + def sysfs_device(self, attr, path, obj, obj_key): + for key in attr.keys(): + sysfs_path = "/sys/kernel/%s/%s" % (path, key) + if sysfs_path not in obj[obj_key]: + obj[obj_key].append(sysfs_path) + + def show_eeprom_device(self, dev, ops): + return + + def show_mux_device(self, dev, ops): + KEY = 'mux' + if KEY not in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + self.sysfs_device(dev['i2c']['topo_info'], "pddf/devices/mux", self.sysfs_obj, KEY) + self.sysfs_device(dev['i2c']['dev_attr'], "pddf/devices/mux", self.sysfs_obj, KEY) + sysfs_path = "/sys/kernel/pddf/devices/mux/dev_ops" + if sysfs_path not in self.sysfs_obj[KEY]: + self.sysfs_obj[KEY].append(sysfs_path) + list = ['/sys/kernel/pddf/devices/mux/i2c_type', + '/sys/kernel/pddf/devices/mux/i2c_name', + '/sys/kernel/pddf/devices/mux/error'] + self.add_list_sysfs_obj(self.sysfs_obj, KEY, list) + + def show_gpio_device(self, dev, ops): + KEY = 'gpio' + if KEY not in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + self.sysfs_device(dev['i2c']['topo_info'], "pddf/devices/gpio", self.sysfs_obj, KEY) + self.sysfs_device(dev['i2c']['dev_attr'], "pddf/devices/gpio", self.sysfs_obj, KEY) + sysfs_path = "/sys/kernel/pddf/devices/gpio/dev_ops" + if sysfs_path not in self.sysfs_obj[KEY]: + self.sysfs_obj[KEY].append(sysfs_path) + list = ['/sys/kernel/pddf/devices/gpio/i2c_type', + '/sys/kernel/pddf/devices/gpio/i2c_name', + '/sys/kernel/pddf/devices/gpio/error'] + self.add_list_sysfs_obj(self.sysfs_obj, KEY, list) + + def show_psu_i2c_device(self, dev, ops): + KEY = 'psu' + path = 'pddf/devices/psu/i2c' + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['PSU']: + if KEY not in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + self.sysfs_device(dev['i2c']['topo_info'], path, self.sysfs_obj, KEY) + sysfs_path = "/sys/kernel/pddf/devices/psu/i2c/psu_idx" + self.sysfs_obj[KEY].append(sysfs_path) + + for attr in dev['i2c']['attr_list']: + self.sysfs_device(attr, "pddf/devices/psu/i2c", self.sysfs_obj, KEY) + sysfs_path = "/sys/kernel/pddf/devices/psu/i2c/dev_ops" + if sysfs_path not in self.sysfs_obj[KEY]: + self.sysfs_obj[KEY].append(sysfs_path) + list = ['/sys/kernel/pddf/devices/psu/i2c/i2c_type', + '/sys/kernel/pddf/devices/fan/i2c/i2c_name', + '/sys/kernel/pddf/devices/psu/i2c/error', + '/sys/kernel/pddf/devices/psu/i2c/attr_ops'] + self.add_list_sysfs_obj(self.sysfs_obj, KEY, list) + + def show_psu_device(self, dev, ops): + self.show_psu_i2c_device(dev, ops) + return + + def show_client_device(self): + KEY = 'client' + if KEY not in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + list = ['/sys/kernel/pddf/devices/showall'] + self.add_list_sysfs_obj(self.sysfs_obj, KEY, list) + + def show_fan_device(self, dev, ops): + KEY = 'fan' + path = 'pddf/devices/fan/i2c' + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['FAN']: + if KEY not in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + + self.sysfs_device(dev['i2c']['topo_info'], path, self.sysfs_obj, KEY) + self.sysfs_device(dev['i2c']['dev_attr'], path, self.sysfs_obj, KEY) + for attr in dev['i2c']['attr_list']: + self.sysfs_device(attr, path, self.sysfs_obj, KEY) + list = ['/sys/kernel/pddf/devices/fan/i2c/i2c_type', + '/sys/kernel/pddf/devices/fan/i2c/i2c_name', + '/sys/kernel/pddf/devices/fan/i2c/error', + '/sys/kernel/pddf/devices/fan/i2c/attr_ops', + '/sys/kernel/pddf/devices/fan/i2c/dev_ops'] + self.add_list_sysfs_obj(self.sysfs_obj, KEY, list) + + def show_temp_sensor_device(self, dev, ops): + return + + def show_sysstatus_device(self, dev, ops): + KEY = 'sysstatus' + if KEY not in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + for attr in dev['attr_list']: + self.sysfs_device(attr, "pddf/devices/sysstatus", self.sysfs_obj, KEY) + sysfs_path = "/sys/kernel/pddf/devices/sysstatus/attr_ops" + if sysfs_path not in self.sysfs_obj[KEY]: + self.sysfs_obj[KEY].append(sysfs_path) + + def show_xcvr_i2c_device(self, dev, ops): + KEY = 'xcvr' + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['PORT_MODULE']: + if KEY not in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + self.sysfs_device(dev['i2c']['topo_info'], "pddf/devices/xcvr/i2c", self.sysfs_obj, KEY) + + for attr in dev['i2c']['attr_list']: + self.sysfs_device(attr, "pddf/devices/xcvr/i2c", self.sysfs_obj, KEY) + sysfs_path = "/sys/kernel/pddf/devices/xcvr/i2c/dev_ops" + if sysfs_path not in self.sysfs_obj[KEY]: + self.sysfs_obj[KEY].append(sysfs_path) + list = ['/sys/kernel/pddf/devices/xcvr/i2c/i2c_type', + '/sys/kernel/pddf/devices/xcvr/i2c/i2c_name', + '/sys/kernel/pddf/devices/xcvr/i2c/error', + '/sys/kernel/pddf/devices/xcvr/i2c/attr_ops'] + self.add_list_sysfs_obj(self.sysfs_obj, KEY, list) + + def show_xcvr_device(self, dev, ops): + self.show_xcvr_i2c_device(dev, ops) + return + + def show_cpld_device(self, dev, ops): + KEY = 'cpld' + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['CPLD']: + if KEY not in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + self.sysfs_device(dev['i2c']['topo_info'], "pddf/devices/cpld", self.sysfs_obj, KEY) + sysfs_path = "/sys/kernel/pddf/devices/cpld/dev_ops" + if sysfs_path not in self.sysfs_obj[KEY]: + self.sysfs_obj[KEY].append(sysfs_path) + list = ['/sys/kernel/pddf/devices/cpld/i2c_type', + '/sys/kernel/pddf/devices/cpld/i2c_name', + '/sys/kernel/pddf/devices/cpld/error'] + self.add_list_sysfs_obj(self.sysfs_obj, KEY, list) + + def show_led_platform_device(self, key, ops): + if ops['attr'] == 'all' or ops['attr'] == 'PLATFORM': + KEY = 'platform' + if KEY not in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + path = 'pddf/devices/platform' + self.sysfs_attr('num_psus', self.data['PLATFORM']['num_psus'], path, self.sysfs_obj, KEY) + self.sysfs_attr('num_fantrays', self.data['PLATFORM']['num_fantrays'], path, self.sysfs_obj, KEY) + + def show_led_device(self, key, ops): + if self.check_led_cmds(key, ops): + KEY = 'led' + if KEY not in self.sysfs_obj: + self.sysfs_obj[KEY] = [] + path = "pddf/devices/led" + for attr in self.data[key]['i2c']['attr_list']: + self.sysfs_attr('device_name', self.data[key]['dev_info']['device_name'], path, self.sysfs_obj, KEY) + self.sysfs_attr('swpld_addr', self.data[key]['dev_info']['device_name'], path, self.sysfs_obj, KEY) + self.sysfs_attr('swpld_addr_offset', self.data[key]['dev_info']['device_name'], path, + self.sysfs_obj, KEY) + self.sysfs_device(self.data[key]['dev_attr'], path, self.sysfs_obj, KEY) + for attr_key in attr.keys(): + attr_path = "pddf/devices/led/" + attr['attr_name'] + if (attr_key != 'attr_name' and attr_key != 'swpld_addr' and attr_key != 'swpld_addr_offset'): + self.sysfs_attr(attr_key, attr[attr_key], attr_path, self.sysfs_obj, KEY) + sysfs_path = "/sys/kernel/pddf/devices/led/dev_ops" + if sysfs_path not in self.sysfs_obj[KEY]: + self.sysfs_obj[KEY].append(sysfs_path) + list = ['/sys/kernel/pddf/devices/led/cur_state/color', + '/sys/kernel/pddf/devices/led/cur_state/color_state'] + self.add_list_sysfs_obj(self.sysfs_obj, KEY, list) + + def validate_xcvr_device(self, dev, ops): + devtype_list = ['optoe1', 'optoe2'] + dev_attribs = ['xcvr_present', 'xcvr_reset', 'xcvr_intr_status', 'xcvr_lpmode'] + ret_val = "xcvr validation failed" + + if dev['i2c']['topo_info']['dev_type'] in devtype_list: + for attr in dev['i2c']['attr_list']: + if 'attr_name' in attr.keys() and 'eeprom' in attr.values(): + ret_val = "xcvr validation success" + else: + print("xcvr validation Failed") + return + + elif dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['PORT_MODULE']: + for attr in dev['i2c']['attr_list']: + if attr.get("attr_name") in dev_attribs: + ret_val = "Success" + else: + print("xcvr validation Failed") + return + print(ret_val) + + def validate_eeprom_device(self, dev, ops): + devtype_list = ['24c02'] + dev_access_mode = ['BLOCK', 'BYTE'] + dev_attribs = ['eeprom'] + ret_val = "eeprom failed" + + if dev['i2c']['topo_info']['dev_type'] in devtype_list: + if dev['i2c']['dev_attr']['access_mode'] in dev_access_mode: + for attr in dev['i2c']['attr_list']: + if attr.get("attr_name") in dev_attribs: + ret_val = "eeprom success" + print(ret_val) + + def validate_mux_device(self, dev, ops): + devtype_list = ['pca9548', 'pca954x'] + dev_channels = ["0", "1", "2", "3", "4", "5", "6", "7"] + ret_val = "mux failed" + + if dev['i2c']['topo_info']['dev_type'] in devtype_list: + for attr in dev['i2c']['channel']: + if attr.get("chn") in dev_channels: + ret_val = "Mux success" + print(ret_val) + + def validate_cpld_device(self, dev, ops): + devtype_list = ['i2c_cpld'] + ret_val = "cpld failed" + + if dev['i2c']['topo_info']['dev_type'] in devtype_list: + ret_val = "cpld success" + print(ret_val) + + def validate_sysstatus_device(self, dev, ops): + dev_attribs = ['board_info', 'cpld1_version', 'power_module_status', 'system_reset5', + 'system_reset6', 'system_reset7', 'misc1', 'cpld2_version', 'cpld3_version' + ] + ret_val = "sysstatus failed" + + if dev['dev_info']['device_type'] == "SYSSTAT": + for attr in dev['attr_list']: + if attr.get("attr_name") in dev_attribs: + ret_val = "sysstatus success" + print(ret_val) + + def validate_temp_sensor_device(self, dev, ops): + devtype_list = ['lm75'] + dev_attribs = ['temp1_max', 'temp1_max_hyst', 'temp1_input'] + ret_val = "temp sensor failed" + + if dev['dev_info']['device_type'] == "TEMP_SENSOR": + if dev['i2c']['topo_info']['dev_type'] in devtype_list: + for attr in dev['i2c']['attr_list']: + if attr.get("attr_name") in dev_attribs: + ret_val = "tempsensor success" + print(ret_val) + + def validate_fan_device(self, dev, ops): + ret_val = "fan failed" + + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['FAN']: + if dev['i2c']['dev_attr']['num_fan'] is not None: + ret_val = "fan success" + + print(ret_val) + + def validate_psu_device(self, dev, ops): + dev_attribs = ['psu_present', 'psu_model_name', 'psu_power_good', 'psu_mfr_id', 'psu_serial_num', + 'psu_fan_dir', 'psu_v_out', 'psu_i_out', 'psu_p_out', 'psu_fan1_speed_rpm' + ] + ret_val = "psu failed" + + if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['PSU']: + for attr in dev['i2c']['attr_list']: + if attr.get("attr_name") in dev_attribs: + if attr.get("attr_devaddr") is not None: + if attr.get("attr_offset") is not None: + if attr.get("attr_mask") is not None: + if attr.get("attr_len") is not None: + ret_val = "psu success" + else: + ret_val = "psu failed" + + print(ret_val) + + ################################################################################################################### + # SPYTEST + ################################################################################################################### + def verify_attr(self, key, attr, path): + node = "/sys/kernel/%s/%s" % (path, key) + try: + with open(node, 'r') as f: + status = f.read() + except IOError: + print("PDDF_VERIFY_ERR: IOError: node:%s key:%s" % (node, key)) + return + + status = status.rstrip("\n\r") + if attr[key] != status: + print("PDDF_VERIFY_ERR: node: %s switch:%s" % (node, status)) + + def verify_device(self, attr, path, ops): + for key in attr.keys(): + self.verify_attr(key, attr, path) + + def get_led_device(self, device_name): + self.create_attr('device_name', self.data[device_name]['dev_info']['device_name'], "pddf/devices/led") + self.create_attr('index', self.data[device_name]['dev_attr']['index'], "pddf/devices/led") + cmd = "echo 'verify' > /sys/kernel/pddf/devices/led/dev_ops" + self.runcmd(cmd) + + def validate_sysfs_creation(self, obj, validate_type): + dir = '/sys/kernel/pddf/devices/'+validate_type + if (os.path.exists(dir) or validate_type == 'client'): + for sysfs in obj[validate_type]: + if not os.path.exists(sysfs): + print("[SYSFS FILE] " + sysfs + ": does not exist") + else: + print("[SYSFS DIR] " + dir + ": does not exist") + + def validate_dsysfs_creation(self, obj, validate_type): + if validate_type in obj.keys(): + # There is a possibility that some components dont have any device-self.data attr + if not obj[validate_type]: + print("[SYSFS ATTR] for " + validate_type + ": empty") + else: + for sysfs in obj[validate_type]: + if not os.path.exists(sysfs): + print("[SYSFS FILE] " + sysfs + ": does not exist") + else: + print("[SYSFS DIR] " + dir + ": not configured") + + def verify_sysfs_data(self, verify_type): + if (verify_type == 'LED'): + for key in self.data.keys(): + if key != 'PLATFORM': + attr = self.data[key]['dev_info'] + if attr['device_type'] == 'LED': + self.get_led_device(key) + self.verify_attr('device_name', self.data[key]['dev_info'], "pddf/devices/led") + self.verify_attr('index', self.data[key]['dev_attr'], "pddf/devices/led") + for attr in self.data[key]['i2c']['attr_list']: + path = "pddf/devices/led/" + attr['attr_name'] + for entry in attr.keys(): + if (entry != 'attr_name' and entry != 'swpld_addr' and entry != 'swpld_addr_offset'): + self.verify_attr(entry, attr, path) + if (entry == 'swpld_addr' or entry == 'swpld_addr_offset'): + self.verify_attr(entry, attr, 'pddf/devices/led') + + def schema_validation(self, validate_type): + process_validate_type = 0 + for key in self.data.keys(): + if (key != 'PLATFORM'): + temp_obj = {} + schema_list = [] + try: + device_type = self.data[key]["dev_info"]["device_type"] + except Exception as e: + print("dev_info or device_type ERROR: " + key) + print(e) + + if validate_type == 'mismatch': + process_validate_type = 1 + device_type = "PSU" + schema_file = "/usr/local/bin/schema/FAN.schema" + schema_list.append(schema_file) + elif validate_type == 'missing': + process_validate_type = 1 + schema_file = "/usr/local/bin/schema/PLATFORM.schema" + schema_list.append(schema_file) + + elif validate_type == 'empty': + process_validate_type = 1 + if not device_type: + print("Empty device_type for " + key) + continue + elif (validate_type == 'all' or validate_type == device_type): + process_validate_type = 1 + if "bmc" in self.data[key].keys(): + schema_file = "/usr/local/bin/schema/"+device_type + "_BMC.schema" + schema_list.append(schema_file) + + if "i2c" in self.data[key].keys(): + schema_file = "/usr/local/bin/schema/"+device_type + ".schema" + schema_list.append(schema_file) + if device_type: + temp_obj[device_type] = self.data[key] + for schema_file in schema_list: + if (os.path.exists(schema_file)): + print("Validate " + schema_file + ";" + key) + json_data = json.dumps(temp_obj) + with open(schema_file, 'r') as f: + schema = json.load(f) + try: + validate(temp_obj, schema) + except Exception as e: + print("Validation ERROR: " + schema_file + ";" + key) + if validate_type == 'mismatch': + return + else: + print(e) + else: + print("ERROR Missing File: " + schema_file) + if not process_validate_type: + print("device_type: " + validate_type + " not configured") + + def modules_validation(self, validate_type): + kos = [] + supported_type = False + module_validation_status = [] + + if validate_type == "bmc": + kos = ['ipmi_devintf', 'ipmi_si', 'ipmi_msghandler'] + validate_type = 'ipmi' + else: + # generate the KOS list from pddf device JSON file + kos.extend(self.data['PLATFORM']['pddf_kos']) + + if 'custom_kos' in self.data['PLATFORM']: + kos.extend(self.data['PLATFORM']['custom_kos']) + + for mod in kos: + if validate_type in mod or validate_type == "pddf": + supported_type = True + cmd = "lsmod | grep " + mod + try: + subprocess.check_output(cmd, shell=True) + except Exception as e: + module_validation_status.append(mod) + if supported_type: + if module_validation_status: + module_validation_status.append(":ERROR not loaded") + print(str(module_validation_status)[1:-1]) + else: + print("Loaded") + else: + print(validate_type + " not configured") + + ################################################################################################################### + # PARSE DEFS + ################################################################################################################### + + def psu_parse(self, dev, ops): + parse_str = "" + ret = "" + for ifce in dev['i2c']['interface']: + ret = getattr(self, ops['cmd']+"_psu_device")(self.data[ifce['dev']], ops) + if ret is not None: + if str(ret).isdigit(): + if ret != 0: + # in case if 'create' functions + print("{}_psu_device failed".format(ops['cmd'])) + return ret + else: + pass + else: + # in case of 'show_attr' functions + parse_str += ret + return parse_str + + def fan_parse(self, dev, ops): + parse_str = "" + ret = getattr(self, ops['cmd']+"_fan_device")(dev, ops) + if ret is not None: + if str(ret).isdigit(): + if ret != 0: + # in case if 'create' functions + print("{}_fan_device failed".format(ops['cmd'])) + return ret + else: + pass + else: + # in case of 'show_attr' functions + parse_str += ret + + return parse_str + + def temp_sensor_parse(self, dev, ops): + parse_str = "" + ret = getattr(self, ops['cmd']+"_temp_sensor_device")(dev, ops) + if ret is not None: + if str(ret).isdigit(): + if ret != 0: + # in case if 'create' functions + print("{}_temp_sensor_device failed".format(ops['cmd'])) + return ret + else: + pass + else: + # in case of 'show_attr' functions + parse_str += ret + + return parse_str + + def cpld_parse(self, dev, ops): + parse_str = "" + ret = getattr(self, ops['cmd']+"_cpld_device")(dev, ops) + if ret is not None: + if str(ret).isdigit(): + if ret != 0: + # in case if 'create' functions + print("{}_cpld_device failed".format(ops['cmd'])) + return ret + else: + pass + else: + # in case of 'show_attr' functions + parse_str += ret + + return parse_str + + def sysstatus_parse(self, dev, ops): + parse_str = "" + ret = getattr(self, ops['cmd']+"_sysstatus_device")(dev, ops) + if ret is not None: + if str(ret).isdigit(): + if ret != 0: + # in case if 'create' functions + print("{}_sysstatus_device failed".format(ops['cmd'])) + return ret + else: + pass + else: + # in case of 'show_attr' functions + parse_str += ret + + return parse_str + + def gpio_parse(self, dev, ops): + parse_str = "" + ret = getattr(self, ops['cmd']+"_gpio_device")(dev, ops) + if ret is not None: + if str(ret).isdigit(): + if ret != 0: + # in case if 'create' functions + print("{}_temp_sensor_device failed".format(ops['cmd'])) + return ret + else: + pass + else: + # in case of 'show_attr' functions + parse_str += ret + + return parse_str + + def mux_parse(self, dev, ops): + parse_str = "" + ret = getattr(self, ops['cmd']+"_mux_device")(dev, ops) + if ret is not None: + if str(ret).isdigit(): + if ret != 0: + # in case if 'create' functions + print("{}_mux_device() cmd failed".format(ops['cmd'])) + return ret + else: + pass + else: + parse_str += ret + + for ch in dev['i2c']['channel']: + ret = self.dev_parse(self.data[ch['dev']], ops) + if ret is not None: + if str(ret).isdigit(): + if ret != 0: + # in case if 'create' functions + return ret + else: + pass + else: + parse_str += ret + return parse_str + + def mux_parse_reverse(self, dev, ops): + parse_str = "" + for ch in reversed(dev['i2c']['channel']): + ret = self.dev_parse(self.data[ch['dev']], ops) + if ret is not None: + if str(ret).isdigit(): + if ret != 0: + # in case if 'create' functions + return ret + else: + pass + else: + parse_str += ret + + ret = getattr(self, ops['cmd']+"_mux_device")(dev, ops) + if ret is not None: + if str(ret).isdigit(): + if ret != 0: + # in case if 'create' functions + print("{}_mux_device() cmd failed".format(ops['cmd'])) + return ret + else: + pass + else: + parse_str += ret + + return parse_str + + def eeprom_parse(self, dev, ops): + parse_str = "" + ret = getattr(self, ops['cmd']+"_eeprom_device")(dev, ops) + if ret is not None: + if str(ret).isdigit(): + if ret != 0: + # in case if 'create' functions + print("{}_eeprom_device() cmd failed".format(ops['cmd'])) + return ret + else: + pass + else: + parse_str += ret + + return parse_str + + def optic_parse(self, dev, ops): + parse_str = "" + ret = "" + for ifce in dev['i2c']['interface']: + ret = getattr(self, ops['cmd']+"_xcvr_device")(self.data[ifce['dev']], ops) + if ret is not None: + if str(ret).isdigit(): + if ret != 0: + # in case if 'create' functions + print("{}_eeprom_device() cmd failed".format(ops['cmd'])) + return ret + else: + pass + else: + parse_str += ret + return parse_str + + def cpu_parse(self, bus, ops): + parse_str = "" + for dev in bus['i2c']['CONTROLLERS']: + dev1 = self.data[dev['dev']] + for d in dev1['i2c']['DEVICES']: + ret = self.dev_parse(self.data[d['dev']], ops) + if ret is not None: + if str(ret).isdigit(): + if ret != 0: + # in case if 'create' functions + return ret + else: + pass + else: + parse_str += ret + return parse_str + + def cpu_parse_reverse(self, bus, ops): + parse_str = "" + for dev in reversed(bus['i2c']['CONTROLLERS']): + dev1 = self.data[dev['dev']] + for d in dev1['i2c']['DEVICES']: + ret = self.dev_parse(self.data[d['dev']], ops) + if ret is not None: + if str(ret).isdigit(): + if ret != 0: + # in case if 'create' functions + return ret + else: + pass + else: + parse_str += ret + return parse_str + + def dev_parse(self, dev, ops): + attr = dev['dev_info'] + if attr['device_type'] == 'CPU': + if ops['cmd'] == 'delete': + return self.cpu_parse_reverse(dev, ops) + else: + return self.cpu_parse(dev, ops) + + if attr['device_type'] == 'EEPROM': + return self.eeprom_parse(dev, ops) + + if attr['device_type'] == 'MUX': + if ops['cmd'] == 'delete': + return self.mux_parse_reverse(dev, ops) + else: + return self.mux_parse(dev, ops) + + if attr['device_type'] == 'GPIO': + return self.gpio_parse(dev, ops) + + if attr['device_type'] == 'PSU': + return self.psu_parse(dev, ops) + + if attr['device_type'] == 'FAN': + return self.fan_parse(dev, ops) + + if attr['device_type'] == 'TEMP_SENSOR': + return self.temp_sensor_parse(dev, ops) + + if attr['device_type'] == 'SFP' or attr['device_type'] == 'QSFP' or \ + attr['device_type'] == 'SFP28' or attr['device_type'] == 'QSFP28' or \ + attr['device_type'] == 'QSFP-DD': + return self.optic_parse(dev, ops) + + if attr['device_type'] == 'CPLD': + return self.cpld_parse(dev, ops) + + if attr['device_type'] == 'SYSSTAT': + return self.sysstatus_parse(dev, ops) + + def is_supported_sysled_state(self, sysled_name, sysled_state): + if sysled_name not in self.data.keys(): + return False, "[FAILED] " + sysled_name + " is not configured" + for attr in self.data[sysled_name]['i2c']['attr_list']: + if attr['attr_name'] == sysled_state: + return True, "supported" + return False, "[FAILED]: Invalid color" + + def create_attr(self, key, value, path): + cmd = "echo '%s' > /sys/kernel/%s/%s" % (value, path, key) + self.runcmd(cmd) + + def create_led_platform_device(self, key, ops): + if ops['attr'] == 'all' or ops['attr'] == 'PLATFORM': + path = 'pddf/devices/platform' + self.create_attr('num_psus', self.data['PLATFORM']['num_psus'], path) + self.create_attr('num_fantrays', self.data['PLATFORM']['num_fantrays'], path) + + def create_led_device(self, key, ops): + if ops['attr'] == 'all' or ops['attr'] == self.data[key]['dev_info']['device_name']: + path = "pddf/devices/led" + for attr in self.data[key]['i2c']['attr_list']: + self.create_attr('device_name', self.data[key]['dev_info']['device_name'], path) + self.create_device(self.data[key]['dev_attr'], path, ops) + for attr_key in attr.keys(): + if (attr_key == 'swpld_addr_offset' or attr_key == 'swpld_addr'): + self.create_attr(attr_key, attr[attr_key], path) + elif (attr_key != 'attr_name' and attr_key != 'descr' and attr_key != 'attr_devtype' and + attr_key != 'attr_devname'): + state_path = path+'/state_attr' + self.create_attr(attr_key, attr[attr_key], state_path) + cmd = "echo '" + attr['attr_name']+"' > /sys/kernel/pddf/devices/led/dev_ops" + self.runcmd(cmd) + + def led_parse(self, ops): + getattr(self, ops['cmd']+"_led_platform_device")("PLATFORM", ops) + for key in self.data.keys(): + if key != 'PLATFORM' and 'dev_info' in self.data[key]: + attr = self.data[key]['dev_info'] + if attr['device_type'] == 'LED': + getattr(self, ops['cmd']+"_led_device")(key, ops) + + def get_device_list(self, list, type): + for key in self.data.keys(): + if key != 'PLATFORM' and 'dev_info' in self.data[key]: + attr = self.data[key]['dev_info'] + if attr['device_type'] == type: + list.append(self.data[key]) + + def create_pddf_devices(self): + self.led_parse({"cmd": "create", "target": "all", "attr": "all"}) + create_ret = 0 + create_ret = self.dev_parse(self.data['SYSTEM'], {"cmd": "create", "target": "all", "attr": "all"}) + if create_ret != 0: + return create_ret + if 'SYSSTATUS' in self.data: + create_ret = self.dev_parse(self.data['SYSSTATUS'], {"cmd": "create", "target": "all", "attr": "all"}) + if create_ret != 0: + return create_ret + + def delete_pddf_devices(self): + self.dev_parse(self.data['SYSTEM'], {"cmd": "delete", "target": "all", "attr": "all"}) + if 'SYSSTATUS' in self.data: + self.dev_parse(self.data['SYSSTATUS'], {"cmd": "delete", "target": "all", "attr": "all"}) + + def populate_pddf_sysfsobj(self): + self.dev_parse(self.data['SYSTEM'], {"cmd": "show", "target": "all", "attr": "all"}) + if 'SYSSTATUS' in self.data: + self.dev_parse(self.data['SYSSTATUS'], {"cmd": "show", "target": "all", "attr": "all"}) + self.led_parse({"cmd": "show", "target": "all", "attr": "all"}) + self.show_client_device() + + def cli_dump_dsysfs(self, component): + self.dev_parse(self.data['SYSTEM'], {"cmd": "show_attr", "target": "all", "attr": "all"}) + if 'SYSSTATUS' in self.data: + self.dev_parse(self.data['SYSSTATUS'], {"cmd": "show_attr", "target": "all", "attr": "all"}) + if component in self.data_sysfs_obj: + return self.data_sysfs_obj[component] + else: + return None + + def validate_pddf_devices(self, *args): + self.populate_pddf_sysfsobj() + v_ops = {'cmd': 'validate', 'target': 'all', 'attr': 'all'} + self.dev_parse(self.data['SYSTEM'], v_ops) + + ################################################################################################################### + # BMC APIs + ################################################################################################################### + def populate_bmc_cache_db(self, bmc_attr): + bmc_cmd = str(bmc_attr['bmc_cmd']).strip() + + o_list = subprocess.check_output(bmc_cmd, shell=True).strip().split('\n') + bmc_cache[bmc_cmd] = {} + bmc_cache[bmc_cmd]['time'] = time.time() + for entry in o_list: + name = entry.split()[0] + bmc_cache[bmc_cmd][name] = entry + + def non_raw_ipmi_get_request(self, bmc_attr): + bmc_db_update_time = 1 + value = 'N/A' + bmc_cmd = str(bmc_attr['bmc_cmd']).strip() + field_name = str(bmc_attr['field_name']).strip() + field_pos = int(bmc_attr['field_pos'])-1 + + if bmc_cmd not in bmc_cache: + self.populate_bmc_cache_db(bmc_attr) + else: + now = time.time() + if (int(now - bmc_cache[bmc_cmd]['time']) > bmc_db_update_time): + self.populate_bmc_cache_db(bmc_attr) + + try: + data = bmc_cache[bmc_cmd][field_name] + value = data.split()[field_pos] + except Exception as e: + pass + + if 'mult' in bmc_attr.keys() and not value.isalpha(): + if value.isalpha(): + value = 0.0 + value = float(value) * float(bmc_attr['mult']) + + return str(value) + + def raw_ipmi_get_request(self, bmc_attr): + value = 'N/A' + cmd = bmc_attr['bmc_cmd'] + " 2>/dev/null" + if bmc_attr['type'] == 'raw': + try: + value = subprocess.check_output(cmd, shell=True).strip() + except Exception as e: + pass + + if value != 'N/A': + value = str(int(value, 16)) + return value + + if bmc_attr['type'] == 'mask': + mask = int(bmc_attr['mask'].encode('utf-8'), 16) + try: + value = subprocess.check_output(cmd, shell=True).strip() + except Exception as e: + pass + + if value != 'N/A': + value = str(int(value, 16) & mask) + + return value + + if bmc_attr['type'] == 'ascii': + try: + value = subprocess.check_output(cmd, shell=True) + except Exception as e: + pass + + if value != 'N/A': + tmp = ''.join(chr(int(i, 16)) for i in value.split()) + tmp = "".join(i for i in str(tmp) if unicodedata.category(i)[0] != "C") + value = str(tmp) + + return (value) + + return value + + def bmc_get_cmd(self, bmc_attr): + if int(bmc_attr['raw']) == 1: + value = self.raw_ipmi_get_request(bmc_attr) + else: + value = self.non_raw_ipmi_get_request(bmc_attr) + return (value) + + def non_raw_ipmi_set_request(self, bmc_attr, val): + value = 'N/A' + # TODO: Implement it + return value + + def raw_ipmi_set_request(self, bmc_attr, val): + value = 'N/A' + # TODO: Implement this + return value + + def bmc_set_cmd(self, bmc_attr, val): + if int(bmc_attr['raw']) == 1: + value = self.raw_ipmi_set_request(bmc_attr, val) + else: + value = self.non_raw_ipmi_set_request(bmc_attr, val) + return (value) + + # bmc-based attr: return attr obj + # non-bmc-based attr: return empty obj + def check_bmc_based_attr(self, device_name, attr_name): + if device_name in self.data.keys(): + if "bmc" in self.data[device_name].keys() and 'ipmitool' in self.data[device_name]['bmc'].keys(): + attr_list = self.data[device_name]['bmc']['ipmitool']['attr_list'] + for attr in attr_list: + if attr['attr_name'].strip() == attr_name.strip(): + return attr + # Required attr_name is not supported in BMC object + return {} + return None + + def get_attr_name_output(self, device_name, attr_name): + bmc_attr = self.check_bmc_based_attr(device_name, attr_name) + output = {"mode": "", "status": ""} + + if bmc_attr is not None: + if bmc_attr == {}: + return {} + output['mode'] = "bmc" + output['status'] = self.bmc_get_cmd(bmc_attr) + else: + output['mode'] = "i2c" + node = self.get_path(device_name, attr_name) + if node is None: + return {} + try: + with open(node, 'r') as f: + output['status'] = f.read() + except IOError: + return {} + return output + + def set_attr_name_output(self, device_name, attr_name, val): + bmc_attr = self.check_bmc_based_attr(device_name, attr_name) + output = {"mode": "", "status": ""} + + if bmc_attr is not None: + if bmc_attr == {}: + return {} + output['mode'] = "bmc" + output['status'] = False # No set operation allowed for BMC attributes as they are handled by BMC itself + else: + output['mode'] = "i2c" + node = self.get_path(device_name, attr_name) + if node is None: + return {} + try: + with open(node, 'w') as f: + f.write(str(val)) + except IOError: + return {} + + output['status'] = True + + return output diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_ref/__init__.py b/platform/pddf/platform-api-pddf-base/sonic_platform_ref/__init__.py new file mode 100644 index 000000000000..d9a604cf816e --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/sonic_platform_ref/__init__.py @@ -0,0 +1,7 @@ +# All the derived classes for PDDF +__all__ = ["platform", "chassis", "sfp", "psu", "thermal"] + +# Commenting the below code as this just for the reference for the ODMs. +# It can be uncommented when this reference code is used + +#from sonic_platform import * diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_ref/chassis.py b/platform/pddf/platform-api-pddf-base/sonic_platform_ref/chassis.py new file mode 100644 index 000000000000..72f1858a776c --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/sonic_platform_ref/chassis.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python + +############################################################################# +# PDDF +# Module contains an implementation of SONiC Chassis API +# +############################################################################# + +try: + from sonic_platform_pddf_base.pddf_chassis import PddfChassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +class Chassis(PddfChassis): + """ + PDDF Platform-specific Chassis class + """ + + def __init__(self, pddf_data=None, pddf_plugin_data=None): + PddfChassis.__init__(self, pddf_data, pddf_plugin_data) + + # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_ref/eeprom.py b/platform/pddf/platform-api-pddf-base/sonic_platform_ref/eeprom.py new file mode 100644 index 000000000000..c25d711354f5 --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/sonic_platform_ref/eeprom.py @@ -0,0 +1,12 @@ +try: + from sonic_platform_pddf_base.pddf_eeprom import PddfEeprom +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Eeprom(PddfEeprom): + + def __init__(self, pddf_data=None, pddf_plugin_data=None): + PddfEeprom.__init__(self, pddf_data, pddf_plugin_data) + + # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_ref/fan.py b/platform/pddf/platform-api-pddf-base/sonic_platform_ref/fan.py new file mode 100644 index 000000000000..027a2f4a6148 --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/sonic_platform_ref/fan.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python + + +try: + from sonic_platform_pddf_base.pddf_fan import PddfFan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Fan(PddfFan): + """PDDF Platform-Specific Fan class""" + + def __init__(self, tray_idx, fan_idx=0, pddf_data=None, pddf_plugin_data=None, is_psu_fan=False, psu_index=0): + # idx is 0-based + PddfFan.__init__(self, tray_idx, fan_idx, pddf_data, pddf_plugin_data, is_psu_fan, psu_index) + + # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_ref/platform.py b/platform/pddf/platform-api-pddf-base/sonic_platform_ref/platform.py new file mode 100644 index 000000000000..406b1179ae1b --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/sonic_platform_ref/platform.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python + +############################################################################# +# PDDF +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + + +try: + from sonic_platform_pddf_base.pddf_platform import PddfPlatform +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PddfPlatform): + """ + PDDF Platform-Specific Platform Class + """ + + def __init__(self): + PddfPlatform.__init__(self) + + # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_ref/psu.py b/platform/pddf/platform-api-pddf-base/sonic_platform_ref/psu.py new file mode 100644 index 000000000000..edd747e9963b --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/sonic_platform_ref/psu.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python + + +try: + from sonic_platform_pddf_base.pddf_psu import PddfPsu +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + + +class Psu(PddfPsu): + """PDDF Platform-Specific PSU class""" + + def __init__(self, index, pddf_data=None, pddf_plugin_data=None): + PddfPsu.__init__(self, index, pddf_data, pddf_plugin_data) + + # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_ref/sfp.py b/platform/pddf/platform-api-pddf-base/sonic_platform_ref/sfp.py new file mode 100644 index 000000000000..9588db53283c --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/sonic_platform_ref/sfp.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python + +try: + from sonic_platform_pddf_base.pddf_sfp import PddfSfp +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + + +class Sfp(PddfSfp): + """ + PDDF Platform-Specific Sfp class + """ + + def __init__(self, index, pddf_data=None, pddf_plugin_data=None): + PddfSfp.__init__(self, index, pddf_data, pddf_plugin_data) + + # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_ref/thermal.py b/platform/pddf/platform-api-pddf-base/sonic_platform_ref/thermal.py new file mode 100644 index 000000000000..5b829fc26caa --- /dev/null +++ b/platform/pddf/platform-api-pddf-base/sonic_platform_ref/thermal.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python + + +try: + from sonic_platform_pddf_base.pddf_thermal import PddfThermal +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + + +class Thermal(PddfThermal): + """PDDF Platform-Specific Thermal class""" + + def __init__(self, index, pddf_data=None, pddf_plugin_data=None): + PddfThermal.__init__(self, index, pddf_data, pddf_plugin_data) + + # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/pddf/platform-modules-pddf.dep b/platform/pddf/platform-modules-pddf.dep new file mode 100644 index 000000000000..19a4bb344759 --- /dev/null +++ b/platform/pddf/platform-modules-pddf.dep @@ -0,0 +1,10 @@ + +MPATH := $($(PDDF_PLATFORM_MODULE)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/pddf/platform-modules-pddf.mk platform/pddf/platform-modules-pddf.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(MPATH)) + +$(PDDF_PLATFORM_MODULE)_CACHE_MODE := GIT_CONTENT_SHA +$(PDDF_PLATFORM_MODULE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(PDDF_PLATFORM_MODULE)_DEP_FILES := $(DEP_FILES) + diff --git a/platform/pddf/platform-modules-pddf.mk b/platform/pddf/platform-modules-pddf.mk new file mode 100644 index 000000000000..5947c1806565 --- /dev/null +++ b/platform/pddf/platform-modules-pddf.mk @@ -0,0 +1,12 @@ +# PDDF Generic Platform modules +#################################################### +PDDF_PLATFORM_MODULE_VERSION = 1.1 + +export PDDF_PLATFORM_MODULE_VERSION + +PDDF_PLATFORM_MODULE = sonic-platform-pddf_$(PDDF_PLATFORM_MODULE_VERSION)_amd64.deb +$(PDDF_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PDDF_PATH)/i2c +$(PDDF_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +SONIC_DPKG_DEBS += $(PDDF_PLATFORM_MODULE) + +SONIC_STRETCH_DEBS += $(PDDF_PLATFORM_MODULE) diff --git a/platform/pddf/rules.dep b/platform/pddf/rules.dep new file mode 100644 index 000000000000..de40f6e88c2f --- /dev/null +++ b/platform/pddf/rules.dep @@ -0,0 +1,3 @@ +#DPKG FRK +include $(PLATFORM_PDDF_PATH)/platform-modules-pddf.dep +include $(PLATFORM_PDDF_PATH)/platform-api-pddf-base.dep diff --git a/platform/pddf/rules.mk b/platform/pddf/rules.mk new file mode 100644 index 000000000000..6c2fdfb89b58 --- /dev/null +++ b/platform/pddf/rules.mk @@ -0,0 +1,3 @@ +include $(PLATFORM_PDDF_PATH)/platform-modules-pddf.mk +include $(PLATFORM_PDDF_PATH)/platform-api-pddf-base.mk + diff --git a/platform/template/docker-gbsyncd-base.mk b/platform/template/docker-gbsyncd-base.mk new file mode 100644 index 000000000000..aa4f574141b2 --- /dev/null +++ b/platform/template/docker-gbsyncd-base.mk @@ -0,0 +1,30 @@ +# docker image for gbsyncd + + +DOCKER_GBSYNCD_BASE_STEM = docker-gbsyncd-$(DOCKER_GBSYNCD_PLATFORM_CODE) +DOCKER_GBSYNCD_BASE = $(DOCKER_GBSYNCD_BASE_STEM).gz +DOCKER_GBSYNCD_BASE_DBG = $(DOCKER_GBSYNCD_BASE_STEM)-$(DBG_IMAGE_MARK).gz + +$(DOCKER_GBSYNCD_BASE)_PATH = $(PLATFORM_PATH)/docker-gbsyncd-$(DOCKER_GBSYNCD_PLATFORM_CODE) + +$(DOCKER_GBSYNCD_BASE)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) + +$(DOCKER_GBSYNCD_BASE)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) + +$(DOCKER_GBSYNCD_BASE)_DBG_DEPENDS += $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) + +$(DOCKER_GBSYNCD_BASE)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) + +SONIC_DOCKER_IMAGES += $(DOCKER_GBSYNCD_BASE) +SONIC_BUSTER_DOCKERS += $(DOCKER_GBSYNCD_BASE) +SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_GBSYNCD_BASE) + +SONIC_DOCKER_DBG_IMAGES += $(DOCKER_GBSYNCD_BASE_DBG) +SONIC_BUSTER_DBG_DOCKERS += $(DOCKER_GBSYNCD_BASE_DBG) +SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_GBSYNCD_BASE_DBG) + +$(DOCKER_GBSYNCD_BASE)_CONTAINER_NAME = gbsyncd +$(DOCKER_GBSYNCD_BASE)_RUN_OPT += --net=host --privileged -t +$(DOCKER_GBSYNCD_BASE)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf +$(DOCKER_GBSYNCD_BASE)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro + diff --git a/platform/template/docker-syncd-base.mk b/platform/template/docker-syncd-base.mk index d0407beee8a0..d95d7a141920 100644 --- a/platform/template/docker-syncd-base.mk +++ b/platform/template/docker-syncd-base.mk @@ -9,25 +9,30 @@ $(DOCKER_SYNCD_BASE)_PATH = $(PLATFORM_PATH)/docker-syncd-$(DOCKER_SYNCD_PLATFOR $(DOCKER_SYNCD_BASE)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) +ifeq ($(BLDENV),stretch) $(DOCKER_SYNCD_BASE)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) $(DOCKER_SYNCD_BASE)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) +else +$(DOCKER_SYNCD_BASE)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) + +$(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) + +$(DOCKER_SYNCD_BASE)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) +endif SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_BASE) -SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_BASE) ifneq ($(ENABLE_SYNCD_RPC),y) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_BASE) endif SONIC_DOCKER_DBG_IMAGES += $(DOCKER_SYNCD_BASE_DBG) -SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_SYNCD_BASE_DBG) ifneq ($(ENABLE_SYNCD_RPC),y) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_SYNCD_BASE_DBG) endif - $(DOCKER_SYNCD_BASE)_CONTAINER_NAME = syncd $(DOCKER_SYNCD_BASE)_RUN_OPT += --privileged -t $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf diff --git a/platform/vs/README.vsdocker.md b/platform/vs/README.vsdocker.md index 42e1cafc8469..694631f095db 100644 --- a/platform/vs/README.vsdocker.md +++ b/platform/vs/README.vsdocker.md @@ -1,42 +1,12 @@ HOWTO Use Virtual Switch (Docker) -1. Create a docker with 32 front panel port +1. Create a docker with two front panel ports ``` $ docker run -id --name sw debian bash -$ sudo ./create_vnet.sh sw +$ sudo ./create_vnet.sh -n 2 sw $ ip netns list -sw-srv31 (id: 37) -sw-srv30 (id: 35) -sw-srv29 (id: 34) -sw-srv28 (id: 33) -sw-srv27 (id: 32) -sw-srv26 (id: 31) -sw-srv25 (id: 30) -sw-srv24 (id: 29) -sw-srv23 (id: 28) -sw-srv22 (id: 27) -sw-srv21 (id: 26) -sw-srv20 (id: 25) -sw-srv19 (id: 24) -sw-srv18 (id: 23) -sw-srv17 (id: 22) -sw-srv16 (id: 21) -sw-srv15 (id: 20) -sw-srv14 (id: 19) -sw-srv13 (id: 18) -sw-srv12 (id: 17) -sw-srv11 (id: 16) -sw-srv10 (id: 15) -sw-srv9 (id: 14) -sw-srv8 (id: 13) -sw-srv7 (id: 12) -sw-srv6 (id: 11) -sw-srv5 (id: 10) -sw-srv4 (id: 9) -sw-srv3 (id: 8) -sw-srv2 (id: 7) sw-srv1 (id: 6) sw-srv0 (id: 5) ``` @@ -51,8 +21,10 @@ $ docker run --privileged --network container:sw --name vs -d docker-sonic-vs ``` $ docker exec -it vs bash -root@2e9b5c2dc2a2:/# ifconfig Ethernet0 10.0.0.0/31 up -root@2e9b5c2dc2a2:/# ifconfig Ethernet4 10.0.0.2/31 up +root@2e9b5c2dc2a2:/# config interface ip add Ethernet0 10.0.0.0/31 +root@2e9b5c2dc2a2:/# config interface ip add Ethernet4 10.0.0.2/31 +root@2e9b5c2dc2a2:/# config interface startup Ethernet0 +root@2e9b5c2dc2a2:/# config interface startup Ethernet4 ``` 4. Setup IP in the server network namespace diff --git a/platform/vs/create_vnet.sh b/platform/vs/create_vnet.sh index 4746e16cbbaf..2217bbbd0220 100755 --- a/platform/vs/create_vnet.sh +++ b/platform/vs/create_vnet.sh @@ -1,4 +1,24 @@ -#!/bin/bash +#!/bin/bash -e + +usage() { + echo "Usage: $0 [-n ] swname" 1>&2 + exit 1 +} + +SERVERS=2 + +while getopts ":n:" opt; do + case $opt in + n) + SERVERS=$((OPTARG)) + ;; + *) + usage + ;; + esac +done + +shift $((OPTIND-1)) SWNAME=$1 @@ -6,9 +26,8 @@ pid=$(docker inspect --format '{{.State.Pid}}' $SWNAME) echo Seting up servers -SERVERS=31 -for srv in `seq 0 $SERVERS`; do +for srv in `seq 0 $((SERVERS-1))`; do SRV="$SWNAME-srv$srv" @@ -24,9 +43,10 @@ for srv in `seq 0 $SERVERS`; do IF="eth$((srv+1))" - ip link add ${SRV}eth0 type veth peer name $IF + ip link add ${SRV}eth0 type veth peer name $SWNAME-$IF ip link set ${SRV}eth0 netns $SRV - ip link set $IF netns ${pid} + ip link set $SWNAME-$IF netns ${pid} + nsenter -t $pid -n ip link set dev $SWNAME-$IF name $IF echo "Bring ${SRV}eth0 up" $NSS ip link set dev ${SRV}eth0 name eth0 diff --git a/platform/vs/docker-gbsyncd-vs.dep b/platform/vs/docker-gbsyncd-vs.dep new file mode 100644 index 000000000000..a3db18642abf --- /dev/null +++ b/platform/vs/docker-gbsyncd-vs.dep @@ -0,0 +1,11 @@ +#DPKG FRK +DPATH := $($(DOCKER_GBSYNCD_BASE)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/vs/docker-gbsyncd-vs.mk platform/vs/docker-gbsyncd-vs.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_GBSYNCD_BASE)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_GBSYNCD_BASE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_GBSYNCD_BASE)_DEP_FILES := $(DEP_FILES) + +$(eval $(call add_dbg_docker,$(DOCKER_GBSYNCD_BASE),$(DOCKER_GBSYNCD_BASE_DBG))) diff --git a/platform/vs/docker-gbsyncd-vs.mk b/platform/vs/docker-gbsyncd-vs.mk new file mode 100644 index 000000000000..2013132d6281 --- /dev/null +++ b/platform/vs/docker-gbsyncd-vs.mk @@ -0,0 +1,14 @@ +# docker image for vs gbsyncd + +DOCKER_GBSYNCD_PLATFORM_CODE = vs +include $(PLATFORM_PATH)/../template/docker-gbsyncd-base.mk + +$(DOCKER_GBSYNCD_BASE)_DEPENDS += $(SYNCD_VS) + +$(DOCKER_GBSYNCD_BASE)_DBG_DEPENDS += $(SYNCD_VS_DBG) \ + $(LIBSWSSCOMMON_DBG) \ + $(LIBSAIMETADATA_DBG) \ + $(LIBSAIREDIS_DBG) \ + $(LIBSAIVS_DBG) + +$(DOCKER_GBSYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot diff --git a/platform/vs/docker-gbsyncd-vs/Dockerfile.j2 b/platform/vs/docker-gbsyncd-vs/Dockerfile.j2 new file mode 100644 index 000000000000..ae7e1c99b7c0 --- /dev/null +++ b/platform/vs/docker-gbsyncd-vs/Dockerfile.j2 @@ -0,0 +1,34 @@ +FROM docker-config-engine-buster + +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 + +RUN apt-get install -f -y iproute2 libcap2-bin + +COPY \ +{% for deb in docker_gbsyncd_vs_debs.split(' ') -%} +debs/{{ deb }}{{' '}} +{%- endfor -%} +debs/ + +RUN dpkg -i \ +{% for deb in docker_gbsyncd_vs_debs.split(' ') -%} +debs/{{ deb }}{{' '}} +{%- endfor %} + +COPY ["start.sh", "/usr/bin/"] + +COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor/"] + +## Clean up +RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y +RUN rm -rf /debs + +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/vs/docker-gbsyncd-vs/critical_processes b/platform/vs/docker-gbsyncd-vs/critical_processes new file mode 100644 index 000000000000..bdd6903c5690 --- /dev/null +++ b/platform/vs/docker-gbsyncd-vs/critical_processes @@ -0,0 +1 @@ +program:syncd diff --git a/platform/vs/docker-gbsyncd-vs/start.sh b/platform/vs/docker-gbsyncd-vs/start.sh new file mode 100755 index 000000000000..e59a2322bbf8 --- /dev/null +++ b/platform/vs/docker-gbsyncd-vs/start.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +HWSKU_DIR=/usr/share/sonic/hwsku + +mkdir -p /etc/sai.d/ + +# Create/Copy the pai.profile to /etc/sai.d/pai.profile +if [ -f $HWSKU_DIR/pai.profile.j2 ]; then + sonic-cfggen -d -t $HWSKU_DIR/pai.profile.j2 > /etc/sai.d/pai.profile +else + if [ -f $HWSKU_DIR/pai.profile ]; then + cp $HWSKU_DIR/pai.profile /etc/sai.d/pai.profile + fi +fi + +# Create/Copy the gearbox configs to /etc/sai.d +if [[ x"$sonic_asic_platform" == x"broadcom" ]]; then + if [ -d $HWSKU_DIR/gearbox ]; then + cp $HWSKU_DIR/gearbox/*.bcm /etc/sai.d/. + fi +fi diff --git a/platform/vs/docker-gbsyncd-vs/supervisord.conf b/platform/vs/docker-gbsyncd-vs/supervisord.conf new file mode 100644 index 000000000000..52267c8fa58f --- /dev/null +++ b/platform/vs/docker-gbsyncd-vs/supervisord.conf @@ -0,0 +1,48 @@ +[supervisord] +logfile_maxbytes=1MB +logfile_backups=2 +nodaemon=true + +[eventlistener:dependent-startup] +command=python3 -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE + +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name gbsyncd +events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING +autostart=true +autorestart=unexpected + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 +autostart=false +autorestart=unexpected +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true + +[program:start] +command=/usr/bin/start.sh +priority=2 +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running + +[program:syncd] +command=/usr/bin/gbsyncd_start.sh +priority=3 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited diff --git a/platform/vs/docker-ptf.dep b/platform/vs/docker-ptf.dep new file mode 100644 index 000000000000..8cd9f7b7a279 --- /dev/null +++ b/platform/vs/docker-ptf.dep @@ -0,0 +1,10 @@ + +DPATH := $($(DOCKER_PTF)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/vs/docker-ptf.mk platform/vs/docker-ptf.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_PTF)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_PTF)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_PTF)_DEP_FILES := $(DEP_FILES) + diff --git a/platform/vs/docker-ptf.mk b/platform/vs/docker-ptf.mk new file mode 100644 index 000000000000..4fde844fe24b --- /dev/null +++ b/platform/vs/docker-ptf.mk @@ -0,0 +1,7 @@ +# docker image for docker-ptf + +DOCKER_PTF = docker-ptf.gz +$(DOCKER_PTF)_PATH = $(DOCKERS_PATH)/docker-ptf +$(DOCKER_PTF)_DEPENDS += $(LIBTHRIFT) $(PYTHON_THRIFT) $(PTF) $(PYTHON_SAITHRIFT) +SONIC_DOCKER_IMAGES += $(DOCKER_PTF) +SONIC_STRETCH_DOCKERS += $(DOCKER_PTF) diff --git a/platform/vs/docker-sonic-vs.mk b/platform/vs/docker-sonic-vs.mk index 718534231689..c48c8f12c704 100644 --- a/platform/vs/docker-sonic-vs.mk +++ b/platform/vs/docker-sonic-vs.mk @@ -4,14 +4,27 @@ DOCKER_SONIC_VS = docker-sonic-vs.gz $(DOCKER_SONIC_VS)_PATH = $(PLATFORM_PATH)/docker-sonic-vs $(DOCKER_SONIC_VS)_DEPENDS += $(SWSS) \ $(SYNCD_VS) \ - $(REDIS_TOOLS) \ - $(REDIS_SERVER) \ $(PYTHON_SWSSCOMMON) \ - $(LIBTEAMDCT) \ + $(PYTHON3_SWSSCOMMON) \ + $(LIBTEAMDCTL) \ $(LIBTEAM_UTILS) \ - $(SONIC_DEVICE_DATA) + $(SONIC_DEVICE_DATA) \ + $(LIBYANG) \ + $(LIBYANG_CPP) \ + $(LIBYANG_PY2) \ + $(LIBYANG_PY3) \ + $(SONIC_UTILITIES_DATA) \ + $(SONIC_HOST_SERVICES_DATA) -$(DOCKER_SONIC_VS)_PYTHON_DEBS += $(SONIC_UTILS) +# swsssdk is a dependency of sonic-py-common +# TODO: sonic-py-common should depend on swsscommon instead +$(DOCKER_SONIC_VS)_PYTHON_WHEELS += $(SWSSSDK_PY3) \ + $(SONIC_PY_COMMON_PY3) \ + $(SONIC_PLATFORM_COMMON_PY3) \ + $(SONIC_YANG_MODELS_PY3) \ + $(SONIC_YANG_MGMT_PY3) \ + $(SONIC_UTILITIES_PY3) \ + $(SONIC_HOST_SERVICES_PY3) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SONIC_VS)_DEPENDS += $(SWSS_DBG) \ @@ -31,10 +44,12 @@ endif $(DOCKER_SONIC_VS)_FILES += $(CONFIGDB_LOAD_SCRIPT) \ $(ARP_UPDATE_SCRIPT) \ + $(ARP_UPDATE_VARS_TEMPLATE) \ $(BUFFERS_CONFIG_TEMPLATE) \ $(QOS_CONFIG_TEMPLATE) \ - $(SONIC_VERSION) + $(SONIC_VERSION) \ + $(UPDATE_CHASSISDB_CONFIG_SCRIPT) \ + $(COPP_CONFIG_TEMPLATE) -$(DOCKER_SONIC_VS)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) +$(DOCKER_SONIC_VS)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) SONIC_DOCKER_IMAGES += $(DOCKER_SONIC_VS) -SONIC_STRETCH_DOCKERS += $(DOCKER_SONIC_VS) diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index 7cc6f98921ff..4313d84a237d 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -1,4 +1,4 @@ -FROM docker-config-engine-stretch +FROM docker-config-engine-buster ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf @@ -22,28 +22,16 @@ RUN apt-get install -y net-tools \ python-ply \ libqt5core5a \ libqt5network5 \ - libboost-program-options1.62.0 \ - libboost-system1.62.0 \ - libboost-thread1.62.0 \ + libboost-program-options1.71.0 \ + libboost-system1.71.0 \ + libboost-thread1.71.0 \ libgmp10 \ libjudydebian1 \ - libdaemon0 \ - libjansson4 \ - libatomic1 \ - libjemalloc1 \ - liblua5.1-0 \ - lua-bitop \ - lua-cjson \ openssh-client \ openssh-server \ libc-ares2 \ - iproute \ - libpython2.7 \ + iproute2 \ grub2-common \ - python-click-default-group \ - python-click \ - python-natsort \ - python-tabulate \ bash-completion \ libelf1 \ libmnl0 \ @@ -51,39 +39,110 @@ RUN apt-get install -y net-tools \ apt-utils \ psmisc \ tcpdump \ - python-scapy - -RUN pip install setuptools -RUN pip install py2_ipaddress -RUN pip install six -RUN pip install pyroute2==0.5.3 netifaces==0.10.7 -RUN pip install monotonic==1.5 + python-scapy \ + conntrack \ + iptables \ + jq \ + libzmq5 \ + # For installing Python m2crypto package + # (these can be uninstalled after installation) + build-essential \ + python-dev \ + python-pip \ + python3-dev \ + libssl-dev \ + swig \ + # For using Python m2crypto package + openssl \ + # For installing dependent Python packages of sonic-host-services + # (these can be uninstalled after installation) + libcairo2-dev \ + libdbus-1-dev \ + libgirepository1.0-dev \ + libsystemd-dev \ + pkg-config \ + # For installing dependent Python packages of sonic-host-services + # these packages are needed at runtime + gir1.2-glib-2.0 \ + libdbus-1-3 \ + libgirepository-1.0-1 \ + libsystemd0 + +# Install redis-server +{% if CONFIGURED_ARCH == "armhf" %} +RUN curl -k -o redis-tools_6.0.6-1~bpo10+1_armhf.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-tools_6.0.6-1_bpo10+1_armhf.deb?sv=2015-04-05&sr=b&sig=67vHAMxsl%2BS3X1KsqhdYhakJkGdg5FKSPgU8kUiw4as%3D&se=2030-10-24T04%3A22%3A40Z&sp=r" +RUN curl -k -o redis-server_6.0.6-1~bpo10+1_armhf.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-server_6.0.6-1_bpo10+1_armhf.deb?sv=2015-04-05&sr=b&sig=xTdayvm0RBguxi9suyv855jKRjU%2FmKQ8nHuct4WSX%2FA%3D&se=2030-10-24T04%3A22%3A05Z&sp=r" +RUN dpkg -i redis-tools_6.0.6-1~bpo10+1_armhf.deb redis-server_6.0.6-1~bpo10+1_armhf.deb || apt-get install -f +RUN rm redis-tools_6.0.6-1~bpo10+1_armhf.deb redis-server_6.0.6-1~bpo10+1_armhf.deb +{% elif CONFIGURED_ARCH == "arm64" %} +RUN curl -o redis-tools_6.0.6-1~bpo10+1_arm64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-tools_6.0.6-1_bpo10+1_arm64.deb?sv=2015-04-05&sr=b&sig=GbkJV2wWln3hoz27zKi5erdk3NDKrAFrQriA97bcRCY%3D&se=2030-10-24T04%3A22%3A21Z&sp=r" +RUN curl -o redis-server_6.0.6-1~bpo10+1_arm64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-server_6.0.6-1_bpo10+1_arm64.deb?sv=2015-04-05&sr=b&sig=622w2KzIKIjAaaA0Bz12MzU%2BUBzY2AiXFIFfuKNoKSk%3D&se=2030-10-24T04%3A21%3A44Z&sp=r" +RUN dpkg -i redis-tools_6.0.6-1~bpo10+1_arm64.deb redis-server_6.0.6-1~bpo10+1_arm64.deb || apt-get install -f +RUN rm redis-tools_6.0.6-1~bpo10+1_arm64.deb redis-server_6.0.6-1~bpo10+1_arm64.deb +{% else %} +RUN curl -o redis-tools_6.0.6-1~bpo10+1_amd64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-tools_6.0.6-1~bpo10+1_amd64.deb?sv=2015-04-05&sr=b&sig=73zbmjkf3pi%2Bn0R8Hy7CWT2EUvOAyzM5aLYJWCLySGM%3D&se=2030-09-06T19%3A44%3A59Z&sp=r" +RUN curl -o redis-server_6.0.6-1~bpo10+1_amd64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-server_6.0.6-1~bpo10+1_amd64.deb?sv=2015-04-05&sr=b&sig=2Ketg7BmkZEaTxR%2FgvAFVmhjn7ywdmkc7l2T2rsL57o%3D&se=2030-09-06T19%3A45%3A20Z&sp=r" +RUN dpkg -i redis-tools_6.0.6-1~bpo10+1_amd64.deb redis-server_6.0.6-1~bpo10+1_amd64.deb || apt-get install -f +RUN rm redis-tools_6.0.6-1~bpo10+1_amd64.deb redis-server_6.0.6-1~bpo10+1_amd64.deb +{% endif %} + +RUN pip2 install --upgrade 'pip<21' +RUN apt-get purge -y python-pip +RUN pip2 install setuptools==40.8.0 +RUN pip2 install wheel==0.33.6 +RUN pip2 install py2_ipaddress +RUN pip2 install six +RUN pip2 install pyroute2==0.5.3 netifaces==0.10.7 +RUN pip2 install monotonic==1.5 +RUN pip2 install urllib3 +RUN pip2 install requests +RUN pip2 install crontab + +# For sonic-config-engine Python 3 package +# Install pyangbind here, outside sonic-config-engine dependencies, as pyangbind causes enum34 to be installed. +# Then immediately uninstall enum34, as enum34 should not be installed for Python >= 3.4, as it causes a +# conflict with the new 'enum' module in the standard library +# https://github.com/robshakir/pyangbind/issues/232 +RUN pip3 install pyangbind==0.8.1 +RUN pip3 uninstall -y enum34 + +# Dependencies of restore_neighbors.py +RUN pip3 install \ + scapy==2.4.4 \ + pyroute2==0.5.14 \ + netifaces==0.10.9 {% if docker_sonic_vs_debs.strip() -%} # Copy locally-built Debian package dependencies -{%- for deb in docker_sonic_vs_debs.split(' ') %} -COPY debs/{{ deb }} /debs/ -{%- endfor %} +COPY {%- for deb in docker_sonic_vs_debs.split(' ') %} debs/{{ deb }}{%- endfor %} /debs/ # Install locally-built Debian packages and implicitly install their dependencies -{%- for deb in docker_sonic_vs_debs.split(' ') %} -RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; }; dpkg_apt /debs/{{ deb }} -{%- endfor %} +RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; }; {%- for deb in docker_sonic_vs_debs.split(' ') %} dpkg_apt /debs/{{ deb }};{%- endfor %} {%- endif %} {% if docker_sonic_vs_pydebs.strip() -%} # Copy locally-built Debian package dependencies -{%- for deb in docker_sonic_vs_pydebs.split(' ') %} -COPY python-debs/{{ deb }} /debs/ -{%- endfor %} +COPY {%- for deb in docker_sonic_vs_pydebs.split(' ') %} python-debs/{{ deb }}{%- endfor %} /debs/ # Install locally-built Debian packages and implicitly install their dependencies -{%- for deb in docker_sonic_vs_pydebs.split(' ') %} -RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; }; dpkg_apt /debs/{{ deb }} -{%- endfor %} +RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; }; {%- for deb in docker_sonic_vs_pydebs.split(' ') %} dpkg_apt /debs/{{ deb }};{%- endfor %} {%- endif %} +{% if docker_sonic_vs_whls.strip() %} +# copy all whl PKGs first, +copy {%- for whl in docker_sonic_vs_whls.split(' ') %} python-wheels/{{ whl }}{%- endfor %} python-wheels/ + +# install PKGs after copying all PKGs to avoid dependency failure +# use py3 to find python3 package, which is forced by wheel as of now +{%- for whl in docker_sonic_vs_whls.split(' ') %} +RUN pip{% if 'py3' in whl %}3{% else %}2{% endif %} install python-wheels/{{ whl }} +{%- endfor %} +{% endif %} + # Clean up +RUN apt-get purge -y build-essential libssl-dev swig +RUN apt-get purge -y python-dev python3-dev +RUN apt-get purge -y libcairo2-dev libdbus-1-dev libgirepository1.0-dev libsystemd-dev pkg-config RUN apt-get clean -y RUN apt-get autoclean -y RUN apt-get autoremove -y @@ -100,13 +159,21 @@ RUN sed -ri 's/^(save .*$)/# \1/g; ' /etc/redis/redis.conf COPY ["50-default.conf", "/etc/rsyslog.d/"] -COPY ["start.sh", "orchagent.sh", "/usr/bin/"] +COPY ["start.sh", "orchagent.sh", "files/update_chassisdb_config", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["files/configdb-load.sh", "/usr/bin/"] COPY ["files/arp_update", "/usr/bin/"] -COPY ["files/buffers_config.j2", "files/qos_config.j2", "/usr/share/sonic/templates/"] +COPY ["files/buffers_config.j2", "files/qos_config.j2", "files/arp_update_vars.j2", "files/copp_cfg.j2", "/usr/share/sonic/templates/"] COPY ["files/sonic_version.yml", "/etc/sonic/"] +COPY ["port_breakout_config_db.json", "/etc/sonic/"] COPY ["database_config.json", "/etc/default/sonic-db/"] +COPY ["hostname.j2", "/usr/share/sonic/templates/"] +COPY ["default_chassis_cfg.json", "/etc/default/sonic-db/"] +COPY ["asic_table.json", "/etc/sonic/"] +COPY ["buffermgrd.sh", "/usr/bin/"] + +COPY ["platform.json", "/usr/share/sonic/device/x86_64-kvm_x86_64-r0/"] +COPY ["hwsku.json", "/usr/share/sonic/device/x86_64-kvm_x86_64-r0/Force10-S6000/"] # Workaround the tcpdump issue RUN mv /usr/sbin/tcpdump /usr/bin/tcpdump @@ -121,4 +188,8 @@ RUN rm /etc/frr/frr.conf # Create /var/warmboot/teamd folder for teammgrd RUN mkdir -p /var/warmboot/teamd -ENTRYPOINT ["/usr/bin/supervisord"] +# Set PLATFORM and HWSKU environment variables +ENV PLATFORM=x86_64-kvm_x86_64-r0 +ENV HWSKU=Force10-S6000 + +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/vs/docker-sonic-vs/asic_table.json b/platform/vs/docker-sonic-vs/asic_table.json new file mode 100644 index 000000000000..f0ed93864e2f --- /dev/null +++ b/platform/vs/docker-sonic-vs/asic_table.json @@ -0,0 +1,11 @@ +[ + { + "ASIC_TABLE:VS-ASIC": { + "cell_size": "128", + "pipeline_latency": "18", + "mac_phy_delay": "0.8", + "peer_response_time": "3.8" + }, + "OP": "SET" + } +] diff --git a/platform/vs/docker-sonic-vs/buffermgrd.sh b/platform/vs/docker-sonic-vs/buffermgrd.sh new file mode 100755 index 000000000000..9cdc57434a8f --- /dev/null +++ b/platform/vs/docker-sonic-vs/buffermgrd.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +BUFFER_CALCULATION_MODE=$(redis-cli -n 4 hget "DEVICE_METADATA|localhost" buffer_model) +export ASIC_VENDOR=vs + +if [ "$BUFFER_CALCULATION_MODE" == "dynamic" ]; then + BUFFERMGRD_ARGS="-a /etc/sonic/asic_table.json" +else + # Should we use the fallback MAC in case it is not found in Device.Metadata + BUFFERMGRD_ARGS="-l /usr/share/sonic/hwsku/pg_profile_lookup.ini" +fi + +exec /usr/bin/buffermgrd ${BUFFERMGRD_ARGS} diff --git a/platform/vs/docker-sonic-vs/database_config.json b/platform/vs/docker-sonic-vs/database_config.json index b86ae11bba98..953c23f22710 100644 --- a/platform/vs/docker-sonic-vs/database_config.json +++ b/platform/vs/docker-sonic-vs/database_config.json @@ -4,6 +4,12 @@ "hostname" : "127.0.0.1", "port" : 6379, "unix_socket_path" : "/var/run/redis/redis.sock" + }, + + "redis_chassis":{ + "hostname" : "redis_chassis.server", + "port": 6380, + "unix_socket_path": "/var/run/redis/redis_chassis.sock" } }, "DATABASES" : { @@ -51,6 +57,26 @@ "id" : 7, "separator": "|", "instance" : "redis" + }, + "GB_ASIC_DB" : { + "id" : 8, + "separator": "|", + "instance" : "redis" + }, + "GB_COUNTERS_DB" : { + "id" : 9, + "separator": "|", + "instance" : "redis" + }, + "GB_FLEX_COUNTER_DB" : { + "id" : 10, + "separator": "|", + "instance" : "redis" + }, + "CHASSIS_APP_DB" : { + "id" : 12, + "separator": "|", + "instance" : "redis_chassis" } }, "VERSION" : "1.0" diff --git a/platform/vs/docker-sonic-vs/default_chassis_cfg.json b/platform/vs/docker-sonic-vs/default_chassis_cfg.json new file mode 100644 index 000000000000..673a4791faeb --- /dev/null +++ b/platform/vs/docker-sonic-vs/default_chassis_cfg.json @@ -0,0 +1,7 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "chassis_db_address" : "10.8.1.200" + } + } +} diff --git a/platform/vs/docker-sonic-vs/hostname.j2 b/platform/vs/docker-sonic-vs/hostname.j2 new file mode 100644 index 000000000000..91d7cbaaeb3e --- /dev/null +++ b/platform/vs/docker-sonic-vs/hostname.j2 @@ -0,0 +1,3 @@ +{% if DEVICE_METADATA.localhost.chassis_db_address %} +{{ DEVICE_METADATA.localhost.chassis_db_address }} redis_chassis.server +{% endif %} diff --git a/platform/vs/docker-sonic-vs/hwsku.json b/platform/vs/docker-sonic-vs/hwsku.json new file mode 100644 index 000000000000..ed121868c9f5 --- /dev/null +++ b/platform/vs/docker-sonic-vs/hwsku.json @@ -0,0 +1,100 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet4": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet8": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet12": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet16": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet20": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet24": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet28": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet32": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet36": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet40": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet44": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet48": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet52": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet56": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet60": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet64": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet68": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet72": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet76": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet80": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet84": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet88": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet92": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet96": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet100": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet104": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet108": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet112": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet116": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet120": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet124": { + "default_brkout_mode": "1x100G[40G]" + } + } +} diff --git a/platform/vs/docker-sonic-vs/orchagent.sh b/platform/vs/docker-sonic-vs/orchagent.sh index 2acd709a8e94..4a035a26b292 100755 --- a/platform/vs/docker-sonic-vs/orchagent.sh +++ b/platform/vs/docker-sonic-vs/orchagent.sh @@ -6,7 +6,12 @@ else export platform=$fake_platform fi -MAC_ADDRESS=$(sonic-cfggen -d -v 'DEVICE_METADATA.localhost.mac') +SWSS_VARS_FILE=/usr/share/sonic/templates/swss_vars.j2 + +# Retrieve SWSS vars from sonic-cfggen +SWSS_VARS=$(sonic-cfggen -d -y /etc/sonic/sonic_version.yml -t $SWSS_VARS_FILE) || exit 1 + +MAC_ADDRESS=$(echo $SWSS_VARS | jq -r '.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" @@ -19,6 +24,12 @@ ORCHAGENT_ARGS="-d /var/log/swss " # Set orchagent pop batch size to 8192 ORCHAGENT_ARGS+="-b 8192 " +# Set synchronous mode if it is enabled in CONFIG_DB +SYNC_MODE=$(echo $SWSS_VARS | jq -r '.synchronous_mode') +if [ "$SYNC_MODE" == "enable" ]; then + ORCHAGENT_ARGS+="-s " +fi + # Set mac address ORCHAGENT_ARGS+="-m $MAC_ADDRESS" diff --git a/platform/vs/docker-sonic-vs/platform.json b/platform/vs/docker-sonic-vs/platform.json new file mode 100644 index 000000000000..053fed5516ed --- /dev/null +++ b/platform/vs/docker-sonic-vs/platform.json @@ -0,0 +1,196 @@ +{ + "interfaces": { + "Ethernet0": { + "index": "0,0,0,0", + "lanes": "25,26,27,28", + "alias_at_lanes": "fortyGigE0/0,fortyGigE0/1,fortyGigE0/2,fortyGigE0/3", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet4": { + "index": "1,1,1,1", + "lanes": "29,30,31,32", + "alias_at_lanes": "fortyGigE0/4,fortyGigE0/5,fortyGigE0/6,fortyGigE0/7", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet8": { + "index": "2,2,2,2", + "lanes": "33,34,35,36", + "alias_at_lanes": "fortyGigE0/8,fortyGigE0/9,fortyGigE0/10,fortyGigE0/11", + "breakout_modes": "1x100G[40G],2x50G,2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet12": { + "index": "3,3,3,3", + "lanes": "37,38,39,40", + "alias_at_lanes": "fortyGigE0/12,fortyGigE0/13,fortyGigE0/14,fortyGigE0/15", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet16": { + "index": "4,4,4,4", + "lanes": "45,46,47,48", + "alias_at_lanes": "fortyGigE0/16,fortyGigE0/17,fortyGigE0/18,fortyGigE0/19", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet20": { + "index": "5,5,5,5", + "lanes": "41,42,43,44", + "alias_at_lanes": "fortyGigE0/20,fortyGigE0/21,fortyGigE0/22,fortyGigE0/23", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet24": { + "index": "6,6,6,6", + "lanes": "1,2,3,4", + "alias_at_lanes": "fortyGigE0/24,fortyGigE0/25,fortyGigE0/26,fortyGigE0/27", + "breakout_modes": "1x100G[40G],4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet28": { + "index": "7,7,7,7", + "lanes": "5,6,7,8", + "alias_at_lanes": "fortyGigE0/28,fortyGigE0/29,fortyGigE0/30,fortyGigE0/31", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet32": { + "index": "8,8,8,8", + "lanes": "13,14,15,16", + "alias_at_lanes": "fortyGigE0/32,fortyGigE0/33,fortyGigE0/34,fortyGigE0/35", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet36": { + "index": "9,9,9,9", + "lanes": "9,10,11,12", + "alias_at_lanes": "fortyGigE0/36,fortyGigE0/37,fortyGigE0/38,fortyGigE0/39", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet40": { + "index": "10,10,10,10", + "lanes": "17,18,19,20", + "alias_at_lanes": "fortyGigE0/40,fortyGigE0/41,fortyGigE0/42,fortyGigE0/43", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet44": { + "index": "11,11,11,11", + "lanes": "21,22,23,24", + "alias_at_lanes": "fortyGigE0/44,fortyGigE0/45,fortyGigE0/46,fortyGigE0/47", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet48": { + "index": "12,12,12,12", + "lanes": "53,54,55,56", + "alias_at_lanes": "fortyGigE0/48,fortyGigE0/49,fortyGigE0/50,fortyGigE0/51", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet52": { + "index": "13,13,13,13", + "lanes": "49,50,51,52", + "alias_at_lanes": "fortyGigE0/52,fortyGigE0/53,fortyGigE0/54,fortyGigE0/55", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet56": { + "index": "14,14,14,14", + "lanes": "57,58,59,60", + "alias_at_lanes": "fortyGigE0/56,fortyGigE0/57,fortyGigE0/58,fortyGigE0/59", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet60": { + "index": "15,15,15,15", + "lanes": "61,62,63,64", + "alias_at_lanes": "fortyGigE0/60,fortyGigE0/61,fortyGigE0/62,fortyGigE0/63", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet64": { + "index": "16,16,16,16", + "lanes": "69,70,71,72", + "alias_at_lanes": "fortyGigE0/64,fortyGigE0/65,fortyGigE0/66,fortyGigE0/67", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet68": { + "index": "17,17,17,17", + "lanes": "65,66,67,68", + "alias_at_lanes": "fortyGigE0/68,fortyGigE0/69,fortyGigE0/70,fortyGigE0/71", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet72": { + "index": "18,18,18,18", + "lanes": "73,74,75,76", + "alias_at_lanes": "fortyGigE0/72,fortyGigE0/73,fortyGigE0/74,fortyGigE0/75", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet76": { + "index": "19,19,19,19", + "lanes": "77,78,79,80", + "alias_at_lanes": "fortyGigE0/76,fortyGigE0/77,fortyGigE0/78,fortyGigE0/79", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet80": { + "index": "20,20,20,20", + "lanes": "109,110,111,112", + "alias_at_lanes": "fortyGigE0/80,fortyGigE0/81,fortyGigE0/82,fortyGigE0/83", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet84": { + "index": "21,21,21,21", + "lanes": "105,106,107,108", + "alias_at_lanes": "fortyGigE0/84,fortyGigE0/85,fortyGigE0/86,fortyGigE0/87", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet88": { + "index": "22,22,22,22", + "lanes": "113,114,115,116", + "alias_at_lanes": "fortyGigE0/88,fortyGigE0/89,fortyGigE0/90,fortyGigE0/91", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet92": { + "index": "23,23,23,23", + "lanes": "117,118,119,120", + "alias_at_lanes": "fortyGigE0/92,fortyGigE0/93,fortyGigE0/94,fortyGigE0/95", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet96": { + "index": "24,24,24,24", + "lanes": "125,126,127,128", + "alias_at_lanes": "fortyGigE0/96,fortyGigE0/97,fortyGigE0/98,fortyGigE0/99", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet100": { + "index": "25,25,25,25", + "lanes": "121,122,123,124", + "alias_at_lanes": "fortyGigE0/100,fortyGigE0/101,fortyGigE0/102,fortyGigE0/103", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet104": { + "index": "26,26,26,26", + "lanes": "81,82,83,84", + "alias_at_lanes": "fortyGigE0/104,fortyGigE0/105,fortyGigE0/106,fortyGigE0/107", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet108": { + "index": "27,27,27,27", + "lanes": "85,86,87,88", + "alias_at_lanes": "fortyGigE0/108,fortyGigE0/109,fortyGigE0/110,fortyGigE0/111", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet112": { + "index": "28,28,28,28", + "lanes": "93,94,95,96", + "alias_at_lanes": "fortyGigE0/112,fortyGigE0/113,fortyGigE0/114,fortyGigE0/115", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet116": { + "index": "29,29,29,29", + "lanes": "89,90,91,92", + "alias_at_lanes": "fortyGigE0/116,fortyGigE0/117,fortyGigE0/118,fortyGigE0/119", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet120": { + "index": "30,30,30,30", + "lanes": "101,102,103,104", + "alias_at_lanes": "fortyGigE0/120,fortyGigE0/121,fortyGigE0/122,fortyGigE0/123", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet124": { + "index": "31,31,31,31", + "lanes": "97,98,99,100", + "alias_at_lanes": "fortyGigE0/124,fortyGigE0/125,fortyGigE0/126,fortyGigE0/127", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + } + } +} diff --git a/platform/vs/docker-sonic-vs/port_breakout_config_db.json b/platform/vs/docker-sonic-vs/port_breakout_config_db.json new file mode 100644 index 000000000000..16b40e14f8f0 --- /dev/null +++ b/platform/vs/docker-sonic-vs/port_breakout_config_db.json @@ -0,0 +1,61 @@ +{ + "ACL_TABLE": { + "DPB_ACL_TBL_1": { + "policy_desc": "ACL table to test DPB/ACL dependency", + "ports": [ + "Ethernet0", + "Ethernet1", + "Ethernet2", + "Ethernet3", + "Ethernet4", + "Ethernet5" + ], + "type": "L3" + }, + "DPB_ACL_TBL_2": { + "policy_desc": "ACL table to test DPB/ACL dependency", + "ports": [ + "Ethernet0", + "Ethernet1", + "Ethernet2", + "Ethernet3", + "Ethernet6", + "Ethernet7" + ], + "type": "L3" + } + }, + "INTERFACE": { + "Ethernet8": {}, + "Ethernet8|10.0.0.8/31": { + "family": "IPv4", + "scope": "global" + } + }, + "VLAN_MEMBER": { + "Vlan100|Ethernet0": { + "tagging_mode": "untagged" + }, + "Vlan100|Ethernet1": { + "tagging_mode": "untagged" + }, + "Vlan100|Ethernet2": { + "tagging_mode": "untagged" + }, + "Vlan100|Ethernet3": { + "tagging_mode": "untagged" + }, + "Vlan100|Ethernet4": { + "tagging_mode": "untagged" + }, + "Vlan100|Ethernet5": { + "tagging_mode": "untagged" + }, + "Vlan101|Ethernet6": { + "tagging_mode": "tagged" + }, + "Vlan101|Ethernet7": { + "tagging_mode": "tagged" + } + } +} diff --git a/platform/vs/docker-sonic-vs/start.sh b/platform/vs/docker-sonic-vs/start.sh index f8fcf974b65c..7ee70efa0815 100755 --- a/platform/vs/docker-sonic-vs/start.sh +++ b/platform/vs/docker-sonic-vs/start.sh @@ -1,27 +1,57 @@ #!/bin/bash -e -# generate configuration +# Generate configuration -PLATFORM=x86_64-kvm_x86_64-r0 -HWSKU=Force10-S6000 +# NOTE: 'PLATFORM' and 'HWSKU' environment variables are set +# in the Dockerfile so that they persist for the life of the container +ln -sf /usr/share/sonic/device/$PLATFORM /usr/share/sonic/platform ln -sf /usr/share/sonic/device/$PLATFORM/$HWSKU /usr/share/sonic/hwsku +pushd /usr/share/sonic/hwsku + +# filter available front panel ports in lanemap.ini +[ -f lanemap.ini.orig ] || cp lanemap.ini lanemap.ini.orig +for p in $(ip link show | grep -oE "eth[0-9]+" | grep -v eth0); do + grep ^$p: lanemap.ini.orig +done > lanemap.ini + +# filter available sonic front panel ports in port_config.ini +[ -f port_config.ini.orig ] || cp port_config.ini port_config.ini.orig +grep ^# port_config.ini.orig > port_config.ini +for lanes in $(awk -F ':' '{print $2}' lanemap.ini); do + grep -E "\s$lanes\s" port_config.ini.orig +done >> port_config.ini + +popd + [ -d /etc/sonic ] || mkdir -p /etc/sonic +if [[ -f /usr/share/sonic/virtual_chassis/default_config.json ]]; then + CHASS_CFG="-j /usr/share/sonic/virtual_chassis/default_config.json" +fi + +# Note: libswsscommon requires a dabase_config file in /var/run/redis/sonic-db/ +# Prepare this file before any dependent application, such as sonic-cfggen +mkdir -p /var/run/redis/sonic-db +cp /etc/default/sonic-db/database_config.json /var/run/redis/sonic-db/ + 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 +sonic-cfggen -a '{"DEVICE_METADATA":{"localhost": {"mac": "'$SYSTEM_MAC_ADDRESS'", "buffer_model": "traditional"}}}' $CHASS_CFG --print-data > /etc/sonic/init_cfg.json if [ -f /etc/sonic/config_db.json ]; then 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 - sonic-cfggen -t /usr/share/sonic/hwsku/buffers.json.j2 > /tmp/buffers.json + sonic-cfggen -k $HWSKU -p /usr/share/sonic/device/$PLATFORM/platform.json -t /usr/share/sonic/hwsku/buffers.json.j2 > /tmp/buffers.json sonic-cfggen -j /etc/sonic/init_cfg.json -t /usr/share/sonic/hwsku/qos.json.j2 > /tmp/qos.json - sonic-cfggen -p /usr/share/sonic/hwsku/port_config.ini -k $HWSKU --print-data > /tmp/ports.json + sonic-cfggen -p /usr/share/sonic/device/$PLATFORM/platform.json -k $HWSKU --print-data > /tmp/ports.json + # change admin_status from up to down; Test cases dependent + sed -i "s/up/down/g" /tmp/ports.json sonic-cfggen -j /etc/sonic/init_cfg.json -j /tmp/buffers.json -j /tmp/qos.json -j /tmp/ports.json --print-data > /etc/sonic/config_db.json fi +sonic-cfggen -t /usr/share/sonic/templates/copp_cfg.j2 > /etc/sonic/copp_cfg.json mkdir -p /etc/swss/config.d/ @@ -29,21 +59,54 @@ rm -f /var/run/rsyslogd.pid supervisorctl start rsyslogd -mkdir -p /var/run/redis/sonic-db -cp /etc/default/sonic-db/database_config.json /var/run/redis/sonic-db/ +supervisord_cfg="/etc/supervisor/conf.d/supervisord.conf" +chassisdb_cfg_file="/usr/share/sonic/virtual_chassis/default_config.json" +chassisdb_cfg_file_default="/etc/default/sonic-db/default_chassis_cfg.json" +host_template="/usr/share/sonic/templates/hostname.j2" +db_cfg_file="/var/run/redis/sonic-db/database_config.json" +db_cfg_file_tmp="/var/run/redis/sonic-db/database_config.json.tmp" + +if [ -r "$chassisdb_cfg_file" ]; then + echo $(sonic-cfggen -j $chassisdb_cfg_file -t $host_template) >> /etc/hosts +else + chassisdb_cfg_file="$chassisdb_cfg_file_default" + echo "10.8.1.200 redis_chassis.server" >> /etc/hosts +fi supervisorctl start redis-server +start_chassis_db=`sonic-cfggen -v DEVICE_METADATA.localhost.start_chassis_db -y $chassisdb_cfg_file` +if [[ "$HOSTNAME" == *"supervisor"* ]] || [ "$start_chassis_db" == "1" ]; then + supervisorctl start redis-chassis +fi + +conn_chassis_db=`sonic-cfggen -v DEVICE_METADATA.localhost.connect_to_chassis_db -y $chassisdb_cfg_file` +if [ "$start_chassis_db" != "1" ] && [ "$conn_chassis_db" != "1" ]; then + cp $db_cfg_file $db_cfg_file_tmp + update_chassisdb_config -j $db_cfg_file_tmp -d + cp $db_cfg_file_tmp $db_cfg_file +fi + +if [ "$conn_chassis_db" == "1" ]; then + if [ -f /usr/share/sonic/virtual_chassis/coreportindexmap.ini ]; then + cp /usr/share/sonic/virtual_chassis/coreportindexmap.ini /usr/share/sonic/hwsku/ + fi +fi + /usr/bin/configdb-load.sh supervisorctl start syncd +supervisorctl start portsyncd + supervisorctl start orchagent -supervisorctl start portsyncd +supervisorctl start coppmgrd supervisorctl start neighsyncd +supervisorctl start fdbsyncd + supervisorctl start teamsyncd supervisorctl start fpmsyncd @@ -74,6 +137,8 @@ supervisorctl start natmgrd supervisorctl start natsyncd +supervisorctl start tunnelmgrd + # 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 3a7acfd20bbe..977b84117e3e 100644 --- a/platform/vs/docker-sonic-vs/supervisord.conf +++ b/platform/vs/docker-sonic-vs/supervisord.conf @@ -27,6 +27,14 @@ autorestart=false stdout_logfile=syslog stderr_logfile=syslog +[program:redis-chassis] +command=/bin/bash -c "{ [[ -s /var/lib/redis_chassis/dump.rdb ]] || rm -f /var/lib/redis_chassis/dump.rdb; } && mkdir -p /var/lib/redis_chassis && exec /usr/bin/redis-server /etc/redis/redis.conf --bind redis_chassis.server --port 6380 --unixsocket /var/run/redis/redis_chassis.sock --pidfile /var/run/redis/redis_chassis.pid --dir /var/lib/redis_chassis" +priority=3 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + [program:syncd] command=/usr/bin/syncd_start.sh priority=4 @@ -35,22 +43,30 @@ autorestart=false stdout_logfile=syslog stderr_logfile=syslog -[program:orchagent] -command=/usr/bin/orchagent.sh +[program:portsyncd] +command=/usr/bin/portsyncd priority=5 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog -[program:portsyncd] -command=/usr/bin/portsyncd +[program:orchagent] +command=/usr/bin/orchagent.sh priority=6 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +[program:coppmgrd] +command=/usr/bin/coppmgrd +priority=7 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + [program:neighsyncd] command=/usr/bin/neighsyncd priority=8 @@ -140,7 +156,7 @@ stdout_logfile=syslog stderr_logfile=syslog [program:buffermgrd] -command=/usr/bin/buffermgrd -l /usr/share/sonic/hwsku/pg_profile_lookup.ini +command=/usr/bin/buffermgrd.sh priority=17 autostart=false autorestart=false @@ -204,3 +220,19 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog + +[program:fdbsyncd] +command=/usr/bin/fdbsyncd +priority=25 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +[program:tunnelmgrd] +command=/usr/bin/tunnelmgrd +priority=26 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog diff --git a/platform/vs/docker-syncd-vs/Dockerfile.j2 b/platform/vs/docker-syncd-vs/Dockerfile.j2 index 070d8b984f4b..b3d7dcef490b 100644 --- a/platform/vs/docker-syncd-vs/Dockerfile.j2 +++ b/platform/vs/docker-syncd-vs/Dockerfile.j2 @@ -1,4 +1,4 @@ -FROM docker-config-engine-stretch +FROM docker-config-engine-buster ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf @@ -8,7 +8,7 @@ ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update -RUN apt-get install -f -y iproute2=4.20.0-2~bpo9+1 libcap2-bin=1:2.25-1 +RUN apt-get install -f -y iproute2 libcap2-bin COPY \ {% for deb in docker_syncd_vs_debs.split(' ') -%} @@ -24,9 +24,11 @@ debs/{{ deb }}{{' '}} COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor/"] ## Clean up RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/platform/vs/docker-syncd-vs/critical_processes b/platform/vs/docker-syncd-vs/critical_processes new file mode 100644 index 000000000000..bdd6903c5690 --- /dev/null +++ b/platform/vs/docker-syncd-vs/critical_processes @@ -0,0 +1 @@ +program:syncd diff --git a/platform/vs/docker-syncd-vs/start.sh b/platform/vs/docker-syncd-vs/start.sh index 98c7d9c15a0d..40178f13e004 100755 --- a/platform/vs/docker-syncd-vs/start.sh +++ b/platform/vs/docker-syncd-vs/start.sh @@ -1,30 +1,7 @@ #!/usr/bin/env bash -PLATFORM_DIR=/usr/share/sonic/platform HWSKU_DIR=/usr/share/sonic/hwsku -SYNCD_SOCKET_FILE=/var/run/sswsyncd/sswsyncd.socket - -# Function: wait until syncd has created the socket for bcmcmd to connect to -wait_syncd() { - while true; do - if [ -e ${SYNCD_SOCKET_FILE} ]; then - break - fi - sleep 1 - done - - # wait until bcm sdk is ready to get a request - sleep 3 -} - - -# Remove stale files if they exist -rm -f /var/run/rsyslogd.pid -rm -f ${SYNCD_SOCKET_FILE} - -supervisorctl start rsyslogd - mkdir -p /etc/sai.d/ # Create/Copy the sai.profile to /etc/sai.d/sai.profile @@ -35,11 +12,3 @@ else cp $HWSKU_DIR/sai.profile /etc/sai.d/sai.profile fi fi - -supervisorctl start syncd - -# If this platform has an initialization file for the Broadcom LED microprocessor, load it -if [ -r ${PLATFORM_DIR}/led_proc_init.soc ]; then - wait_syncd - supervisorctl start ledinit -fi diff --git a/platform/vs/docker-syncd-vs/supervisord.conf b/platform/vs/docker-syncd-vs/supervisord.conf index 1af5d70a1d0c..6a6d946632e0 100644 --- a/platform/vs/docker-syncd-vs/supervisord.conf +++ b/platform/vs/docker-syncd-vs/supervisord.conf @@ -3,21 +3,40 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true -[program:start.sh] -command=/usr/bin/start.sh -priority=1 +[eventlistener:dependent-startup] +command=python3 -m supervisord_dependent_startup autostart=true -autorestart=false +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE +buffer_size=25 + +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name syncd +events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING +autostart=true +autorestart=unexpected + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 +autostart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true -[program:rsyslogd] -command=/usr/sbin/rsyslogd -n +[program:start] +command=/usr/bin/start.sh priority=2 autostart=false autorestart=false +startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running [program:syncd] command=/usr/bin/syncd_start.sh @@ -26,3 +45,5 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited diff --git a/platform/vs/gbsyncd-vs.mk b/platform/vs/gbsyncd-vs.mk new file mode 100644 index 000000000000..2013132d6281 --- /dev/null +++ b/platform/vs/gbsyncd-vs.mk @@ -0,0 +1,14 @@ +# docker image for vs gbsyncd + +DOCKER_GBSYNCD_PLATFORM_CODE = vs +include $(PLATFORM_PATH)/../template/docker-gbsyncd-base.mk + +$(DOCKER_GBSYNCD_BASE)_DEPENDS += $(SYNCD_VS) + +$(DOCKER_GBSYNCD_BASE)_DBG_DEPENDS += $(SYNCD_VS_DBG) \ + $(LIBSWSSCOMMON_DBG) \ + $(LIBSAIMETADATA_DBG) \ + $(LIBSAIREDIS_DBG) \ + $(LIBSAIVS_DBG) + +$(DOCKER_GBSYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot diff --git a/platform/vs/libsaithrift-dev.dep b/platform/vs/libsaithrift-dev.dep new file mode 100644 index 000000000000..be1d3f74b23f --- /dev/null +++ b/platform/vs/libsaithrift-dev.dep @@ -0,0 +1,13 @@ +#DPKG FRK +SPATH := $($(LIBSAITHRIFT_DEV)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/broadcom/libsaithrift-dev.mk platform/broadcom/libsaithrift-dev.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +SMDEP_PATHS := $(SPATH) $(SPATH)/bm/behavioral-model $(SPATH)/test/ptf $(SPATH)/test/saithrift/ctypesgen +$(foreach path, $(SMDEP_PATHS), $(eval $(path) :=$(filter-out $(SMDEP_PATHS),$(addprefix $(path)/, $(shell cd $(path) && git ls-files | grep -Ev " " ))))) + +$(LIBSAITHRIFT_DEV)_CACHE_MODE := GIT_CONTENT_SHA +$(LIBSAITHRIFT_DEV)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(LIBSAITHRIFT_DEV)_DEP_FILES := $(DEP_FILES) +$(LIBSAITHRIFT_DEV)_SMDEP_FILES := $(foreach path, $(SMDEP_PATHS), $($(path))) +$(LIBSAITHRIFT_DEV)_SMDEP_PATHS := $(SMDEP_PATHS) + diff --git a/platform/vs/libsaithrift-dev.mk b/platform/vs/libsaithrift-dev.mk new file mode 100644 index 000000000000..ba8a63d539ac --- /dev/null +++ b/platform/vs/libsaithrift-dev.mk @@ -0,0 +1,22 @@ +# libsaithrift-dev package + +SAI_VER = 0.9.4 + +LIBSAITHRIFT_DEV = libsaithrift-dev_$(SAI_VER)_$(CONFIGURED_ARCH).deb +$(LIBSAITHRIFT_DEV)_SRC_PATH = $(SRC_PATH)/sonic-sairedis/SAI +$(LIBSAITHRIFT_DEV)_DEPENDS += $(LIBTHRIFT) $(LIBTHRIFT_DEV) $(PYTHON_THRIFT) $(THRIFT_COMPILER) \ + $(LIBSAIVS) $(LIBSAIVS_DEV) $(LIBSAIMETADATA) $(LIBSAIMETADATA_DEV) +$(LIBSAITHRIFT_DEV)_RDEPENDS += $(LIBTHRIFT) $(LIBSAIVS) $(LIBSAIMETADATA) +$(LIBSAITHRIFT_DEV)_BUILD_ENV = platform=vs +SONIC_DPKG_DEBS += $(LIBSAITHRIFT_DEV) + +PYTHON_SAITHRIFT = python-saithrift_$(SAI_VER)_$(CONFIGURED_ARCH).deb +$(eval $(call add_extra_package,$(LIBSAITHRIFT_DEV),$(PYTHON_SAITHRIFT))) + +SAISERVER = saiserver_$(SAI_VER)_$(CONFIGURED_ARCH).deb +$(SAISERVER)_RDEPENDS += $(LIBTHRIFT) $(LIBSAIVS) +$(eval $(call add_extra_package,$(LIBSAITHRIFT_DEV),$(SAISERVER))) + +SAISERVER_DBG = saiserver-dbg_$(SAI_VER)_$(CONFIGURED_ARCH).deb +$(SAISERVER_DBG)_RDEPENDS += $(SAISERVER) +$(eval $(call add_extra_package,$(LIBSAITHRIFT_DEV),$(SAISERVER_DBG))) diff --git a/platform/vs/one-image.mk b/platform/vs/one-image.mk index cf4f535382bc..a0e176df1497 100644 --- a/platform/vs/one-image.mk +++ b/platform/vs/one-image.mk @@ -1,9 +1,9 @@ # sonic vs one image installer SONIC_ONE_IMAGE = sonic-vs.bin -$(SONIC_ONE_ABOOT_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) $(SONIC_ONE_IMAGE)_MACHINE = vs $(SONIC_ONE_IMAGE)_IMAGE_TYPE = onie +$(SONIC_ONE_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) 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/vs/raw-image.dep b/platform/vs/raw-image.dep new file mode 100644 index 000000000000..500ba2a70fef --- /dev/null +++ b/platform/vs/raw-image.dep @@ -0,0 +1,2 @@ +#DPKG FRK +$(SONIC_RAW_IMAGE)_CACHE_MODE := none diff --git a/platform/vs/raw-image.mk b/platform/vs/raw-image.mk new file mode 100644 index 000000000000..becb9012f552 --- /dev/null +++ b/platform/vs/raw-image.mk @@ -0,0 +1,8 @@ +# sonic vs raw image installer + +SONIC_RAW_IMAGE = sonic-vs.raw +$(SONIC_RAW_IMAGE)_MACHINE = vs +$(SONIC_RAW_IMAGE)_IMAGE_TYPE = raw +$(SONIC_RAW_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) +$(SONIC_RAW_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_IMAGES) +SONIC_INSTALLERS += $(SONIC_RAW_IMAGE) diff --git a/platform/vs/rules.dep b/platform/vs/rules.dep index 7d36c819509e..0d485e8004d1 100644 --- a/platform/vs/rules.dep +++ b/platform/vs/rules.dep @@ -2,6 +2,9 @@ include $(PLATFORM_PATH)/syncd-vs.dep include $(PLATFORM_PATH)/sonic-version.dep include $(PLATFORM_PATH)/docker-sonic-vs.dep include $(PLATFORM_PATH)/docker-syncd-vs.dep +include $(PLATFORM_PATH)/docker-gbsyncd-vs.dep +include $(PLATFORM_PATH)/docker-ptf.dep +include $(PLATFORM_PATH)/libsaithrift-dev.dep include $(PLATFORM_PATH)/one-image.dep include $(PLATFORM_PATH)/onie.dep include $(PLATFORM_PATH)/kvm-image.dep diff --git a/platform/vs/rules.mk b/platform/vs/rules.mk index 557604d9ec4d..cbb52847edfa 100644 --- a/platform/vs/rules.mk +++ b/platform/vs/rules.mk @@ -2,8 +2,12 @@ include $(PLATFORM_PATH)/syncd-vs.mk include $(PLATFORM_PATH)/sonic-version.mk include $(PLATFORM_PATH)/docker-sonic-vs.mk include $(PLATFORM_PATH)/docker-syncd-vs.mk +include $(PLATFORM_PATH)/docker-gbsyncd-vs.mk +include $(PLATFORM_PATH)/docker-ptf.mk +include $(PLATFORM_PATH)/libsaithrift-dev.mk include $(PLATFORM_PATH)/one-image.mk include $(PLATFORM_PATH)/onie.mk include $(PLATFORM_PATH)/kvm-image.mk +include $(PLATFORM_PATH)/raw-image.mk -SONIC_ALL += $(SONIC_ONE_IMAGE) $(SONIC_KVM_IMAGE) $(DOCKER_SONIC_VS) +SONIC_ALL += $(SONIC_ONE_IMAGE) $(SONIC_KVM_IMAGE) $(DOCKER_SONIC_VS) $(SONIC_RAW_IMAGE) diff --git a/platform/vs/sonic-gns3a.sh b/platform/vs/sonic-gns3a.sh index 57c63fb75f32..41e39cd8686a 100644 --- a/platform/vs/sonic-gns3a.sh +++ b/platform/vs/sonic-gns3a.sh @@ -39,7 +39,7 @@ echo " { \"name\": \"SONiC\", \"category\": \"router\", - \"description\": \"SONiC Virtual Switch/Router\n\", + \"description\": \"SONiC Virtual Switch/Router\", \"vendor_name\": \"SONiC\", \"vendor_url\": \"https://azure.github.io/SONiC/\", \"product_name\": \"SONiC\", @@ -49,6 +49,7 @@ echo " \"maintainer\": \"SONiC\", \"maintainer_email\": \"sonicproject@googlegroups.com\", \"usage\": \"Supports SONiC release: ${RELEASE}\", + \"first_port_name\": \"eth0\", \"qemu\": { \"adapter_type\": \"e1000\", \"adapters\": 10, 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/platform/vs/syncd-vs.mk b/platform/vs/syncd-vs.mk index 49035aaf958b..22b34fbcaae3 100644 --- a/platform/vs/syncd-vs.mk +++ b/platform/vs/syncd-vs.mk @@ -1,8 +1,5 @@ $(LIBSAIREDIS)_DPKG_TARGET = binary-syncd-vs -# inject libsaivs and libsaivs_dev to swss build dependency -$(SWSS)_DEPENDS += $(LIBSAIVS) $(LIBSAIVS_DEV) - SYNCD_VS = syncd-vs_1.0.0_amd64.deb $(SYNCD_VS)_RDEPENDS += $(LIBSAIREDIS) $(LIBSAIMETADATA) $(LIBSAIVS) $(eval $(call add_derived_package,$(LIBSAIREDIS),$(SYNCD_VS))) diff --git a/platform/vs/tests/bgp/files/default_route/bgpd.conf b/platform/vs/tests/bgp/files/default_route/bgpd.conf new file mode 100644 index 000000000000..bc0dffcdbb8b --- /dev/null +++ b/platform/vs/tests/bgp/files/default_route/bgpd.conf @@ -0,0 +1,4 @@ +router bgp 65501 + bgp router-id 1.1.1.1 + no bgp ebgp-requires-policy + neighbor 10.10.10.1 remote-as 65502 diff --git a/platform/vs/tests/bgp/files/default_route/default_route.conf b/platform/vs/tests/bgp/files/default_route/default_route.conf new file mode 100644 index 000000000000..9f9d3cf32f80 --- /dev/null +++ b/platform/vs/tests/bgp/files/default_route/default_route.conf @@ -0,0 +1,17 @@ +neighbor 10.10.10.0 { + router-id 1.2.3.4; + local-address 10.10.10.1; + local-as 65502; + peer-as 65501; + group-updates false; + + family { + ipv4 unicast; + } + + static { + route 0.0.0.0/0 { + next-hop 10.10.10.1; + } + } +} diff --git a/platform/vs/tests/bgp/files/gr_livelock/bgpd.conf b/platform/vs/tests/bgp/files/gr_livelock/bgpd.conf index a26d1d93daf3..dc861ed46934 100644 --- a/platform/vs/tests/bgp/files/gr_livelock/bgpd.conf +++ b/platform/vs/tests/bgp/files/gr_livelock/bgpd.conf @@ -1,5 +1,6 @@ router bgp 65501 bgp router-id 1.1.1.1 + no bgp ebgp-requires-policy bgp graceful-restart restart-time 180 bgp graceful-restart neighbor 10.0.0.1 remote-as 65502 diff --git a/platform/vs/tests/bgp/files/invalid_nexthop/bgpd.conf b/platform/vs/tests/bgp/files/invalid_nexthop/bgpd.conf index b22bf17f92e3..33d235576dab 100644 --- a/platform/vs/tests/bgp/files/invalid_nexthop/bgpd.conf +++ b/platform/vs/tests/bgp/files/invalid_nexthop/bgpd.conf @@ -1,6 +1,7 @@ router bgp 65501 bgp router-id 1.1.1.1 no bgp default ipv4-unicast + no bgp ebgp-requires-policy neighbor fc00::2 remote-as 65502 address-family ipv6 neighbor fc00::2 activate diff --git a/platform/vs/tests/bgp/files/no_export/bgpd.conf b/platform/vs/tests/bgp/files/no_export/bgpd.conf index 40322cedbc69..cd87c330c299 100644 --- a/platform/vs/tests/bgp/files/no_export/bgpd.conf +++ b/platform/vs/tests/bgp/files/no_export/bgpd.conf @@ -1,6 +1,7 @@ router bgp 65501 bgp router-id 1.1.1.1 no bgp default ipv4-unicast + no bgp ebgp-requires-policy neighbor 10.0.0.1 remote-as 65502 address-family ipv4 neighbor 10.0.0.1 activate diff --git a/platform/vs/tests/bgp/test_default_route.py b/platform/vs/tests/bgp/test_default_route.py new file mode 100644 index 000000000000..2cc9021ba78e --- /dev/null +++ b/platform/vs/tests/bgp/test_default_route.py @@ -0,0 +1,48 @@ +from swsscommon import swsscommon +import os +import re +import time +import json +import pytest + +def test_DefaultRoute(dvs, testlog): + + dvs.copy_file("/etc/frr/", "bgp/files/default_route/bgpd.conf") + dvs.runcmd("supervisorctl start bgpd") + dvs.runcmd("ip addr add 10.10.10.0/31 dev Ethernet0") + dvs.runcmd("config interface startup Ethernet0") + dvs.runcmd("ip route del 0.0.0.0/0") + dvs.runcmd("vtysh -c \"confgure terminal\" -c \"ip route 0.0.0.0/0 via 172.17.0.1 200\"") + + dvs.servers[0].runcmd("ip addr add 10.10.10.1/31 dev eth0") + dvs.servers[0].runcmd("ifconfig eth0 up") + + time.sleep(5) + + print(dvs.runcmd("supervisorctl status")) + + p = dvs.servers[0].runcmd_async("exabgp -d bgp/files/default_route/default_route.conf") + + time.sleep(10) + + (exit_code, output) = dvs.runcmd(["redis-cli", "hgetall", "ROUTE_TABLE:0.0.0.0/0"]) + print(exit_code, output) + + # make sure 10.10.10.1 is the correct next hop for default route + assert "10.10.10.1" in output + + # insert default route for table default + dvs.runcmd("ip route add default via 172.17.0.1 table default") + + (exit_code, output) = dvs.runcmd(["redis-cli", "hgetall", "ROUTE_TABLE:0.0.0.0/0"]) + print(exit_code, output) + + time.sleep(10) + # make sure 10.10.10.1 is still the correct next hop for default route + assert "10.10.10.1" in output + + p.terminate() + p = p.wait() + + + diff --git a/platform/vs/tests/bgp/test_gr_livelock.py b/platform/vs/tests/bgp/test_gr_livelock.py index f269f1e8eee4..cd72ffef3e4f 100644 --- a/platform/vs/tests/bgp/test_gr_livelock.py +++ b/platform/vs/tests/bgp/test_gr_livelock.py @@ -6,7 +6,7 @@ import random def output(dvs, title): - print "=========================== %s ===========================" % title + print("=========================== %s ===========================" % title) exit_cod, sum_res = dvs.runcmd(["vtysh", "-c", "show ip bgp sum"]) exit_code, all_route = dvs.runcmd(["vtysh", "-c", "show ip bgp"]) exit_code, neig_1 = dvs.runcmd(["vtysh", "-c", "show ip bgp neighbors 10.0.0.1"]) @@ -14,22 +14,22 @@ def output(dvs, title): exit_code, received_route_1 = dvs.runcmd(["vtysh", "-c", "show ip bgp neighbors 10.0.0.1 routes"]) exit_code, announce_route_3 = dvs.runcmd(["vtysh", "-c", "show ip bgp neighbors 10.0.0.3 advertised-routes"]) exit_code, received_route_3 = dvs.runcmd(["vtysh", "-c", "show ip bgp neighbors 10.0.0.3 routes"]) - print "Summary:" - print sum_res - print "Received routes:" - print "10.0.0.1" - print received_route_1 - print "10.0.0.3" - print received_route_3 - print "Announces routes:" - print "10.0.0.1" - print announce_route_1 - print "10.0.0.3" - print announce_route_3 - print "Neighbors" - print "10.0.0.1" - print neig_1 - print "======================================================" + print("Summary:") + print(sum_res) + print("Received routes:") + print("10.0.0.1") + print(received_route_1) + print("10.0.0.3") + print(received_route_3) + print("Announces routes:") + print("10.0.0.1") + print(announce_route_1) + print("10.0.0.3") + print(announce_route_3) + print("Neighbors") + print("10.0.0.1") + print(neig_1) + print("======================================================") def mkdir(path): if not os.path.exists(path): @@ -66,11 +66,11 @@ def run_exa(dvs, idx, cfg): remove(fifo_out_path) os.mkfifo(fifo_in_path) os.mkfifo(fifo_out_path) - os.chmod(fifo_in_path, 0666) - os.chmod(fifo_out_path, 0666) - print "!!! Start exabgp instance %d" % idx + os.chmod(fifo_in_path, 0o666) + os.chmod(fifo_out_path, 0o666) + print("!!! Start exabgp instance %d" % idx) cmd = "exabgp -d --env %s %s" % (get_target_env(idx), cfg) - print "Cmd is ___ %s ___" % cmd + print("Cmd is ___ %s ___" % cmd) return dvs.servers[idx].runcmd_async(cmd) def run_exacli(dvs, idx, cmd): @@ -81,15 +81,14 @@ def test_gr_livelock(dvs, testlog): dvs.servers[0].runcmd("pip install 'exabgp==4.0.10' --force-reinstall ") # dvs.copy_file("/etc/frr/", "bgp/files/gr_livelock/bgpd.conf") - dvs.servers[0].runcmd("pkill exabgp") # In case previous test didn't stop exa dvs.runcmd("supervisorctl stop bgpd") time.sleep(5) dvs.runcmd("supervisorctl start bgpd") dvs.runcmd("ip addr add 10.0.0.0/31 dev Ethernet0") - dvs.runcmd("ifconfig Ethernet0 up") + dvs.runcmd("config interface startup Ethernet0") dvs.runcmd("ip addr add 10.0.0.2/31 dev Ethernet4") - dvs.runcmd("ifconfig Ethernet4 up") + dvs.runcmd("config interface startup Ethernet4") dvs.servers[0].runcmd("ip addr add 10.0.0.1/31 dev eth0") dvs.servers[0].runcmd("ifconfig eth0 up") diff --git a/platform/vs/tests/bgp/test_invalid_nexthop.py b/platform/vs/tests/bgp/test_invalid_nexthop.py index 021e3bfea002..3e8acd94e20d 100644 --- a/platform/vs/tests/bgp/test_invalid_nexthop.py +++ b/platform/vs/tests/bgp/test_invalid_nexthop.py @@ -10,14 +10,14 @@ def test_InvalidNexthop(dvs, testlog): dvs.copy_file("/etc/frr/", "bgp/files/invalid_nexthop/bgpd.conf") dvs.runcmd("supervisorctl start bgpd") dvs.runcmd("ip addr add fc00::1/126 dev Ethernet0") - dvs.runcmd("ifconfig Ethernet0 up") + dvs.runcmd("config interface startup Ethernet0") dvs.servers[0].runcmd("ip addr add fc00::2/126 dev eth0") dvs.servers[0].runcmd("ifconfig eth0 up") time.sleep(5) - print dvs.runcmd("supervisorctl status") + print(dvs.runcmd("supervisorctl status")) p = dvs.servers[0].runcmd_async("exabgp -d bgp/files/invalid_nexthop/invalid_nexthop.conf") @@ -28,6 +28,6 @@ def test_InvalidNexthop(dvs, testlog): p.terminate() p = p.wait() - print exit_code, output + print(exit_code, output) assert "3333::/64" in output diff --git a/platform/vs/tests/bgp/test_no_export.py b/platform/vs/tests/bgp/test_no_export.py index efbc5331fef8..b2c7c5e7cbde 100644 --- a/platform/vs/tests/bgp/test_no_export.py +++ b/platform/vs/tests/bgp/test_no_export.py @@ -5,14 +5,13 @@ import json def test_bounce(dvs, testlog): - dvs.servers[0].runcmd("pkill -f exabgp") dvs.copy_file("/etc/frr/", "bgp/files/no_export/bgpd.conf") dvs.runcmd("supervisorctl start bgpd") - dvs.runcmd("ip addr add 10.0.0.0/31 dev Ethernet0") - dvs.runcmd("ifconfig Ethernet0 up") + dvs.runcmd("ip addr add 10.0.0.0/31 dev Ethernet0") + dvs.runcmd("config interface startup Ethernet0") dvs.runcmd("ip addr add 10.0.0.2/31 dev Ethernet4") - dvs.runcmd("ifconfig Ethernet4 up") + dvs.runcmd("config interface startup Ethernet4") dvs.servers[0].runcmd("ip addr add 10.0.0.1/31 dev eth0") dvs.servers[0].runcmd("ifconfig eth0 up") @@ -30,15 +29,15 @@ def test_bounce(dvs, testlog): (exit_code, sum_res) = dvs.runcmd(["vtysh", "-c", "show ip bgp sum"]) (exit_code, all_route) = dvs.runcmd(["vtysh", "-c", "show ip bgp"]) (exit_code, announce_route) = dvs.runcmd(["vtysh", "-c", "show ip bgp neighbors 10.0.0.3 advertised-routes"]) - + p1.terminate() p1 = p1.wait() p2.terminate() p2 = p2.wait() - print sum_res - print announce_route + print(sum_res) + print(announce_route) assert "1.1.1.1/32" in all_route assert "1.1.1.1/32" not in announce_route assert "2.2.2.2/32" in all_route diff --git a/platform/vs/tests/breakout/sample_output/sample_new_port_config.json b/platform/vs/tests/breakout/sample_output/sample_new_port_config.json new file mode 100644 index 000000000000..7c5c190a3330 --- /dev/null +++ b/platform/vs/tests/breakout/sample_output/sample_new_port_config.json @@ -0,0 +1,252 @@ +{ + "Ethernet0_2x50G": { + "Ethernet2": { + "alias": "fortyGigE0/2", + "admin_status": "up", + "lanes": "27,28", + "speed": "50000", + "index": "0" + }, + "Ethernet0": { + "alias": "fortyGigE0/0", + "admin_status": "up", + "lanes": "25,26", + "speed": "50000", + "index": "0" + } + }, + "Ethernet12_1x50G_2x25G": { + "Ethernet12": { + "alias": "fortyGigE0/12", + "admin_status": "up", + "lanes": "37,38", + "speed": "50000", + "index": "3" + }, + "Ethernet14": { + "alias": "fortyGigE0/14", + "admin_status": "up", + "lanes": "39", + "speed": "25000", + "index": "3" + }, + "Ethernet15": { + "alias": "fortyGigE0/15", + "admin_status": "up", + "lanes": "40", + "speed": "25000", + "index": "3" + } + }, + "Ethernet0_2x50G": { + "Ethernet2": { + "alias": "fortyGigE0/2", + "admin_status": "up", + "lanes": "27,28", + "speed": "50000", + "index": "0" + }, + "Ethernet0": { + "alias": "fortyGigE0/0", + "admin_status": "up", + "lanes": "25,26", + "speed": "50000", + "index": "0" + } + }, + "Ethernet0_1x100G": { + "Ethernet0": { + "alias": "fortyGigE0/0", + "admin_status": "up", + "lanes": "25,26,27,28", + "speed": "100000", + "index": "0" + } + }, + "Ethernet0_4x25G": { + "Ethernet2": { + "alias": "fortyGigE0/2", + "admin_status": "up", + "lanes": "27", + "speed": "25000", + "index": "0" + }, + "Ethernet3": { + "alias": "fortyGigE0/3", + "admin_status": "up", + "lanes": "28", + "speed": "25000", + "index": "0" + }, + "Ethernet0": { + "alias": "fortyGigE0/0", + "admin_status": "up", + "lanes": "25", + "speed": "25000", + "index": "0" + }, + "Ethernet1": { + "alias": "fortyGigE0/1", + "admin_status": "up", + "lanes": "26", + "speed": "25000", + "index": "0" + } + }, + "Ethernet0_2x25G_1x50G": { + "Ethernet2": { + "alias": "fortyGigE0/2", + "admin_status": "up", + "lanes": "27,28", + "speed": "50000", + "index": "0" + }, + "Ethernet0": { + "alias": "fortyGigE0/0", + "admin_status": "up", + "lanes": "25", + "speed": "25000", + "index": "0" + }, + "Ethernet1": { + "alias": "fortyGigE0/1", + "admin_status": "up", + "lanes": "26", + "speed": "25000", + "index": "0" + } + }, + "Ethernet0_1x50G_2x25G": { + "Ethernet2": { + "alias": "fortyGigE0/2", + "admin_status": "up", + "lanes": "27", + "speed": "25000", + "index": "0" + }, + "Ethernet3": { + "alias": "fortyGigE0/3", + "admin_status": "up", + "lanes": "28", + "speed": "25000", + "index": "0" + }, + "Ethernet0": { + "alias": "fortyGigE0/0", + "admin_status": "up", + "lanes": "25,26", + "speed": "50000", + "index": "0" + } + }, + "Ethernet4_4x25G": { + "Ethernet6": { + "alias": "fortyGigE0/6", + "admin_status": "up", + "lanes": "31", + "speed": "25000", + "index": "1" + }, + "Ethernet7": { + "alias": "fortyGigE0/7", + "admin_status": "up", + "lanes": "32", + "speed": "25000", + "index": "1" + }, + "Ethernet4": { + "alias": "fortyGigE0/4", + "admin_status": "up", + "lanes": "29", + "speed": "25000", + "index": "1" + }, + "Ethernet5": { + "alias": "fortyGigE0/5", + "admin_status": "up", + "lanes": "30", + "speed": "25000", + "index": "1" + } + }, + "Ethernet4_2x50G": { + "Ethernet6": { + "alias": "fortyGigE0/6", + "admin_status": "up", + "lanes": "31,32", + "speed": "50000", + "index": "1" + }, + "Ethernet4": { + "alias": "fortyGigE0/4", + "admin_status": "up", + "lanes": "29,30", + "speed": "50000", + "index": "1" + } + }, + "Ethernet8_2x50G": { + "Ethernet8": { + "alias": "fortyGigE0/8", + "admin_status": "up", + "lanes": "33,34", + "speed": "50000", + "index": "2" + }, + "Ethernet10": { + "alias": "fortyGigE0/10", + "admin_status": "up", + "lanes": "35,36", + "speed": "50000", + "index": "2" + } + }, + "Ethernet8_1x50G_2x25G": { + "Ethernet10": { + "alias": "fortyGigE0/10", + "admin_status": "up", + "lanes": "35", + "speed": "25000", + "index": "2" + }, + "Ethernet11": { + "alias": "fortyGigE0/11", + "admin_status": "up", + "lanes": "36", + "speed": "25000", + "index": "2" + } + }, + "Ethernet8_2x25G_1x50G": { + "Ethernet8": { + "alias": "fortyGigE0/8", + "admin_status": "up", + "lanes": "33", + "speed": "25000", + "index": "2" + }, + "Ethernet9": { + "alias": "fortyGigE0/9", + "admin_status": "up", + "lanes": "34", + "speed": "25000", + "index": "2" + }, + "Ethernet10": { + "alias": "fortyGigE0/10", + "admin_status": "up", + "lanes": "35,36", + "speed": "50000", + "index": "2" + } + }, + "Ethernet8_1x100G": { + "Ethernet8": { + "alias": "fortyGigE0/8", + "admin_status": "up", + "lanes": "33,34,35,36", + "speed": "100000", + "index": "2" + } + } +} diff --git a/platform/vs/tests/breakout/test_breakout_cli.py b/platform/vs/tests/breakout/test_breakout_cli.py new file mode 100755 index 000000000000..d93dc0e044a6 --- /dev/null +++ b/platform/vs/tests/breakout/test_breakout_cli.py @@ -0,0 +1,168 @@ +from swsscommon import swsscommon +import time +import os +import json +import ast +import pytest +import collections + +@pytest.mark.usefixtures('dpb_setup_fixture') +class TestBreakoutCli(object): + def setup_db(self, dvs): + self.cdb = swsscommon.DBConnector(4, dvs.redis_sock, 0) + + def read_Json(self, dvs): + test_dir = os.path.dirname(os.path.realpath(__file__)) + sample_output_file = os.path.join(test_dir, 'sample_output', 'sample_new_port_config.json') + with open(sample_output_file, 'rb') as fh: + fh_data = json.load(fh) + + if not fh_data: + return False + expected = ast.literal_eval(json.dumps(fh_data)) + return expected + + def breakout(self, dvs, interface, brkout_mode): + (exitcode, result) = dvs.runcmd("config interface breakout {} {} -y".format(interface, brkout_mode)) + + if result.strip("\n")[0] == "[ERROR] Breakout feature is not available without platform.json file" : + pytest.skip("**** This test is not needed ****") + root_dir = os.path.dirname('/') + (exitcode, output_dict) = dvs.runcmd("jq '.' new_port_config.json") + if output_dict is None: + raise Exception("Breakout output cant be None") + + output_dict = ast.literal_eval(output_dict.strip()) + return output_dict + + # Check Initial Brakout Mode + def test_InitialBreakoutMode(self, dvs, testlog): + self.setup_db(dvs) + + output_dict = {} + brkoutTbl = swsscommon.Table(self.cdb, "BREAKOUT_CFG") + brkout_entries = brkoutTbl.getKeys() + assert len(brkout_entries) == 32 + + for key in brkout_entries: + (status, fvs) = brkoutTbl.get(key) + assert status + + brkout_mode = fvs[0][1] + output_dict[key] = brkout_mode + output = collections.OrderedDict(sorted(output_dict.items(), key=lambda t: t[0])) + expected_dict = \ + {'Ethernet8': '1x100G[40G]', 'Ethernet0': '1x100G[40G]', 'Ethernet4': '1x100G[40G]', \ + 'Ethernet108': '1x100G[40G]', 'Ethernet100': '1x100G[40G]', 'Ethernet104': '1x100G[40G]', \ + 'Ethernet68': '1x100G[40G]', 'Ethernet96': '1x100G[40G]', 'Ethernet124': '1x100G[40G]', \ + 'Ethernet92': '1x100G[40G]', 'Ethernet120': '1x100G[40G]', 'Ethernet52': '1x100G[40G]', \ + 'Ethernet56': '1x100G[40G]', 'Ethernet76': '1x100G[40G]', 'Ethernet72': '1x100G[40G]', \ + 'Ethernet32': '1x100G[40G]', 'Ethernet16': '1x100G[40G]', 'Ethernet36': '1x100G[40G]', \ + 'Ethernet12': '1x100G[40G]', 'Ethernet28': '1x100G[40G]', 'Ethernet88': '1x100G[40G]', \ + 'Ethernet116': '1x100G[40G]', 'Ethernet80': '1x100G[40G]', 'Ethernet112': '1x100G[40G]', \ + 'Ethernet84': '1x100G[40G]', 'Ethernet48': '1x100G[40G]', 'Ethernet44': '1x100G[40G]', \ + 'Ethernet40': '1x100G[40G]', 'Ethernet64': '1x100G[40G]', 'Ethernet60': '1x100G[40G]', \ + 'Ethernet20': '1x100G[40G]', 'Ethernet24': '1x100G[40G]'} + expected = collections.OrderedDict(sorted(expected_dict.items(), key=lambda t: t[0])) + assert output == expected + + # Breakout Cli Test Mode + def test_breakout_modes(self, dvs): + expected = self.read_Json(dvs) + assert expected + + print("**** Breakout Cli test Starts ****") + output_dict = self.breakout(dvs, 'Ethernet0', '2x50G') + expected_dict = expected["Ethernet0_2x50G"] + assert output_dict == expected_dict + print("**** 1X100G --> 2x50G passed ****") + + output_dict = self.breakout(dvs, 'Ethernet4', '4x25G[10G]') + expected_dict = expected["Ethernet4_4x25G"] + assert output_dict == expected_dict + print("**** 1X100G --> 4x25G[10G] passed ****") + + output_dict = self.breakout(dvs, 'Ethernet8', '2x25G(2)+1x50G(2)') + expected_dict = expected["Ethernet8_2x25G_1x50G"] + assert output_dict == expected_dict + print("**** 1X100G --> 2x25G(2)+1x50G(2) passed ****") + + output_dict = self.breakout(dvs, 'Ethernet12', '1x50G(2)+2x25G(2)') + expected_dict = expected["Ethernet12_1x50G_2x25G"] + assert output_dict == expected_dict + print("**** 1X100G --> 1x50G(2)+2x25G(2) passed ****") + + # TODOFIX: remove comments once #4442 PR got merged and + # yang model for DEVICE_METADATA becomes available. + # As below test cases are dependent on DEVICE_METADATA to go + # from a non-default breakout mode to a different breakout mode. + """ + output_dict = self.breakout(dvs, 'Ethernet0', '1x100G[40G]') + expected_dict = expected["Ethernet0_1x100G"] + assert output_dict == expected_dict + print("**** 2x50G --> 1x100G[40G] passed ****") + + output_dict = self.breakout(dvs, 'Ethernet0', '4x25G[10G]') + expected_dict = expected["Ethernet0_4x25G"] + assert output_dict == expected_dict + print("**** 1X100G --> 4x25G[10G] passed ****") + + output_dict = self.breakout(dvs, 'Ethernet0', '1x100G[40G]') + expected_dict = expected["Ethernet0_1x100G"] + assert output_dict == expected_dict + print("**** 4x25G[10G] --> 1x100G[40G] passed ****") + + output_dict = self.breakout(dvs, 'Ethernet4', '2x50G') + print("**** 1X100G --> 2x50G mode change ****") + + output_dict = self.breakout(dvs, 'Ethernet4', '4x25G[10G]') + expected_dict = expected["Ethernet4_4x25G"] + assert output_dict == expected_dict + print("**** 2X50G --> 4x25G[10G] passed ****") + + output_dict = self.breakout(dvs, 'Ethernet4', '2x50G') + expected_dict = expected["Ethernet4_2x50G"] + assert output_dict == expected_dict + print("**** 4x25G[10G] --> 2X50G passed ****") + + output_dict = self.breakout(dvs, 'Ethernet4', '1x100G[40G]') + print("**** 2x50G -- > 1X100G mode change ****") + + output_dict = self.breakout(dvs, 'Ethernet0', '2x25G(2)+1x50G(2)') + expected_dict = expected["Ethernet0_2x25G_1x50G"] + assert output_dict == expected_dict + print("**** 1x100G[40G] --> 2x25G(2)+1x50G(2) passed ****") + + output_dict = self.breakout(dvs, 'Ethernet0', '1x100G[40G]') + expected_dict = expected["Ethernet0_1x100G"] + assert output_dict == expected_dict + print("**** 2x25G(2)+1x50G(2) --> 1x100G[40G] passed ****") + + output_dict = self.breakout(dvs, 'Ethernet0', '1x50G(2)+2x25G(2)') + expected_dict = expected["Ethernet0_1x50G_2x25G"] + assert output_dict == expected_dict + print("**** 1x100G[40G] --> 1x50G(2)+2x25G(2) passed ****") + + output_dict = self.breakout(dvs, 'Ethernet0', '1x100G[40G]') + expected_dict = expected["Ethernet0_1x100G"] + assert output_dict == expected_dict + print("**** 1x50G(2)+2x25G(2) --> 1x100G[40G] passed ****") + + output_dict = self.breakout(dvs, 'Ethernet8', '2x50G') + print("**** 1x100G[40G] --> 2x50G mode change ****") + + output_dict = self.breakout(dvs, 'Ethernet8', '1x50G(2)+2x25G(2)') + expected_dict = expected["Ethernet8_1x50G_2x25G"] + assert output_dict == expected_dict + print("**** 2x50G --> 2x25G(2)+1x50G(2) passed ****") + + output_dict = self.breakout(dvs, 'Ethernet8', '2x25G(2)+1x50G(2)') + expected_dict = expected["Ethernet8_2x25G_1x50G"] + assert output_dict == expected_dict + print("**** 1x50G(2)+2x25G(2) --> 2x25G(2)+1x50G(2) passed ****") + + output_dict = self.breakout(dvs, 'Ethernet8', '1x100G[40G]') + expected_dict = expected["Ethernet8_1x100G"] + assert output_dict == expected_dict + print("**** 2x25G(2)+1x50G(2) --> 1x100G[40G] passed ****") + """ diff --git a/platform/vs/tests/dvslib b/platform/vs/tests/dvslib new file mode 120000 index 000000000000..4bab298a1800 --- /dev/null +++ b/platform/vs/tests/dvslib @@ -0,0 +1 @@ +../../../src/sonic-swss/tests/dvslib \ No newline at end of file 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" + diff --git a/rules/asyncsnmp-py3.mk b/rules/asyncsnmp-py3.mk index cc0af244d856..2592eb004ee8 100644 --- a/rules/asyncsnmp-py3.mk +++ b/rules/asyncsnmp-py3.mk @@ -5,4 +5,5 @@ $(ASYNCSNMP_PY3)_SRC_PATH = $(SRC_PATH)/sonic-snmpagent $(ASYNCSNMP_PY3)_PYTHON_VERSION = 3 # Depends on sonic-platform-common so it is possible to import sonic_psu $(ASYNCSNMP_PY3)_DEPENDS += $(SWSSSDK_PY3) $(SONIC_PLATFORM_COMMON_PY3) +$(ASYNCSNMP_PY3)_DEBS_DEPENDS += $(LIBSWSSCOMMON) $(PYTHON3_SWSSCOMMON) SONIC_PYTHON_WHEELS += $(ASYNCSNMP_PY3) diff --git a/rules/config b/rules/config index e319ff7fd5a9..433bbeedebf0 100644 --- a/rules/config +++ b/rules/config @@ -16,6 +16,10 @@ SONIC_CONFIG_BUILD_JOBS = 1 # Corresponding -j argument will be passed to make/dpkg commands that build separate packages SONIC_CONFIG_MAKE_JOBS = $(shell nproc) +# DEFAULT_BUILD_LOG_TIMESTAMP - add timestamp in build log +# Supported format: simple, none +DEFAULT_BUILD_LOG_TIMESTAMP = none + # SONIC_USE_DOCKER_BUILDKIT - use docker buildkit for build. # If set to y SONiC build system will set environment variable DOCKER_BUILDKIT=1 # to enable docker buildkit. @@ -59,6 +63,10 @@ DEFAULT_PASSWORD = YourPaSsWoRd # Uncomment next line to enable: # INSTALL_DEBUG_TOOLS = y +# SONIC_USE_PDDF_FRAMEWORK - Use PDDF generic drivers and plugins +# Uncomment next line to enable: +SONIC_USE_PDDF_FRAMEWORK = y + # SONIC_ROUTING_STACK - specify the routing-stack being elected to drive SONiC's control-plane. # Supported routing stacks on SONiC are: # routing-stacks: quagga, frr. @@ -79,9 +87,6 @@ ENABLE_ORGANIZATION_EXTENSIONS = y #SONIC_DEBUGGING_ON = y #SONIC_PROFILING_ON = y -# ENABLE_SYSTEM_TELEMETRY - build docker-sonic-telemetry for system telemetry support -ENABLE_SYSTEM_TELEMETRY = y - # DEFAULT_KERNEL_PROCURE_METHOD - default method for obtaining kernel # build: build kernel from source # download: download pre-built kernel from Azure storage. @@ -111,14 +116,73 @@ SONIC_DPKG_CACHE_SOURCE ?= /var/cache/sonic/artifacts # Default VS build memory preparation DEFAULT_VS_PREPARE_MEM = yes -# ENABLE_SYSTEM_SFLOW - build docker-sonic-sflow for sFlow support -ENABLE_SFLOW = y -# ENABLE_MGMT_FRAMEWORK - build docker-sonic-mgt-framework for CLI and REST server support -ENABLE_MGMT_FRAMEWORK = y +# INCLUDE_SYSTEM_TELEMETRY - build docker-sonic-telemetry for system telemetry support +INCLUDE_SYSTEM_TELEMETRY = y + +# INCLUDE_ICCPD - build docker-iccpd for mclag support +INCLUDE_ICCPD = n -# ENABLE_RESTAPI - build docker-sonic-restapi for configuring the switch using REST APIs -ENABLE_RESTAPI = n +# INCLUDE_SFLOW - build docker-sflow for sFlow support +INCLUDE_SFLOW = y -# ENABLE_NAT - build docker-sonic-nat for nat support -ENABLE_NAT = y +# INCLUDE_MGMT_FRAMEWORK - build docker-sonic-mgmt-framework for CLI and REST server support +INCLUDE_MGMT_FRAMEWORK = y + +# ENABLE_HOST_SERVICE_ON_START - enable sonic-host-server for mgmt-framework and/or +# telemetry containers to access host functionality by default +ENABLE_HOST_SERVICE_ON_START = n + +# INCLUDE_RESTAPI - build docker-sonic-restapi for configuring the switch using REST APIs +INCLUDE_RESTAPI = n + +# INCLUDE_NAT - build docker-nat for nat support +INCLUDE_NAT = y + +# TELEMETRY_WRITABLE - Enable write/config operations via the gNMI interface. +# Uncomment to enable: +# TELEMETRY_WRITABLE = y +# INCLUDE_KUBERNETES - if set to y kubernetes packages are installed to be able to +# run as worker node in kubernetes cluster. +INCLUDE_KUBERNETES = n + +# KUBERNETES_VERSION - Set to the required version. +# K8s_GCR_IO_PAUSE_VERSION - Version of k8s universal pause container image +# These are Used *only* when INCLUDE_KUBERNETES=y +# NOTE: As a worker node it has to run version compatible to kubernetes master. +# +KUBERNETES_VERSION = 1.18.6 +KUBERNETES_CNI_VERSION = 0.8.6 +K8s_GCR_IO_PAUSE_VERSION = 3.2 + +# SONIC_ENABLE_IMAGE_SIGNATURE - enable image signature +# To not use the auto-generated self-signed certificate, the required files to sign the image as below: +# SIGNING_KEY = +# SIGNING_CERT = +# CA_CERT = +# The relative path is build root folder. +SONIC_ENABLE_IMAGE_SIGNATURE ?= n + +# PACKAGE_URL_PREFIX - the package url prefix +PACKAGE_URL_PREFIX ?= https://packages.trafficmanager.net/public/packages + +# TRUSTED_GPG_URLS - the trusted gpgs, separated by comma +TRUSTED_GPG_URLS = https://packages.trafficmanager.net/debian/public_key.gpg,https://packages.microsoft.com/keys/microsoft.asc + +# SONIC_VERSION_CONTROL_COMPONENTS - Valid values: none|all|components..., the components consist of one or multiple: deb,py2,py3,web,git,docker, seperated by comma +# none : disable the version control +# all : enable the version control for all components +# deb : debian packages +# py2 : python2 packages +# py3 : python3 pakcages +# web : web packages, downloaded by wget, curl +# git : git repositories, donloaded by git clone +# docker: docker base images +SONIC_VERSION_CONTROL_COMPONENTS ?= none + +# SONiC docker registry +# +# Uncomment below line to enable pulling sonic-slave docker from registry +# ENABLE_DOCKER_BASE_PULL = y +REGISTRY_PORT=443 +REGISTRY_SERVER=sonicdev-microsoft.azurecr.io diff --git a/rules/dbsyncd-py2.dep b/rules/dbsyncd-py2.dep deleted file mode 100644 index 6ca1ab8dd786..000000000000 --- a/rules/dbsyncd-py2.dep +++ /dev/null @@ -1,12 +0,0 @@ - -SPATH := $($(DBSYNCD_PY2)_SRC_PATH) -DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/dbsyncd-py2.mk rules/dbsyncd-py2.dep -DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) -SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) - -$(DBSYNCD_PY2)_CACHE_MODE := GIT_CONTENT_SHA -$(DBSYNCD_PY2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) -$(DBSYNCD_PY2)_DEP_FILES := $(DEP_FILES) -$(DBSYNCD_PY2)_SMDEP_FILES := $(SMDEP_FILES) -$(DBSYNCD_PY2)_SMDEP_PATHS := $(SPATH) - diff --git a/rules/dbsyncd-py2.mk b/rules/dbsyncd-py2.mk deleted file mode 100644 index 220dc5fe7a1d..000000000000 --- a/rules/dbsyncd-py2.mk +++ /dev/null @@ -1,7 +0,0 @@ -# sonic-dbsyncd python2 wheel - -DBSYNCD_PY2 = sonic_d-2.0.0-py2-none-any.whl -$(DBSYNCD_PY2)_SRC_PATH = $(SRC_PATH)/sonic-dbsyncd -$(DBSYNCD_PY2)_PYTHON_VERSION = 2 -$(DBSYNCD_PY2)_DEPENDS += $(SWSSSDK_PY2) -SONIC_PYTHON_WHEELS += $(DBSYNCD_PY2) diff --git a/rules/dbsyncd-py3.dep b/rules/dbsyncd-py3.dep new file mode 100644 index 000000000000..42a31c2c4972 --- /dev/null +++ b/rules/dbsyncd-py3.dep @@ -0,0 +1,11 @@ +SPATH := $($(DBSYNCD_PY3)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/dbsyncd-py3.mk rules/dbsyncd-py3.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) + +$(DBSYNCD_PY3)_CACHE_MODE := GIT_CONTENT_SHA +$(DBSYNCD_PY3)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DBSYNCD_PY3)_DEP_FILES := $(DEP_FILES) +$(DBSYNCD_PY3)_SMDEP_FILES := $(SMDEP_FILES) +$(DBSYNCD_PY3)_SMDEP_PATHS := $(SPATH) + diff --git a/rules/dbsyncd-py3.mk b/rules/dbsyncd-py3.mk new file mode 100644 index 000000000000..12cf13cafe3b --- /dev/null +++ b/rules/dbsyncd-py3.mk @@ -0,0 +1,8 @@ +# sonic-dbsyncd python3 wheel + +DBSYNCD_PY3 = sonic_d-2.0.0-py3-none-any.whl +$(DBSYNCD_PY3)_SRC_PATH = $(SRC_PATH)/sonic-dbsyncd +$(DBSYNCD_PY3)_PYTHON_VERSION = 3 +$(DBSYNCD_PY3)_DEPENDS += $(SWSSSDK_PY3) +$(DBSYNCD_PY3)_DEBS_DEPENDS += $(LIBSWSSCOMMON) $(PYTHON3_SWSSCOMMON) +SONIC_PYTHON_WHEELS += $(DBSYNCD_PY3) diff --git a/rules/docker-base-buster.dep b/rules/docker-base-buster.dep new file mode 100644 index 000000000000..2cfd2403f7fe --- /dev/null +++ b/rules/docker-base-buster.dep @@ -0,0 +1,10 @@ + +DPATH := $($(DOCKER_BASE_BUSTER)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-base-buster.mk rules/docker-base-buster.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_BASE_BUSTER)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_BASE_BUSTER)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_BASE_BUSTER)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/docker-base-buster.mk b/rules/docker-base-buster.mk new file mode 100644 index 000000000000..86bfc5781466 --- /dev/null +++ b/rules/docker-base-buster.mk @@ -0,0 +1,16 @@ +# Docker base image (based on Debian Buster) + +DOCKER_BASE_BUSTER = docker-base-buster.gz +$(DOCKER_BASE_BUSTER)_PATH = $(DOCKERS_PATH)/docker-base-buster + +$(DOCKER_BASE_BUSTER)_DEPENDS += $(SOCAT) + +GDB = gdb +GDBSERVER = gdbserver +VIM = vim +OPENSSH = openssh-client +SSHPASS = sshpass +STRACE = strace +$(DOCKER_BASE_BUSTER)_DBG_IMAGE_PACKAGES += $(GDB) $(GDBSERVER) $(VIM) $(OPENSSH) $(SSHPASS) $(STRACE) + +SONIC_DOCKER_IMAGES += $(DOCKER_BASE_BUSTER) diff --git a/rules/docker-base-stretch.mk b/rules/docker-base-stretch.mk index a54f4ec092aa..de10f808286e 100644 --- a/rules/docker-base-stretch.mk +++ b/rules/docker-base-stretch.mk @@ -2,7 +2,6 @@ DOCKER_BASE_STRETCH = docker-base-stretch.gz $(DOCKER_BASE_STRETCH)_PATH = $(DOCKERS_PATH)/docker-base-stretch -$(DOCKER_BASE_STRETCH)_DEPENDS += $(SUPERVISOR) $(REDIS_TOOLS) $(DOCKER_BASE_STRETCH)_DEPENDS += $(SOCAT) GDB = gdb diff --git a/rules/docker-base.mk b/rules/docker-base.mk index 2d0653fc8f71..3b2ede987a70 100644 --- a/rules/docker-base.mk +++ b/rules/docker-base.mk @@ -2,7 +2,6 @@ DOCKER_BASE = docker-base.gz $(DOCKER_BASE)_PATH = $(DOCKERS_PATH)/docker-base -$(DOCKER_BASE)_DEPENDS += $(SUPERVISOR) $(DOCKER_BASE)_DEPENDS += $(BASH) $(DOCKER_BASE)_DEPENDS += $(SOCAT) diff --git a/rules/docker-config-engine-buster.dep b/rules/docker-config-engine-buster.dep new file mode 100644 index 000000000000..ae1ec40ccc9e --- /dev/null +++ b/rules/docker-config-engine-buster.dep @@ -0,0 +1,10 @@ + +DPATH := $($(DOCKER_CONFIG_ENGINE_BUSTER)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-config-engine-buster.mk rules/docker-config-engine-buster.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_CONFIG_ENGINE_BUSTER)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_CONFIG_ENGINE_BUSTER)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_CONFIG_ENGINE_BUSTER)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/docker-config-engine-buster.mk b/rules/docker-config-engine-buster.mk new file mode 100644 index 000000000000..b386c882f4c5 --- /dev/null +++ b/rules/docker-config-engine-buster.mk @@ -0,0 +1,17 @@ +# docker image for sonic config engine + +DOCKER_CONFIG_ENGINE_BUSTER = docker-config-engine-buster.gz +$(DOCKER_CONFIG_ENGINE_BUSTER)_PATH = $(DOCKERS_PATH)/docker-config-engine-buster + +$(DOCKER_CONFIG_ENGINE_BUSTER)_DEPENDS += $(LIBSWSSCOMMON) $(PYTHON3_SWSSCOMMON) +$(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SWSSSDK_PY3) +$(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY3) +$(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE_PY3) +$(DOCKER_CONFIG_ENGINE_BUSTER)_LOAD_DOCKERS += $(DOCKER_BASE_BUSTER) +$(DOCKER_CONFIG_ENGINE_BUSTER)_FILES += $(SWSS_VARS_TEMPLATE) +$(DOCKER_CONFIG_ENGINE_BUSTER)_FILES += $($(SONIC_CTRMGRD)_CONTAINER_SCRIPT) + +$(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS = $($(DOCKER_BASE_BUSTER)_DBG_DEPENDS) +$(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES = $($(DOCKER_BASE_BUSTER)_DBG_IMAGE_PACKAGES) + +SONIC_DOCKER_IMAGES += $(DOCKER_CONFIG_ENGINE_BUSTER) diff --git a/rules/docker-config-engine-stretch.mk b/rules/docker-config-engine-stretch.mk index 2a1e36d28833..7e90c1587a9d 100644 --- a/rules/docker-config-engine-stretch.mk +++ b/rules/docker-config-engine-stretch.mk @@ -2,9 +2,12 @@ DOCKER_CONFIG_ENGINE_STRETCH = docker-config-engine-stretch.gz $(DOCKER_CONFIG_ENGINE_STRETCH)_PATH = $(DOCKERS_PATH)/docker-config-engine-stretch +$(DOCKER_CONFIG_ENGINE_STRETCH)_DEPENDS += $(LIBSWSSCOMMON) $(PYTHON_SWSSCOMMON) $(DOCKER_CONFIG_ENGINE_STRETCH)_PYTHON_WHEELS += $(SWSSSDK_PY2) -$(DOCKER_CONFIG_ENGINE_STRETCH)_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE) +$(DOCKER_CONFIG_ENGINE_STRETCH)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY2) +$(DOCKER_CONFIG_ENGINE_STRETCH)_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE_PY2) $(DOCKER_CONFIG_ENGINE_STRETCH)_LOAD_DOCKERS += $(DOCKER_BASE_STRETCH) +$(DOCKER_CONFIG_ENGINE_STRETCH)_FILES += $(SWSS_VARS_TEMPLATE) $(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS = $($(DOCKER_BASE_STRETCH)_DBG_DEPENDS) $(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES = $($(DOCKER_BASE_STRETCH)_DBG_IMAGE_PACKAGES) diff --git a/rules/docker-config-engine.mk b/rules/docker-config-engine.mk index f540bb66f350..518e73415a6b 100644 --- a/rules/docker-config-engine.mk +++ b/rules/docker-config-engine.mk @@ -3,6 +3,8 @@ DOCKER_CONFIG_ENGINE = docker-config-engine.gz $(DOCKER_CONFIG_ENGINE)_PATH = $(DOCKERS_PATH)/docker-config-engine $(DOCKER_CONFIG_ENGINE)_PYTHON_WHEELS += $(SWSSSDK_PY2) -$(DOCKER_CONFIG_ENGINE)_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE) +$(DOCKER_CONFIG_ENGINE)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY2) +$(DOCKER_CONFIG_ENGINE)_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE_PY2) $(DOCKER_CONFIG_ENGINE)_LOAD_DOCKERS += $(DOCKER_BASE) +$(DOCKER_CONFIG_ENGINE)_FILES += $(SWSS_VARS_TEMPLATE) SONIC_DOCKER_IMAGES += $(DOCKER_CONFIG_ENGINE) diff --git a/rules/docker-database.mk b/rules/docker-database.mk index 7e372048afab..0a2f46d19223 100644 --- a/rules/docker-database.mk +++ b/rules/docker-database.mk @@ -6,21 +6,17 @@ DOCKER_DATABASE_DBG = $(DOCKER_DATABASE_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_DATABASE)_PATH = $(DOCKERS_PATH)/$(DOCKER_DATABASE_STEM) -$(DOCKER_DATABASE)_DEPENDS += $(REDIS_TOOLS) $(REDIS_SERVER) -$(DOCKER_DATABASE)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) -$(DOCKER_DATABASE)_DBG_DEPENDS += $(REDIS_TOOLS_DBG) +$(DOCKER_DATABASE)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) -$(DOCKER_DATABASE)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) +$(DOCKER_DATABASE)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) -$(DOCKER_DATABASE)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) +$(DOCKER_DATABASE)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) SONIC_DOCKER_IMAGES += $(DOCKER_DATABASE) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_DATABASE) -SONIC_STRETCH_DOCKERS += $(DOCKER_DATABASE) SONIC_DOCKER_DBG_IMAGES += $(DOCKER_DATABASE_DBG) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_DATABASE_DBG) -SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_DATABASE_DBG) $(DOCKER_DATABASE)_CONTAINER_NAME = database $(DOCKER_DATABASE)_RUN_OPT += --privileged -t @@ -28,4 +24,5 @@ $(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) +$(DOCKER_DATABASE)_FILES += $(SYSCTL_NET_CONFIG) $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) +$(DOCKER_DATABASE)_FILES += $(UPDATE_CHASSISDB_CONFIG_SCRIPT) diff --git a/rules/docker-dhcp-relay.mk b/rules/docker-dhcp-relay.mk index 4c044d5e05a0..6be9bb79fda4 100644 --- a/rules/docker-dhcp-relay.mk +++ b/rules/docker-dhcp-relay.mk @@ -6,23 +6,23 @@ 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) $(SONIC_DHCPMON) -$(DOCKER_DHCP_RELAY)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) +$(DOCKER_DHCP_RELAY)_DEPENDS += $(ISC_DHCP_RELAY) $(SONIC_DHCPMON) + +$(DOCKER_DHCP_RELAY)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) $(DOCKER_DHCP_RELAY)_DBG_DEPENDS += $(ISC_DHCP_RELAY_DBG) -$(DOCKER_DHCP_RELAY)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) +$(DOCKER_DHCP_RELAY)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) -$(DOCKER_DHCP_RELAY)_LOAD_DOCKERS = $(DOCKER_CONFIG_ENGINE_STRETCH) +$(DOCKER_DHCP_RELAY)_LOAD_DOCKERS = $(DOCKER_CONFIG_ENGINE_BUSTER) SONIC_DOCKER_IMAGES += $(DOCKER_DHCP_RELAY) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_DHCP_RELAY) -SONIC_STRETCH_DOCKERS += $(DOCKER_DHCP_RELAY) SONIC_DOCKER_DBG_IMAGES += $(DOCKER_DHCP_RELAY_DBG) 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 += --privileged -t $(DOCKER_DHCP_RELAY)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_DHCP_RELAY)_RUN_OPT += -v /usr/share/sonic/scripts:/usr/share/sonic/scripts: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 517aff3ea9fc..1ea79bc80a42 100644 --- a/rules/docker-fpm-frr.mk +++ b/rules/docker-fpm-frr.mk @@ -5,26 +5,24 @@ DOCKER_FPM_FRR = $(DOCKER_FPM_FRR_STEM).gz DOCKER_FPM_FRR_DBG = $(DOCKER_FPM_FRR_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_FPM_FRR)_PATH = $(DOCKERS_PATH)/$(DOCKER_FPM_FRR_STEM) +$(DOCKER_FPM_FRR)_PYTHON_WHEELS += $(SONIC_BGPCFGD) $(SONIC_FRR_MGMT_FRAMEWORK) -$(DOCKER_FPM_FRR)_DEPENDS += $(FRR) $(FRR_SNMP) $(SWSS) $(LIBYANG) -$(DOCKER_FPM_FRR)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) +$(DOCKER_FPM_FRR)_DEPENDS += $(FRR) $(FRR_SNMP) $(SWSS) $(LIBYANG1) +$(DOCKER_FPM_FRR)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) $(DOCKER_FPM_FRR)_DBG_DEPENDS += $(SWSS_DBG) $(LIBSWSSCOMMON_DBG) \ - $(FRR_DBG) $(FRR_SNMP_DBG) $(LIBYANG_DBG) + $(FRR_DBG) $(FRR_SNMP_DBG) $(LIBYANG1_DBG) -$(DOCKER_FPM_FRR)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) +$(DOCKER_FPM_FRR)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) -$(DOCKER_FPM_FRR)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) +$(DOCKER_FPM_FRR)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) SONIC_DOCKER_IMAGES += $(DOCKER_FPM_FRR) -SONIC_STRETCH_DOCKERS += $(DOCKER_FPM_FRR) 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 += --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) @@ -32,4 +30,5 @@ $(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 += TS:/usr/bin/TS $(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += monit_bgp:/etc/monit/conf.d diff --git a/rules/docker-iccpd.dep b/rules/docker-iccpd.dep new file mode 100644 index 000000000000..878d1711c3b1 --- /dev/null +++ b/rules/docker-iccpd.dep @@ -0,0 +1,11 @@ + +DPATH := $($(DOCKER_ICCPD)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-iccpd.mk rules/docker-iccpd.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_ICCPD)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_ICCPD)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_ICCPD)_DEP_FILES := $(DEP_FILES) + +$(eval $(call add_dbg_docker,$(DOCKER_ICCPD),$(DOCKER_ICCPD_DBG))) diff --git a/rules/docker-iccpd.mk b/rules/docker-iccpd.mk new file mode 100644 index 000000000000..da77d9c9c1fd --- /dev/null +++ b/rules/docker-iccpd.mk @@ -0,0 +1,24 @@ +# docker image for iccpd agent + +DOCKER_ICCPD_STEM = docker-iccpd +DOCKER_ICCPD = $(DOCKER_ICCPD_STEM).gz +DOCKER_ICCPD_DBG = $(DOCKER_ICCPD_STEM)-$(DBG_IMAGE_MARK).gz +$(DOCKER_ICCPD)_PATH = $(DOCKERS_PATH)/$(DOCKER_ICCPD_STEM) +$(DOCKER_ICCPD)_DEPENDS += $(SWSS) $(ICCPD) +$(DOCKER_ICCPD)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) +$(DOCKER_ICCPD)_DBG_DEPENDS += $(SWSS_DBG) $(LIBSWSSCOMMON_DBG) $(ICCPD_DBG) +$(DOCKER_ICCPD)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) +$(DOCKER_ICCPD)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) + +ifeq ($(INCLUDE_ICCPD), y) +SONIC_DOCKER_IMAGES += $(DOCKER_ICCPD) +SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_ICCPD) +SONIC_DOCKER_DBG_IMAGES += $(DOCKER_ICCPD_DBG) +SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_ICCPD_DBG) +endif + +$(DOCKER_ICCPD)_CONTAINER_NAME = iccpd +$(DOCKER_ICCPD)_RUN_OPT += --privileged -t +$(DOCKER_ICCPD)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro + +$(DOCKER_ICCPD)_BASE_IMAGE_FILES += mclagdctl:/usr/bin/mclagdctl diff --git a/rules/docker-lldp-sv2.dep b/rules/docker-lldp-sv2.dep deleted file mode 100644 index 185d85032d49..000000000000 --- a/rules/docker-lldp-sv2.dep +++ /dev/null @@ -1,11 +0,0 @@ - -DPATH := $($(DOCKER_LLDP_SV2)_PATH) -DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-lldp-sv2.mk rules/docker-lldp-sv2.dep -DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) -DEP_FILES += $(shell git ls-files $(DPATH)) - -$(DOCKER_LLDP_SV2)_CACHE_MODE := GIT_CONTENT_SHA -$(DOCKER_LLDP_SV2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) -$(DOCKER_LLDP_SV2)_DEP_FILES := $(DEP_FILES) - -$(eval $(call add_dbg_docker,$(DOCKER_LLDP_SV2),$(DOCKER_LLDP_SV2_DBG))) diff --git a/rules/docker-lldp-sv2.mk b/rules/docker-lldp-sv2.mk deleted file mode 100644 index a39b307d5063..000000000000 --- a/rules/docker-lldp-sv2.mk +++ /dev/null @@ -1,34 +0,0 @@ -# docker image for lldp agent - -DOCKER_LLDP_SV2_STEM = docker-lldp-sv2 -DOCKER_LLDP_SV2 = $(DOCKER_LLDP_SV2_STEM).gz -DOCKER_LLDP_SV2_DBG = $(DOCKER_LLDP_SV2_STEM)-$(DBG_IMAGE_MARK).gz - -$(DOCKER_LLDP_SV2)_PATH = $(DOCKERS_PATH)/docker-lldp-sv2 - -$(DOCKER_LLDP_SV2)_DEPENDS += $(LLDPD) $(LIBSWSSCOMMON) $(PYTHON_SWSSCOMMON) - -$(DOCKER_LLDP_SV2)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) -$(DOCKER_LLDP_SV2)_DBG_DEPENDS += $(LLDPD_DBG) $(LIBSWSSCOMMON_DBG) - -$(DOCKER_LLDP_SV2)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) - -$(DOCKER_LLDP_SV2)_PYTHON_WHEELS += $(DBSYNCD_PY2) -$(DOCKER_LLDP_SV2)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) - -SONIC_DOCKER_IMAGES += $(DOCKER_LLDP_SV2) -SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_LLDP_SV2) -SONIC_STRETCH_DOCKERS += $(DOCKER_LLDP_SV2) - -SONIC_DOCKER_DBG_IMAGES += $(DOCKER_LLDP_SV2_DBG) -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 += --privileged -t -$(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-lldp.dep b/rules/docker-lldp.dep new file mode 100644 index 000000000000..ee7935ea9222 --- /dev/null +++ b/rules/docker-lldp.dep @@ -0,0 +1,11 @@ + +DPATH := $($(DOCKER_LLDP)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-lldp.mk rules/docker-lldp.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_LLDP)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_LLDP)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_LLDP)_DEP_FILES := $(DEP_FILES) + +$(eval $(call add_dbg_docker,$(DOCKER_LLDP),$(DOCKER_LLDP_DBG))) diff --git a/rules/docker-lldp.mk b/rules/docker-lldp.mk new file mode 100644 index 000000000000..5cd4fd02a04f --- /dev/null +++ b/rules/docker-lldp.mk @@ -0,0 +1,33 @@ +# docker image for lldp agent + +DOCKER_LLDP_STEM = docker-lldp +DOCKER_LLDP = $(DOCKER_LLDP_STEM).gz +DOCKER_LLDP_DBG = $(DOCKER_LLDP_STEM)-$(DBG_IMAGE_MARK).gz + +$(DOCKER_LLDP)_PATH = $(DOCKERS_PATH)/docker-lldp + +$(DOCKER_LLDP)_DEPENDS += $(LLDPD) $(LIBSWSSCOMMON) $(PYTHON3_SWSSCOMMON) + +$(DOCKER_LLDP)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) +$(DOCKER_LLDP)_DBG_DEPENDS += $(LLDPD_DBG) $(LIBSWSSCOMMON_DBG) + +$(DOCKER_LLDP)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) + +$(DOCKER_LLDP)_PYTHON_WHEELS += $(DBSYNCD_PY3) +$(DOCKER_LLDP)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) + +SONIC_DOCKER_IMAGES += $(DOCKER_LLDP) +SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_LLDP) + +SONIC_DOCKER_DBG_IMAGES += $(DOCKER_LLDP_DBG) +SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_LLDP_DBG) + +$(DOCKER_LLDP)_CONTAINER_NAME = lldp +$(DOCKER_LLDP)_RUN_OPT += --privileged -t +$(DOCKER_LLDP)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_LLDP)_RUN_OPT += -v /usr/share/sonic/scripts:/usr/share/sonic/scripts:ro + +$(DOCKER_LLDP)_BASE_IMAGE_FILES += lldpctl:/usr/bin/lldpctl +$(DOCKER_LLDP)_BASE_IMAGE_FILES += lldpcli:/usr/bin/lldpcli +$(DOCKER_LLDP)_BASE_IMAGE_FILES += monit_lldp:/etc/monit/conf.d +$(DOCKER_LLDP)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-macsec.dep b/rules/docker-macsec.dep new file mode 100644 index 000000000000..3ceab4fff36a --- /dev/null +++ b/rules/docker-macsec.dep @@ -0,0 +1,11 @@ + +DPATH := $($(DOCKER_MACSEC)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-macsec.mk rules/docker-macsec.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_MACSEC)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_MACSEC)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_MACSEC)_DEP_FILES := $(DEP_FILES) + +$(eval $(call add_dbg_docker,$(DOCKER_MACSEC),$(DOCKER_MACSEC_DBG))) diff --git a/rules/docker-macsec.mk b/rules/docker-macsec.mk new file mode 100644 index 000000000000..f9f8c9b41298 --- /dev/null +++ b/rules/docker-macsec.mk @@ -0,0 +1,32 @@ +# docker image for macsec agent + +DOCKER_MACSEC_STEM = docker-macsec +DOCKER_MACSEC = $(DOCKER_MACSEC_STEM).gz +DOCKER_MACSEC_DBG = $(DOCKER_MACSEC_STEM)-$(DBG_IMAGE_MARK).gz + +$(DOCKER_MACSEC)_PATH = $(DOCKERS_PATH)/$(DOCKER_MACSEC_STEM) + +$(DOCKER_MACSEC)_DEPENDS += $(SWSS) $(WPASUPPLICANT) $(REDIS_TOOLS) $(LIBNL3) $(LIBNL_GENL3) $(LIBNL_ROUTE3) +$(DOCKER_MACSEC)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) +$(DOCKER_MACSEC)_DBG_DEPENDS += $(SWSS_DBG) $(LIBSWSSCOMMON_DBG) +$(DOCKER_MACSEC)_DBG_DEPENDS += $(WPASUPPLICANT_DBG) + +$(DOCKER_MACSEC)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) + +$(DOCKER_MACSEC)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) + +SONIC_DOCKER_IMAGES += $(DOCKER_MACSEC) +SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_MACSEC) +SONIC_BUSTER_DOCKERS += $(DOCKER_MACSEC) + +SONIC_DOCKER_DBG_IMAGES += $(DOCKER_MACSEC_DBG) +SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_MACSEC_DBG) +SONIC_BUSTER_DBG_DOCKERS += $(DOCKER_MACSEC_DBG) + +$(DOCKER_MACSEC)_CONTAINER_NAME = macsec +$(DOCKER_MACSEC)_RUN_OPT += --privileged -t +$(DOCKER_MACSEC)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_MACSEC)_RUN_OPT += -v /host/warmboot:/var/warmboot + +# $(DOCKER_MACSEC)_BASE_IMAGE_FILES += macsecctl:/usr/bin/macsecctl +$(DOCKER_MACSEC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-nat.mk b/rules/docker-nat.mk index eb6bd16ccd46..981019dbcdb6 100644 --- a/rules/docker-nat.mk +++ b/rules/docker-nat.mk @@ -6,23 +6,21 @@ 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)_DEPENDS += $(SWSS) $(IPTABLESIP4TC) $(IPTABLESIP6TC) $(IPTABLESIPTC) $(IPXTABLES12) $(IPTABLES) +$(DOCKER_NAT)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) $(DOCKER_NAT)_DBG_DEPENDS += $(SWSS_DBG) $(LIBSWSSCOMMON_DBG) -$(DOCKER_NAT)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) +$(DOCKER_NAT)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) -$(DOCKER_NAT)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) +$(DOCKER_NAT)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) -ifeq ($(ENABLE_NAT), y) +ifeq ($(INCLUDE_NAT), y) SONIC_DOCKER_IMAGES += $(DOCKER_NAT) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_NAT) -SONIC_STRETCH_DOCKERS += $(DOCKER_NAT) endif -ifeq ($(ENABLE_NAT), y) +ifeq ($(INCLUDE_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 diff --git a/rules/docker-orchagent.mk b/rules/docker-orchagent.mk index bab1a3a29920..5e2e08ee2437 100644 --- a/rules/docker-orchagent.mk +++ b/rules/docker-orchagent.mk @@ -4,25 +4,23 @@ DOCKER_ORCHAGENT_STEM = docker-orchagent DOCKER_ORCHAGENT = $(DOCKER_ORCHAGENT_STEM).gz DOCKER_ORCHAGENT_DBG = $(DOCKER_ORCHAGENT_STEM)-$(DBG_IMAGE_MARK).gz -$(DOCKER_ORCHAGENT)_DEPENDS += $(SWSS) $(REDIS_TOOLS) +$(DOCKER_ORCHAGENT)_DEPENDS += $(SWSS) -$(DOCKER_ORCHAGENT)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) +$(DOCKER_ORCHAGENT)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) $(DOCKER_ORCHAGENT)_DBG_DEPENDS += $(SWSS_DBG) \ $(LIBSWSSCOMMON_DBG) \ $(LIBSAIREDIS_DBG) -$(DOCKER_ORCHAGENT)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) +$(DOCKER_ORCHAGENT)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) $(DOCKER_ORCHAGENT)_PATH = $(DOCKERS_PATH)/$(DOCKER_ORCHAGENT_STEM) -$(DOCKER_ORCHAGENT)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) +$(DOCKER_ORCHAGENT)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) SONIC_DOCKER_IMAGES += $(DOCKER_ORCHAGENT) -SONIC_STRETCH_DOCKERS += $(DOCKER_ORCHAGENT) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_ORCHAGENT) SONIC_DOCKER_DBG_IMAGES += $(DOCKER_ORCHAGENT_DBG) -SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_ORCHAGENT_DBG) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_ORCHAGENT_DBG) $(DOCKER_ORCHAGENT)_CONTAINER_NAME = swss @@ -35,4 +33,4 @@ $(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) +$(DOCKER_ORCHAGENT)_FILES += $(ARP_UPDATE_SCRIPT) $(ARP_UPDATE_VARS_TEMPLATE) $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-platform-monitor.mk b/rules/docker-platform-monitor.mk index db1c8c5a0289..547fbf60813f 100644 --- a/rules/docker-platform-monitor.mk +++ b/rules/docker-platform-monitor.mk @@ -6,39 +6,61 @@ DOCKER_PLATFORM_MONITOR_DBG = $(DOCKER_PLATFORM_MONITOR_STEM)-$(DBG_IMAGE_MARK). $(DOCKER_PLATFORM_MONITOR)_PATH = $(DOCKERS_PATH)/$(DOCKER_PLATFORM_MONITOR_STEM) -$(DOCKER_PLATFORM_MONITOR)_DEPENDS += $(LIBSENSORS) $(LM_SENSORS) $(FANCONTROL) $(SENSORD) $(LIBSWSSCOMMON) $(PYTHON_SWSSCOMMON) $(SMARTMONTOOLS) -ifeq ($(CONFIGURED_PLATFORM),barefoot) -$(DOCKER_PLATFORM_MONITOR)_DEPENDS += $(PYTHON_THRIFT) -endif -$(DOCKER_PLATFORM_MONITOR)_PYTHON_DEBS += $(SONIC_LEDD) $(SONIC_XCVRD) $(SONIC_PSUD) $(SONIC_SYSEEPROMD) $(SONIC_THERMALCTLD) +$(DOCKER_PLATFORM_MONITOR)_DEPENDS += $(LIBSENSORS) $(LM_SENSORS) $(FANCONTROL) $(SENSORD) $(LIBSWSSCOMMON) $(PYTHON_SWSSCOMMON) $(PYTHON3_SWSSCOMMON) $(SMARTMONTOOLS) + $(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_PLATFORM_COMMON_PY2) +$(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_PLATFORM_COMMON_PY3) $(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SWSSSDK_PY2) +$(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SWSSSDK_PY3) +$(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY2) +$(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY3) +$(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE_PY2) $(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_PLATFORM_API_PY2) -$(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_DAEMON_BASE_PY2) +$(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_PLATFORM_API_PY3) +$(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_LEDD_PY2) +$(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_PCIED_PY2) +$(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_PSUD_PY2) +$(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_SYSEEPROMD_PY2) +$(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_THERMALCTLD_PY2) +$(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_XCVRD_PY2) +$(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_LEDD_PY3) +$(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_PCIED_PY3) +$(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_PSUD_PY3) +$(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_SYSEEPROMD_PY3) +$(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_THERMALCTLD_PY3) +$(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_XCVRD_PY3) +$(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_CHASSISD_PY3) + +ifeq ($(PDDF_SUPPORT),y) +$(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(PDDF_PLATFORM_API_BASE_PY2) +endif -$(DOCKER_PLATFORM_MONITOR)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) +$(DOCKER_PLATFORM_MONITOR)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) $(DOCKER_PLATFORM_MONITOR)_DBG_DEPENDS += $(LIBSWSSCOMMON_DBG) $(LIBSENSORS_DBG) $(DOCKER_PLATFORM_MONITOR)_DBG_DEPENDS += $(LM_SENSORS_DBG) $(SENSORD_DBG) -$(DOCKER_PLATFORM_MONITOR)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) +$(DOCKER_PLATFORM_MONITOR)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) -$(DOCKER_PLATFORM_MONITOR)_LOAD_DOCKERS = $(DOCKER_CONFIG_ENGINE_STRETCH) +$(DOCKER_PLATFORM_MONITOR)_LOAD_DOCKERS = $(DOCKER_CONFIG_ENGINE_BUSTER) -SONIC_STRETCH_DOCKERS += $(DOCKER_PLATFORM_MONITOR) SONIC_DOCKER_IMAGES += $(DOCKER_PLATFORM_MONITOR) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_PLATFORM_MONITOR) -SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_PLATFORM_MONITOR_DBG) 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 += --privileged -t $(DOCKER_PLATFORM_MONITOR)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_PLATFORM_MONITOR)_RUN_OPT += -v /usr/share/sonic/scripts:/usr/share/sonic/scripts:ro +$(DOCKER_PLATFORM_MONITOR)_RUN_OPT += -v /var/run/platform_cache:/var/run/platform_cache:ro +$(DOCKER_PLATFORM_MONITOR)_RUN_OPT += -v /usr/share/sonic/device/pddf:/usr/share/sonic/device/pddf:ro # Mount Arista python library on Aboot images to be used by plugins $(DOCKER_PLATFORM_MONITOR)_aboot_RUN_OPT += -v /usr/lib/python2.7/dist-packages/arista:/usr/lib/python2.7/dist-packages/arista:ro -$(DOCKER_PLATFORM_MONITOR)_aboot_RUN_OPT += -v /usr/lib/python2.7/dist-packages/arista/utils/sonic_platform:/usr/lib/python2.7/dist-packages/sonic_platform:ro +$(DOCKER_PLATFORM_MONITOR)_aboot_RUN_OPT += -v /usr/lib/python3/dist-packages/arista:/usr/lib/python3/dist-packages/arista:ro +$(DOCKER_PLATFORM_MONITOR)_aboot_RUN_OPT += -v /usr/lib/python2.7/dist-packages/sonic_platform:/usr/lib/python2.7/dist-packages/sonic_platform:ro +$(DOCKER_PLATFORM_MONITOR)_aboot_RUN_OPT += -v /usr/lib/python3/dist-packages/sonic_platform:/usr/lib/python3/dist-packages/sonic_platform:ro $(DOCKER_PLATFORM_MONITOR)_BASE_IMAGE_FILES += cmd_wrapper:/usr/bin/sensors $(DOCKER_PLATFORM_MONITOR)_BASE_IMAGE_FILES += cmd_wrapper:/usr/sbin/smartctl diff --git a/rules/docker-ptf.dep b/rules/docker-ptf.dep deleted file mode 100644 index d62019e9b386..000000000000 --- a/rules/docker-ptf.dep +++ /dev/null @@ -1,10 +0,0 @@ - -DPATH := $($(DOCKER_PTF)_PATH) -DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-ptf.mk rules/docker-ptf.dep -DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) -DEP_FILES += $(shell git ls-files $(DPATH)) - -$(DOCKER_PTF)_CACHE_MODE := GIT_CONTENT_SHA -$(DOCKER_PTF)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) -$(DOCKER_PTF)_DEP_FILES := $(DEP_FILES) - diff --git a/rules/docker-ptf.mk b/rules/docker-ptf.mk deleted file mode 100644 index 2782c45339bd..000000000000 --- a/rules/docker-ptf.mk +++ /dev/null @@ -1,6 +0,0 @@ -# docker image for ptf - -DOCKER_PTF = docker-ptf.gz -$(DOCKER_PTF)_PATH = $(DOCKERS_PATH)/docker-ptf -$(DOCKER_PTF)_DEPENDS += $(LIBTHRIFT) $(PYTHON_THRIFT) $(PTF) -SONIC_DOCKER_IMAGES += $(DOCKER_PTF) diff --git a/rules/docker-restapi.mk b/rules/docker-restapi.mk index 2141dea64d17..917a270266bd 100644 --- a/rules/docker-restapi.mk +++ b/rules/docker-restapi.mk @@ -10,7 +10,7 @@ $(DOCKER_RESTAPI)_PATH = $(DOCKERS_PATH)/$(DOCKER_RESTAPI_STEM) $(DOCKER_RESTAPI)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) -ifeq ($(ENABLE_RESTAPI), y) +ifeq ($(INCLUDE_RESTAPI), y) SONIC_DOCKER_IMAGES += $(DOCKER_RESTAPI) SONIC_STRETCH_DOCKERS += $(DOCKER_RESTAPI) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_RESTAPI) @@ -19,4 +19,8 @@ endif $(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 +$(DOCKER_RESTAPI)_RUN_OPT += -v /etc/sonic/credentials:/etc/sonic/credentials:ro +$(DOCKER_RESTAPI)_RUN_OPT += -p=8081:8081/tcp + +$(DOCKER_RESTAPI)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) +$(DOCKER_RESTAPI)_BASE_IMAGE_FILES += monit_restapi:/etc/monit/conf.d diff --git a/rules/docker-router-advertiser.mk b/rules/docker-router-advertiser.mk index ec3fcf6e1fa3..38bd95905673 100644 --- a/rules/docker-router-advertiser.mk +++ b/rules/docker-router-advertiser.mk @@ -6,23 +6,21 @@ DOCKER_ROUTER_ADVERTISER_DBG = $(DOCKER_ROUTER_ADVERTISER_STEM)-$(DBG_IMAGE_MARK $(DOCKER_ROUTER_ADVERTISER)_PATH = $(DOCKERS_PATH)/$(DOCKER_ROUTER_ADVERTISER_STEM) -$(DOCKER_ROUTER_ADVERTISER)_DEPENDS += $(RADVD) $(REDIS_TOOLS) -$(DOCKER_ROUTER_ADVERTISER)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) +$(DOCKER_ROUTER_ADVERTISER)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) $(DOCKER_ROUTER_ADVERTISER)_DBG_DEPENDS += $(RADVD_DBG) -$(DOCKER_ROUTER_ADVERTISER)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) +$(DOCKER_ROUTER_ADVERTISER)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) -$(DOCKER_ROUTER_ADVERTISER)_LOAD_DOCKERS = $(DOCKER_CONFIG_ENGINE_STRETCH) +$(DOCKER_ROUTER_ADVERTISER)_LOAD_DOCKERS = $(DOCKER_CONFIG_ENGINE_BUSTER) SONIC_DOCKER_IMAGES += $(DOCKER_ROUTER_ADVERTISER) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_ROUTER_ADVERTISER) -SONIC_STRETCH_DOCKERS += $(DOCKER_ROUTER_ADVERTISER) SONIC_DOCKER_DBG_IMAGES += $(DOCKER_ROUTER_ADVERTISER_DBG) 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 += --privileged -t $(DOCKER_ROUTER_ADVERTISER)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_ROUTER_ADVERTISER)_RUN_OPT += -v /usr/share/sonic/scripts:/usr/share/sonic/scripts:ro $(DOCKER_ROUTER_ADVERTISER)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-sflow.mk b/rules/docker-sflow.mk index 67724ad7c548..6888304b8bce 100644 --- a/rules/docker-sflow.mk +++ b/rules/docker-sflow.mk @@ -6,23 +6,21 @@ DOCKER_SFLOW_DBG = $(DOCKER_SFLOW_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_SFLOW)_PATH = $(DOCKERS_PATH)/$(DOCKER_SFLOW_STEM) -$(DOCKER_SFLOW)_DEPENDS += $(SWSS) $(REDIS_TOOLS) $(HSFLOWD) $(SFLOWTOOL) $(PSAMPLE) -$(DOCKER_SFLOW)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) +$(DOCKER_SFLOW)_DEPENDS += $(SWSS) $(HSFLOWD) $(SFLOWTOOL) $(PSAMPLE) +$(DOCKER_SFLOW)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) $(DOCKER_TEAMD)_DBG_DEPENDS += $(SWSS_DBG) $(LIBSWSSCOMMON_DBG) -$(DOCKER_SFLOW)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) +$(DOCKER_SFLOW)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) -$(DOCKER_SFLOW)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) +$(DOCKER_SFLOW)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) SONIC_DOCKER_IMAGES += $(DOCKER_SFLOW) -ifeq ($(ENABLE_SFLOW), y) +ifeq ($(INCLUDE_SFLOW), y) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SFLOW) -SONIC_STRETCH_DOCKERS += $(DOCKER_SFLOW) endif SONIC_DOCKER_DBG_IMAGES += $(DOCKER_SFLOW_DBG) -ifeq ($(ENABLE_SFLOW), y) +ifeq ($(INCLUDE_SFLOW), y) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_SFLOW_DBG) -SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_SFLOW_DBG) endif $(DOCKER_SFLOW)_CONTAINER_NAME = sflow diff --git a/rules/docker-snmp-sv2.dep b/rules/docker-snmp-sv2.dep deleted file mode 100644 index 38d46e1fbb03..000000000000 --- a/rules/docker-snmp-sv2.dep +++ /dev/null @@ -1,11 +0,0 @@ - -DPATH := $($(DOCKER_SNMP_SV2)_PATH) -DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-snmp-sv2.mk rules/docker-snmp-sv2.dep -DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) -DEP_FILES += $(shell git ls-files $(DPATH)) - -$(DOCKER_SNMP_SV2)_CACHE_MODE := GIT_CONTENT_SHA -$(DOCKER_SNMP_SV2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) -$(DOCKER_SNMP_SV2)_DEP_FILES := $(DEP_FILES) - -$(eval $(call add_dbg_docker,$(DOCKER_SNMP_SV2),$(DOCKER_SNMP_SV2_DBG))) diff --git a/rules/docker-snmp-sv2.mk b/rules/docker-snmp-sv2.mk deleted file mode 100644 index 59f99ac78bc7..000000000000 --- a/rules/docker-snmp-sv2.mk +++ /dev/null @@ -1,34 +0,0 @@ -# docker image for snmp agent - -DOCKER_SNMP_SV2_STEM = docker-snmp-sv2 -DOCKER_SNMP_SV2 = $(DOCKER_SNMP_SV2_STEM).gz -DOCKER_SNMP_SV2_DBG = $(DOCKER_SNMP_SV2_STEM)-$(DBG_IMAGE_MARK).gz - -$(DOCKER_SNMP_SV2)_PATH = $(DOCKERS_PATH)/docker-snmp-sv2 - -## TODO: remove LIBPY3_DEV if we can get pip3 directly -$(DOCKER_SNMP_SV2)_DEPENDS += $(SNMP) $(SNMPD) $(PY3) $(LIBPY3_DEV) - -$(DOCKER_SNMP_SV2)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) -$(DOCKER_SNMP_SV2)_DBG_DEPENDS += $(SNMP_DBG) $(SNMPD_DBG) $(LIBSNMP_DBG) - -$(DOCKER_SNMP_SV2)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) - -$(DOCKER_SNMP_SV2)_PYTHON_WHEELS += $(SONIC_PLATFORM_COMMON_PY3) $(SWSSSDK_PY3) $(ASYNCSNMP_PY3) -$(DOCKER_SNMP_SV2)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) - -SONIC_DOCKER_IMAGES += $(DOCKER_SNMP_SV2) -SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SNMP_SV2) -SONIC_STRETCH_DOCKERS += $(DOCKER_SNMP_SV2) - -SONIC_DOCKER_DBG_IMAGES += $(DOCKER_SNMP_SV2_DBG) -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 += --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 -$(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-snmp.dep b/rules/docker-snmp.dep new file mode 100644 index 000000000000..580ee65d53fe --- /dev/null +++ b/rules/docker-snmp.dep @@ -0,0 +1,11 @@ + +DPATH := $($(DOCKER_SNMP)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-snmp.mk rules/docker-snmp.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_SNMP)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_SNMP)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_SNMP)_DEP_FILES := $(DEP_FILES) + +$(eval $(call add_dbg_docker,$(DOCKER_SNMP),$(DOCKER_SNMP_DBG))) diff --git a/rules/docker-snmp.mk b/rules/docker-snmp.mk new file mode 100644 index 000000000000..cbc69dc92b1b --- /dev/null +++ b/rules/docker-snmp.mk @@ -0,0 +1,31 @@ +# docker image for snmp agent + +DOCKER_SNMP_STEM = docker-snmp +DOCKER_SNMP = $(DOCKER_SNMP_STEM).gz +DOCKER_SNMP_DBG = $(DOCKER_SNMP_STEM)-$(DBG_IMAGE_MARK).gz + +$(DOCKER_SNMP)_PATH = $(DOCKERS_PATH)/docker-snmp + +## TODO: remove LIBPY3_DEV if we can get pip3 directly +$(DOCKER_SNMP)_DEPENDS += $(SNMP) $(SNMPD) + +$(DOCKER_SNMP)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) +$(DOCKER_SNMP)_DBG_DEPENDS += $(SNMP_DBG) $(SNMPD_DBG) $(LIBSNMP_DBG) + +$(DOCKER_SNMP)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) + +$(DOCKER_SNMP)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY3) $(SONIC_PLATFORM_COMMON_PY3) $(SWSSSDK_PY3) $(ASYNCSNMP_PY3) +$(DOCKER_SNMP)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) + +SONIC_DOCKER_IMAGES += $(DOCKER_SNMP) +SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SNMP) + +SONIC_DOCKER_DBG_IMAGES += $(DOCKER_SNMP_DBG) +SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_SNMP_DBG) + +$(DOCKER_SNMP)_CONTAINER_NAME = snmp +$(DOCKER_SNMP)_RUN_OPT += --privileged -t +$(DOCKER_SNMP)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_SNMP)_RUN_OPT += -v /usr/share/sonic/scripts:/usr/share/sonic/scripts:ro +$(DOCKER_SNMP)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) +$(DOCKER_SNMP)_BASE_IMAGE_FILES += monit_snmp:/etc/monit/conf.d diff --git a/rules/docker-sonic-mgmt-framework.mk b/rules/docker-sonic-mgmt-framework.mk index f07b8d023d2d..65bac8bd9ddc 100644 --- a/rules/docker-sonic-mgmt-framework.mk +++ b/rules/docker-sonic-mgmt-framework.mk @@ -6,29 +6,29 @@ DOCKER_MGMT_FRAMEWORK_DBG = $(DOCKER_MGMT_FRAMEWORK_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_MGMT_FRAMEWORK)_PATH = $(DOCKERS_PATH)/$(DOCKER_MGMT_FRAMEWORK_STEM) -$(DOCKER_MGMT_FRAMEWORK)_DEPENDS += $(REDIS_TOOLS) $(SONIC_MGMT_FRAMEWORK) -$(DOCKER_MGMT_FRAMEWORK)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) -$(DOCKER_MGMT_FRAMEWORK)_DBG_DEPENDS += $(REDIS_TOOLS) $(SONIC_MGMT_FRAMEWORK_DBG) +$(DOCKER_MGMT_FRAMEWORK)_DEPENDS += $(SONIC_MGMT_COMMON) +$(DOCKER_MGMT_FRAMEWORK)_DEPENDS += $(SONIC_MGMT_FRAMEWORK) +$(DOCKER_MGMT_FRAMEWORK)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) +$(DOCKER_MGMT_FRAMEWORK)_DBG_DEPENDS += $(SONIC_MGMT_FRAMEWORK_DBG) SONIC_DOCKER_IMAGES += $(DOCKER_MGMT_FRAMEWORK) -$(DOCKER_MGMT_FRAMEWORK)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) -$(DOCKER_MGMT_FRAMEWORK)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) +$(DOCKER_MGMT_FRAMEWORK)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) +$(DOCKER_MGMT_FRAMEWORK)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) -ifeq ($(ENABLE_MGMT_FRAMEWORK), y) +ifeq ($(INCLUDE_MGMT_FRAMEWORK), y) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_MGMT_FRAMEWORK) -SONIC_STRETCH_DOCKERS += $(DOCKER_MGMT_FRAMEWORK) endif SONIC_DOCKER_DBG_IMAGES += $(DOCKER_MGMT_FRAMEWORK_DBG) -ifeq ($(ENABLE_MGMT_FRAMEWORK), y) +ifeq ($(INCLUDE_MGMT_FRAMEWORK), y) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_MGMT_FRAMEWORK_DBG) -SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_MGMT_FRAMEWORK_DBG) endif $(DOCKER_MGMT_FRAMEWORK)_CONTAINER_NAME = mgmt-framework $(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 += -v /var/run/dbus:/var/run/dbus:rw $(DOCKER_MGMT_FRAMEWORK)_RUN_OPT += --mount type=bind,source="/var/platform/",target="/mnt/platform/" $(DOCKER_MGMT_FRAMEWORK)_BASE_IMAGE_FILES += sonic-cli:/usr/bin/sonic-cli diff --git a/rules/docker-sonic-mgmt-spytest.dep b/rules/docker-sonic-mgmt-spytest.dep index 26daffbd1afc..1f6c36eec72d 100644 --- a/rules/docker-sonic-mgmt-spytest.dep +++ b/rules/docker-sonic-mgmt-spytest.dep @@ -8,4 +8,4 @@ $(DOCKER_MGMT_SPYTEST)_CACHE_MODE := GIT_CONTENT_SHA $(DOCKER_MGMT_SPYTEST)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) $(DOCKER_MGMT_SPYTEST)_DEP_FILES := $(DEP_FILES) -$(eval $(call add_dbg_docker,$(DOCKER_MGMT_SPYTEST),$(DOCKER_MGMT_FRAMEWORK_DBG))) +$(eval $(call add_dbg_docker,$(DOCKER_MGMT_SPYTEST),$(DOCKER_MGMT_SPYTEST_DBG))) diff --git a/rules/docker-sonic-mgmt-spytest.mk b/rules/docker-sonic-mgmt-spytest.mk deleted file mode 100644 index c3906263eff3..000000000000 --- a/rules/docker-sonic-mgmt-spytest.mk +++ /dev/null @@ -1,6 +0,0 @@ -# SPYTest Management Docker - -DOCKER_MGMT_SPYTEST = docker-sonic-mgmt-spytest.gz -$(DOCKER_MGMT_SPYTEST)_PATH = $(DOCKERS_PATH)/docker-sonic-mgmt-spytest -$(DOCKER_MGMT_SPYTEST)_LOAD_DOCKERS += $(DOCKER_SONIC_MGMT) -SONIC_DOCKER_IMAGES += $(DOCKER_MGMT_SPYTEST) diff --git a/rules/docker-sonic-mgmt.mk b/rules/docker-sonic-mgmt.mk index b1aaad348734..8d6901755f8a 100644 --- a/rules/docker-sonic-mgmt.mk +++ b/rules/docker-sonic-mgmt.mk @@ -3,3 +3,4 @@ DOCKER_SONIC_MGMT = docker-sonic-mgmt.gz $(DOCKER_SONIC_MGMT)_PATH = $(DOCKERS_PATH)/docker-sonic-mgmt $(DOCKER_SONIC_MGMT)_DEPENDS += $(SONIC_DEVICE_DATA) $(PTF) SONIC_DOCKER_IMAGES += $(DOCKER_SONIC_MGMT) +SONIC_STRETCH_DOCKERS += $(DOCKER_SONIC_MGMT) diff --git a/rules/docker-teamd.mk b/rules/docker-teamd.mk index ce7b5bbab1f5..5442d5bf6b3f 100644 --- a/rules/docker-teamd.mk +++ b/rules/docker-teamd.mk @@ -6,22 +6,20 @@ DOCKER_TEAMD_DBG = $(DOCKER_TEAMD_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_TEAMD)_PATH = $(DOCKERS_PATH)/$(DOCKER_TEAMD_STEM) -$(DOCKER_TEAMD)_DEPENDS += $(SWSS) $(LIBTEAMDCT) $(LIBTEAM_UTILS) $(REDIS_TOOLS) -$(DOCKER_TEAMD)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) +$(DOCKER_TEAMD)_DEPENDS += $(SWSS) $(LIBTEAMDCTL) $(LIBTEAM_UTILS) +$(DOCKER_TEAMD)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) $(DOCKER_TEAMD)_DBG_DEPENDS += $(SWSS_DBG) $(LIBSWSSCOMMON_DBG) -$(DOCKER_TEAMD)_DBG_DEPENDS += $(LIBTEAMDCT_DBG) $(LIBTEAM_UTILS_DBG) +$(DOCKER_TEAMD)_DBG_DEPENDS += $(LIBTEAMDCTL_DBG) $(LIBTEAM_UTILS_DBG) -$(DOCKER_TEAMD)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) +$(DOCKER_TEAMD)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) -$(DOCKER_TEAMD)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) +$(DOCKER_TEAMD)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) SONIC_DOCKER_IMAGES += $(DOCKER_TEAMD) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_TEAMD) -SONIC_STRETCH_DOCKERS += $(DOCKER_TEAMD) SONIC_DOCKER_DBG_IMAGES += $(DOCKER_TEAMD_DBG) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_TEAMD_DBG) -SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_TEAMD_DBG) $(DOCKER_TEAMD)_CONTAINER_NAME = teamd $(DOCKER_TEAMD)_RUN_OPT += --privileged -t @@ -29,4 +27,5 @@ $(DOCKER_TEAMD)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_TEAMD)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_TEAMD)_BASE_IMAGE_FILES += teamdctl:/usr/bin/teamdctl +$(DOCKER_TEAMD)_BASE_IMAGE_FILES += monit_teamd:/etc/monit/conf.d $(DOCKER_TEAMD)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-telemetry.mk b/rules/docker-telemetry.mk index 04f1871f334b..5152a386963b 100644 --- a/rules/docker-telemetry.mk +++ b/rules/docker-telemetry.mk @@ -6,28 +6,28 @@ DOCKER_TELEMETRY_DBG = $(DOCKER_TELEMETRY_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_TELEMETRY)_PATH = $(DOCKERS_PATH)/$(DOCKER_TELEMETRY_STEM) -$(DOCKER_TELEMETRY)_DEPENDS += $(REDIS_TOOLS) $(SONIC_TELEMETRY) -$(DOCKER_TELEMETRY)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) +$(DOCKER_TELEMETRY)_DEPENDS += $(SONIC_MGMT_COMMON) +$(DOCKER_TELEMETRY)_DEPENDS += $(SONIC_TELEMETRY) +$(DOCKER_TELEMETRY)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) -$(DOCKER_TELEMETRY)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) -$(DOCKER_TELEMETRY)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) +$(DOCKER_TELEMETRY)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) +$(DOCKER_TELEMETRY)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) SONIC_DOCKER_IMAGES += $(DOCKER_TELEMETRY) -ifeq ($(ENABLE_SYSTEM_TELEMETRY), y) +ifeq ($(INCLUDE_SYSTEM_TELEMETRY), y) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_TELEMETRY) -SONIC_STRETCH_DOCKERS += $(DOCKER_TELEMETRY) endif SONIC_DOCKER_DBG_IMAGES += $(DOCKER_TELEMETRY_DBG) -ifeq ($(ENABLE_SYSTEM_TELEMETRY), y) +ifeq ($(INCLUDE_SYSTEM_TELEMETRY), y) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_TELEMETRY_DBG) -SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_TELEMETRY_DBG) endif $(DOCKER_TELEMETRY)_CONTAINER_NAME = telemetry $(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/" +$(DOCKER_TELEMETRY)_RUN_OPT += -v /usr/share/sonic/scripts:/usr/share/sonic/scripts:ro +$(DOCKER_TELEMETRY)_RUN_OPT += -v /var/run/dbus:/var/run/dbus:rw $(DOCKER_TELEMETRY)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) $(DOCKER_TELEMETRY)_BASE_IMAGE_FILES += monit_telemetry:/etc/monit/conf.d diff --git a/rules/frr.dep b/rules/frr.dep index c6bd41aca58a..e263cb8e881e 100644 --- a/rules/frr.dep +++ b/rules/frr.dep @@ -2,9 +2,24 @@ SPATH := $($(FRR)_SRC_PATH) DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/frr.mk rules/frr.dep DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) -SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) +DEP_FILES += $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files |grep -Ev '^frr$$$$')) + +# Account for source files under the frr submodule directory as well. +# Remove all the symbolic link files +FRR_SPATH := $(SPATH)/frr +SMDEP_FILES := $(addprefix $(FRR_SPATH)/,$(shell cd $(FRR_SPATH) && git ls-files \ + | grep -Ev -e 'debian/changelog$$$$' \ + -e '^tests/topotests/bgp_instance_del_test/ce[0-9]$$$$' \ + -e '^tests/topotests/bgp_instance_del_test/r[0-9]$$$$' \ + -e '^tests/topotests/bgp_instance_del_test/scripts$$$$' \ + -e '^tests/topotests/bgp_instance_del_test/customize.py$$$$' \ + -e '^tests/topotests/bgp_rfapi_basic_sanity_config2/customize.py$$$$' \ + -e '^tests/topotests/bgp_rfapi_basic_sanity_config2/scripts$$$$' \ + -e '^tests/topotests/bgp_rfapi_basic_sanity_config2/test_bgp_rfapi_basic_sanity_config2.py$$$$' \ + )) $(FRR)_CACHE_MODE := GIT_CONTENT_SHA $(FRR)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) $(FRR)_DEP_FILES := $(DEP_FILES) - +$(FRR)_SMDEP_FILES := $(SMDEP_FILES) +$(FRR)_SMDEP_PATHS := $(FRR_SPATH) diff --git a/rules/frr.mk b/rules/frr.mk index 6b2e92fcbd2e..c8175339f444 100644 --- a/rules/frr.mk +++ b/rules/frr.mk @@ -1,30 +1,30 @@ # FRRouting (frr) package -FRR_VERSION = 7.2.1 +FRR_VERSION = 7.5 FRR_SUBVERSION = 0 -FRR_BRANCH = frr/7.2 -FRR_TAG = frr-7.2.1-s1 +FRR_BRANCH = frr/7.5 +FRR_TAG = frr-7.5-s3 export FRR_VERSION FRR_SUBVERSION FRR_BRANCH FRR_TAG FRR = frr_$(FRR_VERSION)-sonic-$(FRR_SUBVERSION)_$(CONFIGURED_ARCH).deb -$(FRR)_DEPENDS += $(LIBSNMP_DEV) $(LIBYANG_DEV) -$(FRR)_RDEPENDS += $(LIBYANG) +$(FRR)_DEPENDS += $(LIBSNMP_DEV) $(LIBYANG1) $(LIBYANG1_DEV) +$(FRR)_RDEPENDS += $(LIBYANG1) +$(FRR)_UNINSTALLS = $(LIBYANG1_DEV) $(LIBYANG1) $(FRR)_SRC_PATH = $(SRC_PATH)/sonic-frr SONIC_MAKE_DEBS += $(FRR) -SONIC_STRETCH_DEBS += $(FRR) FRR_PYTHONTOOLS = frr-pythontools_$(FRR_VERSION)-sonic-$(FRR_SUBVERSION)_all.deb -$(eval $(call add_derived_package,$(FRR),$(FRR_PYTHONTOOLS))) +$(eval $(call add_extra_package,$(FRR),$(FRR_PYTHONTOOLS))) FRR_DBG = frr-dbgsym_$(FRR_VERSION)-sonic-$(FRR_SUBVERSION)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(FRR),$(FRR_DBG))) +$(eval $(call add_extra_package,$(FRR),$(FRR_DBG))) FRR_SNMP = frr-snmp_$(FRR_VERSION)-sonic-$(FRR_SUBVERSION)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(FRR),$(FRR_SNMP))) +$(eval $(call add_extra_package,$(FRR),$(FRR_SNMP))) FRR_SNMP_DBG = frr-snmp-dbgsym_$(FRR_VERSION)-sonic-$(FRR_SUBVERSION)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(FRR),$(FRR_SNMP_DBG))) +$(eval $(call add_extra_package,$(FRR),$(FRR_SNMP_DBG))) export FRR FRR_PYTHONTOOLS FRR_DBG FRR_SNMP FRR_SNMP_DBG diff --git a/rules/functions b/rules/functions index 5cdd35198820..c6caebe82858 100644 --- a/rules/functions +++ b/rules/functions @@ -17,6 +17,10 @@ GRAY=\033[0m endif endif +ifeq ($(BUILD_LOG_TIMESTAMP),simple) +PROCESS_LOG_OPTION = -t +endif + # Print red colored output # call: # log_red message @@ -43,7 +47,8 @@ log_green = echo -e "$(GREEN)$(1)$(GRAY)" FLUSH_LOG = rm -f $@.log -LOG = &>> $(PROJECT_ROOT)/$@.log || { [ $$? -eq 0 ] || pushd $(PROJECT_ROOT) > /dev/null ; ./update_screen.sh -e $@ ; popd > /dev/null ; false ; } +LOG_SIMPLE = &>> $(PROJECT_ROOT)/$@.log || { [ $$? -eq 0 ] || pushd $(PROJECT_ROOT) > /dev/null ; ./update_screen.sh -e $@ ; popd > /dev/null ; false ; } +LOG = < /dev/null |& $(PROJECT_ROOT)/scripts/process_log.sh $(PROCESS_LOG_OPTION) &>> $(PROJECT_ROOT)/$@.log ; test $${PIPESTATUS[-2]} -eq 0 || { [ $$? -eq 0 ] || pushd $(PROJECT_ROOT) > /dev/null ; ./update_screen.sh -e $@ ; popd > /dev/null ; false ; } ############################################################################### ## Header and footer for each target @@ -59,12 +64,12 @@ define HEADER @ $(PRINT_DEPENDENCIES) $(FLUSH_LOG) -./update_screen.sh -a $@ +./update_screen.sh -a $@ $* endef # footer for each rule define FOOTER -./update_screen.sh -d $@ +./update_screen.sh -d $@ $($*_CACHE_LOADED) endef ############################################################################### @@ -91,6 +96,20 @@ $(1)_EXTRA_DEBS += $(2) SONIC_EXTRA_DEBS += $(2) endef +############################################################################### +## Definition of conflict packages +############################################################################### + +# call: +# add_conflict_package some_deb.deb, conflict_deb +define add_conflict_package +$(1)_CONFLICT_DEBS += $(2) +$(2)_CONFLICT_DEBS += $(1) +endef + +############################################################################### +## Definition of debug dockers +############################################################################### # call: # add_dbg_docker some_docker.gz, some-docker-dbg.gz @@ -98,6 +117,7 @@ define add_dbg_docker $(2)_PATH = $($(1)_PATH) $(2)_DBG_DEPENDS += $($(1)_DBG_DEPENDS) $(2)_DBG_IMAGE_PACKAGES += $($(1)_DBG_IMAGE_PACKAGES) +$(2)_PYTHON_DEBS += $($(1)_PYTHON_DEBS) $(2)_PYTHON_WHEELS += $($(1)_PYTHON_WHEELS) $(2)_LOAD_DOCKERS += $($(1)_LOAD_DOCKERS) $(2)_CACHE_MODE += $($(1)_CACHE_MODE) @@ -121,3 +141,28 @@ endef rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d)) expand = $(foreach d,$(1),$(call expand,$($(d)_$(2)),$(2))) $(1) + +############################################################################### +## Uninstall debs +############################################################################### +define UNINSTALL_DEBS +if [ -n "$(1)" ]; then \ + while true; do \ + if mkdir $(DEBS_PATH)/dpkg_lock &> /dev/null; then \ + { sudo DEBIAN_FRONTEND=noninteractive dpkg -P $(foreach deb,$(1),$(firstword $(subst _, ,$(basename $(deb))))) $(LOG) && rm -d $(DEBS_PATH)/dpkg_lock && break; } || { rm -d $(DEBS_PATH)/dpkg_lock && exit 1 ; } \ + fi; \ + done; \ +fi +endef + +############################################################################### +## Setup overlay fs for dpkg admin directory /var/lib/dpkg +############################################################################### +define SETUP_OVERLAYFS_FOR_DPKG_ADMINDIR +upperdir=$(shell mktemp -d -p $(DPKG_ADMINDIR_PATH)) +workdir=$(shell mktemp -d -p $(DPKG_ADMINDIR_PATH)) +mergedir=$(shell mktemp -d -p $(DPKG_ADMINDIR_PATH)) +sudo mount -t overlay overlay -olowerdir=/var/lib/dpkg,upperdir=$$upperdir,workdir=$$workdir $$mergedir +export SONIC_DPKG_ADMINDIR=$$mergedir +trap "sudo umount $$mergedir && rm -rf $$mergedir $$upperdir $$workdir" EXIT +endef diff --git a/rules/iccpd.dep b/rules/iccpd.dep new file mode 100644 index 000000000000..124cc5e421cb --- /dev/null +++ b/rules/iccpd.dep @@ -0,0 +1,10 @@ + +SPATH := $($(ICCPD)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/iccpd.mk rules/iccpd.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(ICCPD)_CACHE_MODE := GIT_CONTENT_SHA +$(ICCPD)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(ICCPD)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/iccpd.mk b/rules/iccpd.mk new file mode 100644 index 000000000000..eb97efc52b9f --- /dev/null +++ b/rules/iccpd.mk @@ -0,0 +1,19 @@ +# iccpd package + +ICCPD_VERSION = 0.0.5 + +ICCPD = iccpd_$(ICCPD_VERSION)_$(CONFIGURED_ARCH).deb +$(ICCPD)_DEPENDS += $(LIBNL_GENL3_DEV) $(LIBNL_CLI_DEV) +$(ICCPD)_RDEPENDS += $(LIBNL_GENL3) $(LIBNL_CLI) +$(ICCPD)_SRC_PATH = $(SRC_PATH)/iccpd +SONIC_DPKG_DEBS += $(ICCPD) + +ICCPD_DBG = iccpd-dbg_$(ICCPD_VERSION)_$(CONFIGURED_ARCH).deb +$(ICCPD_DBG)_DEPENDS += $(ICCPD) +$(ICCPD_DBG)_RDEPENDS += $(ICCPD) +$(eval $(call add_derived_package,$(ICCPD),$(ICCPD_DBG))) + +# The .c, .cpp, .h & .hpp files under src/{$DBG_SRC_ARCHIVE list} +# are archived into debug one image to facilitate debugging. +# +DBG_SRC_ARCHIVE += iccpd diff --git a/rules/ifupdown2.mk b/rules/ifupdown2.mk index b663cc1532d0..f81facd8ff26 100644 --- a/rules/ifupdown2.mk +++ b/rules/ifupdown2.mk @@ -6,6 +6,5 @@ export IFUPDOWN2_VERSION IFUPDOWN2 = ifupdown2_$(IFUPDOWN2_VERSION)_all.deb $(IFUPDOWN2)_SRC_PATH = $(SRC_PATH)/ifupdown2 SONIC_MAKE_DEBS += $(IFUPDOWN2) -SONIC_STRETCH_DEBS += $(IFUPDOWN2) export IFUPDOWN2 diff --git a/rules/initramfs-tools.mk b/rules/initramfs-tools.mk index badc584dd2be..2f3e55acac76 100644 --- a/rules/initramfs-tools.mk +++ b/rules/initramfs-tools.mk @@ -1,6 +1,6 @@ # initramfs-tools package -INITRAMFS_TOOLS_VERSION = 0.130 +INITRAMFS_TOOLS_VERSION = 0.133 export INITRAMFS_TOOLS_VERSION INITRAMFS_TOOLS = initramfs-tools_$(INITRAMFS_TOOLS_VERSION)_all.deb @@ -9,5 +9,3 @@ SONIC_MAKE_DEBS += $(INITRAMFS_TOOLS) INITRAMFS_TOOLS_CORE = initramfs-tools-core_$(INITRAMFS_TOOLS_VERSION)_all.deb $(eval $(call add_extra_package,$(INITRAMFS_TOOLS),$(INITRAMFS_TOOLS_CORE))) - -SONIC_STRETCH_DEBS += $(INITRAMFS_TOOLS) $(INITRAMFS_TOOLS_CORE) diff --git a/rules/iptables.mk b/rules/iptables.mk index 4d88c0a224b2..fcdcc3434e08 100644 --- a/rules/iptables.mk +++ b/rules/iptables.mk @@ -1,24 +1,23 @@ # iptables package -IPTABLES_VERSION = 1.6.0+snapshot20161117 -IPTABLES_VERSION_SUFFIX = 6 +IPTABLES_VERSION = 1.8.2 +IPTABLES_VERSION_SUFFIX = 4 IPTABLES_VERSION_FULL = $(IPTABLES_VERSION)-$(IPTABLES_VERSION_SUFFIX) -IPTABLES = iptables_$(IPTABLES_VERSION_FULL)_amd64.deb +IPTABLES = iptables_$(IPTABLES_VERSION_FULL)_$(CONFIGURED_ARCH).deb $(IPTABLES)_SRC_PATH = $(SRC_PATH)/iptables SONIC_MAKE_DEBS += $(IPTABLES) -SONIC_STRETCH_DEBS += $(IPTABLES) -IPTABLESIP4TC = libip4tc0_$(IPTABLES_VERSION_FULL)_amd64.deb +IPTABLESIP4TC = libip4tc0_$(IPTABLES_VERSION_FULL)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(IPTABLES),$(IPTABLESIP4TC))) -IPTABLESIP6TC = libip6tc0_$(IPTABLES_VERSION_FULL)_amd64.deb +IPTABLESIP6TC = libip6tc0_$(IPTABLES_VERSION_FULL)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(IPTABLES),$(IPTABLESIP6TC))) -IPTABLESIPTC = libiptc0_$(IPTABLES_VERSION_FULL)_amd64.deb +IPTABLESIPTC = libiptc0_$(IPTABLES_VERSION_FULL)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(IPTABLES),$(IPTABLESIPTC))) -IPXTABLES12 = libxtables12_$(IPTABLES_VERSION_FULL)_amd64.deb +IPXTABLES12 = libxtables12_$(IPTABLES_VERSION_FULL)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(IPTABLES),$(IPXTABLES12))) # Export these variables so they can be used in a sub-make diff --git a/rules/isc-dhcp.mk b/rules/isc-dhcp.mk index da57d0877104..3edebfd0dde0 100644 --- a/rules/isc-dhcp.mk +++ b/rules/isc-dhcp.mk @@ -1,14 +1,15 @@ # isc-dhcp packages -ISC_DHCP_VERSION = 4.3.5-2 +ISC_DHCP_VERSION = 4.4.1 +ISC_DHCP_VERSION_FULL = ${ISC_DHCP_VERSION}-2 -export ISC_DHCP_VERSION +export ISC_DHCP_VERSION ISC_DHCP_VERSION_FULL -ISC_DHCP_RELAY = isc-dhcp-relay_$(ISC_DHCP_VERSION)_$(CONFIGURED_ARCH).deb +ISC_DHCP_RELAY = isc-dhcp-relay_$(ISC_DHCP_VERSION_FULL)_$(CONFIGURED_ARCH).deb $(ISC_DHCP_RELAY)_SRC_PATH = $(SRC_PATH)/isc-dhcp SONIC_MAKE_DEBS += $(ISC_DHCP_RELAY) -SONIC_STRETCH_DEBS += $(ISC_DHCP_RELAY) - -ISC_DHCP_RELAY_DBG = isc-dhcp-relay-dbgsym_$(ISC_DHCP_VERSION)_$(CONFIGURED_ARCH).deb +ISC_DHCP_RELAY_DBG = isc-dhcp-relay-dbgsym_$(ISC_DHCP_VERSION_FULL)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(ISC_DHCP_RELAY),$(ISC_DHCP_RELAY_DBG))) + +export ISC_DHCP_RELAY ISC_DHCP_RELAY_DBG diff --git a/rules/ixgbe.mk b/rules/ixgbe.mk index 86a0e8453a2b..c1b017905b53 100644 --- a/rules/ixgbe.mk +++ b/rules/ixgbe.mk @@ -7,5 +7,3 @@ IXGBE_DRIVER = ixgbe.ko $(IXGBE_DRIVER)_SRC_PATH = $(SRC_PATH)/ixgbe $(IXGBE_DRIVER)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) SONIC_MAKE_FILES += $(IXGBE_DRIVER) - -SONIC_STRETCH_FILES += $(IXGBE_DRIVER) diff --git a/rules/kdump-tools.mk b/rules/kdump-tools.mk index d5d2630389f3..c4b0c792b04a 100644 --- a/rules/kdump-tools.mk +++ b/rules/kdump-tools.mk @@ -2,12 +2,11 @@ KDUMP_TOOLS_VERSION_BASE = 1.6.1 KDUMP_TOOLS_VERSION = $(KDUMP_TOOLS_VERSION_BASE)-1 -export KDUMP_TOOLS_VERSION_BASE +export KDUMP_TOOLS_VERSION_BASE export KDUMP_TOOLS_VERSION KDUMP_TOOLS = kdump-tools_$(KDUMP_TOOLS_VERSION)_all.deb $(KDUMP_TOOLS)_SRC_PATH = $(SRC_PATH)/kdump-tools SONIC_MAKE_DEBS += $(KDUMP_TOOLS) -SONIC_STRETCH_DEBS += $(KDUMP_TOOLS) export KDUMP_TOOLS diff --git a/rules/libteam.mk b/rules/libteam.mk index 02cdcbe0306a..0dd1b88b099a 100644 --- a/rules/libteam.mk +++ b/rules/libteam.mk @@ -13,21 +13,21 @@ LIBTEAM_DBG = libteam5-dbgsym_$(LIBTEAM_VERSION)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(LIBTEAM),$(LIBTEAM_DBG))) LIBTEAM_DEV = libteam-dev_$(LIBTEAM_VERSION)_$(CONFIGURED_ARCH).deb -$(LIBTEAM_DEV)_DEPENDS += $(LIBTEAMDCT) +$(LIBTEAM_DEV)_DEPENDS += $(LIBTEAMDCTL) $(eval $(call add_derived_package,$(LIBTEAM),$(LIBTEAM_DEV))) -LIBTEAMDCT = libteamdctl0_$(LIBTEAM_VERSION)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(LIBTEAM),$(LIBTEAMDCT))) +LIBTEAMDCTL = libteamdctl0_$(LIBTEAM_VERSION)_$(CONFIGURED_ARCH).deb +$(eval $(call add_derived_package,$(LIBTEAM),$(LIBTEAMDCTL))) -LIBTEAMDCT_DBG = libteamdctl0-dbgsym_$(LIBTEAM_VERSION)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(LIBTEAMDCT),$(LIBTEAMDCT_DBG))) +LIBTEAMDCTL_DBG = libteamdctl0-dbgsym_$(LIBTEAM_VERSION)_$(CONFIGURED_ARCH).deb +$(eval $(call add_derived_package,$(LIBTEAM),$(LIBTEAMDCTL_DBG))) LIBTEAM_UTILS = libteam-utils_$(LIBTEAM_VERSION)_$(CONFIGURED_ARCH).deb -$(LIBTEAM_UTILS)_DEPENDS += $(LIBTEAMDCT) +$(LIBTEAM_UTILS)_DEPENDS += $(LIBTEAMDCTL) $(eval $(call add_derived_package,$(LIBTEAM),$(LIBTEAM_UTILS))) LIBTEAM_UTILS_DBG = libteam-utils-dbgsym_$(LIBTEAM_VERSION)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(LIBTEAM_UTILS),$(LIBTEAM_UTILS_DBG))) +$(eval $(call add_derived_package,$(LIBTEAM),$(LIBTEAM_UTILS_DBG))) # The .c, .cpp, .h & .hpp files under src/{$DBG_SRC_ARCHIVE list} # are archived into debug one image to facilitate debugging. diff --git a/rules/libyang.mk b/rules/libyang.mk index d10c2ea2cc66..181db2368c6d 100644 --- a/rules/libyang.mk +++ b/rules/libyang.mk @@ -10,9 +10,10 @@ export LIBYANG_SUBVERSION LIBYANG = libyang_$(LIBYANG_VERSION)_$(CONFIGURED_ARCH).deb $(LIBYANG)_SRC_PATH = $(SRC_PATH)/libyang -$(LIBYANG)_DEPENDS += $(SWIG_BASE) $(SWIG) +# introduce artifical dependency between LIBYANG and FRR +# make sure LIBYANG is compile after FRR +$(LIBYANG)_AFTER = $(FRR) SONIC_MAKE_DEBS += $(LIBYANG) -SONIC_STRETCH_DEBS += $(LIBYANG) LIBYANG_DEV = libyang-dev_$(LIBYANG_VERSION)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(LIBYANG),$(LIBYANG_DEV))) @@ -21,12 +22,18 @@ LIBYANG_DBG = libyang-dbg_$(LIBYANG_VERSION)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(LIBYANG),$(LIBYANG_DBG))) LIBYANG_CPP = libyang-cpp_$(LIBYANG_VERSION)_$(CONFIGURED_ARCH).deb +$(LIBYANG_CPP)_DEPENDS += $(LIBYANG) $(eval $(call add_derived_package,$(LIBYANG),$(LIBYANG_CPP))) LIBYANG_PY3 = python3-yang_$(LIBYANG_VERSION)_$(CONFIGURED_ARCH).deb +$(LIBYANG_PY3)_DEPENDS += $(LIBYANG) $(LIBYANG_CPP) $(eval $(call add_derived_package,$(LIBYANG),$(LIBYANG_PY3))) LIBYANG_PY2 = python2-yang_$(LIBYANG_VERSION)_$(CONFIGURED_ARCH).deb +$(LIBYANG_PY2)_DEPENDS += $(LIBYANG) $(LIBYANG_CPP) $(eval $(call add_derived_package,$(LIBYANG),$(LIBYANG_PY2))) +$(eval $(call add_conflict_package,$(LIBYANG),$(LIBYANG1))) +$(eval $(call add_conflict_package,$(LIBYANG_DEV),$(LIBYANG1_DEV))) + export LIBYANG LIBYANG_DBG LIBYANG_DEV LIBYANG_CPP LIBYANG_PY3 LIBYANG_PY2 diff --git a/rules/libyang1.dep b/rules/libyang1.dep new file mode 100644 index 000000000000..343b06cf9611 --- /dev/null +++ b/rules/libyang1.dep @@ -0,0 +1,10 @@ + +SPATH := $($(LIBYANG1)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/libyang1.mk rules/libyang1.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(LIBYANG1)_CACHE_MODE := GIT_CONTENT_SHA +$(LIBYANG1)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(LIBYANG1)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/libyang1.mk b/rules/libyang1.mk new file mode 100644 index 000000000000..6d24e3fc5a4e --- /dev/null +++ b/rules/libyang1.mk @@ -0,0 +1,43 @@ +# libyang1 + +LIBYANG1_VERSION_BASE = 1.0 +LIBYANG1_VERSION = $(LIBYANG1_VERSION_BASE).184 +LIBYANG1_SUBVERSION = 2 +LIBYANG1_FULLVERSION = $(LIBYANG1_VERSION)-$(LIBYANG1_SUBVERSION) + +export LIBYANG1_VERSION_BASE +export LIBYANG1_VERSION +export LIBYANG1_SUBVERSION +export LIBYANG1_FULLVERSION + +LIBYANG1 = libyang1_$(LIBYANG1_FULLVERSION)_$(CONFIGURED_ARCH).deb +$(LIBYANG1)_SRC_PATH = $(SRC_PATH)/libyang1 +SONIC_MAKE_DEBS += $(LIBYANG1) + +LIBYANG1_DEV = libyang-dev_$(LIBYANG1_FULLVERSION)_$(CONFIGURED_ARCH).deb +$(eval $(call add_derived_package,$(LIBYANG1),$(LIBYANG1_DEV))) + +LIBYANG1_DBG = libyang1-dbgsym_$(LIBYANG1_FULLVERSION)_$(CONFIGURED_ARCH).deb +$(eval $(call add_derived_package,$(LIBYANG1),$(LIBYANG1_DBG))) + +LIBYANG1_CPP = libyang-cpp1_$(LIBYANG1_FULLVERSION)_$(CONFIGURED_ARCH).deb +$(LIBYANG1_CPP)_DEPENDS += $(LIBYANG1) +$(eval $(call add_derived_package,$(LIBYANG1),$(LIBYANG1_CPP))) + +LIBYANG1_CPP_DEV = libyang-cpp-dev_$(LIBYANG1_FULLVERSION)_$(CONFIGURED_ARCH).deb +$(eval $(call add_derived_package,$(LIBYANG1),$(LIBYANG1_CPP_DEV))) + +LIBYANG1_CPP_DBG = libyang-cpp1-dbgsym_$(LIBYANG1_FULLVERSION)_$(CONFIGURED_ARCH).deb +$(eval $(call add_derived_package,$(LIBYANG1),$(LIBYANG1_CPP_DBG))) + +YANG_TOOLS = yang-tools_$(LIBYANG1_FULLVERSION)_all.deb +$(YANG_TOOLS)_DEPENDS += $(LIBYANG1) +$(eval $(call add_derived_package,$(LIBYANG1),$(YANG_TOOLS))) + +LIBYANG1_TOOLS = libyang-tools_$(LIBYANG1_FULLVERSION)_$(CONFIGURED_ARCH).deb +$(eval $(call add_derived_package,$(LIBYANG1),$(LIBYANG1_TOOLS))) + +LIBYANG1_TOOLS_DBG = libyang-tools-dbgsym_$(LIBYANG1_FULLVERSION)_$(CONFIGURED_ARCH).deb +$(eval $(call add_derived_package,$(LIBYANG1),$(LIBYANG1_TOOLS_DBG))) + +export LIBYANG1 LIBYANG1_DBG LIBYANG1_DEV LIBYANG1_CPP LIBYANG1_CPP_DEV LIBYANG1_CPP_DBG YANG_TOOLS LIBYANG1_TOOLS LIBYANG1_TOOLS_DBG diff --git a/rules/linux-kernel.mk b/rules/linux-kernel.mk index e6742bdf14cf..2d369361a9e5 100644 --- a/rules/linux-kernel.mk +++ b/rules/linux-kernel.mk @@ -1,9 +1,9 @@ # linux kernel package -KVERSION_SHORT = 4.9.0-11-2 +KVERSION_SHORT = 4.19.0-12-2 KVERSION = $(KVERSION_SHORT)-$(CONFIGURED_ARCH) -KERNEL_VERSION = 4.9.189 -KERNEL_SUBVERSION = 3+deb9u2 +KERNEL_VERSION = 4.19.152 +KERNEL_SUBVERSION = 1 ifeq ($(CONFIGURED_ARCH), armhf) # Override kernel version for ARMHF as it uses arm MP (multi-platform) for short version KVERSION = $(KVERSION_SHORT)-armmp @@ -18,5 +18,9 @@ SONIC_MAKE_DEBS += $(LINUX_HEADERS_COMMON) LINUX_HEADERS = linux-headers-$(KVERSION)_$(KERNEL_VERSION)-$(KERNEL_SUBVERSION)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(LINUX_HEADERS_COMMON),$(LINUX_HEADERS))) -LINUX_KERNEL = linux-image-$(KVERSION)_$(KERNEL_VERSION)-$(KERNEL_SUBVERSION)_$(CONFIGURED_ARCH).deb +ifeq ($(CONFIGURED_ARCH), armhf) + LINUX_KERNEL = linux-image-$(KVERSION)_$(KERNEL_VERSION)-$(KERNEL_SUBVERSION)_$(CONFIGURED_ARCH).deb +else + LINUX_KERNEL = linux-image-$(KVERSION)-unsigned_$(KERNEL_VERSION)-$(KERNEL_SUBVERSION)_$(CONFIGURED_ARCH).deb +endif $(eval $(call add_derived_package,$(LINUX_HEADERS_COMMON),$(LINUX_KERNEL))) diff --git a/rules/lm-sensors.mk b/rules/lm-sensors.mk index a97b539fd8ad..414aeb72b229 100644 --- a/rules/lm-sensors.mk +++ b/rules/lm-sensors.mk @@ -1,7 +1,11 @@ # lm-senensors package -LM_SENSORS_VERSION=3.4.0 -LM_SENSORS_VERSION_FULL=$(LM_SENSORS_VERSION)-4 +LM_SENSORS_MAJOR_VERSION = 3 +LM_SENSORS_MINOR_VERSION = 5 +LM_SENSORS_PATCH_VERSION = 0 + +LM_SENSORS_VERSION=$(LM_SENSORS_MAJOR_VERSION).$(LM_SENSORS_MINOR_VERSION).$(LM_SENSORS_PATCH_VERSION) +LM_SENSORS_VERSION_FULL=$(LM_SENSORS_VERSION)-3 LM_SENSORS = lm-sensors_$(LM_SENSORS_VERSION_FULL)_$(CONFIGURED_ARCH).deb $(LM_SENSORS)_SRC_PATH = $(SRC_PATH)/lm-sensors @@ -12,18 +16,18 @@ $(eval $(call add_derived_package,$(LM_SENSORS),$(LM_SENSORS_DBG))) FANCONTROL = fancontrol_$(LM_SENSORS_VERSION_FULL)_all.deb $(eval $(call add_derived_package,$(LM_SENSORS),$(FANCONTROL))) -LIBSENSORS = libsensors4_$(LM_SENSORS_VERSION_FULL)_$(CONFIGURED_ARCH).deb +LIBSENSORS = libsensors$(LM_SENSORS_MINOR_VERSION)_$(LM_SENSORS_VERSION_FULL)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(LM_SENSORS),$(LIBSENSORS))) -LIBSENSORS_DBG = libsensors4-dbgsym_$(LM_SENSORS_VERSION_FULL)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(LIBSENSORS),$(LIBSENSORS_DBG))) +LIBSENSORS_DBG = libsensors$(LM_SENSORS_MINOR_VERSION)-dbgsym_$(LM_SENSORS_VERSION_FULL)_$(CONFIGURED_ARCH).deb +$(eval $(call add_derived_package,$(LM_SENSORS),$(LIBSENSORS_DBG))) SENSORD = sensord_$(LM_SENSORS_VERSION_FULL)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(LM_SENSORS),$(SENSORD))) $(SENSORD)_DEPENDS += $(LIBSENSORS) $(LM_SENSORS) SENSORD_DBG = sensord-dbgsym_$(LM_SENSORS_VERSION_FULL)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(SENSORD),$(SENSORD_DBG))) +$(eval $(call add_derived_package,$(LM_SENSORS),$(SENSORD_DBG))) SONIC_MAKE_DEBS += $(LM_SENSORS) diff --git a/rules/monit.mk b/rules/monit.mk index d4c73453e4a6..4c15bc0dfab1 100644 --- a/rules/monit.mk +++ b/rules/monit.mk @@ -8,7 +8,5 @@ MONIT = monit_$(MONIT_VERSION)_$(CONFIGURED_ARCH).deb $(MONIT)_SRC_PATH = $(SRC_PATH)/monit SONIC_MAKE_DEBS += $(MONIT) -SONIC_STRETCH_DEBS += $(MONIT) - MONIT_DBG = monit-dbgsym_$(MONIT_VERSION)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(MONIT),$(MONIT_DBG))) diff --git a/rules/ntp.dep b/rules/ntp.dep new file mode 100644 index 000000000000..c261482f9327 --- /dev/null +++ b/rules/ntp.dep @@ -0,0 +1,10 @@ + +SPATH := $($(NTP)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/ntp.mk rules/ntp.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(NTP)_CACHE_MODE := GIT_CONTENT_SHA +$(NTP)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(NTP)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/ntp.mk b/rules/ntp.mk new file mode 100644 index 000000000000..13cbb495f78f --- /dev/null +++ b/rules/ntp.mk @@ -0,0 +1,11 @@ +# ntp package + +NTP_VERSION = 4.2.8p12+dfsg +export NTP_VERSION + +NTP = ntp_$(NTP_VERSION)-4+deb10u2_$(CONFIGURED_ARCH).deb +$(NTP)_SRC_PATH = $(SRC_PATH)/ntp +SONIC_MAKE_DEBS += $(NTP) +SONIC_STRETCH_DEBS += $(NTP) + +export NTP diff --git a/rules/openssh.dep b/rules/openssh.dep new file mode 100644 index 000000000000..7450743e667b --- /dev/null +++ b/rules/openssh.dep @@ -0,0 +1,8 @@ +SPATH := $($(OPENSSH_SERVER)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/openssh.mk rules/openssh.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(OPENSSH_SERVER)_CACHE_MODE := GIT_CONTENT_SHA +$(OPENSSH_SERVER)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(OPENSSH_SERVER)_DEP_FILES := $(DEP_FILES) diff --git a/rules/openssh.mk b/rules/openssh.mk new file mode 100644 index 000000000000..0cc3de621039 --- /dev/null +++ b/rules/openssh.mk @@ -0,0 +1,14 @@ +# openssh package + +OPENSSH_VERSION = 7.9p1-10+deb10u2 + +export OPENSSH_VERSION + +OPENSSH_SERVER = openssh-server_$(OPENSSH_VERSION)_$(CONFIGURED_ARCH).deb +$(OPENSSH_SERVER)_SRC_PATH = $(SRC_PATH)/openssh +SONIC_MAKE_DEBS += $(OPENSSH_SERVER) + +# The .c, .cpp, .h & .hpp files under src/{$DBG_SRC_ARCHIVE list} +# are archived into debug one image to facilitate debugging. +# +DBG_SRC_ARCHIVE += openssh diff --git a/rules/python-click.dep b/rules/python-click.dep deleted file mode 100644 index 93e75a71efb1..000000000000 --- a/rules/python-click.dep +++ /dev/null @@ -1,10 +0,0 @@ - -SPATH := $($(PYTHON_CLICK)_SRC_PATH) -DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/python-click.mk rules/python-click.dep -DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) -DEP_FILES += $(shell git ls-files $(SPATH)) - -$(PYTHON_CLICK)_CACHE_MODE := GIT_CONTENT_SHA -$(PYTHON_CLICK)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) -$(PYTHON_CLICK)_DEP_FILES := $(DEP_FILES) - diff --git a/rules/python-click.mk b/rules/python-click.mk deleted file mode 100644 index 5d48dc30d604..000000000000 --- a/rules/python-click.mk +++ /dev/null @@ -1,17 +0,0 @@ -# python-click package -# -# Python Click versions < 6.7 have a bug which causes bash completion -# functionality to stop working after two sublevels. sonic-utilities depends -# on this package, and the most recent version provided by Debian Jessie and -# Stretch is v6.6. We build version 6.7 from source in order to fix this bug. -# TODO: If we upgrade to a distro which provides a version >= 6.7 we will no -# longer need to build this. - -PYTHON_CLICK_VERSION = 6.7-4 - -export PYTHON_CLICK_VERSION - -PYTHON_CLICK = python-click_$(PYTHON_CLICK_VERSION)_all.deb -$(PYTHON_CLICK)_SRC_PATH = $(SRC_PATH)/python-click -SONIC_MAKE_DEBS += $(PYTHON_CLICK) -SONIC_STRETCH_DEBS += $(PYTHON_CLICK) diff --git a/rules/python3.dep b/rules/python3.dep deleted file mode 100644 index 98cc5eb3642c..000000000000 --- a/rules/python3.dep +++ /dev/null @@ -1,10 +0,0 @@ - -SPATH := $($(LIBPY3_MIN)_SRC_PATH) -DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/python3.mk rules/python3.dep -DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) -DEP_FILES += $(shell git ls-files $(SPATH)) - -$(LIBPY3_MIN)_CACHE_MODE := GIT_CONTENT_SHA -$(LIBPY3_MIN)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) -$(LIBPY3_MIN)_DEP_FILES := $(DEP_FILES) - diff --git a/rules/python3.mk b/rules/python3.mk deleted file mode 100644 index d9d19d8d1f97..000000000000 --- a/rules/python3.mk +++ /dev/null @@ -1,35 +0,0 @@ -PYTHON_VER=3.6.0-1 -PYTHON_PNAME=python3.6 - -export PYTHON_VER -export PYTHON_PNAME - -LIBPY3_MIN = lib$(PYTHON_PNAME)-minimal_$(PYTHON_VER)_$(CONFIGURED_ARCH).deb -$(LIBPY3_MIN)_SRC_PATH = $(SRC_PATH)/python3 -$(LIBPY3_MIN)_DEPENDS += -$(LIBPY3_MIN)_RDEPENDS += -SONIC_MAKE_DEBS += $(LIBPY3_MIN) - -LIBPY3_STD = lib$(PYTHON_PNAME)-stdlib_$(PYTHON_VER)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(LIBPY3_MIN),$(LIBPY3_STD))) -$(LIBPY3_STD)_DEPENDS += $(LIBMPDECIMAL) -$(LIBPY3_STD)_RDEPENDS += $(LIBPY3_MIN) $(LIBMPDECIMAL) - -LIBPY3 = lib$(PYTHON_PNAME)_$(PYTHON_VER)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(LIBPY3_MIN),$(LIBPY3))) -$(LIBPY3)_DEPENDS += $(LIBPY3_STD) -$(LIBPY3)_RDEPENDS += $(LIBPY3_MIN) $(LIBPY3_STD) - -PY3_MIN = $(PYTHON_PNAME)-minimal_$(PYTHON_VER)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(LIBPY3_MIN),$(PY3_MIN))) -$(PY3_MIN)_RDEPENDS += $(LIBPY3_MIN) - -PY3 = $(PYTHON_PNAME)_$(PYTHON_VER)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(LIBPY3_MIN),$(PY3))) -$(PY3)_DEPENDS += $(PY3_MIN) $(LIBPY3_STD) -$(PY3)_RDEPENDS += $(PY3_MIN) $(LIBPY3_STD) - -LIBPY3_DEV = lib$(PYTHON_PNAME)-dev_$(PYTHON_VER)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(LIBPY3_MIN),$(LIBPY3_DEV))) -$(LIBPY3_DEV)_DEPENDS += $(LIBPY3) $($(LIBPY3)_DEPENDS) -$(LIBPY3_DEV)_RDEPENDS += $(LIBPY3) $($(LIBPY3)_RDEPENDS) diff --git a/rules/radvd.dep b/rules/radvd.dep deleted file mode 100644 index 457a74becc77..000000000000 --- a/rules/radvd.dep +++ /dev/null @@ -1,10 +0,0 @@ - -SPATH := $($(RADVD)_SRC_PATH) -DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/radvd.mk rules/radvd.dep -DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) -DEP_FILES += $(shell git ls-files $(SPATH)) - -$(RADVD)_CACHE_MODE := GIT_CONTENT_SHA -$(RADVD)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) -$(RADVD)_DEP_FILES := $(DEP_FILES) - diff --git a/rules/radvd.mk b/rules/radvd.mk deleted file mode 100644 index fcde8c5767b8..000000000000 --- a/rules/radvd.mk +++ /dev/null @@ -1,18 +0,0 @@ -# radvd package - -RADVD_VERSION = 2.17-2~bpo9+1 - -export RADVD_VERSION - -RADVD = radvd_$(RADVD_VERSION)_$(CONFIGURED_ARCH).deb -$(RADVD)_SRC_PATH = $(SRC_PATH)/radvd -SONIC_MAKE_DEBS += $(RADVD) -SONIC_STRETCH_DEBS += $(RADVD) - -RADVD_DBG = radvd-dbgsym_$(RADVD_VERSION)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(RADVD),$(RADVD_DBG))) - -# The .c, .cpp, .h & .hpp files under src/{$DBG_SRC_ARCHIVE list} -# are archived into debug one image to facilitate debugging. -# -DBG_SRC_ARCHIVE += radvd diff --git a/rules/redis-dump-load-py3.dep b/rules/redis-dump-load-py3.dep new file mode 100644 index 000000000000..1c230acd1f7a --- /dev/null +++ b/rules/redis-dump-load-py3.dep @@ -0,0 +1,10 @@ +SPATH := $($(REDIS_DUMP_LOAD_PY3)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/redis-dump-load-py3.mk rules/redis-dump-load-py3.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) + +$(REDIS_DUMP_LOAD_PY3)_CACHE_MODE := GIT_CONTENT_SHA +$(REDIS_DUMP_LOAD_PY3)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(REDIS_DUMP_LOAD_PY3)_DEP_FILES := $(DEP_FILES) +$(REDIS_DUMP_LOAD_PY3)_SMDEP_FILES := $(SMDEP_FILES) +$(REDIS_DUMP_LOAD_PY3)_SMDEP_PATHS := $(SPATH) diff --git a/rules/redis-dump-load-py3.mk b/rules/redis-dump-load-py3.mk new file mode 100644 index 000000000000..875b5e1c8132 --- /dev/null +++ b/rules/redis-dump-load-py3.mk @@ -0,0 +1,9 @@ +# redis_dump_load python3 wheel + +REDIS_DUMP_LOAD_PY3 = redis_dump_load-1.1-py3-none-any.whl +$(REDIS_DUMP_LOAD_PY3)_SRC_PATH = $(SRC_PATH)/redis-dump-load +$(REDIS_DUMP_LOAD_PY3)_PYTHON_VERSION = 3 +# Synthetic dependency just to avoid race condition +$(REDIS_DUMP_LOAD_PY3)_DEPENDS += $(REDIS_DUMP_LOAD_PY2) +$(REDIS_DUMP_LOAD_PY3)_TEST = n +SONIC_PYTHON_WHEELS += $(REDIS_DUMP_LOAD_PY3) diff --git a/rules/redis.mk b/rules/redis.mk index 83b3d81ba6c5..53566b5cdf8b 100644 --- a/rules/redis.mk +++ b/rules/redis.mk @@ -1,26 +1,30 @@ # redis package +# TODO: docker-sonic-p4 depends on redis-tools in Jessie. +# Remove this file and src/redis after that resolved. +ifneq ($(BLDENV),buster) -REDIS_VERSION = 5.0.3-3~bpo9+2 + REDIS_VERSION = 5.0.3-3~bpo9+2 -REDIS_TOOLS = redis-tools_$(REDIS_VERSION)_$(CONFIGURED_ARCH).deb -$(REDIS_TOOLS)_SRC_PATH = $(SRC_PATH)/redis -$(REDIS_TOOLS)_DEPENDS += $(LIBHIREDIS_DEV) -$(REDIS_TOOLS)_RDEPENDS += $(LIBHIREDIS) -SONIC_MAKE_DEBS += $(REDIS_TOOLS) + REDIS_TOOLS = redis-tools_$(REDIS_VERSION)_$(CONFIGURED_ARCH).deb + $(REDIS_TOOLS)_SRC_PATH = $(SRC_PATH)/redis + $(REDIS_TOOLS)_DEPENDS += $(LIBHIREDIS_DEV) + $(REDIS_TOOLS)_RDEPENDS += $(LIBHIREDIS) + SONIC_MAKE_DEBS += $(REDIS_TOOLS) -REDIS_TOOLS_DBG = redis-tools-dbgsym_$(REDIS_VERSION)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(REDIS_TOOLS),$(REDIS_TOOLS_DBG))) + REDIS_TOOLS_DBG = redis-tools-dbgsym_$(REDIS_VERSION)_$(CONFIGURED_ARCH).deb + $(eval $(call add_derived_package,$(REDIS_TOOLS),$(REDIS_TOOLS_DBG))) -REDIS_SERVER = redis-server_$(REDIS_VERSION)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(REDIS_TOOLS),$(REDIS_SERVER))) + REDIS_SERVER = redis-server_$(REDIS_VERSION)_$(CONFIGURED_ARCH).deb + $(eval $(call add_derived_package,$(REDIS_TOOLS),$(REDIS_SERVER))) -REDIS_SENTINEL = redis-sentinel_$(REDIS_VERSION)_$(CONFIGURED_ARCH).deb -$(REDIS_SENTINEL)_DEPENDS += $(REDIS_SERVER) -$(REDIS_SENTINEL)_RDEPENDS += $(REDIS_SERVER) -$(eval $(call add_derived_package,$(REDIS_TOOLS),$(REDIS_SENTINEL))) + REDIS_SENTINEL = redis-sentinel_$(REDIS_VERSION)_$(CONFIGURED_ARCH).deb + $(REDIS_SENTINEL)_DEPENDS += $(REDIS_SERVER) + $(REDIS_SENTINEL)_RDEPENDS += $(REDIS_SERVER) + $(eval $(call add_derived_package,$(REDIS_TOOLS),$(REDIS_SENTINEL))) -# The .c, .cpp, .h & .hpp files under src/{$DBG_SRC_ARCHIVE list} -# are archived into debug one image to facilitate debugging. -# -DBG_SRC_ARCHIVE += redis + # The .c, .cpp, .h & .hpp files under src/{$DBG_SRC_ARCHIVE list} + # are archived into debug one image to facilitate debugging. + # + DBG_SRC_ARCHIVE += redis +endif diff --git a/rules/sairedis.mk b/rules/sairedis.mk index fd026541a4fb..67148d1b5819 100644 --- a/rules/sairedis.mk +++ b/rules/sairedis.mk @@ -1,16 +1,10 @@ # sairedis package LIBSAIREDIS = libsairedis_1.0.0_$(CONFIGURED_ARCH).deb +$(LIBSAIREDIS)_DPKG_TARGET = binary-sairedis $(LIBSAIREDIS)_SRC_PATH = $(SRC_PATH)/sonic-sairedis $(LIBSAIREDIS)_DEPENDS += $(LIBSWSSCOMMON_DEV) $(LIBSAIREDIS)_RDEPENDS += $(LIBSWSSCOMMON) -ifneq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DPKG_TARGET = binary-syncd -else -# Inject libthrift build dependency for RPC build -$(LIBSAIREDIS)_DEPENDS += $(LIBSWSSCOMMON_DEV) $(LIBTHRIFT_DEV) -$(LIBSAIREDIS)_DPKG_TARGET = binary-syncd-rpc -endif $(LIBSAIREDIS)_DEB_BUILD_OPTIONS = nocheck SONIC_DPKG_DEBS += $(LIBSAIREDIS) @@ -22,18 +16,7 @@ $(eval $(call add_derived_package,$(LIBSAIREDIS),$(LIBSAIVS))) LIBSAIVS_DEV = libsaivs-dev_1.0.0_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(LIBSAIREDIS),$(LIBSAIVS_DEV))) - -ifneq ($(CONFIGURED_PLATFORM),vs) -SYNCD = syncd_1.0.0_$(CONFIGURED_ARCH).deb -$(SYNCD)_RDEPENDS += $(LIBSAIREDIS) $(LIBSAIMETADATA) -$(eval $(call add_derived_package,$(LIBSAIREDIS),$(SYNCD))) - -ifeq ($(ENABLE_SYNCD_RPC),y) -SYNCD_RPC = syncd-rpc_1.0.0_$(CONFIGURED_ARCH).deb -$(SYNCD_RPC)_RDEPENDS += $(LIBSAIREDIS) $(LIBSAIMETADATA) -$(eval $(call add_derived_package,$(LIBSAIREDIS),$(SYNCD_RPC))) -endif -endif +$(LIBSAIVS_DEV)_DEPENDS += $(LIBSAIVS) LIBSAIMETADATA = libsaimetadata_1.0.0_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(LIBSAIREDIS),$(LIBSAIMETADATA))) @@ -52,20 +35,6 @@ $(LIBSAIVS_DBG)_DEPENDS += $(LIBSAIVS) $(LIBSAIVS_DBG)_RDEPENDS += $(LIBSAIVS) $(eval $(call add_derived_package,$(LIBSAIREDIS),$(LIBSAIVS_DBG))) -ifneq ($(CONFIGURED_PLATFORM),vs) -SYNCD_DBG = syncd-dbg_1.0.0_$(CONFIGURED_ARCH).deb -$(SYNCD_DBG)_DEPENDS += $(SYNCD) -$(SYNCD_DBG)_RDEPENDS += $(SYNCD) -$(eval $(call add_derived_package,$(LIBSAIREDIS),$(SYNCD_DBG))) - -ifeq ($(ENABLE_SYNCD_RPC),y) -SYNCD_RPC_DBG = syncd-rpc-dbg_1.0.0_$(CONFIGURED_ARCH).deb -$(SYNCD_RPC_DBG)_DEPENDS += $(SYNCD_RPC) -$(SYNCD_RPC_DBG)_RDEPENDS += $(SYNCD_RPC) -$(eval $(call add_derived_package,$(LIBSAIREDIS),$(SYNCD_RPC_DBG))) -endif -endif - LIBSAIMETADATA_DBG = libsaimetadata-dbg_1.0.0_$(CONFIGURED_ARCH).deb $(LIBSAIMETADATA_DBG)_DEPENDS += $(LIBSAIMETADATA) $(LIBSAIMETADATA_DBG)_RDEPENDS += $(LIBSAIMETADATA) @@ -75,4 +44,3 @@ $(eval $(call add_derived_package,$(LIBSAIREDIS),$(LIBSAIMETADATA_DBG))) # are archived into debug one image to facilitate debugging. # DBG_SRC_ARCHIVE += sonic-sairedis - diff --git a/rules/scripts.dep b/rules/scripts.dep index 907ec1722b5b..929611852ea4 100644 --- a/rules/scripts.dep +++ b/rules/scripts.dep @@ -1,8 +1,10 @@ #DPKG FRK $(ARP_UPDATE_SCRIPT)_CACHE_MODE := none +$(ARP_UPDATE_VARS_TEMPLATE)_CACHE_MODE := none $(CONFIGDB_LOAD_SCRIPT)_CACHE_MODE := none $(BUFFERS_CONFIG_TEMPLATE)_CACHE_MODE := none $(UPDATE_PROC_VARIABLES_SCRIPT)_CACHE_MODE := none $(QOS_CONFIG_TEMPLATE)_CACHE_MODE := none $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT)_CACHE_MODE := none +$(COPP_CONFIG_TEMPLATE)_CACHE_MODE := none diff --git a/rules/scripts.mk b/rules/scripts.mk index 8c6d0324fc0e..e0694a1cdf9b 100644 --- a/rules/scripts.mk +++ b/rules/scripts.mk @@ -2,6 +2,9 @@ ARP_UPDATE_SCRIPT = arp_update $(ARP_UPDATE_SCRIPT)_PATH = files/scripts +ARP_UPDATE_VARS_TEMPLATE = arp_update_vars.j2 +$(ARP_UPDATE_VARS_TEMPLATE)_PATH = files/build_templates + CONFIGDB_LOAD_SCRIPT = configdb-load.sh $(CONFIGDB_LOAD_SCRIPT)_PATH = files/scripts @@ -14,10 +17,25 @@ $(QOS_CONFIG_TEMPLATE)_PATH = files/build_templates SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT = supervisor-proc-exit-listener $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT)_PATH = files/scripts +SYSCTL_NET_CONFIG = sysctl-net.conf +$(SYSCTL_NET_CONFIG)_PATH = files/image_config/sysctl + +UPDATE_CHASSISDB_CONFIG_SCRIPT = update_chassisdb_config +$(UPDATE_CHASSISDB_CONFIG_SCRIPT)_PATH = files/scripts + +SWSS_VARS_TEMPLATE = swss_vars.j2 +$(SWSS_VARS_TEMPLATE)_PATH = files/build_templates + +COPP_CONFIG_TEMPLATE = copp_cfg.j2 +$(COPP_CONFIG_TEMPLATE)_PATH = files/image_config/copp + SONIC_COPY_FILES += $(CONFIGDB_LOAD_SCRIPT) \ $(ARP_UPDATE_SCRIPT) \ + $(ARP_UPDATE_VARS_TEMPLATE) \ $(BUFFERS_CONFIG_TEMPLATE) \ $(QOS_CONFIG_TEMPLATE) \ - $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) - - + $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) \ + $(SYSCTL_NET_CONFIG) \ + $(UPDATE_CHASSISDB_CONFIG_SCRIPT) \ + $(SWSS_VARS_TEMPLATE) \ + $(COPP_CONFIG_TEMPLATE) diff --git a/rules/sflow.mk b/rules/sflow.mk index d4c579ddf167..7f0ac72bed3f 100644 --- a/rules/sflow.mk +++ b/rules/sflow.mk @@ -1,7 +1,7 @@ # host-sflow package -HSFLOWD_VERSION = 2.0.26 -HSFLOWD_SUBVERSION = 3 +HSFLOWD_VERSION = 2.0.32 +HSFLOWD_SUBVERSION = 1 export HSFLOWD_VERSION HSFLOWD_SUBVERSION HSFLOWD = hsflowd_$(HSFLOWD_VERSION)-$(HSFLOWD_SUBVERSION)_$(CONFIGURED_ARCH).deb @@ -9,7 +9,6 @@ $(HSFLOWD)_DEPENDS += $(LIBHIREDIS_DEV) $(HSFLOWD)_SRC_PATH = $(SRC_PATH)/sflow/hsflowd SONIC_MAKE_DEBS += $(HSFLOWD) -SONIC_STRETCH_DEBS += $(HSFLOWD) HSFLOWD_DBG = hsflowd-dbg_$(HSFLOWD_VERSION)-$(HSFLOWD_SUBVERSION)_$(CONFIGURED_ARCH).deb $(HSFLOWD_DBG)_DEPENDS += $(HSFLOWD) @@ -27,7 +26,6 @@ SFLOWTOOL = sflowtool_$(SFLOWTOOL_VERSION)_$(CONFIGURED_ARCH).deb $(SFLOWTOOL)_SRC_PATH = $(SRC_PATH)/sflow/sflowtool SONIC_MAKE_DEBS += $(SFLOWTOOL) -SONIC_STRETCH_DEBS += $(SFLOWTOOL) export SFLOWTOOL # psample package @@ -40,7 +38,6 @@ PSAMPLE = psample_$(PSAMPLE_VERSION)-$(PSAMPLE_SUBVERSION)_$(CONFIGURED_ARCH).de $(PSAMPLE)_SRC_PATH = $(SRC_PATH)/sflow/psample SONIC_MAKE_DEBS += $(PSAMPLE) -SONIC_STRETCH_DEBS += $(PSAMPLE) export PSAMPLE # The .c, .cpp, .h & .hpp files under src/{$DBG_SRC_ARCHIVE list} diff --git a/rules/smartmontools.mk b/rules/smartmontools.mk index 90072592b954..7cc61eee6feb 100644 --- a/rules/smartmontools.mk +++ b/rules/smartmontools.mk @@ -9,5 +9,4 @@ export SMARTMONTOOLS_VERSION_MAJOR SMARTMONTOOLS_VERSION_FULL SMARTMONTOOLS = smartmontools_$(SMARTMONTOOLS_VERSION_FULL)_$(CONFIGURED_ARCH).deb $(SMARTMONTOOLS)_SRC_PATH = $(SRC_PATH)/smartmontools -SONIC_STRETCH_DEBS += $(SMARTMONTOOLS) SONIC_MAKE_DEBS += $(SMARTMONTOOLS) diff --git a/rules/snmpd.mk b/rules/snmpd.mk index 8fb8495ebc3d..7922e2097ff0 100644 --- a/rules/snmpd.mk +++ b/rules/snmpd.mk @@ -1,7 +1,7 @@ # snmpd package SNMPD_VERSION = 5.7.3+dfsg -SNMPD_VERSION_FULL = $(SNMPD_VERSION)-1.5 +SNMPD_VERSION_FULL = $(SNMPD_VERSION)-5 export SNMPD_VERSION SNMPD_VERSION_FULL @@ -27,10 +27,10 @@ $(SNMPD)_RDEPENDS += $(LIBSNMP) $(eval $(call add_derived_package,$(LIBSNMP_BASE),$(SNMPD))) SNMP_DBG = snmp-dbgsym_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(SNMP),$(SNMP_DBG))) +$(eval $(call add_derived_package,$(LIBSNMP_BASE),$(SNMP_DBG))) SNMPD_DBG = snmpd-dbgsym_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(SNMPD),$(SNMPD_DBG))) +$(eval $(call add_derived_package,$(LIBSNMP_BASE),$(SNMPD_DBG))) LIBSNMP = libsnmp30_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb $(LIBSNMP)_RDEPENDS += $(LIBSNMP_BASE) @@ -50,11 +50,6 @@ $(LIBSNMP_PERL)_DEPENDS += $(LIBSNMP) $(LIBSNMP_PERL)_RDEPENDS += $(LIBSNMP) $(eval $(call add_derived_package,$(LIBSNMP_BASE),$(LIBSNMP_PERL))) -PYTHON_NETSNMP = python-netsnmp_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb -$(PYTHON_NETSNMP)_DEPENDS += $(LIBSNMP) -$(PYTHON_NETSNMP)_RDEPENDS += $(LIBSNMP) -$(eval $(call add_derived_package,$(LIBSNMP_BASE),$(PYTHON_NETSNMP))) - TKMIB = tkmib_$(SNMPD_VERSION_FULL)_all.deb $(TKMIB)_DEPENDS += $(LIBSNMP_PERL) $(TKMIB)_RDEPENDS += $(LIBSNMP_PERL) diff --git a/rules/sonic-chassisd.dep b/rules/sonic-chassisd.dep new file mode 100644 index 000000000000..bf27492937e8 --- /dev/null +++ b/rules/sonic-chassisd.dep @@ -0,0 +1,10 @@ +SPATH := $($(SONIC_CHASSISD_PY3)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-chassisd.mk rules/sonic-chassisd.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) + +$(SONIC_CHASSISD_PY3)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_CHASSISD_PY3)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_CHASSISD_PY3)_DEP_FILES := $(DEP_FILES) +$(SONIC_CHASSISD_PY3)_SMDEP_FILES := $(SMDEP_FILES) +$(SONIC_CHASSISD_PY3)_SMDEP_PATHS := $(SPATH) diff --git a/rules/sonic-chassisd.mk b/rules/sonic-chassisd.mk new file mode 100644 index 000000000000..46a49d359769 --- /dev/null +++ b/rules/sonic-chassisd.mk @@ -0,0 +1,8 @@ +# sonic-chassisd (SONiC Chassis mgmt daemon) wheel package + +SONIC_CHASSISD_PY3 = sonic_chassisd-1.0-py3-none-any.whl +$(SONIC_CHASSISD_PY3)_SRC_PATH = $(SRC_PATH)/sonic-platform-daemons/sonic-chassisd +$(SONIC_CHASSISD_PY3)_DEPENDS = $(SONIC_PY_COMMON_PY3) +$(SONIC_CHASSISD_PY3)_DEBS_DEPENDS = $(LIBSWSSCOMMON) $(PYTHON3_SWSSCOMMON) +$(SONIC_CHASSISD_PY3)_PYTHON_VERSION = 3 +SONIC_PYTHON_WHEELS += $(SONIC_CHASSISD_PY3) diff --git a/rules/sonic-config.dep b/rules/sonic-config.dep index f4c74d075d51..148e43a96a5c 100644 --- a/rules/sonic-config.dep +++ b/rules/sonic-config.dep @@ -1,10 +1,19 @@ +# SONIC_CONFIG_ENGINE_PY2 package -SPATH := $($(SONIC_CONFIG_ENGINE)_SRC_PATH) +SPATH := $($(SONIC_CONFIG_ENGINE_PY2)_SRC_PATH) DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-config.mk rules/sonic-config.dep DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) DEP_FILES += $(shell git ls-files $(SPATH)) -$(SONIC_CONFIG_ENGINE)_CACHE_MODE := GIT_CONTENT_SHA -$(SONIC_CONFIG_ENGINE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) -$(SONIC_CONFIG_ENGINE)_DEP_FILES := $(DEP_FILES) +$(SONIC_CONFIG_ENGINE_PY2)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_CONFIG_ENGINE_PY2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_CONFIG_ENGINE_PY2)_DEP_FILES := $(DEP_FILES) + +# SONIC_CONFIG_ENGINE_PY3 package + +SPATH := $($(SONIC_CONFIG_ENGINE_PY3)_SRC_PATH) + +$(SONIC_CONFIG_ENGINE_PY3)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_CONFIG_ENGINE_PY3)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_CONFIG_ENGINE_PY3)_DEP_FILES := $(DEP_FILES) diff --git a/rules/sonic-config.mk b/rules/sonic-config.mk index 854b577b3362..e8e59fc1b92d 100644 --- a/rules/sonic-config.mk +++ b/rules/sonic-config.mk @@ -1,7 +1,20 @@ -# sonic-config-engine package +# SONIC_CONFIG_ENGINE_PY2 package -SONIC_CONFIG_ENGINE = sonic_config_engine-1.0-py2-none-any.whl -$(SONIC_CONFIG_ENGINE)_SRC_PATH = $(SRC_PATH)/sonic-config-engine -$(SONIC_CONFIG_ENGINE)_DEPENDS += $(SWSSSDK_PY2) -$(SONIC_CONFIG_ENGINE)_PYTHON_VERSION = 2 -SONIC_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE) +SONIC_CONFIG_ENGINE_PY2 = sonic_config_engine-1.0-py2-none-any.whl +$(SONIC_CONFIG_ENGINE_PY2)_SRC_PATH = $(SRC_PATH)/sonic-config-engine +$(SONIC_CONFIG_ENGINE_PY2)_DEPENDS += $(SONIC_PY_COMMON_PY2) +$(SONIC_CONFIG_ENGINE_PY2)_DEBS_DEPENDS += $(PYTHON_SWSSCOMMON) +$(SONIC_CONFIG_ENGINE_PY2)_PYTHON_VERSION = 2 +SONIC_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE_PY2) + +# SONIC_CONFIG_ENGINE_PY3 package + +SONIC_CONFIG_ENGINE_PY3 = sonic_config_engine-1.0-py3-none-any.whl +$(SONIC_CONFIG_ENGINE_PY3)_SRC_PATH = $(SRC_PATH)/sonic-config-engine +$(SONIC_CONFIG_ENGINE_PY3)_DEPENDS += $(SONIC_PY_COMMON_PY3) +$(SONIC_CONFIG_ENGINE_PY3)_DEBS_DEPENDS += $(PYTHON3_SWSSCOMMON) +# Synthetic dependency to avoid building the Python 2 and 3 packages +# simultaneously and any potential conflicts which may arise +$(SONIC_CONFIG_ENGINE_PY3)_DEPENDS += $(SONIC_CONFIG_ENGINE_PY2) +$(SONIC_CONFIG_ENGINE_PY3)_PYTHON_VERSION = 3 +SONIC_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE_PY3) diff --git a/rules/sonic-ctrmgrd.dep b/rules/sonic-ctrmgrd.dep new file mode 100644 index 000000000000..b6564212769c --- /dev/null +++ b/rules/sonic-ctrmgrd.dep @@ -0,0 +1,8 @@ +SPATH := $($(SONIC_CTRMGRD)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-ctrmgrd.mk rules/sonic-ctrmgrd.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(SONIC_CTRMGRD)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_CTRMGRD)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_CTRMGRD)_DEP_FILES := $(DEP_FILES) diff --git a/rules/sonic-ctrmgrd.mk b/rules/sonic-ctrmgrd.mk new file mode 100644 index 000000000000..659a2cf4ace1 --- /dev/null +++ b/rules/sonic-ctrmgrd.mk @@ -0,0 +1,31 @@ +# sonic-ctrmgrd package + +SONIC_CTRMGRD = sonic_ctrmgrd-1.0.0-py3-none-any.whl +$(SONIC_CTRMGRD)_SRC_PATH = $(SRC_PATH)/sonic-ctrmgrd +$(SONIC_CTRMGRD)_FILES_PATH = $($(SONIC_CTRMGRD)_SRC_PATH)/ctrmgr + +$(SONIC_CTRMGRD)_PYTHON_VERSION = 3 +$(SONIC_CTRMGRD)_DEBS_DEPENDS += $(PYTHON3_SWSSCOMMON) +$(SONIC_CTRMGRD)_DEPENDS += $(SONIC_PY_COMMON_PY3) + +$(SONIC_CTRMGRD)_CONTAINER_SCRIPT = container +$($(SONIC_CTRMGRD)_CONTAINER_SCRIPT)_PATH = $($(SONIC_CTRMGRD)_FILES_PATH) + +$(SONIC_CTRMGRD)_STARTUP_SCRIPT = container_startup.py +$($(SONIC_CTRMGRD)_STARTUP_SCRIPT)_PATH = $($(SONIC_CTRMGRD)_FILES_PATH) + +$(SONIC_CTRMGRD)_CFG_JSON = remote_ctr.config.json +$($(SONIC_CTRMGRD)_CFG_JSON)_PATH = $($(SONIC_CTRMGRD)_FILES_PATH) + +$(SONIC_CTRMGRD)_SERVICE = ctrmgrd.service +$($(SONIC_CTRMGRD)_SERVICE)_PATH = $($(SONIC_CTRMGRD)_FILES_PATH) + +SONIC_PYTHON_WHEELS += $(SONIC_CTRMGRD) + +$(SONIC_CTRMGRD)_FILES = $($(SONIC_CTRMGRD)_CONTAINER_SCRIPT) +$(SONIC_CTRMGRD)_FILES += $($(SONIC_CTRMGRD)_STARTUP_SCRIPT) +$(SONIC_CTRMGRD)_FILES += $($(SONIC_CTRMGRD)_CFG_JSON) +$(SONIC_CTRMGRD)_FILES += $($(SONIC_CTRMGRD)_SERVICE) + +SONIC_COPY_FILES += $($(SONIC_CTRMGRD)_FILES) + diff --git a/rules/sonic-daemon-base.dep b/rules/sonic-daemon-base.dep deleted file mode 100644 index 2c6e8a38c757..000000000000 --- a/rules/sonic-daemon-base.dep +++ /dev/null @@ -1,10 +0,0 @@ - -SPATH := $($(SONIC_DAEMON_BASE_PY2)_SRC_PATH) -DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-daemon-base.mk rules/sonic-daemon-base.dep -DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) -DEP_FILES += $(shell git ls-files $(SPATH)) - -$(SONIC_DAEMON_BASE_PY2)_CACHE_MODE := GIT_CONTENT_SHA -$(SONIC_DAEMON_BASE_PY2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) -$(SONIC_DAEMON_BASE_PY2)_DEP_FILES := $(DEP_FILES) - diff --git a/rules/sonic-daemon-base.mk b/rules/sonic-daemon-base.mk deleted file mode 100644 index 5385c18f1f12..000000000000 --- a/rules/sonic-daemon-base.mk +++ /dev/null @@ -1,8 +0,0 @@ -# SONIC_DAEMON_BASE_PY2 package - -SONIC_DAEMON_BASE_PY2 = sonic_daemon_base-1.0-py2-none-any.whl -$(SONIC_DAEMON_BASE_PY2)_SRC_PATH = $(SRC_PATH)/sonic-daemon-base -$(SONIC_DAEMON_BASE_PY2)_PYTHON_VERSION = 2 -SONIC_PYTHON_WHEELS += $(SONIC_DAEMON_BASE_PY2) - -export daemon_base_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_DAEMON_BASE_PY2))" diff --git a/rules/sonic-device-data.dep b/rules/sonic-device-data.dep index c6105f939f67..325b1492ab49 100644 --- a/rules/sonic-device-data.dep +++ b/rules/sonic-device-data.dep @@ -3,6 +3,7 @@ SPATH := $($(SONIC_DEVICE_DATA)_SRC_PATH) DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-device-data.mk rules/sonic-device-data.dep DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) DEP_FILES += $(shell git ls-files $(SPATH)) +DEP_FILES += $(shell find device -type l -prune -o -type f -print ) $(SONIC_DEVICE_DATA)_CACHE_MODE := GIT_CONTENT_SHA $(SONIC_DEVICE_DATA)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) diff --git a/rules/sonic-device-data.mk b/rules/sonic-device-data.mk index 4a5bff1a6fa6..abf7d0501f93 100644 --- a/rules/sonic-device-data.mk +++ b/rules/sonic-device-data.mk @@ -8,4 +8,3 @@ export SONIC_DEVICE_DATA_VERSION SONIC_DEVICE_DATA_VERSION_FULL SONIC_DEVICE_DATA = sonic-device-data_$(SONIC_DEVICE_DATA_VERSION_FULL)_all.deb $(SONIC_DEVICE_DATA)_SRC_PATH = $(SRC_PATH)/sonic-device-data SONIC_MAKE_DEBS += $(SONIC_DEVICE_DATA) -SONIC_STRETCH_DEBS += $(SONIC_DEVICE_DATA) diff --git a/rules/sonic-frr-mgmt-framework.dep b/rules/sonic-frr-mgmt-framework.dep new file mode 100644 index 000000000000..318c4edd1da8 --- /dev/null +++ b/rules/sonic-frr-mgmt-framework.dep @@ -0,0 +1,8 @@ +SPATH := $($(SONIC_FRR_MGMT_FRAMEWORK)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-frr-mgmt-framework.mk rules/sonic-frr-mgmt-framework.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(SONIC_FRR_MGMT_FRAMEWORK)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_FRR_MGMT_FRAMEWORK)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_FRR_MGMT_FRAMEWORK)_DEP_FILES := $(DEP_FILES) diff --git a/rules/sonic-frr-mgmt-framework.mk b/rules/sonic-frr-mgmt-framework.mk new file mode 100644 index 000000000000..dfe981b440a9 --- /dev/null +++ b/rules/sonic-frr-mgmt-framework.mk @@ -0,0 +1,13 @@ +# sonic-frr-mgmt-framework package + +SONIC_FRR_MGMT_FRAMEWORK = sonic_frr_mgmt_framework-1.0-py3-none-any.whl +$(SONIC_FRR_MGMT_FRAMEWORK)_SRC_PATH = $(SRC_PATH)/sonic-frr-mgmt-framework +# These dependencies are only needed because they are dependencies +# of sonic-config-engine and frrcfgd explicitly calls sonic-cfggen +# as part of its unit tests. +# TODO: Refactor unit tests so that these dependencies are not needed + +$(SONIC_FRR_MGMT_FRAMEWORK)_DEPENDS += $(SONIC_CONFIG_ENGINE_PY3) +$(SONIC_FRR_MGMT_FRAMEWORK)_DEBS_DEPENDS += $(PYTHON_SWSSCOMMON) +$(SONIC_FRR_MGMT_FRAMEWORK)_PYTHON_VERSION = 3 +SONIC_PYTHON_WHEELS += $(SONIC_FRR_MGMT_FRAMEWORK) diff --git a/rules/sonic-host-services-data.dep b/rules/sonic-host-services-data.dep new file mode 100644 index 000000000000..2b208317f1e2 --- /dev/null +++ b/rules/sonic-host-services-data.dep @@ -0,0 +1,8 @@ +SPATH := $($(SONIC_HOST_SERVICES_DATA)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-host-services-data.mk rules/sonic-host-services-data.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(SONIC_HOST_SERVICES_DATA)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_HOST_SERVICES_DATA)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_HOST_SERVICES_DATA)_DEP_FILES := $(DEP_FILES) diff --git a/rules/sonic-host-services-data.mk b/rules/sonic-host-services-data.mk new file mode 100644 index 000000000000..64a65904820a --- /dev/null +++ b/rules/sonic-host-services-data.mk @@ -0,0 +1,5 @@ +# SONiC host services data package + +SONIC_HOST_SERVICES_DATA = sonic-host-services-data_1.0-1_all.deb +$(SONIC_HOST_SERVICES_DATA)_SRC_PATH = $(SRC_PATH)/sonic-host-services-data +SONIC_DPKG_DEBS += $(SONIC_HOST_SERVICES_DATA) diff --git a/rules/sonic-host-services.dep b/rules/sonic-host-services.dep new file mode 100644 index 000000000000..0e68ccb035c8 --- /dev/null +++ b/rules/sonic-host-services.dep @@ -0,0 +1,10 @@ +SPATH := $($(SONIC_HOST_SERVICES_PY3)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-host-services.mk rules/sonic-host-services.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) + +$(SONIC_HOST_SERVICES_PY3)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_HOST_SERVICES_PY3)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_HOST_SERVICES_PY3)_DEP_FILES := $(DEP_FILES) +$(SONIC_HOST_SERVICES_PY3)_SMDEP_FILES := $(SMDEP_FILES) +$(SONIC_HOST_SERVICES_PY3)_SMDEP_PATHS := $(SPATH) diff --git a/rules/sonic-host-services.mk b/rules/sonic-host-services.mk new file mode 100644 index 000000000000..022c237ee950 --- /dev/null +++ b/rules/sonic-host-services.mk @@ -0,0 +1,8 @@ +# SONiC host services package + +SONIC_HOST_SERVICES_PY3 = sonic_host_services-1.0-py3-none-any.whl +$(SONIC_HOST_SERVICES_PY3)_SRC_PATH = $(SRC_PATH)/sonic-host-services +$(SONIC_HOST_SERVICES_PY3)_PYTHON_VERSION = 3 +$(SONIC_HOST_SERVICES_PY3)_DEPENDS += $(SONIC_PY_COMMON_PY3) \ + $(SWSSSDK_PY3) +SONIC_PYTHON_WHEELS += $(SONIC_HOST_SERVICES_PY3) diff --git a/rules/sonic-ledd.dep b/rules/sonic-ledd.dep index 42e54897423a..d9ae18537c6d 100644 --- a/rules/sonic-ledd.dep +++ b/rules/sonic-ledd.dep @@ -1,14 +1,16 @@ - -SPATH := $($(SONIC_LEDD)_SRC_PATH) -DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-ledd.mk rules/sonic-ledd.dep +SPATH := $($(SONIC_LEDD_PY2)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-ledd.mk rules/sonic-ledd.dep DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) -$(SONIC_LEDD)_CACHE_MODE := GIT_CONTENT_SHA -$(SONIC_LEDD)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) -$(SONIC_LEDD)_DEP_FILES := $(DEP_FILES) -$(SONIC_LEDD)_SMDEP_FILES := $(SMDEP_FILES) -$(SONIC_LEDD)_SMDEP_PATHS := $(SPATH) - - +$(SONIC_LEDD_PY2)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_LEDD_PY2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_LEDD_PY2)_DEP_FILES := $(DEP_FILES) +$(SONIC_LEDD_PY2)_SMDEP_FILES := $(SMDEP_FILES) +$(SONIC_LEDD_PY2)_SMDEP_PATHS := $(SPATH) +$(SONIC_LEDD_PY3)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_LEDD_PY3)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_LEDD_PY3)_DEP_FILES := $(DEP_FILES) +$(SONIC_LEDD_PY3)_SMDEP_FILES := $(SMDEP_FILES) +$(SONIC_LEDD_PY3)_SMDEP_PATHS := $(SPATH) diff --git a/rules/sonic-ledd.mk b/rules/sonic-ledd.mk index 056f0f6c9bd8..1439d2c506b0 100644 --- a/rules/sonic-ledd.mk +++ b/rules/sonic-ledd.mk @@ -1,5 +1,19 @@ # sonic-ledd (SONiC Front-panel LED control daemon) Debian package -SONIC_LEDD = python-sonic-ledd_1.1-1_all.deb -$(SONIC_LEDD)_SRC_PATH = $(SRC_PATH)/sonic-platform-daemons/sonic-ledd -SONIC_PYTHON_STDEB_DEBS += $(SONIC_LEDD) +# SONIC_LEDD_PY2 package + +SONIC_LEDD_PY2 = sonic_ledd-1.1-py2-none-any.whl +$(SONIC_LEDD_PY2)_SRC_PATH = $(SRC_PATH)/sonic-platform-daemons/sonic-ledd +$(SONIC_LEDD_PY2)_DEPENDS = $(SONIC_PY_COMMON_PY2) +$(SONIC_LEDD_PY2)_DEBS_DEPENDS = $(LIBSWSSCOMMON) $(PYTHON_SWSSCOMMON) +$(SONIC_LEDD_PY2)_PYTHON_VERSION = 2 +SONIC_PYTHON_WHEELS += $(SONIC_LEDD_PY2) + +# SONIC_LEDD_PY3 package + +SONIC_LEDD_PY3 = sonic_ledd-1.1-py3-none-any.whl +$(SONIC_LEDD_PY3)_SRC_PATH = $(SRC_PATH)/sonic-platform-daemons/sonic-ledd +$(SONIC_LEDD_PY3)_DEPENDS = $(SONIC_PY_COMMON_PY3) $(SONIC_LEDD_PY2) +$(SONIC_LEDD_PY3)_DEBS_DEPENDS = $(LIBSWSSCOMMON) $(PYTHON3_SWSSCOMMON) +$(SONIC_LEDD_PY3)_PYTHON_VERSION = 3 +SONIC_PYTHON_WHEELS += $(SONIC_LEDD_PY3) diff --git a/rules/sonic-mgmt-common.dep b/rules/sonic-mgmt-common.dep new file mode 100644 index 000000000000..69db9ac08859 --- /dev/null +++ b/rules/sonic-mgmt-common.dep @@ -0,0 +1,12 @@ + +SPATH := $($(SONIC_MGMT_COMMON)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-mgmt-common.mk rules/sonic-mgmt-common.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) + +$(SONIC_MGMT_COMMON)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_MGMT_COMMON)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_MGMT_COMMON)_DEP_FILES := $(DEP_FILES) +$(SONIC_MGMT_COMMON)_SMDEP_FILES := $(SMDEP_FILES) +$(SONIC_MGMT_COMMON)_SMDEP_PATHS := $(SPATH) + diff --git a/rules/sonic-mgmt-common.mk b/rules/sonic-mgmt-common.mk new file mode 100644 index 000000000000..cde659484df6 --- /dev/null +++ b/rules/sonic-mgmt-common.mk @@ -0,0 +1,12 @@ +# SONiC mgmt-common package + +MGMT_COMMON_VERSION = 1.0.0 +SONIC_MGMT_COMMON = sonic-mgmt-common_$(MGMT_COMMON_VERSION)_$(CONFIGURED_ARCH).deb +$(SONIC_MGMT_COMMON)_SRC_PATH = $(SRC_PATH)/sonic-mgmt-common +$(SONIC_MGMT_COMMON)_DEPENDS = $(LIBYANG_DEV) $(LIBYANG) +$(SONIC_MGMT_COMMON)_RDEPENDS = $(LIBYANG) +SONIC_DPKG_DEBS += $(SONIC_MGMT_COMMON) + +SONIC_MGMT_COMMON_CODEGEN = sonic-mgmt-common-codegen_$(MGMT_COMMON_VERSION)_$(CONFIGURED_ARCH).deb +$(eval $(call add_derived_package,$(SONIC_MGMT_COMMON),$(SONIC_MGMT_COMMON_CODEGEN))) + diff --git a/rules/sonic-mgmt-framework.mk b/rules/sonic-mgmt-framework.mk index a57ce6b1b083..a423f7cd506b 100644 --- a/rules/sonic-mgmt-framework.mk +++ b/rules/sonic-mgmt-framework.mk @@ -1,14 +1,14 @@ # SONiC mgmt-framework package -ifeq ($(ENABLE_MGMT_FRAMEWORK), y) +ifeq ($(INCLUDE_MGMT_FRAMEWORK), y) -SONIC_MGMT_FRAMEWORK = sonic-mgmt-framework_1.0-01_amd64.deb +SONIC_MGMT_FRAMEWORK = sonic-mgmt-framework_1.0-01_$(CONFIGURED_ARCH).deb $(SONIC_MGMT_FRAMEWORK)_SRC_PATH = $(SRC_PATH)/sonic-mgmt-framework -$(SONIC_MGMT_FRAMEWORK)_DEPENDS = $(LIBYANG_DEV) $(LIBYANG) -$(SONIC_MGMT_FRAMEWORK)_RDEPENDS = $(LIBYANG) +$(SONIC_MGMT_FRAMEWORK)_DEPENDS = $(SONIC_MGMT_COMMON) $(SONIC_MGMT_COMMON_CODEGEN) +$(SONIC_MGMT_FRAMEWORK)_RDEPENDS = SONIC_DPKG_DEBS += $(SONIC_MGMT_FRAMEWORK) -SONIC_MGMT_FRAMEWORK_DBG = sonic-mgmt-framework-dbg_1.0-01_amd64.deb +SONIC_MGMT_FRAMEWORK_DBG = sonic-mgmt-framework-dbg_1.0-01_$(CONFIGURED_ARCH).deb $(SONIC_MGMT_FRAMEWORK_DBG)_DEPENDS += $(SONIC_MGMT_FRAMEWORK) $(SONIC_MGMT_FRAMEWORK_DBG)_RDEPENDS += $(SONIC_MGMT_FRAMEWORK) $(eval $(call add_derived_package,$(SONIC_MGMT_FRAMEWORK),$(SONIC_MGMT_FRAMEWORK_DBG))) diff --git a/rules/sonic-pcied.dep b/rules/sonic-pcied.dep new file mode 100644 index 000000000000..ddb07f722f6d --- /dev/null +++ b/rules/sonic-pcied.dep @@ -0,0 +1,16 @@ +SPATH:= $($(SONIC_PCIED_PY2)_SRC_PATH) +DEP_FILES:= $(SONIC_COMMON_FILES_LIST) rules/sonic-pcied.mk rules/sonic-pcied.dep +DEP_FILES+= $(SONIC_COMMON_BASE_FILES_LIST) +SMDEP_FILES:= $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) + +$(SONIC_PCIED_PY2)_CACHE_MODE:= GIT_CONTENT_SHA +$(SONIC_PCIED_PY2)_DEP_FLAGS:= $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_PCIED_PY2)_DEP_FILES:= $(DEP_FILES) +$(SONIC_PCIED_PY2)_SMDEP_FILES:= $(SMDEP_FILES) +$(SONIC_PCIED_PY2)_SMDEP_PATHS:= $(SPATH) + +$(SONIC_PCIED_PY3)_CACHE_MODE:= GIT_CONTENT_SHA +$(SONIC_PCIED_PY3)_DEP_FLAGS:= $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_PCIED_PY3)_DEP_FILES:= $(DEP_FILES) +$(SONIC_PCIED_PY3)_SMDEP_FILES:= $(SMDEP_FILES) +$(SONIC_PCIED_PY3)_SMDEP_PATHS:= $(SPATH) diff --git a/rules/sonic-pcied.mk b/rules/sonic-pcied.mk new file mode 100644 index 000000000000..5c80ae276860 --- /dev/null +++ b/rules/sonic-pcied.mk @@ -0,0 +1,17 @@ +# sonic-pcied (SONiC PCIe Monitor daemon) Debian package + +# SONIC_PCIED_PY2 package + +SONIC_PCIED_PY2 = sonic_pcied-1.0-py2-none-any.whl +$(SONIC_PCIED_PY2)_SRC_PATH = $(SRC_PATH)/sonic-platform-daemons/sonic-pcied +$(SONIC_PCIED_PY2)_DEPENDS = $(SONIC_PY_COMMON_PY2) +$(SONIC_PCIED_PY2)_PYTHON_VERSION = 2 +SONIC_PYTHON_WHEELS += $(SONIC_PCIED_PY2) + +# SONIC_PCIED_PY3 package + +SONIC_PCIED_PY3 = sonic_pcied-1.0-py3-none-any.whl +$(SONIC_PCIED_PY3)_SRC_PATH = $(SRC_PATH)/sonic-platform-daemons/sonic-pcied +$(SONIC_PCIED_PY3)_DEPENDS = $(SONIC_PY_COMMON_PY3) $(SONIC_PCIED_PY2) +$(SONIC_PCIED_PY3)_PYTHON_VERSION = 3 +SONIC_PYTHON_WHEELS += $(SONIC_PCIED_PY3) diff --git a/rules/sonic-platform-common.dep b/rules/sonic-platform-common.dep index f93240135988..e921c4df01af 100644 --- a/rules/sonic-platform-common.dep +++ b/rules/sonic-platform-common.dep @@ -2,7 +2,7 @@ SPATH := $($(SONIC_PLATFORM_COMMON_PY2)_SRC_PATH) DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-platform-common.mk rules/sonic-platform-common.dep DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) -SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files|grep -Ev "sonic_sfp|sonic_eeprom")) +SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files|grep -Ev "^sonic_sfp|^sonic_eeprom")) $(SONIC_PLATFORM_COMMON_PY2)_CACHE_MODE := GIT_CONTENT_SHA $(SONIC_PLATFORM_COMMON_PY2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) diff --git a/rules/sonic-platform-common.mk b/rules/sonic-platform-common.mk index 043c820743aa..b3dd0155d59e 100644 --- a/rules/sonic-platform-common.mk +++ b/rules/sonic-platform-common.mk @@ -3,12 +3,14 @@ SONIC_PLATFORM_COMMON_PY2 = sonic_platform_common-1.0-py2-none-any.whl $(SONIC_PLATFORM_COMMON_PY2)_SRC_PATH = $(SRC_PATH)/sonic-platform-common $(SONIC_PLATFORM_COMMON_PY2)_PYTHON_VERSION = 2 +$(SONIC_PLATFORM_COMMON_PY2)_DEPENDS += $(SONIC_PY_COMMON_PY2) $(SONIC_CONFIG_ENGINE_PY2) SONIC_PYTHON_WHEELS += $(SONIC_PLATFORM_COMMON_PY2) # Als build sonic-platform-common into python3 wheel, so we can use PSU code in SNMP docker SONIC_PLATFORM_COMMON_PY3 = sonic_platform_common-1.0-py3-none-any.whl $(SONIC_PLATFORM_COMMON_PY3)_SRC_PATH = $(SRC_PATH)/sonic-platform-common $(SONIC_PLATFORM_COMMON_PY3)_PYTHON_VERSION = 3 +$(SONIC_PLATFORM_COMMON_PY3)_DEPENDS += $(SONIC_PY_COMMON_PY3) $(SONIC_CONFIG_ENGINE_PY3) # Synthetic dependency just to avoid race condition -$(SONIC_PLATFORM_COMMON_PY3)_DEPENDS = $(SONIC_PLATFORM_COMMON_PY2) +$(SONIC_PLATFORM_COMMON_PY3)_DEPENDS += $(SONIC_PLATFORM_COMMON_PY2) SONIC_PYTHON_WHEELS += $(SONIC_PLATFORM_COMMON_PY3) diff --git a/rules/sonic-psud.dep b/rules/sonic-psud.dep index 1999811f2a0a..f58d57571d32 100644 --- a/rules/sonic-psud.dep +++ b/rules/sonic-psud.dep @@ -1,12 +1,16 @@ - -SPATH := $($(SONIC_PSUD)_SRC_PATH) -DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-psud.mk rules/sonic-psud.dep +SPATH := $($(SONIC_PSUD_PY2)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-psud.mk rules/sonic-psud.dep DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) -$(SONIC_PSUD)_CACHE_MODE := GIT_CONTENT_SHA -$(SONIC_PSUD)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) -$(SONIC_PSUD)_DEP_FILES := $(DEP_FILES) -$(SONIC_PSUD)_SMDEP_FILES := $(SMDEP_FILES) -$(SONIC_PSUD)_SMDEP_PATHS := $(SPATH) +$(SONIC_PSUD_PY2)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_PSUD_PY2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_PSUD_PY2)_DEP_FILES := $(DEP_FILES) +$(SONIC_PSUD_PY2)_SMDEP_FILES := $(SMDEP_FILES) +$(SONIC_PSUD_PY2)_SMDEP_PATHS := $(SPATH) +$(SONIC_PSUD_PY3)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_PSUD_PY3)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_PSUD_PY3)_DEP_FILES := $(DEP_FILES) +$(SONIC_PSUD_PY3)_SMDEP_FILES := $(SMDEP_FILES) +$(SONIC_PSUD_PY3)_SMDEP_PATHS := $(SPATH) diff --git a/rules/sonic-psud.mk b/rules/sonic-psud.mk index 0249115359f3..b07aa31b2002 100644 --- a/rules/sonic-psud.mk +++ b/rules/sonic-psud.mk @@ -1,5 +1,19 @@ # sonic-psud (SONiC PSU daemon) Debian package -SONIC_PSUD = python-sonic-psud_1.0-1_all.deb -$(SONIC_PSUD)_SRC_PATH = $(SRC_PATH)/sonic-platform-daemons/sonic-psud -SONIC_PYTHON_STDEB_DEBS += $(SONIC_PSUD) +# SONIC_PSUD_PY2 package + +SONIC_PSUD_PY2 = sonic_psud-1.0-py2-none-any.whl +$(SONIC_PSUD_PY2)_SRC_PATH = $(SRC_PATH)/sonic-platform-daemons/sonic-psud +$(SONIC_PSUD_PY2)_DEPENDS = $(SONIC_PY_COMMON_PY2) +$(SONIC_PSUD_PY2)_DEBS_DEPENDS = $(LIBSWSSCOMMON) $(PYTHON_SWSSCOMMON) +$(SONIC_PSUD_PY2)_PYTHON_VERSION = 2 +SONIC_PYTHON_WHEELS += $(SONIC_PSUD_PY2) + +# SONIC_PSUD_PY3 package + +SONIC_PSUD_PY3 = sonic_psud-1.0-py3-none-any.whl +$(SONIC_PSUD_PY3)_SRC_PATH = $(SRC_PATH)/sonic-platform-daemons/sonic-psud +$(SONIC_PSUD_PY3)_DEPENDS = $(SONIC_PY_COMMON_PY3) $(SONIC_PSUD_PY2) +$(SONIC_PSUD_PY3)_DEBS_DEPENDS = $(LIBSWSSCOMMON) $(PYTHON3_SWSSCOMMON) +$(SONIC_PSUD_PY3)_PYTHON_VERSION = 3 +SONIC_PYTHON_WHEELS += $(SONIC_PSUD_PY3) diff --git a/rules/sonic-py-common.dep b/rules/sonic-py-common.dep new file mode 100644 index 000000000000..9ecedb068a4f --- /dev/null +++ b/rules/sonic-py-common.dep @@ -0,0 +1,12 @@ +SPATH := $($(SONIC_PY_COMMON_PY2)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-py-common.mk rules/sonic-py-common.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(SONIC_PY_COMMON_PY2)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_PY_COMMON_PY2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_PY_COMMON_PY2)_DEP_FILES := $(DEP_FILES) + +$(SONIC_PY_COMMON_PY3)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_PY_COMMON_PY3)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_PY_COMMON_PY3)_DEP_FILES := $(DEP_FILES) diff --git a/rules/sonic-py-common.mk b/rules/sonic-py-common.mk new file mode 100644 index 000000000000..6afe9a826c68 --- /dev/null +++ b/rules/sonic-py-common.mk @@ -0,0 +1,18 @@ +# SONIC_PY_COMMON_PY2 package + +SONIC_PY_COMMON_PY2 = sonic_py_common-1.0-py2-none-any.whl +$(SONIC_PY_COMMON_PY2)_SRC_PATH = $(SRC_PATH)/sonic-py-common +$(SONIC_PY_COMMON_PY2)_DEPENDS += $(SWSSSDK_PY2) +$(SONIC_PY_COMMON_PY2)_PYTHON_VERSION = 2 +SONIC_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY2) + +# SONIC_PY_COMMON_PY3 package + +SONIC_PY_COMMON_PY3 = sonic_py_common-1.0-py3-none-any.whl +$(SONIC_PY_COMMON_PY3)_SRC_PATH = $(SRC_PATH)/sonic-py-common +$(SONIC_PY_COMMON_PY3)_DEPENDS += $(SWSSSDK_PY3) +# Synthetic dependency to avoid building the Python 2 and 3 packages +# simultaneously and any potential conflicts which may arise +$(SONIC_PY_COMMON_PY3)_DEPENDS += $(SONIC_PY_COMMON_PY2) +$(SONIC_PY_COMMON_PY3)_PYTHON_VERSION = 3 +SONIC_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY3) diff --git a/rules/sonic-syseepromd.dep b/rules/sonic-syseepromd.dep index a00131942031..f27e436adfe1 100644 --- a/rules/sonic-syseepromd.dep +++ b/rules/sonic-syseepromd.dep @@ -1,12 +1,16 @@ - -SPATH := $($(SONIC_SYSEEPROMD)_SRC_PATH) -DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-syseepromd.mk rules/sonic-syseepromd.dep +SPATH := $($(SONIC_SYSEEPROMD_PY2)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-syseepromd.mk rules/sonic-syseepromd.dep DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) -$(SONIC_SYSEEPROMD)_CACHE_MODE := GIT_CONTENT_SHA -$(SONIC_SYSEEPROMD)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) -$(SONIC_SYSEEPROMD)_DEP_FILES := $(DEP_FILES) -$(SONIC_SYSEEPROMD)_SMDEP_FILES := $(SMDEP_FILES) -$(SONIC_SYSEEPROMD)_SMDEP_PATHS := $(SPATH) +$(SONIC_SYSEEPROMD_PY2)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_SYSEEPROMD_PY2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_SYSEEPROMD_PY2)_DEP_FILES := $(DEP_FILES) +$(SONIC_SYSEEPROMD_PY2)_SMDEP_FILES := $(SMDEP_FILES) +$(SONIC_SYSEEPROMD_PY2)_SMDEP_PATHS := $(SPATH) +$(SONIC_SYSEEPROMD_PY3)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_SYSEEPROMD_PY3)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_SYSEEPROMD_PY3)_DEP_FILES := $(DEP_FILES) +$(SONIC_SYSEEPROMD_PY3)_SMDEP_FILES := $(SMDEP_FILES) +$(SONIC_SYSEEPROMD_PY3)_SMDEP_PATHS := $(SPATH) diff --git a/rules/sonic-syseepromd.mk b/rules/sonic-syseepromd.mk index 8f7a6e5e902f..0732e3b531c5 100644 --- a/rules/sonic-syseepromd.mk +++ b/rules/sonic-syseepromd.mk @@ -1,5 +1,19 @@ # sonic-syseepromd (SONiC Syseeprom gathering daemon) Debian package -SONIC_SYSEEPROMD = python-sonic-syseepromd_1.0-1_all.deb -$(SONIC_SYSEEPROMD)_SRC_PATH = $(SRC_PATH)/sonic-platform-daemons/sonic-syseepromd -SONIC_PYTHON_STDEB_DEBS += $(SONIC_SYSEEPROMD) +# SONIC_SYSEEPROMD_PY2 package + +SONIC_SYSEEPROMD_PY2 = sonic_syseepromd-1.0-py2-none-any.whl +$(SONIC_SYSEEPROMD_PY2)_SRC_PATH = $(SRC_PATH)/sonic-platform-daemons/sonic-syseepromd +$(SONIC_SYSEEPROMD_PY2)_DEPENDS = $(SONIC_PY_COMMON_PY2) +$(SONIC_SYSEEPROMD_PY2)_DEBS_DEPENDS = $(LIBSWSSCOMMON) $(PYTHON_SWSSCOMMON) +$(SONIC_SYSEEPROMD_PY2)_PYTHON_VERSION = 2 +SONIC_PYTHON_WHEELS += $(SONIC_SYSEEPROMD_PY2) + +# SONIC_SYSEEPROMD_PY3 package + +SONIC_SYSEEPROMD_PY3 = sonic_syseepromd-1.0-py3-none-any.whl +$(SONIC_SYSEEPROMD_PY3)_SRC_PATH = $(SRC_PATH)/sonic-platform-daemons/sonic-syseepromd +$(SONIC_SYSEEPROMD_PY3)_DEPENDS = $(SONIC_PY_COMMON_PY3) $(SONIC_SYSEEPROMD_PY2) +$(SONIC_SYSEEPROMD_PY3)_DEBS_DEPENDS = $(LIBSWSSCOMMON) $(PYTHON3_SWSSCOMMON) +$(SONIC_SYSEEPROMD_PY3)_PYTHON_VERSION = 3 +SONIC_PYTHON_WHEELS += $(SONIC_SYSEEPROMD_PY3) diff --git a/rules/sonic-thermalctld.dep b/rules/sonic-thermalctld.dep index 6faa53b378e6..5b9d05cb648e 100644 --- a/rules/sonic-thermalctld.dep +++ b/rules/sonic-thermalctld.dep @@ -1,12 +1,16 @@ - -SPATH := $($(SONIC_THERMALCTLD)_SRC_PATH) +SPATH := $($(SONIC_THERMALCTLD_PY2)_SRC_PATH) DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-thermalctld.mk rules/sonic-thermalctld.dep DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) -$(SONIC_THERMALCTLD)_CACHE_MODE := GIT_CONTENT_SHA -$(SONIC_THERMALCTLD)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) -$(SONIC_THERMALCTLD)_DEP_FILES := $(DEP_FILES) -$(SONIC_THERMALCTLD)_SMDEP_FILES := $(SMDEP_FILES) -$(SONIC_THERMALCTLD)_SMDEP_PATHS := $(SPATH) +$(SONIC_THERMALCTLD_PY2)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_THERMALCTLD_PY2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_THERMALCTLD_PY2)_DEP_FILES := $(DEP_FILES) +$(SONIC_THERMALCTLD_PY2)_SMDEP_FILES := $(SMDEP_FILES) +$(SONIC_THERMALCTLD_PY2)_SMDEP_PATHS := $(SPATH) +$(SONIC_THERMALCTLD_PY3)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_THERMALCTLD_PY3)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_THERMALCTLD_PY3)_DEP_FILES := $(DEP_FILES) +$(SONIC_THERMALCTLD_PY3)_SMDEP_FILES := $(SMDEP_FILES) +$(SONIC_THERMALCTLD_PY3)_SMDEP_PATHS := $(SPATH) diff --git a/rules/sonic-thermalctld.mk b/rules/sonic-thermalctld.mk index 775082e7bbce..6eb16c5eb3f7 100644 --- a/rules/sonic-thermalctld.mk +++ b/rules/sonic-thermalctld.mk @@ -1,6 +1,19 @@ # sonic-thermalctld (SONiC Thermal control daemon) Debian package -SONIC_THERMALCTLD = python-sonic-thermalctld_1.0-1_all.deb -$(SONIC_THERMALCTLD)_SRC_PATH = $(SRC_PATH)/sonic-platform-daemons/sonic-thermalctld -$(SONIC_THERMALCTLD)_WHEEL_DEPENDS = $(SONIC_DAEMON_BASE_PY2) -SONIC_PYTHON_STDEB_DEBS += $(SONIC_THERMALCTLD) +# SONIC_THERMALCTLD_PY2 package + +SONIC_THERMALCTLD_PY2 = sonic_thermalctld-1.0-py2-none-any.whl +$(SONIC_THERMALCTLD_PY2)_SRC_PATH = $(SRC_PATH)/sonic-platform-daemons/sonic-thermalctld +$(SONIC_THERMALCTLD_PY2)_DEPENDS = $(SONIC_PY_COMMON_PY2) +$(SONIC_THERMALCTLD_PY2)_DEBS_DEPENDS = $(LIBSWSSCOMMON) $(PYTHON_SWSSCOMMON) +$(SONIC_THERMALCTLD_PY2)_PYTHON_VERSION = 2 +SONIC_PYTHON_WHEELS += $(SONIC_THERMALCTLD_PY2) + +# SONIC_THERMALCTLD_PY3 package + +SONIC_THERMALCTLD_PY3 = sonic_thermalctld-1.0-py3-none-any.whl +$(SONIC_THERMALCTLD_PY3)_SRC_PATH = $(SRC_PATH)/sonic-platform-daemons/sonic-thermalctld +$(SONIC_THERMALCTLD_PY3)_DEPENDS = $(SONIC_PY_COMMON_PY3) $(SONIC_THERMALCTLD_PY2) +$(SONIC_THERMALCTLD_PY3)_DEBS_DEPENDS = $(LIBSWSSCOMMON) $(PYTHON3_SWSSCOMMON) +$(SONIC_THERMALCTLD_PY3)_PYTHON_VERSION = 3 +SONIC_PYTHON_WHEELS += $(SONIC_THERMALCTLD_PY3) diff --git a/rules/sonic-utilities-data.dep b/rules/sonic-utilities-data.dep new file mode 100644 index 000000000000..b11d0a554401 --- /dev/null +++ b/rules/sonic-utilities-data.dep @@ -0,0 +1,9 @@ +SPATH := $($(SONIC_UTILITIES_DATA)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-utilities-data.mk rules/sonic-utilities-data.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(SONIC_UTILITIES_DATA)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_UTILITIES_DATA)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_UTILITIES_DATA)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/sonic-utilities-data.mk b/rules/sonic-utilities-data.mk new file mode 100644 index 000000000000..8eca8b1c9732 --- /dev/null +++ b/rules/sonic-utilities-data.mk @@ -0,0 +1,5 @@ +# SONiC command line utilities data package + +SONIC_UTILITIES_DATA = sonic-utilities-data_1.0-1_all.deb +$(SONIC_UTILITIES_DATA)_SRC_PATH = $(SRC_PATH)/sonic-utilities/sonic-utilities-data +SONIC_DPKG_DEBS += $(SONIC_UTILITIES_DATA) diff --git a/rules/sonic-utilities.dep b/rules/sonic-utilities.dep index 9d5f64e0ac62..848b8d66296e 100644 --- a/rules/sonic-utilities.dep +++ b/rules/sonic-utilities.dep @@ -1,12 +1,10 @@ - -SPATH := $($(SONIC_UTILS)_SRC_PATH) +SPATH := $($(SONIC_UTILITIES_PY3)_SRC_PATH) DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-utilities.mk rules/sonic-utilities.dep DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) -$(SONIC_UTILS)_CACHE_MODE := GIT_CONTENT_SHA -$(SONIC_UTILS)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) -$(SONIC_UTILS)_DEP_FILES := $(DEP_FILES) -$(SONIC_UTILS)_SMDEP_FILES := $(SMDEP_FILES) -$(SONIC_UTILS)_SMDEP_PATHS := $(SPATH) - +$(SONIC_UTILITIES_PY3)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_UTILITIES_PY3)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_UTILITIES_PY3)_DEP_FILES := $(DEP_FILES) +$(SONIC_UTILITIES_PY3)_SMDEP_FILES := $(SMDEP_FILES) +$(SONIC_UTILITIES_PY3)_SMDEP_PATHS := $(SPATH) diff --git a/rules/sonic-utilities.mk b/rules/sonic-utilities.mk index eba618d051dc..4e5b5adbc5dc 100644 --- a/rules/sonic-utilities.mk +++ b/rules/sonic-utilities.mk @@ -1,16 +1,17 @@ # sonic utilities package -# -# NOTE: sonic-config-engine is a build-time dependency of sonic-utilities -# due to unit tests which are run during the build. However, -# sonic-platform-common and swsssdk are runtime dependencies, and should be -# added here also. However, the current build system assumes all runtime -# dependencies are .deb packages. -# -# TODO: Create a way to specify both .deb and .whl runtime dependencies -# then add the aforementioned runtime dependencies here. -# -SONIC_UTILS = python-sonic-utilities_1.2-1_all.deb -$(SONIC_UTILS)_SRC_PATH = $(SRC_PATH)/sonic-utilities -$(SONIC_UTILS)_WHEEL_DEPENDS = $(SONIC_CONFIG_ENGINE) -SONIC_PYTHON_STDEB_DEBS += $(SONIC_UTILS) +SONIC_UTILITIES_PY3 = sonic_utilities-1.2-py3-none-any.whl +$(SONIC_UTILITIES_PY3)_SRC_PATH = $(SRC_PATH)/sonic-utilities +$(SONIC_UTILITIES_PY3)_PYTHON_VERSION = 3 +$(SONIC_UTILITIES_PY3)_DEPENDS += $(SONIC_PY_COMMON_PY3) \ + $(SWSSSDK_PY3) \ + $(SONIC_CONFIG_ENGINE_PY3) \ + $(SONIC_PLATFORM_COMMON_PY3) \ + $(SONIC_YANG_MGMT_PY3) \ + $(SONIC_YANG_MODELS_PY3) +$(SONIC_UTILITIES_PY3)_DEBS_DEPENDS = $(LIBYANG) \ + $(LIBYANG_CPP) \ + $(LIBYANG_PY3) \ + $(LIBSWSSCOMMON) \ + $(PYTHON3_SWSSCOMMON) +SONIC_PYTHON_WHEELS += $(SONIC_UTILITIES_PY3) diff --git a/rules/sonic-xcvrd.dep b/rules/sonic-xcvrd.dep index 25c1e8c2aaa7..0bda526b48b5 100644 --- a/rules/sonic-xcvrd.dep +++ b/rules/sonic-xcvrd.dep @@ -1,12 +1,16 @@ - -SPATH := $($(SONIC_XCVRD)_SRC_PATH) -DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-xcvrd.mk rules/sonic-xcvrd.dep +SPATH := $($(SONIC_XCVRD_PY2)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-xcvrd.mk rules/sonic-xcvrd.dep DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) -$(SONIC_XCVRD)_CACHE_MODE := GIT_CONTENT_SHA -$(SONIC_XCVRD)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) -$(SONIC_XCVRD)_DEP_FILES := $(DEP_FILES) -$(SONIC_XCVRD)_SMDEP_FILES := $(SMDEP_FILES) -$(SONIC_XCVRD)_SMDEP_PATHS := $(SPATH) +$(SONIC_XCVRD_PY2)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_XCVRD_PY2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_XCVRD_PY2)_DEP_FILES := $(DEP_FILES) +$(SONIC_XCVRD_PY2)_SMDEP_FILES := $(SMDEP_FILES) +$(SONIC_XCVRD_PY2)_SMDEP_PATHS := $(SPATH) +$(SONIC_XCVRD_PY3)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_XCVRD_PY3)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_XCVRD_PY3)_DEP_FILES := $(DEP_FILES) +$(SONIC_XCVRD_PY3)_SMDEP_FILES := $(SMDEP_FILES) +$(SONIC_XCVRD_PY3)_SMDEP_PATHS := $(SPATH) diff --git a/rules/sonic-xcvrd.mk b/rules/sonic-xcvrd.mk index b97f8dd11b79..018363f367fd 100644 --- a/rules/sonic-xcvrd.mk +++ b/rules/sonic-xcvrd.mk @@ -1,5 +1,19 @@ # sonic-xcvrd (SONiC Transceiver monitoring daemon) Debian package -SONIC_XCVRD = python-sonic-xcvrd_1.0-1_all.deb -$(SONIC_XCVRD)_SRC_PATH = $(SRC_PATH)/sonic-platform-daemons/sonic-xcvrd -SONIC_PYTHON_STDEB_DEBS += $(SONIC_XCVRD) +# SONIC_XCVRD_PY2 package + +SONIC_XCVRD_PY2 = sonic_xcvrd-1.0-py2-none-any.whl +$(SONIC_XCVRD_PY2)_SRC_PATH = $(SRC_PATH)/sonic-platform-daemons/sonic-xcvrd +$(SONIC_XCVRD_PY2)_DEPENDS = $(SONIC_PY_COMMON_PY2) $(SONIC_PLATFORM_COMMON_PY2) +$(SONIC_XCVRD_PY2)_DEBS_DEPENDS = $(LIBSWSSCOMMON) $(PYTHON_SWSSCOMMON) +$(SONIC_XCVRD_PY2)_PYTHON_VERSION = 2 +SONIC_PYTHON_WHEELS += $(SONIC_XCVRD_PY2) + +# SONIC_XCVRD_PY3 package + +SONIC_XCVRD_PY3 = sonic_xcvrd-1.0-py3-none-any.whl +$(SONIC_XCVRD_PY3)_SRC_PATH = $(SRC_PATH)/sonic-platform-daemons/sonic-xcvrd +$(SONIC_XCVRD_PY3)_DEPENDS = $(SONIC_PY_COMMON_PY3) $(SONIC_XCVRD_PY2) $(SONIC_PLATFORM_COMMON_PY3) +$(SONIC_XCVRD_PY3)_DEBS_DEPENDS = $(LIBSWSSCOMMON) $(PYTHON3_SWSSCOMMON) +$(SONIC_XCVRD_PY3)_PYTHON_VERSION = 3 +SONIC_PYTHON_WHEELS += $(SONIC_XCVRD_PY3) diff --git a/rules/sonic-yang-mgmt-py3.dep b/rules/sonic-yang-mgmt-py3.dep new file mode 100644 index 000000000000..e6528220c6d8 --- /dev/null +++ b/rules/sonic-yang-mgmt-py3.dep @@ -0,0 +1,10 @@ + +SPATH := $($(SONIC_YANG_MGMT_PY3)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-yang-mgmt-py3.mk rules/sonic-yang-mgmt-py3.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(SONIC_YANG_MGMT_PY3)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_YANG_MGMT_PY3)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_YANG_MGMT_PY3)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/sonic-yang-mgmt-py3.mk b/rules/sonic-yang-mgmt-py3.mk new file mode 100644 index 000000000000..877fc6de3952 --- /dev/null +++ b/rules/sonic-yang-mgmt-py3.mk @@ -0,0 +1,11 @@ +# sonic-yang-mgmt python3 wheel + +SONIC_YANG_MGMT_PY3 = sonic_yang_mgmt-1.0-py3-none-any.whl +$(SONIC_YANG_MGMT_PY3)_SRC_PATH = $(SRC_PATH)/sonic-yang-mgmt +$(SONIC_YANG_MGMT_PY3)_PYTHON_VERSION = 3 +$(SONIC_YANG_MGMT_PY3)_DEBS_DEPENDS = $(LIBYANG) $(LIBYANG_CPP) $(LIBYANG_PY3) +$(SONIC_YANG_MGMT_PY3)_DEPENDS = $(SONIC_YANG_MODELS_PY3) +$(SONIC_YANG_MGMT_PY3)_RDEPENDS = $(SONIC_YANG_MODELS_PY3) $(LIBYANG) \ + $(LIBYANG_CPP) $(LIBYANG_PY3) + +SONIC_PYTHON_WHEELS += $(SONIC_YANG_MGMT_PY3) diff --git a/rules/sonic-yang-models-py3.dep b/rules/sonic-yang-models-py3.dep new file mode 100644 index 000000000000..34b8c785f4bf --- /dev/null +++ b/rules/sonic-yang-models-py3.dep @@ -0,0 +1,9 @@ +SPATH := $($(SONIC_YANG_MODELS_PY3)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-yang-models-py3.mk rules/sonic-yang-models-py3.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(SONIC_YANG_MODELS_PY3)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_YANG_MODELS_PY3)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_YANG_MODELS_PY3)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/sonic-yang-models-py3.mk b/rules/sonic-yang-models-py3.mk new file mode 100644 index 000000000000..8c11a921a979 --- /dev/null +++ b/rules/sonic-yang-models-py3.mk @@ -0,0 +1,8 @@ +SONIC_YANG_MODELS_PY3 = sonic_yang_models-1.0-py3-none-any.whl +$(SONIC_YANG_MODELS_PY3)_SRC_PATH = $(SRC_PATH)/sonic-yang-models +$(SONIC_YANG_MODELS_PY3)_PYTHON_VERSION = 3 +$(SONIC_YANG_MODELS_PY3)_DEBS_DEPENDS = $(LIBYANG) $(LIBYANG_CPP) \ + $(LIBYANG_PY2) $(LIBYANG_PY3) + +SONIC_PYTHON_WHEELS += $(SONIC_YANG_MODELS_PY3) +export SONIC_YANG_MODELS_PY3 diff --git a/rules/sonic-ztp.dep b/rules/sonic-ztp.dep index 32890c5d74b6..bf6622ddb505 100644 --- a/rules/sonic-ztp.dep +++ b/rules/sonic-ztp.dep @@ -2,7 +2,7 @@ SPATH := $($(SONIC_ZTP)_SRC_PATH) DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-ztp.mk rules/sonic-ztp.dep DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) -SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files|grep -Ev "inband-ztp-ip|dhclient-exit-hooks.d/ztp")) +SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files|grep -Ev "dhclient-enter-hooks.d|dhclient-exit-hooks.d")) $(SONIC_ZTP)_CACHE_MODE := GIT_CONTENT_SHA diff --git a/rules/sonic-ztp.mk b/rules/sonic-ztp.mk index 3f64febd48c0..0c4819ec6004 100644 --- a/rules/sonic-ztp.mk +++ b/rules/sonic-ztp.mk @@ -5,8 +5,8 @@ SONIC_ZTP_VERSION = 1.0.0 SONIC_ZTP = sonic-ztp_$(SONIC_ZTP_VERSION)_all.deb $(SONIC_ZTP)_SRC_PATH = $(SRC_PATH)/sonic-ztp +$(SONIC_ZTP)_WHEEL_DEPENDS += $(SWSSSDK_PY3) SONIC_DPKG_DEBS += $(SONIC_ZTP) -SONIC_STRETCH_DEBS += $(SONIC_ZTP) export SONIC_ZTP_VERSION export SONIC_ZTP diff --git a/rules/sonic_bgpcfgd.dep b/rules/sonic_bgpcfgd.dep new file mode 100644 index 000000000000..abd51062b8bb --- /dev/null +++ b/rules/sonic_bgpcfgd.dep @@ -0,0 +1,10 @@ + +SPATH := $($(SONIC_BGPCFGD)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic_bgpcfgd.mk rules/sonic_bgpcfgd.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(SONIC_BGPCFGD)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_BGPCFGD)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_BGPCFGD)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/sonic_bgpcfgd.mk b/rules/sonic_bgpcfgd.mk new file mode 100644 index 000000000000..3e1395842b51 --- /dev/null +++ b/rules/sonic_bgpcfgd.mk @@ -0,0 +1,13 @@ +# sonic-bgpcfgd package + +SONIC_BGPCFGD = sonic_bgpcfgd-1.0-py3-none-any.whl +$(SONIC_BGPCFGD)_SRC_PATH = $(SRC_PATH)/sonic-bgpcfgd +# These dependencies are only needed because they are dependencies +# of sonic-config-engine and bgpcfgd explicitly calls sonic-cfggen +# as part of its unit tests. +# TODO: Refactor unit tests so that these dependencies are not needed + +$(SONIC_BGPCFGD)_DEPENDS += $(SONIC_CONFIG_ENGINE_PY3) +$(SONIC_BGPCFGD)_DEBS_DEPENDS += $(PYTHON3_SWSSCOMMON) +$(SONIC_BGPCFGD)_PYTHON_VERSION = 3 +SONIC_PYTHON_WHEELS += $(SONIC_BGPCFGD) diff --git a/rules/supervisor.dep b/rules/supervisor.dep deleted file mode 100644 index 7d7bcf36e952..000000000000 --- a/rules/supervisor.dep +++ /dev/null @@ -1,10 +0,0 @@ - -SPATH := $($(SUPERVISOR)_SRC_PATH) -DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/supervisor.mk rules/supervisor.dep -DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) -DEP_FILES += $(shell git ls-files $(SPATH)) - -$(SUPERVISOR)_CACHE_MODE := GIT_CONTENT_SHA -$(SUPERVISOR)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) -$(SUPERVISOR)_DEP_FILES := $(DEP_FILES) - diff --git a/rules/supervisor.mk b/rules/supervisor.mk deleted file mode 100644 index cd97eabf801d..000000000000 --- a/rules/supervisor.mk +++ /dev/null @@ -1,9 +0,0 @@ -# supervisor package - -SUPERVISOR_VERSION = 3.3.3 - -export SUPERVISOR_VERSION - -SUPERVISOR = python-supervisor_$(SUPERVISOR_VERSION)-1_all.deb -$(SUPERVISOR)_SRC_PATH = $(SRC_PATH)/supervisor -SONIC_MAKE_DEBS += $(SUPERVISOR) diff --git a/rules/swig.dep b/rules/swig.dep deleted file mode 100644 index 603dc5587a20..000000000000 --- a/rules/swig.dep +++ /dev/null @@ -1,10 +0,0 @@ - -SPATH := $($(SWIG_BASE)_SRC_PATH) -DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/swig.mk rules/swig.dep -DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) -DEP_FILES += $(shell git ls-files $(SPATH)) - -$(SWIG_BASE)_CACHE_MODE := GIT_CONTENT_SHA -$(SWIG_BASE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) -$(SWIG_BASE)_DEP_FILES := $(DEP_FILES) - diff --git a/rules/swig.mk b/rules/swig.mk deleted file mode 100644 index c5c3c27b6f4b..000000000000 --- a/rules/swig.mk +++ /dev/null @@ -1,22 +0,0 @@ -# swig - -SWIG_VERSION_BASE = 3.0 -SWIG_VERSION = $(SWIG_VERSION_BASE).12 -SWIG_SUBVERSION = 2 - -export SWIG_VERSION_BASE -export SWIG_VERSION -export SWIG_SUBVERSION - -SWIG_BASE = swig$(SWIG_VERSION_BASE)_$(SWIG_VERSION)-$(SWIG_SUBVERSION)_$(CONFIGURED_ARCH).deb -$(SWIG_BASE)_SRC_PATH = $(SRC_PATH)/swig -SONIC_MAKE_DEBS += $(SWIG_BASE) -SONIC_STRETCH_DEBS += $(SWIG_BASE) - -SWIG = swig_$(SWIG_VERSION)-$(SWIG_SUBVERSION)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(SWIG_BASE),$(SWIG))) - -SWIG_DBG = swig$(SWIG_VERSION_BASE)-dbgsym_$(SWIG_VERSION)-$(SWIG_SUBVERSION)_$(CONFIGURED_ARCH).deb -$(eval $(call add_derived_package,$(SWIG_BASE),$(SWIG_DBG))) - -export SWIG_BASE SWIG SWIG_DBG diff --git a/rules/swss-common.mk b/rules/swss-common.mk index 2d49867f9392..8a319ea62bc0 100644 --- a/rules/swss-common.mk +++ b/rules/swss-common.mk @@ -4,7 +4,7 @@ LIBSWSSCOMMON = libswsscommon_1.0.0_$(CONFIGURED_ARCH).deb $(LIBSWSSCOMMON)_SRC_PATH = $(SRC_PATH)/sonic-swss-common $(LIBSWSSCOMMON)_DEPENDS += $(LIBHIREDIS_DEV) $(LIBNL3_DEV) $(LIBNL_GENL3_DEV) \ $(LIBNL_ROUTE3_DEV) $(LIBNL_NF3_DEV) \ - $(LIBNL_CLI_DEV) $(SWIG) + $(LIBNL_CLI_DEV) $(LIBSWSSCOMMON)_RDEPENDS += $(LIBHIREDIS) $(LIBNL3) $(LIBNL_GENL3) \ $(LIBNL_ROUTE3) $(LIBNL_NF3) $(LIBNL_CLI) SONIC_DPKG_DEBS += $(LIBSWSSCOMMON) @@ -15,6 +15,9 @@ $(eval $(call add_derived_package,$(LIBSWSSCOMMON),$(LIBSWSSCOMMON_DEV))) PYTHON_SWSSCOMMON = python-swsscommon_1.0.0_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(LIBSWSSCOMMON),$(PYTHON_SWSSCOMMON))) +PYTHON3_SWSSCOMMON = python3-swsscommon_1.0.0_$(CONFIGURED_ARCH).deb +$(eval $(call add_derived_package,$(LIBSWSSCOMMON),$(PYTHON3_SWSSCOMMON))) + LIBSWSSCOMMON_DBG = libswsscommon-dbg_1.0.0_$(CONFIGURED_ARCH).deb $(LIBSWSSCOMMON_DBG)_DEPENDS += $(LIBSWSSCOMMON) $(LIBSWSSCOMMON_DBG)_RDEPENDS += $(LIBSWSSCOMMON) diff --git a/rules/swss.mk b/rules/swss.mk index f8044d77fb6a..e4d18cf2eb3d 100644 --- a/rules/swss.mk +++ b/rules/swss.mk @@ -3,8 +3,12 @@ SWSS = swss_1.0.0_$(CONFIGURED_ARCH).deb $(SWSS)_SRC_PATH = $(SRC_PATH)/sonic-swss $(SWSS)_DEPENDS += $(LIBSAIREDIS_DEV) $(LIBSAIMETADATA_DEV) $(LIBTEAM_DEV) \ - $(LIBTEAMDCT) $(LIBTEAM_UTILS) $(LIBSWSSCOMMON_DEV) -$(SWSS)_RDEPENDS += $(LIBSAIREDIS) $(LIBSAIMETADATA) $(LIBTEAM) $(LIBSWSSCOMMON) $(PYTHON_SWSSCOMMON) + $(LIBTEAMDCTL) $(LIBTEAM_UTILS) $(LIBSWSSCOMMON_DEV) \ + $(LIBSAIVS) $(LIBSAIVS_DEV) +$(SWSS)_UNINSTALLS = $(LIBSAIVS_DEV) + +$(SWSS)_RDEPENDS += $(LIBSAIREDIS) $(LIBSAIMETADATA) $(LIBTEAM) \ + $(LIBTEAMDCTL) $(LIBSWSSCOMMON) $(PYTHON3_SWSSCOMMON) SONIC_DPKG_DEBS += $(SWSS) SWSS_DBG = swss-dbg_1.0.0_$(CONFIGURED_ARCH).deb diff --git a/rules/swsssdk-py2.mk b/rules/swsssdk-py2.mk index a45677ae5882..8a98d1feda0a 100644 --- a/rules/swsssdk-py2.mk +++ b/rules/swsssdk-py2.mk @@ -3,4 +3,5 @@ SWSSSDK_PY2 = swsssdk-2.0.1-py2-none-any.whl $(SWSSSDK_PY2)_SRC_PATH = $(SRC_PATH)/sonic-py-swsssdk $(SWSSSDK_PY2)_PYTHON_VERSION = 2 +$(SWSSSDK_PY2)_DEPENDS += $(REDIS_DUMP_LOAD_PY2) SONIC_PYTHON_WHEELS += $(SWSSSDK_PY2) diff --git a/rules/swsssdk-py3.mk b/rules/swsssdk-py3.mk index e2f3519e00ca..681ba72f85b7 100644 --- a/rules/swsssdk-py3.mk +++ b/rules/swsssdk-py3.mk @@ -4,5 +4,5 @@ SWSSSDK_PY3 = swsssdk-2.0.1-py3-none-any.whl $(SWSSSDK_PY3)_SRC_PATH = $(SRC_PATH)/sonic-py-swsssdk $(SWSSSDK_PY3)_PYTHON_VERSION = 3 # Synthetic dependency just to avoid race condition -$(SWSSSDK_PY3)_DEPENDS += $(SWSSSDK_PY2) +$(SWSSSDK_PY3)_DEPENDS += $(SWSSSDK_PY2) $(REDIS_DUMP_LOAD_PY3) SONIC_PYTHON_WHEELS += $(SWSSSDK_PY3) diff --git a/rules/syncd.dep b/rules/syncd.dep new file mode 100644 index 000000000000..d9f40a8a0210 --- /dev/null +++ b/rules/syncd.dep @@ -0,0 +1,20 @@ + +ifneq ($(CONFIGURED_PLATFORM),vs) + +#DPKG FRK +SPATH := $($(SYNCD)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/syncd.mk rules/syncd.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) + +SMDEP_PATHS := $(SPATH) $(SPATH)/SAI $(SPATH)/SAI/bm/behavioral-model $(SPATH)/SAI/test/ptf $(SPATH)/SAI/test/saithrift/ctypesgen +$(foreach path, $(SMDEP_PATHS), $(eval $(path) :=$(filter-out $(SMDEP_PATHS),$(addprefix $(path)/, \ + $(shell cd $(path) && git ls-files | grep -v " "))))) + + +$(SYNCD)_CACHE_MODE := GIT_CONTENT_SHA +$(SYNCD)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SYNCD)_DEP_FILES := $(DEP_FILES) +$(SYNCD)_SMDEP_FILES := $(foreach path, $(SMDEP_PATHS), $($(path))) +$(SYNCD)_SMDEP_PATHS := $(SMDEP_PATHS) + +endif diff --git a/rules/syncd.mk b/rules/syncd.mk new file mode 100644 index 000000000000..2b7007d84d5b --- /dev/null +++ b/rules/syncd.mk @@ -0,0 +1,36 @@ +# only used for non-vs platforms + +ifneq ($(CONFIGURED_PLATFORM),vs) + +SYNCD = syncd_1.0.0_$(CONFIGURED_ARCH).deb +$(SYNCD)_RDEPENDS += $(LIBSAIREDIS) $(LIBSAIMETADATA) +$(SYNCD)_DPKG_TARGET = binary-syncd +$(SYNCD)_SRC_PATH = $(SRC_PATH)/sonic-sairedis +$(SYNCD)_DEPENDS += $(LIBSWSSCOMMON_DEV) $(LIBSAIREDIS) +$(SYNCD)_RDEPENDS += $(LIBSWSSCOMMON) +$(SYNCD)_DEB_BUILD_OPTIONS = nocheck +SONIC_DPKG_DEBS += $(SYNCD) + +ifeq ($(ENABLE_SYNCD_RPC),y) +SYNCD_RPC = syncd-rpc_1.0.0_$(CONFIGURED_ARCH).deb +$(SYNCD_RPC)_RDEPENDS += $(LIBSAIREDIS) $(LIBSAIMETADATA) +$(eval $(call add_derived_package,$(SYNCD),$(SYNCD_RPC))) + +# Inject libthrift build dependency for RPC build +$(SYNCD)_DEPENDS += $(LIBSWSSCOMMON_DEV) $(LIBTHRIFT_DEV) +$(SYNCD)_DPKG_TARGET = binary-syncd-rpc +endif + +SYNCD_DBG = syncd-dbg_1.0.0_$(CONFIGURED_ARCH).deb +$(SYNCD_DBG)_DEPENDS += $(SYNCD) +$(SYNCD_DBG)_RDEPENDS += $(SYNCD) +$(eval $(call add_derived_package,$(SYNCD),$(SYNCD_DBG))) + +ifeq ($(ENABLE_SYNCD_RPC),y) +SYNCD_RPC_DBG = syncd-rpc-dbg_1.0.0_$(CONFIGURED_ARCH).deb +$(SYNCD_RPC_DBG)_DEPENDS += $(SYNCD_RPC) +$(SYNCD_RPC_DBG)_RDEPENDS += $(SYNCD_RPC) +$(eval $(call add_derived_package,$(SYNCD),$(SYNCD_RPC_DBG))) +endif + +endif diff --git a/rules/system-health.dep b/rules/system-health.dep new file mode 100644 index 000000000000..31de25cb6d8c --- /dev/null +++ b/rules/system-health.dep @@ -0,0 +1,8 @@ +SPATH := $($(SYSTEM_HEALTH)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/system-health.mk rules/system-health.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(SYSTEM_HEALTH)_CACHE_MODE := GIT_CONTENT_SHA +$(SYSTEM_HEALTH)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SYSTEM_HEALTH)_DEP_FILES := $(DEP_FILES) diff --git a/rules/system-health.mk b/rules/system-health.mk new file mode 100644 index 000000000000..bafc09daa70f --- /dev/null +++ b/rules/system-health.mk @@ -0,0 +1,9 @@ +# system health Python wheel + +SYSTEM_HEALTH = system_health-1.0-py3-none-any.whl +$(SYSTEM_HEALTH)_SRC_PATH = $(SRC_PATH)/system-health +$(SYSTEM_HEALTH)_PYTHON_VERSION = 3 +$(SYSTEM_HEALTH)_DEPENDS = $(SONIC_PY_COMMON_PY3) $(SWSSSDK_PY3) $(SONIC_CONFIG_ENGINE_PY3) +SONIC_PYTHON_WHEELS += $(SYSTEM_HEALTH) + +export system_health_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SYSTEM_HEALTH))" diff --git a/rules/tacacs.mk b/rules/tacacs.mk index c32504f6cd44..1c620ebcedc5 100644 --- a/rules/tacacs.mk +++ b/rules/tacacs.mk @@ -29,8 +29,6 @@ $(LIBNSS_TACPLUS)_RDEPENDS += $(LIBTAC2) $(LIBNSS_TACPLUS)_SRC_PATH = $(SRC_PATH)/tacacs/nss SONIC_MAKE_DEBS += $(LIBNSS_TACPLUS) -SONIC_STRETCH_DEBS += $(LIBPAM_TACPLUS) $(LIBNSS_TACPLUS) - # The .c, .cpp, .h & .hpp files under src/{$DBG_SRC_ARCHIVE list} # are archived into debug one image to facilitate debugging. # diff --git a/rules/telemetry.mk b/rules/telemetry.mk index 0b4421b11942..392ed4f28680 100644 --- a/rules/telemetry.mk +++ b/rules/telemetry.mk @@ -2,6 +2,6 @@ SONIC_TELEMETRY = sonic-telemetry_0.1_$(CONFIGURED_ARCH).deb $(SONIC_TELEMETRY)_SRC_PATH = $(SRC_PATH)/sonic-telemetry -$(SONIC_TELEMETRY)_DEPENDS = $(LIBYANG_DEV) $(LIBYANG) -$(SONIC_TELEMETRY)_RDEPENDS = $(LIBYANG) +$(SONIC_TELEMETRY)_DEPENDS = $(SONIC_MGMT_COMMON) $(SONIC_MGMT_COMMON_CODEGEN) +$(SONIC_TELEMETRY)_RDEPENDS = SONIC_DPKG_DEBS += $(SONIC_TELEMETRY) diff --git a/rules/wpasupplicant.dep b/rules/wpasupplicant.dep new file mode 100644 index 000000000000..cdab026f0c65 --- /dev/null +++ b/rules/wpasupplicant.dep @@ -0,0 +1,16 @@ + +SPATH := $($(WPASUPPLICANT)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/wpasupplicant.mk rules/wpasupplicant.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +# Account files under the src/wpasupplicant/ except submodule directory. +DEP_FILES += $(shell git ls-files $(SPATH) | grep -Ev 'sonic-wpa-supplicant') + +# Account for source files under the sonic-wpa-supplicant submodule directory as well. +WPASUPPLICANT_SPATH := $(SPATH)/sonic-wpa-supplicant +SMDEP_FILES := $(addprefix $(WPASUPPLICANT_SPATH)/,$(shell cd $(WPASUPPLICANT_SPATH) && git ls-files)) + +$(WPASUPPLICANT)_CACHE_MODE := GIT_CONTENT_SHA +$(WPASUPPLICANT)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(WPASUPPLICANT)_DEP_FILES := $(DEP_FILES) +$(WPASUPPLICANT)_SMDEP_FILES := $(SMDEP_FILES) +$(WPASUPPLICANT)_SMDEP_PATHS := $(WPASUPPLICANT_SPATH) diff --git a/rules/wpasupplicant.mk b/rules/wpasupplicant.mk new file mode 100644 index 000000000000..2e6d2ea6b2f1 --- /dev/null +++ b/rules/wpasupplicant.mk @@ -0,0 +1,19 @@ +# wpa package + +WPASUPPLICANT_VERSION = 2.9.0-14 + +export WPASUPPLICANT_VERSION + +WPASUPPLICANT = wpasupplicant_$(WPASUPPLICANT_VERSION)_$(CONFIGURED_ARCH).deb +$(WPASUPPLICANT)_SRC_PATH = $(SRC_PATH)/wpasupplicant +$(WPASUPPLICANT)_DEPENDS += $(LIBSWSSCOMMON_DEV) $(LIBNL3_DEV) $(LIBNL_GENL3_DEV) $(LIBNL_ROUTE3_DEV) +$(WPASUPPLICANT)_RDEPENDS += $(LIBSWSSCOMMON) $(LIBNL3) $(LIBNL_GENL3) $(LIBNL_ROUTE3) +SONIC_MAKE_DEBS += $(WPASUPPLICANT) + +WPASUPPLICANT_DBG = wpasupplicant-dbgsym_$(WPASUPPLICANT_VERSION)_$(CONFIGURED_ARCH).deb +$(eval $(call add_derived_package,$(WPASUPPLICANT),$(WPASUPPLICANT_DBG))) + +# The .c, .cpp, .h & .hpp files under src/{$DBG_SRC_ARCHIVE list} +# are archived into debug one image to facilitate debugging. +# +DBG_SRC_ARCHIVE += wpasupplicant diff --git a/scripts/build_debian_base_system.sh b/scripts/build_debian_base_system.sh new file mode 100755 index 000000000000..a85b3b5bf0ee --- /dev/null +++ b/scripts/build_debian_base_system.sh @@ -0,0 +1,87 @@ +#!/bin/bash + +CONFIGURED_ARCH=$1 +IMAGE_DISTRO=$2 +FILESYSTEM_ROOT=$3 +http_proxy=$4 + +TARGET=$TARGET_PATH +[ -z "$TARGET" ] && TARGET=target + +. /usr/local/share/buildinfo/scripts/buildinfo_base.sh + +TARGET_BASEIMAGE_PATH=$TARGET/versions/host-base-image +mkdir -p $TARGET_BASEIMAGE_PATH + +generate_version_file() +{ + sudo LANG=C chroot $FILESYSTEM_ROOT /bin/bash -c "dpkg-query -W -f '\${Package}==\${Version}\n'" > $TARGET_BASEIMAGE_PATH/versions-deb-${IMAGE_DISTRO}-${CONFIGURED_ARCH} +} + +if [ "$ENABLE_VERSION_CONTROL_DEB" != "y" ]; then + if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then + # qemu arm bin executable for cross-building + sudo mkdir -p $FILESYSTEM_ROOT/usr/bin + sudo cp /usr/bin/qemu*static $FILESYSTEM_ROOT/usr/bin || true + sudo http_proxy=$HTTP_PROXY SKIP_BUILD_HOOK=y debootstrap --variant=minbase --arch $CONFIGURED_ARCH $IMAGE_DISTRO $FILESYSTEM_ROOT http://deb.debian.org/debian + else + sudo http_proxy=$HTTP_PROXY SKIP_BUILD_HOOK=y debootstrap --variant=minbase --arch $CONFIGURED_ARCH $IMAGE_DISTRO $FILESYSTEM_ROOT http://debian-archive.trafficmanager.net/debian + fi + RET=$? + if [ $RET -ne 0 ]; then + exit $RET + fi + + generate_version_file + exit $RET +fi + +ARCH=$(dpkg --print-architecture) +DISTRO=$(grep CODENAME /etc/os-release | cut -d= -f2) +if [ "$ARCH" != "$CONFIGURED_ARCH" ] || [ "$DISTRO" != "$IMAGE_DISTRO" ]; then + "Not support to build different ARCH/DISTRO ${CONFIGURED_ARCH}:${$IMAGE_DISTRO} in ${ARCH}:${DISTRO}." + exit 1 +fi + +BASE_VERSIONS=files/build/versions/host-base-image/versions-deb-${IMAGE_DISTRO} +BASEIMAGE_TARBALLPATH=$TARGET/baseimage +BASEIMAGE_TARBALL=$(realpath -e $TARGET)/baseimage.tgz + +rm -rf $BASEIMAGE_TARBALLPATH $BASEIMAGE_TARBALL + +ARCHIEVES=$BASEIMAGE_TARBALLPATH/var/cache/apt/archives +APTLIST=$BASEIMAGE_TARBALLPATH/var/lib/apt/lists +TARGET_DEBOOTSTRAP=$BASEIMAGE_TARBALLPATH/debootstrap +APTDEBIAN="$APTLIST/deb.debian.org_debian_dists_buster_main_binary-${CONFIGURED_ARCH}_Packages" +DEBPATHS=$TARGET_DEBOOTSTRAP/debpaths +DEBOOTSTRAP_BASE=$TARGET_DEBOOTSTRAP/base +DEBOOTSTRAP_REQUIRED=$TARGET_DEBOOTSTRAP/required +[ -d $BASEIMAGE_TARBALLPATH ] && rm -rf $BASEIMAGE_TARBALLPATH +mkdir -p $ARCHIEVES +mkdir -p $APTLIST +mkdir -p $TARGET_DEBOOTSTRAP +PACKAGES=$(sed -E 's/=(=[^=]*)$/\1/' $BASE_VERSIONS) +URL_ARR=($(apt-get download --print-uris $PACKAGES | cut -d" " -f1 | tr -d "'")) +PACKAGE_ARR=($PACKAGES) +LENGTH=${#PACKAGE_ARR[@]} +for ((i=0;i> $DEBOOTSTRAP_REQUIRED + echo "$packagename /var/cache/apt/archives/$filename" >> $DEBPATHS +done +touch $APTDEBIAN +touch $DEBOOTSTRAP_BASE +(cd $BASEIMAGE_TARBALLPATH && tar -zcf $BASEIMAGE_TARBALL .) + +sudo debootstrap --verbose --variant=minbase --arch $CONFIGURED_ARCH --unpack-tarball=$BASEIMAGE_TARBALL $IMAGE_DISTRO $FILESYSTEM_ROOT +RET=$? +if [ $RET -ne 0 ]; then + exit $RET +fi + +generate_version_file diff --git a/scripts/build_kvm_image.sh b/scripts/build_kvm_image.sh index 5a56ac46efce..06bb87509185 100755 --- a/scripts/build_kvm_image.sh +++ b/scripts/build_kvm_image.sh @@ -20,8 +20,13 @@ on_exit() rm -f $kvm_log } -kvm_log=$(mktemp) -trap on_exit EXIT +on_error() +{ + netstat -antp + ps aux + echo "============= kvm_log ==============" + cat $kvm_log +} create_disk() { @@ -44,18 +49,24 @@ prepare_installer_disk() umount $tmpdir } +apt-get install -y net-tools create_disk prepare_installer_disk echo "Prepare memory for KVM build: $vs_build_prepare_mem" +mount proc /proc -t proc || true free -m if [[ "$vs_build_prepare_mem" == "yes" ]]; then # Force o.s. to drop cache and compact memory so that KVM can get 2G memory - sudo bash -c 'echo 1 > /proc/sys/vm/drop_caches' - sudo bash -c 'echo 1 > /proc/sys/vm/compact_memory' + bash -c 'echo 1 > /proc/sys/vm/drop_caches' + bash -c 'echo 1 > /proc/sys/vm/compact_memory' free -m fi +kvm_log=$(mktemp) +trap on_exit EXIT +trap on_error ERR + /usr/bin/kvm -m $MEM \ -name "onie" \ -boot "order=cd,once=d" -cdrom "$ONIE_RECOVERY_ISO" \ diff --git a/scripts/collect_build_version_files.sh b/scripts/collect_build_version_files.sh new file mode 100755 index 000000000000..b650e421996b --- /dev/null +++ b/scripts/collect_build_version_files.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +RET=$1 +BLDENV=$2 +TARGET_PATH=$3 + +TIMESTAMP=$(date +"%Y%m%d%H%M%S") +. /usr/local/share/buildinfo/scripts/buildinfo_base.sh + +[ -z "$BLDENV" ] && BLDENV=$(grep VERSION_CODENAME /etc/os-release | cut -d= -f2) +[ -z "$BLDENV" ] && exit $RET + +[ -z "$TARGET_PATH" ] && TARGET_PATH=./target + +VERSION_BUILD_PATH=$TARGET_PATH/versions/build +VERSION_SLAVE_PATH=$VERSION_BUILD_PATH/build-sonic-slave-${BLDENV} +LOG_VERSION_PATH=$VERSION_BUILD_PATH/log-${TIMESTAMP} + +sudo chmod -R a+rw $BUILDINFO_PATH +collect_version_files $LOG_VERSION_PATH +([ -d $BUILD_VERSION_PATH ] && [ ! -z "$(ls $BUILD_VERSION_PATH/)" ]) && cp -rf $BUILD_VERSION_PATH/* $LOG_VERSION_PATH/ +mkdir -p $VERSION_SLAVE_PATH + +scripts/versions_manager.py merge -t $VERSION_SLAVE_PATH -b $LOG_VERSION_PATH -e $POST_VERSION_PATH + +rm -rf $BUILD_VERSION_PATH/* + +exit $RET diff --git a/scripts/collect_docker_version_files.sh b/scripts/collect_docker_version_files.sh new file mode 100755 index 000000000000..73f0a9b53198 --- /dev/null +++ b/scripts/collect_docker_version_files.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +DOCKER_IMAGE=$1 +TARGET_PATH=$2 + +[ -z "$TARGET_PATH" ] && TARGET_PATH=./target + +DOCKER_IMAGE_NAME=$(echo $DOCKER_IMAGE | cut -d: -f1) +DOCKER_CONTAINER=$DOCKER_IMAGE_NAME +TARGET_VERSIONS_PATH=$TARGET_PATH/versions/dockers/$DOCKER_IMAGE_NAME + +[ -d $TARGET_VERSIONS_PATH ] && rm -rf $TARGET_VERSIONS_PATH +mkdir -p $TARGET_VERSIONS_PATH + +export DOCKER_CLI_EXPERIMENTAL=enabled + +# Remove the old docker container if existing +if docker container inspect $DOCKER_IMAGE > /dev/null 2>&1; then + docker container rm $DOCKER_IMAGE > /dev/null +fi +docker create --name $DOCKER_CONTAINER --entrypoint /bin/bash $DOCKER_IMAGE +docker cp -L $DOCKER_CONTAINER:/etc/os-release $TARGET_VERSIONS_PATH/ +docker cp -L $DOCKER_CONTAINER:/usr/local/share/buildinfo/pre-versions $TARGET_VERSIONS_PATH/ +docker cp -L $DOCKER_CONTAINER:/usr/local/share/buildinfo/post-versions $TARGET_VERSIONS_PATH/ +docker container rm $DOCKER_CONTAINER diff --git a/scripts/collect_host_image_version_files.sh b/scripts/collect_host_image_version_files.sh new file mode 100755 index 000000000000..2cabc049d9c7 --- /dev/null +++ b/scripts/collect_host_image_version_files.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +TARGET=$1 +FILESYSTEM_ROOT=$2 +VERSIONS_PATH=$TARGET/versions/host-image + +[ -d $VERSIONS_PATH ] && sudo rm -rf $VERSIONS_PATH +mkdir -p $VERSIONS_PATH + +sudo LANG=C chroot $FILESYSTEM_ROOT post_run_buildinfo + +cp -r $FILESYSTEM_ROOT/usr/local/share/buildinfo/pre-versions $VERSIONS_PATH/ +cp -r $FILESYSTEM_ROOT/usr/local/share/buildinfo/post-versions $VERSIONS_PATH/ diff --git a/scripts/convert-pfx-cert-format.sh b/scripts/convert-pfx-cert-format.sh new file mode 100755 index 000000000000..4615dbdf85a9 --- /dev/null +++ b/scripts/convert-pfx-cert-format.sh @@ -0,0 +1,36 @@ +#!/bin/bash -ex + +usage() +{ + echo "Usage: $0 -p -k -c -a " + exit 1 +} + +while getopts "p:k:c:a:" opt; do + case $opt in + p) + PFX_FILE=$OPTARG + ;; + k) + SIGNING_KEY=$OPTARG + ;; + c) + SIGNING_CERT=$OPTARG + ;; + a) + CA_CERT=$OPTARG + ;; + *) + usage + ;; + esac +done + + +( [ -z $PFX_FILE ] || [ -z $SIGNING_KEY ] || [ -z $SIGNING_CERT ] || [ -z $CA_CERT ] ) && exit 1 + +openssl pkcs12 -in "${PFX_FILE}" -clcerts -nokeys -nodes -passin pass: -out ${SIGNING_CERT} +openssl pkcs12 -in "${PFX_FILE}" -nocerts -nodes -passin pass: -out ${SIGNING_KEY} + +# Export the last intermediate CA ceritficate +openssl pkcs12 -in "${PFX_FILE}" -cacerts -nokeys -nodes -passin pass: | sed -z -e "s/.*\(-----BEGIN CERTIFICATE\)/\1/" > ${CA_CERT} diff --git a/scripts/generate_buildinfo_config.sh b/scripts/generate_buildinfo_config.sh new file mode 100755 index 000000000000..fe7657a6b6c9 --- /dev/null +++ b/scripts/generate_buildinfo_config.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +BUILDINFO_PATH=src/sonic-build-hooks + +BUILDINFO_CONFIG=$BUILDINFO_PATH/buildinfo/config/buildinfo.config + +mkdir -p $BUILDINFO_PATH/buildinfo/config + +echo "PACKAGE_URL_PREFIX=$PACKAGE_URL_PREFIX" > $BUILDINFO_CONFIG +echo "SONIC_VERSION_CONTROL_COMPONENTS=$SONIC_VERSION_CONTROL_COMPONENTS" >> $BUILDINFO_CONFIG diff --git a/scripts/prepare_debian_image_buildinfo.sh b/scripts/prepare_debian_image_buildinfo.sh new file mode 100755 index 000000000000..912e0de0b25f --- /dev/null +++ b/scripts/prepare_debian_image_buildinfo.sh @@ -0,0 +1,29 @@ +#!/bin/bash + + +ARCH=$1 +DISTRO=$2 +FILESYSTEM_ROOT=$3 + +. /usr/local/share/buildinfo/scripts/buildinfo_base.sh +VERSION_DEB_PREFERENCE="01-versions-deb" +BUILDINFO_PATH=${FILESYSTEM_ROOT}/usr/local/share/buildinfo +BUILDINFO_VERSION_PATH=${FILESYSTEM_ROOT}/usr/local/share/buildinfo/versions +BUILDINFO_VERSION_DEB=${BUILDINFO_VERSION_PATH}/${VERSION_DEB_PREFERENCE} +OVERRIDE_VERSION_PATH=files/build/versions/host-image +DIFF_VERSIONS_PATH=$BUILDINFO_PATH/diff-versions + +mkdir -p $BUILDINFO_PATH + +# Copy the build info config +cp -rf src/sonic-build-hooks/buildinfo/* $BUILDINFO_PATH/ + +# Generate version lock files +scripts/versions_manager.py generate -t "$BUILDINFO_VERSION_PATH" -m "$OVERRIDE_VERSION_PATH" -d "$DISTRO" -a "$ARCH" + +if [ "$ENABLE_VERSION_CONTROL_DEB" == "y" ]; then + cp -f $BUILDINFO_VERSION_DEB ${FILESYSTEM_ROOT}/etc/apt/preferences.d/ +fi + +sudo LANG=C chroot $FILESYSTEM_ROOT /bin/bash -c "dpkg -i /usr/local/share/buildinfo/sonic-build-hooks_1.0_all.deb" +sudo LANG=C chroot $FILESYSTEM_ROOT /bin/bash -c "pre_run_buildinfo" diff --git a/scripts/prepare_docker_buildinfo.sh b/scripts/prepare_docker_buildinfo.sh new file mode 100755 index 000000000000..aa3aaaa4bed5 --- /dev/null +++ b/scripts/prepare_docker_buildinfo.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +IMAGENAME=$1 +DOCKERFILE=$2 +ARCH=$3 +DOCKERFILE_TARGE=$4 +DISTRO=$5 + +[ -z "$BUILD_SLAVE" ] && BUILD_SLAVE=n +[ -z "$DOCKERFILE_TARGE" ] && DOCKERFILE_TARGE=$DOCKERFILE +DOCKERFILE_PATH=$(dirname "$DOCKERFILE_TARGE") +BUILDINFO_PATH="${DOCKERFILE_PATH}/buildinfo" +BUILDINFO_VERSION_PATH="${BUILDINFO_PATH}/versions" + +[ -d $BUILDINFO_PATH ] && rm -rf $BUILDINFO_PATH +mkdir -p $BUILDINFO_VERSION_PATH + +# Get the debian distribution from the docker base image +if [ -z "$DISTRO" ]; then + DOCKER_BASE_IMAGE=$(grep "^FROM" $DOCKERFILE | head -n 1 | awk '{print $2}') + DISTRO=$(docker run --rm --entrypoint "" $DOCKER_BASE_IMAGE cat /etc/os-release | grep VERSION_CODENAME | cut -d= -f2) + [ -z "$DISTRO" ] && DISTRO=jessie +fi + +DOCKERFILE_PRE_SCRIPT='# Auto-Generated for buildinfo +COPY ["buildinfo", "/usr/local/share/buildinfo"] +RUN dpkg -i /usr/local/share/buildinfo/sonic-build-hooks_1.0_all.deb +RUN pre_run_buildinfo' + +# Add the auto-generate code if it is not added in the target Dockerfile +if [ ! -f $DOCKERFILE_TARGE ] || ! grep -q "Auto-Generated for buildinfo" $DOCKERFILE_TARGE; then + # Insert the docker build script before the RUN command + LINE_NUMBER=$(grep -Fn -m 1 'RUN' $DOCKERFILE | cut -d: -f1) + TEMP_FILE=$(mktemp) + awk -v text="${DOCKERFILE_PRE_SCRIPT}" -v linenumber=$LINE_NUMBER 'NR==linenumber{print text}1' $DOCKERFILE > $TEMP_FILE + + # Append the docker build script at the end of the docker file + echo -e "\nRUN post_run_buildinfo" >> $TEMP_FILE + + cat $TEMP_FILE > $DOCKERFILE_TARGE + rm -f $TEMP_FILE +fi + +# Copy the build info config +cp -rf src/sonic-build-hooks/buildinfo/* $BUILDINFO_PATH + +# Generate the version lock files +scripts/versions_manager.py generate -t "$BUILDINFO_VERSION_PATH" -n "$IMAGENAME" -d "$DISTRO" -a "$ARCH" + +touch $BUILDINFO_VERSION_PATH/versions-deb diff --git a/scripts/prepare_slave_container_buildinfo.sh b/scripts/prepare_slave_container_buildinfo.sh new file mode 100755 index 000000000000..be6fe078bdfb --- /dev/null +++ b/scripts/prepare_slave_container_buildinfo.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +SLAVE_DIR=$1 +ARCH=$2 +DISTRO=$3 + +# Install the latest debian package sonic-build-hooks in the slave container +sudo dpkg -i --force-overwrite $SLAVE_DIR/buildinfo/sonic-build-hooks_*.deb > /dev/null + +# Enable the build hooks +symlink_build_hooks + +# Build the slave running config +cp -rf $SLAVE_DIR/buildinfo/* /usr/local/share/buildinfo/ +. /usr/local/share/buildinfo/scripts/buildinfo_base.sh + +# Build the slave version config +[ -d /usr/local/share/buildinfo/versions ] && rm -rf /usr/local/share/buildinfo/versions +scripts/versions_manager.py generate -t "/usr/local/share/buildinfo/versions" -n "build-${SLAVE_DIR}" -d "$DISTRO" -a "$ARCH" +touch ${BUILDINFO_PATH}/versions/versions-deb + +rm -f /etc/apt/preferences.d/01-versions-deb +([ "$ENABLE_VERSION_CONTROL_DEB" == "y" ] && [ -f $VERSION_DEB_PREFERENCE ]) && cp -f $VERSION_DEB_PREFERENCE /etc/apt/preferences.d/ +exit 0 diff --git a/scripts/process_log.sh b/scripts/process_log.sh new file mode 100755 index 000000000000..9977535ed812 --- /dev/null +++ b/scripts/process_log.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +add_timestamp="" + +while getopts ":t" opt; do + case $opt in + t) + add_timestamp="y" + ;; + esac +done + +while IFS= read -r line; do + if [ $add_timestamp ]; then + printf '[%s] ' "$(date +%T)" + fi + printf '%s\n' "$line" +done + + diff --git a/scripts/sign_image.sh b/scripts/sign_image.sh new file mode 100755 index 000000000000..f726ad130cb8 --- /dev/null +++ b/scripts/sign_image.sh @@ -0,0 +1,69 @@ +#!/bin/bash -ex + + +IMAGE="" +SIGNING_KEY="" +SIGNING_CERT="" +CA_CERT="" + +usage() +{ + echo "Usage: $0 -i [-k -c -a ]" + exit 1 +} + +generate_signing_key() +{ + TMP_CERT_PATH=$(mktemp -d) + SIGNING_KEY="${TMP_CERT_PATH}/signing.key" + SIGNING_CERT="${TMP_CERT_PATH}/signing.crt" + SIGNING_CSR="${TMP_CERT_PATH}/signing.csr" + CA_KEY="${TMP_CERT_PATH}/ca.key" + + # Generate the CA key and certificate + openssl genrsa -out $CA_KEY 4096 + openssl req -x509 -new -nodes -key $CA_KEY -sha256 -days 3650 -subj "/C=US/ST=Test/L=Test/O=Test/CN=Test" -out $CA_CERT + + # Generate the signing key, certificate request and certificate + openssl genrsa -out $SIGNING_KEY 4096 + openssl req -new -key $SIGNING_KEY -subj "/C=US/ST=Test/L=Test/O=Test/CN=Test" -out $SIGNING_CSR + openssl x509 -req -in $SIGNING_CSR -CA $CA_CERT -CAkey $CA_KEY -CAcreateserial -out $SIGNING_CERT -days 1825 -sha256 +} + +while getopts "i:k:c:a:t:" opt; do + case $opt in + i) + IMAGE=$OPTARG + ;; + k) + SIGNING_KEY=$OPTARG + ;; + c) + SIGNING_CERT=$OPTARG + ;; + a) + CA_CERT=$OPTARG + ;; + *) + usage + ;; + esac +done + +[ -z $CA_CERT ] && echo "Not to sign the image since the CA certificate not provided" 1>&2 && exit 1 + +# Generate the self signed cert if not provided by input +[ ! -f $CA_CERT ] && generate_signing_key + +# Verify the required files existing +[ ! -f $SIGNING_KEY ] && echo "$SIGNING_KEY not exist" && exit 1 +[ ! -f $SIGNING_CERT ] && echo "$SIGNING_CERT not exist" && exit 1 +[ ! -f $CA_CERT ] && echo "$CA_CERT not exist" && exit 1 + +# Prepare the image +swi-signature prepare $IMAGE + +# Sign the image +swi-signature sign $IMAGE $SIGNING_CERT $CA_CERT --key $SIGNING_KEY + +exit 0 diff --git a/scripts/versions_manager.py b/scripts/versions_manager.py new file mode 100755 index 000000000000..336568bfb4e0 --- /dev/null +++ b/scripts/versions_manager.py @@ -0,0 +1,668 @@ +#!/usr/bin/python3 + +import argparse +import glob +import os +import sys + +ALL_DIST = 'all' +ALL_ARCH = 'all' +DEFAULT_MODULE = 'default' +DEFAULT_VERSION_PATH = 'files/build/versions' +VERSION_PREFIX="versions-" +VERSION_DEB_PREFERENCE = '01-versions-deb' +DEFAULT_OVERWRITE_COMPONENTS=['deb', 'py2', 'py3'] +SLAVE_INDIVIDULE_VERSION = False + + +class Component: + ''' + The component consists of mutiple packages + + ctype -- Component Type, such as deb, py2, etc + dist -- Distribution, such as stretch, buster, etc + arch -- Architectrue, such as amd64, arm64, etc + + ''' + def __init__(self, versions, ctype, dist=ALL_DIST, arch=ALL_ARCH): + self.versions = versions + self.ctype = ctype + if not dist: + dist = ALL_DIST + if not arch: + arch = ALL_ARCH + self.dist = dist + self.arch = arch + + @classmethod + def get_versions(cls, version_file): + result = {} + if not os.path.exists(version_file): + return result + with open(version_file) as fp: + for line in fp.readlines(): + offset = line.rfind('==') + if offset > 0: + package = line[:offset].strip() + version = line[offset+2:].strip() + result[package] = version + return result + + def clone(self): + return Component(self.versions.copy(), self.ctype, self.dist, self.arch) + + def merge(self, versions, overwritten=True): + for package in versions: + if overwritten or package not in self.versions: + self.versions[package] = versions[package] + + def subtract(self, versions): + for package in versions: + if package in self.versions and self.versions[package] == versions[package]: + del self.versions[package] + + def dump(self, config=False, priority=999): + result = [] + for package in sorted(self.versions.keys(), key=str.casefold): + if config and self.ctype == 'deb': + lines = 'Package: {0}\nPin: version {1}\nPin-Priority: {2}\n\n'.format(package, self.versions[package], priority) + result.append(lines) + else: + result.append('{0}=={1}'.format(package, self.versions[package])) + return "\n".join(result) + + def dump_to_file(self, version_file, config=False, priority=999): + if len(self.versions) <= 0: + return + with open(version_file, 'w') as f: + f.write(self.dump(config, priority)) + + def dump_to_path(self, file_path, config=False, priority=999): + if len(self.versions) <= 0: + return + if not os.path.exists(file_path): + os.makedirs(file_path) + filename = self.get_filename() + if config and self.ctype == 'deb': + none_config_file_path = os.path.join(file_path, filename) + self.dump_to_file(none_config_file_path, False, priority) + filename = VERSION_DEB_PREFERENCE + file_path = os.path.join(file_path, filename) + self.dump_to_file(file_path, config, priority) + + # Check if the self component can be overwritten by the input component + def check_overwritable(self, component, for_all_dist=False, for_all_arch=False): + if self.ctype != component.ctype: + return False + if self.dist != component.dist and not (for_all_dist and self.dist == ALL_DIST): + return False + if self.arch != component.arch and not (for_all_arch and self.arch == ALL_ARCH): + return False + return True + + # Check if the self component can inherit the package versions from the input component + def check_inheritable(self, component): + if self.ctype != component.ctype: + return False + if self.dist != component.dist and component.dist != ALL_DIST: + return False + if self.arch != component.arch and component.arch != ALL_ARCH: + return False + return True + + ''' + Get the file name + + The file name format: versions-{ctype}-{dist}-{arch} + If {arch} is all, then the file name format: versions-{ctype}-{dist} + if {arch} is all and {dist} is all, then the file name format: versions-{ctype} + ''' + def get_filename(self): + filename = VERSION_PREFIX + self.ctype + dist = self.dist + if self.arch and self.arch != ALL_ARCH: + if not dist: + dist = ALL_DIST + return filename + '-' + dist + '-' + self.arch + if dist and self.dist != ALL_DIST: + filename = filename + '-' + dist + return filename + + def get_order_keys(self): + dist = self.dist + if not dist or dist == ALL_DIST: + dist = '' + arch = self.arch + if not arch or arch == ALL_ARCH: + arch = '' + return (self.ctype, dist, arch) + + def clean_info(self, clean_dist=True, clean_arch=True, force=False): + if clean_dist: + if force or self.ctype != 'deb': + self.dist = ALL_DIST + if clean_arch: + self.arch = ALL_ARCH + + +class VersionModule: + ''' + The version module represents a build target, such as docker image, host image, consists of multiple components. + + name -- The name of the image, such as sonic-slave-buster, docker-lldp, etc + ''' + def __init__(self, name=None, components=None): + self.name = name + self.components = components + + # Overwrite the docker/host image/base image versions + def overwrite(self, module, for_all_dist=False, for_all_arch=False): + # Overwrite from generic one to detail one + # For examples: versions-deb overwrtten by versions-deb-buster, and versions-deb-buster overwritten by versions-deb-buster-amd64 + components = sorted(module.components, key = lambda x : x.get_order_keys()) + for merge_component in components: + merged = False + for component in self.components: + if component.check_overwritable(merge_component, for_all_dist=for_all_dist, for_all_arch=for_all_arch): + component.merge(merge_component.versions, True) + merged = True + if not merged: + tmp_component = merge_component.clone() + tmp_component.clean_info(clean_dist=for_all_dist, clean_arch=for_all_arch) + self.components.append(tmp_component) + self.adjust() + + def get_config_module(self, default_module, dist, arch): + if self.is_individule_version(): + return self + module = default_module + if not self.is_aggregatable_module(self.name): + module = default_module.clone(exclude_ctypes=DEFAULT_OVERWRITE_COMPONENTS) + return self._get_config_module(module, dist, arch) + + def _get_config_module(self, default_module, dist, arch): + module = default_module.clone() + default_ctype_components = module._get_components_per_ctypes() + module.overwrite(self) + config_components = [] + ctype_components = module._get_components_per_ctypes() + for ctype in default_ctype_components: + if ctype not in ctype_components: + ctype_components[ctype] = [] + for components in ctype_components.values(): + if len(components) == 0: + continue + config_component = self._get_config_for_ctype(components, dist, arch) + config_components.append(config_component) + config_module = VersionModule(self.name, config_components) + return config_module + + def _get_config_for_ctype(self, components, dist, arch): + result = Component({}, components[0].ctype, dist, arch) + for component in sorted(components, key = lambda x : x.get_order_keys()): + if result.check_inheritable(component): + result.merge(component.versions, True) + return result + + def subtract(self, default_module): + module = self.clone() + result = [] + ctype_components = module._get_components_per_ctypes() + for ctype in ctype_components: + components = ctype_components[ctype] + components = sorted(components, key = lambda x : x.get_order_keys()) + for i in range(0, len(components)): + component = components[i] + base_module = VersionModule(self.name, components[0:i]) + config_module = base_module._get_config_module(default_module, component.dist, component.arch) + config_components = config_module._get_components_by_ctype(ctype) + if len(config_components) > 0: + config_component = config_components[0] + component.subtract(config_component.versions) + if len(component.versions): + result.append(component) + self.components = result + + def adjust(self): + result_components = [] + ctype_components = self._get_components_per_ctypes() + for components in ctype_components.values(): + result_components += self._adjust_components_for_ctype(components) + self.components = result_components + + def _get_components_by_ctype(self, ctype): + components = [] + for component in self.components: + if component.ctype == ctype: + components.append(component) + return components + + def _adjust_components_for_ctype(self, components): + components = sorted(components, key = lambda x : x.get_order_keys()) + result = [] + for i in range(0, len(components)): + component = components[i] + inheritable_component = Component({}, component.ctype) + for j in range(0, i): + base_component = components[j] + if component.check_inheritable(base_component): + inheritable_component.merge(base_component.versions, True) + component.subtract(inheritable_component.versions) + if len(component.versions) > 0: + result.append(component) + return result + + def _get_components_per_ctypes(self): + result = {} + for component in self.components: + components = result.get(component.ctype, []) + components.append(component) + result[component.ctype] = components + return result + + def load(self, image_path, filter_ctype=None, filter_dist=None, filter_arch=None): + version_file_pattern = os.path.join(image_path, VERSION_PREFIX) + '*' + file_paths = glob.glob(version_file_pattern) + components = [] + self.name = os.path.basename(image_path) + self.components = components + for file_path in file_paths: + filename = os.path.basename(file_path) + items = filename.split('-') + if len(items) < 2: + continue + ctype = items[1] + if filter_ctype and filter_ctype != ctype: + continue + dist = '' + arch = '' + if len(items) > 2: + dist = items[2] + if filter_dist and dist and filter_dist != dist: + continue + if len(items) > 3: + arch = items[3] + if filter_arch and arch and filter_arch != arch: + continue + versions = Component.get_versions(file_path) + component = Component(versions, ctype, dist, arch) + components.append(component) + + def load_from_target(self, image_path): + post_versions = os.path.join(image_path, 'post-versions') + if os.path.exists(post_versions): + self.load(post_versions) + self.name = os.path.basename(image_path) + pre_versions = os.path.join(image_path, 'pre-versions') + if os.path.exists(pre_versions): + pre_module = VersionModule() + pre_module.load(pre_versions) + self.subtract(pre_module) + else: + self.load(image_path) + + def dump(self, module_path, config=False, priority=999): + version_file_pattern = os.path.join(module_path, VERSION_PREFIX + '*') + for filename in glob.glob(version_file_pattern): + os.remove(filename) + for component in self.components: + component.dump_to_path(module_path, config, priority) + + def filter(self, ctypes=[]): + if 'all' in ctypes: + return self + components = [] + for component in self.components: + if component.ctype in ctypes: + components.append(component) + self.components = components + + def clean_info(self, clean_dist=True, clean_arch=True, force=False): + for component in self.components: + component.clean_info(clean_dist=clean_dist, clean_arch=clean_arch, force=force) + + def clone(self, ctypes=None, exclude_ctypes=None): + components = [] + for component in self.components: + if exclude_ctypes and component.ctype in exclude_ctypes: + continue + if ctypes and component.ctype not in ctypes: + continue + components.append(component.clone()) + return VersionModule(self.name, components) + + def is_slave_module(self): + return self.name.startswith('sonic-slave-') + + # Do not inherit the version from the default module + def is_individule_version(self): + return self.is_slave_module() and SLAVE_INDIVIDULE_VERSION + + @classmethod + def is_aggregatable_module(cls, module_name): + if module_name.startswith('sonic-slave-'): + return False + if module_name.startswith('build-sonic-slave-'): + return False + if module_name == DEFAULT_MODULE: + return False + if module_name == 'host-image' or module_name == 'host-base-image': + return False + return True + + @classmethod + def get_module_path_by_name(cls, source_path, module_name): + common_modules = ['default', 'host-image', 'host-base-image'] + if module_name in common_modules: + return os.path.join(source_path, 'files/build/versions', module_name) + if module_name.startswith('build-sonic-slave-'): + return os.path.join(source_path, 'files/build/versions/build', module_name) + return os.path.join(source_path, 'files/build/versions/dockers', module_name) + +class VersionBuild: + ''' + The VersionBuild consists of multiple version modules. + + ''' + def __init__(self, target_path="./target", source_path='.'): + self.target_path = target_path + self.source_path = source_path + self.modules = {} + + def load_from_target(self): + dockers_path = os.path.join(self.target_path, 'versions/dockers') + build_path = os.path.join(self.target_path, 'versions/build') + modules = {} + self.modules = modules + file_paths = glob.glob(dockers_path + '/*') + file_paths += glob.glob(build_path + '/build-*') + file_paths.append(os.path.join(self.target_path, 'versions/host-image')) + file_paths.append(os.path.join(self.target_path, 'versions/host-base-image')) + for file_path in file_paths: + if not os.path.isdir(file_path): + continue + module = VersionModule() + module.load_from_target(file_path) + modules[module.name] = module + self._merge_dgb_modules() + + def load_from_source(self): + # Load default versions and host image versions + versions_path = os.path.join(self.source_path, 'files/build/versions') + dockers_path = os.path.join(versions_path, "dockers") + build_path = os.path.join(versions_path, "build") + paths = [os.path.join(versions_path, 'default')] + paths += glob.glob(versions_path + '/host-*') + paths += glob.glob(dockers_path + '/*') + paths += glob.glob(build_path + '/*') + modules = {} + self.modules = modules + for image_path in paths: + module = VersionModule() + module.load(image_path) + modules[module.name] = module + + def overwrite(self, build, for_all_dist=False, for_all_arch=False): + for target_module in build.modules.values(): + module = self.modules.get(target_module.name, None) + tmp_module = target_module.clone() + tmp_module.clean_info(for_all_dist, for_all_arch) + if module: + module.overwrite(tmp_module, for_all_dist=for_all_dist, for_all_arch=for_all_arch) + else: + self.modules[target_module.name] = tmp_module + + def dump(self): + for module in self.modules.values(): + module_path = self.get_module_path(module) + module.dump(module_path) + + def subtract(self, default_module): + none_aggregatable_module = default_module.clone(exclude_ctypes=DEFAULT_OVERWRITE_COMPONENTS) + for module in self.modules.values(): + if module.name == DEFAULT_MODULE: + continue + if module.name == 'host-base-image': + continue + if module.is_individule_version(): + continue + tmp_module = default_module + if not module.is_aggregatable_module(module.name): + tmp_module = none_aggregatable_module + module.subtract(tmp_module) + + def freeze(self, rebuild=False, for_all_dist=False, for_all_arch=False, ctypes=['all']): + if rebuild: + self.load_from_target() + self.filter(ctypes=ctypes) + default_module = self.get_default_module() + self._clean_component_info() + self.subtract(default_module) + self.modules[DEFAULT_MODULE] = default_module + self.dump() + return + self.load_from_source() + default_module = self.modules.get(DEFAULT_MODULE, None) + target_build = VersionBuild(self.target_path, self.source_path) + target_build.load_from_target() + target_build.filter(ctypes=ctypes) + if not default_module: + raise Exception("The default versions does not exist") + for module in target_build.modules.values(): + if module.is_individule_version(): + continue + tmp_module = module.clone(exclude_ctypes=DEFAULT_OVERWRITE_COMPONENTS) + default_module.overwrite(tmp_module, for_all_dist=True, for_all_arch=True) + target_build.subtract(default_module) + self.overwrite(target_build, for_all_dist=for_all_dist, for_all_arch=for_all_arch) + self.dump() + + def filter(self, ctypes=[]): + for module in self.modules.values(): + module.filter(ctypes=ctypes) + + def get_default_module(self): + if DEFAULT_MODULE in self.modules: + return self.modules[DEFAULT_MODULE] + ctypes = self.get_component_types() + dists = self.get_dists() + components = [] + for ctype in ctypes: + if ctype == 'deb': + for dist in dists: + versions = self._get_versions(ctype, dist) + common_versions = self._get_common_versions(versions) + component = Component(common_versions, ctype, dist) + components.append(component) + else: + versions = self._get_versions(ctype) + common_versions = self._get_common_versions(versions) + component = Component(common_versions, ctype) + components.append(component) + return VersionModule(DEFAULT_MODULE, components) + + def get_aggregatable_modules(self): + modules = {} + for module_name in self.modules: + if not VersionModule.is_aggregatable_module(module_name): + continue + module = self.modules[module_name] + modules[module_name] = module + return modules + + def get_components(self): + components = [] + for module_name in self.modules: + module = self.modules[module_name] + for component in module.components: + components.append(component) + return components + + def get_component_types(self): + ctypes = [] + for module_name in self.modules: + module = self.modules[module_name] + for component in module.components: + if component.ctype not in ctypes: + ctypes.append(component.ctype) + return ctypes + + def get_dists(self): + dists = [] + components = self.get_components() + for component in components: + if component.dist not in dists: + dists.append(component.dist) + return dists + + def get_archs(self): + archs = [] + components = self.get_components() + for component in components: + if component.arch not in archs: + archs.append(component.arch) + return archs + + def get_module_path(self, module): + return self.get_module_path_by_name(module.name) + + def get_module_path_by_name(self, module_name): + return VersionModule.get_module_path_by_name(self.source_path, module_name) + + def _merge_dgb_modules(self): + dbg_modules = [] + for module_name in self.modules: + if not module_name.endswith('-dbg'): + continue + dbg_modules.append(module_name) + base_module_name = module_name[:-4] + if base_module_name not in self.modules: + raise Exception('The Module {0} not found'.format(base_module_name)) + base_module = self.modules[base_module_name] + dbg_module = self.modules[module_name] + base_module.overwrite(dbg_module) + for module_name in dbg_modules: + del self.modules[module_name] + + def _clean_component_info(self, clean_dist=True, clean_arch=True): + for module in self.modules.values(): + module.clean_info(clean_dist, clean_arch) + + def _get_versions(self, ctype, dist=None, arch=None): + versions = {} + modules = self.get_aggregatable_modules() + for module_name in self.modules: + if module_name not in modules: + temp_module = self.modules[module_name].clone(exclude_ctypes=DEFAULT_OVERWRITE_COMPONENTS) + modules[module_name] = temp_module + for module in modules.values(): + for component in module.components: + if ctype != component.ctype: + continue + if dist and dist != component.dist: + continue + if arch and arch != component.arch: + continue + for package in component.versions: + version = component.versions[package] + package_versions = versions.get(package, []) + if version not in package_versions: + package_versions.append(version) + versions[package] = package_versions + return versions + + def _get_common_versions(self, versions): + common_versions = {} + for package in versions: + package_versions = versions[package] + if len(package_versions) == 1: + common_versions[package] = package_versions[0] + return common_versions + + +class VersionManagerCommands: + def __init__(self): + usage = 'version_manager.py []\n\n' + usage = usage + 'The most commonly used commands are:\n' + usage = usage + ' freeze Freeze the version files\n' + usage = usage + ' generate Generate the version files\n' + usage = usage + ' merge Merge the version files' + parser = argparse.ArgumentParser(description='Version manager', usage=usage) + parser.add_argument('command', help='Subcommand to run') + args = parser.parse_args(sys.argv[1:2]) + if not hasattr(self, args.command): + print('Unrecognized command: {0}'.format(args.command)) + parser.print_help() + exit(1) + getattr(self, args.command)() + + def freeze(self): + parser = argparse.ArgumentParser(description = 'Freeze the version files') + parser.add_argument('-t', '--target_path', default='./target', help='target path') + parser.add_argument('-s', '--source_path', default='.', help='source path') + + # store_true which implies default=False + parser.add_argument('-r', '--rebuild', action='store_true', help='rebuild all versions') + parser.add_argument('-d', '--for_all_dist', action='store_true', help='apply the versions for all distributions') + parser.add_argument('-a', '--for_all_arch', action='store_true', help='apply the versions for all architectures') + parser.add_argument('-c', '--ctypes', default='all', help='component types to freeze') + args = parser.parse_args(sys.argv[2:]) + ctypes = args.ctypes.split(',') + if len(ctypes) == 0: + ctypes = ['all'] + build = VersionBuild(target_path=args.target_path, source_path=args.source_path) + build.freeze(rebuild=args.rebuild, for_all_dist=args.for_all_dist, for_all_arch=args.for_all_arch, ctypes=ctypes) + + def merge(self): + parser = argparse.ArgumentParser(description = 'Merge the version files') + parser.add_argument('-t', '--target_path', required=True, help='target path to save the merged version files') + parser.add_argument('-m', '--module_path', default=None, help='merge path, use the target path if not specified') + parser.add_argument('-b', '--base_path', required=True, help='base path, merge to the module path') + parser.add_argument('-e', '--exclude_module_path', default=None, help='exclude module path') + args = parser.parse_args(sys.argv[2:]) + module_path = args.module_path + if not module_path: + module_path = args.target_path + if not os.path.exists(module_path): + print('The module path {0} does not exist'.format(module_path)) + if not os.path.exists(args.target_path): + os.makedirs(args.target_path) + module = VersionModule() + module.load(module_path) + base_module = VersionModule() + base_module.load(args.base_path) + module.overwrite(base_module) + if args.exclude_module_path: + exclude_module = VersionModule() + exclude_module.load(args.exclude_module_path) + module.subtract(exclude_module) + module.dump(args.target_path) + + def generate(self): + parser = argparse.ArgumentParser(description = 'Generate the version files') + parser.add_argument('-t', '--target_path', required=True, help='target path to generate the version lock files') + group = parser.add_mutually_exclusive_group(required=True) + group.add_argument('-n', '--module_name', help="module name, such as docker-lldp, sonic-slave-buster, etc") + group.add_argument('-m', '--module_path', help="module apth, such as files/docker/versions/dockers/docker-lldp, files/docker/versions/dockers/sonic-slave-buster, etc") + parser.add_argument('-s', '--source_path', default='.', help='source path') + parser.add_argument('-d', '--distribution', required=True, help="distribution") + parser.add_argument('-a', '--architecture', required=True, help="architecture") + parser.add_argument('-p', '--priority', default=999, help="priority of the debian apt preference") + + args = parser.parse_args(sys.argv[2:]) + module_path = args.module_path + if not module_path: + module_path = VersionModule.get_module_path_by_name(args.source_path, args.module_name) + if not os.path.exists(args.target_path): + os.makedirs(args.target_path) + module = VersionModule() + module.load(module_path, filter_dist=args.distribution, filter_arch=args.architecture) + default_module_path = VersionModule.get_module_path_by_name(args.source_path, DEFAULT_MODULE) + default_module = VersionModule() + default_module.load(default_module_path, filter_dist=args.distribution, filter_arch=args.architecture) + config = module.get_config_module(default_module, args.distribution, args.architecture) + config.clean_info(force=True) + config.dump(args.target_path, config=True, priority=args.priority) + +if __name__ == "__main__": + VersionManagerCommands() diff --git a/slave.mk b/slave.mk index 0bb571e5b70f..33b97653c597 100644 --- a/slave.mk +++ b/slave.mk @@ -9,7 +9,10 @@ SHELL = /bin/bash USER = $(shell id -un) UID = $(shell id -u) GUID = $(shell id -g) -SONIC_GET_VERSION=$(shell export BUILD_TIMESTAMP=$(BUILD_TIMESTAMP) && export BUILD_NUMBER=$(BUILD_NUMBER) && . functions.sh && sonic_get_version) + +ifeq ($(SONIC_IMAGE_VERSION),) + override SONIC_IMAGE_VERSION = $(shell export BUILD_TIMESTAMP=$(BUILD_TIMESTAMP) && export BUILD_NUMBER=$(BUILD_NUMBER) && . functions.sh && sonic_get_version) +endif .SECONDEXPANSION: @@ -24,20 +27,21 @@ SRC_PATH = src RULES_PATH = rules TARGET_PATH = target DOCKERS_PATH = dockers -ifdef BLDENV +BLDENV = $(shell lsb_release -cs) DEBS_PATH = $(TARGET_PATH)/debs/$(BLDENV) FILES_PATH = $(TARGET_PATH)/files/$(BLDENV) -else -DEBS_PATH = $(TARGET_PATH)/debs -FILES_PATH = $(TARGET_PATH)/files -endif PYTHON_DEBS_PATH = $(TARGET_PATH)/python-debs PYTHON_WHEELS_PATH = $(TARGET_PATH)/python-wheels PROJECT_ROOT = $(shell pwd) +JESSIE_DEBS_PATH = $(TARGET_PATH)/debs/jessie +JESSIE_FILES_PATH = $(TARGET_PATH)/files/jessie STRETCH_DEBS_PATH = $(TARGET_PATH)/debs/stretch STRETCH_FILES_PATH = $(TARGET_PATH)/files/stretch +BUSTER_DEBS_PATH = $(TARGET_PATH)/debs/buster +BUSTER_FILES_PATH = $(TARGET_PATH)/files/buster DBG_IMAGE_MARK = dbg DBG_SRC_ARCHIVE_FILE = $(TARGET_PATH)/sonic_src.tar.gz +DPKG_ADMINDIR_PATH = /sonic/dpkg CONFIGURED_PLATFORM := $(shell [ -f .platform ] && cat .platform || echo generic) PLATFORM_PATH = platform/$(CONFIGURED_PLATFORM) @@ -45,10 +49,18 @@ CONFIGURED_ARCH := $(shell [ -f .arch ] && cat .arch || echo amd64) ifeq ($(PLATFORM_ARCH),) override PLATFORM_ARCH = $(CONFIGURED_ARCH) endif +IMAGE_DISTRO := buster +IMAGE_DISTRO_DEBS_PATH = $(TARGET_PATH)/debs/$(IMAGE_DISTRO) +IMAGE_DISTRO_FILES_PATH = $(TARGET_PATH)/files/$(IMAGE_DISTRO) + export BUILD_NUMBER export BUILD_TIMESTAMP +export SONIC_IMAGE_VERSION export CONFIGURED_PLATFORM export CONFIGURED_ARCH +export PYTHON_WHEELS_PATH +export IMAGE_DISTRO +export IMAGE_DISTRO_DEBS_PATH ############################################################################### ## Utility rules @@ -62,12 +74,17 @@ ifneq ($(CONFIGURED_PLATFORM),generic) endif configure : - @mkdir -p target/debs - @mkdir -p target/debs/stretch - @mkdir -p target/files - @mkdir -p target/files/stretch - @mkdir -p target/python-debs - @mkdir -p target/python-wheels + @mkdir -p $(DEBS_PATH) + @mkdir -p $(JESSIE_DEBS_PATH) + @mkdir -p $(STRETCH_DEBS_PATH) + @mkdir -p $(BUSTER_DEBS_PATH) + @mkdir -p $(FILES_PATH) + @mkdir -p $(JESSIE_FILES_PATH) + @mkdir -p $(STRETCH_FILES_PATH) + @mkdir -p $(BUSTER_FILES_PATH) + @mkdir -p $(PYTHON_DEBS_PATH) + @mkdir -p $(PYTHON_WHEELS_PATH) + @mkdir -p $(DPKG_ADMINDIR_PATH) @echo $(PLATFORM) > .platform @echo $(PLATFORM_ARCH) > .arch @@ -83,25 +100,26 @@ list : ############################################################################### include $(RULES_PATH)/config +-include $(RULES_PATH)/config.user + + +############################################################################### +## Version control related exports +############################################################################### +export PACKAGE_URL_PREFIX +export TRUSTED_GPG_URLS +export SONIC_VERSION_CONTROL_COMPONENTS ifeq ($(SONIC_ENABLE_PFCWD_ON_START),y) ENABLE_PFCWD_ON_START = y endif -ifeq ($(SONIC_ENABLE_SYSTEM_TELEMETRY),y) -ENABLE_SYSTEM_TELEMETRY = y +ifeq ($(SONIC_INCLUDE_SYSTEM_TELEMETRY),y) +INCLUDE_SYSTEM_TELEMETRY = y endif -ifneq (,$(filter $(CONFIGURED_ARCH), armhf arm64)) - # Workaround: Force disable Telmetry for ARM, will be removed after fixing issue - # Issue: qemu crashes when it uses "go get url" - # Qemu Support: https://bugs.launchpad.net/qemu/+bug/1838946 - # Golang Support: https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!topic/golang-nuts/1txPOGa4aGc -ENABLE_SYSTEM_TELEMETRY = N -endif - -ifeq ($(SONIC_ENABLE_RESTAPI),y) -ENABLE_RESTAPI = y +ifeq ($(SONIC_INCLUDE_RESTAPI),y) +INCLUDE_RESTAPI = y endif ifeq ($(SONIC_ENABLE_SYNCD_RPC),y) @@ -112,18 +130,31 @@ ifeq ($(SONIC_INSTALL_DEBUG_TOOLS),y) INSTALL_DEBUG_TOOLS = y endif -ifeq ($(SONIC_ENABLE_SFLOW),y) -ENABLE_SFLOW = y +ifeq ($(SONIC_INCLUDE_SFLOW),y) +INCLUDE_SFLOW = y endif -ifeq ($(SONIC_ENABLE_NAT),y) -ENABLE_NAT = y +ifeq ($(SONIC_INCLUDE_NAT),y) +INCLUDE_NAT = y endif include $(RULES_PATH)/functions + +ifeq ($(SONIC_USE_PDDF_FRAMEWORK),y) +PDDF_SUPPORT = y +else +PDDF_SUPPORT = n +endif +export PDDF_SUPPORT + include $(RULES_PATH)/*.mk ifneq ($(CONFIGURED_PLATFORM), undefined) +ifeq ($(PDDF_SUPPORT), y) +PDDF_DIR = pddf +PLATFORM_PDDF_PATH = platform/$(PDDF_DIR) +include $(PLATFORM_PDDF_PATH)/rules.mk +endif include $(PLATFORM_PATH)/rules.mk endif @@ -159,6 +190,10 @@ ifeq ($(KERNEL_PROCURE_METHOD),) override KERNEL_PROCURE_METHOD := $(DEFAULT_KERNEL_PROCURE_METHOD) endif +ifeq ($(BUILD_LOG_TIMESTAMP),) +override BUILD_LOG_TIMESTAMP := $(DEFAULT_BUILD_LOG_TIMESTAMP) +endif + MAKEFLAGS += -j $(SONIC_BUILD_JOBS) export SONIC_CONFIG_MAKE_JOBS @@ -174,6 +209,7 @@ export FRR_USER_GID ## Dumping key config attributes associated to current building exercise ############################################################################### +ifndef SONIC_BUILD_QUIETER $(info SONiC Build System) $(info ) $(info Build Configuration) @@ -188,6 +224,7 @@ $(info "PASSWORD" : "$(PASSWORD)") $(info "ENABLE_DHCP_GRAPH_SERVICE" : "$(ENABLE_DHCP_GRAPH_SERVICE)") $(info "SHUTDOWN_BGP_ON_START" : "$(SHUTDOWN_BGP_ON_START)") $(info "ENABLE_PFCWD_ON_START" : "$(ENABLE_PFCWD_ON_START)") +$(info "SONIC_BUFFER_MODEL" : "$(SONIC_BUFFER_MODEL)") $(info "INSTALL_DEBUG_TOOLS" : "$(INSTALL_DEBUG_TOOLS)") $(info "ROUTING_STACK" : "$(SONIC_ROUTING_STACK)") ifeq ($(SONIC_ROUTING_STACK),frr) @@ -198,17 +235,32 @@ $(info "ENABLE_SYNCD_RPC" : "$(ENABLE_SYNCD_RPC)") $(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)") $(info "BUILD_TIMESTAMP" : "$(BUILD_TIMESTAMP)") +$(info "BUILD_LOG_TIMESTAMP" : "$(BUILD_LOG_TIMESTAMP)") +$(info "SONIC_IMAGE_VERSION" : "$(SONIC_IMAGE_VERSION)") $(info "BLDENV" : "$(BLDENV)") $(info "VS_PREPARE_MEM" : "$(VS_PREPARE_MEM)") -$(info "ENABLE_SFLOW" : "$(ENABLE_SFLOW)") -$(info "ENABLE_NAT" : "$(ENABLE_NAT)") +$(info "INCLUDE_MGMT_FRAMEWORK" : "$(INCLUDE_MGMT_FRAMEWORK)") +$(info "INCLUDE_ICCPD" : "$(INCLUDE_ICCPD)") +$(info "INCLUDE_SYSTEM_TELEMETRY" : "$(INCLUDE_SYSTEM_TELEMETRY)") +$(info "ENABLE_HOST_SERVICE_ON_START" : "$(ENABLE_HOST_SERVICE_ON_START)") +$(info "INCLUDE_RESTAPI" : "$(INCLUDE_RESTAPI)") +$(info "INCLUDE_SFLOW" : "$(INCLUDE_SFLOW)") +$(info "INCLUDE_NAT" : "$(INCLUDE_NAT)") +$(info "INCLUDE_KUBERNETES" : "$(INCLUDE_KUBERNETES)") +$(info "TELEMETRY_WRITABLE" : "$(TELEMETRY_WRITABLE)") +$(info "PDDF_SUPPORT" : "$(PDDF_SUPPORT)") +$(info ) +else +$(info SONiC Build System for $(CONFIGURED_PLATFORM):$(CONFIGURED_ARCH)) +endif + +# Overwrite the buildinfo in slave container +$(shell sudo scripts/prepare_slave_container_buildinfo.sh $(SLAVE_DIR) $(CONFIGURED_ARCH) $(BLDENV)) include Makefile.cache @@ -277,7 +329,7 @@ $(addprefix $(DEBS_PATH)/, $(SONIC_ONLINE_DEBS)) : $(DEBS_PATH)/% : .platform \ $(foreach deb,$* $($*_DERIVED_DEBS), \ { curl -L -f -o $(DEBS_PATH)/$(deb) $($(deb)_URL) $(LOG) || { exit 1 ; } } ; ) - + # Save the target deb into DPKG cache $(call SAVE_CACHE,$*,$@) fi @@ -311,6 +363,7 @@ SONIC_TARGET_LIST += $(addprefix $(FILES_PATH)/, $(SONIC_ONLINE_FILES)) # $(SOME_NEW_FILE)_DEPENDS = $(SOME_OTHER_DEB1) $(SOME_OTHER_DEB2) ... # SONIC_MAKE_FILES += $(SOME_NEW_FILE) $(addprefix $(FILES_PATH)/, $(SONIC_MAKE_FILES)) : $(FILES_PATH)/% : .platform $$(addsuffix -install,$$(addprefix $(DEBS_PATH)/,$$($$*_DEPENDS))) \ + $$(addprefix $(DEBS_PATH)/,$$($$*_AFTER)) \ $(call dpkg_depend,$(FILES_PATH)/%.dep) $(HEADER) @@ -326,12 +379,16 @@ $(addprefix $(FILES_PATH)/, $(SONIC_MAKE_FILES)) : $(FILES_PATH)/% : .platform $ # Build project and take package make DEST=$(shell pwd)/$(FILES_PATH) -C $($*_SRC_PATH) $(shell pwd)/$(FILES_PATH)/$* $(LOG) # Clean up - if [ -f $($*_SRC_PATH).patch/series ]; then pushd $($*_SRC_PATH) && quilt pop -a -f; popd; fi + if [ -f $($*_SRC_PATH).patch/series ]; then pushd $($*_SRC_PATH) && quilt pop -a -f; [ -d .pc ] && rm -rf .pc; popd; fi # Save the target deb into DPKG cache $(call SAVE_CACHE,$*,$@) fi + + # Uninstall unneeded build dependency + $(call UNINSTALL_DEBS,$($*_UNINSTALLS)) + $(FOOTER) SONIC_TARGET_LIST += $(addprefix $(FILES_PATH)/, $(SONIC_MAKE_FILES)) @@ -349,6 +406,7 @@ SONIC_TARGET_LIST += $(addprefix $(FILES_PATH)/, $(SONIC_MAKE_FILES)) # $(SOME_NEW_DEB)_DEPENDS = $(SOME_OTHER_DEB1) $(SOME_OTHER_DEB2) ... # SONIC_MAKE_DEBS += $(SOME_NEW_DEB) $(addprefix $(DEBS_PATH)/, $(SONIC_MAKE_DEBS)) : $(DEBS_PATH)/% : .platform $$(addsuffix -install,$$(addprefix $(DEBS_PATH)/,$$($$*_DEPENDS))) \ + $$(addprefix $(DEBS_PATH)/,$$($$*_AFTER)) \ $(call dpkg_depend,$(DEBS_PATH)/%.dep) $(HEADER) @@ -363,15 +421,19 @@ $(addprefix $(DEBS_PATH)/, $(SONIC_MAKE_DEBS)) : $(DEBS_PATH)/% : .platform $$(a # Apply series of patches if exist if [ -f $($*_SRC_PATH).patch/series ]; then pushd $($*_SRC_PATH) && QUILT_PATCHES=../$(notdir $($*_SRC_PATH)).patch quilt push -a; popd; fi # Build project and take package + $(SETUP_OVERLAYFS_FOR_DPKG_ADMINDIR) DEB_BUILD_OPTIONS="${DEB_BUILD_OPTIONS_GENERIC}" make DEST=$(shell pwd)/$(DEBS_PATH) -C $($*_SRC_PATH) $(shell pwd)/$(DEBS_PATH)/$* $(LOG) # Clean up - if [ -f $($*_SRC_PATH).patch/series ]; then pushd $($*_SRC_PATH) && quilt pop -a -f; popd; fi + if [ -f $($*_SRC_PATH).patch/series ]; then pushd $($*_SRC_PATH) && quilt pop -a -f; [ -d .pc ] && rm -rf .pc; popd; fi # Save the target deb into DPKG cache $(call SAVE_CACHE,$*,$@) fi + # Uninstall unneeded build dependency + $(call UNINSTALL_DEBS,$($*_UNINSTALLS)) + $(FOOTER) SONIC_TARGET_LIST += $(addprefix $(DEBS_PATH)/, $(SONIC_MAKE_DEBS)) @@ -383,6 +445,7 @@ SONIC_TARGET_LIST += $(addprefix $(DEBS_PATH)/, $(SONIC_MAKE_DEBS)) # $(SOME_NEW_DEB)_DEPENDS = $(SOME_OTHER_DEB1) $(SOME_OTHER_DEB2) ... # SONIC_DPKG_DEBS += $(SOME_NEW_DEB) $(addprefix $(DEBS_PATH)/, $(SONIC_DPKG_DEBS)) : $(DEBS_PATH)/% : .platform $$(addsuffix -install,$$(addprefix $(DEBS_PATH)/,$$($$*_DEPENDS))) \ + $$(addprefix $(DEBS_PATH)/,$$($$*_AFTER)) \ $(call dpkg_depend,$(DEBS_PATH)/%.dep ) $(HEADER) @@ -397,22 +460,26 @@ $(addprefix $(DEBS_PATH)/, $(SONIC_DPKG_DEBS)) : $(DEBS_PATH)/% : .platform $$(a # Apply series of patches if exist if [ -f $($*_SRC_PATH).patch/series ]; then pushd $($*_SRC_PATH) && QUILT_PATCHES=../$(notdir $($*_SRC_PATH)).patch quilt push -a; popd; fi # Build project - pushd $($*_SRC_PATH) $(LOG) - [ ! -f ./autogen.sh ] || ./autogen.sh $(LOG) + pushd $($*_SRC_PATH) $(LOG_SIMPLE) + if [ -f ./autogen.sh ]; then ./autogen.sh $(LOG); fi + $(SETUP_OVERLAYFS_FOR_DPKG_ADMINDIR) $(if $($*_DPKG_TARGET), - DEB_BUILD_OPTIONS="${DEB_BUILD_OPTIONS_GENERIC} ${$*_DEB_BUILD_OPTIONS}" dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) --as-root -T$($*_DPKG_TARGET) $(LOG), - DEB_BUILD_OPTIONS="${DEB_BUILD_OPTIONS_GENERIC} ${$*_DEB_BUILD_OPTIONS}" dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) $(LOG) + ${$*_BUILD_ENV} DEB_BUILD_OPTIONS="${DEB_BUILD_OPTIONS_GENERIC} ${$*_DEB_BUILD_OPTIONS}" dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) --as-root -T$($*_DPKG_TARGET) --admindir $$mergedir $(LOG), + ${$*_BUILD_ENV} DEB_BUILD_OPTIONS="${DEB_BUILD_OPTIONS_GENERIC} ${$*_DEB_BUILD_OPTIONS}" dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) --admindir $$mergedir $(LOG) ) - popd $(LOG) + popd $(LOG_SIMPLE) # Clean up - if [ -f $($*_SRC_PATH).patch/series ]; then pushd $($*_SRC_PATH) && quilt pop -a -f; popd; fi + if [ -f $($*_SRC_PATH).patch/series ]; then pushd $($*_SRC_PATH) && quilt pop -a -f; [ -d .pc ] && rm -rf .pc; popd; fi # Take built package(s) - mv $(addprefix $($*_SRC_PATH)/../, $* $($*_DERIVED_DEBS) $($*_EXTRA_DEBS)) $(DEBS_PATH) $(LOG) + mv -f $(addprefix $($*_SRC_PATH)/../, $* $($*_DERIVED_DEBS) $($*_EXTRA_DEBS)) $(DEBS_PATH) $(LOG) # Save the target deb into DPKG cache $(call SAVE_CACHE,$*,$@) fi + # Uninstall unneeded build dependency + $(call UNINSTALL_DEBS,$($*_UNINSTALLS)) + $(FOOTER) SONIC_TARGET_LIST += $(addprefix $(DEBS_PATH)/, $(SONIC_DPKG_DEBS)) @@ -448,7 +515,7 @@ $(addprefix $(DEBS_PATH)/, $(SONIC_EXTRA_DEBS)) : $(DEBS_PATH)/% : .platform $$( SONIC_TARGET_LIST += $(addprefix $(DEBS_PATH)/, $(SONIC_EXTRA_DEBS)) # Targets for installing debian packages prior to build one that depends on them -SONIC_INSTALL_TARGETS = $(addsuffix -install,$(addprefix $(DEBS_PATH)/, \ +SONIC_INSTALL_DEBS = $(addsuffix -install,$(addprefix $(DEBS_PATH)/, \ $(SONIC_ONLINE_DEBS) \ $(SONIC_COPY_DEBS) \ $(SONIC_MAKE_DEBS) \ @@ -456,17 +523,21 @@ SONIC_INSTALL_TARGETS = $(addsuffix -install,$(addprefix $(DEBS_PATH)/, \ $(SONIC_PYTHON_STDEB_DEBS) \ $(SONIC_DERIVED_DEBS) \ $(SONIC_EXTRA_DEBS))) -$(SONIC_INSTALL_TARGETS) : $(DEBS_PATH)/%-install : .platform $$(addsuffix -install,$$(addprefix $(DEBS_PATH)/,$$($$*_DEPENDS))) $(DEBS_PATH)/$$* +$(SONIC_INSTALL_DEBS) : $(DEBS_PATH)/%-install : .platform $$(addsuffix -install,$$(addprefix $(DEBS_PATH)/,$$($$*_DEPENDS))) $(DEBS_PATH)/$$* $(HEADER) [ -f $(DEBS_PATH)/$* ] || { echo $(DEBS_PATH)/$* does not exist $(LOG) && false $(LOG) } - # put a lock here because dpkg does not allow installing packages in parallel while true; do - if mkdir $(DEBS_PATH)/dpkg_lock &> /dev/null; then - { sudo DEBIAN_FRONTEND=noninteractive dpkg -i $(DEBS_PATH)/$* $(LOG) && rm -d $(DEBS_PATH)/dpkg_lock && break; } || { rm -d $(DEBS_PATH)/dpkg_lock && exit 1 ; } - fi + # wait for conflicted packages to be uninstalled + $(foreach deb, $($*_CONFLICT_DEBS), \ + { while dpkg -s $(firstword $(subst _, ,$(basename $(deb)))) | grep "^Version: $(word 2, $(subst _, ,$(basename $(deb))))" &> /dev/null; do echo "waiting for $(deb) to be uninstalled" $(LOG); sleep 1; done } ) + # put a lock here because dpkg does not allow installing packages in parallel + if mkdir $(DEBS_PATH)/dpkg_lock &> /dev/null; then + { sudo DEBIAN_FRONTEND=noninteractive dpkg -i $(DEBS_PATH)/$* $(LOG) && rm -d $(DEBS_PATH)/dpkg_lock && break; } || { rm -d $(DEBS_PATH)/dpkg_lock && exit 1 ; } + fi done $(FOOTER) + ############################################################################### ## Python packages ############################################################################### @@ -478,6 +549,7 @@ $(SONIC_INSTALL_TARGETS) : $(DEBS_PATH)/%-install : .platform $$(addsuffix -inst # $(SOME_NEW_DEB)_DEPENDS = $(SOME_OTHER_DEB1) $(SOME_OTHER_DEB2) ... # SONIC_PYTHON_STDEB_DEBS += $(SOME_NEW_DEB) $(addprefix $(PYTHON_DEBS_PATH)/, $(SONIC_PYTHON_STDEB_DEBS)) : $(PYTHON_DEBS_PATH)/% : .platform \ + $$(addsuffix -install,$$(addprefix $(DEBS_PATH)/,$$($$*_DEBS_DEPENDS))) \ $$(addsuffix -install,$$(addprefix $(PYTHON_DEBS_PATH)/,$$($$*_DEPENDS))) \ $$(addsuffix -install,$$(addprefix $(PYTHON_WHEELS_PATH)/,$$($$*_WHEEL_DEPENDS))) \ $(call dpkg_depend,$(PYTHON_DEBS_PATH)/%.dep) @@ -493,14 +565,14 @@ $(addprefix $(PYTHON_DEBS_PATH)/, $(SONIC_PYTHON_STDEB_DEBS)) : $(PYTHON_DEBS_PA # Apply series of patches if exist if [ -f $($*_SRC_PATH).patch/series ]; then pushd $($*_SRC_PATH) && QUILT_PATCHES=../$(notdir $($*_SRC_PATH)).patch quilt push -a; popd; fi # Build project - pushd $($*_SRC_PATH) $(LOG) + pushd $($*_SRC_PATH) $(LOG_SIMPLE) rm -rf deb_dist/* $(LOG) python setup.py --command-packages=stdeb.command bdist_deb $(LOG) - popd $(LOG) + popd $(LOG_SIMPLE) # Clean up - if [ -f $($*_SRC_PATH).patch/series ]; then pushd $($*_SRC_PATH) && quilt pop -a -f; popd; fi + if [ -f $($*_SRC_PATH).patch/series ]; then pushd $($*_SRC_PATH) && quilt pop -a -f; [ -d .pc ] && rm -rf .pc; popd; fi # Take built package(s) - mv $(addprefix $($*_SRC_PATH)/deb_dist/, $* $($*_DERIVED_DEBS)) $(PYTHON_DEBS_PATH) $(LOG) + mv -f $(addprefix $($*_SRC_PATH)/deb_dist/, $* $($*_DERIVED_DEBS)) $(PYTHON_DEBS_PATH) $(LOG) # Save the target deb into DPKG cache $(call SAVE_CACHE,$*,$@) @@ -519,8 +591,8 @@ SONIC_TARGET_LIST += $(addprefix $(PYTHON_DEBS_PATH)/, $(SONIC_PYTHON_STDEB_DEBS # $(SOME_NEW_WHL)_DEPENDS = $(SOME_OTHER_WHL1) $(SOME_OTHER_WHL2) ... # SONIC_PYTHON_WHEELS += $(SOME_NEW_WHL) $(addprefix $(PYTHON_WHEELS_PATH)/, $(SONIC_PYTHON_WHEELS)) : $(PYTHON_WHEELS_PATH)/% : .platform $$(addsuffix -install,$$(addprefix $(PYTHON_WHEELS_PATH)/,$$($$*_DEPENDS))) \ - $(call dpkg_depend,$(PYTHON_WHEELS_PATH)/%.dep) - + $(call dpkg_depend,$(PYTHON_WHEELS_PATH)/%.dep) \ + $$(addsuffix -install,$$(addprefix $(DEBS_PATH)/,$$($$*_DEBS_DEPENDS))) $(HEADER) # Load the target deb from DPKG cache @@ -529,20 +601,23 @@ $(addprefix $(PYTHON_WHEELS_PATH)/, $(SONIC_PYTHON_WHEELS)) : $(PYTHON_WHEELS_PA # Skip building the target if it is already loaded from cache if [ -z '$($*_CACHE_LOADED)' ] ; then - pushd $($*_SRC_PATH) $(LOG) + pushd $($*_SRC_PATH) $(LOG_SIMPLE) # apply series of patches if exist if [ -f ../$(notdir $($*_SRC_PATH)).patch/series ]; then QUILT_PATCHES=../$(notdir $($*_SRC_PATH)).patch quilt push -a; fi - [ "$($*_TEST)" = "n" ] || python$($*_PYTHON_VERSION) setup.py test $(LOG) + if [ ! "$($*_TEST)" = "n" ]; then python$($*_PYTHON_VERSION) setup.py test $(LOG); fi python$($*_PYTHON_VERSION) setup.py bdist_wheel $(LOG) # clean up - if [ -f ../$(notdir $($*_SRC_PATH)).patch/series ]; then quilt pop -a -f; fi - popd $(LOG) - mv $($*_SRC_PATH)/dist/$* $(PYTHON_WHEELS_PATH) $(LOG) - + if [ -f ../$(notdir $($*_SRC_PATH)).patch/series ]; then quilt pop -a -f; [ -d .pc ] && rm -rf .pc; fi + popd $(LOG_SIMPLE) + mv -f $($*_SRC_PATH)/dist/$* $(PYTHON_WHEELS_PATH) $(LOG) + # Save the target deb into DPKG cache $(call SAVE_CACHE,$*,$@) fi + # Uninstall unneeded build dependency + $(call UNINSTALL_DEBS,$($*_UNINSTALLS)) + $(FOOTER) SONIC_TARGET_LIST += $(addprefix $(PYTHON_WHEELS_PATH)/, $(SONIC_PYTHON_WHEELS)) @@ -576,6 +651,8 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_SIMPLE_DOCKER_IMAGES)) : $(TARGET_PATH)/%.g $(HEADER) # Apply series of patches if exist if [ -f $($*.gz_PATH).patch/series ]; then pushd $($*.gz_PATH) && QUILT_PATCHES=../$(notdir $($*.gz_PATH)).patch quilt push -a; popd; fi + # Prepare docker build info + scripts/prepare_docker_buildinfo.sh $* $($*.gz_PATH)/Dockerfile $(CONFIGURED_ARCH) $(TARGET_DOCKERFILE)/Dockerfile.buildinfo docker info $(LOG) docker build --squash --no-cache \ --build-arg http_proxy=$(HTTP_PROXY) \ @@ -584,32 +661,54 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_SIMPLE_DOCKER_IMAGES)) : $(TARGET_PATH)/%.g --build-arg uid=$(UID) \ --build-arg guid=$(GUID) \ --build-arg docker_container_name=$($*.gz_CONTAINER_NAME) \ - --label Tag=$(SONIC_GET_VERSION) \ + --label Tag=$(SONIC_IMAGE_VERSION) \ + -f $(TARGET_DOCKERFILE)/Dockerfile.buildinfo \ -t $* $($*.gz_PATH) $(LOG) + scripts/collect_docker_version_files.sh $* $(TARGET_PATH) docker save $* | gzip -c > $@ # Clean up - if [ -f $($*.gz_PATH).patch/series ]; then pushd $($*.gz_PATH) && quilt pop -a -f; popd; fi + if [ -f $($*.gz_PATH).patch/series ]; then pushd $($*.gz_PATH) && quilt pop -a -f; [ -d .pc ] && rm -rf .pc; popd; fi $(FOOTER) SONIC_TARGET_LIST += $(addprefix $(TARGET_PATH)/, $(SONIC_SIMPLE_DOCKER_IMAGES)) -# Build jessie docker images only in jessie slave docker, -# jessie docker images only in jessie slave docker -ifeq ($(BLDENV),) - DOCKER_IMAGES_FOR_INSTALLERS := $(sort $(foreach installer,$(SONIC_INSTALLERS),$($(installer)_DOCKERS))) +DOCKER_IMAGES_FOR_INSTALLERS := $(sort $(foreach installer,$(SONIC_INSTALLERS),$($(installer)_DOCKERS))) + +$(foreach DOCKER_IMAGE,$(SONIC_JESSIE_DOCKERS), $(eval $(DOCKER_IMAGE)_DEBS_PATH := $(JESSIE_DEBS_PATH))) +$(foreach DOCKER_IMAGE,$(SONIC_JESSIE_DOCKERS), $(eval $(DOCKER_IMAGE)_FILES_PATH := $(JESSIE_FILES_PATH))) +$(foreach DOCKER_IMAGE,$(SONIC_JESSIE_DBG_DOCKERS), $(eval $(DOCKER_IMAGE)_DEBS_PATH := $(JESSIE_DEBS_PATH))) +$(foreach DOCKER_IMAGE,$(SONIC_JESSIE_DBG_DOCKERS), $(eval $(DOCKER_IMAGE)_FILES_PATH := $(JESSIE_FILES_PATH))) +$(foreach DOCKER_IMAGE,$(SONIC_STRETCH_DOCKERS), $(eval $(DOCKER_IMAGE)_DEBS_PATH := $(STRETCH_DEBS_PATH))) +$(foreach DOCKER_IMAGE,$(SONIC_STRETCH_DOCKERS), $(eval $(DOCKER_IMAGE)_FILES_PATH := $(STRETCH_FILES_PATH))) +$(foreach DOCKER_IMAGE,$(SONIC_STRETCH_DBG_DOCKERS), $(eval $(DOCKER_IMAGE)_DEBS_PATH := $(STRETCH_DEBS_PATH))) +$(foreach DOCKER_IMAGE,$(SONIC_STRETCH_DBG_DOCKERS), $(eval $(DOCKER_IMAGE)_FILES_PATH := $(STRETCH_FILES_PATH))) + +ifeq ($(BLDENV),jessie) DOCKER_IMAGES := $(SONIC_JESSIE_DOCKERS) DOCKER_DBG_IMAGES := $(SONIC_JESSIE_DBG_DOCKERS) - SONIC_JESSIE_DOCKERS_FOR_INSTALLERS = $(filter $(SONIC_JESSIE_DOCKERS),$(DOCKER_IMAGES_FOR_INSTALLERS) $(EXTRA_JESSIE_TARGETS)) - SONIC_JESSIE_DBG_DOCKERS_FOR_INSTALLERS = $(filter $(SONIC_JESSIE_DBG_DOCKERS), $(patsubst %.gz,%-$(DBG_IMAGE_MARK).gz, $(SONIC_JESSIE_DOCKERS_FOR_INSTALLERS))) + JESSIE_DOCKER_IMAGES = $(filter $(SONIC_JESSIE_DOCKERS),$(DOCKER_IMAGES_FOR_INSTALLERS) $(EXTRA_DOCKER_TARGETS)) + JESSIE_DBG_DOCKER_IMAGES = $(filter $(SONIC_JESSIE_DBG_DOCKERS),$(DOCKER_IMAGES_FOR_INSTALLERS) $(EXTRA_DOCKER_TARGETS)) else - DOCKER_IMAGES := $(filter-out $(SONIC_JESSIE_DOCKERS), $(SONIC_DOCKER_IMAGES)) - DOCKER_DBG_IMAGES := $(filter-out $(SONIC_JESSIE_DBG_DOCKERS), $(SONIC_DOCKER_DBG_IMAGES)) +ifeq ($(BLDENV),stretch) + DOCKER_IMAGES := $(SONIC_STRETCH_DOCKERS) + DOCKER_DBG_IMAGES := $(SONIC_STRETCH_DBG_DOCKERS) + STRETCH_DOCKER_IMAGES = $(filter $(SONIC_STRETCH_DOCKERS),$(DOCKER_IMAGES_FOR_INSTALLERS) $(EXTRA_DOCKER_TARGETS)) + STRETCH_DBG_DOCKER_IMAGES = $(filter $(SONIC_STRETCH_DBG_DOCKERS),$(DOCKER_IMAGES_FOR_INSTALLERS) $(EXTRA_DOCKER_TARGETS)) +else + DOCKER_IMAGES = $(filter-out $(SONIC_JESSIE_DOCKERS) $(SONIC_STRETCH_DOCKERS),$(SONIC_DOCKER_IMAGES)) + DOCKER_DBG_IMAGES = $(filter-out $(SONIC_JESSIE_DBG_DOCKERS) $(SONIC_STRETCH_DBG_DOCKERS), $(SONIC_DOCKER_DBG_IMAGES)) +endif endif +$(foreach IMAGE,$(DOCKER_IMAGES), $(eval $(IMAGE)_DEBS_PATH := $(DEBS_PATH))) +$(foreach IMAGE,$(DOCKER_IMAGES), $(eval $(IMAGE)_FILES_PATH := $(FILES_PATH))) +$(foreach IMAGE,$(DOCKER_DBG_IMAGES), $(eval $(IMAGE)_DEBS_PATH := $(DEBS_PATH))) +$(foreach IMAGE,$(DOCKER_DBG_IMAGES), $(eval $(IMAGE)_FILES_PATH := $(FILES_PATH))) + # Targets for building docker images $(addprefix $(TARGET_PATH)/, $(DOCKER_IMAGES)) : $(TARGET_PATH)/%.gz : .platform docker-start \ - $$(addprefix $(DEBS_PATH)/,$$($$*.gz_DEPENDS)) \ - $$(addprefix $(FILES_PATH)/,$$($$*.gz_FILES)) \ + $$(addprefix $$($$*.gz_DEBS_PATH)/,$$($$*.gz_DEPENDS)) \ + $$(addprefix $$($$*.gz_FILES_PATH)/,$$($$*.gz_FILES)) \ $$(addprefix $(PYTHON_DEBS_PATH)/,$$($$*.gz_PYTHON_DEBS)) \ $$(addprefix $(PYTHON_WHEELS_PATH)/,$$($$*.gz_PYTHON_WHEELS)) \ $$(addsuffix -load,$$(addprefix $(TARGET_PATH)/,$$($$*.gz_LOAD_DOCKERS))) \ @@ -629,8 +728,8 @@ $(addprefix $(TARGET_PATH)/, $(DOCKER_IMAGES)) : $(TARGET_PATH)/%.gz : .platform mkdir -p $($*.gz_PATH)/files $(LOG) mkdir -p $($*.gz_PATH)/python-debs $(LOG) mkdir -p $($*.gz_PATH)/python-wheels $(LOG) - sudo mount --bind $(DEBS_PATH) $($*.gz_PATH)/debs $(LOG) - sudo mount --bind $(FILES_PATH) $($*.gz_PATH)/files $(LOG) + sudo mount --bind $($*.gz_DEBS_PATH) $($*.gz_PATH)/debs $(LOG) + sudo mount --bind $($*.gz_FILES_PATH) $($*.gz_PATH)/files $(LOG) sudo mount --bind $(PYTHON_DEBS_PATH) $($*.gz_PATH)/python-debs $(LOG) sudo mount --bind $(PYTHON_WHEELS_PATH) $($*.gz_PATH)/python-wheels $(LOG) # Export variables for j2. Use path for unique variable names, e.g. docker_orchagent_debs @@ -639,6 +738,11 @@ $(addprefix $(TARGET_PATH)/, $(DOCKER_IMAGES)) : $(TARGET_PATH)/%.gz : .platform $(eval export $(subst -,_,$(notdir $($*.gz_PATH)))_whls=$(shell printf "$(subst $(SPACE),\n,$(call expand,$($*.gz_PYTHON_WHEELS)))\n" | awk '!a[$$0]++')) $(eval export $(subst -,_,$(notdir $($*.gz_PATH)))_dbgs=$(shell printf "$(subst $(SPACE),\n,$(call expand,$($*.gz_DBG_PACKAGES)))\n" | awk '!a[$$0]++')) j2 $($*.gz_PATH)/Dockerfile.j2 > $($*.gz_PATH)/Dockerfile + # Prepare docker build info + PACKAGE_URL_PREFIX=$(PACKAGE_URL_PREFIX) \ + SONIC_ENFORCE_VERSIONS=$(SONIC_ENFORCE_VERSIONS) \ + TRUSTED_GPG_URLS=$(TRUSTED_GPG_URLS) \ + scripts/prepare_docker_buildinfo.sh $* $($*.gz_PATH)/Dockerfile $(CONFIGURED_ARCH) docker info $(LOG) docker build --squash --no-cache \ --build-arg http_proxy=$(HTTP_PROXY) \ @@ -649,12 +753,14 @@ $(addprefix $(TARGET_PATH)/, $(DOCKER_IMAGES)) : $(TARGET_PATH)/%.gz : .platform --build-arg docker_container_name=$($*.gz_CONTAINER_NAME) \ --build-arg frr_user_uid=$(FRR_USER_UID) \ --build-arg frr_user_gid=$(FRR_USER_GID) \ - --label Tag=$(SONIC_GET_VERSION) \ + --build-arg image_version=$(SONIC_IMAGE_VERSION) \ + --label Tag=$(SONIC_IMAGE_VERSION) \ -t $* $($*.gz_PATH) $(LOG) + scripts/collect_docker_version_files.sh $* $(TARGET_PATH) docker save $* | gzip -c > $@ # Clean up - if [ -f $($*.gz_PATH).patch/series ]; then pushd $($*.gz_PATH) && quilt pop -a -f; popd; fi - + if [ -f $($*.gz_PATH).patch/series ]; then pushd $($*.gz_PATH) && quilt pop -a -f; [ -d .pc ] && rm -rf .pc; popd; fi + # Save the target deb into DPKG cache $(call SAVE_CACHE,$*.gz,$@) fi @@ -665,7 +771,7 @@ SONIC_TARGET_LIST += $(addprefix $(TARGET_PATH)/, $(DOCKER_IMAGES)) # Targets for building docker images $(addprefix $(TARGET_PATH)/, $(DOCKER_DBG_IMAGES)) : $(TARGET_PATH)/%-$(DBG_IMAGE_MARK).gz : .platform docker-start \ - $$(addprefix $(DEBS_PATH)/,$$($$*.gz_DBG_DEPENDS)) \ + $$(addprefix $$($$*.gz_DEBS_PATH)/,$$($$*.gz_DBG_DEPENDS)) \ $$(addsuffix -load,$$(addprefix $(TARGET_PATH)/,$$*.gz)) \ $(call dpkg_depend,$(TARGET_PATH)/%-$(DBG_IMAGE_MARK).gz.dep) $(HEADER) @@ -677,24 +783,30 @@ $(addprefix $(TARGET_PATH)/, $(DOCKER_DBG_IMAGES)) : $(TARGET_PATH)/%-$(DBG_IMAG if [ -z '$($*-$(DBG_IMAGE_MARK).gz_CACHE_LOADED)' ] ; then mkdir -p $($*.gz_PATH)/debs $(LOG) - sudo mount --bind $(DEBS_PATH) $($*.gz_PATH)/debs $(LOG) + sudo mount --bind $($*.gz_DEBS_PATH) $($*.gz_PATH)/debs $(LOG) # Export variables for j2. Use path for unique variable names, e.g. docker_orchagent_debs $(eval export $(subst -,_,$(notdir $($*.gz_PATH)))_dbg_debs=$(shell printf "$(subst $(SPACE),\n,$(call expand,$($*.gz_DBG_DEPENDS),RDEPENDS))\n" | awk '!a[$$0]++')) $(eval export $(subst -,_,$(notdir $($*.gz_PATH)))_image_dbgs=$(shell printf "$(subst $(SPACE),\n,$(call expand,$($*.gz_DBG_IMAGE_PACKAGES)))\n" | awk '!a[$$0]++')) ./build_debug_docker_j2.sh $* $(subst -,_,$(notdir $($*.gz_PATH)))_dbg_debs $(subst -,_,$(notdir $($*.gz_PATH)))_image_dbgs > $($*.gz_PATH)/Dockerfile-dbg.j2 j2 $($*.gz_PATH)/Dockerfile-dbg.j2 > $($*.gz_PATH)/Dockerfile-dbg + # Prepare docker build info + PACKAGE_URL_PREFIX=$(PACKAGE_URL_PREFIX) \ + SONIC_ENFORCE_VERSIONS=$(SONIC_ENFORCE_VERSIONS) \ + TRUSTED_GPG_URLS=$(TRUSTED_GPG_URLS) \ + scripts/prepare_docker_buildinfo.sh $* $($*.gz_PATH)/Dockerfile-dbg $(CONFIGURED_ARCH) docker info $(LOG) docker build \ $(if $($*.gz_DBG_DEPENDS), --squash --no-cache, --no-cache) \ --build-arg http_proxy=$(HTTP_PROXY) \ --build-arg https_proxy=$(HTTPS_PROXY) \ --build-arg docker_container_name=$($*.gz_CONTAINER_NAME) \ - --label Tag=$(SONIC_GET_VERSION) \ + --label Tag=$(SONIC_IMAGE_VERSION) \ --file $($*.gz_PATH)/Dockerfile-dbg \ -t $*-dbg $($*.gz_PATH) $(LOG) + scripts/collect_docker_version_files.sh $*-dbg $(TARGET_PATH) docker save $*-dbg | gzip -c > $@ # Clean up - if [ -f $($*.gz_PATH).patch/series ]; then pushd $($*.gz_PATH) && quilt pop -a -f; popd; fi + if [ -f $($*.gz_PATH).patch/series ]; then pushd $($*.gz_PATH) && quilt pop -a -f; [ -d .pc ] && rm -rf .pc; popd; fi # Save the target deb into DPKG cache $(call SAVE_CACHE,$*-$(DBG_IMAGE_MARK).gz,$@) @@ -724,34 +836,50 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ build_debian.sh \ scripts/dbg_files.sh \ build_image.sh \ - $$(addsuffix -install,$$(addprefix $(STRETCH_DEBS_PATH)/,$$($$*_DEPENDS))) \ - $$(addprefix $(STRETCH_DEBS_PATH)/,$$($$*_INSTALLS)) \ - $$(addprefix $(STRETCH_DEBS_PATH)/,$$($$*_LAZY_INSTALLS)) \ - $(addprefix $(STRETCH_DEBS_PATH)/,$(INITRAMFS_TOOLS) \ + $$(addsuffix -install,$$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$$($$*_DEPENDS))) \ + $$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$$($$*_INSTALLS)) \ + $$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$$($$*_LAZY_INSTALLS)) \ + $(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(INITRAMFS_TOOLS) \ $(LINUX_KERNEL) \ $(SONIC_DEVICE_DATA) \ - $(PYTHON_CLICK) \ $(IFUPDOWN2) \ $(KDUMP_TOOLS) \ + $(NTP) \ $(LIBPAM_TACPLUS) \ $(LIBNSS_TACPLUS) \ - $(MONIT)) \ + $(MONIT) \ + $(OPENSSH_SERVER) \ + $(PYTHON_SWSSCOMMON) \ + $(PYTHON3_SWSSCOMMON) \ + $(SONIC_UTILITIES_DATA) \ + $(SONIC_HOST_SERVICES_DATA)) \ $$(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)) \ + $(if $(findstring y,$(ENABLE_ZTP)),$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(SONIC_ZTP))) \ + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_UTILITIES_PY3)) \ + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PY_COMMON_PY2)) \ + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PY_COMMON_PY3)) \ + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE_PY2)) \ + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE_PY3)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY2)) \ + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY3)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(REDIS_DUMP_LOAD_PY2)) \ - $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_API_PY2)) + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_API_PY2)) \ + $(if $(findstring y,$(PDDF_SUPPORT)),$(addprefix $(PYTHON_WHEELS_PATH)/,$(PDDF_PLATFORM_API_BASE_PY2))) \ + $(if $(findstring y,$(PDDF_SUPPORT)),$(addprefix $(PYTHON_WHEELS_PATH)/,$(PDDF_PLATFORM_API_BASE_PY3))) \ + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MODELS_PY3)) \ + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CTRMGRD)) \ + $(addprefix $(FILES_PATH)/,$($(SONIC_CTRMGRD)_FILES)) \ + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MGMT_PY3)) \ + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SYSTEM_HEALTH)) \ + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_HOST_SERVICES_PY3)) $(HEADER) # Pass initramfs and linux kernel explicitly. They are used for all platforms - export debs_path="$(STRETCH_DEBS_PATH)" + export debs_path="$(IMAGE_DISTRO_DEBS_PATH)" export files_path="$(FILES_PATH)" export python_debs_path="$(PYTHON_DEBS_PATH)" - export initramfs_tools="$(STRETCH_DEBS_PATH)/$(INITRAMFS_TOOLS)" - export linux_kernel="$(STRETCH_DEBS_PATH)/$(LINUX_KERNEL)" + export initramfs_tools="$(IMAGE_DISTRO_DEBS_PATH)/$(INITRAMFS_TOOLS)" + export linux_kernel="$(IMAGE_DISTRO_DEBS_PATH)/$(LINUX_KERNEL)" export onie_recovery_image="$(FILES_PATH)/$(ONIE_RECOVERY_IMAGE)" export kversion="$(KVERSION)" export image_type="$($*_IMAGE_TYPE)" @@ -759,20 +887,40 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export sonic_asic_platform="$(patsubst %-$(CONFIGURED_ARCH),%,$(CONFIGURED_PLATFORM))" 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 enable_nat="$(ENABLE_NAT)" + export include_system_telemetry="$(INCLUDE_SYSTEM_TELEMETRY)" + export include_restapi="$(INCLUDE_RESTAPI)" + export include_nat="$(INCLUDE_NAT)" + export include_sflow="$(INCLUDE_SFLOW)" + export include_mgmt_framework="$(INCLUDE_MGMT_FRAMEWORK)" + export include_iccpd="$(INCLUDE_ICCPD)" + export pddf_support="$(PDDF_SUPPORT)" export shutdown_bgp_on_start="$(SHUTDOWN_BGP_ON_START)" + export default_buffer_model="$(SONIC_BUFFER_MODEL)" + export include_kubernetes="$(INCLUDE_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))))" + export installer_debs="$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$($*_INSTALLS))" + export lazy_installer_debs="$(foreach deb, $($*_LAZY_INSTALLS),$(foreach device, $($(deb)_PLATFORM),$(addprefix $(device)@, $(IMAGE_DISTRO_DEBS_PATH)/$(deb))))" export installer_images="$(addprefix $(TARGET_PATH)/,$($*_DOCKERS))" - export config_engine_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE))" + export sonic_py_common_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PY_COMMON_PY2))" + export sonic_py_common_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PY_COMMON_PY3))" + export config_engine_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE_PY2))" + export config_engine_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE_PY3))" export swsssdk_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SWSSSDK_PY2))" + export swsssdk_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SWSSSDK_PY3))" export platform_common_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY2))" + export platform_common_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY3))" export redis_dump_load_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(REDIS_DUMP_LOAD_PY2))" + export redis_dump_load_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(REDIS_DUMP_LOAD_PY3))" export install_debug_image="$(INSTALL_DEBUG_TOOLS)" + export sonic_yang_models_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MODELS_PY3))" + export sonic_ctrmgmt_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CTRMGRD))" + export sonic_yang_mgmt_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MGMT_PY3))" + export multi_instance="false" + export python_swss_debs="$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$($(LIBSWSSCOMMON)_RDEPENDS))" + export python_swss_debs+=" $(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(LIBSWSSCOMMON)) $(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(PYTHON_SWSSCOMMON)) $(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(PYTHON3_SWSSCOMMON))" + export sonic_utilities_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_UTILITIES_PY3))" + export sonic_host_services_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_HOST_SERVICES_PY3))" $(foreach docker, $($*_DOCKERS),\ export docker_image="$(docker)" @@ -783,36 +931,56 @@ $(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),\ + # 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),\ $(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 + # Any service template, inside share_image directory, will be used to generate -chassis.service file. + # TODO: need better way to name the image-shared service + if [ -f files/build_templates/share_image/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 ]; then + j2 files/build_templates/share_image/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME)-chassis.service + $(if $(shell ls files/build_templates/share_image/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 2>/dev/null),\ + $(eval $(docker:-dbg.gz=.gz)_SHARE = yes) + ) 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 feature_vs_image_names="$(foreach docker, $($*_DOCKERS), $(addsuffix :, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME):$(docker:-dbg.gz=.gz)))" # 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))") ) + $(if $($(docker:-dbg.gz=.gz)_SHARE),\ + $(eval SERVICES += "$(addsuffix -chassis.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 @@ -832,12 +1000,22 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ DEBUG_SRC_ARCHIVE_FILE="$(DBG_SRC_ARCHIVE_FILE)" \ USERNAME="$(USERNAME)" \ PASSWORD="$(PASSWORD)" \ + IMAGE_TYPE=$($*_IMAGE_TYPE) \ + TARGET_PATH=$(TARGET_PATH) \ + SONIC_ENFORCE_VERSIONS=$(SONIC_ENFORCE_VERSIONS) \ + TRUSTED_GPG_URLS=$(TRUSTED_GPG_URLS) \ + PACKAGE_URL_PREFIX=$(PACKAGE_URL_PREFIX) \ ./build_debian.sh $(LOG) USERNAME="$(USERNAME)" \ PASSWORD="$(PASSWORD)" \ TARGET_MACHINE=$($*_MACHINE) \ IMAGE_TYPE=$($*_IMAGE_TYPE) \ + SONIC_ENABLE_IMAGE_SIGNATURE="$(SONIC_ENABLE_IMAGE_SIGNATURE)" \ + SIGNING_KEY="$(SIGNING_KEY)" \ + SIGNING_CERT="$(SIGNING_CERT)" \ + CA_CERT="$(CA_CERT)" \ + TARGET_PATH="$(TARGET_PATH)" \ ./build_image.sh $(LOG) $(foreach docker, $($*_DOCKERS), \ @@ -909,12 +1087,11 @@ clean :: .platform clean-logs $$(SONIC_CLEAN_DEBS) $$(SONIC_CLEAN_FILES) $$(SONI all : .platform $$(addprefix $(TARGET_PATH)/,$$(SONIC_ALL)) -stretch : $$(addprefix $(DEBS_PATH)/,$$(SONIC_STRETCH_DEBS)) \ - $$(addprefix $(FILES_PATH)/,$$(SONIC_STRETCH_FILES)) \ - $$(addprefix $(TARGET_PATH)/,$$(SONIC_STRETCH_DOCKERS_FOR_INSTALLERS)) \ - $$(addprefix $(TARGET_PATH)/,$$(SONIC_STRETCH_DBG_DOCKERS_FOR_INSTALLERS)) +stretch : $$(addprefix $(TARGET_PATH)/,$$(STRETCH_DOCKER_IMAGES)) \ + $$(addprefix $(TARGET_PATH)/,$$(STRETCH_DBG_DOCKER_IMAGES)) -jessie : $$(addprefix $(TARGET_PATH)/,$$(SONIC_JESSIE_DOCKERS_FOR_INSTALLERS)) +jessie : $$(addprefix $(TARGET_PATH)/,$$(JESSIE_DOCKER_IMAGES)) \ + $$(addprefix $(TARGET_PATH)/,$$(JESSIE_DBG_DOCKER_IMAGES)) ############################################################################### ## Standard targets @@ -922,4 +1099,4 @@ jessie : $$(addprefix $(TARGET_PATH)/,$$(SONIC_JESSIE_DOCKERS_FOR_INSTALLERS)) .PHONY : $(SONIC_CLEAN_DEBS) $(SONIC_CLEAN_FILES) $(SONIC_CLEAN_TARGETS) $(SONIC_CLEAN_STDEB_DEBS) $(SONIC_CLEAN_WHEELS) $(SONIC_PHONY_TARGETS) clean distclean configure -.INTERMEDIATE : $(SONIC_INSTALL_TARGETS) $(SONIC_INSTALL_WHEELS) $(DOCKER_LOAD_TARGETS) docker-start .platform +.INTERMEDIATE : $(SONIC_INSTALL_DEBS) $(SONIC_INSTALL_WHEELS) $(DOCKER_LOAD_TARGETS) docker-start .platform diff --git a/sonic-slave-buster/Dockerfile.j2 b/sonic-slave-buster/Dockerfile.j2 new file mode 100644 index 000000000000..ed541ec5356a --- /dev/null +++ b/sonic-slave-buster/Dockerfile.j2 @@ -0,0 +1,516 @@ +{%- if CONFIGURED_ARCH == "armhf" %} +FROM multiarch/qemu-user-static:x86_64-arm-5.0.0-2 as qemu +FROM multiarch/debian-debootstrap:armhf-buster +COPY --from=qemu /usr/bin/qemu-arm-static /usr/bin +{%- elif CONFIGURED_ARCH == "arm64" %} +FROM multiarch/debian-debootstrap:arm64-buster +{%- else -%} +FROM debian:buster +{%- endif %} + +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/ buster main contrib non-free" >> /etc/apt/sources.list && \ + echo "deb-src [arch=amd64] http://debian-archive.trafficmanager.net/debian/ buster main contrib non-free" >> /etc/apt/sources.list && \ + echo "deb [arch=amd64] http://debian-archive.trafficmanager.net/debian-security/ buster/updates main contrib non-free" >> /etc/apt/sources.list && \ + echo "deb-src [arch=amd64] http://debian-archive.trafficmanager.net/debian-security/ buster/updates main contrib non-free" >> /etc/apt/sources.list && \ + echo "deb [arch=amd64] http://debian-archive.trafficmanager.net/debian buster-backports main" >> /etc/apt/sources.list && \ + echo "deb [arch=amd64] http://packages.trafficmanager.net/debian/debian buster main contrib non-free" >> /etc/apt/sources.list && \ + echo "deb [arch=amd64] http://packages.trafficmanager.net/debian/debian buster-updates main contrib non-free" >> /etc/apt/sources.list + +{%- if CONFIGURED_ARCH == "armhf" %} +RUN echo "deb [arch=armhf] http://deb.debian.org/debian buster main contrib non-free" > /etc/apt/sources.list && \ + echo "deb-src [arch=armhf] http://deb.debian.org/debian buster main contrib non-free" >> /etc/apt/sources.list && \ + echo "deb [arch=armhf] http://deb.debian.org/debian buster-updates main contrib non-free" >> /etc/apt/sources.list && \ + echo "deb-src [arch=armhf] http://deb.debian.org/debian buster-updates main contrib non-free" >> /etc/apt/sources.list && \ + echo "deb [arch=armhf] http://security.debian.org buster/updates main contrib non-free" >> /etc/apt/sources.list && \ + echo "deb-src [arch=armhf] http://security.debian.org buster/updates main contrib non-free" >> /etc/apt/sources.list && \ + echo 'deb [arch=armhf] http://ftp.debian.org/debian buster-backports main' >> /etc/apt/sources.list && \ + echo "deb [arch=armhf] http://packages.trafficmanager.net/debian/debian buster main contrib non-free" >> /etc/apt/sources.list && \ + echo "deb [arch=armhf] http://packages.trafficmanager.net/debian/debian buster-updates main contrib non-free" >> /etc/apt/sources.list +{%- elif CONFIGURED_ARCH == "arm64" %} +RUN echo "deb [arch=arm64] http://deb.debian.org/debian buster main contrib non-free" > /etc/apt/sources.list && \ + echo "deb-src [arch=arm64] http://deb.debian.org/debian buster main contrib non-free" >> /etc/apt/sources.list && \ + echo "deb [arch=arm64] http://deb.debian.org/debian buster-updates main contrib non-free" >> /etc/apt/sources.list && \ + echo "deb-src [arch=arm64] http://deb.debian.org/debian buster-updates main contrib non-free" >> /etc/apt/sources.list && \ + echo "deb [arch=arm64] http://security.debian.org buster/updates main contrib non-free" >> /etc/apt/sources.list && \ + echo "deb-src [arch=arm64] http://security.debian.org buster/updates main contrib non-free" >> /etc/apt/sources.list && \ + echo 'deb [arch=arm64] http://ftp.debian.org/debian buster-backports main' >> /etc/apt/sources.list && \ + echo "deb [arch=arm64] http://packages.trafficmanager.net/debian/debian buster main contrib non-free" >> /etc/apt/sources.list && \ + echo "deb [arch=arm64] http://packages.trafficmanager.net/debian/debian buster-updates main contrib non-free" >> /etc/apt/sources.list +{%- endif %} + +## Make apt-get non-interactive +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get install -y \ + apt-utils \ + default-jre-headless \ + openssh-server \ + curl \ + wget \ + unzip \ + git \ + build-essential \ + libtool \ + lintian \ + sudo \ + dh-make \ + dh-exec \ + kmod \ + libtinyxml2-6a \ + libtinyxml2-dev \ + python \ + python-pip \ + python3 \ + python3-pip \ + libncurses5-dev \ + texinfo \ + dh-autoreconf \ + doxygen \ + devscripts \ + git-buildpackage \ + perl-modules \ + libswitch-perl \ + dh-systemd \ + libzmq5 \ + libzmq3-dev \ +# For quagga build + libreadline-dev \ + texlive-latex-base \ + texlive-generic-recommended \ + texlive-fonts-recommended \ + libpam0g-dev \ + libpam-dev \ + libcap-dev \ + imagemagick \ + ghostscript \ + groff \ + libpcre3-dev \ + gawk \ + chrpath \ +# For frr build + libc-ares-dev \ + libsnmp-dev \ + libjson-c3 \ + libjson-c-dev \ + libsystemd-dev \ + python-ipaddr \ + libcmocka-dev \ + python3-all-dev \ + python3-all-dbg \ + install-info \ + logrotate \ +# For libnl3 (local) build + cdbs \ +# For SAI meta build + libxml-simple-perl \ + graphviz \ + aspell \ +# For linux build + bc \ + fakeroot \ + build-essential \ + devscripts \ + quilt \ + stgit \ +# For platform-modules build + module-assistant \ +# For thrift build\ + gem2deb \ + libevent-dev \ + libglib2.0-dev \ + libqt4-dev \ + python-all-dev \ + python-twisted \ + phpunit \ + libbit-vector-perl \ + openjdk-11-jdk \ + javahelper \ + maven-debian-helper \ + ant \ + libhttpclient-java \ + libslf4j-java \ + libservlet3.1-java \ + qt5-default \ + pkg-php-tools \ +# For mellanox sdk build + libpcre3 \ + libpcre3-dev \ + byacc \ + flex \ + libglib2.0-dev \ + bison \ + expat \ + libexpat1-dev \ + dpatch \ + libdb-dev \ + iptables-dev \ + ctags \ +# For mellanox sai build + libtool-bin \ + libxml2-dev \ +# For BFN sdk build + libusb-1.0-0-dev \ + libcurl3-nss-dev \ + libunwind8-dev \ + telnet \ + libc-ares2 \ + libgoogle-perftools4 \ +# For build image + cpio \ + squashfs-tools \ + zip \ +# For broadcom sdk build +{%- if CONFIGURED_ARCH == "amd64" %} + linux-compiler-gcc-8-x86 \ +{%- endif %} +{%- if CONFIGURED_ARCH == "armhf" %} + linux-compiler-gcc-8-arm \ +{%- endif %} + linux-kbuild-4.19 \ +# teamd build + libdaemon-dev \ + libdbus-1-dev \ + libjansson-dev \ +# For cavium sdk build + libpcap-dev \ + dnsutils \ + libusb-dev \ +# For debian image reconfiguration + augeas-tools \ +# For p4 build + libyaml-dev \ + libevent-dev \ + libjudy-dev \ + libedit-dev \ + libnanomsg-dev \ + python-stdeb \ +# For redis build + libjemalloc-dev \ + liblua5.1-0-dev \ + lua-bitop-dev \ + lua-cjson-dev \ +# For mft kernel module build + dkms \ +# For Jenkins static analysis, unit testing and code coverage + cppcheck \ + clang \ + pylint \ + python-pytest \ + python3-pytest \ + gcovr \ + python-pytest-cov \ + python3-pytest-cov \ + python-parse \ +# For snmpd + default-libmysqlclient-dev \ + libssl-dev \ + libperl-dev \ + libpci-dev \ + libpci3 \ + libsensors5 \ + libsensors4-dev \ + libwrap0-dev \ +# For lldpd + debhelper \ + autotools-dev \ + libbsd-dev \ + pkg-config \ + check \ +# For mpdecimal + docutils-common \ + libjs-sphinxdoc \ + libjs-underscore \ + python-docutils \ + python-jinja2 \ + python-markupsafe \ + python-pygments \ + python-roman \ + python-sphinx \ + sphinx-common \ + python3-sphinx \ +# For sonic config engine testing + python-dev \ +{%- if CONFIGURED_ARCH == "armhf" or CONFIGURED_ARCH == "arm64" %} + libxslt-dev \ +{%- endif %} +# For lockfile + procmail \ +# For gtest + libgtest-dev \ + cmake \ +# For pam_tacplus build + autoconf-archive \ +# For iproute2 + cm-super-minimal \ + libatm1-dev \ + libelf-dev \ + libmnl-dev \ + libselinux1-dev \ + linuxdoc-tools \ + lynx \ + texlive-latex-extra \ + texlive-latex-recommended \ + iproute2 \ +# For bash + texi2html \ +# For initramfs + shellcheck \ + bash-completion \ +{%- if CONFIGURED_ARCH == "amd64" %} +# For sonic vs image build + dosfstools \ + qemu-kvm \ + libvirt-clients \ +{%- endif %} +# For ntp + autogen \ + libopts25-dev \ + pps-tools \ + dh-apparmor \ +# For lm-sensors + librrd8 \ + librrd-dev \ + rrdtool \ +# For smartmontools 6.6-1 + automake1.11 \ + libselinux1-dev \ +# For kdump-tools + liblzo2-dev \ +# For iptables + libnetfilter-conntrack-dev \ + libnftnl-dev \ +# For SAI3.7 + protobuf-compiler \ + libprotobuf-dev \ + xxd \ +# For DHCP Monitor tool + libexplain-dev \ + libevent-dev \ +# For libyang + swig \ +# For build dtb + device-tree-compiler \ +# For sonic-mgmt-framework + autoconf \ + m4 \ + libxml2-utils \ + xsltproc \ + python-lxml \ + libexpat1-dev \ +# For WPA supplication + qtbase5-dev \ + aspell-en \ + libhiredis-dev \ + libnl-3-dev \ + swig3.0 \ + libpython2.7-dev \ + libssl-dev \ + dbus \ + libdbus-1-dev \ + libdbus-glib-1-2 \ + libdbus-glib-1-dev \ + libreadline-dev \ + libncurses5-dev \ + libpcsclite-dev \ + docbook-to-man \ + docbook-utils \ +# For kdump-tools + libbz2-dev \ +# For linkmgrd + libboost1.71-dev \ + libboost-program-options1.71-dev \ + libboost-system1.71-dev \ + libboost-thread1.71-dev \ + libboost-atomic1.71-dev \ + libboost-chrono1.71-dev \ + libboost-container1.71-dev \ + libboost-context1.71-dev \ + libboost-contract1.71-dev \ + libboost-coroutine1.71-dev \ + libboost-date-time1.71-dev \ + libboost-fiber1.71-dev \ + libboost-filesystem1.71-dev \ + libboost-graph-parallel1.71-dev \ + libboost-log1.71-dev \ + libboost-regex1.71-dev \ + googletest \ + libgtest-dev \ + libgcc-8-dev \ +# For sonic-host-services build + libcairo2-dev \ + libdbus-1-dev \ + libgirepository1.0-dev \ + libsystemd-dev \ + pkg-config + +# Build fix for ARMHF buster libsairedis +{%- if CONFIGURED_ARCH == "armhf" %} + # Install doxygen build dependency packages + RUN apt install -y libxapian-dev yui-compressor libclang-3.9-dev texlive-extra-utils \ + texlive-font-utils rdfind llvm-6.0-dev libclang-6.0-dev sassc + + # Update doxygen with 64bit file offset patch + RUN dget -u http://deb.debian.org/debian/pool/main/d/doxygen/doxygen_1.8.13-10.dsc && \ + cd doxygen-1.8.13 && \ + sed -i '56 a add_definitions(-D_FILE_OFFSET_BITS=64)' CMakeLists.txt && \ + DEB_BUILD_OPTIONS=nocheck dpkg-buildpackage -us -uc -b && \ + cd .. && \ + dpkg -i ./doxygen_1.8.13-10_armhf.deb && \ + rm -fr doxygen* + + # Aspell is unable to locate the language dictionaries. + # Re-installing aspell-en dictionary to fix it. + RUN apt-get install --reinstall -y aspell-en +{%- endif %} + +## 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 linux build +RUN apt-get -y build-dep linux + +# For gobgp and telemetry build +RUN export VERSION=1.14.2 \ +{%- if CONFIGURED_ARCH == "armhf" %} + && wget https://storage.googleapis.com/golang/go$VERSION.linux-armv6l.tar.gz \ + && tar -C /usr/local -xzf go$VERSION.linux-armv6l.tar.gz \ +{%- elif CONFIGURED_ARCH == "arm64" %} + && wget https://storage.googleapis.com/golang/go$VERSION.linux-arm64.tar.gz \ + && tar -C /usr/local -xzf go$VERSION.linux-arm64.tar.gz \ +{%- else %} + && wget https://storage.googleapis.com/golang/go$VERSION.linux-amd64.tar.gz \ + && tar -C /usr/local -xzf go$VERSION.linux-amd64.tar.gz \ +{%- endif %} + && echo 'export GOROOT=/usr/local/go' >> /etc/bash.bashrc \ + && echo 'export PATH=$PATH:$GOROOT/bin' >> /etc/bash.bashrc \ + && rm go$VERSION.linux-*.tar.gz + +RUN pip3 install --upgrade pip +RUN pip2 install --upgrade 'pip<21' +RUN apt-get purge -y python-pip python3-pip python3-yaml + +# For building Python packages +RUN pip2 install setuptools==40.8.0 +RUN pip2 install wheel==0.35.1 +RUN pip3 install setuptools==49.6.00 +RUN pip3 install wheel==0.35.1 + +# For building sonic-utilities +RUN pip2 install fastentrypoints +RUN pip3 install fastentrypoints + +# For running Python unit tests +RUN pip2 install pytest-runner==4.4 +RUN pip3 install pytest-runner==5.2 +RUN pip2 install mockredispy==2.9.3 +RUN pip3 install mockredispy==2.9.3 + +# For Python 2 unit tests, we need 'mock'. The last version of 'mock' +# which supports Python 2 is 3.0.5. In Python 3, 'mock' is part of 'unittest' +# in the standard library +RUN pip2 install mock==3.0.5 + +# For p4 build +RUN pip2 install \ + ctypesgen==1.0.2 \ + crc16 + +# For sonic config engine testing +# Install pyangbind here, outside sonic-config-engine dependencies, as pyangbind causes enum34 to be installed. +# enum34 causes Python 're' package to not work properly as it redefines an incompatible enum.py module +# https://github.com/robshakir/pyangbind/issues/232 +RUN pip3 install pyangbind==0.8.1 +RUN pip3 uninstall -y enum34 + +# For templating +RUN pip2 install j2cli==0.3.10 + +# For sonic-mgmt-framework +RUN pip2 install "PyYAML==5.4.1" +RUN pip3 install "PyYAML==5.4.1" +RUN pip2 install "lxml==4.6.2" +RUN pip3 install "lxml==4.6.2" + +# For sonic-platform-common testing +RUN pip3 install redis + +# For vs image build +RUN pip2 install pexpect==4.6.0 +RUN pip3 install pexpect==4.8.0 + +# For sonic-swss-common testing +RUN pip2 install Pympler==0.8 +RUN pip3 install Pympler==0.8 + +# For sonic_yang_model build +RUN pip2 install pyang==2.1.1 +RUN pip3 install pyang==2.1.1 + +# For mgmt-framework build +RUN pip2 install mmh3==2.5.1 +RUN pip3 install mmh3==2.5.1 + +RUN apt-get install -y xsltproc + +# Install dependencies for isc-dhcp-relay build +RUN apt-get -y build-dep isc-dhcp + +# Install vim +RUN apt-get install -y vim + +# Install rsyslog +RUN apt-get install -y rsyslog + +RUN cd /usr/src/gtest && cmake . && make -C /usr/src/gtest + +RUN mkdir /var/run/sshd +EXPOSE 22 + +# Install depot-tools (for git-retry) +RUN git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git /usr/share/depot_tools +ENV PATH /usr/share/depot_tools:$PATH + +# Install docker engine 17.03.2~ce-0 inside docker and enable experimental feature +RUN apt-get update +RUN apt-get install -y \ + apt-transport-https \ + ca-certificates \ + curl \ + gnupg2 \ + software-properties-common +{%- if CONFIGURED_ARCH == "armhf" %} + RUN update-ca-certificates --fresh +{%- endif %} +RUN curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add - +RUN add-apt-repository \ + "deb [arch={{ CONFIGURED_ARCH }}] https://download.docker.com/linux/debian \ + $(lsb_release -cs) \ + stable" +RUN apt-get update +RUN apt-get install -y docker-ce=5:18.09.5~3-0~debian-buster docker-ce-cli=5:18.09.5~3-0~debian-buster +RUN echo "DOCKER_OPTS=\"--experimental --storage-driver=vfs\"" >> /etc/default/docker +RUN update-alternatives --set iptables /usr/sbin/iptables-legacy + +# Install m2crypto package, needed by SWI tools +RUN pip2 install m2crypto==0.36.0 + +# Install swi tools +RUN pip3 install git+https://github.com/aristanetworks/swi-tools.git@bead66bf261770237f7dd21ace3774ba04a017e9 + +{% if CONFIGURED_ARCH != "amd64" -%} +# Install node.js for azure pipeline +RUN curl -sL https://deb.nodesource.com/setup_14.x | bash - +RUN apt-get install -y nodejs + +# Tell azure pipeline to use node.js in the docker +LABEL "com.azure.dev.pipelines.agent.handler.node.path"="/usr/bin/node" +{% endif -%} diff --git a/sonic-slave-buster/Dockerfile.user.j2 b/sonic-slave-buster/Dockerfile.user.j2 new file mode 100644 index 000000000000..a1181524bd91 --- /dev/null +++ b/sonic-slave-buster/Dockerfile.user.j2 @@ -0,0 +1,34 @@ +ARG slave_base_tag_ref=latest +{%- if CONFIGURED_ARCH == "amd64" %} +FROM sonic-slave-buster:${slave_base_tag_ref} +{%- else %} +FROM sonic-slave-buster-{{ CONFIGURED_ARCH }}:${slave_base_tag_ref} +{%- endif %} + +# Add user +ARG user +ARG uid +ARG guid +ARG hostname + +ENV BUILD_HOSTNAME $hostname +ENV USER $user + +RUN groupadd -f -r -g $guid g$user + +RUN useradd $user -l -u $uid -g $guid -d /var/$user -m -s /bin/bash + +RUN gpasswd -a $user docker + +# Config git for stg +RUN su $user -c "git config --global user.name $user" +RUN su $user -c "git config --global user.email $user@contoso.com" + +COPY sonic-jenkins-id_rsa.pub /var/$user/.ssh/authorized_keys2 +RUN chown $user /var/$user/.ssh -R +RUN chmod go= /var/$user/.ssh -R + +# Add user to sudoers +RUN echo "$user ALL=(ALL) NOPASSWD:ALL" >>/etc/sudoers + +USER $user diff --git a/sonic-slave-buster/no-check-valid-until b/sonic-slave-buster/no-check-valid-until new file mode 100644 index 000000000000..c7c25d017f7f --- /dev/null +++ b/sonic-slave-buster/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-buster/sonic-jenkins-id_rsa.pub b/sonic-slave-buster/sonic-jenkins-id_rsa.pub new file mode 100644 index 000000000000..2a19c9e70d3c --- /dev/null +++ b/sonic-slave-buster/sonic-jenkins-id_rsa.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC769BQUJVeSIOyPsN4/Vo8xTqXQ6RI7ysVyCw/ABP3FIxf+fxmtm8t/Nbp9hq0uLHOjCw8UQbJ+XltsThFWJfH6RJY5NbfvwG7nUDjfjjp+SGEIHaVgIlpiuqiPbZ6QMjZ8Q0Sgi5p5ts1xe/4TFThwOJBHmhwydD5nk3BH7P3DDwlOCov5gjM40uMZJkketlO83zGG+25zu7O0hfDVt1vyK9bNWAhhPmGc79zdetfeFCxjimsff2m31B1KuVXiT5PDB1w+BSrUK6nNzJubnYCRgjg4prVTjA50EhlT2P7EoJAbW3TnTq8vUDkcstsGe/HZpfIB1VHBX97u4fAfGJZ root@acs-jenkins diff --git a/sonic-slave-jessie/Dockerfile.j2 b/sonic-slave-jessie/Dockerfile.j2 index 0e59310fc30c..f103dfb789b9 100644 --- a/sonic-slave-jessie/Dockerfile.j2 +++ b/sonic-slave-jessie/Dockerfile.j2 @@ -176,24 +176,6 @@ RUN apt-get update && apt-get install -y \ libjemalloc-dev \ # For mft kernel module build dkms \ -# For python3.5 build - sharutils \ - libncursesw5-dev \ - libbz2-dev \ - liblzma-dev \ - libgdbm-dev \ - tk-dev \ - blt-dev \ - libmpdec-dev \ - libbluetooth-dev \ - locales \ - libsqlite3-dev \ - libgpm2 \ - time \ - net-tools \ - xvfb \ - python-sphinx \ - python3-sphinx \ # For Jenkins static analysis, unit testing and code coverage cppcheck \ clang \ @@ -246,16 +228,6 @@ RUN apt-get update && apt-get install -y \ lynx \ texlive-latex-extra \ texlive-latex-recommended \ -# For python-click build - python-sphinx \ - python-docutils \ - python3-all \ - python3-setuptools \ - python3-sphinx \ - python3-docutils \ - python3-requests \ - python3-pytest \ - python3-colorama \ # For bash texi2html \ # For initramfs @@ -278,7 +250,7 @@ RUN apt-get -y build-dep linux {%- endif %} # For gobgp and telemetry build -RUN export VERSION=1.11.5 \ +RUN export VERSION=1.14.2 \ {%- if CONFIGURED_ARCH == "armhf" %} && wget https://storage.googleapis.com/golang/go$VERSION.linux-armv6l.tar.gz \ && tar -C /usr/local -xzf go$VERSION.linux-armv6l.tar.gz \ @@ -310,12 +282,6 @@ RUN pip install --force-reinstall --upgrade "jinja2>=2.10" # For templating (requiring jinja2) RUN pip install j2cli==0.3.10 -# For sonic utilities testing -RUN pip install click-default-group click natsort tabulate netifaces==0.10.7 fastentrypoints - -# For supervisor build -RUN pip install meld3 mock - # For vs image build RUN pip install pexpect==4.6.0 @@ -324,6 +290,9 @@ RUN pip install mockredispy==2.9.3 RUN pip install pytest-runner==4.4 RUN pip install setuptools==40.8.0 +# For sonic-swss-common testing +RUN pip install Pympler==0.8 + # Install dependencies for isc-dhcp-relay build RUN apt-get -y build-dep isc-dhcp @@ -369,3 +338,9 @@ RUN echo "DOCKER_OPTS=\"--experimental --storage-driver=vfs\"" >> /etc/default/d RUN echo "deb [arch={{ CONFIGURED_ARCH }}] http://archive.debian.org/debian jessie-backports main" >> /etc/apt/sources.list RUN apt-get -o Acquire::Check-Valid-Until=false update RUN apt-get -y -o Acquire::Check-Valid-Until=false install ca-certificates-java=20161107~bpo8+1 openjdk-8-jdk + +# Install m2crypto package, needed by SWI tools +RUN pip install m2crypto==0.36.0 + +# Install swi tools +RUN python -m pip install git+https://github.com/aristanetworks/swi-tools.git@d51761ec0bb93c73039233f3c01ed48235ffad00 diff --git a/sonic-slave-jessie/Dockerfile.user b/sonic-slave-jessie/Dockerfile.user deleted file mode 100644 index 37dd7256c4e5..000000000000 --- a/sonic-slave-jessie/Dockerfile.user +++ /dev/null @@ -1,30 +0,0 @@ -ARG slave_base_tag_ref=latest -FROM sonic-slave-jessie:${slave_base_tag_ref} - -# Add user -ARG user -ARG uid -ARG guid -ARG hostname - -ENV BUILD_HOSTNAME $hostname -ENV USER $user - -RUN groupadd -f -r -g $guid g$user - -RUN useradd $user -l -u $uid -g $guid -d /var/$user -m -s /bin/bash - -RUN gpasswd -a $user docker - -# Config git for stg -RUN su $user -c "git config --global user.name $user" -RUN su $user -c "git config --global user.email $user@contoso.com" - -COPY sonic-jenkins-id_rsa.pub /var/$user/.ssh/authorized_keys2 -RUN chown $user /var/$user/.ssh -R -RUN chmod go= /var/$user/.ssh -R - -# Add user to sudoers -RUN echo "$user ALL=(ALL) NOPASSWD:ALL" >>/etc/sudoers - -USER $user diff --git a/sonic-slave-jessie/Dockerfile.user.j2 b/sonic-slave-jessie/Dockerfile.user.j2 new file mode 100644 index 000000000000..4f9ed9da659b --- /dev/null +++ b/sonic-slave-jessie/Dockerfile.user.j2 @@ -0,0 +1,34 @@ +ARG slave_base_tag_ref=latest +{%- if CONFIGURED_ARCH == "amd64" %} +FROM sonic-slave-jessie:${slave_base_tag_ref} +{%- else %} +FROM sonic-slave-jessie-{{ CONFIGURED_ARCH }}:${slave_base_tag_ref} +{%- endif %} + +# Add user +ARG user +ARG uid +ARG guid +ARG hostname + +ENV BUILD_HOSTNAME $hostname +ENV USER $user + +RUN groupadd -f -r -g $guid g$user + +RUN useradd $user -l -u $uid -g $guid -d /var/$user -m -s /bin/bash + +RUN gpasswd -a $user docker + +# Config git for stg +RUN su $user -c "git config --global user.name $user" +RUN su $user -c "git config --global user.email $user@contoso.com" + +COPY sonic-jenkins-id_rsa.pub /var/$user/.ssh/authorized_keys2 +RUN chown $user /var/$user/.ssh -R +RUN chmod go= /var/$user/.ssh -R + +# Add user to sudoers +RUN echo "$user ALL=(ALL) NOPASSWD:ALL" >>/etc/sudoers + +USER $user diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index 4d34e8e81a75..103a9cd77831 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -14,7 +14,10 @@ RUN echo "deb [arch=amd64] http://debian-archive.trafficmanager.net/debian/ stre 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 && \ echo "deb-src [arch=amd64] http://debian-archive.trafficmanager.net/debian-security/ stretch/updates main contrib non-free" >> /etc/apt/sources.list && \ - echo "deb [arch=amd64] http://debian-archive.trafficmanager.net/debian stretch-backports main" >> /etc/apt/sources.list + echo "deb [arch=amd64] http://debian-archive.trafficmanager.net/debian stretch-backports main" >> /etc/apt/sources.list && \ + echo "deb [arch=amd64] http://packages.trafficmanager.net/debian/debian stretch main contrib non-free" >> /etc/apt/sources.list && \ + echo "deb [arch=amd64] http://packages.trafficmanager.net/debian/debian stretch-updates main contrib non-free" >> /etc/apt/sources.list && \ + echo "deb [arch=amd64] http://packages.microsoft.com/debian/9/prod stretch main" >> /etc/apt/sources.list {%- if CONFIGURED_ARCH == "armhf" %} RUN echo "deb [arch=armhf] http://deb.debian.org/debian stretch main contrib non-free" > /etc/apt/sources.list && \ @@ -23,7 +26,9 @@ RUN echo "deb [arch=armhf] http://deb.debian.org/debian stretch main contrib non echo "deb-src [arch=armhf] http://deb.debian.org/debian stretch-updates main contrib non-free" >> /etc/apt/sources.list && \ echo "deb [arch=armhf] http://security.debian.org stretch/updates main contrib non-free" >> /etc/apt/sources.list && \ echo "deb-src [arch=armhf] http://security.debian.org stretch/updates main contrib non-free" >> /etc/apt/sources.list && \ - echo 'deb [arch=armhf] http://ftp.debian.org/debian stretch-backports main' >> /etc/apt/sources.list + echo 'deb [arch=armhf] http://ftp.debian.org/debian stretch-backports main' >> /etc/apt/sources.list && \ + echo "deb [arch=armhf] http://packages.trafficmanager.net/debian/debian stretch main contrib non-free" >> /etc/apt/sources.list && \ + echo "deb [arch=armhf] http://packages.trafficmanager.net/debian/debian stretch-updates main contrib non-free" >> /etc/apt/sources.list {%- elif CONFIGURED_ARCH == "arm64" %} RUN echo "deb [arch=arm64] http://deb.debian.org/debian stretch main contrib non-free" > /etc/apt/sources.list && \ echo "deb-src [arch=arm64] http://deb.debian.org/debian stretch main contrib non-free" >> /etc/apt/sources.list && \ @@ -31,7 +36,9 @@ RUN echo "deb [arch=arm64] http://deb.debian.org/debian stretch main contrib non echo "deb-src [arch=arm64] http://deb.debian.org/debian stretch-updates main contrib non-free" >> /etc/apt/sources.list && \ echo "deb [arch=arm64] http://security.debian.org stretch/updates main contrib non-free" >> /etc/apt/sources.list && \ echo "deb-src [arch=arm64] http://security.debian.org stretch/updates main contrib non-free" >> /etc/apt/sources.list && \ - echo 'deb [arch=arm64] http://ftp.debian.org/debian stretch-backports main' >> /etc/apt/sources.list + echo 'deb [arch=arm64] http://ftp.debian.org/debian stretch-backports main' >> /etc/apt/sources.list && \ + echo "deb [arch=arm64] http://packages.trafficmanager.net/debian/debian stretch main contrib non-free" >> /etc/apt/sources.list && \ + echo "deb [arch=arm64] http://packages.trafficmanager.net/debian/debian stretch-updates main contrib non-free" >> /etc/apt/sources.list {%- endif %} ## Make apt-get non-interactive @@ -57,16 +64,18 @@ RUN apt-get update && apt-get install -y \ libtinyxml2-dev \ python \ python-pip \ + python3-pip \ libncurses5-dev \ texinfo \ dh-autoreconf \ - python3-pip \ doxygen \ devscripts \ git-buildpackage \ perl-modules \ libswitch-perl \ dh-systemd \ + libzmq5 \ + libzmq3-dev \ # For quagga build libreadline-dev \ texlive-latex-base \ @@ -187,24 +196,6 @@ RUN apt-get update && apt-get install -y \ lua-cjson-dev \ # For mft kernel module build dkms \ -# For python3.5 build - sharutils \ - libncursesw5-dev \ - libbz2-dev \ - liblzma-dev \ - libgdbm-dev \ - tk-dev \ - blt-dev \ - libmpdec-dev \ - libbluetooth-dev \ - locales \ - libsqlite3-dev \ - libgpm2 \ - time \ - net-tools \ - xvfb \ - python-sphinx \ - python3-sphinx \ # For Jenkins static analysis, unit testing and code coverage cppcheck \ clang \ @@ -241,17 +232,12 @@ RUN apt-get update && apt-get install -y \ sphinx-common \ python3-sphinx \ # For sonic config engine testing - python-lxml \ - python-jinja2 \ - python-netaddr \ - python-ipaddr \ - python-yaml \ - python3-yaml \ + python-dev \ +{%- if CONFIGURED_ARCH == "armhf" or CONFIGURED_ARCH == "arm64" %} + libxslt-dev \ +{%- endif %} # For lockfile procmail \ -# For gtest - libgtest-dev \ - cmake \ # For pam_tacplus build autoconf-archive \ # For iproute2 @@ -265,16 +251,6 @@ RUN apt-get update && apt-get install -y \ texlive-latex-extra \ texlive-latex-recommended \ iproute2 \ -# For python-click build - python-sphinx \ - python-docutils \ - python3-all \ - python3-setuptools \ - python3-sphinx \ - python3-docutils \ - python3-requests \ - python3-pytest \ - python3-colorama \ # For bash texi2html \ # For initramfs @@ -298,10 +274,21 @@ RUN apt-get update && apt-get install -y \ libnetfilter-conntrack-dev \ libnftnl-dev \ # For SAI3.7 + protobuf-compiler \ libprotobuf-dev \ + xxd \ # For DHCP Monitor tool libexplain-dev \ - libevent-dev + libevent-dev \ +# For libyang + swig \ +# For sonic-mgmt-framework + autoconf \ + m4 \ + libxml2-utils \ + xsltproc \ + python-lxml \ + libexpat1-dev ## Config dpkg ## install the configuration file if it’s currently missing @@ -318,7 +305,7 @@ RUN apt-get -t stretch-backports install -y debhelper RUN apt-get -y build-dep linux # For gobgp and telemetry build -RUN export VERSION=1.11.5 \ +RUN export VERSION=1.14.2 \ {%- if CONFIGURED_ARCH == "armhf" %} && wget https://storage.googleapis.com/golang/go$VERSION.linux-armv6l.tar.gz \ && tar -C /usr/local -xzf go$VERSION.linux-armv6l.tar.gz \ @@ -333,45 +320,57 @@ RUN export VERSION=1.11.5 \ && echo 'export PATH=$PATH:$GOROOT/bin' >> /etc/bash.bashrc \ && rm go$VERSION.linux-*.tar.gz +RUN pip3 install --upgrade pip +RUN pip2 install --upgrade 'pip<21' +RUN apt-get purge -y python-pip python3-pip + # For p4 build -RUN pip install \ - ctypesgen==0.r125 \ - crc16 +RUN pip2 install \ + ctypesgen==0.r125 \ + crc16 + +# Note: Stick with Jinja2 2.x branch as the 3.x dropped support for Python 2.7 +RUN pip2 install --force-reinstall --upgrade "Jinja2<3.0.0" # For sonic config engine testing -RUN pip install pyangbind==0.6.0 -# Note: force upgrade debian packaged jinja2, if installed -RUN pip install --force-reinstall --upgrade "jinja2>=2.10" +# Install pyangbind here, outside sonic-config-engine dependencies, as pyangbind causes enum34 to be installed. +# enum34 causes Python 're' package to not work properly as it redefines an incompatible enum.py module +# https://github.com/robshakir/pyangbind/issues/232 +RUN pip3 install pyangbind==0.8.1 +RUN pip3 uninstall -y enum34 # For templating -RUN pip install j2cli==0.3.10 - -# Remove python-click 6.6 -RUN apt-get purge -y python-click -# For sonic utilities testing -RUN pip install click-default-group click natsort tabulate netifaces==0.10.7 fastentrypoints +RUN pip2 install j2cli==0.3.10 # For sonic snmpagent mock testing RUN pip3 install mockredispy==2.9.3 -RUN pip3 install "PyYAML>=5.1" +# For sonic-mgmt-framework +RUN pip2 install "PyYAML==5.3.1" +RUN pip3 install "PyYAML==5.3.1" +RUN pip2 install "lxml==4.6.2" +RUN pip3 install "lxml==4.6.2" + # For sonic-platform-common testing RUN pip3 install redis -# For supervisor build -RUN pip install meld3 mock - # For vs image build -RUN pip install pexpect==4.6.0 +RUN pip2 install pexpect==4.6.0 # For sonic-utilities build -RUN pip install mockredispy==2.9.3 -RUN pip install pytest-runner==4.4 -RUN pip install setuptools==40.8.0 +RUN pip2 install mockredispy==2.9.3 +RUN pip2 install pytest-runner==4.4 +RUN pip2 install setuptools==40.8.0 + +# For sonic-swss-common testing +RUN pip2 install Pympler==0.8 + +# For sonic_yang_model build +RUN pip2 install pyang==2.1.1 # For mgmt-framework build -RUN pip install mmh3 +RUN pip2 install mmh3 # Install dependencies for isc-dhcp-relay build RUN apt-get -y build-dep isc-dhcp @@ -382,6 +381,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 @@ -406,8 +422,23 @@ RUN add-apt-repository \ stable" RUN apt-get update {%- if CONFIGURED_ARCH == "amd64" %} -RUN apt-get install -y docker-ce=5:18.09.5~3-0~debian-stretch +RUN apt-get install -y docker-ce=5:18.09.5~3-0~debian-stretch docker-ce-cli=5:18.09.5~3-0~debian-stretch {%- else %} RUN apt-get install -y docker-ce=18.06.3~ce~3-0~debian {%- endif %} RUN echo "DOCKER_OPTS=\"--experimental --storage-driver=vfs\"" >> /etc/default/docker + +# Install m2crypto package, needed by SWI tools +RUN pip install m2crypto==0.36.0 + +# Install swi tools +RUN pip2 install git+https://github.com/aristanetworks/swi-tools.git@d51761ec0bb93c73039233f3c01ed48235ffad00 + +{% if CONFIGURED_ARCH != "amd64" -%} +# Install node.js for azure pipeline +RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - +RUN apt-get install -y nodejs + +# Tell azure pipeline to use node.js in the docker +LABEL "com.azure.dev.pipelines.agent.handler.node.path"="/usr/bin/node" +{% endif -%} diff --git a/sonic-slave-stretch/Dockerfile.user b/sonic-slave-stretch/Dockerfile.user deleted file mode 100644 index 87e4d9568bb1..000000000000 --- a/sonic-slave-stretch/Dockerfile.user +++ /dev/null @@ -1,30 +0,0 @@ -ARG slave_base_tag_ref=latest -FROM sonic-slave-stretch:${slave_base_tag_ref} - -# Add user -ARG user -ARG uid -ARG guid -ARG hostname - -ENV BUILD_HOSTNAME $hostname -ENV USER $user - -RUN groupadd -f -r -g $guid g$user - -RUN useradd $user -l -u $uid -g $guid -d /var/$user -m -s /bin/bash - -RUN gpasswd -a $user docker - -# Config git for stg -RUN su $user -c "git config --global user.name $user" -RUN su $user -c "git config --global user.email $user@contoso.com" - -COPY sonic-jenkins-id_rsa.pub /var/$user/.ssh/authorized_keys2 -RUN chown $user /var/$user/.ssh -R -RUN chmod go= /var/$user/.ssh -R - -# Add user to sudoers -RUN echo "$user ALL=(ALL) NOPASSWD:ALL" >>/etc/sudoers - -USER $user diff --git a/sonic-slave-stretch/Dockerfile.user.j2 b/sonic-slave-stretch/Dockerfile.user.j2 new file mode 100644 index 000000000000..8e94b7046ae3 --- /dev/null +++ b/sonic-slave-stretch/Dockerfile.user.j2 @@ -0,0 +1,34 @@ +ARG slave_base_tag_ref=latest +{%- if CONFIGURED_ARCH == "amd64" %} +FROM sonic-slave-stretch:${slave_base_tag_ref} +{%- else %} +FROM sonic-slave-stretch-{{ CONFIGURED_ARCH }}:${slave_base_tag_ref} +{%- endif %} + +# Add user +ARG user +ARG uid +ARG guid +ARG hostname + +ENV BUILD_HOSTNAME $hostname +ENV USER $user + +RUN groupadd -f -r -g $guid g$user + +RUN useradd $user -l -u $uid -g $guid -d /var/$user -m -s /bin/bash + +RUN gpasswd -a $user docker + +# Config git for stg +RUN su $user -c "git config --global user.name $user" +RUN su $user -c "git config --global user.email $user@contoso.com" + +COPY sonic-jenkins-id_rsa.pub /var/$user/.ssh/authorized_keys2 +RUN chown $user /var/$user/.ssh -R +RUN chmod go= /var/$user/.ssh -R + +# Add user to sudoers +RUN echo "$user ALL=(ALL) NOPASSWD:ALL" >>/etc/sudoers + +USER $user diff --git a/src/bash/.gitignore b/src/bash/.gitignore new file mode 100644 index 000000000000..a0991ff4402b --- /dev/null +++ b/src/bash/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!Makefile diff --git a/src/bash/Makefile b/src/bash/Makefile index 602dc01ece70..6576ff92e74a 100644 --- a/src/bash/Makefile +++ b/src/bash/Makefile @@ -10,7 +10,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : dget -u https://launchpad.net/debian/+archive/primary/+sourcefiles/bash/$(BASH_VERSION_FULL)/bash_$(BASH_VERSION_FULL).dsc pushd bash-$(BASH_VERSION_MAJOR) - DEB_BUILD_OPTIONS=nocheck dpkg-buildpackage -us -uc -b -j$(SONIC_CONFIG_MAKE_JOBS) + DEB_BUILD_OPTIONS=nocheck dpkg-buildpackage -us -uc -b -j$(SONIC_CONFIG_MAKE_JOBS) --admindir $(SONIC_DPKG_ADMINDIR) popd mv $* $(DEST)/ diff --git a/src/dhcpmon/.gitignore b/src/dhcpmon/.gitignore new file mode 100644 index 000000000000..9d09ae6b3f1a --- /dev/null +++ b/src/dhcpmon/.gitignore @@ -0,0 +1,5 @@ +debian/* +!debian/changelog +!debian/compat +!debian/control +!debian/rules diff --git a/src/dhcpmon/debian/control b/src/dhcpmon/debian/control index 2f05fda79963..8623428462e3 100644 --- a/src/dhcpmon/debian/control +++ b/src/dhcpmon/debian/control @@ -12,5 +12,5 @@ Package: sonic-dhcpmon Architecture: any Built-Using: ${misc:Built-Using} Depends: libexplain51, - libevent-2.0-5 + libevent-2.1-6 Description: SONiC DHCP Monitor diff --git a/src/dhcpmon/debian/rules b/src/dhcpmon/debian/rules index 3995a26d7fcd..00c628b6625f 100755 --- a/src/dhcpmon/debian/rules +++ b/src/dhcpmon/debian/rules @@ -1,3 +1,7 @@ #!/usr/bin/make -f + +DEB_CFLAGS_APPEND=-std=gnu11 +export DEB_CFLAGS_APPEND + %: - dh $@ --with systemd + dh $@ --parallel diff --git a/src/dhcpmon/src/dhcp_device.c b/src/dhcpmon/src/dhcp_device.c index aa0c0f835cbd..f5cb705ee285 100644 --- a/src/dhcpmon/src/dhcp_device.c +++ b/src/dhcpmon/src/dhcp_device.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -23,6 +24,9 @@ #include "dhcp_device.h" +/** Counter print width */ +#define DHCP_COUNTER_WIDTH 9 + /** Start of Ether header of a captured frame */ #define ETHER_START_OFFSET 0 /** Start of IP header of a captured frame */ @@ -33,6 +37,8 @@ #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 +/** Offset of DHCP GIADDR */ +#define DHCP_GIADDR_OFFSET 24 #define OP_LDHA (BPF_LD | BPF_H | BPF_ABS) /** bpf ldh Abs */ #define OP_LDHI (BPF_LD | BPF_H | BPF_IND) /** bpf ldh Ind */ @@ -43,8 +49,9 @@ #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)"' +/** Berkeley Packet Filter program for "udp and (port 67 or port 68)". + * This program is obtained using the following command tcpdump: + * `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] @@ -77,61 +84,68 @@ 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}, +/** Aggregate device of DHCP interfaces. It contains aggregate counters from + all interfaces + */ +static dhcp_device_context_t aggregate_dev = {0}; + +/** Monitored DHCP message type */ +static dhcp_message_type_t monitored_msgs[] = { + DHCP_MESSAGE_TYPE_DISCOVER, + DHCP_MESSAGE_TYPE_OFFER, + DHCP_MESSAGE_TYPE_REQUEST, + DHCP_MESSAGE_TYPE_ACK }; -/** 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}, -}; +/** Number of monitored DHCP message type */ +static uint8_t monitored_msg_sz = sizeof(monitored_msgs) / sizeof(*monitored_msgs); /** - * @code handle_dhcp_option_53(context, dhcp_option, dir); + * @code handle_dhcp_option_53(context, dhcp_option, dir, iphdr, dhcphdr); * * @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 + * @param iphdr pointer to packet IP header + * @param dhcphdr pointer to DHCP header * * @return none */ -static void handle_dhcp_option_53(dhcp_device_context_t *context, const u_char *dhcp_option, dhcp_packet_direction_t dir) +static void handle_dhcp_option_53(dhcp_device_context_t *context, + const u_char *dhcp_option, + dhcp_packet_direction_t dir, + struct ip *iphdr, + uint8_t *dhcphdr) { + in_addr_t giaddr; 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++; + // DHCP messages send by client + case DHCP_MESSAGE_TYPE_DISCOVER: + case DHCP_MESSAGE_TYPE_REQUEST: + case DHCP_MESSAGE_TYPE_DECLINE: + case DHCP_MESSAGE_TYPE_RELEASE: + case DHCP_MESSAGE_TYPE_INFORM: + giaddr = ntohl(dhcphdr[DHCP_GIADDR_OFFSET] << 24 | dhcphdr[DHCP_GIADDR_OFFSET + 1] << 16 | + dhcphdr[DHCP_GIADDR_OFFSET + 2] << 8 | dhcphdr[DHCP_GIADDR_OFFSET + 3]); + if ((context->vlan_ip == giaddr && context->is_uplink && dir == DHCP_TX) || + (!context->is_uplink && dir == DHCP_RX && iphdr->ip_dst.s_addr == INADDR_BROADCAST)) { + context->counters[DHCP_COUNTERS_CURRENT][dir][dhcp_option[2]]++; + aggregate_dev.counters[DHCP_COUNTERS_CURRENT][dir][dhcp_option[2]]++; } break; - case 3: - context->counters[dir].request++; - if ((context->is_uplink && dir == DHCP_TX) || (!context->is_uplink && dir == DHCP_RX)) { - glob_counters[dir].request++; + // DHCP messages send by server + case DHCP_MESSAGE_TYPE_OFFER: + case DHCP_MESSAGE_TYPE_ACK: + case DHCP_MESSAGE_TYPE_NAK: + if ((context->vlan_ip == iphdr->ip_dst.s_addr && context->is_uplink && dir == DHCP_RX) || + (!context->is_uplink && dir == DHCP_TX)) { + context->counters[DHCP_COUNTERS_CURRENT][dir][dhcp_option[2]]++; + aggregate_dev.counters[DHCP_COUNTERS_CURRENT][dir][dhcp_option[2]]++; } 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; @@ -146,7 +160,6 @@ static void handle_dhcp_option_53(dhcp_device_context_t *context, const u_char * * @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 */ @@ -158,7 +171,9 @@ static void read_callback(int fd, short event, void *arg) 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 ip *iphdr = (struct ip*) (context->buffer + IP_START_OFFSET); struct udphdr *udp = (struct udphdr*) (context->buffer + UDP_START_OFFSET); + uint8_t *dhcphdr = context->buffer + DHCP_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) && @@ -181,7 +196,7 @@ static void read_callback(int fd, short event, void *arg) { case 53: if (offset < (dhcp_option_sz + 2)) { - handle_dhcp_option_53(context, &dhcp_option[offset], dir); + handle_dhcp_option_53(context, &dhcp_option[offset], dir, iphdr, dhcphdr); } stop_dhcp_processing = 1; // break while loop since we are only interested in Option 53 break; @@ -207,84 +222,188 @@ static void read_callback(int fd, short event, void *arg) } /** - * @code dhcp_device_validate(counters, counters_snapshot); + * @code dhcp_device_is_dhcp_inactive(counters); + * + * @brief Check if there were no DHCP activity + * + * @param counters current/snapshot counter + * + * @return true if there were no DHCP activity, false otherwise + */ +static bool dhcp_device_is_dhcp_inactive(uint64_t counters[][DHCP_DIR_COUNT][DHCP_MESSAGE_TYPE_COUNT]) +{ + uint64_t *rx_counters = counters[DHCP_COUNTERS_CURRENT][DHCP_RX]; + uint64_t *rx_counter_snapshot = counters[DHCP_COUNTERS_SNAPSHOT][DHCP_RX]; + + bool rv = true; + for (uint8_t i = 0; (i < monitored_msg_sz) && rv; i++) { + rv = rx_counters[monitored_msgs[i]] == rx_counter_snapshot[monitored_msgs[i]]; + } + + return rv; +} + +/** + * @code dhcp_device_is_dhcp_msg_unhealthy(type, counters); * - * @brief validate current interface counters by comparing aggregate counter with snapshot counters. + * @brief Check if DHCP relay is functioning properly for message of type 'type'. + * For every rx of message 'type', there should be increment of the same message type. + * + * @param type DHCP message type + * @param counters current/snapshot counter + * + * @return true if DHCP message 'type' is transmitted,false otherwise + */ +static bool dhcp_device_is_dhcp_msg_unhealthy(dhcp_message_type_t type, + uint64_t counters[][DHCP_DIR_COUNT][DHCP_MESSAGE_TYPE_COUNT]) +{ + // check if DHCP message 'type' is being relayed + return ((counters[DHCP_COUNTERS_CURRENT][DHCP_RX][type] > counters[DHCP_COUNTERS_SNAPSHOT][DHCP_RX][type]) && + (counters[DHCP_COUNTERS_CURRENT][DHCP_TX][type] <= counters[DHCP_COUNTERS_SNAPSHOT][DHCP_TX][type]) ); +} + +/** + * @code dhcp_device_check_positive_health(counters, counters_snapshot); + * + * @brief Check if DHCP relay is functioning properly for monitored messages (Discover, Offer, Request, ACK.) + * For every rx of monitored messages, there should be increment of the same message type. + * + * @param counters current/snapshot counter + * + * @return DHCP_MON_STATUS_HEALTHY, DHCP_MON_STATUS_UNHEALTHY, or DHCP_MON_STATUS_INDETERMINATE + */ +static dhcp_mon_status_t dhcp_device_check_positive_health(uint64_t counters[][DHCP_DIR_COUNT][DHCP_MESSAGE_TYPE_COUNT]) +{ + dhcp_mon_status_t rv = DHCP_MON_STATUS_HEALTHY; + + bool is_dhcp_unhealthy = false; + for (uint8_t i = 0; (i < monitored_msg_sz) && !is_dhcp_unhealthy; i++) { + is_dhcp_unhealthy = dhcp_device_is_dhcp_msg_unhealthy(monitored_msgs[i], counters); + } + + // if we have rx DORA then we should have corresponding tx DORA (DORA being relayed) + if (is_dhcp_unhealthy) { + rv = DHCP_MON_STATUS_UNHEALTHY; + } + + return rv; +} + +/** + * @code dhcp_device_check_negative_health(counters); + * + * @brief Check that DHCP relayed messages are not being transmitted out of this interface/dev + * using its counters. The interface is negatively healthy if there are not DHCP message + * travelling through it. * * @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) +static dhcp_mon_status_t dhcp_device_check_negative_health(uint64_t counters[][DHCP_DIR_COUNT][DHCP_MESSAGE_TYPE_COUNT]) { 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 ) ) { + uint64_t *tx_counters = counters[DHCP_COUNTERS_CURRENT][DHCP_TX]; + uint64_t *tx_counter_snapshot = counters[DHCP_COUNTERS_SNAPSHOT][DHCP_TX]; + + bool is_dhcp_unhealthy = false; + for (uint8_t i = 0; (i < monitored_msg_sz) && !is_dhcp_unhealthy; i++) { + is_dhcp_unhealthy = tx_counters[monitored_msgs[i]] > tx_counter_snapshot[monitored_msgs[i]]; + } + + // for negative validation, return unhealthy if DHCP packet are being + // transmitted out of the device/interface + if (is_dhcp_unhealthy) { + rv = DHCP_MON_STATUS_UNHEALTHY; + } + + return rv; +} + +/** + * @code dhcp_device_check_health(check_type, counters, counters_snapshot); + * + * @brief Check that DHCP relay is functioning properly given a check type. Positive check + * indicates for every rx of DHCP message of type 'type', there would increment of + * the corresponding TX of the same message type. While negative check indicates the + * device should not be actively transmitting any DHCP messages. If it does, it is + * considered unhealthy. + * + * @param check_type type of health check + * @param counters current/snapshot counter + * + * @return DHCP_MON_STATUS_HEALTHY, DHCP_MON_STATUS_UNHEALTHY, or DHCP_MON_STATUS_INDETERMINATE + */ +static dhcp_mon_status_t dhcp_device_check_health(dhcp_mon_check_t check_type, + uint64_t counters[][DHCP_DIR_COUNT][DHCP_MESSAGE_TYPE_COUNT]) +{ + dhcp_mon_status_t rv = DHCP_MON_STATUS_HEALTHY; + + if (dhcp_device_is_dhcp_inactive(aggregate_dev.counters)) { 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; - } + } else if (check_type == DHCP_MON_CHECK_POSITIVE) { + rv = dhcp_device_check_positive_health(counters); + } else if (check_type == DHCP_MON_CHECK_NEGATIVE) { + rv = dhcp_device_check_negative_health(counters); } return rv; } /** - * @code dhcp_print_counters(counters); + * @code dhcp_print_counters(vlan_intf, type, counters); * * @brief prints DHCP counters to sylsog. * + * @param vlan_intf vlan interface name + * @param type counter type * @param counters interface counter + * + * @return none */ -static void dhcp_print_counters(dhcp_device_counters_t *counters) +static void dhcp_print_counters(const char *vlan_intf, + dhcp_counters_type_t type, + uint64_t counters[][DHCP_MESSAGE_TYPE_COUNT]) { - 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); + static const char *counter_desc[DHCP_COUNTERS_COUNT] = { + [DHCP_COUNTERS_CURRENT] = " Current", + [DHCP_COUNTERS_SNAPSHOT] = "Snapshot" + }; + + syslog( + LOG_NOTICE, + "[%*s-%*s rx/tx] Discover: %*lu/%*lu, Offer: %*lu/%*lu, Request: %*lu/%*lu, ACK: %*lu/%*lu\n", + IF_NAMESIZE, vlan_intf, + (int) strlen(counter_desc[type]), counter_desc[type], + DHCP_COUNTER_WIDTH, counters[DHCP_RX][DHCP_MESSAGE_TYPE_DISCOVER], + DHCP_COUNTER_WIDTH, counters[DHCP_TX][DHCP_MESSAGE_TYPE_DISCOVER], + DHCP_COUNTER_WIDTH, counters[DHCP_RX][DHCP_MESSAGE_TYPE_OFFER], + DHCP_COUNTER_WIDTH, counters[DHCP_TX][DHCP_MESSAGE_TYPE_OFFER], + DHCP_COUNTER_WIDTH, counters[DHCP_RX][DHCP_MESSAGE_TYPE_REQUEST], + DHCP_COUNTER_WIDTH, counters[DHCP_TX][DHCP_MESSAGE_TYPE_REQUEST], + DHCP_COUNTER_WIDTH, counters[DHCP_RX][DHCP_MESSAGE_TYPE_ACK], + DHCP_COUNTER_WIDTH, counters[DHCP_TX][DHCP_MESSAGE_TYPE_ACK] + ); } /** - * @code init_socket(context, intf, snaplen, base); + * @code init_socket(context, intf); * - * @brief initializes socket, bind it to interface and bpf prgram, and + * @brief initializes socket, bind it to interface and bpf program, 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) +static int init_socket(dhcp_device_context_t *context, const char *intf) { 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)); @@ -301,25 +420,6 @@ static int init_socket(dhcp_device_context_t *context, 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'; @@ -377,15 +477,44 @@ static int initialize_intf_mac_and_ip_addr(dhcp_device_context_t *context) } /** - * @code dhcp_device_init(context, intf, snaplen, is_uplink, base); + * @code dhcp_device_get_ip(context); + * + * @brief Accessor method + * + * @param context pointer to device (interface) context + * + * @return interface IP + */ +int dhcp_device_get_ip(dhcp_device_context_t *context, in_addr_t *ip) +{ + int rv = -1; + + if (context != NULL && ip != NULL) { + *ip = context->ip; + rv = 0; + } + + return rv; +} + +/** + * @code dhcp_device_get_aggregate_context(); + * + * @brief Accessor method + * + * @return pointer to aggregate device (interface) context + */ +dhcp_device_context_t* dhcp_device_get_aggregate_context() +{ + return &aggregate_dev; +} + +/** + * @code dhcp_device_init(context, intf, is_uplink); * * @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 dhcp_device_init(dhcp_device_context_t **context, const char *intf, uint8_t is_uplink) { int rv = -1; dhcp_device_context_t *dev_context = NULL; @@ -394,13 +523,12 @@ int dhcp_device_init(dhcp_device_context_t **context, 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 ) ) { + if ((init_socket(dev_context, intf) == 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)); + memset(dev_context->counters, 0, sizeof(dev_context->counters)); *context = dev_context; rv = 0; @@ -414,6 +542,56 @@ int dhcp_device_init(dhcp_device_context_t **context, return rv; } +/** + * @code dhcp_device_start_capture(context, snaplen, base, vlan_ip); + * + * @brief starts packet capture on this interface + */ +int dhcp_device_start_capture(dhcp_device_context_t *context, + size_t snaplen, + struct event_base *base, + in_addr_t vlan_ip) +{ + int rv = -1; + + do { + if (context == NULL) { + syslog(LOG_ALERT, "NULL interface context pointer'\n"); + break; + } + + if (snaplen < UDP_START_OFFSET + sizeof(struct udphdr) + DHCP_OPTIONS_HEADER_SIZE) { + syslog(LOG_ALERT, "dhcp_device_start_capture(%s): snap length is too low to capture DHCP options", context->intf); + break; + } + + context->vlan_ip = vlan_ip; + + 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; + + 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; + } + + 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); + + rv = 0; + } while (0); + + return rv; +} + /** * @code dhcp_device_shutdown(context); * @@ -425,36 +603,44 @@ void dhcp_device_shutdown(dhcp_device_context_t *context) } /** - * @code dhcp_device_get_status(context); + * @code dhcp_device_get_status(check_type, 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 dhcp_device_get_status(dhcp_mon_check_t check_type, dhcp_device_context_t *context) { - dhcp_mon_status_t rv = 0; + dhcp_mon_status_t rv = DHCP_MON_STATUS_HEALTHY; 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)); + rv = dhcp_device_check_health(check_type, context->counters); } return rv; } /** - * @code dhcp_device_print_status(); + * @code dhcp_device_update_snapshot(context); + * + * @brief Update device/interface counters snapshot + */ +void dhcp_device_update_snapshot(dhcp_device_context_t *context) +{ + if (context != NULL) { + memcpy(context->counters[DHCP_COUNTERS_SNAPSHOT], + context->counters[DHCP_COUNTERS_CURRENT], + sizeof(context->counters[DHCP_COUNTERS_SNAPSHOT])); + } +} + +/** + * @code dhcp_device_print_status(context, type); * - * @brief prints status counters to syslog. If context is null, it will print aggregate status + * @brief prints status counters to syslog. */ -void dhcp_device_print_status(dhcp_device_context_t *context) +void dhcp_device_print_status(dhcp_device_context_t *context, dhcp_counters_type_t type) { if (context != NULL) { - dhcp_print_counters(context->counters); - } else { - dhcp_print_counters(glob_counters); + dhcp_print_counters(context->intf, type, context->counters[type]); } } diff --git a/src/dhcpmon/src/dhcp_device.h b/src/dhcpmon/src/dhcp_device.h index 04113eeabdc0..133b9265a434 100644 --- a/src/dhcpmon/src/dhcp_device.h +++ b/src/dhcpmon/src/dhcp_device.h @@ -17,6 +17,23 @@ #include +/** + * DHCP message types + **/ +typedef enum +{ + DHCP_MESSAGE_TYPE_DISCOVER = 1, + DHCP_MESSAGE_TYPE_OFFER = 2, + DHCP_MESSAGE_TYPE_REQUEST = 3, + DHCP_MESSAGE_TYPE_DECLINE = 4, + DHCP_MESSAGE_TYPE_ACK = 5, + DHCP_MESSAGE_TYPE_NAK = 6, + DHCP_MESSAGE_TYPE_RELEASE = 7, + DHCP_MESSAGE_TYPE_INFORM = 8, + + DHCP_MESSAGE_TYPE_COUNT +} dhcp_message_type_t; + /** packet direction */ typedef enum { @@ -26,6 +43,15 @@ typedef enum DHCP_DIR_COUNT } dhcp_packet_direction_t; +/** counters type */ +typedef enum +{ + DHCP_COUNTERS_CURRENT, /** DHCP current counters */ + DHCP_COUNTERS_SNAPSHOT, /** DHCP snapshot counters */ + + DHCP_COUNTERS_COUNT +} dhcp_counters_type_t; + /** dhcp health status */ typedef enum { @@ -34,14 +60,12 @@ typedef enum DHCP_MON_STATUS_INDETERMINATE, /** DHCP relay health could not be determined */ } dhcp_mon_status_t; -/** DHCP device (interface) health counters */ -typedef struct +/** dhcp check type */ +typedef enum { - 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_MON_CHECK_NEGATIVE, /** Presence of relayed DHCP packets activity is flagged as unhealthy state */ + DHCP_MON_CHECK_POSITIVE, /** Validate that received DORA packets are relayed */ +} dhcp_mon_check_t; /** DHCP device (interface) context */ typedef struct @@ -49,34 +73,67 @@ 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) */ + in_addr_t vlan_ip; /** Vlan IP address */ 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 */ + uint64_t counters[DHCP_COUNTERS_COUNT][DHCP_DIR_COUNT][DHCP_MESSAGE_TYPE_COUNT]; + /** current/snapshot counters of DHCP packets */ } dhcp_device_context_t; /** - * @code dhcp_device_init(context, intf, snaplen, timeout_ms, is_uplink, base); + * @code dhcp_device_get_ip(context, ip); + * + * @brief Accessor method + * + * @param context pointer to device (interface) context + * @param ip(out) pointer to device IP + * + * @return 0 on success, otherwise for failure + */ +int dhcp_device_get_ip(dhcp_device_context_t *context, in_addr_t *ip); + +/** + * @code dhcp_device_get_aggregate_context(); + * + * @brief Accessor method + * + * @return pointer to aggregate device (interface) context + */ +dhcp_device_context_t* dhcp_device_get_aggregate_context(); + +/** + * @code dhcp_device_init(context, intf, is_uplink); * * @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); + uint8_t is_uplink); + +/** + * @code dhcp_device_start_capture(context, snaplen, base, vlan_ip); + * + * @brief starts packet capture on this interface + * + * @param context pointer to device (interface) context + * @param snaplen length of packet capture + * @param base pointer to libevent base + * @param vlan_ip vlan IP address + * + * @return 0 on success, otherwise for failure + */ +int dhcp_device_start_capture(dhcp_device_context_t *context, + size_t snaplen, + struct event_base *base, + in_addr_t vlan_ip); /** * @code dhcp_device_shutdown(context); @@ -90,24 +147,37 @@ int dhcp_device_init(dhcp_device_context_t **context, void dhcp_device_shutdown(dhcp_device_context_t *context); /** - * @code dhcp_device_get_status(context); + * @code dhcp_device_get_status(check_type, 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 + * @param check_type Type of validation + * @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); +dhcp_mon_status_t dhcp_device_get_status(dhcp_mon_check_t check_type, dhcp_device_context_t *context); + +/** + * @code dhcp_device_update_snapshot(context); + * + * @param context Device (interface) context + * + * @brief Update device/interface counters snapshot + */ +void dhcp_device_update_snapshot(dhcp_device_context_t *context); /** - * @code dhcp_device_print_status(); + * @code dhcp_device_print_status(context, type); * * @brief prints status counters to syslog. If context is null, it will print aggregate status * + * @param context Device (interface) context + * @param counters_type Counter type to be printed + * * @return none */ -void dhcp_device_print_status(dhcp_device_context_t *context); +void dhcp_device_print_status(dhcp_device_context_t *context, dhcp_counters_type_t type); #endif /* DHCP_DEVICE_H_ */ diff --git a/src/dhcpmon/src/dhcp_devman.c b/src/dhcpmon/src/dhcp_devman.c index c19cbde591b8..35378a631ca7 100644 --- a/src/dhcpmon/src/dhcp_devman.c +++ b/src/dhcpmon/src/dhcp_devman.c @@ -12,6 +12,9 @@ #include "dhcp_devman.h" +/** Prefix appended to Aggregation device */ +#define AGG_DEV_PREFIX "Agg-" + /** struct for interface information */ struct intf { @@ -27,6 +30,35 @@ static LIST_HEAD(intf_list, intf) intfs; static uint32_t dhcp_num_south_intf = 0; /** dhcp_num_north_intf number of north interfaces */ static uint32_t dhcp_num_north_intf = 0; +/** dhcp_num_mgmt_intf number of mgmt interfaces */ +static uint32_t dhcp_num_mgmt_intf = 0; + +/** On Device vlan interface IP address corresponding vlan downlink IP + * This IP is used to filter Offer/Ack packet coming from DHCP server */ +static in_addr_t vlan_ip = 0; + +/** mgmt interface */ +static struct intf *mgmt_intf = NULL; + +/** + * @code dhcp_devman_get_vlan_intf(); + * + * Accessor method + */ +dhcp_device_context_t* dhcp_devman_get_agg_dev() +{ + return dhcp_device_get_aggregate_context(); +} + +/** + * @code dhcp_devman_get_mgmt_dev(); + * + * Accessor method + */ +dhcp_device_context_t* dhcp_devman_get_mgmt_dev() +{ + return mgmt_intf ? mgmt_intf->dev_context : NULL; +} /** * @code dhcp_devman_init(); @@ -65,28 +97,49 @@ void dhcp_devman_shutdown() } /** - * @code dhcp_devman_add_intf(name, uplink); + * @code dhcp_devman_add_intf(name, is_uplink); * * @brief adds interface to the device manager. */ -int dhcp_devman_add_intf(const char *name, uint8_t is_uplink) +int dhcp_devman_add_intf(const char *name, char intf_type) { int rv = -1; struct intf *dev = malloc(sizeof(struct intf)); if (dev != NULL) { dev->name = name; - dev->is_uplink = is_uplink; - if (is_uplink) { + dev->is_uplink = intf_type != 'd'; + + switch (intf_type) + { + case 'u': dhcp_num_north_intf++; - } else { + break; + case 'd': dhcp_num_south_intf++; assert(dhcp_num_south_intf <= 1); + break; + case 'm': + dhcp_num_mgmt_intf++; + assert(dhcp_num_mgmt_intf <= 1); + mgmt_intf = dev; + break; + default: + break; } - LIST_INSERT_HEAD(&intfs, dev, entry); + rv = dhcp_device_init(&dev->dev_context, dev->name, dev->is_uplink); + if (rv == 0 && intf_type == 'd') { + rv = dhcp_device_get_ip(dev->dev_context, &vlan_ip); - rv = 0; + dhcp_device_context_t *agg_dev = dhcp_device_get_aggregate_context(); + + strncpy(agg_dev->intf, AGG_DEV_PREFIX, sizeof(AGG_DEV_PREFIX)); + strncpy(agg_dev->intf + sizeof(AGG_DEV_PREFIX) - 1, name, sizeof(agg_dev->intf) - sizeof(AGG_DEV_PREFIX)); + agg_dev->intf[sizeof(agg_dev->intf) - 1] = '\0'; + } + + LIST_INSERT_HEAD(&intfs, dev, entry); } else { syslog(LOG_ALERT, "malloc: failed to allocate memory for intf '%s'\n", name); @@ -100,14 +153,14 @@ int dhcp_devman_add_intf(const char *name, uint8_t is_uplink) * * @brief start packet capture on the devman interface list */ -int dhcp_devman_start_capture(int snaplen, struct event_base *base) +int dhcp_devman_start_capture(size_t 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); + rv = dhcp_device_start_capture(int_ptr->dev_context, snaplen, base, vlan_ip); if (rv == 0) { syslog(LOG_INFO, "Capturing DHCP packets on interface %s, ip: 0x%08x, mac [%02x:%02x:%02x:%02x:%02x:%02x] \n", @@ -129,21 +182,51 @@ int dhcp_devman_start_capture(int snaplen, struct event_base *base) } /** - * @code dhcp_devman_get_status(); + * @code dhcp_devman_get_status(check_type, context); * * @brief collects DHCP relay status info. */ -dhcp_mon_status_t dhcp_devman_get_status() +dhcp_mon_status_t dhcp_devman_get_status(dhcp_mon_check_t check_type, dhcp_device_context_t *context) { - return dhcp_device_get_status(NULL); + return dhcp_device_get_status(check_type, context); +} + +/** + * @code dhcp_devman_update_snapshot(context); + * + * @brief Update device/interface counters snapshot + */ +void dhcp_devman_update_snapshot(dhcp_device_context_t *context) +{ + if (context == NULL) { + struct intf *int_ptr; + + LIST_FOREACH(int_ptr, &intfs, entry) { + dhcp_device_update_snapshot(int_ptr->dev_context); + } + + dhcp_device_update_snapshot(dhcp_devman_get_agg_dev()); + } else { + dhcp_device_update_snapshot(context); + } } /** - * @code dhcp_devman_print_status(); + * @code dhcp_devman_print_status(context, type); * - * @brief prints status counters to syslog + * @brief prints status counters to syslog, if context is null, it prints status counters for all interfaces */ -void dhcp_devman_print_status() +void dhcp_devman_print_status(dhcp_device_context_t *context, dhcp_counters_type_t type) { - dhcp_device_print_status(NULL); + if (context == NULL) { + struct intf *int_ptr; + + LIST_FOREACH(int_ptr, &intfs, entry) { + dhcp_device_print_status(int_ptr->dev_context, type); + } + + dhcp_device_print_status(dhcp_devman_get_agg_dev(), type); + } else { + dhcp_device_print_status(context, type); + } } diff --git a/src/dhcpmon/src/dhcp_devman.h b/src/dhcpmon/src/dhcp_devman.h index a0753b4b93a1..bba7076902cb 100644 --- a/src/dhcpmon/src/dhcp_devman.h +++ b/src/dhcpmon/src/dhcp_devman.h @@ -31,46 +31,81 @@ void dhcp_devman_init(); */ void dhcp_devman_shutdown(); +/** + * @code dhcp_devman_get_vlan_intf(); + * + * @brief Accessor method + * + * @return pointer to aggregate device (interface) context + */ +dhcp_device_context_t* dhcp_devman_get_agg_dev(); + +/** + * @code dhcp_devman_get_mgmt_intf_context(); + * + * @brief Accessor method + * + * @return pointer to mgmt interface context + */ +dhcp_device_context_t* dhcp_devman_get_mgmt_dev(); + /** * @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 + * @param name interface name + * @param intf_type 'u' for uplink (north) interface + * 'd' for downlink (south) interface + * 'm' for mgmt interface * * @return 0 on success, nonzero otherwise */ -int dhcp_devman_add_intf(const char *name, uint8_t is_uplink); +int dhcp_devman_add_intf(const char *name, char intf_type); /** - * @code dhcp_devman_start_capture(snaplen, timeout_ms); + * @code dhcp_devman_start_capture(snaplen, base); * * @brief start packet capture on the devman interface list * - * @param snaplen packet capture snap length + * @param snaplen packet 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); +int dhcp_devman_start_capture(size_t snaplen, struct event_base *base); /** - * @code dhcp_devman_get_status(); + * @code dhcp_devman_get_status(check_type, context); * * @brief collects DHCP relay status info. * + * @param check_type Type of validation + * @param context pointer to device (interface) context + * * @return DHCP_MON_STATUS_HEALTHY, DHCP_MON_STATUS_UNHEALTHY, or DHCP_MON_STATUS_INDETERMINATE */ -dhcp_mon_status_t dhcp_devman_get_status(); +dhcp_mon_status_t dhcp_devman_get_status(dhcp_mon_check_t check_type, dhcp_device_context_t *context); + +/** + * @code dhcp_devman_update_snapshot(context); + * + * @param context Device (interface) context + * + * @brief Update device/interface counters snapshot + */ +void dhcp_devman_update_snapshot(dhcp_device_context_t *context); /** - * @code dhcp_devman_print_status(); + * @code dhcp_devman_print_status(context, type); * * @brief prints status counters to syslog * + * @param context pointer to device (interface) context + * @param type Counter type to be printed + * * @return none */ -void dhcp_devman_print_status(); +void dhcp_devman_print_status(dhcp_device_context_t *context, dhcp_counters_type_t type); #endif /* DHCP_DEVMAN_H_ */ diff --git a/src/dhcpmon/src/dhcp_mon.c b/src/dhcpmon/src/dhcp_mon.c index dc0a7d94f149..74d9869741d1 100644 --- a/src/dhcpmon/src/dhcp_mon.c +++ b/src/dhcpmon/src/dhcp_mon.c @@ -16,8 +16,17 @@ #include "dhcp_mon.h" #include "dhcp_devman.h" +/** DHCP device/interface state */ +typedef struct +{ + dhcp_mon_check_t check_type; /** check type */ + dhcp_device_context_t* (*get_context)(); /** functor to a device context accessor function */ + int count; /** count in the number of unhealthy checks */ + const char *msg; /** message to be printed if unhealthy state is determined */ +} dhcp_mon_state_t; + /** window_interval_sec monitoring window for dhcp relay health checks */ -static int window_interval_sec = 12; +static int window_interval_sec = 18; /** dhcp_unhealthy_max_count max count of consecutive unhealthy statuses before reporting to syslog */ static int dhcp_unhealthy_max_count = 10; /** libevent base struct */ @@ -28,6 +37,25 @@ static struct event *ev_timeout = NULL; static struct event *ev_sigint; /** libevent SIGTERM signal event struct */ static struct event *ev_sigterm; +/** libevent SIGUSR1 signal event struct */ +static struct event *ev_sigusr1; + +/** DHCP monitor state data for aggregate device for mgmt device */ +static dhcp_mon_state_t state_data[] = { + [0] = { + .check_type = DHCP_MON_CHECK_POSITIVE, + .get_context = dhcp_devman_get_agg_dev, + .count = 0, + .msg = "dhcpmon detected disparity in DHCP Relay behavior. Duration: %d (sec) for vlan: '%s'\n" + }, + [1] = { + .check_type = DHCP_MON_CHECK_NEGATIVE, + .get_context = dhcp_devman_get_mgmt_dev, + .count = 0, + .msg = "dhcpmon detected DHCP packets traveling through mgmt interface (please check BGP routes.)" + " Duration: %d (sec) for intf: '%s'\n" + } +}; /** * @code signal_callback(fd, event, arg); @@ -36,46 +64,49 @@ static struct event *ev_sigterm; * * @param fd libevent socket * @param event event triggered - * @param arg pointer user provided context (libevent base) + * @param arg pointer to 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(); + syslog(LOG_ALERT, "Received signal: '%s'\n", strsignal(fd)); + dhcp_devman_print_status(NULL, DHCP_COUNTERS_CURRENT); + if ((fd == SIGTERM) || (fd == SIGINT)) { + dhcp_mon_stop(); + } } /** - * @code timeout_callback(fd, event, arg); + * @code check_dhcp_relay_health(state_data); * - * @brief periodic timer call back + * @brief check DHCP relay overall health * - * @param fd libevent socket - * @param event event triggered - * @param arg pointer user provided context (libevent base) + * @param state_data pointer to dhcpmon state data * * @return none */ -static void timeout_callback(evutil_socket_t fd, short event, void *arg) +static void check_dhcp_relay_health(dhcp_mon_state_t *state_data) { - static int count = 0; - dhcp_mon_status_t dhcp_mon_status = dhcp_devman_get_status(); + dhcp_device_context_t *context = state_data->get_context(); + dhcp_mon_status_t dhcp_mon_status = dhcp_devman_get_status(state_data->check_type, context); 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); + if (++state_data->count > dhcp_unhealthy_max_count) { + syslog(LOG_ALERT, state_data->msg, state_data->count * window_interval_sec, context->intf); + dhcp_devman_print_status(context, DHCP_COUNTERS_SNAPSHOT); + dhcp_devman_print_status(context, DHCP_COUNTERS_CURRENT); } break; case DHCP_MON_STATUS_HEALTHY: - if (count > 0) { - count = 0; - } + state_data->count = 0; break; case DHCP_MON_STATUS_INDETERMINATE: + if (state_data->count) { + state_data->count++; + } break; default: syslog(LOG_ERR, "DHCP Relay returned unknown status %d\n", dhcp_mon_status); @@ -83,6 +114,26 @@ static void timeout_callback(evutil_socket_t fd, short event, void *arg) } } +/** + * @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) +{ + for (uint8_t i = 0; i < sizeof(state_data) / sizeof(*state_data); i++) { + check_dhcp_relay_health(&state_data[i]); + } + + dhcp_devman_update_snapshot(NULL); +} + /** * @code dhcp_mon_init(window_sec, max_count); * @@ -116,6 +167,12 @@ int dhcp_mon_init(int window_sec, int max_count) break; } + ev_sigusr1 = evsignal_new(base, SIGUSR1, signal_callback, base); + if (ev_sigusr1 == NULL) { + syslog(LOG_ERR, "Could not create SIGUSER1 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"); @@ -138,10 +195,12 @@ void dhcp_mon_shutdown() event_del(ev_timeout); event_del(ev_sigint); event_del(ev_sigterm); + event_del(ev_sigusr1); event_free(ev_timeout); event_free(ev_sigint); event_free(ev_sigterm); + event_free(ev_sigusr1); event_base_free(base); } @@ -151,7 +210,7 @@ void dhcp_mon_shutdown() * * @brief start monitoring DHCP Relay */ -int dhcp_mon_start(int snaplen) +int dhcp_mon_start(size_t snaplen) { int rv = -1; @@ -171,6 +230,11 @@ int dhcp_mon_start(int snaplen) break; } + if (evsignal_add(ev_sigusr1, NULL) != 0) { + syslog(LOG_ERR, "Could not add SIGUSR1 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"); diff --git a/src/dhcpmon/src/dhcp_mon.h b/src/dhcpmon/src/dhcp_mon.h index 44d361b32ec0..ae8911ab51fc 100644 --- a/src/dhcpmon/src/dhcp_mon.h +++ b/src/dhcpmon/src/dhcp_mon.h @@ -40,7 +40,7 @@ void dhcp_mon_shutdown(); * * @return 0 upon success, otherwise upon failure */ -int dhcp_mon_start(int snaplen); +int dhcp_mon_start(size_t snaplen); /** * @code dhcp_mon_stop(); diff --git a/src/dhcpmon/src/main.c b/src/dhcpmon/src/main.c index 11eab6ee9ea1..bb8c45867f66 100644 --- a/src/dhcpmon/src/main.c +++ b/src/dhcpmon/src/main.c @@ -21,10 +21,10 @@ #include "dhcp_devman.h" /** dhcpmon_default_snaplen: default snap length of packet being captured */ -static const uint32_t dhcpmon_default_snaplen = 65535; +static const size_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; +static const uint32_t dhcpmon_default_health_check_window = 18; /** 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; @@ -40,7 +40,7 @@ static const uint32_t dhcpmon_default_unhealthy_max_count = 10; */ static void usage(const char *prog) { - printf("Usage: %s -id {-iu }+ [-w ]" + printf("Usage: %s -id {-iu }+ -im [-w ]" "[-c ] [-s ] [-d]\n", prog); printf("where\n"); printf("\tsouth interface: is a vlan interface,\n"); @@ -50,7 +50,7 @@ static void usage(const char *prog) 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("\tsnap length: snap length of packet capture (default %ld),\n", dhcpmon_default_snaplen); printf("\t-d: daemonize %s.\n", prog); exit(EXIT_SUCCESS); @@ -109,7 +109,7 @@ int main(int argc, char **argv) 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; + size_t snaplen = dhcpmon_default_snaplen; int make_daemon = 0; setlogmask(LOG_UPTO(LOG_INFO)); @@ -127,7 +127,7 @@ int main(int argc, char **argv) usage(basename(argv[0])); break; case 'i': - if (dhcp_devman_add_intf(argv[i + 1], argv[i][2] == 'u') != 0) { + if (dhcp_devman_add_intf(argv[i + 1], argv[i][2]) != 0) { usage(basename(argv[0])); } i += 2; diff --git a/src/hiredis/.gitignore b/src/hiredis/.gitignore new file mode 100644 index 000000000000..a0991ff4402b --- /dev/null +++ b/src/hiredis/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!Makefile diff --git a/src/hiredis/Makefile b/src/hiredis/Makefile index 746056e51de5..4935a039e0af 100644 --- a/src/hiredis/Makefile +++ b/src/hiredis/Makefile @@ -14,7 +14,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : dpkg-source -x hiredis_$(HIREDIS_VERSION_FULL).dsc pushd hiredis-$(HIREDIS_VERSION) - fakeroot debian/rules -j$(SONIC_CONFIG_MAKE_JOBS) binary + dpkg-buildpackage -rfakeroot -d -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) --admindir $(SONIC_DPKG_ADMINDIR) popd mv $* $(DERIVED_TARGETS) $(DEST)/ diff --git a/src/iccpd/Makefile.am b/src/iccpd/Makefile.am new file mode 100644 index 000000000000..af437a64d6d8 --- /dev/null +++ b/src/iccpd/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = src diff --git a/src/iccpd/autogen.sh b/src/iccpd/autogen.sh new file mode 100755 index 000000000000..c8d0bbe4a251 --- /dev/null +++ b/src/iccpd/autogen.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +libtoolize --force --copy && +autoreconf --force --install -I m4 +rm -Rf autom4te.cache + diff --git a/src/iccpd/configure.ac b/src/iccpd/configure.ac new file mode 100644 index 000000000000..9567d2b5cd7d --- /dev/null +++ b/src/iccpd/configure.ac @@ -0,0 +1,32 @@ +AC_INIT([iccpd],[0.5]) +AC_CONFIG_SRCDIR([]) +AC_CONFIG_AUX_DIR(config) +AM_CONFIG_HEADER(config.h) +AM_INIT_AUTOMAKE([foreign]) +AC_LANG_C +AC_PROG_CC +AC_PROG_LIBTOOL +AC_HEADER_STDC + +AC_ARG_ENABLE(debug, +[ --enable-debug Compile with debugging flags], +[case "${enableval}" in + yes) debug=true ;; + no) debug=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-debug) ;; +esac],[debug=false]) +AM_CONDITIONAL(DEBUG, test x$debug = xtrue) + +CPPFLAGS="-D_FORTIFY_SOURCE=2" + +CFLAGS_COMMON="-Wno-unused-result" + +AC_SUBST(CFLAGS_COMMON) + +AC_CONFIG_FILES([ + Makefile + src/Makefile + src/mclagdctl/Makefile +]) + +AC_OUTPUT diff --git a/src/iccpd/debian/changelog b/src/iccpd/debian/changelog new file mode 100644 index 000000000000..a2b3b066bc82 --- /dev/null +++ b/src/iccpd/debian/changelog @@ -0,0 +1,6 @@ +sonic (0.0.5) stable; urgency=medium + + * Initial release. + + -- Tyler Li Thu, 23 Apr 2020 10:00:00 +0800 + diff --git a/src/iccpd/debian/compat b/src/iccpd/debian/compat new file mode 100644 index 000000000000..f599e28b8ab0 --- /dev/null +++ b/src/iccpd/debian/compat @@ -0,0 +1 @@ +10 diff --git a/src/iccpd/debian/control b/src/iccpd/debian/control new file mode 100644 index 000000000000..3c9334af0a65 --- /dev/null +++ b/src/iccpd/debian/control @@ -0,0 +1,18 @@ +Source: sonic +Maintainer: Tyler Li +Section: net +Priority: optional +Build-Depends: dh-exec (>=0.3), debhelper (>= 9), autotools-dev +Standards-Version: 0.0.5 + +Package: iccpd +Architecture: any +Depends: ${shlibs:Depends} +Description: This package contains Inter-Chassis Control Protocol for SONiC project. + +Package: iccpd-dbg +Architecture: any +Section: debug +Priority: extra +Depends: iccpd (=${binary:Version}) +Description: debugging symbols for iccpd diff --git a/src/iccpd/debian/rules b/src/iccpd/debian/rules new file mode 100755 index 000000000000..81f48423874e --- /dev/null +++ b/src/iccpd/debian/rules @@ -0,0 +1,34 @@ +#!/usr/bin/make -f +# See debhelper(7) (uncomment to enable) +# output every command that modifies files on the build system. +#export DH_VERBOSE = 1 + +# see EXAMPLES in dpkg-buildflags(1) and read /usr/share/dpkg/* +DPKG_EXPORT_BUILDFLAGS = 1 +include /usr/share/dpkg/default.mk + +# see FEATURE AREAS in dpkg-buildflags(1) +#export DEB_BUILD_MAINT_OPTIONS = hardening=+all + +# see ENVIRONMENT in dpkg-buildflags(1) +# package maintainers to append CFLAGS +#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic +# package maintainers to append LDFLAGS +#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed + + +# main packaging script based on dh7 syntax +%: + dh $@ --with autotools-dev + +# dh_make generated override targets +# This is example for Cmake (See https://bugs.debian.org/641051 ) +#override_dh_auto_configure: +# dh_auto_configure -- \ +# -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH) + +override_dh_auto_install: + dh_auto_install --destdir=debian/iccpd + +override_dh_strip: + dh_strip --dbg-package=iccpd-dbg diff --git a/src/iccpd/include/app_csm.h b/src/iccpd/include/app_csm.h new file mode 100644 index 000000000000..a0565556d24c --- /dev/null +++ b/src/iccpd/include/app_csm.h @@ -0,0 +1,73 @@ +/* + * app_csm.h + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef APP_CSM_H_ +#define APP_CSM_H_ + +#include + +#include "../include/mlacp_fsm.h" + +struct CSM; + +enum APP_CONNECTION_STATE +{ + APP_NONEXISTENT, + APP_RESET, + APP_CONNSENT, + APP_CONNREC, + APP_CONNECTING, + APP_OPERATIONAL +}; + +typedef enum APP_CONNECTION_STATE APP_CONNECTION_STATE_E; + +struct AppCSM +{ + struct mLACP mlacp; + APP_CONNECTION_STATE_E current_state; + + uint32_t rx_connect_msg_id; + uint32_t tx_connect_msg_id; + uint32_t invalid_msg_id; + + TAILQ_HEAD(app_msg_list, Msg) app_msg_list; + + uint8_t invalid_msg : 1; + uint8_t nak_msg : 1; +}; + +void app_csm_init(struct CSM*, int all); +void app_csm_finalize(struct CSM*); +void app_csm_transit(struct CSM*); +int app_csm_prepare_iccp_msg(struct CSM*, char*, size_t); +void app_csm_enqueue_msg(struct CSM*, struct Msg*); +struct Msg* app_csm_dequeue_msg(struct CSM*); +void app_csm_correspond_from_msg(struct CSM*, struct Msg*); +void app_csm_correspond_from_connect_msg(struct CSM*, struct Msg*); +void app_csm_correspond_from_connect_ack_msg(struct CSM*, struct Msg*); +int app_csm_prepare_nak_msg(struct CSM*, char*, size_t); +int app_csm_prepare_connect_msg(struct CSM*, char*, size_t); +int app_csm_prepare_connect_ack_msg(struct CSM*, char*, size_t); + +#endif /* APP_CSM_H_ */ diff --git a/src/iccpd/include/cmd_option.h b/src/iccpd/include/cmd_option.h new file mode 100644 index 000000000000..ca5582cfcc60 --- /dev/null +++ b/src/iccpd/include/cmd_option.h @@ -0,0 +1,84 @@ +/* + * cmd_option.h + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef CMD_OPTION_H_ +#define CMD_OPTION_H_ + +#include +#include +#include +#include +#include +#include + +#define OPTION_MAX_LEN 256 +#define MSG_LEN 81 + +#define CMD_OPTION_PARSER_INIT_VALUE \ + { \ + .log_file_path = "/var/log/iccpd.log", \ + .pid_file_path = "/var/run/iccpd/iccpd.pid", \ + .cmd_file_path = "/var/run/iccpd/iccpd.vty", \ + .config_file_path = "/etc/iccpd/iccpd.conf", \ + .mclagdctl_file_path = "/var/run/iccpd/mclagdctl.sock", \ + .console_log = 0, \ + .telnet_port = 2015, \ + .init = cmd_option_parser_init, \ + .finalize = cmd_option_parser_finalize, \ + .dump_usage = cmd_option_parser_dump_usage, \ + .parse = cmd_option_parser_parse, \ + } + +struct CmdOption +{ + char* desc; + char* option; + char* parameter; + LIST_ENTRY(CmdOption) next; +}; + +struct CmdOptionParser +{ + char* log_file_path; + char* pid_file_path; + char* cmd_file_path; + char* config_file_path; + char *mclagdctl_file_path; + uint8_t console_log; + uint16_t telnet_port; + LIST_HEAD(option_list, CmdOption) option_list; + int (*parse)(struct CmdOptionParser*, int, char*[]); + void (*init)(struct CmdOptionParser*); + void (*finalize)(struct CmdOptionParser*); + void (*dump_usage)(struct CmdOptionParser*, char*); +}; + +int cmd_option_parser_parse(struct CmdOptionParser*, int, char*[]); +struct CmdOption* cmd_option_add(struct CmdOptionParser*, char*); +struct CmdOption* cmd_option_find(struct CmdOptionParser*, char*); +void cmd_option_delete(struct CmdOption*); +void cmd_option_parser_init(struct CmdOptionParser*); +void cmd_option_parser_finalize(struct CmdOptionParser*); +void cmd_option_parser_dump_usage(struct CmdOptionParser*, char*); + +#endif /* CMD_OPTION_H_ */ diff --git a/src/iccpd/include/iccp_cli.h b/src/iccpd/include/iccp_cli.h new file mode 100644 index 000000000000..c85fc4316b5f --- /dev/null +++ b/src/iccpd/include/iccp_cli.h @@ -0,0 +1,67 @@ +/* + * iccp_cli.h + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef _ICCP_CLI_H +#define _ICCP_CLI_H + +#include + +struct CSM; + +typedef enum +{ + QU_TYPE_NONE, + QU_TYPE_MLAG_ADD_PO +} cli_queue_type_et; + +typedef struct cli_param_queue +{ + char ifname[16]; + cli_queue_type_et type; + int param; + int itf_add; + LIST_ENTRY(cli_param_queue) cli_queue_next; +} cli_param_queue_st; + +#define MCLAG_ID_STR "mclag_id" +#define LOCAL_IP_STR "local_ip" +#define PEER_IP_STR "peer_ip" +#define PEER_LINK_STR "peer_link" +#define MCLAG_INTF_STR "mclag_interface" +#define SYSTEM_MAC_STR "system_mac" + +int set_mc_lag_id(struct CSM* csm, uint16_t domain); +int set_peer_link(int mid, const char* ifname); +int set_local_address(int mid, const char* addr); +int set_peer_address(int mid, const char* addr); +int unset_mc_lag_id(struct CSM* csm, uint16_t domain); +int unset_peer_link(int mid); +int unset_local_address(int mid); +int unset_peer_address(int mid); + +int iccp_cli_attach_mclag_domain_to_port_channel(int domain, const char* ifname); +int iccp_cli_detach_mclag_domain_to_port_channel(const char* ifname); +int set_local_system_id(const char* mac); +int unset_local_system_id( ); + +#endif diff --git a/src/iccpd/include/iccp_cmd.h b/src/iccpd/include/iccp_cmd.h new file mode 100644 index 000000000000..01f37456b71d --- /dev/null +++ b/src/iccpd/include/iccp_cmd.h @@ -0,0 +1,29 @@ +/* + * iccp_cmd.h + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef ICCP_CMD_H_ +#define ICCP_CMD_H_ + +int iccp_config_from_file(char *config_default_dir); + +#endif /* ICCP_CMD_H_ */ diff --git a/src/iccpd/include/iccp_cmd_show.h b/src/iccpd/include/iccp_cmd_show.h new file mode 100644 index 000000000000..a41fbadf8c77 --- /dev/null +++ b/src/iccpd/include/iccp_cmd_show.h @@ -0,0 +1,36 @@ +/* + * iccp_cmd_show.h + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef _ICCP_CMD_SHOW_H +#define _ICCP_CMD_SHOW_H + +#define ICCP_MAX_PORT_NAME 20 +#define ICCP_MAX_IP_STR_LEN 16 + +extern int iccp_mclag_config_dump(char * *buf, int *num, int mclag_id); +extern int iccp_arp_dump(char * *buf, int *num, int mclag_id); +extern int iccp_ndisc_dump(char * *buf, int *num, int mclag_id); +extern int iccp_mac_dump(char * *buf, int *num, int mclag_id); +extern int iccp_local_if_dump(char * *buf, int *num, int mclag_id); +extern int iccp_peer_if_dump(char * *buf, int *num, int mclag_id); +#endif diff --git a/src/iccpd/include/iccp_consistency_check.h b/src/iccpd/include/iccp_consistency_check.h new file mode 100644 index 000000000000..6fa8ea47e2f4 --- /dev/null +++ b/src/iccpd/include/iccp_consistency_check.h @@ -0,0 +1,43 @@ +/* + * iccp_consistency_check.c + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + * + */ + +#ifndef _ICCP_CONSISTENCY_CHECK_H +#define _ICCP_CONSISTENCY_CHECK_H + + +enum Reason_ID +{ + REASON_NONE = 0, + REASON_INTERRFACE_MODE_IS_ASYNC, + REASON_PEER_IF_IP_IS_ASYNC, + REASON_PEER_IF_VLAN_IS_ASYNC, + REASON_MAX_ARRAY_SIZE +}; + +extern const char *reasons[]; + +enum Reason_ID iccp_consistency_check(char* ifname); + + +#endif diff --git a/src/iccpd/include/iccp_csm.h b/src/iccpd/include/iccp_csm.h new file mode 100644 index 000000000000..01e424d13271 --- /dev/null +++ b/src/iccpd/include/iccp_csm.h @@ -0,0 +1,168 @@ +/* + * iccp_csm.h + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef ICCP_CSM_H_ +#define ICCP_CSM_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../include/app_csm.h" +#include "../include/msg_format.h" +#include "../include/port.h" + +#define CSM_BUFFER_SIZE 65536 + +#ifndef IFNAMSIZ +#define IFNAMSIZ 16 +#endif /*IFNAMSIZ*/ + +#ifndef INET_ADDRSTRLEN +#define INET_ADDRSTRLEN 16 +#endif /* INET_ADDRSTRLEN */ +#ifndef INET6_ADDRSTRLEN +#define INET6_ADDRSTRLEN 46 +#endif /* INET6_ADDRSTRLEN */ +/* For socket binding */ +#define ICCP_TCP_PORT 8888 +#define MAX_ACCEPT_CONNETIONS 20 + +/* LDP message ID */ +extern uint32_t ICCP_MSG_ID; + +/* Global Buffer */ +extern char g_csm_buf[CSM_BUFFER_SIZE]; + +struct IccpInfo +{ + uint32_t icc_rg_id; + char sender_name[MAX_L_ICC_SENDER_NAME]; + uint32_t status_code; + uint8_t peer_capability_flag : 1; + uint8_t peer_rg_connect_flag : 1; + uint8_t sender_capability_flag : 1; + uint8_t sender_rg_connect_flag : 1; + uint32_t rejected_msg_id; +}; + +/* Receive message node */ +struct Msg +{ + char* buf; + size_t len; + TAILQ_ENTRY(Msg) tail; +}; + +/* Connection state */ +enum ICCP_CONNECTION_STATE +{ + ICCP_NONEXISTENT, + ICCP_INITIALIZED, + ICCP_CAPSENT, + ICCP_CAPREC, + ICCP_CONNECTING, + ICCP_OPERATIONAL +}; + +typedef enum ICCP_CONNECTION_STATE ICCP_CONNECTION_STATE_E; + +typedef enum stp_role_type_e +{ + STP_ROLE_NONE, /* mstp do nothing*/ + STP_ROLE_ACTIVE, /* mstp report port state*/ + STP_ROLE_STANDBY /* mstp fwd bpdu & set port state*/ +} stp_role_type_et; + +/* Connection state machine instance */ +struct CSM +{ + int mlag_id; + + /* Socket info */ + int sock_fd; + pthread_mutex_t conn_mutex; + time_t connTimePrev; + time_t heartbeat_send_time; + time_t heartbeat_update_time; + time_t peer_warm_reboot_time; + time_t warm_reboot_disconn_time; + char peer_itf_name[IFNAMSIZ]; + char peer_ip[INET_ADDRSTRLEN]; + char sender_ip[INET_ADDRSTRLEN]; + void* sock_read_event_ptr; + + /* Msg queue */ + TAILQ_HEAD(msg_list, Msg) msg_list; + + /* STP role */ + stp_role_type_et role_type; + + /* Peers msg */ + struct LocalInterface* peer_link_if; + struct IccpInfo iccp_info; + struct AppCSM app_csm; + ICCP_CONNECTION_STATE_E current_state; + + /* Statistic info */ + uint64_t icc_msg_in_count; /* ICC message input count */ + uint64_t icc_msg_out_count; /* ICC message Output count */ + uint64_t u_msg_in_count; /* Unknown message Input count */ + uint64_t i_msg_in_count; /* Illegal message Input count */ + + /* Log */ + struct MsgLog msg_log; + + LIST_ENTRY(CSM) next; + LIST_HEAD(csm_if_list, If_info) if_bind_list; +}; +int iccp_csm_send(struct CSM*, char*, int); +int iccp_csm_init_msg(struct Msg**, char*, int); +int iccp_csm_prepare_nak_msg(struct CSM*, char*, size_t); +int iccp_csm_prepare_iccp_msg(struct CSM*, char*, size_t); +int iccp_csm_prepare_capability_msg(struct CSM*, char*, size_t); +int iccp_csm_prepare_rg_connect_msg(struct CSM*, char*, size_t); +int iccp_csm_prepare_rg_disconnect_msg(struct CSM*, char*, size_t); +struct Msg* iccp_csm_dequeue_msg(struct CSM*); +void *iccp_get_csm(); +void iccp_csm_init(struct CSM*); +void iccp_csm_transit(struct CSM*); +void iccp_csm_finalize(struct CSM*); +void iccp_csm_status_reset(struct CSM*, int); +void iccp_csm_stp_role_count(struct CSM *csm); +void iccp_csm_msg_list_finalize(struct CSM*); +void iccp_csm_enqueue_msg(struct CSM*, struct Msg*); +void iccp_csm_fill_icc_rg_id_tlv(struct CSM*, ICCHdr*); +void iccp_csm_correspond_from_msg(struct CSM*, struct Msg*); +void iccp_csm_correspond_from_capability_msg(struct CSM*, struct Msg*); +void iccp_csm_correspond_from_rg_connect_msg(struct CSM*, struct Msg*); +void iccp_csm_correspond_from_rg_disconnect_msg(struct CSM*, struct Msg*); + +int mlacp_bind_port_channel_to_csm(struct CSM* csm, const char *ifname); + +#endif /* ICCP_CSM_H_ */ diff --git a/src/iccpd/include/iccp_ifm.h b/src/iccpd/include/iccp_ifm.h new file mode 100644 index 000000000000..bbb1af67ee90 --- /dev/null +++ b/src/iccpd/include/iccp_ifm.h @@ -0,0 +1,42 @@ +/* + * iccp_ifm.h + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef ICCP_IFM_H +#define ICCP_IFM_H + +#include + +int iccp_sys_local_if_list_get_init(); + +int iccp_neigh_get_init(); + +void do_arp_update_from_reply_packet(unsigned int ifindex, unsigned int addr, uint8_t mac_addr[ETHER_ADDR_LEN]); +void do_ndisc_update_from_reply_packet(unsigned int ifindex, char *ipv6_addr, uint8_t mac_addr[ETHER_ADDR_LEN]); + +int do_one_neigh_request(struct nlmsghdr *n); + +void iccp_from_netlink_port_state_handler( char * ifname, int state); + +void iccp_parse_if_vlan_info_from_netlink(struct nlmsghdr *n); +#endif // LACP_IFM_H + diff --git a/src/iccpd/include/iccp_netlink.h b/src/iccpd/include/iccp_netlink.h new file mode 100644 index 000000000000..a4f321736d0c --- /dev/null +++ b/src/iccpd/include/iccp_netlink.h @@ -0,0 +1,67 @@ +/* Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef ICCP_NETLINK_H +#define ICCP_NETLINK_H +#include +#include +#include +#include +#include +#include + +#include + +#include "../include/system.h" +#include "../include/port.h" +#include +#include + +#define NDISC_NEIGHBOUR_ADVERTISEMENT 136 +#define ND_OPT_TARGET_LL_ADDR 2 +#define NEXTHDR_ICMP 58 + +struct nd_msg +{ + struct icmp6_hdr icmph; + struct in6_addr target; + __u8 opt[0]; +}; + +struct in6_pktinfo +{ + struct in6_addr ipi6_addr; /* src/dst IPv6 address */ + unsigned int ipi6_ifindex; /* send/recv interface index */ +}; + +int iccp_get_port_member_list(struct LocalInterface* lif); +void iccp_event_handler_obj_input_newlink(struct nl_object *obj, void *arg); +void iccp_event_handler_obj_input_dellink(struct nl_object *obj, void *arg); +int iccp_system_init_netlink_socket(); +void iccp_system_dinit_netlink_socket(); +int iccp_init_netlink_event_fd(struct System *sys); +int iccp_handle_events(struct System * sys); +void update_if_ipmac_on_standby(struct LocalInterface* lif_po); +int iccp_sys_local_if_list_get_addr(); +int iccp_netlink_neighbor_request(int family, uint8_t *addr, int add, uint8_t *mac, char *portname); +int iccp_check_if_addr_from_netlink(int family, uint8_t *addr, struct LocalInterface *lif); + +#endif + diff --git a/src/iccpd/include/logger.h b/src/iccpd/include/logger.h new file mode 100644 index 000000000000..a90fece2a4d9 --- /dev/null +++ b/src/iccpd/include/logger.h @@ -0,0 +1,70 @@ +/* + * logger.h + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef LOGGER_H_ +#define LOGGER_H_ + +#include +#include + +#include "../include/cmd_option.h" + +typedef enum _iccpd_log_level_t +{ + CRITICAL_LOG_LEVEL = 0, + ERR_LOG_LEVEL = 1, + WARN_LOG_LEVEL = 2, + NOTICE_LOG_LEVEL = 3, + INFO_LOG_LEVEL = 4, + DEBUG_LOG_LEVEL = 5 +} _iccpd_log_level_t; + + +#define LOGBUF_SIZE 1024 +#define ICCPD_UTILS_SYSLOG (syslog) + +#define ICCPD_LOG_CRITICAL(tag, format, args ...) write_log(CRITICAL_LOG_LEVEL, tag, format, ## args) +#define ICCPD_LOG_ERR(tag, format, args ...) write_log(ERR_LOG_LEVEL, tag, format, ## args) +#define ICCPD_LOG_WARN(tag, format, args ...) write_log(WARN_LOG_LEVEL, tag, format, ## args) +#define ICCPD_LOG_NOTICE(tag, format, args ...) write_log(NOTICE_LOG_LEVEL, tag, format, ## args) +#define ICCPD_LOG_INFO(tag, format, args ...) write_log(INFO_LOG_LEVEL, tag, format, ## args) +#define ICCPD_LOG_DEBUG(tag, format, args ...) write_log(DEBUG_LOG_LEVEL, tag, format, ## args) + +struct LoggerConfig +{ + uint8_t console_log_enabled; + uint8_t log_level; + uint8_t init; +}; + +struct LoggerConfig* logger_get_configuration(); +void logger_set_configuration(int log_level); +char* log_level_to_string(int level); +void log_setup(char* progname, char* path); +void log_finalize(); +void log_init(struct CmdOptionParser* parser); +void write_log(const int level, const char* tag, const char *format, ...); + +#endif /* LOGGER_H_ */ + + diff --git a/src/iccpd/include/mlacp_fsm.h b/src/iccpd/include/mlacp_fsm.h new file mode 100644 index 000000000000..b335e78cd007 --- /dev/null +++ b/src/iccpd/include/mlacp_fsm.h @@ -0,0 +1,109 @@ +/* + * mlacp_fsm.h + * mLACP finite state machine handler. + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef _MLACP_FSM_H +#define _MLACP_FSM_H + +#include "../include/port.h" + +#define MLCAP_SYNC_PHY_DEV_SEC 1 /*every 1 sec*/ + +#define MLACP(csm_ptr) (csm_ptr->app_csm.mlacp) + +struct CSM; + +enum MLACP_APP_STATE +{ + MLACP_STATE_INIT, + MLACP_STATE_STAGE1, + MLACP_STATE_STAGE2, + MLACP_STATE_EXCHANGE, + MLACP_STATE_ERROR, +}; + +typedef enum MLACP_APP_STATE MLACP_APP_STATE_E; + +/* for sender only*/ +enum MLACP_SYNC_STATE +{ + MLACP_SYNC_SYSCONF=0, + MLACP_SYNC_AGGCONF, + MLACP_SYNC_AGGSTATE, + MLACP_SYNC_AGGINFO, + MLACP_SYNC_PEERLINKINFO, + MLACP_SYNC_ARP_INFO, + MLACP_SYNC_NDISC_INFO, + MLACP_SYNC_DONE, +}; + +typedef enum MLACP_SYNC_STATE MLACP_SYNC_STATE_E; + +struct Remote_System +{ + uint8_t system_id[ETHER_ADDR_LEN]; + uint16_t system_priority; + uint32_t node_id; +}; + +struct mLACP +{ + int id; + int sync_req_num; + + MLACP_APP_STATE_E current_state; + MLACP_SYNC_STATE_E sync_state; + + uint8_t wait_for_sync_data; + uint8_t need_to_sync; + uint8_t node_id; + uint8_t system_id[ETHER_ADDR_LEN]; + uint16_t system_priority; + uint8_t system_config_changed; + + struct Remote_System remote_system; + const char* error_msg; + TAILQ_HEAD(mlacp_msg_list, Msg) mlacp_msg_list; + TAILQ_HEAD(arp_msg_list, Msg) arp_msg_list; + TAILQ_HEAD(arp_info_list, Msg) arp_list; + TAILQ_HEAD(ndisc_msg_list, Msg) ndisc_msg_list; + TAILQ_HEAD(ndisc_info_list, Msg) ndisc_list; + TAILQ_HEAD(mac_msg_list, Msg) mac_msg_list; + TAILQ_HEAD(mac_info_list, Msg) mac_list; + + LIST_HEAD(lif_list, LocalInterface) lif_list; + LIST_HEAD(lif_purge_list, LocalInterface) lif_purge_list; + LIST_HEAD(pif_list, PeerInterface) pif_list; +}; + +void mlacp_init(struct CSM* csm, int all); +void mlacp_finalize(struct CSM* csm); +void mlacp_fsm_transit(struct CSM* csm); +void mlacp_enqueue_msg(struct CSM*, struct Msg*); +struct Msg* mlacp_dequeue_msg(struct CSM*); + +/* from app_csm*/ +extern int mlacp_bind_local_if(struct CSM* csm, struct LocalInterface* local_if); +extern int mlacp_unbind_local_if(struct LocalInterface* local_if); + +#endif /* _MLACP_HANDLER_H */ diff --git a/src/iccpd/include/mlacp_link_handler.h b/src/iccpd/include/mlacp_link_handler.h new file mode 100644 index 000000000000..624b4111a7ee --- /dev/null +++ b/src/iccpd/include/mlacp_link_handler.h @@ -0,0 +1,60 @@ +/* + * mlacp_link_handler.h + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef __MLACP_LINK_HANDLER__ +#define __MLACP_LINK_HANDLER__ + +#include "../include/iccp_csm.h" +#include "../include/mlacp_tlv.h" + +/***************************************** +* Link Handler +* +* ***************************************/ +void mlacp_portchannel_state_handler(struct CSM* csm, struct LocalInterface* local_if, int po_state); +void mlacp_peer_conn_handler(struct CSM* csm); +void mlacp_peer_disconn_handler(struct CSM* csm); +void mlacp_peerlink_up_handler(struct CSM* csm); +void mlacp_peerlink_down_handler(struct CSM* csm); +void update_stp_peer_link(struct CSM *csm, struct PeerInterface *peer_if, int po_state, int new_create); +void update_peerlink_isolate_from_pif(struct CSM *csm, struct PeerInterface *pif, int po_state, int new_create); +void mlacp_mlag_link_add_handler(struct CSM *csm, struct LocalInterface *lif); +void mlacp_mlag_link_del_handler(struct CSM *csm, struct LocalInterface *lif); +void set_peerlink_mlag_port_learn(struct LocalInterface *lif, int enable); +void peerlink_port_isolate_cleanup(struct CSM* csm); +void update_peerlink_isolate_from_all_csm_lif(struct CSM* csm); + +void del_mac_from_chip(struct MACMsg *mac_msg); +void add_mac_to_chip(struct MACMsg *mac_msg, uint8_t mac_type); +uint8_t set_mac_local_age_flag(struct CSM *csm, struct MACMsg *mac_msg, uint8_t set); +void iccp_get_fdb_change_from_syncd(void); + +extern int mclagd_ctl_sock_create(); +extern int mclagd_ctl_sock_accept(int fd); +extern int mclagd_ctl_interactive_process(int client_fd); +extern int parseMacString(const char *str_mac, uint8_t *bin_mac); +char *show_ip_str(uint32_t ipv4_addr); +char *show_ipv6_str(char *ipv6_addr); + +void syncd_info_close(); +int iccp_connect_syncd(); +#endif diff --git a/src/iccpd/include/mlacp_sync_prepare.h b/src/iccpd/include/mlacp_sync_prepare.h new file mode 100644 index 000000000000..17cd8f260155 --- /dev/null +++ b/src/iccpd/include/mlacp_sync_prepare.h @@ -0,0 +1,56 @@ +/* + * mlacp_sync_prepare.h + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef __MLACP_SYNC_PREPARE__ +#define __MLACP_SYNC_PREPARE__ + +struct CSM; +/***************************************** +* Tool Function +* +* ***************************************/ +void update_system_id(struct CSM* csm); + +/***************************************** +* LACP Sync +* +* ***************************************/ +int mlacp_sync_with_kernel_callback(); + +/***************************************** +* MLACP Sync +* +* ***************************************/ +int mlacp_prepare_for_sync_request_tlv(struct CSM* csm, char* buf, size_t max_buf_size); +int mlacp_prepare_for_sync_data_tlv(struct CSM* csm, char* buf, size_t max_buf_size, int end); +int mlacp_prepare_for_sys_config(struct CSM* csm, char* buf, size_t max_buf_size); +int mlacp_prepare_for_mac_info_to_peer(struct CSM* csm, char* buf, size_t max_buf_size, struct MACMsg* mac_msg, int count); +int mlacp_prepare_for_arp_info(struct CSM* csm, char* buf, size_t max_buf_size, struct ARPMsg* arp_msg, int count); +int mlacp_prepare_for_ndisc_info(struct CSM *csm, char *buf, size_t max_buf_size, struct NDISCMsg *ndisc_msg, int count); +int mlacp_prepare_for_heartbeat(struct CSM* csm, char* buf, size_t max_buf_size); +int mlacp_prepare_for_Aggport_state(struct CSM* csm, char* buf, size_t max_buf_size, struct LocalInterface* local_if); +int mlacp_prepare_for_Aggport_config(struct CSM* csm, char* buf, size_t max_buf_size, struct LocalInterface* lif, int purge_flag); +int mlacp_prepare_for_port_channel_info(struct CSM* csm, char* buf, size_t max_buf_size, struct LocalInterface* port_channel); +int mlacp_prepare_for_port_peerlink_info(struct CSM* csm, char* buf, size_t max_buf_size, struct LocalInterface* peerlink_port); +int iccp_netlink_if_hwaddr_set(uint32_t ifindex, uint8_t *addr, unsigned int addr_len); +#endif \ No newline at end of file diff --git a/src/iccpd/include/mlacp_sync_update.h b/src/iccpd/include/mlacp_sync_update.h new file mode 100644 index 000000000000..2a5d5b598d05 --- /dev/null +++ b/src/iccpd/include/mlacp_sync_update.h @@ -0,0 +1,50 @@ +/* + * + * mlacp_sync_update.h + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef __MLACP_SYNC_UPDATE__ +#define __MLACP_SYNC_UPDATE__ + +#include "iccp_csm.h" +#include "mlacp_tlv.h" + +/***************************************** +* FSM Sync Update API +* +* ***************************************/ +int mlacp_fsm_update_system_conf(struct CSM* csm, mLACPSysConfigTLV* tlv); + +int mlacp_fsm_update_Aggport_state(struct CSM* csm, mLACPAggPortStateTLV* tlv); + +int mlacp_fsm_update_arp_info(struct CSM* csm, struct mLACPARPInfoTLV* tlv); +int mlacp_fsm_update_ndisc_info(struct CSM *csm, struct mLACPNDISCInfoTLV* tlv); + +int mlacp_fsm_update_heartbeat(struct CSM* csm, struct mLACPHeartbeatTLV* tlv); + +int mlacp_fsm_update_warmboot(struct CSM* csm, struct mLACPWarmbootTLV* tlv); +void mlacp_enqueue_arp(struct CSM* csm, struct Msg* msg); +void mlacp_enqueue_ndisc(struct CSM *csm, struct Msg* msg); +int mlacp_fsm_update_Agg_conf(struct CSM* csm, mLACPAggConfigTLV* portconf); +int mlacp_fsm_update_port_channel_info(struct CSM* csm, struct mLACPPortChannelInfoTLV* tlv); +int mlacp_fsm_update_peerlink_info(struct CSM* csm, struct mLACPPeerLinkInfoTLV* tlv); +int mlacp_fsm_update_mac_info_from_peer(struct CSM* csm, struct mLACPMACInfoTLV* tlv); +#endif \ No newline at end of file diff --git a/src/iccpd/include/mlacp_tlv.h b/src/iccpd/include/mlacp_tlv.h new file mode 100644 index 000000000000..7d3a4e18e4e2 --- /dev/null +++ b/src/iccpd/include/mlacp_tlv.h @@ -0,0 +1,475 @@ +/* + * mlacp_tlv.h + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef MLACP_TLV_H_ +#define MLACP_TLV_H_ + +#include + +#include "../include/msg_format.h" +#include "../include/port.h" + +#define MLACP_SYSCONF_NODEID_MSB_MASK 0x80 +#define MLACP_SYSCONF_NODEID_NODEID_MASK 0x70 +#define MLACP_SYSCONF_NODEID_FREE_MASK 0x0F + +/* + * RFC 7275 + * 7.2.3. mLACP System Config TLV + * [Page 51] + */ +struct mLACPSysConfigTLV +{ + ICCParameter icc_parameter; + /* [IEEE-802.1AX], Section 5.3.2. */ + uint8_t sys_id[ETHER_ADDR_LEN]; + /* [IEEE-802.1AX], Section 5.3.2. */ + uint16_t sys_priority; + /* + * RFC 7275 + * 7.2.3. mLACP System Config TLV + * [Page 51] + */ + uint8_t node_id; +} __attribute__ ((packed)); + +typedef struct mLACPSysConfigTLV mLACPSysConfigTLV; + +/* + * RFC 7275 + * 7.2.4. mLACP Aggregator Config TLV + * [Page 52] + * NOTE: In this project, Aggregator configuration and state TLV is not support. + */ +struct mLACPAggConfigTLV +{ + ICCParameter icc_parameter; + /* + * RFC 7275 + * 7.2.4. mLACP Aggregator Config TLV + * [Page 53] + */ + uint8_t ro_id[8]; + /* [IEEE-802.1AX], Section 5.4.6. */ + uint16_t agg_id; + /* + * RFC 7275 + * 7.2.4. mLACP Aggregator Config TLV + * [Page 53] + */ + uint8_t mac_addr[ETHER_ADDR_LEN]; + /* [IEEE-802.1AX], Section 5.3.5. */ + uint16_t actor_key; + /* + * RFC 7275 + * 7.2.4. mLACP Aggregator Config TLV + * [Page 53] + */ + uint16_t member_ports_priority; + uint8_t flags; + /* + * RFC 7275 + * 7.2.4. mLACP Aggregator Config TLV + * [Page 54] + */ + uint8_t agg_name_len; + char agg_name[MAX_L_PORT_NAME]; +} __attribute__ ((packed)); + +typedef struct mLACPAggConfigTLV mLACPAggConfigTLV; + +/* + * RFC 7275 + * 7.2.4. mLACP Port Config TLV + * [Page 54] + */ +struct mLACPPortConfigTLV +{ + ICCParameter icc_parameter; + /* [IEEE-802.1AX], Section 5.3.4. */ + uint16_t port_num; + /* + * RFC 7275 + * 7.2.5. mLACP Port Config TLV + * [Page 55] + */ + uint8_t mac_addr[ETHER_ADDR_LEN]; + /* [IEEE-802.1AX], Section 5.3.5. */ + uint16_t actor_key; + /* [IEEE-802.1AX], Section 5.3.4. */ + uint16_t port_priority; + /* IF-MIB [RFC2863] */ + uint32_t port_speed; + /* + * RFC 7275 + * 7.2.4. mLACP Port Config TLV + * [Page 55] + */ + uint8_t flags; + /* + * RFC 7275 + * 7.2.4. mLACP Port Config TLV + * [Page 56] + */ + uint8_t port_name_len; + /* IF-MIB [RFC2863] */ + char port_name[MAX_L_PORT_NAME]; + + /* NOS */ + uint8_t l3_mode; +} __attribute__ ((packed)); + +typedef struct mLACPPortConfigTLV mLACPPortConfigTLV; + +/* + * RFC 7275 + * 7.2.6. mLACP Port Priority TLV + * [Page 56] + */ +struct mLACPPortPriorityTLV +{ + ICCParameter icc_parameter; + /* + * RFC 7275 + * 7.2.6. mLACP Port Priority TLV + * [Page 57] + */ + uint16_t op_code; + /* [IEEE-802.1AX], Section 5.3.4. */ + uint16_t port_num; + /* [IEEE-802.1AX], Section 5.4.6. */ + uint16_t agg_id; + /* [IEEE-802.1AX], Section 5.3.4. */ + uint16_t last_port_priority; + uint16_t current_port_priority; +} __attribute__ ((packed)); + +typedef struct mLACPPortPriorityTLV mLACPPortPriorityTLV; + +/* + * RFC 7275 + * 7.2.7. mLACP Port State TLV + * [Page 58] + */ +struct mLACPPortStateTLV +{ + ICCParameter icc_parameter; + /* [IEEE-802.1AX], Section 5.4.2.2, item r. */ + uint8_t partner_sys_id[ETHER_ADDR_LEN]; + /* [IEEE-802.1AX], Section 5.4.2.2, item q. */ + uint16_t partner_sys_priority; + /* [IEEE-802.1AX], Section 5.4.2.2, item u. */ + uint16_t partner_port_num; + /* [IEEE-802.1AX], Section 5.4.2.2, item t. */ + uint16_t partner_port_priority; + /* [IEEE-802.1AX], Section 5.4.2.2, item s. */ + uint16_t partner_key; + /* [IEEE-802.1AX], Section 5.4.2.2, item v. */ + uint8_t partner_state; + /* [IEEE-802.1AX], Section 5.4.2.2, item m. */ + uint8_t actor_state; + /* [IEEE-802.1AX], Section 5.3.4. */ + uint16_t actor_port_num; + /* [IEEE-802.1AX], Section 5.3.5. */ + uint16_t actor_key; + /* [IEEE-802.1AX], Section 5.4.8 */ + uint8_t selected; + /* + * RFC 7275 + * 7.2.7. mLACP Port State TLV + * [Page 60] + */ + uint8_t port_state; + /* [IEEE-802.1AX], Section 5.4.6. */ + uint16_t agg_id; + + /* NOS */ + uint16_t port_id; + uint8_t l3_mode; + uint8_t is_peer_link; +} __attribute__ ((packed)); + +typedef struct mLACPPortStateTLV mLACPPortStateTLV; + +/* + * RFC 7275 + * 7.2.8. mLACP Aggregator State TLV + * [Page 60] + * NOTE: In this project, Aggregator configuration and state TLV is not support. + */ +struct mLACPAggPortStateTLV +{ + ICCParameter icc_parameter; + /* [IEEE-802.1AX], Section 5.4.2.2, item r. */ + uint8_t partner_sys_id[ETHER_ADDR_LEN]; + /* [IEEE-802.1AX], Section 5.4.2.2, item q. */ + uint16_t partner_sys_priority; + /* [IEEE-802.1AX], Section 5.4.2.2, item s. */ + uint16_t partner_key; + /* [IEEE-802.1AX], Section 5.4.6. */ + uint16_t agg_id; + /* [IEEE-802.1AX], Section 5.3.5. */ + uint16_t actor_key; + /* + * RFC 7275 + * 7.2.8. mLACP Aggregator State TLV + * [Page 61] + */ + uint8_t agg_state; +} __attribute__ ((packed)); + +typedef struct mLACPAggPortStateTLV mLACPAggPortStateTLV; + +/* + * RFC 7275 + * 7.2.9. mLACP Synchronization Request TLV + * [Page 61] + */ +struct mLACPSyncReqTLV +{ + ICCParameter icc_parameter; + /* + * RFC 7275 + * 7.2.9. mLACP Synchronization Request TLV + * [Page 62] + */ + uint16_t req_num; + +#if __BYTE_ORDER == __BIG_ENDIAN + uint16_t c_bit : 1; + /* + * RFC 7275 + * 7.2.9. mLACP Synchronization Request TLV + * [Page 63] + */ + uint16_t s_bit : 1; + uint16_t req_type : 14; +#elif __BYTE_ORDER == __LITTLE_ENDIAN + uint16_t req_type : 14; + /* + * RFC 7275 + * 7.2.9. mLACP Synchronization Request TLV + * [Page 63] + */ + uint16_t s_bit : 1; + uint16_t c_bit : 1; +#endif + /* [IEEE-802.1AX], Section 5.3.4. */ + /* [IEEE-802.1AX], Section 5.4.6. */ + uint16_t port_num_agg_id; + /* [IEEE-802.1AX], Section 5.3.5. */ + uint16_t actor_key; +} __attribute__ ((packed)); + +typedef struct mLACPSyncReqTLV mLACPSyncReqTLV; + +/* + * RFC 7275 + * 7.2.10. mLACP Synchronization Data TLV + * [Page 63] + */ +struct mLACPSyncDataTLV +{ + ICCParameter icc_parameter; + /* + * RFC 7275 + * 7.2.10. mLACP Synchronization Data TLV + * [Page 64] + */ + uint16_t req_num; + uint16_t flags; +} __attribute__ ((packed)); + +typedef struct mLACPSyncDataTLV mLACPSyncDataTLV; + +/* VLAN Information TLV*/ +struct mLACPVLANData +{ + uint16_t vlan_id; +} __attribute__ ((packed)); + +/* + * Port Channel Information TLV + */ +struct mLACPPortChannelInfoTLV +{ + ICCParameter icc_parameter; + uint16_t agg_id; + char if_name[MAX_L_PORT_NAME]; + uint8_t if_name_len; + uint8_t l3_mode; + uint32_t ipv4_addr; + uint16_t po_id; + uint16_t num_of_vlan_id; + struct mLACPVLANData vlanData[0]; +} __attribute__ ((packed)); + +typedef struct mLACPPortChannelInfoTLV mLACPPortChannelInfoTLV; + +/* + * Port PeerLink Information TLV + */ +struct mLACPPeerLinkInfoTLV +{ + ICCParameter icc_parameter; + char if_name[MAX_L_PORT_NAME]; + uint8_t port_type; +} __attribute__ ((packed)); + +typedef struct mLACPPeerLinkInfoTLV mLACPPeerLinkInfoTLV; + +struct mLACPVLANInfoTLV +{ + ICCParameter icc_parameter; + uint16_t id; /* Local Interface ID, not VLAN ID */ + uint16_t num_of_vlan_id; + struct mLACPVLANData vlanData[0]; +} __attribute__ ((packed)); + +/* Mac entry Information TLV*/ +struct mLACPMACData +{ + uint8_t type;/*add or del*/ + char mac_str[ETHER_ADDR_STR_LEN]; + uint16_t vid; + /*Current if name that set in chip*/ + char ifname[MAX_L_PORT_NAME]; +} __attribute__ ((packed)); + +/* + * MAC Information TLV + */ +struct mLACPMACInfoTLV +{ + ICCParameter icc_parameter; + uint16_t num_of_entry; + struct mLACPMACData MacEntry[0]; +} __attribute__ ((packed)); + +struct ARPMsg +{ + uint8_t op_type; + char ifname[MAX_L_PORT_NAME]; + uint32_t ipv4_addr; + uint8_t mac_addr[ETHER_ADDR_LEN]; +}; + +struct NDISCMsg +{ + uint8_t op_type; + char ifname[MAX_L_PORT_NAME]; + uint32_t ipv6_addr[4]; + uint8_t mac_addr[ETHER_ADDR_LEN]; +}; + +/* + * ARP Information TLV + */ +struct mLACPARPInfoTLV +{ + ICCParameter icc_parameter; + /* Local Interface ID */ + uint16_t num_of_entry; + struct ARPMsg ArpEntry[0]; +} __attribute__ ((packed)); + +/* + * NDISC Information TLV + */ +struct mLACPNDISCInfoTLV +{ + ICCParameter icc_parameter; + /* Local Interface ID */ + uint16_t num_of_entry; + struct NDISCMsg NdiscEntry[0]; +} __attribute__ ((packed)); + +/* + * NOS: STP Information TLV + */ +struct stp_msg_s; +struct mLACPSTPInfoTLV +{ + ICCParameter icc_parameter; + uint8_t stp_msg[0]; +} __attribute__ ((packed)); + +/* + * NOS: Heartbeat + */ +struct mLACPHeartbeatTLV +{ + ICCParameter icc_parameter; + uint8_t heartbeat; +} __attribute__ ((packed)); + +/* + * NOS: Warm_reboot + */ +struct mLACPWarmbootTLV +{ + ICCParameter icc_parameter; + uint8_t warmboot; +} __attribute__ ((packed)); + +enum NEIGH_OP_TYPE +{ + NEIGH_SYNC_LIF, + NEIGH_SYNC_ADD, + NEIGH_SYNC_DEL, +}; + +enum MAC_AGE_TYPE +{ + MAC_AGE_LOCAL = 1, /*MAC in local switch is ageout*/ + MAC_AGE_PEER = 2, /*MAC in peer switch is ageout*/ +}; + +enum MAC_OP_TYPE +{ + MAC_SYNC_ADD = 1, + MAC_SYNC_DEL = 2, + MAC_SYNC_ACK = 4, +}; + +enum MAC_TYPE +{ + MAC_TYPE_STATIC = 1, + MAC_TYPE_DYNAMIC = 2, +}; + +struct MACMsg +{ + uint8_t op_type; /*add or del*/ + uint8_t fdb_type; /*static or dynamic*/ + char mac_str[ETHER_ADDR_STR_LEN]; + uint16_t vid; + /*Current if name that set in chip*/ + char ifname[MAX_L_PORT_NAME]; + /*if we set the mac to peer-link, origin_ifname store the + original if name that learned from chip*/ + char origin_ifname[MAX_L_PORT_NAME]; + uint8_t age_flag;/*local or peer is age?*/ +}; + +#endif /* MLACP_TLV_H_ */ diff --git a/src/iccpd/include/msg_format.h b/src/iccpd/include/msg_format.h new file mode 100644 index 000000000000..1af8bf8a46a8 --- /dev/null +++ b/src/iccpd/include/msg_format.h @@ -0,0 +1,500 @@ +/* + * msg_format.h + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef MSG_FORMAT_H_ +#define MSG_FORMAT_H_ +#include +#include +#include "../include/port.h" + +#define MAX_MSG_LOG_SIZE 128 + +/* + * RFC 5561 + * 4. Capability Message + * [Page 7] + */ +#define MSG_T_CAPABILITY 0x0202 + +/* + * RFC 7275 + * 6.1.1. ICC Header - Message Length + * [Page 25] + * 2-octet integer specifying the total length of this message in octets, + * excluding the "U-bit", "Message Type", and "Length" fields. + */ +#define MSG_L_INCLUD_U_BIT_MSG_T_L_FIELDS 4 + +/* + * RFC 7275 + * 12.1. Message Type Name Space + * [Page 79] + */ +#define MSG_T_RG_CONNECT 0x0700 +#define MSG_T_RG_DISCONNECT 0x0701 +#define MSG_T_NOTIFICATION 0x0702 +#define MSG_T_RG_APP_DATA 0x0703 + +/* + * RFC 7275 + * 12.2. TLV Type Name Space + * [Page 79] + */ +#define TLV_T_ICCP_CAPABILITY 0x0700 +#define TLV_L_ICCP_CAPABILITY 0x4 + +/* + * RFC 7275 + * 12.3. ICC RG Parameter Type Space + * [Page 80] + */ +#define TLV_T_ICC_SENDER_NAME 0x0001 +#define MAX_L_ICC_SENDER_NAME 80 +#define TLV_T_NAK 0x0002 +#define TLV_T_REQUESTED_PROTOCOL_VER 0x0003 +#define TLV_T_DISCONNECT_CODE 0x0004 +#define TLV_L_DISCONNECT_CODE 0x4 +#define TLV_T_ICC_RG_ID 0x0005 +#define TLV_L_ICC_RG_ID 0x4 + +#define TLV_T_MLACP_CONNECT 0x0030 +#define TLV_T_MLACP_DISCONNECT 0x0031 +#define TLV_T_MLACP_SYSTEM_CONFIG 0x0032 +#define TLV_T_MLACP_PORT_CONFIG 0x0033 //no support +#define TLV_T_MLACP_PORT_PRIORITY 0x0034 //no support +#define TLV_T_MLACP_PORT_STATE 0x0035 //no support +#define TLV_T_MLACP_AGGREGATOR_CONFIG 0x0036 +#define TLV_T_MLACP_AGGREGATOR_STATE 0x0037 +#define TLV_T_MLACP_SYNC_REQUEST 0x0038 +#define TLV_T_MLACP_SYNC_DATA 0x0039 +#define TLV_T_MLACP_HEARTBEAT 0x003A +#define TLV_T_MLACP_DISCONNECT_CAUSE 0x003B //not yet + +/* Self define Feature */ +#define TLV_T_MLACP_ORPHAN_PORT 0x1033 //not yet +#define TLV_T_MLACP_PORT_CHANNEL_INFO 0x1034 +#define TLV_T_MLACP_PEERLINK_INFO 0x1035 +#define TLV_T_MLACP_ARP_INFO 0x1036 +#define TLV_T_MLACP_STP_INFO 0x1037//no support +#define TLV_T_MLACP_MAC_INFO 0x1038 +#define TLV_T_MLACP_WARMBOOT_FLAG 0x1039 +#define TLV_T_MLACP_NDISC_INFO 0x103A +#define TLV_T_MLACP_LIST_END 0x104a // list end + +/* Debug */ +static char* get_tlv_type_string(int type) +{ + switch (type) + { + case TLV_T_ICCP_CAPABILITY: + return "TLV_T_ICCP_CAPABILITY"; + + case TLV_T_ICC_SENDER_NAME: + return "TLV_T_ICC_SENDER_NAME"; + + case TLV_T_NAK: + return "TLV_T_NAK"; + + case TLV_T_REQUESTED_PROTOCOL_VER: + return "TLV_T_REQUESTED_PROTOCOL_VER"; + + case TLV_T_DISCONNECT_CODE: + return "TLV_T_DISCONNECT_CODE"; + + case TLV_T_ICC_RG_ID: + return "TLV_T_ICC_RG_ID"; + + case TLV_T_MLACP_CONNECT: + return "TLV_T_MLACP_CONNECT"; + + case TLV_T_MLACP_DISCONNECT: + return "TLV_T_MLACP_DISCONNECT"; + + case TLV_T_MLACP_SYSTEM_CONFIG: + return "TLV_T_MLACP_SYSTEM_CONFIG"; + + case TLV_T_MLACP_PORT_CONFIG: + return "TLV_T_MLACP_PORT_CONFIG"; + + case TLV_T_MLACP_PORT_PRIORITY: + return "TLV_T_MLACP_PORT_PRIORITY"; + + case TLV_T_MLACP_PORT_STATE: + return "TLV_T_MLACP_PORT_STATE"; + + case TLV_T_MLACP_AGGREGATOR_CONFIG: + return "TLV_T_MLACP_AGGREGATOR_CONFIG"; + + case TLV_T_MLACP_AGGREGATOR_STATE: + return "TLV_T_MLACP_AGGREGATOR_STATE"; + + case TLV_T_MLACP_SYNC_REQUEST: + return "TLV_T_MLACP_SYNC_REQUEST"; + + case TLV_T_MLACP_SYNC_DATA: + return "TLV_T_MLACP_SYNC_DATA"; + + case TLV_T_MLACP_HEARTBEAT: + return "TLV_T_MLACP_HEARTBEAT"; + + case TLV_T_MLACP_DISCONNECT_CAUSE: + return "TLV_T_MLACP_DISCONNECT_CAUSE"; + + /* NOS Feature */ + case TLV_T_MLACP_ORPHAN_PORT: + return "TLV_T_MLACP_ORPHAN_PORT"; + + case TLV_T_MLACP_PORT_CHANNEL_INFO: + return "TLV_T_MLACP_PORT_CHANNEL_INFO"; + + case TLV_T_MLACP_PEERLINK_INFO: + return "TLV_T_MLACP_PEERLINK_INFO"; + + case TLV_T_MLACP_ARP_INFO: + return "TLV_T_MLACP_ARP_INFO"; + + case TLV_T_MLACP_MAC_INFO: + return "TLV_T_MLACP_MAC_INFO"; + + case TLV_T_MLACP_STP_INFO: + return "TLV_T_MLACP_STP_INFO"; + } + + return "UNKNOWN"; +} + +/* + * RFC 7275 + * 12.4. Status Code Name Space + * [Page 81] + */ +#define STATUS_CODE_U_ICCP_RG 0x00010001 +#define STATUS_CODE_ICCP_CONNECTION_COUNT_EXCEEDED 0x00010002 +#define STATUS_CODE_ICCP_APP_CONNECTION_COUNT_EXCEEDED 0x00010003 +#define STATUS_CODE_ICCP_APP_NOT_IN_RG 0x00010004 +#define STATUS_CODE_INCOMPATIBLE_ICCP_PROTOCOL_VER 0x00010005 +#define STATUS_CODE_ICCP_REJECTED_MSG 0x00010006 +#define STATUS_CODE_ICCP_ADMINISTRATIVELY_DISABLED 0x00010007 +#define STATUS_CODE_ICCP_RG_REMOVED 0x00010010 +#define STATUS_CODE_ICCP_APP_REMOVED_FROM_RG 0x00010011 + + +/* Debug */ +static char* get_status_string(int status) +{ + switch (status) + { + case STATUS_CODE_U_ICCP_RG: + return "Unknown ICCP RG"; + + case STATUS_CODE_ICCP_CONNECTION_COUNT_EXCEEDED: + return "ICCP Connection Count Exceeded"; + + case STATUS_CODE_ICCP_APP_CONNECTION_COUNT_EXCEEDED: + return "ICCP Application Connection Count Exceede"; + + case STATUS_CODE_ICCP_APP_NOT_IN_RG: + return "ICCP Application not in RG"; + + case STATUS_CODE_INCOMPATIBLE_ICCP_PROTOCOL_VER: + return "Incompatible ICCP Protocol Version"; + + case STATUS_CODE_ICCP_REJECTED_MSG: + return "ICCP Rejected Message"; + + case STATUS_CODE_ICCP_ADMINISTRATIVELY_DISABLED: + return "ICCP Administratively Disabled"; + + case STATUS_CODE_ICCP_RG_REMOVED: + return "ICCP RG Removed"; + + case STATUS_CODE_ICCP_APP_REMOVED_FROM_RG: + return "ICCP Application Removed from RG"; + } + + return "UNKNOWN"; +} +/* + * RFC 5036 + * 3.5. LDP Messages + * [Page 44] + */ +struct LDPHdr +{ +#if __BYTE_ORDER == __BIG_ENDIAN + uint16_t u_bit : 1; + uint16_t msg_type : 15; +#elif __BYTE_ORDER == __LITTLE_ENDIAN + uint16_t msg_type : 15; + uint16_t u_bit : 1; +#endif + uint16_t msg_len; + uint32_t msg_id; +} __attribute__ ((packed)); + +typedef struct LDPHdr LDPHdr; + +/* + * RFC 7275 + * 6.1.1. ICC Header + * [Page 24] + */ +struct ICCRGIDTLV +{ + uint16_t type; + uint16_t len; + uint32_t icc_rg_id; +} __attribute__ ((packed)); + +typedef struct ICCRGIDTLV ICCRGIDTLV; + +struct ICCHdr +{ + LDPHdr ldp_hdr; + ICCRGIDTLV icc_rg_id_tlv; +} __attribute__ ((packed)); + +typedef struct ICCHdr ICCHdr; + +/* + * RFC 7275 + * 6.1.2. ICC Parameter Encoding + * [Page 26] + */ +struct ICCParameter +{ +#if __BYTE_ORDER == __BIG_ENDIAN + uint16_t u_bit : 1; + uint16_t f_bit : 1; + uint16_t type : 14; +#elif __BYTE_ORDER == __LITTLE_ENDIAN + uint16_t type : 14; + uint16_t f_bit : 1; + uint16_t u_bit : 1; +#endif + uint16_t len; +} __attribute__ ((packed)); + +typedef struct ICCParameter ICCParameter; + +/* + * RFC 7275 + * 6.2.1. ICC Sender Name TLV + * [Page 28] + */ +struct ICCSenderNameTLV +{ + ICCParameter icc_parameter; + char sender_name[MAX_L_ICC_SENDER_NAME]; +} __attribute__ ((packed)); + +typedef struct ICCSenderNameTLV ICCSenderNameTLV; + +/* + * RFC 7275 + * 6.3. RG Disconnect Message + * [Page 29] + */ +struct DisconnectCodeTLV +{ + ICCParameter icc_parameter; + uint32_t iccp_status_code; +} __attribute__ ((packed)); + +typedef struct DisconnectCodeTLV DisconnectCodeTLV; + +/* + * RFC 7275 + * 6.4.1. Notification Message TLVs + * [Page 32] + */ +struct NAKTLV +{ + ICCParameter icc_parameter; + uint32_t iccp_status_code; + uint32_t rejected_msg_id; +} __attribute__ ((packed)); + +typedef struct NAKTLV NAKTLV; + +/* + * RFC 7275 + * 6.4.1. Notification Message TLVs + * [Page 34] + */ +struct RequestedProtocolVerTLV +{ + ICCParameter icc_parameter; + uint16_t connection_ref; + uint16_t requested_ver; +} __attribute__ ((packed)); + +typedef struct RequestedProtocolVerTLV RequestedProtocolVerTLV; + +/* + * RFC 7275 + * 8. LDP Capability Negotiation + * [Page 65] + */ +struct LDPICCPCapabilityTLV +{ + ICCParameter icc_parameter; +#if __BYTE_ORDER == __BIG_ENDIAN + uint16_t s_bit : 1; + uint16_t reserved : 15; +#elif __BYTE_ORDER == __LITTLE_ENDIAN + uint16_t reserved : 15; + uint16_t s_bit : 1; +#endif + uint8_t major_ver; + uint8_t minior_ver; +} __attribute__ ((packed)); + +typedef struct LDPICCPCapabilityTLV LDPICCPCapabilityTLV; + +/* + * RFC 7275 + * 7.2.1. mLACP Connect TLV + * [Page 47] + */ +struct AppConnectTLV +{ + ICCParameter icc_parameter; + uint16_t protocol_version; +#if __BYTE_ORDER == __BIG_ENDIAN + uint16_t a_bit : 1; + uint16_t reserved : 15; +#elif __BYTE_ORDER == __LITTLE_ENDIAN + uint16_t reserved : 15; + uint16_t a_bit : 1; +#endif + + /* Optional Sub-TLVs */ + /* No optional sub-TLVs in this version */ +} __attribute__ ((packed)); + +typedef struct AppConnectTLV AppConnectTLV; + +/* + * RFC 7275 + * 7.2.2. mLACP Disconnect TLV + * [Page 48] + */ +struct AppDisconnectTLV +{ + ICCParameter icc_parameter; + + /* Optional Sub-TLVs */ + /* mLACP Disconnect Cause TLV */ +} __attribute__ ((packed)); + +typedef struct AppDisconnectTLV AppDisconnectTLV; + +/* + * RFC 7275 + * 7.2.2.1. mLACP Disconnect Cause TLV + * [Page 49] + */ +struct AppDisconnectCauseTLV +{ + ICCParameter iccp_parameter; + + /* Disconnect Cause String */ + char cause_string[0]; /* Trick */ +} __attribute__ ((packed)); + +/*syncd send msg type to iccpd*/ +typedef enum mclag_syncd_msg_type_e_ +{ + MCLAG_SYNCD_MSG_TYPE_NONE = 0, + MCLAG_SYNCD_MSG_TYPE_FDB_OPERATION = 1 +}mclag_syncd_msg_type_e; + +typedef enum mclag_msg_type_e_ +{ + MCLAG_MSG_TYPE_NONE = 0, + MCLAG_MSG_TYPE_PORT_ISOLATE = 1, + MCLAG_MSG_TYPE_PORT_MAC_LEARN_MODE = 2, + MCLAG_MSG_TYPE_FLUSH_FDB = 3, + MCLAG_MSG_TYPE_SET_MAC = 4, + MCLAG_MSG_TYPE_SET_FDB = 5, + MCLAG_MSG_TYPE_GET_FDB_CHANGES = 20 +}mclag_msg_type_e; + + +typedef enum mclag_sub_option_type_e_ +{ + MCLAG_SUB_OPTION_TYPE_NONE = 0, + MCLAG_SUB_OPTION_TYPE_ISOLATE_SRC = 1, + MCLAG_SUB_OPTION_TYPE_ISOLATE_DST = 2, + MCLAG_SUB_OPTION_TYPE_MAC_LEARN_ENABLE = 3, + MCLAG_SUB_OPTION_TYPE_MAC_LEARN_DISABLE = 4, + MCLAG_SUB_OPTION_TYPE_SET_MAC_SRC = 5, + MCLAG_SUB_OPTION_TYPE_SET_MAC_DST = 6 +} mclag_sub_option_type_e; + + +struct IccpSyncdHDr +{ + uint8_t ver; + uint8_t type; + uint16_t len; +}; + +typedef struct mclag_sub_option_hdr_t_ +{ + + uint8_t op_type; + + /* + * Length of option value, not including the header. + */ + uint16_t op_len; + uint8_t data[]; +}mclag_sub_option_hdr_t; + +struct mclag_fdb_info +{ + char mac[ETHER_ADDR_STR_LEN]; + unsigned int vid; + char port_name[MAX_L_PORT_NAME]; + short type; /*dynamic or static*/ + short op_type; /*add or del*/ +}; + +/* For storing message log: For Notification TLV */ +struct MsgTypeSet +{ + uint32_t msg_id; + uint16_t type; + uint16_t tlv; + +}; + +struct MsgLog +{ + struct MsgTypeSet msg[MAX_MSG_LOG_SIZE]; + uint32_t end_index; +}; + +#endif /* MSG_FORMAT_H_ */ diff --git a/src/iccpd/include/port.h b/src/iccpd/include/port.h new file mode 100644 index 000000000000..dbd9d45fa83d --- /dev/null +++ b/src/iccpd/include/port.h @@ -0,0 +1,159 @@ +/* + * port.h + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef PORT_H_ +#define PORT_H_ + +#include +#include +#include + +#define ETHER_ADDR_LEN 6 +#define ETHER_ADDR_STR_LEN 18 +/* + * RFC 7275 + * 7.2.4. mLACP Port Config TLV + * [Page 56] + */ +#define MAX_L_PORT_NAME 20 + +/* defined in RFC 7275 - 7.2.7 (p.59) */ +#define PORT_STATE_UP 0x00 +#define PORT_STATE_DOWN 0x01 +#define PORT_STATE_ADMIN_DOWN 0x02 +#define PORT_STATE_TEST 0x03 + +/* Interface Type */ +#define IF_T_UNKNOW -1 +#define IF_T_PORT 0 +#define IF_T_PORT_CHANNEL 1 +#define IF_T_VLAN 2 +#define IF_T_VXLAN 3 +#define IF_T_BRIDGE 4 +typedef struct +{ + char *ifname; + int type; +} itf_type_t; + +struct If_info +{ + char name[MAX_L_PORT_NAME]; + LIST_ENTRY(If_info) csm_next; +}; + +struct VLAN_ID +{ + uint16_t vid; + uint16_t vlan_removed; + struct LocalInterface* vlan_itf; /* loacl vlan interface */ + LIST_ENTRY(VLAN_ID) port_next; +}; + +struct PeerInterface +{ + int ifindex; + int type; + char name[MAX_L_PORT_NAME]; + + uint8_t mac_addr[ETHER_ADDR_LEN]; + uint8_t state; + uint32_t ipv4_addr; + + uint8_t l3_mode; + uint8_t is_peer_link; + int po_id; + uint8_t po_active; + + struct CSM* csm; + + LIST_ENTRY(PeerInterface) mlacp_next; + LIST_HEAD(peer_vlan_list, VLAN_ID) vlan_list; +}; + +struct LocalInterface +{ + int ifindex; + int type; + char name[MAX_L_PORT_NAME]; + + uint8_t mac_addr[ETHER_ADDR_LEN]; + uint8_t mac_addr_ori[ETHER_ADDR_LEN]; + uint8_t state; + uint32_t ipv4_addr; + uint8_t prefixlen; + uint32_t ipv6_addr[4]; + uint8_t prefixlen_v6; + + uint8_t l3_mode; + uint8_t l3_mac_addr[ETHER_ADDR_LEN]; + uint8_t is_peer_link; + char portchannel_member_buf[512]; + uint8_t is_arp_accept; + int po_id; /* Port Channel ID */ + uint8_t po_active; /* Port Channel is in active status? */ + int mlacp_state; /* Record mlacp state */ + uint8_t isolate_to_peer_link; + + struct CSM* csm; + + uint8_t changed; + uint8_t port_config_sync; + + LIST_HEAD(local_vlan_list, VLAN_ID) vlan_list; + + LIST_ENTRY(LocalInterface) system_next; + LIST_ENTRY(LocalInterface) system_purge_next; + LIST_ENTRY(LocalInterface) mlacp_next; + LIST_ENTRY(LocalInterface) mlacp_purge_next; +}; + +struct LocalInterface* local_if_create(int ifindex, char* ifname, int type); +struct LocalInterface* local_if_find_by_name(const char* ifname); +struct LocalInterface* local_if_find_by_ifindex(int ifindex); +struct LocalInterface* local_if_find_by_po_id(int po_id); + +void local_if_destroy(char *ifname); +void local_if_change_flag_clear(void); +void local_if_purge_clear(void); +int local_if_is_l3_mode(struct LocalInterface* local_if); + +void local_if_init(struct LocalInterface*); +void local_if_finalize(struct LocalInterface*); + +void ether_mac_set_addr_with_if_name(char *name, uint8_t* mac); +struct PeerInterface* peer_if_create(struct CSM* csm, int peer_if_number, int type); +struct PeerInterface* peer_if_find_by_name(struct CSM* csm, char* name); + +void peer_if_destroy(struct PeerInterface* pif); +int peer_if_add_vlan(struct PeerInterface* peer_if, uint16_t vlan_id); +int peer_if_clean_unused_vlan(struct PeerInterface* peer_if); +/* VLAN manipulation */ +int local_if_add_vlan(struct LocalInterface* local_if, uint16_t vid); +void local_if_del_vlan(struct LocalInterface* local_if, uint16_t vid); +void local_if_del_all_vlan(struct LocalInterface* lif); + +/* ARP manipulation */ +int set_sys_arp_accept_flag(char* ifname, int flag); + +#endif /* PORT_H_ */ diff --git a/src/iccpd/include/scheduler.h b/src/iccpd/include/scheduler.h new file mode 100644 index 000000000000..a1b31039d794 --- /dev/null +++ b/src/iccpd/include/scheduler.h @@ -0,0 +1,60 @@ +/* + * scheduler.h + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef SCHEDULER_H_ +#define SCHEDULER_H_ + +#include + +#include +#include +#include + +#include +#include +#include + +struct CSM; +struct System; + +#define CONNECT_INTERVAL_SEC 1 +#define CONNECT_TIMEOUT_MSEC 100 +#define HEARTBEAT_TIMEOUT_SEC 15 +#define TRANSIT_INTERVAL_SEC 1 +#define EPOLL_TIMEOUT_MSEC 100 + +int scheduler_prepare_session(struct CSM*); +int scheduler_check_csm_config(struct CSM*); +int scheduler_unregister_sock_read_event_callback(struct CSM*); +void scheduler_session_disconnect_handler(struct CSM*); +void scheduler_init(); +void scheduler_finalize(); +void scheduler_loop(); +void scheduler_start(); +void scheduler_server_sock_init(); +int scheduler_csm_read_callback(struct CSM* csm); +int iccp_get_server_sock_fd(); +int scheduler_server_accept(); +int iccp_receive_signal_handler(struct System* sys); + +#endif /* SCHEDULER_H_ */ diff --git a/src/iccpd/include/system.h b/src/iccpd/include/system.h new file mode 100644 index 000000000000..3ee314d253aa --- /dev/null +++ b/src/iccpd/include/system.h @@ -0,0 +1,103 @@ +/* + * system.h + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#ifndef SYSTEM_H_ +#define SYSTEM_H_ + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "../include/port.h" + +#define FRONT_PANEL_PORT_PREFIX "Ethernet" +#define PORTCHANNEL_PREFIX "PortChannel" +#define VLAN_PREFIX "Vlan" +#define VXLAN_TUNNEL_PREFIX "VTTNL" + +#define WARM_REBOOT 1 + +#define MCLAG_ERROR -1 + +struct CSM; + +#ifndef MAX_BUFSIZE + #define MAX_BUFSIZE 4096 +#endif + +struct System +{ + int server_fd;/* Peer-Link Socket*/ + int sync_fd; + int sync_ctrl_fd; + int arp_receive_fd; + int ndisc_receive_fd; + int epoll_fd; + + struct nl_sock * genric_sock; + int genric_sock_seq; + int family; + struct nl_sock * route_sock; + int route_sock_seq; + struct nl_sock * genric_event_sock; + struct nl_sock * route_event_sock; + + int sig_pipe_r; + int sig_pipe_w; + int warmboot_start; + int warmboot_exit; + + /* Info List*/ + LIST_HEAD(csm_list, CSM) csm_list; + LIST_HEAD(lif_all_list, LocalInterface) lif_list; + LIST_HEAD(lif_purge_all_list, LocalInterface) lif_purge_list; + + /* Settings */ + char* log_file_path; + char* cmd_file_path; + char* config_file_path; + char* mclagdctl_file_path; + int pid_file_fd; + int telnet_port; + fd_set readfd; /*record socket need to listen*/ + int readfd_count; + time_t csm_trans_time; + int need_sync_team_again; + int need_sync_netlink_again; +}; + +struct CSM* system_create_csm(); +struct CSM* system_get_csm_by_peer_ip(const char*); +struct CSM* system_get_csm_by_mlacp_id(int id); +struct System* system_get_instance(); +void system_finalize(); +void system_init(struct System*); + +#endif /* SYSTEM_H_ */ diff --git a/src/iccpd/src/Makefile.am b/src/iccpd/src/Makefile.am new file mode 100644 index 000000000000..9d19dbb5285c --- /dev/null +++ b/src/iccpd/src/Makefile.am @@ -0,0 +1,22 @@ +SUBDIRS = mclagdctl + +INCLUDES = -I$(top_srcdir)/include -I/usr/include/libnl3 + +bin_PROGRAMS = iccpd + +if DEBUG +DBGFLAGS = -ggdb -DDEBUG +else +DBGFLAGS = -g -DNDEBUG +endif + +iccpd_SOURCES = \ + app_csm.c cmd_option.c iccp_cli.c iccp_cmd_show.c iccp_cmd.c \ + iccp_csm.c iccp_ifm.c iccp_main.c logger.c \ + port.c scheduler.c system.c iccp_consistency_check.c \ + mlacp_link_handler.c \ + mlacp_sync_prepare.c mlacp_sync_update.c\ + mlacp_fsm.c \ + iccp_netlink.c +iccpd_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) +iccpd_LDADD = -lnl-genl-3 -lnl-route-3 -lnl-3 -lpthread diff --git a/src/iccpd/src/app_csm.c b/src/iccpd/src/app_csm.c new file mode 100644 index 000000000000..589cf94015d8 --- /dev/null +++ b/src/iccpd/src/app_csm.c @@ -0,0 +1,316 @@ +/* + * app_csm.c + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#include +#include +#include + +#include "../include/iccp_csm.h" +#include "../include/logger.h" +#include "../include/scheduler.h" +#include "../include/system.h" +#include "../include/iccp_netlink.h" +#include "../include/mlacp_link_handler.h" +/***************************************** +* Define +* +* ***************************************/ +#define APP_CSM_QUEUE_REINIT(list) \ + { \ + struct Msg* msg = NULL; \ + while (!TAILQ_EMPTY(&(list))) { \ + msg = TAILQ_FIRST(&(list)); \ + TAILQ_REMOVE(&(list), msg, tail); \ + free(msg->buf); \ + free(msg); \ + } \ + TAILQ_INIT(&(list)); \ + } + +/* Application State Machine instance initialization */ +void app_csm_init(struct CSM* csm, int all) +{ + if (csm == NULL ) + return; + + APP_CSM_QUEUE_REINIT(csm->app_csm.app_msg_list); + + if (all) + { + bzero(&(csm->app_csm), sizeof(struct AppCSM)); + APP_CSM_QUEUE_REINIT(csm->app_csm.app_msg_list); + } + + csm->app_csm.current_state = APP_NONEXISTENT; + csm->app_csm.rx_connect_msg_id = 0; + csm->app_csm.tx_connect_msg_id = 0; + csm->app_csm.invalid_msg_id = 0; + csm->app_csm.invalid_msg = 0; + csm->app_csm.nak_msg = 0; + + mlacp_init(csm, all); +} + +/* Application State Machine instance tear down */ +void app_csm_finalize(struct CSM* csm) +{ + mlacp_finalize(csm); +} + +/* Application State Machine Transition */ +void app_csm_transit(struct CSM* csm) +{ + if (csm == NULL ) + return; + + /* torn down event */ + if (csm->app_csm.current_state != APP_NONEXISTENT && csm->sock_fd <= 0) + { + csm->app_csm.current_state = APP_NONEXISTENT; + return; + } + + if (csm->app_csm.current_state != APP_OPERATIONAL && csm->current_state == ICCP_OPERATIONAL) + { + csm->app_csm.current_state = APP_OPERATIONAL; + } + + return; +} + +/* Add received message into application message list */ +void app_csm_enqueue_msg(struct CSM* csm, struct Msg* msg) +{ + ICCHdr* icc_hdr = NULL; + ICCParameter* param = NULL; + NAKTLV* naktlv = NULL; + int tlv = -1; + int i = 0; + + if (csm == NULL ) + { + if (msg != NULL ) + free(msg); + return; + } + if (msg == NULL ) + return; + + icc_hdr = (ICCHdr*)msg->buf; + param = (ICCParameter*)&msg->buf[sizeof(struct ICCHdr)]; + *(uint16_t *)param = ntohs(*(uint16_t *)param); + + if ( icc_hdr->ldp_hdr.msg_type == MSG_T_RG_APP_DATA) + { + if (param->type > TLV_T_MLACP_CONNECT && param->type < TLV_T_MLACP_LIST_END) + mlacp_enqueue_msg(csm, msg); + else + TAILQ_INSERT_TAIL(&(csm->app_csm.app_msg_list), msg, tail); + } + else if (icc_hdr->ldp_hdr.msg_type == MSG_T_NOTIFICATION) + { + naktlv = (NAKTLV*)&msg->buf[sizeof(ICCHdr)]; + + for (i = 0; i < MAX_MSG_LOG_SIZE; ++i) + { + if (ntohl(naktlv->rejected_msg_id) == csm->msg_log.msg[i].msg_id) + { + tlv = csm->msg_log.msg[i].tlv; + break; + } + } + + if (tlv > TLV_T_MLACP_CONNECT && tlv <= TLV_T_MLACP_MAC_INFO) + mlacp_enqueue_msg(csm, msg); + else + TAILQ_INSERT_TAIL(&(csm->app_csm.app_msg_list), msg, tail); + } + else + { + /* This packet is not for me, ignore it. */ + ICCPD_LOG_DEBUG(__FUNCTION__, "Ignore the packet with msg_type = %d", icc_hdr->ldp_hdr.msg_type); + } +} + +/* Get received message from message list */ +struct Msg* app_csm_dequeue_msg(struct CSM* csm) +{ + struct Msg* msg = NULL; + + if (!TAILQ_EMPTY(&(csm->app_csm.app_msg_list))) + { + msg = TAILQ_FIRST(&(csm->app_csm.app_msg_list)); + TAILQ_REMOVE(&(csm->app_csm.app_msg_list), msg, tail); + } + + return msg; +} + +/* APP NAK message handle function */ +int app_csm_prepare_nak_msg(struct CSM* csm, char* buf, size_t max_buf_size) +{ + ICCHdr* icc_hdr = (ICCHdr*)buf; + NAKTLV* naktlv = (NAKTLV*)&buf[sizeof(ICCHdr)]; + size_t msg_len = sizeof(ICCHdr) + sizeof(NAKTLV); + + ICCPD_LOG_DEBUG(__FUNCTION__, " Response NAK"); + memset(buf, 0, max_buf_size); + icc_hdr->ldp_hdr.u_bit = 0x0; + icc_hdr->ldp_hdr.msg_type = htons(MSG_T_NOTIFICATION); + icc_hdr->ldp_hdr.msg_len = htons(msg_len - MSG_L_INCLUD_U_BIT_MSG_T_L_FIELDS); + icc_hdr->ldp_hdr.msg_id = htonl(ICCP_MSG_ID++); + iccp_csm_fill_icc_rg_id_tlv(csm, icc_hdr); + naktlv->icc_parameter.u_bit = 0; + naktlv->icc_parameter.f_bit = 0; + naktlv->icc_parameter.type = htons(TLV_T_NAK); + naktlv->icc_parameter.len = htons(sizeof(NAKTLV) - 4); + + naktlv->iccp_status_code = htonl(STATUS_CODE_ICCP_REJECTED_MSG); + naktlv->rejected_msg_id = htonl(csm->app_csm.invalid_msg_id); + + return msg_len; +} + +int mlacp_bind_local_if(struct CSM* csm, struct LocalInterface* lif) +{ + struct LocalInterface* lifp = NULL; + struct LocalInterface* lif_po = NULL; + + if (csm == NULL || lif == NULL) + return MCLAG_ERROR; + + if (lif->csm == csm) + return 0; + + /* remove purge from the csm*/ + do { + LIST_FOREACH(lifp, &(MLACP(csm).lif_purge_list), mlacp_purge_next) + { + if (lifp == lif) + break; + } + if (lifp) + LIST_REMOVE(lifp, mlacp_purge_next); + } while (lifp); + + /* already join csm?*/ + LIST_FOREACH(lifp, &(MLACP(csm).lif_list), mlacp_next) + { + if (lifp == lif) + return 0; + } + + /* join another csm beofre? remove from csm*/ + if (lif->csm != NULL) + mlacp_unbind_local_if(lif); + + /* join new csm*/ + LIST_INSERT_HEAD(&(MLACP(csm).lif_list), lif, mlacp_next); + lif->csm = csm; + if (lif->type == IF_T_PORT_CHANNEL) + lif->port_config_sync = 1; + + ICCPD_LOG_INFO(__FUNCTION__, "%s: MLACP bind on csm %p", lif->name, csm); + if (lif->type == IF_T_PORT_CHANNEL) + return 0; + + /* if join a po member, needs to check po joined also*/ + LIST_FOREACH(lif_po, &(MLACP(csm).lif_list), mlacp_next) + { + if (lif_po->type == IF_T_PORT_CHANNEL && lif_po->po_id == lif->po_id) + { + /*if join a po member, may swss restart, reset portchannel ip mac to mclagsyncd*/ + update_if_ipmac_on_standby(lif_po); + return 0; + } + } + + if (lif_po == NULL) + { + lif_po = local_if_find_by_po_id(lif->po_id); + if (lif_po == NULL) + { + ICCPD_LOG_WARN(__FUNCTION__, "Failed to find port_channel instance for %d.", lif->po_id); + return MCLAG_ERROR; + } + + lif_po->csm = csm; + LIST_INSERT_HEAD(&(MLACP(csm).lif_list), lif_po, mlacp_next); + lif_po->port_config_sync = 1; + ICCPD_LOG_INFO(__FUNCTION__, "Add port_channel %d into local_if_list in CSM %p.", lif->po_id, csm); + } + + return 0; +} + +int mlacp_unbind_local_if(struct LocalInterface* lif) +{ + if (lif == NULL ) + return MCLAG_ERROR; + + if (lif->csm == NULL ) + return 0; + + ICCPD_LOG_INFO(__FUNCTION__, "%s: MLACP un-bind from csm %p", lif->name, lif->csm); + LIST_REMOVE(lif, mlacp_next); + + if (MLACP(lif->csm).current_state == MLACP_STATE_EXCHANGE && lif->type == IF_T_PORT_CHANNEL) + LIST_INSERT_HEAD(&(MLACP(lif->csm).lif_purge_list), lif, mlacp_purge_next); + if (lif->type == IF_T_PORT) + lif->po_id = -1; + lif->csm = NULL; + + return 0; +} + +int mlacp_bind_port_channel_to_csm(struct CSM* csm, const char *ifname) +{ + struct System* sys = NULL; + struct LocalInterface *lif_po = NULL; + + sys = system_get_instance(); + if (sys == NULL) + return 0; + + if (csm == NULL) + return 0; + + /* bind po first*/ + lif_po = local_if_find_by_name(ifname); + if (lif_po) + { + mlacp_bind_local_if(csm, lif_po); + iccp_get_port_member_list(lif_po); + } + else + { + ICCPD_LOG_WARN(__FUNCTION__, "%s: Failed to find a port instance .", ifname); + return 0; + } + /* process link state handler after attaching it.*/ + + mlacp_mlag_link_add_handler(csm, lif_po); + + /*ICCPD_LOG_WARN(tag, "po%d active = %d\n", po_id, po_is_active);*/ + return 0; +} + diff --git a/src/iccpd/src/cmd_option.c b/src/iccpd/src/cmd_option.c new file mode 100644 index 000000000000..596dafb73711 --- /dev/null +++ b/src/iccpd/src/cmd_option.c @@ -0,0 +1,266 @@ +/* + * cmd_option.c + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#include "../include/cmd_option.h" + +struct CmdOption* cmd_option_find(struct CmdOptionParser* parser, char* opt_name) +{ + struct CmdOption* opt = NULL; + + if (opt_name == NULL) + return NULL; + + LIST_FOREACH(opt, &(parser->option_list), next) + { + if (strcmp(opt->option, opt_name) == 0) + return opt; + } + + return NULL; +} + +void cmd_option_delete(struct CmdOption* opt) +{ + if (opt == NULL) + return; + + LIST_REMOVE(opt, next); + if (opt->option != NULL) + free(opt->option); + if (opt->parameter != NULL) + free(opt->parameter); + if (opt->desc != NULL) + free(opt->desc); + free(opt); +} + +struct CmdOption* cmd_option_add(struct CmdOptionParser* parser, char* opt_name) +{ + struct CmdOption* opt = NULL; + + if (opt_name == NULL) + return NULL; + if ((opt = cmd_option_find(parser, opt_name)) != NULL) + return opt; + + if ((opt = (struct CmdOption*)malloc(sizeof(struct CmdOption))) == NULL) + { + strerror(errno); + } + else + { + opt->option = opt_name; + opt->parameter = NULL; + opt->desc = NULL; + LIST_INSERT_HEAD(&(parser->option_list), opt, next); + } + + return opt; +} + +static void cmd_option_register(struct CmdOptionParser* parser, char* syntax, char* desc) +{ + char buf[OPTION_MAX_LEN]; + struct CmdOption* opt = NULL; + char* opt_name = NULL; + char* param = NULL; + char* desc_copy = NULL; + char* token = NULL; + + if (parser == NULL) + return; + if (syntax == NULL) + return; + + memset(buf, 0, OPTION_MAX_LEN); + snprintf(buf, OPTION_MAX_LEN - 1, "%s", syntax); + + if ((token = strtok(buf, " ")) == NULL) + return; + + opt_name = strdup(token); + if ((token = strtok(NULL, " ")) != NULL) + param = strdup(token); + desc_copy = strdup(desc); + if ((opt = cmd_option_find(parser, opt_name)) != NULL) + goto failed; + if ((opt = cmd_option_add(parser, opt_name)) == NULL) + { + goto failed; + } + opt->parameter = param; + opt->desc = desc_copy; + + return; + + failed: + if (opt_name) + free(opt_name); + if (desc_copy != NULL) + free(desc_copy); + if (param != NULL) + free(param); + if (opt != NULL) + free(opt); +} + +void cmd_option_parser_init(struct CmdOptionParser* parser) +{ + if (parser == NULL) + return; + + LIST_INIT(&parser->option_list); + cmd_option_register(parser, "-l ", "Set log file path.\n(Default: /var/log/iccpd.log)"); + cmd_option_register(parser, "-p ", "Set the port used for telnet listening port.\n(Default: 2015)"); + cmd_option_register(parser, "-c", "Dump log message to console. (Default: No)"); + cmd_option_register(parser, "-h", "Show the usage."); +} + +void cmd_option_parser_finalize(struct CmdOptionParser* parser) +{ + while (!LIST_EMPTY(&(parser->option_list))) + { + struct CmdOption* opt = NULL; + opt = LIST_FIRST(&(parser->option_list)); + cmd_option_delete(opt); + } +} + +void cmd_option_parser_dump_usage(struct CmdOptionParser* parser, char* prog_name) +{ + char buf[MSG_LEN]; + struct CmdOption* opt = NULL; + int index, begin, length; + char first_line = 0; + + fprintf(stdout, "Usage: %s [Options]\n", prog_name); + fprintf(stdout, "\n"); + fprintf(stdout, "Options:\n"); + LIST_FOREACH(opt, &(parser->option_list), next) + { + index = 0; + begin = 0; + length = 0; + first_line = 1; + memset(buf, 0, MSG_LEN); + if (opt->parameter != NULL) + snprintf(buf, MSG_LEN - 1, "%s %s", opt->option, opt->parameter); + else + snprintf(buf, MSG_LEN - 1, "%s", opt->option); + fprintf(stdout, "%24s ", buf); + + while (index < strlen(opt->desc)) + { + while (index < strlen(opt->desc) + && opt->desc[index] != '\n' && length < 49) + { + ++index; + ++length; + } + + memset(buf, 0, MSG_LEN); + strncpy(buf, &(opt->desc[begin]), length); + if (length == 49 && index < strlen(opt->desc) + && opt->desc[index] != '\n' + && opt->desc[index - 1] != ' ' + && opt->desc[index] != ' ') + { + buf[length] = '-'; + buf[length + 1] = '\0'; + } + if (length < 49) + ++index; + begin = index; + length = 0; + if (first_line != 0) + { + fprintf(stdout, "%-52s\n", buf); + first_line = 0; + } + else + fprintf(stdout, "%28c%-52s\n", ' ', buf); + } + + fflush(stdout); + } +} + +int cmd_option_parser_parse(struct CmdOptionParser* parser, int argc, char* argv[]) +{ + int index = 1; + struct CmdOption* opt = NULL; + char* opt_name = NULL; + char* val = NULL; + int num = 0; + + if (parser == NULL) + return -255; + + while (index < argc) + { + opt_name = argv[index]; + opt = cmd_option_find(parser, opt_name); + if (opt == NULL) + { + fprintf(stderr, "Unknown option %s, skip it.\n", opt_name); + ++index; + continue; + } + + if (opt->parameter != NULL) + { + ++index; + if (index >= argc) + { + fprintf(stderr, "Error: Insufficient parameter for option %s\n", opt_name); + cmd_option_parser_dump_usage(parser, argv[0]); + return -1; + } + val = argv[index]; + } + + if (strncmp(opt_name, "-h", 2) == 0) + { + cmd_option_parser_dump_usage(parser, argv[0]); + return -1; + } + + if (strncmp(opt_name, "-l", 2) == 0) + parser->log_file_path = val; + + if (strncmp(opt_name, "-p", 2) == 0) + { + num = atoi(val); + if (num > 0 && num < 65535) + parser->telnet_port = num; + } + else if (strncmp(opt_name, "-c", 2) == 0) + parser->console_log = 1; + else + fprintf(stderr, "Unknown option name %s, skip it.\n", opt_name); + + ++index; + } + + return 0; +} diff --git a/src/iccpd/src/iccp_cli.c b/src/iccpd/src/iccp_cli.c new file mode 100644 index 000000000000..8d0ede8b3feb --- /dev/null +++ b/src/iccpd/src/iccp_cli.c @@ -0,0 +1,498 @@ +/* + * iccp_cli.c + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#include + +#include "../include/system.h" +#include "../include/scheduler.h" +#include "../include/logger.h" +#include "../include/iccp_csm.h" +#include "../include/mlacp_link_handler.h" +#include "../include/iccp_netlink.h" +/* + * 'id <1-65535>' command + */ +int set_mc_lag_id( struct CSM *csm, uint16_t id) +{ + if (!csm) + return MCLAG_ERROR; + + ICCPD_LOG_INFO(__FUNCTION__, "Set mlag-id : %d", id); + + /* Mlag-ID, RG-ID, MLACP-ID + Temporary let the three id be the same*/ + csm->mlag_id = id; + csm->iccp_info.icc_rg_id = id; + csm->app_csm.mlacp.id = id; + return 0; +} + +int unset_mc_lag_id( struct CSM *csm, uint16_t id) +{ + if (!csm) + return MCLAG_ERROR; + + /* Mlag-ID, RG-ID, MLACP-ID*/ + csm->mlag_id = 0; + csm->iccp_info.icc_rg_id = 0; + csm->app_csm.mlacp.id = 0; + + iccp_csm_finalize(csm); + + return 0; +} + +/* + * 'peer-link WORD' command + */ +int set_peer_link(int mid, const char* ifname) +{ + struct CSM* csm = NULL; + struct LocalInterface *lif = NULL; + size_t len = 0; + + len = strlen(ifname); + + if (strncmp(ifname, FRONT_PANEL_PORT_PREFIX, strlen(FRONT_PANEL_PORT_PREFIX)) != 0 && strncmp(ifname, PORTCHANNEL_PREFIX, strlen(PORTCHANNEL_PREFIX)) != 0 && strncmp(ifname, VXLAN_TUNNEL_PREFIX, strlen(VXLAN_TUNNEL_PREFIX)) != 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Peer-link is %s, must be Ethernet or PortChannel or VTTNL(Vxlan tunnel)", ifname); + return MCLAG_ERROR; + } + + csm = system_get_csm_by_mlacp_id(mid); + if (csm == NULL) + return MCLAG_ERROR; + + if (len > IFNAMSIZ) + return MCLAG_ERROR; + + if (strlen(csm->peer_itf_name) > 0) + { + if (strcmp(csm->peer_itf_name, ifname) == 0) + { + ICCPD_LOG_INFO(__FUNCTION__, "Peer-link not be changed"); + return 0; + } + else + { + ICCPD_LOG_INFO(__FUNCTION__, "Change peer-link : %s -> %s", + csm->peer_itf_name, ifname); + + /*disconnect the link for mac and arp sync up before change peer_itf_name*/ + scheduler_session_disconnect_handler(csm); + + if (csm->peer_link_if) + { + csm->peer_link_if->is_peer_link = 0; + csm->peer_link_if = NULL; + } + } + } + else + { + ICCPD_LOG_INFO(__FUNCTION__, "Set mlag %d peer-link : %s", + csm->mlag_id, ifname); + } + + memset(csm->peer_itf_name, 0, IFNAMSIZ); + memcpy(csm->peer_itf_name, ifname, len); + + /* update peer-link link handler*/ + lif = local_if_find_by_name(csm->peer_itf_name); + if (lif) + { + /*When set peer-link, the local-if is already created*/ + csm->peer_link_if = lif; + lif->is_peer_link = 1; + MLACP(csm).system_config_changed = 1; + + if (lif->type == IF_T_PORT_CHANNEL) + iccp_get_port_member_list(lif); + } + + /*disconnect the link for mac and arp sync up*/ + scheduler_session_disconnect_handler(csm); + + return 0; +} + +int unset_peer_link(int mid) +{ + struct CSM* csm = NULL; + + csm = system_get_csm_by_mlacp_id(mid); + if (csm == NULL) + return MCLAG_ERROR; + + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + /*must be enabled mac learn*/ + if (csm->peer_link_if) + set_peerlink_mlag_port_learn(csm->peer_link_if, 1); + } + + /* update peer-link link handler*/ + scheduler_session_disconnect_handler(csm); + + /* clean peer-link*/ + memset(csm->peer_itf_name, 0, IFNAMSIZ); + if (csm->peer_link_if) + { + csm->peer_link_if->is_peer_link = 0; + csm->peer_link_if = NULL; + MLACP(csm).system_config_changed = 1; + } + + return 0; +} + +/* + * 'local ip address A.B.C.D' command + */ +int set_local_address(int mid, const char* addr) +{ + struct CSM* csm = NULL; + size_t len = 0; + + csm = system_get_csm_by_mlacp_id(mid); + if (csm == NULL) + return MCLAG_ERROR; + if (addr == NULL) + return MCLAG_ERROR; + + if (strlen(csm->sender_ip) > 0) + { + if (strcmp(csm->sender_ip, addr) == 0) + { + ICCPD_LOG_INFO(__FUNCTION__, "Local-address not be changed"); + return 0; + } + else + { + ICCPD_LOG_INFO(__FUNCTION__, "Change local-address : %s -> %s", + csm->sender_ip, addr); + scheduler_session_disconnect_handler(csm); + } + } + else + { + ICCPD_LOG_INFO(__FUNCTION__, "Set local-address : %s", addr); + } + + len = strlen(addr); + memset(csm->sender_ip, 0, INET_ADDRSTRLEN); + memcpy(csm->sender_ip, addr, len); + memset(csm->iccp_info.sender_name, 0, INET_ADDRSTRLEN); + memcpy(csm->iccp_info.sender_name, addr, len); + + return 0; +} + +int unset_local_address(int mid) +{ + struct CSM* csm = NULL; + + csm = system_get_csm_by_mlacp_id(mid); + if (csm == NULL) + return MCLAG_ERROR; + + memset(csm->sender_ip, 0, INET_ADDRSTRLEN); + memset(csm->iccp_info.sender_name, 0, INET_ADDRSTRLEN); + + /* reset link*/ + scheduler_session_disconnect_handler(csm); + + return 0; +} + +/* + * 'peer-address A.B.C.D' command + */ +int set_peer_address(int mid, const char* addr) +{ + struct CSM* csm = NULL; + size_t len = 0; + + csm = system_get_csm_by_mlacp_id(mid); + if (csm == NULL) + return MCLAG_ERROR; + if (addr == NULL) + return MCLAG_ERROR; + + len = strlen(addr); + + if (strlen(csm->peer_ip) > 0) + { + if (strcmp(csm->peer_ip, addr) == 0) + { + ICCPD_LOG_INFO(__FUNCTION__, "Peer-address not be changed"); + return 0; + } + else + { + ICCPD_LOG_INFO(__FUNCTION__, "Change peer-address : %s -> %s", + csm->peer_ip, addr); + scheduler_session_disconnect_handler(csm); + } + } + else + { + ICCPD_LOG_INFO(__FUNCTION__, "Set peer-address : %s", addr); + } + + memset(csm->peer_ip, 0, INET_ADDRSTRLEN); + memcpy(csm->peer_ip, addr, len); + + return 0; +} + +int unset_peer_address(int mid) +{ + struct CSM* csm = NULL; + + csm = system_get_csm_by_mlacp_id(mid); + if (csm == NULL) + return MCLAG_ERROR; + + memset(csm->peer_ip, 0, INET_ADDRSTRLEN); + + /* reset link*/ + scheduler_session_disconnect_handler(csm); + + return 0; +} + +int iccp_cli_attach_mclag_domain_to_port_channel( int domain, const char* ifname) +{ + struct CSM* csm = NULL; + struct LocalInterface *lif = NULL; + struct If_info * cif = NULL; + + if (!ifname) + return MCLAG_ERROR; + + if (strncmp(ifname, PORTCHANNEL_PREFIX, strlen(PORTCHANNEL_PREFIX)) != 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "Attach interface(%s) is not a port-channel", ifname); + return MCLAG_ERROR; + } + + csm = system_get_csm_by_mlacp_id(domain); + if (csm == NULL) + { + ICCPD_LOG_WARN(__FUNCTION__, "MC-LAG ID %d doesn't exist", domain); + return MCLAG_ERROR; + } + + lif = local_if_find_by_name(ifname); + if (lif) + { + mlacp_bind_port_channel_to_csm(csm, ifname); + } + + LIST_FOREACH(cif, &(csm->if_bind_list), csm_next) + { + if (strcmp(cif->name, ifname) == 0) + break; + } + + if (cif == NULL) + { + cif = (struct If_info *)malloc(sizeof(struct If_info)); + if (!cif) + return MCLAG_ERROR; + + snprintf(cif->name, MAX_L_PORT_NAME, "%s", ifname); + LIST_INSERT_HEAD(&(csm->if_bind_list), cif, csm_next); + } + + return 0; +} + +int iccp_cli_detach_mclag_domain_to_port_channel( const char* ifname) +{ + int unbind_poid = -1; + struct CSM *csm = NULL; + struct LocalInterface *lif_po = NULL; + struct LocalInterface *lif = NULL; + struct If_info * cif = NULL; + + if (!ifname) + return MCLAG_ERROR; + + if (strncmp(ifname, PORTCHANNEL_PREFIX, strlen(PORTCHANNEL_PREFIX)) != 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "Detach interface(%s) is not a port-channel", ifname); + return MCLAG_ERROR; + } + + /* find po*/ + if (!(lif_po = local_if_find_by_name(ifname)) + || lif_po->type != IF_T_PORT_CHANNEL + || lif_po->po_id <= 0 + || lif_po->csm == NULL) + { + return MCLAG_ERROR; + } + + /* find csm*/ + csm = lif_po->csm; + + ICCPD_LOG_DEBUG(__FUNCTION__, "Detach mclag id = %d from ifname = %s", + csm->mlag_id, lif_po->name); + + /* process link state handler before detaching it.*/ + mlacp_mlag_link_del_handler(csm, lif_po); + + unbind_poid = lif_po->po_id; + mlacp_unbind_local_if(lif_po); + LIST_FOREACH(lif, &(csm->app_csm.mlacp.lif_list), mlacp_next) + { + if (lif->type == IF_T_PORT && lif->po_id == unbind_poid) + mlacp_unbind_local_if(lif); + } + + LIST_FOREACH(cif, &(csm->if_bind_list), csm_next) + { + if (strcmp(ifname, cif->name) == 0) + LIST_REMOVE(cif, csm_next); + } + return 0; +} + +/* This function parses a string to a binary mac address (uint8_t[6]) + The string should contain mac address only. No spaces are allowed. + The mac address separators could be either ':' or '-'*/ +int parseMacString(const char * str_mac, uint8_t* bin_mac) +{ + int i; + + if (bin_mac == NULL) + { + return MCLAG_ERROR; + } + + /* 6 hexadecimal numbers (two digits each) + 5 delimiters*/ + if (strlen(str_mac) != ETHER_ADDR_LEN * 2 + 5) + { + return MCLAG_ERROR; + } + + /* first check that all mac address separators are equal to each other + 2, 5, 8, 11, and 14 are MAC address separator positions*/ + if (!(str_mac[2] == str_mac[5] + && str_mac[5] == str_mac[8] + && str_mac[8] == str_mac[11] + && str_mac[11] == str_mac[14])) + { + return MCLAG_ERROR; + } + + /* then check that the first separator is equal to ':' or '-'*/ + if (str_mac[2] != ':' && str_mac[2] != '-') + { + return MCLAG_ERROR; + } + + for (i = 0; i < ETHER_ADDR_LEN; ++i) + { + int left = i * 3; /* left digit position of hexadecimal number*/ + int right = left + 1; /* right digit position of hexadecimal number*/ + + if (str_mac[left] >= '0' && str_mac[left] <= '9') + { + bin_mac[i] = (uint8_t)(str_mac[left] - '0'); + } + else if (str_mac[left] >= 'A' && str_mac[left] <= 'F') + { + bin_mac[i] = (uint8_t)(str_mac[left] - 'A' + 0x0a); + } + else if (str_mac[left] >= 'a' && str_mac[left] <= 'f') + { + bin_mac[i] = (uint8_t)(str_mac[left] - 'a' + 0x0a); + } + else + { + return MCLAG_ERROR; + } + + bin_mac[i] = (uint8_t)(bin_mac[i] << 4); + + if (str_mac[right] >= '0' && str_mac[right] <= '9') + { + bin_mac[i] |= (uint8_t)(str_mac[right] - '0'); + } + else if (str_mac[right] >= 'A' && str_mac[right] <= 'F') + { + bin_mac[i] |= (uint8_t)(str_mac[right] - 'A' + 0x0a); + } + else if (str_mac[right] >= 'a' && str_mac[right] <= 'f') + { + bin_mac[i] |= (uint8_t)(str_mac[right] - 'a' + 0x0a); + } + else + { + return MCLAG_ERROR; + } + } + + return 0; +} + +int set_local_system_id(const char* mac) +{ + struct System* sys = NULL; + struct CSM* csm = NULL; + + if ((sys = system_get_instance()) == NULL ) + return 0; + + LIST_FOREACH(csm, &(sys->csm_list), next) + { + parseMacString(mac, MLACP(csm).system_id); + + ICCPD_LOG_DEBUG(__FUNCTION__, " Set local systemID [%02X:%02X:%02X:%02X:%02X:%02X].", + MLACP(csm).system_id[0], MLACP(csm).system_id[1], MLACP(csm).system_id[2], + MLACP(csm).system_id[3], MLACP(csm).system_id[4], MLACP(csm).system_id[5]); + } + + return 0; +} + +int unset_local_system_id( ) +{ + uint8_t null_mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + struct System* sys = NULL; + struct CSM* csm = NULL; + + if ((sys = system_get_instance()) == NULL ) + return 0; + + LIST_FOREACH(csm, &(sys->csm_list), next) + { + memcpy(MLACP(csm).system_id, null_mac, ETHER_ADDR_LEN); + } + + return 0; +} + diff --git a/src/iccpd/src/iccp_cmd.c b/src/iccpd/src/iccp_cmd.c new file mode 100644 index 000000000000..50025a8e3810 --- /dev/null +++ b/src/iccpd/src/iccp_cmd.c @@ -0,0 +1,168 @@ +/* + * iccp_cmd.c + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#include +#include +#include + +#include "../include/iccp_csm.h" +#include "../include/msg_format.h" +#include "../include/system.h" + +#include "../include/iccp_cmd_show.h" +#include "../include/iccp_cli.h" +#include "../include/logger.h" + +int set_mc_lag_by_id(uint16_t mid) +{ + int ret = 0; + struct CSM* csm = NULL; + + csm = system_get_csm_by_mlacp_id(mid); + if (!csm) + { + csm = (struct CSM*)iccp_get_csm(); + if (csm == NULL) + { + return MCLAG_ERROR; + } + + ret = set_mc_lag_id(csm, mid); + + return ret; + } + + return ret; +} + +#define CONFIG_LINE_LEN 512 + +int iccp_config_from_command(char * line) +{ + char *cp, *start; + char token[64]; + int slen; + static int mid = 0; + char *end; + + if (line == NULL) + return 0; + + cp = line; + + /* Skip white spaces. */ + while (isspace((int)*cp) && *cp != '\0') + cp++; + + /* Return if there is only white spaces */ + if (*cp == '\0') + return 0; + + end = cp; + + /* Skip end white spaces. */ + while (!isspace((int)*end) && *end != '\0') + end++; + + *end = '\0'; + /*mc-lag id*/ + if (strncmp(cp, MCLAG_ID_STR, strlen(MCLAG_ID_STR)) == 0 ) + { + cp += strlen(MCLAG_ID_STR) + 1; + mid = atoi(cp); + set_mc_lag_by_id(mid); + } + else if (strncmp(cp, LOCAL_IP_STR, strlen(LOCAL_IP_STR)) == 0) /*local ip*/ + { + cp += strlen(LOCAL_IP_STR) + 1; + set_local_address(mid, cp); + } + else if (strncmp(cp, PEER_IP_STR, strlen(PEER_IP_STR)) == 0) /*peer ip*/ + { + cp += strlen(PEER_IP_STR) + 1; + set_peer_address(mid, cp); + } + else if (strncmp(cp, PEER_LINK_STR, strlen(PEER_LINK_STR)) == 0)/*peer link*/ + { + cp += strlen(PEER_LINK_STR) + 1; + set_peer_link(mid, cp); + } + else if (strncmp(cp, MCLAG_INTF_STR, strlen(MCLAG_INTF_STR)) == 0)/*mclag interface*/ + { + cp += strlen(MCLAG_INTF_STR) + 1; + + while (1) + { + start = cp; + + while (!(*cp == ',' || *cp == '\r' || *cp == '\n') && + *cp != '\0') + cp++; + + slen = cp - start; + strncpy(token, start, slen); + *(token + slen) = '\0'; + iccp_cli_attach_mclag_domain_to_port_channel(mid, token); + + while ((isspace((int)*cp) || *cp == '\n' || *cp == '\r' || *cp == ',') && + *cp != '\0') + cp++; + + if (*cp == '\0') + break; + } + } + else if (strncmp(cp, SYSTEM_MAC_STR, strlen(SYSTEM_MAC_STR)) == 0)/*system mac*/ + { + cp += strlen(SYSTEM_MAC_STR) + 1; + set_local_system_id(cp); + } + else + { + /*error*/ + } + + return 1; +} + +/* Configration make from file. */ +int +iccp_config_from_file(char *config_default_dir) +{ + FILE *confp = NULL; + char command_buf[CONFIG_LINE_LEN]; + + confp = fopen(config_default_dir, "r"); + if (confp == NULL) + return (1); + + while (fgets(command_buf, CONFIG_LINE_LEN, confp)) + { + iccp_config_from_command(command_buf); + } + + fclose(confp); + + return 0; +} + diff --git a/src/iccpd/src/iccp_cmd_show.c b/src/iccpd/src/iccp_cmd_show.c new file mode 100644 index 000000000000..18b2e5bded8e --- /dev/null +++ b/src/iccpd/src/iccp_cmd_show.c @@ -0,0 +1,544 @@ +/* + * iccp_cmd_show.c + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ +#include +#include +#include +#include + +#include "../include/iccp_csm.h" +#include "../include/mlacp_tlv.h" +#include "../include/system.h" +#include "../include/logger.h" +#include "mclagdctl/mclagdctl.h" +#include "../include/iccp_cmd_show.h" +#include "../include/mlacp_link_handler.h" + +int iccp_mclag_config_dump(char * *buf, int *num, int mclag_id) +{ + struct mclagd_state state_info; + struct System *sys = NULL; + struct CSM *csm = NULL; + struct LocalInterface *peer_link_if = NULL; + struct LocalInterface *lif_po = NULL; + struct LoggerConfig* logconfig; + char unknown[] = { "Unknown" }; + int mclag_num = 0; + int id_exist = 0; + int str_size = 0; + int len = 0; + char *state_buf = NULL; + int state_buf_size = MCLAGDCTL_CMD_SIZE; + + if (!(sys = system_get_instance())) + { + return EXEC_TYPE_NO_EXIST_SYS; + } + + state_buf = (char*)malloc(state_buf_size); + if (!state_buf) + return EXEC_TYPE_FAILED; + + LIST_FOREACH(csm, &(sys->csm_list), next) + { + memset(&state_info, 0, sizeof(struct mclagd_state)); + + if (csm->current_state == ICCP_OPERATIONAL) + state_info.keepalive = 1; + else + state_info.keepalive = 0; + + if (mclag_id > 0) + { + if (csm->mlag_id == mclag_id) + id_exist = 1; + else + continue; + } + + peer_link_if = local_if_find_by_name(csm->peer_itf_name); + + if (csm->mlag_id <= 0) + state_info.mclag_id = -1; + else + state_info.mclag_id = csm->mlag_id; + + memcpy(state_info.local_ip, csm->sender_ip, ICCP_MAX_IP_STR_LEN); + memcpy(state_info.peer_ip, csm->peer_ip, ICCP_MAX_IP_STR_LEN); + + if (peer_link_if) + memcpy(state_info.peer_link_if, peer_link_if->name, ICCP_MAX_PORT_NAME); + else + memcpy(state_info.peer_link_if, unknown, strlen(unknown)); + + if (peer_link_if) + memcpy(state_info.peer_link_mac, peer_link_if->mac_addr, 6); + + logconfig = logger_get_configuration(); + memcpy(state_info.loglevel, log_level_to_string(logconfig->log_level), strlen( log_level_to_string(logconfig->log_level))); + + state_info.role = csm->role_type; + + str_size = MCLAGDCTL_PORT_MEMBER_BUF_LEN; + len = 0; + + LIST_FOREACH(lif_po, &(MLACP(csm).lif_list), mlacp_next) + { + + if (str_size - len < ICCP_MAX_PORT_NAME) + break; + + if (lif_po->type == IF_T_PORT_CHANNEL) + len += snprintf(state_info.enabled_po + len, str_size - len, "%s,", lif_po->name); + } + + /*Skip the last ','*/ + len = strlen(state_info.enabled_po); + if (len > 0) + { + state_info.enabled_po[len - 1] = '\0'; + } + + memcpy(state_buf + MCLAGD_REPLY_INFO_HDR + mclag_num * sizeof(struct mclagd_state), + &state_info, sizeof(struct mclagd_state)); + mclag_num++; + + if ((mclag_num + 1) * sizeof(struct mclagd_state) > (state_buf_size - MCLAGD_REPLY_INFO_HDR)) + { + state_buf_size += MCLAGDCTL_CMD_SIZE; + state_buf = (char*)realloc(state_buf, state_buf_size); + if (!state_buf) + return EXEC_TYPE_FAILED; + } + } + + *buf = state_buf; + *num = mclag_num; + + if (mclag_id > 0 && !id_exist) + return EXEC_TYPE_NO_EXIST_MCLAGID; + + return EXEC_TYPE_SUCCESS; +} + +int iccp_arp_dump(char * *buf, int *num, int mclag_id) +{ + struct System *sys = NULL; + struct CSM *csm = NULL; + struct Msg *msg = NULL; + struct ARPMsg *iccpd_arp = NULL; + struct mclagd_arp_msg mclagd_arp; + int arp_num = 0; + int id_exist = 0; + char * arp_buf = NULL; + int arp_buf_size = MCLAGDCTL_CMD_SIZE; + + if (!(sys = system_get_instance())) + { + return EXEC_TYPE_NO_EXIST_SYS; + } + + arp_buf = (char*)malloc(arp_buf_size); + if (!arp_buf) + return EXEC_TYPE_FAILED; + + LIST_FOREACH(csm, &(sys->csm_list), next) + { + if (mclag_id > 0) + { + if (csm->mlag_id == mclag_id) + id_exist = 1; + else + continue; + } + + TAILQ_FOREACH(msg, &MLACP(csm).arp_list, tail) + { + memset(&mclagd_arp, 0, sizeof(struct mclagd_arp_msg)); + iccpd_arp = (struct ARPMsg*)msg->buf; + + mclagd_arp.op_type = iccpd_arp->op_type; + memcpy(mclagd_arp.ifname, iccpd_arp->ifname, strlen(iccpd_arp->ifname)); + memcpy(mclagd_arp.ipv4_addr, show_ip_str(iccpd_arp->ipv4_addr), 16); + memcpy(mclagd_arp.mac_addr, iccpd_arp->mac_addr, 6); + + memcpy(arp_buf + MCLAGD_REPLY_INFO_HDR + arp_num * sizeof(struct mclagd_arp_msg), + &mclagd_arp, sizeof(struct mclagd_arp_msg)); + + arp_num++; + + if ((arp_num + 1) * sizeof(struct mclagd_arp_msg) > (arp_buf_size - MCLAGD_REPLY_INFO_HDR)) + { + arp_buf_size += MCLAGDCTL_CMD_SIZE; + arp_buf = (char*)realloc(arp_buf, arp_buf_size); + if (!arp_buf) + return EXEC_TYPE_FAILED; + } + } + } + + *buf = arp_buf; + *num = arp_num; + + if (mclag_id > 0 && !id_exist) + return EXEC_TYPE_NO_EXIST_MCLAGID; + + return EXEC_TYPE_SUCCESS; +} + +int iccp_ndisc_dump(char * *buf, int *num, int mclag_id) +{ + struct System *sys = NULL; + struct CSM *csm = NULL; + struct Msg *msg = NULL; + struct NDISCMsg *iccpd_ndisc = NULL; + struct mclagd_ndisc_msg mclagd_ndisc; + int ndisc_num = 0; + int id_exist = 0; + char *ndisc_buf = NULL; + int ndisc_buf_size = MCLAGDCTL_CMD_SIZE; + + if (!(sys = system_get_instance())) + { + ICCPD_LOG_INFO(__FUNCTION__, "cannot find sys!\n"); + return EXEC_TYPE_NO_EXIST_SYS; + } + + ndisc_buf = (char *)malloc(ndisc_buf_size); + if (!ndisc_buf) + return EXEC_TYPE_FAILED; + + LIST_FOREACH(csm, &(sys->csm_list), next) + { + if (mclag_id > 0) + { + if (csm->mlag_id == mclag_id) + id_exist = 1; + else + continue; + } + + TAILQ_FOREACH(msg, &MLACP(csm).ndisc_list, tail) + { + memset(&mclagd_ndisc, 0, sizeof(struct mclagd_ndisc_msg)); + iccpd_ndisc = (struct NDISCMsg *)msg->buf; + + mclagd_ndisc.op_type = iccpd_ndisc->op_type; + memcpy(mclagd_ndisc.ifname, iccpd_ndisc->ifname, strlen(iccpd_ndisc->ifname)); + memcpy(mclagd_ndisc.ipv6_addr, show_ipv6_str((char *)iccpd_ndisc->ipv6_addr), 46); + memcpy(mclagd_ndisc.mac_addr, iccpd_ndisc->mac_addr, 6); + + memcpy(ndisc_buf + MCLAGD_REPLY_INFO_HDR + ndisc_num * sizeof(struct mclagd_ndisc_msg), + &mclagd_ndisc, sizeof(struct mclagd_ndisc_msg)); + + ndisc_num++; + + if ((ndisc_num + 1) * sizeof(struct mclagd_ndisc_msg) > (ndisc_buf_size - MCLAGD_REPLY_INFO_HDR)) + { + ndisc_buf_size += MCLAGDCTL_CMD_SIZE; + ndisc_buf = (char *)realloc(ndisc_buf, ndisc_buf_size); + if (!ndisc_buf) + return EXEC_TYPE_FAILED; + } + } + } + + *buf = ndisc_buf; + *num = ndisc_num; + + if (mclag_id > 0 && !id_exist) + return EXEC_TYPE_NO_EXIST_MCLAGID; + + return EXEC_TYPE_SUCCESS; +} + +int iccp_mac_dump(char * *buf, int *num, int mclag_id) +{ + struct System *sys = NULL; + struct CSM *csm = NULL; + struct Msg *msg = NULL; + struct MACMsg *iccpd_mac = NULL; + struct mclagd_mac_msg mclagd_mac; + int mac_num = 0; + int id_exist = 0; + char * mac_buf = NULL; + int mac_buf_size = MCLAGDCTL_CMD_SIZE; + + if (!(sys = system_get_instance())) + { + return EXEC_TYPE_NO_EXIST_SYS; + } + + mac_buf = (char*)malloc(mac_buf_size); + if (!mac_buf) + return EXEC_TYPE_FAILED; + + LIST_FOREACH(csm, &(sys->csm_list), next) + { + if (mclag_id > 0) + { + if (csm->mlag_id == mclag_id) + id_exist = 1; + else + continue; + } + + TAILQ_FOREACH(msg, &MLACP(csm).mac_list, tail) + { + memset(&mclagd_mac, 0, sizeof(struct mclagd_mac_msg)); + iccpd_mac = (struct MACMsg*)msg->buf; + + mclagd_mac.op_type = iccpd_mac->op_type; + mclagd_mac.fdb_type = iccpd_mac->fdb_type; + memcpy(mclagd_mac.mac_str, iccpd_mac->mac_str, ETHER_ADDR_STR_LEN); + mclagd_mac.vid = iccpd_mac->vid; + memcpy(mclagd_mac.ifname, iccpd_mac->ifname, strlen(iccpd_mac->ifname)); + memcpy(mclagd_mac.origin_ifname, iccpd_mac->origin_ifname, strlen(iccpd_mac->origin_ifname)); + mclagd_mac.age_flag = iccpd_mac->age_flag; + + memcpy(mac_buf + MCLAGD_REPLY_INFO_HDR + mac_num * sizeof(struct mclagd_mac_msg), + &mclagd_mac, sizeof(struct mclagd_mac_msg)); + + mac_num++; + + if ((mac_num + 1) * sizeof(struct mclagd_mac_msg) > (mac_buf_size - MCLAGD_REPLY_INFO_HDR)) + { + mac_buf_size += MCLAGDCTL_CMD_SIZE; + mac_buf = (char*)realloc(mac_buf, mac_buf_size); + if (!mac_buf) + return EXEC_TYPE_FAILED; + } + } + } + + *buf = mac_buf; + *num = mac_num; + + if (mclag_id > 0 && !id_exist) + return EXEC_TYPE_NO_EXIST_MCLAGID; + + return EXEC_TYPE_SUCCESS; +} + +int iccp_local_if_dump(char * *buf, int *num, int mclag_id) +{ + struct System *sys = NULL; + struct CSM *csm = NULL; + struct LocalInterface *lif_po = NULL; + struct mclagd_local_if mclagd_lif; + struct VLAN_ID* vlan_id = NULL; + char * str_buf = NULL; + int str_size = MCLAGDCTL_PARA3_LEN - 1; + int len = 0; + int lif_num = 0; + int id_exist = 0; + int lif_buf_size = MCLAGDCTL_CMD_SIZE; + char * lif_buf = NULL; + + if (!(sys = system_get_instance())) + { + return EXEC_TYPE_NO_EXIST_SYS; + } + + lif_buf = (char*)malloc(lif_buf_size); + if (!lif_buf) + return EXEC_TYPE_FAILED; + + LIST_FOREACH(csm, &(sys->csm_list), next) + { + if (mclag_id > 0) + { + if (csm->mlag_id == mclag_id) + id_exist = 1; + else + continue; + } + + LIST_FOREACH(lif_po, &(MLACP(csm).lif_list), mlacp_next) + { + memset(&mclagd_lif, 0, sizeof(struct mclagd_local_if)); + + mclagd_lif.ifindex = lif_po->ifindex; + + if (lif_po->type == IF_T_UNKNOW) + memcpy(mclagd_lif.type, "Unknown", 6); + else if (lif_po->type == IF_T_PORT) + memcpy(mclagd_lif.type, "Ethernet", 8); + else if (lif_po->type == IF_T_PORT_CHANNEL) + memcpy(mclagd_lif.type, "PortChannel", 11); + + memcpy(mclagd_lif.name, lif_po->name, MAX_L_PORT_NAME); + memcpy(mclagd_lif.mac_addr, lif_po->mac_addr, ETHER_ADDR_LEN); + + if (lif_po->state == PORT_STATE_UP) + memcpy(mclagd_lif.state, "Up", 2); + else if (lif_po->state == PORT_STATE_DOWN) + memcpy(mclagd_lif.state, "Down", 4); + else if (lif_po->state == PORT_STATE_ADMIN_DOWN) + memcpy(mclagd_lif.state, "Admin-down", 10); + else if (lif_po->state == PORT_STATE_TEST) + memcpy(mclagd_lif.state, "Test", 4); + + memcpy(mclagd_lif.ipv4_addr, show_ip_str(htonl(lif_po->ipv4_addr)), 16); + mclagd_lif.prefixlen = lif_po->prefixlen; + + mclagd_lif.l3_mode = local_if_is_l3_mode(lif_po); + + mclagd_lif.is_peer_link = lif_po->is_peer_link; + + memcpy(mclagd_lif.portchannel_member_buf, lif_po->portchannel_member_buf, 512); + + mclagd_lif.po_id = lif_po->po_id; + mclagd_lif.po_active = lif_po->po_active; + /*mlacp_state*/ + if (lif_po->mlacp_state == MLACP_STATE_INIT) + memcpy(mclagd_lif.mlacp_state, "INIT", 4); + else if (lif_po->mlacp_state == MLACP_STATE_STAGE1) + memcpy(mclagd_lif.mlacp_state, "STAGE1", 6); + else if (lif_po->mlacp_state == MLACP_STATE_STAGE2) + memcpy(mclagd_lif.mlacp_state, "STAGE2", 6); + else if (lif_po->mlacp_state == MLACP_STATE_EXCHANGE) + memcpy(mclagd_lif.mlacp_state, "EXCHANGE", 8); + else if (lif_po->mlacp_state == MLACP_STATE_ERROR) + memcpy(mclagd_lif.mlacp_state, "ERROR", 5); + + mclagd_lif.isolate_to_peer_link = lif_po->isolate_to_peer_link; + + str_buf = mclagd_lif.vlanlist; + + len = 0; + LIST_FOREACH(vlan_id, &(lif_po->vlan_list), port_next) + { + if (vlan_id != NULL ) + { + if (str_size - len < 4) + break; + len += snprintf(str_buf + len, str_size - len, "%d ", vlan_id->vid); + } + } + + memcpy(lif_buf + MCLAGD_REPLY_INFO_HDR + lif_num * sizeof(struct mclagd_local_if), + &mclagd_lif, sizeof(struct mclagd_local_if)); + + lif_num++; + + if ((lif_num + 1) * sizeof(struct mclagd_local_if) > (lif_buf_size - MCLAGD_REPLY_INFO_HDR)) + { + lif_buf_size += MCLAGDCTL_CMD_SIZE; + lif_buf = (char*)realloc(lif_buf, lif_buf_size); + if (!lif_buf) + return EXEC_TYPE_FAILED; + } + } + } + + *buf = lif_buf; + *num = lif_num; + + if (mclag_id > 0 && !id_exist) + return EXEC_TYPE_NO_EXIST_MCLAGID; + + return EXEC_TYPE_SUCCESS; +} + +int iccp_peer_if_dump(char * *buf, int *num, int mclag_id) +{ + struct System *sys = NULL; + struct CSM *csm = NULL; + struct PeerInterface *pif_po = NULL; + struct mclagd_peer_if mclagd_pif; + int pif_num = 0; + int id_exist = 0; + int pif_buf_size = MCLAGDCTL_CMD_SIZE; + char *pif_buf = NULL; + + if (!(sys = system_get_instance())) + { + return EXEC_TYPE_NO_EXIST_SYS; + } + + pif_buf = (char*)malloc(pif_buf_size); + if (!pif_buf) + return EXEC_TYPE_FAILED; + + LIST_FOREACH(csm, &(sys->csm_list), next) + { + if (mclag_id > 0) + { + if (csm->mlag_id == mclag_id) + id_exist = 1; + else + continue; + } + + LIST_FOREACH(pif_po, &(MLACP(csm).pif_list), mlacp_next) + { + memset(&mclagd_pif, 0, sizeof(struct mclagd_peer_if)); + + mclagd_pif.ifindex = pif_po->ifindex; + + if (pif_po->type == IF_T_UNKNOW) + memcpy(mclagd_pif.type, "Unknown", 6); + else if (pif_po->type == IF_T_PORT) + memcpy(mclagd_pif.type, "Ethernet", 8); + else if (pif_po->type == IF_T_PORT_CHANNEL) + memcpy(mclagd_pif.type, "PortChannel", 11); + + memcpy(mclagd_pif.name, pif_po->name, MAX_L_PORT_NAME); + memcpy(mclagd_pif.mac_addr, pif_po->mac_addr, ETHER_ADDR_LEN); + + if (pif_po->state == PORT_STATE_UP) + memcpy(mclagd_pif.state, "Up", 2); + else if (pif_po->state == PORT_STATE_DOWN) + memcpy(mclagd_pif.state, "Down", 4); + else if (pif_po->state == PORT_STATE_ADMIN_DOWN) + memcpy(mclagd_pif.state, "Admin-down", 10); + else if (pif_po->state == PORT_STATE_TEST) + memcpy(mclagd_pif.state, "Test", 4); + + mclagd_pif.po_id = pif_po->po_id; + mclagd_pif.po_active = pif_po->po_active; + + memcpy(pif_buf + MCLAGD_REPLY_INFO_HDR + pif_num * sizeof(struct mclagd_peer_if), + &mclagd_pif, sizeof(struct mclagd_peer_if)); + + pif_num++; + + if ((pif_num + 1) * sizeof(struct mclagd_peer_if) > (pif_buf_size - MCLAGD_REPLY_INFO_HDR)) + { + pif_buf_size += MCLAGDCTL_CMD_SIZE; + pif_buf = (char*)realloc(pif_buf, pif_buf_size); + if (!pif_buf) + return EXEC_TYPE_FAILED; + } + } + } + + *buf = pif_buf; + *num = pif_num; + + if (mclag_id > 0 && !id_exist) + return EXEC_TYPE_NO_EXIST_MCLAGID; + + return EXEC_TYPE_SUCCESS; +} + diff --git a/src/iccpd/src/iccp_consistency_check.c b/src/iccpd/src/iccp_consistency_check.c new file mode 100644 index 000000000000..90ac9cd9e790 --- /dev/null +++ b/src/iccpd/src/iccp_consistency_check.c @@ -0,0 +1,175 @@ +/* + * iccp_consistency_check.c + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + * + */ + +#include "../include/iccp_consistency_check.h" +#include "../include/system.h" +#include "../include/port.h" +#include "../include/logger.h" + +/* Return 0 if the checking procedure is failed; otherwise, 1 (non-zero) will be returned. */ +typedef int (*ConsistencyCheckFunc)(char* ifname); + +const char *reasons[] = { + /* REASON_NONE */ + "Success", + /* REASON_INTERRFACE_MODE_IS_ASYNC */ + "Port-channel interface is not in the same mode in local and peer device, please check whether the ip addr settings is correct or not.", + /* REASON_PEER_IF_IP_IS_ASYNC */ + "IP address of peer interface is not synchronized, please check the IP address setting on the corresponding interface.", + /* REASON_PEER_IF_VLAN_IS_ASYNC */ + "VLAN settings on this port-channel interface is not synchronized, please check your configuration.", + /* REASON_MAX_ARRAY_SIZE */ + NULL +}; + +/* Consistency Checking functions */ +static int iccp_check_interface_mode( char* ifname) +{ + struct CSM* csm = NULL; + struct LocalInterface* local_if = NULL; + struct PeerInterface* peer_if = NULL; + + local_if = local_if_find_by_name(ifname); + if (local_if == NULL) + return -2; + + csm = local_if->csm; + if (csm == NULL) + return -3; + + peer_if = peer_if_find_by_name(csm, ifname); + if (peer_if == NULL) + return -4; + + if (peer_if->l3_mode != local_if->l3_mode) + return -5; + + return 1; +} + +static int iccp_check_interface_layer3_addr(char* ifname) +{ + struct CSM* csm = NULL; + struct LocalInterface* local_if = NULL; + struct PeerInterface* peer_if = NULL; + + local_if = local_if_find_by_name(ifname); + if (local_if == NULL) + return -2; + + csm = local_if->csm; + if (csm == NULL) + return -3; + + peer_if = peer_if_find_by_name(csm, ifname); + if (peer_if == NULL) + return -4; + + if (peer_if->ipv4_addr != local_if->ipv4_addr) + return -5; + + return 1; +} + +static int iccp_check_interface_vlan(char* ifname) +{ + struct CSM* csm = NULL; + struct PeerInterface* peer_if = NULL; + struct VLAN_ID* local_vlan = NULL; + struct VLAN_ID* peer_vlan = NULL; + struct LocalInterface* local_if = NULL; + + local_if = local_if_find_by_name(ifname); + if (local_if == NULL) + return -2; + + csm = local_if->csm; + if (csm == NULL) + return -3; + + peer_if = peer_if_find_by_name(csm, ifname); + if (peer_if == NULL) + return -4; + + LIST_FOREACH(local_vlan, &(local_if->vlan_list), port_next) + { + LIST_FOREACH(peer_vlan, &(peer_if->vlan_list), port_next) + { + if (peer_vlan->vid == local_vlan->vid) + break; + } + + if (peer_vlan == NULL) + { + return -5; + } + } + + LIST_FOREACH(peer_vlan, &(peer_if->vlan_list), port_next) + { + + LIST_FOREACH(local_vlan, &(local_if->vlan_list), port_next) + { + if (peer_vlan->vid == local_vlan->vid) + break; + } + + if (local_vlan == NULL) + { + return -6; + } + } + + return 1; +} + +static const ConsistencyCheckFunc check_func[] = { + NULL, + iccp_check_interface_mode, /* REASON_INTERFACE_MODE_IS_ASYNC */ + iccp_check_interface_layer3_addr, /* REASON_PEER_IF_IP_IS_ASYNC */ + iccp_check_interface_vlan, /* REASON_PEER_IF_VLAN_IS_ASYNC */ + NULL /* REASON_MAX_ARRAY_SIZE */ +}; +#define ARRAY_SIZE(array_name) (sizeof(array_name) / sizeof(array_name[0])) + +enum Reason_ID iccp_consistency_check(char* ifname) +{ + int i = 0; + int ret = 0; + + for (i = REASON_INTERRFACE_MODE_IS_ASYNC; i < REASON_MAX_ARRAY_SIZE; ++i) + { + if (check_func[i] == NULL) + continue; + ret = check_func[i](ifname); + if (ret != 1) + { + ICCPD_LOG_WARN(__FUNCTION__, "%s ret = %d", reasons[i], ret); + fprintf(stdout, "%s \n", reasons[i]); + return i; + } + } + + return REASON_NONE; +} diff --git a/src/iccpd/src/iccp_csm.c b/src/iccpd/src/iccp_csm.c new file mode 100644 index 000000000000..79e17b9e1ba2 --- /dev/null +++ b/src/iccpd/src/iccp_csm.c @@ -0,0 +1,797 @@ +/* + * iccp_csm.c + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#include +#include + +#include "../include/logger.h" +#include "../include/system.h" +#include "../include/scheduler.h" +#include "../include/msg_format.h" +#include "../include/iccp_csm.h" +#include "../include/mlacp_link_handler.h" +/***************************************** +* Define +* +* ***************************************/ +#define ICCP_CSM_QUEUE_REINIT(list) \ + { \ + struct Msg* msg = NULL; \ + while (!TAILQ_EMPTY(&(list))) { \ + msg = TAILQ_FIRST(&(list)); \ + TAILQ_REMOVE(&(list), msg, tail); \ + free(msg->buf); \ + free(msg); \ + } \ + TAILQ_INIT(&(list)); \ + } + +/***************************************** +* Global +* +* ***************************************/ +char g_csm_buf[CSM_BUFFER_SIZE] = { 0 }; + +uint32_t ICCP_MSG_ID = 0x1; + +/* Enter Connection State Machine NONEXISTENT handle function */ +static void iccp_csm_enter_state_nonexistent(struct CSM* csm) +{ + iccp_csm_finalize(csm); +} + +/* Enter Connection State Machine INITIALIZED handle function */ +static void iccp_csm_enter_state_initialized(struct CSM* csm) +{ + if (csm == NULL) + return; + + csm->iccp_info.sender_capability_flag = 0x1; +} + +/* Enter Connection State Machine CAPREC handle function */ +static void iccp_csm_enter_state_caprec(struct CSM* csm) +{ + if (csm == NULL) + return; + + csm->iccp_info.sender_capability_flag = 0x1; + csm->iccp_info.peer_capability_flag = 0x1; +} + +/* Enter Connection State Machine CONNECTING handle function */ +static void iccp_csm_enter_state_connecting(struct CSM* csm) +{ + if (csm == NULL) + return; + + csm->iccp_info.sender_rg_connect_flag = 0x1; +} + +/* Enter Connection State Machine OPERATIONAL handle function */ +static void iccp_csm_enter_state_operational(struct CSM* csm) +{ + if (csm == NULL) + return; + + csm->iccp_info.sender_rg_connect_flag = 0x1; + csm->iccp_info.peer_rg_connect_flag = 0x1; +} + +void *iccp_get_csm() +{ + struct CSM* csm = NULL; + struct System* sys = NULL; + + if ((sys = system_get_instance()) == NULL) + { + return NULL; + } + + csm = system_create_csm(); + + return csm; +} + +/* Connection State Machine instance initialization */ +void iccp_csm_init(struct CSM* csm) +{ + iccp_csm_status_reset(csm, 1); + memset(csm->sender_ip, 0, INET_ADDRSTRLEN); + memset(csm->peer_ip, 0, INET_ADDRSTRLEN); + memset(csm->iccp_info.sender_name, 0, MAX_L_ICC_SENDER_NAME); + csm->iccp_info.icc_rg_id = 0x0; +} + +/* Connection State Machine instance status reset */ +void iccp_csm_status_reset(struct CSM* csm, int all) +{ + ICCP_CSM_QUEUE_REINIT(csm->msg_list); + + if (all) + { + bzero(csm, sizeof(struct CSM)); + ICCP_CSM_QUEUE_REINIT(csm->msg_list); + } + + csm->sock_fd = -1; + pthread_mutex_init(&csm->conn_mutex, NULL); + csm->connTimePrev = 0; + csm->heartbeat_send_time = 0; + csm->heartbeat_update_time = 0; + csm->peer_warm_reboot_time = 0; + csm->warm_reboot_disconn_time = 0; + csm->role_type = STP_ROLE_NONE; + csm->sock_read_event_ptr = NULL; + csm->peer_link_if = NULL; + csm->u_msg_in_count = 0x0; + csm->i_msg_in_count = 0x0; + csm->icc_msg_in_count = 0x0; + csm->icc_msg_out_count = 0x0; + csm->iccp_info.status_code = 0x0; + csm->iccp_info.rejected_msg_id = 0x0; + csm->current_state = ICCP_NONEXISTENT; + csm->iccp_info.peer_capability_flag = 0x0; + csm->iccp_info.peer_rg_connect_flag = 0x0; + csm->iccp_info.sender_capability_flag = 0x0; + csm->iccp_info.sender_rg_connect_flag = 0x0; + app_csm_init(csm, all); + + memset(&csm->msg_log, 0, sizeof(struct MsgLog)); +} + +/* Connection State Machine instance tear down */ +void iccp_csm_finalize(struct CSM* csm) +{ + struct If_info * cif = NULL; + struct System* sys = NULL; + + if (csm == NULL) + return; + + if ((sys = system_get_instance()) == NULL) + return; + + /*If warm reboot, don't change port block and peer link MAC learning*/ + if (sys->warmboot_exit != WARM_REBOOT) + { + /*Enable peer link port MAC learning*/ + if (csm->peer_link_if) + set_peerlink_mlag_port_learn(csm->peer_link_if, 1); + } + + /* Disconnect from peer */ + scheduler_session_disconnect_handler(csm); + + /* Release all Connection State Machine instance */ + app_csm_finalize(csm); + + LIST_FOREACH(cif, &(csm->if_bind_list), csm_next) + { + LIST_REMOVE(cif, csm_next); + } + + /* Release iccp_csm */ + pthread_mutex_destroy(&(csm->conn_mutex)); + iccp_csm_msg_list_finalize(csm); + LIST_REMOVE(csm, next); + free(csm); +} + +/* Message list of Connection State Machine instance tear down */ +void iccp_csm_msg_list_finalize(struct CSM* csm) +{ + struct Msg* msg = NULL; + + if (csm == NULL) + return; + + while (!TAILQ_EMPTY(&(csm->msg_list))) + { + msg = TAILQ_FIRST(&(csm->msg_list)); + TAILQ_REMOVE(&(csm->msg_list), msg, tail); + free(msg); + } +} + +/* Send message to peer */ +int iccp_csm_send(struct CSM* csm, char* buf, int msg_len) +{ + LDPHdr* ldp_hdr = (LDPHdr*)buf; + ICCParameter* param = NULL; + + if (csm == NULL || buf == NULL || csm->sock_fd <= 0 || msg_len <= 0) + return MCLAG_ERROR; + + if (ntohs(ldp_hdr->msg_type) == MSG_T_CAPABILITY) + param = (struct ICCParameter*)&buf[sizeof(LDPHdr)]; + else + param = (struct ICCParameter*)&buf[sizeof(ICCHdr)]; + + /*ICCPD_LOG_DEBUG(__FUNCTION__, "Send(%d): len=[%d] msg_type=[%s (0x%X, 0x%X)]", csm->sock_fd, msg_len, get_tlv_type_string(param->type), ldp_hdr->msg_type, param->type);*/ + csm->msg_log.msg[csm->msg_log.end_index].msg_id = ntohl(ldp_hdr->msg_id); + csm->msg_log.msg[csm->msg_log.end_index].type = ntohs(ldp_hdr->msg_type); + csm->msg_log.msg[csm->msg_log.end_index].tlv = ntohs(param->type); + ++csm->msg_log.end_index; + if (csm->msg_log.end_index >= 128) + csm->msg_log.end_index = 0; + + return write(csm->sock_fd, buf, msg_len); +} + +/* Connection State Machine Transition */ +void iccp_csm_transit(struct CSM* csm) +{ + int len = -1; + struct Msg* msg = NULL; + ICCP_CONNECTION_STATE_E prev_state; + char *state_str[] = {"NONEXISTENT", "INITIALIZED", "CAPSENT", "CAPREC", "CONNECTING", "OPERATIONAL"}; + + if (!csm) + return; + + prev_state = csm->current_state; + + /* No connection, but have state change? reset it...*/ + if (csm->current_state != ICCP_NONEXISTENT && csm->sock_fd <= 0) + { + ICCPD_LOG_NOTICE(__FUNCTION__, "csm %d change state from %s to NONEXISTENT.", csm->mlag_id, state_str[csm->current_state]); + csm->current_state = ICCP_NONEXISTENT; + iccp_csm_enter_state_nonexistent(csm); + return; + } + + msg = iccp_csm_dequeue_msg(csm); + + switch (csm->current_state) + { + case ICCP_NONEXISTENT: + scheduler_prepare_session(csm); + if (csm->sock_fd > 0 && scheduler_check_csm_config(csm) > 0) + csm->current_state = ICCP_INITIALIZED; + break; + + case ICCP_INITIALIZED: + if (msg) + iccp_csm_correspond_from_msg(csm, msg); + len = iccp_csm_prepare_iccp_msg(csm, g_csm_buf, CSM_BUFFER_SIZE); + iccp_csm_send(csm, g_csm_buf, len); + if (csm->iccp_info.sender_capability_flag == 0x1 && csm->iccp_info.peer_capability_flag == 0x0) + csm->current_state = ICCP_CAPSENT; + else if (csm->iccp_info.sender_capability_flag == 0x1 && csm->iccp_info.peer_capability_flag == 0x1) + csm->current_state = ICCP_CAPREC; + break; + + case ICCP_CAPSENT: + if (msg) + iccp_csm_correspond_from_msg(csm, msg); + if (csm->iccp_info.sender_capability_flag == 0x1 && csm->iccp_info.peer_capability_flag == 0x1) + csm->current_state = ICCP_CAPREC; + break; + + case ICCP_CAPREC: + if (msg) + iccp_csm_correspond_from_msg(csm, msg); + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + len = iccp_csm_prepare_iccp_msg(csm, g_csm_buf, CSM_BUFFER_SIZE); + iccp_csm_send(csm, g_csm_buf, len); + if (csm->iccp_info.peer_rg_connect_flag == 0x0 && csm->iccp_info.status_code == 0x0) + csm->current_state = ICCP_CONNECTING; + else if (csm->iccp_info.peer_rg_connect_flag == 0x1 && csm->iccp_info.status_code == 0x0) + csm->current_state = ICCP_OPERATIONAL; + break; + + case ICCP_CONNECTING: + if (msg) + iccp_csm_correspond_from_msg(csm, msg); + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + len = iccp_csm_prepare_iccp_msg(csm, g_csm_buf, CSM_BUFFER_SIZE); + iccp_csm_send(csm, g_csm_buf, len); + if (csm->iccp_info.status_code > 0x0) + csm->current_state = ICCP_CAPREC; + else if (csm->iccp_info.peer_rg_connect_flag == 0x1 && csm->iccp_info.status_code == 0x0) + csm->current_state = ICCP_OPERATIONAL; + break; + + case ICCP_OPERATIONAL: + if (msg) + iccp_csm_correspond_from_msg(csm, msg); + if (csm->iccp_info.sender_rg_connect_flag == 0x0 || csm->iccp_info.peer_rg_connect_flag == 0x0) + { + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + len = iccp_csm_prepare_iccp_msg(csm, g_csm_buf, CSM_BUFFER_SIZE); + iccp_csm_send(csm, g_csm_buf, len); + csm->current_state = ICCP_CAPREC; + } + break; + + default: + break; + } + + if (prev_state != csm->current_state || (csm->current_state && msg != NULL)) + { + if (prev_state != csm->current_state) + ICCPD_LOG_NOTICE(__FUNCTION__, "csm %d change state from %s to %s.", csm->mlag_id, state_str[prev_state], state_str[csm->current_state]); + + switch (csm->current_state) + { + case ICCP_NONEXISTENT: + iccp_csm_enter_state_nonexistent(csm); + break; + + case ICCP_INITIALIZED: + iccp_csm_enter_state_initialized(csm); + break; + + case ICCP_CAPSENT: + /* Do nothing on this state */ + break; + + case ICCP_CAPREC: + iccp_csm_enter_state_caprec(csm); + break; + + case ICCP_CONNECTING: + iccp_csm_enter_state_connecting(csm); + break; + + case ICCP_OPERATIONAL: + iccp_csm_enter_state_operational(csm); + break; + + default: + break; + } + } +} + +/* Set up ICCP message */ +int iccp_csm_prepare_iccp_msg(struct CSM* csm, char* buf, size_t max_buf_size) +{ + size_t msg_len = -1; + + if (csm == NULL || buf == NULL) + return MCLAG_ERROR; + + switch (csm->current_state) + { + case ICCP_NONEXISTENT: + /* Do nothing on this state */ + break; + + case ICCP_INITIALIZED: + msg_len = iccp_csm_prepare_capability_msg(csm, buf, max_buf_size); + break; + + case ICCP_CAPSENT: + /* Do nothing on this state */ + break; + + case ICCP_CAPREC: + if (csm->iccp_info.status_code > 0x0) + { + msg_len = iccp_csm_prepare_nak_msg(csm, buf, max_buf_size); + break; + } + msg_len = iccp_csm_prepare_rg_connect_msg(csm, buf, max_buf_size); + break; + + case ICCP_CONNECTING: + if (csm->iccp_info.status_code > 0x0) + { + msg_len = iccp_csm_prepare_nak_msg(csm, buf, max_buf_size); + break; + } + break; + + case ICCP_OPERATIONAL: + if (csm->iccp_info.peer_rg_connect_flag == 0x0) + { + msg_len = iccp_csm_prepare_rg_disconnect_msg(csm, buf, max_buf_size); + break; + } + break; + } + + return msg_len; +} + +/* ICCP capability message handle function */ +int iccp_csm_prepare_capability_msg(struct CSM* csm, char* buf, size_t max_buf_size) +{ + LDPHdr* ldp_hdr = (LDPHdr*)buf; + LDPICCPCapabilityTLV* cap = (LDPICCPCapabilityTLV*)&buf[sizeof(LDPHdr)]; + size_t msg_len = sizeof(LDPHdr) + sizeof(LDPICCPCapabilityTLV); + + memset(buf, 0, max_buf_size); + + /* LDP header */ + ldp_hdr->u_bit = 0x0; + ldp_hdr->msg_type = htons(MSG_T_CAPABILITY); + ldp_hdr->msg_len = htons(msg_len - MSG_L_INCLUD_U_BIT_MSG_T_L_FIELDS); + ldp_hdr->msg_id = htonl(ICCP_MSG_ID++); + + /* LDP ICCP capability TLV */ + cap->icc_parameter.u_bit = 0x1; + cap->icc_parameter.f_bit = 0x0; + cap->icc_parameter.type = TLV_T_ICCP_CAPABILITY; + *(uint16_t *)cap = htons(*(uint16_t *)cap); + + cap->icc_parameter.len = htons(TLV_L_ICCP_CAPABILITY); + + cap->s_bit = csm->iccp_info.sender_capability_flag; + *(uint16_t *)((uint8_t *)cap + sizeof(ICCParameter)) = htons(*(uint16_t *)((uint8_t *)cap + sizeof(ICCParameter))); + + cap->major_ver = 0x1; + cap->minior_ver = 0x0; + + return msg_len; +} + +void iccp_csm_fill_icc_rg_id_tlv(struct CSM* csm, ICCHdr* icc_hdr) +{ + if (!csm || !icc_hdr) + return; + + icc_hdr->icc_rg_id_tlv.type = htons(TLV_T_ICC_RG_ID); + icc_hdr->icc_rg_id_tlv.len = htons(TLV_L_ICC_RG_ID); + icc_hdr->icc_rg_id_tlv.icc_rg_id = htonl(csm->iccp_info.icc_rg_id); +} + +/* ICCP NAK message handle function */ +int iccp_csm_prepare_nak_msg(struct CSM* csm, char* buf, size_t max_buf_size) +{ + ICCHdr* icc_hdr = (ICCHdr*)buf; + NAKTLV* nak = (NAKTLV*)&buf[sizeof(ICCHdr)]; + size_t msg_len = sizeof(ICCHdr) + sizeof(NAKTLV); + + memset(buf, 0, max_buf_size); + + /* ICC header */ + icc_hdr->ldp_hdr.u_bit = 0x0; + icc_hdr->ldp_hdr.msg_type = htons(MSG_T_NOTIFICATION); + icc_hdr->ldp_hdr.msg_len = htons(msg_len - MSG_L_INCLUD_U_BIT_MSG_T_L_FIELDS); + icc_hdr->ldp_hdr.msg_id = htonl(ICCP_MSG_ID++); + iccp_csm_fill_icc_rg_id_tlv(csm, icc_hdr); + + /* NAL TLV */ + nak->icc_parameter.u_bit = 0x0; + nak->icc_parameter.f_bit = 0x0; + nak->icc_parameter.type = htons(TLV_T_NAK); + nak->icc_parameter.len = htons(sizeof(((struct NAKTLV*)0)->iccp_status_code) + sizeof(((struct NAKTLV*)0)->rejected_msg_id)); + + switch (csm->iccp_info.status_code) + { + case STATUS_CODE_U_ICCP_RG: + nak->iccp_status_code = htonl(csm->iccp_info.status_code); + nak->rejected_msg_id = htonl(csm->iccp_info.rejected_msg_id); + break; + + /* Unsupported */ + case STATUS_CODE_ICCP_CONNECTION_COUNT_EXCEEDED: + case STATUS_CODE_ICCP_APP_CONNECTION_COUNT_EXCEEDED: + case STATUS_CODE_ICCP_APP_NOT_IN_RG: + case STATUS_CODE_INCOMPATIBLE_ICCP_PROTOCOL_VER: + case STATUS_CODE_ICCP_REJECTED_MSG: + case STATUS_CODE_ICCP_ADMINISTRATIVELY_DISABLED: + case STATUS_CODE_ICCP_RG_REMOVED: + case STATUS_CODE_ICCP_APP_REMOVED_FROM_RG: + break; + } + + return msg_len; +} + +/* ICCP RG connect handle function */ +int iccp_csm_prepare_rg_connect_msg(struct CSM* csm, char* buf, size_t max_buf_size) +{ + ICCHdr* icc_hdr = (ICCHdr*)buf; + ICCSenderNameTLV* sender = (ICCSenderNameTLV*)&buf[sizeof(ICCHdr)]; + size_t name_len = strlen(csm->iccp_info.sender_name); + size_t msg_len = sizeof(ICCHdr) + sizeof(ICCParameter) + name_len; + + memset(buf, 0, max_buf_size); + + /* ICC header */ + icc_hdr->ldp_hdr.u_bit = 0x0; + icc_hdr->ldp_hdr.msg_type = htons(MSG_T_RG_CONNECT); + icc_hdr->ldp_hdr.msg_len = htons(msg_len - MSG_L_INCLUD_U_BIT_MSG_T_L_FIELDS); + icc_hdr->ldp_hdr.msg_id = htonl(ICCP_MSG_ID++); + iccp_csm_fill_icc_rg_id_tlv(csm, icc_hdr); + + /* ICC sender name TLV */ + sender->icc_parameter.u_bit = 0x0; + sender->icc_parameter.f_bit = 0x0; + sender->icc_parameter.type = htons(TLV_T_ICC_SENDER_NAME); + sender->icc_parameter.len = htons(name_len); + memcpy(sender->sender_name, csm->iccp_info.sender_name, name_len); + + return msg_len; +} + +/* ICCP RG disconnect handle function */ +int iccp_csm_prepare_rg_disconnect_msg(struct CSM* csm, char* buf, size_t max_buf_size) +{ + ICCHdr* icc_hdr = (ICCHdr*)buf; + DisconnectCodeTLV* disconn_code = (DisconnectCodeTLV*)&buf[sizeof(ICCHdr)]; + size_t msg_len = sizeof(ICCHdr) + sizeof(DisconnectCodeTLV); + + memset(buf, 0, max_buf_size); + + /* ICC header */ + icc_hdr->ldp_hdr.u_bit = 0x0; + icc_hdr->ldp_hdr.msg_type = htons(MSG_T_RG_DISCONNECT); + icc_hdr->ldp_hdr.msg_len = htons(msg_len - MSG_L_INCLUD_U_BIT_MSG_T_L_FIELDS); + icc_hdr->ldp_hdr.msg_id = htonl(ICCP_MSG_ID++); + iccp_csm_fill_icc_rg_id_tlv(csm, icc_hdr); + + /* Disconnect code TLV */ + disconn_code->icc_parameter.u_bit = 0x0; + disconn_code->icc_parameter.f_bit = 0x0; + disconn_code->icc_parameter.type = htons(TLV_T_DISCONNECT_CODE); + disconn_code->icc_parameter.len = htons(sizeof(((struct DisconnectCodeTLV*)0)->iccp_status_code)); + disconn_code->iccp_status_code = htonl(csm->iccp_info.status_code); + + return msg_len; +} + +/* Check ID(MC-LAG ID, mLACP ID, RG ID) from received message */ +static void iccp_csm_check_id_from_msg(struct CSM* csm, struct Msg* msg) +{ + ICCHdr* icc_hdr = NULL; + + if (!csm || !msg || !msg->buf) + return; + + icc_hdr = (ICCHdr*)msg->buf; + + /* Capability Message doesn't have ICC RG ID TLV */ + if (icc_hdr->ldp_hdr.msg_type == MSG_T_CAPABILITY) + return; + + /* Check if received message ID same as local configuration */ + if (ntohl(icc_hdr->icc_rg_id_tlv.icc_rg_id) == csm->iccp_info.icc_rg_id) + { + if (csm->iccp_info.status_code == STATUS_CODE_U_ICCP_RG) + { + csm->iccp_info.status_code = 0x0; + csm->iccp_info.rejected_msg_id = 0x0; + } + } + else if (ntohl(icc_hdr->icc_rg_id_tlv.icc_rg_id) != csm->iccp_info.icc_rg_id) + { + csm->iccp_info.status_code = STATUS_CODE_U_ICCP_RG; + csm->iccp_info.rejected_msg_id = ntohl(icc_hdr->icc_rg_id_tlv.icc_rg_id); + } +} + +/* Receive message correspond function */ +void iccp_csm_correspond_from_msg(struct CSM* csm, struct Msg* msg) +{ + ICCHdr* icc_hdr = NULL; + + if (csm == NULL || msg == NULL || msg->buf == NULL) + return; + + icc_hdr = (ICCHdr*)msg->buf; + NAKTLV* nak = (NAKTLV*)( icc_hdr + sizeof(ICCHdr)); + iccp_csm_check_id_from_msg(csm, msg); + + if (icc_hdr->ldp_hdr.msg_type == MSG_T_CAPABILITY) + iccp_csm_correspond_from_capability_msg(csm, msg); + else if (icc_hdr->ldp_hdr.msg_type == MSG_T_RG_CONNECT) + iccp_csm_correspond_from_rg_connect_msg(csm, msg); + else if (icc_hdr->ldp_hdr.msg_type == MSG_T_RG_DISCONNECT) + iccp_csm_correspond_from_rg_disconnect_msg(csm, msg); + else if (icc_hdr->ldp_hdr.msg_type == MSG_T_NOTIFICATION) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "Received MSG_T_NOTIFICATION ,err status %s reason of %s", get_status_string(ntohl(nak->iccp_status_code)), get_status_string(csm->iccp_info.status_code)); + sleep(1); + } + else if (icc_hdr->ldp_hdr.msg_type == MSG_T_RG_APP_DATA) + { + ;// do nothing + } + else + { + ++csm->u_msg_in_count; + } + + free(msg->buf); + free(msg); +} + +/* Receive capability message correspond function */ +void iccp_csm_correspond_from_capability_msg(struct CSM* csm, struct Msg* msg) +{ + LDPICCPCapabilityTLV* cap = (LDPICCPCapabilityTLV*)&(msg->buf)[sizeof(LDPHdr)]; + + *(uint16_t *)cap = ntohs(*(uint16_t *)cap); + *(uint16_t *)((uint8_t *)cap + sizeof(ICCParameter)) = ntohs(*(uint16_t *)((uint8_t *)cap + sizeof(ICCParameter))); + + if (cap->icc_parameter.u_bit == 0x1 + && cap->icc_parameter.f_bit == 0x0 + && cap->icc_parameter.type == TLV_T_ICCP_CAPABILITY + && ntohs(cap->icc_parameter.len) == (TLV_L_ICCP_CAPABILITY) + && cap->s_bit == 1 + && cap->major_ver == 0x1 + && cap->minior_ver == 0x0) + { + csm->iccp_info.peer_capability_flag = 0x1; + } +} + +/* Receive RG connect message correspond function */ +void iccp_csm_correspond_from_rg_connect_msg(struct CSM* csm, struct Msg* msg) +{ + ICCSenderNameTLV* sender = (ICCSenderNameTLV*)&(msg->buf)[sizeof(ICCHdr)]; + + *(uint16_t *)sender = ntohs(*(uint16_t *)sender); + + if (sender->icc_parameter.u_bit == 0x0 && + sender->icc_parameter.f_bit == 0x0 && + sender->icc_parameter.type == TLV_T_ICC_SENDER_NAME) + { + csm->iccp_info.peer_rg_connect_flag = 0x1; + } +} + +/* Receive RG disconnect message correspond function */ +void iccp_csm_correspond_from_rg_disconnect_msg(struct CSM* csm, struct Msg* msg) +{ + DisconnectCodeTLV* diconn_code = (DisconnectCodeTLV*)&(msg->buf)[sizeof(ICCHdr)]; + + *(uint16_t *)diconn_code = ntohs(*(uint16_t *)diconn_code); + + if (diconn_code->icc_parameter.u_bit == 0x0 + && diconn_code->icc_parameter.f_bit == 0x0 + && diconn_code->icc_parameter.type == TLV_T_DISCONNECT_CODE + && ntohs(diconn_code->icc_parameter.len) == (TLV_L_DISCONNECT_CODE) + && ntohl(diconn_code->iccp_status_code) == (STATUS_CODE_ICCP_RG_REMOVED)) + { + csm->iccp_info.sender_rg_connect_flag = 0x0; + csm->iccp_info.peer_rg_connect_flag = 0x0; + } +} + +/* Add received message into message list */ +void iccp_csm_enqueue_msg(struct CSM* csm, struct Msg* msg) +{ + ICCHdr* icc_hdr = NULL; + NAKTLV* naktlv = NULL; + int type = -1; + int i = 0; + + if (csm == NULL) + { + if (msg != NULL) + free(msg); + return; + } + + if (msg == NULL) + return; + + icc_hdr = (ICCHdr*)msg->buf; + + *(uint16_t *)icc_hdr = ntohs(*(uint16_t *)icc_hdr); + + if (icc_hdr->ldp_hdr.msg_type == MSG_T_RG_APP_DATA) + { + app_csm_enqueue_msg(csm, msg); + } + else if (icc_hdr->ldp_hdr.msg_type == MSG_T_NOTIFICATION) + { + naktlv = (NAKTLV*)&msg->buf[sizeof(ICCHdr)]; + + for (i = 0; i < MAX_MSG_LOG_SIZE; ++i) + { + if (ntohl(naktlv->rejected_msg_id) == csm->msg_log.msg[i].msg_id) + { + type = csm->msg_log.msg[i].type; + break; + } + } + + if (type == MSG_T_RG_APP_DATA) + app_csm_enqueue_msg(csm, msg); + else + TAILQ_INSERT_TAIL(&(csm->msg_list), msg, tail); + } + else + { + TAILQ_INSERT_TAIL(&(csm->msg_list), msg, tail); + } +} + +/* Get received message from message list */ +struct Msg* iccp_csm_dequeue_msg(struct CSM* csm) +{ + struct Msg* msg = NULL; + + if (!TAILQ_EMPTY(&(csm->msg_list))) + { + msg = TAILQ_FIRST(&(csm->msg_list)); + TAILQ_REMOVE(&(csm->msg_list), msg, tail); + + } + + return msg; +} + +/* Message initialization */ +int iccp_csm_init_msg(struct Msg** msg, char* data, int len) +{ + struct Msg* iccp_msg = NULL; + + if (msg == NULL) + return -2; + + if (data == NULL || len <= 0) + return MCLAG_ERROR; + + iccp_msg = (struct Msg*)malloc(sizeof(struct Msg)); + if (iccp_msg == NULL) + goto err_ret; + + iccp_msg->buf = (char*)malloc(len); + if (iccp_msg->buf == NULL) + goto err_ret; + + memcpy(iccp_msg->buf, data, len); + iccp_msg->len = len; + *msg = iccp_msg; + + return 0; + + err_ret: + if (iccp_msg) + { + if (iccp_msg->buf) + free(iccp_msg->buf); + free(iccp_msg); + } + + return MCLAG_ERROR; +} + +void iccp_csm_stp_role_count(struct CSM *csm) +{ + /* decide the role, lower ip to be active & socket client*/ + if (csm->role_type == STP_ROLE_NONE) + { + if (inet_addr(csm->sender_ip) < inet_addr(csm->peer_ip)) + { + /* Active*/ + ICCPD_LOG_INFO(__FUNCTION__, "Role: [Active]"); + csm->role_type = STP_ROLE_ACTIVE; + } + else + { + /* Standby*/ + ICCPD_LOG_INFO(__FUNCTION__, "Role [Standby]"); + csm->role_type = STP_ROLE_STANDBY; + } + } +} \ No newline at end of file diff --git a/src/iccpd/src/iccp_ifm.c b/src/iccpd/src/iccp_ifm.c new file mode 100644 index 000000000000..258c661e03a4 --- /dev/null +++ b/src/iccpd/src/iccp_ifm.c @@ -0,0 +1,1038 @@ +/* + * iccp_ifm.c + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "../include/system.h" +#include "../include/iccp_cli.h" +#include "../include/logger.h" +#include "../include/mlacp_sync_update.h" +#include "../include/mlacp_link_handler.h" +#include "../include/port.h" +#include "../include/iccp_netlink.h" + +#define fwd_neigh_state_valid(state) (state & (NUD_REACHABLE | NUD_STALE | NUD_DELAY | NUD_PROBE | NUD_PERMANENT)) + +#ifndef NDA_RTA +#define NDA_RTA(r) \ + ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg)))) +#endif + +static int iccp_valid_handler(struct nl_msg *msg, void *arg) +{ + struct nlmsghdr *nlh = nlmsg_hdr(msg); + unsigned int event = 0; + + if (nlh->nlmsg_type != RTM_NEWLINK) + return 0; + + if (nl_msg_parse(msg, &iccp_event_handler_obj_input_newlink, &event) < 0) + ICCPD_LOG_ERR(__FUNCTION__, "Unknown message type."); + + return 0; +} + +/*Get kernel interfaces and ports during initialization*/ +int iccp_sys_local_if_list_get_init() +{ + struct System *sys = NULL; + struct nl_cb *cb; + struct nl_cb *orig_cb; + struct rtgenmsg rt_hdr = { + .rtgen_family = AF_UNSPEC, + }; + int ret; + int retry = 1; + + if (!(sys = system_get_instance())) + return MCLAG_ERROR; + + while (retry) + { + retry = 0; + ret = nl_send_simple(sys->route_sock, RTM_GETLINK, NLM_F_DUMP, + &rt_hdr, sizeof(rt_hdr)); + if (ret < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "send netlink msg error."); + return ret; + } + + orig_cb = nl_socket_get_cb(sys->route_sock); + cb = nl_cb_clone(orig_cb); + nl_cb_put(orig_cb); + if (!cb) + { + ICCPD_LOG_ERR(__FUNCTION__, "nl cb clone error."); + return -ENOMEM; + } + + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, iccp_valid_handler, sys); + + ret = nl_recvmsgs(sys->route_sock, cb); + nl_cb_put(cb); + if (ret < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "receive netlink msg error. ret = %d errno = %d ", ret, errno); + if (ret != -NLE_DUMP_INTR) + return ret; + retry = 1; + } + } + + return ret; +} + +static void do_arp_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int msgtype) +{ + struct System *sys = NULL; + struct CSM *csm = NULL; + struct Msg *msg = NULL; + struct ARPMsg *arp_msg = NULL, *arp_info = NULL; + struct VLAN_ID *vlan_id_list = NULL; + struct Msg *msg_send = NULL; + + char buf[MAX_BUFSIZE]; + size_t msg_len = 0; + + struct LocalInterface *lif_po = NULL, *arp_lif = NULL; + + int verify_arp = 0; + int arp_update = 0; + + if (!(sys = system_get_instance())) + return; + + /* Find local itf*/ + if (!(arp_lif = local_if_find_by_ifindex(ndm->ndm_ifindex))) + return; + + /* create ARP msg*/ + memset(buf, 0, MAX_BUFSIZE); + msg_len = sizeof(struct ARPMsg); + arp_msg = (struct ARPMsg*)&buf; + arp_msg->op_type = NEIGH_SYNC_LIF; + sprintf(arp_msg->ifname, "%s", arp_lif->name); + if (tb[NDA_DST]) + memcpy(&arp_msg->ipv4_addr, RTA_DATA(tb[NDA_DST]), RTA_PAYLOAD(tb[NDA_DST])); + if (tb[NDA_LLADDR]) + memcpy(arp_msg->mac_addr, RTA_DATA(tb[NDA_LLADDR]), RTA_PAYLOAD(tb[NDA_LLADDR])); + + arp_msg->ipv4_addr = arp_msg->ipv4_addr; + + ICCPD_LOG_NOTICE(__FUNCTION__, "ARP type %s, state (%04X)(%d) ifindex [%d] (%s) ip %s, mac [%02X:%02X:%02X:%02X:%02X:%02X]", + msgtype == RTM_NEWNEIGH ? "New":"Del", ndm->ndm_state, fwd_neigh_state_valid(ndm->ndm_state), + ndm->ndm_ifindex, arp_lif->name, + show_ip_str(arp_msg->ipv4_addr), + arp_msg->mac_addr[0], arp_msg->mac_addr[1], arp_msg->mac_addr[2], arp_msg->mac_addr[3], arp_msg->mac_addr[4], + arp_msg->mac_addr[5]); + + /* Find MLACP itf, member of port-channel*/ + LIST_FOREACH(csm, &(sys->csm_list), next) + { + LIST_FOREACH(lif_po, &(MLACP(csm).lif_list), mlacp_next) + { + if (lif_po->type != IF_T_PORT_CHANNEL) + continue; + + if (!local_if_is_l3_mode(lif_po)) + { + /* Is the L2 MLAG itf belong to a vlan?*/ + LIST_FOREACH(vlan_id_list, &(lif_po->vlan_list), port_next) + { + if ( !(vlan_id_list->vlan_itf + && vlan_id_list->vlan_itf->ifindex == ndm->ndm_ifindex)) + continue; + break; + } + + if (!vlan_id_list) + continue; + + ICCPD_LOG_DEBUG(__FUNCTION__, "ARP is from mclag enabled member port of vlan %s", + vlan_id_list->vlan_itf->name); + } + else + { + /* Is the ARP belong to a L3 mode MLAG itf?*/ + if (ndm->ndm_ifindex != lif_po->ifindex) + continue; + + ICCPD_LOG_DEBUG(__FUNCTION__, "ARP is from mclag enabled intf %s", lif_po->name); + } + + verify_arp = 1; + + break; + } + + if (lif_po) + break; + } + + if (!(csm && lif_po)) + return; + if (!verify_arp) + return; + + /* update lif ARP*/ + TAILQ_FOREACH(msg, &MLACP(csm).arp_list, tail) + { + arp_info = (struct ARPMsg*)msg->buf; + if (arp_info->ipv4_addr != arp_msg->ipv4_addr) + continue; + + if (msgtype == RTM_DELNEIGH) + { + /* delete ARP*/ + TAILQ_REMOVE(&MLACP(csm).arp_list, msg, tail); + free(msg->buf); + free(msg); + msg = NULL; + ICCPD_LOG_DEBUG(__FUNCTION__, "Delete ARP %s", show_ip_str(arp_msg->ipv4_addr)); + } + else + { + /* update ARP*/ + if (arp_info->op_type != arp_msg->op_type + || strcmp(arp_info->ifname, arp_msg->ifname) != 0 + || memcmp(arp_info->mac_addr, arp_msg->mac_addr, + ETHER_ADDR_LEN) != 0) + { + arp_update = 1; + arp_info->op_type = arp_msg->op_type; + sprintf(arp_info->ifname, "%s", arp_msg->ifname); + memcpy(arp_info->mac_addr, arp_msg->mac_addr, ETHER_ADDR_LEN); + ICCPD_LOG_DEBUG(__FUNCTION__, "Update ARP for %s", show_ip_str(arp_msg->ipv4_addr)); + } + } + break; + } + + if (msg && !arp_update) + return; + + if (msgtype != RTM_DELNEIGH) + { + /* enquene lif_msg (add)*/ + if (!msg) + { + arp_msg->op_type = NEIGH_SYNC_LIF; + if (iccp_csm_init_msg(&msg, (char*)arp_msg, msg_len) == 0) + { + mlacp_enqueue_arp(csm, msg); + /*ICCPD_LOG_DEBUG(__FUNCTION__, "ARP-list enqueue: %s, add %s", + arp_msg->ifname, show_ip_str(arp_msg->ipv4_addr));*/ + } + else + ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ARP-list: %s, add %s", + arp_msg->ifname, show_ip_str(arp_msg->ipv4_addr)); + } + + /* enqueue iccp_msg (add)*/ + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + arp_msg->op_type = NEIGH_SYNC_ADD; + if (iccp_csm_init_msg(&msg_send, (char*)arp_msg, msg_len) == 0) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).arp_msg_list), msg_send, tail); + /*ICCPD_LOG_DEBUG(__FUNCTION__, "Enqueue ARP[ADD] message for %s", + show_ip_str(arp_msg->ipv4_addr));*/ + } + else + ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ARP[ADD] message for %s", + show_ip_str(arp_msg->ipv4_addr)); + + } + } + else + { + /* enqueue iccp_msg (delete)*/ + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + arp_msg->op_type = NEIGH_SYNC_DEL; + if (iccp_csm_init_msg(&msg_send, (char*)arp_msg, msg_len) == 0) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).arp_msg_list), msg_send, tail); + /*ICCPD_LOG_DEBUG(__FUNCTION__, "Enqueue ARP[DEL] message for %s", + show_ip_str(arp_msg->ipv4_addr));*/ + } + else + ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ARP[DEL] message for %s", + show_ip_str(arp_msg->ipv4_addr)); + + } + } + + return; +} + +static void do_ndisc_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int msgtype) +{ + struct System *sys = NULL; + struct CSM *csm = NULL; + struct Msg *msg = NULL; + struct NDISCMsg *ndisc_msg = NULL, *ndisc_info = NULL; + struct VLAN_ID *vlan_id_list = NULL; + struct Msg *msg_send = NULL; + + char buf[MAX_BUFSIZE]; + size_t msg_len = 0; + + struct LocalInterface *lif_po = NULL, *ndisc_lif = NULL; + + int verify_neigh = 0; + int neigh_update = 0; + + if (!(sys = system_get_instance())) + return; + + /* Find local itf */ + if (!(ndisc_lif = local_if_find_by_ifindex(ndm->ndm_ifindex))) + return; + + /* create NDISC msg */ + memset(buf, 0, MAX_BUFSIZE); + msg_len = sizeof(struct NDISCMsg); + ndisc_msg = (struct NDISCMsg *)&buf; + ndisc_msg->op_type = NEIGH_SYNC_LIF; + sprintf(ndisc_msg->ifname, "%s", ndisc_lif->name); + if (tb[NDA_DST]) + memcpy(&ndisc_msg->ipv6_addr, RTA_DATA(tb[NDA_DST]), RTA_PAYLOAD(tb[NDA_DST])); + if (tb[NDA_LLADDR]) + memcpy(ndisc_msg->mac_addr, RTA_DATA(tb[NDA_LLADDR]), RTA_PAYLOAD(tb[NDA_LLADDR])); + + ICCPD_LOG_NOTICE(__FUNCTION__, "ndisc type %s, state (%04X)(%d), ifindex [%d] (%s), ip %s, mac [%02X:%02X:%02X:%02X:%02X:%02X]", + msgtype == RTM_NEWNEIGH ? "New" : "Del", ndm->ndm_state, fwd_neigh_state_valid(ndm->ndm_state), + ndm->ndm_ifindex, ndisc_lif->name, + show_ipv6_str((char *)ndisc_msg->ipv6_addr), + ndisc_msg->mac_addr[0], ndisc_msg->mac_addr[1], ndisc_msg->mac_addr[2], ndisc_msg->mac_addr[3], ndisc_msg->mac_addr[4], + ndisc_msg->mac_addr[5]); + + /* Find MLACP itf, member of port-channel */ + LIST_FOREACH(csm, &(sys->csm_list), next) + { + LIST_FOREACH(lif_po, &(MLACP(csm).lif_list), mlacp_next) + { + if (lif_po->type != IF_T_PORT_CHANNEL) + continue; + + if (!local_if_is_l3_mode(lif_po)) + { + /* Is the L2 MLAG itf belong to a vlan? */ + LIST_FOREACH(vlan_id_list, &(lif_po->vlan_list), port_next) + { + if (!(vlan_id_list->vlan_itf && vlan_id_list->vlan_itf->ifindex == ndm->ndm_ifindex)) + continue; + break; + } + + if (!vlan_id_list) + continue; + + ICCPD_LOG_DEBUG(__FUNCTION__, "ND is from mclag enabled member port of vlan %s", vlan_id_list->vlan_itf->name); + } + else + { + /* Is the ND belong to a L3 mode MLAG itf? */ + if (ndm->ndm_ifindex != lif_po->ifindex) + continue; + + ICCPD_LOG_DEBUG(__FUNCTION__, "ND is from mclag enabled intf %s", lif_po->name); + } + + verify_neigh = 1; + + break; + } + + if (lif_po) + break; + } + + if (!(csm && lif_po)) + return; + if (!verify_neigh) + return; + + /* update lif ND */ + TAILQ_FOREACH(msg, &MLACP(csm).ndisc_list, tail) + { + ndisc_info = (struct NDISCMsg *)msg->buf; + + if (memcmp(&ndisc_info->ipv6_addr, &ndisc_msg->ipv6_addr, 16) != 0) + continue; + + if (msgtype == RTM_DELNEIGH) + { + /* delete ND */ + TAILQ_REMOVE(&MLACP(csm).ndisc_list, msg, tail); + free(msg->buf); + free(msg); + msg = NULL; + ICCPD_LOG_DEBUG(__FUNCTION__, "Delete neighbor %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr)); + } + else + { + /* update ND */ + if (ndisc_info->op_type != ndisc_info->op_type + || strcmp(ndisc_info->ifname, ndisc_info->ifname) != 0 + || memcmp(ndisc_info->mac_addr, ndisc_info->mac_addr, ETHER_ADDR_LEN) != 0) + { + neigh_update = 1; + ndisc_info->op_type = ndisc_msg->op_type; + sprintf(ndisc_info->ifname, "%s", ndisc_msg->ifname); + memcpy(ndisc_info->mac_addr, ndisc_msg->mac_addr, ETHER_ADDR_LEN); + ICCPD_LOG_DEBUG(__FUNCTION__, "Update neighbor for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr)); + } + } + break; + } + + if (msg && !neigh_update) + return; + + if (msgtype != RTM_DELNEIGH) + { + /* enquene lif_msg (add) */ + if (!msg) + { + ndisc_msg->op_type = NEIGH_SYNC_LIF; + if (iccp_csm_init_msg(&msg, (char *)ndisc_msg, msg_len) == 0) + { + mlacp_enqueue_ndisc(csm, msg); + /* ICCPD_LOG_DEBUG(__FUNCTION__, "Ndisc-list enqueue: %s, add %s", ndisc_msg->ifname, show_ipv6_str((char *)ndisc_msg->ipv6_addr)); */ + } + else + ICCPD_LOG_DEBUG(__FUNCTION__, "Failed to enqueue Ndisc-list: %s, add %s", + ndisc_msg->ifname, show_ipv6_str((char *)ndisc_msg->ipv6_addr)); + } + + /* enqueue iccp_msg (add) */ + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + ndisc_msg->op_type = NEIGH_SYNC_ADD; + if (iccp_csm_init_msg(&msg_send, (char *)ndisc_msg, msg_len) == 0) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).ndisc_msg_list), msg_send, tail); + /* ICCPD_LOG_DEBUG(__FUNCTION__, "Enqueue Ndisc[ADD] for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr)); */ + } + else + ICCPD_LOG_DEBUG(__FUNCTION__, "Failed to enqueue Ndisc[ADD] message for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr)); + + } + } + else + { + /* enqueue iccp_msg (delete) */ + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + ndisc_msg->op_type = NEIGH_SYNC_DEL; + if (iccp_csm_init_msg(&msg_send, (char *)ndisc_msg, msg_len) == 0) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).ndisc_msg_list), msg_send, tail); + /* ICCPD_LOG_DEBUG(__FUNCTION__, "Enqueue Ndisc[DEL] for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr)); */ + } + else + ICCPD_LOG_DEBUG(__FUNCTION__, "Failed to enqueue Ndisc[DEL] message for [%x:%x:%x:%x]", show_ipv6_str((char *)ndisc_msg->ipv6_addr)); + + } + } + + return; +} + +int parse_rtattr_flags(struct rtattr *tb[], int max, struct rtattr *rta, int len, unsigned short flags) +{ + unsigned short type; + + memset(tb, 0, sizeof(struct rtattr *) * (max + 1)); + while (RTA_OK(rta, len)) + { + type = rta->rta_type & ~flags; + if ((type <= max) && (!tb[type])) + tb[type] = rta; + rta = RTA_NEXT(rta, len); + } + return 0; +} + +int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len) +{ + return parse_rtattr_flags(tb, max, rta, len, 0); +} + +void ifm_parse_rtattr(struct rtattr **tb, int max, struct rtattr *rta, int len) +{ + while (RTA_OK(rta, len)) + { + if (rta->rta_type <= max) + tb[rta->rta_type] = rta; + rta = RTA_NEXT(rta, len); + } +} + +int do_one_neigh_request(struct nlmsghdr *n) +{ + struct ndmsg *ndm = NLMSG_DATA(n); + int len = n->nlmsg_len; + struct rtattr *tb[NDA_MAX + 1] = {0}; + + if (n->nlmsg_type == NLMSG_DONE) + { + return 0; + } + + /* process msg_type RTM_NEWNEIGH, RTM_GETNEIGH, RTM_DELNEIGH */ + if (n->nlmsg_type != RTM_NEWNEIGH && n->nlmsg_type != RTM_DELNEIGH ) + return(0); + + len -= NLMSG_LENGTH(sizeof(*ndm)); + if (len < 0) + return MCLAG_ERROR; + + ifm_parse_rtattr(tb, NDA_MAX, NDA_RTA(ndm), len); + + if (n->nlmsg_type == RTM_NEWNEIGH + && (ndm->ndm_state == NUD_INCOMPLETE + || ndm->ndm_state == NUD_FAILED + || ndm->ndm_state == NUD_NOARP + || ndm->ndm_state == NUD_PERMANENT + || ndm->ndm_state == NUD_NONE)) + { + return(0); + } + + if (!tb[NDA_DST] || ndm->ndm_type != RTN_UNICAST) + { + return(0); + } + + if (ndm->ndm_family == AF_INET) + { + do_arp_learn_from_kernel(ndm, tb, n->nlmsg_type); + } + + if (ndm->ndm_family == AF_INET6) + { + do_ndisc_learn_from_kernel(ndm, tb, n->nlmsg_type); + } + return(0); +} + +static int iccp_neigh_valid_handler(struct nl_msg *msg, void *arg) +{ + struct nlmsghdr *nlh = nlmsg_hdr(msg); + + do_one_neigh_request(nlh); + + return 0; +} + +int iccp_neigh_get_init() +{ + struct System *sys = NULL; + struct nl_cb *cb; + struct nl_cb *orig_cb; + struct rtgenmsg rt_hdr = { + .rtgen_family = AF_UNSPEC, + }; + int ret; + int retry = 1; + + if (!(sys = system_get_instance())) + return MCLAG_ERROR; + + while (retry) + { + retry = 0; + ret = nl_send_simple(sys->route_sock, RTM_GETNEIGH, NLM_F_DUMP, + &rt_hdr, sizeof(rt_hdr)); + if (ret < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Send netlink msg error."); + return ret; + } + + orig_cb = nl_socket_get_cb(sys->route_sock); + cb = nl_cb_clone(orig_cb); + nl_cb_put(orig_cb); + if (!cb) + { + ICCPD_LOG_ERR(__FUNCTION__, "nl cb clone error."); + return -ENOMEM; + } + + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, iccp_neigh_valid_handler, sys); + + ret = nl_recvmsgs(sys->route_sock, cb); + nl_cb_put(cb); + if (ret < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Receive netlink msg error."); + if (ret != -NLE_DUMP_INTR) + return ret; + + retry = 1; + } + } + + return ret; +} + +/*When received ARP packets from kernel, update arp information*/ +void do_arp_update_from_reply_packet(unsigned int ifindex, unsigned int addr, uint8_t mac_addr[ETHER_ADDR_LEN]) +{ + struct System *sys = NULL; + struct CSM *csm = NULL; + struct Msg *msg = NULL; + struct ARPMsg *arp_msg = NULL, *arp_info = NULL; + struct VLAN_ID *vlan_id_list = NULL; + struct Msg *msg_send = NULL; + + char buf[MAX_BUFSIZE]; + size_t msg_len = 0; + + struct LocalInterface *lif_po = NULL, *arp_lif = NULL; + + int verify_arp = 0; + + if (!(sys = system_get_instance())) + return; + + /* Find local itf*/ + if (!(arp_lif = local_if_find_by_ifindex(ifindex))) + return; + + /* create ARP msg*/ + memset(buf, 0, MAX_BUFSIZE); + msg_len = sizeof(struct ARPMsg); + arp_msg = (struct ARPMsg*)&buf; + arp_msg->op_type = NEIGH_SYNC_LIF; + sprintf(arp_msg->ifname, "%s", arp_lif->name); + memcpy(&arp_msg->ipv4_addr, &addr, 4); + memcpy(arp_msg->mac_addr, mac_addr, 6); + + ICCPD_LOG_DEBUG(__FUNCTION__, "ARP ifindex [%d] (%s) ip %s mac [%02X:%02X:%02X:%02X:%02X:%02X]", + ifindex, arp_lif->name, + show_ip_str(arp_msg->ipv4_addr), + arp_msg->mac_addr[0], arp_msg->mac_addr[1], arp_msg->mac_addr[2], arp_msg->mac_addr[3], arp_msg->mac_addr[4], + arp_msg->mac_addr[5]); + + /* Find MLACP itf, member of port-channel*/ + LIST_FOREACH(csm, &(sys->csm_list), next) + { + LIST_FOREACH(lif_po, &(MLACP(csm).lif_list), mlacp_next) + { + if (lif_po->type != IF_T_PORT_CHANNEL) + continue; + + if (!local_if_is_l3_mode(lif_po)) + { + /* Is the L2 MLAG itf belong to a vlan?*/ + LIST_FOREACH(vlan_id_list, &(lif_po->vlan_list), port_next) + { + if ( !(vlan_id_list->vlan_itf + && vlan_id_list->vlan_itf->ifindex == ifindex)) + continue; + break; + } + + if (!vlan_id_list) + continue; + ICCPD_LOG_DEBUG(__FUNCTION__, "ARP is from mclag enabled port %s of vlan %s", + lif_po->name, vlan_id_list->vlan_itf->name); + } + else + { + /* Is the ARP belong to a L3 mode MLAG itf?*/ + if (ifindex != lif_po->ifindex) + continue; + ICCPD_LOG_DEBUG(__FUNCTION__, "ARP is from mclag enabled intf %s", lif_po->name); + } + + verify_arp = 1; + + break; + } + + if (lif_po) + break; + } + + if (!(csm && lif_po)) + return; + if (!verify_arp) + return; + + if (iccp_check_if_addr_from_netlink(AF_INET, (uint8_t *)&addr, arp_lif)) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "ARP %s is identical with the ip address of interface %s", + show_ip_str(arp_msg->ipv4_addr), arp_lif->name); + return; + } + + /* update lif ARP*/ + TAILQ_FOREACH(msg, &MLACP(csm).arp_list, tail) + { + arp_info = (struct ARPMsg*)msg->buf; + if (arp_info->ipv4_addr != arp_msg->ipv4_addr) + continue; + + /* update ARP*/ + if (arp_info->op_type != arp_msg->op_type + || strcmp(arp_info->ifname, arp_msg->ifname) != 0 + || memcmp(arp_info->mac_addr, arp_msg->mac_addr, + ETHER_ADDR_LEN) != 0) + { + arp_info->op_type = arp_msg->op_type; + sprintf(arp_info->ifname, "%s", arp_msg->ifname); + memcpy(arp_info->mac_addr, arp_msg->mac_addr, ETHER_ADDR_LEN); + ICCPD_LOG_NOTICE(__FUNCTION__, "Update ARP for %s by ARP reply, intf %s mac [%02X:%02X:%02X:%02X:%02X:%02X]", + show_ip_str(arp_msg->ipv4_addr), arp_msg->ifname, + arp_msg->mac_addr[0], arp_msg->mac_addr[1], arp_msg->mac_addr[2], arp_msg->mac_addr[3], arp_msg->mac_addr[4], arp_msg->mac_addr[5]); + } + break; + } + + /* enquene lif_msg (add)*/ + if (!msg) + { + arp_msg->op_type = NEIGH_SYNC_LIF; + if (iccp_csm_init_msg(&msg, (char*)arp_msg, msg_len) == 0) + { + mlacp_enqueue_arp(csm, msg); + /*ICCPD_LOG_DEBUG(__FUNCTION__, "ARP-list enqueue: %s, add %s", + arp_msg->ifname, show_ip_str(arp_msg->ipv4_addr));*/ + } + else + ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ARP-list: %s, add %s", + arp_msg->ifname, show_ip_str(arp_msg->ipv4_addr)); + } + + /* enqueue iccp_msg (add)*/ + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + arp_msg->op_type = NEIGH_SYNC_ADD; + if (iccp_csm_init_msg(&msg_send, (char*)arp_msg, msg_len) == 0) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).arp_msg_list), msg_send, tail); + /*ICCPD_LOG_DEBUG(__FUNCTION__, "Enqueue ARP[ADD] for %s", + show_ip_str(arp_msg->ipv4_addr));*/ + } + else + ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ARP[ADD] message for %s", + show_ip_str(arp_msg->ipv4_addr)); + } + + return; +} + +void do_ndisc_update_from_reply_packet(unsigned int ifindex, char *ipv6_addr, uint8_t mac_addr[ETHER_ADDR_LEN]) +{ + struct System *sys = NULL; + struct CSM *csm = NULL; + struct Msg *msg = NULL; + struct NDISCMsg *ndisc_msg = NULL, *ndisc_info = NULL; + struct VLAN_ID *vlan_id_list = NULL; + struct Msg *msg_send = NULL; + char mac_str[18] = ""; + uint8_t null_mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + char buf[MAX_BUFSIZE]; + size_t msg_len = 0; + + struct LocalInterface *lif_po = NULL, *ndisc_lif = NULL; + + int verify_ndisc = 0; + + if (!(sys = system_get_instance())) + return; + + /* Find local itf */ + if (!(ndisc_lif = local_if_find_by_ifindex(ifindex))) + return; + + sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); + + /* create Ndisc msg */ + memset(buf, 0, MAX_BUFSIZE); + msg_len = sizeof(struct NDISCMsg); + ndisc_msg = (struct NDISCMsg *)&buf; + ndisc_msg->op_type = NEIGH_SYNC_LIF; + sprintf(ndisc_msg->ifname, "%s", ndisc_lif->name); + memcpy((char *)ndisc_msg->ipv6_addr, ipv6_addr, 16); + memcpy(ndisc_msg->mac_addr, mac_addr, ETHER_ADDR_LEN); + + ICCPD_LOG_DEBUG(__FUNCTION__, "nd ifindex [%d] (%s) ip %s mac %s", + ifindex, ndisc_lif->name, show_ipv6_str(ipv6_addr), mac_str); + + /* Find MLACP itf, member of port-channel */ + LIST_FOREACH(csm, &(sys->csm_list), next) + { + LIST_FOREACH(lif_po, &(MLACP(csm).lif_list), mlacp_next) + { + if (lif_po->type != IF_T_PORT_CHANNEL) + continue; + + if (!local_if_is_l3_mode(lif_po)) + { + /* Is the L2 MLAG itf belong to a vlan? */ + LIST_FOREACH(vlan_id_list, &(lif_po->vlan_list), port_next) + { + if (!(vlan_id_list->vlan_itf && vlan_id_list->vlan_itf->ifindex == ifindex)) + continue; + break; + } + + if (!vlan_id_list) + continue; + ICCPD_LOG_DEBUG(__FUNCTION__, "ND is from mclag enabled port %s of vlan %s", lif_po->name, vlan_id_list->vlan_itf->name); + } + else + { + /* Is the ND belong to a L3 mode MLAG itf? */ + if (ifindex != lif_po->ifindex) + continue; + ICCPD_LOG_DEBUG(__FUNCTION__, "ND is from mclag enabled port %s", lif_po->name); + } + + verify_ndisc = 1; + + break; + } + + if (lif_po) + break; + } + + if (!(csm && lif_po)) + return; + if (!verify_ndisc) + return; + + if (iccp_check_if_addr_from_netlink(AF_INET6, (uint8_t *)ndisc_msg->ipv6_addr, ndisc_lif)) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "NA %s is identical with the ipv6 address of interface %s", + show_ipv6_str((char *)ndisc_msg->ipv6_addr), ndisc_lif->name); + return; + } + + /* update lif ND */ + TAILQ_FOREACH(msg, &MLACP(csm).ndisc_list, tail) + { + ndisc_info = (struct NDISCMsg *)msg->buf; + + if (memcmp((char *)ndisc_info->ipv6_addr, (char *)ndisc_msg->ipv6_addr, 16) != 0) + continue; + + /* If MAC addr is NULL, use the old one */ + if (memcmp(mac_addr, null_mac, ETHER_ADDR_LEN) == 0) + { + memcpy(ndisc_msg->mac_addr, ndisc_info->mac_addr, ETHER_ADDR_LEN); + sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", ndisc_info->mac_addr[0], ndisc_info->mac_addr[1], + ndisc_info->mac_addr[2], ndisc_info->mac_addr[3], ndisc_info->mac_addr[4], ndisc_info->mac_addr[5]); + } + + /* update ND */ + if (ndisc_info->op_type != ndisc_msg->op_type + || strcmp(ndisc_info->ifname, ndisc_msg->ifname) != 0 + || memcmp(ndisc_info->mac_addr, ndisc_msg->mac_addr, ETHER_ADDR_LEN) != 0) + { + ndisc_info->op_type = ndisc_msg->op_type; + sprintf(ndisc_info->ifname, "%s", ndisc_msg->ifname); + memcpy(ndisc_info->mac_addr, ndisc_msg->mac_addr, ETHER_ADDR_LEN); + ICCPD_LOG_DEBUG(__FUNCTION__, "Update ND for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr)); + } + break; + } + + /* enquene lif_msg (add) */ + if (!msg) + { + /* If MAC addr is NULL, and same ipv6 item is not exist in ndisc_list */ + if (memcmp(mac_addr, null_mac, ETHER_ADDR_LEN) == 0) + { + return; + } + + ndisc_msg->op_type = NEIGH_SYNC_LIF; + if (iccp_csm_init_msg(&msg, (char *)ndisc_msg, msg_len) == 0) + { + mlacp_enqueue_ndisc(csm, msg); + /* ICCPD_LOG_DEBUG(__FUNCTION__, "NDISC-list enqueue: %s, add %s", ndisc_msg->ifname, show_ipv6_str((char *)ndisc_msg->ipv6_addr)); */ + } + else + ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue NDISC-list: %s, add %s", ndisc_msg->ifname, show_ipv6_str((char *)ndisc_msg->ipv6_addr)); + } + + if (iccp_netlink_neighbor_request(AF_INET6, (uint8_t *)ndisc_msg->ipv6_addr, 1, ndisc_msg->mac_addr, ndisc_msg->ifname) < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "Failed to add ND entry(%s, %s, %s) to kernel", + ndisc_msg->ifname, show_ipv6_str((char *)ndisc_msg->ipv6_addr), mac_str); + return; + } + + /* enqueue iccp_msg (add) */ + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + ndisc_msg->op_type = NEIGH_SYNC_ADD; + if (iccp_csm_init_msg(&msg_send, (char *)ndisc_msg, msg_len) == 0) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).ndisc_msg_list), msg_send, tail); + /* ICCPD_LOG_DEBUG(__FUNCTION__, "Enqueue ND[ADD] for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr)); */ + } + else + ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ND[ADD] message for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr)); + } + + return; +} +void iccp_from_netlink_port_state_handler( char * ifname, int state) +{ + struct CSM *csm = NULL; + struct LocalInterface *lif_po = NULL; + struct System *sys; + int po_is_active = 0; + + if ((sys = system_get_instance()) == NULL) + { + ICCPD_LOG_WARN(__FUNCTION__, "Failed to obtain System instance."); + return; + } + + po_is_active = (state == PORT_STATE_UP); + + /* traverse all CSM */ + LIST_FOREACH(csm, &(sys->csm_list), next) + { + /*If peer-link changes to down or up */ + if (strcmp(ifname, csm->peer_itf_name) == 0) + { + if (po_is_active == 0) + mlacp_peerlink_down_handler(csm); + else + mlacp_peerlink_up_handler(csm); + + break; + } + + LIST_FOREACH(lif_po, &(MLACP(csm).lif_list), mlacp_next) + { + if (lif_po->type == IF_T_PORT_CHANNEL && strncmp(lif_po->name, ifname, MAX_L_PORT_NAME) == 0) + { + mlacp_portchannel_state_handler(csm, lif_po, po_is_active); + } + } + } + + return; +} + +void iccp_parse_if_vlan_info_from_netlink(struct nlmsghdr *n) +{ + struct LocalInterface *lif = NULL; + int msglen = 0; + + msglen = n->nlmsg_len; + + while (NLMSG_OK(n, msglen)) + { + struct ifinfomsg *ifm = NLMSG_DATA(n); + int len = n->nlmsg_len; + struct rtattr *tb[IFLA_MAX + 1] = {0}; + + if (n->nlmsg_type != RTM_NEWLINK) + { + return; + } + + len -= NLMSG_LENGTH(sizeof(*ifm)); + if (len < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "BUG: wrong nlmsg len %d\n", len); + return; + } + + if (ifm->ifi_family != AF_BRIDGE) + { + return; + } + + if ((lif = local_if_find_by_ifindex(ifm->ifi_index)) != NULL) + { + parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifm), len); + + /* if AF_SPEC isn't there, vlan table is not preset for this port */ + if (!tb[IFLA_AF_SPEC]) + { + ICCPD_LOG_WARN(__FUNCTION__, "Vlan table is not preset for %d", ifm->ifi_index); + return; + } + else + { + struct rtattr *i, *list = tb[IFLA_AF_SPEC]; + int rem = RTA_PAYLOAD(list); + struct VLAN_ID *vlan = NULL; + + /*set vlan flag is removed*/ + LIST_FOREACH(vlan, &(lif->vlan_list), port_next) + { + vlan->vlan_removed = 1; + } + + for (i = RTA_DATA(list); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) + { + struct bridge_vlan_info *vinfo; + + if (i->rta_type != IFLA_BRIDGE_VLAN_INFO) + continue; + + vinfo = RTA_DATA(i); + + local_if_add_vlan(lif, vinfo->vid); + } + + /*After update vlan list, remove unused item*/ + LIST_FOREACH(vlan, &(lif->vlan_list), port_next) + { + if (vlan->vlan_removed == 1) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "Remove %s from VLAN %d", lif->name, vlan->vid); + + LIST_REMOVE(vlan, port_next); + free(vlan); + } + } + } + } + + n = NLMSG_NEXT(n, msglen); + } +} diff --git a/src/iccpd/src/iccp_main.c b/src/iccpd/src/iccp_main.c new file mode 100644 index 000000000000..86920f07e1fb --- /dev/null +++ b/src/iccpd/src/iccp_main.c @@ -0,0 +1,272 @@ +/* + * iccp_main.c + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#include +#include +#include +#include +#include +#include + +#include "../include/cmd_option.h" +#include "../include/logger.h" +#include "../include/scheduler.h" +#include "../include/system.h" + +int check_instance(char* pid_file_path) +{ + int pid_file = 0; + int rc = 0; + + if (pid_file_path == NULL) + return MCLAG_ERROR; + + pid_file = open(pid_file_path, O_CREAT | O_RDWR, 0666); + if (pid_file <= 0 ) + { + fprintf(stderr, "Can't open a pid file. Terminate.\n"); + close(pid_file); + exit(EXIT_FAILURE); + } + + rc = flock(pid_file, LOCK_EX | LOCK_NB); + + if (rc) + { + if (errno == EWOULDBLOCK) + { + fprintf(stderr, "There is another instance running. Terminate.\n"); + close(pid_file); + exit(EXIT_FAILURE); + } + } + + return pid_file; +} + +void init_daemon(char* pid_file_path, int pid_file) +{ + pid_t pid, sid; + + pid = fork(); + if (pid < 0) + { + fprintf(stderr, "Failed to enter daemon mode: %s\n", strerror(errno)); + fprintf(stderr, "Please try to check your system resources.\n"); + close(pid_file); + unlink(pid_file_path); + exit(EXIT_FAILURE); + } + + if (pid > 0) + exit(EXIT_SUCCESS); + + umask(0); + sid = setsid(); + if (sid < 0) + { + fprintf(stderr, "Failed to create a new SID for this program: %s\n", strerror(errno)); + fprintf(stderr, "Please try to check your system resources.\n"); + close(pid_file); + unlink(pid_file_path); + exit(EXIT_FAILURE); + } + + freopen("/dev/null", "r", stdin); + freopen("/dev/null", "w", stdout); + freopen("/dev/null", "w", stderr); +} + +#ifndef ICCPD_RUN_DIR +#define ICCPD_RUN_DIR "/var/run/iccpd/" +#endif + +static inline int iccpd_make_rundir(void) +{ + int ret; + + ret = mkdir(ICCPD_RUN_DIR, 0755); + if (ret && errno != EEXIST) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to create directory \"%s\"", + ICCPD_RUN_DIR); + + return -errno; + } + + return 0; +} + +void iccpd_signal_handler(int sig) +{ + int err; + struct System* sys = NULL; + const char warmboot_flag = 'w'; + + sys = system_get_instance(); + if (!sys) + { + return; + } + + retry: + err = write(sys->sig_pipe_w, &warmboot_flag, 1); + if (err == -1 && errno == EINTR) + goto retry; + + return; +} + +static int iccpd_signal_init(struct System* sys) +{ + int fds[2]; + int err; + sigset_t ss; + struct sigaction sa; + struct epoll_event event; + + err = pipe(fds); + if (err) + return -errno; + + sys->sig_pipe_r = fds[0]; + sys->sig_pipe_w = fds[1]; + + if (sigemptyset(&ss) < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "sigemptyset(): %d", errno); + goto close_pipe; + } + + if (sigaddset(&ss, SIGUSR1) < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "sigaddset(): %d", errno); + goto close_pipe; + } + + if (sigprocmask(SIG_UNBLOCK, &ss, NULL) < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "sigprocmask(): %d", errno); + goto close_pipe; + } + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = iccpd_signal_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_RESTART; + + if (sigaction(SIGUSR1, &sa, NULL) < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "sigaction(): %d", errno); + goto close_pipe; + } + + event.data.fd = fds[0]; + event.events = EPOLLIN; + err = epoll_ctl(sys->epoll_fd, EPOLL_CTL_ADD, fds[0], &event); + if (err) + { + goto close_pipe; + } + + FD_SET( fds[0], &(sys->readfd)); + sys->readfd_count++; + + return 0; + + close_pipe: + close(sys->sig_pipe_r); + close(sys->sig_pipe_w); + return err; +} + +int main(int argc, char* argv[]) +{ + int pid_file_fd = 0; + struct System* sys = NULL; + int err; + struct CmdOptionParser parser = CMD_OPTION_PARSER_INIT_VALUE; + + err = iccpd_make_rundir(); + if (err) + return 0; + + if (getuid() != 0) + { + fprintf(stderr, + "This program needs root permission to do device manipulation. " + "Please use sudo to execute it or change your user to root.\n"); + exit(EXIT_FAILURE); + } + + parser.init(&parser); + if (parser.parse(&parser, argc, argv) != 0) + { + parser.finalize(&parser); + return MCLAG_ERROR; + } + + pid_file_fd = check_instance(parser.pid_file_path); + if (pid_file_fd < 0) + { + fprintf(stderr, "Check instance with invalidate arguments, iccpd is terminated.\n"); + parser.finalize(&parser); + exit(EXIT_FAILURE); + } + + sys = system_get_instance(); + if (!sys) + { + fprintf(stderr, "Can't get a system instance, iccpd is terminated.\n"); + parser.finalize(&parser); + exit(EXIT_FAILURE); + } + + /*if(!parser.console_log) + init_daemon(parser.pid_file_path, pid_file_fd);*/ + + log_init(&parser); + + if (sys->log_file_path != NULL) + free(sys->log_file_path); + if (sys->cmd_file_path != NULL) + free(sys->cmd_file_path); + if (sys->config_file_path != NULL) + free(sys->config_file_path); + sys->log_file_path = strdup(parser.log_file_path); + sys->cmd_file_path = strdup(parser.cmd_file_path); + sys->config_file_path = strdup(parser.config_file_path); + sys->mclagdctl_file_path = strdup(parser.mclagdctl_file_path); + sys->pid_file_fd = pid_file_fd; + sys->telnet_port = parser.telnet_port; + parser.finalize(&parser); + iccpd_signal_init(sys); + ICCPD_LOG_INFO(__FUNCTION__, "Iccpd is started, process id = %d. uid %d ", getpid(), getuid()); + scheduler_init(); + scheduler_start(); + system_finalize(); + /*scheduler_finalize(); + log_finalize();*/ + + return EXIT_SUCCESS; +} diff --git a/src/iccpd/src/iccp_netlink.c b/src/iccpd/src/iccp_netlink.c new file mode 100644 index 000000000000..002c254ae9c1 --- /dev/null +++ b/src/iccpd/src/iccp_netlink.c @@ -0,0 +1,1847 @@ +/* + * iccp_netlink.c + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "../include/system.h" +#include "../include/iccp_ifm.h" +#include "../include/port.h" +#include "../include/iccp_csm.h" +#include "../include/logger.h" +#include "../include/scheduler.h" +#include "../include/mlacp_link_handler.h" +#include "../include/msg_format.h" +#include "../include/iccp_netlink.h" + +/** + * SECTION: Netlink helpers + */ +/* \cond HIDDEN_SYMBOLS */ +#ifndef SOL_NETLINK +#define SOL_NETLINK 270 +#endif + +#define ARRAY_SIZE(array_name) (sizeof(array_name) / sizeof(array_name[0])) + +#ifndef NETLINK_BROADCAST_SEND_ERROR +#define NETLINK_BROADCAST_SEND_ERROR 0x4 +#endif + +static int iccp_ack_handler(struct nl_msg *msg, void *arg) +{ + bool *acked = arg; + + *acked = true; + + return NL_STOP; +} + +static int iccp_seq_check_handler(struct nl_msg *msg, void *arg) +{ + unsigned int *seq = arg; + struct nlmsghdr *hdr = nlmsg_hdr(msg); + + if (hdr->nlmsg_seq != *seq) + return NL_SKIP; + + return NL_OK; +} + +int iccp_send_and_recv(struct System *sys, struct nl_msg *msg, + int (*valid_handler)(struct nl_msg *, void *), + void *valid_data) +{ + int ret; + struct nl_cb *cb; + struct nl_cb *orig_cb; + bool acked; + unsigned int seq = sys->genric_sock_seq++; + int err; + + ret = nl_send_auto(sys->genric_sock, msg); + nlmsg_free(msg); + if (ret < 0) + return ret; + + orig_cb = nl_socket_get_cb(sys->genric_sock); + cb = nl_cb_clone(orig_cb); + nl_cb_put(orig_cb); + if (!cb) + return -ENOMEM; + + nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, iccp_ack_handler, &acked); + nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, iccp_seq_check_handler, &seq); + if (valid_handler) + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, valid_handler, valid_data); + + /* There is a bug in libnl. When implicit sequence number checking is in + * use the expected next number is increased when NLMSG_DONE is + * received. The ACK which comes after that correctly includes the + * original sequence number. However libnl is checking that number + * against the incremented one and therefore ack handler is never called + * and nl_recvmsgs finished with an error. To resolve this, custom + * sequence number checking is used here. + */ + + acked = false; + + while (!acked) + { + ret = nl_recvmsgs(sys->genric_sock, cb); + if (ret) + { + err = ret; + goto put_cb; + } + } + + err = 0; + put_cb: + nl_cb_put(cb); + return err; +} + +int iccp_get_portchannel_member_list_handler(struct nl_msg *msg, void * arg) +{ + struct nlmsghdr *nlh = nlmsg_hdr(msg); + struct nlattr *attrs[TEAM_ATTR_MAX + 1]; + struct nlattr *nl_port; + struct nlattr *port_attrs[TEAM_ATTR_PORT_MAX + 1]; + struct LocalInterface* lif = NULL; + struct LocalInterface* local_if_member = NULL; + struct CSM* csm; + int i; + uint32_t ifindex = 0; + struct System* sys = NULL; + struct LocalInterface* local_if = NULL; + char temp_buf[512]; + int len = 0; + + sys = system_get_instance(); + if (sys == NULL) + return 0; + + genlmsg_parse(nlh, 0, attrs, TEAM_ATTR_MAX, NULL); + + if (attrs[TEAM_ATTR_TEAM_IFINDEX]) + ifindex = nla_get_u32(attrs[TEAM_ATTR_TEAM_IFINDEX]); + + local_if = local_if_find_by_ifindex(ifindex); + + if (!local_if) + return NL_SKIP; + + if (local_if->type != IF_T_PORT_CHANNEL) + return NL_SKIP; + + csm = local_if->csm; + + if (csm) + { + if (!attrs[TEAM_ATTR_LIST_PORT]) + return NL_SKIP; + + nla_for_each_nested(nl_port, attrs[TEAM_ATTR_LIST_PORT], i) + { + uint32_t member_index; + + if (nla_parse_nested(port_attrs, TEAM_ATTR_PORT_MAX, nl_port, NULL)) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to parse nested attributes."); + return NL_SKIP; + } + + if (!port_attrs[TEAM_ATTR_PORT_IFINDEX]) + { + ICCPD_LOG_ERR(__FUNCTION__, "ifindex port attribute not found."); + return NL_SKIP; + } + + member_index = nla_get_u32(port_attrs[TEAM_ATTR_PORT_IFINDEX]); + + local_if_member = local_if_find_by_ifindex(member_index); + if (local_if_member == NULL) + { + + ICCPD_LOG_WARN(__FUNCTION__, "%s: Failed to find a port instance (%d).", + local_if->name, member_index); + continue; + } + + if (port_attrs[TEAM_ATTR_PORT_REMOVED] && local_if_member->po_id != -1) + { + local_if_member->po_id = -1; + mlacp_unbind_local_if(local_if_member); + } + else if ( local_if_member->po_id == -1) + { + local_if_member->po_id = local_if->po_id; + mlacp_bind_local_if(local_if->csm, local_if_member); + } + } + + memset(temp_buf, 0, 512); + LIST_FOREACH(lif, &(MLACP(csm).lif_list), mlacp_next) + { + if (lif->type == IF_T_PORT && lif->po_id == local_if->po_id) + { + if (strlen(temp_buf) != 0) + len += snprintf(temp_buf + len, 512 - len, "%s", ","); + + len += snprintf(temp_buf + len, 512 - len, "%s", lif->name); + } + } + + if (strcmp(temp_buf, local_if->portchannel_member_buf)) + { + memset(local_if->portchannel_member_buf, 0, 512); + memcpy(local_if->portchannel_member_buf, temp_buf, sizeof(local_if->portchannel_member_buf) - 1); + + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + /* portchannel member changed, update port isolate attribute*/ + update_peerlink_isolate_from_all_csm_lif(csm); + } + } + } + else /*peerlink portchannel */ + { + if (local_if->is_peer_link) + { + LIST_FOREACH(csm, &(sys->csm_list), next) + { + if (csm->peer_link_if == local_if ) + { + break; + } + } + + if (csm == NULL) + return 0; + + nla_for_each_nested(nl_port, attrs[TEAM_ATTR_LIST_PORT], i) + { + uint32_t member_index; + + if (nla_parse_nested(port_attrs, TEAM_ATTR_PORT_MAX, nl_port, NULL)) + { + ICCPD_LOG_WARN(__FUNCTION__, "Failed to parse nested attributes."); + return NL_SKIP; + } + + if (!port_attrs[TEAM_ATTR_PORT_IFINDEX]) + { + ICCPD_LOG_WARN(__FUNCTION__, "ifindex port attribute not found."); + return NL_SKIP; + } + + member_index = nla_get_u32(port_attrs[TEAM_ATTR_PORT_IFINDEX]); + + local_if_member = local_if_find_by_ifindex(member_index); + if (local_if_member == NULL) + { + ICCPD_LOG_WARN(__FUNCTION__, "%s: Failed to find a port instance (%d).", + local_if->name, member_index); + continue; + } + + if (port_attrs[TEAM_ATTR_PORT_REMOVED] && local_if_member->po_id != -1) + { + local_if_member->po_id = -1; + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + /*link removed from portchannel, must be enabled mac learn*/ + set_peerlink_mlag_port_learn(local_if_member, 1); + } + + continue; + } + else if ( local_if_member->po_id == -1) + { + local_if_member->po_id = local_if->po_id; + + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + /*link add to portchannel, must be disabled mac learn*/ + set_peerlink_mlag_port_learn(local_if, 0); + } + } + } + + memset(temp_buf, 0, 512); + LIST_FOREACH(lif, &(sys->lif_list), system_next) + { + if (lif->type == IF_T_PORT && lif->po_id == local_if->po_id) + { + if (strlen(temp_buf) != 0) + len += snprintf(temp_buf + len, 512 - len, "%s", ","); + + len += snprintf(temp_buf + len, 512 - len, "%s", lif->name); + } + } + + if (strcmp(temp_buf, local_if->portchannel_member_buf)) + { + memset(local_if->portchannel_member_buf, 0, 512); + memcpy(local_if->portchannel_member_buf, temp_buf, sizeof(local_if->portchannel_member_buf) - 1); + } + } + } + + return 0; +} + +int iccp_genric_socket_team_family_get() +{ + struct System* sys = NULL; + int err = 0; + int grp_id = 0; + + if ((sys = system_get_instance()) == NULL ) + return MCLAG_ERROR; + if (sys->family < 0) + { + sys->family = genl_ctrl_resolve(sys->genric_sock, TEAM_GENL_NAME); + + while (sys->family < 0) + { + sleep(1); + + /*If no portchannel configuration, teamd will not started, genl_ctrl_resolve() will return <0 forever */ + /*Only log error message 5 times*/ + + ICCPD_LOG_ERR(__FUNCTION__, "Failed to resolve netlink family. %d of TEAM_GENL_NAME %s ", sys->family, TEAM_GENL_NAME); + sys->family = genl_ctrl_resolve(sys->genric_sock, TEAM_GENL_NAME); + + } + + grp_id = genl_ctrl_resolve_grp(sys->genric_sock, TEAM_GENL_NAME, + TEAM_GENL_CHANGE_EVENT_MC_GRP_NAME); + if (grp_id < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to resolve netlink multicast groups. %d", grp_id); + } + + err = nl_socket_add_membership(sys->genric_event_sock, grp_id); + if (err < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to add netlink membership."); + + } + } + + return err; +} + +int iccp_get_port_member_list(struct LocalInterface* lif) +{ + struct System *sys; + struct nl_msg *msg; + int err; + + sys = system_get_instance(); + if (sys == NULL) + return 0; + + msg = nlmsg_alloc(); + if (!msg) + return -ENOMEM; + + err = iccp_genric_socket_team_family_get(); + if (err) + { + ICCPD_LOG_ERR(__FUNCTION__, "genric socket family get err err = %d . errno = %d", err, errno); + return err; + } + + genlmsg_put(msg, NL_AUTO_PID, sys->genric_sock_seq, sys->family, 0, 0, + TEAM_CMD_PORT_LIST_GET, 0); + nla_put_u32(msg, TEAM_ATTR_TEAM_IFINDEX, lif->ifindex); + + err = iccp_send_and_recv(sys, msg, iccp_get_portchannel_member_list_handler, lif); + if (err) + { + ICCPD_LOG_ERR(__FUNCTION__, "recv msg err err = %d . errno = %d", err, errno); + return err; + } + + return 0; +} + +int iccp_netlink_if_hwaddr_set(uint32_t ifindex, uint8_t *addr, unsigned int addr_len) +{ + struct rtnl_link *link; + int err; + struct nl_addr *nl_addr; + struct System* sys = NULL; + + if (!(sys = system_get_instance())) + return MCLAG_ERROR; + + link = rtnl_link_alloc(); + if (!link) + return -ENOMEM; + + nl_addr = nl_addr_build(AF_UNSPEC, (void *)addr, addr_len); + if (!nl_addr) + { + err = -ENOMEM; + goto errout; + } + + rtnl_link_set_ifindex(link, ifindex); + rtnl_link_set_addr(link, nl_addr); + + err = rtnl_link_change(sys->route_sock, link, link, 0); + + nl_addr_put(nl_addr); + + errout: + rtnl_link_put(link); + return err; +} + +#define SET_MAC_STR(buf, macArray) \ + snprintf(buf, 64, "%02x:%02x:%02x:%02x:%02x:%02x", \ + macArray[0], macArray[1], macArray[2], \ + macArray[3], macArray[4], macArray[5]); + +void iccp_set_interface_ipadd_mac(struct LocalInterface *lif, char * mac_addr ) +{ + struct IccpSyncdHDr * msg_hdr; + mclag_sub_option_hdr_t * sub_msg; + char msg_buf[4096]; + struct System *sys; + + int src_len = 0, dst_len = 0; + + sys = system_get_instance(); + if (sys == NULL) + return; + + memset(msg_buf, 0, 4095); + + msg_hdr = (struct IccpSyncdHDr *)msg_buf; + msg_hdr->ver = 1; + msg_hdr->type = MCLAG_MSG_TYPE_SET_MAC; + msg_hdr->len = sizeof(struct IccpSyncdHDr); + + /*sub msg src*/ + sub_msg = (mclag_sub_option_hdr_t *)&msg_buf[msg_hdr->len]; + sub_msg->op_type = MCLAG_SUB_OPTION_TYPE_SET_MAC_SRC; + + /*src_len = snprintf((char *)sub_msg->data, 512, "%s:%s/%d", lif->name,show_ip_str(htonl(lif->ipv4_addr)),lif->prefixlen);*/ + src_len = snprintf((char *)sub_msg->data, 512, "%s", lif->name); + + sub_msg->op_len = src_len; + + /*sub msg dst */ + msg_hdr->len += sub_msg->op_len; + msg_hdr->len += sizeof(mclag_sub_option_hdr_t); + sub_msg = (mclag_sub_option_hdr_t *)&msg_buf[msg_hdr->len]; + sub_msg->op_type = MCLAG_SUB_OPTION_TYPE_SET_MAC_DST; + + dst_len = strlen(mac_addr); + memcpy(sub_msg->data, mac_addr, dst_len); + + ICCPD_LOG_NOTICE(__FUNCTION__, "If name %s ip %s mac %s", lif->name, show_ip_str(htonl(lif->ipv4_addr)), sub_msg->data); + + sub_msg->op_len = dst_len; + msg_hdr->len += sizeof(mclag_sub_option_hdr_t); + msg_hdr->len += sub_msg->op_len; + + /*send msg*/ + if (sys->sync_fd) + write(sys->sync_fd, msg_buf, msg_hdr->len); + + return; +} + +int iccp_netlink_if_startup_set(uint32_t ifindex) +{ + struct rtnl_link *link; + int err; + struct System *sys = NULL; + + if (!(sys = system_get_instance())) + return MCLAG_ERROR; + + link = rtnl_link_alloc(); + if (!link) + return -ENOMEM; + + rtnl_link_set_ifindex(link, ifindex); + rtnl_link_set_flags(link, IFF_UP); + + err = rtnl_link_change(sys->route_sock, link, link, 0); + +errout: + rtnl_link_put(link); + return err; +} + +int iccp_netlink_if_shutdown_set(uint32_t ifindex) +{ + struct rtnl_link *link; + int err; + struct System *sys = NULL; + + if (!(sys = system_get_instance())) + return MCLAG_ERROR; + + link = rtnl_link_alloc(); + if (!link) + return -ENOMEM; + + rtnl_link_set_ifindex(link, ifindex); + rtnl_link_unset_flags(link, IFF_UP); + + err = rtnl_link_change(sys->route_sock, link, link, 0); + +errout: + rtnl_link_put(link); + return err; +} +void update_if_ipmac_on_standby(struct LocalInterface* lif_po) +{ + struct CSM* csm; + uint8_t null_mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + struct VLAN_ID *vlan = NULL; + + csm = lif_po->csm; + struct LocalInterface* lif_Bri; + char macaddr[64]; + int ret = 0; + + if (!csm) + return; + + if (lif_po->type != IF_T_PORT_CHANNEL) + return; + + if (csm->role_type != STP_ROLE_STANDBY) + { + return; + } + + if (memcmp(MLACP(csm).remote_system.system_id, null_mac, ETHER_ADDR_LEN) == 0) + return; + + /*Set new mac*/ + if (memcmp( lif_po->mac_addr, MLACP(csm).remote_system.system_id, ETHER_ADDR_LEN) != 0) + { + /*Backup old sysmac*/ + memcpy(lif_po->mac_addr_ori, lif_po->mac_addr, ETHER_ADDR_LEN); + + ICCPD_LOG_NOTICE(__FUNCTION__, + "%s Change the system-id of %s from [%02X:%02X:%02X:%02X:%02X:%02X] to [%02X:%02X:%02X:%02X:%02X:%02X].", + (csm->role_type == STP_ROLE_STANDBY) ? "Standby" : "Active", + lif_po->name, lif_po->mac_addr[0], lif_po->mac_addr[1], lif_po->mac_addr[2], lif_po->mac_addr[3], lif_po->mac_addr[4], lif_po->mac_addr[5], + MLACP(csm).remote_system.system_id[0], MLACP(csm).remote_system.system_id[1], MLACP(csm).remote_system.system_id[2], MLACP(csm).remote_system.system_id[3], MLACP(csm).remote_system.system_id[4], MLACP(csm).remote_system.system_id[5]); + + ret = iccp_netlink_if_hwaddr_set(lif_po->ifindex, MLACP(csm).remote_system.system_id, ETHER_ADDR_LEN); + if (ret != 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Set %s mac error, ret = %d", lif_po->name, ret); + } + + /* Refresh link local address according the new MAC */ + iccp_netlink_if_shutdown_set(lif_po->ifindex); + iccp_netlink_if_startup_set(lif_po->ifindex); + } + + /*Set portchannel ip mac */ + memset(macaddr, 0, 64); + SET_MAC_STR(macaddr, MLACP(csm).remote_system.system_id); + if (local_if_is_l3_mode(lif_po)) + { + if (memcmp(lif_po->l3_mac_addr, MLACP(csm).remote_system.system_id, ETHER_ADDR_LEN) != 0) + { + iccp_set_interface_ipadd_mac(lif_po, macaddr ); + memcpy(lif_po->l3_mac_addr, MLACP(csm).remote_system.system_id, ETHER_ADDR_LEN); + } + } + else + { + LIST_FOREACH(vlan, &(lif_po->vlan_list), port_next) + { + if (!vlan->vlan_itf) + continue; + + /*If the po is under a vlan, update vlan mac*/ + if (local_if_is_l3_mode(vlan->vlan_itf)) + { + if (memcmp(vlan->vlan_itf->l3_mac_addr, MLACP(csm).remote_system.system_id, ETHER_ADDR_LEN) != 0) + { + ret = iccp_netlink_if_hwaddr_set(vlan->vlan_itf->ifindex, MLACP(csm).remote_system.system_id, ETHER_ADDR_LEN); + if (ret != 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Set %s mac error, ret = %d", vlan->vlan_itf->name, ret); + } + + /* Refresh link local address according the new MAC */ + iccp_netlink_if_shutdown_set(vlan->vlan_itf->ifindex); + iccp_netlink_if_startup_set(vlan->vlan_itf->ifindex); + + iccp_set_interface_ipadd_mac(vlan->vlan_itf, macaddr); + memcpy(vlan->vlan_itf->l3_mac_addr, MLACP(csm).remote_system.system_id, ETHER_ADDR_LEN); + } + } + } + } + + return; +} + +void recover_if_ipmac_on_standby(struct LocalInterface* lif_po) +{ + struct CSM* csm; + uint8_t null_mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + struct VLAN_ID *vlan = NULL; + + csm = lif_po->csm; + char macaddr[64]; + int ret = 0; + + if (!csm) + return; + + if (lif_po->type != IF_T_PORT_CHANNEL) + return; + + if (csm->role_type != STP_ROLE_STANDBY) + { + return; + } + + /*Recover mac to origin mac, it is the 'mac' value in 'localhost' currently*/ + if (memcmp( lif_po->mac_addr, MLACP(csm).system_id, ETHER_ADDR_LEN) != 0) + { + ICCPD_LOG_NOTICE(__FUNCTION__, + "%s Recover the system-id of %s from [%02X:%02X:%02X:%02X:%02X:%02X] to [%02X:%02X:%02X:%02X:%02X:%02X].", + (csm->role_type == STP_ROLE_STANDBY) ? "Standby" : "Active", + lif_po->name, lif_po->mac_addr[0], lif_po->mac_addr[1], lif_po->mac_addr[2], lif_po->mac_addr[3], lif_po->mac_addr[4], lif_po->mac_addr[5], + MLACP(csm).system_id[0], MLACP(csm).system_id[1], MLACP(csm).system_id[2], MLACP(csm).system_id[3], MLACP(csm).system_id[4], MLACP(csm).system_id[5]); + + ret = iccp_netlink_if_hwaddr_set(lif_po->ifindex, MLACP(csm).system_id, ETHER_ADDR_LEN); + if (ret != 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Set %s mac error, ret = %d", lif_po->name, ret); + } + + /* Refresh link local address according the new MAC */ + iccp_netlink_if_shutdown_set(lif_po->ifindex); + iccp_netlink_if_startup_set(lif_po->ifindex); + } + + /*Set portchannel ip mac */ + memset(macaddr, 0, 64); + SET_MAC_STR(macaddr, MLACP(csm).system_id); + if (local_if_is_l3_mode(lif_po)) + { + iccp_set_interface_ipadd_mac(lif_po, macaddr ); + memcpy(lif_po->l3_mac_addr, MLACP(csm).system_id, ETHER_ADDR_LEN); + } + else + { + LIST_FOREACH(vlan, &(lif_po->vlan_list), port_next) + { + if (!vlan->vlan_itf) + continue; + + /*If the po is under a vlan, update vlan mac*/ + if (local_if_is_l3_mode(vlan->vlan_itf)) + { + ret = iccp_netlink_if_hwaddr_set(vlan->vlan_itf->ifindex, MLACP(csm).system_id, ETHER_ADDR_LEN); + if (ret != 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Set %s mac error, ret = %d", vlan->vlan_itf->name, ret); + } + + /* Refresh link local address according the new MAC */ + iccp_netlink_if_shutdown_set(vlan->vlan_itf->ifindex); + iccp_netlink_if_startup_set(vlan->vlan_itf->ifindex); + + iccp_set_interface_ipadd_mac(vlan->vlan_itf, macaddr); + memcpy(vlan->vlan_itf->l3_mac_addr, MLACP(csm).system_id, ETHER_ADDR_LEN); + } + } + } + + return; +} + +int iccp_netlink_neighbor_request(int family, uint8_t *addr, int add, uint8_t *mac, char *portname) +{ + struct System *sys = NULL; + struct rtnl_neigh *neigh = NULL; + struct nl_addr *nl_addr_mac = NULL; + struct nl_addr *nl_addr_dst = NULL; + struct LocalInterface *lif = NULL; + struct nl_cache *link_cache; + char mac_str[18] = ""; + int err = 0; + + if (!(sys = system_get_instance())) + return MCLAG_ERROR; + + lif = local_if_find_by_name(portname); + if (!lif) + return MCLAG_ERROR; + + neigh = rtnl_neigh_alloc(); + if (!neigh) + { + ICCPD_LOG_INFO(__FUNCTION__, "Unable to allocate neighbour object"); + return MCLAG_ERROR; + } + + sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + ICCPD_LOG_NOTICE(__FUNCTION__, "Notify kernel %s %s entry(ip:%s, mac:%s, intf:%s)", + add ? "add" : "del", (family == AF_INET) ? "ARP" : "ND", + (family == AF_INET) ? show_ip_str(*((int *)addr)) : show_ipv6_str(addr), mac_str, portname); + + nl_addr_mac = nl_addr_build(AF_LLC, (void *)mac, ETHER_ADDR_LEN); + if (!nl_addr_mac) + { + err = MCLAG_ERROR; + goto errout; + } + + if (family == AF_INET) + nl_addr_dst = nl_addr_build(family, (void *)addr, 4); + else + nl_addr_dst = nl_addr_build(family, (void *)addr, 16); + + if (!nl_addr_dst) + { + err = MCLAG_ERROR; + goto errout; + } + + rtnl_neigh_set_lladdr(neigh, nl_addr_mac); + rtnl_neigh_set_dst(neigh, nl_addr_dst); + rtnl_neigh_set_ifindex(neigh, lif->ifindex); + rtnl_neigh_set_state(neigh, NUD_REACHABLE); + + if (add) + { + if ((err = rtnl_neigh_add(sys->route_sock, neigh, NLM_F_REPLACE | NLM_F_CREATE)) < 0) + ICCPD_LOG_WARN(__FUNCTION__, "Add %s (ip:%s, mac:%s) error, err = %d", (family == AF_INET) ? "ARP" : "ND", + (family == AF_INET) ? show_ip_str(*((int *)addr)) : show_ipv6_str(addr), mac_str, err); + } + else + { + if ((err = rtnl_neigh_delete(sys->route_sock, neigh, 0)) < 0) + ICCPD_LOG_WARN(__FUNCTION__, "Del %s (ip:%s, mac:%s) error, err = %d", (family == AF_INET) ? "ARP" : "ND", + (family == AF_INET) ? show_ip_str(*((int *)addr)) : show_ipv6_str(addr), mac_str, err); + } + +errout: + nl_addr_put(nl_addr_mac); + nl_addr_put(nl_addr_dst); + rtnl_neigh_put(neigh); + return err; +} + +void iccp_event_handler_obj_input_newlink(struct nl_object *obj, void *arg) +{ + struct rtnl_link *link; + unsigned int *event = arg; + uint32_t ifindex; + char * ifname, *p; + struct LocalInterface *lif = NULL; + struct nl_addr *nl_addr; + int addr_type = 0; + int op_state = 0; + int link_flag = 0; + + link = (struct rtnl_link *)obj; + ifindex = rtnl_link_get_ifindex(link); + op_state = rtnl_link_get_operstate(link); + ifname = rtnl_link_get_name(link); + nl_addr = rtnl_link_get_addr(link); + link_flag = rtnl_link_get_flags(link); + + if (nl_addr) + addr_type = nl_addr_guess_family(nl_addr); + + /*Vxlan tunnel dev name is like VTTNL0001-1000, VTTNL0001 is vxlan tunnel name, 1000 is vni*/ + /*If dev is vxlan tunnel, only create the tunnel with name no vni, like VTTNL0001*/ + if ((strncmp(ifname, VXLAN_TUNNEL_PREFIX, strlen(VXLAN_TUNNEL_PREFIX)) == 0)) + { + /*Change ifname from VTTNL0001-1000 to VTTNL0001*/ + if ((p = strchr(ifname, '-')) != NULL) + { + *p = '\0'; + } + /*Create vxlan tunnel dev, state is always UP*/ + lif = local_if_find_by_name(ifname); + if (!lif) + { + lif = local_if_create(ifindex, ifname, IF_T_VXLAN); + lif->state = PORT_STATE_UP; + } + return; + } + else + lif = local_if_find_by_ifindex(ifindex); + + if (!lif) + { + const itf_type_t if_whitelist[] = { + { PORTCHANNEL_PREFIX, IF_T_PORT_CHANNEL }, + { VLAN_PREFIX, IF_T_VLAN }, + { FRONT_PANEL_PORT_PREFIX, IF_T_PORT }, + { VXLAN_TUNNEL_PREFIX, IF_T_VXLAN }, + { NULL, 0 } + }; + int i = 0; + + for (i = 0; if_whitelist[i].ifname != NULL; ++i) + { + if ((strncmp(ifname, + if_whitelist[i].ifname, strlen(if_whitelist[i].ifname)) == 0)) + { + lif = local_if_create(ifindex, ifname, if_whitelist[i].type); + + lif->state = PORT_STATE_DOWN; + + if (IF_OPER_UP == op_state ) + { + lif->state = PORT_STATE_UP; + } + + switch (addr_type) + { + case AF_LLC: + memcpy( lif->mac_addr, nl_addr_get_binary_addr(nl_addr), ETHER_ADDR_LEN); + default: + break; + } + + break; + } + } + } + else /*update*/ + { + /*update*/ + if (lif->state == PORT_STATE_DOWN && op_state == IF_OPER_UP) + { + lif->state = PORT_STATE_UP; + /*if(lif->type ==IF_T_PORT_CHANNEL)*/ + ICCPD_LOG_NOTICE(__FUNCTION__, "Update local port %s state up", ifname); + + iccp_from_netlink_port_state_handler(lif->name, lif->state); + } + else if (lif->state == PORT_STATE_UP && ( IF_OPER_UP != op_state || !(link_flag & IFF_LOWER_UP))) + { + lif->state = PORT_STATE_DOWN; + /*if(lif->type ==IF_T_PORT_CHANNEL)*/ + ICCPD_LOG_NOTICE(__FUNCTION__, "Update local port %s state down", ifname); + + iccp_from_netlink_port_state_handler(lif->name, lif->state); + } + + switch (addr_type) + { + case AF_LLC: + if (memcmp(nl_addr_get_binary_addr(nl_addr), lif->mac_addr, ETHER_ADDR_LEN) != 0) + { + memcpy( lif->mac_addr, nl_addr_get_binary_addr(nl_addr), ETHER_ADDR_LEN); + lif->port_config_sync = 1; + } + + default: + break; + } + } + + return; +} + +void iccp_event_handler_obj_input_dellink(struct nl_object *obj, void *arg) +{ + struct rtnl_link *link; + struct LocalInterface *lif; + uint32_t ifindex; + + link = (struct rtnl_link *)obj; + + ifindex = rtnl_link_get_ifindex(link); + if ((lif = local_if_find_by_ifindex(ifindex)) != NULL) + local_if_destroy(lif->name); + + return; +} + +void iccp_event_handler_obj_input_newaddr(struct nl_object *obj, void *arg) +{ + struct rtnl_addr *addr; + struct nl_addr *nl_addr; + struct LocalInterface *lif; + uint32_t ifindex; + char addrStr[65] = { 0 }; + char addr_null[16] = { 0 }; + addr = (struct rtnl_addr *)obj; + + ifindex = rtnl_addr_get_ifindex(addr); + nl_addr = rtnl_addr_get_local(addr); + + if (!(lif = local_if_find_by_ifindex(ifindex))) + return; + + if (rtnl_addr_get_family(addr) == AF_INET) + { + lif->ipv4_addr = *(uint32_t *) nl_addr_get_binary_addr(nl_addr); + lif->prefixlen = nl_addr_get_prefixlen(nl_addr); + lif->l3_mode = 1; + lif->port_config_sync = 1; + if (memcmp((char *)lif->ipv6_addr, addr_null, 16) == 0) + update_if_ipmac_on_standby(lif); + ICCPD_LOG_DEBUG(__FUNCTION__, "Ifname %s index %d address %s", lif->name, lif->ifindex, show_ip_str(lif->ipv4_addr)); + } + else if (rtnl_addr_get_family(addr) == AF_INET6) + { + if (memcmp(show_ipv6_str((char *)nl_addr_get_binary_addr(nl_addr)), "FE80", 4) == 0 + || memcmp(show_ipv6_str((char *)nl_addr_get_binary_addr(nl_addr)), "fe80", 4) == 0) + return; + + memcpy((char *)lif->ipv6_addr, nl_addr_get_binary_addr(nl_addr), 16); + lif->prefixlen = nl_addr_get_prefixlen(nl_addr); + lif->l3_mode = 1; + lif->port_config_sync = 1; + if (lif->ipv4_addr == 0) + update_if_ipmac_on_standby(lif); + ICCPD_LOG_DEBUG(__FUNCTION__, "Ifname %s index %d address %s", lif->name, lif->ifindex, show_ipv6_str((char *)lif->ipv6_addr)); + } + + return; +} + +void iccp_event_handler_obj_input_deladdr(struct nl_object *obj, void *arg) +{ + struct rtnl_addr *addr; + struct nl_addr *nl_addr; + struct LocalInterface *lif; + uint32_t ifindex; + char addr_null[16] = { 0 }; + + addr = (struct rtnl_addr *)obj; + + ifindex = rtnl_addr_get_ifindex(addr); + nl_addr = rtnl_addr_get_local(addr); + + if (!(lif = local_if_find_by_ifindex(ifindex))) + return; + + if (rtnl_addr_get_family(addr) == AF_INET) + { + lif->ipv4_addr = 0; + lif->prefixlen = 0; + } + else if (rtnl_addr_get_family(addr) == AF_INET6) + { + if (memcmp(show_ipv6_str((char *)nl_addr_get_binary_addr(nl_addr)), "FE80", 4) == 0 + || memcmp(show_ipv6_str((char *)nl_addr_get_binary_addr(nl_addr)), "fe80", 4) == 0) + return; + + memset((char *)lif->ipv6_addr, 0, 16); + lif->prefixlen_v6 = 0; + } + + if (lif->ipv4_addr == 0 && memcmp((char *)lif->ipv6_addr, addr_null, 16) == 0) + { + lif->l3_mode = 0; + memset(lif->l3_mac_addr, 0, ETHER_ADDR_LEN); + } + + return; +} + +int iccp_addr_valid_handler(struct nl_msg *msg, void *arg) +{ + struct nlmsghdr *nlh = nlmsg_hdr(msg); + unsigned int event = 0; + if (nlh->nlmsg_type != RTM_NEWADDR) + return 0; + + if (nl_msg_parse(msg, &iccp_event_handler_obj_input_newaddr, &event) < 0) + ICCPD_LOG_ERR(__FUNCTION__, "Unknown message type."); + + return 0; +} + +int iccp_check_if_addr_from_netlink(int family, uint8_t *addr, struct LocalInterface *lif) +{ + struct + { + struct nlmsghdr nlh; + struct ifaddrmsg ifa; + } req; + + struct sockaddr_nl nladdr; + struct iovec iov; + struct msghdr msg = { + .msg_name = &nladdr, + .msg_namelen = sizeof(nladdr), + .msg_iov = &iov, + .msg_iovlen = 1, + }; + + int fd; + struct System *sys; + if ((sys = system_get_instance()) == NULL) + { + return 0; + } + + memset(&req, 0, sizeof(req)); + req.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); + req.nlh.nlmsg_type = RTM_GETADDR; + req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST; + req.nlh.nlmsg_pid = 0; + req.nlh.nlmsg_seq = 0; + req.ifa.ifa_family = family; + + fd = nl_socket_get_fd(sys->route_sock); + send(fd, (void*)&req, sizeof(req), 0); + + char * buf = malloc(10000); + iov.iov_base = buf; + + while (1) + { + int status; + int msglen = 0; + iov.iov_len = 10000; + status = recvmsg(fd, &msg, 0); + + if (status < 0 || status == 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "netlink receive error (%d) status %d %d ", fd, status, errno); + free(buf); + return 0; + } + struct nlmsghdr *n = (struct nlmsghdr*)buf; + msglen = status; + + while (NLMSG_OK(n, msglen)) + { + if (n->nlmsg_type != RTM_NEWADDR) + { + free(buf); + return 0; + } + struct ifaddrmsg *ifa; + ifa = NLMSG_DATA(n); + if (lif && lif->ifindex == ifa->ifa_index) + { + struct rtattr *rth = IFA_RTA(ifa); + int rtl = IFA_PAYLOAD(n); + + while (rtl && RTA_OK(rth, rtl)) + { + if (rth->rta_type == IFA_ADDRESS || rth->rta_type == IFA_LOCAL) + { + if (family == AF_INET && ifa->ifa_family == AF_INET) + { + if (*(uint32_t *)addr == ntohl(*((uint32_t *)RTA_DATA(rth)))) + { + free(buf); + return 1; + } + } + + if (family == AF_INET6 && ifa->ifa_family == AF_INET6) + { + void *addr_netlink; + addr_netlink = RTA_DATA(rth); + if (!memcmp((uint8_t *)addr_netlink, addr, 16)) + { + free(buf); + return 1; + } + } + } + rth = RTA_NEXT(rth, rtl); + } + } + n = NLMSG_NEXT(n, msglen); + } + } + + free(buf); + + return 0; +} + +int iccp_sys_local_if_list_get_addr() +{ + struct System *sys = NULL; + struct nl_cb *cb; + struct nl_cb *orig_cb; + struct rtgenmsg rt_hdr = { + .rtgen_family = AF_UNSPEC, + }; + int ret; + int retry = 1; + + if (!(sys = system_get_instance())) + return MCLAG_ERROR; + + while (retry) + { + retry = 0; + ret = nl_send_simple(sys->route_sock, RTM_GETADDR, NLM_F_DUMP, + &rt_hdr, sizeof(rt_hdr)); + + if (ret < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "send netlink msg error."); + return ret; + } + + orig_cb = nl_socket_get_cb(sys->route_sock); + cb = nl_cb_clone(orig_cb); + nl_cb_put(orig_cb); + if (!cb) + { + ICCPD_LOG_ERR(__FUNCTION__, "nl cb clone error."); + return -ENOMEM; + } + + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, iccp_addr_valid_handler, sys); + ret = nl_recvmsgs(sys->route_sock, cb); + nl_cb_put(cb); + if (ret < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Receive netlink msg error, ret = %d errno = %d .", ret, errno); + if (ret != -NLE_DUMP_INTR) + return ret; + retry = 1; + } + } + + return ret; +} + +static int iccp_route_event_handler(struct nl_msg *msg, void *arg) +{ + struct nlmsghdr *nlh = nlmsg_hdr(msg); + unsigned int event = 1; + + switch (nlh->nlmsg_type) + { + case RTM_NEWLINK: + if (nl_msg_parse(msg, &iccp_event_handler_obj_input_newlink, &event) < 0) + ICCPD_LOG_DEBUG(__FUNCTION__, "Unknown message type(RTM_NEWLINK)"); + iccp_parse_if_vlan_info_from_netlink(nlh); + break; + + case RTM_DELLINK: + if (nl_msg_parse(msg, &iccp_event_handler_obj_input_dellink, NULL) < 0) + ICCPD_LOG_DEBUG(__FUNCTION__, "Unknown message type(RTM_DELLINK)"); + break; + + case RTM_NEWNEIGH: + case RTM_DELNEIGH: + do_one_neigh_request(nlh); + break; + + case RTM_NEWADDR: + if (nl_msg_parse(msg, &iccp_event_handler_obj_input_newaddr, NULL) < 0) + ICCPD_LOG_DEBUG(__FUNCTION__, "Unknown message type(RTM_NEWADDR)."); + break; + case RTM_DELADDR: + if (nl_msg_parse(msg, &iccp_event_handler_obj_input_deladdr, NULL) < 0) + ICCPD_LOG_DEBUG(__FUNCTION__, "Unknown message type(RTM_DELADDR)."); + break; + default: + return NL_OK; + } + + return NL_STOP; +} + +/** + * SECTION: Context functions + */ +static int iccp_genric_event_handler(struct nl_msg *msg, void *arg) +{ + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + + switch (gnlh->cmd) + { + case TEAM_CMD_PORT_LIST_GET: + return iccp_get_portchannel_member_list_handler(msg, NULL); + } + + return NL_SKIP; +} + +int iccp_make_nd_socket(void) +{ + int sock; + int ret; + int val; + struct icmp6_filter filter; + + sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); + + if (sock < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to create nd socket"); + return MCLAG_ERROR; + } + + val = 1; +#ifdef IPV6_RECVPKTINFO /* 2292bis-01 */ + if (setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &val, sizeof(val)) < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to set IPV6_RECVPKTINFO for nd socket"); + close(sock); + return MCLAG_ERROR; + } +#else /* RFC2292 */ + if (setsockopt(sock, IPPROTO_IPV6, IPV6_PKTINFO, &val, sizeof(val)) < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to set IPV6_PKTINFO for nd socket"); + close(sock); + return MCLAG_ERROR; + } +#endif + + ICMP6_FILTER_SETBLOCKALL(&filter); + ICMP6_FILTER_SETPASS(ND_NEIGHBOR_ADVERT, &filter); + + ret = setsockopt(sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filter, sizeof(struct icmp6_filter)); + + if (ret < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to set ICMP6_FILTER"); + close(sock); + return MCLAG_ERROR; + } + + return sock; +} + +/*init netlink socket*/ +int iccp_system_init_netlink_socket() +{ + struct System* sys = NULL; + int val = 0; + int err = 0; + + if ((sys = system_get_instance()) == NULL ) + return MCLAG_ERROR; + + sys->genric_sock = nl_socket_alloc(); + if (!sys->genric_sock) + goto err_genric_sock_alloc; + + sys->genric_sock_seq = time(NULL); + err = genl_connect(sys->genric_sock); + if (err) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to connect to netlink sock sys->genric_sock."); + goto err_genric_sock_connect; + } + + sys->genric_event_sock = nl_socket_alloc(); + if (!sys->genric_event_sock) + goto err_genric_event_sock_alloc; + + err = genl_connect(sys->genric_event_sock); + if (err) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to connect to netlink sys->genric_event_sock."); + goto err_genric_event_sock_connect; + } + + sys->route_sock = nl_socket_alloc(); + if (!sys->route_sock) + goto err_route_sock_alloc; + err = nl_connect(sys->route_sock, NETLINK_ROUTE); + if (err) + goto err_route_sock_connect; + + err = nl_socket_set_buffer_size(sys->route_sock, 98304, 0); + if (err) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to set buffer size of netlink route event sock."); + goto err_route_sock_connect; + } + + sys->route_event_sock = nl_socket_alloc(); + if (!sys->route_event_sock) + goto err_route_event_sock_alloc; + + err = nl_connect(sys->route_event_sock, NETLINK_ROUTE); + if (err) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to connect to netlink sys->route_event_sock. "); + goto err_route_event_sock_connect; + } + + err = nl_socket_set_buffer_size(sys->route_event_sock, 983040, 0); + if (err) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to set buffer size of netlink route event sock."); + goto err_route_event_sock_connect; + } + + val = NETLINK_BROADCAST_SEND_ERROR; + err = setsockopt(nl_socket_get_fd(sys->genric_event_sock), SOL_NETLINK, + NETLINK_BROADCAST_ERROR, &val, sizeof(val)); + if (err) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed set NETLINK_BROADCAST_ERROR on netlink event sock."); + goto err_return; + } + + err = nl_socket_set_buffer_size(sys->genric_sock, 98304, 0); + if (err) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to set buffer size of netlink sock."); + goto err_return; + } + + err = nl_socket_set_buffer_size(sys->genric_event_sock, 98304, 0); + if (err) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to set buffer size of netlink event sock."); + goto err_return; + } + + nl_socket_disable_seq_check(sys->genric_event_sock); + nl_socket_modify_cb(sys->genric_event_sock, NL_CB_VALID, NL_CB_CUSTOM, + iccp_genric_event_handler, sys); + + nl_socket_disable_seq_check(sys->route_event_sock); + nl_socket_modify_cb(sys->route_event_sock, NL_CB_VALID, NL_CB_CUSTOM, + iccp_route_event_handler, sys); + + err = nl_socket_add_membership(sys->route_event_sock, RTNLGRP_NEIGH); + if (err < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to add netlink membership."); + goto err_return; + } + + err = nl_socket_add_membership(sys->route_event_sock, RTNLGRP_LINK); + if (err < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to add netlink membership."); + goto err_return; + } + + err = nl_socket_add_membership(sys->route_event_sock, RTNLGRP_IPV4_IFADDR); + if (err < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to add netlink membership."); + goto err_return; + } + err = nl_socket_add_membership(sys->route_event_sock, RTNLGRP_IPV6_IFADDR); + if (err < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to add netlink membership."); + goto err_return; + } + /* receive arp packet socket */ + sys->arp_receive_fd = socket(PF_PACKET, SOCK_DGRAM, 0); + if (sys->arp_receive_fd < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "socket error "); + goto err_return; + } + + if (1) + { + struct sockaddr_ll sll; + memset(&sll, 0, sizeof(sll)); + sll.sll_family = AF_PACKET; + sll.sll_protocol = htons(ETH_P_ARP); + sll.sll_ifindex = 0; + if (bind(sys->arp_receive_fd, (struct sockaddr*)&sll, sizeof(sll)) < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "socket bind error"); + goto err_return; + } + } + + sys->ndisc_receive_fd = iccp_make_nd_socket(); + + if (sys->ndisc_receive_fd < 0) + { + goto err_return; + } + + goto succes_return; + + err_return: + + err_route_event_sock_connect: + nl_socket_free(sys->route_event_sock); + + err_route_sock_alloc: + err_route_sock_connect: + nl_socket_free(sys->route_sock); + + err_route_event_sock_alloc: + err_genric_event_sock_connect: + nl_socket_free(sys->genric_event_sock); + + err_genric_event_sock_alloc: + err_genric_sock_connect: + nl_socket_free(sys->genric_sock); + + return err; + + err_genric_sock_alloc: + + succes_return: + return 0; +} + +void iccp_system_dinit_netlink_socket() +{ + struct System* sys = NULL; + + if ((sys = system_get_instance()) == NULL ) + return; + + nl_socket_free(sys->route_event_sock); + nl_socket_free(sys->route_sock); + nl_socket_free(sys->genric_event_sock); + nl_socket_free(sys->genric_sock); + return; +} + +static int iccp_get_netlink_genic_sock_event_fd(struct System *sys) +{ + return nl_socket_get_fd(sys->genric_event_sock); +} + +static int iccp_netlink_genic_sock_event_handler(struct System *sys) +{ + int ret = 0; + + ret = nl_recvmsgs_default(sys->genric_event_sock); + if (ret) + { + sys->need_sync_team_again = 1; + ICCPD_LOG_DEBUG(__FUNCTION__, "genric_event_sock %d recvmsg error ret = %d ", nl_socket_get_fd(sys->genric_event_sock), ret); + } + + return ret; +} + +static int iccp_get_netlink_route_sock_event_fd(struct System *sys) +{ + return nl_socket_get_fd(sys->route_event_sock); +} + +static int iccp_get_receive_arp_packet_sock_fd(struct System *sys) +{ + return sys->arp_receive_fd; +} + +static int iccp_get_receive_ndisc_packet_sock_fd(struct System *sys) +{ + return sys->ndisc_receive_fd; +} + +static int iccp_receive_arp_packet_handler(struct System *sys) +{ + unsigned char buf[1024]; + struct sockaddr_ll sll; + socklen_t sll_len = sizeof(sll); + struct arphdr *a = (struct arphdr*)buf; + int n; + unsigned int ifindex; + unsigned int addr; + uint8_t mac_addr[ETHER_ADDR_LEN]; + + n = recvfrom(sys->arp_receive_fd, buf, sizeof(buf), MSG_DONTWAIT, + (struct sockaddr*)&sll, &sll_len); + if (n < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "ARP recvfrom error: %s", buf); + return MCLAG_ERROR; + } + + /* Sanity checks */ + /*Only process ARPOP_REPLY*/ + if (n < sizeof(*a) || + a->ar_op != htons(ARPOP_REPLY) || + a->ar_pln != 4 || + a->ar_pro != htons(ETH_P_IP) || + a->ar_hln != sll.sll_halen || + sizeof(*a) + 2 * 4 + 2 * a->ar_hln > n) + return 0; + + ifindex = sll.sll_ifindex; + memcpy(mac_addr, (char*)(a + 1), ETHER_ADDR_LEN); + memcpy(&addr, (char*)(a + 1) + a->ar_hln, 4); + + do_arp_update_from_reply_packet(ifindex, addr, mac_addr); + + return 0; +} + +int iccp_receive_ndisc_packet_handler(struct System *sys) +{ + uint8_t buf[4096]; + uint8_t adata[1024]; + struct sockaddr_in6 from; + unsigned int ifindex = 0; + struct msghdr msg; + struct iovec iov; + struct cmsghdr *cmsgptr; + struct nd_msg *ndmsg = NULL; + struct nd_opt_hdr *nd_opt = NULL; + struct in6_addr target; + uint8_t mac_addr[ETHER_ADDR_LEN]; + int8_t *opt = NULL; + int opt_len = 0, l = 0; + int len; + + memset(mac_addr, 0, ETHER_ADDR_LEN); + + /* Fill in message and iovec. */ + msg.msg_name = (void *)(&from); + msg.msg_namelen = sizeof(struct sockaddr_in6); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = (void *)adata; + msg.msg_controllen = sizeof adata; + iov.iov_base = buf; + iov.iov_len = 4096; + + len = recvmsg(sys->ndisc_receive_fd, &msg, 0); + + if (len < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "Ndisc recvmsg error!"); + return MCLAG_ERROR; + } + + if (msg.msg_controllen >= sizeof(struct cmsghdr)) + for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) + { + /* I want interface index which this packet comes from. */ + if (cmsgptr->cmsg_level == IPPROTO_IPV6 && cmsgptr->cmsg_type == IPV6_PKTINFO) + { + struct in6_pktinfo *ptr; + + ptr = (struct in6_pktinfo *)CMSG_DATA(cmsgptr); + ifindex = ptr->ipi6_ifindex; + } + } + + ndmsg = (struct nd_msg *)buf; + + if (ndmsg->icmph.icmp6_type != NDISC_NEIGHBOUR_ADVERTISEMENT) + return 0; + + memcpy((char *)(&target), (char *)(&ndmsg->target), sizeof(struct in6_addr)); + + opt = (char *)ndmsg->opt; + + opt_len = len - sizeof(struct nd_msg); + + if (opt && opt_len > 0) + { + while (opt_len) + { + if (opt_len < sizeof(struct nd_opt_hdr)) + return 0; + + nd_opt = (struct nd_opt_hdr *)opt; + + l = nd_opt->nd_opt_len << 3; + + if (l == 0) + return 0; + + if (nd_opt->nd_opt_type == ND_OPT_TARGET_LL_ADDR) + { + memcpy(mac_addr, (char *)((char *)nd_opt + sizeof(struct nd_opt_hdr)), ETHER_ADDR_LEN); + break; + } + + opt += l; + opt_len -= l; + } + } + + /* ICCPD_LOG_DEBUG(__FUNCTION__, "Recv na pkt(%s,%02X:%02X:%02X:%02X:%02X:%02X)!", show_ipv6_str((char *)&target), mac_addr[0], mac_addr[1], + mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); */ + do_ndisc_update_from_reply_packet(ifindex, (char *)&target, mac_addr); + + return 0; +} + +void iccp_netlink_sync_again() +{ + struct System* sys = NULL; + struct LocalInterface* lif = NULL; + + if ((sys = system_get_instance()) == NULL ) + return; + + if (sys->need_sync_netlink_again) + { + sys->need_sync_netlink_again = 0; + + /*Get kernel interface and port */ + iccp_sys_local_if_list_get_init(); + } + + if (sys->need_sync_team_again) + { + sys->need_sync_team_again = 0; + + LIST_FOREACH(lif, &(sys->lif_list), system_next) + { + if (lif->type == IF_T_PORT_CHANNEL) + { + iccp_get_port_member_list(lif); + } + } + } + + return; +} + +static int iccp_netlink_route_sock_event_handler(struct System *sys) +{ + int ret = 0; + + ret = nl_recvmsgs_default(sys->route_event_sock); + + if (ret) + { + sys->need_sync_netlink_again = 1; + ICCPD_LOG_DEBUG(__FUNCTION__, "fd %d recvmsg error ret = %d errno = %d ", nl_socket_get_fd(sys->route_event_sock), ret, errno); + } + /*get netlink info again when error happens */ + if (ret == 0 && sys->need_sync_netlink_again == 1) + { + iccp_netlink_sync_again(); + } + + return ret; +} + +extern int iccp_get_receive_fdb_sock_fd(struct System *sys); +extern int iccp_receive_fdb_handler_from_syncd(struct System *sys); + +/* cond HIDDEN_SYMBOLS */ +struct iccp_eventfd +{ + int (*get_fd)(struct System* sys); + int (*event_handler)(struct System* sys); +}; +/* endcond */ + +static const struct iccp_eventfd iccp_eventfds[] = { + { + .get_fd = iccp_get_server_sock_fd, + .event_handler = scheduler_server_accept, + }, + { + .get_fd = iccp_get_netlink_genic_sock_event_fd, + .event_handler = iccp_netlink_genic_sock_event_handler, + }, + { + .get_fd = iccp_get_netlink_route_sock_event_fd, + .event_handler = iccp_netlink_route_sock_event_handler, + }, + { + .get_fd = iccp_get_receive_arp_packet_sock_fd, + .event_handler = iccp_receive_arp_packet_handler, + }, + { + .get_fd = iccp_get_receive_ndisc_packet_sock_fd, + .event_handler = iccp_receive_ndisc_packet_handler, + } +}; + +/* \cond HIDDEN_SYMBOLS */ +#define ICCP_EVENT_FDS_COUNT ARRAY_SIZE(iccp_eventfds) +/* \endcond */ +/* + @return fd. + * + **/ + +int iccp_get_eventfd_fd(struct System *sys) +{ + return sys->epoll_fd; +} + +int iccp_init_netlink_event_fd(struct System *sys) +{ + int efd; + int i; + struct epoll_event event; + int err; + + efd = epoll_create1(0); + if (efd == -1) + return -errno; + + for (i = 0; i < ICCP_EVENT_FDS_COUNT; i++) + { + int fd = iccp_eventfds[i].get_fd(sys); + + event.data.fd = fd; + event.events = EPOLLIN; + err = epoll_ctl(efd, EPOLL_CTL_ADD, fd, &event); + if (err == -1) + { + err = -errno; + goto close_efd; + } + } + + sys->epoll_fd = efd; + + return 0; + + close_efd: + close(efd); + + return err; +} + +/** + * + * @details Handler events which happened on event filedescriptor. + * + * @return Zero on success or negative number in case of an error. + **/ + +int iccp_handle_events(struct System * sys) +{ + struct epoll_event events[ICCP_EVENT_FDS_COUNT + sys->readfd_count]; + struct CSM* csm = NULL; + int nfds; + int n; + int i; + int err; + int max_nfds; + + max_nfds = ICCP_EVENT_FDS_COUNT + sys->readfd_count; + + nfds = epoll_wait(sys->epoll_fd, events, max_nfds, EPOLL_TIMEOUT_MSEC); + + /* Go over list of event fds and handle them sequentially */ + for (i = 0; i < nfds; i++) + { + for (n = 0; n < ICCP_EVENT_FDS_COUNT; n++) + { + const struct iccp_eventfd *eventfd = &iccp_eventfds[n]; + if (events[i].data.fd == eventfd->get_fd(sys)) + { + err = eventfd->event_handler(sys); + if (err) + ICCPD_LOG_INFO(__FUNCTION__, "Scheduler fd %d handler error %d !", events[i].data.fd, err ); + break; + } + } + + if (n < ICCP_EVENT_FDS_COUNT) + continue; + + if (events[i].data.fd == sys->sync_ctrl_fd) + { + int client_fd = mclagd_ctl_sock_accept(sys->sync_ctrl_fd); + if (client_fd > 0) + { + mclagd_ctl_interactive_process(client_fd); + close(client_fd); + } + continue; + } + + if (events[i].data.fd == sys->sync_fd) + { + iccp_receive_fdb_handler_from_syncd(sys); + + continue; + } + + if (events[i].data.fd == sys->sig_pipe_r) + { + iccp_receive_signal_handler(sys); + + continue; + } + + if (FD_ISSET(events[i].data.fd, &sys->readfd)) + { + LIST_FOREACH(csm, &(sys->csm_list), next) + { + if (csm->sock_fd == events[i].data.fd ) + { + scheduler_csm_read_callback(csm); + break; + } + } + } + } + + return 0; +} + diff --git a/src/iccpd/src/logger.c b/src/iccpd/src/logger.c new file mode 100644 index 000000000000..2c17610f7afc --- /dev/null +++ b/src/iccpd/src/logger.c @@ -0,0 +1,140 @@ +/* + * logger.c + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ +#include +#include +#include +#include + +#include "../include/cmd_option.h" +#include "../include/logger.h" + +static uint32_t _iccpd_log_level_map[] = +{ + LOG_CRIT, + LOG_ERR, + LOG_WARNING, + LOG_NOTICE, + LOG_INFO, + LOG_DEBUG, +}; + +char* log_level_to_string(int level) +{ + switch (level) + { + case CRITICAL_LOG_LEVEL: + return "CRITICAL"; + + case ERR_LOG_LEVEL: + return "ERROR"; + + case WARN_LOG_LEVEL: + return "WARN"; + + case NOTICE_LOG_LEVEL: + return "NOTICE"; + + case INFO_LOG_LEVEL: + return "INFO"; + + case DEBUG_LOG_LEVEL: + return "DEBUG"; + } + + return "INFO"; +} + +struct LoggerConfig* logger_get_configuration() +{ + static struct LoggerConfig config; + + if (config.init == 0) + { + config.console_log_enabled = 0; + config.log_level = NOTICE_LOG_LEVEL; + config.init = 1; + } + + return &config; +} + +void logger_set_configuration(int log_level) +{ + struct LoggerConfig* config = logger_get_configuration(); + + config->log_level = log_level; + config->init = 1; + + return; +} + +void log_init(struct CmdOptionParser* parser) +{ + struct LoggerConfig* config = logger_get_configuration(); + + config->console_log_enabled = parser->console_log; +} + +void log_finalize() +{ + /*do nothing*/ +} + +void write_log(const int level, const char* tag, const char* format, ...) +{ + struct LoggerConfig* config = logger_get_configuration(); + char buf[LOGBUF_SIZE]; + va_list args; + unsigned int prefix_len; + unsigned int avbl_buf_len; + unsigned int print_len; + +#if 0 + if (!config->console_log_enabled) + return; +#endif + + if (level > config->log_level) + return; + + prefix_len = snprintf(buf, LOGBUF_SIZE, "[%s.%s] ", tag, log_level_to_string(level)); + avbl_buf_len = LOGBUF_SIZE - prefix_len; + + va_start(args, format); + print_len = vsnprintf(buf + prefix_len, avbl_buf_len, format, args); + va_end(args); + + /* Since osal_vsnprintf doesn't always return the exact size written to the buffer, + * we must check if the user string length exceeds the remaing buffer size. + */ + if (print_len > avbl_buf_len) + { + print_len = avbl_buf_len; + } + + buf[prefix_len + print_len] = '\0'; + ICCPD_UTILS_SYSLOG(_iccpd_log_level_map[level], "%s", buf); + + return; +} + diff --git a/src/iccpd/src/mclagdctl/Makefile.am b/src/iccpd/src/mclagdctl/Makefile.am new file mode 100644 index 000000000000..124129c5d18e --- /dev/null +++ b/src/iccpd/src/mclagdctl/Makefile.am @@ -0,0 +1,10 @@ +bin_PROGRAMS = mclagdctl + +if DEBUG +DBGFLAGS = -ggdb -DDEBUG +else +DBGFLAGS = -g -DNDEBUG +endif + +mclagdctl_SOURCES = mclagdctl.c +mclagdctl_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) diff --git a/src/iccpd/src/mclagdctl/mclagdctl.c b/src/iccpd/src/mclagdctl/mclagdctl.c new file mode 100644 index 000000000000..630e333be6ed --- /dev/null +++ b/src/iccpd/src/mclagdctl/mclagdctl.c @@ -0,0 +1,943 @@ +/* + * Copyright(c) 2016-2019 Nephos. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: Jim Jiang from nephos + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mclagdctl.h" + +static int mclagdctl_sock_fd = -1; +char *mclagdctl_sock_path = "/var/run/iccpd/mclagdctl.sock"; + +/* + Already implemented command: + mclagdctl -i dump state + mclagdctl -i dump arp + mclagdctl -i dump mac + mclagdctl -i dump portlist local + mclagdctl -i dump portlist peer + */ + +static struct command_type command_types[] = +{ + { + .id = ID_CMDTYPE_D, + .name = "dump", + .enca_msg = NULL, + .parse_msg = NULL, + }, + { + .id = ID_CMDTYPE_D_S, + .parent_id = ID_CMDTYPE_D, + .info_type = INFO_TYPE_DUMP_STATE, + .name = "state", + .enca_msg = mclagdctl_enca_dump_state, + .parse_msg = mclagdctl_parse_dump_state, + }, + { + .id = ID_CMDTYPE_D_A, + .parent_id = ID_CMDTYPE_D, + .info_type = INFO_TYPE_DUMP_ARP, + .name = "arp", + .enca_msg = mclagdctl_enca_dump_arp, + .parse_msg = mclagdctl_parse_dump_arp, + }, + { + .id = ID_CMDTYPE_D_A, + .parent_id = ID_CMDTYPE_D, + .info_type = INFO_TYPE_DUMP_NDISC, + .name = "nd", + .enca_msg = mclagdctl_enca_dump_ndisc, + .parse_msg = mclagdctl_parse_dump_ndisc, + }, + { + .id = ID_CMDTYPE_D_A, + .parent_id = ID_CMDTYPE_D, + .info_type = INFO_TYPE_DUMP_MAC, + .name = "mac", + .enca_msg = mclagdctl_enca_dump_mac, + .parse_msg = mclagdctl_parse_dump_mac, + }, + { + .id = ID_CMDTYPE_D_P, + .parent_id = ID_CMDTYPE_D, + .name = "portlist", + }, + { + .id = ID_CMDTYPE_D_P_L, + .parent_id = ID_CMDTYPE_D_P, + .info_type = INFO_TYPE_DUMP_LOCAL_PORTLIST, + .name = "local", + .enca_msg = mclagdctl_enca_dump_local_portlist, + .parse_msg = mclagdctl_parse_dump_local_portlist, + }, + { + .id = ID_CMDTYPE_D_P_P, + .parent_id = ID_CMDTYPE_D_P, + .info_type = INFO_TYPE_DUMP_PEER_PORTLIST, + .name = "peer", + .enca_msg = mclagdctl_enca_dump_peer_portlist, + .parse_msg = mclagdctl_parse_dump_peer_portlist, + }, + { + .id = ID_CMDTYPE_C, + .name = "config", + .enca_msg = NULL, + .parse_msg = NULL, + }, + { + .id = ID_CMDTYPE_C_L, + .parent_id = ID_CMDTYPE_C, + .info_type = INFO_TYPE_CONFIG_LOGLEVEL, + .name = "loglevel", + .enca_msg = mclagdctl_enca_config_loglevel, + .parse_msg = mclagdctl_parse_config_loglevel, + }, +}; + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#define COMMAND_TYPE_COUNT ARRAY_SIZE(command_types) + +int mclagdctl_sock_connect() +{ + struct sockaddr_un addr; + int addrlen = 0; + int ret = 0; + + if (mclagdctl_sock_fd >= 0) + return 0; + + if (strlen(mclagdctl_sock_path) <= 0) + return MCLAG_ERROR; + + mclagdctl_sock_fd = socket(AF_UNIX, SOCK_STREAM, 0); + + if (mclagdctl_sock_fd < 0) + { + return MCLAG_ERROR; + } + + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + snprintf(addr.sun_path, sizeof(addr.sun_path) - 1, "%s", mclagdctl_sock_path); + addrlen = sizeof(addr.sun_family) + strlen(mclagdctl_sock_path); + + if ((ret = connect(mclagdctl_sock_fd, (struct sockaddr*)&addr, addrlen)) < 0) + { + close(mclagdctl_sock_fd); + mclagdctl_sock_fd = -1; + return MCLAG_ERROR; + } + + return 0; +} + +void mclagdctl_sock_close() +{ + if (mclagdctl_sock_fd > 0) + { + close(mclagdctl_sock_fd); + mclagdctl_sock_fd = -1; + } + + return; +} + +int mclagdctl_sock_write(int fd, unsigned char *w_buf, int total_len) +{ + int write_len = 0; + int ret = 0; + + while (write_len < total_len) + { + ret = write(fd, w_buf + write_len, total_len - write_len); + if (ret <= 0) + { + return 0; + } + write_len += ret; + } + + return write_len; +} + +int mclagdctl_sock_read(int fd, unsigned char *r_buf, int total_len) +{ + int read_len = 0; + int ret = 0; + struct timeval tv = { 0 }; + fd_set read_fd; + + while (read_len < total_len) + { + FD_ZERO(&read_fd); + FD_SET(fd, &read_fd); + tv.tv_sec = 10; + tv.tv_usec = 0; + + switch ((ret = select(fd + 1, &read_fd, NULL, NULL, &tv))) + { + case -1: // error + fprintf(stdout, "Mclagdctl:Select return error:%s\n", strerror(errno)); + return MCLAG_ERROR; + + case 0: // timeout + fprintf(stdout, "Mclagdctl:Select timeout:%s\n", strerror(errno)); + return MCLAG_ERROR; + + default: + break; + } + + ret = read(fd, r_buf + read_len, total_len - read_len); + if (ret <= 0) + { + return MCLAG_ERROR; + } + read_len += ret; + } + + return read_len; +} + +int mclagdctl_enca_dump_state(char *msg, int mclag_id, int argc, char **argv) +{ + struct mclagdctl_req_hdr req; + + memset(&req, 0, sizeof(struct mclagdctl_req_hdr)); + req.info_type = INFO_TYPE_DUMP_STATE; + req.mclag_id = mclag_id; + memcpy((struct mclagdctl_req_hdr *)msg, &req, sizeof(struct mclagdctl_req_hdr)); + + return 1; +} + +int mclagdctl_parse_dump_state(char *msg, int data_len) +{ + struct mclagd_state * state_info = NULL; + int len = 0; + int count = 0; + int pos = 0; + + len = sizeof(struct mclagd_state); + + for (; data_len >= len; data_len -= len, count++) + { + state_info = (struct mclagd_state*)(msg + len * count); + + fprintf(stdout, "%s: %s\n", "The MCLAG's keepalive is", state_info->keepalive ? "OK" : "ERROR"); + + if (state_info->mclag_id <= 0) + fprintf(stdout, "%s: %s\n", "Domain id", "Unknown"); + else + fprintf(stdout, "%s: %d\n", "Domain id", state_info->mclag_id); + + fprintf(stdout, "%s: %s\n", "Local Ip", state_info->local_ip); + fprintf(stdout, "%s: %s\n", "Peer Ip", state_info->peer_ip); + fprintf(stdout, "%s: %s\n", "Peer Link Interface", state_info->peer_link_if); + + fprintf(stdout, "%s: %02x:%02x:%02x:%02x:%02x:%02x \n", + "Peer Link Mac", + state_info->peer_link_mac[0], state_info->peer_link_mac[1], + state_info->peer_link_mac[2], state_info->peer_link_mac[3], + state_info->peer_link_mac[4], state_info->peer_link_mac[5]); + + if (state_info->role == 0) + fprintf(stdout, "%s: %s\n", "Role", "None"); + else if (state_info->role == 1) + fprintf(stdout, "%s: %s\n", "Role", "Active"); + else if (state_info->role == 2) + fprintf(stdout, "%s: %s\n", "Role", "Standby"); + + fprintf(stdout, "%s: %s\n", "MCLAG Interface", state_info->enabled_po); + + fprintf(stdout, "%s: %s\n", "Loglevel", state_info->loglevel); + } + + return 0; +} + +int mclagdctl_enca_dump_arp(char *msg, int mclag_id, int argc, char **argv) +{ + struct mclagdctl_req_hdr req; + + if (mclag_id <= 0) + { + fprintf(stderr, "Need to specify mclag-id through the parameter i !\n"); + return MCLAG_ERROR; + } + + memset(&req, 0, sizeof(struct mclagdctl_req_hdr)); + req.info_type = INFO_TYPE_DUMP_ARP; + req.mclag_id = mclag_id; + memcpy((struct mclagdctl_req_hdr *)msg, &req, sizeof(struct mclagdctl_req_hdr)); + + return 1; +} + +int mclagdctl_enca_dump_ndisc(char *msg, int mclag_id, int argc, char **argv) +{ + struct mclagdctl_req_hdr req; + + if (mclag_id <= 0) + { + fprintf(stderr, "Need to specify mclag-id through the parameter i !\n"); + return MCLAG_ERROR; + } + + memset(&req, 0, sizeof(struct mclagdctl_req_hdr)); + req.info_type = INFO_TYPE_DUMP_NDISC; + req.mclag_id = mclag_id; + memcpy((struct mclagdctl_req_hdr *)msg, &req, sizeof(struct mclagdctl_req_hdr)); + + return 1; +} + +int mclagdctl_parse_dump_arp(char *msg, int data_len) +{ + struct mclagd_arp_msg * arp_info = NULL; + int len = 0; + int count = 0; + + fprintf(stdout, "%-6s", "No."); + fprintf(stdout, "%-20s", "IP"); + fprintf(stdout, "%-20s", "MAC"); + fprintf(stdout, "%-20s", "DEV"); + fprintf(stdout, "\n"); + + len = sizeof(struct mclagd_arp_msg); + + for (; data_len >= len; data_len -= len, count++) + { + arp_info = (struct mclagd_arp_msg*)(msg + len * count); + + fprintf(stdout, "%-6d", count + 1); + fprintf(stdout, "%-20s", arp_info->ipv4_addr); + fprintf(stdout, "%02x:%02x:%02x:%02x:%02x:%02x", + arp_info->mac_addr[0], arp_info->mac_addr[1], + arp_info->mac_addr[2], arp_info->mac_addr[3], + arp_info->mac_addr[4], arp_info->mac_addr[5]); + fprintf(stdout, " "); + fprintf(stdout, "%-20s", arp_info->ifname); + fprintf(stdout, "\n"); + } + + return 0; +} + +int mclagdctl_parse_dump_ndisc(char *msg, int data_len) +{ + struct mclagd_ndisc_msg *ndisc_info = NULL; + int len = 0; + int count = 0; + + fprintf(stdout, "%-6s", "No."); + fprintf(stdout, "%-52s", "IPv6"); + fprintf(stdout, "%-20s", "MAC"); + fprintf(stdout, "%-20s", "DEV"); + fprintf(stdout, "\n"); + + len = sizeof(struct mclagd_ndisc_msg); + + for (; data_len >= len; data_len -= len, count++) + { + ndisc_info = (struct mclagd_ndisc_msg *)(msg + len * count); + + fprintf(stdout, "%-6d", count + 1); + fprintf(stdout, "%-52s", ndisc_info->ipv6_addr); + fprintf(stdout, "%02x:%02x:%02x:%02x:%02x:%02x", + ndisc_info->mac_addr[0], ndisc_info->mac_addr[1], + ndisc_info->mac_addr[2], ndisc_info->mac_addr[3], + ndisc_info->mac_addr[4], ndisc_info->mac_addr[5]); + fprintf(stdout, " "); + fprintf(stdout, "%-20s", ndisc_info->ifname); + fprintf(stdout, "\n"); + } + + return 0; +} + +int mclagdctl_enca_dump_mac(char *msg, int mclag_id, int argc, char **argv) +{ + struct mclagdctl_req_hdr req; + + if (mclag_id <= 0) + { + fprintf(stderr, "Need to specify mclag-id through the parameter i !\n"); + return MCLAG_ERROR; + } + + memset(&req, 0, sizeof(struct mclagdctl_req_hdr)); + req.info_type = INFO_TYPE_DUMP_MAC; + req.mclag_id = mclag_id; + memcpy((struct mclagdctl_req_hdr *)msg, &req, sizeof(struct mclagdctl_req_hdr)); + + return 1; +} + +int mclagdctl_parse_dump_mac(char *msg, int data_len) +{ + struct mclagd_mac_msg * mac_info = NULL; + int len = 0; + int count = 0; + + fprintf(stdout, "%-60s\n", "TYPE: S-STATIC, D-DYNAMIC; AGE: L-Local age, P-Peer age"); + + fprintf(stdout, "%-6s", "No."); + fprintf(stdout, "%-5s", "TYPE"); + fprintf(stdout, "%-20s", "MAC"); + fprintf(stdout, "%-5s", "VID"); + fprintf(stdout, "%-20s", "DEV"); + fprintf(stdout, "%-20s", "ORIGIN-DEV"); + fprintf(stdout, "%-5s", "AGE"); + fprintf(stdout, "\n"); + + len = sizeof(struct mclagd_mac_msg); + + for (; data_len >= len; data_len -= len, count++) + { + mac_info = (struct mclagd_mac_msg*)(msg + len * count); + + fprintf(stdout, "%-6d", count + 1); + + if (mac_info->fdb_type == MAC_TYPE_STATIC_CTL) + fprintf(stdout, "%-5s", "S"); + else + fprintf(stdout, "%-5s", "D"); + + fprintf(stdout, "%-20s", mac_info->mac_str); + fprintf(stdout, "%-5d", mac_info->vid); + fprintf(stdout, "%-20s", mac_info->ifname); + fprintf(stdout, "%-20s", mac_info->origin_ifname); + + if ((mac_info->age_flag & MAC_AGE_LOCAL_CTL) && (mac_info->age_flag & MAC_AGE_PEER_CTL)) + fprintf(stdout, "%-5s", "LP"); + else if (mac_info->age_flag & MAC_AGE_LOCAL_CTL) + fprintf(stdout, "%-5s", "L"); + else if (mac_info->age_flag & MAC_AGE_PEER_CTL) + fprintf(stdout, "%-5s", "P"); + else + fprintf(stdout, "%-5s", " "); + fprintf(stdout, "\n"); + } + + return 0; +} + +int mclagdctl_enca_dump_local_portlist(char *msg, int mclag_id, int argc, char **argv) +{ + struct mclagdctl_req_hdr req; + + if (mclag_id <= 0) + { + fprintf(stderr, "Need to specify mclag-id through the parameter i !\n"); + return MCLAG_ERROR; + } + + memset(&req, 0, sizeof(struct mclagdctl_req_hdr)); + req.info_type = INFO_TYPE_DUMP_LOCAL_PORTLIST; + req.mclag_id = mclag_id; + memcpy((struct mclagdctl_req_hdr *)msg, &req, sizeof(struct mclagdctl_req_hdr)); + + return 1; +} + +int mclagdctl_parse_dump_local_portlist(char *msg, int data_len) +{ + struct mclagd_local_if * lif_info = NULL; + int len = 0; + int count = 0; + int pos = 0; + + len = sizeof(struct mclagd_local_if); + + for (; data_len >= len; data_len -= len, count++) + { + lif_info = (struct mclagd_local_if*)(msg + len * count); + + for (pos = 0; pos < 60; ++pos) + fprintf(stdout, "-"); + + fprintf(stdout, "\n"); + + if (memcmp(lif_info->type, "PortChannel", 11) == 0) + { + fprintf(stdout, "%s: %d\n", "Ifindex", lif_info->ifindex); + fprintf(stdout, "%s: %s\n", "Type", lif_info->type); + fprintf(stdout, "%s: %s\n", "PortName", lif_info->name); + fprintf(stdout, "%s: %02x:%02x:%02x:%02x:%02x:%02x \n", + "MAC", + lif_info->mac_addr[0], lif_info->mac_addr[1], + lif_info->mac_addr[2], lif_info->mac_addr[3], + lif_info->mac_addr[4], lif_info->mac_addr[5]); + + fprintf(stdout, "%s: %s\n", "IPv4Address", lif_info->ipv4_addr); + fprintf(stdout, "%s: %d\n", "Prefixlen", lif_info->prefixlen); + fprintf(stdout, "%s: %s\n", "State", lif_info->state); + fprintf(stdout, "%s: %s\n", "IsL3Interface", lif_info->l3_mode ? "Yes" : "No"); + /*fprintf(stdout, "%s: %s\n", "IsPeerlink", lif_info->is_peer_link ? "Yes" : "No");*/ + fprintf(stdout, "%s: %s\n", "MemberPorts", lif_info->portchannel_member_buf); + /*fprintf(stdout,"%s: %d\n" ,"PortchannelId", lif_info->po_id); + fprintf(stdout,"%s: %d\n" ,"PortchannelIsUp", lif_info->po_active); + fprintf(stdout,"%s: %s\n", "MlacpState", lif_info->mlacp_state);*/ + fprintf(stdout, "%s: %s\n", "IsIsolateWithPeerlink", lif_info->isolate_to_peer_link ? "Yes" : "No"); + fprintf(stdout, "%s: %s\n", "VlanList", lif_info->vlanlist); + } + else + { + fprintf(stdout, "%s: %d\n", "Ifindex", lif_info->ifindex); + fprintf(stdout, "%s: %s\n", "Type", lif_info->type); + fprintf(stdout, "%s: %s\n", "PortName", lif_info->name); + fprintf(stdout, "%s: %s\n", "State", lif_info->state); + /*fprintf(stdout,"%s: %d\n" ,"PortchannelId", lif_info->po_id);*/ + } + + for (pos = 0; pos < 60; ++pos) + fprintf(stdout, "-"); + + fprintf(stdout, "\n\n"); + } + + return 0; +} + +int mclagdctl_enca_dump_peer_portlist(char *msg, int mclag_id, int argc, char **argv) +{ + struct mclagdctl_req_hdr req; + + if (mclag_id <= 0) + { + fprintf(stderr, "Need to specify mclag-id through the parameter i !\n"); + return MCLAG_ERROR; + } + + memset(&req, 0, sizeof(struct mclagdctl_req_hdr)); + req.info_type = INFO_TYPE_DUMP_PEER_PORTLIST; + req.mclag_id = mclag_id; + memcpy((struct mclagdctl_req_hdr *)msg, &req, sizeof(struct mclagdctl_req_hdr)); + + return 1; +} + +int mclagdctl_parse_dump_peer_portlist(char *msg, int data_len) +{ + struct mclagd_peer_if * pif_info = NULL; + int len = 0; + int count = 0; + int pos = 0; + + len = sizeof(struct mclagd_peer_if); + + for (; data_len >= len; data_len -= len, count++) + { + pif_info = (struct mclagd_peer_if*)(msg + len * count); + + for (pos = 0; pos < 60; ++pos) + fprintf(stdout, "-"); + + fprintf(stdout, "\n"); + + fprintf(stdout, "%s: %d\n", "Ifindex", pif_info->ifindex); + fprintf(stdout, "%s: %s\n", "Type", pif_info->type); + fprintf(stdout, "%s: %s\n", "PortName", pif_info->name); + fprintf(stdout, "%s: %02x:%02x:%02x:%02x:%02x:%02x \n", + "MAC", + pif_info->mac_addr[0], pif_info->mac_addr[1], + pif_info->mac_addr[2], pif_info->mac_addr[3], + pif_info->mac_addr[4], pif_info->mac_addr[5]); + + fprintf(stdout, "%s: %s\n", "State", pif_info->state); + /*fprintf(stdout,"%s: %d\n" ,"PortchannelId", pif_info->po_id); + fprintf(stdout,"%s: %d\n" ,"PortchannelIsActive", pif_info->po_active);*/ + + for (pos = 0; pos < 60; ++pos) + fprintf(stdout, "-"); + + fprintf(stdout, "\n\n"); + } + + return 0; +} + +int mclagdctl_enca_config_loglevel(char *msg, int log_level, int argc, char **argv) +{ + struct mclagdctl_req_hdr req; + + memset(&req, 0, sizeof(struct mclagdctl_req_hdr)); + req.info_type = INFO_TYPE_CONFIG_LOGLEVEL; + req.mclag_id = log_level; + memcpy((struct mclagdctl_req_hdr *)msg, &req, sizeof(struct mclagdctl_req_hdr)); + + return 1; +} + +int mclagdctl_parse_config_loglevel(char *msg, int data_len) +{ + + int ret = *(int*)msg; + + if (ret == 0) + fprintf(stdout, "%s\n", "Config loglevel success!"); + else + fprintf(stdout, "%s\n", "Config loglevel failed!"); + + return 0; +} + +static bool __mclagdctl_cmd_executable(struct command_type *cmd_type) +{ + if (!cmd_type->enca_msg || !cmd_type->parse_msg) + return 0; + + return 1; +} + +static int __mclagdctl_cmd_param_cnt(struct command_type *cmd_type) +{ + int i = 0; + + while (cmd_type->params[i]) + i++; + + return i; +} + +static struct command_type *__mclagdctl_get_cmd_by_parent(char *cmd_name, + enum id_command_type parent_id) +{ + int i; + + for (i = 0; i < COMMAND_TYPE_COUNT; i++) + { + if (!strncmp(command_types[i].name, cmd_name, strlen(cmd_name)) + && command_types[i].parent_id == parent_id) + return &command_types[i]; + } + + return NULL; +} + +static struct command_type *__mclagdctl_get_cmd_by_id(enum id_command_type id) +{ + int i; + + for (i = 0; i < COMMAND_TYPE_COUNT; i++) + { + if (command_types[i].id == id) + return &command_types[i]; + } + + return NULL; +} + +static int mclagdctl_find_cmd(struct command_type **pcmd_type, int *argc, char ***argv) +{ + char *cmd_name; + enum id_command_type parent_id = ID_CMDTYPE_NONE; + struct command_type *cmd_type; + + while (1) + { + if (!*argc) + { + fprintf(stderr, "None or incomplete command\n"); + return -EINVAL; + } + + cmd_name = *argv[0]; + (*argc)--; + (*argv)++; + cmd_type = __mclagdctl_get_cmd_by_parent(cmd_name, parent_id); + + if (!cmd_type) + { + fprintf(stderr, "Unknown command \"%s\".\n", cmd_name); + return -EINVAL; + } + + if (__mclagdctl_cmd_executable(cmd_type) && __mclagdctl_cmd_param_cnt(cmd_type) >= *argc) + { + *pcmd_type = cmd_type; + return 0; + } + + parent_id = cmd_type->id; + } +} + +static int mclagdctl_check_cmd_params(struct command_type *cmd_type, + int argc, char **argv) +{ + int i = 0; + + while (cmd_type->params[i]) + { + if (i == argc) + { + fprintf(stderr, "Command line parameter \"%s\" expected.\n", cmd_type->params[i]); + return -EINVAL; + } + i++; + } + + return 0; +} + +static void mclagdctl_print_cmd(struct command_type *cmd_type) +{ + if (cmd_type->parent_id != ID_CMDTYPE_NONE) + { + mclagdctl_print_cmd(__mclagdctl_get_cmd_by_id(cmd_type->parent_id)); + fprintf(stdout, " "); + } + fprintf(stdout, "%s", cmd_type->name); +} + +static void mclagdctl_print_help(const char *argv0) +{ + int i, j; + struct command_type *cmd_type; + + fprintf(stdout, "%s [options] command [command args]\n" + " -h --help Show this help\n" + " -i --mclag-id Specify one mclag id\n" + " -l --level Specify log level critical,err,warn,notice,info,debug\n", + argv0); + fprintf(stdout, "Commands:\n"); + + for (i = 0; i < COMMAND_TYPE_COUNT; i++) + { + cmd_type = &command_types[i]; + if (!__mclagdctl_cmd_executable(cmd_type)) + continue; + fprintf(stdout, " "); + mclagdctl_print_cmd(cmd_type); + + for (j = 0; cmd_type->params[j]; j++) + fprintf(stdout, " %s", cmd_type->params[j]); + + fprintf(stdout, "\n"); + } +} + +int main(int argc, char **argv) +{ + char buf[MCLAGDCTL_CMD_SIZE] = { 0 }; + char *argv0 = argv[0]; + char *rcv_buf = NULL; + static const struct option long_options[] = + { + { "help", no_argument, NULL, 'h' }, + { "mclag id", required_argument, NULL, 'i' }, + { "log level", required_argument, NULL, 'l' }, + { NULL, 0, NULL, 0 } + }; + int opt; + int err; + struct command_type *cmd_type; + int ret; + unsigned para_int = 0; + + int len = 0; + char *data; + struct mclagd_reply_hdr *reply; + + while ((opt = getopt_long(argc, argv, "hi:l:", long_options, NULL)) >= 0) + { + switch (opt) + { + case 'h': + mclagdctl_print_help(argv0); + return EXIT_SUCCESS; + + case 'i': + para_int = atoi(optarg); + break; + + case 'l': + switch (tolower(optarg[0])) + { + case 'c': + para_int = CRITICAL; + break; + + case 'e': + para_int = ERR; + break; + + case 'w': + para_int = WARN; + break; + + case 'n': + para_int = NOTICE; + break; + + case 'i': + para_int = INFO; + break; + + case 'd': + para_int = DEBUG; + break; + + default: + fprintf(stderr, "unknown option \"%c\".\n", opt); + mclagdctl_print_help(argv0); + return EXIT_FAILURE; + } + break; + + case '?': + fprintf(stderr, "unknown option.\n"); + mclagdctl_print_help(argv0); + return EXIT_FAILURE; + + default: + fprintf(stderr, "unknown option \"%c\".\n", opt); + mclagdctl_print_help(argv0); + return EXIT_FAILURE; + } + } + + argv += optind; + argc -= optind; + + err = mclagdctl_find_cmd(&cmd_type, &argc, &argv); + if (err) + { + mclagdctl_print_help(argv0); + return EXIT_FAILURE; + } + + err = mclagdctl_check_cmd_params(cmd_type, argc, argv); + if (err) + { + mclagdctl_print_help(argv0); + return EXIT_FAILURE; + } + + if (mclagdctl_sock_fd <= 0) + { + ret = mclagdctl_sock_connect(); + if (ret < 0) + return EXIT_FAILURE; + } + + if (cmd_type->enca_msg(buf, para_int, argc, argv) < 0) + { + ret = EXIT_FAILURE; + goto mclagdctl_disconnect; + } + + ret = mclagdctl_sock_write(mclagdctl_sock_fd, buf, sizeof(struct mclagdctl_req_hdr)); + + if (ret <= 0) + { + fprintf(stderr, "Failed to send command to mclagd\n"); + ret = EXIT_FAILURE; + goto mclagdctl_disconnect; + } + + /*read data length*/ + memset(buf, 0, MCLAGDCTL_CMD_SIZE); + ret = mclagdctl_sock_read(mclagdctl_sock_fd, buf, sizeof(int)); + if (ret <= 0) + { + fprintf(stderr, "Failed to read data length from mclagd\n"); + ret = EXIT_FAILURE; + goto mclagdctl_disconnect; + } + + /*cont length*/ + len = *((int*)buf); + if (len <= 0) + { + ret = EXIT_FAILURE; + fprintf(stderr, "pkt len = %d, error\n", len); + goto mclagdctl_disconnect; + } + + rcv_buf = (char *)malloc(len); + if (!rcv_buf) + { + fprintf(stderr, "Failed to malloc rcv_buf for mclagdctl\n"); + goto mclagdctl_disconnect; + } + + /*read data*/ + ret = mclagdctl_sock_read(mclagdctl_sock_fd, rcv_buf, len); + if (ret <= 0) + { + fprintf(stderr, "Failed to read data from mclagd\n"); + ret = EXIT_FAILURE; + goto mclagdctl_disconnect; + } + + reply = (struct mclagd_reply_hdr *)rcv_buf; + if (reply->info_type != cmd_type->info_type) + { + fprintf(stderr, "Reply info type from mclagd error\n"); + ret = EXIT_FAILURE; + goto mclagdctl_disconnect; + } + + if (reply->exec_result == EXEC_TYPE_NO_EXIST_SYS) + { + fprintf(stderr, "No exist sys in iccpd!\n"); + ret = EXIT_FAILURE; + goto mclagdctl_disconnect; + } + + if (reply->exec_result == EXEC_TYPE_NO_EXIST_MCLAGID) + { + fprintf(stderr, "Mclag-id %d hasn't been configured in iccpd!\n", para_int); + ret = EXIT_FAILURE; + goto mclagdctl_disconnect; + } + + if (reply->exec_result == EXEC_TYPE_FAILED) + { + fprintf(stderr, "exec error in iccpd!\n"); + ret = EXIT_FAILURE; + goto mclagdctl_disconnect; + } + + cmd_type->parse_msg((char *)(rcv_buf + sizeof(struct mclagd_reply_hdr)), len - sizeof(struct mclagd_reply_hdr)); + + ret = EXIT_SUCCESS; + + mclagdctl_disconnect: + mclagdctl_sock_close(); + + if (rcv_buf) + free(rcv_buf); + + return ret; +} + diff --git a/src/iccpd/src/mclagdctl/mclagdctl.h b/src/iccpd/src/mclagdctl/mclagdctl.h new file mode 100644 index 000000000000..91155ecb7321 --- /dev/null +++ b/src/iccpd/src/mclagdctl/mclagdctl.h @@ -0,0 +1,210 @@ +/* Copyright(c) 2016-2019 Nephos. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: Jim Jiang from nephos + */ + +#define MCLAGDCTL_PARA1_LEN 16 +#define MCLAGDCTL_PARA2_LEN 32 +#define MCLAGDCTL_PARA3_LEN 64 +#define MCLAGDCTL_CMD_SIZE 4096 + +#define MCLAGDCTL_MAX_L_PORT_NANE 32 +#define MCLAGDCTL_INET_ADDR_LEN 32 +#define MCLAGDCTL_INET6_ADDR_LEN 64 +#define MCLAGDCTL_ETHER_ADDR_LEN 6 +#define MCLAGDCTL_PORT_MEMBER_BUF_LEN 512 +#define ETHER_ADDR_STR_LEN 18 + +typedef int (*call_enca_msg_fun)(char *msg, int mclag_id, int argc, char **argv); +typedef int (*call_parse_msg_fun)(char *msg, int data_len); + +enum MAC_TYPE_CTL +{ + MAC_TYPE_STATIC_CTL = 1, + MAC_TYPE_DYNAMIC_CTL = 2, +}; + +enum MAC_AGE_TYPE_CTL +{ + MAC_AGE_LOCAL_CTL = 1, /*MAC in local switch is ageout*/ + MAC_AGE_PEER_CTL = 2 /*MAC in peer switch is ageout*/ +}; + +enum id_command_type +{ + ID_CMDTYPE_NONE = 0, + ID_CMDTYPE_D, + ID_CMDTYPE_D_S, + ID_CMDTYPE_D_A, + ID_CMDTYPE_D_P, + ID_CMDTYPE_D_P_L, + ID_CMDTYPE_D_P_P, + ID_CMDTYPE_C, + ID_CMDTYPE_C_L, +}; + +enum mclagdctl_notify_peer_type +{ + INFO_TYPE_NONE = 0, + INFO_TYPE_DUMP_STATE, + INFO_TYPE_DUMP_ARP, + INFO_TYPE_DUMP_NDISC, + INFO_TYPE_DUMP_MAC, + INFO_TYPE_DUMP_LOCAL_PORTLIST, + INFO_TYPE_DUMP_PEER_PORTLIST, + INFO_TYPE_CONFIG_LOGLEVEL, + INFO_TYPE_FINISH, +}; + +enum log_level_type +{ + CRITICAL = 0, + ERR= 1, + WARN = 2, + NOTICE= 3, + INFO = 4, + DEBUG = 5 +}; + +struct mclagdctl_req_hdr +{ + int info_type; + int mclag_id; + char para1[MCLAGDCTL_PARA2_LEN]; + char para2[MCLAGDCTL_PARA2_LEN]; + char para3[MCLAGDCTL_PARA2_LEN]; +}; + +struct mclagd_reply_hdr +{ + int info_type; + int data_len; + int exec_result; +}; + +#define EXEC_TYPE_SUCCESS -1 +#define EXEC_TYPE_NO_EXIST_SYS -2 +#define EXEC_TYPE_NO_EXIST_MCLAGID -3 +#define EXEC_TYPE_FAILED -4 + +#define MCLAG_ERROR -1 + +#define MCLAGD_REPLY_INFO_HDR (sizeof(struct mclagd_reply_hdr) + sizeof(int)) + +#define MCLAGDCTL_COMMAND_PARAM_MAX_CNT 8 +struct command_type +{ + enum id_command_type id; + enum id_command_type parent_id; + enum mclagdctl_notify_peer_type info_type; + char *name; + char *params[MCLAGDCTL_COMMAND_PARAM_MAX_CNT]; + call_enca_msg_fun enca_msg; + call_parse_msg_fun parse_msg; +}; + +struct mclagd_state +{ + int mclag_id; + int keepalive; + char local_ip[MCLAGDCTL_INET_ADDR_LEN]; + char peer_ip[MCLAGDCTL_INET_ADDR_LEN]; + char peer_link_if[MCLAGDCTL_MAX_L_PORT_NANE]; + unsigned char peer_link_mac[MCLAGDCTL_ETHER_ADDR_LEN]; + int role; + char enabled_po[MCLAGDCTL_PORT_MEMBER_BUF_LEN]; + char loglevel[MCLAGDCTL_PARA1_LEN]; +}; + +struct mclagd_arp_msg +{ + char op_type; + char ifname[MCLAGDCTL_MAX_L_PORT_NANE]; + char ipv4_addr[MCLAGDCTL_INET_ADDR_LEN]; + unsigned char mac_addr[MCLAGDCTL_ETHER_ADDR_LEN]; +}; + +struct mclagd_ndisc_msg +{ + char op_type; + char ifname[MCLAGDCTL_MAX_L_PORT_NANE]; + char ipv6_addr[MCLAGDCTL_INET6_ADDR_LEN]; + unsigned char mac_addr[MCLAGDCTL_ETHER_ADDR_LEN]; +}; + +struct mclagd_mac_msg +{ + unsigned char op_type;/*add or del*/ + unsigned char fdb_type;/*static or dynamic*/ + char mac_str[ETHER_ADDR_STR_LEN]; + unsigned short vid; + /*Current if name that set in chip*/ + char ifname[MCLAGDCTL_MAX_L_PORT_NANE]; + /*if we set the mac to peer-link, origin_ifname store the + original if name that learned from chip*/ + char origin_ifname[MCLAGDCTL_MAX_L_PORT_NANE]; + unsigned char age_flag;/*local or peer is age?*/ +}; + +struct mclagd_local_if +{ + int ifindex; + char type[MCLAGDCTL_PARA1_LEN]; + char name[MCLAGDCTL_MAX_L_PORT_NANE]; + unsigned char mac_addr[MCLAGDCTL_ETHER_ADDR_LEN]; + char state[MCLAGDCTL_PARA1_LEN]; + char ipv4_addr[MCLAGDCTL_INET_ADDR_LEN]; + unsigned char prefixlen; + + unsigned char l3_mode; + unsigned char is_peer_link; + char portchannel_member_buf[MCLAGDCTL_PORT_MEMBER_BUF_LEN]; + int po_id; /* Port Channel ID */ + unsigned char po_active; + char mlacp_state[MCLAGDCTL_PARA1_LEN]; + unsigned char isolate_to_peer_link; + + char vlanlist[MCLAGDCTL_PARA3_LEN]; +}; + +struct mclagd_peer_if +{ + int ifindex; + unsigned char type[MCLAGDCTL_PARA1_LEN]; + char name[MCLAGDCTL_MAX_L_PORT_NANE]; + unsigned char mac_addr[MCLAGDCTL_ETHER_ADDR_LEN]; + unsigned char state[MCLAGDCTL_PARA1_LEN]; + int po_id; + unsigned char po_active; +}; + +extern int mclagdctl_enca_dump_state(char *msg, int mclag_id, int argc, char **argv); +extern int mclagdctl_parse_dump_state(char *msg, int data_len); +extern int mclagdctl_enca_dump_arp(char *msg, int mclag_id, int argc, char **argv); +extern int mclagdctl_enca_dump_ndisc(char *msg, int mclag_id, int argc, char **argv); +extern int mclagdctl_parse_dump_arp(char *msg, int data_len); +extern int mclagdctl_parse_dump_ndisc(char *msg, int data_len); +extern int mclagdctl_enca_dump_mac(char *msg, int mclag_id, int argc, char **argv); +extern int mclagdctl_parse_dump_mac(char *msg, int data_len); +extern int mclagdctl_enca_dump_local_portlist(char *msg, int mclag_id, int argc, char **argv); +extern int mclagdctl_parse_dump_local_portlist(char *msg, int data_len); +extern int mclagdctl_enca_dump_peer_portlist(char *msg, int mclag_id, int argc, char **argv); +extern int mclagdctl_parse_dump_peer_portlist(char *msg, int data_len); +int mclagdctl_enca_config_loglevel(char *msg, int log_level, int argc, char **argv); +int mclagdctl_parse_config_loglevel(char *msg, int data_len); + diff --git a/src/iccpd/src/mlacp_fsm.c b/src/iccpd/src/mlacp_fsm.c new file mode 100644 index 000000000000..c56eb9051736 --- /dev/null +++ b/src/iccpd/src/mlacp_fsm.c @@ -0,0 +1,1293 @@ +/* + * mlacp_fsm.c + * mLACP finite state machine handler. + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include "../include/mlacp_tlv.h" +#include "../include/mlacp_sync_prepare.h" +#include "../include/mlacp_link_handler.h" +#include "../include/mlacp_sync_update.h" + +#include + +/***************************************** +* Define +* +* ***************************************/ +#define MLACP_MSG_QUEUE_REINIT(list) \ + { \ + struct Msg* msg = NULL; \ + while (!TAILQ_EMPTY(&(list))) { \ + msg = TAILQ_FIRST(&(list)); \ + TAILQ_REMOVE(&(list), msg, tail); \ + free(msg->buf); \ + free(msg); \ + } \ + TAILQ_INIT(&(list)); \ + } + +#define PIF_QUEUE_REINIT(list) \ + { \ + while (!LIST_EMPTY(&(list))) { \ + struct PeerInterface* peer_if = NULL; \ + peer_if = LIST_FIRST(&(list)); \ + LIST_REMOVE(peer_if, mlacp_next); \ + free(peer_if); \ + } \ + LIST_INIT(&(list)); \ + } + +#define LIF_QUEUE_REINIT(list) \ + { \ + while (!LIST_EMPTY(&(list))) { \ + struct LocalInterface* lif = NULL; \ + lif = LIST_FIRST(&(list)); \ + if (lif->type == IF_T_PORT_CHANNEL && lif->is_arp_accept) { \ + if ((set_sys_arp_accept_flag(lif->name, 0)) == 0) \ + lif->is_arp_accept = 0; \ + } \ + LIST_REMOVE (lif, mlacp_next); \ + } \ + LIST_INIT(&(list)); \ + } + +#define LIF_PURGE_QUEUE_REINIT(list) \ + { \ + while (!LIST_EMPTY(&(list))) { \ + struct LocalInterface* lif = NULL; \ + lif = LIST_FIRST(&(list)); \ + LIST_REMOVE(lif, mlacp_purge_next); \ + } \ + LIST_INIT(&(list)); \ + } + +#define WARM_REBOOT_TIMEOUT 90 + +/***************************************** +* Static Function +* +* ***************************************/ +static char *mlacp_state(struct CSM* csm); +static void mlacp_resync_arp(struct CSM* csm); +static void mlacp_resync_ndisc(struct CSM* csm); +static void mlacp_resync_mac(struct CSM* csm); +/* Sync Sender APIs*/ +static void mlacp_sync_send_sysConf(struct CSM* csm); +static void mlacp_sync_send_aggConf(struct CSM* csm); +static void mlacp_sync_send_aggState(struct CSM* csm); +static void mlacp_sync_send_syncArpInfo(struct CSM* csm); +static void mlacp_sync_send_syncNdiscInfo(struct CSM* csm); +static void mlacp_sync_send_heartbeat(struct CSM* csm); +static void mlacp_sync_send_syncDoneData(struct CSM* csm); +/* Sync Reciever APIs*/ +static void mlacp_sync_recv_sysConf(struct CSM* csm, struct Msg* msg); +static void mlacp_sync_recv_portConf(struct CSM* csm, struct Msg* msg); +static void mlacp_sync_recv_portPrio(struct CSM* csm, struct Msg* msg); +static void mlacp_sync_recv_portState(struct CSM* csm, struct Msg* msg); +static void mlacp_sync_recv_aggConf(struct CSM* csm, struct Msg* msg); +static void mlacp_sync_recv_aggState(struct CSM* csm, struct Msg* msg); +static void mlacp_sync_recv_syncData(struct CSM* csm, struct Msg* msg); +static void mlacp_sync_recv_syncReq(struct CSM* csm, struct Msg* msg); +static void mlacp_sync_recv_portChanInfo(struct CSM* csm, struct Msg* msg); +static void mlacp_sync_recv_peerLlinkInfo(struct CSM* csm, struct Msg* msg); +static void mlacp_sync_recv_arpInfo(struct CSM* csm, struct Msg* msg); +static void mlacp_sync_recv_stpInfo(struct CSM* csm, struct Msg* msg); + +/* Sync Handler*/ +static void mlacp_sync_send_nak_handler(struct CSM* csm, struct Msg* msg); +static void mlacp_sync_recv_nak_handler(struct CSM* csm, struct Msg* msg); +static void mlacp_sync_sender_handler(struct CSM* csm); +static void mlacp_sync_receiver_handler(struct CSM* csm, struct Msg* msg); +static void mlacp_sync_send_all_info_handler(struct CSM* csm); + +/* Sync State Handler*/ +static void mlacp_stage_sync_send_handler(struct CSM* csm, struct Msg* msg); +static void mlacp_stage_sync_request_handler(struct CSM* csm, struct Msg* msg); +static void mlacp_stage_handler(struct CSM* csm, struct Msg* msg); +static void mlacp_exchange_handler(struct CSM* csm, struct Msg* msg); + +/****************************************************************** + * Sync Sender APIs + * + *****************************************************************/ +static void mlacp_sync_send_sysConf(struct CSM* csm) +{ + int msg_len = 0; + + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + msg_len = mlacp_prepare_for_sys_config(csm, g_csm_buf, CSM_BUFFER_SIZE); + if (msg_len > 0) + iccp_csm_send(csm, g_csm_buf, msg_len); + else + ICCPD_LOG_WARN(__FUNCTION__, "Invalid sysconf packet."); + + /*ICCPD_LOG_DEBUG("mlacp_fsm", " [SYNC_Send] SysConf, len=[%d]", msg_len);*/ + + return; +} + +static void mlacp_sync_send_aggConf(struct CSM* csm) +{ + struct System* sys = NULL; + int msg_len = 0; + struct LocalInterface* local_if = NULL; + + if ((sys = system_get_instance()) == NULL) + return; + + LIST_FOREACH(local_if, &(MLACP(csm).lif_list), mlacp_next) + { + if (local_if->type == IF_T_PORT_CHANNEL) + { + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + msg_len = mlacp_prepare_for_Aggport_config(csm, g_csm_buf, CSM_BUFFER_SIZE, local_if, 0); + iccp_csm_send(csm, g_csm_buf, msg_len); + local_if->port_config_sync = 0; + /*ICCPD_LOG_DEBUG("mlacp_fsm", " [SYNC_Send] PortChannel, csm-if-name=[%s], len=[%d]", local_if->name, msg_len);*/ + } + } + + return; +} + +static void mlacp_sync_send_aggState(struct CSM* csm) +{ + struct System* sys = NULL; + int msg_len = 0; + struct LocalInterface* local_if = NULL; + + if ((sys = system_get_instance()) == NULL) + return; + + LIST_FOREACH(local_if, &(MLACP(csm).lif_list), mlacp_next) + { + if (local_if->type == IF_T_PORT_CHANNEL) + { + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + msg_len = mlacp_prepare_for_Aggport_state(csm, g_csm_buf, CSM_BUFFER_SIZE, local_if); + iccp_csm_send(csm, g_csm_buf, msg_len); + local_if->changed = 0; + /*ICCPD_LOG_DEBUG("mlacp_fsm", " [SYNC_Send] PortChannel, csm-if-name=[%s], len=[%d]", local_if->name, msg_len);*/ + } + } + + return; +} +#define MAX_MAC_ENTRY_NUM 30 +#define MAX_NEIGH_ENTRY_NUM 40 +static void mlacp_sync_send_syncMacInfo(struct CSM* csm) +{ + int msg_len = 0; + struct Msg* msg = NULL; + int count = 0; + + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + + while (!TAILQ_EMPTY(&(MLACP(csm).mac_msg_list))) + { + msg = TAILQ_FIRST(&(MLACP(csm).mac_msg_list)); + TAILQ_REMOVE(&(MLACP(csm).mac_msg_list), msg, tail); + msg_len = mlacp_prepare_for_mac_info_to_peer(csm, g_csm_buf, CSM_BUFFER_SIZE, (struct MACMsg*)msg->buf, count); + count++; + free(msg->buf); + free(msg); + if (count >= MAX_MAC_ENTRY_NUM) + { + iccp_csm_send(csm, g_csm_buf, msg_len); + count = 0; + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + } + /*ICCPD_LOG_DEBUG("mlacp_fsm", " [SYNC_Send] MacInfo,len=[%d]", msg_len);*/ + } + + if (count) + iccp_csm_send(csm, g_csm_buf, msg_len); + + return; +} + +static void mlacp_sync_send_syncArpInfo(struct CSM* csm) +{ + int msg_len = 0; + struct Msg* msg = NULL; + int count = 0; + + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + + while (!TAILQ_EMPTY(&(MLACP(csm).arp_msg_list))) + { + msg = TAILQ_FIRST(&(MLACP(csm).arp_msg_list)); + TAILQ_REMOVE(&(MLACP(csm).arp_msg_list), msg, tail); + + msg_len = mlacp_prepare_for_arp_info(csm, g_csm_buf, CSM_BUFFER_SIZE, (struct ARPMsg*)msg->buf, count); + count++; + free(msg->buf); + free(msg); + if (count >= MAX_NEIGH_ENTRY_NUM) + { + iccp_csm_send(csm, g_csm_buf, msg_len); + count = 0; + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + } + /*ICCPD_LOG_DEBUG("mlacp_fsm", " [SYNC_Send] ArpInfo,len=[%d]", msg_len);*/ + } + + if (count) + iccp_csm_send(csm, g_csm_buf, msg_len); + + return; +} + +static void mlacp_sync_send_syncNdiscInfo(struct CSM *csm) +{ + int msg_len = 0; + struct Msg *msg = NULL; + int count = 0; + + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + + while (!TAILQ_EMPTY(&(MLACP(csm).ndisc_msg_list))) + { + msg = TAILQ_FIRST(&(MLACP(csm).ndisc_msg_list)); + TAILQ_REMOVE(&(MLACP(csm).ndisc_msg_list), msg, tail); + + msg_len = mlacp_prepare_for_ndisc_info(csm, g_csm_buf, CSM_BUFFER_SIZE, (struct NDISCMsg *)msg->buf, count); + count++; + free(msg->buf); + free(msg); + if (count >= MAX_NEIGH_ENTRY_NUM) + { + iccp_csm_send(csm, g_csm_buf, msg_len); + count = 0; + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + } + /* ICCPD_LOG_DEBUG("mlacp_fsm", " [SYNC_Send] NDInfo,len=[%d]", msg_len); */ + } + + if (count) + iccp_csm_send(csm, g_csm_buf, msg_len); + + return; +} +static void mlacp_sync_send_syncPortChannelInfo(struct CSM* csm) +{ + struct System* sys = NULL; + int msg_len = 0; + struct LocalInterface* local_if = NULL; + + if ((sys = system_get_instance()) == NULL) + return; + + LIST_FOREACH(local_if, &(MLACP(csm).lif_list), mlacp_next) + { + if (local_if->type == IF_T_PORT_CHANNEL) + { + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + msg_len = mlacp_prepare_for_port_channel_info(csm, g_csm_buf, CSM_BUFFER_SIZE, local_if); + iccp_csm_send(csm, g_csm_buf, msg_len); + local_if->changed = 0; + /*ICCPD_LOG_DEBUG("mlacp_fsm", " [SYNC_Send] PortChannel, csm-if-name=[%s], len=[%d]", local_if->name, msg_len);*/ + } + } + + return; +} + +static void mlacp_sync_send_syncPeerLinkInfo(struct CSM* csm) +{ + struct System* sys = NULL; + int msg_len = 0; + + if ((sys = system_get_instance()) == NULL) + return; + + if (csm->peer_link_if) + { + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + msg_len = mlacp_prepare_for_port_peerlink_info(csm, g_csm_buf, CSM_BUFFER_SIZE, csm->peer_link_if); + iccp_csm_send(csm, g_csm_buf, msg_len); + } + + return; +} + +static void mlacp_sync_send_heartbeat(struct CSM* csm) +{ + int msg_len = 0; + + if ((csm->heartbeat_send_time == 0) || + ((time(NULL) - csm->heartbeat_send_time) > 1)) + { + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + msg_len = mlacp_prepare_for_heartbeat(csm, g_csm_buf, CSM_BUFFER_SIZE); + iccp_csm_send(csm, g_csm_buf, msg_len); + time(&csm->heartbeat_send_time); + } + + return; +} + +static void mlacp_sync_send_syncDoneData(struct CSM* csm) +{ + int msg_len = 0; + + /*Sync done & go to next stage*/ + MLACP(csm).wait_for_sync_data = 0; + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + msg_len = mlacp_prepare_for_sync_data_tlv(csm, g_csm_buf, CSM_BUFFER_SIZE, 1); + iccp_csm_send(csm, g_csm_buf, msg_len); + /*ICCPD_LOG_DEBUG("mlacp_fsm", " [SYNC_Send] SyncDone, len=[%d]", msg_len);*/ + + return; +} + +/****************************************************************** + * Sync Receiver APIs + * + *****************************************************************/ +static void mlacp_sync_recv_sysConf(struct CSM* csm, struct Msg* msg) +{ + mLACPSysConfigTLV* sysconf = NULL; + + sysconf = (mLACPSysConfigTLV*)&(msg->buf[sizeof(ICCHdr)]); + + if (mlacp_fsm_update_system_conf(csm, sysconf) == MCLAG_ERROR) + { + /*NOTE: we just change the node ID local side without sending NAK msg*/ + ICCPD_LOG_WARN(__FUNCTION__, "Same Node ID = %d, send NAK", MLACP(csm).remote_system.node_id); + mlacp_sync_send_nak_handler(csm, msg); + } + + return; +} + +static void mlacp_sync_recv_portConf(struct CSM* csm, struct Msg* msg) +{ + /*Don't support currently*/ + return; +} + +static void mlacp_sync_recv_portPrio(struct CSM* csm, struct Msg* msg) +{ + /*Don't support currently*/ + return; +} + +static void mlacp_sync_recv_portState(struct CSM* csm, struct Msg* msg) +{ + /*Don't support currently*/ + return; +} + +static void mlacp_sync_recv_aggConf(struct CSM* csm, struct Msg* msg) +{ + mLACPAggConfigTLV* portconf = NULL; + + portconf = (mLACPAggConfigTLV*)&(msg->buf[sizeof(ICCHdr)]); + if (mlacp_fsm_update_Agg_conf(csm, portconf) == MCLAG_ERROR) + { + mlacp_sync_send_nak_handler(csm, msg); + } + + return; +} + +static void mlacp_sync_recv_aggState(struct CSM* csm, struct Msg* msg) +{ + mLACPAggPortStateTLV* portstate = NULL; + + portstate = (mLACPAggPortStateTLV*)&(msg->buf[sizeof(ICCHdr)]); + if (mlacp_fsm_update_Aggport_state(csm, portstate) == MCLAG_ERROR) + { + mlacp_sync_send_nak_handler(csm, msg); + /*MLACP(csm).error_msg = "Receive a port state update on an non-existed port. It is suggest to check the environment and re-initialize mLACP again.";*/ + return; + } + + return; +} + +static void mlacp_sync_recv_syncData(struct CSM* csm, struct Msg* msg) +{ + mLACPSyncDataTLV* syncdata = NULL; + + syncdata = (mLACPSyncDataTLV*)&(msg->buf[sizeof(ICCHdr)]); + if (ntohs(syncdata->flags) == 1) + { + /* Sync done*/ + MLACP(csm).wait_for_sync_data = 0; + } + + return; +} + +static void mlacp_sync_recv_syncReq(struct CSM* csm, struct Msg* msg) +{ + mLACPSyncReqTLV* mlacp_sync_req = NULL; + + mlacp_sync_req = (mLACPSyncReqTLV*)&msg->buf[sizeof(ICCHdr)]; + MLACP(csm).sync_req_num = ntohs(mlacp_sync_req->req_num); + + /* Reply the peer all sync info*/ + mlacp_sync_send_all_info_handler(csm); + + return; +} + +static void mlacp_sync_recv_portChanInfo(struct CSM* csm, struct Msg* msg) +{ + mLACPPortChannelInfoTLV* portconf = NULL; + + portconf = (mLACPPortChannelInfoTLV*)&(msg->buf[sizeof(ICCHdr)]); + if (mlacp_fsm_update_port_channel_info(csm, portconf) == MCLAG_ERROR) + { + mlacp_sync_send_nak_handler(csm, msg); + } + + return; +} + +static void mlacp_sync_recv_peerLlinkInfo(struct CSM* csm, struct Msg* msg) +{ + mLACPPeerLinkInfoTLV* peerlink = NULL; + + peerlink = (mLACPPeerLinkInfoTLV*)&(msg->buf[sizeof(ICCHdr)]); + mlacp_fsm_update_peerlink_info( csm, peerlink); + + return; +} + +static void mlacp_sync_recv_macInfo(struct CSM* csm, struct Msg* msg) +{ + struct mLACPMACInfoTLV* mac_info = NULL; + + mac_info = (struct mLACPMACInfoTLV *)&(msg->buf[sizeof(ICCHdr)]); + mlacp_fsm_update_mac_info_from_peer(csm, mac_info); + + return; +} + +static void mlacp_sync_recv_arpInfo(struct CSM* csm, struct Msg* msg) +{ + struct mLACPARPInfoTLV* arp_info = NULL; + + arp_info = (struct mLACPARPInfoTLV *)&(msg->buf[sizeof(ICCHdr)]); + mlacp_fsm_update_arp_info(csm, arp_info); + + return; +} + +static void mlacp_sync_recv_ndiscInfo(struct CSM *csm, struct Msg *msg) +{ + struct mLACPNDISCInfoTLV *ndisc_info = NULL; + + ndisc_info = (struct mLACPNDISCInfoTLV *)&(msg->buf[sizeof(ICCHdr)]); + mlacp_fsm_update_ndisc_info(csm, ndisc_info); + + return; +} +static void mlacp_sync_recv_stpInfo(struct CSM* csm, struct Msg* msg) +{ + /*Don't support currently*/ + return; +} + +static void mlacp_sync_recv_heartbeat(struct CSM* csm, struct Msg* msg) +{ + struct mLACPHeartbeatTLV *tlv = NULL; + + tlv = (struct mLACPHeartbeatTLV *)(&msg->buf[sizeof(ICCHdr)]); + mlacp_fsm_update_heartbeat(csm, tlv); + + return; +} + +static void mlacp_sync_recv_warmboot(struct CSM* csm, struct Msg* msg) +{ + struct mLACPWarmbootTLV *tlv = NULL; + + tlv = (struct mLACPWarmbootTLV *)(&msg->buf[sizeof(ICCHdr)]); + mlacp_fsm_update_warmboot(csm, tlv); + + return; +} + +/***************************************** +* MLACP Init +* +* ***************************************/ +void mlacp_init(struct CSM* csm, int all) +{ + if (csm == NULL) + return; + + MLACP(csm).sync_req_num = -1; + MLACP(csm).need_to_sync = 0; + MLACP(csm).error_msg = NULL; + + MLACP(csm).current_state = MLACP_STATE_INIT; + memset(MLACP(csm).remote_system.system_id, 0, ETHER_ADDR_LEN); + + MLACP_MSG_QUEUE_REINIT(MLACP(csm).mlacp_msg_list); + MLACP_MSG_QUEUE_REINIT(MLACP(csm).arp_msg_list); + MLACP_MSG_QUEUE_REINIT(MLACP(csm).ndisc_msg_list); + MLACP_MSG_QUEUE_REINIT(MLACP(csm).mac_msg_list); + PIF_QUEUE_REINIT(MLACP(csm).pif_list); + LIF_PURGE_QUEUE_REINIT(MLACP(csm).lif_purge_list); + + if (all != 0) + { + /* if no clean all, keep the arp info & local interface info for next connection*/ + MLACP_MSG_QUEUE_REINIT(MLACP(csm).arp_list); + MLACP_MSG_QUEUE_REINIT(MLACP(csm).ndisc_list); + MLACP_MSG_QUEUE_REINIT(MLACP(csm).mac_list); + LIF_QUEUE_REINIT(MLACP(csm).lif_list); + + MLACP(csm).node_id = MLACP_SYSCONF_NODEID_MSB_MASK; + MLACP(csm).node_id |= (((inet_addr(csm->sender_ip) >> 24) << 4) & MLACP_SYSCONF_NODEID_NODEID_MASK); + MLACP(csm).node_id |= rand() % MLACP_SYSCONF_NODEID_FREE_MASK; + } + + return; +} + +/***************************************** +* MLACP finalize +* +* ***************************************/ +void mlacp_finalize(struct CSM* csm) +{ + if (csm == NULL) + return; + + /* msg destroy*/ + MLACP_MSG_QUEUE_REINIT(MLACP(csm).mlacp_msg_list); + MLACP_MSG_QUEUE_REINIT(MLACP(csm).arp_msg_list); + MLACP_MSG_QUEUE_REINIT(MLACP(csm).ndisc_msg_list); + MLACP_MSG_QUEUE_REINIT(MLACP(csm).mac_msg_list); + MLACP_MSG_QUEUE_REINIT(MLACP(csm).arp_list); + MLACP_MSG_QUEUE_REINIT(MLACP(csm).ndisc_list); + MLACP_MSG_QUEUE_REINIT(MLACP(csm).mac_list); + + /* remove lif & lif-purge queue */ + LIF_QUEUE_REINIT(MLACP(csm).lif_list); + LIF_PURGE_QUEUE_REINIT(MLACP(csm).lif_purge_list); + /* remove & destroy pif queue */ + PIF_QUEUE_REINIT(MLACP(csm).pif_list); + + return; +} + +/***************************************** +* MLACP FSM Transit +* +* ***************************************/ +void mlacp_fsm_transit(struct CSM* csm) +{ + struct System* sys = NULL; + struct Msg* msg = NULL; + static MLACP_APP_STATE_E prev_state = MLACP_SYNC_SYSCONF; + ICCHdr* icc_hdr = NULL; + ICCParameter* icc_param = NULL; + int have_msg = 1; + + if (csm == NULL) + return; + if ((sys = system_get_instance()) == NULL) + return; + + /* torn down event */ + if (csm->sock_fd <= 0 || csm->app_csm.current_state != APP_OPERATIONAL) + { + /* drop all legacy mlacp msg*/ + if (MLACP(csm).current_state != MLACP_STATE_INIT) + { + MLACP_MSG_QUEUE_REINIT(MLACP(csm).mlacp_msg_list); + MLACP_MSG_QUEUE_REINIT(MLACP(csm).arp_msg_list); + MLACP_MSG_QUEUE_REINIT(MLACP(csm).ndisc_msg_list); + MLACP_MSG_QUEUE_REINIT(MLACP(csm).mac_msg_list); + MLACP(csm).current_state = MLACP_STATE_INIT; + } + return; + } + + if (csm->warm_reboot_disconn_time != 0) + { + /*After peer warm reboot and disconnect, if peer connection is not establised more than 90s, + recover peer disconnection to normal process, such as add peer age flag for MACs etc*/ + if ((time(NULL) - csm->warm_reboot_disconn_time) >= WARM_REBOOT_TIMEOUT) + { + csm->warm_reboot_disconn_time = 0; + ICCPD_LOG_NOTICE(__FUNCTION__, "Peer warm reboot, reconnection timeout, recover to normal reboot!"); + mlacp_peer_disconn_handler(csm); + } + } + + mlacp_sync_send_heartbeat(csm); + + /* Dequeue msg if any*/ + while (have_msg) + { + if (MLACP(csm).current_state != MLACP_STATE_INIT) + { + /* Handler NAK First*/ + msg = mlacp_dequeue_msg(csm); + if (msg != NULL) + { + have_msg = 1; + icc_hdr = (ICCHdr*)msg->buf; + icc_param = (ICCParameter*)&msg->buf[sizeof(ICCHdr)]; + /*ICCPD_LOG_DEBUG("mlacp_fsm", " SYNC: Message Type = %X, TLV=%s, Len=%d", icc_hdr->ldp_hdr.msg_type, get_tlv_type_string(icc_param->type), msg->len);*/ + + if (icc_hdr->ldp_hdr.msg_type == MSG_T_NOTIFICATION && icc_param->type == TLV_T_NAK) + { + mlacp_sync_recv_nak_handler(csm, msg); + free(msg->buf); + free(msg); + continue; + } + } + else + { + have_msg = 0; + } + } + + if (prev_state != MLACP(csm).current_state) + { + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + mlacp_peer_conn_handler(csm); + prev_state = MLACP(csm).current_state; + } + + /* Sync State */ + if (MLACP(csm).current_state == MLACP_STATE_INIT) + { + MLACP(csm).wait_for_sync_data = 0; + MLACP(csm).current_state = MLACP_STATE_STAGE1; + mlacp_resync_arp(csm); + mlacp_resync_ndisc(csm); + } + + switch (MLACP(csm).current_state) + { + case MLACP_STATE_INIT: + case MLACP_STATE_ERROR: + /* should not be here*/ + break; + + case MLACP_STATE_STAGE1: + case MLACP_STATE_STAGE2: + mlacp_stage_handler(csm, msg); + break; + + case MLACP_STATE_EXCHANGE: + mlacp_exchange_handler(csm, msg); + break; + } + + /*ICCPD_LOG_DEBUG("mlacp_fsm", " Next State = %s", mlacp_state(csm));*/ + if (msg) + { + free(msg->buf); + free(msg); + } + } +} + +/* Helper function for dumping application state machine */ +static char* mlacp_state(struct CSM* csm) +{ + if (csm == NULL ) + return "MLACP_NULL"; + + switch (MLACP(csm).current_state) + { + case MLACP_STATE_INIT: + return "MLACP_STATE_INIT"; + + case MLACP_STATE_STAGE1: + return "MLACP_STATE_STAGE1"; + + case MLACP_STATE_STAGE2: + return "MLACP_STATE_STAGE2"; + + case MLACP_STATE_EXCHANGE: + return "MLACP_STATE_EXCHANGE"; + + case MLACP_STATE_ERROR: + return "MLACP_STATE_ERROR"; + } + + return "MLACP_UNKNOWN"; +} + +/* Add received message into message list */ +void mlacp_enqueue_msg(struct CSM* csm, struct Msg* msg) +{ + if (csm == NULL ) + { + if (msg != NULL ) + free(msg); + return; + } + + if (msg == NULL ) + return; + + #if 0 + icc_hdr = (ICCHdr*)msg->buf; + icc_param = (ICCParameter*)&msg->buf[sizeof(ICCHdr)]; + ICCPD_LOG_DEBUG("mlacp_fsm", " mLACP enqueue: tlv = 0x%04x", icc_param->type); + #endif + + TAILQ_INSERT_TAIL(&(MLACP(csm).mlacp_msg_list), msg, tail); + + return; +} + +/* Get received message from message list */ +struct Msg* mlacp_dequeue_msg(struct CSM* csm) +{ + struct Msg* msg = NULL; + + if (!TAILQ_EMPTY(&(MLACP(csm).mlacp_msg_list))) + { + msg = TAILQ_FIRST(&(MLACP(csm).mlacp_msg_list)); + TAILQ_REMOVE(&(MLACP(csm).mlacp_msg_list), msg, tail); + } + + return msg; +} + +/****************************************** +* When peerlink ready, prepare the MACMsg +* +******************************************/ +static void mlacp_resync_mac(struct CSM* csm) +{ + struct Msg* msg = NULL; + struct MACMsg* mac_msg = NULL; + struct Msg *msg_send = NULL; + + /* recover MAC info sync from peer*/ + if (!TAILQ_EMPTY(&(MLACP(csm).mac_list))) + { + TAILQ_FOREACH(msg, &MLACP(csm).mac_list, tail) + { + mac_msg = (struct MACMsg*)msg->buf; + mac_msg->op_type = MAC_SYNC_ADD; + if (iccp_csm_init_msg(&msg_send, (char*)mac_msg, sizeof(struct MACMsg)) == 0) + { + mac_msg->age_flag &= ~MAC_AGE_PEER; + TAILQ_INSERT_TAIL(&(MLACP(csm).mac_msg_list), msg_send, tail); + ICCPD_LOG_DEBUG(__FUNCTION__, "MAC-msg-list enqueue: %s, add %s vlan-id %d, age_flag %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->age_flag); + } + } + } +} + +/****************************************** +* When peerlink ready, prepare the ARPMsg +* +******************************************/ +static void mlacp_resync_arp(struct CSM* csm) +{ + struct Msg* msg = NULL; + struct ARPMsg* arp_msg = NULL; + struct Msg *msg_send = NULL; + + /* recover ARP info sync from peer*/ + if (!TAILQ_EMPTY(&(MLACP(csm).arp_list))) + { + TAILQ_FOREACH(msg, &MLACP(csm).arp_list, tail) + { + arp_msg = (struct ARPMsg*)msg->buf; + arp_msg->op_type = NEIGH_SYNC_ADD; + if (iccp_csm_init_msg(&msg_send, (char*)arp_msg, sizeof(struct ARPMsg)) == 0) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).arp_msg_list), msg_send, tail); + } + } + } +} + +/****************************************** +* When peerlink ready, prepare the NDISCMsg +* +******************************************/ +static void mlacp_resync_ndisc(struct CSM *csm) +{ + struct Msg *msg = NULL; + struct NDISCMsg *ndisc_msg = NULL; + struct Msg *msg_send = NULL; + + /* recover ndisc info sync from peer */ + if (!TAILQ_EMPTY(&(MLACP(csm).ndisc_list))) + { + TAILQ_FOREACH(msg, &MLACP(csm).ndisc_list, tail) + { + ndisc_msg = (struct NDISCMsg *)msg->buf; + ndisc_msg->op_type = NEIGH_SYNC_ADD; + if (iccp_csm_init_msg(&msg_send, (char *)ndisc_msg, sizeof(struct NDISCMsg)) == 0) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).ndisc_msg_list), msg_send, tail); + } + } + } +} + +/***************************************** +* NAK handler +* +* ***************************************/ +static void mlacp_sync_send_nak_handler(struct CSM* csm, struct Msg* msg) +{ + int msg_len; + ICCHdr* icc_hdr = NULL; + + icc_hdr = (ICCHdr*)msg->buf; + + ICCPD_LOG_WARN(__FUNCTION__, "Send NAK"); + + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + csm->app_csm.invalid_msg_id = ntohl(icc_hdr->ldp_hdr.msg_id); + msg_len = app_csm_prepare_nak_msg(csm, g_csm_buf, CSM_BUFFER_SIZE); + iccp_csm_send(csm, g_csm_buf, msg_len); +} + +static void mlacp_sync_recv_nak_handler(struct CSM* csm, struct Msg* msg) +{ + NAKTLV* naktlv = NULL; + uint16_t tlvType = -1; + int i; + + ICCPD_LOG_WARN(__FUNCTION__, "Receive NAK "); + + /* Dequeuq NAK*/ + naktlv = (NAKTLV*)&msg->buf[sizeof(ICCHdr)]; + + /* Check NAK Type*/ + for (i = 0; i < MAX_MSG_LOG_SIZE; ++i) + { + if (ntohl(naktlv->rejected_msg_id) == csm->msg_log.msg[i].msg_id) + { + tlvType = csm->msg_log.msg[i].tlv; + break; + } + } + + if (tlvType) + { + switch (tlvType) + { + case TLV_T_MLACP_SYSTEM_CONFIG: + MLACP(csm).node_id--; + MLACP(csm).system_config_changed = 1; + ICCPD_LOG_WARN(__FUNCTION__, "[%X] change NodeID as %d", tlvType & 0x00FF, MLACP(csm).node_id); + break; + + default: + ICCPD_LOG_WARN(__FUNCTION__, " [%X]", tlvType & 0x00FF); + MLACP(csm).need_to_sync = 1; + break; + } + } + else + { + ICCPD_LOG_WARN(__FUNCTION__, "Unknow NAK"); + MLACP(csm).need_to_sync = 1; + } + + return; +} + +/***************************************** +* MLACP sync receiver +* +* ***************************************/ +static void mlacp_sync_receiver_handler(struct CSM* csm, struct Msg* msg) +{ + ICCParameter *icc_param; + + /* No receive message...*/ + if (!csm || !msg) + return; + + icc_param = (ICCParameter*)&(msg->buf[sizeof(ICCHdr)]); + + /*fprintf(stderr, " Recv Type [%d]\n", icc_param->type);*/ + switch (icc_param->type) + { + case TLV_T_MLACP_SYSTEM_CONFIG: + mlacp_sync_recv_sysConf(csm, msg); + break; + + case TLV_T_MLACP_PORT_CONFIG: + mlacp_sync_recv_portConf(csm, msg); + break; + + case TLV_T_MLACP_PORT_PRIORITY: + mlacp_sync_recv_portPrio(csm, msg); + break; + + case TLV_T_MLACP_PORT_STATE: + mlacp_sync_recv_portState(csm, msg); + break; + + case TLV_T_MLACP_AGGREGATOR_CONFIG: + /* The following line will be uncommented when Aggregator related structures are supported. */ + mlacp_sync_recv_aggConf(csm, msg); + break; + + case TLV_T_MLACP_AGGREGATOR_STATE: + mlacp_sync_recv_aggState(csm, msg); + break; + + case TLV_T_MLACP_SYNC_DATA: + mlacp_sync_recv_syncData(csm, msg); + break; + + case TLV_T_MLACP_SYNC_REQUEST: + mlacp_sync_recv_syncReq(csm, msg); + break; + + case TLV_T_MLACP_PORT_CHANNEL_INFO: + mlacp_sync_recv_portChanInfo(csm, msg); + break; + + case TLV_T_MLACP_PEERLINK_INFO: + mlacp_sync_recv_peerLlinkInfo(csm, msg); + break; + + case TLV_T_MLACP_MAC_INFO: + mlacp_sync_recv_macInfo(csm, msg); + break; + + case TLV_T_MLACP_ARP_INFO: + mlacp_sync_recv_arpInfo(csm, msg); + break; + + case TLV_T_MLACP_NDISC_INFO: + mlacp_sync_recv_ndiscInfo(csm, msg); + break; + + case TLV_T_MLACP_STP_INFO: + mlacp_sync_recv_stpInfo(csm, msg); + break; + + case TLV_T_MLACP_HEARTBEAT: + mlacp_sync_recv_heartbeat(csm, msg); + break; + + case TLV_T_MLACP_WARMBOOT_FLAG: + mlacp_sync_recv_warmboot(csm, msg); + break; + } + + /*ICCPD_LOG_DEBUG("mlacp_fsm", " [Sync Recv] %s... DONE", get_tlv_type_string(icc_param->type));*/ + + return; +} + +/***************************************** +* MLACP sync sender +* +* ***************************************/ +static void mlacp_sync_sender_handler(struct CSM* csm) +{ + switch (MLACP(csm).sync_state) + { + case MLACP_SYNC_SYSCONF: + mlacp_sync_send_sysConf(csm); + break; + + case MLACP_SYNC_AGGCONF: + /* Do nothing due to no support in this version. */ + mlacp_sync_send_aggConf(csm); + break; + + case MLACP_SYNC_AGGSTATE: + /* Do nothing due to no support in this version. */ + mlacp_sync_send_aggState(csm); + break; + + case MLACP_SYNC_AGGINFO: + mlacp_sync_send_syncPortChannelInfo(csm); + break; + + case MLACP_SYNC_PEERLINKINFO: + mlacp_sync_send_syncPeerLinkInfo(csm); + break; + + case MLACP_SYNC_ARP_INFO: + mlacp_sync_send_syncArpInfo(csm); + break; + + case MLACP_SYNC_NDISC_INFO: + mlacp_sync_send_syncNdiscInfo(csm); + break; + + case MLACP_SYNC_DONE: + mlacp_sync_send_syncDoneData(csm); + break; + + default: + break; + } + + return; +} + +static void mlacp_sync_send_all_info_handler(struct CSM* csm) +{ + size_t len = 0; + + /* Prepare for sync start reply*/ + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + len = mlacp_prepare_for_sync_data_tlv(csm, g_csm_buf, CSM_BUFFER_SIZE, 0); + iccp_csm_send(csm, g_csm_buf, len); + + MLACP(csm).sync_state = MLACP_SYNC_SYSCONF; + + while (1) + { + mlacp_sync_sender_handler(csm); + if (MLACP(csm).sync_state != MLACP_SYNC_DONE) + { + MLACP(csm).sync_state++; + } + else + { + /*Next stage*/ + MLACP(csm).wait_for_sync_data = 0; + MLACP(csm).current_state++; + break; + } + } + + return; +} + +static void mlacp_stage_sync_send_handler(struct CSM* csm, struct Msg* msg) +{ + ICCHdr* icc_hdr = NULL; + ICCParameter* icc_param = NULL; + mLACPSyncReqTLV* mlacp_sync_req = NULL; + + if (MLACP(csm).wait_for_sync_data == 0) + { + /* Waiting the peer sync request*/ + if (msg) + { + icc_hdr = (ICCHdr*)msg->buf; + icc_param = (ICCParameter*)&msg->buf[sizeof(ICCHdr)]; + + if (icc_hdr->ldp_hdr.msg_type == MSG_T_RG_APP_DATA && icc_param->type == TLV_T_MLACP_SYNC_REQUEST) + { + mlacp_sync_req = (mLACPSyncReqTLV*)&msg->buf[sizeof(ICCHdr)]; + MLACP(csm).wait_for_sync_data = 1; + MLACP(csm).sync_req_num = ntohs(mlacp_sync_req->req_num); + + /* Reply the peer all sync info*/ + mlacp_sync_send_all_info_handler(csm); + } + } + } + + return; +} + +static void mlacp_stage_sync_request_handler(struct CSM* csm, struct Msg* msg) +{ + int msg_len = 0; + + /* Socket server send sync request first*/ + if (MLACP(csm).wait_for_sync_data == 0) + { + // Send out the request for ALL + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + msg_len = mlacp_prepare_for_sync_request_tlv(csm, g_csm_buf, CSM_BUFFER_SIZE); + iccp_csm_send(csm, g_csm_buf, msg_len); + MLACP(csm).wait_for_sync_data = 1; + } + else + { + mlacp_sync_receiver_handler(csm, msg); + if (MLACP(csm).wait_for_sync_data == 0) + { + MLACP(csm).current_state++; + } + } + + return; +} + +static void mlacp_stage_handler(struct CSM* csm, struct Msg* msg) +{ + if (MLACP(csm).current_state == MLACP_STATE_STAGE1) + { + /*Stage 1, role active send info first*/ + if (csm->role_type == STP_ROLE_ACTIVE) + mlacp_stage_sync_send_handler(csm, msg); + else + mlacp_stage_sync_request_handler(csm, msg); + } + else + { + /*Stage 2, role standby send info*/ + if (csm->role_type == STP_ROLE_ACTIVE) + mlacp_stage_sync_request_handler(csm, msg); + else + mlacp_stage_sync_send_handler(csm, msg); + } + + return; +} + +static void mlacp_exchange_handler(struct CSM* csm, struct Msg* msg) +{ + int len; + struct System* sys = NULL; + struct LocalInterface* lif = NULL, *lif_purge = NULL; + + ICCHdr* icc_hdr = NULL; + + if ((sys = system_get_instance()) == NULL) + return; + + /* update system id*/ + /*update_system_id(csm);*/ + + /* Any msg?*/ + if (msg) + { + icc_hdr = (ICCHdr*)msg->buf; + if (icc_hdr->ldp_hdr.msg_type == MSG_T_RG_APP_DATA) + { + /* Process receive APP info*/ + mlacp_sync_receiver_handler(csm, msg); + } + } + + if (MLACP(csm).need_to_sync != 0) + { + /* Send out the request for ALL info*/ + MLACP(csm).need_to_sync = 0; + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + len = mlacp_prepare_for_sync_request_tlv(csm, g_csm_buf, CSM_BUFFER_SIZE); + iccp_csm_send(csm, g_csm_buf, len); + } + + /* Send system config*/ + if (MLACP(csm).system_config_changed != 0) + { + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + len = mlacp_prepare_for_sys_config(csm, g_csm_buf, CSM_BUFFER_SIZE); + iccp_csm_send(csm, g_csm_buf, len); + + if (csm->peer_link_if) + { + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + len = mlacp_prepare_for_port_peerlink_info(csm, g_csm_buf, CSM_BUFFER_SIZE, csm->peer_link_if); + iccp_csm_send(csm, g_csm_buf, len); + } + + MLACP(csm).system_config_changed = 0; + } + + /* Send mlag purge lif*/ + LIST_FOREACH(lif_purge, &(MLACP(csm).lif_purge_list), mlacp_purge_next) + { + /* Purge info*/ + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + len = mlacp_prepare_for_Aggport_config(csm, g_csm_buf, CSM_BUFFER_SIZE, lif_purge, 1); + iccp_csm_send(csm, g_csm_buf, len); + /* Destroy old interface*/ + if (lif_purge != NULL) + LIST_REMOVE(lif_purge, mlacp_purge_next); + } + + /* Send mlag lif*/ + LIST_FOREACH(lif, &(MLACP(csm).lif_list), mlacp_next) + { + if (lif->type == IF_T_PORT_CHANNEL && lif->port_config_sync) + { + /* Send port channel information*/ + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + len = mlacp_prepare_for_Aggport_config(csm, g_csm_buf, CSM_BUFFER_SIZE, lif, 0); + iccp_csm_send(csm, g_csm_buf, len); + + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + len = mlacp_prepare_for_port_channel_info(csm, g_csm_buf, CSM_BUFFER_SIZE, lif); + iccp_csm_send(csm, g_csm_buf, len); + + lif->port_config_sync = 0; + } + + /*send if portchannel state change */ + if (lif->type == IF_T_PORT_CHANNEL && lif->changed) + { + /* Send port channel state information*/ + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + len = mlacp_prepare_for_Aggport_state(csm, g_csm_buf, CSM_BUFFER_SIZE, lif); + iccp_csm_send(csm, g_csm_buf, len); + lif->changed = 0; + } + } + + /* Send MAC info if any*/ + mlacp_sync_send_syncMacInfo(csm); + + /* Send ARP info if any*/ + mlacp_sync_send_syncArpInfo(csm); + + /* Send Ndisc info if any */ + mlacp_sync_send_syncNdiscInfo(csm); + + /*If peer is warm reboot*/ + if (csm->peer_warm_reboot_time != 0) + { + /*Peer warm reboot timeout(connection is not broken more than 90s), recover to normal reboot*/ + if ((time(NULL) - csm->peer_warm_reboot_time) >= WARM_REBOOT_TIMEOUT) + { + csm->peer_warm_reboot_time = 0; + ICCPD_LOG_NOTICE(__FUNCTION__, "Peer warm reboot timeout, recover to normal reboot!"); + } + } + + return; +} diff --git a/src/iccpd/src/mlacp_link_handler.c b/src/iccpd/src/mlacp_link_handler.c new file mode 100644 index 000000000000..8bc533e387bd --- /dev/null +++ b/src/iccpd/src/mlacp_link_handler.c @@ -0,0 +1,2413 @@ +/* + * mlacp_link_handler.c + * mLACP link handler + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../include/system.h" +#include "../include/logger.h" +#include "../include/mlacp_tlv.h" + +#include "../include/iccp_csm.h" +#include "mclagdctl/mclagdctl.h" +#include "../include/iccp_cmd_show.h" +#include "../include/iccp_netlink.h" +/***************************************** +* Enum +* +* ***************************************/ +typedef enum route_manipulate_type +{ + ROUTE_NONE, + ROUTE_ADD, + ROUTE_DEL +} ROUTE_MANIPULATE_TYPE_E; + +/***************************************** +* Global +* +* ***************************************/ +char g_ipv4_str[INET_ADDRSTRLEN]; +char g_ipv6_str[INET6_ADDRSTRLEN]; + +/***************************************** +* Tool : show ip string +* +* ***************************************/ +char *show_ip_str(uint32_t ipv4_addr) +{ + struct in_addr in_addr; + + memset(g_ipv4_str, 0, sizeof(g_ipv4_str)); + in_addr.s_addr = ipv4_addr; + inet_ntop(AF_INET, &in_addr, g_ipv4_str, INET_ADDRSTRLEN); + + return g_ipv4_str; +} + +char *show_ipv6_str(char *ipv6_addr) +{ + memset(g_ipv6_str, 0, sizeof(g_ipv6_str)); + inet_ntop(AF_INET6, ipv6_addr, g_ipv6_str, INET6_ADDRSTRLEN); + + return g_ipv6_str; +} + +static int getHwAddr(char *buff, char *mac) +{ + int i = 0; + unsigned int p[6]; + + if ( buff == NULL || mac == NULL ) + { + return MCLAG_ERROR; + } + + if (sscanf(mac, "%x:%x:%x:%x:%x:%x", &p[0], &p[1], &p[2], &p[3], &p[4], &p[5]) < 6) + { + return MCLAG_ERROR; + } + + for (i = 0; i < 6; i++) + { + buff[i] = p[i]; + } + + return 0; +} + +static int arp_set_handler(struct CSM* csm, + struct LocalInterface* lif, + int add) +{ + struct Msg* msg = NULL; + struct ARPMsg* arp_msg = NULL; + char mac_str[18] = ""; + + if (!csm || !lif) + return 0; + + if (add) + goto add_arp; + else + goto del_arp; + + /* Process Add */ + add_arp: + if (MLACP(csm).current_state != MLACP_STATE_EXCHANGE) + return 0; + + TAILQ_FOREACH(msg, &MLACP(csm).arp_list, tail) + { + mac_str[0] = '\0'; + arp_msg = (struct ARPMsg*)msg->buf; + + /* only process add*/ + if (arp_msg->op_type == NEIGH_SYNC_DEL) + continue; + + /* find the ARP for lif_list*/ + if (strcmp(lif->name, arp_msg->ifname) != 0) + continue; + + sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", arp_msg->mac_addr[0], arp_msg->mac_addr[1], arp_msg->mac_addr[2], + arp_msg->mac_addr[3], arp_msg->mac_addr[4], arp_msg->mac_addr[5]); + + iccp_netlink_neighbor_request(AF_INET, (uint8_t *)&arp_msg->ipv4_addr, 1, arp_msg->mac_addr, arp_msg->ifname); + /*ICCPD_LOG_DEBUG(__FUNCTION__, "Add dynamic ARP to kernel [%s]", + show_ip_str(arp_msg->ipv4_addr));*/ + } + goto done; + + del_arp: + /* Process Del */ + TAILQ_FOREACH(msg, &MLACP(csm).arp_list, tail) + { + arp_msg = (struct ARPMsg*)msg->buf; + + /* find the ARP for lif_list*/ + if (strcmp(lif->name, arp_msg->ifname) != 0) + continue; + + /* don't process del*/ + if (arp_msg->op_type == NEIGH_SYNC_DEL) + continue; + + /* link broken, del all dynamic arp on the lif*/ + iccp_netlink_neighbor_request(AF_INET, (uint8_t *)&arp_msg->ipv4_addr, 0, arp_msg->mac_addr, arp_msg->ifname); + /*ICCPD_LOG_DEBUG(__FUNCTION__, "Del dynamic ARP [%s]", + show_ip_str(arp_msg->ipv4_addr));*/ + } + + done: + return 0; +} + +static int ndisc_set_handler(struct CSM *csm, struct LocalInterface *lif, int add) +{ + struct Msg *msg = NULL; + struct NDISCMsg *ndisc_msg = NULL; + char mac_str[18] = ""; + + if (!csm || !lif) + return 0; + + if (add) + goto add_ndisc; + else + goto del_ndisc; + + /* Process Add */ +add_ndisc: + if (MLACP(csm).current_state != MLACP_STATE_EXCHANGE) + return 0; + + TAILQ_FOREACH(msg, &MLACP(csm).ndisc_list, tail) + { + mac_str[0] = '\0'; + ndisc_msg = (struct NDISCMsg *)msg->buf; + + /* only process add */ + if (ndisc_msg->op_type == NEIGH_SYNC_DEL) + continue; + + /* find the ND for lif_list */ + if (strcmp(lif->name, ndisc_msg->ifname) != 0) + continue; + + sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", ndisc_msg->mac_addr[0], ndisc_msg->mac_addr[1], ndisc_msg->mac_addr[2], + ndisc_msg->mac_addr[3], ndisc_msg->mac_addr[4], ndisc_msg->mac_addr[5]); + + iccp_netlink_neighbor_request(AF_INET6, (uint8_t *)ndisc_msg->ipv6_addr, 1, ndisc_msg->mac_addr, ndisc_msg->ifname); + /*ICCPD_LOG_DEBUG(__FUNCTION__, "Add dynamic ND to kernel [%s]", show_ipv6_str((char *)ndisc_msg->ipv6_addr));*/ + } + goto done; + +del_ndisc: + /* Process Del */ + TAILQ_FOREACH(msg, &MLACP(csm).ndisc_list, tail) + { + ndisc_msg = (struct NDISCMsg *)msg->buf; + + /* find the ND for lif_list */ + if (strcmp(lif->name, ndisc_msg->ifname) != 0) + continue; + + /* don't process del */ + if (ndisc_msg->op_type == NEIGH_SYNC_DEL) + continue; + + /* link broken, del all dynamic ndisc on the lif */ + iccp_netlink_neighbor_request(AF_INET6, (uint8_t *)ndisc_msg->ipv6_addr, 0, ndisc_msg->mac_addr, ndisc_msg->ifname); + /*ICCPD_LOG_DEBUG(__FUNCTION__, "Del dynamic ND [%s]", show_ipv6_str((char *)ndisc_msg->ipv6_addr));*/ + } + +done: + return 0; +} + +/***************************************** + * Port-Channel Status Handler + * + ****************************************/ +static void set_route_by_linux_route(struct CSM* csm, + struct LocalInterface *local_if, + int is_add) +{ + /* TODO Need to remove this function + when set static route with zebra works fine*/ + + char ipv4_dest_str[INET_ADDRSTRLEN]; + char syscmd[128]; + char *ptr; + int ret = 0; + + /* enable kernel forwarding support*/ + system("echo 1 > /proc/sys/net/ipv4/ip_forward"); + + if (!csm || !local_if) + return; + + sprintf(ipv4_dest_str, "%s", show_ip_str(htonl(local_if->ipv4_addr))); + ptr = strrchr(ipv4_dest_str, '.'); + strcpy(ptr, ".0\0"); + + /* set gw route */ + /* sprintf(syscmd, "ip route %s %s/%d proto static metric 200 nexthop via %s > /dev/null 2>&1", */ + sprintf(syscmd, "ip route %s %s/%d metric 200 nexthop via %s > /dev/null 2>&1", + (is_add) ? "add" : "del", ipv4_dest_str, local_if->prefixlen, csm->peer_ip); + + ret = system(syscmd); + ICCPD_LOG_DEBUG(__FUNCTION__, "%s ret = %d", syscmd, ret); + + return; +} + +static void update_vlan_if_info(struct CSM *csm, + struct LocalInterface *local_if, + struct LocalInterface *vlan_if, + int po_state) +{ + if (!csm || !local_if || !vlan_if) + return; + + vlan_if->mlacp_state = MLACP(csm).current_state; + + return; +} + +static void update_l3_if_info(struct CSM *csm, + struct LocalInterface *local_if, + struct LocalInterface *l3_if, + int po_state) +{ + if (!csm || !l3_if) + return; + + l3_if->mlacp_state = MLACP(csm).current_state; + + return; +} + +static void update_po_if_info(struct CSM *csm, + struct LocalInterface *local_if, + int po_state) +{ + if (!csm || !local_if) + return; + + /* update local po info*/ + if (local_if->po_active != po_state) + { + local_if->changed = 1; + local_if->po_active = (po_state != 0); + /*printf("update po [%s=%d]\n",local_if->name, local_if->po_active);*/ + } + local_if->mlacp_state = MLACP(csm).current_state; + + return; +} + +static void set_l3_itf_state(struct CSM *csm, + struct LocalInterface *set_l3_local_if, + ROUTE_MANIPULATE_TYPE_E route_type) +{ + if (!csm || !set_l3_local_if) + return; + + if (set_l3_local_if && (route_type != ROUTE_NONE)) + { + /*set_default_route(csm);*/ + + /*ICCPD_LOG_DEBUG(__FUNCTION__, " route set Interface = %s route type = %d route = %s nexthop via = %s ", + set_l3_local_if->name, route_type, show_ip_str(htonl(set_l3_local_if->ipv4_addr)), csm->peer_ip );*/ + + /* set static route*/ + if (route_type == ROUTE_ADD) + { + /*set_route_by_linux_route(csm, set_l3_local_if, 1);*/ /*add static route by linux route tool*/ + /*If the L3 intf is not Vlan, del ARP; else wait ARP age*/ + if (strncmp(set_l3_local_if->name, VLAN_PREFIX, 4) != 0) + { + arp_set_handler(csm, set_l3_local_if, 0); /* del arp*/ + ndisc_set_handler(csm, set_l3_local_if, 0); /* del nd */ + } + } + else if (route_type == ROUTE_DEL) + { + /*set_route_by_linux_route(csm, set_l3_local_if, 0);*/ /*del static route by linux route tool*/ + arp_set_handler(csm, set_l3_local_if, 1); /* add arp*/ + ndisc_set_handler(csm, set_l3_local_if, 1); /* add nd */ + } + } + + return; +} + +static int peer_po_is_alive(struct CSM *csm, int po_ifindex) +{ + struct PeerInterface *pif = NULL; + int pif_active = 0; + + if (!csm) + return 0; + + LIST_FOREACH(pif, &(MLACP(csm).pif_list), mlacp_next) + { + if (pif->type != IF_T_PORT_CHANNEL) + continue; + if (pif->po_id != po_ifindex) + continue; + + if (pif->po_active) + pif_active = 1; /*pif alive*/ + break; + } + + return pif_active; +} + +static void mlacp_clean_fdb(void) +{ + struct IccpSyncdHDr * msg_hdr; + char *msg_buf = g_csm_buf; + + struct System *sys; + + sys = system_get_instance(); + if (sys == NULL) + return; + memset(msg_buf, 0, CSM_BUFFER_SIZE); + msg_hdr = (struct IccpSyncdHDr *)msg_buf; + msg_hdr->ver = 1; + msg_hdr->type = MCLAG_MSG_TYPE_FLUSH_FDB; + msg_hdr->len = sizeof(struct IccpSyncdHDr); + + if (sys->sync_fd) + write(sys->sync_fd, msg_buf, msg_hdr->len); + + ICCPD_LOG_NOTICE(__FUNCTION__, "Notify mclagsyncd to clear FDB"); + + return; +} + +void set_peerlink_mlag_port_learn(struct LocalInterface *lif, int enable) +{ + struct IccpSyncdHDr * msg_hdr; + mclag_sub_option_hdr_t * sub_msg; + char *msg_buf = g_csm_buf; + int msg_len; + struct System *sys; + + sys = system_get_instance(); + if (sys == NULL) + return; + + if (!lif) + return; + memset(msg_buf, 0, CSM_BUFFER_SIZE); + msg_hdr = (struct IccpSyncdHDr *)msg_buf; + msg_hdr->ver = 1; + msg_hdr->type = MCLAG_MSG_TYPE_PORT_MAC_LEARN_MODE; + + msg_hdr->len = sizeof(struct IccpSyncdHDr); + + sub_msg = (mclag_sub_option_hdr_t*)&msg_buf[msg_hdr->len]; + sub_msg->op_type = MCLAG_SUB_OPTION_TYPE_MAC_LEARN_DISABLE; + + if (enable) + sub_msg->op_type = MCLAG_SUB_OPTION_TYPE_MAC_LEARN_ENABLE; + + msg_len = strlen(lif->name); + memcpy(sub_msg->data, lif->name, msg_len); + + sub_msg->op_len = msg_len; + msg_hdr->len += sizeof(mclag_sub_option_hdr_t); + msg_hdr->len += sub_msg->op_len; + + ICCPD_LOG_NOTICE(__FUNCTION__, "Send %s port MAC learn msg to mclagsyncd for %s", + sub_msg->op_type == MCLAG_SUB_OPTION_TYPE_MAC_LEARN_DISABLE ? "DISABLE":"ENABLE", lif->name); + + /*send msg*/ + if (sys->sync_fd) + write(sys->sync_fd, msg_buf, msg_hdr->len); + + return; +} + +static void set_peerlink_mlag_port_kernel_forward( + struct CSM *csm, + struct LocalInterface *lif, + int enable) +{ + if (!csm || !csm->peer_link_if || !lif) + return; + + char cmd[256] = { 0 }; + + sprintf(cmd, "ebtables %s FORWARD -i %s -o %s -j DROP", + "-D", csm->peer_link_if->name, lif->name); + ICCPD_LOG_NOTICE(__FUNCTION__, " ebtable cmd %s", cmd ); + system(cmd); + + sprintf(cmd, "ebtables %s FORWARD -i %s -o %s -j DROP", + (enable) ? "-A" : "-D", csm->peer_link_if->name, lif->name); + ICCPD_LOG_NOTICE(__FUNCTION__, " ebtable cmd %s", cmd ); + system(cmd); + + return; +} + +void update_peerlink_isolate_from_all_csm_lif( + struct CSM* csm) +{ + struct LocalInterface *lif = NULL; + struct IccpSyncdHDr * msg_hdr; + mclag_sub_option_hdr_t * sub_msg; + char msg_buf[4096]; + struct System *sys; + + char mlag_po_buf[512]; + int src_len = 0, dst_len = 0; + + sys = system_get_instance(); + if (sys == NULL) + return; + + if (!csm || !csm->peer_link_if) + return; + + memset(msg_buf, 0, 4095); + memset(mlag_po_buf, 0, 511); + + msg_hdr = (struct IccpSyncdHDr *)msg_buf; + msg_hdr->ver = 1; + msg_hdr->type = MCLAG_MSG_TYPE_PORT_ISOLATE; + msg_hdr->len = sizeof(struct IccpSyncdHDr); + + /*sub msg src*/ + sub_msg = (mclag_sub_option_hdr_t *)&msg_buf[msg_hdr->len]; + sub_msg->op_type = MCLAG_SUB_OPTION_TYPE_ISOLATE_SRC; + + if (csm->peer_link_if->type == IF_T_VXLAN) + { + /*TBD: vxlan tunnel port isolation will be supportted later*/ + return; +#if 0 + int begin_eth_port = 0; + + /*VTTNL0001;Ethernet0001,Ethernet0002*/ + /*src_len= strlen(csm->peer_link_if->name); */ + src_len += snprintf(src_buf + src_len, sizeof(src_buf) - src_len, "%s", csm->peer_link_if->name); + src_len += snprintf(src_buf + src_len, sizeof(src_buf) - src_len, "%s", ";"); + + /*traverse all ethernet port */ + LIST_FOREACH(lif, &(sys->lif_list), system_next) + { + if (lif->type != IF_T_PORT) + continue; + + /* need to isolate port, get it's name */ + if (begin_eth_port != 0) + { + src_len += snprintf(src_buf + src_len, sizeof(src_buf) - src_len, "%s", ","); + } + + src_len += snprintf(src_buf + src_len, sizeof(src_buf) - src_len, "%s", lif->name); + begin_eth_port = 1; + } + memcpy(sub_msg->data, src_buf, src_len); + + ICCPD_LOG_DEBUG(__FUNCTION__, "isolate src %s, data %s, len %d", src_buf, sub_msg->data, src_len); +#endif + } + else + { + src_len = strlen(csm->peer_link_if->name); + memcpy(sub_msg->data, csm->peer_link_if->name, src_len); + } + sub_msg->op_len = src_len; + + /*sub msg dst */ + msg_hdr->len += sub_msg->op_len; + msg_hdr->len += sizeof(mclag_sub_option_hdr_t); + sub_msg = (mclag_sub_option_hdr_t *)&msg_buf[msg_hdr->len]; + sub_msg->op_type = MCLAG_SUB_OPTION_TYPE_ISOLATE_DST; + + /*traverse all portchannel member port and send msg to syncd */ + LIST_FOREACH(lif, &(MLACP(csm).lif_list), mlacp_next) + { + if (lif->type != IF_T_PORT_CHANNEL) + continue; + + /* check pif port state and lif pochannel state */ + if (lif->isolate_to_peer_link == 1) + { + /* need to isolate port, get it's member name */ + if (strlen(mlag_po_buf) != 0) + dst_len += snprintf(mlag_po_buf + dst_len, sizeof(mlag_po_buf) - dst_len, "%s", ","); + + dst_len += snprintf(mlag_po_buf + dst_len, sizeof(mlag_po_buf) - dst_len, "%s", lif->portchannel_member_buf); + } + } + + sub_msg->op_len = dst_len; + msg_hdr->len += sizeof(mclag_sub_option_hdr_t); + msg_hdr->len += sub_msg->op_len; + + if (dst_len) + { + memcpy(sub_msg->data, mlag_po_buf, dst_len); + ICCPD_LOG_NOTICE(__FUNCTION__, "Send port isolate msg to mclagsyncd, src port %s, dst port %s", csm->peer_link_if->name, mlag_po_buf); + } + else + { + ICCPD_LOG_NOTICE(__FUNCTION__, "Send port isolate msg to mclagsyncd, src port %s, dst port is NULL", csm->peer_link_if->name); + } + + /*send msg*/ + if (sys->sync_fd) + write(sys->sync_fd, msg_buf, msg_hdr->len); + + return; +} + +static void set_peerlink_mlag_port_isolate( + struct CSM *csm, + struct LocalInterface *lif, + int enable) +{ + if (!lif) + return; + + lif->isolate_to_peer_link = enable; + + if (!csm || !csm->peer_link_if ) + return; + + if (MLACP(csm).current_state != MLACP_STATE_EXCHANGE) + return; + + ICCPD_LOG_DEBUG(__FUNCTION__, "%s port-isolate from %s to %s", + enable ? "Enable" : "Disable", csm->peer_link_if->name, lif->name); + update_peerlink_isolate_from_all_csm_lif(csm); + + /* Kernel also needs to block traffic from peerlink to mlag-port*/ + set_peerlink_mlag_port_kernel_forward(csm, lif, enable); + + return; +} + +void peerlink_port_isolate_cleanup(struct CSM* csm) +{ + struct LocalInterface *local_if = NULL; + + if (!csm) + return; + + /* Clean all port block*/ + LIST_FOREACH(local_if, &(MLACP(csm).lif_list), mlacp_next) + { + if (local_if->type == IF_T_PORT_CHANNEL) + { + set_peerlink_mlag_port_isolate(csm, local_if, 0); + } + } + + return; +} + +void update_peerlink_isolate_from_pif( + struct CSM *csm, + struct PeerInterface *pif, + int pif_po_state, + int new_create) +{ + struct LocalInterface *lif = NULL; + int lif_po_state = 1; + + if (!csm || !csm->peer_link_if || !pif) + return; + if (new_create == 0 && pif_po_state == pif->po_active) + return; + if (MLACP(csm).current_state != MLACP_STATE_EXCHANGE) + return; + + /* peer link changed*/ + LIST_FOREACH(lif, &(MLACP(csm).lif_list), mlacp_next) + { + if (strcmp(lif->name, pif->name) != 0) + continue; + + lif_po_state = lif->po_active; + break; + } + + if (!lif) + { + ICCPD_LOG_WARN(__FUNCTION__, "Can't find local if for %s", pif->name); + return; + } + + ICCPD_LOG_DEBUG(__FUNCTION__, "From if %s local(%s) / peer(%s)", + lif->name, + (lif_po_state) ? "up" : "down", + (pif_po_state) ? "up" : "down"); + + if (lif_po_state == 1) + { + if (pif_po_state == 1) + { + /* both peer-pair link up, enable port-isolate*/ + ICCPD_LOG_DEBUG(__FUNCTION__, "Enable port-isolate from %s to %s", + csm->peer_link_if->name, lif->name); + set_peerlink_mlag_port_isolate(csm, lif, 1); + } + else + { + /* local link up, and peer link changes to down, disable port-isolate*/ + ICCPD_LOG_DEBUG(__FUNCTION__, "Disable port-isolate from %s to %s", + csm->peer_link_if->name, lif->name); + set_peerlink_mlag_port_isolate(csm, lif, 0); + } + } + else + { + ;/* local link down, do nothing*/ + } + + return; +} + +static void update_peerlink_isolate_from_lif( + struct CSM* csm, + struct LocalInterface* lif, + int lif_po_state) +{ + struct PeerInterface *pif = NULL; + int pif_po_state = 1; + + if (!csm || !csm->peer_link_if || !lif) + return; + /*if (lif_po_state == lif->po_active) return;*/ + if (MLACP(csm).current_state != MLACP_STATE_EXCHANGE) + return; + + /* local link changed*/ + LIST_FOREACH(pif, &(MLACP(csm).pif_list), mlacp_next) + { + if (strcmp(pif->name, lif->name) != 0) + continue; + + pif_po_state = pif->po_active; + break; + } + + ICCPD_LOG_DEBUG(__FUNCTION__, "From if %s local(%s) / peer(%s)", + lif->name, (lif_po_state) ? "up" : "down", (pif_po_state) ? "up" : "down"); + + if (lif_po_state == 1) + { + if (pif_po_state == 1) + { + /* both peer-pair link up, enable port-isolate*/ + ICCPD_LOG_DEBUG(__FUNCTION__, "Enable port-isolate from %s to %s", + csm->peer_link_if->name, lif->name); + set_peerlink_mlag_port_isolate(csm, lif, 1); + } + else + { + /* peer link down, local link changes to up, disable port-isolate*/ + ICCPD_LOG_DEBUG(__FUNCTION__, " Disable port-isolate from %s to %s", + csm->peer_link_if->name, lif->name); + set_peerlink_mlag_port_isolate(csm, lif, 0); + } + } + else + { + ;/* local link down, do nothing*/ + } + + return; +} + +static void update_l2_po_state(struct CSM *csm, + struct LocalInterface *lif, + int po_state) +{ + ROUTE_MANIPULATE_TYPE_E route_type = ROUTE_NONE; + struct VLAN_ID *vlan = NULL; + struct LocalInterface *set_l3_vlan_if = NULL; + + if (!csm || !lif) + return; + + /*L2 po*/ + /*if (po_state != lif->po_active && po_state == 0) + { + mlacp_clean_fdb(); + }*/ + + /*Is there any L3 vlan over L2 po?*/ + LIST_FOREACH(vlan, &(lif->vlan_list), port_next) + { + route_type = ROUTE_NONE; + + if (!vlan->vlan_itf) + continue; + + /* If the po is under a vlan, update vlan state first*/ + update_vlan_if_info(csm, lif, vlan->vlan_itf, po_state); + + if (!local_if_is_l3_mode(vlan->vlan_itf)) + continue; + + /*NOTE + * assume only one mlag per vlan + * need to add rules for per mlag per vlan later (arp list?) + */ + set_l3_vlan_if = vlan->vlan_itf; + if (po_state != lif->po_active + || MLACP(csm).current_state != set_l3_vlan_if->mlacp_state) + { + if (po_state == 1) + { + route_type = ROUTE_DEL; + } + else if (po_state == 0 + && MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + if (peer_po_is_alive(csm, lif->ifindex) == 1) + route_type = ROUTE_ADD; + } + } + + /*update_po_arp_list(csm, set_l3_vlan_if);*/ + set_l3_itf_state(csm, set_l3_vlan_if, route_type); + update_l3_if_info(csm, lif, set_l3_vlan_if, po_state); + } + + return; +} + +static void update_l3_po_state(struct CSM *csm, + struct LocalInterface *lif, + int po_state) +{ + ROUTE_MANIPULATE_TYPE_E route_type = ROUTE_NONE; + struct LocalInterface *set_l3_lif = NULL; + + /*L3 po*/ + set_l3_lif = lif; + + if (!csm || !lif) + return; + + if (po_state != lif->po_active + && po_state == 1) + { + /* po alive, clean static route & recover the ARP*/ + route_type = ROUTE_DEL; + } + else if (po_state != lif->po_active + && po_state == 0 + && MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + /* po is not alive & peer-link alive, set static route*/ + if (peer_po_is_alive(csm, lif->po_id) == 1) + route_type = ROUTE_ADD; + } + else if (MLACP(csm).current_state != lif->mlacp_state + && MLACP(csm).current_state == MLACP_STATE_EXCHANGE + && po_state == 0) + { + /* when peer-pair link ready, set static route for broken po link*/ + if (peer_po_is_alive(csm, lif->po_id) == 1) + route_type = ROUTE_ADD; + } + + /*update_po_arp_list(csm, set_l3_lif);*/ + set_l3_itf_state(csm, set_l3_lif, route_type); + update_l3_if_info(csm, lif, set_l3_lif, po_state); + + return; +} + +int is_local_vlan_on(struct VLAN_ID* vlan_id_list) +{ + if (!vlan_id_list->vlan_itf) + return 0; + + return 1; +} + +void syn_arp_info_to_peer(struct CSM *csm, struct LocalInterface *local_if) +{ + struct Msg *msg = NULL; + struct ARPMsg *arp_msg = NULL, *arp_info = NULL; + struct Msg *msg_send = NULL; + + if (!csm || !local_if) + return; + + if (!TAILQ_EMPTY(&(MLACP(csm).arp_list))) + { + TAILQ_FOREACH(msg, &MLACP(csm).arp_list, tail) + { + arp_info = (struct ARPMsg*)msg->buf; + + if (strcmp(arp_info->ifname, local_if->name) != 0) + continue; + + arp_msg = (struct ARPMsg*)msg->buf; + arp_msg->op_type = NEIGH_SYNC_ADD; + + if (iccp_csm_init_msg(&msg_send, (char*)arp_msg, sizeof(struct ARPMsg)) == 0) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).arp_msg_list), msg_send, tail); + /*ICCPD_LOG_DEBUG( __FUNCTION__, "Enqueue ARP[ADD] for %s", + show_ip_str(htonl(arp_msg->ipv4_addr)));*/ + } + else + ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ARP[ADD] for %s", + show_ip_str(arp_msg->ipv4_addr)); + } + } + + return; +} + +void syn_ndisc_info_to_peer(struct CSM *csm, struct LocalInterface *local_if) +{ + struct Msg *msg = NULL; + struct NDISCMsg *ndisc_msg = NULL, *ndisc_info = NULL; + struct Msg *msg_send = NULL; + + if (!csm || !local_if) + return; + + if (!TAILQ_EMPTY(&(MLACP(csm).ndisc_list))) + { + TAILQ_FOREACH(msg, &MLACP(csm).ndisc_list, tail) + { + ndisc_info = (struct NDISCMsg *)msg->buf; + + if (strcmp(ndisc_info->ifname, local_if->name) != 0) + continue; + + ndisc_msg = (struct NDISCMsg *)msg->buf; + ndisc_msg->op_type = NEIGH_SYNC_ADD; + + if (iccp_csm_init_msg(&msg_send, (char *)ndisc_msg, sizeof(struct NDISCMsg)) == 0) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).ndisc_msg_list), msg_send, tail); + /*ICCPD_LOG_DEBUG(__FUNCTION__, "Enqueue ND[ADD] for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr));*/ + } + else + ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ND[ADD] for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr)); + } + } + + return; +} +void update_stp_peer_link(struct CSM *csm, + struct PeerInterface *pif, + int po_state, int new_create) +{ + struct LocalInterface *lif = NULL; + struct VLAN_ID *vlan = NULL; + + if (!csm || !pif) + return; + if (new_create == 0 && po_state == pif->po_active) + return; + + LIST_FOREACH(lif, &(MLACP(csm).lif_list), mlacp_next) + { + if (strcmp(lif->name, pif->name) != 0) + continue; + + /* update lif route if pif link status changes */ + if (local_if_is_l3_mode(lif)) + { + if (po_state == 1 && lif->po_active == 0) + set_l3_itf_state(csm, lif, ROUTE_ADD); + else if (po_state == 0 && lif->po_active == 0) + set_l3_itf_state(csm, lif, ROUTE_DEL); + + /*If pif change to active, and local is also active, syn arp to peer*/ + if (po_state == 1 && lif->po_active == 1) + { + syn_arp_info_to_peer(csm, lif); + syn_ndisc_info_to_peer(csm, lif); + } + } + else + { + LIST_FOREACH(vlan, &(lif->vlan_list), port_next) + { + if (!is_local_vlan_on(vlan)) + continue; + if (!local_if_is_l3_mode(vlan->vlan_itf)) + continue; + + /*NOTE + * assume only one mlag per bridge + * need to add rules for per mlag per bridge later (arp list?) + */ + if (po_state == 1 && lif->po_active == 0) + set_l3_itf_state(csm, vlan->vlan_itf, ROUTE_ADD); + else if (po_state == 0 && lif->po_active == 0) + set_l3_itf_state(csm, vlan->vlan_itf, ROUTE_DEL); + + /*If pif change to active, and local is also active, syn arp to peer*/ + if (po_state == 1 && lif->po_active == 1) + { + syn_arp_info_to_peer(csm, vlan->vlan_itf); + syn_ndisc_info_to_peer(csm, vlan->vlan_itf); + } + } + } + + break; + } + + return; +} + +void iccp_get_fdb_change_from_syncd( void) +{ + struct IccpSyncdHDr * msg_hdr; + char msg_buf[512]; + struct System *sys; + + sys = system_get_instance(); + if (sys == NULL) + return; + + memset(msg_buf, 0, 512); + + msg_hdr = (struct IccpSyncdHDr *)msg_buf; + msg_hdr->ver = 1; + msg_hdr->type = MCLAG_MSG_TYPE_GET_FDB_CHANGES; + msg_hdr->len = sizeof(struct IccpSyncdHDr); + + ICCPD_LOG_DEBUG(__FUNCTION__, "Send get fdb change msg to mclagsyncd"); + + /*send msg*/ + if (sys->sync_fd > 0) + write(sys->sync_fd, msg_buf, msg_hdr->len); + + return; +} + +void iccp_send_fdb_entry_to_syncd( struct MACMsg* mac_msg, uint8_t mac_type) +{ + struct IccpSyncdHDr * msg_hdr; + char msg_buf[512]; + struct System *sys; + struct mclag_fdb_info * mac_info; + + sys = system_get_instance(); + if (sys == NULL) + return; + + memset(msg_buf, 0, 512); + + msg_hdr = (struct IccpSyncdHDr *)msg_buf; + msg_hdr->ver = 1; + msg_hdr->type = MCLAG_MSG_TYPE_SET_FDB; + + /*mac msg */ + mac_info = (struct mclag_fdb_info *)&msg_buf[sizeof(struct IccpSyncdHDr)]; + mac_info->vid = mac_msg->vid; + memcpy(mac_info->port_name, mac_msg->ifname, MAX_L_PORT_NAME); + memcpy(mac_info->mac, mac_msg->mac_str, ETHER_ADDR_STR_LEN); + mac_info->type = mac_type; + mac_info->op_type = mac_msg->op_type; + msg_hdr->len = sizeof(struct IccpSyncdHDr) + sizeof(struct mclag_fdb_info); + + ICCPD_LOG_NOTICE(__FUNCTION__, "Send mac %s msg to mclagsyncd, vid %d ; ifname %s ; mac %s; type %s", + mac_info->op_type == MAC_SYNC_ADD ? "add" : "del", mac_info->vid, mac_info->port_name, mac_info->mac, mac_info->type == MAC_TYPE_STATIC ? "static" : "dynamic"); + + /*send msg*/ + if (sys->sync_fd > 0 ) + write(sys->sync_fd, msg_buf, msg_hdr->len); + + return; +} + +void add_mac_to_chip(struct MACMsg* mac_msg, uint8_t mac_type) +{ + mac_msg->op_type = MAC_SYNC_ADD; + iccp_send_fdb_entry_to_syncd( mac_msg, mac_type); + + return; +} + +void del_mac_from_chip(struct MACMsg* mac_msg) +{ + mac_msg->op_type = MAC_SYNC_DEL; + iccp_send_fdb_entry_to_syncd( mac_msg, mac_msg->fdb_type); + + return; +} + +uint8_t set_mac_local_age_flag(struct CSM *csm, struct MACMsg* mac_msg, uint8_t set ) +{ + uint8_t new_age_flag = 0; + struct Msg *msg = NULL; + + new_age_flag = mac_msg->age_flag; + + if (set == 0)/*remove age flag*/ + { + new_age_flag &= ~MAC_AGE_LOCAL; + + ICCPD_LOG_DEBUG(__FUNCTION__, "Remove local age flag: %d ifname %s, add %s vlan-id %d, age_flag %d", + new_age_flag, mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->age_flag); + + /*send mac MAC_SYNC_ADD message to peer*/ + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + mac_msg->op_type = MAC_SYNC_ADD; + if (iccp_csm_init_msg(&msg, (char*)mac_msg, sizeof(struct MACMsg)) == 0) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).mac_msg_list), msg, tail); + /*ICCPD_LOG_DEBUG(__FUNCTION__, "MAC-msg-list enqueue: %s, add %s vlan-id %d, age_flag %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->age_flag);*/ + } + else + { + ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue MAC-msg-list: %s, add %s vlan-id %d, age_flag %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->age_flag); + } + } + } + else/*set age flag*/ + { + new_age_flag |= MAC_AGE_LOCAL; + + ICCPD_LOG_DEBUG(__FUNCTION__, "Add local age flag: %s, add %s vlan-id %d, age_flag %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->age_flag); + + /*send mac MAC_SYNC_DEL message to peer*/ + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + mac_msg->op_type = MAC_SYNC_DEL; + if (iccp_csm_init_msg(&msg, (char*)mac_msg, sizeof(struct MACMsg)) == 0) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).mac_msg_list), msg, tail); + /*ICCPD_LOG_DEBUG(__FUNCTION__, "MAC-msg-list enqueue: %s, add %s vlan-id %d, age_flag %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->age_flag);*/ + } + else + { + ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue MAC-msg-list: %s, del %s vlan-id %d, age_flag %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->age_flag); + } + } + } + + return new_age_flag; +} + +/*Deal with mac add,del,move when portchannel up or down*/ +static void update_l2_mac_state(struct CSM *csm, + struct LocalInterface *lif, + int po_state) +{ + struct Msg* msg = NULL; + struct MACMsg* mac_msg = NULL; + + if (!csm || !lif) + return; + + TAILQ_FOREACH(msg, &MLACP(csm).mac_list, tail) + { + mac_msg = (struct MACMsg*)msg->buf; + + /* find the MAC for this interface*/ + if (strcmp(lif->name, mac_msg->origin_ifname) != 0) + continue; + + /*portchannel down*/ + if (po_state == 0) + { + ICCPD_LOG_NOTICE(__FUNCTION__, "Intf %s down, age local MAC %s vlan-id %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); + + mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 1); + + if (mac_msg->age_flag == (MAC_AGE_LOCAL | MAC_AGE_PEER)) + { + /*send mac del message to mclagsyncd.*/ + if (mac_msg->fdb_type != MAC_TYPE_STATIC) + del_mac_from_chip(mac_msg); + + ICCPD_LOG_DEBUG(__FUNCTION__, "Intf %s down, del MAC %s vlan-id %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); + + /*If local and peer both aged, del the mac*/ + TAILQ_REMOVE(&(MLACP(csm).mac_list), msg, tail); + free(msg->buf); + free(msg); + } + else + { + /*If local is aged but peer is not aged, redirect the mac to peer-link*/ + if (strlen(csm->peer_itf_name) != 0) + { + /*Send mac add message to mclagsyncd. fdb_type is not changed*/ + /*Is need to delete the old item before add?(Old item probably is static)*/ + if (csm->peer_link_if && csm->peer_link_if->state == PORT_STATE_UP) + { + memcpy(mac_msg->ifname, csm->peer_itf_name, IFNAMSIZ); + add_mac_to_chip(mac_msg, MAC_TYPE_DYNAMIC); + } + else + { + /*must redirect but peerlink is down, del mac from ASIC*/ + /*if peerlink change to up, mac will add back to ASIC*/ + del_mac_from_chip(mac_msg); + memcpy(mac_msg->ifname, csm->peer_itf_name, IFNAMSIZ); + } + + ICCPD_LOG_NOTICE(__FUNCTION__, "Intf %s down, redirect MAC %s vlan-id %d to peer-link %s", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, csm->peer_itf_name); + } + else + { + /*peer-link is not configured, del mac from ASIC, mac still in mac_list*/ + del_mac_from_chip(mac_msg); + + ICCPD_LOG_NOTICE(__FUNCTION__, "Intf %s down, peer-link is not configured: MAC %s vlan-id %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); + } + } + } + else /*portchannel up*/ + { + /*the old item is redirect to peerlink for portchannel down*/ + /*when this portchannel up, recover the mac back*/ + if (strcmp(mac_msg->ifname, csm->peer_itf_name) == 0) + { + ICCPD_LOG_NOTICE(__FUNCTION__, "Intf %s up, redirect MAC %s vlan-id %d from peerlink to %s", + mac_msg->origin_ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->origin_ifname); + + /*Remove MAC_AGE_LOCAL flag*/ + mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 0); + + /*Reverse interface from peer-link to the original portchannel*/ + memcpy(mac_msg->ifname, mac_msg->origin_ifname, MAX_L_PORT_NAME); + + /*Send dynamic or static mac add message to mclagsyncd*/ + add_mac_to_chip(mac_msg, mac_msg->fdb_type); + } + else + { + /*this may be peerlink is not configured and portchannel is down*/ + /*when this portchannel up, add the mac back to ASIC*/ + ICCPD_LOG_NOTICE(__FUNCTION__, "Intf %s up, add MAC %s vlan-id %d to ASIC", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); + + /*Remove MAC_AGE_LOCAL flag*/ + mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 0); + + /*Send dynamic or static mac add message to mclagsyncd*/ + add_mac_to_chip(mac_msg, mac_msg->fdb_type); + } + } + } + + return; +} + +void mlacp_portchannel_state_handler(struct CSM* csm, + struct LocalInterface* local_if, + int po_state) +{ + if (!csm || !local_if) + return; + + update_peerlink_isolate_from_lif(csm, local_if, po_state); + + update_l2_mac_state(csm, local_if, po_state); + + if (!local_if_is_l3_mode(local_if)) + update_l2_po_state(csm, local_if, po_state); + else + update_l3_po_state(csm, local_if, po_state); + + update_po_if_info(csm, local_if, po_state); + + return; +} + +static void mlacp_conn_handler_fdb(struct CSM* csm) +{ + struct Msg* msg = NULL; + struct MACMsg* mac_msg = NULL; + struct Msg *msg_send = NULL; + + if (!csm) + return; + + if (!TAILQ_EMPTY(&(MLACP(csm).mac_list))) + { + TAILQ_FOREACH(msg, &MLACP(csm).mac_list, tail) + { + mac_msg = (struct MACMsg*)msg->buf; + + /*Wait the ACK from peer?*/ + /*mac_msg->age_flag &= ~MAC_AGE_PEER;*/ + + /*If MAC with local age flag, dont sync to peer. Such MAC only exist when peer is warm-reboot. + If peer is warm-reboot, peer age flag is not set when connection is lost. + When MAC is aged in local switch, this MAC is not deleted for no peer age flag. + After warm-reboot, this MAC must be learnt by peer and sync to local switch*/ + if (!(mac_msg->age_flag & MAC_AGE_LOCAL)) + { + /*Send mac add message to peer*/ + mac_msg->op_type = MAC_SYNC_ADD; + if (iccp_csm_init_msg(&msg_send, (char*)mac_msg, sizeof(struct MACMsg)) == 0) + { + mac_msg->age_flag &= ~MAC_AGE_PEER; + TAILQ_INSERT_TAIL(&(MLACP(csm).mac_msg_list), msg_send, tail); + ICCPD_LOG_DEBUG(__FUNCTION__, "MAC-msg-list enqueue: %s, add %s vlan-id %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); + } + } + else + { + /*If MAC with local age flag and is point to MCLAG enabled port, reomove local age flag*/ + if (strcmp(mac_msg->ifname, csm->peer_itf_name) != 0) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "MAC-msg-list not enqueue for local age flag: %s, mac %s vlan-id %d, remove local age flag", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); + mac_msg->age_flag &= ~MAC_AGE_LOCAL; + } + } + } + } + + return; +} + +static void mlacp_fix_bridge_mac(struct CSM* csm) +{ + char syscmd[128]; + int ret = 0; + char macaddr[64]; + uint8_t null_mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + if (memcmp(MLACP(csm).system_id, null_mac, ETHER_ADDR_LEN) != 0) + { + memset(macaddr, 0, 64); + snprintf(macaddr, 64, "%02x:%02x:%02x:%02x:%02x:%02x", + MLACP(csm).system_id[0], MLACP(csm).system_id[1], MLACP(csm).system_id[2], + MLACP(csm).system_id[3], MLACP(csm).system_id[4], MLACP(csm).system_id[5]); + + /*When changing the mac of a vlan member port, the mac of Bridge will be changed.*/ + /*The Bridge mac can not be the same as peer system id, so fix the Bridge MAC address here.*/ + sprintf(syscmd, "ip link set dev Bridge address %s > /dev/null 2>&1", macaddr); + ret = system(syscmd); + ICCPD_LOG_NOTICE(__FUNCTION__, " %s ret = %d", syscmd, ret); + } + + return; +} + +/***************************************** +* Peer connect/disconnect handler +* +* ***************************************/ +void mlacp_peer_conn_handler(struct CSM* csm) +{ + struct LocalInterface *lif = NULL; + static int once_connected = 0; + struct System* sys = NULL; + + if (!csm) + return; + + if ((sys = system_get_instance()) == NULL) + return; + + if (csm->warm_reboot_disconn_time != 0) + { + /*If peer reconnected, reset peer disconnect time*/ + csm->warm_reboot_disconn_time = 0; + ICCPD_LOG_NOTICE(__FUNCTION__, "Peer warm reboot and reconnect, reset peer disconnect time!"); + } + + if (csm->peer_link_if) + { + set_peerlink_mlag_port_learn(csm->peer_link_if, 0); + } + + /*If peer connect again, don't flush FDB*/ + if (once_connected == 0) + { + once_connected = 1; + mlacp_fix_bridge_mac(csm); + /*If warm reboot, don't flush FDB*/ + if (sys->warmboot_start != WARM_REBOOT) + mlacp_clean_fdb(); + } + + iccp_get_fdb_change_from_syncd(); + sys->csm_trans_time = time(NULL); + + mlacp_conn_handler_fdb(csm); + + LIST_FOREACH(lif, &(MLACP(csm).lif_list), mlacp_next) + { + if (lif->type == IF_T_PORT_CHANNEL) + { + mlacp_portchannel_state_handler(csm, lif, (lif->state == PORT_STATE_UP) ? 1 : 0); + } + } + + return; +} + +extern void recover_if_ipmac_on_standby(struct LocalInterface* lif_po); +void mlacp_peer_disconn_handler(struct CSM* csm) +{ + uint8_t null_mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + struct LocalInterface* lif = NULL; + struct Msg* msg = NULL; + struct MACMsg* mac_msg = NULL; + struct System* sys = NULL; + + if (!csm) + return; + + if ((sys = system_get_instance()) == NULL) + return; + + /*If warm reboot, don't change FDB and MAC address*/ + if (sys->warmboot_exit == WARM_REBOOT) + return; + + /*If peer is warm reboot, don't change FDB*/ + if (csm->peer_warm_reboot_time != 0) + { + /*If peer disconnected, recover peer to normal reboot for next time*/ + csm->peer_warm_reboot_time = 0; + /*peer connection must be establised again within 90s + from last disconnection for peer warm reboot*/ + time(&csm->warm_reboot_disconn_time); + ICCPD_LOG_NOTICE(__FUNCTION__, "Peer warm reboot and disconnect, recover to normal reboot for next time!"); + return; + } + + TAILQ_FOREACH(msg, &MLACP(csm).mac_list, tail) + { + mac_msg = (struct MACMsg*)msg->buf; + + mac_msg->age_flag |= MAC_AGE_PEER; + ICCPD_LOG_DEBUG(__FUNCTION__, "Add peer age flag: %s, MAC %s vlan-id %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); + + /* find the MAC that the port is peer-link or local and peer both aged, to be deleted*/ + if (strcmp(mac_msg->ifname, csm->peer_itf_name) != 0 && mac_msg->age_flag != (MAC_AGE_LOCAL | MAC_AGE_PEER)) + continue; + + ICCPD_LOG_NOTICE(__FUNCTION__, "Peer disconnect, del MAC for peer-link: %s, MAC %s vlan-id %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); + + /*Send mac del message to mclagsyncd, may be already deleted*/ + del_mac_from_chip(mac_msg); + + TAILQ_REMOVE(&(MLACP(csm).mac_list), msg, tail); + free(msg->buf); + free(msg); + } + + /* Clean all port block*/ + peerlink_port_isolate_cleanup(csm); + + memcpy(MLACP(csm).remote_system.system_id, null_mac, ETHER_ADDR_LEN); + + /*If peer is disconnected, recover the MAC address.*/ + if (csm->role_type == STP_ROLE_STANDBY) + { + LIST_FOREACH(lif, &(MLACP(csm).lif_list), mlacp_next) + { + recover_if_ipmac_on_standby(lif); + } + } + + return; +} + +void mlacp_peerlink_up_handler(struct CSM* csm) +{ + struct Msg* msg = NULL; + struct MACMsg* mac_msg = NULL; + + if (!csm) + return; + + /*If peer link up, set all the mac that point to the peer-link in ASIC*/ + TAILQ_FOREACH(msg, &MLACP(csm).mac_list, tail) + { + mac_msg = (struct MACMsg*)msg->buf; + + /* Find the MAC that the port is peer-link to be added*/ + if (strcmp(mac_msg->ifname, csm->peer_itf_name) != 0) + continue; + + ICCPD_LOG_NOTICE(__FUNCTION__, "Peer link up, add MAC to ASIC for peer-link: %s, MAC %s vlan-id %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); + + /*Send mac add message to mclagsyncd, local age flag is already set*/ + add_mac_to_chip(mac_msg, MAC_TYPE_DYNAMIC); + } + + return; +} + +void mlacp_peerlink_down_handler(struct CSM* csm) +{ + struct Msg* msg = NULL; + struct MACMsg* mac_msg = NULL; + + if (!csm) + return; + + /*If peer link down, remove all the mac that point to the peer-link*/ + TAILQ_FOREACH(msg, &MLACP(csm).mac_list, tail) + { + mac_msg = (struct MACMsg*)msg->buf; + + /* Find the MAC that the port is peer-link to be deleted*/ + if (strcmp(mac_msg->ifname, csm->peer_itf_name) != 0) + continue; + + ICCPD_LOG_NOTICE(__FUNCTION__, "Peer link down, del MAC for peer-link: %s, MAC %s vlan-id %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); + + mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 1); + + /*Send mac del message to mclagsyncd*/ + del_mac_from_chip(mac_msg); + + /*If peer is not age, keep the MAC in mac_list, but ASIC is deleted*/ + if (mac_msg->age_flag == (MAC_AGE_LOCAL | MAC_AGE_PEER)) + { + /*If local and peer both aged, del the mac*/ + TAILQ_REMOVE(&(MLACP(csm).mac_list), msg, tail); + free(msg->buf); + free(msg); + } + } + + return; +} + +/***************************************** +* Po add/remove handler +* +*****************************************/ +void mlacp_mlag_link_add_handler(struct CSM *csm, struct LocalInterface *lif) +{ + if (!csm || !lif) + return; + if (MLACP(csm).current_state != MLACP_STATE_EXCHANGE) + return; + + set_peerlink_mlag_port_isolate(csm, lif, 1); + + return; +} + +void mlacp_mlag_link_del_handler(struct CSM *csm, struct LocalInterface *lif) +{ + if (!csm || !lif) + return; + + if (MLACP(csm).current_state != MLACP_STATE_EXCHANGE) + return; + + set_peerlink_mlag_port_isolate(csm, lif, 0); + + return; +} + +int iccp_connect_syncd() +{ + struct System* sys = NULL; + int ret = 0; + int fd = 0; + struct sockaddr_in serv; + static int count = 0; + struct epoll_event event; + + if ((sys = system_get_instance()) == NULL) + goto conn_fail; + + if (sys->sync_fd >= 0) + return 0; + + /*Print the fail log message every 60s*/ + if (count >= 600) + { + count = 0; + } + + fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd < 0) + { + if (count == 0) + ICCPD_LOG_WARN(__FUNCTION__, "Failed to create unix socket: %s", strerror(errno)); + goto conn_fail; + } + + /* Make server socket. */ + memset(&serv, 0, sizeof(serv)); + serv.sin_family = AF_INET; + serv.sin_port = htons(2626); +#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN + serv.sin_len = sizeof(struct sockaddr_in); +#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ + serv.sin_addr.s_addr = htonl(0x7f000006); + + ret = connect(fd, (struct sockaddr *)&serv, sizeof(serv)); + if (ret < 0) + { + if (count == 0) + ICCPD_LOG_WARN(__FUNCTION__, "Failed to connect to mclag syncd: errno str %s", strerror(errno)); + close(fd); + goto conn_fail; + } + + ICCPD_LOG_NOTICE(__FUNCTION__, "Success to link syncd"); + sys->sync_fd = fd; + + event.data.fd = fd; + event.events = EPOLLIN; + ret = epoll_ctl(sys->epoll_fd, EPOLL_CTL_ADD, fd, &event); + + count = 0; + return 0; + + conn_fail: + if (count == 0) + ICCPD_LOG_DEBUG(__FUNCTION__, "Mclag syncd socket connect fail"); + + count++; + + return MCLAG_ERROR; +} + +void syncd_info_close() +{ + struct System* sys = NULL; + + if ((sys = system_get_instance()) == NULL) + return; + + if (sys->sync_fd > 0) + { + close(sys->sync_fd); + sys->sync_fd = -1; + } + + return; +} + +int iccp_get_receive_fdb_sock_fd(struct System *sys) +{ + return sys->sync_fd; +} + +/*When received MAC add and del packets from mclagsyncd, update mac information*/ +void do_mac_update_from_syncd(char mac_str[ETHER_ADDR_STR_LEN], uint16_t vid, char *ifname, uint8_t fdb_type, uint8_t op_type) +{ + struct System *sys = NULL; + struct CSM *csm = NULL; + struct Msg *msg = NULL; + struct MACMsg *mac_msg = NULL, *mac_info = NULL; + uint8_t mac_exist = 0; + char buf[MAX_BUFSIZE]; + size_t msg_len = 0; + uint8_t from_mclag_intf = 0;/*0: orphan port, 1: MCLAG port*/ + struct CSM *first_csm = NULL; + + struct LocalInterface *lif_po = NULL, *mac_lif = NULL; + + if (!(sys = system_get_instance())) + return; + + /* create MAC msg*/ + memset(buf, 0, MAX_BUFSIZE); + msg_len = sizeof(struct MACMsg); + mac_msg = (struct MACMsg*)buf; + mac_msg->op_type = op_type; + mac_msg->fdb_type = fdb_type; + sprintf(mac_msg->mac_str, "%s", mac_str); + mac_msg->vid = vid; + + mac_msg->age_flag = 0; + + ICCPD_LOG_NOTICE(__FUNCTION__, "Recv MAC msg from mclagsyncd, vid %d mac %s port %s optype %s ", vid, mac_str, ifname, op_type == MAC_SYNC_ADD ? "add" : "del"); + + /* Find MLACP itf, may be mclag enabled port-channel*/ + LIST_FOREACH(csm, &(sys->csm_list), next) + { + if (csm && !first_csm) + { + /*Record the first CSM, only one CSM in the system currently*/ + first_csm = csm; + } + + /*If MAC is from peer-link, break; peer-link is not in MLACP(csm).lif_list*/ + if (strcmp(ifname, csm->peer_itf_name) == 0) + break; + + LIST_FOREACH(lif_po, &(MLACP(csm).lif_list), mlacp_next) + { + if (lif_po->type != IF_T_PORT_CHANNEL) + continue; + + if (strcmp(lif_po->name, ifname) == 0) + { + from_mclag_intf = 1; + break; + } + } + + if (from_mclag_intf == 1) + break; + } + + if (!first_csm) + return; + + /*If support multiple CSM, the MAC list of orphan port must be moved to sys->mac_list*/ + csm = first_csm; + + /* find lif MAC+vid*/ + TAILQ_FOREACH(msg, &MLACP(csm).mac_list, tail) + { + mac_info = (struct MACMsg*)msg->buf; + + /*MAC and vid are equal*/ + if (strcmp(mac_info->mac_str, mac_str) == 0 && mac_info->vid == vid) + { + mac_exist = 1; + break; + } + } + + /*handle mac add*/ + if (op_type == MAC_SYNC_ADD) + { + /* Find local itf*/ + if (!(mac_lif = local_if_find_by_name(ifname))) + return; + + sprintf(mac_msg->ifname, "%s", ifname); + sprintf(mac_msg->origin_ifname, "%s", ifname); + + /*same MAC exist*/ + if (mac_exist) + { + /*If the recv mac port is peer-link, that is add from iccpd, no need to handle*/ + if (strcmp(csm->peer_itf_name, mac_msg->ifname) == 0) + { + return; + } + + /*If the current mac port is peer-link, it will handle by port up event*/ + /*if(strcmp(csm->peer_itf_name, mac_info->ifname) == 0) + { + return; + }*/ + + /* update MAC*/ + if (mac_info->fdb_type != mac_msg->fdb_type + || strcmp(mac_info->ifname, mac_msg->ifname) != 0 + || strcmp(mac_info->origin_ifname, mac_msg->ifname) != 0) + { + mac_info->fdb_type = mac_msg->fdb_type; + sprintf(mac_info->ifname, "%s", mac_msg->ifname); + sprintf(mac_info->origin_ifname, "%s", mac_msg->ifname); + + /*Remove MAC_AGE_LOCAL flag*/ + mac_info->age_flag = set_mac_local_age_flag(csm, mac_info, 0); + + ICCPD_LOG_DEBUG(__FUNCTION__, "Update MAC for %s, ifname %s", mac_msg->mac_str, mac_msg->ifname); + } + else + { + /*All info are the same, Remove MAC_AGE_LOCAL flag, then return*/ + /*In theory, this will be happened that mac age and then learn*/ + mac_info->age_flag = set_mac_local_age_flag(csm, mac_info, 0); + + return; + } + } + else/*same MAC not exist*/ + { + /*If the port the mac learn is change to down before the mac + sync to iccp, this mac must be deleted */ + if (mac_lif->state == PORT_STATE_DOWN) + { + del_mac_from_chip(mac_msg); + + return; + } + + /*set MAC_AGE_PEER flag before send this item to peer*/ + mac_msg->age_flag |= MAC_AGE_PEER; + /*ICCPD_LOG_DEBUG(__FUNCTION__, "Add peer age flag: %s, add %s vlan-id %d, age_flag %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->age_flag);*/ + mac_msg->op_type = MAC_SYNC_ADD; + + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + struct Msg *msg_send = NULL; + if (iccp_csm_init_msg(&msg_send, (char*)mac_msg, msg_len) == 0) + { + mac_msg->age_flag &= ~MAC_AGE_PEER; + TAILQ_INSERT_TAIL(&(MLACP(csm).mac_msg_list), msg_send, tail); + + /*ICCPD_LOG_DEBUG(__FUNCTION__, "MAC-msg-list enqueue: %s, add %s vlan-id %d, age_flag %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->age_flag);*/ + } + else + { + ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue MAC-msg-list: %s, MAC %s vlan-id %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); + } + } + + /*enqueue mac to mac-list*/ + if (iccp_csm_init_msg(&msg, (char*)mac_msg, msg_len) == 0) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).mac_list), msg, tail); + + /*ICCPD_LOG_DEBUG(__FUNCTION__, "MAC-list enqueue: %s, add %s vlan-id %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid);*/ + } + else + ICCPD_LOG_DEBUG(__FUNCTION__, "Failed to enqueue MAC %s, MAC %s vlan-id %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); + } + } + else/*handle mac del*/ + { + /*same MAC exist*/ + if (mac_exist) + { + /*orphan port mac or origin from_mclag_intf but state is down*/ + if (strcmp(mac_info->ifname, csm->peer_itf_name) == 0) + { + /*Set MAC_AGE_LOCAL flag*/ + mac_info->age_flag = set_mac_local_age_flag(csm, mac_info, 1); + + if (mac_info->age_flag == (MAC_AGE_LOCAL | MAC_AGE_PEER)) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "Recv MAC del msg: %s(peer-link), del %s vlan-id %d", + mac_info->ifname, mac_info->mac_str, mac_info->vid); + + /*If peer link is down, del the mac*/ + TAILQ_REMOVE(&(MLACP(csm).mac_list), msg, tail); + free(msg->buf); + free(msg); + } + else if (csm->peer_link_if && csm->peer_link_if->state != PORT_STATE_DOWN) + { + /*peer-link learn mac is control by iccpd, ignore the chip del info*/ + add_mac_to_chip(mac_info, MAC_TYPE_DYNAMIC); + + ICCPD_LOG_NOTICE(__FUNCTION__, "Recv MAC del msg: %s(peer-link is up), add back %s vlan-id %d", + mac_info->ifname, mac_info->mac_str, mac_info->vid); + } + + return; + } + + /*Add MAC_AGE_LOCAL flag*/ + mac_info->age_flag = set_mac_local_age_flag(csm, mac_info, 1); + + if (mac_info->age_flag == (MAC_AGE_LOCAL | MAC_AGE_PEER)) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "Recv MAC del msg: %s, del %s vlan-id %d", + mac_info->ifname, mac_info->mac_str, mac_info->vid); + + /*If local and peer both aged, del the mac (local orphan mac is here)*/ + TAILQ_REMOVE(&(MLACP(csm).mac_list), msg, tail); + free(msg->buf); + free(msg); + } + else + { + ICCPD_LOG_NOTICE(__FUNCTION__, "Recv MAC del msg: %s, del %s vlan-id %d, peer is not age, add back to chip", + mac_info->ifname, mac_info->mac_str, mac_info->vid); + + mac_info->fdb_type = MAC_TYPE_DYNAMIC; + + if (from_mclag_intf && lif_po && lif_po->state == PORT_STATE_DOWN) + { + /*If local if is down, redirect the mac to peer-link*/ + if (strlen(csm->peer_itf_name) != 0) + { + memcpy(&mac_info->ifname, csm->peer_itf_name, IFNAMSIZ); + + if (csm->peer_link_if && csm->peer_link_if->state == PORT_STATE_UP) + { + add_mac_to_chip(mac_info, MAC_TYPE_DYNAMIC); + ICCPD_LOG_NOTICE(__FUNCTION__, "Recv MAC del msg: %s(down), del %s vlan-id %d, redirect to peer-link", + mac_info->ifname, mac_info->mac_str, mac_info->vid); + } + } + + return; + } + + /*If local is aged but peer is not aged, Send mac add message to mclagsyncd*/ + /*it is from_mclag_intf and port state is up, local orphan mac can not be here*/ + /* Find local itf*/ + if (!(mac_lif = local_if_find_by_name(mac_info->ifname))) + return; + if (mac_lif->state == PORT_STATE_UP) + add_mac_to_chip(mac_info, MAC_TYPE_DYNAMIC); + } + } + } + + return; +} + +int iccp_receive_fdb_handler_from_syncd(struct System *sys) +{ + char *msg_buf = g_csm_buf; + struct IccpSyncdHDr *msg_hdr; + struct mclag_fdb_info * mac_info; + size_t pos = 0; + int count = 0; + int i = 0; + int n = 0; + + if (sys == NULL) + return MCLAG_ERROR; + + memset(msg_buf, 0, CSM_BUFFER_SIZE); + + n = read(sys->sync_fd, msg_buf, CSM_BUFFER_SIZE); + if (n <= 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "read msg error!!!" ); + return MCLAG_ERROR; + } + + while (pos < n) + { + msg_hdr = (struct IccpSyncdHDr *)&msg_buf[pos]; + if (msg_hdr->ver != 1 || msg_hdr->type != MCLAG_SYNCD_MSG_TYPE_FDB_OPERATION ) + { + ICCPD_LOG_ERR(__FUNCTION__, "msg version or type wrong!!!!! "); + return MCLAG_ERROR; + } + + count = ( msg_hdr->len - sizeof(struct IccpSyncdHDr )) / sizeof(struct mclag_fdb_info); + ICCPD_LOG_DEBUG(__FUNCTION__, "recv msg fdb count %d ", count); + + for (i = 0; i < count; i++) + { + mac_info = (struct mclag_fdb_info *)&msg_buf[pos + sizeof(struct IccpSyncdHDr ) + i * sizeof(struct mclag_fdb_info)]; + /*ICCPD_LOG_DEBUG(__FUNCTION__, "recv msg fdb count %d vid %d mac %s port %s optype %s ", i, mac_info->vid, mac_info->mac, mac_info->port_name, mac_info->op_type == MAC_SYNC_ADD ? "add" : "del");*/ + do_mac_update_from_syncd(mac_info->mac, mac_info->vid, mac_info->port_name, mac_info->type, mac_info->op_type); + } + + pos += msg_hdr->len; + } + + return 0; +} + +char * mclagd_ctl_cmd_str(int req_type) +{ + switch (req_type) + { + case INFO_TYPE_DUMP_STATE: + return "dump config"; + + case INFO_TYPE_DUMP_ARP: + return "dump arp"; + + case INFO_TYPE_DUMP_NDISC: + return "dump nd"; + + case INFO_TYPE_DUMP_MAC: + return "dump mac"; + + case INFO_TYPE_DUMP_LOCAL_PORTLIST: + return "dump local portlist"; + + case INFO_TYPE_DUMP_PEER_PORTLIST: + return "dump peer portlist"; + + case INFO_TYPE_CONFIG_LOGLEVEL: + return "config loglevel"; + default: + break; + } + + return "error req type"; +} + +int mclagd_ctl_sock_create() +{ + struct sockaddr_un addr; + struct System* sys = NULL; + struct epoll_event event; + int addr_len; + int ret = 0; + + if ((sys = system_get_instance()) == NULL) + return MCLAG_ERROR; + + if (sys->sync_ctrl_fd > 0) + return sys->sync_ctrl_fd; + + sys->sync_ctrl_fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (sys->sync_ctrl_fd < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "Failed to create mclagd ctl sock"); + return sys->sync_ctrl_fd; + } + + unlink(sys->mclagdctl_file_path); + + memset((void*)&addr, 0, sizeof(struct sockaddr_un)); + addr.sun_family = AF_UNIX; + snprintf(addr.sun_path, 107, "%s", sys->mclagdctl_file_path); + addr_len = sizeof(addr.sun_family) + strlen(sys->mclagdctl_file_path); + + if ((ret = bind(sys->sync_ctrl_fd, (struct sockaddr*)&addr, addr_len)) < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "Failed to bind mclagd ctl socket %s:%s", sys->mclagdctl_file_path, strerror(errno)); + close(sys->sync_ctrl_fd); + return MCLAG_ERROR; + } + + if (listen(sys->sync_ctrl_fd, 5) < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "Failed to listen unix mclagd ctl socket%s:%s", sys->mclagdctl_file_path, strerror(errno)); + close(sys->sync_ctrl_fd); + return MCLAG_ERROR; + } + + event.data.fd = sys->sync_ctrl_fd; + event.events = EPOLLIN; + epoll_ctl(sys->epoll_fd, EPOLL_CTL_ADD, sys->sync_ctrl_fd, &event); + FD_SET(sys->sync_ctrl_fd, &(sys->readfd)); + sys->readfd_count++; + + return sys->sync_ctrl_fd; +} + +int mclagd_ctl_sock_accept(int fd) +{ + struct sockaddr_in client_addr; + int client_fd = 0; + unsigned int addr_len = 0; + + client_fd = accept(fd, (struct sockaddr*)&client_addr, &addr_len); + if (client_fd < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "Failed to accept a client from mclagdctl"); + return MCLAG_ERROR; + } + + return client_fd; +} + +int mclagd_ctl_sock_read(int fd, char *r_buf, int total_len) +{ + int read_len = 0; + int ret = 0; + struct timeval tv = { 0 }; + fd_set read_fd; + + while (read_len < total_len) + { + FD_ZERO(&read_fd); + FD_SET(fd, &read_fd); + tv.tv_sec = 5; + tv.tv_usec = 0; + + switch ((ret = select(fd + 1, &read_fd, NULL, NULL, &tv))) + { + case -1: + /* error*/ + case 0: + /* timeout*/ + return MCLAG_ERROR; + + default: + break; + } + + if (FD_ISSET(fd, &read_fd)) + ret = read(fd, r_buf + read_len, total_len - read_len); + if (ret <= 0) + { + return MCLAG_ERROR; + } + read_len += ret; + } + + return read_len; +} + +int mclagd_ctl_sock_write(int fd, char *w_buf, int total_len) +{ + int write_len = 0; + int ret = 0; + + while (write_len < total_len) + { + ret = write(fd, w_buf + write_len, total_len - write_len); + if (ret <= 0) + { + return 0; + } + write_len += ret; + } + + return write_len; +} + +void mclagd_ctl_handle_dump_state(int client_fd, int mclag_id) +{ + char * Pbuf = NULL; + char buf[512] = { 0 }; + int state_num = 0; + int ret = 0; + struct mclagd_reply_hdr *hd = NULL; + int len_tmp = 0; + + ret = iccp_mclag_config_dump(&Pbuf, &state_num, mclag_id); + if (ret != EXEC_TYPE_SUCCESS) + { + len_tmp = sizeof(struct mclagd_reply_hdr); + memcpy(buf, &len_tmp, sizeof(int)); + hd = (struct mclagd_reply_hdr *)(buf + sizeof(int)); + hd->exec_result = ret; + hd->info_type = INFO_TYPE_DUMP_STATE; + hd->data_len = 0; + mclagd_ctl_sock_write(client_fd, buf, MCLAGD_REPLY_INFO_HDR); + + if (Pbuf) + free(Pbuf); + + return; + } + hd = (struct mclagd_reply_hdr *)(Pbuf + sizeof(int)); + hd->exec_result = EXEC_TYPE_SUCCESS; + hd->info_type = INFO_TYPE_DUMP_STATE; + hd->data_len = state_num * sizeof(struct mclagd_state); + + len_tmp = (hd->data_len + sizeof(struct mclagd_reply_hdr)); + memcpy(Pbuf, &len_tmp, sizeof(int)); + mclagd_ctl_sock_write(client_fd, Pbuf, MCLAGD_REPLY_INFO_HDR + hd->data_len); + + if (Pbuf) + free(Pbuf); + + return; +} + +void mclagd_ctl_handle_dump_arp(int client_fd, int mclag_id) +{ + char * Pbuf = NULL; + char buf[512] = { 0 }; + int arp_num = 0; + int ret = 0; + struct mclagd_reply_hdr *hd = NULL; + int len_tmp = 0; + + ret = iccp_arp_dump(&Pbuf, &arp_num, mclag_id); + if (ret != EXEC_TYPE_SUCCESS) + { + len_tmp = sizeof(struct mclagd_reply_hdr); + memcpy(buf, &len_tmp, sizeof(int)); + hd = (struct mclagd_reply_hdr *)(buf + sizeof(int)); + hd->exec_result = ret; + hd->info_type = INFO_TYPE_DUMP_ARP; + hd->data_len = 0; + mclagd_ctl_sock_write(client_fd, buf, MCLAGD_REPLY_INFO_HDR); + + if (Pbuf) + free(Pbuf); + + return; + } + + hd = (struct mclagd_reply_hdr *)(Pbuf + sizeof(int)); + hd->exec_result = EXEC_TYPE_SUCCESS; + hd->info_type = INFO_TYPE_DUMP_ARP; + hd->data_len = arp_num * sizeof(struct mclagd_arp_msg); + len_tmp = (hd->data_len + sizeof(struct mclagd_reply_hdr)); + memcpy(Pbuf, &len_tmp, sizeof(int)); + mclagd_ctl_sock_write(client_fd, Pbuf, MCLAGD_REPLY_INFO_HDR + hd->data_len); + + if (Pbuf) + free(Pbuf); + + return; +} + +void mclagd_ctl_handle_dump_ndisc(int client_fd, int mclag_id) +{ + char *Pbuf = NULL; + char buf[512] = { 0 }; + int ndisc_num = 0; + int ret = 0; + struct mclagd_reply_hdr *hd = NULL; + int len_tmp = 0; + + ret = iccp_ndisc_dump(&Pbuf, &ndisc_num, mclag_id); + if (ret != EXEC_TYPE_SUCCESS) + { + len_tmp = sizeof(struct mclagd_reply_hdr); + memcpy(buf, &len_tmp, sizeof(int)); + hd = (struct mclagd_reply_hdr *)(buf + sizeof(int)); + hd->exec_result = ret; + hd->info_type = INFO_TYPE_DUMP_NDISC; + hd->data_len = 0; + mclagd_ctl_sock_write(client_fd, buf, MCLAGD_REPLY_INFO_HDR); + + if (Pbuf) + free(Pbuf); + + return; + } + + hd = (struct mclagd_reply_hdr *)(Pbuf + sizeof(int)); + hd->exec_result = EXEC_TYPE_SUCCESS; + hd->info_type = INFO_TYPE_DUMP_NDISC; + hd->data_len = ndisc_num * sizeof(struct mclagd_ndisc_msg); + len_tmp = (hd->data_len + sizeof(struct mclagd_reply_hdr)); + memcpy(Pbuf, &len_tmp, sizeof(int)); + mclagd_ctl_sock_write(client_fd, Pbuf, MCLAGD_REPLY_INFO_HDR + hd->data_len); + + if (Pbuf) + free(Pbuf); + + return; +} + +void mclagd_ctl_handle_dump_mac(int client_fd, int mclag_id) +{ + char * Pbuf = NULL; + char buf[512] = { 0 }; + int mac_num = 0; + int ret = 0; + struct mclagd_reply_hdr *hd = NULL; + int len_tmp = 0; + + ret = iccp_mac_dump(&Pbuf, &mac_num, mclag_id); + if (ret != EXEC_TYPE_SUCCESS) + { + len_tmp = sizeof(struct mclagd_reply_hdr); + memcpy(buf, &len_tmp, sizeof(int)); + hd = (struct mclagd_reply_hdr *)(buf + sizeof(int)); + hd->exec_result = ret; + hd->info_type = INFO_TYPE_DUMP_MAC; + hd->data_len = 0; + mclagd_ctl_sock_write(client_fd, buf, MCLAGD_REPLY_INFO_HDR); + + if (Pbuf) + free(Pbuf); + + return; + } + + hd = (struct mclagd_reply_hdr *)(Pbuf + sizeof(int)); + hd->exec_result = EXEC_TYPE_SUCCESS; + hd->info_type = INFO_TYPE_DUMP_MAC; + hd->data_len = mac_num * sizeof(struct mclagd_mac_msg); + + len_tmp = (hd->data_len + sizeof(struct mclagd_reply_hdr)); + memcpy(Pbuf, &len_tmp, sizeof(int)); + + mclagd_ctl_sock_write(client_fd, Pbuf, MCLAGD_REPLY_INFO_HDR + hd->data_len); + + if (Pbuf) + free(Pbuf); + + return; +} + +void mclagd_ctl_handle_dump_local_portlist(int client_fd, int mclag_id) +{ + char * Pbuf = NULL; + char buf[512] = { 0 }; + int lif_num = 0;; + int ret = 0; + struct mclagd_reply_hdr *hd = NULL; + int len_tmp = 0; + + ret = iccp_local_if_dump(&Pbuf, &lif_num, mclag_id); + if (ret != EXEC_TYPE_SUCCESS) + { + len_tmp = sizeof(struct mclagd_reply_hdr); + memcpy(buf, &len_tmp, sizeof(int)); + hd = (struct mclagd_reply_hdr *)(buf + sizeof(int)); + hd->exec_result = ret; + hd->info_type = INFO_TYPE_DUMP_LOCAL_PORTLIST; + hd->data_len = 0; + mclagd_ctl_sock_write(client_fd, buf, MCLAGD_REPLY_INFO_HDR); + + if (Pbuf) + free(Pbuf); + + return; + } + + hd = (struct mclagd_reply_hdr *)(Pbuf + sizeof(int)); + hd->exec_result = EXEC_TYPE_SUCCESS; + hd->info_type = INFO_TYPE_DUMP_LOCAL_PORTLIST; + hd->data_len = lif_num * sizeof(struct mclagd_local_if); + len_tmp = (hd->data_len + sizeof(struct mclagd_reply_hdr)); + memcpy(Pbuf, &len_tmp, sizeof(int)); + mclagd_ctl_sock_write(client_fd, Pbuf, MCLAGD_REPLY_INFO_HDR + hd->data_len); + + if (Pbuf) + free(Pbuf); + + return; +} + +void mclagd_ctl_handle_dump_peer_portlist(int client_fd, int mclag_id) +{ + char * Pbuf = NULL; + char buf[512] = { 0 }; + int pif_num = 0; + int ret = 0; + struct mclagd_reply_hdr *hd = NULL; + int len_tmp = 0; + + ret = iccp_peer_if_dump(&Pbuf, &pif_num, mclag_id); + if (ret != EXEC_TYPE_SUCCESS) + { + len_tmp = sizeof(struct mclagd_reply_hdr); + memcpy(buf, &len_tmp, sizeof(int)); + hd = (struct mclagd_reply_hdr *)(buf + sizeof(int)); + hd->exec_result = ret; + hd->info_type = INFO_TYPE_DUMP_PEER_PORTLIST; + hd->data_len = 0; + mclagd_ctl_sock_write(client_fd, buf, MCLAGD_REPLY_INFO_HDR); + + if (Pbuf) + free(Pbuf); + + return; + } + + hd = (struct mclagd_reply_hdr *)(Pbuf + sizeof(int)); + hd->exec_result = EXEC_TYPE_SUCCESS; + hd->info_type = INFO_TYPE_DUMP_PEER_PORTLIST; + hd->data_len = pif_num * sizeof(struct mclagd_peer_if); + len_tmp = (hd->data_len + sizeof(struct mclagd_reply_hdr)); + memcpy(Pbuf, &len_tmp, sizeof(int)); + mclagd_ctl_sock_write(client_fd, Pbuf, MCLAGD_REPLY_INFO_HDR + hd->data_len); + + if (Pbuf) + free(Pbuf); + + return; +} + +void mclagd_ctl_handle_config_loglevel(int client_fd, int log_level) +{ + char buf[sizeof(struct mclagd_reply_hdr)+sizeof(int)]; + struct mclagd_reply_hdr *hd = NULL; + int len_tmp = 0; + + logger_set_configuration(log_level); + + len_tmp = sizeof(struct mclagd_reply_hdr); + memcpy(buf, &len_tmp, sizeof(int)); + hd = (struct mclagd_reply_hdr *)(buf + sizeof(int)); + hd->exec_result = EXEC_TYPE_SUCCESS; + hd->info_type = INFO_TYPE_CONFIG_LOGLEVEL; + hd->data_len = 0; + mclagd_ctl_sock_write(client_fd, buf, MCLAGD_REPLY_INFO_HDR); + + return; +} + +int mclagd_ctl_interactive_process(int client_fd) +{ + char buf[512] = { 0 }; + int ret = 0; + + struct mclagdctl_req_hdr* req = NULL; + + if (client_fd < 0) + return MCLAG_ERROR; + + ret = mclagd_ctl_sock_read(client_fd, buf, sizeof(struct mclagdctl_req_hdr)); + + if (ret < 0) + return MCLAG_ERROR; + + req = (struct mclagdctl_req_hdr*)buf; + + ICCPD_LOG_DEBUG(__FUNCTION__, "Receive request %s from mclagdctl", mclagd_ctl_cmd_str(req->info_type)); + + switch (req->info_type) + { + case INFO_TYPE_DUMP_STATE: + mclagd_ctl_handle_dump_state(client_fd, req->mclag_id); + break; + + case INFO_TYPE_DUMP_ARP: + mclagd_ctl_handle_dump_arp(client_fd, req->mclag_id); + break; + + case INFO_TYPE_DUMP_NDISC: + mclagd_ctl_handle_dump_ndisc(client_fd, req->mclag_id); + break; + + case INFO_TYPE_DUMP_MAC: + mclagd_ctl_handle_dump_mac(client_fd, req->mclag_id); + break; + + case INFO_TYPE_DUMP_LOCAL_PORTLIST: + mclagd_ctl_handle_dump_local_portlist(client_fd, req->mclag_id); + break; + + case INFO_TYPE_DUMP_PEER_PORTLIST: + mclagd_ctl_handle_dump_peer_portlist(client_fd, req->mclag_id); + break; + + case INFO_TYPE_CONFIG_LOGLEVEL: + mclagd_ctl_handle_config_loglevel(client_fd, req->mclag_id); + break; + + default: + return MCLAG_ERROR; + } + + return 0; +} + + diff --git a/src/iccpd/src/mlacp_sync_prepare.c b/src/iccpd/src/mlacp_sync_prepare.c new file mode 100644 index 000000000000..ef1cd244a90a --- /dev/null +++ b/src/iccpd/src/mlacp_sync_prepare.c @@ -0,0 +1,677 @@ +/* + * MLACP Sync Infomation Preparation + * mlacp_sync_prepare.c + + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + * + */ + +#include +#include + +#include + +#include "../include/system.h" +#include "../include/logger.h" +#include "../include/mlacp_fsm.h" +#include "../include/mlacp_tlv.h" +#include "../include/mlacp_link_handler.h" +#include "../include/iccp_ifm.h" +#include "../include/iccp_csm.h" + +/***************************************** +* Static Function +* +* ***************************************/ +static int mlacp_fill_icc_header(struct CSM* csm, ICCHdr* icc_hdr, size_t msg_len); + +/***************************************** +* Create Sync Request TLV +* +* ***************************************/ +int mlacp_prepare_for_sync_request_tlv(struct CSM* csm, char* buf, size_t max_buf_size) +{ + struct System* sys = NULL; + ICCHdr* icc_hdr = NULL; + mLACPSyncReqTLV* tlv = NULL; + size_t msg_len = sizeof(ICCHdr) + sizeof(mLACPSyncReqTLV); + + if (csm == NULL) + return MCLAG_ERROR; + + if (buf == NULL) + return MCLAG_ERROR; + + if (msg_len > max_buf_size) + return MCLAG_ERROR; + + if ((sys = system_get_instance()) == NULL) + return MCLAG_ERROR; + + /* Prepare for sync request */ + memset(buf, 0, max_buf_size); + + icc_hdr = (ICCHdr*)buf; + tlv = (mLACPSyncReqTLV*)&buf[sizeof(ICCHdr)]; + + /* ICC header */ + mlacp_fill_icc_header(csm, icc_hdr, msg_len); + + /* mLACP Synchronization Request TLV */ + tlv->icc_parameter.u_bit = 0; + tlv->icc_parameter.f_bit = 0; + tlv->icc_parameter.type = htons(TLV_T_MLACP_SYNC_REQUEST); + tlv->icc_parameter.len = htons(sizeof(mLACPSyncReqTLV) - sizeof(ICCParameter)); + + tlv->req_num = 0; + MLACP(csm).sync_req_num = 0; + + tlv->c_bit = 1; + tlv->s_bit = 1; + tlv->req_type = 0x3FFF; + *(uint16_t *)((uint8_t *)tlv + sizeof(ICCParameter) + sizeof(uint16_t)) = htons(*(uint16_t *)((uint8_t *)tlv + sizeof(ICCParameter) + sizeof(uint16_t))); + + tlv->port_num_agg_id = 0; + tlv->actor_key = 0; + + return msg_len; +} + +/***************************************** +* Prprare Sync Data TLV +* +* ***************************************/ +int mlacp_prepare_for_sync_data_tlv(struct CSM* csm, char* buf, size_t max_buf_size, int end) +{ + struct System* sys = NULL; + ICCHdr* icc_hdr = (ICCHdr*)buf; + mLACPSyncDataTLV* tlv = (mLACPSyncDataTLV*)&buf[sizeof(ICCHdr)]; + size_t msg_len = sizeof(ICCHdr) + sizeof(mLACPSyncDataTLV); + + if (csm == NULL) + return MCLAG_ERROR; + + if (buf == NULL) + return MCLAG_ERROR; + + if (msg_len > max_buf_size) + return MCLAG_ERROR; + + if ((sys = system_get_instance()) == NULL) + return MCLAG_ERROR; + + /* Prepare for sync request */ + memset(buf, 0, max_buf_size); + + icc_hdr = (ICCHdr*)buf; + tlv = (mLACPSyncDataTLV*)&buf[sizeof(ICCHdr)]; + + /* ICC header */ + mlacp_fill_icc_header(csm, icc_hdr, msg_len); + + /* mLACP Synchronization Data TLV */ + tlv->icc_parameter.u_bit = 0; + tlv->icc_parameter.f_bit = 0; + tlv->icc_parameter.type = htons(TLV_T_MLACP_SYNC_DATA); + tlv->icc_parameter.len = htons(sizeof(mLACPSyncDataTLV) - sizeof(ICCParameter)); + + tlv->req_num = htons(MLACP(csm).sync_req_num); + if (end == 0) + tlv->flags = 0x00; + else + tlv->flags = htons(0x01); + + return msg_len; +} + +/***************************************** +* Prprare Sync System-Config TLV +* +* ***************************************/ +int mlacp_prepare_for_sys_config(struct CSM* csm, char* buf, size_t max_buf_size) +{ + struct System* sys = NULL; + ICCHdr* icc_hdr = (ICCHdr*)buf; + mLACPSysConfigTLV* tlv = (mLACPSysConfigTLV*)&buf[sizeof(ICCHdr)]; + size_t msg_len = sizeof(ICCHdr) + sizeof(mLACPSysConfigTLV); + + if (csm == NULL) + return MCLAG_ERROR; + + if (buf == NULL) + return MCLAG_ERROR; + + if (msg_len > max_buf_size) + return MCLAG_ERROR; + + if ((sys = system_get_instance()) == NULL) + return MCLAG_ERROR; + + /* Prepare for sync request */ + memset(buf, 0, max_buf_size); + + icc_hdr = (ICCHdr*)buf; + tlv = (mLACPSysConfigTLV*)&buf[sizeof(ICCHdr)]; + + /* ICC header */ + mlacp_fill_icc_header(csm, icc_hdr, msg_len); + + /* System Config TLV */ + tlv->icc_parameter.u_bit = 0; + tlv->icc_parameter.f_bit = 0; + tlv->icc_parameter.type = htons(TLV_T_MLACP_SYSTEM_CONFIG); + tlv->icc_parameter.len = htons(sizeof(mLACPSysConfigTLV) - sizeof(ICCParameter)); + + memcpy(tlv->sys_id, MLACP(csm).system_id, ETHER_ADDR_LEN); + tlv->sys_priority = htons(MLACP(csm).system_priority); + tlv->node_id = MLACP(csm).node_id; + return msg_len; +} + +/*Prprare Sync AggPort-State TLV */ +int mlacp_prepare_for_Aggport_state(struct CSM* csm, char* buf, size_t max_buf_size, struct LocalInterface* local_if) +{ + struct System* sys = NULL; + ICCHdr* icc_hdr = (ICCHdr*)buf; + mLACPAggPortStateTLV* tlv = (mLACPAggPortStateTLV*)&buf[sizeof(ICCHdr)]; + size_t msg_len = sizeof(ICCHdr) + sizeof(mLACPAggPortStateTLV); + + if (csm == NULL) + return MCLAG_ERROR; + + if (buf == NULL) + return MCLAG_ERROR; + + if (local_if == NULL) + return MCLAG_ERROR; + + if (local_if->type != IF_T_PORT_CHANNEL) + return MCLAG_ERROR; + + if (msg_len > max_buf_size) + return MCLAG_ERROR; + + if ((sys = system_get_instance()) == NULL) + return MCLAG_ERROR; + + /* Prepare for sync request */ + memset(buf, 0, max_buf_size); + + icc_hdr = (ICCHdr*)buf; + tlv = (mLACPAggPortStateTLV*)&buf[sizeof(ICCHdr)]; + + /* ICC header */ + mlacp_fill_icc_header(csm, icc_hdr, msg_len); + + /* Port State TLV */ + tlv->icc_parameter.u_bit = 0; + tlv->icc_parameter.f_bit = 0; + tlv->icc_parameter.type = htons(TLV_T_MLACP_AGGREGATOR_STATE); + tlv->icc_parameter.len = htons(sizeof(mLACPAggPortStateTLV) - sizeof(ICCParameter)); + + tlv->partner_sys_priority = 0; + tlv->partner_key = 0; + tlv->agg_id = htons(local_if->po_id); + tlv->actor_key = 0; + tlv->agg_state = local_if->state; + + return msg_len; +} + +/***************************************** +* Prprare Sync Purge Port +* +* ***************************************/ +int mlacp_prepare_for_Aggport_config(struct CSM* csm, + char* buf, size_t max_buf_size, + struct LocalInterface* lif, int purge_flag) +{ + ICCHdr* icc_hdr = (ICCHdr*)buf; + mLACPAggConfigTLV* tlv = (mLACPAggConfigTLV*)&buf[sizeof(ICCHdr)]; + size_t msg_len = sizeof(ICCHdr) + sizeof(mLACPAggConfigTLV); + + if (csm == NULL) + return MCLAG_ERROR; + + if (buf == NULL) + return MCLAG_ERROR; + + if (msg_len > max_buf_size) + return MCLAG_ERROR; + + /* Prepare for sync request */ + memset(buf, 0, max_buf_size); + + icc_hdr = (ICCHdr*)buf; + tlv = (mLACPAggConfigTLV*)&buf[sizeof(ICCHdr)]; + + /* ICC header */ + mlacp_fill_icc_header(csm, icc_hdr, msg_len); + + /* Port Config TLV */ + tlv->icc_parameter.u_bit = 0; + tlv->icc_parameter.f_bit = 0; + tlv->icc_parameter.type = htons(TLV_T_MLACP_AGGREGATOR_CONFIG); + + tlv->icc_parameter.len = htons(sizeof(mLACPAggConfigTLV) - sizeof(ICCParameter)); + tlv->agg_id = htons(lif->po_id); + if (purge_flag == 1) + tlv->flags = 0x02; /*purge*/ + else + tlv->flags = 0x1; + tlv->agg_name_len = strlen(lif->name); + memcpy(tlv->agg_name, lif->name, MAX_L_PORT_NAME); + memcpy(tlv->mac_addr, lif->mac_addr, ETHER_ADDR_LEN); + + return msg_len; +} + +/***************************************** +* Preprare Sync MAC-Info TLV +* +* ***************************************/ +int mlacp_prepare_for_mac_info_to_peer(struct CSM* csm, char* buf, size_t max_buf_size, struct MACMsg* mac_msg, int count) +{ + struct mLACPMACInfoTLV* tlv = NULL; + size_t msg_len = 0; + size_t tlv_len = 0; + ICCHdr* icc_hdr = NULL; + struct mLACPMACData *MacData; + + if (!csm) + return MCLAG_ERROR; + if (!buf) + return MCLAG_ERROR; + + tlv_len = sizeof(struct mLACPMACInfoTLV) + sizeof(struct mLACPMACData) * (count + 1); + + if ((msg_len = sizeof(ICCHdr) + tlv_len) > max_buf_size) + return MCLAG_ERROR; + + /* ICC header */ + icc_hdr = (ICCHdr*)buf; + mlacp_fill_icc_header(csm, icc_hdr, msg_len); + /* Prepare for MAC information TLV */ + tlv = (struct mLACPMACInfoTLV*)&buf[sizeof(ICCHdr)]; + tlv->icc_parameter.len = htons(tlv_len - sizeof(ICCParameter)); + tlv->num_of_entry = htons(count + 1); + + if (count == 0) + { + tlv->icc_parameter.u_bit = 0; + tlv->icc_parameter.f_bit = 0; + tlv->icc_parameter.type = htons(TLV_T_MLACP_MAC_INFO); + } + + MacData = (struct mLACPMACData *)&buf[sizeof(ICCHdr) + sizeof(struct mLACPMACInfoTLV) + sizeof(struct mLACPMACData) * count]; + MacData->type = mac_msg->op_type; + sprintf(MacData->mac_str, "%s", mac_msg->mac_str); + sprintf(MacData->ifname, "%s", mac_msg->origin_ifname); + MacData->vid = htons(mac_msg->vid); + + ICCPD_LOG_NOTICE(__FUNCTION__, "Send MAC messge to peer, port %s mac = %s, vid = %d, type = %s count %d ", mac_msg->origin_ifname, + mac_msg->mac_str, mac_msg->vid, mac_msg->op_type == MAC_SYNC_ADD ? "add" : "del", count); + + return msg_len; +} + +/***************************************** +* Preprare Sync ARP-Info TLV +* +* ***************************************/ +int mlacp_prepare_for_arp_info(struct CSM* csm, char* buf, size_t max_buf_size, struct ARPMsg* arp_msg, int count) +{ + struct mLACPARPInfoTLV* tlv = NULL; + size_t msg_len = 0; + size_t tlv_len = 0; + ICCHdr* icc_hdr = NULL; + struct ARPMsg* ArpData; + + if (!csm) + return MCLAG_ERROR; + if (!buf) + return MCLAG_ERROR; + + tlv_len = sizeof(struct mLACPARPInfoTLV) + sizeof(struct ARPMsg) * (count + 1); + + if ((msg_len = sizeof(ICCHdr) + tlv_len) > max_buf_size) + return MCLAG_ERROR; + + /* ICC header */ + icc_hdr = (ICCHdr*)buf; + mlacp_fill_icc_header(csm, icc_hdr, msg_len); + + /* Prepare for ARP information TLV */ + tlv = (struct mLACPARPInfoTLV*)&buf[sizeof(ICCHdr)]; + tlv->icc_parameter.len = htons(tlv_len - sizeof(ICCParameter)); + tlv->num_of_entry = htons(count + 1); + + if (count == 0) + { + tlv->icc_parameter.u_bit = 0; + tlv->icc_parameter.f_bit = 0; + tlv->icc_parameter.type = htons(TLV_T_MLACP_ARP_INFO); + } + + ArpData = (struct ARPMsg *)&buf[sizeof(ICCHdr) + sizeof(struct mLACPARPInfoTLV) + sizeof(struct ARPMsg) * count]; + + ArpData->op_type = arp_msg->op_type; + sprintf(ArpData->ifname, "%s", arp_msg->ifname); + ArpData->ipv4_addr = arp_msg->ipv4_addr; + memcpy(ArpData->mac_addr, arp_msg->mac_addr, ETHER_ADDR_LEN); + + ICCPD_LOG_NOTICE(__FUNCTION__, "Send ARP messge to peer, if name %s mac %02x:%02x:%02x:%02x:%02x:%02x IP %s", ArpData->ifname, ArpData->mac_addr[0], ArpData->mac_addr[1], ArpData->mac_addr[2], + ArpData->mac_addr[3], ArpData->mac_addr[4], ArpData->mac_addr[5], show_ip_str(ArpData->ipv4_addr)); + + return msg_len; +} + +/***************************************** +* Preprare Sync NDISC-Info TLV +* +* ***************************************/ +int mlacp_prepare_for_ndisc_info(struct CSM *csm, char *buf, size_t max_buf_size, struct NDISCMsg *ndisc_msg, int count) +{ + + struct mLACPNDISCInfoTLV *tlv = NULL; + size_t msg_len = 0; + size_t tlv_len = 0; + ICCHdr *icc_hdr = NULL; + struct NDISCMsg *NdiscData; + + if (!csm) + return -1; + if (!buf) + return -1; + + tlv_len = sizeof(struct mLACPNDISCInfoTLV) + sizeof(struct NDISCMsg) * (count + 1); + + if ((msg_len = sizeof(ICCHdr) + tlv_len) > max_buf_size) + return -1; + + /* ICC header */ + icc_hdr = (ICCHdr *)buf; + mlacp_fill_icc_header(csm, icc_hdr, msg_len); + + /* Prepare for ND information TLV */ + tlv = (struct mLACPNDISCInfoTLV *)&buf[sizeof(ICCHdr)]; + tlv->icc_parameter.len = htons(tlv_len - sizeof(ICCParameter)); + tlv->num_of_entry = htons(count + 1); + + if (count == 0) + { + tlv->icc_parameter.u_bit = 0; + tlv->icc_parameter.f_bit = 0; + tlv->icc_parameter.type = htons(TLV_T_MLACP_NDISC_INFO); + } + + NdiscData = (struct mLACPMACData *)&buf[sizeof(ICCHdr) + sizeof(struct mLACPNDISCInfoTLV) + sizeof(struct NDISCMsg) * count]; + + NdiscData->op_type = ndisc_msg->op_type; + sprintf(NdiscData->ifname, "%s", ndisc_msg->ifname); + memcpy(NdiscData->ipv6_addr, ndisc_msg->ipv6_addr, 32); + memcpy(NdiscData->mac_addr, ndisc_msg->mac_addr, ETHER_ADDR_LEN); + + ICCPD_LOG_NOTICE(__FUNCTION__, "Send ND messge to peer, if name %s mac =%02x:%02x:%02x:%02x:%02x:%02x IPv6 %s", NdiscData->ifname, + NdiscData->mac_addr[0], NdiscData->mac_addr[1], NdiscData->mac_addr[2], NdiscData->mac_addr[3], NdiscData->mac_addr[4], + NdiscData->mac_addr[5], show_ipv6_str((char *)NdiscData->ipv6_addr)); + + return msg_len; +} + +/***************************************** +* Prprare Send portchannel info +* +* ***************************************/ +int mlacp_prepare_for_port_channel_info(struct CSM* csm, char* buf, + size_t max_buf_size, + struct LocalInterface* port_channel) +{ + struct System* sys = NULL; + ICCHdr* icc_hdr = NULL; + struct mLACPPortChannelInfoTLV* tlv = NULL; + size_t msg_len; + size_t tlv_len; + size_t name_len = MAX_L_PORT_NAME; + struct VLAN_ID* vlan_id = NULL; + int num_of_vlan_id = 0; + + if (csm == NULL ) + return MCLAG_ERROR; + if (buf == NULL ) + return MCLAG_ERROR; + if (port_channel == NULL ) + return MCLAG_ERROR; + if (port_channel->type == IF_T_PORT) + return MCLAG_ERROR; + if ((sys = system_get_instance()) == NULL ) + return MCLAG_ERROR; + + /* Calculate VLAN ID Length */ + LIST_FOREACH(vlan_id, &(port_channel->vlan_list), port_next) + if (vlan_id != NULL) + num_of_vlan_id++; + + tlv_len = sizeof(struct mLACPPortChannelInfoTLV) + sizeof(struct mLACPVLANData) * num_of_vlan_id; + + if ((msg_len = sizeof(ICCHdr) + tlv_len) > max_buf_size) + return MCLAG_ERROR; + + /* Prepare for port channel info */ + memset(buf, 0, max_buf_size); + + icc_hdr = (ICCHdr*)buf; + tlv = (struct mLACPPortChannelInfoTLV*)&buf[sizeof(ICCHdr)]; + + /* ICC header */ + mlacp_fill_icc_header(csm, icc_hdr, msg_len); + + /* Port Channel Info TLV */ + tlv->icc_parameter.u_bit = 0; + tlv->icc_parameter.f_bit = 0; + tlv->icc_parameter.type = htons(TLV_T_MLACP_PORT_CHANNEL_INFO); + tlv->icc_parameter.len = htons(sizeof(struct mLACPPortChannelInfoTLV) - sizeof(ICCParameter) + sizeof(struct mLACPVLANData) * num_of_vlan_id); + tlv->agg_id = htons(port_channel->po_id); + tlv->ipv4_addr = htonl(port_channel->ipv4_addr); + tlv->l3_mode = port_channel->l3_mode; + tlv->po_id = htons(port_channel->po_id); + + if (strlen(port_channel->name) < name_len) + name_len = strlen(port_channel->name); + memcpy(tlv->if_name, port_channel->name, name_len); + tlv->if_name_len = name_len; + tlv->num_of_vlan_id = htons(num_of_vlan_id); + + num_of_vlan_id = 0; + LIST_FOREACH(vlan_id, &(port_channel->vlan_list), port_next) + { + if (vlan_id != NULL ) + { + tlv->vlanData[num_of_vlan_id].vlan_id = htons(vlan_id->vid); + + num_of_vlan_id++; + ICCPD_LOG_DEBUG(__FUNCTION__, "PortChannel%d: ipv4 addr = %s vlan id %d num %d ", port_channel->po_id, show_ip_str( tlv->ipv4_addr), vlan_id->vid, num_of_vlan_id ); + } + } + + ICCPD_LOG_DEBUG(__FUNCTION__, "PortChannel%d: ipv4 addr = %s l3 mode %d", port_channel->po_id, show_ip_str( tlv->ipv4_addr), tlv->l3_mode); + + return msg_len; +} + +/***************************************** +* Prprare Send port peerlink info +* +* ***************************************/ +int mlacp_prepare_for_port_peerlink_info(struct CSM* csm, char* buf, + size_t max_buf_size, + struct LocalInterface* peerlink_port) +{ + struct System* sys = NULL; + ICCHdr* icc_hdr = NULL; + struct mLACPPeerLinkInfoTLV* tlv = NULL; + size_t msg_len; + size_t tlv_len; + + if (csm == NULL ) + return MCLAG_ERROR; + if (buf == NULL ) + return MCLAG_ERROR; + if (peerlink_port == NULL ) + return MCLAG_ERROR; + if ((sys = system_get_instance()) == NULL ) + return MCLAG_ERROR; + + /* Prepare for port channel info */ + memset(buf, 0, max_buf_size); + + tlv_len = sizeof(struct mLACPPeerLinkInfoTLV); + + if ((msg_len = sizeof(ICCHdr) + tlv_len) > max_buf_size) + return MCLAG_ERROR; + + icc_hdr = (ICCHdr*)buf; + tlv = (struct mLACPPeerLinkInfoTLV*)&buf[sizeof(ICCHdr)]; + + /* ICC header */ + mlacp_fill_icc_header(csm, icc_hdr, msg_len); + + /* Port Channel Info TLV */ + tlv->icc_parameter.u_bit = 0; + tlv->icc_parameter.f_bit = 0; + tlv->icc_parameter.type = htons(TLV_T_MLACP_PEERLINK_INFO); + + tlv->icc_parameter.len = htons(tlv_len - sizeof(ICCParameter)); + memcpy(tlv->if_name, peerlink_port->name, MAX_L_PORT_NAME); + tlv->port_type = peerlink_port->type; + + ICCPD_LOG_DEBUG(__FUNCTION__, "Peerlink port is %s, type = %d", tlv->if_name, tlv->port_type); + + return msg_len; +} + + +/***************************************** +* Prprare Send Heartbeat +* +* ***************************************/ +int mlacp_prepare_for_heartbeat(struct CSM* csm, char* buf, size_t max_buf_size) +{ + struct System* sys = NULL; + ICCHdr* icc_hdr = (ICCHdr*)buf; + struct mLACPHeartbeatTLV* tlv = (struct mLACPHeartbeatTLV*)&buf[sizeof(ICCHdr)]; + size_t msg_len = sizeof(ICCHdr) + sizeof(struct mLACPHeartbeatTLV); + + if (csm == NULL) + return MCLAG_ERROR; + + if (buf == NULL) + return MCLAG_ERROR; + + if (msg_len > max_buf_size) + return MCLAG_ERROR; + + if ((sys = system_get_instance()) == NULL) + return MCLAG_ERROR; + + /* Prepare for sync request */ + memset(buf, 0, max_buf_size); + + icc_hdr = (ICCHdr*)buf; + tlv = (struct mLACPHeartbeatTLV*)&buf[sizeof(ICCHdr)]; + + /* ICC header */ + mlacp_fill_icc_header(csm, icc_hdr, msg_len); + + /* System Config TLV */ + tlv->icc_parameter.u_bit = 0; + tlv->icc_parameter.f_bit = 0; + tlv->icc_parameter.type = htons(TLV_T_MLACP_HEARTBEAT); + + tlv->icc_parameter.len = htons(sizeof(struct mLACPHeartbeatTLV) - sizeof(ICCParameter)); + tlv->heartbeat = 0xFF; + return msg_len; +} + +/***************************************** +* Prepare Send warm-reboot flag +* +* ***************************************/ +int mlacp_prepare_for_warm_reboot(struct CSM* csm, char* buf, size_t max_buf_size) +{ + struct System* sys = NULL; + ICCHdr* icc_hdr = (ICCHdr*)buf; + struct mLACPWarmbootTLV* tlv = (struct mLACPWarmbootTLV*)&buf[sizeof(ICCHdr)]; + size_t msg_len = sizeof(ICCHdr) + sizeof(struct mLACPWarmbootTLV); + + if (csm == NULL) + return MCLAG_ERROR; + + if (buf == NULL) + return MCLAG_ERROR; + + if (msg_len > max_buf_size) + return MCLAG_ERROR; + + if ((sys = system_get_instance()) == NULL) + return MCLAG_ERROR; + + /* Prepare for sync request */ + memset(buf, 0, max_buf_size); + + icc_hdr = (ICCHdr*)buf; + tlv = (struct mLACPWarmbootTLV*)&buf[sizeof(ICCHdr)]; + + /* ICC header */ + mlacp_fill_icc_header(csm, icc_hdr, msg_len); + + /* System Config TLV */ + tlv->icc_parameter.u_bit = 0; + tlv->icc_parameter.f_bit = 0; + tlv->icc_parameter.type = htons(TLV_T_MLACP_WARMBOOT_FLAG); + + tlv->icc_parameter.len = htons(sizeof(struct mLACPWarmbootTLV) - sizeof(ICCParameter)); + tlv->warmboot = 0x1; + + ICCPD_LOG_NOTICE(__FUNCTION__, "Send warm reboot notification to peer!"); + return msg_len; +} + +/***************************************** +* Tool : Prepare ICC Header +* +* ***************************************/ +static int mlacp_fill_icc_header(struct CSM* csm, ICCHdr* icc_hdr, size_t msg_len) +{ + if (csm == NULL || icc_hdr == NULL) + return MCLAG_ERROR; + + /* ICC header */ + icc_hdr->ldp_hdr.u_bit = 0x0; + icc_hdr->ldp_hdr.msg_type = htons(MSG_T_RG_APP_DATA); + + icc_hdr->ldp_hdr.msg_len = htons(msg_len - MSG_L_INCLUD_U_BIT_MSG_T_L_FIELDS); + icc_hdr->ldp_hdr.msg_id = htonl(ICCP_MSG_ID); + ICCP_MSG_ID++; + iccp_csm_fill_icc_rg_id_tlv(csm, icc_hdr); + + return 0; +} + diff --git a/src/iccpd/src/mlacp_sync_update.c b/src/iccpd/src/mlacp_sync_update.c new file mode 100644 index 000000000000..b82fc1c16cb9 --- /dev/null +++ b/src/iccpd/src/mlacp_sync_update.c @@ -0,0 +1,946 @@ +/******************************************************************************** + * mlacp_sync_update.c + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + * + *******************************************************************************/ +#include +#include + +#include +#include + +#include "../include/system.h" +#include "../include/logger.h" +#include "../include/mlacp_tlv.h" +#include "../include/iccp_csm.h" +#include "../include/mlacp_link_handler.h" +#include "../include/iccp_consistency_check.h" +#include "../include/port.h" +#include "../include/iccp_netlink.h" +/***************************************** +* Port-Conf Update +* +* ***************************************/ +extern void update_if_ipmac_on_standby(struct LocalInterface* lif_po); +int mlacp_fsm_update_system_conf(struct CSM* csm, mLACPSysConfigTLV*sysconf) +{ + struct LocalInterface* lif = NULL; + + /*NOTE + a little tricky, we change the NodeID local side if collision happened first time*/ + if (sysconf->node_id == MLACP(csm).node_id) + MLACP(csm).node_id++; + + memcpy(MLACP(csm).remote_system.system_id, sysconf->sys_id, ETHER_ADDR_LEN); + MLACP(csm).remote_system.system_priority = ntohs(sysconf->sys_priority); + MLACP(csm).remote_system.node_id = sysconf->node_id; + + ICCPD_LOG_DEBUG(__FUNCTION__, "SystemID [%02X:%02X:%02X:%02X:%02X:%02X], SystemPriority [%d], Remote NodeID [%d], NodeID [%d]", + MLACP(csm).remote_system.system_id[0], MLACP(csm).remote_system.system_id[1], MLACP(csm).remote_system.system_id[2], + MLACP(csm).remote_system.system_id[3], MLACP(csm).remote_system.system_id[4], MLACP(csm).remote_system.system_id[5], + MLACP(csm).remote_system.system_priority, + MLACP(csm).remote_system.node_id, + MLACP(csm).node_id); + + LIST_FOREACH(lif, &(MLACP(csm).lif_list), mlacp_next) + { + update_if_ipmac_on_standby(lif); + } + + return 0; +} + +/***************************************** +* Port-Conf Update +* +* ***************************************/ +int mlacp_fsm_update_Agg_conf(struct CSM* csm, mLACPAggConfigTLV* portconf) +{ + struct PeerInterface* pif = NULL; + uint8_t po_active; + uint8_t new_create = 0; + + ICCPD_LOG_DEBUG(__FUNCTION__, "Port name %s, po id %d flag %d MAC[%02x:%02x:%02x:%02x:%02x:%02x] ", + portconf->agg_name, ntohs(portconf->agg_id), portconf->flags, portconf->mac_addr[0], portconf->mac_addr[1], portconf->mac_addr[2], + portconf->mac_addr[3], portconf->mac_addr[4], portconf->mac_addr[5] ); + + /* Looking for the peer port instance, is any peer if exist?*/ + pif = peer_if_find_by_name(csm, portconf->agg_name); + + /* Process purge*/ + if (portconf->flags & 0x02) + { + /*Purge*/ + if (pif != NULL ) + peer_if_destroy(pif); + else + MLACP(csm).need_to_sync = 1; + /*ICCPD_LOG_INFO("mlacp_fsm", + " Peer port %s is removed from port-channel member.",portconf->port_name);*/ + + return 0; + } + + if (pif == NULL && portconf->flags & 0x01) + { + pif = peer_if_create(csm, ntohs(portconf->agg_id), IF_T_PORT_CHANNEL); + if (pif == NULL) + return MCLAG_ERROR; + + new_create = 1; + } + + pif->po_id = ntohs(portconf->agg_id); + memcpy(pif->name, portconf->agg_name, portconf->agg_name_len); + memcpy(pif->mac_addr, portconf->mac_addr, ETHER_ADDR_LEN); + + po_active = (pif->state == PORT_STATE_UP); + update_stp_peer_link(csm, pif, po_active, new_create); + update_peerlink_isolate_from_pif(csm, pif, po_active, new_create); + pif->po_active = po_active; + + return 0; +} + +/***************************************** +* Agg Port-State Update +* +* ***************************************/ +int mlacp_fsm_update_Aggport_state(struct CSM* csm, mLACPAggPortStateTLV* tlv) +{ + struct PeerInterface* peer_if = NULL; + uint8_t po_active; + + if (csm == NULL || tlv == NULL) + return MCLAG_ERROR; + ICCPD_LOG_DEBUG(__FUNCTION__, "Portchannel id %d state %d", ntohs(tlv->agg_id), tlv->agg_state); + + po_active = (tlv->agg_state == PORT_STATE_UP); + + LIST_FOREACH(peer_if, &(MLACP(csm).pif_list), mlacp_next) + { + if (peer_if->type != IF_T_PORT_CHANNEL) + continue; + + if (peer_if->po_id != ntohs(tlv->agg_id)) + continue; + + peer_if->state = tlv->agg_state; + + update_stp_peer_link(csm, peer_if, po_active, 0); + update_peerlink_isolate_from_pif(csm, peer_if, po_active, 0); + + peer_if->po_active = po_active; + ICCPD_LOG_DEBUG(__FUNCTION__, "Update peer interface %s to state %s", peer_if->name, tlv->agg_state ? "down" : "up"); + + break; + } + + return 0; +} + +/***************************************** +* Recv from peer, MAC-Info Update +* ***************************************/ +int mlacp_fsm_update_mac_entry_from_peer( struct CSM* csm, struct mLACPMACData *MacData) +{ + + struct Msg* msg = NULL; + struct MACMsg *mac_msg = NULL, mac_data; + struct LocalInterface* local_if = NULL; + uint8_t from_mclag_intf = 0;/*0: orphan port, 1: MCLAG port*/ + + ICCPD_LOG_NOTICE(__FUNCTION__, + "Received MAC Info, port[%s] vid[%d] MAC[%s] type[%s]", + MacData->ifname, ntohs(MacData->vid), MacData->mac_str, MacData->type == MAC_SYNC_ADD ? "add" : "del"); + + /*Find the interface in MCLAG interface list*/ + LIST_FOREACH(local_if, &(MLACP(csm).lif_list), mlacp_next) + { + if (local_if->type == IF_T_PORT_CHANNEL && strcmp(local_if->name, MacData->ifname) == 0) + { + from_mclag_intf = 1; + break; + } + } + + /* update MAC list*/ + TAILQ_FOREACH(msg, &(MLACP(csm).mac_list), tail) + { + mac_msg = (struct MACMsg*)msg->buf; + + /*Same MAC is exist in local switch, this may be mac move*/ + if (strcmp(mac_msg->mac_str, MacData->mac_str) == 0 && mac_msg->vid == ntohs(MacData->vid)) + { + if (MacData->type == MAC_SYNC_ADD) + { + mac_msg->age_flag &= ~MAC_AGE_PEER; + ICCPD_LOG_DEBUG(__FUNCTION__, "Recv ADD, Remove peer age flag:%d ifname %s, MAC %s vlan-id %d", + mac_msg->age_flag, mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); + + /*mac_msg->fdb_type = tlv->fdb_type;*/ + /*The port ifname is different to the local item*/ + if (from_mclag_intf == 0 || strcmp(mac_msg->ifname, MacData->ifname) != 0 || strcmp(mac_msg->origin_ifname, MacData->ifname) != 0) + { + if (mac_msg->fdb_type != MAC_TYPE_STATIC) + { + /*Update local item*/ + memcpy(&mac_msg->origin_ifname, MacData->ifname, MAX_L_PORT_NAME); + } + + /*If the MAC is learned from orphan port, or from MCLAG port but the local port is down*/ + if (from_mclag_intf == 0 || (local_if->state == PORT_STATE_DOWN && strcmp(mac_msg->ifname, csm->peer_itf_name) != 0)) + { + /*Set MAC_AGE_LOCAL flag*/ + mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 1); + + if (strlen(csm->peer_itf_name) != 0) + { + if (strcmp(mac_msg->ifname, csm->peer_itf_name) == 0) + { + /* This MAC is already point to peer-link */ + return 0; + } + + if (csm->peer_link_if && csm->peer_link_if->state == PORT_STATE_UP) + { + /*Redirect the mac to peer-link*/ + memcpy(&mac_msg->ifname, csm->peer_itf_name, IFNAMSIZ); + + /*Send mac add message to mclagsyncd*/ + add_mac_to_chip(mac_msg, MAC_TYPE_DYNAMIC); + } + else + { + /*must redirect but peerlink is down, del mac from ASIC*/ + /*if peerlink change to up, mac will add back to ASIC*/ + del_mac_from_chip(mac_msg); + + /*Redirect the mac to peer-link*/ + memcpy(&mac_msg->ifname, csm->peer_itf_name, IFNAMSIZ); + } + } + else + { + /*must redirect but no peerlink, del mac from ASIC*/ + del_mac_from_chip(mac_msg); + + /*Update local item*/ + memcpy(&mac_msg->ifname, MacData->ifname, MAX_L_PORT_NAME); + + /*if orphan port mac but no peerlink, don't keep this mac*/ + if (from_mclag_intf == 0) + { + TAILQ_REMOVE(&(MLACP(csm).mac_list), msg, tail); + free(msg->buf); + free(msg); + return 0; + } + } + } + else + { + /*Remove MAC_AGE_LOCAL flag*/ + mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 0); + + /*Update local item*/ + memcpy(&mac_msg->ifname, MacData->ifname, MAX_L_PORT_NAME); + + /*from MCLAG port and the local port is up, add mac to ASIC to update port*/ + add_mac_to_chip(mac_msg, MAC_TYPE_DYNAMIC); + } + } + } + + break; + } + } + + /* delete/add MAC list*/ + if (msg && MacData->type == MAC_SYNC_DEL) + { + mac_msg->age_flag |= MAC_AGE_PEER; + ICCPD_LOG_DEBUG(__FUNCTION__, "Recv DEL, Add peer age flag: %d ifname %s, MAC %s vlan-id %d", + mac_msg->age_flag, mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); + + if (mac_msg->age_flag == (MAC_AGE_LOCAL | MAC_AGE_PEER)) + { + /*send mac del message to mclagsyncd.*/ + del_mac_from_chip(mac_msg); + + /*If local and peer both aged, del the mac*/ + TAILQ_REMOVE(&(MLACP(csm).mac_list), msg, tail); + free(msg->buf); + free(msg); + } + else + { + return 0; + } + } + else if (!msg && MacData->type == MAC_SYNC_ADD) + { + mac_msg = (struct MACMsg*)&mac_data; + mac_msg->fdb_type = MAC_TYPE_DYNAMIC; + mac_msg->vid = ntohs(MacData->vid); + sprintf(mac_msg->mac_str, "%s", MacData->mac_str); + sprintf(mac_msg->ifname, "%s", MacData->ifname); + sprintf(mac_msg->origin_ifname, "%s", MacData->ifname); + mac_msg->age_flag = 0; + + /*If the MAC is learned from orphan port, or from MCLAG port but the local port is down*/ + if (from_mclag_intf == 0 || local_if->state == PORT_STATE_DOWN) + { + /*Set MAC_AGE_LOCAL flag*/ + mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 1); + + if (strlen(csm->peer_itf_name) == 0) + { + ICCPD_LOG_NOTICE(__FUNCTION__, "From orphan port or portchannel is down, but peer-link is not configured: ifname %s, MAC %s vlan-id %d", + mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); + + /*if orphan port mac but no peerlink, don't keep this mac*/ + if (from_mclag_intf == 0) + return 0; + } + else + { + /*Redirect the mac to peer-link*/ + memcpy(&mac_msg->ifname, csm->peer_itf_name, IFNAMSIZ); + + ICCPD_LOG_NOTICE(__FUNCTION__, "Redirect to peerlink for orphan port or portchannel is down, Add local age flag: %d ifname %s, MAC %s vlan-id %d", + mac_msg->age_flag, mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); + } + } + else + { + /*Remove MAC_AGE_LOCAL flag*/ + mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 0); + } + + if (iccp_csm_init_msg(&msg, (char*)mac_msg, sizeof(struct MACMsg)) == 0) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).mac_list), msg, tail); + /*ICCPD_LOG_INFO(__FUNCTION__, "add mac queue successfully");*/ + + /*If the mac is from orphan port, or from MCLAG port but the local port is down*/ + if (strcmp(mac_msg->ifname, csm->peer_itf_name) == 0) + { + /*Send mac add message to mclagsyncd*/ + if (csm->peer_link_if && csm->peer_link_if->state == PORT_STATE_UP) + add_mac_to_chip(mac_msg, mac_msg->fdb_type); + } + else + { + /*from MCLAG port and the local port is up*/ + add_mac_to_chip(mac_msg, mac_msg->fdb_type); + } + } + } + + return 0; +} + +int mlacp_fsm_update_mac_info_from_peer(struct CSM* csm, struct mLACPMACInfoTLV* tlv) +{ + int count = 0; + int i; + + if (!csm || !tlv) + return MCLAG_ERROR; + count = ntohs(tlv->num_of_entry); + ICCPD_LOG_INFO(__FUNCTION__, "Received MAC Info count %d", count ); + + for (i = 0; i < count; i++) + { + mlacp_fsm_update_mac_entry_from_peer(csm, &(tlv->MacEntry[i])); + } +} + +/***************************************** + * Tool : Add ARP Info into ARP list + * + ****************************************/ +void mlacp_enqueue_arp(struct CSM* csm, struct Msg* msg) +{ + struct ARPMsg *arp_msg = NULL; + + if (!csm) + { + if (msg) + free(msg); + return; + } + if (!msg) + return; + + arp_msg = (struct ARPMsg*)msg->buf; + if (arp_msg->op_type != NEIGH_SYNC_DEL) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).arp_list), msg, tail); + } + + return; +} + +/***************************************** + * Tool : Add Ndisc Info into ndisc list + * + ****************************************/ +void mlacp_enqueue_ndisc(struct CSM *csm, struct Msg *msg) +{ + struct NDISCMsg *ndisc_msg = NULL; + + if (!csm) + { + if (msg) + free(msg); + return; + } + if (!msg) + return; + + ndisc_msg = (struct NDISCMsg *)msg->buf; + if (ndisc_msg->op_type != NEIGH_SYNC_DEL) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).ndisc_list), msg, tail); + } + + return; +} + +/***************************************** +* ARP-Info Update +* ***************************************/ +int mlacp_fsm_update_arp_entry(struct CSM* csm, struct ARPMsg *arp_entry) +{ + struct Msg* msg = NULL; + struct ARPMsg *arp_msg = NULL, arp_data; + struct LocalInterface* local_if; + struct LocalInterface *peer_link_if = NULL; + struct VLAN_ID *vlan_id_list = NULL; + int set_arp_flag = 0; + char mac_str[18] = ""; + + if (!csm || !arp_entry) + return MCLAG_ERROR; + + sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", arp_entry->mac_addr[0], arp_entry->mac_addr[1], arp_entry->mac_addr[2], + arp_entry->mac_addr[3], arp_entry->mac_addr[4], arp_entry->mac_addr[5]); + + ICCPD_LOG_NOTICE(__FUNCTION__, + "Received ARP Info, intf[%s] IP[%s], MAC[%02x:%02x:%02x:%02x:%02x:%02x]", + arp_entry->ifname, show_ip_str(arp_entry->ipv4_addr), + arp_entry->mac_addr[0], arp_entry->mac_addr[1], arp_entry->mac_addr[2], + arp_entry->mac_addr[3], arp_entry->mac_addr[4], arp_entry->mac_addr[5]); + + if (strncmp(arp_entry->ifname, "Vlan", 4) == 0) + { + peer_link_if = local_if_find_by_name(csm->peer_itf_name); + + if (peer_link_if && !local_if_is_l3_mode(peer_link_if)) + { + /* Is peer-linlk itf belong to a vlan the same as peer?*/ + LIST_FOREACH(vlan_id_list, &(peer_link_if->vlan_list), port_next) + { + if (!vlan_id_list->vlan_itf) + continue; + if (strcmp(vlan_id_list->vlan_itf->name, arp_entry->ifname) != 0) + continue; + if (!local_if_is_l3_mode(vlan_id_list->vlan_itf)) + continue; + + ICCPD_LOG_DEBUG(__FUNCTION__, "ARP is learnt from intf %s, peer-link %s is the member of this vlan", + vlan_id_list->vlan_itf->name, peer_link_if->name); + + /* Peer-link belong to L3 vlan is alive, set the ARP info*/ + set_arp_flag = 1; + + break; + } + } + } + + if (set_arp_flag == 0) + { + LIST_FOREACH(local_if, &(MLACP(csm).lif_list), mlacp_next) + { + if (local_if->type == IF_T_PORT_CHANNEL) + { + if (!local_if_is_l3_mode(local_if)) + { + /* Is the L2 MLAG itf belong to a vlan the same as peer?*/ + LIST_FOREACH(vlan_id_list, &(local_if->vlan_list), port_next) + { + if (!vlan_id_list->vlan_itf) + continue; + if (strcmp(vlan_id_list->vlan_itf->name, arp_entry->ifname) != 0) + continue; + if (!local_if_is_l3_mode(vlan_id_list->vlan_itf)) + continue; + + ICCPD_LOG_DEBUG(__FUNCTION__, "ARP is learnt from intf %s, mclag %s is the member of this vlan", + vlan_id_list->vlan_itf->name, local_if->name); + break; + } + + if (vlan_id_list && local_if->po_active == 1) + { + /* Any po of L3 vlan is alive, set the ARP info*/ + set_arp_flag = 1; + break; + } + } + else + { + /* Is the ARP belong to a L3 mode MLAG itf?*/ + if (strcmp(local_if->name, arp_entry->ifname) == 0) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "ARP is learnt from mclag L3 intf %s", local_if->name); + if (local_if->po_active == 1) + { + /* po is alive, set the ARP info*/ + set_arp_flag = 1; + break; + } + } + else + { + continue; + } + } + } + } + } + + /* set dynamic ARP*/ + if (set_arp_flag == 1) + { + if (arp_entry->op_type == NEIGH_SYNC_ADD) + { + if (iccp_netlink_neighbor_request(AF_INET, (uint8_t *)&arp_entry->ipv4_addr, 1, arp_entry->mac_addr, arp_entry->ifname) < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "ARP add failure for %s %s %s", + arp_entry->ifname, show_ip_str(arp_entry->ipv4_addr), mac_str); + return MCLAG_ERROR; + } + } + else + { + if (iccp_netlink_neighbor_request(AF_INET, (uint8_t *)&arp_entry->ipv4_addr, 0, arp_entry->mac_addr, arp_entry->ifname) < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "ARP delete failure for %s %s %s", + arp_entry->ifname, show_ip_str(arp_entry->ipv4_addr), mac_str); + return MCLAG_ERROR; + } + } + + /*ICCPD_LOG_DEBUG(__FUNCTION__, "%s: ARP update for %s %s %s", + __FUNCTION__, arp_entry->ifname, show_ip_str(arp_entry->ipv4_addr), mac_str);*/ + } + else + { + ICCPD_LOG_NOTICE(__FUNCTION__, "Failure: port-channel is not alive"); + /*TODO Set static route through peer-link or just skip it?*/ + } + + /* update ARP list*/ + TAILQ_FOREACH(msg, &(MLACP(csm).arp_list), tail) + { + arp_msg = (struct ARPMsg*)msg->buf; + if (arp_msg->ipv4_addr == arp_entry->ipv4_addr) + { + /*arp_msg->op_type = tlv->type;*/ + sprintf(arp_msg->ifname, "%s", arp_entry->ifname); + memcpy(arp_msg->mac_addr, arp_entry->mac_addr, ETHER_ADDR_LEN); + break; + } + } + + /* delete/add ARP list*/ + if (msg && arp_entry->op_type == NEIGH_SYNC_DEL) + { + TAILQ_REMOVE(&(MLACP(csm).arp_list), msg, tail); + free(msg->buf); + free(msg); + /*ICCPD_LOG_INFO(__FUNCTION__, "Del arp queue successfully");*/ + } + else if (!msg && arp_entry->op_type == NEIGH_SYNC_ADD) + { + arp_msg = (struct ARPMsg*)&arp_data; + sprintf(arp_msg->ifname, "%s", arp_entry->ifname); + arp_msg->ipv4_addr = arp_entry->ipv4_addr; + arp_msg->op_type = arp_entry->op_type; + memcpy(arp_msg->mac_addr, arp_entry->mac_addr, ETHER_ADDR_LEN); + if (iccp_csm_init_msg(&msg, (char*)arp_msg, sizeof(struct ARPMsg)) == 0) + { + mlacp_enqueue_arp(csm, msg); + /*ICCPD_LOG_INFO(__FUNCTION__, "Add arp queue successfully");*/ + } + } + + /* remove all ARP msg queue, when receive peer's ARP list at the same time*/ + TAILQ_FOREACH(msg, &(MLACP(csm).arp_msg_list), tail) + { + arp_msg = (struct ARPMsg*)msg->buf; + if (arp_msg->ipv4_addr == arp_entry->ipv4_addr) + break; + } + + while (msg) + { + arp_msg = (struct ARPMsg*)msg->buf; + TAILQ_REMOVE(&(MLACP(csm).arp_msg_list), msg, tail); + free(msg->buf); + free(msg); + TAILQ_FOREACH(msg, &(MLACP(csm).arp_msg_list), tail) + { + arp_msg = (struct ARPMsg*)msg->buf; + if (arp_msg->ipv4_addr == arp_entry->ipv4_addr) + break; + } + } + + return 0; +} + +int mlacp_fsm_update_arp_info(struct CSM* csm, struct mLACPARPInfoTLV* tlv) +{ + int count = 0; + int i; + + if (!csm || !tlv) + return MCLAG_ERROR; + count = ntohs(tlv->num_of_entry); + ICCPD_LOG_INFO(__FUNCTION__, "Received ARP Info count %d ", count ); + + for (i = 0; i < count; i++) + { + mlacp_fsm_update_arp_entry(csm, &(tlv->ArpEntry[i])); + } +} + +/***************************************** +* NDISC-Info Update +* ***************************************/ +int mlacp_fsm_update_ndisc_entry(struct CSM *csm, struct NDISCMsg *ndisc_entry) +{ + struct Msg *msg = NULL; + struct NDISCMsg *ndisc_msg = NULL, ndisc_data; + struct LocalInterface *local_if; + struct LocalInterface *peer_link_if = NULL; + struct VLAN_ID *vlan_id_list = NULL; + int set_ndisc_flag = 0; + char mac_str[18] = ""; + + if (!csm || !ndisc_entry) + return MCLAG_ERROR; + + sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", ndisc_entry->mac_addr[0], ndisc_entry->mac_addr[1], ndisc_entry->mac_addr[2], + ndisc_entry->mac_addr[3], ndisc_entry->mac_addr[4], ndisc_entry->mac_addr[5]); + + ICCPD_LOG_NOTICE(__FUNCTION__, + "Received ND Info, intf[%s] IP[%s], MAC[%s]", ndisc_entry->ifname, show_ipv6_str((char *)ndisc_entry->ipv6_addr), mac_str); + + if (strncmp(ndisc_entry->ifname, "Vlan", 4) == 0) + { + peer_link_if = local_if_find_by_name(csm->peer_itf_name); + + if (peer_link_if && !local_if_is_l3_mode(peer_link_if)) + { + /* Is peer-linlk itf belong to a vlan the same as peer? */ + LIST_FOREACH(vlan_id_list, &(peer_link_if->vlan_list), port_next) + { + if (!vlan_id_list->vlan_itf) + continue; + if (strcmp(vlan_id_list->vlan_itf->name, ndisc_entry->ifname) != 0) + continue; + if (!local_if_is_l3_mode(vlan_id_list->vlan_itf)) + continue; + + ICCPD_LOG_DEBUG(__FUNCTION__, + "ND is learnt from intf %s, peer-link %s is the member of this vlan", + vlan_id_list->vlan_itf->name, peer_link_if->name); + + /* Peer-link belong to L3 vlan is alive, set the NDISC info */ + set_ndisc_flag = 1; + + break; + } + } + } + + if (set_ndisc_flag == 0) + { + LIST_FOREACH(local_if, &(MLACP(csm).lif_list), mlacp_next) + { + if (local_if->type == IF_T_PORT_CHANNEL) + { + if (!local_if_is_l3_mode(local_if)) + { + /* Is the L2 MLAG itf belong to a vlan the same as peer? */ + LIST_FOREACH(vlan_id_list, &(local_if->vlan_list), port_next) + { + if (!vlan_id_list->vlan_itf) + continue; + if (strcmp(vlan_id_list->vlan_itf->name, ndisc_entry->ifname) != 0) + continue; + if (!local_if_is_l3_mode(vlan_id_list->vlan_itf)) + continue; + + ICCPD_LOG_DEBUG(__FUNCTION__, + "ND is learnt from intf %s, %s is the member of this vlan", vlan_id_list->vlan_itf->name, local_if->name); + break; + } + + if (vlan_id_list && local_if->po_active == 1) + { + /* Any po of L3 vlan is alive, set the NDISC info */ + set_ndisc_flag = 1; + break; + } + } + else + { + /* Is the ARP belong to a L3 mode MLAG itf? */ + if (strcmp(local_if->name, ndisc_entry->ifname) == 0) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "ND is learnt from mclag L3 intf %s", local_if->name); + if (local_if->po_active == 1) + { + /* po is alive, set the NDISC info */ + set_ndisc_flag = 1; + break; + } + } + else + { + continue; + } + } + } + } + } + + /* set dynamic Ndisc */ + if (set_ndisc_flag == 1) + { + if (ndisc_entry->op_type == NEIGH_SYNC_ADD) + { + if (iccp_netlink_neighbor_request(AF_INET6, (uint8_t *)ndisc_entry->ipv6_addr, 1, ndisc_entry->mac_addr, ndisc_entry->ifname) < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "Failed to add nd entry(%s %s %s) to kernel", + ndisc_entry->ifname, show_ipv6_str((char *)ndisc_entry->ipv6_addr), mac_str); + return MCLAG_ERROR; + } + + } + else + { + if (iccp_netlink_neighbor_request(AF_INET6, (uint8_t *)ndisc_entry->ipv6_addr, 0, ndisc_entry->mac_addr, ndisc_entry->ifname) < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "Failed to delete nd entry(%s %s %s) from kernel", + ndisc_entry->ifname, show_ipv6_str((char *)ndisc_entry->ipv6_addr), mac_str); + return MCLAG_ERROR; + } + + } + + /* ICCPD_LOG_DEBUG(__FUNCTION__, "NDISC update for %s %s %s", ndisc_entry->ifname, show_ipv6_str((char *)ndisc_entry->ipv6_addr), mac_str); */ + } + else + { + ICCPD_LOG_DEBUG(__FUNCTION__, "Failure: port-channel is not alive"); + /* TODO Set static route through peer-link or just skip it? */ + } + + /* update NDISC list */ + TAILQ_FOREACH(msg, &(MLACP(csm).ndisc_list), tail) + { + ndisc_msg = (struct NDISCMsg *)msg->buf; + if (memcmp((char *)ndisc_msg->ipv6_addr, (char *)ndisc_entry->ipv6_addr, 16) == 0) + { + /* ndisc_msg->op_type = tlv->type; */ + sprintf(ndisc_msg->ifname, "%s", ndisc_entry->ifname); + memcpy(ndisc_msg->mac_addr, ndisc_entry->mac_addr, ETHER_ADDR_LEN); + break; + } + } + + /* delete/add NDISC list */ + if (msg && ndisc_entry->op_type == NEIGH_SYNC_DEL) + { + TAILQ_REMOVE(&(MLACP(csm).ndisc_list), msg, tail); + free(msg->buf); + free(msg); + /* ICCPD_LOG_INFO(__FUNCTION__, "Del ndisc queue successfully"); */ + } + else if (!msg && ndisc_entry->op_type == NEIGH_SYNC_ADD) + { + ndisc_msg = (struct NDISCMsg *)&ndisc_data; + sprintf(ndisc_msg->ifname, "%s", ndisc_entry->ifname); + memcpy((char *)ndisc_msg->ipv6_addr, (char *)ndisc_entry->ipv6_addr, 16); + ndisc_msg->op_type = ndisc_entry->op_type; + memcpy(ndisc_msg->mac_addr, ndisc_entry->mac_addr, ETHER_ADDR_LEN); + if (iccp_csm_init_msg(&msg, (char *)ndisc_msg, sizeof(struct NDISCMsg)) == 0) + { + mlacp_enqueue_ndisc(csm, msg); + /* ICCPD_LOG_INFO(__FUNCTION__, "Add ndisc queue successfully"); */ + } + } + + /* remove all NDISC msg queue, when receive peer's NDISC list at the same time */ + TAILQ_FOREACH(msg, &(MLACP(csm).ndisc_msg_list), tail) + { + ndisc_msg = (struct NDISCMsg *)msg->buf; + if (memcmp((char *)ndisc_msg->ipv6_addr, (char *)ndisc_entry->ipv6_addr, 16) == 0) + break; + } + + while (msg) + { + ndisc_msg = (struct NDISCMsg *)msg->buf; + TAILQ_REMOVE(&(MLACP(csm).ndisc_msg_list), msg, tail); + free(msg->buf); + free(msg); + TAILQ_FOREACH(msg, &(MLACP(csm).ndisc_msg_list), tail) + { + ndisc_msg = (struct NDISCMsg *)msg->buf; + if (memcmp((char *)ndisc_msg->ipv6_addr, (char *)ndisc_entry->ipv6_addr, 16) == 0) + break; + } + } + + return 0; +} + +int mlacp_fsm_update_ndisc_info(struct CSM *csm, struct mLACPNDISCInfoTLV *tlv) +{ + int count = 0; + int i; + + if (!csm || !tlv) + return MCLAG_ERROR; + count = ntohs(tlv->num_of_entry); + ICCPD_LOG_INFO(__FUNCTION__, "Received NDISC Info count %d ", count); + + for (i = 0; i < count; i++) + { + mlacp_fsm_update_ndisc_entry(csm, &(tlv->NdiscEntry[i])); + } +} + +/***************************************** +* Port-Channel-Info Update +* ***************************************/ +int mlacp_fsm_update_port_channel_info(struct CSM* csm, + struct mLACPPortChannelInfoTLV* tlv) +{ + struct PeerInterface* peer_if = NULL; + struct VLAN_ID* peer_vlan_id = NULL; + int i = 0; + + if (csm == NULL || tlv == NULL ) + return MCLAG_ERROR; + + LIST_FOREACH(peer_if, &(MLACP(csm).pif_list), mlacp_next) + { + if (peer_if->type != IF_T_PORT_CHANNEL) + continue; + + if (peer_if->po_id != ntohs(tlv->agg_id)) + continue; + + LIST_FOREACH(peer_vlan_id, &(peer_if->vlan_list), port_next) + { + peer_vlan_id->vlan_removed = 1; + } + + /* Record peer info*/ + peer_if->ipv4_addr = ntohl(tlv->ipv4_addr); + peer_if->l3_mode = tlv->l3_mode; + + for (i = 0; i < ntohs(tlv->num_of_vlan_id); i++) + { + peer_if_add_vlan(peer_if, ntohs(tlv->vlanData[i].vlan_id)); + } + + peer_if_clean_unused_vlan(peer_if); + + iccp_consistency_check(peer_if->name); + + ICCPD_LOG_DEBUG(__FUNCTION__, "Peer intf %s info: ipv4 addr %s l3 mode %d", peer_if->name, show_ip_str( tlv->ipv4_addr), peer_if->l3_mode); + break; + } + + return 0; +} + +/***************************************** +* Peerlink port Update +* ***************************************/ +int mlacp_fsm_update_peerlink_info(struct CSM* csm, + struct mLACPPeerLinkInfoTLV* tlv) +{ + if (csm == NULL || tlv == NULL ) + return MCLAG_ERROR; + + if (!csm->peer_link_if) + { + ICCPD_LOG_WARN(__FUNCTION__, "Peerlink port info recv from peer, local peerlink is not exist!"); + return 0; + } + + if (csm->peer_link_if->type != tlv->port_type) + ICCPD_LOG_NOTICE(__FUNCTION__, "Peerlink port type of peer %d is not same with local %d !", tlv->port_type, csm->peer_link_if->type); + + if (tlv->port_type == IF_T_VXLAN && strncmp(csm->peer_itf_name, tlv->if_name, strlen(csm->peer_itf_name))) + ICCPD_LOG_NOTICE(__FUNCTION__, "Peerlink port is vxlan port, but peerlink port of peer %s is not same with local %s !", tlv->if_name, csm->peer_itf_name); + + return 0; +} + +/***************************************** +* Heartbeat Update +*****************************************/ +int mlacp_fsm_update_heartbeat(struct CSM* csm, struct mLACPHeartbeatTLV* tlv) +{ + if (!csm || !tlv) + return MCLAG_ERROR; + + time(&csm->heartbeat_update_time); + + return 0; +} + +/***************************************** +* warm-reboot flag Update +*****************************************/ +int mlacp_fsm_update_warmboot(struct CSM* csm, struct mLACPWarmbootTLV* tlv) +{ + if (!csm || !tlv) + return MCLAG_ERROR; + + time(&csm->peer_warm_reboot_time); + ICCPD_LOG_NOTICE(__FUNCTION__, "Receive warm reboot notification from peer!"); + + return 0; +} + diff --git a/src/iccpd/src/port.c b/src/iccpd/src/port.c new file mode 100644 index 000000000000..e63429a77c2e --- /dev/null +++ b/src/iccpd/src/port.c @@ -0,0 +1,668 @@ +/* + * port.c + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#include +#include + +#include "../include/logger.h" +#include "../include/port.h" +#include "../include/system.h" +#include "../include/iccp_csm.h" +#include "../include/iccp_netlink.h" +#include "../include/scheduler.h" + +void local_if_init(struct LocalInterface* local_if) +{ + if (local_if == NULL) + return; + + memset(local_if, 0, sizeof(struct LocalInterface)); + local_if->po_id = -1; + local_if->po_active = 1; //always guess the po is active + local_if->mlacp_state = MLACP_STATE_INIT; + local_if->type = IF_T_UNKNOW; + local_if->changed = 1; + local_if->port_config_sync = 0; + local_if->is_peer_link = 0; + local_if->is_arp_accept = 0; + local_if->l3_mode = 0; + local_if->state = PORT_STATE_DOWN; + local_if->prefixlen = 32; + local_if->csm = NULL; + local_if->isolate_to_peer_link = 0; + LIST_INIT(&local_if->vlan_list); + + return; +} + +void vlan_info_init(struct VLAN_ID* vlan) +{ + vlan->vid = -1; + vlan->vlan_removed = 0; + vlan->vlan_itf = NULL; + + return; +} + +struct LocalInterface* local_if_create(int ifindex, char* ifname, int type) +{ + struct System* sys = NULL; + struct LocalInterface* local_if = NULL; + struct CSM* csm; + struct If_info * cif = NULL; + + if (!ifname) + return NULL; + + if (!(sys = system_get_instance())) + return NULL; + + if (ifindex < 0) + return NULL; + + if ((local_if = local_if_find_by_ifindex(ifindex))) + return local_if; + + if (!(local_if = (struct LocalInterface*)malloc(sizeof(struct LocalInterface)))) + { + ICCPD_LOG_WARN(__FUNCTION__, "Port ifindex = %d, malloc failed", ifindex); + return NULL; + } + + local_if_init(local_if); + local_if->ifindex = ifindex; + local_if->type = type; + + if (local_if->type == IF_T_PORT_CHANNEL) + { + int i; + int len; + len = strlen(ifname); + + for (i = 0; i < len; ++i) + if (ifname[i] >= '0' && ifname[i] <= '9') + break; + + if (i >= len) + return NULL; + + local_if->po_id = atoi(&ifname[i]); + } + + if (ifname) + snprintf(local_if->name, MAX_L_PORT_NAME, "%s", ifname); + + switch (type) + { + case IF_T_PORT_CHANNEL: + break; + + case IF_T_PORT: + break; + + case IF_T_VLAN: + /* do nothing currently. */ + break; + + case IF_T_VXLAN: + /* do nothing currently. */ + break; + + default: + ICCPD_LOG_WARN(__FUNCTION__, "The type of local interface (%s) is not acceptable", ifname); + if (local_if) + free(local_if); + return NULL; + } + + ICCPD_LOG_NOTICE(__FUNCTION__, + "Create a local_if = %s ifindex = %d MAC = %02x:%02x:%02x:%02x:%02x:%02x, state = %s", + ifname, local_if->ifindex, local_if->mac_addr[0], local_if->mac_addr[1], local_if->mac_addr[2], + local_if->mac_addr[3], local_if->mac_addr[4], local_if->mac_addr[5], local_if->state ? "down" : "up"); + + LIST_INSERT_HEAD(&(sys->lif_list), local_if, system_next); + + /*Check the intf is peer-link? Only support PortChannel and Ethernet currently*/ + /*When set peer-link, the local-if is probably not created*/ + LIST_FOREACH(csm, &(sys->csm_list), next) + { + if (strcmp(local_if->name, csm->peer_itf_name) == 0) + { + local_if->is_peer_link = 1; + csm->peer_link_if = local_if; + break; + } + /*check the intf is bind with csm*/ + LIST_FOREACH(cif, &(csm->if_bind_list), csm_next) + { + if (strcmp(ifname, cif->name) == 0) + mlacp_bind_port_channel_to_csm(csm, ifname); + } + } + + return local_if; +} + +struct LocalInterface* local_if_find_by_name(const char* ifname) +{ + struct System* sys = NULL; + struct LocalInterface* local_if = NULL; + + if (!ifname) + return NULL; + + if (!(sys = system_get_instance())) + return NULL; + + LIST_FOREACH(local_if, &(sys->lif_list), system_next) + { + if (strcmp(local_if->name, ifname) == 0) + return local_if; + } + + return NULL; +} + +struct LocalInterface* local_if_find_by_ifindex(int ifindex) +{ + struct System* sys = NULL; + struct LocalInterface* local_if = NULL; + + if ((sys = system_get_instance()) == NULL) + return NULL; + + LIST_FOREACH(local_if, &(sys->lif_list), system_next) + { + if (local_if->ifindex == ifindex) + return local_if; + } + + return NULL; +} + +struct LocalInterface* local_if_find_by_po_id(int po_id) +{ + struct System* sys = NULL; + struct LocalInterface* local_if = NULL; + + if ((sys = system_get_instance()) == NULL) + return NULL; + + LIST_FOREACH(local_if, &(sys->lif_list), system_next) + { + if (local_if->type == IF_T_PORT_CHANNEL && local_if->po_id == po_id) + return local_if; + } + + return NULL; +} + +static void local_if_vlan_remove(struct LocalInterface *lif_vlan) +{ + struct System *sys = NULL; + struct LocalInterface *lif = NULL; + struct VLAN_ID *vlan = NULL; + + if ((sys = system_get_instance()) != NULL) + { + LIST_FOREACH(lif, &(sys->lif_list), system_next) + { + LIST_FOREACH(vlan, &(lif->vlan_list), port_next) + { + if (lif_vlan != vlan->vlan_itf) + continue; + + vlan->vlan_itf = NULL; + } + } + } + + return; +} + +static void local_if_po_remove(struct LocalInterface *lif_po) +{ + struct System *sys = NULL; + struct CSM *csm = NULL; + struct LocalInterface *lif = NULL; + + /* remove all po member*/ + if ((sys = system_get_instance()) != NULL) + { + csm = lif_po->csm; + if (csm) + { + LIST_FOREACH(lif, &(MLACP(csm).lif_list), mlacp_next) + { + if (lif->type != IF_T_PORT) + continue; + if (lif->po_id != lif_po->po_id) + continue; + + mlacp_unbind_local_if(lif); + } + } + } + + return; +} + +static void local_if_remove(struct LocalInterface *lif) +{ + mlacp_unbind_local_if(lif); + lif->po_id = -1; + + return; +} + +void local_if_destroy(char *ifname) +{ + struct LocalInterface* lif = NULL; + struct CSM *csm = NULL; + struct System *sys = NULL; + + if (!(sys = system_get_instance())) + return; + + lif = local_if_find_by_name(ifname); + if (!lif) + return; + + ICCPD_LOG_WARN(__FUNCTION__, "Destroy interface %s, %d\n", lif->name, lif->ifindex); + + if (lif->type == IF_T_VLAN) + local_if_vlan_remove(lif); + else if (lif->type == IF_T_PORT_CHANNEL) + local_if_po_remove(lif); + else + local_if_remove(lif); + + csm = lif->csm; + if (csm && csm->peer_link_if && strcmp(csm->peer_link_if->name, ifname) == 0) + { + /*if the peerlink interface is not created, peer connection can not establish*/ + scheduler_session_disconnect_handler(csm); + csm->peer_link_if->is_peer_link = 0; + csm->peer_link_if = NULL; + } + + if (csm && MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + goto to_mlacp_purge; + else + goto to_sys_purge; + + to_sys_purge: + /* sys purge */ + LIST_REMOVE(lif, system_next); + if (lif->csm) + LIST_REMOVE(lif, mlacp_next); + LIST_INSERT_HEAD(&(sys->lif_purge_list), lif, system_purge_next); + return; + + to_mlacp_purge: + /* sys & mlacp purge */ + LIST_REMOVE(lif, system_next); + LIST_REMOVE(lif, mlacp_next); + LIST_INSERT_HEAD(&(sys->lif_purge_list), lif, system_purge_next); + LIST_INSERT_HEAD(&(MLACP(csm).lif_purge_list), lif, mlacp_purge_next); + return; +} + +int local_if_is_l3_mode(struct LocalInterface* local_if) +{ + int ret = 0; + char addr_null[16] = { 0 }; + + if (local_if == NULL) + return 0; + + if (local_if->ipv4_addr != 0 || memcmp(local_if->ipv6_addr, addr_null, 16) != 0) + ret = 1; + + return ret; +} + +void local_if_change_flag_clear(void) +{ + struct System* sys = NULL; + struct LocalInterface* lif = NULL; + + if ((sys = system_get_instance()) == NULL) + return; + + LIST_FOREACH(lif, &(sys->lif_list), system_next) + { + if (lif->changed == 1) + { + lif->changed = 0; + } + } + + return; +} + +void local_if_purge_clear(void) +{ + struct System* sys = NULL; + struct LocalInterface* lif = NULL; + + if ((sys = system_get_instance()) == NULL) + return; + + /* destroy purge if*/ + while (!LIST_EMPTY(&(sys->lif_purge_list))) + { + lif = LIST_FIRST(&(sys->lif_purge_list)); + ICCPD_LOG_DEBUG(__FUNCTION__, "Purge %s", lif->name); + LIST_REMOVE(lif, system_purge_next); + if (lif->mlacp_purge_next.le_next != 0 && lif->mlacp_purge_next.le_prev != 0) + LIST_REMOVE(lif, mlacp_purge_next); + local_if_del_all_vlan(lif); + free(lif); + } + + LIST_INIT(&(sys->lif_purge_list)); + + return; +} + +void local_if_finalize(struct LocalInterface* lif) +{ + if (lif == NULL) + return; + + local_if_del_all_vlan(lif); + + free(lif); + + return; +} + +struct PeerInterface* peer_if_create(struct CSM* csm, + int peer_if_number, int type) +{ + struct PeerInterface* peer_if = NULL; + + /* check csm*/ + if (csm == NULL) + return NULL; + + /* check id*/ + if (peer_if_number < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "peer interface id < 0"); + return NULL; + } + + /* check type*/ + if (type != IF_T_PORT && type != IF_T_PORT_CHANNEL) + { + ICCPD_LOG_WARN(__FUNCTION__, + "The type(%) of peer interface(%d) is not acceptable", + type, peer_if_number); + return NULL; + } + + /* create a new peer if*/ + if ((peer_if = (struct PeerInterface*)malloc(sizeof(struct PeerInterface))) == NULL) + { + ICCPD_LOG_WARN(__FUNCTION__, "Peer port id = %d, malloc failed", peer_if_number); + return NULL; + } + memset(peer_if, 0, sizeof(struct PeerInterface)); + + if (type == IF_T_PORT) + { + peer_if->ifindex = peer_if_number; + peer_if->type = IF_T_PORT; + peer_if->csm = csm; + } + else if (type == IF_T_PORT_CHANNEL) + { + peer_if->ifindex = peer_if_number; + peer_if->type = IF_T_PORT_CHANNEL; + } + + LIST_INSERT_HEAD(&(MLACP(csm).pif_list), peer_if, mlacp_next); + + return peer_if; +} + +struct PeerInterface* peer_if_find_by_name(struct CSM* csm, char* name) +{ + struct System* sys = NULL; + struct PeerInterface* peer_if = NULL; + + if ((sys = system_get_instance()) == NULL) + return NULL; + + if (csm == NULL) + return NULL; + + LIST_FOREACH(peer_if, &(csm->app_csm.mlacp.pif_list), mlacp_next) + { + if (strcmp(peer_if->name, name) == 0) + return peer_if; + } + + return NULL; +} + +void peer_if_del_all_vlan(struct PeerInterface* pif) +{ + struct VLAN_ID *pvlan = NULL; + + while (!LIST_EMPTY(&(pif->vlan_list))) + { + pvlan = LIST_FIRST(&(pif->vlan_list)); + ICCPD_LOG_DEBUG(__FUNCTION__, "Remove peer intf %s from VLAN %d", + pif->name, pvlan->vid); + LIST_REMOVE(pvlan, port_next); + free(pvlan); + } + + return; +} + +void peer_if_destroy(struct PeerInterface* pif) +{ + ICCPD_LOG_WARN(__FUNCTION__, "Destroy peer's interface %s, %d", + pif->name, pif->ifindex); + + /* destroy if*/ + LIST_REMOVE(pif, mlacp_next); + peer_if_del_all_vlan(pif); + + free(pif); + return; +} + +int local_if_add_vlan(struct LocalInterface* local_if, uint16_t vid) +{ + struct VLAN_ID *vlan = NULL; + char vlan_name[16] = ""; + + sprintf(vlan_name, "Vlan%d", vid); + + /* traverse 1 time */ + LIST_FOREACH(vlan, &(local_if->vlan_list), port_next) + { + if (vlan->vid == vid) + break; + } + + if (!vlan) + { + vlan = (struct VLAN_ID*)malloc(sizeof(struct VLAN_ID)); + if (!vlan) + return MCLAG_ERROR; + + ICCPD_LOG_DEBUG(__FUNCTION__, "Add %s to VLAN %d", local_if->name, vid); + local_if->port_config_sync = 1; + LIST_INSERT_HEAD(&(local_if->vlan_list), vlan, port_next); + } + + vlan_info_init(vlan); + vlan->vid = vid; + vlan->vlan_removed = 0; + vlan->vlan_itf = local_if_find_by_name(vlan_name); + + update_if_ipmac_on_standby(local_if); + + return 0; +} + +void local_if_del_vlan(struct LocalInterface* local_if, uint16_t vid) +{ + struct VLAN_ID *vlan = NULL; + + /* traverse 1 time */ + LIST_FOREACH(vlan, &(local_if->vlan_list), port_next) + { + if (vlan->vid == vid) + break; + } + + if (vlan != NULL) + { + LIST_REMOVE(vlan, port_next); + free(vlan); + local_if->port_config_sync = 1; + } + + ICCPD_LOG_DEBUG(__FUNCTION__, "Remove %s from VLAN %d", local_if->name, vid); + + return; +} + +void local_if_del_all_vlan(struct LocalInterface* lif) +{ + struct VLAN_ID* vlan = NULL; + + while (!LIST_EMPTY(&(lif->vlan_list))) + { + vlan = LIST_FIRST(&(lif->vlan_list)); + ICCPD_LOG_DEBUG(__FUNCTION__, "Remove %s from VLAN %d", lif->name, vlan->vid); + LIST_REMOVE(vlan, port_next); + free(vlan); + } + + return; +} + +/* Add VLAN from peer-link*/ +int peer_if_add_vlan(struct PeerInterface* peer_if, uint16_t vlan_id) +{ + struct VLAN_ID *peer_vlan = NULL; + char vlan_name[16] = ""; + + sprintf(vlan_name, "Vlan%d", vlan_id); + + /* traverse 1 time */ + LIST_FOREACH(peer_vlan, &(peer_if->vlan_list), port_next) + { + if (peer_vlan->vid == vlan_id) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "Update VLAN ID %d for peer intf %s", peer_vlan->vid, peer_if->name); + break; + } + } + + if (!peer_vlan) + { + peer_vlan = (struct VLAN_ID*)malloc(sizeof(struct VLAN_ID)); + if (!peer_vlan) + return MCLAG_ERROR; + + ICCPD_LOG_DEBUG(__FUNCTION__, "Add peer intf %s to VLAN %d", peer_if->name, vlan_id); + LIST_INSERT_HEAD(&(peer_if->vlan_list), peer_vlan, port_next); + } + + vlan_info_init(peer_vlan); + peer_vlan->vid = vlan_id; + peer_vlan->vlan_removed = 0; + + return 0; +} + +/* Used by sync update*/ +int peer_if_clean_unused_vlan(struct PeerInterface* peer_if) +{ + struct VLAN_ID *peer_vlan = NULL; + struct VLAN_ID *peer_vlan_next = NULL; + + /* traverse 1 time */ + LIST_FOREACH(peer_vlan_next, &(peer_if->vlan_list), port_next) + { + if (peer_vlan != NULL) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "Remove peer intf %s from VLAN %d", peer_if->name, peer_vlan->vid); + LIST_REMOVE(peer_vlan, port_next); + free(peer_vlan); + peer_vlan = NULL; + + } + if (peer_vlan_next->vlan_removed == 1) + peer_vlan = peer_vlan_next; + } + + if (peer_vlan != NULL) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "Remove peer intf %s from VLAN %d", peer_if->name, peer_vlan->vid); + LIST_REMOVE(peer_vlan, port_next); + free(peer_vlan); + } + + return 0; +} + +int set_sys_arp_accept_flag(char* ifname, int flag) +{ + FILE *file_ptr = NULL; + char cmd[64]; + char arp_file[64]; + char buf[2]; + int result = MCLAG_ERROR; + + memset(arp_file, 0, 64); + snprintf(arp_file, 63, "/proc/sys/net/ipv4/conf/%s/arp_accept", ifname); + if (!(file_ptr = fopen(arp_file, "r"))) + { + ICCPD_LOG_WARN(__func__, "Failed to find device %s from %s", ifname, arp_file); + return result; + } + + fgets(buf, sizeof(buf), file_ptr); + if (atoi(buf) == flag) + result = 0; + else + { + memset(cmd, 0, 64); + snprintf(cmd, 63, "echo %d > /proc/sys/net/ipv4/conf/%s/arp_accept", flag, ifname); + if (system(cmd)) + ICCPD_LOG_WARN(__func__, "Failed to execute cmd = %s", flag, cmd); + } + + fclose(file_ptr); + return result; +} diff --git a/src/iccpd/src/scheduler.c b/src/iccpd/src/scheduler.c new file mode 100644 index 000000000000..0ff9d4f5e083 --- /dev/null +++ b/src/iccpd/src/scheduler.c @@ -0,0 +1,773 @@ +/* + * scheduler.c + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../include/logger.h" +#include "../include/system.h" +#include "../include/scheduler.h" +#include "../include/iccp_csm.h" +#include "../include/iccp_ifm.h" +#include "../include/iccp_cmd.h" +#include "../include/mlacp_link_handler.h" +#include "../include/iccp_netlink.h" + +/****************************************************** +* +* Global Variable +* +******************************************************/ + +static int session_conn_thread_lock(pthread_mutex_t *conn_mutex) +{ + return 1; /*pthread_mutex_lock(conn_mutex);*/ +} + +static int session_conn_thread_trylock(pthread_mutex_t *conn_mutex) +{ + return 0; /*pthread_mutex_trylock(conn_mutex);*/ +} + +static int session_conn_thread_unlock(pthread_mutex_t *conn_mutex) +{ + return 1;/* pthread_mutex_unlock(conn_mutex);*/ +} + +static void heartbeat_check(struct CSM *csm) +{ + if (csm->heartbeat_update_time == 0) + { + time(&csm->heartbeat_update_time); + return; + } + + if ( (time(NULL) - csm->heartbeat_update_time) > HEARTBEAT_TIMEOUT_SEC) + { + /* hearbeat timeout*/ + ICCPD_LOG_WARN(__FUNCTION__, "iccpd connection timeout (heartbeat)"); + scheduler_session_disconnect_handler(csm); + } + + return; +} + +static void heartbeat_update(struct CSM *csm) +{ + if (csm->sock_fd > 0) + { + heartbeat_check(csm); + } + + return; +} + +/* Transit FSM of all connections */ +static int scheduler_transit_fsm() +{ + struct CSM* csm = NULL; + struct System* sys = NULL; + + if ((sys = system_get_instance()) == NULL) + return MCLAG_ERROR; + + LIST_FOREACH(csm, &(sys->csm_list), next) + { + heartbeat_update(csm); + iccp_csm_transit(csm); + app_csm_transit(csm); + mlacp_fsm_transit(csm); + + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE && (time(NULL) - sys->csm_trans_time) >= 60) + { + iccp_get_fdb_change_from_syncd(); + sys->csm_trans_time = time(NULL); + } + } + + local_if_change_flag_clear(); + local_if_purge_clear(); + + return 1; +} + +/* Receive packets call back function */ +int scheduler_csm_read_callback(struct CSM* csm) +{ + struct Msg* msg = NULL; + /*peer message*/ + char *peer_msg = g_csm_buf; + LDPHdr* ldp_hdr = (LDPHdr*)peer_msg; + char* data = &peer_msg[sizeof(LDPHdr)]; + size_t data_len = 0; + size_t pos = 0; + int recv_len = 0, len = 0, retval; + + if (csm->sock_fd <= 0) + return MCLAG_ERROR; + + memset(peer_msg, 0, CSM_BUFFER_SIZE); + + recv_len = 0; + + while (recv_len != sizeof(LDPHdr)) + { + len = recv(csm->sock_fd, peer_msg + recv_len, sizeof(LDPHdr) - recv_len, 0); + if (len == -1) + { + perror("recv(). Error"); + goto recv_err; + } + else if (len == 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "Peer disconnect for receive error"); + goto recv_err; + } + recv_len += len; + /*usleep(100);*/ + } + + data_len = ntohs(ldp_hdr->msg_len) - MSG_L_INCLUD_U_BIT_MSG_T_L_FIELDS; + pos = 0; + + while (data_len > 0) + { + recv_len = recv(csm->sock_fd, &data[pos], data_len, 0); + if (recv_len == -1) + { + perror("continue recv(). Error"); + goto recv_err; + } + else if (recv_len == 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "Peer disconnect for read error"); + goto recv_err; + } + data_len -= recv_len; + pos += recv_len; + /*usleep(100);*/ + } + + retval = iccp_csm_init_msg(&msg, peer_msg, ntohs(ldp_hdr->msg_len) + MSG_L_INCLUD_U_BIT_MSG_T_L_FIELDS); + if (retval == 0) + { + iccp_csm_enqueue_msg(csm, msg); + ++csm->icc_msg_in_count; + } + else + ++csm->i_msg_in_count; + + return 1; + + recv_err: + scheduler_session_disconnect_handler(csm); + return MCLAG_ERROR; +} + +/* Handle server accept client */ +int scheduler_server_accept() +{ + int new_fd; + int ret = MCLAG_ERROR; + struct CSM* csm = NULL; + struct System* sys = NULL; + struct sockaddr_in client_addr; + socklen_t addr_len; + + if ((sys = system_get_instance()) == NULL ) + { + return MCLAG_ERROR; + } + if (sys->server_fd <= 0) + { + return MCLAG_ERROR; + } + + addr_len = sizeof(struct sockaddr_in); + new_fd = accept(sys->server_fd, (struct sockaddr *)&client_addr, &addr_len); + if (new_fd == -1) + { + goto reject_client; + } + else + { + csm = system_get_csm_by_peer_ip(inet_ntoa(client_addr.sin_addr)); + if (!csm) + { + /* can't find csm with peer ip*/ + ICCPD_LOG_INFO(__FUNCTION__, "csm null with peer ip [%s]", inet_ntoa(client_addr.sin_addr)); + goto reject_client; + } + + if (csm->sock_fd > 0) + { + /* peer already connected*/ + ICCPD_LOG_INFO(__FUNCTION__, "csm sock is connected with peer ip [%s]", inet_ntoa(client_addr.sin_addr)); + goto reject_client; + } + + if ((ret = scheduler_check_csm_config(csm)) < 0) + { + /* csm config error*/ + ICCPD_LOG_INFO(__FUNCTION__, "csm config error with peer ip [%s]", inet_ntoa(client_addr.sin_addr)); + goto reject_client; + } + } + + /* Accept*/ + goto accept_client; + + reject_client: + if (new_fd >= 0) + close(new_fd); + return MCLAG_ERROR; + + accept_client: + session_conn_thread_lock(&csm->conn_mutex); + ICCPD_LOG_INFO(__FUNCTION__, "Server Accept, SocketFD [%d], %p", new_fd, csm); + + struct epoll_event event; + int err; + event.data.fd = new_fd; + event.events = EPOLLIN; + err = epoll_ctl(sys->epoll_fd, EPOLL_CTL_ADD, new_fd, &event); + if (err) + { + session_conn_thread_unlock(&csm->conn_mutex); + goto reject_client; + } + + csm->sock_fd = new_fd; + csm->current_state = ICCP_NONEXISTENT; + FD_SET(new_fd, &(sys->readfd)); + sys->readfd_count++; + session_conn_thread_unlock(&csm->conn_mutex); + return 0; +} + +void iccp_get_start_type(struct System* sys) +{ + FILE* fp; + + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + + fp = fopen("/proc/cmdline", "r"); + if (!fp) + { + ICCPD_LOG_WARN(__FUNCTION__, "Error: Can't open file /proc/cmdline!"); + return; + } + + fread(g_csm_buf, CSM_BUFFER_SIZE, 1, fp); + (void)fclose(fp); + + if (strstr(g_csm_buf, "SONIC_BOOT_TYPE=warm")) + sys->warmboot_start = WARM_REBOOT; + + return; +} + +/* scheduler initialization */ +void scheduler_init() +{ + struct System* sys = NULL; + + if (!(sys = system_get_instance())) + return; + + iccp_get_start_type(sys); + /*Get kernel interface and port */ + iccp_sys_local_if_list_get_init(); + iccp_sys_local_if_list_get_addr(); + /*Interfaces must be created before this func called*/ + iccp_config_from_file(sys->config_file_path); + + /*Get kernel ARP info */ + iccp_neigh_get_init(); + + if (iccp_connect_syncd() < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "Syncd info socket connect fail"); + } + else + { + ICCPD_LOG_DEBUG(__FUNCTION__, "Syncd info socket connect success"); + } + + if (mclagd_ctl_sock_create() < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "Mclagd ctl info socket connect fail"); + } + + return; +} + +extern int mlacp_prepare_for_warm_reboot(struct CSM* csm, char* buf, size_t max_buf_size); +void mlacp_sync_send_warmboot_flag() +{ + struct System* sys = NULL; + struct CSM* csm = NULL; + int msg_len = 0; + + if ((sys = system_get_instance()) == NULL) + return; + + LIST_FOREACH(csm, &(sys->csm_list), next) + { + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + msg_len = mlacp_prepare_for_warm_reboot(csm, g_csm_buf, CSM_BUFFER_SIZE); + iccp_csm_send(csm, g_csm_buf, msg_len); + } + } + + return; +} + +int iccp_receive_signal_handler(struct System* sys) +{ + char ctrl_byte; + int err = 0; + + err = read(sys->sig_pipe_r, &ctrl_byte, 1); + if (err == -1) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "Read sig_pipe_r fail !"); + return err; + } + + switch (ctrl_byte) + { + case 'w': + /*send packet to peer*/ + mlacp_sync_send_warmboot_flag(); + sys->warmboot_exit = WARM_REBOOT; + break; + + default: + break; + } + + return 0; +} + +/* Thread fetch to call */ +void scheduler_loop() +{ + struct System* sys = NULL; + + if ((sys = system_get_instance()) == NULL) + return; + + while (1) + { + if (sys->sync_fd <= 0) + { + iccp_connect_syncd(); + } + + /*handle socket slelect event ,If no message received, it will block 0.1s*/ + iccp_handle_events(sys); + /*csm, app state machine transit */ + scheduler_transit_fsm(); + + if (sys->warmboot_exit == WARM_REBOOT) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "Warm reboot exit ......"); + return; + } + } + + return; +} + +/***************************************** +* Sync portchannel MAC with kernel +* +* ***************************************/ +int mlacp_sync_with_kernel_callback() +{ + struct System* sys = NULL; + struct CSM* csm = NULL; + struct LocalInterface* local_if = NULL; + + if ((sys = system_get_instance()) == NULL) + { + goto out; + } + + /* traverse all CSM */ + LIST_FOREACH(csm, &(sys->csm_list), next) + { + /* Sync MLAG po state with kernel*/ + LIST_FOREACH(local_if, &(MLACP(csm).lif_list), mlacp_next) + { + if (local_if->type == IF_T_PORT_CHANNEL) + { + /* sync system info from one port-channel device*/ + if (memcmp(MLACP(csm).system_id, local_if->mac_addr, ETHER_ADDR_LEN) != 0) + { + memcpy(MLACP(csm).system_id, local_if->mac_addr, ETHER_ADDR_LEN); + MLACP(csm).system_config_changed = 1; + break; + } + } + } + } + + out: + return 0; +} + +/* Scheduler start while loop */ +void scheduler_start() +{ + /*mlacp_sync_with_kernel_callback();*/ + + scheduler_loop(); + + return; +} + +/* Scheduler tear down */ +void scheduler_finalize() +{ + struct System* sys = NULL; + + if ((sys = system_get_instance()) == NULL) + return; + + syncd_info_close(); + + log_finalize(); + + ICCPD_LOG_INFO(__FUNCTION__, "Scheduler is terminated."); + + return; +} + +void session_client_conn_handler(struct CSM *csm) +{ + struct System* sys = NULL; + struct sockaddr_in peer_addr; + int connFd = -1, connStat = -1; + struct timeval con_tv; + socklen_t len = sizeof(con_tv); + int err = 0; + + struct sockaddr_in src_addr; + bzero(&(src_addr), sizeof(src_addr)); + src_addr.sin_family = PF_INET; + src_addr.sin_port = 0; + src_addr.sin_addr.s_addr = inet_addr(csm->sender_ip); + + /* Lock the thread*/ + session_conn_thread_lock(&csm->conn_mutex); + + sys = system_get_instance(); + if (!sys) + goto conn_fail; + + /* Create sock*/ + connFd = socket(PF_INET, SOCK_STREAM, 0); + bzero(&peer_addr, sizeof(peer_addr)); + peer_addr.sin_family = PF_INET; + peer_addr.sin_port = htons(ICCP_TCP_PORT); + peer_addr.sin_addr.s_addr = inet_addr(csm->peer_ip); + if (connFd == -1) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "Peer IP:%s Socket FD creation failed.", + csm->peer_ip); + goto conn_fail; + } + + /* Set connect timeout secs*/ + con_tv.tv_sec = 0; + con_tv.tv_usec = CONNECT_TIMEOUT_MSEC * 1000; + if (setsockopt(connFd, SOL_SOCKET, SO_SNDTIMEO, &con_tv, len) == -1) + { + ICCPD_LOG_INFO(__FUNCTION__, "Set socket timeout fail"); + } + + err = bind(connFd, (struct sockaddr*)&(src_addr), sizeof(src_addr)); + if (err < 0) + { + ICCPD_LOG_INFO(__FUNCTION__, "Bind socket failed. Error = %d errno = %d ",err,errno); + goto conn_fail; + } + + /* Try conn*/ + ICCPD_LOG_INFO(__FUNCTION__, "Connecting. peer ip = [%s], %p", csm->peer_ip, csm); + connStat = connect(connFd, (struct sockaddr*)&(peer_addr), sizeof(peer_addr)); + ICCPD_LOG_INFO(__FUNCTION__, "Connection. fd = [%d], status = [%d], %p", + connFd, connStat, csm); + + if (connStat != 0) + { + /* Conn Fail*/ + goto conn_fail; + } + else + { + /* Conn OK*/ + struct epoll_event event; + int err; + event.data.fd = connFd; + event.events = EPOLLIN; + err = epoll_ctl(sys->epoll_fd, EPOLL_CTL_ADD, connFd, &event); + if (err) + goto conn_fail; + csm->sock_fd = connFd; + FD_SET(connFd, &(sys->readfd)); + sys->readfd_count++; + ICCPD_LOG_INFO(__FUNCTION__, "Connect to server %s sucess .", csm->peer_ip); + goto conn_ok; + } + + conn_fail: + if (connFd >= 0) + { + csm->sock_fd = -1; + close(connFd); + } + conn_ok: + time(&csm->connTimePrev); + session_conn_thread_unlock(&csm->conn_mutex); + return; +} + +/* Create socket connect to peer */ +int scheduler_prepare_session(struct CSM* csm) +{ + int ret = MCLAG_ERROR; + uint32_t local_ip = 0; + uint32_t peer_ip = 0; + + /* Init time_t*/ + if (csm->connTimePrev == 0) + { + time(&csm->connTimePrev); + } + + /* Don't conn to svr continously*/ + if ((time(NULL) - csm->connTimePrev) < CONNECT_INTERVAL_SEC) + { + goto no_time_update; + } + + /* Already conn?*/ + if (csm->sock_fd > 0) + { + goto time_update; + } + + if ((ret = scheduler_check_csm_config(csm)) < 0) + goto time_update; + + /* Who is client*/ + local_ip = inet_addr(csm->sender_ip); + peer_ip = inet_addr(csm->peer_ip); + if (local_ip > peer_ip) + { + goto time_update; + } + else if (local_ip == peer_ip) + { + ICCPD_LOG_WARN(__FUNCTION__, "Local IP must not be the same as the peer IP."); + goto time_update; + } + + if (session_conn_thread_trylock(&csm->conn_mutex) == 0) + { + session_client_conn_handler(csm); + session_conn_thread_unlock(&csm->conn_mutex); + } + + time_update: + time(&csm->connTimePrev); + return 0; + + no_time_update: + return 0; +} + +/* Server socket initialization */ +void scheduler_server_sock_init() +{ + int optval = 1; + struct System* sys = NULL; + struct sockaddr_in src_addr; + + if ((sys = system_get_instance()) == NULL) + return; + + sys->server_fd = socket(PF_INET, SOCK_STREAM, 0); + bzero(&(src_addr), sizeof(src_addr)); + src_addr.sin_family = PF_INET; + src_addr.sin_port = htons(ICCP_TCP_PORT); + src_addr.sin_addr.s_addr = INADDR_ANY; + + if (sys->server_fd == -1) + { + ICCPD_LOG_ERR(__FUNCTION__, "Server Socket FD creation failed."); + return; + } + + if (setsockopt(sys->server_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1) + { + ICCPD_LOG_INFO(__FUNCTION__, "Set socket option failed. Error"); + /*return;*/ + } + + if (bind(sys->server_fd, (struct sockaddr*)&(src_addr), sizeof(src_addr)) < 0) + { + ICCPD_LOG_INFO(__FUNCTION__, "Bind socket failed. Error"); + return; + } + + if (listen(sys->server_fd, MAX_ACCEPT_CONNETIONS) == -1) + { + ICCPD_LOG_INFO(__FUNCTION__, "Listen failed. Error"); + return; + } + + ICCPD_LOG_INFO(__FUNCTION__, "Server socket init done."); + + return; +} + +int iccp_get_server_sock_fd() +{ + struct System* sys = NULL; + + if ((sys = system_get_instance()) == NULL) + return 0; + + return sys->server_fd; +} + +/* Server socket initialization */ +int scheduler_check_csm_config(struct CSM* csm) +{ + int ret = 1; + struct LocalInterface* lif = NULL; + struct System* sys = NULL; + + if ((sys = system_get_instance()) == NULL) + return MCLAG_ERROR; + + if (csm == NULL ) + return MCLAG_ERROR; + + if (csm->mlag_id <= 0) + ret = MCLAG_ERROR; + else if (strlen(csm->peer_ip) <= 0) + ret = MCLAG_ERROR; + else if (strlen(csm->sender_ip) <= 0) + ret = MCLAG_ERROR; + else if (strlen(csm->peer_itf_name) != 0) + { + lif = local_if_find_by_name(csm->peer_itf_name); + if (lif == NULL) + { + /*if peer-link is configured but the interface is not created, peer connection can not establish*/ + return MCLAG_ERROR; + } + else + { + lif->is_peer_link = 1; + csm->peer_link_if = lif; + } + } + + if (ret == MCLAG_ERROR) + ICCPD_LOG_INFO(__FUNCTION__, "mclag config is not complete or conflicting, please check!"); + + /* Decide STP role*/ + iccp_csm_stp_role_count(csm); + + return ret; +} + +int scheduler_unregister_sock_read_event_callback(struct CSM* csm) +{ + struct System* sys = NULL; + + if ((sys = system_get_instance()) == NULL ) + return MCLAG_ERROR; + + if (csm == NULL ) + { + return MCLAG_ERROR; + } + + if (csm->sock_fd > 0) + { + FD_CLR(csm->sock_fd, &(sys->readfd)); + } + + return 0; +} + +void scheduler_session_disconnect_handler(struct CSM* csm) +{ + struct System* sys = NULL; + + if ((sys = system_get_instance()) == NULL ) + return; + + struct epoll_event event; + + if (csm == NULL) + return; + + session_conn_thread_lock(&csm->conn_mutex); + scheduler_unregister_sock_read_event_callback(csm); + if (csm->sock_fd > 0) + { + event.data.fd = csm->sock_fd; + event.events = EPOLLIN; + epoll_ctl(sys->epoll_fd, EPOLL_CTL_DEL, csm->sock_fd, &event); + + close(csm->sock_fd); + csm->sock_fd = -1; + } + + mlacp_peer_disconn_handler(csm); + MLACP(csm).current_state = MLACP_STATE_INIT; + iccp_csm_status_reset(csm, 0); + time(&csm->connTimePrev); + session_conn_thread_unlock(&csm->conn_mutex); + + return; +} diff --git a/src/iccpd/src/system.c b/src/iccpd/src/system.c new file mode 100644 index 000000000000..33aca67f8079 --- /dev/null +++ b/src/iccpd/src/system.c @@ -0,0 +1,203 @@ +/* + * system.c + * + * Copyright(c) 2016-2019 Nephos/Estinet. + * + * 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, see . + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Maintainer: jianjun, grace Li from nephos + */ + +#include + +#include "../include/iccp_csm.h" +#include "../include/logger.h" +#include "../include/iccp_netlink.h" +#include "../include/scheduler.h" + +/* Singleton */ +struct System* system_get_instance() +{ + static struct System* sys = NULL; + + if (sys == NULL ) + { + sys = (struct System*)malloc(sizeof(struct System)); + if (sys == NULL ) + { + ICCPD_LOG_WARN(__FUNCTION__, "Failed to obtain system instance."); + return NULL; + } + system_init(sys); + } + + return sys; +} + +/* System instance initialization */ +void system_init(struct System* sys) +{ + if (sys == NULL ) + return; + + sys->server_fd = -1; + sys->sync_fd = -1; + sys->sync_ctrl_fd = -1; + sys->arp_receive_fd = -1; + sys->ndisc_receive_fd = -1; + sys->epoll_fd = -1; + sys->family = -1; + sys->warmboot_start = 0; + sys->warmboot_exit = 0; + LIST_INIT(&(sys->csm_list)); + LIST_INIT(&(sys->lif_list)); + LIST_INIT(&(sys->lif_purge_list)); + + sys->log_file_path = strdup("/var/log/iccpd.log"); + sys->cmd_file_path = strdup("/var/run/iccpd/iccpd.vty"); + sys->config_file_path = strdup("/etc/iccpd/iccpd.conf"); + sys->mclagdctl_file_path = strdup("/var/run/iccpd/mclagdctl.sock"); + sys->pid_file_fd = 0; + sys->telnet_port = 2015; + FD_ZERO(&(sys->readfd)); + sys->readfd_count = 0; + sys->csm_trans_time = 0; + sys->need_sync_team_again = 0; + sys->need_sync_netlink_again = 0; + scheduler_server_sock_init(); + iccp_system_init_netlink_socket(); + iccp_init_netlink_event_fd(sys); +} + +/* System instance tear down */ +void system_finalize() +{ + struct System* sys = NULL; + struct CSM* csm = NULL; + struct LocalInterface* local_if = NULL; + + if ((sys = system_get_instance()) == NULL ) + return; + + ICCPD_LOG_INFO(__FUNCTION__, "System resource pool is destructing."); + + while (!LIST_EMPTY(&(sys->csm_list))) + { + csm = LIST_FIRST(&(sys->csm_list)); + iccp_csm_finalize(csm); + } + + /* Release all port objects */ + while (!LIST_EMPTY(&(sys->lif_list))) + { + local_if = LIST_FIRST(&(sys->lif_list)); + LIST_REMOVE(local_if, system_next); + local_if_finalize(local_if); + } + + while (!LIST_EMPTY(&(sys->lif_purge_list))) + { + local_if = LIST_FIRST(&(sys->lif_purge_list)); + LIST_REMOVE(local_if, system_purge_next); + local_if_finalize(local_if); + } + + iccp_system_dinit_netlink_socket(); + + if (sys->log_file_path != NULL ) + free(sys->log_file_path); + if (sys->cmd_file_path != NULL ) + free(sys->cmd_file_path); + if (sys->config_file_path != NULL ) + free(sys->config_file_path); + if (sys->pid_file_fd > 0) + close(sys->pid_file_fd); + if (sys->server_fd > 0) + close(sys->server_fd); + if (sys->sync_fd > 0) + close(sys->sync_fd); + if (sys->sync_ctrl_fd > 0) + close(sys->sync_ctrl_fd); + if (sys->arp_receive_fd > 0) + close(sys->arp_receive_fd); + if (sys->ndisc_receive_fd > 0) + close(sys->ndisc_receive_fd); + if (sys->sig_pipe_r > 0) + close(sys->sig_pipe_r); + if (sys->sig_pipe_w > 0) + close(sys->sig_pipe_w); + + if (sys->epoll_fd) + close(sys->epoll_fd); + + free(sys); + ICCPD_LOG_INFO(__FUNCTION__, "System resource pool destructed successfully..."); +} + +struct CSM* system_create_csm() +{ + struct System* sys = NULL; + struct CSM* csm = NULL; + + if ((sys = system_get_instance()) == NULL ) + return NULL; + + /* Create a new csm */ + csm = (struct CSM*)malloc(sizeof(struct CSM)); + if (csm == NULL ) + return NULL; + else + memset(csm, 0, sizeof(struct CSM)); + iccp_csm_init(csm); + LIST_INSERT_HEAD(&(sys->csm_list), csm, next); + + return csm; +} + +/* Get connect state machine instance by peer ip */ +struct CSM* system_get_csm_by_peer_ip(const char* peer_ip) +{ + struct System* sys = NULL; + struct CSM* csm = NULL; + + if ((sys = system_get_instance()) == NULL ) + return NULL; + + LIST_FOREACH(csm, &(sys->csm_list), next) + { + if (strcmp(csm->peer_ip, peer_ip) == 0) + return csm; + } + + return NULL; +} + +struct CSM* system_get_csm_by_mlacp_id(int id) +{ + struct System* sys = NULL; + struct CSM* csm = NULL; + + if ((sys = system_get_instance()) == NULL ) + return NULL; + + LIST_FOREACH(csm, &(sys->csm_list), next) + { + if (csm->app_csm.mlacp.id == id) + return csm; + } + + return NULL; +} diff --git a/src/ifupdown2/.gitignore b/src/ifupdown2/.gitignore new file mode 100644 index 000000000000..d1cfec62d283 --- /dev/null +++ b/src/ifupdown2/.gitignore @@ -0,0 +1 @@ +ifupdown2-1.2.8-1/ diff --git a/src/ifupdown2/Makefile b/src/ifupdown2/Makefile index 66b4df2ec32f..89228bedafae 100644 --- a/src/ifupdown2/Makefile +++ b/src/ifupdown2/Makefile @@ -14,7 +14,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : pushd ./ifupdown2-$(IFUPDOWN2_VERSION) # Build source and Debian packages - dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) + dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) --admindir $(SONIC_DPKG_ADMINDIR) popd # Move the newly-built .deb packages to the destination directory diff --git a/src/initramfs-tools/.gitignore b/src/initramfs-tools/.gitignore new file mode 100644 index 000000000000..a0991ff4402b --- /dev/null +++ b/src/initramfs-tools/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!Makefile diff --git a/src/initramfs-tools/Makefile b/src/initramfs-tools/Makefile index 0b08e4aa431e..f57b943d2d4f 100644 --- a/src/initramfs-tools/Makefile +++ b/src/initramfs-tools/Makefile @@ -5,21 +5,21 @@ SHELL = /bin/bash MAIN_TARGET = initramfs-tools_$(INITRAMFS_TOOLS_VERSION)_all.deb DERIVED_TARGETS = initramfs-tools-core_$(INITRAMFS_TOOLS_VERSION)_all.deb -INITRAMFS_TOOLS_REVISION = 18fc98e1b63b012f9bcf06ae3f5477872a5880c0 +INITRAMFS_TOOLS_REVISION = 40e544e13611c1b2690eb99a8096fc16c1b9c74e $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : # Obtaining the initramfs-tools rm -rf ./initramfs-tools - git clone --branch v0.130 https://salsa.debian.org/kernel-team/initramfs-tools.git ./initramfs-tools + git clone --branch v0.133 https://salsa.debian.org/kernel-team/initramfs-tools.git ./initramfs-tools # Patch pushd ./initramfs-tools git checkout $(INITRAMFS_TOOLS_REVISION) - patch -p1 < ../loopback-file-system-support.patch + QUILT_PATCHES=.. quilt push -a # Build the package rm -f debian/*.debhelper.log - dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) + dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) --admindir $(SONIC_DPKG_ADMINDIR) popd mv $(DERIVED_TARGETS) $* $(DEST)/ diff --git a/src/initramfs-tools/loopback-file-offset-support.patch b/src/initramfs-tools/loopback-file-offset-support.patch new file mode 100644 index 000000000000..396e1c92007a --- /dev/null +++ b/src/initramfs-tools/loopback-file-offset-support.patch @@ -0,0 +1,73 @@ +From: Samuel Angebault +Date: Tue, 9 Jun 2020 14:43:31 -0700 +Subject: Add loopback from file support + +By providing the extra loopoffset= parameter, it becomes possible to +mount a rootfs from within the file pointed by loop= at a given offset. +This mechanism uses losetup to create a loopdevice +--- + init | 4 ++++ + initramfs-tools.7 | 5 +++++ + scripts/functions | 8 ++++++++ + 3 files changed, 17 insertions(+) + +diff --git a/init b/init +index fe1005a..5fb054f 100755 +--- a/init ++++ b/init +@@ -52,6 +52,7 @@ export ROOTFSTYPE= + export LOOP= + export LOOPFLAGS= + export LOOPFSTYPE= ++export LOOPOFFSET= + export IP= + export DEVICE= + export BOOT= +@@ -116,6 +117,9 @@ for x in $(cat /proc/cmdline); do + loopfstype=*) + LOOPFSTYPE="${x#loopfstype=}" + ;; ++ loopoffset=*) ++ LOOPOFFSET="${x#loopoffset=}" ++ ;; + nfsroot=*) + # shellcheck disable=SC2034 + NFSROOT="${x#nfsroot=}" +diff --git a/initramfs-tools.7 b/initramfs-tools.7 +index 745e7a0..a5d92b0 100644 +--- a/initramfs-tools.7 ++++ b/initramfs-tools.7 +@@ -66,6 +66,11 @@ set the loop file system mount option string, if applicable. + \fB\fI loopfstype + set the loop file system type, if applicable. + ++.TP ++\fB\fI loopoffset ++set the loop file offset from which to mount the loop, if applicable. ++The default is 0 and requires loop to be defined. ++ + .TP + \fB\fI nfsroot + can be either "auto" to try to get the relevant information from DHCP or a +diff --git a/scripts/functions b/scripts/functions +index a17e740..2bef5cb 100644 +--- a/scripts/functions ++++ b/scripts/functions +@@ -473,6 +473,14 @@ mount_loop_root() + modprobe loop + modprobe "${FSTYPE}" + ++ if [ ! -z "${LOOPOFFSET}" ]; then ++ # create a loop device for the fs within the file ++ loopdev="$(losetup -f)" ++ losetup -o "${LOOPOFFSET:-0}" "${loopdev}" "${loopfile}" || \ ++ panic "ALERT! $loopdev could not be setup using $loopfile" ++ loopfile="$loopdev" ++ fi ++ + # FIXME This has no error checking + if [ -z "${LOOPFLAGS}" ]; then + mount ${roflag} -o loop -t "${FSTYPE}" "$loopfile" "${rootmnt}" +-- +2.26.2 + diff --git a/src/initramfs-tools/loopback-file-system-support.patch b/src/initramfs-tools/loopback-file-system-support.patch index e5b75478dc96..fbeb347f9d23 100644 --- a/src/initramfs-tools/loopback-file-system-support.patch +++ b/src/initramfs-tools/loopback-file-system-support.patch @@ -13,11 +13,29 @@ And added NFS support! Full patch below... live well, vagrant +--- + init | 12 ++++++++++++ + initramfs-tools.7 | 13 +++++++++++++ + scripts/functions | 40 ++++++++++++++++++++++++++++++++++++++++ + scripts/local | 7 ++++++- + scripts/nfs | 4 ++++ + 5 files changed, 75 insertions(+), 1 deletion(-) + diff --git a/init b/init -index abf7f25..2760bcb 100755 +index 3dc9f6b..fe1005a 100755 --- a/init +++ b/init -@@ -98,6 +98,15 @@ for x in $(cat /proc/cmdline); do +@@ -49,6 +49,9 @@ export ROOT= + export ROOTDELAY= + export ROOTFLAGS= + export ROOTFSTYPE= ++export LOOP= ++export LOOPFLAGS= ++export LOOPFSTYPE= + export IP= + export DEVICE= + export BOOT= +@@ -104,6 +107,15 @@ for x in $(cat /proc/cmdline); do ;; esac ;; @@ -31,16 +49,17 @@ index abf7f25..2760bcb 100755 + LOOPFSTYPE="${x#loopfstype=}" + ;; nfsroot=*) + # shellcheck disable=SC2034 NFSROOT="${x#nfsroot=}" - ;; -diff --git a/initramfs-tools.8 b/initramfs-tools.8 -index ea8c098..ce8e830 100644 ---- a/initramfs-tools.8 -+++ b/initramfs-tools.8 -@@ -42,6 +42,19 @@ The default is 180 seconds. +diff --git a/initramfs-tools.7 b/initramfs-tools.7 +index 45b7de7..745e7a0 100644 +--- a/initramfs-tools.7 ++++ b/initramfs-tools.7 +@@ -53,6 +53,19 @@ The default is 180 seconds. + \fB\fI rootflags set the file system mount option string. - .TP ++.TP +\fB\fI loop +path within the original root file system to loop-mount and use as the +real root file system. @@ -53,15 +72,14 @@ index ea8c098..ce8e830 100644 +\fB\fI loopfstype +set the loop file system type, if applicable. + -+.TP + .TP \fB\fI nfsroot can be either "auto" to try to get the relevant information from DHCP or a - string of the form NFSSERVER:NFSPATH or NFSSERVER:NFSPATH:NFSOPTS. diff --git a/scripts/functions b/scripts/functions -index 8c1bb1f..2ed3ce3 100644 +index 077697f..a17e740 100644 --- a/scripts/functions +++ b/scripts/functions -@@ -426,6 +426,42 @@ mountfs() +@@ -445,6 +445,46 @@ mountfs() ${type}_mount_fs "$1" } @@ -69,14 +87,14 @@ index 8c1bb1f..2ed3ce3 100644 +mount_loop_root() +{ + mkdir -p /host -+ mount -o move ${rootmnt} /host ++ mount -o move "${rootmnt}" /host + loopfile="/host/${LOOP#/}" + + while [ ! -e "$loopfile" ]; do + panic "ALERT! $loopfile does not exist. Dropping to a shell!" + done + -+ if [ ${readonly} = y ]; then ++ if [ "${readonly?}" = "y" ]; then + roflag=-r + else + roflag=-w @@ -91,13 +109,17 @@ index 8c1bb1f..2ed3ce3 100644 + + # FIXME This has no error checking + modprobe loop -+ modprobe ${FSTYPE} ++ modprobe "${FSTYPE}" + + # FIXME This has no error checking -+ mount ${roflag} -o loop -t ${FSTYPE} ${LOOPFLAGS} "$loopfile" ${rootmnt} ++ if [ -z "${LOOPFLAGS}" ]; then ++ mount ${roflag} -o loop -t "${FSTYPE}" "$loopfile" "${rootmnt}" ++ else ++ mount ${roflag} -o loop -t "${FSTYPE}" "${LOOPFLAGS}" "$loopfile" "${rootmnt}" ++ fi + -+ if [ -d ${rootmnt}/host ]; then -+ mount -o move /host ${rootmnt}/host ++ if [ -d "${rootmnt}/host" ]; then ++ mount -o move /host "${rootmnt}/host" + fi +} + @@ -105,22 +127,22 @@ index 8c1bb1f..2ed3ce3 100644 # boot scripts. mountroot() diff --git a/scripts/local b/scripts/local -index f6424f0..072013e 100644 +index a103e68..2ef6413 100644 --- a/scripts/local +++ b/scripts/local -@@ -135,7 +135,8 @@ local_mount_root() +@@ -170,7 +170,8 @@ local_mount_root() - ROOT=$(resolve_device "$ROOT") + local_premount -- if [ "${readonly}" = "y" ]; then -+ if [ "${readonly}" = "y" ] && \ -+ ([ -z "$LOOP" ] || [ "${FSTYPE#ntfs}" = "$FSTYPE" ]); then +- if [ "${readonly?}" = "y" ]; then ++ if [ "${readonly?}" = "y" ] && \ ++ { [ -z "$LOOP" ] || [ "${FSTYPE#ntfs}" = "$FSTYPE" ]; }; then roflag=-r else roflag=-w -@@ -153,6 +154,10 @@ local_mount_root() - else - mount ${roflag} ${ROOTFLAGS} ${ROOT} ${rootmnt} +@@ -183,6 +184,10 @@ local_mount_root() + if ! mount ${roflag} ${FSTYPE:+-t "${FSTYPE}"} ${ROOTFLAGS} "${ROOT}" "${rootmnt?}"; then + panic "Failed to mount ${ROOT} as root file system." fi + + if [ "${LOOP}" ]; then @@ -130,13 +152,13 @@ index f6424f0..072013e 100644 local_mount_fs() diff --git a/scripts/nfs b/scripts/nfs -index 1c29850..d382413 100644 +index 40c92c7..dfa8e88 100644 --- a/scripts/nfs +++ b/scripts/nfs -@@ -72,6 +72,10 @@ nfs_mount_root_impl() - fi +@@ -73,6 +73,10 @@ nfs_mount_root_impl() - nfsmount -o nolock ${roflag} ${NFSOPTS} ${NFSROOT} ${rootmnt} + # shellcheck disable=SC2086 + nfsmount -o nolock ${roflag} ${NFSOPTS} "${NFSROOT}" "${rootmnt?}" + + if [ "${LOOP}" ]; then + mount_loop_root @@ -144,3 +166,6 @@ index 1c29850..d382413 100644 } # NFS root mounting +-- +2.17.1 + diff --git a/src/initramfs-tools/series b/src/initramfs-tools/series new file mode 100644 index 000000000000..ba6e8edfacd4 --- /dev/null +++ b/src/initramfs-tools/series @@ -0,0 +1,2 @@ +loopback-file-system-support.patch +loopback-file-offset-support.patch diff --git a/src/iproute2/.gitignore b/src/iproute2/.gitignore new file mode 100644 index 000000000000..a0991ff4402b --- /dev/null +++ b/src/iproute2/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!Makefile diff --git a/src/iproute2/Makefile b/src/iproute2/Makefile index 8748550a1d78..5b354ce8b019 100644 --- a/src/iproute2/Makefile +++ b/src/iproute2/Makefile @@ -17,7 +17,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : dpkg-source -x iproute2_$(IPROUTE2_VERSION_FULL).dsc pushd iproute2-$(IPROUTE2_VERSION) - dpkg-buildpackage -us -uc -b -j$(SONIC_CONFIG_MAKE_JOBS) + dpkg-buildpackage -us -uc -b -j$(SONIC_CONFIG_MAKE_JOBS) --admindir $(SONIC_DPKG_ADMINDIR) popd mv $* $(DEST)/ diff --git a/src/iptables/.gitignore b/src/iptables/.gitignore new file mode 100644 index 000000000000..d19db76ab9a9 --- /dev/null +++ b/src/iptables/.gitignore @@ -0,0 +1,4 @@ +* +!.gitignore +!Makefile +!patch/ diff --git a/src/iptables/Makefile b/src/iptables/Makefile index 60154c19ddb1..681ef5d2dcc3 100644 --- a/src/iptables/Makefile +++ b/src/iptables/Makefile @@ -3,10 +3,10 @@ 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 +DERIVED_TARGETS = libip4tc0_$(IPTABLES_VERSION_FULL)_$(CONFIGURED_ARCH).deb \ + libip6tc0_$(IPTABLES_VERSION_FULL)_$(CONFIGURED_ARCH).deb \ + libiptc0_$(IPTABLES_VERSION_FULL)_$(CONFIGURED_ARCH).deb \ + libxtables12_$(IPTABLES_VERSION_FULL)_$(CONFIGURED_ARCH).deb IPTABLES_URL = http://deb.debian.org/debian/pool/main/i/iptables @@ -38,7 +38,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : stg import -s ../patch/series # Build source and Debian packages - dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) + dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) --admindir $(SONIC_DPKG_ADMINDIR) popd # Move the newly-built .deb packages to the destination directory 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 index f7fba85a270b..9ed886bb5dbd 100644 --- 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 @@ -10,7 +10,7 @@ Subject: [PATCH] Passing fullcone option for SNAT and DNAT 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/extensions/libipt_DNAT.c b/extensions/libipt_DNAT.c -index a14d16f..4bfab98 100644 +index 4907a2e..543421c 100644 --- a/extensions/libipt_DNAT.c +++ b/extensions/libipt_DNAT.c @@ -8,14 +8,20 @@ @@ -19,7 +19,7 @@ index a14d16f..4bfab98 100644 +/* 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) ++#define NF_NAT_RANGE_FULLCONE (1 << 6) + enum { O_TO_DEST = 0, @@ -42,8 +42,17 @@ index a14d16f..4bfab98 100644 +"[--random] [--persistent] [--fullcone]\n"); } + static void DNAT_help_v2(void) +@@ -41,7 +47,7 @@ static void DNAT_help_v2(void) + "DNAT target options:\n" + " --to-destination [[-]][:port[-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[] = { +@@ -49,6 +55,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}, @@ -51,7 +60,7 @@ index a14d16f..4bfab98 100644 XTOPT_TABLEEND, }; -@@ -185,10 +192,14 @@ static void DNAT_parse(struct xt_option_call *cb) +@@ -194,10 +201,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; @@ -66,7 +75,7 @@ index a14d16f..4bfab98 100644 } 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, +@@ -233,6 +244,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"); @@ -75,7 +84,7 @@ index a14d16f..4bfab98 100644 } } -@@ -239,6 +252,8 @@ static void DNAT_save(const void *ip, const struct xt_entry_target *target) +@@ -248,6 +261,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"); @@ -84,7 +93,7 @@ index a14d16f..4bfab98 100644 } } -@@ -282,6 +297,11 @@ static int DNAT_xlate(struct xt_xlate *xl, +@@ -291,6 +306,11 @@ static int DNAT_xlate(struct xt_xlate *xl, sep = ","; xt_xlate_add(xl, "%spersistent", sep); } @@ -96,32 +105,77 @@ index a14d16f..4bfab98 100644 } return 1; +@@ -426,10 +446,14 @@ static void DNAT_parse_v2(struct xt_option_call *cb) + static void DNAT_fcheck_v2(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_range2 *range = cb->data; + + if ((cb->xflags & f) == f) + range->flags |= NF_NAT_RANGE_PROTO_RANDOM; ++ ++ if ((cb->xflags & c) == c) ++ range->flags |= NF_NAT_RANGE_FULLCONE; + } + + static void print_range_v2(const struct nf_nat_range2 *range) +@@ -461,6 +485,8 @@ static void DNAT_print_v2(const void *ip, const struct xt_entry_target *target, + printf(" random"); + if (range->flags & NF_NAT_RANGE_PERSISTENT) + printf(" persistent"); ++ if (range->flags & NF_NAT_RANGE_FULLCONE) ++ printf(" fullcone"); + } + + static void DNAT_save_v2(const void *ip, const struct xt_entry_target *target) +@@ -473,6 +499,8 @@ static void DNAT_save_v2(const void *ip, const struct xt_entry_target *target) + printf(" --random"); + if (range->flags & NF_NAT_RANGE_PERSISTENT) + printf(" --persistent"); ++ if (range->flags & NF_NAT_RANGE_FULLCONE) ++ printf(" --fullcone"); + } + + static void print_range_xlate_v2(const struct nf_nat_range2 *range, +@@ -512,6 +540,11 @@ static int DNAT_xlate_v2(struct xt_xlate *xl, + sep = ","; + xt_xlate_add(xl, "%spersistent", sep); + } ++ if (range->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 +index 90bf606..169457d 100644 --- a/extensions/libipt_MASQUERADE.c +++ b/extensions/libipt_MASQUERADE.c -@@ -8,9 +8,15 @@ +@@ -8,10 +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) ++#define NF_NAT_RANGE_FULLCONE (1 << 6) + enum { O_TO_PORTS = 0, O_RANDOM, -+ O_RANDOM_FULLY, + 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" +@@ -23,13 +28,16 @@ static void MASQUERADE_help(void) " --random\n" --" Randomize source port.\n"); -+" Randomize source port.\n" + " Randomize source port.\n" + " --random-fully\n" +-" Fully randomize source port.\n"); ++" Fully randomize source port.\n" +" --fullcone\n" +" Do fullcone NAT mapping.\n"); } @@ -129,13 +183,14 @@ index b7b5fc7..88ff650 100644 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 = "random-fully", .id = O_RANDOM_FULLY, .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; +@@ -104,6 +112,9 @@ static void MASQUERADE_parse(struct xt_option_call *cb) + case O_RANDOM_FULLY: + mr->range[0].flags |= NF_NAT_RANGE_PROTO_RANDOM_FULLY; break; + case O_FULLCONE: + mr->range[0].flags |= NF_NAT_RANGE_FULLCONE; @@ -143,25 +198,27 @@ index b7b5fc7..88ff650 100644 } } -@@ -116,6 +128,8 @@ MASQUERADE_print(const void *ip, const struct xt_entry_target *target, +@@ -126,6 +137,9 @@ 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_PROTO_RANDOM_FULLY) + printf(" random-fully"); ++ + 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) +@@ -145,6 +159,9 @@ 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_PROTO_RANDOM_FULLY) + printf(" --random-fully"); ++ + 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, +@@ -166,6 +183,9 @@ static int MASQUERADE_xlate(struct xt_xlate *xl, if (r->flags & NF_NAT_RANGE_PROTO_RANDOM) xt_xlate_add(xl, "random "); @@ -172,7 +229,7 @@ index b7b5fc7..88ff650 100644 } diff --git a/extensions/libipt_SNAT.c b/extensions/libipt_SNAT.c -index e92d811..9634ba9 100644 +index e92d811..ad42b8c 100644 --- a/extensions/libipt_SNAT.c +++ b/extensions/libipt_SNAT.c @@ -8,16 +8,22 @@ @@ -181,7 +238,7 @@ index e92d811..9634ba9 100644 +/* 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) ++#define NF_NAT_RANGE_FULLCONE (1 << 6) + enum { O_TO_SRC = 0, @@ -262,6 +319,3 @@ index e92d811..9634ba9 100644 } return 1; --- -2.18.0 - diff --git a/src/isc-dhcp/.gitignore b/src/isc-dhcp/.gitignore new file mode 100644 index 000000000000..d19db76ab9a9 --- /dev/null +++ b/src/isc-dhcp/.gitignore @@ -0,0 +1,4 @@ +* +!.gitignore +!Makefile +!patch/ diff --git a/src/isc-dhcp/Makefile b/src/isc-dhcp/Makefile index 45535574ed61..2adf6bba2aa3 100644 --- a/src/isc-dhcp/Makefile +++ b/src/isc-dhcp/Makefile @@ -2,8 +2,8 @@ SHELL = /bin/bash .SHELLFLAGS += -e -MAIN_TARGET = isc-dhcp-relay_$(ISC_DHCP_VERSION)_$(CONFIGURED_ARCH).deb -DERIVED_TARGETS = isc-dhcp-relay-dbgsym_$(ISC_DHCP_VERSION)_$(CONFIGURED_ARCH).deb +MAIN_TARGET = $(ISC_DHCP_RELAY) +DERIVED_TARGETS = $(ISC_DHCP_RELAY_DBG) $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : # Remove any stale files @@ -16,14 +16,14 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : # Reset HEAD to the commit of the proper tag # NOTE: Using "git checkout " here detaches our HEAD, # which stg doesn't like, so we use this method instead - git reset --hard debian/$(ISC_DHCP_VERSION) + git reset --hard debian/$(ISC_DHCP_VERSION_FULL) # 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) + dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) --admindir $(SONIC_DPKG_ADMINDIR) popd # Move the newly-built .deb packages to the destination directory diff --git a/src/isc-dhcp/patch/0002-Customizable-Option-82-circuit-ID-and-remote-ID-fiel.patch b/src/isc-dhcp/patch/0002-Customizable-Option-82-circuit-ID-and-remote-ID-fiel.patch index a796845e516b..e6d09dedc711 100644 --- a/src/isc-dhcp/patch/0002-Customizable-Option-82-circuit-ID-and-remote-ID-fiel.patch +++ b/src/isc-dhcp/patch/0002-Customizable-Option-82-circuit-ID-and-remote-ID-fiel.patch @@ -8,7 +8,7 @@ Subject: [PATCH] Customizable Option 82 circuit ID and remote ID fields 1 file changed, 147 insertions(+), 24 deletions(-) diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c -index 344cee7..7b4c1ef 100644 +index 0cb2ef6..418b943 100644 --- a/relay/dhcrelay.c +++ b/relay/dhcrelay.c @@ -75,6 +75,8 @@ int bad_circuit_id = 0; /* Circuit ID option in matching RAI option @@ -19,8 +19,8 @@ index 344cee7..7b4c1ef 100644 +const char *agent_remote_id_fmt = NULL; /* Remote ID custom format string. */ int max_hop_count = 10; /* Maximum hop count */ - #ifdef DHCPv6 -@@ -148,9 +150,19 @@ static const char url[] = + int no_daemon = 0; +@@ -151,10 +153,20 @@ static const char url[] = char *progname; @@ -35,35 +35,66 @@ index 344cee7..7b4c1ef 100644 +" %%I DHCP relay agent IP Address\n" \ + #ifdef DHCPv6 + #ifdef RELAY_PORT + #define DHCRELAY_USAGE \ +-"Usage: %s [-4] [-d] [-q] [-a] [-D]\n" \ ++"Usage: %s [-4] [-d] [-q] [-a ] [-D]\n"\ + " [-A ] [-c ]\n" \ + " [-p | -rp ]\n" \ + " [-pf ] [--no-pid]\n"\ +@@ -171,11 +183,11 @@ char *progname; + " -l lower0 [ ... -l lowerN]\n" \ + " -u upper0 [ ... -u upperN]\n" \ + " lower (client link): [address%%]interface[#index]\n" \ +-" upper (server link): [address%%]interface\n\n" \ ++" upper (server link): [address%%]interface\n\n" DHCRELAY_OPTION82_USAGE \ + " %s {--version|--help|-h}" + #else #define DHCRELAY_USAGE \ --"Usage: %s [-4] [-d] [-q] [-a] [-D]\n"\ +-"Usage: %s [-4] [-d] [-q] [-a] [-D]\n" \ +"Usage: %s [-4] [-d] [-q] [-a ] [-D]\n"\ " [-A ] [-c ] [-p ]\n" \ " [-pf ] [--no-pid]\n"\ " [-m append|replace|forward|discard]\n" \ -@@ -165,17 +177,18 @@ char *progname; +@@ -190,13 +202,13 @@ char *progname; " -l lower0 [ ... -l lowerN]\n" \ " -u upper0 [ ... -u upperN]\n" \ - " lower (client link): [address%%]interface[#index]\n" \ --" upper (server link): [address%%]interface" -+" upper (server link): [address%%]interface\n\n" DHCRELAY_OPTION82_USAGE + " lower (client link): [address%%]interface[#index]\n" \ +-" upper (server link): [address%%]interface\n\n" \ ++" upper (server link): [address%%]interface\n\n" DHCRELAY_OPTION82_USAGE \ + " %s {--version|--help|-h}" + #endif + #else /* !DHCPv6 */ + #ifdef RELAY_PORT + #define DHCRELAY_USAGE \ +-"Usage: %s [-d] [-q] [-a] [-D] [-A ] [-c ]\n" \ ++"Usage: %s [-d] [-q] [-a ] [-D] [-A ] [-c ]\n" \ + " [-p | -rp ]\n" \ + " [-pf ] [--no-pid]\n" \ + " [-m append|replace|forward|discard]\n" \ +@@ -204,18 +216,18 @@ char *progname; + " [-iu interface0 [ ... -iu interfaceN]\n" \ + " [-id interface0 [ ... -id interfaceN]\n" \ + " [-U interface]\n" \ +-" server0 [ ... serverN]\n\n" \ ++" server0 [ ... serverN]\n\n" DHCRELAY_OPTION82_USAGE \ + " %s {--version|--help|-h}" #else #define DHCRELAY_USAGE \ -"Usage: %s [-d] [-q] [-a] [-D] [-A ] [-c ] [-p ]\n" \ -+"Usage: %s [-d] [-q] [-a ] [-D]\n" \ -+" [-A ] [-c ] [-p ]\n" \ ++"Usage: %s [-d] [-q] [-a ] [-D] [-A ] [-c ] [-p ]\n" \ " [-pf ] [--no-pid]\n" \ " [-m append|replace|forward|discard]\n" \ " [-i interface0 [ ... -i interfaceN]\n" \ " [-iu interface0 [ ... -iu interfaceN]\n" \ " [-id interface0 [ ... -id interfaceN]\n" \ " [-U interface]\n" \ --" server0 [ ... serverN]\n\n" -+" server0 [ ... serverN]\n\n" DHCRELAY_OPTION82_USAGE +-" server0 [ ... serverN]\n\n" \ ++" server0 [ ... serverN]\n\n" DHCRELAY_OPTION82_USAGE \ + " %s {--version|--help|-h}" #endif - - /*! -@@ -354,6 +367,15 @@ main(int argc, char **argv) { + #endif +@@ -471,6 +483,15 @@ main(int argc, char **argv) { local_family_set = 1; local_family = AF_INET; #endif @@ -79,7 +110,7 @@ index 344cee7..7b4c1ef 100644 add_agent_options = 1; } else if (!strcmp(argv[i], "-A")) { #ifdef DHCPv6 -@@ -1050,6 +1072,81 @@ find_interface_by_agent_option(struct dhcp_packet *packet, +@@ -1171,6 +1192,81 @@ find_interface_by_agent_option(struct dhcp_packet *packet, return (-1); } @@ -161,7 +192,7 @@ index 344cee7..7b4c1ef 100644 /* * Examine a packet to see if it's a candidate to have a Relay * Agent Information option tacked onto its tail. If it is, tack -@@ -1059,9 +1156,12 @@ static int +@@ -1180,9 +1276,12 @@ static int add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, unsigned length, struct in_addr giaddr) { int is_dhcp = 0, mms; @@ -175,7 +206,7 @@ index 344cee7..7b4c1ef 100644 /* If we're not adding agent options to packets, we can skip this. */ -@@ -1195,17 +1295,40 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, +@@ -1316,17 +1415,40 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, op = sp; #endif @@ -227,7 +258,7 @@ index 344cee7..7b4c1ef 100644 } if (adding_link_select) { -@@ -1224,7 +1347,7 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, +@@ -1351,7 +1473,7 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, * If not, forward without adding the option. */ if (max - sp >= optlen + 3) { @@ -236,7 +267,7 @@ index 344cee7..7b4c1ef 100644 /* Okay, cons up *our* Relay Agent Information option. */ *sp++ = DHO_DHCP_AGENT_OPTIONS; -@@ -1232,16 +1355,16 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, +@@ -1359,16 +1481,16 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, /* Copy in the circuit id... */ *sp++ = RAI_CIRCUIT_ID; diff --git a/src/isc-dhcp/patch/0003-Support-for-obtaining-name-of-physical-interface-tha.patch b/src/isc-dhcp/patch/0003-Support-for-obtaining-name-of-physical-interface-tha.patch index fd9ff420d970..af3052e4b088 100644 --- a/src/isc-dhcp/patch/0003-Support-for-obtaining-name-of-physical-interface-tha.patch +++ b/src/isc-dhcp/patch/0003-Support-for-obtaining-name-of-physical-interface-tha.patch @@ -9,10 +9,10 @@ Subject: [PATCH] Support for obtaining name of physical interface that is a 1 file changed, 65 insertions(+), 2 deletions(-) diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c -index 4659660..0f7d658 100644 +index db1af9c..f2418e8 100644 --- a/relay/dhcrelay.c +++ b/relay/dhcrelay.c -@@ -1072,6 +1072,47 @@ find_interface_by_agent_option(struct dhcp_packet *packet, +@@ -1192,6 +1192,47 @@ find_interface_by_agent_option(struct dhcp_packet *packet, return (-1); } @@ -60,7 +60,7 @@ index 4659660..0f7d658 100644 /* * Format the message that will be used by circuit_id and remote_id */ -@@ -1104,8 +1145,30 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack +@@ -1224,8 +1265,30 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack break; case 'p': /* Name of interface that we received the request from */ @@ -89,7 +89,7 @@ index 4659660..0f7d658 100644 + } + + str = ifname; -+ } ++ } break; case 'P': /* Physical address of interface that we received the request from */ diff --git a/src/isc-dhcp/patch/0004-Support-for-loading-port-alias-map-file-to-replace-p.patch b/src/isc-dhcp/patch/0004-Support-for-loading-port-alias-map-file-to-replace-p.patch index b564a0822a0c..f26871019b63 100644 --- a/src/isc-dhcp/patch/0004-Support-for-loading-port-alias-map-file-to-replace-p.patch +++ b/src/isc-dhcp/patch/0004-Support-for-loading-port-alias-map-file-to-replace-p.patch @@ -9,10 +9,10 @@ Subject: [PATCH] Support for loading port alias map file to replace port name 1 file changed, 104 insertions(+), 1 deletion(-) diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c -index 0f7d658..797dac6 100644 +index 00c81d3..54f132a 100644 --- a/relay/dhcrelay.c +++ b/relay/dhcrelay.c -@@ -126,6 +126,14 @@ static void setup_streams(void); +@@ -129,6 +129,14 @@ static void setup_streams(void); char *dhcrelay_sub_id = NULL; #endif @@ -27,7 +27,7 @@ index 0f7d658..797dac6 100644 static void do_relay4(struct interface_info *, struct dhcp_packet *, unsigned int, unsigned int, struct iaddr, struct hardware *); -@@ -140,6 +148,10 @@ static int strip_relay_agent_options(struct interface_info *, +@@ -143,6 +151,10 @@ static int strip_relay_agent_options(struct interface_info *, static void request_v4_interface(const char* name, int flags); @@ -36,9 +36,9 @@ index 0f7d658..797dac6 100644 +static void free_interface_alias_map(void); + static const char copyright[] = - "Copyright 2004-2016 Internet Systems Consortium."; + "Copyright 2004-2018 Internet Systems Consortium."; static const char arr[] = "All rights reserved."; -@@ -155,7 +167,7 @@ char *progname; +@@ -158,7 +170,7 @@ char *progname; "\n" \ " %%%% A single %%\n" \ " %%h Hostname of device\n" \ @@ -47,23 +47,23 @@ index 0f7d658..797dac6 100644 " %%P Hardware address of interface that generated the request\n" \ " %%C Client hardware address\n" \ " %%I DHCP relay agent IP Address\n" \ -@@ -166,6 +178,7 @@ char *progname; - " [-A ] [-c ] [-p ]\n" \ +@@ -171,6 +183,7 @@ char *progname; + " [-p | -rp ]\n" \ " [-pf ] [--no-pid]\n"\ " [-m append|replace|forward|discard]\n" \ +" [--name-alias-map-file ]\n" \ " [-i interface0 [ ... -i interfaceN]\n" \ " [-iu interface0 [ ... -iu interfaceN]\n" \ " [-id interface0 [ ... -id interfaceN]\n" \ -@@ -173,6 +186,7 @@ char *progname; - " server0 [ ... serverN]\n\n" \ - " %s -6 [-d] [-q] [-I] [-c ] [-p ]\n" \ +@@ -179,6 +192,7 @@ char *progname; + " %s -6 [-d] [-q] [-I] [-c ]\n" \ + " [-p | -rp ]\n" \ " [-pf ] [--no-pid]\n" \ +" [--name-alias-map-file ]\n" \ " [-s ]\n" \ " -l lower0 [ ... -l lowerN]\n" \ " -u upper0 [ ... -u upperN]\n" \ -@@ -503,6 +517,11 @@ main(int argc, char **argv) { +@@ -619,6 +633,11 @@ main(int argc, char **argv) { no_dhcrelay_pid = ISC_TRUE; } else if (!strcmp(argv[i], "--no-pid")) { no_pid_file = ISC_TRUE; @@ -72,10 +72,10 @@ index 0f7d658..797dac6 100644 + usage(use_noarg, argv[i-1]); + if (load_interface_alias_map(argv[i]) != 0) + log_fatal("Failed to load interface name-alias map."); - } else if (!strcmp(argv[i], "--version")) { - log_info("isc-dhcrelay-%s", PACKAGE_VERSION); - exit(0); -@@ -726,6 +745,7 @@ main(int argc, char **argv) { + } else if (argv[i][0] == '-') { + usage("Unknown command: %s", argv[i]); + } else { +@@ -841,6 +860,7 @@ main(int argc, char **argv) { dispatch(); /* In fact dispatch() never returns. */ @@ -83,7 +83,7 @@ index 0f7d658..797dac6 100644 return (0); } -@@ -1151,6 +1171,7 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack +@@ -1271,6 +1291,7 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack */ if (packet->htype && !packet->giaddr.s_addr) { int ret = 0, vlanid = 0; @@ -91,7 +91,7 @@ index 0f7d658..797dac6 100644 ret = _bridgefdbquery(print_hw_addr(packet->htype, packet->hlen, packet->chaddr), ifname, -@@ -1167,6 +1188,18 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack +@@ -1287,6 +1308,18 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack strncpy(ifname, ip->name, IFNAMSIZ); } @@ -105,12 +105,12 @@ index 0f7d658..797dac6 100644 + // ifname, ifalias, print_hw_addr (packet->htype, packet->hlen, packet->chaddr)); + + strncpy(ifname, ifalias, IFNAMSIZ); -+ } ++ } + str = ifname; - } + } break; -@@ -2096,3 +2129,73 @@ void request_v4_interface(const char* name, int flags) { +@@ -2313,3 +2346,73 @@ void request_v4_interface(const char* name, int flags) { interface_snorf(tmp, (INTERFACE_REQUESTED | flags)); interface_dereference(&tmp, MDL); } diff --git a/src/isc-dhcp/patch/0005-Add-enable-use-sockets-to-configure-flags-in-debian-.patch b/src/isc-dhcp/patch/0005-Add-enable-use-sockets-to-configure-flags-in-debian-.patch index 7c39f977bb3b..7e9bcc30fb89 100644 --- a/src/isc-dhcp/patch/0005-Add-enable-use-sockets-to-configure-flags-in-debian-.patch +++ b/src/isc-dhcp/patch/0005-Add-enable-use-sockets-to-configure-flags-in-debian-.patch @@ -9,15 +9,15 @@ Subject: [PATCH 1/3] Add --enable-use-sockets to configure flags in 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/rules b/debian/rules -index 114606b..9919237 100755 +index d3fcc1d..2a7219d 100755 --- a/debian/rules +++ b/debian/rules -@@ -23,7 +23,7 @@ CFLAGS+=-D_PATH_DHCLIENT_CONF='\"/etc/dhcp/dhclient.conf\"' +@@ -24,7 +24,7 @@ CFLAGS+=-D_PATH_DHCLIENT_CONF='\"/etc/dhcp/dhclient.conf\"' CFLAGS+=-D_PATH_DHCLIENT_DB='\"$(LEASE_PATH)/dhclient.leases\"' CFLAGS+=-D_PATH_DHCLIENT6_DB='\"$(LEASE_PATH)/dhclient6.leases\"' --CONFFLAGS=--prefix=/usr --enable-log-pid --enable-paranoia -+CONFFLAGS=--prefix=/usr --enable-log-pid --enable-paranoia --enable-use-sockets +-CONFFLAGS=--prefix=/usr --with-libbind=/usr --enable-log-pid --enable-paranoia ++CONFFLAGS=--prefix=/usr --with-libbind=/usr --enable-log-pid --enable-paranoia --enable-use-sockets # cross-architecture building ifneq ($(DEB_HOST_GNU_TYPE),$(DEB_BUILD_GNU_TYPE)) diff --git a/src/isc-dhcp/patch/0007-If-destination-of-BOOTREQUEST-is-directed-broadcast-.patch b/src/isc-dhcp/patch/0007-If-destination-of-BOOTREQUEST-is-directed-broadcast-.patch index e64f8439e2a2..bf24e448ea1a 100644 --- a/src/isc-dhcp/patch/0007-If-destination-of-BOOTREQUEST-is-directed-broadcast-.patch +++ b/src/isc-dhcp/patch/0007-If-destination-of-BOOTREQUEST-is-directed-broadcast-.patch @@ -12,52 +12,44 @@ Subject: [PATCH 3/3] If destination of BOOTREQUEST is directed broadcast, 3 files changed, 131 insertions(+), 16 deletions(-) diff --git a/common/discover.c b/common/discover.c -index 8e7f632..73eb8a9 100644 +index 98ac46a..53afecc 100644 --- a/common/discover.c +++ b/common/discover.c -@@ -227,6 +227,7 @@ struct iface_conf_list { +@@ -236,6 +236,7 @@ struct iface_conf_list { struct iface_info { char name[IF_NAMESIZE+1]; /* name of the interface, e.g. "bge0" */ struct sockaddr_storage addr; /* address information */ -+ struct sockaddr_storage netmask; /* netmask information */ ++ struct sockaddr_storage netmask; /* netmask information */ isc_uint64_t flags; /* interface flags, e.g. IFF_LOOPBACK */ }; -@@ -401,6 +402,7 @@ struct iface_conf_list { - struct iface_info { - char name[IFNAMSIZ]; /* name of the interface, e.g. "eth0" */ - struct sockaddr_storage addr; /* address information */ -+ struct sockaddr_storage netmask; /* netmask information */ - isc_uint64_t flags; /* interface flags, e.g. IFF_LOOPBACK */ - }; - -@@ -576,6 +578,17 @@ next_iface4(struct iface_info *info, int *err, struct iface_conf_list *ifaces) { - } - memcpy(&info->addr, &tmp.ifr_addr, sizeof(tmp.ifr_addr)); +@@ -367,6 +368,17 @@ next_iface(struct iface_info *info, int *err, struct iface_conf_list *ifaces) { + } + info->flags = tmp.lifr_flags; -+ if (ioctl(ifaces->sock, SIOCGIFNETMASK, &tmp) < 0) { -+ if (errno == EADDRNOTAVAIL) { -+ continue; -+ } -+ log_error("Error getting netmask " -+ "for '%s'; %m", name); -+ *err = 1; -+ return 0; ++ if (ioctl(ifaces->sock, SIOCGIFNETMASK, &tmp) < 0) { ++ if (errno == EADDRNOTAVAIL) { ++ continue; + } -+ memcpy(&info->netmask, &tmp.ifr_netmask, sizeof(tmp.ifr_netmask)); -+ - memset(&tmp, 0, sizeof(tmp)); - strncpy(tmp.ifr_name, name, sizeof(tmp.ifr_name) - 1); - if (ioctl(ifaces->sock, SIOCGIFFLAGS, &tmp) < 0) { -@@ -780,6 +793,7 @@ struct iface_conf_list { ++ log_error("Error getting netmask " ++ "for '%s'; %m", name); ++ *err = 1; ++ return 0; ++ } ++ memcpy(&info->netmask, &tmp.ifr_netmask, sizeof(tmp.ifr_netmask)); ++ + ifaces->next++; + *err = 0; + return 1; +@@ -410,6 +422,7 @@ struct iface_conf_list { struct iface_info { char name[IFNAMSIZ]; /* name of the interface, e.g. "bge0" */ struct sockaddr_storage addr; /* address information */ -+ struct sockaddr_storage netmask; /* netmask information */ ++ struct sockaddr_storage netmask; /* netmask information */ isc_uint64_t flags; /* interface flags, e.g. IFF_LOOPBACK */ }; -@@ -840,7 +854,8 @@ end_iface_scan(struct iface_conf_list *ifaces) { +@@ -487,7 +500,8 @@ end_iface_scan(struct iface_conf_list *ifaces) { /* XXX: perhaps create drealloc() rather than do it manually */ void add_ipv4_addr_to_interface(struct interface_info *iface, @@ -67,11 +59,10 @@ index 8e7f632..73eb8a9 100644 /* * We don't expect a lot of addresses per IPv4 interface, so * we use 4, as our "chunk size" for collecting addresses. -@@ -851,6 +866,12 @@ add_ipv4_addr_to_interface(struct interface_info *iface, +@@ -498,6 +512,11 @@ add_ipv4_addr_to_interface(struct interface_info *iface, log_fatal("Out of memory saving IPv4 address " "on interface."); } -+ + iface->netmasks = dmalloc(4 * sizeof(struct in_addr), MDL); + if (iface->netmasks == NULL) { + log_fatal("Out of memory saving IPv4 netmask " @@ -80,14 +71,7 @@ index 8e7f632..73eb8a9 100644 iface->address_count = 0; iface->address_max = 4; } else if (iface->address_count >= iface->address_max) { -@@ -863,14 +884,28 @@ add_ipv4_addr_to_interface(struct interface_info *iface, - log_fatal("Out of memory saving IPv4 address " - "on interface."); - } -- memcpy(tmp, -- iface->addresses, -+ memcpy(tmp, -+ iface->addresses, +@@ -515,9 +534,23 @@ add_ipv4_addr_to_interface(struct interface_info *iface, iface->address_max * sizeof(struct in_addr)); dfree(iface->addresses, MDL); iface->addresses = tmp; @@ -95,7 +79,7 @@ index 8e7f632..73eb8a9 100644 + tmp = dmalloc(new_max * sizeof(struct in_addr), MDL); + if (tmp == NULL) { + log_fatal("Out of memory saving IPv4 netmask " -+ "on interface."); ++ "on interface."); + } + memcpy(tmp, + iface->netmasks, @@ -112,7 +96,7 @@ index 8e7f632..73eb8a9 100644 } #ifdef DHCPv6 -@@ -1005,6 +1040,7 @@ discover_interfaces(int state) { +@@ -656,6 +689,7 @@ discover_interfaces(int state) { if ((info.addr.ss_family == AF_INET) && (local_family == AF_INET)) { struct sockaddr_in *a = (struct sockaddr_in*)&info.addr; @@ -120,7 +104,7 @@ index 8e7f632..73eb8a9 100644 struct iaddr addr; /* We don't want the loopback interface. */ -@@ -1019,7 +1055,7 @@ discover_interfaces(int state) { +@@ -670,7 +704,7 @@ discover_interfaces(int state) { if (a->sin_addr.s_addr != htonl(INADDR_ANY)) tmp->configured = 1; @@ -130,10 +114,10 @@ index 8e7f632..73eb8a9 100644 /* invoke the setup hook */ addr.len = 4; diff --git a/includes/dhcpd.h b/includes/dhcpd.h -index 261714d..89bfe82 100644 +index df3da59..2c7f059 100644 --- a/includes/dhcpd.h +++ b/includes/dhcpd.h -@@ -1347,6 +1347,9 @@ struct interface_info { +@@ -1369,6 +1369,9 @@ struct interface_info { struct in_addr *addresses; /* Addresses associated with this * interface. */ @@ -144,7 +128,7 @@ index 261714d..89bfe82 100644 int address_max; /* Size of addresses buffer. */ struct in6_addr *v6addresses; /* IPv6 addresses associated with diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c -index c9b6d8e..8aac4b3 100644 +index 54f132a..beae977 100644 --- a/relay/dhcrelay.c +++ b/relay/dhcrelay.c @@ -30,6 +30,7 @@ @@ -155,7 +139,7 @@ index c9b6d8e..8aac4b3 100644 #include TIME default_lease_time = 43200; /* 12 hours... */ -@@ -881,20 +882,95 @@ do_relay4(struct interface_info *ip, struct dhcp_packet *packet, +@@ -1001,20 +1002,95 @@ do_relay4(struct interface_info *ip, struct dhcp_packet *packet, /* Otherwise, it's a BOOTREQUEST, so forward it to all the servers. */ for (sp = servers; sp; sp = sp->next) { diff --git a/src/isc-dhcp/patch/0008-CVE-2017-3144.patch b/src/isc-dhcp/patch/0008-CVE-2017-3144.patch deleted file mode 100644 index fe066e177a8c..000000000000 --- a/src/isc-dhcp/patch/0008-CVE-2017-3144.patch +++ /dev/null @@ -1,47 +0,0 @@ -From: Thomas Markwalder -Date: Thu, 7 Dec 2017 11:23:36 -0500 -Subject: [master] Plugs a socket descriptor leak in OMAPI -Origin: https://source.isc.org/cgi-bin/gitweb.cgi?p=dhcp.git;a=commit;h=1a6b62fe17a42b00fa234d06b6dfde3d03451894 -Bug: https://bugs.isc.org/Public/Bug/Display.html?id=46767 -Bug-Debian: https://bugs.debian.org/887413 -Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2017-3144 - - Merges in rt46767. ---- - -diff --git a/omapip/buffer.c b/omapip/buffer.c -index 6e0621b5..a21f0a80 100644 ---- a/omapip/buffer.c -+++ b/omapip/buffer.c -@@ -565,6 +565,15 @@ isc_result_t omapi_connection_writer (omapi_object_t *h) - omapi_buffer_dereference (&buffer, MDL); - } - } -+ -+ /* If we had data left to write when we're told to disconnect, -+ * we need recall disconnect, now that we're done writing. -+ * See rt46767. */ -+ if (c->out_bytes == 0 && c->state == omapi_connection_disconnecting) { -+ omapi_disconnect (h, 1); -+ return ISC_R_SHUTTINGDOWN; -+ } -+ - return ISC_R_SUCCESS; - } - -diff --git a/omapip/message.c b/omapip/message.c -index ee15d821..37abbd25 100644 ---- a/omapip/message.c -+++ b/omapip/message.c -@@ -339,7 +339,7 @@ isc_result_t omapi_message_unregister (omapi_object_t *mo) - } - - #ifdef DEBUG_PROTOCOL --static const char *omapi_message_op_name(int op) { -+const char *omapi_message_op_name(int op) { - switch (op) { - case OMAPI_OP_OPEN: return "OMAPI_OP_OPEN"; - case OMAPI_OP_REFRESH: return "OMAPI_OP_REFRESH"; --- -2.16.2 - diff --git a/src/isc-dhcp/patch/0012-Don-t-skip-down-interfaces-when-discovering-interfac.patch b/src/isc-dhcp/patch/0008-Don-t-skip-down-interfaces-when-discovering-interfac.patch similarity index 100% rename from src/isc-dhcp/patch/0012-Don-t-skip-down-interfaces-when-discovering-interfac.patch rename to src/isc-dhcp/patch/0008-Don-t-skip-down-interfaces-when-discovering-interfac.patch diff --git a/src/isc-dhcp/patch/0008-interface-name-maxlen-crash.patch b/src/isc-dhcp/patch/0008-interface-name-maxlen-crash.patch deleted file mode 100644 index 38d000c1b319..000000000000 --- a/src/isc-dhcp/patch/0008-interface-name-maxlen-crash.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/common/discover.c b/common/discover.c -index 3cd64a7..c85d18c 100644 ---- a/common/discover.c -+++ b/common/discover.c -@@ -547,7 +547,7 @@ next_iface4(struct iface_info *info, int *err, struct iface_conf_list *ifaces) { - log_error("Interface name '%s' too long", name); - return 0; - } -- strncpy(info->name, name, sizeof(info->name) - 1); -+ strncpy(info->name, name, sizeof(info->name)); - - #ifdef ALIAS_NAMED_PERMUTED - /* interface aliases look like "eth0:1" or "wlan1:3" */ diff --git a/src/isc-dhcp/patch/0009-CVE-2018-5733.patch b/src/isc-dhcp/patch/0009-CVE-2018-5733.patch deleted file mode 100644 index 99017fc9839d..000000000000 --- a/src/isc-dhcp/patch/0009-CVE-2018-5733.patch +++ /dev/null @@ -1,131 +0,0 @@ -From: Thomas Markwalder -Date: Fri, 9 Feb 2018 14:46:08 -0500 -Subject: [master] Corrected refcnt loss in option parsing -Origin: https://source.isc.org/cgi-bin/gitweb.cgi?p=dhcp.git;a=commit;h=197b26f25309f947b97a83b8fdfc414b767798f8 -Bug: https://bugs.isc.org/Public/Bug/Display.html?id=47140 -Bug-Debian: https://bugs.debian.org/891785 -Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2018-5733 - - Merges in 47140. ---- - ---- a/common/options.c -+++ b/common/options.c -@@ -177,6 +177,8 @@ int parse_option_buffer (options, buffer - - /* If the length is outrageous, the options are bad. */ - if (offset + len > length) { -+ /* Avoid reference count overflow */ -+ option_dereference(&option, MDL); - reason = "option length exceeds option buffer length"; - bogus: - log_error("parse_option_buffer: malformed option " ---- a/common/tests/Makefile.am -+++ b/common/tests/Makefile.am -@@ -10,7 +10,8 @@ ATF_TESTS = - - if HAVE_ATF - --ATF_TESTS += alloc_unittest dns_unittest misc_unittest ns_name_unittest -+ATF_TESTS += alloc_unittest dns_unittest misc_unittest ns_name_unittest \ -+ option_unittest - - alloc_unittest_SOURCES = test_alloc.c $(top_srcdir)/tests/t_api_dhcp.c - alloc_unittest_LDADD = $(ATF_LDFLAGS) -@@ -36,6 +37,14 @@ ns_name_unittest_LDADD += ../libdhcp.a - ../../omapip/libomapi.a $(BINDLIBDIR)/libirs.a \ - $(BINDLIBDIR)/libdns.a $(BINDLIBDIR)/libisccfg.a $(BINDLIBDIR)/libisc.a - -+option_unittest_SOURCES = option_unittest.c $(top_srcdir)/tests/t_api_dhcp.c -+option_unittest_LDADD = $(ATF_LDFLAGS) -+option_unittest_LDADD += ../libdhcp.@A@ ../../omapip/libomapi.@A@ \ -+ @BINDLIBIRSDIR@/libirs.@A@ \ -+ @BINDLIBDNSDIR@/libdns.@A@ \ -+ @BINDLIBISCCFGDIR@/libisccfg.@A@ \ -+ @BINDLIBISCDIR@/libisc.@A@ -+ - check: $(ATF_TESTS) - @if test $(top_srcdir) != ${top_builddir}; then \ - cp $(top_srcdir)/common/tests/Atffile Atffile; \ ---- /dev/null -+++ b/common/tests/option_unittest.c -@@ -0,0 +1,79 @@ -+/* -+ * Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC") -+ * -+ * This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH -+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, -+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -+ * PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#include -+#include -+#include "dhcpd.h" -+ -+ATF_TC(option_refcnt); -+ -+ATF_TC_HEAD(option_refcnt, tc) -+{ -+ atf_tc_set_md_var(tc, "descr", -+ "Verify option reference count does not overflow."); -+} -+ -+/* This test does a simple check to see if option reference count is -+ * decremented even an error path exiting parse_option_buffer() -+ */ -+ATF_TC_BODY(option_refcnt, tc) -+{ -+ struct option_state *options; -+ struct option *option; -+ unsigned code; -+ int refcnt; -+ unsigned char buffer[3] = { 15, 255, 0 }; -+ -+ initialize_common_option_spaces(); -+ -+ options = NULL; -+ if (!option_state_allocate(&options, MDL)) { -+ atf_tc_fail("can't allocate option state"); -+ } -+ -+ option = NULL; -+ code = 15; /* domain-name */ -+ if (!option_code_hash_lookup(&option, dhcp_universe.code_hash, -+ &code, 0, MDL)) { -+ atf_tc_fail("can't find option 15"); -+ } -+ if (option == NULL) { -+ atf_tc_fail("option is NULL"); -+ } -+ refcnt = option->refcnt; -+ -+ buffer[0] = 15; -+ buffer[1] = 255; /* invalid */ -+ buffer[2] = 0; -+ -+ if (parse_option_buffer(options, buffer, 3, &dhcp_universe)) { -+ atf_tc_fail("parse_option_buffer is expected to fail"); -+ } -+ -+ if (refcnt != option->refcnt) { -+ atf_tc_fail("refcnt changed from %d to %d", refcnt, option->refcnt); -+ } -+} -+ -+/* This macro defines main() method that will call specified -+ test cases. tp and simple_test_case names can be whatever you want -+ as long as it is a valid variable identifier. */ -+ATF_TP_ADD_TCS(tp) -+{ -+ ATF_TP_ADD_TC(tp, option_refcnt); -+ -+ return (atf_no_error()); -+} diff --git a/src/isc-dhcp/patch/0009-Support-for-dual-tor-scenario.patch b/src/isc-dhcp/patch/0009-Support-for-dual-tor-scenario.patch new file mode 100644 index 000000000000..e918cc619106 --- /dev/null +++ b/src/isc-dhcp/patch/0009-Support-for-dual-tor-scenario.patch @@ -0,0 +1,269 @@ +From 768df61b57a0a7bda23aa8bc7e08c5b2a96a8087 Mon Sep 17 00:00:00 2001 +From: Tianrong Zhang +Date: Tue, 1 Dec 2020 16:33:34 -0800 +Subject: [PATCH] support for dual tor scenario + +--- + relay/dhcrelay.c | 117 +++++++++++++++++++++++++++++++++++++++-------- + 1 file changed, 98 insertions(+), 19 deletions(-) + +diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c +index e158efe..055d97f 100644 +--- a/relay/dhcrelay.c ++++ b/relay/dhcrelay.c +@@ -56,6 +56,8 @@ int bogus_agent_drops = 0; /* Packets dropped because agent option + specified. */ + int bogus_giaddr_drops = 0; /* Packets sent to us to relay back to a + client, but with a bogus giaddr. */ ++int bogus_yiaddr_drops = 0; /* Packets sent to us to relay back to a ++ client, but with a bogus yiaddr. */ + int client_packets_relayed = 0; /* Packets relayed from client to server. */ + int server_packet_errors = 0; /* Errors sending packets to servers. */ + int server_packets_relayed = 0; /* Packets relayed from server to client. */ +@@ -83,6 +85,13 @@ int max_hop_count = 10; /* Maximum hop count */ + int no_daemon = 0; + int dfd[2] = { -1, -1 }; + ++int enable_support_for_dual_tor = 0; ++ ++struct downstream_intf_list { ++ struct downstream_intf_list *next; ++ struct interface_info *interface; ++} *downstream_intfs = NULL; ++ + #ifdef DHCPv6 + /* Force use of DHCPv6 interface-id option. */ + isc_boolean_t use_if_id = ISC_FALSE; +@@ -156,6 +165,8 @@ static int load_interface_alias_map(const char *port_alias_map_file_path); + static int get_interface_alias_by_name(const char *if_name, char *if_alias_out); + static void free_interface_alias_map(void); + ++static void free_downstream_intfs(void); ++ + static const char copyright[] = + "Copyright 2004-2018 Internet Systems Consortium."; + static const char arr[] = "All rights reserved."; +@@ -189,6 +200,7 @@ char *progname; + " [-iu interface0 [ ... -iu interfaceN]\n" \ + " [-id interface0 [ ... -id interfaceN]\n" \ + " [-U interface]\n" \ ++" [-dt]\n"\ + " server0 [ ... serverN]\n\n" \ + " %s -6 [-d] [-q] [-I] [-c ]\n" \ + " [-p | -rp ]\n" \ +@@ -210,6 +222,7 @@ char *progname; + " [-iu interface0 [ ... -iu interfaceN]\n" \ + " [-id interface0 [ ... -id interfaceN]\n" \ + " [-U interface]\n" \ ++" [-dt]\n"\ + " server0 [ ... serverN]\n\n" \ + " %s -6 [-d] [-q] [-I] [-c ] [-p ]\n" \ + " [-pf ] [--no-pid]\n" \ +@@ -231,6 +244,7 @@ char *progname; + " [-iu interface0 [ ... -iu interfaceN]\n" \ + " [-id interface0 [ ... -id interfaceN]\n" \ + " [-U interface]\n" \ ++" [-dt]\n"\ + " server0 [ ... serverN]\n\n" DHCRELAY_OPTION82_USAGE \ + " %s {--version|--help|-h}" + #else +@@ -242,6 +256,7 @@ char *progname; + " [-iu interface0 [ ... -iu interfaceN]\n" \ + " [-id interface0 [ ... -id interfaceN]\n" \ + " [-U interface]\n" \ ++" [-dt]\n"\ + " server0 [ ... serverN]\n\n" DHCRELAY_OPTION82_USAGE \ + " %s {--version|--help|-h}" + #endif +@@ -639,7 +654,16 @@ main(int argc, char **argv) { + usage(use_noarg, argv[i-1]); + if (load_interface_alias_map(argv[i]) != 0) + log_fatal("Failed to load interface name-alias map."); +- } else if (argv[i][0] == '-') { ++ } else if (!strcmp(argv[i], "-dt")) { ++#ifdef DHCPv6 ++ if (local_family_set && (local_family == AF_INET6)) { ++ usage(use_v4command, argv[i]); ++ } ++ local_family_set = 1; ++ local_family = AF_INET; ++#endif ++ enable_support_for_dual_tor = 1; ++ } else if (argv[i][0] == '-') { + usage("Unknown command: %s", argv[i]); + } else { + struct hostent *he; +@@ -747,7 +771,6 @@ main(int argc, char **argv) { + log_fatal("No servers specified."); + } + +- + /* Set up the server sockaddrs. */ + for (sp = servers; sp; sp = sp->next) { + sp->to.sin_port = local_port; +@@ -862,6 +885,8 @@ main(int argc, char **argv) { + + /* In fact dispatch() never returns. */ + free_interface_alias_map(); ++ free_downstream_intfs(); ++ + return (0); + } + +@@ -885,25 +910,50 @@ do_relay4(struct interface_info *ip, struct dhcp_packet *packet, + return; + } + +- /* Find the interface that corresponds to the giaddr +- in the packet. */ +- if (packet->giaddr.s_addr) { +- for (out = interfaces; out; out = out->next) { +- int i; ++ if (enable_support_for_dual_tor) { ++ if (packet->yiaddr.s_addr) { ++ out = NULL; ++ ++ for (struct downstream_intf_list *cdi = downstream_intfs; cdi; cdi = cdi->next) { ++ int i = 0; ++ out = cdi->interface; ++ ++ for (i = 0 ; i < out->address_count ; i++ ) { ++ if ((out->addresses[i].s_addr & out->netmasks[i].s_addr) == (packet->yiaddr.s_addr & out->netmasks[i].s_addr)) { ++ i = -1; ++ break; ++ } ++ } + +- for (i = 0 ; i < out->address_count ; i++ ) { +- if (out->addresses[i].s_addr == +- packet->giaddr.s_addr) { +- i = -1; ++ if (i == -1) { + break; ++ } else { ++ out = NULL; + } + } +- +- if (i == -1) +- break; ++ } else { ++ out = NULL; + } + } else { +- out = NULL; ++ /* Find the interface that corresponds to the giaddr in the packet. */ ++ if (packet->giaddr.s_addr) { ++ for (out = interfaces; out; out = out->next) { ++ int i; ++ ++ for (i = 0 ; i < out->address_count ; i++ ) { ++ if (out->addresses[i].s_addr == ++ packet->giaddr.s_addr) { ++ i = -1; ++ break; ++ } ++ } ++ ++ if (i == -1) ++ break; ++ } ++ } else { ++ out = NULL; ++ } + } + + /* If it's a bootreply, forward it to the client. */ +@@ -913,6 +963,10 @@ do_relay4(struct interface_info *ip, struct dhcp_packet *packet, + return; + } + ++ /* This bootreply does not belong to the current vlan. */ ++ if (enable_support_for_dual_tor && !out) ++ return; ++ + if (!(packet->flags & htons(BOOTP_BROADCAST)) && + can_unicast_without_arp(out)) { + to.sin_addr = packet->yiaddr; +@@ -945,9 +999,13 @@ do_relay4(struct interface_info *ip, struct dhcp_packet *packet, + return; + + if (!out) { +- log_error("Packet to bogus giaddr %s.\n", +- inet_ntoa(packet->giaddr)); +- ++bogus_giaddr_drops; ++ if (!enable_support_for_dual_tor) { ++ log_error("Packet to bogus giaddr %s.\n", inet_ntoa(packet->giaddr)); ++ ++bogus_giaddr_drops; ++ } else { ++ log_error("Packet to bogus yiaddr %s.\n", inet_ntoa(packet->yiaddr)); ++ ++bogus_yiaddr_drops; ++ } + return; + } + +@@ -989,6 +1047,7 @@ do_relay4(struct interface_info *ip, struct dhcp_packet *packet, + that set giaddr, so we won't see it. */ + if (!packet->giaddr.s_addr) + packet->giaddr = ip->addresses[0]; ++ + if (packet->hops < max_hop_count) + packet->hops = packet->hops + 1; + else +@@ -1264,7 +1323,6 @@ find_interface_by_agent_option(struct dhcp_packet *packet, + + /* Scan the interface list looking for an interface whose + name matches the one specified in circuit_id. */ +- + for (ip = interfaces; ip; ip = ip->next) { + if (ip->circuit_id && + ip->circuit_id_len == circuit_id_len && +@@ -1668,6 +1726,7 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, + *sp++ = 4u; + memcpy(sp, &giaddr.s_addr, 4); + sp += 4; ++ + packet->giaddr = uplink->addresses[0]; + log_debug ("Adding link selection suboption" + " with addr: %s", inet_ntoa(giaddr)); +@@ -2398,6 +2457,7 @@ void request_v4_interface(const char* name, int flags) { + struct interface_info *tmp = NULL; + int len = strlen(name); + isc_result_t status; ++ struct downstream_intf_list *ci = NULL; + + if (len >= sizeof(tmp->name)) { + log_fatal("%s: interface name too long (is %d)", name, len); +@@ -2413,6 +2473,15 @@ void request_v4_interface(const char* name, int flags) { + (flags & INTERFACE_UPSTREAM ? 'Y' : 'N'), + (flags & INTERFACE_DOWNSTREAM ? 'Y' : 'N')); + ++ if (flags & INTERFACE_DOWNSTREAM) { ++ ci = ((struct downstream_intf_list *)dmalloc(sizeof *ci, MDL)); ++ if (!ci) ++ log_fatal("no memory for downstream interface pointer.\n"); ++ ci->next = downstream_intfs; ++ downstream_intfs = ci; ++ ci->interface = tmp; ++ } ++ + strncpy(tmp->name, name, len); + interface_snorf(tmp, (INTERFACE_REQUESTED | flags)); + interface_dereference(&tmp, MDL); +@@ -2487,3 +2556,13 @@ free_interface_alias_map(void) { + free(g_interface_name_alias_map); + g_interface_name_alias_map_size = 0; + } ++ ++static void ++free_downstream_intfs(void) { ++ struct downstream_intf_list *cdi; ++ while (downstream_intfs) { ++ cdi = downstream_intfs; ++ downstream_intfs = downstream_intfs->next; ++ free(cdi); ++ } ++} +-- +2.17.1 + diff --git a/src/isc-dhcp/patch/0010-Bugfix-correctly-set-interface-netmask.patch b/src/isc-dhcp/patch/0010-Bugfix-correctly-set-interface-netmask.patch new file mode 100644 index 000000000000..409e2e32f30e --- /dev/null +++ b/src/isc-dhcp/patch/0010-Bugfix-correctly-set-interface-netmask.patch @@ -0,0 +1,24 @@ +From b19547b0574132e4b2efbda012f3169e4db7923c Mon Sep 17 00:00:00 2001 +From: Tianrong Zhang +Date: Mon, 30 Nov 2020 18:42:09 -0800 +Subject: [PATCH] Bugfix: correctly set interface netmask + +--- + common/discover.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/common/discover.c b/common/discover.c +index c6b2431..06e0b12 100644 +--- a/common/discover.c ++++ b/common/discover.c +@@ -479,6 +479,7 @@ next_iface(struct iface_info *info, int *err, struct iface_conf_list *ifaces) { + sa_len = ifaces->next->ifa_addr->sa_len; + #endif + memcpy(&info->addr, ifaces->next->ifa_addr, sa_len); ++ memcpy(&info->netmask, ifaces->next->ifa_netmask, sa_len); + } + info->flags = ifaces->next->ifa_flags; + ifaces->next = ifaces->next->ifa_next; +-- +2.17.1 + diff --git a/src/isc-dhcp/patch/0010-CVE-2018-5732.patch b/src/isc-dhcp/patch/0010-CVE-2018-5732.patch deleted file mode 100644 index d6c10e2e6532..000000000000 --- a/src/isc-dhcp/patch/0010-CVE-2018-5732.patch +++ /dev/null @@ -1,144 +0,0 @@ -From: Thomas Markwalder -Date: Sat, 10 Feb 2018 12:15:27 -0500 -Subject: [master] Correct buffer overrun in pretty_print_option -Origin: https://source.isc.org/cgi-bin/gitweb.cgi?p=dhcp.git;a=commit;h=c5931725b48b121d232df4ba9e45bc41e0ba114d -Bug: https://bugs.isc.org/Public/Bug/Display.html?id=47139 -Bug-Debian: https://bugs.debian.org/891786 -Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2018-5732 - - Merges in rt47139. ---- - -diff --git a/common/options.c b/common/options.c -index 6f23bc15..fc0e0889 100644 ---- a/common/options.c -+++ b/common/options.c -@@ -1776,7 +1776,8 @@ format_min_length(format, oc) - - - /* Format the specified option so that a human can easily read it. */ -- -+/* Maximum pretty printed size */ -+#define MAX_OUTPUT_SIZE 32*1024 - const char *pretty_print_option (option, data, len, emit_commas, emit_quotes) - struct option *option; - const unsigned char *data; -@@ -1784,8 +1785,9 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes) - int emit_commas; - int emit_quotes; - { -- static char optbuf [32768]; /* XXX */ -- static char *endbuf = &optbuf[sizeof(optbuf)]; -+ /* We add 128 byte pad so we don't have to add checks everywhere. */ -+ static char optbuf [MAX_OUTPUT_SIZE + 128]; /* XXX */ -+ static char *endbuf = optbuf + MAX_OUTPUT_SIZE; - int hunksize = 0; - int opthunk = 0; - int hunkinc = 0; -@@ -2211,7 +2213,14 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes) - log_error ("Unexpected format code %c", - fmtbuf [j]); - } -+ - op += strlen (op); -+ if (op >= endbuf) { -+ log_error ("Option data exceeds" -+ " maximum size %d", MAX_OUTPUT_SIZE); -+ return (""); -+ } -+ - if (dp == data + len) - break; - if (j + 1 < numelem && comma != ':') -diff --git a/common/tests/option_unittest.c b/common/tests/option_unittest.c -index 36236b84..cd52cfb4 100644 ---- a/common/tests/option_unittest.c -+++ b/common/tests/option_unittest.c -@@ -43,7 +43,7 @@ ATF_TC_BODY(option_refcnt, tc) - if (!option_state_allocate(&options, MDL)) { - atf_tc_fail("can't allocate option state"); - } -- -+ - option = NULL; - code = 15; /* domain-name */ - if (!option_code_hash_lookup(&option, dhcp_universe.code_hash, -@@ -68,12 +68,75 @@ ATF_TC_BODY(option_refcnt, tc) - } - } - -+ATF_TC(pretty_print_option); -+ -+ATF_TC_HEAD(pretty_print_option, tc) -+{ -+ atf_tc_set_md_var(tc, "descr", -+ "Verify pretty_print_option does not overrun its buffer."); -+} -+ -+ -+/* -+ * This test verifies that pretty_print_option() will not overrun its -+ * internal, static buffer when given large 'x/X' format options. -+ * -+ */ -+ATF_TC_BODY(pretty_print_option, tc) -+{ -+ struct option *option; -+ unsigned code; -+ unsigned char bad_data[32*1024]; -+ unsigned char good_data[] = { 1,2,3,4,5,6 }; -+ int emit_commas = 1; -+ int emit_quotes = 1; -+ const char *output_buf; -+ -+ /* Initialize whole thing to non-printable chars */ -+ memset(bad_data, 0x1f, sizeof(bad_data)); -+ -+ initialize_common_option_spaces(); -+ -+ /* We'll use dhcp_client_identitifer because it happens to be format X */ -+ code = 61; -+ option = NULL; -+ if (!option_code_hash_lookup(&option, dhcp_universe.code_hash, -+ &code, 0, MDL)) { -+ atf_tc_fail("can't find option %d", code); -+ } -+ -+ if (option == NULL) { -+ atf_tc_fail("option is NULL"); -+ } -+ -+ /* First we will try a good value we know should fit. */ -+ output_buf = pretty_print_option (option, good_data, sizeof(good_data), -+ emit_commas, emit_quotes); -+ -+ /* Make sure we get what we expect */ -+ if (!output_buf || strcmp(output_buf, "1:2:3:4:5:6")) { -+ atf_tc_fail("pretty_print_option did not return \"\""); -+ } -+ -+ -+ /* Now we'll try a data value that's too large */ -+ output_buf = pretty_print_option (option, bad_data, sizeof(bad_data), -+ emit_commas, emit_quotes); -+ -+ /* Make sure we safely get an error */ -+ if (!output_buf || strcmp(output_buf, "")) { -+ atf_tc_fail("pretty_print_option did not return \"\""); -+ } -+} -+ -+ - /* This macro defines main() method that will call specified - test cases. tp and simple_test_case names can be whatever you want - as long as it is a valid variable identifier. */ - ATF_TP_ADD_TCS(tp) - { - ATF_TP_ADD_TC(tp, option_refcnt); -+ ATF_TP_ADD_TC(tp, pretty_print_option); - - return (atf_no_error()); - } --- -2.16.2 - diff --git a/src/isc-dhcp/patch/0011-dhcp-relay-Prevent-Buffer-Overrun.patch b/src/isc-dhcp/patch/0011-dhcp-relay-Prevent-Buffer-Overrun.patch new file mode 100644 index 000000000000..fda59d9e69aa --- /dev/null +++ b/src/isc-dhcp/patch/0011-dhcp-relay-Prevent-Buffer-Overrun.patch @@ -0,0 +1,30 @@ +From 19e400c1040e3621db6a0d8dd70d18c431d1a848 Mon Sep 17 00:00:00 2001 +From: Tamer Ahmed +Date: Sat, 28 Nov 2020 16:28:37 -0800 +Subject: [PATCH] [dhcp-relay] Prevent Buffer Overrun + +The add/strip relay agent options do not take into account the buffer +length and so it is possible to overrun the buffer. The issue will +result in contents from previous packet being added to the current one. + +signed-off-by: Tamer Ahmed +--- + relay/dhcrelay.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c +index 055d97f..1cd99b9 100644 +--- a/relay/dhcrelay.c ++++ b/relay/dhcrelay.c +@@ -1527,7 +1527,7 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, + /* Commence processing after the cookie. */ + sp = op = &packet->options[4]; + +- while (op < max) { ++ while ((op < max) && (op < (((u_int8_t *)packet) + length))) { + switch(*op) { + /* Skip padding... */ + case DHO_PAD: +-- +2.17.1 + diff --git a/src/isc-dhcp/patch/series b/src/isc-dhcp/patch/series index ec68967e28b9..a34b5bf4b0df 100644 --- a/src/isc-dhcp/patch/series +++ b/src/isc-dhcp/patch/series @@ -1,4 +1,4 @@ -# This series applies on GIT commit d613b77d0473054fb0071b00d01eaa1623e50a07 +# This series applies on GIT commit d0d58776805d720029619ea06df5c57706eecd5a 0001-Bugfix-Don-t-print-log-messages-to-stderr-in-release.patch 0002-Customizable-Option-82-circuit-ID-and-remote-ID-fiel.patch 0003-Support-for-obtaining-name-of-physical-interface-tha.patch @@ -6,8 +6,7 @@ 0005-Add-enable-use-sockets-to-configure-flags-in-debian-.patch 0006-Bugfix-Ensure-HAVE_SO_BINDTODEVICE-has-a-chance-to-b.patch 0007-If-destination-of-BOOTREQUEST-is-directed-broadcast-.patch -0008-CVE-2017-3144.patch -0009-CVE-2018-5733.patch -0010-CVE-2018-5732.patch -0008-interface-name-maxlen-crash.patch -0012-Don-t-skip-down-interfaces-when-discovering-interfac.patch +0008-Don-t-skip-down-interfaces-when-discovering-interfac.patch +0009-Support-for-dual-tor-scenario.patch +0010-Bugfix-correctly-set-interface-netmask.patch +0011-dhcp-relay-Prevent-Buffer-Overrun.patch diff --git a/src/ixgbe/.gitignore b/src/ixgbe/.gitignore new file mode 100644 index 000000000000..a0991ff4402b --- /dev/null +++ b/src/ixgbe/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!Makefile diff --git a/src/kdump-tools/.gitignore b/src/kdump-tools/.gitignore new file mode 100644 index 000000000000..d19db76ab9a9 --- /dev/null +++ b/src/kdump-tools/.gitignore @@ -0,0 +1,4 @@ +* +!.gitignore +!Makefile +!patch/ diff --git a/src/kdump-tools/Makefile b/src/kdump-tools/Makefile index 18c2a369b5d7..dadf08503af1 100644 --- a/src/kdump-tools/Makefile +++ b/src/kdump-tools/Makefile @@ -25,7 +25,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : stg import -s ../patch/series # Build source and Debian packages - fakeroot debian/rules binary-indep + dpkg-buildpackage -rfakeroot -b -us -uc -Tbinary-indep -j$(SONIC_CONFIG_MAKE_JOBS) --admindir $(SONIC_DPKG_ADMINDIR) popd # Move the newly-built .deb packages to the destination directory diff --git a/src/libnl3/.gitignore b/src/libnl3/.gitignore new file mode 100644 index 000000000000..906fc0b87997 --- /dev/null +++ b/src/libnl3/.gitignore @@ -0,0 +1,5 @@ +* +!.gitignore +!debian/ +debian/libnl-*/ +!Makefile diff --git a/src/libnl3/Makefile b/src/libnl3/Makefile index a0e9891c9efc..c45ac85b7288 100644 --- a/src/libnl3/Makefile +++ b/src/libnl3/Makefile @@ -21,7 +21,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : git checkout tags/libnl$(subst .,_,$(LIBNL3_VERSION_BASE)) ln -s ../debian debian - dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) + dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) --admindir $(SONIC_DPKG_ADMINDIR) popd mv $(DERIVED_TARGETS) $* $(DEST)/ diff --git a/src/libteam/.gitignore b/src/libteam/.gitignore new file mode 100644 index 000000000000..a0991ff4402b --- /dev/null +++ b/src/libteam/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!Makefile diff --git a/src/libteam/Makefile b/src/libteam/Makefile index 9fd5f582ed4d..47f9d1dd21bf 100644 --- a/src/libteam/Makefile +++ b/src/libteam/Makefile @@ -31,7 +31,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : mv tmp/debian libteam/ rm -rf tmp pushd ./libteam - dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) + dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) --admindir $(SONIC_DPKG_ADMINDIR) popd mv $(DERIVED_TARGETS) $* $(DEST)/ diff --git a/src/libteam/patch/0011-Remove-extensive-debug-output.patch b/src/libteam/patch/0011-Remove-extensive-debug-output.patch new file mode 100644 index 000000000000..429ac56697d5 --- /dev/null +++ b/src/libteam/patch/0011-Remove-extensive-debug-output.patch @@ -0,0 +1,25 @@ +From 19928173ce022f499c59b719179e7ad9a4bafb7f Mon Sep 17 00:00:00 2001 +From: Pavel Shirshov +Date: Mon, 9 Nov 2020 13:21:55 -0800 +Subject: [PATCH] Remove extensive debug output + +--- + libteamdctl/cli_usock.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libteamdctl/cli_usock.c b/libteamdctl/cli_usock.c +index 0dc97ae..d3fbdba 100644 +--- a/libteamdctl/cli_usock.c ++++ b/libteamdctl/cli_usock.c +@@ -163,7 +163,7 @@ static int cli_usock_method_call(struct teamdctl *tdc, const char *method_name, + char *replystr; + int err; + +- dbg(tdc, "usock: Calling method \"%s\"", method_name); ++ /* dbg(tdc, "usock: Calling method \"%s\"", method_name); */ + err= myasprintf(&msg, "%s\n%s\n", TEAMD_USOCK_REQUEST_PREFIX, + method_name); + if (err) +-- +2.29.2.windows.2 + diff --git a/src/libteam/patch/series b/src/libteam/patch/series index 7be69525d9d0..5350d37e4653 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-Remove-extensive-debug-output.patch diff --git a/src/libyang/.gitignore b/src/libyang/.gitignore new file mode 100644 index 000000000000..a0991ff4402b --- /dev/null +++ b/src/libyang/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!Makefile diff --git a/src/libyang/patch/large_file_support_arm32.patch b/src/libyang/patch/large_file_support_arm32.patch new file mode 100644 index 000000000000..e3fb2b739055 --- /dev/null +++ b/src/libyang/patch/large_file_support_arm32.patch @@ -0,0 +1,11 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 8635ba1..39f0741 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -436,3 +436,6 @@ endif(ENABLE_BUILD_FUZZ_TARGETS) + if(GEN_LANGUAGE_BINDINGS AND GEN_CPP_BINDINGS) + add_subdirectory(swig) + endif() ++ ++#Enable large file support for 32-bit arch ++add_definitions(-D_FILE_OFFSET_BITS=64) diff --git a/src/libyang/patch/libyang_mgmt_framework.patch b/src/libyang/patch/libyang_mgmt_framework.patch new file mode 100644 index 000000000000..03b7ea3476b7 --- /dev/null +++ b/src/libyang/patch/libyang_mgmt_framework.patch @@ -0,0 +1,13 @@ +diff --git a/src/tree_data.c b/src/tree_data.c +index 04653a46..65dca211 100644 +--- a/src/tree_data.c ++++ b/src/tree_data.c +@@ -842,7 +842,7 @@ error: + return ret; + } + +-int ++API int + lyd_check_mandatory_tree(struct lyd_node *root, struct ly_ctx *ctx, const struct lys_module **modules, int mod_count, + int options) + { diff --git a/src/libyang/patch/series b/src/libyang/patch/series index 773245e4eed5..28352b9628e5 100644 --- a/src/libyang/patch/series +++ b/src/libyang/patch/series @@ -1,2 +1,4 @@ libyang.patch +libyang_mgmt_framework.patch swig.patch +large_file_support_arm32.patch diff --git a/src/libyang1/.gitignore b/src/libyang1/.gitignore new file mode 100644 index 000000000000..a0991ff4402b --- /dev/null +++ b/src/libyang1/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!Makefile diff --git a/src/libyang1/Makefile b/src/libyang1/Makefile new file mode 100644 index 000000000000..834893eb0bbe --- /dev/null +++ b/src/libyang1/Makefile @@ -0,0 +1,40 @@ +.ONESHELL: +SHELL = /bin/bash +.SHELLFLAGS += -e + +LIBYANG_URL = https://sonicstorage.blob.core.windows.net/debian/pool/main/liby/libyang + +DSC_FILE = libyang_$(LIBYANG1_FULLVERSION).dsc +ORIG_FILE = libyang_$(LIBYANG1_VERSION).orig.tar.gz +DEBIAN_FILE = libyang_$(LIBYANG1_FULLVERSION).debian.tar.xz + +DSC_FILE_URL = $(LIBYANG_URL)/$(DSC_FILE) +ORIG_FILE_URL = $(LIBYANG_URL)/$(ORIG_FILE) +DEBIAN_FILE_URL = $(LIBYANG_URL)/$(DEBIAN_FILE) + +MAIN_TARGET = $(LIBYANG1) +DERIVED_TARGETS = $(LIBYANG1_DEV) $(LIBYANG1_DBG) $(LIBYANG1_CPP) $(LIBYANG1_CPP_DEV) $(LIBYANG1_CPP_DBG) $(YANG_TOOLS) $(LIBYANG1_TOOLS) $(LIBYANG1_TOOLS_DBG) + +$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : + # Obtaining the libyang + rm -fr ./libyang-$(LIBYANG1_VERSION) + + # download debian libyang + wget -NO "$(DSC_FILE)" $(DSC_FILE_URL) + wget -NO "$(ORIG_FILE)" $(ORIG_FILE_URL) + wget -NO "$(DEBIAN_FILE)" $(DEBIAN_FILE_URL) + dpkg-source -x libyang_$(LIBYANG1_FULLVERSION).dsc + + pushd libyang-$(LIBYANG1_VERSION) + sed -i 's/set(LIBYANG_MAJOR_SOVERSION 1)/set(LIBYANG_MAJOR_SOVERSION 2)/' CMakeLists.txt + sed -i 's/libyang1/libyang2/' debian/libyang1.install + # Enable large file support for 32-bit arch + echo 'add_definitions(-D_FILE_OFFSET_BITS=64)' >> CMakeLists.txt + + dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) --admindir $(SONIC_DPKG_ADMINDIR) + 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/lldpd/.gitignore b/src/lldpd/.gitignore new file mode 100644 index 000000000000..d19db76ab9a9 --- /dev/null +++ b/src/lldpd/.gitignore @@ -0,0 +1,4 @@ +* +!.gitignore +!Makefile +!patch/ diff --git a/src/lldpd/Makefile b/src/lldpd/Makefile index 285d7fec9911..a336f1e989ae 100644 --- a/src/lldpd/Makefile +++ b/src/lldpd/Makefile @@ -5,7 +5,7 @@ SHELL = /bin/bash MAIN_TARGET = $(LLDPD) DERIVED_TARGETS = $(LIBLLDPCTL) $(LLDPD_DBG) -LLDP_URL = http://ftp.debian.org/debian/pool/main/l/lldpd +LLDP_URL = https://sonicstorage.blob.core.windows.net/debian/pool/main/l/lldpd DSC_FILE = lldpd_$(LLDPD_VERSION_FULL).dsc ORIG_FILE = lldpd_$(LLDPD_VERSION).orig.tar.gz @@ -35,7 +35,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : stg import -s ../patch/series # Build source and Debian packages - env "with_netlink_receive_bufsize=1024*1024" dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) + env "with_netlink_receive_bufsize=1024*1024" dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) --admindir $(SONIC_DPKG_ADMINDIR) popd # Move the newly-built .deb packages to the destination directory diff --git a/src/lldpd/patch/0010-Ported-fix-for-length-exceeded-from-lldp-community.patch b/src/lldpd/patch/0010-Ported-fix-for-length-exceeded-from-lldp-community.patch new file mode 100644 index 000000000000..072790641206 --- /dev/null +++ b/src/lldpd/patch/0010-Ported-fix-for-length-exceeded-from-lldp-community.patch @@ -0,0 +1,35 @@ +From fdb789c348fdcde6d5ef8b837d7f33718bc0862b Mon Sep 17 00:00:00 2001 +From: sudhanshukumar22 +Date: Mon, 23 Nov 2020 20:47:28 -0800 +Subject: [PATCH] Ported fix for https://github.com/lldpd/lldpd/issues/408 from + community + +--- + src/lib/atom.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/lib/atom.c b/src/lib/atom.c +index f81d3bb..75c1275 100644 +--- a/src/lib/atom.c ++++ b/src/lib/atom.c +@@ -327,7 +327,7 @@ _lldpctl_do_something(lldpctl_conn_t *conn, + conn->state_data[0] = 0; + } + if (conn->state == state_send && +- (state_data == NULL || !strncmp(conn->state_data, state_data, sizeof(conn->state_data)))) { ++ (state_data == NULL || !strncmp(conn->state_data, state_data, sizeof(conn->state_data) - 1))) { + /* We need to send the currently built message */ + rc = lldpctl_send(conn); + if (rc < 0) +@@ -335,7 +335,7 @@ _lldpctl_do_something(lldpctl_conn_t *conn, + conn->state = state_recv; + } + if (conn->state == state_recv && +- (state_data == NULL || !strncmp(conn->state_data, state_data, sizeof(conn->state_data)))) { ++ (state_data == NULL || !strncmp(conn->state_data, state_data, sizeof(conn->state_data) - 1))) { + /* We need to receive the answer */ + while ((rc = ctl_msg_recv_unserialized(&conn->input_buffer, + &conn->input_buffer_len, +-- +2.12.2 + diff --git a/src/lldpd/patch/0011-fix-med-location-len.patch b/src/lldpd/patch/0011-fix-med-location-len.patch new file mode 100644 index 000000000000..2290a94442c1 --- /dev/null +++ b/src/lldpd/patch/0011-fix-med-location-len.patch @@ -0,0 +1,47 @@ +From e9bf329eee94d6d49a17da35aea189179aeed3c6 Mon Sep 17 00:00:00 2001 +From: sudhanshukumar22 +Date: Thu, 24 Dec 2020 09:27:49 -0800 +Subject: [PATCH] From 5c3479463a919193213213e2d8634c754c09aa51 Mon Sep 17 + 00:00:00 2001 From: Vincent Bernat Date: Sun, 6 Dec 2020 + 14:21:04 +0100 Subject: [PATCH] lib: fix LLDP-MED location parsing in + liblldpctl + +Some bounds were not checked correctly when parsing LLDP-MED civic +location fields. This triggers out-of-bound reads (no write) in +lldpcli, ultimately leading to a crash. + +Fix #420 +Signed-off-by: sudhanshukumar22 +--- + src/lib/atoms/med.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/src/lib/atoms/med.c b/src/lib/atoms/med.c +index e1b20fd..595dba4 100644 +--- a/src/lib/atoms/med.c ++++ b/src/lib/atoms/med.c +@@ -540,6 +540,7 @@ _lldpctl_atom_get_str_med_location(lldpctl_atom_t *atom, lldpctl_key_t key) + return NULL; + case lldpctl_k_med_location_country: + if (m->location->format != LLDP_MED_LOCFORMAT_CIVIC) break; ++ if (m->location->data_len < 4) return NULL; + value = _lldpctl_alloc_in_atom(atom, 3); + if (!value) return NULL; + memcpy(value, m->location->data + 2, 2); +@@ -732,8 +733,11 @@ _lldpctl_atom_iter_med_caelements_list(lldpctl_atom_t *atom) + { + struct _lldpctl_atom_med_caelements_list_t *plist = + (struct _lldpctl_atom_med_caelements_list_t *)atom; +- struct ca_iter *iter = _lldpctl_alloc_in_atom(atom, sizeof(struct ca_iter)); +- if (!iter) return NULL; ++ struct ca_iter *iter; ++ if (plist->parent->location->data_len < 4 || ++ *(uint8_t*)plist->parent->location->data < 3 || ++ !(iter = _lldpctl_alloc_in_atom(atom, sizeof(struct ca_iter)))) ++ return NULL; + iter->data = (uint8_t*)plist->parent->location->data + 4; + iter->data_len = *(uint8_t*)plist->parent->location->data - 3; + return (lldpctl_atom_iter_t*)iter; +-- +2.12.2 + diff --git a/src/lldpd/patch/series b/src/lldpd/patch/series index 419fbc96a16f..32fd4c0ca9a7 100644 --- a/src/lldpd/patch/series +++ b/src/lldpd/patch/series @@ -3,3 +3,5 @@ 0004-lldpctl-put-a-lock-around-some-commands-to-avoid-rac.patch 0006-lib-fix-memory-leak.patch 0007-lib-fix-memory-leak-when-handling-I-O.patch +0010-Ported-fix-for-length-exceeded-from-lldp-community.patch +0011-fix-med-location-len.patch diff --git a/src/lm-sensors/.gitignore b/src/lm-sensors/.gitignore new file mode 100644 index 000000000000..dfa47d4833b3 --- /dev/null +++ b/src/lm-sensors/.gitignore @@ -0,0 +1,4 @@ +* +!.gitignore +!Makefile +!patch/* diff --git a/src/lm-sensors/0001-patch-the-debian-package-info-to-get-sensord.patch b/src/lm-sensors/0001-patch-the-debian-package-info-to-get-sensord.patch deleted file mode 100644 index 4ff40124018e..000000000000 --- a/src/lm-sensors/0001-patch-the-debian-package-info-to-get-sensord.patch +++ /dev/null @@ -1,256 +0,0 @@ -From a8047116d3724bf77cb4306f0440ea62f0a453ca Mon Sep 17 00:00:00 2001 -From: Mykola Faryma -Date: Tue, 19 Mar 2019 14:41:15 +0000 -Subject: [PATCH] patch the debian package info to get sensord - -Signed-off-by: Mykola Faryma ---- - .../lm-sensors-3.4.0/debian/sensord.NEWS | 12 ++++ - .../lm-sensors-3.4.0/debian/sensord.README.Debian | 23 ++++++++ - .../lm-sensors-3.4.0/debian/sensord.default | 20 +++++++ - .../lm-sensors-3.4.0/debian/sensord.dirs | 3 + - .../lm-sensors-3.4.0/debian/sensord.init | 64 ++++++++++++++++++++++ - .../lm-sensors-3.4.0/debian/sensord.install | 2 + - .../lm-sensors-3.4.0/debian/sensord.maintscript | 2 + - .../lm-sensors-3.4.0/debian/sensord.postinst | 23 ++++++++ - .../lm-sensors-3.4.0/debian/sensord.substvars | 2 + - .../lm-sensors-3.4.0/debian/control | 14 ++++++++++++++ - 11 files changed, 167 insertions(+), 1 deletion(-) - create mode 100644 src/lm-sensors/lm-sensors-3.4.0/debian/sensord.NEWS - create mode 100644 src/lm-sensors/lm-sensors-3.4.0/debian/sensord.README.Debian - create mode 100644 src/lm-sensors/lm-sensors-3.4.0/debian/sensord.default - create mode 100644 src/lm-sensors/lm-sensors-3.4.0/debian/sensord.dirs - create mode 100644 src/lm-sensors/lm-sensors-3.4.0/debian/sensord.init - create mode 100644 src/lm-sensors/lm-sensors-3.4.0/debian/sensord.install - create mode 100644 src/lm-sensors/lm-sensors-3.4.0/debian/sensord.maintscript - create mode 100644 src/lm-sensors/lm-sensors-3.4.0/debian/sensord.postinst - create mode 100644 src/lm-sensors/lm-sensors-3.4.0/debian/sensord.substvars - -diff --git a/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.NEWS b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.NEWS -new file mode 100644 -index 0000000..4bcfdb9 ---- /dev/null -+++ b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.NEWS -@@ -0,0 +1,12 @@ -+lm-sensors (1:2.9.0-7) unstable; urgency=low -+ -+ Since version 2.9.0 sensord doesn't scale the loadavg itself (* 10) as -+ RRDs work with floating-point values and thus do very well with -+ non-integer values even < 1. -+ -+ They can even be scaled later at display time by rrdtool itself using: -+ DEF:load=sensord.rrd:loadavg:AVERAGE -+ CDEF:load10=load,10,* -+ -+ -- Aurelien Jarno Tue, 11 Jan 2005 22:41:34 +0100 -+ -diff --git a/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.README.Debian b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.README.Debian -new file mode 100644 -index 0000000..9159fbc ---- /dev/null -+++ b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.README.Debian -@@ -0,0 +1,23 @@ -+This is the Debian packaging of sensord, the sensord logging daemon. -+ -+The file /etc/default/sensord specifies the configuration parameters -+used to start the daemon. In particular, the syslog facility is set -+to `daemon' and not `local4'. -+ -+You must load the appropriate lm-sensors modules during system boot in -+order for the daemon to function correctly. -+ -+The file /etc/modules is a useful place to list these modules; for -+example, you might list i2c-amd756 (an I2C/SMBUS module) and w83781d -+(a sensor chip module). -+ -+The daemon does not setup the sensors limits from /etc/sensors3.conf, -+this is the job of sensors, when called with -s. Note that 'sensors -s' -+is called at boot time from /etc/init.d/lm-sensors, so that the sensors -+limits should be the right ones in normal use. Don't forget to run -+sensors -s again if you changed the limits in /etc/sensors3.conf. -+ -+For full documentation on setting up lm-sensors on your system, -+see /usr/share/doc/lm-sensors. -+ -+-- David Z. Maze -diff --git a/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.default b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.default -new file mode 100644 -index 0000000..589b94c ---- /dev/null -+++ b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.default -@@ -0,0 +1,20 @@ -+# Interval between scanning for alarms; e.g., 30s, 1m, 1h -+# ALARM_INTERVAL=1m -+# Interval between logging sensor measurements; e.g., 30s, 1m, 1h -+# LOG_INTERVAL=30m -+# Syslog facility to use -+SYSLOG_FACILITY=daemon -+# Libsensors config file to use -+# CONFIG_FILE=/etc/sensors3.conf -+# Chips to scan -+# SCAN_CHIPS=... -+ -+# Uncomment this to enable a 7-day round-robin database of sensor -+# readings. See the ROUND ROBIN DATABASES section of the sensord -+# manual page for details. -+# RRD_FILE=/var/log/sensord.rrd -+# Interval between RRD readings; e.g. 30s, 5m (default), 1h -+# RRD_INTERVAL=5m -+# Include the load average in the RRD file. If you enable this you -+# must remove your old RRD file and rebuild your CGI script. -+# RRD_LOADAVG=yes -diff --git a/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.dirs b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.dirs -new file mode 100644 -index 0000000..b9cd814 ---- /dev/null -+++ b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.dirs -@@ -0,0 +1,3 @@ -+usr/sbin -+usr/share/man/man8 -+etc/default -diff --git a/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.init b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.init -new file mode 100644 -index 0000000..4d70d43 ---- /dev/null -+++ b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.init -@@ -0,0 +1,64 @@ -+#!/bin/sh -+ -+### BEGIN INIT INFO -+# Provides: sensord -+# Required-Start: $remote_fs $syslog lm-sensors -+# Required-Stop: $remote_fs $syslog -+# Default-Start: 2 3 4 5 -+# Default-Stop: -+# Short-Description: lm-sensors daemon -+# Description: hardware sensor information logging daemon -+### END INIT INFO -+ -+. /lib/lsb/init-functions -+ -+[ -f /etc/default/rcS ] && . /etc/default/rcS -+PATH=/bin:/usr/bin:/sbin:/usr/sbin -+DAEMON=/usr/sbin/sensord -+DESC="sensor daemon" -+NAME="sensord" -+PIDFILE=/var/run/sensord.pid -+CONFIG=/etc/default/sensord -+ -+test -x $DAEMON || exit 0 -+ -+if [ -f $CONFIG ]; then . $CONFIG; fi -+ -+if [ -n "$ALARM_INTERVAL" ]; then ALARM_INTERVAL="-i $ALARM_INTERVAL"; fi -+if [ -n "$LOG_INTERVAL" ]; then LOG_INTERVAL="-l $LOG_INTERVAL"; fi -+if [ -n "$SYSLOG_FACILITY" ]; then SYSLOG_FACILITY="-f $SYSLOG_FACILITY"; fi -+if [ -n "$CONFIG_FILE" ]; then CONFIG_FILE="-c $CONFIG_FILE"; fi -+if [ -n "$RRD_FILE" ]; then RRD_FILE="-r $RRD_FILE"; fi -+if [ -n "$RRD_INTERVAL" ]; then RRD_INTERVAL="-t $RRD_INTERVAL"; fi -+if [ -n "$RRD_LOADAVG" ]; then RRD_LOADAVG="-a"; fi -+ -+case "$1" in -+ start) -+ log_daemon_msg "Starting $DESC" "$NAME" -+ /sbin/start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- $ALARM_INTERVAL $LOG_INTERVAL $SYSLOG_FACILITY $RRD_INTERVAL $RRD_FILE $RRD_LOADAVG $CONFIG_FILE $SCAN_CHIPS -+ log_end_msg $? -+ ;; -+ stop) -+ log_daemon_msg "Stopping $DESC" "$NAME" -+ start-stop-daemon --stop --quiet --pidfile $PIDFILE --oknodo --exec $DAEMON -+ log_end_msg $? -+ ;; -+ restart) -+ $0 stop -+ sleep 1 -+ $0 start -+ ;; -+ force-reload) -+ if start-stop-daemon --stop --test --quiet --pidfile $PIDFILE --exec $DAEMON ; then -+ $0 restart -+ fi -+ ;; -+ status) -+ status_of_proc $DAEMON $NAME && exit 0 || exit $? -+ ;; -+ *) -+ echo "Usage: /etc/init.d/sensord {start|stop|restart|force-reload|status}" -+ exit 1 -+esac -+ -+exit 0 -diff --git a/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.install b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.install -new file mode 100644 -index 0000000..9713fee ---- /dev/null -+++ b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.install -@@ -0,0 +1,2 @@ -+usr/sbin/sensord -+usr/share/man/man8/sensord.8 -diff --git a/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.maintscript b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.maintscript -new file mode 100644 -index 0000000..0e0ff03 ---- /dev/null -+++ b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.maintscript -@@ -0,0 +1,2 @@ -+# Remove old logcheck ignore file -+rm_conffile /etc/logcheck/ignore.d.server/sensord 1:3.3.5-1~ -diff --git a/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.postinst b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.postinst -new file mode 100644 -index 0000000..3418fa6 ---- /dev/null -+++ b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.postinst -@@ -0,0 +1,23 @@ -+#!/bin/sh -+# postinst script for sensord -+# -+# see: dh_installdeb(1) -+set -e -+ -+case "$1" in -+ configure) -+ # Remove shutdown and reboot links; this init script does not need them. -+ if dpkg --compare-versions "$2" lt "1:3.1.1-5"; then -+ rm -f /etc/rc0.d/K[0-9][0-9]sensord /etc/rc1.d/K[0-9][0-9]sensord /etc/rc6.d/K[0-9][0-9]sensord -+ fi -+ ;; -+ abort-upgrade|abort-remove|abort-deconfigure) -+ ;; -+ -+ *) -+ echo "postinst called with unknown argument \`$1'" >&2 -+ exit 1 -+ ;; -+esac -+ -+#DEBHELPER# -diff --git a/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.substvars b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.substvars -new file mode 100644 -index 0000000..978fc8b ---- /dev/null -+++ b/src/lm-sensors/lm-sensors-3.4.0/debian/sensord.substvars -@@ -0,0 +1,2 @@ -+misc:Depends= -+misc:Pre-Depends= -diff --git a/src/lm-sensors/lm-sensors-3.4.0/debian/control b/src/lm-sensors/lm-sensors-3.4.0/debian/control ---- a/src/lm-sensors/lm-sensors-3.4.0/debian/control -+++ b/src/lm-sensors/lm-sensors-3.4.0/debian/control -@@ -68,3 +68,17 @@ Description: utility to control the fan speed - and sets the corresponding PWM outputs to the computed values. This is - useful when this feature is not provided by the BIOS or ACPI, which should - normally be the case on a laptop. -+ -+Package: sensord -+Architecture: any -+Section: utils -+Depends: lm-sensors, lsb-base (>= 3.2-13), ${shlibs:Depends}, ${misc:Depends} -+Suggests: rrdtool -+Description: hardware sensor information logging daemon -+ Lm-sensors is a hardware health monitoring package for Linux. It allows you -+ to access information from temperature, voltage, and fan speed sensors. It -+ works with most newer systems. -+ . -+ This package contains a daemon that logs hardware health status to the -+ system log with optional warnings on potential system problems. -+ --- -1.9.1 diff --git a/src/lm-sensors/Makefile b/src/lm-sensors/Makefile index 50cc3e51bb3c..a5aa3ba7d885 100644 --- a/src/lm-sensors/Makefile +++ b/src/lm-sensors/Makefile @@ -5,7 +5,7 @@ SHELL = /bin/bash MAIN_TARGET = $(LM_SENSORS) DERIVED_TARGETS = fancontrol_$(LM_SENSORS_VERSION_FULL)_all.deb \ - libsensors4_$(LM_SENSORS_VERSION_FULL)_$(CONFIGURED_ARCH).deb \ + $(LIBSENSORS) \ sensord_$(LM_SENSORS_VERSION_FULL)_$(CONFIGURED_ARCH).deb \ $(LM_SENSORS_DBG) \ $(LIBSENSORS_DBG) \ @@ -14,9 +14,18 @@ DERIVED_TARGETS = fancontrol_$(LM_SENSORS_VERSION_FULL)_all.deb \ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : rm -rf lm-sensors-$(LM_SENSORS_VERSION) dget -u http://deb.debian.org/debian/pool/main/l/lm-sensors/lm-sensors_$(LM_SENSORS_VERSION_FULL).dsc - git apply *.patch pushd lm-sensors-$(LM_SENSORS_VERSION) - DEB_BUILD_OPTIONS=nocheck PROG_EXTRA=sensord dpkg-buildpackage -us -uc -b -j$(SONIC_CONFIG_MAKE_JOBS) + + # Initialize as git repository + git init + git add -f * + git commit -m "unmodified lm-sensors sources" + + # Apply patches + stg init + stg import -s ../patch/series + + DEB_BUILD_OPTIONS=nocheck PROG_EXTRA=sensord dpkg-buildpackage -us -uc -b -j$(SONIC_CONFIG_MAKE_JOBS) --admindir $(SONIC_DPKG_ADMINDIR) popd mv $(DERIVED_TARGETS) $* $(DEST)/ diff --git a/src/lm-sensors/patch/0001-patch-the-debian-package-info-to-get-sensord.patch b/src/lm-sensors/patch/0001-patch-the-debian-package-info-to-get-sensord.patch new file mode 100644 index 000000000000..262c7bca3f46 --- /dev/null +++ b/src/lm-sensors/patch/0001-patch-the-debian-package-info-to-get-sensord.patch @@ -0,0 +1,256 @@ +From a8047116d3724bf77cb4306f0440ea62f0a453ca Mon Sep 17 00:00:00 2001 +From: Mykola Faryma +Date: Tue, 19 Mar 2019 14:41:15 +0000 +Subject: [PATCH] patch the debian package info to get sensord + +Signed-off-by: Mykola Faryma +--- + debian/sensord.NEWS | 12 ++++ + debian/sensord.README.Debian | 23 ++++++++ + debian/sensord.default | 20 +++++++ + debian/sensord.dirs | 3 + + debian/sensord.init | 64 ++++++++++++++++++++++ + debian/sensord.install | 2 + + debian/sensord.maintscript | 2 + + debian/sensord.postinst | 23 ++++++++ + debian/sensord.substvars | 2 + + debian/control | 14 ++++++++++++++ + 11 files changed, 167 insertions(+), 1 deletion(-) + create mode 100644 /debian/sensord.NEWS + create mode 100644 /debian/sensord.README.Debian + create mode 100644 /debian/sensord.default + create mode 100644 /debian/sensord.dirs + create mode 100644 /debian/sensord.init + create mode 100644 /debian/sensord.install + create mode 100644 /debian/sensord.maintscript + create mode 100644 /debian/sensord.postinst + create mode 100644 /debian/sensord.substvars + +diff --git a/debian/sensord.NEWS b/debian/sensord.NEWS +new file mode 100644 +index 0000000..4bcfdb9 +--- /dev/null ++++ b/debian/sensord.NEWS +@@ -0,0 +1,12 @@ ++lm-sensors (1:2.9.0-7) unstable; urgency=low ++ ++ Since version 2.9.0 sensord doesn't scale the loadavg itself (* 10) as ++ RRDs work with floating-point values and thus do very well with ++ non-integer values even < 1. ++ ++ They can even be scaled later at display time by rrdtool itself using: ++ DEF:load=sensord.rrd:loadavg:AVERAGE ++ CDEF:load10=load,10,* ++ ++ -- Aurelien Jarno Tue, 11 Jan 2005 22:41:34 +0100 ++ +diff --git a/debian/sensord.README.Debian b/debian/sensord.README.Debian +new file mode 100644 +index 0000000..9159fbc +--- /dev/null ++++ b/debian/sensord.README.Debian +@@ -0,0 +1,23 @@ ++This is the Debian packaging of sensord, the sensord logging daemon. ++ ++The file /etc/default/sensord specifies the configuration parameters ++used to start the daemon. In particular, the syslog facility is set ++to `daemon' and not `local4'. ++ ++You must load the appropriate lm-sensors modules during system boot in ++order for the daemon to function correctly. ++ ++The file /etc/modules is a useful place to list these modules; for ++example, you might list i2c-amd756 (an I2C/SMBUS module) and w83781d ++(a sensor chip module). ++ ++The daemon does not setup the sensors limits from /etc/sensors3.conf, ++this is the job of sensors, when called with -s. Note that 'sensors -s' ++is called at boot time from /etc/init.d/lm-sensors, so that the sensors ++limits should be the right ones in normal use. Don't forget to run ++sensors -s again if you changed the limits in /etc/sensors3.conf. ++ ++For full documentation on setting up lm-sensors on your system, ++see /usr/share/doc/lm-sensors. ++ ++-- David Z. Maze +diff --git a/debian/sensord.default b/debian/sensord.default +new file mode 100644 +index 0000000..589b94c +--- /dev/null ++++ b/debian/sensord.default +@@ -0,0 +1,20 @@ ++# Interval between scanning for alarms; e.g., 30s, 1m, 1h ++# ALARM_INTERVAL=1m ++# Interval between logging sensor measurements; e.g., 30s, 1m, 1h ++# LOG_INTERVAL=30m ++# Syslog facility to use ++SYSLOG_FACILITY=daemon ++# Libsensors config file to use ++# CONFIG_FILE=/etc/sensors3.conf ++# Chips to scan ++# SCAN_CHIPS=... ++ ++# Uncomment this to enable a 7-day round-robin database of sensor ++# readings. See the ROUND ROBIN DATABASES section of the sensord ++# manual page for details. ++# RRD_FILE=/var/log/sensord.rrd ++# Interval between RRD readings; e.g. 30s, 5m (default), 1h ++# RRD_INTERVAL=5m ++# Include the load average in the RRD file. If you enable this you ++# must remove your old RRD file and rebuild your CGI script. ++# RRD_LOADAVG=yes +diff --git a/debian/sensord.dirs b/debian/sensord.dirs +new file mode 100644 +index 0000000..b9cd814 +--- /dev/null ++++ b/debian/sensord.dirs +@@ -0,0 +1,3 @@ ++usr/sbin ++usr/share/man/man8 ++etc/default +diff --git a/debian/sensord.init b/debian/sensord.init +new file mode 100644 +index 0000000..4d70d43 +--- /dev/null ++++ b/debian/sensord.init +@@ -0,0 +1,64 @@ ++#!/bin/sh ++ ++### BEGIN INIT INFO ++# Provides: sensord ++# Required-Start: $remote_fs $syslog lm-sensors ++# Required-Stop: $remote_fs $syslog ++# Default-Start: 2 3 4 5 ++# Default-Stop: ++# Short-Description: lm-sensors daemon ++# Description: hardware sensor information logging daemon ++### END INIT INFO ++ ++. /lib/lsb/init-functions ++ ++[ -f /etc/default/rcS ] && . /etc/default/rcS ++PATH=/bin:/usr/bin:/sbin:/usr/sbin ++DAEMON=/usr/sbin/sensord ++DESC="sensor daemon" ++NAME="sensord" ++PIDFILE=/var/run/sensord.pid ++CONFIG=/etc/default/sensord ++ ++test -x $DAEMON || exit 0 ++ ++if [ -f $CONFIG ]; then . $CONFIG; fi ++ ++if [ -n "$ALARM_INTERVAL" ]; then ALARM_INTERVAL="-i $ALARM_INTERVAL"; fi ++if [ -n "$LOG_INTERVAL" ]; then LOG_INTERVAL="-l $LOG_INTERVAL"; fi ++if [ -n "$SYSLOG_FACILITY" ]; then SYSLOG_FACILITY="-f $SYSLOG_FACILITY"; fi ++if [ -n "$CONFIG_FILE" ]; then CONFIG_FILE="-c $CONFIG_FILE"; fi ++if [ -n "$RRD_FILE" ]; then RRD_FILE="-r $RRD_FILE"; fi ++if [ -n "$RRD_INTERVAL" ]; then RRD_INTERVAL="-t $RRD_INTERVAL"; fi ++if [ -n "$RRD_LOADAVG" ]; then RRD_LOADAVG="-a"; fi ++ ++case "$1" in ++ start) ++ log_daemon_msg "Starting $DESC" "$NAME" ++ /sbin/start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- $ALARM_INTERVAL $LOG_INTERVAL $SYSLOG_FACILITY $RRD_INTERVAL $RRD_FILE $RRD_LOADAVG $CONFIG_FILE $SCAN_CHIPS ++ log_end_msg $? ++ ;; ++ stop) ++ log_daemon_msg "Stopping $DESC" "$NAME" ++ start-stop-daemon --stop --quiet --pidfile $PIDFILE --oknodo --exec $DAEMON ++ log_end_msg $? ++ ;; ++ restart) ++ $0 stop ++ sleep 1 ++ $0 start ++ ;; ++ force-reload) ++ if start-stop-daemon --stop --test --quiet --pidfile $PIDFILE --exec $DAEMON ; then ++ $0 restart ++ fi ++ ;; ++ status) ++ status_of_proc $DAEMON $NAME && exit 0 || exit $? ++ ;; ++ *) ++ echo "Usage: /etc/init.d/sensord {start|stop|restart|force-reload|status}" ++ exit 1 ++esac ++ ++exit 0 +diff --git a/debian/sensord.install b/debian/sensord.install +new file mode 100644 +index 0000000..9713fee +--- /dev/null ++++ b/debian/sensord.install +@@ -0,0 +1,2 @@ ++usr/sbin/sensord ++usr/share/man/man8/sensord.8 +diff --git a/debian/sensord.maintscript b/debian/sensord.maintscript +new file mode 100644 +index 0000000..0e0ff03 +--- /dev/null ++++ b/debian/sensord.maintscript +@@ -0,0 +1,2 @@ ++# Remove old logcheck ignore file ++rm_conffile /etc/logcheck/ignore.d.server/sensord 1:3.3.5-1~ +diff --git a/debian/sensord.postinst b/debian/sensord.postinst +new file mode 100644 +index 0000000..3418fa6 +--- /dev/null ++++ b/debian/sensord.postinst +@@ -0,0 +1,23 @@ ++#!/bin/sh ++# postinst script for sensord ++# ++# see: dh_installdeb(1) ++set -e ++ ++case "$1" in ++ configure) ++ # Remove shutdown and reboot links; this init script does not need them. ++ if dpkg --compare-versions "$2" lt "1:3.1.1-5"; then ++ rm -f /etc/rc0.d/K[0-9][0-9]sensord /etc/rc1.d/K[0-9][0-9]sensord /etc/rc6.d/K[0-9][0-9]sensord ++ fi ++ ;; ++ abort-upgrade|abort-remove|abort-deconfigure) ++ ;; ++ ++ *) ++ echo "postinst called with unknown argument \`$1'" >&2 ++ exit 1 ++ ;; ++esac ++ ++#DEBHELPER# +diff --git a/debian/sensord.substvars b/debian/sensord.substvars +new file mode 100644 +index 0000000..978fc8b +--- /dev/null ++++ b/debian/sensord.substvars +@@ -0,0 +1,2 @@ ++misc:Depends= ++misc:Pre-Depends= +diff --git a/debian/control b/debian/control +--- a/debian/control ++++ b/debian/control +@@ -68,3 +68,17 @@ Description: utility to control the fan speed + and sets the corresponding PWM outputs to the computed values. This is + useful when this feature is not provided by the BIOS or ACPI, which should + normally be the case on a laptop. ++ ++Package: sensord ++Architecture: any ++Section: utils ++Depends: lm-sensors, lsb-base (>= 3.2-13), ${shlibs:Depends}, ${misc:Depends} ++Suggests: rrdtool ++Description: hardware sensor information logging daemon ++ Lm-sensors is a hardware health monitoring package for Linux. It allows you ++ to access information from temperature, voltage, and fan speed sensors. It ++ works with most newer systems. ++ . ++ This package contains a daemon that logs hardware health status to the ++ system log with optional warnings on potential system problems. ++ +-- +1.9.1 diff --git a/src/lm-sensors/patch/0002-Patch-to-peform-dh_installinit-to-include-sensord.in.patch b/src/lm-sensors/patch/0002-Patch-to-peform-dh_installinit-to-include-sensord.in.patch new file mode 100644 index 000000000000..7bfdee11e3be --- /dev/null +++ b/src/lm-sensors/patch/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/debian/rules b/debian/rules +index 5ebda06..1d77e28 100755 +--- a/debian/rules ++++ b/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 + diff --git a/src/lm-sensors/patch/series b/src/lm-sensors/patch/series new file mode 100644 index 000000000000..43980ccab4db --- /dev/null +++ b/src/lm-sensors/patch/series @@ -0,0 +1,2 @@ +0001-patch-the-debian-package-info-to-get-sensord.patch +0002-Patch-to-peform-dh_installinit-to-include-sensord.in.patch diff --git a/src/monit/.gitignore b/src/monit/.gitignore new file mode 100644 index 000000000000..d19db76ab9a9 --- /dev/null +++ b/src/monit/.gitignore @@ -0,0 +1,4 @@ +* +!.gitignore +!Makefile +!patch/ diff --git a/src/monit/Makefile b/src/monit/Makefile index 4ad9edd79143..570f30cf60f8 100644 --- a/src/monit/Makefile +++ b/src/monit/Makefile @@ -24,7 +24,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : stg import -s ../patch/series # Build source and Debian packages - dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) + dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) --admindir $(SONIC_DPKG_ADMINDIR) popd # Move the newly-built .deb packages to the destination directory diff --git a/src/monit/patch/0002-change_monit_alert_log_error.patch b/src/monit/patch/0002-change_monit_alert_log_error.patch new file mode 100644 index 000000000000..1e43078e6215 --- /dev/null +++ b/src/monit/patch/0002-change_monit_alert_log_error.patch @@ -0,0 +1,64 @@ +From 97a5defc6a7fcc6a00f691bb5314ceb8fb7704e9 Mon Sep 17 00:00:00 2001 +From: Abhishek Dosi +Date: Mon, 26 Oct 2020 11:40:02 -0700 +Subject: [PATCH] Patch on top of commit Patch is addressing these changes:- + +a) Enable repeat keyword for alert action . Using this we can log +syslog error message for persistent failure condition + +b) Make sure error message is loggged if state is changed to fail first time (fault tolerance condition) +or we have repeat clause for alert + +Signed-off-by: Abhishek Dosi + +--- + src/event.c | 6 +++++- + src/p.y | 8 +++++++- + 2 files changed, 12 insertions(+), 2 deletions(-) + +diff --git a/src/event.c b/src/event.c +index ed363ee..9d08fc0 100644 +--- a/src/event.c ++++ b/src/event.c +@@ -336,7 +336,8 @@ static void _handleEvent(Service_T S, Event_T E) { + if (E->state != State_Init || E->state_map & 0x1) { + if (E->state == State_Succeeded || E->state == State_ChangedNot || E->id == Event_Instance || E->id == Event_Action) + LogInfo("'%s' %s\n", S->name, E->message); +- else ++ /* Send Error log if state change to failed for 1st time or if we have repeat clause then do periodically */ ++ else if ((E->state_changed) || (E->state == State_Failed && E->action->failed->repeat && E->count % E->action->failed->repeat == 0)) + LogError("'%s' %s\n", S->name, E->message); + } + if (E->state == State_Init) + return; +diff --git a/src/p.y b/src/p.y +index a57807d..b46b1a1 100644 +--- a/src/p.y ++++ b/src/p.y +@@ -2250,9 +2250,12 @@ repeat : /* EMPTY */ { + } + ; + +-action : ALERT { ++action : ALERT repeat{ + $$ = Action_Alert; + } ++ | ALERT { ++ $$ = Action_Alert; ++ } + | EXEC argumentlist repeat { + $$ = Action_Exec; + } +@@ -2281,6 +2284,9 @@ action1 : action { + repeat = 0; + command1 = command; + command = NULL; ++ } else if ($1 == Action_Alert) { ++ repeat1 = repeat; ++ repeat = 0; + } + } + ; +-- +2.17.1 + diff --git a/src/monit/patch/series b/src/monit/patch/series index 15fcdd50c8a5..f5534d0f554f 100644 --- a/src/monit/patch/series +++ b/src/monit/patch/series @@ -1,2 +1,3 @@ # This series applies on GIT commit dc9bc1c949125140d967edfc598dfad47eedc552 0001-used_system_memory_sysdep-Use-MemAvailable-value-if-.patch +0002-change_monit_alert_log_error.patch diff --git a/src/mpdecimal/.gitignore b/src/mpdecimal/.gitignore new file mode 100644 index 000000000000..a0991ff4402b --- /dev/null +++ b/src/mpdecimal/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!Makefile diff --git a/src/mpdecimal/Makefile b/src/mpdecimal/Makefile index c4ef5b78b49c..b7f82ba702e5 100644 --- a/src/mpdecimal/Makefile +++ b/src/mpdecimal/Makefile @@ -14,7 +14,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : dpkg-source -x mpdecimal_$(MPDECIMAL_VERSION_FULL).dsc pushd mpdecimal-$(MPDECIMAL_VERSION) - dpkg-buildpackage -us -uc -b -j$(SONIC_CONFIG_MAKE_JOBS) + dpkg-buildpackage -us -uc -b -j$(SONIC_CONFIG_MAKE_JOBS) --admindir $(SONIC_DPKG_ADMINDIR) popd mv $* $(DERIVED_TARGETS) $(DEST)/ diff --git a/src/ntp/.gitignore b/src/ntp/.gitignore new file mode 100644 index 000000000000..1b46fe753f41 --- /dev/null +++ b/src/ntp/.gitignore @@ -0,0 +1,5 @@ +*+dfsg +*.buildinfo +*.changes +*.xz +*.deb diff --git a/src/ntp/Makefile b/src/ntp/Makefile new file mode 100644 index 000000000000..6d96010be156 --- /dev/null +++ b/src/ntp/Makefile @@ -0,0 +1,48 @@ +.ONESHELL: +SHELL = /bin/bash +.SHELLFLAGS += -e + +MAIN_TARGET = $(NTP) + +$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : + # Remove any stale files + rm -rf ./ntp-$(NTP_VERSION) ./ntp_$(NTP_VERSION).orig.tar.xz ./ntp_$(NTP_VERSION)-4.debian.tar.xz + + # Get ntp release, debian files + wget http://deb.debian.org/debian/pool/main/n/ntp/ntp_$(NTP_VERSION).orig.tar.xz + wget http://deb.debian.org/debian/pool/main/n/ntp/ntp_$(NTP_VERSION)-4.debian.tar.xz + + # UnTar ntp release + xzcat ntp_$(NTP_VERSION).orig.tar.xz | tar -xvf - + + pushd ./ntp-4.2.8p12 + + # UnTar debian files + xzcat ../ntp_$(NTP_VERSION)-4.debian.tar.xz | tar -xvf - + + # Add the additional patch + cp ../patch/bug1970-UNLINK_EXPR_SLIST_empty_list.patch debian/patches/ + cp ../patch/update_ENOBUFS_log_level.patch debian/patches/ + cat ../patch/series >> debian/patches/series + + # Update the changelog + cat ../patch/changelog debian/changelog > debian/changelog.new + rm debian/changelog ; mv debian/changelog.new debian/changelog + + # The debian mirror build likely took place on a system without + # libevent installed, thus adding the below for SONiC + sed -i 's/--with-locfile=legacy/--with-locfile=legacy --enable-local-libevent/' debian/rules + + # Fix the apparmor profile to avoid the following message + # "Failed name lookup - disconnected path" + # and go into learning mode. + sed -i 's/\/usr\/sbin\/ntpd {/\/usr\/sbin\/ntpd flags=(attach_disconnected complain) {/' debian/apparmor-profile + + # Build source and Debian packages with the symbols + dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) --admindir $(SONIC_DPKG_ADMINDIR) + + popd + + # Move the newly-built .deb packages to the destination directory + mv $* $(DEST)/ + diff --git a/src/ntp/patch/bug1970-UNLINK_EXPR_SLIST_empty_list.patch b/src/ntp/patch/bug1970-UNLINK_EXPR_SLIST_empty_list.patch new file mode 100644 index 000000000000..701dc0103944 --- /dev/null +++ b/src/ntp/patch/bug1970-UNLINK_EXPR_SLIST_empty_list.patch @@ -0,0 +1,26 @@ +Bug 1970 UNLINK_EXPR_SLIST() causes crash if list is empty + +From: Arun Barboza + + +--- + include/ntp_lists.h | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/include/ntp_lists.h b/include/ntp_lists.h +index d741974..f90bf23 100644 +--- a/include/ntp_lists.h ++++ b/include/ntp_lists.h +@@ -184,7 +184,11 @@ do { \ + do { \ + entrytype **ppentry; \ + \ +- ppentry = &(listhead); \ ++ if (!listhead) { \ ++ (punlinked) = NULL; \ ++ break; \ ++ } \ ++ else ppentry = &(listhead); \ + \ + while (!(expr)) \ + if (*ppentry != NULL && \ diff --git a/src/ntp/patch/changelog b/src/ntp/patch/changelog new file mode 100644 index 000000000000..8fa477cca266 --- /dev/null +++ b/src/ntp/patch/changelog @@ -0,0 +1,12 @@ +ntp (1:4.2.8p12+dfsg-4+deb10u2) stretch; urgency=medium + + * Adjust the ENOBUFS syslog level on the Netlink routing to LOG_WARNING. + + -- Arun Barboza Mon, 09 Sep 2019 10:15:35 -0700 + +ntp (1:4.2.8p12+dfsg-4+deb10u1) stretch; urgency=medium + + * Apply Bug1970 fix for UNLINK_EXPR_SLIST_empty_list from dev branch. + + -- Arun Barboza Tue, 25 Jun 2019 14:35:24 -0700 + diff --git a/src/ntp/patch/series b/src/ntp/patch/series new file mode 100644 index 000000000000..9ce40f13e21a --- /dev/null +++ b/src/ntp/patch/series @@ -0,0 +1,3 @@ +# This series applies on GIT commit d09f041a49c61971f59fc29f505446c63aea51b1 +bug1970-UNLINK_EXPR_SLIST_empty_list.patch +update_ENOBUFS_log_level.patch diff --git a/src/ntp/patch/update_ENOBUFS_log_level.patch b/src/ntp/patch/update_ENOBUFS_log_level.patch new file mode 100644 index 000000000000..618fc323b105 --- /dev/null +++ b/src/ntp/patch/update_ENOBUFS_log_level.patch @@ -0,0 +1,22 @@ +Adjust the ENOBUFS syslog level on the Netlink routing to LOG_WARNING. + +From: Arun Barboza + + +--- + ntpd/ntp_io.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: b/ntpd/ntp_io.c +=================================================================== +--- a/ntpd/ntp_io.c ++++ b/ntpd/ntp_io.c +@@ -4709,7 +4709,7 @@ process_routing_msgs(struct asyncio_read + + if (cnt < 0) { + if (errno == ENOBUFS) { +- msyslog(LOG_ERR, ++ msyslog(LOG_WARNING, + "routing socket reports: %m"); + } else { + msyslog(LOG_ERR, diff --git a/src/openssh/Makefile b/src/openssh/Makefile new file mode 100644 index 000000000000..0fd8642b1285 --- /dev/null +++ b/src/openssh/Makefile @@ -0,0 +1,28 @@ +.ONESHELL: +SHELL = /bin/bash +.SHELLFLAGS += -e + +MAIN_TARGET = openssh-server_$(OPENSSH_VERSION)_$(CONFIGURED_ARCH).deb +DERIVED_TARGETS = openssh-server-dbgsym_$(OPENSSH_VERSION)_$(CONFIGURED_ARCH).deb + +$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : + # Obtain openssh: https://salsa.debian.org/ssh-team/openssh/-/tree/debian/1%257.9p1-10+deb10u2 + rm -rf ./openssh-server + git clone https://salsa.debian.org/ssh-team/openssh.git openssh-server + pushd ./openssh-server + + # Check out tag: debian/1%7.9p1-10+deb10u2 + git checkout -b openssh-src -f 6d9ca74c48d9911342c6ca5aaac8a25974fa2619 + + # Apply patch series + stg init + stg import -s ../patch/series + + # Build package + sudo http_proxy=$(http_proxy) apt-get -y build-dep openssh + dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) --admindir $(SONIC_DPKG_ADMINDIR) + popd + + mv $(DERIVED_TARGETS) $* $(DEST)/ + +$(addprefix $(DEST)/, $(DERIVED_TARGETS)): $(DEST)/% : $(DEST)/$(MAIN_TARGET) diff --git a/src/openssh/patch/0001-Put-style-as-line-number-to-ssh-session-environment-.patch b/src/openssh/patch/0001-Put-style-as-line-number-to-ssh-session-environment-.patch new file mode 100644 index 000000000000..a11c7bf46c37 --- /dev/null +++ b/src/openssh/patch/0001-Put-style-as-line-number-to-ssh-session-environment-.patch @@ -0,0 +1,36 @@ +From 6e8cca780dab4680292192058b90a4a28f35d4ab Mon Sep 17 00:00:00 2001 +From: Blueve +Date: Mon, 26 Oct 2020 06:44:59 +0000 +Subject: [PATCH 1/1] Put style as line number to ssh session environment + variable + +By default, the content between : and @ will be trimmed by sshd before it do +authentication and the trimmed string will be dropped silently. To use this +segment as line number for reverse SSH feature, we need to modify the source +code of OpenSSH and put this segment to a environment variable +SSH_TARGET_CONSOLE_LINE, then we can insert a short script into /etc/bash.bashrc +and run command consutil connect $SSH_TARGET_CONSOLE_LINE to enter the +management session automatically after user login. +--- + session.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/session.c b/session.c +index 19f38637e..654371447 100644 +--- a/session.c ++++ b/session.c +@@ -1209,6 +1209,11 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) + child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND", + original_command); + ++ /* Take advantage of authentication style field */ ++ if (s->authctxt->style) ++ child_set_env(&env, &envsize, "SSH_TARGET_CONSOLE_LINE", ++ s->authctxt->style); ++ + if (debug_flag) { + /* dump the environment */ + fprintf(stderr, "Environment:\n"); +-- +2.25.1 + diff --git a/src/openssh/patch/series b/src/openssh/patch/series new file mode 100644 index 000000000000..a645ad25833f --- /dev/null +++ b/src/openssh/patch/series @@ -0,0 +1 @@ +0001-Put-style-as-line-number-to-ssh-session-environment-.patch diff --git a/src/python-click/Makefile b/src/python-click/Makefile deleted file mode 100644 index 4deb27257fd2..000000000000 --- a/src/python-click/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -.ONESHELL: -SHELL = /bin/bash -.SHELLFLAGS += -e - -MAIN_TARGET = python-click_$(PYTHON_CLICK_VERSION)_all.deb - -$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : - # Remove any stale files - rm -rf ./python-click - - # Clone python-click Debian repo - git clone https://salsa.debian.org/debian/python-click - - pushd ./python-click - - # Reset HEAD to the commit of the proper tag - # NOTE: Using "git checkout " here detaches our HEAD, - # which stg doesn't like, so we use this method instead - git reset --hard debian/$(PYTHON_CLICK_VERSION) - - # Build source and Debian packages - dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) - popd - - # Move the newly-built .deb package to the destination directory - mv $* $(DEST)/ diff --git a/src/python3/Makefile b/src/python3/Makefile deleted file mode 100644 index c5d8c386c1b0..000000000000 --- a/src/python3/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -.ONESHELL: -SHELL = /bin/bash -.SHELLFLAGS += -e - -PYTHON_VER=3.6.0 -PYTHON_DEB_VER=1 -PYTHON_PNAME=python3.6 - -MAIN_TARGET = lib$(PYTHON_PNAME)-minimal_$(PYTHON_VER)-$(PYTHON_DEB_VER)_$(CONFIGURED_ARCH).deb -DERIVED_TARGETS = lib$(PYTHON_PNAME)-stdlib_$(PYTHON_VER)-$(PYTHON_DEB_VER)_$(CONFIGURED_ARCH).deb \ - lib$(PYTHON_PNAME)_$(PYTHON_VER)-$(PYTHON_DEB_VER)_$(CONFIGURED_ARCH).deb \ - $(PYTHON_PNAME)-minimal_$(PYTHON_VER)-$(PYTHON_DEB_VER)_$(CONFIGURED_ARCH).deb \ - $(PYTHON_PNAME)_$(PYTHON_VER)-$(PYTHON_DEB_VER)_$(CONFIGURED_ARCH).deb \ - lib$(PYTHON_PNAME)-dev_$(PYTHON_VER)-$(PYTHON_DEB_VER)_$(CONFIGURED_ARCH).deb - #$(PYTHON_PNAME)-dev_$(PYTHON_VER)-$(PYTHON_DEB_VER)_$(CONFIGURED_ARCH).deb - -$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : - # Remove any stale files - rm -rf $(PYTHON_PNAME)-$(PYTHON_VER) - - ## Obtaining the python3 - wget 'https://sonicstorage.blob.core.windows.net/packages/$(PYTHON_PNAME)_$(PYTHON_VER).orig.tar.xz?sv=2015-04-05&sr=b&sig=d42Wh1CA9NZvlskhW4fpWcHVgc7N3IKhdFzyeO2zbRA%3D&se=2027-02-02T01%3A00%3A57Z&sp=r' -O $(PYTHON_PNAME)_$(PYTHON_VER).orig.tar.xz - wget 'https://sonicstorage.blob.core.windows.net/packages/$(PYTHON_PNAME)_$(PYTHON_VER)-$(PYTHON_DEB_VER).debian.tar.xz?sv=2015-04-05&sr=b&sig=KLX9pMJ3zpQvGBo6ZjzoZXgooMJRUUwMx8ZaTJtywK0%3D&se=2027-02-02T00%3A59%3A34Z&sp=r' -O $(PYTHON_PNAME)_$(PYTHON_VER)-$(PYTHON_DEB_VER).debian.tar.xz - wget 'https://sonicstorage.blob.core.windows.net/packages/$(PYTHON_PNAME)_$(PYTHON_VER)-$(PYTHON_DEB_VER).dsc?sv=2015-04-05&sr=b&sig=95s%2FC4vKY6bRKtkUTz%2BmHLqOllBOYbfP3zV5ayAuzSM%3D&se=2027-02-02T01%3A00%3A26Z&sp=r' -O $(PYTHON_PNAME)_$(PYTHON_VER)-$(PYTHON_DEB_VER).dsc - - ## Build - dpkg-source -x $(PYTHON_PNAME)_$(PYTHON_VER)-$(PYTHON_DEB_VER).dsc - pushd $(PYTHON_PNAME)-$(PYTHON_VER) - mk-build-deps - - # put a lock here because dpkg does not allow installing packages in parallel - while true; do - if mkdir $(DEST)/dpkg_lock &> /dev/null; then - { echo here && (sudo dpkg -i $(PYTHON_PNAME)-build-deps_$(PYTHON_VER)-$(PYTHON_DEB_VER)_$(CONFIGURED_ARCH).deb || sudo apt-get install -f) && rm -d $(DEST)/dpkg_lock && break; } || { rm -d $(DEST)/dpkg_lock && exit 1 ; } - fi - done - - dpkg-buildpackage -rfakeroot -us -uc -b -j$(SONIC_CONFIG_MAKE_JOBS) - popd - - cp $(DERIVED_TARGETS) $* $(DEST)/ - -$(addprefix $(DEST)/, $(DERIVED_TARGETS)): $(DEST)/% : $(DEST)/$(MAIN_TARGET) diff --git a/src/radvd/Makefile b/src/radvd/Makefile deleted file mode 100644 index 98e62bc216d4..000000000000 --- a/src/radvd/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -.ONESHELL: -SHELL = /bin/bash -.SHELLFLAGS += -e - -MAIN_TARGET = radvd_$(RADVD_VERSION)_$(CONFIGURED_ARCH).deb -DERIVED_TARGETS = radvd-dbgsym_$(RADVD_VERSION)_$(CONFIGURED_ARCH).deb - -$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : - # Remove any stale files - rm -rf ./radvd - - # Clone radvd repo - git clone https://salsa.debian.org/debian/radvd.git - pushd ./radvd - - # Reset HEAD to the commit of the proper tag - # NOTE: Using "git checkout " here detaches our HEAD, - # which stg doesn't like, so we use this method instead - # NOTE 1: For some reason, tags in the Debian radvd repo are prefixed with "1%" - # NOTE 2: "~" in version string is replaced by "_" in branch name - git reset --hard debian/1\%$(subst ~,_,$(RADVD_VERSION)) - - # Apply patches - stg init - stg import -s ../patch/series - - # Build source and Debian packages - dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) - popd - - # Move the newly-built .deb package to the destination directory - mv $(DERIVED_TARGETS) $* $(DEST)/ diff --git a/src/radvd/patch/0001-Don-t-treat-out-of-range-MTU-as-an-error.patch b/src/radvd/patch/0001-Don-t-treat-out-of-range-MTU-as-an-error.patch deleted file mode 100644 index a9f988fee5d7..000000000000 --- a/src/radvd/patch/0001-Don-t-treat-out-of-range-MTU-as-an-error.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 45c15407f11de8b1064b77212727e5234f3ef1e8 Mon Sep 17 00:00:00 2001 -From: Joe LeVeque -Date: Sat, 16 Feb 2019 02:59:10 +0000 -Subject: [PATCH] Don't treat out-of-range MTU as an error - ---- - interface.c | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - -diff --git a/interface.c b/interface.c -index 512f2bd..0dc19f4 100644 ---- a/interface.c -+++ b/interface.c -@@ -200,9 +200,14 @@ int check_iface(struct Interface *iface) - - if ((iface->AdvLinkMTU != 0) && ((iface->AdvLinkMTU < MIN_AdvLinkMTU) || - (iface->sllao.if_maxmtu != -1 && (iface->AdvLinkMTU > iface->sllao.if_maxmtu)))) { -- flog(LOG_ERR, "AdvLinkMTU for %s (%u) must be zero or between %u and %u", iface->props.name, iface->AdvLinkMTU, -+ // FIXME: Temporary workaround for SONiC. Currently, when interfaces are added -+ // or removed from VLANs, the kernel sets the MTU size for the VLAN to the -+ // default value of 1500. Here, we prevent radvd from treating a larger value -+ // in its configuration as an error. Instead of logging an error and setting -+ // res to -1, we simply log a warning and continue on. Once the aforementioned -+ // behavior is addressed, this patch should be removed. -+ flog(LOG_WARNING, "AdvLinkMTU for %s (%u) must be zero or between %u and %u", iface->props.name, iface->AdvLinkMTU, - MIN_AdvLinkMTU, iface->sllao.if_maxmtu); -- res = -1; - } - - if (iface->ra_header_info.AdvReachableTime > MAX_AdvReachableTime) { --- -2.17.1 - diff --git a/src/radvd/patch/series b/src/radvd/patch/series deleted file mode 100644 index 7a12163dc040..000000000000 --- a/src/radvd/patch/series +++ /dev/null @@ -1,2 +0,0 @@ -# This series applies on GIT commit 413616c1b6a05f07f07f3ee6af0cf25a3215fe1a -0001-Don-t-treat-out-of-range-MTU-as-an-error.patch diff --git a/src/redis-dump-load b/src/redis-dump-load index 832a645e4ddf..758549795174 160000 --- a/src/redis-dump-load +++ b/src/redis-dump-load @@ -1 +1 @@ -Subproject commit 832a645e4ddff0f38ec0d64e3be70f48013287e6 +Subproject commit 758549795174dc6b3be70810e0e4d6308f80f1a3 diff --git a/src/redis-dump-load.patch/0001-Use-pipelines-when-dumping-52.patch b/src/redis-dump-load.patch/0001-Use-pipelines-when-dumping-52.patch index 5eea3faba2c3..c37cbd9f4bf1 100644 --- a/src/redis-dump-load.patch/0001-Use-pipelines-when-dumping-52.patch +++ b/src/redis-dump-load.patch/0001-Use-pipelines-when-dumping-52.patch @@ -33,7 +33,7 @@ index df2870b..1b6063b 100755 if pretty: # hack to avoid implementing pretty printing fp.write(dumps(host=host, port=port, password=password, db=db, -@@ -276,28 +276,76 @@ def _read_key(key, r, pretty, encoding): +@@ -276,28 +276,77 @@ def _read_key(key, r, pretty, encoding): return (type, ttl, value) def _reader(r, pretty, encoding, keys='*'): @@ -68,7 +68,7 @@ index df2870b..1b6063b 100755 + i += 10000 + +def _read_keys(r, encoded_keys, pretty, encoding): -+ decoded_keys = [encoded_key.decode() for encoded_key in encoded_keys] ++ decoded_keys = [encoded_key.decode(encoding) for encoded_key in encoded_keys] + do_keys = decoded_keys + retries = 5 + type_results = None @@ -84,12 +84,13 @@ index df2870b..1b6063b 100755 + p = r.pipeline() + for key in do_keys: + p.type(key) -+ type_results = p.execute() ++ encoded_type_results = p.execute() ++ type_results = [encoded_type_result.decode('ascii') for encoded_type_result in encoded_type_results] + + p = r.pipeline() + for i in range(len(do_keys)): + key = decoded_keys[i] -+ type = type_results[i].decode('ascii') ++ type = type_results[i] + if type == 'none': + # key was deleted by a concurrent operation on the data store. + # issue noops so that the number of results does not change diff --git a/src/redis/.gitignore b/src/redis/.gitignore new file mode 100644 index 000000000000..a0991ff4402b --- /dev/null +++ b/src/redis/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!Makefile diff --git a/src/redis/Makefile b/src/redis/Makefile index e2d9e5828f5b..3a4fe3f4844c 100644 --- a/src/redis/Makefile +++ b/src/redis/Makefile @@ -22,7 +22,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : pushd redis-$(REDIS_VERSION) export ARCH="" - DEB_BUILD_OPTIONS=nocheck dpkg-buildpackage -us -uc -b -j$(SONIC_CONFIG_MAKE_JOBS) + DEB_BUILD_OPTIONS=nocheck dpkg-buildpackage -us -uc -b -j$(SONIC_CONFIG_MAKE_JOBS) --admindir $(SONIC_DPKG_ADMINDIR) popd mv $(DERIVED_TARGETS) $* $(DEST)/ diff --git a/src/sflow/hsflowd/.gitignore b/src/sflow/hsflowd/.gitignore new file mode 100644 index 000000000000..d19db76ab9a9 --- /dev/null +++ b/src/sflow/hsflowd/.gitignore @@ -0,0 +1,4 @@ +* +!.gitignore +!Makefile +!patch/ diff --git a/src/sflow/hsflowd/Makefile b/src/sflow/hsflowd/Makefile index e3a930549f19..e29dbcc199bb 100644 --- a/src/sflow/hsflowd/Makefile +++ b/src/sflow/hsflowd/Makefile @@ -10,7 +10,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : git clone https://github.com/sflow/host-sflow pushd ./host-sflow - git checkout -b sflow tags/v2.0.26-3 + git checkout -b sflow tags/v$(HSFLOWD_VERSION)-$(HSFLOWD_SUBVERSION) # Apply patch series stg init @@ -21,7 +21,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : chmod u+x debian/rules sed -i -e s/_VERSION_/$(HSFLOWD_VERSION)-$(HSFLOWD_SUBVERSION)/g debian/changelog - dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) --buildinfo-option=-u. --changes-option=-u. + dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) --admindir $(SONIC_DPKG_ADMINDIR) --buildinfo-option=-u. --changes-option=-u. mv $(DERIVED_TARGET) $* $(DEST)/ popd diff --git a/src/sflow/psample/.gitignore b/src/sflow/psample/.gitignore new file mode 100644 index 000000000000..eec3a10fb01e --- /dev/null +++ b/src/sflow/psample/.gitignore @@ -0,0 +1,8 @@ +* +!.gitignore +!debian/changelog +!debian/compat +!debian/control +!debian/psample.install +!debian/rules +!Makefile diff --git a/src/sflow/psample/Makefile b/src/sflow/psample/Makefile index 3f03c249989a..bbdefde2289b 100644 --- a/src/sflow/psample/Makefile +++ b/src/sflow/psample/Makefile @@ -13,7 +13,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : pushd ./libpsample git checkout -b libpsample -f e48fad2 - dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) + dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) --admindir $(SONIC_DPKG_ADMINDIR) popd mv $* $(DEST)/ diff --git a/src/sflow/sflowtool/.gitignore b/src/sflow/sflowtool/.gitignore new file mode 100644 index 000000000000..138e705d63f0 --- /dev/null +++ b/src/sflow/sflowtool/.gitignore @@ -0,0 +1,8 @@ +* +!.gitignore +!debian/changelog +!debian/compat +!debian/control +!debian/sflowtool.install +!debian/rules +!Makefile diff --git a/src/sflow/sflowtool/Makefile b/src/sflow/sflowtool/Makefile index 10a3f2d24dea..5f2ad995a585 100644 --- a/src/sflow/sflowtool/Makefile +++ b/src/sflow/sflowtool/Makefile @@ -12,7 +12,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : pushd ./sflowtool git checkout -b sflowtool -f 6c2963b - dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) + dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) --admindir $(SONIC_DPKG_ADMINDIR) popd mv $* $(DEST)/ diff --git a/src/smartmontools/.gitignore b/src/smartmontools/.gitignore new file mode 100644 index 000000000000..a0991ff4402b --- /dev/null +++ b/src/smartmontools/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!Makefile diff --git a/src/smartmontools/Makefile b/src/smartmontools/Makefile index 4ac3d6ac315e..8f0f0695659f 100644 --- a/src/smartmontools/Makefile +++ b/src/smartmontools/Makefile @@ -13,7 +13,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : dpkg-source -x smartmontools_$(SMARTMONTOOLS_VERSION_FULL).dsc pushd smartmontools-$(SMARTMONTOOLS_VERSION_MAJOR) - dpkg-buildpackage -us -uc -b -j$(SONIC_CONFIG_MAKE_JOBS) + dpkg-buildpackage -us -uc -b -j$(SONIC_CONFIG_MAKE_JOBS) --admindir $(SONIC_DPKG_ADMINDIR) popd mv $* $(DEST)/ diff --git a/src/snmpd/.gitignore b/src/snmpd/.gitignore new file mode 100644 index 000000000000..a0991ff4402b --- /dev/null +++ b/src/snmpd/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!Makefile diff --git a/src/snmpd/Makefile b/src/snmpd/Makefile index 77084594d8ba..2e0ac828169c 100644 --- a/src/snmpd/Makefile +++ b/src/snmpd/Makefile @@ -12,17 +12,13 @@ DERIVED_TARGETS = snmptrapd_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb \ libsnmp30-dbg_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb \ libsnmp-dev_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb \ libsnmp-perl_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb \ - python-netsnmp_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb \ tkmib_$(SNMPD_VERSION_FULL)_all.deb $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : rm -rf net-snmp-$(SNMPD_VERSION) # download debian net-snmp - wget -NO net-snmp_$(SNMPD_VERSION_FULL).dsc "https://sonicstorage.blob.core.windows.net/packages/net-snmp_5.7.3+dfsg-1.5.dsc?sv=2015-04-05&sr=b&sig=vDAYAKlwi7JjF%2FesdJUyf4VIEXPsCfLhqqTqNr75zBs%3D&se=2030-10-12T13%3A59%3A45Z&sp=r" - wget -NO net-snmp_$(SNMPD_VERSION).orig.tar.xz "https://sonicstorage.blob.core.windows.net/packages/net-snmp_5.7.3+dfsg.orig.tar.xz?sv=2015-04-05&sr=b&sig=UjIh%2FTcHrIEzEV7a%2BV2ZP4ks3xHlAA3wqyxkyV7Ms8I%3D&se=2030-10-12T13%3A58%3A19Z&sp=r" - wget -NO net-snmp_$(SNMPD_VERSION_FULL).debian.tar.xz "https://sonicstorage.blob.core.windows.net/packages/net-snmp_5.7.3+dfsg-1.5.debian.tar.xz?sv=2015-04-05&sr=b&sig=xJkmxjtKXYcPe4yR%2FuCA0TXUfT40rj4XUMBaiK9CjsA%3D&se=2030-10-12T14%3A00%3A15Z&sp=r" - dpkg-source -x net-snmp_$(SNMPD_VERSION_FULL).dsc + dget -u https://sonicstorage.blob.core.windows.net/debian/pool/main/n/net-snmp/net-snmp_$(SNMPD_VERSION_FULL).dsc pushd net-snmp-$(SNMPD_VERSION) git init @@ -33,7 +29,11 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : stg init stg import -s ../patch-$(SNMPD_VERSION)/series - fakeroot debian/rules -j$(SONIC_CONFIG_MAKE_JOBS) binary +ifeq ($(CONFIGURED_ARCH), arm64) + dpkg-buildpackage -rfakeroot -b -d -us -uc -j1 --admindir $(SONIC_DPKG_ADMINDIR) +else + dpkg-buildpackage -rfakeroot -b -d -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) --admindir $(SONIC_DPKG_ADMINDIR) +endif popd mv $(DERIVED_TARGETS) $* $(DEST)/ diff --git a/src/snmpd/patch-5.7.3+dfsg/0005-Port-OpenSSL-1.1.0-with-support-for-1.0.2.patch b/src/snmpd/patch-5.7.3+dfsg/0005-Port-OpenSSL-1.1.0-with-support-for-1.0.2.patch deleted file mode 100644 index b4a5e4a351dd..000000000000 --- a/src/snmpd/patch-5.7.3+dfsg/0005-Port-OpenSSL-1.1.0-with-support-for-1.0.2.patch +++ /dev/null @@ -1,184 +0,0 @@ -From: Andreas Henriksson -Date: Sat, 23 Dec 2017 22:25:41 +0000 -Subject: [PATCH] Port OpenSSL 1.1.0 with support for 1.0.2 - -Initial support for OpenSSL 1.1.0 - -Changes by sebastian@breakpoint.cc: -- added OpenSSL 1.0.2 glue layer for backwarts compatibility -- dropped HAVE_EVP_MD_CTX_CREATE + DESTROY and added a check for OpenSSL - version instead (and currently 1.0.2 is the only one supported). - -BTS: https://bugs.debian.org/828449 -Signed-off-by: Sebastian Andrzej Siewior ---- - apps/snmpusm.c | 43 ++++++++++++++++++++++++++++++++++++------- - configure.d/config_os_libs2 | 6 ------ - snmplib/keytools.c | 13 ++++++------- - snmplib/scapi.c | 17 +++++------------ - 4 files changed, 47 insertions(+), 32 deletions(-) - ---- a/apps/snmpusm.c -+++ b/apps/snmpusm.c -@@ -183,6 +183,31 @@ setup_oid(oid * it, size_t * len, u_char - } - - #if defined(HAVE_OPENSSL_DH_H) && defined(HAVE_LIBCRYPTO) -+ -+#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) -+ -+static void DH_get0_pqg(const DH *dh, -+ const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) -+{ -+ if (p != NULL) -+ *p = dh->p; -+ if (q != NULL) -+ *q = dh->q; -+ if (g != NULL) -+ *g = dh->g; -+} -+ -+static void DH_get0_key(const DH *dh, const BIGNUM **pub_key, -+ const BIGNUM **priv_key) -+{ -+ if (pub_key != NULL) -+ *pub_key = dh->pub_key; -+ if (priv_key != NULL) -+ *priv_key = dh->priv_key; -+} -+ -+#endif -+ - int - get_USM_DH_key(netsnmp_variable_list *vars, netsnmp_variable_list *dhvar, - size_t outkey_len, -@@ -190,7 +215,7 @@ get_USM_DH_key(netsnmp_variable_list *va - oid *keyoid, size_t keyoid_len) { - u_char *dhkeychange; - DH *dh; -- BIGNUM *other_pub; -+ const BIGNUM *p, *g, *pub_key, *other_pub; - u_char *key; - size_t key_len; - -@@ -205,25 +230,29 @@ get_USM_DH_key(netsnmp_variable_list *va - dh = d2i_DHparams(NULL, &cp, dhvar->val_len); - } - -- if (!dh || !dh->g || !dh->p) { -+ if (dh) -+ DH_get0_pqg(dh, &p, NULL, &g); -+ -+ if (!dh || !g || !p) { - SNMP_FREE(dhkeychange); - return SNMPERR_GENERR; - } - -- DH_generate_key(dh); -- if (!dh->pub_key) { -+ if (!DH_generate_key(dh)) { - SNMP_FREE(dhkeychange); - return SNMPERR_GENERR; - } - -- if (vars->val_len != (unsigned int)BN_num_bytes(dh->pub_key)) { -+ DH_get0_key(dh, &pub_key, NULL); -+ -+ if (vars->val_len != (unsigned int)BN_num_bytes(pub_key)) { - SNMP_FREE(dhkeychange); - fprintf(stderr,"incorrect diffie-helman lengths (%lu != %d)\n", -- (unsigned long)vars->val_len, BN_num_bytes(dh->pub_key)); -+ (unsigned long)vars->val_len, BN_num_bytes(pub_key)); - return SNMPERR_GENERR; - } - -- BN_bn2bin(dh->pub_key, dhkeychange + vars->val_len); -+ BN_bn2bin(pub_key, dhkeychange + vars->val_len); - - key_len = DH_size(dh); - if (!key_len) { ---- a/configure.d/config_os_libs2 -+++ b/configure.d/config_os_libs2 -@@ -291,12 +291,6 @@ if test "x$tryopenssl" != "xno" -a "x$tr - AC_CHECK_LIB(${CRYPTO}, AES_cfb128_encrypt, - AC_DEFINE(HAVE_AES_CFB128_ENCRYPT, 1, - [Define to 1 if you have the `AES_cfb128_encrypt' function.])) -- -- AC_CHECK_LIB(${CRYPTO}, EVP_MD_CTX_create, -- AC_DEFINE([HAVE_EVP_MD_CTX_CREATE], [], -- [Define to 1 if you have the `EVP_MD_CTX_create' function.]) -- AC_DEFINE([HAVE_EVP_MD_CTX_DESTROY], [], -- [Define to 1 if you have the `EVP_MD_CTX_destroy' function.])) - fi - if echo " $transport_result_list " | $GREP "DTLS" > /dev/null; then - AC_CHECK_LIB(ssl, DTLSv1_method, ---- a/snmplib/keytools.c -+++ b/snmplib/keytools.c -@@ -149,13 +149,13 @@ generate_Ku(const oid * hashtype, u_int - */ - #ifdef NETSNMP_USE_OPENSSL - --#ifdef HAVE_EVP_MD_CTX_CREATE -+#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) - ctx = EVP_MD_CTX_create(); - #else -- ctx = malloc(sizeof(*ctx)); -- if (!EVP_MD_CTX_init(ctx)) -- return SNMPERR_GENERR; -+ ctx = EVP_MD_CTX_new(); - #endif -+ if (!ctx) -+ return SNMPERR_GENERR; - #ifndef NETSNMP_DISABLE_MD5 - if (ISTRANSFORM(hashtype, HMACMD5Auth)) { - if (!EVP_DigestInit(ctx, EVP_md5())) -@@ -259,11 +259,10 @@ generate_Ku(const oid * hashtype, u_int - memset(buf, 0, sizeof(buf)); - #ifdef NETSNMP_USE_OPENSSL - if (ctx) { --#ifdef HAVE_EVP_MD_CTX_DESTROY -+#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) - EVP_MD_CTX_destroy(ctx); - #else -- EVP_MD_CTX_cleanup(ctx); -- free(ctx); -+ EVP_MD_CTX_free(ctx); - #endif - } - #endif ---- a/snmplib/scapi.c -+++ b/snmplib/scapi.c -@@ -486,15 +486,10 @@ sc_hash(const oid * hashtype, size_t has - } - - /** initialize the pointer */ --#ifdef HAVE_EVP_MD_CTX_CREATE -+#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) - cptr = EVP_MD_CTX_create(); - #else -- cptr = malloc(sizeof(*cptr)); --#if defined(OLD_DES) -- memset(cptr, 0, sizeof(*cptr)); --#else -- EVP_MD_CTX_init(cptr); --#endif -+ cptr = EVP_MD_CTX_new(); - #endif - if (!EVP_DigestInit(cptr, hashfn)) { - /* requested hash function is not available */ -@@ -507,13 +502,11 @@ sc_hash(const oid * hashtype, size_t has - /** do the final pass */ - EVP_DigestFinal(cptr, MAC, &tmp_len); - *MAC_len = tmp_len; --#ifdef HAVE_EVP_MD_CTX_DESTROY -+ -+#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) - EVP_MD_CTX_destroy(cptr); - #else --#if !defined(OLD_DES) -- EVP_MD_CTX_cleanup(cptr); --#endif -- free(cptr); -+ EVP_MD_CTX_free(cptr); - #endif - return (rval); diff --git a/src/snmpd/patch-5.7.3+dfsg/0008-Enable-macro-DEB_BUILD_ARCH_OS-in-order-to-build-ipv.patch b/src/snmpd/patch-5.7.3+dfsg/0008-Enable-macro-DEB_BUILD_ARCH_OS-in-order-to-build-ipv.patch index f3e878077ff5..c41b5b5a6638 100644 --- a/src/snmpd/patch-5.7.3+dfsg/0008-Enable-macro-DEB_BUILD_ARCH_OS-in-order-to-build-ipv.patch +++ b/src/snmpd/patch-5.7.3+dfsg/0008-Enable-macro-DEB_BUILD_ARCH_OS-in-order-to-build-ipv.patch @@ -11,14 +11,12 @@ diff --git a/debian/rules b/debian/rules index 4c3b5b6..1fab6a4 100755 --- a/debian/rules +++ b/debian/rules -@@ -5,6 +5,7 @@ - # without -pie build fails during perl module build somehow... - export DEB_BUILD_MAINT_OPTIONS := hardening=+all,-pie +@@ -4,4 +4,5 @@ + export DEB_BUILD_MAINT_OPTIONS := hardening=+all DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) +DEB_BUILD_ARCH_OS ?= $(shell dpkg-architecture -qDEB_BUILD_ARCH_OS) LIB_VERSION = 30 - UPSTREAM_VERSION = $(shell dpkg-parsechangelog | egrep '^Version:' | cut -f 2 -d ':' | sed 's/ //' | sed 's/~dfsg.*$$//') -- 2.18.0 diff --git a/src/snmpd/patch-5.7.3+dfsg/series b/src/snmpd/patch-5.7.3+dfsg/series index 428a81eb6b22..31b251845dea 100644 --- a/src/snmpd/patch-5.7.3+dfsg/series +++ b/src/snmpd/patch-5.7.3+dfsg/series @@ -1,7 +1,5 @@ 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 -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 0008-Enable-macro-DEB_BUILD_ARCH_OS-in-order-to-build-ipv.patch diff --git a/src/socat/.gitignore b/src/socat/.gitignore new file mode 100644 index 000000000000..d19db76ab9a9 --- /dev/null +++ b/src/socat/.gitignore @@ -0,0 +1,4 @@ +* +!.gitignore +!Makefile +!patch/ diff --git a/src/socat/Makefile b/src/socat/Makefile index 50c2c8d96d2d..cc2cd7238684 100644 --- a/src/socat/Makefile +++ b/src/socat/Makefile @@ -18,7 +18,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : # Build source and Debian packages pushd socat-1.7.3.1 patch -p0 < ../enable_readline.patch - dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) + dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) --admindir $(SONIC_DPKG_ADMINDIR) popd # Move the newly-built .deb packages to the destination directory diff --git a/src/sonic-bgpcfgd/.gitignore b/src/sonic-bgpcfgd/.gitignore new file mode 100644 index 000000000000..7611d6274601 --- /dev/null +++ b/src/sonic-bgpcfgd/.gitignore @@ -0,0 +1,12 @@ +.eggs/ +build/ +dist/ +*.egg-info/ +bgpcfgd/*.pyc +tests/*.pyc +tests/__pycache__/ +.idea +.coverage +bgpcfgd/__pycache__/ +venv +tests/.coverage* diff --git a/src/sonic-bgpcfgd/bgpcfgd/__init__.py b/src/sonic-bgpcfgd/bgpcfgd/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/src/sonic-bgpcfgd/bgpcfgd/__main__.py b/src/sonic-bgpcfgd/bgpcfgd/__main__.py new file mode 100644 index 000000000000..413eeee346d0 --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/__main__.py @@ -0,0 +1,4 @@ +from .main import main + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/src/sonic-bgpcfgd/bgpcfgd/config.py b/src/sonic-bgpcfgd/bgpcfgd/config.py new file mode 100644 index 000000000000..bba45133c9df --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/config.py @@ -0,0 +1,114 @@ +class ConfigMgr(object): + """ The class represents frr configuration """ + def __init__(self, frr): + self.frr = frr + self.current_config = None + self.current_config_raw = None + self.changes = "" + self.peer_groups_to_restart = [] + + def reset(self): + """ Reset stored config """ + self.current_config = None + self.current_config_raw = None + self.changes = "" + self.peer_groups_to_restart = [] + + def update(self): + """ Read current config from FRR """ + self.current_config = None + self.current_config_raw = None + out = self.frr.get_config() + text = [] + for line in out.split('\n'): + if line.lstrip().startswith('!'): + continue + text.append(line) + text += [" "] # Add empty line to have something to work on, if there is no text + self.current_config_raw = text + self.current_config = self.to_canonical(out) # FIXME: use text as an input + + def push_list(self, cmdlist): + """ + Prepare new changes for FRR. The changes should be committed by self.commit() + :param cmdlist: configuration change for FRR. Type: List of Strings + """ + self.changes += "\n".join(cmdlist) + "\n" + + def push(self, cmd): + """ + Prepare new changes for FRR. The changes should be committed by self.commit() + :param cmd: configuration change for FRR. Type: String + """ + self.changes += cmd + "\n" + return True + + def restart_peer_groups(self, peer_groups): + """ + Schedule peer_groups for restart on commit + :param peer_groups: List of peer_groups + """ + self.peer_groups_to_restart.extend(peer_groups) + + def commit(self): + """ + Write configuration change to FRR. + :return: True if change was applied successfully, False otherwise + """ + if self.changes.strip() == "": + return True + rc_write = self.frr.write(self.changes) + rc_restart = self.frr.restart_peer_groups(self.peer_groups_to_restart) + self.reset() + return rc_write and rc_restart + + def get_text(self): + return self.current_config_raw + + @staticmethod + def to_canonical(raw_config): + """ + Convert FRR config into canonical format + :param raw_config: config in frr format + :return: frr config in canonical format + """ + parsed_config = [] + lines_with_comments = raw_config.split("\n") + lines = [line for line in lines_with_comments + if not line.strip().startswith('!') and line.strip() != ''] + if len(lines) == 0: + return [] + cur_path = [lines[0]] + cur_offset = ConfigMgr.count_spaces(lines[0]) + for line in lines: + n_spaces = ConfigMgr.count_spaces(line) + s_line = line.strip() + if n_spaces == cur_offset: + cur_path[-1] = s_line + elif n_spaces > cur_offset: + cur_path.append(s_line) + elif n_spaces < cur_offset: + cur_path = cur_path[:-2] + cur_path.append(s_line) + parsed_config.append(cur_path[:]) + cur_offset = n_spaces + return parsed_config + + @staticmethod + def count_spaces(line): + """ Count leading spaces in the line """ + return len(line) - len(line.lstrip()) + + @staticmethod + def from_canonical(canonical_config): + """ + Convert config from canonical format into FRR raw format + :param canonical_config: config in a canonical format + :return: config in the FRR raw format + """ + out = "" + for lines in canonical_config: + spaces = len(lines) - 1 + out += " " * spaces + lines[-1] + "\n" + + return out \ No newline at end of file diff --git a/src/sonic-bgpcfgd/bgpcfgd/directory.py b/src/sonic-bgpcfgd/bgpcfgd/directory.py new file mode 100644 index 000000000000..d2dfc915c037 --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/directory.py @@ -0,0 +1,159 @@ +from collections import defaultdict + +from .log import log_err + + +class Directory(object): + """ This class stores values and notifies callbacks which were registered to be executed as soon + as some value is changed. This class works as DB cache mostly """ + def __init__(self): + self.data = defaultdict(dict) # storage. A key is a slot name, a value is a dictionary with data + self.notify = defaultdict(lambda: defaultdict(list)) # registered callbacks: slot -> path -> handlers[] + + @staticmethod + def get_slot_name(db, table): + """ Convert db, table pair into a slot name """ + return db + "__" + table + + def path_traverse(self, slot, path): + """ + Traverse a path in the storage. + If the path is an empty string, it returns a value as it is. + If the path is not an empty string, the method will traverse through the dictionary value. + Example: + self.data["key_1"] = { "abc": { "cde": { "fgh": "val_1", "ijk": "val_2" } } } + self.path_traverse("key_1", "abc/cde") will return True, { "fgh": "val_1", "ijk": "val_2" } + :param slot: storage key + :param path: storage path as a string where each internal key is separated by '/' + :return: a pair: True if the path was found, object if it was found + """ + if slot not in self.data: + return False, None + elif path == '': + return True, self.data[slot] + d = self.data[slot] + for p in path.split("/"): + if p not in d: + return False, None + d = d[p] + return True, d + + def path_exist(self, db, table, path): + """ + Check if the path exists in the storage + :param db: db name + :param table: table name + :param path: requested path + :return: True if the path is available, False otherwise + """ + slot = self.get_slot_name(db, table) + return self.path_traverse(slot, path)[0] + + def get_path(self, db, table, path): + """ + Return the requested path from the storage + :param db: db name + :param table: table name + :param path: requested path + :return: object if the path was found, None otherwise + """ + slot = self.get_slot_name(db, table) + return self.path_traverse(slot, path)[1] + + def put(self, db, table, key, value): + """ + Put information into the storage. Notify handlers which are dependant to the information + :param db: db name + :param table: table name + :param key: key to change + :param value: value to put + :return: + """ + slot = self.get_slot_name(db, table) + self.data[slot][key] = value + if slot in self.notify: + for path in self.notify[slot].keys(): + if self.path_exist(db, table, path): + for handler in self.notify[slot][path]: + handler() + + def get(self, db, table, key): + """ + Get a value from the storage + :param db: db name + :param table: table name + :param key: ket to get + :return: value for the key + """ + slot = self.get_slot_name(db, table) + return self.data[slot][key] + + def get_slot(self, db, table): + """ + Get an object from the storage + :param db: db name + :param table: table name + :return: object for the slot + """ + slot = self.get_slot_name(db, table) + return self.data[slot] + + def remove(self, db, table, key): + """ + Remove a value from the storage + :param db: db name + :param table: table name + :param key: key to remove + """ + slot = self.get_slot_name(db, table) + if slot in self.data: + if key in self.data[slot]: + del self.data[slot][key] + else: + log_err("Directory: Can't remove key '%s' from slot '%s'. The key doesn't exist" % (key, slot)) + else: + log_err("Directory: Can't remove key '%s' from slot '%s'. The slot doesn't exist" % (key, slot)) + + def remove_slot(self, db, table): + """ + Remove an object from the storage + :param db: db name + :param table: table name + """ + slot = self.get_slot_name(db, table) + if slot in self.data: + del self.data[slot] + else: + log_err("Directory: Can't remove slot '%s'. The slot doesn't exist" % slot) + + def available(self, db, table): + """ + Check if the table is available + :param db: db name + :param table: table name + :return: True if the slot is available, False if not + """ + slot = self.get_slot_name(db, table) + return slot in self.data + + def available_deps(self, deps): + """ + Check if all items from the deps list is available in the storage + :param deps: list of dependencies + :return: True if all dependencies are presented, False otherwise + """ + res = True + for db, table, path in deps: + res = res and self.path_exist(db, table, path) + return res + + def subscribe(self, deps, handler): + """ + Subscribe the handler to be run as soon as all dependencies are presented + :param deps: + :param handler: + :return: + """ + for db, table, path in deps: + slot = self.get_slot_name(db, table) + self.notify[slot][path].append(handler) \ No newline at end of file diff --git a/src/sonic-bgpcfgd/bgpcfgd/frr.py b/src/sonic-bgpcfgd/bgpcfgd/frr.py new file mode 100644 index 000000000000..6b88e5ee47f5 --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/frr.py @@ -0,0 +1,70 @@ +import os +import datetime +import time +import tempfile + +from bgpcfgd.log import log_err, log_info, log_warn, log_crit +from .vars import g_debug +from .utils import run_command + + +class FRR(object): + """Proxy object with FRR""" + def __init__(self, daemons): + self.daemons = daemons + + def wait_for_daemons(self, seconds): + """ + Wait until FRR daemons are ready for requests + :param seconds: number of seconds to wait, until raise an error + """ + stop_time = datetime.datetime.now() + datetime.timedelta(seconds=seconds) + log_info("Start waiting for FRR daemons: %s" % str(datetime.datetime.now())) + while datetime.datetime.now() < stop_time: + ret_code, out, err = run_command(["vtysh", "-c", "show daemons"], hide_errors=True) + if ret_code == 0 and all(daemon in out for daemon in self.daemons): + log_info("All required daemons have connected to vtysh: %s" % str(datetime.datetime.now())) + return + else: + log_warn("Can't read daemon status from FRR: %s" % str(err)) + time.sleep(0.1) # sleep 100 ms + raise RuntimeError("FRR daemons hasn't been started in %d seconds" % seconds) + + @staticmethod + def get_config(): + ret_code, out, err = run_command(["vtysh", "-c", "show running-config"]) + if ret_code != 0: + log_crit("can't update running config: rc=%d out='%s' err='%s'" % (ret_code, out, err)) + return "" + return out + + @staticmethod + def write(config_text): + fd, tmp_filename = tempfile.mkstemp(dir='/tmp') + os.close(fd) + with open(tmp_filename, 'w') as fp: + fp.write("%s\n" % config_text) + command = ["vtysh", "-f", tmp_filename] + ret_code, out, err = run_command(command) + if ret_code != 0: + err_tuple = tmp_filename, ret_code, out, err + log_err("ConfigMgr::commit(): can't push configuration from file='%s', rc='%d', stdout='%s', stderr='%s'" % err_tuple) + else: + if not g_debug: + os.remove(tmp_filename) + return ret_code == 0 + + @staticmethod + def restart_peer_groups(peer_groups): + """ Restart peer-groups which support BBR + :param peer_groups: List of peer_groups to restart + :return: True if restart of all peer-groups was successful, False otherwise + """ + res = True + for peer_group in sorted(peer_groups): + rc, out, err = run_command(["vtysh", "-c", "clear bgp peer-group %s soft in" % peer_group]) + if rc != 0: + log_value = peer_group, rc, out, err + log_crit("Can't restart bgp peer-group '%s'. rc='%d', out='%s', err='%s'" % log_value) + res = res and (rc == 0) + return res diff --git a/src/sonic-bgpcfgd/bgpcfgd/log.py b/src/sonic-bgpcfgd/bgpcfgd/log.py new file mode 100644 index 000000000000..4083b13aa6ad --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/log.py @@ -0,0 +1,33 @@ +import syslog + +from .vars import g_debug + +def log_debug(msg): + """ Send a message msg to the syslog as DEBUG """ + if g_debug: + syslog.syslog(syslog.LOG_DEBUG, msg) + + +def log_notice(msg): + """ Send a message msg to the syslog as NOTICE """ + syslog.syslog(syslog.LOG_NOTICE, msg) + + +def log_info(msg): + """ Send a message msg to the syslog as INFO """ + syslog.syslog(syslog.LOG_INFO, msg) + + +def log_warn(msg): + """ Send a message msg to the syslog as WARNING """ + syslog.syslog(syslog.LOG_WARNING, msg) + + +def log_err(msg): + """ Send a message msg to the syslog as ERR """ + syslog.syslog(syslog.LOG_ERR, msg) + + +def log_crit(msg): + """ Send a message msg to the syslog as CRIT """ + syslog.syslog(syslog.LOG_CRIT, msg) \ No newline at end of file diff --git a/src/sonic-bgpcfgd/bgpcfgd/main.py b/src/sonic-bgpcfgd/bgpcfgd/main.py new file mode 100644 index 000000000000..360b54dc11aa --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/main.py @@ -0,0 +1,87 @@ +import os +import signal +import sys +import syslog +import traceback + +from swsscommon import swsscommon + +from .config import ConfigMgr +from .directory import Directory +from .log import log_notice, log_crit +from .managers_allow_list import BGPAllowListMgr +from .managers_bbr import BBRMgr +from .managers_bgp import BGPPeerMgrBase +from .managers_db import BGPDataBaseMgr +from .managers_intf import InterfaceMgr +from .managers_setsrc import ZebraSetSrc +from .runner import Runner, signal_handler +from .template import TemplateFabric +from .utils import read_constants +from .frr import FRR +from .vars import g_debug + + +def do_work(): + """ Main function """ + frr = FRR(["bgpd", "zebra", "staticd"]) + frr.wait_for_daemons(seconds=20) + # + common_objs = { + 'directory': Directory(), + 'cfg_mgr': ConfigMgr(frr), + 'tf': TemplateFabric(), + 'constants': read_constants(), + } + managers = [ + # Config DB managers + BGPDataBaseMgr(common_objs, "CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME), + BGPDataBaseMgr(common_objs, "CONFIG_DB", swsscommon.CFG_DEVICE_NEIGHBOR_METADATA_TABLE_NAME), + # Interface managers + InterfaceMgr(common_objs, "CONFIG_DB", swsscommon.CFG_INTF_TABLE_NAME), + InterfaceMgr(common_objs, "CONFIG_DB", swsscommon.CFG_LOOPBACK_INTERFACE_TABLE_NAME), + InterfaceMgr(common_objs, "CONFIG_DB", swsscommon.CFG_VLAN_INTF_TABLE_NAME), + InterfaceMgr(common_objs, "CONFIG_DB", swsscommon.CFG_LAG_INTF_TABLE_NAME), + # State DB managers + ZebraSetSrc(common_objs, "STATE_DB", swsscommon.STATE_INTERFACE_TABLE_NAME), + # Peer Managers + BGPPeerMgrBase(common_objs, "CONFIG_DB", swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME, "general", True), + BGPPeerMgrBase(common_objs, "CONFIG_DB", swsscommon.CFG_BGP_INTERNAL_NEIGHBOR_TABLE_NAME, "internal", False), + BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_MONITORS", "monitors", False), + BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_PEER_RANGE", "dynamic", False), + # AllowList Managers + BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES"), + # BBR Manager + BBRMgr(common_objs, "CONFIG_DB", "BGP_BBR"), + ] + runner = Runner(common_objs['cfg_mgr']) + for mgr in managers: + runner.add_manager(mgr) + runner.run() + + +def main(): + rc = 0 + try: + syslog.openlog('bgpcfgd') + signal.signal(signal.SIGTERM, signal_handler) + signal.signal(signal.SIGINT, signal_handler) + do_work() + except KeyboardInterrupt: + log_notice("Keyboard interrupt") + except RuntimeError as exc: + log_crit(str(exc)) + rc = -2 + if g_debug: + raise + except Exception as exc: + log_crit("Got an exception %s: Traceback: %s" % (str(exc), traceback.format_exc())) + rc = -1 + if g_debug: + raise + finally: + syslog.closelog() + try: + sys.exit(rc) + except SystemExit: + os._exit(rc) diff --git a/src/sonic-bgpcfgd/bgpcfgd/manager.py b/src/sonic-bgpcfgd/bgpcfgd/manager.py new file mode 100644 index 000000000000..6966a20f4b35 --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/manager.py @@ -0,0 +1,71 @@ +from swsscommon import swsscommon + +from .log import log_debug, log_err + + +class Manager(object): + """ This class represents a SONiC DB table """ + def __init__(self, common_objs, deps, database, table_name): + """ + Initialize class + :param common_objs: common object dictionary + :param deps: dependencies list + :param database: database name + :param table_name: table name + """ + self.directory = common_objs['directory'] + self.cfg_mgr = common_objs['cfg_mgr'] + self.constants = common_objs['constants'] + self.deps = deps + self.db_name = database + self.table_name = table_name + self.set_queue = [] + self.directory.subscribe(deps, self.on_deps_change) # subscribe this class method on directory changes + + def get_database(self): + """ Return associated database """ + return self.db_name + + def get_table_name(self): + """ Return associated table name""" + return self.table_name + + def handler(self, key, op, data): + """ + This method is executed on each add/remove event on the table. + :param key: key of the table entry + :param op: operation on the table entry. Could be either 'SET' or 'DEL' + :param data: associated data of the event. Empty for 'DEL' operation. + """ + if op == swsscommon.SET_COMMAND: + if self.directory.available_deps(self.deps): # all required dependencies are set in the Directory? + res = self.set_handler(key, data) + if not res: # set handler returned False, which means it is not ready to process is. Save it for later. + log_debug("'SET' handler returned NOT_READY for the Manager: %s" % self.__class__) + self.set_queue.append((key, data)) + else: + log_debug("Not all dependencies are met for the Manager: %s" % self.__class__) + self.set_queue.append((key, data)) + elif op == swsscommon.DEL_COMMAND: + self.del_handler(key) + else: + log_err("Invalid operation '%s' for key '%s'" % (op, key)) + + def on_deps_change(self): + """ This method is being executed on every dependency change """ + if not self.directory.available_deps(self.deps): + return + new_queue = [] + for key, data in self.set_queue: + res = self.set_handler(key, data) + if not res: + new_queue.append((key, data)) + self.set_queue = new_queue + + def set_handler(self, key, data): + """ Placeholder for 'SET' command """ + log_err("set_handler() wasn't implemented for %s" % self.__class__.__name__) + + def del_handler(self, key): + """ Placeholder for 'DEL' command """ + log_err("del_handler wasn't implemented for %s" % self.__class__.__name__) \ No newline at end of file diff --git a/src/sonic-bgpcfgd/bgpcfgd/managers_allow_list.py b/src/sonic-bgpcfgd/bgpcfgd/managers_allow_list.py new file mode 100644 index 000000000000..435be91d20d2 --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/managers_allow_list.py @@ -0,0 +1,703 @@ +""" +Implementation of "allow-list" feature +""" +import re + +from .log import log_debug, log_info, log_err, log_warn +from .template import TemplateFabric +from .manager import Manager + + +class BGPAllowListMgr(Manager): + """ This class initialize "AllowList" settings """ + ALLOW_ADDRESS_PL_NAME_TMPL = "ALLOW_ADDRESS_%d_%s" # template for a name for the ALLOW_ADDRESS prefix-list ??? + EMPTY_COMMUNITY = "empty" + PL_NAME_TMPL = "PL_ALLOW_LIST_DEPLOYMENT_ID_%d_COMMUNITY_%s_V%s" + COMMUNITY_NAME_TMPL = "COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_%d_COMMUNITY_%s" + RM_NAME_TMPL = "ALLOW_LIST_DEPLOYMENT_ID_%d_V%s" + ROUTE_MAP_ENTRY_WITH_COMMUNITY_START = 10 + ROUTE_MAP_ENTRY_WITH_COMMUNITY_END = 29990 + ROUTE_MAP_ENTRY_WITHOUT_COMMUNITY_START = 30000 + ROUTE_MAP_ENTRY_WITHOUT_COMMUNITY_END = 65530 + + V4 = "v4" # constant for af enum: V4 + V6 = "v6" # constant for af enum: V6 + + def __init__(self, common_objs, db, table): + """ + Initialize the object + :param common_objs: common object dictionary + :param db: name of the db + :param table: name of the table in the db + """ + super(BGPAllowListMgr, self).__init__( + common_objs, + [], + db, + table, + ) + self.key_re = re.compile(r"^DEPLOYMENT_ID\|\d+\|\S+$|^DEPLOYMENT_ID\|\d+$") + self.enabled = self.__get_enabled() + self.__load_constant_lists() + + def set_handler(self, key, data): + """ + Manager method which runs on receiving 'SET' message + :param key: ket of the 'SET' message + :param data: data of the 'SET' message + :return: True if the message was executed, False - the message should be postponed. + """ + if not self.enabled: + log_warn("BGPAllowListMgr::Received 'SET' command, but this feature is disabled in constants") + return True + if not self.__set_handler_validate(key, data): + return True + key = key.replace("DEPLOYMENT_ID|", "") + deployment_id, community_value = key.split('|', 1) if '|' in key else (key, BGPAllowListMgr.EMPTY_COMMUNITY) + deployment_id = int(deployment_id) + prefixes_v4 = [] + prefixes_v6 = [] + if "prefixes_v4" in data: + prefixes_v4 = str(data['prefixes_v4']).split(",") + if "prefixes_v6" in data: + prefixes_v6 = str(data['prefixes_v6']).split(",") + default_action_community = self.__get_default_action_community(data) + self.__update_policy(deployment_id, community_value, prefixes_v4, prefixes_v6, default_action_community) + return True + + def __set_handler_validate(self, key, data): + """ + Validate parameters of a "Set" message + :param key: ket of the 'SET' message + :param data: data of the 'SET' message + :return: True if parameters are valid, False if parameters are invalid + """ + if data is None: + log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message without data") + return False + if not self.key_re.match(key): + log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message with invalid key: '%s'" % key) + return False + prefixes_v4 = [] + prefixes_v6 = [] + if "prefixes_v4" in data: + prefixes_v4 = str(data["prefixes_v4"]).split(",") + if not all(TemplateFabric.is_ipv4(prefix) for prefix in prefixes_v4): + arguments = "prefixes_v4", str(data["prefixes_v4"]) + log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message with invalid input[%s]:'%s'" % arguments) + return False + if "prefixes_v6" in data: + prefixes_v6 = str(data["prefixes_v6"]).split(",") + if not all(TemplateFabric.is_ipv6(prefix) for prefix in prefixes_v6): + arguments = "prefixes_v6", str(data["prefixes_v6"]) + log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message with invalid input[%s]:'%s'" % arguments) + return False + if not prefixes_v4 and not prefixes_v6: + log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message with no prefixes specified: %s" % str(data)) + return False + if "default_action" in data and data["default_action"] != "permit" and data["default_action"] != "deny": + log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message with invalid 'default_action' field: '%s'" % str(data)) + return False + return True + + def del_handler(self, key): + """ + Manager method which runs on "DEL" message + :param key: a key of "DEL" message + """ + if not self.enabled: + log_warn("BGPAllowListMgr::Received 'DEL' command, but this feature is disabled in constants") + return + if not self.__del_handler_validate(key): + return + key = key.replace('DEPLOYMENT_ID|', '') + deployment_id, community = key.split('|', 1) if '|' in key else (key, BGPAllowListMgr.EMPTY_COMMUNITY) + deployment_id = int(deployment_id) + self.__remove_policy(deployment_id, community) + + def __del_handler_validate(self, key): + """ + Validate "DEL" method parameters + :param key: a key of "DEL" message + :return: True if parameters are valid, False if parameters are invalid + """ + if not self.key_re.match(key): + log_err("BGPAllowListMgr::Received BGP ALLOWED 'DEL' message with invalid key: '$s'" % key) + return False + return True + + def __update_policy(self, deployment_id, community_value, prefixes_v4, prefixes_v6, default_action): + """ + Update "allow list" policy with parameters + :param deployment_id: deployment id which policy will be changed + :param community_value: community value to match for the updated policy + :param prefixes_v4: a list of v4 prefixes for the updated policy + :param prefixes_v6: a list of v6 prefixes for the updated policy + :param default_action: the default action for the policy. should be either 'permit' or 'deny' + """ + # update all related entries with the information + info = deployment_id, community_value, str(prefixes_v4), str(prefixes_v6) + msg = "BGPAllowListMgr::Updating 'Allow list' policy." + msg += " deployment_id '%s'. community: '%s'" + msg += " prefix_v4 '%s'. prefix_v6: '%s'" + log_info(msg % info) + names = self.__generate_names(deployment_id, community_value) + self.cfg_mgr.update() + cmds = [] + cmds += self.__update_prefix_list(self.V4, names['pl_v4'], prefixes_v4) + cmds += self.__update_prefix_list(self.V6, names['pl_v6'], prefixes_v6) + cmds += self.__update_community(names['community'], community_value) + cmds += self.__update_allow_route_map_entry(self.V4, names['pl_v4'], names['community'], names['rm_v4']) + cmds += self.__update_allow_route_map_entry(self.V6, names['pl_v6'], names['community'], names['rm_v6']) + cmds += self.__update_default_route_map_entry(names['rm_v4'], default_action) + cmds += self.__update_default_route_map_entry(names['rm_v6'], default_action) + if cmds: + self.cfg_mgr.push_list(cmds) + peer_groups = self.__find_peer_group_by_deployment_id(deployment_id) + self.cfg_mgr.restart_peer_groups(peer_groups) + log_debug("BGPAllowListMgr::__update_policy. The peers configuration scheduled for updates") + else: + log_debug("BGPAllowListMgr::__update_policy. Nothing to update") + log_info("BGPAllowListMgr::Done") + + def __remove_policy(self, deployment_id, community_value): + """ + Remove "allow list" policy for given deployment_id and community_value + :param deployment_id: deployment id which policy will be removed + :param community_value: community value to match for the removed policy + """ + # remove all related entries from the configuration + # put default rule to the route-map + info = deployment_id, community_value + msg = "BGPAllowListMgr::Removing 'Allow list' policy." + msg += " deployment_id '%s'. community: '%s'" + log_info(msg % info) + + default_action = self.__get_default_action_community() + names = self.__generate_names(deployment_id, community_value) + self.cfg_mgr.update() + cmds = [] + cmds += self.__remove_allow_route_map_entry(self.V4, names['pl_v4'], names['community'], names['rm_v4']) + cmds += self.__remove_allow_route_map_entry(self.V6, names['pl_v6'], names['community'], names['rm_v6']) + cmds += self.__remove_prefix_list(self.V4, names['pl_v4']) + cmds += self.__remove_prefix_list(self.V6, names['pl_v6']) + cmds += self.__remove_community(names['community']) + cmds += self.__update_default_route_map_entry(names['rm_v4'], default_action) + cmds += self.__update_default_route_map_entry(names['rm_v6'], default_action) + if cmds: + self.cfg_mgr.push_list(cmds) + peer_groups = self.__find_peer_group_by_deployment_id(deployment_id) + self.cfg_mgr.restart_peer_groups(peer_groups) + log_debug("BGPAllowListMgr::__remove_policy. 'Allow list' policy was scheduled for removal") + else: + log_debug("BGPAllowListMgr::__remove_policy. Nothing to remove") + log_info('BGPAllowListMgr::Done') + + @staticmethod + def __generate_names(deployment_id, community_value): + """ + Generate prefix-list names for a given peer_ip and community value + :param deployment_id: deployment_id for which we're going to filter prefixes + :param community_value: community, which we want to use to filter prefixes + :return: a dictionary with names + """ + if community_value == BGPAllowListMgr.EMPTY_COMMUNITY: + community_name = BGPAllowListMgr.EMPTY_COMMUNITY + else: + community_name = BGPAllowListMgr.COMMUNITY_NAME_TMPL % (deployment_id, community_value) + names = { + "pl_v4": BGPAllowListMgr.PL_NAME_TMPL % (deployment_id, community_value, '4'), + "pl_v6": BGPAllowListMgr.PL_NAME_TMPL % (deployment_id, community_value, '6'), + "rm_v4": BGPAllowListMgr.RM_NAME_TMPL % (deployment_id, '4'), + "rm_v6": BGPAllowListMgr.RM_NAME_TMPL % (deployment_id, '6'), + "community": community_name, + } + arguments = deployment_id, community_value, str(names) + log_debug("BGPAllowListMgr::__generate_names. deployment_id: %d, community: %s. names: %s" % arguments) + return names + + def __update_prefix_list(self, af, pl_name, allow_list): + """ + Create or update a prefix-list with name pl_name. + :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list + :param pl_name: prefix-list name + :param allow_list: prefix-list entries + :return: True if updating was successful, False otherwise + """ + assert af == self.V4 or af == self.V6 + constant_list = self.__get_constant_list(af) + allow_list = self.__to_prefix_list(af, allow_list) + log_debug("BGPAllowListMgr::__update_prefix_list. af='%s' prefix-list name=%s" % (af, pl_name)) + exist, correct = self.__is_prefix_list_valid(af, pl_name, allow_list, constant_list) + if correct: + log_debug("BGPAllowListMgr::__update_prefix_list. the prefix-list '%s' exists and correct" % pl_name) + return [] + family = self.__af_to_family(af) + cmds = [] + seq_no = 10 + if exist: + cmds.append('no %s prefix-list %s' % (family, pl_name)) + for entry in constant_list + allow_list: + cmds.append('%s prefix-list %s seq %d %s' % (family, pl_name, seq_no, entry)) + seq_no += 10 + return cmds + + def __remove_prefix_list(self, af, pl_name): + """ + Remove prefix-list in the address-family af. + :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list + :param pl_name: list of prefix-list names + :return: True if operation was successful, False otherwise + """ + assert af == self.V4 or af == self.V6 + log_debug("BGPAllowListMgr::__remove_prefix_lists. af='%s' pl_names='%s'" % (af, pl_name)) + exist, _ = self.__is_prefix_list_valid(af, pl_name, [], []) + if not exist: + log_debug("BGPAllowListMgr::__remove_prefix_lists: prefix_list '%s' not found" % pl_name) + return [] + family = self.__af_to_family(af) + return ["no %s prefix-list %s" % (family, pl_name)] + + def __is_prefix_list_valid(self, af, pl_name, allow_list, constant_list): + """ + Check that a prefix list exists and it has valid entries + :param af: address family of the checked prefix-list + :param pl_name: prefix-list name + :param allow_list: a prefix-list which must be a part of the valid prefix list + :param constant_list: a constant list which must be on top of each "allow" prefix list on the device + :return: a tuple. The first element of the tuple has True if the prefix-list exists, False otherwise, + The second element of the tuple has True if the prefix-list contains correct entries, False if not + """ + assert af == self.V4 or af == self.V6 + family = self.__af_to_family(af) + match_string = '%s prefix-list %s seq ' % (family, pl_name) + conf = self.cfg_mgr.get_text() + if not any(line.strip().startswith(match_string) for line in conf): + return False, False # if the prefix list is not exists, it is not correct + constant_set = set(constant_list) + allow_set = set(allow_list) + for line in conf: + if line.startswith(match_string): + found = line[len(match_string):].strip().split(' ') + rule = " ".join(found[1:]) + if rule in constant_set: + constant_set.discard(rule) + elif rule in allow_set: + if constant_set: + return True, False # Not everything from constant set is presented + else: + allow_set.discard(rule) + return True, len(allow_set) == 0 # allow_set should be presented all + + def __update_community(self, community_name, community_value): + """ + Update community for a peer + :param community_name: name of the community to update + :param community_value: community value for the peer + :return: True if operation was successful, False otherwise + """ + log_debug("BGPAllowListMgr::__update_community. community_name='%s' community='%s'" % (community_name, community_value)) + if community_value == self.EMPTY_COMMUNITY: # we don't need to do anything for EMPTY community + log_debug("BGPAllowListMgr::__update_community. Empty community. exiting") + return [] + cmds = [] + exists, found_community_value = self.__is_community_presented(community_name) + if exists: + if community_value == found_community_value: + log_debug("BGPAllowListMgr::__update_community. community '%s' is already presented" % community_name) + return [] + else: + msg = "BGPAllowListMgr::__update_community. " + msg += "community '%s' is already presented, but community value should be updated" % community_name + log_debug(msg) + cmds.append("no bgp community-list standard %s" % community_name) + cmds.append('bgp community-list standard %s permit %s' % (community_name, community_value)) + return cmds + + def __remove_community(self, community_name): + """ + Remove community for a peer + :param community_name: community value for the peer + :return: True if operation was successful, False otherwise + """ + log_debug("BGPAllowListMgr::__remove_community. community='%s'" % community_name) + if community_name == self.EMPTY_COMMUNITY: # we don't need to do anything for EMPTY community + log_debug("BGPAllowListMgr::__remove_community. There is nothing to remove in empty community") + return [] + exists, _ = self.__is_community_presented(community_name) + if not exists: + log_debug("BGPAllowListMgr::__remove_community. Community is already removed.") + return [] + return ['no bgp community-list standard %s' % community_name] + + def __is_community_presented(self, community_name): + """ + Return True if community for the peer_ip exists + :param community_name: community value for the peer + :return: A tuple. First element: True if operation was successful, False otherwise + Second element: community value if the first element is True no value otherwise + """ + log_debug("BGPAllowListMgr::__is_community_presented. community='%s'" % community_name) + match_string = 'bgp community-list standard %s permit ' % community_name + conf = self.cfg_mgr.get_text() + found = [line.strip() for line in conf if line.strip().startswith(match_string)] + if not found: + return False, None + community_value = found[0].replace(match_string, '') + return True, community_value + + def __update_allow_route_map_entry(self, af, allow_address_pl_name, community_name, route_map_name): + """ + Add or update a "Allow address" route-map entry with the parameters + :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list + :return: True if operation was successful, False otherwise + """ + assert af == self.V4 or af == self.V6 + info = af, route_map_name, allow_address_pl_name, community_name + log_debug("BGPAllowListMgr::__update_allow_route_map_entry. af='%s' Allow rm='%s' pl='%s' cl='%s'" % info) + entries = self.__parse_allow_route_map_entries(af, route_map_name) + found, _ = self.__find_route_map_entry(entries, allow_address_pl_name, community_name) + if found: + log_debug("BGPAllowListMgr::__update_allow_route_map_entry. route-map='%s' is already found" % route_map_name) + return [] + seq_number = self.__find_next_seq_number(entries.keys(), community_name != self.EMPTY_COMMUNITY, route_map_name) + info = af, seq_number, allow_address_pl_name, community_name + out = "af='%s' seqno='%d' Allow pl='%s' cl='%s'" % info + log_debug("BGPAllowListMgr::__update_allow_route_map_entry. %s" % out) + ip_version = "" if af == self.V4 else "v6" + cmds = [ + 'route-map %s permit %d' % (route_map_name, seq_number), + ' match ip%s address prefix-list %s' % (ip_version, allow_address_pl_name) + ] + if not community_name.endswith(self.EMPTY_COMMUNITY): + cmds.append(" match community %s" % community_name) + return cmds + + def __update_default_route_map_entry(self, route_map_name, default_action_community): + """ + Add or update default action rule for the route-map. + Default action rule is hardcoded into route-map permit 65535 + :param route_map_name: name of the target route_map + :param default_action_community: community value to mark not-matched prefixes + """ + info = route_map_name, default_action_community + log_debug("BGPAllowListMgr::__update_default_route_map_entry. rm='%s' set_community='%s'" % info) + current_default_action_value = self.__parse_default_action_route_map_entry(route_map_name) + if current_default_action_value != default_action_community: + return [ + 'route-map %s permit 65535' % route_map_name, + ' set community %s additive' % default_action_community + ] + else: + return [] + + def __parse_default_action_route_map_entry(self, route_map_name): + """ + Parse default-action route-map entry + :param route_map_name: Name of the route-map to parse + :return: a community value used for default action + """ + log_debug("BGPAllowListMgr::__parse_default_action_route_map_entries. rm='%s'" % route_map_name) + match_string = 'route-map %s permit 65535' % route_map_name + match_community = re.compile(r'^set community (\S+) additive$') + inside_route_map = False + community_value = "" + conf = self.cfg_mgr.get_text() + for line in conf + [""]: + s_line = line.strip() + if inside_route_map: + matched = match_community.match(s_line) + if matched: + community_value = matched.group(1) + break + else: + log_err("BGPAllowListMgr::Found incomplete route-map '%s' entry. seq_no=65535" % route_map_name) + inside_route_map = False + elif s_line == match_string: + inside_route_map = True + if community_value == "": + log_err("BGPAllowListMgr::Default action community value is not found. route-map '%s' entry. seq_no=65535" % route_map_name) + return community_value + + def __remove_allow_route_map_entry(self, af, allow_address_pl_name, community_name, route_map_name): + """ + Add or update a "Allow address" route-map entry with the parameters + :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list + :return: True if operation was successful, False otherwise + """ + assert af == self.V4 or af == self.V6 + info = af, route_map_name, allow_address_pl_name, community_name + log_debug("BGPAllowListMgr::__update_allow_route_map_entry. af='%s' Allow rm='%s' pl='%s' cl='%s'" % info) + entries = self.__parse_allow_route_map_entries(af, route_map_name) + found, seq_number = self.__find_route_map_entry(entries, allow_address_pl_name, community_name) + if not found: + log_debug("BGPAllowListMgr::__update_allow_route_map_entry. Not found route-map '%s' entry" % allow_address_pl_name) + return [] + return ['no route-map %s permit %d' % (route_map_name, seq_number)] + + @staticmethod + def __find_route_map_entry(entries, allow_address_pl_name, community_name): + """ + Find route-map entry with given allow_address prefix list name and community name in the parsed route-map. + :param entries: entries of parsed route-map + :param allow_address_pl_name: name of the "allow address" prefix-list + :param community_name: name of the "allow address" community name + :return: a tuple. The first element of the tuple is True, if the route-map entry was found, False otherwise. + The second element of the tuple has a sequence number of the entry. + """ + for sequence_number, values in entries.items(): + if sequence_number == 65535: + continue + allow_list_presented = values['pl_allow_list'] == allow_address_pl_name + community_presented = values['community'] == community_name + if allow_list_presented and community_presented: + log_debug("BGPAllowListMgr::__find_route_map_entry. found route-map '%s' entry" % allow_address_pl_name) + return True, sequence_number + return False, None + + def __parse_allow_route_map_entries(self, af, route_map_name): + """ + Parse "Allow list" route-map entries. + :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list + :return: A tuple, First element: True if operation was successful, False otherwise + Second element: list of object with parsed route-map entries + """ + assert af == self.V4 or af == self.V6 + log_debug("BGPAllowListMgr::__parse_allow_route_map_entries. af='%s', rm='%s'" % (af, route_map_name)) + match_string = 'route-map %s permit ' % route_map_name + entries = {} + inside_route_map = False + route_map_seq_number = None + pl_allow_list_name = None + community_name = self.EMPTY_COMMUNITY + if af == self.V4: + match_pl_allow_list = 'match ip address prefix-list ' + else: # self.V6 + match_pl_allow_list = 'match ipv6 address prefix-list ' + match_community = 'match community ' + conf = self.cfg_mgr.get_text() + for line in conf + [""]: + if inside_route_map: + if line.strip().startswith(match_pl_allow_list): + pl_allow_list_name = line.strip()[len(match_pl_allow_list):] + continue + elif line.strip().startswith(match_community): + community_name = line.strip()[len(match_community):] + continue + else: + if pl_allow_list_name is not None: + entries[route_map_seq_number] = { + 'pl_allow_list': pl_allow_list_name, + 'community': community_name, + } + else: + if route_map_seq_number != 65535: + log_warn("BGPAllowListMgr::Found incomplete route-map '%s' entry. seq_no=%d" % (route_map_name, route_map_seq_number)) + inside_route_map = False + pl_allow_list_name = None + community_name = self.EMPTY_COMMUNITY + route_map_seq_number = None + if line.startswith(match_string): + found = line[len(match_string):] + assert found.isdigit() + route_map_seq_number = int(found) + inside_route_map = True + return entries + + @staticmethod + def __find_next_seq_number(seq_numbers, has_community, route_map_name): + """ + Find a next available "Allow list" route-map entry number + :param seq_numbers: a list of already used sequence numbers + :param has_community: True, if the route-map entry has community + :return: next available route-map sequence number + """ + used_sequence_numbers = set(seq_numbers) + sequence_number = None + if has_community: # put entries without communities after 29999 + start_seq = BGPAllowListMgr.ROUTE_MAP_ENTRY_WITH_COMMUNITY_START + end_seq = BGPAllowListMgr.ROUTE_MAP_ENTRY_WITH_COMMUNITY_END + else: + start_seq = BGPAllowListMgr.ROUTE_MAP_ENTRY_WITHOUT_COMMUNITY_START + end_seq = BGPAllowListMgr.ROUTE_MAP_ENTRY_WITHOUT_COMMUNITY_END + for i in range(start_seq, end_seq, 10): + if i not in used_sequence_numbers: + sequence_number = i + break + if sequence_number is None: + raise RuntimeError("No free sequence numbers for '%s'" % route_map_name) + info = sequence_number, "yes" if has_community else "no" + log_debug("BGPAllowListMgr::__find_next_seq_number '%d' has_community='%s'" % info) + return sequence_number + + def __extract_peer_group_names(self): + """ + Extract names of all peer-groups defined in the config + :return: list of peer-group names + """ + # Find all peer-groups entries + re_peer_group = re.compile(r'^\s*neighbor (\S+) peer-group$') + peer_groups = [] + for line in self.cfg_mgr.get_text(): + result = re_peer_group.match(line) + if result: + peer_groups.append(result.group(1)) + return peer_groups + + def __get_peer_group_to_route_map(self, peer_groups): + """ + Extract names of route-maps which is connected to peer-groups defines as peer_groups + :peer_groups: a list of peer-group names + :return: dictionary where key is a peer-group, value is a route-map name which is defined as route-map in + for the peer_group. + """ + pg_2_rm = {} + for pg in peer_groups: + re_peer_group_rm = re.compile(r'^\s*neighbor %s route-map (\S+) in$' % pg) + for line in self.cfg_mgr.get_text(): + result = re_peer_group_rm.match(line) + if result: + pg_2_rm[pg] = result.group(1) + break + return pg_2_rm + + def __get_route_map_calls(self, rms): + """ + Find mapping between route-maps and route-map call names, defined for the route-maps + :rms: a set with route-map names + :return: a dictionary: key - name of a route-map, value - name of a route-map call defined for the route-map + """ + rm_2_call = {} + re_rm = re.compile(r'^route-map (\S+) permit \d+$') + re_call = re.compile(r'^\s*call (\S+)$') + inside_name = None + for line in self.cfg_mgr.get_text(): + if inside_name: + inside_result = re_call.match(line) + if inside_result: + rm_2_call[inside_name] = inside_result.group(1) + inside_name = None + continue + result = re_rm.match(line) + if not result: + continue + inside_name = None + if result.group(1) not in rms: + continue + inside_name = result.group(1) + return rm_2_call + + @staticmethod + def __get_peer_group_to_restart(deployment_id, pg_2_rm, rm_2_call): + """ + Get peer_groups which are assigned to deployment_id + :deployment_id: deployment_id number + :pg_2_rm: a dictionary where key is a peer-group, value is a route-map name which is defined as route-map in + for the peer_group. + :rm_2_call: a dictionary: key - name of a route-map, value - name of a route-map call defined for the route-map + """ + ret = set() + target_allow_list_prefix = 'ALLOW_LIST_DEPLOYMENT_ID_%d_V' % deployment_id + for peer_group, route_map in pg_2_rm.items(): + if route_map in rm_2_call: + if rm_2_call[route_map].startswith(target_allow_list_prefix): + ret.add(peer_group) + return list(ret) + + def __find_peer_group_by_deployment_id(self, deployment_id): + """ + Deduce peer-group names which are connected to devices with requested deployment_id + :param deployment_id: deployment_id number + :return: a list of peer-groups which a used by devices with requested deployment_id number + """ + self.cfg_mgr.update() + peer_groups = self.__extract_peer_group_names() + pg_2_rm = self.__get_peer_group_to_route_map(peer_groups) + rm_2_call = self.__get_route_map_calls(set(pg_2_rm.values())) + ret = self.__get_peer_group_to_restart(deployment_id, pg_2_rm, rm_2_call) + return list(ret) + + def __get_enabled(self): + """ + Load enable/disabled property from constants + :return: True if enabled, False otherwise + """ + return 'bgp' in self.constants \ + and 'allow_list' in self.constants["bgp"] \ + and "enabled" in self.constants["bgp"]["allow_list"] \ + and self.constants["bgp"]["allow_list"]["enabled"] + + def __load_constant_lists(self): + """ + Load default prefix-list entries from constants.yml file + """ + if 'bgp' in self.constants and 'allow_list' in self.constants["bgp"] \ + and "default_pl_rules" in self.constants["bgp"]["allow_list"]: + obj = self.constants["bgp"]["allow_list"]["default_pl_rules"] + if "v4" in obj: + self.constants_v4 = obj["v4"] + else: + self.constants_v4 = [] + if "v6" in obj: + self.constants_v6 = obj["v6"] + else: + self.constants_v6 = [] + + def __get_constant_list(self, af): + """ + Return loaded default prefix-list entries bases on address family + :param af: address family + :return: default prefix-list entries + """ + if af == self.V4: + return self.constants_v4 + else: + return self.constants_v6 + + def __to_prefix_list(self, af, allow_list): + """ + Convert "allow list" prefix list, to a prefix-list rules + :param af: address-family + :param allow_list: "allow list" prefix list + :return: prefix-list rules + """ + res = [] + prefix_mask_default = 32 if af == self.V4 else 128 + for prefix in allow_list: + prefix_mask = int(prefix.split("/")[1]) + if prefix_mask == prefix_mask_default: + res.append("permit %s" % prefix) + else: + res.append("permit %s le %d" % (prefix, prefix_mask_default)) + return res + + def __af_to_family(self, af): + """ + Convert address family into prefix list family + :param af: address family + :return: prefix list ip family + """ + return 'ip' if af == self.V4 else 'ipv6' + + def __get_default_action_community(self, data=None): + """ + Determine the default action community based on the request. + If request doesn't contain "default_action" field - the default_action value + from the constants is being used + :param data: SET request data + :return: returns community value for "default_action" + """ + drop_community = self.constants["bgp"]["allow_list"]["drop_community"] + if data and "default_action" in data: + if data["default_action"] == "deny": + return "no-export" + else: # "permit" + return drop_community + else: + if "default_action" in self.constants["bgp"]["allow_list"]: + if self.constants["bgp"]["allow_list"]["default_action"].strip() == "deny": + return "no-export" + else: + return drop_community + else: + return drop_community diff --git a/src/sonic-bgpcfgd/bgpcfgd/managers_bbr.py b/src/sonic-bgpcfgd/bgpcfgd/managers_bbr.py new file mode 100644 index 000000000000..0e82d0a4b6d5 --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/managers_bbr.py @@ -0,0 +1,134 @@ +import re + +from swsscommon import swsscommon + +from .log import log_err, log_info +from .manager import Manager + + +class BBRMgr(Manager): + """ This class initialize "BBR" feature for """ + def __init__(self, common_objs, db, table): + """ + Initialize the object + :param common_objs: common object dictionary + :param db: name of the db + :param table: name of the table in the db + """ + super(BBRMgr, self).__init__( + common_objs, + [("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME, "localhost/bgp_asn"),], + db, + table, + ) + self.enabled = False + self.bbr_enabled_pgs = {} + self.directory.put(self.db_name, self.table_name, 'status', "disabled") + self.__init() + + def set_handler(self, key, data): + """ Implementation of 'SET' command for this class """ + if not self.enabled: + log_info("BBRMgr::BBR is disabled. Drop the request") + return True + if not self.__set_validation(key, data): + return True + cmds, peer_groups_to_restart = self.__set_prepare_config(data['status']) + self.cfg_mgr.push_list(cmds) + self.cfg_mgr.restart_peer_groups(peer_groups_to_restart) + log_info("BBRMgr::Scheduled BBR update") + return True + + def del_handler(self, key): + """ Implementation of 'DEL' command for this class """ + log_err("The '%s' table shouldn't be removed from the db" % self.table_name) + + def __init(self): + """ Initialize BBRMgr. Extracted from constructor """ + if not 'bgp' in self.constants: + log_err("BBRMgr::Disabled: 'bgp' key is not found in constants") + return + if 'bbr' in self.constants['bgp'] \ + and 'enabled' in self.constants['bgp']['bbr'] \ + and self.constants['bgp']['bbr']['enabled']: + self.bbr_enabled_pgs = self.__read_pgs() + if self.bbr_enabled_pgs: + self.enabled = True + if 'default_state' in self.constants['bgp']['bbr'] \ + and self.constants['bgp']['bbr']['default_state'] == 'enabled': + default_status = "enabled" + else: + default_status = "disabled" + self.directory.put(self.db_name, self.table_name, 'status', default_status) + log_info("BBRMgr::Initialized and enabled. Default state: '%s'" % default_status) + else: + log_info("BBRMgr::Disabled: no BBR enabled peers") + else: + log_info("BBRMgr::Disabled: no bgp.bbr.enabled in the constants") + + def __read_pgs(self): + """ + Read peer-group bbr settings from constants file + :return: return bbr information from constant peer-group settings + """ + if 'peers' not in self.constants['bgp']: + log_info("BBRMgr::no 'peers' was found in constants") + return {} + res = {} + for peer_name, value in self.constants['bgp']['peers'].items(): + if 'bbr' not in value: + continue + for pg_name, pg_afs in value['bbr'].items(): + res[pg_name] = pg_afs + return res + + def __set_validation(self, key, data): + """ Validate set-command arguments + :param key: key of 'set' command + :param data: data of 'set' command + :return: True is the parameters are valid, False otherwise + """ + if key != 'all': + log_err("Invalid key '%s' for table '%s'. Only key value 'all' is supported" % (key, self.table_name)) + return False + if 'status' not in data: + log_err("Invalid value '%s' for table '%s', key '%s'. Key 'status' in data is expected" % (data, self.table_name, key)) + return False + if data['status'] != "enabled" and data['status'] != "disabled": + log_err("Invalid value '%s' for table '%s', key '%s'. Only 'enabled' and 'disabled' are supported" % (data, self.table_name, key)) + return False + return True + + def __set_prepare_config(self, status): + """ + Generate FFR configuration to apply changes + :param status: either "enabled" or "disabled" + :return: list of commands prepared for FRR + """ + bgp_asn = self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME)["localhost"]["bgp_asn"] + available_peer_groups = self.__get_available_peer_groups() + cmds = ["router bgp %s" % bgp_asn] + prefix_of_commands = "" if status == "enabled" else "no " + peer_groups_to_restart = set() + for af in ["ipv4", "ipv6"]: + cmds.append(" address-family %s" % af) + for pg_name in sorted(self.bbr_enabled_pgs.keys()): + for peer_group_name in available_peer_groups: + if peer_group_name.startswith(pg_name) and af in self.bbr_enabled_pgs[pg_name]: + cmds.append(" %sneighbor %s allowas-in 1" % (prefix_of_commands, peer_group_name)) + peer_groups_to_restart.add(peer_group_name) + return cmds, list(peer_groups_to_restart) + + def __get_available_peer_groups(self): + """ + Extract configured peer-groups from the config + :return: set of available peer-groups + """ + re_pg = re.compile(r'^\s*neighbor\s+(\S+)\s+peer-group\s*$') + res = set() + self.cfg_mgr.update() + for line in self.cfg_mgr.get_text(): + m = re_pg.match(line) + if m: + res.add(m.group(1)) + return res diff --git a/src/sonic-bgpcfgd/bgpcfgd/managers_bgp.py b/src/sonic-bgpcfgd/bgpcfgd/managers_bgp.py new file mode 100644 index 000000000000..f6108bfb61c4 --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/managers_bgp.py @@ -0,0 +1,387 @@ +import json +from swsscommon import swsscommon + +import jinja2 +import netaddr + +from .log import log_warn, log_err, log_info, log_debug, log_crit +from .manager import Manager +from .template import TemplateFabric +from .utils import run_command + + +class BGPPeerGroupMgr(object): + """ This class represents peer-group and routing policy for the peer_type """ + def __init__(self, common_objs, base_template): + """ + Construct the object + :param common_objs: common objects + :param base_template: path to the directory with Jinja2 templates + """ + self.cfg_mgr = common_objs['cfg_mgr'] + self.constants = common_objs['constants'] + tf = common_objs['tf'] + self.policy_template = tf.from_file(base_template + "policies.conf.j2") + self.peergroup_template = tf.from_file(base_template + "peer-group.conf.j2") + + def update(self, name, **kwargs): + """ + Update peer-group and routing policy for the peer with the name + :param name: name of the peer. Used for logging only + :param kwargs: dictionary with parameters for rendering + """ + rc_policy = self.update_policy(name, **kwargs) + rc_pg = self.update_pg(name, **kwargs) + return rc_policy and rc_pg + + def update_policy(self, name, **kwargs): + """ + Update routing policy for the peer + :param name: name of the peer. Used for logging only + :param kwargs: dictionary with parameters for rendering + """ + try: + policy = self.policy_template.render(**kwargs) + except jinja2.TemplateError as e: + log_err("Can't render policy template name: '%s': %s" % (name, str(e))) + return False + self.update_entity(policy, "Routing policy for peer '%s'" % name) + return True + + def update_pg(self, name, **kwargs): + """ + Update peer-group for the peer + :param name: name of the peer. Used for logging only + :param kwargs: dictionary with parameters for rendering + """ + try: + pg = self.peergroup_template.render(**kwargs) + except jinja2.TemplateError as e: + log_err("Can't render peer-group template: '%s': %s" % (name, str(e))) + return False + + if kwargs['vrf'] == 'default': + cmd = ('router bgp %s\n' % kwargs['bgp_asn']) + pg + else: + cmd = ('router bgp %s vrf %s\n' % (kwargs['bgp_asn'], kwargs['vrf'])) + pg + self.update_entity(cmd, "Peer-group for peer '%s'" % name) + return True + + def update_entity(self, cmd, txt): + """ + Send commands to FRR + :param cmd: commands to send in a raw form + :param txt: text for the syslog output + :return: + """ + self.cfg_mgr.push(cmd) + log_info("%s has been scheduled to be updated" % txt) + return True + + +class BGPPeerMgrBase(Manager): + """ Manager of BGP peers """ + def __init__(self, common_objs, db_name, table_name, peer_type, check_neig_meta): + """ + Initialize the object + :param common_objs: common objects + :param table_name: name of the table with peers + :param peer_type: type of the peers. It is used to find right templates + """ + self.common_objs = common_objs + self.constants = self.common_objs["constants"] + self.fabric = common_objs['tf'] + self.peer_type = peer_type + + base_template = "bgpd/templates/" + self.constants["bgp"]["peers"][peer_type]["template_dir"] + "/" + self.templates = { + "add": self.fabric.from_file(base_template + "instance.conf.j2"), + "delete": self.fabric.from_string('no neighbor {{ neighbor_addr }}'), + "shutdown": self.fabric.from_string('neighbor {{ neighbor_addr }} shutdown'), + "no shutdown": self.fabric.from_string('no neighbor {{ neighbor_addr }} shutdown'), + } + + deps = [ + ("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME, "localhost/bgp_asn"), + ("CONFIG_DB", swsscommon.CFG_LOOPBACK_INTERFACE_TABLE_NAME, "Loopback0"), + ("LOCAL", "local_addresses", ""), + ("LOCAL", "interfaces", ""), + ] + + if check_neig_meta: + self.check_neig_meta = 'bgp' in self.constants \ + and 'use_neighbors_meta' in self.constants['bgp'] \ + and self.constants['bgp']['use_neighbors_meta'] + else: + self.check_neig_meta = False + + self.check_deployment_id = 'bgp' in self.constants \ + and 'use_deployment_id' in self.constants['bgp'] \ + and self.constants['bgp']['use_deployment_id'] + + if self.check_neig_meta: + deps.append(("CONFIG_DB", swsscommon.CFG_DEVICE_NEIGHBOR_METADATA_TABLE_NAME, "")) + + if self.check_deployment_id: + deps.append(("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME, "localhost/deployment_id")) + + super(BGPPeerMgrBase, self).__init__( + common_objs, + deps, + db_name, + table_name, + ) + + self.peers = self.load_peers() + self.peer_group_mgr = BGPPeerGroupMgr(self.common_objs, base_template) + return + + def set_handler(self, key, data): + """ + It runs on 'SET' command + :param key: key of the changed table + :param data: the data associated with the change + """ + vrf, nbr = self.split_key(key) + peer_key = (vrf, nbr) + if peer_key not in self.peers: + return self.add_peer(vrf, nbr, data) + else: + return self.update_peer(vrf, nbr, data) + + def add_peer(self, vrf, nbr, data): + """ + Add a peer into FRR. This is used if the peer is not existed in FRR yet + :param vrf: vrf name. Name is equal "default" for the global vrf + :param nbr: neighbor ip address (name for dynamic peer type) + :param data: associated data + :return: True if this adding was successful, False otherwise + """ + print_data = vrf, nbr, data + bgp_asn = self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME)["localhost"]["bgp_asn"] + # + lo0_ipv4 = self.get_lo0_ipv4() + if lo0_ipv4 is None: + log_warn("Loopback0 ipv4 address is not presented yet") + return False + # + if "local_addr" not in data: + log_warn("Peer %s. Missing attribute 'local_addr'" % nbr) + 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. + data["local_addr"] = str(netaddr.IPNetwork(str(data["local_addr"])).ip) + interface = self.get_local_interface(data["local_addr"]) + if not interface: + print_data = nbr, data["local_addr"] + log_debug("Peer '%s' with local address '%s' wait for the corresponding interface to be set" % print_data) + return False + vnet = self.get_vnet(interface) + if vnet: + # Ignore the bgp session that is in a vnet + log_info("Ignore the BGP peer '%s' as the interface '%s' is in vnet '%s'" % (nbr, interface, vnet)) + return True + + kwargs = { + 'CONFIG_DB__DEVICE_METADATA': self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME), + 'CONFIG_DB__BGP_BBR': self.directory.get_slot('CONFIG_DB', 'BGP_BBR'), + 'constants': self.constants, + 'bgp_asn': bgp_asn, + 'vrf': vrf, + 'neighbor_addr': nbr, + 'bgp_session': data, + 'loopback0_ipv4': lo0_ipv4, + } + if self.check_neig_meta: + neigmeta = self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_NEIGHBOR_METADATA_TABLE_NAME) + if 'name' in data and data["name"] not in neigmeta: + log_info("DEVICE_NEIGHBOR_METADATA is not ready for neighbor '%s' - '%s'" % (nbr, data['name'])) + return False + kwargs['CONFIG_DB__DEVICE_NEIGHBOR_METADATA'] = neigmeta + + tag = data['name'] if 'name' in data else nbr + self.peer_group_mgr.update(tag, **kwargs) + + try: + cmd = self.templates["add"].render(**kwargs) + except jinja2.TemplateError as e: + msg = "Peer '(%s|%s)'. Error in rendering the template for 'SET' command '%s'" % print_data + log_err("%s: %s" % (msg, str(e))) + return True + if cmd is not None: + self.apply_op(cmd, vrf) + key = (vrf, nbr) + self.peers.add(key) + log_info("Peer '(%s|%s)' has been scheduled to be added with attributes '%s'" % print_data) + + return True + + def update_peer(self, vrf, nbr, data): + """ + Update a peer. This is used when the peer is already in the FRR + Update support only "admin_status" for now + :param vrf: vrf name. Name is equal "default" for the global vrf + :param nbr: neighbor ip address (name for dynamic peer type) + :param data: associated data + :return: True if this adding was successful, False otherwise + """ + if "admin_status" in data: + self.change_admin_status(vrf, nbr, data) + else: + log_err("Peer '(%s|%s)': Can't update the peer. Only 'admin_status' attribute is supported" % (vrf, nbr)) + + return True + + def change_admin_status(self, vrf, nbr, data): + """ + Change admin status of a peer + :param vrf: vrf name. Name is equal "default" for the global vrf + :param nbr: neighbor ip address (name for dynamic peer type) + :param data: associated data + :return: True if this adding was successful, False otherwise + """ + if data['admin_status'] == 'up': + self.apply_admin_status(vrf, nbr, "no shutdown", "up") + elif data['admin_status'] == 'down': + self.apply_admin_status(vrf, nbr, "shutdown", "down") + else: + print_data = vrf, nbr, data['admin_status'] + log_err("Peer '%s|%s': Can't update the peer. It has wrong attribute value attr['admin_status'] = '%s'" % print_data) + + def apply_admin_status(self, vrf, nbr, template_name, admin_state): + """ + Render admin state template and apply the command to the FRR + :param vrf: vrf name. Name is equal "default" for the global vrf + :param nbr: neighbor ip address (name for dynamic peer type) + :param template_name: name of the template to render + :param admin_state: desired admin state + :return: True if this adding was successful, False otherwise + """ + print_data = vrf, nbr, admin_state + ret_code = self.apply_op(self.templates[template_name].render(neighbor_addr=nbr), vrf) + if ret_code: + log_info("Peer '%s|%s' admin state is set to '%s'" % print_data) + else: + log_err("Can't set peer '%s|%s' admin state to '%s'." % print_data) + + def del_handler(self, key): + """ + 'DEL' handler for the BGP PEER tables + :param key: key of the neighbor + """ + vrf, nbr = self.split_key(key) + peer_key = (vrf, nbr) + if peer_key not in self.peers: + log_warn("Peer '(%s|%s)' has not been found" % (vrf, nbr)) + return + cmd = self.templates["delete"].render(neighbor_addr=nbr) + ret_code = self.apply_op(cmd, vrf) + if ret_code: + log_info("Peer '(%s|%s)' has been removed" % (vrf, nbr)) + self.peers.remove(peer_key) + else: + log_err("Peer '(%s|%s)' hasn't been removed" % (vrf, nbr)) + + def apply_op(self, cmd, vrf): + """ + Push commands cmd into FRR + :param cmd: commands in raw format + :param vrf: vrf where the commands should be applied + :return: True if no errors, False if there are errors + """ + bgp_asn = self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME)["localhost"]["bgp_asn"] + if vrf == 'default': + cmd = ('router bgp %s\n' % bgp_asn) + cmd + else: + cmd = ('router bgp %s vrf %s\n' % (bgp_asn, vrf)) + cmd + self.cfg_mgr.push(cmd) + return True + + def get_lo0_ipv4(self): + """ + Extract Loopback0 ipv4 address from the Directory + :return: ipv4 address for Loopback0, None if nothing found + """ + loopback0_ipv4 = None + for loopback in self.directory.get_slot("CONFIG_DB", swsscommon.CFG_LOOPBACK_INTERFACE_TABLE_NAME).keys(): + if loopback.startswith("Loopback0|"): + loopback0_prefix_str = loopback.replace("Loopback0|", "") + loopback0_ip_str = loopback0_prefix_str[:loopback0_prefix_str.find('/')] + if TemplateFabric.is_ipv4(loopback0_ip_str): + loopback0_ipv4 = loopback0_ip_str + break + + return loopback0_ipv4 + + def get_local_interface(self, local_addr): + """ + 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 = self.directory.get_slot("LOCAL", "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 = self.directory.get_slot("LOCAL", "interfaces") + # Check if the information for the interface of this local address has been set + if "interface" in local_address and local_address["interface"] in interfaces: + return interfaces[local_address["interface"]] + else: + return None + + @staticmethod + def get_vnet(interface): + """ + 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 "vnet_name" in interface and interface["vnet_name"]: + return interface["vnet_name"] + else: + return None + + @staticmethod + def split_key(key): + """ + Split key into ip address and vrf name. If there is no vrf, "default" would be return for vrf + :param key: key to split + :return: vrf name extracted from the key, peer ip address extracted from the key + """ + if '|' not in key: + return 'default', key + else: + return tuple(key.split('|', 1)) + + @staticmethod + def load_peers(): + """ + Load peers from FRR. + :return: set of peers, which are already installed in FRR + """ + command = ["vtysh", "-c", "show bgp vrfs json"] + ret_code, out, err = run_command(command) + if ret_code == 0: + js_vrf = json.loads(out) + vrfs = js_vrf['vrfs'].keys() + else: + log_crit("Can't read bgp vrfs: %s" % err) + raise Exception("Can't read bgp vrfs: %s" % err) + peers = set() + for vrf in vrfs: + command = ["vtysh", "-c", 'show bgp vrf %s neighbors json' % str(vrf)] + ret_code, out, err = run_command(command) + if ret_code == 0: + js_bgp = json.loads(out) + for nbr in js_bgp.keys(): + peers.add((vrf, nbr)) + else: + log_crit("Can't read vrf '%s' neighbors: %s" % (vrf, str(err))) + raise Exception("Can't read vrf '%s' neighbors: %s" % (vrf, str(err))) + + return peers \ No newline at end of file diff --git a/src/sonic-bgpcfgd/bgpcfgd/managers_db.py b/src/sonic-bgpcfgd/bgpcfgd/managers_db.py new file mode 100644 index 000000000000..37d2eee99a8f --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/managers_db.py @@ -0,0 +1,28 @@ +from .manager import Manager + + +class BGPDataBaseMgr(Manager): + """ This class updates the Directory object when db table is updated """ + def __init__(self, common_objs, db, table): + """ + Initialize the object + :param common_objs: common object dictionary + :param db: name of the db + :param table: name of the table in the db + """ + super(BGPDataBaseMgr, self).__init__( + common_objs, + [], + db, + table, + ) + + def set_handler(self, key, data): + """ Implementation of 'SET' command for this class """ + self.directory.put(self.db_name, self.table_name, key, data) + + return True + + def del_handler(self, key): + """ Implementation of 'DEL' command for this class """ + self.directory.remove(self.db_name, self.table_name, key) \ No newline at end of file diff --git a/src/sonic-bgpcfgd/bgpcfgd/managers_intf.py b/src/sonic-bgpcfgd/bgpcfgd/managers_intf.py new file mode 100644 index 000000000000..c633c43046e0 --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/managers_intf.py @@ -0,0 +1,56 @@ +import netaddr + +from .log import log_warn +from .manager import Manager + + +class InterfaceMgr(Manager): + """ This class updates the Directory object when interface-related table is updated """ + def __init__(self, common_objs, db, table): + """ + Initialize the object + :param common_objs: common object dictionary + :param db: name of the db + :param table: name of the table in the db + """ + super(InterfaceMgr, self).__init__( + common_objs, + [], + db, + table, + ) + + def set_handler(self, key, data): + """ Implementation of 'SET' command. + Similar to BGPDataBaseMgr but enriches data object with additional data """ + # Interface table can have two keys, + # one with ip prefix and one without ip prefix + if '|' in key: + interface_name, network_str = key.split('|', 1) + try: + network = netaddr.IPNetwork(str(network_str)) + except (netaddr.NotRegisteredError, netaddr.AddrFormatError, netaddr.AddrConversionError): + log_warn("Subnet '%s' format is wrong for interface '%s'" % (network_str, interface_name)) + return True + data["interface"] = interface_name + data["prefixlen"] = str(network.prefixlen) + ip = str(network.ip) + self.directory.put("LOCAL", "local_addresses", ip, data) + self.directory.put(self.db_name, self.table_name, key, data) + self.directory.put("LOCAL", "interfaces", key, data) + return True + + def del_handler(self, key): + """ Implementation of 'DEL' command + Also removes data object enrichment """ + if '|' in key: + interface, network = key.split('|', 1) + try: + network = netaddr.IPNetwork(str(network)) + except (netaddr.NotRegisteredError, netaddr.AddrFormatError, netaddr.AddrConversionError): + log_warn("Subnet '%s' format is wrong for interface '%s'" % (network, interface)) + return + ip = str(network.ip) + self.directory.remove("LOCAL", "local_addresses", ip) + self.directory.remove(self.db_name, self.table_name, key) + self.directory.remove("LOCAL", "interfaces", key) \ No newline at end of file diff --git a/src/sonic-bgpcfgd/bgpcfgd/managers_setsrc.py b/src/sonic-bgpcfgd/bgpcfgd/managers_setsrc.py new file mode 100644 index 000000000000..d1de585b0520 --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/managers_setsrc.py @@ -0,0 +1,67 @@ +import jinja2 + +from .log import log_err, log_warn, log_info +from .manager import Manager +from .template import TemplateFabric + + +class ZebraSetSrc(Manager): + """ This class initialize "set src" settings for zebra """ + def __init__(self, common_objs, db, table): + """ + Initialize the object + :param common_objs: common object dictionary + :param db: name of the db + :param table: name of the table in the db + """ + super(ZebraSetSrc, self).__init__( + common_objs, + [], + db, + table, + ) + tf = common_objs['tf'] + self.zebra_set_src_template = tf.from_file("zebra/zebra.set_src.conf.j2") + self.lo_ipv4 = None + self.lo_ipv6 = None + + def set_handler(self, key, data): + """ Implementation of 'SET' command for this class """ + self.directory.put(self.db_name, self.table_name, key, data) + # + if key.startswith("Loopback0|") and "state" in data and data["state"] == "ok": + ip_addr_w_mask = key.replace("Loopback0|", "") + slash_pos = ip_addr_w_mask.rfind("/") + if slash_pos == -1: + log_err("Wrong Loopback0 ip prefix: '%s'" % ip_addr_w_mask) + return True + ip_addr = ip_addr_w_mask[:slash_pos] + try: + if TemplateFabric.is_ipv4(ip_addr): + if self.lo_ipv4 is None: + self.lo_ipv4 = ip_addr + txt = self.zebra_set_src_template.render(rm_name="RM_SET_SRC", lo_ip=ip_addr, ip_proto="") + else: + log_warn("Update command is not supported for set src templates. current ip='%s'. new ip='%s'" % (self.lo_ipv4, ip_addr)) + return True + elif TemplateFabric.is_ipv6(ip_addr): + if self.lo_ipv6 is None: + self.lo_ipv6 = ip_addr + txt = self.zebra_set_src_template.render(rm_name="RM_SET_SRC6", lo_ip=ip_addr, ip_proto="v6") + else: + log_warn("Update command is not supported for set src templates. current ip='%s'. new ip='%s'" % (self.lo_ipv6, ip_addr)) + return True + else: + log_err("Got ambiguous ip address '%s'" % ip_addr) + return True + except jinja2.TemplateError as e: + log_err("Error while rendering 'set src' template: %s" % str(e)) + return True + self.cfg_mgr.push(txt) + log_info("The 'set src' configuration with Loopback0 ip '%s' has been scheduled to be added" % ip_addr) + return True + + def del_handler(self, key): + """ Implementation of 'DEL' command for this class """ + self.directory.remove(self.db_name, self.table_name, key) + log_warn("Delete command is not supported for 'zebra set src' templates") \ No newline at end of file diff --git a/src/sonic-bgpcfgd/bgpcfgd/runner.py b/src/sonic-bgpcfgd/bgpcfgd/runner.py new file mode 100644 index 000000000000..4c160e5967cf --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/runner.py @@ -0,0 +1,70 @@ +from collections import defaultdict +from swsscommon import swsscommon + +from .log import log_debug, log_crit + + +g_run = True + + +def signal_handler(_, __): # signal_handler(signum, frame) + """ signal handler """ + global g_run + g_run = False + + +class Runner(object): + """ Implements main io-loop of the application + It will run event handlers inside of Manager objects + when corresponding db/table is updated + """ + SELECT_TIMEOUT = 1000 + + def __init__(self, cfg_manager): + """ Constructor """ + self.cfg_manager = cfg_manager + self.db_connectors = {} + self.selector = swsscommon.Select() + self.callbacks = defaultdict(lambda: defaultdict(list)) # db -> table -> handlers[] + self.subscribers = set() + + def add_manager(self, manager): + """ + Add a manager to the Runner. + As soon as new events will be receiving by Runner, + handlers of corresponding objects will be executed + :param manager: an object implementing Manager + """ + db_name = manager.get_database() + table_name = manager.get_table_name() + db = swsscommon.SonicDBConfig.getDbId(db_name) + if db not in self.db_connectors: + self.db_connectors[db] = swsscommon.DBConnector(db_name, 0) + + if table_name not in self.callbacks[db]: + conn = self.db_connectors[db] + subscriber = swsscommon.SubscriberStateTable(conn, table_name) + self.subscribers.add(subscriber) + self.selector.addSelectable(subscriber) + self.callbacks[db][table_name].append(manager.handler) + + def run(self): + """ Main loop """ + while g_run: + state, _ = self.selector.select(Runner.SELECT_TIMEOUT) + if state == self.selector.TIMEOUT: + continue + elif state == self.selector.ERROR: + raise Exception("Received error from select") + + for subscriber in self.subscribers: + while True: + key, op, fvs = subscriber.pop() + if not key: + break + log_debug("Received message : '%s'" % str((key, op, fvs))) + for callback in self.callbacks[subscriber.getDbConnector().getDbId()][subscriber.getTableName()]: + callback(key, op, dict(fvs)) + rc = self.cfg_manager.commit() + if not rc: + log_crit("Runner::commit was unsuccessful") diff --git a/src/sonic-bgpcfgd/bgpcfgd/template.py b/src/sonic-bgpcfgd/bgpcfgd/template.py new file mode 100644 index 000000000000..e88073881171 --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/template.py @@ -0,0 +1,108 @@ +from collections import OrderedDict +from functools import partial + +import jinja2 +import netaddr + +from .log import log_err + +class TemplateFabric(object): + """ Fabric for rendering jinja2 templates """ + def __init__(self, template_path = '/usr/share/sonic/templates'): + j2_template_paths = [template_path] + j2_loader = jinja2.FileSystemLoader(j2_template_paths) + j2_env = jinja2.Environment(loader=j2_loader, trim_blocks=False) + j2_env.filters['ipv4'] = self.is_ipv4 + j2_env.filters['ipv6'] = self.is_ipv6 + j2_env.filters['pfx_filter'] = self.pfx_filter + for attr in ['ip', 'network', 'prefixlen', 'netmask']: + j2_env.filters[attr] = partial(self.prefix_attr, attr) + self.env = j2_env + + def from_file(self, filename): + """ + Read a template from a file + :param filename: filename of the file. Type String + :return: Jinja2 template object + """ + return self.env.get_template(filename) + + def from_string(self, tmpl): + """ + Read a template from a string + :param tmpl: Text representation of Jinja2 template + :return: Jinja2 template object + """ + return self.env.from_string(tmpl) + + @staticmethod + def is_ipv4(value): + """ Return True if the value is an ipv4 address """ + if not value: + return False + if isinstance(value, netaddr.IPNetwork): + addr = value + else: + try: + addr = netaddr.IPNetwork(str(value)) + except (netaddr.NotRegisteredError, netaddr.AddrFormatError, netaddr.AddrConversionError): + return False + return addr.version == 4 + + @staticmethod + def is_ipv6(value): + """ Return True if the value is an ipv6 address """ + if not value: + return False + if isinstance(value, netaddr.IPNetwork): + addr = value + else: + try: + addr = netaddr.IPNetwork(str(value)) + except (netaddr.NotRegisteredError, netaddr.AddrFormatError, netaddr.AddrConversionError): + return False + return addr.version == 6 + + @staticmethod + def prefix_attr(attr, value): + """ + Extract attribute from IPNetwork object + :param attr: attribute to extract + :param value: the string representation of ip prefix which will be converted to IPNetwork. + :return: the value of the extracted attribute + """ + if not value: + return None + else: + try: + prefix = netaddr.IPNetwork(str(value)) + except (netaddr.NotRegisteredError, netaddr.AddrFormatError, netaddr.AddrConversionError): + return None + return str(getattr(prefix, attr)) + + @staticmethod + def pfx_filter(value): + """INTERFACE Table can have keys in one of the two formats: + string or tuple - This filter skips the string keys and only + take into account the tuple. + For eg - VLAN_INTERFACE|Vlan1000 vs VLAN_INTERFACE|Vlan1000|192.168.0.1/21 + """ + table = OrderedDict() + + if not value: + return table + + for key, val in value.items(): + if not isinstance(key, tuple): + continue + intf, ip_address = key + if '/' not in ip_address: + if TemplateFabric.is_ipv4(ip_address): + table[(intf, "%s/32" % ip_address)] = val + elif TemplateFabric.is_ipv6(ip_address): + table[(intf, "%s/128" % ip_address)] = val + else: + log_err("'%s' is invalid ip address" % ip_address) + else: + table[key] = val + return table \ No newline at end of file diff --git a/src/sonic-bgpcfgd/bgpcfgd/utils.py b/src/sonic-bgpcfgd/bgpcfgd/utils.py new file mode 100644 index 000000000000..01c21b0f4872 --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/utils.py @@ -0,0 +1,33 @@ +import subprocess +import yaml + +from .log import log_crit, log_debug, log_err + + +def run_command(command, shell=False, hide_errors=False): + """ + Run a linux command. The command is defined as a list. See subprocess.Popen documentation on format + :param command: command to execute. Type: List of strings + :param shell: execute the command through shell when True. Type: Boolean + :param hide_errors: don't report errors to syslog when True. Type: Boolean + :return: Tuple: integer exit code from the command, stdout as a string, stderr as a string + """ + log_debug("execute command '%s'." % str(command)) + p = subprocess.Popen(command, shell=shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='utf-8') + stdout, stderr = p.communicate() + if p.returncode != 0: + if not hide_errors: + print_tuple = p.returncode, str(command), stdout, stderr + log_err("command execution returned %d. Command: '%s', stdout: '%s', stderr: '%s'" % print_tuple) + + return p.returncode, stdout, stderr + + +def read_constants(): + """ Read file with constants values from /etc/sonic/constants.yml """ + with open('/etc/sonic/constants.yml') as fp: + content = yaml.load(fp) # FIXME: , Loader=yaml.FullLoader) + if "constants" not in content: + log_crit("/etc/sonic/constants.yml doesn't have 'constants' key") + raise Exception("/etc/sonic/constants.yml doesn't have 'constants' key") + return content["constants"] \ No newline at end of file diff --git a/src/sonic-bgpcfgd/bgpcfgd/vars.py b/src/sonic-bgpcfgd/bgpcfgd/vars.py new file mode 100644 index 000000000000..18bee5578e25 --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/vars.py @@ -0,0 +1 @@ +g_debug = True # FIXME: read from env variable, or from constants diff --git a/src/sonic-bgpcfgd/bgpmon/__init__.py b/src/sonic-bgpcfgd/bgpmon/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/src/sonic-bgpcfgd/bgpmon/bgpmon.py b/src/sonic-bgpcfgd/bgpmon/bgpmon.py new file mode 100755 index 000000000000..2b50bd6cf58d --- /dev/null +++ b/src/sonic-bgpcfgd/bgpmon/bgpmon.py @@ -0,0 +1,169 @@ +#!/usr/bin/env python3 + +"""" +Description: bgpmon.py -- populating bgp related information in stateDB. + script is started by supervisord in bgp docker when the docker is started. + + Initial creation of this daemon is to assist SNMP agent in obtaining the + BGP related information for its MIB support. The MIB that this daemon is + assisting is for the CiscoBgp4MIB (Neighbor state only). If there are other + BGP related items that needs to be updated in a periodic manner in the + future, then more can be added into this process. + + The script check if there are any bgp activities by monitoring the bgp + frr.log file timestamp. If activity is detected, then it will request bgp + neighbor state via vtysh cli interface. This bgp activity monitoring is + done periodically (every 15 second). When triggered, it looks specifically + for the neighbor state in the json output of show ip bgp neighbors json + and update the state DB for each neighbor accordingly. + In order to not disturb and hold on to the State DB access too long and + removal of the stale neighbors (neighbors that was there previously on + previous get request but no longer there in the current get request), a + "previous" neighbor dictionary will be kept and used to determine if there + is a need to perform update or the peer is stale to be removed from the + state DB +""" +import subprocess +import json +import os +import syslog +import swsssdk +import time + +PIPE_BATCH_MAX_COUNT = 50 + +class BgpStateGet: + def __init__(self): + # set peer_l stores the Neighbor peer Ip address + # dic peer_state stores the Neighbor peer state entries + # set new_peer_l stores the new snapshot of Neighbor peer ip address + # dic new_peer_state stores the new snapshot of Neighbor peer states + self.peer_l = set() + self.peer_state = {} + self.new_peer_l = set() + self.new_peer_state = {} + self.cached_timestamp = 0 + self.db = swsssdk.SonicV2Connector() + self.db.connect(self.db.STATE_DB, False) + client = self.db.get_redis_client(self.db.STATE_DB) + self.pipe = client.pipeline() + self.db.delete_all_by_pattern(self.db.STATE_DB, "NEIGH_STATE_TABLE|*" ) + + # A quick way to check if there are anything happening within BGP is to + # check its log file has any activities. This is by checking its modified + # timestamp against the cached timestamp that we keep and if there is a + # difference, there is activity detected. In case the log file got wiped + # out, it will default back to constant pulling every 15 seconds + def bgp_activity_detected(self): + try: + timestamp = os.stat("/var/log/frr/frr.log").st_mtime + if timestamp != self.cached_timestamp: + self.cached_timestamp = timestamp + return True + else: + return False + except (IOError, OSError): + return True + + def update_new_peer_states(self, peer_dict): + peer_l = peer_dict["peers"].keys() + self.new_peer_l.update(peer_l) + for peer in peer_l: + self.new_peer_state[peer] = peer_dict["peers"][peer]["state"] + + # Get a new snapshot of BGP neighbors and store them in the "new" location + def get_all_neigh_states(self): + cmd = "vtysh -c 'show bgp summary json'" + rc, output = subprocess.getstatusoutput(cmd) + if rc: + syslog.syslog(syslog.LOG_ERR, "*ERROR* Failed with rc:{} when execute: {}".format(rc, cmd)) + return + + peer_info = json.loads(output) + # cmd ran successfully, safe to Clean the "new" set/dict for new snapshot + self.new_peer_l.clear() + self.new_peer_state.clear() + for key, value in peer_info.items(): + if key == "ipv4Unicast" or key == "ipv6Unicast": + self.update_new_peer_states(value) + + # This method will take the caller's dictionary which contains the peer state operation + # That need to be updated in StateDB using Redis pipeline. + # The data{} will be cleared at the end of this method before returning to caller. + def flush_pipe(self, data): + """Dump each entry in data{} into State DB via redis pipeline. + Args: + data: Neighbor state in dictionary format + { + 'NEIGH_STATE_TABLE|ip_address_a': {'state':state}, + 'NEIGH_STATE_TABLE|ip_address_b': {'state':state}, + 'NEIGH_STATE_TABLE|ip_address_c': {'state':state}, + 'NEIGH_STATE_TABLE|ip_address_x': None, + 'NEIGH_STATE_TABLE|ip_address_z': None + ... + } + """ + for key, value in data.items(): + if value is None: + # delete case + self.pipe.delete(key) + else: + # Add or Modify case + self.pipe.hmset(key, value) + self.pipe.execute() + data.clear() + + def update_neigh_states(self): + data = {} + for peer in self.new_peer_l: + key = "NEIGH_STATE_TABLE|%s" % peer + if peer in self.peer_l: + # only update the entry if state changed + if self.peer_state[peer] != self.new_peer_state[peer]: + # state changed. Update state DB for this entry + state = self.new_peer_state[peer] + data[key] = {'state':state} + self.peer_state[peer] = state + # remove this neighbor from old set since it is accounted for + self.peer_l.remove(peer) + else: + # New neighbor found case. Add to dictionary and state DB + state = self.new_peer_state[peer] + data[key] = {'state':state} + self.peer_state[peer] = state + if len(data) > PIPE_BATCH_MAX_COUNT: + self.flush_pipe(data) + # Check for stale state entries to be cleaned up + for peer in self.peer_l: + # remove this from the stateDB and the current neighbor state entry + del_key = "NEIGH_STATE_TABLE|%s" % peer + data[del_key] = None + if peer in self.peer_state: + del self.peer_state[peer] + if len(data) > PIPE_BATCH_MAX_COUNT: + self.flush_pipe(data) + # If anything in the pipeline not yet flushed, flush them now + if len(data) > 0: + self.flush_pipe(data) + # Save the new set + self.peer_l = self.new_peer_l.copy() + +def main(): + + syslog.syslog(syslog.LOG_INFO, "bgpmon service started") + bgp_state_get = None + try: + bgp_state_get = BgpStateGet() + except Exception as e: + syslog.syslog(syslog.LOG_ERR, "{}: error exit 1, reason {}".format("THIS_MODULE", str(e))) + exit(1) + + # periodically obtain the new neighbor information and update if necessary + while True: + time.sleep(15) + if bgp_state_get.bgp_activity_detected(): + bgp_state_get.get_all_neigh_states() + bgp_state_get.update_neigh_states() + +if __name__ == '__main__': + main() diff --git a/src/sonic-bgpcfgd/pytest.ini b/src/sonic-bgpcfgd/pytest.ini new file mode 100644 index 000000000000..a49b58e45f0f --- /dev/null +++ b/src/sonic-bgpcfgd/pytest.ini @@ -0,0 +1,2 @@ +[pytest] +addopts = --cov=bgpcfgd --cov-report term diff --git a/src/sonic-bgpcfgd/setup.cfg b/src/sonic-bgpcfgd/setup.cfg new file mode 100644 index 000000000000..00ed5efbcbad --- /dev/null +++ b/src/sonic-bgpcfgd/setup.cfg @@ -0,0 +1,5 @@ +[aliases] +test=pytest +[tool:pytest] +addopts = --verbose +python_files = tests/*.py diff --git a/src/sonic-bgpcfgd/setup.py b/src/sonic-bgpcfgd/setup.py new file mode 100755 index 000000000000..ab86ca20ec19 --- /dev/null +++ b/src/sonic-bgpcfgd/setup.py @@ -0,0 +1,31 @@ +import setuptools + +setuptools.setup( + name = 'sonic-bgpcfgd', + version = '1.0', + description = 'Utility to dynamically generate BGP configuration for FRR', + author = 'Pavel Shirshov', + author_email = 'pavelsh@microsoft.com', + url = 'https://github.com/Azure/sonic-buildimage', + packages = setuptools.find_packages(), + entry_points = { + 'console_scripts': [ + 'bgpcfgd = bgpcfgd.main:main', + 'bgpmon = bgpmon.bgpmon:main', + ] + }, + install_requires = [ + 'jinja2>=2.10', + 'netaddr==0.8.0', + 'pyyaml==5.4.1', + ], + setup_requires = [ + 'pytest-runner', + 'wheel' + ], + tests_require = [ + 'pytest', + 'pytest-cov', + 'sonic-config-engine' + ] +) diff --git a/src/sonic-bgpcfgd/tests/__init__.py b/src/sonic-bgpcfgd/tests/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/src/sonic-bgpcfgd/tests/data/dynamic/instance.conf/param_all.json b/src/sonic-bgpcfgd/tests/data/dynamic/instance.conf/param_all.json new file mode 100644 index 000000000000..c4134ff29806 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/dynamic/instance.conf/param_all.json @@ -0,0 +1,21 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "deployment_id": "5" + } + }, + "CONFIG_DB__LOOPBACK_INTERFACE": { + "Loopback1|55.55.55.55/32": {} + }, + "bgp_session": { + "ip_range": "10.10.20.0/24,20.20.20.0/24", + "name": "dyn_name", + "peer_asn": "11111", + "src_address": "1.1.1.1" + }, + "constants": { + "deployment_id_asn_map": { + "5": "51111" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/dynamic/instance.conf/param_base.json b/src/sonic-bgpcfgd/tests/data/dynamic/instance.conf/param_base.json new file mode 100644 index 000000000000..04fd24fa0819 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/dynamic/instance.conf/param_base.json @@ -0,0 +1,19 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "deployment_id": "5" + } + }, + "CONFIG_DB__LOOPBACK_INTERFACE": { + "Loopback1|55.55.55.55/32": {} + }, + "bgp_session": { + "ip_range": "10.10.20.0/24,20.20.20.0/24", + "name": "dyn_name" + }, + "constants": { + "deployment_id_asn_map": { + "5": "51111" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/dynamic/instance.conf/result_all.conf b/src/sonic-bgpcfgd/tests/data/dynamic/instance.conf/result_all.conf new file mode 100644 index 000000000000..1ffc3d34343e --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/dynamic/instance.conf/result_all.conf @@ -0,0 +1,22 @@ +! +! template: bgpd/templates/dynamic/instance.conf.j2 +! + neighbor dyn_name peer-group + neighbor dyn_name passive + neighbor dyn_name ebgp-multihop 255 + neighbor dyn_name soft-reconfiguration inbound + neighbor dyn_name route-map FROM_BGP_SPEAKER in + neighbor dyn_name route-map TO_BGP_SPEAKER out + neighbor dyn_name remote-as 11111 + bgp listen range 10.10.20.0/24 peer-group dyn_name + bgp listen range 20.20.20.0/24 peer-group dyn_name + neighbor dyn_name update-source 1.1.1.1 + address-family ipv4 + neighbor dyn_name activate + exit-address-family + address-family ipv6 + neighbor dyn_name activate + exit-address-family +! +! end of template: bgpd/templates/dynamic/instance.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/dynamic/instance.conf/result_base.conf b/src/sonic-bgpcfgd/tests/data/dynamic/instance.conf/result_base.conf new file mode 100644 index 000000000000..ac2a4f3e18d7 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/dynamic/instance.conf/result_base.conf @@ -0,0 +1,22 @@ +! +! template: bgpd/templates/dynamic/instance.conf.j2 +! + neighbor dyn_name peer-group + neighbor dyn_name passive + neighbor dyn_name ebgp-multihop 255 + neighbor dyn_name soft-reconfiguration inbound + neighbor dyn_name route-map FROM_BGP_SPEAKER in + neighbor dyn_name route-map TO_BGP_SPEAKER out + neighbor dyn_name remote-as 51111 + bgp listen range 10.10.20.0/24 peer-group dyn_name + bgp listen range 20.20.20.0/24 peer-group dyn_name + neighbor dyn_name update-source 55.55.55.55 + address-family ipv4 + neighbor dyn_name activate + exit-address-family + address-family ipv6 + neighbor dyn_name activate + exit-address-family +! +! end of template: bgpd/templates/dynamic/instance.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/dynamic/peer-group.conf/param_all.json b/src/sonic-bgpcfgd/tests/data/dynamic/peer-group.conf/param_all.json new file mode 100644 index 000000000000..0967ef424bce --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/dynamic/peer-group.conf/param_all.json @@ -0,0 +1 @@ +{} diff --git a/src/sonic-bgpcfgd/tests/data/dynamic/peer-group.conf/result_all.conf b/src/sonic-bgpcfgd/tests/data/dynamic/peer-group.conf/result_all.conf new file mode 100644 index 000000000000..86d5c0297227 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/dynamic/peer-group.conf/result_all.conf @@ -0,0 +1,7 @@ +! +! template: bgpd/templates/BGP_SPEAKER/peer-group.conf.j2 +! +! nothing is here +! +! end of template: bgpd/templates/BGP_SPEAKER/peer-group.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/dynamic/policies.conf/param_all.json b/src/sonic-bgpcfgd/tests/data/dynamic/policies.conf/param_all.json new file mode 100644 index 000000000000..0967ef424bce --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/dynamic/policies.conf/param_all.json @@ -0,0 +1 @@ +{} diff --git a/src/sonic-bgpcfgd/tests/data/dynamic/policies.conf/result_all.conf b/src/sonic-bgpcfgd/tests/data/dynamic/policies.conf/result_all.conf new file mode 100644 index 000000000000..17ca09ec2a36 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/dynamic/policies.conf/result_all.conf @@ -0,0 +1,9 @@ +! +! template: bgpd/templates/BGP_SPEAKER/policies.conf.j2 +! +route-map FROM_BGP_SPEAKER permit 10 +! +route-map TO_BGP_SPEAKER deny 1 +! +! end of template: bgpd/templates/BGP_SPEAKER/policies.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_all_v4.json b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_all_v4.json new file mode 100644 index 000000000000..4afd00f38da1 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_all_v4.json @@ -0,0 +1,18 @@ +{ + "neighbor_addr": "10.10.10.10", + "bgp_session": { + "asn": "555", + "name": "remote_peer", + "keepalive": "5", + "holdtime": "30", + "admin_status": "down", + "ASIC": "something", + "rrclient": "1", + "nhopself": "1" + }, + "constants": { + "deployment_id_asn_map": { + "5": "51111" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_all_v6.json b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_all_v6.json new file mode 100644 index 000000000000..115f5a32c941 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_all_v6.json @@ -0,0 +1,18 @@ +{ + "neighbor_addr": "fc::10", + "bgp_session": { + "asn": "555", + "name": "remote_peer", + "keepalive": "5", + "holdtime": "30", + "admin_status": "down", + "ASIC": "something", + "rrclient": "1", + "nhopself": "1" + }, + "constants": { + "deployment_id_asn_map": { + "5": "51111" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_base_v4.json b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_base_v4.json new file mode 100644 index 000000000000..e2e59575cbb3 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_base_v4.json @@ -0,0 +1,15 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": {} + }, + "neighbor_addr": "10.10.10.10", + "bgp_session": { + "asn": "555", + "name": "remote_peer" + }, + "constants": { + "deployment_id_asn_map": { + "5": "51111" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_base_v6.json b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_base_v6.json new file mode 100644 index 000000000000..5e79378e3e00 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_base_v6.json @@ -0,0 +1,15 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": {} + }, + "neighbor_addr": "fc00::2", + "bgp_session": { + "asn": "555", + "name": "remote_peer" + }, + "constants": { + "deployment_id_asn_map": { + "5": "51111" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_l2vpn.json b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_l2vpn.json new file mode 100644 index 000000000000..e679bff08435 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_l2vpn.json @@ -0,0 +1,18 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "type": "SpineChassisFrontendRouter" + } + }, + "neighbor_addr": "10.10.10.10", + "bgp_session": { + "asn": "555", + "name": "remote_peer" + }, + "constants": { + "deployment_id_asn_map": { + "5": "51111" + } + }, + "bgp_asn": "555" +} diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_shutdown_1.json b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_shutdown_1.json new file mode 100644 index 000000000000..b7c1e2075f02 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_shutdown_1.json @@ -0,0 +1,17 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "default_bgp_status": "down" + } + }, + "neighbor_addr": "10.10.10.10", + "bgp_session": { + "asn": "555", + "name": "remote_peer" + }, + "constants": { + "deployment_id_asn_map": { + "5": "51111" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_shutdown_2.json b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_shutdown_2.json new file mode 100644 index 000000000000..610254a2b2ba --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_shutdown_2.json @@ -0,0 +1,17 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "default_bgp_status": "up" + } + }, + "neighbor_addr": "10.10.10.10", + "bgp_session": { + "asn": "555", + "name": "remote_peer" + }, + "constants": { + "deployment_id_asn_map": { + "5": "51111" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_timers_1.json b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_timers_1.json new file mode 100644 index 000000000000..88d2b6defb2a --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_timers_1.json @@ -0,0 +1,16 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": {} + }, + "neighbor_addr": "10.10.10.10", + "bgp_session": { + "asn": "555", + "name": "remote_peer", + "keepalive": "5" + }, + "constants": { + "deployment_id_asn_map": { + "5": "51111" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_timers_2.json b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_timers_2.json new file mode 100644 index 000000000000..4b5c2bec220b --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/param_timers_2.json @@ -0,0 +1,16 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": {} + }, + "neighbor_addr": "10.10.10.10", + "bgp_session": { + "asn": "555", + "name": "remote_peer", + "holdtime": "240" + }, + "constants": { + "deployment_id_asn_map": { + "5": "51111" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_all_v4.conf b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_all_v4.conf new file mode 100644 index 000000000000..a6102cdb87a2 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_all_v4.conf @@ -0,0 +1,16 @@ +! +! template: bgpd/templates/general/instance.conf.j2 +! + neighbor 10.10.10.10 remote-as 555 + neighbor 10.10.10.10 description remote_peer + neighbor 10.10.10.10 timers 5 30 + neighbor 10.10.10.10 shutdown + address-family ipv4 + neighbor 10.10.10.10 peer-group PEER_V4 + neighbor 10.10.10.10 route-reflector-client + neighbor 10.10.10.10 next-hop-self + neighbor 10.10.10.10 activate + exit-address-family +! +! end of template: bgpd/templates/general/instance.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_all_v6.conf b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_all_v6.conf new file mode 100644 index 000000000000..aa06657d91a8 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_all_v6.conf @@ -0,0 +1,16 @@ +! +! template: bgpd/templates/general/instance.conf.j2 +! + neighbor fc::10 remote-as 555 + neighbor fc::10 description remote_peer + neighbor fc::10 timers 5 30 + neighbor fc::10 shutdown + address-family ipv6 + neighbor fc::10 peer-group PEER_V6 + neighbor fc::10 route-reflector-client + neighbor fc::10 next-hop-self + neighbor fc::10 activate + exit-address-family +! +! end of template: bgpd/templates/general/instance.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_base_v4.conf b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_base_v4.conf new file mode 100644 index 000000000000..2990d5aef7c7 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_base_v4.conf @@ -0,0 +1,12 @@ +! +! template: bgpd/templates/general/instance.conf.j2 +! + neighbor 10.10.10.10 remote-as 555 + neighbor 10.10.10.10 description remote_peer + address-family ipv4 + neighbor 10.10.10.10 peer-group PEER_V4 + neighbor 10.10.10.10 activate + exit-address-family +! +! end of template: bgpd/templates/general/instance.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_base_v6.conf b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_base_v6.conf new file mode 100644 index 000000000000..38ec714894ae --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_base_v6.conf @@ -0,0 +1,12 @@ +! +! template: bgpd/templates/general/instance.conf.j2 +! + neighbor fc00::2 remote-as 555 + neighbor fc00::2 description remote_peer + address-family ipv6 + neighbor fc00::2 peer-group PEER_V6 + neighbor fc00::2 activate + exit-address-family +! +! end of template: bgpd/templates/general/instance.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_l2vpn.conf b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_l2vpn.conf new file mode 100644 index 000000000000..b30eaaa62a35 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_l2vpn.conf @@ -0,0 +1,16 @@ +! +! template: bgpd/templates/general/instance.conf.j2 +! + neighbor 10.10.10.10 remote-as 555 + neighbor 10.10.10.10 description remote_peer + address-family ipv4 + neighbor 10.10.10.10 peer-group PEER_V4 + neighbor 10.10.10.10 activate + exit-address-family + address-family l2vpn evpn + neighbor 10.10.10.10 activate + advertise-all-vni + exit-address-family +! +! end of template: bgpd/templates/general/instance.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_shutdown_1.conf b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_shutdown_1.conf new file mode 100644 index 000000000000..9303e3b9ab7f --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_shutdown_1.conf @@ -0,0 +1,13 @@ +! +! template: bgpd/templates/general/instance.conf.j2 +! + neighbor 10.10.10.10 remote-as 555 + neighbor 10.10.10.10 description remote_peer + neighbor 10.10.10.10 shutdown + address-family ipv4 + neighbor 10.10.10.10 peer-group PEER_V4 + neighbor 10.10.10.10 activate + exit-address-family +! +! end of template: bgpd/templates/general/instance.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_shutdown_2.conf b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_shutdown_2.conf new file mode 100644 index 000000000000..2990d5aef7c7 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_shutdown_2.conf @@ -0,0 +1,12 @@ +! +! template: bgpd/templates/general/instance.conf.j2 +! + neighbor 10.10.10.10 remote-as 555 + neighbor 10.10.10.10 description remote_peer + address-family ipv4 + neighbor 10.10.10.10 peer-group PEER_V4 + neighbor 10.10.10.10 activate + exit-address-family +! +! end of template: bgpd/templates/general/instance.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_timers_1.conf b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_timers_1.conf new file mode 100644 index 000000000000..ffca0e6b69e6 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_timers_1.conf @@ -0,0 +1,13 @@ +! +! template: bgpd/templates/general/instance.conf.j2 +! + neighbor 10.10.10.10 remote-as 555 + neighbor 10.10.10.10 description remote_peer + neighbor 10.10.10.10 timers 5 180 + address-family ipv4 + neighbor 10.10.10.10 peer-group PEER_V4 + neighbor 10.10.10.10 activate + exit-address-family +! +! end of template: bgpd/templates/general/instance.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_timers_2.conf b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_timers_2.conf new file mode 100644 index 000000000000..3a8ac3d90e3f --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/instance.conf/result_timers_2.conf @@ -0,0 +1,13 @@ +! +! template: bgpd/templates/general/instance.conf.j2 +! + neighbor 10.10.10.10 remote-as 555 + neighbor 10.10.10.10 description remote_peer + neighbor 10.10.10.10 timers 60 240 + address-family ipv4 + neighbor 10.10.10.10 peer-group PEER_V4 + neighbor 10.10.10.10 activate + exit-address-family +! +! end of template: bgpd/templates/general/instance.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/param_all.json b/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/param_all.json new file mode 100644 index 000000000000..0820dd4050f9 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/param_all.json @@ -0,0 +1,10 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "type": "ToRRouter" + } + }, + "CONFIG_DB__BGP_BBR": { + "status": "enabled" + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/param_base.json b/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/param_base.json new file mode 100644 index 000000000000..efee873fe726 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/param_base.json @@ -0,0 +1,10 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "type": "LeafRouter" + } + }, + "CONFIG_DB__BGP_BBR": { + "status": "disabled" + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/result_all.conf b/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/result_all.conf new file mode 100644 index 000000000000..afa7201b742a --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/result_all.conf @@ -0,0 +1,20 @@ +! +! template: bgpd/templates/general/peer-group.conf.j2 +! + neighbor PEER_V4 peer-group + neighbor PEER_V6 peer-group + address-family ipv4 + neighbor PEER_V4 allowas-in 1 + neighbor PEER_V4 soft-reconfiguration inbound + neighbor PEER_V4 route-map FROM_BGP_PEER_V4 in + neighbor PEER_V4 route-map TO_BGP_PEER_V4 out + exit-address-family + address-family ipv6 + neighbor PEER_V6 allowas-in 1 + neighbor PEER_V6 soft-reconfiguration inbound + neighbor PEER_V6 route-map FROM_BGP_PEER_V6 in + neighbor PEER_V6 route-map TO_BGP_PEER_V6 out + exit-address-family +! +! end of template: bgpd/templates/general/peer-group.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/result_base.conf b/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/result_base.conf new file mode 100644 index 000000000000..3bef9fe4fdc2 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/peer-group.conf/result_base.conf @@ -0,0 +1,18 @@ +! +! template: bgpd/templates/general/peer-group.conf.j2 +! + neighbor PEER_V4 peer-group + neighbor PEER_V6 peer-group + address-family ipv4 + neighbor PEER_V4 soft-reconfiguration inbound + neighbor PEER_V4 route-map FROM_BGP_PEER_V4 in + neighbor PEER_V4 route-map TO_BGP_PEER_V4 out + exit-address-family + address-family ipv6 + neighbor PEER_V6 soft-reconfiguration inbound + neighbor PEER_V6 route-map FROM_BGP_PEER_V6 in + neighbor PEER_V6 route-map TO_BGP_PEER_V6 out + exit-address-family +! +! end of template: bgpd/templates/general/peer-group.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json new file mode 100644 index 000000000000..0e08c6a51d03 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json @@ -0,0 +1,12 @@ +{ + "loopback0_ipv4": "10.10.10.10/32", + "constants": { + "bgp": { + "allow_list": { + "enabled": true, + "drop_community": "12345:12345" + } + } + }, + "allow_list_default_action": "permit" +} diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json new file mode 100644 index 000000000000..b752581e3096 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json @@ -0,0 +1,10 @@ +{ + "loopback0_ipv4": "10.10.10.10/32", + "constants": { + "bgp": { + "allow_list": { + "enabled": false + } + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_deny.json b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_deny.json new file mode 100644 index 000000000000..b2799abfaa0f --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_deny.json @@ -0,0 +1,12 @@ +{ + "loopback0_ipv4": "10.10.10.10/32", + "constants": { + "bgp": { + "allow_list": { + "enabled": true, + "drop_community": "12345:12345" + } + } + }, + "allow_list_default_action": "deny" +} diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf new file mode 100644 index 000000000000..8d0c17d592b8 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf @@ -0,0 +1,44 @@ +! +! template: bgpd/templates/general/policies.conf.j2 +! +! please don't remove. 65535 entries are default rules +! which works when allow_list is enabled, but new configuration +! is not applied +! +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535 + set community 12345:12345 additive +! +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535 + set community 12345:12345 additive +! +bgp community-list standard allow_list_default_community permit no-export +bgp community-list standard allow_list_default_community permit 12345:12345 +! +route-map FROM_BGP_PEER_V4 permit 10 + call ALLOW_LIST_DEPLOYMENT_ID_0_V4 + on-match next +! +route-map FROM_BGP_PEER_V4 permit 11 + match community allow_list_default_community +! +route-map FROM_BGP_PEER_V6 permit 10 + call ALLOW_LIST_DEPLOYMENT_ID_0_V6 + on-match next +! +route-map FROM_BGP_PEER_V6 permit 11 + match community allow_list_default_community +! +route-map FROM_BGP_PEER_V4 permit 100 +! +route-map TO_BGP_PEER_V4 permit 100 +! +route-map FROM_BGP_PEER_V6 permit 1 + on-match next + set ipv6 next-hop prefer-global +! +route-map FROM_BGP_PEER_V6 permit 100 +! +route-map TO_BGP_PEER_V6 permit 100 +! +! end of template: bgpd/templates/general/policies.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_base.conf b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_base.conf new file mode 100644 index 000000000000..8f7631caabd8 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_base.conf @@ -0,0 +1,17 @@ +! +! template: bgpd/templates/general/policies.conf.j2 +! +route-map FROM_BGP_PEER_V4 permit 100 +! +route-map TO_BGP_PEER_V4 permit 100 +! +route-map FROM_BGP_PEER_V6 permit 1 + on-match next + set ipv6 next-hop prefer-global +! +route-map FROM_BGP_PEER_V6 permit 100 +! +route-map TO_BGP_PEER_V6 permit 100 +! +! end of template: bgpd/templates/general/policies.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_deny.conf b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_deny.conf new file mode 100644 index 000000000000..661414bd579c --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_deny.conf @@ -0,0 +1,44 @@ +! +! template: bgpd/templates/general/policies.conf.j2 +! +! please don't remove. 65535 entries are default rules +! which works when allow_list is enabled, but new configuration +! is not applied +! +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535 + set community no-export additive +! +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535 + set community no-export additive +! +bgp community-list standard allow_list_default_community permit no-export +bgp community-list standard allow_list_default_community permit 12345:12345 +! +route-map FROM_BGP_PEER_V4 permit 10 + call ALLOW_LIST_DEPLOYMENT_ID_0_V4 + on-match next +! +route-map FROM_BGP_PEER_V4 permit 11 + match community allow_list_default_community +! +route-map FROM_BGP_PEER_V6 permit 10 + call ALLOW_LIST_DEPLOYMENT_ID_0_V6 + on-match next +! +route-map FROM_BGP_PEER_V6 permit 11 + match community allow_list_default_community +! +route-map FROM_BGP_PEER_V4 permit 100 +! +route-map TO_BGP_PEER_V4 permit 100 +! +route-map FROM_BGP_PEER_V6 permit 1 + on-match next + set ipv6 next-hop prefer-global +! +route-map FROM_BGP_PEER_V6 permit 100 +! +route-map TO_BGP_PEER_V6 permit 100 +! +! end of template: bgpd/templates/general/policies.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/param_back_v4.json b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/param_back_v4.json new file mode 100644 index 000000000000..c2391674a56e --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/param_back_v4.json @@ -0,0 +1,23 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "sub_role": "BackEnd" + } + }, + "neighbor_addr": "10.10.10.10", + "bgp_session": { + "asn": "555", + "name": "remote_peer", + "keepalive": "5", + "holdtime": "30", + "admin_status": "down", + "ASIC": "something", + "rrclient": "1", + "nhopself": "1" + }, + "constants": { + "deployment_id_asn_map": { + "5": "51111" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/param_back_v6.json b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/param_back_v6.json new file mode 100644 index 000000000000..d19139a75a88 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/param_back_v6.json @@ -0,0 +1,23 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "sub_role": "BackEnd" + } + }, + "neighbor_addr": "fc::10", + "bgp_session": { + "asn": "555", + "name": "remote_peer", + "keepalive": "5", + "holdtime": "30", + "admin_status": "down", + "ASIC": "something", + "rrclient": "1", + "nhopself": "1" + }, + "constants": { + "deployment_id_asn_map": { + "5": "51111" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/param_front_v4.json b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/param_front_v4.json new file mode 100644 index 000000000000..6f1b5a735355 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/param_front_v4.json @@ -0,0 +1,21 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "sub_role": "FrontEnd" + } + }, + "neighbor_addr": "10.10.10.10", + "bgp_session": { + "asn": "555", + "name": "remote_peer", + "keepalive": "5", + "holdtime": "30", + "admin_status": "down", + "ASIC": "something" + }, + "constants": { + "deployment_id_asn_map": { + "5": "51111" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/param_front_v6.json b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/param_front_v6.json new file mode 100644 index 000000000000..becb1f00fbfe --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/param_front_v6.json @@ -0,0 +1,21 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "sub_role": "FrontEnd" + } + }, + "neighbor_addr": "fc::10", + "bgp_session": { + "asn": "555", + "name": "remote_peer", + "keepalive": "5", + "holdtime": "30", + "admin_status": "down", + "ASIC": "something" + }, + "constants": { + "deployment_id_asn_map": { + "5": "51111" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v4.conf b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v4.conf new file mode 100644 index 000000000000..fc7b82a64acc --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v4.conf @@ -0,0 +1,16 @@ +! +! template: bgpd/templates/internal/instance.conf.j2 +! + neighbor 10.10.10.10 remote-as 555 + neighbor 10.10.10.10 description remote_peer + neighbor 10.10.10.10 timers 3 10 + address-family ipv4 + neighbor 10.10.10.10 peer-group INTERNAL_PEER_V4 + neighbor 10.10.10.10 route-map FROM_BGP_INTERNAL_PEER_V4 in + neighbor 10.10.10.10 route-reflector-client + neighbor 10.10.10.10 next-hop-self force + neighbor 10.10.10.10 activate + exit-address-family +! +! end of template: bgpd/templates/internal/instance.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v6.conf b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v6.conf new file mode 100644 index 000000000000..74cececad969 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_back_v6.conf @@ -0,0 +1,16 @@ +! +! template: bgpd/templates/internal/instance.conf.j2 +! + neighbor fc::10 remote-as 555 + neighbor fc::10 description remote_peer + neighbor fc::10 timers 3 10 + address-family ipv6 + neighbor fc::10 peer-group INTERNAL_PEER_V6 + neighbor fc::10 route-map FROM_BGP_INTERNAL_PEER_V6 in + neighbor fc::10 route-reflector-client + neighbor fc::10 next-hop-self force + neighbor fc::10 activate + exit-address-family +! +! end of template: bgpd/templates/internal/instance.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v4.conf b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v4.conf new file mode 100644 index 000000000000..95eb985b1546 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v4.conf @@ -0,0 +1,14 @@ +! +! template: bgpd/templates/internal/instance.conf.j2 +! + neighbor 10.10.10.10 remote-as 555 + neighbor 10.10.10.10 description remote_peer + neighbor 10.10.10.10 timers 3 10 + address-family ipv4 + neighbor 10.10.10.10 peer-group INTERNAL_PEER_V4 + neighbor 10.10.10.10 next-hop-self force + neighbor 10.10.10.10 activate + exit-address-family +! +! end of template: bgpd/templates/internal/instance.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v6.conf b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v6.conf new file mode 100644 index 000000000000..a4a4648e4855 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/internal/instance.conf/result_front_v6.conf @@ -0,0 +1,14 @@ +! +! template: bgpd/templates/internal/instance.conf.j2 +! + neighbor fc::10 remote-as 555 + neighbor fc::10 description remote_peer + neighbor fc::10 timers 3 10 + address-family ipv6 + neighbor fc::10 peer-group INTERNAL_PEER_V6 + neighbor fc::10 next-hop-self force + neighbor fc::10 activate + exit-address-family +! +! end of template: bgpd/templates/internal/instance.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/internal/peer-group.conf/param_back.json b/src/sonic-bgpcfgd/tests/data/internal/peer-group.conf/param_back.json new file mode 100644 index 000000000000..c3269a7da0e5 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/internal/peer-group.conf/param_back.json @@ -0,0 +1,8 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "type": "LeafRouter", + "sub_role": "BackEnd" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/internal/peer-group.conf/param_front.json b/src/sonic-bgpcfgd/tests/data/internal/peer-group.conf/param_front.json new file mode 100644 index 000000000000..2fbedc92c963 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/internal/peer-group.conf/param_front.json @@ -0,0 +1,8 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "type": "LeafRouter", + "sub_role": "FrontEnd" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/internal/peer-group.conf/result_back.conf b/src/sonic-bgpcfgd/tests/data/internal/peer-group.conf/result_back.conf new file mode 100644 index 000000000000..15076685eb1a --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/internal/peer-group.conf/result_back.conf @@ -0,0 +1,20 @@ +! +! template: bgpd/templates/internal/peer-group.conf.j2 +! + neighbor INTERNAL_PEER_V4 peer-group + neighbor INTERNAL_PEER_V6 peer-group + address-family ipv4 + neighbor INTERNAL_PEER_V4 route-reflector-client + neighbor INTERNAL_PEER_V4 soft-reconfiguration inbound + neighbor INTERNAL_PEER_V4 route-map FROM_BGP_INTERNAL_PEER_V4 in + neighbor INTERNAL_PEER_V4 route-map TO_BGP_INTERNAL_PEER_V4 out + exit-address-family + address-family ipv6 + neighbor INTERNAL_PEER_V6 route-reflector-client + neighbor INTERNAL_PEER_V6 soft-reconfiguration inbound + neighbor INTERNAL_PEER_V6 route-map FROM_BGP_INTERNAL_PEER_V6 in + neighbor INTERNAL_PEER_V6 route-map TO_BGP_INTERNAL_PEER_V6 out + exit-address-family +! +! end of template: bgpd/templates/internal/peer-group.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/internal/peer-group.conf/result_front.conf b/src/sonic-bgpcfgd/tests/data/internal/peer-group.conf/result_front.conf new file mode 100644 index 000000000000..8f4aa450f5db --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/internal/peer-group.conf/result_front.conf @@ -0,0 +1,18 @@ +! +! template: bgpd/templates/internal/peer-group.conf.j2 +! + neighbor INTERNAL_PEER_V4 peer-group + neighbor INTERNAL_PEER_V6 peer-group + address-family ipv4 + neighbor INTERNAL_PEER_V4 soft-reconfiguration inbound + neighbor INTERNAL_PEER_V4 route-map FROM_BGP_INTERNAL_PEER_V4 in + neighbor INTERNAL_PEER_V4 route-map TO_BGP_INTERNAL_PEER_V4 out + exit-address-family + address-family ipv6 + neighbor INTERNAL_PEER_V6 soft-reconfiguration inbound + neighbor INTERNAL_PEER_V6 route-map FROM_BGP_INTERNAL_PEER_V6 in + neighbor INTERNAL_PEER_V6 route-map TO_BGP_INTERNAL_PEER_V6 out + exit-address-family +! +! end of template: bgpd/templates/internal/peer-group.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/internal/policies.conf/param_back.json b/src/sonic-bgpcfgd/tests/data/internal/policies.conf/param_back.json new file mode 100644 index 000000000000..148456fe960f --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/internal/policies.conf/param_back.json @@ -0,0 +1,8 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "sub_role": "BackEnd" + } + }, + "loopback0_ipv4": "10.10.10.10/32" +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/internal/policies.conf/param_front.json b/src/sonic-bgpcfgd/tests/data/internal/policies.conf/param_front.json new file mode 100644 index 000000000000..68c27766d257 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/internal/policies.conf/param_front.json @@ -0,0 +1,8 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "sub_role": "FrontkEnd" + } + }, + "loopback0_ipv4": "10.10.10.10/32" +} diff --git a/src/sonic-bgpcfgd/tests/data/internal/policies.conf/result_back.conf b/src/sonic-bgpcfgd/tests/data/internal/policies.conf/result_back.conf new file mode 100644 index 000000000000..81bf0808f77a --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/internal/policies.conf/result_back.conf @@ -0,0 +1,23 @@ +! +! template: bgpd/templates/internal/policies.conf.j2 +! +route-map FROM_BGP_INTERNAL_PEER_V4 permit 100 +! +route-map TO_BGP_INTERNAL_PEER_V4 permit 100 +! +route-map FROM_BGP_INTERNAL_PEER_V6 permit 1 + on-match next + set ipv6 next-hop prefer-global +! +route-map FROM_BGP_INTERNAL_PEER_V6 permit 100 +! +route-map TO_BGP_INTERNAL_PEER_V6 permit 100 +! +route-map FROM_BGP_INTERNAL_PEER_V4 permit 2 + set originator-id 10.10.10.10 +! +route-map FROM_BGP_INTERNAL_PEER_V6 permit 2 + set originator-id 10.10.10.10 +! +! end of template: bgpd/templates/internal/policies.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/internal/policies.conf/result_front.conf b/src/sonic-bgpcfgd/tests/data/internal/policies.conf/result_front.conf new file mode 100644 index 000000000000..94dc55a5458f --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/internal/policies.conf/result_front.conf @@ -0,0 +1,17 @@ +! +! template: bgpd/templates/internal/policies.conf.j2 +! +route-map FROM_BGP_INTERNAL_PEER_V4 permit 100 +! +route-map TO_BGP_INTERNAL_PEER_V4 permit 100 +! +route-map FROM_BGP_INTERNAL_PEER_V6 permit 1 + on-match next + set ipv6 next-hop prefer-global +! +route-map FROM_BGP_INTERNAL_PEER_V6 permit 100 +! +route-map TO_BGP_INTERNAL_PEER_V6 permit 100 +! +! end of template: bgpd/templates/internal/policies.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/monitors/instance.conf/param_all.json b/src/sonic-bgpcfgd/tests/data/monitors/instance.conf/param_all.json new file mode 100644 index 000000000000..9ac3ceda978a --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/monitors/instance.conf/param_all.json @@ -0,0 +1,12 @@ +{ + "bgp_asn": "555", + "neighbor_addr": "10.20.30.40", + "bgp_session": { + "name": "monitor" + }, + "constants": { + "deployment_id_asn_map": { + "5": "51111" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/monitors/instance.conf/result_all.conf b/src/sonic-bgpcfgd/tests/data/monitors/instance.conf/result_all.conf new file mode 100644 index 000000000000..c8faaa895bd7 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/monitors/instance.conf/result_all.conf @@ -0,0 +1,13 @@ +! +! template: bgpd/templates/monitors/instance.conf.j2 +! + neighbor 10.20.30.40 remote-as 555 + neighbor 10.20.30.40 peer-group BGPMON + neighbor 10.20.30.40 description monitor + neighbor 10.20.30.40 activate + address-family ipv6 + neighbor 10.20.30.40 activate + exit-address-family +! +! end of template: bgpd/templates/BGPMON/instance.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/monitors/peer-group.conf/param_all.json b/src/sonic-bgpcfgd/tests/data/monitors/peer-group.conf/param_all.json new file mode 100644 index 000000000000..4f45f8a0f3f4 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/monitors/peer-group.conf/param_all.json @@ -0,0 +1,3 @@ +{ + "loopback0_ipv4": "1.1.1.1/32" +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/monitors/peer-group.conf/result_all.conf b/src/sonic-bgpcfgd/tests/data/monitors/peer-group.conf/result_all.conf new file mode 100644 index 000000000000..d5e9624ff1a5 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/monitors/peer-group.conf/result_all.conf @@ -0,0 +1,12 @@ +! +! template: bgpd/templates/BGPMON/peer-group.conf.j2 +! + neighbor BGPMON peer-group + neighbor BGPMON update-source 1.1.1.1 + neighbor BGPMON route-map FROM_BGPMON in + neighbor BGPMON route-map TO_BGPMON out + neighbor BGPMON send-community + neighbor BGPMON maximum-prefix 1 +! +! end of template: bgpd/templates/BGPMON/peer-group.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/monitors/policies.conf/param_all.json b/src/sonic-bgpcfgd/tests/data/monitors/policies.conf/param_all.json new file mode 100644 index 000000000000..9e26dfeeb6e6 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/monitors/policies.conf/param_all.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/monitors/policies.conf/result_all.conf b/src/sonic-bgpcfgd/tests/data/monitors/policies.conf/result_all.conf new file mode 100644 index 000000000000..8d53991064de --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/monitors/policies.conf/result_all.conf @@ -0,0 +1,9 @@ +! +! template: bgpd/templates/BGPMON/policies.conf.j2 +! +route-map FROM_BGPMON deny 10 +! +route-map TO_BGPMON permit 10 +! +! end of template: bgpd/templates/BGPMON/policies.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.conf new file mode 100644 index 000000000000..43a65bd2dd61 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.conf @@ -0,0 +1,81 @@ +! +! template: bgpd/bgpd.conf.j2 +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/quagga/bgpd.conf.j2 with config DB data +! file: bgpd.conf +! +! template: common/daemons.common.conf.j2 +! +hostname new_hostname +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +agentx +! +! template: bgpd/bgpd.main.conf.j2 +! +! bgp multiple-instance +! +! BGP configuration +! +! TSA configuration +! +ip prefix-list PL_LoopbackV4 permit 55.55.55.55/32 +! +ipv6 prefix-list PL_LoopbackV6 permit fc00::/64 +! +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 5 permit 10.10.10.0/24 +! +ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 10 permit fc01::/64 +! +route-map HIDE_INTERNAL permit 10 + set community local-AS +! +router bgp 55555 +! + bgp log-neighbor-changes + no bgp default ipv4-unicast + no bgp ebgp-requires-policy +! + bgp bestpath as-path multipath-relax +! + bgp graceful-restart restart-time 480 + bgp graceful-restart + bgp graceful-restart preserve-fw-state +! + bgp router-id 55.55.55.55 +! + network 55.55.55.55/32 +! + address-family ipv6 + network fc00::1/64 + exit-address-family +! + network 10.10.10.1/24 + address-family ipv6 + network fc01::1/64 + exit-address-family +! + address-family ipv4 + redistribute connected route-map HIDE_INTERNAL + exit-address-family + address-family ipv6 + redistribute connected route-map HIDE_INTERNAL + exit-address-family +! + address-family ipv4 + maximum-paths 32 + exit-address-family + address-family ipv6 + maximum-paths 32 + exit-address-family +! +! end of template: bgpd/bgpd.main.conf.j2 +!! +! end of template: bgpd/bgpd.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.json new file mode 100644 index 000000000000..17e32589d84c --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.json @@ -0,0 +1,33 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "hostname": "new_hostname", + "bgp_asn": "55555", + "sub_role": "FrontEnd" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0|55.55.55.55/32": {}, + "Loopback0|fc00::1/128": {} + }, + "VLAN_INTERFACE": { + "Vlan10|10.10.10.1/24": {}, + "Vlan10|fc01::1/64": {} + }, + "constants": { + "bgp": { + "multipath_relax": { + "enabled": true + }, + "graceful_restart": { + "enabled": true, + "restart_time": 480 + }, + "maximum_paths": { + "enabled": true, + "ipv4": 32, + "ipv6": 32 + } + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.conf new file mode 100644 index 000000000000..4a749516fe18 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.conf @@ -0,0 +1,61 @@ +! +! template: bgpd/bgpd.main.conf.j2 +! +! bgp multiple-instance +! +! BGP configuration +! +! TSA configuration +! +ip prefix-list PL_LoopbackV4 permit 55.55.55.55/32 +! +ipv6 prefix-list PL_LoopbackV6 permit fc00::/64 +! +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 5 permit 10.10.10.0/24 +! +ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 10 permit fc01::/64 +! +route-map HIDE_INTERNAL permit 10 + set community local-AS +! +router bgp 55555 +! + bgp log-neighbor-changes + no bgp default ipv4-unicast + no bgp ebgp-requires-policy +! + bgp bestpath as-path multipath-relax +! + bgp graceful-restart restart-time 480 + bgp graceful-restart + bgp graceful-restart preserve-fw-state +! + bgp router-id 55.55.55.55 +! + network 55.55.55.55/32 +! + address-family ipv6 + network fc00::1/64 + exit-address-family +! + network 10.10.10.1/24 + address-family ipv6 + network fc01::1/64 + exit-address-family +! + address-family ipv4 + redistribute connected route-map HIDE_INTERNAL + exit-address-family + address-family ipv6 + redistribute connected route-map HIDE_INTERNAL + exit-address-family +! + address-family ipv4 + maximum-paths 32 + exit-address-family + address-family ipv6 + maximum-paths 32 + exit-address-family +! +! end of template: bgpd/bgpd.main.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.json new file mode 100644 index 000000000000..3d5d07d95f09 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.json @@ -0,0 +1,35 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "bgp_asn": "55555", + "sub_role": "FrontEnd" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0|55.55.55.55/32": {}, + "Loopback0|fc00::1/128": {} + }, + "VLAN_INTERFACE": { + "Vlan10|10.10.10.1/24": {}, + "Vlan10|fc01::1/64": {}, + "Vlan20": {"vnet_name": "Vnet1"}, + "Vlan20|20.20.20.1/24": {}, + "Vlan20|fd01::1/64": {} + }, + "constants": { + "bgp": { + "multipath_relax": { + "enabled": true + }, + "graceful_restart": { + "enabled": true, + "restart_time": 480 + }, + "maximum_paths": { + "enabled": true, + "ipv4": 32, + "ipv6": 32 + } + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/base.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/base.conf new file mode 100644 index 000000000000..77cc9d6fffd8 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/base.conf @@ -0,0 +1,23 @@ +! +! template: bgpd/bgpd.main.conf.j2 +! +! bgp multiple-instance +! +! BGP configuration +! +! TSA configuration +! +ip prefix-list PL_LoopbackV4 permit 55.55.55.55/32 +! +router bgp 55555 +! + bgp log-neighbor-changes + no bgp default ipv4-unicast + no bgp ebgp-requires-policy +! + bgp router-id 55.55.55.55 +! + network 55.55.55.55/32 +! +! end of template: bgpd/bgpd.main.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/base.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/base.json new file mode 100644 index 000000000000..692d4c78f0b9 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/base.json @@ -0,0 +1,19 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "bgp_asn": "55555", + "sub_role": "" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0|55.55.55.55/32": {}, + "Loopback1|fc00::1/128": {} + }, + "constants": { + "bgp": { + "multipath_relax": {}, + "graceful_restart": {}, + "maximum_paths": {} + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.conf new file mode 100644 index 000000000000..30fc479d6af8 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.conf @@ -0,0 +1,61 @@ +! +! template: bgpd/bgpd.main.conf.j2 +! +! bgp multiple-instance +! +! BGP configuration +! +! TSA configuration +! +ip prefix-list PL_LoopbackV4 permit 55.55.55.55/32 +! +ipv6 prefix-list PL_LoopbackV6 permit fc00::/64 +! +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 5 permit 10.10.10.0/24 +! +ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 10 permit fc01::/64 +! +route-map HIDE_INTERNAL permit 10 + set community local-AS +! +router bgp 55555 +! + bgp log-neighbor-changes + no bgp default ipv4-unicast + no bgp ebgp-requires-policy +! + bgp bestpath as-path multipath-relax +! + bgp graceful-restart restart-time 240 + bgp graceful-restart + bgp graceful-restart preserve-fw-state +! + bgp router-id 55.55.55.55 +! + network 55.55.55.55/32 +! + address-family ipv6 + network fc00::1/64 + exit-address-family +! + network 10.10.10.1/24 + address-family ipv6 + network fc01::1/64 + exit-address-family +! + address-family ipv4 + redistribute connected route-map HIDE_INTERNAL + exit-address-family + address-family ipv6 + redistribute connected route-map HIDE_INTERNAL + exit-address-family +! + address-family ipv4 + maximum-paths 64 + exit-address-family + address-family ipv6 + maximum-paths 64 + exit-address-family +! +! end of template: bgpd/bgpd.main.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.json new file mode 100644 index 000000000000..e841437650ac --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.json @@ -0,0 +1,32 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "bgp_asn": "55555", + "sub_role": "FrontEnd" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0|55.55.55.55/32": {}, + "Loopback0|fc00::1/128": {} + }, + "VLAN_INTERFACE": { + "Vlan10|10.10.10.1/24": {}, + "Vlan10|fc01::1/64": {}, + "Vlan20": {"vnet_name": "Vnet1"}, + "Vlan20|20.20.20.1/24": {}, + "Vlan20|fd01::1/64": {} + }, + "constants": { + "bgp": { + "multipath_relax": { + "enabled": true + }, + "graceful_restart": { + "enabled": true + }, + "maximum_paths": { + "enabled": true + } + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.conf new file mode 100644 index 000000000000..581eb107ec23 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.conf @@ -0,0 +1,39 @@ +! +! Vnet BGP instance +router bgp 555 vrf First + no bgp default ipv4-unicast + bgp log-neighbor-changes + bgp bestpath as-path multipath-relax + no bgp default ipv4-unicast + bgp graceful-restart restart-time 240 + bgp graceful-restart + bgp router-id 10.20.30.40 + neighbor 10.10.10.1 remote-as 10 + neighbor 10.10.10.1 description session1 + address-family ipv4 unicast + neighbor 10.10.10.1 activate + neighbor 10.10.10.1 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + address-family l2vpn evpn + advertise ipv4 unicast + exit-address-family +router bgp 555 vrf Second + no bgp default ipv4-unicast + bgp log-neighbor-changes + bgp bestpath as-path multipath-relax + no bgp default ipv4-unicast + bgp graceful-restart restart-time 240 + bgp graceful-restart + bgp router-id 10.20.30.40 + neighbor 20.20.20.1 remote-as 20 + neighbor 20.20.20.1 description session2 + address-family ipv4 unicast + neighbor 20.20.20.1 activate + neighbor 20.20.20.1 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + address-family l2vpn evpn + advertise ipv4 unicast + exit-address-family +! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.json new file mode 100644 index 000000000000..d6f09fb1139e --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.json @@ -0,0 +1,42 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "bgp_asn": "555" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0|10.20.30.40/32": {} + }, + "VNET": { + "First": { + "vni": 10 + }, + "Second": { + "vni": 20 + } + }, + "INTERFACE": { + "Ethernet0": { + "vnet_name": "First" + }, + "Ethernet0|10.10.10.10/24": {}, + "Ethernet8": { + "vnet_name": "Second" + }, + "Ethernet8|20.20.20.20/24": {}, + "Ethernet10": {}, + "Ethernet10|20.20.20.20/24": {} + }, + "BGP_NEIGHBOR": { + "10.10.10.1": { + "asn": "10", + "name": "session1", + "local_addr": "10.10.10.10" + }, + "20.20.20.1": { + "asn": "20", + "name": "session2", + "local_addr": "20.20.20.20" + } + } +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/daemons.common.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/daemons.common.conf new file mode 100644 index 000000000000..14d7b99d07ed --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/daemons.common.conf @@ -0,0 +1,10 @@ +! template: common/daemons.common.conf.j2 +! +hostname test_hostname +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2 diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/daemons.common.conf.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/daemons.common.conf.json new file mode 100644 index 000000000000..8ef3e43694a7 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/daemons.common.conf.json @@ -0,0 +1,7 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "hostname": "test_hostname" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/functions.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/functions.conf new file mode 100644 index 000000000000..8b137891791f --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/functions.conf @@ -0,0 +1 @@ + diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/functions.conf.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/functions.conf.json new file mode 100644 index 000000000000..9e26dfeeb6e6 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/functions.conf.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf new file mode 100644 index 000000000000..37b7691ad95f --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf @@ -0,0 +1,103 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/frr.conf.j2 with config DB data +! file: frr.conf +! +! template: common/daemons.common.conf.j2 +! +hostname test_hostname +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +agentx +! +! Enable nht through default route +ip nht resolve-via-default +! Enable link-detect (default disabled) +interface Ethernet0 +link-detect +! +interface Ethernet4 +link-detect +! +interface PortChannel10 +link-detect +! +interface PortChannel20 +link-detect +! +!! +! +! set static default route to mgmt gateway as a backup to learned default +ip route 0.0.0.0/0 10.10.10.1 200 +!! +! +! +! add static ipv6 /64 loopback route to allow bgpd to advertise the loopback route prefix +ipv6 route fc00::/64 Loopback0 +! +!! +! template: bgpd/bgpd.main.conf.j2 +! +! bgp multiple-instance +! +! BGP configuration +! +! TSA configuration +! +ip prefix-list PL_LoopbackV4 permit 55.55.55.55/32 +! +ipv6 prefix-list PL_LoopbackV6 permit fc00::/64 +! +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 5 permit 10.10.10.0/24 +! +ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 10 permit fc01::/64 +! +route-map HIDE_INTERNAL permit 10 + set community local-AS +! +router bgp 55555 +! + bgp log-neighbor-changes + no bgp default ipv4-unicast + no bgp ebgp-requires-policy +! + bgp bestpath as-path multipath-relax +! + bgp graceful-restart restart-time 480 + bgp graceful-restart + bgp graceful-restart preserve-fw-state +! + bgp router-id 55.55.55.55 +! + network 55.55.55.55/32 +! + address-family ipv6 + network fc00::1/64 + exit-address-family +! + network 10.10.10.1/24 + address-family ipv6 + network fc01::1/64 + exit-address-family +! + address-family ipv4 + redistribute connected route-map HIDE_INTERNAL + exit-address-family + address-family ipv6 + redistribute connected route-map HIDE_INTERNAL + exit-address-family +! + address-family ipv4 + maximum-paths 32 + exit-address-family + address-family ipv6 + maximum-paths 32 + exit-address-family +! +! end of template: bgpd/bgpd.main.conf.j2 +!! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.json new file mode 100644 index 000000000000..d81eba2b0fe6 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.json @@ -0,0 +1,46 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "bgp_asn": "55555", + "hostname": "test_hostname", + "sub_role": "FrontEnd" + } + }, + "INTERFACE": { + "Ethernet0|10.20.30.40/24": {}, + "Ethernet4|20.20.30.40/24": {} + }, + "PORTCHANNEL": { + "PortChannel10": {}, + "PortChannel20": {} + }, + "MGMT_INTERFACE": { + "eth0|10.10.10.10/24": { + "gwaddr": "10.10.10.1" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0|55.55.55.55/32": {}, + "Loopback0|fc00::1/128": {} + }, + "VLAN_INTERFACE": { + "Vlan10|10.10.10.1/24": {}, + "Vlan10|fc01::1/64": {} + }, + "constants": { + "bgp": { + "multipath_relax": { + "enabled": true + }, + "graceful_restart": { + "enabled": true, + "restart_time": 480 + }, + "maximum_paths": { + "enabled": true, + "ipv4": 32, + "ipv6": 32 + } + } + } +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/isolate b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/isolate new file mode 100644 index 000000000000..74f107495298 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/isolate @@ -0,0 +1,17 @@ +#!/bin/bash +## vtysh only accepts script in stdin, so cannot be directly used in shebang +## Cut the tail of this script and feed vtysh stdin +sed -n -e '9,$p' < "$0" | vtysh "$@" +## Exit with vtysh return code +exit $? +## vtysh script start from next line, which line number MUST equal in 'sed' command above +configure terminal + router bgp 12345 + neighbor 10.20.30.40 route-map ISOLATE out + address-family ipv6 + neighbor fc00::1 route-map ISOLATE out + exit-address-family + exit +exit +clear ip bgp 10.20.30.40 soft out +clear ip bgp fc00::1 soft out diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/isolate.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/isolate.json new file mode 100644 index 000000000000..012b69ef3036 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/isolate.json @@ -0,0 +1,11 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "bgp_asn": "12345" + } + }, + "BGP_NEIGHBOR": { + "10.20.30.40": {}, + "fc00::1": {} + } +} diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/unisolate b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/unisolate new file mode 100644 index 000000000000..b9476d0b7107 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/unisolate @@ -0,0 +1,17 @@ +#!/bin/bash +## vtysh only accepts script in stdin, so cannot be directly used in shebang +## Cut the tail of this script and feed vtysh stdin +sed -n -e '9,$p' < "$0" | vtysh "$@" +## Exit with vtysh return code +exit $? +## vtysh script start from next line, which line number MUST equal in 'sed' command above +configure terminal + router bgp 12345 + no neighbor 10.20.30.40 route-map ISOLATE out + address-family ipv6 + no neighbor fc00::1 route-map ISOLATE out + exit-address-family + exit +exit +clear ip bgp 10.20.30.40 soft out +clear ip bgp fc00::1 soft out diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/unisolate.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/unisolate.json new file mode 100644 index 000000000000..012b69ef3036 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/unisolate.json @@ -0,0 +1,11 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "bgp_asn": "12345" + } + }, + "BGP_NEIGHBOR": { + "10.20.30.40": {}, + "fc00::1": {} + } +} diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.conf new file mode 100644 index 000000000000..59bbe983af76 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.conf @@ -0,0 +1,23 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/frr/staticd.conf.j2 using config DB data +! file: staticd.conf +! +! template: common/daemons.common.conf.j2 +! +hostname new_hostname +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +! +! set static default route to mgmt gateway as a backup to learned default +ip route 0.0.0.0/0 10.10.10.1 200 +!! +! +! add static ipv6 /64 loopback route to allow bgpd to advertise the loopback route prefix +ipv6 route fc00:1::/64 Loopback0 +!! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.conf.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.conf.json new file mode 100644 index 000000000000..0cbd67c7ef68 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.conf.json @@ -0,0 +1,15 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "hostname": "new_hostname" + } + }, + "MGMT_INTERFACE": { + "eth0|10.10.10.10/24": { + "gwaddr": "10.10.10.1" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0|FC00:1::32/128": {} + } +} diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.default_route.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.default_route.conf new file mode 100644 index 000000000000..11adb98ebc3c --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.default_route.conf @@ -0,0 +1,4 @@ +! +! set static default route to mgmt gateway as a backup to learned default +ip route 0.0.0.0/0 10.10.10.1 200 +! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.default_route.conf.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.default_route.conf.json new file mode 100644 index 000000000000..80cd218a790e --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.default_route.conf.json @@ -0,0 +1,7 @@ +{ + "MGMT_INTERFACE": { + "eth0|10.10.10.10/24": { + "gwaddr": "10.10.10.1" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.loopback_route.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.loopback_route.conf new file mode 100644 index 000000000000..27078305d461 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.loopback_route.conf @@ -0,0 +1,4 @@ +! +! add static ipv6 /64 loopback route to allow bgpd to advertise the loopback route prefix +ipv6 route fc00:1::/64 Loopback0 +!! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.loopback_route.conf.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.loopback_route.conf.json new file mode 100644 index 000000000000..ffd3c2a2a117 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.loopback_route.conf.json @@ -0,0 +1,5 @@ +{ + "LOOPBACK_INTERFACE": { + "Loopback0|FC00:1::32/128": {} + } +} diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/isolate.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/isolate.conf new file mode 100644 index 000000000000..2ea4111dfc26 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/isolate.conf @@ -0,0 +1,5 @@ +route-map test_rm_name permit 20 + match ip address prefix-list PL_LoopbackV4 + set community 12345:555 +route-map test_rm_name deny 30 +! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/isolate.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/isolate.json new file mode 100644 index 000000000000..807dfe7e1a0c --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/isolate.json @@ -0,0 +1,10 @@ +{ + "constants": { + "bgp": { + "traffic_shift_community": "12345:555" + } + }, + "route_map_name": "test_rm_name", + "ip_version": "V4", + "ip_protocol": "ip" +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/unisolate.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/unisolate.conf new file mode 100644 index 000000000000..2adeac6e0ef7 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/unisolate.conf @@ -0,0 +1,3 @@ +no route-map test_rm permit 20 +no route-map test_rm deny 30 +! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/unisolate.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/unisolate.json new file mode 100644 index 000000000000..da070431493d --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/unisolate.json @@ -0,0 +1,3 @@ +{ + "route_map_name": "test_rm" +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.conf new file mode 100644 index 000000000000..ddd129bcd18b --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.conf @@ -0,0 +1,16 @@ +! +! Enable nht through default route +ip nht resolve-via-default +! Enable link-detect (default disabled) +interface Ethernet0 +link-detect +! +interface Ethernet4 +link-detect +! +interface PortChannel10 +link-detect +! +interface PortChannel20 +link-detect +! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.json new file mode 100644 index 000000000000..e9c1bcba418d --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.json @@ -0,0 +1,10 @@ +{ + "INTERFACE": { + "Ethernet0|10.20.30.40/24": {}, + "Ethernet4|20.20.30.40/24": {} + }, + "PORTCHANNEL": { + "PortChannel10": {}, + "PortChannel20": {} + } +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/set_src.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/set_src.conf new file mode 100644 index 000000000000..b543d24e0023 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/set_src.conf @@ -0,0 +1,8 @@ +! +! Set ip source to loopback for bgp learned routes +! +route-map new_rm_name permit 10 + set src 10.20.30.40 +! +ipv4 protocol bgp route-map new_rm_name +! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/set_src.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/set_src.json new file mode 100644 index 000000000000..2e76d46fd106 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/set_src.json @@ -0,0 +1,5 @@ +{ + "rm_name": "new_rm_name", + "lo_ip": "10.20.30.40", + "ip_proto": "v4" +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf new file mode 100644 index 000000000000..ac2d8dac88f2 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf @@ -0,0 +1,38 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/zebra/zebra.conf.j2 using config DB data +! file: zebra.conf +! +! template: common/daemons.common.conf.j2 +! +hostname new_hostname +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +! +vrf First +vni 10 +! +vrf Second +vni 20 +! +! Enable nht through default route +ip nht resolve-via-default +! Enable link-detect (default disabled) +interface Ethernet0 +link-detect +! +interface Ethernet4 +link-detect +! +interface PortChannel10 +link-detect +! +interface PortChannel20 +link-detect +! +!! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf.json new file mode 100644 index 000000000000..9b63ff526fb9 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf.json @@ -0,0 +1,23 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "hostname": "new_hostname" + } + }, + "VNET": { + "First": { + "vni": 10 + }, + "Second": { + "vni": 20 + } + }, + "INTERFACE": { + "Ethernet0|10.20.30.40/24": {}, + "Ethernet4|20.20.30.40/24": {} + }, + "PORTCHANNEL": { + "PortChannel10": {}, + "PortChannel20": {} + } +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/swsscommon_test.py b/src/sonic-bgpcfgd/tests/swsscommon_test.py new file mode 100644 index 000000000000..46984bafc609 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/swsscommon_test.py @@ -0,0 +1,4 @@ +from unittest.mock import MagicMock + + +swsscommon = MagicMock(CFG_DEVICE_METADATA_TABLE_NAME = "DEVICE_METADATA") diff --git a/src/sonic-bgpcfgd/tests/test_allow_list.py b/src/sonic-bgpcfgd/tests/test_allow_list.py new file mode 100644 index 000000000000..cb0896982a39 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/test_allow_list.py @@ -0,0 +1,959 @@ +from unittest.mock import MagicMock, patch + +import bgpcfgd.frr +from bgpcfgd.directory import Directory +from bgpcfgd.template import TemplateFabric +import bgpcfgd +from copy import deepcopy + + +swsscommon_module_mock = MagicMock() + +global_constants = { + "bgp": { + "allow_list": { + "enabled": True, + "default_pl_rules": { + "v4": [ "deny 0.0.0.0/0 le 17" ], + "v6": [ + "deny 0::/0 le 59", + "deny 0::/0 ge 65" + ] + }, + "default_action": "permit", + "drop_community": "123:123" + } + } +} + +@patch.dict("sys.modules", swsscommon=swsscommon_module_mock) +def set_del_test(op, args, currect_config, expected_config, update_global_default_action=None): + from bgpcfgd.managers_allow_list import BGPAllowListMgr + set_del_test.push_list_called = False + def push_list(args): + set_del_test.push_list_called = True + assert args == expected_config + return True + # + bgpcfgd.frr.run_command = lambda cmd: (0, "", "") + # + cfg_mgr = MagicMock() + cfg_mgr.update.return_value = None + cfg_mgr.push_list = push_list + cfg_mgr.get_text.return_value = currect_config + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': deepcopy(global_constants), + } + + mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") + if update_global_default_action: + mgr.constants["bgp"]["allow_list"]["default_action"] = update_global_default_action + if op == "SET": + mgr.set_handler(*args) + elif op == "DEL": + mgr.del_handler(*args) + else: + assert False, "Wrong operation" + if expected_config: + assert set_del_test.push_list_called, "cfg_mgr.push_list wasn't called" + else: + assert not set_del_test.push_list_called, "cfg_mgr.push_list was called" + +def test_set_handler_with_community(): + set_del_test( + "SET", + ("DEPLOYMENT_ID|5|1010:2020", { + "prefixes_v4": "10.20.30.0/24,30.50.0.0/16", + "prefixes_v6": "fc00:20::/64,fc00:30::/64", + }), + [ + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 65535', + ' set community 123:123 additive', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 65535', + ' set community 123:123 additive' + ], + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 le 32', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 le 32', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 le 128', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 le 128', + 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + ] + ) +def test_set_handler_with_community_and_permit_action(): + set_del_test( + "SET", + ("DEPLOYMENT_ID|5|1010:2020", { + "prefixes_v4": "10.20.30.0/24,30.50.0.0/16", + "prefixes_v6": "fc00:20::/64,fc00:30::/64", + "default_action":"permit" + }), + [ + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 65535', + ' set community 123:123 additive', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 65535', + ' set community 123:123 additive' + ], + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 le 32', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 le 32', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 le 128', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 le 128', + 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + ] + ) + +def test_set_handler_with_community_and_deny_action(): + set_del_test( + "SET", + ("DEPLOYMENT_ID|5|1010:2020", { + "prefixes_v4": "10.20.30.0/24,30.50.0.0/16", + "prefixes_v6": "fc00:20::/64,fc00:30::/64", + "default_action":"deny" + }), + [ + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 65535', + ' set community 123:123 additive', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 65535', + ' set community 123:123 additive' + ], + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 le 32', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 le 32', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 le 128', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 le 128', + 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 65535', + ' set community no-export additive', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 65535', + ' set community no-export additive' + ] + ) + + +def test_set_handler_no_community(): + set_del_test( + "SET", + ("DEPLOYMENT_ID|5", { + "prefixes_v4": "20.20.30.0/24,40.50.0.0/16", + "prefixes_v6": "fc01:20::/64,fc01:30::/64", + }), + [ + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 65535', + ' set community 123:123 additive', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 65535', + ' set community 123:123 additive', + ], + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 le 32', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 le 32', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 le 128', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 le 128', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + ] + ) +def test_set_handler_no_community_with_permit_action(): + set_del_test( + "SET", + ("DEPLOYMENT_ID|5", { + "prefixes_v4": "20.20.30.0/24,40.50.0.0/16", + "prefixes_v6": "fc01:20::/64,fc01:30::/64", + "default_action":"permit" + }), + [ + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 65535', + ' set community 123:123 additive', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 65535', + ' set community 123:123 additive', + ], + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 le 32', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 le 32', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 le 128', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 le 128', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + ] + ) +def test_set_handler_no_community_with_deny_action(): + set_del_test( + "SET", + ("DEPLOYMENT_ID|5", { + "prefixes_v4": "20.20.30.0/24,40.50.0.0/16", + "prefixes_v6": "fc01:20::/64,fc01:30::/64", + "default_action":"deny" + }), + [ + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 65535', + ' set community 123:123 additive', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 65535', + ' set community 123:123 additive', + ], + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 le 32', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 le 32', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 le 128', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 le 128', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 65535', + ' set community no-export additive', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 65535', + ' set community no-export additive' + ] + ) + +def test_del_handler_with_community(): + set_del_test( + "DEL", + ("DEPLOYMENT_ID|5|1010:2020",), + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', + 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 65535', + ' set community 123:123 additive', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 65535', + ' set community 123:123 additive', + + "" + ], + [ + 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + 'no bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + ] + ) + +def test_del_handler_with_exiting_community_deny_action(): + set_del_test( + "DEL", + ("DEPLOYMENT_ID|5|1010:2020",), + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', + 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 65535', + ' set community no-export additive', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 65535', + ' set community no-export additive', + "" + ], + [ + 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + 'no bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 65535', + ' set community 123:123 additive', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 65535', + ' set community 123:123 additive', + ] + ) + + +def test_del_handler_with_exiting_community_permit_action(): + set_del_test( + "DEL", + ("DEPLOYMENT_ID|5|1010:2020",), + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', + 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 65535', + ' set community 123:123 additive', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 65535', + ' set community 123:123 additive', + "" + ], + [ + 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + 'no bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + ] + ) + +def test_del_handler_with_exiting_community_deny_action_global_deny(): + set_del_test( + "DEL", + ("DEPLOYMENT_ID|5|1010:2020",), + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', + 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 65535', + ' set community no-export additive', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 65535', + ' set community no-export additive', + "" + ], + [ + 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + 'no bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + ], + "deny" + ) + + +def test_del_handler_with_exiting_community_permit_action_global_deny(): + set_del_test( + "DEL", + ("DEPLOYMENT_ID|5|1010:2020",), + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', + 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 65535', + ' set community 123:123 additive', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 65535', + ' set community 123:123 additive', + "" + ], + [ + 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + 'no bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 65535', + ' set community no-export additive', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 65535', + ' set community no-export additive', + ], + "deny" + ) + + +def test_del_handler_no_community(): + set_del_test( + "DEL", + ("DEPLOYMENT_ID|5",), + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 65535', + ' set community 123:123 additive', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 65535', + ' set community 123:123 additive', + " " + ], + [ + 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', + 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', + 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + ] + ) +def test_del_handler_with_no_community_deny_action(): + set_del_test( + "DEL", + ("DEPLOYMENT_ID|5",), + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 65535', + ' set community no-export additive', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 65535', + ' set community no-export additive', + "" + ], + [ + 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', + 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', + 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 65535', + ' set community 123:123 additive', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 65535', + ' set community 123:123 additive', + ] + ) +def test_del_handler_with_no_community_permit_action_global_deny(): + set_del_test( + "DEL", + ("DEPLOYMENT_ID|5",), + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 65535', + ' set community 123:123 additive', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 65535', + ' set community 123:123 additive', + "" + ], + [ + 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', + 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', + 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 65535', + ' set community no-export additive', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 65535', + ' set community no-export additive', + ], + "deny" + ) + + + +def test_set_handler_with_community_data_is_already_presented(): + set_del_test( + "SET", + ("DEPLOYMENT_ID|5|1010:2020", { + "prefixes_v4": "10.20.30.0/24,30.50.0.0/16", + "prefixes_v6": "fc00:20::/64,fc00:30::/64", + }), + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 le 32', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 le 32', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 le 128', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 le 128', + 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 65535', + ' set community 123:123 additive', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 65535', + ' set community 123:123 additive', + "" + ], + [] + ) + +@patch.dict("sys.modules", swsscommon=swsscommon_module_mock) +def test_set_handler_no_community_data_is_already_presented(): + from bgpcfgd.managers_allow_list import BGPAllowListMgr + cfg_mgr = MagicMock() + cfg_mgr.update.return_value = None + cfg_mgr.get_text.return_value = [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 le 32', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 le 32', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 le 128', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 le 128', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 65535', + ' set community 123:123 additive', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 65535', + ' set community 123:123 additive', + "" + ] + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") + mgr.set_handler("DEPLOYMENT_ID|5", { + "prefixes_v4": "20.20.30.0/24,40.50.0.0/16", + "prefixes_v6": "fc01:20::/64,fc01:30::/64", + }) + assert not cfg_mgr.push_list.called, "cfg_mgr.push_list was called, but it shouldn't have been" + +def test_del_handler_with_community_no_data(): + set_del_test( + "DEL", + ("DEPLOYMENT_ID|5|1010:2020",), + [ + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 65535', + ' set community 123:123 additive', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 65535', + ' set community 123:123 additive' + ], + [] + ) + +def test_del_handler_no_community_no_data(): + set_del_test( + "DEL", + ("DEPLOYMENT_ID|5",), + [ + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 65535', + ' set community 123:123 additive', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 65535', + ' set community 123:123 additive' + ], + [] + ) + +def test_set_handler_with_community_update_prefixes_add(): + set_del_test( + "SET", + ("DEPLOYMENT_ID|5|1010:2020", { + "prefixes_v4": "10.20.30.0/24,30.50.0.0/16,80.90.0.0/16", + "prefixes_v6": "fc00:20::/64,fc00:30::/64,fc02::/64", + }), + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 le 32', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 le 32', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 le 128', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 le 128', + 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 65535', + ' set community 123:123 additive', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 65535', + ' set community 123:123 additive', + "" + ], + [ + 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 le 32', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 le 32', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 40 permit 80.90.0.0/16 le 32', + 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 le 128', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 le 128', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 50 permit fc02::/64 le 128', + ] + ) + +def test_set_handler_no_community_update_prefixes_add(): + set_del_test( + "SET", + ("DEPLOYMENT_ID|5", { + "prefixes_v4": "20.20.30.0/24,40.50.0.0/16,80.90.0.0/16", + "prefixes_v6": "fc01:20::/64,fc01:30::/64,fc02::/64", + }), + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 le 32', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 le 32', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 le 128', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 le 128', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 65535', + ' set community 123:123 additive', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 65535', + ' set community 123:123 additive', + "" + ], + [ + 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 le 32', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 le 32', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 40 permit 80.90.0.0/16 le 32', + 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 le 128', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 le 128', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 50 permit fc02::/64 le 128', + ] + ) + +@patch.dict("sys.modules", swsscommon=swsscommon_module_mock) +def test___set_handler_validate(): + from bgpcfgd.managers_allow_list import BGPAllowListMgr + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") + data = { + "prefixes_v4": "20.20.30.0/24,40.50.0.0/16", + "prefixes_v6": "fc01:20::/64,fc01:30::/64", + } + assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID|5|1010:2020", None) + assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID1|5|1010:2020", data) + assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID|z|1010:2020", data) + assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID|5|1010:2020", { + "prefixes_v4": "20.20.30.0/24,40.50.0.0/16", + "prefixes_v6": "20.20.30.0/24,40.50.0.0/16", + }) + assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID|5|1010:2020", { + "prefixes_v4": "fc01:20::/64,fc01:30::/64", + "prefixes_v6": "fc01:20::/64,fc01:30::/64", + }) + +@patch.dict("sys.modules", swsscommon=swsscommon_module_mock) +def test___find_peer_group_by_deployment_id(): + from bgpcfgd.managers_allow_list import BGPAllowListMgr + cfg_mgr = MagicMock() + cfg_mgr.update.return_value = None + cfg_mgr.get_text.return_value = [ + 'router bgp 64601', + ' neighbor BGPSLBPassive peer-group', + ' neighbor BGPSLBPassive remote-as 65432', + ' neighbor BGPSLBPassive passive', + ' neighbor BGPSLBPassive ebgp-multihop 255', + ' neighbor BGPSLBPassive update-source 10.1.0.32', + ' neighbor PEER_V4 peer-group', + ' neighbor PEER_V4_INT peer-group', + ' neighbor PEER_V6 peer-group', + ' neighbor PEER_V6_INT peer-group', + ' neighbor 10.0.0.1 remote-as 64802', + ' neighbor 10.0.0.1 peer-group PEER_V4', + ' neighbor 10.0.0.1 description ARISTA01T1', + ' neighbor 10.0.0.1 timers 3 10', + ' neighbor fc00::2 remote-as 64802', + ' neighbor fc00::2 peer-group PEER_V6', + ' neighbor fc00::2 description ARISTA01T1', + ' neighbor fc00::2 timers 3 10', + ' address-family ipv4 unicast', + ' neighbor BGPSLBPassive activate', + ' neighbor BGPSLBPassive soft-reconfiguration inbound', + ' neighbor BGPSLBPassive route-map FROM_BGP_SPEAKER in', + ' neighbor BGPSLBPassive route-map TO_BGP_SPEAKER out', + ' neighbor PEER_V4 soft-reconfiguration inbound', + ' neighbor PEER_V4 allowas-in 1', + ' neighbor PEER_V4 route-map FROM_BGP_PEER_V4 in', + ' neighbor PEER_V4 route-map TO_BGP_PEER_V4 out', + ' neighbor PEER_V4_INT soft-reconfiguration inbound', + ' neighbor PEER_V4_INT allowas-in 1', + ' neighbor PEER_V4_INT route-map FROM_BGP_PEER_V4 in', + ' neighbor PEER_V4_INT route-map TO_BGP_PEER_V4 out', + ' neighbor 10.0.0.1 activate', + ' exit-address-family', + ' address-family ipv6 unicast', + ' neighbor BGPSLBPassive activate', + ' neighbor PEER_V6 soft-reconfiguration inbound', + ' neighbor PEER_V6 allowas-in 1', + ' neighbor PEER_V6 route-map FROM_BGP_PEER_V6 in', + ' neighbor PEER_V6 route-map TO_BGP_PEER_V6 out', + ' neighbor PEER_V6_INT soft-reconfiguration inbound', + ' neighbor PEER_V6_INT allowas-in 1', + ' neighbor PEER_V6_INT route-map FROM_BGP_PEER_V6 in', + ' neighbor PEER_V6_INT route-map TO_BGP_PEER_V6 out', + ' neighbor fc00::2 activate', + ' exit-address-family', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 10', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 30000', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_empty_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535', + ' set community 5060:12345 additive', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 10', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010_V6', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 30000', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_empty_V6', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535', + ' set community 5060:12345 additive', + 'route-map FROM_BGP_PEER_V4 permit 100', + 'route-map FROM_BGP_PEER_V4 permit 2', + ' call ALLOW_LIST_DEPLOYMENT_ID_0_V4', + ' on-match next', + 'route-map FROM_BGP_PEER_V6 permit 1', + ' set ipv6 next-hop prefer-global ', + 'route-map FROM_BGP_PEER_V6 permit 100', + 'route-map FROM_BGP_PEER_V6 permit 2', + ' call ALLOW_LIST_DEPLOYMENT_ID_0_V6', + ' on-match next', + 'route-map FROM_BGP_SPEAKER permit 10', + 'route-map RM_SET_SRC permit 10', + ' set src 10.1.0.32', + 'route-map RM_SET_SRC6 permit 10', + ' set src FC00:1::32', + 'route-map TO_BGP_PEER_V4 permit 100', + 'route-map TO_BGP_PEER_V6 permit 100', + 'route-map TO_BGP_SPEAKER deny 1', + ] + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") + values = mgr._BGPAllowListMgr__find_peer_group_by_deployment_id(0) + assert set(values) == {'PEER_V4_INT', 'PEER_V6_INT', 'PEER_V6', 'PEER_V4'} + +@patch.dict("sys.modules", swsscommon=swsscommon_module_mock) +def test___to_prefix_list(): + from bgpcfgd.managers_allow_list import BGPAllowListMgr + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") + + res_v4 = mgr._BGPAllowListMgr__to_prefix_list(mgr.V4, ["1.2.3.4/32", "10.20.20.10/24"]) + assert res_v4 == ["permit 1.2.3.4/32", "permit 10.20.20.10/24 le 32"] + res_v6 = mgr._BGPAllowListMgr__to_prefix_list(mgr.V6, ["fc00::1/128", "fc00::/64"]) + assert res_v6 == ["permit fc00::1/128", "permit fc00::/64 le 128"] + +@patch.dict("sys.modules", swsscommon=swsscommon_module_mock) +def construct_BGPAllowListMgr(constants): + from bgpcfgd.managers_allow_list import BGPAllowListMgr + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': constants, + } + mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") + return mgr + +def test___get_enabled_enabled(): + constants = { + "bgp": { + "allow_list": { + "enabled": True, + } + } + } + mgr = construct_BGPAllowListMgr(constants) + assert mgr._BGPAllowListMgr__get_enabled() + +def test___get_enabled_disabled_1(): + constants = { + "bgp": { + "allow_list": { + "enabled": False, + } + } + } + mgr = construct_BGPAllowListMgr(constants) + assert not mgr._BGPAllowListMgr__get_enabled() + +def test___get_enabled_disabled_2(): + constants = { + "bgp": { + "allow_list": {} + } + } + mgr = construct_BGPAllowListMgr(constants) + assert not mgr._BGPAllowListMgr__get_enabled() + +def test___get_enabled_disabled_3(): + constants = { + "bgp": {} + } + mgr = construct_BGPAllowListMgr(constants) + assert not mgr._BGPAllowListMgr__get_enabled() + +def test___get_enabled_disabled_4(): + constants = {} + mgr = construct_BGPAllowListMgr(constants) + assert not mgr._BGPAllowListMgr__get_enabled() + +def test___get_default_action_deny(): + constants = { + "bgp": { + "allow_list": { + "enabled": True, + "default_action": "deny", + "drop_community": "123:123" + } + } + } + data = {} + mgr = construct_BGPAllowListMgr(constants) + assert mgr._BGPAllowListMgr__get_default_action_community(data) == "no-export" + +def test___get_default_action_permit_1(): + constants = { + "bgp": { + "allow_list": { + "enabled": True, + "default_action": "permit", + "drop_community": "123:123" + } + } + } + data = {} + mgr = construct_BGPAllowListMgr(constants) + assert mgr._BGPAllowListMgr__get_default_action_community(data) == "123:123" + +def test___get_default_action_permit_2(): + constants = { + "bgp": { + "allow_list": { + "enabled": True, + "drop_community": "123:123" + } + } + } + data = {} + mgr = construct_BGPAllowListMgr(constants) + assert mgr._BGPAllowListMgr__get_default_action_community(data) == "123:123" + +def test___get_default_action_permit_3(): + constants = { + "bgp": { + "allow_list": { + "enabled": False, + "drop_community": "123:123" + } + } + } + data = {} + mgr = construct_BGPAllowListMgr(constants) + assert mgr._BGPAllowListMgr__get_default_action_community(data) == "123:123" + +# FIXME: more testcases for coverage diff --git a/src/sonic-bgpcfgd/tests/test_bbr.py b/src/sonic-bgpcfgd/tests/test_bbr.py new file mode 100644 index 000000000000..b11277bae7b8 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/test_bbr.py @@ -0,0 +1,393 @@ +from unittest.mock import MagicMock, patch + +from bgpcfgd.directory import Directory +from bgpcfgd.template import TemplateFabric +from copy import deepcopy +from . import swsscommon_test + + +with patch.dict("sys.modules", swsscommon=swsscommon_test): + from bgpcfgd.managers_bbr import BBRMgr + +global_constants = { + "bgp": { + "allow_list": { + "enabled": True, + "default_pl_rules": { + "v4": [ "deny 0.0.0.0/0 le 17" ], + "v6": [ + "deny 0::/0 le 59", + "deny 0::/0 ge 65" + ] + } + } + } +} + +def test_constructor():#m1, m2, m3): + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': {}, + } + m = BBRMgr(common_objs, "CONFIG_DB", "BGP_BBR") + assert not m.enabled + assert len(m.bbr_enabled_pgs) == 0 + assert m.directory.get("CONFIG_DB", "BGP_BBR", "status") == "disabled" + +@patch('bgpcfgd.managers_bbr.log_info') +def set_handler_common(key, value, + is_enabled, is_valid, + mocked_log_info): + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + m = BBRMgr(common_objs, "CONFIG_DB", "BGP_BBR") + m.enabled = is_enabled + prepare_config_return_value = ( + [ + ["vtysh", "-c", "clear bgp peer-group PEER_V4 soft in"], + ["vtysh", "-c", "clear bgp peer-group PEER_V6 soft in"] + ], + [ + "PEER_V4", + "PEER_V6" + ] + ) + m._BBRMgr__set_prepare_config = MagicMock(return_value = prepare_config_return_value) + m.cfg_mgr.push_list = MagicMock(return_value = None) + m.cfg_mgr.restart_peer_groups = MagicMock(return_value = None) # FIXME: check for input + res = m.set_handler(key, value) + assert res, "Returns always True" + if not is_enabled: + mocked_log_info.assert_called_with('BBRMgr::BBR is disabled. Drop the request') + else: + if is_valid: + m._BBRMgr__set_prepare_config.assert_called_once_with(value["status"]) + m.cfg_mgr.push_list.assert_called_once_with(prepare_config_return_value[0]) + m.cfg_mgr.restart_peer_groups.assert_called_once_with(prepare_config_return_value[1]) + else: + m._BBRMgr__set_prepare_config.assert_not_called() + m.cfg_mgr.push_list.assert_not_called() + m.cfg_mgr.restart_peer_groups.assert_not_called() + +def test_set_handler_not_enabled_not_valid(): + set_handler_common("anything", {}, False, False) + +def test_set_handler_enabled_not_valid(): + set_handler_common("anything", {}, True, False) + +def test_set_handler_enabled_valid(): + set_handler_common("all", {"status": "enabled"}, True, True) + +@patch('bgpcfgd.managers_bbr.log_err') +def test_del_handler(mocked_log_err): + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + m = BBRMgr(common_objs, "CONFIG_DB", "BGP_BBR") + m.del_handler("anything") + mocked_log_err.assert_called_with("The 'BGP_BBR' table shouldn't be removed from the db") + +@patch('bgpcfgd.managers_bbr.log_info') +@patch('bgpcfgd.managers_bbr.log_err') +def __init_common(constants, + expected_log_info, expected_log_err, expected_bbr_enabled_pgs, expected_status, + mocked_log_err, mocked_log_info): + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': constants, + } + m = BBRMgr(common_objs, "CONFIG_DB", "BGP_BBR") + m._BBRMgr__init() + assert m.bbr_enabled_pgs == expected_bbr_enabled_pgs + assert m.directory.get("CONFIG_DB", "BGP_BBR", "status") == expected_status + if expected_status == "enabled": + assert m.enabled + if expected_log_err is not None: + mocked_log_err.assert_called_with(expected_log_err) + if expected_log_info is not None: + mocked_log_info.assert_called_with(expected_log_info) + +def test___init_1(): + __init_common({}, None, "BBRMgr::Disabled: 'bgp' key is not found in constants", {}, "disabled") + +def test___init_2(): + constants = deepcopy(global_constants) + __init_common(constants, "BBRMgr::Disabled: no bgp.bbr.enabled in the constants", None, {}, "disabled") + +def test___init_3(): + constants = deepcopy(global_constants) + constants["bgp"]["bbr"] = { "123" : False } + __init_common(constants, "BBRMgr::Disabled: no bgp.bbr.enabled in the constants", None, {}, "disabled") + +def test___init_4(): + constants = deepcopy(global_constants) + constants["bgp"]["bbr"] = { "enabled" : False } + __init_common(constants, "BBRMgr::Disabled: no bgp.bbr.enabled in the constants", None, {}, "disabled") + +def test___init_5(): + constants = deepcopy(global_constants) + constants["bgp"]["bbr"] = { "enabled" : True } + __init_common(constants, "BBRMgr::Disabled: no BBR enabled peers", None, {}, "disabled") + +def test___init_6(): + expected_bbr_entries = { + "PEER_V4": ["ipv4"], + "PEER_V6": ["ipv6"], + } + constants = deepcopy(global_constants) + constants["bgp"]["bbr"] = { "enabled" : True } + constants["bgp"]["peers"] = { + "general": { + "bbr": expected_bbr_entries, + } + } + __init_common(constants, "BBRMgr::Initialized and enabled. Default state: 'disabled'", None, expected_bbr_entries, "disabled") + +def test___init_7(): + expected_bbr_entries = { + "PEER_V4": ["ipv4"], + "PEER_V6": ["ipv6"], + } + constants = deepcopy(global_constants) + constants["bgp"]["bbr"] = { "enabled" : True, "default_state": "disabled" } + constants["bgp"]["peers"] = { + "general": { + "bbr": expected_bbr_entries, + } + } + __init_common(constants, "BBRMgr::Initialized and enabled. Default state: 'disabled'", None, expected_bbr_entries, "disabled") + +def test___init_8(): + expected_bbr_entries = { + "PEER_V4": ["ipv4"], + "PEER_V6": ["ipv6"], + } + constants = deepcopy(global_constants) + constants["bgp"]["bbr"] = { "enabled" : True, "default_state": "enabled" } + constants["bgp"]["peers"] = { + "general": { + "bbr": expected_bbr_entries, + } + } + __init_common(constants, "BBRMgr::Initialized and enabled. Default state: 'enabled'", None, expected_bbr_entries, "enabled") + +@patch('bgpcfgd.managers_bbr.log_info') +def read_pgs_common(constants, expected_log_info, expected_bbr_enabled_pgs, mocked_log_info): + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': constants, + } + m = BBRMgr(common_objs, "CONFIG_DB", "BGP_BBR") + res = m._BBRMgr__read_pgs() + assert res == expected_bbr_enabled_pgs + if expected_log_info is not None: + mocked_log_info.assert_called_with(expected_log_info) + +def test___read_pgs_no_configuration(): + read_pgs_common(global_constants, "BBRMgr::no 'peers' was found in constants", {}) + +def test___read_pgs_parse_configuration(): + expected_bbr_entries = { + "PEER_V4": ["ipv4", "ipv6"], + "PEER_V6": ["ipv6"], + } + constants = deepcopy(global_constants) + constants["bgp"]["peers"] = { + "general": { + "bbr": expected_bbr_entries, + }, + "dynamic": { + "123": { + "PEER_V8": ["ipv10", "ipv20"], + } + } + } + read_pgs_common(constants, None, expected_bbr_entries) + +@patch('bgpcfgd.managers_bbr.log_err') +def __set_validation_common(key, data, expected_log_err, expected_result, mocked_log_err): + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + m = BBRMgr(common_objs, "CONFIG_DB", "BGP_BBR") + res = m._BBRMgr__set_validation(key, data) + assert res == expected_result + if expected_log_err is not None: + mocked_log_err.assert_called_with(expected_log_err) + +def test___set_validation_1(): + __set_validation_common("all1", {}, "Invalid key 'all1' for table 'BGP_BBR'. Only key value 'all' is supported", False) + +def test___set_validation_2(): + __set_validation_common("all", {"stat": "enabled"}, "Invalid value '{'stat': 'enabled'}' for table 'BGP_BBR', key 'all'. Key 'status' in data is expected", False) + +def test___set_validation_3(): + __set_validation_common("all", {"status": "enabled1"}, "Invalid value '{'status': 'enabled1'}' for table 'BGP_BBR', key 'all'. Only 'enabled' and 'disabled' are supported", False) + +def test___set_validation_4(): + __set_validation_common("all", {"status": "enabled"}, None, True) + +def test___set_validation_5(): + __set_validation_common("all", {"status": "disabled"}, None, True) + +def __set_prepare_config_common(status, bbr_enabled_pgs, available_pgs, expected_cmds, bbr_applied_pgs=None): + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + m = BBRMgr(common_objs, "CONFIG_DB", "BGP_BBR") + m.directory.data = {"CONFIG_DB__DEVICE_METADATA": + { + "localhost": { + "bgp_asn": "65500" + } + } + } + m.bbr_enabled_pgs = bbr_enabled_pgs + m._BBRMgr__get_available_peer_groups = MagicMock(return_value = sorted(available_pgs)) + cmds, peer_groups = m._BBRMgr__set_prepare_config(status) + assert cmds == expected_cmds + assert set(peer_groups) == (available_pgs if not bbr_applied_pgs else bbr_applied_pgs) + +def test___set_prepare_config_enabled(): + __set_prepare_config_common("enabled", { + "PEER_V4": ["ipv4", "ipv6"], + "PEER_V6": ["ipv6"], + }, {"PEER_V4", "PEER_V6"}, [ + 'router bgp 65500', + ' address-family ipv4', + ' neighbor PEER_V4 allowas-in 1', + ' address-family ipv6', + ' neighbor PEER_V4 allowas-in 1', + ' neighbor PEER_V6 allowas-in 1', + ]) + +def test___set_prepare_config_disabled(): + __set_prepare_config_common("disabled", { + "PEER_V4": ["ipv4", "ipv6"], + "PEER_V6": ["ipv6"], + }, {"PEER_V4", "PEER_V6"}, [ + 'router bgp 65500', + ' address-family ipv4', + ' no neighbor PEER_V4 allowas-in 1', + ' address-family ipv6', + ' no neighbor PEER_V4 allowas-in 1', + ' no neighbor PEER_V6 allowas-in 1', + ]) + +def test___set_prepare_config_enabled_part(): + __set_prepare_config_common("enabled", { + "PEER_V4": ["ipv4", "ipv6"], + "PEER_V6": ["ipv6"], + "PEER_V8": ["ipv4"] + }, {"PEER_V4", "PEER_V6"}, [ + 'router bgp 65500', + ' address-family ipv4', + ' neighbor PEER_V4 allowas-in 1', + ' address-family ipv6', + ' neighbor PEER_V4 allowas-in 1', + ' neighbor PEER_V6 allowas-in 1', + ]) + +def test___set_prepare_config_disabled_part(): + __set_prepare_config_common("disabled", { + "PEER_V4": ["ipv4", "ipv6"], + "PEER_V6": ["ipv6"], + "PEER_v10": ["ipv4"], + }, {"PEER_V4", "PEER_V6"}, [ + 'router bgp 65500', + ' address-family ipv4', + ' no neighbor PEER_V4 allowas-in 1', + ' address-family ipv6', + ' no neighbor PEER_V4 allowas-in 1', + ' no neighbor PEER_V6 allowas-in 1', + ]) +def test___set_prepare_config_enabled_multiple_peers(): + __set_prepare_config_common("enabled", { + "PEER_V4": ["ipv4"], + "PEER_V6": ["ipv6"], + }, {"PEER_V4", "PEER_V4_DEPLOYMENT_ID_0", "PEER_V4_DEPLOYMENT_ID_1", "PEER_V6", "PEER_V6_DEPLOYMENT_ID_0", "PEER_V6_DEPLOYMENT_ID_1", "PEER_INVALID"}, + [ + 'router bgp 65500', + ' address-family ipv4', + ' neighbor PEER_V4 allowas-in 1', + ' neighbor PEER_V4_DEPLOYMENT_ID_0 allowas-in 1', + ' neighbor PEER_V4_DEPLOYMENT_ID_1 allowas-in 1', + ' address-family ipv6', + ' neighbor PEER_V6 allowas-in 1', + ' neighbor PEER_V6_DEPLOYMENT_ID_0 allowas-in 1', + ' neighbor PEER_V6_DEPLOYMENT_ID_1 allowas-in 1', + ], + {"PEER_V4", "PEER_V4_DEPLOYMENT_ID_0", "PEER_V4_DEPLOYMENT_ID_1", "PEER_V6", "PEER_V6_DEPLOYMENT_ID_0", "PEER_V6_DEPLOYMENT_ID_1"}) + +def test___set_prepare_config_disabled_multiple_peers(): + __set_prepare_config_common("disabled", { + "PEER_V4": ["ipv4"], + "PEER_V6": ["ipv6"], + }, {"PEER_V4", "PEER_V4_DEPLOYMENT_ID_0", "PEER_V4_DEPLOYMENT_ID_1", "PEER_V6", "PEER_V6_DEPLOYMENT_ID_0", "PEER_V6_DEPLOYMENT_ID_1", "PEER_INVALID"}, + [ + 'router bgp 65500', + ' address-family ipv4', + ' no neighbor PEER_V4 allowas-in 1', + ' no neighbor PEER_V4_DEPLOYMENT_ID_0 allowas-in 1', + ' no neighbor PEER_V4_DEPLOYMENT_ID_1 allowas-in 1', + ' address-family ipv6', + ' no neighbor PEER_V6 allowas-in 1', + ' no neighbor PEER_V6_DEPLOYMENT_ID_0 allowas-in 1', + ' no neighbor PEER_V6_DEPLOYMENT_ID_1 allowas-in 1', + ], + {"PEER_V4", "PEER_V4_DEPLOYMENT_ID_0", "PEER_V4_DEPLOYMENT_ID_1", "PEER_V6", "PEER_V6_DEPLOYMENT_ID_0", "PEER_V6_DEPLOYMENT_ID_1"}) + +def test__get_available_peer_groups(): + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + m = BBRMgr(common_objs, "CONFIG_DB", "BGP_BBR") + m.cfg_mgr.get_text = MagicMock(return_value=[ + ' neighbor PEER_V4 peer-group', + ' neighbor PEER_V6 peer-group', + ' address-family ipv4', + ' neighbor PEER_V4 allowas-in 1', + ' neighbor PEER_V4 soft-reconfiguration inbound', + ' neighbor PEER_V4 route-map FROM_BGP_PEER_V4 in', + ' neighbor PEER_V4 route-map TO_BGP_PEER_V4 out', + ' exit-address-family', + ' address-family ipv6', + ' neighbor PEER_V6 allowas-in 1', + ' neighbor PEER_V6 soft-reconfiguration inbound', + ' neighbor PEER_V6 route-map FROM_BGP_PEER_V6 in', + ' neighbor PEER_V6 route-map TO_BGP_PEER_V6 out', + ' exit-address-family', + ' ', + ]) + res = m._BBRMgr__get_available_peer_groups() + assert res == {"PEER_V4", "PEER_V6"} diff --git a/src/sonic-bgpcfgd/tests/test_bbr_templates.py b/src/sonic-bgpcfgd/tests/test_bbr_templates.py new file mode 100644 index 000000000000..989734d79714 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/test_bbr_templates.py @@ -0,0 +1,70 @@ +import itertools +import os +import re + +from .util import load_constants_dir_mappings, load_constants + + +TEMPLATE_PATH = os.path.abspath('../../dockers/docker-fpm-frr/frr/bgpd/templates') + + +def find_all_files(path): + paths_to_check = [path] + res = [] + while paths_to_check: + path = paths_to_check[0] + paths_to_check = paths_to_check[1:] + for name in os.listdir(path): + full_path = "%s/%s" % (path, name) + if os.path.isfile(full_path): + res.append(full_path) + elif os.path.isdir(full_path): + paths_to_check.append(full_path) + return res + +def get_files_to_check(): + directories = load_constants_dir_mappings() + general_path = "%s/%s" % (TEMPLATE_PATH, directories['general']) + files = find_all_files(general_path) + return files + +def get_peer_groups_with_bbr(filename): + re_bbr = re.compile(r".+CONFIG_DB__BGP_BBR.+") #\['status'\] == 'enabled'") + re_endif = re.compile(r'^\s*{% +endif +%}\s*$') + re_peer = re.compile(r'^\s*neighbor\s+(\S+)\s+allowas-in\s+1\s*$') + inside_bbr = False + res = [] + with open(filename) as fp: + for line in fp: + s_line = line.strip() + if s_line == '': + continue + elif s_line.startswith('!'): + continue + elif re_bbr.match(s_line): + inside_bbr = True + elif re_peer.match(s_line) and inside_bbr: + m = re_peer.match(s_line) + pg = m.group(1) + res.append(pg) + elif re_endif.match(s_line) and inside_bbr: + inside_bbr = False + return res + +def load_constants_bbr(): + data = load_constants() + assert "bgp" in data["constants"], "'bgp' key not found in constants.yml" + assert "peers" in data["constants"]["bgp"], "'peers' key not found in constants.yml" + assert "general" in data["constants"]["bgp"]['peers'], "'general' key not found in constants.yml" + return data["constants"]["bgp"]["peers"]['general'] + +def test_bbr_templates(): + files_to_check = get_files_to_check() + pg_with_bbr_per_file = [ get_peer_groups_with_bbr(name) for name in files_to_check ] + pg_with_bbr = set(itertools.chain.from_iterable(pg_with_bbr_per_file)) + general = load_constants_bbr() + if pg_with_bbr: + assert 'bbr' in general, "BBR is not defined in 'general', but BBR is enabled for %s" % pg_with_bbr + for pg in pg_with_bbr: + assert pg in general['bbr'], "peer-group '%s' has BBR enabled, but it is not configured in constants.yml" + diff --git a/src/sonic-bgpcfgd/tests/test_bgp.py b/src/sonic-bgpcfgd/tests/test_bgp.py new file mode 100644 index 000000000000..a4c5ef997725 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/test_bgp.py @@ -0,0 +1,112 @@ +from unittest.mock import MagicMock, patch + +import os +from bgpcfgd.directory import Directory +from bgpcfgd.template import TemplateFabric +from . import swsscommon_test +from .util import load_constants +from swsscommon import swsscommon +import bgpcfgd.managers_bgp + +TEMPLATE_PATH = os.path.abspath('../../dockers/docker-fpm-frr/frr') + +def constructor(): + cfg_mgr = MagicMock() + constants = load_constants()['constants'] + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(TEMPLATE_PATH), + 'constants': constants + } + + return_value_map = { + "['vtysh', '-c', 'show bgp vrfs json']": (0, "{\"vrfs\": {\"default\": {}}}", ""), + "['vtysh', '-c', 'show bgp vrf default neighbors json']": (0, "{\"10.10.10.1\": {}, \"20.20.20.1\": {}, \"fc00:10::1\": {}}", "") + } + + bgpcfgd.managers_bgp.run_command = lambda cmd: return_value_map[str(cmd)] + m = bgpcfgd.managers_bgp.BGPPeerMgrBase(common_objs, "CONFIG_DB", swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME, "general", True) + assert m.peer_type == "general" + assert m.check_neig_meta == ('bgp' in constants and 'use_neighbors_meta' in constants['bgp'] and constants['bgp']['use_neighbors_meta']) + + m.directory.put("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME, "localhost", {"bgp_asn": "65100"}) + m.directory.put("CONFIG_DB", swsscommon.CFG_LOOPBACK_INTERFACE_TABLE_NAME, "Loopback0|11.11.11.11/32", {}) + m.directory.put("CONFIG_DB", swsscommon.CFG_LOOPBACK_INTERFACE_TABLE_NAME, "Loopback0|FC00:1::32/128", {}) + m.directory.put("LOCAL", "local_addresses", "30.30.30.30", {"interface": "Ethernet4|30.30.30.30/24"}) + m.directory.put("LOCAL", "local_addresses", "fc00:20::20", {"interface": "Ethernet8|fc00:20::20/96"}) + m.directory.put("LOCAL", "interfaces", "Ethernet4|30.30.30.30/24", {"anything": "anything"}) + m.directory.put("LOCAL", "interfaces", "Ethernet8|fc00:20::20/96", {"anything": "anything"}) + + return m + +@patch('bgpcfgd.managers_bgp.log_info') +def test_update_peer_up(mocked_log_info): + m = constructor() + res = m.set_handler("10.10.10.1", {"admin_status": "up"}) + assert res, "Expect True return value for peer update" + mocked_log_info.assert_called_with("Peer 'default|10.10.10.1' admin state is set to 'up'") + +@patch('bgpcfgd.managers_bgp.log_info') +def test_update_peer_up_ipv6(mocked_log_info): + m = constructor() + res = m.set_handler("fc00:10::1", {"admin_status": "up"}) + assert res, "Expect True return value for peer update" + mocked_log_info.assert_called_with("Peer 'default|fc00:10::1' admin state is set to 'up'") + +@patch('bgpcfgd.managers_bgp.log_info') +def test_update_peer_down(mocked_log_info): + m = constructor() + res = m.set_handler("10.10.10.1", {"admin_status": "down"}) + assert res, "Expect True return value for peer update" + mocked_log_info.assert_called_with("Peer 'default|10.10.10.1' admin state is set to 'down'") + +@patch('bgpcfgd.managers_bgp.log_err') +def test_update_peer_no_admin_status(mocked_log_err): + m = constructor() + res = m.set_handler("10.10.10.1", {"anything": "anything"}) + assert res, "Expect True return value for peer update" + mocked_log_err.assert_called_with("Peer '(default|10.10.10.1)': Can't update the peer. Only 'admin_status' attribute is supported") + +@patch('bgpcfgd.managers_bgp.log_err') +def test_update_peer_invalid_admin_status(mocked_log_err): + m = constructor() + res = m.set_handler("10.10.10.1", {"admin_status": "invalid"}) + assert res, "Expect True return value for peer update" + mocked_log_err.assert_called_with("Peer 'default|10.10.10.1': Can't update the peer. It has wrong attribute value attr['admin_status'] = 'invalid'") + +def test_add_peer(): + m = constructor() + res = m.set_handler("30.30.30.1", {"local_addr": "30.30.30.30", "admin_status": "up"}) + assert res, "Expect True return value" + +def test_add_peer_ipv6(): + m = constructor() + res = m.set_handler("fc00:20::1", {"local_addr": "fc00:20::20", "admin_status": "up"}) + assert res, "Expect True return value" + +@patch('bgpcfgd.managers_bgp.log_warn') +def test_add_peer_no_local_addr(mocked_log_warn): + m = constructor() + res = m.set_handler("30.30.30.1", {"admin_status": "up"}) + assert res, "Expect True return value" + mocked_log_warn.assert_called_with("Peer 30.30.30.1. Missing attribute 'local_addr'") + +@patch('bgpcfgd.managers_bgp.log_debug') +def test_add_peer_invalid_local_addr(mocked_log_debug): + m = constructor() + res = m.set_handler("30.30.30.1", {"local_addr": "40.40.40.40", "admin_status": "up"}) + assert not res, "Expect False return value" + mocked_log_debug.assert_called_with("Peer '30.30.30.1' with local address '40.40.40.40' wait for the corresponding interface to be set") + +@patch('bgpcfgd.managers_bgp.log_info') +def test_del_handler(mocked_log_info): + m = constructor() + m.del_handler("10.10.10.1") + mocked_log_info.assert_called_with("Peer '(default|10.10.10.1)' has been removed") + +@patch('bgpcfgd.managers_bgp.log_warn') +def test_del_handler_nonexist_peer(mocked_log_warn): + m = constructor() + m.del_handler("40.40.40.1") + mocked_log_warn.assert_called_with("Peer '(default|40.40.40.1)' has not been found") diff --git a/src/sonic-bgpcfgd/tests/test_config.py b/src/sonic-bgpcfgd/tests/test_config.py new file mode 100644 index 000000000000..c8bd0c9ca2be --- /dev/null +++ b/src/sonic-bgpcfgd/tests/test_config.py @@ -0,0 +1,207 @@ +from unittest.mock import MagicMock + +from bgpcfgd.config import ConfigMgr + + +def test_constructor(): + frr = MagicMock() + c = ConfigMgr(frr) + assert c.frr == frr + assert c.current_config is None + assert c.current_config_raw is None + assert c.changes == "" + assert c.peer_groups_to_restart == [] + +def test_reset(): + frr = MagicMock() + c = ConfigMgr(frr) + c.reset() + assert c.frr == frr + assert c.current_config is None + assert c.current_config_raw is None + assert c.changes == "" + assert c.peer_groups_to_restart == [] + +def test_update(): + frr = MagicMock() + frr.get_config = MagicMock(return_value = """! + text1 + ! comment + text2 + text3 + ! comment + text4 + """) + c = ConfigMgr(frr) + c.update() + assert c.current_config_raw == [' text1', ' text2', ' text3', ' text4', ' ', ' '] + assert c.current_config == [['text1'], ['text2'], ['text3'], ['text4']] + +def test_push_list(): + frr = MagicMock() + c = ConfigMgr(frr) + c.push_list(["change1", "change2"]) + assert c.changes == "change1\nchange2\n" + c.push_list(["change3", "change4"]) + assert c.changes == "change1\nchange2\nchange3\nchange4\n" + +def test_push(): + frr = MagicMock() + c = ConfigMgr(frr) + c.push("update1\nupdate2\n") + assert c.changes == "update1\nupdate2\n\n" + c.push("update3\nupdate4\n") + assert c.changes == "update1\nupdate2\n\nupdate3\nupdate4\n\n" + +def test_push_and_push_list(): + frr = MagicMock() + c = ConfigMgr(frr) + c.push("update1\nupdate2\n") + c.push_list(["change1", "change2"]) + assert c.changes == "update1\nupdate2\n\nchange1\nchange2\n" + +def test_restart_peer_groups(): + frr = MagicMock() + c = ConfigMgr(frr) + c.restart_peer_groups(["pg_1", "pg_2"]) + assert c.peer_groups_to_restart == ["pg_1", "pg_2"] + c.restart_peer_groups(["pg_3", "pg_4"]) + assert c.peer_groups_to_restart == ["pg_1", "pg_2", "pg_3", "pg_4"] + +def test_commit_empty_changes(): + frr = MagicMock() + c = ConfigMgr(frr) + res = c.commit() + assert res + assert not frr.write.called + +def commit_changes_common(write_error, restart_error, result): + frr = MagicMock() + frr.write = MagicMock(return_value = write_error) + frr.restart_peer_groups = MagicMock(return_value = restart_error) + c = ConfigMgr(frr) + c.reset = MagicMock() + c.push_list(["change1", "change2"]) + c.restart_peer_groups(["pg1", "pg2"]) + res = c.commit() + assert res == result + assert c.reset.called + frr.write.assert_called_with('change1\nchange2\n') + frr.restart_peer_groups.assert_called_with(["pg1", "pg2"]) + +def test_commit_changes_no_errors(): + commit_changes_common(True, True, True) + +def test_commit_changes_write_error(): + commit_changes_common(False, True, False) + +def test_commit_changes_restart_error(): + commit_changes_common(True, False, False) + +def test_commit_changes_both_errors(): + commit_changes_common(False, False, False) + +def test_restart_get_text(): + frr = MagicMock() + frr.get_config = MagicMock(return_value = """! + text1 + ! comment + text2 + text3 + ! comment + text4 + """) + c = ConfigMgr(frr) + c.update() + assert c.get_text() == [' text1', ' text2', ' text3', ' text4', ' ', ' '] + +def to_canonical_common(raw_text, expected_canonical): + frr = MagicMock() + c = ConfigMgr(frr) + assert c.to_canonical(raw_text) == expected_canonical + +def test_to_canonical_empty(): + raw_config = """ +! + ! + ! + ! + + ! + +""" + to_canonical_common(raw_config, []) + +def test_to_canonical_(): + raw_config = """ +! +router bgp 12345 + bgp router-id 1020 + address-family ipv4 + neighbor PEER_V4 peer-group + neighbor PEER_V4 route-map A10 in + exit-address-family + address-family ipv6 + neighbor PEER_V6 peer-group + neighbor PEER_V6 route-map A20 in + exit-address-family +route-map A10 permit 10 +! +route-map A20 permit 10 +! + +""" + expected = [ + ['router bgp 12345'], + ['router bgp 12345', 'bgp router-id 1020'], + ['router bgp 12345', 'address-family ipv4'], + ['router bgp 12345', 'address-family ipv4', 'neighbor PEER_V4 peer-group'], + ['router bgp 12345', 'address-family ipv4', 'neighbor PEER_V4 route-map A10 in'], + ['router bgp 12345', 'exit-address-family'], + ['router bgp 12345', 'address-family ipv6'], + ['router bgp 12345', 'address-family ipv6', 'neighbor PEER_V6 peer-group'], + ['router bgp 12345', 'address-family ipv6', 'neighbor PEER_V6 route-map A20 in'], + ['router bgp 12345', 'exit-address-family'], + ['route-map A10 permit 10'], + ['route-map A20 permit 10'] + ] + to_canonical_common(raw_config, expected) + +def test_count_spaces(): + frr = MagicMock() + c = ConfigMgr(frr) + assert c.count_spaces(" !") == 2 + assert c.count_spaces("!") == 0 + assert c.count_spaces("") == 0 + +def test_from_canonical(): + canonical = [ + ['router bgp 12345'], + ['router bgp 12345', 'bgp router-id 1020'], + ['router bgp 12345', 'address-family ipv4'], + ['router bgp 12345', 'address-family ipv4', 'neighbor PEER_V4 peer-group'], + ['router bgp 12345', 'address-family ipv4', 'neighbor PEER_V4 route-map A10 in'], + ['router bgp 12345', 'exit-address-family'], + ['router bgp 12345', 'address-family ipv6'], + ['router bgp 12345', 'address-family ipv6', 'neighbor PEER_V6 peer-group'], + ['router bgp 12345', 'address-family ipv6', 'neighbor PEER_V6 route-map A20 in'], + ['router bgp 12345', 'exit-address-family'], + ['route-map A10 permit 10'], + ['route-map A20 permit 10'] + ] + expected = 'router bgp 12345\n' \ + ' bgp router-id 1020\n' \ + ' address-family ipv4\n' \ + ' neighbor PEER_V4 peer-group\n' \ + ' neighbor PEER_V4 route-map A10 in\n' \ + ' exit-address-family\n' \ + ' address-family ipv6\n' \ + ' neighbor PEER_V6 peer-group\n' \ + ' neighbor PEER_V6 route-map A20 in\n' \ + ' exit-address-family\n' \ + 'route-map A10 permit 10\n' \ + 'route-map A20 permit 10\n' + frr = MagicMock() + c = ConfigMgr(frr) + raw = c.from_canonical(canonical) + assert raw == expected diff --git a/src/sonic-bgpcfgd/tests/test_db.py b/src/sonic-bgpcfgd/tests/test_db.py new file mode 100644 index 000000000000..7078bc2735f0 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/test_db.py @@ -0,0 +1,40 @@ +from unittest.mock import MagicMock, patch + +from bgpcfgd.directory import Directory +from bgpcfgd.template import TemplateFabric +from . import swsscommon_test +from swsscommon import swsscommon + +with patch.dict("sys.modules", swsscommon=swsscommon_test): + from bgpcfgd.managers_db import BGPDataBaseMgr + +def test_set_del_handler(): + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': {}, + } + m = BGPDataBaseMgr(common_objs, "CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME) + assert m.constants == {} + + # test set_handler + res = m.set_handler("test_key1", {"test_value1"}) + assert res, "Returns always True" + assert "test_key1" in m.directory.get_slot(m.db_name, m.table_name) + assert m.directory.get(m.db_name, m.table_name, "test_key1") == {"test_value1"} + + res = m.set_handler("test_key2", {}) + assert res, "Returns always True" + assert "test_key2" in m.directory.get_slot(m.db_name, m.table_name) + assert m.directory.get(m.db_name, m.table_name, "test_key2") == {} + + # test del_handler + m.del_handler("test_key") + assert "test_key" not in m.directory.get_slot(m.db_name, m.table_name) + assert "test_key2" in m.directory.get_slot(m.db_name, m.table_name) + assert m.directory.get(m.db_name, m.table_name, "test_key2") == {} + + m.del_handler("test_key2") + assert "test_key2" not in m.directory.get_slot(m.db_name, m.table_name) diff --git a/src/sonic-bgpcfgd/tests/test_directory.py b/src/sonic-bgpcfgd/tests/test_directory.py new file mode 100644 index 000000000000..b20803ed32c5 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/test_directory.py @@ -0,0 +1,57 @@ +from unittest.mock import MagicMock, patch +from bgpcfgd.directory import Directory + +@patch('bgpcfgd.directory.log_err') +def test_directory(mocked_log_err): + test_values = { + "key1": { + "key1_1": { + "key1_1_1": "value1_1_1", + "key1_1_2": "value1_1_2", + "key1_1_3": "value1_1_3" + } + }, + "key2": { + "value2" + } + } + + directory = Directory() + + # Put test values + directory.put("db_name", "table", "key1", test_values["key1"]) + directory.put("db_name", "table", "key2", test_values["key2"]) + + # Test get_path() + assert directory.get_path("db_name", "table", "") == test_values + assert directory.get_path("db_name", "table", "key1/key1_1/key1_1_1") == "value1_1_1" + assert directory.get_path("db_name", "table", "key1/key_nonexist") == None + + # Test path_exist() + assert directory.path_exist("db_name", "table", "key1/key1_1/key1_1_1") + assert not directory.path_exist("db_name", "table_nonexist", "") + assert not directory.path_exist("db_name", "table", "key1/key_nonexist") + + # Test get_slot() + assert directory.get_slot("db_name", "table") == test_values + + # Test get() + assert directory.get("db_name", "table", "key2") == test_values["key2"] + + # Test remove() + directory.remove("db_name", "table", "key2") + assert not directory.path_exist("db_name", "table", "key2") + + # Test remove() with invalid input + directory.remove("db_name", "table_nonexist", "key2") + mocked_log_err.assert_called_with("Directory: Can't remove key 'key2' from slot 'db_name__table_nonexist'. The slot doesn't exist") + directory.remove("db_name", "table", "key_nonexist") + mocked_log_err.assert_called_with("Directory: Can't remove key 'key_nonexist' from slot 'db_name__table'. The key doesn't exist") + + # Test remove_slot() + directory.remove_slot("db_name", "table") + assert not directory.available("db_name", "table") + + # Test remove_slot() with nonexist table + directory.remove_slot("db_name", "table_nonexist") + mocked_log_err.assert_called_with("Directory: Can't remove slot 'db_name__table_nonexist'. The slot doesn't exist") diff --git a/src/sonic-bgpcfgd/tests/test_frr.py b/src/sonic-bgpcfgd/tests/test_frr.py new file mode 100644 index 000000000000..5a20281fa553 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/test_frr.py @@ -0,0 +1,68 @@ +from unittest.mock import patch +import bgpcfgd.frr +import pytest + +def test_constructor(): + f = bgpcfgd.frr.FRR(["abc", "cde"]) + assert f.daemons == ["abc", "cde"] + +def test_wait_for_daemons(): + bgpcfgd.frr.run_command = lambda cmd, **kwargs: (0, ["abc", "cde"], "") + f = bgpcfgd.frr.FRR(["abc", "cde"]) + f.wait_for_daemons(5) + +def test_wait_for_daemons_fail(): + bgpcfgd.frr.run_command = lambda cmd, **kwargs: (0, ["abc", "non_expected"], "") + f = bgpcfgd.frr.FRR(["abc", "cde"]) + with pytest.raises(Exception): + assert f.wait_for_daemons(5) + +def test_wait_for_daemons_error(): + bgpcfgd.frr.run_command = lambda cmd, **kwargs: (1, ["abc", "cde"], "some error") + f = bgpcfgd.frr.FRR(["abc", "cde"]) + with pytest.raises(Exception): + assert f.wait_for_daemons(5) + +def test_get_config(): + bgpcfgd.frr.run_command = lambda cmd: (0, "expected config", "") + f = bgpcfgd.frr.FRR(["abc", "cde"]) + out = f.get_config() + assert out == "expected config" + +@patch('bgpcfgd.frr.log_crit') +def test_get_config_fail(mocked_log_crit): + bgpcfgd.frr.run_command = lambda cmd: (1, "some config", "some error") + f = bgpcfgd.frr.FRR(["abc", "cde"]) + out = f.get_config() + assert out == "" + mocked_log_crit.assert_called_with("can't update running config: rc=1 out='some config' err='some error'") + +def test_write(): + bgpcfgd.frr.run_command = lambda cmd: (0, "some output", "") + f = bgpcfgd.frr.FRR(["abc", "cde"]) + res = f.write("config context") + assert res, "Expect True return value" + +def test_write_fail(): + bgpcfgd.frr.run_command = lambda cmd: (1, "some output", "some error") + f = bgpcfgd.frr.FRR(["abc", "cde"]) + res = f.write("config context") + assert not res, "Expect False return value" + +def test_restart_peer_groups(): + bgpcfgd.frr.run_command = lambda cmd: (0, "some output", "") + f = bgpcfgd.frr.FRR(["abc", "cde"]) + res = f.restart_peer_groups(["pg_1", "pg_2"]) + assert res, "Expect True return value" + +@patch('bgpcfgd.frr.log_crit') +def test_restart_peer_groups_fail(mocked_log_crit): + return_value_map = { + "['vtysh', '-c', 'clear bgp peer-group pg_1 soft in']": (0, "", ""), + "['vtysh', '-c', 'clear bgp peer-group pg_2 soft in']": (1, "some output", "some error") + } + bgpcfgd.frr.run_command = lambda cmd: return_value_map[str(cmd)] + f = bgpcfgd.frr.FRR(["abc", "cde"]) + res = f.restart_peer_groups(["pg_1", "pg_2"]) + assert not res, "Expect False return value" + mocked_log_crit.assert_called_with("Can't restart bgp peer-group 'pg_2'. rc='1', out='some output', err='some error'") diff --git a/src/sonic-bgpcfgd/tests/test_intf.py b/src/sonic-bgpcfgd/tests/test_intf.py new file mode 100644 index 000000000000..74fa8e471ac6 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/test_intf.py @@ -0,0 +1,52 @@ +from unittest.mock import MagicMock, patch + +from bgpcfgd.directory import Directory +from bgpcfgd.template import TemplateFabric +from swsscommon import swsscommon +from bgpcfgd.managers_intf import InterfaceMgr + +def set_handler_test(manager, key, value): + res = manager.set_handler(key, value) + assert res, "Returns always True" + assert manager.directory.get(manager.db_name, manager.table_name, key) == value + +def del_handler_test(manager, key): + manager.del_handler(key) + assert manager.directory.get_path(manager.db_name, manager.table_name, key) == None + +@patch('bgpcfgd.managers_intf.log_warn') +def test_intf(mocked_log_warn): + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': {}, + } + m = InterfaceMgr(common_objs, "CONFIG_DB", swsscommon.CFG_VLAN_INTF_TABLE_NAME) + + set_handler_test(m, "Vlan1000", {}) + set_handler_test(m, "Vlan1000|192.168.0.1/21", {}) + + # test set handler with invalid ip network + res = m.set_handler("Vlan1000|invalid_netowrk", {}) + assert res, "Returns always True" + mocked_log_warn.assert_called_with("Subnet 'invalid_netowrk' format is wrong for interface 'Vlan1000'") + + del_handler_test(m, "Vlan1000") + del_handler_test(m, "Vlan1000|192.168.0.1/21") + del_handler_test(m, "Vlan1000|invalid_netowrk") + mocked_log_warn.assert_called_with("Subnet 'invalid_netowrk' format is wrong for interface 'Vlan1000'") + +def test_intf_ipv6(): + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': {}, + } + m = InterfaceMgr(common_objs, "CONFIG_DB", swsscommon.CFG_VLAN_INTF_TABLE_NAME) + + set_handler_test(m, "Vlan1000|fc02:1000::1/64", {}) + del_handler_test(m, "Vlan1000|fc02:1000::1/64") diff --git a/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py b/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py new file mode 100644 index 000000000000..398c8a19f3f7 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py @@ -0,0 +1,129 @@ +import os +import re + +from bgpcfgd.template import TemplateFabric +from .util import load_constants_dir_mappings + +TEMPLATE_PATH = os.path.abspath('../../dockers/docker-fpm-frr/frr') + + +def parse_instance_conf(filename): + activate_re = re.compile(r'^neighbor\s+(\S+)\s+activate$') + with open(filename) as fp: + lines = [line.strip() for line in fp if not line.strip().startswith('!') and line.strip() != ''] + # Search all v6 neighbors + neighbors = {} + for line in lines: + if activate_re.match(line): + neighbor = activate_re.match(line).group(1) + if TemplateFabric.is_ipv6(neighbor): + neighbors[neighbor] = {} + # Extract peer-groups and route-maps + for neighbor, neighbor_data in neighbors.items(): + route_map_in_re = re.compile(r'^neighbor\s+%s\s+route-map\s+(\S+) in$' % neighbor) + peer_group_re = re.compile(r'^neighbor\s+%s\s+peer-group\s+(\S+)$' % neighbor) + for line in lines: + if route_map_in_re.match(line): + assert "route-map" not in neighbor_data + neighbor_data["route-map"] = route_map_in_re.match(line).group(1) + if peer_group_re.match(line): + assert "peer-group" not in neighbor_data + neighbor_data["peer-group"] = peer_group_re.match(line).group(1) + # Ensure that every ivp6 neighbor has either route-map or peer-group + for neighbor, neighbor_data in neighbors.items(): + assert "route-map" in neighbor_data or "peer-group" in neighbor_data,\ + "IPv6 neighbor '%s' must have either route-map in or peer-group %s" % (neighbor, neighbor_data) + return neighbors + +def load_results(path, dir_name): + result_files = [] + for fname in os.listdir(os.path.join(path, dir_name)): + if not fname.startswith("result_"): + continue + full_fname = os.path.join(path, dir_name, fname) + if not os.path.isfile(full_fname): + continue + result_files.append(full_fname) + return result_files + +def process_instances(path): + result_files = load_results(path, "instance.conf") + # search for ipv6 neighbors + neighbors_list = [] + for fname in result_files: + neighbors = parse_instance_conf(fname) + if neighbors: + neighbors_list.append(neighbors) + return neighbors_list + +def parse_peer_group_conf(filename, pg_name): + route_map_re = re.compile(r'^neighbor\s+%s\s+route-map\s+(\S+)\s+in$' % pg_name) + with open(filename) as fp: + lines = [line.strip() for line in fp if not line.strip().startswith('!') and line.strip() != ''] + route_maps = set() + for line in lines: + if route_map_re.match(line): + route_map = route_map_re.match(line).group(1) + route_maps.add(route_map) + return route_maps + +def extract_rm_from_peer_group(path, peer_group_name): + result_files = load_results(path, "peer-group.conf") + rm_set = set() + for fname in result_files: + route_maps = parse_peer_group_conf(fname, peer_group_name) + if route_maps: + rm_set |= route_maps + return list(rm_set) + +def check_routemap_in_file(filename, route_map_name): + route_map_re = re.compile(r'^route-map\s+%s\s+permit\s+(\d+)' % route_map_name) + set_re = re.compile(r'set ipv6 next-hop prefer-global') + next_re = re.compile(r'on-match next') + with open(filename) as fp: + lines = [line.strip() for line in fp if not line.strip().startswith('!') and line.strip() != ''] + found_entry = False + found_seq_no = None + route_map_entries = {} + for line in lines: + if found_entry: + if set_re.match(line): + route_map_entries[found_seq_no][0] = True + elif next_re.match(line): + route_map_entries[found_seq_no][1] = True + else: + found_entry = False + found_seq_no = None + if route_map_re.match(line): + found_seq_no = None + seq_n_txt = route_map_re.match(line).group(1) + assert seq_n_txt.isdigit(), "wrong sequence number for line '%s'" % line + found_seq_no = int(seq_n_txt) + assert found_seq_no not in route_map_entries, "Route-map has duplicate entries: %s - %d" % (route_map_name, found_seq_no) + found_entry = True + route_map_entries[found_seq_no] = [False, False] + results = [route_map_entries[seq] for seq in sorted(route_map_entries.keys())] + err_msg = "route-map %s doesn't have mandatory permit entry for 'set ipv6 next-hop prefer-global" % route_map_name + assert len(results), err_msg + assert all(results[0]), "first ipv6 route-map entry doesn't have set ipv6 nexthop" + return True + +def check_routemap(path, route_map_name): + result_files = load_results(path, "policies.conf") + checked = False + for fname in result_files: + checked = checked or check_routemap_in_file(fname, route_map_name) + assert checked, "route-map %s wasn't found" % route_map_name + +def test_v6_next_hop_global(): + paths = ["tests/data/%s" % value for value in load_constants_dir_mappings().values()] + for path in paths: + test_cases = process_instances(path) + for test_case in test_cases: + for neighbor_value in test_case.values(): + if 'route-map' in neighbor_value: + check_routemap(path, neighbor_value['route-map']) + elif 'peer-group' in neighbor_value: + route_map_in_list = extract_rm_from_peer_group(path, neighbor_value['peer-group']) + for route_map_in in route_map_in_list: + check_routemap(path, route_map_in) diff --git a/src/sonic-bgpcfgd/tests/test_pfx_filter.py b/src/sonic-bgpcfgd/tests/test_pfx_filter.py new file mode 100644 index 000000000000..0714be56a892 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/test_pfx_filter.py @@ -0,0 +1,139 @@ +from bgpcfgd.template import TemplateFabric +from collections import OrderedDict +import pytest + + +def test_pfx_filter_none(): + res = TemplateFabric.pfx_filter(None) + assert isinstance(res, OrderedDict) and len(res) == 0 + +def test_pfx_filter_empty_tuple(): + res = TemplateFabric.pfx_filter(()) + assert isinstance(res, OrderedDict) and len(res) == 0 + +def test_pfx_filter_empty_list(): + res = TemplateFabric.pfx_filter([]) + assert isinstance(res, OrderedDict) and len(res) == 0 + +def test_pfx_filter_empty_dict(): + res = TemplateFabric.pfx_filter({}) + assert isinstance(res, OrderedDict) and len(res) == 0 + +def test_pfx_filter_strings(): + src = { + 'Loopback0': {}, + 'Loopback1': {}, + } + expected = OrderedDict([]) + res = TemplateFabric.pfx_filter(src) + assert res == expected + +def test_pfx_filter_mixed_keys(): + src = { + 'Loopback0': {}, + ('Loopback0', '11.11.11.11/32'): {}, + 'Loopback1': {}, + ('Loopback1', '55.55.55.55/32'): {}, + } + expected = OrderedDict( + [ + (('Loopback1', '55.55.55.55/32'), {}), + (('Loopback0', '11.11.11.11/32'), {}), + ] + ) + res = TemplateFabric.pfx_filter(src) + assert dict(res) == dict(expected) + + +def test_pfx_filter_pfx_v4_w_mask(): + src = { + ('Loopback0', '11.11.11.11/32'): {}, + ('Loopback1', '55.55.55.55/32'): {}, + } + expected = OrderedDict( + [ + (('Loopback1', '55.55.55.55/32'), {}), + (('Loopback0', '11.11.11.11/32'), {}), + ] + ) + res = TemplateFabric.pfx_filter(src) + assert dict(res) == dict(expected) + +def test_pfx_filter_pfx_v6_w_mask(): + src = { + ('Loopback0', 'fc00::/128'): {}, + ('Loopback1', 'fc00::1/128'): {}, + } + expected = OrderedDict( + [ + (('Loopback0', 'fc00::/128'), {}), + (('Loopback1', 'fc00::1/128'), {}), + ] + ) + res = TemplateFabric.pfx_filter(src) + assert res == expected + +def test_pfx_filter_pfx_v4_no_mask(): + src = { + ('Loopback0', '11.11.11.11'): {}, + ('Loopback1', '55.55.55.55'): {}, + } + expected = OrderedDict( + [ + (('Loopback1', '55.55.55.55/32'), {}), + (('Loopback0', '11.11.11.11/32'), {}), + ] + ) + res = TemplateFabric.pfx_filter(src) + assert dict(res) == dict(expected) + +def test_pfx_filter_pfx_v6_no_mask(): + src = { + ('Loopback0', 'fc00::'): {}, + ('Loopback1', 'fc00::1'): {}, + } + expected = OrderedDict( + [ + (('Loopback0', 'fc00::/128'), {}), + (('Loopback1', 'fc00::1/128'), {}), + ] + ) + res = TemplateFabric.pfx_filter(src) + assert res == expected + + +def test_pfx_filter_pfx_comprehensive(): + src = { + 'Loopback0': {}, + ('Loopback0', 'fc00::'): {}, + 'Loopback1': {}, + ('Loopback1', 'fc00::1/128'): {}, + ('Loopback2', '11.11.11.11/32'): {}, + ('Loopback3', '55.55.55.55'): {}, + 'Loopback2': {}, + 'Loopback3': {}, + ('Loopback5', '22.22.22.1/24'): {}, + ('Loopback6', 'fc00::55/64'): {}, + } + expected = OrderedDict( + [ + (('Loopback1', 'fc00::1/128'), {}), + (('Loopback3', '55.55.55.55/32'), {}), + (('Loopback6', 'fc00::55/64'), {}), + (('Loopback2', '11.11.11.11/32'), {}), + (('Loopback0', 'fc00::/128'), {}), + (('Loopback5', '22.22.22.1/24'), {}), + ] + ) + res = TemplateFabric.pfx_filter(src) + assert dict(res) == dict(expected) + +@pytest.fixture +def test_pfx_filter_wrong_ip(caplog): + src = { + ('Loopback0', 'wrong_ip'): {}, + } + res = TemplateFabric.pfx_filter(src) + assert "'wrong_ip' is invalid ip address" in caplog.text + assert isinstance(res, OrderedDict) and len(res) == 0 + diff --git a/src/sonic-bgpcfgd/tests/test_setsrc.py b/src/sonic-bgpcfgd/tests/test_setsrc.py new file mode 100644 index 000000000000..5d1a81908837 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/test_setsrc.py @@ -0,0 +1,62 @@ +from unittest.mock import MagicMock, patch + +import os +from bgpcfgd.directory import Directory +from bgpcfgd.template import TemplateFabric +from copy import deepcopy +from . import swsscommon_test +from swsscommon import swsscommon + +with patch.dict("sys.modules", swsscommon=swsscommon_test): + from bgpcfgd.managers_setsrc import ZebraSetSrc + +TEMPLATE_PATH = os.path.abspath('../../dockers/docker-fpm-frr/frr') + +def constructor(): + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(TEMPLATE_PATH), + 'constants': {}, + } + + m = ZebraSetSrc(common_objs, "STATE_DB", swsscommon.STATE_INTERFACE_TABLE_NAME) + assert m.lo_ipv4 == None + assert m.lo_ipv6 == None + + return m + +@patch('bgpcfgd.managers_setsrc.log_info') +def test_set_handler(mocked_log_info): + m = constructor() + res = m.set_handler("Loopback0|10.1.0.32/32", {"state": "ok"}) + assert res, "Returns always True" + mocked_log_info.assert_called_with("The 'set src' configuration with Loopback0 ip '10.1.0.32' has been scheduled to be added") + +@patch('bgpcfgd.managers_setsrc.log_err') +def test_set_handler_no_slash(mocked_log_err): + m = constructor() + res = m.set_handler("Loopback0|10.1.0.32", {"state": "ok"}) + assert res, "Returns always True" + mocked_log_err.assert_called_with("Wrong Loopback0 ip prefix: '10.1.0.32'") + +@patch('bgpcfgd.managers_setsrc.log_info') +def test_set_handler_ipv6(mocked_log_info): + m = constructor() + res = m.set_handler("Loopback0|FC00:1::32/128", {"state": "ok"}) + assert res, "Returns always True" + mocked_log_info.assert_called_with("The 'set src' configuration with Loopback0 ip 'FC00:1::32' has been scheduled to be added") + +@patch('bgpcfgd.managers_setsrc.log_err') +def test_set_handler_invalid_ip(mocked_log_err): + m = constructor() + res = m.set_handler("Loopback0|invalid/ip", {"state": "ok"}) + assert res, "Returns always True" + mocked_log_err.assert_called_with("Got ambiguous ip address 'invalid'") + +@patch('bgpcfgd.managers_setsrc.log_warn') +def test_del_handler(mocked_log_warn): + m = constructor() + m.del_handler("Loopback0|10.1.0.32/32") + mocked_log_warn.assert_called_with("Delete command is not supported for 'zebra set src' templates") diff --git a/src/sonic-bgpcfgd/tests/test_sonic-cfggen.py b/src/sonic-bgpcfgd/tests/test_sonic-cfggen.py new file mode 100644 index 000000000000..a9c93749d5c4 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/test_sonic-cfggen.py @@ -0,0 +1,136 @@ +import os +import subprocess + +from bgpcfgd.config import ConfigMgr + + +TEMPLATE_PATH = os.path.abspath('../../dockers/docker-fpm-frr/frr') +DATA_PATH = "tests/data/sonic-cfggen/" +CONSTANTS_PATH = os.path.abspath('../../files/image_config/constants/constants.yml') + + +def run_test(name, template_path, json_path, match_path): + template_path = os.path.join(TEMPLATE_PATH, template_path) + json_path = os.path.join(DATA_PATH, json_path) + command = ['sonic-cfggen', "-T", TEMPLATE_PATH, "-t", template_path, "-y", json_path] + p = subprocess.Popen(command, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = p.communicate() + assert p.returncode == 0, "sonic-cfggen for %s test returned %d code. stderr='%s'" % (name, p.returncode, stderr) + raw_generated_result = stdout.decode("ascii") + assert "None" not in raw_generated_result, "Test %s" % name + canonical_generated_result = ConfigMgr.to_canonical(raw_generated_result) + match_path = os.path.join(DATA_PATH, match_path) + # only for development write_result(match_path, raw_generated_result) + with open(match_path) as result_fp: + raw_saved_result = result_fp.read() + canonical_saved_result = ConfigMgr.to_canonical(raw_saved_result) + assert canonical_saved_result == canonical_generated_result, "Test %s" % name + + +def test_bgpd_main_conf_base(): + run_test("Base bgpd.main.conf.j2", + "bgpd/bgpd.main.conf.j2", + "bgpd.main.conf.j2/base.json", + "bgpd.main.conf.j2/base.conf") + +def test_bgpd_main_conf_comprehensive(): + run_test("Comprehensive bgpd.main.conf.j2", + "bgpd/bgpd.main.conf.j2", + "bgpd.main.conf.j2/all.json", + "bgpd.main.conf.j2/all.conf") + +def test_bgpd_main_conf_defaults(): + run_test("Defaults bgpd.main.conf.j2", + "bgpd/bgpd.main.conf.j2", + "bgpd.main.conf.j2/defaults.json", + "bgpd.main.conf.j2/defaults.conf") + +def test_tsa_isolate(): + run_test("tsa/bgpd.tsa.isolate.conf.j2", + "bgpd/tsa/bgpd.tsa.isolate.conf.j2", + "tsa/isolate.json", + "tsa/isolate.conf") + +def test_tsa_unisolate(): + run_test("tsa/bgpd.tsa.unisolate.conf.j2", + "bgpd/tsa/bgpd.tsa.unisolate.conf.j2", + "tsa/unisolate.json", + "tsa/unisolate.conf") + +def test_common_daemons(): + run_test("daemons.common.conf.j2", + "common/daemons.common.conf.j2", + "common/daemons.common.conf.json", + "common/daemons.common.conf") + +def test_common_functions(): + run_test("functions.conf.j2", + "common/functions.conf.j2", + "common/functions.conf.json", + "common/functions.conf") + +def test_staticd_default_route(): + run_test("staticd.default_route.conf.j2", + "staticd/staticd.default_route.conf.j2", + "staticd/staticd.default_route.conf.json", + "staticd/staticd.default_route.conf") + +def test_staticd_loopback_route(): + run_test("staticd.loopback_route.conf.j2", + "staticd/staticd.loopback_route.conf.j2", + "staticd/staticd.loopback_route.conf.json", + "staticd/staticd.loopback_route.conf") + +def test_staticd(): + run_test("staticd.conf.j2", + "staticd/staticd.conf.j2", + "staticd/staticd.conf.json", + "staticd/staticd.conf") + +def test_zebra_interfaces(): + run_test("zebra.interfaces.conf.j2", + "zebra/zebra.interfaces.conf.j2", + "zebra/interfaces.json", + "zebra/interfaces.conf") + +def test_zebra_set_src(): + run_test("zebra.set_src.conf.j2", + "zebra/zebra.set_src.conf.j2", + "zebra/set_src.json", + "zebra/set_src.conf") + +def test_zebra(): + run_test("zebra.conf.j2", + "zebra/zebra.conf.j2", + "zebra/zebra.conf.json", + "zebra/zebra.conf") + +def test_isolate(): + run_test("isolate.j2", + "isolate.j2", + "isolate/isolate.json", + "isolate/isolate") + +def test_unisolate(): + run_test("unisolate.j2", + "unisolate.j2", + "isolate/unisolate.json", + "isolate/unisolate") + +def test_frr_conf(): + run_test("frr.conf.j2", + "frr.conf.j2", + "frr.conf.j2/all.json", + "frr.conf.j2/all.conf") + +def test_l3vpn_base(): + run_test("bgpd spine_chassis_frontend_router.conf.j2", + "bgpd/bgpd.spine_chassis_frontend_router.conf.j2", + "bgpd.spine_chassis_frontend_router.conf.j2/base.json", + "bgpd.spine_chassis_frontend_router.conf.j2/base.conf") + +def test_bgp_conf_all(): + run_test("bgpd/bgpd.conf", + "bgpd/bgpd.conf.j2", + "bgpd.conf.j2/all.json", + "bgpd.conf.j2/all.conf") diff --git a/src/sonic-bgpcfgd/tests/test_templates.py b/src/sonic-bgpcfgd/tests/test_templates.py new file mode 100644 index 000000000000..7d3bc773ad16 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/test_templates.py @@ -0,0 +1,142 @@ +import os +import json + + +from bgpcfgd.template import TemplateFabric +from bgpcfgd.config import ConfigMgr +from .util import load_constants_dir_mappings + + +TEMPLATE_PATH = os.path.abspath('../../dockers/docker-fpm-frr/frr') + + +def load_tests(peer_type, template_name): + constants = load_constants_dir_mappings() + path = "tests/data/%s/%s" % (constants[peer_type], template_name) + param_files = [name for name in os.listdir(path) + if os.path.isfile(os.path.join(path, name)) and name.startswith("param_")] + tests = [] + for param_fname in param_files: + casename = param_fname.replace("param_", "").replace(".json", "") + result_fname = "result_%s.conf" % casename + full_param_fname = os.path.join(path, param_fname) + full_result_fname = os.path.join(path, result_fname) + tests.append((casename, full_param_fname, full_result_fname)) + tmpl_path = os.path.join("bgpd", "templates", constants[peer_type], "%s.j2" % template_name) + return tmpl_path, tests + +def load_json(fname): + with open(fname) as param_fp: + raw_params = json.load(param_fp) + params = {} + for table_key, table_entries in raw_params.items(): + if table_key.startswith("CONFIG_DB__"): + # convert CONFIG_DB__* entries keys into tuple if needed + new_table_entries = {} + for entry_key, entry_value in table_entries.items(): + if '|' in entry_key: + new_key = tuple(entry_key.split('|')) + else: + new_key = entry_key + new_table_entries[new_key] = entry_value + params[table_key] = new_table_entries + else: + params[table_key] = table_entries + return params + +def compress_comments(raw_config): + comment_counter = 0 + output = [] + for line in raw_config.split('\n'): + stripped_line = line.strip() + # Skip empty lines + if stripped_line == '': + pass + # Write lines without comments + elif not stripped_line.startswith('!'): + if comment_counter > 0: + output.append("!") + comment_counter = 0 + output.append(line) + # Write non-empty comments + elif stripped_line.startswith('!') and len(stripped_line) > 1: + if comment_counter > 0: + output.append("!") + comment_counter = 0 + output.append(line) + # Count empty comments + else: # stripped_line == '!' + comment_counter += 1 + # Flush last comment if we have one + if comment_counter > 0: + output.append("!") + return "\n".join(output) + "\n" + +def write_result(fname, raw_result): + with open(fname, 'w') as fp: + raw_result_w_commpressed_comments = compress_comments(raw_result) + fp.write(raw_result_w_commpressed_comments) + +def run_tests(test_name, template_fname, tests): + tf = TemplateFabric(TEMPLATE_PATH) + template = tf.from_file(template_fname) + for case_name, param_fname, result_fname in tests: + params = load_json(param_fname) + raw_generated_result = str(template.render(params)) + assert "None" not in raw_generated_result, "Test %s.%s" % (test_name, case_name) + # this is used only for initial generation write_result(result_fname, raw_generated_result) + canonical_generated_result = ConfigMgr.to_canonical(raw_generated_result) + with open(result_fname) as result_fp: + raw_saved_result = result_fp.read() + canonical_saved_result = ConfigMgr.to_canonical(raw_saved_result) + assert canonical_saved_result == canonical_generated_result, "Test %s.%s" % (test_name, case_name) + +# Tests + +def test_general_policies(): + test_data = load_tests("general", "policies.conf") + run_tests("general_policies", *test_data) + +def test_general_pg(): + test_data = load_tests("general", "peer-group.conf") + run_tests("general_pg", *test_data) + +def test_general_instance(): + test_data = load_tests("general", "instance.conf") + run_tests("general_instance", *test_data) + +def test_internal_policies(): + test_data = load_tests("internal", "policies.conf") + run_tests("internal_policies", *test_data) + +def test_internal_pg(): + test_data = load_tests("internal", "peer-group.conf") + run_tests("internal_pg", *test_data) + +def test_internal_instance(): + test_data = load_tests("internal", "instance.conf") + run_tests("internal_instance", *test_data) + +def test_dynamic_policies(): + test_data = load_tests("dynamic", "policies.conf") + run_tests("dynamic_policies", *test_data) + +def test_dynamic_pg(): + test_data = load_tests("dynamic", "peer-group.conf") + run_tests("dynamic_pg", *test_data) + +def test_dynamic_instance(): + test_data = load_tests("dynamic", "instance.conf") + run_tests("dynamic_instance", *test_data) + +def test_monitors_policies(): + test_data = load_tests("monitors", "policies.conf") + run_tests("monitors_policies", *test_data) + +def test_monitors_pg(): + test_data = load_tests("monitors", "peer-group.conf") + run_tests("monitors_pg", *test_data) + +def test_monitors_instance(): + test_data = load_tests("monitors", "instance.conf") + run_tests("monitors_instance", *test_data) diff --git a/src/sonic-bgpcfgd/tests/util.py b/src/sonic-bgpcfgd/tests/util.py new file mode 100644 index 000000000000..a328a272c836 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/util.py @@ -0,0 +1,20 @@ +import os +import yaml + +CONSTANTS_PATH = os.path.abspath('../../files/image_config/constants/constants.yml') + +def load_constants_dir_mappings(): + data = load_constants() + result = {} + assert "bgp" in data["constants"], "'bgp' key not found in constants.yml" + assert "peers" in data["constants"]["bgp"], "'peers' key not found in constants.yml" + for name, value in data["constants"]["bgp"]["peers"].items(): + assert "template_dir" in value, "'template_dir' key not found for peer '%s'" % name + result[name] = value["template_dir"] + return result + +def load_constants(): + with open(CONSTANTS_PATH) as f: + data = yaml.load(f) # FIXME" , Loader=yaml.FullLoader) + assert "constants" in data, "'constants' key not found in constants.yml" + return data diff --git a/src/sonic-build-hooks/.gitignore b/src/sonic-build-hooks/.gitignore new file mode 100644 index 000000000000..4490afae4a5e --- /dev/null +++ b/src/sonic-build-hooks/.gitignore @@ -0,0 +1,2 @@ +buildinfo +tmp diff --git a/src/sonic-build-hooks/Makefile b/src/sonic-build-hooks/Makefile new file mode 100644 index 000000000000..786af9056332 --- /dev/null +++ b/src/sonic-build-hooks/Makefile @@ -0,0 +1,39 @@ +SONIC_BUILD_HOOKS = sonic-build-hooks +SONIC_BUILD_HOOKS_VERSION = 1.0 +SONIC_BUILD_HOOKS_PACKAGE = $(SONIC_BUILD_HOOKS)_$(SONIC_BUILD_HOOKS_VERSION)_all.deb + +BUILDINFO_DIR = buildinfo +TMP_DIR = tmp +SYMBOL_LINKS_SRC_DIR = ../../usr/local/share/buildinfo/scripts +SYMBOL_LINKS = symlink_build_hooks post_run_buildinfo pre_run_buildinfo collect_version_files +SONIC_BUILD_HOOKS_TARGET = $(BUILDINFO_DIR)/$(SONIC_BUILD_HOOKS_PACKAGE) +BUILD_ROOT_DIR = $(TMP_DIR)/$(SONIC_BUILD_HOOKS) +DEBIAN_DIR = $(BUILD_ROOT_DIR)/DEBIAN +TRUSTED_GPG_PATH = $(BUILD_ROOT_DIR)/etc/apt/trusted.gpg.d +INSTALL_PATH = $(BUILD_ROOT_DIR)/usr/local/share/buildinfo +SYMBOL_LINK_PATH = $(BUILD_ROOT_DIR)/usr/sbin +SCRIPTS_PATH = $(INSTALL_PATH)/scripts +HOOKS_PATH = $(INSTALL_PATH)/hooks +DPKGTOOL = $(shell which dpkg-deb) + + +# If the depk-deb not installed, use the docker container to make the debian package +ifeq ($(shell which dpkg-deb),) +BUILD_COMMAND=docker run --user $(shell id -u):$(shell id -g) --rm -v $(shell pwd):/build debian:buster bash -c 'cd /build; dpkg-deb --build $(TMP_DIR)/$(SONIC_BUILD_HOOKS) $(SONIC_BUILD_HOOKS_TARGET)' +else +BUILD_COMMAND=dpkg-deb --build $(TMP_DIR)/$(SONIC_BUILD_HOOKS) $(SONIC_BUILD_HOOKS_TARGET) +endif + +DEPENDS := $(shell find scripts hooks debian -type f) +$(SONIC_BUILD_HOOKS_TARGET): $(DEPENDS) + @rm -rf $(BUILDINFO_DIR)/$(SONIC_BUILD_HOOKS) $(TMP_DIR) + @mkdir -p $(DEBIAN_DIR) $(SCRIPTS_PATH) $(HOOKS_PATH) $(SYMBOL_LINK_PATH) $(TRUSTED_GPG_PATH) $(BUILDINFO_DIR) + @chmod 0775 $(DEBIAN_DIR) + @cp debian/* $(DEBIAN_DIR)/ + @cp scripts/* $(SCRIPTS_PATH)/ + @cp hooks/* $(HOOKS_PATH)/ + @for url in $$(echo $(TRUSTED_GPG_URLS) | sed 's/[,;]/ /g'); do wget -q "$$url" -P "$(TRUSTED_GPG_PATH)/"; done + @for f in $(SYMBOL_LINKS); do ln -s $(SYMBOL_LINKS_SRC_DIR)/$$f $(SYMBOL_LINK_PATH)/$$f; done + @$(BUILD_COMMAND) + +all: $(SONIC_BUILD_HOOKS_TARGET) diff --git a/src/sonic-build-hooks/debian/control b/src/sonic-build-hooks/debian/control new file mode 100644 index 000000000000..9e2454be9d95 --- /dev/null +++ b/src/sonic-build-hooks/debian/control @@ -0,0 +1,10 @@ +Package: sonic-build-hooks +Version: 1.0 +Section: devel +Priority: optional +Architecture: all +Depends: +Maintainer: SONiC +Description: sonic build hooks + Hooks the build tools, such as apt-get, wget, pip, etc. + It is used to monitor and control the packages installed during the build. diff --git a/src/sonic-build-hooks/hooks/apt-get b/src/sonic-build-hooks/hooks/apt-get new file mode 100755 index 000000000000..9ae50a118650 --- /dev/null +++ b/src/sonic-build-hooks/hooks/apt-get @@ -0,0 +1,38 @@ +#!/bin/bash + +INSTALL= +. /usr/local/share/buildinfo/scripts/buildinfo_base.sh + +REAL_COMMAND=$(get_command apt-get) +if [ -z "$REAL_COMMAND" ]; then + echo "The command apt-get does not exist." 1>&2 + exit 1 +fi + +VERSION_FILE="/usr/local/share/buildinfo/versions/versions-deb" +if [ "$ENABLE_VERSION_CONTROL_DEB" == "y" ]; then + for para in $@ + do + if [[ "$para" != -* ]]; then + continue + fi + if [ ! -z "$INSTALL" ]; then + if [[ "$para" == *=* ]]; then + continue + elif [[ "$para" == *=* ]]; then + continue + else + package=$para + if ! grep -q "^${package}=" $VERSION_FILE; then + echo "The version of the package ${package} is not specified." + exit 1 + fi + fi + elif [[ "$para" == "install" ]]; then + INSTALL=y + fi + done +fi + + +$REAL_COMMAND "$@" diff --git a/src/sonic-build-hooks/hooks/curl b/src/sonic-build-hooks/hooks/curl new file mode 100755 index 000000000000..58bfe0395e55 --- /dev/null +++ b/src/sonic-build-hooks/hooks/curl @@ -0,0 +1,6 @@ +#!/bin/bash + +. /usr/local/share/buildinfo/scripts/buildinfo_base.sh +[ -z $REAL_COMMAND ] && REAL_COMMAND=/usr/bin/curl + +REAL_COMMAND=$REAL_COMMAND download_packages "$@" diff --git a/src/sonic-build-hooks/hooks/git b/src/sonic-build-hooks/hooks/git new file mode 100755 index 000000000000..644a01d5fe1e --- /dev/null +++ b/src/sonic-build-hooks/hooks/git @@ -0,0 +1,76 @@ +#!/bin/bash + +parse_config(){ + . /usr/local/share/buildinfo/scripts/buildinfo_base.sh + REAL_COMMAND=$(get_command git) + + version_file=$VERSION_PATH/versions-git + new_version_file=$BUILD_VERSION_PATH/versions-git + + MODE_CLONE=0 + # parse input parameters + for i in "$@" + do + if [[ $i == "clone" ]];then + MODE_CLONE=1 + fi + done +} + +get_clone_path(){ + # get paremater of clone path + while (( "$#" )); do + case $1 in + -b|--branch|--reference|--reference-if-able|-c|--config|--origin|-u|--upload-pack|-j|--jobs|--depth|--dissociate) + shift 2 + ;; + clone|-l|--local|--no-hardlinks|-s|--shared|--dissociate|-q|--quiet|-v|--verbose|--progress|--server-option=*|--bare|--sparse|--filter=*|--template=*|--mirror|--reference|--shallow-*|--no-tags|--recurse-submodules*|--remote-submodules|--no-remote-submodules|--separate-git-dir*) + shift 1 + ;; + *) + if [[ $URL == "" ]];then + URL=$1 + else + clone_PATH=$1 + fi + shift 1 + ;; + esac + done + + # if not specific clone path, get default clone path + [ -z $clone_PATH ] && clone_PATH=`echo $URL | rev | awk -F/ '{print$1}' | rev | awk -F. '{print$1}'` +} + +main(){ + parse_config "$@" + + # execute git. + $REAL_COMMAND "$@" + result=$? + + # if sub command is not "clone", exit + if [[ $MODE_CLONE != 1 ]];then + exit $result + fi + + get_clone_path "$@" + pushd $clone_PATH &> /dev/null + commit_latest=`$REAL_COMMAND log -n 1 | head -n 1| awk '{print$2}'` + [ -f $version_file ] && commit=`grep $URL $version_file | awk -F, '{print$2}'` + + # control version or record version file + if [[ $ENABLE_VERSION_CONTROL_GIT == "y" ]];then + # control version + [ ! -z $commit ] && $REAL_COMMAND reset --hard $commit &> /dev/null + else + # record version file + echo "$URL==$commit_latest" >> $new_version_file + sort $new_version_file -o $new_version_file -u &> /dev/null + fi + popd &> /dev/null + + exit $result +} + +main "$@" diff --git a/src/sonic-build-hooks/hooks/pip b/src/sonic-build-hooks/hooks/pip new file mode 120000 index 000000000000..b31c5d8ca9d0 --- /dev/null +++ b/src/sonic-build-hooks/hooks/pip @@ -0,0 +1 @@ +pip2 \ No newline at end of file diff --git a/src/sonic-build-hooks/hooks/pip2 b/src/sonic-build-hooks/hooks/pip2 new file mode 100755 index 000000000000..e2ccfff2aac0 --- /dev/null +++ b/src/sonic-build-hooks/hooks/pip2 @@ -0,0 +1,13 @@ +#!/bin/bash + +. /usr/local/share/buildinfo/scripts/buildinfo_base.sh + +VERSION_FILE="$BUILDINFO_PATH/versions/versions-py2" +REAL_COMMAND=$(get_command pip2) + +if [ ! -x "$REAL_COMMAND" ]; then + echo "The command pip2 not found" 1>&2 + exit 1 +fi + +PIP_VERSION_FILE=$VERSION_FILE ENABLE_VERSION_CONTROL_PY=$ENABLE_VERSION_CONTROL_PY2 REAL_COMMAND=$REAL_COMMAND run_pip_command "$@" diff --git a/src/sonic-build-hooks/hooks/pip3 b/src/sonic-build-hooks/hooks/pip3 new file mode 100755 index 000000000000..36a8fd93a13d --- /dev/null +++ b/src/sonic-build-hooks/hooks/pip3 @@ -0,0 +1,12 @@ +#!/bin/bash + +. /usr/local/share/buildinfo/scripts/buildinfo_base.sh + +VERSION_FILE="$BUILDINFO_PATH/versions/versions-py3" +REAL_COMMAND=$(get_command pip3) +if [ ! -x "$REAL_COMMAND" ]; then + echo "The command pip3 not found" 1>&2 + exit 1 +fi + +PIP_VERSION_FILE=$VERSION_FILE ENABLE_VERSION_CONTROL_PY=$ENABLE_VERSION_CONTROL_PY2 REAL_COMMAND=$REAL_COMMAND run_pip_command "$@" diff --git a/src/sonic-build-hooks/hooks/wget b/src/sonic-build-hooks/hooks/wget new file mode 100755 index 000000000000..c4cb1a3d1be9 --- /dev/null +++ b/src/sonic-build-hooks/hooks/wget @@ -0,0 +1,15 @@ +#!/bin/bash + +. /usr/local/share/buildinfo/scripts/buildinfo_base.sh +[ -z $REAL_COMMAND ] && REAL_COMMAND=$(get_command wget) +if [ -z "$REAL_COMMAND" ]; then + echo "The command wget does not exist." 1>&2 + exit 1 +fi + +if [ "$SKIP_BUILD_HOOK" == y ]; then + $REAL_COMMAND "$@" + exit $? +fi + +REAL_COMMAND=$REAL_COMMAND download_packages "$@" diff --git a/src/sonic-build-hooks/scripts/buildinfo_base.sh b/src/sonic-build-hooks/scripts/buildinfo_base.sh new file mode 100755 index 000000000000..ae85c2dcf129 --- /dev/null +++ b/src/sonic-build-hooks/scripts/buildinfo_base.sh @@ -0,0 +1,161 @@ +#!/bin/bash + +BUILDINFO_PATH=/usr/local/share/buildinfo + +LOG_PATH=$BUILDINFO_PATH/log +VERSION_PATH=$BUILDINFO_PATH/versions +PRE_VERSION_PATH=$BUILDINFO_PATH/pre-versions +DIFF_VERSION_PATH=$BUILDINFO_PATH/diff-versions +BUILD_VERSION_PATH=$BUILDINFO_PATH/build-versions +POST_VERSION_PATH=$BUILDINFO_PATH/post-versions +VERSION_DEB_PREFERENCE=$BUILDINFO_PATH/versions/01-versions-deb +WEB_VERSION_FILE=$VERSION_PATH/versions-web +BUILD_WEB_VERSION_FILE=$BUILD_VERSION_PATH/versions-web + +. $BUILDINFO_PATH/config/buildinfo.config + +URL_PREFIX=$(echo "${PACKAGE_URL_PREFIX}" | sed -E "s#(//[^/]*/).*#\1#") + +log_err() +{ + echo "$1" >> $LOG_PATH/error.log + echo "$1" 1>&2 +} + +# Get the real command not hooked by sonic-build-hook package +get_command() +{ + # Change the PATH env to get the real command by excluding the command in the hooked folders + local path=$(echo $PATH | sed 's#[^:]*buildinfo/scripts:##' | sed "s#/usr/local/sbin:##") + local command=$(PATH=$path which $1) + echo $command +} + +check_version_control() +{ + # The env variable SONIC_VERSION_CONTROL_COMPONENTS examples: + # all -- match all components + # py2,py3,deb -- match py2, py3 and deb only + if [[ ",$SONIC_VERSION_CONTROL_COMPONENTS," == *,all,* ]] || [[ ",$SONIC_VERSION_CONTROL_COMPONENTS," == *,$1,* ]]; then + echo "y" + else + echo "n" + fi +} + +get_url_version() +{ + local package_url=$1 + /usr/bin/curl -Lks $package_url | md5sum | cut -d' ' -f1 +} + +check_if_url_exist() +{ + local url=$1 + if /usr/bin/curl --output /dev/null --silent --head --fail "$1" > /dev/null 2>&1; then + echo y + else + echo n + fi +} + +download_packages() +{ + local parameters=("$@") + local filenames= + declare -A filenames + for (( i=0; i<${#parameters[@]}; i++ )) + do + local para=${parameters[$i]} + local nexti=$((i+1)) + if [[ "$para" == *://* ]]; then + local url=$para + local real_version= + if [ "$ENABLE_VERSION_CONTROL_WEB" == y ]; then + local version= + local filename=$(echo $url | awk -F"/" '{print $NF}' | cut -d? -f1 | cut -d# -f1) + [ -f $WEB_VERSION_FILE ] && version=$(grep "^${url}=" $WEB_VERSION_FILE | awk -F"==" '{print $NF}') + if [ -z "$version" ]; then + echo "Failed to verify the package: $url, the version is not specified" 2>&1 + exit 1 + fi + + local version_filename="${filename}-${version}" + local proxy_url="${PACKAGE_URL_PREFIX}/${version_filename}" + local url_exist=$(check_if_url_exist $proxy_url) + if [ "$url_exist" == y ]; then + parameters[$i]=$proxy_url + filenames[$version_filename]=$filename + real_version=$version + else + real_version=$(get_url_version $url) + if [ "$real_version" != "$version" ]; then + echo "Failed to verify url: $url, real hash value: $real_version, expected value: $version_filename" 1>&2 + exit 1 + fi + fi + else + real_version=$(get_url_version $url) + fi + + echo "$url==$real_version" >> ${BUILD_WEB_VERSION_FILE} + fi + done + + $REAL_COMMAND "${parameters[@]}" + local result=$? + + for filename in "${!filenames[@]}" + do + [ -f "$filename" ] && mv "$filename" "${filenames[$filename]}" + done + + return $result +} + +run_pip_command() +{ + parameters=("$@") + + if [ ! -x "$REAL_COMMAND" ] && [ " $1" == "freeze" ]; then + return 1 + fi + + if [ "$ENABLE_VERSION_CONTROL_PY" != "y" ]; then + $REAL_COMMAND "$@" + return $? + fi + + local found=n + local install=n + local pip_version_file=$PIP_VERSION_FILE + local tmp_version_file=$(mktemp) + [ -f "$pip_version_file" ] && cp -f $pip_version_file $tmp_version_file + for para in "${parameters[@]}" + do + ([ "$para" == "-c" ] || [ "$para" == "--constraint" ]) && found=y + if [ "$para" == "install" ]; then + install=y + elif [[ "$para" == *.whl ]]; then + package_name=$(echo $para | cut -d- -f1 | tr _ .) + sed "/^${package_name}==/d" -i $tmp_version_file + fi + done + + if [ "$found" == "n" ] && [ "$install" == "y" ]; then + parameters+=("-c") + parameters+=("${tmp_version_file}") + fi + + $REAL_COMMAND "${parameters[@]}" + local result=$? + rm $tmp_version_file + return $result +} + +ENABLE_VERSION_CONTROL_DEB=$(check_version_control "deb") +ENABLE_VERSION_CONTROL_PY2=$(check_version_control "py2") +ENABLE_VERSION_CONTROL_PY3=$(check_version_control "py3") +ENABLE_VERSION_CONTROL_WEB=$(check_version_control "web") +ENABLE_VERSION_CONTROL_GIT=$(check_version_control "git") +ENABLE_VERSION_CONTROL_DOCKER=$(check_version_control "docker") diff --git a/src/sonic-build-hooks/scripts/collect_version_files b/src/sonic-build-hooks/scripts/collect_version_files new file mode 100755 index 000000000000..b62beb4a2115 --- /dev/null +++ b/src/sonic-build-hooks/scripts/collect_version_files @@ -0,0 +1,14 @@ +#!/bin/bash + +TARGET_PATH=$1 +ARCH=$(dpkg --print-architecture) +DIST=$(grep VERSION_CODENAME /etc/os-release | cut -d= -f2) +([ -z "$DIST" ] && grep -q jessie /etc/os-release) && DIST=jessie + +mkdir -p $TARGET_PATH +chmod a+rw $TARGET_PATH +dpkg-query -W -f '${Package}==${Version}\n' > "${TARGET_PATH}/versions-deb-${DIST}-${ARCH}" +([ -x "/usr/local/bin/pip2" ] || [ -x "/usr/bin/pip2" ]) && pip2 freeze > "${TARGET_PATH}/versions-py2-${DIST}-${ARCH}" +([ -x "/usr/local/bin/pip3" ] || [ -x "/usr/bin/pip3" ]) && pip3 freeze > "${TARGET_PATH}/versions-py3-${DIST}-${ARCH}" + +exit 0 diff --git a/src/sonic-build-hooks/scripts/post_run_buildinfo b/src/sonic-build-hooks/scripts/post_run_buildinfo new file mode 100755 index 000000000000..a8dab41021b1 --- /dev/null +++ b/src/sonic-build-hooks/scripts/post_run_buildinfo @@ -0,0 +1,14 @@ +#!/bin/bash + +. /usr/local/share/buildinfo/scripts/buildinfo_base.sh + +[ -d $POST_VERSION_PATH ] && rm -rf $POST_VERSION_PATH + +# Collect the version files +collect_version_files $POST_VERSION_PATH + +[ -d $BUILD_VERSION_PATH ] && [ ! -z "$(ls -A $BUILD_VERSION_PATH)" ] && cp -rf $BUILD_VERSION_PATH/* $POST_VERSION_PATH +rm -rf $BUILD_VERSION_PATH/* + +# Disable the build hooks +symlink_build_hooks -d diff --git a/src/sonic-build-hooks/scripts/pre_run_buildinfo b/src/sonic-build-hooks/scripts/pre_run_buildinfo new file mode 100755 index 000000000000..a8450690b6ff --- /dev/null +++ b/src/sonic-build-hooks/scripts/pre_run_buildinfo @@ -0,0 +1,20 @@ +#!/bin/bash + +. /usr/local/share/buildinfo/scripts/buildinfo_base.sh + +[ -d $DIFF_VERSION_PATH ] && rm -rf $DIFF_VERSION_PATH +mkdir -p $DIFF_VERSION_PATH +mkdir -p $BUILD_VERSION_PATH +mkdir -p $LOG_PATH + +[ -d $PRE_VERSION_PATH ] && rm -rf $PRE_VERSION_PATH +collect_version_files $PRE_VERSION_PATH +symlink_build_hooks + +chmod -R a+rw $BUILDINFO_PATH + +if [ "$ENABLE_VERSION_CONTROL_DEB" == "y" ] && [ -f $VERSION_DEB_PREFERENCE ]; then + cp -f $VERSION_DEB_PREFERENCE /etc/apt/preferences.d/ +fi + +exit 0 diff --git a/src/sonic-build-hooks/scripts/symlink_build_hooks b/src/sonic-build-hooks/scripts/symlink_build_hooks new file mode 100755 index 000000000000..2ce5ec27720f --- /dev/null +++ b/src/sonic-build-hooks/scripts/symlink_build_hooks @@ -0,0 +1,34 @@ +#!/bin/bash + +HOOK_PATH=/usr/local/share/buildinfo/hooks +TARGET_PATH=/usr/local/sbin +FILES=$(ls $HOOK_PATH) + +usage() +{ + echo "Usage: $0 [-d]" + exit 1 +} + +DISABLE=n +while getopts "d" opt; do + case $opt in + d) + DISABLE=y + ;; + *) + usage + ;; + esac +done + +for f in $FILES +do + if [ $DISABLE == "n" ]; then + [ ! -e $TARGET_PATH/$f ] && ln -s $HOOK_PATH/$f $TARGET_PATH/$f + else + ([ -e $TARGET_PATH/$f ] && ls -l $TARGET_PATH/$f | grep -q $HOOK_PATH) && rm -f $TARGET_PATH/$f + fi +done + +exit 0 diff --git a/src/sonic-config-engine/.gitignore b/src/sonic-config-engine/.gitignore new file mode 100644 index 000000000000..8562c3d1344c --- /dev/null +++ b/src/sonic-config-engine/.gitignore @@ -0,0 +1,7 @@ +**/*.pyc +*.egg-info/ +.eggs/ +build/ +dist/ +tests/output +tests/output2 diff --git a/src/sonic-config-engine/__init__.py b/src/sonic-config-engine/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/src/sonic-config-engine/config_samples.py b/src/sonic-config-engine/config_samples.py index 1b38276524c0..9072e0209c3e 100644 --- a/src/sonic-config-engine/config_samples.py +++ b/src/sonic-config-engine/config_samples.py @@ -1,6 +1,3 @@ -#!/usr/bin/env python -import os -import sys from natsort import natsorted def generate_t1_sample_config(data): @@ -13,13 +10,13 @@ def generate_t1_sample_config(data): data['INTERFACE'] = {} port_count = 0 total_port_amount = len(data['PORT']) - for port in natsorted(data['PORT'].keys()): + for port in natsorted(data['PORT']): data['PORT'][port]['admin_status'] = 'up' data['PORT'][port]['mtu'] = '9100' - local_addr = '10.0.{}.{}'.format(2 * port_count / 256, 2 * port_count % 256) - peer_addr = '10.0.{}.{}'.format(2 * port_count / 256, 2 * port_count % 256 + 1) - peer_name='ARISTA{0:02d}{1}'.format(1+port_count%(total_port_amount/2), 'T2' if port_count < (total_port_amount/2) else 'T0') - peer_asn = 65200 if port_count < total_port_amount/2 else 64001 + port_count - total_port_amount/2 + local_addr = '10.0.{}.{}'.format(2 * port_count // 256, 2 * port_count % 256) + peer_addr = '10.0.{}.{}'.format(2 * port_count // 256, 2 * port_count % 256 + 1) + peer_name='ARISTA{0:02d}{1}'.format(1+port_count%(total_port_amount // 2), 'T2' if port_count < (total_port_amount // 2) else 'T0') + peer_asn = 65200 if port_count < (total_port_amount // 2) else 64001 + port_count - (total_port_amount // 2) data['INTERFACE']['{}|{}/31'.format(port, local_addr)] = {} data['BGP_NEIGHBOR'][peer_addr] = { 'rrclient': 0, @@ -35,22 +32,16 @@ def generate_t1_sample_config(data): def generate_empty_config(data): new_data = {'DEVICE_METADATA': data['DEVICE_METADATA']} - if not new_data['DEVICE_METADATA']['localhost'].has_key('hostname'): + if 'hostname' not in new_data['DEVICE_METADATA']['localhost']: new_data['DEVICE_METADATA']['localhost']['hostname'] = 'sonic' - if not new_data['DEVICE_METADATA']['localhost'].has_key('type'): + if 'type' not in new_data['DEVICE_METADATA']['localhost']: new_data['DEVICE_METADATA']['localhost']['type'] = 'LeafRouter' return new_data def generate_l2_config(data): - if not data['DEVICE_METADATA']['localhost'].has_key('hostname'): - data['DEVICE_METADATA']['localhost']['hostname'] = 'sonic' - if not data['DEVICE_METADATA']['localhost'].has_key('type'): - data['DEVICE_METADATA']['localhost']['type'] = 'ToRRouter' data['VLAN'] = {'Vlan1000': {'vlanid': '1000'}} - vp = natsorted(data['PORT'].keys()) - data['VLAN']['Vlan1000'].setdefault('members', vp) data['VLAN_MEMBER'] = {} - for port in natsorted(data['PORT'].keys()): + for port in natsorted(data['PORT']): data['PORT'][port].setdefault('admin_status', 'up') data['VLAN_MEMBER']['Vlan1000|{}'.format(port)] = {'tagging_mode': 'untagged'} return data @@ -62,7 +53,7 @@ def generate_l2_config(data): } def get_available_config(): - return _sample_generators.keys() + return list(_sample_generators.keys()) def generate_sample_config(data, setting_name): return _sample_generators[setting_name.lower()](data) diff --git a/src/sonic-config-engine/data/l2switch.j2 b/src/sonic-config-engine/data/l2switch.j2 index c9f166b6798b..22de3158c589 100644 --- a/src/sonic-config-engine/data/l2switch.j2 +++ b/src/sonic-config-engine/data/l2switch.j2 @@ -2,13 +2,16 @@ "DEVICE_METADATA": {{ DEVICE_METADATA | tojson }}, {% set ns = {'firstPrinted': False} -%} "PORT": { - {%- for key,value in PORT.iteritems() -%} + {%- for key, value in PORT.items() -%} {%- if ns.firstPrinted %},{% endif %} "{{ key }}": { - "alias": "{{ value.alias }}", - "lanes": "{{ value.lanes }}", - "admin_status": "up" + {%- for keyPort, valuePort in value.items() %} + + {% if keyPort != "admin_status" %}"{{ keyPort }}": "{{ valuePort }}",{% endif %} + {%- endfor %} + + "admin_status": "{{ value.admin_status|default("up") }}" } {%- if ns.update({'firstPrinted': True}) %}{% endif -%} {%- endfor %} diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 3ba6362c6ff0..06b799cdeff7 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -1,19 +1,25 @@ -#!/usr/bin/env python -import calendar +from __future__ import print_function + +import ipaddress import math import os import sys -import socket -import struct import json -import copy -import ipaddr as ipaddress from collections import defaultdict from lxml import etree as ET from lxml.etree import QName + from portconfig import get_port_config +from sonic_py_common.multi_asic import get_asic_id_from_name +from sonic_py_common.interface import backplane_prefix + +# TODO: Remove this once we no longer support Python 2 +if sys.version_info.major == 3: + UNICODE_TYPE = str +else: + UNICODE_TYPE = unicode """minigraph.py version_added: "1.9" @@ -31,9 +37,13 @@ chassis_backend_role = 'ChassisBackendRouter' backend_device_types = ['BackEndToRRouter', 'BackEndLeafRouter'] +console_device_types = ['MgmtTsToR'] VLAN_SUB_INTERFACE_SEPARATOR = '.' VLAN_SUB_INTERFACE_VLAN_ID = '10' +FRONTEND_ASIC_SUB_ROLE = 'FrontEnd' +BACKEND_ASIC_SUB_ROLE = 'BackEnd' + # Default Virtual Network Index (VNI) vni_default = 8000 @@ -52,19 +62,35 @@ def default(self, obj): return str(obj) return json.JSONEncoder.default(self, obj) +def get_peer_switch_info(link_metadata, devices): + peer_switch_table = {} + for data in link_metadata.values(): + if "PeerSwitch" in data: + peer_hostname = data["PeerSwitch"] + peer_lo_addr_str = devices[peer_hostname]["lo_addr"] + peer_lo_addr = ipaddress.ip_network(UNICODE_TYPE(peer_lo_addr_str)) if peer_lo_addr_str else None + + peer_switch_table[peer_hostname] = { + 'address_ipv4': str(peer_lo_addr.network_address) if peer_lo_addr else peer_lo_addr_str + } + + return peer_switch_table + def parse_device(device): lo_prefix = None + lo_prefix_v6 = None mgmt_prefix = None d_type = None # don't shadow type() hwsku = None name = None deployment_id = None - if str(QName(ns3, "type")) in device.attrib: - d_type = device.attrib[str(QName(ns3, "type"))] + cluster = None for node in device: if node.tag == str(QName(ns, "Address")): lo_prefix = node.find(str(QName(ns2, "IPPrefix"))).text + elif node.tag == str(QName(ns, "AddressV6")): + lo_prefix_v6 = node.find(str(QName(ns2, "IPPrefix"))).text elif node.tag == str(QName(ns, "ManagementAddress")): mgmt_prefix = node.find(str(QName(ns2, "IPPrefix"))).text elif node.tag == str(QName(ns, "Hostname")): @@ -73,9 +99,83 @@ def parse_device(device): hwsku = node.text elif node.tag == str(QName(ns, "DeploymentId")): deployment_id = node.text - return (lo_prefix, mgmt_prefix, name, hwsku, d_type, deployment_id) + elif node.tag == str(QName(ns, "ElementType")): + d_type = node.text + elif node.tag == str(QName(ns, "ClusterName")): + cluster = node.text + + if d_type is None and str(QName(ns3, "type")) in device.attrib: + d_type = device.attrib[str(QName(ns3, "type"))] + + return (lo_prefix, lo_prefix_v6, mgmt_prefix, name, hwsku, d_type, deployment_id, cluster) -def parse_png(png, hname): +def calculate_lcm_for_ecmp (nhdevices_bank_map, nhip_bank_map): + banks_enumerated = {} + lcm_array = [] + for value in nhdevices_bank_map.values(): + for key in nhip_bank_map.keys(): + if nhip_bank_map[key] == value: + if value not in banks_enumerated: + banks_enumerated[value] = 1 + else: + banks_enumerated[value] = banks_enumerated[value] + 1 + for bank_enumeration in banks_enumerated.values(): + lcm_list = range(1, bank_enumeration+1) + lcm_comp = lcm_list[0] + for i in lcm_list[1:]: + lcm_comp = lcm_comp * i / calculate_gcd(lcm_comp, i) + lcm_array.append(lcm_comp) + + LCM = sum(lcm_array) + return int(LCM) + +def calculate_gcd(x, y): + while y != 0: + (x, y) = (y, x % y) + return int(x) + +def formulate_fine_grained_ecmp(version, dpg_ecmp_content, port_device_map, port_alias_map): + family = "" + tag = "" + neigh_key = [] + if version == "ipv4": + family = "IPV4" + tag = "fgnhg_v4" + elif version == "ipv6": + family = "IPV6" + tag = "fgnhg_v6" + + port_nhip_map = dpg_ecmp_content['port_nhip_map'] + nhgaddr = dpg_ecmp_content['nhgaddr'] + nhg_int = dpg_ecmp_content['nhg_int'] + + nhip_device_map = {port_nhip_map[x]: port_device_map[x] for x in port_device_map + if x in port_nhip_map} + nhip_devices = sorted(list(set(nhip_device_map.values()))) + nhdevices_ip_bank_map = {device: bank for bank, device in enumerate(nhip_devices)} + nhip_bank_map = {ip: nhdevices_ip_bank_map[device] for ip, device in nhip_device_map.items()} + LCM = calculate_lcm_for_ecmp(nhdevices_ip_bank_map, nhip_bank_map) + + FG_NHG_MEMBER = {ip: {"FG_NHG": tag, "bank": bank} for ip, bank in nhip_bank_map.items()} + nhip_port_map = dict(zip(port_nhip_map.values(), port_nhip_map.keys())) + + + + for nhip, memberinfo in FG_NHG_MEMBER.items(): + if nhip in nhip_port_map: + memberinfo["link"] = port_alias_map[nhip_port_map[nhip]] + FG_NHG_MEMBER[nhip] = memberinfo + + FG_NHG_PREFIX = {nhgaddr: {"FG_NHG": tag}} + FG_NHG = {tag: {"bucket_size": LCM}} + for ip in nhip_bank_map: + neigh_key.append(str(nhg_int + "|" + ip)) + NEIGH = {neigh_key: {"family": family} for neigh_key in neigh_key} + + fine_grained_content = {"FG_NHG_MEMBER": FG_NHG_MEMBER, "FG_NHG": FG_NHG, "FG_NHG_PREFIX": FG_NHG_PREFIX, "NEIGH": NEIGH} + return fine_grained_content + +def parse_png(png, hname, dpg_ecmp_content = None): neighbors = {} devices = {} console_dev = '' @@ -84,6 +184,15 @@ def parse_png(png, hname): mgmt_port = '' port_speeds = {} console_ports = {} + mux_cable_ports = {} + is_storage_device = False + port_device_map = {} + png_ecmp_content = {} + FG_NHG_MEMBER = {} + FG_NHG_PREFIX = {} + FG_NHG = {} + NEIGH = {} + for child in png: if child.tag == str(QName(ns, "DeviceInterfaceLinks")): for link in child.findall(str(QName(ns, "DeviceLinkBase"))): @@ -109,6 +218,11 @@ def parse_png(png, hname): } continue + if linktype == "DeviceInterfaceLink": + endport = link.find(str(QName(ns, "EndPort"))).text + startdevice = link.find(str(QName(ns, "StartDevice"))).text + port_device_map[endport] = startdevice + if linktype != "DeviceInterfaceLink" and linktype != "UnderlayInterfaceLink": continue @@ -118,15 +232,14 @@ def parse_png(png, hname): startport = link.find(str(QName(ns, "StartPort"))).text bandwidth_node = link.find(str(QName(ns, "Bandwidth"))) bandwidth = bandwidth_node.text if bandwidth_node is not None else None - if enddevice.lower() == hname.lower(): - if port_alias_map.has_key(endport): + if endport in port_alias_map: endport = port_alias_map[endport] neighbors[endport] = {'name': startdevice, 'port': startport} if bandwidth: port_speeds[endport] = bandwidth - else: - if port_alias_map.has_key(startport): + elif startdevice.lower() == hname.lower(): + if startport in port_alias_map: startport = port_alias_map[startport] neighbors[startport] = {'name': enddevice, 'port': endport} if bandwidth: @@ -134,12 +247,20 @@ def parse_png(png, hname): if child.tag == str(QName(ns, "Devices")): for device in child.findall(str(QName(ns, "Device"))): - (lo_prefix, mgmt_prefix, name, hwsku, d_type, deployment_id) = parse_device(device) + (lo_prefix, lo_prefix_v6, mgmt_prefix, name, hwsku, d_type, deployment_id, cluster) = parse_device(device) device_data = {'lo_addr': lo_prefix, 'type': d_type, 'mgmt_addr': mgmt_prefix, 'hwsku': hwsku } + if cluster: + device_data['cluster'] = cluster if deployment_id: device_data['deployment_id'] = deployment_id + if lo_prefix_v6: + device_data['lo_addr_v6'] = lo_prefix_v6 devices[name] = device_data + if name == hname: + if cluster and "str" in cluster.lower(): + is_storage_device = True + if child.tag == str(QName(ns, "DeviceInterfaceLinks")): for if_link in child.findall(str(QName(ns, 'DeviceLinkBase'))): if str(QName(ns3, "type")) in if_link.attrib: @@ -157,11 +278,152 @@ def parse_png(png, hname): elif node.tag == str(QName(ns, "EndDevice")): mgmt_dev = node.text - return (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speeds, console_ports) + if child.tag == str(QName(ns, "DeviceInterfaceLinks")): + for link in child.findall(str(QName(ns, 'DeviceLinkBase'))): + if link.find(str(QName(ns, "ElementType"))).text == "LogicalLink": + intf_name = link.find(str(QName(ns, "EndPort"))).text + if intf_name in port_alias_map: + intf_name = port_alias_map[intf_name] + + mux_cable_ports[intf_name] = "true" + + if (len(dpg_ecmp_content)): + for version, content in dpg_ecmp_content.items(): # version is ipv4 or ipv6 + fine_grained_content = formulate_fine_grained_ecmp(version, content, port_device_map, port_alias_map) # port_alias_map + FG_NHG_MEMBER.update(fine_grained_content['FG_NHG_MEMBER']) + FG_NHG_PREFIX.update(fine_grained_content['FG_NHG_PREFIX']) + FG_NHG.update(fine_grained_content['FG_NHG']) + NEIGH.update(fine_grained_content['NEIGH']) + + png_ecmp_content = {"FG_NHG_PREFIX": FG_NHG_PREFIX, "FG_NHG_MEMBER": FG_NHG_MEMBER, "FG_NHG": FG_NHG, + "NEIGH": NEIGH} + + return (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speeds, console_ports, mux_cable_ports, is_storage_device, png_ecmp_content) + + +def parse_asic_external_link(link, asic_name, hostname): + neighbors = {} + port_speeds = {} + enddevice = link.find(str(QName(ns, "EndDevice"))).text + endport = link.find(str(QName(ns, "EndPort"))).text + startdevice = link.find(str(QName(ns, "StartDevice"))).text + startport = link.find(str(QName(ns, "StartPort"))).text + bandwidth_node = link.find(str(QName(ns, "Bandwidth"))) + bandwidth = bandwidth_node.text if bandwidth_node is not None else None + # if chassis internal is false, the interface name will be + # interface alias which should be converted to asic port name + if (enddevice.lower() == hostname.lower()): + if ((endport in port_alias_asic_map) and + (asic_name.lower() in port_alias_asic_map[endport].lower())): + endport = port_alias_asic_map[endport] + neighbors[port_alias_map[endport]] = {'name': startdevice, 'port': startport} + if bandwidth: + port_speeds[port_alias_map[endport]] = bandwidth + elif (startdevice.lower() == hostname.lower()): + if ((startport in port_alias_asic_map) and + (asic_name.lower() in port_alias_asic_map[startport].lower())): + startport = port_alias_asic_map[startport] + neighbors[port_alias_map[startport]] = {'name': enddevice, 'port': endport} + if bandwidth: + port_speeds[port_alias_map[startport]] = bandwidth + + return neighbors, port_speeds + +def parse_asic_internal_link(link, asic_name, hostname): + neighbors = {} + port_speeds = {} + enddevice = link.find(str(QName(ns, "EndDevice"))).text + endport = link.find(str(QName(ns, "EndPort"))).text + startdevice = link.find(str(QName(ns, "StartDevice"))).text + startport = link.find(str(QName(ns, "StartPort"))).text + bandwidth_node = link.find(str(QName(ns, "Bandwidth"))) + bandwidth = bandwidth_node.text if bandwidth_node is not None else None + if ((enddevice.lower() == asic_name.lower()) and + (startdevice.lower() != hostname.lower())): + if endport in port_alias_map: + endport = port_alias_map[endport] + neighbors[endport] = {'name': startdevice, 'port': startport} + if bandwidth: + port_speeds[endport] = bandwidth + elif ((startdevice.lower() == asic_name.lower()) and + (enddevice.lower() != hostname.lower())): + if startport in port_alias_map: + startport = port_alias_map[startport] + neighbors[startport] = {'name': enddevice, 'port': endport} + if bandwidth: + port_speeds[startport] = bandwidth + + return neighbors, port_speeds + +def parse_asic_png(png, asic_name, hostname): + neighbors = {} + devices = {} + port_speeds = {} + for child in png: + if child.tag == str(QName(ns, "DeviceInterfaceLinks")): + for link in child.findall(str(QName(ns, "DeviceLinkBase"))): + # Chassis internal node is used in multi-asic device or chassis minigraph + # where the minigraph will contain the internal asic connectivity and + # external neighbor information. The ChassisInternal node will be used to + # determine if the link is internal to the device or chassis. + chassis_internal_node = link.find(str(QName(ns, "ChassisInternal"))) + chassis_internal = chassis_internal_node.text if chassis_internal_node is not None else "false" + + # If the link is an external link include the external neighbor + # information in ASIC ports table + if chassis_internal.lower() == "false": + ext_neighbors, ext_port_speeds = parse_asic_external_link(link, asic_name, hostname) + neighbors.update(ext_neighbors) + port_speeds.update(ext_port_speeds) + else: + int_neighbors, int_port_speeds = parse_asic_internal_link(link, asic_name, hostname) + neighbors.update(int_neighbors) + port_speeds.update(int_port_speeds) + + if child.tag == str(QName(ns, "Devices")): + for device in child.findall(str(QName(ns, "Device"))): + (lo_prefix, lo_prefix_v6, mgmt_prefix, name, hwsku, d_type, deployment_id, cluster) = parse_device(device) + device_data = {'lo_addr': lo_prefix, 'type': d_type, 'mgmt_addr': mgmt_prefix, 'hwsku': hwsku } + if cluster: + device_data['cluster'] = cluster + if deployment_id: + device_data['deployment_id'] = deployment_id + if lo_prefix_v6: + device_data['lo_addr_v6']= lo_prefix_v6 + devices[name] = device_data + + + return (neighbors, devices, port_speeds) + +def parse_loopback_intf(child): + lointfs = child.find(str(QName(ns, "LoopbackIPInterfaces"))) + lo_intfs = {} + for lointf in lointfs.findall(str(QName(ns1, "LoopbackIPInterface"))): + intfname = lointf.find(str(QName(ns, "AttachTo"))).text + ipprefix = lointf.find(str(QName(ns1, "PrefixStr"))).text + lo_intfs[(intfname, ipprefix)] = {} + return lo_intfs def parse_dpg(dpg, hname): + aclintfs = None + mgmtintfs = None + tunnelintfs = defaultdict(dict) for child in dpg: + """ + In Multi-NPU platforms the acl intfs are defined only for the host not for individual asic. + There is just one aclintf node in the minigraph + Get the aclintfs node first. + """ + if aclintfs is None and child.find(str(QName(ns, "AclInterfaces"))) is not None: + aclintfs = child.find(str(QName(ns, "AclInterfaces"))) + """ + In Multi-NPU platforms the mgmt intfs are defined only for the host not for individual asic + There is just one mgmtintf node in the minigraph + Get the mgmtintfs node first. We need mgmt intf to get mgmt ip in per asic dockers. + """ + if mgmtintfs is None and child.find(str(QName(ns, "ManagementIPInterfaces"))) is not None: + mgmtintfs = child.find(str(QName(ns, "ManagementIPInterfaces"))) hostname = child.find(str(QName(ns, "Hostname"))) if hostname.text.lower() != hname.lower(): continue @@ -172,22 +434,18 @@ def parse_dpg(dpg, hname): if vni_element.text.isdigit(): vni = int(vni_element.text) else: - print >> sys.stderr, "VNI must be an integer (use default VNI %d instead)" % vni_default + print("VNI must be an integer (use default VNI %d instead)" % vni_default, file=sys.stderr) ipintfs = child.find(str(QName(ns, "IPInterfaces"))) intfs = {} + ip_intfs_map = {} for ipintf in ipintfs.findall(str(QName(ns, "IPInterface"))): intfalias = ipintf.find(str(QName(ns, "AttachTo"))).text intfname = port_alias_map.get(intfalias, intfalias) ipprefix = ipintf.find(str(QName(ns, "Prefix"))).text intfs[(intfname, ipprefix)] = {} - - lointfs = child.find(str(QName(ns, "LoopbackIPInterfaces"))) - lo_intfs = {} - for lointf in lointfs.findall(str(QName(ns1, "LoopbackIPInterface"))): - intfname = lointf.find(str(QName(ns, "AttachTo"))).text - ipprefix = lointf.find(str(QName(ns1, "PrefixStr"))).text - lo_intfs[(intfname, ipprefix)] = {} + ip_intfs_map[ipprefix] = intfalias + lo_intfs = parse_loopback_intf(child) mvrfConfigs = child.find(str(QName(ns, "MgmtVrfConfigs"))) mvrf = {} @@ -197,13 +455,12 @@ def parse_dpg(dpg, hname): mvrf_en_flag = mv.find(str(QName(ns, "mgmtVrfEnabled"))).text mvrf["vrf_global"] = {"mgmtVrfEnabled": mvrf_en_flag} - mgmtintfs = child.find(str(QName(ns, "ManagementIPInterfaces"))) mgmt_intf = {} for mgmtintf in mgmtintfs.findall(str(QName(ns1, "ManagementIPInterface"))): intfname = mgmtintf.find(str(QName(ns, "AttachTo"))).text ipprefix = mgmtintf.find(str(QName(ns1, "PrefixStr"))).text - mgmtipn = ipaddress.IPNetwork(ipprefix) - gwaddr = ipaddress.IPAddress(int(mgmtipn.network) + 1) + mgmtipn = ipaddress.ip_network(UNICODE_TYPE(ipprefix), False) + gwaddr = ipaddress.ip_address(next(mgmtipn.hosts())) mgmt_intf[(intfname, ipprefix)] = {'gwaddr': gwaddr} pcintfs = child.find(str(QName(ns, "PortChannelInterfaces"))) @@ -224,20 +481,66 @@ def parse_dpg(dpg, hname): pcs[pcintfname] = {'members': pcmbr_list, 'fallback': pcintf.find(str(QName(ns, "Fallback"))).text, 'min_links': str(int(math.ceil(len() * 0.75)))} else: pcs[pcintfname] = {'members': pcmbr_list, 'min_links': str(int(math.ceil(len(pcmbr_list) * 0.75)))} - + port_nhipv4_map = {} + port_nhipv6_map = {} + nhgaddr = ["", ""] + nhg_int = "" + nhportlist = [] + dpg_ecmp_content = {} + ipnhs = child.find(str(QName(ns, "IPNextHops"))) + if ipnhs is not None: + for ipnh in ipnhs.findall(str(QName(ns, "IPNextHop"))): + if ipnh.find(str(QName(ns, "Type"))).text == 'FineGrainedECMPGroupMember': + ipnhfmbr = ipnh.find(str(QName(ns, "AttachTo"))).text + ipnhaddr = ipnh.find(str(QName(ns, "Address"))).text + nhportlist.append(ipnhfmbr) + if "." in ipnhaddr: + port_nhipv4_map[ipnhfmbr] = ipnhaddr + elif ":" in ipnhaddr: + port_nhipv6_map[ipnhfmbr] = ipnhaddr + + if port_nhipv4_map is not None and port_nhipv6_map is not None: + subnet_check_ip = list(port_nhipv4_map.values())[0] + for subnet_range in ip_intfs_map: + if ("." in subnet_range): + a = ipaddress.ip_address(UNICODE_TYPE(subnet_check_ip)) + n = list(ipaddress.ip_network(UNICODE_TYPE(subnet_range), False).hosts()) + if a in n: + nhg_int = ip_intfs_map[subnet_range] + dwnstrms = child.find(str(QName(ns, "DownstreamSummarySet"))) + for dwnstrm in dwnstrms.findall(str(QName(ns, "DownstreamSummary"))): + dwnstrmentry = str(ET.tostring(dwnstrm)) + if ("FineGrainedECMPGroupDestination" in dwnstrmentry): + subnet_ip = dwnstrm.find(str(QName(ns1, "Subnet"))).text + truncsubnet_ip = subnet_ip.split("/")[0] + if "." in (truncsubnet_ip): + nhgaddr[0] = subnet_ip + elif ":" in (truncsubnet_ip): + nhgaddr[1] = subnet_ip + ipv4_content = {"port_nhip_map": port_nhipv4_map, "nhgaddr": nhgaddr[0], "nhg_int": nhg_int} + ipv6_content = {"port_nhip_map": port_nhipv6_map, "nhgaddr": nhgaddr[1], "nhg_int": nhg_int} + dpg_ecmp_content['ipv4'] = ipv4_content + dpg_ecmp_content['ipv6'] = ipv6_content vlanintfs = child.find(str(QName(ns, "VlanInterfaces"))) vlan_intfs = [] vlans = {} vlan_members = {} + vlantype_name = "" for vintf in vlanintfs.findall(str(QName(ns, "VlanInterface"))): vintfname = vintf.find(str(QName(ns, "Name"))).text vlanid = vintf.find(str(QName(ns, "VlanID"))).text vintfmbr = vintf.find(str(QName(ns, "AttachTo"))).text + vlantype = vintf.find(str(QName(ns, "Type"))) + if vlantype != None: + vlantype_name = vintf.find(str(QName(ns, "Type"))).text vmbr_list = vintfmbr.split(';') for i, member in enumerate(vmbr_list): vmbr_list[i] = port_alias_map.get(member, member) sonic_vlan_member_name = "Vlan%s" % (vlanid) - vlan_members[(sonic_vlan_member_name, vmbr_list[i])] = {'tagging_mode': 'untagged'} + if vlantype_name == "Tagged": + vlan_members[(sonic_vlan_member_name, vmbr_list[i])] = {'tagging_mode': 'tagged'} + else: + vlan_members[(sonic_vlan_member_name, vmbr_list[i])] = {'tagging_mode': 'untagged'} vlan_attributes = {'vlanid': vlanid} @@ -249,15 +552,25 @@ def parse_dpg(dpg, hname): vdhcpserver_list = vintfdhcpservers.split(';') vlan_attributes['dhcp_servers'] = vdhcpserver_list + vlanmac = vintf.find(str(QName(ns, "MacAddress"))) + if vlanmac != None: + vlan_attributes['mac'] = vlanmac.text + sonic_vlan_name = "Vlan%s" % vlanid if sonic_vlan_name != vintfname: vlan_attributes['alias'] = vintfname vlans[sonic_vlan_name] = vlan_attributes - 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 @@ -268,20 +581,20 @@ def parse_dpg(dpg, hname): # decide an ACL is a Control Plane ACL if acl_intfs is empty below. for member in aclattach: member = member.strip() - if pcs.has_key(member): + if member in pcs: # If try to attach ACL to a LAG interface then we shall add the LAG to # to acl_intfs directly instead of break it into member ports, ACL attach # to LAG will be applied to all the LAG members internally by SAI/SDK acl_intfs.append(member) - elif vlans.has_key(member): - print >> sys.stderr, "Warning: ACL " + aclname + " is attached to a Vlan interface, which is currently not supported" - elif port_alias_map.has_key(member): + elif member in vlans: + acl_intfs.append(member) + elif member in port_alias_map: acl_intfs.append(port_alias_map[member]) # Give a warning if trying to attach ACL to a LAG member interface, correct way is to attach ACL to the LAG interface if port_alias_map[member] in intfs_inpc: - print >> sys.stderr, "Warning: ACL " + aclname + " is attached to a LAG member interface " + port_alias_map[member] + ", instead of LAG interface" - elif member.lower().startswith('erspan'): - if member.lower().startswith('erspanv6'): + print("Warning: ACL " + aclname + " is attached to a LAG member interface " + port_alias_map[member] + ", instead of LAG interface", file=sys.stderr) + elif member.lower().startswith('erspan') or member.lower().startswith('egress_erspan'): + if member.lower().startswith('erspanv6') or member.lower().startswith('egress_erspanv6'): is_mirror_v6 = True else: is_mirror = True @@ -292,18 +605,21 @@ def parse_dpg(dpg, hname): # later after the rest of the minigraph has been parsed. acl_intfs = pc_intfs[:] for panel_port in port_alias_map.values(): - if panel_port not in intfs_inpc: + # because of port_alias_asic_map we can have duplicate in port_alias_map + # so check if already present do not add + if panel_port not in intfs_inpc and panel_port not in acl_intfs: acl_intfs.append(panel_port) 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: @@ -313,24 +629,52 @@ def parse_dpg(dpg, hname): # append the service to our list of services if aclname in acls: if acls[aclname]['type'] != 'CTRLPLANE': - print >> sys.stderr, "Warning: ACL '%s' type mismatch. Not updating ACL." % aclname + print("Warning: ACL '%s' type mismatch. Not updating ACL." % aclname, file=sys.stderr) elif acls[aclname]['services'] == aclservice: - print >> sys.stderr, "Warning: ACL '%s' already contains service '%s'. Not updating ACL." % (aclname, aclservice) + print("Warning: ACL '%s' already contains service '%s'. Not updating ACL." % (aclname, aclservice), file=sys.stderr) else: acls[aclname]['services'].append(aclservice) 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 - - return intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni + print("Warning: Ignoring Control Plane ACL %s without type" % aclname, file=sys.stderr) + + + mg_tunnels = child.find(str(QName(ns, "TunnelInterfaces"))) + if mg_tunnels is not None: + table_key_to_mg_key_map = {"encap_ecn_mode": "EcnEncapsulationMode", + "ecn_mode": "EcnDecapsulationMode", + "dscp_mode": "DifferentiatedServicesCodePointMode", + "ttl_mode": "TtlMode"} + for mg_tunnel in mg_tunnels.findall(str(QName(ns, "TunnelInterface"))): + tunnel_type = mg_tunnel.attrib["Type"] + tunnel_name = mg_tunnel.attrib["Name"] + tunnelintfs[tunnel_type][tunnel_name] = { + "tunnel_type": mg_tunnel.attrib["Type"].upper(), + } + + for table_key, mg_key in table_key_to_mg_key_map.items(): + # If the minigraph has the key, add the corresponding config DB key to the table + if mg_key in mg_tunnel.attrib: + tunnelintfs[tunnel_type][tunnel_name][table_key] = mg_tunnel.attrib[mg_key] + + return intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni, tunnelintfs, dpg_ecmp_content return None, None, None, None, None, None, None, None, None, None +def parse_host_loopback(dpg, hname): + for child in dpg: + hostname = child.find(str(QName(ns, "Hostname"))) + if hostname.text.lower() != hname.lower(): + continue + lo_intfs = parse_loopback_intf(child) + return lo_intfs -def parse_cpg(cpg, hname): +def parse_cpg(cpg, hname, local_devices=[]): bgp_sessions = {} + bgp_internal_sessions = {} myasn = None bgp_peers_with_range = {} for child in cpg: @@ -351,24 +695,47 @@ def parse_cpg(cpg, hname): else: keepalive = 60 nhopself = 1 if session.find(str(QName(ns, "NextHopSelf"))) is not None else 0 + if end_router.lower() == hname.lower(): - bgp_sessions[start_peer.lower()] = { - 'name': start_router, - 'local_addr': end_peer.lower(), - 'rrclient': rrclient, - 'holdtime': holdtime, - 'keepalive': keepalive, - 'nhopself': nhopself - } - else: - bgp_sessions[end_peer.lower()] = { - 'name': end_router, - 'local_addr': start_peer.lower(), - 'rrclient': rrclient, - 'holdtime': holdtime, - 'keepalive': keepalive, - 'nhopself': nhopself - } + if end_router.lower() in local_devices and start_router.lower() in local_devices: + bgp_internal_sessions[start_peer.lower()] = { + 'name': start_router, + 'local_addr': end_peer.lower(), + 'rrclient': rrclient, + 'holdtime': holdtime, + 'keepalive': keepalive, + 'nhopself': nhopself, + 'admin_status': 'up' + } + else: + bgp_sessions[start_peer.lower()] = { + 'name': start_router, + 'local_addr': end_peer.lower(), + 'rrclient': rrclient, + 'holdtime': holdtime, + 'keepalive': keepalive, + 'nhopself': nhopself + } + elif start_router.lower() == hname.lower(): + if end_router.lower() in local_devices and start_router.lower() in local_devices: + bgp_internal_sessions[end_peer.lower()] = { + 'name': end_router, + 'local_addr': start_peer.lower(), + 'rrclient': rrclient, + 'holdtime': holdtime, + 'keepalive': keepalive, + 'nhopself': nhopself, + 'admin_status': 'up' + } + else: + bgp_sessions[end_peer.lower()] = { + 'name': end_router, + 'local_addr': start_peer.lower(), + 'rrclient': rrclient, + 'holdtime': holdtime, + 'keepalive': keepalive, + 'nhopself': nhopself + } elif child.tag == str(QName(ns, "Routers")): for router in child.findall(str(QName(ns1, "BGPRouterDeclaration"))): asn = router.find(str(QName(ns1, "ASN"))).text @@ -395,11 +762,16 @@ def parse_cpg(cpg, hname): bgp_session = bgp_sessions[peer] if hostname.lower() == bgp_session['name'].lower(): bgp_session['asn'] = asn + for peer in bgp_internal_sessions: + bgp_internal_session = bgp_internal_sessions[peer] + if hostname.lower() == bgp_internal_session['name'].lower(): + bgp_internal_session['asn'] = asn - bgp_monitors = { key: bgp_sessions[key] for key in bgp_sessions if bgp_sessions[key].has_key('asn') and bgp_sessions[key]['name'] == 'BGPMonitor' } - bgp_sessions = { key: bgp_sessions[key] for key in bgp_sessions if bgp_sessions[key].has_key('asn') and int(bgp_sessions[key]['asn']) != 0 } + bgp_monitors = { key: bgp_sessions[key] for key in bgp_sessions if 'asn' in bgp_sessions[key] and bgp_sessions[key]['name'] == 'BGPMonitor' } + bgp_sessions = { key: bgp_sessions[key] for key in bgp_sessions if 'asn' in bgp_sessions[key] and int(bgp_sessions[key]['asn']) != 0 } + bgp_internal_sessions = { key: bgp_internal_sessions[key] for key in bgp_internal_sessions if 'asn' in bgp_internal_sessions[key] and int(bgp_internal_sessions[key]['asn']) != 0 } - return bgp_sessions, myasn, bgp_peers_with_range, bgp_monitors + return bgp_sessions, bgp_internal_sessions, myasn, bgp_peers_with_range, bgp_monitors def parse_meta(meta, hname): @@ -410,6 +782,10 @@ def parse_meta(meta, hname): mgmt_routes = [] erspan_dst = [] deployment_id = None + region = None + cloudtype = None + resource_type = None + kube_data = {} device_metas = meta.find(str(QName(ns, "Devices"))) for device in device_metas.findall(str(QName(ns1, "DeviceMetadata"))): if device.find(str(QName(ns1, "Name"))).text.lower() == hname.lower(): @@ -432,7 +808,78 @@ def parse_meta(meta, hname): erspan_dst = value_group elif name == "DeploymentId": deployment_id = value - return syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id + elif name == "Region": + region = value + elif name == "CloudType": + cloudtype = value + elif name == "ResourceType": + resource_type = value + elif name == "KubernetesEnabled": + kube_data["enable"] = value + elif name == "KubernetesServerIp": + kube_data["ip"] = value + return syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region, cloudtype, resource_type, kube_data + + +def parse_linkmeta(meta, hname): + link = meta.find(str(QName(ns, "Link"))) + linkmetas = {} + for linkmeta in link.findall(str(QName(ns1, "LinkMetadata"))): + port = None + fec_disabled = None + + # Sample: ARISTA05T1:Ethernet1/33;switch-t0:fortyGigE0/4 + key = linkmeta.find(str(QName(ns1, "Key"))).text + endpoints = key.split(';') + for endpoint in endpoints: + t = endpoint.split(':') + if len(t) == 2 and t[0].lower() == hname.lower(): + port = t[1] + break + else: + # Cannot find a matching hname, something went wrong + continue + + has_peer_switch = False + upper_tor_hostname = '' + lower_tor_hostname = '' + + properties = linkmeta.find(str(QName(ns1, "Properties"))) + for device_property in properties.findall(str(QName(ns1, "DeviceProperty"))): + name = device_property.find(str(QName(ns1, "Name"))).text + value = device_property.find(str(QName(ns1, "Value"))).text + if name == "FECDisabled": + fec_disabled = value + elif name == "GeminiPeeringLink": + has_peer_switch = True + elif name == "UpperTOR": + upper_tor_hostname = value + elif name == "LowerTOR": + lower_tor_hostname = value + + linkmetas[port] = {} + if fec_disabled: + linkmetas[port]["FECDisabled"] = fec_disabled + if has_peer_switch: + if upper_tor_hostname == hname: + linkmetas[port]["PeerSwitch"] = lower_tor_hostname + else: + linkmetas[port]["PeerSwitch"] = upper_tor_hostname + return linkmetas + + +def parse_asic_meta(meta, hname): + sub_role = None + device_metas = meta.find(str(QName(ns, "Devices"))) + for device in device_metas.findall(str(QName(ns1, "DeviceMetadata"))): + if device.find(str(QName(ns1, "Name"))).text.lower() == hname.lower(): + properties = device.find(str(QName(ns1, "Properties"))) + for device_property in properties.findall(str(QName(ns1, "DeviceProperty"))): + name = device_property.find(str(QName(ns1, "Name"))).text + value = device_property.find(str(QName(ns1, "Value"))).text + if name == "SubRole": + sub_role = value + return sub_role def parse_deviceinfo(meta, hwsku): port_speeds = {} @@ -465,11 +912,10 @@ def parse_spine_chassis_fe(results, vni, lo_intfs, phyport_intfs, pc_intfs, pc_m # Vxlan tunnel information lo_addr = '0.0.0.0' for lo in lo_intfs: - lo_network = ipaddress.IPNetwork(lo[1]) + lo_network = ipaddress.ip_network(UNICODE_TYPE(lo[1]), False) if lo_network.version == 4: - lo_addr = str(lo_network.ip) - break - + lo_addr = str(lo_network.network_address) + break results['VXLAN_TUNNEL'] = {chassis_vxlan_tunnel: { 'src_ip': lo_addr }} @@ -508,10 +954,10 @@ def parse_spine_chassis_fe(results, vni, lo_intfs, phyport_intfs, pc_intfs, pc_m for pc_member in pc_members: if pc_member[0] == pc_intf: intf_name = pc_member[1] - break + break - if intf_name == None: - print >> sys.stderr, 'Warning: cannot find any interfaces that belong to %s' % (pc_intf) + if intf_name is None: + print('Warning: cannot find any interfaces that belong to %s' % (pc_intf), file=sys.stderr) continue # Get the neighbor router of this port channel interface @@ -528,37 +974,96 @@ def parse_spine_chassis_fe(results, vni, lo_intfs, phyport_intfs, pc_intfs, pc_m # ############################################################################### -def filter_acl_mirror_table_bindings(acls, neighbors, port_channels): - """ - Filters out inactive front-panel ports from the binding list for mirror - ACL tables. We define an "active" port as one that is a member of a - port channel or one that is connected to a neighboring device. - """ - - for acl_table, group_params in acls.iteritems(): +def filter_acl_table_bindings(acls, neighbors, port_channels, sub_role): + filter_acls = {} + + # If the asic role is BackEnd no ACL Table (Ctrl/Data/Everflow) is binded. + # This will be applicable in Multi-NPU Platforms. + + if sub_role == BACKEND_ASIC_SUB_ROLE: + return filter_acls + + front_port_channel_intf = [] + + # List of Backplane ports + backplane_port_list = [v for k,v in port_alias_map.items() if v.startswith(backplane_prefix())] + + # Get the front panel port channel. + for port_channel_intf in port_channels: + backend_port_channel = any(lag_member in backplane_port_list \ + for lag_member in port_channels[port_channel_intf]['members']) + if not backend_port_channel: + front_port_channel_intf.append(port_channel_intf) + + for acl_table, group_params in acls.items(): group_type = group_params.get('type', None) + filter_acls[acl_table] = acls[acl_table] + # For Control Plane and Data ACL no filtering is needed + # Control Plane ACL has no Interface associated and + # Data Plane ACL Interface are attached via minigraph + # AclInterface. if group_type != 'MIRROR' and group_type != 'MIRRORV6': continue - active_ports = [ port for port in group_params.get('ports', []) if port in neighbors.keys() or port in port_channels ] - + # Filters out back-panel ports from the binding list for Everflow (Mirror) + # ACL tables. We define an "back-panel" port as one that is a member of a + # port channel connected to back asic or directly connected to back asic. + # This will be applicable in Multi-NPU Platforms. + front_panel_ports = [] + for port in group_params.get('ports', []): + # Filter out backplane ports + if port in backplane_port_list: + continue + # Filter out backplane port channels + if port in port_channels and port not in front_port_channel_intf: + continue + front_panel_ports.append(port) + + # Filters out inactive front-panel ports from the binding list for mirror + # ACL tables. We define an "active" port as one that is a member of a + # front pannel port channel or one that is connected to a neighboring device via front panel port. + active_ports = [port for port in front_panel_ports if port in neighbors.keys() or port in front_port_channel_intf] + if not active_ports: - print >> sys.stderr, 'Warning: mirror table {} in ACL_TABLE does not have any ports bound to it'.format(acl_table) + print('Warning: mirror table {} in ACL_TABLE does not have any ports bound to it'.format(acl_table), file=sys.stderr) - acls[acl_table]['ports'] = active_ports + filter_acls[acl_table]['ports'] = active_ports - return acls + return filter_acls + +def enable_internal_bgp_session(bgp_sessions, filename, asic_name): + ''' + In Multi-NPU session the internal sessions will always be up. + So adding the admin-status 'up' configuration to bgp sessions + BGP session between FrontEnd and BackEnd Asics are internal bgp sessions + ''' + local_sub_role = parse_asic_sub_role(filename, asic_name) + + for peer_ip in bgp_sessions.keys(): + peer_name = bgp_sessions[peer_ip]['name'] + peer_sub_role = parse_asic_sub_role(filename, peer_name) + if ((local_sub_role == FRONTEND_ASIC_SUB_ROLE and peer_sub_role == BACKEND_ASIC_SUB_ROLE) or + (local_sub_role == BACKEND_ASIC_SUB_ROLE and peer_sub_role == FRONTEND_ASIC_SUB_ROLE)): + bgp_sessions[peer_ip].update({'admin_status': 'up'}) ############################################################################### # # Main functions # ############################################################################### +def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hwsku_config_file=None): + """ Parse minigraph xml file. + + Keyword arguments: + filename -- minigraph file name + platform -- device platform + port_config_file -- port config file name + asic_name -- asic name; to parse multi-asic device minigraph to + generate asic specific configuration. + """ -def parse_xml(filename, platform=None, port_config_file=None): root = ET.parse(filename).getroot() - mini_graph_path = filename u_neighbors = None u_devices = None @@ -567,8 +1072,11 @@ def parse_xml(filename, platform=None, port_config_file=None): bgp_monitors = [] bgp_asn = None intfs = None + dpg_ecmp_content = {} + png_ecmp_content = {} vlan_intfs = None pc_intfs = None + tunnel_intfs = None vlans = None vlan_members = None pcs = None @@ -576,12 +1084,14 @@ def parse_xml(filename, platform=None, port_config_file=None): lo_intfs = None neighbors = None devices = None - hostname = None + sub_role = None + resource_type = None docker_routing_config_mode = "separated" port_speeds_default = {} port_speed_png = {} port_descriptions = {} console_ports = {} + mux_cable_ports = {} syslog_servers = [] dhcp_servers = [] ntp_servers = [] @@ -590,6 +1100,20 @@ def parse_xml(filename, platform=None, port_config_file=None): erspan_dst = [] bgp_peers_with_range = None deployment_id = None + region = None + cloudtype = None + hostname = None + linkmetas = {} + host_lo_intfs = None + is_storage_device = False + local_devices = [] + kube_data = {} + + # hostname is the asic_name, get the asic_id from the asic_name + if asic_name is not None: + asic_id = get_asic_id_from_name(asic_name) + else: + asic_id = None hwsku_qn = QName(ns, "HwSku") hostname_qn = QName(ns, "Hostname") @@ -602,51 +1126,113 @@ def parse_xml(filename, platform=None, port_config_file=None): if child.tag == str(docker_routing_config_mode_qn): docker_routing_config_mode = child.text - (ports, alias_map) = get_port_config(hwsku, platform, port_config_file) + (ports, alias_map, alias_asic_map) = get_port_config(hwsku=hwsku, platform=platform, port_config_file=port_config_file, asic=asic_id, hwsku_config_file=hwsku_config_file) port_alias_map.update(alias_map) + port_alias_asic_map.update(alias_asic_map) + + # Get the local device node from DeviceMetadata + local_devices = parse_asic_meta_get_devices(root) + for child in root: - if child.tag == str(QName(ns, "DpgDec")): - (intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni) = parse_dpg(child, hostname) - elif child.tag == str(QName(ns, "CpgDec")): - (bgp_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, hostname) - elif child.tag == str(QName(ns, "PngDec")): - (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speed_png, console_ports) = parse_png(child, hostname) - elif child.tag == str(QName(ns, "UngDec")): - (u_neighbors, u_devices, _, _, _, _, _, _) = parse_png(child, hostname) - elif child.tag == str(QName(ns, "MetadataDeclaration")): - (syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id) = parse_meta(child, hostname) - elif child.tag == str(QName(ns, "DeviceInfos")): - (port_speeds_default, port_descriptions) = parse_deviceinfo(child, hwsku) - - current_device = [devices[key] for key in devices if key.lower() == hostname.lower()][0] + if asic_name is None: + if child.tag == str(QName(ns, "DpgDec")): + (intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni, tunnel_intfs, dpg_ecmp_content) = parse_dpg(child, hostname) + elif child.tag == str(QName(ns, "CpgDec")): + (bgp_sessions, bgp_internal_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, hostname) + elif child.tag == str(QName(ns, "PngDec")): + (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speed_png, console_ports, mux_cable_ports, is_storage_device, png_ecmp_content) = parse_png(child, hostname, dpg_ecmp_content) + elif child.tag == str(QName(ns, "UngDec")): + (u_neighbors, u_devices, _, _, _, _, _, _) = parse_png(child, hostname, None) + elif child.tag == str(QName(ns, "MetadataDeclaration")): + (syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region, cloudtype, resource_type, kube_data) = parse_meta(child, hostname) + elif child.tag == str(QName(ns, "LinkMetadataDeclaration")): + linkmetas = parse_linkmeta(child, hostname) + elif child.tag == str(QName(ns, "DeviceInfos")): + (port_speeds_default, port_descriptions) = parse_deviceinfo(child, hwsku) + else: + if child.tag == str(QName(ns, "DpgDec")): + (intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni, tunnel_intfs, dpg_ecmp_content) = parse_dpg(child, asic_name) + host_lo_intfs = parse_host_loopback(child, hostname) + elif child.tag == str(QName(ns, "CpgDec")): + (bgp_sessions, bgp_internal_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, asic_name, local_devices) + elif child.tag == str(QName(ns, "PngDec")): + (neighbors, devices, port_speed_png) = parse_asic_png(child, asic_name, hostname) + elif child.tag == str(QName(ns, "MetadataDeclaration")): + (sub_role) = parse_asic_meta(child, asic_name) + elif child.tag == str(QName(ns, "LinkMetadataDeclaration")): + linkmetas = parse_linkmeta(child, hostname) + elif child.tag == str(QName(ns, "DeviceInfos")): + (port_speeds_default, port_descriptions) = parse_deviceinfo(child, hwsku) + + # set the host device type in asic metadata also + device_type = [devices[key]['type'] for key in devices if key.lower() == hostname.lower()][0] + if asic_name is None: + current_device = [devices[key] for key in devices if key.lower() == hostname.lower()][0] + else: + current_device = [devices[key] for key in devices if key.lower() == asic_name.lower()][0] + results = {} results['DEVICE_METADATA'] = {'localhost': { 'bgp_asn': bgp_asn, 'deployment_id': deployment_id, + 'region': region, + 'cloudtype': cloudtype, 'docker_routing_config_mode': docker_routing_config_mode, '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' + 'type': device_type, + 'synchronous_mode': 'enable' } } + + cluster = [devices[key] for key in devices if key.lower() == hostname.lower()][0].get('cluster', "") + if cluster: + results['DEVICE_METADATA']['localhost']['cluster'] = cluster + + if kube_data: + results['KUBERNETES_MASTER'] = { + 'SERVER': { + 'disable': str(kube_data.get('enable', '0') == '0'), + 'ip': kube_data.get('ip', '') + } + } + + results['PEER_SWITCH'] = get_peer_switch_info(linkmetas, devices) + + if bool(results['PEER_SWITCH']): + results['DEVICE_METADATA']['localhost']['subtype'] = 'DualToR' + if len(results['PEER_SWITCH'].keys()) > 1: + print("Warning: more than one peer switch was found. Only the first will be parsed: {}".format(results['PEER_SWITCH'].keys()[0])) + + results['DEVICE_METADATA']['localhost']['peer_switch'] = list(results['PEER_SWITCH'].keys())[0] + + if is_storage_device: + results['DEVICE_METADATA']['localhost']['storage_device'] = "true" + + # for this hostname, if sub_role is defined, add sub_role in + # device_metadata + if sub_role is not None: + current_device['sub_role'] = sub_role + results['DEVICE_METADATA']['localhost']['sub_role'] = sub_role + results['DEVICE_METADATA']['localhost']['asic_name'] = asic_name + + if resource_type is not None: + results['DEVICE_METADATA']['localhost']['resource_type'] = resource_type + results['BGP_NEIGHBOR'] = bgp_sessions results['BGP_MONITORS'] = bgp_monitors results['BGP_PEER_RANGE'] = bgp_peers_with_range + results['BGP_INTERNAL_NEIGHBOR'] = bgp_internal_sessions if mgmt_routes: # TODO: differentiate v4 and v6 - mgmt_intf.itervalues().next()['forced_mgmt_routes'] = mgmt_routes + next(iter(mgmt_intf.values()))['forced_mgmt_routes'] = mgmt_routes results['MGMT_PORT'] = {} results['MGMT_INTERFACE'] = {} mgmt_intf_count = 0 mgmt_alias_reverse_mapping = {} for key in mgmt_intf: alias = key[0] - if mgmt_alias_reverse_mapping.has_key(alias): + if alias in mgmt_alias_reverse_mapping: name = mgmt_alias_reverse_mapping[alias] else: name = 'eth' + str(mgmt_intf_count) @@ -660,21 +1246,41 @@ def parse_xml(filename, platform=None, port_config_file=None): for lo_intf in lo_intfs: results['LOOPBACK_INTERFACE'][lo_intf] = lo_intfs[lo_intf] results['LOOPBACK_INTERFACE'][lo_intf[0]] = {} + + if host_lo_intfs is not None: + for host_lo_intf in host_lo_intfs: + results['LOOPBACK_INTERFACE'][host_lo_intf] = host_lo_intfs[host_lo_intf] + results['LOOPBACK_INTERFACE'][host_lo_intf[0]] = {} + results['MGMT_VRF_CONFIG'] = mvrf phyport_intfs = {} vlan_intfs = {} pc_intfs = {} - vlan_invert_mapping = { v['alias']:k for k,v in vlans.items() if v.has_key('alias') } + vlan_invert_mapping = { v['alias']:k for k,v in vlans.items() if 'alias' in v } vlan_sub_intfs = {} for intf in intfs: if intf[0][0:4] == 'Vlan': vlan_intfs[intf] = {} - vlan_intfs[intf[0]] = {} - elif vlan_invert_mapping.has_key(intf[0]): + + if bool(results['PEER_SWITCH']): + vlan_intfs[intf[0]] = { + 'proxy_arp': 'enabled', + 'grat_arp': 'enabled' + } + else: + vlan_intfs[intf[0]] = {} + elif intf[0] in vlan_invert_mapping: vlan_intfs[(vlan_invert_mapping[intf[0]], intf[1])] = {} - vlan_intfs[vlan_invert_mapping[intf[0]]] = {} + + if bool(results['PEER_SWITCH']): + vlan_intfs[vlan_invert_mapping[intf[0]]] = { + 'proxy_arp': 'enabled', + 'grat_arp': 'enabled' + } + else: + vlan_intfs[vlan_invert_mapping[intf[0]]] = {} elif intf[0][0:11] == 'PortChannel': pc_intfs[intf] = {} pc_intfs[intf[0]] = {} @@ -687,34 +1293,45 @@ def parse_xml(filename, platform=None, port_config_file=None): for port_name in port_speeds_default: # ignore port not in port_config.ini - if not ports.has_key(port_name): + if port_name not in ports: continue ports.setdefault(port_name, {})['speed'] = port_speeds_default[port_name] for port_name in port_speed_png: # not consider port not in port_config.ini - if port_name not in ports: - print >> sys.stderr, "Warning: ignore interface '%s' as it is not in the port_config.ini" % port_name - continue + # If no port_config_file is found ports is empty so ignore this error + if port_config_file is not None: + if port_name not in ports: + print("Warning: ignore interface '%s' as it is not in the port_config.ini" % port_name, file=sys.stderr) + continue ports.setdefault(port_name, {})['speed'] = port_speed_png[port_name] - for port_name, port in ports.items(): - if port.get('speed') == '100000': + for port_name, port in list(ports.items()): + # get port alias from port_config.ini + alias = port.get('alias', port_name) + # generate default 100G FEC + # Note: FECDisabled only be effective on 100G port right now + if port.get('speed') == '100000' and linkmetas.get(alias, {}).get('FECDisabled', '').lower() != 'true': port['fec'] = 'rs' + # If connected to a smart cable, get the connection position + for port_name, port in ports.items(): + if port_name in mux_cable_ports: + port['mux_cable'] = mux_cable_ports[port_name] + # set port description if parsed from deviceinfo for port_name in port_descriptions: # ignore port not in port_config.ini - if not ports.has_key(port_name): + if port_name not in ports: continue ports.setdefault(port_name, {})['description'] = port_descriptions[port_name] for port_name, port in ports.items(): if not port.get('description'): - if neighbors.has_key(port_name): + if port_name in neighbors: # for the ports w/o description set it to neighbor name:port port['description'] = "%s:%s" % (neighbors[port_name]['name'], neighbors[port_name]['port']) else: @@ -722,11 +1339,11 @@ def parse_xml(filename, platform=None, port_config_file=None): port['description'] = port.get('alias', port_name) # set default port MTU as 9100 - for port in ports.itervalues(): + for port in ports.values(): port['mtu'] = '9100' # asymmetric PFC is disabled by default - for port in ports.itervalues(): + for port in ports.values(): port['pfc_asym'] = 'off' # set physical port default admin status up @@ -734,41 +1351,46 @@ def parse_xml(filename, platform=None, port_config_file=None): if port[0] in ports: ports.get(port[0])['admin_status'] = 'up' - for member in pc_members.keys() + vlan_members.keys(): + for member in list(pc_members.keys()) + list(vlan_members.keys()): port = ports.get(member[1]) if port: port['admin_status'] = 'up' + for port in neighbors.keys(): + if port in ports.keys(): + # make all neighbors connected ports to 'admin_up' + ports[port]['admin_status'] = 'up' + results['PORT'] = ports results['CONSOLE_PORT'] = console_ports if port_config_file: port_set = set(ports.keys()) - for (pc_name, mbr_map) in pcs.items(): + for (pc_name, mbr_map) in list(pcs.items()): # remove portchannels that contain ports not existing in port_config.ini # when port_config.ini exists if not set(mbr_map['members']).issubset(port_set): - print >> sys.stderr, "Warning: ignore '%s' as part of its member interfaces is not in the port_config.ini" % pc_name + print("Warning: ignore '%s' as part of its member interfaces is not in the port_config.ini" % pc_name, file=sys.stderr) del pcs[pc_name] # set default port channel MTU as 9100 and admin status up - for pc in pcs.itervalues(): + for pc in pcs.values(): pc['mtu'] = '9100' pc['admin_status'] = 'up' results['PORTCHANNEL'] = pcs results['PORTCHANNEL_MEMBER'] = pc_members - for pc_intf in pc_intfs.keys(): + for pc_intf in list(pc_intfs.keys()): # remove portchannels not in PORTCHANNEL dictionary if isinstance(pc_intf, tuple) and pc_intf[0] not in pcs: - print >> sys.stderr, "Warning: ignore '%s' interface '%s' as '%s' is not in the valid PortChannel list" % (pc_intf[0], pc_intf[1], pc_intf[0]) + print("Warning: ignore '%s' interface '%s' as '%s' is not in the valid PortChannel list" % (pc_intf[0], pc_intf[1], pc_intf[0]), file=sys.stderr) del pc_intfs[pc_intf] pc_intfs.pop(pc_intf[0], None) results['PORTCHANNEL_INTERFACE'] = pc_intfs - if current_device['type'] in backend_device_types: + if current_device['type'] in backend_device_types and is_storage_device: del results['INTERFACE'] del results['PORTCHANNEL_INTERFACE'] @@ -797,19 +1419,26 @@ def parse_xml(filename, platform=None, port_config_file=None): results['VLAN'] = vlans results['VLAN_MEMBER'] = vlan_members - for nghbr in neighbors.keys(): + results['TUNNEL'] = get_tunnel_entries(tunnel_intfs, lo_intfs, hostname) + + results['MUX_CABLE'] = get_mux_cable_entries(mux_cable_ports, neighbors, devices) + + for nghbr in list(neighbors.keys()): # remove port not in port_config.ini if nghbr not in ports: - print >> sys.stderr, "Warning: ignore interface '%s' in DEVICE_NEIGHBOR as it is not in the port_config.ini" % nghbr + if port_config_file is not None: + print("Warning: ignore interface '%s' in DEVICE_NEIGHBOR as it is not in the port_config.ini" % nghbr, file=sys.stderr) del neighbors[nghbr] - results['DEVICE_NEIGHBOR'] = neighbors - results['DEVICE_NEIGHBOR_METADATA'] = { key:devices[key] for key in devices if key.lower() != hostname.lower() } + if asic_name is None: + results['DEVICE_NEIGHBOR_METADATA'] = { key:devices[key] for key in devices if key.lower() != hostname.lower() } + else: + results['DEVICE_NEIGHBOR_METADATA'] = { key:devices[key] for key in devices if key in {device['name'] for device in neighbors.values()} } results['SYSLOG_SERVER'] = dict((item, {}) for item in syslog_servers) results['DHCP_SERVER'] = dict((item, {}) for item in dhcp_servers) results['NTP_SERVER'] = dict((item, {}) for item in ntp_servers) results['TACPLUS_SERVER'] = dict((item, {'priority': '1', 'tcp_port': '49'}) for item in tacacs_servers) - results['ACL_TABLE'] = filter_acl_mirror_table_bindings(acls, neighbors, pcs) + results['ACL_TABLE'] = filter_acl_table_bindings(acls, neighbors, pcs, sub_role) results['FEATURE'] = { 'telemetry': { 'status': 'enabled' @@ -820,17 +1449,41 @@ 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' + } + } + results['RESTAPI'] = { + 'config': { + 'client_auth': 'true', + 'allow_insecure': 'false', + 'log_level': 'trace' + }, + 'certs': { + 'server_crt': '/etc/sonic/credentials/restapiserver.crt', + 'server_key': '/etc/sonic/credentials/restapiserver.key', + 'ca_crt': '/etc/sonic/credentials/restapica.crt', + 'client_crt_cname': 'client.restapi.sonic' } } + if len(png_ecmp_content): + results['FG_NHG_MEMBER'] = png_ecmp_content['FG_NHG_MEMBER'] + results['FG_NHG_PREFIX'] = png_ecmp_content['FG_NHG_PREFIX'] + results['FG_NHG'] = png_ecmp_content['FG_NHG'] + results['NEIGH'] = png_ecmp_content['NEIGH'] + # Do not configure the minigraph's mirror session, which is currently unused # mirror_sessions = {} # if erspan_dst: # lo_addr = '0.0.0.0' # for lo in lo_intfs: - # lo_network = ipaddress.IPNetwork(lo[1]) + # lo_network = ipaddress.ip_network(UNICODE_TYPE(lo[1]), False) # if lo_network.version == 4: - # lo_addr = str(lo_network.ip) + # lo_addr = str(lo_network.network_address) # break # count = 0 # for dst in erspan_dst: @@ -842,12 +1495,59 @@ def parse_xml(filename, platform=None, port_config_file=None): if current_device['type'] == spine_chassis_frontend_role: parse_spine_chassis_fe(results, vni, lo_intfs, phyport_intfs, pc_intfs, pc_members, devices) + # Enable console management feature for console swtich + results['CONSOLE_SWITCH'] = { + 'console_mgmt' : { + 'enabled' : 'yes' if current_device['type'] in console_device_types else 'no' + } + } + return results +def get_tunnel_entries(tunnel_intfs, lo_intfs, hostname): + lo_addr = '' + # Use the first IPv4 loopback as the tunnel destination IP + for addr in lo_intfs.keys(): + ip_addr = ipaddress.ip_network(UNICODE_TYPE(addr[1])) + if isinstance(ip_addr, ipaddress.IPv4Network): + lo_addr = str(ip_addr.network_address) + break + + tunnels = {} + for type, tunnel_dict in tunnel_intfs.items(): + for tunnel_key, tunnel_attr in tunnel_dict.items(): + tunnel_attr['dst_ip'] = lo_addr + tunnels[tunnel_key] = tunnel_attr + return tunnels + +def get_mux_cable_entries(mux_cable_ports, neighbors, devices): + mux_cable_table = {} + + for intf in mux_cable_ports: + if intf in neighbors: + entry = {} + neighbor = neighbors[intf]['name'] + entry['state'] = 'auto' + + if devices[neighbor]['lo_addr'] is not None: + # Always force a /32 prefix for server IPv4 loopbacks + server_ipv4_lo_addr = devices[neighbor]['lo_addr'].split("/")[0] + server_ipv4_lo_prefix = ipaddress.ip_network(UNICODE_TYPE(server_ipv4_lo_addr)) + entry['server_ipv4'] = str(server_ipv4_lo_prefix) + + if 'lo_addr_v6' in devices[neighbor] and devices[neighbor]['lo_addr_v6'] is not None: + server_ipv6_lo_addr = devices[neighbor]['lo_addr_v6'].split('/')[0] + server_ipv6_lo_prefix = ipaddress.ip_network(UNICODE_TYPE(server_ipv6_lo_addr)) + entry['server_ipv6'] = str(server_ipv6_lo_prefix) + mux_cable_table[intf] = entry + else: + print("Warning: no server IPv4 loopback found for {}, skipping mux cable table entry".format(neighbor)) + + return mux_cable_table def parse_device_desc_xml(filename): root = ET.parse(filename).getroot() - (lo_prefix, mgmt_prefix, hostname, hwsku, d_type, _) = parse_device(root) + (lo_prefix, lo_prefix_v6, mgmt_prefix, hostname, hwsku, d_type, _, _) = parse_device(root) results = {} results['DEVICE_METADATA'] = {'localhost': { @@ -856,18 +1556,41 @@ def parse_device_desc_xml(filename): }} results['LOOPBACK_INTERFACE'] = {('lo', lo_prefix): {}} + if lo_prefix_v6: + results['LOOPBACK_INTERFACE'] = {('lo_v6', lo_prefix_v6): {}} mgmt_intf = {} - mgmtipn = ipaddress.IPNetwork(mgmt_prefix) - gwaddr = ipaddress.IPAddress(int(mgmtipn.network) + 1) + mgmtipn = ipaddress.ip_network(UNICODE_TYPE(mgmt_prefix), False) + gwaddr = ipaddress.ip_address((next(mgmtipn.hosts()))) results['MGMT_INTERFACE'] = {('eth0', mgmt_prefix): {'gwaddr': gwaddr}} return results +def parse_asic_sub_role(filename, asic_name): + if not os.path.isfile(filename): + return None + root = ET.parse(filename).getroot() + for child in root: + if child.tag == str(QName(ns, "MetadataDeclaration")): + sub_role = parse_asic_meta(child, asic_name) + return sub_role + +def parse_asic_meta_get_devices(root): + local_devices = [] + + for child in root: + if child.tag == str(QName(ns, "MetadataDeclaration")): + device_metas = child.find(str(QName(ns, "Devices"))) + for device in device_metas.findall(str(QName(ns1, "DeviceMetadata"))): + name = device.find(str(QName(ns1, "Name"))).text.lower() + local_devices.append(name) + + return local_devices port_alias_map = {} +port_alias_asic_map = {} def print_parse_xml(filename): results = parse_xml(filename) - print(json.dumps(results, indent=3, cls=minigraph_encoder)) + print((json.dumps(results, indent=3, cls=minigraph_encoder))) diff --git a/src/sonic-config-engine/openconfig_acl.py b/src/sonic-config-engine/openconfig_acl.py index cb29183652e7..c49f79c70175 100644 --- a/src/sonic-config-engine/openconfig_acl.py +++ b/src/sonic-config-engine/openconfig_acl.py @@ -18,7 +18,9 @@ from pyangbind.lib.base import PybindBase from decimal import Decimal from bitarray import bitarray -import __builtin__ + +import builtins + class yc_state_openconfig_acl__acl_state(PybindBase): """ This class was auto-generated by the PythonClass plugin for PYANG @@ -30,16 +32,12 @@ class yc_state_openconfig_acl__acl_state(PybindBase): """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__counter_capability',) - _yang_name = 'state' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'state' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False - self.__counter_capability = YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'oc-acl:AGGREGATE_ONLY': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:INTERFACE_AGGREGATE': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'AGGREGATE_ONLY': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'INTERFACE_AGGREGATE': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'INTERFACE_ONLY': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:INTERFACE_ONLY': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}},), is_leaf=True, yang_name="counter-capability", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=False) + self.__counter_capability = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'oc-acl:AGGREGATE_ONLY': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:INTERFACE_AGGREGATE': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'AGGREGATE_ONLY': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'INTERFACE_AGGREGATE': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'INTERFACE_ONLY': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:INTERFACE_ONLY': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}},), is_leaf=True, yang_name="counter-capability", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=False) load = kwargs.pop("load", None) if args: @@ -66,7 +64,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'state'] + return ['acl', 'state'] def _get_counter_capability(self): """ @@ -91,7 +89,7 @@ def _set_counter_capability(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'oc-acl:AGGREGATE_ONLY': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:INTERFACE_AGGREGATE': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'AGGREGATE_ONLY': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'INTERFACE_AGGREGATE': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'INTERFACE_ONLY': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:INTERFACE_ONLY': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}},), is_leaf=True, yang_name="counter-capability", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=False) + t = YANGDynClass(v,base=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'oc-acl:AGGREGATE_ONLY': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:INTERFACE_AGGREGATE': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'AGGREGATE_ONLY': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'INTERFACE_AGGREGATE': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'INTERFACE_ONLY': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:INTERFACE_ONLY': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}},), is_leaf=True, yang_name="counter-capability", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """counter_capability must be of a type compatible with identityref""", @@ -104,9 +102,9 @@ def _set_counter_capability(self, v, load=False): self._set() def _unset_counter_capability(self): - self.__counter_capability = YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'oc-acl:AGGREGATE_ONLY': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:INTERFACE_AGGREGATE': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'AGGREGATE_ONLY': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'INTERFACE_AGGREGATE': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'INTERFACE_ONLY': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:INTERFACE_ONLY': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}},), is_leaf=True, yang_name="counter-capability", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=False) + self.__counter_capability = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'oc-acl:AGGREGATE_ONLY': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:INTERFACE_AGGREGATE': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'AGGREGATE_ONLY': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'INTERFACE_AGGREGATE': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'INTERFACE_ONLY': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:INTERFACE_ONLY': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}},), is_leaf=True, yang_name="counter-capability", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=False) - counter_capability = __builtin__.property(_get_counter_capability) + counter_capability = builtins.property(_get_counter_capability) _pyangbind_elements = {'counter_capability': counter_capability, } @@ -123,17 +121,13 @@ class yc_config_openconfig_acl__acl_acl_sets_acl_set_config(PybindBase): """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__name','__description',) - _yang_name = 'config' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'config' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False - self.__name = YANGDynClass(base=unicode, is_leaf=True, yang_name="name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=True) - self.__description = YANGDynClass(base=unicode, is_leaf=True, yang_name="description", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=True) + self.__name = YANGDynClass(base=str, is_leaf=True, yang_name="name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=True) + self.__description = YANGDynClass(base=str, is_leaf=True, yang_name="description", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=True) load = kwargs.pop("load", None) if args: @@ -160,7 +154,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'acl-sets', u'acl-set', u'config'] + return ['acl', 'acl-sets', 'acl-set', 'config'] def _get_name(self): """ @@ -183,7 +177,7 @@ def _set_name(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=unicode, is_leaf=True, yang_name="name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=True) + t = YANGDynClass(v,base=str, is_leaf=True, yang_name="name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """name must be of a type compatible with string""", @@ -196,7 +190,7 @@ def _set_name(self, v, load=False): self._set() def _unset_name(self): - self.__name = YANGDynClass(base=unicode, is_leaf=True, yang_name="name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=True) + self.__name = YANGDynClass(base=str, is_leaf=True, yang_name="name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=True) def _get_description(self): @@ -220,7 +214,7 @@ def _set_description(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=unicode, is_leaf=True, yang_name="description", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=True) + t = YANGDynClass(v,base=str, is_leaf=True, yang_name="description", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """description must be of a type compatible with string""", @@ -233,10 +227,10 @@ def _set_description(self, v, load=False): self._set() def _unset_description(self): - self.__description = YANGDynClass(base=unicode, is_leaf=True, yang_name="description", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=True) + self.__description = YANGDynClass(base=str, is_leaf=True, yang_name="description", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=True) - name = __builtin__.property(_get_name, _set_name) - description = __builtin__.property(_get_description, _set_description) + name = builtins.property(_get_name, _set_name) + description = builtins.property(_get_description, _set_description) _pyangbind_elements = {'name': name, 'description': description, } @@ -253,17 +247,13 @@ class yc_state_openconfig_acl__acl_acl_sets_acl_set_state(PybindBase): """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__name','__description',) - _yang_name = 'state' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'state' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False - self.__name = YANGDynClass(base=unicode, is_leaf=True, yang_name="name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=False) - self.__description = YANGDynClass(base=unicode, is_leaf=True, yang_name="description", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=False) + self.__name = YANGDynClass(base=str, is_leaf=True, yang_name="name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=False) + self.__description = YANGDynClass(base=str, is_leaf=True, yang_name="description", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=False) load = kwargs.pop("load", None) if args: @@ -290,7 +280,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'acl-sets', u'acl-set', u'state'] + return ['acl', 'acl-sets', 'acl-set', 'state'] def _get_name(self): """ @@ -313,7 +303,7 @@ def _set_name(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=unicode, is_leaf=True, yang_name="name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=False) + t = YANGDynClass(v,base=str, is_leaf=True, yang_name="name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """name must be of a type compatible with string""", @@ -326,7 +316,7 @@ def _set_name(self, v, load=False): self._set() def _unset_name(self): - self.__name = YANGDynClass(base=unicode, is_leaf=True, yang_name="name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=False) + self.__name = YANGDynClass(base=str, is_leaf=True, yang_name="name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=False) def _get_description(self): @@ -350,7 +340,7 @@ def _set_description(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=unicode, is_leaf=True, yang_name="description", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=False) + t = YANGDynClass(v,base=str, is_leaf=True, yang_name="description", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """description must be of a type compatible with string""", @@ -363,10 +353,10 @@ def _set_description(self, v, load=False): self._set() def _unset_description(self): - self.__description = YANGDynClass(base=unicode, is_leaf=True, yang_name="description", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=False) + self.__description = YANGDynClass(base=str, is_leaf=True, yang_name="description", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=False) - name = __builtin__.property(_get_name) - description = __builtin__.property(_get_description) + name = builtins.property(_get_name) + description = builtins.property(_get_description) _pyangbind_elements = {'name': name, 'description': description, } @@ -383,17 +373,13 @@ class yc_config_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_confi """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__sequence_id','__description',) - _yang_name = 'config' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'config' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False - self.__sequence_id = YANGDynClass(base=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..4294967295']}, int_size=32), is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='uint32', is_config=True) - self.__description = YANGDynClass(base=unicode, is_leaf=True, yang_name="description", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=True) + self.__sequence_id = YANGDynClass(base=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..4294967295']}, int_size=32), is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='uint32', is_config=True) + self.__description = YANGDynClass(base=str, is_leaf=True, yang_name="description", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=True) load = kwargs.pop("load", None) if args: @@ -420,7 +406,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'acl-sets', u'acl-set', u'acl-entries', u'acl-entry', u'config'] + return ['acl', 'acl-sets', 'acl-set', 'acl-entries', 'acl-entry', 'config'] def _get_sequence_id(self): """ @@ -451,7 +437,7 @@ def _set_sequence_id(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..4294967295']}, int_size=32), is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='uint32', is_config=True) + t = YANGDynClass(v,base=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..4294967295']}, int_size=32), is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='uint32', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """sequence_id must be of a type compatible with uint32""", @@ -464,7 +450,7 @@ def _set_sequence_id(self, v, load=False): self._set() def _unset_sequence_id(self): - self.__sequence_id = YANGDynClass(base=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..4294967295']}, int_size=32), is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='uint32', is_config=True) + self.__sequence_id = YANGDynClass(base=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..4294967295']}, int_size=32), is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='uint32', is_config=True) def _get_description(self): @@ -490,7 +476,7 @@ def _set_description(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=unicode, is_leaf=True, yang_name="description", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=True) + t = YANGDynClass(v,base=str, is_leaf=True, yang_name="description", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """description must be of a type compatible with string""", @@ -503,10 +489,10 @@ def _set_description(self, v, load=False): self._set() def _unset_description(self): - self.__description = YANGDynClass(base=unicode, is_leaf=True, yang_name="description", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=True) + self.__description = YANGDynClass(base=str, is_leaf=True, yang_name="description", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=True) - sequence_id = __builtin__.property(_get_sequence_id, _set_sequence_id) - description = __builtin__.property(_get_description, _set_description) + sequence_id = builtins.property(_get_sequence_id, _set_sequence_id) + description = builtins.property(_get_description, _set_description) _pyangbind_elements = {'sequence_id': sequence_id, 'description': description, } @@ -523,19 +509,15 @@ class yc_state_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_state( """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__sequence_id','__description','__matched_packets','__matched_octets',) - _yang_name = 'state' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'state' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False - self.__matched_octets = YANGDynClass(base=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-octets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) - self.__sequence_id = YANGDynClass(base=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..4294967295']}, int_size=32), is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='uint32', is_config=False) - self.__description = YANGDynClass(base=unicode, is_leaf=True, yang_name="description", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=False) - self.__matched_packets = YANGDynClass(base=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-packets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) + self.__matched_octets = YANGDynClass(base=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-octets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) + self.__sequence_id = YANGDynClass(base=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..4294967295']}, int_size=32), is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='uint32', is_config=False) + self.__description = YANGDynClass(base=str, is_leaf=True, yang_name="description", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=False) + self.__matched_packets = YANGDynClass(base=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-packets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) load = kwargs.pop("load", None) if args: @@ -562,7 +544,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'acl-sets', u'acl-set', u'acl-entries', u'acl-entry', u'state'] + return ['acl', 'acl-sets', 'acl-set', 'acl-entries', 'acl-entry', 'state'] def _get_sequence_id(self): """ @@ -593,7 +575,7 @@ def _set_sequence_id(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..4294967295']}, int_size=32), is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='uint32', is_config=False) + t = YANGDynClass(v,base=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..4294967295']}, int_size=32), is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='uint32', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """sequence_id must be of a type compatible with uint32""", @@ -606,7 +588,7 @@ def _set_sequence_id(self, v, load=False): self._set() def _unset_sequence_id(self): - self.__sequence_id = YANGDynClass(base=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..4294967295']}, int_size=32), is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='uint32', is_config=False) + self.__sequence_id = YANGDynClass(base=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..4294967295']}, int_size=32), is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='uint32', is_config=False) def _get_description(self): @@ -632,7 +614,7 @@ def _set_description(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=unicode, is_leaf=True, yang_name="description", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=False) + t = YANGDynClass(v,base=str, is_leaf=True, yang_name="description", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """description must be of a type compatible with string""", @@ -645,7 +627,7 @@ def _set_description(self, v, load=False): self._set() def _unset_description(self): - self.__description = YANGDynClass(base=unicode, is_leaf=True, yang_name="description", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=False) + self.__description = YANGDynClass(base=str, is_leaf=True, yang_name="description", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='string', is_config=False) def _get_matched_packets(self): @@ -695,7 +677,7 @@ def _set_matched_packets(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-packets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) + t = YANGDynClass(v,base=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-packets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """matched_packets must be of a type compatible with yang:counter64""", @@ -708,7 +690,7 @@ def _set_matched_packets(self, v, load=False): self._set() def _unset_matched_packets(self): - self.__matched_packets = YANGDynClass(base=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-packets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) + self.__matched_packets = YANGDynClass(base=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-packets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) def _get_matched_octets(self): @@ -758,7 +740,7 @@ def _set_matched_octets(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-octets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) + t = YANGDynClass(v,base=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-octets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """matched_octets must be of a type compatible with yang:counter64""", @@ -771,12 +753,12 @@ def _set_matched_octets(self, v, load=False): self._set() def _unset_matched_octets(self): - self.__matched_octets = YANGDynClass(base=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-octets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) + self.__matched_octets = YANGDynClass(base=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-octets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) - sequence_id = __builtin__.property(_get_sequence_id) - description = __builtin__.property(_get_description) - matched_packets = __builtin__.property(_get_matched_packets) - matched_octets = __builtin__.property(_get_matched_octets) + sequence_id = builtins.property(_get_sequence_id) + description = builtins.property(_get_description) + matched_packets = builtins.property(_get_matched_packets) + matched_octets = builtins.property(_get_matched_octets) _pyangbind_elements = {'sequence_id': sequence_id, 'description': description, 'matched_packets': matched_packets, 'matched_octets': matched_octets, } @@ -793,20 +775,16 @@ class yc_config_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_l2_co """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__source_mac','__source_mac_mask','__destination_mac','__destination_mac_mask','__ethertype',) - _yang_name = 'config' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'config' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False - self.__source_mac = YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="source-mac", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=True) - self.__destination_mac = YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="destination-mac", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=True) - self.__destination_mac_mask = YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="destination-mac-mask", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=True) - self.__ethertype = YANGDynClass(base=[RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': [u'1..65535']}),RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'oc-pkt-match-types:ETHERTYPE_LLDP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_VLAN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_ROCE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_ARP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_IPV4': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_IPV6': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_ARP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_MPLS': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_VLAN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_ROCE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_IPV6': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_MPLS': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_IPV4': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_LLDP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}},),], is_leaf=True, yang_name="ethertype", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:ethertype-type', is_config=True) - self.__source_mac_mask = YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="source-mac-mask", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=True) + self.__source_mac = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_dict={'pattern': '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="source-mac", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=True) + self.__destination_mac = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_dict={'pattern': '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="destination-mac", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=True) + self.__destination_mac_mask = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_dict={'pattern': '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="destination-mac-mask", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=True) + self.__ethertype = YANGDynClass(base=[RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': ['1..65535']}),RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'oc-pkt-match-types:ETHERTYPE_LLDP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_VLAN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_ROCE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_ARP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_IPV4': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_IPV6': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_ARP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_MPLS': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_VLAN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_ROCE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_IPV6': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_MPLS': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_IPV4': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_LLDP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}},),], is_leaf=True, yang_name="ethertype", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:ethertype-type', is_config=True) + self.__source_mac_mask = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_dict={'pattern': '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="source-mac-mask", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=True) load = kwargs.pop("load", None) if args: @@ -833,7 +811,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'acl-sets', u'acl-set', u'acl-entries', u'acl-entry', u'l2', u'config'] + return ['acl', 'acl-sets', 'acl-set', 'acl-entries', 'acl-entry', 'l2', 'config'] def _get_source_mac(self): """ @@ -856,7 +834,7 @@ def _set_source_mac(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="source-mac", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=True) + t = YANGDynClass(v,base=RestrictedClassType(base_type=str, restriction_dict={'pattern': '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="source-mac", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """source_mac must be of a type compatible with yang:mac-address""", @@ -869,7 +847,7 @@ def _set_source_mac(self, v, load=False): self._set() def _unset_source_mac(self): - self.__source_mac = YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="source-mac", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=True) + self.__source_mac = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_dict={'pattern': '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="source-mac", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=True) def _get_source_mac_mask(self): @@ -893,7 +871,7 @@ def _set_source_mac_mask(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="source-mac-mask", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=True) + t = YANGDynClass(v,base=RestrictedClassType(base_type=str, restriction_dict={'pattern': '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="source-mac-mask", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """source_mac_mask must be of a type compatible with yang:mac-address""", @@ -906,7 +884,7 @@ def _set_source_mac_mask(self, v, load=False): self._set() def _unset_source_mac_mask(self): - self.__source_mac_mask = YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="source-mac-mask", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=True) + self.__source_mac_mask = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_dict={'pattern': '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="source-mac-mask", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=True) def _get_destination_mac(self): @@ -930,7 +908,7 @@ def _set_destination_mac(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="destination-mac", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=True) + t = YANGDynClass(v,base=RestrictedClassType(base_type=str, restriction_dict={'pattern': '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="destination-mac", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """destination_mac must be of a type compatible with yang:mac-address""", @@ -943,7 +921,7 @@ def _set_destination_mac(self, v, load=False): self._set() def _unset_destination_mac(self): - self.__destination_mac = YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="destination-mac", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=True) + self.__destination_mac = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_dict={'pattern': '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="destination-mac", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=True) def _get_destination_mac_mask(self): @@ -967,7 +945,7 @@ def _set_destination_mac_mask(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="destination-mac-mask", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=True) + t = YANGDynClass(v,base=RestrictedClassType(base_type=str, restriction_dict={'pattern': '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="destination-mac-mask", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """destination_mac_mask must be of a type compatible with yang:mac-address""", @@ -980,7 +958,7 @@ def _set_destination_mac_mask(self, v, load=False): self._set() def _unset_destination_mac_mask(self): - self.__destination_mac_mask = YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="destination-mac-mask", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=True) + self.__destination_mac_mask = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_dict={'pattern': '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="destination-mac-mask", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=True) def _get_ethertype(self): @@ -1004,7 +982,7 @@ def _set_ethertype(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=[RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': [u'1..65535']}),RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'oc-pkt-match-types:ETHERTYPE_LLDP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_VLAN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_ROCE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_ARP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_IPV4': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_IPV6': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_ARP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_MPLS': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_VLAN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_ROCE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_IPV6': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_MPLS': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_IPV4': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_LLDP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}},),], is_leaf=True, yang_name="ethertype", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:ethertype-type', is_config=True) + t = YANGDynClass(v,base=[RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': ['1..65535']}),RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'oc-pkt-match-types:ETHERTYPE_LLDP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_VLAN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_ROCE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_ARP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_IPV4': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_IPV6': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_ARP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_MPLS': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_VLAN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_ROCE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_IPV6': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_MPLS': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_IPV4': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_LLDP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}},),], is_leaf=True, yang_name="ethertype", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:ethertype-type', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """ethertype must be of a type compatible with oc-pkt-match-types:ethertype-type""", @@ -1017,13 +995,13 @@ def _set_ethertype(self, v, load=False): self._set() def _unset_ethertype(self): - self.__ethertype = YANGDynClass(base=[RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': [u'1..65535']}),RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'oc-pkt-match-types:ETHERTYPE_LLDP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_VLAN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_ROCE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_ARP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_IPV4': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_IPV6': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_ARP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_MPLS': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_VLAN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_ROCE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_IPV6': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_MPLS': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_IPV4': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_LLDP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}},),], is_leaf=True, yang_name="ethertype", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:ethertype-type', is_config=True) + self.__ethertype = YANGDynClass(base=[RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': ['1..65535']}),RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'oc-pkt-match-types:ETHERTYPE_LLDP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_VLAN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_ROCE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_ARP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_IPV4': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_IPV6': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_ARP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_MPLS': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_VLAN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_ROCE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_IPV6': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_MPLS': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_IPV4': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_LLDP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}},),], is_leaf=True, yang_name="ethertype", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:ethertype-type', is_config=True) - source_mac = __builtin__.property(_get_source_mac, _set_source_mac) - source_mac_mask = __builtin__.property(_get_source_mac_mask, _set_source_mac_mask) - destination_mac = __builtin__.property(_get_destination_mac, _set_destination_mac) - destination_mac_mask = __builtin__.property(_get_destination_mac_mask, _set_destination_mac_mask) - ethertype = __builtin__.property(_get_ethertype, _set_ethertype) + source_mac = builtins.property(_get_source_mac, _set_source_mac) + source_mac_mask = builtins.property(_get_source_mac_mask, _set_source_mac_mask) + destination_mac = builtins.property(_get_destination_mac, _set_destination_mac) + destination_mac_mask = builtins.property(_get_destination_mac_mask, _set_destination_mac_mask) + ethertype = builtins.property(_get_ethertype, _set_ethertype) _pyangbind_elements = {'source_mac': source_mac, 'source_mac_mask': source_mac_mask, 'destination_mac': destination_mac, 'destination_mac_mask': destination_mac_mask, 'ethertype': ethertype, } @@ -1040,20 +1018,16 @@ class yc_state_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_l2_sta """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__source_mac','__source_mac_mask','__destination_mac','__destination_mac_mask','__ethertype',) - _yang_name = 'state' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'state' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False - self.__source_mac = YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="source-mac", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=False) - self.__destination_mac = YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="destination-mac", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=False) - self.__destination_mac_mask = YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="destination-mac-mask", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=False) - self.__ethertype = YANGDynClass(base=[RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': [u'1..65535']}),RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'oc-pkt-match-types:ETHERTYPE_LLDP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_VLAN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_ROCE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_ARP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_IPV4': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_IPV6': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_ARP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_MPLS': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_VLAN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_ROCE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_IPV6': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_MPLS': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_IPV4': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_LLDP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}},),], is_leaf=True, yang_name="ethertype", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:ethertype-type', is_config=False) - self.__source_mac_mask = YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="source-mac-mask", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=False) + self.__source_mac = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_dict={'pattern': '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="source-mac", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=False) + self.__destination_mac = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_dict={'pattern': '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="destination-mac", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=False) + self.__destination_mac_mask = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_dict={'pattern': '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="destination-mac-mask", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=False) + self.__ethertype = YANGDynClass(base=[RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': ['1..65535']}),RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'oc-pkt-match-types:ETHERTYPE_LLDP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_VLAN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_ROCE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_ARP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_IPV4': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_IPV6': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_ARP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_MPLS': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_VLAN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_ROCE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_IPV6': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_MPLS': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_IPV4': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_LLDP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}},),], is_leaf=True, yang_name="ethertype", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:ethertype-type', is_config=False) + self.__source_mac_mask = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_dict={'pattern': '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="source-mac-mask", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=False) load = kwargs.pop("load", None) if args: @@ -1080,7 +1054,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'acl-sets', u'acl-set', u'acl-entries', u'acl-entry', u'l2', u'state'] + return ['acl', 'acl-sets', 'acl-set', 'acl-entries', 'acl-entry', 'l2', 'state'] def _get_source_mac(self): """ @@ -1103,7 +1077,7 @@ def _set_source_mac(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="source-mac", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=False) + t = YANGDynClass(v,base=RestrictedClassType(base_type=str, restriction_dict={'pattern': '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="source-mac", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """source_mac must be of a type compatible with yang:mac-address""", @@ -1116,7 +1090,7 @@ def _set_source_mac(self, v, load=False): self._set() def _unset_source_mac(self): - self.__source_mac = YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="source-mac", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=False) + self.__source_mac = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_dict={'pattern': '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="source-mac", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=False) def _get_source_mac_mask(self): @@ -1140,7 +1114,7 @@ def _set_source_mac_mask(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="source-mac-mask", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=False) + t = YANGDynClass(v,base=RestrictedClassType(base_type=str, restriction_dict={'pattern': '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="source-mac-mask", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """source_mac_mask must be of a type compatible with yang:mac-address""", @@ -1153,7 +1127,7 @@ def _set_source_mac_mask(self, v, load=False): self._set() def _unset_source_mac_mask(self): - self.__source_mac_mask = YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="source-mac-mask", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=False) + self.__source_mac_mask = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_dict={'pattern': '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="source-mac-mask", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=False) def _get_destination_mac(self): @@ -1177,7 +1151,7 @@ def _set_destination_mac(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="destination-mac", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=False) + t = YANGDynClass(v,base=RestrictedClassType(base_type=str, restriction_dict={'pattern': '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="destination-mac", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """destination_mac must be of a type compatible with yang:mac-address""", @@ -1190,7 +1164,7 @@ def _set_destination_mac(self, v, load=False): self._set() def _unset_destination_mac(self): - self.__destination_mac = YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="destination-mac", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=False) + self.__destination_mac = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_dict={'pattern': '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="destination-mac", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=False) def _get_destination_mac_mask(self): @@ -1214,7 +1188,7 @@ def _set_destination_mac_mask(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="destination-mac-mask", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=False) + t = YANGDynClass(v,base=RestrictedClassType(base_type=str, restriction_dict={'pattern': '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="destination-mac-mask", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """destination_mac_mask must be of a type compatible with yang:mac-address""", @@ -1227,7 +1201,7 @@ def _set_destination_mac_mask(self, v, load=False): self._set() def _unset_destination_mac_mask(self): - self.__destination_mac_mask = YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="destination-mac-mask", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=False) + self.__destination_mac_mask = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_dict={'pattern': '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'}), is_leaf=True, yang_name="destination-mac-mask", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:mac-address', is_config=False) def _get_ethertype(self): @@ -1251,7 +1225,7 @@ def _set_ethertype(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=[RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': [u'1..65535']}),RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'oc-pkt-match-types:ETHERTYPE_LLDP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_VLAN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_ROCE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_ARP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_IPV4': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_IPV6': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_ARP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_MPLS': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_VLAN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_ROCE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_IPV6': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_MPLS': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_IPV4': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_LLDP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}},),], is_leaf=True, yang_name="ethertype", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:ethertype-type', is_config=False) + t = YANGDynClass(v,base=[RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': ['1..65535']}),RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'oc-pkt-match-types:ETHERTYPE_LLDP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_VLAN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_ROCE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_ARP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_IPV4': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_IPV6': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_ARP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_MPLS': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_VLAN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_ROCE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_IPV6': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_MPLS': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_IPV4': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_LLDP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}},),], is_leaf=True, yang_name="ethertype", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:ethertype-type', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """ethertype must be of a type compatible with oc-pkt-match-types:ethertype-type""", @@ -1264,13 +1238,13 @@ def _set_ethertype(self, v, load=False): self._set() def _unset_ethertype(self): - self.__ethertype = YANGDynClass(base=[RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': [u'1..65535']}),RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'oc-pkt-match-types:ETHERTYPE_LLDP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_VLAN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_ROCE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_ARP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_IPV4': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_IPV6': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_ARP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_MPLS': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_VLAN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_ROCE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_IPV6': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_MPLS': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:ETHERTYPE_IPV4': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'ETHERTYPE_LLDP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}},),], is_leaf=True, yang_name="ethertype", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:ethertype-type', is_config=False) + self.__ethertype = YANGDynClass(base=[RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': ['1..65535']}),RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'oc-pkt-match-types:ETHERTYPE_LLDP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_VLAN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_ROCE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_ARP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_IPV4': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_IPV6': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_ARP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_MPLS': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_VLAN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_ROCE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_IPV6': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_MPLS': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:ETHERTYPE_IPV4': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'ETHERTYPE_LLDP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}},),], is_leaf=True, yang_name="ethertype", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:ethertype-type', is_config=False) - source_mac = __builtin__.property(_get_source_mac) - source_mac_mask = __builtin__.property(_get_source_mac_mask) - destination_mac = __builtin__.property(_get_destination_mac) - destination_mac_mask = __builtin__.property(_get_destination_mac_mask) - ethertype = __builtin__.property(_get_ethertype) + source_mac = builtins.property(_get_source_mac) + source_mac_mask = builtins.property(_get_source_mac_mask) + destination_mac = builtins.property(_get_destination_mac) + destination_mac_mask = builtins.property(_get_destination_mac_mask) + ethertype = builtins.property(_get_ethertype) _pyangbind_elements = {'source_mac': source_mac, 'source_mac_mask': source_mac_mask, 'destination_mac': destination_mac, 'destination_mac_mask': destination_mac_mask, 'ethertype': ethertype, } @@ -1287,14 +1261,10 @@ class yc_l2_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_l2(Pybind """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__config','__state',) - _yang_name = 'l2' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'l2' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__state = YANGDynClass(base=yc_state_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_l2_state, is_container='container', yang_name="state", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) self.__config = YANGDynClass(base=yc_config_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_l2_config, is_container='container', yang_name="config", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) @@ -1324,7 +1294,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'acl-sets', u'acl-set', u'acl-entries', u'acl-entry', u'l2'] + return ['acl', 'acl-sets', 'acl-set', 'acl-entries', 'acl-entry', 'l2'] def _get_config(self): """ @@ -1399,8 +1369,8 @@ def _set_state(self, v, load=False): def _unset_state(self): self.__state = YANGDynClass(base=yc_state_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_l2_state, is_container='container', yang_name="state", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) - config = __builtin__.property(_get_config, _set_config) - state = __builtin__.property(_get_state, _set_state) + config = builtins.property(_get_config, _set_config) + state = builtins.property(_get_state, _set_state) _pyangbind_elements = {'config': config, 'state': state, } @@ -1417,23 +1387,19 @@ class yc_config_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_ip_co """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__ip_version','__source_ip_address','__source_ip_flow_label','__destination_ip_address','__destination_ip_flow_label','__dscp','__protocol','__hop_limit',) - _yang_name = 'config' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'config' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False - self.__hop_limit = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': [u'0..255']}), is_leaf=True, yang_name="hop-limit", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='uint8', is_config=True) - self.__protocol = YANGDynClass(base=[RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': [u'0..254']}),RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'oc-pkt-match-types:IP_TCP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_L2TP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_L2TP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_AUTH': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_RSVP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_GRE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_TCP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_AUTH': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_UDP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_PIM': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_GRE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_IGMP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_RSVP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_ICMP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_PIM': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_UDP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_IGMP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_ICMP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}},),], is_leaf=True, yang_name="protocol", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:ip-protocol-type', is_config=True) - self.__dscp = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': [u'0..63']}), is_leaf=True, yang_name="dscp", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:dscp', is_config=True) - self.__source_ip_address = YANGDynClass(base=[RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))'}),RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))'}),], is_leaf=True, yang_name="source-ip-address", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-prefix', is_config=True) - self.__destination_ip_address = YANGDynClass(base=[RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))'}),RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))'}),], is_leaf=True, yang_name="destination-ip-address", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-prefix', is_config=True) - self.__ip_version = YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'unknown': {'value': 0}, u'ipv4': {'value': 1}, u'ipv6': {'value': 2}},), is_leaf=True, yang_name="ip-version", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-version', is_config=True) - self.__destination_ip_flow_label = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..4294967295']}, int_size=32), restriction_dict={'range': [u'0..1048575']}), is_leaf=True, yang_name="destination-ip-flow-label", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ipv6-flow-label', is_config=True) - self.__source_ip_flow_label = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..4294967295']}, int_size=32), restriction_dict={'range': [u'0..1048575']}), is_leaf=True, yang_name="source-ip-flow-label", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ipv6-flow-label', is_config=True) + self.__hop_limit = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': ['0..255']}), is_leaf=True, yang_name="hop-limit", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='uint8', is_config=True) + self.__protocol = YANGDynClass(base=[RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': ['0..254']}),RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'oc-pkt-match-types:IP_TCP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_L2TP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_L2TP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_AUTH': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_RSVP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_GRE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_TCP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_AUTH': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_UDP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_PIM': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_GRE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_IGMP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_RSVP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_ICMP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_PIM': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_UDP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_IGMP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_ICMP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}},),], is_leaf=True, yang_name="protocol", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:ip-protocol-type', is_config=True) + self.__dscp = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': ['0..63']}), is_leaf=True, yang_name="dscp", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:dscp', is_config=True) + self.__source_ip_address = YANGDynClass(base=[RestrictedClassType(base_type=str, restriction_dict={'pattern': '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))'}),RestrictedClassType(base_type=str, restriction_dict={'pattern': '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))'}),], is_leaf=True, yang_name="source-ip-address", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-prefix', is_config=True) + self.__destination_ip_address = YANGDynClass(base=[RestrictedClassType(base_type=str, restriction_dict={'pattern': '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))'}),RestrictedClassType(base_type=str, restriction_dict={'pattern': '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))'}),], is_leaf=True, yang_name="destination-ip-address", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-prefix', is_config=True) + self.__ip_version = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'unknown': {'value': 0}, 'ipv4': {'value': 1}, 'ipv6': {'value': 2}},), is_leaf=True, yang_name="ip-version", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-version', is_config=True) + self.__destination_ip_flow_label = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..4294967295']}, int_size=32), restriction_dict={'range': ['0..1048575']}), is_leaf=True, yang_name="destination-ip-flow-label", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ipv6-flow-label', is_config=True) + self.__source_ip_flow_label = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..4294967295']}, int_size=32), restriction_dict={'range': ['0..1048575']}), is_leaf=True, yang_name="source-ip-flow-label", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ipv6-flow-label', is_config=True) load = kwargs.pop("load", None) if args: @@ -1460,7 +1426,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'acl-sets', u'acl-set', u'acl-entries', u'acl-entry', u'ip', u'config'] + return ['acl', 'acl-sets', 'acl-set', 'acl-entries', 'acl-entry', 'ip', 'config'] def _get_ip_version(self): """ @@ -1483,12 +1449,12 @@ def _set_ip_version(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'unknown': {'value': 0}, u'ipv4': {'value': 1}, u'ipv6': {'value': 2}},), is_leaf=True, yang_name="ip-version", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-version', is_config=True) + t = YANGDynClass(v,base=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'unknown': {'value': 0}, 'ipv4': {'value': 1}, 'ipv6': {'value': 2}},), is_leaf=True, yang_name="ip-version", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-version', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """ip_version must be of a type compatible with inet:ip-version""", 'defined-type': "inet:ip-version", - 'generated-type': """YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'unknown': {'value': 0}, u'ipv4': {'value': 1}, u'ipv6': {'value': 2}},), is_leaf=True, yang_name="ip-version", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-version', is_config=True)""", + 'generated-type': """YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'unknown': {'value': 0}, u'ipv4': {'value': 1}, u'ipv6': {'value': 2}},), is_leaf=True, yang_name="ip-version", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-version', is_config=True)""", }) self.__ip_version = t @@ -1496,7 +1462,7 @@ def _set_ip_version(self, v, load=False): self._set() def _unset_ip_version(self): - self.__ip_version = YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'unknown': {'value': 0}, u'ipv4': {'value': 1}, u'ipv6': {'value': 2}},), is_leaf=True, yang_name="ip-version", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-version', is_config=True) + self.__ip_version = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'unknown': {'value': 0}, 'ipv4': {'value': 1}, 'ipv6': {'value': 2}},), is_leaf=True, yang_name="ip-version", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-version', is_config=True) def _get_source_ip_address(self): @@ -1520,7 +1486,7 @@ def _set_source_ip_address(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=[RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))'}),RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))'}),], is_leaf=True, yang_name="source-ip-address", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-prefix', is_config=True) + t = YANGDynClass(v,base=[RestrictedClassType(base_type=str, restriction_dict={'pattern': '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))'}),RestrictedClassType(base_type=str, restriction_dict={'pattern': '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))'}),], is_leaf=True, yang_name="source-ip-address", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-prefix', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """source_ip_address must be of a type compatible with inet:ip-prefix""", @@ -1533,7 +1499,7 @@ def _set_source_ip_address(self, v, load=False): self._set() def _unset_source_ip_address(self): - self.__source_ip_address = YANGDynClass(base=[RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))'}),RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))'}),], is_leaf=True, yang_name="source-ip-address", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-prefix', is_config=True) + self.__source_ip_address = YANGDynClass(base=[RestrictedClassType(base_type=str, restriction_dict={'pattern': '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))'}),RestrictedClassType(base_type=str, restriction_dict={'pattern': '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))'}),], is_leaf=True, yang_name="source-ip-address", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-prefix', is_config=True) def _get_source_ip_flow_label(self): @@ -1557,7 +1523,7 @@ def _set_source_ip_flow_label(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=RestrictedClassType(base_type=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..4294967295']}, int_size=32), restriction_dict={'range': [u'0..1048575']}), is_leaf=True, yang_name="source-ip-flow-label", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ipv6-flow-label', is_config=True) + t = YANGDynClass(v,base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..4294967295']}, int_size=32), restriction_dict={'range': ['0..1048575']}), is_leaf=True, yang_name="source-ip-flow-label", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ipv6-flow-label', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """source_ip_flow_label must be of a type compatible with inet:ipv6-flow-label""", @@ -1570,7 +1536,7 @@ def _set_source_ip_flow_label(self, v, load=False): self._set() def _unset_source_ip_flow_label(self): - self.__source_ip_flow_label = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..4294967295']}, int_size=32), restriction_dict={'range': [u'0..1048575']}), is_leaf=True, yang_name="source-ip-flow-label", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ipv6-flow-label', is_config=True) + self.__source_ip_flow_label = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..4294967295']}, int_size=32), restriction_dict={'range': ['0..1048575']}), is_leaf=True, yang_name="source-ip-flow-label", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ipv6-flow-label', is_config=True) def _get_destination_ip_address(self): @@ -1594,7 +1560,7 @@ def _set_destination_ip_address(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=[RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))'}),RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))'}),], is_leaf=True, yang_name="destination-ip-address", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-prefix', is_config=True) + t = YANGDynClass(v,base=[RestrictedClassType(base_type=str, restriction_dict={'pattern': '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))'}),RestrictedClassType(base_type=str, restriction_dict={'pattern': '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))'}),], is_leaf=True, yang_name="destination-ip-address", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-prefix', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """destination_ip_address must be of a type compatible with inet:ip-prefix""", @@ -1607,7 +1573,7 @@ def _set_destination_ip_address(self, v, load=False): self._set() def _unset_destination_ip_address(self): - self.__destination_ip_address = YANGDynClass(base=[RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))'}),RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))'}),], is_leaf=True, yang_name="destination-ip-address", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-prefix', is_config=True) + self.__destination_ip_address = YANGDynClass(base=[RestrictedClassType(base_type=str, restriction_dict={'pattern': '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))'}),RestrictedClassType(base_type=str, restriction_dict={'pattern': '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))'}),], is_leaf=True, yang_name="destination-ip-address", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-prefix', is_config=True) def _get_destination_ip_flow_label(self): @@ -1631,7 +1597,7 @@ def _set_destination_ip_flow_label(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=RestrictedClassType(base_type=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..4294967295']}, int_size=32), restriction_dict={'range': [u'0..1048575']}), is_leaf=True, yang_name="destination-ip-flow-label", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ipv6-flow-label', is_config=True) + t = YANGDynClass(v,base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..4294967295']}, int_size=32), restriction_dict={'range': ['0..1048575']}), is_leaf=True, yang_name="destination-ip-flow-label", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ipv6-flow-label', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """destination_ip_flow_label must be of a type compatible with inet:ipv6-flow-label""", @@ -1644,7 +1610,7 @@ def _set_destination_ip_flow_label(self, v, load=False): self._set() def _unset_destination_ip_flow_label(self): - self.__destination_ip_flow_label = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..4294967295']}, int_size=32), restriction_dict={'range': [u'0..1048575']}), is_leaf=True, yang_name="destination-ip-flow-label", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ipv6-flow-label', is_config=True) + self.__destination_ip_flow_label = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..4294967295']}, int_size=32), restriction_dict={'range': ['0..1048575']}), is_leaf=True, yang_name="destination-ip-flow-label", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ipv6-flow-label', is_config=True) def _get_dscp(self): @@ -1668,7 +1634,7 @@ def _set_dscp(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': [u'0..63']}), is_leaf=True, yang_name="dscp", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:dscp', is_config=True) + t = YANGDynClass(v,base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': ['0..63']}), is_leaf=True, yang_name="dscp", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:dscp', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """dscp must be of a type compatible with inet:dscp""", @@ -1681,7 +1647,7 @@ def _set_dscp(self, v, load=False): self._set() def _unset_dscp(self): - self.__dscp = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': [u'0..63']}), is_leaf=True, yang_name="dscp", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:dscp', is_config=True) + self.__dscp = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': ['0..63']}), is_leaf=True, yang_name="dscp", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:dscp', is_config=True) def _get_protocol(self): @@ -1705,7 +1671,7 @@ def _set_protocol(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=[RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': [u'0..254']}),RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'oc-pkt-match-types:IP_TCP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_L2TP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_L2TP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_AUTH': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_RSVP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_GRE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_TCP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_AUTH': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_UDP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_PIM': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_GRE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_IGMP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_RSVP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_ICMP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_PIM': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_UDP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_IGMP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_ICMP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}},),], is_leaf=True, yang_name="protocol", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:ip-protocol-type', is_config=True) + t = YANGDynClass(v,base=[RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': ['0..254']}),RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'oc-pkt-match-types:IP_TCP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_L2TP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_L2TP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_AUTH': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_RSVP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_GRE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_TCP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_AUTH': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_UDP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_PIM': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_GRE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_IGMP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_RSVP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_ICMP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_PIM': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_UDP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_IGMP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_ICMP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}},),], is_leaf=True, yang_name="protocol", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:ip-protocol-type', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """protocol must be of a type compatible with oc-pkt-match-types:ip-protocol-type""", @@ -1718,7 +1684,7 @@ def _set_protocol(self, v, load=False): self._set() def _unset_protocol(self): - self.__protocol = YANGDynClass(base=[RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': [u'0..254']}),RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'oc-pkt-match-types:IP_TCP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_L2TP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_L2TP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_AUTH': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_RSVP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_GRE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_TCP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_AUTH': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_UDP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_PIM': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_GRE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_IGMP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_RSVP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_ICMP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_PIM': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_UDP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_IGMP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_ICMP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}},),], is_leaf=True, yang_name="protocol", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:ip-protocol-type', is_config=True) + self.__protocol = YANGDynClass(base=[RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': ['0..254']}),RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'oc-pkt-match-types:IP_TCP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_L2TP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_L2TP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_AUTH': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_RSVP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_GRE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_TCP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_AUTH': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_UDP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_PIM': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_GRE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_IGMP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_RSVP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_ICMP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_PIM': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_UDP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_IGMP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_ICMP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}},),], is_leaf=True, yang_name="protocol", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:ip-protocol-type', is_config=True) def _get_hop_limit(self): @@ -1744,7 +1710,7 @@ def _set_hop_limit(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': [u'0..255']}), is_leaf=True, yang_name="hop-limit", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='uint8', is_config=True) + t = YANGDynClass(v,base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': ['0..255']}), is_leaf=True, yang_name="hop-limit", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='uint8', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """hop_limit must be of a type compatible with uint8""", @@ -1757,16 +1723,16 @@ def _set_hop_limit(self, v, load=False): self._set() def _unset_hop_limit(self): - self.__hop_limit = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': [u'0..255']}), is_leaf=True, yang_name="hop-limit", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='uint8', is_config=True) + self.__hop_limit = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': ['0..255']}), is_leaf=True, yang_name="hop-limit", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='uint8', is_config=True) - ip_version = __builtin__.property(_get_ip_version, _set_ip_version) - source_ip_address = __builtin__.property(_get_source_ip_address, _set_source_ip_address) - source_ip_flow_label = __builtin__.property(_get_source_ip_flow_label, _set_source_ip_flow_label) - destination_ip_address = __builtin__.property(_get_destination_ip_address, _set_destination_ip_address) - destination_ip_flow_label = __builtin__.property(_get_destination_ip_flow_label, _set_destination_ip_flow_label) - dscp = __builtin__.property(_get_dscp, _set_dscp) - protocol = __builtin__.property(_get_protocol, _set_protocol) - hop_limit = __builtin__.property(_get_hop_limit, _set_hop_limit) + ip_version = builtins.property(_get_ip_version, _set_ip_version) + source_ip_address = builtins.property(_get_source_ip_address, _set_source_ip_address) + source_ip_flow_label = builtins.property(_get_source_ip_flow_label, _set_source_ip_flow_label) + destination_ip_address = builtins.property(_get_destination_ip_address, _set_destination_ip_address) + destination_ip_flow_label = builtins.property(_get_destination_ip_flow_label, _set_destination_ip_flow_label) + dscp = builtins.property(_get_dscp, _set_dscp) + protocol = builtins.property(_get_protocol, _set_protocol) + hop_limit = builtins.property(_get_hop_limit, _set_hop_limit) _pyangbind_elements = {'ip_version': ip_version, 'source_ip_address': source_ip_address, 'source_ip_flow_label': source_ip_flow_label, 'destination_ip_address': destination_ip_address, 'destination_ip_flow_label': destination_ip_flow_label, 'dscp': dscp, 'protocol': protocol, 'hop_limit': hop_limit, } @@ -1783,23 +1749,19 @@ class yc_state_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_ip_sta """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__ip_version','__source_ip_address','__source_ip_flow_label','__destination_ip_address','__destination_ip_flow_label','__dscp','__protocol','__hop_limit',) - _yang_name = 'state' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'state' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False - self.__hop_limit = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': [u'0..255']}), is_leaf=True, yang_name="hop-limit", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='uint8', is_config=False) - self.__protocol = YANGDynClass(base=[RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': [u'0..254']}),RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'oc-pkt-match-types:IP_TCP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_L2TP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_L2TP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_AUTH': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_RSVP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_GRE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_TCP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_AUTH': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_UDP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_PIM': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_GRE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_IGMP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_RSVP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_ICMP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_PIM': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_UDP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_IGMP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_ICMP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}},),], is_leaf=True, yang_name="protocol", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:ip-protocol-type', is_config=False) - self.__dscp = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': [u'0..63']}), is_leaf=True, yang_name="dscp", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:dscp', is_config=False) - self.__source_ip_address = YANGDynClass(base=[RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))'}),RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))'}),], is_leaf=True, yang_name="source-ip-address", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-prefix', is_config=False) - self.__destination_ip_address = YANGDynClass(base=[RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))'}),RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))'}),], is_leaf=True, yang_name="destination-ip-address", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-prefix', is_config=False) - self.__ip_version = YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'unknown': {'value': 0}, u'ipv4': {'value': 1}, u'ipv6': {'value': 2}},), is_leaf=True, yang_name="ip-version", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-version', is_config=False) - self.__destination_ip_flow_label = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..4294967295']}, int_size=32), restriction_dict={'range': [u'0..1048575']}), is_leaf=True, yang_name="destination-ip-flow-label", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ipv6-flow-label', is_config=False) - self.__source_ip_flow_label = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..4294967295']}, int_size=32), restriction_dict={'range': [u'0..1048575']}), is_leaf=True, yang_name="source-ip-flow-label", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ipv6-flow-label', is_config=False) + self.__hop_limit = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': ['0..255']}), is_leaf=True, yang_name="hop-limit", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='uint8', is_config=False) + self.__protocol = YANGDynClass(base=[RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': ['0..254']}),RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'oc-pkt-match-types:IP_TCP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_L2TP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_L2TP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_AUTH': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_RSVP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_GRE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_TCP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_AUTH': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_UDP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_PIM': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_GRE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_IGMP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_RSVP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_ICMP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_PIM': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_UDP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_IGMP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_ICMP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}},),], is_leaf=True, yang_name="protocol", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:ip-protocol-type', is_config=False) + self.__dscp = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': ['0..63']}), is_leaf=True, yang_name="dscp", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:dscp', is_config=False) + self.__source_ip_address = YANGDynClass(base=[RestrictedClassType(base_type=str, restriction_dict={'pattern': '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))'}),RestrictedClassType(base_type=str, restriction_dict={'pattern': '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))'}),], is_leaf=True, yang_name="source-ip-address", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-prefix', is_config=False) + self.__destination_ip_address = YANGDynClass(base=[RestrictedClassType(base_type=str, restriction_dict={'pattern': '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))'}),RestrictedClassType(base_type=str, restriction_dict={'pattern': '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))'}),], is_leaf=True, yang_name="destination-ip-address", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-prefix', is_config=False) + self.__ip_version = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'unknown': {'value': 0}, 'ipv4': {'value': 1}, 'ipv6': {'value': 2}},), is_leaf=True, yang_name="ip-version", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-version', is_config=False) + self.__destination_ip_flow_label = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..4294967295']}, int_size=32), restriction_dict={'range': ['0..1048575']}), is_leaf=True, yang_name="destination-ip-flow-label", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ipv6-flow-label', is_config=False) + self.__source_ip_flow_label = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..4294967295']}, int_size=32), restriction_dict={'range': ['0..1048575']}), is_leaf=True, yang_name="source-ip-flow-label", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ipv6-flow-label', is_config=False) load = kwargs.pop("load", None) if args: @@ -1826,7 +1788,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'acl-sets', u'acl-set', u'acl-entries', u'acl-entry', u'ip', u'state'] + return ['acl', 'acl-sets', 'acl-set', 'acl-entries', 'acl-entry', 'ip', 'state'] def _get_ip_version(self): """ @@ -1849,12 +1811,12 @@ def _set_ip_version(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'unknown': {'value': 0}, u'ipv4': {'value': 1}, u'ipv6': {'value': 2}},), is_leaf=True, yang_name="ip-version", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-version', is_config=False) + t = YANGDynClass(v,base=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'unknown': {'value': 0}, 'ipv4': {'value': 1}, 'ipv6': {'value': 2}},), is_leaf=True, yang_name="ip-version", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-version', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """ip_version must be of a type compatible with inet:ip-version""", 'defined-type': "inet:ip-version", - 'generated-type': """YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'unknown': {'value': 0}, u'ipv4': {'value': 1}, u'ipv6': {'value': 2}},), is_leaf=True, yang_name="ip-version", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-version', is_config=False)""", + 'generated-type': """YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'unknown': {'value': 0}, u'ipv4': {'value': 1}, u'ipv6': {'value': 2}},), is_leaf=True, yang_name="ip-version", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-version', is_config=False)""", }) self.__ip_version = t @@ -1862,7 +1824,7 @@ def _set_ip_version(self, v, load=False): self._set() def _unset_ip_version(self): - self.__ip_version = YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'unknown': {'value': 0}, u'ipv4': {'value': 1}, u'ipv6': {'value': 2}},), is_leaf=True, yang_name="ip-version", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-version', is_config=False) + self.__ip_version = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'unknown': {'value': 0}, 'ipv4': {'value': 1}, 'ipv6': {'value': 2}},), is_leaf=True, yang_name="ip-version", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-version', is_config=False) def _get_source_ip_address(self): @@ -1886,7 +1848,7 @@ def _set_source_ip_address(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=[RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))'}),RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))'}),], is_leaf=True, yang_name="source-ip-address", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-prefix', is_config=False) + t = YANGDynClass(v,base=[RestrictedClassType(base_type=str, restriction_dict={'pattern': '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))'}),RestrictedClassType(base_type=str, restriction_dict={'pattern': '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))'}),], is_leaf=True, yang_name="source-ip-address", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-prefix', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """source_ip_address must be of a type compatible with inet:ip-prefix""", @@ -1899,7 +1861,7 @@ def _set_source_ip_address(self, v, load=False): self._set() def _unset_source_ip_address(self): - self.__source_ip_address = YANGDynClass(base=[RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))'}),RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))'}),], is_leaf=True, yang_name="source-ip-address", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-prefix', is_config=False) + self.__source_ip_address = YANGDynClass(base=[RestrictedClassType(base_type=str, restriction_dict={'pattern': '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))'}),RestrictedClassType(base_type=str, restriction_dict={'pattern': '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))'}),], is_leaf=True, yang_name="source-ip-address", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-prefix', is_config=False) def _get_source_ip_flow_label(self): @@ -1923,7 +1885,7 @@ def _set_source_ip_flow_label(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=RestrictedClassType(base_type=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..4294967295']}, int_size=32), restriction_dict={'range': [u'0..1048575']}), is_leaf=True, yang_name="source-ip-flow-label", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ipv6-flow-label', is_config=False) + t = YANGDynClass(v,base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..4294967295']}, int_size=32), restriction_dict={'range': ['0..1048575']}), is_leaf=True, yang_name="source-ip-flow-label", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ipv6-flow-label', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """source_ip_flow_label must be of a type compatible with inet:ipv6-flow-label""", @@ -1936,7 +1898,7 @@ def _set_source_ip_flow_label(self, v, load=False): self._set() def _unset_source_ip_flow_label(self): - self.__source_ip_flow_label = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..4294967295']}, int_size=32), restriction_dict={'range': [u'0..1048575']}), is_leaf=True, yang_name="source-ip-flow-label", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ipv6-flow-label', is_config=False) + self.__source_ip_flow_label = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..4294967295']}, int_size=32), restriction_dict={'range': ['0..1048575']}), is_leaf=True, yang_name="source-ip-flow-label", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ipv6-flow-label', is_config=False) def _get_destination_ip_address(self): @@ -1960,7 +1922,7 @@ def _set_destination_ip_address(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=[RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))'}),RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))'}),], is_leaf=True, yang_name="destination-ip-address", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-prefix', is_config=False) + t = YANGDynClass(v,base=[RestrictedClassType(base_type=str, restriction_dict={'pattern': '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))'}),RestrictedClassType(base_type=str, restriction_dict={'pattern': '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))'}),], is_leaf=True, yang_name="destination-ip-address", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-prefix', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """destination_ip_address must be of a type compatible with inet:ip-prefix""", @@ -1973,7 +1935,7 @@ def _set_destination_ip_address(self, v, load=False): self._set() def _unset_destination_ip_address(self): - self.__destination_ip_address = YANGDynClass(base=[RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))'}),RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))'}),], is_leaf=True, yang_name="destination-ip-address", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-prefix', is_config=False) + self.__destination_ip_address = YANGDynClass(base=[RestrictedClassType(base_type=str, restriction_dict={'pattern': '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))'}),RestrictedClassType(base_type=str, restriction_dict={'pattern': '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))'}),], is_leaf=True, yang_name="destination-ip-address", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ip-prefix', is_config=False) def _get_destination_ip_flow_label(self): @@ -1997,7 +1959,7 @@ def _set_destination_ip_flow_label(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=RestrictedClassType(base_type=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..4294967295']}, int_size=32), restriction_dict={'range': [u'0..1048575']}), is_leaf=True, yang_name="destination-ip-flow-label", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ipv6-flow-label', is_config=False) + t = YANGDynClass(v,base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..4294967295']}, int_size=32), restriction_dict={'range': ['0..1048575']}), is_leaf=True, yang_name="destination-ip-flow-label", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ipv6-flow-label', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """destination_ip_flow_label must be of a type compatible with inet:ipv6-flow-label""", @@ -2010,7 +1972,7 @@ def _set_destination_ip_flow_label(self, v, load=False): self._set() def _unset_destination_ip_flow_label(self): - self.__destination_ip_flow_label = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..4294967295']}, int_size=32), restriction_dict={'range': [u'0..1048575']}), is_leaf=True, yang_name="destination-ip-flow-label", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ipv6-flow-label', is_config=False) + self.__destination_ip_flow_label = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..4294967295']}, int_size=32), restriction_dict={'range': ['0..1048575']}), is_leaf=True, yang_name="destination-ip-flow-label", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:ipv6-flow-label', is_config=False) def _get_dscp(self): @@ -2034,7 +1996,7 @@ def _set_dscp(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': [u'0..63']}), is_leaf=True, yang_name="dscp", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:dscp', is_config=False) + t = YANGDynClass(v,base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': ['0..63']}), is_leaf=True, yang_name="dscp", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:dscp', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """dscp must be of a type compatible with inet:dscp""", @@ -2047,7 +2009,7 @@ def _set_dscp(self, v, load=False): self._set() def _unset_dscp(self): - self.__dscp = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': [u'0..63']}), is_leaf=True, yang_name="dscp", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:dscp', is_config=False) + self.__dscp = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': ['0..63']}), is_leaf=True, yang_name="dscp", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='inet:dscp', is_config=False) def _get_protocol(self): @@ -2071,7 +2033,7 @@ def _set_protocol(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=[RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': [u'0..254']}),RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'oc-pkt-match-types:IP_TCP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_L2TP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_L2TP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_AUTH': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_RSVP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_GRE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_TCP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_AUTH': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_UDP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_PIM': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_GRE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_IGMP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_RSVP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_ICMP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_PIM': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_UDP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_IGMP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_ICMP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}},),], is_leaf=True, yang_name="protocol", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:ip-protocol-type', is_config=False) + t = YANGDynClass(v,base=[RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': ['0..254']}),RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'oc-pkt-match-types:IP_TCP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_L2TP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_L2TP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_AUTH': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_RSVP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_GRE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_TCP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_AUTH': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_UDP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_PIM': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_GRE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_IGMP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_RSVP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_ICMP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_PIM': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_UDP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_IGMP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_ICMP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}},),], is_leaf=True, yang_name="protocol", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:ip-protocol-type', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """protocol must be of a type compatible with oc-pkt-match-types:ip-protocol-type""", @@ -2084,7 +2046,7 @@ def _set_protocol(self, v, load=False): self._set() def _unset_protocol(self): - self.__protocol = YANGDynClass(base=[RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': [u'0..254']}),RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'oc-pkt-match-types:IP_TCP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_L2TP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_L2TP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_AUTH': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_RSVP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_GRE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_TCP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_AUTH': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_UDP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_PIM': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_GRE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_IGMP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_RSVP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_ICMP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_PIM': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_UDP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:IP_IGMP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'IP_ICMP': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}},),], is_leaf=True, yang_name="protocol", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:ip-protocol-type', is_config=False) + self.__protocol = YANGDynClass(base=[RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': ['0..254']}),RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'oc-pkt-match-types:IP_TCP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_L2TP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_L2TP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_AUTH': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_RSVP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_GRE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_TCP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_AUTH': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_UDP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_PIM': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_GRE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_IGMP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_RSVP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_ICMP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_PIM': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_UDP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:IP_IGMP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'IP_ICMP': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}},),], is_leaf=True, yang_name="protocol", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:ip-protocol-type', is_config=False) def _get_hop_limit(self): @@ -2110,7 +2072,7 @@ def _set_hop_limit(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': [u'0..255']}), is_leaf=True, yang_name="hop-limit", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='uint8', is_config=False) + t = YANGDynClass(v,base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': ['0..255']}), is_leaf=True, yang_name="hop-limit", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='uint8', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """hop_limit must be of a type compatible with uint8""", @@ -2123,16 +2085,16 @@ def _set_hop_limit(self, v, load=False): self._set() def _unset_hop_limit(self): - self.__hop_limit = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': [u'0..255']}), is_leaf=True, yang_name="hop-limit", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='uint8', is_config=False) + self.__hop_limit = YANGDynClass(base=RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..255']}, int_size=8), restriction_dict={'range': ['0..255']}), is_leaf=True, yang_name="hop-limit", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='uint8', is_config=False) - ip_version = __builtin__.property(_get_ip_version) - source_ip_address = __builtin__.property(_get_source_ip_address) - source_ip_flow_label = __builtin__.property(_get_source_ip_flow_label) - destination_ip_address = __builtin__.property(_get_destination_ip_address) - destination_ip_flow_label = __builtin__.property(_get_destination_ip_flow_label) - dscp = __builtin__.property(_get_dscp) - protocol = __builtin__.property(_get_protocol) - hop_limit = __builtin__.property(_get_hop_limit) + ip_version = builtins.property(_get_ip_version) + source_ip_address = builtins.property(_get_source_ip_address) + source_ip_flow_label = builtins.property(_get_source_ip_flow_label) + destination_ip_address = builtins.property(_get_destination_ip_address) + destination_ip_flow_label = builtins.property(_get_destination_ip_flow_label) + dscp = builtins.property(_get_dscp) + protocol = builtins.property(_get_protocol) + hop_limit = builtins.property(_get_hop_limit) _pyangbind_elements = {'ip_version': ip_version, 'source_ip_address': source_ip_address, 'source_ip_flow_label': source_ip_flow_label, 'destination_ip_address': destination_ip_address, 'destination_ip_flow_label': destination_ip_flow_label, 'dscp': dscp, 'protocol': protocol, 'hop_limit': hop_limit, } @@ -2149,14 +2111,10 @@ class yc_ip_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_ip(Pybind """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__config','__state',) - _yang_name = 'ip' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'ip' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__state = YANGDynClass(base=yc_state_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_ip_state, is_container='container', yang_name="state", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) self.__config = YANGDynClass(base=yc_config_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_ip_config, is_container='container', yang_name="config", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) @@ -2186,7 +2144,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'acl-sets', u'acl-set', u'acl-entries', u'acl-entry', u'ip'] + return ['acl', 'acl-sets', 'acl-set', 'acl-entries', 'acl-entry', 'ip'] def _get_config(self): """ @@ -2261,8 +2219,8 @@ def _set_state(self, v, load=False): def _unset_state(self): self.__state = YANGDynClass(base=yc_state_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_ip_state, is_container='container', yang_name="state", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) - config = __builtin__.property(_get_config, _set_config) - state = __builtin__.property(_get_state, _set_state) + config = builtins.property(_get_config, _set_config) + state = builtins.property(_get_state, _set_state) _pyangbind_elements = {'config': config, 'state': state, } @@ -2279,18 +2237,14 @@ class yc_config_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_trans """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__source_port','__destination_port','__tcp_flags',) - _yang_name = 'config' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'config' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False - self.__source_port = YANGDynClass(base=[RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': [u'0..65535']}),RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'ANY': {}},),], is_leaf=True, yang_name="source-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=True) - self.__tcp_flags = YANGDynClass(base=TypedListType(allowed_type=RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'TCP_FIN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_ACK': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_URG': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_RST': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_SYN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_ECE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_ACK': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_SYN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_CWR': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_CWR': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_URG': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_RST': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_FIN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_ECE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_PSH': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_PSH': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}},)), is_leaf=False, yang_name="tcp-flags", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=True) - self.__destination_port = YANGDynClass(base=[RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': [u'0..65535']}),RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'ANY': {}},),], is_leaf=True, yang_name="destination-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=True) + self.__source_port = YANGDynClass(base=[RestrictedClassType(base_type=str, restriction_dict={'pattern': '^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': ['0..65535']}),RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'ANY': {}},),], is_leaf=True, yang_name="source-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=True) + self.__tcp_flags = YANGDynClass(base=TypedListType(allowed_type=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'TCP_FIN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_ACK': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_URG': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_RST': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_SYN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_ECE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_ACK': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_SYN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_CWR': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_CWR': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_URG': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_RST': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_FIN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_ECE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_PSH': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_PSH': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}},)), is_leaf=False, yang_name="tcp-flags", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=True) + self.__destination_port = YANGDynClass(base=[RestrictedClassType(base_type=str, restriction_dict={'pattern': '^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': ['0..65535']}),RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'ANY': {}},),], is_leaf=True, yang_name="destination-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=True) load = kwargs.pop("load", None) if args: @@ -2317,7 +2271,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'acl-sets', u'acl-set', u'acl-entries', u'acl-entry', u'transport', u'config'] + return ['acl', 'acl-sets', 'acl-set', 'acl-entries', 'acl-entry', 'transport', 'config'] def _get_source_port(self): """ @@ -2340,12 +2294,12 @@ def _set_source_port(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=[RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': [u'0..65535']}),RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'ANY': {}},),], is_leaf=True, yang_name="source-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=True) + t = YANGDynClass(v,base=[RestrictedClassType(base_type=str, restriction_dict={'pattern': '^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': ['0..65535']}),RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'ANY': {}},),], is_leaf=True, yang_name="source-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """source_port must be of a type compatible with oc-pkt-match-types:port-num-range""", 'defined-type': "oc-pkt-match-types:port-num-range", - 'generated-type': """YANGDynClass(base=[RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': [u'0..65535']}),RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'ANY': {}},),], is_leaf=True, yang_name="source-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=True)""", + 'generated-type': """YANGDynClass(base=[RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': [u'0..65535']}),RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'ANY': {}},),], is_leaf=True, yang_name="source-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=True)""", }) self.__source_port = t @@ -2353,7 +2307,7 @@ def _set_source_port(self, v, load=False): self._set() def _unset_source_port(self): - self.__source_port = YANGDynClass(base=[RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': [u'0..65535']}),RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'ANY': {}},),], is_leaf=True, yang_name="source-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=True) + self.__source_port = YANGDynClass(base=[RestrictedClassType(base_type=str, restriction_dict={'pattern': '^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': ['0..65535']}),RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'ANY': {}},),], is_leaf=True, yang_name="source-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=True) def _get_destination_port(self): @@ -2377,12 +2331,12 @@ def _set_destination_port(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=[RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': [u'0..65535']}),RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'ANY': {}},),], is_leaf=True, yang_name="destination-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=True) + t = YANGDynClass(v,base=[RestrictedClassType(base_type=str, restriction_dict={'pattern': '^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': ['0..65535']}),RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'ANY': {}},),], is_leaf=True, yang_name="destination-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """destination_port must be of a type compatible with oc-pkt-match-types:port-num-range""", 'defined-type': "oc-pkt-match-types:port-num-range", - 'generated-type': """YANGDynClass(base=[RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': [u'0..65535']}),RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'ANY': {}},),], is_leaf=True, yang_name="destination-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=True)""", + 'generated-type': """YANGDynClass(base=[RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': [u'0..65535']}),RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'ANY': {}},),], is_leaf=True, yang_name="destination-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=True)""", }) self.__destination_port = t @@ -2390,7 +2344,7 @@ def _set_destination_port(self, v, load=False): self._set() def _unset_destination_port(self): - self.__destination_port = YANGDynClass(base=[RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': [u'0..65535']}),RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'ANY': {}},),], is_leaf=True, yang_name="destination-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=True) + self.__destination_port = YANGDynClass(base=[RestrictedClassType(base_type=str, restriction_dict={'pattern': '^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': ['0..65535']}),RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'ANY': {}},),], is_leaf=True, yang_name="destination-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=True) def _get_tcp_flags(self): @@ -2414,7 +2368,7 @@ def _set_tcp_flags(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=TypedListType(allowed_type=RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'TCP_FIN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_ACK': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_URG': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_RST': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_SYN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_ECE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_ACK': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_SYN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_CWR': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_CWR': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_URG': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_RST': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_FIN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_ECE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_PSH': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_PSH': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}},)), is_leaf=False, yang_name="tcp-flags", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=True) + t = YANGDynClass(v,base=TypedListType(allowed_type=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'TCP_FIN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_ACK': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_URG': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_RST': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_SYN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_ECE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_ACK': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_SYN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_CWR': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_CWR': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_URG': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_RST': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_FIN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_ECE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_PSH': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_PSH': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}},)), is_leaf=False, yang_name="tcp-flags", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """tcp_flags must be of a type compatible with identityref""", @@ -2427,11 +2381,11 @@ def _set_tcp_flags(self, v, load=False): self._set() def _unset_tcp_flags(self): - self.__tcp_flags = YANGDynClass(base=TypedListType(allowed_type=RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'TCP_FIN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_ACK': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_URG': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_RST': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_SYN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_ECE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_ACK': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_SYN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_CWR': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_CWR': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_URG': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_RST': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_FIN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_ECE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_PSH': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_PSH': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}},)), is_leaf=False, yang_name="tcp-flags", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=True) + self.__tcp_flags = YANGDynClass(base=TypedListType(allowed_type=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'TCP_FIN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_ACK': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_URG': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_RST': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_SYN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_ECE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_ACK': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_SYN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_CWR': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_CWR': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_URG': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_RST': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_FIN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_ECE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_PSH': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_PSH': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}},)), is_leaf=False, yang_name="tcp-flags", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=True) - source_port = __builtin__.property(_get_source_port, _set_source_port) - destination_port = __builtin__.property(_get_destination_port, _set_destination_port) - tcp_flags = __builtin__.property(_get_tcp_flags, _set_tcp_flags) + source_port = builtins.property(_get_source_port, _set_source_port) + destination_port = builtins.property(_get_destination_port, _set_destination_port) + tcp_flags = builtins.property(_get_tcp_flags, _set_tcp_flags) _pyangbind_elements = {'source_port': source_port, 'destination_port': destination_port, 'tcp_flags': tcp_flags, } @@ -2448,18 +2402,14 @@ class yc_state_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_transp """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__source_port','__destination_port','__tcp_flags',) - _yang_name = 'state' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'state' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False - self.__source_port = YANGDynClass(base=[RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': [u'0..65535']}),RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'ANY': {}},),], is_leaf=True, yang_name="source-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=False) - self.__tcp_flags = YANGDynClass(base=TypedListType(allowed_type=RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'TCP_FIN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_ACK': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_URG': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_RST': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_SYN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_ECE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_ACK': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_SYN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_CWR': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_CWR': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_URG': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_RST': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_FIN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_ECE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_PSH': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_PSH': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}},)), is_leaf=False, yang_name="tcp-flags", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=False) - self.__destination_port = YANGDynClass(base=[RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': [u'0..65535']}),RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'ANY': {}},),], is_leaf=True, yang_name="destination-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=False) + self.__source_port = YANGDynClass(base=[RestrictedClassType(base_type=str, restriction_dict={'pattern': '^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': ['0..65535']}),RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'ANY': {}},),], is_leaf=True, yang_name="source-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=False) + self.__tcp_flags = YANGDynClass(base=TypedListType(allowed_type=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'TCP_FIN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_ACK': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_URG': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_RST': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_SYN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_ECE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_ACK': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_SYN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_CWR': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_CWR': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_URG': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_RST': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_FIN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_ECE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_PSH': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_PSH': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}},)), is_leaf=False, yang_name="tcp-flags", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=False) + self.__destination_port = YANGDynClass(base=[RestrictedClassType(base_type=str, restriction_dict={'pattern': '^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': ['0..65535']}),RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'ANY': {}},),], is_leaf=True, yang_name="destination-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=False) load = kwargs.pop("load", None) if args: @@ -2486,7 +2436,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'acl-sets', u'acl-set', u'acl-entries', u'acl-entry', u'transport', u'state'] + return ['acl', 'acl-sets', 'acl-set', 'acl-entries', 'acl-entry', 'transport', 'state'] def _get_source_port(self): """ @@ -2509,12 +2459,12 @@ def _set_source_port(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=[RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': [u'0..65535']}),RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'ANY': {}},),], is_leaf=True, yang_name="source-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=False) + t = YANGDynClass(v,base=[RestrictedClassType(base_type=str, restriction_dict={'pattern': '^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': ['0..65535']}),RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'ANY': {}},),], is_leaf=True, yang_name="source-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """source_port must be of a type compatible with oc-pkt-match-types:port-num-range""", 'defined-type': "oc-pkt-match-types:port-num-range", - 'generated-type': """YANGDynClass(base=[RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': [u'0..65535']}),RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'ANY': {}},),], is_leaf=True, yang_name="source-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=False)""", + 'generated-type': """YANGDynClass(base=[RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': [u'0..65535']}),RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'ANY': {}},),], is_leaf=True, yang_name="source-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=False)""", }) self.__source_port = t @@ -2522,7 +2472,7 @@ def _set_source_port(self, v, load=False): self._set() def _unset_source_port(self): - self.__source_port = YANGDynClass(base=[RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': [u'0..65535']}),RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'ANY': {}},),], is_leaf=True, yang_name="source-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=False) + self.__source_port = YANGDynClass(base=[RestrictedClassType(base_type=str, restriction_dict={'pattern': '^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': ['0..65535']}),RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'ANY': {}},),], is_leaf=True, yang_name="source-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=False) def _get_destination_port(self): @@ -2546,12 +2496,12 @@ def _set_destination_port(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=[RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': [u'0..65535']}),RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'ANY': {}},),], is_leaf=True, yang_name="destination-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=False) + t = YANGDynClass(v,base=[RestrictedClassType(base_type=str, restriction_dict={'pattern': '^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': ['0..65535']}),RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'ANY': {}},),], is_leaf=True, yang_name="destination-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """destination_port must be of a type compatible with oc-pkt-match-types:port-num-range""", 'defined-type': "oc-pkt-match-types:port-num-range", - 'generated-type': """YANGDynClass(base=[RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': [u'0..65535']}),RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'ANY': {}},),], is_leaf=True, yang_name="destination-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=False)""", + 'generated-type': """YANGDynClass(base=[RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': [u'0..65535']}),RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'ANY': {}},),], is_leaf=True, yang_name="destination-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=False)""", }) self.__destination_port = t @@ -2559,7 +2509,7 @@ def _set_destination_port(self, v, load=False): self._set() def _unset_destination_port(self): - self.__destination_port = YANGDynClass(base=[RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': [u'0..65535']}),RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'ANY': {}},),], is_leaf=True, yang_name="destination-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=False) + self.__destination_port = YANGDynClass(base=[RestrictedClassType(base_type=str, restriction_dict={'pattern': '^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)\\.\\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?[0-9]?)$'}),RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': ['0..65535']}),RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'ANY': {}},),], is_leaf=True, yang_name="destination-port", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-pkt-match-types:port-num-range', is_config=False) def _get_tcp_flags(self): @@ -2583,7 +2533,7 @@ def _set_tcp_flags(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=TypedListType(allowed_type=RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'TCP_FIN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_ACK': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_URG': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_RST': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_SYN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_ECE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_ACK': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_SYN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_CWR': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_CWR': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_URG': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_RST': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_FIN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_ECE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_PSH': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_PSH': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}},)), is_leaf=False, yang_name="tcp-flags", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=False) + t = YANGDynClass(v,base=TypedListType(allowed_type=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'TCP_FIN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_ACK': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_URG': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_RST': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_SYN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_ECE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_ACK': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_SYN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_CWR': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_CWR': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_URG': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_RST': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_FIN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_ECE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_PSH': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_PSH': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}},)), is_leaf=False, yang_name="tcp-flags", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """tcp_flags must be of a type compatible with identityref""", @@ -2596,11 +2546,11 @@ def _set_tcp_flags(self, v, load=False): self._set() def _unset_tcp_flags(self): - self.__tcp_flags = YANGDynClass(base=TypedListType(allowed_type=RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'TCP_FIN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_ACK': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_URG': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_RST': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_SYN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_ECE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_ACK': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_SYN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_CWR': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_CWR': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_URG': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_RST': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_FIN': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_ECE': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'TCP_PSH': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}, u'oc-pkt-match-types:TCP_PSH': {'@namespace': u'http://openconfig.net/yang/packet-match-types', '@module': u'openconfig-packet-match-types'}},)), is_leaf=False, yang_name="tcp-flags", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=False) + self.__tcp_flags = YANGDynClass(base=TypedListType(allowed_type=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'TCP_FIN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_ACK': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_URG': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_RST': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_SYN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_ECE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_ACK': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_SYN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_CWR': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_CWR': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_URG': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_RST': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_FIN': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_ECE': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'TCP_PSH': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}, 'oc-pkt-match-types:TCP_PSH': {'@namespace': 'http://openconfig.net/yang/packet-match-types', '@module': 'openconfig-packet-match-types'}},)), is_leaf=False, yang_name="tcp-flags", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=False) - source_port = __builtin__.property(_get_source_port) - destination_port = __builtin__.property(_get_destination_port) - tcp_flags = __builtin__.property(_get_tcp_flags) + source_port = builtins.property(_get_source_port) + destination_port = builtins.property(_get_destination_port) + tcp_flags = builtins.property(_get_tcp_flags) _pyangbind_elements = {'source_port': source_port, 'destination_port': destination_port, 'tcp_flags': tcp_flags, } @@ -2617,14 +2567,10 @@ class yc_transport_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_tr """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__config','__state',) - _yang_name = 'transport' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'transport' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__state = YANGDynClass(base=yc_state_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_transport_state, is_container='container', yang_name="state", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) self.__config = YANGDynClass(base=yc_config_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_transport_config, is_container='container', yang_name="config", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) @@ -2654,7 +2600,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'acl-sets', u'acl-set', u'acl-entries', u'acl-entry', u'transport'] + return ['acl', 'acl-sets', 'acl-set', 'acl-entries', 'acl-entry', 'transport'] def _get_config(self): """ @@ -2729,8 +2675,8 @@ def _set_state(self, v, load=False): def _unset_state(self): self.__state = YANGDynClass(base=yc_state_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_transport_state, is_container='container', yang_name="state", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) - config = __builtin__.property(_get_config, _set_config) - state = __builtin__.property(_get_state, _set_state) + config = builtins.property(_get_config, _set_config) + state = builtins.property(_get_state, _set_state) _pyangbind_elements = {'config': config, 'state': state, } @@ -2747,17 +2693,13 @@ class yc_config_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_input """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__interface','__subinterface',) - _yang_name = 'config' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'config' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False - self.__interface = YANGDynClass(base=unicode, is_leaf=True, yang_name="interface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) - self.__subinterface = YANGDynClass(base=unicode, is_leaf=True, yang_name="subinterface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) + self.__interface = YANGDynClass(base=str, is_leaf=True, yang_name="interface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) + self.__subinterface = YANGDynClass(base=str, is_leaf=True, yang_name="subinterface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) load = kwargs.pop("load", None) if args: @@ -2784,7 +2726,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'acl-sets', u'acl-set', u'acl-entries', u'acl-entry', u'input-interface', u'interface-ref', u'config'] + return ['acl', 'acl-sets', 'acl-set', 'acl-entries', 'acl-entry', 'input-interface', 'interface-ref', 'config'] def _get_interface(self): """ @@ -2811,7 +2753,7 @@ def _set_interface(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=unicode, is_leaf=True, yang_name="interface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) + t = YANGDynClass(v,base=str, is_leaf=True, yang_name="interface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """interface must be of a type compatible with leafref""", @@ -2824,7 +2766,7 @@ def _set_interface(self, v, load=False): self._set() def _unset_interface(self): - self.__interface = YANGDynClass(base=unicode, is_leaf=True, yang_name="interface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) + self.__interface = YANGDynClass(base=str, is_leaf=True, yang_name="interface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) def _get_subinterface(self): @@ -2854,7 +2796,7 @@ def _set_subinterface(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=unicode, is_leaf=True, yang_name="subinterface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) + t = YANGDynClass(v,base=str, is_leaf=True, yang_name="subinterface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """subinterface must be of a type compatible with leafref""", @@ -2867,10 +2809,10 @@ def _set_subinterface(self, v, load=False): self._set() def _unset_subinterface(self): - self.__subinterface = YANGDynClass(base=unicode, is_leaf=True, yang_name="subinterface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) + self.__subinterface = YANGDynClass(base=str, is_leaf=True, yang_name="subinterface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) - interface = __builtin__.property(_get_interface, _set_interface) - subinterface = __builtin__.property(_get_subinterface, _set_subinterface) + interface = builtins.property(_get_interface, _set_interface) + subinterface = builtins.property(_get_subinterface, _set_subinterface) _pyangbind_elements = {'interface': interface, 'subinterface': subinterface, } @@ -2887,17 +2829,13 @@ class yc_state_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_input_ """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__interface','__subinterface',) - _yang_name = 'state' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'state' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False - self.__interface = YANGDynClass(base=unicode, is_leaf=True, yang_name="interface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) - self.__subinterface = YANGDynClass(base=unicode, is_leaf=True, yang_name="subinterface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) + self.__interface = YANGDynClass(base=str, is_leaf=True, yang_name="interface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) + self.__subinterface = YANGDynClass(base=str, is_leaf=True, yang_name="subinterface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) load = kwargs.pop("load", None) if args: @@ -2924,7 +2862,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'acl-sets', u'acl-set', u'acl-entries', u'acl-entry', u'input-interface', u'interface-ref', u'state'] + return ['acl', 'acl-sets', 'acl-set', 'acl-entries', 'acl-entry', 'input-interface', 'interface-ref', 'state'] def _get_interface(self): """ @@ -2951,7 +2889,7 @@ def _set_interface(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=unicode, is_leaf=True, yang_name="interface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) + t = YANGDynClass(v,base=str, is_leaf=True, yang_name="interface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """interface must be of a type compatible with leafref""", @@ -2964,7 +2902,7 @@ def _set_interface(self, v, load=False): self._set() def _unset_interface(self): - self.__interface = YANGDynClass(base=unicode, is_leaf=True, yang_name="interface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) + self.__interface = YANGDynClass(base=str, is_leaf=True, yang_name="interface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) def _get_subinterface(self): @@ -2994,7 +2932,7 @@ def _set_subinterface(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=unicode, is_leaf=True, yang_name="subinterface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) + t = YANGDynClass(v,base=str, is_leaf=True, yang_name="subinterface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """subinterface must be of a type compatible with leafref""", @@ -3007,10 +2945,10 @@ def _set_subinterface(self, v, load=False): self._set() def _unset_subinterface(self): - self.__subinterface = YANGDynClass(base=unicode, is_leaf=True, yang_name="subinterface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) + self.__subinterface = YANGDynClass(base=str, is_leaf=True, yang_name="subinterface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) - interface = __builtin__.property(_get_interface) - subinterface = __builtin__.property(_get_subinterface) + interface = builtins.property(_get_interface) + subinterface = builtins.property(_get_subinterface) _pyangbind_elements = {'interface': interface, 'subinterface': subinterface, } @@ -3027,14 +2965,10 @@ class yc_interface_ref_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entr """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__config','__state',) - _yang_name = 'interface-ref' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'interface-ref' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__state = YANGDynClass(base=yc_state_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_input_interface_interface_ref_state, is_container='container', yang_name="state", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) self.__config = YANGDynClass(base=yc_config_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_input_interface_interface_ref_config, is_container='container', yang_name="config", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) @@ -3064,7 +2998,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'acl-sets', u'acl-set', u'acl-entries', u'acl-entry', u'input-interface', u'interface-ref'] + return ['acl', 'acl-sets', 'acl-set', 'acl-entries', 'acl-entry', 'input-interface', 'interface-ref'] def _get_config(self): """ @@ -3139,8 +3073,8 @@ def _set_state(self, v, load=False): def _unset_state(self): self.__state = YANGDynClass(base=yc_state_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_input_interface_interface_ref_state, is_container='container', yang_name="state", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) - config = __builtin__.property(_get_config, _set_config) - state = __builtin__.property(_get_state, _set_state) + config = builtins.property(_get_config, _set_config) + state = builtins.property(_get_state, _set_state) _pyangbind_elements = {'config': config, 'state': state, } @@ -3157,14 +3091,10 @@ class yc_input_interface_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_en """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__interface_ref',) - _yang_name = 'input-interface' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'input-interface' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__interface_ref = YANGDynClass(base=yc_interface_ref_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_input_interface_interface_ref, is_container='container', yang_name="interface-ref", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) @@ -3193,7 +3123,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'acl-sets', u'acl-set', u'acl-entries', u'acl-entry', u'input-interface'] + return ['acl', 'acl-sets', 'acl-set', 'acl-entries', 'acl-entry', 'input-interface'] def _get_interface_ref(self): """ @@ -3231,7 +3161,7 @@ def _set_interface_ref(self, v, load=False): def _unset_interface_ref(self): self.__interface_ref = YANGDynClass(base=yc_interface_ref_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_input_interface_interface_ref, is_container='container', yang_name="interface-ref", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) - interface_ref = __builtin__.property(_get_interface_ref, _set_interface_ref) + interface_ref = builtins.property(_get_interface_ref, _set_interface_ref) _pyangbind_elements = {'interface_ref': interface_ref, } @@ -3248,17 +3178,13 @@ class yc_config_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_actio """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__forwarding_action','__log_action',) - _yang_name = 'config' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'config' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False - self.__forwarding_action = YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'DROP': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:REJECT': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'ACCEPT': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'REJECT': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:ACCEPT': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:DROP': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}},), is_leaf=True, yang_name="forwarding-action", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=True) - self.__log_action = YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'LOG_SYSLOG': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:LOG_SYSLOG': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'LOG_NONE': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:LOG_NONE': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}},), default=unicode("LOG_NONE"), is_leaf=True, yang_name="log-action", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=True) + self.__forwarding_action = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'DROP': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:REJECT': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'ACCEPT': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'REJECT': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:ACCEPT': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:DROP': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}},), is_leaf=True, yang_name="forwarding-action", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=True) + self.__log_action = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'LOG_SYSLOG': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:LOG_SYSLOG': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'LOG_NONE': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:LOG_NONE': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}},), default=str("LOG_NONE"), is_leaf=True, yang_name="log-action", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=True) load = kwargs.pop("load", None) if args: @@ -3285,7 +3211,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'acl-sets', u'acl-set', u'acl-entries', u'acl-entry', u'actions', u'config'] + return ['acl', 'acl-sets', 'acl-set', 'acl-entries', 'acl-entry', 'actions', 'config'] def _get_forwarding_action(self): """ @@ -3310,7 +3236,7 @@ def _set_forwarding_action(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'DROP': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:REJECT': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'ACCEPT': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'REJECT': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:ACCEPT': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:DROP': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}},), is_leaf=True, yang_name="forwarding-action", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=True) + t = YANGDynClass(v,base=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'DROP': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:REJECT': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'ACCEPT': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'REJECT': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:ACCEPT': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:DROP': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}},), is_leaf=True, yang_name="forwarding-action", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """forwarding_action must be of a type compatible with identityref""", @@ -3323,7 +3249,7 @@ def _set_forwarding_action(self, v, load=False): self._set() def _unset_forwarding_action(self): - self.__forwarding_action = YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'DROP': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:REJECT': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'ACCEPT': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'REJECT': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:ACCEPT': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:DROP': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}},), is_leaf=True, yang_name="forwarding-action", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=True) + self.__forwarding_action = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'DROP': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:REJECT': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'ACCEPT': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'REJECT': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:ACCEPT': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:DROP': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}},), is_leaf=True, yang_name="forwarding-action", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=True) def _get_log_action(self): @@ -3351,7 +3277,7 @@ def _set_log_action(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'LOG_SYSLOG': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:LOG_SYSLOG': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'LOG_NONE': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:LOG_NONE': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}},), default=unicode("LOG_NONE"), is_leaf=True, yang_name="log-action", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=True) + t = YANGDynClass(v,base=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'LOG_SYSLOG': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:LOG_SYSLOG': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'LOG_NONE': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:LOG_NONE': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}},), default=str("LOG_NONE"), is_leaf=True, yang_name="log-action", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """log_action must be of a type compatible with identityref""", @@ -3364,10 +3290,10 @@ def _set_log_action(self, v, load=False): self._set() def _unset_log_action(self): - self.__log_action = YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'LOG_SYSLOG': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:LOG_SYSLOG': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'LOG_NONE': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:LOG_NONE': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}},), default=unicode("LOG_NONE"), is_leaf=True, yang_name="log-action", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=True) + self.__log_action = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'LOG_SYSLOG': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:LOG_SYSLOG': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'LOG_NONE': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:LOG_NONE': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}},), default=str("LOG_NONE"), is_leaf=True, yang_name="log-action", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=True) - forwarding_action = __builtin__.property(_get_forwarding_action, _set_forwarding_action) - log_action = __builtin__.property(_get_log_action, _set_log_action) + forwarding_action = builtins.property(_get_forwarding_action, _set_forwarding_action) + log_action = builtins.property(_get_log_action, _set_log_action) _pyangbind_elements = {'forwarding_action': forwarding_action, 'log_action': log_action, } @@ -3384,17 +3310,13 @@ class yc_state_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_action """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__forwarding_action','__log_action',) - _yang_name = 'state' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'state' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False - self.__forwarding_action = YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'DROP': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:REJECT': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'ACCEPT': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'REJECT': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:ACCEPT': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:DROP': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}},), is_leaf=True, yang_name="forwarding-action", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=False) - self.__log_action = YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'LOG_SYSLOG': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:LOG_SYSLOG': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'LOG_NONE': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:LOG_NONE': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}},), default=unicode("LOG_NONE"), is_leaf=True, yang_name="log-action", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=False) + self.__forwarding_action = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'DROP': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:REJECT': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'ACCEPT': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'REJECT': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:ACCEPT': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:DROP': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}},), is_leaf=True, yang_name="forwarding-action", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=False) + self.__log_action = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'LOG_SYSLOG': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:LOG_SYSLOG': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'LOG_NONE': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:LOG_NONE': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}},), default=str("LOG_NONE"), is_leaf=True, yang_name="log-action", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=False) load = kwargs.pop("load", None) if args: @@ -3421,7 +3343,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'acl-sets', u'acl-set', u'acl-entries', u'acl-entry', u'actions', u'state'] + return ['acl', 'acl-sets', 'acl-set', 'acl-entries', 'acl-entry', 'actions', 'state'] def _get_forwarding_action(self): """ @@ -3446,7 +3368,7 @@ def _set_forwarding_action(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'DROP': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:REJECT': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'ACCEPT': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'REJECT': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:ACCEPT': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:DROP': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}},), is_leaf=True, yang_name="forwarding-action", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=False) + t = YANGDynClass(v,base=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'DROP': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:REJECT': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'ACCEPT': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'REJECT': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:ACCEPT': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:DROP': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}},), is_leaf=True, yang_name="forwarding-action", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """forwarding_action must be of a type compatible with identityref""", @@ -3459,7 +3381,7 @@ def _set_forwarding_action(self, v, load=False): self._set() def _unset_forwarding_action(self): - self.__forwarding_action = YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'DROP': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:REJECT': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'ACCEPT': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'REJECT': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:ACCEPT': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:DROP': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}},), is_leaf=True, yang_name="forwarding-action", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=False) + self.__forwarding_action = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'DROP': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:REJECT': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'ACCEPT': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'REJECT': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:ACCEPT': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:DROP': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}},), is_leaf=True, yang_name="forwarding-action", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=False) def _get_log_action(self): @@ -3487,7 +3409,7 @@ def _set_log_action(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'LOG_SYSLOG': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:LOG_SYSLOG': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'LOG_NONE': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:LOG_NONE': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}},), default=unicode("LOG_NONE"), is_leaf=True, yang_name="log-action", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=False) + t = YANGDynClass(v,base=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'LOG_SYSLOG': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:LOG_SYSLOG': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'LOG_NONE': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:LOG_NONE': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}},), default=str("LOG_NONE"), is_leaf=True, yang_name="log-action", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """log_action must be of a type compatible with identityref""", @@ -3500,10 +3422,10 @@ def _set_log_action(self, v, load=False): self._set() def _unset_log_action(self): - self.__log_action = YANGDynClass(base=RestrictedClassType(base_type=unicode, restriction_type="dict_key", restriction_arg={u'LOG_SYSLOG': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:LOG_SYSLOG': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'LOG_NONE': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}, u'oc-acl:LOG_NONE': {'@namespace': u'http://openconfig.net/yang/acl', '@module': u'openconfig-acl'}},), default=unicode("LOG_NONE"), is_leaf=True, yang_name="log-action", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=False) + self.__log_action = YANGDynClass(base=RestrictedClassType(base_type=str, restriction_type="dict_key", restriction_arg={'LOG_SYSLOG': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:LOG_SYSLOG': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'LOG_NONE': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}, 'oc-acl:LOG_NONE': {'@namespace': 'http://openconfig.net/yang/acl', '@module': 'openconfig-acl'}},), default=str("LOG_NONE"), is_leaf=True, yang_name="log-action", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='identityref', is_config=False) - forwarding_action = __builtin__.property(_get_forwarding_action) - log_action = __builtin__.property(_get_log_action) + forwarding_action = builtins.property(_get_forwarding_action) + log_action = builtins.property(_get_log_action) _pyangbind_elements = {'forwarding_action': forwarding_action, 'log_action': log_action, } @@ -3521,14 +3443,10 @@ class yc_actions_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_acti """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__config','__state',) - _yang_name = 'actions' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'actions' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__state = YANGDynClass(base=yc_state_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_actions_state, is_container='container', yang_name="state", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) self.__config = YANGDynClass(base=yc_config_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_actions_config, is_container='container', yang_name="config", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) @@ -3558,7 +3476,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'acl-sets', u'acl-set', u'acl-entries', u'acl-entry', u'actions'] + return ['acl', 'acl-sets', 'acl-set', 'acl-entries', 'acl-entry', 'actions'] def _get_config(self): """ @@ -3633,8 +3551,8 @@ def _set_state(self, v, load=False): def _unset_state(self): self.__state = YANGDynClass(base=yc_state_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_actions_state, is_container='container', yang_name="state", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) - config = __builtin__.property(_get_config, _set_config) - state = __builtin__.property(_get_state, _set_state) + config = builtins.property(_get_config, _set_config) + state = builtins.property(_get_state, _set_state) _pyangbind_elements = {'config': config, 'state': state, } @@ -3651,20 +3569,16 @@ class yc_acl_entry_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry(Py """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__sequence_id','__config','__state','__l2','__ip','__transport','__input_interface','__actions',) - _yang_name = 'acl-entry' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'acl-entry' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__ip = YANGDynClass(base=yc_ip_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_ip, is_container='container', yang_name="ip", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) self.__input_interface = YANGDynClass(base=yc_input_interface_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_input_interface, is_container='container', yang_name="input-interface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) self.__state = YANGDynClass(base=yc_state_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_state, is_container='container', yang_name="state", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) self.__actions = YANGDynClass(base=yc_actions_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_actions, is_container='container', yang_name="actions", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) - self.__sequence_id = YANGDynClass(base=unicode, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) + self.__sequence_id = YANGDynClass(base=str, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) self.__l2 = YANGDynClass(base=yc_l2_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_l2, is_container='container', yang_name="l2", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) self.__config = YANGDynClass(base=yc_config_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_config, is_container='container', yang_name="config", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) self.__transport = YANGDynClass(base=yc_transport_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_transport, is_container='container', yang_name="transport", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) @@ -3694,7 +3608,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'acl-sets', u'acl-set', u'acl-entries', u'acl-entry'] + return ['acl', 'acl-sets', 'acl-set', 'acl-entries', 'acl-entry'] def _get_sequence_id(self): """ @@ -3722,7 +3636,7 @@ def _set_sequence_id(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=unicode, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) + t = YANGDynClass(v,base=str, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """sequence_id must be of a type compatible with leafref""", @@ -3735,7 +3649,7 @@ def _set_sequence_id(self, v, load=False): self._set() def _unset_sequence_id(self): - self.__sequence_id = YANGDynClass(base=unicode, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) + self.__sequence_id = YANGDynClass(base=str, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) def _get_config(self): @@ -3998,14 +3912,14 @@ def _set_actions(self, v, load=False): def _unset_actions(self): self.__actions = YANGDynClass(base=yc_actions_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry_actions, is_container='container', yang_name="actions", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) - sequence_id = __builtin__.property(_get_sequence_id, _set_sequence_id) - config = __builtin__.property(_get_config, _set_config) - state = __builtin__.property(_get_state, _set_state) - l2 = __builtin__.property(_get_l2, _set_l2) - ip = __builtin__.property(_get_ip, _set_ip) - transport = __builtin__.property(_get_transport, _set_transport) - input_interface = __builtin__.property(_get_input_interface, _set_input_interface) - actions = __builtin__.property(_get_actions, _set_actions) + sequence_id = builtins.property(_get_sequence_id, _set_sequence_id) + config = builtins.property(_get_config, _set_config) + state = builtins.property(_get_state, _set_state) + l2 = builtins.property(_get_l2, _set_l2) + ip = builtins.property(_get_ip, _set_ip) + transport = builtins.property(_get_transport, _set_transport) + input_interface = builtins.property(_get_input_interface, _set_input_interface) + actions = builtins.property(_get_actions, _set_actions) _pyangbind_elements = {'sequence_id': sequence_id, 'config': config, 'state': state, 'l2': l2, 'ip': ip, 'transport': transport, 'input_interface': input_interface, 'actions': actions, } @@ -4022,14 +3936,10 @@ class yc_acl_entries_openconfig_acl__acl_acl_sets_acl_set_acl_entries(PybindBase """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__acl_entry',) - _yang_name = 'acl-entries' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'acl-entries' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__acl_entry = YANGDynClass(base=YANGListType("sequence_id",yc_acl_entry_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry, yang_name="acl-entry", parent=self, is_container='list', user_ordered=False, path_helper=self._path_helper, yang_keys='sequence-id', extensions=None), is_container='list', yang_name="acl-entry", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='list', is_config=True) @@ -4058,7 +3968,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'acl-sets', u'acl-set', u'acl-entries'] + return ['acl', 'acl-sets', 'acl-set', 'acl-entries'] def _get_acl_entry(self): """ @@ -4096,7 +4006,7 @@ def _set_acl_entry(self, v, load=False): def _unset_acl_entry(self): self.__acl_entry = YANGDynClass(base=YANGListType("sequence_id",yc_acl_entry_openconfig_acl__acl_acl_sets_acl_set_acl_entries_acl_entry, yang_name="acl-entry", parent=self, is_container='list', user_ordered=False, path_helper=self._path_helper, yang_keys='sequence-id', extensions=None), is_container='list', yang_name="acl-entry", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='list', is_config=True) - acl_entry = __builtin__.property(_get_acl_entry, _set_acl_entry) + acl_entry = builtins.property(_get_acl_entry, _set_acl_entry) _pyangbind_elements = {'acl_entry': acl_entry, } @@ -4114,18 +4024,14 @@ class yc_acl_set_openconfig_acl__acl_acl_sets_acl_set(PybindBase): """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__name','__config','__state','__acl_entries',) - _yang_name = 'acl-set' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'acl-set' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__state = YANGDynClass(base=yc_state_openconfig_acl__acl_acl_sets_acl_set_state, is_container='container', yang_name="state", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) self.__config = YANGDynClass(base=yc_config_openconfig_acl__acl_acl_sets_acl_set_config, is_container='container', yang_name="config", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) - self.__name = YANGDynClass(base=unicode, is_leaf=True, yang_name="name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) + self.__name = YANGDynClass(base=str, is_leaf=True, yang_name="name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) self.__acl_entries = YANGDynClass(base=yc_acl_entries_openconfig_acl__acl_acl_sets_acl_set_acl_entries, is_container='container', yang_name="acl-entries", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) load = kwargs.pop("load", None) @@ -4153,7 +4059,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'acl-sets', u'acl-set'] + return ['acl', 'acl-sets', 'acl-set'] def _get_name(self): """ @@ -4181,7 +4087,7 @@ def _set_name(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=unicode, is_leaf=True, yang_name="name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) + t = YANGDynClass(v,base=str, is_leaf=True, yang_name="name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """name must be of a type compatible with leafref""", @@ -4194,7 +4100,7 @@ def _set_name(self, v, load=False): self._set() def _unset_name(self): - self.__name = YANGDynClass(base=unicode, is_leaf=True, yang_name="name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) + self.__name = YANGDynClass(base=str, is_leaf=True, yang_name="name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) def _get_config(self): @@ -4307,10 +4213,10 @@ def _set_acl_entries(self, v, load=False): def _unset_acl_entries(self): self.__acl_entries = YANGDynClass(base=yc_acl_entries_openconfig_acl__acl_acl_sets_acl_set_acl_entries, is_container='container', yang_name="acl-entries", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) - name = __builtin__.property(_get_name, _set_name) - config = __builtin__.property(_get_config, _set_config) - state = __builtin__.property(_get_state, _set_state) - acl_entries = __builtin__.property(_get_acl_entries, _set_acl_entries) + name = builtins.property(_get_name, _set_name) + config = builtins.property(_get_config, _set_config) + state = builtins.property(_get_state, _set_state) + acl_entries = builtins.property(_get_acl_entries, _set_acl_entries) _pyangbind_elements = {'name': name, 'config': config, 'state': state, 'acl_entries': acl_entries, } @@ -4327,14 +4233,10 @@ class yc_acl_sets_openconfig_acl__acl_acl_sets(PybindBase): """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__acl_set',) - _yang_name = 'acl-sets' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'acl-sets' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__acl_set = YANGDynClass(base=YANGListType("name",yc_acl_set_openconfig_acl__acl_acl_sets_acl_set, yang_name="acl-set", parent=self, is_container='list', user_ordered=False, path_helper=self._path_helper, yang_keys='name', extensions=None), is_container='list', yang_name="acl-set", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='list', is_config=True) @@ -4363,7 +4265,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'acl-sets'] + return ['acl', 'acl-sets'] def _get_acl_set(self): """ @@ -4403,7 +4305,7 @@ def _set_acl_set(self, v, load=False): def _unset_acl_set(self): self.__acl_set = YANGDynClass(base=YANGListType("name",yc_acl_set_openconfig_acl__acl_acl_sets_acl_set, yang_name="acl-set", parent=self, is_container='list', user_ordered=False, path_helper=self._path_helper, yang_keys='name', extensions=None), is_container='list', yang_name="acl-set", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='list', is_config=True) - acl_set = __builtin__.property(_get_acl_set, _set_acl_set) + acl_set = builtins.property(_get_acl_set, _set_acl_set) _pyangbind_elements = {'acl_set': acl_set, } @@ -4420,16 +4322,12 @@ class yc_config_openconfig_acl__acl_interfaces_interface_config(PybindBase): """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__id',) - _yang_name = 'config' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'config' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False - self.__id = YANGDynClass(base=unicode, is_leaf=True, yang_name="id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-if:interface-id', is_config=True) + self.__id = YANGDynClass(base=str, is_leaf=True, yang_name="id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-if:interface-id', is_config=True) load = kwargs.pop("load", None) if args: @@ -4456,7 +4354,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'interfaces', u'interface', u'config'] + return ['acl', 'interfaces', 'interface', 'config'] def _get_id(self): """ @@ -4481,7 +4379,7 @@ def _set_id(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=unicode, is_leaf=True, yang_name="id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-if:interface-id', is_config=True) + t = YANGDynClass(v,base=str, is_leaf=True, yang_name="id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-if:interface-id', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """id must be of a type compatible with oc-if:interface-id""", @@ -4494,9 +4392,9 @@ def _set_id(self, v, load=False): self._set() def _unset_id(self): - self.__id = YANGDynClass(base=unicode, is_leaf=True, yang_name="id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-if:interface-id', is_config=True) + self.__id = YANGDynClass(base=str, is_leaf=True, yang_name="id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-if:interface-id', is_config=True) - id = __builtin__.property(_get_id, _set_id) + id = builtins.property(_get_id, _set_id) _pyangbind_elements = {'id': id, } @@ -4513,16 +4411,12 @@ class yc_state_openconfig_acl__acl_interfaces_interface_state(PybindBase): """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__id',) - _yang_name = 'state' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'state' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False - self.__id = YANGDynClass(base=unicode, is_leaf=True, yang_name="id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-if:interface-id', is_config=False) + self.__id = YANGDynClass(base=str, is_leaf=True, yang_name="id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-if:interface-id', is_config=False) load = kwargs.pop("load", None) if args: @@ -4549,7 +4443,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'interfaces', u'interface', u'state'] + return ['acl', 'interfaces', 'interface', 'state'] def _get_id(self): """ @@ -4574,7 +4468,7 @@ def _set_id(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=unicode, is_leaf=True, yang_name="id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-if:interface-id', is_config=False) + t = YANGDynClass(v,base=str, is_leaf=True, yang_name="id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-if:interface-id', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """id must be of a type compatible with oc-if:interface-id""", @@ -4587,9 +4481,9 @@ def _set_id(self, v, load=False): self._set() def _unset_id(self): - self.__id = YANGDynClass(base=unicode, is_leaf=True, yang_name="id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-if:interface-id', is_config=False) + self.__id = YANGDynClass(base=str, is_leaf=True, yang_name="id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='oc-if:interface-id', is_config=False) - id = __builtin__.property(_get_id) + id = builtins.property(_get_id) _pyangbind_elements = {'id': id, } @@ -4606,17 +4500,13 @@ class yc_config_openconfig_acl__acl_interfaces_interface_interface_ref_config(Py """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__interface','__subinterface',) - _yang_name = 'config' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'config' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False - self.__interface = YANGDynClass(base=unicode, is_leaf=True, yang_name="interface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) - self.__subinterface = YANGDynClass(base=unicode, is_leaf=True, yang_name="subinterface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) + self.__interface = YANGDynClass(base=str, is_leaf=True, yang_name="interface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) + self.__subinterface = YANGDynClass(base=str, is_leaf=True, yang_name="subinterface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) load = kwargs.pop("load", None) if args: @@ -4643,7 +4533,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'interfaces', u'interface', u'interface-ref', u'config'] + return ['acl', 'interfaces', 'interface', 'interface-ref', 'config'] def _get_interface(self): """ @@ -4670,7 +4560,7 @@ def _set_interface(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=unicode, is_leaf=True, yang_name="interface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) + t = YANGDynClass(v,base=str, is_leaf=True, yang_name="interface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """interface must be of a type compatible with leafref""", @@ -4683,7 +4573,7 @@ def _set_interface(self, v, load=False): self._set() def _unset_interface(self): - self.__interface = YANGDynClass(base=unicode, is_leaf=True, yang_name="interface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) + self.__interface = YANGDynClass(base=str, is_leaf=True, yang_name="interface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) def _get_subinterface(self): @@ -4713,7 +4603,7 @@ def _set_subinterface(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=unicode, is_leaf=True, yang_name="subinterface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) + t = YANGDynClass(v,base=str, is_leaf=True, yang_name="subinterface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """subinterface must be of a type compatible with leafref""", @@ -4726,10 +4616,10 @@ def _set_subinterface(self, v, load=False): self._set() def _unset_subinterface(self): - self.__subinterface = YANGDynClass(base=unicode, is_leaf=True, yang_name="subinterface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) + self.__subinterface = YANGDynClass(base=str, is_leaf=True, yang_name="subinterface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) - interface = __builtin__.property(_get_interface, _set_interface) - subinterface = __builtin__.property(_get_subinterface, _set_subinterface) + interface = builtins.property(_get_interface, _set_interface) + subinterface = builtins.property(_get_subinterface, _set_subinterface) _pyangbind_elements = {'interface': interface, 'subinterface': subinterface, } @@ -4746,17 +4636,13 @@ class yc_state_openconfig_acl__acl_interfaces_interface_interface_ref_state(Pybi """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__interface','__subinterface',) - _yang_name = 'state' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'state' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False - self.__interface = YANGDynClass(base=unicode, is_leaf=True, yang_name="interface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) - self.__subinterface = YANGDynClass(base=unicode, is_leaf=True, yang_name="subinterface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) + self.__interface = YANGDynClass(base=str, is_leaf=True, yang_name="interface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) + self.__subinterface = YANGDynClass(base=str, is_leaf=True, yang_name="subinterface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) load = kwargs.pop("load", None) if args: @@ -4783,7 +4669,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'interfaces', u'interface', u'interface-ref', u'state'] + return ['acl', 'interfaces', 'interface', 'interface-ref', 'state'] def _get_interface(self): """ @@ -4810,7 +4696,7 @@ def _set_interface(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=unicode, is_leaf=True, yang_name="interface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) + t = YANGDynClass(v,base=str, is_leaf=True, yang_name="interface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """interface must be of a type compatible with leafref""", @@ -4823,7 +4709,7 @@ def _set_interface(self, v, load=False): self._set() def _unset_interface(self): - self.__interface = YANGDynClass(base=unicode, is_leaf=True, yang_name="interface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) + self.__interface = YANGDynClass(base=str, is_leaf=True, yang_name="interface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) def _get_subinterface(self): @@ -4853,7 +4739,7 @@ def _set_subinterface(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=unicode, is_leaf=True, yang_name="subinterface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) + t = YANGDynClass(v,base=str, is_leaf=True, yang_name="subinterface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """subinterface must be of a type compatible with leafref""", @@ -4866,10 +4752,10 @@ def _set_subinterface(self, v, load=False): self._set() def _unset_subinterface(self): - self.__subinterface = YANGDynClass(base=unicode, is_leaf=True, yang_name="subinterface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) + self.__subinterface = YANGDynClass(base=str, is_leaf=True, yang_name="subinterface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) - interface = __builtin__.property(_get_interface) - subinterface = __builtin__.property(_get_subinterface) + interface = builtins.property(_get_interface) + subinterface = builtins.property(_get_subinterface) _pyangbind_elements = {'interface': interface, 'subinterface': subinterface, } @@ -4886,14 +4772,10 @@ class yc_interface_ref_openconfig_acl__acl_interfaces_interface_interface_ref(Py """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__config','__state',) - _yang_name = 'interface-ref' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'interface-ref' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__state = YANGDynClass(base=yc_state_openconfig_acl__acl_interfaces_interface_interface_ref_state, is_container='container', yang_name="state", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) self.__config = YANGDynClass(base=yc_config_openconfig_acl__acl_interfaces_interface_interface_ref_config, is_container='container', yang_name="config", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) @@ -4923,7 +4805,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'interfaces', u'interface', u'interface-ref'] + return ['acl', 'interfaces', 'interface', 'interface-ref'] def _get_config(self): """ @@ -4998,8 +4880,8 @@ def _set_state(self, v, load=False): def _unset_state(self): self.__state = YANGDynClass(base=yc_state_openconfig_acl__acl_interfaces_interface_interface_ref_state, is_container='container', yang_name="state", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) - config = __builtin__.property(_get_config, _set_config) - state = __builtin__.property(_get_state, _set_state) + config = builtins.property(_get_config, _set_config) + state = builtins.property(_get_state, _set_state) _pyangbind_elements = {'config': config, 'state': state, } @@ -5016,16 +4898,12 @@ class yc_config_openconfig_acl__acl_interfaces_interface_ingress_acl_sets_ingres """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__set_name',) - _yang_name = 'config' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'config' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False - self.__set_name = YANGDynClass(base=unicode, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) + self.__set_name = YANGDynClass(base=str, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) load = kwargs.pop("load", None) if args: @@ -5052,7 +4930,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'interfaces', u'interface', u'ingress-acl-sets', u'ingress-acl-set', u'config'] + return ['acl', 'interfaces', 'interface', 'ingress-acl-sets', 'ingress-acl-set', 'config'] def _get_set_name(self): """ @@ -5075,7 +4953,7 @@ def _set_set_name(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=unicode, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) + t = YANGDynClass(v,base=str, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """set_name must be of a type compatible with leafref""", @@ -5088,9 +4966,9 @@ def _set_set_name(self, v, load=False): self._set() def _unset_set_name(self): - self.__set_name = YANGDynClass(base=unicode, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) + self.__set_name = YANGDynClass(base=str, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) - set_name = __builtin__.property(_get_set_name, _set_set_name) + set_name = builtins.property(_get_set_name, _set_set_name) _pyangbind_elements = {'set_name': set_name, } @@ -5107,16 +4985,12 @@ class yc_state_openconfig_acl__acl_interfaces_interface_ingress_acl_sets_ingress """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__set_name',) - _yang_name = 'state' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'state' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False - self.__set_name = YANGDynClass(base=unicode, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) + self.__set_name = YANGDynClass(base=str, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) load = kwargs.pop("load", None) if args: @@ -5143,7 +5017,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'interfaces', u'interface', u'ingress-acl-sets', u'ingress-acl-set', u'state'] + return ['acl', 'interfaces', 'interface', 'ingress-acl-sets', 'ingress-acl-set', 'state'] def _get_set_name(self): """ @@ -5166,7 +5040,7 @@ def _set_set_name(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=unicode, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) + t = YANGDynClass(v,base=str, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """set_name must be of a type compatible with leafref""", @@ -5179,9 +5053,9 @@ def _set_set_name(self, v, load=False): self._set() def _unset_set_name(self): - self.__set_name = YANGDynClass(base=unicode, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) + self.__set_name = YANGDynClass(base=str, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) - set_name = __builtin__.property(_get_set_name) + set_name = builtins.property(_get_set_name) _pyangbind_elements = {'set_name': set_name, } @@ -5198,18 +5072,14 @@ class yc_state_openconfig_acl__acl_interfaces_interface_ingress_acl_sets_ingress """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__sequence_id','__matched_packets','__matched_octets',) - _yang_name = 'state' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'state' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False - self.__sequence_id = YANGDynClass(base=unicode, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) - self.__matched_packets = YANGDynClass(base=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-packets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) - self.__matched_octets = YANGDynClass(base=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-octets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) + self.__sequence_id = YANGDynClass(base=str, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) + self.__matched_packets = YANGDynClass(base=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-packets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) + self.__matched_octets = YANGDynClass(base=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-octets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) load = kwargs.pop("load", None) if args: @@ -5236,7 +5106,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'interfaces', u'interface', u'ingress-acl-sets', u'ingress-acl-set', u'acl-entries', u'acl-entry', u'state'] + return ['acl', 'interfaces', 'interface', 'ingress-acl-sets', 'ingress-acl-set', 'acl-entries', 'acl-entry', 'state'] def _get_sequence_id(self): """ @@ -5261,7 +5131,7 @@ def _set_sequence_id(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=unicode, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) + t = YANGDynClass(v,base=str, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """sequence_id must be of a type compatible with leafref""", @@ -5274,7 +5144,7 @@ def _set_sequence_id(self, v, load=False): self._set() def _unset_sequence_id(self): - self.__sequence_id = YANGDynClass(base=unicode, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) + self.__sequence_id = YANGDynClass(base=str, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) def _get_matched_packets(self): @@ -5324,7 +5194,7 @@ def _set_matched_packets(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-packets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) + t = YANGDynClass(v,base=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-packets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """matched_packets must be of a type compatible with yang:counter64""", @@ -5337,7 +5207,7 @@ def _set_matched_packets(self, v, load=False): self._set() def _unset_matched_packets(self): - self.__matched_packets = YANGDynClass(base=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-packets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) + self.__matched_packets = YANGDynClass(base=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-packets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) def _get_matched_octets(self): @@ -5387,7 +5257,7 @@ def _set_matched_octets(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-octets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) + t = YANGDynClass(v,base=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-octets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """matched_octets must be of a type compatible with yang:counter64""", @@ -5400,11 +5270,11 @@ def _set_matched_octets(self, v, load=False): self._set() def _unset_matched_octets(self): - self.__matched_octets = YANGDynClass(base=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-octets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) + self.__matched_octets = YANGDynClass(base=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-octets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) - sequence_id = __builtin__.property(_get_sequence_id) - matched_packets = __builtin__.property(_get_matched_packets) - matched_octets = __builtin__.property(_get_matched_octets) + sequence_id = builtins.property(_get_sequence_id) + matched_packets = builtins.property(_get_matched_packets) + matched_octets = builtins.property(_get_matched_octets) _pyangbind_elements = {'sequence_id': sequence_id, 'matched_packets': matched_packets, 'matched_octets': matched_octets, } @@ -5421,16 +5291,12 @@ class yc_acl_entry_openconfig_acl__acl_interfaces_interface_ingress_acl_sets_ing """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__sequence_id','__state',) - _yang_name = 'acl-entry' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'acl-entry' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False - self.__sequence_id = YANGDynClass(base=unicode, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) + self.__sequence_id = YANGDynClass(base=str, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) self.__state = YANGDynClass(base=yc_state_openconfig_acl__acl_interfaces_interface_ingress_acl_sets_ingress_acl_set_acl_entries_acl_entry_state, is_container='container', yang_name="state", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=False) load = kwargs.pop("load", None) @@ -5458,7 +5324,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'interfaces', u'interface', u'ingress-acl-sets', u'ingress-acl-set', u'acl-entries', u'acl-entry'] + return ['acl', 'interfaces', 'interface', 'ingress-acl-sets', 'ingress-acl-set', 'acl-entries', 'acl-entry'] def _get_sequence_id(self): """ @@ -5486,7 +5352,7 @@ def _set_sequence_id(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=unicode, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) + t = YANGDynClass(v,base=str, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """sequence_id must be of a type compatible with leafref""", @@ -5499,7 +5365,7 @@ def _set_sequence_id(self, v, load=False): self._set() def _unset_sequence_id(self): - self.__sequence_id = YANGDynClass(base=unicode, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) + self.__sequence_id = YANGDynClass(base=str, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) def _get_state(self): @@ -5538,8 +5404,8 @@ def _set_state(self, v, load=False): def _unset_state(self): self.__state = YANGDynClass(base=yc_state_openconfig_acl__acl_interfaces_interface_ingress_acl_sets_ingress_acl_set_acl_entries_acl_entry_state, is_container='container', yang_name="state", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=False) - sequence_id = __builtin__.property(_get_sequence_id) - state = __builtin__.property(_get_state) + sequence_id = builtins.property(_get_sequence_id) + state = builtins.property(_get_state) _pyangbind_elements = {'sequence_id': sequence_id, 'state': state, } @@ -5556,14 +5422,10 @@ class yc_acl_entries_openconfig_acl__acl_interfaces_interface_ingress_acl_sets_i """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__acl_entry',) - _yang_name = 'acl-entries' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'acl-entries' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__acl_entry = YANGDynClass(base=YANGListType("sequence_id",yc_acl_entry_openconfig_acl__acl_interfaces_interface_ingress_acl_sets_ingress_acl_set_acl_entries_acl_entry, yang_name="acl-entry", parent=self, is_container='list', user_ordered=False, path_helper=self._path_helper, yang_keys='sequence-id', extensions=None), is_container='list', yang_name="acl-entry", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='list', is_config=False) @@ -5592,7 +5454,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'interfaces', u'interface', u'ingress-acl-sets', u'ingress-acl-set', u'acl-entries'] + return ['acl', 'interfaces', 'interface', 'ingress-acl-sets', 'ingress-acl-set', 'acl-entries'] def _get_acl_entry(self): """ @@ -5630,7 +5492,7 @@ def _set_acl_entry(self, v, load=False): def _unset_acl_entry(self): self.__acl_entry = YANGDynClass(base=YANGListType("sequence_id",yc_acl_entry_openconfig_acl__acl_interfaces_interface_ingress_acl_sets_ingress_acl_set_acl_entries_acl_entry, yang_name="acl-entry", parent=self, is_container='list', user_ordered=False, path_helper=self._path_helper, yang_keys='sequence-id', extensions=None), is_container='list', yang_name="acl-entry", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='list', is_config=False) - acl_entry = __builtin__.property(_get_acl_entry) + acl_entry = builtins.property(_get_acl_entry) _pyangbind_elements = {'acl_entry': acl_entry, } @@ -5647,16 +5509,12 @@ class yc_ingress_acl_set_openconfig_acl__acl_interfaces_interface_ingress_acl_se """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__set_name','__config','__state','__acl_entries',) - _yang_name = 'ingress-acl-set' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'ingress-acl-set' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False - self.__set_name = YANGDynClass(base=unicode, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) + self.__set_name = YANGDynClass(base=str, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) self.__config = YANGDynClass(base=yc_config_openconfig_acl__acl_interfaces_interface_ingress_acl_sets_ingress_acl_set_config, is_container='container', yang_name="config", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) self.__state = YANGDynClass(base=yc_state_openconfig_acl__acl_interfaces_interface_ingress_acl_sets_ingress_acl_set_state, is_container='container', yang_name="state", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) self.__acl_entries = YANGDynClass(base=yc_acl_entries_openconfig_acl__acl_interfaces_interface_ingress_acl_sets_ingress_acl_set_acl_entries, is_container='container', yang_name="acl-entries", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) @@ -5686,7 +5544,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'interfaces', u'interface', u'ingress-acl-sets', u'ingress-acl-set'] + return ['acl', 'interfaces', 'interface', 'ingress-acl-sets', 'ingress-acl-set'] def _get_set_name(self): """ @@ -5714,7 +5572,7 @@ def _set_set_name(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=unicode, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) + t = YANGDynClass(v,base=str, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """set_name must be of a type compatible with leafref""", @@ -5727,7 +5585,7 @@ def _set_set_name(self, v, load=False): self._set() def _unset_set_name(self): - self.__set_name = YANGDynClass(base=unicode, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) + self.__set_name = YANGDynClass(base=str, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) def _get_config(self): @@ -5840,10 +5698,10 @@ def _set_acl_entries(self, v, load=False): def _unset_acl_entries(self): self.__acl_entries = YANGDynClass(base=yc_acl_entries_openconfig_acl__acl_interfaces_interface_ingress_acl_sets_ingress_acl_set_acl_entries, is_container='container', yang_name="acl-entries", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) - set_name = __builtin__.property(_get_set_name, _set_set_name) - config = __builtin__.property(_get_config, _set_config) - state = __builtin__.property(_get_state, _set_state) - acl_entries = __builtin__.property(_get_acl_entries, _set_acl_entries) + set_name = builtins.property(_get_set_name, _set_set_name) + config = builtins.property(_get_config, _set_config) + state = builtins.property(_get_state, _set_state) + acl_entries = builtins.property(_get_acl_entries, _set_acl_entries) _pyangbind_elements = {'set_name': set_name, 'config': config, 'state': state, 'acl_entries': acl_entries, } @@ -5861,14 +5719,10 @@ class yc_ingress_acl_sets_openconfig_acl__acl_interfaces_interface_ingress_acl_s """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__ingress_acl_set',) - _yang_name = 'ingress-acl-sets' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'ingress-acl-sets' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__ingress_acl_set = YANGDynClass(base=YANGListType("set_name",yc_ingress_acl_set_openconfig_acl__acl_interfaces_interface_ingress_acl_sets_ingress_acl_set, yang_name="ingress-acl-set", parent=self, is_container='list', user_ordered=False, path_helper=self._path_helper, yang_keys='set-name', extensions=None), is_container='list', yang_name="ingress-acl-set", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='list', is_config=True) @@ -5897,7 +5751,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'interfaces', u'interface', u'ingress-acl-sets'] + return ['acl', 'interfaces', 'interface', 'ingress-acl-sets'] def _get_ingress_acl_set(self): """ @@ -5935,7 +5789,7 @@ def _set_ingress_acl_set(self, v, load=False): def _unset_ingress_acl_set(self): self.__ingress_acl_set = YANGDynClass(base=YANGListType("set_name",yc_ingress_acl_set_openconfig_acl__acl_interfaces_interface_ingress_acl_sets_ingress_acl_set, yang_name="ingress-acl-set", parent=self, is_container='list', user_ordered=False, path_helper=self._path_helper, yang_keys='set-name', extensions=None), is_container='list', yang_name="ingress-acl-set", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='list', is_config=True) - ingress_acl_set = __builtin__.property(_get_ingress_acl_set, _set_ingress_acl_set) + ingress_acl_set = builtins.property(_get_ingress_acl_set, _set_ingress_acl_set) _pyangbind_elements = {'ingress_acl_set': ingress_acl_set, } @@ -5952,16 +5806,12 @@ class yc_config_openconfig_acl__acl_interfaces_interface_egress_acl_sets_egress_ """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__set_name',) - _yang_name = 'config' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'config' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False - self.__set_name = YANGDynClass(base=unicode, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) + self.__set_name = YANGDynClass(base=str, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) load = kwargs.pop("load", None) if args: @@ -5988,7 +5838,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'interfaces', u'interface', u'egress-acl-sets', u'egress-acl-set', u'config'] + return ['acl', 'interfaces', 'interface', 'egress-acl-sets', 'egress-acl-set', 'config'] def _get_set_name(self): """ @@ -6011,7 +5861,7 @@ def _set_set_name(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=unicode, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) + t = YANGDynClass(v,base=str, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """set_name must be of a type compatible with leafref""", @@ -6024,9 +5874,9 @@ def _set_set_name(self, v, load=False): self._set() def _unset_set_name(self): - self.__set_name = YANGDynClass(base=unicode, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) + self.__set_name = YANGDynClass(base=str, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) - set_name = __builtin__.property(_get_set_name, _set_set_name) + set_name = builtins.property(_get_set_name, _set_set_name) _pyangbind_elements = {'set_name': set_name, } @@ -6043,16 +5893,12 @@ class yc_state_openconfig_acl__acl_interfaces_interface_egress_acl_sets_egress_a """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__set_name',) - _yang_name = 'state' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'state' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False - self.__set_name = YANGDynClass(base=unicode, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) + self.__set_name = YANGDynClass(base=str, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) load = kwargs.pop("load", None) if args: @@ -6079,7 +5925,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'interfaces', u'interface', u'egress-acl-sets', u'egress-acl-set', u'state'] + return ['acl', 'interfaces', 'interface', 'egress-acl-sets', 'egress-acl-set', 'state'] def _get_set_name(self): """ @@ -6102,7 +5948,7 @@ def _set_set_name(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=unicode, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) + t = YANGDynClass(v,base=str, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """set_name must be of a type compatible with leafref""", @@ -6115,9 +5961,9 @@ def _set_set_name(self, v, load=False): self._set() def _unset_set_name(self): - self.__set_name = YANGDynClass(base=unicode, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) + self.__set_name = YANGDynClass(base=str, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) - set_name = __builtin__.property(_get_set_name) + set_name = builtins.property(_get_set_name) _pyangbind_elements = {'set_name': set_name, } @@ -6134,18 +5980,14 @@ class yc_state_openconfig_acl__acl_interfaces_interface_egress_acl_sets_egress_a """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__sequence_id','__matched_packets','__matched_octets',) - _yang_name = 'state' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'state' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False - self.__sequence_id = YANGDynClass(base=unicode, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) - self.__matched_packets = YANGDynClass(base=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-packets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) - self.__matched_octets = YANGDynClass(base=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-octets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) + self.__sequence_id = YANGDynClass(base=str, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) + self.__matched_packets = YANGDynClass(base=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-packets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) + self.__matched_octets = YANGDynClass(base=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-octets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) load = kwargs.pop("load", None) if args: @@ -6172,7 +6014,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'interfaces', u'interface', u'egress-acl-sets', u'egress-acl-set', u'acl-entries', u'acl-entry', u'state'] + return ['acl', 'interfaces', 'interface', 'egress-acl-sets', 'egress-acl-set', 'acl-entries', 'acl-entry', 'state'] def _get_sequence_id(self): """ @@ -6197,7 +6039,7 @@ def _set_sequence_id(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=unicode, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) + t = YANGDynClass(v,base=str, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """sequence_id must be of a type compatible with leafref""", @@ -6210,7 +6052,7 @@ def _set_sequence_id(self, v, load=False): self._set() def _unset_sequence_id(self): - self.__sequence_id = YANGDynClass(base=unicode, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) + self.__sequence_id = YANGDynClass(base=str, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) def _get_matched_packets(self): @@ -6260,7 +6102,7 @@ def _set_matched_packets(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-packets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) + t = YANGDynClass(v,base=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-packets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """matched_packets must be of a type compatible with yang:counter64""", @@ -6273,7 +6115,7 @@ def _set_matched_packets(self, v, load=False): self._set() def _unset_matched_packets(self): - self.__matched_packets = YANGDynClass(base=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-packets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) + self.__matched_packets = YANGDynClass(base=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-packets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) def _get_matched_octets(self): @@ -6323,7 +6165,7 @@ def _set_matched_octets(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-octets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) + t = YANGDynClass(v,base=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-octets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """matched_octets must be of a type compatible with yang:counter64""", @@ -6336,11 +6178,11 @@ def _set_matched_octets(self, v, load=False): self._set() def _unset_matched_octets(self): - self.__matched_octets = YANGDynClass(base=RestrictedClassType(base_type=long, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-octets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) + self.__matched_octets = YANGDynClass(base=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..18446744073709551615']}, int_size=64), is_leaf=True, yang_name="matched-octets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='yang:counter64', is_config=False) - sequence_id = __builtin__.property(_get_sequence_id) - matched_packets = __builtin__.property(_get_matched_packets) - matched_octets = __builtin__.property(_get_matched_octets) + sequence_id = builtins.property(_get_sequence_id) + matched_packets = builtins.property(_get_matched_packets) + matched_octets = builtins.property(_get_matched_octets) _pyangbind_elements = {'sequence_id': sequence_id, 'matched_packets': matched_packets, 'matched_octets': matched_octets, } @@ -6357,16 +6199,12 @@ class yc_acl_entry_openconfig_acl__acl_interfaces_interface_egress_acl_sets_egre """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__sequence_id','__state',) - _yang_name = 'acl-entry' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'acl-entry' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False - self.__sequence_id = YANGDynClass(base=unicode, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) + self.__sequence_id = YANGDynClass(base=str, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) self.__state = YANGDynClass(base=yc_state_openconfig_acl__acl_interfaces_interface_egress_acl_sets_egress_acl_set_acl_entries_acl_entry_state, is_container='container', yang_name="state", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=False) load = kwargs.pop("load", None) @@ -6394,7 +6232,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'interfaces', u'interface', u'egress-acl-sets', u'egress-acl-set', u'acl-entries', u'acl-entry'] + return ['acl', 'interfaces', 'interface', 'egress-acl-sets', 'egress-acl-set', 'acl-entries', 'acl-entry'] def _get_sequence_id(self): """ @@ -6422,7 +6260,7 @@ def _set_sequence_id(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=unicode, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) + t = YANGDynClass(v,base=str, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) except (TypeError, ValueError): raise ValueError({ 'error-string': """sequence_id must be of a type compatible with leafref""", @@ -6435,7 +6273,7 @@ def _set_sequence_id(self, v, load=False): self._set() def _unset_sequence_id(self): - self.__sequence_id = YANGDynClass(base=unicode, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) + self.__sequence_id = YANGDynClass(base=str, is_leaf=True, yang_name="sequence-id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=False) def _get_state(self): @@ -6474,8 +6312,8 @@ def _set_state(self, v, load=False): def _unset_state(self): self.__state = YANGDynClass(base=yc_state_openconfig_acl__acl_interfaces_interface_egress_acl_sets_egress_acl_set_acl_entries_acl_entry_state, is_container='container', yang_name="state", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=False) - sequence_id = __builtin__.property(_get_sequence_id) - state = __builtin__.property(_get_state) + sequence_id = builtins.property(_get_sequence_id) + state = builtins.property(_get_state) _pyangbind_elements = {'sequence_id': sequence_id, 'state': state, } @@ -6492,14 +6330,10 @@ class yc_acl_entries_openconfig_acl__acl_interfaces_interface_egress_acl_sets_eg """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__acl_entry',) - _yang_name = 'acl-entries' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'acl-entries' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__acl_entry = YANGDynClass(base=YANGListType("sequence_id",yc_acl_entry_openconfig_acl__acl_interfaces_interface_egress_acl_sets_egress_acl_set_acl_entries_acl_entry, yang_name="acl-entry", parent=self, is_container='list', user_ordered=False, path_helper=self._path_helper, yang_keys='sequence-id', extensions=None), is_container='list', yang_name="acl-entry", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='list', is_config=False) @@ -6528,7 +6362,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'interfaces', u'interface', u'egress-acl-sets', u'egress-acl-set', u'acl-entries'] + return ['acl', 'interfaces', 'interface', 'egress-acl-sets', 'egress-acl-set', 'acl-entries'] def _get_acl_entry(self): """ @@ -6566,7 +6400,7 @@ def _set_acl_entry(self, v, load=False): def _unset_acl_entry(self): self.__acl_entry = YANGDynClass(base=YANGListType("sequence_id",yc_acl_entry_openconfig_acl__acl_interfaces_interface_egress_acl_sets_egress_acl_set_acl_entries_acl_entry, yang_name="acl-entry", parent=self, is_container='list', user_ordered=False, path_helper=self._path_helper, yang_keys='sequence-id', extensions=None), is_container='list', yang_name="acl-entry", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='list', is_config=False) - acl_entry = __builtin__.property(_get_acl_entry) + acl_entry = builtins.property(_get_acl_entry) _pyangbind_elements = {'acl_entry': acl_entry, } @@ -6583,16 +6417,12 @@ class yc_egress_acl_set_openconfig_acl__acl_interfaces_interface_egress_acl_sets """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__set_name','__config','__state','__acl_entries',) - _yang_name = 'egress-acl-set' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'egress-acl-set' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False - self.__set_name = YANGDynClass(base=unicode, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) + self.__set_name = YANGDynClass(base=str, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) self.__config = YANGDynClass(base=yc_config_openconfig_acl__acl_interfaces_interface_egress_acl_sets_egress_acl_set_config, is_container='container', yang_name="config", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) self.__state = YANGDynClass(base=yc_state_openconfig_acl__acl_interfaces_interface_egress_acl_sets_egress_acl_set_state, is_container='container', yang_name="state", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) self.__acl_entries = YANGDynClass(base=yc_acl_entries_openconfig_acl__acl_interfaces_interface_egress_acl_sets_egress_acl_set_acl_entries, is_container='container', yang_name="acl-entries", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) @@ -6622,7 +6452,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'interfaces', u'interface', u'egress-acl-sets', u'egress-acl-set'] + return ['acl', 'interfaces', 'interface', 'egress-acl-sets', 'egress-acl-set'] def _get_set_name(self): """ @@ -6650,7 +6480,7 @@ def _set_set_name(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=unicode, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) + t = YANGDynClass(v,base=str, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """set_name must be of a type compatible with leafref""", @@ -6663,7 +6493,7 @@ def _set_set_name(self, v, load=False): self._set() def _unset_set_name(self): - self.__set_name = YANGDynClass(base=unicode, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) + self.__set_name = YANGDynClass(base=str, is_leaf=True, yang_name="set-name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) def _get_config(self): @@ -6776,10 +6606,10 @@ def _set_acl_entries(self, v, load=False): def _unset_acl_entries(self): self.__acl_entries = YANGDynClass(base=yc_acl_entries_openconfig_acl__acl_interfaces_interface_egress_acl_sets_egress_acl_set_acl_entries, is_container='container', yang_name="acl-entries", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) - set_name = __builtin__.property(_get_set_name, _set_set_name) - config = __builtin__.property(_get_config, _set_config) - state = __builtin__.property(_get_state, _set_state) - acl_entries = __builtin__.property(_get_acl_entries, _set_acl_entries) + set_name = builtins.property(_get_set_name, _set_set_name) + config = builtins.property(_get_config, _set_config) + state = builtins.property(_get_state, _set_state) + acl_entries = builtins.property(_get_acl_entries, _set_acl_entries) _pyangbind_elements = {'set_name': set_name, 'config': config, 'state': state, 'acl_entries': acl_entries, } @@ -6797,14 +6627,10 @@ class yc_egress_acl_sets_openconfig_acl__acl_interfaces_interface_egress_acl_set """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__egress_acl_set',) - _yang_name = 'egress-acl-sets' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'egress-acl-sets' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__egress_acl_set = YANGDynClass(base=YANGListType("set_name",yc_egress_acl_set_openconfig_acl__acl_interfaces_interface_egress_acl_sets_egress_acl_set, yang_name="egress-acl-set", parent=self, is_container='list', user_ordered=False, path_helper=self._path_helper, yang_keys='set-name', extensions=None), is_container='list', yang_name="egress-acl-set", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='list', is_config=True) @@ -6833,7 +6659,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'interfaces', u'interface', u'egress-acl-sets'] + return ['acl', 'interfaces', 'interface', 'egress-acl-sets'] def _get_egress_acl_set(self): """ @@ -6871,7 +6697,7 @@ def _set_egress_acl_set(self, v, load=False): def _unset_egress_acl_set(self): self.__egress_acl_set = YANGDynClass(base=YANGListType("set_name",yc_egress_acl_set_openconfig_acl__acl_interfaces_interface_egress_acl_sets_egress_acl_set, yang_name="egress-acl-set", parent=self, is_container='list', user_ordered=False, path_helper=self._path_helper, yang_keys='set-name', extensions=None), is_container='list', yang_name="egress-acl-set", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='list', is_config=True) - egress_acl_set = __builtin__.property(_get_egress_acl_set, _set_egress_acl_set) + egress_acl_set = builtins.property(_get_egress_acl_set, _set_egress_acl_set) _pyangbind_elements = {'egress_acl_set': egress_acl_set, } @@ -6888,20 +6714,16 @@ class yc_interface_openconfig_acl__acl_interfaces_interface(PybindBase): """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__id','__config','__state','__interface_ref','__ingress_acl_sets','__egress_acl_sets',) - _yang_name = 'interface' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'interface' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__ingress_acl_sets = YANGDynClass(base=yc_ingress_acl_sets_openconfig_acl__acl_interfaces_interface_ingress_acl_sets, is_container='container', yang_name="ingress-acl-sets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) self.__egress_acl_sets = YANGDynClass(base=yc_egress_acl_sets_openconfig_acl__acl_interfaces_interface_egress_acl_sets, is_container='container', yang_name="egress-acl-sets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) self.__state = YANGDynClass(base=yc_state_openconfig_acl__acl_interfaces_interface_state, is_container='container', yang_name="state", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) self.__config = YANGDynClass(base=yc_config_openconfig_acl__acl_interfaces_interface_config, is_container='container', yang_name="config", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) - self.__id = YANGDynClass(base=unicode, is_leaf=True, yang_name="id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) + self.__id = YANGDynClass(base=str, is_leaf=True, yang_name="id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) self.__interface_ref = YANGDynClass(base=yc_interface_ref_openconfig_acl__acl_interfaces_interface_interface_ref, is_container='container', yang_name="interface-ref", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) load = kwargs.pop("load", None) @@ -6929,7 +6751,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'interfaces', u'interface'] + return ['acl', 'interfaces', 'interface'] def _get_id(self): """ @@ -6957,7 +6779,7 @@ def _set_id(self, v, load=False): if hasattr(v, "_utype"): v = v._utype(v) try: - t = YANGDynClass(v,base=unicode, is_leaf=True, yang_name="id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) + t = YANGDynClass(v,base=str, is_leaf=True, yang_name="id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) except (TypeError, ValueError): raise ValueError({ 'error-string': """id must be of a type compatible with leafref""", @@ -6970,7 +6792,7 @@ def _set_id(self, v, load=False): self._set() def _unset_id(self): - self.__id = YANGDynClass(base=unicode, is_leaf=True, yang_name="id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) + self.__id = YANGDynClass(base=str, is_leaf=True, yang_name="id", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, is_keyval=True, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='leafref', is_config=True) def _get_config(self): @@ -7161,12 +6983,12 @@ def _set_egress_acl_sets(self, v, load=False): def _unset_egress_acl_sets(self): self.__egress_acl_sets = YANGDynClass(base=yc_egress_acl_sets_openconfig_acl__acl_interfaces_interface_egress_acl_sets, is_container='container', yang_name="egress-acl-sets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) - id = __builtin__.property(_get_id, _set_id) - config = __builtin__.property(_get_config, _set_config) - state = __builtin__.property(_get_state, _set_state) - interface_ref = __builtin__.property(_get_interface_ref, _set_interface_ref) - ingress_acl_sets = __builtin__.property(_get_ingress_acl_sets, _set_ingress_acl_sets) - egress_acl_sets = __builtin__.property(_get_egress_acl_sets, _set_egress_acl_sets) + id = builtins.property(_get_id, _set_id) + config = builtins.property(_get_config, _set_config) + state = builtins.property(_get_state, _set_state) + interface_ref = builtins.property(_get_interface_ref, _set_interface_ref) + ingress_acl_sets = builtins.property(_get_ingress_acl_sets, _set_ingress_acl_sets) + egress_acl_sets = builtins.property(_get_egress_acl_sets, _set_egress_acl_sets) _pyangbind_elements = {'id': id, 'config': config, 'state': state, 'interface_ref': interface_ref, 'ingress_acl_sets': ingress_acl_sets, 'egress_acl_sets': egress_acl_sets, } @@ -7184,14 +7006,10 @@ class yc_interfaces_openconfig_acl__acl_interfaces(PybindBase): """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__interface',) - _yang_name = 'interfaces' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'interfaces' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__interface = YANGDynClass(base=YANGListType("id",yc_interface_openconfig_acl__acl_interfaces_interface, yang_name="interface", parent=self, is_container='list', user_ordered=False, path_helper=self._path_helper, yang_keys='id', extensions=None), is_container='list', yang_name="interface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='list', is_config=True) @@ -7220,7 +7038,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl', u'interfaces'] + return ['acl', 'interfaces'] def _get_interface(self): """ @@ -7258,7 +7076,7 @@ def _set_interface(self, v, load=False): def _unset_interface(self): self.__interface = YANGDynClass(base=YANGListType("id",yc_interface_openconfig_acl__acl_interfaces_interface, yang_name="interface", parent=self, is_container='list', user_ordered=False, path_helper=self._path_helper, yang_keys='id', extensions=None), is_container='list', yang_name="interface", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='list', is_config=True) - interface = __builtin__.property(_get_interface, _set_interface) + interface = builtins.property(_get_interface, _set_interface) _pyangbind_elements = {'interface': interface, } @@ -7276,14 +7094,10 @@ class yc_acl_openconfig_acl__acl(PybindBase): """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__state','__acl_sets','__interfaces',) - _yang_name = 'acl' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'acl' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__state = YANGDynClass(base=yc_state_openconfig_acl__acl_state, is_container='container', yang_name="state", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) self.__acl_sets = YANGDynClass(base=yc_acl_sets_openconfig_acl__acl_acl_sets, is_container='container', yang_name="acl-sets", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) @@ -7314,7 +7128,7 @@ def _path(self): if hasattr(self, "_parent"): return self._parent._path()+[self._yang_name] else: - return [u'acl'] + return ['acl'] def _get_state(self): """ @@ -7428,9 +7242,9 @@ def _set_interfaces(self, v, load=False): def _unset_interfaces(self): self.__interfaces = YANGDynClass(base=yc_interfaces_openconfig_acl__acl_interfaces, is_container='container', yang_name="interfaces", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) - state = __builtin__.property(_get_state, _set_state) - acl_sets = __builtin__.property(_get_acl_sets, _set_acl_sets) - interfaces = __builtin__.property(_get_interfaces, _set_interfaces) + state = builtins.property(_get_state, _set_state) + acl_sets = builtins.property(_get_acl_sets, _set_acl_sets) + interfaces = builtins.property(_get_interfaces, _set_interfaces) _pyangbind_elements = {'state': state, 'acl_sets': acl_sets, 'interfaces': interfaces, } @@ -7460,14 +7274,10 @@ class openconfig_acl(PybindBase): """ __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_extmethods', '__acl',) - _yang_name = 'openconfig-acl' - - _pybind_generated_by = 'container' - def __init__(self, *args, **kwargs): - + self._yang_name = 'openconfig-acl' + self._pybind_generated_by = 'container' self._path_helper = False - self._extmethods = False self.__acl = YANGDynClass(base=yc_acl_openconfig_acl__acl, is_container='container', yang_name="acl", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) @@ -7536,7 +7346,7 @@ def _set_acl(self, v, load=False): def _unset_acl(self): self.__acl = YANGDynClass(base=yc_acl_openconfig_acl__acl, is_container='container', yang_name="acl", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='http://openconfig.net/yang/acl', defining_module='openconfig-acl', yang_type='container', is_config=True) - acl = __builtin__.property(_get_acl, _set_acl) + acl = builtins.property(_get_acl, _set_acl) _pyangbind_elements = {'acl': acl, } diff --git a/src/sonic-config-engine/portconfig.py b/src/sonic-config-engine/portconfig.py index db2baa308174..478198e5af84 100644 --- a/src/sonic-config-engine/portconfig.py +++ b/src/sonic-config-engine/portconfig.py @@ -1,33 +1,122 @@ -#!/usr/bin/env python -import os -import sys +try: + import ast + import json + import os + import re + import sys + from swsscommon.swsscommon import ConfigDBConnector + from sonic_py_common import device_info +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) -def get_port_config_file_name(hwsku=None, platform=None): - port_config_candidates = [] - port_config_candidates.append('/usr/share/sonic/hwsku/port_config.ini') +# Global Variable +PLATFORM_ROOT_PATH = '/usr/share/sonic/device' +PLATFORM_ROOT_PATH_DOCKER = '/usr/share/sonic/platform' +SONIC_ROOT_PATH = '/usr/share/sonic' +HWSKU_ROOT_PATH = '/usr/share/sonic/hwsku' + +PLATFORM_JSON = 'platform.json' +PORT_CONFIG_INI = 'port_config.ini' +HWSKU_JSON = 'hwsku.json' + +PORT_STR = "Ethernet" +BRKOUT_MODE = "default_brkout_mode" +CUR_BRKOUT_MODE = "brkout_mode" +INTF_KEY = "interfaces" +OPTIONAL_HWSKU_ATTRIBUTES = ["fec", "autoneg"] + +BRKOUT_PATTERN = r'(\d{1,3})x(\d{1,3}G)(\[\d{1,3}G\])?(\((\d{1,3})\))?' + + +# +# Helper Functions +# +def readJson(filename): + # Read 'platform.json' or 'hwsku.json' file + try: + with open(filename) as fp: + try: + data = json.load(fp) + except json.JSONDecodeError: + print("Json file does not exist") + data_dict = ast.literal_eval(json.dumps(data)) + return data_dict + except Exception as e: + print("error occurred while parsing json: {}".format(sys.exc_info()[1])) + return None + +def db_connect_configdb(): + """ + Connect to configdb + """ + config_db = ConfigDBConnector() + if config_db is None: + return None + try: + """ + This could be blocking during the config load_minigraph phase, + as the CONFIG_DB_INITIALIZED is not yet set in the configDB. + We can ignore the check by using config_db.db_connect('CONFIG_DB') instead + """ + # Connect only if available & initialized + config_db.connect(wait_for_init=False) + except Exception as e: + config_db = None + return config_db + +def get_hwsku_file_name(hwsku=None, platform=None): + hwsku_candidates_Json = [] + hwsku_candidates_Json.append(os.path.join(HWSKU_ROOT_PATH, HWSKU_JSON)) if hwsku: if platform: - port_config_candidates.append(os.path.join('/usr/share/sonic/device', platform, hwsku, 'port_config.ini')) - port_config_candidates.append(os.path.join('/usr/share/sonic/platform', hwsku, 'port_config.ini')) - port_config_candidates.append(os.path.join('/usr/share/sonic', hwsku, 'port_config.ini')) - for candidate in port_config_candidates: + hwsku_candidates_Json.append(os.path.join(PLATFORM_ROOT_PATH, platform, hwsku, HWSKU_JSON)) + hwsku_candidates_Json.append(os.path.join(PLATFORM_ROOT_PATH_DOCKER, hwsku, HWSKU_JSON)) + hwsku_candidates_Json.append(os.path.join(SONIC_ROOT_PATH, hwsku, HWSKU_JSON)) + for candidate in hwsku_candidates_Json: if os.path.isfile(candidate): return candidate return None - -def get_port_config(hwsku=None, platform=None, port_config_file=None): +def get_port_config(hwsku=None, platform=None, port_config_file=None, hwsku_config_file=None, asic=None): + config_db = db_connect_configdb() + # If available, Read from CONFIG DB first + if config_db is not None and port_config_file is None: + + port_data = config_db.get_table("PORT") + if bool(port_data): + ports = ast.literal_eval(json.dumps(port_data)) + port_alias_map = {} + port_alias_asic_map = {} + for intf_name in ports.keys(): + port_alias_map[ports[intf_name]["alias"]] = intf_name + return (ports, port_alias_map, port_alias_asic_map) + if not port_config_file: - port_config_file = get_port_config_file_name(hwsku, platform) + port_config_file = device_info.get_path_to_port_config_file(hwsku, asic) if not port_config_file: - return ({}, {}) - return parse_port_config_file(port_config_file) + return ({}, {}, {}) + + + # Read from 'platform.json' file + if port_config_file.endswith('.json'): + if not hwsku_config_file: + hwsku_json_file = get_hwsku_file_name(hwsku, platform) + if not hwsku_json_file: + return ({}, {}, {}) + else: + hwsku_json_file = hwsku_config_file + return parse_platform_json_file(hwsku_json_file, port_config_file) + + # If 'platform.json' file is not available, read from 'port_config.ini' + else: + return parse_port_config_file(port_config_file) def parse_port_config_file(port_config_file): ports = {} port_alias_map = {} + port_alias_asic_map = {} # Default column definition titles = ['name', 'lanes', 'alias', 'index'] with open(port_config_file) as data: @@ -49,6 +138,158 @@ def parse_port_config_file(port_config_file): data.setdefault('alias', name) ports[name] = data port_alias_map[data['alias']] = name - return (ports, port_alias_map) + # asic_port_name to sonic_name mapping also included in + # port_alias_map + if (('asic_port_name' in data) and + (data['asic_port_name'] != name)): + port_alias_map[data['asic_port_name']] = name + # alias to asic_port_name mapping + if 'asic_port_name' in data: + port_alias_asic_map[data['alias']] = data['asic_port_name'].strip() + return (ports, port_alias_map, port_alias_asic_map) + +# Generate configs (i.e. alias, lanes, speed, index) for port +def gen_port_config(ports, parent_intf_id, index, alias_at_lanes, lanes, k, offset): + if k is not None: + num_lane_used, speed, alt_speed, _ , assigned_lane = k[0], k[1], k[2], k[3], k[4] + + # In case of symmetric mode + if assigned_lane is None: + assigned_lane = len(lanes.split(",")) + + parent_intf_id = int(offset)+int(parent_intf_id) + alias_start = 0 + offset + + step = int(assigned_lane)//int(num_lane_used) + for i in range(0,int(assigned_lane), step): + intf_name = PORT_STR + str(parent_intf_id) + ports[intf_name] = {} + ports[intf_name]['alias'] = alias_at_lanes.split(",")[alias_start] + ports[intf_name]['lanes'] = ','.join(lanes.split(",")[alias_start:alias_start+step]) + if speed: + speed_pat = re.search("^((\d+)G|\d+)$", speed.upper()) + if speed_pat is None: + raise Exception('{} speed is not Supported...'.format(speed)) + speed_G, speed_orig = speed_pat.group(2), speed_pat.group(1) + if speed_G: + conv_speed = int(speed_G)*1000 + else: + conv_speed = int(speed_orig) + ports[intf_name]['speed'] = str(conv_speed) + else: + raise Exception('Regex return for speed is None...') + + ports[intf_name]['index'] = index.split(",")[alias_start] + ports[intf_name]['admin_status'] = "up" + + parent_intf_id += step + alias_start += step + + offset = int(assigned_lane) + int(offset) + return offset + else: + raise Exception('Regex return for k is None...') + +""" +Given a port and breakout mode, this method returns +the list of child ports using platform_json file +""" +def get_child_ports(interface, breakout_mode, platform_json_file): + child_ports = {} + + port_dict = readJson(platform_json_file) + + index = port_dict[INTF_KEY][interface]['index'] + alias_at_lanes = port_dict[INTF_KEY][interface]['alias_at_lanes'] + lanes = port_dict[INTF_KEY][interface]['lanes'] + + """ + Example of match_list for some breakout_mode using regex + Breakout Mode -------> Match_list + ----------------------------- + 2x25G(2)+1x50G(2) ---> [('2', '25G', None, '(2)', '2'), ('1', '50G', None, '(2)', '2')] + 1x50G(2)+2x25G(2) ---> [('1', '50G', None, '(2)', '2'), ('2', '25G', None, '(2)', '2')] + 1x100G[40G] ---------> [('1', '100G', '[40G]', None, None)] + 2x50G ---------------> [('2', '50G', None, None, None)] + """ + # Asymmetric breakout mode + if re.search("\+",breakout_mode) is not None: + breakout_parts = breakout_mode.split("+") + match_list = [re.match(BRKOUT_PATTERN, i).groups() for i in breakout_parts] + + # Symmetric breakout mode + else: + match_list = [re.match(BRKOUT_PATTERN, breakout_mode).groups()] + + offset = 0 + parent_intf_id = int(re.search("Ethernet(\d+)", interface).group(1)) + for k in match_list: + offset = gen_port_config(child_ports, parent_intf_id, index, alias_at_lanes, lanes, k, offset) + return child_ports + +def parse_platform_json_file(hwsku_json_file, platform_json_file): + ports = {} + port_alias_map = {} + port_alias_asic_map = {} + + port_dict = readJson(platform_json_file) + hwsku_dict = readJson(hwsku_json_file) + + if not port_dict: + raise Exception("port_dict is none") + if not hwsku_dict: + raise Exception("hwsku_dict is none") + + if INTF_KEY not in port_dict or INTF_KEY not in hwsku_dict: + raise Exception("INTF_KEY is not present in appropriate file") + + for intf in port_dict[INTF_KEY]: + if intf not in hwsku_dict[INTF_KEY]: + raise Exception("{} is not available in hwsku_dict".format(intf)) + + # take default_brkout_mode from hwsku.json + brkout_mode = hwsku_dict[INTF_KEY][intf][BRKOUT_MODE] + + child_ports = get_child_ports(intf, brkout_mode, platform_json_file) + + # take optional fields from hwsku.json + for key, item in hwsku_dict[INTF_KEY][intf].items(): + if key in OPTIONAL_HWSKU_ATTRIBUTES: + child_ports.get(intf)[key] = item + + ports.update(child_ports) + + if not ports: + raise Exception("Ports dictionary is empty") + + for i in ports.keys(): + port_alias_map[ports[i]["alias"]]= i + return (ports, port_alias_map, port_alias_asic_map) + + +def get_breakout_mode(hwsku=None, platform=None, port_config_file=None): + if not port_config_file: + port_config_file = device_info.get_path_to_port_config_file(hwsku) + if not port_config_file: + return None + if port_config_file.endswith('.json'): + hwsku_json_file = get_hwsku_file_name(hwsku, platform) + if not hwsku_json_file: + raise Exception("'hwsku_json' file does not exist!!! This file is necessary to proceed forward.") + + return parse_breakout_mode(hwsku_json_file) + else: + return None +def parse_breakout_mode(hwsku_json_file): + brkout_table = {} + hwsku_dict = readJson(hwsku_json_file) + if not hwsku_dict: + raise Exception("hwsku_dict is empty") + if INTF_KEY not in hwsku_dict: + raise Exception("INTF_KEY is not present in hwsku_dict") + for intf in hwsku_dict[INTF_KEY]: + brkout_table[intf] = {} + brkout_table[intf][CUR_BRKOUT_MODE] = hwsku_dict[INTF_KEY][intf][BRKOUT_MODE] + return brkout_table diff --git a/src/sonic-config-engine/redis_bcc.py b/src/sonic-config-engine/redis_bcc.py index 5ab59b6a6959..c9d3ebca239f 100644 --- a/src/sonic-config-engine/redis_bcc.py +++ b/src/sonic-config-engine/redis_bcc.py @@ -1,5 +1,7 @@ import jinja2 +from base64 import b64encode, b64decode + class RedisBytecodeCache(jinja2.BytecodeCache): """ A bytecode cache for jinja2 template that stores bytecode in Redis """ @@ -8,19 +10,20 @@ class RedisBytecodeCache(jinja2.BytecodeCache): def __init__(self, client): self._client = client try: - self._client.connect(self._client.STATE_DB, retry_on=False) + self._client.connect(self._client.LOGLEVEL_DB, retry_on=False) except Exception: self._client = None def load_bytecode(self, bucket): if self._client is None: return - code = self._client.get(self._client.STATE_DB, self.REDIS_HASH, bucket.key) + code = self._client.get(self._client.LOGLEVEL_DB, self.REDIS_HASH, bucket.key) if code is not None: - bucket.bytecode_from_string(code) + bucket.bytecode_from_string(b64decode(code.encode())) def dump_bytecode(self, bucket): if self._client is None: return - self._client.set(self._client.STATE_DB, self.REDIS_HASH, bucket.key, bucket.bytecode_to_string()) + self._client.set(self._client.LOGLEVEL_DB, self.REDIS_HASH, + bucket.key, b64encode(bucket.bytecode_to_string()).decode()) diff --git a/src/sonic-config-engine/setup.py b/src/sonic-config-engine/setup.py old mode 100755 new mode 100644 index c75a5b5a03a6..d167e0566438 --- a/src/sonic-config-engine/setup.py +++ b/src/sonic-config-engine/setup.py @@ -1,26 +1,79 @@ -#!/usr/bin/env python +import glob +import sys from setuptools import setup -import os.path -import unittest -import glob -def get_test_suite(): - test_loader = unittest.TestLoader() - test_suite = test_loader.discover('tests', pattern='*.py') - return test_suite +# Common dependencies for Python 2 and 3 +dependencies = [ + 'bitarray==1.5.3', + 'ipaddress==1.0.23', + 'lxml==4.6.2', + 'netaddr==0.8.0', + 'pyyaml==5.4.1', + 'sonic-py-common', +] + +if sys.version_info.major == 3: + # Python 3-only dependencies + dependencies += [ + # pyangbind v0.8.1 pull down enum43 which causes 're' package to malfunction. + # Python3 has enum module and so pyangbind should be installed outside + # dependencies section of setuptools followed by uninstall of enum43 + # 'pyangbind==0.8.1', + 'Jinja2>=2.10' + ] +else: + # Python 2-only dependencies + dependencies += [ + # Jinja2 v3.0.0+ dropped support for Python 2.7 and causes setuptools to + # malfunction on stretch slave docker. + 'future', + 'Jinja2<3.0.0', + 'pyangbind==0.6.0', + 'zipp==1.2.0', # importlib-resources needs zipp and seems to have a bug where it will try to install too new of a version for Python 2 + 'importlib-resources==3.3.1' # importlib-resources v4.0.0 was released 2020-12-23 and drops support for Python 2 + ] + -setup(name='sonic-config-engine', - version='1.0', - description='Utilities for generating SONiC configuration files', - author='Taoyu Li', - author_email='taoyl@microsoft.com', - url='https://github.com/Azure/sonic-buildimage', - py_modules=['portconfig', 'minigraph', 'openconfig_acl', 'sonic_device_util', 'config_samples', 'redis_bcc', 'lazy_re'], - scripts=['sonic-cfggen'], - install_requires=['lxml', 'jinja2>=2.10', 'netaddr', 'ipaddr', 'pyyaml', 'pyangbind==0.6.0'], - test_suite='setup.get_test_suite', - data_files=[ +setup( + name = 'sonic-config-engine', + version = '1.0', + description = 'Utilities for generating SONiC configuration files', + author = 'Taoyu Li', + author_email = 'taoyl@microsoft.com', + url = 'https://github.com/Azure/sonic-buildimage', + py_modules = [ + 'config_samples', + 'lazy_re', + 'minigraph', + 'openconfig_acl', + 'portconfig', + 'redis_bcc', + ], + scripts = [ + 'sonic-cfggen', + ], + install_requires = dependencies, + data_files = [ ('/usr/share/sonic/templates', glob.glob('data/*')), - ], - ) + ], + setup_requires= [ + 'pytest-runner', + 'wheel' + ], + tests_require=[ + 'pytest', + ], + classifiers = [ + 'Intended Audience :: Developers', + 'Natural Language :: English', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + ], + keywords = 'SONiC sonic-cfggen config-engine PYTHON python' +) diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index 34f5a36f0fe3..0f9ffafad635 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -26,33 +26,46 @@ from __future__ import print_function # FIXME: remove this once sonic-cfggen and templates dependencies are replaced with a faster approach import lazy_re -import sys -import os.path import argparse -import yaml +import contextlib import jinja2 -import netaddr import json +import netaddr +import os +import sys +import yaml + +from collections import OrderedDict +from config_samples import generate_sample_config, get_available_config from functools import partial -from minigraph import minigraph_encoder -from minigraph import parse_xml -from minigraph import parse_device_desc_xml -from portconfig import get_port_config -from sonic_device_util import get_machine_info -from sonic_device_util import get_platform_info -from sonic_device_util import get_system_mac -from config_samples import generate_sample_config -from config_samples import get_available_config -from swsssdk import SonicV2Connector, ConfigDBConnector +from minigraph import minigraph_encoder, parse_xml, parse_device_desc_xml, parse_asic_sub_role +from portconfig import get_port_config, get_breakout_mode from redis_bcc import RedisBytecodeCache -from collections import OrderedDict -from natsort import natsorted +from sonic_py_common.multi_asic import get_asic_id_from_name, is_multi_asic +from sonic_py_common import device_info +from swsscommon.swsscommon import SonicV2Connector, ConfigDBConnector, SonicDBConfig, ConfigDBPipeConnector + + +PY3x = sys.version_info >= (3, 0) + +#TODO: Remove STR_TYPE, FILE_TYPE once SONiC moves to Python 3.x +if PY3x: + from io import IOBase + STR_TYPE = str + FILE_TYPE = IOBase +else: + STR_TYPE = unicode + FILE_TYPE = file def sort_by_port_index(value): if not value: return if isinstance(value, list): - value.sort(key = lambda k: int(k[8:])) + # In multi-ASIC platforms backend ethernet ports are identified as + # 'Ethernet-BPxy'. Add 1024 to sort backend ports to the end. + value.sort( + key = lambda k: int(k[8:]) if "BP" not in k else int(k[11:]) + 1024 + ) def is_ipv4(value): if not value: @@ -111,7 +124,17 @@ def pfx_filter(value): for key,val in value.items(): if not isinstance(key, tuple): continue - table[key] = val + intf, ip_address = key + if '/' not in ip_address: + if is_ipv4(ip_address): + new_ip_address = "%s/32" % ip_address + elif is_ipv6(ip_address): + new_ip_address = "%s/128" % ip_address + else: + raise ValueError("'%s' is invalid ip address" % ip_address) + table[(intf, new_ip_address)] = val + else: + table[key] = val return table def ip_network(value): @@ -145,17 +168,16 @@ TODO(taoyl): Current version of config db only supports BGP admin states. @staticmethod def to_serialized(data, lookup_key = None): if type(data) is dict: - data = OrderedDict(natsorted(data.items())) - - if lookup_key != None: + if lookup_key is not None: newData = {} for key in data.keys(): - if ((type(key) is unicode and lookup_key == key) or (type(key) is tuple and lookup_key in key)): + if ((type(key) is STR_TYPE and lookup_key == key) or (type(key) is tuple and lookup_key in key)): newData[ConfigDBConnector.serialize_key(key)] = data.pop(key) break return newData - for key in data.keys(): + current_keys = list(data.keys()) + for key in current_keys: new_key = ConfigDBConnector.serialize_key(key) if new_key != key: data[new_key] = data.pop(key) @@ -166,7 +188,8 @@ TODO(taoyl): Current version of config db only supports BGP admin states. def to_deserialized(data): for table in data: if type(data[table]) is dict: - for key in data[table].keys(): + current_keys = list(data[table].keys()) + for key in current_keys: new_key = ConfigDBConnector.deserialize_key(key) if new_key != key: data[table][new_key] = data[table].pop(key) @@ -174,20 +197,64 @@ TODO(taoyl): Current version of config db only supports BGP admin states. def deep_update(dst, src): - for key, value in src.iteritems(): - if isinstance(value, dict): - node = dst.setdefault(key, {}) - deep_update(node, value) - else: - dst[key] = value + """ Deep update of dst dict with contest of src dict""" + pending_nodes = [(dst, src)] + while len(pending_nodes) > 0: + d, s = pending_nodes.pop(0) + for key, value in s.items(): + if isinstance(value, dict): + node = d.setdefault(key, type(value)()) + pending_nodes.append((node, value)) + else: + d[key] = value return dst +# sort_data is required as it is being imported by config/config_mgmt module in sonic_utilities def sort_data(data): for table in data: if type(data[table]) is dict: data[table] = OrderedDict(natsorted(data[table].items())) return data +@contextlib.contextmanager +def smart_open(filename=None, mode=None): + """ + Provide contextual file descriptor of filename if it is not a file descriptor + """ + smart_file = open(filename, mode) if not isinstance(filename, FILE_TYPE) else filename + try: + yield smart_file + finally: + if not isinstance(filename, FILE_TYPE): + smart_file.close() + +def _process_json(args, data): + """ + Process JSON file and update switch configuration data + """ + for json_file in args.json: + with open(json_file, 'r') as stream: + deep_update(data, FormatConverter.to_deserialized(json.load(stream))) + +def _get_jinja2_env(paths): + """ + Retreive Jinj2 env used to render configuration templates + """ + loader = jinja2.FileSystemLoader(paths) + redis_bcc = RedisBytecodeCache(SonicV2Connector(host='127.0.0.1')) + env = jinja2.Environment(loader=loader, trim_blocks=True, bytecode_cache=redis_bcc) + env.filters['sort_by_port_index'] = sort_by_port_index + env.filters['ipv4'] = is_ipv4 + env.filters['ipv6'] = is_ipv6 + env.filters['unique_name'] = unique_name + env.filters['pfx_filter'] = pfx_filter + env.filters['ip_network'] = ip_network + for attr in ['ip', 'network', 'prefixlen', 'netmask', 'broadcast']: + env.filters[attr] = partial(prefix_attr, attr) + # Pass the is_multi_asic function as global + env.globals['multi_asic'] = is_multi_asic + + return env def main(): parser=argparse.ArgumentParser(description="Render configuration file from minigraph data and jinja2 template.") @@ -195,7 +262,9 @@ def main(): group.add_argument("-m", "--minigraph", help="minigraph xml file", nargs='?', const='/etc/sonic/minigraph.xml') group.add_argument("-M", "--device-description", help="device description xml file") group.add_argument("-k", "--hwsku", help="HwSKU") + parser.add_argument("-n", "--namespace", help="namespace name", nargs='?', const=None, default=None) parser.add_argument("-p", "--port-config", help="port config file, used with -m or -k", nargs='?', const=None) + parser.add_argument("-S", "--hwsku-config", help="hwsku config file, used with -p and -m or -k", nargs='?', const=None) parser.add_argument("-y", "--yaml", help="yaml file that contains additional variables", action='append', default=[]) parser.add_argument("-j", "--json", help="json file that contains additional variables", action='append', default=[]) parser.add_argument("-a", "--additional-data", help="addition data, in json string") @@ -203,51 +272,72 @@ def main(): parser.add_argument("-H", "--platform-info", help="read platform and hardware info", action='store_true') parser.add_argument("-s", "--redis-unix-sock-file", help="unix sock file for redis connection") group = parser.add_mutually_exclusive_group() - group.add_argument("-t", "--template", help="render the data with the template file") + group.add_argument("-t", "--template", help="render the data with the template file", action="append", default=[], + type=lambda opt_value: tuple(opt_value.split(',')) if ',' in opt_value else (opt_value, sys.stdout)) + parser.add_argument("-T", "--template_dir", help="search base for the template files", action='store') group.add_argument("-v", "--var", help="print the value of a variable, support jinja2 expression") group.add_argument("--var-json", help="print the value of a variable, in json format") - group.add_argument("-w", "--write-to-db", help="write config into configdb", action='store_true') - group.add_argument("--print-data", help="print all data", action='store_true') group.add_argument("--preset", help="generate sample configuration from a preset template", choices=get_available_config()) group = parser.add_mutually_exclusive_group() + group.add_argument("--print-data", help="print all data", action='store_true') + group.add_argument("-w", "--write-to-db", help="write config into configdb", action='store_true') group.add_argument("-K", "--key", help="Lookup for a specific key") args = parser.parse_args() - platform = get_platform_info(get_machine_info()) + platform = device_info.get_platform() db_kwargs = {} - if args.redis_unix_sock_file != None: + if args.redis_unix_sock_file is not None: db_kwargs['unix_socket_path'] = args.redis_unix_sock_file data = {} hwsku = args.hwsku + asic_name = args.namespace + asic_id = None + if asic_name is not None: + asic_id = get_asic_id_from_name(asic_name) + # get the namespace ID + namespace_id = os.getenv("NAMESPACE_ID") + if namespace_id: + deep_update(data, { + 'DEVICE_METADATA': { + 'localhost': {'namespace_id': namespace_id} + } + }) + # Load the database config for the namespace from global database json + if args.namespace is not None: + SonicDBConfig.load_sonic_global_db_config(namespace=args.namespace) if hwsku is not None: hardware_data = {'DEVICE_METADATA': {'localhost': { 'hwsku': hwsku }}} deep_update(data, hardware_data) - (ports, _) = get_port_config(hwsku, platform, args.port_config) + if args.port_config is None: + args.port_config = device_info.get_path_to_port_config_file(hwsku) + (ports, _, _) = get_port_config(hwsku, platform, args.port_config, asic_id) if not ports: print('Failed to get port config', file=sys.stderr) 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))) + brkout_table = get_breakout_mode(hwsku, platform, args.port_config) + if brkout_table is not None: + deep_update(data, {'BREAKOUT_CFG': brkout_table}) - if args.minigraph != None: + _process_json(args, data) + + if args.minigraph is not None: minigraph = args.minigraph if platform: - if args.port_config != None: - deep_update(data, parse_xml(minigraph, platform, args.port_config)) + if args.port_config is not None: + deep_update(data, parse_xml(minigraph, platform, args.port_config, asic_name=asic_name, hwsku_config_file=args.hwsku_config)) else: - deep_update(data, parse_xml(minigraph, platform)) + deep_update(data, parse_xml(minigraph, platform, asic_name=asic_name)) else: - deep_update(data, parse_xml(minigraph, port_config_file=args.port_config)) + deep_update(data, parse_xml(minigraph, port_config_file=args.port_config, asic_name=asic_name, hwsku_config_file=args.hwsku_config)) - if args.device_description != None: + if args.device_description is not None: deep_update(data, parse_device_desc_xml(args.device_description)) for yaml_file in args.yaml: @@ -258,58 +348,82 @@ def main(): additional_data = yaml.load(stream) deep_update(data, FormatConverter.to_deserialized(additional_data)) - if args.additional_data != None: + if args.additional_data is not None: deep_update(data, json.loads(args.additional_data)) if args.from_db: - configdb = ConfigDBConnector(**db_kwargs) + if args.namespace is None: + configdb = ConfigDBPipeConnector(use_unix_socket_path=True, **db_kwargs) + else: + configdb = ConfigDBPipeConnector(use_unix_socket_path=True, namespace=args.namespace, **db_kwargs) + configdb.connect() deep_update(data, FormatConverter.db_to_output(configdb.get_config())) + + # the minigraph file must be provided to get the mac address for backend asics if args.platform_info: + asic_role = None + if asic_name is not None: + if args.minigraph is not None: + asic_role = parse_asic_sub_role(args.minigraph, asic_name) + + if asic_role is not None and asic_role.lower() == "backend": + mac = device_info.get_system_mac(namespace=asic_name) + else: + mac = device_info.get_system_mac() + else: + mac = device_info.get_system_mac() + hardware_data = {'DEVICE_METADATA': {'localhost': { 'platform': platform, - 'mac': get_system_mac() + 'mac': mac, }}} + # The ID needs to be passed to the SAI to identify the asic. + if asic_name is not None: + hardware_data['DEVICE_METADATA']['localhost'].update(asic_id=asic_id) deep_update(data, hardware_data) - if args.template != None: - template_file = os.path.abspath(args.template) - paths = ['/', '/usr/share/sonic/templates', os.path.dirname(template_file)] - loader = jinja2.FileSystemLoader(paths) - - redis_bcc = RedisBytecodeCache(SonicV2Connector(host='127.0.0.1')) - env = jinja2.Environment(loader=loader, trim_blocks=True, bytecode_cache=redis_bcc) - env.filters['sort_by_port_index'] = sort_by_port_index - env.filters['ipv4'] = is_ipv4 - env.filters['ipv6'] = is_ipv6 - env.filters['unique_name'] = unique_name - env.filters['pfx_filter'] = pfx_filter - env.filters['ip_network'] = ip_network - for attr in ['ip', 'network', 'prefixlen', 'netmask']: - env.filters[attr] = partial(prefix_attr, attr) - template = env.get_template(template_file) - print(template.render(sort_data(data))) - - if args.var != None: + paths = ['/', '/usr/share/sonic/templates'] + if args.template_dir: + paths.append(os.path.abspath(args.template_dir)) + + if args.template: + for template_file, _ in args.template: + paths.append(os.path.dirname(os.path.abspath(template_file))) + env = _get_jinja2_env(paths) + for template_file, dest_file in args.template: + template = env.get_template(os.path.basename(template_file)) + template_data = template.render(data) + if dest_file == "config-db": + deep_update(data, FormatConverter.to_deserialized(json.loads(template_data))) + else: + with smart_open(dest_file, 'w') as df: + print(template_data, file=df) + + if args.var is not None: template = jinja2.Template('{{' + args.var + '}}') print(template.render(data)) - if args.var_json != None: - if args.key != None: + if args.var_json is not None and args.var_json in data: + if args.key is not None: print(json.dumps(FormatConverter.to_serialized(data[args.var_json], args.key), indent=4, cls=minigraph_encoder)) else: print(json.dumps(FormatConverter.to_serialized(data[args.var_json]), indent=4, cls=minigraph_encoder)) if args.write_to_db: - configdb = ConfigDBConnector(**db_kwargs) + if args.namespace is None: + configdb = ConfigDBPipeConnector(use_unix_socket_path=True, **db_kwargs) + else: + configdb = ConfigDBPipeConnector(use_unix_socket_path=True, namespace=args.namespace, **db_kwargs) + configdb.connect(False) configdb.mod_config(FormatConverter.output_to_db(data)) if args.print_data: print(json.dumps(FormatConverter.to_serialized(data), indent=4, cls=minigraph_encoder)) - if args.preset != None: + if args.preset is not None: data = generate_sample_config(data, args.preset) print(json.dumps(FormatConverter.to_serialized(data), indent=4, cls=minigraph_encoder)) diff --git a/src/sonic-config-engine/sonic_device_util.py b/src/sonic-config-engine/sonic_device_util.py deleted file mode 100644 index 34877600fd13..000000000000 --- a/src/sonic-config-engine/sonic_device_util.py +++ /dev/null @@ -1,120 +0,0 @@ -#!/usr/bin/env python -import os -import yaml -import subprocess -import re - -DOCUMENTATION = ''' ---- -module: sonic_device_util -version_added: "1.9" -short_description: Retrieve device related facts for a device. -description: - - Retrieve device related facts from config files. -''' - -''' -TODO: this file shall be renamed and moved to other places in future -to have it shared with multiple applications. -''' -def get_machine_info(): - if not os.path.isfile('/host/machine.conf'): - return None - machine_vars = {} - with open('/host/machine.conf') as machine_file: - for line in machine_file: - tokens = line.split('=') - if len(tokens) < 2: - continue - machine_vars[tokens[0]] = tokens[1].strip() - return machine_vars - -def get_platform_info(machine_info): - if machine_info != None: - if machine_info.has_key('onie_platform'): - return machine_info['onie_platform'] - elif machine_info.has_key('aboot_platform'): - return machine_info['aboot_platform'] - return None - -def get_sonic_version_info(): - if not os.path.isfile('/etc/sonic/sonic_version.yml'): - return None - data = {} - with open('/etc/sonic/sonic_version.yml') as stream: - if yaml.__version__ >= "5.1": - data = yaml.full_load(stream) - else: - data = yaml.load(stream) - return data - -def valid_mac_address(mac): - return bool(re.match("^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$", mac)) - -def get_system_mac(): - version_info = get_sonic_version_info() - - if (version_info['asic_type'] == 'mellanox'): - # With Mellanox ONIE release(2019.05-5.2.0012) and above - # "onie_base_mac" was added to /host/machine.conf: - # onie_base_mac=e4:1d:2d:44:5e:80 - # So we have another way to get the mac address besides decode syseeprom - # By this can mitigate the dependency on the hw-management service - base_mac_key = "onie_base_mac" - machine_vars = get_machine_info() - if machine_vars is not None and base_mac_key in machine_vars: - mac = machine_vars[base_mac_key] - mac = mac.strip() - if valid_mac_address(mac): - return mac - - hw_mac_entry_cmds = [ "sudo decode-syseeprom -m" ] - elif (version_info['asic_type'] == 'marvell'): - # Try valid mac in eeprom, else fetch it from eth0 - platform = get_platform_info(get_machine_info()) - hwsku = get_machine_info()['onie_machine'] - profile_cmd = 'cat /usr/share/sonic/device/' + platform +'/'+ hwsku +'/profile.ini | cut -f2 -d=' - hw_mac_entry_cmds = [ profile_cmd, "sudo decode-syseeprom -m", "ip link show eth0 | grep ether | awk '{print $2}'" ] - else: - hw_mac_entry_cmds = [ "ip link show eth0 | grep ether | awk '{print $2}'" ] - - for get_mac_cmd in hw_mac_entry_cmds: - proc = subprocess.Popen(get_mac_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - (mac, err) = proc.communicate() - if err: - continue - mac = mac.strip() - if valid_mac_address(mac): - break - - if not valid_mac_address(mac): - return None - - # Align last byte of MAC if necessary - if version_info and version_info['asic_type'] == 'centec': - last_byte = mac[-2:] - aligned_last_byte = format(int(int(last_byte, 16) & 0b11000000), '02x') - mac = mac[:-2] + aligned_last_byte - return mac - -# -# Function to obtain the routing-stack being utilized. Function is not -# platform-specific; it's being placed in this file temporarily till a more -# suitable location is identified as part of upcoming refactoring efforts. -# -def get_system_routing_stack(): - command = "sudo docker ps | grep bgp | awk '{print$2}' | cut -d'-' -f3 | cut -d':' -f1" - - try: - proc = subprocess.Popen(command, - stdout=subprocess.PIPE, - shell=True, - stderr=subprocess.STDOUT) - stdout = proc.communicate()[0] - proc.wait() - result = stdout.rstrip('\n') - - except OSError, e: - raise OSError("Cannot detect routing-stack") - - return result diff --git a/src/sonic-config-engine/tests/common_utils.py b/src/sonic-config-engine/tests/common_utils.py new file mode 100644 index 000000000000..3d8a3029dad9 --- /dev/null +++ b/src/sonic-config-engine/tests/common_utils.py @@ -0,0 +1,33 @@ +import json +import re +import sys + +PY3x = sys.version_info >= (3, 0) +PYvX_DIR = "py3" if PY3x else "py2" +PYTHON_INTERPRETTER = "python3" if PY3x else "python2" + +def tuple_to_str(tuplestr): + """ Convert Python tuple '('elem1', 'elem2')' representation into string on the for "elem1|elem2" """ + def to_str(tupleobj): + tupleobj = re.sub(r"([\(\)])", '"', tupleobj.group(0)) + return re.sub(r"( *, *)", '|', tupleobj).replace("'", '') + + return re.sub(r"(\(.*?\))", to_str, tuplestr) + +def to_dict(dictstr): + """ Convert string represention of Python dict into dict """ + # handle tuple elements + dictstr = tuple_to_str(dictstr) + + return json.loads(dictstr.replace("'", '"')) + +def liststr_to_dict(liststr): + """ Convert string represention of Python list into dict with list key and sorted liststr as its value """ + # handle tuple elements + liststr = tuple_to_str(liststr) + + list_obj = json.loads("{\"list\":" + liststr.replace("'", '"') +'}') + list_obj["list"] = sorted(list_obj["list"]) + + return list_obj + diff --git a/src/sonic-config-engine/tests/data/lldp/mgmt_iface_ipv4.json b/src/sonic-config-engine/tests/data/lldp/mgmt_iface_ipv4.json new file mode 100644 index 000000000000..c38b677aad7a --- /dev/null +++ b/src/sonic-config-engine/tests/data/lldp/mgmt_iface_ipv4.json @@ -0,0 +1,12 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "hostname": "switch-t0" + } + }, + "MGMT_INTERFACE": { + "eth0|10.0.0.100/24": { + "gwaddr": "10.0.0.100" + } + } +} diff --git a/src/sonic-config-engine/tests/data/lldp/mgmt_iface_ipv4_and_ipv6.json b/src/sonic-config-engine/tests/data/lldp/mgmt_iface_ipv4_and_ipv6.json new file mode 100644 index 000000000000..87f887fb870d --- /dev/null +++ b/src/sonic-config-engine/tests/data/lldp/mgmt_iface_ipv4_and_ipv6.json @@ -0,0 +1,15 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "hostname": "switch-t0" + } + }, + "MGMT_INTERFACE": { + "eth0|10.0.0.100/24": { + "gwaddr": "10.0.0.100" + }, + "eth0|2603:10e2:0:2902::8/64": { + "gwaddr": "2603:10e2:0:2902::8" + } + } +} diff --git a/src/sonic-config-engine/tests/data/lldp/mgmt_iface_ipv6.json b/src/sonic-config-engine/tests/data/lldp/mgmt_iface_ipv6.json new file mode 100644 index 000000000000..c1dd4964c6bf --- /dev/null +++ b/src/sonic-config-engine/tests/data/lldp/mgmt_iface_ipv6.json @@ -0,0 +1,12 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "hostname": "switch-t0" + } + }, + "MGMT_INTERFACE": { + "eth0|2603:10e2:0:2902::8/64": { + "gwaddr": "2603:10e2:0:2902::8" + } + } +} diff --git a/src/sonic-config-engine/tests/data/ndppd/vlan_interfaces.json b/src/sonic-config-engine/tests/data/ndppd/vlan_interfaces.json new file mode 100644 index 000000000000..d45214827642 --- /dev/null +++ b/src/sonic-config-engine/tests/data/ndppd/vlan_interfaces.json @@ -0,0 +1,20 @@ +{ + "VLAN_INTERFACE": { + "Vlan1000": { + "proxy_arp": "enabled" + }, + "Vlan1000|192.168.0.1/21": {}, + "Vlan1000|fc01:1000::1/64": {}, + "Vlan1000|fc02:1000::1/64": {}, + "Vlan1000|fc03:1000::1/64": {}, + "Vlan2000": { + "proxy_arp": "enabled" + }, + "Vlan2000|fc01:2000::1/64": {}, + "Vlan3000|fc01:3000::1/64": {}, + "Vlan4000": { + "proxy_arp": "disabled" + }, + "Vlan4000|fc01:4000::1/64": {} + } +} \ No newline at end of file diff --git a/src/sonic-config-engine/tests/data/pfx_filter/param_1.json b/src/sonic-config-engine/tests/data/pfx_filter/param_1.json new file mode 100644 index 000000000000..ce6cd21886a2 --- /dev/null +++ b/src/sonic-config-engine/tests/data/pfx_filter/param_1.json @@ -0,0 +1,12 @@ +{ + "VLAN_INTERFACE": { + "Vlan1": {}, + "Vlan1|1.1.1.1/32": {}, + "Vlan2": {}, + "Vlan2|2.2.2.2": {}, + "Vlan3": {}, + "Vlan3|fc00::1": {}, + "Vlan4": {}, + "Vlan4|fc00::2/64": {} + } +} diff --git a/src/sonic-config-engine/tests/data/pfx_filter/result_1.txt b/src/sonic-config-engine/tests/data/pfx_filter/result_1.txt new file mode 100644 index 000000000000..d8ea7d304222 --- /dev/null +++ b/src/sonic-config-engine/tests/data/pfx_filter/result_1.txt @@ -0,0 +1,5 @@ +"Vlan1"="1.1.1.1/32" +"Vlan2"="2.2.2.2/32" +"Vlan3"="fc00::1/128" +"Vlan4"="fc00::2/64" + diff --git a/src/sonic-config-engine/tests/data/pfx_filter/tmpl_1.txt.j2 b/src/sonic-config-engine/tests/data/pfx_filter/tmpl_1.txt.j2 new file mode 100644 index 000000000000..2612fe4a2936 --- /dev/null +++ b/src/sonic-config-engine/tests/data/pfx_filter/tmpl_1.txt.j2 @@ -0,0 +1,3 @@ +{% for intf, addr in VLAN_INTERFACE|pfx_filter %} +"{{ intf }}"="{{ addr }}" +{% endfor %} diff --git a/src/sonic-config-engine/tests/fg-ecmp-sample-minigraph.xml b/src/sonic-config-engine/tests/fg-ecmp-sample-minigraph.xml new file mode 100644 index 000000000000..f8fcf1e0fce7 --- /dev/null +++ b/src/sonic-config-engine/tests/fg-ecmp-sample-minigraph.xml @@ -0,0 +1,1591 @@ + + + + + + + false + str2-sn3800-azd + 10.0.0.56 + ARISTA01T1 + 10.0.0.57 + 1 + 10 + 3 + + + str2-sn3800-azd + FC00::71 + ARISTA01T1 + FC00::72 + 1 + 10 + 3 + + + false + str2-sn3800-azd + 10.0.0.58 + ARISTA02T1 + 10.0.0.59 + 1 + 10 + 3 + + + str2-sn3800-azd + FC00::75 + ARISTA02T1 + FC00::76 + 1 + 10 + 3 + + + false + str2-sn3800-azd + 10.0.0.60 + ARISTA03T1 + 10.0.0.61 + 1 + 10 + 3 + + + str2-sn3800-azd + FC00::79 + ARISTA03T1 + FC00::7A + 1 + 10 + 3 + + + false + str2-sn3800-azd + 10.0.0.62 + ARISTA04T1 + 10.0.0.63 + 1 + 10 + 3 + + + str2-sn3800-azd + FC00::7D + ARISTA04T1 + FC00::7E + 1 + 10 + 3 + + + + + 65100 + str2-sn3800-azd + + +
10.0.0.57
+ + + +
+ +
10.0.0.59
+ + + +
+ +
10.0.0.61
+ + + +
+ +
10.0.0.63
+ + + +
+ + BGPPeer +
10.1.0.32
+ + + + BGPSLBPassive + 10.255.0.0/25 +
+ + BGPPeer +
10.1.0.32
+ + + + BGPVac + 192.168.0.0/21 +
+
+ +
+ + 64600 + ARISTA01T1 + + + + 64600 + ARISTA02T1 + + + + 64600 + ARISTA03T1 + + + + 64600 + ARISTA04T1 + + +
+
+ + + + + + HostIP + Loopback0 + + 10.1.0.32/32 + + 10.1.0.32/32 + + + HostIP1 + Loopback0 + + FC00:1::32/128 + + FC00:1::32/128 + + + + + HostIP + eth0 + + 10.3.146.183/23 + + 10.3.146.183/23 + + + V6HostIP + eth0 + + FC00:2::32/64 + + FC00:2::32/64 + + + + + + + str2-sn3800-azd + + + PortChannel0001 + etp29 + + + + PortChannel0002 + etp30 + + + + PortChannel0003 + etp31 + + + + PortChannel0004 + etp32 + + + + + + Vlan1000 + etp2;etp3;etp4;etp5;etp6;etp7;etp8;etp9;etp10;etp11;etp12;etp13;etp14;etp15;etp16;etp17;etp18;etp19;etp20;etp21;etp22;etp23;etp24;etp25 + False + 0.0.0.0/0 + + 192.0.0.1;192.0.0.2;192.0.0.3;192.0.0.4;192.0.0.5;192.0.0.6;192.0.0.7;192.0.0.8;192.0.0.9;192.0.0.10;192.0.0.11;192.0.0.12;192.0.0.13;192.0.0.14;192.0.0.15;192.0.0.16;192.0.0.17;192.0.0.18;192.0.0.19;192.0.0.20;192.0.0.21;192.0.0.22;192.0.0.23;192.0.0.24;192.0.0.25;192.0.0.26;192.0.0.27;192.0.0.28;192.0.0.29;192.0.0.30;192.0.0.31;192.0.0.32;192.0.0.33;192.0.0.34;192.0.0.35;192.0.0.36;192.0.0.37;192.0.0.38;192.0.0.39;192.0.0.40;192.0.0.41;192.0.0.42;192.0.0.43;192.0.0.44;192.0.0.45;192.0.0.46;192.0.0.47;192.0.0.48 + 1000 + 1000 + 192.168.0.0/21 + + + + + + PortChannel0001 + 10.0.0.56/31 + + + + PortChannel0001 + FC00::71/126 + + + + PortChannel0002 + 10.0.0.58/31 + + + + PortChannel0002 + FC00::75/126 + + + + PortChannel0003 + 10.0.0.60/31 + + + + PortChannel0003 + FC00::79/126 + + + + PortChannel0004 + 10.0.0.62/31 + + + + PortChannel0004 + FC00::7D/126 + + + + Vlan1000 + 192.168.0.1/21 + + + + Vlan31 + 200.200.200.0/27 + + + + + + SNMP_ACL + SNMP + SNMP + + + ERSPAN + fg-ecmp-sample-minigraphfg-ecmp-sample-minigraph + Everflow + Everflow + + + ERSPANV6 + EverflowV6 + EverflowV6 + + + VTY_LINE + ssh-only + SSH + + + PortChannel0001;PortChannel0002;PortChannel0003;PortChannel0004 + DataAcl + DataPlane + + + + + + false + 100.50.25.12/32 + FineGrainedECMPGroupDestination + + + true + 2603:10b0:10d:e07::/64 + DeviceAggregate + + + false + fc:5::/128 + FineGrainedECMPGroupDestination + + + + + IPNextHop + + etp10 +
200.200.200.1
+ FineGrainedECMPGroupMember +
+ + IPNextHop + + etp11 +
200.200.200.2
+ FineGrainedECMPGroupMember +
+ + IPNextHop + + etp12 +
200.200.200.3
+ FineGrainedECMPGroupMember +
+ + IPNextHop + + etp13 +
200.200.200.4
+ FineGrainedECMPGroupMember +
+ + IPNextHop + + etp14 +
200.200.200.5
+ FineGrainedECMPGroupMember +
+ + IPNextHop + + etp15 +
200.200.200.6
+ FineGrainedECMPGroupMember +
+ + IPNextHop + + etp16 +
200.200.200.7
+ FineGrainedECMPGroupMember +
+ + IPNextHop + + etp17 +
200.200.200.8
+ FineGrainedECMPGroupMember +
+ + IPNextHop + + etp18 +
200.200.200.9
+ FineGrainedECMPGroupMember +
+ + IPNextHop + + etp19 +
200.200.200.10
+ FineGrainedECMPGroupMember +
+ + IPNextHop + + etp10 +
200:200:200:200::1
+ FineGrainedECMPGroupMember +
+ + IPNextHop + + etp11 +
200:200:200:200::2
+ FineGrainedECMPGroupMember +
+ + IPNextHop + + etp12 +
200:200:200:200::3
+ FineGrainedECMPGroupMember +
+ + IPNextHop + + etp13 +
200:200:200:200::4
+ FineGrainedECMPGroupMember +
+ + IPNextHop + + etp14 +
200:200:200:200::5
+ FineGrainedECMPGroupMember +
+ + IPNextHop + + etp15 +
200:200:200:200::6
+ FineGrainedECMPGroupMember +
+ + IPNextHop + + etp16 +
200:200:200:200::7
+ FineGrainedECMPGroupMember +
+ + IPNextHop + + etp17 +
200:200:200:200::8
+ FineGrainedECMPGroupMember +
+ + IPNextHop + + etp18 +
200:200:200:200::9
+ FineGrainedECMPGroupMember +
+ + IPNextHop + + etp19 +
200:200:200:200::10
+ FineGrainedECMPGroupMember +
+
+
+
+ + + + DeviceInterfaceLink + ARISTA01T1 + Ethernet1 + str2-sn3800-azd + etp29 + + + DeviceInterfaceLink + ARISTA02T1 + Ethernet1 + str2-sn3800-azd + etp30 + + + DeviceInterfaceLink + ARISTA03T1 + Ethernet1 + str2-sn3800-azd + etp31 + + + DeviceInterfaceLink + ARISTA04T1 + Ethernet1 + str2-sn3800-azd + etp32 + + + DeviceInterfaceLink + str2-sn3800-azd + etp2 + Servers0 + eth0 + + + DeviceInterfaceLink + str2-sn3800-azd + etp5 + Servers3 + eth0 + + + DeviceInterfaceLink + str2-sn3800-azd + etp6 + Servers4 + eth0 + + + DeviceInterfaceLink + str2-sn3800-azd + etp9 + Servers7 + eth0 + + + DeviceInterfaceLink + str2-sn3800-azd + etp10 + Servers10 + eth0 + + + DeviceInterfaceLink + str2-sn3800-azd + etp11 + Servers11 + eth0 + + + DeviceInterfaceLink + str2-sn3800-azd + etp12 + Servers10 + eth0 + + + DeviceInterfaceLink + str2-sn3800-azd + etp13 + Servers11 + eth0 + + + DeviceInterfaceLink + str2-sn3800-azd + etp14 + Servers10 + eth0 + + + DeviceInterfaceLink + str2-sn3800-azd + etp15 + Servers11 + eth0 + + + DeviceInterfaceLink + str2-sn3800-azd + etp16 + Servers10 + eth0 + + + DeviceInterfaceLink + str2-sn3800-azd + etp17 + Servers11 + eth0 + + + DeviceInterfaceLink + str2-sn3800-azd + etp18 + Servers10 + eth0 + + + DeviceInterfaceLink + str2-sn3800-azd + etp19 + Servers11 + eth0 + + + DeviceInterfaceLink + str2-sn3800-azd + etp20 + Servers10 + eth0 + + + DeviceInterfaceLink + str2-sn3800-azd + etp21 + Servers11 + eth0 + + + DeviceInterfaceLink + str2-sn3800-azd + etp22 + Servers20 + eth0 + + + DeviceInterfaceLink + str2-sn3800-azd + etp23 + Servers21 + eth0 + + + DeviceInterfaceLink + str2-sn3800-azd + etp24 + Servers22 + eth0 + + + DeviceInterfaceLink + str2-sn3800-azd + etp25 + Servers23 + eth0 + + + + + str2-sn3800-azd + ACS-MSN3800 + + 10.3.146.183 + + + + ARISTA04T1 + + 172.16.134.63 + + Arista-VM + + + ARISTA03T1 + + 172.16.134.62 + + Arista-VM + + + ARISTA02T1 + + 172.16.134.61 + + Arista-VM + + + ARISTA01T1 + + 172.16.134.60 + + Arista-VM + + + + + + true + + + DeviceInterface + + true + true + 1 + etp1 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp2 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp3 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp4 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp5 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp6 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp7 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp8 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp9 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp10 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp11 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp12 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp13 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp14 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp15 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp16 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp17 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp18 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp19 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp20 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp21 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp22 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp23 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp24 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp25 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp26 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp27 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp28 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp29 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp30 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp31 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp32 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp33 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp34 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp35 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp36 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp37 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp38 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp39 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp40 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp41 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp42 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp43 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp44 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp45 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp46 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp47 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp48 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp49 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp50 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp51 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp52 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp53 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp54 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp55 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp56 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp57 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp58 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp59 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp60 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp61 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp62 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp63 + + false + 0 + 0 + 100000 + + + DeviceInterface + + true + true + 1 + etp64 + + false + 0 + 0 + 100000 + + + true + 0 + ACS-MSN3800 + + + + + + + str2-sn3800-azd + + + DeploymentId + + 26 + + + QosProfile + + Profile0 + + + DhcpResources + + 192.0.0.1;192.0.0.2;192.0.0.3;192.0.0.4;192.0.0.5;192.0.0.6;192.0.0.7;192.0.0.8;192.0.0.9;192.0.0.10;192.0.0.11;192.0.0.12;192.0.0.13;192.0.0.14;192.0.0.15;192.0.0.16;192.0.0.17;192.0.0.18;192.0.0.19;192.0.0.20;192.0.0.21;192.0.0.22;192.0.0.23;192.0.0.24;192.0.0.25;192.0.0.26;192.0.0.27;192.0.0.28;192.0.0.29;192.0.0.30;192.0.0.31;192.0.0.32;192.0.0.33;192.0.0.34;192.0.0.35;192.0.0.36;192.0.0.37;192.0.0.38;192.0.0.39;192.0.0.40;192.0.0.41;192.0.0.42;192.0.0.43;192.0.0.44;192.0.0.45;192.0.0.46;192.0.0.47;192.0.0.48 + + + NtpResources + + 10.20.8.129;10.20.8.130 + + + SnmpResources + + 10.3.145.98 + + + SyslogResources + + 10.3.145.8;100.127.20.21 + + + TacacsGroup + + Starlab + + + TacacsServer + + 100.127.20.21 + + + ForcedMgmtRoutes + + 10.3.145.98/31;10.3.145.8;100.127.20.16/28;10.3.149.170/31;40.122.216.24;13.91.48.226;10.3.145.14 + + + ErspanDestinationIpv4 + + 10.20.6.16 + + + + + + + str2-sn3800-azd + ACS-MSN3800 +
\ No newline at end of file diff --git a/src/sonic-config-engine/tests/mellanox-sample-port-config.ini b/src/sonic-config-engine/tests/mellanox-sample-port-config.ini new file mode 100644 index 000000000000..2af5aa67ff3a --- /dev/null +++ b/src/sonic-config-engine/tests/mellanox-sample-port-config.ini @@ -0,0 +1,65 @@ +# name lanes alias index +Ethernet0 0,1,2,3 etp1 1 +Ethernet4 4,5,6,7 etp2 2 +Ethernet8 8,9,10,11 etp3 3 +Ethernet12 12,13,14,15 etp4 4 +Ethernet16 16,17,18,19 etp5 5 +Ethernet20 20,21,22,23 etp6 6 +Ethernet24 24,25,26,27 etp7 7 +Ethernet28 28,29,30,31 etp8 8 +Ethernet32 32,33,34,35 etp9 9 +Ethernet36 36,37,38,39 etp10 10 +Ethernet40 40,41,42,43 etp11 11 +Ethernet44 44,45,46,47 etp12 12 +Ethernet48 48,49,50,51 etp13 13 +Ethernet52 52,53,54,55 etp14 14 +Ethernet56 56,57,58,59 etp15 15 +Ethernet60 60,61,62,63 etp16 16 +Ethernet64 64,65,66,67 etp17 17 +Ethernet68 68,69,70,71 etp18 18 +Ethernet72 72,73,74,75 etp19 19 +Ethernet76 76,77,78,79 etp20 20 +Ethernet80 80,81,82,83 etp21 21 +Ethernet84 84,85,86,87 etp22 22 +Ethernet88 88,89,90,91 etp23 23 +Ethernet92 92,93,94,95 etp24 24 +Ethernet96 96,97,98,99 etp25 25 +Ethernet100 100,101,102,103 etp26 26 +Ethernet104 104,105,106,107 etp27 27 +Ethernet108 108,109,110,111 etp28 28 +Ethernet112 112,113,114,115 etp29 29 +Ethernet116 116,117,118,119 etp30 30 +Ethernet120 120,121,122,123 etp31 31 +Ethernet124 124,125,126,127 etp32 32 +Ethernet128 128,129,130,131 etp33 33 +Ethernet132 132,133,134,135 etp34 34 +Ethernet136 136,137,138,139 etp35 35 +Ethernet140 140,141,142,143 etp36 36 +Ethernet144 144,145,146,147 etp37 37 +Ethernet148 148,149,150,151 etp38 38 +Ethernet152 152,153,154,155 etp39 39 +Ethernet156 156,157,158,159 etp40 40 +Ethernet160 160,161,162,163 etp41 41 +Ethernet164 164,165,166,167 etp42 42 +Ethernet168 168,169,170,171 etp43 43 +Ethernet172 172,173,174,175 etp44 44 +Ethernet176 176,177,178,179 etp45 45 +Ethernet180 180,181,182,183 etp46 46 +Ethernet184 184,185,186,187 etp47 47 +Ethernet188 188,189,190,191 etp48 48 +Ethernet192 192,193,194,195 etp49 49 +Ethernet196 196,197,198,199 etp50 50 +Ethernet200 200,201,202,203 etp51 51 +Ethernet204 204,205,206,207 etp52 52 +Ethernet208 208,209,210,211 etp53 53 +Ethernet212 212,213,214,215 etp54 54 +Ethernet216 216,217,218,219 etp55 55 +Ethernet220 220,221,222,223 etp56 56 +Ethernet224 224,225,226,227 etp57 57 +Ethernet228 228,229,230,231 etp58 58 +Ethernet232 232,233,234,235 etp59 59 +Ethernet236 236,237,238,239 etp60 60 +Ethernet240 240,241,242,243 etp61 61 +Ethernet244 244,245,246,247 etp62 62 +Ethernet248 248,249,250,251 etp63 63 +Ethernet252 252,253,254,255 etp64 64 \ No newline at end of file diff --git a/src/sonic-config-engine/tests/multi_npu_data/py2/ipinip.json b/src/sonic-config-engine/tests/multi_npu_data/py2/ipinip.json new file mode 100644 index 000000000000..3e8d4429d77d --- /dev/null +++ b/src/sonic-config-engine/tests/multi_npu_data/py2/ipinip.json @@ -0,0 +1,23 @@ +[ + { + "TUNNEL_DECAP_TABLE:IPINIP_TUNNEL" : { + "tunnel_type":"IPINIP", + "dst_ip":"10.0.0.0,10.1.0.1,10.1.0.3,10.1.0.32,8.0.0.0", + "dscp_mode":"pipe", + "ecn_mode":"copy_from_outer", + "ttl_mode":"pipe" + }, + "OP": "SET" + } + , + { + "TUNNEL_DECAP_TABLE:IPINIP_V6_TUNNEL" : { + "tunnel_type":"IPINIP", + "dst_ip":"fc00:1::32,fc00::1,fd00:1::32", + "dscp_mode":"pipe", + "ecn_mode":"copy_from_outer", + "ttl_mode":"pipe" + }, + "OP": "SET" + } +] diff --git a/src/sonic-config-engine/tests/multi_npu_data/py3/ipinip.json b/src/sonic-config-engine/tests/multi_npu_data/py3/ipinip.json new file mode 100644 index 000000000000..3e8d4429d77d --- /dev/null +++ b/src/sonic-config-engine/tests/multi_npu_data/py3/ipinip.json @@ -0,0 +1,23 @@ +[ + { + "TUNNEL_DECAP_TABLE:IPINIP_TUNNEL" : { + "tunnel_type":"IPINIP", + "dst_ip":"10.0.0.0,10.1.0.1,10.1.0.3,10.1.0.32,8.0.0.0", + "dscp_mode":"pipe", + "ecn_mode":"copy_from_outer", + "ttl_mode":"pipe" + }, + "OP": "SET" + } + , + { + "TUNNEL_DECAP_TABLE:IPINIP_V6_TUNNEL" : { + "tunnel_type":"IPINIP", + "dst_ip":"fc00:1::32,fc00::1,fd00:1::32", + "dscp_mode":"pipe", + "ecn_mode":"copy_from_outer", + "ttl_mode":"pipe" + }, + "OP": "SET" + } +] diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml b/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml new file mode 100644 index 000000000000..412262315b4e --- /dev/null +++ b/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml @@ -0,0 +1,1246 @@ + + + + + + false + multi_npu_platform_01 + 10.0.0.0 + 01T2 + 10.0.0.1 + 1 + 10 + 3 + + + multi_npu_platform_01 + FC00::1 + 01T2 + FC00::2 + 1 + 10 + 3 + + + false + multi_npu_platform_01 + 10.0.0.8 + 05T2 + 10.0.0.9 + 1 + 10 + 3 + + + multi_npu_platform_01 + FC00::9 + 05T2 + FC00::A + 1 + 10 + 3 + + + BGPSession + false + ASIC2 + 10.1.0.0 + ASIC0 + 10.1.0.1 + 1 + 0 + 0 + + + BGPSession + false + ASIC2 + 10.1.0.4 + ASIC1 + 10.1.0.5 + 1 + 0 + 0 + + + BGPSession + false + ASIC3 + 10.1.0.2 + ASIC0 + 10.1.0.3 + 1 + 0 + 0 + + + BGPSession + false + ASIC3 + 10.1.0.6 + ASIC1 + 10.1.0.7 + 1 + 0 + 0 + + + false + ASIC0 + 10.0.0.0 + 01T2 + 10.0.0.1 + 1 + 10 + 3 + + + ASIC0 + FC00::1 + 01T2 + FC00::2 + 1 + 10 + 3 + + + false + ASIC1 + 10.0.0.8 + 05T2 + 10.0.0.9 + 1 + 10 + 3 + + + ASIC1 + FC00::9 + 05T2 + FC00::A + 1 + 10 + 3 + + + + + 65100 + multi_npu_platform_01 + + +
10.0.0.1
+ + + +
+ +
10.0.0.9
+ + + +
+
+ +
+ + 65100 + + ASIC0 + + + BGPPeer +
10.1.0.1
+ + + +
+ + BGPPeer +
10.1.0.3
+ + + +
+ + BGPPeer +
10.0.0.1
+ + + +
+ + BGPPeer +
FC00::1
+ + + +
+
+ +
+ + 65100 + + ASIC1 + + + BGPPeer +
10.1.0.5
+ + + +
+ + BGPPeer +
10.1.0.7
+ + + +
+ + BGPPeer +
10.0.0.9
+ + + +
+ + BGPPeer +
FC00::A
+ + + +
+
+ +
+ + 65100 + + ASIC2 + + + BGPPeer +
10.1.0.0
+ + + +
+ + BGPPeer +
10.1.0.4
+ + + +
+
+ +
+ + 65100 + + ASIC3 + + + BGPPeer +
10.1.0.2
+ + + +
+ + BGPPeer +
10.1.0.6
+ + + +
+
+ +
+ + 65200 + 01T2 + + + + 65200 + 05T2 + + +
+
+ + + + + + HostIP + Loopback0 + + 10.1.0.32/32 + + 10.1.0.32/32 + + + HostIP1 + Loopback0 + + FC00:1::32/128 + + FC00:1::32/128 + + + + + HostIP + eth0 + + 3.10.147.150/23 + + 3.10.147.150/23 + + + V6HostIP + eth0 + + FC00:2::32/64 + + FC00:2::32/64 + + + + + + + multi_npu_platform_01 + + + PortChannel0002 + Ethernet1/1;Ethernet1/2 + + + + PortChannel0008 + Ethernet1/5;Ethernet1/6 + + + + + + + + PortChannel0002 + 10.0.0.0/31 + + + + PortChannel0002 + FC00::1/126 + + + + PortChannel0008 + 10.0.0.8/31 + + + + PortChannel0008 + FC00::9/126 + + + + + + SNMP_ACL + SNMP + SNMP + + + ERSPAN + Everflow + Everflow + + + ERSPANV6 + EverflowV6 + EverflowV6 + + + VTY_LINE + ssh-only + SSH + + + ;PortChannel0002;PortChannel0008 + DataAcl + DataPlane + + + + + + + + + + LoopbackInterface + HostIP + Loopback4096 + + 8.0.0.0/32 + + 8.0.0.0/32 + + + HostIP1 + Loopback4096 + + FD00:1::32/128 + + FD00:1::32/128 + + + + + + + + ASIC0 + + + PortChannelInterface + PortChannel4001 + Eth4-ASIC0;Eth5-ASIC0 + + + + PortChannelInterface + PortChannel4002 + Eth6-ASIC0;Eth7-ASIC0 + + + + PortChannelInterface + PortChannel0002 + Eth0-ASIC0;Eth1-ASIC0 + + + + + + + + IPInterface + + PortChannel4001 + 10.1.0.1/31 + + + IPInterface + + PortChannel4002 + 10.1.0.3/31 + + + + PortChannel0002 + 10.0.0.0/31 + + + + PortChannel0002 + FC00::1/126 + + + + + + + + + + + + LoopbackInterface + HostIP + Loopback4096 + + 8.0.0.1/32 + + 8.0.0.1/32 + + + HostIP1 + Loopback4096 + + FD00:2::32/128 + + FD00:2::32/128 + + + + + + + + ASIC1 + + + PortChannelInterface + PortChannel4003 + Eth4-ASIC1;Eth5-ASIC1 + + + + PortChannelInterface + PortChannel4004 + Eth6-ASIC1;Eth7-ASIC1 + + + + PortChannel0008 + Eth0-ASIC1;Eth1-ASIC1 + + + + + + + + IPInterface + + PortChannel4003 + 10.1.0.5/31 + + + IPInterface + + PortChannel4004 + 10.1.0.7/31 + + + + PortChannel0008 + 10.0.0.8/31 + + + + PortChannel0008 + FC00::9/126 + + + + + + + + + + + + LoopbackInterface + HostIP + Loopback4096 + + 8.0.0.4/32 + + 8.0.0.4/32 + + + HostIP1 + Loopback4096 + + FD00:3::32/128 + + FD00:3::32/128 + + + + + + + + ASIC2 + + + PortChannelInterface + PortChannel4009 + Eth0-ASIC2;Eth1-ASIC2 + + + + PortChannelInterface + PortChannel4010 + Eth2-ASIC2;Eth3-ASIC2 + + + + + + + + IPInterface + + PortChannel4009 + 10.1.0.0/31 + + + IPInterface + + PortChannel4010 + 10.1.0.4/31 + + + + + + + + + + + + LoopbackInterface + HostIP + Loopback4096 + + 8.0.0.5/32 + + 8.0.0.5/32 + + + HostIP1 + Loopback4096 + + FD00:4::32/128 + + FD00:4::32/128 + + + + + + + + ASIC3 + + + PortChannelInterface + PortChannel4013 + Eth0-ASIC3;Eth1-ASIC3 + + + + PortChannelInterface + PortChannel4014 + Eth2-ASIC3;Eth3-ASIC3 + + + + + + + + IPInterface + + PortChannel4013 + 10.1.0.2/31 + + + IPInterface + + PortChannel4014 + 10.1.0.6/31 + + + + + + + + + + + + DeviceInterfaceLink + 01T2 + Ethernet1 + multi_npu_platform_01 + Ethernet1/1 + + + DeviceInterfaceLink + 01T2 + Ethernet2 + multi_npu_platform_01 + Ethernet1/2 + + + DeviceInterfaceLink + 05T2 + Ethernet1 + multi_npu_platform_01 + Ethernet1/5 + + + DeviceInterfaceLink + 05T2 + Ethernet2 + multi_npu_platform_01 + Ethernet1/6 + + + DeviceInterfaceLink + 40000 + true + ASIC2 + Eth0-ASIC2 + true + ASIC0 + Eth4-ASIC0 + true + + + DeviceInterfaceLink + 40000 + true + ASIC2 + Eth1-ASIC2 + true + ASIC0 + Eth5-ASIC0 + true + + + DeviceInterfaceLink + 40000 + true + ASIC3 + Eth0-ASIC3 + true + ASIC0 + Eth6-ASIC0 + true + + + DeviceInterfaceLink + 40000 + true + ASIC3 + Eth1-ASIC3 + true + ASIC0 + Eth7-ASIC0 + true + + + DeviceInterfaceLink + 40000 + true + ASIC2 + Eth2-ASIC2 + true + ASIC1 + Eth4-ASIC1 + true + + + DeviceInterfaceLink + 40000 + true + ASIC2 + Eth3-ASIC2 + true + ASIC1 + Eth5-ASIC1 + true + + + DeviceInterfaceLink + 40000 + true + ASIC3 + Eth2-ASIC3 + true + ASIC1 + Eth6-ASIC1 + true + + + DeviceInterfaceLink + 40000 + true + ASIC3 + Eth3-ASIC3 + true + ASIC1 + Eth7-ASIC1 + true + + + DeviceInterfaceLink + 40000 + true + ASIC0 + Eth0-ASIC0 + true + multi_npu_platform_01 + Ethernet1/1 + true + + + DeviceInterfaceLink + 40000 + true + ASIC0 + Eth1-ASIC0 + true + multi_npu_platform_01 + Ethernet1/2 + true + + + DeviceInterfaceLink + 40000 + true + ASIC0 + Eth2-ASIC0 + true + multi_npu_platform_01 + Ethernet1/3 + true + + + DeviceInterfaceLink + 40000 + true + ASIC0 + Eth3-ASIC0 + true + multi_npu_platform_01 + Ethernet1/4 + true + + + DeviceInterfaceLink + 40000 + true + ASIC1 + Eth0-ASIC1 + true + multi_npu_platform_01 + Ethernet1/5 + true + + + DeviceInterfaceLink + 40000 + true + ASIC1 + Eth1-ASIC1 + true + multi_npu_platform_01 + Ethernet1/6 + true + + + DeviceInterfaceLink + 40000 + true + ASIC1 + Eth2-ASIC1 + true + multi_npu_platform_01 + Ethernet1/7 + true + + + DeviceInterfaceLink + 40000 + true + ASIC1 + Eth3-ASIC1 + true + multi_npu_platform_01 + Ethernet1/8 + true + + + + + multi_npu_platform_01 + multi-npu-01 + + 3.10.147.150 + + + + 07T2 + + 89.139.132.43 + + VM + + + 01T2 + + 89.139.132.40 + + VM + + + 05T2 + + 89.139.132.42 + + VM + + + 03T2 + + 89.139.132.41 + + VM + + + Asic +
+ 0.0.0.0/0 +
+ + ::/0 + + + + + + + + + + 0.0.0.0/0 + + + ::/0 + + + ASIC0 + multi-npu-asic +
+ + Asic +
+ 0.0.0.0/0 +
+ + ::/0 + + + + + + + + + + 0.0.0.0/0 + + + ::/0 + + + ASIC1 + multi-npu-asic +
+ + Asic +
+ 0.0.0.0/0 +
+ + ::/0 + + + + + + + + + + 0.0.0.0/0 + + + ::/0 + + + ASIC2 + multi-npu-asic +
+ + Asic +
+ 0.0.0.0/0 +
+ + ::/0 + + + + + + + + + + 0.0.0.0/0 + + + ::/0 + + + ASIC3 + multi-npu-asic +
+
+
+ + + true + + + DeviceInterface + + true + true + 1 + Ethernet1/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet1/2 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet1/3 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet1/4 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet1/5 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet1/6 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet1/7 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet1/8 + + false + 0 + 0 + 40000 + + + true + 0 + multi-npu-01 + + + + + + + multi_npu_platform_01 + + + DeploymentId + + 1 + + + QosProfile + + Profile0 + + + DhcpResources + + 169.118.23.1;169.118.23.2;169.118.23.3;169.118.23.4;169.118.23.5;169.118.23.6;169.118.23.7;169.118.23.8;169.118.23.9;169.118.23.10;169.118.23.11;169.118.23.12;169.118.23.13;169.118.23.14;169.118.23.15;169.118.23.16;169.118.23.17;169.118.23.18;169.118.23.19;169.118.23.20;169.118.23.21;169.118.23.22;169.118.23.23;169.118.23.24;169.118.23.25;169.118.23.26;169.118.23.27;169.118.23.28;169.118.23.29;169.118.23.30;169.118.23.31;169.118.23.32;169.118.23.33;169.118.23.34;169.118.23.35;169.118.23.36;169.118.23.37;169.118.23.38;169.118.23.39;169.118.23.40;169.118.23.41;169.118.23.42;169.118.23.43;169.118.23.44;169.118.23.45;169.118.23.46;169.118.23.47;169.118.23.48 + + + NtpResources + + 17.39.1.129;17.39.1.130 + + + SnmpResources + + 71.49.219.98 + + + SyslogResources + + 71.49.219.8;123.46.98.21 + + + TacacsGroup + + Starlab + + + TacacsServer + + 123.46.98.21 + + + ForcedMgmtRoutes + + 71.49.219.98/31;71.49.219.8;123.46.98.16/28;10.3.149.170/31;40.122.216.24;13.91.48.226;71.49.219.14 + + + ErspanDestinationIpv4 + + 10.20.6.16 + + + + + ASIC0 + + + SubRole + + FrontEnd + + + + + ASIC1 + + + SubRole + + FrontEnd + + + + + ASIC2 + + + SubRole + + FrontEnd + + + + + ASIC3 + + + SubRole + + FrontEnd + + + + + ASIC2 + + + SubRole + + BackEnd + + + + + ASIC3 + + + SubRole + + BackEnd + + + + + + + multi_npu_platform_01 + multi-npu-01 +
diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-0.ini b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-0.ini new file mode 100644 index 000000000000..b6b0379f6072 --- /dev/null +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-0.ini @@ -0,0 +1,9 @@ +# name lanes alias index asic_port_name role +Ethernet0 33,34,35,36 Ethernet1/1 0 Eth0-ASIC0 Ext +Ethernet4 29,30,31,32 Ethernet1/2 1 Eth1-ASIC0 Ext +Ethernet8 41,42,43,44 Ethernet1/3 2 Eth2-ASIC0 Ext +Ethernet12 37,38,39,40 Ethernet1/4 3 Eth3-ASIC0 Ext +Ethernet-BP0 13,14,15,16 Eth4-ASIC0 0 Eth4-ASIC0 Int +Ethernet-BP4 17,18,19,20 Eth5-ASIC0 1 Eth5-ASIC0 Int +Ethernet-BP8 21,22,23,24 Eth6-ASIC0 2 Eth6-ASIC0 Int +Ethernet-BP12 25,26,27,28 Eth7-ASIC0 3 Eth7-ASIC0 Int diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-1.ini b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-1.ini new file mode 100644 index 000000000000..a581b19fd61a --- /dev/null +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-1.ini @@ -0,0 +1,9 @@ +# name lanes alias index asic_port_name role +Ethernet16 33,34,35,36 Ethernet1/5 4 Eth0-ASIC1 Ext +Ethernet20 29,30,31,32 Ethernet1/6 5 Eth1-ASIC1 Ext +Ethernet24 41,42,43,44 Ethernet1/7 6 Eth2-ASIC1 Ext +Ethernet28 37,38,39,40 Ethernet1/8 7 Eth3-ASIC1 Ext +Ethernet-BP16 13,14,15,16 Eth4-ASIC1 4 Eth4-ASIC1 Int +Ethernet-BP20 17,18,19,20 Eth5-ASIC1 5 Eth5-ASIC1 Int +Ethernet-BP24 21,22,23,24 Eth6-ASIC1 6 Eth6-ASIC1 Int +Ethernet-BP28 25,26,27,28 Eth7-ASIC1 7 Eth7-ASIC1 Int diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-2.ini b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-2.ini new file mode 100644 index 000000000000..71467a9a6ec4 --- /dev/null +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-2.ini @@ -0,0 +1,9 @@ +# name lanes alias index asic_port_name role +Ethernet-BP256 61,62,63,64 Eth0-ASIC2 8 Eth0-ASIC2 Int +Ethernet-BP260 57,58,59,60 Eth1-ASIC2 9 Eth1-ASIC2 Int +Ethernet-BP264 53,54,55,56 Eth2-ASIC2 10 Eth2-ASIC2 Int +Ethernet-BP268 49,50,51,52 Eth3-ASIC2 11 Eth3-ASIC2 Int +Ethernet-BP272 45,46,47,48 Eth4-ASIC2 12 Eth4-ASIC2 Int +Ethernet-BP276 41,42,43,44 Eth5-ASIC2 13 Eth5-ASIC2 Int +Ethernet-BP280 37,38,39,40 Eth6-ASIC2 14 Eth6-ASIC2 Int +Ethernet-BP284 33,34,35,36 Eth7-ASIC2 15 Eth7-ASIC2 Int diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-3.ini b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-3.ini new file mode 100644 index 000000000000..e786bbdd8f62 --- /dev/null +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-3.ini @@ -0,0 +1,9 @@ +# name lanes alias index asic_port_name role +Ethernet-BP384 29,30,31,32 Eth0-ASIC3 16 Eth0-ASIC3 Int +Ethernet-BP388 25,26,27,28 Eth1-ASIC3 17 Eth1-ASIC3 Int +Ethernet-BP392 21,22,23,24 Eth2-ASIC3 18 Eth2-ASIC3 Int +Ethernet-BP396 17,18,19,20 Eth3-ASIC3 19 Eth3-ASIC3 Int +Ethernet-BP400 13,14,15,16 Eth4-ASIC3 20 Eth4-ASIC3 Int +Ethernet-BP404 9,10,11,12 Eth5-ASIC3 21 Eth5-ASIC3 Int +Ethernet-BP408 5,6,7,8 Eth6-ASIC3 22 Eth6-ASIC3 Int +Ethernet-BP412 1,2,3,4 Eth7-ASIC3 23 Eth7-ASIC3 Int diff --git a/src/sonic-config-engine/tests/ndppd.conf.j2 b/src/sonic-config-engine/tests/ndppd.conf.j2 new file mode 120000 index 000000000000..e6f2f543eee4 --- /dev/null +++ b/src/sonic-config-engine/tests/ndppd.conf.j2 @@ -0,0 +1 @@ +../../../dockers/docker-orchagent/ndppd.conf.j2 \ No newline at end of file diff --git a/src/sonic-config-engine/tests/sample-arista-7050-t0-minigraph.xml b/src/sonic-config-engine/tests/sample-arista-7050-t0-minigraph.xml new file mode 100644 index 000000000000..4fd1ba9ba128 --- /dev/null +++ b/src/sonic-config-engine/tests/sample-arista-7050-t0-minigraph.xml @@ -0,0 +1,907 @@ + + + + + + s7050-dev-1 + 10.0.0.56 + ARISTA01T1 + 10.0.0.57 + 1 + 10 + 3 + + + s7050-dev-1 + FC00::71 + ARISTA01T1 + FC00::72 + 1 + 10 + 3 + + + s7050-dev-1 + 10.0.0.58 + ARISTA02T1 + 10.0.0.59 + 1 + 10 + 3 + + + s7050-dev-1 + FC00::75 + ARISTA02T1 + FC00::76 + 1 + 10 + 3 + + + s7050-dev-1 + 10.0.0.60 + ARISTA03T1 + 10.0.0.61 + 1 + 10 + 3 + + + s7050-dev-1 + FC00::79 + ARISTA03T1 + FC00::7A + 1 + 10 + 3 + + + s7050-dev-1 + 10.0.0.62 + ARISTA04T1 + 10.0.0.63 + 1 + 10 + 3 + + + s7050-dev-1 + FC00::7D + ARISTA04T1 + FC00::7E + 1 + 10 + 3 + + + + + 65100 + s7050-dev-1 + + +
10.0.0.57
+ + + +
+ +
10.0.0.59
+ + + +
+ +
10.0.0.61
+ + + +
+ +
10.0.0.63
+ + + +
+
+ +
+ + 64600 + ARISTA01T1 + + + + 64600 + ARISTA02T1 + + + + 64600 + ARISTA03T1 + + + + 64600 + ARISTA04T1 + + +
+
+ + + + + + HostIP + Loopback0 + + 10.1.0.32/32 + + 10.1.0.32/32 + + + HostIP1 + Loopback0 + + FC00:1::32/128 + + FC00:1::32/128 + + + + + HostIP + eth0 + + 10.0.0.243/23 + + 10.0.0.243/23 + + + + + + s7050-dev-1 + + + PortChannel0001 + Ethernet33 + + + + PortChannel0002 + Ethernet34 + + + + PortChannel0003 + Ethernet35 + + + + PortChannel0004 + Ethernet36 + + + + + + Vlan1000 + Ethernet6/1;Ethernet7/1;Ethernet8/1;Ethernet9/1;Ethernet10/1;Ethernet11/1;Ethernet12/1;Ethernet13/1;Ethernet14/1;Ethernet15/1;Ethernet16/1;Ethernet17/1;Ethernet18/1;Ethernet19/1;Ethernet20/1;Ethernet21/1;Ethernet22/1;Ethernet23/1;Ethernet24/1;Ethernet25/1;Ethernet26/1;Ethernet27/1;Ethernet28/1;Ethernet29 + False + 0.0.0.0/0 + + 1000 + 1000 + 192.168.0.0/21 + + + + + + PortChannel0001 + 10.0.0.56/31 + + + + PortChannel0001 + FC00::71/126 + + + + PortChannel0002 + 10.0.0.58/31 + + + + PortChannel0002 + FC00::75/126 + + + + PortChannel0003 + 10.0.0.60/31 + + + + PortChannel0003 + FC00::79/126 + + + + PortChannel0004 + 10.0.0.62/31 + + + + PortChannel0004 + FC00::7D/126 + + + + Vlan1000 + 192.168.0.1/21 + + + + + + + + + + + + DeviceInterfaceLink + ARISTA01T1 + Ethernet1 + s7050-dev-1 + Ethernet33 + + + DeviceInterfaceLink + ARISTA02T1 + Ethernet1 + s7050-dev-1 + Ethernet34 + + + DeviceInterfaceLink + ARISTA03T1 + Ethernet1 + s7050-dev-1 + Ethernet35 + + + DeviceInterfaceLink + ARISTA04T1 + Ethernet1 + s7050-dev-1 + Ethernet36 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet6/1 + Servers0 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet7/1 + Servers1 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet8/1 + Servers2 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet9/1 + Servers3 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet10/1 + Servers4 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet11/1 + Servers5 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet12/1 + Servers6 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet13/1 + Servers7 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet14/1 + Servers8 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet15/1 + Servers9 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet16/1 + Servers10 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet17/1 + Servers11 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet18/1 + Servers12 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet19/1 + Servers13 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet20/1 + Servers14 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet21/1 + Servers15 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet22/1 + Servers16 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet23/1 + Servers17 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet24/1 + Servers18 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet25/1 + Servers19 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet26/1 + Servers20 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet27/1 + Servers21 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet28/1 + Servers22 + eth0 + + + DeviceInterfaceLink + s7050-dev-1 + Ethernet29 + Servers23 + eth0 + + + + + s7050-dev-1 + Arista-7050-QX-32S + + 10.0.0.243 + + + + + + + true + + + DeviceInterface + + true + true + 1 + Ethernet5/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet6/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet7/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet8/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet9/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet10/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet11/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet12/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet13/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet14/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet15/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet16/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet17/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet18/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet19/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet20/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet21/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet22/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet23/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet24/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet25/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet26/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet27/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet28/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet29 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet30 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet31 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet32 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet33 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet34 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet35 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet36 + + false + 0 + 0 + 40000 + + + true + 0 + Arista-7050-QX-32S + + + + + + + s7050-dev-1 + + + ErspanDestinationIpv4 + + 10.0.0.16 + + + + + + + s7050-dev-1 + Arista-7050-QX-32S +
diff --git a/src/sonic-config-engine/tests/sample-template-1.json.j2 b/src/sonic-config-engine/tests/sample-template-1.json.j2 new file mode 100644 index 000000000000..96051b502fb7 --- /dev/null +++ b/src/sonic-config-engine/tests/sample-template-1.json.j2 @@ -0,0 +1,4 @@ +{ + "jk1_1": "{{ key1_1 }}", + "jk1_2": "{{ key1_2 }}" +} diff --git a/src/sonic-config-engine/tests/sample-template-2.json.j2 b/src/sonic-config-engine/tests/sample-template-2.json.j2 new file mode 100644 index 000000000000..3de91ab36edb --- /dev/null +++ b/src/sonic-config-engine/tests/sample-template-2.json.j2 @@ -0,0 +1,4 @@ +{ + "jk2_1": "{{ key2_1 }}", + "jk2_2": "{{ key2_2 }}" +} diff --git a/src/sonic-config-engine/tests/sample_hwsku.json b/src/sonic-config-engine/tests/sample_hwsku.json new file mode 100644 index 000000000000..5b450932c238 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_hwsku.json @@ -0,0 +1,100 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet4": { + "default_brkout_mode": "2x50G" + }, + "Ethernet8": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet12": { + "default_brkout_mode": "2x25G(2)+1x50G(2)" + }, + "Ethernet16": { + "default_brkout_mode": "1x50G(2)+2x25G(2)" + }, + "Ethernet20": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet24": { + "default_brkout_mode": "2x50G" + }, + "Ethernet28": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet32": { + "default_brkout_mode": "2x25G(2)+1x50G(2)" + }, + "Ethernet36": { + "default_brkout_mode": "1x50G(2)+2x25G(2)" + }, + "Ethernet40": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet44": { + "default_brkout_mode": "2x50G" + }, + "Ethernet48": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet52": { + "default_brkout_mode": "2x25G(2)+1x50G(2)" + }, + "Ethernet56": { + "default_brkout_mode": "1x50G(2)+2x25G(2)" + }, + "Ethernet60": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet64": { + "default_brkout_mode": "2x50G" + }, + "Ethernet68": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet72": { + "default_brkout_mode": "2x25G(2)+1x50G(2)" + }, + "Ethernet76": { + "default_brkout_mode": "1x50G(2)+2x25G(2)" + }, + "Ethernet80": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet84": { + "default_brkout_mode": "2x50G" + }, + "Ethernet88": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet92": { + "default_brkout_mode": "2x25G(2)+1x50G(2)" + }, + "Ethernet96": { + "default_brkout_mode": "1x50G(2)+2x25G(2)" + }, + "Ethernet100": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet104": { + "default_brkout_mode": "2x50G" + }, + "Ethernet108": { + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet112": { + "default_brkout_mode": "2x25G(2)+1x50G(2)" + }, + "Ethernet116": { + "default_brkout_mode": "1x50G(2)+2x25G(2)" + }, + "Ethernet120": { + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet124": { + "default_brkout_mode": "2x50G" + } + } +} diff --git a/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf b/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf deleted file mode 100644 index 566d6384fcfd..000000000000 --- a/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf +++ /dev/null @@ -1,89 +0,0 @@ -! -! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== -! generated by templates/quagga/bgpd.conf.j2 with config DB data -! file: bgpd.conf -! -! -! -hostname switch-t0 -password zebra -enable password zebra -! -log syslog informational -log facility local4 -!! -agentx -! -! -! -! -! bgp multiple-instance -! -route-map FROM_BGP_SPEAKER_V4 permit 10 -! -route-map TO_BGP_SPEAKER_V4 deny 10 -! -ip prefix-list PL_LoopbackV4 permit 10.1.0.32/32 -ipv6 prefix-list PL_LoopbackV6 permit fc00:1::/64 -! -! -route-map TO_BGP_PEER_V4 permit 100 -! -route-map TO_BGP_PEER_V6 permit 100 -! -route-map FROM_BGPMON deny 10 -! -route-map TO_BGPMON permit 10 -! -! -route-map ISOLATE permit 10 - set as-path prepend 65100 -! -route-map set-next-hop-global-v6 permit 10 - set ipv6 next-hop prefer-global -! -router bgp 65100 - bgp log-neighbor-changes - bgp bestpath as-path multipath-relax - no bgp default ipv4-unicast - bgp graceful-restart restart-time 240 - bgp graceful-restart - bgp graceful-restart preserve-fw-state - bgp router-id 10.1.0.32 - network 10.1.0.32/32 - address-family ipv6 - network fc00:1::32/64 - exit-address-family - network 192.168.0.1/27 - address-family ipv4 - maximum-paths 64 - exit-address-family - address-family ipv6 - maximum-paths 64 - exit-address-family - neighbor PEER_V4 peer-group - neighbor PEER_V6 peer-group - address-family ipv4 - neighbor PEER_V4 allowas-in 1 - neighbor PEER_V4 soft-reconfiguration inbound - neighbor PEER_V4 route-map TO_BGP_PEER_V4 out - exit-address-family - address-family ipv6 - neighbor PEER_V6 allowas-in 1 - neighbor PEER_V6 soft-reconfiguration inbound - neighbor PEER_V6 route-map TO_BGP_PEER_V6 out - exit-address-family - neighbor BGPMON peer-group - neighbor BGPMON update-source 10.1.0.32 - neighbor BGPMON route-map FROM_BGPMON in - neighbor BGPMON route-map TO_BGPMON out - neighbor BGPMON send-community - neighbor BGPMON maximum-prefix 1 - neighbor 10.20.30.40 remote-as 65100 - neighbor 10.20.30.40 peer-group BGPMON - neighbor 10.20.30.40 description BGPMonitor - neighbor 10.20.30.40 activate - address-family ipv6 - neighbor 10.20.30.40 activate - exit-address-family -!! diff --git a/src/sonic-config-engine/tests/sample_output/bgpd_quagga.conf b/src/sonic-config-engine/tests/sample_output/bgpd_quagga.conf deleted file mode 100644 index ebffcaa7c24d..000000000000 --- a/src/sonic-config-engine/tests/sample_output/bgpd_quagga.conf +++ /dev/null @@ -1,100 +0,0 @@ -! -! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== -! generated by templates/quagga/bgpd.conf.j2 with config DB data -! file: bgpd.conf -! -! -hostname switch-t0 -password zebra -log syslog informational -log facility local4 -! enable password ! -! -! bgp multiple-instance -! -route-map FROM_BGP_SPEAKER_V4 permit 10 -! -route-map TO_BGP_SPEAKER_V4 deny 10 -! -router bgp 65100 - bgp log-neighbor-changes - bgp bestpath as-path multipath-relax - no bgp default ipv4-unicast - bgp graceful-restart restart-time 240 - bgp graceful-restart - bgp router-id 10.1.0.32 - network 10.1.0.32/32 - address-family ipv6 - network fc00:1::32/64 - exit-address-family - network 192.168.0.1/27 - neighbor 10.0.0.57 remote-as 64600 - neighbor 10.0.0.57 description ARISTA01T1 - address-family ipv4 - neighbor 10.0.0.57 allowas-in 1 - neighbor 10.0.0.57 activate - neighbor 10.0.0.57 soft-reconfiguration inbound - maximum-paths 64 - exit-address-family - neighbor 10.0.0.59 remote-as 64600 - neighbor 10.0.0.59 description ARISTA02T1 - address-family ipv4 - neighbor 10.0.0.59 allowas-in 1 - neighbor 10.0.0.59 activate - neighbor 10.0.0.59 soft-reconfiguration inbound - maximum-paths 64 - exit-address-family - neighbor 10.0.0.61 remote-as 64600 - neighbor 10.0.0.61 description ARISTA03T1 - address-family ipv4 - neighbor 10.0.0.61 allowas-in 1 - neighbor 10.0.0.61 activate - neighbor 10.0.0.61 soft-reconfiguration inbound - maximum-paths 64 - exit-address-family - neighbor 10.0.0.63 remote-as 64600 - neighbor 10.0.0.63 description ARISTA04T1 - address-family ipv4 - neighbor 10.0.0.63 allowas-in 1 - neighbor 10.0.0.63 activate - neighbor 10.0.0.63 soft-reconfiguration inbound - maximum-paths 64 - exit-address-family - neighbor fc00::7a remote-as 64600 - neighbor fc00::7a description ARISTA03T1 - address-family ipv6 - neighbor fc00::7a allowas-in 1 - neighbor fc00::7a activate - neighbor fc00::7a soft-reconfiguration inbound - maximum-paths 64 - exit-address-family - neighbor fc00::7e remote-as 64600 - neighbor fc00::7e description ARISTA04T1 - address-family ipv6 - neighbor fc00::7e allowas-in 1 - neighbor fc00::7e activate - neighbor fc00::7e soft-reconfiguration inbound - maximum-paths 64 - exit-address-family - neighbor fc00::72 remote-as 64600 - neighbor fc00::72 description ARISTA01T1 - address-family ipv6 - neighbor fc00::72 allowas-in 1 - neighbor fc00::72 activate - neighbor fc00::72 soft-reconfiguration inbound - maximum-paths 64 - exit-address-family - neighbor fc00::76 remote-as 64600 - neighbor fc00::76 description ARISTA02T1 - address-family ipv6 - neighbor fc00::76 allowas-in 1 - neighbor fc00::76 activate - neighbor fc00::76 soft-reconfiguration inbound - maximum-paths 64 - exit-address-family -! -maximum-paths 64 -! -route-map ISOLATE permit 10 -set as-path prepend 65100 -! diff --git a/src/sonic-config-engine/tests/sample_output/buffers-dell6100.json b/src/sonic-config-engine/tests/sample_output/buffers-dell6100.json deleted file mode 100644 index 5cf0472f3f11..000000000000 --- a/src/sonic-config-engine/tests/sample_output/buffers-dell6100.json +++ /dev/null @@ -1,640 +0,0 @@ - -{ - "CABLE_LENGTH": { - "AZURE": { - "Ethernet0": "5m", - "Ethernet1": "5m", - "Ethernet2": "5m", - "Ethernet3": "5m", - "Ethernet4": "5m", - "Ethernet5": "5m", - "Ethernet6": "5m", - "Ethernet7": "5m", - "Ethernet8": "5m", - "Ethernet9": "5m", - "Ethernet10": "5m", - "Ethernet11": "5m", - "Ethernet12": "5m", - "Ethernet13": "5m", - "Ethernet14": "5m", - "Ethernet15": "5m", - "Ethernet16": "5m", - "Ethernet17": "5m", - "Ethernet18": "5m", - "Ethernet19": "5m", - "Ethernet20": "5m", - "Ethernet21": "5m", - "Ethernet22": "5m", - "Ethernet23": "5m", - "Ethernet24": "5m", - "Ethernet25": "5m", - "Ethernet26": "5m", - "Ethernet27": "5m", - "Ethernet28": "5m", - "Ethernet29": "5m", - "Ethernet30": "5m", - "Ethernet31": "5m", - "Ethernet32": "5m", - "Ethernet33": "5m", - "Ethernet34": "5m", - "Ethernet35": "5m", - "Ethernet36": "5m", - "Ethernet37": "5m", - "Ethernet38": "5m", - "Ethernet39": "5m", - "Ethernet40": "5m", - "Ethernet41": "5m", - "Ethernet42": "5m", - "Ethernet43": "5m", - "Ethernet44": "5m", - "Ethernet45": "5m", - "Ethernet46": "5m", - "Ethernet47": "5m", - "Ethernet48": "5m", - "Ethernet49": "5m", - "Ethernet50": "5m", - "Ethernet51": "5m", - "Ethernet52": "5m", - "Ethernet53": "5m", - "Ethernet54": "5m", - "Ethernet55": "5m", - "Ethernet56": "5m", - "Ethernet57": "5m", - "Ethernet58": "5m", - "Ethernet59": "5m", - "Ethernet60": "5m", - "Ethernet61": "5m", - "Ethernet62": "5m", - "Ethernet63": "5m" - } - }, - - "BUFFER_POOL": { - "ingress_lossless_pool": { - "size": "10875072", - "type": "ingress", - "mode": "dynamic", - "xoff": "4194112" - }, - "egress_lossy_pool": { - "size": "9243812", - "type": "egress", - "mode": "dynamic" - }, - "egress_lossless_pool": { - "size": "15982720", - "type": "egress", - "mode": "static" - } - }, - "BUFFER_PROFILE": { - "ingress_lossy_profile": { - "pool":"[BUFFER_POOL|ingress_lossless_pool]", - "size":"0", - "dynamic_th":"3" - }, - "egress_lossless_profile": { - "pool":"[BUFFER_POOL|egress_lossless_pool]", - "size":"1518", - "static_th":"15982720" - }, - "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_lossy_pool]", - "size":"1518", - "dynamic_th":"3" - } - }, - "BUFFER_PG": { - "Ethernet0|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet1|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet4|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet5|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet6|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet7|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet8|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet9|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet10|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet11|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet12|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet13|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet14|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet15|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet16|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet17|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet20|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet21|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet22|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet23|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet24|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet25|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet26|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet27|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet28|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet29|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet30|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet31|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet32|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet36|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet37|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet38|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet39|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet40|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet41|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet42|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet48|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet52|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet53|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet54|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet55|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet56|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet57|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - }, - "Ethernet58|0": { - "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - } - }, - - "BUFFER_QUEUE": { - "Ethernet0|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet1|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet4|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet5|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet6|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet7|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet8|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet9|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet10|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet11|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet12|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet13|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet14|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet15|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet16|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet17|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet20|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet21|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet22|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet23|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet24|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet25|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet26|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet27|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet28|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet29|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet30|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet31|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet32|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet36|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet37|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet38|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet39|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet40|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet41|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet42|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet48|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet52|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet53|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet54|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet55|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet56|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet57|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet58|3-4": { - "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" - }, - "Ethernet0|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet1|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet4|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet5|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet6|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet7|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet8|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet9|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet10|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet11|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet12|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet13|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet14|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet15|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet16|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet17|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet20|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet21|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet22|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet23|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet24|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet25|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet26|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet27|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet28|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet29|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet30|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet31|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet32|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet36|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet37|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet38|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet39|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet40|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet41|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet42|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet48|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet52|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet53|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet54|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet55|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet56|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet57|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet58|0-2": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet0|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet1|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet4|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet5|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet6|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet7|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet8|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet9|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet10|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet11|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet12|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet13|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet14|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet15|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet16|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet17|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet20|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet21|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet22|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet23|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet24|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet25|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet26|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet27|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet28|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet29|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet30|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet31|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet32|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet36|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet37|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet38|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet39|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet40|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet41|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet42|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet48|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet52|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet53|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet54|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet55|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet56|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet57|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - }, - "Ethernet58|5-6": { - "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - } - } -} 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 deleted file mode 100644 index fde1d6c7714d..000000000000 --- a/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf +++ /dev/null @@ -1,52 +0,0 @@ -[supervisord] -logfile_maxbytes=1MB -logfile_backups=2 -nodaemon=true - -[eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener --container-name dhcp_relay -events=PROCESS_STATE_EXITED -autostart=true -autorestart=unexpected - -[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 - -[group:isc-dhcp-relay] -programs=isc-dhcp-relay-Vlan1000 - -[program:isc-dhcp-relay-Vlan1000] -command=/usr/sbin/dhcrelay -d -m discard -a %%h:%%p %%P --name-alias-map-file /tmp/port-name-alias-map.txt -id Vlan1000 -iu PortChannel01 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 192.0.0.1 192.0.0.2 -priority=3 -autostart=false -autorestart=false -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 - - - diff --git a/src/sonic-config-engine/tests/sample_output/frr.conf b/src/sonic-config-engine/tests/sample_output/frr.conf deleted file mode 100644 index 47855ce7c841..000000000000 --- a/src/sonic-config-engine/tests/sample_output/frr.conf +++ /dev/null @@ -1,121 +0,0 @@ -! -! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== -! generated by templates/frr/frr.conf.j2 with config DB data -! file: frr.conf -! -! -! -hostname switch-t0 -password zebra -enable password zebra -! -log syslog informational -log facility local4 -!! -agentx -! -! -! -! Enable link-detect (default disabled) -interface PortChannel01 -link-detect -! -interface PortChannel02 -link-detect -! -interface PortChannel03 -link-detect -! -interface PortChannel04 -link-detect -! -! -! Set ip source to loopback for bgp learned routes -route-map RM_SET_SRC permit 10 - set src 10.1.0.32 -! - -route-map RM_SET_SRC6 permit 10 - set src fc00:1::32 -! -ip protocol bgp route-map RM_SET_SRC -! -ipv6 protocol bgp route-map RM_SET_SRC6 -! -!! -! -! set static default route to mgmt gateway as a backup to learned default -ip route 0.0.0.0/0 10.0.0.1 200 -!! -! -! -! bgp multiple-instance -! -route-map FROM_BGP_SPEAKER_V4 permit 10 -! -route-map TO_BGP_SPEAKER_V4 deny 10 -! -ip prefix-list PL_LoopbackV4 permit 10.1.0.32/32 -ipv6 prefix-list PL_LoopbackV6 permit fc00:1::/64 -! -! -route-map TO_BGP_PEER_V4 permit 100 -! -route-map TO_BGP_PEER_V6 permit 100 -! -route-map FROM_BGPMON deny 10 -! -route-map TO_BGPMON permit 10 -! -! -route-map ISOLATE permit 10 - set as-path prepend 65100 -! -route-map set-next-hop-global-v6 permit 10 - set ipv6 next-hop prefer-global -! -router bgp 65100 - bgp log-neighbor-changes - bgp bestpath as-path multipath-relax - no bgp default ipv4-unicast - bgp graceful-restart restart-time 240 - bgp graceful-restart - bgp graceful-restart preserve-fw-state - bgp router-id 10.1.0.32 - network 10.1.0.32/32 - address-family ipv6 - network fc00:1::32/64 - exit-address-family - network 192.168.0.1/27 - address-family ipv4 - maximum-paths 64 - exit-address-family - address-family ipv6 - maximum-paths 64 - exit-address-family - neighbor PEER_V4 peer-group - neighbor PEER_V6 peer-group - address-family ipv4 - neighbor PEER_V4 allowas-in 1 - neighbor PEER_V4 soft-reconfiguration inbound - neighbor PEER_V4 route-map TO_BGP_PEER_V4 out - exit-address-family - address-family ipv6 - neighbor PEER_V6 allowas-in 1 - neighbor PEER_V6 soft-reconfiguration inbound - neighbor PEER_V6 route-map TO_BGP_PEER_V6 out - exit-address-family - neighbor BGPMON peer-group - neighbor BGPMON update-source 10.1.0.32 - neighbor BGPMON route-map FROM_BGPMON in - neighbor BGPMON route-map TO_BGPMON out - neighbor BGPMON send-community - neighbor BGPMON maximum-prefix 1 - neighbor 10.20.30.40 remote-as 65100 - neighbor 10.20.30.40 peer-group BGPMON - neighbor 10.20.30.40 description BGPMonitor - neighbor 10.20.30.40 activate - address-family ipv6 - neighbor 10.20.30.40 activate - exit-address-family -!! diff --git a/src/sonic-config-engine/tests/sample_output/interfaces b/src/sonic-config-engine/tests/sample_output/interfaces deleted file mode 100644 index 913fc8531443..000000000000 --- a/src/sonic-config-engine/tests/sample_output/interfaces +++ /dev/null @@ -1,39 +0,0 @@ -# -# =============== Managed by SONiC Config Engine DO NOT EDIT! =============== -# generated from /usr/share/sonic/templates/interfaces.j2 using sonic-cfggen -# file: /etc/network/interfaces -# -# The loopback network interface -auto lo -iface lo inet loopback - -# The management network interface -auto eth0 -iface eth0 inet static - address 10.0.0.100 - netmask 255.255.255.0 - ########## management network policy routing rules - # management port up rules - up ip -4 route add default via 10.0.0.1 dev eth0 table default metric 201 - up ip -4 route add 10.0.0.0/24 dev eth0 table default - up ip -4 rule add from 10.0.0.100/32 table default - # management port down rules - pre-down ip -4 route delete default via 10.0.0.1 dev eth0 table default - pre-down ip -4 route delete 10.0.0.0/24 dev eth0 table default - pre-down ip -4 rule delete from 10.0.0.100/32 table default -iface eth0 inet6 static - address 2603:10e2:0:2902::8 - netmask 64 - ########## management network policy routing rules - # management port up rules - up ip -6 route add default via 2603:10e2:0:2902::1 dev eth0 table default metric 201 - up ip -6 route add 2603:10e2:0:2902::/64 dev eth0 table default - up ip -6 rule add from 2603:10e2:0:2902::8/128 table default - # management port down rules - pre-down ip -6 route delete default via 2603:10e2:0:2902::1 dev eth0 table default - pre-down ip -6 route delete 2603:10e2:0:2902::/64 dev eth0 table default - pre-down ip -6 rule delete from 2603:10e2:0:2902::8/128 table default -# -source /etc/network/interfaces.d/* -# - diff --git a/src/sonic-config-engine/tests/sample_output/ipinip.json b/src/sonic-config-engine/tests/sample_output/ipinip.json deleted file mode 100644 index e4028ea01a2d..000000000000 --- a/src/sonic-config-engine/tests/sample_output/ipinip.json +++ /dev/null @@ -1,23 +0,0 @@ -[ - { - "TUNNEL_DECAP_TABLE:IPINIP_TUNNEL" : { - "tunnel_type":"IPINIP", - "dst_ip":"10.1.0.32,10.0.0.56,10.0.0.58,10.0.0.60,10.0.0.62,192.168.0.1", - "dscp_mode":"pipe", - "ecn_mode":"copy_from_outer", - "ttl_mode":"pipe" - }, - "OP": "SET" - } - , - { - "TUNNEL_DECAP_TABLE:IPINIP_V6_TUNNEL" : { - "tunnel_type":"IPINIP", - "dst_ip":"fc00:1::32,fc00::71,fc00::75,fc00::79,fc00::7d", - "dscp_mode":"pipe", - "ecn_mode":"copy_from_outer", - "ttl_mode":"pipe" - }, - "OP": "SET" - } -] diff --git a/src/sonic-config-engine/tests/sample_output/lldpd.conf b/src/sonic-config-engine/tests/sample_output/lldpd.conf deleted file mode 100644 index d28ec8418362..000000000000 --- a/src/sonic-config-engine/tests/sample_output/lldpd.conf +++ /dev/null @@ -1,3 +0,0 @@ -configure ports eth0 lldp portidsubtype local eth0 -configure system ip management pattern 10.0.0.100 -configure system hostname switch-t0 diff --git a/src/sonic-config-engine/tests/sample_output/mvrf_interfaces b/src/sonic-config-engine/tests/sample_output/mvrf_interfaces deleted file mode 100644 index 7bd664d4a9db..000000000000 --- a/src/sonic-config-engine/tests/sample_output/mvrf_interfaces +++ /dev/null @@ -1,56 +0,0 @@ -# -# =============== Managed by SONiC Config Engine DO NOT EDIT! =============== -# generated from /usr/share/sonic/templates/interfaces.j2 using sonic-cfggen -# file: /etc/network/interfaces -# -auto mgmt -iface mgmt - vrf-table 5000 -# 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 - down ip link delete dev lo-m -# The loopback network interface -auto lo -iface lo inet loopback - -# The management network interface -auto eth0 -iface eth0 inet static - address 10.0.0.100 - netmask 255.255.255.0 - vrf mgmt - ########## management network policy routing rules - # management port up rules - up ip -4 route add default via 10.0.0.1 dev eth0 table 5000 metric 201 - up ip -4 route add 10.0.0.0/24 dev eth0 table 5000 - up ip -4 rule add from 10.0.0.100/32 table 5000 - up cgcreate -g l3mdev:mgmt - up cgset -r l3mdev.master-device=mgmt mgmt - # management port down rules - pre-down ip -4 route delete default via 10.0.0.1 dev eth0 table 5000 - pre-down ip -4 route delete 10.0.0.0/24 dev eth0 table 5000 - pre-down ip -4 rule delete from 10.0.0.100/32 table 5000 - down cgdelete -g l3mdev:mgmt -iface eth0 inet6 static - address 2603:10e2:0:2902::8 - netmask 64 - vrf mgmt - ########## management network policy routing rules - # management port up rules - up ip -6 route add default via 2603:10e2:0:2902::1 dev eth0 table 5000 metric 201 - up ip -6 route add 2603:10e2:0:2902::/64 dev eth0 table 5000 - up ip -6 rule add from 2603:10e2:0:2902::8/128 table 5000 - up cgcreate -g l3mdev:mgmt - up cgset -r l3mdev.master-device=mgmt mgmt - # management port down rules - 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/* -# - diff --git a/src/sonic-config-engine/tests/sample_output/platform_output.json b/src/sonic-config-engine/tests/sample_output/platform_output.json new file mode 100644 index 000000000000..f4e031fbe536 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/platform_output.json @@ -0,0 +1,819 @@ +{ + "Ethernet8": { + "index": "3", + "lanes": "8", + "description": "Eth3/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth3/1", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet9": { + "index": "3", + "lanes": "9", + "description": " Eth3/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth3/2", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet36": { + "index": "10", + "lanes": "36,37", + "description": "Eth10/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth10/1", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet98": { + "index": "25", + "lanes": "98", + "description": " Eth25/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth25/3", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet0": { + "index": "1", + "lanes": "0,1,2,3", + "fec": "rs", + "description": "Eth1/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth1/1", + "pfc_asym": "off", + "speed": "100000" + }, + "Ethernet6": { + "index": "2", + "lanes": "6,7", + "description": " Eth2/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth2/3", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet4": { + "index": "2", + "lanes": "4,5", + "description": "Eth2/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth2/1", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet109": { + "index": "28", + "lanes": "109", + "description": " Eth28/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth28/2", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet108": { + "index": "28", + "lanes": "108", + "description": "Eth28/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth28/1", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet18": { + "index": "5", + "lanes": "18", + "description": " Eth5/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth5/3", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet100": { + "index": "26", + "lanes": "100,101,102,103", + "fec": "rs", + "description": "Eth26/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth26/1", + "pfc_asym": "off", + "speed": "100000" + }, + "Ethernet34": { + "index": "9", + "lanes": "34,35", + "description": " Eth9/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth9/3", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet104": { + "index": "27", + "lanes": "104,105", + "description": "Eth27/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth27/1", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet106": { + "index": "27", + "lanes": "106,107", + "description": " Eth27/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth27/3", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet94": { + "index": "24", + "lanes": "94,95", + "description": " Eth24/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth24/3", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet126": { + "index": "32", + "lanes": "126,127", + "description": " Eth32/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth32/3", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet96": { + "index": "25", + "lanes": "96,97", + "description": "Eth25/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth25/1", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet124": { + "index": "32", + "lanes": "124,125", + "description": "Eth32/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth32/1", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet90": { + "index": "23", + "lanes": "90", + "description": " Eth23/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth23/3", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet91": { + "index": "23", + "lanes": "91", + "description": " Eth23/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth23/4", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet92": { + "index": "24", + "lanes": "92", + "description": "Eth24/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth24/1", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet93": { + "index": "24", + "lanes": "93", + "description": " Eth24/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth24/2", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet50": { + "index": "13", + "lanes": "50", + "description": " Eth13/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth13/3", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet51": { + "index": "13", + "lanes": "51", + "description": " Eth13/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth13/4", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet52": { + "index": "14", + "lanes": "52", + "description": "Eth14/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth14/1", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet53": { + "index": "14", + "lanes": "53", + "description": " Eth14/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth14/2", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet54": { + "index": "14", + "lanes": "54,55", + "description": " Eth14/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth14/3", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet99": { + "index": "25", + "lanes": "99", + "description": " Eth25/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth25/4", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet56": { + "index": "15", + "lanes": "56,57", + "description": "Eth15/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth15/1", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet113": { + "index": "29", + "lanes": "113", + "description": " Eth29/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth29/2", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet76": { + "index": "20", + "lanes": "76,77", + "description": "Eth20/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth20/1", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet74": { + "index": "19", + "lanes": "74,75", + "description": " Eth19/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth19/3", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet39": { + "index": "10", + "lanes": "39", + "description": " Eth10/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth10/4", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet72": { + "index": "19", + "lanes": "72", + "description": "Eth19/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth19/1", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet73": { + "index": "19", + "lanes": "73", + "description": " Eth19/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth19/2", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet70": { + "index": "18", + "lanes": "70", + "description": " Eth18/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth18/3", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet71": { + "index": "18", + "lanes": "71", + "description": " Eth18/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth18/4", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet32": { + "index": "9", + "lanes": "32", + "description": "Eth9/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth9/1", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet33": { + "index": "9", + "lanes": "33", + "description": " Eth9/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth9/2", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet16": { + "index": "5", + "lanes": "16,17", + "description": "Eth5/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth5/1", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet111": { + "index": "28", + "lanes": "111", + "description": " Eth28/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth28/4", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet10": { + "index": "3", + "lanes": "10", + "description": " Eth3/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth3/3", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet11": { + "index": "3", + "lanes": "11", + "description": " Eth3/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth3/4", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet12": { + "index": "4", + "lanes": "12", + "description": "Eth4/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth4/1", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet13": { + "index": "4", + "lanes": "13", + "description": " Eth4/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth4/2", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet58": { + "index": "15", + "lanes": "58", + "description": " Eth15/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth15/3", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet19": { + "index": "5", + "lanes": "19", + "description": " Eth5/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth5/4", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet59": { + "index": "15", + "lanes": "59", + "description": " Eth15/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth15/4", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet38": { + "index": "10", + "lanes": "38", + "description": " Eth10/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth10/3", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet78": { + "index": "20", + "lanes": "78", + "description": " Eth20/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth20/3", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet68": { + "index": "18", + "lanes": "68", + "description": "Eth18/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth18/1", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet14": { + "index": "4", + "lanes": "14,15", + "description": " Eth4/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth4/3", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet89": { + "index": "23", + "lanes": "89", + "description": " Eth23/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth23/2", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet88": { + "index": "23", + "lanes": "88", + "description": "Eth23/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth23/1", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet118": { + "index": "30", + "lanes": "118", + "description": " Eth30/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth30/3", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet119": { + "index": "30", + "lanes": "119", + "description": " Eth30/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth30/4", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet116": { + "index": "30", + "lanes": "116,117", + "description": "Eth30/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth30/1", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet114": { + "index": "29", + "lanes": "114,115", + "description": " Eth29/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth29/3", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet80": { + "index": "21", + "lanes": "80,81,82,83", + "fec": "rs", + "description": "Eth21/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth21/1", + "pfc_asym": "off", + "speed": "100000" + }, + "Ethernet112": { + "index": "29", + "lanes": "112", + "description": "Eth29/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth29/1", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet86": { + "index": "22", + "lanes": "86,87", + "description": " Eth22/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth22/3", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet110": { + "index": "28", + "lanes": "110", + "description": " Eth28/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth28/3", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet84": { + "index": "22", + "lanes": "84,85", + "description": "Eth22/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth22/1", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet31": { + "index": "8", + "lanes": "31", + "description": " Eth8/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth8/4", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet49": { + "index": "13", + "lanes": "49", + "description": " Eth13/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth13/2", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet48": { + "index": "13", + "lanes": "48", + "description": "Eth13/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth13/1", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet46": { + "index": "12", + "lanes": "46,47", + "description": " Eth12/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth12/3", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet30": { + "index": "8", + "lanes": "30", + "description": " Eth8/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth8/3", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet29": { + "index": "8", + "lanes": "29", + "description": " Eth8/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth8/2", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet40": { + "index": "11", + "lanes": "40,41,42,43", + "fec": "rs", + "description": "Eth11/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth11/1", + "pfc_asym": "off", + "speed": "100000" + }, + "Ethernet120": { + "index": "31", + "lanes": "120,121,122,123", + "fec": "rs", + "description": "Eth31/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth31/1", + "pfc_asym": "off", + "speed": "100000" + }, + "Ethernet28": { + "index": "8", + "lanes": "28", + "description": "Eth8/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth8/1", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet66": { + "index": "17", + "lanes": "66,67", + "description": " Eth17/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth17/3", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet60": { + "index": "16", + "lanes": "60,61,62,63", + "fec": "rs", + "description": "Eth16/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth16/1", + "pfc_asym": "off", + "speed": "100000" + }, + "Ethernet64": { + "index": "17", + "lanes": "64,65", + "description": "Eth17/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth17/1", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet44": { + "index": "12", + "lanes": "44,45", + "description": "Eth12/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth12/1", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet20": { + "index": "6", + "lanes": "20,21,22,23", + "fec": "rs", + "description": "Eth6/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth6/1", + "pfc_asym": "off", + "speed": "100000" + }, + "Ethernet79": { + "index": "20", + "lanes": "79", + "description": " Eth20/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth20/4", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet69": { + "index": "18", + "lanes": "69", + "description": " Eth18/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth18/2", + "pfc_asym": "off", + "speed": "25000" + }, + "Ethernet24": { + "index": "7", + "lanes": "24,25", + "description": "Eth7/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth7/1", + "pfc_asym": "off", + "speed": "50000" + }, + "Ethernet26": { + "index": "7", + "lanes": "26,27", + "description": " Eth7/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth7/3", + "pfc_asym": "off", + "speed": "50000" + } +} diff --git a/src/sonic-config-engine/tests/sample_output/py2/bgpd_frr.conf b/src/sonic-config-engine/tests/sample_output/py2/bgpd_frr.conf new file mode 100644 index 000000000000..a312e7532620 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py2/bgpd_frr.conf @@ -0,0 +1,74 @@ +! +! template: bgpd/bgpd.conf.j2 +! +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/quagga/bgpd.conf.j2 with config DB data +! file: bgpd.conf +! +! +! template: common/daemons.common.conf.j2 +! +hostname switch-t0 +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +agentx +! +! +! +! template: bgpd/bgpd.main.conf.j2 +! +! bgp multiple-instance +! +! BGP configuration +! +! TSA configuration +! +ip prefix-list PL_LoopbackV4 permit 10.1.0.32/32 +! +ipv6 prefix-list PL_LoopbackV6 permit fc00:1::/64 +! +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 5 permit 192.168.0.0/27 +! +! +! +router bgp 65100 +! + bgp log-neighbor-changes + no bgp default ipv4-unicast + no bgp ebgp-requires-policy +! + bgp bestpath as-path multipath-relax +! + bgp graceful-restart restart-time 240 + bgp graceful-restart + bgp graceful-restart preserve-fw-state +! + bgp router-id 10.1.0.32 +! + network 10.1.0.32/32 +! + address-family ipv6 + network fc00:1::32/64 + exit-address-family +! + network 192.168.0.1/27 +! +! +! + address-family ipv4 + maximum-paths 64 + exit-address-family + address-family ipv6 + maximum-paths 64 + exit-address-family +! +! end of template: bgpd/bgpd.main.conf.j2 +!! +! end of template: bgpd/bgpd.conf.j2 +! diff --git a/src/sonic-config-engine/tests/sample_output/py2/bgpd_quagga.conf b/src/sonic-config-engine/tests/sample_output/py2/bgpd_quagga.conf new file mode 100644 index 000000000000..f75d9de9a30e --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py2/bgpd_quagga.conf @@ -0,0 +1,100 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/quagga/bgpd.conf.j2 with config DB data +! file: bgpd.conf +! +! +hostname switch-t0 +password zebra +log syslog informational +log facility local4 +! enable password ! +! +! bgp multiple-instance +! +route-map FROM_BGP_SPEAKER_V4 permit 10 +! +route-map TO_BGP_SPEAKER_V4 deny 10 +! +router bgp 65100 + bgp log-neighbor-changes + bgp bestpath as-path multipath-relax + no bgp default ipv4-unicast + bgp graceful-restart restart-time 240 + bgp graceful-restart + bgp router-id 10.1.0.32 + address-family ipv6 + network fc00:1::32/64 + exit-address-family + network 10.1.0.32/32 + network 192.168.0.1/27 + neighbor 10.0.0.59 remote-as 64600 + neighbor 10.0.0.59 description ARISTA02T1 + address-family ipv4 + neighbor 10.0.0.59 allowas-in 1 + neighbor 10.0.0.59 activate + neighbor 10.0.0.59 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + neighbor 10.0.0.61 remote-as 64600 + neighbor 10.0.0.61 description ARISTA03T1 + address-family ipv4 + neighbor 10.0.0.61 allowas-in 1 + neighbor 10.0.0.61 activate + neighbor 10.0.0.61 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + neighbor 10.0.0.63 remote-as 64600 + neighbor 10.0.0.63 description ARISTA04T1 + address-family ipv4 + neighbor 10.0.0.63 allowas-in 1 + neighbor 10.0.0.63 activate + neighbor 10.0.0.63 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + neighbor fc00::7e remote-as 64600 + neighbor fc00::7e description ARISTA04T1 + address-family ipv6 + neighbor fc00::7e allowas-in 1 + neighbor fc00::7e activate + neighbor fc00::7e soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + neighbor fc00::7a remote-as 64600 + neighbor fc00::7a description ARISTA03T1 + address-family ipv6 + neighbor fc00::7a allowas-in 1 + neighbor fc00::7a activate + neighbor fc00::7a soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + neighbor 10.0.0.57 remote-as 64600 + neighbor 10.0.0.57 description ARISTA01T1 + address-family ipv4 + neighbor 10.0.0.57 allowas-in 1 + neighbor 10.0.0.57 activate + neighbor 10.0.0.57 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + neighbor fc00::76 remote-as 64600 + neighbor fc00::76 description ARISTA02T1 + address-family ipv6 + neighbor fc00::76 allowas-in 1 + neighbor fc00::76 activate + neighbor fc00::76 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + neighbor fc00::72 remote-as 64600 + neighbor fc00::72 description ARISTA01T1 + address-family ipv6 + neighbor fc00::72 allowas-in 1 + neighbor fc00::72 activate + neighbor fc00::72 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family +! +maximum-paths 64 +! +route-map ISOLATE permit 10 +set as-path prepend 65100 +! diff --git a/src/sonic-config-engine/tests/sample_output/py2/buffers-dell6100.json b/src/sonic-config-engine/tests/sample_output/py2/buffers-dell6100.json new file mode 100644 index 000000000000..56de7500c1ad --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py2/buffers-dell6100.json @@ -0,0 +1,640 @@ + +{ + "CABLE_LENGTH": { + "AZURE": { + "Ethernet8": "5m", + "Ethernet9": "5m", + "Ethernet2": "5m", + "Ethernet3": "5m", + "Ethernet0": "5m", + "Ethernet1": "5m", + "Ethernet6": "5m", + "Ethernet7": "5m", + "Ethernet4": "5m", + "Ethernet5": "5m", + "Ethernet46": "5m", + "Ethernet34": "5m", + "Ethernet22": "5m", + "Ethernet58": "5m", + "Ethernet59": "5m", + "Ethernet50": "5m", + "Ethernet51": "5m", + "Ethernet52": "5m", + "Ethernet53": "5m", + "Ethernet54": "5m", + "Ethernet55": "5m", + "Ethernet56": "5m", + "Ethernet57": "5m", + "Ethernet38": "5m", + "Ethernet39": "5m", + "Ethernet18": "5m", + "Ethernet19": "5m", + "Ethernet14": "5m", + "Ethernet15": "5m", + "Ethernet16": "5m", + "Ethernet17": "5m", + "Ethernet10": "5m", + "Ethernet11": "5m", + "Ethernet12": "5m", + "Ethernet35": "5m", + "Ethernet37": "5m", + "Ethernet32": "5m", + "Ethernet33": "5m", + "Ethernet30": "5m", + "Ethernet31": "5m", + "Ethernet49": "5m", + "Ethernet48": "5m", + "Ethernet47": "5m", + "Ethernet36": "5m", + "Ethernet45": "5m", + "Ethernet44": "5m", + "Ethernet43": "5m", + "Ethernet42": "5m", + "Ethernet41": "5m", + "Ethernet40": "5m", + "Ethernet29": "5m", + "Ethernet28": "5m", + "Ethernet61": "5m", + "Ethernet60": "5m", + "Ethernet63": "5m", + "Ethernet62": "5m", + "Ethernet21": "5m", + "Ethernet20": "5m", + "Ethernet23": "5m", + "Ethernet13": "5m", + "Ethernet25": "5m", + "Ethernet24": "5m", + "Ethernet27": "5m", + "Ethernet26": "5m" + } + }, + + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "10875072", + "type": "ingress", + "mode": "dynamic", + "xoff": "4194112" + }, + "egress_lossy_pool": { + "size": "9243812", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "15982720", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "static_th":"15982720" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, + "BUFFER_PG": { + "Ethernet8|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet9|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet0|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet1|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet6|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet7|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet4|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet5|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet58|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet52|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet53|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet54|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet55|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet56|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet57|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet38|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet39|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet32|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet15|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet16|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet17|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet36|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet37|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet12|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet13|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet14|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet30|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet31|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet48|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet10|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet42|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet41|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet40|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet29|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet28|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet11|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet21|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet20|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet23|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet22|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet25|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet24|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet27|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet26|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, + + "BUFFER_QUEUE": { + "Ethernet8|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet9|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet0|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet1|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet6|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet7|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet4|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet5|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet58|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet52|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet53|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet54|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet55|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet56|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet57|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet38|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet39|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet32|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet15|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet16|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet17|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet36|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet37|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet12|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet13|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet14|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet30|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet31|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet48|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet10|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet42|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet41|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet40|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet29|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet28|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet11|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet21|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet20|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet23|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet22|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet25|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet24|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet27|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet26|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet8|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet9|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet0|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet1|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet6|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet7|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet4|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet5|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet58|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet52|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet53|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet54|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet55|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet56|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet57|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet38|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet39|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet32|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet15|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet16|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet17|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet36|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet37|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet12|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet13|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet14|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet30|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet31|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet48|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet10|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet42|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet41|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet40|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet29|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet28|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet11|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet21|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet20|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet23|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet22|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet25|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet24|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet27|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet26|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet8|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet9|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet0|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet1|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet6|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet7|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet4|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet5|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet58|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet52|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet53|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet54|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet55|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet56|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet57|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet38|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet39|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet32|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet15|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet16|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet17|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet36|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet37|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet12|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet13|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet14|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet30|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet31|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet48|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet10|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet42|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet41|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet40|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet29|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet28|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet11|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet21|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet20|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet23|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet22|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet25|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet24|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet27|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet26|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +} diff --git a/src/sonic-config-engine/tests/sample_output/py2/docker-dhcp-relay.supervisord.conf b/src/sonic-config-engine/tests/sample_output/py2/docker-dhcp-relay.supervisord.conf new file mode 100644 index 000000000000..dad758947f22 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py2/docker-dhcp-relay.supervisord.conf @@ -0,0 +1,69 @@ +[supervisord] +logfile_maxbytes=1MB +logfile_backups=2 +nodaemon=true + +[eventlistener:dependent-startup] +command=python3 -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE +buffer_size=50 + +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name dhcp_relay +events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING +autostart=true +autorestart=unexpected + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true + +[program:start] +command=/usr/bin/start.sh +priority=2 +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running + +[group:isc-dhcp-relay] +programs=isc-dhcp-relay-Vlan1000 + +[program:isc-dhcp-relay-Vlan1000] +command=/usr/sbin/dhcrelay -d -m discard -a %%h:%%p %%P --name-alias-map-file /tmp/port-name-alias-map.txt -id Vlan1000 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 -iu PortChannel01 192.0.0.1 192.0.0.2 +priority=3 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited + + +[group:dhcpmon] +programs=dhcpmon-Vlan1000 + +[program:dhcpmon-Vlan1000] +command=/usr/sbin/dhcpmon -id Vlan1000 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 -iu PortChannel01 -im eth0 +priority=4 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=isc-dhcp-relay-Vlan1000:running + + + diff --git a/src/sonic-config-engine/tests/sample_output/py2/frr.conf b/src/sonic-config-engine/tests/sample_output/py2/frr.conf new file mode 100644 index 000000000000..43df66c3f4e7 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py2/frr.conf @@ -0,0 +1,95 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/frr.conf.j2 with config DB data +! file: frr.conf +! +! +! template: common/daemons.common.conf.j2 +! +hostname switch-t0 +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +agentx +! +! +! +! Enable nht through default route +ip nht resolve-via-default +! Enable link-detect (default disabled) +interface PortChannel03 +link-detect +! +interface PortChannel02 +link-detect +! +interface PortChannel01 +link-detect +! +interface PortChannel04 +link-detect +! +!! +! +! set static default route to mgmt gateway as a backup to learned default +ip route 0.0.0.0/0 10.0.0.1 200 +!! +! +! +! add static ipv6 /64 loopback route to allow bgpd to advertise the loopback route prefix +ipv6 route fc00:1::/64 Loopback0 +!! +! +! template: bgpd/bgpd.main.conf.j2 +! +! bgp multiple-instance +! +! BGP configuration +! +! TSA configuration +! +ip prefix-list PL_LoopbackV4 permit 10.1.0.32/32 +! +ipv6 prefix-list PL_LoopbackV6 permit fc00:1::/64 +! +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 5 permit 192.168.0.0/27 +! +! +! +router bgp 65100 +! + bgp log-neighbor-changes + no bgp default ipv4-unicast + no bgp ebgp-requires-policy +! + bgp bestpath as-path multipath-relax +! + bgp graceful-restart restart-time 240 + bgp graceful-restart + bgp graceful-restart preserve-fw-state +! + bgp router-id 10.1.0.32 +! + network 10.1.0.32/32 +! + address-family ipv6 + network fc00:1::32/64 + exit-address-family +! + network 192.168.0.1/27 +! +! +! + address-family ipv4 + maximum-paths 64 + exit-address-family + address-family ipv6 + maximum-paths 64 + exit-address-family +! +! end of template: bgpd/bgpd.main.conf.j2 +!! diff --git a/src/sonic-config-engine/tests/sample_output/py2/interfaces b/src/sonic-config-engine/tests/sample_output/py2/interfaces new file mode 100644 index 000000000000..6e952d6f71ea --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py2/interfaces @@ -0,0 +1,46 @@ +# +# =============== Managed by SONiC Config Engine DO NOT EDIT! =============== +# generated from /usr/share/sonic/templates/interfaces.j2 using sonic-cfggen +# file: /etc/network/interfaces +# +# The loopback network interface +auto lo +iface lo inet loopback + address 127.0.0.1 + netmask 255.255.0.0 + post-up ip addr del 127.0.0.1/8 dev lo + +# The management network interface +auto eth0 +iface eth0 inet static + address 10.0.0.100 + netmask 255.255.255.0 + network 10.0.0.0 + broadcast 10.0.0.255 + ########## management network policy routing rules + # management port up rules + up ip -4 route add default via 10.0.0.1 dev eth0 table default metric 201 + up ip -4 route add 10.0.0.0/24 dev eth0 table default + up ip -4 rule add pref 32765 from 10.0.0.100/32 table default + # management port down rules + pre-down ip -4 route delete default via 10.0.0.1 dev eth0 table default + pre-down ip -4 route delete 10.0.0.0/24 dev eth0 table default + pre-down ip -4 rule delete pref 32765 from 10.0.0.100/32 table default +iface eth0 inet6 static + address 2603:10e2:0:2902::8 + netmask 64 + network 2603:10e2:0:2902:: + broadcast 2603:10e2:0:2902:ffff:ffff:ffff:ffff + ########## management network policy routing rules + # management port up rules + up ip -6 route add default via 2603:10e2:0:2902::1 dev eth0 table default metric 201 + up ip -6 route add 2603:10e2:0:2902::/64 dev eth0 table default + up ip -6 rule add pref 32765 from 2603:10e2:0:2902::8/128 table default + # management port down rules + pre-down ip -6 route delete default via 2603:10e2:0:2902::1 dev eth0 table default + pre-down ip -6 route delete 2603:10e2:0:2902::/64 dev eth0 table default + pre-down ip -6 rule delete pref 32765 from 2603:10e2:0:2902::8/128 table default +# +source /etc/network/interfaces.d/* +# + diff --git a/src/sonic-config-engine/tests/sample_output/py2/ipinip.json b/src/sonic-config-engine/tests/sample_output/py2/ipinip.json new file mode 100644 index 000000000000..db70ea403121 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py2/ipinip.json @@ -0,0 +1,23 @@ +[ + { + "TUNNEL_DECAP_TABLE:IPINIP_TUNNEL" : { + "tunnel_type":"IPINIP", + "dst_ip":"10.0.0.56,10.0.0.58,10.0.0.60,10.0.0.62,10.1.0.32,192.168.0.1", + "dscp_mode":"pipe", + "ecn_mode":"copy_from_outer", + "ttl_mode":"pipe" + }, + "OP": "SET" + } + , + { + "TUNNEL_DECAP_TABLE:IPINIP_V6_TUNNEL" : { + "tunnel_type":"IPINIP", + "dst_ip":"fc00:1::32,fc00::71,fc00::75,fc00::79,fc00::7d", + "dscp_mode":"pipe", + "ecn_mode":"copy_from_outer", + "ttl_mode":"pipe" + }, + "OP": "SET" + } +] diff --git a/src/sonic-config-engine/tests/sample_output/py2/l2switch.json b/src/sonic-config-engine/tests/sample_output/py2/l2switch.json new file mode 100644 index 000000000000..1c9e0ebbcd2e --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py2/l2switch.json @@ -0,0 +1,268 @@ +{ + "DEVICE_METADATA": {"localhost": {"hwsku": "Mellanox-SN2700"}}, + "PORT": { + "Ethernet8": { + "alias": "fortyGigE0/8", + "lanes": "37,38,39,40", + "admin_status": "up" + }, + "Ethernet0": { + "alias": "fortyGigE0/0", + "lanes": "29,30,31,32", + "admin_status": "up" + }, + "Ethernet4": { + "alias": "fortyGigE0/4", + "lanes": "25,26,27,28", + "admin_status": "up" + }, + "Ethernet108": { + "alias": "fortyGigE0/108", + "lanes": "81,82,83,84", + "admin_status": "up" + }, + "Ethernet100": { + "alias": "fortyGigE0/100", + "lanes": "125,126,127,128", + "admin_status": "up" + }, + "Ethernet104": { + "alias": "fortyGigE0/104", + "lanes": "85,86,87,88", + "admin_status": "up" + }, + "Ethernet68": { + "alias": "fortyGigE0/68", + "lanes": "69,70,71,72", + "admin_status": "up" + }, + "Ethernet96": { + "alias": "fortyGigE0/96", + "lanes": "121,122,123,124", + "admin_status": "up" + }, + "Ethernet124": { + "alias": "fortyGigE0/124", + "lanes": "101,102,103,104", + "admin_status": "up" + }, + "Ethernet92": { + "alias": "fortyGigE0/92", + "lanes": "113,114,115,116", + "admin_status": "up" + }, + "Ethernet120": { + "alias": "fortyGigE0/120", + "lanes": "97,98,99,100", + "admin_status": "up" + }, + "Ethernet52": { + "alias": "fortyGigE0/52", + "lanes": "53,54,55,56", + "admin_status": "up" + }, + "Ethernet56": { + "alias": "fortyGigE0/56", + "lanes": "61,62,63,64", + "admin_status": "up" + }, + "Ethernet76": { + "alias": "fortyGigE0/76", + "lanes": "73,74,75,76", + "admin_status": "up" + }, + "Ethernet72": { + "alias": "fortyGigE0/72", + "lanes": "77,78,79,80", + "admin_status": "up" + }, + "Ethernet64": { + "alias": "fortyGigE0/64", + "lanes": "65,66,67,68", + "admin_status": "up" + }, + "Ethernet32": { + "alias": "fortyGigE0/32", + "lanes": "9,10,11,12", + "admin_status": "up" + }, + "Ethernet16": { + "alias": "fortyGigE0/16", + "lanes": "41,42,43,44", + "admin_status": "up" + }, + "Ethernet36": { + "alias": "fortyGigE0/36", + "lanes": "13,14,15,16", + "admin_status": "up" + }, + "Ethernet12": { + "alias": "fortyGigE0/12", + "lanes": "33,34,35,36", + "admin_status": "up" + }, + "Ethernet88": { + "alias": "fortyGigE0/88", + "lanes": "117,118,119,120", + "admin_status": "up" + }, + "Ethernet116": { + "alias": "fortyGigE0/116", + "lanes": "93,94,95,96", + "admin_status": "up" + }, + "Ethernet80": { + "alias": "fortyGigE0/80", + "lanes": "105,106,107,108", + "admin_status": "up" + }, + "Ethernet112": { + "alias": "fortyGigE0/112", + "lanes": "89,90,91,92", + "admin_status": "up" + }, + "Ethernet84": { + "alias": "fortyGigE0/84", + "lanes": "109,110,111,112", + "admin_status": "up" + }, + "Ethernet48": { + "alias": "fortyGigE0/48", + "lanes": "49,50,51,52", + "admin_status": "up" + }, + "Ethernet44": { + "alias": "fortyGigE0/44", + "lanes": "17,18,19,20", + "admin_status": "up" + }, + "Ethernet40": { + "alias": "fortyGigE0/40", + "lanes": "21,22,23,24", + "admin_status": "up" + }, + "Ethernet28": { + "alias": "fortyGigE0/28", + "lanes": "1,2,3,4", + "admin_status": "up" + }, + "Ethernet60": { + "alias": "fortyGigE0/60", + "lanes": "57,58,59,60", + "admin_status": "up" + }, + "Ethernet20": { + "alias": "fortyGigE0/20", + "lanes": "45,46,47,48", + "admin_status": "up" + }, + "Ethernet24": { + "alias": "fortyGigE0/24", + "lanes": "5,6,7,8", + "admin_status": "up" + } + }, + "VLAN": { + "Vlan1000": { + "vlanid": "1000" + } + }, + "VLAN_MEMBER": { + "Vlan1000|Ethernet8": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet0": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet4": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet108": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet100": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet104": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet68": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet96": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet124": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet92": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet120": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet52": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet56": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet76": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet72": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet64": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet32": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet16": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet36": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet12": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet88": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet116": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet80": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet112": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet84": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet48": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet44": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet40": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet28": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet60": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet20": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet24": { + "tagging_mode": "untagged" + } + } +} diff --git a/src/sonic-config-engine/tests/sample_output/py2/lldp_conf/lldpd-ipv4-iface.conf b/src/sonic-config-engine/tests/sample_output/py2/lldp_conf/lldpd-ipv4-iface.conf new file mode 100644 index 000000000000..c9cb2c8123dd --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py2/lldp_conf/lldpd-ipv4-iface.conf @@ -0,0 +1,4 @@ +configure ports eth0 lldp portidsubtype local eth0 +configure system ip management pattern 10.0.0.100 +configure system hostname switch-t0 +pause diff --git a/src/sonic-config-engine/tests/sample_output/py2/lldp_conf/lldpd-ipv6-iface.conf b/src/sonic-config-engine/tests/sample_output/py2/lldp_conf/lldpd-ipv6-iface.conf new file mode 100644 index 000000000000..f5727556fdf3 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py2/lldp_conf/lldpd-ipv6-iface.conf @@ -0,0 +1,2 @@ +configure system hostname switch-t0 +pause diff --git a/src/sonic-config-engine/tests/sample_output/py2/mvrf_interfaces b/src/sonic-config-engine/tests/sample_output/py2/mvrf_interfaces new file mode 100644 index 000000000000..9e5c8a4261cf --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py2/mvrf_interfaces @@ -0,0 +1,61 @@ +# +# =============== Managed by SONiC Config Engine DO NOT EDIT! =============== +# generated from /usr/share/sonic/templates/interfaces.j2 using sonic-cfggen +# file: /etc/network/interfaces +# +auto mgmt +iface mgmt + vrf-table 5000 +# 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/16 dev lo-m + up ip link set lo-m up + down ip link delete dev lo-m +# The loopback network interface +auto lo +iface lo inet loopback + address 127.0.0.1 + netmask 255.255.0.0 + post-up ip addr del 127.0.0.1/8 dev lo + +# The management network interface +auto eth0 +iface eth0 inet static + address 10.0.0.100 + netmask 255.255.255.0 + network 10.0.0.0 + broadcast 10.0.0.255 + vrf mgmt + ########## management network policy routing rules + # management port up rules + up ip -4 route add default via 10.0.0.1 dev eth0 table 5000 metric 201 + up ip -4 route add 10.0.0.0/24 dev eth0 table 5000 + up ip -4 rule add pref 32765 from 10.0.0.100/32 table 5000 + up ip rule add pref 32764 to 11.11.11.11 table 5000 + up ip rule add pref 32764 to 22.22.22.0/23 table 5000 + # management port down rules + pre-down ip -4 route delete default via 10.0.0.1 dev eth0 table 5000 + pre-down ip -4 route delete 10.0.0.0/24 dev eth0 table 5000 + pre-down ip -4 rule delete pref 32765 from 10.0.0.100/32 table 5000 + pre-down ip rule delete pref 32764 to 11.11.11.11 table 5000 + pre-down ip rule delete pref 32764 to 22.22.22.0/23 table 5000 +iface eth0 inet6 static + address 2603:10e2:0:2902::8 + netmask 64 + network 2603:10e2:0:2902:: + broadcast 2603:10e2:0:2902:ffff:ffff:ffff:ffff + vrf mgmt + ########## management network policy routing rules + # management port up rules + up ip -6 route add default via 2603:10e2:0:2902::1 dev eth0 table 5000 metric 201 + up ip -6 route add 2603:10e2:0:2902::/64 dev eth0 table 5000 + up ip -6 rule add pref 32765 from 2603:10e2:0:2902::8/128 table 5000 + # management port down rules + 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 pref 32765 from 2603:10e2:0:2902::8/128 table 5000 +# +source /etc/network/interfaces.d/* +# + diff --git a/src/sonic-config-engine/tests/sample_output/py2/ndppd.conf b/src/sonic-config-engine/tests/sample_output/py2/ndppd.conf new file mode 100644 index 000000000000..71ff1dfaf9ca --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py2/ndppd.conf @@ -0,0 +1,25 @@ +# =========== Managed by sonic-cfggen -- DO NOT edit manually! ==================== +# Generated by /usr/share/sonic/templates/ndppd.conf.j2 using config DB data +# File: /etc/ndppd.conf +# +# Config file for ndppd, the NDP Proxy Daemon +# See man page for ndppd.conf.5 for descriptions of all available options + +proxy Vlan1000 { + rule fc02:1000::/64 { + static + } + rule fc03:1000::/64 { + static + } + rule fc01:1000::/64 { + static + } +} + +proxy Vlan2000 { + rule fc01:2000::/64 { + static + } +} + diff --git a/src/sonic-config-engine/tests/sample_output/py2/ports.json b/src/sonic-config-engine/tests/sample_output/py2/ports.json new file mode 100644 index 000000000000..0e174972fbe4 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py2/ports.json @@ -0,0 +1,30 @@ +[ + { + "PORT_TABLE:Ethernet8": { + "speed": "1000", + "description": "Interface description" + }, + "OP": "SET" + }, + { + "PORT_TABLE:Ethernet0": { + "speed": "10000", + "description": "fortyGigE0/0" + }, + "OP": "SET" + }, + { + "PORT_TABLE:Ethernet4": { + "speed": "25000", + "description": "fortyGigE0/4" + }, + "OP": "SET" + }, + { + "PORT_TABLE:Ethernet12": { + "speed": "100000", + "description": "Interface description" + }, + "OP": "SET" + } +] diff --git a/src/sonic-config-engine/tests/sample_output/py2/qos-arista7050.json b/src/sonic-config-engine/tests/sample_output/py2/qos-arista7050.json new file mode 100644 index 000000000000..aa05ef4ec36c --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py2/qos-arista7050.json @@ -0,0 +1,977 @@ +{ + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "0", + "2": "0", + "3": "3", + "4": "4", + "5": "0", + "6": "0", + "7": "7" + } + }, + "MAP_PFC_PRIORITY_TO_QUEUE": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0" : "1", + "1" : "1", + "2" : "1", + "3" : "3", + "4" : "4", + "5" : "2", + "6" : "1", + "7" : "1", + "8" : "0", + "9" : "1", + "10": "1", + "11": "1", + "12": "1", + "13": "1", + "14": "1", + "15": "1", + "16": "1", + "17": "1", + "18": "1", + "19": "1", + "20": "1", + "21": "1", + "22": "1", + "23": "1", + "24": "1", + "25": "1", + "26": "1", + "27": "1", + "28": "1", + "29": "1", + "30": "1", + "31": "1", + "32": "1", + "33": "1", + "34": "1", + "35": "1", + "36": "1", + "37": "1", + "38": "1", + "39": "1", + "40": "1", + "41": "1", + "42": "1", + "43": "1", + "44": "1", + "45": "1", + "46": "5", + "47": "1", + "48": "6", + "49": "1", + "50": "1", + "51": "1", + "52": "1", + "53": "1", + "54": "1", + "55": "1", + "56": "1", + "57": "1", + "58": "1", + "59": "1", + "60": "1", + "61": "1", + "62": "1", + "63": "1" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type" : "DWRR", + "weight": "14" + }, + "scheduler.1": { + "type" : "DWRR", + "weight": "15" + } + }, + "PORT_QOS_MAP": { + "Ethernet4": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet8": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet12": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet16": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet20": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet24": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet28": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet32": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet36": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet40": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet44": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet48": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet52": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet56": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet60": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet64": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet68": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet72": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet76": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet80": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet84": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet88": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet92": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet96": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet112": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet116": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet120": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet124": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "wred_green_enable" : "true", + "wred_yellow_enable" : "true", + "wred_red_enable" : "true", + "ecn" : "ecn_all", + "green_max_threshold" : "2097152", + "green_min_threshold" : "1048576", + "yellow_max_threshold" : "2097152", + "yellow_min_threshold" : "1048576", + "red_max_threshold" : "2097152", + "red_min_threshold" : "1048576", + "green_drop_probability" : "5", + "yellow_drop_probability": "5", + "red_drop_probability" : "5" + } + }, + "QUEUE": { + "Ethernet4|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet8|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet12|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet16|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet20|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet24|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet28|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet32|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet36|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet40|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet44|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet48|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet52|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet56|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet60|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet64|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet68|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet72|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet76|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet80|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet84|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet88|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet92|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet96|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet112|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet116|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet120|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet124|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet4|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet8|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet12|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet16|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet20|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet24|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet28|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet32|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet36|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet40|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet44|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet48|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet52|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet56|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet60|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet64|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet68|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet72|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet76|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet80|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet84|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet88|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet92|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet96|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet112|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet116|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet120|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet124|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet4|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet44|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet60|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet64|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet68|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet72|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet76|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet80|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet84|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet88|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet92|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet96|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet112|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet116|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet120|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet124|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet44|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet60|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet64|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet68|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet72|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet76|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet80|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet84|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet88|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet92|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet96|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet112|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet116|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet120|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet124|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet44|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet60|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet64|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet68|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet72|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet76|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet80|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet84|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet88|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet92|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet96|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet112|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet116|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet120|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet124|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet44|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet60|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet64|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet68|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet72|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet76|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet80|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet84|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet88|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet92|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet96|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet112|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet116|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet120|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet124|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet44|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet60|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet64|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet68|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet72|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet76|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet80|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet84|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet88|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet92|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet96|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet112|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet116|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet120|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet124|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + } + } +} diff --git a/src/sonic-config-engine/tests/sample_output/py2/qos-dell6100.json b/src/sonic-config-engine/tests/sample_output/py2/qos-dell6100.json new file mode 100644 index 000000000000..75d9b3a87eee --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py2/qos-dell6100.json @@ -0,0 +1,1457 @@ +{ + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "0", + "2": "0", + "3": "3", + "4": "4", + "5": "0", + "6": "0", + "7": "7" + } + }, + "MAP_PFC_PRIORITY_TO_QUEUE": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0" : "1", + "1" : "1", + "2" : "1", + "3" : "3", + "4" : "4", + "5" : "2", + "6" : "1", + "7" : "1", + "8" : "0", + "9" : "1", + "10": "1", + "11": "1", + "12": "1", + "13": "1", + "14": "1", + "15": "1", + "16": "1", + "17": "1", + "18": "1", + "19": "1", + "20": "1", + "21": "1", + "22": "1", + "23": "1", + "24": "1", + "25": "1", + "26": "1", + "27": "1", + "28": "1", + "29": "1", + "30": "1", + "31": "1", + "32": "1", + "33": "1", + "34": "1", + "35": "1", + "36": "1", + "37": "1", + "38": "1", + "39": "1", + "40": "1", + "41": "1", + "42": "1", + "43": "1", + "44": "1", + "45": "1", + "46": "5", + "47": "1", + "48": "6", + "49": "1", + "50": "1", + "51": "1", + "52": "1", + "53": "1", + "54": "1", + "55": "1", + "56": "1", + "57": "1", + "58": "1", + "59": "1", + "60": "1", + "61": "1", + "62": "1", + "63": "1" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type" : "DWRR", + "weight": "14" + }, + "scheduler.1": { + "type" : "DWRR", + "weight": "15" + } + }, + "PORT_QOS_MAP": { + "Ethernet0": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet1": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet4": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet5": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet6": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet7": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet8": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet9": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet10": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet11": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet12": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet13": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet14": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet15": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet16": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet17": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet20": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet21": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet22": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet23": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet24": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet25": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet26": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet27": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet28": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet29": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet30": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet31": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet32": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet36": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet37": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet38": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet39": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet40": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet41": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet42": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet48": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet52": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet53": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet54": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet55": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet56": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet57": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet58": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "wred_green_enable" : "true", + "wred_yellow_enable" : "true", + "wred_red_enable" : "true", + "ecn" : "ecn_all", + "green_max_threshold" : "2097152", + "green_min_threshold" : "250000", + "yellow_max_threshold" : "2097152", + "yellow_min_threshold" : "1048576", + "red_max_threshold" : "2097152", + "red_min_threshold" : "1048576", + "green_drop_probability" : "5", + "yellow_drop_probability": "5", + "red_drop_probability" : "5" + } + }, + "QUEUE": { + "Ethernet0|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet1|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet4|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet5|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet6|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet7|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet8|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet9|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet10|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet11|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet12|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet13|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet14|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet15|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet16|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet17|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet20|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet21|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet22|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet23|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet24|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet25|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet26|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet27|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet28|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet29|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet30|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet31|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet32|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet36|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet37|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet38|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet39|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet40|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet41|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet42|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet48|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet52|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet53|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet54|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet55|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet56|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet57|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet58|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet0|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet1|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet4|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet5|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet6|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet7|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet8|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet9|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet10|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet11|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet12|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet13|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet14|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet15|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet16|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet17|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet20|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet21|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet22|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet23|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet24|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet25|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet26|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet27|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet28|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet29|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet30|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet31|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet32|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet36|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet37|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet38|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet39|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet40|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet41|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet42|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet48|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet52|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet53|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet54|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet55|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet56|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet57|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet58|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet0|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet1|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet5|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet6|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet7|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet9|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet10|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet11|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet13|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet14|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet15|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet17|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet21|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet22|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet23|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet25|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet26|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet27|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet29|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet30|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet31|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet37|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet38|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet39|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet41|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet42|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet53|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet54|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet55|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet57|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet58|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet0|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet1|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet5|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet6|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet7|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet9|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet10|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet11|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet13|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet14|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet15|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet17|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet21|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet22|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet23|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet25|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet26|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet27|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet29|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet30|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet31|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet37|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet38|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet39|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet41|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet42|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet53|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet54|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet55|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet57|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet58|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet0|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet1|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet5|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet6|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet7|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet9|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet10|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet11|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet13|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet14|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet15|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet17|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet21|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet22|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet23|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet25|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet26|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet27|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet29|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet30|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet31|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet37|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet38|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet39|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet41|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet42|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet53|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet54|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet55|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet57|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet58|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet0|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet1|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet5|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet6|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet7|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet9|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet10|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet11|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet13|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet14|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet15|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet17|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet21|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet22|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet23|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet25|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet26|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet27|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet29|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet30|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet31|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet37|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet38|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet39|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet41|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet42|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet53|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet54|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet55|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet57|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet58|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet0|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet1|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet5|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet6|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet7|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet9|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet10|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet11|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet13|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet14|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet15|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet17|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet21|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet22|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet23|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet25|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet26|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet27|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet29|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet30|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet31|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet37|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet38|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet39|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet41|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet42|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet53|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet54|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet55|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet57|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet58|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + } + } +} diff --git a/src/sonic-config-engine/tests/sample_output/py2/staticd_frr.conf b/src/sonic-config-engine/tests/sample_output/py2/staticd_frr.conf new file mode 100644 index 000000000000..54d83525b1f0 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py2/staticd_frr.conf @@ -0,0 +1,25 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/frr/staticd.conf.j2 using config DB data +! file: staticd.conf +! +! +! template: common/daemons.common.conf.j2 +! +hostname switch-t0 +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +! +! set static default route to mgmt gateway as a backup to learned default +ip route 0.0.0.0/0 10.0.0.1 200 +!! +! +! +! add static ipv6 /64 loopback route to allow bgpd to advertise the loopback route prefix +ipv6 route fc00:1::/64 Loopback0 +!! diff --git a/src/sonic-config-engine/tests/sample_output/py2/t2-chassis-fe-bgpd.conf b/src/sonic-config-engine/tests/sample_output/py2/t2-chassis-fe-bgpd.conf new file mode 100644 index 000000000000..7633ac117bf7 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py2/t2-chassis-fe-bgpd.conf @@ -0,0 +1,88 @@ +! +! template: bgpd/bgpd.conf.j2 +! +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/quagga/bgpd.conf.j2 with config DB data +! file: bgpd.conf +! +! +! template: common/daemons.common.conf.j2 +! +hostname SpineFront01 +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +agentx +! +! +! Vnet BGP instance +router bgp 4000 vrf VnetFE + no bgp default ipv4-unicast + bgp log-neighbor-changes + bgp bestpath as-path multipath-relax + no bgp default ipv4-unicast + bgp graceful-restart restart-time 240 + bgp graceful-restart + bgp router-id 4.0.0.0 + neighbor 192.168.0.1 remote-as 3000 + neighbor 192.168.0.1 description Leaf01 + neighbor 192.168.0.1 timers 3 10 + address-family ipv4 unicast + neighbor 192.168.0.1 activate + neighbor 192.168.0.1 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + address-family l2vpn evpn + advertise ipv4 unicast + exit-address-family +!! +! +! template: bgpd/bgpd.main.conf.j2 +! +! bgp multiple-instance +! +! BGP configuration +! +! TSA configuration +! +ip prefix-list PL_LoopbackV4 permit 4.0.0.0/32 +! +! +! +! +router bgp 4000 +! + bgp log-neighbor-changes + no bgp default ipv4-unicast + no bgp ebgp-requires-policy +! + bgp bestpath as-path multipath-relax +! + bgp graceful-restart restart-time 240 + bgp graceful-restart + bgp graceful-restart preserve-fw-state +! + bgp router-id 4.0.0.0 +! + network 4.0.0.0/32 +! +! +! +! +! + address-family ipv4 + maximum-paths 64 + exit-address-family + address-family ipv6 + maximum-paths 64 + exit-address-family +! +! end of template: bgpd/bgpd.main.conf.j2 +!! +! end of template: bgpd/bgpd.conf.j2 +! diff --git a/src/sonic-config-engine/tests/sample_output/py2/t2-chassis-fe-vni-zebra.conf b/src/sonic-config-engine/tests/sample_output/py2/t2-chassis-fe-vni-zebra.conf new file mode 100644 index 000000000000..fb441f69f6f0 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py2/t2-chassis-fe-vni-zebra.conf @@ -0,0 +1,34 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/zebra/zebra.conf.j2 using config DB data +! file: zebra.conf +! +! +! template: common/daemons.common.conf.j2 +! +hostname SpineFront01 +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +! +vrf VnetFE +vni 9000 +! +! +! Enable nht through default route +ip nht resolve-via-default +! Enable link-detect (default disabled) +interface Ethernet8 +link-detect +! +interface Ethernet4 +link-detect +! +interface Ethernet0 +link-detect +! +!! diff --git a/src/sonic-config-engine/tests/sample_output/py2/t2-chassis-fe-zebra.conf b/src/sonic-config-engine/tests/sample_output/py2/t2-chassis-fe-zebra.conf new file mode 100644 index 000000000000..908280e2ddfa --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py2/t2-chassis-fe-zebra.conf @@ -0,0 +1,34 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/zebra/zebra.conf.j2 using config DB data +! file: zebra.conf +! +! +! template: common/daemons.common.conf.j2 +! +hostname SpineFront01 +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +! +vrf VnetFE +vni 8000 +! +! +! Enable nht through default route +ip nht resolve-via-default +! Enable link-detect (default disabled) +interface Ethernet8 +link-detect +! +interface Ethernet4 +link-detect +! +interface Ethernet0 +link-detect +! +!! diff --git a/src/sonic-config-engine/tests/sample_output/py2/wait_for_intf.sh b/src/sonic-config-engine/tests/sample_output/py2/wait_for_intf.sh new file mode 100644 index 000000000000..2af5cee2f005 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py2/wait_for_intf.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash + +function wait_until_iface_ready +{ + IFACE_NAME=$1 + IFACE_CIDR=$2 + + echo "Waiting until interface ${IFACE_NAME} is ready..." + + # Wait for the interface to come up + # (i.e., interface is present in STATE_DB and state is "ok") + while true; do + 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 + + sleep 1 + done + + echo "Interface ${IFACE_NAME} is ready!" +} + + +# Wait for all interfaces with IPv4 addresses to be up and ready +wait_until_iface_ready Vlan1000 192.168.0.1/27 +wait_until_iface_ready PortChannel02 10.0.0.58/31 +wait_until_iface_ready PortChannel03 10.0.0.60/31 +wait_until_iface_ready PortChannel04 10.0.0.62/31 +wait_until_iface_ready PortChannel01 10.0.0.56/31 + diff --git a/src/sonic-config-engine/tests/sample_output/py2/zebra_frr.conf b/src/sonic-config-engine/tests/sample_output/py2/zebra_frr.conf new file mode 100644 index 000000000000..4024f4b340e2 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py2/zebra_frr.conf @@ -0,0 +1,34 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/zebra/zebra.conf.j2 using config DB data +! file: zebra.conf +! +! +! template: common/daemons.common.conf.j2 +! +hostname switch-t0 +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +! +! +! Enable nht through default route +ip nht resolve-via-default +! Enable link-detect (default disabled) +interface PortChannel03 +link-detect +! +interface PortChannel02 +link-detect +! +interface PortChannel01 +link-detect +! +interface PortChannel04 +link-detect +! +!! diff --git a/src/sonic-config-engine/tests/sample_output/py2/zebra_quagga.conf b/src/sonic-config-engine/tests/sample_output/py2/zebra_quagga.conf new file mode 100644 index 000000000000..b1b791b252e8 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py2/zebra_quagga.conf @@ -0,0 +1,44 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/quagga/zebra.conf.j2 using config DB data +! file: zebra.conf +! +! +hostname switch-t0 +password zebra +enable password zebra +! +! Enable link-detect (default disabled) +interface PortChannel03 +link-detect +! +interface PortChannel02 +link-detect +! +interface PortChannel01 +link-detect +! +interface PortChannel04 +link-detect +! +! +! set static default route to mgmt gateway as a backup to learned default +ip route 0.0.0.0/0 10.0.0.1 200 +! +! Set ip source to loopback for bgp learned routes +route-map RM_SET_SRC permit 10 + set src 10.1.0.32 +! + +route-map RM_SET_SRC6 permit 10 + set src fc00:1::32 +! +ip protocol bgp route-map RM_SET_SRC +! +ipv6 protocol bgp route-map RM_SET_SRC6 +! +! +log syslog informational +log facility local4 +! + diff --git a/src/sonic-config-engine/tests/sample_output/py3/bgpd_frr.conf b/src/sonic-config-engine/tests/sample_output/py3/bgpd_frr.conf new file mode 100644 index 000000000000..a312e7532620 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/bgpd_frr.conf @@ -0,0 +1,74 @@ +! +! template: bgpd/bgpd.conf.j2 +! +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/quagga/bgpd.conf.j2 with config DB data +! file: bgpd.conf +! +! +! template: common/daemons.common.conf.j2 +! +hostname switch-t0 +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +agentx +! +! +! +! template: bgpd/bgpd.main.conf.j2 +! +! bgp multiple-instance +! +! BGP configuration +! +! TSA configuration +! +ip prefix-list PL_LoopbackV4 permit 10.1.0.32/32 +! +ipv6 prefix-list PL_LoopbackV6 permit fc00:1::/64 +! +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 5 permit 192.168.0.0/27 +! +! +! +router bgp 65100 +! + bgp log-neighbor-changes + no bgp default ipv4-unicast + no bgp ebgp-requires-policy +! + bgp bestpath as-path multipath-relax +! + bgp graceful-restart restart-time 240 + bgp graceful-restart + bgp graceful-restart preserve-fw-state +! + bgp router-id 10.1.0.32 +! + network 10.1.0.32/32 +! + address-family ipv6 + network fc00:1::32/64 + exit-address-family +! + network 192.168.0.1/27 +! +! +! + address-family ipv4 + maximum-paths 64 + exit-address-family + address-family ipv6 + maximum-paths 64 + exit-address-family +! +! end of template: bgpd/bgpd.main.conf.j2 +!! +! end of template: bgpd/bgpd.conf.j2 +! diff --git a/src/sonic-config-engine/tests/sample_output/py3/bgpd_quagga.conf b/src/sonic-config-engine/tests/sample_output/py3/bgpd_quagga.conf new file mode 100644 index 000000000000..16eb6095463b --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/bgpd_quagga.conf @@ -0,0 +1,100 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/quagga/bgpd.conf.j2 with config DB data +! file: bgpd.conf +! +! +hostname switch-t0 +password zebra +log syslog informational +log facility local4 +! enable password ! +! +! bgp multiple-instance +! +route-map FROM_BGP_SPEAKER_V4 permit 10 +! +route-map TO_BGP_SPEAKER_V4 deny 10 +! +router bgp 65100 + bgp log-neighbor-changes + bgp bestpath as-path multipath-relax + no bgp default ipv4-unicast + bgp graceful-restart restart-time 240 + bgp graceful-restart + bgp router-id 10.1.0.32 + network 10.1.0.32/32 + address-family ipv6 + network fc00:1::32/64 + exit-address-family + network 192.168.0.1/27 + neighbor 10.0.0.57 remote-as 64600 + neighbor 10.0.0.57 description ARISTA01T1 + address-family ipv4 + neighbor 10.0.0.57 allowas-in 1 + neighbor 10.0.0.57 activate + neighbor 10.0.0.57 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + neighbor fc00::72 remote-as 64600 + neighbor fc00::72 description ARISTA01T1 + address-family ipv6 + neighbor fc00::72 allowas-in 1 + neighbor fc00::72 activate + neighbor fc00::72 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + neighbor 10.0.0.59 remote-as 64600 + neighbor 10.0.0.59 description ARISTA02T1 + address-family ipv4 + neighbor 10.0.0.59 allowas-in 1 + neighbor 10.0.0.59 activate + neighbor 10.0.0.59 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + neighbor fc00::76 remote-as 64600 + neighbor fc00::76 description ARISTA02T1 + address-family ipv6 + neighbor fc00::76 allowas-in 1 + neighbor fc00::76 activate + neighbor fc00::76 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + neighbor 10.0.0.61 remote-as 64600 + neighbor 10.0.0.61 description ARISTA03T1 + address-family ipv4 + neighbor 10.0.0.61 allowas-in 1 + neighbor 10.0.0.61 activate + neighbor 10.0.0.61 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + neighbor fc00::7a remote-as 64600 + neighbor fc00::7a description ARISTA03T1 + address-family ipv6 + neighbor fc00::7a allowas-in 1 + neighbor fc00::7a activate + neighbor fc00::7a soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + neighbor 10.0.0.63 remote-as 64600 + neighbor 10.0.0.63 description ARISTA04T1 + address-family ipv4 + neighbor 10.0.0.63 allowas-in 1 + neighbor 10.0.0.63 activate + neighbor 10.0.0.63 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + neighbor fc00::7e remote-as 64600 + neighbor fc00::7e description ARISTA04T1 + address-family ipv6 + neighbor fc00::7e allowas-in 1 + neighbor fc00::7e activate + neighbor fc00::7e soft-reconfiguration inbound + maximum-paths 64 + exit-address-family +! +maximum-paths 64 +! +route-map ISOLATE permit 10 +set as-path prepend 65100 +! diff --git a/src/sonic-config-engine/tests/sample_output/py3/buffers-dell6100.json b/src/sonic-config-engine/tests/sample_output/py3/buffers-dell6100.json new file mode 100644 index 000000000000..39fb042cc4cb --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/buffers-dell6100.json @@ -0,0 +1,640 @@ + +{ + "CABLE_LENGTH": { + "AZURE": { + "Ethernet0": "5m", + "Ethernet1": "5m", + "Ethernet2": "5m", + "Ethernet3": "5m", + "Ethernet4": "5m", + "Ethernet5": "5m", + "Ethernet6": "5m", + "Ethernet7": "5m", + "Ethernet8": "5m", + "Ethernet9": "5m", + "Ethernet10": "5m", + "Ethernet11": "5m", + "Ethernet12": "5m", + "Ethernet13": "5m", + "Ethernet14": "5m", + "Ethernet15": "5m", + "Ethernet16": "5m", + "Ethernet17": "5m", + "Ethernet18": "5m", + "Ethernet19": "5m", + "Ethernet20": "5m", + "Ethernet21": "5m", + "Ethernet22": "5m", + "Ethernet23": "5m", + "Ethernet24": "5m", + "Ethernet25": "5m", + "Ethernet26": "5m", + "Ethernet27": "5m", + "Ethernet28": "5m", + "Ethernet29": "5m", + "Ethernet30": "5m", + "Ethernet31": "5m", + "Ethernet32": "5m", + "Ethernet33": "5m", + "Ethernet34": "5m", + "Ethernet35": "5m", + "Ethernet36": "5m", + "Ethernet37": "5m", + "Ethernet38": "5m", + "Ethernet39": "5m", + "Ethernet40": "5m", + "Ethernet41": "5m", + "Ethernet42": "5m", + "Ethernet43": "5m", + "Ethernet44": "5m", + "Ethernet45": "5m", + "Ethernet46": "5m", + "Ethernet47": "5m", + "Ethernet48": "5m", + "Ethernet49": "5m", + "Ethernet50": "5m", + "Ethernet51": "5m", + "Ethernet52": "5m", + "Ethernet53": "5m", + "Ethernet54": "5m", + "Ethernet55": "5m", + "Ethernet56": "5m", + "Ethernet57": "5m", + "Ethernet58": "5m", + "Ethernet59": "5m", + "Ethernet60": "5m", + "Ethernet61": "5m", + "Ethernet62": "5m", + "Ethernet63": "5m" + } + }, + + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "10875072", + "type": "ingress", + "mode": "dynamic", + "xoff": "4194112" + }, + "egress_lossy_pool": { + "size": "9243812", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "15982720", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "static_th":"15982720" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, + "BUFFER_PG": { + "Ethernet0|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet1|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet4|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet5|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet16|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet17|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet20|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet21|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet6|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet7|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet8|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet9|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet10|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet11|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet12|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet13|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet14|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet15|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet32|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet36|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet37|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet38|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet39|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet40|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet41|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet42|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet22|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet23|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet24|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet25|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet26|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet27|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet28|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet29|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet30|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet31|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet48|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet52|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet53|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet54|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet55|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet56|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet57|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet58|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, + + "BUFFER_QUEUE": { + "Ethernet0|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet1|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet4|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet5|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet16|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet17|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet20|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet21|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet6|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet7|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet8|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet9|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet10|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet11|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet12|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet13|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet14|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet15|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet32|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet36|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet37|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet38|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet39|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet40|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet41|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet42|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet22|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet23|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet24|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet25|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet26|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet27|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet28|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet29|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet30|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet31|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet48|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet52|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet53|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet54|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet55|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet56|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet57|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet58|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet0|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet1|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet4|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet5|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet16|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet17|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet20|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet21|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet6|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet7|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet8|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet9|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet10|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet11|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet12|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet13|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet14|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet15|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet32|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet36|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet37|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet38|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet39|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet40|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet41|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet42|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet22|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet23|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet24|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet25|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet26|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet27|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet28|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet29|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet30|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet31|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet48|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet52|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet53|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet54|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet55|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet56|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet57|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet58|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet0|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet1|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet4|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet5|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet16|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet17|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet20|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet21|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet6|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet7|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet8|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet9|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet10|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet11|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet12|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet13|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet14|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet15|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet32|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet36|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet37|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet38|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet39|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet40|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet41|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet42|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet22|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet23|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet24|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet25|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet26|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet27|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet28|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet29|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet30|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet31|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet48|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet52|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet53|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet54|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet55|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet56|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet57|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet58|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +} diff --git a/src/sonic-config-engine/tests/sample_output/py3/docker-dhcp-relay.supervisord.conf b/src/sonic-config-engine/tests/sample_output/py3/docker-dhcp-relay.supervisord.conf new file mode 100644 index 000000000000..e2135d05296b --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/docker-dhcp-relay.supervisord.conf @@ -0,0 +1,69 @@ +[supervisord] +logfile_maxbytes=1MB +logfile_backups=2 +nodaemon=true + +[eventlistener:dependent-startup] +command=python3 -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE +buffer_size=50 + +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name dhcp_relay +events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING +autostart=true +autorestart=unexpected + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true + +[program:start] +command=/usr/bin/start.sh +priority=2 +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running + +[group:isc-dhcp-relay] +programs=isc-dhcp-relay-Vlan1000 + +[program:isc-dhcp-relay-Vlan1000] +command=/usr/sbin/dhcrelay -d -m discard -a %%h:%%p %%P --name-alias-map-file /tmp/port-name-alias-map.txt -id Vlan1000 -iu PortChannel01 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 192.0.0.1 192.0.0.2 +priority=3 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited + + +[group:dhcpmon] +programs=dhcpmon-Vlan1000 + +[program:dhcpmon-Vlan1000] +command=/usr/sbin/dhcpmon -id Vlan1000 -iu PortChannel01 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 -im eth0 +priority=4 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=isc-dhcp-relay-Vlan1000:running + + + diff --git a/src/sonic-config-engine/tests/sample_output/py3/frr.conf b/src/sonic-config-engine/tests/sample_output/py3/frr.conf new file mode 100644 index 000000000000..bb3c4e214e20 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/frr.conf @@ -0,0 +1,95 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/frr.conf.j2 with config DB data +! file: frr.conf +! +! +! template: common/daemons.common.conf.j2 +! +hostname switch-t0 +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +agentx +! +! +! +! Enable nht through default route +ip nht resolve-via-default +! Enable link-detect (default disabled) +interface PortChannel01 +link-detect +! +interface PortChannel02 +link-detect +! +interface PortChannel03 +link-detect +! +interface PortChannel04 +link-detect +! +!! +! +! set static default route to mgmt gateway as a backup to learned default +ip route 0.0.0.0/0 10.0.0.1 200 +!! +! +! +! add static ipv6 /64 loopback route to allow bgpd to advertise the loopback route prefix +ipv6 route fc00:1::/64 Loopback0 +!! +! +! template: bgpd/bgpd.main.conf.j2 +! +! bgp multiple-instance +! +! BGP configuration +! +! TSA configuration +! +ip prefix-list PL_LoopbackV4 permit 10.1.0.32/32 +! +ipv6 prefix-list PL_LoopbackV6 permit fc00:1::/64 +! +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 5 permit 192.168.0.0/27 +! +! +! +router bgp 65100 +! + bgp log-neighbor-changes + no bgp default ipv4-unicast + no bgp ebgp-requires-policy +! + bgp bestpath as-path multipath-relax +! + bgp graceful-restart restart-time 240 + bgp graceful-restart + bgp graceful-restart preserve-fw-state +! + bgp router-id 10.1.0.32 +! + network 10.1.0.32/32 +! + address-family ipv6 + network fc00:1::32/64 + exit-address-family +! + network 192.168.0.1/27 +! +! +! + address-family ipv4 + maximum-paths 64 + exit-address-family + address-family ipv6 + maximum-paths 64 + exit-address-family +! +! end of template: bgpd/bgpd.main.conf.j2 +!! diff --git a/src/sonic-config-engine/tests/sample_output/py3/interfaces b/src/sonic-config-engine/tests/sample_output/py3/interfaces new file mode 100644 index 000000000000..6e952d6f71ea --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/interfaces @@ -0,0 +1,46 @@ +# +# =============== Managed by SONiC Config Engine DO NOT EDIT! =============== +# generated from /usr/share/sonic/templates/interfaces.j2 using sonic-cfggen +# file: /etc/network/interfaces +# +# The loopback network interface +auto lo +iface lo inet loopback + address 127.0.0.1 + netmask 255.255.0.0 + post-up ip addr del 127.0.0.1/8 dev lo + +# The management network interface +auto eth0 +iface eth0 inet static + address 10.0.0.100 + netmask 255.255.255.0 + network 10.0.0.0 + broadcast 10.0.0.255 + ########## management network policy routing rules + # management port up rules + up ip -4 route add default via 10.0.0.1 dev eth0 table default metric 201 + up ip -4 route add 10.0.0.0/24 dev eth0 table default + up ip -4 rule add pref 32765 from 10.0.0.100/32 table default + # management port down rules + pre-down ip -4 route delete default via 10.0.0.1 dev eth0 table default + pre-down ip -4 route delete 10.0.0.0/24 dev eth0 table default + pre-down ip -4 rule delete pref 32765 from 10.0.0.100/32 table default +iface eth0 inet6 static + address 2603:10e2:0:2902::8 + netmask 64 + network 2603:10e2:0:2902:: + broadcast 2603:10e2:0:2902:ffff:ffff:ffff:ffff + ########## management network policy routing rules + # management port up rules + up ip -6 route add default via 2603:10e2:0:2902::1 dev eth0 table default metric 201 + up ip -6 route add 2603:10e2:0:2902::/64 dev eth0 table default + up ip -6 rule add pref 32765 from 2603:10e2:0:2902::8/128 table default + # management port down rules + pre-down ip -6 route delete default via 2603:10e2:0:2902::1 dev eth0 table default + pre-down ip -6 route delete 2603:10e2:0:2902::/64 dev eth0 table default + pre-down ip -6 rule delete pref 32765 from 2603:10e2:0:2902::8/128 table default +# +source /etc/network/interfaces.d/* +# + diff --git a/src/sonic-config-engine/tests/sample_output/py3/ipinip.json b/src/sonic-config-engine/tests/sample_output/py3/ipinip.json new file mode 100644 index 000000000000..db70ea403121 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/ipinip.json @@ -0,0 +1,23 @@ +[ + { + "TUNNEL_DECAP_TABLE:IPINIP_TUNNEL" : { + "tunnel_type":"IPINIP", + "dst_ip":"10.0.0.56,10.0.0.58,10.0.0.60,10.0.0.62,10.1.0.32,192.168.0.1", + "dscp_mode":"pipe", + "ecn_mode":"copy_from_outer", + "ttl_mode":"pipe" + }, + "OP": "SET" + } + , + { + "TUNNEL_DECAP_TABLE:IPINIP_V6_TUNNEL" : { + "tunnel_type":"IPINIP", + "dst_ip":"fc00:1::32,fc00::71,fc00::75,fc00::79,fc00::7d", + "dscp_mode":"pipe", + "ecn_mode":"copy_from_outer", + "ttl_mode":"pipe" + }, + "OP": "SET" + } +] diff --git a/src/sonic-config-engine/tests/sample_output/l2switch.json b/src/sonic-config-engine/tests/sample_output/py3/l2switch.json similarity index 100% rename from src/sonic-config-engine/tests/sample_output/l2switch.json rename to src/sonic-config-engine/tests/sample_output/py3/l2switch.json diff --git a/src/sonic-config-engine/tests/sample_output/py3/lldp_conf/lldpd-ipv4-iface.conf b/src/sonic-config-engine/tests/sample_output/py3/lldp_conf/lldpd-ipv4-iface.conf new file mode 100644 index 000000000000..c9cb2c8123dd --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/lldp_conf/lldpd-ipv4-iface.conf @@ -0,0 +1,4 @@ +configure ports eth0 lldp portidsubtype local eth0 +configure system ip management pattern 10.0.0.100 +configure system hostname switch-t0 +pause diff --git a/src/sonic-config-engine/tests/sample_output/py3/lldp_conf/lldpd-ipv6-iface.conf b/src/sonic-config-engine/tests/sample_output/py3/lldp_conf/lldpd-ipv6-iface.conf new file mode 100644 index 000000000000..f5727556fdf3 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/lldp_conf/lldpd-ipv6-iface.conf @@ -0,0 +1,2 @@ +configure system hostname switch-t0 +pause diff --git a/src/sonic-config-engine/tests/sample_output/py3/mvrf_interfaces b/src/sonic-config-engine/tests/sample_output/py3/mvrf_interfaces new file mode 100644 index 000000000000..9e5c8a4261cf --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/mvrf_interfaces @@ -0,0 +1,61 @@ +# +# =============== Managed by SONiC Config Engine DO NOT EDIT! =============== +# generated from /usr/share/sonic/templates/interfaces.j2 using sonic-cfggen +# file: /etc/network/interfaces +# +auto mgmt +iface mgmt + vrf-table 5000 +# 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/16 dev lo-m + up ip link set lo-m up + down ip link delete dev lo-m +# The loopback network interface +auto lo +iface lo inet loopback + address 127.0.0.1 + netmask 255.255.0.0 + post-up ip addr del 127.0.0.1/8 dev lo + +# The management network interface +auto eth0 +iface eth0 inet static + address 10.0.0.100 + netmask 255.255.255.0 + network 10.0.0.0 + broadcast 10.0.0.255 + vrf mgmt + ########## management network policy routing rules + # management port up rules + up ip -4 route add default via 10.0.0.1 dev eth0 table 5000 metric 201 + up ip -4 route add 10.0.0.0/24 dev eth0 table 5000 + up ip -4 rule add pref 32765 from 10.0.0.100/32 table 5000 + up ip rule add pref 32764 to 11.11.11.11 table 5000 + up ip rule add pref 32764 to 22.22.22.0/23 table 5000 + # management port down rules + pre-down ip -4 route delete default via 10.0.0.1 dev eth0 table 5000 + pre-down ip -4 route delete 10.0.0.0/24 dev eth0 table 5000 + pre-down ip -4 rule delete pref 32765 from 10.0.0.100/32 table 5000 + pre-down ip rule delete pref 32764 to 11.11.11.11 table 5000 + pre-down ip rule delete pref 32764 to 22.22.22.0/23 table 5000 +iface eth0 inet6 static + address 2603:10e2:0:2902::8 + netmask 64 + network 2603:10e2:0:2902:: + broadcast 2603:10e2:0:2902:ffff:ffff:ffff:ffff + vrf mgmt + ########## management network policy routing rules + # management port up rules + up ip -6 route add default via 2603:10e2:0:2902::1 dev eth0 table 5000 metric 201 + up ip -6 route add 2603:10e2:0:2902::/64 dev eth0 table 5000 + up ip -6 rule add pref 32765 from 2603:10e2:0:2902::8/128 table 5000 + # management port down rules + 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 pref 32765 from 2603:10e2:0:2902::8/128 table 5000 +# +source /etc/network/interfaces.d/* +# + diff --git a/src/sonic-config-engine/tests/sample_output/py3/ndppd.conf b/src/sonic-config-engine/tests/sample_output/py3/ndppd.conf new file mode 100644 index 000000000000..28a239006d24 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/ndppd.conf @@ -0,0 +1,25 @@ +# =========== Managed by sonic-cfggen -- DO NOT edit manually! ==================== +# Generated by /usr/share/sonic/templates/ndppd.conf.j2 using config DB data +# File: /etc/ndppd.conf +# +# Config file for ndppd, the NDP Proxy Daemon +# See man page for ndppd.conf.5 for descriptions of all available options + +proxy Vlan1000 { + rule fc01:1000::/64 { + static + } + rule fc02:1000::/64 { + static + } + rule fc03:1000::/64 { + static + } +} + +proxy Vlan2000 { + rule fc01:2000::/64 { + static + } +} + diff --git a/src/sonic-config-engine/tests/sample_output/ports.json b/src/sonic-config-engine/tests/sample_output/py3/ports.json similarity index 100% rename from src/sonic-config-engine/tests/sample_output/ports.json rename to src/sonic-config-engine/tests/sample_output/py3/ports.json diff --git a/src/sonic-config-engine/tests/sample_output/py3/qos-arista7050.json b/src/sonic-config-engine/tests/sample_output/py3/qos-arista7050.json new file mode 100644 index 000000000000..aa05ef4ec36c --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/qos-arista7050.json @@ -0,0 +1,977 @@ +{ + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "0", + "2": "0", + "3": "3", + "4": "4", + "5": "0", + "6": "0", + "7": "7" + } + }, + "MAP_PFC_PRIORITY_TO_QUEUE": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0" : "1", + "1" : "1", + "2" : "1", + "3" : "3", + "4" : "4", + "5" : "2", + "6" : "1", + "7" : "1", + "8" : "0", + "9" : "1", + "10": "1", + "11": "1", + "12": "1", + "13": "1", + "14": "1", + "15": "1", + "16": "1", + "17": "1", + "18": "1", + "19": "1", + "20": "1", + "21": "1", + "22": "1", + "23": "1", + "24": "1", + "25": "1", + "26": "1", + "27": "1", + "28": "1", + "29": "1", + "30": "1", + "31": "1", + "32": "1", + "33": "1", + "34": "1", + "35": "1", + "36": "1", + "37": "1", + "38": "1", + "39": "1", + "40": "1", + "41": "1", + "42": "1", + "43": "1", + "44": "1", + "45": "1", + "46": "5", + "47": "1", + "48": "6", + "49": "1", + "50": "1", + "51": "1", + "52": "1", + "53": "1", + "54": "1", + "55": "1", + "56": "1", + "57": "1", + "58": "1", + "59": "1", + "60": "1", + "61": "1", + "62": "1", + "63": "1" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type" : "DWRR", + "weight": "14" + }, + "scheduler.1": { + "type" : "DWRR", + "weight": "15" + } + }, + "PORT_QOS_MAP": { + "Ethernet4": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet8": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet12": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet16": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet20": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet24": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet28": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet32": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet36": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet40": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet44": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet48": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet52": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet56": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet60": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet64": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet68": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet72": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet76": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet80": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet84": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet88": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet92": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet96": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet112": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet116": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet120": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet124": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "wred_green_enable" : "true", + "wred_yellow_enable" : "true", + "wred_red_enable" : "true", + "ecn" : "ecn_all", + "green_max_threshold" : "2097152", + "green_min_threshold" : "1048576", + "yellow_max_threshold" : "2097152", + "yellow_min_threshold" : "1048576", + "red_max_threshold" : "2097152", + "red_min_threshold" : "1048576", + "green_drop_probability" : "5", + "yellow_drop_probability": "5", + "red_drop_probability" : "5" + } + }, + "QUEUE": { + "Ethernet4|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet8|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet12|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet16|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet20|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet24|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet28|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet32|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet36|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet40|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet44|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet48|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet52|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet56|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet60|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet64|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet68|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet72|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet76|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet80|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet84|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet88|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet92|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet96|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet112|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet116|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet120|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet124|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet4|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet8|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet12|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet16|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet20|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet24|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet28|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet32|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet36|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet40|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet44|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet48|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet52|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet56|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet60|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet64|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet68|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet72|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet76|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet80|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet84|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet88|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet92|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet96|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet112|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet116|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet120|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet124|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet4|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet44|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet60|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet64|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet68|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet72|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet76|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet80|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet84|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet88|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet92|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet96|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet112|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet116|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet120|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet124|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet44|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet60|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet64|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet68|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet72|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet76|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet80|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet84|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet88|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet92|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet96|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet112|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet116|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet120|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet124|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet44|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet60|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet64|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet68|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet72|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet76|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet80|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet84|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet88|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet92|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet96|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet112|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet116|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet120|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet124|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet44|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet60|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet64|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet68|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet72|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet76|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet80|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet84|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet88|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet92|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet96|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet112|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet116|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet120|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet124|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet44|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet60|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet64|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet68|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet72|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet76|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet80|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet84|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet88|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet92|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet96|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet112|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet116|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet120|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet124|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + } + } +} diff --git a/src/sonic-config-engine/tests/sample_output/py3/qos-dell6100.json b/src/sonic-config-engine/tests/sample_output/py3/qos-dell6100.json new file mode 100644 index 000000000000..75d9b3a87eee --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/qos-dell6100.json @@ -0,0 +1,1457 @@ +{ + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "0", + "2": "0", + "3": "3", + "4": "4", + "5": "0", + "6": "0", + "7": "7" + } + }, + "MAP_PFC_PRIORITY_TO_QUEUE": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0" : "1", + "1" : "1", + "2" : "1", + "3" : "3", + "4" : "4", + "5" : "2", + "6" : "1", + "7" : "1", + "8" : "0", + "9" : "1", + "10": "1", + "11": "1", + "12": "1", + "13": "1", + "14": "1", + "15": "1", + "16": "1", + "17": "1", + "18": "1", + "19": "1", + "20": "1", + "21": "1", + "22": "1", + "23": "1", + "24": "1", + "25": "1", + "26": "1", + "27": "1", + "28": "1", + "29": "1", + "30": "1", + "31": "1", + "32": "1", + "33": "1", + "34": "1", + "35": "1", + "36": "1", + "37": "1", + "38": "1", + "39": "1", + "40": "1", + "41": "1", + "42": "1", + "43": "1", + "44": "1", + "45": "1", + "46": "5", + "47": "1", + "48": "6", + "49": "1", + "50": "1", + "51": "1", + "52": "1", + "53": "1", + "54": "1", + "55": "1", + "56": "1", + "57": "1", + "58": "1", + "59": "1", + "60": "1", + "61": "1", + "62": "1", + "63": "1" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type" : "DWRR", + "weight": "14" + }, + "scheduler.1": { + "type" : "DWRR", + "weight": "15" + } + }, + "PORT_QOS_MAP": { + "Ethernet0": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet1": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet4": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet5": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet6": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet7": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet8": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet9": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet10": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet11": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet12": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet13": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet14": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet15": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet16": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet17": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet20": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet21": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet22": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet23": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet24": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet25": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet26": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet27": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet28": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet29": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet30": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet31": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet32": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet36": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet37": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet38": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet39": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet40": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet41": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet42": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet48": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet52": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet53": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet54": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet55": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet56": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet57": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet58": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "wred_green_enable" : "true", + "wred_yellow_enable" : "true", + "wred_red_enable" : "true", + "ecn" : "ecn_all", + "green_max_threshold" : "2097152", + "green_min_threshold" : "250000", + "yellow_max_threshold" : "2097152", + "yellow_min_threshold" : "1048576", + "red_max_threshold" : "2097152", + "red_min_threshold" : "1048576", + "green_drop_probability" : "5", + "yellow_drop_probability": "5", + "red_drop_probability" : "5" + } + }, + "QUEUE": { + "Ethernet0|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet1|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet4|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet5|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet6|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet7|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet8|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet9|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet10|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet11|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet12|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet13|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet14|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet15|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet16|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet17|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet20|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet21|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet22|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet23|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet24|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet25|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet26|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet27|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet28|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet29|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet30|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet31|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet32|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet36|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet37|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet38|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet39|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet40|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet41|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet42|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet48|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet52|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet53|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet54|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet55|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet56|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet57|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet58|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet0|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet1|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet4|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet5|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet6|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet7|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet8|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet9|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet10|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet11|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet12|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet13|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet14|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet15|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet16|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet17|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet20|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet21|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet22|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet23|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet24|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet25|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet26|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet27|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet28|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet29|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet30|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet31|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet32|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet36|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet37|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet38|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet39|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet40|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet41|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet42|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet48|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet52|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet53|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet54|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet55|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet56|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet57|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet58|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet0|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet1|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet5|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet6|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet7|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet9|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet10|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet11|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet13|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet14|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet15|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet17|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet21|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet22|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet23|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet25|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet26|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet27|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet29|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet30|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet31|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet37|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet38|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet39|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet41|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet42|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet53|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet54|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet55|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet57|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet58|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet0|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet1|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet5|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet6|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet7|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet9|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet10|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet11|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet13|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet14|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet15|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet17|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet21|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet22|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet23|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet25|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet26|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet27|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet29|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet30|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet31|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet37|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet38|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet39|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet41|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet42|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet53|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet54|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet55|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet57|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet58|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet0|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet1|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet5|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet6|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet7|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet9|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet10|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet11|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet13|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet14|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet15|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet17|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet21|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet22|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet23|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet25|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet26|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet27|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet29|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet30|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet31|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet37|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet38|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet39|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet41|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet42|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet53|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet54|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet55|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet57|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet58|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet0|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet1|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet5|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet6|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet7|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet9|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet10|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet11|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet13|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet14|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet15|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet17|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet21|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet22|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet23|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet25|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet26|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet27|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet29|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet30|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet31|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet37|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet38|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet39|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet41|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet42|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet53|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet54|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet55|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet57|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet58|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet0|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet1|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet5|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet6|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet7|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet9|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet10|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet11|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet13|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet14|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet15|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet17|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet21|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet22|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet23|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet25|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet26|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet27|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet29|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet30|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet31|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet37|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet38|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet39|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet41|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet42|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet53|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet54|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet55|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet57|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet58|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + } + } +} diff --git a/src/sonic-config-engine/tests/sample_output/py3/staticd_frr.conf b/src/sonic-config-engine/tests/sample_output/py3/staticd_frr.conf new file mode 100644 index 000000000000..54d83525b1f0 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/staticd_frr.conf @@ -0,0 +1,25 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/frr/staticd.conf.j2 using config DB data +! file: staticd.conf +! +! +! template: common/daemons.common.conf.j2 +! +hostname switch-t0 +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +! +! set static default route to mgmt gateway as a backup to learned default +ip route 0.0.0.0/0 10.0.0.1 200 +!! +! +! +! add static ipv6 /64 loopback route to allow bgpd to advertise the loopback route prefix +ipv6 route fc00:1::/64 Loopback0 +!! diff --git a/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-bgpd.conf b/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-bgpd.conf new file mode 100644 index 000000000000..7633ac117bf7 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-bgpd.conf @@ -0,0 +1,88 @@ +! +! template: bgpd/bgpd.conf.j2 +! +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/quagga/bgpd.conf.j2 with config DB data +! file: bgpd.conf +! +! +! template: common/daemons.common.conf.j2 +! +hostname SpineFront01 +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +agentx +! +! +! Vnet BGP instance +router bgp 4000 vrf VnetFE + no bgp default ipv4-unicast + bgp log-neighbor-changes + bgp bestpath as-path multipath-relax + no bgp default ipv4-unicast + bgp graceful-restart restart-time 240 + bgp graceful-restart + bgp router-id 4.0.0.0 + neighbor 192.168.0.1 remote-as 3000 + neighbor 192.168.0.1 description Leaf01 + neighbor 192.168.0.1 timers 3 10 + address-family ipv4 unicast + neighbor 192.168.0.1 activate + neighbor 192.168.0.1 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + address-family l2vpn evpn + advertise ipv4 unicast + exit-address-family +!! +! +! template: bgpd/bgpd.main.conf.j2 +! +! bgp multiple-instance +! +! BGP configuration +! +! TSA configuration +! +ip prefix-list PL_LoopbackV4 permit 4.0.0.0/32 +! +! +! +! +router bgp 4000 +! + bgp log-neighbor-changes + no bgp default ipv4-unicast + no bgp ebgp-requires-policy +! + bgp bestpath as-path multipath-relax +! + bgp graceful-restart restart-time 240 + bgp graceful-restart + bgp graceful-restart preserve-fw-state +! + bgp router-id 4.0.0.0 +! + network 4.0.0.0/32 +! +! +! +! +! + address-family ipv4 + maximum-paths 64 + exit-address-family + address-family ipv6 + maximum-paths 64 + exit-address-family +! +! end of template: bgpd/bgpd.main.conf.j2 +!! +! end of template: bgpd/bgpd.conf.j2 +! diff --git a/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-vni-zebra.conf b/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-vni-zebra.conf new file mode 100644 index 000000000000..7b7987650d61 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-vni-zebra.conf @@ -0,0 +1,34 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/zebra/zebra.conf.j2 using config DB data +! file: zebra.conf +! +! +! template: common/daemons.common.conf.j2 +! +hostname SpineFront01 +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +! +vrf VnetFE +vni 9000 +! +! +! Enable nht through default route +ip nht resolve-via-default +! Enable link-detect (default disabled) +interface Ethernet0 +link-detect +! +interface Ethernet4 +link-detect +! +interface Ethernet8 +link-detect +! +!! diff --git a/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-zebra.conf b/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-zebra.conf new file mode 100644 index 000000000000..fc8a8a2fb3bf --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-zebra.conf @@ -0,0 +1,34 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/zebra/zebra.conf.j2 using config DB data +! file: zebra.conf +! +! +! template: common/daemons.common.conf.j2 +! +hostname SpineFront01 +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +! +vrf VnetFE +vni 8000 +! +! +! Enable nht through default route +ip nht resolve-via-default +! Enable link-detect (default disabled) +interface Ethernet0 +link-detect +! +interface Ethernet4 +link-detect +! +interface Ethernet8 +link-detect +! +!! diff --git a/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh b/src/sonic-config-engine/tests/sample_output/py3/wait_for_intf.sh similarity index 100% rename from src/sonic-config-engine/tests/sample_output/wait_for_intf.sh rename to src/sonic-config-engine/tests/sample_output/py3/wait_for_intf.sh diff --git a/src/sonic-config-engine/tests/sample_output/py3/zebra_frr.conf b/src/sonic-config-engine/tests/sample_output/py3/zebra_frr.conf new file mode 100644 index 000000000000..f596c5579d3b --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/zebra_frr.conf @@ -0,0 +1,34 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/zebra/zebra.conf.j2 using config DB data +! file: zebra.conf +! +! +! template: common/daemons.common.conf.j2 +! +hostname switch-t0 +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +! +! +! Enable nht through default route +ip nht resolve-via-default +! Enable link-detect (default disabled) +interface PortChannel01 +link-detect +! +interface PortChannel02 +link-detect +! +interface PortChannel03 +link-detect +! +interface PortChannel04 +link-detect +! +!! diff --git a/src/sonic-config-engine/tests/sample_output/zebra_quagga.conf b/src/sonic-config-engine/tests/sample_output/py3/zebra_quagga.conf similarity index 100% rename from src/sonic-config-engine/tests/sample_output/zebra_quagga.conf rename to src/sonic-config-engine/tests/sample_output/py3/zebra_quagga.conf diff --git a/src/sonic-config-engine/tests/sample_output/qos-dell6100.json b/src/sonic-config-engine/tests/sample_output/qos-dell6100.json deleted file mode 100644 index 680ca6232e11..000000000000 --- a/src/sonic-config-engine/tests/sample_output/qos-dell6100.json +++ /dev/null @@ -1,1457 +0,0 @@ -{ - "TC_TO_PRIORITY_GROUP_MAP": { - "AZURE": { - "0": "0", - "1": "0", - "2": "0", - "3": "3", - "4": "4", - "5": "0", - "6": "0", - "7": "7" - } - }, - "MAP_PFC_PRIORITY_TO_QUEUE": { - "AZURE": { - "0": "0", - "1": "1", - "2": "2", - "3": "3", - "4": "4", - "5": "5", - "6": "6", - "7": "7" - } - }, - "TC_TO_QUEUE_MAP": { - "AZURE": { - "0": "0", - "1": "1", - "2": "2", - "3": "3", - "4": "4", - "5": "5", - "6": "6", - "7": "7" - } - }, - "DSCP_TO_TC_MAP": { - "AZURE": { - "0" : "1", - "1" : "1", - "2" : "1", - "3" : "3", - "4" : "4", - "5" : "2", - "6" : "1", - "7" : "1", - "8" : "0", - "9" : "1", - "10": "1", - "11": "1", - "12": "1", - "13": "1", - "14": "1", - "15": "1", - "16": "1", - "17": "1", - "18": "1", - "19": "1", - "20": "1", - "21": "1", - "22": "1", - "23": "1", - "24": "1", - "25": "1", - "26": "1", - "27": "1", - "28": "1", - "29": "1", - "30": "1", - "31": "1", - "32": "1", - "33": "1", - "34": "1", - "35": "1", - "36": "1", - "37": "1", - "38": "1", - "39": "1", - "40": "1", - "41": "1", - "42": "1", - "43": "1", - "44": "1", - "45": "1", - "46": "5", - "47": "1", - "48": "6", - "49": "1", - "50": "1", - "51": "1", - "52": "1", - "53": "1", - "54": "1", - "55": "1", - "56": "1", - "57": "1", - "58": "1", - "59": "1", - "60": "1", - "61": "1", - "62": "1", - "63": "1" - } - }, - "SCHEDULER": { - "scheduler.0": { - "type" : "DWRR", - "weight": "14" - }, - "scheduler.1": { - "type" : "DWRR", - "weight": "15" - } - }, - "PORT_QOS_MAP": { - "Ethernet0": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet1": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet4": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet5": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet6": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet7": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet8": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet9": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet10": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet11": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet12": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet13": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet14": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet15": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet16": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet17": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet20": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet21": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet22": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet23": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet24": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet25": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet26": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet27": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet28": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet29": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet30": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet31": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet32": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet36": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet37": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet38": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet39": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet40": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet41": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet42": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet48": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet52": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet53": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet54": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet55": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet56": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet57": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - }, - "Ethernet58": { - "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", - "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", - "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", - "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", - "pfc_enable" : "3,4" - } - }, - "WRED_PROFILE": { - "AZURE_LOSSLESS" : { - "wred_green_enable" : "true", - "wred_yellow_enable" : "true", - "wred_red_enable" : "true", - "ecn" : "ecn_all", - "green_max_threshold" : "2097152", - "green_min_threshold" : "1048576", - "yellow_max_threshold" : "2097152", - "yellow_min_threshold" : "1048576", - "red_max_threshold" : "2097152", - "red_min_threshold" : "1048576", - "green_drop_probability" : "5", - "yellow_drop_probability": "5", - "red_drop_probability" : "5" - } - }, - "QUEUE": { - "Ethernet0|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet1|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet4|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet5|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet6|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet7|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet8|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet9|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet10|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet11|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet12|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet13|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet14|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet15|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet16|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet17|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet20|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet21|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet22|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet23|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet24|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet25|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet26|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet27|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet28|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet29|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet30|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet31|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet32|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet36|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet37|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet38|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet39|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet40|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet41|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet42|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet48|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet52|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet53|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet54|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet55|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet56|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet57|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet58|3": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet0|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet1|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet4|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet5|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet6|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet7|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet8|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet9|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet10|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet11|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet12|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet13|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet14|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet15|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet16|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet17|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet20|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet21|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet22|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet23|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet24|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet25|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet26|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet27|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet28|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet29|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet30|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet31|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet32|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet36|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet37|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet38|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet39|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet40|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet41|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet42|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet48|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet52|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet53|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet54|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet55|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet56|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet57|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet58|4": { - "scheduler" : "[SCHEDULER|scheduler.1]", - "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet0|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet1|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet4|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet5|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet6|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet7|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet8|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet9|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet10|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet11|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet12|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet13|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet14|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet15|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet16|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet17|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet20|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet21|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet22|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet23|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet24|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet25|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet26|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet27|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet28|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet29|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet30|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet31|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet32|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet36|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet37|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet38|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet39|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet40|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet41|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet42|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet48|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet52|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet53|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet54|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet55|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet56|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet57|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet58|0": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet0|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet1|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet4|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet5|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet6|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet7|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet8|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet9|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet10|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet11|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet12|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet13|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet14|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet15|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet16|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet17|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet20|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet21|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet22|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet23|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet24|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet25|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet26|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet27|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet28|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet29|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet30|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet31|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet32|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet36|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet37|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet38|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet39|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet40|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet41|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet42|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet48|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet52|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet53|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet54|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet55|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet56|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet57|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet58|1": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet0|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet1|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet4|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet5|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet6|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet7|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet8|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet9|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet10|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet11|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet12|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet13|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet14|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet15|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet16|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet17|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet20|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet21|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet22|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet23|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet24|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet25|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet26|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet27|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet28|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet29|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet30|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet31|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet32|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet36|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet37|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet38|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet39|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet40|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet41|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet42|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet48|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet52|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet53|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet54|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet55|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet56|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet57|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet58|2": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet0|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet1|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet4|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet5|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet6|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet7|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet8|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet9|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet10|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet11|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet12|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet13|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet14|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet15|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet16|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet17|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet20|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet21|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet22|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet23|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet24|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet25|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet26|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet27|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet28|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet29|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet30|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet31|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet32|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet36|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet37|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet38|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet39|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet40|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet41|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet42|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet48|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet52|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet53|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet54|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet55|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet56|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet57|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet58|5": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet0|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet1|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet4|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet5|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet6|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet7|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet8|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet9|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet10|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet11|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet12|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet13|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet14|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet15|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet16|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet17|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet20|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet21|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet22|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet23|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet24|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet25|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet26|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet27|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet28|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet29|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet30|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet31|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet32|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet36|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet37|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet38|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet39|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet40|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet41|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet42|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet48|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet52|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet53|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet54|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet55|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet56|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet57|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - }, - "Ethernet58|6": { - "scheduler": "[SCHEDULER|scheduler.0]" - } - } -} diff --git a/src/sonic-config-engine/tests/sample_output/staticd_frr.conf b/src/sonic-config-engine/tests/sample_output/staticd_frr.conf deleted file mode 100644 index 12a81de82125..000000000000 --- a/src/sonic-config-engine/tests/sample_output/staticd_frr.conf +++ /dev/null @@ -1,18 +0,0 @@ -! -! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== -! generated by templates/frr/staticd.conf.j2 using config DB data -! file: staticd.conf -! -! -! -hostname switch-t0 -password zebra -enable password zebra -! -log syslog informational -log facility local4 -!! -! -! set static default route to mgmt gateway as a backup to learned default -ip route 0.0.0.0/0 10.0.0.1 200 -!! diff --git a/src/sonic-config-engine/tests/sample_output/t0-switch-masic1.json b/src/sonic-config-engine/tests/sample_output/t0-switch-masic1.json new file mode 100644 index 000000000000..34fd946da361 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/t0-switch-masic1.json @@ -0,0 +1,10 @@ +[ + { + "SWITCH_TABLE:switch": { + "ecmp_hash_seed": "11", + "lag_hash_seed": "11", + "fdb_aging_time": "600" + }, + "OP": "SET" + } +] diff --git a/src/sonic-config-engine/tests/sample_output/t0-switch-masic3.json b/src/sonic-config-engine/tests/sample_output/t0-switch-masic3.json new file mode 100644 index 000000000000..d9f929679cbc --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/t0-switch-masic3.json @@ -0,0 +1,10 @@ +[ + { + "SWITCH_TABLE:switch": { + "ecmp_hash_seed": "13", + "lag_hash_seed": "13", + "fdb_aging_time": "600" + }, + "OP": "SET" + } +] diff --git a/src/sonic-config-engine/tests/sample_output/t0-switch.json b/src/sonic-config-engine/tests/sample_output/t0-switch.json new file mode 100644 index 000000000000..414e53b8a356 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/t0-switch.json @@ -0,0 +1,10 @@ +[ + { + "SWITCH_TABLE:switch": { + "ecmp_hash_seed": "0", + "lag_hash_seed": "0", + "fdb_aging_time": "600" + }, + "OP": "SET" + } +] diff --git a/src/sonic-config-engine/tests/sample_output/t1-switch.json b/src/sonic-config-engine/tests/sample_output/t1-switch.json new file mode 100644 index 000000000000..fdae474251f0 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/t1-switch.json @@ -0,0 +1,10 @@ +[ + { + "SWITCH_TABLE:switch": { + "ecmp_hash_seed": "10", + "lag_hash_seed": "10", + "fdb_aging_time": "600" + }, + "OP": "SET" + } +] diff --git a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-bgpd.conf b/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-bgpd.conf deleted file mode 100644 index b0b5e2cb1192..000000000000 --- a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-bgpd.conf +++ /dev/null @@ -1,85 +0,0 @@ -! -! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== -! generated by templates/quagga/bgpd.conf.j2 with config DB data -! file: bgpd.conf -! -! -! -hostname SpineFront01 -password zebra -enable password zebra -! -log syslog informational -log facility local4 -!! -agentx -! -! -! Vnet BGP instance -router bgp 4000 vrf VnetFE - no bgp default ipv4-unicast - bgp log-neighbor-changes - bgp bestpath as-path multipath-relax - no bgp default ipv4-unicast - bgp graceful-restart restart-time 240 - bgp graceful-restart - bgp router-id 4.0.0.0 - neighbor 192.168.0.1 remote-as 3000 - neighbor 192.168.0.1 description Leaf01 - neighbor 192.168.0.1 timers 3 10 - address-family ipv4 unicast - neighbor 192.168.0.1 activate - neighbor 192.168.0.1 soft-reconfiguration inbound - maximum-paths 64 - exit-address-family - address-family l2vpn evpn - advertise ipv4 unicast - exit-address-family -!! -! -! -! bgp multiple-instance -! -route-map FROM_BGP_SPEAKER_V4 permit 10 -! -route-map TO_BGP_SPEAKER_V4 deny 10 -! -ip prefix-list PL_LoopbackV4 permit 4.0.0.0/32 -! -! -route-map TO_BGP_PEER_V4 permit 100 -! -route-map TO_BGP_PEER_V6 permit 100 -! -! -route-map ISOLATE permit 10 - set as-path prepend 4000 -! -route-map set-next-hop-global-v6 permit 10 - set ipv6 next-hop prefer-global -! -router bgp 4000 - bgp log-neighbor-changes - bgp bestpath as-path multipath-relax - no bgp default ipv4-unicast - bgp graceful-restart restart-time 240 - bgp graceful-restart - bgp router-id 4.0.0.0 - network 4.0.0.0/32 - address-family ipv4 - maximum-paths 64 - exit-address-family - address-family ipv6 - maximum-paths 64 - exit-address-family - neighbor PEER_V4 peer-group - neighbor PEER_V6 peer-group - address-family ipv4 - neighbor PEER_V4 soft-reconfiguration inbound - neighbor PEER_V4 route-map TO_BGP_PEER_V4 out - exit-address-family - address-family ipv6 - neighbor PEER_V6 soft-reconfiguration inbound - neighbor PEER_V6 route-map TO_BGP_PEER_V6 out - exit-address-family -!! diff --git a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-pc-zebra.conf b/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-pc-zebra.conf index 312394bf76c9..be261bab99a8 100644 --- a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-pc-zebra.conf +++ b/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-pc-zebra.conf @@ -12,6 +12,8 @@ vrf VnetFE vni 8000 ! ! +! Enable nht through default route +ip nht resolve-via-default ! Enable link-detect (default disabled) interface PortChannel0 link-detect diff --git a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-vni-zebra.conf b/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-vni-zebra.conf deleted file mode 100644 index bd2b5c84f471..000000000000 --- a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-vni-zebra.conf +++ /dev/null @@ -1,37 +0,0 @@ -! -! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== -! generated by templates/quagga/zebra.conf.j2 using config DB data -! file: zebra.conf -! -! -! -hostname SpineFront01 -password zebra -enable password zebra -! -log syslog informational -log facility local4 -!! -! -vrf VnetFE -vni 9000 -! -! -! Enable link-detect (default disabled) -interface Ethernet0 -link-detect -! -interface Ethernet4 -link-detect -! -interface Ethernet8 -link-detect -! -! -! Set ip source to loopback for bgp learned routes -route-map RM_SET_SRC permit 10 - set src 4.0.0.0 -! -ip protocol bgp route-map RM_SET_SRC -! -!! diff --git a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-zebra.conf b/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-zebra.conf deleted file mode 100644 index e047fcd64f29..000000000000 --- a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-zebra.conf +++ /dev/null @@ -1,37 +0,0 @@ -! -! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== -! generated by templates/quagga/zebra.conf.j2 using config DB data -! file: zebra.conf -! -! -! -hostname SpineFront01 -password zebra -enable password zebra -! -log syslog informational -log facility local4 -!! -! -vrf VnetFE -vni 8000 -! -! -! Enable link-detect (default disabled) -interface Ethernet0 -link-detect -! -interface Ethernet4 -link-detect -! -interface Ethernet8 -link-detect -! -! -! Set ip source to loopback for bgp learned routes -route-map RM_SET_SRC permit 10 - set src 4.0.0.0 -! -ip protocol bgp route-map RM_SET_SRC -! -!! diff --git a/src/sonic-config-engine/tests/sample_output/zebra_frr.conf b/src/sonic-config-engine/tests/sample_output/zebra_frr.conf deleted file mode 100644 index 690f609dafcf..000000000000 --- a/src/sonic-config-engine/tests/sample_output/zebra_frr.conf +++ /dev/null @@ -1,43 +0,0 @@ -! -! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== -! generated by templates/quagga/zebra.conf.j2 using config DB data -! file: zebra.conf -! -! -! -hostname switch-t0 -password zebra -enable password zebra -! -log syslog informational -log facility local4 -!! -! -! -! Enable link-detect (default disabled) -interface PortChannel01 -link-detect -! -interface PortChannel02 -link-detect -! -interface PortChannel03 -link-detect -! -interface PortChannel04 -link-detect -! -! -! Set ip source to loopback for bgp learned routes -route-map RM_SET_SRC permit 10 - set src 10.1.0.32 -! - -route-map RM_SET_SRC6 permit 10 - set src fc00:1::32 -! -ip protocol bgp route-map RM_SET_SRC -! -ipv6 protocol bgp route-map RM_SET_SRC6 -! -!! diff --git a/src/sonic-config-engine/tests/sample_platform.json b/src/sonic-config-engine/tests/sample_platform.json new file mode 100644 index 000000000000..fd11a49ed0a0 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_platform.json @@ -0,0 +1,196 @@ +{ + "interfaces": { + "Ethernet0": { + "index": "1,1,1,1", + "lanes": "0,1,2,3", + "alias_at_lanes": "Eth1/1, Eth1/2, Eth1/3, Eth1/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet4": { + "index": "2,2,2,2", + "lanes": "4,5,6,7", + "alias_at_lanes": "Eth2/1, Eth2/2, Eth2/3, Eth2/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]" + }, + "Ethernet8": { + "index": "3,3,3,3", + "lanes": "8,9,10,11", + "alias_at_lanes": "Eth3/1, Eth3/2, Eth3/3, Eth3/4", + "breakout_modes": "1x100G[40G],2x50G,2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet12": { + "index": "4,4,4,4", + "lanes": "12,13,14,15", + "alias_at_lanes": "Eth4/1, Eth4/2, Eth4/3, Eth4/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet16": { + "index": "5,5,5,5", + "lanes": "16,17,18,19", + "alias_at_lanes": "Eth5/1, Eth5/2, Eth5/3, Eth5/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet20": { + "index": "6,6,6,6", + "lanes": "20,21,22,23", + "alias_at_lanes": "Eth6/1, Eth6/2, Eth6/3, Eth6/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet24": { + "index": "7,7,7,7", + "lanes": "24,25,26,27", + "alias_at_lanes": "Eth7/1, Eth7/2, Eth7/3, Eth7/4", + "breakout_modes": "1x100G[40G],4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet28": { + "index": "8,8,8,8", + "lanes": "28,29,30,31", + "alias_at_lanes": "Eth8/1, Eth8/2, Eth8/3, Eth8/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet32": { + "index": "9,9,9,9", + "lanes": "32,33,34,35", + "alias_at_lanes": "Eth9/1, Eth9/2, Eth9/3, Eth9/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet36": { + "index": "10,10,10,10", + "lanes": "36,37,38,39", + "alias_at_lanes": "Eth10/1, Eth10/2, Eth10/3, Eth10/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet40": { + "index": "11,11,11,11", + "lanes": "40,41,42,43", + "alias_at_lanes": "Eth11/1, Eth11/2, Eth11/3, Eth11/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet44": { + "index": "12,12,12,12", + "lanes": "44,45,46,47", + "alias_at_lanes": "Eth12/1, Eth12/2, Eth12/3, Eth12/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet48": { + "index": "13,13,13,13", + "lanes": "48,49,50,51", + "alias_at_lanes": "Eth13/1, Eth13/2, Eth13/3, Eth13/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet52": { + "index": "14,14,14,14", + "lanes": "52,53,54,55", + "alias_at_lanes": "Eth14/1, Eth14/2, Eth14/3, Eth14/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet56": { + "index": "15,15,15,15", + "lanes": "56,57,58,59", + "alias_at_lanes": "Eth15/1, Eth15/2, Eth15/3, Eth15/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet60": { + "index": "16,16,16,16", + "lanes": "60,61,62,63", + "alias_at_lanes": "Eth16/1, Eth16/2, Eth16/3, Eth16/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet64": { + "index": "17,17,17,17", + "lanes": "64,65,66,67", + "alias_at_lanes": "Eth17/1, Eth17/2, Eth17/3, Eth17/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet68": { + "index": "18,18,18,18", + "lanes": "68,69,70,71", + "alias_at_lanes": "Eth18/1, Eth18/2, Eth18/3, Eth18/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet72": { + "index": "19,19,19,19", + "lanes": "72,73,74,75", + "alias_at_lanes": "Eth19/1, Eth19/2, Eth19/3, Eth19/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet76": { + "index": "20,20,20,20", + "lanes": "76,77,78,79", + "alias_at_lanes": "Eth20/1, Eth20/2, Eth20/3, Eth20/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet80": { + "index": "21,21,21,21", + "lanes": "80,81,82,83", + "alias_at_lanes": "Eth21/1, Eth21/2, Eth21/3, Eth21/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet84": { + "index": "22,22,22,22", + "lanes": "84,85,86,87", + "alias_at_lanes": "Eth22/1, Eth22/2, Eth22/3, Eth22/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet88": { + "index": "23,23,23,23", + "lanes": "88,89,90,91", + "alias_at_lanes": "Eth23/1, Eth23/2, Eth23/3, Eth23/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet92": { + "index": "24,24,24,24", + "lanes": "92,93,94,95", + "alias_at_lanes": "Eth24/1, Eth24/2, Eth24/3, Eth24/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet96": { + "index": "25,25,25,25", + "lanes": "96,97,98,99", + "alias_at_lanes": "Eth25/1, Eth25/2, Eth25/3, Eth25/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet100": { + "index": "26,26,26,26", + "lanes": "100,101,102,103", + "alias_at_lanes": "Eth26/1, Eth26/2, Eth26/3, Eth26/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet104": { + "index": "27,27,27,27", + "lanes": "104,105,106,107", + "alias_at_lanes": "Eth27/1, Eth27/2, Eth27/3, Eth27/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet108": { + "index": "28,28,28,28", + "lanes": "108,109,110,111", + "alias_at_lanes": "Eth28/1, Eth28/2, Eth28/3, Eth28/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet112": { + "index": "29,29,29,29", + "lanes": "112,113,114,115", + "alias_at_lanes": "Eth29/1, Eth29/2, Eth29/3, Eth29/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet116": { + "index": "30,30,30,30", + "lanes": "116,117,118,119", + "alias_at_lanes": "Eth30/1, Eth30/2, Eth30/3, Eth30/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet120": { + "index": "31,31,31,31", + "lanes": "120,121,122,123", + "alias_at_lanes": "Eth31/1, Eth31/2, Eth31/3, Eth31/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + }, + "Ethernet124": { + "index": "32,32,32,32", + "lanes": "124,125,126,127", + "alias_at_lanes": "Eth32/1, Eth32/2, Eth32/3, Eth32/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)" + } + } +} diff --git a/src/sonic-config-engine/tests/simple-sample-graph-case.xml b/src/sonic-config-engine/tests/simple-sample-graph-case.xml index 35d8f8343796..95f501200c83 100644 --- a/src/sonic-config-engine/tests/simple-sample-graph-case.xml +++ b/src/sonic-config-engine/tests/simple-sample-graph-case.xml @@ -126,6 +126,9 @@ + + + ab1 @@ -134,6 +137,7 @@ 1000 1000 192.168.0.0/27 + 00:aa:bb:cc:dd:ee @@ -200,11 +204,86 @@ switch-01t1 port1 + + DeviceInterfaceLink + true + 10000 + switch-t0 + fortyGigE0/12 + switch-02t1 + port1 + + + DeviceInterfaceLink + true + 25000 + switch-t0 + fortyGigE0/4 + server1 + port1 + + + DeviceInterfaceLink + true + 40000 + switch-t0 + fortyGigE0/8 + server2 + port1 + + + LogicalLink + 10000 + false + switch-t0 + fortyGigE0/4 + true + mux-cable + L + true + + + LogicalLink + 10000 + false + switch-t0 + fortyGigE0/8 + true + mux-cable + U + true + + + LogicalLink + 0 + false + switch-t0 + MuxTunnel0 + false + switch2-t0 + MuxTunnel0 + true + - + + ToRRouter +
+ 26.1.1.10/32 +
switch-t0 Force10-S6000 + AAA00PrdStr00 +
+ +
+ 25.1.1.10/32 +
+ + 10.7.0.196/26 + + switch2-t0 + Force10-S6000
switch-01t1 @@ -218,8 +297,61 @@ Force10-S6000 + + Server +
+ 10.10.10.1/32 +
+ + fe80::0001/80 + + + 10.0.0.1/32 + + server1 + server-sku +
+ + Server +
+ 10.10.10.2/32 +
+ + fe80::0002/128 + + + 10.0.0.2/32 + + server2 + server-sku +
+ + + + + + + GeminiPeeringLink + + True + + + UpperTOR + + switch-t0 + + + LowerTOR + + switch2-t0 + + + switch2-t0:MuxTunnel0;switch-t0:MuxTunnel0 + + + @@ -258,6 +390,16 @@ 10.0.10.7;10.0.10.8 + + KubernetesEnabled + + 0 + + + KubernetesServerIp + + 10.10.10.10 + @@ -340,6 +482,6 @@ - switch-T0 + switch-t0 Force10-S6000 diff --git a/src/sonic-config-engine/tests/simple-sample-graph-metadata.xml b/src/sonic-config-engine/tests/simple-sample-graph-metadata.xml index 1b1da1ff1787..2b3368b7a9c7 100644 --- a/src/sonic-config-engine/tests/simple-sample-graph-metadata.xml +++ b/src/sonic-config-engine/tests/simple-sample-graph-metadata.xml @@ -215,6 +215,16 @@ 1 + + Region + + usfoo + + + CloudType + + Public + ErspanDestinationIpv4 @@ -243,6 +253,11 @@ 10.0.10.7;10.0.10.8 + + ResourceType + + resource_type_x + diff --git a/src/sonic-config-engine/tests/simple-sample-graph.xml b/src/sonic-config-engine/tests/simple-sample-graph.xml index 5ebbaafd9671..7215209da545 100644 --- a/src/sonic-config-engine/tests/simple-sample-graph.xml +++ b/src/sonic-config-engine/tests/simple-sample-graph.xml @@ -164,6 +164,15 @@ 1000 192.168.0.0/27 + + kk1 + fortyGigE0/12 + 192.0.0.1;192.0.0.2 + 2020 + 2020 + Tagged + 192.168.0.0/28 + @@ -259,6 +268,7 @@ switch-t0 Force10-S6000 + AAA00PrdStr00 ARISTA01T1 diff --git a/src/sonic-config-engine/tests/t0-sample-graph-mvrf.xml b/src/sonic-config-engine/tests/t0-sample-graph-mvrf.xml index 5162086d9316..ee633c18bd1e 100644 --- a/src/sonic-config-engine/tests/t0-sample-graph-mvrf.xml +++ b/src/sonic-config-engine/tests/t0-sample-graph-mvrf.xml @@ -393,6 +393,11 @@ switch-t0 + + ForcedMgmtRoutes + + 11.11.11.11;22.22.22.0/23 + ErspanDestinationIpv4 diff --git a/src/sonic-config-engine/tests/t0-sample-graph.xml b/src/sonic-config-engine/tests/t0-sample-graph.xml index 0c641107da06..63f892fe6d04 100644 --- a/src/sonic-config-engine/tests/t0-sample-graph.xml +++ b/src/sonic-config-engine/tests/t0-sample-graph.xml @@ -237,11 +237,28 @@ fortyGigE0/4;fortyGigE0/8;fortyGigE0/12;fortyGigE0/16;fortyGigE0/20;fortyGigE0/24;fortyGigE0/28;fortyGigE0/32;fortyGigE0/36;fortyGigE0/40;fortyGigE0/44;fortyGigE0/48;fortyGigE0/52;fortyGigE0/56;fortyGigE0/60;fortyGigE0/64;fortyGigE0/68;fortyGigE0/72;fortyGigE0/76;fortyGigE0/80;fortyGigE0/84;fortyGigE0/88;fortyGigE0/92;fortyGigE0/96 False 0.0.0.0/0 + 192.0.0.1;192.0.0.2 1000 1000 192.168.0.0/27 + + + + + Vlan99 + fortyGigE0/100 + False + 0.0.0.0/0 + + UserDefinedL2Vlan + 192.0.0.1;192.0.0.2 + 99 + 99 + + + @@ -303,9 +320,19 @@ everflowV6 Everflow + + EGRESS_ERSPAN + everflow_egress + Everflow + PortChannel01;PortChannel02;PortChannel03;PortChannel04 - DataAcl + DataAclIngress + DataPlane + + + PortChannel01;PortChannel02 + DataAclEgress DataPlane @@ -371,13 +398,14 @@ Ethernet1/1 switch-t0 fortyGigE0/124 + 100000 DeviceInterfaceLink true - 10000 + 100000 switch-t0 - fortyGigE0/2 + fortyGigE0/4 true ARISTA05T1 Ethernet1/33 @@ -390,6 +418,13 @@ switch-t0 fortyGigE0/4 + + DeviceInterfaceLink + Servers100 + eth0 + switch-t0 + fortyGigE0/100 + @@ -429,6 +464,32 @@ + + + + + + + FECDisabled + + True + + + ARISTA05T1:Ethernet1/33;switch-t0:fortyGigE0/4 + + + + + + FECDisabled + + True + + + ARISTA06T1:Ethernet1/34;switch-t0:fortyGigE0/8 + + + switch-t0 Force10-S6000 diff --git a/src/sonic-config-engine/tests/test2.j2 b/src/sonic-config-engine/tests/test2.j2 new file mode 100644 index 000000000000..df36b83cf382 --- /dev/null +++ b/src/sonic-config-engine/tests/test2.j2 @@ -0,0 +1 @@ +{{ key1 }} diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index 8288b729584c..3a85346de2fd 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -1,7 +1,11 @@ -from unittest import TestCase +import json import subprocess import os +import tests.common_utils as utils + +from unittest import TestCase + TOR_ROUTER = 'ToRRouter' BACKEND_TOR_ROUTER = 'BackEndToRRouter' @@ -9,28 +13,43 @@ class TestCfgGen(TestCase): def setUp(self): self.test_dir = os.path.dirname(os.path.realpath(__file__)) - self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen') + self.script_file = utils.PYTHON_INTERPRETTER + ' ' + os.path.join(self.test_dir, '..', 'sonic-cfggen') self.sample_graph = os.path.join(self.test_dir, 'sample_graph.xml') self.sample_graph_t0 = os.path.join(self.test_dir, 't0-sample-graph.xml') self.sample_graph_simple = os.path.join(self.test_dir, 'simple-sample-graph.xml') + self.sample_graph_simple_case = os.path.join(self.test_dir, 'simple-sample-graph-case.xml') self.sample_graph_metadata = os.path.join(self.test_dir, 'simple-sample-graph-metadata.xml') self.sample_graph_pc_test = os.path.join(self.test_dir, 'pc-test-graph.xml') self.sample_graph_bgp_speaker = os.path.join(self.test_dir, 't0-sample-bgp-speaker.xml') self.sample_device_desc = os.path.join(self.test_dir, 'device.xml') self.port_config = os.path.join(self.test_dir, 't0-sample-port-config.ini') + self.mlnx_port_config = os.path.join(self.test_dir, 'mellanox-sample-port-config.ini') + self.output_file = os.path.join(self.test_dir, 'output') + self.output2_file = os.path.join(self.test_dir, 'output2') + self.ecmp_graph = os.path.join(self.test_dir, 'fg-ecmp-sample-minigraph.xml') + + def tearDown(self): + try: + os.remove(self.output_file) + os.remove(self.output2_file) + except OSError: + pass def run_script(self, argument, check_stderr=False): - print '\n Running sonic-cfggen ' + argument + print('\n Running sonic-cfggen ' + argument) if check_stderr: output = subprocess.check_output(self.script_file + ' ' + argument, stderr=subprocess.STDOUT, shell=True) else: output = subprocess.check_output(self.script_file + ' ' + argument, shell=True) + if utils.PY3x: + output = output.decode() + linecount = output.strip().count('\n') if linecount <= 0: - print ' Output: ' + output.strip() + print(' Output: ' + output.strip()) else: - print ' Output: ({0} lines, {1} bytes)'.format(linecount + 1, len(output)) + print(' Output: ({0} lines, {1} bytes)'.format(linecount + 1, len(output))) return output def test_dummy_run(self): @@ -44,7 +63,7 @@ def test_device_desc(self): self.assertEqual(output.strip(), 'ACS-MSN2700') def test_device_desc_mgmt_ip(self): - argument = '-v "MGMT_INTERFACE.keys()[0]" -M "' + self.sample_device_desc + '"' + argument = '-v "(MGMT_INTERFACE.keys()|list)[0]" -M "' + self.sample_device_desc + '"' output = self.run_script(argument) self.assertEqual(output.strip(), "('eth0', '10.0.1.5/28')") @@ -53,6 +72,21 @@ def test_minigraph_sku(self): output = self.run_script(argument) self.assertEqual(output.strip(), 'Force10-Z9100') + def test_minigraph_region(self): + argument = '-v "DEVICE_METADATA[\'localhost\'][\'region\']" -m "' + self.sample_graph_metadata + '"' + output = self.run_script(argument) + self.assertEqual(output.strip(), 'usfoo') + + def test_minigraph_cloudtype(self): + argument = '-v "DEVICE_METADATA[\'localhost\'][\'cloudtype\']" -m "' + self.sample_graph_metadata + '"' + output = self.run_script(argument) + self.assertEqual(output.strip(), 'Public') + + def test_minigraph_resourcetype(self): + argument = '-v "DEVICE_METADATA[\'localhost\'][\'resource_type\']" -m "' + self.sample_graph_metadata + '"' + output = self.run_script(argument) + self.assertEqual(output.strip(), 'resource_type_x') + def test_print_data(self): argument = '-m "' + self.sample_graph + '" --print-data' output = self.run_script(argument) @@ -73,17 +107,23 @@ def test_additional_json_data(self): def test_additional_json_data_level1_key(self): argument = '-a \'{"k1":{"k11":"v11","k12":"v12"}, "k2":{"k22":"v22"}}\' --var-json k1' output = self.run_script(argument) - self.assertEqual(output.strip(), '{\n "k11": "v11", \n "k12": "v12"\n}') + self.assertEqual(utils.to_dict(output.strip()), utils.to_dict('{\n "k11": "v11", \n "k12": "v12"\n}')) def test_additional_json_data_level2_key(self): argument = '-a \'{"k1":{"k11":"v11","k12":"v12"},"k2":{"k22":"v22"}}\' --var-json k1 -K k11' output = self.run_script(argument) - self.assertEqual(output.strip(), '{\n "k11": "v11"\n}') + self.assertEqual(utils.to_dict(output.strip()), utils.to_dict('{\n "k11": "v11"\n}')) def test_var_json_data(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" --var-json VLAN_MEMBER' output = self.run_script(argument) - self.assertEqual(output.strip(), '{\n "Vlan1000|Ethernet8": {\n "tagging_mode": "untagged"\n }\n}') + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict( + '{\n "Vlan1000|Ethernet8": {\n "tagging_mode": "untagged"\n },' + ' \n "Vlan2020|Ethernet12": {\n "tagging_mode": "tagged"\n }\n}' + ) + ) def test_read_yaml(self): argument = '-v yml_item -y ' + os.path.join(self.test_dir, 'test.yml') @@ -95,22 +135,50 @@ def test_render_template(self): output = self.run_script(argument) self.assertEqual(output.strip(), 'value1\nvalue2') + def test_template_batch_mode(self): + argument = '-y ' + os.path.join(self.test_dir, 'test.yml') + argument += ' -a \'{"key1":"value"}\'' + argument += ' -t ' + os.path.join(self.test_dir, 'test.j2') + ',' + self.output_file + argument += ' -t ' + os.path.join(self.test_dir, 'test2.j2') + ',' + self.output2_file + output = self.run_script(argument) + assert(os.path.exists(self.output_file)) + assert(os.path.exists(self.output2_file)) + with open(self.output_file) as tf: + self.assertEqual(tf.read().strip(), 'value1\nvalue2') + with open(self.output2_file) as tf: + self.assertEqual(tf.read().strip(), 'value') + + def test_template_json_batch_mode(self): + data = {"key1_1":"value1_1", "key1_2":"value1_2", "key2_1":"value2_1", "key2_2":"value2_2"} + argument = " -a '{0}'".format(repr(data).replace('\'', '"')) + argument += ' -t ' + os.path.join(self.test_dir, 'sample-template-1.json.j2') + ",config-db" + argument += ' -t ' + os.path.join(self.test_dir, 'sample-template-2.json.j2') + ",config-db" + argument += ' --print-data' + output = self.run_script(argument) + output_data = json.loads(output) + for key, value in data.items(): + self.assertEqual(output_data[key.replace("key", "jk")], value) + # FIXME: This test depends heavily on the ordering of the interfaces and # it is not at all intuitive what that ordering should be. Could make it # more robust by adding better parsing logic. def test_minigraph_acl(self): argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v ACL_TABLE' output = self.run_script(argument, True) - self.assertEqual(output.strip(), "Warning: Ignoring Control Plane ACL NTP_ACL without type\n" - "Warning: ignore interface 'fortyGigE0/2' as it is not in the port_config.ini\n" - "Warning: ignore interface 'fortyGigE0/2' in DEVICE_NEIGHBOR as it is not in the port_config.ini\n" - "{'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']}}") + self.assertEqual( + utils.to_dict(output.strip().replace("Warning: Ignoring Control Plane ACL NTP_ACL without type\n", '')), + utils.to_dict( + "{'NTP_ACL': {'services': ['NTP'], 'type': 'CTRLPLANE', 'policy_desc': 'NTP_ACL', 'stage': 'ingress'}, " + "'EVERFLOW': {'stage': 'ingress', 'type': 'MIRROR', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4', 'Ethernet100'], 'policy_desc': 'EVERFLOW'}, " + "'EVERFLOW_EGRESS': {'stage': 'egress', 'type': 'MIRROR', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4', 'Ethernet100'], 'policy_desc': 'EVERFLOW_EGRESS'}, " + "'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', 'Ethernet100'], 'policy_desc': 'EVERFLOWV6'}}" + ) + ) # everflow portion is not used # def test_minigraph_everflow(self): @@ -121,52 +189,108 @@ def test_minigraph_acl(self): def test_minigraph_mgmt_ports(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v MGMT_PORT' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'eth0': {'alias': 'Management0', 'admin_status': 'up'}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'eth0': {'alias': 'Management0', 'admin_status': 'up'}}") + ) def test_minigraph_interfaces(self): - argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "INTERFACE.keys()"' + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "INTERFACE.keys()|list"' output = self.run_script(argument) self.assertEqual(output.strip(), "[('Ethernet0', '10.0.0.58/31'), 'Ethernet0', ('Ethernet0', 'FC00::75/126')]") def test_minigraph_vlans(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v VLAN' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'Vlan1000': {'alias': 'ab1', 'dhcp_servers': ['192.0.0.1', '192.0.0.2'], 'vlanid': '1000'}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict( + "{'Vlan1000': {'alias': 'ab1', 'dhcp_servers': ['192.0.0.1', '192.0.0.2'], 'vlanid': '1000'}, " + "'Vlan2020': {'alias': 'kk1', 'dhcp_servers': ['192.0.0.1', '192.0.0.2'], 'vlanid': '2020'}}" + ) + ) def test_minigraph_vlan_members(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v VLAN_MEMBER' output = self.run_script(argument) - self.assertEqual(output.strip(), "{('Vlan1000', 'Ethernet8'): {'tagging_mode': 'untagged'}}") + self.assertEqual( + output.strip(), + "{('Vlan1000', 'Ethernet8'): {'tagging_mode': 'untagged'}, " + "('Vlan2020', 'Ethernet12'): {'tagging_mode': 'tagged'}}" + ) def test_minigraph_vlan_interfaces(self): - argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "VLAN_INTERFACE.keys()"' + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "VLAN_INTERFACE.keys()|list"' output = self.run_script(argument) self.assertEqual(output.strip(), "[('Vlan1000', '192.168.0.1/27'), 'Vlan1000']") + def test_minigraph_ecmp_fg_nhg(self): + argument = '-m "' + self.ecmp_graph + '" -p "' + self.mlnx_port_config + '" -v \"FG_NHG.values()|list\"' + output = self.run_script(argument) + self.assertEqual(output.strip(), "[{'bucket_size': 120}, {'bucket_size': 120}]") + + def test_minigraph_ecmp_members(self): + argument = '-m "' + self.ecmp_graph + '" -p "' + self.mlnx_port_config + '" -v "FG_NHG_MEMBER.keys()|list|sort"' + output = self.run_script(argument) + self.assertEqual(output.strip(), "['200.200.200.1', '200.200.200.10', '200.200.200.2', '200.200.200.3', '200.200.200.4', '200.200.200.5'," + " '200.200.200.6', '200.200.200.7', '200.200.200.8', '200.200.200.9', '200:200:200:200::1', '200:200:200:200::10'," + " '200:200:200:200::2', '200:200:200:200::3', '200:200:200:200::4', '200:200:200:200::5', '200:200:200:200::6'," + " '200:200:200:200::7', '200:200:200:200::8', '200:200:200:200::9']") + + def test_minigraph_ecmp_neighbors(self): + argument = '-m "' + self.ecmp_graph + '" -p "' + self.mlnx_port_config + '" -v "NEIGH.keys()|list|sort"' + output = self.run_script(argument) + self.assertEqual(output.strip(), "['Vlan31|200.200.200.1', 'Vlan31|200.200.200.10', 'Vlan31|200.200.200.2', 'Vlan31|200.200.200.3'," + " 'Vlan31|200.200.200.4', 'Vlan31|200.200.200.5', 'Vlan31|200.200.200.6', 'Vlan31|200.200.200.7'," + " 'Vlan31|200.200.200.8', 'Vlan31|200.200.200.9', 'Vlan31|200:200:200:200::1', 'Vlan31|200:200:200:200::10'," + " 'Vlan31|200:200:200:200::2', 'Vlan31|200:200:200:200::3', 'Vlan31|200:200:200:200::4', 'Vlan31|200:200:200:200::5', " + "'Vlan31|200:200:200:200::6', 'Vlan31|200:200:200:200::7', 'Vlan31|200:200:200:200::8', 'Vlan31|200:200:200:200::9']") + + def test_minigraph_ecmp_prefixes(self): + argument = '-m "' + self.ecmp_graph + '" -p "' + self.mlnx_port_config + '" -v "FG_NHG_PREFIX.keys()|list|sort"' + output = self.run_script(argument) + self.assertEqual(output.strip(), "['100.50.25.12/32', 'fc:5::/128']") + + def test_minigraph_portchannels(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v PORTCHANNEL' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'PortChannel01': {'admin_status': 'up', 'min_links': '1', 'members': ['Ethernet4'], 'mtu': '9100'}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'PortChannel01': {'admin_status': 'up', 'min_links': '1', 'members': ['Ethernet4'], 'mtu': '9100'}}") + ) def test_minigraph_portchannel_with_more_member(self): argument = '-m "' + self.sample_graph_pc_test + '" -p "' + self.port_config + '" -v PORTCHANNEL' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'PortChannel01': {'admin_status': 'up', 'min_links': '3', 'members': ['Ethernet112', 'Ethernet116', 'Ethernet120', 'Ethernet124'], 'mtu': '9100'}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'PortChannel01': {'admin_status': 'up', 'min_links': '3', 'members': ['Ethernet112', 'Ethernet116', 'Ethernet120', 'Ethernet124'], 'mtu': '9100'}}") + ) def test_minigraph_portchannel_members(self): - argument = '-m "' + self.sample_graph_pc_test + '" -p "' + self.port_config + '" -v "PORTCHANNEL_MEMBER.keys()"' + argument = '-m "' + self.sample_graph_pc_test + '" -p "' + self.port_config + '" -v "PORTCHANNEL_MEMBER.keys()|list"' output = self.run_script(argument) - self.assertEqual(output.strip(), "[('PortChannel01', 'Ethernet120'), ('PortChannel01', 'Ethernet116'), ('PortChannel01', 'Ethernet124'), ('PortChannel01', 'Ethernet112')]") + self.assertEqual( + utils.liststr_to_dict(output.strip()), + utils.liststr_to_dict("[('PortChannel01', 'Ethernet120'), ('PortChannel01', 'Ethernet116'), ('PortChannel01', 'Ethernet124'), ('PortChannel01', 'Ethernet112')]") + ) def test_minigraph_portchannel_interfaces(self): - argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "PORTCHANNEL_INTERFACE.keys()"' + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "PORTCHANNEL_INTERFACE.keys()|list"' output = self.run_script(argument) - self.assertEqual(output.strip(), "['PortChannel01', ('PortChannel01', '10.0.0.56/31'), ('PortChannel01', 'FC00::71/126')]") + self.assertEqual( + utils.liststr_to_dict(output.strip()), + utils.liststr_to_dict("['PortChannel01', ('PortChannel01', '10.0.0.56/31'), ('PortChannel01', 'FC00::71/126')]") + ) def test_minigraph_neighbors(self): argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v "DEVICE_NEIGHBOR[\'Ethernet124\']"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'name': 'ARISTA04T1', 'port': 'Ethernet1/1'}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'name': 'ARISTA04T1', 'port': 'Ethernet1/1'}") + ) # FIXME: This test depends heavily on the ordering of the interfaces and # it is not at all intuitive what that ordering should be. Could make it @@ -174,27 +298,57 @@ def test_minigraph_neighbors(self): def test_minigraph_extra_neighbors(self): argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v DEVICE_NEIGHBOR' output = self.run_script(argument) - self.assertEqual(output.strip(), \ - "{'Ethernet116': {'name': 'ARISTA02T1', 'port': 'Ethernet1/1'}, " - "'Ethernet124': {'name': 'ARISTA04T1', 'port': 'Ethernet1/1'}, " - "'Ethernet112': {'name': 'ARISTA01T1', 'port': 'Ethernet1/1'}, " - "'Ethernet4': {'name': 'Servers0', 'port': 'eth0'}, " - "'Ethernet120': {'name': 'ARISTA03T1', 'port': 'Ethernet1/1'}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict( + "{'Ethernet124': {'name': 'ARISTA04T1', 'port': 'Ethernet1/1'}, " + "'Ethernet120': {'name': 'ARISTA03T1', 'port': 'Ethernet1/1'}, " + "'Ethernet4': {'name': 'Servers0', 'port': 'eth0'}, " + "'Ethernet116': {'name': 'ARISTA02T1', 'port': 'Ethernet1/1'}, " + "'Ethernet100': {'name': 'Servers100', 'port': 'eth0'}, " + "'Ethernet112': {'name': 'ARISTA01T1', 'port': 'Ethernet1/1'}}") + ) def test_minigraph_port_description(self): argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v "PORT[\'Ethernet124\']"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'lanes': '101,102,103,104', 'description': 'ARISTA04T1:Ethernet1/1', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/124', 'admin_status': 'up'}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'lanes': '101,102,103,104', 'fec': 'rs', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/124', 'admin_status': 'up', 'speed': '100000', 'description': 'ARISTA04T1:Ethernet1/1'}") + ) + + def test_minigraph_port_fec_disabled(self): + # Test for FECDisabled + argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v "PORT[\'Ethernet4\']"' + output = self.run_script(argument) + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'lanes': '25,26,27,28', 'description': 'Servers0:eth0', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/4', 'admin_status': 'up', 'speed': '100000'}") + ) + + def test_minigraph_port_rs(self): + argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v "PORT[\'Ethernet124\']"' + output = self.run_script(argument) + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'lanes': '101,102,103,104', 'fec': 'rs', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/124', 'admin_status': 'up', 'speed': '100000', 'description': 'ARISTA04T1:Ethernet1/1'}") + ) def test_minigraph_bgp(self): argument = '-m "' + self.sample_graph_bgp_speaker + '" -p "' + self.port_config + '" -v "BGP_NEIGHBOR[\'10.0.0.59\']"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'rrclient': 0, 'name': 'ARISTA02T1', 'local_addr': '10.0.0.58', 'nhopself': 0, 'holdtime': '180', 'asn': '64600', 'keepalive': '60'}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'rrclient': 0, 'name': 'ARISTA02T1', 'local_addr': '10.0.0.58', 'nhopself': 0, 'holdtime': '180', 'asn': '64600', 'keepalive': '60'}") + ) def test_minigraph_peers_with_range(self): - argument = '-m "' + self.sample_graph_bgp_speaker + '" -p "' + self.port_config + '" -v BGP_PEER_RANGE.values\(\)' + argument = "-m " + self.sample_graph_bgp_speaker + " -p " + self.port_config + " -v \"BGP_PEER_RANGE.values()|list\"" output = self.run_script(argument) - self.assertEqual(output.strip(), "[{'src_address': '10.1.0.32', 'name': 'BGPSLBPassive', 'ip_range': ['10.10.10.10/26', '100.100.100.100/26']}]") + self.assertEqual( + utils.liststr_to_dict(output.strip()), + utils.liststr_to_dict("[{'src_address': '10.1.0.32', 'name': 'BGPSLBPassive', 'ip_range': ['10.10.10.10/26', '100.100.100.100/26']}]") + ) def test_minigraph_deployment_id(self): argument = '-m "' + self.sample_graph_bgp_speaker + '" -p "' + self.port_config + '" -v "DEVICE_METADATA[\'localhost\'][\'deployment_id\']"' @@ -204,48 +358,100 @@ def test_minigraph_deployment_id(self): def test_minigraph_ethernet_interfaces(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "PORT[\'Ethernet8\']"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'lanes': '37,38,39,40', 'description': 'Interface description', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/8', 'admin_status': 'up', 'speed': '1000'}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'lanes': '37,38,39,40', 'description': 'Interface description', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/8', 'admin_status': 'up', 'speed': '1000'}") + ) argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "PORT[\'Ethernet12\']"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'lanes': '33,34,35,36', 'fec': 'rs', 'mtu': '9100', 'alias': 'fortyGigE0/12', 'pfc_asym': 'off', 'speed': '100000', 'description': 'Interface description'}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'lanes': '33,34,35,36', 'fec': 'rs', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/12', 'admin_status': 'up', 'speed': '100000', 'description': 'Interface description'}") + ) + + def test_minigraph_neighbor_interfaces(self): + argument = '-m "' + self.sample_graph_simple_case + '" -p "' + self.port_config + '" -v "PORT"' + output = self.run_script(argument) + + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict( + "{'Ethernet8': {'lanes': '37,38,39,40', 'description': 'Interface description', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/8', 'admin_status': 'up', 'speed': '40000', 'mux_cable': 'true'}, " + "'Ethernet0': {'lanes': '29,30,31,32', 'description': 'switch-01t1:port1', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/0', 'admin_status': 'up', 'speed': '10000'}, " + "'Ethernet4': {'lanes': '25,26,27,28', 'description': 'server1:port1', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/4', 'admin_status': 'up', 'speed': '25000', 'mux_cable': 'true'}, " + "'Ethernet108': {'alias': 'fortyGigE0/108', 'pfc_asym': 'off', 'lanes': '81,82,83,84', 'description': 'fortyGigE0/108', 'mtu': '9100'}, " + "'Ethernet100': {'alias': 'fortyGigE0/100', 'pfc_asym': 'off', 'lanes': '125,126,127,128', 'description': 'fortyGigE0/100', 'mtu': '9100'}, " + "'Ethernet104': {'alias': 'fortyGigE0/104', 'pfc_asym': 'off', 'lanes': '85,86,87,88', 'description': 'fortyGigE0/104', 'mtu': '9100'}, " + "'Ethernet68': {'alias': 'fortyGigE0/68', 'pfc_asym': 'off', 'lanes': '69,70,71,72', 'description': 'fortyGigE0/68', 'mtu': '9100'}, " + "'Ethernet96': {'alias': 'fortyGigE0/96', 'pfc_asym': 'off', 'lanes': '121,122,123,124', 'description': 'fortyGigE0/96', 'mtu': '9100'}, " + "'Ethernet124': {'alias': 'fortyGigE0/124', 'pfc_asym': 'off', 'lanes': '101,102,103,104', 'description': 'fortyGigE0/124', 'mtu': '9100'}, " + "'Ethernet92': {'alias': 'fortyGigE0/92', 'pfc_asym': 'off', 'lanes': '113,114,115,116', 'description': 'fortyGigE0/92', 'mtu': '9100'}, " + "'Ethernet120': {'alias': 'fortyGigE0/120', 'pfc_asym': 'off', 'lanes': '97,98,99,100', 'description': 'fortyGigE0/120', 'mtu': '9100'}, " + "'Ethernet52': {'alias': 'fortyGigE0/52', 'pfc_asym': 'off', 'lanes': '53,54,55,56', 'description': 'fortyGigE0/52', 'mtu': '9100'}, " + "'Ethernet56': {'alias': 'fortyGigE0/56', 'pfc_asym': 'off', 'lanes': '61,62,63,64', 'description': 'fortyGigE0/56', 'mtu': '9100'}, " + "'Ethernet76': {'alias': 'fortyGigE0/76', 'pfc_asym': 'off', 'lanes': '73,74,75,76', 'description': 'fortyGigE0/76', 'mtu': '9100'}, " + "'Ethernet72': {'alias': 'fortyGigE0/72', 'pfc_asym': 'off', 'lanes': '77,78,79,80', 'description': 'fortyGigE0/72', 'mtu': '9100'}, " + "'Ethernet64': {'alias': 'fortyGigE0/64', 'pfc_asym': 'off', 'lanes': '65,66,67,68', 'description': 'fortyGigE0/64', 'mtu': '9100'}, " + "'Ethernet32': {'alias': 'fortyGigE0/32', 'pfc_asym': 'off', 'lanes': '9,10,11,12', 'description': 'fortyGigE0/32', 'mtu': '9100'}, " + "'Ethernet16': {'alias': 'fortyGigE0/16', 'pfc_asym': 'off', 'lanes': '41,42,43,44', 'description': 'fortyGigE0/16', 'mtu': '9100'}, " + "'Ethernet36': {'alias': 'fortyGigE0/36', 'pfc_asym': 'off', 'lanes': '13,14,15,16', 'description': 'fortyGigE0/36', 'mtu': '9100'}, " + "'Ethernet12': {'lanes': '33,34,35,36', 'description': 'Interface description', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/12', 'admin_status': 'up', 'speed': '10000'}, " + "'Ethernet88': {'alias': 'fortyGigE0/88', 'pfc_asym': 'off', 'lanes': '117,118,119,120', 'description': 'fortyGigE0/88', 'mtu': '9100'}, " + "'Ethernet116': {'alias': 'fortyGigE0/116', 'pfc_asym': 'off', 'lanes': '93,94,95,96', 'description': 'fortyGigE0/116', 'mtu': '9100'}, " + "'Ethernet80': {'alias': 'fortyGigE0/80', 'pfc_asym': 'off', 'lanes': '105,106,107,108', 'description': 'fortyGigE0/80', 'mtu': '9100'}, " + "'Ethernet112': {'alias': 'fortyGigE0/112', 'pfc_asym': 'off', 'lanes': '89,90,91,92', 'description': 'fortyGigE0/112', 'mtu': '9100'}, " + "'Ethernet84': {'alias': 'fortyGigE0/84', 'pfc_asym': 'off', 'lanes': '109,110,111,112', 'description': 'fortyGigE0/84', 'mtu': '9100'}, " + "'Ethernet48': {'alias': 'fortyGigE0/48', 'pfc_asym': 'off', 'lanes': '49,50,51,52', 'description': 'fortyGigE0/48', 'mtu': '9100'}, " + "'Ethernet44': {'alias': 'fortyGigE0/44', 'pfc_asym': 'off', 'lanes': '17,18,19,20', 'description': 'fortyGigE0/44', 'mtu': '9100'}, " + "'Ethernet40': {'alias': 'fortyGigE0/40', 'pfc_asym': 'off', 'lanes': '21,22,23,24', 'description': 'fortyGigE0/40', 'mtu': '9100'}, " + "'Ethernet28': {'alias': 'fortyGigE0/28', 'pfc_asym': 'off', 'lanes': '1,2,3,4', 'description': 'fortyGigE0/28', 'mtu': '9100'}, " + "'Ethernet60': {'alias': 'fortyGigE0/60', 'pfc_asym': 'off', 'lanes': '57,58,59,60', 'description': 'fortyGigE0/60', 'mtu': '9100'}, " + "'Ethernet20': {'alias': 'fortyGigE0/20', 'pfc_asym': 'off', 'lanes': '45,46,47,48', 'description': 'fortyGigE0/20', 'mtu': '9100'}, " + "'Ethernet24': {'alias': 'fortyGigE0/24', 'pfc_asym': 'off', 'lanes': '5,6,7,8', 'description': 'fortyGigE0/24', 'mtu': '9100'}}" + ) + ) def test_minigraph_extra_ethernet_interfaces(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "PORT"' output = self.run_script(argument) - self.assertEqual(output.strip(), \ - "{'Ethernet8': {'lanes': '37,38,39,40', 'description': 'Interface description', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/8', 'admin_status': 'up', 'speed': '1000'}, " - "'Ethernet0': {'lanes': '29,30,31,32', 'description': 'fortyGigE0/0', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/0', 'admin_status': 'up', 'speed': '10000'}, " - "'Ethernet4': {'lanes': '25,26,27,28', 'description': 'fortyGigE0/4', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/4', 'admin_status': 'up', 'speed': '25000'}, " - "'Ethernet108': {'alias': 'fortyGigE0/108', 'pfc_asym': 'off', 'lanes': '81,82,83,84', 'description': 'fortyGigE0/108', 'mtu': '9100'}, " - "'Ethernet100': {'alias': 'fortyGigE0/100', 'pfc_asym': 'off', 'lanes': '125,126,127,128', 'description': 'fortyGigE0/100', 'mtu': '9100'}, " - "'Ethernet104': {'alias': 'fortyGigE0/104', 'pfc_asym': 'off', 'lanes': '85,86,87,88', 'description': 'fortyGigE0/104', 'mtu': '9100'}, " - "'Ethernet68': {'alias': 'fortyGigE0/68', 'pfc_asym': 'off', 'lanes': '69,70,71,72', 'description': 'fortyGigE0/68', 'mtu': '9100'}, " - "'Ethernet96': {'alias': 'fortyGigE0/96', 'pfc_asym': 'off', 'lanes': '121,122,123,124', 'description': 'fortyGigE0/96', 'mtu': '9100'}, " - "'Ethernet124': {'alias': 'fortyGigE0/124', 'pfc_asym': 'off', 'lanes': '101,102,103,104', 'description': 'fortyGigE0/124', 'mtu': '9100'}, " - "'Ethernet92': {'alias': 'fortyGigE0/92', 'pfc_asym': 'off', 'lanes': '113,114,115,116', 'description': 'fortyGigE0/92', 'mtu': '9100'}, " - "'Ethernet120': {'alias': 'fortyGigE0/120', 'pfc_asym': 'off', 'lanes': '97,98,99,100', 'description': 'fortyGigE0/120', 'mtu': '9100'}, " - "'Ethernet52': {'alias': 'fortyGigE0/52', 'pfc_asym': 'off', 'lanes': '53,54,55,56', 'description': 'fortyGigE0/52', 'mtu': '9100'}, " - "'Ethernet56': {'alias': 'fortyGigE0/56', 'pfc_asym': 'off', 'lanes': '61,62,63,64', 'description': 'fortyGigE0/56', 'mtu': '9100'}, " - "'Ethernet76': {'alias': 'fortyGigE0/76', 'pfc_asym': 'off', 'lanes': '73,74,75,76', 'description': 'fortyGigE0/76', 'mtu': '9100'}, " - "'Ethernet72': {'alias': 'fortyGigE0/72', 'pfc_asym': 'off', 'lanes': '77,78,79,80', 'description': 'fortyGigE0/72', 'mtu': '9100'}, " - "'Ethernet64': {'alias': 'fortyGigE0/64', 'pfc_asym': 'off', 'lanes': '65,66,67,68', 'description': 'fortyGigE0/64', 'mtu': '9100'}, " - "'Ethernet32': {'alias': 'fortyGigE0/32', 'pfc_asym': 'off', 'lanes': '9,10,11,12', 'description': 'fortyGigE0/32', 'mtu': '9100'}, " - "'Ethernet16': {'alias': 'fortyGigE0/16', 'pfc_asym': 'off', 'lanes': '41,42,43,44', 'description': 'fortyGigE0/16', 'mtu': '9100'}, " - "'Ethernet36': {'alias': 'fortyGigE0/36', 'pfc_asym': 'off', 'lanes': '13,14,15,16', 'description': 'fortyGigE0/36', 'mtu': '9100'}, " - "'Ethernet12': {'lanes': '33,34,35,36', 'fec': 'rs', 'mtu': '9100', 'alias': 'fortyGigE0/12', 'pfc_asym': 'off', 'speed': '100000', 'description': 'Interface description'}, " - "'Ethernet88': {'alias': 'fortyGigE0/88', 'pfc_asym': 'off', 'lanes': '117,118,119,120', 'description': 'fortyGigE0/88', 'mtu': '9100'}, " - "'Ethernet116': {'alias': 'fortyGigE0/116', 'pfc_asym': 'off', 'lanes': '93,94,95,96', 'description': 'fortyGigE0/116', 'mtu': '9100'}, " - "'Ethernet80': {'alias': 'fortyGigE0/80', 'pfc_asym': 'off', 'lanes': '105,106,107,108', 'description': 'fortyGigE0/80', 'mtu': '9100'}, " - "'Ethernet112': {'alias': 'fortyGigE0/112', 'pfc_asym': 'off', 'lanes': '89,90,91,92', 'description': 'fortyGigE0/112', 'mtu': '9100'}, " - "'Ethernet84': {'alias': 'fortyGigE0/84', 'pfc_asym': 'off', 'lanes': '109,110,111,112', 'description': 'fortyGigE0/84', 'mtu': '9100'}, " - "'Ethernet48': {'alias': 'fortyGigE0/48', 'pfc_asym': 'off', 'lanes': '49,50,51,52', 'description': 'fortyGigE0/48', 'mtu': '9100'}, " - "'Ethernet44': {'alias': 'fortyGigE0/44', 'pfc_asym': 'off', 'lanes': '17,18,19,20', 'description': 'fortyGigE0/44', 'mtu': '9100'}, " - "'Ethernet40': {'alias': 'fortyGigE0/40', 'pfc_asym': 'off', 'lanes': '21,22,23,24', 'description': 'fortyGigE0/40', 'mtu': '9100'}, " - "'Ethernet28': {'alias': 'fortyGigE0/28', 'pfc_asym': 'off', 'lanes': '1,2,3,4', 'description': 'fortyGigE0/28', 'mtu': '9100'}, " - "'Ethernet60': {'alias': 'fortyGigE0/60', 'pfc_asym': 'off', 'lanes': '57,58,59,60', 'description': 'fortyGigE0/60', 'mtu': '9100'}, " - "'Ethernet20': {'alias': 'fortyGigE0/20', 'pfc_asym': 'off', 'lanes': '45,46,47,48', 'description': 'fortyGigE0/20', 'mtu': '9100'}, " - "'Ethernet24': {'alias': 'fortyGigE0/24', 'pfc_asym': 'off', 'lanes': '5,6,7,8', 'description': 'fortyGigE0/24', 'mtu': '9100'}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict( + "{'Ethernet8': {'lanes': '37,38,39,40', 'description': 'Interface description', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/8', 'admin_status': 'up', 'speed': '1000'}, " + "'Ethernet0': {'lanes': '29,30,31,32', 'description': 'fortyGigE0/0', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/0', 'admin_status': 'up', 'speed': '10000'}, " + "'Ethernet4': {'lanes': '25,26,27,28', 'description': 'fortyGigE0/4', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/4', 'admin_status': 'up', 'speed': '25000'}, " + "'Ethernet108': {'alias': 'fortyGigE0/108', 'pfc_asym': 'off', 'lanes': '81,82,83,84', 'description': 'fortyGigE0/108', 'mtu': '9100'}, " + "'Ethernet100': {'alias': 'fortyGigE0/100', 'pfc_asym': 'off', 'lanes': '125,126,127,128', 'description': 'fortyGigE0/100', 'mtu': '9100'}, " + "'Ethernet104': {'alias': 'fortyGigE0/104', 'pfc_asym': 'off', 'lanes': '85,86,87,88', 'description': 'fortyGigE0/104', 'mtu': '9100'}, " + "'Ethernet68': {'alias': 'fortyGigE0/68', 'pfc_asym': 'off', 'lanes': '69,70,71,72', 'description': 'fortyGigE0/68', 'mtu': '9100'}, " + "'Ethernet96': {'alias': 'fortyGigE0/96', 'pfc_asym': 'off', 'lanes': '121,122,123,124', 'description': 'fortyGigE0/96', 'mtu': '9100'}, " + "'Ethernet124': {'alias': 'fortyGigE0/124', 'pfc_asym': 'off', 'lanes': '101,102,103,104', 'description': 'fortyGigE0/124', 'mtu': '9100'}, " + "'Ethernet92': {'alias': 'fortyGigE0/92', 'pfc_asym': 'off', 'lanes': '113,114,115,116', 'description': 'fortyGigE0/92', 'mtu': '9100'}, " + "'Ethernet120': {'alias': 'fortyGigE0/120', 'pfc_asym': 'off', 'lanes': '97,98,99,100', 'description': 'fortyGigE0/120', 'mtu': '9100'}, " + "'Ethernet52': {'alias': 'fortyGigE0/52', 'pfc_asym': 'off', 'lanes': '53,54,55,56', 'description': 'fortyGigE0/52', 'mtu': '9100'}, " + "'Ethernet56': {'alias': 'fortyGigE0/56', 'pfc_asym': 'off', 'lanes': '61,62,63,64', 'description': 'fortyGigE0/56', 'mtu': '9100'}, " + "'Ethernet76': {'alias': 'fortyGigE0/76', 'pfc_asym': 'off', 'lanes': '73,74,75,76', 'description': 'fortyGigE0/76', 'mtu': '9100'}, " + "'Ethernet72': {'alias': 'fortyGigE0/72', 'pfc_asym': 'off', 'lanes': '77,78,79,80', 'description': 'fortyGigE0/72', 'mtu': '9100'}, " + "'Ethernet64': {'alias': 'fortyGigE0/64', 'pfc_asym': 'off', 'lanes': '65,66,67,68', 'description': 'fortyGigE0/64', 'mtu': '9100'}, " + "'Ethernet32': {'alias': 'fortyGigE0/32', 'pfc_asym': 'off', 'lanes': '9,10,11,12', 'description': 'fortyGigE0/32', 'mtu': '9100'}, " + "'Ethernet16': {'alias': 'fortyGigE0/16', 'pfc_asym': 'off', 'lanes': '41,42,43,44', 'description': 'fortyGigE0/16', 'mtu': '9100'}, " + "'Ethernet36': {'alias': 'fortyGigE0/36', 'pfc_asym': 'off', 'lanes': '13,14,15,16', 'description': 'fortyGigE0/36', 'mtu': '9100'}, " + "'Ethernet12': {'lanes': '33,34,35,36', 'fec': 'rs', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/12', 'admin_status': 'up', 'speed': '100000', 'description': 'Interface description'}, " + "'Ethernet88': {'alias': 'fortyGigE0/88', 'pfc_asym': 'off', 'lanes': '117,118,119,120', 'description': 'fortyGigE0/88', 'mtu': '9100'}, " + "'Ethernet116': {'alias': 'fortyGigE0/116', 'pfc_asym': 'off', 'lanes': '93,94,95,96', 'description': 'fortyGigE0/116', 'mtu': '9100'}, " + "'Ethernet80': {'alias': 'fortyGigE0/80', 'pfc_asym': 'off', 'lanes': '105,106,107,108', 'description': 'fortyGigE0/80', 'mtu': '9100'}, " + "'Ethernet112': {'alias': 'fortyGigE0/112', 'pfc_asym': 'off', 'lanes': '89,90,91,92', 'description': 'fortyGigE0/112', 'mtu': '9100'}, " + "'Ethernet84': {'alias': 'fortyGigE0/84', 'pfc_asym': 'off', 'lanes': '109,110,111,112', 'description': 'fortyGigE0/84', 'mtu': '9100'}, " + "'Ethernet48': {'alias': 'fortyGigE0/48', 'pfc_asym': 'off', 'lanes': '49,50,51,52', 'description': 'fortyGigE0/48', 'mtu': '9100'}, " + "'Ethernet44': {'alias': 'fortyGigE0/44', 'pfc_asym': 'off', 'lanes': '17,18,19,20', 'description': 'fortyGigE0/44', 'mtu': '9100'}, " + "'Ethernet40': {'alias': 'fortyGigE0/40', 'pfc_asym': 'off', 'lanes': '21,22,23,24', 'description': 'fortyGigE0/40', 'mtu': '9100'}, " + "'Ethernet28': {'alias': 'fortyGigE0/28', 'pfc_asym': 'off', 'lanes': '1,2,3,4', 'description': 'fortyGigE0/28', 'mtu': '9100'}, " + "'Ethernet60': {'alias': 'fortyGigE0/60', 'pfc_asym': 'off', 'lanes': '57,58,59,60', 'description': 'fortyGigE0/60', 'mtu': '9100'}, " + "'Ethernet20': {'alias': 'fortyGigE0/20', 'pfc_asym': 'off', 'lanes': '45,46,47,48', 'description': 'fortyGigE0/20', 'mtu': '9100'}, " + "'Ethernet24': {'alias': 'fortyGigE0/24', 'pfc_asym': 'off', 'lanes': '5,6,7,8', 'description': 'fortyGigE0/24', 'mtu': '9100'}}" + ) + ) # everflow portion is not used # def test_metadata_everflow(self): @@ -256,12 +462,15 @@ def test_minigraph_extra_ethernet_interfaces(self): def test_metadata_tacacs(self): argument = '-m "' + self.sample_graph_metadata + '" -p "' + self.port_config + '" -v "TACPLUS_SERVER"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'10.0.10.7': {'priority': '1', 'tcp_port': '49'}, '10.0.10.8': {'priority': '1', 'tcp_port': '49'}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'10.0.10.7': {'priority': '1', 'tcp_port': '49'}, '10.0.10.8': {'priority': '1', 'tcp_port': '49'}}") + ) def test_metadata_ntp(self): argument = '-m "' + self.sample_graph_metadata + '" -p "' + self.port_config + '" -v "NTP_SERVER"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'10.0.10.1': {}, '10.0.10.2': {}}") + self.assertEqual(utils.to_dict(output.strip()), utils.to_dict("{'10.0.10.1': {}, '10.0.10.2': {}}")) def test_minigraph_vnet(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "VNET"' @@ -276,11 +485,14 @@ def test_minigraph_vxlan(self): def test_minigraph_bgp_mon(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "BGP_MONITORS"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'10.20.30.40': {'rrclient': 0, 'name': 'BGPMonitor', 'local_addr': '10.1.0.32', 'nhopself': 0, 'holdtime': '10', 'asn': '0', 'keepalive': '3'}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'10.20.30.40': {'rrclient': 0, 'name': 'BGPMonitor', 'local_addr': '10.1.0.32', 'nhopself': 0, 'holdtime': '10', 'asn': '0', 'keepalive': '3'}}") + ) def test_minigraph_sub_port_interfaces(self, check_stderr=True): try: - print '\n Change device type to %s' % (BACKEND_TOR_ROUTER) + print('\n Change device type to %s' % (BACKEND_TOR_ROUTER)) if check_stderr: output = subprocess.check_output("sed -i \'s/%s/%s/g\' %s" % (TOR_ROUTER, BACKEND_TOR_ROUTER, self.sample_graph_simple), stderr=subprocess.STDOUT, shell=True) else: @@ -313,20 +525,34 @@ def test_minigraph_sub_port_interfaces(self, check_stderr=True): # VLAN_SUB_INTERFACE argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v VLAN_SUB_INTERFACE' output = self.run_script(argument) - print output.strip() - self.assertEqual(output.strip(), \ + print(output.strip()) + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict( "{('PortChannel01.10', '10.0.0.56/31'): {}, " "'Ethernet0.10': {'admin_status': 'up'}, " "('Ethernet0.10', '10.0.0.58/31'): {}, " "('PortChannel01.10', 'FC00::71/126'): {}, " "'PortChannel01.10': {'admin_status': 'up'}, " - "('Ethernet0.10', 'FC00::75/126'): {}}") + "('Ethernet0.10', 'FC00::75/126'): {}}" + ) + ) finally: - print '\n Change device type back to %s' % (TOR_ROUTER) + print('\n Change device type back to %s' % (TOR_ROUTER)) if check_stderr: output = subprocess.check_output("sed -i \'s/%s/%s/g\' %s" % (BACKEND_TOR_ROUTER, TOR_ROUTER, self.sample_graph_simple), stderr=subprocess.STDOUT, shell=True) else: 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, '') diff --git a/src/sonic-config-engine/tests/test_cfggen_pfx_filter.py b/src/sonic-config-engine/tests/test_cfggen_pfx_filter.py new file mode 100644 index 000000000000..1ac2b7f7f5f3 --- /dev/null +++ b/src/sonic-config-engine/tests/test_cfggen_pfx_filter.py @@ -0,0 +1,21 @@ +import subprocess + +import tests.common_utils as utils + +from unittest import TestCase + + +class TestPfxFilter(TestCase): + def test_comprehensive(self): + # Generate output + data_dir = "tests/data/pfx_filter" + cmd = "{} ./sonic-cfggen -j {}/param_1.json -t {}/tmpl_1.txt.j2 > /tmp/result_1.txt".format( + utils.PYTHON_INTERPRETTER, data_dir, data_dir + ) + subprocess.check_output(cmd, shell=True) + # Compare outputs + cmd = "diff -u tests/data/pfx_filter/result_1.txt /tmp/result_1.txt" + try: + res = subprocess.check_output(cmd, shell=True) + except subprocess.CalledProcessError as e: + assert False, "Wrong output. return code: %d, Diff: %s" % (e.returncode, e.output) diff --git a/src/sonic-config-engine/tests/test_cfggen_platformJson.py b/src/sonic-config-engine/tests/test_cfggen_platformJson.py new file mode 100644 index 000000000000..254ec77ae00d --- /dev/null +++ b/src/sonic-config-engine/tests/test_cfggen_platformJson.py @@ -0,0 +1,83 @@ +import ast +import json +import os +import subprocess + +import tests.common_utils as utils + +from unittest import TestCase + + +# Global Variable +PLATFORM_OUTPUT_FILE = "platform_output.json" + +class TestCfgGenPlatformJson(TestCase): + + def setUp(self): + self.test_dir = os.path.dirname(os.path.realpath(__file__)) + self.script_file = utils.PYTHON_INTERPRETTER + ' ' + os.path.join(self.test_dir, '..', 'sonic-cfggen') + self.sample_graph_simple = os.path.join(self.test_dir, 'simple-sample-graph.xml') + self.platform_json = os.path.join(self.test_dir, 'sample_platform.json') + self.hwsku_json = os.path.join(self.test_dir, 'sample_hwsku.json') + + def run_script(self, argument, check_stderr=False): + print('\n Running sonic-cfggen ' + argument) + if check_stderr: + output = subprocess.check_output(self.script_file + ' ' + argument, stderr=subprocess.STDOUT, shell=True) + else: + output = subprocess.check_output(self.script_file + ' ' + argument, shell=True) + + if utils.PY3x: + output = output.decode() + + linecount = output.strip().count('\n') + if linecount <= 0: + print(' Output: ' + output.strip()) + else: + print(' Output: ({0} lines, {1} bytes)'.format(linecount + 1, len(output))) + return output + + def test_dummy_run(self): + argument = '' + output = self.run_script(argument) + self.assertEqual(output, '') + + def test_print_data(self): + argument = '-m "' + self.sample_graph_simple + '" --print-data' + output = self.run_script(argument) + self.assertTrue(len(output.strip()) > 0) + + # Check whether all interfaces present or not as per platform.json + def test_platform_json_interfaces_keys(self): + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.platform_json + '" -S "' + self.hwsku_json + '" -v "PORT.keys()|list"' + output = self.run_script(argument) + expected = "['Ethernet8', 'Ethernet9', 'Ethernet36', 'Ethernet98', 'Ethernet0', 'Ethernet6', 'Ethernet4', 'Ethernet109', 'Ethernet108', 'Ethernet18', 'Ethernet100', 'Ethernet34', 'Ethernet104', 'Ethernet106', 'Ethernet94', 'Ethernet126', 'Ethernet96', 'Ethernet124', 'Ethernet90', 'Ethernet91', 'Ethernet92', 'Ethernet93', 'Ethernet50', 'Ethernet51', 'Ethernet52', 'Ethernet53', 'Ethernet54', 'Ethernet99', 'Ethernet56', 'Ethernet113', 'Ethernet76', 'Ethernet74', 'Ethernet39', 'Ethernet72', 'Ethernet73', 'Ethernet70', 'Ethernet71', 'Ethernet32', 'Ethernet33', 'Ethernet16', 'Ethernet111', 'Ethernet10', 'Ethernet11', 'Ethernet12', 'Ethernet13', 'Ethernet58', 'Ethernet19', 'Ethernet59', 'Ethernet38', 'Ethernet78', 'Ethernet68', 'Ethernet14', 'Ethernet89', 'Ethernet88', 'Ethernet118', 'Ethernet119', 'Ethernet116', 'Ethernet114', 'Ethernet80', 'Ethernet112', 'Ethernet86', 'Ethernet110', 'Ethernet84', 'Ethernet31', 'Ethernet49', 'Ethernet48', 'Ethernet46', 'Ethernet30', 'Ethernet29', 'Ethernet40', 'Ethernet120', 'Ethernet28', 'Ethernet66', 'Ethernet60', 'Ethernet64', 'Ethernet44', 'Ethernet20', 'Ethernet79', 'Ethernet69', 'Ethernet24', 'Ethernet26']" + + self.assertEqual(sorted(output.strip()), sorted(expected)) + + # Check specific Interface with it's proper configuration as per platform.json + def test_platform_json_specific_ethernet_interfaces(self): + + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.platform_json + '" -S "' + self.hwsku_json + '" -v "PORT[\'Ethernet8\']"' + output = self.run_script(argument) + expected = "{'index': '3', 'lanes': '8', 'description': 'Eth3/1', 'admin_status': 'up', 'mtu': '9100', 'alias': 'Eth3/1', 'pfc_asym': 'off', 'speed': '25000'}" + self.assertEqual(utils.to_dict(output.strip()), utils.to_dict(expected)) + + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.platform_json + '" -S "' + self.hwsku_json + '" -v "PORT[\'Ethernet112\']"' + output = self.run_script(argument) + expected = "{'index': '29', 'lanes': '112', 'description': 'Eth29/1', 'admin_status': 'up', 'mtu': '9100', 'alias': 'Eth29/1', 'pfc_asym': 'off', 'speed': '25000'}" + self.assertEqual(utils.to_dict(output.strip()), utils.to_dict(expected)) + + # Check all Interface with it's proper configuration as per platform.json + def test_platform_json_all_ethernet_interfaces(self): + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.platform_json + '" -S "' + self.hwsku_json + '" -v "PORT"' + output = self.run_script(argument) + + sample_file = os.path.join(self.test_dir, 'sample_output', PLATFORM_OUTPUT_FILE) + fh = open(sample_file, 'rb') + fh_data = json.load(fh) + fh.close() + + output_dict = ast.literal_eval(output.strip()) + expected = ast.literal_eval(json.dumps(fh_data)) + self.assertDictEqual(output_dict, expected) diff --git a/src/sonic-config-engine/tests/test_cfggen_t2_chassis_fe.py b/src/sonic-config-engine/tests/test_cfggen_t2_chassis_fe.py index f6de92121115..a3d6d02a7ff2 100644 --- a/src/sonic-config-engine/tests/test_cfggen_t2_chassis_fe.py +++ b/src/sonic-config-engine/tests/test_cfggen_t2_chassis_fe.py @@ -1,29 +1,36 @@ -from unittest import TestCase -import subprocess import os +import subprocess + +import tests.common_utils as utils + +from unittest import TestCase + class TestCfgGenT2ChassisFe(TestCase): def setUp(self): self.test_dir = os.path.dirname(os.path.realpath(__file__)) - self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen') + self.script_file = utils.PYTHON_INTERPRETTER + ' ' + os.path.join(self.test_dir, '..', 'sonic-cfggen') self.sample_graph_t2_chassis_fe = os.path.join(self.test_dir, 't2-chassis-fe-graph.xml') self.sample_graph_t2_chassis_fe_vni = os.path.join(self.test_dir, 't2-chassis-fe-graph-vni.xml') self.sample_graph_t2_chassis_fe_pc = os.path.join(self.test_dir, 't2-chassis-fe-graph-pc.xml') self.t2_chassis_fe_port_config = os.path.join(self.test_dir, 't2-chassis-fe-port-config.ini') def run_script(self, argument, check_stderr=False): - print '\n Running sonic-cfggen ' + argument + print('\n Running sonic-cfggen ' + argument) if check_stderr: output = subprocess.check_output(self.script_file + ' ' + argument, stderr=subprocess.STDOUT, shell=True) else: output = subprocess.check_output(self.script_file + ' ' + argument, shell=True) + if utils.PY3x: + output = output.decode() + linecount = output.strip().count('\n') if linecount <= 0: - print ' Output: ' + output.strip() + print(' Output: ' + output.strip()) else: - print ' Output: ({0} lines, {1} bytes)'.format(linecount + 1, len(output)) + print(' Output: ({0} lines, {1} bytes)'.format(linecount + 1, len(output))) return output def test_minigraph_t2_chassis_fe_type(self): @@ -34,24 +41,31 @@ def test_minigraph_t2_chassis_fe_type(self): def test_minigraph_t2_chassis_fe_interfaces(self): argument = '-m "' + self.sample_graph_t2_chassis_fe + '" -p "' + self.t2_chassis_fe_port_config + '" -v "INTERFACE"' output = self.run_script(argument) - self.assertEqual(output.strip(), - "{'Ethernet8': {}, " - "('Ethernet8', '172.16.0.9/30'): {}, " - "'Ethernet0': {'vnet_name': 'VnetFE'}, " - "('Ethernet4', '172.16.0.1/30'): {}, " - "('Ethernet0', '192.168.0.2/30'): {}, " - "'Ethernet4': {}}") - + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict( + "{'Ethernet8': {}, " + "('Ethernet8', '172.16.0.9/30'): {}, " + "'Ethernet0': {'vnet_name': 'VnetFE'}, " + "('Ethernet4', '172.16.0.1/30'): {}, " + "('Ethernet0', '192.168.0.2/30'): {}, " + "'Ethernet4': {}}" + ) + ) def test_minigraph_t2_chassis_fe_pc_interfaces(self): argument = '-m "' + self.sample_graph_t2_chassis_fe_pc + '" -p "' + self.t2_chassis_fe_port_config + '" -v "PORTCHANNEL_INTERFACE"' output = self.run_script(argument) - self.assertEqual(output.strip(), - "{'PortChannel8': {}, " - "('PortChannel0', '192.168.0.2/30'): {}, " - "('PortChannel4', '172.16.0.1/30'): {}, " - "'PortChannel4': {}, " - "('PortChannel8', '172.16.0.9/30'): {}, " - "'PortChannel0': {'vnet_name': 'VnetFE'}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict( + "{'PortChannel8': {}, " + "('PortChannel0', '192.168.0.2/30'): {}, " + "('PortChannel4', '172.16.0.1/30'): {}, " + "'PortChannel4': {}, " + "('PortChannel8', '172.16.0.9/30'): {}, " + "'PortChannel0': {'vnet_name': 'VnetFE'}}" + ) + ) # Test a minigraph file where VNI is not specified # Default VNI is 8000 diff --git a/src/sonic-config-engine/tests/test_frr.py b/src/sonic-config-engine/tests/test_frr.py index fcbff063b13b..4998db2d5b25 100644 --- a/src/sonic-config-engine/tests/test_frr.py +++ b/src/sonic-config-engine/tests/test_frr.py @@ -1,13 +1,15 @@ -from unittest import TestCase -import subprocess -import os import filecmp +import os +import subprocess + +import tests.common_utils as utils +from unittest import TestCase class TestCfgGen(TestCase): def setUp(self): self.test_dir = os.path.dirname(os.path.realpath(__file__)) - self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen') + self.script_file = utils.PYTHON_INTERPRETTER + ' ' + os.path.join(self.test_dir, '..', 'sonic-cfggen') self.t0_minigraph = os.path.join(self.test_dir, 't0-sample-graph.xml') self.t0_port_config = os.path.join(self.test_dir, 't0-sample-port-config.ini') self.output_file = os.path.join(self.test_dir, 'output') @@ -26,37 +28,47 @@ def run_script(self, argument, check_stderr=False): else: output = subprocess.check_output(self.script_file + ' ' + argument, shell=True) + if utils.PY3x: + output = output.decode() + linecount = output.strip().count('\n') if linecount <= 0: - print ' Output: ' + output.strip() + print(' Output: ' + output.strip()) else: - print ' Output: ({0} lines, {1} bytes)'.format(linecount + 1, len(output)) + print(' Output: ({0} lines, {1} bytes)'.format(linecount + 1, len(output))) return output def run_diff(self, file1, file2): - return subprocess.check_output('diff -u {} {} || true'.format(file1, file2), shell=True) + output = subprocess.check_output('diff -u {} {} || true'.format(file1, file2), shell=True) + + if utils.PY3x: + output = output.decode() + + return output def run_case(self, template, target): - conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-frr', template) - cmd = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + conf_template + ' > ' + self.output_file + template_dir = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-frr', "frr") + conf_template = os.path.join(template_dir, template) + constants = os.path.join(self.test_dir, '..', '..', '..', 'files', 'image_config', 'constants', 'constants.yml') + cmd_args = self.t0_minigraph, self.t0_port_config, constants, conf_template, template_dir, self.output_file + cmd = "-m %s -p %s -y %s -t %s -T %s > %s" % cmd_args self.run_script(cmd) - original_filename = os.path.join(self.test_dir, 'sample_output', target) + original_filename = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, target) r = filecmp.cmp(original_filename, self.output_file) diff_output = self.run_diff(original_filename, self.output_file) if not r else "" return r, "Diff:\n" + diff_output - def test_config_frr(self): self.assertTrue(*self.run_case('frr.conf.j2', 'frr.conf')) def test_bgpd_frr(self): - self.assertTrue(*self.run_case('bgpd.conf.j2', 'bgpd_frr.conf')) + self.assertTrue(*self.run_case('bgpd/bgpd.conf.j2', 'bgpd_frr.conf')) def test_zebra_frr(self): - self.assertTrue(*self.run_case('zebra.conf.j2', 'zebra_frr.conf')) + self.assertTrue(*self.run_case('zebra/zebra.conf.j2', 'zebra_frr.conf')) def test_staticd_frr(self): - self.assertTrue(*self.run_case('staticd.conf.j2', 'staticd_frr.conf')) + self.assertTrue(*self.run_case('staticd/staticd.conf.j2', 'staticd_frr.conf')) diff --git a/src/sonic-config-engine/tests/test_j2files.py b/src/sonic-config-engine/tests/test_j2files.py index c3585a41d44e..a66cd99820be 100644 --- a/src/sonic-config-engine/tests/test_j2files.py +++ b/src/sonic-config-engine/tests/test_j2files.py @@ -1,15 +1,17 @@ import filecmp -import os -import subprocess import json +import os import shutil +import subprocess from unittest import TestCase +import tests.common_utils as utils + class TestJ2Files(TestCase): def setUp(self): self.test_dir = os.path.dirname(os.path.realpath(__file__)) - self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen') + self.script_file = utils.PYTHON_INTERPRETTER + ' ' + os.path.join(self.test_dir, '..', 'sonic-cfggen') self.simple_minigraph = os.path.join(self.test_dir, 'simple-sample-graph.xml') self.t0_minigraph = os.path.join(self.test_dir, 't0-sample-graph.xml') self.t0_mvrf_minigraph = os.path.join(self.test_dir, 't0-sample-graph-mvrf.xml') @@ -18,11 +20,19 @@ def setUp(self): self.t1_mlnx_minigraph = os.path.join(self.test_dir, 't1-sample-graph-mlnx.xml') self.mlnx_port_config = os.path.join(self.test_dir, 'sample-port-config-mlnx.ini') self.dell6100_t0_minigraph = os.path.join(self.test_dir, 'sample-dell-6100-t0-minigraph.xml') + self.arista7050_t0_minigraph = os.path.join(self.test_dir, 'sample-arista-7050-t0-minigraph.xml') + self.multi_asic_minigraph = os.path.join(self.test_dir, 'multi_npu_data', 'sample-minigraph.xml') + self.multi_asic_port_config = os.path.join(self.test_dir, 'multi_npu_data', 'sample_port_config-0.ini') self.output_file = os.path.join(self.test_dir, 'output') def run_script(self, argument): - print 'CMD: sonic-cfggen ' + argument - return subprocess.check_output(self.script_file + ' ' + argument, shell=True) + print('CMD: sonic-cfggen ' + argument) + output = subprocess.check_output(self.script_file + ' ' + argument, shell=True) + + if utils.PY3x: + output = output.decode() + + return output def run_diff(self, file1, file2): return subprocess.check_output('diff -u {} {} || true'.format(file1, file2), shell=True) @@ -31,42 +41,61 @@ def test_interfaces(self): interfaces_template = os.path.join(self.test_dir, '..', '..', '..', 'files', 'image_config', 'interfaces', 'interfaces.j2') argument = '-m ' + self.t0_minigraph + ' -a \'{\"hwaddr\":\"e4:1d:2d:a5:f3:ad\"}\' -t ' + interfaces_template + ' > ' + self.output_file self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'interfaces'), self.output_file)) + self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'interfaces'), self.output_file)) argument = '-m ' + self.t0_mvrf_minigraph + ' -a \'{\"hwaddr\":\"e4:1d:2d:a5:f3:ad\"}\' -t ' + interfaces_template + ' > ' + self.output_file self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'mvrf_interfaces'), self.output_file)) + self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'mvrf_interfaces'), self.output_file)) def test_ports_json(self): ports_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-orchagent', 'ports.json.j2') argument = '-m ' + self.simple_minigraph + ' -p ' + self.t0_port_config + ' -t ' + ports_template + ' > ' + self.output_file self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'ports.json'), self.output_file)) + self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'ports.json'), self.output_file)) def test_dhcp_relay(self): # Test generation of wait_for_intf.sh template_path = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-dhcp-relay', 'wait_for_intf.sh.j2') argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + template_path + ' > ' + self.output_file self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'wait_for_intf.sh'), self.output_file)) + self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'wait_for_intf.sh'), self.output_file)) # Test generation of docker-dhcp-relay.supervisord.conf template_path = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-dhcp-relay', 'docker-dhcp-relay.supervisord.conf.j2') argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + template_path + ' > ' + self.output_file self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'docker-dhcp-relay.supervisord.conf'), self.output_file)) + self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'docker-dhcp-relay.supervisord.conf'), self.output_file)) def test_lldp(self): - lldpd_conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-lldp-sv2', 'lldpd.conf.j2') - argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + lldpd_conf_template + ' > ' + self.output_file + lldpd_conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-lldp', 'lldpd.conf.j2') + + expected_mgmt_ipv4 = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'lldp_conf', 'lldpd-ipv4-iface.conf') + expected_mgmt_ipv6 = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'lldp_conf', 'lldpd-ipv6-iface.conf') + expected_mgmt_ipv4_and_ipv6 = expected_mgmt_ipv4 + + # Test generation of lldpd.conf if IPv4 and IPv6 management interfaces exist + mgmt_iface_ipv4_and_ipv6_json = os.path.join(self.test_dir, "data", "lldp", "mgmt_iface_ipv4_and_ipv6.json") + argument = '-j {} -t {} > {}'.format(mgmt_iface_ipv4_and_ipv6_json, lldpd_conf_template, self.output_file) + self.run_script(argument) + self.assertTrue(filecmp.cmp(expected_mgmt_ipv4_and_ipv6, self.output_file)) + + # Test generation of lldpd.conf if management interface IPv4 only exist + mgmt_iface_ipv4_json = os.path.join(self.test_dir, "data", "lldp", "mgmt_iface_ipv4.json") + argument = '-j {} -t {} > {}'.format(mgmt_iface_ipv4_json, lldpd_conf_template, self.output_file) + self.run_script(argument) + self.assertTrue(filecmp.cmp(expected_mgmt_ipv4, self.output_file)) + + # Test generation of lldpd.conf if Management interface IPv6 only exist + mgmt_iface_ipv6_json = os.path.join(self.test_dir, "data", "lldp", "mgmt_iface_ipv6.json") + argument = '-j {} -t {} > {}'.format(mgmt_iface_ipv6_json, lldpd_conf_template, self.output_file) self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'lldpd.conf'), self.output_file)) + self.assertTrue(filecmp.cmp(expected_mgmt_ipv6, self.output_file)) def test_bgpd_quagga(self): conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-quagga', 'bgpd.conf.j2') argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + conf_template + ' > ' + self.output_file self.run_script(argument) - original_filename = os.path.join(self.test_dir, 'sample_output', 'bgpd_quagga.conf') + original_filename = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'bgpd_quagga.conf') r = filecmp.cmp(original_filename, self.output_file) diff_output = self.run_diff(original_filename, self.output_file) if not r else "" self.assertTrue(r, "Diff:\n" + diff_output) @@ -75,23 +104,52 @@ def test_zebra_quagga(self): conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-quagga', 'zebra.conf.j2') argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + conf_template + ' > ' + self.output_file self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'zebra_quagga.conf'), self.output_file)) + self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'zebra_quagga.conf'), self.output_file)) def test_ipinip(self): ipinip_file = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-orchagent', 'ipinip.json.j2') argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + ipinip_file + ' > ' + self.output_file self.run_script(argument) - sample_output_file = os.path.join(self.test_dir, 'sample_output', 'ipinip.json') + sample_output_file = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'ipinip.json') assert filecmp.cmp(sample_output_file, self.output_file) def test_l2switch_template(self): - argument = '-k Mellanox-SN2700 -t ' + os.path.join(self.test_dir, '../data/l2switch.j2') + ' -p ' + self.t0_port_config + ' > ' + self.output_file + argument = '-k Mellanox-SN2700 --preset l2 -p ' + self.t0_port_config + output = self.run_script(argument) + output_json = json.loads(output) + + sample_output_file = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'l2switch.json') + with open(sample_output_file) as sample_output_fd: + sample_output_json = json.load(sample_output_fd) + + self.assertTrue(json.dumps(sample_output_json, sort_keys=True) == json.dumps(output_json, sort_keys=True)) + + template_dir = os.path.join(self.test_dir, '..', 'data', 'l2switch.j2') + argument = '-t ' + template_dir + ' -k Mellanox-SN2700 -p ' + self.t0_port_config + output = self.run_script(argument) + output_json = json.loads(output) + + self.assertTrue(json.dumps(sample_output_json, sort_keys=True) == json.dumps(output_json, sort_keys=True)) + + def test_qos_arista7050_render_template(self): + arista_dir_path = os.path.join(self.test_dir, '..', '..', '..', 'device', 'arista', 'x86_64-arista_7050_qx32s', 'Arista-7050-QX-32S') + qos_file = os.path.join(arista_dir_path, 'qos.json.j2') + port_config_ini_file = os.path.join(arista_dir_path, 'port_config.ini') + + # copy qos_config.j2 to the Arista 7050 directory to have all templates in one directory + qos_config_file = os.path.join(self.test_dir, '..', '..', '..', 'files', 'build_templates', 'qos_config.j2') + shutil.copy2(qos_config_file, arista_dir_path) + + argument = '-m ' + self.arista7050_t0_minigraph + ' -p ' + port_config_ini_file + ' -t ' + qos_file + ' > ' + self.output_file self.run_script(argument) - sample_output_file = os.path.join(self.test_dir, 'sample_output', 'l2switch.json') + # cleanup + qos_config_file_new = os.path.join(arista_dir_path, 'qos_config.j2') + os.remove(qos_config_file_new) - self.assertTrue(filecmp.cmp(sample_output_file, self.output_file)) + sample_output_file = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'qos-arista7050.json') + assert filecmp.cmp(sample_output_file, self.output_file) def test_qos_dell6100_render_template(self): dell_dir_path = os.path.join(self.test_dir, '..', '..', '..', 'device', 'dell', 'x86_64-dell_s6100_c2538-r0', 'Force10-S6100') @@ -109,7 +167,7 @@ def test_qos_dell6100_render_template(self): qos_config_file_new = os.path.join(dell_dir_path, 'qos_config.j2') os.remove(qos_config_file_new) - sample_output_file = os.path.join(self.test_dir, 'sample_output', 'qos-dell6100.json') + sample_output_file = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'qos-dell6100.json') assert filecmp.cmp(sample_output_file, self.output_file) def test_buffers_dell6100_render_template(self): @@ -128,9 +186,88 @@ def test_buffers_dell6100_render_template(self): buffers_config_file_new = os.path.join(dell_dir_path, 'buffers_config.j2') os.remove(buffers_config_file_new) - sample_output_file = os.path.join(self.test_dir, 'sample_output', 'buffers-dell6100.json') + sample_output_file = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'buffers-dell6100.json') assert filecmp.cmp(sample_output_file, self.output_file) + def test_ipinip_multi_asic(self): + ipinip_file = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-orchagent', 'ipinip.json.j2') + argument = '-m ' + self.multi_asic_minigraph + ' -p ' + self.multi_asic_port_config + ' -t ' + ipinip_file + ' -n asic0 ' + ' > ' + self.output_file + print(argument) + self.run_script(argument) + sample_output_file = os.path.join(self.test_dir, 'multi_npu_data', utils.PYvX_DIR, 'ipinip.json') + assert filecmp.cmp(sample_output_file, self.output_file) + + def test_swss_switch_render_template(self): + switch_template = os.path.join( + self.test_dir, '..', '..', '..', 'dockers', 'docker-orchagent', + 'switch.json.j2' + ) + constants_yml = os.path.join( + self.test_dir, '..', '..', '..', 'files', 'image_config', + 'constants', 'constants.yml' + ) + test_list = { + "t1": { + "graph": self.t1_mlnx_minigraph, + "output": "t1-switch.json" + }, + "t0": { + "graph": self.t0_minigraph, + "output": "t0-switch.json" + }, + } + for _, v in test_list.items(): + argument = " -m {} -y {} -t {} > {}".format( + v["graph"], constants_yml, switch_template, self.output_file + ) + sample_output_file = os.path.join( + self.test_dir, 'sample_output', v["output"] + ) + self.run_script(argument) + assert filecmp.cmp(sample_output_file, self.output_file) + + def test_swss_switch_render_template_multi_asic(self): + # verify the ECMP hash seed changes per namespace + switch_template = os.path.join( + self.test_dir, '..', '..', '..', 'dockers', 'docker-orchagent', + 'switch.json.j2' + ) + constants_yml = os.path.join( + self.test_dir, '..', '..', '..', 'files', 'image_config', + 'constants', 'constants.yml' + ) + test_list = { + "0": { + "namespace_id": "1", + "output": "t0-switch-masic1.json" + }, + "1": { + "namespace_id": "3", + "output": "t0-switch-masic3.json" + }, + } + for _, v in test_list.items(): + os.environ["NAMESPACE_ID"] = v["namespace_id"] + argument = " -m {} -y {} -t {} > {}".format( + self.t1_mlnx_minigraph, constants_yml, switch_template, + self.output_file + ) + sample_output_file = os.path.join( + self.test_dir, 'sample_output', v["output"] + ) + self.run_script(argument) + assert filecmp.cmp(sample_output_file, self.output_file) + os.environ["NAMESPACE_ID"] = "" + + def test_ndppd_conf(self): + conf_template = os.path.join(self.test_dir, "ndppd.conf.j2") + vlan_interfaces_json = os.path.join(self.test_dir, "data", "ndppd", "vlan_interfaces.json") + expected = os.path.join(self.test_dir, "sample_output", utils.PYvX_DIR, "ndppd.conf") + + argument = '-j {} -t {} > {}'.format(vlan_interfaces_json, conf_template, self.output_file) + self.run_script(argument) + assert filecmp.cmp(expected, self.output_file), self.run_diff(expected, self.output_file) + def tearDown(self): try: os.remove(self.output_file) diff --git a/src/sonic-config-engine/tests/test_j2files_t2_chassis_fe.py b/src/sonic-config-engine/tests/test_j2files_t2_chassis_fe.py index 41ac347e2b18..e6bc82941bf6 100644 --- a/src/sonic-config-engine/tests/test_j2files_t2_chassis_fe.py +++ b/src/sonic-config-engine/tests/test_j2files_t2_chassis_fe.py @@ -1,15 +1,17 @@ import filecmp -import os -import subprocess import json +import os import shutil +import subprocess from unittest import TestCase +import tests.common_utils as utils + class TestJ2FilesT2ChassisFe(TestCase): def setUp(self): self.test_dir = os.path.dirname(os.path.realpath(__file__)) - self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen') + self.script_file = utils.PYTHON_INTERPRETTER + ' ' + os.path.join(self.test_dir, '..', 'sonic-cfggen') self.t2_chassis_fe_minigraph = os.path.join(self.test_dir, 't2-chassis-fe-graph.xml') self.t2_chassis_fe_vni_minigraph = os.path.join(self.test_dir, 't2-chassis-fe-graph-vni.xml') self.t2_chassis_fe_pc_minigraph = os.path.join(self.test_dir, 't2-chassis-fe-graph-pc.xml') @@ -23,18 +25,26 @@ def tearDown(self): pass def run_script(self, argument): - print 'CMD: sonic-cfggen ' + argument - return subprocess.check_output(self.script_file + ' ' + argument, shell=True) + print('CMD: sonic-cfggen ' + argument) + output = subprocess.check_output(self.script_file + ' ' + argument, shell=True) + + if utils.PY3x: + output = output.decode() + + return output def run_diff(self, file1, file2): return subprocess.check_output('diff -u {} {} || true'.format(file1, file2), shell=True) def run_case(self, minigraph, template, target): - conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-frr', template) - cmd = '-m ' + minigraph + ' -p ' + self.t2_chassis_fe_port_config + ' -t ' + conf_template + ' > ' + self.output_file + template_dir = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-frr', "frr") + conf_template = os.path.join(template_dir, template) + constants = os.path.join(self.test_dir, '..', '..', '..', 'files', 'image_config', 'constants', 'constants.yml') + cmd_args = minigraph, self.t2_chassis_fe_port_config, constants, conf_template, template_dir, self.output_file + cmd = "-m %s -p %s -y %s -t %s -T %s > %s" % cmd_args self.run_script(cmd) - original_filename = os.path.join(self.test_dir, 'sample_output', target) + original_filename = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, target) r = filecmp.cmp(original_filename, self.output_file) diff_output = self.run_diff(original_filename, self.output_file) if not r else "" @@ -42,13 +52,13 @@ def run_case(self, minigraph, template, target): # Test zebra.conf in FRR docker for a T2 chassis frontend (fe) def test_t2_chassis_fe_zebra_frr(self): - self.assertTrue(*self.run_case(self.t2_chassis_fe_minigraph, 'zebra.conf.j2', 't2-chassis-fe-zebra.conf')) + self.assertTrue(*self.run_case(self.t2_chassis_fe_minigraph, 'zebra/zebra.conf.j2', 't2-chassis-fe-zebra.conf')) # Test zebra.conf in FRR docker for a T2 chassis frontend (fe) switch with specified VNI def test_t2_chassis_fe_vni_zebra_frr(self): - self.assertTrue(*self.run_case(self.t2_chassis_fe_vni_minigraph, 'zebra.conf.j2', 't2-chassis-fe-vni-zebra.conf')) + self.assertTrue(*self.run_case(self.t2_chassis_fe_vni_minigraph, 'zebra/zebra.conf.j2', 't2-chassis-fe-vni-zebra.conf')) # Test bgpd.conf in FRR docker for a T2 chassis frontend (fe) def test_t2_chassis_frontend_bgpd_frr(self): - self.assertTrue(*self.run_case(self.t2_chassis_fe_minigraph, 'bgpd.conf.j2', 't2-chassis-fe-bgpd.conf')) + self.assertTrue(*self.run_case(self.t2_chassis_fe_minigraph, 'bgpd/bgpd.conf.j2', 't2-chassis-fe-bgpd.conf')) diff --git a/src/sonic-config-engine/tests/test_minigraph_case.py b/src/sonic-config-engine/tests/test_minigraph_case.py index b77f0859584a..64e0bb09d730 100644 --- a/src/sonic-config-engine/tests/test_minigraph_case.py +++ b/src/sonic-config-engine/tests/test_minigraph_case.py @@ -1,27 +1,36 @@ -from unittest import TestCase -import subprocess +import json import os +import subprocess + +import tests.common_utils as utils +import minigraph + +from unittest import TestCase + class TestCfgGenCaseInsensitive(TestCase): def setUp(self): self.test_dir = os.path.dirname(os.path.realpath(__file__)) - self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen') + self.script_file = utils.PYTHON_INTERPRETTER + ' ' + os.path.join(self.test_dir, '..', 'sonic-cfggen') self.sample_graph = os.path.join(self.test_dir, 'simple-sample-graph-case.xml') self.port_config = os.path.join(self.test_dir, 't0-sample-port-config.ini') def run_script(self, argument, check_stderr=False): - print '\n Running sonic-cfggen ' + argument + print('\n Running sonic-cfggen ' + argument) if check_stderr: output = subprocess.check_output(self.script_file + ' ' + argument, stderr=subprocess.STDOUT, shell=True) else: output = subprocess.check_output(self.script_file + ' ' + argument, shell=True) + if utils.PY3x: + output = output.decode() + linecount = output.strip().count('\n') if linecount <= 0: - print ' Output: ' + output.strip() + print(' Output: ' + output.strip()) else: - print ' Output: ({0} lines, {1} bytes)'.format(linecount + 1, len(output)) + print(' Output: ({0} lines, {1} bytes)'.format(linecount + 1, len(output))) return output def test_dummy_run(self): @@ -44,6 +53,16 @@ def test_jinja_expression(self): output = self.run_script(argument) self.assertEqual(output.strip(), 'ToRRouter') + def test_minigraph_subtype(self): + argument = '-m "' + self.sample_graph + '" -v "DEVICE_METADATA[\'localhost\'][\'subtype\']"' + output = self.run_script(argument) + self.assertEqual(output.strip(), 'DualToR') + + def test_minigraph_peer_switch_hostname(self): + argument = '-m "' + self.sample_graph + '" -v "DEVICE_METADATA[\'localhost\'][\'peer_switch\']"' + output = self.run_script(argument) + self.assertEqual(output.strip(), 'switch2-t0') + def test_additional_json_data(self): argument = '-a \'{"key1":"value1"}\' -v key1' output = self.run_script(argument) @@ -66,44 +85,110 @@ def test_render_template(self): # self.assertEqual(output.strip(), "{'everflow0': {'src_ip': '10.1.0.32', 'dst_ip': '10.0.100.1'}}") def test_minigraph_interfaces(self): - argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v \'INTERFACE.keys()\'' + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v \'INTERFACE.keys()|list\'' output = self.run_script(argument) self.assertEqual(output.strip(), "[('Ethernet0', '10.0.0.58/31'), 'Ethernet0', ('Ethernet0', 'FC00::75/126')]") def test_minigraph_vlans(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v VLAN' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'Vlan1000': {'alias': 'ab1', 'dhcp_servers': ['192.0.0.1', '192.0.0.2'], 'vlanid': '1000'}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'Vlan1000': {'alias': 'ab1', 'dhcp_servers': ['192.0.0.1', '192.0.0.2'], 'vlanid': '1000', 'mac': '00:aa:bb:cc:dd:ee' }}") + ) def test_minigraph_vlan_members(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v VLAN_MEMBER' output = self.run_script(argument) self.assertEqual(output.strip(), "{('Vlan1000', 'Ethernet8'): {'tagging_mode': 'untagged'}}") - def test_minigraph_vlan_interfaces(self): - argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "VLAN_INTERFACE.keys()"' + def test_minigraph_vlan_interfaces_keys(self): + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "VLAN_INTERFACE.keys()|list"' output = self.run_script(argument) self.assertEqual(output.strip(), "[('Vlan1000', '192.168.0.1/27'), 'Vlan1000']") + def test_minigraph_vlan_interfaces(self): + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "VLAN_INTERFACE"' + output = self.run_script(argument) + expected_table = { + 'Vlan1000|192.168.0.1/27': {}, + 'Vlan1000': { + 'proxy_arp': 'enabled', + 'grat_arp': 'enabled' + } + } + self.assertEqual(utils.to_dict(output.strip()), expected_table) + def test_minigraph_portchannels(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v PORTCHANNEL' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'PortChannel01': {'admin_status': 'up', 'min_links': '1', 'members': ['Ethernet4'], 'mtu': '9100'}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'PortChannel01': {'admin_status': 'up', 'min_links': '1', 'members': ['Ethernet4'], 'mtu': '9100'}}") + ) + + def test_minigraph_console_mgmt_feature(self): + argument = '-m "' + self.sample_graph + '" -v CONSOLE_SWITCH' + output = self.run_script(argument) + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'console_mgmt': {'enabled': 'no'}}")) def test_minigraph_console_port(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v CONSOLE_PORT' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'1': {'baud_rate': '9600', 'remote_device': 'managed_device', 'flow_control': 1}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'1': {'baud_rate': '9600', 'remote_device': 'managed_device', 'flow_control': 1}}")) def test_minigraph_deployment_id(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "DEVICE_METADATA[\'localhost\'][\'deployment_id\']"' output = self.run_script(argument) self.assertEqual(output.strip(), "1") + def test_minigraph_cluster(self): + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "DEVICE_METADATA[\'localhost\'][\'cluster\']"' + output = self.run_script(argument) + self.assertEqual(output.strip(), "AAA00PrdStr00") + def test_minigraph_neighbor_metadata(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "DEVICE_NEIGHBOR_METADATA"' + + expected_table = { + 'switch-01t1': { + 'lo_addr': '10.1.0.186/32', + 'mgmt_addr': '10.7.0.196/26', + 'hwsku': 'Force10-S6000', + 'type': 'LeafRouter', + 'deployment_id': '2' + }, + 'switch2-t0': { + 'hwsku': 'Force10-S6000', + 'lo_addr': '25.1.1.10/32', + 'mgmt_addr': '10.7.0.196/26', + 'type': 'ToRRouter' + }, + 'server1': { + 'hwsku': 'server-sku', + 'lo_addr': '10.10.10.1/32', + 'lo_addr_v6': 'fe80::0001/80', + 'mgmt_addr': '10.0.0.1/32', + 'type': 'Server' + }, + 'server2': { + 'hwsku': 'server-sku', + 'lo_addr': '10.10.10.2/32', + 'lo_addr_v6': 'fe80::0002/128', + 'mgmt_addr': '10.0.0.2/32', + 'type': 'Server' + } + } output = self.run_script(argument) - self.assertEqual(output.strip(), "{'switch-01t1': {'lo_addr': '10.1.0.186/32', 'mgmt_addr': '10.7.0.196/26', 'hwsku': 'Force10-S6000', 'type': 'LeafRouter', 'deployment_id': '2'}}") + self.maxDiff = None + self.assertEqual( + utils.to_dict(output.strip()), + expected_table + ) # everflow portion is not used # def test_metadata_everflow(self): @@ -116,6 +201,12 @@ def test_metadata_tacacs(self): output = self.run_script(argument) self.assertEqual(output.strip(), "{'10.0.10.7': {'priority': '1', 'tcp_port': '49'}, '10.0.10.8': {'priority': '1', 'tcp_port': '49'}}") + def test_metadata_kube(self): + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "KUBERNETES_MASTER[\'SERVER\']"' + output = self.run_script(argument) + self.assertEqual(json.loads(output.strip().replace("'", "\"")), + json.loads('{"ip": "10.10.10.10", "disable": "True"}')) + def test_minigraph_mgmt_port(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "MGMT_PORT"' output = self.run_script(argument) @@ -141,3 +232,72 @@ def test_minigraph_bgp_mon(self): output = self.run_script(argument) self.assertEqual(output.strip(), "{}") + def test_minigraph_peer_switch(self): + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "PEER_SWITCH"' + expected_table = { + 'switch2-t0': { + 'address_ipv4': "25.1.1.10" + } + } + + output = self.run_script(argument) + self.assertEqual( + utils.to_dict(output.strip()), + expected_table + ) + + def test_mux_cable_parsing(self): + result = minigraph.parse_xml(self.sample_graph, port_config_file=self.port_config) + + expected_mux_cable_ports = ["Ethernet4", "Ethernet8"] + port_table = result['PORT'] + for port_name, port in port_table.items(): + if port_name in expected_mux_cable_ports: + self.assertTrue(port["mux_cable"]) + else: + self.assertTrue("mux_cable" not in port) + + def test_minigraph_storage_device(self): + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "DEVICE_METADATA[\'localhost\'][\'storage_device\']"' + output = self.run_script(argument) + self.assertEqual(output.strip(), "true") + + def test_minigraph_tunnel_table(self): + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "TUNNEL"' + expected_tunnel = { + "MuxTunnel0": { + "tunnel_type": "IPINIP", + "dst_ip": "10.1.0.32", + "dscp_mode": "uniform", + "encap_ecn_mode": "standard", + "ecn_mode": "copy_from_outer", + "ttl_mode": "pipe" + } + } + + output = self.run_script(argument) + self.assertEqual( + utils.to_dict(output.strip()), + expected_tunnel + ) + + def test_minigraph_mux_cable_table(self): + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "MUX_CABLE"' + expected_table = { + 'Ethernet4': { + 'state': 'auto', + 'server_ipv4': '10.10.10.1/32', + 'server_ipv6': 'fe80::1/128' + }, + 'Ethernet8': { + 'state': 'auto', + 'server_ipv4': '10.10.10.2/32', + 'server_ipv6': 'fe80::2/128' + } + } + + output = self.run_script(argument) + self.assertEqual( + utils.to_dict(output.strip()), + expected_table + ) diff --git a/src/sonic-config-engine/tests/test_multinpu_cfggen.py b/src/sonic-config-engine/tests/test_multinpu_cfggen.py new file mode 100644 index 000000000000..83955925c9e5 --- /dev/null +++ b/src/sonic-config-engine/tests/test_multinpu_cfggen.py @@ -0,0 +1,354 @@ +import json +import os +import shutil +import subprocess +import unittest +import yaml + +import tests.common_utils as utils + +from unittest import TestCase + + +SKU = 'multi-npu-01' +ASIC_SKU = 'multi-npu-asic' +NUM_ASIC = 4 +HOSTNAME = 'multi_npu_platform_01' +DEVICE_TYPE = 'LeafRouter' + +class TestMultiNpuCfgGen(TestCase): + + def setUp(self): + self.test_dir = os.path.dirname(os.path.realpath(__file__)) + self.test_data_dir = os.path.join(self.test_dir, 'multi_npu_data') + self.script_file = utils.PYTHON_INTERPRETTER + ' ' + os.path.join(self.test_dir, '..', 'sonic-cfggen') + self.sample_graph = os.path.join(self.test_data_dir, 'sample-minigraph.xml') + self.port_config = [] + for asic in range(NUM_ASIC): + self.port_config.append(os.path.join(self.test_data_dir, "sample_port_config-{}.ini".format(asic))) + + def run_script(self, argument, check_stderr=False): + print('\n Running sonic-cfggen ' + argument) + if check_stderr: + output = subprocess.check_output(self.script_file + ' ' + argument, stderr=subprocess.STDOUT, shell=True) + else: + output = subprocess.check_output(self.script_file + ' ' + argument, shell=True) + + if utils.PY3x: + output = output.decode() + + linecount = output.strip().count('\n') + if linecount <= 0: + print(' Output: ' + output.strip()) + else: + print(' Output: ({0} lines, {1} bytes)'.format(linecount + 1, len(output))) + return output + + def run_diff(self, file1, file2): + return subprocess.check_output('diff -u {} {} || true'.format(file1, file2), shell=True) + + def run_script_for_asic(self,argument,asic, port_config=None): + argument = "{} -n asic{} ".format(argument, asic) + if port_config: + argument += "-p {}".format(port_config) + output = self.run_script(argument) + return output + + def test_dummy_run(self): + argument = '' + output = self.run_script(argument) + self.assertEqual(output, '') + + def test_hwsku(self): + argument = "-v \"DEVICE_METADATA[\'localhost\'][\'hwsku\']\" -m \"{}\"".format(self.sample_graph) + output = self.run_script(argument) + self.assertEqual(output.strip(), SKU) + for asic in range(NUM_ASIC): + output = self.run_script_for_asic(argument, asic) + self.assertEqual(output.strip(), SKU) + + def test_print_data(self): + argument = "-m \"{}\" --print-data".format(self.sample_graph) + output = self.run_script(argument) + self.assertGreater(len(output.strip()) , 0) + for asic in range(NUM_ASIC): + output = self.run_script_for_asic(argument, asic) + self.assertGreater(len(output.strip()) , 0) + + def test_additional_json_data(self): + argument = '-a \'{"key1":"value1"}\' -v key1' + output = self.run_script(argument) + self.assertEqual(output.strip(), 'value1') + for asic in range(NUM_ASIC): + output = self.run_script_for_asic(argument, asic) + self.assertEqual(output.strip(), 'value1') + + def test_read_yaml(self): + argument = '-v yml_item -y ' + os.path.join(self.test_dir, 'test.yml') + output = yaml.load(self.run_script(argument)) + self.assertListEqual(output, ['value1', 'value2']) + for asic in range(NUM_ASIC): + output = yaml.load(self.run_script_for_asic(argument, asic)) + self.assertListEqual(output, ['value1', 'value2']) + + def test_render_template(self): + argument = '-y ' + os.path.join(self.test_dir, 'test.yml') + ' -t ' + os.path.join(self.test_dir, 'test.j2') + output = self.run_script(argument) + self.assertEqual(output.strip(), 'value1\nvalue2') + for asic in range(NUM_ASIC): + output = self.run_script_for_asic(argument, asic) + self.assertEqual(output.strip(), 'value1\nvalue2') + + def test_metadata_tacacs(self): + argument = '-m "' + self.sample_graph + '" --var-json "TACPLUS_SERVER"' + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, {'123.46.98.21': {'priority': '1', 'tcp_port': '49'}}) + #TACPLUS_SERVER not present in the asic configuration. + for asic in range(NUM_ASIC): + output = json.loads(self.run_script_for_asic(argument, asic, self.port_config[asic])) + self.assertDictEqual(output, {}) + + def test_metadata_ntp(self): + argument = '-m "' + self.sample_graph + '" --var-json "NTP_SERVER"' + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, {'17.39.1.130': {}, '17.39.1.129': {}}) + #NTP data is present only in the host config + for asic in range(NUM_ASIC): + output = json.loads(self.run_script_for_asic(argument, asic, self.port_config[asic])) + print("Log:asic{} sku {}".format(asic,output)) + self.assertDictEqual(output, {}) + + def test_mgmt_port(self): + argument = '-m "' + self.sample_graph + '" --var-json "MGMT_PORT"' + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, {'eth0': {'alias': 'eth0', 'admin_status': 'up'}}) + for asic in range(NUM_ASIC): + output = json.loads(self.run_script_for_asic(argument, asic, self.port_config[asic])) + self.assertDictEqual(output, {'eth0': {'alias': 'eth0', 'admin_status': 'up'}}) + + def test_frontend_asic_portchannels(self): + argument = "-m {} -p {} -n asic0 --var-json \"PORTCHANNEL\"".format(self.sample_graph, self.port_config[0]) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, \ + {'PortChannel0002': {'admin_status': 'up', 'min_links': '2', 'members': ['Ethernet0', 'Ethernet4'], 'mtu': '9100'}, + 'PortChannel4001': {'admin_status': 'up', 'min_links': '2', 'members': ['Ethernet-BP0', 'Ethernet-BP4'], 'mtu': '9100'}, + 'PortChannel4002': {'admin_status': 'up', 'min_links': '2', 'members': ['Ethernet-BP8', 'Ethernet-BP12'], 'mtu': '9100'}}) + + def test_backend_asic_portchannels(self): + argument = "-m {} -p {} -n asic3 --var-json \"PORTCHANNEL\"".format(self.sample_graph, self.port_config[3]) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, \ + {'PortChannel4013': {'admin_status': 'up', 'min_links': '2', 'members': ['Ethernet-BP384', 'Ethernet-BP388'], 'mtu': '9100'}, + 'PortChannel4014': {'admin_status': 'up', 'min_links': '2', 'members': ['Ethernet-BP392', 'Ethernet-BP396'], 'mtu': '9100'}}) + + def test_frontend_asic_portchannel_mem(self): + argument = "-m {} -p {} -n asic0 -v \"PORTCHANNEL_MEMBER.keys()|list\"".format(self.sample_graph, self.port_config[0]) + output = self.run_script(argument) + self.assertEqual( + utils.liststr_to_dict(output.strip()), + utils.liststr_to_dict("['PortChannel4002|Ethernet-BP8', 'PortChannel0002|Ethernet0', 'PortChannel0002|Ethernet4', 'PortChannel4002|Ethernet-BP12', 'PortChannel4001|Ethernet-BP0', 'PortChannel4001|Ethernet-BP4']") + ) + + def test_backend_asic_portchannels_mem(self): + argument = "-m {} -p {} -n asic3 -v \"PORTCHANNEL_MEMBER.keys()|list\"".format(self.sample_graph, self.port_config[3]) + output = self.run_script(argument) + self.assertEqual( + utils.liststr_to_dict(output.strip()), + utils.liststr_to_dict("['PortChannel4013|Ethernet-BP384', 'PortChannel4014|Ethernet-BP392', 'PortChannel4014|Ethernet-BP396', 'PortChannel4013|Ethernet-BP388']") + ) + + def test_frontend_asic_portchannel_intf(self): + argument = "-m {} -p {} -n asic0 -v \"PORTCHANNEL_INTERFACE.keys()|list\"".format(self.sample_graph, self.port_config[0]) + output = self.run_script(argument) + self.assertEqual( + utils.liststr_to_dict(output.strip()), + utils.liststr_to_dict("['PortChannel4001|10.1.0.1/31', 'PortChannel0002|FC00::1/126', 'PortChannel4002|10.1.0.3/31', 'PortChannel0002', 'PortChannel0002|10.0.0.0/31', 'PortChannel4001', 'PortChannel4002']") + ) + + def test_backend_asic_portchannel_intf(self): + argument = "-m {} -p {} -n asic3 -v \"PORTCHANNEL_INTERFACE.keys()|list\"".format(self.sample_graph, self.port_config[3]) + output = self.run_script(argument) + self.assertEqual( + utils.liststr_to_dict(output.strip()), + utils.liststr_to_dict("['PortChannel4013', 'PortChannel4013|10.1.0.2/31', 'PortChannel4014', 'PortChannel4014|10.1.0.6/31']") + ) + + def test_frontend_asic_ports(self): + argument = "-m {} -p {} -n asic0 --var-json \"PORT\"".format(self.sample_graph, self.port_config[0]) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, \ + {"Ethernet0": { "admin_status": "up", "alias": "Ethernet1/1", "asic_port_name": "Eth0-ASIC0", "description": "01T2:Ethernet1", "index": "0", "lanes": "33,34,35,36", "mtu": "9100", "pfc_asym": "off", "role": "Ext", "speed": "40000" }, + "Ethernet4": { "admin_status": "up", "alias": "Ethernet1/2", "asic_port_name": "Eth1-ASIC0", "description": "01T2:Ethernet2", "index": "1", "lanes": "29,30,31,32", "mtu": "9100", "pfc_asym": "off", "role": "Ext", "speed": "40000" }, + "Ethernet8": { "alias": "Ethernet1/3", "asic_port_name": "Eth2-ASIC0", "description": "Ethernet1/3", "index": "2", "lanes": "41,42,43,44", "mtu": "9100", "pfc_asym": "off", "role": "Ext", "speed": "40000" }, + "Ethernet12": { "alias": "Ethernet1/4", "asic_port_name": "Eth3-ASIC0", "description": "Ethernet1/4", "index": "3", "lanes": "37,38,39,40", "mtu": "9100", "pfc_asym": "off", "role": "Ext", "speed": "40000" }, + "Ethernet-BP0": { "admin_status": "up", "alias": "Eth4-ASIC0", "asic_port_name": "Eth4-ASIC0", "description": "ASIC2:Eth0-ASIC2", "index": "0", "lanes": "13,14,15,16", "mtu": "9100", "pfc_asym": "off", "role": "Int", "speed": "40000" }, + "Ethernet-BP4": { "admin_status": "up", "alias": "Eth5-ASIC0", "asic_port_name": "Eth5-ASIC0", "description": "ASIC2:Eth1-ASIC2", "index": "1", "lanes": "17,18,19,20", "mtu": "9100", "pfc_asym": "off", "role": "Int", "speed": "40000" }, + "Ethernet-BP8": { "admin_status": "up", "alias": "Eth6-ASIC0", "asic_port_name": "Eth6-ASIC0", "description": "ASIC3:Eth0-ASIC3", "index": "2", "lanes": "21,22,23,24", "mtu": "9100", "pfc_asym": "off", "role": "Int", "speed": "40000" }, + "Ethernet-BP12": { "admin_status": "up", "alias": "Eth7-ASIC0", "asic_port_name": "Eth7-ASIC0", "description": "ASIC3:Eth1-ASIC3", "index": "3", "lanes": "25,26,27,28", "mtu": "9100", "pfc_asym": "off", "role": "Int", "speed": "40000" }}) + + def test_frontend_asic_device_neigh(self): + argument = "-m {} -p {} -n asic0 --var-json \"DEVICE_NEIGHBOR\"".format(self.sample_graph, self.port_config[0]) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, \ + {'Ethernet0': {'name': '01T2', 'port': 'Ethernet1'}, + 'Ethernet4': {'name': '01T2', 'port': 'Ethernet2'}, + 'Ethernet-BP4': {'name': 'ASIC2', 'port': 'Eth1-ASIC2'}, + 'Ethernet-BP12': {'name': 'ASIC3', 'port': 'Eth1-ASIC3'}, + 'Ethernet-BP0': {'name': 'ASIC2', 'port': 'Eth0-ASIC2'}, + 'Ethernet-BP8': {'name': 'ASIC3', 'port': 'Eth0-ASIC3'}}) + + def test_frontend_asic_device_neigh_metadata(self): + argument = "-m {} -p {} -n asic0 --var-json \"DEVICE_NEIGHBOR_METADATA\"".format(self.sample_graph, self.port_config[0]) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, \ + {'01T2': {'lo_addr': None, 'mgmt_addr': '89.139.132.40', 'hwsku': 'VM', 'type': 'SpineRouter'}, + 'ASIC3': {'lo_addr': '0.0.0.0/0', 'lo_addr_v6': '::/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'}, + 'ASIC2': {'lo_addr': '0.0.0.0/0', 'lo_addr_v6': '::/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'}}) + + def test_backend_asic_device_neigh(self): + argument = "-m {} -p {} -n asic3 --var-json \"DEVICE_NEIGHBOR\"".format(self.sample_graph, self.port_config[3]) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, \ + {'Ethernet-BP396': {'name': 'ASIC1', 'port': 'Eth7-ASIC1'}, + 'Ethernet-BP384': {'name': 'ASIC0', 'port': 'Eth6-ASIC0'}, + 'Ethernet-BP392': {'name': 'ASIC1', 'port': 'Eth6-ASIC1'}, + 'Ethernet-BP388': {'name': 'ASIC0', 'port': 'Eth7-ASIC0'}}) + + def test_backend_device_neigh_metadata(self): + argument = "-m {} -p {} -n asic3 --var-json \"DEVICE_NEIGHBOR_METADATA\"".format(self.sample_graph, self.port_config[3]) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, \ + {'ASIC1': {'lo_addr': '0.0.0.0/0', 'lo_addr_v6': '::/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'}, + 'ASIC0': {'lo_addr': '0.0.0.0/0', 'lo_addr_v6': '::/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'}}) + + def test_frontend_bgp_neighbor(self): + argument = "-m {} -p {} -n asic0 --var-json \"BGP_NEIGHBOR\"".format(self.sample_graph, self.port_config[0]) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, \ + {'10.0.0.1': {'rrclient': 0, 'name': '01T2', 'local_addr': '10.0.0.0', 'nhopself': 0, 'holdtime': '10', 'asn': '65200', 'keepalive': '3'}, + 'fc00::2': {'rrclient': 0, 'name': '01T2', 'local_addr': 'fc00::1', 'nhopself': 0, 'holdtime': '10', 'asn': '65200', 'keepalive': '3'}}) + + def test_frontend_asic_bgp_neighbor(self): + argument = "-m {} -p {} -n asic0 --var-json \"BGP_INTERNAL_NEIGHBOR\"".format(self.sample_graph, self.port_config[3]) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, \ + {'10.1.0.0': {'rrclient': 0, 'name': 'ASIC2', 'local_addr': '10.1.0.1', 'nhopself': 0, 'admin_status': 'up', 'holdtime': '0', 'asn': '65100', 'keepalive': '0'}, + '10.1.0.2': {'rrclient': 0, 'name': 'ASIC3', 'local_addr': '10.1.0.3', 'nhopself': 0, 'admin_status': 'up', 'holdtime': '0', 'asn': '65100', 'keepalive': '0'}}) + + def test_backend_asic_bgp_neighbor(self): + argument = "-m {} -p {} -n asic3 --var-json \"BGP_INTERNAL_NEIGHBOR\"".format(self.sample_graph, self.port_config[3]) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, \ + {'10.1.0.7': {'rrclient': 0, 'name': 'ASIC1', 'local_addr': '10.1.0.6', 'nhopself': 0, 'admin_status': 'up', 'holdtime': '0', 'asn': '65100', 'keepalive': '0'}, + '10.1.0.3': {'rrclient': 0, 'name': 'ASIC0', 'local_addr': '10.1.0.2', 'nhopself': 0, 'admin_status': 'up', 'holdtime': '0', 'asn': '65100', 'keepalive': '0'}}) + + def test_device_asic_metadata(self): + argument = "-m {} --var-json DEVICE_METADATA".format(self.sample_graph) + for asic in range(NUM_ASIC): + output = json.loads(self.run_script_for_asic(argument, asic,self.port_config[asic])) + asic_name = "asic{}".format(asic) + self.assertEqual(output['localhost']['hostname'], 'multi_npu_platform_01') + self.assertEqual(output['localhost']['asic_name'], asic_name) + self.assertEqual(output['localhost']['type'], DEVICE_TYPE) + if asic == 0 or asic == 1: + self.assertEqual(output['localhost']['sub_role'], 'FrontEnd') + else: + self.assertEqual(output['localhost']['sub_role'], 'BackEnd') + + def test_global_asic_acl(self): + argument = "-m {} --var-json \"ACL_TABLE\"".format(self.sample_graph) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, {\ + 'DATAACL': {'policy_desc': 'DATAACL', 'ports': ['PortChannel0002','PortChannel0008'], 'stage': 'ingress', 'type': 'L3'}, + 'EVERFLOW': {'policy_desc': 'EVERFLOW', 'ports': ['PortChannel0002','PortChannel0008'], 'stage': 'ingress', 'type': 'MIRROR'}, + 'EVERFLOWV6':{'policy_desc': 'EVERFLOWV6', 'ports': ['PortChannel0002','PortChannel0008'], 'stage': 'ingress', 'type': 'MIRRORV6'}, + 'SNMP_ACL': {'policy_desc': 'SNMP_ACL', 'services': ['SNMP'], 'stage': 'ingress', 'type': 'CTRLPLANE'}, + 'SSH_ONLY': {'policy_desc': 'SSH_ONLY', 'services': ['SSH'], 'stage': 'ingress', 'type': 'CTRLPLANE'}}) + + def test_front_end_asic_acl(self): + argument = "-m {} -p {} -n asic0 --var-json \"ACL_TABLE\"".format(self.sample_graph, self.port_config[0]) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, {\ + 'DATAACL': {'policy_desc': 'DATAACL', 'ports': ['PortChannel0002'], 'stage': 'ingress', 'type': 'L3'}, + 'EVERFLOW': {'policy_desc': 'EVERFLOW', 'ports': ['PortChannel0002'], 'stage': 'ingress', 'type': 'MIRROR'}, + 'EVERFLOWV6':{'policy_desc': 'EVERFLOWV6', 'ports': ['PortChannel0002'], 'stage': 'ingress', 'type': 'MIRRORV6'}, + 'SNMP_ACL': {'policy_desc': 'SNMP_ACL', 'services': ['SNMP'], 'stage': 'ingress', 'type': 'CTRLPLANE'}, + 'SSH_ONLY': {'policy_desc': 'SSH_ONLY', 'services': ['SSH'], 'stage': 'ingress', 'type': 'CTRLPLANE'}}) + + def test_back_end_asic_acl(self): + argument = "-m {} -p {} -n asic3 --var-json \"ACL_TABLE\"".format(self.sample_graph, self.port_config[3]) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, {}) + + def test_loopback_intfs(self): + argument = "-m {} --var-json \"LOOPBACK_INTERFACE\"".format(self.sample_graph) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, {\ + "Loopback0": {}, + "Loopback0|10.1.0.32/32": {}, + "Loopback0|FC00:1::32/128": {}}) + + # The asic configuration should have 2 loopback interfaces + argument = "-m {} -n asic0 --var-json \"LOOPBACK_INTERFACE\"".format(self.sample_graph) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, { \ + "Loopback0": {}, + "Loopback4096": {}, + "Loopback0|10.1.0.32/32": {}, + "Loopback0|FC00:1::32/128": {}, + "Loopback4096|8.0.0.0/32": {}, + "Loopback4096|FD00:1::32/128": {}}) + + argument = "-m {} -n asic3 --var-json \"LOOPBACK_INTERFACE\"".format(self.sample_graph) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, {\ + "Loopback0": {}, + "Loopback4096": {}, + "Loopback0|10.1.0.32/32": {}, + "Loopback0|FC00:1::32/128": {}, + "Loopback4096|8.0.0.5/32": {}, + "Loopback4096|FD00:4::32/128": {}}) + + def test_buffers_multi_asic_template(self): + build_root_dir = os.path.join( + self.test_dir, "..", "..", ".." + ) + # using Trident2 buffer configuration + device_config_dir = os.path.join( + build_root_dir, + "device", + "arista", + "x86_64-arista_7050_qx32", + "Arista-7050-QX32" + ) + device_buffer_template = os.path.join( + device_config_dir, "buffers.json.j2" + ) + buffer_template = os.path.join( + build_root_dir, "files", "build_templates", "buffers_config.j2" + ) + port_config_ini_asic0 = os.path.join( + self.test_data_dir, "sample_port_config-0.ini" + ) + # asic0 - mix of front end and back end ports + shutil.copy2(buffer_template, device_config_dir) + argument = "-m {} -p {} -n asic0 -t {}".format( + self.sample_graph, port_config_ini_asic0, device_buffer_template + ) + output = json.loads(self.run_script(argument)) + os.remove(os.path.join(device_config_dir, "buffers_config.j2")) + self.assertDictEqual( + output['CABLE_LENGTH'], + { + 'AZURE': { + 'Ethernet8': '300m', + 'Ethernet0': '300m', + 'Ethernet4': '300m', + 'Ethernet-BP4': '5m', + 'Ethernet-BP0': '5m', + 'Ethernet-BP12': '5m', + 'Ethernet-BP8': '5m', + 'Ethernet12': '300m' + } + } + ) diff --git a/src/sonic-ctrmgrd/.gitignore b/src/sonic-ctrmgrd/.gitignore new file mode 100644 index 000000000000..bdebd5e838cd --- /dev/null +++ b/src/sonic-ctrmgrd/.gitignore @@ -0,0 +1,12 @@ +.eggs/ +build/ +dist/ +*.egg-info/ +ctrmgr/*.pyc +tests/*.pyc +tests/__pycache__/ +.idea +.coverage +ctrmgr/__pycache__/ +venv +tests/.coverage* diff --git a/src/sonic-ctrmgrd/README.rst b/src/sonic-ctrmgrd/README.rst new file mode 100644 index 000000000000..30207f44b3ee --- /dev/null +++ b/src/sonic-ctrmgrd/README.rst @@ -0,0 +1,3 @@ +" +This Package contains modules required for remote container management. +" diff --git a/src/sonic-ctrmgrd/ctrmgr/__init__.py b/src/sonic-ctrmgrd/ctrmgr/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/src/sonic-ctrmgrd/ctrmgr/container b/src/sonic-ctrmgrd/ctrmgr/container new file mode 100755 index 000000000000..ff3706a6a7a7 --- /dev/null +++ b/src/sonic-ctrmgrd/ctrmgr/container @@ -0,0 +1,413 @@ +#!/usr/bin/env python3 + +import argparse +import os +import inspect +import json +import syslog +import time +import datetime + +import docker +from swsscommon import swsscommon + +CTR_STATE_SCR_PATH = '/usr/share/sonic/scripts/container_startup.py' + +state_db = None + +# DB field names +FEATURE_TABLE = "FEATURE" +SET_OWNER = "set_owner" +NO_FALLBACK = "no_fallback_to_local" + +CURRENT_OWNER = "current_owner" +UPD_TIMESTAMP = "update_time" +CONTAINER_ID = "container_id" +REMOTE_STATE = "remote_state" +VERSION = "container_version" +SYSTEM_STATE = "system_state" + +KUBE_LABEL_TABLE = "KUBE_LABELS" +KUBE_LABEL_SET_KEY = "SET" + +# Get seconds to wait for remote docker to start. +# If not, revert to local +# +SONIC_CTR_CONFIG = "/etc/sonic/remote_ctr.config.json" +SONIC_CTR_CONFIG_PEND_SECS = "revert_to_local_on_wait_seconds" +DEFAULT_PEND_SECS = ( 5 * 60 ) +WAIT_POLL_SECS = 2 + +remote_ctr_enabled = False + +def debug_msg(m): + msg = "{}: {}".format(inspect.stack()[1][3], m) + # print(msg) + syslog.syslog(syslog.LOG_DEBUG, msg) + + +def init(): + """ Get DB connections """ + global state_db, cfg_db, remote_ctr_enabled + + cfg_db = swsscommon.DBConnector("CONFIG_DB", 0) + state_db = swsscommon.DBConnector("STATE_DB", 0) + + remote_ctr_enabled = os.path.exists(CTR_STATE_SCR_PATH) + + +def get_config_data(fld, dflt): + """ Read entry from kube config file """ + if os.path.exists(SONIC_CTR_CONFIG): + with open(SONIC_CTR_CONFIG, "r") as s: + d = json.load(s) + if fld in d: + return d[fld] + return dflt + + +def read_data(is_config, feature, fields): + """ Read data from DB for desired fields using given defaults""" + ret = [] + + db = cfg_db if is_config else state_db + + tbl = swsscommon.Table(db, FEATURE_TABLE) + + data = dict(tbl.get(feature)[1]) + for (field, default) in fields: + val = data.get(field, default) + ret += [val] + + debug_msg("config:{} feature:{} fields:{} val:{}".format( + is_config, feature, str(fields), str(ret))) + + return tuple(ret) + + +def read_config(feature): + """ Read requried feature config """ + set_owner, no_fallback = read_data(True, feature, + [(SET_OWNER, "local"), (NO_FALLBACK, False)]) + + return (set_owner, not no_fallback) + + +def read_state(feature): + """ Read requried feature state """ + + return read_data(False, feature, + [(CURRENT_OWNER, "none"), (REMOTE_STATE, "none"), (CONTAINER_ID, "")]) + + +def docker_action(action, feature, **kwargs): + """ Execute docker action """ + try: + client = docker.from_env() + container = client.containers.get(feature) + getattr(container, action)(**kwargs) + syslog.syslog(syslog.LOG_INFO, "docker cmd: {} for {}".format(action, feature)) + return 0 + + except (docker.errors.NotFound, docker.errors.APIError) as err: + syslog.syslog(syslog.LOG_ERR, "docker cmd: {} for {} failed with {}". + format(action, feature, str(err))) + return -1 + + +def set_label(feature, create): + """ Set/drop label as required + Update is done in state-db. + ctrmgrd sets it with kube API server as required + """ + if remote_ctr_enabled: + tbl = swsscommon.Table(state_db, KUBE_LABEL_TABLE) + fld = "{}_enabled".format(feature) + + # redundant set (data already exist) can still raise subscriber + # notification. So check & set. + # Redundant delete (data doesn't exist) does not raise any + # subscriber notification. So no need to pre-check for delete. + # + tbl.set(KUBE_LABEL_SET_KEY, [(fld, "true" if create else "false")]) + + +def update_data(feature, data): + if remote_ctr_enabled: + debug_msg("feature:{} data:{}".format(feature, str(data))) + tbl = swsscommon.Table(state_db, FEATURE_TABLE) + tbl.set(feature, list(data.items())) + + +def container_id(feature): + """ + Return the container ID for the feature. + + if current_owner is local, use feature name as the start/stop + of local image is synchronous. + Else get it from FEATURE table in STATE-DB + + :param feature: Name of the feature to start. + + """ + init() + + tbl = swsscommon.Table(state_db, "FEATURE") + data = dict(tbl.get(feature)[1]) + + if (data.get(CURRENT_OWNER, "").lower() == "local"): + return feature + else: + return data.get(CONTAINER_ID, feature) + + +def container_start(feature, **kwargs): + """ + Starts a container for given feature. + + Starts from local image and/or trigger kubernetes to deploy the image + for this feature. Marks the feature state up in STATE-DB FEATURE table. + + If feature's set_owner is local, invoke docker start. + If feature's set_owner is kube, it creates a node label that + would trigger kubernetes to start the container. With kube as + owner, if fallback is enabled and remote_state==none, it starts + the local image using docker, which will run until kube + deployment occurs. + + :param feature: Name of the feature to start. + + """ + START_LOCAL = 1 + START_KUBE = 2 + + ret = 0 + debug_msg("BEGIN") + + init() + + set_owner, fallback = read_config(feature) + _, remote_state, _ = read_state(feature) + + debug_msg("{}: set_owner:{} fallback:{} remote_state:{}".format( + feature, set_owner, fallback, remote_state)) + + data = { + SYSTEM_STATE: "up", + UPD_TIMESTAMP: str(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")) + } + + + start_val = 0 + if set_owner == "local": + start_val = START_LOCAL + else: + start_val = START_KUBE + if fallback and (remote_state == "none"): + start_val |= START_LOCAL + + if start_val == START_LOCAL: + # Implies *only* local. + # Ensure label is not there, to block kube deployment. + set_label(feature, False) + data[REMOTE_STATE] = "none" + + if (start_val & START_LOCAL): + data[CURRENT_OWNER] = "local" + data[CONTAINER_ID] = feature + + update_data(feature, data) + + if (start_val & START_LOCAL): + ret = docker_action("start", feature, **kwargs) + + if (start_val & START_KUBE): + set_label(feature, True) + debug_msg("END") + return ret + + +def container_stop(feature, **kwargs): + """ + Stops the running container for this feature. + + Instruct/ensure kube terminates, by removing label, unless + an kube upgrade is happening. + + Gets the container ID for this feature and call docker stop. + + Marks the feature state down in STATE-DB FEATURE table. + + :param feature: Name of the feature to stop. + + """ + debug_msg("BEGIN") + + init() + + set_owner, _ = read_config(feature) + current_owner, remote_state, _ = read_state(feature) + docker_id = container_id(feature) + remove_label = (remote_state != "pending") or (set_owner == "local") + + debug_msg("{}: set_owner:{} current_owner:{} remote_state:{} docker_id:{}".format( + feature, set_owner, current_owner, remote_state, docker_id)) + + if remove_label: + set_label(feature, False) + + if docker_id: + docker_action("stop", docker_id, **kwargs) + else: + syslog.syslog( + syslog.LOG_ERR if current_owner != "none" else syslog.LOG_INFO, + "docker stop skipped as no docker-id for {}".format(feature)) + + # Container could get killed or crashed. In either case + # it does not have opportunity to mark itself down. + # Even during normal termination, with SIGTERM received + # container process may not have enough window of time to + # mark itself down and has the potential to get aborted. + # + # systemctl ensures that it handles only one instance for + # a feature at anytime and however the feature container + # exits, upon stop/kill/crash, systemctl-stop process + # is assured to get called. So mark the feature down here. + # + data = { + CURRENT_OWNER: "none", + UPD_TIMESTAMP: str(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")), + CONTAINER_ID: "", + VERSION: "", + SYSTEM_STATE: "down" + } + if remote_state == "running": + data[REMOTE_STATE] = "stopped" + + update_data(feature, data) + + debug_msg("END") + + +def container_kill(feature, **kwargs): + """ + Kills the running container for this feature. + + Instruct/ensure kube terminates, by removing label. + + :param feature: Name of the feature to kill. + + """ + debug_msg("BEGIN") + + init() + + set_owner, _ = read_config(feature) + current_owner, remote_state, _ = read_state(feature) + docker_id = container_id(feature) + remove_label = (set_owner != "local") or (current_owner != "local") + + debug_msg("{}: set_owner:{} current_owner:{} remote_state:{} docker_id:{}".format( + feature, set_owner, current_owner, remote_state, docker_id)) + + if remove_label: + set_label(feature, False) + + if docker_id: + docker_action("kill", docker_id, **kwargs) + + else: + syslog.syslog( + syslog.LOG_ERR if current_owner != "none" else syslog.LOG_INFO, + "docker stop skipped as no docker-id for {}".format(feature)) + + + debug_msg("END") + + +def container_wait(feature, **kwargs): + """ + Waits on the running container for this feature. + + Get the container-id and call docker wait. + + If docker-id can't be obtained for a configurable fail-duration + the wait clears the feature's remote-state in STATE-DB FEATURE + table and exit. + + :param feature: Name of the feature to wait. + + """ + debug_msg("BEGIN") + + init() + + set_owner, fallback = read_config(feature) + current_owner, remote_state, _ = read_state(feature) + docker_id = container_id(feature) + pend_wait_secs = 0 + + if not docker_id and fallback: + pend_wait_secs = get_config_data( + SONIC_CTR_CONFIG_PEND_SECS, DEFAULT_PEND_SECS) + + debug_msg("{}: set_owner:{} ct_owner:{} state:{} id:{} pend={}".format( + feature, set_owner, current_owner, remote_state, docker_id, + pend_wait_secs)) + + while not docker_id: + if fallback: + pend_wait_secs = pend_wait_secs - WAIT_POLL_SECS + if pend_wait_secs < 0: + break + + time.sleep(WAIT_POLL_SECS) + + current_owner, remote_state, docker_id = read_state(feature) + + debug_msg("wait_loop: {} = {} {} {}".format(feature, current_owner, remote_state, docker_id)) + + if (remote_state == "pending"): + update_data(feature, {REMOTE_STATE: "ready"}) + + if not docker_id: + # Clear remote state and exit. + # systemd would restart and fallback to local + update_data(feature, { REMOTE_STATE: "none" }) + debug_msg("{}: Exiting to fallback as remote is *not* starting". + format(feature)) + else: + debug_msg("END -- transitioning to docker wait") + docker_action("wait", docker_id, **kwargs) + + +def main(): + parser=argparse.ArgumentParser(description="container commands for start/stop/wait/kill/id") + parser.add_argument("action", choices=["start", "stop", "wait", "kill", "id"]) + parser.add_argument('-t', '--timeout', type=int, help='container action timeout value', default=None) + parser.add_argument("name") + + args = parser.parse_args() + kwargs = {} + + if args.action == "start": + container_start(args.name, **kwargs) + + elif args.action == "stop": + if args.timeout is not None: + kwargs['timeout'] = args.timeout + container_stop(args.name, **kwargs) + + elif args.action == "kill": + container_kill(args.name, **kwargs) + + elif args.action == "wait": + container_wait(args.name, **kwargs) + + elif args.action == "id": + id = container_id(args.name, **kwargs) + print(id) + + +if __name__ == "__main__": + main() diff --git a/src/sonic-ctrmgrd/ctrmgr/container_startup.py b/src/sonic-ctrmgrd/ctrmgr/container_startup.py new file mode 100755 index 000000000000..c56160aa488d --- /dev/null +++ b/src/sonic-ctrmgrd/ctrmgr/container_startup.py @@ -0,0 +1,291 @@ +#!/usr/bin/env python3 + +import argparse +import datetime +import inspect +import json +import subprocess +import syslog +import time + +from swsscommon import swsscommon + +# DB field names +SET_OWNER = "set_owner" + +CURRENT_OWNER = "current_owner" +UPD_TIMESTAMP = "update_time" +DOCKER_ID = "container_id" +REMOTE_STATE = "remote_state" +VERSION = "container_version" +SYSTEM_STATE = "system_state" + +KUBE_LABEL_TABLE = "KUBE_LABELS" +KUBE_LABEL_SET_KEY = "SET" + +UNIT_TESTING = 0 + + +def debug_msg(m): + msg = "{}: {}".format(inspect.stack()[1][3], m) + print(msg) + syslog.syslog(syslog.LOG_DEBUG, msg) + + +def _get_version_key(feature, version): + # Coin label for version control + return "{}_{}_enabled".format(feature, version) + + +def read_data(feature): + state_data = { + CURRENT_OWNER: "none", + UPD_TIMESTAMP: "", + DOCKER_ID: "", + REMOTE_STATE: "none", + VERSION: "0.0.0", + SYSTEM_STATE: "" + } + + set_owner = "local" + + # read owner from config-db and current state data from state-db. + db = swsscommon.DBConnector("CONFIG_DB", 0) + tbl = swsscommon.Table(db, 'FEATURE') + data = dict(tbl.get(feature)[1]) + + if (SET_OWNER in data): + set_owner = data[SET_OWNER] + + state_db = swsscommon.DBConnector("STATE_DB", 0) + tbl = swsscommon.Table(state_db, 'FEATURE') + state_data.update(dict(tbl.get(feature)[1])) + + return (state_db, set_owner, state_data) + + +def read_fields(state_db, feature, fields): + # Read directly from STATE-DB, given fields + # for given feature. + # Fields is a list of tuples (, ) + # + tbl = swsscommon.Table(state_db, 'FEATURE') + ret = [] + + # tbl.get for non-existing feature would return + # [False, {} ] + # + data = dict(tbl.get(feature)[1]) + for (field, default) in fields: + val = data[field] if field in data else default + ret += [val] + + return tuple(ret) + + +def check_version_blocked(state_db, feature, version): + # Ensure this version is *not* blocked explicitly. + # + tbl = swsscommon.Table(state_db, KUBE_LABEL_TABLE) + labels = dict(tbl.get(KUBE_LABEL_SET_KEY)[1]) + key = _get_version_key(feature, version) + return (key in labels) and (labels[key].lower() == "false") + + +def drop_label(state_db, feature, version): + # Mark given feature version as dropped in labels. + # Update is done in state-db. + # ctrmgrd sets it with kube API server per reaschability + + tbl = swsscommon.Table(state_db, KUBE_LABEL_TABLE) + name = _get_version_key(feature, version) + tbl.set(KUBE_LABEL_SET_KEY, [ (name, "false")]) + + +def update_data(state_db, feature, data): + # Update STATE-DB entry for this feature with given data + # + debug_msg("{}: {}".format(feature, str(data))) + tbl = swsscommon.Table(state_db, "FEATURE") + tbl.set(feature, list(data.items())) + + +def get_docker_id(): + # Read the container-id + # Note: This script runs inside the context of container + # + cmd = 'cat /proc/self/cgroup | grep -e ":memory:" | rev | cut -f1 -d\'/\' | rev' + proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) + output = proc.communicate()[0].decode("utf-8") + return output.strip()[:12] + + +def instance_higher(feature, ct_version, version): + # Compares given version against current version in STATE-DB. + # Return True if this version is higher than current. + # + ret = False + if ct_version: + ct = ct_version.split('.') + nxt = version.split('.') + for cs, ns in zip(ct, nxt): + c = int(cs) + n = int(ns) + if n < c: + break + elif n > c: + ret = True + break + else: + # Empty version implies no one is running. + ret = True + + debug_msg("compare version: new:{} current:{} res={}".format( + version, ct_version, ret)) + return ret + + +def is_active(feature, system_state): + # Check current system state of the feature + if system_state == "up": + return True + else: + syslog.syslog(syslog.LOG_ERR, "Found inactive for {}".format(feature)) + return False + + +def update_state(state_db, feature, owner=None, version=None): + """ + sets owner, version & container-id for this feature in state-db. + + If owner is local, update label to block remote deploying same version or + if kube, sets state to "running". + + """ + data = { + CURRENT_OWNER: owner, + DOCKER_ID: get_docker_id() if owner != "local" else feature, + UPD_TIMESTAMP: str(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")), + "hello": "world", + VERSION: version + } + + if (owner == "local"): + # Disable deployment of this version as available locally + drop_label(state_db, feature, version) + else: + data[REMOTE_STATE] = "running" + + debug_msg("{} up data:{}".format(feature, str(data))) + update_data(state_db, feature, data) + + +def do_freeze(feat, m): + # Exiting will kick off the container to run. + # So sleep forever with periodic logs. + # + while True: + syslog.syslog(syslog.LOG_ERR, "Blocking .... feat:{} docker_id:{} msg:{}".format( + feat, get_docker_id(), m)) + if UNIT_TESTING: + break + time.sleep(60) + + +def container_up(feature, owner, version): + """ + This is called by container upon post start. + + The container will run its application, only upon this call + complete. + + This call does the basic check for if this starting-container can be allowed + to run based on current state, and owner & version of this starting + container. + + If allowed to proceed, this info is recorded in state-db and return + to enable container start the main application. Else it proceeds to + sleep forever, blocking the container from starting the main application. + + """ + debug_msg("BEGIN") + (state_db, set_owner, state_data) = read_data(feature) + + debug_msg("args: feature={}, owner={}, version={} DB: set_owner={} state_data={}".format( + feature, owner, version, set_owner, json.dumps(state_data, indent=4))) + + if owner == "local": + update_state(state_db, feature, owner, version) + else: + if (set_owner == "local"): + do_freeze(feature, "bail out as set_owner is local") + return + + if not is_active(feature, state_data[SYSTEM_STATE]): + do_freeze(feature, "bail out as system state not active") + return + + if check_version_blocked(state_db, feature, version): + do_freeze(feature, "This version is marked disabled. Exiting ...") + return + + if not instance_higher(feature, state_data[VERSION], version): + # TODO: May Remove label __enabled + # Else kubelet will continue to re-deploy every 5 mins, until + # master removes the lable to un-deploy. + # + do_freeze(feature, "bail out as current deploy version {} is not higher". + format(version)) + return + + update_data(state_db, feature, { VERSION: version }) + + mode = state_data[REMOTE_STATE] + if mode in ("none", "running", "stopped"): + update_data(state_db, feature, { REMOTE_STATE: "pending" }) + mode = "pending" + else: + debug_msg("{}: Skip remote_state({}) update".format(feature, mode)) + + + i = 0 + while (mode != "ready"): + if (i % 10) == 0: + debug_msg("{}: remote_state={}. Waiting to go ready".format(feature, mode)) + i += 1 + + time.sleep(2) + mode, db_version = read_fields(state_db, + feature, [(REMOTE_STATE, "none"), (VERSION, "")]) + if version != db_version: + # looks like another instance has overwritten. Exit for now. + # If this happens to be higher version, next deploy by kube will fix + # This is a very rare window of opportunity, for this version to be higher. + # + do_freeze(feature, + "bail out as current deploy version={} is different than {}. re-deploy higher one". + format(version, db_version)) + return + if UNIT_TESTING: + return + + + update_state(state_db, feature, owner, version) + + debug_msg("END") + + +def main(): + parser = argparse.ArgumentParser(description="container_startup kube/local []") + + parser.add_argument("-f", "--feature", required=True) + parser.add_argument("-o", "--owner", choices=["local", "kube"], required=True) + parser.add_argument("-v", "--version", required=True) + + args = parser.parse_args() + container_up(args.feature, args.owner, args.version) + + + +if __name__ == "__main__": + main() diff --git a/src/sonic-ctrmgrd/ctrmgr/ctrmgr_tools.py b/src/sonic-ctrmgrd/ctrmgr/ctrmgr_tools.py new file mode 100755 index 000000000000..d85f76c4f955 --- /dev/null +++ b/src/sonic-ctrmgrd/ctrmgr/ctrmgr_tools.py @@ -0,0 +1,147 @@ +#! /usr/bin/env python3 + +import argparse +import json +import os +import syslog + +import docker +from swsscommon import swsscommon + +CTR_NAMES_FILE = "/usr/share/sonic/templates/ctr_image_names.json" + +LATEST_TAG = "latest" + +# DB fields +CT_OWNER = 'current_owner' +CT_ID = 'container_id' +SYSTEM_STATE = 'system_state' + +def _get_local_image_name(feature): + d = {} + if os.path.exists(CTR_NAMES_FILE): + with open(CTR_NAMES_FILE, "r") as s: + d = json.load(s) + return d[feature] if feature in d else None + + +def _remove_container(client, feature): + try: + # Remove stopped container instance, if any for this feature + container = client.containers.get(feature) + container.remove() + syslog.syslog(syslog.LOG_INFO, "Removed container for {}". + format(feature)) + return 0 + except Exception as err: + syslog.syslog(syslog.LOG_INFO, "No container to remove for {} err={}". + format(feature, str(err))) + return -1 + + +def _tag_container_image(feature, container_id, image_name, image_tag): + client = docker.from_env() + + try: + container = client.containers.get(container_id) + + # Tag this image for given name & tag + container.image.tag(image_name, image_tag, force=True) + + syslog.syslog(syslog.LOG_INFO, + "Tagged image for {} with container-id={} to {}:{}". + format(feature, container_id, image_name, image_tag)) + ret = _remove_container(client, feature) + return ret + + except Exception as err: + syslog.syslog(syslog.LOG_ERR, "Image tag: container:{} {}:{} failed with {}". + format(container_id, image_name, image_tag, str(err))) + return -1 + + +def tag_feature(feature=None, image_name=None, image_tag=None): + ret = 0 + state_db = swsscommon.DBConnector("STATE_DB", 0) + tbl = swsscommon.Table(state_db, 'FEATURE') + keys = tbl.getKeys() + for k in keys: + if (not feature) or (k == feature): + d = dict(tbl.get(k)[1]) + owner = d.get(CT_OWNER, "") + id = d.get(CT_ID, "") + if not image_name: + image_name = _get_local_image_name(k) + if not image_tag: + image_tag = LATEST_TAG + if id and (owner == "kube") and image_name: + ret = _tag_container_image(k, id, image_name, image_tag) + else: + syslog.syslog(syslog.LOG_ERR, + "Skip to tag feature={} image={} tag={}".format( + k, str(image_name), str(image_tag))) + ret = -1 + + image_name=None + return ret + + +def func_tag_feature(args): + return tag_feature(args.feature, args.image_name, args.image_tag) + + +def func_tag_all(args): + return tag_feature() + + +def func_kill_all(args): + client = docker.from_env() + state_db = swsscommon.DBConnector("STATE_DB", 0) + tbl = swsscommon.Table(state_db, 'FEATURE') + + keys = tbl.getKeys() + for k in keys: + data = dict(tbl.get(k)[1]) + is_up = data.get(SYSTEM_STATE, "").lower() == "up" + id = data.get(CT_ID, "") if is_up else "" + if id: + try: + container = client.containers.get(id) + container.kill() + syslog.syslog(syslog.LOG_INFO, + "Killed container for {} with id={}".format(k, id)) + except Exception as err: + syslog.syslog(syslog.LOG_ERR, + "kill: feature={} id={} unable to get container". + format(k, id)) + return -1 + return 0 + + +def main(): + parser = argparse.ArgumentParser(description="Remote container mgmt tools") + subparsers = parser.add_subparsers(title="ctrmgr_tools") + + parser_tag = subparsers.add_parser('tag') + parser_tag.add_argument("-f", "--feature", required=True) + parser_tag.add_argument("-n", "--image-name") + parser_tag.add_argument("-t", "--image-tag") + parser_tag.set_defaults(func=func_tag_feature) + + parser_tag_all = subparsers.add_parser('tag-all') + parser_tag_all.set_defaults(func=func_tag_all) + + parser_kill_all = subparsers.add_parser('kill-all') + parser_kill_all.set_defaults(func=func_kill_all) + + args = parser.parse_args() + if len(args.__dict__) < 1: + parser.print_help() + return -1 + + ret = args.func(args) + return ret + + +if __name__ == "__main__": + main() diff --git a/src/sonic-ctrmgrd/ctrmgr/ctrmgrd.py b/src/sonic-ctrmgrd/ctrmgr/ctrmgrd.py new file mode 100755 index 000000000000..ba4f0057bd05 --- /dev/null +++ b/src/sonic-ctrmgrd/ctrmgr/ctrmgrd.py @@ -0,0 +1,598 @@ +#!/usr/bin/env python3 + +import datetime +import inspect +import json +import os +import sys +import syslog + +from collections import defaultdict + +from swsscommon import swsscommon +from sonic_py_common import device_info + +sys.path.append(os.path.dirname(os.path.realpath(__file__))) +import kube_commands + +UNIT_TESTING = 0 +UNIT_TESTING_ACTIVE = 0 + +# Kube config file +SONIC_CTR_CONFIG = "/etc/sonic/remote_ctr.config.json" + +CONFIG_DB_NAME = "CONFIG_DB" +STATE_DB_NAME = "STATE_DB" + +# DB SERVER +SERVER_TABLE = "KUBERNETES_MASTER" +SERVER_KEY = "SERVER" +CFG_SER_IP = "ip" +CFG_SER_PORT = "port" +CFG_SER_DISABLE = "disable" +CFG_SER_INSECURE = "insecure" + +ST_SER_IP = "ip" +ST_SER_PORT = "port" +ST_SER_CONNECTED = "connected" +ST_SER_UPDATE_TS = "update_time" + +# DB FEATURE +FEATURE_TABLE = "FEATURE" +CFG_FEAT_OWNER = "set_owner" +CFG_FEAT_NO_FALLBACK = "no_fallback_to_local" +CFG_FEAT_FAIL_DETECTION = "remote_fail_detection" + +ST_FEAT_OWNER = "current_owner" +ST_FEAT_UPDATE_TS = "update_time" +ST_FEAT_CTR_ID = "container_id" +ST_FEAT_CTR_VER = "container_version" +ST_FEAT_REMOTE_STATE = "remote_state" +ST_FEAT_SYS_STATE = "system_state" + +KUBE_LABEL_TABLE = "KUBE_LABELS" +KUBE_LABEL_SET_KEY = "SET" + +remote_connected = False + +dflt_cfg_ser = { + CFG_SER_IP: "", + CFG_SER_PORT: "6443", + CFG_SER_DISABLE: "false", + CFG_SER_INSECURE: "false" + } + +dflt_st_ser = { + ST_SER_IP: "", + ST_SER_PORT: "", + ST_SER_CONNECTED: "", + ST_SER_UPDATE_TS: "" + } + +dflt_cfg_feat= { + CFG_FEAT_OWNER: "local", + CFG_FEAT_NO_FALLBACK: "false", + CFG_FEAT_FAIL_DETECTION: "300" + } + +dflt_st_feat= { + ST_FEAT_OWNER: "none", + ST_FEAT_UPDATE_TS: "", + ST_FEAT_CTR_ID: "", + ST_FEAT_CTR_VER: "", + ST_FEAT_REMOTE_STATE: "none", + ST_FEAT_SYS_STATE: "" + } + +JOIN_LATENCY = "join_latency_on_boot_seconds" +JOIN_RETRY = "retry_join_interval_seconds" +LABEL_RETRY = "retry_labels_update_seconds" + +remote_ctr_config = { + JOIN_LATENCY: 10, + JOIN_RETRY: 10, + LABEL_RETRY: 2 + } + +def log_debug(m): + msg = "{}: {}".format(inspect.stack()[1][3], m) + print(msg) + syslog.syslog(syslog.LOG_DEBUG, msg) + + +def log_error(m): + syslog.syslog(syslog.LOG_ERR, msg) + + +def log_info(m): + syslog.syslog(syslog.LOG_INFO, msg) + + +def ts_now(): + return str(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")) + + +def is_systemd_active(feat): + if not UNIT_TESTING: + status = os.system('systemctl is-active --quiet {}'.format(feat)) + else: + status = UNIT_TESTING_ACTIVE + log_debug("system status for {}: {}".format(feat, str(status))) + return status == 0 + + +def restart_systemd_service(server, feat, owner): + log_debug("Restart service {} to owner:{}".format(feat, owner)) + if not UNIT_TESTING: + status = os.system("systemctl restart {}".format(feat)) + else: + server.mod_db_entry(STATE_DB_NAME, + FEATURE_TABLE, feat, {"restart": "true"}) + status = 0 + if status != 0: + syslog.syslog(syslog.LOG_ERR, + "Failed to restart {} to switch to {}".format(feat, owner)) + else: + syslog.syslog(syslog.LOG_INFO, + "Restarted {} to switch to {}".format(feat, owner)) + return status + + +def init(): + if os.path.exists(SONIC_CTR_CONFIG): + with open(SONIC_CTR_CONFIG, "r") as s: + d = json.load(s) + remote_ctr_config.update(d) + + +class MainServer: + """ Implements main io-loop of the application + Accept handler registration per db/table. + Call handler on update + """ + + SELECT_TIMEOUT = 1000 + + def __init__(self): + """ Constructor """ + self.db_connectors = {} + self.selector = swsscommon.Select() + self.callbacks = defaultdict(lambda: defaultdict(list)) # db -> table -> handlers[] + self.timer_handlers = defaultdict(list) + self.subscribers = set() + + def register_db(self, db_name): + """ Get DB connector, if not there """ + if db_name not in self.db_connectors: + self.db_connectors[db_name] = swsscommon.DBConnector(db_name, 0) + + + def register_timer(self, ts, handler): + """ Register timer based handler. + The handler will be called on/after give timestamp, ts + """ + self.timer_handlers[ts].append(handler) + + + def register_handler(self, db_name, table_name, handler): + """ + Handler registration for any update in given table + in given db. The handler will be called for any update + to the table in this db. + """ + self.register_db(db_name) + + if table_name not in self.callbacks[db_name]: + conn = self.db_connectors[db_name] + subscriber = swsscommon.SubscriberStateTable(conn, table_name) + self.subscribers.add(subscriber) + self.selector.addSelectable(subscriber) + self.callbacks[db_name][table_name].append(handler) + + + def get_db_entry(self, db_name, table_name, key): + """ Return empty dict if key not present """ + conn = self.db_connectors[db_name] + tbl = swsscommon.Table(conn, table_name) + return dict(tbl.get(key)[1]) + + + def mod_db_entry(self, db_name, table_name, key, data): + """ Modify entry for given table|key with given dict type data """ + conn = self.db_connectors[db_name] + tbl = swsscommon.Table(conn, table_name) + print("mod_db_entry: db={} tbl={} key={} data={}".format(db_name, table_name, key, str(data))) + tbl.set(key, list(data.items())) + + + def set_db_entry(self, db_name, table_name, key, data): + """ Set given data as complete data, which includes + removing any fields that are in DB but not in data + """ + conn = self.db_connectors[db_name] + tbl = swsscommon.Table(conn, table_name) + ct_data = dict(tbl.get(key)[1]) + for k in ct_data: + if k not in data: + # Drop fields that are not in data + tbl.hdel(key, k) + tbl.set(key, list(data.items())) + + + def run(self): + """ Main loop """ + while True: + timeout = MainServer.SELECT_TIMEOUT + ct_ts = datetime.datetime.now() + while self.timer_handlers: + k = sorted(self.timer_handlers.keys())[0] + if k <= ct_ts: + lst = self.timer_handlers[k] + del self.timer_handlers[k] + for fn in lst: + fn() + else: + timeout = (k - ct_ts).seconds + break + + state, _ = self.selector.select(timeout) + if state == self.selector.TIMEOUT: + continue + elif state == self.selector.ERROR: + if not UNIT_TESTING: + raise Exception("Received error from select") + else: + print("Skipped Exception; Received error from select") + return + + for subscriber in self.subscribers: + key, op, fvs = subscriber.pop() + if not key: + continue + log_debug("Received message : '%s'" % str((key, op, fvs))) + for callback in (self.callbacks + [subscriber.getDbConnector().getDbName()] + [subscriber.getTableName()]): + callback(key, op, dict(fvs)) + + + +def set_node_labels(server): + labels = {} + + version_info = (device_info.get_sonic_version_info() if not UNIT_TESTING + else { "build_version": "20201230.111"}) + dev_data = server.get_db_entry(CONFIG_DB_NAME, 'DEVICE_METADATA', + 'localhost') + dep_type = dev_data['type'] if 'type' in dev_data else "unknown" + + labels["sonic_version"] = version_info['build_version'] + labels["hwsku"] = device_info.get_hwsku() if not UNIT_TESTING else "mock" + labels["deployment_type"] = dep_type + server.mod_db_entry(STATE_DB_NAME, + KUBE_LABEL_TABLE, KUBE_LABEL_SET_KEY, labels) + + +def _update_entry(ct, upd): + # Helper function, to update with case lowered. + ret = dict(ct) + for (k, v) in upd.items(): + ret[k.lower()] = v.lower() + + return ret + + +# +# SERVER-config changes: +# Act if IP or disable changes. +# If disabled or IP removed: +# reset connection +# else: +# join +# Update state-DB appropriately +# +class RemoteServerHandler: + def __init__(self, server): + """ Register self for updates """ + self.server = server + + server.register_handler( + CONFIG_DB_NAME, SERVER_TABLE, self.on_config_update) + self.cfg_server = _update_entry(dflt_cfg_ser, server.get_db_entry( + CONFIG_DB_NAME, SERVER_TABLE, SERVER_KEY)) + + log_debug("startup config: {}".format(str(self.cfg_server))) + + server.register_db(STATE_DB_NAME) + self.st_server = _update_entry(dflt_st_ser, server.get_db_entry( + STATE_DB_NAME, SERVER_TABLE, SERVER_KEY)) + + self.start_time = datetime.datetime.now() + + if not self.st_server[ST_FEAT_UPDATE_TS]: + # This is upon system start. Sleep 10m before join + self.start_time += datetime.timedelta( + seconds=remote_ctr_config[JOIN_LATENCY]) + server.register_timer(self.start_time, self.handle_update) + self.pending = True + log_debug("Pause to join {} seconds @ {}".format( + remote_ctr_config[JOIN_LATENCY], self.start_time)) + else: + self.pending = False + self.handle_update() + + + + def on_config_update(self, key, op, data): + """ On config update """ + if key != SERVER_KEY: + return + + cfg_data = _update_entry(dflt_cfg_ser, data) + if self.cfg_server == cfg_data: + log_debug("No change in server config") + return + + log_debug("Received config update: {}".format(str(data))) + self.cfg_server = cfg_data + + if self.pending: + tnow = datetime.datetime.now() + if tnow < self.start_time: + # Pausing for initial latency since reboot or last retry + due_secs = (self.start_time - tnow).seconds + else: + due_secs = 0 + log_debug("Pending to start in {} seconds at {}".format( + due_secs, self.start_time)) + return + + self.handle_update() + + + def handle_update(self): + # Called upon start and upon any config-update only. + # Called by timer / main thread. + # Main thread calls only if timer is not running. + # + self.pending = False + + ip = self.cfg_server[CFG_SER_IP] + disable = self.cfg_server[CFG_SER_DISABLE] != "false" + + pre_state = dict(self.st_server) + log_debug("server: handle_update: disable={} ip={}".format(disable, ip)) + if disable or not ip: + self.do_reset() + else: + self.do_join(ip, self.cfg_server[ST_SER_PORT], + self.cfg_server[CFG_SER_INSECURE]) + + if pre_state != self.st_server: + self.st_server[ST_SER_UPDATE_TS] = ts_now() + self.server.set_db_entry(STATE_DB_NAME, + SERVER_TABLE, SERVER_KEY, self.st_server) + log_debug("Update server state={}".format(str(self.st_server))) + + + def do_reset(self): + global remote_connected + + kube_commands.kube_reset_master(True) + + self.st_server[ST_SER_CONNECTED] = "false" + log_debug("kube_reset_master called") + + remote_connected = False + + + def do_join(self, ip, port, insecure): + global remote_connected + (ret, out, err) = kube_commands.kube_join_master( + ip, port, insecure) + + if ret == 0: + self.st_server[ST_SER_CONNECTED] = "true" + self.st_server[ST_SER_IP] = ip + self.st_server[ST_SER_PORT] = port + remote_connected = True + + set_node_labels(self.server) + log_debug("kube_join_master succeeded") + else: + # Ensure state reflects the current status + self.st_server[ST_SER_CONNECTED] = "false" + remote_connected = False + + # Join failed. Retry after an interval + self.start_time = datetime.datetime.now() + self.start_time += datetime.timedelta( + seconds=remote_ctr_config[JOIN_RETRY]) + self.server.register_timer(self.start_time, self.handle_update) + self.pending = True + + log_debug("kube_join_master failed retry after {} seconds @{}". + format(remote_ctr_config[JOIN_RETRY], self.start_time)) + + +# +# Feature changes +# +# Handle Set_owner change: +# restart service and/or label add/drop +# +# Handle remote_state change: +# When pending, trigger restart +# +class FeatureTransitionHandler: + def __init__(self, server): + self.server = server + self.cfg_data = defaultdict(lambda: defaultdict(str)) + self.st_data = defaultdict(lambda: defaultdict(str)) + server.register_handler( + CONFIG_DB_NAME, FEATURE_TABLE, self.on_config_update) + server.register_handler( + STATE_DB_NAME, FEATURE_TABLE, self.on_state_update) + return + + + def handle_update(self, feat, set_owner, ct_owner, remote_state): + # Called upon startup once for every feature in config & state DBs. + # There after only called upon changes in either that requires action + # + if not is_systemd_active(feat): + # Nothing todo, if system state is down + return + + label_add = set_owner == "kube" + service_restart = False + + if set_owner == "local": + if ct_owner != "local": + service_restart = True + else: + if (ct_owner != "none") and (remote_state == "pending"): + service_restart = True + + log_debug( + "feat={} set={} ct={} state={} restart={} label_add={}".format( + feat, set_owner, ct_owner, remote_state, service_restart, + label_add)) + # read labels and add/drop if different + self.server.mod_db_entry(STATE_DB_NAME, KUBE_LABEL_TABLE, KUBE_LABEL_SET_KEY, + { "{}_enabled".format(feat): ("true" if label_add else "false") }) + + + # service_restart + if service_restart: + restart_systemd_service(self.server, feat, set_owner) + + + + def on_config_update(self, key, op, data): + # Hint/Note: + # If the key don't pre-exist: + # This attempt to read will create the key for given + # field with empty string as value and return empty string + + init = key not in self.cfg_data + old_set_owner = self.cfg_data[key][CFG_FEAT_OWNER] + + self.cfg_data[key] = _update_entry(dflt_cfg_feat, data) + set_owner = self.cfg_data[key][CFG_FEAT_OWNER] + + if (not init) and (old_set_owner == set_owner): + # No change, bail out + log_debug("No change in feat={} set_owner={}. Bail out.".format( + key, set_owner)) + return + + if key in self.st_data: + log_debug("{} init={} old_set_owner={} owner={}".format(key, init, old_set_owner, set_owner)) + self.handle_update(key, set_owner, + self.st_data[key][ST_FEAT_OWNER], + self.st_data[key][ST_FEAT_REMOTE_STATE]) + + else: + # Handle it upon data from state-db, which must come + # if systemd is up + log_debug("Yet to get state info key={}. Bail out.".format(key)) + return + + + def on_state_update(self, key, op, data): + # Hint/Note: + # If the key don't pre-exist: + # This attempt to read will create the key for given + # field with empty string as value and return empty string + + init = key not in self.st_data + old_remote_state = self.st_data[key][ST_FEAT_REMOTE_STATE] + + self.st_data[key] = _update_entry(dflt_st_feat, data) + remote_state = self.st_data[key][ST_FEAT_REMOTE_STATE] + + if (not init) and ( + (old_remote_state == remote_state) or (remote_state != "pending")): + # no change or nothing to do. + return + + if key in self.cfg_data: + log_debug("{} init={} old_remote_state={} remote_state={}".format(key, init, old_remote_state, remote_state)) + self.handle_update(key, self.cfg_data[key][CFG_FEAT_OWNER], + self.st_data[key][ST_FEAT_OWNER], + remote_state) + return + + +# +# Label re-sync +# When labels applied at remote are pending, start monitoring +# API server reachability and trigger the label handler to +# apply the labels +# +# Non-empty KUBE_LABELS|PENDING, monitor API Server reachability +# +class LabelsPendingHandler: + def __init__(self, server): + server.register_handler(STATE_DB_NAME, KUBE_LABEL_TABLE, self.on_update) + self.server = server + self.pending = False + self.set_labels = {} + return + + + def on_update(self, key, op, data): + # For any update sync with kube API server. + # Don't optimize, as API server could differ with DB's contents + # in many ways. + # + if (key == KUBE_LABEL_SET_KEY): + self.set_labels = dict(data) + else: + return + + if remote_connected and not self.pending: + self.update_node_labels() + else: + log_debug("Skip label update: connected:{} pending:{}". + format(remote_connected, self.pending)) + + + + def update_node_labels(self): + # Called on config update by main thread upon init or config-change or + # it was not connected during last config update + # NOTE: remote-server-handler forces a config update notification upon + # join. + # Or it could be called by timer thread, if last upate to API server + # failed. + # + self.pending = False + ret = kube_commands.kube_write_labels(self.set_labels) + if (ret != 0): + self.pending = True + pause = remote_ctr_config[LABEL_RETRY] + ts = (datetime.datetime.now() + datetime.timedelta(seconds=pause)) + self.server.register_timer(ts, self.update_node_labels) + + log_debug("ret={} set={} pending={}".format(ret, + str(self.set_labels), self.pending)) + return + + +def main(): + init() + server = MainServer() + RemoteServerHandler(server) + FeatureTransitionHandler(server) + LabelsPendingHandler(server) + server.run() + print("ctrmgrd.py main called") + return 0 + + +if __name__ == '__main__': + if os.geteuid() != 0: + exit("Please run as root. Exiting ...") + main() diff --git a/src/sonic-ctrmgrd/ctrmgr/ctrmgrd.service b/src/sonic-ctrmgrd/ctrmgr/ctrmgrd.service new file mode 100644 index 000000000000..6052c10785da --- /dev/null +++ b/src/sonic-ctrmgrd/ctrmgr/ctrmgrd.service @@ -0,0 +1,14 @@ +[Unit] +Description=Container Manager watcher daemon +Requires=updategraph.service +After=updategraph.service + + +[Service] +Type=simple +ExecStart=/usr/local/bin/ctrmgrd.py +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target diff --git a/src/sonic-ctrmgrd/ctrmgr/kube_commands.py b/src/sonic-ctrmgrd/ctrmgr/kube_commands.py new file mode 100755 index 000000000000..1ebfa606f07f --- /dev/null +++ b/src/sonic-ctrmgrd/ctrmgr/kube_commands.py @@ -0,0 +1,391 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import argparse +import fcntl +import inspect +import json +import os +import shutil +import ssl +import subprocess +import sys +import syslog +import tempfile +import urllib.request +from urllib.parse import urlparse + +import yaml +from sonic_py_common import device_info + +KUBE_ADMIN_CONF = "/etc/sonic/kube_admin.conf" +KUBELET_YAML = "/var/lib/kubelet/config.yaml" +SERVER_ADMIN_URL = "https://{}/admin.conf" +LOCK_FILE = "/var/lock/kube_join.lock" + +# kubectl --kubeconfig label nodes +#